diff --git a/CREDITS b/CREDITS
--- a/CREDITS
+++ b/CREDITS
@@ -1624,10 +1624,10 @@ E: ajoshi@shell.unixbox.com
 D: fbdev hacking
 
 N: Jesper Juhl
-E: juhl-lkml@dif.dk
-D: Various small janitor fixes, cleanups etc.
+E: jesper.juhl@gmail.com
+D: Various fixes, cleanups and minor features.
 S: Lemnosvej 1, 3.tv
-S: 2300 Copenhagen S
+S: 2300 Copenhagen S.
 S: Denmark
 
 N: Jozsef Kadlecsik
@@ -1880,6 +1880,13 @@ S: Schlehenweg 9
 S: D-91080 Uttenreuth
 S: Germany
 
+N: Jaya Kumar
+E: jayalk@intworks.biz
+W: http://www.intworks.biz
+D: Arc monochrome LCD framebuffer driver, x86 reboot fixups
+S: Gurgaon, India
+S: Kuala Lumpur, Malaysia
+
 N: Gabor Kuti
 M: seasons@falcon.sch.bme.hu
 M: seasons@makosteszta.sote.hu
@@ -2373,9 +2380,10 @@ E: tmolina@cablespeed.com
 D: bug fixes, documentation, minor hackery
 
 N: James Morris
-E: jmorris@intercode.com.au
-W: http://www.intercode.com.au/jmorris/
-D: Netfilter, Linux Security Modules (LSM).
+E: jmorris@namei.org
+W: http://namei.org/
+D: Netfilter, Linux Security Modules (LSM), SELinux, IPSec,
+D: Crypto API, general networking, miscellaneous.
 S: PO Box 707
 S: Spit Junction NSW 2088
 S: Australia
@@ -2415,8 +2423,7 @@ S: Toronto, Ontario
 S: Canada
 
 N: Zwane Mwaikambo
-E: zwane@linuxpower.ca
-W: http://function.linuxpower.ca
+E: zwane@arm.linux.org.uk
 D: Various driver hacking
 D: Lowlevel x86 kernel hacking
 D: General debugging
diff --git a/Documentation/00-INDEX b/Documentation/00-INDEX
--- a/Documentation/00-INDEX
+++ b/Documentation/00-INDEX
@@ -138,6 +138,8 @@ java.txt
 	- info on the in-kernel binary support for Java(tm).
 kbuild/
 	- directory with info about the kernel build process.
+kdumpt.txt
+       - mini HowTo on getting the crash dump code to work.
 kernel-doc-nano-HOWTO.txt
 	- mini HowTo on generation and location of kernel documentation files.
 kernel-docs.txt
diff --git a/Documentation/Changes b/Documentation/Changes
--- a/Documentation/Changes
+++ b/Documentation/Changes
@@ -44,9 +44,9 @@ running, the suggested command should te
 
 Again, keep in mind that this list assumes you are already
 functionally running a Linux 2.4 kernel.  Also, not all tools are
-necessary on all systems; obviously, if you don't have any PCMCIA (PC
-Card) hardware, for example, you probably needn't concern yourself
-with pcmcia-cs.
+necessary on all systems; obviously, if you don't have any ISDN
+hardware, for example, you probably needn't concern yourself with
+isdn4k-utils.
 
 o  Gnu C                  2.95.3                  # gcc --version
 o  Gnu make               3.79.1                  # make --version
@@ -57,13 +57,15 @@ o  e2fsprogs              1.29          
 o  jfsutils               1.1.3                   # fsck.jfs -V
 o  reiserfsprogs          3.6.3                   # reiserfsck -V 2>&1|grep reiserfsprogs
 o  xfsprogs               2.6.0                   # xfs_db -V
+o  pcmciautils            004
 o  pcmcia-cs              3.1.21                  # cardmgr -V
 o  quota-tools            3.09                    # quota -V
 o  PPP                    2.4.0                   # pppd --version
 o  isdn4k-utils           3.1pre1                 # isdnctrl 2>&1|grep version
 o  nfs-utils              1.0.5                   # showmount --version
 o  procps                 3.2.0                   # ps --version
-o  oprofile               0.5.3                   # oprofiled --version
+o  oprofile               0.9                     # oprofiled --version
+o  udev                   058                     # udevinfo -V
 
 Kernel compilation
 ==================
@@ -186,13 +188,20 @@ architecture independent and any version
 work correctly with this version of the XFS kernel code (2.6.0 or
 later is recommended, due to some significant improvements).
 
+PCMCIAutils
+-----------
+
+PCMCIAutils replaces pcmcia-cs (see below). It properly sets up
+PCMCIA sockets at system startup and loads the appropriate modules
+for 16-bit PCMCIA devices if the kernel is modularized and the hotplug
+subsystem is used.
 
 Pcmcia-cs
 ---------
 
 PCMCIA (PC Card) support is now partially implemented in the main
-kernel source.  Pay attention when you recompile your kernel ;-).
-Also, be sure to upgrade to the latest pcmcia-cs release.
+kernel source. The "pcmciautils" package (see above) replaces pcmcia-cs
+for newest kernels.
 
 Quota-tools
 -----------
@@ -349,9 +358,13 @@ Xfsprogs
 --------
 o  <ftp://oss.sgi.com/projects/xfs/download/>
 
+Pcmciautils
+-----------
+o  <ftp://ftp.kernel.org/pub/linux/utils/kernel/pcmcia/>
+
 Pcmcia-cs
 ---------
-o  <ftp://pcmcia-cs.sourceforge.net/pub/pcmcia-cs/pcmcia-cs-3.1.21.tar.gz>
+o  <http://pcmcia-cs.sourceforge.net/>
 
 Quota-tools
 ----------
diff --git a/Documentation/DocBook/Makefile b/Documentation/DocBook/Makefile
--- a/Documentation/DocBook/Makefile
+++ b/Documentation/DocBook/Makefile
@@ -8,7 +8,7 @@
 
 DOCBOOKS := wanbook.xml z8530book.xml mcabook.xml videobook.xml \
 	    kernel-hacking.xml kernel-locking.xml deviceiobook.xml \
-	    procfs-guide.xml writing_usb_driver.xml scsidrivers.xml \
+	    procfs-guide.xml writing_usb_driver.xml \
 	    sis900.xml kernel-api.xml journal-api.xml lsm.xml usb.xml \
 	    gadget.xml libata.xml mtdnand.xml librs.xml
 
@@ -49,7 +49,7 @@ installmandocs: mandocs
 KERNELDOC = scripts/kernel-doc
 DOCPROC   = scripts/basic/docproc
 
-XMLTOFLAGS = -m Documentation/DocBook/stylesheet.xsl
+XMLTOFLAGS = -m $(srctree)/Documentation/DocBook/stylesheet.xsl
 #XMLTOFLAGS += --skip-validation
 
 ###
diff --git a/Documentation/DocBook/kernel-api.tmpl b/Documentation/DocBook/kernel-api.tmpl
--- a/Documentation/DocBook/kernel-api.tmpl
+++ b/Documentation/DocBook/kernel-api.tmpl
@@ -266,7 +266,7 @@ X!Ekernel/module.c
   <chapter id="hardware">
      <title>Hardware Interfaces</title>
      <sect1><title>Interrupt Handling</title>
-!Iarch/i386/kernel/irq.c
+!Ikernel/irq/manage.c
      </sect1>
 
      <sect1><title>Resources Management</title>
@@ -338,7 +338,6 @@ X!Earch/i386/kernel/mca.c
 X!Iinclude/linux/device.h
 -->
 !Edrivers/base/driver.c
-!Edrivers/base/class_simple.c
 !Edrivers/base/core.c
 !Edrivers/base/firmware_class.c
 !Edrivers/base/transport_class.c
diff --git a/Documentation/DocBook/libata.tmpl b/Documentation/DocBook/libata.tmpl
--- a/Documentation/DocBook/libata.tmpl
+++ b/Documentation/DocBook/libata.tmpl
@@ -84,6 +84,14 @@ void (*port_disable) (struct ata_port *)
 	Called from ata_bus_probe() and ata_bus_reset() error paths,
 	as well as when unregistering from the SCSI module (rmmod, hot
 	unplug).
+	This function should do whatever needs to be done to take the
+	port out of use.  In most cases, ata_port_disable() can be used
+	as this hook.
+	</para>
+	<para>
+	Called from ata_bus_probe() on a failed probe.
+	Called from ata_bus_reset() on a failed bus reset.
+	Called from ata_scsi_release().
 	</para>
 
 	</sect2>
@@ -98,6 +106,13 @@ void (*dev_config) (struct ata_port *, s
 	found.  Typically used to apply device-specific fixups prior to
 	issue of SET FEATURES - XFER MODE, and prior to operation.
 	</para>
+	<para>
+	Called by ata_device_add() after ata_dev_identify() determines
+	a device is present.
+	</para>
+	<para>
+	This entry may be specified as NULL in ata_port_operations.
+	</para>
 
 	</sect2>
 
@@ -135,6 +150,8 @@ void (*tf_read) (struct ata_port *ap, st
 	registers / DMA buffers.  ->tf_read() is called to read the
 	hardware registers / DMA buffers, to obtain the current set of
 	taskfile register values.
+	Most drivers for taskfile-based hardware (PIO or MMIO) use
+	ata_tf_load() and ata_tf_read() for these hooks.
 	</para>
 
 	</sect2>
@@ -147,6 +164,8 @@ void (*exec_command)(struct ata_port *ap
 	<para>
 	causes an ATA command, previously loaded with
 	->tf_load(), to be initiated in hardware.
+	Most drivers for taskfile-based hardware use ata_exec_command()
+	for this hook.
 	</para>
 
 	</sect2>
@@ -161,6 +180,10 @@ Allow low-level driver to filter ATA PAC
 indicating whether or not it is OK to use DMA for the supplied PACKET
 command.
 	</para>
+	<para>
+	This hook may be specified as NULL, in which case libata will
+	assume that atapi dma can be supported.
+	</para>
 
 	</sect2>
 
@@ -175,6 +198,14 @@ u8   (*check_err)(struct ata_port *ap);
 	Reads the Status/AltStatus/Error ATA shadow register from
 	hardware.  On some hardware, reading the Status register has
 	the side effect of clearing the interrupt condition.
+	Most drivers for taskfile-based hardware use
+	ata_check_status() for this hook.
+	</para>
+	<para>
+	Note that because this is called from ata_device_add(), at
+	least a dummy function that clears device interrupts must be
+	provided for all drivers, even if the controller doesn't
+	actually have a taskfile status register.
 	</para>
 
 	</sect2>
@@ -188,7 +219,13 @@ void (*dev_select)(struct ata_port *ap, 
 	Issues the low-level hardware command(s) that causes one of N
 	hardware devices to be considered 'selected' (active and
 	available for use) on the ATA bus.  This generally has no
-meaning on FIS-based devices.
+	meaning on FIS-based devices.
+	</para>
+	<para>
+	Most drivers for taskfile-based hardware use
+	ata_std_dev_select() for this hook.  Controllers which do not
+	support second drives on a port (such as SATA contollers) will
+	use ata_noop_dev_select().
 	</para>
 
 	</sect2>
@@ -204,6 +241,8 @@ void (*phy_reset) (struct ata_port *ap);
 	for device presence (PATA and SATA), typically a soft reset
 	(SRST) will be performed.  Drivers typically use the helper
 	functions ata_bus_reset() or sata_phy_reset() for this hook.
+	Many SATA drivers use sata_phy_reset() or call it from within
+	their own phy_reset() functions.
 	</para>
 
 	</sect2>
@@ -227,6 +266,25 @@ PCI IDE DMA Status register.
 These hooks are typically either no-ops, or simply not implemented, in
 FIS-based drivers.
 	</para>
+	<para>
+Most legacy IDE drivers use ata_bmdma_setup() for the bmdma_setup()
+hook.  ata_bmdma_setup() will write the pointer to the PRD table to
+the IDE PRD Table Address register, enable DMA in the DMA Command
+register, and call exec_command() to begin the transfer.
+	</para>
+	<para>
+Most legacy IDE drivers use ata_bmdma_start() for the bmdma_start()
+hook.  ata_bmdma_start() will write the ATA_DMA_START flag to the DMA
+Command register.
+	</para>
+	<para>
+Many legacy IDE drivers use ata_bmdma_stop() for the bmdma_stop()
+hook.  ata_bmdma_stop() clears the ATA_DMA_START flag in the DMA
+command register.
+	</para>
+	<para>
+Many legacy IDE drivers use ata_bmdma_status() as the bmdma_status() hook.
+	</para>
 
 	</sect2>
 
@@ -250,6 +308,10 @@ int (*qc_issue) (struct ata_queued_cmd *
 	helper function ata_qc_issue_prot() for taskfile protocol-based
 	dispatch.  More advanced drivers implement their own ->qc_issue.
 	</para>
+	<para>
+	ata_qc_issue_prot() calls ->tf_load(), ->bmdma_setup(), and
+	->bmdma_start() as necessary to initiate a transfer.
+	</para>
 
 	</sect2>
 
@@ -279,6 +341,21 @@ void (*irq_clear) (struct ata_port *);
 	before the interrupt handler is registered, to be sure hardware
 	is quiet.
 	</para>
+	<para>
+	The second argument, dev_instance, should be cast to a pointer
+	to struct ata_host_set.
+	</para>
+	<para>
+	Most legacy IDE drivers use ata_interrupt() for the
+	irq_handler hook, which scans all ports in the host_set,
+	determines which queued command was active (if any), and calls
+	ata_host_intr(ap,qc).
+	</para>
+	<para>
+	Most legacy IDE drivers use ata_bmdma_irq_clear() for the
+	irq_clear() hook, which simply clears the interrupt and error
+	flags in the DMA status register.
+	</para>
 
 	</sect2>
 
@@ -292,6 +369,7 @@ void (*scr_write) (struct ata_port *ap, 
 	<para>
 	Read and write standard SATA phy registers.  Currently only used
 	if ->phy_reset hook called the sata_phy_reset() helper function.
+	sc_reg is one of SCR_STATUS, SCR_CONTROL, SCR_ERROR, or SCR_ACTIVE.
 	</para>
 
 	</sect2>
@@ -307,17 +385,29 @@ void (*host_stop) (struct ata_host_set *
 	->port_start() is called just after the data structures for each
 	port are initialized.  Typically this is used to alloc per-port
 	DMA buffers / tables / rings, enable DMA engines, and similar
-	tasks.  
+	tasks.  Some drivers also use this entry point as a chance to
+	allocate driver-private memory for ap->private_data.
+	</para>
+	<para>
+	Many drivers use ata_port_start() as this hook or call
+	it from their own port_start() hooks.  ata_port_start()
+	allocates space for a legacy IDE PRD table and returns.
 	</para>
 	<para>
 	->port_stop() is called after ->host_stop().  It's sole function
 	is to release DMA/memory resources, now that they are no longer
-	actively being used.
+	actively being used.  Many drivers also free driver-private
+	data from port at this time.
+	</para>
+	<para>
+	Many drivers use ata_port_stop() as this hook, which frees the
+	PRD table.
 	</para>
 	<para>
 	->host_stop() is called after all ->port_stop() calls
 have completed.  The hook must finalize hardware shutdown, release DMA
 and other resources, etc.
+	This hook may be specified as NULL, in which case it is not called.
 	</para>
 
 	</sect2>
diff --git a/Documentation/DocBook/scsidrivers.tmpl b/Documentation/DocBook/scsidrivers.tmpl
deleted file mode 100644
--- a/Documentation/DocBook/scsidrivers.tmpl
+++ /dev/null
@@ -1,193 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
-	"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []>
-
-<book id="scsidrivers">
- <bookinfo>
-  <title>SCSI Subsystem Interfaces</title>
-  
-  <authorgroup>
-   <author>
-    <firstname>Douglas</firstname>
-    <surname>Gilbert</surname>
-    <affiliation>
-     <address>
-      <email>dgilbert@interlog.com</email>
-     </address>
-    </affiliation>
-   </author>
-  </authorgroup>
-  <pubdate>2003-08-11</pubdate>
-
-  <copyright>
-   <year>2002</year>
-   <year>2003</year>
-   <holder>Douglas Gilbert</holder>
-  </copyright>
-
-  <legalnotice>
-   <para>
-     This documentation is free software; you can redistribute
-     it and/or modify it under the terms of the GNU General Public
-     License as published by the Free Software Foundation; either
-     version 2 of the License, or (at your option) any later
-     version.
-   </para>
-      
-   <para>
-     This program is distributed in the hope that it will be
-     useful, but WITHOUT ANY WARRANTY; without even the implied
-     warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-     See the GNU General Public License for more details.
-   </para>
-      
-   <para>
-     You should have received a copy of the GNU General Public
-     License along with this program; if not, write to the Free
-     Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
-     MA 02111-1307 USA
-   </para>
-      
-   <para>
-     For more details see the file COPYING in the source
-     distribution of Linux.
-   </para>
-  </legalnotice>
-
- </bookinfo>
-
-<toc></toc>
-
-  <chapter id="intro">
-      <title>Introduction</title>
-  <para>
-This document outlines the interface between the Linux scsi mid level
-and lower level drivers. Lower level drivers are variously called HBA
-(host bus adapter) drivers, host drivers (HD) or pseudo adapter drivers.
-The latter alludes to the fact that a lower level driver may be a
-bridge to another IO subsystem (and the "ide-scsi" driver is an example
-of this). There can be many lower level drivers active in a running
-system, but only one per hardware type. For example, the aic7xxx driver
-controls adaptec controllers based on the 7xxx chip series. Most lower
-level drivers can control one or more scsi hosts (a.k.a. scsi initiators).
-  </para>
-<para>
-This document can been found in an ASCII text file in the linux kernel 
-source: <filename>Documentation/scsi/scsi_mid_low_api.txt</filename> .
-It currently hold a little more information than this document. The
-<filename>drivers/scsi/hosts.h</filename> and <filename>
-drivers/scsi/scsi.h</filename> headers contain descriptions of members
-of important structures for the scsi subsystem.
-</para>
-  </chapter>
-
-  <chapter id="driver-struct">
-      <title>Driver structure</title>
-  <para>
-Traditionally a lower level driver for the scsi subsystem has been
-at least two files in the drivers/scsi directory. For example, a
-driver called "xyz" has a header file "xyz.h" and a source file
-"xyz.c". [Actually there is no good reason why this couldn't all
-be in one file.] Some drivers that have been ported to several operating
-systems (e.g. aic7xxx which has separate  files for generic and
-OS-specific code) have more than two files. Such drivers tend to have
-their own directory under the drivers/scsi directory.
-  </para>
-  <para>
-scsi_module.c is normally included at the end of a lower
-level driver. For it to work a declaration like this is needed before
-it is included:
-<programlisting>
-    static Scsi_Host_Template driver_template = DRIVER_TEMPLATE;
-    /* DRIVER_TEMPLATE should contain pointers to supported interface
-       functions. Scsi_Host_Template is defined hosts.h */
-    #include "scsi_module.c"
-</programlisting>
-  </para>
-  <para>
-The scsi_module.c assumes the name "driver_template" is appropriately
-defined. It contains 2 functions:
-<orderedlist>
-<listitem><para>
-     init_this_scsi_driver() called during builtin and module driver
-     initialization: invokes mid level's scsi_register_host()
-</para></listitem>
-<listitem><para>
-     exit_this_scsi_driver() called during closedown: invokes
-     mid level's scsi_unregister_host()
-</para></listitem>
-</orderedlist>
-  </para>
-<para>
-When a new, lower level driver is being added to Linux, the following 
-files (all found in the drivers/scsi directory) will need some attention: 
-Makefile, Config.help and Config.in . It is probably best to look at what 
-an existing lower level driver does in this regard.
-</para>
-  </chapter>
-
-  <chapter id="intfunctions">
-     <title>Interface Functions</title>
-!EDocumentation/scsi/scsi_mid_low_api.txt
-  </chapter>
-
-  <chapter id="locks">
-     <title>Locks</title>
-<para>
-Each Scsi_Host instance has a spin_lock called Scsi_Host::default_lock
-which is initialized in scsi_register() [found in hosts.c]. Within the
-same function the Scsi_Host::host_lock pointer is initialized to point
-at default_lock with the scsi_assign_lock() function. Thereafter
-lock and unlock operations performed by the mid level use the
-Scsi_Host::host_lock pointer.
-</para>
-<para>
-Lower level drivers can override the use of Scsi_Host::default_lock by
-using scsi_assign_lock(). The earliest opportunity to do this would
-be in the detect() function after it has invoked scsi_register(). It
-could be replaced by a coarser grain lock (e.g. per driver) or a
-lock of equal granularity (i.e. per host). Using finer grain locks
-(e.g. per scsi device) may be possible by juggling locks in
-queuecommand().
-</para>
-  </chapter>
-
-  <chapter id="changes">
-     <title>Changes since lk 2.4 series</title>
-<para>
-io_request_lock has been replaced by several finer grained locks. The lock
-relevant to lower level drivers is Scsi_Host::host_lock and there is one
-per scsi host.
-</para>
-<para>
-The older error handling mechanism has been removed. This means the
-lower level interface functions abort() and reset() have been removed.
-</para>
-<para>
-In the 2.4 series the scsi subsystem configuration descriptions were
-aggregated with the configuration descriptions from all other Linux
-subsystems in the Documentation/Configure.help file. In the 2.5 series,
-the scsi subsystem now has its own (much smaller) drivers/scsi/Config.help
-file.
-</para>
-  </chapter>
-
-  <chapter id="credits">
-     <title>Credits</title>
-<para>
-The following people have contributed to this document:
-<orderedlist>
-<listitem><para>
-Mike Anderson <email>andmike@us.ibm.com</email>
-</para></listitem>
-<listitem><para>
-James Bottomley <email>James.Bottomley@steeleye.com</email>
-</para></listitem>
-<listitem><para>
-Patrick Mansfield <email>patmans@us.ibm.com</email>
-</para></listitem>
-</orderedlist>
-</para>
-  </chapter>
-
-</book>
diff --git a/Documentation/DocBook/stylesheet.xsl b/Documentation/DocBook/stylesheet.xsl
--- a/Documentation/DocBook/stylesheet.xsl
+++ b/Documentation/DocBook/stylesheet.xsl
@@ -2,4 +2,5 @@
 <stylesheet xmlns="http://www.w3.org/1999/XSL/Transform" version="1.0">
 <param name="chunk.quietly">1</param>
 <param name="funcsynopsis.style">ansi</param>
+<param name="funcsynopsis.tabular.threshold">80</param>
 </stylesheet>
diff --git a/Documentation/IPMI.txt b/Documentation/IPMI.txt
--- a/Documentation/IPMI.txt
+++ b/Documentation/IPMI.txt
@@ -25,9 +25,10 @@ subject and I can't cover it all here!
 Configuration
 -------------
 
-The LinuxIPMI driver is modular, which means you have to pick several
+The Linux IPMI driver is modular, which means you have to pick several
 things to have it work right depending on your hardware.  Most of
-these are available in the 'Character Devices' menu.
+these are available in the 'Character Devices' menu then the IPMI
+menu.
 
 No matter what, you must pick 'IPMI top-level message handler' to use
 IPMI.  What you do beyond that depends on your needs and hardware.
@@ -35,33 +36,30 @@ IPMI.  What you do beyond that depends o
 The message handler does not provide any user-level interfaces.
 Kernel code (like the watchdog) can still use it.  If you need access
 from userland, you need to select 'Device interface for IPMI' if you
-want access through a device driver.  Another interface is also
-available, you may select 'IPMI sockets' in the 'Networking Support'
-main menu.  This provides a socket interface to IPMI.  You may select
-both of these at the same time, they will both work together.
-
-The driver interface depends on your hardware.  If you have a board
-with a standard interface (These will generally be either "KCS",
-"SMIC", or "BT", consult your hardware manual), choose the 'IPMI SI
-handler' option.  A driver also exists for direct I2C access to the
-IPMI management controller.  Some boards support this, but it is
-unknown if it will work on every board.  For this, choose 'IPMI SMBus
-handler', but be ready to try to do some figuring to see if it will
-work.
+want access through a device driver.
 
-There is also a KCS-only driver interface supplied, but it is
-depracated in favor of the SI interface.
+The driver interface depends on your hardware.  If your system
+properly provides the SMBIOS info for IPMI, the driver will detect it
+and just work.  If you have a board with a standard interface (These
+will generally be either "KCS", "SMIC", or "BT", consult your hardware
+manual), choose the 'IPMI SI handler' option.  A driver also exists
+for direct I2C access to the IPMI management controller.  Some boards
+support this, but it is unknown if it will work on every board.  For
+this, choose 'IPMI SMBus handler', but be ready to try to do some
+figuring to see if it will work on your system if the SMBIOS/APCI
+information is wrong or not present.  It is fairly safe to have both
+these enabled and let the drivers auto-detect what is present.
 
 You should generally enable ACPI on your system, as systems with IPMI
-should have ACPI tables describing them.
+can have ACPI tables describing them.
 
 If you have a standard interface and the board manufacturer has done
 their job correctly, the IPMI controller should be automatically
-detect (via ACPI or SMBIOS tables) and should just work.  Sadly, many
-boards do not have this information.  The driver attempts standard
-defaults, but they may not work.  If you fall into this situation, you
-need to read the section below named 'The SI Driver' on how to
-hand-configure your system.
+detected (via ACPI or SMBIOS tables) and should just work.  Sadly,
+many boards do not have this information.  The driver attempts
+standard defaults, but they may not work.  If you fall into this
+situation, you need to read the section below named 'The SI Driver' or
+"The SMBus Driver" on how to hand-configure your system.
 
 IPMI defines a standard watchdog timer.  You can enable this with the
 'IPMI Watchdog Timer' config option.  If you compile the driver into
@@ -73,6 +71,18 @@ closed (by default it is disabled on clo
 Cards' menu, enable 'Watchdog Timer Support', and enable the option
 'Disable watchdog shutdown on close'.
 
+IPMI systems can often be powered off using IPMI commands.  Select
+'IPMI Poweroff' to do this.  The driver will auto-detect if the system
+can be powered off by IPMI.  It is safe to enable this even if your
+system doesn't support this option.  This works on ATCA systems, the
+Radisys CPI1 card, and any IPMI system that supports standard chassis
+management commands.
+
+If you want the driver to put an event into the event log on a panic,
+enable the 'Generate a panic event to all BMCs on a panic' option.  If
+you want the whole panic string put into the event log using OEM
+events, enable the 'Generate OEM events containing the panic string'
+option.
 
 Basic Design
 ------------
@@ -80,7 +90,7 @@ Basic Design
 The Linux IPMI driver is designed to be very modular and flexible, you
 only need to take the pieces you need and you can use it in many
 different ways.  Because of that, it's broken into many chunks of
-code.  These chunks are:
+code.  These chunks (by module name) are:
 
 ipmi_msghandler - This is the central piece of software for the IPMI
 system.  It handles all messages, message timing, and responses.  The
@@ -93,18 +103,26 @@ ipmi_devintf - This provides a userland 
 driver, each open file for this device ties in to the message handler
 as an IPMI user.
 
-ipmi_si - A driver for various system interfaces.  This supports
-KCS, SMIC, and may support BT in the future.  Unless you have your own
-custom interface, you probably need to use this.
+ipmi_si - A driver for various system interfaces.  This supports KCS,
+SMIC, and BT interfaces.  Unless you have an SMBus interface or your
+own custom interface, you probably need to use this.
 
 ipmi_smb - A driver for accessing BMCs on the SMBus. It uses the
 I2C kernel driver's SMBus interfaces to send and receive IPMI messages
 over the SMBus.
 
-af_ipmi - A network socket interface to IPMI.  This doesn't take up
-a character device in your system.
-
-Note that the KCS-only interface ahs been removed.
+ipmi_watchdog - IPMI requires systems to have a very capable watchdog
+timer.  This driver implements the standard Linux watchdog timer
+interface on top of the IPMI message handler.
+
+ipmi_poweroff - Some systems support the ability to be turned off via
+IPMI commands.
+
+These are all individually selectable via configuration options.
+
+Note that the KCS-only interface has been removed.  The af_ipmi driver
+is no longer supported and has been removed because it was impossible
+to do 32 bit emulation on 64-bit kernels with it.
 
 Much documentation for the interface is in the include files.  The
 IPMI include files are:
@@ -424,7 +442,7 @@ at module load time (for a module) with:
   modprobe ipmi_smb.o
 	addr=<adapter1>,<i2caddr1>[,<adapter2>,<i2caddr2>[,...]]
 	dbg=<flags1>,<flags2>...
-	[defaultprobe=0] [dbg_probe=1]
+	[defaultprobe=1] [dbg_probe=1]
 
 The addresses are specified in pairs, the first is the adapter ID and the
 second is the I2C address on that adapter.
@@ -532,3 +550,67 @@ Once you open the watchdog timer, you mu
 device to close it, or the timer will not stop.  This is a new semantic
 for the driver, but makes it consistent with the rest of the watchdog
 drivers in Linux.
+
+
+Panic Timeouts
+--------------
+
+The OpenIPMI driver supports the ability to put semi-custom and custom
+events in the system event log if a panic occurs.  if you enable the
+'Generate a panic event to all BMCs on a panic' option, you will get
+one event on a panic in a standard IPMI event format.  If you enable
+the 'Generate OEM events containing the panic string' option, you will
+also get a bunch of OEM events holding the panic string.
+
+
+The field settings of the events are:
+* Generator ID: 0x21 (kernel)
+* EvM Rev: 0x03 (this event is formatting in IPMI 1.0 format)
+* Sensor Type: 0x20 (OS critical stop sensor)
+* Sensor #: The first byte of the panic string (0 if no panic string)
+* Event Dir | Event Type: 0x6f (Assertion, sensor-specific event info)
+* Event Data 1: 0xa1 (Runtime stop in OEM bytes 2 and 3)
+* Event data 2: second byte of panic string
+* Event data 3: third byte of panic string
+See the IPMI spec for the details of the event layout.  This event is
+always sent to the local management controller.  It will handle routing
+the message to the right place
+
+Other OEM events have the following format:
+Record ID (bytes 0-1): Set by the SEL.
+Record type (byte 2): 0xf0 (OEM non-timestamped)
+byte 3: The slave address of the card saving the panic
+byte 4: A sequence number (starting at zero)
+The rest of the bytes (11 bytes) are the panic string.  If the panic string
+is longer than 11 bytes, multiple messages will be sent with increasing
+sequence numbers.
+
+Because you cannot send OEM events using the standard interface, this
+function will attempt to find an SEL and add the events there.  It
+will first query the capabilities of the local management controller.
+If it has an SEL, then they will be stored in the SEL of the local
+management controller.  If not, and the local management controller is
+an event generator, the event receiver from the local management
+controller will be queried and the events sent to the SEL on that
+device.  Otherwise, the events go nowhere since there is nowhere to
+send them.
+
+
+Poweroff
+--------
+
+If the poweroff capability is selected, the IPMI driver will install
+a shutdown function into the standard poweroff function pointer.  This
+is in the ipmi_poweroff module.  When the system requests a powerdown,
+it will send the proper IPMI commands to do this.  This is supported on
+several platforms.
+
+There is a module parameter named "poweroff_control" that may either be zero
+(do a power down) or 2 (do a power cycle, power the system off, then power
+it on in a few seconds).  Setting ipmi_poweroff.poweroff_control=x will do
+the same thing on the kernel command line.  The parameter is also available
+via the proc filesystem in /proc/ipmi/poweroff_control.  Note that if the
+system does not support power cycling, it will always to the power off.
+
+Note that if you have ACPI enabled, the system will prefer using ACPI to
+power off.
diff --git a/Documentation/SubmittingDrivers b/Documentation/SubmittingDrivers
--- a/Documentation/SubmittingDrivers
+++ b/Documentation/SubmittingDrivers
@@ -13,13 +13,14 @@ Allocating Device Numbers
 -------------------------
 
 Major and minor numbers for block and character devices are allocated
-by the Linux assigned name and number authority (currently better
-known as H Peter Anvin). The site is http://www.lanana.org/. This
+by the Linux assigned name and number authority (currently this is
+Torben Mathiasen). The site is http://www.lanana.org/. This
 also deals with allocating numbers for devices that are not going to
 be submitted to the mainstream kernel.
+See Documentation/devices.txt for more information on this.
 
-If you don't use assigned numbers then when you device is submitted it will
-get given an assigned number even if that is different from values you may
+If you don't use assigned numbers then when your device is submitted it will
+be given an assigned number even if that is different from values you may
 have shipped to customers before.
 
 Who To Submit Drivers To
@@ -32,7 +33,8 @@ Linux 2.2:
 	If the code area has a general maintainer then please submit it to
 	the maintainer listed in MAINTAINERS in the kernel file. If the
 	maintainer does not respond or you cannot find the appropriate
-	maintainer then please contact Alan Cox <alan@lxorguk.ukuu.org.uk>
+	maintainer then please contact the 2.2 kernel maintainer:
+	Marc-Christian Petersen <m.c.p@wolk-project.de>.
 
 Linux 2.4:
 	The same rules apply as 2.2. The final contact point for Linux 2.4
@@ -48,7 +50,7 @@ What Criteria Determine Acceptance
 
 Licensing:	The code must be released to us under the
 		GNU General Public License. We don't insist on any kind
-		of exclusively GPL licensing, and if you wish the driver
+		of exclusive GPL licensing, and if you wish the driver
 		to be useful to other communities such as BSD you may well
 		wish to release under multiple licenses.
 
diff --git a/Documentation/SubmittingPatches b/Documentation/SubmittingPatches
--- a/Documentation/SubmittingPatches
+++ b/Documentation/SubmittingPatches
@@ -35,7 +35,7 @@ not in any lower subdirectory.
 
 To create a patch for a single file, it is often sufficient to do:
 
-	SRCTREE= linux-2.4
+	SRCTREE= linux-2.6
 	MYFILE=  drivers/net/mydriver.c
 
 	cd $SRCTREE
@@ -48,17 +48,18 @@ To create a patch for multiple files, yo
 or unmodified kernel source tree, and generate a diff against your
 own source tree.  For example:
 
-	MYSRC= /devel/linux-2.4
+	MYSRC= /devel/linux-2.6
 
-	tar xvfz linux-2.4.0-test11.tar.gz
-	mv linux linux-vanilla
-	wget http://www.moses.uklinux.net/patches/dontdiff
-	diff -uprN -X dontdiff linux-vanilla $MYSRC > /tmp/patch
-	rm -f dontdiff
+	tar xvfz linux-2.6.12.tar.gz
+	mv linux-2.6.12 linux-2.6.12-vanilla
+	diff -uprN -X linux-2.6.12-vanilla/Documentation/dontdiff \
+		linux-2.6.12-vanilla $MYSRC > /tmp/patch
 
 "dontdiff" is a list of files which are generated by the kernel during
 the build process, and should be ignored in any diff(1)-generated
-patch.  dontdiff is maintained by Tigran Aivazian <tigran@veritas.com>
+patch.  The "dontdiff" file is included in the kernel tree in
+2.6.12 and later.  For earlier kernel versions, you can get it
+from <http://www.xenotime.net/linux/doc/dontdiff>.
 
 Make sure your patch does not include any extra files which do not
 belong in a patch submission.  Make sure to review your patch -after-
@@ -66,18 +67,20 @@ generated it with diff(1), to ensure acc
 
 If your changes produce a lot of deltas, you may want to look into
 splitting them into individual patches which modify things in
-logical stages, this will facilitate easier reviewing by other
+logical stages.  This will facilitate easier reviewing by other
 kernel developers, very important if you want your patch accepted.
-There are a number of scripts which can aid in this;
+There are a number of scripts which can aid in this:
 
 Quilt:
 http://savannah.nongnu.org/projects/quilt
 
 Randy Dunlap's patch scripts:
-http://developer.osdl.org/rddunlap/scripts/patching-scripts.tgz
+http://www.xenotime.net/linux/scripts/patching-scripts-002.tar.gz
 
 Andrew Morton's patch scripts:
-http://www.zip.com.au/~akpm/linux/patches/patch-scripts-0.16
+http://www.zip.com.au/~akpm/linux/patches/patch-scripts-0.20
+
+
 
 2) Describe your changes.
 
@@ -132,21 +135,6 @@ which require discussion or do not have 
 usually be sent first to linux-kernel.  Only after the patch is
 discussed should the patch then be submitted to Linus.
 
-For small patches you may want to CC the Trivial Patch Monkey
-trivial@rustcorp.com.au set up by Rusty Russell; which collects "trivial"
-patches. Trivial patches must qualify for one of the following rules:
- Spelling fixes in documentation
- Spelling fixes which could break grep(1).
- Warning fixes (cluttering with useless warnings is bad)
- Compilation fixes (only if they are actually correct)
- Runtime fixes (only if they actually fix things)
- Removing use of deprecated functions/macros (eg. check_region).
- Contact detail and documentation fixes
- Non-portable code replaced by portable code (even in arch-specific,
- since people copy, as long as it's trivial)
- Any fix by the author/maintainer of the file. (ie. patch monkey
- in re-transmission mode)
-
 
 
 5) Select your CC (e-mail carbon copy) list.
@@ -161,6 +149,11 @@ USB, framebuffer devices, the VFS, the S
 MAINTAINERS file for a mailing list that relates specifically to
 your change.
 
+If changes affect userland-kernel interfaces, please send
+the MAN-PAGES maintainer (as listed in the MAINTAINERS file)
+a man-pages patch, or at least a notification of the change,
+so that some information makes its way into the manual pages.
+
 Even if the maintainer did not respond in step #4, make sure to ALWAYS
 copy the maintainer when you change their code.
 
@@ -178,6 +171,8 @@ patches. Trivial patches must qualify fo
  since people copy, as long as it's trivial)
  Any fix by the author/maintainer of the file. (ie. patch monkey
  in re-transmission mode)
+URL: <http://www.kernel.org/pub/linux/kernel/people/rusty/trivial/>
+
 
 
 
@@ -299,13 +294,24 @@ can certify the below:
 
 then you just add a line saying
 
-	Signed-off-by: Random J Developer <random@developer.org>
+	Signed-off-by: Random J Developer <random@developer.example.org>
 
 Some people also put extra tags at the end.  They'll just be ignored for
 now, but you can do this to mark internal company procedures or just
 point out some special detail about the sign-off. 
 
 
+
+12) More references for submitting patches
+
+Andrew Morton, "The perfect patch" (tpp).
+  <http://www.zip.com.au/~akpm/linux/patches/stuff/tpp.txt>
+
+Jeff Garzik, "Linux kernel patch submission format."
+  <http://linux.yyz.us/patch-format.html>
+
+
+
 -----------------------------------
 SECTION 2 - HINTS, TIPS, AND TRICKS
 -----------------------------------
@@ -374,7 +380,5 @@ and 'extern __inline__'.
 4) Don't over-design.
 
 Don't try to anticipate nebulous future cases which may or may not
-be useful:  "Make it as simple as you can, and no simpler"
-
-
+be useful:  "Make it as simple as you can, and no simpler."
 
diff --git a/Documentation/acpi-hotkey.txt b/Documentation/acpi-hotkey.txt
new file mode 100644
--- /dev/null
+++ b/Documentation/acpi-hotkey.txt
@@ -0,0 +1,38 @@
+driver/acpi/hotkey.c implement:
+1. /proc/acpi/hotkey/event_config 
+(event based hotkey or event config interface):
+a. add a  event based hotkey(event) : 
+echo "0:bus::action:method:num:num" > event_config
+
+b. delete a event based hotkey(event): 
+echo "1:::::num:num" > event_config
+
+c.  modify a event based hotkey(event):    
+echo "2:bus::action:method:num:num" > event_config
+
+2. /proc/acpi/hotkey/poll_config 
+(polling based hotkey or event config interface):
+a.add a polling based hotkey(event) : 	
+echo "0:bus:method:action:method:num" > poll_config
+this adding command will create a proc file 
+/proc/acpi/hotkey/method, which is used to get 
+result of polling.
+
+b.delete a polling based hotkey(event): 	
+echo "1:::::num" > event_config
+
+c.modify a polling based hotkey(event):    
+echo "2:bus:method:action:method:num" > poll_config
+
+3./proc/acpi/hotkey/action 
+(interface to call aml method associated with a 
+specific hotkey(event))
+echo "event_num:event_type:event_argument" > 
+	/proc/acpi/hotkey/action.
+The result of the execution of this aml method is 
+attached to /proc/acpi/hotkey/poll_method, which is dnyamically
+created.  Please use command "cat /proc/acpi/hotkey/polling_method" 
+to retrieve it.
+
+Note: Use cmdline "acpi_generic_hotkey" to over-ride
+loading any platform specific drivers.
diff --git a/Documentation/arm/Samsung-S3C24XX/USB-Host.txt b/Documentation/arm/Samsung-S3C24XX/USB-Host.txt
new file mode 100644
--- /dev/null
+++ b/Documentation/arm/Samsung-S3C24XX/USB-Host.txt
@@ -0,0 +1,93 @@
+			S3C24XX USB Host support
+			========================
+
+
+
+Introduction
+------------
+
+  This document details the S3C2410/S3C2440 in-built OHCI USB host support.
+
+Configuration
+-------------
+
+  Enable at least the following kernel options:
+
+  menuconfig:
+
+   Device Drivers  --->
+     USB support  --->
+       <*> Support for Host-side USB
+       <*>   OHCI HCD support
+
+
+  .config:
+    CONFIG_USB
+    CONFIG_USB_OHCI_HCD
+
+
+  Once these options are configured, the standard set of USB device
+  drivers can be configured and used.
+
+
+Board Support
+-------------
+
+  The driver attaches to a platform device, which will need to be
+  added by the board specific support file in linux/arch/arm/mach-s3c2410,
+  such as mach-bast.c or mach-smdk2410.c
+
+  The platform device's platform_data field is only needed if the
+  board implements extra power control or over-current monitoring.
+
+  The OHCI driver does not ensure the state of the S3C2410's MISCCTRL
+  register, so if both ports are to be used for the host, then it is
+  the board support file's responsibility to ensure that the second
+  port is configured to be connected to the OHCI core.
+
+
+Platform Data
+-------------
+
+  See linux/include/asm-arm/arch-s3c2410/usb-control.h for the
+  descriptions of the platform device data. An implementation
+  can be found in linux/arch/arm/mach-s3c2410/usb-simtec.c .
+
+  The `struct s3c2410_hcd_info` contains a pair of functions
+  that get called to enable over-current detection, and to
+  control the port power status.
+
+  The ports are numbered 0 and 1.
+
+  power_control:
+
+    Called to enable or disable the power on the port.
+
+  enable_oc:
+
+    Called to enable or disable the over-current monitoring.
+    This should claim or release the resources being used to
+    check the power condition on the port, such as an IRQ.
+
+  report_oc:
+
+    The OHCI driver fills this field in for the over-current code
+    to call when there is a change to the over-current state on
+    an port. The ports argument is a bitmask of 1 bit per port,
+    with bit X being 1 for an over-current on port X.
+
+    The function s3c2410_usb_report_oc() has been provided to
+    ensure this is called correctly.
+
+  port[x]:
+
+    This is struct describes each port, 0 or 1. The platform driver
+    should set the flags field of each port to S3C_HCDFLG_USED if
+    the port is enabled.
+
+
+
+Document Author
+---------------
+
+Ben Dooks, (c) 2005 Simtec Electronics
diff --git a/Documentation/basic_profiling.txt b/Documentation/basic_profiling.txt
--- a/Documentation/basic_profiling.txt
+++ b/Documentation/basic_profiling.txt
@@ -27,9 +27,13 @@ dump output	readprofile -m /boot/System.
 
 Oprofile
 --------
-Get the source (I use 0.8) from http://oprofile.sourceforge.net/
-and add "idle=poll" to the kernel command line
+
+Get the source (see Changes for required version) from
+http://oprofile.sourceforge.net/ and add "idle=poll" to the kernel command
+line.
+
 Configure with CONFIG_PROFILING=y and CONFIG_OPROFILE=y & reboot on new kernel
+
 ./configure --with-kernel-support
 make install
 
@@ -46,7 +50,7 @@ start		opcontrol --start
 stop		opcontrol --stop
 dump output	opreport >  output_file
 
-To only report on the kernel, run opreport /boot/vmlinux > output_file
+To only report on the kernel, run opreport -l /boot/vmlinux > output_file
 
 A reset is needed to clear old statistics, which survive a reboot.
 
diff --git a/Documentation/block/ioprio.txt b/Documentation/block/ioprio.txt
new file mode 100644
--- /dev/null
+++ b/Documentation/block/ioprio.txt
@@ -0,0 +1,176 @@
+Block io priorities
+===================
+
+
+Intro
+-----
+
+With the introduction of cfq v3 (aka cfq-ts or time sliced cfq), basic io
+priorities is supported for reads on files. This enables users to io nice
+processes or process groups, similar to what has been possible to cpu
+scheduling for ages. This document mainly details the current possibilites
+with cfq, other io schedulers do not support io priorities so far.
+
+Scheduling classes
+------------------
+
+CFQ implements three generic scheduling classes that determine how io is
+served for a process.
+
+IOPRIO_CLASS_RT: This is the realtime io class. This scheduling class is given
+higher priority than any other in the system, processes from this class are
+given first access to the disk every time. Thus it needs to be used with some
+care, one io RT process can starve the entire system. Within the RT class,
+there are 8 levels of class data that determine exactly how much time this
+process needs the disk for on each service. In the future this might change
+to be more directly mappable to performance, by passing in a wanted data
+rate instead.
+
+IOPRIO_CLASS_BE: This is the best-effort scheduling class, which is the default
+for any process that hasn't set a specific io priority. The class data
+determines how much io bandwidth the process will get, it's directly mappable
+to the cpu nice levels just more coarsely implemented. 0 is the highest
+BE prio level, 7 is the lowest. The mapping between cpu nice level and io
+nice level is determined as: io_nice = (cpu_nice + 20) / 5.
+
+IOPRIO_CLASS_IDLE: This is the idle scheduling class, processes running at this
+level only get io time when no one else needs the disk. The idle class has no
+class data, since it doesn't really apply here.
+
+Tools
+-----
+
+See below for a sample ionice tool. Usage:
+
+# ionice -c<class> -n<level> -p<pid>
+
+If pid isn't given, the current process is assumed. IO priority settings
+are inherited on fork, so you can use ionice to start the process at a given
+level:
+
+# ionice -c2 -n0 /bin/ls
+
+will run ls at the best-effort scheduling class at the highest priority.
+For a running process, you can give the pid instead:
+
+# ionice -c1 -n2 -p100
+
+will change pid 100 to run at the realtime scheduling class, at priority 2.
+
+---> snip ionice.c tool <---
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <getopt.h>
+#include <unistd.h>
+#include <sys/ptrace.h>
+#include <asm/unistd.h>
+
+extern int sys_ioprio_set(int, int, int);
+extern int sys_ioprio_get(int, int);
+
+#if defined(__i386__)
+#define __NR_ioprio_set		289
+#define __NR_ioprio_get		290
+#elif defined(__ppc__)
+#define __NR_ioprio_set		273
+#define __NR_ioprio_get		274
+#elif defined(__x86_64__)
+#define __NR_ioprio_set		251
+#define __NR_ioprio_get		252
+#elif defined(__ia64__)
+#define __NR_ioprio_set		1274
+#define __NR_ioprio_get		1275
+#else
+#error "Unsupported arch"
+#endif
+
+_syscall3(int, ioprio_set, int, which, int, who, int, ioprio);
+_syscall2(int, ioprio_get, int, which, int, who);
+
+enum {
+	IOPRIO_CLASS_NONE,
+	IOPRIO_CLASS_RT,
+	IOPRIO_CLASS_BE,
+	IOPRIO_CLASS_IDLE,
+};
+
+enum {
+	IOPRIO_WHO_PROCESS = 1,
+	IOPRIO_WHO_PGRP,
+	IOPRIO_WHO_USER,
+};
+
+#define IOPRIO_CLASS_SHIFT	13
+
+const char *to_prio[] = { "none", "realtime", "best-effort", "idle", };
+
+int main(int argc, char *argv[])
+{
+	int ioprio = 4, set = 0, ioprio_class = IOPRIO_CLASS_BE;
+	int c, pid = 0;
+
+	while ((c = getopt(argc, argv, "+n:c:p:")) != EOF) {
+		switch (c) {
+		case 'n':
+			ioprio = strtol(optarg, NULL, 10);
+			set = 1;
+			break;
+		case 'c':
+			ioprio_class = strtol(optarg, NULL, 10);
+			set = 1;
+			break;
+		case 'p':
+			pid = strtol(optarg, NULL, 10);
+			break;
+		}
+	}
+
+	switch (ioprio_class) {
+		case IOPRIO_CLASS_NONE:
+			ioprio_class = IOPRIO_CLASS_BE;
+			break;
+		case IOPRIO_CLASS_RT:
+		case IOPRIO_CLASS_BE:
+			break;
+		case IOPRIO_CLASS_IDLE:
+			ioprio = 7;
+			break;
+		default:
+			printf("bad prio class %d\n", ioprio_class);
+			return 1;
+	}
+
+	if (!set) {
+		if (!pid && argv[optind])
+			pid = strtol(argv[optind], NULL, 10);
+
+		ioprio = ioprio_get(IOPRIO_WHO_PROCESS, pid);
+
+		printf("pid=%d, %d\n", pid, ioprio);
+
+		if (ioprio == -1)
+			perror("ioprio_get");
+		else {
+			ioprio_class = ioprio >> IOPRIO_CLASS_SHIFT;
+			ioprio = ioprio & 0xff;
+			printf("%s: prio %d\n", to_prio[ioprio_class], ioprio);
+		}
+	} else {
+		if (ioprio_set(IOPRIO_WHO_PROCESS, pid, ioprio | ioprio_class << IOPRIO_CLASS_SHIFT) == -1) {
+			perror("ioprio_set");
+			return 1;
+		}
+
+		if (argv[optind])
+			execvp(argv[optind], &argv[optind]);
+	}
+
+	return 0;
+}
+
+---> snip ionice.c tool <---
+
+
+March 11 2005, Jens Axboe <axboe@suse.de>
diff --git a/Documentation/cciss.txt b/Documentation/cciss.txt
--- a/Documentation/cciss.txt
+++ b/Documentation/cciss.txt
@@ -17,6 +17,7 @@ This driver is known to work with the fo
 	* SA P600
 	* SA P800
 	* SA E400
+	* SA E300
 
 If nodes are not already created in the /dev/cciss directory, run as root:
 
diff --git a/Documentation/cdrom/sbpcd b/Documentation/cdrom/sbpcd
--- a/Documentation/cdrom/sbpcd
+++ b/Documentation/cdrom/sbpcd
@@ -419,6 +419,7 @@ into the file "track01":
  */
 #include <stdio.h>
 #include <sys/ioctl.h>
+#include <sys/types.h>
 #include <linux/cdrom.h>
 
 static struct cdrom_tochdr hdr;
@@ -429,7 +430,7 @@ static int datafile, drive;
 static int i, j, limit, track, err;
 static char filename[32];
 
-main(int argc, char *argv[])
+int main(int argc, char *argv[])
 {
 /*
  * open /dev/cdrom
@@ -516,6 +517,7 @@ entry[track+1].cdte_addr.lba=entry[track
 	}
       arg.addr.lba++;
     }
+    return 0;
 }
 /*===================== end program ========================================*/
 
@@ -564,15 +566,16 @@ Appendix -- the "cdtester" utility:
 #include <stdio.h>
 #include <malloc.h>
 #include <sys/ioctl.h>
+#include <sys/types.h>
 #include <linux/cdrom.h>
 
 #ifdef AZT_PRIVATE_IOCTLS
 #include <linux/../../drivers/cdrom/aztcd.h>
-#endif AZT_PRIVATE_IOCTLS
+#endif /* AZT_PRIVATE_IOCTLS */
 #ifdef SBP_PRIVATE_IOCTLS
 #include <linux/../../drivers/cdrom/sbpcd.h>
 #include <linux/fs.h>
-#endif SBP_PRIVATE_IOCTLS
+#endif /* SBP_PRIVATE_IOCTLS */
 
 struct cdrom_tochdr hdr;
 struct cdrom_tochdr tocHdr;
@@ -590,7 +593,7 @@ union
 	struct cdrom_msf msf;
 	unsigned char buf[CD_FRAMESIZE_RAW];
 } azt;
-#endif AZT_PRIVATE_IOCTLS
+#endif /* AZT_PRIVATE_IOCTLS */
 int i, i1, i2, i3, j, k;
 unsigned char sequence=0;
 unsigned char command[80];
@@ -738,7 +741,7 @@ void display(int size,unsigned char *buf
 	} 
 } 
 
-main(int argc, char *argv[])
+int main(int argc, char *argv[])
 {
 	printf("\nTesting tool for a CDROM driver's audio functions V0.1\n");
 	printf("(C) 1995 Eberhard Moenkeberg <emoenke@gwdg.de>\n");
@@ -1046,12 +1049,13 @@ main(int argc, char *argv[])
 			rc=ioctl(drive,CDROMAUDIOBUFSIZ,j);
 			printf("%d frames granted.\n",rc);
 			break;
-#endif SBP_PRIVATE_IOCTLS
+#endif /* SBP_PRIVATE_IOCTLS */
 		default:
 			printf("unknown command: \"%s\".\n",command);
 			break;
 		}
 	}
+	return 0;
 }
 /*==========================================================================*/
 
diff --git a/Documentation/cpu-freq/governors.txt b/Documentation/cpu-freq/governors.txt
--- a/Documentation/cpu-freq/governors.txt
+++ b/Documentation/cpu-freq/governors.txt
@@ -9,6 +9,7 @@
 
 
 		    Dominik Brodowski  <linux@brodo.de>
+            some additions and corrections by Nico Golde <nico@ngolde.de>
 
 
 
@@ -25,6 +26,7 @@ Contents:
 2.1  Performance
 2.2  Powersave
 2.3  Userspace
+2.4  Ondemand
 
 3.   The Governor Interface in the CPUfreq Core
 
@@ -86,7 +88,7 @@ highest frequency within the borders of 
 scaling_max_freq.
 
 
-2.1 Powersave
+2.2 Powersave
 -------------
 
 The CPUfreq governor "powersave" sets the CPU statically to the
@@ -94,7 +96,7 @@ lowest frequency within the borders of s
 scaling_max_freq.
 
 
-2.2 Userspace
+2.3 Userspace
 -------------
 
 The CPUfreq governor "userspace" allows the user, or any userspace
@@ -103,6 +105,14 @@ by making a sysfs file "scaling_setspeed
 directory.
 
 
+2.4 Ondemand
+------------
+
+The CPUfreq govenor "ondemand" sets the CPU depending on the
+current usage. To do this the CPU must have the capability to
+switch the frequency very fast.
+
+
 
 3. The Governor Interface in the CPUfreq Core
 =============================================
diff --git a/Documentation/cpusets.txt b/Documentation/cpusets.txt
--- a/Documentation/cpusets.txt
+++ b/Documentation/cpusets.txt
@@ -51,6 +51,14 @@ mems_allowed vector.
 
 If a cpuset is cpu or mem exclusive, no other cpuset, other than a direct
 ancestor or descendent, may share any of the same CPUs or Memory Nodes.
+A cpuset that is cpu exclusive has a sched domain associated with it.
+The sched domain consists of all cpus in the current cpuset that are not
+part of any exclusive child cpusets.
+This ensures that the scheduler load balacing code only balances
+against the cpus that are in the sched domain as defined above and not
+all of the cpus in the system. This removes any overhead due to
+load balancing code trying to pull tasks outside of the cpu exclusive
+cpuset only to be prevented by the tasks' cpus_allowed mask.
 
 User level code may create and destroy cpusets by name in the cpuset
 virtual file system, manage the attributes and permissions of these
@@ -84,6 +92,9 @@ This can be especially valuable on:
       and a database), or
     * NUMA systems running large HPC applications with demanding
       performance characteristics.
+    * Also cpu_exclusive cpusets are useful for servers running orthogonal
+      workloads such as RT applications requiring low latency and HPC
+      applications that are throughput sensitive
 
 These subsets, or "soft partitions" must be able to be dynamically
 adjusted, as the job mix changes, without impacting other concurrently
@@ -125,6 +136,8 @@ Cpusets extends these two mechanisms as 
  - A cpuset may be marked exclusive, which ensures that no other
    cpuset (except direct ancestors and descendents) may contain
    any overlapping CPUs or Memory Nodes.
+   Also a cpu_exclusive cpuset would be associated with a sched
+   domain.
  - You can list all the tasks (by pid) attached to any cpuset.
 
 The implementation of cpusets requires a few, simple hooks
@@ -136,6 +149,9 @@ into the rest of the kernel, none in per
    allowed in that tasks cpuset.
  - in sched.c migrate_all_tasks(), to keep migrating tasks within
    the CPUs allowed by their cpuset, if possible.
+ - in sched.c, a new API partition_sched_domains for handling
+   sched domain changes associated with cpu_exclusive cpusets
+   and related changes in both sched.c and arch/ia64/kernel/domain.c
  - in the mbind and set_mempolicy system calls, to mask the requested
    Memory Nodes by what's allowed in that tasks cpuset.
  - in page_alloc, to restrict memory to allowed nodes.
diff --git a/Documentation/devices.txt b/Documentation/devices.txt
--- a/Documentation/devices.txt
+++ b/Documentation/devices.txt
@@ -94,6 +94,7 @@ Your cooperation is appreciated.
 		  9 = /dev/urandom	Faster, less secure random number gen.
 		 10 = /dev/aio		Asyncronous I/O notification interface
 		 11 = /dev/kmsg		Writes to this come out as printk's
+		 12 = /dev/oldmem	Access to crash dump from kexec kernel
   1 block	RAM disk
 		  0 = /dev/ram0		First RAM disk
 		  1 = /dev/ram1		Second RAM disk
diff --git a/Documentation/dontdiff b/Documentation/dontdiff
--- a/Documentation/dontdiff
+++ b/Documentation/dontdiff
@@ -41,6 +41,7 @@ COPYING
 CREDITS
 CVS
 ChangeSet
+Image
 Kerntypes
 MODS.txt
 Module.symvers
@@ -103,6 +104,8 @@ logo_*.c
 logo_*_clut224.c
 logo_*_mono.c
 lxdialog
+mach-types
+mach-types.h
 make_times_h
 map
 maui_boot.h
@@ -111,6 +114,7 @@ mkdep
 mktables
 modpost
 modversions.h*
+offset.h
 offsets.h
 oui.c*
 parse.c*
diff --git a/Documentation/driver-model/device.txt b/Documentation/driver-model/device.txt
--- a/Documentation/driver-model/device.txt
+++ b/Documentation/driver-model/device.txt
@@ -76,6 +76,14 @@ driver_data:   Driver-specific data.
 
 platform_data: Platform data specific to the device.
 
+	       Example:  for devices on custom boards, as typical of embedded
+	       and SOC based hardware, Linux often uses platform_data to point
+	       to board-specific structures describing devices and how they
+	       are wired.  That can include what ports are available, chip
+	       variants, which GPIO pins act in what additional roles, and so
+	       on.  This shrinks the "Board Support Packages" (BSPs) and
+	       minimizes board-specific #ifdefs in drivers.
+
 current_state: Current power state of the device.
 
 saved_state:   Pointer to saved state of the device. This is usable by
diff --git a/Documentation/driver-model/driver.txt b/Documentation/driver-model/driver.txt
--- a/Documentation/driver-model/driver.txt
+++ b/Documentation/driver-model/driver.txt
@@ -5,21 +5,17 @@ struct device_driver {
         char                    * name;
         struct bus_type         * bus;
 
-        rwlock_t                lock;
-        atomic_t                refcount;
-
-        list_t                  bus_list;
+        struct completion	unloaded;
+        struct kobject		kobj;
         list_t                  devices;
 
-        struct driver_dir_entry dir;
+        struct module		*owner;
 
         int     (*probe)        (struct device * dev);
         int     (*remove)       (struct device * dev);
 
         int     (*suspend)      (struct device * dev, pm_message_t state, u32 level);
         int     (*resume)       (struct device * dev, u32 level);
-
-        void    (*release)      (struct device_driver * drv);
 };
 
 
@@ -51,7 +47,6 @@ being converted completely to the new mo
 static struct device_driver eepro100_driver = {
        .name		= "eepro100",
        .bus		= &pci_bus_type,
-       .devclass	= &ethernet_devclass,	/* when it's implemented */
        
        .probe		= eepro100_probe,
        .remove		= eepro100_remove,
@@ -85,7 +80,6 @@ static struct pci_driver eepro100_driver
        .driver	       = {
 		.name		= "eepro100",
 		.bus		= &pci_bus_type,
-		.devclass	= &ethernet_devclass,	/* when it's implemented */
 		.probe		= eepro100_probe,
 		.remove		= eepro100_remove,
 		.suspend	= eepro100_suspend,
@@ -166,27 +160,32 @@ Callbacks
 
 	int	(*probe)	(struct device * dev);
 
-probe is called to verify the existence of a certain type of
-hardware. This is called during the driver binding process, after the
-bus has verified that the device ID of a device matches one of the
-device IDs supported by the driver. 
-
-This callback only verifies that there actually is supported hardware
-present. It may allocate a driver-specific structure, but it should
-not do any initialization of the hardware itself. The device-specific
-structure may be stored in the device's driver_data field. 
-
-	int	(*init)		(struct device * dev);
-
-init is called during the binding stage. It is called after probe has
-successfully returned and the device has been registered with its
-class. It is responsible for initializing the hardware.
+The probe() entry is called in task context, with the bus's rwsem locked
+and the driver partially bound to the device.  Drivers commonly use
+container_of() to convert "dev" to a bus-specific type, both in probe()
+and other routines.  That type often provides device resource data, such
+as pci_dev.resource[] or platform_device.resources, which is used in
+addition to dev->platform_data to initialize the driver.
+
+This callback holds the driver-specific logic to bind the driver to a
+given device.  That includes verifying that the device is present, that
+it's a version the driver can handle, that driver data structures can
+be allocated and initialized, and that any hardware can be initialized.
+Drivers often store a pointer to their state with dev_set_drvdata().
+When the driver has successfully bound itself to that device, then probe()
+returns zero and the driver model code will finish its part of binding
+the driver to that device.
+
+A driver's probe() may return a negative errno value to indicate that
+the driver did not bind to this device, in which case it should have
+released all reasources it allocated.
 
 	int 	(*remove)	(struct device * dev);
 
-remove is called to dissociate a driver with a device. This may be
+remove is called to unbind a driver from a device. This may be
 called if a device is physically removed from the system, if the
-driver module is being unloaded, or during a reboot sequence. 
+driver module is being unloaded, during a reboot sequence, or
+in other cases.
 
 It is up to the driver to determine if the device is present or
 not. It should free any resources allocated specifically for the
diff --git a/Documentation/dvb/README.dibusb b/Documentation/dvb/README.dibusb
deleted file mode 100644
--- a/Documentation/dvb/README.dibusb
+++ /dev/null
@@ -1,285 +0,0 @@
-Documentation for dib3000* frontend drivers and dibusb device driver
-====================================================================
-
-Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de),
-
-dibusb and dib3000mb/mc drivers based on GPL code, which has
-
-Copyright (C) 2004 Amaury Demol for DiBcom (ademol@dibcom.fr)
-
-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, version 2.
-
-
-Supported devices USB1.1
-========================
-
-Produced and reselled by Twinhan:
----------------------------------
-- TwinhanDTV USB-Ter DVB-T Device (VP7041)
-	http://www.twinhan.com/product_terrestrial_3.asp
-
-- TwinhanDTV Magic Box (VP7041e)
-	http://www.twinhan.com/product_terrestrial_4.asp
-
-- HAMA DVB-T USB device
-	http://www.hama.de/portal/articleId*110620/action*2598
-
-- CTS Portable (Chinese Television System) (2)
-	http://www.2cts.tv/ctsportable/
-
-- Unknown USB DVB-T device with vendor ID Hyper-Paltek
-
-
-Produced and reselled by KWorld:
---------------------------------
-- KWorld V-Stream XPERT DTV DVB-T USB
-	http://www.kworld.com.tw/en/product/DVBT-USB/DVBT-USB.html
-
-- JetWay DTV DVB-T USB
-	http://www.jetway.com.tw/evisn/product/lcd-tv/DVT-USB/dtv-usb.htm
-
-- ADSTech Instant TV DVB-T USB
-	http://www.adstech.com/products/PTV-333/intro/PTV-333_intro.asp?pid=PTV-333
-
-
-Others:
--------
-- Ultima Electronic/Artec T1 USB TVBOX (AN2135, AN2235, AN2235 with Panasonic Tuner)
-	http://82.161.246.249/products-tvbox.html
-
-- Compro Videomate DVB-U2000 - DVB-T USB (2)
-	http://www.comprousa.com/products/vmu2000.htm
-
-- Grandtec USB DVB-T
-	http://www.grand.com.tw/
-
-- Avermedia AverTV DVBT USB (2)
-	http://www.avermedia.com/
-
-- DiBcom USB DVB-T reference device (non-public)
-
-
-Supported devices USB2.0
-========================
-- Twinhan MagicBox II (2)
-	http://www.twinhan.com/product_terrestrial_7.asp
-
-- Hanftek UMT-010 (1)
-	http://www.globalsources.com/si/6008819757082/ProductDetail/Digital-TV/product_id-100046529
-
-- Typhoon/Yakumo/HAMA DVB-T mobile USB2.0 (1)
-	http://www.yakumo.de/produkte/index.php?pid=1&ag=DVB-T
-
-- Artec T1 USB TVBOX (FX2) (2)
-
-- Hauppauge WinTV NOVA-T USB2
-	http://www.hauppauge.com/
-
-- KWorld/ADSTech Instant DVB-T USB2.0 (DiB3000M-B)
-
-- DiBcom USB2.0 DVB-T reference device (non-public)
-
-1) It is working almost.
-2) No test reports received yet.
-
-
-0. NEWS:
-  2005-02-11 - added support for the KWorld/ADSTech Instant DVB-T USB2.0. Thanks a lot to Joachim von Caron
-  2005-02-02 - added support for the Hauppauge Win-TV Nova-T USB2
-  2005-01-31 - distorted streaming is finally gone for USB1.1 devices
-  2005-01-13 - moved the mirrored pid_filter_table back to dvb-dibusb
-             - first almost working version for HanfTek UMT-010
-             - found out, that Yakumo/HAMA/Typhoon are predessors of the HanfTek UMT-010
-  2005-01-10 - refactoring completed, now everything is very delightful
-             - tuner quirks for some weird devices (Artec T1 AN2235 device has sometimes a
-               Panasonic Tuner assembled). Tunerprobing implemented. Thanks a lot to Gunnar Wittich.
-  2004-12-29 - after several days of struggling around bug of no returning URBs fixed.
-  2004-12-26 - refactored the dibusb-driver, splitted into separate files
-             - i2c-probing enabled
-  2004-12-06 - possibility for demod i2c-address probing
-             - new usb IDs (Compro,Artec)
-  2004-11-23 - merged changes from DiB3000MC_ver2.1
-             - revised the debugging
-             - possibility to deliver the complete TS for USB2.0
-  2004-11-21 - first working version of the dib3000mc/p frontend driver.
-  2004-11-12 - added additional remote control keys. Thanks to Uwe Hanke.
-  2004-11-07 - added remote control support. Thanks to David Matthews.
-  2004-11-05 - added support for a new devices (Grandtec/Avermedia/Artec)
-             - merged my changes (for dib3000mb/dibusb) to the FE_REFACTORING, because it became HEAD
-             - moved transfer control (pid filter, fifo control) from usb driver to frontend, it seems
-               better settled there (added xfer_ops-struct)
-             - created a common files for frontends (mc/p/mb)
-  2004-09-28 - added support for a new device (Unkown, vendor ID is Hyper-Paltek)
-  2004-09-20 - added support for a new device (Compro DVB-U2000), thanks
-               to Amaury Demol for reporting
-             - changed usb TS transfer method (several urbs, stopping transfer
-               before setting a new pid)
-  2004-09-13 - added support for a new device (Artec T1 USB TVBOX), thanks
-               to Christian Motschke for reporting
-  2004-09-05 - released the dibusb device and dib3000mb-frontend driver
-
-  (old news for vp7041.c)
-  2004-07-15 - found out, by accident, that the device has a TUA6010XS for
-               PLL
-  2004-07-12 - figured out, that the driver should also work with the
-               CTS Portable (Chinese Television System)
-  2004-07-08 - firmware-extraction-2.422-problem solved, driver is now working
-               properly with firmware extracted from 2.422
-			 - #if for 2.6.4 (dvb), compile issue
-			 - changed firmware handling, see vp7041.txt sec 1.1
-  2004-07-02 - some tuner modifications, v0.1, cleanups, first public
-  2004-06-28 - now using the dvb_dmx_swfilter_packets, everything
-               runs fine now
-  2004-06-27 - able to watch and switching channels (pre-alpha)
-             - no section filtering yet
-  2004-06-06 - first TS received, but kernel oops :/
-  2004-05-14 - firmware loader is working
-  2004-05-11 - start writing the driver
-
-1. How to use?
-NOTE: This driver was developed using Linux 2.6.6.,
-it is working with 2.6.7 and above.
-
-Linux 2.4.x support is not planned, but patches are very welcome.
-
-NOTE: I'm using Debian testing, so the following explaination (especially
-the hotplug-path) needn't match your system, but probably it will :).
-
-The driver is included in the kernel since Linux 2.6.10.
-
-1.1. Firmware
-
-The USB driver needs to download a firmware to start working.
-
-You can either use "get_dvb_firmware dibusb" to download the firmware or you
-can get it directly via
-
-for USB1.1 (AN2135)
-http://www.linuxtv.org/downloads/firmware/dvb-dibusb-5.0.0.11.fw
-
-for USB1.1 (AN2235) (a few Artec T1 devices)
-http://www.linuxtv.org/downloads/firmware/dvb-dibusb-an2235-1.fw
-
-for USB2.0 (FX2) Hauppauge, DiBcom
-http://www.linuxtv.org/downloads/firmware/dvb-dibusb-6.0.0.5.fw
-
-for USB2.0 ADSTech/Kworld USB2.0
-http://www.linuxtv.org/downloads/firmware/dvb-dibusb-adstech-usb2-1.fw
-
-for USB2.0 HanfTek
-http://www.linuxtv.org/downloads/firmware/dvb-dibusb-an2235-1.fw
-
-
-1.2. Compiling
-
-Since the driver is in the linux kernel, activating the driver in
-your favorite config-environment should sufficient. I recommend
-to compile the driver as module. Hotplug does the rest.
-
-1.3. Loading the drivers
-
-Hotplug is able to load the driver, when it is needed (because you plugged
-in the device).
-
-If you want to enable debug output, you have to load the driver manually and
-from withing the dvb-kernel cvs repository.
-
-first have a look, which debug level are available:
-
-modinfo dib3000mb
-modinfo dib3000-common
-modinfo dib3000mc
-modinfo dvb-dibusb
-
-modprobe dib3000-common debug=<level>
-modprobe dib3000mb debug=<level>
-modprobe dib3000mc debug=<level>
-modprobe dvb-dibusb debug=<level>
-
-should do the trick.
-
-When the driver is loaded successfully, the firmware file was in
-the right place and the device is connected, the "Power"-LED should be
-turned on.
-
-At this point you should be able to start a dvb-capable application. For myself
-I used mplayer, dvbscan, tzap and kaxtv, they are working. Using the device
-in vdr is working now also.
-
-2. Known problems and bugs
-
-- Don't remove the USB device while running an DVB application, your system will die.
-
-2.1. Adding support for devices
-
-It is not possible to determine the range of devices based on the DiBcom
-reference designs. This is because the reference design of DiBcom can be sold
-to thirds, without telling DiBcom (so done with the Twinhan VP7041 and
-the HAMA device).
-
-When you think you have a device like this and the driver does not recognizes it,
-please send the ****load*.inf and the ****cap*.inf of the Windows driver to me.
-
-Sometimes the Vendor or Product ID is identical to the ones of Twinhan, even
-though it is not a Twinhan device (e.g. HAMA), then please send me the name
-of the device. I will add it to this list in order to make this clear to
-others.
-
-If you are familar with C you can also add the VID and PID of the device to
-the dvb-dibusb-core.c-file and create a patch and send it over to me or to
-the linux-dvb mailing list, _after_ you have tried compiling and modprobing
-it.
-
-2.2. USB1.1 Bandwidth limitation
-
-Most of the currently supported devices are USB1.1 and thus they have a
-maximum bandwidth of about 5-6 MBit/s when connected to a USB2.0 hub.
-This is not enough for receiving the complete transport stream of a
-DVB-T channel (which can be about 16 MBit/s). Normally this is not a
-problem, if you only want to watch TV (this does not apply for HDTV),
-but watching a channel while recording another channel on the same
-frequency simply does not work very well. This applies to all USB1.1
-DVB-T devices, not just dibusb)
-
-Update: For the USB1.1 and VDR some work has been done (patches and comments
-are still very welcome). Maybe the problem is solved in the meantime because I
-now use the dmx_sw_filter function instead of dmx_sw_filter_packet. I hope the
-linux-dvb software filter is able to get the best of the garbled TS.
-
-The bug, where the TS is distorted by a heavy usage of the device is gone
-definitely. All dibusb-devices I was using (Twinhan, Kworld, DiBcom) are
-working like charm now with VDR. Sometimes I even was able to record a channel
-and watch another one.
-
-2.3. Comments
-
-Patches, comments and suggestions are very very welcome.
-
-3. Acknowledgements
-	Amaury Demol (ademol@dibcom.fr) and Francois Kanounnikoff from DiBcom for
-    providing specs, code and help, on which the dvb-dibusb, dib3000mb and
-    dib3000mc are based.
-
-   David Matthews for identifying a new device type (Artec T1 with AN2235)
-    and for extending dibusb with remote control event handling. Thank you.
-
-   Alex Woods for frequently answering question about usb and dvb
-    stuff, a big thank you.
-
-   Bernd Wagner for helping with huge bug reports and discussions.
-
-   Gunnar Wittich and Joachim von Caron for their trust for giving me
-    root-shells on their machines to implement support for new devices.
-
-   Some guys on the linux-dvb mailing list for encouraging me
-
-   Peter Schildmann >peter.schildmann-nospam-at-web.de< for his
-    user-level firmware loader, which saves a lot of time
-    (when writing the vp7041 driver)
-
-   Ulf Hermenau for helping me out with traditional chinese.
-
-   André Smoktun and Christian Frömmel for supporting me with
-    hardware and listening to my problems very patient
diff --git a/Documentation/dvb/README.dvb-usb b/Documentation/dvb/README.dvb-usb
new file mode 100644
--- /dev/null
+++ b/Documentation/dvb/README.dvb-usb
@@ -0,0 +1,232 @@
+Documentation for dvb-usb-framework module and its devices
+
+Idea behind the dvb-usb-framework
+=================================
+
+In March 2005 I got the new Twinhan USB2.0 DVB-T device. They provided specs and a firmware.
+
+Quite keen I wanted to put the driver (with some quirks of course) into dibusb.
+After reading some specs and doing some USB snooping, it realized, that the
+dibusb-driver would be a complete mess afterwards. So I decided to do it in a
+different way: With the help of a dvb-usb-framework.
+
+The framework provides generic functions (mostly kernel API calls), such as:
+
+- Transport Stream URB handling in conjunction with dvb-demux-feed-control
+  (bulk and isoc are supported)
+- registering the device for the DVB-API
+- registering an I2C-adapter if applicable
+- remote-control/input-device handling
+- firmware requesting and loading (currently just for the Cypress USB
+  controllers)
+- other functions/methods which can be shared by several drivers (such as
+  functions for bulk-control-commands)
+- TODO: a I2C-chunker. It creates device-specific chunks of register-accesses
+  depending on length of a register and the number of values that can be
+  multi-written and multi-read.
+
+The source code of the particular DVB USB devices does just the communication
+with the device via the bus. The connection between the DVB-API-functionality
+is done via callbacks, assigned in a static device-description (struct
+dvb_usb_device) each device-driver has to have.
+
+For an example have a look in drivers/media/dvb/dvb-usb/vp7045*.
+
+Objective is to migrate all the usb-devices (dibusb, cinergyT2, maybe the
+ttusb; flexcop-usb already benefits from the generic flexcop-device) to use
+the dvb-usb-lib.
+
+TODO: dynamic enabling and disabling of the pid-filter in regard to number of
+feeds requested.
+
+Supported devices
+========================
+
+See the LinuxTV DVB Wiki at www.linuxtv.org for a complete list of
+cards/drivers/firmwares:
+
+http://www.linuxtv.org/wiki/index.php/DVB_USB
+
+0. History & News:
+  2005-06-30 - added support for WideView WT-220U (Thanks to Steve Chang)
+  2005-05-30 - added basic isochronous support to the dvb-usb-framework
+               added support for Conexant Hybrid reference design and Nebula DigiTV USB
+  2005-04-17 - all dibusb devices ported to make use of the dvb-usb-framework
+  2005-04-02 - re-enabled and improved remote control code.
+  2005-03-31 - ported the Yakumo/Hama/Typhoon DVB-T USB2.0 device to dvb-usb.
+  2005-03-30 - first commit of the dvb-usb-module based on the dibusb-source. First device is a new driver for the
+               TwinhanDTV Alpha / MagicBox II USB2.0-only DVB-T device.
+
+  (change from dvb-dibusb to dvb-usb)
+  2005-03-28 - added support for the AVerMedia AverTV DVB-T USB2.0 device (Thanks to Glen Harris and Jiun-Kuei Jung, AVerMedia)
+  2005-03-14 - added support for the Typhoon/Yakumo/HAMA DVB-T mobile USB2.0
+  2005-02-11 - added support for the KWorld/ADSTech Instant DVB-T USB2.0. Thanks a lot to Joachim von Caron
+  2005-02-02 - added support for the Hauppauge Win-TV Nova-T USB2
+  2005-01-31 - distorted streaming is gone for USB1.1 devices
+  2005-01-13 - moved the mirrored pid_filter_table back to dvb-dibusb
+             - first almost working version for HanfTek UMT-010
+             - found out, that Yakumo/HAMA/Typhoon are predecessors of the HanfTek UMT-010
+  2005-01-10 - refactoring completed, now everything is very delightful
+             - tuner quirks for some weird devices (Artec T1 AN2235 device has sometimes a
+               Panasonic Tuner assembled). Tunerprobing implemented. Thanks a lot to Gunnar Wittich.
+  2004-12-29 - after several days of struggling around bug of no returning URBs fixed.
+  2004-12-26 - refactored the dibusb-driver, splitted into separate files
+             - i2c-probing enabled
+  2004-12-06 - possibility for demod i2c-address probing
+             - new usb IDs (Compro, Artec)
+  2004-11-23 - merged changes from DiB3000MC_ver2.1
+             - revised the debugging
+             - possibility to deliver the complete TS for USB2.0
+  2004-11-21 - first working version of the dib3000mc/p frontend driver.
+  2004-11-12 - added additional remote control keys. Thanks to Uwe Hanke.
+  2004-11-07 - added remote control support. Thanks to David Matthews.
+  2004-11-05 - added support for a new devices (Grandtec/Avermedia/Artec)
+             - merged my changes (for dib3000mb/dibusb) to the FE_REFACTORING, because it became HEAD
+             - moved transfer control (pid filter, fifo control) from usb driver to frontend, it seems
+               better settled there (added xfer_ops-struct)
+             - created a common files for frontends (mc/p/mb)
+  2004-09-28 - added support for a new device (Unkown, vendor ID is Hyper-Paltek)
+  2004-09-20 - added support for a new device (Compro DVB-U2000), thanks
+               to Amaury Demol for reporting
+             - changed usb TS transfer method (several urbs, stopping transfer
+               before setting a new pid)
+  2004-09-13 - added support for a new device (Artec T1 USB TVBOX), thanks
+               to Christian Motschke for reporting
+  2004-09-05 - released the dibusb device and dib3000mb-frontend driver
+
+  (old news for vp7041.c)
+  2004-07-15 - found out, by accident, that the device has a TUA6010XS for
+               PLL
+  2004-07-12 - figured out, that the driver should also work with the
+               CTS Portable (Chinese Television System)
+  2004-07-08 - firmware-extraction-2.422-problem solved, driver is now working
+               properly with firmware extracted from 2.422
+             - #if for 2.6.4 (dvb), compile issue
+             - changed firmware handling, see vp7041.txt sec 1.1
+  2004-07-02 - some tuner modifications, v0.1, cleanups, first public
+  2004-06-28 - now using the dvb_dmx_swfilter_packets, everything
+               runs fine now
+  2004-06-27 - able to watch and switching channels (pre-alpha)
+             - no section filtering yet
+  2004-06-06 - first TS received, but kernel oops :/
+  2004-05-14 - firmware loader is working
+  2004-05-11 - start writing the driver
+
+1. How to use?
+1.1. Firmware
+
+Most of the USB drivers need to download a firmware to the device before start
+working.
+
+Have a look at the Wikipage for the DVB-USB-drivers to find out, which firmware
+you need for your device:
+
+http://www.linuxtv.org/wiki/index.php/DVB_USB
+
+1.2. Compiling
+
+Since the driver is in the linux kernel, activating the driver in
+your favorite config-environment should sufficient. I recommend
+to compile the driver as module. Hotplug does the rest.
+
+If you use dvb-kernel enter the build-2.6 directory run 'make' and 'insmod.sh
+load' afterwards.
+
+1.3. Loading the drivers
+
+Hotplug is able to load the driver, when it is needed (because you plugged
+in the device).
+
+If you want to enable debug output, you have to load the driver manually and
+from withing the dvb-kernel cvs repository.
+
+first have a look, which debug level are available:
+
+modinfo dvb-usb
+modinfo dvb-usb-vp7045
+etc.
+
+modprobe dvb-usb debug=<level>
+modprobe dvb-usb-vp7045 debug=<level>
+etc.
+
+should do the trick.
+
+When the driver is loaded successfully, the firmware file was in
+the right place and the device is connected, the "Power"-LED should be
+turned on.
+
+At this point you should be able to start a dvb-capable application. I'm use
+(t|s)zap, mplayer and dvbscan to test the basics. VDR-xine provides the
+long-term test scenario.
+
+2. Known problems and bugs
+
+- Don't remove the USB device while running an DVB application, your system
+  will go crazy or die most likely.
+
+2.1. Adding support for devices
+
+TODO
+
+2.2. USB1.1 Bandwidth limitation
+
+A lot of the currently supported devices are USB1.1 and thus they have a
+maximum bandwidth of about 5-6 MBit/s when connected to a USB2.0 hub.
+This is not enough for receiving the complete transport stream of a
+DVB-T channel (which is about 16 MBit/s). Normally this is not a
+problem, if you only want to watch TV (this does not apply for HDTV),
+but watching a channel while recording another channel on the same
+frequency simply does not work very well. This applies to all USB1.1
+DVB-T devices, not just the dvb-usb-devices)
+
+The bug, where the TS is distorted by a heavy usage of the device is gone
+definitely. All dvb-usb-devices I was using (Twinhan, Kworld, DiBcom) are
+working like charm now with VDR. Sometimes I even was able to record a channel
+and watch another one.
+
+2.3. Comments
+
+Patches, comments and suggestions are very very welcome.
+
+3. Acknowledgements
+   Amaury Demol (ademol@dibcom.fr) and Francois Kanounnikoff from DiBcom for
+    providing specs, code and help, on which the dvb-dibusb, dib3000mb and
+    dib3000mc are based.
+
+   David Matthews for identifying a new device type (Artec T1 with AN2235)
+    and for extending dibusb with remote control event handling. Thank you.
+
+   Alex Woods for frequently answering question about usb and dvb
+    stuff, a big thank you.
+
+   Bernd Wagner for helping with huge bug reports and discussions.
+
+   Gunnar Wittich and Joachim von Caron for their trust for providing
+    root-shells on their machines to implement support for new devices.
+
+   Allan Third and Michael Hutchinson for their help to write the Nebula
+    digitv-driver.
+
+   Glen Harris for bringing up, that there is a new dibusb-device and Jiun-Kuei
+    Jung from AVerMedia who kindly provided a special firmware to get the device
+    up and running in Linux.
+
+   Jennifer Chen, Jeff and Jack from Twinhan for kindly supporting by
+	writing the vp7045-driver.
+
+   Steve Chang from WideView for providing information for new devices and
+	firmware files.
+
+   Michael Paxton for submitting remote control keymaps.
+
+   Some guys on the linux-dvb mailing list for encouraging me.
+
+   Peter Schildmann >peter.schildmann-nospam-at-web.de< for his
+    user-level firmware loader, which saves a lot of time
+    (when writing the vp7041 driver)
+
+   Ulf Hermenau for helping me out with traditional chinese.
+
+   André Smoktun and Christian Frömmel for supporting me with
+    hardware and listening to my problems very patiently.
diff --git a/Documentation/dvb/bt8xx.txt b/Documentation/dvb/bt8xx.txt
--- a/Documentation/dvb/bt8xx.txt
+++ b/Documentation/dvb/bt8xx.txt
@@ -1,69 +1,55 @@
-How to get the Nebula, PCTV and Twinhan DST cards working
-=========================================================
+How to get the Nebula Electronics DigiTV, Pinnacle PCTV Sat, Twinhan DST + clones working
+=========================================================================================
 
-This class of cards has a bt878a as the PCI interface, and
-require the bttv driver.
+1) General information
+======================
 
-Please pay close attention to the warning about the bttv module
-options below for the DST card.
+This class of cards has a bt878a chip as the PCI interface.
+The different card drivers require the bttv driver to provide the means
+to access the i2c bus and the gpio pins of the bt8xx chipset.
 
-1) General informations
-=======================
+2) Compilation rules for Kernel >= 2.6.12
+=========================================
 
-These drivers require the bttv driver to provide the means to access
-the i2c bus and the gpio pins of the bt8xx chipset.
+Enable the following options:
 
-Because of this, you need to enable
 "Device drivers" => "Multimedia devices"
-  => "Video For Linux" => "BT848 Video For Linux"
-
-Furthermore you need to enable
+ => "Video For Linux" => "BT848 Video For Linux"
 "Device drivers" => "Multimedia devices" => "Digital Video Broadcasting Devices"
-  => "DVB for Linux" "DVB Core Support" "Nebula/Pinnacle PCTV/TwinHan PCI Cards"
+ => "DVB for Linux" "DVB Core Support" "Nebula/Pinnacle PCTV/TwinHan PCI Cards"
 
-2) Loading Modules
-==================
+3) Loading Modules, described by two approaches
+===============================================
 
 In general you need to load the bttv driver, which will handle the gpio and
-i2c communication for us, plus the common dvb-bt8xx device driver.
-The frontends for Nebula (nxt6000), Pinnacle PCTV (cx24110) and
-TwinHan (dst) are loaded automatically by the dvb-bt8xx device driver.
-
-3a) Nebula / Pinnacle PCTV
---------------------------
+i2c communication for us, plus the common dvb-bt8xx device driver,
+which is called the backend.
+The frontends for Nebula DigiTV (nxt6000), Pinnacle PCTV Sat (cx24110),
+TwinHan DST + clones (dst and dst-ca) are loaded automatically by the backend.
+For further details about TwinHan DST + clones see /Documentation/dvb/ci.txt.
+
+3a) The manual approach
+-----------------------
+
+Loading modules:
+modprobe bttv
+modprobe dvb-bt8xx
+
+Unloading modules:
+modprobe -r dvb-bt8xx
+modprobe -r bttv
 
-   $ modprobe bttv (normally bttv is being loaded automatically by kmod)
-   $ modprobe dvb-bt8xx (or just place dvb-bt8xx in /etc/modules for automatic loading)
-
-
-3b) TwinHan and Clones
+3b) The automatic approach
 --------------------------
 
-   $ modprobe bttv i2c_hw=1 card=0x71
-   $ modprobe dvb-bt8xx
-   $ modprobe dst
-
-The value 0x71 will override the PCI type detection for dvb-bt8xx,
-which  is necessary for TwinHan cards.
-
-If you're having an older card (blue color circuit) and card=0x71 locks
-your machine, try using 0x68, too. If that does not work, ask on the
-mailing list.
-
-The DST module takes a couple of useful parameters.
-
-verbose takes values 0 to 5. These values control the verbosity level.
-
-debug takes values 0 and 1. You can either disable or enable debugging.
-
-dst_addons takes values 0 and 0x20. A value of 0 means it is a FTA card.
-0x20 means it has a Conditional Access slot.
-
-The autodected values are determined bythe cards 'response
-string' which you can see in your logs e.g.
+If not already done by installation, place a line either in
+/etc/modules.conf or in /etc/modprobe.conf containing this text:
+alias char-major-81	bttv
 
-dst_get_device_id: Recognise [DSTMCI]
+Then place a line in /etc/modules containing this text:
+dvb-bt8xx
 
+Reboot your system and have fun!
 
 --
-Authors: Richard Walker, Jamie Honan, Michael Hunold, Manu Abraham
+Authors: Richard Walker, Jamie Honan, Michael Hunold, Manu Abraham, Uwe Bugla
diff --git a/Documentation/fb/intelfb.txt b/Documentation/fb/intelfb.txt
new file mode 100644
--- /dev/null
+++ b/Documentation/fb/intelfb.txt
@@ -0,0 +1,135 @@
+Intel 830M/845G/852GM/855GM/865G/915G Framebuffer driver
+================================================================
+
+A. Introduction
+	This is a framebuffer driver for various Intel 810/815 compatible
+graphics devices.  These would include:
+
+	Intel 830M
+	Intel 810E845G
+	Intel 852GM
+	Intel 855GM
+	Intel 865G
+	Intel 915G
+
+B.  List of available options
+
+   a. "video=intelfb"
+	enables the intelfb driver
+
+	Recommendation: required
+
+   b. "mode=<xres>x<yres>[-<bpp>][@<refresh>]"
+	select mode
+
+	Recommendation: user preference
+	(default = 1024x768-32@70)
+
+   c. "vram=<value>"
+	select amount of system RAM in MB to allocate for the video memory
+	if not enough RAM was already allocated by the BIOS.
+
+	Recommendation: 1 - 4 MB.
+	(default = 4 MB)
+
+   d. "voffset=<value>"
+        select at what offset in MB of the logical memory to allocate the
+	framebuffer memory.  The intent is to avoid the memory blocks
+	used by standard graphics applications (XFree86). Depending on your
+        usage, adjust the value up or down, (0 for maximum usage, 63/127 MB
+        for the least amount).  Note, an arbitrary setting may conflict
+        with XFree86.
+
+	Recommendation: do not set
+	(default = 48 MB)
+
+   e. "accel"
+	enable text acceleration.  This can be enabled/reenabled anytime
+	by using 'fbset -accel true/false'.
+
+	Recommendation: enable
+	(default = set)
+
+   f. "hwcursor"
+	enable cursor acceleration.
+
+	Recommendation: enable
+	(default = set)
+
+   g. "mtrr"
+	enable MTRR.  This allows data transfers to the framebuffer memory
+	to occur in bursts which can significantly increase performance.
+	Not very helpful with the intel chips because of 'shared memory'.
+
+	Recommendation: set
+	(default = set)
+
+   h. "fixed"
+	disable mode switching.
+
+	Recommendation: do not set
+	(default = not set)
+
+   The binary parameters can be unset with a "no" prefix, example "noaccel".
+   The default parameter (not named) is the mode.
+
+C. Kernel booting
+
+Separate each option/option-pair by commas (,) and the option from its value
+with an equals sign (=) as in the following:
+
+video=i810fb:option1,option2=value2
+
+Sample Usage
+------------
+
+In /etc/lilo.conf, add the line:
+
+append="video=intelfb:800x600-32@75,accel,hwcursor,vram=8"
+
+This will initialize the framebuffer to 800x600 at 32bpp and 75Hz. The
+framebuffer will use 8 MB of System RAM. hw acceleration of text and cursor
+will be enabled.
+
+D.  Module options
+
+	The module parameters are essentially similar to the kernel
+parameters. The main difference is that you need to include a Boolean value
+(1 for TRUE, and 0 for FALSE) for those options which don't need a value.
+
+Example, to enable MTRR, include "mtrr=1".
+
+Sample Usage
+------------
+
+Using the same setup as described above, load the module like this:
+
+	modprobe intelfb mode=800x600-32@75 vram=8 accel=1 hwcursor=1
+
+Or just add the following to /etc/modprobe.conf
+
+	options intelfb mode=800x600-32@75 vram=8 accel=1 hwcursor=1
+
+and just do a
+
+	modprobe intelfb
+
+
+E.  Acknowledgment:
+
+	1.  Geert Uytterhoeven - his excellent howto and the virtual
+                                 framebuffer driver code made this possible.
+
+	2.  Jeff Hartmann for his agpgart code.
+
+	3.  David Dawes for his original kernel 2.4 code.
+
+	4.  The X developers.  Insights were provided just by reading the
+	    XFree86 source code.
+
+	5.  Antonino A. Daplas for his inspiring i810fb driver.
+
+	6.  Andrew Morton for his kernel patches maintenance.
+
+###########################
+Sylvain
diff --git a/Documentation/fb/vesafb.txt b/Documentation/fb/vesafb.txt
--- a/Documentation/fb/vesafb.txt
+++ b/Documentation/fb/vesafb.txt
@@ -144,7 +144,21 @@ vgapal	Use the standard vga registers fo
 	This is the default.
 pmipal	Use the protected mode interface for palette changes.
 
-mtrr	setup memory type range registers for the vesafb framebuffer.
+mtrr:n	setup memory type range registers for the vesafb framebuffer
+	where n:
+	      0 - disabled (equivalent to nomtrr)
+	      1 - uncachable
+	      2 - write-back
+	      3 - write-combining (default)
+	      4 - write-through
+
+	If you see the following in dmesg, choose the type that matches the
+	old one. In this example, use "mtrr:2".
+...
+mtrr: type mismatch for e0000000,8000000 old: write-back new: write-combining
+...
+
+nomtrr  disable mtrr
 
 vremap:n
         remap 'n' MiB of video RAM. If 0 or not specified, remap memory
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -43,6 +43,14 @@ Who:	Randy Dunlap <rddunlap@osdl.org>
 
 ---------------------------
 
+What:	RAW driver (CONFIG_RAW_DRIVER)
+When:	December 2005
+Why:	declared obsolete since kernel 2.6.3
+	O_DIRECT can be used instead
+Who:	Adrian Bunk <bunk@stusta.de>
+
+---------------------------
+
 What:	register_ioctl32_conversion() / unregister_ioctl32_conversion()
 When:	April 2005
 Why:	Replaced by ->compat_ioctl in file_operations and other method
@@ -66,6 +74,14 @@ Who:	Paul E. McKenney <paulmck@us.ibm.co
 
 ---------------------------
 
+What:	remove verify_area()
+When:	July 2006
+Files:	Various uaccess.h headers.
+Why:	Deprecated and redundant. access_ok() should be used instead.
+Who:	Jesper Juhl <juhl-lkml@dif.dk>
+
+---------------------------
+
 What:	IEEE1394 Audio and Music Data Transmission Protocol driver,
 	Connection Management Procedures driver
 When:	November 2005
@@ -83,3 +99,39 @@ Why:	Deprecated in favour of the new ioc
 	more efficient.  You should really be using libraw1394 for raw1394
 	access anyway.
 Who:	Jody McIntyre <scjody@steamballoon.com>
+
+---------------------------
+
+What:	register_serial/unregister_serial
+When:	September 2005
+Why:	This interface does not allow serial ports to be registered against
+	a struct device, and as such does not allow correct power management
+	of such ports.  8250-based ports should use serial8250_register_port
+	and serial8250_unregister_port, or platform devices instead.
+Who:	Russell King <rmk@arm.linux.org.uk>
+
+---------------------------
+
+What:	i2c sysfs name change: in1_ref, vid deprecated in favour of cpu0_vid
+When:	November 2005
+Files:	drivers/i2c/chips/adm1025.c, drivers/i2c/chips/adm1026.c
+Why:	Match the other drivers' name for the same function, duplicate names
+	will be available until removal of old names.
+Who:	Grant Coady <gcoady@gmail.com>
+
+---------------------------
+
+What:	PCMCIA control ioctl (needed for pcmcia-cs [cardmgr, cardctl])
+When:	November 2005
+Files:	drivers/pcmcia/: pcmcia_ioctl.c
+Why:	With the 16-bit PCMCIA subsystem now behaving (almost) like a
+	normal hotpluggable bus, and with it using the default kernel
+	infrastructure (hotplug, driver core, sysfs) keeping the PCMCIA
+	control ioctl needed by cardmgr and cardctl from pcmcia-cs is
+	unnecessary, and makes further cleanups and integration of the
+	PCMCIA subsystem into the Linux kernel device driver model more
+	difficult. The features provided by cardmgr and cardctl are either
+	handled by the kernel itself now or are available in the new
+	pcmciautils package available at
+	http://kernel.org/pub/linux/utils/kernel/pcmcia/
+Who:	Dominik Brodowski <linux@brodo.de>
diff --git a/Documentation/filesystems/ext2.txt b/Documentation/filesystems/ext2.txt
--- a/Documentation/filesystems/ext2.txt
+++ b/Documentation/filesystems/ext2.txt
@@ -58,6 +58,8 @@ noacl				Don't support POSIX ACLs.
 
 nobh				Do not attach buffer_heads to file pagecache.
 
+xip				Use execute in place (no caching) if possible
+
 grpquota,noquota,quota,usrquota	Quota options are silently ignored by ext2.
 
 
diff --git a/Documentation/filesystems/inotify.txt b/Documentation/filesystems/inotify.txt
new file mode 100644
--- /dev/null
+++ b/Documentation/filesystems/inotify.txt
@@ -0,0 +1,151 @@
+				   inotify
+	    a powerful yet simple file change notification system
+
+
+
+Document started 15 Mar 2005 by Robert Love <rml@novell.com>
+
+
+(i) User Interface
+
+Inotify is controlled by a set of three system calls and normal file I/O on a
+returned file descriptor.
+
+First step in using inotify is to initialise an inotify instance:
+
+	int fd = inotify_init ();
+
+Each instance is associated with a unique, ordered queue.
+
+Change events are managed by "watches".  A watch is an (object,mask) pair where
+the object is a file or directory and the mask is a bit mask of one or more
+inotify events that the application wishes to receive.  See <linux/inotify.h>
+for valid events.  A watch is referenced by a watch descriptor, or wd.
+
+Watches are added via a path to the file.
+
+Watches on a directory will return events on any files inside of the directory.
+
+Adding a watch is simple:
+
+	int wd = inotify_add_watch (fd, path, mask);
+
+Where "fd" is the return value from inotify_init(), path is the path to the
+object to watch, and mask is the watch mask (see <linux/inotify.h>).
+
+You can update an existing watch in the same manner, by passing in a new mask.
+
+An existing watch is removed via
+
+	int ret = inotify_rm_watch (fd, wd);
+
+Events are provided in the form of an inotify_event structure that is read(2)
+from a given inotify instance.  The filename is of dynamic length and follows
+the struct. It is of size len.  The filename is padded with null bytes to
+ensure proper alignment.  This padding is reflected in len.
+
+You can slurp multiple events by passing a large buffer, for example
+
+	size_t len = read (fd, buf, BUF_LEN);
+
+Where "buf" is a pointer to an array of "inotify_event" structures at least
+BUF_LEN bytes in size.  The above example will return as many events as are
+available and fit in BUF_LEN.
+
+Each inotify instance fd is also select()- and poll()-able.
+
+You can find the size of the current event queue via the standard FIONREAD
+ioctl on the fd returned by inotify_init().
+
+All watches are destroyed and cleaned up on close.
+
+
+(ii)
+
+Prototypes:
+
+	int inotify_init (void);
+	int inotify_add_watch (int fd, const char *path, __u32 mask);
+	int inotify_rm_watch (int fd, __u32 mask);
+
+
+(iii) Internal Kernel Implementation
+
+Each inotify instance is associated with an inotify_device structure.
+
+Each watch is associated with an inotify_watch structure.  Watches are chained
+off of each associated device and each associated inode.
+
+See fs/inotify.c for the locking and lifetime rules.
+
+
+(iv) Rationale
+
+Q: What is the design decision behind not tying the watch to the open fd of
+   the watched object?
+
+A: Watches are associated with an open inotify device, not an open file.
+   This solves the primary problem with dnotify: keeping the file open pins
+   the file and thus, worse, pins the mount.  Dnotify is therefore infeasible
+   for use on a desktop system with removable media as the media cannot be
+   unmounted.  Watching a file should not require that it be open.
+
+Q: What is the design decision behind using an-fd-per-instance as opposed to
+   an fd-per-watch?
+
+A: An fd-per-watch quickly consumes more file descriptors than are allowed,
+   more fd's than are feasible to manage, and more fd's than are optimally
+   select()-able.  Yes, root can bump the per-process fd limit and yes, users
+   can use epoll, but requiring both is a silly and extraneous requirement.
+   A watch consumes less memory than an open file, separating the number
+   spaces is thus sensible.  The current design is what user-space developers
+   want: Users initialize inotify, once, and add n watches, requiring but one
+   fd and no twiddling with fd limits.  Initializing an inotify instance two
+   thousand times is silly.  If we can implement user-space's preferences 
+   cleanly--and we can, the idr layer makes stuff like this trivial--then we 
+   should.
+
+   There are other good arguments.  With a single fd, there is a single
+   item to block on, which is mapped to a single queue of events.  The single
+   fd returns all watch events and also any potential out-of-band data.  If
+   every fd was a separate watch,
+
+   - There would be no way to get event ordering.  Events on file foo and
+     file bar would pop poll() on both fd's, but there would be no way to tell
+     which happened first.  A single queue trivially gives you ordering.  Such
+     ordering is crucial to existing applications such as Beagle.  Imagine
+     "mv a b ; mv b a" events without ordering.
+
+   - We'd have to maintain n fd's and n internal queues with state,
+     versus just one.  It is a lot messier in the kernel.  A single, linear
+     queue is the data structure that makes sense.
+
+   - User-space developers prefer the current API.  The Beagle guys, for
+     example, love it.  Trust me, I asked.  It is not a surprise: Who'd want
+     to manage and block on 1000 fd's via select?
+
+   - No way to get out of band data.
+
+   - 1024 is still too low.  ;-)
+
+   When you talk about designing a file change notification system that
+   scales to 1000s of directories, juggling 1000s of fd's just does not seem
+   the right interface.  It is too heavy.
+
+   Additionally, it _is_ possible to  more than one instance  and
+   juggle more than one queue and thus more than one associated fd.  There
+   need not be a one-fd-per-process mapping; it is one-fd-per-queue and a
+   process can easily want more than one queue.
+
+Q: Why the system call approach?
+
+A: The poor user-space interface is the second biggest problem with dnotify.
+   Signals are a terrible, terrible interface for file notification.  Or for
+   anything, for that matter.  The ideal solution, from all perspectives, is a
+   file descriptor-based one that allows basic file I/O and poll/select.
+   Obtaining the fd and managing the watches could have been done either via a
+   device file or a family of new system calls.  We decided to implement a
+   family of system calls because that is the preffered approach for new kernel
+   interfaces.  The only real difference was whether we wanted to use open(2)
+   and ioctl(2) or a couple of new system calls.  System calls beat ioctls.
+
diff --git a/Documentation/filesystems/isofs.txt b/Documentation/filesystems/isofs.txt
--- a/Documentation/filesystems/isofs.txt
+++ b/Documentation/filesystems/isofs.txt
@@ -26,7 +26,11 @@ Mount options unique to the isofs filesy
   mode=xxx      Sets the permissions on files to xxx
   nojoliet      Ignore Joliet extensions if they are present.
   norock        Ignore Rock Ridge extensions if they are present.
-  unhide        Show hidden files.
+  hide		Completely strip hidden files from the file system.
+  showassoc	Show files marked with the 'associated' bit
+  unhide	Deprecated; showing hidden files is now default;
+		If given, it is a synonym for 'showassoc' which will
+		recreate previous unhide behavior
   session=x     Select number of session on multisession CD
   sbsector=xxx  Session begins from sector xxx
 
diff --git a/Documentation/filesystems/ntfs.txt b/Documentation/filesystems/ntfs.txt
--- a/Documentation/filesystems/ntfs.txt
+++ b/Documentation/filesystems/ntfs.txt
@@ -21,7 +21,7 @@ Overview
 ========
 
 Linux-NTFS comes with a number of user-space programs known as ntfsprogs.
-These include mkntfs, a full-featured ntfs file system format utility,
+These include mkntfs, a full-featured ntfs filesystem format utility,
 ntfsundelete used for recovering files that were unintentionally deleted
 from an NTFS volume and ntfsresize which is used to resize an NTFS partition.
 See the web site for more information.
@@ -149,7 +149,14 @@ case_sensitive=<BOOL>	If case_sensitive 
 			name, if it exists.  If case_sensitive, you will need
 			to provide the correct case of the short file name.
 
-errors=opt		What to do when critical file system errors are found.
+disable_sparse=<BOOL>	If disable_sparse is specified, creation of sparse
+			regions, i.e. holes, inside files is disabled for the
+			volume (for the duration of this mount only).  By
+			default, creation of sparse regions is enabled, which
+			is consistent with the behaviour of traditional Unix
+			filesystems.
+
+errors=opt		What to do when critical filesystem errors are found.
 			Following values can be used for "opt":
 			  continue: DEFAULT, try to clean-up as much as
 				    possible, e.g. marking a corrupt inode as
@@ -432,6 +439,24 @@ ChangeLog
 
 Note, a technical ChangeLog aimed at kernel hackers is in fs/ntfs/ChangeLog.
 
+2.1.23:
+	- Stamp the user space journal, aka transaction log, aka $UsnJrnl, if
+	  it is present and active thus telling Windows and applications using
+	  the transaction log that changes can have happened on the volume
+	  which are not recorded in $UsnJrnl.
+	- Detect the case when Windows has been hibernated (suspended to disk)
+	  and if this is the case do not allow (re)mounting read-write to
+	  prevent data corruption when you boot back into the suspended
+	  Windows session.
+	- Implement extension of resident files using the normal file write
+	  code paths, i.e. most very small files can be extended to be a little
+	  bit bigger but not by much.
+	- Add new mount option "disable_sparse".  (See list of mount options
+	  above for details.)
+	- Improve handling of ntfs volumes with errors and strange boot sectors
+	  in particular.
+	- Fix various bugs including a nasty deadlock that appeared in recent
+	  kernels (around 2.6.11-2.6.12 timeframe).
 2.1.22:
 	- Improve handling of ntfs volumes with errors.
 	- Fix various bugs and race conditions.
diff --git a/Documentation/filesystems/sysfs.txt b/Documentation/filesystems/sysfs.txt
--- a/Documentation/filesystems/sysfs.txt
+++ b/Documentation/filesystems/sysfs.txt
@@ -214,7 +214,7 @@ Other notes:
 
 A very simple (and naive) implementation of a device attribute is:
 
-static ssize_t show_name(struct device * dev, char * buf)
+static ssize_t show_name(struct device *dev, struct device_attribute *attr, char *buf)
 {
         return sprintf(buf,"%s\n",dev->name);
 }
diff --git a/Documentation/filesystems/tmpfs.txt b/Documentation/filesystems/tmpfs.txt
--- a/Documentation/filesystems/tmpfs.txt
+++ b/Documentation/filesystems/tmpfs.txt
@@ -71,8 +71,8 @@ can be changed on remount.  The size par
 to limit this tmpfs instance to that percentage of your physical RAM:
 the default, when neither size nor nr_blocks is specified, is size=50%
 
-If both nr_blocks (or size) and nr_inodes are set to 0, neither blocks
-nor inodes will be limited in that instance.  It is generally unwise to
+If nr_blocks=0 (or size=0), blocks will not be limited in that instance;
+if nr_inodes=0, inodes will not be limited.  It is generally unwise to
 mount with such options, since it allows any user with write access to
 use up all the memory on the machine; but enhances the scalability of
 that instance in a system with many cpus making intensive use of it.
@@ -97,4 +97,4 @@ RAM/SWAP in 10240 inodes and it is only 
 Author:
    Christoph Rohland <cr@sap.com>, 1.12.01
 Updated:
-   Hugh Dickins <hugh@veritas.com>, 01 September 2004
+   Hugh Dickins <hugh@veritas.com>, 13 March 2005
diff --git a/Documentation/filesystems/xip.txt b/Documentation/filesystems/xip.txt
new file mode 100644
--- /dev/null
+++ b/Documentation/filesystems/xip.txt
@@ -0,0 +1,67 @@
+Execute-in-place for file mappings
+----------------------------------
+
+Motivation
+----------
+File mappings are performed by mapping page cache pages to userspace. In
+addition, read&write type file operations also transfer data from/to the page
+cache.
+
+For memory backed storage devices that use the block device interface, the page
+cache pages are in fact copies of the original storage. Various approaches
+exist to work around the need for an extra copy. The ramdisk driver for example
+does read the data into the page cache, keeps a reference, and discards the
+original data behind later on.
+
+Execute-in-place solves this issue the other way around: instead of keeping
+data in the page cache, the need to have a page cache copy is eliminated
+completely. With execute-in-place, read&write type operations are performed
+directly from/to the memory backed storage device. For file mappings, the
+storage device itself is mapped directly into userspace.
+
+This implementation was initialy written for shared memory segments between
+different virtual machines on s390 hardware to allow multiple machines to
+share the same binaries and libraries.
+
+Implementation
+--------------
+Execute-in-place is implemented in three steps: block device operation,
+address space operation, and file operations.
+
+A block device operation named direct_access is used to retrieve a
+reference (pointer) to a block on-disk. The reference is supposed to be
+cpu-addressable, physical address and remain valid until the release operation
+is performed. A struct block_device reference is used to address the device,
+and a sector_t argument is used to identify the individual block. As an
+alternative, memory technology devices can be used for this.
+
+The block device operation is optional, these block devices support it as of
+today:
+- dcssblk: s390 dcss block device driver
+
+An address space operation named get_xip_page is used to retrieve reference
+to a struct page. To address the target page, a reference to an address_space,
+and a sector number is provided. A 3rd argument indicates whether the
+function should allocate blocks if needed.
+
+This address space operation is mutually exclusive with readpage&writepage that
+do page cache read/write operations.
+The following filesystems support it as of today:
+- ext2: the second extended filesystem, see Documentation/filesystems/ext2.txt
+
+A set of file operations that do utilize get_xip_page can be found in
+mm/filemap_xip.c . The following file operation implementations are provided:
+- aio_read/aio_write
+- readv/writev
+- sendfile
+
+The generic file operations do_sync_read/do_sync_write can be used to implement
+classic synchronous IO calls.
+
+Shortcomings
+------------
+This implementation is limited to storage devices that are cpu addressable at
+all times (no highmem or such). It works well on rom/ram, but enhancements are
+needed to make it work with flash in read+write mode.
+Putting the Linux kernel and/or its modules on a xip filesystem does not mean
+they are not copied.
diff --git a/Documentation/hwmon/adm1021 b/Documentation/hwmon/adm1021
new file mode 100644
--- /dev/null
+++ b/Documentation/hwmon/adm1021
@@ -0,0 +1,111 @@
+Kernel driver adm1021
+=====================
+
+Supported chips:
+  * Analog Devices ADM1021
+    Prefix: 'adm1021'
+    Addresses scanned: I2C 0x18 - 0x1a, 0x29 - 0x2b, 0x4c - 0x4e
+    Datasheet: Publicly available at the Analog Devices website
+  * Analog Devices ADM1021A/ADM1023
+    Prefix: 'adm1023'
+    Addresses scanned: I2C 0x18 - 0x1a, 0x29 - 0x2b, 0x4c - 0x4e
+    Datasheet: Publicly available at the Analog Devices website
+  * Genesys Logic GL523SM
+    Prefix: 'gl523sm'
+    Addresses scanned: I2C 0x18 - 0x1a, 0x29 - 0x2b, 0x4c - 0x4e
+    Datasheet:
+  * Intel Xeon Processor
+    Prefix: - any other - may require 'force_adm1021' parameter
+    Addresses scanned: none
+    Datasheet: Publicly available at Intel website
+  * Maxim MAX1617
+    Prefix: 'max1617'
+    Addresses scanned: I2C 0x18 - 0x1a, 0x29 - 0x2b, 0x4c - 0x4e
+    Datasheet: Publicly available at the Maxim website
+  * Maxim MAX1617A
+    Prefix: 'max1617a'
+    Addresses scanned: I2C 0x18 - 0x1a, 0x29 - 0x2b, 0x4c - 0x4e
+    Datasheet: Publicly available at the Maxim website
+  * National Semiconductor LM84
+    Prefix: 'lm84'
+    Addresses scanned: I2C 0x18 - 0x1a, 0x29 - 0x2b, 0x4c - 0x4e
+    Datasheet: Publicly available at the National Semiconductor website
+  * Philips NE1617
+    Prefix: 'max1617' (probably detected as a max1617)
+    Addresses scanned: I2C 0x18 - 0x1a, 0x29 - 0x2b, 0x4c - 0x4e
+    Datasheet: Publicly available at the Philips website
+  * Philips NE1617A
+    Prefix: 'max1617' (probably detected as a max1617)
+    Addresses scanned: I2C 0x18 - 0x1a, 0x29 - 0x2b, 0x4c - 0x4e
+    Datasheet: Publicly available at the Philips website
+  * TI THMC10
+    Prefix: 'thmc10'
+    Addresses scanned: I2C 0x18 - 0x1a, 0x29 - 0x2b, 0x4c - 0x4e
+    Datasheet: Publicly available at the TI website
+  * Onsemi MC1066
+    Prefix: 'mc1066'
+    Addresses scanned: I2C 0x18 - 0x1a, 0x29 - 0x2b, 0x4c - 0x4e
+    Datasheet: Publicly available at the Onsemi website
+
+
+Authors:
+        Frodo Looijaard <frodol@dds.nl>,
+        Philip Edelbrock <phil@netroedge.com>
+
+Module Parameters
+-----------------
+
+* read_only: int
+  Don't set any values, read only mode
+
+
+Description
+-----------
+
+The chips supported by this driver are very similar. The Maxim MAX1617 is
+the oldest; it has the problem that it is not very well detectable. The
+MAX1617A solves that. The ADM1021 is a straight clone of the MAX1617A.
+Ditto for the THMC10. From here on, we will refer to all these chips as
+ADM1021-clones.
+
+The ADM1021 and MAX1617A reports a die code, which is a sort of revision
+code. This can help us pinpoint problems; it is not very useful
+otherwise.
+
+ADM1021-clones implement two temperature sensors. One of them is internal,
+and measures the temperature of the chip itself; the other is external and
+is realised in the form of a transistor-like device. A special alarm
+indicates whether the remote sensor is connected.
+
+Each sensor has its own low and high limits. When they are crossed, the
+corresponding alarm is set and remains on as long as the temperature stays
+out of range. Temperatures are measured in degrees Celsius. Measurements
+are possible between -65 and +127 degrees, with a resolution of one degree.
+
+If an alarm triggers, it will remain triggered until the hardware register
+is read at least once. This means that the cause for the alarm may already
+have disappeared!
+
+This driver only updates its values each 1.5 seconds; reading it more often
+will do no harm, but will return 'old' values. It is possible to make
+ADM1021-clones do faster measurements, but there is really no good reason
+for that.
+
+Xeon support
+------------
+
+Some Xeon processors have real max1617, adm1021, or compatible chips
+within them, with two temperature sensors.
+
+Other Xeons have chips with only one sensor.
+
+If you have a Xeon, and the adm1021 module loads, and both temperatures
+appear valid, then things are good.
+
+If the adm1021 module doesn't load, you should try this:
+	modprobe adm1021 force_adm1021=BUS,ADDRESS
+	ADDRESS can only be 0x18, 0x1a, 0x29, 0x2b, 0x4c, or 0x4e.
+
+If you have dual Xeons you may have appear to have two separate
+adm1021-compatible chips, or two single-temperature sensors, at distinct
+addresses.
diff --git a/Documentation/hwmon/adm1025 b/Documentation/hwmon/adm1025
new file mode 100644
--- /dev/null
+++ b/Documentation/hwmon/adm1025
@@ -0,0 +1,51 @@
+Kernel driver adm1025
+=====================
+
+Supported chips:
+  * Analog Devices ADM1025, ADM1025A
+    Prefix: 'adm1025'
+    Addresses scanned: I2C 0x2c - 0x2e
+    Datasheet: Publicly available at the Analog Devices website
+  * Philips NE1619
+    Prefix: 'ne1619'
+    Addresses scanned: I2C 0x2c - 0x2d
+    Datasheet: Publicly available at the Philips website
+
+The NE1619 presents some differences with the original ADM1025:
+  * Only two possible addresses (0x2c - 0x2d).
+  * No temperature offset register, but we don't use it anyway.
+  * No INT mode for pin 16. We don't play with it anyway.
+
+Authors:
+        Chen-Yuan Wu <gwu@esoft.com>,
+        Jean Delvare <khali@linux-fr.org>
+
+Description
+-----------
+
+(This is from Analog Devices.) The ADM1025 is a complete system hardware
+monitor for microprocessor-based systems, providing measurement and limit
+comparison of various system parameters. Five voltage measurement inputs
+are provided, for monitoring +2.5V, +3.3V, +5V and +12V power supplies and
+the processor core voltage. The ADM1025 can monitor a sixth power-supply
+voltage by measuring its own VCC. One input (two pins) is dedicated to a
+remote temperature-sensing diode and an on-chip temperature sensor allows
+ambient temperature to be monitored.
+
+One specificity of this chip is that the pin 11 can be hardwired in two
+different manners. It can act as the +12V power-supply voltage analog
+input, or as the a fifth digital entry for the VID reading (bit 4). It's
+kind of strange since both are useful, and the reason for designing the
+chip that way is obscure at least to me. The bit 5 of the configuration
+register can be used to define how the chip is hardwired. Please note that
+it is not a choice you have to make as the user. The choice was already
+made by your motherboard's maker. If the configuration bit isn't set
+properly, you'll have a wrong +12V reading or a wrong VID reading. The way
+the driver handles that is to preserve this bit through the initialization
+process, assuming that the BIOS set it up properly beforehand. If it turns
+out not to be true in some cases, we'll provide a module parameter to force
+modes.
+
+This driver also supports the ADM1025A, which differs from the ADM1025
+only in that it has "open-drain VID inputs while the ADM1025 has on-chip
+100k pull-ups on the VID inputs". It doesn't make any difference for us.
diff --git a/Documentation/hwmon/adm1026 b/Documentation/hwmon/adm1026
new file mode 100644
--- /dev/null
+++ b/Documentation/hwmon/adm1026
@@ -0,0 +1,93 @@
+Kernel driver adm1026
+=====================
+
+Supported chips:
+  * Analog Devices ADM1026
+    Prefix: 'adm1026'
+    Addresses scanned: I2C 0x2c, 0x2d, 0x2e
+    Datasheet: Publicly available at the Analog Devices website
+               http://www.analog.com/en/prod/0,,766_825_ADM1026,00.html
+
+Authors:
+        Philip Pokorny <ppokorny@penguincomputing.com> for Penguin Computing
+        Justin Thiessen <jthiessen@penguincomputing.com>
+
+Module Parameters
+-----------------
+
+* gpio_input: int array (min = 1, max = 17)
+  List of GPIO pins (0-16) to program as inputs
+* gpio_output: int array (min = 1, max = 17)
+  List of GPIO pins (0-16) to program as outputs
+* gpio_inverted: int array (min = 1, max = 17)
+  List of GPIO pins (0-16) to program as inverted
+* gpio_normal: int array (min = 1, max = 17)
+  List of GPIO pins (0-16) to program as normal/non-inverted
+* gpio_fan: int array (min = 1, max = 8)
+  List of GPIO pins (0-7) to program as fan tachs
+
+
+Description
+-----------
+
+This driver implements support for the Analog Devices ADM1026. Analog
+Devices calls it a "complete thermal system management controller."
+
+The ADM1026 implements three (3) temperature sensors, 17 voltage sensors,
+16 general purpose digital I/O lines, eight (8) fan speed sensors (8-bit),
+an analog output and a PWM output along with limit, alarm and mask bits for
+all of the above. There is even 8k bytes of EEPROM memory on chip.
+
+Temperatures are measured in degrees Celsius. There are two external
+sensor inputs and one internal sensor. Each sensor has a high and low
+limit. If the limit is exceeded, an interrupt (#SMBALERT) can be
+generated. The interrupts can be masked. In addition, there are over-temp
+limits for each sensor. If this limit is exceeded, the #THERM output will
+be asserted. The current temperature and limits have a resolution of 1
+degree.
+
+Fan rotation speeds are reported in RPM (rotations per minute) but measured
+in counts of a 22.5kHz internal clock. Each fan has a high limit which
+corresponds to a minimum fan speed. If the limit is exceeded, an interrupt
+can be generated. Each fan can be programmed to divide the reference clock
+by 1, 2, 4 or 8. Not all RPM values can accurately be represented, so some
+rounding is done. With a divider of 8, the slowest measurable speed of a
+two pulse per revolution fan is 661 RPM.
+
+There are 17 voltage sensors. An alarm is triggered if the voltage has
+crossed a programmable minimum or maximum limit. Note that minimum in this
+case always means 'closest to zero'; this is important for negative voltage
+measurements. Several inputs have integrated attenuators so they can measure
+higher voltages directly. 3.3V, 5V, 12V, -12V and battery voltage all have
+dedicated inputs. There are several inputs scaled to 0-3V full-scale range
+for SCSI terminator power. The remaining inputs are not scaled and have
+a 0-2.5V full-scale range. A 2.5V or 1.82V reference voltage is provided
+for negative voltage measurements.
+
+If an alarm triggers, it will remain triggered until the hardware register
+is read at least once. This means that the cause for the alarm may already
+have disappeared! Note that in the current implementation, all hardware
+registers are read whenever any data is read (unless it is less than 2.0
+seconds since the last update). This means that you can easily miss
+once-only alarms.
+
+The ADM1026 measures continuously. Analog inputs are measured about 4
+times a second. Fan speed measurement time depends on fan speed and
+divisor. It can take as long as 1.5 seconds to measure all fan speeds.
+
+The ADM1026 has the ability to automatically control fan speed based on the
+temperature sensor inputs. Both the PWM output and the DAC output can be
+used to control fan speed. Usually only one of these two outputs will be
+used. Write the minimum PWM or DAC value to the appropriate control
+register. Then set the low temperature limit in the tmin values for each
+temperature sensor. The range of control is fixed at 20 °C, and the
+largest difference between current and tmin of the temperature sensors sets
+the control output. See the datasheet for several example circuits for
+controlling fan speed with the PWM and DAC outputs. The fan speed sensors
+do not have PWM compensation, so it is probably best to control the fan
+voltage from the power lead rather than on the ground lead.
+
+The datasheet shows an example application with VID signals attached to
+GPIO lines. Unfortunately, the chip may not be connected to the VID lines
+in this way. The driver assumes that the chips *is* connected this way to
+get a VID voltage.
diff --git a/Documentation/hwmon/adm1031 b/Documentation/hwmon/adm1031
new file mode 100644
--- /dev/null
+++ b/Documentation/hwmon/adm1031
@@ -0,0 +1,35 @@
+Kernel driver adm1031
+=====================
+
+Supported chips:
+  * Analog Devices ADM1030
+    Prefix: 'adm1030'
+    Addresses scanned: I2C 0x2c to 0x2e
+    Datasheet: Publicly available at the Analog Devices website
+               http://products.analog.com/products/info.asp?product=ADM1030
+
+  * Analog Devices ADM1031
+    Prefix: 'adm1031'
+    Addresses scanned: I2C 0x2c to 0x2e
+    Datasheet: Publicly available at the Analog Devices website
+               http://products.analog.com/products/info.asp?product=ADM1031
+
+Authors:
+        Alexandre d'Alton <alex@alexdalton.org>
+        Jean Delvare <khali@linux-fr.org>
+
+Description
+-----------
+
+The ADM1030 and ADM1031 are digital temperature sensors and fan controllers.
+They sense their own temperature as well as the temperature of up to one
+(ADM1030) or two (ADM1031) external diodes.
+
+All temperature values are given in degrees Celsius. Resolution is 0.5
+degree for the local temperature, 0.125 degree for the remote temperatures.
+
+Each temperature channel has its own high and low limits, plus a critical
+limit.
+
+The ADM1030 monitors a single fan speed, while the ADM1031 monitors up to
+two. Each fan channel has its own low speed limit.
diff --git a/Documentation/hwmon/adm9240 b/Documentation/hwmon/adm9240
new file mode 100644
--- /dev/null
+++ b/Documentation/hwmon/adm9240
@@ -0,0 +1,177 @@
+Kernel driver adm9240
+=====================
+
+Supported chips:
+  * Analog Devices ADM9240
+    Prefix: 'adm9240'
+    Addresses scanned: I2C 0x2c - 0x2f
+    Datasheet: Publicly available at the Analog Devices website
+    http://www.analog.com/UploadedFiles/Data_Sheets/79857778ADM9240_0.pdf
+
+  * Dallas Semiconductor DS1780
+    Prefix: 'ds1780'
+    Addresses scanned: I2C 0x2c - 0x2f
+    Datasheet: Publicly available at the Dallas Semiconductor (Maxim) website
+    http://pdfserv.maxim-ic.com/en/ds/DS1780.pdf
+
+  * National Semiconductor LM81
+    Prefix: 'lm81'
+    Addresses scanned: I2C 0x2c - 0x2f
+    Datasheet: Publicly available at the National Semiconductor website
+    http://www.national.com/ds.cgi/LM/LM81.pdf
+
+Authors:
+    Frodo Looijaard <frodol@dds.nl>,
+    Philip Edelbrock <phil@netroedge.com>,
+    Michiel Rook <michiel@grendelproject.nl>,
+    Grant Coady <gcoady@gmail.com> with guidance
+        from Jean Delvare <khali@linux-fr.org>
+
+Interface
+---------
+The I2C addresses listed above assume BIOS has not changed the
+chip MSB 5-bit address. Each chip reports a unique manufacturer
+identification code as well as the chip revision/stepping level.
+
+Description
+-----------
+[From ADM9240] The ADM9240 is a complete system hardware monitor for
+microprocessor-based systems, providing measurement and limit comparison
+of up to four power supplies and two processor core voltages, plus
+temperature, two fan speeds and chassis intrusion. Measured values can
+be read out via an I2C-compatible serial System Management Bus, and values
+for limit comparisons can be programmed in over the same serial bus. The
+high speed successive approximation ADC allows frequent sampling of all
+analog channels to ensure a fast interrupt response to any out-of-limit
+measurement.
+
+The ADM9240, DS1780 and LM81 are register compatible, the following
+details are common to the three chips. Chip differences are described
+after this section.
+
+
+Measurements
+------------
+The measurement cycle
+
+The adm9240 driver will take a measurement reading no faster than once
+each two seconds. User-space may read sysfs interface faster than the
+measurement update rate and will receive cached data from the most
+recent measurement.
+
+ADM9240 has a very fast 320us temperature and voltage measurement cycle
+with independent fan speed measurement cycles counting alternating rising
+edges of the fan tacho inputs.
+
+DS1780 measurement cycle is about once per second including fan speed.
+
+LM81 measurement cycle is about once per 400ms including fan speed.
+The LM81 12-bit extended temperature measurement mode is not supported.
+
+Temperature
+-----------
+On chip temperature is reported as degrees Celsius as 9-bit signed data
+with resolution of 0.5 degrees Celsius. High and low temperature limits
+are 8-bit signed data with resolution of one degree Celsius.
+
+Temperature alarm is asserted once the temperature exceeds the high limit,
+and is cleared when the temperature falls below the temp1_max_hyst value.
+
+Fan Speed
+---------
+Two fan tacho inputs are provided, the ADM9240 gates an internal 22.5kHz
+clock via a divider to an 8-bit counter. Fan speed (rpm) is calculated by:
+
+rpm = (22500 * 60) / (count * divider)
+
+Automatic fan clock divider
+
+  * User sets 0 to fan_min limit
+    - low speed alarm is disabled
+    - fan clock divider not changed
+    - auto fan clock adjuster enabled for valid fan speed reading
+
+  * User sets fan_min limit too low
+    - low speed alarm is enabled
+    - fan clock divider set to max
+    - fan_min set to register value 254 which corresponds
+      to 664 rpm on adm9240
+    - low speed alarm will be asserted if fan speed is
+      less than minimum measurable speed
+    - auto fan clock adjuster disabled
+
+  * User sets reasonable fan speed
+    - low speed alarm is enabled
+    - fan clock divider set to suit fan_min
+    - auto fan clock adjuster enabled: adjusts fan_min
+
+  * User sets unreasonably high low fan speed limit
+    - resolution of the low speed limit may be reduced
+    - alarm will be asserted
+    - auto fan clock adjuster enabled: adjusts fan_min
+
+    * fan speed may be displayed as zero until the auto fan clock divider
+      adjuster brings fan speed clock divider back into chip measurement
+      range, this will occur within a few measurement cycles.
+
+Analog Output
+-------------
+An analog output provides a 0 to 1.25 volt signal intended for an external
+fan speed amplifier circuit. The analog output is set to maximum value on
+power up or reset. This doesn't do much on the test Intel SE440BX-2.
+
+Voltage Monitor
+
+Voltage (IN) measurement is internally scaled:
+
+    nr  label       nominal     maximum   resolution
+                      mV          mV         mV
+    0   +2.5V        2500        3320       13.0
+    1   Vccp1        2700        3600       14.1
+    2   +3.3V        3300        4380       17.2
+    3     +5V        5000        6640       26.0
+    4    +12V       12000       15940       62.5
+    5   Vccp2        2700        3600       14.1
+
+The reading is an unsigned 8-bit value, nominal voltage measurement is
+represented by a reading of 192, being 3/4 of the measurement range.
+
+An alarm is asserted for any voltage going below or above the set limits.
+
+The driver reports and accepts voltage limits scaled to the above table.
+
+VID Monitor
+-----------
+The chip has five inputs to read the 5-bit VID and reports the mV value
+based on detected CPU type.
+
+Chassis Intrusion
+-----------------
+An alarm is asserted when the CI pin goes active high. The ADM9240
+Datasheet has an example of an external temperature sensor driving
+this pin. On an Intel SE440BX-2 the Chassis Intrusion header is
+connected to a normally open switch.
+
+The ADM9240 provides an internal open drain on this line, and may output
+a 20 ms active low pulse to reset an external Chassis Intrusion latch.
+
+Clear the CI latch by writing value 1 to the sysfs chassis_clear file.
+
+Alarm flags reported as 16-bit word
+
+    bit     label               comment
+    ---     -------------       --------------------------
+     0      +2.5 V_Error        high or low limit exceeded
+     1      VCCP_Error          high or low limit exceeded
+     2      +3.3 V_Error        high or low limit exceeded
+     3      +5 V_Error          high or low limit exceeded
+     4      Temp_Error          temperature error
+     6      FAN1_Error          fan low limit exceeded
+     7      FAN2_Error          fan low limit exceeded
+     8      +12 V_Error         high or low limit exceeded
+     9      VCCP2_Error         high or low limit exceeded
+    12      Chassis_Error       CI pin went high
+
+Remaining bits are reserved and thus undefined. It is important to note
+that alarm bits may be cleared on read, user-space may latch alarms and
+provide the end-user with a method to clear alarm memory.
diff --git a/Documentation/hwmon/asb100 b/Documentation/hwmon/asb100
new file mode 100644
--- /dev/null
+++ b/Documentation/hwmon/asb100
@@ -0,0 +1,72 @@
+Kernel driver asb100
+====================
+
+Supported Chips:
+  * Asus ASB100 and ASB100-A "Bach"
+    Prefix: 'asb100'
+    Addresses scanned: I2C 0x2d
+    Datasheet: none released
+
+Author: Mark M. Hoffman <mhoffman@lightlink.com>
+
+Description
+-----------
+
+This driver implements support for the Asus ASB100 and ASB100-A "Bach".
+These are custom ASICs available only on Asus mainboards. Asus refuses to
+supply a datasheet for these chips. Thanks go to many people who helped
+investigate their hardware, including:
+
+Vitaly V. Bursov
+Alexander van Kaam (author of MBM for Windows)
+Bertrik Sikken
+
+The ASB100 implements seven voltage sensors, three fan rotation speed
+sensors, four temperature sensors, VID lines and alarms. In addition to
+these, the ASB100-A also implements a single PWM controller for fans 2 and
+3 (i.e. one setting controls both.) If you have a plain ASB100, the PWM
+controller will simply not work (or maybe it will for you... it doesn't for
+me).
+
+Temperatures are measured and reported in degrees Celsius.
+
+Fan speeds are reported in RPM (rotations per minute). An alarm is
+triggered if the rotation speed has dropped below a programmable limit.
+
+Voltage sensors (also known as IN sensors) report values in volts.
+
+The VID lines encode the core voltage value: the voltage level your
+processor should work with. This is hardcoded by the mainboard and/or
+processor itself. It is a value in volts.
+
+Alarms: (TODO question marks indicate may or may not work)
+
+0x0001 => in0 (?)
+0x0002 => in1 (?)
+0x0004 => in2
+0x0008 => in3
+0x0010 => temp1 (1)
+0x0020 => temp2
+0x0040 => fan1
+0x0080 => fan2
+0x0100 => in4
+0x0200 => in5 (?) (2)
+0x0400 => in6 (?) (2)
+0x0800 => fan3
+0x1000 => chassis switch
+0x2000 => temp3
+
+Alarm Notes:
+
+(1) This alarm will only trigger if the hysteresis value is 127C.
+I.e. it behaves the same as w83781d.
+
+(2) The min and max registers for these values appear to
+be read-only or otherwise stuck at 0x00.
+
+TODO:
+* Experiment with fan divisors > 8.
+* Experiment with temp. sensor types.
+* Are there really 13 voltage inputs? Probably not...
+* Cleanups, no doubt...
+
diff --git a/Documentation/hwmon/ds1621 b/Documentation/hwmon/ds1621
new file mode 100644
--- /dev/null
+++ b/Documentation/hwmon/ds1621
@@ -0,0 +1,108 @@
+Kernel driver ds1621
+====================
+
+Supported chips:
+  * Dallas Semiconductor DS1621
+    Prefix: 'ds1621'
+    Addresses scanned: I2C 0x48 - 0x4f
+    Datasheet: Publicly available at the Dallas Semiconductor website
+               http://www.dalsemi.com/
+  * Dallas Semiconductor DS1625
+    Prefix: 'ds1621'
+    Addresses scanned: I2C 0x48 - 0x4f
+    Datasheet: Publicly available at the Dallas Semiconductor website
+               http://www.dalsemi.com/
+
+Authors:
+        Christian W. Zuckschwerdt <zany@triq.net>
+        valuable contributions by Jan M. Sendler <sendler@sendler.de>
+        ported to 2.6 by Aurelien Jarno <aurelien@aurel32.net>
+        with the help of Jean Delvare <khali@linux-fr.org>
+
+Module Parameters
+------------------
+
+* polarity int
+  Output's polarity: 0 = active high, 1 = active low
+
+Description
+-----------
+
+The DS1621 is a (one instance) digital thermometer and thermostat. It has
+both high and low temperature limits which can be user defined (i.e.
+programmed into non-volatile on-chip registers). Temperature range is -55
+degree Celsius to +125 in 0.5 increments. You may convert this into a
+Fahrenheit range of -67 to +257 degrees with 0.9 steps. If polarity
+parameter is not provided, original value is used.
+
+As for the thermostat, behavior can also be programmed using the polarity
+toggle. On the one hand ("heater"), the thermostat output of the chip,
+Tout, will trigger when the low limit temperature is met or underrun and
+stays high until the high limit is met or exceeded. On the other hand
+("cooler"), vice versa. That way "heater" equals "active low", whereas
+"conditioner" equals "active high". Please note that the DS1621 data sheet
+is somewhat misleading in this point since setting the polarity bit does
+not simply invert Tout.
+
+A second thing is that, during extensive testing, Tout showed a tolerance
+of up to +/- 0.5 degrees even when compared against precise temperature
+readings. Be sure to have a high vs. low temperature limit gap of al least
+1.0 degree Celsius to avoid Tout "bouncing", though!
+
+As for alarms, you can read the alarm status of the DS1621 via the 'alarms'
+/sys file interface. The result consists mainly of bit 6 and 5 of the
+configuration register of the chip; bit 6 (0x40 or 64) is the high alarm
+bit and bit 5 (0x20 or 32) the low one. These bits are set when the high or
+low limits are met or exceeded and are reset by the module as soon as the
+respective temperature ranges are left.
+
+The alarm registers are in no way suitable to find out about the actual
+status of Tout. They will only tell you about its history, whether or not
+any of the limits have ever been met or exceeded since last power-up or
+reset. Be aware: When testing, it showed that the status of Tout can change
+with neither of the alarms set.
+
+Temperature conversion of the DS1621 takes up to 1000ms; internal access to
+non-volatile registers may last for 10ms or below.
+
+High Accuracy Temperature Reading
+---------------------------------
+
+As said before, the temperature issued via the 9-bit i2c-bus data is
+somewhat arbitrary. Internally, the temperature conversion is of a
+different kind that is explained (not so...) well in the DS1621 data sheet.
+To cut the long story short: Inside the DS1621 there are two oscillators,
+both of them biassed by a temperature coefficient.
+
+Higher resolution of the temperature reading can be achieved using the
+internal projection, which means taking account of REG_COUNT and REG_SLOPE
+(the driver manages them):
+
+Taken from Dallas Semiconductors App Note 068: 'Increasing Temperature
+Resolution on the DS1620' and App Note 105: 'High Resolution Temperature
+Measurement with Dallas Direct-to-Digital Temperature Sensors'
+
+- Read the 9-bit temperature and strip the LSB (Truncate the .5 degs)
+- The resulting value is TEMP_READ.
+- Then, read REG_COUNT.
+- And then, REG_SLOPE.
+
+      TEMP = TEMP_READ - 0.25 + ((REG_SLOPE - REG_COUNT) / REG_SLOPE)
+
+Note that this is what the DONE bit in the DS1621 configuration register is
+good for: Internally, one temperature conversion takes up to 1000ms. Before
+that conversion is complete you will not be able to read valid things out
+of REG_COUNT and REG_SLOPE. The DONE bit, as you may have guessed by now,
+tells you whether the conversion is complete ("done", in plain English) and
+thus, whether the values you read are good or not.
+
+The DS1621 has two modes of operation: "Continuous" conversion, which can
+be understood as the default stand-alone mode where the chip gets the
+temperature and controls external devices via its Tout pin or tells other
+i2c's about it if they care. The other mode is called "1SHOT", that means
+that it only figures out about the temperature when it is explicitly told
+to do so; this can be seen as power saving mode.
+
+Now if you want to read REG_COUNT and REG_SLOPE, you have to either stop
+the continuous conversions until the contents of these registers are valid,
+or, in 1SHOT mode, you have to have one conversion made.
diff --git a/Documentation/hwmon/fscher b/Documentation/hwmon/fscher
new file mode 100644
--- /dev/null
+++ b/Documentation/hwmon/fscher
@@ -0,0 +1,169 @@
+Kernel driver fscher
+====================
+
+Supported chips:
+  * Fujitsu-Siemens Hermes chip
+    Prefix: 'fscher'
+    Addresses scanned: I2C 0x73
+
+Authors:
+        Reinhard Nissl <rnissl@gmx.de> based on work
+        from Hermann Jung <hej@odn.de>,
+        Frodo Looijaard <frodol@dds.nl>,
+        Philip Edelbrock <phil@netroedge.com>
+
+Description
+-----------
+
+This driver implements support for the Fujitsu-Siemens Hermes chip. It is
+described in the 'Register Set Specification BMC Hermes based Systemboard'
+from Fujitsu-Siemens.
+
+The Hermes chip implements a hardware-based system management, e.g. for
+controlling fan speed and core voltage. There is also a watchdog counter on
+the chip which can trigger an alarm and even shut the system down.
+
+The chip provides three temperature values (CPU, motherboard and
+auxiliary), three voltage values (+12V, +5V and battery) and three fans
+(power supply, CPU and auxiliary).
+
+Temperatures are measured in degrees Celsius. The resolution is 1 degree.
+
+Fan rotation speeds are reported in RPM (rotations per minute). The value
+can be divided by a programmable divider (1, 2 or 4) which is stored on
+the chip.
+
+Voltage sensors (also known as "in" sensors) report their values in volts.
+
+All values are reported as final values from the driver. There is no need
+for further calculations.
+
+
+Detailed description
+--------------------
+
+Below you'll find a single line description of all the bit values. With
+this information, you're able to decode e. g. alarms, wdog, etc. To make
+use of the watchdog, you'll need to set the watchdog time and enable the
+watchdog. After that it is necessary to restart the watchdog time within
+the specified period of time, or a system reset will occur.
+
+* revision
+  READING & 0xff = 0x??: HERMES revision identification
+
+* alarms
+  READING & 0x80 = 0x80: CPU throttling active
+  READING & 0x80 = 0x00: CPU running at full speed
+
+  READING & 0x10 = 0x10: software event (see control:1)
+  READING & 0x10 = 0x00: no software event
+
+  READING & 0x08 = 0x08: watchdog event (see wdog:2)
+  READING & 0x08 = 0x00: no watchdog event
+
+  READING & 0x02 = 0x02: thermal event (see temp*:1)
+  READING & 0x02 = 0x00: no thermal event
+
+  READING & 0x01 = 0x01: fan event (see fan*:1)
+  READING & 0x01 = 0x00: no fan event
+
+  READING & 0x13 ! 0x00: ALERT LED is flashing
+
+* control
+  READING & 0x01 = 0x01: software event
+  READING & 0x01 = 0x00: no software event
+
+  WRITING & 0x01 = 0x01: set software event
+  WRITING & 0x01 = 0x00: clear software event
+
+* watchdog_control
+  READING & 0x80 = 0x80: power off on watchdog event while thermal event
+  READING & 0x80 = 0x00: watchdog power off disabled (just system reset enabled)
+
+  READING & 0x40 = 0x40: watchdog timebase 60 seconds (see also wdog:1)
+  READING & 0x40 = 0x00: watchdog timebase  2 seconds
+
+  READING & 0x10 = 0x10: watchdog enabled
+  READING & 0x10 = 0x00: watchdog disabled
+
+  WRITING & 0x80 = 0x80: enable "power off on watchdog event while thermal event"
+  WRITING & 0x80 = 0x00: disable "power off on watchdog event while thermal event"
+
+  WRITING & 0x40 = 0x40: set watchdog timebase to 60 seconds
+  WRITING & 0x40 = 0x00: set watchdog timebase to  2 seconds
+
+  WRITING & 0x20 = 0x20: disable watchdog
+
+  WRITING & 0x10 = 0x10: enable watchdog / restart watchdog time
+
+* watchdog_state
+  READING & 0x02 = 0x02: watchdog system reset occurred
+  READING & 0x02 = 0x00: no watchdog system reset occurred
+
+  WRITING & 0x02 = 0x02: clear watchdog event
+
+* watchdog_preset
+  READING & 0xff = 0x??: configured watch dog time in units (see wdog:3 0x40)
+
+  WRITING & 0xff = 0x??: configure watch dog time in units
+
+* in*     (0: +5V, 1: +12V, 2: onboard 3V battery)
+  READING: actual voltage value
+
+* temp*_status   (1: CPU sensor, 2: onboard sensor, 3: auxiliary sensor)
+  READING & 0x02 = 0x02: thermal event (overtemperature)
+  READING & 0x02 = 0x00: no thermal event
+
+  READING & 0x01 = 0x01: sensor is working
+  READING & 0x01 = 0x00: sensor is faulty
+
+  WRITING & 0x02 = 0x02: clear thermal event
+
+* temp*_input   (1: CPU sensor, 2: onboard sensor, 3: auxiliary sensor)
+  READING: actual temperature value
+
+* fan*_status   (1: power supply fan, 2: CPU fan, 3: auxiliary fan)
+  READING & 0x04 = 0x04: fan event (fan fault)
+  READING & 0x04 = 0x00: no fan event
+
+  WRITING & 0x04 = 0x04: clear fan event
+
+* fan*_div (1: power supply fan, 2: CPU fan, 3: auxiliary fan)
+  	Divisors 2,4 and 8 are supported, both for reading and writing
+
+* fan*_pwm   (1: power supply fan, 2: CPU fan, 3: auxiliary fan)
+  READING & 0xff = 0x00: fan may be switched off
+  READING & 0xff = 0x01: fan must run at least at minimum speed (supply: 6V)
+  READING & 0xff = 0xff: fan must run at maximum speed (supply: 12V)
+  READING & 0xff = 0x??: fan must run at least at given speed (supply: 6V..12V)
+
+  WRITING & 0xff = 0x00: fan may be switched off
+  WRITING & 0xff = 0x01: fan must run at least at minimum speed (supply: 6V)
+  WRITING & 0xff = 0xff: fan must run at maximum speed (supply: 12V)
+  WRITING & 0xff = 0x??: fan must run at least at given speed (supply: 6V..12V)
+
+* fan*_input   (1: power supply fan, 2: CPU fan, 3: auxiliary fan)
+  READING: actual RPM value
+
+
+Limitations
+-----------
+
+* Measuring fan speed
+It seems that the chip counts "ripples" (typical fans produce 2 ripples per
+rotation while VERAX fans produce 18) in a 9-bit register. This register is
+read out every second, then the ripple prescaler (2, 4 or 8) is applied and
+the result is stored in the 8 bit output register. Due to the limitation of
+the counting register to 9 bits, it is impossible to measure a VERAX fan
+properly (even with a prescaler of 8). At its maximum speed of 3500 RPM the
+fan produces 1080 ripples per second which causes the counting register to
+overflow twice, leading to only 186 RPM.
+
+* Measuring input voltages
+in2 ("battery") reports the voltage of the onboard lithium battery and not
++3.3V from the power supply.
+
+* Undocumented features
+Fujitsu-Siemens Computers has not documented all features of the chip so
+far. Their software, System Guard, shows that there are a still some
+features which cannot be controlled by this implementation.
diff --git a/Documentation/hwmon/gl518sm b/Documentation/hwmon/gl518sm
new file mode 100644
--- /dev/null
+++ b/Documentation/hwmon/gl518sm
@@ -0,0 +1,74 @@
+Kernel driver gl518sm
+=====================
+
+Supported chips:
+  * Genesys Logic GL518SM release 0x00
+    Prefix: 'gl518sm'
+    Addresses scanned: I2C 0x2c and 0x2d
+    Datasheet: http://www.genesyslogic.com/pdf
+  * Genesys Logic GL518SM release 0x80
+    Prefix: 'gl518sm'
+    Addresses scanned: I2C 0x2c and 0x2d
+    Datasheet: http://www.genesyslogic.com/pdf
+
+Authors:
+        Frodo Looijaard <frodol@dds.nl>,
+        Kyösti Mälkki <kmalkki@cc.hut.fi>
+        Hong-Gunn Chew <hglinux@gunnet.org>
+        Jean Delvare <khali@linux-fr.org>
+
+Description
+-----------
+
+IMPORTANT:
+
+For the revision 0x00 chip, the in0, in1, and in2  values (+5V, +3V,
+and +12V) CANNOT be read. This is a limitation of the chip, not the driver.
+
+This driver supports the Genesys Logic GL518SM chip. There are at least
+two revision of this chip, which we call revision 0x00 and 0x80. Revision
+0x80 chips support the reading of all voltages and revision 0x00 only
+for VIN3.
+
+The GL518SM implements one temperature sensor, two fan rotation speed
+sensors, and four voltage sensors. It can report alarms through the
+computer speakers.
+
+Temperatures are measured in degrees Celsius. An alarm goes off while the
+temperature is above the over temperature limit, and has not yet dropped
+below the hysteresis limit. The alarm always reflects the current
+situation. Measurements are guaranteed between -10 degrees and +110
+degrees, with a accuracy of +/-3 degrees.
+
+Rotation speeds are reported in RPM (rotations per minute). An alarm is
+triggered if the rotation speed has dropped below a programmable limit. In
+case when you have selected to turn fan1 off, no fan1 alarm is triggered.
+
+Fan readings can be divided by a programmable divider (1, 2, 4 or 8) to
+give the readings more range or accuracy.  Not all RPM values can
+accurately be represented, so some rounding is done. With a divider
+of 2, the lowest representable value is around 1900 RPM.
+
+Voltage sensors (also known as VIN sensors) report their values in volts.
+An alarm is triggered if the voltage has crossed a programmable minimum or
+maximum limit. Note that minimum in this case always means 'closest to
+zero'; this is important for negative voltage measurements. The VDD input
+measures voltages between 0.000 and 5.865 volt, with a resolution of 0.023
+volt. The other inputs measure voltages between 0.000 and 4.845 volt, with
+a resolution of 0.019 volt. Note that revision 0x00 chips do not support
+reading the current voltage of any input except for VIN3; limit setting and
+alarms work fine, though.
+
+When an alarm is triggered, you can be warned by a beeping signal through your
+computer speaker. It is possible to enable all beeping globally, or only the
+beeping for some alarms.
+
+If an alarm triggers, it will remain triggered until the hardware register
+is read at least once (except for temperature alarms). This means that the
+cause for the alarm may already have disappeared! Note that in the current
+implementation, all hardware registers are read whenever any data is read
+(unless it is less than 1.5 seconds since the last update). This means that
+you can easily miss once-only alarms.
+
+The GL518SM only updates its values each 1.5 seconds; reading it more often
+will do no harm, but will return 'old' values.
diff --git a/Documentation/hwmon/it87 b/Documentation/hwmon/it87
new file mode 100644
--- /dev/null
+++ b/Documentation/hwmon/it87
@@ -0,0 +1,96 @@
+Kernel driver it87
+==================
+
+Supported chips:
+  * IT8705F
+    Prefix: 'it87'
+    Addresses scanned: from Super I/O config space, or default ISA 0x290 (8 I/O ports)
+    Datasheet: Publicly available at the ITE website
+               http://www.ite.com.tw/
+  * IT8712F
+    Prefix: 'it8712'
+    Addresses scanned: I2C 0x28 - 0x2f
+                       from Super I/O config space, or default ISA 0x290 (8 I/O ports)
+    Datasheet: Publicly available at the ITE website
+               http://www.ite.com.tw/
+  * SiS950   [clone of IT8705F]
+    Prefix: 'sis950'
+    Addresses scanned: from Super I/O config space, or default ISA 0x290 (8 I/O ports)
+    Datasheet: No longer be available
+
+Author: Christophe Gauthron <chrisg@0-in.com>
+
+
+Module Parameters
+-----------------
+
+* update_vbat: int
+
+  0 if vbat should report power on value, 1 if vbat should be updated after
+  each read. Default is 0. On some boards the battery voltage is provided
+  by either the battery or the onboard power supply. Only the first reading
+  at power on will be the actual battery voltage (which the chip does
+  automatically). On other boards the battery voltage is always fed to
+  the chip so can be read at any time. Excessive reading may decrease
+  battery life but no information is given in the datasheet.
+
+* fix_pwm_polarity int
+
+  Force PWM polarity to active high (DANGEROUS). Some chips are
+  misconfigured by BIOS - PWM values would be inverted. This option tries
+  to fix this. Please contact your BIOS manufacturer and ask him for fix.
+
+Description
+-----------
+
+This driver implements support for the IT8705F, IT8712F and SiS950 chips.
+
+This driver also supports IT8712F, which adds SMBus access, and a VID
+input, used to report the Vcore voltage of the Pentium processor.
+The IT8712F additionally features VID inputs.
+
+These chips are 'Super I/O chips', supporting floppy disks, infrared ports,
+joysticks and other miscellaneous stuff. For hardware monitoring, they
+include an 'environment controller' with 3 temperature sensors, 3 fan
+rotation speed sensors, 8 voltage sensors, and associated alarms.
+
+Temperatures are measured in degrees Celsius. An alarm is triggered once
+when the Overtemperature Shutdown limit is crossed.
+
+Fan rotation speeds are reported in RPM (rotations per minute). An alarm is
+triggered if the rotation speed has dropped below a programmable limit. Fan
+readings can be divided by a programmable divider (1, 2, 4 or 8) to give the
+readings more range or accuracy. Not all RPM values can accurately be
+represented, so some rounding is done. With a divider of 2, the lowest
+representable value is around 2600 RPM.
+
+Voltage sensors (also known as IN sensors) report their values in volts. An
+alarm is triggered if the voltage has crossed a programmable minimum or
+maximum limit. Note that minimum in this case always means 'closest to
+zero'; this is important for negative voltage measurements. All voltage
+inputs can measure voltages between 0 and 4.08 volts, with a resolution of
+0.016 volt. The battery voltage in8 does not have limit registers.
+
+The VID lines (IT8712F only) encode the core voltage value: the voltage
+level your processor should work with. This is hardcoded by the mainboard
+and/or processor itself. It is a value in volts.
+
+If an alarm triggers, it will remain triggered until the hardware register
+is read at least once. This means that the cause for the alarm may already
+have disappeared! Note that in the current implementation, all hardware
+registers are read whenever any data is read (unless it is less than 1.5
+seconds since the last update). This means that you can easily miss
+once-only alarms.
+
+The IT87xx only updates its values each 1.5 seconds; reading it more often
+will do no harm, but will return 'old' values.
+
+To change sensor N to a thermistor, 'echo 2 > tempN_type' where N is 1, 2,
+or 3. To change sensor N to a thermal diode, 'echo 3 > tempN_type'.
+Give 0 for unused sensor. Any other value is invalid. To configure this at
+startup, consult lm_sensors's /etc/sensors.conf. (2 = thermistor;
+3 = thermal diode)
+
+The fan speed control features are limited to manual PWM mode. Automatic
+"Smart Guardian" mode control handling is not implemented. However
+if you want to go for "manual mode" just write 1 to pwmN_enable.
diff --git a/Documentation/hwmon/lm63 b/Documentation/hwmon/lm63
new file mode 100644
--- /dev/null
+++ b/Documentation/hwmon/lm63
@@ -0,0 +1,57 @@
+Kernel driver lm63
+==================
+
+Supported chips:
+  * National Semiconductor LM63
+    Prefix: 'lm63'
+    Addresses scanned: I2C 0x4c
+    Datasheet: Publicly available at the National Semiconductor website
+               http://www.national.com/pf/LM/LM63.html
+
+Author: Jean Delvare <khali@linux-fr.org>
+
+Thanks go to Tyan and especially Alex Buckingham for setting up a remote
+access to their S4882 test platform for this driver.
+  http://www.tyan.com/
+
+Description
+-----------
+
+The LM63 is a digital temperature sensor with integrated fan monitoring
+and control.
+
+The LM63 is basically an LM86 with fan speed monitoring and control
+capabilities added. It misses some of the LM86 features though:
+ - No low limit for local temperature.
+ - No critical limit for local temperature.
+ - Critical limit for remote temperature can be changed only once. We
+   will consider that the critical limit is read-only.
+
+The datasheet isn't very clear about what the tachometer reading is.
+
+An explanation from National Semiconductor: The two lower bits of the read
+value have to be masked out. The value is still 16 bit in width.
+
+All temperature values are given in degrees Celsius. Resolution is 1.0
+degree for the local temperature, 0.125 degree for the remote temperature.
+
+The fan speed is measured using a tachometer. Contrary to most chips which
+store the value in an 8-bit register and have a selectable clock divider
+to make sure that the result will fit in the register, the LM63 uses 16-bit
+value for measuring the speed of the fan. It can measure fan speeds down to
+83 RPM, at least in theory.
+
+Note that the pin used for fan monitoring is shared with an alert out
+function. Depending on how the board designer wanted to use the chip, fan
+speed monitoring will or will not be possible. The proper chip configuration
+is left to the BIOS, and the driver will blindly trust it.
+
+A PWM output can be used to control the speed of the fan. The LM63 has two
+PWM modes: manual and automatic. Automatic mode is not fully implemented yet
+(you cannot define your custom PWM/temperature curve), and mode change isn't
+supported either.
+
+The lm63 driver will not update its values more frequently than every
+second; reading them more often will do no harm, but will return 'old'
+values.
+
diff --git a/Documentation/hwmon/lm75 b/Documentation/hwmon/lm75
new file mode 100644
--- /dev/null
+++ b/Documentation/hwmon/lm75
@@ -0,0 +1,65 @@
+Kernel driver lm75
+==================
+
+Supported chips:
+  * National Semiconductor LM75
+    Prefix: 'lm75'
+    Addresses scanned: I2C 0x48 - 0x4f
+    Datasheet: Publicly available at the National Semiconductor website
+               http://www.national.com/
+  * Dallas Semiconductor DS75
+    Prefix: 'lm75'
+    Addresses scanned: I2C 0x48 - 0x4f
+    Datasheet: Publicly available at the Dallas Semiconductor website
+               http://www.maxim-ic.com/
+  * Dallas Semiconductor DS1775
+    Prefix: 'lm75'
+    Addresses scanned: I2C 0x48 - 0x4f
+    Datasheet: Publicly available at the Dallas Semiconductor website
+               http://www.maxim-ic.com/
+  * Maxim MAX6625, MAX6626
+    Prefix: 'lm75'
+    Addresses scanned: I2C 0x48 - 0x4b
+    Datasheet: Publicly available at the Maxim website
+               http://www.maxim-ic.com/
+  * Microchip (TelCom) TCN75
+    Prefix: 'lm75'
+    Addresses scanned: I2C 0x48 - 0x4f
+    Datasheet: Publicly available at the Microchip website
+               http://www.microchip.com/
+
+Author: Frodo Looijaard <frodol@dds.nl>
+
+Description
+-----------
+
+The LM75 implements one temperature sensor. Limits can be set through the
+Overtemperature Shutdown register and Hysteresis register. Each value can be
+set and read to half-degree accuracy.
+An alarm is issued (usually to a connected LM78) when the temperature
+gets higher then the Overtemperature Shutdown value; it stays on until
+the temperature falls below the Hysteresis value.
+All temperatures are in degrees Celsius, and are guaranteed within a
+range of -55 to +125 degrees.
+
+The LM75 only updates its values each 1.5 seconds; reading it more often
+will do no harm, but will return 'old' values.
+
+The LM75 is usually used in combination with LM78-like chips, to measure
+the temperature of the processor(s).
+
+The DS75, DS1775, MAX6625, and MAX6626 are supported as well.
+They are not distinguished from an LM75. While most of these chips
+have three additional bits of accuracy (12 vs. 9 for the LM75),
+the additional bits are not supported. Not only that, but these chips will
+not be detected if not in 9-bit precision mode (use the force parameter if
+needed).
+
+The TCN75 is supported as well, and is not distinguished from an LM75.
+
+The LM75 is essentially an industry standard; there may be other
+LM75 clones not listed here, with or without various enhancements,
+that are supported.
+
+The LM77 is not supported, contrary to what we pretended for a long time.
+Both chips are simply not compatible, value encoding differs.
diff --git a/Documentation/hwmon/lm77 b/Documentation/hwmon/lm77
new file mode 100644
--- /dev/null
+++ b/Documentation/hwmon/lm77
@@ -0,0 +1,22 @@
+Kernel driver lm77
+==================
+
+Supported chips:
+  * National Semiconductor LM77
+    Prefix: 'lm77'
+    Addresses scanned: I2C 0x48 - 0x4b
+    Datasheet: Publicly available at the National Semiconductor website
+               http://www.national.com/
+
+Author: Andras BALI <drewie@freemail.hu>
+
+Description
+-----------
+
+The LM77 implements one temperature sensor. The temperature
+sensor incorporates a band-gap type temperature sensor,
+10-bit ADC, and a digital comparator with user-programmable upper
+and lower limit values.
+
+Limits can be set through the Overtemperature Shutdown register and
+Hysteresis register.
diff --git a/Documentation/hwmon/lm78 b/Documentation/hwmon/lm78
new file mode 100644
--- /dev/null
+++ b/Documentation/hwmon/lm78
@@ -0,0 +1,82 @@
+Kernel driver lm78
+==================
+
+Supported chips:
+  * National Semiconductor LM78
+    Prefix: 'lm78'
+    Addresses scanned: I2C 0x20 - 0x2f, ISA 0x290 (8 I/O ports)
+    Datasheet: Publicly available at the National Semiconductor website
+               http://www.national.com/
+  * National Semiconductor LM78-J
+    Prefix: 'lm78-j'
+    Addresses scanned: I2C 0x20 - 0x2f, ISA 0x290 (8 I/O ports)
+    Datasheet: Publicly available at the National Semiconductor website
+               http://www.national.com/
+  * National Semiconductor LM79
+    Prefix: 'lm79'
+    Addresses scanned: I2C 0x20 - 0x2f, ISA 0x290 (8 I/O ports)
+    Datasheet: Publicly available at the National Semiconductor website
+               http://www.national.com/
+
+Author: Frodo Looijaard <frodol@dds.nl>
+
+Description
+-----------
+
+This driver implements support for the National Semiconductor LM78, LM78-J
+and LM79. They are described as 'Microprocessor System Hardware Monitors'.
+
+There is almost no difference between the three supported chips. Functionally,
+the LM78 and LM78-J are exactly identical. The LM79 has one more VID line,
+which is used to report the lower voltages newer Pentium processors use.
+From here on, LM7* means either of these three types.
+
+The LM7* implements one temperature sensor, three fan rotation speed sensors,
+seven voltage sensors, VID lines, alarms, and some miscellaneous stuff.
+
+Temperatures are measured in degrees Celsius. An alarm is triggered once
+when the Overtemperature Shutdown limit is crossed; it is triggered again
+as soon as it drops below the Hysteresis value. A more useful behavior
+can be found by setting the Hysteresis value to +127 degrees Celsius; in
+this case, alarms are issued during all the time when the actual temperature
+is above the Overtemperature Shutdown value. Measurements are guaranteed
+between -55 and +125 degrees, with a resolution of 1 degree.
+
+Fan rotation speeds are reported in RPM (rotations per minute). An alarm is
+triggered if the rotation speed has dropped below a programmable limit. Fan
+readings can be divided by a programmable divider (1, 2, 4 or 8) to give
+the readings more range or accuracy. Not all RPM values can accurately be
+represented, so some rounding is done. With a divider of 2, the lowest
+representable value is around 2600 RPM.
+
+Voltage sensors (also known as IN sensors) report their values in volts.
+An alarm is triggered if the voltage has crossed a programmable minimum
+or maximum limit. Note that minimum in this case always means 'closest to
+zero'; this is important for negative voltage measurements. All voltage
+inputs can measure voltages between 0 and 4.08 volts, with a resolution
+of 0.016 volt.
+
+The VID lines encode the core voltage value: the voltage level your processor
+should work with. This is hardcoded by the mainboard and/or processor itself.
+It is a value in volts. When it is unconnected, you will often find the
+value 3.50 V here.
+
+In addition to the alarms described above, there are a couple of additional
+ones. There is a BTI alarm, which gets triggered when an external chip has
+crossed its limits. Usually, this is connected to all LM75 chips; if at
+least one crosses its limits, this bit gets set. The CHAS alarm triggers
+if your computer case is open. The FIFO alarms should never trigger; it
+indicates an internal error. The SMI_IN alarm indicates some other chip
+has triggered an SMI interrupt. As we do not use SMI interrupts at all,
+this condition usually indicates there is a problem with some other
+device.
+
+If an alarm triggers, it will remain triggered until the hardware register
+is read at least once. This means that the cause for the alarm may
+already have disappeared! Note that in the current implementation, all
+hardware registers are read whenever any data is read (unless it is less
+than 1.5 seconds since the last update). This means that you can easily
+miss once-only alarms.
+
+The LM7* only updates its values each 1.5 seconds; reading it more often
+will do no harm, but will return 'old' values.
diff --git a/Documentation/hwmon/lm80 b/Documentation/hwmon/lm80
new file mode 100644
--- /dev/null
+++ b/Documentation/hwmon/lm80
@@ -0,0 +1,56 @@
+Kernel driver lm80
+==================
+
+Supported chips:
+  * National Semiconductor LM80
+    Prefix: 'lm80'
+    Addresses scanned: I2C 0x28 - 0x2f
+    Datasheet: Publicly available at the National Semiconductor website
+               http://www.national.com/
+
+Authors:
+        Frodo Looijaard <frodol@dds.nl>,
+        Philip Edelbrock <phil@netroedge.com>
+
+Description
+-----------
+
+This driver implements support for the National Semiconductor LM80.
+It is described as a 'Serial Interface ACPI-Compatible Microprocessor
+System Hardware Monitor'.
+
+The LM80 implements one temperature sensor, two fan rotation speed sensors,
+seven voltage sensors, alarms, and some miscellaneous stuff.
+
+Temperatures are measured in degrees Celsius. There are two sets of limits
+which operate independently. When the HOT Temperature Limit is crossed,
+this will cause an alarm that will be reasserted until the temperature
+drops below the HOT Hysteresis. The Overtemperature Shutdown (OS) limits
+should work in the same way (but this must be checked; the datasheet
+is unclear about this). Measurements are guaranteed between -55 and
++125 degrees. The current temperature measurement has a resolution of
+0.0625 degrees; the limits have a resolution of 1 degree.
+
+Fan rotation speeds are reported in RPM (rotations per minute). An alarm is
+triggered if the rotation speed has dropped below a programmable limit. Fan
+readings can be divided by a programmable divider (1, 2, 4 or 8) to give
+the readings more range or accuracy. Not all RPM values can accurately be
+represented, so some rounding is done. With a divider of 2, the lowest
+representable value is around 2600 RPM.
+
+Voltage sensors (also known as IN sensors) report their values in volts.
+An alarm is triggered if the voltage has crossed a programmable minimum
+or maximum limit. Note that minimum in this case always means 'closest to
+zero'; this is important for negative voltage measurements. All voltage
+inputs can measure voltages between 0 and 2.55 volts, with a resolution
+of 0.01 volt.
+
+If an alarm triggers, it will remain triggered until the hardware register
+is read at least once. This means that the cause for the alarm may
+already have disappeared! Note that in the current implementation, all
+hardware registers are read whenever any data is read (unless it is less
+than 2.0 seconds since the last update). This means that you can easily
+miss once-only alarms.
+
+The LM80 only updates its values each 1.5 seconds; reading it more often
+will do no harm, but will return 'old' values.
diff --git a/Documentation/hwmon/lm83 b/Documentation/hwmon/lm83
new file mode 100644
--- /dev/null
+++ b/Documentation/hwmon/lm83
@@ -0,0 +1,76 @@
+Kernel driver lm83
+==================
+
+Supported chips:
+  * National Semiconductor LM83
+    Prefix: 'lm83'
+    Addresses scanned: I2C 0x18 - 0x1a, 0x29 - 0x2b, 0x4c - 0x4e
+    Datasheet: Publicly available at the National Semiconductor website
+               http://www.national.com/pf/LM/LM83.html
+
+
+Author: Jean Delvare <khali@linux-fr.org>
+
+Description
+-----------
+
+The LM83 is a digital temperature sensor. It senses its own temperature as
+well as the temperature of up to three external diodes. It is compatible
+with many other devices such as the LM84 and all other ADM1021 clones.
+The main difference between the LM83 and the LM84 in that the later can
+only sense the temperature of one external diode.
+
+Using the adm1021 driver for a LM83 should work, but only two temperatures
+will be reported instead of four.
+
+The LM83 is only found on a handful of motherboards. Both a confirmed
+list and an unconfirmed list follow. If you can confirm or infirm the
+fact that any of these motherboards do actually have an LM83, please
+contact us. Note that the LM90 can easily be misdetected as a LM83.
+
+Confirmed motherboards:
+    SBS         P014
+
+Unconfirmed motherboards:
+    Gigabyte    GA-8IK1100
+    Iwill       MPX2
+    Soltek      SL-75DRV5
+
+The driver has been successfully tested by Magnus Forsström, who I'd
+like to thank here. More testers will be of course welcome.
+
+The fact that the LM83 is only scarcely used can be easily explained.
+Most motherboards come with more than just temperature sensors for
+health monitoring. They also have voltage and fan rotation speed
+sensors. This means that temperature-only chips are usually used as
+secondary chips coupled with another chip such as an IT8705F or similar
+chip, which provides more features. Since systems usually need three
+temperature sensors (motherboard, processor, power supply) and primary
+chips provide some temperature sensors, the secondary chip, if needed,
+won't have to handle more than two temperatures. Thus, ADM1021 clones
+are sufficient, and there is no need for a four temperatures sensor
+chip such as the LM83. The only case where using an LM83 would make
+sense is on SMP systems, such as the above-mentioned Iwill MPX2,
+because you want an additional temperature sensor for each additional
+CPU.
+
+On the SBS P014, this is different, since the LM83 is the only hardware
+monitoring chipset. One temperature sensor is used for the motherboard
+(actually measuring the LM83's own temperature), one is used for the
+CPU. The two other sensors must be used to measure the temperature of
+two other points of the motherboard. We suspect these points to be the
+north and south bridges, but this couldn't be confirmed.
+
+All temperature values are given in degrees Celsius. Local temperature
+is given within a range of 0 to +85 degrees. Remote temperatures are
+given within a range of 0 to +125 degrees. Resolution is 1.0 degree,
+accuracy is guaranteed to 3.0 degrees (see the datasheet for more
+details).
+
+Each sensor has its own high limit, but the critical limit is common to
+all four sensors. There is no hysteresis mechanism as found on most
+recent temperature sensors.
+
+The lm83 driver will not update its values more frequently than every
+other second; reading them more often will do no harm, but will return
+'old' values.
diff --git a/Documentation/hwmon/lm85 b/Documentation/hwmon/lm85
new file mode 100644
--- /dev/null
+++ b/Documentation/hwmon/lm85
@@ -0,0 +1,221 @@
+Kernel driver lm85
+==================
+
+Supported chips:
+  * National Semiconductor LM85 (B and C versions)
+    Prefix: 'lm85'
+    Addresses scanned: I2C 0x2c, 0x2d, 0x2e
+    Datasheet: http://www.national.com/pf/LM/LM85.html
+  * Analog Devices ADM1027
+    Prefix: 'adm1027'
+    Addresses scanned: I2C 0x2c, 0x2d, 0x2e
+    Datasheet: http://www.analog.com/en/prod/0,,766_825_ADM1027,00.html
+  * Analog Devices ADT7463
+    Prefix: 'adt7463'
+    Addresses scanned: I2C 0x2c, 0x2d, 0x2e
+    Datasheet: http://www.analog.com/en/prod/0,,766_825_ADT7463,00.html
+  * SMSC EMC6D100, SMSC EMC6D101
+    Prefix: 'emc6d100'
+    Addresses scanned: I2C 0x2c, 0x2d, 0x2e
+    Datasheet: http://www.smsc.com/main/tools/discontinued/6d100.pdf
+  * SMSC EMC6D102
+    Prefix: 'emc6d102'
+    Addresses scanned: I2C 0x2c, 0x2d, 0x2e
+    Datasheet: http://www.smsc.com/main/catalog/emc6d102.html
+
+Authors:
+        Philip Pokorny <ppokorny@penguincomputing.com>,
+        Frodo Looijaard <frodol@dds.nl>,
+        Richard Barrington <rich_b_nz@clear.net.nz>,
+        Margit Schubert-While <margitsw@t-online.de>,
+        Justin Thiessen <jthiessen@penguincomputing.com>
+
+Description
+-----------
+
+This driver implements support for the National Semiconductor LM85 and
+compatible chips including the Analog Devices ADM1027, ADT7463 and
+SMSC EMC6D10x chips family.
+
+The LM85 uses the 2-wire interface compatible with the SMBUS 2.0
+specification. Using an analog to digital converter it measures three (3)
+temperatures and five (5) voltages. It has four (4) 16-bit counters for
+measuring fan speed. Five (5) digital inputs are provided for sampling the
+VID signals from the processor to the VRM. Lastly, there are three (3) PWM
+outputs that can be used to control fan speed.
+
+The voltage inputs have internal scaling resistors so that the following
+voltage can be measured without external resistors:
+
+  2.5V, 3.3V, 5V, 12V, and CPU core voltage (2.25V)
+
+The temperatures measured are one internal diode, and two remote diodes.
+Remote 1 is generally the CPU temperature. These inputs are designed to
+measure a thermal diode like the one in a Pentium 4 processor in a socket
+423 or socket 478 package. They can also measure temperature using a
+transistor like the 2N3904.
+
+A sophisticated control system for the PWM outputs is designed into the
+LM85 that allows fan speed to be adjusted automatically based on any of the
+three temperature sensors. Each PWM output is individually adjustable and
+programmable. Once configured, the LM85 will adjust the PWM outputs in
+response to the measured temperatures without further host intervention.
+This feature can also be disabled for manual control of the PWM's.
+
+Each of the measured inputs (voltage, temperature, fan speed) has
+corresponding high/low limit values. The LM85 will signal an ALARM if any
+measured value exceeds either limit.
+
+The LM85 samples all inputs continuously. The lm85 driver will not read
+the registers more often than once a second. Further, configuration data is
+only read once each 5 minutes. There is twice as much config data as
+measurements, so this would seem to be a worthwhile optimization.
+
+Special Features
+----------------
+
+The LM85 has four fan speed monitoring modes. The ADM1027 has only two.
+Both have special circuitry to compensate for PWM interactions with the
+TACH signal from the fans. The ADM1027 can be configured to measure the
+speed of a two wire fan, but the input conditioning circuitry is different
+for 3-wire and 2-wire mode. For this reason, the 2-wire fan modes are not
+exposed to user control. The BIOS should initialize them to the correct
+mode. If you've designed your own ADM1027, you'll have to modify the
+init_client function and add an insmod parameter to set this up.
+
+To smooth the response of fans to changes in temperature, the LM85 has an
+optional filter for smoothing temperatures. The ADM1027 has the same
+config option but uses it to rate limit the changes to fan speed instead.
+
+The ADM1027 and ADT7463 have a 10-bit ADC and can therefore measure
+temperatures with 0.25 degC resolution. They also provide an offset to the
+temperature readings that is automatically applied during measurement.
+This offset can be used to zero out any errors due to traces and placement.
+The documentation says that the offset is in 0.25 degC steps, but in
+initial testing of the ADM1027 it was 1.00 degC steps. Analog Devices has
+confirmed this "bug". The ADT7463 is reported to work as described in the
+documentation. The current lm85 driver does not show the offset register.
+
+The ADT7463 has a THERM asserted counter. This counter has a 22.76ms
+resolution and a range of 5.8 seconds. The driver implements a 32-bit
+accumulator of the counter value to extend the range to over a year. The
+counter will stay at it's max value until read.
+
+See the vendor datasheets for more information. There is application note
+from National (AN-1260) with some additional information about the LM85.
+The Analog Devices datasheet is very detailed and describes a procedure for
+determining an optimal configuration for the automatic PWM control.
+
+The SMSC EMC6D100 & EMC6D101 monitor external voltages, temperatures, and
+fan speeds. They use this monitoring capability to alert the system to out
+of limit conditions and can automatically control the speeds of multiple
+fans in a PC or embedded system. The EMC6D101, available in a 24-pin SSOP
+package, and the EMC6D100, available in a 28-pin SSOP package, are designed
+to be register compatible. The EMC6D100 offers all the features of the
+EMC6D101 plus additional voltage monitoring and system control features.
+Unfortunately it is not possible to distinguish between the package
+versions on register level so these additional voltage inputs may read
+zero. The EMC6D102 features addtional ADC bits thus extending precision
+of voltage and temperature channels.
+
+
+Hardware Configurations
+-----------------------
+
+The LM85 can be jumpered for 3 different SMBus addresses. There are
+no other hardware configuration options for the LM85.
+
+The lm85 driver detects both LM85B and LM85C revisions of the chip. See the
+datasheet for a complete description of the differences. Other than
+identifying the chip, the driver behaves no differently with regard to
+these two chips. The LM85B is recommended for new designs.
+
+The ADM1027 and ADT7463 chips have an optional SMBALERT output that can be
+used to signal the chipset in case a limit is exceeded or the temperature
+sensors fail. Individual sensor interrupts can be masked so they won't
+trigger SMBALERT. The SMBALERT output if configured replaces one of the other
+functions (PWM2 or IN0). This functionality is not implemented in current
+driver.
+
+The ADT7463 also has an optional THERM output/input which can be connected
+to the processor PROC_HOT output. If available, the autofan control
+dynamic Tmin feature can be enabled to keep the system temperature within
+spec (just?!) with the least possible fan noise.
+
+Configuration Notes
+-------------------
+
+Besides standard interfaces driver adds following:
+
+* Temperatures and Zones
+
+Each temperature sensor is associated with a Zone. There are three
+sensors and therefore three zones (# 1, 2 and 3). Each zone has the following
+temperature configuration points:
+
+* temp#_auto_temp_off - temperature below which fans should be off or spinning very low.
+* temp#_auto_temp_min - temperature over which fans start to spin.
+* temp#_auto_temp_max - temperature when fans spin at full speed.
+* temp#_auto_temp_crit - temperature when all fans will run full speed.
+
+* PWM Control
+
+There are three PWM outputs. The LM85 datasheet suggests that the
+pwm3 output control both fan3 and fan4. Each PWM can be individually
+configured and assigned to a zone for it's control value. Each PWM can be
+configured individually according to the following options.
+
+* pwm#_auto_pwm_min - this specifies the PWM value for temp#_auto_temp_off
+                      temperature. (PWM value from 0 to 255)
+
+* pwm#_auto_pwm_freq - select base frequency of PWM output. You can select
+                       in range of 10.0 to 94.0 Hz in .1 Hz units.
+		       (Values 100 to 940).
+
+The pwm#_auto_pwm_freq can be set to one of the following 8 values. Setting the
+frequency to a value not on this list, will result in the next higher frequency
+being selected. The actual device frequency may vary slightly from this
+specification as designed by the manufacturer. Consult the datasheet for more
+details. (PWM Frequency values:  100, 150, 230, 300, 380, 470, 620, 940)
+
+* pwm#_auto_pwm_minctl - this flags selects for temp#_auto_temp_off temperature
+                         the bahaviour of fans. Write 1 to let fans spinning at
+			 pwm#_auto_pwm_min or write 0 to let them off.
+
+NOTE: It has been reported that there is a bug in the LM85 that causes the flag
+to be associated with the zones not the PWMs. This contradicts all the
+published documentation. Setting pwm#_min_ctl in this case actually affects all
+PWMs controlled by zone '#'.
+
+* PWM Controlling Zone selection
+
+* pwm#_auto_channels - controls zone that is associated with PWM
+
+Configuration choices:
+
+   Value     Meaning
+  ------  ------------------------------------------------
+      1    Controlled by Zone 1
+      2    Controlled by Zone 2
+      3    Controlled by Zone 3
+     23    Controlled by higher temp of Zone 2 or 3
+    123    Controlled by highest temp of Zone 1, 2 or 3
+      0    PWM always 0%  (off)
+     -1    PWM always 100%  (full on)
+     -2    Manual control (write to 'pwm#' to set)
+
+The National LM85's have two vendor specific configuration
+features. Tach. mode and Spinup Control. For more details on these,
+see the LM85 datasheet or Application Note AN-1260.
+
+The Analog Devices ADM1027 has several vendor specific enhancements.
+The number of pulses-per-rev of the fans can be set, Tach monitoring
+can be optimized for PWM operation, and an offset can be applied to
+the temperatures to compensate for systemic errors in the
+measurements.
+
+In addition to the ADM1027 features, the ADT7463 also has Tmin control
+and THERM asserted counts. Automatic Tmin control acts to adjust the
+Tmin value to maintain the measured temperature sensor at a specified
+temperature. There isn't much documentation on this feature in the
+ADT7463 data sheet. This is not supported by current driver.
diff --git a/Documentation/hwmon/lm87 b/Documentation/hwmon/lm87
new file mode 100644
--- /dev/null
+++ b/Documentation/hwmon/lm87
@@ -0,0 +1,73 @@
+Kernel driver lm87
+==================
+
+Supported chips:
+  * National Semiconductor LM87
+    Prefix: 'lm87'
+    Addresses scanned: I2C 0x2c - 0x2f
+    Datasheet: http://www.national.com/pf/LM/LM87.html
+
+Authors:
+        Frodo Looijaard <frodol@dds.nl>,
+        Philip Edelbrock <phil@netroedge.com>,
+        Mark Studebaker <mdsxyz123@yahoo.com>,
+        Stephen Rousset <stephen.rousset@rocketlogix.com>,
+        Dan Eaton <dan.eaton@rocketlogix.com>,
+        Jean Delvare <khali@linux-fr.org>,
+        Original 2.6 port Jeff Oliver
+
+Description
+-----------
+
+This driver implements support for the National Semiconductor LM87.
+
+The LM87 implements up to three temperature sensors, up to two fan
+rotation speed sensors, up to seven voltage sensors, alarms, and some
+miscellaneous stuff.
+
+Temperatures are measured in degrees Celsius. Each input has a high
+and low alarm settings. A high limit produces an alarm when the value
+goes above it, and an alarm is also produced when the value goes below
+the low limit.
+
+Fan rotation speeds are reported in RPM (rotations per minute). An alarm is
+triggered if the rotation speed has dropped below a programmable limit. Fan
+readings can be divided by a programmable divider (1, 2, 4 or 8) to give
+the readings more range or accuracy. Not all RPM values can accurately be
+represented, so some rounding is done. With a divider of 2, the lowest
+representable value is around 2600 RPM.
+
+Voltage sensors (also known as IN sensors) report their values in
+volts. An alarm is triggered if the voltage has crossed a programmable
+minimum or maximum limit. Note that minimum in this case always means
+'closest to zero'; this is important for negative voltage measurements.
+
+If an alarm triggers, it will remain triggered until the hardware register
+is read at least once. This means that the cause for the alarm may
+already have disappeared! Note that in the current implementation, all
+hardware registers are read whenever any data is read (unless it is less
+than 1.0 seconds since the last update). This means that you can easily
+miss once-only alarms.
+
+The lm87 driver only updates its values each 1.0 seconds; reading it more
+often will do no harm, but will return 'old' values.
+
+
+Hardware Configurations
+-----------------------
+
+The LM87 has four pins which can serve one of two possible functions,
+depending on the hardware configuration.
+
+Some functions share pins, so not all functions are available at the same
+time. Which are depends on the hardware setup. This driver assumes that
+the BIOS configured the chip correctly. In that respect, it differs from
+the original driver (from lm_sensors for Linux 2.4), which would force the
+LM87 to an arbitrary, compile-time chosen mode, regardless of the actual
+chipset wiring.
+
+For reference, here is the list of exclusive functions:
+ - in0+in5 (default) or temp3
+ - fan1 (default) or in6
+ - fan2 (default) or in7
+ - VID lines (default) or IRQ lines (not handled by this driver)
diff --git a/Documentation/hwmon/lm90 b/Documentation/hwmon/lm90
new file mode 100644
--- /dev/null
+++ b/Documentation/hwmon/lm90
@@ -0,0 +1,121 @@
+Kernel driver lm90
+==================
+
+Supported chips:
+  * National Semiconductor LM90
+    Prefix: 'lm90'
+    Addresses scanned: I2C 0x4c
+    Datasheet: Publicly available at the National Semiconductor website
+               http://www.national.com/pf/LM/LM90.html
+  * National Semiconductor LM89
+    Prefix: 'lm99'
+    Addresses scanned: I2C 0x4c and 0x4d
+    Datasheet: Publicly available at the National Semiconductor website
+               http://www.national.com/pf/LM/LM89.html
+  * National Semiconductor LM99
+    Prefix: 'lm99'
+    Addresses scanned: I2C 0x4c and 0x4d
+    Datasheet: Publicly available at the National Semiconductor website
+               http://www.national.com/pf/LM/LM99.html
+  * National Semiconductor LM86
+    Prefix: 'lm86'
+    Addresses scanned: I2C 0x4c
+    Datasheet: Publicly available at the National Semiconductor website
+               http://www.national.com/pf/LM/LM86.html
+  * Analog Devices ADM1032
+    Prefix: 'adm1032'
+    Addresses scanned: I2C 0x4c
+    Datasheet: Publicly available at the Analog Devices website
+               http://products.analog.com/products/info.asp?product=ADM1032
+  * Analog Devices ADT7461
+    Prefix: 'adt7461'
+    Addresses scanned: I2C 0x4c
+    Datasheet: Publicly available at the Analog Devices website
+               http://products.analog.com/products/info.asp?product=ADT7461
+    Note: Only if in ADM1032 compatibility mode
+  * Maxim MAX6657
+    Prefix: 'max6657'
+    Addresses scanned: I2C 0x4c
+    Datasheet: Publicly available at the Maxim website
+               http://www.maxim-ic.com/quick_view2.cfm/qv_pk/2578
+  * Maxim MAX6658
+    Prefix: 'max6657'
+    Addresses scanned: I2C 0x4c
+    Datasheet: Publicly available at the Maxim website
+               http://www.maxim-ic.com/quick_view2.cfm/qv_pk/2578
+  * Maxim MAX6659
+    Prefix: 'max6657'
+    Addresses scanned: I2C 0x4c, 0x4d (unsupported 0x4e)
+    Datasheet: Publicly available at the Maxim website
+               http://www.maxim-ic.com/quick_view2.cfm/qv_pk/2578
+
+
+Author: Jean Delvare <khali@linux-fr.org>
+
+
+Description
+-----------
+
+The LM90 is a digital temperature sensor. It senses its own temperature as
+well as the temperature of up to one external diode. It is compatible
+with many other devices such as the LM86, the LM89, the LM99, the ADM1032,
+the MAX6657, MAX6658 and the MAX6659 all of which are supported by this driver.
+Note that there is no easy way to differentiate between the last three
+variants. The extra address and features of the MAX6659 are not supported by
+this driver. Additionally, the ADT7461 is supported if found in ADM1032
+compatibility mode.
+
+The specificity of this family of chipsets over the ADM1021/LM84
+family is that it features critical limits with hysteresis, and an
+increased resolution of the remote temperature measurement.
+
+The different chipsets of the family are not strictly identical, although
+very similar. This driver doesn't handle any specific feature for now,
+but could if there ever was a need for it. For reference, here comes a
+non-exhaustive list of specific features:
+
+LM90:
+  * Filter and alert configuration register at 0xBF.
+  * ALERT is triggered by temperatures over critical limits.
+
+LM86 and LM89:
+  * Same as LM90
+  * Better external channel accuracy
+
+LM99:
+  * Same as LM89
+  * External temperature shifted by 16 degrees down
+
+ADM1032:
+  * Consecutive alert register at 0x22.
+  * Conversion averaging.
+  * Up to 64 conversions/s.
+  * ALERT is triggered by open remote sensor.
+
+ADT7461
+  * Extended temperature range (breaks compatibility)
+  * Lower resolution for remote temperature
+
+MAX6657 and MAX6658:
+  * Remote sensor type selection
+
+MAX6659
+  * Selectable address
+  * Second critical temperature limit
+  * Remote sensor type selection
+
+All temperature values are given in degrees Celsius. Resolution
+is 1.0 degree for the local temperature, 0.125 degree for the remote
+temperature.
+
+Each sensor has its own high and low limits, plus a critical limit.
+Additionally, there is a relative hysteresis value common to both critical
+values. To make life easier to user-space applications, two absolute values
+are exported, one for each channel, but these values are of course linked.
+Only the local hysteresis can be set from user-space, and the same delta
+applies to the remote hysteresis.
+
+The lm90 driver will not update its values more frequently than every
+other second; reading them more often will do no harm, but will return
+'old' values.
+
diff --git a/Documentation/hwmon/lm92 b/Documentation/hwmon/lm92
new file mode 100644
--- /dev/null
+++ b/Documentation/hwmon/lm92
@@ -0,0 +1,37 @@
+Kernel driver lm92
+==================
+
+Supported chips:
+  * National Semiconductor LM92
+    Prefix: 'lm92'
+    Addresses scanned: I2C 0x48 - 0x4b
+    Datasheet: http://www.national.com/pf/LM/LM92.html
+  * National Semiconductor LM76
+    Prefix: 'lm92'
+    Addresses scanned: none, force parameter needed
+    Datasheet: http://www.national.com/pf/LM/LM76.html
+  * Maxim MAX6633/MAX6634/MAX6635
+    Prefix: 'lm92'
+    Addresses scanned: I2C 0x48 - 0x4b
+    MAX6633 with address in 0x40 - 0x47, 0x4c - 0x4f needs force parameter
+    and MAX6634 with address in 0x4c - 0x4f needs force parameter
+    Datasheet: http://www.maxim-ic.com/quick_view2.cfm/qv_pk/3074
+
+Authors:
+        Abraham van der Merwe <abraham@2d3d.co.za>
+        Jean Delvare <khali@linux-fr.org>
+
+
+Description
+-----------
+
+This driver implements support for the National Semiconductor LM92
+temperature sensor.
+
+Each LM92 temperature sensor supports a single temperature sensor. There are
+alarms for high, low, and critical thresholds. There's also an hysteresis to
+control the thresholds for resetting alarms.
+
+Support was added later for the LM76 and Maxim MAX6633/MAX6634/MAX6635,
+which are mostly compatible. They have not all been tested, so you
+may need to use the force parameter.
diff --git a/Documentation/hwmon/max1619 b/Documentation/hwmon/max1619
new file mode 100644
--- /dev/null
+++ b/Documentation/hwmon/max1619
@@ -0,0 +1,29 @@
+Kernel driver max1619
+=====================
+
+Supported chips:
+  * Maxim MAX1619
+    Prefix: 'max1619'
+    Addresses scanned: I2C 0x18-0x1a, 0x29-0x2b, 0x4c-0x4e
+    Datasheet: Publicly available at the Maxim website
+               http://pdfserv.maxim-ic.com/en/ds/MAX1619.pdf
+
+Authors:
+        Alexey Fisher <fishor@mail.ru>,
+        Jean Delvare <khali@linux-fr.org>
+
+Description
+-----------
+
+The MAX1619 is a digital temperature sensor. It senses its own temperature as
+well as the temperature of up to one external diode.
+
+All temperature values are given in degrees Celsius. Resolution
+is 1.0 degree for the local temperature and for the remote temperature.
+
+Only the external sensor has high and low limits.
+
+The max1619 driver will not update its values more frequently than every
+other second; reading them more often will do no harm, but will return
+'old' values.
+
diff --git a/Documentation/hwmon/pc87360 b/Documentation/hwmon/pc87360
new file mode 100644
--- /dev/null
+++ b/Documentation/hwmon/pc87360
@@ -0,0 +1,189 @@
+Kernel driver pc87360
+=====================
+
+Supported chips:
+  * National Semiconductor PC87360, PC87363, PC87364, PC87365 and PC87366
+    Prefixes: 'pc87360', 'pc87363', 'pc87364', 'pc87365', 'pc87366'
+    Addresses scanned: none, address read from Super I/O config space
+    Datasheets:
+        http://www.national.com/pf/PC/PC87360.html
+        http://www.national.com/pf/PC/PC87363.html
+        http://www.national.com/pf/PC/PC87364.html
+        http://www.national.com/pf/PC/PC87365.html
+        http://www.national.com/pf/PC/PC87366.html
+
+Authors: Jean Delvare <khali@linux-fr.org>
+
+Thanks to Sandeep Mehta, Tonko de Rooy and Daniel Ceregatti for testing.
+Thanks to Rudolf Marek for helping me investigate conversion issues.
+
+
+Module Parameters
+-----------------
+
+* init int
+  Chip initialization level:
+   0: None
+  *1: Forcibly enable internal voltage and temperature channels, except in9
+   2: Forcibly enable all voltage and temperature channels, except in9
+   3: Forcibly enable all voltage and temperature channels, including in9
+
+Note that this parameter has no effect for the PC87360, PC87363 and PC87364
+chips.
+
+Also note that for the PC87366, initialization levels 2 and 3 don't enable
+all temperature channels, because some of them share pins with each other,
+so they can't be used at the same time.
+
+
+Description
+-----------
+
+The National Semiconductor PC87360 Super I/O chip contains monitoring and
+PWM control circuitry for two fans. The PC87363 chip is similar, and the
+PC87364 chip has monitoring and PWM control for a third fan.
+
+The National Semiconductor PC87365 and PC87366 Super I/O chips are complete
+hardware monitoring chipsets, not only controlling and monitoring three fans,
+but also monitoring eleven voltage inputs and two (PC87365) or up to four
+(PC87366) temperatures.
+
+  Chip        #vin    #fan    #pwm    #temp   devid
+
+  PC87360     -       2       2       -       0xE1
+  PC87363     -       2       2       -       0xE8
+  PC87364     -       3       3       -       0xE4
+  PC87365     11      3       3       2       0xE5
+  PC87366     11      3       3       3-4     0xE9
+
+The driver assumes that no more than one chip is present, and one of the
+standard Super I/O addresses is used (0x2E/0x2F or 0x4E/0x4F)
+
+Fan Monitoring
+--------------
+
+Fan rotation speeds are reported in RPM (revolutions per minute). An alarm
+is triggered if the rotation speed has dropped below a programmable limit.
+A different alarm is triggered if the fan speed is too low to be measured.
+
+Fan readings are affected by a programmable clock divider, giving the
+readings more range or accuracy. Usually, users have to learn how it works,
+but this driver implements dynamic clock divider selection, so you don't
+have to care no more.
+
+For reference, here are a few values about clock dividers:
+
+                slowest         accuracy        highest
+                measurable      around 3000     accurate
+    divider     speed (RPM)     RPM (RPM)       speed (RPM)
+         1        1882              18           6928
+         2         941              37           4898
+         4         470              74           3464
+         8         235             150           2449
+
+For the curious, here is how the values above were computed:
+ * slowest measurable speed: clock/(255*divider)
+ * accuracy around 3000 RPM: 3000^2/clock
+ * highest accurate speed: sqrt(clock*100)
+The clock speed for the PC87360 family is 480 kHz. I arbitrarily chose 100
+RPM as the lowest acceptable accuracy.
+
+As mentioned above, you don't have to care about this no more.
+
+Note that not all RPM values can be represented, even when the best clock
+divider is selected. This is not only true for the measured speeds, but
+also for the programmable low limits, so don't be surprised if you try to
+set, say, fan1_min to 2900 and it finally reads 2909.
+
+
+Fan Control
+-----------
+
+PWM (pulse width modulation) values range from 0 to 255, with 0 meaning
+that the fan is stopped, and 255 meaning that the fan goes at full speed.
+
+Be extremely careful when changing PWM values. Low PWM values, even
+non-zero, can stop the fan, which may cause irreversible damage to your
+hardware if temperature increases too much. When changing PWM values, go
+step by step and keep an eye on temperatures.
+
+One user reported problems with PWM. Changing PWM values would break fan
+speed readings. No explanation nor fix could be found.
+
+
+Temperature Monitoring
+----------------------
+
+Temperatures are reported in degrees Celsius. Each temperature measured has
+associated low, high and overtemperature limits, each of which triggers an
+alarm when crossed.
+
+The first two temperature channels are external. The third one (PC87366
+only) is internal.
+
+The PC87366 has three additional temperature channels, based on
+thermistors (as opposed to thermal diodes for the first three temperature
+channels). For technical reasons, these channels are held by the VLM
+(voltage level monitor) logical device, not the TMS (temperature
+measurement) one. As a consequence, these temperatures are exported as
+voltages, and converted into temperatures in user-space.
+
+Note that these three additional channels share their pins with the
+external thermal diode channels, so you (physically) can't use them all at
+the same time. Although it should be possible to mix the two sensor types,
+the documents from National Semiconductor suggest that motherboard
+manufacturers should choose one type and stick to it. So you will more
+likely have either channels 1 to 3 (thermal diodes) or 3 to 6 (internal
+thermal diode, and thermistors).
+
+
+Voltage Monitoring
+------------------
+
+Voltages are reported relatively to a reference voltage, either internal or
+external. Some of them (in7:Vsb, in8:Vdd and in10:AVdd) are divided by two
+internally, you will have to compensate in sensors.conf. Others (in0 to in6)
+are likely to be divided externally. The meaning of each of these inputs as
+well as the values of the resistors used for division is left to the
+motherboard manufacturers, so you will have to document yourself and edit
+sensors.conf accordingly. National Semiconductor has a document with
+recommended resistor values for some voltages, but this still leaves much
+room for per motherboard specificities, unfortunately. Even worse,
+motherboard manufacturers don't seem to care about National Semiconductor's
+recommendations.
+
+Each voltage measured has associated low and high limits, each of which
+triggers an alarm when crossed.
+
+When available, VID inputs are used to provide the nominal CPU Core voltage.
+The driver will default to VRM 9.0, but this can be changed from user-space.
+The chipsets can handle two sets of VID inputs (on dual-CPU systems), but
+the driver will only export one for now. This may change later if there is
+a need.
+
+
+General Remarks
+---------------
+
+If an alarm triggers, it will remain triggered until the hardware register
+is read at least once. This means that the cause for the alarm may already
+have disappeared! Note that all hardware registers are read whenever any
+data is read (unless it is less than 2 seconds since the last update, in
+which case cached values are returned instead). As a consequence, when
+a once-only alarm triggers, it may take 2 seconds for it to show, and 2
+more seconds for it to disappear.
+
+Monitoring of in9 isn't enabled at lower init levels (<3) because that
+channel measures the battery voltage (Vbat). It is a known fact that
+repeatedly sampling the battery voltage reduces its lifetime. National
+Semiconductor smartly designed their chipset so that in9 is sampled only
+once every 1024 sampling cycles (that is every 34 minutes at the default
+sampling rate), so the effect is attenuated, but still present.
+
+
+Limitations
+-----------
+
+The datasheets suggests that some values (fan mins, fan dividers)
+shouldn't be changed once the monitoring has started, but we ignore that
+recommendation. We'll reconsider if it actually causes trouble.
diff --git a/Documentation/hwmon/sis5595 b/Documentation/hwmon/sis5595
new file mode 100644
--- /dev/null
+++ b/Documentation/hwmon/sis5595
@@ -0,0 +1,106 @@
+Kernel driver sis5595
+=====================
+
+Supported chips:
+  * Silicon Integrated Systems Corp. SiS5595 Southbridge Hardware Monitor
+    Prefix: 'sis5595'
+    Addresses scanned: ISA in PCI-space encoded address
+    Datasheet: Publicly available at the Silicon Integrated Systems Corp. site.
+
+Authors:
+        Kyösti Mälkki <kmalkki@cc.hut.fi>,
+        Mark D. Studebaker <mdsxyz123@yahoo.com>,
+        Aurelien Jarno <aurelien@aurel32.net> 2.6 port
+
+   SiS southbridge has a LM78-like chip integrated on the same IC.
+   This driver is a customized copy of lm78.c
+
+   Supports following revisions:
+       Version         PCI ID          PCI Revision
+       1               1039/0008       AF or less
+       2               1039/0008       B0 or greater
+
+   Note: these chips contain a 0008 device which is incompatible with the
+        5595. We recognize these by the presence of the listed
+        "blacklist" PCI ID and refuse to load.
+
+   NOT SUPPORTED       PCI ID          BLACKLIST PCI ID
+        540            0008            0540
+        550            0008            0550
+       5513            0008            5511
+       5581            0008            5597
+       5582            0008            5597
+       5597            0008            5597
+        630            0008            0630
+        645            0008            0645
+        730            0008            0730
+        735            0008            0735
+
+
+Module Parameters
+-----------------
+force_addr=0xaddr	Set the I/O base address. Useful for boards
+			that don't set the address in the BIOS. Does not do a
+			PCI force; the device must still be present in lspci.
+			Don't use this unless the driver complains that the
+			base address is not set.
+			Example: 'modprobe sis5595 force_addr=0x290'
+
+
+Description
+-----------
+
+The SiS5595 southbridge has integrated hardware monitor functions. It also
+has an I2C bus, but this driver only supports the hardware monitor. For the
+I2C bus driver see i2c-sis5595.
+
+The SiS5595 implements zero or one temperature sensor, two fan speed
+sensors, four or five voltage sensors, and alarms.
+
+On the first version of the chip, there are four voltage sensors and one
+temperature sensor.
+
+On the second version of the chip, the temperature sensor (temp) and the
+fifth voltage sensor (in4) share a pin which is configurable, but not
+through the driver. Sorry. The driver senses the configuration of the pin,
+which was hopefully set by the BIOS.
+
+Temperatures are measured in degrees Celsius. An alarm is triggered once
+when the max is crossed; it is also triggered when it drops below the min
+value. Measurements are guaranteed between -55 and +125 degrees, with a
+resolution of 1 degree.
+
+Fan rotation speeds are reported in RPM (rotations per minute). An alarm is
+triggered if the rotation speed has dropped below a programmable limit. Fan
+readings can be divided by a programmable divider (1, 2, 4 or 8) to give
+the readings more range or accuracy. Not all RPM values can accurately be
+represented, so some rounding is done. With a divider of 2, the lowest
+representable value is around 2600 RPM.
+
+Voltage sensors (also known as IN sensors) report their values in volts. An
+alarm is triggered if the voltage has crossed a programmable minimum or
+maximum limit. Note that minimum in this case always means 'closest to
+zero'; this is important for negative voltage measurements. All voltage
+inputs can measure voltages between 0 and 4.08 volts, with a resolution of
+0.016 volt.
+
+In addition to the alarms described above, there is a BTI alarm, which gets
+triggered when an external chip has crossed its limits. Usually, this is
+connected to some LM75-like chip; if at least one crosses its limits, this
+bit gets set.
+
+If an alarm triggers, it will remain triggered until the hardware register
+is read at least once. This means that the cause for the alarm may already
+have disappeared! Note that in the current implementation, all hardware
+registers are read whenever any data is read (unless it is less than 1.5
+seconds since the last update). This means that you can easily miss
+once-only alarms.
+
+The SiS5595 only updates its values each 1.5 seconds; reading it more often
+will do no harm, but will return 'old' values.
+
+Problems
+--------
+Some chips refuse to be enabled. We don't know why.
+The driver will recognize this and print a message in dmesg.
+
diff --git a/Documentation/hwmon/smsc47b397 b/Documentation/hwmon/smsc47b397
new file mode 100644
--- /dev/null
+++ b/Documentation/hwmon/smsc47b397
@@ -0,0 +1,158 @@
+Kernel driver smsc47b397
+========================
+
+Supported chips:
+  * SMSC LPC47B397-NC
+    Prefix: 'smsc47b397'
+    Addresses scanned: none, address read from Super I/O config space
+    Datasheet: In this file
+
+Authors: Mark M. Hoffman <mhoffman@lightlink.com>
+         Utilitek Systems, Inc.
+
+November 23, 2004
+
+The following specification describes the SMSC LPC47B397-NC sensor chip
+(for which there is no public datasheet available). This document was
+provided by Craig Kelly (In-Store Broadcast Network) and edited/corrected
+by Mark M. Hoffman <mhoffman@lightlink.com>.
+
+* * * * *
+
+Methods for detecting the HP SIO and reading the thermal data on a dc7100.
+
+The thermal information on the dc7100 is contained in the SIO Hardware Monitor
+(HWM). The information is accessed through an index/data pair. The index/data
+pair is located at the HWM Base Address + 0 and the HWM Base Address + 1. The
+HWM Base address can be obtained from Logical Device 8, registers 0x60 (MSB)
+and 0x61 (LSB). Currently we are using 0x480 for the HWM Base Address and
+0x480 and 0x481 for the index/data pair.
+
+Reading temperature information.
+The temperature information is located in the following registers:
+Temp1		0x25	(Currently, this reflects the CPU temp on all systems).
+Temp2		0x26
+Temp3		0x27
+Temp4		0x80
+
+Programming Example
+The following is an example of how to read the HWM temperature registers:
+MOV	DX,480H
+MOV	AX,25H
+OUT	DX,AL
+MOV	DX,481H
+IN	AL,DX
+
+AL contains the data in hex, the temperature in Celsius is the decimal
+equivalent.
+
+Ex: If AL contains 0x2A, the temperature is 42 degrees C.
+
+Reading tach information.
+The fan speed information is located in the following registers:
+		LSB	MSB
+Tach1		0x28	0x29	(Currently, this reflects the CPU
+				fan speed on all systems).
+Tach2		0x2A	0x2B
+Tach3		0x2C	0x2D
+Tach4		0x2E	0x2F
+
+Important!!!
+Reading the tach LSB locks the tach MSB.
+The LSB Must be read first.
+
+How to convert the tach reading to RPM.
+The tach reading (TCount) is given by: (Tach MSB * 256) + (Tach LSB)
+The SIO counts the number of 90kHz (11.111us) pulses per revolution.
+RPM = 60/(TCount * 11.111us)
+
+Example:
+Reg 0x28 = 0x9B
+Reg 0x29 = 0x08
+
+TCount = 0x89B = 2203
+
+RPM = 60 / (2203 * 11.11111 E-6) = 2451 RPM
+
+Obtaining the SIO version.
+
+CONFIGURATION SEQUENCE
+To program the configuration registers, the following sequence must be followed:
+1. Enter Configuration Mode
+2. Configure the Configuration Registers
+3. Exit Configuration Mode.
+
+Enter Configuration Mode
+To place the chip into the Configuration State The config key (0x55) is written
+to the CONFIG PORT (0x2E).
+
+Configuration Mode
+In configuration mode, the INDEX PORT is located at the CONFIG PORT address and
+the DATA PORT is at INDEX PORT address + 1.
+
+The desired configuration registers are accessed in two steps:
+a.	Write the index of the Logical Device Number Configuration Register
+	(i.e., 0x07) to the INDEX PORT and then write the number of the
+	desired logical device to the DATA PORT.
+
+b.	Write the address of the desired configuration register within the
+	logical device to the INDEX PORT and then write or read the config-
+	uration register through the DATA PORT.
+
+Note: If accessing the Global Configuration Registers, step (a) is not required.
+
+Exit Configuration Mode
+To exit the Configuration State the write 0xAA to the CONFIG PORT (0x2E).
+The chip returns to the RUN State.  (This is important).
+
+Programming Example
+The following is an example of how to read the SIO Device ID located at 0x20
+
+; ENTER CONFIGURATION MODE
+MOV	DX,02EH
+MOV	AX,055H
+OUT	DX,AL
+; GLOBAL CONFIGURATION  REGISTER
+MOV	DX,02EH
+MOV	AL,20H
+OUT	DX,AL
+; READ THE DATA
+MOV	DX,02FH
+IN	AL,DX
+; EXIT CONFIGURATION MODE
+MOV	DX,02EH
+MOV	AX,0AAH
+OUT	DX,AL
+
+The registers of interest for identifying the SIO on the dc7100 are Device ID
+(0x20) and Device Rev  (0x21).
+
+The Device ID will read 0X6F
+The Device Rev currently reads 0x01
+
+Obtaining the HWM Base Address.
+The following is an example of how to read the HWM Base Address located in
+Logical Device 8.
+
+; ENTER CONFIGURATION MODE
+MOV	DX,02EH
+MOV	AX,055H
+OUT	DX,AL
+; CONFIGURE REGISTER CRE0,
+; LOGICAL DEVICE 8
+MOV	DX,02EH
+MOV	AL,07H
+OUT	DX,AL ;Point to LD# Config Reg
+MOV	DX,02FH
+MOV	AL, 08H
+OUT	DX,AL;Point to Logical Device 8
+;
+MOV	DX,02EH
+MOV	AL,60H
+OUT	DX,AL	; Point to HWM Base Addr MSB
+MOV	DX,02FH
+IN	AL,DX	; Get MSB of HWM Base Addr
+; EXIT CONFIGURATION MODE
+MOV	DX,02EH
+MOV	AX,0AAH
+OUT	DX,AL
diff --git a/Documentation/hwmon/smsc47m1 b/Documentation/hwmon/smsc47m1
new file mode 100644
--- /dev/null
+++ b/Documentation/hwmon/smsc47m1
@@ -0,0 +1,52 @@
+Kernel driver smsc47m1
+======================
+
+Supported chips:
+  * SMSC LPC47B27x, LPC47M10x, LPC47M13x, LPC47M14x, LPC47M15x and LPC47M192
+    Addresses scanned: none, address read from Super I/O config space
+    Prefix: 'smsc47m1'
+    Datasheets:
+        http://www.smsc.com/main/datasheets/47b27x.pdf
+        http://www.smsc.com/main/datasheets/47m10x.pdf
+        http://www.smsc.com/main/tools/discontinued/47m13x.pdf
+        http://www.smsc.com/main/datasheets/47m14x.pdf
+        http://www.smsc.com/main/tools/discontinued/47m15x.pdf
+        http://www.smsc.com/main/datasheets/47m192.pdf
+
+Authors:
+        Mark D. Studebaker <mdsxyz123@yahoo.com>,
+        With assistance from Bruce Allen <ballen@uwm.edu>, and his
+        fan.c program: http://www.lsc-group.phys.uwm.edu/%7Eballen/driver/
+        Gabriele Gorla <gorlik@yahoo.com>,
+        Jean Delvare <khali@linux-fr.org>
+
+Description
+-----------
+
+The Standard Microsystems Corporation (SMSC) 47M1xx Super I/O chips
+contain monitoring and PWM control circuitry for two fans.
+
+The 47M15x and 47M192 chips contain a full 'hardware monitoring block'
+in addition to the fan monitoring and control. The hardware monitoring
+block is not supported by the driver.
+
+Fan rotation speeds are reported in RPM (rotations per minute). An alarm is
+triggered if the rotation speed has dropped below a programmable limit. Fan
+readings can be divided by a programmable divider (1, 2, 4 or 8) to give
+the readings more range or accuracy. Not all RPM values can accurately be
+represented, so some rounding is done. With a divider of 2, the lowest
+representable value is around 2600 RPM.
+
+PWM values are from 0 to 255.
+
+If an alarm triggers, it will remain triggered until the hardware register
+is read at least once. This means that the cause for the alarm may
+already have disappeared! Note that in the current implementation, all
+hardware registers are read whenever any data is read (unless it is less
+than 1.5 seconds since the last update). This means that you can easily
+miss once-only alarms.
+
+
+**********************
+The lm_sensors project gratefully acknowledges the support of
+Intel in the development of this driver.
diff --git a/Documentation/hwmon/sysfs-interface b/Documentation/hwmon/sysfs-interface
new file mode 100644
--- /dev/null
+++ b/Documentation/hwmon/sysfs-interface
@@ -0,0 +1,274 @@
+Naming and data format standards for sysfs files
+------------------------------------------------
+
+The libsensors library offers an interface to the raw sensors data
+through the sysfs interface. See libsensors documentation and source for
+more further information. As of writing this document, libsensors
+(from lm_sensors 2.8.3) is heavily chip-dependant. Adding or updating
+support for any given chip requires modifying the library's code.
+This is because libsensors was written for the procfs interface
+older kernel modules were using, which wasn't standardized enough.
+Recent versions of libsensors (from lm_sensors 2.8.2 and later) have
+support for the sysfs interface, though.
+
+The new sysfs interface was designed to be as chip-independant as
+possible.
+
+Note that motherboards vary widely in the connections to sensor chips.
+There is no standard that ensures, for example, that the second
+temperature sensor is connected to the CPU, or that the second fan is on
+the CPU. Also, some values reported by the chips need some computation
+before they make full sense. For example, most chips can only measure
+voltages between 0 and +4V. Other voltages are scaled back into that
+range using external resistors. Since the values of these resistors
+can change from motherboard to motherboard, the conversions cannot be
+hard coded into the driver and have to be done in user space.
+
+For this reason, even if we aim at a chip-independant libsensors, it will
+still require a configuration file (e.g. /etc/sensors.conf) for proper
+values conversion, labeling of inputs and hiding of unused inputs.
+
+An alternative method that some programs use is to access the sysfs
+files directly. This document briefly describes the standards that the
+drivers follow, so that an application program can scan for entries and
+access this data in a simple and consistent way. That said, such programs
+will have to implement conversion, labeling and hiding of inputs. For
+this reason, it is still not recommended to bypass the library.
+
+If you are developing a userspace application please send us feedback on
+this standard.
+
+Note that this standard isn't completely established yet, so it is subject
+to changes, even important ones. One more reason to use the library instead
+of accessing sysfs files directly.
+
+Each chip gets its own directory in the sysfs /sys/devices tree.  To
+find all sensor chips, it is easier to follow the symlinks from
+/sys/i2c/devices/
+
+All sysfs values are fixed point numbers.  To get the true value of some
+of the values, you should divide by the specified value.
+
+There is only one value per file, unlike the older /proc specification.
+The common scheme for files naming is: <type><number>_<item>. Usual
+types for sensor chips are "in" (voltage), "temp" (temperature) and
+"fan" (fan). Usual items are "input" (measured value), "max" (high
+threshold, "min" (low threshold). Numbering usually starts from 1,
+except for voltages which start from 0 (because most data sheets use
+this). A number is always used for elements that can be present more
+than once, even if there is a single element of the given type on the
+specific chip. Other files do not refer to a specific element, so
+they have a simple name, and no number.
+
+Alarms are direct indications read from the chips. The drivers do NOT
+make comparisons of readings to thresholds. This allows violations
+between readings to be caught and alarmed. The exact definition of an
+alarm (for example, whether a threshold must be met or must be exceeded
+to cause an alarm) is chip-dependent.
+
+
+-------------------------------------------------------------------------
+
+************
+* Voltages *
+************
+
+in[0-8]_min	Voltage min value.
+		Unit: millivolt
+		Read/Write
+		
+in[0-8]_max	Voltage max value.
+		Unit: millivolt
+		Read/Write
+		
+in[0-8]_input	Voltage input value.
+		Unit: millivolt
+		Read only
+		Actual voltage depends on the scaling resistors on the
+		motherboard, as recommended in the chip datasheet.
+		This varies by chip and by motherboard.
+		Because of this variation, values are generally NOT scaled
+		by the chip driver, and must be done by the application.
+		However, some drivers (notably lm87 and via686a)
+		do scale, with various degrees of success.
+		These drivers will output the actual voltage.
+
+		Typical usage:
+			in0_*	CPU #1 voltage (not scaled)
+			in1_*	CPU #2 voltage (not scaled)
+			in2_*	3.3V nominal (not scaled)
+			in3_*	5.0V nominal (scaled)
+			in4_*	12.0V nominal (scaled)
+			in5_*	-12.0V nominal (scaled)
+			in6_*	-5.0V nominal (scaled)
+			in7_*	varies
+			in8_*	varies
+
+cpu[0-1]_vid	CPU core reference voltage.
+		Unit: millivolt
+		Read only.
+		Not always correct.
+
+vrm		Voltage Regulator Module version number. 
+		Read only.
+		Two digit number, first is major version, second is
+		minor version.
+		Affects the way the driver calculates the CPU core reference
+		voltage from the vid pins.
+
+
+********
+* Fans *
+********
+
+fan[1-3]_min	Fan minimum value
+		Unit: revolution/min (RPM)
+		Read/Write.
+
+fan[1-3]_input	Fan input value.
+		Unit: revolution/min (RPM)
+		Read only.
+
+fan[1-3]_div	Fan divisor.
+		Integer value in powers of two (1, 2, 4, 8, 16, 32, 64, 128).
+		Some chips only support values 1, 2, 4 and 8.
+		Note that this is actually an internal clock divisor, which
+		affects the measurable speed range, not the read value.
+
+*******
+* PWM *
+*******
+
+pwm[1-3]	Pulse width modulation fan control.
+		Integer value in the range 0 to 255
+		Read/Write
+		255 is max or 100%.
+
+pwm[1-3]_enable
+		Switch PWM on and off.
+		Not always present even if fan*_pwm is.
+		0 to turn off
+		1 to turn on in manual mode
+		2 to turn on in automatic mode
+		Read/Write
+
+pwm[1-*]_auto_channels_temp
+		Select which temperature channels affect this PWM output in
+		auto mode. Bitfield, 1 is temp1, 2 is temp2, 4 is temp3 etc...
+		Which values are possible depend on the chip used.
+
+pwm[1-*]_auto_point[1-*]_pwm
+pwm[1-*]_auto_point[1-*]_temp
+pwm[1-*]_auto_point[1-*]_temp_hyst
+		Define the PWM vs temperature curve. Number of trip points is
+		chip-dependent. Use this for chips which associate trip points
+		to PWM output channels.
+
+OR
+
+temp[1-*]_auto_point[1-*]_pwm
+temp[1-*]_auto_point[1-*]_temp
+temp[1-*]_auto_point[1-*]_temp_hyst
+		Define the PWM vs temperature curve. Number of trip points is
+		chip-dependent. Use this for chips which associate trip points
+		to temperature channels.
+
+
+****************
+* Temperatures *
+****************
+
+temp[1-3]_type	Sensor type selection.
+		Integers 1, 2, 3 or thermistor Beta value (3435)
+		Read/Write.
+		1: PII/Celeron Diode
+		2: 3904 transistor
+		3: thermal diode
+		Not all types are supported by all chips
+
+temp[1-4]_max	Temperature max value.
+		Unit: millidegree Celcius
+		Read/Write value.
+
+temp[1-3]_min	Temperature min value.
+		Unit: millidegree Celcius
+		Read/Write value.
+
+temp[1-3]_max_hyst
+		Temperature hysteresis value for max limit.
+		Unit: millidegree Celcius
+		Must be reported as an absolute temperature, NOT a delta
+		from the max value.
+		Read/Write value.
+
+temp[1-4]_input Temperature input value.
+		Unit: millidegree Celcius
+		Read only value.
+
+temp[1-4]_crit	Temperature critical value, typically greater than
+		corresponding temp_max values.
+		Unit: millidegree Celcius
+		Read/Write value.
+
+temp[1-2]_crit_hyst
+		Temperature hysteresis value for critical limit.
+		Unit: millidegree Celcius
+		Must be reported as an absolute temperature, NOT a delta
+		from the critical value.
+		Read/Write value.
+
+		If there are multiple temperature sensors, temp1_* is
+		generally the sensor inside the chip itself,
+		reported as "motherboard temperature".  temp2_* to
+		temp4_* are generally sensors external to the chip
+		itself, for example the thermal diode inside the CPU or
+		a thermistor nearby.
+
+
+************
+* Currents *
+************
+
+Note that no known chip provides current measurements as of writing,
+so this part is theoretical, so to say.
+
+curr[1-n]_max	Current max value
+		Unit: milliampere
+		Read/Write.
+
+curr[1-n]_min	Current min value.
+		Unit: milliampere
+		Read/Write.
+
+curr[1-n]_input	Current input value
+		Unit: milliampere
+		Read only.
+
+
+*********
+* Other *
+*********
+
+alarms		Alarm bitmask.
+		Read only.
+		Integer representation of one to four bytes.
+		A '1' bit means an alarm.
+		Chips should be programmed for 'comparator' mode so that
+		the alarm will 'come back' after you read the register
+		if it is still valid.
+		Generally a direct representation of a chip's internal
+		alarm registers; there is no standard for the position
+		of individual bits.
+		Bits are defined in kernel/include/sensors.h.
+
+beep_enable	Beep/interrupt enable
+		0 to disable.
+		1 to enable.
+		Read/Write
+
+beep_mask	Bitmask for beep.
+		Same format as 'alarms' with the same bit locations.
+		Read/Write
+
+eeprom		Raw EEPROM data in binary form.
+		Read only.
diff --git a/Documentation/hwmon/userspace-tools b/Documentation/hwmon/userspace-tools
new file mode 100644
--- /dev/null
+++ b/Documentation/hwmon/userspace-tools
@@ -0,0 +1,39 @@
+Introduction
+------------
+
+Most mainboards have sensor chips to monitor system health (like temperatures,
+voltages, fans speed). They are often connected through an I2C bus, but some
+are also connected directly through the ISA bus.
+
+The kernel drivers make the data from the sensor chips available in the /sys
+virtual filesystem. Userspace tools are then used to display or set or the
+data in a more friendly manner.
+
+Lm-sensors
+----------
+
+Core set of utilites that will allow you to obtain health information,
+setup monitoring limits etc. You can get them on their homepage
+http://www.lm-sensors.nu/ or as a package from your Linux distribution.
+
+If from website:
+Get lmsensors from project web site. Please note, you need only userspace
+part, so compile with "make user_install" target.
+
+General hints to get things working:
+
+0) get lm-sensors userspace utils
+1) compile all drivers in I2C section as modules in your kernel
+2) run sensors-detect script, it will tell you what modules you need to load.
+3) load them and run "sensors" command, you should see some results.
+4) fix sensors.conf, labels, limits, fan divisors
+5) if any more problems consult FAQ, or documentation
+
+Other utilites
+--------------
+
+If you want some graphical indicators of system health look for applications
+like: gkrellm, ksensors, xsensors, wmtemp, wmsensors, wmgtemp, ksysguardd,
+hardware-monitor
+
+If you are server administrator you can try snmpd or mrtgutils.
diff --git a/Documentation/hwmon/via686a b/Documentation/hwmon/via686a
new file mode 100644
--- /dev/null
+++ b/Documentation/hwmon/via686a
@@ -0,0 +1,65 @@
+Kernel driver via686a
+=====================
+
+Supported chips:
+  * Via VT82C686A, VT82C686B  Southbridge Integrated Hardware Monitor
+    Prefix: 'via686a'
+    Addresses scanned: ISA in PCI-space encoded address
+    Datasheet: On request through web form (http://www.via.com.tw/en/support/datasheets/)
+
+Authors:
+        Kyösti Mälkki <kmalkki@cc.hut.fi>,
+        Mark D. Studebaker <mdsxyz123@yahoo.com>
+        Bob Dougherty <bobd@stanford.edu>
+        (Some conversion-factor data were contributed by
+        Jonathan Teh Soon Yew <j.teh@iname.com>
+        and Alex van Kaam <darkside@chello.nl>.)
+
+Module Parameters
+-----------------
+
+force_addr=0xaddr       Set the I/O base address. Useful for Asus A7V boards
+                        that don't set the address in the BIOS. Does not do a
+                        PCI force; the via686a must still be present in lspci.
+                        Don't use this unless the driver complains that the
+                        base address is not set.
+                        Example: 'modprobe via686a force_addr=0x6000'
+
+Description
+-----------
+
+The driver does not distinguish between the chips and reports
+all as a 686A.
+
+The Via 686a southbridge has integrated hardware monitor functionality.
+It also has an I2C bus, but this driver only supports the hardware monitor.
+For the I2C bus driver, see <file:Documentation/i2c/busses/i2c-viapro>
+
+The Via 686a implements three temperature sensors, two fan rotation speed
+sensors, five voltage sensors and alarms.
+
+Temperatures are measured in degrees Celsius. An alarm is triggered once
+when the Overtemperature Shutdown limit is crossed; it is triggered again
+as soon as it drops below the hysteresis value.
+
+Fan rotation speeds are reported in RPM (rotations per minute). An alarm is
+triggered if the rotation speed has dropped below a programmable limit. Fan
+readings can be divided by a programmable divider (1, 2, 4 or 8) to give
+the readings more range or accuracy. Not all RPM values can accurately be
+represented, so some rounding is done. With a divider of 2, the lowest
+representable value is around 2600 RPM.
+
+Voltage sensors (also known as IN sensors) report their values in volts.
+An alarm is triggered if the voltage has crossed a programmable minimum
+or maximum limit. Voltages are internally scalled, so each voltage channel
+has a different resolution and range.
+
+If an alarm triggers, it will remain triggered until the hardware register
+is read at least once. This means that the cause for the alarm may
+already have disappeared! Note that in the current implementation, all
+hardware registers are read whenever any data is read (unless it is less
+than 1.5 seconds since the last update). This means that you can easily
+miss once-only alarms.
+
+The driver only updates its values each 1.5 seconds; reading it more often
+will do no harm, but will return 'old' values.
diff --git a/Documentation/hwmon/w83627hf b/Documentation/hwmon/w83627hf
new file mode 100644
--- /dev/null
+++ b/Documentation/hwmon/w83627hf
@@ -0,0 +1,66 @@
+Kernel driver w83627hf
+======================
+
+Supported chips:
+  * Winbond W83627HF (ISA accesses ONLY)
+    Prefix: 'w83627hf'
+    Addresses scanned: ISA address retrieved from Super I/O registers
+    Datasheet: http://www.winbond.com/PDF/sheet/w83627hf.pdf
+  * Winbond W83627THF
+    Prefix: 'w83627thf'
+    Addresses scanned: ISA address retrieved from Super I/O registers
+    Datasheet: http://www.winbond.com/PDF/sheet/w83627thf.pdf
+  * Winbond W83697HF
+    Prefix: 'w83697hf'
+    Addresses scanned: ISA address retrieved from Super I/O registers
+    Datasheet: http://www.winbond.com/PDF/sheet/697hf.pdf
+  * Winbond W83637HF
+    Prefix: 'w83637hf'
+    Addresses scanned: ISA address retrieved from Super I/O registers
+    Datasheet: http://www.winbond.com/PDF/sheet/w83637hf.pdf
+
+Authors:
+        Frodo Looijaard <frodol@dds.nl>,
+        Philip Edelbrock <phil@netroedge.com>,
+        Mark Studebaker <mdsxyz123@yahoo.com>,
+        Bernhard C. Schrenk <clemy@clemy.org>
+
+Module Parameters
+-----------------
+
+* force_addr: int
+  Initialize the ISA address of the sensors
+* force_i2c: int
+  Initialize the I2C address of the sensors
+* init: int
+  (default is 1)
+  Use 'init=0' to bypass initializing the chip.
+  Try this if your computer crashes when you load the module.
+
+Description
+-----------
+
+This driver implements support for ISA accesses *only* for
+the Winbond W83627HF, W83627THF, W83697HF and W83637HF Super I/O chips.
+We will refer to them collectively as Winbond chips.
+
+This driver supports ISA accesses, which should be more reliable
+than i2c accesses. Also, for Tyan boards which contain both a
+Super I/O chip and a second i2c-only Winbond chip (often a W83782D),
+using this driver will avoid i2c address conflicts and complex
+initialization that were required in the w83781d driver.
+
+If you really want i2c accesses for these Super I/O chips,
+use the w83781d driver. However this is not the preferred method
+now that this ISA driver has been developed.
+
+Technically, the w83627thf does not support a VID reading. However, it's
+possible or even likely that your mainboard maker has routed these signals
+to a specific set of general purpose IO pins (the Asus P4C800-E is one such
+board). The w83627thf driver now interprets these as VID. If the VID on
+your board doesn't work, first see doc/vid in the lm_sensors package. If
+that still doesn't help, email us at lm-sensors@lm-sensors.org.
+
+For further information on this driver see the w83781d driver
+documentation.
+
diff --git a/Documentation/hwmon/w83781d b/Documentation/hwmon/w83781d
new file mode 100644
--- /dev/null
+++ b/Documentation/hwmon/w83781d
@@ -0,0 +1,402 @@
+Kernel driver w83781d
+=====================
+
+Supported chips:
+  * Winbond W83781D
+    Prefix: 'w83781d'
+    Addresses scanned: I2C 0x20 - 0x2f, ISA 0x290 (8 I/O ports)
+    Datasheet: http://www.winbond-usa.com/products/winbond_products/pdfs/PCIC/w83781d.pdf
+  * Winbond W83782D
+    Prefix: 'w83782d'
+    Addresses scanned: I2C 0x20 - 0x2f, ISA 0x290 (8 I/O ports)
+    Datasheet: http://www.winbond.com/PDF/sheet/w83782d.pdf
+  * Winbond W83783S
+    Prefix: 'w83783s'
+    Addresses scanned: I2C 0x2d
+    Datasheet: http://www.winbond-usa.com/products/winbond_products/pdfs/PCIC/w83783s.pdf
+  * Winbond W83627HF
+    Prefix: 'w83627hf'
+    Addresses scanned: I2C 0x20 - 0x2f, ISA 0x290 (8 I/O ports)
+    Datasheet: http://www.winbond.com/PDF/sheet/w83627hf.pdf
+  * Asus AS99127F
+    Prefix: 'as99127f'
+    Addresses scanned: I2C 0x28 - 0x2f
+    Datasheet: Unavailable from Asus
+
+Authors:
+        Frodo Looijaard <frodol@dds.nl>,
+        Philip Edelbrock <phil@netroedge.com>,
+        Mark Studebaker <mdsxyz123@yahoo.com>
+
+Module parameters
+-----------------
+
+* init int
+  (default 1)
+  Use 'init=0' to bypass initializing the chip.
+  Try this if your computer crashes when you load the module.
+
+force_subclients=bus,caddr,saddr,saddr
+  This is used to force the i2c addresses for subclients of
+  a certain chip. Typical usage is `force_subclients=0,0x2d,0x4a,0x4b'
+  to force the subclients of chip 0x2d on bus 0 to i2c addresses
+  0x4a and 0x4b. This parameter is useful for certain Tyan boards.
+
+Description
+-----------
+
+This driver implements support for the Winbond W83781D, W83782D, W83783S,
+W83627HF chips, and the Asus AS99127F chips. We will refer to them
+collectively as W8378* chips.
+
+There is quite some difference between these chips, but they are similar
+enough that it was sensible to put them together in one driver.
+The W83627HF chip is assumed to be identical to the ISA W83782D.
+The Asus chips are similar to an I2C-only W83782D.
+
+Chip        #vin    #fanin  #pwm    #temp   wchipid vendid  i2c     ISA
+as99127f    7       3       0       3       0x31    0x12c3  yes     no
+as99127f rev.2 (type_name = as99127f)       0x31    0x5ca3  yes     no
+w83781d     7       3       0       3       0x10-1  0x5ca3  yes     yes
+w83627hf    9       3       2       3       0x21    0x5ca3  yes     yes(LPC)
+w83782d     9       3       2-4     3       0x30    0x5ca3  yes     yes
+w83783s     5-6     3       2       1-2     0x40    0x5ca3  yes     no
+
+Detection of these chips can sometimes be foiled because they can be in
+an internal state that allows no clean access. If you know the address
+of the chip, use a 'force' parameter; this will put them into a more
+well-behaved state first.
+
+The W8378* implements temperature sensors (three on the W83781D and W83782D,
+two on the W83783S), three fan rotation speed sensors, voltage sensors
+(seven on the W83781D, nine on the W83782D and six on the W83783S), VID
+lines, alarms with beep warnings, and some miscellaneous stuff.
+
+Temperatures are measured in degrees Celsius. There is always one main
+temperature sensor, and one (W83783S) or two (W83781D and W83782D) other
+sensors. An alarm is triggered for the main sensor once when the
+Overtemperature Shutdown limit is crossed; it is triggered again as soon as
+it drops below the Hysteresis value. A more useful behavior
+can be found by setting the Hysteresis value to +127 degrees Celsius; in
+this case, alarms are issued during all the time when the actual temperature
+is above the Overtemperature Shutdown value. The driver sets the
+hysteresis value for temp1 to 127 at initialization.
+
+For the other temperature sensor(s), an alarm is triggered when the
+temperature gets higher then the Overtemperature Shutdown value; it stays
+on until the temperature falls below the Hysteresis value. But on the
+W83781D, there is only one alarm that functions for both other sensors!
+Temperatures are guaranteed within a range of -55 to +125 degrees. The
+main temperature sensors has a resolution of 1 degree; the other sensor(s)
+of 0.5 degree.
+
+Fan rotation speeds are reported in RPM (rotations per minute). An alarm is
+triggered if the rotation speed has dropped below a programmable limit. Fan
+readings can be divided by a programmable divider (1, 2, 4 or 8 for the
+W83781D; 1, 2, 4, 8, 16, 32, 64 or 128 for the others) to give
+the readings more range or accuracy. Not all RPM values can accurately
+be represented, so some rounding is done. With a divider of 2, the lowest
+representable value is around 2600 RPM.
+
+Voltage sensors (also known as IN sensors) report their values in volts.
+An alarm is triggered if the voltage has crossed a programmable minimum
+or maximum limit. Note that minimum in this case always means 'closest to
+zero'; this is important for negative voltage measurements. All voltage
+inputs can measure voltages between 0 and 4.08 volts, with a resolution
+of 0.016 volt.
+
+The VID lines encode the core voltage value: the voltage level your processor
+should work with. This is hardcoded by the mainboard and/or processor itself.
+It is a value in volts. When it is unconnected, you will often find the
+value 3.50 V here.
+
+The W83782D and W83783S temperature conversion machine understands about
+several kinds of temperature probes. You can program the so-called
+beta value in the sensor files. '1' is the PII/Celeron diode, '2' is the
+TN3904 transistor, and 3435 the default thermistor value. Other values
+are (not yet) supported.
+
+In addition to the alarms described above, there is a CHAS alarm on the
+chips which triggers if your computer case is open.
+
+When an alarm goes off, you can be warned by a beeping signal through
+your computer speaker. It is possible to enable all beeping globally,
+or only the beeping for some alarms.
+
+If an alarm triggers, it will remain triggered until the hardware register
+is read at least once. This means that the cause for the alarm may
+already have disappeared! Note that in the current implementation, all
+hardware registers are read whenever any data is read (unless it is less
+than 1.5 seconds since the last update). This means that you can easily
+miss once-only alarms.
+
+The chips only update values each 1.5 seconds; reading them more often
+will do no harm, but will return 'old' values.
+
+AS99127F PROBLEMS
+-----------------
+The as99127f support was developed without the benefit of a datasheet.
+In most cases it is treated as a w83781d (although revision 2 of the
+AS99127F looks more like a w83782d).
+This support will be BETA until a datasheet is released.
+One user has reported problems with fans stopping
+occasionally.
+
+Note that the individual beep bits are inverted from the other chips.
+The driver now takes care of this so that user-space applications
+don't have to know about it.
+
+Known problems:
+	- Problems with diode/thermistor settings (supported?)
+	- One user reports fans stopping under high server load.
+	- Revision 2 seems to have 2 PWM registers but we don't know
+	  how to handle them. More details below.
+
+These will not be fixed unless we get a datasheet.
+If you have problems, please lobby Asus to release a datasheet.
+Unfortunately several others have without success.
+Please do not send mail to us asking for better as99127f support.
+We have done the best we can without a datasheet.
+Please do not send mail to the author or the sensors group asking for
+a datasheet or ideas on how to convince Asus. We can't help.
+
+
+NOTES:
+-----
+  783s has no in1 so that in[2-6] are compatible with the 781d/782d.
+
+  783s pin is programmable for -5V or temp1; defaults to -5V,
+       no control in driver so temp1 doesn't work.
+
+  782d and 783s datasheets differ on which is pwm1 and which is pwm2.
+       We chose to follow 782d.
+
+  782d and 783s pin is programmable for fan3 input or pwm2 output;
+       defaults to fan3 input.
+       If pwm2 is enabled (with echo 255 1 > pwm2), then
+       fan3 will report 0.
+
+  782d has pwm1-2 for ISA, pwm1-4 for i2c. (pwm3-4 share pins with
+       the ISA pins)
+
+Data sheet updates:
+------------------
+	- PWM clock registers:
+
+		000: master /  512
+		001: master / 1024
+		010: master / 2048
+		011: master / 4096
+		100: master / 8192
+
+
+Answers from Winbond tech support
+---------------------------------
+>
+> 1) In the W83781D data sheet section 7.2 last paragraph, it talks about
+>    reprogramming the R-T table if the Beta of the thermistor is not
+>    3435K. The R-T table is described briefly in section 8.20.
+>    What formulas do I use to program a new R-T table for a given Beta?
+>
+	We are sorry that the calculation for R-T table value is
+confidential. If you have another Beta value of thermistor, we can help
+to calculate the R-T table for you. But you should give us real R-T
+Table which can be gotten by thermistor vendor. Therefore we will calculate
+them and obtain 32-byte data, and you can fill the 32-byte data to the
+register in Bank0.CR51 of W83781D.
+
+
+> 2) In the W83782D data sheet, it mentions that pins 38, 39, and 40 are
+>    programmable to be either thermistor or Pentium II diode inputs.
+>    How do I program them for diode inputs? I can't find any register
+>    to program these to be diode inputs.
+ --> You may program Bank0 CR[5Dh] and CR[59h] registers.
+
+ 	CR[5Dh]    		bit 1(VTIN1)    bit 2(VTIN2)   bit 3(VTIN3)
+
+      	thermistor                0		 0		0
+ 	diode 		          1		 1		1
+
+
+(error) CR[59h] 		bit 4(VTIN1)	bit 2(VTIN2)   bit 3(VTIN3)
+(right) CR[59h] 		bit 4(VTIN1)	bit 5(VTIN2)   bit 6(VTIN3)
+
+ 	PII thermal diode         1		 1		1
+ 	2N3904	diode	          0		 0		0
+
+
+Asus Clones
+-----------
+
+We have no datasheets for the Asus clones (AS99127F and ASB100 Bach).
+Here are some very useful information that were given to us by Alex Van
+Kaam about how to detect these chips, and how to read their values. He
+also gives advice for another Asus chipset, the Mozart-2 (which we
+don't support yet). Thanks Alex!
+I reworded some parts and added personal comments.
+
+# Detection:
+
+AS99127F rev.1, AS99127F rev.2 and ASB100:
+- I2C address range: 0x29 - 0x2F
+- If register 0x58 holds 0x31 then we have an Asus (either ASB100 or
+  AS99127F)
+- Which one depends on register 0x4F (manufacturer ID):
+  0x06 or 0x94: ASB100
+  0x12 or 0xC3: AS99127F rev.1
+  0x5C or 0xA3: AS99127F rev.2
+  Note that 0x5CA3 is Winbond's ID (WEC), which let us think Asus get their
+  AS99127F rev.2 direct from Winbond. The other codes mean ATT and DVC,
+  respectively. ATT could stand for Asustek something (although it would be
+  very badly chosen IMHO), I don't know what DVC could stand for. Maybe
+  these codes simply aren't meant to be decoded that way.
+
+Mozart-2:
+- I2C address: 0x77
+- If register 0x58 holds 0x56 or 0x10 then we have a Mozart-2
+- Of the Mozart there are 3 types:
+  0x58=0x56, 0x4E=0x94, 0x4F=0x36: Asus ASM58 Mozart-2
+  0x58=0x56, 0x4E=0x94, 0x4F=0x06: Asus AS2K129R Mozart-2
+  0x58=0x10, 0x4E=0x5C, 0x4F=0xA3: Asus ??? Mozart-2
+  You can handle all 3 the exact same way :)
+
+# Temperature sensors:
+
+ASB100:
+- sensor 1: register 0x27
+- sensor 2 & 3 are the 2 LM75's on the SMBus
+- sensor 4: register 0x17
+Remark: I noticed that on Intel boards sensor 2 is used for the CPU
+  and 4 is ignored/stuck, on AMD boards sensor 4 is the CPU and sensor 2 is
+  either ignored or a socket temperature.
+
+AS99127F (rev.1 and 2 alike):
+- sensor 1: register 0x27
+- sensor 2 & 3 are the 2 LM75's on the SMBus
+Remark: Register 0x5b is suspected to be temperature type selector. Bit 1
+  would control temp1, bit 3 temp2 and bit 5 temp3.
+
+Mozart-2:
+- sensor 1: register 0x27
+- sensor 2: register 0x13
+
+# Fan sensors:
+
+ASB100, AS99127F (rev.1 and 2 alike):
+- 3 fans, identical to the W83781D
+
+Mozart-2:
+- 2 fans only, 1350000/RPM/div
+- fan 1: register 0x28,  divisor on register 0xA1 (bits 4-5)
+- fan 2: register 0x29,  divisor on register 0xA1 (bits 6-7)
+
+# Voltages:
+
+This is where there is a difference between AS99127F rev.1 and 2.
+Remark: The difference is similar to the difference between
+  W83781D and W83782D.
+
+ASB100:
+in0=r(0x20)*0.016
+in1=r(0x21)*0.016
+in2=r(0x22)*0.016
+in3=r(0x23)*0.016*1.68
+in4=r(0x24)*0.016*3.8
+in5=r(0x25)*(-0.016)*3.97
+in6=r(0x26)*(-0.016)*1.666
+
+AS99127F rev.1:
+in0=r(0x20)*0.016
+in1=r(0x21)*0.016
+in2=r(0x22)*0.016
+in3=r(0x23)*0.016*1.68
+in4=r(0x24)*0.016*3.8
+in5=r(0x25)*(-0.016)*3.97
+in6=r(0x26)*(-0.016)*1.503
+
+AS99127F rev.2:
+in0=r(0x20)*0.016
+in1=r(0x21)*0.016
+in2=r(0x22)*0.016
+in3=r(0x23)*0.016*1.68
+in4=r(0x24)*0.016*3.8
+in5=(r(0x25)*0.016-3.6)*5.14+3.6
+in6=(r(0x26)*0.016-3.6)*3.14+3.6
+
+Mozart-2:
+in0=r(0x20)*0.016
+in1=255
+in2=r(0x22)*0.016
+in3=r(0x23)*0.016*1.68
+in4=r(0x24)*0.016*4
+in5=255
+in6=255
+
+
+# PWM
+
+Additional info about PWM on the AS99127F (may apply to other Asus
+chips as well) by Jean Delvare as of 2004-04-09:
+
+AS99127F revision 2 seems to have two PWM registers at 0x59 and 0x5A,
+and a temperature sensor type selector at 0x5B (which basically means
+that they swapped registers 0x59 and 0x5B when you compare with Winbond
+chips).
+Revision 1 of the chip also has the temperature sensor type selector at
+0x5B, but PWM registers have no effect.
+
+We don't know exactly how the temperature sensor type selection works.
+Looks like bits 1-0 are for temp1, bits 3-2 for temp2 and bits 5-4 for
+temp3, although it is possible that only the most significant bit matters
+each time. So far, values other than 0 always broke the readings.
+
+PWM registers seem to be split in two parts: bit 7 is a mode selector,
+while the other bits seem to define a value or threshold.
+
+When bit 7 is clear, bits 6-0 seem to hold a threshold value. If the value
+is below a given limit, the fan runs at low speed. If the value is above
+the limit, the fan runs at full speed. We have no clue as to what the limit
+represents. Note that there seem to be some inertia in this mode, speed
+changes may need some time to trigger. Also, an hysteresis mechanism is
+suspected since walking through all the values increasingly and then
+decreasingly led to slightly different limits.
+
+When bit 7 is set, bits 3-0 seem to hold a threshold value, while bits 6-4
+would not be significant. If the value is below a given limit, the fan runs
+at full speed, while if it is above the limit it runs at low speed (so this
+is the contrary of the other mode, in a way). Here again, we don't know
+what the limit is supposed to represent.
+
+One remarkable thing is that the fans would only have two or three
+different speeds (transitional states left apart), not a whole range as
+you usually get with PWM.
+
+As a conclusion, you can write 0x00 or 0x8F to the PWM registers to make
+fans run at low speed, and 0x7F or 0x80 to make them run at full speed.
+
+Please contact us if you can figure out how it is supposed to work. As
+long as we don't know more, the w83781d driver doesn't handle PWM on
+AS99127F chips at all.
+
+Additional info about PWM on the AS99127F rev.1 by Hector Martin:
+
+I've been fiddling around with the (in)famous 0x59 register and
+found out the following values do work as a form of coarse pwm:
+
+0x80 - seems to turn fans off after some time(1-2 minutes)... might be
+some form of auto-fan-control based on temp? hmm (Qfan? this mobo is an
+old ASUS, it isn't marketed as Qfan. Maybe some beta pre-attemp at Qfan
+that was dropped at the BIOS)
+0x81 - off
+0x82 - slightly "on-ner" than off, but my fans do not get to move. I can
+hear the high-pitched PWM sound that motors give off at too-low-pwm.
+0x83 - now they do move. Estimate about 70% speed or so.
+0x84-0x8f - full on
+
+Changing the high nibble doesn't seem to do much except the high bit
+(0x80) must be set for PWM to work, else the current pwm doesn't seem to
+change.
+
+My mobo is an ASUS A7V266-E. This behavior is similar to what I got
+with speedfan under Windows, where 0-15% would be off, 15-2x% (can't
+remember the exact value) would be 70% and higher would be full on.
diff --git a/Documentation/hwmon/w83l785ts b/Documentation/hwmon/w83l785ts
new file mode 100644
--- /dev/null
+++ b/Documentation/hwmon/w83l785ts
@@ -0,0 +1,39 @@
+Kernel driver w83l785ts
+=======================
+
+Supported chips:
+  * Winbond W83L785TS-S
+    Prefix: 'w83l785ts'
+    Addresses scanned: I2C 0x2e
+    Datasheet: Publicly available at the Winbond USA website
+               http://www.winbond-usa.com/products/winbond_products/pdfs/PCIC/W83L785TS-S.pdf
+
+Authors:
+        Jean Delvare <khali@linux-fr.org>
+
+Description
+-----------
+
+The W83L785TS-S is a digital temperature sensor. It senses the
+temperature of a single external diode. The high limit is
+theoretically defined as 85 or 100 degrees C through a combination
+of external resistors, so the user cannot change it. Values seen so
+far suggest that the two possible limits are actually 95 and 110
+degrees C. The datasheet is rather poor and obviously inaccurate
+on several points including this one.
+
+All temperature values are given in degrees Celsius. Resolution
+is 1.0 degree. See the datasheet for details.
+
+The w83l785ts driver will not update its values more frequently than
+every other second; reading them more often will do no harm, but will
+return 'old' values.
+
+Known Issues
+------------
+
+On some systems (Asus), the BIOS is known to interfere with the driver
+and cause read errors. The driver will retry a given number of times
+(5 by default) and then give up, returning the old value (or 0 if
+there is no old value). It seems to work well enough so that you should
+not notice anything. Thanks to James Bolt for helping test this feature.
diff --git a/Documentation/i2c/busses/i2c-sis69x b/Documentation/i2c/busses/i2c-sis69x
--- a/Documentation/i2c/busses/i2c-sis69x
+++ b/Documentation/i2c/busses/i2c-sis69x
@@ -42,7 +42,7 @@ I suspect that this driver could be made
 chipsets as well: 635, and 635T. If anyone owns a board with those chips
 AND is willing to risk crashing & burning an otherwise well-behaved kernel
 in the name of progress... please contact me at <mhoffman@lightlink.com> or
-via the project's mailing list: <sensors@stimpy.netroedge.com>.  Please
+via the project's mailing list: <lm-sensors@lm-sensors.org>.  Please
 send bug reports and/or success stories as well.
 
 
diff --git a/Documentation/i2c/chips/eeprom b/Documentation/i2c/chips/eeprom
new file mode 100644
--- /dev/null
+++ b/Documentation/i2c/chips/eeprom
@@ -0,0 +1,96 @@
+Kernel driver eeprom
+====================
+
+Supported chips:
+  * Any EEPROM chip in the designated address range
+    Prefix: 'eeprom'
+    Addresses scanned: I2C 0x50 - 0x57
+    Datasheets: Publicly available from:
+                Atmel (www.atmel.com),
+                Catalyst (www.catsemi.com),
+                Fairchild (www.fairchildsemi.com),
+                Microchip (www.microchip.com),
+                Philips (www.semiconductor.philips.com),
+                Rohm (www.rohm.com),
+                ST (www.st.com),
+                Xicor (www.xicor.com),
+                and others.
+
+        Chip     Size (bits)    Address
+        24C01     1K            0x50 (shadows at 0x51 - 0x57)
+        24C01A    1K            0x50 - 0x57 (Typical device on DIMMs)
+        24C02     2K            0x50 - 0x57
+        24C04     4K            0x50, 0x52, 0x54, 0x56
+                                (additional data at 0x51, 0x53, 0x55, 0x57)
+        24C08     8K            0x50, 0x54 (additional data at 0x51, 0x52,
+                                0x53, 0x55, 0x56, 0x57)
+        24C16    16K            0x50 (additional data at 0x51 - 0x57)
+        Sony      2K            0x57
+
+        Atmel     34C02B  2K    0x50 - 0x57, SW write protect at 0x30-37
+        Catalyst  34FC02  2K    0x50 - 0x57, SW write protect at 0x30-37
+        Catalyst  34RC02  2K    0x50 - 0x57, SW write protect at 0x30-37
+        Fairchild 34W02   2K    0x50 - 0x57, SW write protect at 0x30-37
+        Microchip 24AA52  2K    0x50 - 0x57, SW write protect at 0x30-37
+        ST        M34C02  2K    0x50 - 0x57, SW write protect at 0x30-37
+
+
+Authors:
+        Frodo Looijaard <frodol@dds.nl>,
+        Philip Edelbrock <phil@netroedge.com>,
+        Jean Delvare <khali@linux-fr.org>,
+        Greg Kroah-Hartman <greg@kroah.com>,
+        IBM Corp.
+
+Description
+-----------
+
+This is a simple EEPROM module meant to enable reading the first 256 bytes
+of an EEPROM (on a SDRAM DIMM for example). However, it will access serial
+EEPROMs on any I2C adapter. The supported devices are generically called
+24Cxx, and are listed above; however the numbering for these
+industry-standard devices may vary by manufacturer.
+
+This module was a programming exercise to get used to the new project
+organization laid out by Frodo, but it should be at least completely
+effective for decoding the contents of EEPROMs on DIMMs.
+
+DIMMS will typically contain a 24C01A or 24C02, or the 34C02 variants.
+The other devices will not be found on a DIMM because they respond to more
+than one address.
+
+DDC Monitors may contain any device. Often a 24C01, which responds to all 8
+addresses, is found.
+
+Recent Sony Vaio laptops have an EEPROM at 0x57. We couldn't get the
+specification, so it is guess work and far from being complete.
+
+The Microchip 24AA52/24LCS52, ST M34C02, and others support an additional
+software write protect register at 0x30 - 0x37 (0x20 less than the memory
+location). The chip responds to "write quick" detection at this address but
+does not respond to byte reads. If this register is present, the lower 128
+bytes of the memory array are not write protected. Any byte data write to
+this address will write protect the memory array permanently, and the
+device will no longer respond at the 0x30-37 address. The eeprom driver
+does not support this register.
+
+Lacking functionality:
+
+* Full support for larger devices (24C04, 24C08, 24C16). These are not
+typically found on a PC. These devices will appear as separate devices at
+multiple addresses.
+
+* Support for really large devices (24C32, 24C64, 24C128, 24C256, 24C512).
+These devices require two-byte address fields and are not supported.
+
+* Enable Writing. Again, no technical reason why not, but making it easy
+to change the contents of the EEPROMs (on DIMMs anyway) also makes it easy
+to disable the DIMMs (potentially preventing the computer from booting)
+until the values are restored somehow.
+
+Use:
+
+After inserting the module (and any other required SMBus/i2c modules), you
+should have some EEPROM directories in /sys/bus/i2c/devices/* of names such
+as "0-0050". Inside each of these is a series of files, the eeprom file
+contains the binary data from EEPROM.
diff --git a/Documentation/i2c/chips/max6875 b/Documentation/i2c/chips/max6875
new file mode 100644
--- /dev/null
+++ b/Documentation/i2c/chips/max6875
@@ -0,0 +1,66 @@
+Kernel driver max6875
+=====================
+
+Supported chips:
+  * Maxim MAX6874, MAX6875
+    Prefix: 'max6875'
+    Addresses scanned: 0x50, 0x52
+    Datasheet:
+        http://pdfserv.maxim-ic.com/en/ds/MAX6874-MAX6875.pdf
+
+Author: Ben Gardner <bgardner@wabtec.com>
+
+
+Module Parameters
+-----------------
+
+* allow_write int
+  Set to non-zero to enable write permission:
+  *0: Read only
+   1: Read and write
+
+
+Description
+-----------
+
+The Maxim MAX6875 is an EEPROM-programmable power-supply sequencer/supervisor.
+It provides timed outputs that can be used as a watchdog, if properly wired.
+It also provides 512 bytes of user EEPROM.
+
+At reset, the MAX6875 reads the configuration EEPROM into its configuration
+registers.  The chip then begins to operate according to the values in the
+registers.
+
+The Maxim MAX6874 is a similar, mostly compatible device, with more intputs
+and outputs:
+
+             vin     gpi    vout
+MAX6874        6       4       8
+MAX6875        4       3       5
+
+MAX6874 chips can have four different addresses (as opposed to only two for
+the MAX6875). The additional addresses (0x54 and 0x56) are not probed by
+this driver by default, but the probe module parameter can be used if
+needed.
+
+See the datasheet for details on how to program the EEPROM.
+
+
+Sysfs entries
+-------------
+
+eeprom_user   - 512 bytes of user-defined EEPROM space. Only writable if
+                allow_write was set and register 0x43 is 0.
+
+eeprom_config - 70 bytes of config EEPROM. Note that changes will not get
+                loaded into register space until a power cycle or device reset.
+
+reg_config    - 70 bytes of register space. Any changes take affect immediately.
+
+
+General Remarks
+---------------
+
+A typical application will require that the EEPROMs be programmed once and
+never altered afterwards.
+
diff --git a/Documentation/i2c/chips/pca9539 b/Documentation/i2c/chips/pca9539
new file mode 100644
--- /dev/null
+++ b/Documentation/i2c/chips/pca9539
@@ -0,0 +1,47 @@
+Kernel driver pca9539
+=====================
+
+Supported chips:
+  * Philips PCA9539
+    Prefix: 'pca9539'
+    Addresses scanned: 0x74 - 0x77
+    Datasheet:
+        http://www.semiconductors.philips.com/acrobat/datasheets/PCA9539_2.pdf
+
+Author: Ben Gardner <bgardner@wabtec.com>
+
+
+Description
+-----------
+
+The Philips PCA9539 is a 16 bit low power I/O device.
+All 16 lines can be individually configured as an input or output.
+The input sense can also be inverted.
+The 16 lines are split between two bytes.
+
+
+Sysfs entries
+-------------
+
+Each is a byte that maps to the 8 I/O bits.
+A '0' suffix is for bits 0-7, while '1' is for bits 8-15.
+
+input[01]     - read the current value
+output[01]    - sets the output value
+direction[01] - direction of each bit: 1=input, 0=output
+invert[01]    - toggle the input bit sense
+
+input reads the actual state of the line and is always available.
+The direction defaults to input for all channels.
+
+
+General Remarks
+---------------
+
+Note that each output, direction, and invert entry controls 8 lines.
+You should use the read, modify, write sequence.
+For example. to set output bit 0 of 1.
+  val=$(cat output0)
+  val=$(( $val | 1 ))
+  echo $val > output0
+
diff --git a/Documentation/i2c/chips/pcf8574 b/Documentation/i2c/chips/pcf8574
new file mode 100644
--- /dev/null
+++ b/Documentation/i2c/chips/pcf8574
@@ -0,0 +1,69 @@
+Kernel driver pcf8574
+=====================
+
+Supported chips:
+  * Philips PCF8574
+    Prefix: 'pcf8574'
+    Addresses scanned: I2C 0x20 - 0x27
+    Datasheet: Publicly available at the Philips Semiconductors website
+               http://www.semiconductors.philips.com/pip/PCF8574P.html
+
+ * Philips PCF8574A
+    Prefix: 'pcf8574a'
+    Addresses scanned: I2C 0x38 - 0x3f
+    Datasheet: Publicly available at the Philips Semiconductors website
+               http://www.semiconductors.philips.com/pip/PCF8574P.html
+
+Authors:
+        Frodo Looijaard <frodol@dds.nl>,
+        Philip Edelbrock <phil@netroedge.com>,
+        Dan Eaton <dan.eaton@rocketlogix.com>,
+        Aurelien Jarno <aurelien@aurel32.net>,
+        Jean Delvare <khali@linux-fr.org>,
+
+
+Description
+-----------
+The PCF8574(A) is an 8-bit I/O expander for the I2C bus produced by Philips
+Semiconductors. It is designed to provide a byte I2C interface to up to 16
+separate devices (8 x PCF8574 and 8 x PCF8574A).
+
+This device consists of a quasi-bidirectional port. Each of the eight I/Os
+can be independently used as an input or output. To setup an I/O as an
+input, you have to write a 1 to the corresponding output.
+
+For more informations see the datasheet.
+
+
+Accessing PCF8574(A) via /sys interface
+-------------------------------------
+
+! Be careful !
+The PCF8574(A) is plainly impossible to detect ! Stupid chip.
+So every chip with address in the interval [20..27] and [38..3f] are
+detected as PCF8574(A). If you have other chips in this address
+range, the workaround is to load this module after the one
+for your others chips.
+
+On detection (i.e. insmod, modprobe et al.), directories are being
+created for each detected PCF8574(A):
+
+/sys/bus/i2c/devices/<0>-<1>/
+where <0> is the bus the chip was detected on (e. g. i2c-0)
+and <1> the chip address ([20..27] or [38..3f]):
+
+(example: /sys/bus/i2c/devices/1-0020/)
+
+Inside these directories, there are two files each:
+read and write (and one file with chip name).
+
+The read file is read-only. Reading gives you the current I/O input
+if the corresponding output is set as 1, otherwise the current output
+value, that is to say 0.
+
+The write file is read/write. Writing a value outputs it on the I/O
+port. Reading returns the last written value.
+
+On module initialization the chip is configured as eight inputs (all
+outputs to 1), so you can connect any circuit to the PCF8574(A) without
+being afraid of short-circuit.
diff --git a/Documentation/i2c/chips/pcf8591 b/Documentation/i2c/chips/pcf8591
new file mode 100644
--- /dev/null
+++ b/Documentation/i2c/chips/pcf8591
@@ -0,0 +1,90 @@
+Kernel driver pcf8591
+=====================
+
+Supported chips:
+  * Philips PCF8591
+    Prefix: 'pcf8591'
+    Addresses scanned: I2C 0x48 - 0x4f
+    Datasheet: Publicly available at the Philips Semiconductor website
+               http://www.semiconductors.philips.com/pip/PCF8591P.html
+
+Authors:
+        Aurelien Jarno <aurelien@aurel32.net>
+        valuable contributions by Jan M. Sendler <sendler@sendler.de>,
+        Jean Delvare <khali@linux-fr.org>
+
+
+Description
+-----------
+The PCF8591 is an 8-bit A/D and D/A converter (4 analog inputs and one
+analog output) for the I2C bus produced by Philips Semiconductors. It
+is designed to provide a byte I2C interface to up to 4 separate devices.
+
+The PCF8591 has 4 analog inputs programmable as single-ended or
+differential inputs :
+- mode 0 : four single ended inputs
+        Pins AIN0 to AIN3 are single ended inputs for channels 0 to 3
+
+- mode 1 : three differential inputs
+        Pins AIN3 is the common negative differential input
+        Pins AIN0 to AIN2 are positive differential inputs for channels 0 to 2
+
+- mode 2 : single ended and differential mixed
+        Pins AIN0 and AIN1 are single ended inputs for channels 0 and 1
+        Pins AIN2 is the positive differential input for channel 3
+        Pins AIN3 is the negative differential input for channel 3
+
+- mode 3 : two differential inputs
+        Pins AIN0 is the positive differential input for channel 0
+        Pins AIN1 is the negative differential input for channel 0
+        Pins AIN2 is the positive differential input for channel 1
+        Pins AIN3 is the negative differential input for channel 1
+
+See the datasheet for details.
+
+Module parameters
+-----------------
+
+* input_mode int
+
+    Analog input mode:
+         0 = four single ended inputs
+         1 = three differential inputs
+         2 = single ended and differential mixed
+         3 = two differential inputs
+
+
+Accessing PCF8591 via /sys interface
+-------------------------------------
+
+! Be careful !
+The PCF8591 is plainly impossible to detect ! Stupid chip.
+So every chip with address in the interval [48..4f] is
+detected as PCF8591. If you have other chips in this address
+range, the workaround is to load this module after the one
+for your others chips.
+
+On detection (i.e. insmod, modprobe et al.), directories are being
+created for each detected PCF8591:
+
+/sys/bus/devices/<0>-<1>/
+where <0> is the bus the chip was detected on (e. g. i2c-0)
+and <1> the chip address ([48..4f])
+
+Inside these directories, there are such files:
+in0, in1, in2, in3, out0_enable, out0_output, name
+
+Name contains chip name.
+
+The in0, in1, in2 and in3 files are RO. Reading gives the value of the
+corresponding channel. Depending on the current analog inputs configuration,
+files in2 and/or in3 do not exist. Values range are from 0 to 255 for single
+ended inputs and -128 to +127 for differential inputs (8-bit ADC).
+
+The out0_enable file is RW. Reading gives "1" for analog output enabled and
+"0" for analog output disabled. Writing accepts "0" and "1" accordingly.
+
+The out0_output file is RW. Writing a number between 0 and 255 (8-bit DAC), send
+the value to the digital-to-analog converter. Note that a voltage will
+only appears on AOUT pin if aout0_enable equals 1. Reading returns the last
+value written.
diff --git a/Documentation/i2c/chips/smsc47b397.txt b/Documentation/i2c/chips/smsc47b397.txt
deleted file mode 100644
--- a/Documentation/i2c/chips/smsc47b397.txt
+++ /dev/null
@@ -1,146 +0,0 @@
-November 23, 2004
-
-The following specification describes the SMSC LPC47B397-NC sensor chip
-(for which there is no public datasheet available).  This document was
-provided by Craig Kelly (In-Store Broadcast Network) and edited/corrected
-by Mark M. Hoffman <mhoffman@lightlink.com>.
-
-* * * * *
-
-Methods for detecting the HP SIO and reading the thermal data on a dc7100.
-
-The thermal information on the dc7100 is contained in the SIO Hardware Monitor
-(HWM).  The information is accessed through an index/data pair.  The index/data
-pair is located at the HWM Base Address + 0 and the HWM Base Address + 1.  The
-HWM Base address can be obtained from Logical Device 8, registers 0x60 (MSB)
-and 0x61 (LSB).  Currently we are using 0x480 for the HWM Base Address and
-0x480 and 0x481 for the index/data pair.
-
-Reading temperature information.
-The temperature information is located in the following registers:
-Temp1		0x25	(Currently, this reflects the CPU temp on all systems).
-Temp2		0x26
-Temp3		0x27
-Temp4		0x80
-
-Programming Example
-The following is an example of how to read the HWM temperature registers:
-MOV	DX,480H
-MOV	AX,25H
-OUT	DX,AL
-MOV	DX,481H
-IN	AL,DX
-
-AL contains the data in hex, the temperature in Celsius is the decimal
-equivalent.
-
-Ex: If AL contains 0x2A, the temperature is 42 degrees C.
-
-Reading tach information.
-The fan speed information is located in the following registers:
-		LSB	MSB
-Tach1		0x28	0x29	(Currently, this reflects the CPU
-				fan speed on all systems).
-Tach2		0x2A	0x2B
-Tach3		0x2C	0x2D
-Tach4		0x2E	0x2F
-
-Important!!!
-Reading the tach LSB locks the tach MSB.
-The LSB Must be read first.
-
-How to convert the tach reading to RPM.
-The tach reading (TCount) is given by:  (Tach MSB * 256) + (Tach LSB)
-The SIO counts the number of 90kHz (11.111us) pulses per revolution.
-RPM = 60/(TCount * 11.111us)
-
-Example:
-Reg 0x28 = 0x9B
-Reg 0x29 = 0x08
-
-TCount = 0x89B = 2203
-
-RPM = 60 / (2203 * 11.11111 E-6) = 2451 RPM
-
-Obtaining the SIO version.
-
-CONFIGURATION SEQUENCE
-To program the configuration registers, the following sequence must be followed:
-1. Enter Configuration Mode
-2. Configure the Configuration Registers
-3. Exit Configuration Mode.
-
-Enter Configuration Mode
-To place the chip into the Configuration State The config key (0x55) is written
-to the CONFIG PORT (0x2E). 
-
-Configuration Mode
-In configuration mode, the INDEX PORT is located at the CONFIG PORT address and
-the DATA PORT is at INDEX PORT address + 1.
-
-The desired configuration registers are accessed in two steps: 
-a.	Write the index of the Logical Device Number Configuration Register
-	(i.e., 0x07) to the INDEX PORT and then write the number of the
-	desired logical device to the DATA PORT.
-
-b.	Write the address of the desired configuration register within the
-	logical device to the INDEX PORT and then write or read the config-
-	uration register through the DATA PORT.  
-
-Note: If accessing the Global Configuration Registers, step (a) is not required.
-
-Exit Configuration Mode
-To exit the Configuration State the write 0xAA to the CONFIG PORT (0x2E).
-The chip returns to the RUN State.  (This is important).
-
-Programming Example
-The following is an example of how to read the SIO Device ID located at 0x20
-
-; ENTER CONFIGURATION MODE   
-MOV	DX,02EH
-MOV	AX,055H
-OUT	DX,AL
-; GLOBAL CONFIGURATION  REGISTER 
-MOV	DX,02EH
-MOV	AL,20H
-OUT	DX,AL 
-; READ THE DATA
-MOV	DX,02FH
-IN	AL,DX
-; EXIT CONFIGURATION MODE     
-MOV	DX,02EH
-MOV	AX,0AAH
-OUT	DX,AL
-
-The registers of interest for identifying the SIO on the dc7100 are Device ID
-(0x20) and Device Rev  (0x21).
-
-The Device ID will read 0X6F
-The Device Rev currently reads 0x01
-
-Obtaining the HWM Base Address.
-The following is an example of how to read the HWM Base Address located in
-Logical Device 8.
-
-; ENTER CONFIGURATION MODE   
-MOV	DX,02EH
-MOV	AX,055H
-OUT	DX,AL
-; CONFIGURE REGISTER CRE0,   
-; LOGICAL DEVICE 8           
-MOV	DX,02EH
-MOV	AL,07H
-OUT	DX,AL ;Point to LD# Config Reg
-MOV	DX,02FH
-MOV	AL, 08H
-OUT	DX,AL;Point to Logical Device 8
-;
-MOV	DX,02EH 
-MOV	AL,60H
-OUT	DX,AL	; Point to HWM Base Addr MSB
-MOV	DX,02FH
-IN	AL,DX	; Get MSB of HWM Base Addr
-; EXIT CONFIGURATION MODE     
-MOV	DX,02EH
-MOV	AX,0AAH
-OUT	DX,AL
diff --git a/Documentation/i2c/dev-interface b/Documentation/i2c/dev-interface
--- a/Documentation/i2c/dev-interface
+++ b/Documentation/i2c/dev-interface
@@ -14,9 +14,12 @@ C example
 =========
 
 So let's say you want to access an i2c adapter from a C program. The
-first thing to do is `#include <linux/i2c.h>" and "#include <linux/i2c-dev.h>. 
-Yes, I know, you should never include kernel header files, but until glibc 
-knows about i2c, there is not much choice.
+first thing to do is "#include <linux/i2c-dev.h>". Please note that
+there are two files named "i2c-dev.h" out there, one is distributed
+with the Linux kernel and is meant to be included from kernel
+driver code, the other one is distributed with lm_sensors and is
+meant to be included from user-space programs. You obviously want
+the second one here.
 
 Now, you have to decide which adapter you want to access. You should
 inspect /sys/class/i2c-dev/ to decide this. Adapter numbers are assigned
@@ -78,7 +81,7 @@ Full interface description
 ==========================
 
 The following IOCTLs are defined and fully supported 
-(see also i2c-dev.h and i2c.h):
+(see also i2c-dev.h):
 
 ioctl(file,I2C_SLAVE,long addr)
   Change slave address. The address is passed in the 7 lower bits of the
@@ -97,10 +100,10 @@ ioctl(file,I2C_PEC,long select)
 ioctl(file,I2C_FUNCS,unsigned long *funcs)
   Gets the adapter functionality and puts it in *funcs.
 
-ioctl(file,I2C_RDWR,struct i2c_ioctl_rdwr_data *msgset)
+ioctl(file,I2C_RDWR,struct i2c_rdwr_ioctl_data *msgset)
 
   Do combined read/write transaction without stop in between.
-  The argument is a pointer to a struct i2c_ioctl_rdwr_data {
+  The argument is a pointer to a struct i2c_rdwr_ioctl_data {
 
       struct i2c_msg *msgs;  /* ptr to array of simple messages */
       int nmsgs;             /* number of messages to exchange */
diff --git a/Documentation/i2c/porting-clients b/Documentation/i2c/porting-clients
--- a/Documentation/i2c/porting-clients
+++ b/Documentation/i2c/porting-clients
@@ -57,7 +57,7 @@ Technical changes:
   Documentation/i2c/sysfs-interface for the individual files. Also
   convert the units these files read and write to the specified ones.
   If you need to add a new type of file, please discuss it on the
-  sensors mailing list <sensors@stimpy.netroedge.com> by providing a
+  sensors mailing list <lm-sensors@lm-sensors.org> by providing a
   patch to the Documentation/i2c/sysfs-interface file.
 
 * [Attach] For I2C drivers, the attach function should make sure
diff --git a/Documentation/i2c/sysfs-interface b/Documentation/i2c/sysfs-interface
deleted file mode 100644
--- a/Documentation/i2c/sysfs-interface
+++ /dev/null
@@ -1,274 +0,0 @@
-Naming and data format standards for sysfs files
-------------------------------------------------
-
-The libsensors library offers an interface to the raw sensors data
-through the sysfs interface. See libsensors documentation and source for
-more further information. As of writing this document, libsensors
-(from lm_sensors 2.8.3) is heavily chip-dependant. Adding or updating
-support for any given chip requires modifying the library's code.
-This is because libsensors was written for the procfs interface
-older kernel modules were using, which wasn't standardized enough.
-Recent versions of libsensors (from lm_sensors 2.8.2 and later) have
-support for the sysfs interface, though.
-
-The new sysfs interface was designed to be as chip-independant as
-possible.
-
-Note that motherboards vary widely in the connections to sensor chips.
-There is no standard that ensures, for example, that the second
-temperature sensor is connected to the CPU, or that the second fan is on
-the CPU. Also, some values reported by the chips need some computation
-before they make full sense. For example, most chips can only measure
-voltages between 0 and +4V. Other voltages are scaled back into that
-range using external resistors. Since the values of these resistors
-can change from motherboard to motherboard, the conversions cannot be
-hard coded into the driver and have to be done in user space.
-
-For this reason, even if we aim at a chip-independant libsensors, it will
-still require a configuration file (e.g. /etc/sensors.conf) for proper
-values conversion, labeling of inputs and hiding of unused inputs.
-
-An alternative method that some programs use is to access the sysfs
-files directly. This document briefly describes the standards that the
-drivers follow, so that an application program can scan for entries and
-access this data in a simple and consistent way. That said, such programs
-will have to implement conversion, labeling and hiding of inputs. For
-this reason, it is still not recommended to bypass the library.
-
-If you are developing a userspace application please send us feedback on
-this standard.
-
-Note that this standard isn't completely established yet, so it is subject
-to changes, even important ones. One more reason to use the library instead
-of accessing sysfs files directly.
-
-Each chip gets its own directory in the sysfs /sys/devices tree.  To
-find all sensor chips, it is easier to follow the symlinks from
-/sys/i2c/devices/
-
-All sysfs values are fixed point numbers.  To get the true value of some
-of the values, you should divide by the specified value.
-
-There is only one value per file, unlike the older /proc specification.
-The common scheme for files naming is: <type><number>_<item>. Usual
-types for sensor chips are "in" (voltage), "temp" (temperature) and
-"fan" (fan). Usual items are "input" (measured value), "max" (high
-threshold, "min" (low threshold). Numbering usually starts from 1,
-except for voltages which start from 0 (because most data sheets use
-this). A number is always used for elements that can be present more
-than once, even if there is a single element of the given type on the
-specific chip. Other files do not refer to a specific element, so
-they have a simple name, and no number.
-
-Alarms are direct indications read from the chips. The drivers do NOT
-make comparisons of readings to thresholds. This allows violations
-between readings to be caught and alarmed. The exact definition of an
-alarm (for example, whether a threshold must be met or must be exceeded
-to cause an alarm) is chip-dependent.
-
-
--------------------------------------------------------------------------
-
-************
-* Voltages *
-************
-
-in[0-8]_min	Voltage min value.
-		Unit: millivolt
-		Read/Write
-		
-in[0-8]_max	Voltage max value.
-		Unit: millivolt
-		Read/Write
-		
-in[0-8]_input	Voltage input value.
-		Unit: millivolt
-		Read only
-		Actual voltage depends on the scaling resistors on the
-		motherboard, as recommended in the chip datasheet.
-		This varies by chip and by motherboard.
-		Because of this variation, values are generally NOT scaled
-		by the chip driver, and must be done by the application.
-		However, some drivers (notably lm87 and via686a)
-		do scale, with various degrees of success.
-		These drivers will output the actual voltage.
-
-		Typical usage:
-			in0_*	CPU #1 voltage (not scaled)
-			in1_*	CPU #2 voltage (not scaled)
-			in2_*	3.3V nominal (not scaled)
-			in3_*	5.0V nominal (scaled)
-			in4_*	12.0V nominal (scaled)
-			in5_*	-12.0V nominal (scaled)
-			in6_*	-5.0V nominal (scaled)
-			in7_*	varies
-			in8_*	varies
-
-cpu[0-1]_vid	CPU core reference voltage.
-		Unit: millivolt
-		Read only.
-		Not always correct.
-
-vrm		Voltage Regulator Module version number. 
-		Read only.
-		Two digit number, first is major version, second is
-		minor version.
-		Affects the way the driver calculates the CPU core reference
-		voltage from the vid pins.
-
-
-********
-* Fans *
-********
-
-fan[1-3]_min	Fan minimum value
-		Unit: revolution/min (RPM)
-		Read/Write.
-
-fan[1-3]_input	Fan input value.
-		Unit: revolution/min (RPM)
-		Read only.
-
-fan[1-3]_div	Fan divisor.
-		Integer value in powers of two (1, 2, 4, 8, 16, 32, 64, 128).
-		Some chips only support values 1, 2, 4 and 8.
-		Note that this is actually an internal clock divisor, which
-		affects the measurable speed range, not the read value.
-
-*******
-* PWM *
-*******
-
-pwm[1-3]	Pulse width modulation fan control.
-		Integer value in the range 0 to 255
-		Read/Write
-		255 is max or 100%.
-
-pwm[1-3]_enable
-		Switch PWM on and off.
-		Not always present even if fan*_pwm is.
-		0 to turn off
-		1 to turn on in manual mode
-		2 to turn on in automatic mode
-		Read/Write
-
-pwm[1-*]_auto_channels_temp
-		Select which temperature channels affect this PWM output in
-		auto mode. Bitfield, 1 is temp1, 2 is temp2, 4 is temp3 etc...
-		Which values are possible depend on the chip used.
-
-pwm[1-*]_auto_point[1-*]_pwm
-pwm[1-*]_auto_point[1-*]_temp
-pwm[1-*]_auto_point[1-*]_temp_hyst
-		Define the PWM vs temperature curve. Number of trip points is
-		chip-dependent. Use this for chips which associate trip points
-		to PWM output channels.
-
-OR
-
-temp[1-*]_auto_point[1-*]_pwm
-temp[1-*]_auto_point[1-*]_temp
-temp[1-*]_auto_point[1-*]_temp_hyst
-		Define the PWM vs temperature curve. Number of trip points is
-		chip-dependent. Use this for chips which associate trip points
-		to temperature channels.
-
-
-****************
-* Temperatures *
-****************
-
-temp[1-3]_type	Sensor type selection.
-		Integers 1, 2, 3 or thermistor Beta value (3435)
-		Read/Write.
-		1: PII/Celeron Diode
-		2: 3904 transistor
-		3: thermal diode
-		Not all types are supported by all chips
-
-temp[1-4]_max	Temperature max value.
-		Unit: millidegree Celcius
-		Read/Write value.
-
-temp[1-3]_min	Temperature min value.
-		Unit: millidegree Celcius
-		Read/Write value.
-
-temp[1-3]_max_hyst
-		Temperature hysteresis value for max limit.
-		Unit: millidegree Celcius
-		Must be reported as an absolute temperature, NOT a delta
-		from the max value.
-		Read/Write value.
-
-temp[1-4]_input Temperature input value.
-		Unit: millidegree Celcius
-		Read only value.
-
-temp[1-4]_crit	Temperature critical value, typically greater than
-		corresponding temp_max values.
-		Unit: millidegree Celcius
-		Read/Write value.
-
-temp[1-2]_crit_hyst
-		Temperature hysteresis value for critical limit.
-		Unit: millidegree Celcius
-		Must be reported as an absolute temperature, NOT a delta
-		from the critical value.
-		Read/Write value.
-
-		If there are multiple temperature sensors, temp1_* is
-		generally the sensor inside the chip itself,
-		reported as "motherboard temperature".  temp2_* to
-		temp4_* are generally sensors external to the chip
-		itself, for example the thermal diode inside the CPU or
-		a thermistor nearby.
-
-
-************
-* Currents *
-************
-
-Note that no known chip provides current measurements as of writing,
-so this part is theoretical, so to say.
-
-curr[1-n]_max	Current max value
-		Unit: milliampere
-		Read/Write.
-
-curr[1-n]_min	Current min value.
-		Unit: milliampere
-		Read/Write.
-
-curr[1-n]_input	Current input value
-		Unit: milliampere
-		Read only.
-
-
-*********
-* Other *
-*********
-
-alarms		Alarm bitmask.
-		Read only.
-		Integer representation of one to four bytes.
-		A '1' bit means an alarm.
-		Chips should be programmed for 'comparator' mode so that
-		the alarm will 'come back' after you read the register
-		if it is still valid.
-		Generally a direct representation of a chip's internal
-		alarm registers; there is no standard for the position
-		of individual bits.
-		Bits are defined in kernel/include/sensors.h.
-
-beep_enable	Beep/interrupt enable
-		0 to disable.
-		1 to enable.
-		Read/Write
-
-beep_mask	Bitmask for beep.
-		Same format as 'alarms' with the same bit locations.
-		Read/Write
-
-eeprom		Raw EEPROM data in binary form.
-		Read only.
diff --git a/Documentation/i2c/writing-clients b/Documentation/i2c/writing-clients
--- a/Documentation/i2c/writing-clients
+++ b/Documentation/i2c/writing-clients
@@ -27,7 +27,6 @@ address.
 static struct i2c_driver foo_driver = {
 	.owner		= THIS_MODULE,
 	.name		= "Foo version 2.3 driver",
-	.id		= I2C_DRIVERID_FOO, /* from i2c-id.h, optional */
 	.flags		= I2C_DF_NOTIFY,
 	.attach_adapter	= &foo_attach_adapter,
 	.detach_client	= &foo_detach_client,
@@ -37,12 +36,6 @@ static struct i2c_driver foo_driver = {
 The name can be chosen freely, and may be upto 40 characters long. Please
 use something descriptive here.
 
-If used, the id should be a unique ID. The range 0xf000 to 0xffff is
-reserved for local use, and you can use one of those until you start
-distributing the driver, at which time you should contact the i2c authors
-to get your own ID(s). Note that most of the time you don't need an ID
-at all so you can just omit it.
-
 Don't worry about the flags field; just put I2C_DF_NOTIFY into it. This
 means that your driver will be notified when new adapters are found.
 This is almost always what you want.
@@ -171,45 +164,31 @@ The following lists are used internally:
 
   normal_i2c: filled in by the module writer. 
      A list of I2C addresses which should normally be examined.
-   normal_i2c_range: filled in by the module writer.
-     A list of pairs of I2C addresses, each pair being an inclusive range of
-     addresses which should normally be examined.
    probe: insmod parameter. 
      A list of pairs. The first value is a bus number (-1 for any I2C bus), 
      the second is the address. These addresses are also probed, as if they 
      were in the 'normal' list.
-   probe_range: insmod parameter. 
-     A list of triples. The first value is a bus number (-1 for any I2C bus), 
-     the second and third are addresses.  These form an inclusive range of 
-     addresses that are also probed, as if they were in the 'normal' list.
    ignore: insmod parameter.
      A list of pairs. The first value is a bus number (-1 for any I2C bus), 
      the second is the I2C address. These addresses are never probed. 
      This parameter overrules 'normal' and 'probe', but not the 'force' lists.
-   ignore_range: insmod parameter. 
-     A list of triples. The first value is a bus number (-1 for any I2C bus), 
-     the second and third are addresses. These form an inclusive range of 
-     I2C addresses that are never probed.
-     This parameter overrules 'normal' and 'probe', but not the 'force' lists.
    force: insmod parameter. 
      A list of pairs. The first value is a bus number (-1 for any I2C bus),
      the second is the I2C address. A device is blindly assumed to be on
      the given address, no probing is done. 
 
-Fortunately, as a module writer, you just have to define the `normal' 
-and/or `normal_range' parameters. The complete declaration could look
-like this:
-
-  /* Scan 0x20 to 0x2f, 0x37, and 0x40 to 0x4f */
-  static unsigned short normal_i2c[] = { 0x37,I2C_CLIENT_END }; 
-  static unsigned short normal_i2c_range[] = { 0x20, 0x2f, 0x40, 0x4f, 
-                                               I2C_CLIENT_END };
+Fortunately, as a module writer, you just have to define the `normal_i2c' 
+parameter. The complete declaration could look like this:
+
+  /* Scan 0x37, and 0x48 to 0x4f */
+  static unsigned short normal_i2c[] = { 0x37, 0x48, 0x49, 0x4a, 0x4b, 0x4c,
+                                         0x4d, 0x4e, 0x4f, I2C_CLIENT_END };
 
   /* Magic definition of all other variables and things */
   I2C_CLIENT_INSMOD;
 
-Note that you *have* to call the two defined variables `normal_i2c' and
-`normal_i2c_range', without any prefix!
+Note that you *have* to call the defined variable `normal_i2c',
+without any prefix!
 
 
 Probing classes (sensors)
@@ -223,39 +202,17 @@ The following lists are used internally.
 
    normal_i2c: filled in by the module writer. Terminated by SENSORS_I2C_END.
      A list of I2C addresses which should normally be examined.
-   normal_i2c_range: filled in by the module writer. Terminated by 
-     SENSORS_I2C_END
-     A list of pairs of I2C addresses, each pair being an inclusive range of
-     addresses which should normally be examined.
    normal_isa: filled in by the module writer. Terminated by SENSORS_ISA_END.
      A list of ISA addresses which should normally be examined.
-   normal_isa_range: filled in by the module writer. Terminated by 
-     SENSORS_ISA_END
-     A list of triples. The first two elements are ISA addresses, being an
-     range of addresses which should normally be examined. The third is the
-     modulo parameter: only addresses which are 0 module this value relative
-     to the first address of the range are actually considered.
    probe: insmod parameter. Initialize this list with SENSORS_I2C_END values.
      A list of pairs. The first value is a bus number (SENSORS_ISA_BUS for
      the ISA bus, -1 for any I2C bus), the second is the address. These
      addresses are also probed, as if they were in the 'normal' list.
-   probe_range: insmod parameter. Initialize this list with SENSORS_I2C_END 
-     values.
-     A list of triples. The first value is a bus number (SENSORS_ISA_BUS for
-     the ISA bus, -1 for any I2C bus), the second and third are addresses. 
-     These form an inclusive range of addresses that are also probed, as
-     if they were in the 'normal' list.
    ignore: insmod parameter. Initialize this list with SENSORS_I2C_END values.
      A list of pairs. The first value is a bus number (SENSORS_ISA_BUS for
      the ISA bus, -1 for any I2C bus), the second is the I2C address. These
      addresses are never probed. This parameter overrules 'normal' and 
      'probe', but not the 'force' lists.
-   ignore_range: insmod parameter. Initialize this list with SENSORS_I2C_END 
-      values.
-     A list of triples. The first value is a bus number (SENSORS_ISA_BUS for
-     the ISA bus, -1 for any I2C bus), the second and third are addresses. 
-     These form an inclusive range of I2C addresses that are never probed.
-     This parameter overrules 'normal' and 'probe', but not the 'force' lists.
 
 Also used is a list of pointers to sensors_force_data structures:
    force_data: insmod parameters. A list, ending with an element of which
@@ -269,16 +226,14 @@ Also used is a list of pointers to senso
 So we have a generic insmod variabled `force', and chip-specific variables
 `force_CHIPNAME'.
 
-Fortunately, as a module writer, you just have to define the `normal' 
-and/or `normal_range' parameters, and define what chip names are used. 
+Fortunately, as a module writer, you just have to define the `normal_i2c' 
+and `normal_isa' parameters, and define what chip names are used. 
 The complete declaration could look like this:
-  /* Scan i2c addresses 0x20 to 0x2f, 0x37, and 0x40 to 0x4f
-  static unsigned short normal_i2c[] = {0x37,SENSORS_I2C_END};
-  static unsigned short normal_i2c_range[] = {0x20,0x2f,0x40,0x4f,
-                                              SENSORS_I2C_END};
+  /* Scan i2c addresses 0x37, and 0x48 to 0x4f */
+  static unsigned short normal_i2c[] = { 0x37, 0x48, 0x49, 0x4a, 0x4b, 0x4c,
+                                         0x4d, 0x4e, 0x4f, I2C_CLIENT_END };
   /* Scan ISA address 0x290 */
   static unsigned int normal_isa[] = {0x0290,SENSORS_ISA_END};
-  static unsigned int normal_isa_range[] = {SENSORS_ISA_END};
 
   /* Define chips foo and bar, as well as all module parameters and things */
   SENSORS_INSMOD_2(foo,bar);
diff --git a/Documentation/infiniband/core_locking.txt b/Documentation/infiniband/core_locking.txt
new file mode 100644
--- /dev/null
+++ b/Documentation/infiniband/core_locking.txt
@@ -0,0 +1,114 @@
+INFINIBAND MIDLAYER LOCKING
+
+  This guide is an attempt to make explicit the locking assumptions
+  made by the InfiniBand midlayer.  It describes the requirements on
+  both low-level drivers that sit below the midlayer and upper level
+  protocols that use the midlayer.
+
+Sleeping and interrupt context
+
+  With the following exceptions, a low-level driver implementation of
+  all of the methods in struct ib_device may sleep.  The exceptions
+  are any methods from the list:
+
+    create_ah
+    modify_ah
+    query_ah
+    destroy_ah
+    bind_mw
+    post_send
+    post_recv
+    poll_cq
+    req_notify_cq
+    map_phys_fmr
+
+  which may not sleep and must be callable from any context.
+
+  The corresponding functions exported to upper level protocol
+  consumers:
+
+    ib_create_ah
+    ib_modify_ah
+    ib_query_ah
+    ib_destroy_ah
+    ib_bind_mw
+    ib_post_send
+    ib_post_recv
+    ib_req_notify_cq
+    ib_map_phys_fmr
+
+  are therefore safe to call from any context.
+
+  In addition, the function
+
+    ib_dispatch_event
+
+  used by low-level drivers to dispatch asynchronous events through
+  the midlayer is also safe to call from any context.
+
+Reentrancy
+
+  All of the methods in struct ib_device exported by a low-level
+  driver must be fully reentrant.  The low-level driver is required to
+  perform all synchronization necessary to maintain consistency, even
+  if multiple function calls using the same object are run
+  simultaneously.
+
+  The IB midlayer does not perform any serialization of function calls.
+
+  Because low-level drivers are reentrant, upper level protocol
+  consumers are not required to perform any serialization.  However,
+  some serialization may be required to get sensible results.  For
+  example, a consumer may safely call ib_poll_cq() on multiple CPUs
+  simultaneously.  However, the ordering of the work completion
+  information between different calls of ib_poll_cq() is not defined.
+
+Callbacks
+
+  A low-level driver must not perform a callback directly from the
+  same callchain as an ib_device method call.  For example, it is not
+  allowed for a low-level driver to call a consumer's completion event
+  handler directly from its post_send method.  Instead, the low-level
+  driver should defer this callback by, for example, scheduling a
+  tasklet to perform the callback.
+
+  The low-level driver is responsible for ensuring that multiple
+  completion event handlers for the same CQ are not called
+  simultaneously.  The driver must guarantee that only one CQ event
+  handler for a given CQ is running at a time.  In other words, the
+  following situation is not allowed:
+
+        CPU1                                    CPU2
+
+  low-level driver ->
+    consumer CQ event callback:
+      /* ... */
+      ib_req_notify_cq(cq, ...);
+                                        low-level driver ->
+      /* ... */                           consumer CQ event callback:
+                                            /* ... */
+      return from CQ event handler
+
+  The context in which completion event and asynchronous event
+  callbacks run is not defined.  Depending on the low-level driver, it
+  may be process context, softirq context, or interrupt context.
+  Upper level protocol consumers may not sleep in a callback.
+
+Hot-plug
+
+  A low-level driver announces that a device is ready for use by
+  consumers when it calls ib_register_device(), all initialization
+  must be complete before this call.  The device must remain usable
+  until the driver's call to ib_unregister_device() has returned.
+
+  A low-level driver must call ib_register_device() and
+  ib_unregister_device() from process context.  It must not hold any
+  semaphores that could cause deadlock if a consumer calls back into
+  the driver across these calls.
+
+  An upper level protocol consumer may begin using an IB device as
+  soon as the add method of its struct ib_client is called for that
+  device.  A consumer must finish all cleanup and free all resources
+  relating to a device before returning from the remove method.
+
+  A consumer is permitted to sleep in its add and remove methods.
diff --git a/Documentation/infiniband/user_mad.txt b/Documentation/infiniband/user_mad.txt
--- a/Documentation/infiniband/user_mad.txt
+++ b/Documentation/infiniband/user_mad.txt
@@ -28,13 +28,37 @@ Creating MAD agents
 
 Receiving MADs
 
-  MADs are received using read().  The buffer passed to read() must be
-  large enough to hold at least one struct ib_user_mad.  For example:
+  MADs are received using read().  The receive side now supports
+  RMPP. The buffer passed to read() must be at least one
+  struct ib_user_mad + 256 bytes. For example:
+
+  If the buffer passed is not large enough to hold the received
+  MAD (RMPP), the errno is set to ENOSPC and the length of the
+  buffer needed is set in mad.length.
+
+  Example for normal MAD (non RMPP) reads:
+	struct ib_user_mad *mad;
+	mad = malloc(sizeof *mad + 256);
+	ret = read(fd, mad, sizeof *mad + 256);
+	if (ret != sizeof mad + 256) {
+		perror("read");
+		free(mad);
+	}
 
-	struct ib_user_mad mad;
-	ret = read(fd, &mad, sizeof mad);
-	if (ret != sizeof mad)
+  Example for RMPP reads:
+	struct ib_user_mad *mad;
+	mad = malloc(sizeof *mad + 256);
+	ret = read(fd, mad, sizeof *mad + 256);
+	if (ret == -ENOSPC)) {
+		length = mad.length;
+		free(mad);
+		mad = malloc(sizeof *mad + length);
+		ret = read(fd, mad, sizeof *mad + length);
+	}
+	if (ret < 0) {
 		perror("read");
+		free(mad);
+	}
 
   In addition to the actual MAD contents, the other struct ib_user_mad
   fields will be filled in with information on the received MAD.  For
@@ -50,18 +74,21 @@ Sending MADs
 
   MADs are sent using write().  The agent ID for sending should be
   filled into the id field of the MAD, the destination LID should be
-  filled into the lid field, and so on.  For example:
+  filled into the lid field, and so on.  The send side does support
+  RMPP so arbitrary length MAD can be sent. For example:
+
+	struct ib_user_mad *mad;
 
-	struct ib_user_mad mad;
+	mad = malloc(sizeof *mad + mad_length);
 
-	/* fill in mad.data */
+	/* fill in mad->data */
 
-	mad.id  = my_agent;	/* req.id from agent registration */
-	mad.lid = my_dest;	/* in network byte order... */
+	mad->hdr.id  = my_agent;	/* req.id from agent registration */
+	mad->hdr.lid = my_dest;		/* in network byte order... */
 	/* etc. */
 
-	ret = write(fd, &mad, sizeof mad);
-	if (ret != sizeof mad)
+	ret = write(fd, &mad, sizeof *mad + mad_length);
+	if (ret != sizeof *mad + mad_length)
 		perror("write");
 
 Setting IsSM Capability Bit
diff --git a/Documentation/infiniband/user_verbs.txt b/Documentation/infiniband/user_verbs.txt
new file mode 100644
--- /dev/null
+++ b/Documentation/infiniband/user_verbs.txt
@@ -0,0 +1,69 @@
+USERSPACE VERBS ACCESS
+
+  The ib_uverbs module, built by enabling CONFIG_INFINIBAND_USER_VERBS,
+  enables direct userspace access to IB hardware via "verbs," as
+  described in chapter 11 of the InfiniBand Architecture Specification.
+
+  To use the verbs, the libibverbs library, available from
+  <http://openib.org/>, is required.  libibverbs contains a
+  device-independent API for using the ib_uverbs interface.
+  libibverbs also requires appropriate device-dependent kernel and
+  userspace driver for your InfiniBand hardware.  For example, to use
+  a Mellanox HCA, you will need the ib_mthca kernel module and the
+  libmthca userspace driver be installed.
+
+User-kernel communication
+
+  Userspace communicates with the kernel for slow path, resource
+  management operations via the /dev/infiniband/uverbsN character
+  devices.  Fast path operations are typically performed by writing
+  directly to hardware registers mmap()ed into userspace, with no
+  system call or context switch into the kernel.
+
+  Commands are sent to the kernel via write()s on these device files.
+  The ABI is defined in drivers/infiniband/include/ib_user_verbs.h.
+  The structs for commands that require a response from the kernel
+  contain a 64-bit field used to pass a pointer to an output buffer.
+  Status is returned to userspace as the return value of the write()
+  system call.
+
+Resource management
+
+  Since creation and destruction of all IB resources is done by
+  commands passed through a file descriptor, the kernel can keep track
+  of which resources are attached to a given userspace context.  The
+  ib_uverbs module maintains idr tables that are used to translate
+  between kernel pointers and opaque userspace handles, so that kernel
+  pointers are never exposed to userspace and userspace cannot trick
+  the kernel into following a bogus pointer.
+
+  This also allows the kernel to clean up when a process exits and
+  prevent one process from touching another process's resources.
+
+Memory pinning
+
+  Direct userspace I/O requires that memory regions that are potential
+  I/O targets be kept resident at the same physical address.  The
+  ib_uverbs module manages pinning and unpinning memory regions via
+  get_user_pages() and put_page() calls.  It also accounts for the
+  amount of memory pinned in the process's locked_vm, and checks that
+  unprivileged processes do not exceed their RLIMIT_MEMLOCK limit.
+
+  Pages that are pinned multiple times are counted each time they are
+  pinned, so the value of locked_vm may be an overestimate of the
+  number of pages pinned by a process.
+
+/dev files
+
+  To create the appropriate character device files automatically with
+  udev, a rule like
+
+    KERNEL="uverbs*", NAME="infiniband/%k"
+
+  can be used.  This will create device nodes named
+
+    /dev/infiniband/uverbs0
+
+  and so on.  Since the InfiniBand userspace verbs should be safe for
+  use by non-privileged processes, it may be useful to add an
+  appropriate MODE or GROUP to the udev rule.
diff --git a/Documentation/kdump/gdbmacros.txt b/Documentation/kdump/gdbmacros.txt
new file mode 100644
--- /dev/null
+++ b/Documentation/kdump/gdbmacros.txt
@@ -0,0 +1,179 @@
+#
+# This file contains a few gdb macros (user defined commands) to extract
+# useful information from kernel crashdump (kdump) like stack traces of
+# all the processes or a particular process and trapinfo.
+#
+# These macros can be used by copying this file in .gdbinit (put in home
+# directory or current directory) or by invoking gdb command with
+# --command=<command-file-name> option
+#
+# Credits:
+# Alexander Nyberg <alexn@telia.com>
+# V Srivatsa <vatsa@in.ibm.com>
+# Maneesh Soni <maneesh@in.ibm.com>
+#
+
+define bttnobp
+	set $tasks_off=((size_t)&((struct task_struct *)0)->tasks)
+	set $pid_off=((size_t)&((struct task_struct *)0)->pids[1].pid_list.next)
+	set $init_t=&init_task
+	set $next_t=(((char *)($init_t->tasks).next) - $tasks_off)
+	while ($next_t != $init_t)
+		set $next_t=(struct task_struct *)$next_t
+		printf "\npid %d; comm %s:\n", $next_t.pid, $next_t.comm
+		printf "===================\n"
+		set var $stackp = $next_t.thread.esp
+		set var $stack_top = ($stackp & ~4095) + 4096
+
+		while ($stackp < $stack_top)
+			if (*($stackp) > _stext && *($stackp) < _sinittext)
+				info symbol *($stackp)
+			end
+			set $stackp += 4
+		end
+		set $next_th=(((char *)$next_t->pids[1].pid_list.next) - $pid_off)
+		while ($next_th != $next_t)
+			set $next_th=(struct task_struct *)$next_th
+			printf "\npid %d; comm %s:\n", $next_t.pid, $next_t.comm
+			printf "===================\n"
+			set var $stackp = $next_t.thread.esp
+			set var $stack_top = ($stackp & ~4095) + 4096
+
+			while ($stackp < $stack_top)
+				if (*($stackp) > _stext && *($stackp) < _sinittext)
+					info symbol *($stackp)
+				end
+				set $stackp += 4
+			end
+			set $next_th=(((char *)$next_th->pids[1].pid_list.next) - $pid_off)
+		end
+		set $next_t=(char *)($next_t->tasks.next) - $tasks_off
+	end
+end
+document bttnobp
+	dump all thread stack traces on a kernel compiled with !CONFIG_FRAME_POINTER
+end
+
+define btt
+	set $tasks_off=((size_t)&((struct task_struct *)0)->tasks)
+	set $pid_off=((size_t)&((struct task_struct *)0)->pids[1].pid_list.next)
+	set $init_t=&init_task
+	set $next_t=(((char *)($init_t->tasks).next) - $tasks_off)
+	while ($next_t != $init_t)
+		set $next_t=(struct task_struct *)$next_t
+		printf "\npid %d; comm %s:\n", $next_t.pid, $next_t.comm
+		printf "===================\n"
+		set var $stackp = $next_t.thread.esp
+		set var $stack_top = ($stackp & ~4095) + 4096
+		set var $stack_bot = ($stackp & ~4095)
+
+		set $stackp = *($stackp)
+		while (($stackp < $stack_top) && ($stackp > $stack_bot))
+			set var $addr = *($stackp + 4)
+			info symbol $addr
+			set $stackp = *($stackp)
+		end
+
+		set $next_th=(((char *)$next_t->pids[1].pid_list.next) - $pid_off)
+		while ($next_th != $next_t)
+			set $next_th=(struct task_struct *)$next_th
+			printf "\npid %d; comm %s:\n", $next_t.pid, $next_t.comm
+			printf "===================\n"
+			set var $stackp = $next_t.thread.esp
+			set var $stack_top = ($stackp & ~4095) + 4096
+			set var $stack_bot = ($stackp & ~4095)
+
+			set $stackp = *($stackp)
+			while (($stackp < $stack_top) && ($stackp > $stack_bot))
+				set var $addr = *($stackp + 4)
+				info symbol $addr
+				set $stackp = *($stackp)
+			end
+			set $next_th=(((char *)$next_th->pids[1].pid_list.next) - $pid_off)
+		end
+		set $next_t=(char *)($next_t->tasks.next) - $tasks_off
+	end
+end
+document btt
+	dump all thread stack traces on a kernel compiled with CONFIG_FRAME_POINTER
+end
+
+define btpid
+	set var $pid = $arg0
+	set $tasks_off=((size_t)&((struct task_struct *)0)->tasks)
+	set $pid_off=((size_t)&((struct task_struct *)0)->pids[1].pid_list.next)
+	set $init_t=&init_task
+	set $next_t=(((char *)($init_t->tasks).next) - $tasks_off)
+	set var $pid_task = 0
+
+	while ($next_t != $init_t)
+		set $next_t=(struct task_struct *)$next_t
+
+		if ($next_t.pid == $pid)
+			set $pid_task = $next_t
+		end
+
+		set $next_th=(((char *)$next_t->pids[1].pid_list.next) - $pid_off)
+		while ($next_th != $next_t)
+			set $next_th=(struct task_struct *)$next_th
+			if ($next_th.pid == $pid)
+				set $pid_task = $next_th
+			end
+			set $next_th=(((char *)$next_th->pids[1].pid_list.next) - $pid_off)
+		end
+		set $next_t=(char *)($next_t->tasks.next) - $tasks_off
+	end
+
+	printf "\npid %d; comm %s:\n", $pid_task.pid, $pid_task.comm
+	printf "===================\n"
+	set var $stackp = $pid_task.thread.esp
+	set var $stack_top = ($stackp & ~4095) + 4096
+	set var $stack_bot = ($stackp & ~4095)
+
+	set $stackp = *($stackp)
+	while (($stackp < $stack_top) && ($stackp > $stack_bot))
+		set var $addr = *($stackp + 4)
+		info symbol $addr
+		set $stackp = *($stackp)
+	end
+end
+document btpid
+	backtrace of pid
+end
+
+
+define trapinfo
+	set var $pid = $arg0
+	set $tasks_off=((size_t)&((struct task_struct *)0)->tasks)
+	set $pid_off=((size_t)&((struct task_struct *)0)->pids[1].pid_list.next)
+	set $init_t=&init_task
+	set $next_t=(((char *)($init_t->tasks).next) - $tasks_off)
+	set var $pid_task = 0
+
+	while ($next_t != $init_t)
+		set $next_t=(struct task_struct *)$next_t
+
+		if ($next_t.pid == $pid)
+			set $pid_task = $next_t
+		end
+
+		set $next_th=(((char *)$next_t->pids[1].pid_list.next) - $pid_off)
+		while ($next_th != $next_t)
+			set $next_th=(struct task_struct *)$next_th
+			if ($next_th.pid == $pid)
+				set $pid_task = $next_th
+			end
+			set $next_th=(((char *)$next_th->pids[1].pid_list.next) - $pid_off)
+		end
+		set $next_t=(char *)($next_t->tasks.next) - $tasks_off
+	end
+
+	printf "Trapno %ld, cr2 0x%lx, error_code %ld\n", $pid_task.thread.trap_no, \
+				$pid_task.thread.cr2, $pid_task.thread.error_code
+
+end
+document trapinfo
+	Run info threads and lookup pid of thread #1
+	'trapinfo <pid>' will tell you by which trap & possibly
+	addresthe kernel paniced.
+end
diff --git a/Documentation/kdump/kdump.txt b/Documentation/kdump/kdump.txt
new file mode 100644
--- /dev/null
+++ b/Documentation/kdump/kdump.txt
@@ -0,0 +1,141 @@
+Documentation for kdump - the kexec-based crash dumping solution
+================================================================
+
+DESIGN
+======
+
+Kdump uses kexec to reboot to a second kernel whenever a dump needs to be taken.
+This second kernel is booted with very little memory. The first kernel reserves
+the section of memory that the second kernel uses. This ensures that on-going
+DMA from the first kernel does not corrupt the second kernel.
+
+All the necessary information about Core image is encoded in ELF format and
+stored in reserved area of memory before crash. Physical address of start of
+ELF header is passed to new kernel through command line parameter elfcorehdr=.
+
+On i386, the first 640 KB of physical memory is needed to boot, irrespective
+of where the kernel loads. Hence, this region is backed up by kexec just before
+rebooting into the new kernel.
+
+In the second kernel, "old memory" can be accessed in two ways.
+
+- The first one is through a /dev/oldmem device interface. A capture utility
+  can read the device file and write out the memory in raw format. This is raw
+  dump of memory and analysis/capture tool should be intelligent enough to
+  determine where to look for the right information. ELF headers (elfcorehdr=)
+  can become handy here.
+
+- The second interface is through /proc/vmcore. This exports the dump as an ELF
+  format file which can be written out using any file copy command
+  (cp, scp, etc). Further, gdb can be used to perform limited debugging on
+  the dump file. This method ensures methods ensure that there is correct
+  ordering of the dump pages (corresponding to the first 640 KB that has been
+  relocated).
+
+SETUP
+=====
+
+1) Download http://www.xmission.com/~ebiederm/files/kexec/kexec-tools-1.101.tar.gz
+   and apply http://lse.sourceforge.net/kdump/patches/kexec-tools-1.101-kdump.patch
+   and after that build the source.
+
+2) Download and build the appropriate (latest) kexec/kdump (-mm) kernel
+   patchset and apply it to the vanilla kernel tree.
+
+   Two kernels need to be built in order to get this feature working.
+
+  A) First kernel:
+   a) Enable "kexec system call" feature (in Processor type and features).
+	CONFIG_KEXEC=y
+   b) This kernel's physical load address should be the default value of
+      0x100000 (0x100000, 1 MB) (in Processor type and features).
+	CONFIG_PHYSICAL_START=0x100000
+   c) Enable "sysfs file system support" (in Pseudo filesystems).
+	CONFIG_SYSFS=y
+   d) Boot into first kernel with the command line parameter "crashkernel=Y@X".
+      Use appropriate values for X and Y. Y denotes how much memory to reserve
+      for the second kernel, and X denotes at what physical address the reserved
+      memory section starts. For example: "crashkernel=64M@16M".
+
+  B) Second kernel:
+   a) Enable "kernel crash dumps" feature (in Processor type and features).
+	CONFIG_CRASH_DUMP=y
+   b) Specify a suitable value for "Physical address where the kernel is
+      loaded" (in Processor type and features). Typically this value
+      should be same as X (See option d) above, e.g., 16 MB or 0x1000000.
+	CONFIG_PHYSICAL_START=0x1000000
+   c) Enable "/proc/vmcore support" (Optional, in Pseudo filesystems).
+	CONFIG_PROC_VMCORE=y
+   d) Disable SMP support and build a UP kernel (Until it is fixed).
+   	CONFIG_SMP=n
+   e) Enable "Local APIC support on uniprocessors".
+   	CONFIG_X86_UP_APIC=y
+   f) Enable "IO-APIC support on uniprocessors"
+   	CONFIG_X86_UP_IOAPIC=y
+
+  Note:   i) Options a) and b) depend upon "Configure standard kernel features
+	     (for small systems)" (under General setup).
+	 ii) Option a) also depends on CONFIG_HIGHMEM (under Processor
+		type and features).
+	iii) Both option a) and b) are under "Processor type and features".
+
+3) Boot into the first kernel. You are now ready to try out kexec-based crash
+   dumps.
+
+4) Load the second kernel to be booted using:
+
+   kexec -p <second-kernel> --crash-dump --args-linux --append="root=<root-dev>
+   init 1 irqpoll"
+
+   Note: i) <second-kernel> has to be a vmlinux image. bzImage will not work,
+	    as of now.
+	ii) By default ELF headers are stored in ELF32 format (for i386). This
+	    is sufficient to represent the physical memory up to 4GB. To store
+	    headers in ELF64 format, specifiy "--elf64-core-headers" on the
+	    kexec command line additionally.
+       iii) Specify "irqpoll" as command line parameter. This reduces driver
+            initialization failures in second kernel due to shared interrupts.
+
+5) System reboots into the second kernel when a panic occurs. A module can be
+   written to force the panic or "ALT-SysRq-c" can be used initiate a crash
+   dump for testing purposes.
+
+6) Write out the dump file using
+
+   cp /proc/vmcore <dump-file>
+
+   Dump memory can also be accessed as a /dev/oldmem device for a linear/raw
+   view.  To create the device, type:
+
+   mknod /dev/oldmem c 1 12
+
+   Use "dd" with suitable options for count, bs and skip to access specific
+   portions of the dump.
+
+   Entire memory:  dd if=/dev/oldmem of=oldmem.001
+
+ANALYSIS
+========
+
+Limited analysis can be done using gdb on the dump file copied out of
+/proc/vmcore. Use vmlinux built with -g and run
+
+  gdb vmlinux <dump-file>
+
+Stack trace for the task on processor 0, register display, memory display
+work fine.
+
+Note: gdb cannot analyse core files generated in ELF64 format for i386.
+
+TODO
+====
+
+1) Provide a kernel pages filtering mechanism so that core file size is not
+   insane on systems having huge memory banks.
+2) Modify "crash" tool to make it recognize this dump.
+
+CONTACT
+=======
+
+Vivek Goyal (vgoyal@in.ibm.com)
+Maneesh Soni (maneesh@in.ibm.com)
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -37,7 +37,7 @@ restrictions referred to are that the re
 	IA-32	IA-32 aka i386 architecture is enabled.
 	IA-64	IA-64 architecture is enabled.
 	IOSCHED	More than one I/O scheduler is enabled.
-	IP_PNP	IP DCHP, BOOTP, or RARP is enabled.
+	IP_PNP	IP DHCP, BOOTP, or RARP is enabled.
 	ISAPNP	ISA PnP code is enabled.
 	ISDN	Appropriate ISDN support is enabled.
 	JOY	Appropriate joystick support is enabled.
@@ -159,6 +159,11 @@ running once the system is up.
 
 	acpi_fake_ecdt	[HW,ACPI] Workaround failure due to BIOS lacking ECDT
 
+	acpi_generic_hotkey [HW,ACPI]
+			Allow consolidated generic hotkey driver to
+			over-ride platform specific driver.
+			See also Documentation/acpi-hotkey.txt.
+
 	ad1816=		[HW,OSS]
 			Format: <io>,<irq>,<dma>,<dma2>
 			See also Documentation/sound/oss/AD1816.
@@ -358,6 +363,10 @@ running once the system is up.
 	cpia_pp=	[HW,PPT]
 			Format: { parport<nr> | auto | none }
 
+	crashkernel=nn[KMG]@ss[KMG]
+			[KNL] Reserve a chunk of physical memory to
+			hold a kernel to switch to with kexec on panic.
+
 	cs4232=		[HW,OSS]
 			Format: <io>,<irq>,<dma>,<dma2>,<mpuio>,<mpuirq>
 
@@ -447,6 +456,10 @@ running once the system is up.
 			Format: {"as"|"cfq"|"deadline"|"noop"}
 			See Documentation/block/as-iosched.txt
 			and Documentation/block/deadline-iosched.txt for details.
+	elfcorehdr=	[IA-32]
+			Specifies physical address of start of kernel core image
+			elf header.
+			See Documentation/kdump.txt for details.
 
 	enforcing	[SELINUX] Set initial enforcing status.
 			Format: {"0" | "1"}
@@ -548,6 +561,9 @@ running once the system is up.
 
 	i810=		[HW,DRM]
 
+	i8k.ignore_dmi	[HW] Continue probing hardware even if DMI data
+			indicates that the driver is running on unsupported
+			hardware.
 	i8k.force	[HW] Activate i8k driver even if SMM BIOS signature
 			does not match list of supported models.
 	i8k.power_status
@@ -611,6 +627,17 @@ running once the system is up.
 	ips=		[HW,SCSI] Adaptec / IBM ServeRAID controller
 			See header of drivers/scsi/ips.c.
 
+	irqfixup	[HW]
+			When an interrupt is not handled search all handlers
+			for it. Intended to get systems with badly broken
+			firmware running.
+
+	irqpoll		[HW]
+			When an interrupt is not handled search all handlers
+			for it. Also check all handlers each timer
+			interrupt. Intended to get systems with badly broken
+			firmware running.
+
 	isapnp=		[ISAPNP]
 			Format: <RDP>, <reset>, <pci_scan>, <verbosity>
 
@@ -736,6 +763,9 @@ running once the system is up.
 	maxcpus=	[SMP] Maximum number of processors that	an SMP kernel
 			should make use of
 
+	max_addr=[KMG]	[KNL,BOOT,ia64] All physical memory greater than or
+			equal to this physical address is ignored.
+
 	max_luns=	[SCSI] Maximum number of LUNs to probe
 			Should be between 1 and 2^32-1.
 
@@ -1019,6 +1049,10 @@ running once the system is up.
 		irqmask=0xMMMM		[IA-32] Set a bit mask of IRQs allowed to be assigned
 					automatically to PCI devices. You can make the kernel
 					exclude IRQs of your ISA cards this way.
+		pirqaddr=0xAAAAA	[IA-32] Specify the physical address
+					of the PIRQ table (normally generated
+					by the BIOS) if it is outside the
+					F0000h-100000h range.
 		lastbus=N		[IA-32] Scan all buses till bus #N. Can be useful
 					if the kernel is unable to find your secondary buses
 					and you want to tell it explicitly which ones they are.
@@ -1104,7 +1138,7 @@ running once the system is up.
 			See Documentation/ramdisk.txt.
 
 	psmouse.proto=  [HW,MOUSE] Highest PS2 mouse protocol extension to
-			probe for (bare|imps|exps).
+			probe for (bare|imps|exps|lifebook|any).
 	psmouse.rate=	[HW,MOUSE] Set desired mouse report rate, in reports
 			per second.
 	psmouse.resetafter=
diff --git a/Documentation/keys.txt b/Documentation/keys.txt
--- a/Documentation/keys.txt
+++ b/Documentation/keys.txt
@@ -22,6 +22,7 @@ This document has the following sections
 	- New procfs files
 	- Userspace system call interface
 	- Kernel services
+	- Notes on accessing payload contents
 	- Defining a key type
 	- Request-key callback service
 	- Key access filesystem
@@ -45,27 +46,26 @@ Each key has a number of attributes:
 	- State.
 
 
- (*) Each key is issued a serial number of type key_serial_t that is unique
-     for the lifetime of that key. All serial numbers are positive non-zero
-     32-bit integers.
+ (*) Each key is issued a serial number of type key_serial_t that is unique for
+     the lifetime of that key. All serial numbers are positive non-zero 32-bit
+     integers.
 
      Userspace programs can use a key's serial numbers as a way to gain access
      to it, subject to permission checking.
 
  (*) Each key is of a defined "type". Types must be registered inside the
-     kernel by a kernel service (such as a filesystem) before keys of that
-     type can be added or used. Userspace programs cannot define new types
-     directly.
+     kernel by a kernel service (such as a filesystem) before keys of that type
+     can be added or used. Userspace programs cannot define new types directly.
 
-     Key types are represented in the kernel by struct key_type. This defines
-     a number of operations that can be performed on a key of that type.
+     Key types are represented in the kernel by struct key_type. This defines a
+     number of operations that can be performed on a key of that type.
 
      Should a type be removed from the system, all the keys of that type will
      be invalidated.
 
  (*) Each key has a description. This should be a printable string. The key
-     type provides an operation to perform a match between the description on
-     a key and a criterion string.
+     type provides an operation to perform a match between the description on a
+     key and a criterion string.
 
  (*) Each key has an owner user ID, a group ID and a permissions mask. These
      are used to control what a process may do to a key from userspace, and
@@ -74,10 +74,10 @@ Each key has a number of attributes:
  (*) Each key can be set to expire at a specific time by the key type's
      instantiation function. Keys can also be immortal.
 
- (*) Each key can have a payload. This is a quantity of data that represent
-     the actual "key". In the case of a keyring, this is a list of keys to
-     which the keyring links; in the case of a user-defined key, it's an
-     arbitrary blob of data.
+ (*) Each key can have a payload. This is a quantity of data that represent the
+     actual "key". In the case of a keyring, this is a list of keys to which
+     the keyring links; in the case of a user-defined key, it's an arbitrary
+     blob of data.
 
      Having a payload is not required; and the payload can, in fact, just be a
      value stored in the struct key itself.
@@ -92,8 +92,8 @@ Each key has a number of attributes:
 
  (*) Each key can be in one of a number of basic states:
 
-     (*) Uninstantiated. The key exists, but does not have any data
-	 attached. Keys being requested from userspace will be in this state.
+     (*) Uninstantiated. The key exists, but does not have any data attached.
+     	 Keys being requested from userspace will be in this state.
 
      (*) Instantiated. This is the normal state. The key is fully formed, and
 	 has data attached.
@@ -140,10 +140,10 @@ The key service provides a number of fea
      clone, fork, vfork or execve occurs. A new keyring is created only when
      required.
 
-     The process-specific keyring is replaced with an empty one in the child
-     on clone, fork, vfork unless CLONE_THREAD is supplied, in which case it
-     is shared. execve also discards the process's process keyring and creates
-     a new one.
+     The process-specific keyring is replaced with an empty one in the child on
+     clone, fork, vfork unless CLONE_THREAD is supplied, in which case it is
+     shared. execve also discards the process's process keyring and creates a
+     new one.
 
      The session-specific keyring is persistent across clone, fork, vfork and
      execve, even when the latter executes a set-UID or set-GID binary. A
@@ -177,11 +177,11 @@ The key service provides a number of fea
      If a system call that modifies a key or keyring in some way would put the
      user over quota, the operation is refused and error EDQUOT is returned.
 
- (*) There's a system call interface by which userspace programs can create
-     and manipulate keys and keyrings.
+ (*) There's a system call interface by which userspace programs can create and
+     manipulate keys and keyrings.
 
- (*) There's a kernel interface by which services can register types and
-     search for keys.
+ (*) There's a kernel interface by which services can register types and search
+     for keys.
 
  (*) There's a way for the a search done from the kernel to call back to
      userspace to request a key that can't be found in a process's keyrings.
@@ -194,9 +194,9 @@ The key service provides a number of fea
 KEY ACCESS PERMISSIONS
 ======================
 
-Keys have an owner user ID, a group access ID, and a permissions mask. The
-mask has up to eight bits each for user, group and other access. Only five of
-each set of eight bits are defined. These permissions granted are:
+Keys have an owner user ID, a group access ID, and a permissions mask. The mask
+has up to eight bits each for user, group and other access. Only five of each
+set of eight bits are defined. These permissions granted are:
 
  (*) View
 
@@ -210,8 +210,8 @@ each set of eight bits are defined. Thes
 
  (*) Write
 
-     This permits a key's payload to be instantiated or updated, or it allows
-     a link to be added to or removed from a keyring.
+     This permits a key's payload to be instantiated or updated, or it allows a
+     link to be added to or removed from a keyring.
 
  (*) Search
 
@@ -238,8 +238,8 @@ about the status of the key service:
  (*) /proc/keys
 
      This lists all the keys on the system, giving information about their
-     type, description and permissions. The payload of the key is not
-     available this way:
+     type, description and permissions. The payload of the key is not available
+     this way:
 
 	SERIAL   FLAGS  USAGE EXPY PERM   UID   GID   TYPE      DESCRIPTION: SUMMARY
 	00000001 I-----    39 perm 1f0000     0     0 keyring   _uid_ses.0: 1/4
@@ -318,21 +318,21 @@ The main syscalls are:
      If a key of the same type and description as that proposed already exists
      in the keyring, this will try to update it with the given payload, or it
      will return error EEXIST if that function is not supported by the key
-     type. The process must also have permission to write to the key to be
-     able to update it. The new key will have all user permissions granted and
-     no group or third party permissions.
-
-     Otherwise, this will attempt to create a new key of the specified type
-     and description, and to instantiate it with the supplied payload and
-     attach it to the keyring. In this case, an error will be generated if the
-     process does not have permission to write to the keyring.
+     type. The process must also have permission to write to the key to be able
+     to update it. The new key will have all user permissions granted and no
+     group or third party permissions.
+
+     Otherwise, this will attempt to create a new key of the specified type and
+     description, and to instantiate it with the supplied payload and attach it
+     to the keyring. In this case, an error will be generated if the process
+     does not have permission to write to the keyring.
 
      The payload is optional, and the pointer can be NULL if not required by
      the type. The payload is plen in size, and plen can be zero for an empty
      payload.
 
-     A new keyring can be generated by setting type "keyring", the keyring
-     name as the description (or NULL) and setting the payload to NULL.
+     A new keyring can be generated by setting type "keyring", the keyring name
+     as the description (or NULL) and setting the payload to NULL.
 
      User defined keys can be created by specifying type "user". It is
      recommended that a user defined key's description by prefixed with a type
@@ -369,9 +369,9 @@ The keyctl syscall functions are:
 	key_serial_t keyctl(KEYCTL_GET_KEYRING_ID, key_serial_t id,
 			    int create);
 
-     The special key specified by "id" is looked up (with the key being
-     created if necessary) and the ID of the key or keyring thus found is
-     returned if it exists.
+     The special key specified by "id" is looked up (with the key being created
+     if necessary) and the ID of the key or keyring thus found is returned if
+     it exists.
 
      If the key does not yet exist, the key will be created if "create" is
      non-zero; and the error ENOKEY will be returned if "create" is zero.
@@ -402,8 +402,8 @@ The keyctl syscall functions are:
 
      This will try to update the specified key with the given payload, or it
      will return error EOPNOTSUPP if that function is not supported by the key
-     type. The process must also have permission to write to the key to be
-     able to update it.
+     type. The process must also have permission to write to the key to be able
+     to update it.
 
      The payload is of length plen, and may be absent or empty as for
      add_key().
@@ -422,8 +422,8 @@ The keyctl syscall functions are:
 
 	long keyctl(KEYCTL_CHOWN, key_serial_t key, uid_t uid, gid_t gid);
 
-     This function permits a key's owner and group ID to be changed. Either
-     one of uid or gid can be set to -1 to suppress that change.
+     This function permits a key's owner and group ID to be changed. Either one
+     of uid or gid can be set to -1 to suppress that change.
 
      Only the superuser can change a key's owner to something other than the
      key's current owner. Similarly, only the superuser can change a key's
@@ -484,12 +484,12 @@ The keyctl syscall functions are:
 
 	long keyctl(KEYCTL_LINK, key_serial_t keyring, key_serial_t key);
 
-     This function creates a link from the keyring to the key. The process
-     must have write permission on the keyring and must have link permission
-     on the key.
+     This function creates a link from the keyring to the key. The process must
+     have write permission on the keyring and must have link permission on the
+     key.
 
-     Should the keyring not be a keyring, error ENOTDIR will result; and if
-     the keyring is full, error ENFILE will result.
+     Should the keyring not be a keyring, error ENOTDIR will result; and if the
+     keyring is full, error ENFILE will result.
 
      The link procedure checks the nesting of the keyrings, returning ELOOP if
      it appears to deep or EDEADLK if the link would introduce a cycle.
@@ -503,8 +503,8 @@ The keyctl syscall functions are:
      specified key, and removes it if found. Subsequent links to that key are
      ignored. The process must have write permission on the keyring.
 
-     If the keyring is not a keyring, error ENOTDIR will result; and if the
-     key is not present, error ENOENT will be the result.
+     If the keyring is not a keyring, error ENOTDIR will result; and if the key
+     is not present, error ENOENT will be the result.
 
 
  (*) Search a keyring tree for a key:
@@ -513,9 +513,9 @@ The keyctl syscall functions are:
 			    const char *type, const char *description,
 			    key_serial_t dest_keyring);
 
-     This searches the keyring tree headed by the specified keyring until a
-     key is found that matches the type and description criteria. Each keyring
-     is checked for keys before recursion into its children occurs.
+     This searches the keyring tree headed by the specified keyring until a key
+     is found that matches the type and description criteria. Each keyring is
+     checked for keys before recursion into its children occurs.
 
      The process must have search permission on the top level keyring, or else
      error EACCES will result. Only keyrings that the process has search
@@ -549,8 +549,8 @@ The keyctl syscall functions are:
      As much of the data as can be fitted into the buffer will be copied to
      userspace if the buffer pointer is not NULL.
 
-     On a successful return, the function will always return the amount of
-     data available rather than the amount copied.
+     On a successful return, the function will always return the amount of data
+     available rather than the amount copied.
 
 
  (*) Instantiate a partially constructed key.
@@ -568,8 +568,8 @@ The keyctl syscall functions are:
      it, and the key must be uninstantiated.
 
      If a keyring is specified (non-zero), the key will also be linked into
-     that keyring, however all the constraints applying in KEYCTL_LINK apply
-     in this case too.
+     that keyring, however all the constraints applying in KEYCTL_LINK apply in
+     this case too.
 
      The payload and plen arguments describe the payload data as for add_key().
 
@@ -587,8 +587,39 @@ The keyctl syscall functions are:
      it, and the key must be uninstantiated.
 
      If a keyring is specified (non-zero), the key will also be linked into
-     that keyring, however all the constraints applying in KEYCTL_LINK apply
-     in this case too.
+     that keyring, however all the constraints applying in KEYCTL_LINK apply in
+     this case too.
+
+
+ (*) Set the default request-key destination keyring.
+
+	long keyctl(KEYCTL_SET_REQKEY_KEYRING, int reqkey_defl);
+
+     This sets the default keyring to which implicitly requested keys will be
+     attached for this thread. reqkey_defl should be one of these constants:
+
+	CONSTANT				VALUE	NEW DEFAULT KEYRING
+	======================================	======	=======================
+	KEY_REQKEY_DEFL_NO_CHANGE		-1	No change
+	KEY_REQKEY_DEFL_DEFAULT			0	Default[1]
+	KEY_REQKEY_DEFL_THREAD_KEYRING		1	Thread keyring
+	KEY_REQKEY_DEFL_PROCESS_KEYRING		2	Process keyring
+	KEY_REQKEY_DEFL_SESSION_KEYRING		3	Session keyring
+	KEY_REQKEY_DEFL_USER_KEYRING		4	User keyring
+	KEY_REQKEY_DEFL_USER_SESSION_KEYRING	5	User session keyring
+	KEY_REQKEY_DEFL_GROUP_KEYRING		6	Group keyring
+
+     The old default will be returned if successful and error EINVAL will be
+     returned if reqkey_defl is not one of the above values.
+
+     The default keyring can be overridden by the keyring indicated to the
+     request_key() system call.
+
+     Note that this setting is inherited across fork/exec.
+
+     [1] The default default is: the thread keyring if there is one, otherwise
+     the process keyring if there is one, otherwise the session keyring if
+     there is one, otherwise the user default session keyring.
 
 
 ===============
@@ -601,17 +632,14 @@ be broken down into two areas: keys and 
 Dealing with keys is fairly straightforward. Firstly, the kernel service
 registers its type, then it searches for a key of that type. It should retain
 the key as long as it has need of it, and then it should release it. For a
-filesystem or device file, a search would probably be performed during the
-open call, and the key released upon close. How to deal with conflicting keys
-due to two different users opening the same file is left to the filesystem
-author to solve.
-
-When accessing a key's payload data, key->lock should be at least read locked,
-or else the data may be changed by an update being performed from userspace
-whilst the driver or filesystem is trying to access it. If no update method is
-supplied, then the key's payload may be accessed without holding a lock as
-there is no way to change it, provided it can be guaranteed that the key's
-type definition won't go away.
+filesystem or device file, a search would probably be performed during the open
+call, and the key released upon close. How to deal with conflicting keys due to
+two different users opening the same file is left to the filesystem author to
+solve.
+
+When accessing a key's payload contents, certain precautions must be taken to
+prevent access vs modification races. See the section "Notes on accessing
+payload contents" for more information.
 
 (*) To search for a key, call:
 
@@ -629,6 +657,9 @@ type definition won't go away.
     Should the function fail error ENOKEY, EKEYEXPIRED or EKEYREVOKED will be
     returned.
 
+    If successful, the key will have been attached to the default keyring for
+    implicitly obtained request-key keys, as set by KEYCTL_SET_REQKEY_KEYRING.
+
 
 (*) When it is no longer required, the key should be released using:
 
@@ -690,6 +721,54 @@ type definition won't go away.
 	void unregister_key_type(struct key_type *type);
 
 
+===================================
+NOTES ON ACCESSING PAYLOAD CONTENTS
+===================================
+
+The simplest payload is just a number in key->payload.value. In this case,
+there's no need to indulge in RCU or locking when accessing the payload.
+
+More complex payload contents must be allocated and a pointer to them set in
+key->payload.data. One of the following ways must be selected to access the
+data:
+
+ (1) Unmodifyable key type.
+
+     If the key type does not have a modify method, then the key's payload can
+     be accessed without any form of locking, provided that it's known to be
+     instantiated (uninstantiated keys cannot be "found").
+
+ (2) The key's semaphore.
+
+     The semaphore could be used to govern access to the payload and to control
+     the payload pointer. It must be write-locked for modifications and would
+     have to be read-locked for general access. The disadvantage of doing this
+     is that the accessor may be required to sleep.
+
+ (3) RCU.
+
+     RCU must be used when the semaphore isn't already held; if the semaphore
+     is held then the contents can't change under you unexpectedly as the
+     semaphore must still be used to serialise modifications to the key. The
+     key management code takes care of this for the key type.
+
+     However, this means using:
+
+	rcu_read_lock() ... rcu_dereference() ... rcu_read_unlock()
+
+     to read the pointer, and:
+
+	rcu_dereference() ... rcu_assign_pointer() ... call_rcu()
+
+     to set the pointer and dispose of the old contents after a grace period.
+     Note that only the key type should ever modify a key's payload.
+
+     Furthermore, an RCU controlled payload must hold a struct rcu_head for the
+     use of call_rcu() and, if the payload is of variable size, the length of
+     the payload. key->datalen cannot be relied upon to be consistent with the
+     payload just dereferenced if the key's semaphore is not held.
+
+
 ===================
 DEFINING A KEY TYPE
 ===================
@@ -717,15 +796,15 @@ The structure has a number of fields, so
 
 	int key_payload_reserve(struct key *key, size_t datalen);
 
-     With the revised data length. Error EDQUOT will be returned if this is
-     not viable.
+     With the revised data length. Error EDQUOT will be returned if this is not
+     viable.
 
 
  (*) int (*instantiate)(struct key *key, const void *data, size_t datalen);
 
      This method is called to attach a payload to a key during construction.
-     The payload attached need not bear any relation to the data passed to
-     this function.
+     The payload attached need not bear any relation to the data passed to this
+     function.
 
      If the amount of data attached to the key differs from the size in
      keytype->def_datalen, then key_payload_reserve() should be called.
@@ -734,38 +813,47 @@ The structure has a number of fields, so
      The fact that KEY_FLAG_INSTANTIATED is not set in key->flags prevents
      anything else from gaining access to the key.
 
-     This method may sleep if it wishes.
+     It is safe to sleep in this method.
 
 
  (*) int (*duplicate)(struct key *key, const struct key *source);
 
      If this type of key can be duplicated, then this method should be
-     provided. It is called to copy the payload attached to the source into
-     the new key. The data length on the new key will have been updated and
-     the quota adjusted already.
+     provided. It is called to copy the payload attached to the source into the
+     new key. The data length on the new key will have been updated and the
+     quota adjusted already.
 
      This method will be called with the source key's semaphore read-locked to
-     prevent its payload from being changed. It is safe to sleep here.
+     prevent its payload from being changed, thus RCU constraints need not be
+     applied to the source key.
+
+     This method does not have to lock the destination key in order to attach a
+     payload. The fact that KEY_FLAG_INSTANTIATED is not set in key->flags
+     prevents anything else from gaining access to the key.
+
+     It is safe to sleep in this method.
 
 
  (*) int (*update)(struct key *key, const void *data, size_t datalen);
 
-     If this type of key can be updated, then this method should be
-     provided. It is called to update a key's payload from the blob of data
-     provided.
+     If this type of key can be updated, then this method should be provided.
+     It is called to update a key's payload from the blob of data provided.
 
      key_payload_reserve() should be called if the data length might change
-     before any changes are actually made. Note that if this succeeds, the
-     type is committed to changing the key because it's already been altered,
-     so all memory allocation must be done first.
-
-     key_payload_reserve() should be called with the key->lock write locked,
-     and the changes to the key's attached payload should be made before the
-     key is locked.
-
-     The key will have its semaphore write-locked before this method is
-     called. Any changes to the key should be made with the key's rwlock
-     write-locked also. It is safe to sleep here.
+     before any changes are actually made. Note that if this succeeds, the type
+     is committed to changing the key because it's already been altered, so all
+     memory allocation must be done first.
+
+     The key will have its semaphore write-locked before this method is called,
+     but this only deters other writers; any changes to the key's payload must
+     be made under RCU conditions, and call_rcu() must be used to dispose of
+     the old payload.
+
+     key_payload_reserve() should be called before the changes are made, but
+     after all allocations and other potentially failing function calls are
+     made.
+
+     It is safe to sleep in this method.
 
 
  (*) int (*match)(const struct key *key, const void *desc);
@@ -782,12 +870,12 @@ The structure has a number of fields, so
 
  (*) void (*destroy)(struct key *key);
 
-     This method is optional. It is called to discard the payload data on a
-     key when it is being destroyed.
+     This method is optional. It is called to discard the payload data on a key
+     when it is being destroyed.
 
-     This method does not need to lock the key; it can consider the key as
-     being inaccessible. Note that the key's type may have changed before this
-     function is called.
+     This method does not need to lock the key to access the payload; it can
+     consider the key as being inaccessible at this time. Note that the key's
+     type may have been changed before this function is called.
 
      It is not safe to sleep in this method; the caller may hold spinlocks.
 
@@ -797,26 +885,31 @@ The structure has a number of fields, so
      This method is optional. It is called during /proc/keys reading to
      summarise a key's description and payload in text form.
 
-     This method will be called with the key's rwlock read-locked. This will
-     prevent the key's payload and state changing; also the description should
-     not change. This also means it is not safe to sleep in this method.
+     This method will be called with the RCU read lock held. rcu_dereference()
+     should be used to read the payload pointer if the payload is to be
+     accessed. key->datalen cannot be trusted to stay consistent with the
+     contents of the payload.
+
+     The description will not change, though the key's state may.
+
+     It is not safe to sleep in this method; the RCU read lock is held by the
+     caller.
 
 
  (*) long (*read)(const struct key *key, char __user *buffer, size_t buflen);
 
      This method is optional. It is called by KEYCTL_READ to translate the
-     key's payload into something a blob of data for userspace to deal
-     with. Ideally, the blob should be in the same format as that passed in to
-     the instantiate and update methods.
+     key's payload into something a blob of data for userspace to deal with.
+     Ideally, the blob should be in the same format as that passed in to the
+     instantiate and update methods.
 
      If successful, the blob size that could be produced should be returned
      rather than the size copied.
 
-     This method will be called with the key's semaphore read-locked. This
-     will prevent the key's payload changing. It is not necessary to also
-     read-lock key->lock when accessing the key's payload. It is safe to sleep
-     in this method, such as might happen when the userspace buffer is
-     accessed.
+     This method will be called with the key's semaphore read-locked. This will
+     prevent the key's payload changing. It is not necessary to use RCU locking
+     when accessing the key's payload. It is safe to sleep in this method, such
+     as might happen when the userspace buffer is accessed.
 
 
 ============================
@@ -853,8 +946,8 @@ If it returns with the key remaining in 
 be marked as being negative, it will be added to the session keyring, and an
 error will be returned to the key requestor.
 
-Supplementary information may be provided from whoever or whatever invoked
-this service. This will be passed as the <callout_info> parameter. If no such
+Supplementary information may be provided from whoever or whatever invoked this
+service. This will be passed as the <callout_info> parameter. If no such
 information was made available, then "-" will be passed as this parameter
 instead.
 
diff --git a/Documentation/kprobes.txt b/Documentation/kprobes.txt
new file mode 100644
--- /dev/null
+++ b/Documentation/kprobes.txt
@@ -0,0 +1,588 @@
+Title	: Kernel Probes (Kprobes)
+Authors	: Jim Keniston <jkenisto@us.ibm.com>
+	: Prasanna S Panchamukhi <prasanna@in.ibm.com>
+
+CONTENTS
+
+1. Concepts: Kprobes, Jprobes, Return Probes
+2. Architectures Supported
+3. Configuring Kprobes
+4. API Reference
+5. Kprobes Features and Limitations
+6. Probe Overhead
+7. TODO
+8. Kprobes Example
+9. Jprobes Example
+10. Kretprobes Example
+
+1. Concepts: Kprobes, Jprobes, Return Probes
+
+Kprobes enables you to dynamically break into any kernel routine and
+collect debugging and performance information non-disruptively. You
+can trap at almost any kernel code address, specifying a handler
+routine to be invoked when the breakpoint is hit.
+
+There are currently three types of probes: kprobes, jprobes, and
+kretprobes (also called return probes).  A kprobe can be inserted
+on virtually any instruction in the kernel.  A jprobe is inserted at
+the entry to a kernel function, and provides convenient access to the
+function's arguments.  A return probe fires when a specified function
+returns.
+
+In the typical case, Kprobes-based instrumentation is packaged as
+a kernel module.  The module's init function installs ("registers")
+one or more probes, and the exit function unregisters them.  A
+registration function such as register_kprobe() specifies where
+the probe is to be inserted and what handler is to be called when
+the probe is hit.
+
+The next three subsections explain how the different types of
+probes work.  They explain certain things that you'll need to
+know in order to make the best use of Kprobes -- e.g., the
+difference between a pre_handler and a post_handler, and how
+to use the maxactive and nmissed fields of a kretprobe.  But
+if you're in a hurry to start using Kprobes, you can skip ahead
+to section 2.
+
+1.1 How Does a Kprobe Work?
+
+When a kprobe is registered, Kprobes makes a copy of the probed
+instruction and replaces the first byte(s) of the probed instruction
+with a breakpoint instruction (e.g., int3 on i386 and x86_64).
+
+When a CPU hits the breakpoint instruction, a trap occurs, the CPU's
+registers are saved, and control passes to Kprobes via the
+notifier_call_chain mechanism.  Kprobes executes the "pre_handler"
+associated with the kprobe, passing the handler the addresses of the
+kprobe struct and the saved registers.
+
+Next, Kprobes single-steps its copy of the probed instruction.
+(It would be simpler to single-step the actual instruction in place,
+but then Kprobes would have to temporarily remove the breakpoint
+instruction.  This would open a small time window when another CPU
+could sail right past the probepoint.)
+
+After the instruction is single-stepped, Kprobes executes the
+"post_handler," if any, that is associated with the kprobe.
+Execution then continues with the instruction following the probepoint.
+
+1.2 How Does a Jprobe Work?
+
+A jprobe is implemented using a kprobe that is placed on a function's
+entry point.  It employs a simple mirroring principle to allow
+seamless access to the probed function's arguments.  The jprobe
+handler routine should have the same signature (arg list and return
+type) as the function being probed, and must always end by calling
+the Kprobes function jprobe_return().
+
+Here's how it works.  When the probe is hit, Kprobes makes a copy of
+the saved registers and a generous portion of the stack (see below).
+Kprobes then points the saved instruction pointer at the jprobe's
+handler routine, and returns from the trap.  As a result, control
+passes to the handler, which is presented with the same register and
+stack contents as the probed function.  When it is done, the handler
+calls jprobe_return(), which traps again to restore the original stack
+contents and processor state and switch to the probed function.
+
+By convention, the callee owns its arguments, so gcc may produce code
+that unexpectedly modifies that portion of the stack.  This is why
+Kprobes saves a copy of the stack and restores it after the jprobe
+handler has run.  Up to MAX_STACK_SIZE bytes are copied -- e.g.,
+64 bytes on i386.
+
+Note that the probed function's args may be passed on the stack
+or in registers (e.g., for x86_64 or for an i386 fastcall function).
+The jprobe will work in either case, so long as the handler's
+prototype matches that of the probed function.
+
+1.3 How Does a Return Probe Work?
+
+When you call register_kretprobe(), Kprobes establishes a kprobe at
+the entry to the function.  When the probed function is called and this
+probe is hit, Kprobes saves a copy of the return address, and replaces
+the return address with the address of a "trampoline."  The trampoline
+is an arbitrary piece of code -- typically just a nop instruction.
+At boot time, Kprobes registers a kprobe at the trampoline.
+
+When the probed function executes its return instruction, control
+passes to the trampoline and that probe is hit.  Kprobes' trampoline
+handler calls the user-specified handler associated with the kretprobe,
+then sets the saved instruction pointer to the saved return address,
+and that's where execution resumes upon return from the trap.
+
+While the probed function is executing, its return address is
+stored in an object of type kretprobe_instance.  Before calling
+register_kretprobe(), the user sets the maxactive field of the
+kretprobe struct to specify how many instances of the specified
+function can be probed simultaneously.  register_kretprobe()
+pre-allocates the indicated number of kretprobe_instance objects.
+
+For example, if the function is non-recursive and is called with a
+spinlock held, maxactive = 1 should be enough.  If the function is
+non-recursive and can never relinquish the CPU (e.g., via a semaphore
+or preemption), NR_CPUS should be enough.  If maxactive <= 0, it is
+set to a default value.  If CONFIG_PREEMPT is enabled, the default
+is max(10, 2*NR_CPUS).  Otherwise, the default is NR_CPUS.
+
+It's not a disaster if you set maxactive too low; you'll just miss
+some probes.  In the kretprobe struct, the nmissed field is set to
+zero when the return probe is registered, and is incremented every
+time the probed function is entered but there is no kretprobe_instance
+object available for establishing the return probe.
+
+2. Architectures Supported
+
+Kprobes, jprobes, and return probes are implemented on the following
+architectures:
+
+- i386
+- x86_64 (AMD-64, E64MT)
+- ppc64
+- ia64 (Support for probes on certain instruction types is still in progress.)
+- sparc64 (Return probes not yet implemented.)
+
+3. Configuring Kprobes
+
+When configuring the kernel using make menuconfig/xconfig/oldconfig,
+ensure that CONFIG_KPROBES is set to "y".  Under "Kernel hacking",
+look for "Kprobes".  You may have to enable "Kernel debugging"
+(CONFIG_DEBUG_KERNEL) before you can enable Kprobes.
+
+You may also want to ensure that CONFIG_KALLSYMS and perhaps even
+CONFIG_KALLSYMS_ALL are set to "y", since kallsyms_lookup_name()
+is a handy, version-independent way to find a function's address.
+
+If you need to insert a probe in the middle of a function, you may find
+it useful to "Compile the kernel with debug info" (CONFIG_DEBUG_INFO),
+so you can use "objdump -d -l vmlinux" to see the source-to-object
+code mapping.
+
+4. API Reference
+
+The Kprobes API includes a "register" function and an "unregister"
+function for each type of probe.  Here are terse, mini-man-page
+specifications for these functions and the associated probe handlers
+that you'll write.  See the latter half of this document for examples.
+
+4.1 register_kprobe
+
+#include <linux/kprobes.h>
+int register_kprobe(struct kprobe *kp);
+
+Sets a breakpoint at the address kp->addr.  When the breakpoint is
+hit, Kprobes calls kp->pre_handler.  After the probed instruction
+is single-stepped, Kprobe calls kp->post_handler.  If a fault
+occurs during execution of kp->pre_handler or kp->post_handler,
+or during single-stepping of the probed instruction, Kprobes calls
+kp->fault_handler.  Any or all handlers can be NULL.
+
+register_kprobe() returns 0 on success, or a negative errno otherwise.
+
+User's pre-handler (kp->pre_handler):
+#include <linux/kprobes.h>
+#include <linux/ptrace.h>
+int pre_handler(struct kprobe *p, struct pt_regs *regs);
+
+Called with p pointing to the kprobe associated with the breakpoint,
+and regs pointing to the struct containing the registers saved when
+the breakpoint was hit.  Return 0 here unless you're a Kprobes geek.
+
+User's post-handler (kp->post_handler):
+#include <linux/kprobes.h>
+#include <linux/ptrace.h>
+void post_handler(struct kprobe *p, struct pt_regs *regs,
+	unsigned long flags);
+
+p and regs are as described for the pre_handler.  flags always seems
+to be zero.
+
+User's fault-handler (kp->fault_handler):
+#include <linux/kprobes.h>
+#include <linux/ptrace.h>
+int fault_handler(struct kprobe *p, struct pt_regs *regs, int trapnr);
+
+p and regs are as described for the pre_handler.  trapnr is the
+architecture-specific trap number associated with the fault (e.g.,
+on i386, 13 for a general protection fault or 14 for a page fault).
+Returns 1 if it successfully handled the exception.
+
+4.2 register_jprobe
+
+#include <linux/kprobes.h>
+int register_jprobe(struct jprobe *jp)
+
+Sets a breakpoint at the address jp->kp.addr, which must be the address
+of the first instruction of a function.  When the breakpoint is hit,
+Kprobes runs the handler whose address is jp->entry.
+
+The handler should have the same arg list and return type as the probed
+function; and just before it returns, it must call jprobe_return().
+(The handler never actually returns, since jprobe_return() returns
+control to Kprobes.)  If the probed function is declared asmlinkage,
+fastcall, or anything else that affects how args are passed, the
+handler's declaration must match.
+
+register_jprobe() returns 0 on success, or a negative errno otherwise.
+
+4.3 register_kretprobe
+
+#include <linux/kprobes.h>
+int register_kretprobe(struct kretprobe *rp);
+
+Establishes a return probe for the function whose address is
+rp->kp.addr.  When that function returns, Kprobes calls rp->handler.
+You must set rp->maxactive appropriately before you call
+register_kretprobe(); see "How Does a Return Probe Work?" for details.
+
+register_kretprobe() returns 0 on success, or a negative errno
+otherwise.
+
+User's return-probe handler (rp->handler):
+#include <linux/kprobes.h>
+#include <linux/ptrace.h>
+int kretprobe_handler(struct kretprobe_instance *ri, struct pt_regs *regs);
+
+regs is as described for kprobe.pre_handler.  ri points to the
+kretprobe_instance object, of which the following fields may be
+of interest:
+- ret_addr: the return address
+- rp: points to the corresponding kretprobe object
+- task: points to the corresponding task struct
+The handler's return value is currently ignored.
+
+4.4 unregister_*probe
+
+#include <linux/kprobes.h>
+void unregister_kprobe(struct kprobe *kp);
+void unregister_jprobe(struct jprobe *jp);
+void unregister_kretprobe(struct kretprobe *rp);
+
+Removes the specified probe.  The unregister function can be called
+at any time after the probe has been registered.
+
+5. Kprobes Features and Limitations
+
+As of Linux v2.6.12, Kprobes allows multiple probes at the same
+address.  Currently, however, there cannot be multiple jprobes on
+the same function at the same time.
+
+In general, you can install a probe anywhere in the kernel.
+In particular, you can probe interrupt handlers.  Known exceptions
+are discussed in this section.
+
+For obvious reasons, it's a bad idea to install a probe in
+the code that implements Kprobes (mostly kernel/kprobes.c and
+arch/*/kernel/kprobes.c).  A patch in the v2.6.13 timeframe instructs
+Kprobes to reject such requests.
+
+If you install a probe in an inline-able function, Kprobes makes
+no attempt to chase down all inline instances of the function and
+install probes there.  gcc may inline a function without being asked,
+so keep this in mind if you're not seeing the probe hits you expect.
+
+A probe handler can modify the environment of the probed function
+-- e.g., by modifying kernel data structures, or by modifying the
+contents of the pt_regs struct (which are restored to the registers
+upon return from the breakpoint).  So Kprobes can be used, for example,
+to install a bug fix or to inject faults for testing.  Kprobes, of
+course, has no way to distinguish the deliberately injected faults
+from the accidental ones.  Don't drink and probe.
+
+Kprobes makes no attempt to prevent probe handlers from stepping on
+each other -- e.g., probing printk() and then calling printk() from a
+probe handler.  As of Linux v2.6.12, if a probe handler hits a probe,
+that second probe's handlers won't be run in that instance.
+
+In Linux v2.6.12 and previous versions, Kprobes' data structures are
+protected by a single lock that is held during probe registration and
+unregistration and while handlers are run.  Thus, no two handlers
+can run simultaneously.  To improve scalability on SMP systems,
+this restriction will probably be removed soon, in which case
+multiple handlers (or multiple instances of the same handler) may
+run concurrently on different CPUs.  Code your handlers accordingly.
+
+Kprobes does not use semaphores or allocate memory except during
+registration and unregistration.
+
+Probe handlers are run with preemption disabled.  Depending on the
+architecture, handlers may also run with interrupts disabled.  In any
+case, your handler should not yield the CPU (e.g., by attempting to
+acquire a semaphore).
+
+Since a return probe is implemented by replacing the return
+address with the trampoline's address, stack backtraces and calls
+to __builtin_return_address() will typically yield the trampoline's
+address instead of the real return address for kretprobed functions.
+(As far as we can tell, __builtin_return_address() is used only
+for instrumentation and error reporting.)
+
+If the number of times a function is called does not match the
+number of times it returns, registering a return probe on that
+function may produce undesirable results.  We have the do_exit()
+and do_execve() cases covered.  do_fork() is not an issue.  We're
+unaware of other specific cases where this could be a problem.
+
+6. Probe Overhead
+
+On a typical CPU in use in 2005, a kprobe hit takes 0.5 to 1.0
+microseconds to process.  Specifically, a benchmark that hits the same
+probepoint repeatedly, firing a simple handler each time, reports 1-2
+million hits per second, depending on the architecture.  A jprobe or
+return-probe hit typically takes 50-75% longer than a kprobe hit.
+When you have a return probe set on a function, adding a kprobe at
+the entry to that function adds essentially no overhead.
+
+Here are sample overhead figures (in usec) for different architectures.
+k = kprobe; j = jprobe; r = return probe; kr = kprobe + return probe
+on same function; jr = jprobe + return probe on same function
+
+i386: Intel Pentium M, 1495 MHz, 2957.31 bogomips
+k = 0.57 usec; j = 1.00; r = 0.92; kr = 0.99; jr = 1.40
+
+x86_64: AMD Opteron 246, 1994 MHz, 3971.48 bogomips
+k = 0.49 usec; j = 0.76; r = 0.80; kr = 0.82; jr = 1.07
+
+ppc64: POWER5 (gr), 1656 MHz (SMT disabled, 1 virtual CPU per physical CPU)
+k = 0.77 usec; j = 1.31; r = 1.26; kr = 1.45; jr = 1.99
+
+7. TODO
+
+a. SystemTap (http://sourceware.org/systemtap): Work in progress
+to provide a simplified programming interface for probe-based
+instrumentation.
+b. Improved SMP scalability: Currently, work is in progress to handle
+multiple kprobes in parallel.
+c. Kernel return probes for sparc64.
+d. Support for other architectures.
+e. User-space probes.
+
+8. Kprobes Example
+
+Here's a sample kernel module showing the use of kprobes to dump a
+stack trace and selected i386 registers when do_fork() is called.
+----- cut here -----
+/*kprobe_example.c*/
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/kprobes.h>
+#include <linux/kallsyms.h>
+#include <linux/sched.h>
+
+/*For each probe you need to allocate a kprobe structure*/
+static struct kprobe kp;
+
+/*kprobe pre_handler: called just before the probed instruction is executed*/
+int handler_pre(struct kprobe *p, struct pt_regs *regs)
+{
+	printk("pre_handler: p->addr=0x%p, eip=%lx, eflags=0x%lx\n",
+		p->addr, regs->eip, regs->eflags);
+	dump_stack();
+	return 0;
+}
+
+/*kprobe post_handler: called after the probed instruction is executed*/
+void handler_post(struct kprobe *p, struct pt_regs *regs, unsigned long flags)
+{
+	printk("post_handler: p->addr=0x%p, eflags=0x%lx\n",
+		p->addr, regs->eflags);
+}
+
+/* fault_handler: this is called if an exception is generated for any
+ * instruction within the pre- or post-handler, or when Kprobes
+ * single-steps the probed instruction.
+ */
+int handler_fault(struct kprobe *p, struct pt_regs *regs, int trapnr)
+{
+	printk("fault_handler: p->addr=0x%p, trap #%dn",
+		p->addr, trapnr);
+	/* Return 0 because we don't handle the fault. */
+	return 0;
+}
+
+int init_module(void)
+{
+	int ret;
+	kp.pre_handler = handler_pre;
+	kp.post_handler = handler_post;
+	kp.fault_handler = handler_fault;
+	kp.addr = (kprobe_opcode_t*) kallsyms_lookup_name("do_fork");
+	/* register the kprobe now */
+	if (!kp.addr) {
+		printk("Couldn't find %s to plant kprobe\n", "do_fork");
+		return -1;
+	}
+	if ((ret = register_kprobe(&kp) < 0)) {
+		printk("register_kprobe failed, returned %d\n", ret);
+		return -1;
+	}
+	printk("kprobe registered\n");
+	return 0;
+}
+
+void cleanup_module(void)
+{
+	unregister_kprobe(&kp);
+	printk("kprobe unregistered\n");
+}
+
+MODULE_LICENSE("GPL");
+----- cut here -----
+
+You can build the kernel module, kprobe-example.ko, using the following
+Makefile:
+----- cut here -----
+obj-m := kprobe-example.o
+KDIR := /lib/modules/$(shell uname -r)/build
+PWD := $(shell pwd)
+default:
+	$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
+clean:
+	rm -f *.mod.c *.ko *.o
+----- cut here -----
+
+$ make
+$ su -
+...
+# insmod kprobe-example.ko
+
+You will see the trace data in /var/log/messages and on the console
+whenever do_fork() is invoked to create a new process.
+
+9. Jprobes Example
+
+Here's a sample kernel module showing the use of jprobes to dump
+the arguments of do_fork().
+----- cut here -----
+/*jprobe-example.c */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/uio.h>
+#include <linux/kprobes.h>
+#include <linux/kallsyms.h>
+
+/*
+ * Jumper probe for do_fork.
+ * Mirror principle enables access to arguments of the probed routine
+ * from the probe handler.
+ */
+
+/* Proxy routine having the same arguments as actual do_fork() routine */
+long jdo_fork(unsigned long clone_flags, unsigned long stack_start,
+	      struct pt_regs *regs, unsigned long stack_size,
+	      int __user * parent_tidptr, int __user * child_tidptr)
+{
+	printk("jprobe: clone_flags=0x%lx, stack_size=0x%lx, regs=0x%p\n",
+	       clone_flags, stack_size, regs);
+	/* Always end with a call to jprobe_return(). */
+	jprobe_return();
+	/*NOTREACHED*/
+	return 0;
+}
+
+static struct jprobe my_jprobe = {
+	.entry = (kprobe_opcode_t *) jdo_fork
+};
+
+int init_module(void)
+{
+	int ret;
+	my_jprobe.kp.addr = (kprobe_opcode_t *) kallsyms_lookup_name("do_fork");
+	if (!my_jprobe.kp.addr) {
+		printk("Couldn't find %s to plant jprobe\n", "do_fork");
+		return -1;
+	}
+
+	if ((ret = register_jprobe(&my_jprobe)) <0) {
+		printk("register_jprobe failed, returned %d\n", ret);
+		return -1;
+	}
+	printk("Planted jprobe at %p, handler addr %p\n",
+	       my_jprobe.kp.addr, my_jprobe.entry);
+	return 0;
+}
+
+void cleanup_module(void)
+{
+	unregister_jprobe(&my_jprobe);
+	printk("jprobe unregistered\n");
+}
+
+MODULE_LICENSE("GPL");
+----- cut here -----
+
+Build and insert the kernel module as shown in the above kprobe
+example.  You will see the trace data in /var/log/messages and on
+the console whenever do_fork() is invoked to create a new process.
+(Some messages may be suppressed if syslogd is configured to
+eliminate duplicate messages.)
+
+10. Kretprobes Example
+
+Here's a sample kernel module showing the use of return probes to
+report failed calls to sys_open().
+----- cut here -----
+/*kretprobe-example.c*/
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/kprobes.h>
+#include <linux/kallsyms.h>
+
+static const char *probed_func = "sys_open";
+
+/* Return-probe handler: If the probed function fails, log the return value. */
+static int ret_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
+{
+	// Substitute the appropriate register name for your architecture --
+	// e.g., regs->rax for x86_64, regs->gpr[3] for ppc64.
+	int retval = (int) regs->eax;
+	if (retval < 0) {
+		printk("%s returns %d\n", probed_func, retval);
+	}
+	return 0;
+}
+
+static struct kretprobe my_kretprobe = {
+	.handler = ret_handler,
+	/* Probe up to 20 instances concurrently. */
+	.maxactive = 20
+};
+
+int init_module(void)
+{
+	int ret;
+	my_kretprobe.kp.addr =
+		(kprobe_opcode_t *) kallsyms_lookup_name(probed_func);
+	if (!my_kretprobe.kp.addr) {
+		printk("Couldn't find %s to plant return probe\n", probed_func);
+		return -1;
+	}
+	if ((ret = register_kretprobe(&my_kretprobe)) < 0) {
+		printk("register_kretprobe failed, returned %d\n", ret);
+		return -1;
+	}
+	printk("Planted return probe at %p\n", my_kretprobe.kp.addr);
+	return 0;
+}
+
+void cleanup_module(void)
+{
+	unregister_kretprobe(&my_kretprobe);
+	printk("kretprobe unregistered\n");
+	/* nmissed > 0 suggests that maxactive was set too low. */
+	printk("Missed probing %d instances of %s\n",
+		my_kretprobe.nmissed, probed_func);
+}
+
+MODULE_LICENSE("GPL");
+----- cut here -----
+
+Build and insert the kernel module as shown in the above kprobe
+example.  You will see the trace data in /var/log/messages and on the
+console whenever sys_open() returns a negative value.  (Some messages
+may be suppressed if syslogd is configured to eliminate duplicate
+messages.)
+
+For additional information on Kprobes, refer to the following URLs:
+http://www-106.ibm.com/developerworks/library/l-kprobes.html?ca=dgr-lnxw42Kprobe
+http://www.redhat.com/magazine/005mar05/features/kprobes/
diff --git a/Documentation/networking/00-INDEX b/Documentation/networking/00-INDEX
--- a/Documentation/networking/00-INDEX
+++ b/Documentation/networking/00-INDEX
@@ -114,9 +114,7 @@ tuntap.txt
 vortex.txt
 	- info on using 3Com Vortex (3c590, 3c592, 3c595, 3c597) Ethernet cards.
 wan-router.txt
-	- Wan router documentation
-wanpipe.txt
-	- WANPIPE(tm) Multiprotocol WAN Driver for Linux WAN Router
+	- WAN router documentation
 wavelan.txt
 	- AT&T GIS (nee NCR) WaveLAN card: An Ethernet-like radio transceiver
 x25.txt
diff --git a/Documentation/networking/bonding.txt b/Documentation/networking/bonding.txt
--- a/Documentation/networking/bonding.txt
+++ b/Documentation/networking/bonding.txt
@@ -1,5 +1,7 @@
 
-                   Linux Ethernet Bonding Driver HOWTO
+		Linux Ethernet Bonding Driver HOWTO
+
+		Latest update: 21 June 2005
 
 Initial release : Thomas Davis <tadavis at lbl.gov>
 Corrections, HA extensions : 2000/10/03-15 :
@@ -11,15 +13,22 @@ Corrections, HA extensions : 2000/10/03-
 
 Reorganized and updated Feb 2005 by Jay Vosburgh
 
-Note :
-------
+Introduction
+============
+
+	The Linux bonding driver provides a method for aggregating
+multiple network interfaces into a single logical "bonded" interface.
+The behavior of the bonded interfaces depends upon the mode; generally
+speaking, modes provide either hot standby or load balancing services.
+Additionally, link integrity monitoring may be performed.
 	
-The bonding driver originally came from Donald Becker's beowulf patches for
-kernel 2.0. It has changed quite a bit since, and the original tools from
-extreme-linux and beowulf sites will not work with this version of the driver.
+	The bonding driver originally came from Donald Becker's
+beowulf patches for kernel 2.0. It has changed quite a bit since, and
+the original tools from extreme-linux and beowulf sites will not work
+with this version of the driver.
 
-For new versions of the driver, patches for older kernels and the updated
-userspace tools, please follow the links at the end of this file.
+	For new versions of the driver, updated userspace tools, and
+who to ask for help, please follow the links at the end of this file.
 
 Table of Contents
 =================
@@ -30,9 +39,13 @@ Table of Contents
 
 3. Configuring Bonding Devices
 3.1	Configuration with sysconfig support
+3.1.1		Using DHCP with sysconfig
+3.1.2		Configuring Multiple Bonds with sysconfig
 3.2	Configuration with initscripts support
+3.2.1		Using DHCP with initscripts
+3.2.2		Configuring Multiple Bonds with initscripts
 3.3	Configuring Bonding Manually
-3.4	Configuring Multiple Bonds
+3.3.1		Configuring Multiple Bonds Manually
 
 5. Querying Bonding Configuration
 5.1	Bonding Configuration
@@ -56,21 +69,30 @@ Table of Contents
 
 11. Promiscuous mode
 
-12. High Availability Information
+12. Configuring Bonding for High Availability
 12.1	High Availability in a Single Switch Topology
-12.1.1		Bonding Mode Selection for Single Switch Topology
-12.1.2		Link Monitoring for Single Switch Topology
 12.2	High Availability in a Multiple Switch Topology
-12.2.1		Bonding Mode Selection for Multiple Switch Topology
-12.2.2		Link Monitoring for Multiple Switch Topology
-12.3	Switch Behavior Issues for High Availability
+12.2.1		HA Bonding Mode Selection for Multiple Switch Topology
+12.2.2		HA Link Monitoring for Multiple Switch Topology
+
+13. Configuring Bonding for Maximum Throughput
+13.1	Maximum Throughput in a Single Switch Topology
+13.1.1		MT Bonding Mode Selection for Single Switch Topology
+13.1.2		MT Link Monitoring for Single Switch Topology
+13.2	Maximum Throughput in a Multiple Switch Topology
+13.2.1		MT Bonding Mode Selection for Multiple Switch Topology
+13.2.2		MT Link Monitoring for Multiple Switch Topology
+
+14. Switch Behavior Issues
+14.1	Link Establishment and Failover Delays
+14.2	Duplicated Incoming Packets
 
-13. Hardware Specific Considerations
-13.1	IBM BladeCenter
+15. Hardware Specific Considerations
+15.1	IBM BladeCenter
 
-14. Frequently Asked Questions
+16. Frequently Asked Questions
 
-15. Resources and Links
+17. Resources and Links
 
 
 1. Bonding Driver Installation
@@ -86,16 +108,10 @@ the following steps:
 1.1 Configure and build the kernel with bonding
 -----------------------------------------------
 
-	The latest version of the bonding driver is available in the
+	The current version of the bonding driver is available in the
 drivers/net/bonding subdirectory of the most recent kernel source
-(which is available on http://kernel.org).
-
-	Prior to the 2.4.11 kernel, the bonding driver was maintained
-largely outside the kernel tree; patches for some earlier kernels are
-available on the bonding sourceforge site, although those patches are
-still several years out of date.  Most users will want to use either
-the most recent kernel from kernel.org or whatever kernel came with
-their distro.
+(which is available on http://kernel.org).  Most users "rolling their
+own" will want to use the most recent kernel from kernel.org.
 
 	Configure kernel with "make menuconfig" (or "make xconfig" or
 "make config"), then select "Bonding driver support" in the "Network
@@ -103,8 +119,8 @@ device support" section.  It is recommen
 driver as module since it is currently the only way to pass parameters
 to the driver or configure more than one bonding device.
 
-	Build and install the new kernel and modules, then proceed to
-step 2.
+	Build and install the new kernel and modules, then continue
+below to install ifenslave.
 
 1.2 Install ifenslave Control Utility
 -------------------------------------
@@ -147,9 +163,9 @@ default kernel source include directory.
 	Options for the bonding driver are supplied as parameters to
 the bonding module at load time.  They may be given as command line
 arguments to the insmod or modprobe command, but are usually specified
-in either the /etc/modprobe.conf configuration file, or in a
-distro-specific configuration file (some of which are detailed in the
-next section).
+in either the /etc/modules.conf or /etc/modprobe.conf configuration
+file, or in a distro-specific configuration file (some of which are
+detailed in the next section).
 
 	The available bonding driver parameters are listed below. If a
 parameter is not specified the default value is used.  When initially
@@ -162,34 +178,34 @@ degradation will occur during link failu
 support at least miimon, so there is really no reason not to use it.
 
 	Options with textual values will accept either the text name
-	or, for backwards compatibility, the option value.  E.g.,
-	"mode=802.3ad" and "mode=4" set the same mode.
+or, for backwards compatibility, the option value.  E.g.,
+"mode=802.3ad" and "mode=4" set the same mode.
 
 	The parameters are as follows:
 
 arp_interval
 
-	Specifies the ARP monitoring frequency in milli-seconds. If
-	ARP monitoring is used in a load-balancing mode (mode 0 or 2),
-	the switch should be configured in a mode that evenly
-	distributes packets across all links - such as round-robin. If
-	the switch is configured to distribute the packets in an XOR
+	Specifies the ARP link monitoring frequency in milliseconds.
+	If ARP monitoring is used in an etherchannel compatible mode
+	(modes 0 and 2), the switch should be configured in a mode
+	that evenly distributes packets across all links. If the
+	switch is configured to distribute the packets in an XOR
 	fashion, all replies from the ARP targets will be received on
 	the same link which could cause the other team members to
-	fail. ARP monitoring should not be used in conjunction with
-	miimon. A value of 0 disables ARP monitoring. The default
+	fail.  ARP monitoring should not be used in conjunction with
+	miimon.  A value of 0 disables ARP monitoring.  The default
 	value is 0.
 
 arp_ip_target
 
-	Specifies the ip addresses to use when arp_interval is > 0.
-	These are the targets of the ARP request sent to determine the
-	health of the link to the targets.  Specify these values in
-	ddd.ddd.ddd.ddd format.  Multiple ip adresses must be
-	seperated by a comma.  At least one IP address must be given
-	for ARP monitoring to function.  The maximum number of targets
-	that can be specified is 16.  The default value is no IP
-	addresses.
+	Specifies the IP addresses to use as ARP monitoring peers when
+	arp_interval is > 0.  These are the targets of the ARP request
+	sent to determine the health of the link to the targets.
+	Specify these values in ddd.ddd.ddd.ddd format.  Multiple IP
+	addresses must be separated by a comma.  At least one IP
+	address must be given for ARP monitoring to function.  The
+	maximum number of targets that can be specified is 16.  The
+	default value is no IP addresses.
 
 downdelay
 
@@ -207,11 +223,13 @@ lacp_rate
 	are:
 
 	slow or 0
-		Request partner to transmit LACPDUs every 30 seconds (default)
+		Request partner to transmit LACPDUs every 30 seconds
 
 	fast or 1
 		Request partner to transmit LACPDUs every 1 second
 
+	The default is slow.
+
 max_bonds
 
 	Specifies the number of bonding devices to create for this
@@ -221,10 +239,11 @@ max_bonds
 
 miimon
 
-	Specifies the frequency in milli-seconds that MII link
-	monitoring will occur.  A value of zero disables MII link
-	monitoring.  A value of 100 is a good starting point.  The
-	use_carrier option, below, affects how the link state is
+	Specifies the MII link monitoring frequency in milliseconds.
+	This determines how often the link state of each slave is
+	inspected for link failures.  A value of zero disables MII
+	link monitoring.  A value of 100 is a good starting point.
+	The use_carrier option, below, affects how the link state is
 	determined.  See the High Availability section for additional
 	information.  The default value is 0.
 
@@ -246,17 +265,31 @@ mode
 		active.  A different slave becomes active if, and only
 		if, the active slave fails.  The bond's MAC address is
 		externally visible on only one port (network adapter)
-		to avoid confusing the switch.  This mode provides
-		fault tolerance.  The primary option affects the
-		behavior of this mode.
+		to avoid confusing the switch.
+
+		In bonding version 2.6.2 or later, when a failover
+		occurs in active-backup mode, bonding will issue one
+		or more gratuitous ARPs on the newly active slave.
+		One gratutious ARP is issued for the bonding master
+		interface and each VLAN interfaces configured above
+		it, provided that the interface has at least one IP
+		address configured.  Gratuitous ARPs issued for VLAN
+		interfaces are tagged with the appropriate VLAN id.
+
+		This mode provides fault tolerance.  The primary
+		option, documented below, affects the behavior of this
+		mode.
 
 	balance-xor or 2
 
-		XOR policy: Transmit based on [(source MAC address
-		XOR'd with destination MAC address) modulo slave
-		count].  This selects the same slave for each
-		destination MAC address.  This mode provides load
-		balancing and fault tolerance.
+		XOR policy: Transmit based on the selected transmit
+		hash policy.  The default policy is a simple [(source
+		MAC address XOR'd with destination MAC address) modulo
+		slave count].  Alternate transmit policies may be
+		selected via the xmit_hash_policy option, described
+		below.
+
+		This mode provides load balancing and fault tolerance.
 
 	broadcast or 3
 
@@ -270,7 +303,17 @@ mode
 		duplex settings.  Utilizes all slaves in the active
 		aggregator according to the 802.3ad specification.
 
-		Pre-requisites:
+		Slave selection for outgoing traffic is done according
+		to the transmit hash policy, which may be changed from
+		the default simple XOR policy via the xmit_hash_policy
+		option, documented below.  Note that not all transmit
+		policies may be 802.3ad compliant, particularly in
+		regards to the packet mis-ordering requirements of
+		section 43.2.4 of the 802.3ad standard.  Differing
+		peer implementations will have varying tolerances for
+		noncompliance.
+
+		Prerequisites:
 
 		1. Ethtool support in the base drivers for retrieving
 		the speed and duplex of each slave.
@@ -333,7 +376,7 @@ mode
 
 		When a link is reconnected or a new slave joins the
 		bond the receive traffic is redistributed among all
-		active slaves in the bond by intiating ARP Replies
+		active slaves in the bond by initiating ARP Replies
 		with the selected mac address to each of the
 		clients. The updelay parameter (detailed below) must
 		be set to a value equal or greater than the switch's
@@ -396,6 +439,60 @@ use_carrier
 	0 will use the deprecated MII / ETHTOOL ioctls.  The default
 	value is 1.
 
+xmit_hash_policy
+
+	Selects the transmit hash policy to use for slave selection in
+	balance-xor and 802.3ad modes.  Possible values are:
+
+	layer2
+
+		Uses XOR of hardware MAC addresses to generate the
+		hash.  The formula is
+
+		(source MAC XOR destination MAC) modulo slave count
+
+		This algorithm will place all traffic to a particular
+		network peer on the same slave.
+
+		This algorithm is 802.3ad compliant.
+
+	layer3+4
+
+		This policy uses upper layer protocol information,
+		when available, to generate the hash.  This allows for
+		traffic to a particular network peer to span multiple
+		slaves, although a single connection will not span
+		multiple slaves.
+
+		The formula for unfragmented TCP and UDP packets is
+
+		((source port XOR dest port) XOR
+			 ((source IP XOR dest IP) AND 0xffff)
+				modulo slave count
+
+		For fragmented TCP or UDP packets and all other IP
+		protocol traffic, the source and destination port
+		information is omitted.  For non-IP traffic, the
+		formula is the same as for the layer2 transmit hash
+		policy.
+
+		This policy is intended to mimic the behavior of
+		certain switches, notably Cisco switches with PFC2 as
+		well as some Foundry and IBM products.
+
+		This algorithm is not fully 802.3ad compliant.  A
+		single TCP or UDP conversation containing both
+		fragmented and unfragmented packets will see packets
+		striped across two interfaces.  This may result in out
+		of order delivery.  Most traffic types will not meet
+		this criteria, as TCP rarely fragments traffic, and
+		most UDP traffic is not involved in extended
+		conversations.  Other implementations of 802.3ad may
+		or may not tolerate this noncompliance.
+
+	The default value is layer2.  This option was added in bonding
+version 2.6.3.  In earlier versions of bonding, this parameter does
+not exist, and the layer2 policy is the only policy.
 
 
 3. Configuring Bonding Devices
@@ -448,8 +545,9 @@ Bonding devices can be managed by hand, 
 slave devices.  On SLES 9, this is most easily done by running the
 yast2 sysconfig configuration utility.  The goal is for to create an
 ifcfg-id file for each slave device.  The simplest way to accomplish
-this is to configure the devices for DHCP.  The name of the
-configuration file for each device will be of the form:
+this is to configure the devices for DHCP (this is only to get the
+file ifcfg-id file created; see below for some issues with DHCP).  The
+name of the configuration file for each device will be of the form:
 
 ifcfg-id-xx:xx:xx:xx:xx:xx
 
@@ -459,7 +557,7 @@ the device's permanent MAC address.
 	Once the set of ifcfg-id-xx:xx:xx:xx:xx:xx files has been
 created, it is necessary to edit the configuration files for the slave
 devices (the MAC addresses correspond to those of the slave devices).
-Before editing, the file will contain muliple lines, and will look
+Before editing, the file will contain multiple lines, and will look
 something like this:
 
 BOOTPROTO='dhcp'
@@ -496,16 +594,11 @@ STARTMODE="onboot"
 BONDING_MASTER="yes"
 BONDING_MODULE_OPTS="mode=active-backup miimon=100"
 BONDING_SLAVE0="eth0"
-BONDING_SLAVE1="eth1"
+BONDING_SLAVE1="bus-pci-0000:06:08.1"
 
 	Replace the sample BROADCAST, IPADDR, NETMASK and NETWORK
 values with the appropriate values for your network.
 
-	Note that configuring the bonding device with BOOTPROTO='dhcp'
-does not work; the scripts attempt to obtain the device address from
-DHCP prior to adding any of the slave devices.  Without active slaves,
-the DHCP requests are not sent to the network.
-
 	The STARTMODE specifies when the device is brought online.
 The possible values are:
 
@@ -531,9 +624,17 @@ for the bonding mode, link monitoring, a
 the max_bonds bonding parameter; this will confuse the configuration
 system if you have multiple bonding devices.
 
-	Finally, supply one BONDING_SLAVEn="ethX" for each slave,
-where "n" is an increasing value, one for each slave, and "ethX" is
-the name of the slave device (eth0, eth1, etc).
+	Finally, supply one BONDING_SLAVEn="slave device" for each
+slave.  where "n" is an increasing value, one for each slave.  The
+"slave device" is either an interface name, e.g., "eth0", or a device
+specifier for the network device.  The interface name is easier to
+find, but the ethN names are subject to change at boot time if, e.g.,
+a device early in the sequence has failed.  The device specifiers
+(bus-pci-0000:06:08.1 in the example above) specify the physical
+network device, and will not change unless the device's bus location
+changes (for example, it is moved from one PCI slot to another).  The
+example above uses one of each type for demonstration purposes; most
+configurations will choose one or the other for all slave devices.
 
 	When all configuration files have been modified or created,
 networking must be restarted for the configuration changes to take
@@ -544,7 +645,7 @@ effect.  This can be accomplished via th
 	Note that the network control script (/sbin/ifdown) will
 remove the bonding module as part of the network shutdown processing,
 so it is not necessary to remove the module by hand if, e.g., the
-module paramters have changed.
+module parameters have changed.
 
 	Also, at this writing, YaST/YaST2 will not manage bonding
 devices (they do not show bonding interfaces on its list of network
@@ -559,12 +660,37 @@ format can be found in an example ifcfg 
 	Note that the template does not document the various BONDING_
 settings described above, but does describe many of the other options.
 
+3.1.1 Using DHCP with sysconfig
+-------------------------------
+
+	Under sysconfig, configuring a device with BOOTPROTO='dhcp'
+will cause it to query DHCP for its IP address information.  At this
+writing, this does not function for bonding devices; the scripts
+attempt to obtain the device address from DHCP prior to adding any of
+the slave devices.  Without active slaves, the DHCP requests are not
+sent to the network.
+
+3.1.2 Configuring Multiple Bonds with sysconfig
+-----------------------------------------------
+
+	The sysconfig network initialization system is capable of
+handling multiple bonding devices.  All that is necessary is for each
+bonding instance to have an appropriately configured ifcfg-bondX file
+(as described above).  Do not specify the "max_bonds" parameter to any
+instance of bonding, as this will confuse sysconfig.  If you require
+multiple bonding devices with identical parameters, create multiple
+ifcfg-bondX files.
+
+	Because the sysconfig scripts supply the bonding module
+options in the ifcfg-bondX file, it is not necessary to add them to
+the system /etc/modules.conf or /etc/modprobe.conf configuration file.
+
 3.2 Configuration with initscripts support
 ------------------------------------------
 
 	This section applies to distros using a version of initscripts
 with bonding support, for example, Red Hat Linux 9 or Red Hat
-Enterprise Linux version 3.  On these systems, the network
+Enterprise Linux version 3 or 4.  On these systems, the network
 initialization scripts have some knowledge of bonding, and can be
 configured to control bonding devices.
 
@@ -614,10 +740,11 @@ USERCTL=no
 	Be sure to change the networking specific lines (IPADDR,
 NETMASK, NETWORK and BROADCAST) to match your network configuration.
 
-	Finally, it is necessary to edit /etc/modules.conf to load the
-bonding module when the bond0 interface is brought up.  The following
-sample lines in /etc/modules.conf will load the bonding module, and
-select its options:
+	Finally, it is necessary to edit /etc/modules.conf (or
+/etc/modprobe.conf, depending upon your distro) to load the bonding
+module with your desired options when the bond0 interface is brought
+up.  The following lines in /etc/modules.conf (or modprobe.conf) will
+load the bonding module, and select its options:
 
 alias bond0 bonding
 options bond0 mode=balance-alb miimon=100
@@ -629,6 +756,33 @@ options for your configuration.
 will restart the networking subsystem and your bond link should be now
 up and running.
 
+3.2.1 Using DHCP with initscripts
+---------------------------------
+
+	Recent versions of initscripts (the version supplied with
+Fedora Core 3 and Red Hat Enterprise Linux 4 is reported to work) do
+have support for assigning IP information to bonding devices via DHCP.
+
+	To configure bonding for DHCP, configure it as described
+above, except replace the line "BOOTPROTO=none" with "BOOTPROTO=dhcp"
+and add a line consisting of "TYPE=Bonding".  Note that the TYPE value
+is case sensitive.
+
+3.2.2 Configuring Multiple Bonds with initscripts
+-------------------------------------------------
+
+	At this writing, the initscripts package does not directly
+support loading the bonding driver multiple times, so the process for
+doing so is the same as described in the "Configuring Multiple Bonds
+Manually" section, below.
+
+	NOTE: It has been observed that some Red Hat supplied kernels
+are apparently unable to rename modules at load time (the "-obonding1"
+part).  Attempts to pass that option to modprobe will produce an
+"Operation not permitted" error.  This has been reported on some
+Fedora Core kernels, and has been seen on RHEL 4 as well.  On kernels
+exhibiting this problem, it will be impossible to configure multiple
+bonds with differing parameters.
 
 3.3 Configuring Bonding Manually
 --------------------------------
@@ -638,10 +792,11 @@ scripts (the sysconfig or initscripts pa
 knowledge of bonding.  One such distro is SuSE Linux Enterprise Server
 version 8.
 
-	The general methodology for these systems is to place the
-bonding module parameters into /etc/modprobe.conf, then add modprobe
-and/or ifenslave commands to the system's global init script.  The
-name of the global init script differs; for sysconfig, it is
+	The general method for these systems is to place the bonding
+module parameters into /etc/modules.conf or /etc/modprobe.conf (as
+appropriate for the installed distro), then add modprobe and/or
+ifenslave commands to the system's global init script.  The name of
+the global init script differs; for sysconfig, it is
 /etc/init.d/boot.local and for initscripts it is /etc/rc.d/rc.local.
 
 	For example, if you wanted to make a simple bond of two e100
@@ -649,7 +804,7 @@ devices (presumed to be eth0 and eth1), 
 reboots, edit the appropriate file (/etc/init.d/boot.local or
 /etc/rc.d/rc.local), and add the following:
 
-modprobe bonding -obond0 mode=balance-alb miimon=100
+modprobe bonding mode=balance-alb miimon=100
 modprobe e100
 ifconfig bond0 192.168.1.1 netmask 255.255.255.0 up
 ifenslave bond0 eth0
@@ -657,11 +812,7 @@ ifenslave bond0 eth1
 
 	Replace the example bonding module parameters and bond0
 network configuration (IP address, netmask, etc) with the appropriate
-values for your configuration.  The above example loads the bonding
-module with the name "bond0," this simplifies the naming if multiple
-bonding modules are loaded (each successive instance of the module is
-given a different name, and the module instance names match the
-bonding interface names).
+values for your configuration.
 
 	Unfortunately, this method will not provide support for the
 ifup and ifdown scripts on the bond devices.  To reload the bonding
@@ -684,20 +835,23 @@ appropriate device driver modules.  For 
 the following:
 
 # ifconfig bond0 down
-# rmmod bond0
+# rmmod bonding
 # rmmod e100
 
 	Again, for convenience, it may be desirable to create a script
 with these commands.
 
 
-3.4 Configuring Multiple Bonds
-------------------------------
+3.3.1 Configuring Multiple Bonds Manually
+-----------------------------------------
 
 	This section contains information on configuring multiple
-bonding devices with differing options.  If you require multiple
-bonding devices, but all with the same options, see the "max_bonds"
-module paramter, documented above.
+bonding devices with differing options for those systems whose network
+initialization scripts lack support for configuring multiple bonds.
+
+	If you require multiple bonding devices, but all with the same
+options, you may wish to use the "max_bonds" module parameter,
+documented above.
 
 	To create multiple bonding devices with differing options, it
 is necessary to load the bonding driver multiple times.  Note that
@@ -724,11 +878,16 @@ named "bond0" and creates the bond0 devi
 miimon of 100.  The second instance is named "bond1" and creates the
 bond1 device in balance-alb mode with an miimon of 50.
 
+	In some circumstances (typically with older distributions),
+the above does not work, and the second bonding instance never sees
+its options.  In that case, the second options line can be substituted
+as follows:
+
+install bonding1 /sbin/modprobe bonding -obond1 mode=balance-alb miimon=50
+
 	This may be repeated any number of times, specifying a new and
-unique name in place of bond0 or bond1 for each instance.
+unique name in place of bond1 for each subsequent instance.
 
-	When the appropriate module paramters are in place, then
-configure bonding according to the instructions for your distro.
 
 5. Querying Bonding Configuration 
 =================================
@@ -846,8 +1005,8 @@ tagged internally by bonding itself.  As
 self generated packets.
 
 	For reasons of simplicity, and to support the use of adapters
-that can do VLAN hardware acceleration offloding, the bonding
-interface declares itself as fully hardware offloaing capable, it gets
+that can do VLAN hardware acceleration offloading, the bonding
+interface declares itself as fully hardware offloading capable, it gets
 the add_vid/kill_vid notifications to gather the necessary
 information, and it propagates those actions to the slaves.  In case
 of mixed adapter types, hardware accelerated tagged packets that
@@ -880,7 +1039,7 @@ bond interface:
 matches the hardware address of the VLAN interfaces.
 
 	Note that changing a VLAN interface's HW address would set the
-underlying device -- i.e. the bonding interface -- to promiscouos
+underlying device -- i.e. the bonding interface -- to promiscuous
 mode, which might not be what you want.
 
 
@@ -923,7 +1082,7 @@ down or have a problem making it unrespo
 an additional target (or several) increases the reliability of the ARP
 monitoring.
 
-	Multiple ARP targets must be seperated by commas as follows:
+	Multiple ARP targets must be separated by commas as follows:
 
 # example options for ARP monitoring with three targets
 alias bond0 bonding
@@ -1045,7 +1204,7 @@ install bonding /sbin/modprobe tg3; /sbi
 	This will, when loading the bonding module, rather than
 performing the normal action, instead execute the provided command.
 This command loads the device drivers in the order needed, then calls
-modprobe with --ingore-install to cause the normal action to then take
+modprobe with --ignore-install to cause the normal action to then take
 place.  Full documentation on this can be found in the modprobe.conf
 and modprobe manual pages.
 
@@ -1130,14 +1289,14 @@ association.
 common to enable promiscuous mode on the device, so that all traffic
 is seen (instead of seeing only traffic destined for the local host).
 The bonding driver handles promiscuous mode changes to the bonding
-master device (e.g., bond0), and propogates the setting to the slave
+master device (e.g., bond0), and propagates the setting to the slave
 devices.
 
 	For the balance-rr, balance-xor, broadcast, and 802.3ad modes,
-the promiscuous mode setting is propogated to all slaves.
+the promiscuous mode setting is propagated to all slaves.
 
 	For the active-backup, balance-tlb and balance-alb modes, the
-promiscuous mode setting is propogated only to the active slave.
+promiscuous mode setting is propagated only to the active slave.
 
 	For balance-tlb mode, the active slave is the slave currently
 receiving inbound traffic.
@@ -1148,46 +1307,182 @@ sending to peers that are unassigned or 
 
 	For the active-backup, balance-tlb and balance-alb modes, when
 the active slave changes (e.g., due to a link failure), the
-promiscuous setting will be propogated to the new active slave.
+promiscuous setting will be propagated to the new active slave.
 
-12. High Availability Information
-=================================
+12. Configuring Bonding for High Availability
+=============================================
 
 	High Availability refers to configurations that provide
 maximum network availability by having redundant or backup devices,
-links and switches between the host and the rest of the world.
-
-	There are currently two basic methods for configuring to
-maximize availability. They are dependent on the network topology and
-the primary goal of the configuration, but in general, a configuration
-can be optimized for maximum available bandwidth, or for maximum
-network availability.
+links or switches between the host and the rest of the world.  The
+goal is to provide the maximum availability of network connectivity
+(i.e., the network always works), even though other configurations
+could provide higher throughput.
 
 12.1 High Availability in a Single Switch Topology
 --------------------------------------------------
 
-	If two hosts (or a host and a switch) are directly connected
-via multiple physical links, then there is no network availability
-penalty for optimizing for maximum bandwidth: there is only one switch
-(or peer), so if it fails, you have no alternative access to fail over
-to.
-
-Example 1 : host to switch (or other host)
-
-          +----------+                          +----------+
-          |          |eth0                  eth0|  switch  |
-          | Host A   +--------------------------+    or    |
-          |          +--------------------------+  other   |
-          |          |eth1                  eth1|  host    |
-          +----------+                          +----------+
+	If two hosts (or a host and a single switch) are directly
+connected via multiple physical links, then there is no availability
+penalty to optimizing for maximum bandwidth.  In this case, there is
+only one switch (or peer), so if it fails, there is no alternative
+access to fail over to.  Additionally, the bonding load balance modes
+support link monitoring of their members, so if individual links fail,
+the load will be rebalanced across the remaining devices.
+
+	See Section 13, "Configuring Bonding for Maximum Throughput"
+for information on configuring bonding with one peer device.
+
+12.2 High Availability in a Multiple Switch Topology
+----------------------------------------------------
+
+	With multiple switches, the configuration of bonding and the
+network changes dramatically.  In multiple switch topologies, there is
+a trade off between network availability and usable bandwidth.
+
+	Below is a sample network, configured to maximize the
+availability of the network:
+
+                |                                     |
+                |port3                           port3|
+          +-----+----+                          +-----+----+
+          |          |port2       ISL      port2|          |
+          | switch A +--------------------------+ switch B |
+          |          |                          |          |
+          +-----+----+                          +-----++---+
+                |port1                           port1|
+                |             +-------+               |
+                +-------------+ host1 +---------------+
+                         eth0 +-------+ eth1
+
+	In this configuration, there is a link between the two
+switches (ISL, or inter switch link), and multiple ports connecting to
+the outside world ("port3" on each switch).  There is no technical
+reason that this could not be extended to a third switch.
+
+12.2.1 HA Bonding Mode Selection for Multiple Switch Topology
+-------------------------------------------------------------
 
+	In a topology such as the example above, the active-backup and
+broadcast modes are the only useful bonding modes when optimizing for
+availability; the other modes require all links to terminate on the
+same peer for them to behave rationally.
 
-12.1.1 Bonding Mode Selection for single switch topology
---------------------------------------------------------
+active-backup: This is generally the preferred mode, particularly if
+	the switches have an ISL and play together well.  If the
+	network configuration is such that one switch is specifically
+	a backup switch (e.g., has lower capacity, higher cost, etc),
+	then the primary option can be used to insure that the
+	preferred link is always used when it is available.
+
+broadcast: This mode is really a special purpose mode, and is suitable
+	only for very specific needs.  For example, if the two
+	switches are not connected (no ISL), and the networks beyond
+	them are totally independent.  In this case, if it is
+	necessary for some specific one-way traffic to reach both
+	independent networks, then the broadcast mode may be suitable.
+
+12.2.2 HA Link Monitoring Selection for Multiple Switch Topology
+----------------------------------------------------------------
+
+	The choice of link monitoring ultimately depends upon your
+switch.  If the switch can reliably fail ports in response to other
+failures, then either the MII or ARP monitors should work.  For
+example, in the above example, if the "port3" link fails at the remote
+end, the MII monitor has no direct means to detect this.  The ARP
+monitor could be configured with a target at the remote end of port3,
+thus detecting that failure without switch support.
+
+	In general, however, in a multiple switch topology, the ARP
+monitor can provide a higher level of reliability in detecting end to
+end connectivity failures (which may be caused by the failure of any
+individual component to pass traffic for any reason).  Additionally,
+the ARP monitor should be configured with multiple targets (at least
+one for each switch in the network).  This will insure that,
+regardless of which switch is active, the ARP monitor has a suitable
+target to query.
+
+
+13. Configuring Bonding for Maximum Throughput
+==============================================
+
+13.1 Maximizing Throughput in a Single Switch Topology
+------------------------------------------------------
+
+	In a single switch configuration, the best method to maximize
+throughput depends upon the application and network environment.  The
+various load balancing modes each have strengths and weaknesses in
+different environments, as detailed below.
+
+	For this discussion, we will break down the topologies into
+two categories.  Depending upon the destination of most traffic, we
+categorize them into either "gatewayed" or "local" configurations.
+
+	In a gatewayed configuration, the "switch" is acting primarily
+as a router, and the majority of traffic passes through this router to
+other networks.  An example would be the following:
+
+
+     +----------+                     +----------+
+     |          |eth0            port1|          | to other networks
+     | Host A   +---------------------+ router   +------------------->
+     |          +---------------------+          | Hosts B and C are out
+     |          |eth1            port2|          | here somewhere
+     +----------+                     +----------+
+
+	The router may be a dedicated router device, or another host
+acting as a gateway.  For our discussion, the important point is that
+the majority of traffic from Host A will pass through the router to
+some other network before reaching its final destination.
+
+	In a gatewayed network configuration, although Host A may
+communicate with many other systems, all of its traffic will be sent
+and received via one other peer on the local network, the router.
+
+	Note that the case of two systems connected directly via
+multiple physical links is, for purposes of configuring bonding, the
+same as a gatewayed configuration.  In that case, it happens that all
+traffic is destined for the "gateway" itself, not some other network
+beyond the gateway.
+
+	In a local configuration, the "switch" is acting primarily as
+a switch, and the majority of traffic passes through this switch to
+reach other stations on the same network.  An example would be the
+following:
+
+    +----------+            +----------+       +--------+
+    |          |eth0   port1|          +-------+ Host B |
+    |  Host A  +------------+  switch  |port3  +--------+
+    |          +------------+          |                  +--------+
+    |          |eth1   port2|          +------------------+ Host C |
+    +----------+            +----------+port4             +--------+
+
+
+	Again, the switch may be a dedicated switch device, or another
+host acting as a gateway.  For our discussion, the important point is
+that the majority of traffic from Host A is destined for other hosts
+on the same local network (Hosts B and C in the above example).
+
+	In summary, in a gatewayed configuration, traffic to and from
+the bonded device will be to the same MAC level peer on the network
+(the gateway itself, i.e., the router), regardless of its final
+destination.  In a local configuration, traffic flows directly to and
+from the final destinations, thus, each destination (Host B, Host C)
+will be addressed directly by their individual MAC addresses.
+
+	This distinction between a gatewayed and a local network
+configuration is important because many of the load balancing modes
+available use the MAC addresses of the local network source and
+destination to make load balancing decisions.  The behavior of each
+mode is described below.
+
+
+13.1.1 MT Bonding Mode Selection for Single Switch Topology
+-----------------------------------------------------------
 
 	This configuration is the easiest to set up and to understand,
 although you will have to decide which bonding mode best suits your
-needs.  The tradeoffs for each mode are detailed below:
+needs.  The trade offs for each mode are detailed below:
 
 balance-rr: This mode is the only mode that will permit a single
 	TCP/IP connection to stripe traffic across multiple
@@ -1206,6 +1501,23 @@ balance-rr: This mode is the only mode t
 	interface's worth of throughput, even after adjusting
 	tcp_reordering.
 
+	Note that this out of order delivery occurs when both the
+	sending and receiving systems are utilizing a multiple
+	interface bond.  Consider a configuration in which a
+	balance-rr bond feeds into a single higher capacity network
+	channel (e.g., multiple 100Mb/sec ethernets feeding a single
+	gigabit ethernet via an etherchannel capable switch).  In this
+	configuration, traffic sent from the multiple 100Mb devices to
+	a destination connected to the gigabit device will not see
+	packets out of order.  However, traffic sent from the gigabit
+	device to the multiple 100Mb devices may or may not see
+	traffic out of order, depending upon the balance policy of the
+	switch.  Many switches do not support any modes that stripe
+	traffic (instead choosing a port based upon IP or MAC level
+	addresses); for those devices, traffic flowing from the
+	gigabit device to the many 100Mb devices will only utilize one
+	interface.
+
 	If you are utilizing protocols other than TCP/IP, UDP for
 	example, and your application can tolerate out of order
 	delivery, then this mode can allow for single stream datagram
@@ -1220,16 +1532,21 @@ active-backup: There is not much advanta
 	connected to the same peer as the primary.  In this case, a
 	load balancing mode (with link monitoring) will provide the
 	same level of network availability, but with increased
-	available bandwidth.  On the plus side, it does not require
-	any configuration of the switch.
+	available bandwidth.  On the plus side, active-backup mode
+	does not require any configuration of the switch, so it may
+	have value if the hardware available does not support any of
+	the load balance modes.
 
 balance-xor: This mode will limit traffic such that packets destined
 	for specific peers will always be sent over the same
 	interface.  Since the destination is determined by the MAC
-	addresses involved, this may be desirable if you have a large
-	network with many hosts.  It is likely to be suboptimal if all
-	your traffic is passed through a single router, however.  As
-	with balance-rr, the switch ports need to be configured for
+	addresses involved, this mode works best in a "local" network
+	configuration (as described above), with destinations all on
+	the same local network.  This mode is likely to be suboptimal
+	if all your traffic is passed through a single router (i.e., a
+	"gatewayed" network configuration, as described above).
+
+	As with balance-rr, the switch ports need to be configured for
 	"etherchannel" or "trunking."
 
 broadcast: Like active-backup, there is not much advantage to this
@@ -1241,122 +1558,131 @@ broadcast: Like active-backup, there is 
 	protocol includes automatic configuration of the aggregates,
 	so minimal manual configuration of the switch is needed
 	(typically only to designate that some set of devices is
-	usable for 802.3ad).  The 802.3ad standard also mandates that
-	frames be delivered in order (within certain limits), so in
-	general single connections will not see misordering of
+	available for 802.3ad).  The 802.3ad standard also mandates
+	that frames be delivered in order (within certain limits), so
+	in general single connections will not see misordering of
 	packets.  The 802.3ad mode does have some drawbacks: the
 	standard mandates that all devices in the aggregate operate at
 	the same speed and duplex.  Also, as with all bonding load
 	balance modes other than balance-rr, no single connection will
 	be able to utilize more than a single interface's worth of
-	bandwidth.  Additionally, the linux bonding 802.3ad
-	implementation distributes traffic by peer (using an XOR of
-	MAC addresses), so in general all traffic to a particular
-	destination will use the same interface.  Finally, the 802.3ad
-	mode mandates the use of the MII monitor, therefore, the ARP
-	monitor is not available in this mode.
-
-balance-tlb: This mode is also a good choice for this type of
-	topology.  It has no special switch configuration
-	requirements, and balances outgoing traffic by peer, in a
-	vaguely intelligent manner (not a simple XOR as in balance-xor
-	or 802.3ad mode), so that unlucky MAC addresses will not all
-	"bunch up" on a single interface.  Interfaces may be of
-	differing speeds.  On the down side, in this mode all incoming
-	traffic arrives over a single interface, this mode requires
-	certain ethtool support in the network device driver of the
-	slave interfaces, and the ARP monitor is not available.
-
-balance-alb: This mode is everything that balance-tlb is, and more. It
-	has all of the features (and restrictions) of balance-tlb, and
-	will also balance incoming traffic from peers (as described in
-	the Bonding Module Options section, above).  The only extra
-	down side to this mode is that the network device driver must
-	support changing the hardware address while the device is
-	open.
+	bandwidth.  
 
-12.1.2 Link Monitoring for Single Switch Topology
--------------------------------------------------
+	Additionally, the linux bonding 802.3ad implementation
+	distributes traffic by peer (using an XOR of MAC addresses),
+	so in a "gatewayed" configuration, all outgoing traffic will
+	generally use the same device.  Incoming traffic may also end
+	up on a single device, but that is dependent upon the
+	balancing policy of the peer's 8023.ad implementation.  In a
+	"local" configuration, traffic will be distributed across the
+	devices in the bond.
+
+	Finally, the 802.3ad mode mandates the use of the MII monitor,
+	therefore, the ARP monitor is not available in this mode.
+
+balance-tlb: The balance-tlb mode balances outgoing traffic by peer.
+	Since the balancing is done according to MAC address, in a
+	"gatewayed" configuration (as described above), this mode will
+	send all traffic across a single device.  However, in a
+	"local" network configuration, this mode balances multiple
+	local network peers across devices in a vaguely intelligent
+	manner (not a simple XOR as in balance-xor or 802.3ad mode),
+	so that mathematically unlucky MAC addresses (i.e., ones that
+	XOR to the same value) will not all "bunch up" on a single
+	interface.
+
+	Unlike 802.3ad, interfaces may be of differing speeds, and no
+	special switch configuration is required.  On the down side,
+	in this mode all incoming traffic arrives over a single
+	interface, this mode requires certain ethtool support in the
+	network device driver of the slave interfaces, and the ARP
+	monitor is not available.
+
+balance-alb: This mode is everything that balance-tlb is, and more.
+	It has all of the features (and restrictions) of balance-tlb,
+	and will also balance incoming traffic from local network
+	peers (as described in the Bonding Module Options section,
+	above).
+
+	The only additional down side to this mode is that the network
+	device driver must support changing the hardware address while
+	the device is open.
+
+13.1.2 MT Link Monitoring for Single Switch Topology
+----------------------------------------------------
 
 	The choice of link monitoring may largely depend upon which
 mode you choose to use.  The more advanced load balancing modes do not
 support the use of the ARP monitor, and are thus restricted to using
-the MII monitor (which does not provide as high a level of assurance
-as the ARP monitor).
-
+the MII monitor (which does not provide as high a level of end to end
+assurance as the ARP monitor).
 
-12.2 High Availability in a Multiple Switch Topology
-----------------------------------------------------
+13.2 Maximum Throughput in a Multiple Switch Topology
+-----------------------------------------------------
 
-	With multiple switches, the configuration of bonding and the
-network changes dramatically.  In multiple switch topologies, there is
-a tradeoff between network availability and usable bandwidth.
+	Multiple switches may be utilized to optimize for throughput
+when they are configured in parallel as part of an isolated network
+between two or more systems, for example:
+
+                       +-----------+
+                       |  Host A   | 
+                       +-+---+---+-+
+                         |   |   |
+                +--------+   |   +---------+
+                |            |             |
+         +------+---+  +-----+----+  +-----+----+
+         | Switch A |  | Switch B |  | Switch C |
+         +------+---+  +-----+----+  +-----+----+
+                |            |             |
+                +--------+   |   +---------+
+                         |   |   |
+                       +-+---+---+-+
+                       |  Host B   | 
+                       +-----------+
+
+	In this configuration, the switches are isolated from one
+another.  One reason to employ a topology such as this is for an
+isolated network with many hosts (a cluster configured for high
+performance, for example), using multiple smaller switches can be more
+cost effective than a single larger switch, e.g., on a network with 24
+hosts, three 24 port switches can be significantly less expensive than
+a single 72 port switch.
+
+	If access beyond the network is required, an individual host
+can be equipped with an additional network device connected to an
+external network; this host then additionally acts as a gateway.
 
-	Below is a sample network, configured to maximize the
-availability of the network:
-
-                |                                     |
-                |port3                           port3|
-          +-----+----+                          +-----+----+
-          |          |port2       ISL      port2|          |
-          | switch A +--------------------------+ switch B |
-          |          |                          |          |
-          +-----+----+                          +-----++---+
-                |port1                           port1|
-                |             +-------+               |
-                +-------------+ host1 +---------------+
-                         eth0 +-------+ eth1
-
-	In this configuration, there is a link between the two
-switches (ISL, or inter switch link), and multiple ports connecting to
-the outside world ("port3" on each switch).  There is no technical
-reason that this could not be extended to a third switch.
-
-12.2.1 Bonding Mode Selection for Multiple Switch Topology
-----------------------------------------------------------
-
-	In a topology such as this, the active-backup and broadcast
-modes are the only useful bonding modes; the other modes require all
-links to terminate on the same peer for them to behave rationally.
-
-active-backup: This is generally the preferred mode, particularly if
-	the switches have an ISL and play together well.  If the
-	network configuration is such that one switch is specifically
-	a backup switch (e.g., has lower capacity, higher cost, etc),
-	then the primary option can be used to insure that the
-	preferred link is always used when it is available.
-
-broadcast: This mode is really a special purpose mode, and is suitable
-	only for very specific needs.  For example, if the two
-	switches are not connected (no ISL), and the networks beyond
-	them are totally independant.  In this case, if it is
-	necessary for some specific one-way traffic to reach both
-	independent networks, then the broadcast mode may be suitable.
-
-12.2.2 Link Monitoring Selection for Multiple Switch Topology
+13.2.1 MT Bonding Mode Selection for Multiple Switch Topology
 -------------------------------------------------------------
 
-	The choice of link monitoring ultimately depends upon your
-switch.  If the switch can reliably fail ports in response to other
-failures, then either the MII or ARP monitors should work.  For
-example, in the above example, if the "port3" link fails at the remote
-end, the MII monitor has no direct means to detect this.  The ARP
-monitor could be configured with a target at the remote end of port3,
-thus detecting that failure without switch support.
-
-	In general, however, in a multiple switch topology, the ARP
-monitor can provide a higher level of reliability in detecting link
-failures.  Additionally, it should be configured with multiple targets
-(at least one for each switch in the network).  This will insure that,
-regardless of which switch is active, the ARP monitor has a suitable
-target to query.
+	In actual practice, the bonding mode typically employed in
+configurations of this type is balance-rr.  Historically, in this
+network configuration, the usual caveats about out of order packet
+delivery are mitigated by the use of network adapters that do not do
+any kind of packet coalescing (via the use of NAPI, or because the
+device itself does not generate interrupts until some number of
+packets has arrived).  When employed in this fashion, the balance-rr
+mode allows individual connections between two hosts to effectively
+utilize greater than one interface's bandwidth.
+
+13.2.2 MT Link Monitoring for Multiple Switch Topology
+------------------------------------------------------
+
+	Again, in actual practice, the MII monitor is most often used
+in this configuration, as performance is given preference over
+availability.  The ARP monitor will function in this topology, but its
+advantages over the MII monitor are mitigated by the volume of probes
+needed as the number of systems involved grows (remember that each
+host in the network is configured with bonding).
 
+14. Switch Behavior Issues
+==========================
 
-12.3 Switch Behavior Issues for High Availability
--------------------------------------------------
+14.1 Link Establishment and Failover Delays
+-------------------------------------------
 
-	You may encounter issues with the timing of link up and down
-reporting by the switch.
+	Some switches exhibit undesirable behavior with regard to the
+timing of link up and down reporting by the switch.
 
 	First, when a link comes up, some switches may indicate that
 the link is up (carrier available), but not pass traffic over the
@@ -1370,30 +1696,70 @@ relevant interface(s).
 	Second, some switches may "bounce" the link state one or more
 times while a link is changing state.  This occurs most commonly while
 the switch is initializing.  Again, an appropriate updelay value may
-help, but note that if all links are down, then updelay is ignored
-when any link becomes active (the slave closest to completing its
-updelay is chosen).
+help.
 
 	Note that when a bonding interface has no active links, the
-driver will immediately reuse the first link that goes up, even if
-updelay parameter was specified.  If there are slave interfaces
-waiting for the updelay timeout to expire, the interface that first
-went into that state will be immediately reused.  This reduces down
-time of the network if the value of updelay has been overestimated.
+driver will immediately reuse the first link that goes up, even if the
+updelay parameter has been specified (the updelay is ignored in this
+case).  If there are slave interfaces waiting for the updelay timeout
+to expire, the interface that first went into that state will be
+immediately reused.  This reduces down time of the network if the
+value of updelay has been overestimated, and since this occurs only in
+cases with no connectivity, there is no additional penalty for
+ignoring the updelay.
 
 	In addition to the concerns about switch timings, if your
 switches take a long time to go into backup mode, it may be desirable
 to not activate a backup interface immediately after a link goes down.
 Failover may be delayed via the downdelay bonding module option.
 
-13. Hardware Specific Considerations
+14.2 Duplicated Incoming Packets
+--------------------------------
+
+	It is not uncommon to observe a short burst of duplicated
+traffic when the bonding device is first used, or after it has been
+idle for some period of time.  This is most easily observed by issuing
+a "ping" to some other host on the network, and noticing that the
+output from ping flags duplicates (typically one per slave).
+
+	For example, on a bond in active-backup mode with five slaves
+all connected to one switch, the output may appear as follows:
+
+# ping -n 10.0.4.2
+PING 10.0.4.2 (10.0.4.2) from 10.0.3.10 : 56(84) bytes of data.
+64 bytes from 10.0.4.2: icmp_seq=1 ttl=64 time=13.7 ms
+64 bytes from 10.0.4.2: icmp_seq=1 ttl=64 time=13.8 ms (DUP!)
+64 bytes from 10.0.4.2: icmp_seq=1 ttl=64 time=13.8 ms (DUP!)
+64 bytes from 10.0.4.2: icmp_seq=1 ttl=64 time=13.8 ms (DUP!)
+64 bytes from 10.0.4.2: icmp_seq=1 ttl=64 time=13.8 ms (DUP!)
+64 bytes from 10.0.4.2: icmp_seq=2 ttl=64 time=0.216 ms
+64 bytes from 10.0.4.2: icmp_seq=3 ttl=64 time=0.267 ms
+64 bytes from 10.0.4.2: icmp_seq=4 ttl=64 time=0.222 ms
+
+	This is not due to an error in the bonding driver, rather, it
+is a side effect of how many switches update their MAC forwarding
+tables.  Initially, the switch does not associate the MAC address in
+the packet with a particular switch port, and so it may send the
+traffic to all ports until its MAC forwarding table is updated.  Since
+the interfaces attached to the bond may occupy multiple ports on a
+single switch, when the switch (temporarily) floods the traffic to all
+ports, the bond device receives multiple copies of the same packet
+(one per slave device).
+
+	The duplicated packet behavior is switch dependent, some
+switches exhibit this, and some do not.  On switches that display this
+behavior, it can be induced by clearing the MAC forwarding table (on
+most Cisco switches, the privileged command "clear mac address-table
+dynamic" will accomplish this).
+
+15. Hardware Specific Considerations
 ====================================
 
 	This section contains additional information for configuring
 bonding on specific hardware platforms, or for interfacing bonding
 with particular switches or other devices.
 
-13.1 IBM BladeCenter
+15.1 IBM BladeCenter
 --------------------
 
 	This applies to the JS20 and similar systems.
@@ -1407,12 +1773,12 @@ JS20 network adapter information
 --------------------------------
 
 	All JS20s come with two Broadcom Gigabit Ethernet ports
-integrated on the planar.  In the BladeCenter chassis, the eth0 port
-of all JS20 blades is hard wired to I/O Module #1; similarly, all eth1
-ports are wired to I/O Module #2.  An add-on Broadcom daughter card
-can be installed on a JS20 to provide two more Gigabit Ethernet ports.
-These ports, eth2 and eth3, are wired to I/O Modules 3 and 4,
-respectively.
+integrated on the planar (that's "motherboard" in IBM-speak).  In the
+BladeCenter chassis, the eth0 port of all JS20 blades is hard wired to
+I/O Module #1; similarly, all eth1 ports are wired to I/O Module #2.
+An add-on Broadcom daughter card can be installed on a JS20 to provide
+two more Gigabit Ethernet ports.  These ports, eth2 and eth3, are
+wired to I/O Modules 3 and 4, respectively.
 
 	Each I/O Module may contain either a switch or a passthrough
 module (which allows ports to be directly connected to an external
@@ -1432,29 +1798,30 @@ BladeCenter networking configuration
 of ways, this discussion will be confined to describing basic
 configurations.
 
-	Normally, Ethernet Switch Modules (ESM) are used in I/O
+	Normally, Ethernet Switch Modules (ESMs) are used in I/O
 modules 1 and 2.  In this configuration, the eth0 and eth1 ports of a
 JS20 will be connected to different internal switches (in the
 respective I/O modules).
 
-	An optical passthru module (OPM) connects the I/O module
-directly to an external switch.  By using OPMs in I/O module #1 and
-#2, the eth0 and eth1 interfaces of a JS20 can be redirected to the
-outside world and connected to a common external switch.
-
-	Depending upon the mix of ESM and OPM modules, the network
-will appear to bonding as either a single switch topology (all OPM
-modules) or as a multiple switch topology (one or more ESM modules,
-zero or more OPM modules).  It is also possible to connect ESM modules
-together, resulting in a configuration much like the example in "High
-Availability in a multiple switch topology."
-
-Requirements for specifc modes
-------------------------------
-
-	The balance-rr mode requires the use of OPM modules for
-devices in the bond, all connected to an common external switch.  That
-switch must be configured for "etherchannel" or "trunking" on the
+	A passthrough module (OPM or CPM, optical or copper,
+passthrough module) connects the I/O module directly to an external
+switch.  By using PMs in I/O module #1 and #2, the eth0 and eth1
+interfaces of a JS20 can be redirected to the outside world and
+connected to a common external switch.
+
+	Depending upon the mix of ESMs and PMs, the network will
+appear to bonding as either a single switch topology (all PMs) or as a
+multiple switch topology (one or more ESMs, zero or more PMs).  It is
+also possible to connect ESMs together, resulting in a configuration
+much like the example in "High Availability in a Multiple Switch
+Topology," above.
+
+Requirements for specific modes
+-------------------------------
+
+	The balance-rr mode requires the use of passthrough modules
+for devices in the bond, all connected to an common external switch.
+That switch must be configured for "etherchannel" or "trunking" on the
 appropriate ports, as is usual for balance-rr.
 
 	The balance-alb and balance-tlb modes will function with
@@ -1484,17 +1851,18 @@ connected to the JS20 system.
 Other concerns
 --------------
 
-	The Serial Over LAN link is established over the primary
+	The Serial Over LAN (SoL) link is established over the primary
 ethernet (eth0) only, therefore, any loss of link to eth0 will result
 in losing your SoL connection.  It will not fail over with other
-network traffic.
+network traffic, as the SoL system is beyond the control of the
+bonding driver.
 
 	It may be desirable to disable spanning tree on the switch
 (either the internal Ethernet Switch Module, or an external switch) to
-avoid fail-over delays issues when using bonding.
+avoid fail-over delay issues when using bonding.
 
 	
-14. Frequently Asked Questions
+16. Frequently Asked Questions
 ==============================
 
 1.  Is it SMP safe?
@@ -1505,8 +1873,8 @@ The new driver was designed to be SMP sa
 2.  What type of cards will work with it?
 
 	Any Ethernet type cards (you can even mix cards - a Intel
-EtherExpress PRO/100 and a 3com 3c905b, for example).  They need not
-be of the same speed.
+EtherExpress PRO/100 and a 3com 3c905b, for example).  For most modes,
+devices need not be of the same speed.
 
 3.  How many bonding devices can I have?
 
@@ -1524,11 +1892,12 @@ system.
 disabled.  The active-backup mode will fail over to a backup link, and
 other modes will ignore the failed link.  The link will continue to be
 monitored, and should it recover, it will rejoin the bond (in whatever
-manner is appropriate for the mode). See the section on High
-Availability for additional information.
+manner is appropriate for the mode). See the sections on High
+Availability and the documentation for each mode for additional
+information.
 	
 	Link monitoring can be enabled via either the miimon or
-arp_interval paramters (described in the module paramters section,
+arp_interval parameters (described in the module parameters section,
 above).  In general, miimon monitors the carrier state as sensed by
 the underlying network device, and the arp monitor (arp_interval)
 monitors connectivity to another host on the local network.
@@ -1536,7 +1905,7 @@ monitors connectivity to another host on
 	If no link monitoring is configured, the bonding driver will
 be unable to detect link failures, and will assume that all links are
 always available.  This will likely result in lost packets, and a
-resulting degredation of performance.  The precise performance loss
+resulting degradation of performance.  The precise performance loss
 depends upon the bonding mode and network configuration.
 
 6.  Can bonding be used for High Availability?
@@ -1550,12 +1919,12 @@ depends upon the bonding mode and networ
 	In the basic balance modes (balance-rr and balance-xor), it
 works with any system that supports etherchannel (also called
 trunking).  Most managed switches currently available have such
-support, and many unmananged switches as well.
+support, and many unmanaged switches as well.
 
 	The advanced balance modes (balance-tlb and balance-alb) do
 not have special switch requirements, but do need device drivers that
 support specific features (described in the appropriate section under
-module paramters, above).
+module parameters, above).
 
 	In 802.3ad mode, it works with with systems that support IEEE
 802.3ad Dynamic Link Aggregation.  Most managed and many unmanaged
@@ -1565,17 +1934,19 @@ switches currently available support 802
 
 8.  Where does a bonding device get its MAC address from?
 
-	If not explicitly configured with ifconfig, the MAC address of
-the bonding device is taken from its first slave device. This MAC
-address is then passed to all following slaves and remains persistent
-(even if the the first slave is removed) until the bonding device is
-brought down or reconfigured.
+	If not explicitly configured (with ifconfig or ip link), the
+MAC address of the bonding device is taken from its first slave
+device.  This MAC address is then passed to all following slaves and
+remains persistent (even if the the first slave is removed) until the
+bonding device is brought down or reconfigured.
 
 	If you wish to change the MAC address, you can set it with
-ifconfig:
+ifconfig or ip link:
 
 # ifconfig bond0 hw ether 00:11:22:33:44:55
 
+# ip link set bond0 address 66:77:88:99:aa:bb
+
 	The MAC address can be also changed by bringing down/up the
 device and then changing its slaves (or their order):
 
@@ -1591,23 +1962,28 @@ from the bond (`ifenslave -d bond0 eth0'
 then restore the MAC addresses that the slaves had before they were
 enslaved.
 
-15. Resources and Links
+16. Resources and Links
 =======================
 
 The latest version of the bonding driver can be found in the latest
 version of the linux kernel, found on http://kernel.org
 
+The latest version of this document can be found in either the latest
+kernel source (named Documentation/networking/bonding.txt), or on the
+bonding sourceforge site:
+
+http://www.sourceforge.net/projects/bonding
+
 Discussions regarding the bonding driver take place primarily on the
 bonding-devel mailing list, hosted at sourceforge.net.  If you have
-questions or problems, post them to the list.
+questions or problems, post them to the list.  The list address is:
 
 bonding-devel@lists.sourceforge.net
 
-https://lists.sourceforge.net/lists/listinfo/bonding-devel
-
-There is also a project site on sourceforge.
+	The administrative interface (to subscribe or unsubscribe) can
+be found at:
 
-http://www.sourceforge.net/projects/bonding
+https://lists.sourceforge.net/lists/listinfo/bonding-devel
 
 Donald Becker's Ethernet Drivers and diag programs may be found at :
  - http://www.scyld.com/network/
diff --git a/Documentation/networking/dmfe.txt b/Documentation/networking/dmfe.txt
--- a/Documentation/networking/dmfe.txt
+++ b/Documentation/networking/dmfe.txt
@@ -1,59 +1,65 @@
-  dmfe.c: Version 1.28        01/18/2000
+Davicom DM9102(A)/DM9132/DM9801 fast ethernet driver for Linux.
 
-        A Davicom DM9102(A)/DM9132/DM9801 fast ethernet driver for Linux. 
-        Copyright (C) 1997  Sten Wang
+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 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.
 
-        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.
 
+This driver provides kernel support for Davicom DM9102(A)/DM9132/DM9801 ethernet cards ( CNET
+10/100 ethernet cards uses Davicom chipset too, so this driver supports CNET cards too ).If you
+didn't compile this driver as a module, it will automatically load itself on boot and print a
+line similar to :
 
-  A. Compiler command:
+	dmfe: Davicom DM9xxx net driver, version 1.36.4 (2002-01-17)
 
-     A-1: For normal single or multiple processor kernel
-          "gcc -DMODULE -D__KERNEL__ -I/usr/src/linux/net/inet -Wall 
-            -Wstrict-prototypes -O6 -c dmfe.c"
+If you compiled this driver as a module, you have to load it on boot.You can load it with command :
 
-     A-2: For single or multiple processor with kernel module version function
-          "gcc -DMODULE -DMODVERSIONS -D__KERNEL__ -I/usr/src/linux/net/inet 
-            -Wall -Wstrict-prototypes -O6 -c dmfe.c"
+	insmod dmfe
 
+This way it will autodetect the device mode.This is the suggested way to load the module.Or you can pass
+a mode= setting to module while loading, like :
 
-  B. The following steps teach you how to activate a DM9102 board:
+	insmod dmfe mode=0 # Force 10M Half Duplex
+	insmod dmfe mode=1 # Force 100M Half Duplex
+	insmod dmfe mode=4 # Force 10M Full Duplex
+	insmod dmfe mode=5 # Force 100M Full Duplex
 
-        1. Used the upper compiler command to compile dmfe.c
+Next you should configure your network interface with a command similar to :
 
-        2. Insert dmfe module into kernel
-           "insmod dmfe"        ;;Auto Detection Mode (Suggest)
-           "insmod dmfe mode=0" ;;Force 10M Half Duplex
-           "insmod dmfe mode=1" ;;Force 100M Half Duplex
-           "insmod dmfe mode=4" ;;Force 10M Full Duplex
-           "insmod dmfe mode=5" ;;Force 100M Full Duplex
+	ifconfig eth0 172.22.3.18
+                      ^^^^^^^^^^^
+		     Your IP Adress
 
-        3. Config a dm9102 network interface
-           "ifconfig eth0 172.22.3.18"
-                          ^^^^^^^^^^^ Your IP address
+Then you may have to modify the default routing table with command :
 
-        4. Activate the IP routing table. For some distributions, it is not
-           necessary. You can type "route" to check.
+	route add default eth0
 
-           "route add default eth0"
 
+Now your ethernet card should be up and running.
 
-        5. Well done. Your DM9102 adapter is now activated.
 
+TODO:
 
-   C. Object files description:
-        1. dmfe_rh61.o:       	For Redhat 6.1
+Implement pci_driver::suspend() and pci_driver::resume() power management methods.
+Check on 64 bit boxes.
+Check and fix on big endian boxes.
+Test and make sure PCI latency is now correct for all cases.
 
-        If you can make sure your kernel version, you can rename
-        to dmfe.o and directly use it without re-compiling.
 
+Authors:
 
-  Author: Sten Wang, 886-3-5798797-8517, E-mail: sten_wang@davicom.com.tw
+Sten Wang <sten_wang@davicom.com.tw >   : Original Author
+Tobias Ringstrom <tori@unhappy.mine.nu> : Current Maintainer
+
+Contributors:
+
+Marcelo Tosatti <marcelo@conectiva.com.br>
+Alan Cox <alan@redhat.com>
+Jeff Garzik <jgarzik@pobox.com>
+Vojtech Pavlik <vojtech@suse.cz>
diff --git a/Documentation/networking/fib_trie.txt b/Documentation/networking/fib_trie.txt
new file mode 100644
--- /dev/null
+++ b/Documentation/networking/fib_trie.txt
@@ -0,0 +1,145 @@
+			LC-trie implementation notes.
+
+Node types
+----------
+leaf 
+	An end node with data. This has a copy of the relevant key, along
+	with 'hlist' with routing table entries sorted by prefix length.
+	See struct leaf and struct leaf_info.
+
+trie node or tnode
+	An internal node, holding an array of child (leaf or tnode) pointers,
+	indexed	through a subset of the key. See Level Compression.
+
+A few concepts explained
+------------------------
+Bits (tnode) 
+	The number of bits in the key segment used for indexing into the
+	child array - the "child index". See Level Compression.
+
+Pos (tnode)
+	The position (in the key) of the key segment used for indexing into
+	the child array. See Path Compression.
+
+Path Compression / skipped bits
+	Any given tnode is linked to from the child array of its parent, using
+	a segment of the key specified by the parent's "pos" and "bits" 
+	In certain cases, this tnode's own "pos" will not be immediately
+	adjacent to the parent (pos+bits), but there will be some bits
+	in the key skipped over because they represent a single path with no
+	deviations. These "skipped bits" constitute Path Compression.
+	Note that the search algorithm will simply skip over these bits when
+	searching, making it necessary to save the keys in the leaves to
+	verify that they actually do match the key we are searching for.
+
+Level Compression / child arrays
+	the trie is kept level balanced moving, under certain conditions, the
+	children of a full child (see "full_children") up one level, so that
+	instead of a pure binary tree, each internal node ("tnode") may
+	contain an arbitrarily large array of links to several children.
+	Conversely, a tnode with a mostly empty	child array (see empty_children)
+	may be "halved", having some of its children moved downwards one level,
+	in order to avoid ever-increasing child arrays.
+
+empty_children
+	the number of positions in the child array of a given tnode that are
+	NULL.
+
+full_children
+	the number of children of a given tnode that aren't path compressed.
+	(in other words, they aren't NULL or leaves and their "pos" is equal
+	to this	tnode's "pos"+"bits").
+
+	(The word "full" here is used more in the sense of "complete" than
+	as the opposite of "empty", which might be a tad confusing.)
+
+Comments
+---------
+
+We have tried to keep the structure of the code as close to fib_hash as 
+possible to allow verification and help up reviewing. 
+
+fib_find_node()
+	A good start for understanding this code. This function implements a
+	straightforward trie lookup.
+
+fib_insert_node()
+	Inserts a new leaf node in the trie. This is bit more complicated than
+	fib_find_node(). Inserting a new node means we might have to run the
+	level compression algorithm on part of the trie.
+
+trie_leaf_remove()
+	Looks up a key, deletes it and runs the level compression algorithm.
+
+trie_rebalance()
+	The key function for the dynamic trie after any change in the trie
+	it is run to optimize and reorganize. Tt will walk the trie upwards 
+	towards the root from a given tnode, doing a resize() at each step 
+	to implement level compression.
+
+resize()
+	Analyzes a tnode and optimizes the child array size by either inflating
+	or shrinking it repeatedly until it fullfills the criteria for optimal
+	level compression. This part follows the original paper pretty closely
+	and there may be some room for experimentation here.
+
+inflate()
+	Doubles the size of the child array within a tnode. Used by resize().
+
+halve()
+	Halves the size of the child array within a tnode - the inverse of
+	inflate(). Used by resize();
+
+fn_trie_insert(), fn_trie_delete(), fn_trie_select_default()
+	The route manipulation functions. Should conform pretty closely to the
+	corresponding functions in fib_hash.
+
+fn_trie_flush()
+	This walks the full trie (using nextleaf()) and searches for empty
+	leaves which have to be removed.
+
+fn_trie_dump()
+	Dumps the routing table ordered by prefix length. This is somewhat
+	slower than the corresponding fib_hash function, as we have to walk the
+	entire trie for each prefix length. In comparison, fib_hash is organized
+	as one "zone"/hash per prefix length.
+
+Locking
+-------
+
+fib_lock is used for an RW-lock in the same way that this is done in fib_hash.
+However, the functions are somewhat separated for other possible locking
+scenarios. It might conceivably be possible to run trie_rebalance via RCU
+to avoid read_lock in the fn_trie_lookup() function.
+
+Main lookup mechanism
+---------------------
+fn_trie_lookup() is the main lookup function.
+
+The lookup is in its simplest form just like fib_find_node(). We descend the
+trie, key segment by key segment, until we find a leaf. check_leaf() does
+the fib_semantic_match in the leaf's sorted prefix hlist.
+
+If we find a match, we are done.
+
+If we don't find a match, we enter prefix matching mode. The prefix length,
+starting out at the same as the key length, is reduced one step at a time,
+and we backtrack upwards through the trie trying to find a longest matching
+prefix. The goal is always to reach a leaf and get a positive result from the
+fib_semantic_match mechanism.
+
+Inside each tnode, the search for longest matching prefix consists of searching
+through the child array, chopping off (zeroing) the least significant "1" of
+the child index until we find a match or the child index consists of nothing but
+zeros.
+
+At this point we backtrack (t->stats.backtrack++) up the trie, continuing to
+chop off part of the key in order to find the longest matching prefix.
+
+At this point we will repeatedly descend subtries to look for a match, and there
+are some optimizations available that can provide us with "shortcuts" to avoid
+descending into dead ends. Look for "HL_OPTIMIZE" sections in the code.
+
+To alleviate any doubts about the correctness of the route selection process,
+a new netlink operation has been added. Look for NETLINK_FIB_LOOKUP, which
+gives userland access to fib_lookup().
diff --git a/Documentation/networking/generic-hdlc.txt b/Documentation/networking/generic-hdlc.txt
--- a/Documentation/networking/generic-hdlc.txt
+++ b/Documentation/networking/generic-hdlc.txt
@@ -1,21 +1,21 @@
 Generic HDLC layer
 Krzysztof Halasa <khc@pm.waw.pl>
-January, 2003
 
 
 Generic HDLC layer currently supports:
-- Frame Relay (ANSI, CCITT and no LMI), with ARP support (no InARP).
-  Normal (routed) and Ethernet-bridged (Ethernet device emulation)
-  interfaces can share a single PVC.
-- raw HDLC - either IP (IPv4) interface or Ethernet device emulation.
-- Cisco HDLC,
-- PPP (uses syncppp.c),
-- X.25 (uses X.25 routines).
-
-There are hardware drivers for the following cards:
-- C101 by Moxa Technologies Co., Ltd.
-- RISCom/N2 by SDL Communications Inc.
-- and others, some not in the official kernel.
+1. Frame Relay (ANSI, CCITT, Cisco and no LMI).
+   - Normal (routed) and Ethernet-bridged (Ethernet device emulation)
+     interfaces can share a single PVC.
+   - ARP support (no InARP support in the kernel - there is an
+     experimental InARP user-space daemon available on:
+     http://www.kernel.org/pub/linux/utils/net/hdlc/).
+2. raw HDLC - either IP (IPv4) interface or Ethernet device emulation.
+3. Cisco HDLC.
+4. PPP (uses syncppp.c).
+5. X.25 (uses X.25 routines).
+
+Generic HDLC is a protocol driver only - it needs a low-level driver
+for your particular hardware.
 
 Ethernet device emulation (using HDLC or Frame-Relay PVC) is compatible
 with IEEE 802.1Q (VLANs) and 802.1D (Ethernet bridging).
@@ -24,7 +24,7 @@ with IEEE 802.1Q (VLANs) and 802.1D (Eth
 Make sure the hdlc.o and the hardware driver are loaded. It should
 create a number of "hdlc" (hdlc0 etc) network devices, one for each
 WAN port. You'll need the "sethdlc" utility, get it from:
-	http://hq.pm.waw.pl/hdlc/
+	http://www.kernel.org/pub/linux/utils/net/hdlc/
 
 Compile sethdlc.c utility:
 	gcc -O2 -Wall -o sethdlc sethdlc.c
@@ -52,12 +52,12 @@ Setting interface:
 * v35 | rs232 | x21 | t1 | e1 - sets physical interface for a given port
                                 if the card has software-selectable interfaces
   loopback - activate hardware loopback (for testing only)
-* clock ext - external clock (uses DTE RX and TX clock)
-* clock int - internal clock (provides clock signal on DCE clock output)
-* clock txint - TX internal, RX external (provides TX clock on DCE output)
-* clock txfromrx - TX clock derived from RX clock (TX clock on DCE output)
-* rate - sets clock rate in bps (not required for external clock or
-                                 for txfromrx)
+* clock ext - both RX clock and TX clock external
+* clock int - both RX clock and TX clock internal
+* clock txint - RX clock external, TX clock internal
+* clock txfromrx - RX clock external, TX clock derived from RX clock
+* rate - sets clock rate in bps (for "int" or "txint" clock only)
+
 
 Setting protocol:
 
@@ -79,7 +79,7 @@ Setting protocol:
 * x25 - sets X.25 mode
 
 * fr - Frame Relay mode
-  lmi ansi / ccitt / none - LMI (link management) type
+  lmi ansi / ccitt / cisco / none - LMI (link management) type
   dce - Frame Relay DCE (network) side LMI instead of default DTE (user).
   It has nothing to do with clocks!
   t391 - link integrity verification polling timer (in seconds) - user
@@ -119,13 +119,14 @@ or
 
 
 
-If you have a problem with N2 or C101 card, you can issue the "private"
-command to see port's packet descriptor rings (in kernel logs):
+If you have a problem with N2, C101 or PLX200SYN card, you can issue the
+"private" command to see port's packet descriptor rings (in kernel logs):
 
 	sethdlc hdlc0 private
 
-The hardware driver has to be build with CONFIG_HDLC_DEBUG_RINGS.
+The hardware driver has to be build with #define DEBUG_RINGS.
 Attaching this info to bug reports would be helpful. Anyway, let me know
 if you have problems using this.
 
-For patches and other info look at http://hq.pm.waw.pl/hdlc/
+For patches and other info look at:
+<http://www.kernel.org/pub/linux/utils/net/hdlc/>.
diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt
--- a/Documentation/networking/ip-sysctl.txt
+++ b/Documentation/networking/ip-sysctl.txt
@@ -304,57 +304,6 @@ tcp_low_latency - BOOLEAN
 	changed would be a Beowulf compute cluster.
 	Default: 0
 
-tcp_westwood - BOOLEAN
-        Enable TCP Westwood+ congestion control algorithm.
-	TCP Westwood+ is a sender-side only modification of the TCP Reno 
-	protocol stack that optimizes the performance of TCP congestion 
-	control. It is based on end-to-end bandwidth estimation to set 
-	congestion window and slow start threshold after a congestion 
-	episode. Using this estimation, TCP Westwood+ adaptively sets a 
-	slow start threshold and a congestion window which takes into 
-	account the bandwidth used  at the time congestion is experienced. 
-	TCP Westwood+ significantly increases fairness wrt TCP Reno in 
-	wired networks and throughput over wireless links.   
-        Default: 0
-
-tcp_vegas_cong_avoid - BOOLEAN
-	Enable TCP Vegas congestion avoidance algorithm.
-	TCP Vegas is a sender-side only change to TCP that anticipates
-	the onset of congestion by estimating the bandwidth. TCP Vegas
-	adjusts the sending rate by modifying the congestion
-	window. TCP Vegas should provide less packet loss, but it is
-	not as aggressive as TCP Reno.
-	Default:0
-
-tcp_bic - BOOLEAN
-	Enable BIC TCP congestion control algorithm.
-	BIC-TCP is a sender-side only change that ensures a linear RTT
-	fairness under large windows while offering both scalability and
-	bounded TCP-friendliness. The protocol combines two schemes
-	called additive increase and binary search increase. When the
-	congestion window is large, additive increase with a large
-	increment ensures linear RTT fairness as well as good
-	scalability. Under small congestion windows, binary search
-	increase provides TCP friendliness.
-	Default: 0
-
-tcp_bic_low_window - INTEGER
-	Sets the threshold window (in packets) where BIC TCP starts to
-	adjust the congestion window. Below this threshold BIC TCP behaves
-	the same as the default TCP Reno. 
-	Default: 14
-
-tcp_bic_fast_convergence - BOOLEAN
-	Forces BIC TCP to more quickly respond to changes in congestion
-	window. Allows two flows sharing the same connection to converge
-	more rapidly.
-	Default: 1
-
-tcp_default_win_scale - INTEGER
-	Sets the minimum window scale TCP will negotiate for on all
-	conections.
-	Default: 7
-
 tcp_tso_win_divisor - INTEGER
        This allows control over what percentage of the congestion window
        can be consumed by a single TSO frame.
@@ -368,6 +317,11 @@ tcp_frto - BOOLEAN
 	where packet loss is typically due to random radio interference
 	rather than intermediate router congestion.
 
+tcp_congestion_control - STRING
+	Set the congestion control algorithm to be used for new
+	connections. The algorithm "reno" is always available, but
+	additional choices may be available based on kernel configuration.
+
 somaxconn - INTEGER
 	Limit of socket listen() backlog, known in userspace as SOMAXCONN.
 	Defaults to 128.  See also tcp_max_syn_backlog for additional tuning
diff --git a/Documentation/networking/multicast.txt b/Documentation/networking/multicast.txt
--- a/Documentation/networking/multicast.txt
+++ b/Documentation/networking/multicast.txt
@@ -47,7 +47,6 @@ ni52		<------------------ Buggy --------
 ni65		YES		YES		YES		Software(#)
 seeq		NO		NO		NO		N/A
 sgiseek		<------------------ Buggy ------------------>
-sk_g16		NO		NO		YES		N/A
 smc-ultra	YES		YES		YES		Hardware
 sunlance	YES		YES		YES		Hardware
 tulip		YES		YES		YES		Hardware
diff --git a/Documentation/networking/net-modules.txt b/Documentation/networking/net-modules.txt
--- a/Documentation/networking/net-modules.txt
+++ b/Documentation/networking/net-modules.txt
@@ -284,9 +284,6 @@ ppp.c:
 seeq8005.c: *Not modularized*
 	(Probes ports: 0x300, 0x320, 0x340, 0x360)
 
-sk_g16.c: *Not modularized*
-	(Probes ports: 0x100, 0x180, 0x208, 0x220m 0x288, 0x320, 0x328, 0x390)
-
 skeleton.c: *Skeleton*
 
 slhc.c:
diff --git a/Documentation/networking/tcp.txt b/Documentation/networking/tcp.txt
--- a/Documentation/networking/tcp.txt
+++ b/Documentation/networking/tcp.txt
@@ -1,5 +1,72 @@
-How the new TCP output machine [nyi] works.
+TCP protocol
+============
+
+Last updated: 21 June 2005
+
+Contents
+========
 
+- Congestion control
+- How the new TCP output machine [nyi] works
+
+Congestion control
+==================
+
+The following variables are used in the tcp_sock for congestion control:
+snd_cwnd		The size of the congestion window
+snd_ssthresh		Slow start threshold. We are in slow start if
+			snd_cwnd is less than this.
+snd_cwnd_cnt		A counter used to slow down the rate of increase
+			once we exceed slow start threshold.
+snd_cwnd_clamp		This is the maximum size that snd_cwnd can grow to.
+snd_cwnd_stamp		Timestamp for when congestion window last validated.
+snd_cwnd_used		Used as a highwater mark for how much of the
+			congestion window is in use. It is used to adjust
+			snd_cwnd down when the link is limited by the
+			application rather than the network.
+
+As of 2.6.13, Linux supports pluggable congestion control algorithms.
+A congestion control mechanism can be registered through functions in
+tcp_cong.c. The functions used by the congestion control mechanism are
+registered via passing a tcp_congestion_ops struct to
+tcp_register_congestion_control. As a minimum name, ssthresh,
+cong_avoid, min_cwnd must be valid.
+
+Private data for a congestion control mechanism is stored in tp->ca_priv.
+tcp_ca(tp) returns a pointer to this space.  This is preallocated space - it
+is important to check the size of your private data will fit this space, or
+alternatively space could be allocated elsewhere and a pointer to it could
+be stored here.
+
+There are three kinds of congestion control algorithms currently: The
+simplest ones are derived from TCP reno (highspeed, scalable) and just
+provide an alternative the congestion window calculation. More complex
+ones like BIC try to look at other events to provide better
+heuristics.  There are also round trip time based algorithms like
+Vegas and Westwood+.
+
+Good TCP congestion control is a complex problem because the algorithm
+needs to maintain fairness and performance. Please review current
+research and RFC's before developing new modules.
+
+The method that is used to determine which congestion control mechanism is
+determined by the setting of the sysctl net.ipv4.tcp_congestion_control.
+The default congestion control will be the last one registered (LIFO);
+so if you built everything as modules. the default will be reno. If you
+build with the default's from Kconfig, then BIC will be builtin (not a module)
+and it will end up the default.
+
+If you really want a particular default value then you will need
+to set it with the sysctl.  If you use a sysctl, the module will be autoloaded
+if needed and you will get the expected protocol. If you ask for an
+unknown congestion method, then the sysctl attempt will fail.
+
+If you remove a tcp congestion control module, then you will get the next
+available one. Since reno can not be built as a module, and can not be
+deleted, it will always be available.
+
+How the new TCP output machine [nyi] works.
+===========================================
 
 Data is kept on a single queue. The skb->users flag tells us if the frame is
 one that has been queued already. To add a frame we throw it on the end. Ack
diff --git a/Documentation/networking/wanpipe.txt b/Documentation/networking/wanpipe.txt
deleted file mode 100644
--- a/Documentation/networking/wanpipe.txt
+++ /dev/null
@@ -1,622 +0,0 @@
-------------------------------------------------------------------------------
-Linux WAN Router Utilities Package
-------------------------------------------------------------------------------
-Version 2.2.1 
-Mar 28, 2001
-Author: Nenad Corbic <ncorbic@sangoma.com>
-Copyright (c) 1995-2001 Sangoma Technologies Inc.
-------------------------------------------------------------------------------
-
-INTRODUCTION
-
-Wide Area Networks (WANs) are used to interconnect Local Area Networks (LANs)
-and/or stand-alone hosts over vast distances with data transfer rates
-significantly higher than those achievable with commonly used dial-up
-connections.
-
-Usually an external device called `WAN router' sitting on your local network
-or connected to your machine's serial port provides physical connection to
-WAN.  Although router's job may be as simple as taking your local network
-traffic, converting it to WAN format and piping it through the WAN link, these
-devices are notoriously expensive, with prices as much as 2 - 5 times higher
-then the price of a typical PC box.
-
-Alternatively, considering robustness and multitasking capabilities of Linux,
-an internal router can be built (most routers use some sort of stripped down
-Unix-like operating system anyway). With a number of relatively inexpensive WAN
-interface cards available on the market, a perfectly usable router can be
-built for less than half a price of an external router.  Yet a Linux box
-acting as a router can still be used for other purposes, such as fire-walling,
-running FTP, WWW or DNS server, etc.
-
-This kernel module introduces the notion of a WAN Link Driver (WLD) to Linux
-operating system and provides generic hardware-independent services for such
-drivers.  Why can existing Linux network device interface not be used for
-this purpose?  Well, it can.  However, there are a few key differences between
-a typical network interface (e.g. Ethernet) and a WAN link.
-
-Many WAN protocols, such as X.25 and frame relay, allow for multiple logical
-connections (known as `virtual circuits' in X.25 terminology) over a single
-physical link.  Each such virtual circuit may (and almost always does) lead
-to a different geographical location and, therefore, different network.  As a
-result, it is the virtual circuit, not the physical link, that represents a
-route and, therefore, a network interface in Linux terms.
-
-To further complicate things, virtual circuits are usually volatile in nature
-(excluding so called `permanent' virtual circuits or PVCs).  With almost no
-time required to set up and tear down a virtual circuit, it is highly desirable
-to implement on-demand connections in order to minimize network charges.  So
-unlike a typical network driver, the WAN driver must be able to handle multiple
-network interfaces and cope as multiple virtual circuits come into existence
-and go away dynamically.
- 
-Last, but not least, WAN configuration is much more complex than that of say
-Ethernet and may well amount to several dozens of parameters.  Some of them
-are "link-wide"  while others are virtual circuit-specific.  The same holds
-true for WAN statistics which is by far more extensive and extremely useful
-when troubleshooting WAN connections.  Extending the ifconfig utility to suit
-these needs may be possible, but does not seem quite reasonable.  Therefore, a
-WAN configuration utility and corresponding application programmer's interface
-is needed for this purpose.
-
-Most of these problems are taken care of by this module.  Its goal is to
-provide a user with more-or-less standard look and feel for all WAN devices and
-assist a WAN device driver writer by providing common services, such as:
-
- o User-level interface via /proc file system
- o Centralized configuration
- o Device management (setup, shutdown, etc.)
- o Network interface management (dynamic creation/destruction)
- o Protocol encapsulation/decapsulation
-
-To ba able to use the Linux WAN Router you will also need a WAN Tools package
-available from
-
-	ftp.sangoma.com/pub/linux/current_wanpipe/wanpipe-X.Y.Z.tgz
-
-where vX.Y.Z represent the wanpipe version number.
-
-For technical questions and/or comments please e-mail to ncorbic@sangoma.com.
-For general inquiries please contact Sangoma Technologies Inc. by
-
-	Hotline:	1-800-388-2475	(USA and Canada, toll free)
-	Phone:		(905) 474-1990  ext: 106
-	Fax:		(905) 474-9223
-	E-mail:		dm@sangoma.com	(David Mandelstam)
-	WWW:		http://www.sangoma.com
-
-
-INSTALLATION
-
-Please read the WanpipeForLinux.pdf manual on how to 
-install the WANPIPE tools and drivers properly. 
-
-
-After installing wanpipe package: /usr/local/wanrouter/doc. 
-On the ftp.sangoma.com : /linux/current_wanpipe/doc
-
-
-COPYRIGHT AND LICENSING INFORMATION
-
-This program is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free Software
-Foundation; either version 2, 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.
-
-
-
-ACKNOWLEDGEMENTS
-
-This product is based on the WANPIPE(tm) Multiprotocol WAN Router developed
-by Sangoma Technologies Inc. for Linux 2.0.x and 2.2.x.  Success of the WANPIPE
-together with the next major release of Linux kernel in summer 1996 commanded
-adequate changes to the WANPIPE code to take full advantage of new Linux
-features.
-
-Instead of continuing developing proprietary interface tied to Sangoma WAN
-cards, we decided to separate all hardware-independent code into a separate
-module and defined two levels of interfaces - one for user-level applications
-and another for kernel-level WAN drivers.  WANPIPE is now implemented as a
-WAN driver compliant with the WAN Link Driver interface.  Also a general
-purpose WAN configuration utility and a set of shell scripts was developed to 
-support WAN router at the user level.
-
-Many useful ideas concerning hardware-independent interface implementation
-were given by Mike McLagan <mike.mclagan@linux.org> and his implementation
-of the Frame Relay router and drivers for Sangoma cards (dlci/sdla).
-
-With the new implementation of the APIs being incorporated into the WANPIPE,
-a special thank goes to Alan Cox in providing insight into BSD sockets.
-
-Special thanks to all the WANPIPE users who performed field-testing, reported
-bugs and made valuable comments and suggestions that help us to improve this
-product.
-
-
-
-NEW IN THIS RELEASE
-
-	o Updated the WANCFG utility
-		Calls the pppconfig to configure the PPPD
-		for async connections.
-
-	o Added the PPPCONFIG utility
-		Used to configure the PPPD dameon for the
-		WANPIPE Async PPP and standard serial port.
-		The wancfg calls the pppconfig to configure
-		the pppd.
-
-	o Fixed the PCI autodetect feature.  
-		The SLOT 0 was used as an autodetect option
-		however, some high end PC's slot numbers start
-		from 0. 
-
-	o This release has been tested with the new backupd
-	  daemon release.
-	
-
-PRODUCT COMPONENTS AND RELATED FILES
-
-/etc: (or user defined)
-	wanpipe1.conf	default router configuration file
-
-/lib/modules/X.Y.Z/misc:
-	wanrouter.o	router kernel loadable module
-	af_wanpipe.o	wanpipe api socket module
-
-/lib/modules/X.Y.Z/net:
-	sdladrv.o	Sangoma SDLA support module
-	wanpipe.o	Sangoma WANPIPE(tm) driver module
-
-/proc/net/wanrouter
-	Config		reads current router configuration
-	Status		reads current router status
-	{name}		reads WAN driver statistics
-
-/usr/sbin:
-	wanrouter	wanrouter start-up script
-	wanconfig	wanrouter configuration utility
-	sdladump	WANPIPE adapter memory dump utility
-        fpipemon        Monitor for Frame Relay
-        cpipemon        Monitor for Cisco HDLC
-	ppipemon 	Monitor for PPP
-	xpipemon 	Monitor for X25
-	wpkbdmon        WANPIPE keyboard led monitor/debugger
-
-/usr/local/wanrouter:
-	README		this file
-	COPYING		GNU General Public License
-	Setup		installation script
-	Filelist	distribution definition file
-	wanrouter.rc	meta-configuration file 
-			(used by the Setup and wanrouter script)
-
-/usr/local/wanrouter/doc:
-	wanpipeForLinux.pdf 	WAN Router User's Manual
-
-/usr/local/wanrouter/patches:
-	wanrouter-v2213.gz  	patch for Linux kernels 2.2.11 up to 2.2.13.
-	wanrouter-v2214.gz	patch for Linux kernel 2.2.14. 
-	wanrouter-v2215.gz	patch for Linux kernels 2.2.15 to 2.2.17.
-	wanrouter-v2218.gz	patch for Linux kernels 2.2.18 and up.
-	wanrouter-v240.gz	patch for Linux kernel 2.4.0.  
-	wanrouter-v242.gz	patch for Linux kernel 2.4.2 and up.
-	wanrouter-v2034.gz	patch for Linux kernel 2.0.34
-	wanrouter-v2036.gz 	patch for Linux kernel 2.0.36 and up. 
-
-/usr/local/wanrouter/patches/kdrivers:
-	Sources of the latest WANPIPE device drivers.
-	These are used to UPGRADE the linux kernel to the newest
-	version if the kernel source has already been pathced with
-	WANPIPE drivers.
-
-/usr/local/wanrouter/samples:
-	interface	sample interface configuration file
-	wanpipe1.cpri 	CHDLC primary port
-     	wanpipe2.csec 	CHDLC secondary port
-     	wanpipe1.fr   	Frame Relay protocol
-     	wanpipe1.ppp  	PPP protocol ) 
-	wanpipe1.asy	CHDLC ASYNC protocol
-	wanpipe1.x25	X25 protocol
-	wanpipe1.stty	Sync TTY driver (Used by Kernel PPPD daemon)
-	wanpipe1.atty	Async TTY driver (Used by Kernel PPPD daemon)
-	wanrouter.rc	sample meta-configuration file
-
-/usr/local/wanrouter/util:
-	*		wan-tools utilities source code
-
-/usr/local/wanrouter/api/x25:
-	*		x25 api sample programs.
-/usr/local/wanrouter/api/chdlc:
-	*		chdlc api sample programs.
-/usr/local/wanrouter/api/fr:
-	*		fr api sample programs.
-/usr/local/wanrouter/config/wancfg:
-	wancfg		WANPIPE GUI configuration program.
-                        Creates wanpipe#.conf files. 
-/usr/local/wanrouter/config/cfgft1:
-	cfgft1		GUI CSU/DSU configuration program.
-
-/usr/include/linux:
-	wanrouter.h	router API definitions
-	wanpipe.h	WANPIPE API definitions
-	sdladrv.h	SDLA support module API definitions
-	sdlasfm.h	SDLA firmware module definitions
-	if_wanpipe.h	WANPIPE Socket definitions
-	if_wanpipe_common.h	WANPIPE Socket/Driver common definitions.
-	sdlapci.h	WANPIPE PCI definitions
-	
-
-/usr/src/linux/net/wanrouter:
-	*		wanrouter source code
-
-/var/log:
-	wanrouter	wanrouter start-up log (created by the Setup script)
-
-/var/lock:  (or /var/lock/subsys for RedHat)
-	wanrouter	wanrouter lock file (created by the Setup script)
-
-/usr/local/wanrouter/firmware:
-	fr514.sfm	Frame relay firmware for Sangoma S508/S514 card
-	cdual514.sfm	Dual Port Cisco HDLC firmware for Sangoma S508/S514 card
-	ppp514.sfm      PPP Firmware for Sangoma S508 and S514 cards
-	x25_508.sfm	X25 Firmware for Sangoma S508 card.
-
-
-REVISION HISTORY
-
-1.0.0	December 31, 1996	Initial version
-
-1.0.1	January 30, 1997	Status and statistics can be read via /proc
-				filesystem entries.
-
-1.0.2   April 30, 1997          Added UDP management via monitors.
-
-1.0.3	June 3, 1997		UDP management for multiple boards using Frame
-				Relay and PPP
-				Enabled continuous transmission of Configure 
-				Request Packet for PPP (for 508 only)
-				Connection Timeout for PPP changed from 900 to 0
-				Flow Control Problem fixed for Frame Relay
-
-1.0.4	July 10, 1997		S508/FT1 monitoring capability in fpipemon and
-				ppipemon utilities.
-				Configurable TTL for UDP packets.
-				Multicast and Broadcast IP source addresses are
-				silently discarded.
-
-1.0.5	July 28, 1997		Configurable T391,T392,N391,N392,N393 for Frame
-				Relay in router.conf.
-				Configurable Memory Address through router.conf 
-				for Frame Relay, PPP and X.25. (commenting this
- 				out enables auto-detection).
-				Fixed freeing up received buffers using kfree()
- 				for Frame Relay and X.25.
-				Protect sdla_peek() by calling save_flags(),
-				cli() and restore_flags().
-				Changed number of Trace elements from 32 to 20
-				Added DLCI specific data monitoring in FPIPEMON. 
-2.0.0	Nov 07, 1997		Implemented protection of RACE conditions by 
-				critical flags for FRAME RELAY and PPP.
-				DLCI List interrupt mode implemented.
-				IPX support in FRAME RELAY and PPP.
-				IPX Server Support (MARS)
-				More driver specific stats included in FPIPEMON
-				and PIPEMON.
-
-2.0.1	Nov 28, 1997		Bug Fixes for version 2.0.0.
-				Protection of "enable_irq()" while 
-				"disable_irq()" has been enabled from any other
-				routine (for Frame Relay, PPP and X25).
-				Added additional Stats for Fpipemon and Ppipemon
-				Improved Load Sharing for multiple boards
-
-2.0.2	Dec 09, 1997		Support for PAP and CHAP for ppp has been
-				implemented.
-
-2.0.3	Aug 15, 1998		New release supporting Cisco HDLC, CIR for Frame
-				relay, Dynamic IP assignment for PPP and Inverse
-				Arp support for Frame-relay.  Man Pages are 
-				included for better support and a new utility
-				for configuring FT1 cards.
-
-2.0.4	Dec 09, 1998	        Dual Port support for Cisco HDLC.
-				Support for HDLC (LAPB) API.
-				Supports BiSync Streaming code for S502E 
-				and S503 cards.
-				Support for Streaming HDLC API.
-				Provides a BSD socket interface for 
-				creating applications using BiSync
-   				streaming.        
-
-2.0.5   Aug 04, 1999 		CHDLC initializatin bug fix.
-				PPP interrupt driven driver: 
-  				Fix to the PPP line hangup problem.
-				New PPP firmware
-				Added comments to the startup SYSTEM ERROR messages
-				Xpipemon debugging application for the X25 protocol
-				New USER_MANUAL.txt
-				Fixed the odd boundary 4byte writes to the board.
-				BiSync Streaming code has been taken out.  
-				 Available as a patch.
-				Streaming HDLC API has been taken out.  
-				 Available as a patch.                 
-
-2.0.6   Aug 17, 1999		Increased debugging in statup scripts
-				Fixed insallation bugs from 2.0.5
-				Kernel patch works for both 2.2.10 and 2.2.11 kernels.
-				There is no functional difference between the two packages         
-
-2.0.7   Aug 26, 1999		o  Merged X25API code into WANPIPE.
-				o  Fixed a memeory leak for X25API
-				o  Updated the X25API code for 2.2.X kernels.
-				o  Improved NEM handling.   
-
-2.1.0	Oct 25, 1999		o New code for S514 PCI Card
-				o New CHDLC and Frame Relay drivers
-				o PPP and X25 are not supported in this release    
-
-2.1.1	Nov 30, 1999		o PPP support for S514 PCI Cards
-
-2.1.3   Apr 06, 2000		o Socket based x25api 
-				o Socket based chdlc api
-				o Socket based fr api
-				o Dual Port Receive only CHDLC support.
-				o Asynchronous CHDLC support (Secondary Port)
-				o cfgft1 GUI csu/dsu configurator
-				o wancfg GUI configuration file 
-				  configurator.
-				o Architectual directory changes.
-
-beta-2.1.4 Jul 2000		o Dynamic interface configuration:
-					Network interfaces reflect the state
-					of protocol layer.  If the protocol becomes
-					disconnected, driver will bring down
-					the interface.  Once the protocol reconnects
-					the interface will be brought up. 
-					
-					Note: This option is turned off by default.
-
-				o Dynamic wanrouter setup using 'wanconfig':
-					wanconfig utility can be used to
-					shutdown,restart,start or reconfigure 
-					a virtual circuit dynamically.
-				     
-					Frame Relay:  Each DLCI can be: 
-						      created,stopped,restarted and reconfigured
-						      dynamically using wanconfig.
-					
-						      ex: wanconfig card wanpipe1 dev wp1_fr16 up
-				  
-				o Wanrouter startup via command line arguments:
-					wanconfig also supports wanrouter startup via command line
-					arguments.  Thus, there is no need to create a wanpipe#.conf
-					configuration file.  
-
-				o Socket based x25api update/bug fixes.
-					Added support for LCN numbers greater than 255.
-					Option to pass up modem messages.
-					Provided a PCI IRQ check, so a single S514
-					card is guaranteed to have a non-sharing interrupt.
-
-				o Fixes to the wancfg utility.
-				o New FT1 debugging support via *pipemon utilities.
-				o Frame Relay ARP support Enabled.
-
-beta3-2.1.4 Jul 2000		o X25 M_BIT Problem fix.
-				o Added the Multi-Port PPP
-				  Updated utilites for the Multi-Port PPP.
-
-2.1.4	Aut 2000
-				o In X25API:
-					Maximum packet an application can send
-					to the driver has been extended to 4096 bytes.
-
-					Fixed the x25 startup bug. Enable 
-					communications only after all interfaces
-					come up.  HIGH SVC/PVC is used to calculate
-					the number of channels.
-					Enable protocol only after all interfaces
-					are enabled.
-
-				o Added an extra state to the FT1 config, kernel module.
-				o Updated the pipemon debuggers.
-
-				o Blocked the Multi-Port PPP from running on kernels
-				  2.2.16 or greater, due to syncppp kernel module
-				  change. 
-	  
-beta1-2.1.5 	Nov 15 2000
-				o Fixed the MulitPort PPP Support for kernels 2.2.16 and above.
-				  2.2.X kernels only
-
-				o Secured the driver UDP debugging calls
-					- All illegal netowrk debugging calls are reported to
-					  the log.
-					- Defined a set of allowed commands, all other denied.
-					
-				o Cpipemon
-					- Added set FT1 commands to the cpipemon. Thus CSU/DSU
-					  configuraiton can be performed using cpipemon.
-					  All systems that cannot run cfgft1 GUI utility should
-					  use cpipemon to configure the on board CSU/DSU.
-
-
-				o Keyboard Led Monitor/Debugger
-					- A new utilty /usr/sbin/wpkbdmon uses keyboard leds
-					  to convey operatinal statistic information of the 
-					  Sangoma WANPIPE cards.
-					NUM_LOCK    = Line State  (On=connected,    Off=disconnected)
-					CAPS_LOCK   = Tx data     (On=transmitting, Off=no tx data)
-					SCROLL_LOCK = Rx data     (On=receiving,    Off=no rx data
-					
-				o Hardware probe on module load and dynamic device allocation
-					- During WANPIPE module load, all Sangoma cards are probed
-					  and found information is printed in the /var/log/messages.
-					- If no cards are found, the module load fails.
-					- Appropriate number of devices are dynamically loaded 
-					  based on the number of Sangoma cards found.
-
-					  Note: The kernel configuraiton option 
-						CONFIG_WANPIPE_CARDS has been taken out.
-					
-				o Fixed the Frame Relay and Chdlc network interfaces so they are
-				  compatible with libpcap libraries.  Meaning, tcpdump, snort,
-				  ethereal, and all other packet sniffers and debuggers work on
-				  all WANPIPE netowrk interfaces.
-					- Set the network interface encoding type to ARPHRD_PPP.
-					  This tell the sniffers that data obtained from the
-					  network interface is in pure IP format.
-				  Fix for 2.2.X kernels only.
-				
-				o True interface encoding option for Frame Relay and CHDLC
-					- The above fix sets the network interface encoding
-					  type to ARPHRD_PPP, however some customers use
-					  the encoding interface type to determine the
-					  protocol running.  Therefore, the TURE ENCODING
-					  option will set the interface type back to the
-					  original value.  
-
-					  NOTE: If this option is used with Frame Relay and CHDLC
-						libpcap library support will be broken.  
-						i.e. tcpdump will not work.
-					Fix for 2.2.x Kernels only.
-						
-				o Ethernet Bridgind over Frame Relay
-					- The Frame Relay bridging has been developed by 
-					  Kristian Hoffmann and Mark Wells.  
-					- The Linux kernel bridge is used to send ethernet 
-					  data over the frame relay links.
-					For 2.2.X Kernels only.
-
-				o Added extensive 2.0.X support. Most new features of
-				  2.1.5 for protocols Frame Relay, PPP and CHDLC are
-				  supported under 2.0.X kernels. 
-
-beta1-2.2.0 	Dec 30 2000
-				o Updated drivers for 2.4.X kernels.
-				o Updated drivers for SMP support.
-				o X25API is now able to share PCI interrupts.
-				o Took out a general polling routine that was used
-				  only by X25API. 
-				o Added appropriate locks to the dynamic reconfiguration
-				  code.
-				o Fixed a bug in the keyboard debug monitor.
-
-beta2-2.2.0	Jan 8 2001
-				o Patches for 2.4.0 kernel
-				o Patches for 2.2.18 kernel
-				o Minor updates to PPP and CHLDC drivers.
-				  Note: No functinal difference. 
-
-beta3-2.2.9	Jan 10 2001
-				o I missed the 2.2.18 kernel patches in beta2-2.2.0
-				  release.  They are included in this release.
-
-Stable Release
-2.2.0		Feb 01 2001
-				o Bug fix in wancfg GUI configurator.
-					The edit function didn't work properly.
-
-
-bata1-2.2.1	Feb 09 2001
-			o WANPIPE TTY Driver emulation. 
-			  Two modes of operation Sync and Async.
-				Sync: Using the PPPD daemon, kernel SyncPPP layer
-				      and the Wanpipe sync TTY driver: a PPP protocol 
-				      connection can be established via Sangoma adapter, over
-				      a T1 leased line.
-			
-				      The 2.4.0 kernel PPP layer supports MULTILINK
-				      protocol, that can be used to bundle any number of Sangoma
-				      adapters (T1 lines) into one, under a single IP address.
-				      Thus, efficiently obtaining multiple T1 throughput. 
-
-				      NOTE: The remote side must also implement MULTILINK PPP
-					    protocol.
-
-				Async:Using the PPPD daemon, kernel AsyncPPP layer
-				      and the WANPIPE async TTY driver: a PPP protocol
-				      connection can be established via Sangoma adapter and
-				      a modem, over a telephone line.
-
-				      Thus, the WANPIPE async TTY driver simulates a serial
-				      TTY driver that would normally be used to interface the 
-				      MODEM to the linux kernel.
-				
-			o WANPIPE PPP Backup Utility
-				This utility will monitor the state of the PPP T1 line.
-				In case of failure, a dial up connection will be established
-				via pppd daemon, ether via a serial tty driver (serial port), 
-				or a WANPIPE async TTY driver (in case serial port is unavailable).
-				
-				Furthermore, while in dial up mode, the primary PPP T1 link
-				will be monitored for signs of life.  
-
-				If the PPP T1 link comes back to life, the dial up connection
-				will be shutdown and T1 line re-established.
-			
-
-			o New Setup installation script.
-				Option to UPGRADE device drivers if the kernel source has
-				already been patched with WANPIPE.
-
-				Option to COMPILE WANPIPE modules against the currently 
-				running kernel, thus no need for manual kernel and module
-				re-compilatin.
-			
-			o Updates and Bug Fixes to wancfg utility.
-
-bata2-2.2.1	Feb 20 2001
-
-			o Bug fixes to the CHDLC device drivers.
-				The driver had compilation problems under kernels
-				2.2.14 or lower.
-
-			o Bug fixes to the Setup installation script.
-				The device drivers compilation options didn't work
-				properly.
-
-			o Update to the wpbackupd daemon.  
-				Optimized the cross-over times, between the primary
-				link and the backup dialup.
-
-beta3-2.2.1	Mar 02 2001
-			o Patches for 2.4.2 kernel.
-
-			o Bug fixes to util/ make files.
-			o Bug fixes to the Setup installation script.
-
-			o Took out the backupd support and made it into
-			  as separate package.
-			  
-beta4-2.2.1     Mar 12 2001
-
-		o Fix to the Frame Relay Device driver.
-			IPSAC sends a packet of zero length
-			header to the frame relay driver.  The
-			driver tries to push its own 2 byte header
-			into the packet, which causes the driver to
-			crash.
-
-		o Fix the WANPIPE re-configuration code.
-			Bug was found by trying to run  the cfgft1 while the
-			interface was already running.  
-
-		o Updates to cfgft1.
-			Writes a wanpipe#.cfgft1 configuration file
-			once the CSU/DSU is configured. This file can
-			holds the current CSU/DSU configuration.
-
-
-
->>>>>> END OF README <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
-
-
diff --git a/Documentation/pci.txt b/Documentation/pci.txt
--- a/Documentation/pci.txt
+++ b/Documentation/pci.txt
@@ -266,20 +266,6 @@ port an old driver to the new PCI interf
 in the kernel as they aren't compatible with hotplug or PCI domains or
 having sane locking.
 
-pcibios_present() and		Since ages, you don't need to test presence
-pci_present()			of PCI subsystem when trying to talk to it.
-				If it's not there, the list of PCI devices
-				is empty and all functions for searching for
-				devices just return NULL.
-pcibios_(read|write)_*		Superseded by their pci_(read|write)_*
-				counterparts.
-pcibios_find_*			Superseded by their pci_get_* counterparts.
-pci_for_each_dev()		Superseded by pci_get_device()
-pci_for_each_dev_reverse()	Superseded by pci_find_device_reverse()
-pci_for_each_bus()		Superseded by pci_find_next_bus()
 pci_find_device()		Superseded by pci_get_device()
 pci_find_subsys()		Superseded by pci_get_subsys()
 pci_find_slot()			Superseded by pci_get_slot()
-pcibios_find_class()		Superseded by pci_get_class()
-pci_find_class()		Superseded by pci_get_class()
-pci_(read|write)_*_nodev()	Superseded by pci_bus_(read|write)_*()
diff --git a/Documentation/pcmcia/devicetable.txt b/Documentation/pcmcia/devicetable.txt
new file mode 100644
--- /dev/null
+++ b/Documentation/pcmcia/devicetable.txt
@@ -0,0 +1,63 @@
+Matching of PCMCIA devices to drivers is done using one or more of the
+following criteria:
+
+- manufactor ID
+- card ID
+- product ID strings _and_ hashes of these strings
+- function ID
+- device function (actual and pseudo)
+
+You should use the helpers in include/pcmcia/device_id.h for generating the
+struct pcmcia_device_id[] entries which match devices to drivers.
+
+If you want to match product ID strings, you also need to pass the crc32
+hashes of the string to the macro, e.g. if you want to match the product ID
+string 1, you need to use
+
+PCMCIA_DEVICE_PROD_ID1("some_string", 0x(hash_of_some_string)),
+
+If the hash is incorrect, the kernel will inform you about this in "dmesg"
+upon module initialization, and tell you of the correct hash.
+
+You can determine the hash of the product ID strings by catting the file
+"modalias" in the sysfs directory of the PCMCIA device. It generates a string
+in the following form:
+pcmcia:m0149cC1ABf06pfn00fn00pa725B842DpbF1EFEE84pc0877B627pd00000000
+
+The hex value after "pa" is the hash of product ID string 1, after "pb" for
+string 2 and so on.
+
+Alternatively, you can use this small tool to determine the crc32 hash.
+simply pass the string you want to evaluate as argument to this program,
+e.g.
+$ ./crc32hash "Dual Speed"
+
+-------------------------------------------------------------------------
+/* crc32hash.c - derived from linux/lib/crc32.c, GNU GPL v2 */
+#include <string.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+
+unsigned int crc32(unsigned char const *p, unsigned int len)
+{
+	int i;
+	unsigned int crc = 0;
+	while (len--) {
+		crc ^= *p++;
+		for (i = 0; i < 8; i++)
+			crc = (crc >> 1) ^ ((crc & 1) ? 0xedb88320 : 0);
+	}
+	return crc;
+}
+
+int main(int argc, char **argv) {
+	unsigned int result;
+	if (argc != 2) {
+		printf("no string passed as argument\n");
+		return -1;
+	}
+	result = crc32(argv[1], strlen(argv[1]));
+	printf("0x%x\n", result);
+	return 0;
+}
diff --git a/Documentation/pcmcia/driver-changes.txt b/Documentation/pcmcia/driver-changes.txt
new file mode 100644
--- /dev/null
+++ b/Documentation/pcmcia/driver-changes.txt
@@ -0,0 +1,67 @@
+This file details changes in 2.6 which affect PCMCIA card driver authors:
+
+* event handler initialization in struct pcmcia_driver (as of 2.6.13)
+   The event handler is notified of all events, and must be initialized
+   as the event() callback in the driver's struct pcmcia_driver.
+
+* pcmcia/version.h should not be used (as of 2.6.13)
+   This file will be removed eventually.
+
+* in-kernel device<->driver matching (as of 2.6.13)
+   PCMCIA devices and their correct drivers can now be matched in
+   kernelspace. See 'devicetable.txt' for details.
+
+* Device model integration (as of 2.6.11)
+   A struct pcmcia_device is registered with the device model core,
+   and can be used (e.g. for SET_NETDEV_DEV) by using
+   handle_to_dev(client_handle_t * handle).
+
+* Convert internal I/O port addresses to unsigned long (as of 2.6.11)
+   ioaddr_t should be replaced by kio_addr_t in PCMCIA card drivers.
+
+* irq_mask and irq_list parameters (as of 2.6.11)
+   The irq_mask and irq_list parameters should no longer be used in
+   PCMCIA card drivers. Instead, it is the job of the PCMCIA core to
+   determine which IRQ should be used. Therefore, link->irq.IRQInfo2
+   is ignored.
+
+* client->PendingEvents is gone (as of 2.6.11)
+   client->PendingEvents is no longer available.
+
+* client->Attributes are gone (as of 2.6.11)
+   client->Attributes is unused, therefore it is removed from all
+   PCMCIA card drivers
+
+* core functions no longer available (as of 2.6.11)
+   The following functions have been removed from the kernel source
+   because they are unused by all in-kernel drivers, and no external
+   driver was reported to rely on them:
+	pcmcia_get_first_region()
+	pcmcia_get_next_region()
+	pcmcia_modify_window()
+	pcmcia_set_event_mask()
+	pcmcia_get_first_window()
+	pcmcia_get_next_window()
+
+* device list iteration upon module removal (as of 2.6.10)
+   It is no longer necessary to iterate on the driver's internal
+   client list and call the ->detach() function upon module removal.
+
+* Resource management. (as of 2.6.8)
+   Although the PCMCIA subsystem will allocate resources for cards,
+   it no longer marks these resources busy. This means that driver
+   authors are now responsible for claiming your resources as per
+   other drivers in Linux. You should use request_region() to mark
+   your IO regions in-use, and request_mem_region() to mark your
+   memory regions in-use. The name argument should be a pointer to
+   your driver name. Eg, for pcnet_cs, name should point to the
+   string "pcnet_cs".
+
+* CardServices is gone
+  CardServices() in 2.4 is just a big switch statement to call various
+  services.  In 2.6, all of those entry points are exported and called
+  directly (except for pcmcia_report_error(), just use cs_error() instead).
+
+* struct pcmcia_driver
+  You need to use struct pcmcia_driver and pcmcia_{un,}register_driver
+  instead of {un,}register_pccard_driver
diff --git a/Documentation/power/kernel_threads.txt b/Documentation/power/kernel_threads.txt
--- a/Documentation/power/kernel_threads.txt
+++ b/Documentation/power/kernel_threads.txt
@@ -12,8 +12,7 @@ refrigerator. Code to do this looks like
 	do {
 		hub_events();
 		wait_event_interruptible(khubd_wait, !list_empty(&hub_event_list));
-		if (current->flags & PF_FREEZE)
-			refrigerator(PF_FREEZE);
+		try_to_freeze();
 	} while (!signal_pending(current));
 
 from drivers/usb/core/hub.c::hub_thread()
diff --git a/Documentation/power/pci.txt b/Documentation/power/pci.txt
--- a/Documentation/power/pci.txt
+++ b/Documentation/power/pci.txt
@@ -291,6 +291,44 @@ a request to enable wake events from D3,
 pci_enable_wake (one for both D3hot and D3cold).
 
 
+A reference implementation
+-------------------------
+.suspend()
+{
+	/* driver specific operations */
+
+	/* Disable IRQ */
+	free_irq();
+	/* If using MSI */
+	pci_disable_msi();
+
+	pci_save_state();
+	pci_enable_wake();
+	/* Disable IO/bus master/irq router */
+	pci_disable_device();
+	pci_set_power_state(pci_choose_state());
+}
+
+.resume()
+{
+	pci_set_power_state(PCI_D0);
+	pci_restore_state();
+	/* device's irq possibly is changed, driver should take care */
+	pci_enable_device();
+	pci_set_master();
+
+	/* if using MSI, device's vector possibly is changed */
+	pci_enable_msi();
+
+	request_irq();
+	/* driver specific operations; */
+}
+
+This is a typical implementation. Drivers can slightly change the order
+of the operations in the implementation, ignore some operations or add
+more deriver specific operations in it, but drivers should do something like
+this on the whole.
+
 5. Resources
 ~~~~~~~~~~~~
 
diff --git a/Documentation/power/swsusp.txt b/Documentation/power/swsusp.txt
--- a/Documentation/power/swsusp.txt
+++ b/Documentation/power/swsusp.txt
@@ -164,11 +164,11 @@ place where the thread is safe to be fro
 should be held at that point and it must be safe to sleep there), and
 add:
 
-            if (current->flags & PF_FREEZE)
-                    refrigerator(PF_FREEZE);
+       try_to_freeze();
 
 If the thread is needed for writing the image to storage, you should
-instead set the PF_NOFREEZE process flag when creating the thread.
+instead set the PF_NOFREEZE process flag when creating the thread (and
+be very carefull).
 
 
 Q: What is the difference between between "platform", "shutdown" and
@@ -233,3 +233,81 @@ A: Try running
 cat `cat /proc/[0-9]*/maps | grep / | sed 's:.* /:/:' | sort -u` > /dev/null
 
 after resume. swapoff -a; swapon -a may also be usefull.
+
+Q: What happens to devices during swsusp? They seem to be resumed
+during system suspend?
+
+A: That's correct. We need to resume them if we want to write image to
+disk. Whole sequence goes like
+
+      Suspend part
+      ~~~~~~~~~~~~
+      running system, user asks for suspend-to-disk
+
+      user processes are stopped
+
+      suspend(PMSG_FREEZE): devices are frozen so that they don't interfere
+      		      with state snapshot
+
+      state snapshot: copy of whole used memory is taken with interrupts disabled
+
+      resume(): devices are woken up so that we can write image to swap
+
+      write image to swap
+
+      suspend(PMSG_SUSPEND): suspend devices so that we can power off
+
+      turn the power off
+
+      Resume part
+      ~~~~~~~~~~~
+      (is actually pretty similar)
+
+      running system, user asks for suspend-to-disk
+
+      user processes are stopped (in common case there are none, but with resume-from-initrd, noone knows)
+
+      read image from disk
+
+      suspend(PMSG_FREEZE): devices are frozen so that they don't interfere
+      		      with image restoration
+
+      image restoration: rewrite memory with image
+
+      resume(): devices are woken up so that system can continue
+
+      thaw all user processes
+
+Q: What is this 'Encrypt suspend image' for?
+
+A: First of all: it is not a replacement for dm-crypt encrypted swap.
+It cannot protect your computer while it is suspended. Instead it does
+protect from leaking sensitive data after resume from suspend.
+
+Think of the following: you suspend while an application is running
+that keeps sensitive data in memory. The application itself prevents
+the data from being swapped out. Suspend, however, must write these
+data to swap to be able to resume later on. Without suspend encryption
+your sensitive data are then stored in plaintext on disk.  This means
+that after resume your sensitive data are accessible to all
+applications having direct access to the swap device which was used
+for suspend. If you don't need swap after resume these data can remain
+on disk virtually forever. Thus it can happen that your system gets
+broken in weeks later and sensitive data which you thought were
+encrypted and protected are retrieved and stolen from the swap device.
+To prevent this situation you should use 'Encrypt suspend image'.
+
+During suspend a temporary key is created and this key is used to
+encrypt the data written to disk. When, during resume, the data was
+read back into memory the temporary key is destroyed which simply
+means that all data written to disk during suspend are then
+inaccessible so they can't be stolen later on.  The only thing that
+you must then take care of is that you call 'mkswap' for the swap
+partition used for suspend as early as possible during regular
+boot. This asserts that any temporary key from an oopsed suspend or
+from a failed or aborted resume is erased from the swap device.
+
+As a rule of thumb use encrypted swap to protect your data while your
+system is shut down or suspended. Additionally use the encrypted
+suspend image to prevent sensitive data from being stolen after
+resume.
diff --git a/Documentation/power/video.txt b/Documentation/power/video.txt
--- a/Documentation/power/video.txt
+++ b/Documentation/power/video.txt
@@ -83,8 +83,10 @@ Compaq Armada E500 - P3-700     none (1)
 Compaq Evo N620c		vga=normal, s3_bios (2)
 Dell 600m, ATI R250 Lf		none (1), but needs xorg-x11-6.8.1.902-1
 Dell D600, ATI RV250            vga=normal and X, or try vbestate (6)
+Dell D610			vga=normal and X (possibly vbestate (6) too, but not tested)
 Dell Inspiron 4000		??? (*)
 Dell Inspiron 500m		??? (*)
+Dell Inspiron 510m		???
 Dell Inspiron 600m		??? (*)
 Dell Inspiron 8200		??? (*)
 Dell Inspiron 8500		??? (*)
@@ -115,6 +117,7 @@ IBM Thinkpad X40 Type 2371-7JG  s3_bios,
 Medion MD4220			??? (*)
 Samsung P35			vbetool needed (6)
 Sharp PC-AR10 (ATI rage)	none (1)
+Sony Vaio PCG-C1VRX/K		s3_bios (2)
 Sony Vaio PCG-F403		??? (*)
 Sony Vaio PCG-N505SN		??? (*)
 Sony Vaio vgn-s260		X or boot-radeon can init it (5)
@@ -123,6 +126,7 @@ Toshiba Satellite 4030CDT	s3_mode (3)
 Toshiba Satellite 4080XCDT      s3_mode (3)
 Toshiba Satellite 4090XCDT      ??? (*)
 Toshiba Satellite P10-554       s3_bios,s3_mode (4)(****)
+Toshiba M30                     (2) xor X with nvidia driver using internal AGP
 Uniwill 244IIO			??? (*)
 
 
diff --git a/Documentation/power/video_extension.txt b/Documentation/power/video_extension.txt
--- a/Documentation/power/video_extension.txt
+++ b/Documentation/power/video_extension.txt
@@ -1,13 +1,16 @@
-This driver implement the ACPI Extensions For Display Adapters
-for integrated graphics devices on motherboard, as specified in
-ACPI 2.0 Specification, Appendix B, allowing to perform some basic
-control like defining the video POST device, retrieving EDID information
-or to setup a video output, etc.  Note that this is an ref. implementation only.
-It may or may not work for your integrated video device.
+ACPI video extensions
+~~~~~~~~~~~~~~~~~~~~~
+
+This driver implement the ACPI Extensions For Display Adapters for
+integrated graphics devices on motherboard, as specified in ACPI 2.0
+Specification, Appendix B, allowing to perform some basic control like
+defining the video POST device, retrieving EDID information or to
+setup a video output, etc.  Note that this is an ref. implementation
+only.  It may or may not work for your integrated video device.
 
 Interfaces exposed to userland through /proc/acpi/video:
 
-VGA/info : display the supported video bus device capability like ,Video ROM, CRT/LCD/TV.
+VGA/info : display the supported video bus device capability like Video ROM, CRT/LCD/TV.
 VGA/ROM :  Used to get a copy of the display devices' ROM data (up to 4k).
 VGA/POST_info : Used to determine what options are implemented.
 VGA/POST : Used to get/set POST device.
@@ -15,7 +18,7 @@ VGA/DOS : Used to get/set ownership of o
 	Please refer ACPI spec B.4.1 _DOS
 VGA/CRT : CRT output
 VGA/LCD : LCD output
-VGA/TV : TV output 
+VGA/TVO : TV output
 VGA/*/brightness : Used to get/set brightness of output device
 
 Notify event through /proc/acpi/event:
diff --git a/Documentation/s390/CommonIO b/Documentation/s390/CommonIO
--- a/Documentation/s390/CommonIO
+++ b/Documentation/s390/CommonIO
@@ -30,7 +30,7 @@ Command line parameters
   device numbers (0xabcd or abcd, for 2.4 backward compatibility).
   You can use the 'all' keyword to ignore all devices.
   The '!' operator will cause the I/O-layer to _not_ ignore a device.
-  The order on the command line is not important.
+  The command line is parsed from left to right.
 
   For example, 
 	cio_ignore=0.0.0023-0.0.0042,0.0.4711
@@ -72,13 +72,14 @@ Command line parameters
   /proc/cio_ignore; "add <device range>, <device range>, ..." will ignore the
   specified devices.
 
-  Note: Already known devices cannot be ignored.
+  Note: While already known devices can be added to the list of devices to be
+        ignored, there will be no effect on then. However, if such a device
+        disappears and then reappeares, it will then be ignored.
 
-  For example, if device 0.0.abcd is already known and all other devices
-  0.0.a000-0.0.afff are not known,
+  For example,
 	"echo add 0.0.a000-0.0.accc, 0.0.af00-0.0.afff > /proc/cio_ignore"
-  will add 0.0.a000-0.0.abcc, 0.0.abce-0.0.accc and 0.0.af00-0.0.afff to the
-  list of ignored devices and skip 0.0.abcd.
+  will add 0.0.a000-0.0.accc and 0.0.af00-0.0.afff to the list of ignored
+  devices.
 
   The devices can be specified either by bus id (0.0.abcd) or, for 2.4 backward
   compatibilty, by the device number in hexadecimal (0xabcd or abcd).
@@ -98,7 +99,8 @@ Command line parameters
 
   - /proc/s390dbf/cio_trace/hex_ascii
     Logs the calling of functions in the common I/O-layer and, if applicable, 
-    which subchannel they were called for.
+    which subchannel they were called for, as well as dumps of some data
+    structures (like irb in an error case).
 
   The level of logging can be changed to be more or less verbose by piping to 
   /proc/s390dbf/cio_*/level a number between 0 and 6; see the documentation on
diff --git a/Documentation/s390/s390dbf.txt b/Documentation/s390/s390dbf.txt
--- a/Documentation/s390/s390dbf.txt
+++ b/Documentation/s390/s390dbf.txt
@@ -12,8 +12,8 @@ where log records can be stored efficien
 One purpose of this is to inspect the debug logs after a production system crash
 in order to analyze the reason for the crash.
 If the system still runs but only a subcomponent which uses dbf failes,
-it is possible to look at the debug logs on a live system via the Linux proc
-filesystem.
+it is possible to look at the debug logs on a live system via the Linux
+debugfs filesystem.
 The debug feature may also very useful for kernel and driver development.
 
 Design:
@@ -52,16 +52,18 @@ Each debug entry contains the following 
 - Flag, if entry is an exception or not
 
 The debug logs can be inspected in a live system through entries in
-the proc-filesystem. Under the path /proc/s390dbf there is 
+the debugfs-filesystem. Under the toplevel directory "s390dbf" there is
 a directory for each registered component, which is named like the
-corresponding component.
+corresponding component. The debugfs normally should be mounted to
+/sys/kernel/debug therefore the debug feature can be accessed unter
+/sys/kernel/debug/s390dbf.
 
 The content of the directories are files which represent different views
 to the debug log. Each component can decide which views should be
 used through registering them with the function debug_register_view().
 Predefined views for hex/ascii, sprintf and raw binary data are provided.
 It is also possible to define other views. The content of
-a view can be inspected simply by reading the corresponding proc file.
+a view can be inspected simply by reading the corresponding debugfs file.
 
 All debug logs have an an actual debug level (range from 0 to 6).
 The default level is 3. Event and Exception functions have a 'level'
@@ -69,14 +71,14 @@ parameter. Only debug entries with a lev
 than the actual level are written to the log. This means, when
 writing events, high priority log entries should have a low level
 value whereas low priority entries should have a high one.
-The actual debug level can be changed with the help of the proc-filesystem 
-through writing a number string "x" to the 'level' proc file which is
+The actual debug level can be changed with the help of the debugfs-filesystem
+through writing a number string "x" to the 'level' debugfs file which is
 provided for every debug log. Debugging can be switched off completely
-by using "-" on the 'level' proc file.
+by using "-" on the 'level' debugfs file.
 
 Example:
 
-> echo "-" > /proc/s390dbf/dasd/level
+> echo "-" > /sys/kernel/debug/s390dbf/dasd/level
 
 It is also possible to deactivate the debug feature globally for every
 debug log. You can change the behavior using  2 sysctl parameters in
@@ -99,11 +101,11 @@ Kernel Interfaces:
 ------------------
 
 ----------------------------------------------------------------------------
-debug_info_t *debug_register(char *name, int pages_index, int nr_areas,
+debug_info_t *debug_register(char *name, int pages, int nr_areas,
                              int buf_size);
 
-Parameter:    name:        Name of debug log (e.g. used for proc entry) 
-              pages_index: 2^pages_index pages will be allocated per area
+Parameter:    name:        Name of debug log (e.g. used for debugfs entry)
+              pages:       number of pages, which will be allocated per area
               nr_areas:    number of debug areas
               buf_size:    size of data area in each debug entry
 
@@ -134,7 +136,7 @@ Return Value:  none 
 Description:   Sets new actual debug level if new_level is valid. 
 
 ---------------------------------------------------------------------------
-+void debug_stop_all(void);
+void debug_stop_all(void);
 
 Parameter:     none
 
@@ -270,7 +272,7 @@ Parameter:     id:    handle for debug l
 Return Value:  0  : ok 
                < 0: Error 
 
-Description:   registers new debug view and creates proc dir entry 
+Description:   registers new debug view and creates debugfs dir entry
 
 ---------------------------------------------------------------------------
 int debug_unregister_view (debug_info_t * id, struct debug_view *view); 
@@ -281,7 +283,7 @@ Parameter:     id:    handle for debug l
 Return Value:  0  : ok 
                < 0: Error 
 
-Description:   unregisters debug view and removes proc dir entry 
+Description:   unregisters debug view and removes debugfs dir entry
 
 
 
@@ -308,7 +310,7 @@ static int init(void)
 {
     /* register 4 debug areas with one page each and 4 byte data field */
 
-    debug_info = debug_register ("test", 0, 4, 4 );
+    debug_info = debug_register ("test", 1, 4, 4 );
     debug_register_view(debug_info,&debug_hex_ascii_view);
     debug_register_view(debug_info,&debug_raw_view);
 
@@ -343,7 +345,7 @@ static int init(void)
     /* register 4 debug areas with one page each and data field for */
     /* format string pointer + 2 varargs (= 3 * sizeof(long))       */
 
-    debug_info = debug_register ("test", 0, 4, sizeof(long) * 3);
+    debug_info = debug_register ("test", 1, 4, sizeof(long) * 3);
     debug_register_view(debug_info,&debug_sprintf_view);
 
     debug_sprintf_event(debug_info, 2 , "first event in %s:%i\n",__FILE__,__LINE__);
@@ -362,16 +364,16 @@ module_exit(cleanup);
 
 
 
-ProcFS Interface
+Debugfs Interface
 ----------------
 Views to the debug logs can be investigated through reading the corresponding 
-proc-files:
+debugfs-files:
 
 Example:
 
-> ls /proc/s390dbf/dasd
-flush  hex_ascii  level      raw 
-> cat /proc/s390dbf/dasd/hex_ascii | sort +1
+> ls /sys/kernel/debug/s390dbf/dasd
+flush  hex_ascii  level pages raw
+> cat /sys/kernel/debug/s390dbf/dasd/hex_ascii | sort +1
 00 00974733272:680099 2 - 02 0006ad7e  07 ea 4a 90 | ....
 00 00974733272:682210 2 - 02 0006ade6  46 52 45 45 | FREE
 00 00974733272:682213 2 - 02 0006adf6  07 ea 4a 90 | ....
@@ -391,25 +393,36 @@ Changing the debug level
 Example:
 
 
-> cat /proc/s390dbf/dasd/level
+> cat /sys/kernel/debug/s390dbf/dasd/level
 3
-> echo "5" > /proc/s390dbf/dasd/level
-> cat /proc/s390dbf/dasd/level
+> echo "5" > /sys/kernel/debug/s390dbf/dasd/level
+> cat /sys/kernel/debug/s390dbf/dasd/level
 5
 
 Flushing debug areas
 --------------------
 Debug areas can be flushed with piping the number of the desired
-area (0...n) to the proc file "flush". When using "-" all debug areas
+area (0...n) to the debugfs file "flush". When using "-" all debug areas
 are flushed.
 
 Examples:
 
 1. Flush debug area 0:
-> echo "0" > /proc/s390dbf/dasd/flush  
+> echo "0" > /sys/kernel/debug/s390dbf/dasd/flush
 
 2. Flush all debug areas:
-> echo "-" > /proc/s390dbf/dasd/flush
+> echo "-" > /sys/kernel/debug/s390dbf/dasd/flush
+
+Changing the size of debug areas
+------------------------------------
+It is possible the change the size of debug areas through piping
+the number of pages to the debugfs file "pages". The resize request will
+also flush the debug areas.
+
+Example:
+
+Define 4 pages for the debug areas of debug feature "dasd":
+> echo "4" > /sys/kernel/debug/s390dbf/dasd/pages
 
 Stooping the debug feature
 --------------------------
@@ -491,7 +504,7 @@ Defining views
 --------------
 
 Views are specified with the 'debug_view' structure. There are defined
-callback functions which are used for reading and writing the proc files:
+callback functions which are used for reading and writing the debugfs files:
 
 struct debug_view {
         char name[DEBUG_MAX_PROCF_LEN];  
@@ -525,7 +538,7 @@ typedef int (debug_input_proc_t) (debug_
 The "private_data" member can be used as pointer to view specific data.
 It is not used by the debug feature itself.
 
-The output when reading a debug-proc file is structured like this:
+The output when reading a debugfs file is structured like this:
 
 "prolog_proc output"
 
@@ -534,13 +547,13 @@ The output when reading a debug-proc fil
 "header_proc output 3"  "format_proc output 3"
 ...
 
-When a view is read from the proc fs, the Debug Feature calls the 
+When a view is read from the debugfs, the Debug Feature calls the
 'prolog_proc' once for writing the prolog.
 Then 'header_proc' and 'format_proc' are called for each 
 existing debug entry.
 
 The input_proc can be used to implement functionality when it is written to 
-the view (e.g. like with 'echo "0" > /proc/s390dbf/dasd/level).
+the view (e.g. like with 'echo "0" > /sys/kernel/debug/s390dbf/dasd/level).
 
 For header_proc there can be used the default function
 debug_dflt_header_fn() which is defined in in debug.h.
@@ -602,7 +615,7 @@ debug_info = debug_register ("test", 0, 
 debug_register_view(debug_info, &debug_test_view);
 for(i = 0; i < 10; i ++) debug_int_event(debug_info, 1, i);
 
-> cat /proc/s390dbf/test/myview
+> cat /sys/kernel/debug/s390dbf/test/myview
 00 00964419734:611402 1 - 00 88042ca   This error...........
 00 00964419734:611405 1 - 00 88042ca   That error...........
 00 00964419734:611408 1 - 00 88042ca   Problem..............
diff --git a/Documentation/scsi/ChangeLog.megaraid b/Documentation/scsi/ChangeLog.megaraid
--- a/Documentation/scsi/ChangeLog.megaraid
+++ b/Documentation/scsi/ChangeLog.megaraid
@@ -1,3 +1,69 @@
+Release Date	: Mon Mar 07 12:27:22 EST 2005 - Seokmann Ju <sju@lsil.com>
+Current Version : 2.20.4.6 (scsi module), 2.20.2.6 (cmm module)
+Older Version	: 2.20.4.5 (scsi module), 2.20.2.5 (cmm module)
+
+1.	Added IOCTL backward compatibility.
+	Convert megaraid_mm driver to new compat_ioctl entry points.
+	I don't have easy access to hardware, so only compile tested.
+		- Signed-off-by:Andi Kleen <ak@muc.de>
+
+2.	megaraid_mbox fix: wrong order of arguments in memset()
+	That, BTW, shows why cross-builds are useful-the only indication of
+	problem had been a new warning showing up in sparse output on alpha
+	build (number of exceeding 256 got truncated).
+		- Signed-off-by: Al Viro
+		<viro@parcelfarce.linux.theplanet.co.uk>
+
+3.	Convert pci_module_init to pci_register_driver
+	Convert from pci_module_init to pci_register_driver
+	(from:http://kerneljanitors.org/TODO)
+		- Signed-off-by: Domen Puncer <domen@coderock.org>
+
+4.	Use the pre defined DMA mask constants from dma-mapping.h
+	Use the DMA_{64,32}BIT_MASK constants from dma-mapping.h when calling
+	pci_set_dma_mask() or pci_set_consistend_dma_mask(). See
+	http://marc.theaimsgroup.com/?t=108001993000001&r=1&w=2 for more
+	details.
+		Signed-off-by: Tobias Klauser <tklauser@nuerscht.ch>
+		Signed-off-by: Domen Puncer <domen@coderock.org>
+
+5.	Remove SSID checking for Dobson, Lindsay, and Verde based products.
+	Checking the SSVID/SSID for controllers which have Dobson, Lindsay,
+	and Verde is unnecessary because device ID has been assigned by LSI
+	and it is unique value. So, all controllers with these IOPs have to be
+	supported by the driver regardless SSVID/SSID.
+
+6.	Date Thu, 27 Jan 2005 04:31:09 +0100 
+	From Herbert Poetzl <> 
+	Subject RFC: assert_spin_locked() for 2.6 
+
+	Greetings!
+
+	overcautious programming will kill your kernel ;)
+	ever thought about checking a spin_lock or even
+	asserting that it must be held (maybe just for
+	spinlock debugging?) ...
+
+	there are several checks present in the kernel
+	where somebody does a variation on the following:
+
+	  BUG_ON(!spin_is_locked(&some_lock));
+
+	so what's wrong about that? nothing, unless you
+	compile the code with CONFIG_DEBUG_SPINLOCK but 
+	without CONFIG_SMP ... in which case the BUG()
+	will kill your kernel ...
+
+	maybe it's not advised to make such assertions, 
+	but here is a solution which works for me ...
+	(compile tested for sh, x86_64 and x86, boot/run
+	tested for x86 only)
+
+	best,
+	Herbert
+
+		- Herbert Poetzl <herbert@13thfloor.at>, Thu, 27 Jan 2005
+
 Release Date	: Thu Feb 03 12:27:22 EST 2005 - Seokmann Ju <sju@lsil.com>
 Current Version	: 2.20.4.5 (scsi module), 2.20.2.5 (cmm module)
 Older Version	: 2.20.4.4 (scsi module), 2.20.2.4 (cmm module)
diff --git a/Documentation/scsi/scsi-changer.txt b/Documentation/scsi/scsi-changer.txt
new file mode 100644
--- /dev/null
+++ b/Documentation/scsi/scsi-changer.txt
@@ -0,0 +1,180 @@
+
+README for the SCSI media changer driver
+========================================
+
+This is a driver for SCSI Medium Changer devices, which are listed
+with "Type: Medium Changer" in /proc/scsi/scsi.
+
+This is for *real* Jukeboxes.  It is *not* supported to work with
+common small CD-ROM changers, neither one-lun-per-slot SCSI changers
+nor IDE drives.
+
+Userland tools available from here:
+	http://linux.bytesex.org/misc/changer.html
+
+
+General Information
+-------------------
+
+First some words about how changers work: A changer has 2 (possibly
+more) SCSI ID's. One for the changer device which controls the robot,
+and one for the device which actually reads and writes the data. The
+later may be anything, a MOD, a CD-ROM, a tape or whatever. For the
+changer device this is a "don't care", he *only* shuffles around the
+media, nothing else.
+
+
+The SCSI changer model is complex, compared to - for example - IDE-CD
+changers. But it allows to handle nearly all possible cases. It knows
+4 different types of changer elements:
+
+  media transport - this one shuffles around the media, i.e. the
+                    transport arm.  Also known as "picker".
+  storage         - a slot which can hold a media.
+  import/export   - the same as above, but is accessable from outside,
+                    i.e. there the operator (you !) can use this to
+                    fill in and remove media from the changer.
+		    Sometimes named "mailslot".
+  data transfer   - this is the device which reads/writes, i.e. the
+		    CD-ROM / Tape / whatever drive.
+
+None of these is limited to one: A huge Jukebox could have slots for
+123 CD-ROM's, 5 CD-ROM readers (and therefore 6 SCSI ID's: the changer
+and each CD-ROM) and 2 transport arms. No problem to handle.
+
+
+How it is implemented
+---------------------
+
+I implemented the driver as character device driver with a NetBSD-like
+ioctl interface. Just grabbed NetBSD's header file and one of the
+other linux SCSI device drivers as starting point. The interface
+should be source code compatible with NetBSD. So if there is any
+software (anybody knows ???) which supports a BSDish changer driver,
+it should work with this driver too.
+
+Over time a few more ioctls where added, volume tag support for example
+wasn't covered by the NetBSD ioctl API.
+
+
+Current State
+-------------
+
+Support for more than one transport arm is not implemented yet (and
+nobody asked for it so far...).
+
+I test and use the driver myself with a 35 slot cdrom jukebox from
+Grundig.  I got some reports telling it works ok with tape autoloaders
+(Exabyte, HP and DEC).  Some People use this driver with amanda.  It
+works fine with small (11 slots) and a huge (4 MOs, 88 slots)
+magneto-optical Jukebox.  Probably with lots of other changers too, most
+(but not all :-) people mail me only if it does *not* work...
+
+I don't have any device lists, neither black-list nor white-list.  Thus
+it is quite useless to ask me whenever a specific device is supported or
+not.  In theory every changer device which supports the SCSI-2 media
+changer command set should work out-of-the-box with this driver.  If it
+doesn't, it is a bug.  Either within the driver or within the firmware
+of the changer device.
+
+
+Using it
+--------
+
+This is a character device with major number is 86, so use
+"mknod /dev/sch0 c 86 0" to create the special file for the driver.
+
+If the module finds the changer, it prints some messages about the
+device [ try "dmesg" if you don't see anything ] and should show up in
+/proc/devices. If not....  some changers use ID ? / LUN 0 for the
+device and ID ? / LUN 1 for the robot mechanism. But Linux does *not*
+look for LUN's other than 0 as default, becauce there are to many
+broken devices. So you can try:
+
+  1) echo "scsi add-single-device 0 0 ID 1" > /proc/scsi/scsi
+     (replace ID with the SCSI-ID of the device)
+  2) boot the kernel with "max_scsi_luns=1" on the command line
+     (append="max_scsi_luns=1" in lilo.conf should do the trick)
+
+
+Trouble?
+--------
+
+If you insmod the driver with "insmod debug=1", it will be verbose and
+prints a lot of stuff to the syslog.  Compiling the kernel with
+CONFIG_SCSI_CONSTANTS=y improves the quality of the error messages alot
+because the kernel will translate the error codes into human-readable
+strings then.
+
+You can display these messages with the dmesg command (or check the
+logfiles).  If you email me some question becauce of a problem with the
+driver, please include these messages.
+
+
+Insmod options
+--------------
+
+debug=0/1
+	Enable debug messages (see above, default: 0).
+
+verbose=0/1
+	Be verbose (default: 1).
+
+init=0/1
+	Send INITIALIZE ELEMENT STATUS command to the changer
+	at insmod time (default: 1).
+
+timeout_init=<seconds>
+	timeout for the INITIALIZE ELEMENT STATUS command
+	(default: 3600).
+
+timeout_move=<seconds>
+	timeout for all other commands (default: 120).
+
+dt_id=<id1>,<id2>,...
+dt_lun=<lun1>,<lun2>,...
+	These two allow to specify the SCSI ID and LUN for the data
+	transfer elements.  You likely don't need this as the jukebox
+	should provide this information.  But some devices don't ...
+
+vendor_firsts=
+vendor_counts=
+vendor_labels=
+	These insmod options can be used to tell the driver that there
+	are some vendor-specific element types.  Grundig for example
+	does this.  Some jukeboxes have a printer to label fresh burned
+	CDs, which is addressed as element 0xc000 (type 5).  To tell the
+	driver about this vendor-specific element, use this:
+		$ insmod ch			\
+			vendor_firsts=0xc000	\
+			vendor_counts=1		\
+			vendor_labels=printer
+	All three insmod options accept up to four comma-separated
+	values, this way you can configure the element types 5-8.
+	You likely need the SCSI specs for the device in question to
+	find the correct values as they are not covered by the SCSI-2
+	standard.
+
+
+Credits
+-------
+
+I wrote this driver using the famous mailing-patches-around-the-world
+method.  With (more or less) help from:
+
+	Daniel Moehwald <moehwald@hdg.de>
+	Dane Jasper <dane@sonic.net>
+	R. Scott Bailey <sbailey@dsddi.eds.com>
+	Jonathan Corbet <corbet@lwn.net>
+
+Special thanks go to
+	Martin Kuehne <martin.kuehne@bnbt.de>
+for a old, second-hand (but full functional) cdrom jukebox which I use
+to develop/test driver and tools now.
+
+Have fun,
+
+   Gerd
+
+-- 
+Gerd Knorr <kraxel@bytesex.org>
diff --git a/Documentation/scsi/scsi_mid_low_api.txt b/Documentation/scsi/scsi_mid_low_api.txt
--- a/Documentation/scsi/scsi_mid_low_api.txt
+++ b/Documentation/scsi/scsi_mid_low_api.txt
@@ -388,7 +388,6 @@ Summary:
    scsi_remove_device - detach and remove a SCSI device
    scsi_remove_host - detach and remove all SCSI devices owned by host
    scsi_report_bus_reset - report scsi _bus_ reset observed
-   scsi_set_device - place device reference in host structure
    scsi_track_queue_full - track successive QUEUE_FULL events 
    scsi_unblock_requests - allow further commands to be queued to given host
    scsi_unregister - [calls scsi_host_put()]
@@ -741,20 +740,6 @@ void scsi_report_bus_reset(struct Scsi_H
 
 
 /**
- * scsi_set_device - place device reference in host structure
- * @shost: a pointer to a scsi host instance
- * @pdev: pointer to device instance to assign
- *
- *      Returns nothing
- *
- *      Might block: no
- *
- *      Defined in: include/scsi/scsi_host.h .
- **/
-void scsi_set_device(struct Scsi_Host * shost, struct device * dev)
-
-
-/**
  * scsi_track_queue_full - track successive QUEUE_FULL events on given
  *                      device to determine if and when there is a need
  *                      to adjust the queue depth on the device.
@@ -936,8 +921,7 @@ Details:
  *
  *      Returns SUCCESS if command aborted else FAILED
  *
- *      Locks: struct Scsi_Host::host_lock held (with irqsave) on entry 
- *      and assumed to be held on return.
+ *      Locks: None held
  *
  *      Calling context: kernel thread
  *
@@ -955,8 +939,7 @@ Details:
  *
  *      Returns SUCCESS if command aborted else FAILED
  *
- *      Locks: struct Scsi_Host::host_lock held (with irqsave) on entry 
- *      and assumed to be held on return.
+ *      Locks: None held
  *
  *      Calling context: kernel thread
  *
@@ -974,8 +957,7 @@ Details:
  *
  *      Returns SUCCESS if command aborted else FAILED
  *
- *      Locks: struct Scsi_Host::host_lock held (with irqsave) on entry
- *      and assumed to be held on return.
+ *      Locks: None held
  *
  *      Calling context: kernel thread
  *
@@ -993,8 +975,7 @@ Details:
  *
  *      Returns SUCCESS if command aborted else FAILED
  *
- *      Locks: struct Scsi_Host::host_lock held (with irqsave) on entry
- *      and assumed to be held on return.
+ *      Locks: None held
  *
  *      Calling context: kernel thread
  *
diff --git a/Documentation/serial/driver b/Documentation/serial/driver
--- a/Documentation/serial/driver
+++ b/Documentation/serial/driver
@@ -107,8 +107,8 @@ hardware.
 	indicate that the signal is permanently active.  If RI is
 	not available, the signal should not be indicated as active.
 
-	Locking: none.
-	Interrupts: caller dependent.
+	Locking: port->lock taken.
+	Interrupts: locally disabled.
 	This call must not sleep
 
   stop_tx(port,tty_stop)
diff --git a/Documentation/sgi-ioc4.txt b/Documentation/sgi-ioc4.txt
new file mode 100644
--- /dev/null
+++ b/Documentation/sgi-ioc4.txt
@@ -0,0 +1,45 @@
+The SGI IOC4 PCI device is a bit of a strange beast, so some notes on
+it are in order.
+
+First, even though the IOC4 performs multiple functions, such as an
+IDE controller, a serial controller, a PS/2 keyboard/mouse controller,
+and an external interrupt mechanism, it's not implemented as a
+multifunction device.  The consequence of this from a software
+standpoint is that all these functions share a single IRQ, and
+they can't all register to own the same PCI device ID.  To make
+matters a bit worse, some of the register blocks (and even registers
+themselves) present in IOC4 are mixed-purpose between these several
+functions, meaning that there's no clear "owning" device driver.
+
+The solution is to organize the IOC4 driver into several independent
+drivers, "ioc4", "sgiioc4", and "ioc4_serial".  Note that there is no
+PS/2 controller driver as this functionality has never been wired up
+on a shipping IO card.
+
+ioc4
+====
+This is the core (or shim) driver for IOC4.  It is responsible for
+initializing the basic functionality of the chip, and allocating
+the PCI resources that are shared between the IOC4 functions.
+
+This driver also provides registration functions that the other
+IOC4 drivers can call to make their presence known.  Each driver
+needs to provide a probe and remove function, which are invoked
+by the core driver at appropriate times.  The interface of these
+IOC4 function probe and remove operations isn't precisely the same
+as PCI device probe and remove operations, but is logically the
+same operation.
+
+sgiioc4
+=======
+This is the IDE driver for IOC4.  Its name isn't very descriptive
+simply for historical reasons (it used to be the only IOC4 driver
+component).  There's not much to say about it other than it hooks
+up to the ioc4 driver via the appropriate registration, probe, and
+remove functions.
+
+ioc4_serial
+===========
+This is the serial driver for IOC4.  There's not much to say about it
+other than it hooks up to the ioc4 driver via the appropriate registration,
+probe, and remove functions.
diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt
--- a/Documentation/sound/alsa/ALSA-Configuration.txt
+++ b/Documentation/sound/alsa/ALSA-Configuration.txt
@@ -615,9 +615,11 @@ Prior to version 0.9.0rc4 options had a 
   Module snd-hda-intel
   --------------------
 
-    Module for Intel HD Audio (ICH6, ICH6M, ICH7)
+    Module for Intel HD Audio (ICH6, ICH6M, ICH7), ATI SB450,
+	       VIA VT8251/VT8237A
 
     model	- force the model name
+    position_fix - Fix DMA pointer (0 = FIFO size, 1 = none, 2 = POSBUF)
 
     Module supports up to 8 cards.
 
@@ -634,7 +636,16 @@ Prior to version 0.9.0rc4 options had a 
 	  3stack-digout	3-jack in back, a HP out and a SPDIF out
 	  5stack	5-jack in back, 2-jack in front
 	  5stack-digout	5-jack in back, 2-jack in front, a SPDIF out
+	  6stack	6-jack in back, 2-jack in front
+	  6stack-digout	6-jack with a SPDIF out
 	  w810		3-jack
+	  z71v		3-jack (HP shared SPDIF)
+	  asus		3-jack
+	  uniwill	3-jack
+	  F1734		2-jack
+	  test		for testing/debugging purpose, almost all controls can be
+			adjusted.  Appearing only when compiled with
+			$CONFIG_SND_DEBUG=y
 
 	CMI9880
 	  minimal	3-jack in back
@@ -642,6 +653,15 @@ Prior to version 0.9.0rc4 options had a 
 	  full		6-jack in back, 2-jack in front
 	  full_dig	6-jack in back, 2-jack in front, SPDIF I/O
 	  allout	5-jack in back, 2-jack in front, SPDIF out
+	  auto		auto-config reading BIOS (default)
+
+    Note 2: If you get click noises on output, try the module option
+	    position_fix=1 or 2.  position_fix=1 will use the SD_LPIB
+	    register value without FIFO size correction as the current
+	    DMA pointer.  position_fix=2 will make the driver to use
+	    the position buffer instead of reading SD_LPIB register.
+	    (Usually SD_LPLIB register is more accurate than the
+	    position buffer.)
 
   Module snd-hdsp
   ---------------
@@ -660,7 +680,19 @@ Prior to version 0.9.0rc4 options had a 
           module did formerly.  It will allocate the buffers in advance
           when any HDSP cards are found.  To make the buffer
           allocation sure, load snd-page-alloc module in the early
-          stage of boot sequence.
+          stage of boot sequence.  See "Early Buffer Allocation"
+	  section.
+
+  Module snd-hdspm
+  ----------------
+
+    Module for RME HDSP MADI board.
+
+    precise_ptr		- Enable precise pointer, or disable.
+    line_outs_monitor	- Send playback streams to analog outs by default.
+    enable_monitor	- Enable Analog Out on Channel 63/64 by default.
+
+    See hdspm.txt for details.
 
   Module snd-ice1712
   ------------------
@@ -677,15 +709,19 @@ Prior to version 0.9.0rc4 options had a 
                         * TerraTec EWS 88D
                         * TerraTec EWX 24/96
                         * TerraTec DMX 6Fire
+			* TerraTec Phase 88
                         * Hoontech SoundTrack DSP 24
                         * Hoontech SoundTrack DSP 24 Value
                         * Hoontech SoundTrack DSP 24 Media 7.1
+			* Event Electronics, EZ8
                         * Digigram VX442
+			* Lionstracs, Mediastaton
 
     model       - Use the given board model, one of the following:
 		  delta1010, dio2496, delta66, delta44, audiophile, delta410,
 		  delta1010lt, vx442, ewx2496, ews88mt, ews88mt_new, ews88d,
-		  dmx6fire, dsp24, dsp24_value, dsp24_71, ez8
+		  dmx6fire, dsp24, dsp24_value, dsp24_71, ez8,
+		  phase88, mediastation
     omni	- Omni I/O support for MidiMan M-Audio Delta44/66
     cs8427_timeout - reset timeout for the CS8427 chip (S/PDIF transciever)
                      in msec resolution, default value is 500 (0.5 sec)
@@ -694,20 +730,46 @@ Prior to version 0.9.0rc4 options had a 
     is not used with all Envy24 based cards (for example in the MidiMan Delta
     serie).
 
+    Note: The supported board is detected by reading EEPROM or PCI
+	  SSID (if EEPROM isn't available).  You can override the
+	  model by passing "model" module option in case that the
+	  driver isn't configured properly or you want to try another
+	  type for testing.
+
   Module snd-ice1724
   ------------------
 
-    Module for Envy24HT (VT/ICE1724) based PCI sound cards.
+    Module for Envy24HT (VT/ICE1724), Envy24PT (VT1720) based PCI sound cards.
 			* MidiMan M Audio Revolution 7.1
 			* AMP Ltd AUDIO2000
-			* TerraTec Aureon Sky-5.1, Space-7.1
+			* TerraTec Aureon 5.1 Sky
+			* TerraTec Aureon 7.1 Space
+			* TerraTec Aureon 7.1 Universe
+			* TerraTec Phase 22
+			* TerraTec Phase 28
+			* AudioTrak Prodigy 7.1
+			* AudioTrak Prodigy 192
+			* Pontis MS300
+			* Albatron K8X800 Pro II 
+			* Chaintech ZNF3-150
+			* Chaintech ZNF3-250
+			* Chaintech 9CJS
+			* Chaintech AV-710
+			* Shuttle SN25P
 
     model       - Use the given board model, one of the following:
-		  revo71, amp2000, prodigy71, aureon51, aureon71,
-		  k8x800
+		  revo71, amp2000, prodigy71, prodigy192, aureon51,
+		  aureon71, universe, k8x800, phase22, phase28, ms300,
+		  av710
 
     Module supports up to 8 cards and autoprobe.
 
+    Note: The supported board is detected by reading EEPROM or PCI
+	  SSID (if EEPROM isn't available).  You can override the
+	  model by passing "model" module option in case that the
+	  driver isn't configured properly or you want to try another
+	  type for testing.
+
   Module snd-intel8x0
   -------------------
 
@@ -997,6 +1059,13 @@ Prior to version 0.9.0rc4 options had a 
 
     The power-management is supported.
 
+  Module snd-pxa2xx-ac97 (on arm only)
+  ------------------------------------
+
+    Module for AC97 driver for the Intel PXA2xx chip
+
+    For ARM architecture only.
+
   Module snd-rme32
   ----------------
 
@@ -1026,7 +1095,8 @@ Prior to version 0.9.0rc4 options had a 
           module did formerly.  It will allocate the buffers in advance
           when any RME9652 cards are found.  To make the buffer
           allocation sure, load snd-page-alloc module in the early
-          stage of boot sequence.
+          stage of boot sequence.  See "Early Buffer Allocation"
+	  section.
 
   Module snd-sa11xx-uda1341 (on arm only)
   ---------------------------------------
@@ -1115,6 +1185,13 @@ Prior to version 0.9.0rc4 options had a 
 
     Module supports up to 8 cards.
 
+  Module snd-sun-dbri (on sparc only)
+  -----------------------------------
+
+    Module for DBRI sound chips found on Sparcs.
+
+    Module supports up to 8 cards.
+
   Module snd-wavefront
   --------------------
 
@@ -1211,16 +1288,18 @@ Prior to version 0.9.0rc4 options had a 
   ------------------
 
     Module for AC'97 motherboards based on VIA 82C686A/686B, 8233,
-    8233A, 8233C, 8235 (south) bridge.
+    8233A, 8233C, 8235, 8237 (south) bridge.
 
     mpu_port	- 0x300,0x310,0x320,0x330, otherwise obtain BIOS setup
 		  [VIA686A/686B only]
     joystick	- Enable joystick (default off) [VIA686A/686B only]
     ac97_clock	- AC'97 codec clock base (default 48000Hz)
     dxs_support	- support DXS channels,
-		  0 = auto (defalut), 1 = enable, 2 = disable,
-		  3 = 48k only, 4 = no VRA
-		  [VIA8233/C,8235 only]
+		  0 = auto (default), 1 = enable, 2 = disable,
+		  3 = 48k only, 4 = no VRA, 5 = enable any sample
+		  rate and different sample rates on different
+		  channels
+		  [VIA8233/C, 8235, 8237 only]
     ac97_quirk  - AC'97 workaround for strange hardware
                   See the description of intel8x0 module for details.
 
@@ -1232,18 +1311,23 @@ Prior to version 0.9.0rc4 options had a 
           default value 1.4.  Then the interrupt number will be
           assigned under 15. You might also upgrade your BIOS.
     
-    Note: VIA8233/5 (not VIA8233A) can support DXS (direct sound)
+    Note: VIA8233/5/7 (not VIA8233A) can support DXS (direct sound)
 	  channels as the first PCM.  On these channels, up to 4
-	  streams can be played at the same time.
+	  streams can be played at the same time, and the controller
+	  can perform sample rate conversion with separate rates for
+	  each channel.
 	  As default (dxs_support = 0), 48k fixed rate is chosen
 	  except for the known devices since the output is often
 	  noisy except for 48k on some mother boards due to the
 	  bug of BIOS.
-	  Please try once dxs_support=1 and if it works on other
+	  Please try once dxs_support=5 and if it works on other
 	  sample rates (e.g. 44.1kHz of mp3 playback), please let us
 	  know the PCI subsystem vendor/device id's (output of
 	  "lspci -nv").
-	  If it doesn't work, try dxs_support=4.  If it still doesn't
+	  If dxs_support=5 does not work, try dxs_support=4; if it
+	  doesn't work too, try dxs_support=1.  (dxs_support=1 is
+	  usually for old motherboards.  The correct implementated
+	  board should work with 4 or 5.)  If it still doesn't
 	  work and the default setting is ok, dxs_support=3 is the
 	  right choice.  If the default setting doesn't work at all,
 	  try dxs_support=2 to disable the DXS channels.
@@ -1306,7 +1390,7 @@ Prior to version 0.9.0rc4 options had a 
   Module snd-vxpocket
   -------------------
 
-    Module for Digigram VX-Pocket VX2 PCMCIA card.
+    Module for Digigram VX-Pocket VX2 and 440 PCMCIA cards.
 
     ibl      - Capture IBL size. (default = 0, minimum size)
 
@@ -1326,29 +1410,6 @@ Prior to version 0.9.0rc4 options had a 
 
     Note: the driver is build only when CONFIG_ISA is set.
     
-  Module snd-vxp440
-  -----------------
-
-    Module for Digigram VX-Pocket 440 PCMCIA card.
-
-    ibl      - Capture IBL size. (default = 0, minimum size)
-
-    Module supports up to 8 cards.  The module is compiled only when
-    PCMCIA is supported on kernel.
-
-    To activate the driver via the card manager, you'll need to set
-    up /etc/pcmcia/vxp440.conf.  See the sound/pcmcia/vx/vxp440.c.
-
-    When the driver is compiled as a module and the hotplug firmware
-    is supported, the firmware data is loaded via hotplug automatically.
-    Install the necessary firmware files in alsa-firmware package.
-    When no hotplug fw loader is available, you need to load the
-    firmware via vxloader utility in alsa-tools package.
-
-    About capture IBL, see the description of snd-vx222 module.
-
-    Note: the driver is build only when CONFIG_ISA is set.
-    
   Module snd-ymfpci
   -----------------
 
@@ -1497,6 +1558,36 @@ Proc interfaces (/proc/asound)
 	   echo "rvplayer 0 0 block" > /proc/asound/card0/pcm0p/oss
 
 
+Early Buffer Allocation
+=======================
+
+Some drivers (e.g. hdsp) require the large contiguous buffers, and
+sometimes it's too late to find such spaces when the driver module is
+actually loaded due to memory fragmentation.  You can pre-allocate the
+PCM buffers by loading snd-page-alloc module and write commands to its
+proc file in prior, for example, in the early boot stage like
+/etc/init.d/*.local scripts.
+
+Reading the proc file /proc/drivers/snd-page-alloc shows the current
+usage of page allocation.  In writing, you can send the following
+commands to the snd-page-alloc driver:
+
+  - add VENDOR DEVICE MASK SIZE BUFFERS
+
+    VENDOR and DEVICE are PCI vendor and device IDs.  They take
+    integer numbers (0x prefix is needed for the hex).
+    MASK is the PCI DMA mask.  Pass 0 if not restricted.
+    SIZE is the size of each buffer to allocate.  You can pass
+    k and m suffix for KB and MB.  The max number is 16MB.
+    BUFFERS is the number of buffers to allocate.  It must be greater
+    than 0.  The max number is 4.
+
+  - erase
+
+    This will erase the all pre-allocated buffers which are not in
+    use.
+
+
 Links
 =====
 
diff --git a/Documentation/sound/alsa/CMIPCI.txt b/Documentation/sound/alsa/CMIPCI.txt
--- a/Documentation/sound/alsa/CMIPCI.txt
+++ b/Documentation/sound/alsa/CMIPCI.txt
@@ -89,19 +89,22 @@ and use the interleaved 4 channel data.
 
 There are some control switchs affecting to the speaker connections:
 
-"Line-In As Rear"	- As mentioned above, the line-in jack is used
-	for the rear (3th and 4th channels) output.
-"Line-In As Bass"	- The line-in jack is used for the bass (5th
-	and 6th channels) output.
-"Mic As Center/LFE"	- The mic jack is used for the bass output.
-	If this switch is on, you cannot use a microphone as a capture
-	source, of course.
-
+"Line-In Mode"	- an enum control to change the behavior of line-in
+	jack.  Either "Line-In", "Rear Output" or "Bass Output" can
+	be selected.  The last item is available only with model 039
+	or newer. 
+	When "Rear Output" is chosen, the surround channels 3 and 4
+	are output to line-in jack.
+"Mic-In Mode"	- an enum control to change the behavior of mic-in
+	jack.  Either "Mic-In" or "Center/LFE Output" can be
+	selected. 
+	When "Center/LFE Output" is chosen, the center and bass
+	channels (channels 5 and 6) are output to mic-in jack. 
 
 Digital I/O
 -----------
 
-The CM8x38 provides the excellent SPDIF capability with very chip
+The CM8x38 provides the excellent SPDIF capability with very cheap
 price (yes, that's the reason I bought the card :)
 
 The SPDIF playback and capture are done via the third PCM device
@@ -122,8 +125,9 @@ respectively, so you cannot playback bot
 simultaneously.
 
 To enable SPDIF output, you need to turn on "IEC958 Output Switch"
-control via mixer or alsactl.  Then you'll see the red light on from
-the card so you know that's working obviously :)
+control via mixer or alsactl ("IEC958" is the official name of
+so-called S/PDIF).  Then you'll see the red light on from the card so
+you know that's working obviously :)
 The SPDIF input is always enabled, so you can hear SPDIF input data
 from line-out with "IEC958 In Monitor" switch at any time (see
 below).
@@ -205,9 +209,10 @@ In addition to the standard SB mixer, CM
 MIDI CONTROLLER
 ---------------
 
-The MPU401-UART interface is enabled as default only for the first
-(CMIPCI) card.  You need to set module option "midi_port" properly
-for the 2nd (CMIPCI) card.
+The MPU401-UART interface is disabled as default.  You need to set
+module option "mpu_port" with a valid I/O port address to enable the
+MIDI support.  The valid I/O ports are 0x300, 0x310, 0x320 and 0x330.
+Choose the value which doesn't conflict with other cards.
 
 There is _no_ hardware wavetable function on this chip (except for
 OPL3 synth below).
@@ -229,9 +234,11 @@ I don't know why..
 Joystick and Modem
 ------------------
 
-The joystick and modem should be available by enabling the control
-switch "Joystick" and "Modem" respectively.  But I myself have never
-tested them yet.
+The legacy joystick is supported.  To enable the joystick support, pass
+joystick_port=1 module option.  The value 1 means the auto-detection.
+If the auto-detection fails, try to pass the exact I/O address.
+
+The modem is enabled dynamically via a card control switch "Modem".
 
 
 Debugging Information
diff --git a/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl b/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
--- a/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
+++ b/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
@@ -371,7 +371,7 @@
           <listitem><para>create <function>probe()</function> callback.</para></listitem>
           <listitem><para>create <function>remove()</function> callback.</para></listitem>
           <listitem><para>create pci_driver table which contains the three pointers above.</para></listitem>
-          <listitem><para>create <function>init()</function> function just calling <function>pci_module_init()</function> to register the pci_driver table defined above.</para></listitem>
+          <listitem><para>create <function>init()</function> function just calling <function>pci_register_driver()</function> to register the pci_driver table defined above.</para></listitem>
           <listitem><para>create <function>exit()</function> function to call <function>pci_unregister_driver()</function> function.</para></listitem>
         </itemizedlist>
       </para>
@@ -1198,7 +1198,7 @@
   /* initialization of the module */
   static int __init alsa_card_mychip_init(void)
   {
-          return pci_module_init(&driver);
+          return pci_register_driver(&driver);
   }
 
   /* clean up the module */
@@ -1654,7 +1654,7 @@
 <![CDATA[
   static int __init alsa_card_mychip_init(void)
   {
-          return pci_module_init(&driver);
+          return pci_register_driver(&driver);
   }
 
   static void __exit alsa_card_mychip_exit(void)
diff --git a/Documentation/sound/alsa/emu10k1-jack.txt b/Documentation/sound/alsa/emu10k1-jack.txt
new file mode 100644
--- /dev/null
+++ b/Documentation/sound/alsa/emu10k1-jack.txt
@@ -0,0 +1,74 @@
+This document is a guide to using the emu10k1 based devices with JACK for low
+latency, multichannel recording functionality.  All of my recent work to allow
+Linux users to use the full capabilities of their hardware has been inspired 
+by the kX Project.  Without their work I never would have discovered the true
+power of this hardware.
+
+	http://www.kxproject.com
+						- Lee Revell, 2005.03.30
+
+Low latency, multichannel audio with JACK and the emu10k1/emu10k2
+-----------------------------------------------------------------
+
+Until recently, emu10k1 users on Linux did not have access to the same low
+latency, multichannel features offered by the "kX ASIO" feature of their
+Windows driver.  As of ALSA 1.0.9 this is no more!
+
+For those unfamiliar with kX ASIO, this consists of 16 capture and 16 playback
+channels.  With a post 2.6.9 Linux kernel, latencies down to 64 (1.33 ms) or
+even 32 (0.66ms) frames should work well.
+
+The configuration is slightly more involved than on Windows, as you have to
+select the correct device for JACK to use.  Actually, for qjackctl users it's
+fairly self explanatory - select Duplex, then for capture and playback select
+the multichannel devices, set the in and out channels to 16, and the sample
+rate to 48000Hz.  The command line looks like this:
+
+/usr/local/bin/jackd -R -dalsa -r48000 -p64 -n2 -D -Chw:0,2 -Phw:0,3 -S
+
+This will give you 16 input ports and 16 output ports.
+
+The 16 output ports map onto the 16 FX buses (or the first 16 of 64, for the
+Audigy).  The mapping from FX bus to physical output is described in
+SB-Live-mixer.txt (or Audigy-mixer.txt).
+
+The 16 input ports are connected to the 16 physical inputs.  Contrary to
+popular belief, all emu10k1 cards are multichannel cards.  Which of these
+input channels have physical inputs connected to them depends on the card
+model.  Trial and error is highly recommended; the pinout diagrams
+for the card have been reverse engineered by some enterprising kX users and are 
+available on the internet.  Meterbridge is helpful here, and the kX forums are
+packed with useful information.
+
+Each input port will either correspond to a digital (SPDIF) input, an analog
+input, or nothing.  The one exception is the SBLive! 5.1.  On these devices,
+the second and third input ports are wired to the center/LFE output.  You will
+still see 16 capture channels, but only 14 are available for recording inputs.
+
+This chart, borrowed from kxfxlib/da_asio51.cpp, describes the mapping of JACK
+ports to FXBUS2 (multitrack recording input) and EXTOUT (physical output)
+channels.
+
+/*JACK (& ASIO) mappings on 10k1 5.1 SBLive cards:
+--------------------------------------------
+JACK		Epilog		FXBUS2(nr)
+--------------------------------------------
+capture_1	asio14		FXBUS2(0xe)
+capture_2	asio15		FXBUS2(0xf)
+capture_3	asio0		FXBUS2(0x0)	
+~capture_4	Center		EXTOUT(0x11)	// mapped to by Center
+~capture_5	LFE		EXTOUT(0x12)	// mapped to by LFE
+capture_6	asio3		FXBUS2(0x3)
+capture_7	asio4		FXBUS2(0x4)
+capture_8	asio5		FXBUS2(0x5)
+capture_9	asio6		FXBUS2(0x6)
+capture_10	asio7		FXBUS2(0x7)
+capture_11	asio8		FXBUS2(0x8)
+capture_12	asio9		FXBUS2(0x9)
+capture_13	asio10		FXBUS2(0xa)
+capture_14	asio11		FXBUS2(0xb)
+capture_15	asio12		FXBUS2(0xc)
+capture_16	asio13		FXBUS2(0xd)
+*/
+
+TODO: describe use of ld10k1/qlo10k1 in conjunction with JACK
diff --git a/Documentation/sound/alsa/hdspm.txt b/Documentation/sound/alsa/hdspm.txt
new file mode 100644
--- /dev/null
+++ b/Documentation/sound/alsa/hdspm.txt
@@ -0,0 +1,362 @@
+Software Interface ALSA-DSP MADI Driver 
+
+(translated from German, so no good English ;-), 
+2004 - winfried ritsch
+
+
+
+ Full functionality has been added to the driver. Since some of
+ the Controls and startup-options  are ALSA-Standard and only the
+ special Controls are described and discussed below.
+
+
+ hardware functionality:
+
+   
+   Audio transmission:
+
+     number of channels --  depends on transmission mode
+
+		The number of channels chosen is from 1..Nmax. The reason to
+		use for a lower number of channels is only resource allocation,
+		since unused DMA channels are disabled and less memory is
+		allocated. So also the throughput of the PCI system can be
+		scaled. (Only important for low performance boards).
+
+       Single Speed -- 1..64 channels 
+
+		 (Note: Choosing the 56channel mode for transmission or as
+		 receiver, only 56 are transmitted/received over the MADI, but
+		 all 64 channels are available for the mixer, so channel count
+		 for the driver)
+
+       Double Speed -- 1..32 channels
+
+		 Note: Choosing the 56-channel mode for
+		 transmission/receive-mode , only 28 are transmitted/received
+		 over the MADI, but all 32 channels are available for the mixer,
+		 so channel count for the driver
+
+
+       Quad Speed -- 1..16 channels 
+
+		 Note: Choosing the 56-channel mode for
+		 transmission/receive-mode , only 14 are transmitted/received
+		 over the MADI, but all 16 channels are available for the mixer,
+		 so channel count for the driver
+
+     Format -- signed 32 Bit Little Endian (SNDRV_PCM_FMTBIT_S32_LE)
+
+     Sample Rates --
+
+       Single Speed -- 32000, 44100, 48000
+
+       Double Speed -- 64000, 88200, 96000 (untested)
+
+       Quad Speed -- 128000, 176400, 192000 (untested)
+
+     access-mode -- MMAP (memory mapped), Not interleaved
+     (PCM_NON-INTERLEAVED)
+
+     buffer-sizes -- 64,128,256,512,1024,2048,8192 Samples
+
+     fragments -- 2
+
+     Hardware-pointer -- 2 Modi
+
+
+		 The Card supports the readout of the actual Buffer-pointer,
+		 where DMA reads/writes. Since of the bulk mode of PCI it is only
+		 64 Byte accurate. SO it is not really usable for the
+		 ALSA-mid-level functions (here the buffer-ID gives a better
+		 result), but if MMAP is used by the application. Therefore it
+		 can be configured at load-time with the parameter
+		 precise-pointer.
+
+
+		 (Hint: Experimenting I found that the pointer is maximum 64 to
+		 large never to small. So if you subtract 64 you always have a
+		 safe pointer for writing, which is used on this mode inside
+		 ALSA. In theory now you can get now a latency as low as 16
+		 Samples, which is a quarter of the interrupt possibilities.)
+
+       Precise Pointer -- off
+					interrupt used for pointer-calculation
+
+       Precise Pointer -- on
+					hardware pointer used.
+
+   Controller:
+
+
+	  Since DSP-MADI-Mixer has 8152 Fader, it does not make sense to
+	  use the standard mixer-controls, since this would break most of
+	  (especially graphic) ALSA-Mixer GUIs. So Mixer control has be
+	  provided by a 2-dimensional controller using the
+	  hwdep-interface. 
+
+     Also all 128+256 Peak and RMS-Meter can be accessed via the
+     hwdep-interface. Since it could be a performance problem always
+     copying and converting Peak and RMS-Levels even if you just need
+     one, I decided to export the hardware structure, so that of
+     needed some driver-guru can implement a memory-mapping of mixer
+     or peak-meters over ioctl, or also to do only copying and no
+     conversion. A test-application shows the usage of the controller.
+
+    Latency Controls --- not implemented !!!
+
+
+	   Note: Within the windows-driver the latency is accessible of a
+	   control-panel, but buffer-sizes are controlled with ALSA from
+	   hwparams-calls and should not be changed in run-state, I did not
+	   implement it here.
+
+
+    System Clock -- suspended !!!!
+
+        Name -- "System Clock Mode"
+
+        Access -- Read Write
+
+        Values -- "Master" "Slave"
+
+
+		  !!!! This is a hardware-function but is in conflict with the
+		  Clock-source controller, which is a kind of ALSA-standard. I
+		  makes sense to set the card to a special mode (master at some
+		  frequency or slave), since even not using an Audio-application
+		  a studio should have working synchronisations setup. So use
+		  Clock-source-controller instead !!!!
+
+    Clock Source  
+
+       Name -- "Sample Clock Source"
+
+       Access -- Read Write
+
+       Values -- "AutoSync", "Internal 32.0 kHz", "Internal 44.1 kHz",
+       "Internal 48.0 kHz", "Internal 64.0 kHz", "Internal 88.2 kHz",
+       "Internal 96.0 kHz"
+
+		 Choose between Master at a specific Frequency and so also the
+		 Speed-mode or Slave (Autosync). Also see  "Preferred Sync Ref"
+
+
+       !!!! This is no pure hardware function but was implemented by
+       ALSA by some ALSA-drivers before, so I use it also. !!!
+
+
+    Preferred Sync Ref
+
+       Name -- "Preferred Sync Reference"
+
+       Access -- Read Write
+
+       Values -- "Word" "MADI"
+
+
+		 Within the Auto-sync-Mode the preferred Sync Source can be
+		 chosen. If it is not available another is used if possible.
+
+		 Note: Since MADI has a much higher bit-rate than word-clock, the
+		 card should synchronise better in MADI Mode. But since the
+		 RME-PLL is very good, there are almost no problems with
+		 word-clock too. I never found a difference.
+
+
+    TX 64 channel --- 
+
+       Name -- "TX 64 channels mode"
+
+       Access -- Read Write
+
+       Values -- 0 1
+
+		 Using 64-channel-modus (1) or 56-channel-modus for
+		 MADI-transmission (0).
+
+
+		 Note: This control is for output only. Input-mode is detected
+		 automatically from hardware sending MADI.
+
+
+    Clear TMS ---
+
+       Name -- "Clear Track Marker"
+
+       Access -- Read Write
+
+       Values -- 0 1
+
+
+		 Don't use to lower 5 Audio-bits on AES as additional Bits.
+        
+
+    Safe Mode oder Auto Input --- 
+
+       Name -- "Safe Mode"
+
+       Access -- Read Write
+
+       Values -- 0 1
+
+       (default on)
+
+		 If on (1), then if either the optical or coaxial connection
+		 has a failure, there is a takeover to the working one, with no
+		 sample failure. Its only useful if you use the second as a
+		 backup connection.
+
+    Input --- 
+
+       Name -- "Input Select"
+
+       Access -- Read Write
+
+       Values -- optical coaxial
+
+
+		 Choosing the Input, optical or coaxial. If Safe-mode is active,
+		 this is the preferred Input.
+
+-------------- Mixer ----------------------
+
+    Mixer
+
+       Name -- "Mixer"
+
+       Access -- Read Write
+
+       Values - <channel-number 0-127> <Value 0-65535>
+
+
+		 Here as a first value the channel-index is taken to get/set the
+		 corresponding mixer channel, where 0-63 are the input to output
+		 fader and 64-127 the playback to outputs fader. Value 0
+		 is channel muted 0 and 32768 an amplification of  1.
+
+    Chn 1-64
+
+       fast mixer for the ALSA-mixer utils. The diagonal of the
+       mixer-matrix is implemented from playback to output.
+       
+
+    Line Out
+
+       Name  -- "Line Out"
+
+       Access -- Read Write
+
+       Values -- 0 1
+
+		 Switching on and off the analog out, which has nothing to do
+		 with mixing or routing. the analog outs reflects channel 63,64.
+
+
+--- information (only read access):
+ 
+    Sample Rate
+
+       Name -- "System Sample Rate"
+
+       Access -- Read-only
+
+		 getting the sample rate.
+
+
+    External Rate measured
+
+       Name -- "External Rate"
+
+       Access -- Read only
+
+
+		 Should be "Autosync Rate", but Name used is
+		 ALSA-Scheme. External Sample frequency liked used on Autosync is
+		 reported.
+
+
+    MADI Sync Status
+
+       Name -- "MADI Sync Lock Status"
+
+       Access -- Read
+
+       Values -- 0,1,2
+
+       MADI-Input is 0=Unlocked, 1=Locked, or 2=Synced.
+
+
+    Word Clock Sync Status
+
+       Name -- "Word Clock Lock Status"
+
+       Access -- Read
+
+       Values -- 0,1,2
+
+       Word Clock Input is 0=Unlocked, 1=Locked, or 2=Synced.
+
+    AutoSync
+
+       Name -- "AutoSync Reference"
+
+       Access -- Read
+
+       Values -- "WordClock", "MADI", "None"
+
+		 Sync-Reference is either "WordClock", "MADI" or none.
+
+   RX 64ch --- noch nicht implementiert
+
+       MADI-Receiver is in 64 channel mode oder 56 channel mode.
+
+
+   AB_inp   --- not tested 
+
+		 Used input for Auto-Input.
+
+
+   actual Buffer Position --- not implemented
+
+	   !!! this is a ALSA internal function, so no control is used !!!
+
+
+
+Calling Parameter:
+
+   index int array (min = 1, max = 8), 
+     "Index value for RME HDSPM interface." card-index within ALSA
+
+     note: ALSA-standard
+
+   id string array (min = 1, max = 8), 
+     "ID string for RME HDSPM interface."
+
+     note: ALSA-standard
+
+   enable int array (min = 1, max = 8), 
+     "Enable/disable specific HDSPM sound-cards."
+
+     note: ALSA-standard
+
+   precise_ptr int array (min = 1, max = 8), 
+     "Enable precise pointer, or disable."
+
+     note: Use only when the application supports this (which is a special case).
+
+   line_outs_monitor int array (min = 1, max = 8), 
+     "Send playback streams to analog outs by default."
+
+
+	  note: each playback channel is mixed to the same numbered output
+	  channel (routed). This is against the ALSA-convention, where all
+	  channels have to be muted on after loading the driver, but was
+	  used before on other cards, so i historically use it again)
+
+
+
+   enable_monitor int array (min = 1, max = 8), 
+     "Enable Analog Out on Channel 63/64 by default."
+
+      note: here the analog output is enabled (but not routed).
\ No newline at end of file
diff --git a/Documentation/stable_api_nonsense.txt b/Documentation/stable_api_nonsense.txt
--- a/Documentation/stable_api_nonsense.txt
+++ b/Documentation/stable_api_nonsense.txt
@@ -132,7 +132,7 @@ to extra work for the USB developers.  S
 their work on their own time, asking programmers to do extra work for no
 gain, for free, is not a possibility.
 
-Security issues are also a very important for Linux.  When a
+Security issues are also very important for Linux.  When a
 security issue is found, it is fixed in a very short amount of time.  A
 number of times this has caused internal kernel interfaces to be
 reworked to prevent the security problem from occurring.  When this
diff --git a/Documentation/stable_kernel_rules.txt b/Documentation/stable_kernel_rules.txt
new file mode 100644
--- /dev/null
+++ b/Documentation/stable_kernel_rules.txt
@@ -0,0 +1,58 @@
+Everything you ever wanted to know about Linux 2.6 -stable releases.
+
+Rules on what kind of patches are accepted, and what ones are not, into
+the "-stable" tree:
+
+ - It must be obviously correct and tested.
+ - It can not bigger than 100 lines, with context.
+ - It must fix only one thing.
+ - It must fix a real bug that bothers people (not a, "This could be a
+   problem..." type thing.)
+ - It must fix a problem that causes a build error (but not for things
+   marked CONFIG_BROKEN), an oops, a hang, data corruption, a real
+   security issue, or some "oh, that's not good" issue.  In short,
+   something critical.
+ - No "theoretical race condition" issues, unless an explanation of how
+   the race can be exploited.
+ - It can not contain any "trivial" fixes in it (spelling changes,
+   whitespace cleanups, etc.)
+ - It must be accepted by the relevant subsystem maintainer.
+ - It must follow Documentation/SubmittingPatches rules.
+
+
+Procedure for submitting patches to the -stable tree:
+
+ - Send the patch, after verifying that it follows the above rules, to
+   stable@kernel.org.
+ - The sender will receive an ack when the patch has been accepted into
+   the queue, or a nak if the patch is rejected.  This response might
+   take a few days, according to the developer's schedules.
+ - If accepted, the patch will be added to the -stable queue, for review
+   by other developers.
+ - Security patches should not be sent to this alias, but instead to the
+   documented security@kernel.org.
+
+
+Review cycle:
+
+ - When the -stable maintainers decide for a review cycle, the patches
+   will be sent to the review committee, and the maintainer of the
+   affected area of the patch (unless the submitter is the maintainer of
+   the area) and CC: to the linux-kernel mailing list.
+ - The review committee has 48 hours in which to ack or nak the patch.
+ - If the patch is rejected by a member of the committee, or linux-kernel
+   members object to the patch, bringing up issues that the maintainers
+   and members did not realize, the patch will be dropped from the
+   queue.
+ - At the end of the review cycle, the acked patches will be added to
+   the latest -stable release, and a new -stable release will happen.
+ - Security patches will be accepted into the -stable tree directly from
+   the security kernel team, and not go through the normal review cycle.
+   Contact the kernel security team for more details on this procedure.
+
+
+Review committe:
+
+ - This will be made up of a number of kernel developers who have
+   volunteered for this task, and a few that haven't.
+
diff --git a/Documentation/sysctl/kernel.txt b/Documentation/sysctl/kernel.txt
--- a/Documentation/sysctl/kernel.txt
+++ b/Documentation/sysctl/kernel.txt
@@ -49,6 +49,7 @@ show up in /proc/sys/kernel:
 - shmmax                      [ sysv ipc ]
 - shmmni
 - stop-a                      [ SPARC only ]
+- suid_dumpable
 - sysrq                       ==> Documentation/sysrq.txt
 - tainted
 - threads-max
@@ -300,6 +301,25 @@ kernel.  This value defaults to SHMMAX.
 
 ==============================================================
 
+suid_dumpable:
+
+This value can be used to query and set the core dump mode for setuid
+or otherwise protected/tainted binaries. The modes are
+
+0 - (default) - traditional behaviour. Any process which has changed
+	privilege levels or is execute only will not be dumped
+1 - (debug) - all processes dump core when possible. The core dump is
+	owned by the current user and no security is applied. This is
+	intended for system debugging situations only. Ptrace is unchecked.
+2 - (suidsafe) - any binary which normally would not be dumped is dumped
+	readable by root only. This allows the end user to remove
+	such a dump but not access it directly. For security reasons
+	core dumps in this mode will not overwrite one another or
+	other files. This mode is appropriate when adminstrators are
+	attempting to debug problems in a normal environment.
+
+==============================================================
+
 tainted: 
 
 Non-zero if the kernel has been tainted.  Numeric values, which
diff --git a/Documentation/sysrq.txt b/Documentation/sysrq.txt
--- a/Documentation/sysrq.txt
+++ b/Documentation/sysrq.txt
@@ -72,6 +72,8 @@ On all -  write a character to /proc/sys
 'b'     - Will immediately reboot the system without syncing or unmounting
           your disks.
 
+'c'	- Will perform a kexec reboot in order to take a crashdump.
+
 'o'     - Will shut your system off (if configured and supported).
 
 's'     - Will attempt to sync all mounted filesystems.
@@ -122,6 +124,9 @@ useful when you want to exit a program t
 re'B'oot is good when you're unable to shut down. But you should also 'S'ync
 and 'U'mount first.
 
+'C'rashdump can be used to manually trigger a crashdump when the system is hung.
+The kernel needs to have been built with CONFIG_KEXEC enabled.
+
 'S'ync is great when your system is locked up, it allows you to sync your
 disks and will certainly lessen the chance of data loss and fscking. Note
 that the sync hasn't taken place until you see the "OK" and "Done" appear
diff --git a/Documentation/tty.txt b/Documentation/tty.txt
--- a/Documentation/tty.txt
+++ b/Documentation/tty.txt
@@ -22,7 +22,7 @@ copy of the structure. You must not re-r
 discipline even with the same data or your computer again will be eaten by
 demons.
 
-In order to remove a line discipline call tty_register_ldisc passing NULL.
+In order to remove a line discipline call tty_unregister_ldisc().
 In ancient times this always worked. In modern times the function will
 return -EBUSY if the ldisc is currently in use. Since the ldisc referencing
 code manages the module counts this should not usually be a concern.
diff --git a/Documentation/usb/sn9c102.txt b/Documentation/usb/sn9c102.txt
--- a/Documentation/usb/sn9c102.txt
+++ b/Documentation/usb/sn9c102.txt
@@ -297,6 +297,7 @@ Vendor ID  Product ID
 0x0c45     0x602a
 0x0c45     0x602b
 0x0c45     0x602c
+0x0c45     0x602d
 0x0c45     0x6030
 0x0c45     0x6080
 0x0c45     0x6082
@@ -333,6 +334,7 @@ Model       Manufacturer
 -----       ------------
 HV7131D     Hynix Semiconductor, Inc.
 MI-0343     Micron Technology, Inc.
+OV7630      OmniVision Technologies, Inc.
 PAS106B     PixArt Imaging, Inc.
 PAS202BCB   PixArt Imaging, Inc.
 TAS5110C1B  Taiwan Advanced Sensor Corporation
@@ -470,9 +472,11 @@ order):
 - Luca Capello for the donation of a webcam;
 - Joao Rodrigo Fuzaro, Joao Limirio, Claudio Filho and Caio Begotti for the
   donation of a webcam;
+- Jon Hollstrom for the donation of a webcam;
 - Carlos Eduardo Medaglia Dyonisio, who added the support for the PAS202BCB
   image sensor;
 - Stefano Mozzi, who donated 45 EU;
+- Andrew Pearce for the donation of a webcam;
 - Bertrik Sikken, who reverse-engineered and documented the Huffman compression
   algorithm used in the SN9C10x controllers and implemented the first decoder;
 - Mizuno Takafumi for the donation of a webcam;
diff --git a/Documentation/usb/usbmon.txt b/Documentation/usb/usbmon.txt
--- a/Documentation/usb/usbmon.txt
+++ b/Documentation/usb/usbmon.txt
@@ -101,6 +101,13 @@ Here is the list of words, from left to 
   or 3 and 2 positions, correspondingly.
 - URB Status. This field makes no sense for submissions, but is present
   to help scripts with parsing. In error case, it contains the error code.
+  In case of a setup packet, it contains a Setup Tag. If scripts read a number
+  in this field, they proceed to read Data Length. Otherwise, they read
+  the setup packet before reading the Data Length.
+- Setup packet, if present, consists of 5 words: one of each for bmRequestType,
+  bRequest, wValue, wIndex, wLength, as specified by the USB Specification 2.0.
+  These words are safe to decode if Setup Tag was 's'. Otherwise, the setup
+  packet was present, but not captured, and the fields contain filler.
 - Data Length. This is the actual length in the URB.
 - Data tag. The usbmon may not always capture data, even if length is nonzero.
   Only if tag is '=', the data words are present.
@@ -125,25 +132,31 @@ class ParsedLine {
 			String data_str = st.nextToken();
 			int len = data_str.length() / 2;
 			int i;
+			int b;	// byte is signed, apparently?! XXX
 			for (i = 0; i < len; i++) {
-				data[data_len] = Byte.parseByte(
-				    data_str.substring(i*2, i*2 + 2),
-				    16);
+				// data[data_len] = Byte.parseByte(
+				//     data_str.substring(i*2, i*2 + 2),
+				//     16);
+				b = Integer.parseInt(
+				     data_str.substring(i*2, i*2 + 2),
+				     16);
+				if (b >= 128)
+					b *= -1;
+				data[data_len] = (byte) b;
 				data_len++;
 			}
 		}
 	}
 }
 
-This format is obviously deficient. For example, the setup packet for control
-transfers is not delivered. This will change in the future.
+This format may be changed in the future.
 
 Examples:
 
-An input control transfer to get a port status:
+An input control transfer to get a port status.
 
-d74ff9a0 2640288196 S Ci:001:00 -115 4 <
-d74ff9a0 2640288202 C Ci:001:00 0 4 = 01010100
+d5ea89a0 3575914555 S Ci:001:00 s a3 00 0000 0003 0004 4 <
+d5ea89a0 3575914560 C Ci:001:00 0 4 = 01050000
 
 An output bulk transfer to send a SCSI command 0x5E in a 31-byte Bulk wrapper
 to a storage device at address 5:
diff --git a/Documentation/video4linux/API.html b/Documentation/video4linux/API.html
--- a/Documentation/video4linux/API.html
+++ b/Documentation/video4linux/API.html
@@ -1,399 +1,16 @@
-<HTML><HEAD>
-<TITLE>Video4Linux Kernel API Reference v0.1:19990430</TITLE>
-</HEAD>
-<! Revision History: >
-<!   4/30/1999 - Fred Gleason (fredg@wava.com)>
-<! Documented extensions for the Radio Data System (RDS) extensions >
-<BODY bgcolor="#ffffff">
-<H3>Devices</H3>
-Video4Linux provides the following sets of device files. These live on the
-character device formerly known as "/dev/bttv". /dev/bttv should be a
-symlink to /dev/video0 for most people. 
-<P>
-<TABLE>
-<TR><TH>Device Name</TH><TH>Minor Range</TH><TH>Function</TH>
-<TR><TD>/dev/video</TD><TD>0-63</TD><TD>Video Capture Interface</TD>
-<TR><TD>/dev/radio</TD><TD>64-127</TD><TD>AM/FM Radio Devices</TD>
-<TR><TD>/dev/vtx</TD><TD>192-223</TD><TD>Teletext Interface Chips</TD>
-<TR><TD>/dev/vbi</TD><TD>224-239</TD><TD>Raw VBI Data (Intercast/teletext)</TD>
-</TABLE>
-<P>
-Video4Linux programs open and scan the devices to find what they are looking
-for. Capability queries define what each interface supports. The 
-described API is only defined for video capture cards. The relevant subset
-applies to radio cards. Teletext interfaces talk the existing VTX API.
-<P>
-<H3>Capability Query Ioctl</H3>
-The <B>VIDIOCGCAP</B> ioctl call is used to obtain the capability
-information for a video device. The <b>struct video_capability</b> object
-passed to the ioctl is completed and returned. It contains the following
-information
-<P>
-<TABLE>
-<TR><TD><b>name[32]</b><TD>Canonical name for this interface</TD>
-<TR><TD><b>type</b><TD>Type of interface</TD>
-<TR><TD><b>channels</b><TD>Number of radio/tv channels if appropriate</TD>
-<TR><TD><b>audios</b><TD>Number of audio devices if appropriate</TD>
-<TR><TD><b>maxwidth</b><TD>Maximum capture width in pixels</TD>
-<TR><TD><b>maxheight</b><TD>Maximum capture height in pixels</TD>
-<TR><TD><b>minwidth</b><TD>Minimum capture width in pixels</TD>
-<TR><TD><b>minheight</b><TD>Minimum capture height in pixels</TD>
-</TABLE>
-<P>
-The type field lists the capability flags for the device. These are
-as follows
-<P>
-<TABLE>
-<TR><TH>Name</TH><TH>Description</TH>
-<TR><TD><b>VID_TYPE_CAPTURE</b><TD>Can capture to memory</TD>
-<TR><TD><b>VID_TYPE_TUNER</b><TD>Has a tuner of some form</TD>
-<TR><TD><b>VID_TYPE_TELETEXT</b><TD>Has teletext capability</TD>
-<TR><TD><b>VID_TYPE_OVERLAY</b><TD>Can overlay its image onto the frame buffer</TD>
-<TR><TD><b>VID_TYPE_CHROMAKEY</b><TD>Overlay is Chromakeyed</TD>
-<TR><TD><b>VID_TYPE_CLIPPING</b><TD>Overlay clipping is supported</TD>
-<TR><TD><b>VID_TYPE_FRAMERAM</b><TD>Overlay overwrites frame buffer memory</TD>
-<TR><TD><b>VID_TYPE_SCALES</b><TD>The hardware supports image scaling</TD>
-<TR><TD><b>VID_TYPE_MONOCHROME</b><TD>Image capture is grey scale only</TD>
-<TR><TD><b>VID_TYPE_SUBCAPTURE</b><TD>Capture can be of only part of the image</TD>
-</TABLE>
-<P>
-The minimum and maximum sizes listed for a capture device do not imply all
-that all height/width ratios or sizes within the range are possible. A
-request to set a size will be honoured by the largest available capture
-size whose capture is no large than the requested rectangle in either
-direction. For example the quickcam has 3 fixed settings. 
-<P>
-<H3>Frame Buffer</H3>
-Capture cards that drop data directly onto the frame buffer must be told the
-base address of the frame buffer, its size and organisation. This is a 
-privileged ioctl and one that eventually X itself should set.
-<P>
-The <b>VIDIOCSFBUF</b> ioctl sets the frame buffer parameters for a capture
-card. If the card does not do direct writes to the frame buffer then this
-ioctl will be unsupported. The <b>VIDIOCGFBUF</b> ioctl returns the
-currently used parameters. The structure used in both cases is a 
-<b>struct video_buffer</b>.
-<P>
-<TABLE>
-<TR><TD><b>void *base</b></TD><TD>Base physical address of the buffer</TD>
-<TR><TD><b>int height</b></TD><TD>Height of the frame buffer</TD>
-<TR><TD><b>int width</b></TD><TD>Width of the frame buffer</TD>
-<TR><TD><b>int depth</b></TD><TD>Depth of the frame buffer</TD>
-<TR><TD><b>int bytesperline</b></TD><TD>Number of bytes of memory between the start of two adjacent lines</TD>
-</TABLE>
-<P>
-Note that these values reflect the physical layout of the frame buffer. 
-The visible area may be smaller. In fact under XFree86 this is commonly the
-case. XFree86 DGA can provide the parameters required to set up this ioctl.
-Setting the base address to NULL indicates there is no physical frame buffer
-access.
-<P>
-<H3>Capture Windows</H3>
-The capture area is described by a <b>struct video_window</b>. This defines
-a capture area and the clipping information if relevant. The 
-<b>VIDIOCGWIN</b> ioctl recovers the current settings and the 
-<b>VIDIOCSWIN</b> sets new values. A successful call to <b>VIDIOCSWIN</b> 
-indicates that a suitable set of parameters have been chosen. They do not
-indicate that exactly what was requested was granted. The program should
-call <b>VIDIOCGWIN</b> to check if the nearest match was suitable. The
-<b>struct video_window</b> contains the following fields.
-<P>
-<TABLE>
-<TR><TD><b>x</b><TD>The X co-ordinate specified in X windows format.</TD>
-<TR><TD><b>y</b><TD>The Y co-ordinate specified in X windows format.</TD>
-<TR><TD><b>width</b><TD>The width of the image capture.</TD>
-<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>clipcount</b><TD>The number of clipping rectangles. <em>(Set only)</em></TD>
-</TABLE>
-<P>
-Clipping rectangles are passed as an array. Each clip consists of the following
-fields available to the user.
-<P>
-<TABLE>
-<TR><TD><b>x</b></TD><TD>X co-ordinate of rectangle to skip</TD>
-<TR><TD><b>y</b></TD><TD>Y co-ordinate of rectangle to skip</TD>
-<TR><TD><b>width</b></TD><TD>Width of rectangle to skip</TD>
-<TR><TD><b>height</b></TD><TD>Height of rectangle to skip</TD>
-</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>
-Some capture devices can capture a subfield of the image they actually see.
-This is indicated when VIDEO_TYPE_SUBCAPTURE is defined.
-The video_capture describes the time and special subfields to capture.
-The video_capture structure contains the following fields.
-<P>
-<TABLE>
-<TR><TD><b>x</b></TD><TD>X co-ordinate of source rectangle to grab</TD>
-<TR><TD><b>y</b></TD><TD>Y co-ordinate of source rectangle to grab</TD>
-<TR><TD><b>width</b></TD><TD>Width of source rectangle to grab</TD>
-<TR><TD><b>height</b></TD><TD>Height of source rectangle to grab</TD>
-<TR><TD><b>decimation</b></TD><TD>Decimation to apply</TD>
-<TR><TD><b>flags</b></TD><TD>Flag settings for grabbing</TD>
-</TABLE>
-The available flags are
-<P>
-<TABLE>
-<TR><TH>Name</TH><TH>Description</TH>
-<TR><TD><b>VIDEO_CAPTURE_ODD</b><TD>Capture only odd frames</TD>
-<TR><TD><b>VIDEO_CAPTURE_EVEN</b><TD>Capture only even frames</TD>
-</TABLE>
-<P>
-<H3>Video Sources</H3>
-Each video4linux video or audio device captures from one or more 
-source <b>channels</b>. Each channel can be queries with the 
-<b>VDIOCGCHAN</b> ioctl call. Before invoking this function the caller
-must set the channel field to the channel that is being queried. On return
-the <b>struct video_channel</b> is filled in with information about the
-nature of the channel itself.
-<P>
-The <b>VIDIOCSCHAN</b> ioctl takes an integer argument and switches the
-capture to this input. It is not defined whether parameters such as colour
-settings or tuning are maintained across a channel switch. The caller should
-maintain settings as desired for each channel. (This is reasonable as 
-different video inputs may have different properties).
-<P>
-The <b>struct video_channel</b> consists of the following
-<P>
-<TABLE>
-<TR><TD><b>channel</b></TD><TD>The channel number</TD>
-<TR><TD><b>name</b></TD><TD>The input name - preferably reflecting the label
-on the card input itself</TD>
-<TR><TD><b>tuners</b></TD><TD>Number of tuners for this input</TD>
-<TR><TD><b>flags</b></TD><TD>Properties the tuner has</TD>
-<TR><TD><b>type</b></TD><TD>Input type (if known)</TD>
-<TR><TD><b>norm</b><TD>The norm for this channel</TD>
-</TABLE>
-<P>
-The flags defined are
-<P>
-<TABLE>
-<TR><TD><b>VIDEO_VC_TUNER</b><TD>Channel has tuners.</TD>
-<TR><TD><b>VIDEO_VC_AUDIO</b><TD>Channel has audio.</TD>
-<TR><TD><b>VIDEO_VC_NORM</b><TD>Channel has norm setting.</TD>
-</TABLE>
-<P>
-The types defined are
-<P>
-<TABLE>
-<TR><TD><b>VIDEO_TYPE_TV</b><TD>The input is a TV input.</TD>
-<TR><TD><b>VIDEO_TYPE_CAMERA</b><TD>The input is a camera.</TD>
-</TABLE>
-<P>
-<H3>Image Properties</H3>
-The image properties of the picture can be queried with the <b>VIDIOCGPICT</b>
-ioctl which fills in a <b>struct video_picture</b>. The <b>VIDIOCSPICT</b> 
-ioctl allows values to be changed. All values except for the palette type
-are scaled between 0-65535. 
-<P>
-The <b>struct video_picture</b> consists of the following fields
-<P>
-<TABLE>
-<TR><TD><b>brightness</b><TD>Picture brightness</TD>
-<TR><TD><b>hue</b><TD>Picture hue (colour only)</TD>
-<TR><TD><b>colour</b><TD>Picture colour (colour only)</TD>
-<TR><TD><b>contrast</b><TD>Picture contrast</TD>
-<TR><TD><b>whiteness</b><TD>The whiteness (greyscale only)</TD>
-<TR><TD><b>depth</b><TD>The capture depth (may need to match the frame buffer depth)</TD>
-<TR><TD><b>palette</b><TD>Reports the palette that should be used for this image</TD>
-</TABLE>
-<P>
-The following palettes are defined
-<P>
-<TABLE>
-<TR><TD><b>VIDEO_PALETTE_GREY</b><TD>Linear intensity grey scale (255 is brightest).</TD>
-<TR><TD><b>VIDEO_PALETTE_HI240</b><TD>The BT848 8bit colour cube.</TD>
-<TR><TD><b>VIDEO_PALETTE_RGB565</b><TD>RGB565 packed into 16 bit words.</TD>
-<TR><TD><b>VIDEO_PALETTE_RGB555</b><TD>RGV555 packed into 16 bit words, top bit undefined.</TD>
-<TR><TD><b>VIDEO_PALETTE_RGB24</b><TD>RGB888 packed into 24bit words.</TD>
-<TR><TD><b>VIDEO_PALETTE_RGB32</b><TD>RGB888 packed into the low 3 bytes of 32bit words. The top 8bits are undefined.</TD>
-<TR><TD><b>VIDEO_PALETTE_YUV422</b><TD>Video style YUV422 - 8bits packed 4bits Y 2bits U 2bits V</TD>
-<TR><TD><b>VIDEO_PALETTE_YUYV</b><TD>Describe me</TD>
-<TR><TD><b>VIDEO_PALETTE_UYVY</b><TD>Describe me</TD>
-<TR><TD><b>VIDEO_PALETTE_YUV420</b><TD>YUV420 capture</TD>
-<TR><TD><b>VIDEO_PALETTE_YUV411</b><TD>YUV411 capture</TD>
-<TR><TD><b>VIDEO_PALETTE_RAW</b><TD>RAW capture (BT848)</TD>
-<TR><TD><b>VIDEO_PALETTE_YUV422P</b><TD>YUV 4:2:2 Planar</TD>
-<TR><TD><b>VIDEO_PALETTE_YUV411P</b><TD>YUV 4:1:1 Planar</TD>
-</TABLE>
-<P>
-<H3>Tuning</H3>
-Each video input channel can have one or more tuners associated with it. Many
-devices will not have tuners. TV cards and radio cards will have one or more
-tuners attached.
-<P>
-Tuners are described by a <b>struct video_tuner</b> which can be obtained by
-the <b>VIDIOCGTUNER</b> ioctl. Fill in the tuner number in the structure
-then pass the structure to the ioctl to have the data filled in. The 
-tuner can be switched using <b>VIDIOCSTUNER</b> which takes an integer argument
-giving the tuner to use. A struct tuner has the following fields
-<P>
-<TABLE>
-<TR><TD><b>tuner</b><TD>Number of the tuner</TD>
-<TR><TD><b>name</b><TD>Canonical name for this tuner (eg FM/AM/TV)</TD>
-<TR><TD><b>rangelow</b><TD>Lowest tunable frequency</TD>
-<TR><TD><b>rangehigh</b><TD>Highest tunable frequency</TD>
-<TR><TD><b>flags</b><TD>Flags describing the tuner</TD>
-<TR><TD><b>mode</b><TD>The video signal mode if relevant</TD>
-<TR><TD><b>signal</b><TD>Signal strength if known - between 0-65535</TD>
-</TABLE>
-<P>
-The following flags exist
-<P>
-<TABLE>
-<TR><TD><b>VIDEO_TUNER_PAL</b><TD>PAL tuning is supported</TD>
-<TR><TD><b>VIDEO_TUNER_NTSC</b><TD>NTSC tuning is supported</TD>
-<TR><TD><b>VIDEO_TUNER_SECAM</b><TD>SECAM tuning is supported</TD>
-<TR><TD><b>VIDEO_TUNER_LOW</b><TD>Frequency is in a lower range</TD>
-<TR><TD><b>VIDEO_TUNER_NORM</b><TD>The norm for this tuner is settable</TD>
-<TR><TD><b>VIDEO_TUNER_STEREO_ON</b><TD>The tuner is seeing stereo audio</TD>
-<TR><TD><b>VIDEO_TUNER_RDS_ON</b><TD>The tuner is seeing a RDS datastream</TD>
-<TR><TD><b>VIDEO_TUNER_MBS_ON</b><TD>The tuner is seeing a MBS datastream</TD>
-</TABLE>
-<P>
-The following modes are defined
-<P>
-<TABLE>
-<TR><TD><b>VIDEO_MODE_PAL</b><TD>The tuner is in PAL mode</TD>
-<TR><TD><b>VIDEO_MODE_NTSC</b><TD>The tuner is in NTSC mode</TD>
-<TR><TD><b>VIDEO_MODE_SECAM</b><TD>The tuner is in SECAM mode</TD>
-<TR><TD><b>VIDEO_MODE_AUTO</b><TD>The tuner auto switches, or mode does not apply</TD>
-</TABLE>
-<P>
-Tuning frequencies are an unsigned 32bit value in 1/16th MHz or if the
-<b>VIDEO_TUNER_LOW</b> flag is set they are in 1/16th KHz. The current
-frequency is obtained as an unsigned long via the <b>VIDIOCGFREQ</b> ioctl and
-set by the <b>VIDIOCSFREQ</b> ioctl.
-<P>
-<H3>Audio</H3>
-TV and Radio devices have one or more audio inputs that may be selected. 
-The audio properties are queried by passing a <b>struct video_audio</b> to <b>VIDIOCGAUDIO</b> ioctl. The
-<b>VIDIOCSAUDIO</b> ioctl sets audio properties.
-<P>
-The structure contains the following fields
-<P>
-<TABLE>
-<TR><TD><b>audio</b><TD>The channel number</TD>
-<TR><TD><b>volume</b><TD>The volume level</TD>
-<TR><TD><b>bass</b><TD>The bass level</TD>
-<TR><TD><b>treble</b><TD>The treble level</TD>
-<TR><TD><b>flags</b><TD>Flags describing the audio channel</TD>
-<TR><TD><b>name</b><TD>Canonical name for the audio input</TD>
-<TR><TD><b>mode</b><TD>The mode the audio input is in</TD>
-<TR><TD><b>balance</b><TD>The left/right balance</TD>
-<TR><TD><b>step</b><TD>Actual step used by the hardware</TD>
-</TABLE>
-<P>
-The following flags are defined
-<P>
-<TABLE>
-<TR><TD><b>VIDEO_AUDIO_MUTE</b><TD>The audio is muted</TD>
-<TR><TD><b>VIDEO_AUDIO_MUTABLE</b><TD>Audio muting is supported</TD>
-<TR><TD><b>VIDEO_AUDIO_VOLUME</b><TD>The volume is controllable</TD>
-<TR><TD><b>VIDEO_AUDIO_BASS</b><TD>The bass is controllable</TD>
-<TR><TD><b>VIDEO_AUDIO_TREBLE</b><TD>The treble is controllable</TD>
-<TR><TD><b>VIDEO_AUDIO_BALANCE</b><TD>The balance is controllable</TD>
-</TABLE>
-<P>
-The following decoding modes are defined
-<P>
-<TABLE>
-<TR><TD><b>VIDEO_SOUND_MONO</b><TD>Mono signal</TD>
-<TR><TD><b>VIDEO_SOUND_STEREO</b><TD>Stereo signal (NICAM for TV)</TD>
-<TR><TD><b>VIDEO_SOUND_LANG1</b><TD>European TV alternate language 1</TD>
-<TR><TD><b>VIDEO_SOUND_LANG2</b><TD>European TV alternate language 2</TD>
-</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 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.
-To use the mmap interface a user first sets the desired image size and depth
-properties. Next the VIDIOCGMBUF ioctl is issued. This reports the size
-of buffer to mmap and the offset within the buffer for each frame. The
-number of frames supported is device dependent and may only be one. 
-<P>
-The video_mbuf structure contains the following fields
-<P>
-<TABLE>
-<TR><TD><b>size</b><TD>The number of bytes to map</TD>
-<TR><TD><b>frames</b><TD>The number of frames</TD>
-<TR><TD><b>offsets</b><TD>The offset of each frame</TD>
-</TABLE>
-<P>
-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
-with vbi0 which would cause an intercast display program to make a bad
-mistake). The VIDIOCGUNIT ioctl reports the unit numbers of the associated
-devices if any exist. The video_unit structure has the following fields.
-<P>
-<TABLE>
-<TR><TD><b>video</b><TD>Video capture device</TD>
-<TR><TD><b>vbi</b><TD>VBI capture device</TD>
-<TR><TD><b>radio</b><TD>Radio device</TD>
-<TR><TD><b>audio</b><TD>Audio mixer</TD>
-<TR><TD><b>teletext</b><TD>Teletext device</TD>
-</TABLE>
-<P>
-<H3>RDS Datastreams</H3>
-For radio devices that support it, it is possible to receive Radio Data
-System (RDS) data by means of a read() on the device.  The data is packed in
-groups of three, as follows:
-<TABLE>
-<TR><TD>First Octet</TD><TD>Least Significant Byte of RDS Block</TD></TR>
-<TR><TD>Second Octet</TD><TD>Most Significant Byte of RDS Block
-<TR><TD>Third Octet</TD><TD>Bit 7:</TD><TD>Error bit.  Indicates that
-an uncorrectable error occurred during reception of this block.</TD></TR>
-<TR><TD>&nbsp;</TD><TD>Bit 6:</TD><TD>Corrected bit.  Indicates that  
-an error was corrected for this data block.</TD></TR>
-<TR><TD>&nbsp;</TD><TD>Bits 5-3:</TD><TD>Received Offset.  Indicates the  
-offset received by the sync system.</TD></TR>
-<TR><TD>&nbsp;</TD><TD>Bits 2-0:</TD><TD>Offset Name.  Indicates the  
-offset applied to this data.</TD></TR>
-</TABLE>
-</BODY>
-</HTML>
+<TITLE>V4L API</TITLE>
+<H1>Video For Linux APIs</H1>
+<table border=0>
+<tr>
+<td>
+<A HREF=http://www.linuxtv.org/downloads/video4linux/API/V4L1_API.html>
+V4L original API</a>
+</td><td>
+Obsoleted by V4L2 API
+</td></tr><tr><td>
+<A HREF=http://www.linuxtv.org/downloads/video4linux/API/V4L2_API.html>
+V4L2 API</a>
+</td><td>
+Should be used for new projects
+</td></tr>
+</table>
diff --git a/Documentation/video4linux/CARDLIST.bttv b/Documentation/video4linux/CARDLIST.bttv
--- a/Documentation/video4linux/CARDLIST.bttv
+++ b/Documentation/video4linux/CARDLIST.bttv
@@ -1,4 +1,4 @@
-card=0 -  *** UNKNOWN/GENERIC *** 
+card=0 -  *** UNKNOWN/GENERIC ***
 card=1 - MIRO PCTV
 card=2 - Hauppauge (bt848)
 card=3 - STB, Gateway P/N 6000699 (bt848)
@@ -119,3 +119,17 @@ card=117 - NGS NGSTV+
 card=118 - LMLBT4
 card=119 - Tekram M205 PRO
 card=120 - Conceptronic CONTVFMi
+card=121 - Euresys Picolo Tetra
+card=122 - Spirit TV Tuner
+card=123 - AVerMedia AVerTV DVB-T 771
+card=124 - AverMedia AverTV DVB-T 761
+card=125 - MATRIX Vision Sigma-SQ
+card=126 - MATRIX Vision Sigma-SLC
+card=127 - APAC Viewcomp 878(AMAX)
+card=128 - DVICO FusionHDTV DVB-T Lite
+card=129 - V-Gear MyVCD
+card=130 - Super TV Tuner
+card=131 - Tibet Systems 'Progress DVR' CS16
+card=132 - Kodicom 4400R (master)
+card=133 - Kodicom 4400R (slave)
+card=134 - Adlink RTV24
diff --git a/Documentation/video4linux/CARDLIST.cx88 b/Documentation/video4linux/CARDLIST.cx88
new file mode 100644
--- /dev/null
+++ b/Documentation/video4linux/CARDLIST.cx88
@@ -0,0 +1,32 @@
+card=0 - UNKNOWN/GENERIC
+card=1 - Hauppauge WinTV 34xxx models
+card=2 - GDI Black Gold
+card=3 - PixelView
+card=4 - ATI TV Wonder Pro
+card=5 - Leadtek Winfast 2000XP Expert
+card=6 - AverTV Studio 303 (M126)
+card=7 - MSI TV-@nywhere Master
+card=8 - Leadtek Winfast DV2000
+card=9 - Leadtek PVR 2000
+card=10 - IODATA GV-VCP3/PCI
+card=11 - Prolink PlayTV PVR
+card=12 - ASUS PVR-416
+card=13 - MSI TV-@nywhere
+card=14 - KWorld/VStream XPert DVB-T
+card=15 - DViCO FusionHDTV DVB-T1
+card=16 - KWorld LTV883RF
+card=17 - DViCO FusionHDTV 3 Gold-Q
+card=18 - Hauppauge Nova-T DVB-T
+card=19 - Conexant DVB-T reference design
+card=20 - Provideo PV259
+card=21 - DViCO FusionHDTV DVB-T Plus
+card=22 - digitalnow DNTV Live! DVB-T
+card=23 - pcHDTV HD3000 HDTV
+card=24 - Hauppauge WinTV 28xxx (Roslyn) models
+card=25 - Digital-Logic MICROSPACE Entertainment Center (MEC)
+card=26 - IODATA GV/BCTV7E
+card=27 - PixelView PlayTV Ultra Pro (Stereo)
+card=28 - DViCO FusionHDTV 3 Gold-T
+card=29 - ADS Tech Instant TV DVB-T PCI
+card=30 - TerraTec Cinergy 1400 DVB-T
+card=31 - DViCO FusionHDTV 5 Gold
diff --git a/Documentation/video4linux/CARDLIST.saa7134 b/Documentation/video4linux/CARDLIST.saa7134
--- a/Documentation/video4linux/CARDLIST.saa7134
+++ b/Documentation/video4linux/CARDLIST.saa7134
@@ -1,10 +1,10 @@
-  0 -> UNKNOWN/GENERIC                         
+  0 -> UNKNOWN/GENERIC
   1 -> Proteus Pro [philips reference design]   [1131:2001,1131:2001]
   2 -> LifeView FlyVIDEO3000                    [5168:0138,4e42:0138]
   3 -> LifeView FlyVIDEO2000                    [5168:0138]
   4 -> EMPRESS                                  [1131:6752]
   5 -> SKNet Monster TV                         [1131:4e85]
-  6 -> Tevion MD 9717                          
+  6 -> Tevion MD 9717
   7 -> KNC One TV-Station RDS / Typhoon TV Tuner RDS [1131:fe01,1894:fe01]
   8 -> Terratec Cinergy 400 TV                  [153B:1142]
   9 -> Medion 5044
@@ -20,16 +20,45 @@
  19 -> Compro VideoMate TV                      [185b:c100]
  20 -> Matrox CronosPlus                        [102B:48d0]
  21 -> 10MOONS PCI TV CAPTURE CARD              [1131:2001]
- 22 -> Medion 2819/ AverMedia M156              [1461:a70b,1461:2115]
+ 22 -> AverMedia M156 / Medion 2819             [1461:a70b]
  23 -> BMK MPEX Tuner
  24 -> KNC One TV-Station DVR                   [1894:a006]
  25 -> ASUS TV-FM 7133                          [1043:4843]
  26 -> Pinnacle PCTV Stereo (saa7134)           [11bd:002b]
- 27 -> Manli MuchTV M-TV002
- 28 -> Manli MuchTV M-TV001
+ 27 -> Manli MuchTV M-TV002/Behold TV 403 FM
+ 28 -> Manli MuchTV M-TV001/Behold TV 401
  29 -> Nagase Sangyo TransGear 3000TV           [1461:050c]
  30 -> Elitegroup ECS TVP3XP FM1216 Tuner Card(PAL-BG,FM)  [1019:4cb4]
  31 -> Elitegroup ECS TVP3XP FM1236 Tuner Card (NTSC,FM) [1019:4cb5]
  32 -> AVACS SmartTV
  33 -> AVerMedia DVD EZMaker                    [1461:10ff]
- 34 -> LifeView FlyTV Platinum33 mini           [5168:0212]
+ 34 -> Noval Prime TV 7133
+ 35 -> AverMedia AverTV Studio 305              [1461:2115]
+ 36 -> UPMOST PURPLE TV                         [12ab:0800]
+ 37 -> Items MuchTV Plus / IT-005
+ 38 -> Terratec Cinergy 200 TV                  [153B:1152]
+ 39 -> LifeView FlyTV Platinum Mini             [5168:0212]
+ 40 -> Compro VideoMate TV PVR/FM               [185b:c100]
+ 41 -> Compro VideoMate TV Gold+                [185b:c100]
+ 42 -> Sabrent SBT-TVFM (saa7130)
+ 43 -> :Zolid Xpert TV7134
+ 44 -> Empire PCI TV-Radio LE
+ 45 -> Avermedia AVerTV Studio 307              [1461:9715]
+ 46 -> AVerMedia Cardbus TV/Radio (E500)        [1461:d6ee]
+ 47 -> Terratec Cinergy 400 mobile              [153b:1162]
+ 48 -> Terratec Cinergy 600 TV MK3              [153B:1158]
+ 49 -> Compro VideoMate Gold+ Pal               [185b:c200]
+ 50 -> Pinnacle PCTV 300i DVB-T + PAL           [11bd:002d]
+ 51 -> ProVideo PV952                           [1540:9524]
+ 52 -> AverMedia AverTV/305                     [1461:2108]
+ 53 -> ASUS TV-FM 7135                          [1043:4845]
+ 54 -> LifeView FlyTV Platinum FM               [5168:0214,1489:0214]
+ 55 -> LifeView FlyDVB-T DUO                    [5168:0502,5168:0306]
+ 56 -> Avermedia AVerTV 307                     [1461:a70a]
+ 57 -> Avermedia AVerTV GO 007 FM               [1461:f31f]
+ 58 -> ADS Tech Instant TV (saa7135)            [1421:0350,1421:0370]
+ 59 -> Kworld/Tevion V-Stream Xpert TV PVR7134
+ 60 -> Typhoon DVB-T Duo Digital/Analog Cardbus [4e42:0502]
+ 61 -> Philips TOUGH DVB-T reference design     [1131:2004]
+ 62 -> Compro VideoMate TV Gold+II
+ 63 -> Kworld Xpert TV PVR7134
diff --git a/Documentation/video4linux/CARDLIST.tuner b/Documentation/video4linux/CARDLIST.tuner
--- a/Documentation/video4linux/CARDLIST.tuner
+++ b/Documentation/video4linux/CARDLIST.tuner
@@ -44,3 +44,23 @@ tuner=42 - Philips 1236D ATSC/NTSC daul 
 tuner=43 - Philips NTSC MK3 (FM1236MK3 or FM1236/F)
 tuner=44 - Philips 4 in 1 (ATI TV Wonder Pro/Conexant)
 tuner=45 - Microtune 4049 FM5
+tuner=46 - Panasonic VP27s/ENGE4324D
+tuner=47 - LG NTSC (TAPE series)
+tuner=48 - Tenna TNF 8831 BGFF)
+tuner=49 - Microtune 4042 FI5 ATSC/NTSC dual in
+tuner=50 - TCL 2002N
+tuner=51 - Philips PAL/SECAM_D (FM 1256 I-H3)
+tuner=52 - Thomson DDT 7610 (ATSC/NTSC)
+tuner=53 - Philips FQ1286
+tuner=54 - tda8290+75
+tuner=55 - LG PAL (TAPE series)
+tuner=56 - Philips PAL/SECAM multi (FQ1216AME MK4)
+tuner=57 - Philips FQ1236A MK4
+tuner=58 - Ymec TVision TVF-8531MF/8831MF/8731MF
+tuner=59 - Ymec TVision TVF-5533MF
+tuner=60 - Thomson DDT 7611 (ATSC/NTSC)
+tuner=61 - Tena TNF9533-D/IF/TNF9533-B/DF
+tuner=62 - Philips TEA5767HN FM Radio
+tuner=63 - Philips FMD1216ME MK3 Hybrid Tuner
+tuner=64 - LG TDVS-H062F/TUA6034
+tuner=65 - Ymec TVF66T5-B/DFF
diff --git a/Documentation/video4linux/README.saa7134 b/Documentation/video4linux/README.saa7134
--- a/Documentation/video4linux/README.saa7134
+++ b/Documentation/video4linux/README.saa7134
@@ -57,6 +57,15 @@ Cards can use either of these two crysta
  - 24.576MHz -> .audio_clock=0x200000
 (xtal * .audio_clock = 51539600)
 
+Some details about 30/34/35:
+
+ - saa7130 - low-price chip, doesn't have mute, that is why all those
+ cards should have .mute field defined in their tuner structure.
+
+ - saa7134 - usual chip
+
+ - saa7133/35 - saa7135 is probably a marketing decision, since all those
+ chips identifies itself as 33 on pci.
 
 Credits
 =======
diff --git a/Documentation/video4linux/bttv/Cards b/Documentation/video4linux/bttv/Cards
--- a/Documentation/video4linux/bttv/Cards
+++ b/Documentation/video4linux/bttv/Cards
@@ -20,7 +20,7 @@ All other cards only differ by additiona
 decoders, EEPROMs, teletext decoders ...
 
 
-Unsupported Cards: 
+Unsupported Cards:
 ------------------
 
 Cards with Zoran (ZR) or Philips (SAA) or ISA are not supported by
@@ -50,11 +50,11 @@ Bt848a/Bt849 single crytal operation sup
 Miro/Pinnacle PCTV
 ------------------
 
-- Bt848 
-  some (all??) come with 2 crystals for PAL/SECAM and NTSC 
+- Bt848
+  some (all??) come with 2 crystals for PAL/SECAM and NTSC
 - PAL, SECAM or NTSC TV tuner (Philips or TEMIC)
 - MSP34xx sound decoder on add on board
-  decoder is supported but AFAIK does not yet work 
+  decoder is supported but AFAIK does not yet work
   (other sound MUX setting in GPIO port needed??? somebody who fixed this???)
 - 1 tuner, 1 composite and 1 S-VHS input
 - tuner type is autodetected
@@ -70,7 +70,7 @@ in 1997!
 Hauppauge Win/TV pci
 --------------------
 
-There are many different versions of the Hauppauge cards with different 
+There are many different versions of the Hauppauge cards with different
 tuners (TV+Radio ...), teletext decoders.
 Note that even cards with same model numbers have (depending on the revision)
 different chips on it.
@@ -80,22 +80,22 @@ different chips on it.
 - PAL, SECAM, NTSC or tuner with or without Radio support
 
 e.g.:
-  PAL: 
+  PAL:
   TDA5737: VHF, hyperband and UHF mixer/oscillator for TV and VCR 3-band tuners
   TSA5522: 1.4 GHz I2C-bus controlled synthesizer, I2C 0xc2-0xc3
-  
+
   NTSC:
   TDA5731: VHF, hyperband and UHF mixer/oscillator for TV and VCR 3-band tuners
   TSA5518: no datasheet available on Philips site
-- Philips SAA5246 or SAA5284 ( or no) Teletext decoder chip	
+- Philips SAA5246 or SAA5284 ( or no) Teletext decoder chip
   with buffer RAM (e.g. Winbond W24257AS-35: 32Kx8 CMOS static RAM)
   SAA5246 (I2C 0x22) is supported
-- 256 bytes EEPROM: Microchip 24LC02B or Philips 8582E2Y 
+- 256 bytes EEPROM: Microchip 24LC02B or Philips 8582E2Y
   with configuration information
   I2C address 0xa0 (24LC02B also responds to 0xa2-0xaf)
 - 1 tuner, 1 composite and (depending on model) 1 S-VHS input
 - 14052B: mux for selection of sound source
-- sound decoder: TDA9800, MSP34xx (stereo cards) 
+- sound decoder: TDA9800, MSP34xx (stereo cards)
 
 
 Askey CPH-Series
@@ -108,17 +108,17 @@ Developed by TelSignal(?), OEMed by many
     CPH05x: BT878 with FM
     CPH06x: BT878 (w/o FM)
     CPH07x: BT878 capture only
- 
+
   TV standards:
      CPH0x0: NTSC-M/M
      CPH0x1: PAL-B/G
      CPH0x2: PAL-I/I
      CPH0x3: PAL-D/K
-     CPH0x4: SECAM-L/L 
-     CPH0x5: SECAM-B/G 
-     CPH0x6: SECAM-D/K 
-     CPH0x7: PAL-N/N 
-     CPH0x8: PAL-B/H 
+     CPH0x4: SECAM-L/L
+     CPH0x5: SECAM-B/G
+     CPH0x6: SECAM-D/K
+     CPH0x7: PAL-N/N
+     CPH0x8: PAL-B/H
      CPH0x9: PAL-M/M
 
   CPH03x was often sold as "TV capturer".
@@ -174,7 +174,7 @@ Lifeview Flyvideo Series:
       "The FlyVideo2000 and FlyVideo2000s product name have renamed to FlyVideo98."
       Their Bt8x8 cards are listed as discontinued.
       Flyvideo 2000S was probably sold as Flyvideo 3000 in some contries(Europe?).
-      The new Flyvideo 2000/3000 are SAA7130/SAA7134 based. 
+      The new Flyvideo 2000/3000 are SAA7130/SAA7134 based.
 
   "Flyvideo II" had been the name for the 848 cards, nowadays (in Germany)
   this name is re-used for LR50 Rev.W.
@@ -235,12 +235,12 @@ Prolink
    Multimedia TV packages (card + software pack):
    PixelView Play TV Theater - (Model: PV-M4200) =  PixelView Play TV pro + Software
    PixelView Play TV PAK -     (Model: PV-BT878P+ REV 4E)
-   PixelView Play TV/VCR -     (Model: PV-M3200 REV 4C / 8D / 10A ) 
+   PixelView Play TV/VCR -     (Model: PV-M3200 REV 4C / 8D / 10A )
    PixelView Studio PAK -      (Model:    M2200 REV 4C / 8D / 10A )
    PixelView PowerStudio PAK - (Model: PV-M3600 REV 4E)
    PixelView DigitalVCR PAK -  (Model: PV-M2400 REV 4C / 8D / 10A )
 
-   PixelView PlayTV PAK II (TV/FM card + usb camera)  PV-M3800 
+   PixelView PlayTV PAK II (TV/FM card + usb camera)  PV-M3800
    PixelView PlayTV XP PV-M4700,PV-M4700(w/FM)
    PixelView PlayTV DVR PV-M4600  package contents:PixelView PlayTV pro, windvr & videoMail s/w
 
@@ -254,7 +254,7 @@ Prolink
 
    DTV3000 PV-DTV3000P+ DVB-S CI = Twinhan VP-1030
    DTV2000 DVB-S = Twinhan VP-1020
-   
+
    Video Conferencing:
    PixelView Meeting PAK - (Model: PV-BT878P)
    PixelView Meeting PAK Lite - (Model: PV-BT878P)
@@ -308,7 +308,7 @@ KNC One
 
    newer Cards have saa7134, but model name stayed the same?
 
-Provideo 
+Provideo
 --------
   PV951 or PV-951 (also are sold as:
    Boeder TV-FM Video Capture Card
@@ -353,7 +353,7 @@ AVerMedia
    AVerTV
    AVerTV Stereo
    AVerTV Studio (w/FM)
-   AVerMedia TV98 with Remote 
+   AVerMedia TV98 with Remote
    AVerMedia TV/FM98 Stereo
    AVerMedia TVCAM98
    TVCapture (Bt848)
@@ -373,7 +373,7 @@ AVerMedia
    (1) Daughterboard MB68-A with TDA9820T and TDA9840T
    (2) Sony NE41S soldered (stereo sound?)
    (3) Daughterboard M118-A w/ pic 16c54 and 4 MHz quartz
- 
+
    US site has different drivers for (as of 09/2002):
    EZ Capture/InterCam PCI (BT-848 chip)
    EZ Capture/InterCam PCI (BT-878 chip)
@@ -437,7 +437,7 @@ Terratec
    Terra TValueRadio,             "LR102 Rev.C" printed on the PCB
    Terra TV/Radio+ Version 1.0,   "80-CP2830100-0" TTTV3 printed on the PCB,
 				     "CPH010-E83" on the back, SAA6588T, TDA9873H
-   Terra TValue Version BT878,    "80-CP2830110-0 TTTV4" printed on the PCB, 
+   Terra TValue Version BT878,    "80-CP2830110-0 TTTV4" printed on the PCB,
 				     "CPH011-D83" on back
    Terra TValue Version 1.0       "ceb105.PCB" (really identical to Terra TV+ Version 1.0)
    Terra TValue New Revision	  "LR102 Rec.C"
@@ -528,7 +528,7 @@ Koutech
    KW-606RSF
    KW-607A (capture only)
    KW-608 (Zoran capture only)
- 
+
 IODATA (jp)
 ------
    GV-BCTV/PCI
@@ -542,15 +542,15 @@ Canopus (jp)
 -------
    WinDVR	= Kworld "KW-TVL878RF"
 
-www.sigmacom.co.kr 
+www.sigmacom.co.kr
 ------------------
-   Sigma Cyber TV II 
+   Sigma Cyber TV II
 
 www.sasem.co.kr
 ---------------
    Litte OnAir TV
 
-hama 
+hama
 ----
    TV/Radio-Tuner Card, PCI (Model 44677) = CPH051
 
@@ -638,7 +638,7 @@ Media-Surfer  (esc-kathrein.de)
 
 Jetway (www.jetway.com.tw)
 --------------------------
-   JW-TV 878M 
+   JW-TV 878M
    JW-TV 878  = KWorld KW-TV878RF
 
 Galaxis
@@ -715,7 +715,7 @@ Hauppauge
   809 MyVideo
   872 MyTV2Go FM
 
- 
+
   546 WinTV Nova-S CI
   543 WinTV Nova
   907 Nova-S USB
@@ -739,7 +739,7 @@ Hauppauge
   832 MyTV2Go
   869 MyTV2Go-FM
   805 MyVideo (USB)
-  
+
 
 Matrix-Vision
 -------------
@@ -764,7 +764,7 @@ Gallant  (www.gallantcom.com) www.minton
    Intervision IV-550 (bt8x8)
    Intervision IV-100 (zoran)
    Intervision IV-1000 (bt8x8)
-   
+
 Asonic (www.asonic.com.cn) (website down)
 -----------------------------------------
    SkyEye tv 878
@@ -804,11 +804,11 @@ Kworld (www.kworld.com.tw)
 
 JTT/ Justy Corp.http://www.justy.co.jp/ (www.jtt.com.jp website down)
 ---------------------------------------------------------------------
-   JTT-02 (JTT TV) "TV watchmate pro" (bt848) 
+   JTT-02 (JTT TV) "TV watchmate pro" (bt848)
 
 ADS www.adstech.com
 -------------------
-   Channel Surfer TV ( CHX-950 ) 
+   Channel Surfer TV ( CHX-950 )
    Channel Surfer TV+FM ( CHX-960FM )
 
 AVEC www.prochips.com
@@ -874,7 +874,7 @@ www.ids-imaging.de
 ------------------
    Falcon Series (capture only)
  In USA: http://www.theimagingsource.com/
-   DFG/LC1	
+   DFG/LC1
 
 www.sknet-web.co.jp
 -------------------
@@ -890,7 +890,7 @@ Cybertainment
    CyberMail Xtreme
   These are Flyvideo
 
-VCR (http://www.vcrinc.com/) 
+VCR (http://www.vcrinc.com/)
 ---
   Video Catcher 16
 
@@ -920,7 +920,7 @@ Sdisilk www.sdisilk.com/
     SDI Silk 200 SDI Input Card
 
 www.euresys.com
-    PICOLO series 
+    PICOLO series
 
 PMC/Pace
 www.pacecom.co.uk website closed
diff --git a/Documentation/video4linux/bttv/Insmod-options b/Documentation/video4linux/bttv/Insmod-options
--- a/Documentation/video4linux/bttv/Insmod-options
+++ b/Documentation/video4linux/bttv/Insmod-options
@@ -44,6 +44,9 @@ bttv.o
 				push used by bttv.  bttv will disable overlay
 				by default on this hardware to avoid crashes.
 				With this insmod option you can override this.
+		no_overlay=1	Disable overlay. It should be used by broken
+				hardware that doesn't support PCI2PCI direct
+				transfers.
 		automute=0/1	Automatically mutes the sound if there is
 				no TV signal, on by default.  You might try
 				to disable this if you have bad input signal
diff --git a/Documentation/video4linux/hauppauge-wintv-cx88-ir.txt b/Documentation/video4linux/hauppauge-wintv-cx88-ir.txt
new file mode 100644
--- /dev/null
+++ b/Documentation/video4linux/hauppauge-wintv-cx88-ir.txt
@@ -0,0 +1,54 @@
+The controls for the mux are GPIO [0,1] for source, and GPIO 2 for muting.
+
+GPIO0  GPIO1
+  0        0    TV Audio
+  1        0    FM radio
+  0        1    Line-In
+  1        1    Mono tuner bypass or CD passthru (tuner specific)
+
+GPIO 16(i believe) is tied to the IR port (if present).
+
+------------------------------------------------------------------------------------
+
+>From the data sheet:
+ Register 24'h20004  PCI Interrupt Status
+  bit [18]  IR_SMP_INT Set when 32 input samples have been collected over
+  gpio[16] pin into GP_SAMPLE register.
+
+What's missing from the data sheet:
+
+Setup 4KHz sampling rate (roughly 2x oversampled; good enough for our RC5
+compat remote)
+set register 0x35C050 to  0xa80a80
+
+enable sampling
+set register 0x35C054 to 0x5
+
+Of course, enable the IRQ bit 18 in the interrupt mask register .(and
+provide for a handler)
+
+GP_SAMPLE register is at 0x35C058
+
+Bits are then right shifted into the GP_SAMPLE register at the specified
+rate; you get an interrupt when a full DWORD is recieved.
+You need to recover the actual RC5 bits out of the (oversampled) IR sensor
+bits. (Hint: look for the 0/1and 1/0 crossings of the RC5 bi-phase data)  An
+actual raw RC5 code will span 2-3 DWORDS, depending on the actual alignment.
+
+I'm pretty sure when no IR signal is present the receiver is always in a
+marking state(1); but stray light, etc can cause intermittent noise values
+as well.  Remember, this is a free running sample of the IR receiver state
+over time, so don't assume any sample starts at any particular place.
+
+http://www.atmel.com/dyn/resources/prod_documents/doc2817.pdf
+This data sheet (google search) seems to have a lovely description of the
+RC5 basics
+
+http://users.pandora.be/nenya/electronics/rc5/  and more data
+
+http://www.ee.washington.edu/circuit_archive/text/ir_decode.txt
+and even a reference to how to decode a bi-phase data stream.
+
+http://www.xs4all.nl/~sbp/knowledge/ir/rc5.htm
+still more info
+
diff --git a/Documentation/video4linux/lifeview.txt b/Documentation/video4linux/lifeview.txt
new file mode 100644
--- /dev/null
+++ b/Documentation/video4linux/lifeview.txt
@@ -0,0 +1,42 @@
+collecting data about the lifeview models and the config coding on
+gpio pins 0-9 ...
+==================================================================
+
+bt878:
+ LR50 rev. Q ("PARTS: 7031505116), Tuner wurde als Nr. 5 erkannt, EingÃ¤nge
+ SVideo, TV, Composite, Audio, Remote. CP9..1=100001001 (1: 0-Ohm-Widerstand
+ gegen GND unbestÃ¼ckt; 0: bestÃ¼ckt)
+
+------------------------------------------------------------------------------
+
+saa7134:
+                /* LifeView FlyTV Platinum FM (LR214WF) */
+                /* "Peter Missel <peter.missel@onlinehome.de> */
+                .name           = "LifeView FlyTV Platinum FM",
+                /*      GP27    MDT2005 PB4 pin 10 */
+                /*      GP26    MDT2005 PB3 pin 9 */
+                /*      GP25    MDT2005 PB2 pin 8 */
+                /*      GP23    MDT2005 PB1 pin 7 */
+                /*      GP22    MDT2005 PB0 pin 6 */
+                /*      GP21    MDT2005 PB5 pin 11 */
+                /*      GP20    MDT2005 PB6 pin 12 */
+                /*      GP19    MDT2005 PB7 pin 13 */
+                /*      nc      MDT2005 PA3 pin 2 */
+                /*      Remote  MDT2005 PA2 pin 1 */
+                /*      GP18    MDT2005 PA1 pin 18 */
+                /*      nc      MDT2005 PA0 pin 17 strap low */
+
+                /*      GP17    Strap "GP7"=High */
+                /*      GP16    Strap "GP6"=High
+                                0=Radio 1=TV
+                                Drives SA630D ENCH1 and HEF4052 A1 pins
+                                to do FM radio through SIF input */
+                /*      GP15    nc */
+                /*      GP14    nc */
+                /*      GP13    nc */
+                /*      GP12    Strap "GP5" = High */
+                /*      GP11    Strap "GP4" = High */
+                /*      GP10    Strap "GP3" = High */
+                /*      GP09    Strap "GP2" = Low */
+                /*      GP08    Strap "GP1" = Low */
+                /*      GP07.00 nc */
diff --git a/Documentation/video4linux/not-in-cx2388x-datasheet.txt b/Documentation/video4linux/not-in-cx2388x-datasheet.txt
new file mode 100644
--- /dev/null
+++ b/Documentation/video4linux/not-in-cx2388x-datasheet.txt
@@ -0,0 +1,41 @@
+=================================================================================
+MO_OUTPUT_FORMAT (0x310164)
+
+  Previous default from DScaler: 0x1c1f0008
+  Digit 8: 31-28
+  28: PREVREMOD = 1
+
+  Digit 7: 27-24 (0xc = 12 = b1100 )
+  27: COMBALT = 1
+  26: PAL_INV_PHASE
+    (DScaler apparently set this to 1, resulted in sucky picture)
+
+  Digits 6,5: 23-16
+  25-16: COMB_RANGE = 0x1f [default] (9 bits -> max 512)
+
+  Digit 4: 15-12
+  15: DISIFX = 0
+  14: INVCBF = 0
+  13: DISADAPT = 0
+  12: NARROWADAPT = 0
+
+  Digit 3: 11-8
+  11: FORCE2H
+  10: FORCEREMD
+  9: NCHROMAEN
+  8: NREMODEN
+
+  Digit 2: 7-4
+  7-6: YCORE
+  5-4: CCORE
+
+  Digit 1: 3-0
+  3: RANGE = 1
+  2: HACTEXT
+  1: HSFMT
+
+0x47 is the sync byte for MPEG-2 transport stream packets.
+Datasheet incorrectly states to use 47 decimal. 188 is the length.
+All DVB compliant frontends output packets with this start code.
+
+=================================================================================
diff --git a/Documentation/w1/w1.generic b/Documentation/w1/w1.generic
--- a/Documentation/w1/w1.generic
+++ b/Documentation/w1/w1.generic
@@ -1,19 +1,92 @@
-Any w1 device must be connected to w1 bus master device - for example
-ds9490 usb device or w1-over-GPIO or RS232 converter.
-Driver for w1 bus master must provide several functions(you can find
-them in struct w1_bus_master definition in w1.h) which then will be
-called by w1 core to send various commands over w1 bus(by default it is
-reset and search commands). When some device is found on the bus, w1 core
-checks if driver for it's family is loaded.
-If driver is loaded w1 core creates new w1_slave object and registers it
-in the system(creates some generic sysfs files(struct w1_family_ops in
-w1_family.h), notifies any registered listener and so on...).
-It is device driver's business to provide any communication method
-upstream.
-For example w1_therm driver(ds18?20 thermal sensor family driver)
-provides temperature reading function which is bound to ->rbin() method
-of the above w1_family_ops structure.
-w1_smem - driver for simple 64bit memory cell provides ID reading
-method.
+The 1-wire (w1) subsystem
+------------------------------------------------------------------
+The 1-wire bus is a simple master-slave bus that communicates via a single
+signal wire (plus ground, so two wires).
+
+Devices communicate on the bus by pulling the signal to ground via an open
+drain output and by sampling the logic level of the signal line.
+
+The w1 subsystem provides the framework for managing w1 masters and
+communication with slaves.
+
+All w1 slave devices must be connected to a w1 bus master device.
+
+Example w1 master devices:
+    DS9490 usb device
+    W1-over-GPIO
+    DS2482 (i2c to w1 bridge)
+    Emulated devices, such as a RS232 converter, parallel port adapter, etc
+
+
+What does the w1 subsystem do?
+------------------------------------------------------------------
+When a w1 master driver registers with the w1 subsystem, the following occurs:
+
+ - sysfs entries for that w1 master are created
+ - the w1 bus is periodically searched for new slave devices
+
+When a device is found on the bus, w1 core checks if driver for it's family is
+loaded. If so, the family driver is attached to the slave.
+If there is no driver for the family, a simple sysfs entry is created
+for the slave device.
+
+
+W1 device families
+------------------------------------------------------------------
+Slave devices are handled by a driver written for a family of w1 devices.
+
+A family driver populates a struct w1_family_ops (see w1_family.h) and
+registers with the w1 subsystem.
+
+Current family drivers:
+w1_therm - (ds18?20 thermal sensor family driver)
+    provides temperature reading function which is bound to ->rbin() method
+    of the above w1_family_ops structure.
+
+w1_smem - driver for simple 64bit memory cell provides ID reading method.
 
 You can call above methods by reading appropriate sysfs files.
+
+
+What does a w1 master driver need to implement?
+------------------------------------------------------------------
+
+The driver for w1 bus master must provide at minimum two functions.
+
+Emulated devices must provide the ability to set the output signal level
+(write_bit) and sample the signal level (read_bit).
+
+Devices that support the 1-wire natively must provide the ability to write and
+sample a bit (touch_bit) and reset the bus (reset_bus).
+
+Most hardware provides higher-level functions that offload w1 handling.
+See struct w1_bus_master definition in w1.h for details.
+
+
+w1 master sysfs interface
+------------------------------------------------------------------
+<xx-xxxxxxxxxxxxx> - a directory for a found device. The format is family-serial
+bus                - (standard) symlink to the w1 bus
+driver             - (standard) symlink to the w1 driver
+w1_master_attempts - the number of times a search was attempted
+w1_master_max_slave_count
+                   - the maximum slaves that may be attached to a master
+w1_master_name     - the name of the device (w1_bus_masterX)
+w1_master_search   - the number of searches left to do, -1=continual (default)
+w1_master_slave_count
+                   - the number of slaves found
+w1_master_slaves   - the names of the slaves, one per line
+w1_master_timeout  - the delay in seconds between searches
+
+If you have a w1 bus that never changes (you don't add or remove devices),
+you can set w1_master_search to a positive value to disable searches.
+
+
+w1 slave sysfs interface
+------------------------------------------------------------------
+bus                - (standard) symlink to the w1 bus
+driver             - (standard) symlink to the w1 driver
+name               - the device name, usually the same as the directory name
+w1_slave           - (optional) a binary file whose meaning depends on the
+                     family driver
+
diff --git a/Documentation/x86_64/boot-options.txt b/Documentation/x86_64/boot-options.txt
--- a/Documentation/x86_64/boot-options.txt
+++ b/Documentation/x86_64/boot-options.txt
@@ -6,6 +6,11 @@ only the AMD64 specific ones are listed 
 Machine check
 
    mce=off disable machine check
+   mce=bootlog Enable logging of machine checks left over from booting.
+               Disabled by default because some BIOS leave bogus ones.
+               If your BIOS doesn't do that it's a good idea to enable though
+               to make sure you log even machine check events that result
+               in a reboot.
 
    nomce (for compatibility with i386): same as mce=off
 
@@ -47,7 +52,7 @@ Timing
   notsc
   Don't use the CPU time stamp counter to read the wall time.
   This can be used to work around timing problems on multiprocessor systems
-  with not properly synchronized CPUs. Only useful with a SMP kernel
+  with not properly synchronized CPUs.
 
   report_lost_ticks
   Report when timer interrupts are lost because some code turned off
@@ -74,6 +79,9 @@ Idle loop
   event. This will make the CPUs eat a lot more power, but may be useful
   to get slightly better performance in multiprocessor benchmarks. It also
   makes some profiling using performance counters more accurate.
+  Please note that on systems with MONITOR/MWAIT support (like Intel EM64T
+  CPUs) this option has no performance advantage over the normal idle loop.
+  It may also interact badly with hyperthreading.
 
 Rebooting
 
@@ -178,6 +186,5 @@ Debugging
 Misc
 
   noreplacement  Don't replace instructions with more appropiate ones
-  				 for the CPU. This may be useful on asymmetric MP systems
-				 where some CPU have less capabilities than the others.
-
+		 for the CPU. This may be useful on asymmetric MP systems
+		 where some CPU have less capabilities than the others.
diff --git a/MAINTAINERS b/MAINTAINERS
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -194,7 +194,7 @@ S:	Maintained
 ADM1025 HARDWARE MONITOR DRIVER
 P:	Jean Delvare
 M:	khali@linux-fr.org
-L:	sensors@stimpy.netroedge.com
+L:	lm-sensors@lm-sensors.org
 S:	Maintained
 
 ADT746X FAN DRIVER
@@ -242,7 +242,7 @@ S:	Maintained
 ALI1563 I2C DRIVER
 P:	Rudolf Marek
 M:	r.marek@sh.cvut.cz
-L:	sensors@stimpy.netroedge.com
+L:	lm-sensors@lm-sensors.org
 S:	Maintained
 
 ALPHA PORT
@@ -265,6 +265,11 @@ P:	Arnaldo Carvalho de Melo
 M:	acme@conectiva.com.br
 S:	Maintained
 
+ARC FRAMEBUFFER DRIVER
+P:	Jaya Kumar
+M:	jayalk@intworks.biz
+S:	Maintained
+
 ARM26 ARCHITECTURE
 P:	Ian Molton
 M:	spyro@f2s.com
@@ -299,7 +304,7 @@ S:	Maintained
 ARM/PT DIGITAL BOARD PORT
 P:	Stefan Eletzhofer
 M:	stefan.eletzhofer@eletztrick.de
-L:	linux-arm-kernel@lists.arm.linux.org.uk
+L:	linux-arm-kernel@lists.arm.linux.org.uk	(subscribers-only)
 W:	http://www.arm.linux.org.uk/
 S:	Maintained
 
@@ -312,21 +317,21 @@ S:	Maintained
 ARM/STRONGARM110 PORT
 P:	Russell King
 M:	rmk@arm.linux.org.uk
-L:	linux-arm-kernel@lists.arm.linux.org.uk
+L:	linux-arm-kernel@lists.arm.linux.org.uk	(subscribers-only)
 W:	http://www.arm.linux.org.uk/
 S:	Maintained
 
 ARM/S3C2410 ARM ARCHITECTURE
 P:	Ben Dooks
 M:	ben-s3c2410@fluff.org
-L:	linux-arm-kernel@lists.arm.linux.org.uk
+L:	linux-arm-kernel@lists.arm.linux.org.uk	(subscribers-only)
 W:	http://www.fluff.org/ben/linux/
 S:	Maintained
 
 ARM/S3C2440 ARM ARCHITECTURE
 P:	Ben Dooks
 M:	ben-s3c2440@fluff.org
-L:	linux-arm-kernel@lists.arm.linux.org.uk
+L:	linux-arm-kernel@lists.arm.linux.org.uk	(subscribers-only)
 W:	http://www.fluff.org/ben/linux/
 S:	Maintained
 
@@ -365,6 +370,10 @@ W:	http://www.thekelleys.org.uk/atmel
 W:	http://atmelwlandriver.sourceforge.net/
 S:	Maintained
 
+AUDIT SUBSYSTEM
+L:	linux-audit@redhat.com (subscribers-only)
+S:	Maintained
+
 AX.25 NETWORK LAYER
 P:	Ralf Baechle
 M:	ralf@linux-mips.org
@@ -499,12 +508,19 @@ L:   bonding-devel@lists.sourceforge.net
 W:   http://sourceforge.net/projects/bonding/
 S:   Supported
 
+BROADBAND PROCESSOR ARCHITECTURE
+P:	Arnd Bergmann
+M:	arnd@arndb.de
+L:	linuxppc64-dev@ozlabs.org
+W:	http://linuxppc64.org
+S:	Supported
+
 BTTV VIDEO4LINUX DRIVER
-P:	Gerd Knorr
-M:	kraxel@bytesex.org
+P:	Mauro Carvalho Chehab
+M:	mchehab@brturbo.com.br
 L:	video4linux-list@redhat.com
-W:	http://bytesex.org/bttv/
-S:	Orphan
+W:	http://linuxtv.org
+S:	Maintained
 
 BUSLOGIC SCSI DRIVER
 P:	Leonard N. Zubkoff
@@ -564,10 +580,9 @@ S:	Supported
 
 COMPUTONE INTELLIPORT MULTIPORT CARD
 P:	Michael H. Warfield
-M:	Michael H. Warfield <mhw@wittsend.com>
+M:	mhw@wittsend.com
 W:	http://www.wittsend.com/computone.html
-L:	linux-computone@lazuli.wittsend.com
-S:	Orphaned
+S:	Maintained
 
 COSA/SRP SYNC SERIAL DRIVER
 P:	Jan "Yenya" Kasprzak
@@ -736,6 +751,11 @@ M:	tori@unhappy.mine.nu
 L:	linux-kernel@vger.kernel.org
 S:	Maintained
 
+DOCBOOK FOR DOCUMENTATION
+P:	Martin Waitz
+M:	tali@admingilde.org
+S:	Maintained
+
 DOUBLETALK DRIVER
 P:	James R. Van Zandt
 M:	jrv@vanzandt.mv.com
@@ -764,7 +784,7 @@ DVB SUBSYSTEM AND DRIVERS
 P:	LinuxTV.org Project
 M: 	linux-dvb-maintainer@linuxtv.org
 L: 	linux-dvb@linuxtv.org (subscription required)
-W:	http://linuxtv.org/developer/dvb.xml
+W:	http://linuxtv.org/
 S:	Supported
 
 EATA-DMA SCSI DRIVER
@@ -992,7 +1012,7 @@ P:	Greg Kroah-Hartman
 M:	greg@kroah.com
 P:	Jean Delvare
 M:	khali@linux-fr.org
-L:	sensors@stimpy.netroedge.com
+L:	lm-sensors@lm-sensors.org
 W:	http://www.lm-sensors.nu/
 S:	Maintained
 
@@ -1133,7 +1153,7 @@ S:	Maintained
 
 INFINIBAND SUBSYSTEM
 P:	Roland Dreier
-M:	roland@topspin.com
+M:	rolandd@cisco.com
 P:	Sean Hefty
 M:	mshefty@ichips.intel.com
 P:	Hal Rosenstock
@@ -1149,6 +1169,12 @@ L:	linux-input@atrey.karlin.mff.cuni.cz
 L:	linux-joystick@atrey.karlin.mff.cuni.cz
 S:	Maintained
 
+INOTIFY
+P:	John McCutchan and Robert Love
+M:	ttb@tentacle.dhs.org and rml@novell.com
+L:	linux-kernel@vger.kernel.org
+S:	Maintained
+
 INTEL 810/815 FRAMEBUFFER DRIVER
 P:      Antonino Daplas
 M:      adaplas@pol.net
@@ -1220,7 +1246,7 @@ S:	Maintained
 
 IRDA SUBSYSTEM
 P:	Jean Tourrilhes
-L:	irda-users@lists.sourceforge.net
+L:	irda-users@lists.sourceforge.net (subscribers-only)
 W:	http://irda.sourceforge.net/
 S:	Maintained
 
@@ -1313,6 +1339,16 @@ M:	rml@novell.com
 L:	linux-kernel@vger.kernel.org
 S:	Maintained
 
+KEXEC
+P:	Eric Biederman
+P:	Randy Dunlap
+M:	ebiederm@xmission.com
+M:	rddunlap@osdl.org
+W:	http://www.xmission.com/~ebiederm/files/kexec/
+L:	linux-kernel@vger.kernel.org
+L:	fastboot@osdl.org
+S:	Maintained
+
 LANMEDIA WAN CARD DRIVER
 P:	Andrew Stanley-Jones
 M:	asj@lanmedia.com
@@ -1380,13 +1416,20 @@ W:	http://www.penguinppc.org/
 L:	linuxppc-embedded@ozlabs.org
 S:	Maintained
 
-LINUX FOR POWERPC EMBEDDED PPC8XX AND BOOT CODE
+LINUX FOR POWERPC BOOT CODE
 P:	Tom Rini
 M:	trini@kernel.crashing.org
 W:	http://www.penguinppc.org/
 L:	linuxppc-embedded@ozlabs.org
 S:	Maintained
 
+LINUX FOR POWERPC EMBEDDED PPC8XX
+P:	Marcelo Tosatti
+M:	marcelo.tosatti@cyclades.com
+W:	http://www.penguinppc.org/
+L:	linuxppc-embedded@ozlabs.org
+S:	Maintained
+
 LINUX FOR POWERPC EMBEDDED PPC83XX AND PPC85XX
 P:     Kumar Gala
 M:     kumar.gala@freescale.com
@@ -1420,13 +1463,13 @@ S:	Supported
 LM83 HARDWARE MONITOR DRIVER
 P:	Jean Delvare
 M:	khali@linux-fr.org
-L:	sensors@stimpy.netroedge.com
+L:	lm-sensors@lm-sensors.org
 S:	Maintained
 
 LM90 HARDWARE MONITOR DRIVER
 P:	Jean Delvare
 M:	khali@linux-fr.org
-L:	sensors@stimpy.netroedge.com
+L:	lm-sensors@lm-sensors.org
 S:	Maintained
 
 LOGICAL DISK MANAGER SUPPORT (LDM, Windows 2000/XP Dynamic Disks)
@@ -1478,6 +1521,12 @@ P:	Zach Brown
 M:	zab@zabbo.net
 S:	Odd Fixes
 
+MAN-PAGES: MANUAL PAGES FOR LINUX -- Sections 2, 3, 4, 5, and 7
+P: Michael Kerrisk
+M: mtk-manpages@gmx.net
+W: ftp://ftp.kernel.org/pub/linux/docs/manpages
+S: Maintained
+
 MARVELL MV64340 ETHERNET DRIVER
 P:	Manish Lachwani
 M:	Manish_Lachwani@pmc-sierra.com
@@ -1609,7 +1658,7 @@ M:	kuznet@ms2.inr.ac.ru
 P:	Pekka Savola (ipv6)
 M:	pekkas@netcore.fi
 P:	James Morris
-M:	jmorris@redhat.com
+M:	jmorris@namei.org
 P:	Hideaki YOSHIFUJI
 M:	yoshfuji@linux-ipv6.org
 P:	Patrick McHardy
@@ -1690,7 +1739,7 @@ S:	Maintained
 
 OPL3-SA2, SA3, and SAx DRIVER
 P:	Zwane Mwaikambo
-M:	zwane@commfireservices.com
+M:	zwane@arm.linux.org.uk
 L:	linux-sound@vger.kernel.org
 S:	Maintained
 
@@ -1776,9 +1825,16 @@ P:	Greg Kroah-Hartman
 M:	greg@kroah.com
 S:	Maintained
 
+PCIE HOTPLUG DRIVER
+P:	Kristen Carlson Accardi
+M:	kristen.c.accardi@intel.com
+L:	pcihpd-discuss@lists.sourceforge.net
+S:	Maintained
+
 PCMCIA SUBSYSTEM
+P:	Linux PCMCIA Team
 L:	http://lists.infradead.org/mailman/listinfo/linux-pcmcia
-S:	Unmaintained
+S:	Maintained
 
 PCNET32 NETWORK DRIVER
 P:	Thomas Bogendörfer
@@ -1843,7 +1899,7 @@ S:	Maintained
 PXA2xx SUPPORT
 P:	Nicolas Pitre
 M:	nico@cam.org
-L:	linux-arm-kernel@lists.arm.linux.org.uk
+L:	linux-arm-kernel@lists.arm.linux.org.uk	(subscribers-only)
 S:	Maintained
 
 QLOGIC QLA2XXX FC-SCSI DRIVER
@@ -1939,7 +1995,7 @@ S:	Maintained
 
 SC1200 WDT DRIVER
 P:	Zwane Mwaikambo
-M:	zwane@commfireservices.com
+M:	zwane@arm.linux.org.uk
 S:	Maintained
 
 SCHEDULER
@@ -1997,7 +2053,7 @@ SELINUX SECURITY MODULE
 P:	Stephen Smalley
 M:	sds@epoch.ncsc.mil
 P:	James Morris
-M:	jmorris@redhat.com
+M:	jmorris@namei.org
 L:	linux-kernel@vger.kernel.org (kernel issues)
 L: 	selinux@tycho.nsa.gov (general discussion)
 W:	http://www.nsa.gov/selinux
@@ -2065,7 +2121,7 @@ S:	Maintained
 SMSC47M1 HARDWARE MONITOR DRIVER
 P:	Jean Delvare
 M:	khali@linux-fr.org
-L:	sensors@stimpy.netroedge.com
+L:	lm-sensors@lm-sensors.org
 S:	Odd Fixes
 
 SMB FILESYSTEM
@@ -2098,9 +2154,7 @@ S:	Maintained
 SOFTWARE SUSPEND:
 P:	Pavel Machek
 M:	pavel@suse.cz
-M:	pavel@ucw.cz
-L:	http://lister.fornax.hu/mailman/listinfo/swsusp
-W:	http://swsusp.sf.net/
+L:	linux-pm@osdl.org
 S:	Maintained
 
 SONIC NETWORK DRIVER
@@ -2128,11 +2182,16 @@ W:	http://tpmdd.sourceforge.net
 L:	tpmdd-devel@lists.sourceforge.net
 S:	Maintained
 
+TENSILICA XTENSA PORT (xtensa):
+P:	Chris Zankel
+M:	chris@zankel.net
+S:	Maintained
+
 UltraSPARC (sparc64):
 P:	David S. Miller
 M:	davem@davemloft.net
 P:	Eddie C. Dost
-M:	ecd@skynet.be
+M:	ecd@brainaid.de
 P:	Jakub Jelinek
 M:	jj@sunsite.ms.mff.cuni.cz
 P:	Anton Blanchard
@@ -2145,7 +2204,13 @@ SHARP LH SUPPORT (LH7952X & LH7A40X)
 P:	Marc Singer
 M:	elf@buici.com
 W:	http://projects.buici.com/arm
-L:	linux-arm-kernel@lists.arm.linux.org.uk
+L:	linux-arm-kernel@lists.arm.linux.org.uk	(subscribers-only)
+S:	Maintained
+
+SHPC HOTPLUG DRIVER
+P:	Kristen Carlson Accardi
+M:	kristen.c.accardi@intel.com
+L:	pcihpd-discuss@lists.sourceforge.net
 S:	Maintained
 
 SPARC (sparc32):
@@ -2386,6 +2451,12 @@ L:	linux-usb-users@lists.sourceforge.net
 L:	linux-usb-devel@lists.sourceforge.net
 S:	Maintained
 
+USB OPTION-CARD DRIVER
+P:	Matthias Urlichs
+M:	smurf@smurf.noris.de
+L:	linux-usb-devel@lists.sourceforge.net
+S:	Maintained
+
 USB OV511 DRIVER
 P:	Mark McClelland
 M:	mmcclell@bigfoot.com
@@ -2572,7 +2643,7 @@ M:	davidm@snapgear.com
 P:	D. Jeff Dionne (created first uClinux port)
 M:	jeff@uclinux.org
 W:	http://www.uclinux.org/
-L:	uclinux-dev@uclinux.org
+L:	uclinux-dev@uclinux.org  (subscribers-only)
 S:	Maintained
 
 UCLINUX FOR NEC V850
@@ -2596,15 +2667,16 @@ W:	http://rio500.sourceforge.net
 S:	Maintained
 
 VIDEO FOR LINUX
-P:	Gerd Knorr
-M:	kraxel@bytesex.org
+P:	Mauro Carvalho Chehab
+M:	mchehab@brturbo.com.br
 L:	video4linux-list@redhat.com
-S:	Orphan
+W:	http://linuxtv.org
+S:	Maintained
 
 W1 DALLAS'S 1-WIRE BUS
 P:	Evgeniy Polyakov
 M:	johnpol@2ka.mipt.ru
-L:	sensors@stimpy.netroedge.com
+L:	lm-sensors@lm-sensors.org
 S:	Maintained
 
 W83L51xD SD/MMC CARD INTERFACE DRIVER
@@ -2617,7 +2689,7 @@ S:	Maintained
 W83L785TS HARDWARE MONITOR DRIVER
 P:	Jean Delvare
 M:	khali@linux-fr.org
-L:	sensors@stimpy.netroedge.com
+L:	lm-sensors@lm-sensors.org
 S:	Odd Fixes
 
 WAN ROUTER & SANGOMA WANPIPE DRIVERS & API (X.25, FRAME RELAY, PPP, CISCO HDLC)
diff --git a/Makefile b/Makefile
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 VERSION = 2
 PATCHLEVEL = 6
-SUBLEVEL = 12
+SUBLEVEL = 13
 EXTRAVERSION =
 NAME=Woozy Numbat
 
@@ -281,7 +281,7 @@ export quiet Q KBUILD_VERBOSE
 # See documentation in Documentation/kbuild/makefiles.txt
 
 # cc-option
-# Usage: cflags-y += $(call gcc-option, -march=winchip-c6, -march=i586)
+# Usage: cflags-y += $(call cc-option, -march=winchip-c6, -march=i586)
 
 cc-option = $(shell if $(CC) $(CFLAGS) $(1) -S -o /dev/null -xc /dev/null \
              > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi ;)
@@ -518,7 +518,7 @@ CFLAGS		+= $(call add-align,CONFIG_CC_AL
 CFLAGS		+= $(call add-align,CONFIG_CC_ALIGN_JUMPS,-jumps)
 
 ifdef CONFIG_FRAME_POINTER
-CFLAGS		+= -fno-omit-frame-pointer
+CFLAGS		+= -fno-omit-frame-pointer $(call cc-option,-fno-optimize-sibling-calls,)
 else
 CFLAGS		+= -fomit-frame-pointer
 endif
@@ -792,6 +792,9 @@ export CPPFLAGS_vmlinux.lds += -P -C -U$
 	$(Q)$(MAKE) $(build)=$(@D) $@
 %.o: %.c scripts FORCE
 	$(Q)$(MAKE) $(build)=$(@D) $@
+%.ko: scripts FORCE
+	$(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) $(build)=$(@D) $(@:.ko=.o)
+	$(Q)$(MAKE) -rR -f $(srctree)/scripts/Makefile.modpost
 %/:      scripts prepare FORCE
 	$(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) $(build)=$(@D)
 %.lst: %.c scripts FORCE
@@ -1033,6 +1036,7 @@ help:
 	@echo  '  modules_install - Install all modules'
 	@echo  '  dir/            - Build all files in dir and below'
 	@echo  '  dir/file.[ois]  - Build specified target only'
+	@echo  '  dir/file.ko     - Build module including final link'
 	@echo  '  rpm		  - Build a kernel as an RPM package'
 	@echo  '  tags/TAGS	  - Generate tags file for editors'
 	@echo  '  cscope	  - Generate cscope index'
@@ -1149,7 +1153,7 @@ endif # KBUILD_EXTMOD
 #(which is the most common case IMHO) to avoid unneeded clutter in the big tags file.
 #Adding $(srctree) adds about 20M on i386 to the size of the output file!
 
-ifeq ($(KBUILD_OUTPUT),)
+ifeq ($(src),$(obj))
 __srctree =
 else
 __srctree = $(srctree)/
diff --git a/README b/README
--- a/README
+++ b/README
@@ -87,6 +87,16 @@ INSTALLING the kernel:
    kernel source.  Patches are applied from the current directory, but
    an alternative directory can be specified as the second argument.
 
+ - If you are upgrading between releases using the stable series patches
+   (for example, patch-2.6.xx.y), note that these "dot-releases" are
+   not incremental and must be applied to the 2.6.xx base tree. For
+   example, if your base kernel is 2.6.12 and you want to apply the
+   2.6.12.3 patch, you do not and indeed must not first apply the
+   2.6.12.1 and 2.6.12.2 patches. Similarly, if you are running kernel
+   version 2.6.12.2 and want to jump to 2.6.12.3, you must first
+   reverse the 2.6.12.2 patch (that is, patch -R) _before_ applying
+   the 2.6.12.3 patch.
+
  - Make sure you have no stale .o files and dependencies lying around:
 
 		cd linux
diff --git a/REPORTING-BUGS b/REPORTING-BUGS
--- a/REPORTING-BUGS
+++ b/REPORTING-BUGS
@@ -41,18 +41,19 @@ summary from [1.]>" for easy identificat
 [2.] Full description of the problem/report:
 [3.] Keywords (i.e., modules, networking, kernel):
 [4.] Kernel version (from /proc/version):
-[5.] Output of Oops.. message (if applicable) with symbolic information 
+[5.] Most recent kernel version which did not have the bug:
+[6.] Output of Oops.. message (if applicable) with symbolic information
      resolved (see Documentation/oops-tracing.txt)
-[6.] A small shell script or example program which triggers the
+[7.] A small shell script or example program which triggers the
      problem (if possible)
-[7.] Environment
-[7.1.] Software (add the output of the ver_linux script here)
-[7.2.] Processor information (from /proc/cpuinfo):
-[7.3.] Module information (from /proc/modules):
-[7.4.] Loaded driver and hardware information (/proc/ioports, /proc/iomem)
-[7.5.] PCI information ('lspci -vvv' as root)
-[7.6.] SCSI information (from /proc/scsi/scsi)
-[7.7.] Other information that might be relevant to the problem
+[8.] Environment
+[8.1.] Software (add the output of the ver_linux script here)
+[8.2.] Processor information (from /proc/cpuinfo):
+[8.3.] Module information (from /proc/modules):
+[8.4.] Loaded driver and hardware information (/proc/ioports, /proc/iomem)
+[8.5.] PCI information ('lspci -vvv' as root)
+[8.6.] SCSI information (from /proc/scsi/scsi)
+[8.7.] Other information that might be relevant to the problem
        (please look in /proc and include all information that you
        think to be relevant):
 [X.] Other notes, patches, fixes, workarounds:
diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig
--- a/arch/alpha/Kconfig
+++ b/arch/alpha/Kconfig
@@ -509,7 +509,7 @@ config NR_CPUS
 	depends on SMP
 	default "64"
 
-config DISCONTIGMEM
+config ARCH_DISCONTIGMEM_ENABLE
 	bool "Discontiguous Memory Support (EXPERIMENTAL)"
 	depends on EXPERIMENTAL
 	help
@@ -518,9 +518,11 @@ config DISCONTIGMEM
 	  or have huge holes in the physical address space for other reasons.
 	  See <file:Documentation/vm/numa> for more.
 
+source "mm/Kconfig"
+
 config NUMA
 	bool "NUMA Support (EXPERIMENTAL)"
-	depends on DISCONTIGMEM
+	depends on DISCONTIGMEM && BROKEN
 	help
 	  Say Y to compile the kernel to support NUMA (Non-Uniform Memory
 	  Access).  This option is for configuring high-end multiprocessor
@@ -594,6 +596,8 @@ source "fs/Kconfig.binfmt"
 
 endmenu
 
+source "net/Kconfig"
+
 source "drivers/Kconfig"
 
 source "fs/Kconfig"
diff --git a/arch/alpha/defconfig b/arch/alpha/defconfig
--- a/arch/alpha/defconfig
+++ b/arch/alpha/defconfig
@@ -96,7 +96,7 @@ CONFIG_ALPHA_CORE_AGP=y
 CONFIG_ALPHA_BROKEN_IRQ_MASK=y
 CONFIG_EISA=y
 # CONFIG_SMP is not set
-# CONFIG_DISCONTIGMEM is not set
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
 CONFIG_VERBOSE_MCHECK=y
 CONFIG_VERBOSE_MCHECK_ON=1
 CONFIG_PCI_LEGACY_PROC=y
diff --git a/arch/alpha/kernel/irq_alpha.c b/arch/alpha/kernel/irq_alpha.c
--- a/arch/alpha/kernel/irq_alpha.c
+++ b/arch/alpha/kernel/irq_alpha.c
@@ -55,6 +55,8 @@ do_entInt(unsigned long type, unsigned l
 #ifdef CONFIG_SMP
 	  {
 		long cpu;
+
+		local_irq_disable();
 		smp_percpu_timer_interrupt(regs);
 		cpu = smp_processor_id();
 		if (cpu != boot_cpuid) {
diff --git a/arch/alpha/kernel/pci.c b/arch/alpha/kernel/pci.c
--- a/arch/alpha/kernel/pci.c
+++ b/arch/alpha/kernel/pci.c
@@ -350,8 +350,24 @@ pcibios_resource_to_bus(struct pci_dev *
 	region->end = res->end - offset;
 }
 
+void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
+			     struct pci_bus_region *region)
+{
+	struct pci_controller *hose = (struct pci_controller *)dev->sysdata;
+	unsigned long offset = 0;
+
+	if (res->flags & IORESOURCE_IO)
+		offset = hose->io_space->start;
+	else if (res->flags & IORESOURCE_MEM)
+		offset = hose->mem_space->start;
+
+	res->start = region->start + offset;
+	res->end = region->end + offset;
+}
+
 #ifdef CONFIG_HOTPLUG
 EXPORT_SYMBOL(pcibios_resource_to_bus);
+EXPORT_SYMBOL(pcibios_bus_to_resource);
 #endif
 
 int
diff --git a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c
--- a/arch/alpha/kernel/process.c
+++ b/arch/alpha/kernel/process.c
@@ -165,7 +165,6 @@ machine_restart(char *restart_cmd)
 	common_shutdown(LINUX_REBOOT_CMD_RESTART, restart_cmd);
 }
 
-EXPORT_SYMBOL(machine_restart);
 
 void
 machine_halt(void)
@@ -173,7 +172,6 @@ machine_halt(void)
 	common_shutdown(LINUX_REBOOT_CMD_HALT, NULL);
 }
 
-EXPORT_SYMBOL(machine_halt);
 
 void
 machine_power_off(void)
@@ -181,7 +179,6 @@ machine_power_off(void)
 	common_shutdown(LINUX_REBOOT_CMD_POWER_OFF, NULL);
 }
 
-EXPORT_SYMBOL(machine_power_off);
 
 /* Used by sysrq-p, among others.  I don't believe r9-r15 are ever
    saved in the context it's used.  */
diff --git a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c
--- a/arch/alpha/kernel/smp.c
+++ b/arch/alpha/kernel/smp.c
@@ -1036,7 +1036,7 @@ debug_spin_lock(spinlock_t * lock, const
 	"	br	1b\n"
 	".previous"
 	: "=r" (tmp), "=m" (lock->lock), "=r" (stuck)
-	: "1" (lock->lock), "2" (stuck) : "memory");
+	: "m" (lock->lock), "2" (stuck) : "memory");
 
 	if (stuck < 0) {
 		printk(KERN_WARNING
@@ -1115,7 +1115,7 @@ void _raw_write_lock(rwlock_t * lock)
 	".previous"
 	: "=m" (*(volatile int *)lock), "=&r" (regx), "=&r" (regy),
 	  "=&r" (stuck_lock), "=&r" (stuck_reader)
-	: "0" (*(volatile int *)lock), "3" (stuck_lock), "4" (stuck_reader) : "memory");
+	: "m" (*(volatile int *)lock), "3" (stuck_lock), "4" (stuck_reader) : "memory");
 
 	if (stuck_lock < 0) {
 		printk(KERN_WARNING "write_lock stuck at %p\n", inline_pc);
@@ -1153,7 +1153,7 @@ void _raw_read_lock(rwlock_t * lock)
 	"	br	1b\n"
 	".previous"
 	: "=m" (*(volatile int *)lock), "=&r" (regx), "=&r" (stuck_lock)
-	: "0" (*(volatile int *)lock), "2" (stuck_lock) : "memory");
+	: "m" (*(volatile int *)lock), "2" (stuck_lock) : "memory");
 
 	if (stuck_lock < 0) {
 		printk(KERN_WARNING "read_lock stuck at %p\n", inline_pc);
diff --git a/arch/alpha/kernel/systbls.S b/arch/alpha/kernel/systbls.S
--- a/arch/alpha/kernel/systbls.S
+++ b/arch/alpha/kernel/systbls.S
@@ -461,6 +461,11 @@ sys_call_table:
 	.quad sys_add_key
 	.quad sys_request_key			/* 440 */
 	.quad sys_keyctl
+	.quad sys_ioprio_set
+	.quad sys_ioprio_get
+	.quad sys_inotify_init
+	.quad sys_inotify_add_watch		/* 445 */
+	.quad sys_inotify_rm_watch
 
 	.size sys_call_table, . - sys_call_table
 	.type sys_call_table, @object
diff --git a/arch/alpha/kernel/traps.c b/arch/alpha/kernel/traps.c
--- a/arch/alpha/kernel/traps.c
+++ b/arch/alpha/kernel/traps.c
@@ -240,7 +240,7 @@ do_entIF(unsigned long type, struct pt_r
 	siginfo_t info;
 	int signo, code;
 
-	if (regs->ps == 0) {
+	if ((regs->ps & ~IPL_MAX) == 0) {
 		if (type == 1) {
 			const unsigned int *data
 			  = (const unsigned int *) regs->pc;
diff --git a/arch/alpha/mm/numa.c b/arch/alpha/mm/numa.c
--- a/arch/alpha/mm/numa.c
+++ b/arch/alpha/mm/numa.c
@@ -327,8 +327,6 @@ void __init mem_init(void)
 	extern char _text, _etext, _data, _edata;
 	extern char __init_begin, __init_end;
 	unsigned long nid, i;
-	struct page * lmem_map;
-
 	high_memory = (void *) __va(max_low_pfn << PAGE_SHIFT);
 
 	reservedpages = 0;
@@ -338,10 +336,10 @@ void __init mem_init(void)
 		 */
 		totalram_pages += free_all_bootmem_node(NODE_DATA(nid));
 
-		lmem_map = node_mem_map(nid);
 		pfn = NODE_DATA(nid)->node_start_pfn;
 		for (i = 0; i < node_spanned_pages(nid); i++, pfn++)
-			if (page_is_ram(pfn) && PageReserved(lmem_map+i))
+			if (page_is_ram(pfn) &&
+			    PageReserved(nid_page_nr(nid, i)))
 				reservedpages++;
 	}
 
@@ -373,18 +371,18 @@ show_mem(void)
 	show_free_areas();
 	printk("Free swap:       %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
 	for_each_online_node(nid) {
-		struct page * lmem_map = node_mem_map(nid);
 		i = node_spanned_pages(nid);
 		while (i-- > 0) {
+			struct page *page = nid_page_nr(nid, i);
 			total++;
-			if (PageReserved(lmem_map+i))
+			if (PageReserved(page))
 				reserved++;
-			else if (PageSwapCache(lmem_map+i))
+			else if (PageSwapCache(page))
 				cached++;
-			else if (!page_count(lmem_map+i))
+			else if (!page_count(page))
 				free++;
 			else
-				shared += page_count(lmem_map + i) - 1;
+				shared += page_count(page) - 1;
 		}
 	}
 	printk("%ld pages of RAM\n",total);
diff --git a/arch/alpha/oprofile/common.c b/arch/alpha/oprofile/common.c
--- a/arch/alpha/oprofile/common.c
+++ b/arch/alpha/oprofile/common.c
@@ -65,7 +65,7 @@ op_axp_setup(void)
 	model->reg_setup(&reg, ctr, &sys);
 
 	/* Configure the registers on all cpus.  */
-	smp_call_function(model->cpu_setup, &reg, 0, 1);
+	(void)smp_call_function(model->cpu_setup, &reg, 0, 1);
 	model->cpu_setup(&reg);
 	return 0;
 }
@@ -86,7 +86,7 @@ op_axp_cpu_start(void *dummy)
 static int
 op_axp_start(void)
 {
-	smp_call_function(op_axp_cpu_start, NULL, 0, 1);
+	(void)smp_call_function(op_axp_cpu_start, NULL, 0, 1);
 	op_axp_cpu_start(NULL);
 	return 0;
 }
@@ -101,7 +101,7 @@ op_axp_cpu_stop(void *dummy)
 static void
 op_axp_stop(void)
 {
-	smp_call_function(op_axp_cpu_stop, NULL, 0, 1);
+	(void)smp_call_function(op_axp_cpu_stop, NULL, 0, 1);
 	op_axp_cpu_stop(NULL);
 }
 
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -67,10 +67,6 @@ config GENERIC_BUST_SPINLOCK
 config GENERIC_ISA_DMA
 	bool
 
-config GENERIC_IOMAP
-	bool
-	default y
-
 config FIQ
 	bool
 
@@ -161,7 +157,7 @@ config ARCH_RPC
 config ARCH_SA1100
 	bool "SA1100-based"
 	select ISA
-	select DISCONTIGMEM
+	select ARCH_DISCONTIGMEM_ENABLE
 
 config ARCH_S3C2410
 	bool "Samsung S3C2410"
@@ -202,6 +198,11 @@ config ARCH_H720X
 	help
 	  This enables support for systems based on the Hynix HMS720x
 
+config ARCH_AAEC2000
+	bool "Agilent AAEC-2000 based"
+	help
+	  This enables support for systems based on the Agilent AAEC-2000
+
 endchoice
 
 source "arch/arm/mach-clps711x/Kconfig"
@@ -222,7 +223,9 @@ source "arch/arm/mach-pxa/Kconfig"
 
 source "arch/arm/mach-sa1100/Kconfig"
 
-source "arch/arm/mach-omap/Kconfig"
+source "arch/arm/plat-omap/Kconfig"
+
+source "arch/arm/mach-omap1/Kconfig"
 
 source "arch/arm/mach-s3c2410/Kconfig"
 
@@ -234,6 +237,8 @@ source "arch/arm/mach-h720x/Kconfig"
 
 source "arch/arm/mach-versatile/Kconfig"
 
+source "arch/arm/mach-aaec2000/Kconfig"
+
 # Definitions to make life easier
 config ARCH_ACORN
 	bool
@@ -277,7 +282,7 @@ config ISA_DMA_API
 	default y
 
 config PCI
-	bool "PCI support" if ARCH_INTEGRATOR_AP
+	bool "PCI support" if ARCH_INTEGRATOR_AP || ARCH_VERSATILE_PB
 	help
 	  Find out whether you have a PCI motherboard. PCI is the name of a
 	  bus system, i.e. the way the CPU talks to the other stuff inside
@@ -305,7 +310,7 @@ menu "Kernel Features"
 
 config SMP
 	bool "Symmetric Multi-Processing (EXPERIMENTAL)"
-	depends on EXPERIMENTAL #&& n
+	depends on EXPERIMENTAL && BROKEN #&& n
 	help
 	  This enables support for systems with more than one CPU. If you have
 	  a system with only one CPU, like most personal computers, say N. If
@@ -343,7 +348,27 @@ config PREEMPT
 	  Say Y here if you are building a kernel for a desktop, embedded
 	  or real-time system.  Say N if you are unsure.
 
-config DISCONTIGMEM
+config NO_IDLE_HZ
+	bool "Dynamic tick timer"
+	help
+	  Select this option if you want to disable continuous timer ticks
+	  and have them programmed to occur as required. This option saves
+	  power as the system can remain in idle state for longer.
+
+	  By default dynamic tick is disabled during the boot, and can be
+	  manually enabled with:
+
+	    echo 1 > /sys/devices/system/timer/timer0/dyn_tick
+
+	  Alternatively, if you want dynamic tick automatically enabled
+	  during boot, pass "dyntick=enable" via the kernel command string.
+
+	  Please note that dynamic tick may affect the accuracy of
+	  timekeeping on some platforms depending on the implementation.
+	  Currently at least OMAP platform is known to have accurate
+	  timekeeping with dynamic tick.
+
+config ARCH_DISCONTIGMEM_ENABLE
 	bool
 	default (ARCH_LH7A40X && !LH7A40X_CONTIGMEM)
 	help
@@ -352,6 +377,8 @@ config DISCONTIGMEM
 	  or have huge holes in the physical address space for other reasons.
 	  See <file:Documentation/vm/numa> for more.
 
+source "mm/Kconfig"
+
 config LEDS
 	bool "Timer and CPU usage LEDs"
 	depends on ARCH_CDB89712 || ARCH_CO285 || ARCH_EBSA110 || \
@@ -489,7 +516,7 @@ config XIP_PHYS_ADDR
 
 endmenu
 
-if (ARCH_SA1100 || ARCH_INTEGRATOR)
+if (ARCH_SA1100 || ARCH_INTEGRATOR || ARCH_OMAP1)
 
 menu "CPU Frequency scaling"
 
@@ -673,6 +700,8 @@ config APM
 
 endmenu
 
+source "net/Kconfig"
+
 menu "Device Drivers"
 
 source "drivers/base/Kconfig"
@@ -705,7 +734,7 @@ source "drivers/ieee1394/Kconfig"
 
 source "drivers/message/i2o/Kconfig"
 
-source "net/Kconfig"
+source "drivers/net/Kconfig"
 
 source "drivers/isdn/Kconfig"
 
@@ -717,6 +746,8 @@ source "drivers/char/Kconfig"
 
 source "drivers/i2c/Kconfig"
 
+source "drivers/hwmon/Kconfig"
+
 #source "drivers/l3/Kconfig"
 
 source "drivers/misc/Kconfig"
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -56,7 +56,7 @@ tune-$(CONFIG_CPU_XSCALE)	:=$(call cc-op
 tune-$(CONFIG_CPU_V6)		:=-mtune=strongarm
 
 # Need -Uarm for gcc < 3.x
-CFLAGS_ABI	:=$(call cc-option,-mapcs-32,-mabi=apcs-gnu)
+CFLAGS_ABI	:=$(call cc-option,-mapcs-32,-mabi=apcs-gnu) $(call cc-option,-mno-thumb-interwork,)
 CFLAGS		+=$(CFLAGS_ABI) $(arch-y) $(tune-y) $(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) -msoft-float -Uarm
 AFLAGS		+=$(CFLAGS_ABI) $(arch-y) $(tune-y) -msoft-float
 
@@ -91,12 +91,14 @@ textaddr-$(CONFIG_ARCH_FORTUNET)   := 0x
  machine-$(CONFIG_ARCH_IOP3XX)	   := iop3xx
  machine-$(CONFIG_ARCH_IXP4XX)	   := ixp4xx
  machine-$(CONFIG_ARCH_IXP2000)    := ixp2000
- machine-$(CONFIG_ARCH_OMAP)	   := omap
+ machine-$(CONFIG_ARCH_OMAP1)	   := omap1
+  incdir-$(CONFIG_ARCH_OMAP)	   := omap
  machine-$(CONFIG_ARCH_S3C2410)	   := s3c2410
  machine-$(CONFIG_ARCH_LH7A40X)	   := lh7a40x
  machine-$(CONFIG_ARCH_VERSATILE)  := versatile
  machine-$(CONFIG_ARCH_IMX)	   := imx
  machine-$(CONFIG_ARCH_H720X)	   := h720x
+ machine-$(CONFIG_ARCH_AAEC2000)   := aaec2000
 
 ifeq ($(CONFIG_ARCH_EBSA110),y)
 # This is what happens if you forget the IOCS16 line.
@@ -141,6 +143,9 @@ core-$(CONFIG_FPE_NWFPE)	+= arch/arm/nwf
 core-$(CONFIG_FPE_FASTFPE)	+= $(FASTFPE_OBJ)
 core-$(CONFIG_VFP)		+= arch/arm/vfp/
 
+# If we have a common platform directory, then include it in the build.
+core-$(CONFIG_ARCH_OMAP)	+= arch/arm/plat-omap/
+
 drivers-$(CONFIG_OPROFILE)      += arch/arm/oprofile/
 drivers-$(CONFIG_ARCH_CLPS7500)	+= drivers/acorn/char/
 drivers-$(CONFIG_ARCH_L7200)	+= drivers/acorn/char/
diff --git a/arch/arm/boot/compressed/head-shark.S b/arch/arm/boot/compressed/head-shark.S
--- a/arch/arm/boot/compressed/head-shark.S
+++ b/arch/arm/boot/compressed/head-shark.S
@@ -63,8 +63,8 @@ __beginning:	mov	r4, r0				@ save the en
 
 		mov	pc, r2
 
-__copy_target:	.long	0x08508000
-__copy_end:	.long	0x08608000
+__copy_target:	.long	0x08507FFC
+__copy_end:	.long	0x08607FFC
 		
 		.word	_start
 		.word	__bss_start
@@ -73,9 +73,10 @@ __copy_end:	.long	0x08608000
 __temp_stack:	.space 128
 
 __mmu_off:
-		adr	r0, __ofw_data
+		adr	r0, __ofw_data			@ read the 1. entry of the memory map
 		ldr	r0, [r0, #4]
 		orr	r0, r0, #0x00600000
+		sub	r0, r0, #4
 	
 		ldr	r1, __copy_end
 		ldr	r3, __copy_target
@@ -89,20 +90,43 @@ __mmu_off:
  * from 0x08500000 to 0x08508000 if we have only 8MB
  */
 
+/* As we get more 2.6-kernels it gets more and more
+ * uncomfortable to be bound to kernel images of 1MB only.
+ * So we add a loop here, to be able to copy some more.
+ * Alexander Schulz 2005-07-17
+ */
+
+		mov	r4, #3				@ How many megabytes to copy
+
+
+__MoveCode:	sub	r4, r4, #1
 	
 __Copy:		ldr	r2, [r0], #-4
 		str	r2, [r1], #-4
 		teq	r1, r3
 		bne	__Copy
+
+		/* The firmware maps us in blocks of 1 MB, the next block is
+		   _below_ the last one. So our decrementing source pointer
+		   ist right here, but the destination pointer must be increased
+		   by 2 MB */
+		add	r1, r1, #0x00200000
+		add	r3, r3, #0x00100000
+
+		teq	r4, #0
+		bne	__MoveCode
+
+
 		/* and jump to it */
-		adr	r2, __go_on
-		adr	r0, __ofw_data
+		adr	r2, __go_on			@ where we want to jump
+		adr	r0, __ofw_data			@ read the 1. entry of the memory map
 		ldr	r0, [r0, #4]
-		sub	r2, r2, r0
-		sub	r2, r2, #0x00500000
-		ldr	r0, __copy_target
+		sub	r2, r2, r0			@ we are mapped add 0e50 now, sub that (-0e00)
+		sub	r2, r2, #0x00500000		@ -0050
+		ldr	r0, __copy_target		@ and add 0850 8000 instead
+		add	r0, r0, #4
 		add	r2, r2, r0
-		mov	pc, r2
+		mov	pc, r2				@ and jump there
 
 __go_on:
 		adr	sp, __temp_stack
diff --git a/arch/arm/boot/install.sh b/arch/arm/boot/install.sh
--- a/arch/arm/boot/install.sh
+++ b/arch/arm/boot/install.sh
@@ -21,8 +21,8 @@
 #
 
 # User may have a custom install script
-if [ -x ~/bin/installkernel ]; then exec ~/bin/installkernel "$@"; fi
-if [ -x /sbin/installkernel ]; then exec /sbin/installkernel "$@"; fi
+if [ -x ~/bin/${CROSS_COMPILE}installkernel ]; then exec ~/bin/${CROSS_COMPILE}installkernel "$@"; fi
+if [ -x /sbin/${CROSS_COMPILE}installkernel ]; then exec /sbin/${CROSS_COMPILE}installkernel "$@"; fi
 
 if [ "$(basename $2)" = "zImage" ]; then
 # Compressed install
diff --git a/arch/arm/common/amba.c b/arch/arm/common/amba.c
--- a/arch/arm/common/amba.c
+++ b/arch/arm/common/amba.c
@@ -169,7 +169,7 @@ static void amba_device_release(struct d
 }
 
 #define amba_attr(name,fmt,arg...)				\
-static ssize_t show_##name(struct device *_dev, char *buf)	\
+static ssize_t show_##name(struct device *_dev, struct device_attribute *attr, char *buf)	\
 {								\
 	struct amba_device *dev = to_amba_device(_dev);		\
 	return sprintf(buf, fmt, arg);				\
diff --git a/arch/arm/common/dmabounce.c b/arch/arm/common/dmabounce.c
--- a/arch/arm/common/dmabounce.c
+++ b/arch/arm/common/dmabounce.c
@@ -30,6 +30,8 @@
 #include <linux/dmapool.h>
 #include <linux/list.h>
 
+#include <asm/cacheflush.h>
+
 #undef DEBUG
 
 #undef STATS
@@ -91,15 +93,12 @@ static void print_alloc_stats(struct dma
 static inline struct dmabounce_device_info *
 find_dmabounce_dev(struct device *dev)
 {
-	struct list_head *entry;
-
-	list_for_each(entry, &dmabounce_devs) {
-		struct dmabounce_device_info *d =
-			list_entry(entry, struct dmabounce_device_info, node);
+	struct dmabounce_device_info *d;
 
+	list_for_each_entry(d, &dmabounce_devs, node)
 		if (d->dev == dev)
 			return d;
-	}
+
 	return NULL;
 }
 
@@ -170,15 +169,11 @@ alloc_safe_buffer(struct dmabounce_devic
 static inline struct safe_buffer *
 find_safe_buffer(struct dmabounce_device_info *device_info, dma_addr_t safe_dma_addr)
 {
-	struct list_head *entry;
-
-	list_for_each(entry, &device_info->safe_buffers) {
-		struct safe_buffer *b =
-			list_entry(entry, struct safe_buffer, node);
+	struct safe_buffer *b;
 
+	list_for_each_entry(b, &device_info->safe_buffers, node)
 		if (b->safe_dma_addr == safe_dma_addr)
 			return b;
-	}
 
 	return NULL;
 }
@@ -299,15 +294,26 @@ unmap_single(struct device *dev, dma_add
 			__func__, buf->ptr, (void *) virt_to_dma(dev, buf->ptr),
 			buf->safe, (void *) buf->safe_dma_addr);
 
-
 		DO_STATS ( device_info->bounce_count++ );
 
-		if ((dir == DMA_FROM_DEVICE) ||
-		    (dir == DMA_BIDIRECTIONAL)) {
+		if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL) {
+			unsigned long ptr;
+
 			dev_dbg(dev,
 				"%s: copy back safe %p to unsafe %p size %d\n",
 				__func__, buf->safe, buf->ptr, size);
 			memcpy(buf->ptr, buf->safe, size);
+
+			/*
+			 * DMA buffers must have the same cache properties
+			 * as if they were really used for DMA - which means
+			 * data must be written back to RAM.  Note that
+			 * we don't use dmac_flush_range() here for the
+			 * bidirectional case because we know the cache
+			 * lines will be coherent with the data written.
+			 */
+			ptr = (unsigned long)buf->ptr;
+			dmac_clean_range(ptr, ptr + size);
 		}
 		free_safe_buffer(device_info, buf);
 	}
diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c
--- a/arch/arm/common/sa1111.c
+++ b/arch/arm/common/sa1111.c
@@ -721,16 +721,17 @@ __sa1111_probe(struct device *me, struct
 	return ret;
 }
 
+static int sa1111_remove_one(struct device *dev, void *data)
+{
+	device_unregister(dev);
+	return 0;
+}
+
 static void __sa1111_remove(struct sa1111 *sachip)
 {
-	struct list_head *l, *n;
 	void __iomem *irqbase = sachip->base + SA1111_INTC;
 
-	list_for_each_safe(l, n, &sachip->dev->children) {
-		struct device *d = list_to_dev(l);
-
-		device_unregister(d);
-	}
+	device_for_each_child(sachip->dev, NULL, sa1111_remove_one);
 
 	/* disable all IRQs */
 	sa1111_writel(0, irqbase + SA1111_INTEN0);
diff --git a/arch/arm/common/sharpsl_param.c b/arch/arm/common/sharpsl_param.c
--- a/arch/arm/common/sharpsl_param.c
+++ b/arch/arm/common/sharpsl_param.c
@@ -22,7 +22,7 @@
  * them early in the boot process, then pass them to the appropriate drivers.
  * Not all devices use all paramaters but the format is common to all.
  */
-#ifdef ARCH_SA1100
+#ifdef CONFIG_ARCH_SA1100
 #define PARAM_BASE	0xe8ffc000
 #else
 #define PARAM_BASE	0xa0000a00
diff --git a/arch/arm/configs/bast_defconfig b/arch/arm/configs/bast_defconfig
--- a/arch/arm/configs/bast_defconfig
+++ b/arch/arm/configs/bast_defconfig
@@ -561,7 +561,6 @@ CONFIG_SERIAL_8250_SHARE_IRQ=y
 #
 CONFIG_SERIAL_S3C2410=y
 CONFIG_SERIAL_S3C2410_CONSOLE=y
-CONFIG_SERIAL_BAST_SIO=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_UNIX98_PTYS=y
diff --git a/arch/arm/configs/enp2611_defconfig b/arch/arm/configs/enp2611_defconfig
--- a/arch/arm/configs/enp2611_defconfig
+++ b/arch/arm/configs/enp2611_defconfig
@@ -1,14 +1,13 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc1-bk2
-# Sun Mar 27 22:08:24 2005
+# Linux kernel version: 2.6.13-rc2
+# Thu Jul  7 16:41:21 2005
 #
 CONFIG_ARM=y
 CONFIG_MMU=y
 CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_GENERIC_IOMAP=y
 
 #
 # Code maturity level options
@@ -16,6 +15,7 @@ CONFIG_GENERIC_IOMAP=y
 CONFIG_EXPERIMENTAL=y
 CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
@@ -35,6 +35,8 @@ CONFIG_EMBEDDED=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
@@ -50,7 +52,13 @@ CONFIG_BASE_SMALL=0
 #
 # Loadable module support
 #
-# CONFIG_MODULES is not set
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
 
 #
 # System Type
@@ -76,6 +84,7 @@ CONFIG_ARCH_IXP2000=y
 # CONFIG_ARCH_VERSATILE is not set
 # CONFIG_ARCH_IMX is not set
 # CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_AAEC2000 is not set
 CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y
 
 #
@@ -90,6 +99,7 @@ CONFIG_ARCH_ENP2611=y
 # CONFIG_ARCH_IXDP2800 is not set
 # CONFIG_ARCH_IXDP2401 is not set
 # CONFIG_ARCH_IXDP2801 is not set
+# CONFIG_IXP2000_SUPPORT_BROKEN_PCI_IO is not set
 
 #
 # Processor Type
@@ -100,7 +110,6 @@ CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5T=y
 CONFIG_CPU_CACHE_VIVT=y
 CONFIG_CPU_TLB_V4WBI=y
-CONFIG_CPU_MINICACHE=y
 
 #
 # Processor Features
@@ -112,9 +121,11 @@ CONFIG_XSCALE_PMU=y
 #
 # Bus support
 #
+CONFIG_ISA_DMA_API=y
 CONFIG_PCI=y
 CONFIG_PCI_LEGACY_PROC=y
 CONFIG_PCI_NAMES=y
+# CONFIG_PCI_DEBUG is not set
 
 #
 # PCCARD (PCMCIA/CardBus) support
@@ -124,7 +135,16 @@ CONFIG_PCI_NAMES=y
 #
 # Kernel Features
 #
+# CONFIG_SMP is not set
 # CONFIG_PREEMPT is not set
+# CONFIG_NO_IDLE_HZ is not set
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_ALIGNMENT_TRAP=y
 
 #
@@ -263,7 +283,6 @@ CONFIG_MTD_IXP2000=y
 #
 # Block devices
 #
-# CONFIG_BLK_DEV_FD is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
 # CONFIG_BLK_DEV_DAC960 is not set
@@ -302,6 +321,7 @@ CONFIG_IOSCHED_CFQ=y
 #
 # Fusion MPT device support
 #
+# CONFIG_FUSION is not set
 
 #
 # IEEE 1394 (FireWire) support
@@ -323,12 +343,12 @@ CONFIG_NET=y
 #
 CONFIG_PACKET=y
 CONFIG_PACKET_MMAP=y
-# CONFIG_NETLINK_DEV is not set
 CONFIG_UNIX=y
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
 # CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
 CONFIG_IP_PNP=y
 CONFIG_IP_PNP_DHCP=y
 CONFIG_IP_PNP_BOOTP=y
@@ -343,6 +363,8 @@ CONFIG_SYN_COOKIES=y
 # CONFIG_INET_TUNNEL is not set
 # CONFIG_IP_TCPDIAG is not set
 # CONFIG_IP_TCPDIAG_IPV6 is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
 # CONFIG_IPV6 is not set
 # CONFIG_NETFILTER is not set
 
@@ -398,6 +420,7 @@ CONFIG_MII=y
 # CONFIG_SUNGEM is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
 
 #
 # Tulip family network device support
@@ -434,9 +457,11 @@ CONFIG_EEPRO100=y
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
 # CONFIG_R8169 is not set
+# CONFIG_SKGE is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
 
 #
 # Ethernet (10000 Mbit)
@@ -458,6 +483,7 @@ CONFIG_EEPRO100=y
 # Wan interfaces
 #
 CONFIG_WAN=y
+# CONFIG_DSCC4 is not set
 # CONFIG_LANMEDIA is not set
 # CONFIG_SYNCLINK_SYNCPPP is not set
 CONFIG_HDLC=y
@@ -520,7 +546,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 #
 # CONFIG_SERIO is not set
 # CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
 
 #
 # Character devices
@@ -541,6 +566,7 @@ CONFIG_SERIAL_8250_NR_UARTS=2
 #
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -607,17 +633,18 @@ CONFIG_I2C_ALGOBIT=y
 # CONFIG_I2C_AMD8111 is not set
 # CONFIG_I2C_I801 is not set
 # CONFIG_I2C_I810 is not set
+# CONFIG_I2C_PIIX4 is not set
 # CONFIG_I2C_ISA is not set
 # CONFIG_I2C_IXP2000 is not set
 # CONFIG_I2C_NFORCE2 is not set
 # CONFIG_I2C_PARPORT_LIGHT is not set
-# CONFIG_I2C_PIIX4 is not set
 # CONFIG_I2C_PROSAVAGE is not set
 # CONFIG_I2C_SAVAGE4 is not set
 # CONFIG_SCx200_ACB is not set
 # CONFIG_I2C_SIS5595 is not set
 # CONFIG_I2C_SIS630 is not set
 # CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_STUB is not set
 # CONFIG_I2C_VIA is not set
 # CONFIG_I2C_VIAPRO is not set
 # CONFIG_I2C_VOODOO3 is not set
@@ -631,7 +658,9 @@ CONFIG_I2C_SENSOR=y
 # CONFIG_SENSORS_ADM1025 is not set
 # CONFIG_SENSORS_ADM1026 is not set
 # CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
 # CONFIG_SENSORS_ASB100 is not set
+# CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_FSCHER is not set
 # CONFIG_SENSORS_FSCPOS is not set
@@ -647,6 +676,7 @@ CONFIG_I2C_SENSOR=y
 # CONFIG_SENSORS_LM85 is not set
 # CONFIG_SENSORS_LM87 is not set
 # CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
 # CONFIG_SENSORS_MAX1619 is not set
 # CONFIG_SENSORS_PC87360 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
@@ -656,14 +686,19 @@ CONFIG_I2C_SENSOR=y
 # CONFIG_SENSORS_W83781D is not set
 # CONFIG_SENSORS_W83L785TS is not set
 # CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
 
 #
 # Other I2C Chip support
 #
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
 CONFIG_SENSORS_EEPROM=y
 # CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_SENSORS_PCA9539 is not set
 # CONFIG_SENSORS_PCF8591 is not set
 # CONFIG_SENSORS_RTC8564 is not set
+# CONFIG_SENSORS_MAX6875 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
@@ -717,6 +752,7 @@ CONFIG_EXT2_FS=y
 CONFIG_EXT2_FS_XATTR=y
 CONFIG_EXT2_FS_POSIX_ACL=y
 # CONFIG_EXT2_FS_SECURITY is not set
+# CONFIG_EXT2_FS_XIP is not set
 CONFIG_EXT3_FS=y
 CONFIG_EXT3_FS_XATTR=y
 CONFIG_EXT3_FS_POSIX_ACL=y
@@ -757,7 +793,6 @@ CONFIG_DNOTIFY=y
 #
 CONFIG_PROC_FS=y
 CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
 # CONFIG_DEVPTS_FS_XATTR is not set
 CONFIG_TMPFS=y
 # CONFIG_TMPFS_XATTR is not set
@@ -795,12 +830,14 @@ CONFIG_JFFS2_RTIME=y
 #
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
 # CONFIG_NFS_V4 is not set
 # CONFIG_NFS_DIRECTIO is not set
 # CONFIG_NFSD is not set
 CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
diff --git a/arch/arm/configs/ixdp2400_defconfig b/arch/arm/configs/ixdp2400_defconfig
--- a/arch/arm/configs/ixdp2400_defconfig
+++ b/arch/arm/configs/ixdp2400_defconfig
@@ -1,14 +1,13 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc1-bk2
-# Sun Mar 27 21:13:38 2005
+# Linux kernel version: 2.6.13-rc2
+# Thu Jul  7 16:49:01 2005
 #
 CONFIG_ARM=y
 CONFIG_MMU=y
 CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_GENERIC_IOMAP=y
 
 #
 # Code maturity level options
@@ -16,6 +15,7 @@ CONFIG_GENERIC_IOMAP=y
 CONFIG_EXPERIMENTAL=y
 CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
@@ -35,6 +35,8 @@ CONFIG_EMBEDDED=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
@@ -50,7 +52,13 @@ CONFIG_BASE_SMALL=0
 #
 # Loadable module support
 #
-# CONFIG_MODULES is not set
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
 
 #
 # System Type
@@ -76,6 +84,7 @@ CONFIG_ARCH_IXP2000=y
 # CONFIG_ARCH_VERSATILE is not set
 # CONFIG_ARCH_IMX is not set
 # CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_AAEC2000 is not set
 CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y
 
 #
@@ -91,6 +100,7 @@ CONFIG_ARCH_IXDP2400=y
 CONFIG_ARCH_IXDP2X00=y
 # CONFIG_ARCH_IXDP2401 is not set
 # CONFIG_ARCH_IXDP2801 is not set
+# CONFIG_IXP2000_SUPPORT_BROKEN_PCI_IO is not set
 
 #
 # Processor Type
@@ -101,7 +111,6 @@ CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5T=y
 CONFIG_CPU_CACHE_VIVT=y
 CONFIG_CPU_TLB_V4WBI=y
-CONFIG_CPU_MINICACHE=y
 
 #
 # Processor Features
@@ -113,9 +122,11 @@ CONFIG_XSCALE_PMU=y
 #
 # Bus support
 #
+CONFIG_ISA_DMA_API=y
 CONFIG_PCI=y
 CONFIG_PCI_LEGACY_PROC=y
 CONFIG_PCI_NAMES=y
+# CONFIG_PCI_DEBUG is not set
 
 #
 # PCCARD (PCMCIA/CardBus) support
@@ -125,7 +136,16 @@ CONFIG_PCI_NAMES=y
 #
 # Kernel Features
 #
+# CONFIG_SMP is not set
 # CONFIG_PREEMPT is not set
+# CONFIG_NO_IDLE_HZ is not set
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_ALIGNMENT_TRAP=y
 
 #
@@ -264,7 +284,6 @@ CONFIG_MTD_IXP2000=y
 #
 # Block devices
 #
-# CONFIG_BLK_DEV_FD is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
 # CONFIG_BLK_DEV_DAC960 is not set
@@ -303,6 +322,7 @@ CONFIG_IOSCHED_CFQ=y
 #
 # Fusion MPT device support
 #
+# CONFIG_FUSION is not set
 
 #
 # IEEE 1394 (FireWire) support
@@ -324,12 +344,12 @@ CONFIG_NET=y
 #
 CONFIG_PACKET=y
 CONFIG_PACKET_MMAP=y
-# CONFIG_NETLINK_DEV is not set
 CONFIG_UNIX=y
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
 # CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
 CONFIG_IP_PNP=y
 CONFIG_IP_PNP_DHCP=y
 CONFIG_IP_PNP_BOOTP=y
@@ -344,6 +364,8 @@ CONFIG_SYN_COOKIES=y
 # CONFIG_INET_TUNNEL is not set
 # CONFIG_IP_TCPDIAG is not set
 # CONFIG_IP_TCPDIAG_IPV6 is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
 # CONFIG_IPV6 is not set
 # CONFIG_NETFILTER is not set
 
@@ -399,6 +421,7 @@ CONFIG_MII=y
 # CONFIG_SUNGEM is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
 
 #
 # Tulip family network device support
@@ -435,9 +458,11 @@ CONFIG_EEPRO100=y
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
 # CONFIG_R8169 is not set
+# CONFIG_SKGE is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
 
 #
 # Ethernet (10000 Mbit)
@@ -459,6 +484,7 @@ CONFIG_EEPRO100=y
 # Wan interfaces
 #
 CONFIG_WAN=y
+# CONFIG_DSCC4 is not set
 # CONFIG_LANMEDIA is not set
 # CONFIG_SYNCLINK_SYNCPPP is not set
 CONFIG_HDLC=y
@@ -521,7 +547,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 #
 # CONFIG_SERIO is not set
 # CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
 
 #
 # Character devices
@@ -542,6 +567,7 @@ CONFIG_SERIAL_8250_NR_UARTS=2
 #
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -608,17 +634,18 @@ CONFIG_I2C_ALGOBIT=y
 # CONFIG_I2C_AMD8111 is not set
 # CONFIG_I2C_I801 is not set
 # CONFIG_I2C_I810 is not set
+# CONFIG_I2C_PIIX4 is not set
 # CONFIG_I2C_ISA is not set
 # CONFIG_I2C_IXP2000 is not set
 # CONFIG_I2C_NFORCE2 is not set
 # CONFIG_I2C_PARPORT_LIGHT is not set
-# CONFIG_I2C_PIIX4 is not set
 # CONFIG_I2C_PROSAVAGE is not set
 # CONFIG_I2C_SAVAGE4 is not set
 # CONFIG_SCx200_ACB is not set
 # CONFIG_I2C_SIS5595 is not set
 # CONFIG_I2C_SIS630 is not set
 # CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_STUB is not set
 # CONFIG_I2C_VIA is not set
 # CONFIG_I2C_VIAPRO is not set
 # CONFIG_I2C_VOODOO3 is not set
@@ -632,7 +659,9 @@ CONFIG_I2C_SENSOR=y
 # CONFIG_SENSORS_ADM1025 is not set
 # CONFIG_SENSORS_ADM1026 is not set
 # CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
 # CONFIG_SENSORS_ASB100 is not set
+# CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_FSCHER is not set
 # CONFIG_SENSORS_FSCPOS is not set
@@ -648,6 +677,7 @@ CONFIG_I2C_SENSOR=y
 # CONFIG_SENSORS_LM85 is not set
 # CONFIG_SENSORS_LM87 is not set
 # CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
 # CONFIG_SENSORS_MAX1619 is not set
 # CONFIG_SENSORS_PC87360 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
@@ -657,14 +687,19 @@ CONFIG_I2C_SENSOR=y
 # CONFIG_SENSORS_W83781D is not set
 # CONFIG_SENSORS_W83L785TS is not set
 # CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
 
 #
 # Other I2C Chip support
 #
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
 CONFIG_SENSORS_EEPROM=y
 # CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_SENSORS_PCA9539 is not set
 # CONFIG_SENSORS_PCF8591 is not set
 # CONFIG_SENSORS_RTC8564 is not set
+# CONFIG_SENSORS_MAX6875 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
@@ -718,6 +753,7 @@ CONFIG_EXT2_FS=y
 CONFIG_EXT2_FS_XATTR=y
 CONFIG_EXT2_FS_POSIX_ACL=y
 # CONFIG_EXT2_FS_SECURITY is not set
+# CONFIG_EXT2_FS_XIP is not set
 CONFIG_EXT3_FS=y
 CONFIG_EXT3_FS_XATTR=y
 CONFIG_EXT3_FS_POSIX_ACL=y
@@ -758,7 +794,6 @@ CONFIG_DNOTIFY=y
 #
 CONFIG_PROC_FS=y
 CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
 # CONFIG_DEVPTS_FS_XATTR is not set
 CONFIG_TMPFS=y
 # CONFIG_TMPFS_XATTR is not set
@@ -796,12 +831,14 @@ CONFIG_JFFS2_RTIME=y
 #
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
 # CONFIG_NFS_V4 is not set
 # CONFIG_NFS_DIRECTIO is not set
 # CONFIG_NFSD is not set
 CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
diff --git a/arch/arm/configs/ixdp2401_defconfig b/arch/arm/configs/ixdp2401_defconfig
--- a/arch/arm/configs/ixdp2401_defconfig
+++ b/arch/arm/configs/ixdp2401_defconfig
@@ -1,14 +1,13 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc1-bk2
-# Sun Mar 27 21:53:55 2005
+# Linux kernel version: 2.6.13-rc2
+# Thu Jul  7 16:49:08 2005
 #
 CONFIG_ARM=y
 CONFIG_MMU=y
 CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_GENERIC_IOMAP=y
 
 #
 # Code maturity level options
@@ -16,6 +15,7 @@ CONFIG_GENERIC_IOMAP=y
 CONFIG_EXPERIMENTAL=y
 CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
@@ -35,6 +35,8 @@ CONFIG_EMBEDDED=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
@@ -50,7 +52,13 @@ CONFIG_BASE_SMALL=0
 #
 # Loadable module support
 #
-# CONFIG_MODULES is not set
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
 
 #
 # System Type
@@ -76,6 +84,7 @@ CONFIG_ARCH_IXP2000=y
 # CONFIG_ARCH_VERSATILE is not set
 # CONFIG_ARCH_IMX is not set
 # CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_AAEC2000 is not set
 CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y
 
 #
@@ -91,6 +100,7 @@ CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y
 CONFIG_ARCH_IXDP2401=y
 # CONFIG_ARCH_IXDP2801 is not set
 CONFIG_ARCH_IXDP2X01=y
+# CONFIG_IXP2000_SUPPORT_BROKEN_PCI_IO is not set
 
 #
 # Processor Type
@@ -101,7 +111,6 @@ CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5T=y
 CONFIG_CPU_CACHE_VIVT=y
 CONFIG_CPU_TLB_V4WBI=y
-CONFIG_CPU_MINICACHE=y
 
 #
 # Processor Features
@@ -113,9 +122,11 @@ CONFIG_XSCALE_PMU=y
 #
 # Bus support
 #
+CONFIG_ISA_DMA_API=y
 CONFIG_PCI=y
 CONFIG_PCI_LEGACY_PROC=y
 CONFIG_PCI_NAMES=y
+# CONFIG_PCI_DEBUG is not set
 
 #
 # PCCARD (PCMCIA/CardBus) support
@@ -125,7 +136,16 @@ CONFIG_PCI_NAMES=y
 #
 # Kernel Features
 #
+# CONFIG_SMP is not set
 # CONFIG_PREEMPT is not set
+# CONFIG_NO_IDLE_HZ is not set
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_ALIGNMENT_TRAP=y
 
 #
@@ -264,7 +284,6 @@ CONFIG_MTD_IXP2000=y
 #
 # Block devices
 #
-# CONFIG_BLK_DEV_FD is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
 # CONFIG_BLK_DEV_DAC960 is not set
@@ -303,6 +322,7 @@ CONFIG_IOSCHED_CFQ=y
 #
 # Fusion MPT device support
 #
+# CONFIG_FUSION is not set
 
 #
 # IEEE 1394 (FireWire) support
@@ -324,12 +344,12 @@ CONFIG_NET=y
 #
 CONFIG_PACKET=y
 CONFIG_PACKET_MMAP=y
-# CONFIG_NETLINK_DEV is not set
 CONFIG_UNIX=y
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
 # CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
 CONFIG_IP_PNP=y
 CONFIG_IP_PNP_DHCP=y
 CONFIG_IP_PNP_BOOTP=y
@@ -344,6 +364,8 @@ CONFIG_SYN_COOKIES=y
 # CONFIG_INET_TUNNEL is not set
 CONFIG_IP_TCPDIAG=y
 # CONFIG_IP_TCPDIAG_IPV6 is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
 # CONFIG_IPV6 is not set
 # CONFIG_NETFILTER is not set
 
@@ -399,6 +421,7 @@ CONFIG_MII=y
 # CONFIG_SUNGEM is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
 
 #
 # Tulip family network device support
@@ -436,9 +459,11 @@ CONFIG_EEPRO100=y
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
 # CONFIG_R8169 is not set
+# CONFIG_SKGE is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
 
 #
 # Ethernet (10000 Mbit)
@@ -460,6 +485,7 @@ CONFIG_EEPRO100=y
 # Wan interfaces
 #
 CONFIG_WAN=y
+# CONFIG_DSCC4 is not set
 # CONFIG_LANMEDIA is not set
 # CONFIG_SYNCLINK_SYNCPPP is not set
 CONFIG_HDLC=y
@@ -522,7 +548,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 #
 # CONFIG_SERIO is not set
 # CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
 
 #
 # Character devices
@@ -543,6 +568,7 @@ CONFIG_SERIAL_8250_NR_UARTS=2
 #
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -609,17 +635,18 @@ CONFIG_I2C_ALGOBIT=y
 # CONFIG_I2C_AMD8111 is not set
 # CONFIG_I2C_I801 is not set
 # CONFIG_I2C_I810 is not set
+# CONFIG_I2C_PIIX4 is not set
 # CONFIG_I2C_ISA is not set
 # CONFIG_I2C_IXP2000 is not set
 # CONFIG_I2C_NFORCE2 is not set
 # CONFIG_I2C_PARPORT_LIGHT is not set
-# CONFIG_I2C_PIIX4 is not set
 # CONFIG_I2C_PROSAVAGE is not set
 # CONFIG_I2C_SAVAGE4 is not set
 # CONFIG_SCx200_ACB is not set
 # CONFIG_I2C_SIS5595 is not set
 # CONFIG_I2C_SIS630 is not set
 # CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_STUB is not set
 # CONFIG_I2C_VIA is not set
 # CONFIG_I2C_VIAPRO is not set
 # CONFIG_I2C_VOODOO3 is not set
@@ -633,7 +660,9 @@ CONFIG_I2C_SENSOR=y
 # CONFIG_SENSORS_ADM1025 is not set
 # CONFIG_SENSORS_ADM1026 is not set
 # CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
 # CONFIG_SENSORS_ASB100 is not set
+# CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_FSCHER is not set
 # CONFIG_SENSORS_FSCPOS is not set
@@ -649,6 +678,7 @@ CONFIG_I2C_SENSOR=y
 # CONFIG_SENSORS_LM85 is not set
 # CONFIG_SENSORS_LM87 is not set
 # CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
 # CONFIG_SENSORS_MAX1619 is not set
 # CONFIG_SENSORS_PC87360 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
@@ -658,14 +688,19 @@ CONFIG_I2C_SENSOR=y
 # CONFIG_SENSORS_W83781D is not set
 # CONFIG_SENSORS_W83L785TS is not set
 # CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
 
 #
 # Other I2C Chip support
 #
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
 CONFIG_SENSORS_EEPROM=y
 # CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_SENSORS_PCA9539 is not set
 # CONFIG_SENSORS_PCF8591 is not set
 # CONFIG_SENSORS_RTC8564 is not set
+# CONFIG_SENSORS_MAX6875 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
@@ -719,6 +754,7 @@ CONFIG_EXT2_FS=y
 CONFIG_EXT2_FS_XATTR=y
 CONFIG_EXT2_FS_POSIX_ACL=y
 # CONFIG_EXT2_FS_SECURITY is not set
+# CONFIG_EXT2_FS_XIP is not set
 CONFIG_EXT3_FS=y
 CONFIG_EXT3_FS_XATTR=y
 CONFIG_EXT3_FS_POSIX_ACL=y
@@ -759,7 +795,6 @@ CONFIG_DNOTIFY=y
 #
 CONFIG_PROC_FS=y
 CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
 # CONFIG_DEVPTS_FS_XATTR is not set
 CONFIG_TMPFS=y
 # CONFIG_TMPFS_XATTR is not set
@@ -797,12 +832,14 @@ CONFIG_JFFS2_RTIME=y
 #
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
 # CONFIG_NFS_V4 is not set
 # CONFIG_NFS_DIRECTIO is not set
 # CONFIG_NFSD is not set
 CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
diff --git a/arch/arm/configs/ixdp2800_defconfig b/arch/arm/configs/ixdp2800_defconfig
--- a/arch/arm/configs/ixdp2800_defconfig
+++ b/arch/arm/configs/ixdp2800_defconfig
@@ -1,14 +1,13 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc1-bk2
-# Sun Mar 27 22:15:23 2005
+# Linux kernel version: 2.6.13-rc2
+# Thu Jul  7 16:49:20 2005
 #
 CONFIG_ARM=y
 CONFIG_MMU=y
 CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_GENERIC_IOMAP=y
 
 #
 # Code maturity level options
@@ -16,6 +15,7 @@ CONFIG_GENERIC_IOMAP=y
 CONFIG_EXPERIMENTAL=y
 CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
@@ -35,6 +35,8 @@ CONFIG_EMBEDDED=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
@@ -50,7 +52,13 @@ CONFIG_BASE_SMALL=0
 #
 # Loadable module support
 #
-# CONFIG_MODULES is not set
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
 
 #
 # System Type
@@ -76,6 +84,7 @@ CONFIG_ARCH_IXP2000=y
 # CONFIG_ARCH_VERSATILE is not set
 # CONFIG_ARCH_IMX is not set
 # CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_AAEC2000 is not set
 CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y
 
 #
@@ -91,6 +100,7 @@ CONFIG_ARCH_IXDP2800=y
 CONFIG_ARCH_IXDP2X00=y
 # CONFIG_ARCH_IXDP2401 is not set
 # CONFIG_ARCH_IXDP2801 is not set
+# CONFIG_IXP2000_SUPPORT_BROKEN_PCI_IO is not set
 
 #
 # Processor Type
@@ -101,7 +111,6 @@ CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5T=y
 CONFIG_CPU_CACHE_VIVT=y
 CONFIG_CPU_TLB_V4WBI=y
-CONFIG_CPU_MINICACHE=y
 
 #
 # Processor Features
@@ -113,9 +122,11 @@ CONFIG_XSCALE_PMU=y
 #
 # Bus support
 #
+CONFIG_ISA_DMA_API=y
 CONFIG_PCI=y
 CONFIG_PCI_LEGACY_PROC=y
 CONFIG_PCI_NAMES=y
+# CONFIG_PCI_DEBUG is not set
 
 #
 # PCCARD (PCMCIA/CardBus) support
@@ -125,7 +136,16 @@ CONFIG_PCI_NAMES=y
 #
 # Kernel Features
 #
+# CONFIG_SMP is not set
 # CONFIG_PREEMPT is not set
+# CONFIG_NO_IDLE_HZ is not set
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_ALIGNMENT_TRAP=y
 
 #
@@ -264,7 +284,6 @@ CONFIG_MTD_IXP2000=y
 #
 # Block devices
 #
-# CONFIG_BLK_DEV_FD is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
 # CONFIG_BLK_DEV_DAC960 is not set
@@ -303,6 +322,7 @@ CONFIG_IOSCHED_CFQ=y
 #
 # Fusion MPT device support
 #
+# CONFIG_FUSION is not set
 
 #
 # IEEE 1394 (FireWire) support
@@ -324,12 +344,12 @@ CONFIG_NET=y
 #
 CONFIG_PACKET=y
 CONFIG_PACKET_MMAP=y
-# CONFIG_NETLINK_DEV is not set
 CONFIG_UNIX=y
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
 # CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
 CONFIG_IP_PNP=y
 CONFIG_IP_PNP_DHCP=y
 CONFIG_IP_PNP_BOOTP=y
@@ -344,6 +364,8 @@ CONFIG_SYN_COOKIES=y
 # CONFIG_INET_TUNNEL is not set
 # CONFIG_IP_TCPDIAG is not set
 # CONFIG_IP_TCPDIAG_IPV6 is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
 # CONFIG_IPV6 is not set
 # CONFIG_NETFILTER is not set
 
@@ -399,6 +421,7 @@ CONFIG_MII=y
 # CONFIG_SUNGEM is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
 
 #
 # Tulip family network device support
@@ -435,9 +458,11 @@ CONFIG_EEPRO100=y
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
 # CONFIG_R8169 is not set
+# CONFIG_SKGE is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
 
 #
 # Ethernet (10000 Mbit)
@@ -459,6 +484,7 @@ CONFIG_EEPRO100=y
 # Wan interfaces
 #
 CONFIG_WAN=y
+# CONFIG_DSCC4 is not set
 # CONFIG_LANMEDIA is not set
 # CONFIG_SYNCLINK_SYNCPPP is not set
 CONFIG_HDLC=y
@@ -521,7 +547,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 #
 # CONFIG_SERIO is not set
 # CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
 
 #
 # Character devices
@@ -542,6 +567,7 @@ CONFIG_SERIAL_8250_NR_UARTS=2
 #
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -608,17 +634,18 @@ CONFIG_I2C_ALGOBIT=y
 # CONFIG_I2C_AMD8111 is not set
 # CONFIG_I2C_I801 is not set
 # CONFIG_I2C_I810 is not set
+# CONFIG_I2C_PIIX4 is not set
 # CONFIG_I2C_ISA is not set
 # CONFIG_I2C_IXP2000 is not set
 # CONFIG_I2C_NFORCE2 is not set
 # CONFIG_I2C_PARPORT_LIGHT is not set
-# CONFIG_I2C_PIIX4 is not set
 # CONFIG_I2C_PROSAVAGE is not set
 # CONFIG_I2C_SAVAGE4 is not set
 # CONFIG_SCx200_ACB is not set
 # CONFIG_I2C_SIS5595 is not set
 # CONFIG_I2C_SIS630 is not set
 # CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_STUB is not set
 # CONFIG_I2C_VIA is not set
 # CONFIG_I2C_VIAPRO is not set
 # CONFIG_I2C_VOODOO3 is not set
@@ -632,7 +659,9 @@ CONFIG_I2C_SENSOR=y
 # CONFIG_SENSORS_ADM1025 is not set
 # CONFIG_SENSORS_ADM1026 is not set
 # CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
 # CONFIG_SENSORS_ASB100 is not set
+# CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_FSCHER is not set
 # CONFIG_SENSORS_FSCPOS is not set
@@ -648,6 +677,7 @@ CONFIG_I2C_SENSOR=y
 # CONFIG_SENSORS_LM85 is not set
 # CONFIG_SENSORS_LM87 is not set
 # CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
 # CONFIG_SENSORS_MAX1619 is not set
 # CONFIG_SENSORS_PC87360 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
@@ -657,14 +687,19 @@ CONFIG_I2C_SENSOR=y
 # CONFIG_SENSORS_W83781D is not set
 # CONFIG_SENSORS_W83L785TS is not set
 # CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
 
 #
 # Other I2C Chip support
 #
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
 CONFIG_SENSORS_EEPROM=y
 # CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_SENSORS_PCA9539 is not set
 # CONFIG_SENSORS_PCF8591 is not set
 # CONFIG_SENSORS_RTC8564 is not set
+# CONFIG_SENSORS_MAX6875 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
@@ -718,6 +753,7 @@ CONFIG_EXT2_FS=y
 CONFIG_EXT2_FS_XATTR=y
 CONFIG_EXT2_FS_POSIX_ACL=y
 # CONFIG_EXT2_FS_SECURITY is not set
+# CONFIG_EXT2_FS_XIP is not set
 CONFIG_EXT3_FS=y
 CONFIG_EXT3_FS_XATTR=y
 CONFIG_EXT3_FS_POSIX_ACL=y
@@ -758,7 +794,6 @@ CONFIG_DNOTIFY=y
 #
 CONFIG_PROC_FS=y
 CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
 # CONFIG_DEVPTS_FS_XATTR is not set
 CONFIG_TMPFS=y
 # CONFIG_TMPFS_XATTR is not set
@@ -796,12 +831,14 @@ CONFIG_JFFS2_RTIME=y
 #
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
 # CONFIG_NFS_V4 is not set
 # CONFIG_NFS_DIRECTIO is not set
 # CONFIG_NFSD is not set
 CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
diff --git a/arch/arm/configs/ixdp2801_defconfig b/arch/arm/configs/ixdp2801_defconfig
--- a/arch/arm/configs/ixdp2801_defconfig
+++ b/arch/arm/configs/ixdp2801_defconfig
@@ -1,14 +1,13 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc1-bk2
-# Sun Mar 27 22:39:19 2005
+# Linux kernel version: 2.6.13-rc2
+# Thu Jul  7 16:49:13 2005
 #
 CONFIG_ARM=y
 CONFIG_MMU=y
 CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_GENERIC_IOMAP=y
 
 #
 # Code maturity level options
@@ -16,6 +15,7 @@ CONFIG_GENERIC_IOMAP=y
 CONFIG_EXPERIMENTAL=y
 CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
@@ -35,6 +35,8 @@ CONFIG_EMBEDDED=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
@@ -50,7 +52,13 @@ CONFIG_BASE_SMALL=0
 #
 # Loadable module support
 #
-# CONFIG_MODULES is not set
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
 
 #
 # System Type
@@ -76,6 +84,7 @@ CONFIG_ARCH_IXP2000=y
 # CONFIG_ARCH_VERSATILE is not set
 # CONFIG_ARCH_IMX is not set
 # CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_AAEC2000 is not set
 CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y
 
 #
@@ -91,6 +100,7 @@ CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y
 # CONFIG_ARCH_IXDP2401 is not set
 CONFIG_ARCH_IXDP2801=y
 CONFIG_ARCH_IXDP2X01=y
+# CONFIG_IXP2000_SUPPORT_BROKEN_PCI_IO is not set
 
 #
 # Processor Type
@@ -101,7 +111,6 @@ CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5T=y
 CONFIG_CPU_CACHE_VIVT=y
 CONFIG_CPU_TLB_V4WBI=y
-CONFIG_CPU_MINICACHE=y
 
 #
 # Processor Features
@@ -113,9 +122,11 @@ CONFIG_XSCALE_PMU=y
 #
 # Bus support
 #
+CONFIG_ISA_DMA_API=y
 CONFIG_PCI=y
 CONFIG_PCI_LEGACY_PROC=y
 CONFIG_PCI_NAMES=y
+# CONFIG_PCI_DEBUG is not set
 
 #
 # PCCARD (PCMCIA/CardBus) support
@@ -125,7 +136,16 @@ CONFIG_PCI_NAMES=y
 #
 # Kernel Features
 #
+# CONFIG_SMP is not set
 # CONFIG_PREEMPT is not set
+# CONFIG_NO_IDLE_HZ is not set
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_ALIGNMENT_TRAP=y
 
 #
@@ -264,7 +284,6 @@ CONFIG_MTD_IXP2000=y
 #
 # Block devices
 #
-# CONFIG_BLK_DEV_FD is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
 # CONFIG_BLK_DEV_DAC960 is not set
@@ -303,6 +322,7 @@ CONFIG_IOSCHED_CFQ=y
 #
 # Fusion MPT device support
 #
+# CONFIG_FUSION is not set
 
 #
 # IEEE 1394 (FireWire) support
@@ -324,12 +344,12 @@ CONFIG_NET=y
 #
 CONFIG_PACKET=y
 CONFIG_PACKET_MMAP=y
-# CONFIG_NETLINK_DEV is not set
 CONFIG_UNIX=y
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
 # CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
 CONFIG_IP_PNP=y
 CONFIG_IP_PNP_DHCP=y
 CONFIG_IP_PNP_BOOTP=y
@@ -344,6 +364,8 @@ CONFIG_SYN_COOKIES=y
 # CONFIG_INET_TUNNEL is not set
 # CONFIG_IP_TCPDIAG is not set
 # CONFIG_IP_TCPDIAG_IPV6 is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
 # CONFIG_IPV6 is not set
 # CONFIG_NETFILTER is not set
 
@@ -399,6 +421,7 @@ CONFIG_MII=y
 # CONFIG_SUNGEM is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
 
 #
 # Tulip family network device support
@@ -436,9 +459,11 @@ CONFIG_EEPRO100=y
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
 # CONFIG_R8169 is not set
+# CONFIG_SKGE is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
 
 #
 # Ethernet (10000 Mbit)
@@ -460,6 +485,7 @@ CONFIG_EEPRO100=y
 # Wan interfaces
 #
 CONFIG_WAN=y
+# CONFIG_DSCC4 is not set
 # CONFIG_LANMEDIA is not set
 # CONFIG_SYNCLINK_SYNCPPP is not set
 CONFIG_HDLC=y
@@ -522,7 +548,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 #
 # CONFIG_SERIO is not set
 # CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
 
 #
 # Character devices
@@ -543,6 +568,7 @@ CONFIG_SERIAL_8250_NR_UARTS=2
 #
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -609,17 +635,18 @@ CONFIG_I2C_ALGOBIT=y
 # CONFIG_I2C_AMD8111 is not set
 # CONFIG_I2C_I801 is not set
 # CONFIG_I2C_I810 is not set
+# CONFIG_I2C_PIIX4 is not set
 # CONFIG_I2C_ISA is not set
 # CONFIG_I2C_IXP2000 is not set
 # CONFIG_I2C_NFORCE2 is not set
 # CONFIG_I2C_PARPORT_LIGHT is not set
-# CONFIG_I2C_PIIX4 is not set
 # CONFIG_I2C_PROSAVAGE is not set
 # CONFIG_I2C_SAVAGE4 is not set
 # CONFIG_SCx200_ACB is not set
 # CONFIG_I2C_SIS5595 is not set
 # CONFIG_I2C_SIS630 is not set
 # CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_STUB is not set
 # CONFIG_I2C_VIA is not set
 # CONFIG_I2C_VIAPRO is not set
 # CONFIG_I2C_VOODOO3 is not set
@@ -633,7 +660,9 @@ CONFIG_I2C_SENSOR=y
 # CONFIG_SENSORS_ADM1025 is not set
 # CONFIG_SENSORS_ADM1026 is not set
 # CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
 # CONFIG_SENSORS_ASB100 is not set
+# CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_FSCHER is not set
 # CONFIG_SENSORS_FSCPOS is not set
@@ -649,6 +678,7 @@ CONFIG_I2C_SENSOR=y
 # CONFIG_SENSORS_LM85 is not set
 # CONFIG_SENSORS_LM87 is not set
 # CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
 # CONFIG_SENSORS_MAX1619 is not set
 # CONFIG_SENSORS_PC87360 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
@@ -658,14 +688,19 @@ CONFIG_I2C_SENSOR=y
 # CONFIG_SENSORS_W83781D is not set
 # CONFIG_SENSORS_W83L785TS is not set
 # CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
 
 #
 # Other I2C Chip support
 #
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
 CONFIG_SENSORS_EEPROM=y
 # CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_SENSORS_PCA9539 is not set
 # CONFIG_SENSORS_PCF8591 is not set
 # CONFIG_SENSORS_RTC8564 is not set
+# CONFIG_SENSORS_MAX6875 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
@@ -719,6 +754,7 @@ CONFIG_EXT2_FS=y
 CONFIG_EXT2_FS_XATTR=y
 CONFIG_EXT2_FS_POSIX_ACL=y
 # CONFIG_EXT2_FS_SECURITY is not set
+# CONFIG_EXT2_FS_XIP is not set
 CONFIG_EXT3_FS=y
 CONFIG_EXT3_FS_XATTR=y
 CONFIG_EXT3_FS_POSIX_ACL=y
@@ -759,7 +795,6 @@ CONFIG_DNOTIFY=y
 #
 CONFIG_PROC_FS=y
 CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
 # CONFIG_DEVPTS_FS_XATTR is not set
 CONFIG_TMPFS=y
 # CONFIG_TMPFS_XATTR is not set
@@ -797,12 +832,14 @@ CONFIG_JFFS2_RTIME=y
 #
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
 # CONFIG_NFS_V4 is not set
 # CONFIG_NFS_DIRECTIO is not set
 # CONFIG_NFSD is not set
 CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
diff --git a/arch/arm/configs/omap_h2_1610_defconfig b/arch/arm/configs/omap_h2_1610_defconfig
--- a/arch/arm/configs/omap_h2_1610_defconfig
+++ b/arch/arm/configs/omap_h2_1610_defconfig
@@ -1,14 +1,13 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc1-bk2
-# Sun Mar 27 17:52:41 2005
+# Linux kernel version: 2.6.13-rc2
+# Fri Jul  8 04:49:34 2005
 #
 CONFIG_ARM=y
 CONFIG_MMU=y
 CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_GENERIC_IOMAP=y
 
 #
 # Code maturity level options
@@ -17,6 +16,7 @@ CONFIG_EXPERIMENTAL=y
 CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
 CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
@@ -33,8 +33,9 @@ CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
 # CONFIG_EMBEDDED is not set
 CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
@@ -82,10 +83,28 @@ CONFIG_ARCH_OMAP=y
 # CONFIG_ARCH_VERSATILE is not set
 # CONFIG_ARCH_IMX is not set
 # CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_AAEC2000 is not set
 
 #
 # TI OMAP Implementations
 #
+CONFIG_ARCH_OMAP_OTG=y
+CONFIG_ARCH_OMAP1=y
+# CONFIG_ARCH_OMAP2 is not set
+
+#
+# OMAP Feature Selections
+#
+# CONFIG_OMAP_RESET_CLOCKS is not set
+CONFIG_OMAP_MUX=y
+# CONFIG_OMAP_MUX_DEBUG is not set
+CONFIG_OMAP_MUX_WARNINGS=y
+# CONFIG_OMAP_MPU_TIMER is not set
+CONFIG_OMAP_32K_TIMER=y
+CONFIG_OMAP_32K_TIMER_HZ=128
+CONFIG_OMAP_LL_DEBUG_UART1=y
+# CONFIG_OMAP_LL_DEBUG_UART2 is not set
+# CONFIG_OMAP_LL_DEBUG_UART3 is not set
 
 #
 # OMAP Core Type
@@ -93,7 +112,6 @@ CONFIG_ARCH_OMAP=y
 # CONFIG_ARCH_OMAP730 is not set
 # CONFIG_ARCH_OMAP1510 is not set
 CONFIG_ARCH_OMAP16XX=y
-CONFIG_ARCH_OMAP_OTG=y
 
 #
 # OMAP Board Type
@@ -101,21 +119,14 @@ CONFIG_ARCH_OMAP_OTG=y
 # CONFIG_MACH_OMAP_INNOVATOR is not set
 CONFIG_MACH_OMAP_H2=y
 # CONFIG_MACH_OMAP_H3 is not set
-# CONFIG_MACH_OMAP_H4 is not set
 # CONFIG_MACH_OMAP_OSK is not set
 # CONFIG_MACH_OMAP_GENERIC is not set
 
 #
-# OMAP Feature Selections
+# OMAP CPU Speed
 #
-CONFIG_OMAP_MUX=y
-# CONFIG_OMAP_MUX_DEBUG is not set
-CONFIG_OMAP_MUX_WARNINGS=y
-CONFIG_OMAP_MPU_TIMER=y
-# CONFIG_OMAP_32K_TIMER is not set
-CONFIG_OMAP_LL_DEBUG_UART1=y
-# CONFIG_OMAP_LL_DEBUG_UART2 is not set
-# CONFIG_OMAP_LL_DEBUG_UART3 is not set
+# CONFIG_OMAP_CLOCKS_SET_BY_BOOTLOADER is not set
+# CONFIG_OMAP_ARM_216MHZ is not set
 CONFIG_OMAP_ARM_192MHZ=y
 # CONFIG_OMAP_ARM_168MHZ is not set
 # CONFIG_OMAP_ARM_120MHZ is not set
@@ -145,6 +156,7 @@ CONFIG_ARM_THUMB=y
 #
 # Bus support
 #
+CONFIG_ISA_DMA_API=y
 
 #
 # PCCARD (PCMCIA/CardBus) support
@@ -154,7 +166,16 @@ CONFIG_ARM_THUMB=y
 #
 # Kernel Features
 #
+# CONFIG_SMP is not set
 CONFIG_PREEMPT=y
+CONFIG_NO_IDLE_HZ=y
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
 # CONFIG_LEDS is not set
 CONFIG_ALIGNMENT_TRAP=y
 
@@ -167,6 +188,22 @@ CONFIG_CMDLINE="mem=32M console=ttyS0,11
 # CONFIG_XIP_KERNEL is not set
 
 #
+# CPU Frequency scaling
+#
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=y
+# CONFIG_CPU_FREQ_DEBUG is not set
+CONFIG_CPU_FREQ_STAT=y
+# CONFIG_CPU_FREQ_STAT_DETAILS is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
+# CONFIG_CPU_FREQ_GOV_PERFORMANCE is not set
+# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
+
+#
 # Floating point emulation
 #
 
@@ -202,7 +239,6 @@ CONFIG_PM=y
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_FW_LOADER is not set
-CONFIG_DEBUG_DRIVER=y
 
 #
 # Memory Technology Devices (MTD)
@@ -292,7 +328,6 @@ CONFIG_MTD_CFI_UTIL=y
 #
 # Block devices
 #
-# CONFIG_BLK_DEV_FD is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
@@ -327,6 +362,7 @@ CONFIG_SCSI_PROC_FS=y
 # CONFIG_CHR_DEV_OSST is not set
 # CONFIG_BLK_DEV_SR is not set
 # CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
 
 #
 # Some SCSI devices (e.g. CD jukebox) support multiple LUNs
@@ -356,6 +392,7 @@ CONFIG_SCSI_PROC_FS=y
 #
 # Fusion MPT device support
 #
+# CONFIG_FUSION is not set
 
 #
 # IEEE 1394 (FireWire) support
@@ -375,12 +412,12 @@ CONFIG_NET=y
 #
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK_DEV is not set
 CONFIG_UNIX=y
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
 # CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
 CONFIG_IP_PNP=y
 CONFIG_IP_PNP_DHCP=y
 CONFIG_IP_PNP_BOOTP=y
@@ -395,6 +432,8 @@ CONFIG_IP_PNP_BOOTP=y
 # CONFIG_INET_TUNNEL is not set
 CONFIG_IP_TCPDIAG=y
 # CONFIG_IP_TCPDIAG_IPV6 is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
 # CONFIG_IPV6 is not set
 # CONFIG_NETFILTER is not set
 
@@ -442,6 +481,7 @@ CONFIG_NETDEVICES=y
 CONFIG_NET_ETHERNET=y
 CONFIG_MII=y
 CONFIG_SMC91X=y
+# CONFIG_DM9000 is not set
 
 #
 # Ethernet (1000 Mbit)
@@ -518,7 +558,6 @@ CONFIG_SERIO=y
 CONFIG_SERIO_SERPORT=y
 # CONFIG_SERIO_RAW is not set
 # CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
 
 #
 # Character devices
@@ -567,13 +606,11 @@ CONFIG_WATCHDOG_NOWAYOUT=y
 #
 # Ftape, the floppy tape device driver
 #
-# CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
 #
 # TPM devices
 #
-# CONFIG_TCG_TPM is not set
 
 #
 # I2C support
@@ -604,7 +641,9 @@ CONFIG_I2C_CHARDEV=y
 # CONFIG_SENSORS_ADM1025 is not set
 # CONFIG_SENSORS_ADM1026 is not set
 # CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
 # CONFIG_SENSORS_ASB100 is not set
+# CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_FSCHER is not set
 # CONFIG_SENSORS_FSCPOS is not set
@@ -620,6 +659,7 @@ CONFIG_I2C_CHARDEV=y
 # CONFIG_SENSORS_LM85 is not set
 # CONFIG_SENSORS_LM87 is not set
 # CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
 # CONFIG_SENSORS_MAX1619 is not set
 # CONFIG_SENSORS_PC87360 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
@@ -627,15 +667,21 @@ CONFIG_I2C_CHARDEV=y
 # CONFIG_SENSORS_W83781D is not set
 # CONFIG_SENSORS_W83L785TS is not set
 # CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
 
 #
 # Other I2C Chip support
 #
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
 # CONFIG_SENSORS_EEPROM is not set
 # CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_SENSORS_PCA9539 is not set
 # CONFIG_SENSORS_PCF8591 is not set
 # CONFIG_SENSORS_RTC8564 is not set
 CONFIG_ISP1301_OMAP=y
+CONFIG_TPS65010=y
+# CONFIG_SENSORS_MAX6875 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
@@ -663,8 +709,10 @@ CONFIG_FB=y
 # CONFIG_FB_CFB_COPYAREA is not set
 # CONFIG_FB_CFB_IMAGEBLIT is not set
 # CONFIG_FB_SOFT_CURSOR is not set
+# CONFIG_FB_MACMODES is not set
 CONFIG_FB_MODE_HELPERS=y
 # CONFIG_FB_TILEBLITTING is not set
+# CONFIG_FB_S1D13XXX is not set
 # CONFIG_FB_VIRTUAL is not set
 
 #
@@ -677,11 +725,13 @@ CONFIG_FONTS=y
 CONFIG_FONT_8x8=y
 CONFIG_FONT_8x16=y
 # CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_7x14 is not set
 # CONFIG_FONT_PEARL_8x8 is not set
 # CONFIG_FONT_ACORN_8x8 is not set
 # CONFIG_FONT_MINI_4x6 is not set
 # CONFIG_FONT_SUN8x16 is not set
 # CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_10x18 is not set
 
 #
 # Logo configuration
@@ -729,14 +779,14 @@ CONFIG_USB_ARCH_HAS_OHCI=y
 #
 CONFIG_USB_GADGET=y
 # CONFIG_USB_GADGET_DEBUG_FILES is not set
+CONFIG_USB_GADGET_SELECTED=y
 # CONFIG_USB_GADGET_NET2280 is not set
 # CONFIG_USB_GADGET_PXA2XX is not set
 # CONFIG_USB_GADGET_GOKU is not set
-# CONFIG_USB_GADGET_SA1100 is not set
 # CONFIG_USB_GADGET_LH7A40X is not set
-# CONFIG_USB_GADGET_DUMMY_HCD is not set
 CONFIG_USB_GADGET_OMAP=y
 CONFIG_USB_OMAP=y
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
 # CONFIG_USB_GADGET_DUALSPEED is not set
 # CONFIG_USB_ZERO is not set
 CONFIG_USB_ETH=y
@@ -755,6 +805,7 @@ CONFIG_USB_ETH_RNDIS=y
 #
 CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_JBD is not set
 # CONFIG_REISERFS_FS is not set
@@ -791,7 +842,6 @@ CONFIG_FAT_DEFAULT_CODEPAGE=437
 #
 CONFIG_PROC_FS=y
 CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
 # CONFIG_DEVPTS_FS_XATTR is not set
 # CONFIG_TMPFS is not set
 # CONFIG_HUGETLB_PAGE is not set
@@ -828,12 +878,14 @@ CONFIG_CRAMFS=y
 #
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
 CONFIG_NFS_V4=y
 # CONFIG_NFS_DIRECTIO is not set
 # CONFIG_NFSD is not set
 CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
@@ -903,24 +955,11 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
-CONFIG_DEBUG_KERNEL=y
-# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_SCHEDSTATS is not set
-# CONFIG_DEBUG_SLAB is not set
-CONFIG_DEBUG_PREEMPT=y
-# CONFIG_DEBUG_SPINLOCK is not set
-# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
-# CONFIG_DEBUG_KOBJECT is not set
 CONFIG_DEBUG_BUGVERBOSE=y
-CONFIG_DEBUG_INFO=y
-# CONFIG_DEBUG_FS is not set
 CONFIG_FRAME_POINTER=y
-CONFIG_DEBUG_USER=y
-# CONFIG_DEBUG_WAITQ is not set
-CONFIG_DEBUG_ERRORS=y
-CONFIG_DEBUG_LL=y
-# CONFIG_DEBUG_ICEDCC is not set
+# CONFIG_DEBUG_USER is not set
 
 #
 # Security options
diff --git a/arch/arm/configs/omnimeter_defconfig b/arch/arm/configs/omnimeter_defconfig
deleted file mode 100644
--- a/arch/arm/configs/omnimeter_defconfig
+++ /dev/null
@@ -1,803 +0,0 @@
-#
-# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc1-bk2
-# Sun Mar 27 21:31:45 2005
-#
-CONFIG_ARM=y
-CONFIG_MMU=y
-CONFIG_UID16=y
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_GENERIC_IOMAP=y
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
-CONFIG_BROKEN_ON_SMP=y
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-# CONFIG_POSIX_MQUEUE is not set
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
-# CONFIG_IKCONFIG is not set
-# CONFIG_EMBEDDED is not set
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-CONFIG_CC_OPTIMIZE_FOR_SIZE=y
-CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-# CONFIG_MODULE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
-# CONFIG_MODVERSIONS is not set
-# CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_KMOD=y
-
-#
-# System Type
-#
-# CONFIG_ARCH_CLPS7500 is not set
-# CONFIG_ARCH_CLPS711X is not set
-# CONFIG_ARCH_CO285 is not set
-# CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
-# CONFIG_ARCH_FOOTBRIDGE is not set
-# CONFIG_ARCH_INTEGRATOR is not set
-# CONFIG_ARCH_IOP3XX is not set
-# CONFIG_ARCH_IXP4XX is not set
-# CONFIG_ARCH_IXP2000 is not set
-# CONFIG_ARCH_L7200 is not set
-# CONFIG_ARCH_PXA is not set
-# CONFIG_ARCH_RPC is not set
-CONFIG_ARCH_SA1100=y
-# CONFIG_ARCH_S3C2410 is not set
-# CONFIG_ARCH_SHARK is not set
-# CONFIG_ARCH_LH7A40X is not set
-# CONFIG_ARCH_OMAP is not set
-# CONFIG_ARCH_VERSATILE is not set
-# CONFIG_ARCH_IMX is not set
-# CONFIG_ARCH_H720X is not set
-
-#
-# SA11x0 Implementations
-#
-# CONFIG_SA1100_ASSABET is not set
-# CONFIG_SA1100_CERF is not set
-# CONFIG_SA1100_COLLIE is not set
-# CONFIG_SA1100_H3100 is not set
-# CONFIG_SA1100_H3600 is not set
-# CONFIG_SA1100_H3800 is not set
-# CONFIG_SA1100_BADGE4 is not set
-# CONFIG_SA1100_JORNADA720 is not set
-# CONFIG_SA1100_HACKKIT is not set
-# CONFIG_SA1100_LART is not set
-# CONFIG_SA1100_PLEB is not set
-# CONFIG_SA1100_SHANNON is not set
-# CONFIG_SA1100_SIMPAD is not set
-# CONFIG_SA1100_SSP is not set
-
-#
-# Processor Type
-#
-CONFIG_CPU_32=y
-CONFIG_CPU_SA1100=y
-CONFIG_CPU_32v4=y
-CONFIG_CPU_ABRT_EV4=y
-CONFIG_CPU_CACHE_V4WB=y
-CONFIG_CPU_CACHE_VIVT=y
-CONFIG_CPU_TLB_V4WB=y
-CONFIG_CPU_MINICACHE=y
-
-#
-# Processor Features
-#
-
-#
-# Bus support
-#
-CONFIG_ISA=y
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
-CONFIG_PCCARD=y
-# CONFIG_PCMCIA_DEBUG is not set
-CONFIG_PCMCIA=y
-
-#
-# PC-card bridges
-#
-CONFIG_I82365=y
-# CONFIG_TCIC is not set
-CONFIG_PCMCIA_SA1100=y
-CONFIG_PCCARD_NONSTATIC=y
-
-#
-# Kernel Features
-#
-# CONFIG_PREEMPT is not set
-CONFIG_DISCONTIGMEM=y
-# CONFIG_LEDS is not set
-CONFIG_ALIGNMENT_TRAP=y
-
-#
-# Boot options
-#
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="keepinitrd mem=16M root=/dev/ram ramdisk=8192 initrd=0xd0000000,4M"
-# CONFIG_XIP_KERNEL is not set
-
-#
-# CPU Frequency scaling
-#
-# CONFIG_CPU_FREQ is not set
-
-#
-# Floating point emulation
-#
-
-#
-# At least one emulation must be selected
-#
-# CONFIG_FPE_NWFPE is not set
-# CONFIG_FPE_FASTFPE is not set
-
-#
-# Userspace binary formats
-#
-CONFIG_BINFMT_ELF=y
-CONFIG_BINFMT_AOUT=y
-# CONFIG_BINFMT_MISC is not set
-# CONFIG_ARTHUR is not set
-
-#
-# Power management options
-#
-# CONFIG_PM is not set
-
-#
-# Device Drivers
-#
-
-#
-# Generic Driver Options
-#
-CONFIG_STANDALONE=y
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
-
-#
-# Memory Technology Devices (MTD)
-#
-# CONFIG_MTD is not set
-
-#
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-
-#
-# Plug and Play support
-#
-# CONFIG_PNP is not set
-
-#
-# Block devices
-#
-# CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_DEV_XD is not set
-# CONFIG_BLK_DEV_COW_COMMON is not set
-CONFIG_BLK_DEV_LOOP=m
-# CONFIG_BLK_DEV_CRYPTOLOOP is not set
-CONFIG_BLK_DEV_NBD=m
-# CONFIG_BLK_DEV_RAM is not set
-CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_CDROM_PKTCDVD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-# CONFIG_ATA_OVER_ETH is not set
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
-CONFIG_IDE=y
-CONFIG_BLK_DEV_IDE=y
-
-#
-# Please see Documentation/ide.txt for help/info on IDE drives
-#
-# CONFIG_BLK_DEV_IDE_SATA is not set
-CONFIG_BLK_DEV_IDEDISK=y
-# CONFIG_IDEDISK_MULTI_MODE is not set
-# CONFIG_BLK_DEV_IDECS is not set
-# CONFIG_BLK_DEV_IDECD is not set
-# CONFIG_BLK_DEV_IDETAPE is not set
-# CONFIG_BLK_DEV_IDEFLOPPY is not set
-# CONFIG_IDE_TASK_IOCTL is not set
-
-#
-# IDE chipset support/bugfixes
-#
-CONFIG_IDE_GENERIC=y
-# CONFIG_IDE_ARM is not set
-# CONFIG_IDE_CHIPSETS is not set
-# CONFIG_BLK_DEV_IDEDMA is not set
-# CONFIG_IDEDMA_AUTO is not set
-# CONFIG_BLK_DEV_HD is not set
-
-#
-# SCSI device support
-#
-# CONFIG_SCSI is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
-# CONFIG_MD is not set
-
-#
-# Fusion MPT device support
-#
-
-#
-# IEEE 1394 (FireWire) support
-#
-
-#
-# I2O device support
-#
-
-#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
-# CONFIG_NETLINK_DEV is not set
-CONFIG_UNIX=y
-# CONFIG_NET_KEY is not set
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-# CONFIG_IP_PNP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_TUNNEL is not set
-CONFIG_IP_TCPDIAG=y
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-
-#
-# IP: Virtual Server Configuration
-#
-# CONFIG_IP_VS is not set
-# CONFIG_IPV6 is not set
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-
-#
-# IP: Netfilter Configuration
-#
-# CONFIG_IP_NF_CONNTRACK is not set
-# CONFIG_IP_NF_CONNTRACK_MARK is not set
-# CONFIG_IP_NF_QUEUE is not set
-# CONFIG_IP_NF_IPTABLES is not set
-# CONFIG_IP_NF_ARPTABLES is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
-CONFIG_NETDEVICES=y
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
-
-#
-# ARCnet devices
-#
-# CONFIG_ARCNET is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
-CONFIG_NET_ETHERNET=y
-# CONFIG_MII is not set
-# CONFIG_NET_VENDOR_3COM is not set
-# CONFIG_LANCE is not set
-# CONFIG_NET_VENDOR_SMC is not set
-# CONFIG_SMC91X is not set
-# CONFIG_NET_VENDOR_RACAL is not set
-# CONFIG_AT1700 is not set
-# CONFIG_DEPCA is not set
-# CONFIG_HP100 is not set
-# CONFIG_NET_ISA is not set
-# CONFIG_NET_PCI is not set
-# CONFIG_NET_POCKET is not set
-
-#
-# Ethernet (1000 Mbit)
-#
-
-#
-# Ethernet (10000 Mbit)
-#
-
-#
-# Token Ring devices
-#
-# CONFIG_TR is not set
-
-#
-# Wireless LAN (non-hamradio)
-#
-CONFIG_NET_RADIO=y
-
-#
-# Obsolete Wireless cards support (pre-802.11)
-#
-# CONFIG_STRIP is not set
-# CONFIG_ARLAN is not set
-# CONFIG_WAVELAN is not set
-CONFIG_PCMCIA_WAVELAN=y
-# CONFIG_PCMCIA_NETWAVE is not set
-
-#
-# Wireless 802.11 Frequency Hopping cards support
-#
-# CONFIG_PCMCIA_RAYCS is not set
-
-#
-# Wireless 802.11b ISA/PCI cards support
-#
-# CONFIG_HERMES is not set
-# CONFIG_ATMEL is not set
-
-#
-# Wireless 802.11b Pcmcia/Cardbus cards support
-#
-CONFIG_AIRO_CS=y
-CONFIG_PCMCIA_WL3501=y
-CONFIG_NET_WIRELESS=y
-
-#
-# PCMCIA network device support
-#
-CONFIG_NET_PCMCIA=y
-CONFIG_PCMCIA_3C589=y
-# CONFIG_PCMCIA_3C574 is not set
-# CONFIG_PCMCIA_FMVJ18X is not set
-CONFIG_PCMCIA_PCNET=y
-# CONFIG_PCMCIA_NMCLAN is not set
-# CONFIG_PCMCIA_SMC91C92 is not set
-# CONFIG_PCMCIA_XIRC2PS is not set
-# CONFIG_PCMCIA_AXNET is not set
-
-#
-# Wan interfaces
-#
-# CONFIG_WAN is not set
-# CONFIG_PPP is not set
-# CONFIG_SLIP is not set
-# CONFIG_SHAPER is not set
-# CONFIG_NETCONSOLE is not set
-
-#
-# ISDN subsystem
-#
-# CONFIG_ISDN is not set
-
-#
-# Input device support
-#
-CONFIG_INPUT=y
-
-#
-# Userland interfaces
-#
-CONFIG_INPUT_MOUSEDEV=y
-CONFIG_INPUT_MOUSEDEV_PSAUX=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_TSDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-# CONFIG_INPUT_EVBUG is not set
-
-#
-# Input Device Drivers
-#
-CONFIG_INPUT_KEYBOARD=y
-CONFIG_KEYBOARD_ATKBD=y
-# CONFIG_KEYBOARD_SUNKBD is not set
-# CONFIG_KEYBOARD_LKKBD is not set
-# CONFIG_KEYBOARD_XTKBD is not set
-# CONFIG_KEYBOARD_NEWTON is not set
-CONFIG_INPUT_MOUSE=y
-CONFIG_MOUSE_PS2=y
-# CONFIG_MOUSE_SERIAL is not set
-# CONFIG_MOUSE_INPORT is not set
-# CONFIG_MOUSE_LOGIBM is not set
-# CONFIG_MOUSE_PC110PAD is not set
-# CONFIG_MOUSE_VSXXXAA is not set
-# CONFIG_INPUT_JOYSTICK is not set
-# CONFIG_INPUT_TOUCHSCREEN is not set
-# CONFIG_INPUT_MISC is not set
-
-#
-# Hardware I/O ports
-#
-CONFIG_SERIO=y
-CONFIG_SERIO_SERPORT=y
-CONFIG_SERIO_LIBPS2=y
-# CONFIG_SERIO_RAW is not set
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_HW_CONSOLE=y
-# CONFIG_SERIAL_NONSTANDARD is not set
-
-#
-# Serial drivers
-#
-# CONFIG_SERIAL_8250 is not set
-
-#
-# Non-8250 serial port support
-#
-CONFIG_SERIAL_SA1100=y
-CONFIG_SERIAL_SA1100_CONSOLE=y
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-CONFIG_UNIX98_PTYS=y
-CONFIG_LEGACY_PTYS=y
-CONFIG_LEGACY_PTY_COUNT=256
-
-#
-# IPMI
-#
-# CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
-# CONFIG_NVRAM is not set
-# CONFIG_RTC is not set
-# CONFIG_DTLK is not set
-# CONFIG_R3964 is not set
-
-#
-# Ftape, the floppy tape device driver
-#
-# CONFIG_DRM is not set
-
-#
-# PCMCIA character devices
-#
-# CONFIG_SYNCLINK_CS is not set
-# CONFIG_RAW_DRIVER is not set
-
-#
-# TPM devices
-#
-# CONFIG_TCG_TPM is not set
-
-#
-# I2C support
-#
-# CONFIG_I2C is not set
-
-#
-# Misc devices
-#
-
-#
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
-# Digital Video Broadcasting Devices
-#
-# CONFIG_DVB is not set
-
-#
-# Graphics support
-#
-CONFIG_FB=y
-CONFIG_FB_CFB_FILLRECT=y
-CONFIG_FB_CFB_COPYAREA=y
-CONFIG_FB_CFB_IMAGEBLIT=y
-CONFIG_FB_SOFT_CURSOR=y
-# CONFIG_FB_MODE_HELPERS is not set
-# CONFIG_FB_TILEBLITTING is not set
-CONFIG_FB_SA1100=y
-# CONFIG_FB_VIRTUAL is not set
-
-#
-# Console display driver support
-#
-# CONFIG_VGA_CONSOLE is not set
-# CONFIG_MDA_CONSOLE is not set
-CONFIG_DUMMY_CONSOLE=y
-CONFIG_FRAMEBUFFER_CONSOLE=y
-CONFIG_FONTS=y
-CONFIG_FONT_8x8=y
-# CONFIG_FONT_8x16 is not set
-# CONFIG_FONT_6x11 is not set
-# CONFIG_FONT_PEARL_8x8 is not set
-# CONFIG_FONT_ACORN_8x8 is not set
-# CONFIG_FONT_MINI_4x6 is not set
-# CONFIG_FONT_SUN8x16 is not set
-# CONFIG_FONT_SUN12x22 is not set
-
-#
-# Logo configuration
-#
-# CONFIG_LOGO is not set
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
-
-#
-# Sound
-#
-# CONFIG_SOUND is not set
-
-#
-# USB support
-#
-CONFIG_USB_ARCH_HAS_HCD=y
-# CONFIG_USB_ARCH_HAS_OHCI is not set
-# CONFIG_USB is not set
-
-#
-# USB Gadget Support
-#
-# CONFIG_USB_GADGET is not set
-
-#
-# MMC/SD Card support
-#
-# CONFIG_MMC is not set
-
-#
-# File systems
-#
-CONFIG_EXT2_FS=y
-# CONFIG_EXT2_FS_XATTR is not set
-# CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
-# CONFIG_REISERFS_FS is not set
-# CONFIG_JFS_FS is not set
-
-#
-# XFS support
-#
-# CONFIG_XFS_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
-# CONFIG_QUOTA is not set
-CONFIG_DNOTIFY=y
-# CONFIG_AUTOFS_FS is not set
-# CONFIG_AUTOFS4_FS is not set
-
-#
-# CD-ROM/DVD Filesystems
-#
-# CONFIG_ISO9660_FS is not set
-# CONFIG_UDF_FS is not set
-
-#
-# DOS/FAT/NT Filesystems
-#
-CONFIG_FAT_FS=y
-CONFIG_MSDOS_FS=y
-# CONFIG_VFAT_FS is not set
-CONFIG_FAT_DEFAULT_CODEPAGE=437
-# CONFIG_NTFS_FS is not set
-
-#
-# Pseudo filesystems
-#
-CONFIG_PROC_FS=y
-CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-# CONFIG_DEVPTS_FS_XATTR is not set
-# CONFIG_TMPFS is not set
-# CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
-
-#
-# Miscellaneous filesystems
-#
-# CONFIG_ADFS_FS is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_HFSPLUS_FS is not set
-# CONFIG_BEFS_FS is not set
-# CONFIG_BFS_FS is not set
-# CONFIG_EFS_FS is not set
-# CONFIG_CRAMFS is not set
-# CONFIG_VXFS_FS is not set
-# CONFIG_HPFS_FS is not set
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_SYSV_FS is not set
-# CONFIG_UFS_FS is not set
-
-#
-# Network File Systems
-#
-CONFIG_NFS_FS=y
-# CONFIG_NFS_V3 is not set
-# CONFIG_NFS_V4 is not set
-# CONFIG_NFS_DIRECTIO is not set
-# CONFIG_NFSD is not set
-CONFIG_LOCKD=y
-CONFIG_SUNRPC=y
-# CONFIG_RPCSEC_GSS_KRB5 is not set
-# CONFIG_RPCSEC_GSS_SPKM3 is not set
-# CONFIG_SMB_FS is not set
-# CONFIG_CIFS is not set
-# CONFIG_NCP_FS is not set
-# CONFIG_CODA_FS is not set
-# CONFIG_AFS_FS is not set
-
-#
-# Partition Types
-#
-# CONFIG_PARTITION_ADVANCED is not set
-CONFIG_MSDOS_PARTITION=y
-
-#
-# Native Language Support
-#
-CONFIG_NLS=y
-CONFIG_NLS_DEFAULT="iso8859-1"
-# CONFIG_NLS_CODEPAGE_437 is not set
-# CONFIG_NLS_CODEPAGE_737 is not set
-# CONFIG_NLS_CODEPAGE_775 is not set
-# CONFIG_NLS_CODEPAGE_850 is not set
-# CONFIG_NLS_CODEPAGE_852 is not set
-# CONFIG_NLS_CODEPAGE_855 is not set
-# CONFIG_NLS_CODEPAGE_857 is not set
-# CONFIG_NLS_CODEPAGE_860 is not set
-# CONFIG_NLS_CODEPAGE_861 is not set
-# CONFIG_NLS_CODEPAGE_862 is not set
-# CONFIG_NLS_CODEPAGE_863 is not set
-# CONFIG_NLS_CODEPAGE_864 is not set
-# CONFIG_NLS_CODEPAGE_865 is not set
-# CONFIG_NLS_CODEPAGE_866 is not set
-# CONFIG_NLS_CODEPAGE_869 is not set
-# CONFIG_NLS_CODEPAGE_936 is not set
-# CONFIG_NLS_CODEPAGE_950 is not set
-# CONFIG_NLS_CODEPAGE_932 is not set
-# CONFIG_NLS_CODEPAGE_949 is not set
-# CONFIG_NLS_CODEPAGE_874 is not set
-# CONFIG_NLS_ISO8859_8 is not set
-# CONFIG_NLS_CODEPAGE_1250 is not set
-# CONFIG_NLS_CODEPAGE_1251 is not set
-# CONFIG_NLS_ASCII is not set
-# CONFIG_NLS_ISO8859_1 is not set
-# CONFIG_NLS_ISO8859_2 is not set
-# CONFIG_NLS_ISO8859_3 is not set
-# CONFIG_NLS_ISO8859_4 is not set
-# CONFIG_NLS_ISO8859_5 is not set
-# CONFIG_NLS_ISO8859_6 is not set
-# CONFIG_NLS_ISO8859_7 is not set
-# CONFIG_NLS_ISO8859_9 is not set
-# CONFIG_NLS_ISO8859_13 is not set
-# CONFIG_NLS_ISO8859_14 is not set
-# CONFIG_NLS_ISO8859_15 is not set
-# CONFIG_NLS_KOI8_R is not set
-# CONFIG_NLS_KOI8_U is not set
-# CONFIG_NLS_UTF8 is not set
-
-#
-# Profiling support
-#
-# CONFIG_PROFILING is not set
-
-#
-# Kernel hacking
-#
-# CONFIG_PRINTK_TIME is not set
-# CONFIG_DEBUG_KERNEL is not set
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_DEBUG_BUGVERBOSE=y
-CONFIG_FRAME_POINTER=y
-# CONFIG_DEBUG_USER is not set
-
-#
-# Security options
-#
-# CONFIG_KEYS is not set
-# CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
-# CONFIG_CRYPTO is not set
-
-#
-# Hardware crypto devices
-#
-
-#
-# Library routines
-#
-# CONFIG_CRC_CCITT is not set
-CONFIG_CRC32=y
-# CONFIG_LIBCRC32C is not set
diff --git a/arch/arm/configs/s3c2410_defconfig b/arch/arm/configs/s3c2410_defconfig
--- a/arch/arm/configs/s3c2410_defconfig
+++ b/arch/arm/configs/s3c2410_defconfig
@@ -1,14 +1,13 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc1-bk2
-# Sun Mar 27 17:47:45 2005
+# Linux kernel version: 2.6.12-git4
+# Wed Jun 22 15:56:42 2005
 #
 CONFIG_ARM=y
 CONFIG_MMU=y
 CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_GENERIC_IOMAP=y
 
 #
 # Code maturity level options
@@ -17,6 +16,7 @@ CONFIG_EXPERIMENTAL=y
 # CONFIG_CLEAN_COMPILE is not set
 CONFIG_BROKEN=y
 CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
@@ -35,6 +35,8 @@ CONFIG_KOBJECT_UEVENT=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
@@ -81,6 +83,7 @@ CONFIG_ARCH_S3C2410=y
 # CONFIG_ARCH_VERSATILE is not set
 # CONFIG_ARCH_IMX is not set
 # CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_AAEC2000 is not set
 
 #
 # S3C24XX Implementations
@@ -134,6 +137,7 @@ CONFIG_CPU_TLB_V4WBI=y
 #
 # Bus support
 #
+CONFIG_ISA_DMA_API=y
 
 #
 # PCCARD (PCMCIA/CardBus) support
@@ -143,7 +147,9 @@ CONFIG_CPU_TLB_V4WBI=y
 #
 # Kernel Features
 #
+# CONFIG_SMP is not set
 # CONFIG_PREEMPT is not set
+# CONFIG_DISCONTIGMEM is not set
 CONFIG_ALIGNMENT_TRAP=y
 
 #
@@ -297,7 +303,6 @@ CONFIG_PARPORT_1284=y
 #
 # Block devices
 #
-# CONFIG_BLK_DEV_FD is not set
 # CONFIG_PARIDE is not set
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
@@ -359,6 +364,7 @@ CONFIG_BLK_DEV_IDE_BAST=y
 #
 # Fusion MPT device support
 #
+# CONFIG_FUSION is not set
 
 #
 # IEEE 1394 (FireWire) support
@@ -378,10 +384,11 @@ CONFIG_NET=y
 # Networking options
 #
 # CONFIG_PACKET is not set
-# CONFIG_NETLINK_DEV is not set
 CONFIG_UNIX=y
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_FIB_TRIE is not set
 # CONFIG_IP_MULTICAST is not set
 # CONFIG_IP_ADVANCED_ROUTER is not set
 CONFIG_IP_PNP=y
@@ -443,8 +450,9 @@ CONFIG_NETDEVICES=y
 # Ethernet (10 or 100Mbit)
 #
 CONFIG_NET_ETHERNET=y
-# CONFIG_MII is not set
+CONFIG_MII=m
 # CONFIG_SMC91X is not set
+CONFIG_DM9000=m
 
 #
 # Ethernet (1000 Mbit)
@@ -521,7 +529,6 @@ CONFIG_SERIO_SERPORT=y
 CONFIG_SERIO_LIBPS2=y
 # CONFIG_SERIO_RAW is not set
 # CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
 
 #
 # Character devices
@@ -563,7 +570,6 @@ CONFIG_SERIAL_8250_SHARE_IRQ=y
 #
 CONFIG_SERIAL_S3C2410=y
 CONFIG_SERIAL_S3C2410_CONSOLE=y
-CONFIG_SERIAL_BAST_SIO=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_UNIX98_PTYS=y
@@ -605,7 +611,6 @@ CONFIG_S3C2410_RTC=y
 #
 # TPM devices
 #
-# CONFIG_TCG_TPM is not set
 
 #
 # I2C support
@@ -654,6 +659,7 @@ CONFIG_SENSORS_LM78=m
 CONFIG_SENSORS_LM85=m
 # CONFIG_SENSORS_LM87 is not set
 # CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
 # CONFIG_SENSORS_MAX1619 is not set
 # CONFIG_SENSORS_PC87360 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
@@ -665,6 +671,7 @@ CONFIG_SENSORS_LM85=m
 #
 # Other I2C Chip support
 #
+# CONFIG_SENSORS_DS1337 is not set
 CONFIG_SENSORS_EEPROM=m
 # CONFIG_SENSORS_PCF8574 is not set
 # CONFIG_SENSORS_PCF8591 is not set
@@ -696,8 +703,10 @@ CONFIG_FB=y
 # CONFIG_FB_CFB_COPYAREA is not set
 # CONFIG_FB_CFB_IMAGEBLIT is not set
 # CONFIG_FB_SOFT_CURSOR is not set
+# CONFIG_FB_MACMODES is not set
 CONFIG_FB_MODE_HELPERS=y
 # CONFIG_FB_TILEBLITTING is not set
+# CONFIG_FB_S1D13XXX is not set
 # CONFIG_FB_VIRTUAL is not set
 
 #
@@ -782,7 +791,6 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 #
 CONFIG_PROC_FS=y
 CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
 # CONFIG_DEVPTS_FS_XATTR is not set
 # CONFIG_TMPFS is not set
 # CONFIG_HUGETLBFS is not set
diff --git a/arch/arm/configs/shark_defconfig b/arch/arm/configs/shark_defconfig
--- a/arch/arm/configs/shark_defconfig
+++ b/arch/arm/configs/shark_defconfig
@@ -1,22 +1,21 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc1-bk2
-# Sun Mar 27 23:59:14 2005
+# Linux kernel version: 2.6.12-git3
+# Sat Jul 16 15:21:47 2005
 #
 CONFIG_ARM=y
 CONFIG_MMU=y
 CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_GENERIC_IOMAP=y
 
 #
 # Code maturity level options
 #
 CONFIG_EXPERIMENTAL=y
-# CONFIG_CLEAN_COMPILE is not set
-CONFIG_BROKEN=y
+CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
@@ -33,7 +32,10 @@ CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
 # CONFIG_EMBEDDED is not set
 CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
@@ -81,6 +83,7 @@ CONFIG_ARCH_SHARK=y
 # CONFIG_ARCH_VERSATILE is not set
 # CONFIG_ARCH_IMX is not set
 # CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_AAEC2000 is not set
 
 #
 # Processor Type
@@ -103,10 +106,12 @@ CONFIG_CPU_TLB_V4WB=y
 #
 CONFIG_ISA=y
 CONFIG_ISA_DMA=y
+CONFIG_ISA_DMA_API=y
 CONFIG_PCI=y
 CONFIG_PCI_HOST_VIA82C505=y
 CONFIG_PCI_LEGACY_PROC=y
 # CONFIG_PCI_NAMES is not set
+# CONFIG_PCI_DEBUG is not set
 
 #
 # PCCARD (PCMCIA/CardBus) support
@@ -116,7 +121,9 @@ CONFIG_PCI_LEGACY_PROC=y
 #
 # Kernel Features
 #
+# CONFIG_SMP is not set
 # CONFIG_PREEMPT is not set
+# CONFIG_DISCONTIGMEM is not set
 CONFIG_LEDS=y
 CONFIG_LEDS_TIMER=y
 # CONFIG_LEDS_CPU is not set
@@ -163,6 +170,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_STANDALONE is not set
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -172,8 +180,8 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 #
 # Parallel port support
 #
-CONFIG_PARPORT=y
-CONFIG_PARPORT_PC=y
+CONFIG_PARPORT=m
+CONFIG_PARPORT_PC=m
 # CONFIG_PARPORT_SERIAL is not set
 # CONFIG_PARPORT_PC_FIFO is not set
 # CONFIG_PARPORT_PC_SUPERIO is not set
@@ -189,7 +197,6 @@ CONFIG_PARPORT_PC=y
 #
 # Block devices
 #
-# CONFIG_BLK_DEV_FD is not set
 # CONFIG_BLK_DEV_XD is not set
 # CONFIG_PARIDE is not set
 # CONFIG_BLK_CPQ_DA is not set
@@ -229,7 +236,7 @@ CONFIG_BLK_DEV_IDE=y
 # CONFIG_BLK_DEV_IDE_SATA is not set
 CONFIG_BLK_DEV_IDEDISK=y
 # CONFIG_IDEDISK_MULTI_MODE is not set
-CONFIG_BLK_DEV_IDECD=y
+CONFIG_BLK_DEV_IDECD=m
 # CONFIG_BLK_DEV_IDETAPE is not set
 CONFIG_BLK_DEV_IDEFLOPPY=y
 # CONFIG_BLK_DEV_IDESCSI is not set
@@ -261,6 +268,7 @@ CONFIG_CHR_DEV_ST=m
 CONFIG_BLK_DEV_SR=m
 # CONFIG_BLK_DEV_SR_VENDOR is not set
 CONFIG_CHR_DEV_SG=m
+# CONFIG_CHR_DEV_SCH is not set
 
 #
 # Some SCSI devices (e.g. CD jukebox) support multiple LUNs
@@ -290,17 +298,14 @@ CONFIG_CHR_DEV_SG=m
 # CONFIG_SCSI_AIC7XXX_OLD is not set
 # CONFIG_SCSI_AIC79XX is not set
 # CONFIG_SCSI_DPT_I2O is not set
-# CONFIG_SCSI_ADVANSYS is not set
 # CONFIG_SCSI_IN2000 is not set
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
 # CONFIG_SCSI_SATA is not set
 # CONFIG_SCSI_BUSLOGIC is not set
-# CONFIG_SCSI_CPQFCTS is not set
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_DTC3280 is not set
 # CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_EATA_PIO is not set
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
 # CONFIG_SCSI_GDTH is not set
 # CONFIG_SCSI_GENERIC_NCR5380 is not set
@@ -314,11 +319,8 @@ CONFIG_CHR_DEV_SG=m
 # CONFIG_SCSI_SYM53C8XX_2 is not set
 # CONFIG_SCSI_IPR is not set
 # CONFIG_SCSI_PAS16 is not set
-# CONFIG_SCSI_PCI2000 is not set
-# CONFIG_SCSI_PCI2220I is not set
 # CONFIG_SCSI_PSI240I is not set
 # CONFIG_SCSI_QLOGIC_FAS is not set
-# CONFIG_SCSI_QLOGIC_ISP is not set
 # CONFIG_SCSI_QLOGIC_FC is not set
 # CONFIG_SCSI_QLOGIC_1280 is not set
 CONFIG_SCSI_QLA2XXX=m
@@ -327,6 +329,7 @@ CONFIG_SCSI_QLA2XXX=m
 # CONFIG_SCSI_QLA2300 is not set
 # CONFIG_SCSI_QLA2322 is not set
 # CONFIG_SCSI_QLA6312 is not set
+# CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_SYM53C416 is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
@@ -344,6 +347,8 @@ CONFIG_SCSI_QLA2XXX=m
 # Fusion MPT device support
 #
 # CONFIG_FUSION is not set
+# CONFIG_FUSION_SPI is not set
+# CONFIG_FUSION_FC is not set
 
 #
 # IEEE 1394 (FireWire) support
@@ -365,7 +370,6 @@ CONFIG_NET=y
 #
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK_DEV is not set
 CONFIG_UNIX=y
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
@@ -380,7 +384,7 @@ CONFIG_INET=y
 # CONFIG_INET_ESP is not set
 # CONFIG_INET_IPCOMP is not set
 # CONFIG_INET_TUNNEL is not set
-# CONFIG_IP_TCPDIAG is not set
+CONFIG_IP_TCPDIAG=y
 # CONFIG_IP_TCPDIAG_IPV6 is not set
 # CONFIG_IPV6 is not set
 # CONFIG_NETFILTER is not set
@@ -439,6 +443,7 @@ CONFIG_NET_ETHERNET=y
 # CONFIG_LANCE is not set
 # CONFIG_NET_VENDOR_SMC is not set
 # CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
 # CONFIG_NET_VENDOR_RACAL is not set
 
 #
@@ -483,9 +488,11 @@ CONFIG_CS89x0=y
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
 # CONFIG_R8169 is not set
+# CONFIG_SKGE is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
 
 #
 # Ethernet (10000 Mbit)
@@ -569,7 +576,6 @@ CONFIG_SERIO_I8042=y
 CONFIG_SERIO_LIBPS2=y
 # CONFIG_SERIO_RAW is not set
 # CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
 
 #
 # Character devices
@@ -592,6 +598,7 @@ CONFIG_SERIAL_8250_NR_UARTS=4
 #
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -653,6 +660,7 @@ CONFIG_FB_CFB_FILLRECT=y
 CONFIG_FB_CFB_COPYAREA=y
 CONFIG_FB_CFB_IMAGEBLIT=y
 CONFIG_FB_SOFT_CURSOR=y
+# CONFIG_FB_MACMODES is not set
 # CONFIG_FB_MODE_HELPERS is not set
 # CONFIG_FB_TILEBLITTING is not set
 # CONFIG_FB_CIRRUS is not set
@@ -674,7 +682,7 @@ CONFIG_FB_CYBER2000=y
 # CONFIG_FB_3DFX is not set
 # CONFIG_FB_VOODOO1 is not set
 # CONFIG_FB_TRIDENT is not set
-# CONFIG_FB_PM3 is not set
+# CONFIG_FB_S1D13XXX is not set
 # CONFIG_FB_VIRTUAL is not set
 
 #
@@ -808,7 +816,7 @@ CONFIG_DNOTIFY=y
 #
 # CD-ROM/DVD Filesystems
 #
-CONFIG_ISO9660_FS=y
+CONFIG_ISO9660_FS=m
 CONFIG_JOLIET=y
 # CONFIG_ZISOFS is not set
 # CONFIG_UDF_FS is not set
@@ -816,9 +824,9 @@ CONFIG_JOLIET=y
 #
 # DOS/FAT/NT Filesystems
 #
-CONFIG_FAT_FS=y
-CONFIG_MSDOS_FS=y
-CONFIG_VFAT_FS=y
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
 CONFIG_FAT_DEFAULT_CODEPAGE=437
 CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 # CONFIG_NTFS_FS is not set
@@ -833,7 +841,6 @@ CONFIG_DEVFS_MOUNT=y
 # CONFIG_DEVFS_DEBUG is not set
 # CONFIG_DEVPTS_FS_XATTR is not set
 # CONFIG_TMPFS is not set
-# CONFIG_HUGETLBFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
 
@@ -857,13 +864,14 @@ CONFIG_RAMFS=y
 #
 # Network File Systems
 #
-CONFIG_NFS_FS=y
-# CONFIG_NFS_V3 is not set
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
 # CONFIG_NFS_V4 is not set
 # CONFIG_NFS_DIRECTIO is not set
 # CONFIG_NFSD is not set
-CONFIG_LOCKD=y
-CONFIG_SUNRPC=y
+CONFIG_LOCKD=m
+CONFIG_LOCKD_V4=y
+CONFIG_SUNRPC=m
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -895,12 +903,12 @@ CONFIG_MSDOS_PARTITION=y
 #
 # Native Language Support
 #
-CONFIG_NLS=y
+CONFIG_NLS=m
 CONFIG_NLS_DEFAULT="iso8859-1"
-CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_437=m
 # CONFIG_NLS_CODEPAGE_737 is not set
 # CONFIG_NLS_CODEPAGE_775 is not set
-CONFIG_NLS_CODEPAGE_850=y
+CONFIG_NLS_CODEPAGE_850=m
 # CONFIG_NLS_CODEPAGE_852 is not set
 # CONFIG_NLS_CODEPAGE_855 is not set
 # CONFIG_NLS_CODEPAGE_857 is not set
@@ -921,7 +929,7 @@ CONFIG_NLS_CODEPAGE_850=y
 # CONFIG_NLS_CODEPAGE_1250 is not set
 # CONFIG_NLS_CODEPAGE_1251 is not set
 # CONFIG_NLS_ASCII is not set
-CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_1=m
 # CONFIG_NLS_ISO8859_2 is not set
 # CONFIG_NLS_ISO8859_3 is not set
 # CONFIG_NLS_ISO8859_4 is not set
@@ -945,11 +953,22 @@ CONFIG_NLS_ISO8859_1=y
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
-# CONFIG_DEBUG_KERNEL is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_MAGIC_SYSRQ is not set
 CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_KOBJECT is not set
 CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_FS is not set
 CONFIG_FRAME_POINTER=y
 CONFIG_DEBUG_USER=y
+# CONFIG_DEBUG_WAITQ is not set
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_LL is not set
 
 #
 # Security options
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -6,7 +6,7 @@ AFLAGS_head.o := -DTEXTADDR=$(TEXTADDR) 
 
 # Object file lists.
 
-obj-y		:= arch.o compat.o dma.o entry-armv.o entry-common.o irq.o   \
+obj-y		:= compat.o dma.o entry-armv.o entry-common.o irq.o \
 		   process.o ptrace.o semaphore.o setup.o signal.o sys_arm.o \
 		   time.o traps.o
 
diff --git a/arch/arm/kernel/arch.c b/arch/arm/kernel/arch.c
deleted file mode 100644
--- a/arch/arm/kernel/arch.c
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- *  linux/arch/arm/kernel/arch.c
- *
- *  Architecture specific fixups.
- */
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/types.h>
-
-#include <asm/elf.h>
-#include <asm/page.h>
-#include <asm/setup.h>
-#include <asm/mach/arch.h>
-
-unsigned int vram_size;
-
-#ifdef CONFIG_ARCH_ACORN
-
-unsigned int memc_ctrl_reg;
-unsigned int number_mfm_drives;
-
-static int __init parse_tag_acorn(const struct tag *tag)
-{
-	memc_ctrl_reg = tag->u.acorn.memc_control_reg;
-	number_mfm_drives = tag->u.acorn.adfsdrives;
-
-	switch (tag->u.acorn.vram_pages) {
-	case 512:
-		vram_size += PAGE_SIZE * 256;
-	case 256:
-		vram_size += PAGE_SIZE * 256;
-	default:
-		break;
-	}
-#if 0
-	if (vram_size) {
-		desc->video_start = 0x02000000;
-		desc->video_end   = 0x02000000 + vram_size;
-	}
-#endif
-	return 0;
-}
-
-__tagtable(ATAG_ACORN, parse_tag_acorn);
-
-#endif
diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c
--- a/arch/arm/kernel/armksyms.c
+++ b/arch/arm/kernel/armksyms.c
@@ -30,9 +30,6 @@ extern void __lshrdi3(void);
 extern void __modsi3(void);
 extern void __muldi3(void);
 extern void __ucmpdi2(void);
-extern void __udivdi3(void);
-extern void __umoddi3(void);
-extern void __udivmoddi4(void);
 extern void __udivsi3(void);
 extern void __umodsi3(void);
 extern void __do_div64(void);
@@ -44,7 +41,10 @@ extern void fp_enter(void);
  * This has a special calling convention; it doesn't
  * modify any of the usual registers, except for LR.
  */
+#define EXPORT_CRC_ALIAS(sym) __CRC_SYMBOL(sym, "")
+
 #define EXPORT_SYMBOL_ALIAS(sym,orig)		\
+ EXPORT_CRC_ALIAS(sym)				\
  const struct kernel_symbol __ksymtab_##sym	\
   __attribute__((section("__ksymtab"))) =	\
     { (unsigned long)&orig, #sym };
@@ -134,9 +134,6 @@ EXPORT_SYMBOL(__lshrdi3);
 EXPORT_SYMBOL(__modsi3);
 EXPORT_SYMBOL(__muldi3);
 EXPORT_SYMBOL(__ucmpdi2);
-EXPORT_SYMBOL(__udivdi3);
-EXPORT_SYMBOL(__umoddi3);
-EXPORT_SYMBOL(__udivmoddi4);
 EXPORT_SYMBOL(__udivsi3);
 EXPORT_SYMBOL(__umodsi3);
 EXPORT_SYMBOL(__do_div64);
diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
--- a/arch/arm/kernel/bios32.c
+++ b/arch/arm/kernel/bios32.c
@@ -447,9 +447,26 @@ pcibios_resource_to_bus(struct pci_dev *
 	region->end   = res->end - offset;
 }
 
+void __devinit
+pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
+			struct pci_bus_region *region)
+{
+	struct pci_sys_data *root = dev->sysdata;
+	unsigned long offset = 0;
+
+	if (res->flags & IORESOURCE_IO)
+		offset = root->io_offset;
+	if (res->flags & IORESOURCE_MEM)
+		offset = root->mem_offset;
+
+	res->start = region->start + offset;
+	res->end   = region->end + offset;
+}
+
 #ifdef CONFIG_HOTPLUG
 EXPORT_SYMBOL(pcibios_fixup_bus);
 EXPORT_SYMBOL(pcibios_resource_to_bus);
+EXPORT_SYMBOL(pcibios_bus_to_resource);
 #endif
 
 /*
diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S
--- a/arch/arm/kernel/calls.S
+++ b/arch/arm/kernel/calls.S
@@ -327,6 +327,12 @@ __syscall_start:
 /* 310 */	.long	sys_request_key
 		.long	sys_keyctl
 		.long	sys_semtimedop
+/* vserver */	.long	sys_ni_syscall
+		.long	sys_ioprio_set
+/* 315 */	.long	sys_ioprio_get
+		.long	sys_inotify_init
+		.long	sys_inotify_add_watch
+		.long	sys_inotify_rm_watch
 __syscall_end:
 
 		.rept	NR_syscalls - (__syscall_end - __syscall_start) / 4
diff --git a/arch/arm/kernel/ecard.c b/arch/arm/kernel/ecard.c
--- a/arch/arm/kernel/ecard.c
+++ b/arch/arm/kernel/ecard.c
@@ -866,19 +866,19 @@ static struct expansion_card *__init eca
 	return ec;
 }
 
-static ssize_t ecard_show_irq(struct device *dev, char *buf)
+static ssize_t ecard_show_irq(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct expansion_card *ec = ECARD_DEV(dev);
 	return sprintf(buf, "%u\n", ec->irq);
 }
 
-static ssize_t ecard_show_dma(struct device *dev, char *buf)
+static ssize_t ecard_show_dma(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct expansion_card *ec = ECARD_DEV(dev);
 	return sprintf(buf, "%u\n", ec->dma);
 }
 
-static ssize_t ecard_show_resources(struct device *dev, char *buf)
+static ssize_t ecard_show_resources(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct expansion_card *ec = ECARD_DEV(dev);
 	char *str = buf;
@@ -893,19 +893,19 @@ static ssize_t ecard_show_resources(stru
 	return str - buf;
 }
 
-static ssize_t ecard_show_vendor(struct device *dev, char *buf)
+static ssize_t ecard_show_vendor(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct expansion_card *ec = ECARD_DEV(dev);
 	return sprintf(buf, "%u\n", ec->cid.manufacturer);
 }
 
-static ssize_t ecard_show_device(struct device *dev, char *buf)
+static ssize_t ecard_show_device(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct expansion_card *ec = ECARD_DEV(dev);
 	return sprintf(buf, "%u\n", ec->cid.product);
 }
 
-static ssize_t ecard_show_type(struct device *dev, char *buf)
+static ssize_t ecard_show_type(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct expansion_card *ec = ECARD_DEV(dev);
 	return sprintf(buf, "%s\n", ec->type == ECARD_EASI ? "EASI" : "IOC");
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -24,48 +24,91 @@
 #include "entry-header.S"
 
 /*
+ * Interrupt handling.  Preserves r7, r8, r9
+ */
+	.macro	irq_handler
+1:	get_irqnr_and_base r0, r6, r5, lr
+	movne	r1, sp
+	@
+	@ routine called with r0 = irq number, r1 = struct pt_regs *
+	@
+	adrne	lr, 1b
+	bne	asm_do_IRQ
+
+#ifdef CONFIG_SMP
+	/*
+	 * XXX
+	 *
+	 * this macro assumes that irqstat (r6) and base (r5) are
+	 * preserved from get_irqnr_and_base above
+	 */
+	test_for_ipi r0, r6, r5, lr
+	movne	r0, sp
+	adrne	lr, 1b
+	bne	do_IPI
+#endif
+
+	.endm
+
+/*
  * Invalid mode handlers
  */
-	.macro	inv_entry, sym, reason
-	sub	sp, sp, #S_FRAME_SIZE		@ Allocate frame size in one go
-	stmia	sp, {r0 - lr}			@ Save XXX r0 - lr
-	ldr	r4, .LC\sym
+	.macro	inv_entry, reason
+	sub	sp, sp, #S_FRAME_SIZE
+	stmib	sp, {r1 - lr}
 	mov	r1, #\reason
 	.endm
 
 __pabt_invalid:
-	inv_entry abt, BAD_PREFETCH
-	b	1f
+	inv_entry BAD_PREFETCH
+	b	common_invalid
 
 __dabt_invalid:
-	inv_entry abt, BAD_DATA
-	b	1f
+	inv_entry BAD_DATA
+	b	common_invalid
 
 __irq_invalid:
-	inv_entry irq, BAD_IRQ
-	b	1f
+	inv_entry BAD_IRQ
+	b	common_invalid
 
 __und_invalid:
-	inv_entry und, BAD_UNDEFINSTR
+	inv_entry BAD_UNDEFINSTR
+
+	@
+	@ XXX fall through to common_invalid
+	@
+
+@
+@ common_invalid - generic code for failed exception (re-entrant version of handlers)
+@
+common_invalid:
+	zero_fp
+
+	ldmia	r0, {r4 - r6}
+	add	r0, sp, #S_PC		@ here for interlock avoidance
+	mov	r7, #-1			@  ""   ""    ""        ""
+	str	r4, [sp]		@ save preserved r0
+	stmia	r0, {r5 - r7}		@ lr_<exception>,
+					@ cpsr_<exception>, "old_r0"
 
-1:	zero_fp
-	ldmia	r4, {r5 - r7}			@ Get XXX pc, cpsr, old_r0
-	add	r4, sp, #S_PC
-	stmia	r4, {r5 - r7}			@ Save XXX pc, cpsr, old_r0
 	mov	r0, sp
-	and	r2, r6, #31			@ int mode
+	and	r2, r6, #0x1f
 	b	bad_mode
 
 /*
  * SVC mode handlers
  */
-	.macro	svc_entry, sym
+	.macro	svc_entry
 	sub	sp, sp, #S_FRAME_SIZE
-	stmia	sp, {r0 - r12}			@ save r0 - r12
-	ldr	r2, .LC\sym
-	add	r0, sp, #S_FRAME_SIZE
-	ldmia	r2, {r2 - r4}			@ get pc, cpsr
-	add	r5, sp, #S_SP
+	stmib	sp, {r1 - r12}
+
+	ldmia	r0, {r1 - r3}
+	add	r5, sp, #S_SP		@ here for interlock avoidance
+	mov	r4, #-1			@  ""  ""      ""       ""
+	add	r0, sp, #S_FRAME_SIZE   @  ""  ""      ""       ""
+	str	r1, [sp]		@ save the "real" r0 copied
+					@ from the exception stack
+
 	mov	r1, lr
 
 	@
@@ -82,7 +125,7 @@ __und_invalid:
 
 	.align	5
 __dabt_svc:
-	svc_entry abt
+	svc_entry
 
 	@
 	@ get ready to re-enable interrupts if appropriate
@@ -129,28 +172,24 @@ __dabt_svc:
 
 	.align	5
 __irq_svc:
-	svc_entry irq
+	svc_entry
+
 #ifdef CONFIG_PREEMPT
-	get_thread_info r8
-	ldr	r9, [r8, #TI_PREEMPT]		@ get preempt count
-	add	r7, r9, #1			@ increment it
-	str	r7, [r8, #TI_PREEMPT]
+	get_thread_info tsk
+	ldr	r8, [tsk, #TI_PREEMPT]		@ get preempt count
+	add	r7, r8, #1			@ increment it
+	str	r7, [tsk, #TI_PREEMPT]
 #endif
-1:	get_irqnr_and_base r0, r6, r5, lr
-	movne	r1, sp
-	@
-	@ routine called with r0 = irq number, r1 = struct pt_regs *
-	@
-	adrne	lr, 1b
-	bne	asm_do_IRQ
+
+	irq_handler
 #ifdef CONFIG_PREEMPT
-	ldr	r0, [r8, #TI_FLAGS]		@ get flags
+	ldr	r0, [tsk, #TI_FLAGS]		@ get flags
 	tst	r0, #_TIF_NEED_RESCHED
 	blne	svc_preempt
 preempt_return:
-	ldr	r0, [r8, #TI_PREEMPT]		@ read preempt value
+	ldr	r0, [tsk, #TI_PREEMPT]		@ read preempt value
+	str	r8, [tsk, #TI_PREEMPT]		@ restore preempt count
 	teq	r0, r7
-	str	r9, [r8, #TI_PREEMPT]		@ restore preempt count
 	strne	r0, [r0, -r0]			@ bug()
 #endif
 	ldr	r0, [sp, #S_PSR]		@ irqs are already disabled
@@ -161,7 +200,7 @@ preempt_return:
 
 #ifdef CONFIG_PREEMPT
 svc_preempt:
-	teq	r9, #0				@ was preempt count = 0
+	teq	r8, #0				@ was preempt count = 0
 	ldreq	r6, .LCirq_stat
 	movne	pc, lr				@ no
 	ldr	r0, [r6, #4]			@ local_irq_count
@@ -169,9 +208,9 @@ svc_preempt:
 	adds	r0, r0, r1
 	movne	pc, lr
 	mov	r7, #0				@ preempt_schedule_irq
-	str	r7, [r8, #TI_PREEMPT]		@ expects preempt_count == 0
+	str	r7, [tsk, #TI_PREEMPT]		@ expects preempt_count == 0
 1:	bl	preempt_schedule_irq		@ irq en/disable is done inside
-	ldr	r0, [r8, #TI_FLAGS]		@ get new tasks TI_FLAGS
+	ldr	r0, [tsk, #TI_FLAGS]		@ get new tasks TI_FLAGS
 	tst	r0, #_TIF_NEED_RESCHED
 	beq	preempt_return			@ go again
 	b	1b
@@ -179,7 +218,7 @@ svc_preempt:
 
 	.align	5
 __und_svc:
-	svc_entry und
+	svc_entry
 
 	@
 	@ call emulation code, which returns using r9 if it has emulated
@@ -209,7 +248,7 @@ __und_svc:
 
 	.align	5
 __pabt_svc:
-	svc_entry abt
+	svc_entry
 
 	@
 	@ re-enable interrupts if appropriate
@@ -242,12 +281,8 @@ __pabt_svc:
 	ldmia	sp, {r0 - pc}^			@ load r0 - pc, cpsr
 
 	.align	5
-.LCirq:
-	.word	__temp_irq
-.LCund:
-	.word	__temp_und
-.LCabt:
-	.word	__temp_abt
+.LCcralign:
+	.word	cr_alignment
 #ifdef MULTI_ABORT
 .LCprocfns:
 	.word	processor
@@ -262,12 +297,16 @@ __pabt_svc:
 /*
  * User mode handlers
  */
-	.macro	usr_entry, sym
-	sub	sp, sp, #S_FRAME_SIZE		@ Allocate frame size in one go
-	stmia	sp, {r0 - r12}			@ save r0 - r12
-	ldr	r7, .LC\sym
-	add	r5, sp, #S_PC
-	ldmia	r7, {r2 - r4}			@ Get USR pc, cpsr
+	.macro	usr_entry
+	sub	sp, sp, #S_FRAME_SIZE
+	stmib	sp, {r1 - r12}
+
+	ldmia	r0, {r1 - r3}
+	add	r0, sp, #S_PC		@ here for interlock avoidance
+	mov	r4, #-1			@  ""  ""     ""        ""
+
+	str	r1, [sp]		@ save the "real" r0 copied
+					@ from the exception stack
 
 #if __LINUX_ARM_ARCH__ < 6 && !defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG)
 	@ make sure our user space atomic helper is aborted
@@ -284,13 +323,13 @@ __pabt_svc:
 	@
 	@ Also, separately save sp_usr and lr_usr
 	@
-	stmia	r5, {r2 - r4}
-	stmdb	r5, {sp, lr}^
+	stmia	r0, {r2 - r4}
+	stmdb	r0, {sp, lr}^
 
 	@
 	@ Enable the alignment trap while in kernel mode
 	@
-	alignment_trap r7, r0, __temp_\sym
+	alignment_trap r0
 
 	@
 	@ Clear FP to mark the first stack frame
@@ -300,7 +339,7 @@ __pabt_svc:
 
 	.align	5
 __dabt_usr:
-	usr_entry abt
+	usr_entry
 
 	@
 	@ Call the processor-specific abort handler:
@@ -329,30 +368,23 @@ __dabt_usr:
 
 	.align	5
 __irq_usr:
-	usr_entry irq
+	usr_entry
 
+	get_thread_info tsk
 #ifdef CONFIG_PREEMPT
-	get_thread_info r8
-	ldr	r9, [r8, #TI_PREEMPT]		@ get preempt count
-	add	r7, r9, #1			@ increment it
-	str	r7, [r8, #TI_PREEMPT]
+	ldr	r8, [tsk, #TI_PREEMPT]		@ get preempt count
+	add	r7, r8, #1			@ increment it
+	str	r7, [tsk, #TI_PREEMPT]
 #endif
-1:	get_irqnr_and_base r0, r6, r5, lr
-	movne	r1, sp
-	adrne	lr, 1b
-	@
-	@ routine called with r0 = irq number, r1 = struct pt_regs *
-	@
-	bne	asm_do_IRQ
+
+	irq_handler
 #ifdef CONFIG_PREEMPT
-	ldr	r0, [r8, #TI_PREEMPT]
+	ldr	r0, [tsk, #TI_PREEMPT]
+	str	r8, [tsk, #TI_PREEMPT]
 	teq	r0, r7
-	str	r9, [r8, #TI_PREEMPT]
 	strne	r0, [r0, -r0]
-	mov	tsk, r8
-#else
-	get_thread_info tsk
 #endif
+
 	mov	why, #0
 	b	ret_to_user
 
@@ -360,7 +392,7 @@ __irq_usr:
 
 	.align	5
 __und_usr:
-	usr_entry und
+	usr_entry
 
 	tst	r3, #PSR_T_BIT			@ Thumb mode?
 	bne	fpundefinstr			@ ignore FP
@@ -476,7 +508,7 @@ fpundefinstr:
 
 	.align	5
 __pabt_usr:
-	usr_entry abt
+	usr_entry
 
 	enable_irq				@ Enable interrupts
 	mov	r0, r2				@ address (pc)
@@ -501,6 +533,13 @@ ENTRY(__switch_to)
 	ldr	r3, [r2, #TI_TP_VALUE]
 	stmia	ip!, {r4 - sl, fp, sp, lr}	@ Store most regs on stack
 	ldr	r6, [r2, #TI_CPU_DOMAIN]!
+#if __LINUX_ARM_ARCH__ >= 6
+#ifdef CONFIG_CPU_MPCORE
+	clrex
+#else
+	strex	r3, r4, [ip]			@ Clear exclusive monitor
+#endif
+#endif
 #if defined(CONFIG_CPU_XSCALE) && !defined(CONFIG_IWMMXT)
 	mra	r4, r5, acc0
 	stmia   ip, {r4, r5}
@@ -741,29 +780,41 @@ __kuser_helper_end:
  *
  * Common stub entry macro:
  *   Enter in IRQ mode, spsr = SVC/USR CPSR, lr = SVC/USR PC
+ *
+ * SP points to a minimal amount of processor-private memory, the address
+ * of which is copied into r0 for the mode specific abort handler.
  */
-	.macro	vector_stub, name, sym, correction=0
+	.macro	vector_stub, name, correction=0
 	.align	5
 
 vector_\name:
-	ldr	r13, .LCs\sym
 	.if \correction
 	sub	lr, lr, #\correction
 	.endif
-	str	lr, [r13]			@ save lr_IRQ
+
+	@
+	@ Save r0, lr_<exception> (parent PC) and spsr_<exception>
+	@ (parent CPSR)
+	@
+	stmia	sp, {r0, lr}		@ save r0, lr
 	mrs	lr, spsr
-	str	lr, [r13, #4]			@ save spsr_IRQ
+	str	lr, [sp, #8]		@ save spsr
+
 	@
-	@ now branch to the relevant MODE handling routine
+	@ Prepare for SVC32 mode.  IRQs remain disabled.
 	@
-	mrs	r13, cpsr
-	bic	r13, r13, #MODE_MASK
-	orr	r13, r13, #SVC_MODE
-	msr	spsr_cxsf, r13			@ switch to SVC_32 mode
+	mrs	r0, cpsr
+	bic	r0, r0, #MODE_MASK
+	orr	r0, r0, #SVC_MODE
+	msr	spsr_cxsf, r0
 
-	and	lr, lr, #15
+	@
+	@ the branch table must immediately follow this code
+	@
+	mov	r0, sp
+	and	lr, lr, #0x0f
 	ldr	lr, [pc, lr, lsl #2]
-	movs	pc, lr				@ Changes mode and branches
+	movs	pc, lr			@ branch to handler in SVC mode
 	.endm
 
 	.globl	__stubs_start
@@ -771,7 +822,7 @@ __stubs_start:
 /*
  * Interrupt dispatcher
  */
-	vector_stub	irq, irq, 4
+	vector_stub	irq, 4
 
 	.long	__irq_usr			@  0  (USR_26 / USR_32)
 	.long	__irq_invalid			@  1  (FIQ_26 / FIQ_32)
@@ -794,7 +845,7 @@ __stubs_start:
  * Data abort dispatcher
  * Enter in ABT mode, spsr = USR CPSR, lr = USR PC
  */
-	vector_stub	dabt, abt, 8
+	vector_stub	dabt, 8
 
 	.long	__dabt_usr			@  0  (USR_26 / USR_32)
 	.long	__dabt_invalid			@  1  (FIQ_26 / FIQ_32)
@@ -817,7 +868,7 @@ __stubs_start:
  * Prefetch abort dispatcher
  * Enter in ABT mode, spsr = USR CPSR, lr = USR PC
  */
-	vector_stub	pabt, abt, 4
+	vector_stub	pabt, 4
 
 	.long	__pabt_usr			@  0 (USR_26 / USR_32)
 	.long	__pabt_invalid			@  1 (FIQ_26 / FIQ_32)
@@ -840,7 +891,7 @@ __stubs_start:
  * Undef instr entry dispatcher
  * Enter in UND mode, spsr = SVC/USR CPSR, lr = SVC/USR PC
  */
-	vector_stub	und, und
+	vector_stub	und
 
 	.long	__und_usr			@  0 (USR_26 / USR_32)
 	.long	__und_invalid			@  1 (FIQ_26 / FIQ_32)
@@ -894,13 +945,6 @@ vector_addrexcptn:
 .LCvswi:
 	.word	vector_swi
 
-.LCsirq:
-	.word	__temp_irq
-.LCsund:
-	.word	__temp_und
-.LCsabt:
-	.word	__temp_abt
-
 	.globl	__stubs_end
 __stubs_end:
 
@@ -922,23 +966,6 @@ __vectors_end:
 
 	.data
 
-/*
- * Do not reorder these, and do not insert extra data between...
- */
-
-__temp_irq:
-	.word	0				@ saved lr_irq
-	.word	0				@ saved spsr_irq
-	.word	-1				@ old_r0
-__temp_und:
-	.word	0				@ Saved lr_und
-	.word	0				@ Saved spsr_und
-	.word	-1				@ old_r0
-__temp_abt:
-	.word	0				@ Saved lr_abt
-	.word	0				@ Saved spsr_abt
-	.word	-1				@ old_r0
-
 	.globl	cr_alignment
 	.globl	cr_no_alignment
 cr_alignment:
diff --git a/arch/arm/kernel/entry-header.S b/arch/arm/kernel/entry-header.S
--- a/arch/arm/kernel/entry-header.S
+++ b/arch/arm/kernel/entry-header.S
@@ -59,11 +59,10 @@
 	mov	\rd, \rd, lsl #13
 	.endm
 
-	.macro	alignment_trap, rbase, rtemp, sym
+	.macro	alignment_trap, rtemp
 #ifdef CONFIG_ALIGNMENT_TRAP
-#define OFF_CR_ALIGNMENT(x)	cr_alignment - x
-
-	ldr	\rtemp, [\rbase, #OFF_CR_ALIGNMENT(\sym)]
+	ldr	\rtemp, .LCcralign
+	ldr	\rtemp, [\rtemp]
 	mcr	p15, 0, \rtemp, c1, c0
 #endif
 	.endm
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -2,6 +2,8 @@
  *  linux/arch/arm/kernel/head.S
  *
  *  Copyright (C) 1994-2002 Russell King
+ *  Copyright (c) 2003 ARM Limited
+ *  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 version 2 as
@@ -165,6 +167,48 @@ __mmap_switched:
 	stmia	r6, {r0, r4}			@ Save control register values
 	b	start_kernel
 
+#if defined(CONFIG_SMP)
+	.type   secondary_startup, #function
+ENTRY(secondary_startup)
+	/*
+	 * Common entry point for secondary CPUs.
+	 *
+	 * Ensure that we're in SVC mode, and IRQs are disabled.  Lookup
+	 * the processor type - there is no need to check the machine type
+	 * as it has already been validated by the primary processor.
+	 */
+	msr	cpsr_c, #PSR_F_BIT | PSR_I_BIT | MODE_SVC
+	bl	__lookup_processor_type
+	movs	r10, r5				@ invalid processor?
+	moveq	r0, #'p'			@ yes, error 'p'
+	beq	__error
+
+	/*
+	 * Use the page tables supplied from  __cpu_up.
+	 */
+	adr	r4, __secondary_data
+	ldmia	r4, {r5, r6, r13}		@ address to jump to after
+	sub	r4, r4, r5			@ mmu has been enabled
+	ldr	r4, [r6, r4]			@ get secondary_data.pgdir
+	adr	lr, __enable_mmu		@ return address
+	add	pc, r10, #12			@ initialise processor
+						@ (return control reg)
+
+	/*
+	 * r6  = &secondary_data
+	 */
+ENTRY(__secondary_switched)
+	ldr	sp, [r6, #4]			@ get secondary_data.stack
+	mov	fp, #0
+	b	secondary_start_kernel
+
+	.type	__secondary_data, %object
+__secondary_data:
+	.long	.
+	.long	secondary_data
+	.long	__secondary_switched
+#endif /* defined(CONFIG_SMP) */
+
 
 
 /*
@@ -300,9 +344,9 @@ __create_page_tables:
 	str	r6, [r0]
 #endif
 
+#ifdef CONFIG_DEBUG_LL
 	bic	r7, r7, #0x0c			@ turn off cacheable
 						@ and bufferable bits
-#ifdef CONFIG_DEBUG_LL
 	/*
 	 * Map in IO space for serial debugging.
 	 * This allows debug messages to be output
@@ -328,28 +372,24 @@ __create_page_tables:
 	teq	r1, #MACH_TYPE_NETWINDER
 	teqne	r1, #MACH_TYPE_CATS
 	bne	1f
-	add	r0, r4, #0x3fc0			@ ff000000
-	mov	r3, #0x7c000000
-	orr	r3, r3, r7
-	str	r3, [r0], #4
-	add	r3, r3, #1 << 20
-	str	r3, [r0], #4
+	add	r0, r4, #0xff000000 >> 18
+	orr	r3, r7, #0x7c000000
+	str	r3, [r0]
 1:
 #endif
-#endif
 #ifdef CONFIG_ARCH_RPC
 	/*
 	 * Map in screen at 0x02000000 & SCREEN2_BASE
 	 * Similar reasons here - for debug.  This is
 	 * only for Acorn RiscPC architectures.
 	 */
-	add	r0, r4, #0x80			@ 02000000
-	mov	r3, #0x02000000
-	orr	r3, r3, r7
+	add	r0, r4, #0x02000000 >> 18
+	orr	r3, r7, #0x02000000
 	str	r3, [r0]
-	add	r0, r4, #0x3600			@ d8000000
+	add	r0, r4, #0xd8000000 >> 18
 	str	r3, [r0]
 #endif
+#endif
 	mov	pc, lr
 	.ltorg
 
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
--- a/arch/arm/kernel/irq.c
+++ b/arch/arm/kernel/irq.c
@@ -4,6 +4,10 @@
  *  Copyright (C) 1992 Linus Torvalds
  *  Modifications for ARM processor Copyright (C) 1995-2000 Russell King.
  *
+ *  Support for Dynamic Tick Timer Copyright (C) 2004-2005 Nokia Corporation.
+ *  Dynamic Tick Timer written by Tony Lindgren <tony@atomide.com> and
+ *  Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>.
+ *
  * 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.
@@ -37,6 +41,7 @@
 #include <asm/irq.h>
 #include <asm/system.h>
 #include <asm/mach/irq.h>
+#include <asm/mach/time.h>
 
 /*
  * Maximum IRQ count.  Currently, this is arbitary.  However, it should
@@ -329,6 +334,15 @@ __do_irq(unsigned int irq, struct irqact
 
 	spin_unlock(&irq_controller_lock);
 
+#ifdef CONFIG_NO_IDLE_HZ
+	if (!(action->flags & SA_TIMER) && system_timer->dyn_tick != NULL) {
+		write_seqlock(&xtime_lock);
+		if (system_timer->dyn_tick->state & DYN_TICK_ENABLED)
+			system_timer->dyn_tick->handler(irq, 0, regs);
+		write_sequnlock(&xtime_lock);
+	}
+#endif
+
 	if (!(action->flags & SA_INTERRUPT))
 		local_irq_enable();
 
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -32,6 +32,7 @@
 #include <asm/leds.h>
 #include <asm/processor.h>
 #include <asm/uaccess.h>
+#include <asm/mach/time.h>
 
 extern const char *processor_modes[];
 extern void setup_mm_for_reboot(char mode);
@@ -85,8 +86,10 @@ EXPORT_SYMBOL(pm_power_off);
 void default_idle(void)
 {
 	local_irq_disable();
-	if (!need_resched() && !hlt_counter)
+	if (!need_resched() && !hlt_counter) {
+		timer_dyn_reprogram();
 		arch_idle();
+	}
 	local_irq_enable();
 }
 
@@ -128,7 +131,6 @@ void machine_halt(void)
 {
 }
 
-EXPORT_SYMBOL(machine_halt);
 
 void machine_power_off(void)
 {
@@ -136,7 +138,6 @@ void machine_power_off(void)
 		pm_power_off();
 }
 
-EXPORT_SYMBOL(machine_power_off);
 
 void machine_restart(char * __unused)
 {
@@ -166,8 +167,6 @@ void machine_restart(char * __unused)
 	while (1);
 }
 
-EXPORT_SYMBOL(machine_restart);
-
 void __show_regs(struct pt_regs *regs)
 {
 	unsigned long flags = condition_codes(regs);
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -92,6 +92,14 @@ struct cpu_user_fns cpu_user;
 struct cpu_cache_fns cpu_cache;
 #endif
 
+struct stack {
+	u32 irq[3];
+	u32 abt[3];
+	u32 und[3];
+} ____cacheline_aligned;
+
+static struct stack stacks[NR_CPUS];
+
 char elf_platform[ELF_PLATFORM_SIZE];
 EXPORT_SYMBOL(elf_platform);
 
@@ -307,8 +315,6 @@ static void __init setup_processor(void)
 	       cpu_name, processor_id, (int)processor_id & 15,
 	       proc_arch[cpu_architecture()]);
 
-	dump_cpu_info(smp_processor_id());
-
 	sprintf(system_utsname.machine, "%s%c", list->arch_name, ENDIANNESS);
 	sprintf(elf_platform, "%s%c", list->elf_name, ENDIANNESS);
 	elf_hwcap = list->elf_hwcap;
@@ -316,6 +322,47 @@ static void __init setup_processor(void)
 	cpu_proc_init();
 }
 
+/*
+ * cpu_init - initialise one CPU.
+ *
+ * cpu_init dumps the cache information, initialises SMP specific
+ * information, and sets up the per-CPU stacks.
+ */
+void cpu_init(void)
+{
+	unsigned int cpu = smp_processor_id();
+	struct stack *stk = &stacks[cpu];
+
+	if (cpu >= NR_CPUS) {
+		printk(KERN_CRIT "CPU%u: bad primary CPU number\n", cpu);
+		BUG();
+	}
+
+	dump_cpu_info(cpu);
+
+	/*
+	 * setup stacks for re-entrant exception handlers
+	 */
+	__asm__ (
+	"msr	cpsr_c, %1\n\t"
+	"add	sp, %0, %2\n\t"
+	"msr	cpsr_c, %3\n\t"
+	"add	sp, %0, %4\n\t"
+	"msr	cpsr_c, %5\n\t"
+	"add	sp, %0, %6\n\t"
+	"msr	cpsr_c, %7"
+	    :
+	    : "r" (stk),
+	      "I" (PSR_F_BIT | PSR_I_BIT | IRQ_MODE),
+	      "I" (offsetof(struct stack, irq[0])),
+	      "I" (PSR_F_BIT | PSR_I_BIT | ABT_MODE),
+	      "I" (offsetof(struct stack, abt[0])),
+	      "I" (PSR_F_BIT | PSR_I_BIT | UND_MODE),
+	      "I" (offsetof(struct stack, und[0])),
+	      "I" (PSR_F_BIT | PSR_I_BIT | SVC_MODE)
+	    : "r14");
+}
+
 static struct machine_desc * __init setup_machine(unsigned int nr)
 {
 	struct machine_desc *list;
@@ -349,6 +396,20 @@ static void __init early_initrd(char **p
 }
 __early_param("initrd=", early_initrd);
 
+static void __init add_memory(unsigned long start, unsigned long size)
+{
+	/*
+	 * Ensure that start/size are aligned to a page boundary.
+	 * Size is appropriately rounded down, start is rounded up.
+	 */
+	size -= start & ~PAGE_MASK;
+
+	meminfo.bank[meminfo.nr_banks].start = PAGE_ALIGN(start);
+	meminfo.bank[meminfo.nr_banks].size  = size & PAGE_MASK;
+	meminfo.bank[meminfo.nr_banks].node  = PHYS_TO_NID(start);
+	meminfo.nr_banks += 1;
+}
+
 /*
  * Pick out the memory size.  We look for mem=size@start,
  * where start and size are "size[KkMm]"
@@ -373,10 +434,7 @@ static void __init early_mem(char **p)
 	if (**p == '@')
 		start = memparse(*p + 1, p);
 
-	meminfo.bank[meminfo.nr_banks].start = start;
-	meminfo.bank[meminfo.nr_banks].size  = size;
-	meminfo.bank[meminfo.nr_banks].node  = PHYS_TO_NID(start);
-	meminfo.nr_banks += 1;
+	add_memory(start, size);
 }
 __early_param("mem=", early_mem);
 
@@ -518,11 +576,7 @@ static int __init parse_tag_mem32(const 
 			tag->u.mem.start, tag->u.mem.size / 1024);
 		return -EINVAL;
 	}
-	meminfo.bank[meminfo.nr_banks].start = tag->u.mem.start;
-	meminfo.bank[meminfo.nr_banks].size  = tag->u.mem.size;
-	meminfo.bank[meminfo.nr_banks].node  = PHYS_TO_NID(tag->u.mem.start);
-	meminfo.nr_banks += 1;
-
+	add_memory(tag->u.mem.start, tag->u.mem.size);
 	return 0;
 }
 
@@ -683,8 +737,8 @@ void __init setup_arch(char **cmdline_p)
 	if (mdesc->soft_reboot)
 		reboot_setup("s");
 
-	if (mdesc->param_offset)
-		tags = phys_to_virt(mdesc->param_offset);
+	if (mdesc->boot_params)
+		tags = phys_to_virt(mdesc->boot_params);
 
 	/*
 	 * If we have the old style parameters, convert them to
@@ -715,6 +769,8 @@ void __init setup_arch(char **cmdline_p)
 	paging_init(&meminfo, mdesc);
 	request_standard_resources(&meminfo, mdesc);
 
+	cpu_init();
+
 	/*
 	 * Set up various architecture-specific pointers
 	 */
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
--- a/arch/arm/kernel/signal.c
+++ b/arch/arm/kernel/signal.c
@@ -19,6 +19,7 @@
 #include <asm/unistd.h>
 
 #include "ptrace.h"
+#include "signal.h"
 
 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
 
@@ -35,7 +36,7 @@
 #define SWI_THUMB_SIGRETURN	(0xdf00 << 16 | 0x2700 | (__NR_sigreturn - __NR_SYSCALL_BASE))
 #define SWI_THUMB_RT_SIGRETURN	(0xdf00 << 16 | 0x2700 | (__NR_rt_sigreturn - __NR_SYSCALL_BASE))
 
-static const unsigned long retcodes[4] = {
+const unsigned long sigreturn_codes[4] = {
 	SWI_SYS_SIGRETURN,	SWI_THUMB_SIGRETURN,
 	SWI_SYS_RT_SIGRETURN,	SWI_THUMB_RT_SIGRETURN
 };
@@ -500,17 +501,25 @@ setup_return(struct pt_regs *regs, struc
 		if (ka->sa.sa_flags & SA_SIGINFO)
 			idx += 2;
 
-		if (__put_user(retcodes[idx], rc))
+		if (__put_user(sigreturn_codes[idx], rc))
 			return 1;
 
-		/*
-		 * Ensure that the instruction cache sees
-		 * the return code written onto the stack.
-		 */
-		flush_icache_range((unsigned long)rc,
-				   (unsigned long)(rc + 1));
+		if (cpsr & MODE32_BIT) {
+			/*
+			 * 32-bit code can use the new high-page
+			 * signal return code support.
+			 */
+			retcode = KERN_SIGRETURN_CODE + (idx << 2) + thumb;
+		} else {
+			/*
+			 * Ensure that the instruction cache sees
+			 * the return code written onto the stack.
+			 */
+			flush_icache_range((unsigned long)rc,
+					   (unsigned long)(rc + 1));
 
-		retcode = ((unsigned long)rc) + thumb;
+			retcode = ((unsigned long)rc) + thumb;
+		}
 	}
 
 	regs->ARM_r0 = usig;
@@ -688,7 +697,7 @@ static int do_signal(sigset_t *oldset, s
 	if (!user_mode(regs))
 		return 0;
 
-	if (try_to_freeze(0))
+	if (try_to_freeze())
 		goto no_signal;
 
 	if (current->ptrace & PT_SINGLESTEP)
diff --git a/arch/arm/kernel/signal.h b/arch/arm/kernel/signal.h
new file mode 100644
--- /dev/null
+++ b/arch/arm/kernel/signal.h
@@ -0,0 +1,12 @@
+/*
+ *  linux/arch/arm/kernel/signal.h
+ *
+ *  Copyright (C) 2005 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#define KERN_SIGRETURN_CODE	0xffff0500
+
+extern const unsigned long sigreturn_codes[4];
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -24,6 +24,9 @@
 #include <asm/atomic.h>
 #include <asm/cacheflush.h>
 #include <asm/cpu.h>
+#include <asm/mmu_context.h>
+#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
 #include <asm/processor.h>
 #include <asm/tlbflush.h>
 #include <asm/ptrace.h>
@@ -33,10 +36,17 @@
  * The present bitmask indicates that the CPU is physically present.
  * The online bitmask indicates that the CPU is up and running.
  */
-cpumask_t cpu_present_mask;
+cpumask_t cpu_possible_map;
 cpumask_t cpu_online_map;
 
 /*
+ * as from 2.5, kernels no longer have an init_tasks structure
+ * so we need some other way of telling a new secondary core
+ * where to place its SVC stack
+ */
+struct secondary_data secondary_data;
+
+/*
  * structures for inter-processor calls
  * - A collection of single bit ipi messages.
  */
@@ -68,9 +78,11 @@ struct smp_call_struct {
 static struct smp_call_struct * volatile smp_call_function_data;
 static DEFINE_SPINLOCK(smp_call_function_lock);
 
-int __init __cpu_up(unsigned int cpu)
+int __cpuinit __cpu_up(unsigned int cpu)
 {
 	struct task_struct *idle;
+	pgd_t *pgd;
+	pmd_t *pmd;
 	int ret;
 
 	/*
@@ -84,11 +96,57 @@ int __init __cpu_up(unsigned int cpu)
 	}
 
 	/*
+	 * Allocate initial page tables to allow the new CPU to
+	 * enable the MMU safely.  This essentially means a set
+	 * of our "standard" page tables, with the addition of
+	 * a 1:1 mapping for the physical address of the kernel.
+	 */
+	pgd = pgd_alloc(&init_mm);
+	pmd = pmd_offset(pgd, PHYS_OFFSET);
+	*pmd = __pmd((PHYS_OFFSET & PGDIR_MASK) |
+		     PMD_TYPE_SECT | PMD_SECT_AP_WRITE);
+
+	/*
+	 * We need to tell the secondary core where to find
+	 * its stack and the page tables.
+	 */
+	secondary_data.stack = (void *)idle->thread_info + THREAD_SIZE - 8;
+	secondary_data.pgdir = virt_to_phys(pgd);
+	wmb();
+
+	/*
 	 * Now bring the CPU into our world.
 	 */
 	ret = boot_secondary(cpu, idle);
+	if (ret == 0) {
+		unsigned long timeout;
+
+		/*
+		 * CPU was successfully started, wait for it
+		 * to come online or time out.
+		 */
+		timeout = jiffies + HZ;
+		while (time_before(jiffies, timeout)) {
+			if (cpu_online(cpu))
+				break;
+
+			udelay(10);
+			barrier();
+		}
+
+		if (!cpu_online(cpu))
+			ret = -EIO;
+	}
+
+	secondary_data.stack = 0;
+	secondary_data.pgdir = 0;
+
+	*pmd_offset(pgd, PHYS_OFFSET) = __pmd(0);
+	pgd_free(pgd);
+
 	if (ret) {
-		printk(KERN_CRIT "cpu_up: processor %d failed to boot\n", cpu);
+		printk(KERN_CRIT "CPU%u: processor failed to boot\n", cpu);
+
 		/*
 		 * FIXME: We need to clean up the new idle thread. --rmk
 		 */
@@ -98,10 +156,61 @@ int __init __cpu_up(unsigned int cpu)
 }
 
 /*
+ * This is the secondary CPU boot entry.  We're using this CPUs
+ * idle thread stack, but a set of temporary page tables.
+ */
+asmlinkage void __cpuinit secondary_start_kernel(void)
+{
+	struct mm_struct *mm = &init_mm;
+	unsigned int cpu = smp_processor_id();
+
+	printk("CPU%u: Booted secondary processor\n", cpu);
+
+	/*
+	 * All kernel threads share the same mm context; grab a
+	 * reference and switch to it.
+	 */
+	atomic_inc(&mm->mm_users);
+	atomic_inc(&mm->mm_count);
+	current->active_mm = mm;
+	cpu_set(cpu, mm->cpu_vm_mask);
+	cpu_switch_mm(mm->pgd, mm);
+	enter_lazy_tlb(mm, current);
+	local_flush_tlb_all();
+
+	cpu_init();
+
+	/*
+	 * Give the platform a chance to do its own initialisation.
+	 */
+	platform_secondary_init(cpu);
+
+	/*
+	 * Enable local interrupts.
+	 */
+	local_irq_enable();
+	local_fiq_enable();
+
+	calibrate_delay();
+
+	smp_store_cpu_info(cpu);
+
+	/*
+	 * OK, now it's safe to let the boot CPU continue
+	 */
+	cpu_set(cpu, cpu_online_map);
+
+	/*
+	 * OK, it's off to the idle thread for us
+	 */
+	cpu_idle();
+}
+
+/*
  * Called by both boot and secondaries to move global data into
  * per-processor storage.
  */
-void __init smp_store_cpu_info(unsigned int cpuid)
+void __cpuinit smp_store_cpu_info(unsigned int cpuid)
 {
 	struct cpuinfo_arm *cpu_info = &per_cpu(cpu_data, cpuid);
 
@@ -127,7 +236,8 @@ void __init smp_prepare_boot_cpu(void)
 {
 	unsigned int cpu = smp_processor_id();
 
-	cpu_set(cpu, cpu_present_mask);
+	cpu_set(cpu, cpu_possible_map);
+	cpu_set(cpu, cpu_present_map);
 	cpu_set(cpu, cpu_online_map);
 }
 
@@ -247,7 +357,7 @@ void show_ipi_list(struct seq_file *p)
 
 	seq_puts(p, "IPI:");
 
-	for_each_online_cpu(cpu)
+	for_each_present_cpu(cpu)
 		seq_printf(p, " %10lu", per_cpu(ipi_data, cpu).ipi_count);
 
 	seq_putc(p, '\n');
@@ -394,3 +504,126 @@ int __init setup_profiling_timer(unsigne
 {
 	return -EINVAL;
 }
+
+static int
+on_each_cpu_mask(void (*func)(void *), void *info, int retry, int wait,
+		 cpumask_t mask)
+{
+	int ret = 0;
+
+	preempt_disable();
+
+	ret = smp_call_function_on_cpu(func, info, retry, wait, mask);
+	if (cpu_isset(smp_processor_id(), mask))
+		func(info);
+
+	preempt_enable();
+
+	return ret;
+}
+
+/**********************************************************************/
+
+/*
+ * TLB operations
+ */
+struct tlb_args {
+	struct vm_area_struct *ta_vma;
+	unsigned long ta_start;
+	unsigned long ta_end;
+};
+
+static inline void ipi_flush_tlb_all(void *ignored)
+{
+	local_flush_tlb_all();
+}
+
+static inline void ipi_flush_tlb_mm(void *arg)
+{
+	struct mm_struct *mm = (struct mm_struct *)arg;
+
+	local_flush_tlb_mm(mm);
+}
+
+static inline void ipi_flush_tlb_page(void *arg)
+{
+	struct tlb_args *ta = (struct tlb_args *)arg;
+
+	local_flush_tlb_page(ta->ta_vma, ta->ta_start);
+}
+
+static inline void ipi_flush_tlb_kernel_page(void *arg)
+{
+	struct tlb_args *ta = (struct tlb_args *)arg;
+
+	local_flush_tlb_kernel_page(ta->ta_start);
+}
+
+static inline void ipi_flush_tlb_range(void *arg)
+{
+	struct tlb_args *ta = (struct tlb_args *)arg;
+
+	local_flush_tlb_range(ta->ta_vma, ta->ta_start, ta->ta_end);
+}
+
+static inline void ipi_flush_tlb_kernel_range(void *arg)
+{
+	struct tlb_args *ta = (struct tlb_args *)arg;
+
+	local_flush_tlb_kernel_range(ta->ta_start, ta->ta_end);
+}
+
+void flush_tlb_all(void)
+{
+	on_each_cpu(ipi_flush_tlb_all, NULL, 1, 1);
+}
+
+void flush_tlb_mm(struct mm_struct *mm)
+{
+	cpumask_t mask = mm->cpu_vm_mask;
+
+	on_each_cpu_mask(ipi_flush_tlb_mm, mm, 1, 1, mask);
+}
+
+void flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr)
+{
+	cpumask_t mask = vma->vm_mm->cpu_vm_mask;
+	struct tlb_args ta;
+
+	ta.ta_vma = vma;
+	ta.ta_start = uaddr;
+
+	on_each_cpu_mask(ipi_flush_tlb_page, &ta, 1, 1, mask);
+}
+
+void flush_tlb_kernel_page(unsigned long kaddr)
+{
+	struct tlb_args ta;
+
+	ta.ta_start = kaddr;
+
+	on_each_cpu(ipi_flush_tlb_kernel_page, &ta, 1, 1);
+}
+
+void flush_tlb_range(struct vm_area_struct *vma,
+                     unsigned long start, unsigned long end)
+{
+	cpumask_t mask = vma->vm_mm->cpu_vm_mask;
+	struct tlb_args ta;
+
+	ta.ta_vma = vma;
+	ta.ta_start = start;
+	ta.ta_end = end;
+
+	on_each_cpu_mask(ipi_flush_tlb_range, &ta, 1, 1, mask);
+}
+
+void flush_tlb_kernel_range(unsigned long start, unsigned long end)
+{
+	struct tlb_args ta;
+
+	ta.ta_start = start;
+	ta.ta_end = end;
+
+	on_each_cpu(ipi_flush_tlb_kernel_range, &ta, 1, 1);
+}
diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c
--- a/arch/arm/kernel/time.c
+++ b/arch/arm/kernel/time.c
@@ -381,6 +381,99 @@ static struct sysdev_class timer_sysclas
 	.resume		= timer_resume,
 };
 
+#ifdef CONFIG_NO_IDLE_HZ
+static int timer_dyn_tick_enable(void)
+{
+	struct dyn_tick_timer *dyn_tick = system_timer->dyn_tick;
+	unsigned long flags;
+	int ret = -ENODEV;
+
+	if (dyn_tick) {
+		write_seqlock_irqsave(&xtime_lock, flags);
+		ret = 0;
+		if (!(dyn_tick->state & DYN_TICK_ENABLED)) {
+			ret = dyn_tick->enable();
+
+			if (ret == 0)
+				dyn_tick->state |= DYN_TICK_ENABLED;
+		}
+		write_sequnlock_irqrestore(&xtime_lock, flags);
+	}
+
+	return ret;
+}
+
+static int timer_dyn_tick_disable(void)
+{
+	struct dyn_tick_timer *dyn_tick = system_timer->dyn_tick;
+	unsigned long flags;
+	int ret = -ENODEV;
+
+	if (dyn_tick) {
+		write_seqlock_irqsave(&xtime_lock, flags);
+		ret = 0;
+		if (dyn_tick->state & DYN_TICK_ENABLED) {
+			ret = dyn_tick->disable();
+
+			if (ret == 0)
+				dyn_tick->state &= ~DYN_TICK_ENABLED;
+		}
+		write_sequnlock_irqrestore(&xtime_lock, flags);
+	}
+
+	return ret;
+}
+
+/*
+ * Reprogram the system timer for at least the calculated time interval.
+ * This function should be called from the idle thread with IRQs disabled,
+ * immediately before sleeping.
+ */
+void timer_dyn_reprogram(void)
+{
+	struct dyn_tick_timer *dyn_tick = system_timer->dyn_tick;
+
+	write_seqlock(&xtime_lock);
+	if (dyn_tick->state & DYN_TICK_ENABLED)
+		dyn_tick->reprogram(next_timer_interrupt() - jiffies);
+	write_sequnlock(&xtime_lock);
+}
+
+static ssize_t timer_show_dyn_tick(struct sys_device *dev, char *buf)
+{
+	return sprintf(buf, "%i\n",
+		       (system_timer->dyn_tick->state & DYN_TICK_ENABLED) >> 1);
+}
+
+static ssize_t timer_set_dyn_tick(struct sys_device *dev, const char *buf,
+				  size_t count)
+{
+	unsigned int enable = simple_strtoul(buf, NULL, 2);
+
+	if (enable)
+		timer_dyn_tick_enable();
+	else
+		timer_dyn_tick_disable();
+
+	return count;
+}
+static SYSDEV_ATTR(dyn_tick, 0644, timer_show_dyn_tick, timer_set_dyn_tick);
+
+/*
+ * dyntick=enable|disable
+ */
+static char dyntick_str[4] __initdata = "";
+
+static int __init dyntick_setup(char *str)
+{
+	if (str)
+		strlcpy(dyntick_str, str, sizeof(dyntick_str));
+	return 1;
+}
+
+__setup("dyntick=", dyntick_setup);
+#endif
+
 static int __init timer_init_sysfs(void)
 {
 	int ret = sysdev_class_register(&timer_sysclass);
@@ -388,6 +481,20 @@ static int __init timer_init_sysfs(void)
 		system_timer->dev.cls = &timer_sysclass;
 		ret = sysdev_register(&system_timer->dev);
 	}
+
+#ifdef CONFIG_NO_IDLE_HZ
+	if (ret == 0 && system_timer->dyn_tick) {
+		ret = sysdev_create_file(&system_timer->dev, &attr_dyn_tick);
+
+		/*
+		 * Turn on dynamic tick after calibrate delay
+		 * for correct bogomips
+		 */
+		if (ret == 0 && dyntick_str[0] == 'e')
+			ret = timer_dyn_tick_enable();
+	}
+#endif
+
 	return ret;
 }
 
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -30,6 +30,7 @@
 #include <asm/traps.h>
 
 #include "ptrace.h"
+#include "signal.h"
 
 const char *processor_modes[]=
 { "USER_26", "FIQ_26" , "IRQ_26" , "SVC_26" , "UK4_26" , "UK5_26" , "UK6_26" , "UK7_26" ,
@@ -229,16 +230,8 @@ NORET_TYPE void die(const char *str, str
 	do_exit(SIGSEGV);
 }
 
-void die_if_kernel(const char *str, struct pt_regs *regs, int err)
-{
-	if (user_mode(regs))
-    		return;
-
-    	die(str, regs, err);
-}
-
-static void notify_die(const char *str, struct pt_regs *regs, siginfo_t *info,
-		       unsigned long err, unsigned long trap)
+void notify_die(const char *str, struct pt_regs *regs, struct siginfo *info,
+		unsigned long err, unsigned long trap)
 {
 	if (user_mode(regs)) {
 		current->thread.error_code = err;
@@ -255,16 +248,20 @@ static DEFINE_SPINLOCK(undef_lock);
 
 void register_undef_hook(struct undef_hook *hook)
 {
-	spin_lock_irq(&undef_lock);
+	unsigned long flags;
+
+	spin_lock_irqsave(&undef_lock, flags);
 	list_add(&hook->node, &undef_hook);
-	spin_unlock_irq(&undef_lock);
+	spin_unlock_irqrestore(&undef_lock, flags);
 }
 
 void unregister_undef_hook(struct undef_hook *hook)
 {
-	spin_lock_irq(&undef_lock);
+	unsigned long flags;
+
+	spin_lock_irqsave(&undef_lock, flags);
 	list_del(&hook->node);
-	spin_unlock_irq(&undef_lock);
+	spin_unlock_irqrestore(&undef_lock, flags);
 }
 
 asmlinkage void do_undefinstr(struct pt_regs *regs)
@@ -620,7 +617,7 @@ baddataabort(int code, unsigned long ins
 	notify_die("unknown data abort code", regs, &info, instr, 0);
 }
 
-volatile void __bug(const char *file, int line, void *data)
+void __attribute__((noreturn)) __bug(const char *file, int line, void *data)
 {
 	printk(KERN_CRIT"kernel BUG at %s:%d!", file, line);
 	if (data)
@@ -683,6 +680,14 @@ void __init trap_init(void)
 	memcpy((void *)0xffff0000, __vectors_start, __vectors_end - __vectors_start);
 	memcpy((void *)0xffff0200, __stubs_start, __stubs_end - __stubs_start);
 	memcpy((void *)0xffff1000 - kuser_sz, __kuser_helper_start, kuser_sz);
+
+	/*
+	 * Copy signal return handlers into the vector page, and
+	 * set sigreturn to be a pointer to these.
+	 */
+	memcpy((void *)KERN_SIGRETURN_CODE, sigreturn_codes,
+	       sizeof(sigreturn_codes));
+
 	flush_icache_range(0xffff0000, 0xffff0000 + PAGE_SIZE);
 	modify_domain(DOMAIN_USER, DOMAIN_CLIENT);
 }
diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile
--- a/arch/arm/lib/Makefile
+++ b/arch/arm/lib/Makefile
@@ -11,7 +11,7 @@ lib-y		:= backtrace.o changebit.o csumip
 		   strnlen_user.o strchr.o strrchr.o testchangebit.o  \
 		   testclearbit.o testsetbit.o uaccess.o getuser.o    \
 		   putuser.o ashldi3.o ashrdi3.o lshrdi3.o muldi3.o   \
-		   ucmpdi2.o udivdi3.o lib1funcs.o div64.o	      \
+		   ucmpdi2.o lib1funcs.o div64.o	              \
 		   io-readsb.o io-writesb.o io-readsl.o io-writesl.o
 
 ifeq ($(CONFIG_CPU_32v3),y)
diff --git a/arch/arm/lib/ashldi3.c b/arch/arm/lib/ashldi3.c
--- a/arch/arm/lib/ashldi3.c
+++ b/arch/arm/lib/ashldi3.c
@@ -31,31 +31,26 @@ Boston, MA 02111-1307, USA.  */
 
 #include "gcclib.h"
 
-DItype
-__ashldi3 (DItype u, word_type b)
+s64 __ashldi3(s64 u, int b)
 {
-  DIunion w;
-  word_type bm;
-  DIunion uu;
-
-  if (b == 0)
-    return u;
-
-  uu.ll = u;
-
-  bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
-  if (bm <= 0)
-    {
-      w.s.low = 0;
-      w.s.high = (USItype)uu.s.low << -bm;
-    }
-  else
-    {
-      USItype carries = (USItype)uu.s.low >> bm;
-      w.s.low = (USItype)uu.s.low << b;
-      w.s.high = ((USItype)uu.s.high << b) | carries;
-    }
+	DIunion w;
+	int bm;
+	DIunion uu;
+
+	if (b == 0)
+		return u;
+
+	uu.ll = u;
+
+	bm = (sizeof(s32) * BITS_PER_UNIT) - b;
+	if (bm <= 0) {
+		w.s.low = 0;
+		w.s.high = (u32) uu.s.low << -bm;
+	} else {
+		u32 carries = (u32) uu.s.low >> bm;
+		w.s.low = (u32) uu.s.low << b;
+		w.s.high = ((u32) uu.s.high << b) | carries;
+	}
 
-  return w.ll;
+	return w.ll;
 }
-
diff --git a/arch/arm/lib/ashrdi3.c b/arch/arm/lib/ashrdi3.c
--- a/arch/arm/lib/ashrdi3.c
+++ b/arch/arm/lib/ashrdi3.c
@@ -31,31 +31,27 @@ Boston, MA 02111-1307, USA.  */
 
 #include "gcclib.h"
 
-DItype
-__ashrdi3 (DItype u, word_type b)
+s64 __ashrdi3(s64 u, int b)
 {
-  DIunion w;
-  word_type bm;
-  DIunion uu;
-
-  if (b == 0)
-    return u;
-
-  uu.ll = u;
-
-  bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
-  if (bm <= 0)
-    {
-      /* w.s.high = 1..1 or 0..0 */
-      w.s.high = uu.s.high >> (sizeof (SItype) * BITS_PER_UNIT - 1);
-      w.s.low = uu.s.high >> -bm;
-    }
-  else
-    {
-      USItype carries = (USItype)uu.s.high << bm;
-      w.s.high = uu.s.high >> b;
-      w.s.low = ((USItype)uu.s.low >> b) | carries;
-    }
+	DIunion w;
+	int bm;
+	DIunion uu;
+
+	if (b == 0)
+		return u;
+
+	uu.ll = u;
+
+	bm = (sizeof(s32) * BITS_PER_UNIT) - b;
+	if (bm <= 0) {
+		/* w.s.high = 1..1 or 0..0 */
+		w.s.high = uu.s.high >> (sizeof(s32) * BITS_PER_UNIT - 1);
+		w.s.low = uu.s.high >> -bm;
+	} else {
+		u32 carries = (u32) uu.s.high << bm;
+		w.s.high = uu.s.high >> b;
+		w.s.low = ((u32) uu.s.low >> b) | carries;
+	}
 
-  return w.ll;
+	return w.ll;
 }
diff --git a/arch/arm/lib/bitops.h b/arch/arm/lib/bitops.h
--- a/arch/arm/lib/bitops.h
+++ b/arch/arm/lib/bitops.h
@@ -1,3 +1,35 @@
+#include <linux/config.h>
+
+#if __LINUX_ARM_ARCH__ >= 6 && defined(CONFIG_CPU_MPCORE)
+	.macro	bitop, instr
+	mov	r2, #1
+	and	r3, r0, #7		@ Get bit offset
+	add	r1, r1, r0, lsr #3	@ Get byte offset
+	mov	r3, r2, lsl r3
+1:	ldrexb	r2, [r1]
+	\instr	r2, r2, r3
+	strexb	r0, r2, [r1]
+	cmp	r0, #0
+	bne	1b
+	mov	pc, lr
+	.endm
+
+	.macro	testop, instr, store
+	and	r3, r0, #7		@ Get bit offset
+	mov	r2, #1
+	add	r1, r1, r0, lsr #3	@ Get byte offset
+	mov	r3, r2, lsl r3		@ create mask
+1:	ldrexb	r2, [r1]
+	ands	r0, r2, r3		@ save old value of bit
+	\instr	r2, r2, r3			@ toggle bit
+	strexb	ip, r2, [r1]
+	cmp	ip, #0
+	bne	1b
+	cmp	r0, #0
+	movne	r0, #1
+2:	mov	pc, lr
+	.endm
+#else
 	.macro	bitop, instr
 	and	r2, r0, #7
 	mov	r3, #1
@@ -31,3 +63,4 @@
 	moveq	r0, #0
 	mov	pc, lr
 	.endm
+#endif
diff --git a/arch/arm/lib/gcclib.h b/arch/arm/lib/gcclib.h
--- a/arch/arm/lib/gcclib.h
+++ b/arch/arm/lib/gcclib.h
@@ -1,25 +1,22 @@
 /* gcclib.h -- definitions for various functions 'borrowed' from gcc-2.95.3 */
 /* I Molton     29/07/01 */
 
-#define BITS_PER_UNIT  8
-#define SI_TYPE_SIZE (sizeof (SItype) * BITS_PER_UNIT)
+#include <linux/types.h>
 
-typedef unsigned int UQItype    __attribute__ ((mode (QI)));
-typedef          int SItype     __attribute__ ((mode (SI)));
-typedef unsigned int USItype    __attribute__ ((mode (SI)));
-typedef          int DItype     __attribute__ ((mode (DI)));
-typedef          int word_type 	__attribute__ ((mode (__word__)));
-typedef unsigned int UDItype    __attribute__ ((mode (DI)));
+#define BITS_PER_UNIT	8
+#define SI_TYPE_SIZE	(sizeof(s32) * BITS_PER_UNIT)
 
 #ifdef __ARMEB__
-  struct DIstruct {SItype high, low;};
+struct DIstruct {
+	s32 high, low;
+};
 #else
-  struct DIstruct {SItype low, high;};
+struct DIstruct {
+	s32 low, high;
+};
 #endif
 
-typedef union
-{
-  struct DIstruct s;
-  DItype ll;
+typedef union {
+	struct DIstruct s;
+	s64 ll;
 } DIunion;
-
diff --git a/arch/arm/lib/io-shark.c b/arch/arm/lib/io-shark.c
--- a/arch/arm/lib/io-shark.c
+++ b/arch/arm/lib/io-shark.c
@@ -11,73 +11,3 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-#include <linux/kernel.h>
-
-#include <asm/io.h>
-
-void print_warning(void)
-{
-	printk(KERN_WARNING "ins?/outs? not implemented on this architecture\n");
-}
-
-void insl(unsigned int port, void *to, int len)
-{
-	print_warning();
-}
-
-void insb(unsigned int port, void *to, int len)
-{
-	print_warning();
-}
-
-void outsl(unsigned int port, const void *from, int len)
-{
-	print_warning();
-}
-
-void outsb(unsigned int port, const void *from, int len)
-{
-	print_warning();
-}
-
-/* these should be in assembler again */
-
-/*
- * Purpose: read a block of data from a hardware register to memory.
- * Proto  : insw(int from_port, void *to, int len_in_words);
- * Proto  : inswb(int from_port, void *to, int len_in_bytes);
- * Notes  : increment to
- */
-
-void insw(unsigned int port, void *to, int len)
-{
-	int i;
-
-	for (i = 0; i < len; i++)
-		((unsigned short *) to)[i] = inw(port);
-}
-
-void inswb(unsigned int port, void *to, int len)
-{
-	insw(port, to, len >> 2);
-}
-
-/*
- * Purpose: write a block of data from memory to a hardware register.
- * Proto  : outsw(int to_reg, void *from, int len_in_words);
- * Proto  : outswb(int to_reg, void *from, int len_in_bytes);
- * Notes  : increments from
- */
-
-void outsw(unsigned int port, const void *from, int len)
-{
-	int i;
-
-	for (i = 0; i < len; i++)
-		outw(((unsigned short *) from)[i], port);
-}
-
-void outswb(unsigned int port, const void *from, int len)
-{
-	outsw(port, from, len >> 2);
-}
diff --git a/arch/arm/lib/longlong.h b/arch/arm/lib/longlong.h
deleted file mode 100644
--- a/arch/arm/lib/longlong.h
+++ /dev/null
@@ -1,183 +0,0 @@
-/* longlong.h -- based on code from gcc-2.95.3
-
-   definitions for mixed size 32/64 bit arithmetic.
-   Copyright (C) 1991, 92, 94, 95, 96, 1997, 1998 Free Software Foundation, Inc.
-
-   This definition file 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 definition file 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.  */
-
-/* Borrowed from GCC 2.95.3, I Molton 29/07/01 */
-
-#ifndef SI_TYPE_SIZE
-#define SI_TYPE_SIZE 32
-#endif
-
-#define __BITS4 (SI_TYPE_SIZE / 4)
-#define __ll_B (1L << (SI_TYPE_SIZE / 2))
-#define __ll_lowpart(t) ((USItype) (t) % __ll_B)
-#define __ll_highpart(t) ((USItype) (t) / __ll_B)
-
-/* Define auxiliary asm macros.
-
-   1) umul_ppmm(high_prod, low_prod, multipler, multiplicand)
-   multiplies two USItype integers MULTIPLER and MULTIPLICAND,
-   and generates a two-part USItype product in HIGH_PROD and
-   LOW_PROD.
-
-   2) __umulsidi3(a,b) multiplies two USItype integers A and B,
-   and returns a UDItype product.  This is just a variant of umul_ppmm.
-
-   3) udiv_qrnnd(quotient, remainder, high_numerator, low_numerator,
-   denominator) divides a two-word unsigned integer, composed by the
-   integers HIGH_NUMERATOR and LOW_NUMERATOR, by DENOMINATOR and
-   places the quotient in QUOTIENT and the remainder in REMAINDER.
-   HIGH_NUMERATOR must be less than DENOMINATOR for correct operation.
-   If, in addition, the most significant bit of DENOMINATOR must be 1,
-   then the pre-processor symbol UDIV_NEEDS_NORMALIZATION is defined to 1.
-
-   4) sdiv_qrnnd(quotient, remainder, high_numerator, low_numerator,
-   denominator).  Like udiv_qrnnd but the numbers are signed.  The
-   quotient is rounded towards 0.
-
-   5) count_leading_zeros(count, x) counts the number of zero-bits from
-   the msb to the first non-zero bit.  This is the number of steps X
-   needs to be shifted left to set the msb.  Undefined for X == 0.
-
-   6) add_ssaaaa(high_sum, low_sum, high_addend_1, low_addend_1,
-   high_addend_2, low_addend_2) adds two two-word unsigned integers,
-   composed by HIGH_ADDEND_1 and LOW_ADDEND_1, and HIGH_ADDEND_2 and
-   LOW_ADDEND_2 respectively.  The result is placed in HIGH_SUM and
-   LOW_SUM.  Overflow (i.e. carry out) is not stored anywhere, and is
-   lost.
-
-   7) sub_ddmmss(high_difference, low_difference, high_minuend,
-   low_minuend, high_subtrahend, low_subtrahend) subtracts two
-   two-word unsigned integers, composed by HIGH_MINUEND_1 and
-   LOW_MINUEND_1, and HIGH_SUBTRAHEND_2 and LOW_SUBTRAHEND_2
-   respectively.  The result is placed in HIGH_DIFFERENCE and
-   LOW_DIFFERENCE.  Overflow (i.e. carry out) is not stored anywhere,
-   and is lost.
-
-   If any of these macros are left undefined for a particular CPU,
-   C macros are used.  */
-
-#if defined (__arm__)
-#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
-  __asm__ ("adds	%1, %4, %5					\n\
-	adc	%0, %2, %3"						\
-	   : "=r" ((USItype) (sh)),					\
-	     "=&r" ((USItype) (sl))					\
-	   : "%r" ((USItype) (ah)),					\
-	     "rI" ((USItype) (bh)),					\
-	     "%r" ((USItype) (al)),					\
-	     "rI" ((USItype) (bl)))
-#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
-  __asm__ ("subs	%1, %4, %5					\n\
-	sbc	%0, %2, %3"						\
-	   : "=r" ((USItype) (sh)),					\
-	     "=&r" ((USItype) (sl))					\
-	   : "r" ((USItype) (ah)),					\
-	     "rI" ((USItype) (bh)),					\
-	     "r" ((USItype) (al)),					\
-	     "rI" ((USItype) (bl)))
-#define umul_ppmm(xh, xl, a, b) \
-{register USItype __t0, __t1, __t2;					\
-  __asm__ ("%@ Inlined umul_ppmm					\n\
-	mov	%2, %5, lsr #16						\n\
-	mov	%0, %6, lsr #16						\n\
-	bic	%3, %5, %2, lsl #16					\n\
-	bic	%4, %6, %0, lsl #16					\n\
-	mul	%1, %3, %4						\n\
-	mul	%4, %2, %4						\n\
-	mul	%3, %0, %3						\n\
-	mul	%0, %2, %0						\n\
-	adds	%3, %4, %3						\n\
-	addcs	%0, %0, #65536						\n\
-	adds	%1, %1, %3, lsl #16					\n\
-	adc	%0, %0, %3, lsr #16"					\
-	   : "=&r" ((USItype) (xh)),					\
-	     "=r" ((USItype) (xl)),					\
-	     "=&r" (__t0), "=&r" (__t1), "=r" (__t2)			\
-	   : "r" ((USItype) (a)),					\
-	     "r" ((USItype) (b)));}
-#define UMUL_TIME 20
-#define UDIV_TIME 100
-#endif /* __arm__ */
-
-#define __umulsidi3(u, v) \
-  ({DIunion __w;							\
-    umul_ppmm (__w.s.high, __w.s.low, u, v);				\
-    __w.ll; })
-
-#define __udiv_qrnnd_c(q, r, n1, n0, d) \
-  do {									\
-    USItype __d1, __d0, __q1, __q0;					\
-    USItype __r1, __r0, __m;						\
-    __d1 = __ll_highpart (d);						\
-    __d0 = __ll_lowpart (d);						\
-									\
-    __r1 = (n1) % __d1;							\
-    __q1 = (n1) / __d1;							\
-    __m = (USItype) __q1 * __d0;					\
-    __r1 = __r1 * __ll_B | __ll_highpart (n0);				\
-    if (__r1 < __m)							\
-      {									\
-	__q1--, __r1 += (d);						\
-	if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */\
-	  if (__r1 < __m)						\
-	    __q1--, __r1 += (d);					\
-      }									\
-    __r1 -= __m;							\
-									\
-    __r0 = __r1 % __d1;							\
-    __q0 = __r1 / __d1;							\
-    __m = (USItype) __q0 * __d0;					\
-    __r0 = __r0 * __ll_B | __ll_lowpart (n0);				\
-    if (__r0 < __m)							\
-      {									\
-	__q0--, __r0 += (d);						\
-	if (__r0 >= (d))						\
-	  if (__r0 < __m)						\
-	    __q0--, __r0 += (d);					\
-      }									\
-    __r0 -= __m;							\
-									\
-    (q) = (USItype) __q1 * __ll_B | __q0;				\
-    (r) = __r0;								\
-  } while (0)
-
-#define UDIV_NEEDS_NORMALIZATION 1
-#define udiv_qrnnd __udiv_qrnnd_c
-
-#define count_leading_zeros(count, x) \
-  do {									\
-    USItype __xr = (x);							\
-    USItype __a;							\
-									\
-    if (SI_TYPE_SIZE <= 32)						\
-      {									\
-	__a = __xr < ((USItype)1<<2*__BITS4)				\
-	  ? (__xr < ((USItype)1<<__BITS4) ? 0 : __BITS4)		\
-	  : (__xr < ((USItype)1<<3*__BITS4) ?  2*__BITS4 : 3*__BITS4);	\
-      }									\
-    else								\
-      {									\
-	for (__a = SI_TYPE_SIZE - 8; __a > 0; __a -= 8)			\
-	  if (((__xr >> __a) & 0xff) != 0)				\
-	    break;							\
-      }									\
-									\
-    (count) = SI_TYPE_SIZE - (__clz_tab[__xr >> __a] + __a);		\
-  } while (0)
diff --git a/arch/arm/lib/lshrdi3.c b/arch/arm/lib/lshrdi3.c
--- a/arch/arm/lib/lshrdi3.c
+++ b/arch/arm/lib/lshrdi3.c
@@ -31,31 +31,26 @@ Boston, MA 02111-1307, USA.  */
 
 #include "gcclib.h"
 
-DItype
-__lshrdi3 (DItype u, word_type b)
+s64 __lshrdi3(s64 u, int b)
 {
-  DIunion w;
-  word_type bm;
-  DIunion uu;
-
-  if (b == 0)
-    return u;
-
-  uu.ll = u;
-
-  bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
-  if (bm <= 0)
-    {
-      w.s.high = 0;
-      w.s.low = (USItype)uu.s.high >> -bm;
-    }
-  else
-    {
-      USItype carries = (USItype)uu.s.high << bm;
-      w.s.high = (USItype)uu.s.high >> b;
-      w.s.low = ((USItype)uu.s.low >> b) | carries;
-    }
+	DIunion w;
+	int bm;
+	DIunion uu;
+
+	if (b == 0)
+		return u;
+
+	uu.ll = u;
+
+	bm = (sizeof(s32) * BITS_PER_UNIT) - b;
+	if (bm <= 0) {
+		w.s.high = 0;
+		w.s.low = (u32) uu.s.high >> -bm;
+	} else {
+		u32 carries = (u32) uu.s.high << bm;
+		w.s.high = (u32) uu.s.high >> b;
+		w.s.low = ((u32) uu.s.low >> b) | carries;
+	}
 
-  return w.ll;
+	return w.ll;
 }
-
diff --git a/arch/arm/lib/muldi3.c b/arch/arm/lib/muldi3.c
--- a/arch/arm/lib/muldi3.c
+++ b/arch/arm/lib/muldi3.c
@@ -32,7 +32,7 @@ Boston, MA 02111-1307, USA.  */
 #include "gcclib.h"
 
 #define umul_ppmm(xh, xl, a, b) \
-{register USItype __t0, __t1, __t2;                                     \
+{register u32 __t0, __t1, __t2;                                     \
   __asm__ ("%@ Inlined umul_ppmm					\n\
         mov     %2, %5, lsr #16						\n\
         mov     %0, %6, lsr #16						\n\
@@ -46,32 +46,27 @@ Boston, MA 02111-1307, USA.  */
         addcs   %0, %0, #65536						\n\
         adds    %1, %1, %3, lsl #16					\n\
         adc     %0, %0, %3, lsr #16"                                    \
-           : "=&r" ((USItype) (xh)),                                    \
-             "=r" ((USItype) (xl)),                                     \
+           : "=&r" ((u32) (xh)),                                    \
+             "=r" ((u32) (xl)),                                     \
              "=&r" (__t0), "=&r" (__t1), "=r" (__t2)                    \
-           : "r" ((USItype) (a)),                                       \
-             "r" ((USItype) (b)));}
-
+           : "r" ((u32) (a)),                                       \
+             "r" ((u32) (b)));}
 
 #define __umulsidi3(u, v) \
   ({DIunion __w;                                                        \
     umul_ppmm (__w.s.high, __w.s.low, u, v);                            \
     __w.ll; })
 
-
-DItype
-__muldi3 (DItype u, DItype v)
+s64 __muldi3(s64 u, s64 v)
 {
-  DIunion w;
-  DIunion uu, vv;
+	DIunion w;
+	DIunion uu, vv;
 
-  uu.ll = u,
-  vv.ll = v;
+	uu.ll = u, vv.ll = v;
 
-  w.ll = __umulsidi3 (uu.s.low, vv.s.low);
-  w.s.high += ((USItype) uu.s.low * (USItype) vv.s.high
-               + (USItype) uu.s.high * (USItype) vv.s.low);
+	w.ll = __umulsidi3(uu.s.low, vv.s.low);
+	w.s.high += ((u32) uu.s.low * (u32) vv.s.high
+		     + (u32) uu.s.high * (u32) vv.s.low);
 
-  return w.ll;
+	return w.ll;
 }
-
diff --git a/arch/arm/lib/ucmpdi2.c b/arch/arm/lib/ucmpdi2.c
--- a/arch/arm/lib/ucmpdi2.c
+++ b/arch/arm/lib/ucmpdi2.c
@@ -31,21 +31,19 @@ Boston, MA 02111-1307, USA.  */
 
 #include "gcclib.h"
 
-word_type
-__ucmpdi2 (DItype a, DItype b)
+int __ucmpdi2(s64 a, s64 b)
 {
-  DIunion au, bu;
+	DIunion au, bu;
 
-  au.ll = a, bu.ll = b;
+	au.ll = a, bu.ll = b;
 
-  if ((USItype) au.s.high < (USItype) bu.s.high)
-    return 0;
-  else if ((USItype) au.s.high > (USItype) bu.s.high)
-    return 2;
-  if ((USItype) au.s.low < (USItype) bu.s.low)
-    return 0;
-  else if ((USItype) au.s.low > (USItype) bu.s.low)
-    return 2;
-  return 1;
+	if ((u32) au.s.high < (u32) bu.s.high)
+		return 0;
+	else if ((u32) au.s.high > (u32) bu.s.high)
+		return 2;
+	if ((u32) au.s.low < (u32) bu.s.low)
+		return 0;
+	else if ((u32) au.s.low > (u32) bu.s.low)
+		return 2;
+	return 1;
 }
-
diff --git a/arch/arm/lib/udivdi3.c b/arch/arm/lib/udivdi3.c
deleted file mode 100644
--- a/arch/arm/lib/udivdi3.c
+++ /dev/null
@@ -1,242 +0,0 @@
-/* More subroutines needed by GCC output code on some machines.  */
-/* Compile this one with gcc.  */
-/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc.
-
-This file is part of GNU CC.
-
-GNU CC 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.
-
-GNU CC 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 GNU CC; see the file COPYING.  If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
-
-/* As a special exception, if you link this library with other files,
-   some of which are compiled with GCC, to produce an executable,
-   this library does not by itself cause the resulting executable
-   to be covered by the GNU General Public License.
-   This exception does not however invalidate any other reasons why
-   the executable file might be covered by the GNU General Public License.
- */
-/* support functions required by the kernel. based on code from gcc-2.95.3 */
-/* I Molton     29/07/01 */
-
-#include "gcclib.h"
-#include "longlong.h"
-
-static const UQItype __clz_tab[] =
-{
-  0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-  6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
-  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
-  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
-  8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
-  8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
-  8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
-  8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
-};
-
-UDItype
-__udivmoddi4 (UDItype n, UDItype d, UDItype *rp)
-{
-  DIunion ww;
-  DIunion nn, dd;
-  DIunion rr;
-  USItype d0, d1, n0, n1, n2;
-  USItype q0, q1;
-  USItype b, bm;
-
-  nn.ll = n;
-  dd.ll = d;
-
-  d0 = dd.s.low;
-  d1 = dd.s.high;
-  n0 = nn.s.low;
-  n1 = nn.s.high;
-
-  if (d1 == 0)
-    {
-      if (d0 > n1)
-        {
-          /* 0q = nn / 0D */
-
-          count_leading_zeros (bm, d0);
-
-          if (bm != 0)
-            {
-              /* Normalize, i.e. make the most significant bit of the
-                 denominator set.  */
-
-              d0 = d0 << bm;
-              n1 = (n1 << bm) | (n0 >> (SI_TYPE_SIZE - bm));
-              n0 = n0 << bm;
-            }
-
-          udiv_qrnnd (q0, n0, n1, n0, d0);
-          q1 = 0;
-
-          /* Remainder in n0 >> bm.  */
-        }
-      else
-        {
-          /* qq = NN / 0d */
-
-          if (d0 == 0)
-            d0 = 1 / d0;        /* Divide intentionally by zero.  */
-
-          count_leading_zeros (bm, d0);
-
-          if (bm == 0)
-            {
-              /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
-                 conclude (the most significant bit of n1 is set) /\ (the
-                 leading quotient digit q1 = 1).
-
-                 This special case is necessary, not an optimization.
-                 (Shifts counts of SI_TYPE_SIZE are undefined.)  */
-
-              n1 -= d0;
-              q1 = 1;
-            }
-          else
-            {
-              /* Normalize.  */
-
-              b = SI_TYPE_SIZE - bm;
-
-              d0 = d0 << bm;
-              n2 = n1 >> b;
-              n1 = (n1 << bm) | (n0 >> b);
-              n0 = n0 << bm;
-
-              udiv_qrnnd (q1, n1, n2, n1, d0);
-            }
-
-          /* n1 != d0...  */
-
-          udiv_qrnnd (q0, n0, n1, n0, d0);
-
-          /* Remainder in n0 >> bm.  */
-        }
-
-      if (rp != 0)
-        {
-          rr.s.low = n0 >> bm;
-          rr.s.high = 0;
-          *rp = rr.ll;
-        }
-    }
-  else
-    {
-      if (d1 > n1)
-        {
-          /* 00 = nn / DD */
-
-          q0 = 0;
-          q1 = 0;
-
-          /* Remainder in n1n0.  */
-          if (rp != 0)
-            {
-              rr.s.low = n0;
-              rr.s.high = n1;
-              *rp = rr.ll;
-            }
-        }
-      else
-        {
-          /* 0q = NN / dd */
-
-          count_leading_zeros (bm, d1);
-          if (bm == 0)
-            {
-              /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
-                 conclude (the most significant bit of n1 is set) /\ (the
-                 quotient digit q0 = 0 or 1).
-
-                 This special case is necessary, not an optimization.  */
-
-              /* The condition on the next line takes advantage of that
-                 n1 >= d1 (true due to program flow).  */
-              if (n1 > d1 || n0 >= d0)
-                {
-                  q0 = 1;
-                  sub_ddmmss (n1, n0, n1, n0, d1, d0);
-                }
-              else
-                q0 = 0;
-
-              q1 = 0;
-
-              if (rp != 0)
-                {
-                  rr.s.low = n0;
-                  rr.s.high = n1;
-                  *rp = rr.ll;
-                }
-            }
-          else
-            {
-              USItype m1, m0;
-              /* Normalize.  */
-
-              b = SI_TYPE_SIZE - bm;
-
-              d1 = (d1 << bm) | (d0 >> b);
-              d0 = d0 << bm;
-              n2 = n1 >> b;
-              n1 = (n1 << bm) | (n0 >> b);
-              n0 = n0 << bm;
-
-              udiv_qrnnd (q0, n1, n2, n1, d1);
-              umul_ppmm (m1, m0, q0, d0);
-
-              if (m1 > n1 || (m1 == n1 && m0 > n0))
-                {
-                  q0--;
-                  sub_ddmmss (m1, m0, m1, m0, d1, d0);
-                }
-
-              q1 = 0;
-
-              /* Remainder in (n1n0 - m1m0) >> bm.  */
-              if (rp != 0)
-                {
-                  sub_ddmmss (n1, n0, n1, n0, m1, m0);
-                  rr.s.low = (n1 << b) | (n0 >> bm);
-                  rr.s.high = n1 >> bm;
-                  *rp = rr.ll;
-                }
-            }
-        }
-    }
-
-  ww.s.low = q0;
-  ww.s.high = q1;
-  return ww.ll;
-}
-
-UDItype
-__udivdi3 (UDItype n, UDItype d)
-{
-  return __udivmoddi4 (n, d, (UDItype *) 0);
-}
-
-UDItype
-__umoddi3 (UDItype u, UDItype v)
-{
-  UDItype w;
-
-  (void) __udivmoddi4 (u ,v, &w);
-
-  return w;
-}
-
diff --git a/arch/arm/mach-aaec2000/Kconfig b/arch/arm/mach-aaec2000/Kconfig
new file mode 100644
--- /dev/null
+++ b/arch/arm/mach-aaec2000/Kconfig
@@ -0,0 +1,11 @@
+if ARCH_AAEC2000
+
+menu "Agilent AAEC-2000 Implementations"
+
+config MACH_AAED2000
+	bool "Agilent AAED-2000 Development Platform"
+	select CPU_ARM920T
+
+endmenu
+
+endif
diff --git a/arch/arm/mach-aaec2000/Makefile b/arch/arm/mach-aaec2000/Makefile
new file mode 100644
--- /dev/null
+++ b/arch/arm/mach-aaec2000/Makefile
@@ -0,0 +1,9 @@
+#
+# Makefile for the linux kernel.
+#
+
+# Common support (must be linked before board specific support)
+obj-y += core.o
+
+# Specific board support
+obj-$(CONFIG_MACH_AAED2000) += aaed2000.o
diff --git a/arch/arm/mach-aaec2000/Makefile.boot b/arch/arm/mach-aaec2000/Makefile.boot
new file mode 100644
--- /dev/null
+++ b/arch/arm/mach-aaec2000/Makefile.boot
@@ -0,0 +1 @@
+	zreladdr-y := 0xf0008000
diff --git a/arch/arm/mach-aaec2000/aaed2000.c b/arch/arm/mach-aaec2000/aaed2000.c
new file mode 100644
--- /dev/null
+++ b/arch/arm/mach-aaec2000/aaed2000.c
@@ -0,0 +1,50 @@
+/*
+ *  linux/arch/arm/mach-aaec2000/aaed2000.c
+ *
+ *  Support for the Agilent AAED-2000 Development Platform.
+ *
+ *  Copyright (c) 2005 Nicolas Bellido Y Ortega
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ *
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/major.h>
+#include <linux/interrupt.h>
+
+#include <asm/setup.h>
+#include <asm/memory.h>
+#include <asm/mach-types.h>
+#include <asm/hardware.h>
+#include <asm/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include "core.h"
+
+static void __init aaed2000_init_irq(void)
+{
+	aaec2000_init_irq();
+}
+
+static void __init aaed2000_map_io(void)
+{
+	aaec2000_map_io();
+}
+
+MACHINE_START(AAED2000, "Agilent AAED-2000 Development Platform")
+	/* Maintainer: Nicolas Bellido Y Ortega */
+	.phys_ram	= 0xf0000000,
+	.phys_io	= PIO_BASE,
+	.io_pg_offst	= ((VIO_BASE) >> 18) & 0xfffc,
+	.map_io		= aaed2000_map_io,
+	.init_irq	= aaed2000_init_irq,
+	.timer		= &aaec2000_timer,
+MACHINE_END
diff --git a/arch/arm/mach-aaec2000/core.c b/arch/arm/mach-aaec2000/core.c
new file mode 100644
--- /dev/null
+++ b/arch/arm/mach-aaec2000/core.c
@@ -0,0 +1,157 @@
+/*
+ *  linux/arch/arm/mach-aaec2000/core.c
+ *
+ *  Code common to all AAEC-2000 machines
+ *
+ *  Copyright (c) 2005 Nicolas Bellido Y Ortega
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/timex.h>
+#include <linux/signal.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+
+#include <asm/mach/irq.h>
+#include <asm/mach/time.h>
+#include <asm/mach/map.h>
+
+/*
+ * Common I/O mapping:
+ *
+ * Static virtual address mappings are as follow:
+ *
+ * 0xf8000000-0xf8001ffff: Devices connected to APB bus
+ * 0xf8002000-0xf8003ffff: Devices connected to AHB bus
+ *
+ * Below 0xe8000000 is reserved for vm allocation.
+ *
+ * The machine specific code must provide the extra mapping beside the
+ * default mapping provided here.
+ */
+static struct map_desc standard_io_desc[] __initdata = {
+ /* virtual         physical       length           type */
+  { VIO_APB_BASE,   PIO_APB_BASE,  IO_APB_LENGTH,   MT_DEVICE },
+  { VIO_AHB_BASE,   PIO_AHB_BASE,  IO_AHB_LENGTH,   MT_DEVICE }
+};
+
+void __init aaec2000_map_io(void)
+{
+	iotable_init(standard_io_desc, ARRAY_SIZE(standard_io_desc));
+}
+
+/*
+ * Interrupt handling routines
+ */
+static void aaec2000_int_ack(unsigned int irq)
+{
+	IRQ_INTSR = 1 << irq;
+}
+
+static void aaec2000_int_mask(unsigned int irq)
+{
+	IRQ_INTENC |= (1 << irq);
+}
+
+static void aaec2000_int_unmask(unsigned int irq)
+{
+	IRQ_INTENS |= (1 << irq);
+}
+
+static struct irqchip aaec2000_irq_chip = {
+	.ack	= aaec2000_int_ack,
+	.mask	= aaec2000_int_mask,
+	.unmask	= aaec2000_int_unmask,
+};
+
+void __init aaec2000_init_irq(void)
+{
+	unsigned int i;
+
+	for (i = 0; i < NR_IRQS; i++) {
+		set_irq_handler(i, do_level_IRQ);
+		set_irq_chip(i, &aaec2000_irq_chip);
+		set_irq_flags(i, IRQF_VALID);
+	}
+
+	/* Disable all interrupts */
+	IRQ_INTENC = 0xffffffff;
+
+	/* Clear any pending interrupts */
+	IRQ_INTSR = IRQ_INTSR;
+}
+
+/*
+ * Time keeping
+ */
+/* IRQs are disabled before entering here from do_gettimeofday() */
+static unsigned long aaec2000_gettimeoffset(void)
+{
+	unsigned long ticks_to_match, elapsed, usec;
+
+	/* Get ticks before next timer match */
+	ticks_to_match = TIMER1_LOAD - TIMER1_VAL;
+
+	/* We need elapsed ticks since last match */
+	elapsed = LATCH - ticks_to_match;
+
+	/* Now, convert them to usec */
+	usec = (unsigned long)(elapsed * (tick_nsec / 1000))/LATCH;
+
+	return usec;
+}
+
+/* We enter here with IRQs enabled */
+static irqreturn_t
+aaec2000_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	/* TODO: Check timer accuracy */
+	write_seqlock(&xtime_lock);
+
+	timer_tick(regs);
+	TIMER1_CLEAR = 1;
+
+	write_sequnlock(&xtime_lock);
+
+	return IRQ_HANDLED;
+}
+
+static struct irqaction aaec2000_timer_irq = {
+	.name		= "AAEC-2000 Timer Tick",
+	.flags		= SA_INTERRUPT | SA_TIMER,
+	.handler	= aaec2000_timer_interrupt,
+};
+
+static void __init aaec2000_timer_init(void)
+{
+	/* Disable timer 1 */
+	TIMER1_CTRL = 0;
+
+	/* We have somehow to generate a 100Hz clock.
+	 * We then use the 508KHz timer in periodic mode.
+	 */
+	TIMER1_LOAD = LATCH;
+	TIMER1_CLEAR = 1; /* Clear interrupt */
+
+	setup_irq(INT_TMR1_OFL, &aaec2000_timer_irq);
+
+	TIMER1_CTRL = TIMER_CTRL_ENABLE |
+	                TIMER_CTRL_PERIODIC |
+	                TIMER_CTRL_CLKSEL_508K;
+}
+
+struct sys_timer aaec2000_timer = {
+	.init		= aaec2000_timer_init,
+	.offset		= aaec2000_gettimeoffset,
+};
+
diff --git a/arch/arm/mach-aaec2000/core.h b/arch/arm/mach-aaec2000/core.h
new file mode 100644
--- /dev/null
+++ b/arch/arm/mach-aaec2000/core.h
@@ -0,0 +1,16 @@
+/*
+ *  linux/arch/arm/mach-aaec2000/core.h
+ *
+ *  Copyright (c) 2005 Nicolas Bellido Y Ortega
+ *
+ *  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.
+ *
+ */
+
+struct sys_timer;
+
+extern struct sys_timer aaec2000_timer;
+extern void __init aaec2000_map_io(void);
+extern void __init aaec2000_init_irq(void);
diff --git a/arch/arm/mach-clps711x/Kconfig b/arch/arm/mach-clps711x/Kconfig
--- a/arch/arm/mach-clps711x/Kconfig
+++ b/arch/arm/mach-clps711x/Kconfig
@@ -28,7 +28,7 @@ config ARCH_CLEP7312
 config ARCH_EDB7211
 	bool "EDB7211"
 	select ISA
-	select DISCONTIGMEM
+	select ARCH_DISCONTIGMEM_ENABLE
 	help
 	  Say Y here if you intend to run this kernel on a Cirrus Logic EDB-7211
 	  evaluation board.
diff --git a/arch/arm/mach-clps711x/autcpu12.c b/arch/arm/mach-clps711x/autcpu12.c
--- a/arch/arm/mach-clps711x/autcpu12.c
+++ b/arch/arm/mach-clps711x/autcpu12.c
@@ -59,11 +59,13 @@ void __init autcpu12_map_io(void)
 }
 
 MACHINE_START(AUTCPU12, "autronix autcpu12")
-	MAINTAINER("Thomas Gleixner")
-        BOOT_MEM(0xc0000000, 0x80000000, 0xff000000)
-	BOOT_PARAMS(0xc0020000)
-	MAPIO(autcpu12_map_io)
-	INITIRQ(clps711x_init_irq)
+	/* Maintainer: Thomas Gleixner */
+	.phys_ram	= 0xc0000000,
+	.phys_io	= 0x80000000,
+	.io_pg_offst	= ((0xff000000) >> 18) & 0xfffc,
+	.boot_params	= 0xc0020000,
+	.map_io		= autcpu12_map_io,
+	.init_irq	= clps711x_init_irq,
 	.timer		= &clps711x_timer,
 MACHINE_END
 
diff --git a/arch/arm/mach-clps711x/cdb89712.c b/arch/arm/mach-clps711x/cdb89712.c
--- a/arch/arm/mach-clps711x/cdb89712.c
+++ b/arch/arm/mach-clps711x/cdb89712.c
@@ -49,10 +49,12 @@ static void __init cdb89712_map_io(void)
 }
 
 MACHINE_START(CDB89712, "Cirrus-CDB89712")
-	MAINTAINER("Ray Lehtiniemi")
-	BOOT_MEM(0xc0000000, 0x80000000, 0xff000000)
-	BOOT_PARAMS(0xc0000100)
-	MAPIO(cdb89712_map_io)
-	INITIRQ(clps711x_init_irq)
+	/* Maintainer: Ray Lehtiniemi */
+	.phys_ram	= 0xc0000000,
+	.phys_io	= 0x80000000,
+	.io_pg_offst	= ((0xff000000) >> 18) & 0xfffc,
+	.boot_params	= 0xc0000100,
+	.map_io		= cdb89712_map_io,
+	.init_irq	= clps711x_init_irq,
 	.timer		= &clps711x_timer,
 MACHINE_END
diff --git a/arch/arm/mach-clps711x/ceiva.c b/arch/arm/mach-clps711x/ceiva.c
--- a/arch/arm/mach-clps711x/ceiva.c
+++ b/arch/arm/mach-clps711x/ceiva.c
@@ -53,10 +53,12 @@ static void __init ceiva_map_io(void)
 
 
 MACHINE_START(CEIVA, "CEIVA/Polaroid Photo MAX Digital Picture Frame")
-	MAINTAINER("Rob Scott")
-	BOOT_MEM(0xc0000000, 0x80000000, 0xff000000)
-	BOOT_PARAMS(0xc0000100)
-	MAPIO(ceiva_map_io)
-	INITIRQ(clps711x_init_irq)
+	/* Maintainer: Rob Scott */
+	.phys_ram	= 0xc0000000,
+	.phys_io	= 0x80000000,
+	.io_pg_offst	= ((0xff000000) >> 18) & 0xfffc,
+	.boot_params	= 0xc0000100,
+	.map_io		= ceiva_map_io,
+	.init_irq	= clps711x_init_irq,
 	.timer		= &clps711x_timer,
 MACHINE_END
diff --git a/arch/arm/mach-clps711x/clep7312.c b/arch/arm/mach-clps711x/clep7312.c
--- a/arch/arm/mach-clps711x/clep7312.c
+++ b/arch/arm/mach-clps711x/clep7312.c
@@ -37,12 +37,14 @@ fixup_clep7312(struct machine_desc *desc
 
 
 MACHINE_START(CLEP7212, "Cirrus Logic 7212/7312")
-	MAINTAINER("Nobody")
-        BOOT_MEM(0xc0000000, 0x80000000, 0xff000000)
-	BOOT_PARAMS(0xc0000100)
-	FIXUP(fixup_clep7312)
-	MAPIO(clps711x_map_io)
-	INITIRQ(clps711x_init_irq)
+	/* Maintainer: Nobody */
+	.phys_ram	= 0xc0000000,
+	.phys_io	= 0x80000000,
+	.io_pg_offst	= ((0xff000000) >> 18) & 0xfffc,
+	.boot_params	= 0xc0000100,
+	.fixup		= fixup_clep7312,
+	.map_io		= clps711x_map_io,
+	.init_irq	= clps711x_init_irq,
 	.timer		= &clps711x_timer,
 MACHINE_END
 
diff --git a/arch/arm/mach-clps711x/edb7211-arch.c b/arch/arm/mach-clps711x/edb7211-arch.c
--- a/arch/arm/mach-clps711x/edb7211-arch.c
+++ b/arch/arm/mach-clps711x/edb7211-arch.c
@@ -51,11 +51,13 @@ fixup_edb7211(struct machine_desc *desc,
 }
 
 MACHINE_START(EDB7211, "CL-EDB7211 (EP7211 eval board)")
-	MAINTAINER("Jon McClintock")
-	BOOT_MEM(0xc0000000, 0x80000000, 0xff000000)
-	BOOT_PARAMS(0xc0020100)	/* 0xc0000000 - 0xc001ffff can be video RAM */
-	FIXUP(fixup_edb7211)
-	MAPIO(edb7211_map_io)
-	INITIRQ(clps711x_init_irq)
+	/* Maintainer: Jon McClintock */
+	.phys_ram	= 0xc0000000,
+	.phys_io	= 0x80000000,
+	.io_pg_offst	= ((0xff000000) >> 18) & 0xfffc,
+	.boot_params	= 0xc0020100,	/* 0xc0000000 - 0xc001ffff can be video RAM */
+	.fixup		= fixup_edb7211,
+	.map_io		= edb7211_map_io,
+	.init_irq	= clps711x_init_irq,
 	.timer		= &clps711x_timer,
 MACHINE_END
diff --git a/arch/arm/mach-clps711x/fortunet.c b/arch/arm/mach-clps711x/fortunet.c
--- a/arch/arm/mach-clps711x/fortunet.c
+++ b/arch/arm/mach-clps711x/fortunet.c
@@ -75,11 +75,13 @@ fortunet_fixup(struct machine_desc *desc
 }
 
 MACHINE_START(FORTUNET, "ARM-FortuNet")
-	MAINTAINER("FortuNet Inc.")
-        BOOT_MEM(0xc0000000, 0x80000000, 0xf0000000)
-	BOOT_PARAMS(0x00000000)
-	FIXUP(fortunet_fixup)
-	MAPIO(clps711x_map_io)
-	INITIRQ(clps711x_init_irq)
+	/* Maintainer: FortuNet Inc. */
+	.phys_ram	= 0xc0000000,
+	.phys_io	= 0x80000000,
+	.io_pg_offst	= ((0xf0000000) >> 18) & 0xfffc,
+	.boot_params	= 0x00000000,
+	.fixup		= fortunet_fixup,
+	.map_io		= clps711x_map_io,
+	.init_irq	= clps711x_init_irq,
 	.timer		= &clps711x_timer,
 MACHINE_END
diff --git a/arch/arm/mach-clps711x/p720t.c b/arch/arm/mach-clps711x/p720t.c
--- a/arch/arm/mach-clps711x/p720t.c
+++ b/arch/arm/mach-clps711x/p720t.c
@@ -79,12 +79,14 @@ static void __init p720t_map_io(void)
 }
 
 MACHINE_START(P720T, "ARM-Prospector720T")
-	MAINTAINER("ARM Ltd/Deep Blue Solutions Ltd")
-	BOOT_MEM(0xc0000000, 0x80000000, 0xff000000)
-	BOOT_PARAMS(0xc0000100)
-	FIXUP(fixup_p720t)
-	MAPIO(p720t_map_io)
-	INITIRQ(clps711x_init_irq)
+	/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
+	.phys_ram	= 0xc0000000,
+	.phys_io	= 0x80000000,
+	.io_pg_offst	= ((0xff000000) >> 18) & 0xfffc,
+	.boot_params	= 0xc0000100,
+	.fixup		= fixup_p720t,
+	.map_io		= p720t_map_io,
+	.init_irq	= clps711x_init_irq,
 	.timer		= &clps711x_timer,
 MACHINE_END
 
diff --git a/arch/arm/mach-clps711x/time.c b/arch/arm/mach-clps711x/time.c
--- a/arch/arm/mach-clps711x/time.c
+++ b/arch/arm/mach-clps711x/time.c
@@ -57,8 +57,8 @@ p720t_timer_interrupt(int irq, void *dev
 
 static struct irqaction clps711x_timer_irq = {
 	.name		= "CLPS711x Timer Tick",
-	.flags		= SA_INTERRUPT,
-	.handler	= p720t_timer_interrupt
+	.flags		= SA_INTERRUPT | SA_TIMER,
+	.handler	= p720t_timer_interrupt,
 };
 
 static void __init clps711x_timer_init(void)
diff --git a/arch/arm/mach-clps7500/core.c b/arch/arm/mach-clps7500/core.c
--- a/arch/arm/mach-clps7500/core.c
+++ b/arch/arm/mach-clps7500/core.c
@@ -26,6 +26,8 @@
 #include <asm/irq.h>
 #include <asm/mach-types.h>
 
+unsigned int vram_size;
+
 static void cl7500_ack_irq_a(unsigned int irq)
 {
 	unsigned int val, mask;
@@ -296,8 +298,8 @@ clps7500_timer_interrupt(int irq, void *
 
 static struct irqaction clps7500_timer_irq = {
 	.name		= "CLPS7500 Timer Tick",
-	.flags		= SA_INTERRUPT,
-	.handler	= clps7500_timer_interrupt
+	.flags		= SA_INTERRUPT | SA_TIMER,
+	.handler	= clps7500_timer_interrupt,
 };
 
 /*
@@ -364,11 +366,13 @@ static void __init clps7500_init(void)
 }
 
 MACHINE_START(CLPS7500, "CL-PS7500")
-	MAINTAINER("Philip Blundell")
-	BOOT_MEM(0x10000000, 0x03000000, 0xe0000000)
-	MAPIO(clps7500_map_io)
-	INITIRQ(clps7500_init_irq)
-		.init_machine	= clps7500_init,
-		.timer		= &clps7500_timer,
+	/* Maintainer: Philip Blundell */
+	.phys_ram	= 0x10000000,
+	.phys_io	= 0x03000000,
+	.io_pg_offst	= ((0xe0000000) >> 18) & 0xfffc,
+	.map_io		= clps7500_map_io,
+	.init_irq	= clps7500_init_irq,
+	.init_machine	= clps7500_init,
+	.timer		= &clps7500_timer,
 MACHINE_END
 
diff --git a/arch/arm/mach-ebsa110/core.c b/arch/arm/mach-ebsa110/core.c
--- a/arch/arm/mach-ebsa110/core.c
+++ b/arch/arm/mach-ebsa110/core.c
@@ -173,8 +173,8 @@ ebsa110_timer_interrupt(int irq, void *d
 
 static struct irqaction ebsa110_timer_irq = {
 	.name		= "EBSA110 Timer Tick",
-	.flags		= SA_INTERRUPT,
-	.handler	= ebsa110_timer_interrupt
+	.flags		= SA_INTERRUPT | SA_TIMER,
+	.handler	= ebsa110_timer_interrupt,
 };
 
 /*
@@ -233,13 +233,15 @@ static int __init ebsa110_init(void)
 arch_initcall(ebsa110_init);
 
 MACHINE_START(EBSA110, "EBSA110")
-	MAINTAINER("Russell King")
-	BOOT_MEM(0x00000000, 0xe0000000, 0xe0000000)
-	BOOT_PARAMS(0x00000400)
-	DISABLE_PARPORT(0)
-	DISABLE_PARPORT(2)
-	SOFT_REBOOT
-	MAPIO(ebsa110_map_io)
-	INITIRQ(ebsa110_init_irq)
+	/* Maintainer: Russell King */
+	.phys_ram	= 0x00000000,
+	.phys_io	= 0xe0000000,
+	.io_pg_offst	= ((0xe0000000) >> 18) & 0xfffc,
+	.boot_params	= 0x00000400,
+	.reserve_lp0	= 1,
+	.reserve_lp2	= 1,
+	.soft_reboot	= 1,
+	.map_io		= ebsa110_map_io,
+	.init_irq	= ebsa110_init_irq,
 	.timer		= &ebsa110_timer,
 MACHINE_END
diff --git a/arch/arm/mach-epxa10db/arch.c b/arch/arm/mach-epxa10db/arch.c
--- a/arch/arm/mach-epxa10db/arch.c
+++ b/arch/arm/mach-epxa10db/arch.c
@@ -63,10 +63,12 @@ extern void epxa10db_init_irq(void);
 extern struct sys_timer epxa10db_timer;
 
 MACHINE_START(CAMELOT, "Altera Epxa10db")
-	MAINTAINER("Altera Corporation")
-	BOOT_MEM(0x00000000, 0x7fffc000, 0xffffc000)
-	MAPIO(epxa10db_map_io)
-	INITIRQ(epxa10db_init_irq)
+	/* Maintainer: Altera Corporation */
+	.phys_ram	= 0x00000000,
+	.phys_io	= 0x7fffc000,
+	.io_pg_offst	= ((0xffffc000) >> 18) & 0xfffc,
+	.map_io		= epxa10db_map_io,
+	.init_irq	= epxa10db_init_irq,
 	.timer		= &epxa10db_timer,
 MACHINE_END
 
diff --git a/arch/arm/mach-epxa10db/time.c b/arch/arm/mach-epxa10db/time.c
--- a/arch/arm/mach-epxa10db/time.c
+++ b/arch/arm/mach-epxa10db/time.c
@@ -56,8 +56,8 @@ epxa10db_timer_interrupt(int irq, void *
 
 static struct irqaction epxa10db_timer_irq = {
 	.name		= "Excalibur Timer Tick",
-	.flags		= SA_INTERRUPT,
-	.handler	= epxa10db_timer_interrupt
+	.flags		= SA_INTERRUPT | SA_TIMER,
+	.handler	= epxa10db_timer_interrupt,
 };
 
 /*
diff --git a/arch/arm/mach-footbridge/cats-hw.c b/arch/arm/mach-footbridge/cats-hw.c
--- a/arch/arm/mach-footbridge/cats-hw.c
+++ b/arch/arm/mach-footbridge/cats-hw.c
@@ -84,12 +84,14 @@ fixup_cats(struct machine_desc *desc, st
 }
 
 MACHINE_START(CATS, "Chalice-CATS")
-	MAINTAINER("Philip Blundell")
-	BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0xfe000000)
-	BOOT_PARAMS(0x00000100)
-	SOFT_REBOOT
-	FIXUP(fixup_cats)
-	MAPIO(footbridge_map_io)
-	INITIRQ(footbridge_init_irq)
+	/* Maintainer: Philip Blundell */
+	.phys_ram	= 0x00000000,
+	.phys_io	= DC21285_ARMCSR_BASE,
+	.io_pg_offst	= ((0xfe000000) >> 18) & 0xfffc,
+	.boot_params	= 0x00000100,
+	.soft_reboot	= 1,
+	.fixup		= fixup_cats,
+	.map_io		= footbridge_map_io,
+	.init_irq	= footbridge_init_irq,
 	.timer		= &isa_timer,
 MACHINE_END
diff --git a/arch/arm/mach-footbridge/co285.c b/arch/arm/mach-footbridge/co285.c
--- a/arch/arm/mach-footbridge/co285.c
+++ b/arch/arm/mach-footbridge/co285.c
@@ -28,11 +28,13 @@ fixup_coebsa285(struct machine_desc *des
 }
 
 MACHINE_START(CO285, "co-EBSA285")
-	MAINTAINER("Mark van Doesburg")
-	BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0x7cf00000)
-	FIXUP(fixup_coebsa285)
-	MAPIO(footbridge_map_io)
-	INITIRQ(footbridge_init_irq)
+	/* Maintainer: Mark van Doesburg */
+	.phys_ram	= 0x00000000,
+	.phys_io	= DC21285_ARMCSR_BASE,
+	.io_pg_offst	= ((0x7cf00000) >> 18) & 0xfffc,
+	.fixup		= fixup_coebsa285,
+	.map_io		= footbridge_map_io,
+	.init_irq	= footbridge_init_irq,
 	.timer		= &footbridge_timer,
 MACHINE_END
 
diff --git a/arch/arm/mach-footbridge/dc21285-timer.c b/arch/arm/mach-footbridge/dc21285-timer.c
--- a/arch/arm/mach-footbridge/dc21285-timer.c
+++ b/arch/arm/mach-footbridge/dc21285-timer.c
@@ -43,7 +43,7 @@ timer1_interrupt(int irq, void *dev_id, 
 static struct irqaction footbridge_timer_irq = {
 	.name		= "Timer1 timer tick",
 	.handler	= timer1_interrupt,
-	.flags		= SA_INTERRUPT,
+	.flags		= SA_INTERRUPT | SA_TIMER,
 };
 
 /*
diff --git a/arch/arm/mach-footbridge/ebsa285.c b/arch/arm/mach-footbridge/ebsa285.c
--- a/arch/arm/mach-footbridge/ebsa285.c
+++ b/arch/arm/mach-footbridge/ebsa285.c
@@ -13,12 +13,15 @@
 #include "common.h"
 
 MACHINE_START(EBSA285, "EBSA285")
-	MAINTAINER("Russell King")
-	BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0xfe000000)
-	BOOT_PARAMS(0x00000100)
-	VIDEO(0x000a0000, 0x000bffff)
-	MAPIO(footbridge_map_io)
-	INITIRQ(footbridge_init_irq)
+	/* Maintainer: Russell King */
+	.phys_ram	= 0x00000000,
+	.phys_io	= DC21285_ARMCSR_BASE,
+	.io_pg_offst	= ((0xfe000000) >> 18) & 0xfffc,
+	.boot_params	= 0x00000100,
+	.video_start	= 0x000a0000,
+	.video_end	= 0x000bffff,
+	.map_io		= footbridge_map_io,
+	.init_irq	= footbridge_init_irq,
 	.timer		= &footbridge_timer,
 MACHINE_END
 
diff --git a/arch/arm/mach-footbridge/isa-timer.c b/arch/arm/mach-footbridge/isa-timer.c
--- a/arch/arm/mach-footbridge/isa-timer.c
+++ b/arch/arm/mach-footbridge/isa-timer.c
@@ -72,7 +72,7 @@ isa_timer_interrupt(int irq, void *dev_i
 static struct irqaction isa_timer_irq = {
 	.name		= "ISA timer tick",
 	.handler	= isa_timer_interrupt,
-	.flags		= SA_INTERRUPT,
+	.flags		= SA_INTERRUPT | SA_TIMER,
 };
 
 static void __init isa_timer_init(void)
diff --git a/arch/arm/mach-footbridge/netwinder-hw.c b/arch/arm/mach-footbridge/netwinder-hw.c
--- a/arch/arm/mach-footbridge/netwinder-hw.c
+++ b/arch/arm/mach-footbridge/netwinder-hw.c
@@ -647,14 +647,17 @@ fixup_netwinder(struct machine_desc *des
 }
 
 MACHINE_START(NETWINDER, "Rebel-NetWinder")
-	MAINTAINER("Russell King/Rebel.com")
-	BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0xfe000000)
-	BOOT_PARAMS(0x00000100)
-	VIDEO(0x000a0000, 0x000bffff)
-	DISABLE_PARPORT(0)
-	DISABLE_PARPORT(2)
-	FIXUP(fixup_netwinder)
-	MAPIO(footbridge_map_io)
-	INITIRQ(footbridge_init_irq)
+	/* Maintainer: Russell King/Rebel.com */
+	.phys_ram	= 0x00000000,
+	.phys_io	= DC21285_ARMCSR_BASE,
+	.io_pg_offst	= ((0xfe000000) >> 18) & 0xfffc,
+	.boot_params	= 0x00000100,
+	.video_start	= 0x000a0000,
+	.video_end	= 0x000bffff,
+	.reserve_lp0	= 1,
+	.reserve_lp2	= 1,
+	.fixup		= fixup_netwinder,
+	.map_io		= footbridge_map_io,
+	.init_irq	= footbridge_init_irq,
 	.timer		= &isa_timer,
 MACHINE_END
diff --git a/arch/arm/mach-footbridge/personal.c b/arch/arm/mach-footbridge/personal.c
--- a/arch/arm/mach-footbridge/personal.c
+++ b/arch/arm/mach-footbridge/personal.c
@@ -13,11 +13,13 @@
 #include "common.h"
 
 MACHINE_START(PERSONAL_SERVER, "Compaq-PersonalServer")
-	MAINTAINER("Jamey Hicks / George France")
-	BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0xfe000000)
-	BOOT_PARAMS(0x00000100)
-	MAPIO(footbridge_map_io)
-	INITIRQ(footbridge_init_irq)
+	/* Maintainer: Jamey Hicks / George France */
+	.phys_ram	= 0x00000000,
+	.phys_io	= DC21285_ARMCSR_BASE,
+	.io_pg_offst	= ((0xfe000000) >> 18) & 0xfffc,
+	.boot_params	= 0x00000100,
+	.map_io		= footbridge_map_io,
+	.init_irq	= footbridge_init_irq,
 	.timer		= &footbridge_timer,
 MACHINE_END
 
diff --git a/arch/arm/mach-h720x/cpu-h7201.c b/arch/arm/mach-h720x/cpu-h7201.c
--- a/arch/arm/mach-h720x/cpu-h7201.c
+++ b/arch/arm/mach-h720x/cpu-h7201.c
@@ -41,8 +41,8 @@ h7201_timer_interrupt(int irq, void *dev
 
 static struct irqaction h7201_timer_irq = {
 	.name		= "h7201 Timer Tick",
-	.flags		= SA_INTERRUPT,
-	.handler	= h7201_timer_interrupt
+	.flags		= SA_INTERRUPT | SA_TIMER,
+	.handler	= h7201_timer_interrupt,
 };
 
 /*
diff --git a/arch/arm/mach-h720x/cpu-h7202.c b/arch/arm/mach-h720x/cpu-h7202.c
--- a/arch/arm/mach-h720x/cpu-h7202.c
+++ b/arch/arm/mach-h720x/cpu-h7202.c
@@ -171,8 +171,8 @@ static struct irqchip h7202_timerx_chip 
 
 static struct irqaction h7202_timer_irq = {
 	.name		= "h7202 Timer Tick",
-	.flags		= SA_INTERRUPT,
-	.handler	= h7202_timer_interrupt
+	.flags		= SA_INTERRUPT | SA_TIMER,
+	.handler	= h7202_timer_interrupt,
 };
 
 /*
diff --git a/arch/arm/mach-h720x/h7201-eval.c b/arch/arm/mach-h720x/h7201-eval.c
--- a/arch/arm/mach-h720x/h7201-eval.c
+++ b/arch/arm/mach-h720x/h7201-eval.c
@@ -30,10 +30,12 @@
 #include "common.h"
 
 MACHINE_START(H7201, "Hynix GMS30C7201")
-	MAINTAINER("Robert Schwebel, Pengutronix")
-	BOOT_MEM(0x40000000, 0x80000000, 0xf0000000)
-	BOOT_PARAMS(0xc0001000)
-	MAPIO(h720x_map_io)
-	INITIRQ(h720x_init_irq)
-	.timer = &h7201_timer,
+	/* Maintainer: Robert Schwebel, Pengutronix */
+	.phys_ram	= 0x40000000,
+	.phys_io	= 0x80000000,
+	.io_pg_offst	= ((0xf0000000) >> 18) & 0xfffc,
+	.boot_params	= 0xc0001000,
+	.map_io		= h720x_map_io,
+	.init_irq	= h720x_init_irq,
+	.timer		= &h7201_timer,
 MACHINE_END
diff --git a/arch/arm/mach-h720x/h7202-eval.c b/arch/arm/mach-h720x/h7202-eval.c
--- a/arch/arm/mach-h720x/h7202-eval.c
+++ b/arch/arm/mach-h720x/h7202-eval.c
@@ -71,11 +71,13 @@ static void __init init_eval_h7202(void)
 }
 
 MACHINE_START(H7202, "Hynix HMS30C7202")
-	MAINTAINER("Robert Schwebel, Pengutronix")
-	BOOT_MEM(0x40000000, 0x80000000, 0xf0000000)
-	BOOT_PARAMS(0x40000100)
-	MAPIO(h720x_map_io)
-	INITIRQ(h7202_init_irq)
-	.timer = &h7202_timer,
-	INIT_MACHINE(init_eval_h7202)
+	/* Maintainer: Robert Schwebel, Pengutronix */
+	.phys_ram	= 0x40000000,
+	.phys_io	= 0x80000000,
+	.io_pg_offst	= ((0xf0000000) >> 18) & 0xfffc,
+	.boot_params	= 0x40000100,
+	.map_io		= h720x_map_io,
+	.init_irq	= h7202_init_irq,
+	.timer		= &h7202_timer,
+	.init_machine	= init_eval_h7202,
 MACHINE_END
diff --git a/arch/arm/mach-imx/mx1ads.c b/arch/arm/mach-imx/mx1ads.c
--- a/arch/arm/mach-imx/mx1ads.c
+++ b/arch/arm/mach-imx/mx1ads.c
@@ -78,11 +78,13 @@ mx1ads_map_io(void)
 }
 
 MACHINE_START(MX1ADS, "Motorola MX1ADS")
-	MAINTAINER("Sascha Hauer, Pengutronix")
-	BOOT_MEM(0x08000000, 0x00200000, 0xe0200000)
-	BOOT_PARAMS(0x08000100)
-	MAPIO(mx1ads_map_io)
-	INITIRQ(imx_init_irq)
+	/* Maintainer: Sascha Hauer, Pengutronix */
+	.phys_ram	= 0x08000000,
+	.phys_io	= 0x00200000,
+	.io_pg_offst	= ((0xe0200000) >> 18) & 0xfffc,
+	.boot_params	= 0x08000100,
+	.map_io		= mx1ads_map_io,
+	.init_irq	= imx_init_irq,
 	.timer		= &imx_timer,
-	INIT_MACHINE(mx1ads_init)
+	.init_machine	= mx1ads_init,
 MACHINE_END
diff --git a/arch/arm/mach-imx/time.c b/arch/arm/mach-imx/time.c
--- a/arch/arm/mach-imx/time.c
+++ b/arch/arm/mach-imx/time.c
@@ -72,8 +72,8 @@ imx_timer_interrupt(int irq, void *dev_i
 
 static struct irqaction imx_timer_irq = {
 	.name		= "i.MX Timer Tick",
-	.flags		= SA_INTERRUPT,
-	.handler	= imx_timer_interrupt
+	.flags		= SA_INTERRUPT | SA_TIMER,
+	.handler	= imx_timer_interrupt,
 };
 
 /*
diff --git a/arch/arm/mach-integrator/Makefile b/arch/arm/mach-integrator/Makefile
--- a/arch/arm/mach-integrator/Makefile
+++ b/arch/arm/mach-integrator/Makefile
@@ -12,3 +12,4 @@ obj-$(CONFIG_LEDS)			+= leds.o
 obj-$(CONFIG_PCI)			+= pci_v3.o pci.o
 obj-$(CONFIG_CPU_FREQ_INTEGRATOR)	+= cpu.o
 obj-$(CONFIG_INTEGRATOR_IMPD1)		+= impd1.o
+obj-$(CONFIG_SMP)			+= platsmp.o headsmp.o
diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c
--- a/arch/arm/mach-integrator/core.c
+++ b/arch/arm/mach-integrator/core.c
@@ -14,11 +14,13 @@
 #include <linux/spinlock.h>
 #include <linux/interrupt.h>
 #include <linux/sched.h>
+#include <linux/smp.h>
 
 #include <asm/hardware.h>
 #include <asm/irq.h>
 #include <asm/io.h>
 #include <asm/hardware/amba.h>
+#include <asm/hardware/arm_timer.h>
 #include <asm/arch/cm.h>
 #include <asm/system.h>
 #include <asm/leds.h>
@@ -155,16 +157,6 @@ EXPORT_SYMBOL(cm_control);
 #define TICKS2USECS(x)	((x) / TICKS_PER_uSEC)
 #endif
 
-/*
- * What does it look like?
- */
-typedef struct TimerStruct {
-	unsigned long TimerLoad;
-	unsigned long TimerValue;
-	unsigned long TimerControl;
-	unsigned long TimerClear;
-} TimerStruct_t;
-
 static unsigned long timer_reload;
 
 /*
@@ -173,7 +165,6 @@ static unsigned long timer_reload;
  */
 unsigned long integrator_gettimeoffset(void)
 {
-	volatile TimerStruct_t *timer1 = (TimerStruct_t *)TIMER1_VA_BASE;
 	unsigned long ticks1, ticks2, status;
 
 	/*
@@ -182,11 +173,11 @@ unsigned long integrator_gettimeoffset(v
 	 * an interrupt.  We get around this by ensuring that the
 	 * counter has not reloaded between our two reads.
 	 */
-	ticks2 = timer1->TimerValue & 0xffff;
+	ticks2 = readl(TIMER1_VA_BASE + TIMER_VALUE) & 0xffff;
 	do {
 		ticks1 = ticks2;
 		status = __raw_readl(VA_IC_BASE + IRQ_RAW_STATUS);
-		ticks2 = timer1->TimerValue & 0xffff;
+		ticks2 = readl(TIMER1_VA_BASE + TIMER_VALUE) & 0xffff;
 	} while (ticks2 > ticks1);
 
 	/*
@@ -212,16 +203,30 @@ unsigned long integrator_gettimeoffset(v
 static irqreturn_t
 integrator_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-	volatile TimerStruct_t *timer1 = (volatile TimerStruct_t *)TIMER1_VA_BASE;
-
 	write_seqlock(&xtime_lock);
 
 	/*
 	 * clear the interrupt
 	 */
-	timer1->TimerClear = 1;
+	writel(1, TIMER1_VA_BASE + TIMER_INTCLR);
 
-	timer_tick(regs);
+	/*
+	 * the clock tick routines are only processed on the
+	 * primary CPU
+	 */
+	if (hard_smp_processor_id() == 0) {
+		timer_tick(regs);
+#ifdef CONFIG_SMP
+		smp_send_timer();
+#endif
+	}
+
+#ifdef CONFIG_SMP
+	/*
+	 * this is the ARM equivalent of the APIC timer interrupt
+	 */
+	update_process_times(user_mode(regs));
+#endif /* CONFIG_SMP */
 
 	write_sequnlock(&xtime_lock);
 
@@ -230,8 +235,8 @@ integrator_timer_interrupt(int irq, void
 
 static struct irqaction integrator_timer_irq = {
 	.name		= "Integrator Timer Tick",
-	.flags		= SA_INTERRUPT,
-	.handler	= integrator_timer_interrupt
+	.flags		= SA_INTERRUPT | SA_TIMER,
+	.handler	= integrator_timer_interrupt,
 };
 
 /*
@@ -239,32 +244,29 @@ static struct irqaction integrator_timer
  */
 void __init integrator_time_init(unsigned long reload, unsigned int ctrl)
 {
-	volatile TimerStruct_t *timer0 = (volatile TimerStruct_t *)TIMER0_VA_BASE;
-	volatile TimerStruct_t *timer1 = (volatile TimerStruct_t *)TIMER1_VA_BASE;
-	volatile TimerStruct_t *timer2 = (volatile TimerStruct_t *)TIMER2_VA_BASE;
-	unsigned int timer_ctrl = 0x80 | 0x40;	/* periodic */
+	unsigned int timer_ctrl = TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC;
 
 	timer_reload = reload;
 	timer_ctrl |= ctrl;
 
 	if (timer_reload > 0x100000) {
 		timer_reload >>= 8;
-		timer_ctrl |= 0x08; /* /256 */
+		timer_ctrl |= TIMER_CTRL_DIV256;
 	} else if (timer_reload > 0x010000) {
 		timer_reload >>= 4;
-		timer_ctrl |= 0x04; /* /16 */
+		timer_ctrl |= TIMER_CTRL_DIV16;
 	}
 
 	/*
 	 * Initialise to a known state (all timers off)
 	 */
-	timer0->TimerControl = 0;
-	timer1->TimerControl = 0;
-	timer2->TimerControl = 0;
-
-	timer1->TimerLoad    = timer_reload;
-	timer1->TimerValue   = timer_reload;
-	timer1->TimerControl = timer_ctrl;
+	writel(0, TIMER0_VA_BASE + TIMER_CTRL);
+	writel(0, TIMER1_VA_BASE + TIMER_CTRL);
+	writel(0, TIMER2_VA_BASE + TIMER_CTRL);
+
+	writel(timer_reload, TIMER1_VA_BASE + TIMER_LOAD);
+	writel(timer_reload, TIMER1_VA_BASE + TIMER_VALUE);
+	writel(timer_ctrl, TIMER1_VA_BASE + TIMER_CTRL);
 
 	/*
 	 * Make irqs happen for the system timer
diff --git a/arch/arm/mach-integrator/headsmp.S b/arch/arm/mach-integrator/headsmp.S
new file mode 100644
--- /dev/null
+++ b/arch/arm/mach-integrator/headsmp.S
@@ -0,0 +1,37 @@
+/*
+ *  linux/arch/arm/mach-integrator/headsmp.S
+ *
+ *  Copyright (c) 2003 ARM Limited
+ *  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 version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/linkage.h>
+#include <linux/init.h>
+
+	__INIT
+
+/*
+ * Integrator specific entry point for secondary CPUs.  This provides
+ * a "holding pen" into which all secondary cores are held until we're
+ * ready for them to initialise.
+ */
+ENTRY(integrator_secondary_startup)
+	adr	r4, 1f
+	ldmia	r4, {r5, r6}
+	sub	r4, r4, r5
+	ldr	r6, [r6, r4]
+pen:	ldr	r7, [r6]
+	cmp	r7, r0
+	bne	pen
+
+	/*
+	 * we've been released from the holding pen: secondary_stack
+	 * should now contain the SVC stack for this core
+	 */
+	b	secondary_startup
+
+1:	.long	.
+	.long	phys_pen_release
diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c
--- a/arch/arm/mach-integrator/integrator_ap.c
+++ b/arch/arm/mach-integrator/integrator_ap.c
@@ -292,11 +292,13 @@ static struct sys_timer ap_timer = {
 };
 
 MACHINE_START(INTEGRATOR, "ARM-Integrator")
-	MAINTAINER("ARM Ltd/Deep Blue Solutions Ltd")
-	BOOT_MEM(0x00000000, 0x16000000, 0xf1600000)
-	BOOT_PARAMS(0x00000100)
-	MAPIO(ap_map_io)
-	INITIRQ(ap_init_irq)
+	/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
+	.phys_ram	= 0x00000000,
+	.phys_io	= 0x16000000,
+	.io_pg_offst	= ((0xf1600000) >> 18) & 0xfffc,
+	.boot_params	= 0x00000100,
+	.map_io		= ap_map_io,
+	.init_irq	= ap_init_irq,
 	.timer		= &ap_timer,
-	INIT_MACHINE(ap_init)
+	.init_machine	= ap_init,
 MACHINE_END
diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c
--- a/arch/arm/mach-integrator/integrator_cp.c
+++ b/arch/arm/mach-integrator/integrator_cp.c
@@ -532,11 +532,13 @@ static struct sys_timer cp_timer = {
 };
 
 MACHINE_START(CINTEGRATOR, "ARM-IntegratorCP")
-	MAINTAINER("ARM Ltd/Deep Blue Solutions Ltd")
-	BOOT_MEM(0x00000000, 0x16000000, 0xf1600000)
-	BOOT_PARAMS(0x00000100)
-	MAPIO(intcp_map_io)
-	INITIRQ(intcp_init_irq)
+	/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
+	.phys_ram	= 0x00000000,
+	.phys_io	= 0x16000000,
+	.io_pg_offst	= ((0xf1600000) >> 18) & 0xfffc,
+	.boot_params	= 0x00000100,
+	.map_io		= intcp_map_io,
+	.init_irq	= intcp_init_irq,
 	.timer		= &cp_timer,
-	INIT_MACHINE(intcp_init)
+	.init_machine	= intcp_init,
 MACHINE_END
diff --git a/arch/arm/mach-integrator/leds.c b/arch/arm/mach-integrator/leds.c
--- a/arch/arm/mach-integrator/leds.c
+++ b/arch/arm/mach-integrator/leds.c
@@ -22,6 +22,8 @@
  */
 #include <linux/kernel.h>
 #include <linux/init.h>
+#include <linux/smp.h>
+#include <linux/spinlock.h>
 
 #include <asm/hardware.h>
 #include <asm/io.h>
@@ -85,4 +87,4 @@ static int __init leds_init(void)
 	return 0;
 }
 
-__initcall(leds_init);
+core_initcall(leds_init);
diff --git a/arch/arm/mach-integrator/platsmp.c b/arch/arm/mach-integrator/platsmp.c
new file mode 100644
--- /dev/null
+++ b/arch/arm/mach-integrator/platsmp.c
@@ -0,0 +1,196 @@
+/*
+ *  linux/arch/arm/mach-cintegrator/platsmp.c
+ *
+ *  Copyright (C) 2002 ARM Ltd.
+ *  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 version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/mm.h>
+
+#include <asm/atomic.h>
+#include <asm/cacheflush.h>
+#include <asm/delay.h>
+#include <asm/mmu_context.h>
+#include <asm/procinfo.h>
+#include <asm/ptrace.h>
+#include <asm/smp.h>
+
+extern void integrator_secondary_startup(void);
+
+/*
+ * control for which core is the next to come out of the secondary
+ * boot "holding pen"
+ */
+volatile int __cpuinitdata pen_release = -1;
+unsigned long __cpuinitdata phys_pen_release = 0;
+
+static DEFINE_SPINLOCK(boot_lock);
+
+void __cpuinit platform_secondary_init(unsigned int cpu)
+{
+	/*
+	 * the primary core may have used a "cross call" soft interrupt
+	 * to get this processor out of WFI in the BootMonitor - make
+	 * sure that we are no longer being sent this soft interrupt
+	 */
+	smp_cross_call_done(cpumask_of_cpu(cpu));
+
+	/*
+	 * if any interrupts are already enabled for the primary
+	 * core (e.g. timer irq), then they will not have been enabled
+	 * for us: do so
+	 */
+	secondary_scan_irqs();
+
+	/*
+	 * let the primary processor know we're out of the
+	 * pen, then head off into the C entry point
+	 */
+	pen_release = -1;
+
+	/*
+	 * Synchronise with the boot thread.
+	 */
+	spin_lock(&boot_lock);
+	spin_unlock(&boot_lock);
+}
+
+int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+	unsigned long timeout;
+
+	/*
+	 * set synchronisation state between this boot processor
+	 * and the secondary one
+	 */
+	spin_lock(&boot_lock);
+
+	/*
+	 * The secondary processor is waiting to be released from
+	 * the holding pen - release it, then wait for it to flag
+	 * that it has been released by resetting pen_release.
+	 *
+	 * Note that "pen_release" is the hardware CPU ID, whereas
+	 * "cpu" is Linux's internal ID.
+	 */
+	pen_release = cpu;
+	flush_cache_all();
+
+	/*
+	 * XXX
+	 *
+	 * This is a later addition to the booting protocol: the
+	 * bootMonitor now puts secondary cores into WFI, so
+	 * poke_milo() no longer gets the cores moving; we need
+	 * to send a soft interrupt to wake the secondary core.
+	 * Use smp_cross_call() for this, since there's little
+	 * point duplicating the code here
+	 */
+	smp_cross_call(cpumask_of_cpu(cpu));
+
+	timeout = jiffies + (1 * HZ);
+	while (time_before(jiffies, timeout)) {
+		if (pen_release == -1)
+			break;
+
+		udelay(10);
+	}
+
+	/*
+	 * now the secondary core is starting up let it run its
+	 * calibrations, then wait for it to finish
+	 */
+	spin_unlock(&boot_lock);
+
+	return pen_release != -1 ? -ENOSYS : 0;
+}
+
+static void __init poke_milo(void)
+{
+	extern void secondary_startup(void);
+
+	/* nobody is to be released from the pen yet */
+	pen_release = -1;
+
+	phys_pen_release = virt_to_phys(&pen_release);
+
+	/*
+	 * write the address of secondary startup into the system-wide
+	 * flags register, then clear the bottom two bits, which is what
+	 * BootMonitor is waiting for
+	 */
+#if 1
+#define CINTEGRATOR_HDR_FLAGSS_OFFSET 0x30
+	__raw_writel(virt_to_phys(integrator_secondary_startup),
+		     (IO_ADDRESS(INTEGRATOR_HDR_BASE) +
+		      CINTEGRATOR_HDR_FLAGSS_OFFSET));
+#define CINTEGRATOR_HDR_FLAGSC_OFFSET 0x34
+	__raw_writel(3,
+		     (IO_ADDRESS(INTEGRATOR_HDR_BASE) +
+		      CINTEGRATOR_HDR_FLAGSC_OFFSET));
+#endif
+
+	mb();
+}
+
+void __init smp_prepare_cpus(unsigned int max_cpus)
+{
+	unsigned int ncores = get_core_count();
+	unsigned int cpu = smp_processor_id();
+	int i;
+
+	/* sanity check */
+	if (ncores == 0) {
+		printk(KERN_ERR
+		       "Integrator/CP: strange CM count of 0? Default to 1\n");
+
+		ncores = 1;
+	}
+
+	if (ncores > NR_CPUS) {
+		printk(KERN_WARNING
+		       "Integrator/CP: no. of cores (%d) greater than configured "
+		       "maximum of %d - clipping\n",
+		       ncores, NR_CPUS);
+		ncores = NR_CPUS;
+	}
+
+	/*
+	 * start with some more config for the Boot CPU, now that
+	 * the world is a bit more alive (which was not the case
+	 * when smp_prepare_boot_cpu() was called)
+	 */
+	smp_store_cpu_info(cpu);
+
+	/*
+	 * are we trying to boot more cores than exist?
+	 */
+	if (max_cpus > ncores)
+		max_cpus = ncores;
+
+	/*
+	 * Initialise the possible/present maps.
+	 * cpu_possible_map describes the set of CPUs which may be present
+	 * cpu_present_map describes the set of CPUs populated
+	 */
+	for (i = 0; i < max_cpus; i++) {
+		cpu_set(i, cpu_possible_map);
+		cpu_set(i, cpu_present_map);
+	}
+
+	/*
+	 * Do we need any more CPUs? If so, then let them know where
+	 * to start. Note that, on modern versions of MILO, the "poke"
+	 * doesn't actually do anything until each individual core is
+	 * sent a soft interrupt to get it out of WFI
+	 */
+	if (max_cpus > 1)
+		poke_milo();
+}
diff --git a/arch/arm/mach-iop3xx/iop321-setup.c b/arch/arm/mach-iop3xx/iop321-setup.c
--- a/arch/arm/mach-iop3xx/iop321-setup.c
+++ b/arch/arm/mach-iop3xx/iop321-setup.c
@@ -146,23 +146,27 @@ extern void iop321_init_time(void);
 
 #if defined(CONFIG_ARCH_IQ80321)
 MACHINE_START(IQ80321, "Intel IQ80321")
-	MAINTAINER("Intel Corporation")
-	BOOT_MEM(PHYS_OFFSET, IQ80321_UART, IQ80321_UART)
-	MAPIO(iq80321_map_io)
-	INITIRQ(iop321_init_irq)
+	/* Maintainer: Intel Corporation */
+	.phys_ram	= PHYS_OFFSET,
+	.phys_io	= IQ80321_UART,
+	.io_pg_offst	= ((IQ80321_UART) >> 18) & 0xfffc,
+	.map_io		= iq80321_map_io,
+	.init_irq	= iop321_init_irq,
 	.timer		= &iop321_timer,
-    BOOT_PARAMS(0xa0000100)
-	INIT_MACHINE(iop32x_init)
+	.boot_params	= 0xa0000100,
+	.init_machine	= iop32x_init,
 MACHINE_END
 #elif defined(CONFIG_ARCH_IQ31244)
 MACHINE_START(IQ31244, "Intel IQ31244")
-    MAINTAINER("Intel Corp.")
-    BOOT_MEM(PHYS_OFFSET, IQ31244_UART, IQ31244_UART)
-    MAPIO(iq31244_map_io)
-    INITIRQ(iop321_init_irq)
+	/* Maintainer: Intel Corp. */
+	.phys_ram	= PHYS_OFFSET,
+	.phys_io	= IQ31244_UART,
+	.io_pg_offst	= ((IQ31244_UART) >> 18) & 0xfffc,
+	.map_io		= iq31244_map_io,
+	.init_irq	= iop321_init_irq,
 	.timer		= &iop321_timer,
-    BOOT_PARAMS(0xa0000100)
-	INIT_MACHINE(iop32x_init)
+	.boot_params	= 0xa0000100,
+	.init_machine	= iop32x_init,
 MACHINE_END
 #else
 #error No machine descriptor defined for this IOP3XX implementation
diff --git a/arch/arm/mach-iop3xx/iop321-time.c b/arch/arm/mach-iop3xx/iop321-time.c
--- a/arch/arm/mach-iop3xx/iop321-time.c
+++ b/arch/arm/mach-iop3xx/iop321-time.c
@@ -86,7 +86,7 @@ iop321_timer_interrupt(int irq, void *de
 static struct irqaction iop321_timer_irq = {
 	.name		= "IOP321 Timer Tick",
 	.handler	= iop321_timer_interrupt,
-	.flags		= SA_INTERRUPT
+	.flags		= SA_INTERRUPT | SA_TIMER,
 };
 
 static void __init iop321_timer_init(void)
diff --git a/arch/arm/mach-iop3xx/iop331-setup.c b/arch/arm/mach-iop3xx/iop331-setup.c
--- a/arch/arm/mach-iop3xx/iop331-setup.c
+++ b/arch/arm/mach-iop3xx/iop331-setup.c
@@ -148,26 +148,28 @@ extern void iq80332_map_io(void);
 
 #if defined(CONFIG_ARCH_IQ80331)
 MACHINE_START(IQ80331, "Intel IQ80331")
-    MAINTAINER("Intel Corp.")
-    BOOT_MEM(PHYS_OFFSET, 0xfefff000, 0xfffff000) // virtual, physical
-    //BOOT_MEM(PHYS_OFFSET, IOP331_UART0_VIRT, IOP331_UART0_PHYS)
-    MAPIO(iq80331_map_io)
-    INITIRQ(iop331_init_irq)
+	/* Maintainer: Intel Corp. */
+	.phys_ram	= PHYS_OFFSET,
+	.phys_io	= 0xfefff000,
+	.io_pg_offst	= ((0xfffff000) >> 18) & 0xfffc, // virtual, physical
+	.map_io		= iq80331_map_io,
+	.init_irq	= iop331_init_irq,
 	.timer		= &iop331_timer,
-    BOOT_PARAMS(0x0100)
-	INIT_MACHINE(iop33x_init)
+	.boot_params	= 0x0100,
+	.init_machine	= iop33x_init,
 MACHINE_END
 
 #elif defined(CONFIG_MACH_IQ80332)
 MACHINE_START(IQ80332, "Intel IQ80332")
-    MAINTAINER("Intel Corp.")
-    BOOT_MEM(PHYS_OFFSET, 0xfefff000, 0xfffff000) // virtual, physical
-    //BOOT_MEM(PHYS_OFFSET, IOP331_UART0_VIRT, IOP331_UART0_PHYS)
-    MAPIO(iq80332_map_io)
-    INITIRQ(iop331_init_irq)
+	/* Maintainer: Intel Corp. */
+	.phys_ram	= PHYS_OFFSET,
+	.phys_io	= 0xfefff000,
+	.io_pg_offst	= ((0xfffff000) >> 18) & 0xfffc, // virtual, physical
+	.map_io		= iq80332_map_io,
+	.init_irq	= iop331_init_irq,
 	.timer		= &iop331_timer,
-    BOOT_PARAMS(0x0100)
-	INIT_MACHINE(iop33x_init)
+	.boot_params	= 0x0100,
+	.init_machine	= iop33x_init,
 MACHINE_END
 
 #else
diff --git a/arch/arm/mach-iop3xx/iop331-time.c b/arch/arm/mach-iop3xx/iop331-time.c
--- a/arch/arm/mach-iop3xx/iop331-time.c
+++ b/arch/arm/mach-iop3xx/iop331-time.c
@@ -83,7 +83,7 @@ iop331_timer_interrupt(int irq, void *de
 static struct irqaction iop331_timer_irq = {
 	.name		= "IOP331 Timer Tick",
 	.handler	= iop331_timer_interrupt,
-	.flags		= SA_INTERRUPT
+	.flags		= SA_INTERRUPT | SA_TIMER,
 };
 
 static void __init iop331_timer_init(void)
diff --git a/arch/arm/mach-ixp2000/Kconfig b/arch/arm/mach-ixp2000/Kconfig
--- a/arch/arm/mach-ixp2000/Kconfig
+++ b/arch/arm/mach-ixp2000/Kconfig
@@ -54,6 +54,14 @@ config ARCH_IXDP2X01
 	depends on ARCH_IXDP2401 || ARCH_IXDP2801
 	default y	
 
+config IXP2000_SUPPORT_BROKEN_PCI_IO
+	bool "Support broken PCI I/O on older IXP2000s"
+	default y
+	help
+	  Say 'N' here if you only intend to run your kernel on an
+	  IXP2000 B0 or later model and do not need the PCI I/O
+	  byteswap workaround.  Say 'Y' otherwise.
+
 endmenu
 
 endif
diff --git a/arch/arm/mach-ixp2000/core.c b/arch/arm/mach-ixp2000/core.c
--- a/arch/arm/mach-ixp2000/core.c
+++ b/arch/arm/mach-ixp2000/core.c
@@ -23,7 +23,7 @@
 #include <linux/serial.h>
 #include <linux/tty.h>
 #include <linux/bitops.h>
-#include <linux/serial_core.h>
+#include <linux/serial_8250.h>
 #include <linux/mm.h>
 
 #include <asm/types.h>
@@ -40,6 +40,8 @@
 #include <asm/mach/time.h>
 #include <asm/mach/irq.h>
 
+#include <asm/arch/gpio.h>
+
 static DEFINE_SPINLOCK(ixp2000_slowport_lock);
 static unsigned long ixp2000_slowport_irq_flags;
 
@@ -101,6 +103,11 @@ static struct map_desc ixp2000_io_desc[]
 		.length		= IXP2000_PCI_CSR_SIZE,
 		.type		= MT_DEVICE
 	}, {
+		.virtual	= IXP2000_MSF_VIRT_BASE,
+		.physical	= IXP2000_MSF_PHYS_BASE,
+		.length		= IXP2000_MSF_SIZE,
+		.type		= MT_DEVICE
+	}, {
 		.virtual	= IXP2000_PCI_IO_VIRT_BASE,
 		.physical	= IXP2000_PCI_IO_PHYS_BASE,
 		.length		= IXP2000_PCI_IO_SIZE,
@@ -118,19 +125,6 @@ static struct map_desc ixp2000_io_desc[]
 	}
 };
 
-static struct uart_port ixp2000_serial_port = {
-	.membase	= (char *)(IXP2000_UART_VIRT_BASE + 3),
-	.mapbase	= IXP2000_UART_PHYS_BASE + 3,
-	.irq		= IRQ_IXP2000_UART,
-	.flags		= UPF_SKIP_TEST,
-	.iotype		= UPIO_MEM,
-	.regshift	= 2,
-	.uartclk	= 50000000,
-	.line		= 0,
-	.type		= PORT_XSCALE,
-	.fifosize	= 16
-};
-
 void __init ixp2000_map_io(void)
 {
 	extern unsigned int processor_id;
@@ -150,24 +144,63 @@ void __init ixp2000_map_io(void)
 	}
 
 	iotable_init(ixp2000_io_desc, ARRAY_SIZE(ixp2000_io_desc));
-	early_serial_setup(&ixp2000_serial_port);
 
 	/* Set slowport to 8-bit mode.  */
 	ixp2000_reg_write(IXP2000_SLOWPORT_FRM, 1);
 }
 
+
+/*************************************************************************
+ * Serial port support for IXP2000
+ *************************************************************************/
+static struct plat_serial8250_port ixp2000_serial_port[] = {
+	{
+		.mapbase	= IXP2000_UART_PHYS_BASE,
+		.membase	= (char *)(IXP2000_UART_VIRT_BASE + 3),
+		.irq		= IRQ_IXP2000_UART,
+		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+		.iotype		= UPIO_MEM,
+		.regshift	= 2,
+		.uartclk	= 50000000,
+	},
+	{ },
+};
+
+static struct resource ixp2000_uart_resource = {
+	.start		= IXP2000_UART_PHYS_BASE,
+	.end		= IXP2000_UART_PHYS_BASE + 0xffff,
+	.flags		= IORESOURCE_MEM,
+};
+
+static struct platform_device ixp2000_serial_device = {
+	.name		= "serial8250",
+	.id		= 0,
+	.dev		= {
+		.platform_data		= ixp2000_serial_port,
+	},
+	.num_resources	= 1,
+	.resource	= &ixp2000_uart_resource,
+};
+
+void __init ixp2000_uart_init(void)
+{
+	platform_device_register(&ixp2000_serial_device);
+}
+
+
 /*************************************************************************
  * Timer-tick functions for IXP2000
  *************************************************************************/
 static unsigned ticks_per_jiffy;
 static unsigned ticks_per_usec;
 static unsigned next_jiffy_time;
+static volatile unsigned long *missing_jiffy_timer_csr;
 
 unsigned long ixp2000_gettimeoffset (void)
 {
  	unsigned long offset;
 
-	offset = next_jiffy_time - *IXP2000_T4_CSR;
+	offset = next_jiffy_time - *missing_jiffy_timer_csr;
 
 	return offset / ticks_per_usec;
 }
@@ -178,8 +211,8 @@ static int ixp2000_timer_interrupt(int i
 
 	/* clear timer 1 */
 	ixp2000_reg_write(IXP2000_T1_CLR, 1);
-	
-	while ((next_jiffy_time - *IXP2000_T4_CSR) > ticks_per_jiffy) {
+
+	while ((next_jiffy_time - *missing_jiffy_timer_csr) > ticks_per_jiffy) {
 		timer_tick(regs);
 		next_jiffy_time -= ticks_per_jiffy;
 	}
@@ -191,26 +224,43 @@ static int ixp2000_timer_interrupt(int i
 
 static struct irqaction ixp2000_timer_irq = {
 	.name		= "IXP2000 Timer Tick",
-	.flags		= SA_INTERRUPT,
-	.handler	= ixp2000_timer_interrupt
+	.flags		= SA_INTERRUPT | SA_TIMER,
+	.handler	= ixp2000_timer_interrupt,
 };
 
 void __init ixp2000_init_time(unsigned long tick_rate)
 {
-	ixp2000_reg_write(IXP2000_T1_CLR, 0);
-	ixp2000_reg_write(IXP2000_T4_CLR, 0);
-
 	ticks_per_jiffy = (tick_rate + HZ/2) / HZ;
 	ticks_per_usec = tick_rate / 1000000;
 
+	/*
+	 * We use timer 1 as our timer interrupt.
+	 */
+	ixp2000_reg_write(IXP2000_T1_CLR, 0);
 	ixp2000_reg_write(IXP2000_T1_CLD, ticks_per_jiffy - 1);
 	ixp2000_reg_write(IXP2000_T1_CTL, (1 << 7));
 
 	/*
-	 * We use T4 as a monotonic counter to track missed jiffies
+	 * We use a second timer as a monotonic counter for tracking
+	 * missed jiffies.  The IXP2000 has four timers, but if we're
+	 * on an A-step IXP2800, timer 2 and 3 don't work, so on those
+	 * chips we use timer 4.  Timer 4 is the only timer that can
+	 * be used for the watchdog, so we use timer 2 if we're on a
+	 * non-buggy chip.
 	 */
-	ixp2000_reg_write(IXP2000_T4_CLD, -1);
-	ixp2000_reg_write(IXP2000_T4_CTL, (1 << 7));
+	if ((*IXP2000_PRODUCT_ID & 0x001ffef0) == 0x00000000) {
+		printk(KERN_INFO "Enabling IXP2800 erratum #25 workaround\n");
+
+		ixp2000_reg_write(IXP2000_T4_CLR, 0);
+		ixp2000_reg_write(IXP2000_T4_CLD, -1);
+		ixp2000_reg_write(IXP2000_T4_CTL, (1 << 7));
+		missing_jiffy_timer_csr = IXP2000_T4_CSR;
+	} else {
+		ixp2000_reg_write(IXP2000_T2_CLR, 0);
+		ixp2000_reg_write(IXP2000_T2_CLD, -1);
+		ixp2000_reg_write(IXP2000_T2_CTL, (1 << 7));
+		missing_jiffy_timer_csr = IXP2000_T2_CSR;
+	}
  	next_jiffy_time = 0xffffffff;
 
 	/* register for interrupt */
@@ -220,35 +270,40 @@ void __init ixp2000_init_time(unsigned l
 /*************************************************************************
  * GPIO helpers
  *************************************************************************/
-static unsigned long GPIO_IRQ_rising_edge;
 static unsigned long GPIO_IRQ_falling_edge;
+static unsigned long GPIO_IRQ_rising_edge;
 static unsigned long GPIO_IRQ_level_low;
 static unsigned long GPIO_IRQ_level_high;
 
-void gpio_line_config(int line, int style)
+static void update_gpio_int_csrs(void)
+{
+	ixp2000_reg_write(IXP2000_GPIO_FEDR, GPIO_IRQ_falling_edge);
+	ixp2000_reg_write(IXP2000_GPIO_REDR, GPIO_IRQ_rising_edge);
+	ixp2000_reg_write(IXP2000_GPIO_LSLR, GPIO_IRQ_level_low);
+	ixp2000_reg_write(IXP2000_GPIO_LSHR, GPIO_IRQ_level_high);
+}
+
+void gpio_line_config(int line, int direction)
 {
 	unsigned long flags;
 
 	local_irq_save(flags);
+	if (direction == GPIO_OUT) {
+		irq_desc[line + IRQ_IXP2000_GPIO0].valid = 0;
 
-	if(style == GPIO_OUT) {
 		/* if it's an output, it ain't an interrupt anymore */
-		ixp2000_reg_write(IXP2000_GPIO_PDSR, (1 << line));
 		GPIO_IRQ_falling_edge &= ~(1 << line);
 		GPIO_IRQ_rising_edge &= ~(1 << line);
 		GPIO_IRQ_level_low &= ~(1 << line);
 		GPIO_IRQ_level_high &= ~(1 << line);
-		ixp2000_reg_write(IXP2000_GPIO_FEDR, GPIO_IRQ_falling_edge);
-		ixp2000_reg_write(IXP2000_GPIO_REDR, GPIO_IRQ_rising_edge);
-		ixp2000_reg_write(IXP2000_GPIO_LSHR, GPIO_IRQ_level_high);
-		ixp2000_reg_write(IXP2000_GPIO_LSLR, GPIO_IRQ_level_low);
-		irq_desc[line+IRQ_IXP2000_GPIO0].valid = 0;
-	} else if(style == GPIO_IN) {
-		ixp2000_reg_write(IXP2000_GPIO_PDCR, (1 << line));
+		update_gpio_int_csrs();
+
+		ixp2000_reg_write(IXP2000_GPIO_PDSR, 1 << line);
+	} else if (direction == GPIO_IN) {
+		ixp2000_reg_write(IXP2000_GPIO_PDCR, 1 << line);
 	}
-		
 	local_irq_restore(flags);
-}	
+}
 
 
 /*************************************************************************
@@ -267,9 +322,50 @@ static void ixp2000_GPIO_irq_handler(uns
 	}
 }
 
+static int ixp2000_GPIO_irq_type(unsigned int irq, unsigned int type)
+{
+	int line = irq - IRQ_IXP2000_GPIO0;
+
+	/*
+	 * First, configure this GPIO line as an input.
+	 */
+	ixp2000_reg_write(IXP2000_GPIO_PDCR, 1 << line);
+
+	/*
+	 * Then, set the proper trigger type.
+	 */
+	if (type & IRQT_FALLING)
+		GPIO_IRQ_falling_edge |= 1 << line;
+	else
+		GPIO_IRQ_falling_edge &= ~(1 << line);
+	if (type & IRQT_RISING)
+		GPIO_IRQ_rising_edge |= 1 << line;
+	else
+		GPIO_IRQ_rising_edge &= ~(1 << line);
+	if (type & IRQT_LOW)
+		GPIO_IRQ_level_low |= 1 << line;
+	else
+		GPIO_IRQ_level_low &= ~(1 << line);
+	if (type & IRQT_HIGH)
+		GPIO_IRQ_level_high |= 1 << line;
+	else
+		GPIO_IRQ_level_high &= ~(1 << line);
+	update_gpio_int_csrs();
+
+	/*
+	 * Finally, mark the corresponding IRQ as valid.
+	 */
+	irq_desc[irq].valid = 1;
+
+	return 0;
+}
+
 static void ixp2000_GPIO_irq_mask_ack(unsigned int irq)
 {
 	ixp2000_reg_write(IXP2000_GPIO_INCR, (1 << (irq - IRQ_IXP2000_GPIO0)));
+
+	ixp2000_reg_write(IXP2000_GPIO_EDSR, (1 << (irq - IRQ_IXP2000_GPIO0)));
+	ixp2000_reg_write(IXP2000_GPIO_LDSR, (1 << (irq - IRQ_IXP2000_GPIO0)));
 	ixp2000_reg_write(IXP2000_GPIO_INST, (1 << (irq - IRQ_IXP2000_GPIO0)));
 }
 
@@ -284,6 +380,7 @@ static void ixp2000_GPIO_irq_unmask(unsi
 }
 
 static struct irqchip ixp2000_GPIO_irq_chip = {
+	.type	= ixp2000_GPIO_irq_type,
 	.ack	= ixp2000_GPIO_irq_mask_ack,
 	.mask	= ixp2000_GPIO_irq_mask,
 	.unmask	= ixp2000_GPIO_irq_unmask
@@ -320,7 +417,7 @@ static void ixp2000_irq_mask(unsigned in
 
 static void ixp2000_irq_unmask(unsigned int irq)
 {
-	ixp2000_reg_write(IXP2000_IRQ_ENABLE_SET,  (1 << irq));
+	ixp2000_reg_write(IXP2000_IRQ_ENABLE_SET, (1 << irq));
 }
 
 static struct irqchip ixp2000_irq_chip = {
@@ -357,16 +454,16 @@ void __init ixp2000_init_irq(void)
 	 * our mask/unmask code much simpler.
 	 */
 	for (irq = IRQ_IXP2000_SOFT_INT; irq <= IRQ_IXP2000_THDB3; irq++) {
-		if((1 << irq) & IXP2000_VALID_IRQ_MASK) {
+		if ((1 << irq) & IXP2000_VALID_IRQ_MASK) {
 			set_irq_chip(irq, &ixp2000_irq_chip);
 			set_irq_handler(irq, do_level_IRQ);
 			set_irq_flags(irq, IRQF_VALID);
 		} else set_irq_flags(irq, 0);
 	}
-	
+
 	/*
 	 * GPIO IRQs are invalid until someone sets the interrupt mode
-	 * by calling gpio_line_set();
+	 * by calling set_irq_type().
 	 */
 	for (irq = IRQ_IXP2000_GPIO0; irq <= IRQ_IXP2000_GPIO7; irq++) {
 		set_irq_chip(irq, &ixp2000_GPIO_irq_chip);
diff --git a/arch/arm/mach-ixp2000/enp2611.c b/arch/arm/mach-ixp2000/enp2611.c
--- a/arch/arm/mach-ixp2000/enp2611.c
+++ b/arch/arm/mach-ixp2000/enp2611.c
@@ -197,24 +197,42 @@ static struct platform_device enp2611_fl
 	.resource	= &enp2611_flash_resource,
 };
 
+static struct ixp2000_i2c_pins enp2611_i2c_gpio_pins = {
+	.sda_pin	= ENP2611_GPIO_SDA,
+	.scl_pin	= ENP2611_GPIO_SCL,
+};
+
+static struct platform_device enp2611_i2c_controller = {
+	.name		= "IXP2000-I2C",
+	.id		= 0,
+	.dev		= {
+		.platform_data = &enp2611_i2c_gpio_pins
+	},
+	.num_resources	= 0
+};
+
 static struct platform_device *enp2611_devices[] __initdata = {
-	&enp2611_flash
+	&enp2611_flash,
+	&enp2611_i2c_controller
 };
 
 static void __init enp2611_init_machine(void)
 {
 	platform_add_devices(enp2611_devices, ARRAY_SIZE(enp2611_devices));
+	ixp2000_uart_init();
 }
 
 
 MACHINE_START(ENP2611, "Radisys ENP-2611 PCI network processor board")
-	MAINTAINER("Lennert Buytenhek <buytenh@wantstofly.org>")
-	BOOT_MEM(0x00000000, IXP2000_UART_PHYS_BASE, IXP2000_UART_VIRT_BASE)
-	BOOT_PARAMS(0x00000100)
-	MAPIO(ixp2000_map_io)
-	INITIRQ(ixp2000_init_irq)
+	/* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */
+	.phys_ram	= 0x00000000,
+	.phys_io	= IXP2000_UART_PHYS_BASE,
+	.io_pg_offst	= ((IXP2000_UART_VIRT_BASE) >> 18) & 0xfffc,
+	.boot_params	= 0x00000100,
+	.map_io		= ixp2000_map_io,
+	.init_irq	= ixp2000_init_irq,
 	.timer		= &enp2611_timer,
-	INIT_MACHINE(enp2611_init_machine)
+	.init_machine	= enp2611_init_machine,
 MACHINE_END
 
 
diff --git a/arch/arm/mach-ixp2000/ixdp2400.c b/arch/arm/mach-ixp2000/ixdp2400.c
--- a/arch/arm/mach-ixp2000/ixdp2400.c
+++ b/arch/arm/mach-ixp2000/ixdp2400.c
@@ -168,12 +168,14 @@ void ixdp2400_init_irq(void)
 }
 
 MACHINE_START(IXDP2400, "Intel IXDP2400 Development Platform")
-	MAINTAINER("MontaVista Software, Inc.")
-	BOOT_MEM(0x00000000, IXP2000_UART_PHYS_BASE, IXP2000_UART_VIRT_BASE)
-	BOOT_PARAMS(0x00000100)
-	MAPIO(ixdp2x00_map_io)
-	INITIRQ(ixdp2400_init_irq)
+	/* Maintainer: MontaVista Software, Inc. */
+	.phys_ram	= 0x00000000,
+	.phys_io	= IXP2000_UART_PHYS_BASE,
+	.io_pg_offst	= ((IXP2000_UART_VIRT_BASE) >> 18) & 0xfffc,
+	.boot_params	= 0x00000100,
+	.map_io		= ixdp2x00_map_io,
+	.init_irq	= ixdp2400_init_irq,
 	.timer		= &ixdp2400_timer,
-	INIT_MACHINE(ixdp2x00_init_machine)
+	.init_machine	= ixdp2x00_init_machine,
 MACHINE_END
 
diff --git a/arch/arm/mach-ixp2000/ixdp2800.c b/arch/arm/mach-ixp2000/ixdp2800.c
--- a/arch/arm/mach-ixp2000/ixdp2800.c
+++ b/arch/arm/mach-ixp2000/ixdp2800.c
@@ -42,12 +42,6 @@
 #include <asm/mach/flash.h>
 #include <asm/mach/arch.h>
 
-
-void ixdp2400_init_irq(void)
-{
-	ixdp2x00_init_irq(IXDP2800_CPLD_INT_STAT, IXDP2800_CPLD_INT_MASK, IXDP2400_NR_IRQS);
-}
-
 /*************************************************************************
  * IXDP2800 timer tick
  *************************************************************************/
@@ -290,12 +284,14 @@ void ixdp2800_init_irq(void)
 }
 
 MACHINE_START(IXDP2800, "Intel IXDP2800 Development Platform")
-	MAINTAINER("MontaVista Software, Inc.")
-	BOOT_MEM(0x00000000, IXP2000_UART_PHYS_BASE, IXP2000_UART_VIRT_BASE)
-	BOOT_PARAMS(0x00000100)
-	MAPIO(ixdp2x00_map_io)
-	INITIRQ(ixdp2800_init_irq)
+	/* Maintainer: MontaVista Software, Inc. */
+	.phys_ram	= 0x00000000,
+	.phys_io	= IXP2000_UART_PHYS_BASE,
+	.io_pg_offst	= ((IXP2000_UART_VIRT_BASE) >> 18) & 0xfffc,
+	.boot_params	= 0x00000100,
+	.map_io		= ixdp2x00_map_io,
+	.init_irq	= ixdp2800_init_irq,
 	.timer		= &ixdp2800_timer,
-	INIT_MACHINE(ixdp2x00_init_machine)
+	.init_machine	= ixdp2x00_init_machine,
 MACHINE_END
 
diff --git a/arch/arm/mach-ixp2000/ixdp2x00.c b/arch/arm/mach-ixp2000/ixdp2x00.c
--- a/arch/arm/mach-ixp2000/ixdp2x00.c
+++ b/arch/arm/mach-ixp2000/ixdp2x00.c
@@ -42,6 +42,9 @@
 #include <asm/mach/flash.h>
 #include <asm/mach/arch.h>
 
+#include <asm/arch/gpio.h>
+
+
 /*************************************************************************
  * IXDP2x00 IRQ Initialization
  *************************************************************************/
@@ -300,5 +303,6 @@ void __init ixdp2x00_init_machine(void)
 	gpio_line_config(IXDP2X00_GPIO_I2C_ENABLE, GPIO_OUT);
 
 	platform_add_devices(ixdp2x00_devices, ARRAY_SIZE(ixdp2x00_devices));
+	ixp2000_uart_init();
 }
 
diff --git a/arch/arm/mach-ixp2000/ixdp2x01.c b/arch/arm/mach-ixp2000/ixdp2x01.c
--- a/arch/arm/mach-ixp2000/ixdp2x01.c
+++ b/arch/arm/mach-ixp2000/ixdp2x01.c
@@ -370,30 +370,35 @@ static void __init ixdp2x01_init_machine
 		((*IXDP2X01_CPLD_FLASH_REG & IXDP2X01_CPLD_FLASH_BANK_MASK) + 1);
 
 	platform_add_devices(ixdp2x01_devices, ARRAY_SIZE(ixdp2x01_devices));
+	ixp2000_uart_init();
 }
 
 
 #ifdef CONFIG_ARCH_IXDP2401
 MACHINE_START(IXDP2401, "Intel IXDP2401 Development Platform")
-	MAINTAINER("MontaVista Software, Inc.")
-	BOOT_MEM(0x00000000, IXP2000_UART_PHYS_BASE, IXP2000_UART_VIRT_BASE)
-	BOOT_PARAMS(0x00000100)
-	MAPIO(ixdp2x01_map_io)
-	INITIRQ(ixdp2x01_init_irq)
+	/* Maintainer: MontaVista Software, Inc. */
+	.phys_ram	= 0x00000000,
+	.phys_io	= IXP2000_UART_PHYS_BASE,
+	.io_pg_offst	= ((IXP2000_UART_VIRT_BASE) >> 18) & 0xfffc,
+	.boot_params	= 0x00000100,
+	.map_io		= ixdp2x01_map_io,
+	.init_irq	= ixdp2x01_init_irq,
 	.timer		= &ixdp2x01_timer,
-	INIT_MACHINE(ixdp2x01_init_machine)
+	.init_machine	= ixdp2x01_init_machine,
 MACHINE_END
 #endif
 
 #ifdef CONFIG_ARCH_IXDP2801
 MACHINE_START(IXDP2801, "Intel IXDP2801 Development Platform")
-	MAINTAINER("MontaVista Software, Inc.")
-	BOOT_MEM(0x00000000, IXP2000_UART_PHYS_BASE, IXP2000_UART_VIRT_BASE)
-	BOOT_PARAMS(0x00000100)
-	MAPIO(ixdp2x01_map_io)
-	INITIRQ(ixdp2x01_init_irq)
+	/* Maintainer: MontaVista Software, Inc. */
+	.phys_ram	= 0x00000000,
+	.phys_io	= IXP2000_UART_PHYS_BASE,
+	.io_pg_offst	= ((IXP2000_UART_VIRT_BASE) >> 18) & 0xfffc,
+	.boot_params	= 0x00000100,
+	.map_io		= ixdp2x01_map_io,
+	.init_irq	= ixdp2x01_init_irq,
 	.timer		= &ixdp2x01_timer,
-	INIT_MACHINE(ixdp2x01_init_machine)
+	.init_machine	= ixdp2x01_init_machine,
 MACHINE_END
 #endif
 
diff --git a/arch/arm/mach-ixp2000/pci.c b/arch/arm/mach-ixp2000/pci.c
--- a/arch/arm/mach-ixp2000/pci.c
+++ b/arch/arm/mach-ixp2000/pci.c
@@ -198,6 +198,19 @@ clear_master_aborts(void)
 void __init
 ixp2000_pci_preinit(void)
 {
+#ifndef CONFIG_IXP2000_SUPPORT_BROKEN_PCI_IO
+	/*
+	 * Configure the PCI unit to properly byteswap I/O transactions,
+	 * and verify that it worked.
+	 */
+	ixp2000_reg_write(IXP2000_PCI_CONTROL,
+			  (*IXP2000_PCI_CONTROL | PCI_CONTROL_IEE));
+
+	if ((*IXP2000_PCI_CONTROL & PCI_CONTROL_IEE) == 0)
+		panic("IXP2000: PCI I/O is broken on this ixp model, and "
+			"the needed workaround has not been configured in");
+#endif
+
 	hook_fault_code(16+6, ixp2000_pci_abort_handler, SIGBUS,
 				"PCI config cycle to non-existent device");
 }
diff --git a/arch/arm/mach-ixp4xx/common-pci.c b/arch/arm/mach-ixp4xx/common-pci.c
--- a/arch/arm/mach-ixp4xx/common-pci.c
+++ b/arch/arm/mach-ixp4xx/common-pci.c
@@ -453,8 +453,8 @@ int ixp4xx_setup(int nr, struct pci_sys_
 	local_write_config(PCI_COMMAND, 2, PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
 
 	res[0].name = "PCI I/O Space";
-	res[0].start = 0x00001000;
-	res[0].end = 0xffff0000;
+	res[0].start = 0x00000000;
+	res[0].end = 0x0000ffff;
 	res[0].flags = IORESOURCE_IO;
 
 	res[1].name = "PCI Memory Space";
diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c
--- a/arch/arm/mach-ixp4xx/common.c
+++ b/arch/arm/mach-ixp4xx/common.c
@@ -141,7 +141,15 @@ static struct map_desc ixp4xx_io_desc[] 
 		.physical	= IXP4XX_PCI_CFG_BASE_PHYS,
 		.length		= IXP4XX_PCI_CFG_REGION_SIZE,
 		.type		= MT_DEVICE
+	},
+#ifdef CONFIG_DEBUG_LL
+	{	/* Debug UART mapping */
+		.virtual	= IXP4XX_DEBUG_UART_BASE_VIRT,
+		.physical	= IXP4XX_DEBUG_UART_BASE_PHYS,
+		.length		= IXP4XX_DEBUG_UART_REGION_SIZE,
+		.type		= MT_DEVICE
 	}
+#endif
 };
 
 void __init ixp4xx_map_io(void)
@@ -290,8 +298,8 @@ static irqreturn_t ixp4xx_timer_interrup
 
 static struct irqaction ixp4xx_timer_irq = {
 	.name		= "IXP4xx Timer Tick",
-	.flags		= SA_INTERRUPT,
-	.handler	= ixp4xx_timer_interrupt
+	.flags		= SA_INTERRUPT | SA_TIMER,
+	.handler	= ixp4xx_timer_interrupt,
 };
 
 static void __init ixp4xx_timer_init(void)
diff --git a/arch/arm/mach-ixp4xx/coyote-setup.c b/arch/arm/mach-ixp4xx/coyote-setup.c
--- a/arch/arm/mach-ixp4xx/coyote-setup.c
+++ b/arch/arm/mach-ixp4xx/coyote-setup.c
@@ -36,7 +36,7 @@ static struct flash_platform_data coyote
 
 static struct resource coyote_flash_resource = {
 	.start		= COYOTE_FLASH_BASE,
-	.end		= COYOTE_FLASH_BASE + COYOTE_FLASH_SIZE,
+	.end		= COYOTE_FLASH_BASE + COYOTE_FLASH_SIZE - 1,
 	.flags		= IORESOURCE_MEM,
 };
 
@@ -56,21 +56,24 @@ static struct resource coyote_uart_resou
 	.flags	= IORESOURCE_MEM,
 };
 
-static struct plat_serial8250_port coyote_uart_data = {
-	.mapbase	= IXP4XX_UART2_BASE_PHYS,
-	.membase	= (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET,
-	.irq		= IRQ_IXP4XX_UART2,
-	.flags		= UPF_BOOT_AUTOCONF,
-	.iotype		= UPIO_MEM,
-	.regshift	= 2,
-	.uartclk	= IXP4XX_UART_XTAL,
+static struct plat_serial8250_port coyote_uart_data[] = {
+	{
+		.mapbase	= IXP4XX_UART2_BASE_PHYS,
+		.membase	= (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET,
+		.irq		= IRQ_IXP4XX_UART2,
+		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+		.iotype		= UPIO_MEM,
+		.regshift	= 2,
+		.uartclk	= IXP4XX_UART_XTAL,
+	},
+	{ },
 };
 
 static struct platform_device coyote_uart = {
 	.name		= "serial8250",
 	.id		= 0,
 	.dev			= {
-		.platform_data	= &coyote_uart_data,
+		.platform_data	= coyote_uart_data,
 	},
 	.num_resources	= 1,
 	.resource	= &coyote_uart_resource,
@@ -87,10 +90,10 @@ static void __init coyote_init(void)
 	*IXP4XX_EXP_CS1 = *IXP4XX_EXP_CS0;
 
 	if (machine_is_ixdpg425()) {
-		coyote_uart_data.membase =
+		coyote_uart_data[0].membase =
 			(char*)(IXP4XX_UART1_BASE_VIRT + REG_OFFSET);
-		coyote_uart_data.mapbase = IXP4XX_UART1_BASE_PHYS;
-		coyote_uart_data.irq = IRQ_IXP4XX_UART1;
+		coyote_uart_data[0].mapbase = IXP4XX_UART1_BASE_PHYS;
+		coyote_uart_data[0].irq = IRQ_IXP4XX_UART1;
 	}
 
 
@@ -100,14 +103,15 @@ static void __init coyote_init(void)
 
 #ifdef CONFIG_ARCH_ADI_COYOTE
 MACHINE_START(ADI_COYOTE, "ADI Engineering Coyote")
-        MAINTAINER("MontaVista Software, Inc.")
-        BOOT_MEM(PHYS_OFFSET, IXP4XX_PERIPHERAL_BASE_PHYS,
-                IXP4XX_PERIPHERAL_BASE_VIRT)
-        MAPIO(coyote_map_io)
-        INITIRQ(ixp4xx_init_irq)
+	/* Maintainer: MontaVista Software, Inc. */
+	.phys_ram	= PHYS_OFFSET,
+	.phys_io	= IXP4XX_PERIPHERAL_BASE_PHYS,
+	.io_pg_offst	= ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc,
+	.map_io		= coyote_map_io,
+	.init_irq	= ixp4xx_init_irq,
 	.timer		= &ixp4xx_timer,
-        BOOT_PARAMS(0x0100)
-	INIT_MACHINE(coyote_init)
+	.boot_params	= 0x0100,
+	.init_machine	= coyote_init,
 MACHINE_END
 #endif
 
@@ -117,14 +121,15 @@ MACHINE_END
  */
 #ifdef CONFIG_MACH_IXDPG425
 MACHINE_START(IXDPG425, "Intel IXDPG425")
-        MAINTAINER("MontaVista Software, Inc.")
-        BOOT_MEM(PHYS_OFFSET, IXP4XX_PERIPHERAL_BASE_PHYS,
-                IXP4XX_PERIPHERAL_BASE_VIRT)
-        MAPIO(coyote_map_io)
-        INITIRQ(ixp4xx_init_irq)
+	/* Maintainer: MontaVista Software, Inc. */
+	.phys_ram	= PHYS_OFFSET,
+	.phys_io	= IXP4XX_PERIPHERAL_BASE_PHYS,
+	.io_pg_offst	= ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc,
+	.map_io		= coyote_map_io,
+	.init_irq	= ixp4xx_init_irq,
 	.timer		= &ixp4xx_timer,
-        BOOT_PARAMS(0x0100)
-	INIT_MACHINE(coyote_init)
+	.boot_params	= 0x0100,
+	.init_machine	= coyote_init,
 MACHINE_END
 #endif
 
diff --git a/arch/arm/mach-ixp4xx/gtwx5715-setup.c b/arch/arm/mach-ixp4xx/gtwx5715-setup.c
--- a/arch/arm/mach-ixp4xx/gtwx5715-setup.c
+++ b/arch/arm/mach-ixp4xx/gtwx5715-setup.c
@@ -83,7 +83,7 @@ static struct plat_serial8250_port gtwx5
 	.mapbase	= IXP4XX_UART2_BASE_PHYS,
 	.membase	= (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET,
 	.irq		= IRQ_IXP4XX_UART2,
-	.flags		= UPF_BOOT_AUTOCONF,
+	.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
 	.iotype		= UPIO_MEM,
 	.regshift	= 2,
 	.uartclk	= IXP4XX_UART_XTAL,
@@ -114,7 +114,7 @@ static struct flash_platform_data gtwx57
 
 static struct resource gtwx5715_flash_resource = {
 	.start		= GTWX5715_FLASH_BASE,
-	.end		= GTWX5715_FLASH_BASE + GTWX5715_FLASH_SIZE,
+	.end		= GTWX5715_FLASH_BASE + GTWX5715_FLASH_SIZE - 1,
 	.flags		= IORESOURCE_MEM,
 };
 
@@ -140,14 +140,15 @@ static void __init gtwx5715_init(void)
 
 
 MACHINE_START(GTWX5715, "Gemtek GTWX5715 (Linksys WRV54G)")
-        MAINTAINER("George Joseph")
-        BOOT_MEM(PHYS_OFFSET, IXP4XX_UART2_BASE_PHYS,
-                IXP4XX_UART2_BASE_VIRT)
-        MAPIO(gtwx5715_map_io)
-        INITIRQ(ixp4xx_init_irq)
-		  .timer		= &ixp4xx_timer,
-        BOOT_PARAMS(0x0100)
-        INIT_MACHINE(gtwx5715_init)
+	/* Maintainer: George Joseph */
+	.phys_ram	= PHYS_OFFSET,
+	.phys_io	= IXP4XX_UART2_BASE_PHYS,
+	.io_pg_offst	= ((IXP4XX_UART2_BASE_VIRT) >> 18) & 0xfffc,
+	.map_io		= gtwx5715_map_io,
+	.init_irq	= ixp4xx_init_irq,
+	.timer		= &ixp4xx_timer,
+	.boot_params	= 0x0100,
+	.init_machine	= gtwx5715_init,
 MACHINE_END
 
 
diff --git a/arch/arm/mach-ixp4xx/ixdp425-setup.c b/arch/arm/mach-ixp4xx/ixdp425-setup.c
--- a/arch/arm/mach-ixp4xx/ixdp425-setup.c
+++ b/arch/arm/mach-ixp4xx/ixdp425-setup.c
@@ -36,7 +36,7 @@ static struct flash_platform_data ixdp42
 
 static struct resource ixdp425_flash_resource = {
 	.start		= IXDP425_FLASH_BASE,
-	.end		= IXDP425_FLASH_BASE + IXDP425_FLASH_SIZE,
+	.end		= IXDP425_FLASH_BASE + IXDP425_FLASH_SIZE - 1,
 	.flags		= IORESOURCE_MEM,
 };
 
@@ -82,7 +82,7 @@ static struct plat_serial8250_port ixdp4
 		.mapbase	= IXP4XX_UART1_BASE_PHYS,
 		.membase	= (char *)IXP4XX_UART1_BASE_VIRT + REG_OFFSET,
 		.irq		= IRQ_IXP4XX_UART1,
-		.flags		= UPF_BOOT_AUTOCONF,
+		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
 		.iotype		= UPIO_MEM,
 		.regshift	= 2,
 		.uartclk	= IXP4XX_UART_XTAL,
@@ -91,11 +91,12 @@ static struct plat_serial8250_port ixdp4
 		.mapbase	= IXP4XX_UART2_BASE_PHYS,
 		.membase	= (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET,
 		.irq		= IRQ_IXP4XX_UART1,
-		.flags		= UPF_BOOT_AUTOCONF,
+		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
 		.iotype		= UPIO_MEM,
 		.regshift	= 2,
 		.uartclk	= IXP4XX_UART_XTAL,
-	}
+	},
+	{ },
 };
 
 static struct platform_device ixdp425_uart = {
@@ -128,36 +129,39 @@ static void __init ixdp425_init(void)
 }
 
 MACHINE_START(IXDP425, "Intel IXDP425 Development Platform")
-	MAINTAINER("MontaVista Software, Inc.")
-	BOOT_MEM(PHYS_OFFSET, IXP4XX_PERIPHERAL_BASE_PHYS,
-		IXP4XX_PERIPHERAL_BASE_VIRT)
-	MAPIO(ixdp425_map_io)
-	INITIRQ(ixp4xx_init_irq)
+	/* Maintainer: MontaVista Software, Inc. */
+	.phys_ram	= PHYS_OFFSET,
+	.phys_io	= IXP4XX_PERIPHERAL_BASE_PHYS,
+	.io_pg_offst	= ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc,
+	.map_io		= ixdp425_map_io,
+	.init_irq	= ixp4xx_init_irq,
 	.timer		= &ixp4xx_timer,
-	BOOT_PARAMS(0x0100)
-	INIT_MACHINE(ixdp425_init)
+	.boot_params	= 0x0100,
+	.init_machine	= ixdp425_init,
 MACHINE_END
 
 MACHINE_START(IXDP465, "Intel IXDP465 Development Platform")
-	MAINTAINER("MontaVista Software, Inc.")
-	BOOT_MEM(PHYS_OFFSET, IXP4XX_PERIPHERAL_BASE_PHYS,
-		IXP4XX_PERIPHERAL_BASE_VIRT)
-	MAPIO(ixdp425_map_io)
-	INITIRQ(ixp4xx_init_irq)
+	/* Maintainer: MontaVista Software, Inc. */
+	.phys_ram	= PHYS_OFFSET,
+	.phys_io	= IXP4XX_PERIPHERAL_BASE_PHYS,
+	.io_pg_offst	= ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc,
+	.map_io		= ixdp425_map_io,
+	.init_irq	= ixp4xx_init_irq,
 	.timer		= &ixp4xx_timer,
-	BOOT_PARAMS(0x0100)
-	INIT_MACHINE(ixdp425_init)
+	.boot_params	= 0x0100,
+	.init_machine	= ixdp425_init,
 MACHINE_END
 
 MACHINE_START(IXCDP1100, "Intel IXCDP1100 Development Platform")
-	MAINTAINER("MontaVista Software, Inc.")
-	BOOT_MEM(PHYS_OFFSET, IXP4XX_PERIPHERAL_BASE_PHYS,
-		IXP4XX_PERIPHERAL_BASE_VIRT)
-	MAPIO(ixdp425_map_io)
-	INITIRQ(ixp4xx_init_irq)
+	/* Maintainer: MontaVista Software, Inc. */
+	.phys_ram	= PHYS_OFFSET,
+	.phys_io	= IXP4XX_PERIPHERAL_BASE_PHYS,
+	.io_pg_offst	= ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc,
+	.map_io		= ixdp425_map_io,
+	.init_irq	= ixp4xx_init_irq,
 	.timer		= &ixp4xx_timer,
-	BOOT_PARAMS(0x0100)
-	INIT_MACHINE(ixdp425_init)
+	.boot_params	= 0x0100,
+	.init_machine	= ixdp425_init,
 MACHINE_END
 
 /*
@@ -168,14 +172,15 @@ MACHINE_END
  */
 #ifdef CONFIG_ARCH_AVILA
 MACHINE_START(AVILA, "Gateworks Avila Network Platform")
-	MAINTAINER("Deepak Saxena <dsaxena@plexity.net>")
-	BOOT_MEM(PHYS_OFFSET, IXP4XX_PERIPHERAL_BASE_PHYS,
-		IXP4XX_PERIPHERAL_BASE_VIRT)
-	MAPIO(ixdp425_map_io)
-	INITIRQ(ixp4xx_init_irq)
+	/* Maintainer: Deepak Saxena <dsaxena@plexity.net> */
+	.phys_ram	= PHYS_OFFSET,
+	.phys_io	= IXP4XX_PERIPHERAL_BASE_PHYS,
+	.io_pg_offst	= ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc,
+	.map_io		= ixdp425_map_io,
+	.init_irq	= ixp4xx_init_irq,
 	.timer		= &ixp4xx_timer,
-	BOOT_PARAMS(0x0100)
-	INIT_MACHINE(ixdp425_init)
+	.boot_params	= 0x0100,
+	.init_machine	= ixdp425_init,
 MACHINE_END
 #endif
 
diff --git a/arch/arm/mach-l7200/core.c b/arch/arm/mach-l7200/core.c
--- a/arch/arm/mach-l7200/core.c
+++ b/arch/arm/mach-l7200/core.c
@@ -81,9 +81,11 @@ static void __init l7200_map_io(void)
 }
 
 MACHINE_START(L7200, "LinkUp Systems L7200")
-	MAINTAINER("Steve Hill / Scott McConnell")
-	BOOT_MEM(0xf0000000, 0x80040000, 0xd0000000)
-	MAPIO(l7200_map_io)
-	INITIRQ(l7200_init_irq)
+	/* Maintainer: Steve Hill / Scott McConnell */
+	.phys_ram	= 0xf0000000,
+	.phys_io	= 0x80040000,
+	.io_pg_offst	= ((0xd0000000) >> 18) & 0xfffc,
+	.map_io		= l7200_map_io,
+	.init_irq	= l7200_init_irq,
 MACHINE_END
 
diff --git a/arch/arm/mach-lh7a40x/arch-kev7a400.c b/arch/arm/mach-lh7a40x/arch-kev7a400.c
--- a/arch/arm/mach-lh7a40x/arch-kev7a400.c
+++ b/arch/arm/mach-lh7a40x/arch-kev7a400.c
@@ -102,10 +102,12 @@ void __init lh7a40x_init_board_irq (void
 }
 
 MACHINE_START (KEV7A400, "Sharp KEV7a400")
-	MAINTAINER ("Marc Singer")
-	BOOT_MEM (0xc0000000, 0x80000000, io_p2v (0x80000000))
-	BOOT_PARAMS (0xc0000100)
-	MAPIO (kev7a400_map_io)
-	INITIRQ (lh7a400_init_irq)
+	/* Maintainer: Marc Singer */
+	.phys_ram	= 0xc0000000,
+	.phys_io	= 0x80000000,
+	.io_pg_offst	= ((io_p2v (0x80000000))>>18) & 0xfffc,
+	.boot_params	= 0xc0000100,
+	.map_io		= kev7a400_map_io,
+	.init_irq	= lh7a400_init_irq,
 	.timer		= &lh7a40x_timer,
 MACHINE_END
diff --git a/arch/arm/mach-lh7a40x/arch-lpd7a40x.c b/arch/arm/mach-lh7a40x/arch-lpd7a40x.c
--- a/arch/arm/mach-lh7a40x/arch-lpd7a40x.c
+++ b/arch/arm/mach-lh7a40x/arch-lpd7a40x.c
@@ -260,13 +260,15 @@ lpd7a400_map_io(void)
 #ifdef CONFIG_MACH_LPD7A400
 
 MACHINE_START (LPD7A400, "Logic Product Development LPD7A400-10")
-	MAINTAINER ("Marc Singer")
-	BOOT_MEM (0xc0000000, 0x80000000, io_p2v (0x80000000))
-	BOOT_PARAMS (0xc0000100)
-	MAPIO (lpd7a400_map_io)
-	INITIRQ (lh7a400_init_irq)
+	/* Maintainer: Marc Singer */
+	.phys_ram	= 0xc0000000,
+	.phys_io	= 0x80000000,
+	.io_pg_offst	= ((io_p2v (0x80000000))>>18) & 0xfffc,
+	.boot_params	= 0xc0000100,
+	.map_io		= lpd7a400_map_io,
+	.init_irq	= lh7a400_init_irq,
 	.timer		= &lh7a40x_timer,
-	INIT_MACHINE (lpd7a40x_init)
+	.init_machine	= lpd7a40x_init,
 MACHINE_END
 
 #endif
@@ -274,13 +276,15 @@ MACHINE_END
 #ifdef CONFIG_MACH_LPD7A404
 
 MACHINE_START (LPD7A404, "Logic Product Development LPD7A404-10")
-	MAINTAINER ("Marc Singer")
-	BOOT_MEM (0xc0000000, 0x80000000, io_p2v (0x80000000))
-	BOOT_PARAMS (0xc0000100)
-	MAPIO (lpd7a400_map_io)
-	INITIRQ (lh7a404_init_irq)
+	/* Maintainer: Marc Singer */
+	.phys_ram	= 0xc0000000,
+	.phys_io	= 0x80000000,
+	.io_pg_offst	= ((io_p2v (0x80000000))>>18) & 0xfffc,
+	.boot_params	= 0xc0000100,
+	.map_io		= lpd7a400_map_io,
+	.init_irq	= lh7a404_init_irq,
 	.timer		= &lh7a40x_timer,
-	INIT_MACHINE (lpd7a40x_init)
+	.init_machine	= lpd7a40x_init,
 MACHINE_END
 
 #endif
diff --git a/arch/arm/mach-lh7a40x/time.c b/arch/arm/mach-lh7a40x/time.c
--- a/arch/arm/mach-lh7a40x/time.c
+++ b/arch/arm/mach-lh7a40x/time.c
@@ -53,8 +53,8 @@ lh7a40x_timer_interrupt(int irq, void *d
 
 static struct irqaction lh7a40x_timer_irq = {
 	.name		= "LHA740x Timer Tick",
-	.flags		= SA_INTERRUPT,
-	.handler	= lh7a40x_timer_interrupt
+	.flags		= SA_INTERRUPT | SA_TIMER,
+	.handler	= lh7a40x_timer_interrupt,
 };
 
 static void __init lh7a40x_timer_init(void)
diff --git a/arch/arm/mach-omap/Kconfig b/arch/arm/mach-omap/Kconfig
deleted file mode 100644
--- a/arch/arm/mach-omap/Kconfig
+++ /dev/null
@@ -1,221 +0,0 @@
-if ARCH_OMAP
-
-menu "TI OMAP Implementations"
-
-comment "OMAP Core Type"
-
-config ARCH_OMAP730
-	depends on ARCH_OMAP
-	bool "OMAP730 Based System"
-	select ARCH_OMAP_OTG
-
-config ARCH_OMAP1510
-	depends on ARCH_OMAP
-	default y
-	bool "OMAP1510 Based System"
-
-config ARCH_OMAP16XX
-	depends on ARCH_OMAP
-	bool "OMAP16XX Based System"
-	select ARCH_OMAP_OTG
-
-config ARCH_OMAP_OTG
-	bool
-
-comment "OMAP Board Type"
-
-config MACH_OMAP_INNOVATOR
-	bool "TI Innovator"
-	depends on ARCH_OMAP1510 || ARCH_OMAP16XX
-	help
-          TI OMAP 1510 or 1610 Innovator board support. Say Y here if you
-          have such a board.
-
-config MACH_OMAP_H2
-	bool "TI H2 Support"
-	depends on ARCH_OMAP16XX
-    	help
-	  TI OMAP 1610/1611B H2 board support. Say Y here if you have such
-	  a board.
-
-config MACH_OMAP_H3
-	bool "TI H3 Support"
-	depends on ARCH_OMAP16XX
-    	help
-	  TI OMAP 1710 H3 board support. Say Y here if you have such
-	  a board.
-
-config MACH_OMAP_H4
-	bool "TI H4 Support"
-	depends on ARCH_OMAP16XX
-    	help
-	  TI OMAP 1610 H4 board support. Say Y here if you have such
-	  a board.
-
-config MACH_OMAP_OSK
-	bool "TI OSK Support"
-	depends on ARCH_OMAP16XX
-    	help
-	  TI OMAP 5912 OSK (OMAP Starter Kit) board support. Say Y here
-          if you have such a board.
-
-config MACH_OMAP_PERSEUS2
-	bool "TI Perseus2"
-	depends on ARCH_OMAP730
-    	help
-	  Support for TI OMAP 730 Perseus2 board. Say Y here if you have such
-	  a board.
-
-config MACH_VOICEBLUE
-	bool "Voiceblue"
-	depends on ARCH_OMAP1510
-	help
-	  Support for Voiceblue GSM/VoIP gateway. Say Y here if you have such
-	  board.
-
-config MACH_NETSTAR
-	bool "NetStar"
-	depends on ARCH_OMAP1510
-	help
-	  Support for NetStar PBX. Say Y here if you have such a board.
-
-config MACH_OMAP_GENERIC
-	bool "Generic OMAP board"
-	depends on ARCH_OMAP1510 || ARCH_OMAP16XX
-	help
-          Support for generic OMAP-1510, 1610 or 1710 board with
-          no FPGA. Can be used as template for porting Linux to
-          custom OMAP boards. Say Y here if you have a custom
-          board.
-
-comment "OMAP Feature Selections"
-
-#config OMAP_BOOT_TAG
-#	bool "OMAP bootloader information passing"
-#        depends on ARCH_OMAP
-#        default n
-#        help
-#          Say Y, if you have a bootloader which passes information
-#          about your board and its peripheral configuration.
-
-config OMAP_MUX
-	bool "OMAP multiplexing support"
-        depends on ARCH_OMAP
-	default y
-        help
-          Pin multiplexing support for OMAP boards. If your bootloader
-          sets the multiplexing correctly, say N. Otherwise, or if unsure,
-          say Y.
-
-config OMAP_MUX_DEBUG
-	bool "Multiplexing debug output"
-        depends on OMAP_MUX
-        default n
-        help
-          Makes the multiplexing functions print out a lot of debug info.
-          This is useful if you want to find out the correct values of the
-          multiplexing registers.
-
-config OMAP_MUX_WARNINGS
-	bool "Warn about pins the bootloader didn't set up"
-        depends on OMAP_MUX
-        default y
-        help
-	  Choose Y here to warn whenever driver initialization logic needs
-	  to change the pin multiplexing setup.  When there are no warnings
-	  printed, it's safe to deselect OMAP_MUX for your product.
-
-choice
-        prompt "System timer"
-	default OMAP_MPU_TIMER
-
-config OMAP_MPU_TIMER
-	bool "Use mpu timer"
-	help
-	  Select this option if you want to use the OMAP mpu timer. This
-	  timer provides more intra-tick resolution than the 32KHz timer,
-	  but consumes more power.
-
-config OMAP_32K_TIMER
-	bool "Use 32KHz timer"
-	depends on ARCH_OMAP16XX
-	help
-	  Select this option if you want to enable the OMAP 32KHz timer.
-	  This timer saves power compared to the OMAP_MPU_TIMER, and has
-	  support for no tick during idle. The 32KHz timer provides less
-	  intra-tick resolution than OMAP_MPU_TIMER. The 32KHz timer is
-	  currently only available for OMAP-16xx.
-
-endchoice
-
-config OMAP_32K_TIMER_HZ
-       int "Kernel internal timer frequency for 32KHz timer"
-       range 32 1024
-       depends on OMAP_32K_TIMER
-       default "128"
-       help
-	  Kernel internal timer frequency should be a divisor of 32768,
-	  such as 64 or 128.
-
-choice
-	prompt "Low-level debug console UART"
-	depends on ARCH_OMAP
-	default OMAP_LL_DEBUG_UART1
-
-config OMAP_LL_DEBUG_UART1
-	bool "UART1"
-
-config OMAP_LL_DEBUG_UART2
-	bool "UART2"
-
-config OMAP_LL_DEBUG_UART3
-	bool "UART3"
-
-endchoice
-
-config OMAP_ARM_195MHZ
-	bool "OMAP ARM 195 MHz CPU"
-	depends on ARCH_OMAP730
-	help
-          Enable 195MHz clock for OMAP CPU. If unsure, say N.
-
-config OMAP_ARM_192MHZ
-	bool "OMAP ARM 192 MHz CPU"
-	depends on ARCH_OMAP16XX
-	help
-          Enable 192MHz clock for OMAP CPU. If unsure, say N.
-
-config OMAP_ARM_182MHZ
-	bool "OMAP ARM 182 MHz CPU"
-	depends on ARCH_OMAP730
-	help
-          Enable 182MHz clock for OMAP CPU. If unsure, say N.
-
-config OMAP_ARM_168MHZ
-	bool "OMAP ARM 168 MHz CPU"
-	depends on ARCH_OMAP1510 || ARCH_OMAP16XX || ARCH_OMAP730
-	help
-          Enable 168MHz clock for OMAP CPU. If unsure, say N.
-
-config OMAP_ARM_120MHZ
-	bool "OMAP ARM 120 MHz CPU"
-	depends on ARCH_OMAP1510 || ARCH_OMAP16XX || ARCH_OMAP730
-	help
-          Enable 120MHz clock for OMAP CPU. If unsure, say N.
-
-config OMAP_ARM_60MHZ
-	bool "OMAP ARM 60 MHz CPU"
-	depends on ARCH_OMAP1510 || ARCH_OMAP16XX || ARCH_OMAP730
-        default y
-	help
-          Enable 60MHz clock for OMAP CPU. If unsure, say Y.
-
-config OMAP_ARM_30MHZ
-	bool "OMAP ARM 30 MHz CPU"
-	depends on ARCH_OMAP1510 || ARCH_OMAP16XX || ARCH_OMAP730
-	help
-          Enable 30MHz clock for OMAP CPU. If unsure, say N.
-
-endmenu
-
-endif
diff --git a/arch/arm/mach-omap/Makefile b/arch/arm/mach-omap/Makefile
deleted file mode 100644
--- a/arch/arm/mach-omap/Makefile
+++ /dev/null
@@ -1,40 +0,0 @@
-#
-# Makefile for the linux kernel.
-#
-
-# Common support
-obj-y := common.o time.o irq.o dma.o clock.o mux.o gpio.o mcbsp.o usb.o
-obj-m :=
-obj-n :=
-obj-  :=
-led-y := leds.o
-
-# Specific board support
-obj-$(CONFIG_MACH_OMAP_H2) += board-h2.o
-obj-$(CONFIG_MACH_OMAP_INNOVATOR) += board-innovator.o
-obj-$(CONFIG_MACH_OMAP_GENERIC) += board-generic.o
-obj-$(CONFIG_MACH_OMAP_PERSEUS2) += board-perseus2.o
-obj-$(CONFIG_MACH_OMAP_OSK) += board-osk.o
-obj-$(CONFIG_MACH_OMAP_H3) += board-h3.o
-obj-$(CONFIG_MACH_VOICEBLUE) += board-voiceblue.o
-obj-$(CONFIG_MACH_NETSTAR) += board-netstar.o
-
-# OCPI interconnect support for 1710, 1610 and 5912
-obj-$(CONFIG_ARCH_OMAP16XX) += ocpi.o
-
-# LEDs support
-led-$(CONFIG_MACH_OMAP_H2) += leds-h2p2-debug.o
-led-$(CONFIG_MACH_OMAP_INNOVATOR) += leds-innovator.o
-led-$(CONFIG_MACH_OMAP_PERSEUS2) += leds-h2p2-debug.o
-obj-$(CONFIG_LEDS) += $(led-y)
-
-# Power Management
-obj-$(CONFIG_PM) += pm.o sleep.o
-
-ifeq ($(CONFIG_ARCH_OMAP1510),y)
-# Innovator-1510 FPGA
-obj-$(CONFIG_MACH_OMAP_INNOVATOR) += fpga.o
-endif
-
-# kgdb support
-obj-$(CONFIG_KGDB_SERIAL)	+= kgdb-serial.o
diff --git a/arch/arm/mach-omap/Makefile.boot b/arch/arm/mach-omap/Makefile.boot
deleted file mode 100644
--- a/arch/arm/mach-omap/Makefile.boot
+++ /dev/null
@@ -1,4 +0,0 @@
-   zreladdr-y		:= 0x10008000
-params_phys-y		:= 0x10000100
-initrd_phys-y		:= 0x10800000
-
diff --git a/arch/arm/mach-omap/board-generic.c b/arch/arm/mach-omap/board-generic.c
deleted file mode 100644
--- a/arch/arm/mach-omap/board-generic.c
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * linux/arch/arm/mach-omap/board-generic.c
- *
- * Modified from board-innovator1510.c
- *
- * Code for generic OMAP board. Should work on many OMAP systems where
- * the device drivers take care of all the necessary hardware initialization.
- * Do not put any board specific code to this file; create a new machine
- * type if you need custom low-level initializations.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/device.h>
-
-#include <asm/hardware.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-
-#include <asm/arch/gpio.h>
-#include <asm/arch/mux.h>
-#include <asm/arch/usb.h>
-#include <asm/arch/board.h>
-
-#include "common.h"
-
-static int __initdata generic_serial_ports[OMAP_MAX_NR_PORTS] = {1, 1, 1};
-
-static void __init omap_generic_init_irq(void)
-{
-	omap_init_irq();
-}
-
-/* assume no Mini-AB port */
-
-#ifdef CONFIG_ARCH_OMAP1510
-static struct omap_usb_config generic1510_usb_config __initdata = {
-	.register_host	= 1,
-	.register_dev	= 1,
-	.hmc_mode	= 16,
-	.pins[0]	= 3,
-};
-#endif
-
-#if defined(CONFIG_ARCH_OMAP16XX)
-static struct omap_usb_config generic1610_usb_config __initdata = {
-	.register_host	= 1,
-	.register_dev	= 1,
-	.hmc_mode	= 16,
-	.pins[0]	= 6,
-};
-#endif
-
-static struct omap_board_config_kernel generic_config[] = {
-	{ OMAP_TAG_USB,           NULL },
-};
-
-static void __init omap_generic_init(void)
-{
-	/*
-	 * Make sure the serial ports are muxed on at this point.
-	 * You have to mux them off in device drivers later on
-	 * if not needed.
-	 */
-#ifdef CONFIG_ARCH_OMAP1510
-	if (cpu_is_omap1510()) {
-		generic_config[0].data = &generic1510_usb_config;
-	}
-#endif
-#if defined(CONFIG_ARCH_OMAP16XX)
-	if (!cpu_is_omap1510()) {
-		generic_config[0].data = &generic1610_usb_config;
-	}
-#endif
-	omap_board_config = generic_config;
-	omap_board_config_size = ARRAY_SIZE(generic_config);
-	omap_serial_init(generic_serial_ports);
-}
-
-static void __init omap_generic_map_io(void)
-{
-	omap_map_io();
-}
-
-MACHINE_START(OMAP_GENERIC, "Generic OMAP1510/1610/1710")
-	MAINTAINER("Tony Lindgren <tony@atomide.com>")
-	BOOT_MEM(0x10000000, 0xfff00000, 0xfef00000)
-	BOOT_PARAMS(0x10000100)
-	MAPIO(omap_generic_map_io)
-	INITIRQ(omap_generic_init_irq)
-	INIT_MACHINE(omap_generic_init)
-	.timer		= &omap_timer,
-MACHINE_END
diff --git a/arch/arm/mach-omap/board-h2.c b/arch/arm/mach-omap/board-h2.c
deleted file mode 100644
--- a/arch/arm/mach-omap/board-h2.c
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * linux/arch/arm/mach-omap/board-h2.c
- *
- * Board specific inits for OMAP-1610 H2
- *
- * Copyright (C) 2001 RidgeRun, Inc.
- * Author: Greg Lonnon <glonnon@ridgerun.com>
- *
- * Copyright (C) 2002 MontaVista Software, Inc.
- *
- * Separated FPGA interrupts from innovator1510.c and cleaned up for 2.6
- * Copyright (C) 2004 Nokia Corporation by Tony Lindrgen <tony@atomide.com>
- *
- * H2 specific changes and cleanup
- * Copyright (C) 2004 Nokia Corporation by Imre Deak <imre.deak@nokia.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/delay.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/partitions.h>
-
-#include <asm/hardware.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/flash.h>
-#include <asm/mach/map.h>
-
-#include <asm/arch/gpio.h>
-#include <asm/arch/tc.h>
-#include <asm/arch/usb.h>
-
-#include "common.h"
-
-extern int omap_gpio_init(void);
-
-static int __initdata h2_serial_ports[OMAP_MAX_NR_PORTS] = {1, 1, 1};
-
-static struct mtd_partition h2_partitions[] = {
-	/* bootloader (U-Boot, etc) in first sector */
-	{
-	      .name		= "bootloader",
-	      .offset		= 0,
-	      .size		= SZ_128K,
-	      .mask_flags	= MTD_WRITEABLE, /* force read-only */
-	},
-	/* bootloader params in the next sector */
-	{
-	      .name		= "params",
-	      .offset		= MTDPART_OFS_APPEND,
-	      .size		= SZ_128K,
-	      .mask_flags	= 0,
-	},
-	/* kernel */
-	{
-	      .name		= "kernel",
-	      .offset		= MTDPART_OFS_APPEND,
-	      .size		= SZ_2M,
-	      .mask_flags	= 0
-	},
-	/* file system */
-	{
-	      .name		= "filesystem",
-	      .offset		= MTDPART_OFS_APPEND,
-	      .size		= MTDPART_SIZ_FULL,
-	      .mask_flags	= 0
-	}
-};
-
-static struct flash_platform_data h2_flash_data = {
-	.map_name	= "cfi_probe",
-	.width		= 2,
-	.parts		= h2_partitions,
-	.nr_parts	= ARRAY_SIZE(h2_partitions),
-};
-
-static struct resource h2_flash_resource = {
-	.start		= OMAP_CS2B_PHYS,
-	.end		= OMAP_CS2B_PHYS + OMAP_CS2B_SIZE - 1,
-	.flags		= IORESOURCE_MEM,
-};
-
-static struct platform_device h2_flash_device = {
-	.name		= "omapflash",
-	.id		= 0,
-	.dev		= {
-		.platform_data	= &h2_flash_data,
-	},
-	.num_resources	= 1,
-	.resource	= &h2_flash_resource,
-};
-
-static struct resource h2_smc91x_resources[] = {
-	[0] = {
-		.start	= OMAP1610_ETHR_START,		/* Physical */
-		.end	= OMAP1610_ETHR_START + 0xf,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= OMAP_GPIO_IRQ(0),
-		.end	= OMAP_GPIO_IRQ(0),
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device h2_smc91x_device = {
-	.name		= "smc91x",
-	.id		= 0,
-	.num_resources	= ARRAY_SIZE(h2_smc91x_resources),
-	.resource	= h2_smc91x_resources,
-};
-
-static struct platform_device *h2_devices[] __initdata = {
-	&h2_flash_device,
-	&h2_smc91x_device,
-};
-
-static void __init h2_init_smc91x(void)
-{
-	if ((omap_request_gpio(0)) < 0) {
-		printk("Error requesting gpio 0 for smc91x irq\n");
-		return;
-	}
-	omap_set_gpio_edge_ctrl(0, OMAP_GPIO_FALLING_EDGE);
-}
-
-void h2_init_irq(void)
-{
-	omap_init_irq();
-	omap_gpio_init();
-	h2_init_smc91x();
-}
-
-static struct omap_usb_config h2_usb_config __initdata = {
-	/* usb1 has a Mini-AB port and external isp1301 transceiver */
-	.otg		= 2,
-
-#ifdef	CONFIG_USB_GADGET_OMAP
-	.hmc_mode	= 19,	// 0:host(off) 1:dev|otg 2:disabled
-	// .hmc_mode	= 21,	// 0:host(off) 1:dev(loopback) 2:host(loopback)
-#elif	defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
-	/* needs OTG cable, or NONSTANDARD (B-to-MiniB) */
-	.hmc_mode	= 20,	// 1:dev|otg(off) 1:host 2:disabled
-#endif
-
-	.pins[1]	= 3,
-};
-
-static struct omap_mmc_config h2_mmc_config __initdata = {
-	.mmc_blocks		= 1,
-	.mmc1_power_pin		= -1,	/* tps65010 gpio3 */
-	.mmc1_switch_pin	= OMAP_MPUIO(1),
-};
-
-static struct omap_board_config_kernel h2_config[] = {
-	{ OMAP_TAG_USB,           &h2_usb_config },
-	{ OMAP_TAG_MMC,           &h2_mmc_config },
-};
-
-static void __init h2_init(void)
-{
-	platform_add_devices(h2_devices, ARRAY_SIZE(h2_devices));
-	omap_board_config = h2_config;
-	omap_board_config_size = ARRAY_SIZE(h2_config);
-}
-
-static void __init h2_map_io(void)
-{
-	omap_map_io();
-	omap_serial_init(h2_serial_ports);
-}
-
-MACHINE_START(OMAP_H2, "TI-H2")
-	MAINTAINER("Imre Deak <imre.deak@nokia.com>")
-	BOOT_MEM(0x10000000, 0xfff00000, 0xfef00000)
-	BOOT_PARAMS(0x10000100)
-	MAPIO(h2_map_io)
-	INITIRQ(h2_init_irq)
-	INIT_MACHINE(h2_init)
-	.timer		= &omap_timer,
-MACHINE_END
diff --git a/arch/arm/mach-omap/board-h3.c b/arch/arm/mach-omap/board-h3.c
deleted file mode 100644
--- a/arch/arm/mach-omap/board-h3.c
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * linux/arch/arm/mach-omap/board-h3.c
- *
- * This file contains OMAP1710 H3 specific code.
- *
- * Copyright (C) 2004 Texas Instruments, Inc.
- * Copyright (C) 2002 MontaVista Software, Inc.
- * Copyright (C) 2001 RidgeRun, Inc.
- * Author: RidgeRun, Inc.
- *         Greg Lonnon (glonnon@ridgerun.com) or info@ridgerun.com
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/config.h>
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/major.h>
-#include <linux/kernel.h>
-#include <linux/device.h>
-#include <linux/errno.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/partitions.h>
-
-#include <asm/setup.h>
-#include <asm/page.h>
-#include <asm/hardware.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/flash.h>
-#include <asm/mach/map.h>
-
-#include <asm/arch/gpio.h>
-#include <asm/arch/irqs.h>
-#include <asm/arch/mux.h>
-#include <asm/arch/tc.h>
-#include <asm/arch/usb.h>
-
-#include "common.h"
-
-extern int omap_gpio_init(void);
-
-static int __initdata h3_serial_ports[OMAP_MAX_NR_PORTS] = {1, 1, 1};
-
-static struct mtd_partition h3_partitions[] = {
-	/* bootloader (U-Boot, etc) in first sector */
-	{
-	      .name		= "bootloader",
-	      .offset		= 0,
-	      .size		= SZ_128K,
-	      .mask_flags	= MTD_WRITEABLE, /* force read-only */
-	},
-	/* bootloader params in the next sector */
-	{
-	      .name		= "params",
-	      .offset		= MTDPART_OFS_APPEND,
-	      .size		= SZ_128K,
-	      .mask_flags	= 0,
-	},
-	/* kernel */
-	{
-	      .name		= "kernel",
-	      .offset		= MTDPART_OFS_APPEND,
-	      .size		= SZ_2M,
-	      .mask_flags	= 0
-	},
-	/* file system */
-	{
-	      .name		= "filesystem",
-	      .offset		= MTDPART_OFS_APPEND,
-	      .size		= MTDPART_SIZ_FULL,
-	      .mask_flags	= 0
-	}
-};
-
-static struct flash_platform_data h3_flash_data = {
-	.map_name	= "cfi_probe",
-	.width		= 2,
-	.parts		= h3_partitions,
-	.nr_parts	= ARRAY_SIZE(h3_partitions),
-};
-
-static struct resource h3_flash_resource = {
-	.start		= OMAP_CS2B_PHYS,
-	.end		= OMAP_CS2B_PHYS + OMAP_CS2B_SIZE - 1,
-	.flags		= IORESOURCE_MEM,
-};
-
-static struct platform_device flash_device = {
-	.name		= "omapflash",
-	.id		= 0,
-	.dev		= {
-		.platform_data	= &h3_flash_data,
-	},
-	.num_resources	= 1,
-	.resource	= &h3_flash_resource,
-};
-
-static struct resource smc91x_resources[] = {
-	[0] = {
-		.start	= OMAP1710_ETHR_START,		/* Physical */
-		.end	= OMAP1710_ETHR_START + 0xf,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= OMAP_GPIO_IRQ(40),
-		.end	= OMAP_GPIO_IRQ(40),
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device smc91x_device = {
-	.name		= "smc91x",
-	.id		= 0,
-	.num_resources	= ARRAY_SIZE(smc91x_resources),
-	.resource	= smc91x_resources,
-};
-
-#define GPTIMER_BASE		0xFFFB1400
-#define GPTIMER_REGS(x)	(0xFFFB1400 + (x * 0x800))
-#define GPTIMER_REGS_SIZE	0x46
-
-static struct resource intlat_resources[] = {
-	[0] = {
-		.start  = GPTIMER_REGS(0),	      /* Physical */
-		.end    = GPTIMER_REGS(0) + GPTIMER_REGS_SIZE,
-		.flags  = IORESOURCE_MEM,
-	},
-	[1] = {
-		.start  = INT_1610_GPTIMER1,
-		.end    = INT_1610_GPTIMER1,
-		.flags  = IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device intlat_device = {
-	.name	   = "omap_intlat",
-	.id	     = 0,
-	.num_resources  = ARRAY_SIZE(intlat_resources),
-	.resource       = intlat_resources,
-};
-
-static struct platform_device *devices[] __initdata = {
-	&flash_device,
-        &smc91x_device,
-	&intlat_device,
-};
-
-static struct omap_usb_config h3_usb_config __initdata = {
-	/* usb1 has a Mini-AB port and external isp1301 transceiver */
-	.otg	    = 2,
-
-#ifdef CONFIG_USB_GADGET_OMAP
-	.hmc_mode       = 19,   /* 0:host(off) 1:dev|otg 2:disabled */
-#elif  defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
-	/* NONSTANDARD CABLE NEEDED (B-to-Mini-B) */
-	.hmc_mode       = 20,   /* 1:dev|otg(off) 1:host 2:disabled */
-#endif
-
-	.pins[1]	= 3,
-};
-
-static struct omap_board_config_kernel h3_config[] = {
-	{ OMAP_TAG_USB,	 &h3_usb_config },
-};
-
-static void __init h3_init(void)
-{
-	(void) platform_add_devices(devices, ARRAY_SIZE(devices));
-}
-
-static void __init h3_init_smc91x(void)
-{
-	omap_cfg_reg(W15_1710_GPIO40);
-	if (omap_request_gpio(40) < 0) {
-		printk("Error requesting gpio 40 for smc91x irq\n");
-		return;
-	}
-	omap_set_gpio_edge_ctrl(40, OMAP_GPIO_FALLING_EDGE);
-}
-
-void h3_init_irq(void)
-{
-	omap_init_irq();
-	omap_gpio_init();
-	h3_init_smc91x();
-}
-
-static void __init h3_map_io(void)
-{
-	omap_map_io();
-	omap_serial_init(h3_serial_ports);
-}
-
-MACHINE_START(OMAP_H3, "TI OMAP1710 H3 board")
-	MAINTAINER("Texas Instruments, Inc.")
-	BOOT_MEM(0x10000000, 0xfff00000, 0xfef00000)
-	BOOT_PARAMS(0x10000100)
-	MAPIO(h3_map_io)
-	INITIRQ(h3_init_irq)
-	INIT_MACHINE(h3_init)
-	.timer		= &omap_timer,
-MACHINE_END
diff --git a/arch/arm/mach-omap/board-innovator.c b/arch/arm/mach-omap/board-innovator.c
deleted file mode 100644
--- a/arch/arm/mach-omap/board-innovator.c
+++ /dev/null
@@ -1,280 +0,0 @@
-/*
- * linux/arch/arm/mach-omap/board-innovator.c
- *
- * Board specific inits for OMAP-1510 and OMAP-1610 Innovator
- *
- * Copyright (C) 2001 RidgeRun, Inc.
- * Author: Greg Lonnon <glonnon@ridgerun.com>
- *
- * Copyright (C) 2002 MontaVista Software, Inc.
- *
- * Separated FPGA interrupts from innovator1510.c and cleaned up for 2.6
- * Copyright (C) 2004 Nokia Corporation by Tony Lindrgen <tony@atomide.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/delay.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/partitions.h>
-
-#include <asm/hardware.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/flash.h>
-#include <asm/mach/map.h>
-
-#include <asm/arch/fpga.h>
-#include <asm/arch/gpio.h>
-#include <asm/arch/tc.h>
-#include <asm/arch/usb.h>
-
-#include "common.h"
-
-static int __initdata innovator_serial_ports[OMAP_MAX_NR_PORTS] = {1, 1, 1};
-
-static struct mtd_partition innovator_partitions[] = {
-	/* bootloader (U-Boot, etc) in first sector */
-	{
-	      .name		= "bootloader",
-	      .offset		= 0,
-	      .size		= SZ_128K,
-	      .mask_flags	= MTD_WRITEABLE, /* force read-only */
-	},
-	/* bootloader params in the next sector */
-	{
-	      .name		= "params",
-	      .offset		= MTDPART_OFS_APPEND,
-	      .size		= SZ_128K,
-	      .mask_flags	= 0,
-	},
-	/* kernel */
-	{
-	      .name		= "kernel",
-	      .offset		= MTDPART_OFS_APPEND,
-	      .size		= SZ_2M,
-	      .mask_flags	= 0
-	},
-	/* rest of flash1 is a file system */
-	{
-	      .name		= "rootfs",
-	      .offset		= MTDPART_OFS_APPEND,
-	      .size		= SZ_16M - SZ_2M - 2 * SZ_128K,
-	      .mask_flags	= 0
-	},
-	/* file system */
-	{
-	      .name		= "filesystem",
-	      .offset		= MTDPART_OFS_APPEND,
-	      .size		= MTDPART_SIZ_FULL,
-	      .mask_flags	= 0
-	}
-};
-
-static struct flash_platform_data innovator_flash_data = {
-	.map_name	= "cfi_probe",
-	.width		= 2,
-	.parts		= innovator_partitions,
-	.nr_parts	= ARRAY_SIZE(innovator_partitions),
-};
-
-static struct resource innovator_flash_resource = {
-	.start		= OMAP_CS0_PHYS,
-	.end		= OMAP_CS0_PHYS + SZ_32M - 1,
-	.flags		= IORESOURCE_MEM,
-};
-
-static struct platform_device innovator_flash_device = {
-	.name		= "omapflash",
-	.id		= 0,
-	.dev		= {
-		.platform_data	= &innovator_flash_data,
-	},
-	.num_resources	= 1,
-	.resource	= &innovator_flash_resource,
-};
-
-#ifdef CONFIG_ARCH_OMAP1510
-
-/* Only FPGA needs to be mapped here. All others are done with ioremap */
-static struct map_desc innovator1510_io_desc[] __initdata = {
-{ OMAP1510_FPGA_BASE, OMAP1510_FPGA_START, OMAP1510_FPGA_SIZE,
-	MT_DEVICE },
-};
-
-static struct resource innovator1510_smc91x_resources[] = {
-	[0] = {
-		.start	= OMAP1510_FPGA_ETHR_START,	/* Physical */
-		.end	= OMAP1510_FPGA_ETHR_START + 0xf,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= OMAP1510_INT_ETHER,
-		.end	= OMAP1510_INT_ETHER,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device innovator1510_smc91x_device = {
-	.name		= "smc91x",
-	.id		= 0,
-	.num_resources	= ARRAY_SIZE(innovator1510_smc91x_resources),
-	.resource	= innovator1510_smc91x_resources,
-};
-
-static struct platform_device *innovator1510_devices[] __initdata = {
-	&innovator_flash_device,
-	&innovator1510_smc91x_device,
-};
-
-#endif /* CONFIG_ARCH_OMAP1510 */
-
-#ifdef CONFIG_ARCH_OMAP16XX
-
-static struct resource innovator1610_smc91x_resources[] = {
-	[0] = {
-		.start	= INNOVATOR1610_ETHR_START,		/* Physical */
-		.end	= INNOVATOR1610_ETHR_START + 0xf,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= OMAP_GPIO_IRQ(0),
-		.end	= OMAP_GPIO_IRQ(0),
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device innovator1610_smc91x_device = {
-	.name		= "smc91x",
-	.id		= 0,
-	.num_resources	= ARRAY_SIZE(innovator1610_smc91x_resources),
-	.resource	= innovator1610_smc91x_resources,
-};
-
-static struct platform_device *innovator1610_devices[] __initdata = {
-	&innovator_flash_device,
-	&innovator1610_smc91x_device,
-};
-
-#endif /* CONFIG_ARCH_OMAP16XX */
-
-static void __init innovator_init_smc91x(void)
-{
-	if (cpu_is_omap1510()) {
-		fpga_write(fpga_read(OMAP1510_FPGA_RST) & ~1,
-			   OMAP1510_FPGA_RST);
-		udelay(750);
-	} else {
-		if ((omap_request_gpio(0)) < 0) {
-			printk("Error requesting gpio 0 for smc91x irq\n");
-			return;
-		}
-		omap_set_gpio_edge_ctrl(0, OMAP_GPIO_RISING_EDGE);
-	}
-}
-
-void innovator_init_irq(void)
-{
-	omap_init_irq();
-	omap_gpio_init();
-#ifdef CONFIG_ARCH_OMAP1510
-	if (cpu_is_omap1510()) {
-		omap1510_fpga_init_irq();
-	}
-#endif
-	innovator_init_smc91x();
-}
-
-#ifdef CONFIG_ARCH_OMAP1510
-static struct omap_usb_config innovator1510_usb_config __initdata = {
-	/* for bundled non-standard host and peripheral cables */
-	.hmc_mode	= 4,
-
-	.register_host	= 1,
-	.pins[1]	= 6,
-	.pins[2]	= 6,		/* Conflicts with UART2 */
-
-	.register_dev	= 1,
-	.pins[0]	= 2,
-};
-#endif
-
-#ifdef CONFIG_ARCH_OMAP16XX
-static struct omap_usb_config h2_usb_config __initdata = {
-	/* usb1 has a Mini-AB port and external isp1301 transceiver */
-	.otg		= 2,
-
-#ifdef	CONFIG_USB_GADGET_OMAP
-	.hmc_mode	= 19,	// 0:host(off) 1:dev|otg 2:disabled
-	// .hmc_mode	= 21,	// 0:host(off) 1:dev(loopback) 2:host(loopback)
-#elif	defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
-	/* NONSTANDARD CABLE NEEDED (B-to-Mini-B) */
-	.hmc_mode	= 20,	// 1:dev|otg(off) 1:host 2:disabled
-#endif
-
-	.pins[1]	= 3,
-};
-#endif
-
-static struct omap_board_config_kernel innovator_config[] = {
-	{ OMAP_TAG_USB,         NULL },
-};
-
-static void __init innovator_init(void)
-{
-#ifdef CONFIG_ARCH_OMAP1510
-	if (cpu_is_omap1510()) {
-		platform_add_devices(innovator1510_devices, ARRAY_SIZE(innovator1510_devices));
-	}
-#endif
-#ifdef CONFIG_ARCH_OMAP16XX
-	if (!cpu_is_omap1510()) {
-		platform_add_devices(innovator1610_devices, ARRAY_SIZE(innovator1610_devices));
-	}
-#endif
-
-#ifdef CONFIG_ARCH_OMAP1510
-	if (cpu_is_omap1510())
-		innovator_config[0].data = &innovator1510_usb_config;
-#endif
-#ifdef CONFIG_ARCH_OMAP16XX
-	if (cpu_is_omap1610())
-		innovator_config[0].data = &h2_usb_config;
-#endif
-	omap_board_config = innovator_config;
-	omap_board_config_size = ARRAY_SIZE(innovator_config);
-}
-
-static void __init innovator_map_io(void)
-{
-	omap_map_io();
-
-#ifdef CONFIG_ARCH_OMAP1510
-	if (cpu_is_omap1510()) {
-		iotable_init(innovator1510_io_desc, ARRAY_SIZE(innovator1510_io_desc));
-		udelay(10);	/* Delay needed for FPGA */
-
-		/* Dump the Innovator FPGA rev early - useful info for support. */
-		printk("Innovator FPGA Rev %d.%d Board Rev %d\n",
-		       fpga_read(OMAP1510_FPGA_REV_HIGH),
-		       fpga_read(OMAP1510_FPGA_REV_LOW),
-		       fpga_read(OMAP1510_FPGA_BOARD_REV));
-	}
-#endif
-	omap_serial_init(innovator_serial_ports);
-}
-
-MACHINE_START(OMAP_INNOVATOR, "TI-Innovator")
-	MAINTAINER("MontaVista Software, Inc.")
-	BOOT_MEM(0x10000000, 0xfff00000, 0xfef00000)
-	BOOT_PARAMS(0x10000100)
-	MAPIO(innovator_map_io)
-	INITIRQ(innovator_init_irq)
-	INIT_MACHINE(innovator_init)
-	.timer		= &omap_timer,
-MACHINE_END
diff --git a/arch/arm/mach-omap/board-netstar.c b/arch/arm/mach-omap/board-netstar.c
deleted file mode 100644
--- a/arch/arm/mach-omap/board-netstar.c
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Modified from board-generic.c
- *
- * Copyright (C) 2004 2N Telekomunikace, Ladislav Michl <michl@2n.cz>
- *
- * Code for Netstar OMAP board.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/delay.h>
-#include <linux/device.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/notifier.h>
-#include <linux/reboot.h>
-
-#include <asm/hardware.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-
-#include <asm/arch/gpio.h>
-#include <asm/arch/mux.h>
-#include <asm/arch/usb.h>
-
-#include "common.h"
-
-extern void __init omap_init_time(void);
-extern int omap_gpio_init(void);
-
-static struct resource netstar_smc91x_resources[] = {
-	[0] = {
-		.start	= OMAP_CS1_PHYS + 0x300,
-		.end	= OMAP_CS1_PHYS + 0x300 + 16,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= OMAP_GPIO_IRQ(8),
-		.end	= OMAP_GPIO_IRQ(8),
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device netstar_smc91x_device = {
-	.name		= "smc91x",
-	.id		= 0,
-	.num_resources	= ARRAY_SIZE(netstar_smc91x_resources),
-	.resource	= netstar_smc91x_resources,
-};
-
-static struct platform_device *netstar_devices[] __initdata = {
-	&netstar_smc91x_device,
-};
-
-static void __init netstar_init_irq(void)
-{
-	omap_init_irq();
-	omap_gpio_init();
-}
-
-static void __init netstar_init(void)
-{
-	/* green LED */
-	omap_request_gpio(4);
-	omap_set_gpio_direction(4, 0);
-	/* smc91x reset */
-	omap_request_gpio(7);
-	omap_set_gpio_direction(7, 0);
-	omap_set_gpio_dataout(7, 1);
-	udelay(2);	/* wait at least 100ns */
-	omap_set_gpio_dataout(7, 0);
-	mdelay(50);	/* 50ms until PHY ready */
-	/* smc91x interrupt pin */
-	omap_request_gpio(8);
-	omap_set_gpio_edge_ctrl(8, OMAP_GPIO_RISING_EDGE);
-
-	omap_request_gpio(12);
-	omap_request_gpio(13);
-	omap_request_gpio(14);
-	omap_request_gpio(15);
-	omap_set_gpio_edge_ctrl(12, OMAP_GPIO_FALLING_EDGE);
-	omap_set_gpio_edge_ctrl(13, OMAP_GPIO_FALLING_EDGE);
-	omap_set_gpio_edge_ctrl(14, OMAP_GPIO_FALLING_EDGE);
-	omap_set_gpio_edge_ctrl(15, OMAP_GPIO_FALLING_EDGE);
-
-	platform_add_devices(netstar_devices, ARRAY_SIZE(netstar_devices));
-
-	/* Switch on green LED */
-	omap_set_gpio_dataout(4, 0);
-	/* Switch off red LED */
-	omap_writeb(0x00, OMAP_LPG1_PMR);	/* Disable clock */
-	omap_writeb(0x80, OMAP_LPG1_LCR);
-}
-
-static int __initdata omap_serial_ports[OMAP_MAX_NR_PORTS] = {1, 1, 1};
-
-static void __init netstar_map_io(void)
-{
-	omap_map_io();
-	omap_serial_init(omap_serial_ports);
-}
-
-#define MACHINE_PANICED		1
-#define MACHINE_REBOOTING	2
-#define MACHINE_REBOOT		4
-static unsigned long machine_state;
-
-static int panic_event(struct notifier_block *this, unsigned long event,
-	 void *ptr)
-{
-	if (test_and_set_bit(MACHINE_PANICED, &machine_state))
-		return NOTIFY_DONE;
-
-	/* Switch off green LED */
-	omap_set_gpio_dataout(4, 1);
-	/* Flash red LED */
-	omap_writeb(0x78, OMAP_LPG1_LCR);
-	omap_writeb(0x01, OMAP_LPG1_PMR);	/* Enable clock */
-
-	return NOTIFY_DONE;
-}
-
-static struct notifier_block panic_block = {
-	.notifier_call	= panic_event,
-};
-
-static int __init netstar_late_init(void)
-{
-	/* TODO: Setup front panel switch here */
-
-	/* Setup panic notifier */
-	notifier_chain_register(&panic_notifier_list, &panic_block);
-
-	return 0;
-}
-
-postcore_initcall(netstar_late_init);
-
-MACHINE_START(NETSTAR, "NetStar OMAP5910")
-	MAINTAINER("Ladislav Michl <michl@2n.cz>")
-	BOOT_MEM(0x10000000, 0xfff00000, 0xfef00000)
-	BOOT_PARAMS(0x10000100)
-	MAPIO(netstar_map_io)
-	INITIRQ(netstar_init_irq)
-	INIT_MACHINE(netstar_init)
-	.timer = &omap_timer,
-MACHINE_END
diff --git a/arch/arm/mach-omap/board-osk.c b/arch/arm/mach-omap/board-osk.c
deleted file mode 100644
--- a/arch/arm/mach-omap/board-osk.c
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * linux/arch/arm/mach-omap/board-osk.c
- *
- * Board specific init for OMAP5912 OSK
- *
- * Written by Dirk Behme <dirk.behme@de.bosch.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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
- * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * You should have received a copy of the  GNU General Public License along
- * with this program; if not, write  to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/device.h>
-
-#include <asm/hardware.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-
-#include <asm/arch/gpio.h>
-#include <asm/arch/usb.h>
-#include <asm/arch/mux.h>
-#include <asm/arch/tc.h>
-
-#include "common.h"
-
-static struct map_desc osk5912_io_desc[] __initdata = {
-{ OMAP_OSK_NOR_FLASH_BASE, OMAP_OSK_NOR_FLASH_START, OMAP_OSK_NOR_FLASH_SIZE,
-	MT_DEVICE },
-};
-
-static int __initdata osk_serial_ports[OMAP_MAX_NR_PORTS] = {1, 0, 0};
-
-static struct resource osk5912_smc91x_resources[] = {
-	[0] = {
-		.start	= OMAP_OSK_ETHR_START,		/* Physical */
-		.end	= OMAP_OSK_ETHR_START + 0xf,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= OMAP_GPIO_IRQ(0),
-		.end	= OMAP_GPIO_IRQ(0),
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device osk5912_smc91x_device = {
-	.name		= "smc91x",
-	.id		= -1,
-	.num_resources	= ARRAY_SIZE(osk5912_smc91x_resources),
-	.resource	= osk5912_smc91x_resources,
-};
-
-static struct resource osk5912_cf_resources[] = {
-	[0] = {
-		.start	= OMAP_GPIO_IRQ(62),
-		.end	= OMAP_GPIO_IRQ(62),
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device osk5912_cf_device = {
-	.name		= "omap_cf",
-	.id		= -1,
-	.dev = {
-		.platform_data	= (void *) 2 /* CS2 */,
-	},
-	.num_resources	= ARRAY_SIZE(osk5912_cf_resources),
-	.resource	= osk5912_cf_resources,
-};
-
-static struct platform_device *osk5912_devices[] __initdata = {
-	&osk5912_smc91x_device,
-	&osk5912_cf_device,
-};
-
-static void __init osk_init_smc91x(void)
-{
-	if ((omap_request_gpio(0)) < 0) {
-		printk("Error requesting gpio 0 for smc91x irq\n");
-		return;
-	}
-	omap_set_gpio_edge_ctrl(0, OMAP_GPIO_RISING_EDGE);
-
-	/* Check EMIFS wait states to fix errors with SMC_GET_PKT_HDR */
-	EMIFS_CCS(1) |= 0x2;
-}
-
-static void __init osk_init_cf(void)
-{
-	omap_cfg_reg(M7_1610_GPIO62);
-	if ((omap_request_gpio(62)) < 0) {
-		printk("Error requesting gpio 62 for CF irq\n");
-		return;
-	}
-	/* it's really active-low */
-	omap_set_gpio_edge_ctrl(62, OMAP_GPIO_FALLING_EDGE);
-}
-
-void osk_init_irq(void)
-{
-	omap_init_irq();
-	omap_gpio_init();
-	osk_init_smc91x();
-	osk_init_cf();
-}
-
-static struct omap_usb_config osk_usb_config __initdata = {
-	/* has usb host connector (A) ... for development it can also
-	 * be used, with a NONSTANDARD gender-bending cable/dongle, as
-	 * a peripheral.
-	 */
-#ifdef	CONFIG_USB_GADGET_OMAP
-	.register_dev	= 1,
-	.hmc_mode	= 0,
-#else
-	.register_host	= 1,
-	.hmc_mode	= 16,
-	.rwc		= 1,
-#endif
-	.pins[0]	= 2,
-};
-
-static struct omap_board_config_kernel osk_config[] = {
-	{ OMAP_TAG_USB,           &osk_usb_config },
-};
-
-static void __init osk_init(void)
-{
-	platform_add_devices(osk5912_devices, ARRAY_SIZE(osk5912_devices));
-	omap_board_config = osk_config;
-	omap_board_config_size = ARRAY_SIZE(osk_config);
-	USB_TRANSCEIVER_CTRL_REG |= (3 << 1);
-}
-
-static void __init osk_map_io(void)
-{
-	omap_map_io();
-	iotable_init(osk5912_io_desc, ARRAY_SIZE(osk5912_io_desc));
-	omap_serial_init(osk_serial_ports);
-}
-
-MACHINE_START(OMAP_OSK, "TI-OSK")
-	MAINTAINER("Dirk Behme <dirk.behme@de.bosch.com>")
-	BOOT_MEM(0x10000000, 0xfff00000, 0xfef00000)
-	BOOT_PARAMS(0x10000100)
-	MAPIO(osk_map_io)
-	INITIRQ(osk_init_irq)
-	INIT_MACHINE(osk_init)
-	.timer		= &omap_timer,
-MACHINE_END
diff --git a/arch/arm/mach-omap/board-perseus2.c b/arch/arm/mach-omap/board-perseus2.c
deleted file mode 100644
--- a/arch/arm/mach-omap/board-perseus2.c
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * linux/arch/arm/mach-omap/board-perseus2.c
- *
- * Modified from board-generic.c
- *
- * Original OMAP730 support by Jean Pihet <j-pihet@ti.com>
- * Updated for 2.6 by Kevin Hilman <kjh@hilman.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.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/delay.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/partitions.h>
-
-#include <asm/hardware.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/flash.h>
-#include <asm/mach/map.h>
-
-#include <asm/arch/gpio.h>
-#include <asm/arch/mux.h>
-#include <asm/arch/fpga.h>
-
-#include "common.h"
-
-static struct resource smc91x_resources[] = {
-	[0] = {
-		.start	= H2P2_DBG_FPGA_ETHR_START,	/* Physical */
-		.end	= H2P2_DBG_FPGA_ETHR_START + 0xf,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= INT_730_MPU_EXT_NIRQ,
-		.end	= 0,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static int __initdata p2_serial_ports[OMAP_MAX_NR_PORTS] = {1, 1, 0};
-
-static struct mtd_partition p2_partitions[] = {
-	/* bootloader (U-Boot, etc) in first sector */
-	{
-	      .name		= "bootloader",
-	      .offset		= 0,
-	      .size		= SZ_128K,
-	      .mask_flags	= MTD_WRITEABLE, /* force read-only */
-	},
-	/* bootloader params in the next sector */
-	{
-	      .name		= "params",
-	      .offset		= MTDPART_OFS_APPEND,
-	      .size		= SZ_128K,
-	      .mask_flags	= 0,
-	},
-	/* kernel */
-	{
-	      .name		= "kernel",
-	      .offset		= MTDPART_OFS_APPEND,
-	      .size		= SZ_2M,
-	      .mask_flags	= 0
-	},
-	/* rest of flash is a file system */
-	{
-	      .name		= "rootfs",
-	      .offset		= MTDPART_OFS_APPEND,
-	      .size		= MTDPART_SIZ_FULL,
-	      .mask_flags	= 0
-	},
-};
-
-static struct flash_platform_data p2_flash_data = {
-	.map_name	= "cfi_probe",
-	.width		= 2,
-	.parts		= p2_partitions,
-	.nr_parts	= ARRAY_SIZE(p2_partitions),
-};
-
-static struct resource p2_flash_resource = {
-	.start		= OMAP_FLASH_0_START,
-	.end		= OMAP_FLASH_0_START + OMAP_FLASH_0_SIZE - 1,
-	.flags		= IORESOURCE_MEM,
-};
-
-static struct platform_device p2_flash_device = {
-	.name		= "omapflash",
-	.id		= 0,
-	.dev		= {
-		.platform_data	= &p2_flash_data,
-	},
-	.num_resources	= 1,
-	.resource	= &p2_flash_resource,
-};
-
-static struct platform_device smc91x_device = {
-	.name		= "smc91x",
-	.id		= 0,
-	.num_resources	= ARRAY_SIZE(smc91x_resources),
-	.resource	= smc91x_resources,
-};
-
-static struct platform_device *devices[] __initdata = {
-	&p2_flash_device,
-	&smc91x_device,
-};
-
-static void __init omap_perseus2_init(void)
-{
-	(void) platform_add_devices(devices, ARRAY_SIZE(devices));
-}
-
-static void __init perseus2_init_smc91x(void)
-{
-	fpga_write(1, H2P2_DBG_FPGA_LAN_RESET);
-	mdelay(50);
-	fpga_write(fpga_read(H2P2_DBG_FPGA_LAN_RESET) & ~1,
-		   H2P2_DBG_FPGA_LAN_RESET);
-	mdelay(50);
-}
-
-void omap_perseus2_init_irq(void)
-{
-	omap_init_irq();
-	omap_gpio_init();
-	perseus2_init_smc91x();
-}
-
-/* Only FPGA needs to be mapped here. All others are done with ioremap */
-static struct map_desc omap_perseus2_io_desc[] __initdata = {
-	{H2P2_DBG_FPGA_BASE, H2P2_DBG_FPGA_START, H2P2_DBG_FPGA_SIZE,
-	 MT_DEVICE},
-};
-
-static void __init omap_perseus2_map_io(void)
-{
-	omap_map_io();
-	iotable_init(omap_perseus2_io_desc,
-		     ARRAY_SIZE(omap_perseus2_io_desc));
-
-	/* Early, board-dependent init */
-
-	/*
-	 * Hold GSM Reset until needed
-	 */
-	omap_writew(omap_readw(OMAP730_DSP_M_CTL) & ~1, OMAP730_DSP_M_CTL);
-
-	/*
-	 * UARTs -> done automagically by 8250 driver
-	 */
-
-	/*
-	 * CSx timings, GPIO Mux ... setup
-	 */
-
-	/* Flash: CS0 timings setup */
-	omap_writel(0x0000fff3, OMAP730_FLASH_CFG_0);
-	omap_writel(0x00000088, OMAP730_FLASH_ACFG_0);
-
-	/*
-	 * Ethernet support trough the debug board
-	 * CS1 timings setup
-	 */
-	omap_writel(0x0000fff3, OMAP730_FLASH_CFG_1);
-	omap_writel(0x00000000, OMAP730_FLASH_ACFG_1);
-
-	/*
-	 * Configure MPU_EXT_NIRQ IO in IO_CONF9 register,
-	 * It is used as the Ethernet controller interrupt
-	 */
-	omap_writel(omap_readl(OMAP730_IO_CONF_9) & 0x1FFFFFFF, OMAP730_IO_CONF_9);
-	omap_serial_init(p2_serial_ports);
-}
-
-MACHINE_START(OMAP_PERSEUS2, "OMAP730 Perseus2")
-	MAINTAINER("Kevin Hilman <kjh@hilman.org>")
-	BOOT_MEM(0x10000000, 0xfff00000, 0xfef00000)
-	BOOT_PARAMS(0x10000100)
-	MAPIO(omap_perseus2_map_io)
-	INITIRQ(omap_perseus2_init_irq)
-	INIT_MACHINE(omap_perseus2_init)
-	.timer		= &omap_timer,
-MACHINE_END
diff --git a/arch/arm/mach-omap/board-voiceblue.c b/arch/arm/mach-omap/board-voiceblue.c
deleted file mode 100644
--- a/arch/arm/mach-omap/board-voiceblue.c
+++ /dev/null
@@ -1,256 +0,0 @@
-/*
- * linux/arch/arm/mach-omap/board-voiceblue.c
- *
- * Modified from board-generic.c
- *
- * Copyright (C) 2004 2N Telekomunikace, Ladislav Michl <michl@2n.cz>
- *
- * Code for OMAP5910 based VoiceBlue board (VoIP to GSM gateway).
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/delay.h>
-#include <linux/device.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/notifier.h>
-#include <linux/reboot.h>
-#include <linux/serial_8250.h>
-#include <linux/serial_reg.h>
-
-#include <asm/hardware.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-
-#include <asm/arch/gpio.h>
-#include <asm/arch/tc.h>
-#include <asm/arch/mux.h>
-#include <asm/arch/usb.h>
-
-#include "common.h"
-
-extern void omap_init_time(void);
-extern int omap_gpio_init(void);
-
-static struct plat_serial8250_port voiceblue_ports[] = {
-	{
-		.mapbase	= (unsigned long)(OMAP_CS1_PHYS + 0x40000),
-		.irq		= OMAP_GPIO_IRQ(12),
-		.flags		= UPF_BOOT_AUTOCONF | UPF_IOREMAP,
-		.iotype		= UPIO_MEM,
-		.regshift	= 1,
-		.uartclk	= 3686400,
-	},
-	{
-		.mapbase	= (unsigned long)(OMAP_CS1_PHYS + 0x50000),
-		.irq		= OMAP_GPIO_IRQ(13),
-		.flags		= UPF_BOOT_AUTOCONF | UPF_IOREMAP,
-		.iotype		= UPIO_MEM,
-		.regshift	= 1,
-		.uartclk	= 3686400,
-	},
-	{
-		.mapbase	= (unsigned long)(OMAP_CS1_PHYS + 0x60000),
-		.irq		= OMAP_GPIO_IRQ(14),
-		.flags		= UPF_BOOT_AUTOCONF | UPF_IOREMAP,
-		.iotype		= UPIO_MEM,
-		.regshift	= 1,
-		.uartclk	= 3686400,
-	},
-	{
-		.mapbase	= (unsigned long)(OMAP_CS1_PHYS + 0x70000),
-		.irq		= OMAP_GPIO_IRQ(15),
-		.flags		= UPF_BOOT_AUTOCONF | UPF_IOREMAP,
-		.iotype		= UPIO_MEM,
-		.regshift	= 1,
-		.uartclk	= 3686400,
-	},
-	{ },
-};
-
-static struct platform_device serial_device = {
-	.name			= "serial8250",
-	.id			= 1,
-	.dev			= {
-		.platform_data	= voiceblue_ports,
-	},
-};
-
-static int __init ext_uart_init(void)
-{
-	return platform_device_register(&serial_device);
-}
-arch_initcall(ext_uart_init);
-
-static struct resource voiceblue_smc91x_resources[] = {
-	[0] = {
-		.start	= OMAP_CS2_PHYS + 0x300,
-		.end	= OMAP_CS2_PHYS + 0x300 + 16,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= OMAP_GPIO_IRQ(8),
-		.end	= OMAP_GPIO_IRQ(8),
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device voiceblue_smc91x_device = {
-	.name		= "smc91x",
-	.id		= 0,
-	.num_resources	= ARRAY_SIZE(voiceblue_smc91x_resources),
-	.resource	= voiceblue_smc91x_resources,
-};
-
-static struct platform_device *voiceblue_devices[] __initdata = {
-	&voiceblue_smc91x_device,
-};
-
-static struct omap_usb_config voiceblue_usb_config __initdata = {
-	.hmc_mode	= 3,
-	.register_host	= 1,
-	.register_dev   = 1,
-	.pins[0]	= 2,
-	.pins[1]	= 6,
-	.pins[2]	= 6,
-};
-
-static struct omap_board_config_kernel voiceblue_config[] = {
-	{ OMAP_TAG_USB, &voiceblue_usb_config },
-};
-
-static void __init voiceblue_init_irq(void)
-{
-	omap_init_irq();
-	omap_gpio_init();
-}
-
-static void __init voiceblue_init(void)
-{
-	/* There is a good chance board is going up, so enable Power LED
-	 * (it is connected through invertor) */
-	omap_writeb(0x00, OMAP_LPG1_LCR);
-	/* Watchdog */
-	omap_request_gpio(0);
-	/* smc91x reset */
-	omap_request_gpio(7);
-	omap_set_gpio_direction(7, 0);
-	omap_set_gpio_dataout(7, 1);
-	udelay(2);	/* wait at least 100ns */
-	omap_set_gpio_dataout(7, 0);
-	mdelay(50);	/* 50ms until PHY ready */
-	/* smc91x interrupt pin */
-	omap_request_gpio(8);
-	omap_set_gpio_edge_ctrl(8, OMAP_GPIO_RISING_EDGE);
-	/* 16C554 reset*/
-	omap_request_gpio(6);
-	omap_set_gpio_direction(6, 0);
-	omap_set_gpio_dataout(6, 0);
-	/* 16C554 interrupt pins */
-	omap_request_gpio(12);
-	omap_request_gpio(13);
-	omap_request_gpio(14);
-	omap_request_gpio(15);
-	omap_set_gpio_edge_ctrl(12, OMAP_GPIO_RISING_EDGE);
-	omap_set_gpio_edge_ctrl(13, OMAP_GPIO_RISING_EDGE);
-	omap_set_gpio_edge_ctrl(14, OMAP_GPIO_RISING_EDGE);
-	omap_set_gpio_edge_ctrl(15, OMAP_GPIO_RISING_EDGE);
-
-	platform_add_devices(voiceblue_devices, ARRAY_SIZE(voiceblue_devices));
-	omap_board_config = voiceblue_config;
-	omap_board_config_size = ARRAY_SIZE(voiceblue_config);
-}
-
-static int __initdata omap_serial_ports[OMAP_MAX_NR_PORTS] = {1, 1, 1};
-
-static void __init voiceblue_map_io(void)
-{
-	omap_map_io();
-	omap_serial_init(omap_serial_ports);
-}
-
-#define MACHINE_PANICED		1
-#define MACHINE_REBOOTING	2
-#define MACHINE_REBOOT		4
-static unsigned long machine_state;
-
-static int panic_event(struct notifier_block *this, unsigned long event,
-	 void *ptr)
-{
-	if (test_and_set_bit(MACHINE_PANICED, &machine_state))
-		return NOTIFY_DONE;
-
-	/* Flash Power LED
-	 * (TODO: Enable clock right way (enabled in bootloader already)) */
-	omap_writeb(0x78, OMAP_LPG1_LCR);
-
-	return NOTIFY_DONE;
-}
-
-static struct notifier_block panic_block = {
-	.notifier_call	= panic_event,
-};
-
-static int __init setup_notifier(void)
-{
-	/* Setup panic notifier */
-	notifier_chain_register(&panic_notifier_list, &panic_block);
-
-	return 0;
-}
-
-postcore_initcall(setup_notifier);
-
-static int wdt_gpio_state;
-
-void voiceblue_wdt_enable(void)
-{
-	omap_set_gpio_direction(0, 0);
-	omap_set_gpio_dataout(0, 0);
-	omap_set_gpio_dataout(0, 1);
-	omap_set_gpio_dataout(0, 0);
-	wdt_gpio_state = 0;
-}
-
-void voiceblue_wdt_disable(void)
-{
-	omap_set_gpio_dataout(0, 0);
-	omap_set_gpio_dataout(0, 1);
-	omap_set_gpio_dataout(0, 0);
-	omap_set_gpio_direction(0, 1);
-}
-
-void voiceblue_wdt_ping(void)
-{
-	if (test_bit(MACHINE_REBOOT, &machine_state))
-		return;
-
-	wdt_gpio_state = !wdt_gpio_state;
-	omap_set_gpio_dataout(0, wdt_gpio_state);
-}
-
-void voiceblue_reset(void)
-{
-	set_bit(MACHINE_REBOOT, &machine_state);
-	voiceblue_wdt_enable();
-	while (1) ;
-}
-
-EXPORT_SYMBOL(voiceblue_wdt_enable);
-EXPORT_SYMBOL(voiceblue_wdt_disable);
-EXPORT_SYMBOL(voiceblue_wdt_ping);
-
-MACHINE_START(VOICEBLUE, "VoiceBlue OMAP5910")
-	MAINTAINER("Ladislav Michl <michl@2n.cz>")
-	BOOT_MEM(0x10000000, 0xfff00000, 0xfef00000)
-	BOOT_PARAMS(0x10000100)
-	MAPIO(voiceblue_map_io)
-	INITIRQ(voiceblue_init_irq)
-	INIT_MACHINE(voiceblue_init)
-	.timer = &omap_timer,
-MACHINE_END
diff --git a/arch/arm/mach-omap/clock.c b/arch/arm/mach-omap/clock.c
deleted file mode 100644
--- a/arch/arm/mach-omap/clock.c
+++ /dev/null
@@ -1,1076 +0,0 @@
-/*
- *  linux/arch/arm/mach-omap/clock.c
- *
- *  Copyright (C) 2004 Nokia corporation
- *  Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/errno.h>
-#include <linux/err.h>
-
-#include <asm/semaphore.h>
-#include <asm/hardware/clock.h>
-#include <asm/arch/board.h>
-#include <asm/arch/usb.h>
-
-#include "clock.h"
-
-static LIST_HEAD(clocks);
-static DECLARE_MUTEX(clocks_sem);
-static DEFINE_SPINLOCK(clockfw_lock);
-static void propagate_rate(struct clk *  clk);
-/* External clock (MCLK & BCLK) functions */
-static int set_ext_clk_rate(struct clk *  clk, unsigned long rate);
-static long round_ext_clk_rate(struct clk *  clk, unsigned long rate);
-static void init_ext_clk(struct clk *  clk);
-/* MPU virtual clock functions */
-static int select_table_rate(struct clk *  clk, unsigned long rate);
-static long round_to_table_rate(struct clk *  clk, unsigned long rate);
-void clk_setdpll(__u16, __u16);
-
-struct mpu_rate rate_table[] = {
-	/* MPU MHz, xtal MHz, dpll1 MHz, CKCTL, DPLL_CTL
-	 * armdiv, dspdiv, dspmmu, tcdiv, perdiv, lcddiv
-	 */
-#if defined(CONFIG_OMAP_ARM_216MHZ)
-	{ 216000000, 12000000, 216000000, 0x050d, 0x2910 }, /* 1/1/2/2/2/8 */
-#endif
-#if defined(CONFIG_OMAP_ARM_195MHZ)
-	{ 195000000, 13000000, 195000000, 0x050e, 0x2790 }, /* 1/1/2/2/4/8 */
-#endif
-#if defined(CONFIG_OMAP_ARM_192MHZ)
-	{ 192000000, 19200000, 192000000, 0x050f, 0x2510 }, /* 1/1/2/2/8/8 */
-	{ 192000000, 12000000, 192000000, 0x050f, 0x2810 }, /* 1/1/2/2/8/8 */
-	{  96000000, 12000000, 192000000, 0x055f, 0x2810 }, /* 2/2/2/2/8/8 */
-	{  48000000, 12000000, 192000000, 0x0ccf, 0x2810 }, /* 4/4/4/4/8/8 */
-	{  24000000, 12000000, 192000000, 0x0fff, 0x2810 }, /* 8/8/8/8/8/8 */
-#endif
-#if defined(CONFIG_OMAP_ARM_182MHZ)
-	{ 182000000, 13000000, 182000000, 0x050e, 0x2710 }, /* 1/1/2/2/4/8 */
-#endif
-#if defined(CONFIG_OMAP_ARM_168MHZ)
-	{ 168000000, 12000000, 168000000, 0x010f, 0x2710 }, /* 1/1/1/2/8/8 */
-#endif
-#if defined(CONFIG_OMAP_ARM_150MHZ)
-	{ 150000000, 12000000, 150000000, 0x150a, 0x2cb0 }, /* 0/0/1/1/2/2 */
-#endif
-#if defined(CONFIG_OMAP_ARM_120MHZ)
-	{ 120000000, 12000000, 120000000, 0x010a, 0x2510 }, /* 1/1/1/2/4/4 */
-#endif
-#if defined(CONFIG_OMAP_ARM_96MHZ)
-	{  96000000, 12000000,  96000000, 0x0005, 0x2410 }, /* 1/1/1/1/2/2 */
-#endif
-#if defined(CONFIG_OMAP_ARM_60MHZ)
-	{  60000000, 12000000,  60000000, 0x0005, 0x2290 }, /* 1/1/1/1/2/2 */
-#endif
-#if defined(CONFIG_OMAP_ARM_30MHZ)
-	{  30000000, 12000000,  60000000, 0x0555, 0x2290 }, /* 2/2/2/2/2/2 */
-#endif
-	{ 0, 0, 0, 0, 0 },
-};
-
-
-static void ckctl_recalc(struct clk *  clk)
-{
-	int dsor;
-
-	/* Calculate divisor encoded as 2-bit exponent */
-	dsor = 1 << (3 & (omap_readw(ARM_CKCTL) >> clk->rate_offset));
-	if (unlikely(clk->rate == clk->parent->rate / dsor))
-		return; /* No change, quick exit */
-	clk->rate = clk->parent->rate / dsor;
-
-	if (unlikely(clk->flags & RATE_PROPAGATES))
-		propagate_rate(clk);
-}
-
-
-static void followparent_recalc(struct clk *  clk)
-{
-	clk->rate = clk->parent->rate;
-}
-
-
-static void watchdog_recalc(struct clk *  clk)
-{
-	clk->rate = clk->parent->rate / 14;
-}
-
-
-static struct clk ck_ref = {
-	.name		= "ck_ref",
-	.rate		= 12000000,
-	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
-			  ALWAYS_ENABLED,
-};
-
-static struct clk ck_dpll1 = {
-	.name		= "ck_dpll1",
-	.parent		= &ck_ref,
-	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
-			  RATE_PROPAGATES | ALWAYS_ENABLED,
-};
-
-static struct clk ck_dpll1out = {
-	.name		= "ck_dpll1out",
-	.parent		= &ck_dpll1,
-	.flags		= CLOCK_IN_OMAP16XX,
-	.enable_reg	= ARM_IDLECT2,
-	.enable_bit	= EN_CKOUT_ARM,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk arm_ck = {
-	.name		= "arm_ck",
-	.parent		= &ck_dpll1,
-	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
-			  RATE_CKCTL | RATE_PROPAGATES | ALWAYS_ENABLED,
-	.rate_offset	= CKCTL_ARMDIV_OFFSET,
-	.recalc		= &ckctl_recalc,
-};
-
-static struct clk armper_ck = {
-	.name		= "armper_ck",
-	.parent		= &ck_dpll1,
-	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
-			  RATE_CKCTL,
-	.enable_reg	= ARM_IDLECT2,
-	.enable_bit	= EN_PERCK,
-	.rate_offset	= CKCTL_PERDIV_OFFSET,
-	.recalc		= &ckctl_recalc,
-};
-
-static struct clk arm_gpio_ck = {
-	.name		= "arm_gpio_ck",
-	.parent		= &ck_dpll1,
-	.flags		= CLOCK_IN_OMAP1510,
-	.enable_reg	= ARM_IDLECT2,
-	.enable_bit	= EN_GPIOCK,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk armxor_ck = {
-	.name		= "armxor_ck",
-	.parent		= &ck_ref,
-	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
-	.enable_reg	= ARM_IDLECT2,
-	.enable_bit	= EN_XORPCK,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk armtim_ck = {
-	.name		= "armtim_ck",
-	.parent		= &ck_ref,
-	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
-	.enable_reg	= ARM_IDLECT2,
-	.enable_bit	= EN_TIMCK,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk armwdt_ck = {
-	.name		= "armwdt_ck",
-	.parent		= &ck_ref,
-	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
-	.enable_reg	= ARM_IDLECT2,
-	.enable_bit	= EN_WDTCK,
-	.recalc		= &watchdog_recalc,
-};
-
-static struct clk arminth_ck16xx = {
-	.name		= "arminth_ck",
-	.parent		= &arm_ck,
-	.flags		= CLOCK_IN_OMAP16XX,
-	.recalc		= &followparent_recalc,
-	/* Note: On 16xx the frequency can be divided by 2 by programming
-	 * ARM_CKCTL:ARM_INTHCK_SEL(14) to 1
-	 *
-	 * 1510 version is in TC clocks.
-	 */
-};
-
-static struct clk dsp_ck = {
-	.name		= "dsp_ck",
-	.parent		= &ck_dpll1,
-	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
-			  RATE_CKCTL,
-	.enable_reg	= ARM_CKCTL,
-	.enable_bit	= EN_DSPCK,
-	.rate_offset	= CKCTL_DSPDIV_OFFSET,
-	.recalc		= &ckctl_recalc,
-};
-
-static struct clk dspmmu_ck = {
-	.name		= "dspmmu_ck",
-	.parent		= &ck_dpll1,
-	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
-			  RATE_CKCTL | ALWAYS_ENABLED,
-	.rate_offset	= CKCTL_DSPMMUDIV_OFFSET,
-	.recalc		= &ckctl_recalc,
-};
-
-static struct clk tc_ck = {
-	.name		= "tc_ck",
-	.parent		= &ck_dpll1,
-	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP730 |
-			  RATE_CKCTL | RATE_PROPAGATES | ALWAYS_ENABLED,
-	.rate_offset	= CKCTL_TCDIV_OFFSET,
-	.recalc		= &ckctl_recalc,
-};
-
-static struct clk arminth_ck1510 = {
-	.name		= "arminth_ck",
-	.parent		= &tc_ck,
-	.flags		= CLOCK_IN_OMAP1510,
-	.recalc		= &followparent_recalc,
-	/* Note: On 1510 the frequency follows TC_CK
-	 *
-	 * 16xx version is in MPU clocks.
-	 */
-};
-
-static struct clk tipb_ck = {
-	.name		= "tibp_ck",
-	.parent		= &tc_ck,
-	.flags		= CLOCK_IN_OMAP1510,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk l3_ocpi_ck = {
-	.name		= "l3_ocpi_ck",
-	.parent		= &tc_ck,
-	.flags		= CLOCK_IN_OMAP16XX,
-	.enable_reg	= ARM_IDLECT3,
-	.enable_bit	= EN_OCPI_CK,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk tc1_ck = {
-	.name		= "tc1_ck",
-	.parent		= &tc_ck,
-	.flags		= CLOCK_IN_OMAP16XX,
-	.enable_reg	= ARM_IDLECT3,
-	.enable_bit	= EN_TC1_CK,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk tc2_ck = {
-	.name		= "tc2_ck",
-	.parent		= &tc_ck,
-	.flags		= CLOCK_IN_OMAP16XX,
-	.enable_reg	= ARM_IDLECT3,
-	.enable_bit	= EN_TC2_CK,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk dma_ck = {
-	.name		= "dma_ck",
-	.parent		= &tc_ck,
-	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk dma_lcdfree_ck = {
-	.name		= "dma_lcdfree_ck",
-	.parent		= &tc_ck,
-	.flags		= CLOCK_IN_OMAP16XX,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk api_ck = {
-	.name		= "api_ck",
-	.parent		= &tc_ck,
-	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
-	.enable_reg	= ARM_IDLECT2,
-	.enable_bit	= EN_APICK,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk lb_ck = {
-	.name		= "lb_ck",
-	.parent		= &tc_ck,
-	.flags		= CLOCK_IN_OMAP1510,
-	.enable_reg	= ARM_IDLECT2,
-	.enable_bit	= EN_LBCK,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk rhea1_ck = {
-	.name		= "rhea1_ck",
-	.parent		= &tc_ck,
-	.flags		= CLOCK_IN_OMAP16XX,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk rhea2_ck = {
-	.name		= "rhea2_ck",
-	.parent		= &tc_ck,
-	.flags		= CLOCK_IN_OMAP16XX,
-	.recalc		= &followparent_recalc,
-};
-
-static struct clk lcd_ck = {
-	.name		= "lcd_ck",
-	.parent		= &ck_dpll1,
-	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP730 |
-			  RATE_CKCTL,
-	.enable_reg	= ARM_IDLECT2,
-	.enable_bit	= EN_LCDCK,
-	.rate_offset	= CKCTL_LCDDIV_OFFSET,
-	.recalc		= &ckctl_recalc,
-};
-
-static struct clk uart1_ck = {
-	.name		= "uart1_ck",
-	/* Direct from ULPD, no parent */
-	.rate		= 48000000,
-	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
-			  RATE_FIXED | ENABLE_REG_32BIT,
-	.enable_reg	= MOD_CONF_CTRL_0,
-	.enable_bit	= 29,
-	/* (Only on 1510)
-	 * The "enable bit" actually chooses between 48MHz and 12MHz.
-	 */
-};
-
-static struct clk uart2_ck = {
-	.name		= "uart2_ck",
-	/* Direct from ULPD, no parent */
-	.rate		= 48000000,
-	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
-			  RATE_FIXED | ENABLE_REG_32BIT,
-	.enable_reg	= MOD_CONF_CTRL_0,
-	.enable_bit	= 30,
-	/* (for both 1510 and 16xx)
-	 * The "enable bit" actually chooses between 48MHz and 12MHz/32kHz.
-	 */
-};
-
-static struct clk uart3_ck = {
-	.name		= "uart3_ck",
-	/* Direct from ULPD, no parent */
-	.rate		= 48000000,
-	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
-			  RATE_FIXED | ENABLE_REG_32BIT,
-	.enable_reg	= MOD_CONF_CTRL_0,
-	.enable_bit	= 31,
-	/* (Only on 1510)
-	 * The "enable bit" actually chooses between 48MHz and 12MHz.
-	 */
-};
-
-static struct clk usb_clko = {	/* 6 MHz output on W4_USB_CLKO */
-	.name		= "usb_clko",
-	/* Direct from ULPD, no parent */
-	.rate		= 6000000,
-	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
-			  RATE_FIXED | ENABLE_REG_32BIT,
-	.enable_reg	= ULPD_CLOCK_CTRL,
-	.enable_bit	= USB_MCLK_EN_BIT,
-};
-
-static struct clk usb_hhc_ck1510 = {
-	.name		= "usb_hhc_ck",
-	/* Direct from ULPD, no parent */
-	.rate		= 48000000, /* Actually 2 clocks, 12MHz and 48MHz */
-	.flags		= CLOCK_IN_OMAP1510 |
-			  RATE_FIXED | ENABLE_REG_32BIT,
-	.enable_reg	= MOD_CONF_CTRL_0,
-	.enable_bit	= USB_HOST_HHC_UHOST_EN,
-};
-
-static struct clk usb_hhc_ck16xx = {
-	.name		= "usb_hhc_ck",
-	/* Direct from ULPD, no parent */
-	.rate		= 48000000,
-	/* OTG_SYSCON_2.OTG_PADEN == 0 (not 1510-compatible) */
-	.flags		= CLOCK_IN_OMAP16XX |
-			  RATE_FIXED | ENABLE_REG_32BIT,
-	.enable_reg	= OTG_BASE + 0x08 /* OTG_SYSCON_2 */,
-	.enable_bit	= 8 /* UHOST_EN */,
-};
-
-static struct clk mclk_1510 = {
-	.name		= "mclk",
-	/* Direct from ULPD, no parent. May be enabled by ext hardware. */
-	.rate		= 12000000,
-	.flags		= CLOCK_IN_OMAP1510 | RATE_FIXED,
-};
-
-static struct clk mclk_16xx = {
-	.name		= "mclk",
-	/* Direct from ULPD, no parent. May be enabled by ext hardware. */
-	.flags		= CLOCK_IN_OMAP16XX,
-	.enable_reg	= COM_CLK_DIV_CTRL_SEL,
-	.enable_bit	= COM_ULPD_PLL_CLK_REQ,
-	.set_rate	= &set_ext_clk_rate,
-	.round_rate	= &round_ext_clk_rate,
-	.init		= &init_ext_clk,
-};
-
-static struct clk bclk_1510 = {
-	.name		= "bclk",
-	/* Direct from ULPD, no parent. May be enabled by ext hardware. */
-	.rate		= 12000000,
-	.flags		= CLOCK_IN_OMAP1510 | RATE_FIXED,
-};
-
-static struct clk bclk_16xx = {
-	.name		= "bclk",
-	/* Direct from ULPD, no parent. May be enabled by ext hardware. */
-	.flags		= CLOCK_IN_OMAP16XX,
-	.enable_reg	= SWD_CLK_DIV_CTRL_SEL,
-	.enable_bit	= SWD_ULPD_PLL_CLK_REQ,
-	.set_rate	= &set_ext_clk_rate,
-	.round_rate	= &round_ext_clk_rate,
-	.init		= &init_ext_clk,
-};
-
-static struct clk mmc1_ck = {
-	.name		= "mmc1_ck",
-	/* Functional clock is direct from ULPD, interface clock is ARMPER */
-	.parent		= &armper_ck,
-	.rate		= 48000000,
-	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
-			  RATE_FIXED | ENABLE_REG_32BIT,
-	.enable_reg	= MOD_CONF_CTRL_0,
-	.enable_bit	= 23,
-};
-
-static struct clk mmc2_ck = {
-	.name		= "mmc2_ck",
-	/* Functional clock is direct from ULPD, interface clock is ARMPER */
-	.parent		= &armper_ck,
-	.rate		= 48000000,
-	.flags		= CLOCK_IN_OMAP16XX |
-			  RATE_FIXED | ENABLE_REG_32BIT,
-	.enable_reg	= MOD_CONF_CTRL_0,
-	.enable_bit	= 20,
-};
-
-static struct clk virtual_ck_mpu = {
-	.name		= "mpu",
-	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
-			  VIRTUAL_CLOCK | ALWAYS_ENABLED,
-	.parent		= &arm_ck, /* Is smarter alias for */
-	.recalc		= &followparent_recalc,
-	.set_rate	= &select_table_rate,
-	.round_rate	= &round_to_table_rate,
-};
-
-
-static struct clk *  onchip_clks[] = {
-	/* non-ULPD clocks */
-	&ck_ref,
-	&ck_dpll1,
-	/* CK_GEN1 clocks */
-	&ck_dpll1out,
-	&arm_ck,
-	&armper_ck,
-	&arm_gpio_ck,
-	&armxor_ck,
-	&armtim_ck,
-	&armwdt_ck,
-	&arminth_ck1510,  &arminth_ck16xx,
-	/* CK_GEN2 clocks */
-	&dsp_ck,
-	&dspmmu_ck,
-	/* CK_GEN3 clocks */
-	&tc_ck,
-	&tipb_ck,
-	&l3_ocpi_ck,
-	&tc1_ck,
-	&tc2_ck,
-	&dma_ck,
-	&dma_lcdfree_ck,
-	&api_ck,
-	&lb_ck,
-	&rhea1_ck,
-	&rhea2_ck,
-	&lcd_ck,
-	/* ULPD clocks */
-	&uart1_ck,
-	&uart2_ck,
-	&uart3_ck,
-	&usb_clko,
-	&usb_hhc_ck1510, &usb_hhc_ck16xx,
-	&mclk_1510,  &mclk_16xx,
-	&bclk_1510,  &bclk_16xx,
-	&mmc1_ck,
-	&mmc2_ck,
-	/* Virtual clocks */
-	&virtual_ck_mpu,
-};
-
-struct clk *clk_get(struct device *dev, const char *id)
-{
-	struct clk *p, *clk = ERR_PTR(-ENOENT);
-
-	down(&clocks_sem);
-	list_for_each_entry(p, &clocks, node) {
-		if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
-			clk = p;
-			break;
-		}
-	}
-	up(&clocks_sem);
-
-	return clk;
-}
-EXPORT_SYMBOL(clk_get);
-
-
-void clk_put(struct clk *clk)
-{
-	if (clk && !IS_ERR(clk))
-		module_put(clk->owner);
-}
-EXPORT_SYMBOL(clk_put);
-
-
-int __clk_enable(struct clk *clk)
-{
-	__u16 regval16;
-	__u32 regval32;
-
-	if (clk->flags & ALWAYS_ENABLED)
-		return 0;
-
-	if (unlikely(clk->enable_reg == 0)) {
-		printk(KERN_ERR "clock.c: Enable for %s without enable code\n",
-		       clk->name);
-		return 0;
-	}
-
-	if (clk->flags & ENABLE_REG_32BIT) {
-		regval32 = omap_readl(clk->enable_reg);
-		regval32 |= (1 << clk->enable_bit);
-		omap_writel(regval32, clk->enable_reg);
-	} else {
-		regval16 = omap_readw(clk->enable_reg);
-		regval16 |= (1 << clk->enable_bit);
-		omap_writew(regval16, clk->enable_reg);
-	}
-
-	return 0;
-}
-
-
-void __clk_disable(struct clk *clk)
-{
-	__u16 regval16;
-	__u32 regval32;
-
-	if (clk->enable_reg == 0)
-		return;
-
-	if (clk->flags & ENABLE_REG_32BIT) {
-		regval32 = omap_readl(clk->enable_reg);
-		regval32 &= ~(1 << clk->enable_bit);
-		omap_writel(regval32, clk->enable_reg);
-	} else {
-		regval16 = omap_readw(clk->enable_reg);
-		regval16 &= ~(1 << clk->enable_bit);
-		omap_writew(regval16, clk->enable_reg);
-	}
-}
-
-
-void __clk_unuse(struct clk *clk)
-{
-	if (clk->usecount > 0 && !(--clk->usecount)) {
-		__clk_disable(clk);
-		if (likely(clk->parent))
-			__clk_unuse(clk->parent);
-	}
-}
-
-
-int __clk_use(struct clk *clk)
-{
-	int ret = 0;
-	if (clk->usecount++ == 0) {
-		if (likely(clk->parent))
-			ret = __clk_use(clk->parent);
-
-		if (unlikely(ret != 0)) {
-			clk->usecount--;
-			return ret;
-		}
-
-		ret = __clk_enable(clk);
-
-		if (unlikely(ret != 0) && clk->parent) {
-			__clk_unuse(clk->parent);
-			clk->usecount--;
-		}
-	}
-
-	return ret;
-}
-
-
-int clk_enable(struct clk *clk)
-{
-	unsigned long flags;
-	int ret;
-
-	spin_lock_irqsave(&clockfw_lock, flags);
-	ret = __clk_enable(clk);
-	spin_unlock_irqrestore(&clockfw_lock, flags);
-	return ret;
-}
-EXPORT_SYMBOL(clk_enable);
-
-
-void clk_disable(struct clk *clk)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&clockfw_lock, flags);
-	__clk_disable(clk);
-	spin_unlock_irqrestore(&clockfw_lock, flags);
-}
-EXPORT_SYMBOL(clk_disable);
-
-
-int clk_use(struct clk *clk)
-{
-	unsigned long flags;
-	int ret = 0;
-
-	spin_lock_irqsave(&clockfw_lock, flags);
-	ret = __clk_use(clk);
-	spin_unlock_irqrestore(&clockfw_lock, flags);
-	return ret;
-}
-EXPORT_SYMBOL(clk_use);
-
-
-void clk_unuse(struct clk *clk)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&clockfw_lock, flags);
-	__clk_unuse(clk);
-	spin_unlock_irqrestore(&clockfw_lock, flags);
-}
-EXPORT_SYMBOL(clk_unuse);
-
-
-int clk_get_usecount(struct clk *clk)
-{
-        return clk->usecount;
-}
-EXPORT_SYMBOL(clk_get_usecount);
-
-
-unsigned long clk_get_rate(struct clk *clk)
-{
-	return clk->rate;
-}
-EXPORT_SYMBOL(clk_get_rate);
-
-
-static __u16 verify_ckctl_value(__u16 newval)
-{
-	/* This function checks for following limitations set
-	 * by the hardware (all conditions must be true):
-	 * DSPMMU_CK == DSP_CK  or  DSPMMU_CK == DSP_CK/2
-	 * ARM_CK >= TC_CK
-	 * DSP_CK >= TC_CK
-	 * DSPMMU_CK >= TC_CK
-	 *
-	 * In addition following rules are enforced:
-	 * LCD_CK <= TC_CK
-	 * ARMPER_CK <= TC_CK
-	 *
-	 * However, maximum frequencies are not checked for!
-	 */
-	__u8 per_exp;
-	__u8 lcd_exp;
-	__u8 arm_exp;
-	__u8 dsp_exp;
-	__u8 tc_exp;
-	__u8 dspmmu_exp;
-
-	per_exp = (newval >> CKCTL_PERDIV_OFFSET) & 3;
-	lcd_exp = (newval >> CKCTL_LCDDIV_OFFSET) & 3;
-	arm_exp = (newval >> CKCTL_ARMDIV_OFFSET) & 3;
-	dsp_exp = (newval >> CKCTL_DSPDIV_OFFSET) & 3;
-	tc_exp = (newval >> CKCTL_TCDIV_OFFSET) & 3;
-	dspmmu_exp = (newval >> CKCTL_DSPMMUDIV_OFFSET) & 3;
-
-	if (dspmmu_exp < dsp_exp)
-		dspmmu_exp = dsp_exp;
-	if (dspmmu_exp > dsp_exp+1)
-		dspmmu_exp = dsp_exp+1;
-	if (tc_exp < arm_exp)
-		tc_exp = arm_exp;
-	if (tc_exp < dspmmu_exp)
-		tc_exp = dspmmu_exp;
-	if (tc_exp > lcd_exp)
-		lcd_exp = tc_exp;
-	if (tc_exp > per_exp)
-		per_exp = tc_exp;
-
-	newval &= 0xf000;
-	newval |= per_exp << CKCTL_PERDIV_OFFSET;
-	newval |= lcd_exp << CKCTL_LCDDIV_OFFSET;
-	newval |= arm_exp << CKCTL_ARMDIV_OFFSET;
-	newval |= dsp_exp << CKCTL_DSPDIV_OFFSET;
-	newval |= tc_exp << CKCTL_TCDIV_OFFSET;
-	newval |= dspmmu_exp << CKCTL_DSPMMUDIV_OFFSET;
-
-	return newval;
-}
-
-
-static int calc_dsor_exp(struct clk *clk, unsigned long rate)
-{
-	/* Note: If target frequency is too low, this function will return 4,
-	 * which is invalid value. Caller must check for this value and act
-	 * accordingly.
-	 *
-	 * Note: This function does not check for following limitations set
-	 * by the hardware (all conditions must be true):
-	 * DSPMMU_CK == DSP_CK  or  DSPMMU_CK == DSP_CK/2
-	 * ARM_CK >= TC_CK
-	 * DSP_CK >= TC_CK
-	 * DSPMMU_CK >= TC_CK
-	 */
-	unsigned long realrate;
-	struct clk *  parent;
-	unsigned  dsor_exp;
-
-	if (unlikely(!(clk->flags & RATE_CKCTL)))
-		return -EINVAL;
-
-	parent = clk->parent;
-	if (unlikely(parent == 0))
-		return -EIO;
-
-	realrate = parent->rate;
-	for (dsor_exp=0; dsor_exp<4; dsor_exp++) {
-		if (realrate <= rate)
-			break;
-
-		realrate /= 2;
-	}
-
-	return dsor_exp;
-}
-
-long clk_round_rate(struct clk *clk, unsigned long rate)
-{
-	int dsor_exp;
-
-	if (clk->flags & RATE_FIXED)
-		return clk->rate;
-
-	if (clk->flags & RATE_CKCTL) {
-		dsor_exp = calc_dsor_exp(clk, rate);
-		if (dsor_exp < 0)
-			return dsor_exp;
-		if (dsor_exp > 3)
-			dsor_exp = 3;
-		return clk->parent->rate / (1 << dsor_exp);
-	}
-
-	if(clk->round_rate != 0)
-		return clk->round_rate(clk, rate);
-
-	return clk->rate;
-}
-EXPORT_SYMBOL(clk_round_rate);
-
-
-static void propagate_rate(struct clk *  clk)
-{
-	struct clk **  clkp;
-
-	for (clkp = onchip_clks; clkp < onchip_clks+ARRAY_SIZE(onchip_clks); clkp++) {
-		if (likely((*clkp)->parent != clk)) continue;
-		if (likely((*clkp)->recalc))
-			(*clkp)->recalc(*clkp);
-	}
-}
-
-
-static int select_table_rate(struct clk *  clk, unsigned long rate)
-{
-	/* Find the highest supported frequency <= rate and switch to it */
-	struct mpu_rate *  ptr;
-
-	if (clk != &virtual_ck_mpu)
-		return -EINVAL;
-
-	for (ptr = rate_table; ptr->rate; ptr++) {
-		if (ptr->xtal != ck_ref.rate)
-			continue;
-
-		/* DPLL1 cannot be reprogrammed without risking system crash */
-		if (likely(ck_dpll1.rate!=0) && ptr->pll_rate != ck_dpll1.rate)
-			continue;
-
-		/* Can check only after xtal frequency check */
-		if (ptr->rate <= rate)
-			break;
-	}
-
-	if (!ptr->rate)
-		return -EINVAL;
-
-	if (unlikely(ck_dpll1.rate == 0)) {
-		omap_writew(ptr->dpllctl_val, DPLL_CTL);
-		ck_dpll1.rate = ptr->pll_rate;
-	}
-	omap_writew(ptr->ckctl_val, ARM_CKCTL);
-	propagate_rate(&ck_dpll1);
-	return 0;
-}
-
-
-static long round_to_table_rate(struct clk *  clk, unsigned long rate)
-{
-	/* Find the highest supported frequency <= rate */
-	struct mpu_rate *  ptr;
-	long  highest_rate;
-
-	if (clk != &virtual_ck_mpu)
-		return -EINVAL;
-
-	highest_rate = -EINVAL;
-
-	for (ptr = rate_table; ptr->rate; ptr++) {
-		if (ptr->xtal != ck_ref.rate)
-			continue;
-
-		highest_rate = ptr->rate;
-
-		/* Can check only after xtal frequency check */
-		if (ptr->rate <= rate)
-			break;
-	}
-
-	return highest_rate;
-}
-
-
-int clk_set_rate(struct clk *clk, unsigned long rate)
-{
-	int  ret = -EINVAL;
-	int  dsor_exp;
-	__u16  regval;
-	unsigned long  flags;
-
-	if (clk->flags & RATE_CKCTL) {
-		dsor_exp = calc_dsor_exp(clk, rate);
-		if (dsor_exp > 3)
-			dsor_exp = -EINVAL;
-		if (dsor_exp < 0)
-			return dsor_exp;
-
-		spin_lock_irqsave(&clockfw_lock, flags);
-		regval = omap_readw(ARM_CKCTL);
-		regval &= ~(3 << clk->rate_offset);
-		regval |= dsor_exp << clk->rate_offset;
-		regval = verify_ckctl_value(regval);
-		omap_writew(regval, ARM_CKCTL);
-		clk->rate = clk->parent->rate / (1 << dsor_exp);
-		spin_unlock_irqrestore(&clockfw_lock, flags);
-		ret = 0;
-	} else if(clk->set_rate != 0) {
-		spin_lock_irqsave(&clockfw_lock, flags);
-		ret = clk->set_rate(clk, rate);
-		spin_unlock_irqrestore(&clockfw_lock, flags);
-	}
-
-	if (unlikely(ret == 0 && (clk->flags & RATE_PROPAGATES)))
-		propagate_rate(clk);
-
-	return ret;
-}
-EXPORT_SYMBOL(clk_set_rate);
-
-
-static unsigned calc_ext_dsor(unsigned long rate)
-{
-	unsigned dsor;
-
-	/* MCLK and BCLK divisor selection is not linear:
-	 * freq = 96MHz / dsor
-	 *
-	 * RATIO_SEL range: dsor <-> RATIO_SEL
-	 * 0..6: (RATIO_SEL+2) <-> (dsor-2)
-	 * 6..48:  (8+(RATIO_SEL-6)*2) <-> ((dsor-8)/2+6)
-	 * Minimum dsor is 2 and maximum is 96. Odd divisors starting from 9
-	 * can not be used.
-	 */
-	for (dsor = 2; dsor < 96; ++dsor) {
-		if ((dsor & 1) && dsor > 8)
-		  	continue;
-		if (rate >= 96000000 / dsor)
-			break;
-	}
-	return dsor;
-}
-
-
-static int set_ext_clk_rate(struct clk *  clk, unsigned long rate)
-{
-	unsigned dsor;
-	__u16 ratio_bits;
-
-	dsor = calc_ext_dsor(rate);
-	clk->rate = 96000000 / dsor;
-	if (dsor > 8)
-		ratio_bits = ((dsor - 8) / 2 + 6) << 2;
-	else
-		ratio_bits = (dsor - 2) << 2;
-
-	ratio_bits |= omap_readw(clk->enable_reg) & ~0xfd;
-	omap_writew(ratio_bits, clk->enable_reg);
-
-	return 0;
-}
-
-
-static long round_ext_clk_rate(struct clk *  clk, unsigned long rate)
-{
-	return 96000000 / calc_ext_dsor(rate);
-}
-
-
-static void init_ext_clk(struct clk *  clk)
-{
-	unsigned dsor;
-	__u16 ratio_bits;
-
-	/* Determine current rate and ensure clock is based on 96MHz APLL */
-	ratio_bits = omap_readw(clk->enable_reg) & ~1;
-	omap_writew(ratio_bits, clk->enable_reg);
-
-	ratio_bits = (ratio_bits & 0xfc) >> 2;
-	if (ratio_bits > 6)
-		dsor = (ratio_bits - 6) * 2 + 8;
-	else
-		dsor = ratio_bits + 2;
-
-	clk-> rate = 96000000 / dsor;
-}
-
-
-int clk_register(struct clk *clk)
-{
-	down(&clocks_sem);
-	list_add(&clk->node, &clocks);
-	if (clk->init)
-		clk->init(clk);
-	up(&clocks_sem);
-	return 0;
-}
-EXPORT_SYMBOL(clk_register);
-
-void clk_unregister(struct clk *clk)
-{
-	down(&clocks_sem);
-	list_del(&clk->node);
-	up(&clocks_sem);
-}
-EXPORT_SYMBOL(clk_unregister);
-
-
-
-int __init clk_init(void)
-{
-	struct clk **  clkp;
-	const struct omap_clock_config *info;
-	int crystal_type = 0; /* Default 12 MHz */
-
-	for (clkp = onchip_clks; clkp < onchip_clks+ARRAY_SIZE(onchip_clks); clkp++) {
-		if (((*clkp)->flags &CLOCK_IN_OMAP1510) && cpu_is_omap1510()) {
-			clk_register(*clkp);
-			continue;
-		}
-
-		if (((*clkp)->flags &CLOCK_IN_OMAP16XX) && cpu_is_omap16xx()) {
-			clk_register(*clkp);
-			continue;
-		}
-
-		if (((*clkp)->flags &CLOCK_IN_OMAP730) && cpu_is_omap730()) {
-			clk_register(*clkp);
-			continue;
-		}
-	}
-
-	info = omap_get_config(OMAP_TAG_CLOCK, struct omap_clock_config);
-	if (info != NULL) {
-		if (!cpu_is_omap1510())
-			crystal_type = info->system_clock_type;
-	}
-
-#if defined(CONFIG_ARCH_OMAP730)
-	ck_ref.rate = 13000000;
-#elif defined(CONFIG_ARCH_OMAP16XX)
-	if (crystal_type == 2)
-		ck_ref.rate = 19200000;
-#endif
-
-	/* We want to be in syncronous scalable mode */
-	omap_writew(0x1000, ARM_SYSST);
-
-	/* Find the highest supported frequency and enable it */
-	if (select_table_rate(&virtual_ck_mpu, ~0)) {
-		printk(KERN_ERR "System frequencies not set. Check your config.\n");
-		/* Guess sane values (60MHz) */
-		omap_writew(0x2290, DPLL_CTL);
-		omap_writew(0x1005, ARM_CKCTL);
-		ck_dpll1.rate = 60000000;
-		propagate_rate(&ck_dpll1);
-		printk(KERN_INFO "Clocking rate (xtal/DPLL1/MPU): %ld/%ld/%ld\n",
-		       ck_ref.rate, ck_dpll1.rate, arm_ck.rate);
-	}
-
-	/* Cache rates for clocks connected to ck_ref (not dpll1) */
-	propagate_rate(&ck_ref);
-
-#ifdef CONFIG_MACH_OMAP_PERSEUS2
-	/* Select slicer output as OMAP input clock */
-	omap_writew(omap_readw(OMAP730_PCC_UPLD_CTRL) & ~0x1, OMAP730_PCC_UPLD_CTRL);
-#endif
-
-	/* Turn off DSP and ARM_TIMXO. Make sure ARM_INTHCK is not divided */
-	omap_writew(omap_readw(ARM_CKCTL) & 0x0fff, ARM_CKCTL);
-
-	/* Put DSP/MPUI into reset until needed */
-	omap_writew(0, ARM_RSTCT1);
-	omap_writew(1, ARM_RSTCT2);
-	omap_writew(0x400, ARM_IDLECT1);
-
-	/*
-	 * According to OMAP5910 Erratum SYS_DMA_1, bit DMACK_REQ (bit 8)
-	 * of the ARM_IDLECT2 register must be set to zero. The power-on
-	 * default value of this bit is one.
-	 */
-	omap_writew(0x0000, ARM_IDLECT2);	/* Turn LCD clock off also */
-
-	/*
-	 * Only enable those clocks we will need, let the drivers
-	 * enable other clocks as necessary
-	 */
-	clk_use(&armper_ck);
-	clk_use(&armxor_ck);
-	clk_use(&armtim_ck);
-
-	if (cpu_is_omap1510())
-		clk_enable(&arm_gpio_ck);
-
-	return 0;
-}
diff --git a/arch/arm/mach-omap/clock.h b/arch/arm/mach-omap/clock.h
deleted file mode 100644
--- a/arch/arm/mach-omap/clock.h
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- *  linux/arch/arm/mach-omap/clock.h
- *
- *  Copyright (C) 2004 Nokia corporation
- *  Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
- *  Based on clocks.h by Tony Lindgren, Gordon McNutt and RidgeRun, Inc
- *
- * 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.
- */
-
-#ifndef __ARCH_ARM_OMAP_CLOCK_H
-#define __ARCH_ARM_OMAP_CLOCK_H
-
-struct module;
-
-struct clk {
-	struct list_head	node;
-	struct module		*owner;
-	const char		*name;
-	struct clk		*parent;
-	unsigned long		rate;
-	__s8			usecount;
-	__u16			flags;
-	__u32			enable_reg;
-	__u8			enable_bit;
-	__u8			rate_offset;
-	void			(*recalc)(struct clk *);
-	int			(*set_rate)(struct clk *, unsigned long);
-	long			(*round_rate)(struct clk *, unsigned long);
-	void			(*init)(struct clk *);
-};
-
-
-struct mpu_rate {
-	unsigned long		rate;
-	unsigned long		xtal;
-	unsigned long		pll_rate;
-	__u16			ckctl_val;
-	__u16			dpllctl_val;
-};
-
-
-/* Clock flags */
-#define RATE_CKCTL		1
-#define RATE_FIXED		2
-#define RATE_PROPAGATES		4
-#define VIRTUAL_CLOCK		8
-#define ALWAYS_ENABLED		16
-#define ENABLE_REG_32BIT	32
-#define CLOCK_IN_OMAP16XX	64
-#define CLOCK_IN_OMAP1510	128
-#define CLOCK_IN_OMAP730	256
-
-/* ARM_CKCTL bit shifts */
-#define CKCTL_PERDIV_OFFSET	0
-#define CKCTL_LCDDIV_OFFSET	2
-#define CKCTL_ARMDIV_OFFSET	4
-#define CKCTL_DSPDIV_OFFSET	6
-#define CKCTL_TCDIV_OFFSET	8
-#define CKCTL_DSPMMUDIV_OFFSET	10
-/*#define ARM_TIMXO		12*/
-#define EN_DSPCK		13
-/*#define ARM_INTHCK_SEL	14*/ /* Divide-by-2 for mpu inth_ck */
-
-/* ARM_IDLECT1 bit shifts */
-/*#define IDLWDT_ARM	0*/
-/*#define IDLXORP_ARM	1*/
-/*#define IDLPER_ARM	2*/
-/*#define IDLLCD_ARM	3*/
-/*#define IDLLB_ARM	4*/
-/*#define IDLHSAB_ARM	5*/
-/*#define IDLIF_ARM	6*/
-/*#define IDLDPLL_ARM	7*/
-/*#define IDLAPI_ARM	8*/
-/*#define IDLTIM_ARM	9*/
-/*#define SETARM_IDLE	11*/
-
-/* ARM_IDLECT2 bit shifts */
-#define EN_WDTCK	0
-#define EN_XORPCK	1
-#define EN_PERCK	2
-#define EN_LCDCK	3
-#define EN_LBCK		4 /* Not on 1610/1710 */
-/*#define EN_HSABCK	5*/
-#define EN_APICK	6
-#define EN_TIMCK	7
-#define DMACK_REQ	8
-#define EN_GPIOCK	9 /* Not on 1610/1710 */
-/*#define EN_LBFREECK	10*/
-#define EN_CKOUT_ARM	11
-
-/* ARM_IDLECT3 bit shifts */
-#define EN_OCPI_CK	0
-#define EN_TC1_CK	2
-#define EN_TC2_CK	4
-
-/* Various register defines for clock controls scattered around OMAP chip */
-#define USB_MCLK_EN_BIT		4	/* In ULPD_CLKC_CTRL */
-#define USB_HOST_HHC_UHOST_EN	9	/* In MOD_CONF_CTRL_0 */
-#define SWD_ULPD_PLL_CLK_REQ	1	/* In SWD_CLK_DIV_CTRL_SEL */
-#define COM_ULPD_PLL_CLK_REQ	1	/* In COM_CLK_DIV_CTRL_SEL */
-#define SWD_CLK_DIV_CTRL_SEL	0xfffe0874
-#define COM_CLK_DIV_CTRL_SEL	0xfffe0878
-
-
-int clk_register(struct clk *clk);
-void clk_unregister(struct clk *clk);
-int clk_init(void);
-
-#endif
diff --git a/arch/arm/mach-omap/common.c b/arch/arm/mach-omap/common.c
deleted file mode 100644
--- a/arch/arm/mach-omap/common.c
+++ /dev/null
@@ -1,549 +0,0 @@
-/*
- * linux/arch/arm/mach-omap/common.c
- *
- * Code common to all OMAP machines.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/pm.h>
-#include <linux/console.h>
-#include <linux/serial.h>
-#include <linux/tty.h>
-#include <linux/serial_8250.h>
-#include <linux/serial_reg.h>
-
-#include <asm/hardware.h>
-#include <asm/system.h>
-#include <asm/pgtable.h>
-#include <asm/mach/map.h>
-#include <asm/hardware/clock.h>
-#include <asm/io.h>
-#include <asm/mach-types.h>
-
-#include <asm/arch/board.h>
-#include <asm/arch/mux.h>
-#include <asm/arch/fpga.h>
-
-#include "clock.h"
-
-#define DEBUG 1
-
-struct omap_id {
-	u16	jtag_id;	/* Used to determine OMAP type */
-	u8	die_rev;	/* Processor revision */
-	u32	omap_id;	/* OMAP revision */
-	u32	type;		/* Cpu id bits [31:08], cpu class bits [07:00] */
-};
-
-/* Register values to detect the OMAP version */
-static struct omap_id omap_ids[] __initdata = {
-	{ .jtag_id = 0x355f, .die_rev = 0x0, .omap_id = 0x03320000, .type = 0x07300100},
-	{ .jtag_id = 0xb55f, .die_rev = 0x0, .omap_id = 0x03320000, .type = 0x07300300},
-	{ .jtag_id = 0xb470, .die_rev = 0x0, .omap_id = 0x03310100, .type = 0x15100000},
-	{ .jtag_id = 0xb576, .die_rev = 0x0, .omap_id = 0x03320000, .type = 0x16100000},
-	{ .jtag_id = 0xb576, .die_rev = 0x2, .omap_id = 0x03320100, .type = 0x16110000},
-	{ .jtag_id = 0xb576, .die_rev = 0x3, .omap_id = 0x03320100, .type = 0x16100c00},
-	{ .jtag_id = 0xb576, .die_rev = 0x0, .omap_id = 0x03320200, .type = 0x16100d00},
-	{ .jtag_id = 0xb613, .die_rev = 0x0, .omap_id = 0x03320300, .type = 0x1610ef00},
-	{ .jtag_id = 0xb613, .die_rev = 0x0, .omap_id = 0x03320300, .type = 0x1610ef00},
-	{ .jtag_id = 0xb576, .die_rev = 0x1, .omap_id = 0x03320100, .type = 0x16110000},
-	{ .jtag_id = 0xb58c, .die_rev = 0x2, .omap_id = 0x03320200, .type = 0x16110b00},
-	{ .jtag_id = 0xb58c, .die_rev = 0x3, .omap_id = 0x03320200, .type = 0x16110c00},
-	{ .jtag_id = 0xb65f, .die_rev = 0x0, .omap_id = 0x03320400, .type = 0x16212300},
-	{ .jtag_id = 0xb65f, .die_rev = 0x1, .omap_id = 0x03320400, .type = 0x16212300},
-	{ .jtag_id = 0xb65f, .die_rev = 0x1, .omap_id = 0x03320500, .type = 0x16212300},
-	{ .jtag_id = 0xb5f7, .die_rev = 0x0, .omap_id = 0x03330000, .type = 0x17100000},
-	{ .jtag_id = 0xb5f7, .die_rev = 0x1, .omap_id = 0x03330100, .type = 0x17100000},
-	{ .jtag_id = 0xb5f7, .die_rev = 0x2, .omap_id = 0x03330100, .type = 0x17100000},
-};
-
-/*
- * Get OMAP type from PROD_ID.
- * 1710 has the PROD_ID in bits 15:00, not in 16:01 as documented in TRM.
- * 1510 PROD_ID is empty, and 1610 PROD_ID does not make sense.
- * Undocumented register in TEST BLOCK is used as fallback; This seems to
- * work on 1510, 1610 & 1710. The official way hopefully will work in future
- * processors.
- */
-static u16 __init omap_get_jtag_id(void)
-{
-	u32 prod_id, omap_id;
-
-	prod_id = omap_readl(OMAP_PRODUCTION_ID_1);
-	omap_id = omap_readl(OMAP32_ID_1);
-
-	/* Check for unusable OMAP_PRODUCTION_ID_1 on 1611B/5912 and 730 */
-	if (((prod_id >> 20) == 0) || (prod_id == omap_id))
-		prod_id = 0;
-	else
-		prod_id &= 0xffff;
-
-	if (prod_id)
-		return prod_id;
-
-	/* Use OMAP32_ID_1 as fallback */
-	prod_id = ((omap_id >> 12) & 0xffff);
-
-	return prod_id;
-}
-
-/*
- * Get OMAP revision from DIE_REV.
- * Early 1710 processors may have broken OMAP_DIE_ID, it contains PROD_ID.
- * Undocumented register in the TEST BLOCK is used as fallback.
- * REVISIT: This does not seem to work on 1510
- */
-static u8 __init omap_get_die_rev(void)
-{
-	u32 die_rev;
-
-	die_rev = omap_readl(OMAP_DIE_ID_1);
-
-	/* Check for broken OMAP_DIE_ID on early 1710 */
-	if (((die_rev >> 12) & 0xffff) == omap_get_jtag_id())
-		die_rev = 0;
-
-	die_rev = (die_rev >> 17) & 0xf;
-	if (die_rev)
-		return die_rev;
-
-	die_rev = (omap_readl(OMAP32_ID_1) >> 28) & 0xf;
-
-	return die_rev;
-}
-
-static void __init omap_check_revision(void)
-{
-	int i;
-	u16 jtag_id;
-	u8 die_rev;
-	u32 omap_id;
-	u8 cpu_type;
-
-	jtag_id = omap_get_jtag_id();
-	die_rev = omap_get_die_rev();
-	omap_id = omap_readl(OMAP32_ID_0);
-
-#ifdef DEBUG
-	printk("OMAP_DIE_ID_0: 0x%08x\n", omap_readl(OMAP_DIE_ID_0));
-	printk("OMAP_DIE_ID_1: 0x%08x DIE_REV: %i\n",
-		omap_readl(OMAP_DIE_ID_1),
-	       (omap_readl(OMAP_DIE_ID_1) >> 17) & 0xf);
-	printk("OMAP_PRODUCTION_ID_0: 0x%08x\n", omap_readl(OMAP_PRODUCTION_ID_0));
-	printk("OMAP_PRODUCTION_ID_1: 0x%08x JTAG_ID: 0x%04x\n",
-		omap_readl(OMAP_PRODUCTION_ID_1),
-		omap_readl(OMAP_PRODUCTION_ID_1) & 0xffff);
-	printk("OMAP32_ID_0: 0x%08x\n", omap_readl(OMAP32_ID_0));
-	printk("OMAP32_ID_1: 0x%08x\n", omap_readl(OMAP32_ID_1));
-	printk("JTAG_ID: 0x%04x DIE_REV: %i\n", jtag_id, die_rev);
-#endif
-
-	system_serial_high = omap_readl(OMAP_DIE_ID_0);
-	system_serial_low = omap_readl(OMAP_DIE_ID_1);
-
-	/* First check only the major version in a safe way */
-	for (i = 0; i < ARRAY_SIZE(omap_ids); i++) {
-		if (jtag_id == (omap_ids[i].jtag_id)) {
-			system_rev = omap_ids[i].type;
-			break;
-		}
-	}
-
-	/* Check if we can find the die revision */
-	for (i = 0; i < ARRAY_SIZE(omap_ids); i++) {
-		if (jtag_id == omap_ids[i].jtag_id && die_rev == omap_ids[i].die_rev) {
-			system_rev = omap_ids[i].type;
-			break;
-		}
-	}
-
-	/* Finally check also the omap_id */
-	for (i = 0; i < ARRAY_SIZE(omap_ids); i++) {
-		if (jtag_id == omap_ids[i].jtag_id
-		    && die_rev == omap_ids[i].die_rev
-		    && omap_id == omap_ids[i].omap_id) {
-			system_rev = omap_ids[i].type;
-			break;
-		}
-	}
-
-	/* Add the cpu class info (7xx, 15xx, 16xx, 24xx) */
-	cpu_type = system_rev >> 24;
-
-	switch (cpu_type) {
-	case 0x07:
-		system_rev |= 0x07;
-		break;
-	case 0x15:
-		system_rev |= 0x15;
-		break;
-	case 0x16:
-	case 0x17:
-		system_rev |= 0x16;
-		break;
-	case 0x24:
-		system_rev |= 0x24;
-		break;
-	default:
-		printk("Unknown OMAP cpu type: 0x%02x\n", cpu_type);
-	}
-
-	printk("OMAP%04x", system_rev >> 16);
-	if ((system_rev >> 8) & 0xff)
-		printk("%x", (system_rev >> 8) & 0xff);
-	printk(" revision %i handled as %02xxx id: %08x%08x\n",
-	       die_rev, system_rev & 0xff, system_serial_low,
-	       system_serial_high);
-}
-
-/*
- * ----------------------------------------------------------------------------
- * OMAP I/O mapping
- *
- * The machine specific code may provide the extra mapping besides the
- * default mapping provided here.
- * ----------------------------------------------------------------------------
- */
-
-static struct map_desc omap_io_desc[] __initdata = {
- { IO_VIRT,      	IO_PHYS,             IO_SIZE,        	   MT_DEVICE },
-};
-
-#ifdef CONFIG_ARCH_OMAP730
-static struct map_desc omap730_io_desc[] __initdata = {
- { OMAP730_DSP_BASE,    OMAP730_DSP_START,    OMAP730_DSP_SIZE,    MT_DEVICE },
- { OMAP730_DSPREG_BASE, OMAP730_DSPREG_START, OMAP730_DSPREG_SIZE, MT_DEVICE },
- { OMAP730_SRAM_BASE,   OMAP730_SRAM_START,   OMAP730_SRAM_SIZE,   MT_DEVICE }
-};
-#endif
-
-#ifdef CONFIG_ARCH_OMAP1510
-static struct map_desc omap1510_io_desc[] __initdata = {
- { OMAP1510_DSP_BASE,    OMAP1510_DSP_START,    OMAP1510_DSP_SIZE,    MT_DEVICE },
- { OMAP1510_DSPREG_BASE, OMAP1510_DSPREG_START, OMAP1510_DSPREG_SIZE, MT_DEVICE },
- { OMAP1510_SRAM_BASE,   OMAP1510_SRAM_START,   OMAP1510_SRAM_SIZE,   MT_DEVICE }
-};
-#endif
-
-#if defined(CONFIG_ARCH_OMAP16XX)
-static struct map_desc omap1610_io_desc[] __initdata = {
- { OMAP16XX_DSP_BASE,    OMAP16XX_DSP_START,    OMAP16XX_DSP_SIZE,    MT_DEVICE },
- { OMAP16XX_DSPREG_BASE, OMAP16XX_DSPREG_START, OMAP16XX_DSPREG_SIZE, MT_DEVICE },
- { OMAP16XX_SRAM_BASE,   OMAP16XX_SRAM_START,   OMAP1610_SRAM_SIZE,   MT_DEVICE }
-};
-
-static struct map_desc omap5912_io_desc[] __initdata = {
- { OMAP16XX_DSP_BASE,    OMAP16XX_DSP_START,    OMAP16XX_DSP_SIZE,    MT_DEVICE },
- { OMAP16XX_DSPREG_BASE, OMAP16XX_DSPREG_START, OMAP16XX_DSPREG_SIZE, MT_DEVICE },
-/*
- * The OMAP5912 has 250kByte internal SRAM. Because the mapping is baseed on page
- * size (4kByte), it seems that the last 2kByte (=0x800) of the 250kByte are not mapped.
- * Add additional 2kByte (0x800) so that the last page is mapped and the last 2kByte
- * can be used.
- */
- { OMAP16XX_SRAM_BASE,   OMAP16XX_SRAM_START,   OMAP5912_SRAM_SIZE + 0x800,   MT_DEVICE }
-};
-#endif
-
-static int initialized = 0;
-
-static void __init _omap_map_io(void)
-{
-	initialized = 1;
-
-	/* We have to initialize the IO space mapping before we can run
-	 * cpu_is_omapxxx() macros. */
-	iotable_init(omap_io_desc, ARRAY_SIZE(omap_io_desc));
-	omap_check_revision();
-
-#ifdef CONFIG_ARCH_OMAP730
-	if (cpu_is_omap730()) {
-		iotable_init(omap730_io_desc, ARRAY_SIZE(omap730_io_desc));
-	}
-#endif
-#ifdef CONFIG_ARCH_OMAP1510
-	if (cpu_is_omap1510()) {
-		iotable_init(omap1510_io_desc, ARRAY_SIZE(omap1510_io_desc));
-	}
-#endif
-#if defined(CONFIG_ARCH_OMAP16XX)
-	if (cpu_is_omap1610() || cpu_is_omap1710()) {
-		iotable_init(omap1610_io_desc, ARRAY_SIZE(omap1610_io_desc));
-	}
-	if (cpu_is_omap5912()) {
-		iotable_init(omap5912_io_desc, ARRAY_SIZE(omap5912_io_desc));
-	}
-#endif
-
-	/* REVISIT: Refer to OMAP5910 Errata, Advisory SYS_1: "Timeout Abort
-	 * on a Posted Write in the TIPB Bridge".
-	 */
-	omap_writew(0x0, MPU_PUBLIC_TIPB_CNTL);
-	omap_writew(0x0, MPU_PRIVATE_TIPB_CNTL);
-
-	/* Must init clocks early to assure that timer interrupt works
-	 */
-	clk_init();
-}
-
-/*
- * This should only get called from board specific init
- */
-void omap_map_io(void)
-{
-	if (!initialized)
-		_omap_map_io();
-}
-
-static inline unsigned int omap_serial_in(struct plat_serial8250_port *up,
-					  int offset)
-{
-	offset <<= up->regshift;
-	return (unsigned int)__raw_readb(up->membase + offset);
-}
-
-static inline void omap_serial_outp(struct plat_serial8250_port *p, int offset,
-				    int value)
-{
-	offset <<= p->regshift;
-	__raw_writeb(value, p->membase + offset);
-}
-
-/*
- * Internal UARTs need to be initialized for the 8250 autoconfig to work
- * properly. Note that the TX watermark initialization may not be needed
- * once the 8250.c watermark handling code is merged.
- */
-static void __init omap_serial_reset(struct plat_serial8250_port *p)
-{
-	omap_serial_outp(p, UART_OMAP_MDR1, 0x07);	/* disable UART */
-	omap_serial_outp(p, UART_OMAP_SCR, 0x08);	/* TX watermark */
-	omap_serial_outp(p, UART_OMAP_MDR1, 0x00);	/* enable UART */
-
-	if (!cpu_is_omap1510()) {
-		omap_serial_outp(p, UART_OMAP_SYSC, 0x01);
-		while (!(omap_serial_in(p, UART_OMAP_SYSC) & 0x01));
-	}
-}
-
-static struct plat_serial8250_port serial_platform_data[] = {
-	{
-		.membase	= (char*)IO_ADDRESS(OMAP_UART1_BASE),
-		.mapbase	= (unsigned long)OMAP_UART1_BASE,
-		.irq		= INT_UART1,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.iotype		= UPIO_MEM,
-		.regshift	= 2,
-		.uartclk	= OMAP16XX_BASE_BAUD * 16,
-	},
-	{
-		.membase	= (char*)IO_ADDRESS(OMAP_UART2_BASE),
-		.mapbase	= (unsigned long)OMAP_UART2_BASE,
-		.irq		= INT_UART2,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.iotype		= UPIO_MEM,
-		.regshift	= 2,
-		.uartclk	= OMAP16XX_BASE_BAUD * 16,
-	},
-	{
-		.membase	= (char*)IO_ADDRESS(OMAP_UART3_BASE),
-		.mapbase	= (unsigned long)OMAP_UART3_BASE,
-		.irq		= INT_UART3,
-		.flags		= UPF_BOOT_AUTOCONF,
-		.iotype		= UPIO_MEM,
-		.regshift	= 2,
-		.uartclk	= OMAP16XX_BASE_BAUD * 16,
-	},
-	{ },
-};
-
-static struct platform_device serial_device = {
-	.name			= "serial8250",
-	.id			= 0,
-	.dev			= {
-		.platform_data	= serial_platform_data,
-	},
-};
-
-/*
- * Note that on Innovator-1510 UART2 pins conflict with USB2.
- * By default UART2 does not work on Innovator-1510 if you have
- * USB OHCI enabled. To use UART2, you must disable USB2 first.
- */
-void __init omap_serial_init(int ports[OMAP_MAX_NR_PORTS])
-{
-	int i;
-
-	if (cpu_is_omap730()) {
-		serial_platform_data[0].regshift = 0;
-		serial_platform_data[1].regshift = 0;
-		serial_platform_data[0].irq = INT_730_UART_MODEM_1;
-		serial_platform_data[1].irq = INT_730_UART_MODEM_IRDA_2;
-	}
-
-	if (cpu_is_omap1510()) {
-		serial_platform_data[0].uartclk = OMAP1510_BASE_BAUD * 16;
-		serial_platform_data[1].uartclk = OMAP1510_BASE_BAUD * 16;
-		serial_platform_data[2].uartclk = OMAP1510_BASE_BAUD * 16;
-	}
-
-	for (i = 0; i < OMAP_MAX_NR_PORTS; i++) {
-		unsigned char reg;
-
-		if (ports[i] == 0) {
-			serial_platform_data[i].membase = 0;
-			serial_platform_data[i].mapbase = 0;
-			continue;
-		}
-
-		switch (i) {
-		case 0:
-			if (cpu_is_omap1510()) {
-				omap_cfg_reg(UART1_TX);
-				omap_cfg_reg(UART1_RTS);
-				if (machine_is_omap_innovator()) {
-					reg = fpga_read(OMAP1510_FPGA_POWER);
-					reg |= OMAP1510_FPGA_PCR_COM1_EN;
-					fpga_write(reg, OMAP1510_FPGA_POWER);
-					udelay(10);
-				}
-			}
-			break;
-		case 1:
-			if (cpu_is_omap1510()) {
-				omap_cfg_reg(UART2_TX);
-				omap_cfg_reg(UART2_RTS);
-				if (machine_is_omap_innovator()) {
-					reg = fpga_read(OMAP1510_FPGA_POWER);
-					reg |= OMAP1510_FPGA_PCR_COM2_EN;
-					fpga_write(reg, OMAP1510_FPGA_POWER);
-					udelay(10);
-				}
-			}
-			break;
-		case 2:
-			if (cpu_is_omap1510()) {
-				omap_cfg_reg(UART3_TX);
-				omap_cfg_reg(UART3_RX);
-			}
-			if (cpu_is_omap1710()) {
-				clk_enable(clk_get(0, "uart3_ck"));
-			}
-			break;
-		}
-		omap_serial_reset(&serial_platform_data[i]);
-	}
-}
-
-static int __init omap_init(void)
-{
-	return platform_device_register(&serial_device);
-}
-arch_initcall(omap_init);
-
-#define NO_LENGTH_CHECK 0xffffffff
-
-extern int omap_bootloader_tag_len;
-extern u8 omap_bootloader_tag[];
-
-struct omap_board_config_kernel *omap_board_config;
-int omap_board_config_size = 0;
-
-static const void *get_config(u16 tag, size_t len, int skip, size_t *len_out)
-{
-	struct omap_board_config_kernel *kinfo = NULL;
-	int i;
-
-#ifdef CONFIG_OMAP_BOOT_TAG
-	struct omap_board_config_entry *info = NULL;
-
-	if (omap_bootloader_tag_len > 4)
-		info = (struct omap_board_config_entry *) omap_bootloader_tag;
-	while (info != NULL) {
-		u8 *next;
-
-		if (info->tag == tag) {
-			if (skip == 0)
-				break;
-			skip--;
-		}
-
-		if ((info->len & 0x03) != 0) {
-			/* We bail out to avoid an alignment fault */
-			printk(KERN_ERR "OMAP peripheral config: Length (%d) not word-aligned (tag %04x)\n",
-			       info->len, info->tag);
-			return NULL;
-		}
-		next = (u8 *) info + sizeof(*info) + info->len;
-		if (next >= omap_bootloader_tag + omap_bootloader_tag_len)
-			info = NULL;
-		else
-			info = (struct omap_board_config_entry *) next;
-	}
-	if (info != NULL) {
-		/* Check the length as a lame attempt to check for
-		 * binary inconsistancy. */
-		if (len != NO_LENGTH_CHECK) {
-			/* Word-align len */
-			if (len & 0x03)
-				len = (len + 3) & ~0x03;
-			if (info->len != len) {
-				printk(KERN_ERR "OMAP peripheral config: Length mismatch with tag %x (want %d, got %d)\n",
-				       tag, len, info->len);
-				return NULL;
-			}
-		}
-		if (len_out != NULL)
-			*len_out = info->len;
-		return info->data;
-	}
-#endif
-	/* Try to find the config from the board-specific structures
-	 * in the kernel. */
-	for (i = 0; i < omap_board_config_size; i++) {
-		if (omap_board_config[i].tag == tag) {
-			kinfo = &omap_board_config[i];
-			break;
-		}
-	}
-	if (kinfo == NULL)
-		return NULL;
-	return kinfo->data;
-}
-
-const void *__omap_get_config(u16 tag, size_t len, int nr)
-{
-        return get_config(tag, len, nr, NULL);
-}
-EXPORT_SYMBOL(__omap_get_config);
-
-const void *omap_get_var_config(u16 tag, size_t *len)
-{
-        return get_config(tag, NO_LENGTH_CHECK, 0, len);
-}
-EXPORT_SYMBOL(omap_get_var_config);
-
-static int __init omap_add_serial_console(void)
-{
-	const struct omap_uart_config *info;
-
-	info = omap_get_config(OMAP_TAG_UART, struct omap_uart_config);
-	if (info != NULL && info->console_uart) {
-		static char speed[11], *opt = NULL;
-
-		if (info->console_speed) {
-			snprintf(speed, sizeof(speed), "%u", info->console_speed);
-			opt = speed;
-		}
-		return add_preferred_console("ttyS", info->console_uart - 1, opt);
-	}
-	return 0;
-}
-console_initcall(omap_add_serial_console);
diff --git a/arch/arm/mach-omap/common.h b/arch/arm/mach-omap/common.h
deleted file mode 100644
--- a/arch/arm/mach-omap/common.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * linux/arch/arm/mach-omap/common.h
- *
- * Header for code common to all OMAP machines.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
- * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * You should have received a copy of the  GNU General Public License along
- * with this program; if not, write  to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef __ARCH_ARM_MACH_OMAP_COMMON_H
-#define __ARCH_ARM_MACH_OMAP_COMMON_H
-
-struct sys_timer;
-
-extern void omap_map_io(void);
-extern struct sys_timer omap_timer;
-extern void omap_serial_init(int ports[]);
-
-#endif /* __ARCH_ARM_MACH_OMAP_COMMON_H */
diff --git a/arch/arm/mach-omap/dma.c b/arch/arm/mach-omap/dma.c
deleted file mode 100644
--- a/arch/arm/mach-omap/dma.c
+++ /dev/null
@@ -1,1086 +0,0 @@
-/*
- * linux/arch/arm/omap/dma.c
- *
- * Copyright (C) 2003 Nokia Corporation
- * Author: Juha Yrjölä <juha.yrjola@nokia.com>
- * DMA channel linking for 1610 by Samuel Ortiz <samuel.ortiz@nokia.com>
- * Graphics DMA and LCD DMA graphics tranformations
- * by Imre Deak <imre.deak@nokia.com>
- * Some functions based on earlier dma-omap.c Copyright (C) 2001 RidgeRun, Inc.
- *
- * Support functions for the OMAP internal DMA channels.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/spinlock.h>
-#include <linux/errno.h>
-#include <linux/interrupt.h>
-
-#include <asm/system.h>
-#include <asm/irq.h>
-#include <asm/hardware.h>
-#include <asm/dma.h>
-#include <asm/io.h>
-
-#include <asm/arch/tc.h>
-
-#define OMAP_DMA_ACTIVE		0x01
-
-#define OMAP_DMA_CCR_EN		(1 << 7)
-
-#define OMAP_FUNC_MUX_ARM_BASE	(0xfffe1000 + 0xec)
-
-static int enable_1510_mode = 0;
-
-struct omap_dma_lch {
-	int next_lch;
-	int dev_id;
-	u16 saved_csr;
-	u16 enabled_irqs;
-	const char *dev_name;
-	void (* callback)(int lch, u16 ch_status, void *data);
-	void *data;
-	long flags;
-};
-
-static int dma_chan_count;
-
-static spinlock_t dma_chan_lock;
-static struct omap_dma_lch dma_chan[OMAP_LOGICAL_DMA_CH_COUNT];
-
-const static u8 dma_irq[OMAP_LOGICAL_DMA_CH_COUNT] = {
-	INT_DMA_CH0_6, INT_DMA_CH1_7, INT_DMA_CH2_8, INT_DMA_CH3,
-	INT_DMA_CH4, INT_DMA_CH5, INT_1610_DMA_CH6, INT_1610_DMA_CH7,
-	INT_1610_DMA_CH8, INT_1610_DMA_CH9, INT_1610_DMA_CH10,
-	INT_1610_DMA_CH11, INT_1610_DMA_CH12, INT_1610_DMA_CH13,
-	INT_1610_DMA_CH14, INT_1610_DMA_CH15, INT_DMA_LCD
-};
-
-static inline int get_gdma_dev(int req)
-{
-	u32 reg = OMAP_FUNC_MUX_ARM_BASE + ((req - 1) / 5) * 4;
-	int shift = ((req - 1) % 5) * 6;
-
-	return ((omap_readl(reg) >> shift) & 0x3f) + 1;
-}
-
-static inline void set_gdma_dev(int req, int dev)
-{
-	u32 reg = OMAP_FUNC_MUX_ARM_BASE + ((req - 1) / 5) * 4;
-	int shift = ((req - 1) % 5) * 6;
-	u32 l;
-
-	l = omap_readl(reg);
-	l &= ~(0x3f << shift);
-	l |= (dev - 1) << shift;
-	omap_writel(l, reg);
-}
-
-static void clear_lch_regs(int lch)
-{
-	int i;
-	u32 lch_base = OMAP_DMA_BASE + lch * 0x40;
-
-	for (i = 0; i < 0x2c; i += 2)
-		omap_writew(0, lch_base + i);
-}
-
-void omap_set_dma_priority(int dst_port, int priority)
-{
-	unsigned long reg;
-	u32 l;
-
-	switch (dst_port) {
-	case OMAP_DMA_PORT_OCP_T1:	/* FFFECC00 */
-		reg = OMAP_TC_OCPT1_PRIOR;
-		break;
-	case OMAP_DMA_PORT_OCP_T2:	/* FFFECCD0 */
-		reg = OMAP_TC_OCPT2_PRIOR;
-		break;
-	case OMAP_DMA_PORT_EMIFF:	/* FFFECC08 */
-		reg = OMAP_TC_EMIFF_PRIOR;
-		break;
-	case OMAP_DMA_PORT_EMIFS:	/* FFFECC04 */
-		reg = OMAP_TC_EMIFS_PRIOR;
-		break;
-	default:
-		BUG();
-		return;
-	}
-	l = omap_readl(reg);
-	l &= ~(0xf << 8);
-	l |= (priority & 0xf) << 8;
-	omap_writel(l, reg);
-}
-
-void omap_set_dma_transfer_params(int lch, int data_type, int elem_count,
-				  int frame_count, int sync_mode)
-{
-	u16 w;
-
-	w = omap_readw(OMAP_DMA_CSDP(lch));
-	w &= ~0x03;
-	w |= data_type;
-	omap_writew(w, OMAP_DMA_CSDP(lch));
-
-	w = omap_readw(OMAP_DMA_CCR(lch));
-	w &= ~(1 << 5);
-	if (sync_mode == OMAP_DMA_SYNC_FRAME)
-		w |= 1 << 5;
-	omap_writew(w, OMAP_DMA_CCR(lch));
-
-	w = omap_readw(OMAP_DMA_CCR2(lch));
-	w &= ~(1 << 2);
-	if (sync_mode == OMAP_DMA_SYNC_BLOCK)
-		w |= 1 << 2;
-	omap_writew(w, OMAP_DMA_CCR2(lch));
-
-	omap_writew(elem_count, OMAP_DMA_CEN(lch));
-	omap_writew(frame_count, OMAP_DMA_CFN(lch));
-
-}
-void omap_set_dma_color_mode(int lch, enum omap_dma_color_mode mode, u32 color)
-{
-	u16 w;
-
-	BUG_ON(omap_dma_in_1510_mode());
-
-	w = omap_readw(OMAP_DMA_CCR2(lch)) & ~0x03;
-	switch (mode) {
-	case OMAP_DMA_CONSTANT_FILL:
-		w |= 0x01;
-		break;
-	case OMAP_DMA_TRANSPARENT_COPY:
-		w |= 0x02;
-		break;
-	case OMAP_DMA_COLOR_DIS:
-		break;
-	default:
-		BUG();
-	}
-	omap_writew(w, OMAP_DMA_CCR2(lch));
-
-	w = omap_readw(OMAP_DMA_LCH_CTRL(lch)) & ~0x0f;
-	/* Default is channel type 2D */
-	if (mode) {
-		omap_writew((u16)color, OMAP_DMA_COLOR_L(lch));
-		omap_writew((u16)(color >> 16), OMAP_DMA_COLOR_U(lch));
-		w |= 1;		/* Channel type G */
-	}
-	omap_writew(w, OMAP_DMA_LCH_CTRL(lch));
-}
-
-
-void omap_set_dma_src_params(int lch, int src_port, int src_amode,
-			     unsigned long src_start)
-{
-	u16 w;
-
-	w = omap_readw(OMAP_DMA_CSDP(lch));
-	w &= ~(0x1f << 2);
-	w |= src_port << 2;
-	omap_writew(w, OMAP_DMA_CSDP(lch));
-
-	w = omap_readw(OMAP_DMA_CCR(lch));
-	w &= ~(0x03 << 12);
-	w |= src_amode << 12;
-	omap_writew(w, OMAP_DMA_CCR(lch));
-
-	omap_writew(src_start >> 16, OMAP_DMA_CSSA_U(lch));
-	omap_writew(src_start, OMAP_DMA_CSSA_L(lch));
-}
-
-void omap_set_dma_src_index(int lch, int eidx, int fidx)
-{
-	omap_writew(eidx, OMAP_DMA_CSEI(lch));
-	omap_writew(fidx, OMAP_DMA_CSFI(lch));
-}
-
-void omap_set_dma_src_data_pack(int lch, int enable)
-{
-	u16 w;
-
-	w = omap_readw(OMAP_DMA_CSDP(lch)) & ~(1 << 6);
-	w |= enable ? (1 << 6) : 0;
-	omap_writew(w, OMAP_DMA_CSDP(lch));
-}
-
-void omap_set_dma_src_burst_mode(int lch, enum omap_dma_burst_mode burst_mode)
-{
-	u16 w;
-
-	w = omap_readw(OMAP_DMA_CSDP(lch)) & ~(0x03 << 7);
-	switch (burst_mode) {
-	case OMAP_DMA_DATA_BURST_DIS:
-		break;
-	case OMAP_DMA_DATA_BURST_4:
-		w |= (0x01 << 7);
-		break;
-	case OMAP_DMA_DATA_BURST_8:
-		/* not supported by current hardware
-		 * w |= (0x03 << 7);
-		 * fall through
-		 */
-	default:
-		BUG();
-	}
-	omap_writew(w, OMAP_DMA_CSDP(lch));
-}
-
-void omap_set_dma_dest_params(int lch, int dest_port, int dest_amode,
-			      unsigned long dest_start)
-{
-	u16 w;
-
-	w = omap_readw(OMAP_DMA_CSDP(lch));
-	w &= ~(0x1f << 9);
-	w |= dest_port << 9;
-	omap_writew(w, OMAP_DMA_CSDP(lch));
-
-	w = omap_readw(OMAP_DMA_CCR(lch));
-	w &= ~(0x03 << 14);
-	w |= dest_amode << 14;
-	omap_writew(w, OMAP_DMA_CCR(lch));
-
-	omap_writew(dest_start >> 16, OMAP_DMA_CDSA_U(lch));
-	omap_writew(dest_start, OMAP_DMA_CDSA_L(lch));
-}
-
-void omap_set_dma_dest_index(int lch, int eidx, int fidx)
-{
-	omap_writew(eidx, OMAP_DMA_CDEI(lch));
-	omap_writew(fidx, OMAP_DMA_CDFI(lch));
-}
-
-void omap_set_dma_dest_data_pack(int lch, int enable)
-{
-	u16 w;
-
-	w = omap_readw(OMAP_DMA_CSDP(lch)) & ~(1 << 13);
-	w |= enable ? (1 << 13) : 0;
-	omap_writew(w, OMAP_DMA_CSDP(lch));
-}
-
-void omap_set_dma_dest_burst_mode(int lch, enum omap_dma_burst_mode burst_mode)
-{
-	u16 w;
-
-	w = omap_readw(OMAP_DMA_CSDP(lch)) & ~(0x03 << 14);
-	switch (burst_mode) {
-	case OMAP_DMA_DATA_BURST_DIS:
-		break;
-	case OMAP_DMA_DATA_BURST_4:
-		w |= (0x01 << 14);
-		break;
-	case OMAP_DMA_DATA_BURST_8:
-		w |= (0x03 << 14);
-		break;
-	default:
-		printk(KERN_ERR "Invalid DMA burst mode\n");
-		BUG();
-		return;
-	}
-	omap_writew(w, OMAP_DMA_CSDP(lch));
-}
-
-static inline void init_intr(int lch)
-{
-	u16 w;
-
-	/* Read CSR to make sure it's cleared. */
-	w = omap_readw(OMAP_DMA_CSR(lch));
-	/* Enable some nice interrupts. */
-	omap_writew(dma_chan[lch].enabled_irqs, OMAP_DMA_CICR(lch));
-	dma_chan[lch].flags |= OMAP_DMA_ACTIVE;
-}
-
-static inline void enable_lnk(int lch)
-{
-	u16 w;
-
-	/* Clear the STOP_LNK bits */
-	w = omap_readw(OMAP_DMA_CLNK_CTRL(lch));
-	w &= ~(1 << 14);
-	omap_writew(w, OMAP_DMA_CLNK_CTRL(lch));
-
-	/* And set the ENABLE_LNK bits */
-	if (dma_chan[lch].next_lch != -1)
-		omap_writew(dma_chan[lch].next_lch | (1 << 15),
-			    OMAP_DMA_CLNK_CTRL(lch));
-}
-
-static inline void disable_lnk(int lch)
-{
-	u16 w;
-
-	/* Disable interrupts */
-	omap_writew(0, OMAP_DMA_CICR(lch));
-
-	/* Set the STOP_LNK bit */
-	w = omap_readw(OMAP_DMA_CLNK_CTRL(lch));
-	w |= (1 << 14);
-	w = omap_writew(w, OMAP_DMA_CLNK_CTRL(lch));
-
-	dma_chan[lch].flags &= ~OMAP_DMA_ACTIVE;
-}
-
-void omap_start_dma(int lch)
-{
-	u16 w;
-
-	if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) {
-		int next_lch, cur_lch;
-		char dma_chan_link_map[OMAP_LOGICAL_DMA_CH_COUNT];
-
-		dma_chan_link_map[lch] = 1;
-		/* Set the link register of the first channel */
-		enable_lnk(lch);
-
-		memset(dma_chan_link_map, 0, sizeof(dma_chan_link_map));
-		cur_lch = dma_chan[lch].next_lch;
-		do {
-			next_lch = dma_chan[cur_lch].next_lch;
-
-                        /* The loop case: we've been here already */
-			if (dma_chan_link_map[cur_lch])
-				break;
-			/* Mark the current channel */
-			dma_chan_link_map[cur_lch] = 1;
-
-			enable_lnk(cur_lch);
-			init_intr(cur_lch);
-
-			cur_lch = next_lch;
-		} while (next_lch != -1);
-	}
-
-	init_intr(lch);
-
-	w = omap_readw(OMAP_DMA_CCR(lch));
-	w |= OMAP_DMA_CCR_EN;
-	omap_writew(w, OMAP_DMA_CCR(lch));
-	dma_chan[lch].flags |= OMAP_DMA_ACTIVE;
-}
-
-void omap_stop_dma(int lch)
-{
-	u16 w;
-
-	if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) {
-		int next_lch, cur_lch = lch;
-		char dma_chan_link_map[OMAP_LOGICAL_DMA_CH_COUNT];
-
-		memset(dma_chan_link_map, 0, sizeof(dma_chan_link_map));
-		do {
-			/* The loop case: we've been here already */
-			if (dma_chan_link_map[cur_lch])
-				break;
-			/* Mark the current channel */
-			dma_chan_link_map[cur_lch] = 1;
-
-			disable_lnk(cur_lch);
-
-			next_lch = dma_chan[cur_lch].next_lch;
-			cur_lch = next_lch;
-		} while (next_lch != -1);
-
-		return;
-	}
-	/* Disable all interrupts on the channel */
-	omap_writew(0, OMAP_DMA_CICR(lch));
-
-	w = omap_readw(OMAP_DMA_CCR(lch));
-	w &= ~OMAP_DMA_CCR_EN;
-	omap_writew(w, OMAP_DMA_CCR(lch));
-	dma_chan[lch].flags &= ~OMAP_DMA_ACTIVE;
-}
-
-void omap_enable_dma_irq(int lch, u16 bits)
-{
-	dma_chan[lch].enabled_irqs |= bits;
-}
-
-void omap_disable_dma_irq(int lch, u16 bits)
-{
-	dma_chan[lch].enabled_irqs &= ~bits;
-}
-
-static int dma_handle_ch(int ch)
-{
-	u16 csr;
-
-	if (enable_1510_mode && ch >= 6) {
-		csr = dma_chan[ch].saved_csr;
-		dma_chan[ch].saved_csr = 0;
-	} else
-		csr = omap_readw(OMAP_DMA_CSR(ch));
-	if (enable_1510_mode && ch <= 2 && (csr >> 7) != 0) {
-		dma_chan[ch + 6].saved_csr = csr >> 7;
-		csr &= 0x7f;
-	}
-	if (!csr)
-		return 0;
-	if (unlikely(dma_chan[ch].dev_id == -1)) {
-		printk(KERN_WARNING "Spurious interrupt from DMA channel %d (CSR %04x)\n",
-		       ch, csr);
-		return 0;
-	}
-	if (unlikely(csr & OMAP_DMA_TOUT_IRQ))
-		printk(KERN_WARNING "DMA timeout with device %d\n", dma_chan[ch].dev_id);
-	if (unlikely(csr & OMAP_DMA_DROP_IRQ))
-		printk(KERN_WARNING "DMA synchronization event drop occurred with device %d\n",
-		       dma_chan[ch].dev_id);
-	if (likely(csr & OMAP_DMA_BLOCK_IRQ))
-		dma_chan[ch].flags &= ~OMAP_DMA_ACTIVE;
-	if (likely(dma_chan[ch].callback != NULL))
-		dma_chan[ch].callback(ch, csr, dma_chan[ch].data);
-	return 1;
-}
-
-static irqreturn_t dma_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
-{
-	int ch = ((int) dev_id) - 1;
-	int handled = 0;
-
-	for (;;) {
-		int handled_now = 0;
-
-		handled_now += dma_handle_ch(ch);
-		if (enable_1510_mode && dma_chan[ch + 6].saved_csr)
-			handled_now += dma_handle_ch(ch + 6);
-		if (!handled_now)
-			break;
-		handled += handled_now;
-	}
-
-	return handled ? IRQ_HANDLED : IRQ_NONE;
-}
-
-int omap_request_dma(int dev_id, const char *dev_name,
-		     void (* callback)(int lch, u16 ch_status, void *data),
-		     void *data, int *dma_ch_out)
-{
-	int ch, free_ch = -1;
-	unsigned long flags;
-	struct omap_dma_lch *chan;
-
-	spin_lock_irqsave(&dma_chan_lock, flags);
-	for (ch = 0; ch < dma_chan_count; ch++) {
-		if (free_ch == -1 && dma_chan[ch].dev_id == -1) {
-			free_ch = ch;
-			if (dev_id == 0)
-				break;
-		}
-	}
-	if (free_ch == -1) {
-		spin_unlock_irqrestore(&dma_chan_lock, flags);
-		return -EBUSY;
-	}
-	chan = dma_chan + free_ch;
-	chan->dev_id = dev_id;
-	clear_lch_regs(free_ch);
-	spin_unlock_irqrestore(&dma_chan_lock, flags);
-
-	chan->dev_id = dev_id;
-	chan->dev_name = dev_name;
-	chan->callback = callback;
-	chan->data = data;
-	chan->enabled_irqs = OMAP_DMA_TOUT_IRQ | OMAP_DMA_DROP_IRQ | OMAP_DMA_BLOCK_IRQ;
-
-	if (cpu_is_omap16xx()) {
-		/* If the sync device is set, configure it dynamically. */
-		if (dev_id != 0) {
-			set_gdma_dev(free_ch + 1, dev_id);
-			dev_id = free_ch + 1;
-		}
-		/* Disable the 1510 compatibility mode and set the sync device
-		 * id. */
-		omap_writew(dev_id | (1 << 10), OMAP_DMA_CCR(free_ch));
-	} else {
-		omap_writew(dev_id, OMAP_DMA_CCR(free_ch));
-	}
-	*dma_ch_out = free_ch;
-
-	return 0;
-}
-
-void omap_free_dma(int ch)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&dma_chan_lock, flags);
-	if (dma_chan[ch].dev_id == -1) {
-		printk("omap_dma: trying to free nonallocated DMA channel %d\n", ch);
-		spin_unlock_irqrestore(&dma_chan_lock, flags);
-		return;
-	}
-	dma_chan[ch].dev_id = -1;
-	spin_unlock_irqrestore(&dma_chan_lock, flags);
-
-	/* Disable all DMA interrupts for the channel. */
-	omap_writew(0, OMAP_DMA_CICR(ch));
-	/* Make sure the DMA transfer is stopped. */
-	omap_writew(0, OMAP_DMA_CCR(ch));
-}
-
-int omap_dma_in_1510_mode(void)
-{
-	return enable_1510_mode;
-}
-
-/*
- * lch_queue DMA will start right after lch_head one is finished.
- * For this DMA link to start, you still need to start (see omap_start_dma)
- * the first one. That will fire up the entire queue.
- */
-void omap_dma_link_lch (int lch_head, int lch_queue)
-{
-	if (omap_dma_in_1510_mode()) {
-		printk(KERN_ERR "DMA linking is not supported in 1510 mode\n");
-		BUG();
-		return;
-	}
-
-	if ((dma_chan[lch_head].dev_id == -1) ||
-	    (dma_chan[lch_queue].dev_id == -1)) {
-		printk(KERN_ERR "omap_dma: trying to link non requested channels\n");
-		dump_stack();
-	}
-
-	dma_chan[lch_head].next_lch = lch_queue;
-}
-
-/*
- * Once the DMA queue is stopped, we can destroy it.
- */
-void omap_dma_unlink_lch (int lch_head, int lch_queue)
-{
-	if (omap_dma_in_1510_mode()) {
-		printk(KERN_ERR "DMA linking is not supported in 1510 mode\n");
-		BUG();
-		return;
-	}
-
-	if (dma_chan[lch_head].next_lch != lch_queue ||
-	    dma_chan[lch_head].next_lch == -1) {
-		printk(KERN_ERR "omap_dma: trying to unlink non linked channels\n");
-		dump_stack();
-	}
-
-
-	if ((dma_chan[lch_head].flags & OMAP_DMA_ACTIVE) ||
-	    (dma_chan[lch_head].flags & OMAP_DMA_ACTIVE)) {
-		printk(KERN_ERR "omap_dma: You need to stop the DMA channels before unlinking\n");
-		dump_stack();
-	}
-
-	dma_chan[lch_head].next_lch = -1;
-}
-
-
-static struct lcd_dma_info {
-	spinlock_t lock;
-	int reserved;
-	void (* callback)(u16 status, void *data);
-	void *cb_data;
-
-	int active;
-	unsigned long addr, size;
-	int rotate, data_type, xres, yres;
-	int vxres;
-	int mirror;
-	int xscale, yscale;
-	int ext_ctrl;
-	int src_port;
-	int single_transfer;
-} lcd_dma;
-
-void omap_set_lcd_dma_b1(unsigned long addr, u16 fb_xres, u16 fb_yres,
-			 int data_type)
-{
-	lcd_dma.addr = addr;
-	lcd_dma.data_type = data_type;
-	lcd_dma.xres = fb_xres;
-	lcd_dma.yres = fb_yres;
-}
-
-void omap_set_lcd_dma_src_port(int port)
-{
-	lcd_dma.src_port = port;
-}
-
-void omap_set_lcd_dma_ext_controller(int external)
-{
-	lcd_dma.ext_ctrl = external;
-}
-
-void omap_set_lcd_dma_single_transfer(int single)
-{
-	lcd_dma.single_transfer = single;
-}
-
-
-void omap_set_lcd_dma_b1_rotation(int rotate)
-{
-	if (omap_dma_in_1510_mode()) {
-		printk(KERN_ERR "DMA rotation is not supported in 1510 mode\n");
-		BUG();
-		return;
-	}
-	lcd_dma.rotate = rotate;
-}
-
-void omap_set_lcd_dma_b1_mirror(int mirror)
-{
-	if (omap_dma_in_1510_mode()) {
-		printk(KERN_ERR "DMA mirror is not supported in 1510 mode\n");
-		BUG();
-	}
-	lcd_dma.mirror = mirror;
-}
-
-void omap_set_lcd_dma_b1_vxres(unsigned long vxres)
-{
-	if (omap_dma_in_1510_mode()) {
-		printk(KERN_ERR "DMA virtual resulotion is not supported "
-				"in 1510 mode\n");
-		BUG();
-	}
-	lcd_dma.vxres = vxres;
-}
-
-void omap_set_lcd_dma_b1_scale(unsigned int xscale, unsigned int yscale)
-{
-	if (omap_dma_in_1510_mode()) {
-		printk(KERN_ERR "DMA scale is not supported in 1510 mode\n");
-		BUG();
-	}
-	lcd_dma.xscale = xscale;
-	lcd_dma.yscale = yscale;
-}
-
-static void set_b1_regs(void)
-{
-	unsigned long top, bottom;
-	int es;
-	u16 w;
-	unsigned long en, fn;
-	long ei, fi;
-	unsigned long vxres;
-	unsigned int xscale, yscale;
-
-	switch (lcd_dma.data_type) {
-	case OMAP_DMA_DATA_TYPE_S8:
-		es = 1;
-		break;
-	case OMAP_DMA_DATA_TYPE_S16:
-		es = 2;
-		break;
-	case OMAP_DMA_DATA_TYPE_S32:
-		es = 4;
-		break;
-	default:
-		BUG();
-		return;
-	}
-
-	vxres = lcd_dma.vxres ? lcd_dma.vxres : lcd_dma.xres;
-	xscale = lcd_dma.xscale ? lcd_dma.xscale : 1;
-	yscale = lcd_dma.yscale ? lcd_dma.yscale : 1;
-	BUG_ON(vxres < lcd_dma.xres);
-#define PIXADDR(x,y) (lcd_dma.addr + ((y) * vxres * yscale + (x) * xscale) * es)
-#define PIXSTEP(sx, sy, dx, dy) (PIXADDR(dx, dy) - PIXADDR(sx, sy) - es + 1)
-	switch (lcd_dma.rotate) {
-	case 0:
-		if (!lcd_dma.mirror) {
-			top = PIXADDR(0, 0);
-			bottom = PIXADDR(lcd_dma.xres - 1, lcd_dma.yres - 1);
-			/* 1510 DMA requires the bottom address to be 2 more
-			 * than the actual last memory access location. */
-			if (omap_dma_in_1510_mode() &&
-			    lcd_dma.data_type == OMAP_DMA_DATA_TYPE_S32)
-				bottom += 2;
-			ei = PIXSTEP(0, 0, 1, 0);
-			fi = PIXSTEP(lcd_dma.xres - 1, 0, 0, 1);
-		} else {
-			top = PIXADDR(lcd_dma.xres - 1, 0);
-			bottom = PIXADDR(0, lcd_dma.yres - 1);
-			ei = PIXSTEP(1, 0, 0, 0);
-			fi = PIXSTEP(0, 0, lcd_dma.xres - 1, 1);
-		}
-		en = lcd_dma.xres;
-		fn = lcd_dma.yres;
-		break;
-	case 90:
-		if (!lcd_dma.mirror) {
-			top = PIXADDR(0, lcd_dma.yres - 1);
-			bottom = PIXADDR(lcd_dma.xres - 1, 0);
-			ei = PIXSTEP(0, 1, 0, 0);
-			fi = PIXSTEP(0, 0, 1, lcd_dma.yres - 1);
-		} else {
-			top = PIXADDR(lcd_dma.xres - 1, lcd_dma.yres - 1);
-			bottom = PIXADDR(0, 0);
-			ei = PIXSTEP(0, 1, 0, 0);
-			fi = PIXSTEP(1, 0, 0, lcd_dma.yres - 1);
-		}
-		en = lcd_dma.yres;
-		fn = lcd_dma.xres;
-		break;
-	case 180:
-		if (!lcd_dma.mirror) {
-			top = PIXADDR(lcd_dma.xres - 1, lcd_dma.yres - 1);
-			bottom = PIXADDR(0, 0);
-			ei = PIXSTEP(1, 0, 0, 0);
-			fi = PIXSTEP(0, 1, lcd_dma.xres - 1, 0);
-		} else {
-			top = PIXADDR(0, lcd_dma.yres - 1);
-			bottom = PIXADDR(lcd_dma.xres - 1, 0);
-			ei = PIXSTEP(0, 0, 1, 0);
-			fi = PIXSTEP(lcd_dma.xres - 1, 1, 0, 0);
-		}
-		en = lcd_dma.xres;
-		fn = lcd_dma.yres;
-		break;
-	case 270:
-		if (!lcd_dma.mirror) {
-			top = PIXADDR(lcd_dma.xres - 1, 0);
-			bottom = PIXADDR(0, lcd_dma.yres - 1);
-			ei = PIXSTEP(0, 0, 0, 1);
-			fi = PIXSTEP(1, lcd_dma.yres - 1, 0, 0);
-		} else {
-			top = PIXADDR(0, 0);
-			bottom = PIXADDR(lcd_dma.xres - 1, lcd_dma.yres - 1);
-			ei = PIXSTEP(0, 0, 0, 1);
-			fi = PIXSTEP(0, lcd_dma.yres - 1, 1, 0);
-		}
-		en = lcd_dma.yres;
-		fn = lcd_dma.xres;
-		break;
-	default:
-		BUG();
-		return;	/* Supress warning about uninitialized vars */
-	}
-
-	if (omap_dma_in_1510_mode()) {
-		omap_writew(top >> 16, OMAP1510_DMA_LCD_TOP_F1_U);
-		omap_writew(top, OMAP1510_DMA_LCD_TOP_F1_L);
-		omap_writew(bottom >> 16, OMAP1510_DMA_LCD_BOT_F1_U);
-		omap_writew(bottom, OMAP1510_DMA_LCD_BOT_F1_L);
-
-		return;
-	}
-
-	/* 1610 regs */
-	omap_writew(top >> 16, OMAP1610_DMA_LCD_TOP_B1_U);
-	omap_writew(top, OMAP1610_DMA_LCD_TOP_B1_L);
-	omap_writew(bottom >> 16, OMAP1610_DMA_LCD_BOT_B1_U);
-	omap_writew(bottom, OMAP1610_DMA_LCD_BOT_B1_L);
-
-	omap_writew(en, OMAP1610_DMA_LCD_SRC_EN_B1);
-	omap_writew(fn, OMAP1610_DMA_LCD_SRC_FN_B1);
-
-	w = omap_readw(OMAP1610_DMA_LCD_CSDP);
-	w &= ~0x03;
-	w |= lcd_dma.data_type;
-	omap_writew(w, OMAP1610_DMA_LCD_CSDP);
-
-	w = omap_readw(OMAP1610_DMA_LCD_CTRL);
-	/* Always set the source port as SDRAM for now*/
-	w &= ~(0x03 << 6);
-	if (lcd_dma.ext_ctrl)
-		w |= 1 << 8;
-	else
-		w &= ~(1 << 8);
-	if (lcd_dma.callback != NULL)
-		w |= 1 << 1;            /* Block interrupt enable */
-	else
-		w &= ~(1 << 1);
-	omap_writew(w, OMAP1610_DMA_LCD_CTRL);
-
-	if (!(lcd_dma.rotate || lcd_dma.mirror ||
-	      lcd_dma.vxres || lcd_dma.xscale || lcd_dma.yscale))
-		return;
-
-	w = omap_readw(OMAP1610_DMA_LCD_CCR);
-	/* Set the double-indexed addressing mode */
-	w |= (0x03 << 12);
-	omap_writew(w, OMAP1610_DMA_LCD_CCR);
-
-	omap_writew(ei, OMAP1610_DMA_LCD_SRC_EI_B1);
-	omap_writew(fi >> 16, OMAP1610_DMA_LCD_SRC_FI_B1_U);
-	omap_writew(fi, OMAP1610_DMA_LCD_SRC_FI_B1_L);
-}
-
-static irqreturn_t lcd_dma_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
-{
-	u16 w;
-
-	w = omap_readw(OMAP1610_DMA_LCD_CTRL);
-	if (unlikely(!(w & (1 << 3)))) {
-		printk(KERN_WARNING "Spurious LCD DMA IRQ\n");
-		return IRQ_NONE;
-	}
-	/* Ack the IRQ */
-	w |= (1 << 3);
-	omap_writew(w, OMAP1610_DMA_LCD_CTRL);
-	lcd_dma.active = 0;
-	if (lcd_dma.callback != NULL)
-		lcd_dma.callback(w, lcd_dma.cb_data);
-
-	return IRQ_HANDLED;
-}
-
-int omap_request_lcd_dma(void (* callback)(u16 status, void *data),
-			 void *data)
-{
-	spin_lock_irq(&lcd_dma.lock);
-	if (lcd_dma.reserved) {
-		spin_unlock_irq(&lcd_dma.lock);
-		printk(KERN_ERR "LCD DMA channel already reserved\n");
-		BUG();
-		return -EBUSY;
-	}
-	lcd_dma.reserved = 1;
-	spin_unlock_irq(&lcd_dma.lock);
-	lcd_dma.callback = callback;
-	lcd_dma.cb_data = data;
-	lcd_dma.active = 0;
-	lcd_dma.single_transfer = 0;
-	lcd_dma.rotate = 0;
-	lcd_dma.vxres = 0;
-	lcd_dma.mirror = 0;
-	lcd_dma.xscale = 0;
-	lcd_dma.yscale = 0;
-	lcd_dma.ext_ctrl = 0;
-	lcd_dma.src_port = 0;
-
-	return 0;
-}
-
-void omap_free_lcd_dma(void)
-{
-	spin_lock(&lcd_dma.lock);
-	if (!lcd_dma.reserved) {
-		spin_unlock(&lcd_dma.lock);
-		printk(KERN_ERR "LCD DMA is not reserved\n");
-		BUG();
-		return;
-	}
-	if (!enable_1510_mode)
-		omap_writew(omap_readw(OMAP1610_DMA_LCD_CCR) & ~1, OMAP1610_DMA_LCD_CCR);
-	lcd_dma.reserved = 0;
-	spin_unlock(&lcd_dma.lock);
-}
-
-void omap_enable_lcd_dma(void)
-{
-	u16 w;
-
-	/* Set the Enable bit only if an external controller is
-	 * connected. Otherwise the OMAP internal controller will
-	 * start the transfer when it gets enabled.
-	 */
-	if (enable_1510_mode || !lcd_dma.ext_ctrl)
-		return;
-	w = omap_readw(OMAP1610_DMA_LCD_CCR);
-	w |= 1 << 7;
-	omap_writew(w, OMAP1610_DMA_LCD_CCR);
-	lcd_dma.active = 1;
-}
-
-void omap_setup_lcd_dma(void)
-{
-	BUG_ON(lcd_dma.active);
-	if (!enable_1510_mode) {
-		/* Set some reasonable defaults */
-		omap_writew(0x5440, OMAP1610_DMA_LCD_CCR);
-		omap_writew(0x9102, OMAP1610_DMA_LCD_CSDP);
-		omap_writew(0x0004, OMAP1610_DMA_LCD_LCH_CTRL);
-	}
-	set_b1_regs();
-	if (!enable_1510_mode) {
-		u16 w;
-
-		w = omap_readw(OMAP1610_DMA_LCD_CCR);
-		/* If DMA was already active set the end_prog bit to have
-		 * the programmed register set loaded into the active
-		 * register set.
-		 */
-		w |= 1 << 11;		/* End_prog */
-		if (!lcd_dma.single_transfer)
-	        	w |= (3 << 8);	/* Auto_init, repeat */
-		omap_writew(w, OMAP1610_DMA_LCD_CCR);
-	}
-}
-
-void omap_stop_lcd_dma(void)
-{
-	lcd_dma.active = 0;
-	if (!enable_1510_mode && lcd_dma.ext_ctrl)
-		omap_writew(omap_readw(OMAP1610_DMA_LCD_CCR) & ~(1 << 7),
-			    OMAP1610_DMA_LCD_CCR);
-}
-
-/*
- * Clears any DMA state so the DMA engine is ready to restart with new buffers
- * through omap_start_dma(). Any buffers in flight are discarded.
- */
-void omap_clear_dma(int lch)
-{
-	unsigned long flags;
-	int status;
-
-	local_irq_save(flags);
-	omap_writew(omap_readw(OMAP_DMA_CCR(lch)) & ~OMAP_DMA_CCR_EN,
-		    OMAP_DMA_CCR(lch));
-	status = OMAP_DMA_CSR(lch);	/* clear pending interrupts */
-	local_irq_restore(flags);
-}
-
-/*
- * Returns current physical source address for the given DMA channel.
- * If the channel is running the caller must disable interrupts prior calling
- * this function and process the returned value before re-enabling interrupt to
- * prevent races with the interrupt handler. Note that in continuous mode there
- * is a chance for CSSA_L register overflow inbetween the two reads resulting
- * in incorrect return value.
- */
-dma_addr_t omap_get_dma_src_pos(int lch)
-{
-	return (dma_addr_t) (OMAP_DMA_CSSA_L(lch) |
-			     (OMAP_DMA_CSSA_U(lch) << 16));
-}
-
-/*
- * Returns current physical destination address for the given DMA channel.
- * If the channel is running the caller must disable interrupts prior calling
- * this function and process the returned value before re-enabling interrupt to
- * prevent races with the interrupt handler. Note that in continuous mode there
- * is a chance for CDSA_L register overflow inbetween the two reads resulting
- * in incorrect return value.
- */
-dma_addr_t omap_get_dma_dst_pos(int lch)
-{
-	return (dma_addr_t) (OMAP_DMA_CDSA_L(lch) |
-			     (OMAP_DMA_CDSA_U(lch) << 16));
-}
-
-static int __init omap_init_dma(void)
-{
-	int ch, r;
-
-	if (cpu_is_omap1510()) {
-		printk(KERN_INFO "DMA support for OMAP1510 initialized\n");
-		dma_chan_count = 9;
-		enable_1510_mode = 1;
-	} else if (cpu_is_omap16xx() || cpu_is_omap730()) {
-		printk(KERN_INFO "OMAP DMA hardware version %d\n",
-		       omap_readw(OMAP_DMA_HW_ID));
-		printk(KERN_INFO "DMA capabilities: %08x:%08x:%04x:%04x:%04x\n",
-		       (omap_readw(OMAP_DMA_CAPS_0_U) << 16) | omap_readw(OMAP_DMA_CAPS_0_L),
-		       (omap_readw(OMAP_DMA_CAPS_1_U) << 16) | omap_readw(OMAP_DMA_CAPS_1_L),
-		       omap_readw(OMAP_DMA_CAPS_2), omap_readw(OMAP_DMA_CAPS_3),
-		       omap_readw(OMAP_DMA_CAPS_4));
-		if (!enable_1510_mode) {
-			u16 w;
-
-			/* Disable OMAP 3.0/3.1 compatibility mode. */
-			w = omap_readw(OMAP_DMA_GSCR);
-			w |= 1 << 3;
-			omap_writew(w, OMAP_DMA_GSCR);
-			dma_chan_count = 16;
-		} else
-			dma_chan_count = 9;
-	} else {
-		dma_chan_count = 0;
-		return 0;
-	}
-
-	memset(&lcd_dma, 0, sizeof(lcd_dma));
-	spin_lock_init(&lcd_dma.lock);
-	spin_lock_init(&dma_chan_lock);
-	memset(&dma_chan, 0, sizeof(dma_chan));
-
-	for (ch = 0; ch < dma_chan_count; ch++) {
-		dma_chan[ch].dev_id = -1;
-		dma_chan[ch].next_lch = -1;
-
-		if (ch >= 6 && enable_1510_mode)
-			continue;
-
-		/* request_irq() doesn't like dev_id (ie. ch) being zero,
-		 * so we have to kludge around this. */
-		r = request_irq(dma_irq[ch], dma_irq_handler, 0, "DMA",
-				(void *) (ch + 1));
-		if (r != 0) {
-			int i;
-
-			printk(KERN_ERR "unable to request IRQ %d for DMA (error %d)\n",
-			       dma_irq[ch], r);
-			for (i = 0; i < ch; i++)
-				free_irq(dma_irq[i], (void *) (i + 1));
-			return r;
-		}
-	}
-	r = request_irq(INT_DMA_LCD, lcd_dma_irq_handler, 0, "LCD DMA", NULL);
-	if (r != 0) {
-		int i;
-
-		printk(KERN_ERR "unable to request IRQ for LCD DMA (error %d)\n", r);
-		for (i = 0; i < dma_chan_count; i++)
-			free_irq(dma_irq[i], (void *) (i + 1));
-		return r;
-	}
-	return 0;
-}
-
-arch_initcall(omap_init_dma);
-
-
-EXPORT_SYMBOL(omap_get_dma_src_pos);
-EXPORT_SYMBOL(omap_get_dma_dst_pos);
-EXPORT_SYMBOL(omap_clear_dma);
-EXPORT_SYMBOL(omap_set_dma_priority);
-EXPORT_SYMBOL(omap_request_dma);
-EXPORT_SYMBOL(omap_free_dma);
-EXPORT_SYMBOL(omap_start_dma);
-EXPORT_SYMBOL(omap_stop_dma);
-EXPORT_SYMBOL(omap_enable_dma_irq);
-EXPORT_SYMBOL(omap_disable_dma_irq);
-
-EXPORT_SYMBOL(omap_set_dma_transfer_params);
-EXPORT_SYMBOL(omap_set_dma_color_mode);
-
-EXPORT_SYMBOL(omap_set_dma_src_params);
-EXPORT_SYMBOL(omap_set_dma_src_index);
-EXPORT_SYMBOL(omap_set_dma_src_data_pack);
-EXPORT_SYMBOL(omap_set_dma_src_burst_mode);
-
-EXPORT_SYMBOL(omap_set_dma_dest_params);
-EXPORT_SYMBOL(omap_set_dma_dest_index);
-EXPORT_SYMBOL(omap_set_dma_dest_data_pack);
-EXPORT_SYMBOL(omap_set_dma_dest_burst_mode);
-
-EXPORT_SYMBOL(omap_dma_link_lch);
-EXPORT_SYMBOL(omap_dma_unlink_lch);
-
-EXPORT_SYMBOL(omap_request_lcd_dma);
-EXPORT_SYMBOL(omap_free_lcd_dma);
-EXPORT_SYMBOL(omap_enable_lcd_dma);
-EXPORT_SYMBOL(omap_setup_lcd_dma);
-EXPORT_SYMBOL(omap_stop_lcd_dma);
-EXPORT_SYMBOL(omap_set_lcd_dma_b1);
-EXPORT_SYMBOL(omap_set_lcd_dma_single_transfer);
-EXPORT_SYMBOL(omap_set_lcd_dma_ext_controller);
-EXPORT_SYMBOL(omap_set_lcd_dma_b1_rotation);
-EXPORT_SYMBOL(omap_set_lcd_dma_b1_vxres);
-EXPORT_SYMBOL(omap_set_lcd_dma_b1_scale);
-EXPORT_SYMBOL(omap_set_lcd_dma_b1_mirror);
-
diff --git a/arch/arm/mach-omap/fpga.c b/arch/arm/mach-omap/fpga.c
deleted file mode 100644
--- a/arch/arm/mach-omap/fpga.c
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * linux/arch/arm/mach-omap/fpga.c
- *
- * Interrupt handler for OMAP-1510 Innovator FPGA
- *
- * Copyright (C) 2001 RidgeRun, Inc.
- * Author: Greg Lonnon <glonnon@ridgerun.com>
- *
- * Copyright (C) 2002 MontaVista Software, Inc.
- *
- * Separated FPGA interrupts from innovator1510.c and cleaned up for 2.6
- * Copyright (C) 2004 Nokia Corporation by Tony Lindrgen <tony@atomide.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/config.h>
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/device.h>
-#include <linux/errno.h>
-
-#include <asm/hardware.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/mach/irq.h>
-
-#include <asm/arch/fpga.h>
-#include <asm/arch/gpio.h>
-
-static void fpga_mask_irq(unsigned int irq)
-{
-	irq -= OMAP1510_IH_FPGA_BASE;
-
-	if (irq < 8)
-		__raw_writeb((__raw_readb(OMAP1510_FPGA_IMR_LO)
-			      & ~(1 << irq)), OMAP1510_FPGA_IMR_LO);
-	else if (irq < 16)
-		__raw_writeb((__raw_readb(OMAP1510_FPGA_IMR_HI)
-			      & ~(1 << (irq - 8))), OMAP1510_FPGA_IMR_HI);
-	else
-		__raw_writeb((__raw_readb(INNOVATOR_FPGA_IMR2)
-			      & ~(1 << (irq - 16))), INNOVATOR_FPGA_IMR2);
-}
-
-
-static inline u32 get_fpga_unmasked_irqs(void)
-{
-	return
-		((__raw_readb(OMAP1510_FPGA_ISR_LO) &
-		  __raw_readb(OMAP1510_FPGA_IMR_LO))) |
-		((__raw_readb(OMAP1510_FPGA_ISR_HI) &
-		  __raw_readb(OMAP1510_FPGA_IMR_HI)) << 8) |
-		((__raw_readb(INNOVATOR_FPGA_ISR2) &
-		  __raw_readb(INNOVATOR_FPGA_IMR2)) << 16);
-}
-
-
-static void fpga_ack_irq(unsigned int irq)
-{
-	/* Don't need to explicitly ACK FPGA interrupts */
-}
-
-static void fpga_unmask_irq(unsigned int irq)
-{
-	irq -= OMAP1510_IH_FPGA_BASE;
-
-	if (irq < 8)
-		__raw_writeb((__raw_readb(OMAP1510_FPGA_IMR_LO) | (1 << irq)),
-		     OMAP1510_FPGA_IMR_LO);
-	else if (irq < 16)
-		__raw_writeb((__raw_readb(OMAP1510_FPGA_IMR_HI)
-			      | (1 << (irq - 8))), OMAP1510_FPGA_IMR_HI);
-	else
-		__raw_writeb((__raw_readb(INNOVATOR_FPGA_IMR2)
-			      | (1 << (irq - 16))), INNOVATOR_FPGA_IMR2);
-}
-
-static void fpga_mask_ack_irq(unsigned int irq)
-{
-	fpga_mask_irq(irq);
-	fpga_ack_irq(irq);
-}
-
-void innovator_fpga_IRQ_demux(unsigned int irq, struct irqdesc *desc,
-			      struct pt_regs *regs)
-{
-	struct irqdesc *d;
-	u32 stat;
-	int fpga_irq;
-
-	stat = get_fpga_unmasked_irqs();
-
-	if (!stat)
-		return;
-
-	for (fpga_irq = OMAP1510_IH_FPGA_BASE;
-	     (fpga_irq < (OMAP1510_IH_FPGA_BASE + NR_FPGA_IRQS)) && stat;
-	     fpga_irq++, stat >>= 1) {
-		if (stat & 1) {
-			d = irq_desc + fpga_irq;
-			d->handle(fpga_irq, d, regs);
-		}
-	}
-}
-
-static struct irqchip omap_fpga_irq_ack = {
-	.ack		= fpga_mask_ack_irq,
-	.mask		= fpga_mask_irq,
-	.unmask		= fpga_unmask_irq,
-};
-
-
-static struct irqchip omap_fpga_irq = {
-	.ack		= fpga_ack_irq,
-	.mask		= fpga_mask_irq,
-	.unmask		= fpga_unmask_irq,
-};
-
-/*
- * All of the FPGA interrupt request inputs except for the touchscreen are
- * edge-sensitive; the touchscreen is level-sensitive.  The edge-sensitive
- * interrupts are acknowledged as a side-effect of reading the interrupt
- * status register from the FPGA.  The edge-sensitive interrupt inputs
- * cause a problem with level interrupt requests, such as Ethernet.  The
- * problem occurs when a level interrupt request is asserted while its
- * interrupt input is masked in the FPGA, which results in a missed
- * interrupt.
- *
- * In an attempt to workaround the problem with missed interrupts, the
- * mask_ack routine for all of the FPGA interrupts has been changed from
- * fpga_mask_ack_irq() to fpga_ack_irq() so that the specific FPGA interrupt
- * being serviced is left unmasked.  We can do this because the FPGA cascade
- * interrupt is installed with the SA_INTERRUPT flag, which leaves all
- * interrupts masked at the CPU while an FPGA interrupt handler executes.
- *
- * Limited testing indicates that this workaround appears to be effective
- * for the smc9194 Ethernet driver used on the Innovator.  It should work
- * on other FPGA interrupts as well, but any drivers that explicitly mask
- * interrupts at the interrupt controller via disable_irq/enable_irq
- * could pose a problem.
- */
-void omap1510_fpga_init_irq(void)
-{
-	int i;
-
-	__raw_writeb(0, OMAP1510_FPGA_IMR_LO);
-	__raw_writeb(0, OMAP1510_FPGA_IMR_HI);
-	__raw_writeb(0, INNOVATOR_FPGA_IMR2);
-
-	for (i = OMAP1510_IH_FPGA_BASE; i < (OMAP1510_IH_FPGA_BASE + NR_FPGA_IRQS); i++) {
-
-		if (i == OMAP1510_INT_FPGA_TS) {
-			/*
-			 * The touchscreen interrupt is level-sensitive, so
-			 * we'll use the regular mask_ack routine for it.
-			 */
-			set_irq_chip(i, &omap_fpga_irq_ack);
-		}
-		else {
-			/*
-			 * All FPGA interrupts except the touchscreen are
-			 * edge-sensitive, so we won't mask them.
-			 */
-			set_irq_chip(i, &omap_fpga_irq);
-		}
-
-		set_irq_handler(i, do_edge_IRQ);
-		set_irq_flags(i, IRQF_VALID);
-	}
-
-	/*
-	 * The FPGA interrupt line is connected to GPIO13. Claim this pin for
-	 * the ARM.
-	 *
-	 * NOTE: For general GPIO/MPUIO access and interrupts, please see
-	 * gpio.[ch]
-	 */
-	omap_request_gpio(13);
-	omap_set_gpio_direction(13, 1);
-	omap_set_gpio_edge_ctrl(13, OMAP_GPIO_RISING_EDGE);
-	set_irq_chained_handler(OMAP1510_INT_FPGA, innovator_fpga_IRQ_demux);
-}
-
-EXPORT_SYMBOL(omap1510_fpga_init_irq);
diff --git a/arch/arm/mach-omap/gpio.c b/arch/arm/mach-omap/gpio.c
deleted file mode 100644
--- a/arch/arm/mach-omap/gpio.c
+++ /dev/null
@@ -1,762 +0,0 @@
-/*
- *  linux/arch/arm/mach-omap/gpio.c
- *
- * Support functions for OMAP GPIO
- *
- * Copyright (C) 2003 Nokia Corporation
- * Written by Juha Yrjölä <juha.yrjola@nokia.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/ptrace.h>
-
-#include <asm/hardware.h>
-#include <asm/irq.h>
-#include <asm/arch/irqs.h>
-#include <asm/arch/gpio.h>
-#include <asm/mach/irq.h>
-
-#include <asm/io.h>
-
-/*
- * OMAP1510 GPIO registers
- */
-#define OMAP1510_GPIO_BASE		0xfffce000
-#define OMAP1510_GPIO_DATA_INPUT	0x00
-#define OMAP1510_GPIO_DATA_OUTPUT	0x04
-#define OMAP1510_GPIO_DIR_CONTROL	0x08
-#define OMAP1510_GPIO_INT_CONTROL	0x0c
-#define OMAP1510_GPIO_INT_MASK		0x10
-#define OMAP1510_GPIO_INT_STATUS	0x14
-#define OMAP1510_GPIO_PIN_CONTROL	0x18
-
-#define OMAP1510_IH_GPIO_BASE		64
-
-/*
- * OMAP1610 specific GPIO registers
- */
-#define OMAP1610_GPIO1_BASE		0xfffbe400
-#define OMAP1610_GPIO2_BASE		0xfffbec00
-#define OMAP1610_GPIO3_BASE		0xfffbb400
-#define OMAP1610_GPIO4_BASE		0xfffbbc00
-#define OMAP1610_GPIO_REVISION		0x0000
-#define OMAP1610_GPIO_SYSCONFIG		0x0010
-#define OMAP1610_GPIO_SYSSTATUS		0x0014
-#define OMAP1610_GPIO_IRQSTATUS1	0x0018
-#define OMAP1610_GPIO_IRQENABLE1	0x001c
-#define OMAP1610_GPIO_DATAIN		0x002c
-#define OMAP1610_GPIO_DATAOUT		0x0030
-#define OMAP1610_GPIO_DIRECTION		0x0034
-#define OMAP1610_GPIO_EDGE_CTRL1	0x0038
-#define OMAP1610_GPIO_EDGE_CTRL2	0x003c
-#define OMAP1610_GPIO_CLEAR_IRQENABLE1	0x009c
-#define OMAP1610_GPIO_CLEAR_DATAOUT	0x00b0
-#define OMAP1610_GPIO_SET_IRQENABLE1	0x00dc
-#define OMAP1610_GPIO_SET_DATAOUT	0x00f0
-
-/*
- * OMAP730 specific GPIO registers
- */
-#define OMAP730_GPIO1_BASE		0xfffbc000
-#define OMAP730_GPIO2_BASE		0xfffbc800
-#define OMAP730_GPIO3_BASE		0xfffbd000
-#define OMAP730_GPIO4_BASE		0xfffbd800
-#define OMAP730_GPIO5_BASE		0xfffbe000
-#define OMAP730_GPIO6_BASE		0xfffbe800
-#define OMAP730_GPIO_DATA_INPUT		0x00
-#define OMAP730_GPIO_DATA_OUTPUT	0x04
-#define OMAP730_GPIO_DIR_CONTROL	0x08
-#define OMAP730_GPIO_INT_CONTROL	0x0c
-#define OMAP730_GPIO_INT_MASK		0x10
-#define OMAP730_GPIO_INT_STATUS		0x14
-
-#define OMAP_MPUIO_MASK		(~OMAP_MAX_GPIO_LINES & 0xff)
-
-struct gpio_bank {
-	u32 base;
-	u16 irq;
-	u16 virtual_irq_start;
-	u8 method;
-	u32 reserved_map;
-	spinlock_t lock;
-};
-
-#define METHOD_MPUIO		0
-#define METHOD_GPIO_1510	1
-#define METHOD_GPIO_1610	2
-#define METHOD_GPIO_730		3
-
-#if defined(CONFIG_ARCH_OMAP16XX)
-static struct gpio_bank gpio_bank_1610[5] = {
-	{ OMAP_MPUIO_BASE,     INT_MPUIO,	    IH_MPUIO_BASE,     METHOD_MPUIO},
-	{ OMAP1610_GPIO1_BASE, INT_GPIO_BANK1,	    IH_GPIO_BASE,      METHOD_GPIO_1610 },
-	{ OMAP1610_GPIO2_BASE, INT_1610_GPIO_BANK2, IH_GPIO_BASE + 16, METHOD_GPIO_1610 },
-	{ OMAP1610_GPIO3_BASE, INT_1610_GPIO_BANK3, IH_GPIO_BASE + 32, METHOD_GPIO_1610 },
-	{ OMAP1610_GPIO4_BASE, INT_1610_GPIO_BANK4, IH_GPIO_BASE + 48, METHOD_GPIO_1610 },
-};
-#endif
-
-#ifdef CONFIG_ARCH_OMAP1510
-static struct gpio_bank gpio_bank_1510[2] = {
-	{ OMAP_MPUIO_BASE,    INT_MPUIO,      IH_MPUIO_BASE, METHOD_MPUIO },
-	{ OMAP1510_GPIO_BASE, INT_GPIO_BANK1, IH_GPIO_BASE,  METHOD_GPIO_1510 }
-};
-#endif
-
-#ifdef CONFIG_ARCH_OMAP730
-static struct gpio_bank gpio_bank_730[7] = {
-	{ OMAP_MPUIO_BASE,     INT_730_MPUIO,	    IH_MPUIO_BASE,	METHOD_MPUIO },
-	{ OMAP730_GPIO1_BASE,  INT_730_GPIO_BANK1,  IH_GPIO_BASE,	METHOD_GPIO_730 },
-	{ OMAP730_GPIO2_BASE,  INT_730_GPIO_BANK2,  IH_GPIO_BASE + 32,	METHOD_GPIO_730 },
-	{ OMAP730_GPIO3_BASE,  INT_730_GPIO_BANK3,  IH_GPIO_BASE + 64,	METHOD_GPIO_730 },
-	{ OMAP730_GPIO4_BASE,  INT_730_GPIO_BANK4,  IH_GPIO_BASE + 96,	METHOD_GPIO_730 },
-	{ OMAP730_GPIO5_BASE,  INT_730_GPIO_BANK5,  IH_GPIO_BASE + 128, METHOD_GPIO_730 },
-	{ OMAP730_GPIO6_BASE,  INT_730_GPIO_BANK6,  IH_GPIO_BASE + 160, METHOD_GPIO_730 },
-};
-#endif
-
-static struct gpio_bank *gpio_bank;
-static int gpio_bank_count;
-
-static inline struct gpio_bank *get_gpio_bank(int gpio)
-{
-#ifdef CONFIG_ARCH_OMAP1510
-	if (cpu_is_omap1510()) {
-		if (OMAP_GPIO_IS_MPUIO(gpio))
-			return &gpio_bank[0];
-		return &gpio_bank[1];
-	}
-#endif
-#if defined(CONFIG_ARCH_OMAP16XX)
-	if (cpu_is_omap16xx()) {
-		if (OMAP_GPIO_IS_MPUIO(gpio))
-			return &gpio_bank[0];
-		return &gpio_bank[1 + (gpio >> 4)];
-	}
-#endif
-#ifdef CONFIG_ARCH_OMAP730
-	if (cpu_is_omap730()) {
-		if (OMAP_GPIO_IS_MPUIO(gpio))
-			return &gpio_bank[0];
-		return &gpio_bank[1 + (gpio >> 5)];
-	}
-#endif
-}
-
-static inline int get_gpio_index(int gpio)
-{
-	if (cpu_is_omap730())
-		return gpio & 0x1f;
-	else
-		return gpio & 0x0f;
-}
-
-static inline int gpio_valid(int gpio)
-{
-	if (gpio < 0)
-		return -1;
-	if (OMAP_GPIO_IS_MPUIO(gpio)) {
-		if ((gpio & OMAP_MPUIO_MASK) > 16)
-			return -1;
-		return 0;
-	}
-#ifdef CONFIG_ARCH_OMAP1510
-	if (cpu_is_omap1510() && gpio < 16)
-		return 0;
-#endif
-#if defined(CONFIG_ARCH_OMAP16XX)
-	if ((cpu_is_omap16xx()) && gpio < 64)
-		return 0;
-#endif
-#ifdef CONFIG_ARCH_OMAP730
-	if (cpu_is_omap730() && gpio < 192)
-		return 0;
-#endif
-	return -1;
-}
-
-static int check_gpio(int gpio)
-{
-	if (unlikely(gpio_valid(gpio)) < 0) {
-		printk(KERN_ERR "omap-gpio: invalid GPIO %d\n", gpio);
-		dump_stack();
-		return -1;
-	}
-	return 0;
-}
-
-static void _set_gpio_direction(struct gpio_bank *bank, int gpio, int is_input)
-{
-	u32 reg = bank->base;
-	u32 l;
-
-	switch (bank->method) {
-	case METHOD_MPUIO:
-		reg += OMAP_MPUIO_IO_CNTL;
-		break;
-	case METHOD_GPIO_1510:
-		reg += OMAP1510_GPIO_DIR_CONTROL;
-		break;
-	case METHOD_GPIO_1610:
-		reg += OMAP1610_GPIO_DIRECTION;
-		break;
-	case METHOD_GPIO_730:
-		reg += OMAP730_GPIO_DIR_CONTROL;
-		break;
-	}
-	l = __raw_readl(reg);
-	if (is_input)
-		l |= 1 << gpio;
-	else
-		l &= ~(1 << gpio);
-	__raw_writel(l, reg);
-}
-
-void omap_set_gpio_direction(int gpio, int is_input)
-{
-	struct gpio_bank *bank;
-
-	if (check_gpio(gpio) < 0)
-		return;
-	bank = get_gpio_bank(gpio);
-	spin_lock(&bank->lock);
-	_set_gpio_direction(bank, get_gpio_index(gpio), is_input);
-	spin_unlock(&bank->lock);
-}
-
-static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable)
-{
-	u32 reg = bank->base;
-	u32 l = 0;
-
-	switch (bank->method) {
-	case METHOD_MPUIO:
-		reg += OMAP_MPUIO_OUTPUT;
-		l = __raw_readl(reg);
-		if (enable)
-			l |= 1 << gpio;
-		else
-			l &= ~(1 << gpio);
-		break;
-	case METHOD_GPIO_1510:
-		reg += OMAP1510_GPIO_DATA_OUTPUT;
-		l = __raw_readl(reg);
-		if (enable)
-			l |= 1 << gpio;
-		else
-			l &= ~(1 << gpio);
-		break;
-	case METHOD_GPIO_1610:
-		if (enable)
-			reg += OMAP1610_GPIO_SET_DATAOUT;
-		else
-			reg += OMAP1610_GPIO_CLEAR_DATAOUT;
-		l = 1 << gpio;
-		break;
-	case METHOD_GPIO_730:
-		reg += OMAP730_GPIO_DATA_OUTPUT;
-		l = __raw_readl(reg);
-		if (enable)
-			l |= 1 << gpio;
-		else
-			l &= ~(1 << gpio);
-		break;
-	default:
-		BUG();
-		return;
-	}
-	__raw_writel(l, reg);
-}
-
-void omap_set_gpio_dataout(int gpio, int enable)
-{
-	struct gpio_bank *bank;
-
-	if (check_gpio(gpio) < 0)
-		return;
-	bank = get_gpio_bank(gpio);
-	spin_lock(&bank->lock);
-	_set_gpio_dataout(bank, get_gpio_index(gpio), enable);
-	spin_unlock(&bank->lock);
-}
-
-int omap_get_gpio_datain(int gpio)
-{
-	struct gpio_bank *bank;
-	u32 reg;
-
-	if (check_gpio(gpio) < 0)
-		return -1;
-	bank = get_gpio_bank(gpio);
-	reg = bank->base;
-	switch (bank->method) {
-	case METHOD_MPUIO:
-		reg += OMAP_MPUIO_INPUT_LATCH;
-		break;
-	case METHOD_GPIO_1510:
-		reg += OMAP1510_GPIO_DATA_INPUT;
-		break;
-	case METHOD_GPIO_1610:
-		reg += OMAP1610_GPIO_DATAIN;
-		break;
-	case METHOD_GPIO_730:
-		reg += OMAP730_GPIO_DATA_INPUT;
-		break;
-	default:
-		BUG();
-		return -1;
-	}
-	return (__raw_readl(reg) & (1 << get_gpio_index(gpio))) != 0;
-}
-
-static void _set_gpio_edge_ctrl(struct gpio_bank *bank, int gpio, int edge)
-{
-	u32 reg = bank->base;
-	u32 l;
-
-	switch (bank->method) {
-	case METHOD_MPUIO:
-		reg += OMAP_MPUIO_GPIO_INT_EDGE;
-		l = __raw_readl(reg);
-		if (edge == OMAP_GPIO_RISING_EDGE)
-			l |= 1 << gpio;
-		else
-			l &= ~(1 << gpio);
-		__raw_writel(l, reg);
-		break;
-	case METHOD_GPIO_1510:
-		reg += OMAP1510_GPIO_INT_CONTROL;
-		l = __raw_readl(reg);
-		if (edge == OMAP_GPIO_RISING_EDGE)
-			l |= 1 << gpio;
-		else
-			l &= ~(1 << gpio);
-		__raw_writel(l, reg);
-		break;
-	case METHOD_GPIO_1610:
-		edge &= 0x03;
-		if (gpio & 0x08)
-			reg += OMAP1610_GPIO_EDGE_CTRL2;
-		else
-			reg += OMAP1610_GPIO_EDGE_CTRL1;
-		gpio &= 0x07;
-		l = __raw_readl(reg);
-		l &= ~(3 << (gpio << 1));
-		l |= edge << (gpio << 1);
-		__raw_writel(l, reg);
-		break;
-	case METHOD_GPIO_730:
-		reg += OMAP730_GPIO_INT_CONTROL;
-		l = __raw_readl(reg);
-		if (edge == OMAP_GPIO_RISING_EDGE)
-			l |= 1 << gpio;
-		else
-			l &= ~(1 << gpio);
-		__raw_writel(l, reg);
-		break;
-	default:
-		BUG();
-		return;
-	}
-}
-
-void omap_set_gpio_edge_ctrl(int gpio, int edge)
-{
-	struct gpio_bank *bank;
-
-	if (check_gpio(gpio) < 0)
-		return;
-	bank = get_gpio_bank(gpio);
-	spin_lock(&bank->lock);
-	_set_gpio_edge_ctrl(bank, get_gpio_index(gpio), edge);
-	spin_unlock(&bank->lock);
-}
-
-
-static int _get_gpio_edge_ctrl(struct gpio_bank *bank, int gpio)
-{
-	u32 reg = bank->base, l;
-
-	switch (bank->method) {
-	case METHOD_MPUIO:
-		l = __raw_readl(reg + OMAP_MPUIO_GPIO_INT_EDGE);
-		return (l & (1 << gpio)) ?
-			OMAP_GPIO_RISING_EDGE : OMAP_GPIO_FALLING_EDGE;
-	case METHOD_GPIO_1510:
-		l = __raw_readl(reg + OMAP1510_GPIO_INT_CONTROL);
-		return (l & (1 << gpio)) ?
-			OMAP_GPIO_RISING_EDGE : OMAP_GPIO_FALLING_EDGE;
-	case METHOD_GPIO_1610:
-		if (gpio & 0x08)
-			reg += OMAP1610_GPIO_EDGE_CTRL2;
-		else
-			reg += OMAP1610_GPIO_EDGE_CTRL1;
-		return (__raw_readl(reg) >> ((gpio & 0x07) << 1)) & 0x03;
-	case METHOD_GPIO_730:
-		l = __raw_readl(reg + OMAP730_GPIO_INT_CONTROL);
-		return (l & (1 << gpio)) ?
-			OMAP_GPIO_RISING_EDGE : OMAP_GPIO_FALLING_EDGE;
-	default:
-		BUG();
-		return -1;
-	}
-}
-
-static void _clear_gpio_irqbank(struct gpio_bank *bank, int gpio_mask)
-{
-	u32 reg = bank->base;
-
-	switch (bank->method) {
-	case METHOD_MPUIO:
-		/* MPUIO irqstatus is reset by reading the status register,
-		 * so do nothing here */
-		return;
-	case METHOD_GPIO_1510:
-		reg += OMAP1510_GPIO_INT_STATUS;
-		break;
-	case METHOD_GPIO_1610:
-		reg += OMAP1610_GPIO_IRQSTATUS1;
-		break;
-	case METHOD_GPIO_730:
-		reg += OMAP730_GPIO_INT_STATUS;
-		break;
-	default:
-		BUG();
-		return;
-	}
-	__raw_writel(gpio_mask, reg);
-}
-
-static inline void _clear_gpio_irqstatus(struct gpio_bank *bank, int gpio)
-{
-	_clear_gpio_irqbank(bank, 1 << get_gpio_index(gpio));
-}
-
-static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enable)
-{
-	u32 reg = bank->base;
-	u32 l;
-
-	switch (bank->method) {
-	case METHOD_MPUIO:
-		reg += OMAP_MPUIO_GPIO_MASKIT;
-		l = __raw_readl(reg);
-		if (enable)
-			l &= ~(gpio_mask);
-		else
-			l |= gpio_mask;
-		break;
-	case METHOD_GPIO_1510:
-		reg += OMAP1510_GPIO_INT_MASK;
-		l = __raw_readl(reg);
-		if (enable)
-			l &= ~(gpio_mask);
-		else
-			l |= gpio_mask;
-		break;
-	case METHOD_GPIO_1610:
-		if (enable)
-			reg += OMAP1610_GPIO_SET_IRQENABLE1;
-		else
-			reg += OMAP1610_GPIO_CLEAR_IRQENABLE1;
-		l = gpio_mask;
-		break;
-	case METHOD_GPIO_730:
-		reg += OMAP730_GPIO_INT_MASK;
-		l = __raw_readl(reg);
-		if (enable)
-			l &= ~(gpio_mask);
-		else
-			l |= gpio_mask;
-		break;
-	default:
-		BUG();
-		return;
-	}
-	__raw_writel(l, reg);
-}
-
-static inline void _set_gpio_irqenable(struct gpio_bank *bank, int gpio, int enable)
-{
-	_enable_gpio_irqbank(bank, 1 << get_gpio_index(gpio), enable);
-}
-
-int omap_request_gpio(int gpio)
-{
-	struct gpio_bank *bank;
-
-	if (check_gpio(gpio) < 0)
-		return -EINVAL;
-
-	bank = get_gpio_bank(gpio);
-	spin_lock(&bank->lock);
-	if (unlikely(bank->reserved_map & (1 << get_gpio_index(gpio)))) {
-		printk(KERN_ERR "omap-gpio: GPIO %d is already reserved!\n", gpio);
-		dump_stack();
-		spin_unlock(&bank->lock);
-		return -1;
-	}
-	bank->reserved_map |= (1 << get_gpio_index(gpio));
-#ifdef CONFIG_ARCH_OMAP1510
-	if (bank->method == METHOD_GPIO_1510) {
-		u32 reg;
-
-		/* Claim the pin for the ARM */
-		reg = bank->base + OMAP1510_GPIO_PIN_CONTROL;
-		__raw_writel(__raw_readl(reg) | (1 << get_gpio_index(gpio)), reg);
-	}
-#endif
-	spin_unlock(&bank->lock);
-
-	return 0;
-}
-
-void omap_free_gpio(int gpio)
-{
-	struct gpio_bank *bank;
-
-	if (check_gpio(gpio) < 0)
-		return;
-	bank = get_gpio_bank(gpio);
-	spin_lock(&bank->lock);
-	if (unlikely(!(bank->reserved_map & (1 << get_gpio_index(gpio))))) {
-		printk(KERN_ERR "omap-gpio: GPIO %d wasn't reserved!\n", gpio);
-		dump_stack();
-		spin_unlock(&bank->lock);
-		return;
-	}
-	bank->reserved_map &= ~(1 << get_gpio_index(gpio));
-	_set_gpio_direction(bank, get_gpio_index(gpio), 1);
-	_set_gpio_irqenable(bank, gpio, 0);
-	_clear_gpio_irqstatus(bank, gpio);
-	spin_unlock(&bank->lock);
-}
-
-/*
- * We need to unmask the GPIO bank interrupt as soon as possible to
- * avoid missing GPIO interrupts for other lines in the bank.
- * Then we need to mask-read-clear-unmask the triggered GPIO lines
- * in the bank to avoid missing nested interrupts for a GPIO line.
- * If we wait to unmask individual GPIO lines in the bank after the
- * line's interrupt handler has been run, we may miss some nested
- * interrupts.
- */
-static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc,
-			     struct pt_regs *regs)
-{
-	u32 isr_reg = 0;
-	u32 isr;
-	unsigned int gpio_irq;
-	struct gpio_bank *bank;
-
-	desc->chip->ack(irq);
-
-	bank = (struct gpio_bank *) desc->data;
-	if (bank->method == METHOD_MPUIO)
-		isr_reg = bank->base + OMAP_MPUIO_GPIO_INT;
-#ifdef CONFIG_ARCH_OMAP1510
-	if (bank->method == METHOD_GPIO_1510)
-		isr_reg = bank->base + OMAP1510_GPIO_INT_STATUS;
-#endif
-#if defined(CONFIG_ARCH_OMAP16XX)
-	if (bank->method == METHOD_GPIO_1610)
-		isr_reg = bank->base + OMAP1610_GPIO_IRQSTATUS1;
-#endif
-#ifdef CONFIG_ARCH_OMAP730
-	if (bank->method == METHOD_GPIO_730)
-		isr_reg = bank->base + OMAP730_GPIO_INT_STATUS;
-#endif
-
-	isr = __raw_readl(isr_reg);
-	_enable_gpio_irqbank(bank, isr, 0);
-	_clear_gpio_irqbank(bank, isr);
-	_enable_gpio_irqbank(bank, isr, 1);
-	desc->chip->unmask(irq);
-
-	if (unlikely(!isr))
-		return;
-
-	gpio_irq = bank->virtual_irq_start;
-	for (; isr != 0; isr >>= 1, gpio_irq++) {
-		struct irqdesc *d;
-		if (!(isr & 1))
-			continue;
-		d = irq_desc + gpio_irq;
-		d->handle(gpio_irq, d, regs);
-	}
-}
-
-static void gpio_ack_irq(unsigned int irq)
-{
-	unsigned int gpio = irq - IH_GPIO_BASE;
-	struct gpio_bank *bank = get_gpio_bank(gpio);
-
-	_clear_gpio_irqstatus(bank, gpio);
-}
-
-static void gpio_mask_irq(unsigned int irq)
-{
-	unsigned int gpio = irq - IH_GPIO_BASE;
-	struct gpio_bank *bank = get_gpio_bank(gpio);
-
-	_set_gpio_irqenable(bank, gpio, 0);
-}
-
-static void gpio_unmask_irq(unsigned int irq)
-{
-	unsigned int gpio = irq - IH_GPIO_BASE;
-	struct gpio_bank *bank = get_gpio_bank(gpio);
-
-	if (_get_gpio_edge_ctrl(bank, get_gpio_index(gpio)) == OMAP_GPIO_NO_EDGE) {
-		printk(KERN_ERR "OMAP GPIO %d: trying to enable GPIO IRQ while no edge is set\n",
-		       gpio);
-		_set_gpio_edge_ctrl(bank, get_gpio_index(gpio), OMAP_GPIO_RISING_EDGE);
-	}
-	_set_gpio_irqenable(bank, gpio, 1);
-}
-
-static void mpuio_ack_irq(unsigned int irq)
-{
-	/* The ISR is reset automatically, so do nothing here. */
-}
-
-static void mpuio_mask_irq(unsigned int irq)
-{
-	unsigned int gpio = OMAP_MPUIO(irq - IH_MPUIO_BASE);
-	struct gpio_bank *bank = get_gpio_bank(gpio);
-
-	_set_gpio_irqenable(bank, gpio, 0);
-}
-
-static void mpuio_unmask_irq(unsigned int irq)
-{
-	unsigned int gpio = OMAP_MPUIO(irq - IH_MPUIO_BASE);
-	struct gpio_bank *bank = get_gpio_bank(gpio);
-
-	_set_gpio_irqenable(bank, gpio, 1);
-}
-
-static struct irqchip gpio_irq_chip = {
-	.ack	= gpio_ack_irq,
-	.mask	= gpio_mask_irq,
-	.unmask = gpio_unmask_irq,
-};
-
-static struct irqchip mpuio_irq_chip = {
-	.ack	= mpuio_ack_irq,
-	.mask	= mpuio_mask_irq,
-	.unmask = mpuio_unmask_irq
-};
-
-static int initialized = 0;
-
-static int __init _omap_gpio_init(void)
-{
-	int i;
-	struct gpio_bank *bank;
-
-	initialized = 1;
-
-#ifdef CONFIG_ARCH_OMAP1510
-	if (cpu_is_omap1510()) {
-		printk(KERN_INFO "OMAP1510 GPIO hardware\n");
-		gpio_bank_count = 2;
-		gpio_bank = gpio_bank_1510;
-	}
-#endif
-#if defined(CONFIG_ARCH_OMAP16XX)
-	if (cpu_is_omap16xx()) {
-		int rev;
-
-		gpio_bank_count = 5;
-		gpio_bank = gpio_bank_1610;
-		rev = omap_readw(gpio_bank[1].base + OMAP1610_GPIO_REVISION);
-		printk(KERN_INFO "OMAP GPIO hardware version %d.%d\n",
-		       (rev >> 4) & 0x0f, rev & 0x0f);
-	}
-#endif
-#ifdef CONFIG_ARCH_OMAP730
-	if (cpu_is_omap730()) {
-		printk(KERN_INFO "OMAP730 GPIO hardware\n");
-		gpio_bank_count = 7;
-		gpio_bank = gpio_bank_730;
-	}
-#endif
-	for (i = 0; i < gpio_bank_count; i++) {
-		int j, gpio_count = 16;
-
-		bank = &gpio_bank[i];
-		bank->reserved_map = 0;
-		bank->base = IO_ADDRESS(bank->base);
-		spin_lock_init(&bank->lock);
-		if (bank->method == METHOD_MPUIO) {
-			omap_writew(0xFFFF, OMAP_MPUIO_BASE + OMAP_MPUIO_GPIO_MASKIT);
-		}
-#ifdef CONFIG_ARCH_OMAP1510
-		if (bank->method == METHOD_GPIO_1510) {
-			__raw_writew(0xffff, bank->base + OMAP1510_GPIO_INT_MASK);
-			__raw_writew(0x0000, bank->base + OMAP1510_GPIO_INT_STATUS);
-		}
-#endif
-#if defined(CONFIG_ARCH_OMAP16XX)
-		if (bank->method == METHOD_GPIO_1610) {
-			__raw_writew(0x0000, bank->base + OMAP1610_GPIO_IRQENABLE1);
-			__raw_writew(0xffff, bank->base + OMAP1610_GPIO_IRQSTATUS1);
-		}
-#endif
-#ifdef CONFIG_ARCH_OMAP730
-		if (bank->method == METHOD_GPIO_730) {
-			__raw_writel(0xffffffff, bank->base + OMAP730_GPIO_INT_MASK);
-			__raw_writel(0x00000000, bank->base + OMAP730_GPIO_INT_STATUS);
-
-			gpio_count = 32; /* 730 has 32-bit GPIOs */
-		}
-#endif
-		for (j = bank->virtual_irq_start;
-		     j < bank->virtual_irq_start + gpio_count; j++) {
-			if (bank->method == METHOD_MPUIO)
-				set_irq_chip(j, &mpuio_irq_chip);
-			else
-				set_irq_chip(j, &gpio_irq_chip);
-			set_irq_handler(j, do_simple_IRQ);
-			set_irq_flags(j, IRQF_VALID);
-		}
-		set_irq_chained_handler(bank->irq, gpio_irq_handler);
-		set_irq_data(bank->irq, bank);
-	}
-
-	/* Enable system clock for GPIO module.
-	 * The CAM_CLK_CTRL *is* really the right place. */
-	if (cpu_is_omap1610() || cpu_is_omap1710())
-		omap_writel(omap_readl(ULPD_CAM_CLK_CTRL) | 0x04, ULPD_CAM_CLK_CTRL);
-
-	return 0;
-}
-
-/*
- * This may get called early from board specific init
- */
-int omap_gpio_init(void)
-{
-	if (!initialized)
-		return _omap_gpio_init();
-	else
-		return 0;
-}
-
-EXPORT_SYMBOL(omap_request_gpio);
-EXPORT_SYMBOL(omap_free_gpio);
-EXPORT_SYMBOL(omap_set_gpio_direction);
-EXPORT_SYMBOL(omap_set_gpio_dataout);
-EXPORT_SYMBOL(omap_get_gpio_datain);
-EXPORT_SYMBOL(omap_set_gpio_edge_ctrl);
-
-arch_initcall(omap_gpio_init);
diff --git a/arch/arm/mach-omap/irq.c b/arch/arm/mach-omap/irq.c
deleted file mode 100644
--- a/arch/arm/mach-omap/irq.c
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * linux/arch/arm/mach-omap/irq.c
- *
- * Interrupt handler for all OMAP boards
- *
- * Copyright (C) 2004 Nokia Corporation
- * Written by Tony Lindgren <tony@atomide.com>
- * Major cleanups by Juha Yrjölä <juha.yrjola@nokia.com>
- *
- * Completely re-written to support various OMAP chips with bank specific
- * interrupt handlers.
- *
- * Some snippets of the code taken from the older OMAP interrupt handler
- * Copyright (C) 2001 RidgeRun, Inc. Greg Lonnon <glonnon@ridgerun.com>
- *
- * GPIO interrupt handler moved to gpio.c by Juha Yrjola
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
- * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * You should have received a copy of the  GNU General Public License along
- * with this program; if not, write  to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/ptrace.h>
-
-#include <asm/hardware.h>
-#include <asm/irq.h>
-#include <asm/mach/irq.h>
-#include <asm/arch/gpio.h>
-
-#include <asm/io.h>
-
-#define IRQ_BANK(irq) ((irq) >> 5)
-#define IRQ_BIT(irq)  ((irq) & 0x1f)
-
-struct omap_irq_bank {
-	unsigned long base_reg;
-	unsigned long trigger_map;
-};
-
-static unsigned int irq_bank_count = 0;
-static struct omap_irq_bank *irq_banks;
-
-static inline unsigned int irq_bank_readl(int bank, int offset)
-{
-	return omap_readl(irq_banks[bank].base_reg + offset);
-}
-
-static inline void irq_bank_writel(unsigned long value, int bank, int offset)
-{
-	omap_writel(value, irq_banks[bank].base_reg + offset);
-}
-
-static void omap_ack_irq(unsigned int irq)
-{
-	if (irq > 31)
-		omap_writel(0x1, OMAP_IH2_BASE + IRQ_CONTROL_REG_OFFSET);
-
-	omap_writel(0x1, OMAP_IH1_BASE + IRQ_CONTROL_REG_OFFSET);
-}
-
-static void omap_mask_irq(unsigned int irq)
-{
-	int bank = IRQ_BANK(irq);
-	u32 l;
-
-	l = omap_readl(irq_banks[bank].base_reg + IRQ_MIR_REG_OFFSET);
-	l |= 1 << IRQ_BIT(irq);
-	omap_writel(l, irq_banks[bank].base_reg + IRQ_MIR_REG_OFFSET);
-}
-
-static void omap_unmask_irq(unsigned int irq)
-{
-	int bank = IRQ_BANK(irq);
-	u32 l;
-
-	l = omap_readl(irq_banks[bank].base_reg + IRQ_MIR_REG_OFFSET);
-	l &= ~(1 << IRQ_BIT(irq));
-	omap_writel(l, irq_banks[bank].base_reg + IRQ_MIR_REG_OFFSET);
-}
-
-static void omap_mask_ack_irq(unsigned int irq)
-{
-	omap_mask_irq(irq);
-	omap_ack_irq(irq);
-}
-
-/*
- * Allows tuning the IRQ type and priority
- *
- * NOTE: There is currently no OMAP fiq handler for Linux. Read the
- *	 mailing list threads on FIQ handlers if you are planning to
- *	 add a FIQ handler for OMAP.
- */
-static void omap_irq_set_cfg(int irq, int fiq, int priority, int trigger)
-{
-	signed int bank;
-	unsigned long val, offset;
-
-	bank = IRQ_BANK(irq);
-	/* FIQ is only available on bank 0 interrupts */
-	fiq = bank ? 0 : (fiq & 0x1);
-	val = fiq | ((priority & 0x1f) << 2) | ((trigger & 0x1) << 1);
-	offset = IRQ_ILR0_REG_OFFSET + IRQ_BIT(irq) * 0x4;
-	irq_bank_writel(val, bank, offset);
-}
-
-#ifdef CONFIG_ARCH_OMAP730
-static struct omap_irq_bank omap730_irq_banks[] = {
-	{ .base_reg = OMAP_IH1_BASE, 		.trigger_map = 0xb3f8e22f },
-	{ .base_reg = OMAP_IH2_BASE, 		.trigger_map = 0xfdb9c1f2 },
-	{ .base_reg = OMAP_IH2_BASE + 0x100,	.trigger_map = 0x800040f3 },
-};
-#endif
-
-#ifdef CONFIG_ARCH_OMAP1510
-static struct omap_irq_bank omap1510_irq_banks[] = {
-	{ .base_reg = OMAP_IH1_BASE, 		.trigger_map = 0xb3febfff },
-	{ .base_reg = OMAP_IH2_BASE, 		.trigger_map = 0xffbfffed },
-};
-#endif
-
-#if defined(CONFIG_ARCH_OMAP16XX)
-
-static struct omap_irq_bank omap1610_irq_banks[] = {
-	{ .base_reg = OMAP_IH1_BASE, 		.trigger_map = 0xb3fefe8f },
-	{ .base_reg = OMAP_IH2_BASE, 		.trigger_map = 0xfdb7c1fd },
-	{ .base_reg = OMAP_IH2_BASE + 0x100,	.trigger_map = 0xfffff7ff },
-	{ .base_reg = OMAP_IH2_BASE + 0x200,	.trigger_map = 0xffffffff },
-};
-#endif
-
-static struct irqchip omap_irq_chip = {
-	.ack    = omap_mask_ack_irq,
-	.mask   = omap_mask_irq,
-	.unmask = omap_unmask_irq,
-};
-
-void __init omap_init_irq(void)
-{
-	int i, j;
-
-#ifdef CONFIG_ARCH_OMAP730
-	if (cpu_is_omap730()) {
-		irq_banks = omap730_irq_banks;
-		irq_bank_count = ARRAY_SIZE(omap730_irq_banks);
-	}
-#endif
-#ifdef CONFIG_ARCH_OMAP1510
-	if (cpu_is_omap1510()) {
-		irq_banks = omap1510_irq_banks;
-		irq_bank_count = ARRAY_SIZE(omap1510_irq_banks);
-	}
-#endif
-#if defined(CONFIG_ARCH_OMAP16XX)
-	if (cpu_is_omap16xx()) {
-		irq_banks = omap1610_irq_banks;
-		irq_bank_count = ARRAY_SIZE(omap1610_irq_banks);
-	}
-#endif
-	printk("Total of %i interrupts in %i interrupt banks\n",
-	       irq_bank_count * 32, irq_bank_count);
-
-	/* Mask and clear all interrupts */
-	for (i = 0; i < irq_bank_count; i++) {
-		irq_bank_writel(~0x0, i, IRQ_MIR_REG_OFFSET);
-		irq_bank_writel(0x0, i, IRQ_ITR_REG_OFFSET);
-	}
-
-	/* Clear any pending interrupts */
-	irq_bank_writel(0x03, 0, IRQ_CONTROL_REG_OFFSET);
-	irq_bank_writel(0x03, 1, IRQ_CONTROL_REG_OFFSET);
-
-	/* Enable interrupts in global mask */
-	if (cpu_is_omap730()) {
-		irq_bank_writel(0x0, 0, IRQ_GMR_REG_OFFSET);
-	}
-
-	/* Install the interrupt handlers for each bank */
-	for (i = 0; i < irq_bank_count; i++) {
-		for (j = i * 32; j < (i + 1) * 32; j++) {
-			int irq_trigger;
-
-			irq_trigger = irq_banks[i].trigger_map >> IRQ_BIT(j);
-			omap_irq_set_cfg(j, 0, 0, irq_trigger);
-
-			set_irq_chip(j, &omap_irq_chip);
-			set_irq_handler(j, do_level_IRQ);
-			set_irq_flags(j, IRQF_VALID);
-		}
-	}
-
-	/* Unmask level 2 handler */
-	if (cpu_is_omap730()) {
-		omap_unmask_irq(INT_730_IH2_IRQ);
-	} else {
-		omap_unmask_irq(INT_IH2_IRQ);
-	}
-}
diff --git a/arch/arm/mach-omap/leds-h2p2-debug.c b/arch/arm/mach-omap/leds-h2p2-debug.c
deleted file mode 100644
--- a/arch/arm/mach-omap/leds-h2p2-debug.c
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * linux/arch/arm/mach-omap/leds-h2p2-debug.c
- *
- * Copyright 2003 by Texas Instruments Incorporated
- *
- * There are 16 LEDs on the debug board (all green); four may be used
- * for logical 'green', 'amber', 'red', and 'blue' (after "claiming").
- *
- * The "surfer" expansion board and H2 sample board also have two-color
- * green+red LEDs (in parallel), used here for timer and idle indicators.
- */
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/kernel_stat.h>
-#include <linux/sched.h>
-#include <linux/version.h>
-
-#include <asm/io.h>
-#include <asm/hardware.h>
-#include <asm/leds.h>
-#include <asm/system.h>
-
-#include <asm/arch/fpga.h>
-#include <asm/arch/gpio.h>
-
-#include "leds.h"
-
-
-#define GPIO_LED_RED		3
-#define GPIO_LED_GREEN		OMAP_MPUIO(4)
-
-
-#define LED_STATE_ENABLED	0x01
-#define LED_STATE_CLAIMED	0x02
-#define LED_TIMER_ON		0x04
-
-#define GPIO_IDLE		GPIO_LED_GREEN
-#define GPIO_TIMER		GPIO_LED_RED
-
-
-void h2p2_dbg_leds_event(led_event_t evt)
-{
-	unsigned long flags;
-
-	static struct h2p2_dbg_fpga __iomem *fpga;
-	static u16 led_state, hw_led_state;
-
-	local_irq_save(flags);
-
-	if (!(led_state & LED_STATE_ENABLED) && evt != led_start)
-		goto done;
-
-	switch (evt) {
-	case led_start:
-		if (!fpga)
-			fpga = ioremap(H2P2_DBG_FPGA_START,
-						H2P2_DBG_FPGA_SIZE);
-		if (fpga) {
-			led_state |= LED_STATE_ENABLED;
-			__raw_writew(~0, &fpga->leds);
-		}
-		break;
-
-	case led_stop:
-	case led_halted:
-		/* all leds off during suspend or shutdown */
-		omap_set_gpio_dataout(GPIO_TIMER, 0);
-		omap_set_gpio_dataout(GPIO_IDLE, 0);
-		__raw_writew(~0, &fpga->leds);
-		led_state &= ~LED_STATE_ENABLED;
-		if (evt == led_halted) {
-			iounmap(fpga);
-			fpga = NULL;
-		}
-		goto done;
-
-	case led_claim:
-		led_state |= LED_STATE_CLAIMED;
-		hw_led_state = 0;
-		break;
-
-	case led_release:
-		led_state &= ~LED_STATE_CLAIMED;
-		break;
-
-#ifdef CONFIG_LEDS_TIMER
-	case led_timer:
-		led_state ^= LED_TIMER_ON;
-		omap_set_gpio_dataout(GPIO_TIMER, led_state & LED_TIMER_ON);
-		goto done;
-#endif
-
-#ifdef CONFIG_LEDS_CPU
-	case led_idle_start:
-		omap_set_gpio_dataout(GPIO_IDLE, 1);
-		goto done;
-
-	case led_idle_end:
-		omap_set_gpio_dataout(GPIO_IDLE, 0);
-		goto done;
-#endif
-
-	case led_green_on:
-		hw_led_state |= H2P2_DBG_FPGA_LED_GREEN;
-		break;
-	case led_green_off:
-		hw_led_state &= ~H2P2_DBG_FPGA_LED_GREEN;
-		break;
-
-	case led_amber_on:
-		hw_led_state |= H2P2_DBG_FPGA_LED_AMBER;
-		break;
-	case led_amber_off:
-		hw_led_state &= ~H2P2_DBG_FPGA_LED_AMBER;
-		break;
-
-	case led_red_on:
-		hw_led_state |= H2P2_DBG_FPGA_LED_RED;
-		break;
-	case led_red_off:
-		hw_led_state &= ~H2P2_DBG_FPGA_LED_RED;
-		break;
-
-	case led_blue_on:
-		hw_led_state |= H2P2_DBG_FPGA_LED_BLUE;
-		break;
-	case led_blue_off:
-		hw_led_state &= ~H2P2_DBG_FPGA_LED_BLUE;
-		break;
-
-	default:
-		break;
-	}
-
-
-	/*
-	 *  Actually burn the LEDs
-	 */
-	if (led_state & LED_STATE_CLAIMED)
-		__raw_writew(~hw_led_state, &fpga->leds);
-
-done:
-	local_irq_restore(flags);
-}
diff --git a/arch/arm/mach-omap/leds-innovator.c b/arch/arm/mach-omap/leds-innovator.c
deleted file mode 100644
--- a/arch/arm/mach-omap/leds-innovator.c
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * linux/arch/arm/mach-omap/leds-innovator.c
- */
-#include <linux/config.h>
-#include <linux/init.h>
-
-#include <asm/hardware.h>
-#include <asm/leds.h>
-#include <asm/system.h>
-
-#include "leds.h"
-
-
-#define LED_STATE_ENABLED	1
-#define LED_STATE_CLAIMED	2
-
-static unsigned int led_state;
-static unsigned int hw_led_state;
-
-void innovator_leds_event(led_event_t evt)
-{
-	unsigned long flags;
-
-	local_irq_save(flags);
-
-	switch (evt) {
-	case led_start:
-		hw_led_state = 0;
-		led_state = LED_STATE_ENABLED;
-		break;
-
-	case led_stop:
-		led_state &= ~LED_STATE_ENABLED;
-		hw_led_state = 0;
-		break;
-
-	case led_claim:
-		led_state |= LED_STATE_CLAIMED;
-		hw_led_state = 0;
-		break;
-
-	case led_release:
-		led_state &= ~LED_STATE_CLAIMED;
-		hw_led_state = 0;
-		break;
-
-#ifdef CONFIG_LEDS_TIMER
-	case led_timer:
-		if (!(led_state & LED_STATE_CLAIMED))
-			hw_led_state ^= 0;
-		break;
-#endif
-
-#ifdef CONFIG_LEDS_CPU
-	case led_idle_start:
-		if (!(led_state & LED_STATE_CLAIMED))
-			hw_led_state |= 0;
-		break;
-
-	case led_idle_end:
-		if (!(led_state & LED_STATE_CLAIMED))
-			hw_led_state &= ~0;
-		break;
-#endif
-
-	case led_halted:
-		break;
-
-	case led_green_on:
-		if (led_state & LED_STATE_CLAIMED)
-			hw_led_state &= ~0;
-		break;
-
-	case led_green_off:
-		if (led_state & LED_STATE_CLAIMED)
-			hw_led_state |= 0;
-		break;
-
-	case led_amber_on:
-		break;
-
-	case led_amber_off:
-		break;
-
-	case led_red_on:
-		if (led_state & LED_STATE_CLAIMED)
-			hw_led_state &= ~0;
-		break;
-
-	case led_red_off:
-		if (led_state & LED_STATE_CLAIMED)
-			hw_led_state |= 0;
-		break;
-
-	default:
-		break;
-	}
-
-	if (led_state & LED_STATE_ENABLED)
-		;
-
-	local_irq_restore(flags);
-}
diff --git a/arch/arm/mach-omap/leds-osk.c b/arch/arm/mach-omap/leds-osk.c
deleted file mode 100644
--- a/arch/arm/mach-omap/leds-osk.c
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * linux/arch/arm/mach-omap/leds-osk.c
- *
- * LED driver for OSK, and optionally Mistral QVGA, boards
- */
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/workqueue.h>
-
-#include <asm/hardware.h>
-#include <asm/leds.h>
-#include <asm/system.h>
-
-#include <asm/arch/gpio.h>
-#include <asm/arch/tps65010.h>
-
-#include "leds.h"
-
-
-#define LED_STATE_ENABLED	(1 << 0)
-#define LED_STATE_CLAIMED	(1 << 1)
-static u8 led_state;
-
-#define	GREEN_LED		(1 << 0)	/* TPS65010 LED1 */
-#define	AMBER_LED		(1 << 1)	/* TPS65010 LED2 */
-#define	RED_LED			(1 << 2)	/* TPS65010 GPIO2 */
-#define	TIMER_LED		(1 << 3)	/* Mistral board */
-#define	IDLE_LED		(1 << 4)	/* Mistral board */
-static u8 hw_led_state;
-
-
-/* TPS65010 leds are changed using i2c -- from a task context.
- * Using one of these for the "idle" LED would be impractical...
- */
-#define	TPS_LEDS	(GREEN_LED | RED_LED | AMBER_LED)
-
-static u8 tps_leds_change;
-
-static void tps_work(void *unused)
-{
-	for (;;) {
-		u8	leds;
-
-		local_irq_disable();
-		leds = tps_leds_change;
-		tps_leds_change = 0;
-		local_irq_enable();
-
-		if (!leds)
-			break;
-
-		/* careful:  the set_led() value is on/off/blink */
-		if (leds & GREEN_LED)
-			tps65010_set_led(LED1, !!(hw_led_state & GREEN_LED));
-		if (leds & AMBER_LED)
-			tps65010_set_led(LED2, !!(hw_led_state & AMBER_LED));
-
-		/* the gpio led doesn't have that issue */
-		if (leds & RED_LED)
-			tps65010_set_gpio_out_value(GPIO2,
-					!(hw_led_state & RED_LED));
-	}
-}
-
-static DECLARE_WORK(work, tps_work, NULL);
-
-#ifdef	CONFIG_FB_OMAP
-
-/* For now, all system indicators require the Mistral board, since that
- * LED can be manipulated without a task context.  This LED is either red,
- * or green, but not both; it can't give the full "disco led" effect.
- */
-
-#define GPIO_LED_RED		3
-#define GPIO_LED_GREEN		OMAP_MPUIO(4)
-
-static void mistral_setled(void)
-{
-	int	red = 0;
-	int	green = 0;
-
-	if (hw_led_state & TIMER_LED)
-		red = 1;
-	else if (hw_led_state & IDLE_LED)
-		green = 1;
-	// else both sides are disabled
-
-	omap_set_gpio_dataout(GPIO_LED_GREEN, green);
-	omap_set_gpio_dataout(GPIO_LED_RED, red);
-}
-
-#endif
-
-void osk_leds_event(led_event_t evt)
-{
-	unsigned long	flags;
-	u16		leds;
-
-	local_irq_save(flags);
-
-	if (!(led_state & LED_STATE_ENABLED) && evt != led_start)
-		goto done;
-
-	leds = hw_led_state;
-	switch (evt) {
-	case led_start:
-		led_state |= LED_STATE_ENABLED;
-		hw_led_state = 0;
-		leds = ~0;
-		break;
-
-	case led_halted:
-	case led_stop:
-		led_state &= ~LED_STATE_ENABLED;
-		hw_led_state = 0;
-		// NOTE:  work may still be pending!!
-		break;
-
-	case led_claim:
-		led_state |= LED_STATE_CLAIMED;
-		hw_led_state = 0;
-		leds = ~0;
-		break;
-
-	case led_release:
-		led_state &= ~LED_STATE_CLAIMED;
-		hw_led_state = 0;
-		break;
-
-#ifdef	CONFIG_FB_OMAP
-
-#ifdef CONFIG_LEDS_TIMER
-	case led_timer:
-		hw_led_state ^= TIMER_LED;
-		mistral_setled();
-		break;
-#endif
-
-#ifdef CONFIG_LEDS_CPU
-	case led_idle_start:
-		hw_led_state |= IDLE_LED;
-		mistral_setled();
-		break;
-
-	case led_idle_end:
-		hw_led_state &= ~IDLE_LED;
-		mistral_setled();
-		break;
-#endif
-
-#endif	/* CONFIG_FB_OMAP */
-
-	/* "green" == tps LED1 (leftmost, normally power-good)
-	 * works only with DC adapter, not on battery power!
-	 */
-	case led_green_on:
-		if (led_state & LED_STATE_CLAIMED)
-			hw_led_state |= GREEN_LED;
-		break;
-	case led_green_off:
-		if (led_state & LED_STATE_CLAIMED)
-			hw_led_state &= ~GREEN_LED;
-		break;
-
-	/* "amber" == tps LED2 (middle) */
-	case led_amber_on:
-		if (led_state & LED_STATE_CLAIMED)
-			hw_led_state |= AMBER_LED;
-		break;
-	case led_amber_off:
-		if (led_state & LED_STATE_CLAIMED)
-			hw_led_state &= ~AMBER_LED;
-		break;
-
-	/* "red" == LED on tps gpio3 (rightmost) */
-	case led_red_on:
-		if (led_state & LED_STATE_CLAIMED)
-			hw_led_state |= RED_LED;
-		break;
-	case led_red_off:
-		if (led_state & LED_STATE_CLAIMED)
-			hw_led_state &= ~RED_LED;
-		break;
-
-	default:
-		break;
-	}
-
-	leds ^= hw_led_state;
-	leds &= TPS_LEDS;
-	if (leds && (led_state & LED_STATE_CLAIMED)) {
-		tps_leds_change |= leds;
-		schedule_work(&work);
-	}
-
-done:
-	local_irq_restore(flags);
-}
diff --git a/arch/arm/mach-omap/leds.c b/arch/arm/mach-omap/leds.c
deleted file mode 100644
--- a/arch/arm/mach-omap/leds.c
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * linux/arch/arm/mach-omap/leds.c
- *
- * OMAP LEDs dispatcher
- */
-#include <linux/kernel.h>
-#include <linux/init.h>
-
-#include <asm/leds.h>
-#include <asm/mach-types.h>
-
-#include <asm/arch/gpio.h>
-#include <asm/arch/mux.h>
-
-#include "leds.h"
-
-static int __init
-omap_leds_init(void)
-{
-	if (machine_is_omap_innovator())
-		leds_event = innovator_leds_event;
-
-	else if (machine_is_omap_h2() || machine_is_omap_perseus2())
-		leds_event = h2p2_dbg_leds_event;
-
-	else if (machine_is_omap_osk())
-		leds_event = osk_leds_event;
-
-	else
-		return -1;
-
-	if (machine_is_omap_h2()
-			|| machine_is_omap_perseus2()
-			|| machine_is_omap_osk()) {
-
-		/* LED1/LED2 pins can be used as GPIO (as done here), or by
-		 * the LPG (works even in deep sleep!), to drive a bicolor
-		 * LED on the H2 sample board, and another on the H2/P2
-		 * "surfer" expansion board.
-		 *
-		 * The same pins drive a LED on the OSK Mistral board, but
-		 * that's a different kind of LED (just one color at a time).
-		 */
-		omap_cfg_reg(P18_1610_GPIO3);
-		if (omap_request_gpio(3) == 0)
-			omap_set_gpio_direction(3, 0);
-		else
-			printk(KERN_WARNING "LED: can't get GPIO3/red?\n");
-
-		omap_cfg_reg(MPUIO4);
-		if (omap_request_gpio(OMAP_MPUIO(4)) == 0)
-			omap_set_gpio_direction(OMAP_MPUIO(4), 0);
-		else
-			printk(KERN_WARNING "LED: can't get MPUIO4/green?\n");
-	}
-
-	leds_event(led_start);
-	return 0;
-}
-
-__initcall(omap_leds_init);
diff --git a/arch/arm/mach-omap/leds.h b/arch/arm/mach-omap/leds.h
deleted file mode 100644
--- a/arch/arm/mach-omap/leds.h
+++ /dev/null
@@ -1,3 +0,0 @@
-extern void innovator_leds_event(led_event_t evt);
-extern void h2p2_dbg_leds_event(led_event_t evt);
-extern void osk_leds_event(led_event_t evt);
diff --git a/arch/arm/mach-omap/mcbsp.c b/arch/arm/mach-omap/mcbsp.c
deleted file mode 100644
--- a/arch/arm/mach-omap/mcbsp.c
+++ /dev/null
@@ -1,685 +0,0 @@
-/*
- * linux/arch/arm/omap/mcbsp.c
- *
- * Copyright (C) 2004 Nokia Corporation
- * Author: Samuel Ortiz <samuel.ortiz@nokia.com>
- *
- *
- * 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.
- *
- * Multichannel mode not supported.
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/wait.h>
-#include <linux/completion.h>
-#include <linux/interrupt.h>
-#include <linux/err.h>
-
-#include <asm/delay.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-
-#include <asm/arch/dma.h>
-#include <asm/arch/mux.h>
-#include <asm/arch/irqs.h>
-#include <asm/arch/mcbsp.h>
-
-#include <asm/hardware/clock.h>
-
-#ifdef CONFIG_MCBSP_DEBUG
-#define DBG(x...)	printk(x)
-#else
-#define DBG(x...)	do { } while (0)
-#endif
-
-struct omap_mcbsp {
-	u32                          io_base;
-	u8                           id;
-	u8                           free;
-	omap_mcbsp_word_length       rx_word_length;
-	omap_mcbsp_word_length       tx_word_length;
-
-	/* IRQ based TX/RX */
-	int                          rx_irq;
-	int                          tx_irq;
-
-	/* DMA stuff */
-	u8                           dma_rx_sync;
-	short                        dma_rx_lch;
-	u8                           dma_tx_sync;
-	short                        dma_tx_lch;
-
-	/* Completion queues */
-	struct completion            tx_irq_completion;
-	struct completion            rx_irq_completion;
-	struct completion            tx_dma_completion;
-	struct completion            rx_dma_completion;
-
-	spinlock_t                   lock;
-};
-
-static struct omap_mcbsp mcbsp[OMAP_MAX_MCBSP_COUNT];
-static struct clk *mcbsp_dsp_ck = 0;
-static struct clk *mcbsp_api_ck = 0;
-
-
-static void omap_mcbsp_dump_reg(u8 id)
-{
-	DBG("**** MCBSP%d regs ****\n", mcbsp[id].id);
-	DBG("DRR2:  0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, DRR2));
-	DBG("DRR1:  0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, DRR1));
-	DBG("DXR2:  0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, DXR2));
-	DBG("DXR1:  0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, DXR1));
-	DBG("SPCR2: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, SPCR2));
-	DBG("SPCR1: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, SPCR1));
-	DBG("RCR2:  0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, RCR2));
-	DBG("RCR1:  0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, RCR1));
-	DBG("XCR2:  0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, XCR2));
-	DBG("XCR1:  0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, XCR1));
-	DBG("SRGR2: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, SRGR2));
-	DBG("SRGR1: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, SRGR1));
-	DBG("PCR0:  0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, PCR0));
-	DBG("***********************\n");
-}
-
-
-static irqreturn_t omap_mcbsp_tx_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
-{
-	struct omap_mcbsp * mcbsp_tx = (struct omap_mcbsp *)(dev_id);
-
-	DBG("TX IRQ callback : 0x%x\n", OMAP_MCBSP_READ(mcbsp_tx->io_base, SPCR2));
-
-	complete(&mcbsp_tx->tx_irq_completion);
-	return IRQ_HANDLED;
-}
-
-static irqreturn_t omap_mcbsp_rx_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
-{
-	struct omap_mcbsp * mcbsp_rx = (struct omap_mcbsp *)(dev_id);
-
-	DBG("RX IRQ callback : 0x%x\n", OMAP_MCBSP_READ(mcbsp_rx->io_base, SPCR2));
-
-	complete(&mcbsp_rx->rx_irq_completion);
-	return IRQ_HANDLED;
-}
-
-
-static void omap_mcbsp_tx_dma_callback(int lch, u16 ch_status, void *data)
-{
-	struct omap_mcbsp * mcbsp_dma_tx = (struct omap_mcbsp *)(data);
-
-	DBG("TX DMA callback : 0x%x\n", OMAP_MCBSP_READ(mcbsp_dma_tx->io_base, SPCR2));
-
-	/* We can free the channels */
-	omap_free_dma(mcbsp_dma_tx->dma_tx_lch);
-	mcbsp_dma_tx->dma_tx_lch = -1;
-
-	complete(&mcbsp_dma_tx->tx_dma_completion);
-}
-
-static void omap_mcbsp_rx_dma_callback(int lch, u16 ch_status, void *data)
-{
-	struct omap_mcbsp * mcbsp_dma_rx = (struct omap_mcbsp *)(data);
-
-	DBG("RX DMA callback : 0x%x\n", OMAP_MCBSP_READ(mcbsp_dma_rx->io_base, SPCR2));
-
-	/* We can free the channels */
-	omap_free_dma(mcbsp_dma_rx->dma_rx_lch);
-	mcbsp_dma_rx->dma_rx_lch = -1;
-
-	complete(&mcbsp_dma_rx->rx_dma_completion);
-}
-
-
-/*
- * omap_mcbsp_config simply write a config to the
- * appropriate McBSP.
- * You either call this function or set the McBSP registers
- * by yourself before calling omap_mcbsp_start().
- */
-
-void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg * config)
-{
-	u32 io_base = mcbsp[id].io_base;
-
-	DBG("OMAP-McBSP: McBSP%d  io_base: 0x%8x\n", id+1, io_base);
-
-	/* We write the given config */
-	OMAP_MCBSP_WRITE(io_base, SPCR2, config->spcr2);
-	OMAP_MCBSP_WRITE(io_base, SPCR1, config->spcr1);
-	OMAP_MCBSP_WRITE(io_base, RCR2, config->rcr2);
-	OMAP_MCBSP_WRITE(io_base, RCR1, config->rcr1);
-	OMAP_MCBSP_WRITE(io_base, XCR2, config->xcr2);
-	OMAP_MCBSP_WRITE(io_base, XCR1, config->xcr1);
-	OMAP_MCBSP_WRITE(io_base, SRGR2, config->srgr2);
-	OMAP_MCBSP_WRITE(io_base, SRGR1, config->srgr1);
-	OMAP_MCBSP_WRITE(io_base, MCR2, config->mcr2);
-	OMAP_MCBSP_WRITE(io_base, MCR1, config->mcr1);
-	OMAP_MCBSP_WRITE(io_base, PCR0, config->pcr0);
-}
-
-
-
-static int omap_mcbsp_check(unsigned int id)
-{
-	if (cpu_is_omap730()) {
-		if (id > OMAP_MAX_MCBSP_COUNT - 1) {
-		       printk(KERN_ERR "OMAP-McBSP: McBSP%d doesn't exist\n", id + 1);
-		       return -1;
-		}
-		return 0;
-	}
-
-	if (cpu_is_omap1510() || cpu_is_omap1610() || cpu_is_omap1710()) {
-		if (id > OMAP_MAX_MCBSP_COUNT) {
-			printk(KERN_ERR "OMAP-McBSP: McBSP%d doesn't exist\n", id + 1);
-			return -1;
-		}
-		return 0;
-	}
-
-	return -1;
-}
-
-#define EN_XORPCK		1
-#define DSP_RSTCT2              0xe1008014
-
-static void omap_mcbsp_dsp_request(void)
-{
-	if (cpu_is_omap1510() || cpu_is_omap1610() || cpu_is_omap1710()) {
-		omap_writew((omap_readw(ARM_RSTCT1) | (1 << 1) | (1 << 2)),
-			    ARM_RSTCT1);
-		clk_enable(mcbsp_dsp_ck);
-		clk_enable(mcbsp_api_ck);
-
-		/* enable 12MHz clock to mcbsp 1 & 3 */
-		__raw_writew(__raw_readw(DSP_IDLECT2) | (1 << EN_XORPCK),
-			     DSP_IDLECT2);
-		__raw_writew(__raw_readw(DSP_RSTCT2) | 1 | 1 << 1,
-			     DSP_RSTCT2);
-	}
-}
-
-static void omap_mcbsp_dsp_free(void)
-{
-	/* Useless for now */
-}
-
-
-int omap_mcbsp_request(unsigned int id)
-{
-	int err;
-
-	if (omap_mcbsp_check(id) < 0)
-		return -EINVAL;
-
-	/*
-	 * On 1510, 1610 and 1710, McBSP1 and McBSP3
-	 * are DSP public peripherals.
-	 */
-	if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3)
-		omap_mcbsp_dsp_request();
-
-	spin_lock(&mcbsp[id].lock);
-	if (!mcbsp[id].free) {
-		printk (KERN_ERR "OMAP-McBSP: McBSP%d is currently in use\n", id + 1);
-		spin_unlock(&mcbsp[id].lock);
-		return -1;
-	}
-
-	mcbsp[id].free = 0;
-	spin_unlock(&mcbsp[id].lock);
-
-	/* We need to get IRQs here */
-	err = request_irq(mcbsp[id].tx_irq, omap_mcbsp_tx_irq_handler, 0,
-			  "McBSP",
-			  (void *) (&mcbsp[id]));
-	if (err != 0) {
-		printk(KERN_ERR "OMAP-McBSP: Unable to request TX IRQ %d for McBSP%d\n",
-		       mcbsp[id].tx_irq, mcbsp[id].id);
-		return err;
-	}
-
-	init_completion(&(mcbsp[id].tx_irq_completion));
-
-
-	err = request_irq(mcbsp[id].rx_irq, omap_mcbsp_rx_irq_handler, 0,
-			  "McBSP",
-			  (void *) (&mcbsp[id]));
-	if (err != 0) {
-		printk(KERN_ERR "OMAP-McBSP: Unable to request RX IRQ %d for McBSP%d\n",
-		       mcbsp[id].rx_irq, mcbsp[id].id);
-		free_irq(mcbsp[id].tx_irq, (void *) (&mcbsp[id]));
-		return err;
-	}
-
-	init_completion(&(mcbsp[id].rx_irq_completion));
-	return 0;
-
-}
-
-void omap_mcbsp_free(unsigned int id)
-{
-	if (omap_mcbsp_check(id) < 0)
-		return;
-
-	if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3)
-		omap_mcbsp_dsp_free();
-
-	spin_lock(&mcbsp[id].lock);
-	if (mcbsp[id].free) {
-		printk (KERN_ERR "OMAP-McBSP: McBSP%d was not reserved\n", id + 1);
-		spin_unlock(&mcbsp[id].lock);
-		return;
-	}
-
-	mcbsp[id].free = 1;
-	spin_unlock(&mcbsp[id].lock);
-
-	/* Free IRQs */
-	free_irq(mcbsp[id].rx_irq, (void *) (&mcbsp[id]));
-	free_irq(mcbsp[id].tx_irq, (void *) (&mcbsp[id]));
-}
-
-/*
- * Here we start the McBSP, by enabling the sample
- * generator, both transmitter and receivers,
- * and the frame sync.
- */
-void omap_mcbsp_start(unsigned int id)
-{
-	u32 io_base;
-	u16 w;
-
-	if (omap_mcbsp_check(id) < 0)
-		return;
-
-	io_base = mcbsp[id].io_base;
-
-	mcbsp[id].rx_word_length = ((OMAP_MCBSP_READ(io_base, RCR1) >> 5) & 0x7);
-	mcbsp[id].tx_word_length = ((OMAP_MCBSP_READ(io_base, XCR1) >> 5) & 0x7);
-
-	/* Start the sample generator */
-	w = OMAP_MCBSP_READ(io_base, SPCR2);
-	OMAP_MCBSP_WRITE(io_base, SPCR2, w | (1 << 6));
-
-	/* Enable transmitter and receiver */
-	w = OMAP_MCBSP_READ(io_base, SPCR2);
-	OMAP_MCBSP_WRITE(io_base, SPCR2, w | 1);
-
-	w = OMAP_MCBSP_READ(io_base, SPCR1);
-	OMAP_MCBSP_WRITE(io_base, SPCR1, w | 1);
-
-	udelay(100);
-
-	/* Start frame sync */
-	w = OMAP_MCBSP_READ(io_base, SPCR2);
-	OMAP_MCBSP_WRITE(io_base, SPCR2, w | (1 << 7));
-
-	/* Dump McBSP Regs */
-	omap_mcbsp_dump_reg(id);
-
-}
-
-void omap_mcbsp_stop(unsigned int id)
-{
-	u32 io_base;
-	u16 w;
-
-	if (omap_mcbsp_check(id) < 0)
-		return;
-
-	io_base = mcbsp[id].io_base;
-
-        /* Reset transmitter */
-	w = OMAP_MCBSP_READ(io_base, SPCR2);
-	OMAP_MCBSP_WRITE(io_base, SPCR2, w & ~(1));
-
-	/* Reset receiver */
-	w = OMAP_MCBSP_READ(io_base, SPCR1);
-	OMAP_MCBSP_WRITE(io_base, SPCR1, w & ~(1));
-
-	/* Reset the sample rate generator */
-	w = OMAP_MCBSP_READ(io_base, SPCR2);
-	OMAP_MCBSP_WRITE(io_base, SPCR2, w & ~(1 << 6));
-}
-
-
-/*
- * IRQ based word transmission.
- */
-void omap_mcbsp_xmit_word(unsigned int id, u32 word)
-{
-	u32 io_base;
-	omap_mcbsp_word_length word_length = mcbsp[id].tx_word_length;
-
-	if (omap_mcbsp_check(id) < 0)
-		return;
-
-	io_base = mcbsp[id].io_base;
-
-	wait_for_completion(&(mcbsp[id].tx_irq_completion));
-
-	if (word_length > OMAP_MCBSP_WORD_16)
-		OMAP_MCBSP_WRITE(io_base, DXR2, word >> 16);
-	OMAP_MCBSP_WRITE(io_base, DXR1, word & 0xffff);
-}
-
-u32 omap_mcbsp_recv_word(unsigned int id)
-{
-	u32 io_base;
-	u16 word_lsb, word_msb = 0;
-	omap_mcbsp_word_length word_length = mcbsp[id].rx_word_length;
-
-	if (omap_mcbsp_check(id) < 0)
-		return -EINVAL;
-
-	io_base = mcbsp[id].io_base;
-
-	wait_for_completion(&(mcbsp[id].rx_irq_completion));
-
-	if (word_length > OMAP_MCBSP_WORD_16)
-		word_msb = OMAP_MCBSP_READ(io_base, DRR2);
-	word_lsb = OMAP_MCBSP_READ(io_base, DRR1);
-
-	return (word_lsb | (word_msb << 16));
-}
-
-
-/*
- * Simple DMA based buffer rx/tx routines.
- * Nothing fancy, just a single buffer tx/rx through DMA.
- * The DMA resources are released once the transfer is done.
- * For anything fancier, you should use your own customized DMA
- * routines and callbacks.
- */
-int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer, unsigned int length)
-{
-	int dma_tx_ch;
-
-	if (omap_mcbsp_check(id) < 0)
-		return -EINVAL;
-
-	if (omap_request_dma(mcbsp[id].dma_tx_sync, "McBSP TX", omap_mcbsp_tx_dma_callback,
-			     &mcbsp[id],
-			     &dma_tx_ch)) {
-		printk("OMAP-McBSP: Unable to request DMA channel for McBSP%d TX. Trying IRQ based TX\n", id+1);
-		return -EAGAIN;
-	}
-	mcbsp[id].dma_tx_lch = dma_tx_ch;
-
-	DBG("TX DMA on channel %d\n", dma_tx_ch);
-
-	init_completion(&(mcbsp[id].tx_dma_completion));
-
-	omap_set_dma_transfer_params(mcbsp[id].dma_tx_lch,
-				     OMAP_DMA_DATA_TYPE_S16,
-				     length >> 1, 1,
-				     OMAP_DMA_SYNC_ELEMENT);
-
-	omap_set_dma_dest_params(mcbsp[id].dma_tx_lch,
-				 OMAP_DMA_PORT_TIPB,
-				 OMAP_DMA_AMODE_CONSTANT,
-				 mcbsp[id].io_base + OMAP_MCBSP_REG_DXR1);
-
-	omap_set_dma_src_params(mcbsp[id].dma_tx_lch,
-				OMAP_DMA_PORT_EMIFF,
-				OMAP_DMA_AMODE_POST_INC,
-				buffer);
-
-	omap_start_dma(mcbsp[id].dma_tx_lch);
-	wait_for_completion(&(mcbsp[id].tx_dma_completion));
-	return 0;
-}
-
-
-int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer, unsigned int length)
-{
-	int dma_rx_ch;
-
-	if (omap_mcbsp_check(id) < 0)
-		return -EINVAL;
-
-	if (omap_request_dma(mcbsp[id].dma_rx_sync, "McBSP RX", omap_mcbsp_rx_dma_callback,
-			     &mcbsp[id],
-			     &dma_rx_ch)) {
-		printk("Unable to request DMA channel for McBSP%d RX. Trying IRQ based RX\n", id+1);
-		return -EAGAIN;
-	}
-	mcbsp[id].dma_rx_lch = dma_rx_ch;
-
-	DBG("RX DMA on channel %d\n", dma_rx_ch);
-
-	init_completion(&(mcbsp[id].rx_dma_completion));
-
-	omap_set_dma_transfer_params(mcbsp[id].dma_rx_lch,
-				     OMAP_DMA_DATA_TYPE_S16,
-				     length >> 1, 1,
-				     OMAP_DMA_SYNC_ELEMENT);
-
-	omap_set_dma_src_params(mcbsp[id].dma_rx_lch,
-				OMAP_DMA_PORT_TIPB,
-				OMAP_DMA_AMODE_CONSTANT,
-				mcbsp[id].io_base + OMAP_MCBSP_REG_DRR1);
-
-	omap_set_dma_dest_params(mcbsp[id].dma_rx_lch,
-				 OMAP_DMA_PORT_EMIFF,
-				 OMAP_DMA_AMODE_POST_INC,
-				 buffer);
-
-	omap_start_dma(mcbsp[id].dma_rx_lch);
-	wait_for_completion(&(mcbsp[id].rx_dma_completion));
-	return 0;
-}
-
-
-/*
- * SPI wrapper.
- * Since SPI setup is much simpler than the generic McBSP one,
- * this wrapper just need an omap_mcbsp_spi_cfg structure as an input.
- * Once this is done, you can call omap_mcbsp_start().
- */
-void omap_mcbsp_set_spi_mode(unsigned int id, const struct omap_mcbsp_spi_cfg * spi_cfg)
-{
-	struct omap_mcbsp_reg_cfg mcbsp_cfg;
-
-	if (omap_mcbsp_check(id) < 0)
-		return;
-
-	memset(&mcbsp_cfg, 0, sizeof(struct omap_mcbsp_reg_cfg));
-
-	/* SPI has only one frame */
-	mcbsp_cfg.rcr1 |= (RWDLEN1(spi_cfg->word_length) | RFRLEN1(0));
-	mcbsp_cfg.xcr1 |= (XWDLEN1(spi_cfg->word_length) | XFRLEN1(0));
-
-        /* Clock stop mode */
-	if (spi_cfg->clk_stp_mode == OMAP_MCBSP_CLK_STP_MODE_NO_DELAY)
-		mcbsp_cfg.spcr1 |= (1 << 12);
-	else
-		mcbsp_cfg.spcr1 |= (3 << 11);
-
-	/* Set clock parities */
-	if (spi_cfg->rx_clock_polarity == OMAP_MCBSP_CLK_RISING)
-		mcbsp_cfg.pcr0 |= CLKRP;
-	else
-		mcbsp_cfg.pcr0 &= ~CLKRP;
-
-	if (spi_cfg->tx_clock_polarity == OMAP_MCBSP_CLK_RISING)
-		mcbsp_cfg.pcr0 &= ~CLKXP;
-	else
-		mcbsp_cfg.pcr0 |= CLKXP;
-
-	/* Set SCLKME to 0 and CLKSM to 1 */
-	mcbsp_cfg.pcr0 &= ~SCLKME;
-	mcbsp_cfg.srgr2 |= CLKSM;
-
-	/* Set FSXP */
-	if (spi_cfg->fsx_polarity == OMAP_MCBSP_FS_ACTIVE_HIGH)
-		mcbsp_cfg.pcr0 &= ~FSXP;
-	else
-		mcbsp_cfg.pcr0 |= FSXP;
-
-	if (spi_cfg->spi_mode == OMAP_MCBSP_SPI_MASTER) {
-		mcbsp_cfg.pcr0 |= CLKXM;
-		mcbsp_cfg.srgr1 |= CLKGDV(spi_cfg->clk_div -1);
-		mcbsp_cfg.pcr0 |= FSXM;
-		mcbsp_cfg.srgr2 &= ~FSGM;
-		mcbsp_cfg.xcr2 |= XDATDLY(1);
-		mcbsp_cfg.rcr2 |= RDATDLY(1);
-	}
-	else {
-		mcbsp_cfg.pcr0 &= ~CLKXM;
-		mcbsp_cfg.srgr1 |= CLKGDV(1);
-		mcbsp_cfg.pcr0 &= ~FSXM;
-		mcbsp_cfg.xcr2 &= ~XDATDLY(3);
-		mcbsp_cfg.rcr2 &= ~RDATDLY(3);
-	}
-
-	mcbsp_cfg.xcr2 &= ~XPHASE;
-	mcbsp_cfg.rcr2 &= ~RPHASE;
-
-	omap_mcbsp_config(id, &mcbsp_cfg);
-}
-
-
-/*
- * McBSP1 and McBSP3 are directly mapped on 1610 and 1510.
- * 730 has only 2 McBSP, and both of them are MPU peripherals.
- */
-struct omap_mcbsp_info {
-	u32 virt_base;
-	u8 dma_rx_sync, dma_tx_sync;
-	u16 rx_irq, tx_irq;
-};
-
-#ifdef CONFIG_ARCH_OMAP730
-static const struct omap_mcbsp_info mcbsp_730[] = {
-	[0] = { .virt_base = io_p2v(OMAP730_MCBSP1_BASE),
-		.dma_rx_sync = OMAP_DMA_MCBSP1_RX,
-		.dma_tx_sync = OMAP_DMA_MCBSP1_TX,
-		.rx_irq = INT_730_McBSP1RX,
-		.tx_irq = INT_730_McBSP1TX },
-	[1] = { .virt_base = io_p2v(OMAP730_MCBSP2_BASE),
-		.dma_rx_sync = OMAP_DMA_MCBSP3_RX,
-		.dma_tx_sync = OMAP_DMA_MCBSP3_TX,
-		.rx_irq = INT_730_McBSP2RX,
-		.tx_irq = INT_730_McBSP2TX },
-};
-#endif
-
-#ifdef CONFIG_ARCH_OMAP1510
-static const struct omap_mcbsp_info mcbsp_1510[] = {
-	[0] = { .virt_base = OMAP1510_MCBSP1_BASE,
-		.dma_rx_sync = OMAP_DMA_MCBSP1_RX,
-		.dma_tx_sync = OMAP_DMA_MCBSP1_TX,
-		.rx_irq = INT_McBSP1RX,
-		.tx_irq = INT_McBSP1TX },
-	[1] = { .virt_base = io_p2v(OMAP1510_MCBSP2_BASE),
-		.dma_rx_sync = OMAP_DMA_MCBSP2_RX,
-		.dma_tx_sync = OMAP_DMA_MCBSP2_TX,
-		.rx_irq = INT_1510_SPI_RX,
-		.tx_irq = INT_1510_SPI_TX },
-	[2] = { .virt_base = OMAP1510_MCBSP3_BASE,
-		.dma_rx_sync = OMAP_DMA_MCBSP3_RX,
-		.dma_tx_sync = OMAP_DMA_MCBSP3_TX,
-		.rx_irq = INT_McBSP3RX,
-		.tx_irq = INT_McBSP3TX },
-};
-#endif
-
-#if defined(CONFIG_ARCH_OMAP16XX)
-static const struct omap_mcbsp_info mcbsp_1610[] = {
-	[0] = { .virt_base = OMAP1610_MCBSP1_BASE,
-		.dma_rx_sync = OMAP_DMA_MCBSP1_RX,
-		.dma_tx_sync = OMAP_DMA_MCBSP1_TX,
-		.rx_irq = INT_McBSP1RX,
-		.tx_irq = INT_McBSP1TX },
-	[1] = { .virt_base = io_p2v(OMAP1610_MCBSP2_BASE),
-		.dma_rx_sync = OMAP_DMA_MCBSP2_RX,
-		.dma_tx_sync = OMAP_DMA_MCBSP2_TX,
-		.rx_irq = INT_1610_McBSP2_RX,
-		.tx_irq = INT_1610_McBSP2_TX },
-	[2] = { .virt_base = OMAP1610_MCBSP3_BASE,
-		.dma_rx_sync = OMAP_DMA_MCBSP3_RX,
-		.dma_tx_sync = OMAP_DMA_MCBSP3_TX,
-		.rx_irq = INT_McBSP3RX,
-		.tx_irq = INT_McBSP3TX },
-};
-#endif
-
-static int __init omap_mcbsp_init(void)
-{
-	int mcbsp_count = 0, i;
-	static const struct omap_mcbsp_info *mcbsp_info;
-
-	printk("Initializing OMAP McBSP system\n");
-
-	mcbsp_dsp_ck = clk_get(0, "dsp_ck");
-	if (IS_ERR(mcbsp_dsp_ck)) {
-		printk(KERN_ERR "mcbsp: could not acquire dsp_ck handle.\n");
-		return PTR_ERR(mcbsp_dsp_ck);
-	}
-	mcbsp_api_ck = clk_get(0, "api_ck");
-	if (IS_ERR(mcbsp_dsp_ck)) {
-		printk(KERN_ERR "mcbsp: could not acquire api_ck handle.\n");
-		return PTR_ERR(mcbsp_api_ck);
-	}
-
-#ifdef CONFIG_ARCH_OMAP730
-	if (cpu_is_omap730()) {
-		mcbsp_info = mcbsp_730;
-		mcbsp_count = ARRAY_SIZE(mcbsp_730);
-	}
-#endif
-#ifdef CONFIG_ARCH_OMAP1510
-	if (cpu_is_omap1510()) {
-		mcbsp_info = mcbsp_1510;
-		mcbsp_count = ARRAY_SIZE(mcbsp_1510);
-	}
-#endif
-#if defined(CONFIG_ARCH_OMAP16XX)
-	if (cpu_is_omap1610() || cpu_is_omap1710()) {
-		mcbsp_info = mcbsp_1610;
-		mcbsp_count = ARRAY_SIZE(mcbsp_1610);
-	}
-#endif
-	for (i = 0; i < OMAP_MAX_MCBSP_COUNT ; i++) {
-		if (i >= mcbsp_count) {
-			mcbsp[i].io_base = 0;
-			mcbsp[i].free = 0;
-                        continue;
-		}
-		mcbsp[i].id = i + 1;
-		mcbsp[i].free = 1;
-		mcbsp[i].dma_tx_lch = -1;
-		mcbsp[i].dma_rx_lch = -1;
-
-		mcbsp[i].io_base = mcbsp_info[i].virt_base;
-		mcbsp[i].tx_irq = mcbsp_info[i].tx_irq;
-		mcbsp[i].rx_irq = mcbsp_info[i].rx_irq;
-		mcbsp[i].dma_rx_sync = mcbsp_info[i].dma_rx_sync;
-		mcbsp[i].dma_tx_sync = mcbsp_info[i].dma_tx_sync;
-		spin_lock_init(&mcbsp[i].lock);
-	}
-
-	return 0;
-}
-
-
-arch_initcall(omap_mcbsp_init);
-
-EXPORT_SYMBOL(omap_mcbsp_config);
-EXPORT_SYMBOL(omap_mcbsp_request);
-EXPORT_SYMBOL(omap_mcbsp_free);
-EXPORT_SYMBOL(omap_mcbsp_start);
-EXPORT_SYMBOL(omap_mcbsp_stop);
-EXPORT_SYMBOL(omap_mcbsp_xmit_word);
-EXPORT_SYMBOL(omap_mcbsp_recv_word);
-EXPORT_SYMBOL(omap_mcbsp_xmit_buffer);
-EXPORT_SYMBOL(omap_mcbsp_recv_buffer);
-EXPORT_SYMBOL(omap_mcbsp_set_spi_mode);
diff --git a/arch/arm/mach-omap/mux.c b/arch/arm/mach-omap/mux.c
deleted file mode 100644
--- a/arch/arm/mach-omap/mux.c
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * linux/arch/arm/mach-omap/mux.c
- *
- * Utility to set the Omap MUX and PULL_DWN registers from a table in mux.h
- *
- * Copyright (C) 2003 Nokia Corporation
- *
- * Written by Tony Lindgren <tony.lindgren@nokia.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/config.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <asm/system.h>
-#include <asm/io.h>
-#include <linux/spinlock.h>
-
-#define __MUX_C__
-#include <asm/arch/mux.h>
-
-#ifdef CONFIG_OMAP_MUX
-
-/*
- * Sets the Omap MUX and PULL_DWN registers based on the table
- */
-int __init_or_module
-omap_cfg_reg(const reg_cfg_t reg_cfg)
-{
-	static DEFINE_SPINLOCK(mux_spin_lock);
-
-	unsigned long flags;
-	reg_cfg_set *cfg;
-	unsigned int reg_orig = 0, reg = 0, pu_pd_orig = 0, pu_pd = 0,
-		pull_orig = 0, pull = 0;
-	unsigned int mask, warn = 0;
-
-	if (reg_cfg > ARRAY_SIZE(reg_cfg_table)) {
-		printk(KERN_ERR "MUX: reg_cfg %d\n", reg_cfg);
-		return -EINVAL;
-	}
-
-	cfg = &reg_cfg_table[reg_cfg];
-
-	/*
-	 * We do a pretty long section here with lock on, but pin muxing
-	 * should only happen on driver init for each driver, so it's not time
-	 * critical.
-	 */
-	spin_lock_irqsave(&mux_spin_lock, flags);
-
-	/* Check the mux register in question */
-	if (cfg->mux_reg) {
-		unsigned	tmp1, tmp2;
-
-		reg_orig = omap_readl(cfg->mux_reg);
-
-		/* The mux registers always seem to be 3 bits long */
-		mask = (0x7 << cfg->mask_offset);
-		tmp1 = reg_orig & mask;
-		reg = reg_orig & ~mask;
-
-		tmp2 = (cfg->mask << cfg->mask_offset);
-		reg |= tmp2;
-
-		if (tmp1 != tmp2)
-			warn = 1;
-
-		omap_writel(reg, cfg->mux_reg);
-	}
-
-	/* Check for pull up or pull down selection on 1610 */
-	if (!cpu_is_omap1510()) {
-		if (cfg->pu_pd_reg && cfg->pull_val) {
-			pu_pd_orig = omap_readl(cfg->pu_pd_reg);
-			mask = 1 << cfg->pull_bit;
-
-			if (cfg->pu_pd_val) {
-				if (!(pu_pd_orig & mask))
-					warn = 1;
-				/* Use pull up */
-				pu_pd = pu_pd_orig | mask;
-			} else {
-				if (pu_pd_orig & mask)
-					warn = 1;
-				/* Use pull down */
-				pu_pd = pu_pd_orig & ~mask;
-			}
-			omap_writel(pu_pd, cfg->pu_pd_reg);
-		}
-	}
-
-	/* Check for an associated pull down register */
-	if (cfg->pull_reg) {
-		pull_orig = omap_readl(cfg->pull_reg);
-		mask = 1 << cfg->pull_bit;
-
-		if (cfg->pull_val) {
-			if (pull_orig & mask)
-				warn = 1;
-			/* Low bit = pull enabled */
-			pull = pull_orig & ~mask;
-		} else {
-			if (!(pull_orig & mask))
-				warn = 1;
-			/* High bit = pull disabled */
-			pull = pull_orig | mask;
-		}
-
-		omap_writel(pull, cfg->pull_reg);
-	}
-
-	if (warn) {
-#ifdef CONFIG_OMAP_MUX_WARNINGS
-		printk(KERN_WARNING "MUX: initialized %s\n", cfg->name);
-#endif
-	}
-
-#ifdef CONFIG_OMAP_MUX_DEBUG
-	if (cfg->debug || warn) {
-		printk("MUX: Setting register %s\n", cfg->name);
-		printk("      %s (0x%08x) = 0x%08x -> 0x%08x\n",
-		       cfg->mux_reg_name, cfg->mux_reg, reg_orig, reg);
-
-		if (!cpu_is_omap1510()) {
-			if (cfg->pu_pd_reg && cfg->pull_val) {
-				printk("      %s (0x%08x) = 0x%08x -> 0x%08x\n",
-				       cfg->pu_pd_name, cfg->pu_pd_reg,
-				       pu_pd_orig, pu_pd);
-			}
-		}
-
-		if (cfg->pull_reg)
-			printk("      %s (0x%08x) = 0x%08x -> 0x%08x\n",
-			       cfg->pull_name, cfg->pull_reg, pull_orig, pull);
-	}
-#endif
-
-	spin_unlock_irqrestore(&mux_spin_lock, flags);
-
-#ifdef CONFIG_OMAP_MUX_ERRORS
-	return warn ? -ETXTBSY : 0;
-#else
-	return 0;
-#endif
-}
-
-EXPORT_SYMBOL(omap_cfg_reg);
-
-#endif	/* CONFIG_OMAP_MUX */
diff --git a/arch/arm/mach-omap/ocpi.c b/arch/arm/mach-omap/ocpi.c
deleted file mode 100644
--- a/arch/arm/mach-omap/ocpi.c
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * linux/arch/arm/mach-omap/ocpi.c
- *
- * Minimal OCP bus support for omap16xx
- *
- * Copyright (C) 2003 - 2005 Nokia Corporation
- * Written by Tony Lindgren <tony@atomide.com>
- *
- * Modified for clock framework by Paul Mundt <paul.mundt@nokia.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/config.h>
-#include <linux/module.h>
-#include <linux/version.h>
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/spinlock.h>
-#include <linux/err.h>
-
-#include <asm/io.h>
-#include <asm/hardware/clock.h>
-#include <asm/arch/hardware.h>
-
-#define OCPI_BASE		0xfffec320
-#define OCPI_FAULT		(OCPI_BASE + 0x00)
-#define OCPI_CMD_FAULT		(OCPI_BASE + 0x04)
-#define OCPI_SINT0		(OCPI_BASE + 0x08)
-#define OCPI_TABORT		(OCPI_BASE + 0x0c)
-#define OCPI_SINT1		(OCPI_BASE + 0x10)
-#define OCPI_PROT		(OCPI_BASE + 0x14)
-#define OCPI_SEC		(OCPI_BASE + 0x18)
-
-/* USB OHCI OCPI access error registers */
-#define HOSTUEADDR	0xfffba0e0
-#define HOSTUESTATUS	0xfffba0e4
-
-static struct clk *ocpi_ck;
-
-/*
- * Enables device access to OMAP buses via the OCPI bridge
- * FIXME: Add locking
- */
-int ocpi_enable(void)
-{
-	unsigned int val;
-
-	if (!cpu_is_omap16xx())
-		return -ENODEV;
-
-	/* Make sure there's clock for OCPI */
-	clk_enable(ocpi_ck);
-
-	/* Enable access for OHCI in OCPI */
-	val = omap_readl(OCPI_PROT);
-	val &= ~0xff;
-	//val &= (1 << 0);	/* Allow access only to EMIFS */
-	omap_writel(val, OCPI_PROT);
-
-	val = omap_readl(OCPI_SEC);
-	val &= ~0xff;
-	omap_writel(val, OCPI_SEC);
-
-	return 0;
-}
-EXPORT_SYMBOL(ocpi_enable);
-
-static int __init omap_ocpi_init(void)
-{
-	if (!cpu_is_omap16xx())
-		return -ENODEV;
-
-	ocpi_ck = clk_get(NULL, "l3_ocpi_ck");
-	if (IS_ERR(ocpi_ck))
-		return PTR_ERR(ocpi_ck);
-
-	clk_use(ocpi_ck);
-	ocpi_enable();
-	printk("OMAP OCPI interconnect driver loaded\n");
-
-	return 0;
-}
-
-static void __exit omap_ocpi_exit(void)
-{
-	/* REVISIT: Disable OCPI */
-
-	if (!cpu_is_omap16xx())
-		return;
-
-	clk_unuse(ocpi_ck);
-	clk_put(ocpi_ck);
-}
-
-MODULE_AUTHOR("Tony Lindgren <tony@atomide.com>");
-MODULE_DESCRIPTION("OMAP OCPI bus controller module");
-MODULE_LICENSE("GPL");
-module_init(omap_ocpi_init);
-module_exit(omap_ocpi_exit);
diff --git a/arch/arm/mach-omap/pm.c b/arch/arm/mach-omap/pm.c
deleted file mode 100644
--- a/arch/arm/mach-omap/pm.c
+++ /dev/null
@@ -1,628 +0,0 @@
-/*
- * linux/arch/arm/mach-omap/pm.c
- *
- * OMAP Power Management Routines
- *
- * Original code for the SA11x0:
- * Copyright (c) 2001 Cliff Brake <cbrake@accelent.com>
- *
- * Modified for the PXA250 by Nicolas Pitre:
- * Copyright (c) 2002 Monta Vista Software, Inc.
- *
- * Modified for the OMAP1510 by David Singleton:
- * Copyright (c) 2002 Monta Vista Software, Inc.
- *
- * Cleanup 2004 for OMAP1510/1610 by Dirk Behme <dirk.behme@de.bosch.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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
- * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/pm.h>
-#include <linux/sched.h>
-#include <linux/proc_fs.h>
-#include <linux/pm.h>
-
-#include <asm/io.h>
-#include <asm/mach-types.h>
-#include <asm/arch/omap16xx.h>
-#include <asm/arch/pm.h>
-#include <asm/arch/mux.h>
-#include <asm/arch/tc.h>
-#include <asm/arch/tps65010.h>
-
-#include "clock.h"
-
-static unsigned int arm_sleep_save[ARM_SLEEP_SAVE_SIZE];
-static unsigned short ulpd_sleep_save[ULPD_SLEEP_SAVE_SIZE];
-static unsigned int mpui1510_sleep_save[MPUI1510_SLEEP_SAVE_SIZE];
-static unsigned int mpui1610_sleep_save[MPUI1610_SLEEP_SAVE_SIZE];
-
-/*
- * Let's power down on idle, but only if we are really
- * idle, because once we start down the path of
- * going idle we continue to do idle even if we get
- * a clock tick interrupt . .
- */
-void omap_pm_idle(void)
-{
-	int (*func_ptr)(void) = 0;
-	unsigned int mask32 = 0;
-
-	/*
-	 * If the DSP is being used let's just idle the CPU, the overhead
-	 * to wake up from Big Sleep is big, milliseconds versus micro
-	 * seconds for wait for interrupt.
-	 */
-
-	local_irq_disable();
-	local_fiq_disable();
-	if (need_resched()) {
-		local_fiq_enable();
-		local_irq_enable();
-		return;
-	}
-	mask32 = omap_readl(ARM_SYSST);
-	local_fiq_enable();
-	local_irq_enable();
-
-#if defined(CONFIG_OMAP_32K_TIMER) && defined(CONFIG_NO_IDLE_HZ)
-	/* Override timer to use VST for the next cycle */
-	omap_32k_timer_next_vst_interrupt();
-#endif
-
-	if ((mask32 & DSP_IDLE) == 0) {
-		__asm__ volatile ("mcr	p15, 0, r0, c7, c0, 4");
-	} else {
-
-		if (cpu_is_omap1510()) {
-			func_ptr = (void *)(OMAP1510_SRAM_IDLE_SUSPEND);
-		} else if (cpu_is_omap1610() || cpu_is_omap1710()) {
-			func_ptr = (void *)(OMAP1610_SRAM_IDLE_SUSPEND);
-		} else if (cpu_is_omap5912()) {
-			func_ptr = (void *)(OMAP5912_SRAM_IDLE_SUSPEND);
-		}
-
-		func_ptr();
-	}
-}
-
-/*
- * Configuration of the wakeup event is board specific. For the
- * moment we put it into this helper function. Later it may move
- * to board specific files.
- */
-static void omap_pm_wakeup_setup(void)
-{
-	/*
-	 * Enable ARM XOR clock and release peripheral from reset by
-	 * writing 1 to PER_EN bit in ARM_RSTCT2, this is required
-	 * for UART configuration to use UART2 to wake up.
-	 */
-
-	omap_writel(omap_readl(ARM_IDLECT2) | ENABLE_XORCLK, ARM_IDLECT2);
-	omap_writel(omap_readl(ARM_RSTCT2) | PER_EN, ARM_RSTCT2);
-	omap_writew(MODEM_32K_EN, ULPD_CLOCK_CTRL);
-
-	/*
-	 * Turn off all interrupts except L1-2nd level cascade,
-	 * and the L2 wakeup interrupts: keypad and UART2.
-	 */
-
-	omap_writel(~IRQ_LEVEL2, OMAP_IH1_MIR);
-
-	if (cpu_is_omap1510()) {
-		omap_writel(~(IRQ_UART2 | IRQ_KEYBOARD),  OMAP_IH2_MIR);
-	}
-
-	if (cpu_is_omap16xx()) {
-		omap_writel(~(IRQ_UART2 | IRQ_KEYBOARD), OMAP_IH2_0_MIR);
-
-		omap_writel(~0x0, OMAP_IH2_1_MIR);
-		omap_writel(~0x0, OMAP_IH2_2_MIR);
-		omap_writel(~0x0, OMAP_IH2_3_MIR);
-	}
-
-	/*  New IRQ agreement */
- 	omap_writel(1, OMAP_IH1_CONTROL);
-
-	/* external PULL to down, bit 22 = 0 */
-	omap_writel(omap_readl(PULL_DWN_CTRL_2) & ~(1<<22), PULL_DWN_CTRL_2);
-}
-
-void omap_pm_suspend(void)
-{
-	unsigned int mask32 = 0;
-	unsigned long arg0 = 0, arg1 = 0;
-	int (*func_ptr)(unsigned short, unsigned short) = 0;
-	unsigned short save_dsp_idlect2;
-
-	printk("PM: OMAP%x is entering deep sleep now ...\n", system_rev);
-
-	if (machine_is_omap_osk()) {
-		/* Stop LED1 (D9) blink */
-		tps65010_set_led(LED1, OFF);
-	}
-
-	/*
-	 * Step 1: turn off interrupts
-	 */
-
-	local_irq_disable();
-	local_fiq_disable();
-
-	/*
-	 * Step 2: save registers
-	 *
-	 * The omap is a strange/beautiful device. The caches, memory
-	 * and register state are preserved across power saves.
-	 * We have to save and restore very little register state to
-	 * idle the omap.
-         *
- 	 * Save interrupt, MPUI, ARM and UPLD control registers.
-	 */
-
-	if (cpu_is_omap1510()) {
-		MPUI1510_SAVE(OMAP_IH1_MIR);
-		MPUI1510_SAVE(OMAP_IH2_MIR);
-		MPUI1510_SAVE(MPUI_CTRL);
-		MPUI1510_SAVE(MPUI_DSP_BOOT_CONFIG);
-		MPUI1510_SAVE(MPUI_DSP_API_CONFIG);
-		MPUI1510_SAVE(EMIFS_CONFIG);
-		MPUI1510_SAVE(EMIFF_SDRAM_CONFIG);
-	} else if (cpu_is_omap16xx()) {
-		MPUI1610_SAVE(OMAP_IH1_MIR);
-		MPUI1610_SAVE(OMAP_IH2_0_MIR);
-		MPUI1610_SAVE(OMAP_IH2_1_MIR);
-		MPUI1610_SAVE(OMAP_IH2_2_MIR);
-		MPUI1610_SAVE(OMAP_IH2_3_MIR);
-		MPUI1610_SAVE(MPUI_CTRL);
-		MPUI1610_SAVE(MPUI_DSP_BOOT_CONFIG);
-		MPUI1610_SAVE(MPUI_DSP_API_CONFIG);
-		MPUI1610_SAVE(EMIFS_CONFIG);
-		MPUI1610_SAVE(EMIFF_SDRAM_CONFIG);
-	}
-
-	ARM_SAVE(ARM_CKCTL);
-	ARM_SAVE(ARM_IDLECT1);
-	ARM_SAVE(ARM_IDLECT2);
-	ARM_SAVE(ARM_EWUPCT);
-	ARM_SAVE(ARM_RSTCT1);
-	ARM_SAVE(ARM_RSTCT2);
-	ARM_SAVE(ARM_SYSST);
-	ULPD_SAVE(ULPD_CLOCK_CTRL);
-	ULPD_SAVE(ULPD_STATUS_REQ);
-
-	/*
-	 * Step 3: LOW_PWR signal enabling
-	 *
-	 * Allow the LOW_PWR signal to be visible on MPUIO5 ball.
-	 */
-	if (cpu_is_omap1510()) {
-		/* POWER_CTRL_REG = 0x1 (LOW_POWER is available) */
-		omap_writew(omap_readw(ULPD_POWER_CTRL) |
-			    OMAP1510_ULPD_LOW_POWER_REQ, ULPD_POWER_CTRL);
-	} else if (cpu_is_omap16xx()) {
-		/* POWER_CTRL_REG = 0x1 (LOW_POWER is available) */
-		omap_writew(omap_readw(ULPD_POWER_CTRL) |
-			    OMAP1610_ULPD_LOW_POWER_REQ, ULPD_POWER_CTRL);
-	}
-
-	/* configure LOW_PWR pin */
-	omap_cfg_reg(T20_1610_LOW_PWR);
-
-	/*
-	 * Step 4: OMAP DSP Shutdown
-	 */
-
-	/* Set DSP_RST = 1 and DSP_EN = 0, put DSP block into reset */
-	omap_writel((omap_readl(ARM_RSTCT1) | DSP_RST) & ~DSP_ENABLE,
-		    ARM_RSTCT1);
-
-	/* Set DSP boot mode to DSP-IDLE, DSP_BOOT_MODE = 0x2 */
-        omap_writel(DSP_IDLE_MODE, MPUI_DSP_BOOT_CONFIG);
-
-	/* Set EN_DSPCK = 0, stop DSP block clock */
-	omap_writel(omap_readl(ARM_CKCTL) & ~DSP_CLOCK_ENABLE, ARM_CKCTL);
-
-	/* Stop any DSP domain clocks */
-	omap_writel(omap_readl(ARM_IDLECT2) | (1<<EN_APICK), ARM_IDLECT2);
-	save_dsp_idlect2 = __raw_readw(DSP_IDLECT2);
-	__raw_writew(0, DSP_IDLECT2);
-
-	/*
-	 * Step 5: Wakeup Event Setup
-	 */
-
-	omap_pm_wakeup_setup();
-
-	/*
-	 * Step 6a: ARM and Traffic controller shutdown
-	 *
-	 * Step 6 starts here with clock and watchdog disable
-	 */
-
-	/* stop clocks */
-	mask32 = omap_readl(ARM_IDLECT2);
-	mask32 &= ~(1<<EN_WDTCK);  /* bit 0 -> 0 (WDT clock) */
-	mask32 |=  (1<<EN_XORPCK); /* bit 1 -> 1 (XORPCK clock) */
-	mask32 &= ~(1<<EN_PERCK);  /* bit 2 -> 0 (MPUPER_CK clock) */
-	mask32 &= ~(1<<EN_LCDCK);  /* bit 3 -> 0 (LCDC clock) */
-	mask32 &= ~(1<<EN_LBCK);   /* bit 4 -> 0 (local bus clock) */
-	mask32 |=  (1<<EN_APICK);  /* bit 6 -> 1 (MPUI clock) */
-	mask32 &= ~(1<<EN_TIMCK);  /* bit 7 -> 0 (MPU timer clock) */
-	mask32 &= ~(1<<DMACK_REQ); /* bit 8 -> 0 (DMAC clock) */
-	mask32 &= ~(1<<EN_GPIOCK); /* bit 9 -> 0 (GPIO clock) */
-	omap_writel(mask32, ARM_IDLECT2);
-
-	/* disable ARM watchdog */
-	omap_writel(0x00F5, OMAP_WDT_TIMER_MODE);
-	omap_writel(0x00A0, OMAP_WDT_TIMER_MODE);
-
-	/*
-	 * Step 6b: ARM and Traffic controller shutdown
-	 *
-	 * Step 6 continues here. Prepare jump to power management
-	 * assembly code in internal SRAM.
-	 *
-	 * Since the omap_cpu_suspend routine has been copied to
-	 * SRAM, we'll do an indirect procedure call to it and pass the
-	 * contents of arm_idlect1 and arm_idlect2 so it can restore
-	 * them when it wakes up and it will return.
-	 */
-
-	arg0 = arm_sleep_save[ARM_SLEEP_SAVE_ARM_IDLECT1];
-	arg1 = arm_sleep_save[ARM_SLEEP_SAVE_ARM_IDLECT2];
-
-	if (cpu_is_omap1510()) {
-		func_ptr = (void *)(OMAP1510_SRAM_API_SUSPEND);
-	} else if (cpu_is_omap1610() || cpu_is_omap1710()) {
-		func_ptr = (void *)(OMAP1610_SRAM_API_SUSPEND);
-	} else if (cpu_is_omap5912()) {
-		func_ptr = (void *)(OMAP5912_SRAM_API_SUSPEND);
-	}
-
-	/*
-	 * Step 6c: ARM and Traffic controller shutdown
-	 *
-	 * Jump to assembly code. The processor will stay there
- 	 * until wake up.
-	 */
-
-        func_ptr(arg0, arg1);
-
-	/*
-	 * If we are here, processor is woken up!
-	 */
-
-	if (cpu_is_omap1510()) {
-		/* POWER_CTRL_REG = 0x0 (LOW_POWER is disabled) */
-		omap_writew(omap_readw(ULPD_POWER_CTRL) &
-			    ~OMAP1510_ULPD_LOW_POWER_REQ, ULPD_POWER_CTRL);
-	} else if (cpu_is_omap16xx()) {
-		/* POWER_CTRL_REG = 0x0 (LOW_POWER is disabled) */
-		omap_writew(omap_readw(ULPD_POWER_CTRL) &
-			    ~OMAP1610_ULPD_LOW_POWER_REQ, ULPD_POWER_CTRL);
-	}
-
-
-	/* Restore DSP clocks */
-	omap_writel(omap_readl(ARM_IDLECT2) | (1<<EN_APICK), ARM_IDLECT2);
-	__raw_writew(save_dsp_idlect2, DSP_IDLECT2);
-	ARM_RESTORE(ARM_IDLECT2);
-
-	/*
-	 * Restore ARM state, except ARM_IDLECT1/2 which omap_cpu_suspend did
-	 */
-
-	ARM_RESTORE(ARM_CKCTL);
-	ARM_RESTORE(ARM_EWUPCT);
-	ARM_RESTORE(ARM_RSTCT1);
-	ARM_RESTORE(ARM_RSTCT2);
-	ARM_RESTORE(ARM_SYSST);
-	ULPD_RESTORE(ULPD_CLOCK_CTRL);
-	ULPD_RESTORE(ULPD_STATUS_REQ);
-
-	if (cpu_is_omap1510()) {
-		MPUI1510_RESTORE(MPUI_CTRL);
-		MPUI1510_RESTORE(MPUI_DSP_BOOT_CONFIG);
-		MPUI1510_RESTORE(MPUI_DSP_API_CONFIG);
-		MPUI1510_RESTORE(EMIFS_CONFIG);
-		MPUI1510_RESTORE(EMIFF_SDRAM_CONFIG);
-		MPUI1510_RESTORE(OMAP_IH1_MIR);
-		MPUI1510_RESTORE(OMAP_IH2_MIR);
-	} else if (cpu_is_omap16xx()) {
-		MPUI1610_RESTORE(MPUI_CTRL);
-		MPUI1610_RESTORE(MPUI_DSP_BOOT_CONFIG);
-		MPUI1610_RESTORE(MPUI_DSP_API_CONFIG);
-		MPUI1610_RESTORE(EMIFS_CONFIG);
-		MPUI1610_RESTORE(EMIFF_SDRAM_CONFIG);
-
-		MPUI1610_RESTORE(OMAP_IH1_MIR);
-		MPUI1610_RESTORE(OMAP_IH2_0_MIR);
-		MPUI1610_RESTORE(OMAP_IH2_1_MIR);
-		MPUI1610_RESTORE(OMAP_IH2_2_MIR);
-		MPUI1610_RESTORE(OMAP_IH2_3_MIR);
-	}
-
-	/*
-	 * Reenable interrupts
-	 */
-
-	local_irq_enable();
-	local_fiq_enable();
-
-	printk("PM: OMAP%x is re-starting from deep sleep...\n", system_rev);
-
-	if (machine_is_omap_osk()) {
-		/* Let LED1 (D9) blink again */
-		tps65010_set_led(LED1, BLINK);
-	}
-}
-
-#if defined(DEBUG) && defined(CONFIG_PROC_FS)
-static int g_read_completed;
-
-/*
- * Read system PM registers for debugging
- */
-static int omap_pm_read_proc(
-	char *page_buffer,
-	char **my_first_byte,
-	off_t virtual_start,
-	int length,
-	int *eof,
-	void *data)
-{
-	int my_buffer_offset = 0;
-	char * const my_base = page_buffer;
-
-	ARM_SAVE(ARM_CKCTL);
-	ARM_SAVE(ARM_IDLECT1);
-	ARM_SAVE(ARM_IDLECT2);
-	ARM_SAVE(ARM_EWUPCT);
-	ARM_SAVE(ARM_RSTCT1);
-	ARM_SAVE(ARM_RSTCT2);
-	ARM_SAVE(ARM_SYSST);
-
-	ULPD_SAVE(ULPD_IT_STATUS);
-	ULPD_SAVE(ULPD_CLOCK_CTRL);
-	ULPD_SAVE(ULPD_SOFT_REQ);
-	ULPD_SAVE(ULPD_STATUS_REQ);
-	ULPD_SAVE(ULPD_DPLL_CTRL);
-	ULPD_SAVE(ULPD_POWER_CTRL);
-
-	if (cpu_is_omap1510()) {
-		MPUI1510_SAVE(MPUI_CTRL);
-		MPUI1510_SAVE(MPUI_DSP_STATUS);
-		MPUI1510_SAVE(MPUI_DSP_BOOT_CONFIG);
-		MPUI1510_SAVE(MPUI_DSP_API_CONFIG);
-		MPUI1510_SAVE(EMIFF_SDRAM_CONFIG);
-		MPUI1510_SAVE(EMIFS_CONFIG);
-	} else if (cpu_is_omap16xx()) {
-		MPUI1610_SAVE(MPUI_CTRL);
-		MPUI1610_SAVE(MPUI_DSP_STATUS);
-		MPUI1610_SAVE(MPUI_DSP_BOOT_CONFIG);
-		MPUI1610_SAVE(MPUI_DSP_API_CONFIG);
-		MPUI1610_SAVE(EMIFF_SDRAM_CONFIG);
-		MPUI1610_SAVE(EMIFS_CONFIG);
-	}
-
-	if (virtual_start == 0) {
-		g_read_completed = 0;
-
-		my_buffer_offset += sprintf(my_base + my_buffer_offset,
-		   "ARM_CKCTL_REG:            0x%-8x     \n"
-		   "ARM_IDLECT1_REG:          0x%-8x     \n"
-		   "ARM_IDLECT2_REG:          0x%-8x     \n"
-		   "ARM_EWUPCT_REG:           0x%-8x     \n"
-		   "ARM_RSTCT1_REG:           0x%-8x     \n"
-		   "ARM_RSTCT2_REG:           0x%-8x     \n"
-		   "ARM_SYSST_REG:            0x%-8x     \n"
-		   "ULPD_IT_STATUS_REG:       0x%-4x     \n"
-		   "ULPD_CLOCK_CTRL_REG:      0x%-4x     \n"
-		   "ULPD_SOFT_REQ_REG:        0x%-4x     \n"
-		   "ULPD_DPLL_CTRL_REG:       0x%-4x     \n"
-		   "ULPD_STATUS_REQ_REG:      0x%-4x     \n"
-		   "ULPD_POWER_CTRL_REG:      0x%-4x     \n",
-		   ARM_SHOW(ARM_CKCTL),
-		   ARM_SHOW(ARM_IDLECT1),
-		   ARM_SHOW(ARM_IDLECT2),
-		   ARM_SHOW(ARM_EWUPCT),
-		   ARM_SHOW(ARM_RSTCT1),
-		   ARM_SHOW(ARM_RSTCT2),
-		   ARM_SHOW(ARM_SYSST),
-		   ULPD_SHOW(ULPD_IT_STATUS),
-		   ULPD_SHOW(ULPD_CLOCK_CTRL),
-		   ULPD_SHOW(ULPD_SOFT_REQ),
-		   ULPD_SHOW(ULPD_DPLL_CTRL),
-		   ULPD_SHOW(ULPD_STATUS_REQ),
-		   ULPD_SHOW(ULPD_POWER_CTRL));
-
-		if (cpu_is_omap1510()) {
-			my_buffer_offset += sprintf(my_base + my_buffer_offset,
-			   "MPUI1510_CTRL_REG             0x%-8x \n"
-			   "MPUI1510_DSP_STATUS_REG:      0x%-8x \n"
-			   "MPUI1510_DSP_BOOT_CONFIG_REG: 0x%-8x \n"
-		   	   "MPUI1510_DSP_API_CONFIG_REG:  0x%-8x \n"
-		   	   "MPUI1510_SDRAM_CONFIG_REG:    0x%-8x \n"
-		   	   "MPUI1510_EMIFS_CONFIG_REG:    0x%-8x \n",
-		   	   MPUI1510_SHOW(MPUI_CTRL),
-		   	   MPUI1510_SHOW(MPUI_DSP_STATUS),
-		   	   MPUI1510_SHOW(MPUI_DSP_BOOT_CONFIG),
-		   	   MPUI1510_SHOW(MPUI_DSP_API_CONFIG),
-		   	   MPUI1510_SHOW(EMIFF_SDRAM_CONFIG),
-		   	   MPUI1510_SHOW(EMIFS_CONFIG));
-		} else if (cpu_is_omap16xx()) {
-			my_buffer_offset += sprintf(my_base + my_buffer_offset,
-			   "MPUI1610_CTRL_REG             0x%-8x \n"
-			   "MPUI1610_DSP_STATUS_REG:      0x%-8x \n"
-			   "MPUI1610_DSP_BOOT_CONFIG_REG: 0x%-8x \n"
-		   	   "MPUI1610_DSP_API_CONFIG_REG:  0x%-8x \n"
-		   	   "MPUI1610_SDRAM_CONFIG_REG:    0x%-8x \n"
-		   	   "MPUI1610_EMIFS_CONFIG_REG:    0x%-8x \n",
-		   	   MPUI1610_SHOW(MPUI_CTRL),
-		   	   MPUI1610_SHOW(MPUI_DSP_STATUS),
-		   	   MPUI1610_SHOW(MPUI_DSP_BOOT_CONFIG),
-		   	   MPUI1610_SHOW(MPUI_DSP_API_CONFIG),
-		   	   MPUI1610_SHOW(EMIFF_SDRAM_CONFIG),
-		   	   MPUI1610_SHOW(EMIFS_CONFIG));
-		}
-
-		g_read_completed++;
-	} else if (g_read_completed >= 1) {
-		 *eof = 1;
-		 return 0;
-	}
-	g_read_completed++;
-
-	*my_first_byte = page_buffer;
-	return  my_buffer_offset;
-}
-
-static void omap_pm_init_proc(void)
-{
-	struct proc_dir_entry *entry;
-
-	entry = create_proc_read_entry("driver/omap_pm",
-				       S_IWUSR | S_IRUGO, NULL,
-				       omap_pm_read_proc, 0);
-}
-
-#endif /* DEBUG && CONFIG_PROC_FS */
-
-/*
- *	omap_pm_prepare - Do preliminary suspend work.
- *	@state:		suspend state we're entering.
- *
- */
-//#include <asm/arch/hardware.h>
-
-static int omap_pm_prepare(suspend_state_t state)
-{
-	int error = 0;
-
-	switch (state)
-	{
-	case PM_SUSPEND_STANDBY:
-	case PM_SUSPEND_MEM:
-		break;
-
-	case PM_SUSPEND_DISK:
-		return -ENOTSUPP;
-
-	default:
-		return -EINVAL;
-	}
-
-	return error;
-}
-
-
-/*
- *	omap_pm_enter - Actually enter a sleep state.
- *	@state:		State we're entering.
- *
- */
-
-static int omap_pm_enter(suspend_state_t state)
-{
-	switch (state)
-	{
-	case PM_SUSPEND_STANDBY:
-	case PM_SUSPEND_MEM:
-		omap_pm_suspend();
-		break;
-
-	case PM_SUSPEND_DISK:
-		return -ENOTSUPP;
-
-	default:
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-
-/**
- *	omap_pm_finish - Finish up suspend sequence.
- *	@state:		State we're coming out of.
- *
- *	This is called after we wake back up (or if entering the sleep state
- *	failed).
- */
-
-static int omap_pm_finish(suspend_state_t state)
-{
-	return 0;
-}
-
-
-struct pm_ops omap_pm_ops ={
-	.pm_disk_mode = 0,
-        .prepare        = omap_pm_prepare,
-        .enter          = omap_pm_enter,
-        .finish         = omap_pm_finish,
-};
-
-static int __init omap_pm_init(void)
-{
-	printk("Power Management for TI OMAP.\n");
-	pm_idle = omap_pm_idle;
-	/*
-	 * We copy the assembler sleep/wakeup routines to SRAM.
-	 * These routines need to be in SRAM as that's the only
-	 * memory the MPU can see when it wakes up.
-	 */
-
-#ifdef	CONFIG_ARCH_OMAP1510
-	if (cpu_is_omap1510()) {
-		memcpy((void *)OMAP1510_SRAM_IDLE_SUSPEND,
-		       omap1510_idle_loop_suspend,
-		       omap1510_idle_loop_suspend_sz);
-		memcpy((void *)OMAP1510_SRAM_API_SUSPEND, omap1510_cpu_suspend,
-		       omap1510_cpu_suspend_sz);
-	} else
-#endif
-	if (cpu_is_omap1610() || cpu_is_omap1710()) {
-		memcpy((void *)OMAP1610_SRAM_IDLE_SUSPEND,
-		       omap1610_idle_loop_suspend,
-		       omap1610_idle_loop_suspend_sz);
-		memcpy((void *)OMAP1610_SRAM_API_SUSPEND, omap1610_cpu_suspend,
-		       omap1610_cpu_suspend_sz);
-	} else if (cpu_is_omap5912()) {
-		memcpy((void *)OMAP5912_SRAM_IDLE_SUSPEND,
-		       omap1610_idle_loop_suspend,
-		       omap1610_idle_loop_suspend_sz);
-		memcpy((void *)OMAP5912_SRAM_API_SUSPEND, omap1610_cpu_suspend,
-		       omap1610_cpu_suspend_sz);
-	}
-
-	pm_set_ops(&omap_pm_ops);
-
-#if defined(DEBUG) && defined(CONFIG_PROC_FS)
-	omap_pm_init_proc();
-#endif
-
-	return 0;
-}
-__initcall(omap_pm_init);
-
diff --git a/arch/arm/mach-omap/sleep.S b/arch/arm/mach-omap/sleep.S
deleted file mode 100644
--- a/arch/arm/mach-omap/sleep.S
+++ /dev/null
@@ -1,314 +0,0 @@
-/*
- * linux/arch/arm/mach-omap/sleep.S
- *
- * Low-level OMAP1510/1610 sleep/wakeUp support
- *
- * Initial SA1110 code:
- * Copyright (c) 2001 Cliff Brake <cbrake@accelent.com>
- *
- * Adapted for PXA by Nicolas Pitre:
- * Copyright (c) 2002 Monta Vista Software, Inc.
- *
- * Support for OMAP1510/1610 by Dirk Behme <dirk.behme@de.bosch.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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
- * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/config.h>
-#include <linux/linkage.h>
-#include <asm/assembler.h>
-#include <asm/arch/io.h>
-#include <asm/arch/pm.h>
-
-		.text
-
-/*
- * Forces OMAP into idle state
- *
- * omapXXXX_idle_loop_suspend()
- *
- * Note: This code get's copied to internal SRAM at boot. When the OMAP
- *	 wakes up it continues execution at the point it went to sleep.
- *
- * Note: Because of slightly different configuration values we have
- *       processor specific functions here.
- */
-
-#ifdef CONFIG_ARCH_OMAP1510
-ENTRY(omap1510_idle_loop_suspend)
-
-	stmfd	sp!, {r0 - r12, lr}		@ save registers on stack
-
-	@ load base address of ARM_IDLECT1 and ARM_IDLECT2
-	mov	r4, #CLKGEN_REG_ASM_BASE & 0xff000000
-	orr	r4, r4, #CLKGEN_REG_ASM_BASE & 0x00ff0000
-	orr	r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00
-
-	@ turn off clock domains
-	@ get ARM_IDLECT2 into r2
-	ldrh	r2, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
-	mov	r5, #OMAP1510_IDLE_CLOCK_DOMAINS & 0xff
- 	orr	r5,r5, #OMAP1510_IDLE_CLOCK_DOMAINS & 0xff00
-	strh	r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
-
-	@ request ARM idle
-	@ get ARM_IDLECT1 into r1
-	ldrh	r1, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
-	orr	r3, r1, #OMAP1510_IDLE_LOOP_REQUEST & 0xffff
-	strh	r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
-
-	mov	r5, #IDLE_WAIT_CYCLES & 0xff
-	orr     r5, r5, #IDLE_WAIT_CYCLES & 0xff00
-l_1510:	subs	r5, r5, #1
-	bne	l_1510
-/*
- * Let's wait for the next clock tick to wake us up.
- */
-	mov	r0, #0
-	mcr	p15, 0, r0, c7, c0, 4		@ wait for interrupt
-/*
- * omap1510_idle_loop_suspend()'s resume point.
- *
- * It will just start executing here, so we'll restore stuff from the
- * stack, reset the ARM_IDLECT1 and ARM_IDLECT2.
- */
-
-	@ restore ARM_IDLECT1 and ARM_IDLECT2 and return
-	@ r1 has ARM_IDLECT1 and r2 still has ARM_IDLECT2
-	strh	r2, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
-	strh	r1, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
-
-	ldmfd   sp!, {r0 - r12, pc}     @ restore regs and return
-
-ENTRY(omap1510_idle_loop_suspend_sz)
-	.word	. - omap1510_idle_loop_suspend
-#endif /* CONFIG_ARCH_OMAP1510 */
-
-#if defined(CONFIG_ARCH_OMAP16XX)
-ENTRY(omap1610_idle_loop_suspend)
-
-	stmfd	sp!, {r0 - r12, lr}		@ save registers on stack
-
-	@ load base address of ARM_IDLECT1 and ARM_IDLECT2
-	mov	r4, #CLKGEN_REG_ASM_BASE & 0xff000000
-	orr	r4, r4, #CLKGEN_REG_ASM_BASE & 0x00ff0000
-	orr	r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00
-
-	@ turn off clock domains
-	@ get ARM_IDLECT2 into r2
-	ldrh	r2, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
-	mov	r5, #OMAP1610_IDLE_CLOCK_DOMAINS & 0xff
- 	orr	r5,r5, #OMAP1610_IDLE_CLOCK_DOMAINS & 0xff00
-	strh	r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
-
-	@ request ARM idle
-	@ get ARM_IDLECT1 into r1
-	ldrh	r1, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
-	orr	r3, r1, #OMAP1610_IDLE_LOOP_REQUEST & 0xffff
-	strh	r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
-
-	mov	r5, #IDLE_WAIT_CYCLES & 0xff
-	orr     r5, r5, #IDLE_WAIT_CYCLES & 0xff00
-l_1610:	subs	r5, r5, #1
-	bne	l_1610
-/*
- * Let's wait for the next clock tick to wake us up.
- */
-	mov	r0, #0
-	mcr	p15, 0, r0, c7, c0, 4		@ wait for interrupt
-/*
- * omap1610_idle_loop_suspend()'s resume point.
- *
- * It will just start executing here, so we'll restore stuff from the
- * stack, reset the ARM_IDLECT1 and ARM_IDLECT2.
- */
-
-	@ restore ARM_IDLECT1 and ARM_IDLECT2 and return
-	@ r1 has ARM_IDLECT1 and r2 still has ARM_IDLECT2
-	strh	r2, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
-	strh	r1, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
-
-	ldmfd   sp!, {r0 - r12, pc}     @ restore regs and return
-
-ENTRY(omap1610_idle_loop_suspend_sz)
-	.word	. - omap1610_idle_loop_suspend
-#endif /* CONFIG_ARCH_OMAP16XX */
-
-/*
- * Forces OMAP into deep sleep state
- *
- * omapXXXX_cpu_suspend()
- *
- * The values of the registers ARM_IDLECT1 and ARM_IDLECT2 are passed
- * as arg0 and arg1 from caller. arg0 is stored in register r0 and arg1
- * in register r1.
- *
- * Note: This code get's copied to internal SRAM at boot. When the OMAP
- *	 wakes up it continues execution at the point it went to sleep.
- *
- * Note: Because of errata work arounds we have processor specific functions
- *       here. They are mostly the same, but slightly different.
- *
- */
-
-#ifdef CONFIG_ARCH_OMAP1510
-ENTRY(omap1510_cpu_suspend)
-
-	@ save registers on stack
-	stmfd	sp!, {r0 - r12, lr}
-
-	@ load base address of Traffic Controller
-	mov	r4, #TCMIF_ASM_BASE & 0xff000000
-	orr	r4, r4, #TCMIF_ASM_BASE & 0x00ff0000
-	orr	r4, r4, #TCMIF_ASM_BASE & 0x0000ff00
-
-	@ work around errata of OMAP1510 PDE bit for TC shut down
-	@ clear PDE bit
-	ldr	r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
-	bic	r5, r5, #PDE_BIT & 0xff
-	str	r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
-
-	@ set PWD_EN bit
-	and	r5, r5, #PWD_EN_BIT & 0xff
-	str	r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
-
-	@ prepare to put SDRAM into self-refresh manually
-	ldr	r5, [r4, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
-	orr	r5, r5, #SELF_REFRESH_MODE & 0xff000000
-	orr	r5, r5, #SELF_REFRESH_MODE & 0x000000ff
-	str	r5, [r4, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
-
-	@ prepare to put EMIFS to Sleep
-	ldr	r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
-	orr	r5, r5, #IDLE_EMIFS_REQUEST & 0xff
-	str	r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
-
-	@ load base address of ARM_IDLECT1 and ARM_IDLECT2
-	mov	r4, #CLKGEN_REG_ASM_BASE & 0xff000000
-	orr	r4, r4, #CLKGEN_REG_ASM_BASE & 0x00ff0000
-	orr	r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00
-
-	@ turn off clock domains
-	mov	r5, #OMAP1510_IDLE_CLOCK_DOMAINS & 0xff
- 	orr	r5,r5, #OMAP1510_IDLE_CLOCK_DOMAINS & 0xff00
-	strh	r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
-
-	@ request ARM idle
-	mov	r3, #OMAP1510_DEEP_SLEEP_REQUEST & 0xff
-	orr	r3, r3, #OMAP1510_DEEP_SLEEP_REQUEST & 0xff00
-	strh	r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
-
-	mov	r5, #IDLE_WAIT_CYCLES & 0xff
-	orr     r5, r5, #IDLE_WAIT_CYCLES & 0xff00
-l_1510_2:
-	subs	r5, r5, #1
-	bne	l_1510_2
-/*
- * Let's wait for the next wake up event to wake us up. r0 can't be
- * used here because r0 holds ARM_IDLECT1
- */
-	mov	r2, #0
-	mcr	p15, 0, r2, c7, c0, 4		@ wait for interrupt
-/*
- * omap1510_cpu_suspend()'s resume point.
- *
- * It will just start executing here, so we'll restore stuff from the
- * stack, reset the ARM_IDLECT1 and ARM_IDLECT2.
- */
-	strh	r1, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
-	strh	r0, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
-
-	@ restore regs and return
-	ldmfd   sp!, {r0 - r12, pc}
-
-ENTRY(omap1510_cpu_suspend_sz)
-	.word	. - omap1510_cpu_suspend
-#endif /* CONFIG_ARCH_OMAP1510 */
-
-#if defined(CONFIG_ARCH_OMAP16XX)
-ENTRY(omap1610_cpu_suspend)
-
-	@ save registers on stack
-	stmfd	sp!, {r0 - r12, lr}
-
-	@ load base address of Traffic Controller
-	mov	r4, #TCMIF_ASM_BASE & 0xff000000
-	orr	r4, r4, #TCMIF_ASM_BASE & 0x00ff0000
-	orr	r4, r4, #TCMIF_ASM_BASE & 0x0000ff00
-
-	@ prepare to put SDRAM into self-refresh manually
-	ldr	r5, [r4, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
-	orr	r5, r5, #SELF_REFRESH_MODE & 0xff000000
-	orr	r5, r5, #SELF_REFRESH_MODE & 0x000000ff
-	str	r5, [r4, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
-
-	@ prepare to put EMIFS to Sleep
-	ldr	r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
-	orr	r5, r5, #IDLE_EMIFS_REQUEST & 0xff
-	str	r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
-
-	@ load base address of ARM_IDLECT1 and ARM_IDLECT2
-	mov	r4, #CLKGEN_REG_ASM_BASE & 0xff000000
-	orr	r4, r4, #CLKGEN_REG_ASM_BASE & 0x00ff0000
-	orr	r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00
-
-	@ turn off clock domains
-	mov	r5, #OMAP1610_IDLE_CLOCK_DOMAINS & 0xff
- 	orr	r5,r5, #OMAP1610_IDLE_CLOCK_DOMAINS & 0xff00
-	strh	r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
-
-	@ work around errata of OMAP1610/5912. Enable (!) peripheral
-	@ clock to let the chip go into deep sleep
-	ldrh	r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
- 	orr	r5,r5, #EN_PERCK_BIT & 0xff
-	strh	r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
-
-	@ request ARM idle
-	mov	r3, #OMAP1610_DEEP_SLEEP_REQUEST & 0xff
-	orr	r3, r3, #OMAP1610_DEEP_SLEEP_REQUEST & 0xff00
-	strh	r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
-
-	mov	r5, #IDLE_WAIT_CYCLES & 0xff
-	orr     r5, r5, #IDLE_WAIT_CYCLES & 0xff00
-l_1610_2:
-	subs	r5, r5, #1
-	bne	l_1610_2
-/*
- * Let's wait for the next wake up event to wake us up. r0 can't be
- * used here because r0 holds ARM_IDLECT1
- */
-	mov	r2, #0
-	mcr	p15, 0, r2, c7, c0, 4		@ wait for interrupt
-/*
- * omap1610_cpu_suspend()'s resume point.
- *
- * It will just start executing here, so we'll restore stuff from the
- * stack, reset the ARM_IDLECT1 and ARM_IDLECT2.
- */
-	strh	r1, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
-	strh	r0, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
-
-	@ restore regs and return
-	ldmfd   sp!, {r0 - r12, pc}
-
-ENTRY(omap1610_cpu_suspend_sz)
-	.word	. - omap1610_cpu_suspend
-#endif /* CONFIG_ARCH_OMAP16XX */
diff --git a/arch/arm/mach-omap/time.c b/arch/arm/mach-omap/time.c
deleted file mode 100644
--- a/arch/arm/mach-omap/time.c
+++ /dev/null
@@ -1,384 +0,0 @@
-/*
- * linux/arch/arm/mach-omap/time.c
- *
- * OMAP Timers
- *
- * Copyright (C) 2004 Nokia Corporation
- * Partial timer rewrite and additional VST timer support by
- * Tony Lindgen <tony@atomide.com> and
- * Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
- *
- * MPU timer code based on the older MPU timer code for OMAP
- * Copyright (C) 2000 RidgeRun, Inc.
- * Author: Greg Lonnon <glonnon@ridgerun.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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
- * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * You should have received a copy of the  GNU General Public License along
- * with this program; if not, write  to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/sched.h>
-#include <linux/spinlock.h>
-
-#include <asm/system.h>
-#include <asm/hardware.h>
-#include <asm/io.h>
-#include <asm/leds.h>
-#include <asm/irq.h>
-#include <asm/mach/irq.h>
-#include <asm/mach/time.h>
-
-struct sys_timer omap_timer;
-
-#ifdef CONFIG_OMAP_MPU_TIMER
-
-/*
- * ---------------------------------------------------------------------------
- * MPU timer
- * ---------------------------------------------------------------------------
- */
-#define OMAP_MPU_TIMER1_BASE		(0xfffec500)
-#define OMAP_MPU_TIMER2_BASE		(0xfffec600)
-#define OMAP_MPU_TIMER3_BASE		(0xfffec700)
-#define OMAP_MPU_TIMER_BASE		OMAP_MPU_TIMER1_BASE
-#define OMAP_MPU_TIMER_OFFSET		0x100
-
-#define MPU_TIMER_FREE			(1 << 6)
-#define MPU_TIMER_CLOCK_ENABLE		(1 << 5)
-#define MPU_TIMER_AR			(1 << 1)
-#define MPU_TIMER_ST			(1 << 0)
-
-/* cycles to nsec conversions taken from arch/i386/kernel/timers/timer_tsc.c,
- * converted to use kHz by Kevin Hilman */
-/* convert from cycles(64bits) => nanoseconds (64bits)
- *  basic equation:
- *		ns = cycles / (freq / ns_per_sec)
- *		ns = cycles * (ns_per_sec / freq)
- *		ns = cycles * (10^9 / (cpu_khz * 10^3))
- *		ns = cycles * (10^6 / cpu_khz)
- *
- *	Then we use scaling math (suggested by george at mvista.com) to get:
- *		ns = cycles * (10^6 * SC / cpu_khz / SC
- *		ns = cycles * cyc2ns_scale / SC
- *
- *	And since SC is a constant power of two, we can convert the div
- *  into a shift.
- *			-johnstul at us.ibm.com "math is hard, lets go shopping!"
- */
-static unsigned long cyc2ns_scale;
-#define CYC2NS_SCALE_FACTOR 10 /* 2^10, carefully chosen */
-
-static inline void set_cyc2ns_scale(unsigned long cpu_khz)
-{
-	cyc2ns_scale = (1000000 << CYC2NS_SCALE_FACTOR)/cpu_khz;
-}
-
-static inline unsigned long long cycles_2_ns(unsigned long long cyc)
-{
-	return (cyc * cyc2ns_scale) >> CYC2NS_SCALE_FACTOR;
-}
-
-/*
- * MPU_TICKS_PER_SEC must be an even number, otherwise machinecycles_to_usecs
- * will break. On P2, the timer count rate is 6.5 MHz after programming PTV
- * with 0. This divides the 13MHz input by 2, and is undocumented.
- */
-#ifdef CONFIG_MACH_OMAP_PERSEUS2
-/* REVISIT: This ifdef construct should be replaced by a query to clock
- * framework to see if timer base frequency is 12.0, 13.0 or 19.2 MHz.
- */
-#define MPU_TICKS_PER_SEC		(13000000 / 2)
-#else
-#define MPU_TICKS_PER_SEC		(12000000 / 2)
-#endif
-
-#define MPU_TIMER_TICK_PERIOD		((MPU_TICKS_PER_SEC / HZ) - 1)
-
-typedef struct {
-	u32 cntl;			/* CNTL_TIMER, R/W */
-	u32 load_tim;			/* LOAD_TIM,   W */
-	u32 read_tim;			/* READ_TIM,   R */
-} omap_mpu_timer_regs_t;
-
-#define omap_mpu_timer_base(n)						\
-((volatile omap_mpu_timer_regs_t*)IO_ADDRESS(OMAP_MPU_TIMER_BASE +	\
-				 (n)*OMAP_MPU_TIMER_OFFSET))
-
-static inline unsigned long omap_mpu_timer_read(int nr)
-{
-	volatile omap_mpu_timer_regs_t* timer = omap_mpu_timer_base(nr);
-	return timer->read_tim;
-}
-
-static inline void omap_mpu_timer_start(int nr, unsigned long load_val)
-{
-	volatile omap_mpu_timer_regs_t* timer = omap_mpu_timer_base(nr);
-
-	timer->cntl = MPU_TIMER_CLOCK_ENABLE;
-	udelay(1);
-	timer->load_tim = load_val;
-        udelay(1);
-	timer->cntl = (MPU_TIMER_CLOCK_ENABLE | MPU_TIMER_AR | MPU_TIMER_ST);
-}
-
-unsigned long omap_mpu_timer_ticks_to_usecs(unsigned long nr_ticks)
-{
-	unsigned long long nsec;
-
-	nsec = cycles_2_ns((unsigned long long)nr_ticks);
-	return (unsigned long)nsec / 1000;
-}
-
-/*
- * Last processed system timer interrupt
- */
-static unsigned long omap_mpu_timer_last = 0;
-
-/*
- * Returns elapsed usecs since last system timer interrupt
- */
-static unsigned long omap_mpu_timer_gettimeoffset(void)
-{
-	unsigned long now = 0 - omap_mpu_timer_read(0);
-	unsigned long elapsed = now - omap_mpu_timer_last;
-
-	return omap_mpu_timer_ticks_to_usecs(elapsed);
-}
-
-/*
- * Elapsed time between interrupts is calculated using timer0.
- * Latency during the interrupt is calculated using timer1.
- * Both timer0 and timer1 are counting at 6MHz (P2 6.5MHz).
- */
-static irqreturn_t omap_mpu_timer_interrupt(int irq, void *dev_id,
-					struct pt_regs *regs)
-{
-	unsigned long now, latency;
-
-	write_seqlock(&xtime_lock);
-	now = 0 - omap_mpu_timer_read(0);
-	latency = MPU_TICKS_PER_SEC / HZ - omap_mpu_timer_read(1);
-	omap_mpu_timer_last = now - latency;
-	timer_tick(regs);
-	write_sequnlock(&xtime_lock);
-
-	return IRQ_HANDLED;
-}
-
-static struct irqaction omap_mpu_timer_irq = {
-	.name		= "mpu timer",
-	.flags		= SA_INTERRUPT,
-	.handler	= omap_mpu_timer_interrupt
-};
-
-static unsigned long omap_mpu_timer1_overflows;
-static irqreturn_t omap_mpu_timer1_interrupt(int irq, void *dev_id,
-					     struct pt_regs *regs)
-{
-	omap_mpu_timer1_overflows++;
-	return IRQ_HANDLED;
-}
-
-static struct irqaction omap_mpu_timer1_irq = {
-	.name		= "mpu timer1 overflow",
-	.flags		= SA_INTERRUPT,
-	.handler	= omap_mpu_timer1_interrupt
-};
-
-static __init void omap_init_mpu_timer(void)
-{
-	set_cyc2ns_scale(MPU_TICKS_PER_SEC / 1000);
-	omap_timer.offset = omap_mpu_timer_gettimeoffset;
-	setup_irq(INT_TIMER1, &omap_mpu_timer1_irq);
-	setup_irq(INT_TIMER2, &omap_mpu_timer_irq);
-	omap_mpu_timer_start(0, 0xffffffff);
-	omap_mpu_timer_start(1, MPU_TIMER_TICK_PERIOD);
-}
-
-/*
- * Scheduler clock - returns current time in nanosec units.
- */
-unsigned long long sched_clock(void)
-{
-	unsigned long ticks = 0 - omap_mpu_timer_read(0);
-	unsigned long long ticks64;
-
-	ticks64 = omap_mpu_timer1_overflows;
-	ticks64 <<= 32;
-	ticks64 |= ticks;
-
-	return cycles_2_ns(ticks64);
-}
-#endif	/* CONFIG_OMAP_MPU_TIMER */
-
-#ifdef CONFIG_OMAP_32K_TIMER
-
-#ifdef CONFIG_ARCH_OMAP1510
-#error OMAP 32KHz timer does not currently work on 1510!
-#endif
-
-/*
- * ---------------------------------------------------------------------------
- * 32KHz OS timer
- *
- * This currently works only on 16xx, as 1510 does not have the continuous
- * 32KHz synchronous timer. The 32KHz synchronous timer is used to keep track
- * of time in addition to the 32KHz OS timer. Using only the 32KHz OS timer
- * on 1510 would be possible, but the timer would not be as accurate as
- * with the 32KHz synchronized timer.
- * ---------------------------------------------------------------------------
- */
-#define OMAP_32K_TIMER_BASE		0xfffb9000
-#define OMAP_32K_TIMER_CR		0x08
-#define OMAP_32K_TIMER_TVR		0x00
-#define OMAP_32K_TIMER_TCR		0x04
-
-#define OMAP_32K_TICKS_PER_HZ		(32768 / HZ)
-
-/*
- * TRM says 1 / HZ = ( TVR + 1) / 32768, so TRV = (32768 / HZ) - 1
- * so with HZ = 100, TVR = 327.68.
- */
-#define OMAP_32K_TIMER_TICK_PERIOD	((32768 / HZ) - 1)
-#define MAX_SKIP_JIFFIES		25
-#define TIMER_32K_SYNCHRONIZED		0xfffbc410
-
-#define JIFFIES_TO_HW_TICKS(nr_jiffies, clock_rate)			\
-				(((nr_jiffies) * (clock_rate)) / HZ)
-
-static inline void omap_32k_timer_write(int val, int reg)
-{
-	omap_writew(val, reg + OMAP_32K_TIMER_BASE);
-}
-
-static inline unsigned long omap_32k_timer_read(int reg)
-{
-	return omap_readl(reg + OMAP_32K_TIMER_BASE) & 0xffffff;
-}
-
-/*
- * The 32KHz synchronized timer is an additional timer on 16xx.
- * It is always running.
- */
-static inline unsigned long omap_32k_sync_timer_read(void)
-{
-	return omap_readl(TIMER_32K_SYNCHRONIZED);
-}
-
-static inline void omap_32k_timer_start(unsigned long load_val)
-{
-	omap_32k_timer_write(load_val, OMAP_32K_TIMER_TVR);
-	omap_32k_timer_write(0x0f, OMAP_32K_TIMER_CR);
-}
-
-static inline void omap_32k_timer_stop(void)
-{
-	omap_32k_timer_write(0x0, OMAP_32K_TIMER_CR);
-}
-
-/*
- * Rounds down to nearest usec
- */
-static inline unsigned long omap_32k_ticks_to_usecs(unsigned long ticks_32k)
-{
-	return (ticks_32k * 5*5*5*5*5*5) >> 9;
-}
-
-static unsigned long omap_32k_last_tick = 0;
-
-/*
- * Returns elapsed usecs since last 32k timer interrupt
- */
-static unsigned long omap_32k_timer_gettimeoffset(void)
-{
-	unsigned long now = omap_32k_sync_timer_read();
-	return omap_32k_ticks_to_usecs(now - omap_32k_last_tick);
-}
-
-/*
- * Timer interrupt for 32KHz timer. When dynamic tick is enabled, this
- * function is also called from other interrupts to remove latency
- * issues with dynamic tick. In the dynamic tick case, we need to lock
- * with irqsave.
- */
-static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id,
-					    struct pt_regs *regs)
-{
-	unsigned long flags;
-	unsigned long now;
-
-	write_seqlock_irqsave(&xtime_lock, flags);
-	now = omap_32k_sync_timer_read();
-
-	while (now - omap_32k_last_tick >= OMAP_32K_TICKS_PER_HZ) {
-		omap_32k_last_tick += OMAP_32K_TICKS_PER_HZ;
-		timer_tick(regs);
-	}
-
-	/* Restart timer so we don't drift off due to modulo or dynamic tick.
-	 * By default we program the next timer to be continuous to avoid
-	 * latencies during high system load. During dynamic tick operation the
-	 * continuous timer can be overridden from pm_idle to be longer.
-	 */
-	omap_32k_timer_start(omap_32k_last_tick + OMAP_32K_TICKS_PER_HZ - now);
-	write_sequnlock_irqrestore(&xtime_lock, flags);
-
-	return IRQ_HANDLED;
-}
-
-static struct irqaction omap_32k_timer_irq = {
-	.name		= "32KHz timer",
-	.flags		= SA_INTERRUPT,
-	.handler	= omap_32k_timer_interrupt
-};
-
-static __init void omap_init_32k_timer(void)
-{
-	setup_irq(INT_OS_TIMER, &omap_32k_timer_irq);
-	omap_timer.offset  = omap_32k_timer_gettimeoffset;
-	omap_32k_last_tick = omap_32k_sync_timer_read();
-	omap_32k_timer_start(OMAP_32K_TIMER_TICK_PERIOD);
-}
-#endif	/* CONFIG_OMAP_32K_TIMER */
-
-/*
- * ---------------------------------------------------------------------------
- * Timer initialization
- * ---------------------------------------------------------------------------
- */
-void __init omap_timer_init(void)
-{
-#if defined(CONFIG_OMAP_MPU_TIMER)
-	omap_init_mpu_timer();
-#elif defined(CONFIG_OMAP_32K_TIMER)
-	omap_init_32k_timer();
-#else
-#error No system timer selected in Kconfig!
-#endif
-}
-
-struct sys_timer omap_timer = {
-	.init		= omap_timer_init,
-	.offset		= NULL,		/* Initialized later */
-};
diff --git a/arch/arm/mach-omap/usb.c b/arch/arm/mach-omap/usb.c
deleted file mode 100644
--- a/arch/arm/mach-omap/usb.c
+++ /dev/null
@@ -1,594 +0,0 @@
-/*
- * arch/arm/mach-omap/usb.c -- platform level USB initialization
- *
- * Copyright (C) 2004 Texas Instruments, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#undef	DEBUG
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/usb_otg.h>
-
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/system.h>
-#include <asm/hardware.h>
-#include <asm/mach-types.h>
-
-#include <asm/arch/mux.h>
-#include <asm/arch/usb.h>
-#include <asm/arch/board.h>
-
-/* These routines should handle the standard chip-specific modes
- * for usb0/1/2 ports, covering basic mux and transceiver setup.
- * Call omap_usb_init() once, from INIT_MACHINE().
- *
- * Some board-*.c files will need to set up additional mux options,
- * like for suspend handling, vbus sensing, GPIOs, and the D+ pullup.
- */
-
-/* TESTED ON:
- *  - 1611B H2 (with usb1 mini-AB) using standard Mini-B or OTG cables
- *  - 5912 OSK OHCI (with usb0 standard-A), standard A-to-B cables
- *  - 5912 OSK UDC, with *nonstandard* A-to-A cable
- *  - 1510 Innovator UDC with bundled usb0 cable
- *  - 1510 Innovator OHCI with bundled usb1/usb2 cable
- *  - 1510 Innovator OHCI with custom usb0 cable, feeding 5V VBUS
- *  - 1710 custom development board using alternate pin group
- *  - 1710 H3 (with usb1 mini-AB) using standard Mini-B or OTG cables
- */
-
-/*-------------------------------------------------------------------------*/
-
-#ifdef	CONFIG_ARCH_OMAP_OTG
-
-static struct otg_transceiver *xceiv;
-
-/**
- * otg_get_transceiver - find the (single) OTG transceiver driver
- *
- * Returns the transceiver driver, after getting a refcount to it; or
- * null if there is no such transceiver.  The caller is responsible for
- * releasing that count.
- */
-struct otg_transceiver *otg_get_transceiver(void)
-{
-	if (xceiv)
-		get_device(xceiv->dev);
-	return xceiv;
-}
-EXPORT_SYMBOL(otg_get_transceiver);
-
-int otg_set_transceiver(struct otg_transceiver *x)
-{
-	if (xceiv && x)
-		return -EBUSY;
-	xceiv = x;
-	return 0;
-}
-EXPORT_SYMBOL(otg_set_transceiver);
-
-#endif
-
-/*-------------------------------------------------------------------------*/
-
-static u32 __init omap_usb0_init(unsigned nwires, unsigned is_device)
-{
-	u32	syscon1 = 0;
-
-	if (nwires == 0) {
-		if (!cpu_is_omap15xx()) {
-			/* pulldown D+/D- */
-			USB_TRANSCEIVER_CTRL_REG &= ~(3 << 1);
-		}
-		return 0;
-	}
-
-	if (is_device)
-		omap_cfg_reg(W4_USB_PUEN);
-
-	/* internal transceiver */
-	if (nwires == 2) {
-		// omap_cfg_reg(P9_USB_DP);
-		// omap_cfg_reg(R8_USB_DM);
-
-		if (cpu_is_omap15xx()) {
-			/* This works on 1510-Innovator */
-			return 0;
-		}
-
-		/* NOTES:
-		 *  - peripheral should configure VBUS detection!
-		 *  - only peripherals may use the internal D+/D- pulldowns
-		 *  - OTG support on this port not yet written
-		 */
-
-		USB_TRANSCEIVER_CTRL_REG &= ~(7 << 4);
-		if (!is_device)
-			USB_TRANSCEIVER_CTRL_REG |= (3 << 1);
-
-		return 3 << 16;
-	}
-
-	/* alternate pin config, external transceiver */
-	if (cpu_is_omap15xx()) {
-		printk(KERN_ERR "no usb0 alt pin config on 15xx\n");
-		return 0;
-	}
-
-	omap_cfg_reg(V6_USB0_TXD);
-	omap_cfg_reg(W9_USB0_TXEN);
-	omap_cfg_reg(W5_USB0_SE0);
-
-	/* NOTE:  SPEED and SUSP aren't configured here */
-
-	if (nwires != 3)
-		omap_cfg_reg(Y5_USB0_RCV);
-	if (nwires != 6)
-		USB_TRANSCEIVER_CTRL_REG &= ~CONF_USB2_UNI_R;
-
-	switch (nwires) {
-	case 3:
-		syscon1 = 2;
-		break;
-	case 4:
-		syscon1 = 1;
-		break;
-	case 6:
-		syscon1 = 3;
-		omap_cfg_reg(AA9_USB0_VP);
-		omap_cfg_reg(R9_USB0_VM);
-		USB_TRANSCEIVER_CTRL_REG |= CONF_USB2_UNI_R;
-		break;
-	default:
-		printk(KERN_ERR "illegal usb%d %d-wire transceiver\n",
-			0, nwires);
-	}
-	return syscon1 << 16;
-}
-
-static u32 __init omap_usb1_init(unsigned nwires)
-{
-	u32	syscon1 = 0;
-
-	if (nwires != 6 && !cpu_is_omap15xx())
-		USB_TRANSCEIVER_CTRL_REG &= ~CONF_USB1_UNI_R;
-	if (nwires == 0)
-		return 0;
-
-	/* external transceiver */
-	omap_cfg_reg(USB1_TXD);
-	omap_cfg_reg(USB1_TXEN);
-	if (cpu_is_omap15xx()) {
-		omap_cfg_reg(USB1_SEO);
-		omap_cfg_reg(USB1_SPEED);
-		// SUSP
-	} else if (cpu_is_omap1610() || cpu_is_omap5912()) {
-		omap_cfg_reg(W13_1610_USB1_SE0);
-		omap_cfg_reg(R13_1610_USB1_SPEED);
-		// SUSP
-	} else if (cpu_is_omap1710()) {
-		omap_cfg_reg(R13_1710_USB1_SE0);
-		// SUSP
-	} else {
-		pr_debug("usb unrecognized\n");
-	}
-	if (nwires != 3)
-		omap_cfg_reg(USB1_RCV);
-
-	switch (nwires) {
-	case 3:
-		syscon1 = 2;
-		break;
-	case 4:
-		syscon1 = 1;
-		break;
-	case 6:
-		syscon1 = 3;
-		omap_cfg_reg(USB1_VP);
-		omap_cfg_reg(USB1_VM);
-		if (!cpu_is_omap15xx())
-			USB_TRANSCEIVER_CTRL_REG |= CONF_USB1_UNI_R;
-		break;
-	default:
-		printk(KERN_ERR "illegal usb%d %d-wire transceiver\n",
-			1, nwires);
-	}
-	return syscon1 << 20;
-}
-
-static u32 __init omap_usb2_init(unsigned nwires, unsigned alt_pingroup)
-{
-	u32	syscon1 = 0;
-
-	/* NOTE erratum: must leave USB2_UNI_R set if usb0 in use */
-	if (alt_pingroup || nwires == 0)
-		return 0;
-	if (nwires != 6 && !cpu_is_omap15xx())
-		USB_TRANSCEIVER_CTRL_REG &= ~CONF_USB2_UNI_R;
-
-	/* external transceiver */
-	if (cpu_is_omap15xx()) {
-		omap_cfg_reg(USB2_TXD);
-		omap_cfg_reg(USB2_TXEN);
-		omap_cfg_reg(USB2_SEO);
-		if (nwires != 3)
-			omap_cfg_reg(USB2_RCV);
-		/* there is no USB2_SPEED */
-	} else if (cpu_is_omap16xx()) {
-		omap_cfg_reg(V6_USB2_TXD);
-		omap_cfg_reg(W9_USB2_TXEN);
-		omap_cfg_reg(W5_USB2_SE0);
-		if (nwires != 3)
-			omap_cfg_reg(Y5_USB2_RCV);
-		// FIXME omap_cfg_reg(USB2_SPEED);
-	} else {
-		pr_debug("usb unrecognized\n");
-	}
-	// omap_cfg_reg(USB2_SUSP);
-
-	switch (nwires) {
-	case 3:
-		syscon1 = 2;
-		break;
-	case 4:
-		syscon1 = 1;
-		break;
-	case 6:
-		syscon1 = 3;
-		if (cpu_is_omap15xx()) {
-			omap_cfg_reg(USB2_VP);
-			omap_cfg_reg(USB2_VM);
-		} else {
-			omap_cfg_reg(AA9_USB2_VP);
-			omap_cfg_reg(R9_USB2_VM);
-			USB_TRANSCEIVER_CTRL_REG |= CONF_USB2_UNI_R;
-		}
-		break;
-	default:
-		printk(KERN_ERR "illegal usb%d %d-wire transceiver\n",
-			2, nwires);
-	}
-	return syscon1 << 24;
-}
-
-/*-------------------------------------------------------------------------*/
-
-#if	defined(CONFIG_USB_GADGET_OMAP) || \
-	defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) || \
-	(defined(CONFIG_USB_OTG) && defined(CONFIG_ARCH_OMAP_OTG))
-static void usb_release(struct device *dev)
-{
-	/* normally not freed */
-}
-#endif
-
-#ifdef	CONFIG_USB_GADGET_OMAP
-
-static struct resource udc_resources[] = {
-	/* order is significant! */
-	{		/* registers */
-		.start		= IO_ADDRESS(UDC_BASE),
-		.end		= IO_ADDRESS(UDC_BASE + 0xff),
-		.flags		= IORESOURCE_MEM,
-	}, {		/* general IRQ */
-		.start		= IH2_BASE + 20,
-		.flags		= IORESOURCE_IRQ,
-	}, {		/* PIO IRQ */
-		.start		= IH2_BASE + 30,
-		.flags		= IORESOURCE_IRQ,
-	}, {		/* SOF IRQ */
-		.start		= IH2_BASE + 29,
-		.flags		= IORESOURCE_IRQ,
-	},
-};
-
-static u64 udc_dmamask = ~(u32)0;
-
-static struct platform_device udc_device = {
-	.name		= "omap_udc",
-	.id		= -1,
-	.dev = {
-		.release		= usb_release,
-		.dma_mask		= &udc_dmamask,
-		.coherent_dma_mask	= 0xffffffff,
-	},
-	.num_resources	= ARRAY_SIZE(udc_resources),
-	.resource	= udc_resources,
-};
-
-#endif
-
-#if	defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
-
-/* The dmamask must be set for OHCI to work */
-static u64 ohci_dmamask = ~(u32)0;
-
-static struct resource ohci_resources[] = {
-	{
-		.start	= OMAP_OHCI_BASE,
-		.end	= OMAP_OHCI_BASE + 4096,
-		.flags	= IORESOURCE_MEM,
-	},
-	{
-		.start	= INT_USB_HHC_1,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device ohci_device = {
-	.name			= "ohci",
-	.id			= -1,
-	.dev = {
-		.release		= usb_release,
-		.dma_mask		= &ohci_dmamask,
-		.coherent_dma_mask	= 0xffffffff,
-	},
-	.num_resources	= ARRAY_SIZE(ohci_resources),
-	.resource		= ohci_resources,
-};
-
-#endif
-
-#if	defined(CONFIG_USB_OTG) && defined(CONFIG_ARCH_OMAP_OTG)
-
-static struct resource otg_resources[] = {
-	/* order is significant! */
-	{
-		.start		= IO_ADDRESS(OTG_BASE),
-		.end		= IO_ADDRESS(OTG_BASE + 0xff),
-		.flags		= IORESOURCE_MEM,
-	}, {
-		.start		= IH2_BASE + 8,
-		.flags		= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device otg_device = {
-	.name		= "omap_otg",
-	.id		= -1,
-	.dev = {
-		.release		= usb_release,
-	},
-	.num_resources	= ARRAY_SIZE(otg_resources),
-	.resource	= otg_resources,
-};
-
-#endif
-
-/*-------------------------------------------------------------------------*/
-
-#define ULPD_CLOCK_CTRL_REG	__REG16(ULPD_CLOCK_CTRL)
-#define ULPD_SOFT_REQ_REG	__REG16(ULPD_SOFT_REQ)
-
-
-// FIXME correct answer depends on hmc_mode,
-// as does any nonzero value for config->otg port number
-#ifdef	CONFIG_USB_GADGET_OMAP
-#define	is_usb0_device(config)	1
-#else
-#define	is_usb0_device(config)	0
-#endif
-
-/*-------------------------------------------------------------------------*/
-
-#ifdef	CONFIG_ARCH_OMAP_OTG
-
-void __init
-omap_otg_init(struct omap_usb_config *config)
-{
-	u32		syscon = OTG_SYSCON_1_REG & 0xffff;
-	int		status;
-	int		alt_pingroup = 0;
-
-	/* NOTE:  no bus or clock setup (yet?) */
-
-	syscon = OTG_SYSCON_1_REG & 0xffff;
-	if (!(syscon & OTG_RESET_DONE))
-		pr_debug("USB resets not complete?\n");
-
-	// OTG_IRQ_EN_REG = 0;
-
-	/* pin muxing and transceiver pinouts */
-	if (config->pins[0] > 2)	/* alt pingroup 2 */
-		alt_pingroup = 1;
-	syscon |= omap_usb0_init(config->pins[0], is_usb0_device(config));
-	syscon |= omap_usb1_init(config->pins[1]);
-	syscon |= omap_usb2_init(config->pins[2], alt_pingroup);
-	pr_debug("OTG_SYSCON_1_REG = %08x\n", syscon);
-	OTG_SYSCON_1_REG = syscon;
-
-	syscon = config->hmc_mode;
-	syscon |= USBX_SYNCHRO | (4 << 16) /* B_ASE0_BRST */;
-#ifdef	CONFIG_USB_OTG
-	if (config->otg)
-		syscon |= OTG_EN;
-#endif
-	pr_debug("USB_TRANSCEIVER_CTRL_REG = %03x\n", USB_TRANSCEIVER_CTRL_REG);
-	pr_debug("OTG_SYSCON_2_REG = %08x\n", syscon);
-	OTG_SYSCON_2_REG = syscon;
-
-	printk("USB: hmc %d", config->hmc_mode);
-	if (alt_pingroup)
-		printk(", usb2 alt %d wires", config->pins[2]);
-	else if (config->pins[0])
-		printk(", usb0 %d wires%s", config->pins[0],
-			is_usb0_device(config) ? " (dev)" : "");
-	if (config->pins[1])
-		printk(", usb1 %d wires", config->pins[1]);
-	if (!alt_pingroup && config->pins[2])
-		printk(", usb2 %d wires", config->pins[2]);
-	if (config->otg)
-		printk(", Mini-AB on usb%d", config->otg - 1);
-	printk("\n");
-
-	/* leave USB clocks/controllers off until needed */
-	ULPD_SOFT_REQ_REG &= ~SOFT_USB_CLK_REQ;
-	ULPD_CLOCK_CTRL_REG &= ~USB_MCLK_EN;
-	ULPD_CLOCK_CTRL_REG |= DIS_USB_PVCI_CLK;
-	syscon = OTG_SYSCON_1_REG;
-	syscon |= HST_IDLE_EN|DEV_IDLE_EN|OTG_IDLE_EN;
-
-#ifdef	CONFIG_USB_GADGET_OMAP
-	if (config->otg || config->register_dev) {
-		syscon &= ~DEV_IDLE_EN;
-		udc_device.dev.platform_data = config;
-		/* FIXME patch IRQ numbers for omap730 */
-		status = platform_device_register(&udc_device);
-		if (status)
-			pr_debug("can't register UDC device, %d\n", status);
-	}
-#endif
-
-#if	defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
-	if (config->otg || config->register_host) {
-		syscon &= ~HST_IDLE_EN;
-		ohci_device.dev.platform_data = config;
-		if (cpu_is_omap730())
-			ohci_resources[1].start = INT_730_USB_HHC_1;
-		status = platform_device_register(&ohci_device);
-		if (status)
-			pr_debug("can't register OHCI device, %d\n", status);
-	}
-#endif
-
-#ifdef	CONFIG_USB_OTG
-	if (config->otg) {
-		syscon &= ~OTG_IDLE_EN;
-		otg_device.dev.platform_data = config;
-		if (cpu_is_omap730())
-			otg_resources[1].start = INT_730_USB_OTG;
-		status = platform_device_register(&otg_device);
-		if (status)
-			pr_debug("can't register OTG device, %d\n", status);
-	}
-#endif
-	pr_debug("OTG_SYSCON_1_REG = %08x\n", syscon);
-	OTG_SYSCON_1_REG = syscon;
-
-	status = 0;
-}
-
-#else
-static inline void omap_otg_init(struct omap_usb_config *config) {}
-#endif
-
-/*-------------------------------------------------------------------------*/
-
-#ifdef	CONFIG_ARCH_OMAP1510
-
-#define ULPD_DPLL_CTRL_REG	__REG16(ULPD_DPLL_CTRL)
-#define DPLL_IOB		(1 << 13)
-#define DPLL_PLL_ENABLE		(1 << 4)
-#define DPLL_LOCK		(1 << 0)
-
-#define ULPD_APLL_CTRL_REG	__REG16(ULPD_APLL_CTRL)
-#define APLL_NDPLL_SWITCH	(1 << 0)
-
-
-static void __init omap_1510_usb_init(struct omap_usb_config *config)
-{
-	int status;
-	unsigned int val;
-
-	omap_usb0_init(config->pins[0], is_usb0_device(config));
-	omap_usb1_init(config->pins[1]);
-	omap_usb2_init(config->pins[2], 0);
-
-	val = omap_readl(MOD_CONF_CTRL_0) & ~(0x3f << 1);
-	val |= (config->hmc_mode << 1);
-	omap_writel(val, MOD_CONF_CTRL_0);
-
-	printk("USB: hmc %d", config->hmc_mode);
-	if (config->pins[0])
-		printk(", usb0 %d wires%s", config->pins[0],
-			is_usb0_device(config) ? " (dev)" : "");
-	if (config->pins[1])
-		printk(", usb1 %d wires", config->pins[1]);
-	if (config->pins[2])
-		printk(", usb2 %d wires", config->pins[2]);
-	printk("\n");
-
-	/* use DPLL for 48 MHz function clock */
-	pr_debug("APLL %04x DPLL %04x REQ %04x\n", ULPD_APLL_CTRL_REG,
-			ULPD_DPLL_CTRL_REG, ULPD_SOFT_REQ_REG);
-	ULPD_APLL_CTRL_REG &= ~APLL_NDPLL_SWITCH;
-	ULPD_DPLL_CTRL_REG |= DPLL_IOB | DPLL_PLL_ENABLE;
-	ULPD_SOFT_REQ_REG |= SOFT_UDC_REQ | SOFT_DPLL_REQ;
-	while (!(ULPD_DPLL_CTRL_REG & DPLL_LOCK))
-		cpu_relax();
-
-#ifdef	CONFIG_USB_GADGET_OMAP
-	if (config->register_dev) {
-		udc_device.dev.platform_data = config;
-		status = platform_device_register(&udc_device);
-		if (status)
-			pr_debug("can't register UDC device, %d\n", status);
-		/* udc driver gates 48MHz by D+ pullup */
-	}
-#endif
-
-#if	defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
-	if (config->register_host) {
-		ohci_device.dev.platform_data = config;
-		status = platform_device_register(&ohci_device);
-		if (status)
-			pr_debug("can't register OHCI device, %d\n", status);
-		/* hcd explicitly gates 48MHz */
-	}
-#endif
-}
-
-#else
-static inline void omap_1510_usb_init(struct omap_usb_config *config) {}
-#endif
-
-/*-------------------------------------------------------------------------*/
-
-static struct omap_usb_config platform_data;
-
-static int __init
-omap_usb_init(void)
-{
-	const struct omap_usb_config *config;
-
-	config = omap_get_config(OMAP_TAG_USB, struct omap_usb_config);
-	if (config == NULL) {
-		printk(KERN_ERR "USB: No board-specific "
-				"platform config found\n");
-		return -ENODEV;
-	}
-	platform_data = *config;
-
-	if (cpu_is_omap730() || cpu_is_omap16xx())
-		omap_otg_init(&platform_data);
-	else if (cpu_is_omap15xx())
-		omap_1510_usb_init(&platform_data);
-	else {
-		printk(KERN_ERR "USB: No init for your chip yet\n");
-		return -ENODEV;
-	}
-	return 0;
-}
-
-subsys_initcall(omap_usb_init);
diff --git a/arch/arm/mach-omap1/Kconfig b/arch/arm/mach-omap1/Kconfig
new file mode 100644
--- /dev/null
+++ b/arch/arm/mach-omap1/Kconfig
@@ -0,0 +1,144 @@
+comment "OMAP Core Type"
+	depends on ARCH_OMAP1
+
+config ARCH_OMAP730
+	depends on ARCH_OMAP1
+	bool "OMAP730 Based System"
+	select ARCH_OMAP_OTG
+
+config ARCH_OMAP1510
+	depends on ARCH_OMAP1
+	default y
+	bool "OMAP1510 Based System"
+
+config ARCH_OMAP16XX
+	depends on ARCH_OMAP1
+	bool "OMAP16xx Based System"
+	select ARCH_OMAP_OTG
+
+comment "OMAP Board Type"
+	depends on ARCH_OMAP1
+
+config MACH_OMAP_INNOVATOR
+	bool "TI Innovator"
+	depends on ARCH_OMAP1 && (ARCH_OMAP1510 || ARCH_OMAP16XX)
+	help
+          TI OMAP 1510 or 1610 Innovator board support. Say Y here if you
+          have such a board.
+
+config MACH_OMAP_H2
+	bool "TI H2 Support"
+	depends on ARCH_OMAP1 && ARCH_OMAP16XX
+    	help
+	  TI OMAP 1610/1611B H2 board support. Say Y here if you have such
+	  a board.
+
+config MACH_OMAP_H3
+	bool "TI H3 Support"
+	depends on ARCH_OMAP1 && ARCH_OMAP16XX
+    	help
+	  TI OMAP 1710 H3 board support. Say Y here if you have such
+	  a board.
+
+config MACH_OMAP_OSK
+	bool "TI OSK Support"
+	depends on ARCH_OMAP1 && ARCH_OMAP16XX
+    	help
+	  TI OMAP 5912 OSK (OMAP Starter Kit) board support. Say Y here
+          if you have such a board.
+
+config MACH_OMAP_PERSEUS2
+	bool "TI Perseus2"
+	depends on ARCH_OMAP1 && ARCH_OMAP730
+    	help
+	  Support for TI OMAP 730 Perseus2 board. Say Y here if you have such
+	  a board.
+
+config MACH_VOICEBLUE
+	bool "Voiceblue"
+	depends on ARCH_OMAP1 && ARCH_OMAP1510
+	help
+	  Support for Voiceblue GSM/VoIP gateway. Say Y here if you have
+	  such a board.
+
+config MACH_NETSTAR
+	bool "NetStar"
+	depends on ARCH_OMAP1 && ARCH_OMAP1510
+	help
+	  Support for NetStar PBX. Say Y here if you have such a board.
+
+config MACH_OMAP_GENERIC
+	bool "Generic OMAP board"
+	depends on ARCH_OMAP1 && (ARCH_OMAP1510 || ARCH_OMAP16XX)
+	help
+          Support for generic OMAP-1510, 1610 or 1710 board with
+          no FPGA. Can be used as template for porting Linux to
+          custom OMAP boards. Say Y here if you have a custom
+          board.
+
+comment "OMAP CPU Speed"
+	depends on ARCH_OMAP1
+
+config OMAP_CLOCKS_SET_BY_BOOTLOADER
+	bool "OMAP clocks set by bootloader"
+	depends on ARCH_OMAP1
+	help
+	  Enable this option to prevent the kernel from overriding the clock
+	  frequencies programmed by bootloader for MPU, DSP, MMUs, TC,
+	  internal LCD controller and MPU peripherals.
+
+config OMAP_ARM_216MHZ
+	bool "OMAP ARM 216 MHz CPU (1710 only)"
+        depends on ARCH_OMAP1 && ARCH_OMAP16XX
+        help
+          Enable 216 MHz clock for OMAP1710 CPU. If unsure, say N.
+
+config OMAP_ARM_195MHZ
+	bool "OMAP ARM 195 MHz CPU"
+	depends on ARCH_OMAP1 && ARCH_OMAP730
+	help
+          Enable 195MHz clock for OMAP CPU. If unsure, say N.
+
+config OMAP_ARM_192MHZ
+	bool "OMAP ARM 192 MHz CPU"
+	depends on ARCH_OMAP1 && ARCH_OMAP16XX
+	help
+          Enable 192MHz clock for OMAP CPU. If unsure, say N.
+
+config OMAP_ARM_182MHZ
+	bool "OMAP ARM 182 MHz CPU"
+	depends on ARCH_OMAP1 && ARCH_OMAP730
+	help
+          Enable 182MHz clock for OMAP CPU. If unsure, say N.
+
+config OMAP_ARM_168MHZ
+	bool "OMAP ARM 168 MHz CPU"
+	depends on ARCH_OMAP1 && (ARCH_OMAP1510 || ARCH_OMAP16XX || ARCH_OMAP730)
+	help
+          Enable 168MHz clock for OMAP CPU. If unsure, say N.
+
+config OMAP_ARM_150MHZ
+	bool "OMAP ARM 150 MHz CPU"
+	depends on ARCH_OMAP1 && ARCH_OMAP1510
+	help
+	  Enable 150MHz clock for OMAP CPU. If unsure, say N.
+
+config OMAP_ARM_120MHZ
+	bool "OMAP ARM 120 MHz CPU"
+	depends on ARCH_OMAP1 && (ARCH_OMAP1510 || ARCH_OMAP16XX || ARCH_OMAP730)
+	help
+          Enable 120MHz clock for OMAP CPU. If unsure, say N.
+
+config OMAP_ARM_60MHZ
+	bool "OMAP ARM 60 MHz CPU"
+	depends on ARCH_OMAP1 && (ARCH_OMAP1510 || ARCH_OMAP16XX || ARCH_OMAP730)
+        default y
+	help
+          Enable 60MHz clock for OMAP CPU. If unsure, say Y.
+
+config OMAP_ARM_30MHZ
+	bool "OMAP ARM 30 MHz CPU"
+	depends on ARCH_OMAP1 && (ARCH_OMAP1510 || ARCH_OMAP16XX || ARCH_OMAP730)
+	help
+          Enable 30MHz clock for OMAP CPU. If unsure, say N.
+
diff --git a/arch/arm/mach-omap1/Makefile b/arch/arm/mach-omap1/Makefile
new file mode 100644
--- /dev/null
+++ b/arch/arm/mach-omap1/Makefile
@@ -0,0 +1,30 @@
+#
+# Makefile for the linux kernel.
+#
+
+# Common support
+obj-y := io.o id.o irq.o time.o serial.o
+led-y := leds.o
+
+# Specific board support
+obj-$(CONFIG_MACH_OMAP_H2)		+= board-h2.o
+obj-$(CONFIG_MACH_OMAP_INNOVATOR)	+= board-innovator.o
+obj-$(CONFIG_MACH_OMAP_GENERIC)		+= board-generic.o
+obj-$(CONFIG_MACH_OMAP_PERSEUS2)	+= board-perseus2.o
+obj-$(CONFIG_MACH_OMAP_OSK)		+= board-osk.o
+obj-$(CONFIG_MACH_OMAP_H3)		+= board-h3.o
+obj-$(CONFIG_MACH_VOICEBLUE)		+= board-voiceblue.o
+obj-$(CONFIG_MACH_NETSTAR)		+= board-netstar.o
+
+ifeq ($(CONFIG_ARCH_OMAP1510),y)
+# Innovator-1510 FPGA
+obj-$(CONFIG_MACH_OMAP_INNOVATOR)	+= fpga.o
+endif
+
+# LEDs support
+led-$(CONFIG_MACH_OMAP_H2)		+= leds-h2p2-debug.o
+led-$(CONFIG_MACH_OMAP_INNOVATOR)	+= leds-innovator.o
+led-$(CONFIG_MACH_OMAP_PERSEUS2)	+= leds-h2p2-debug.o
+led-$(CONFIG_MACH_OMAP_OSK)		+= leds-osk.o
+obj-$(CONFIG_LEDS)			+= $(led-y)
+
diff --git a/arch/arm/mach-omap1/Makefile.boot b/arch/arm/mach-omap1/Makefile.boot
new file mode 100644
--- /dev/null
+++ b/arch/arm/mach-omap1/Makefile.boot
@@ -0,0 +1,3 @@
+   zreladdr-y		:= 0x10008000
+params_phys-y		:= 0x10000100
+initrd_phys-y		:= 0x10800000
diff --git a/arch/arm/mach-omap1/board-generic.c b/arch/arm/mach-omap1/board-generic.c
new file mode 100644
--- /dev/null
+++ b/arch/arm/mach-omap1/board-generic.c
@@ -0,0 +1,99 @@
+/*
+ * linux/arch/arm/mach-omap1/board-generic.c
+ *
+ * Modified from board-innovator1510.c
+ *
+ * Code for generic OMAP board. Should work on many OMAP systems where
+ * the device drivers take care of all the necessary hardware initialization.
+ * Do not put any board specific code to this file; create a new machine
+ * type if you need custom low-level initializations.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/device.h>
+
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <asm/arch/gpio.h>
+#include <asm/arch/mux.h>
+#include <asm/arch/usb.h>
+#include <asm/arch/board.h>
+#include <asm/arch/common.h>
+
+static int __initdata generic_serial_ports[OMAP_MAX_NR_PORTS] = {1, 1, 1};
+
+static void __init omap_generic_init_irq(void)
+{
+	omap_init_irq();
+}
+
+/* assume no Mini-AB port */
+
+#ifdef CONFIG_ARCH_OMAP1510
+static struct omap_usb_config generic1510_usb_config __initdata = {
+	.register_host	= 1,
+	.register_dev	= 1,
+	.hmc_mode	= 16,
+	.pins[0]	= 3,
+};
+#endif
+
+#if defined(CONFIG_ARCH_OMAP16XX)
+static struct omap_usb_config generic1610_usb_config __initdata = {
+	.register_host	= 1,
+	.register_dev	= 1,
+	.hmc_mode	= 16,
+	.pins[0]	= 6,
+};
+#endif
+
+static struct omap_board_config_kernel generic_config[] = {
+	{ OMAP_TAG_USB,           NULL },
+};
+
+static void __init omap_generic_init(void)
+{
+	/*
+	 * Make sure the serial ports are muxed on at this point.
+	 * You have to mux them off in device drivers later on
+	 * if not needed.
+	 */
+#ifdef CONFIG_ARCH_OMAP1510
+	if (cpu_is_omap1510()) {
+		generic_config[0].data = &generic1510_usb_config;
+	}
+#endif
+#if defined(CONFIG_ARCH_OMAP16XX)
+	if (!cpu_is_omap1510()) {
+		generic_config[0].data = &generic1610_usb_config;
+	}
+#endif
+	omap_board_config = generic_config;
+	omap_board_config_size = ARRAY_SIZE(generic_config);
+	omap_serial_init(generic_serial_ports);
+}
+
+static void __init omap_generic_map_io(void)
+{
+	omap_map_common_io()
+}
+
+MACHINE_START(OMAP_GENERIC, "Generic OMAP1510/1610/1710")
+	/* Maintainer: Tony Lindgren <tony@atomide.com> */
+	.phys_ram	= 0x10000000,
+	.phys_io	= 0xfff00000,
+	.io_pg_offst	= ((0xfef00000) >> 18) & 0xfffc,
+	.boot_params	= 0x10000100,
+	.map_io		= omap_generic_map_io,
+	.init_irq	= omap_generic_init_irq,
+	.init_machine	= omap_generic_init,
+	.timer		= &omap_timer,
+MACHINE_END
diff --git a/arch/arm/mach-omap1/board-h2.c b/arch/arm/mach-omap1/board-h2.c
new file mode 100644
--- /dev/null
+++ b/arch/arm/mach-omap1/board-h2.c
@@ -0,0 +1,188 @@
+/*
+ * linux/arch/arm/mach-omap1/board-h2.c
+ *
+ * Board specific inits for OMAP-1610 H2
+ *
+ * Copyright (C) 2001 RidgeRun, Inc.
+ * Author: Greg Lonnon <glonnon@ridgerun.com>
+ *
+ * Copyright (C) 2002 MontaVista Software, Inc.
+ *
+ * Separated FPGA interrupts from innovator1510.c and cleaned up for 2.6
+ * Copyright (C) 2004 Nokia Corporation by Tony Lindrgen <tony@atomide.com>
+ *
+ * H2 specific changes and cleanup
+ * Copyright (C) 2004 Nokia Corporation by Imre Deak <imre.deak@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/delay.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
+#include <asm/mach/map.h>
+
+#include <asm/arch/gpio.h>
+#include <asm/arch/tc.h>
+#include <asm/arch/usb.h>
+#include <asm/arch/common.h>
+
+extern int omap_gpio_init(void);
+
+static int __initdata h2_serial_ports[OMAP_MAX_NR_PORTS] = {1, 1, 1};
+
+static struct mtd_partition h2_partitions[] = {
+	/* bootloader (U-Boot, etc) in first sector */
+	{
+	      .name		= "bootloader",
+	      .offset		= 0,
+	      .size		= SZ_128K,
+	      .mask_flags	= MTD_WRITEABLE, /* force read-only */
+	},
+	/* bootloader params in the next sector */
+	{
+	      .name		= "params",
+	      .offset		= MTDPART_OFS_APPEND,
+	      .size		= SZ_128K,
+	      .mask_flags	= 0,
+	},
+	/* kernel */
+	{
+	      .name		= "kernel",
+	      .offset		= MTDPART_OFS_APPEND,
+	      .size		= SZ_2M,
+	      .mask_flags	= 0
+	},
+	/* file system */
+	{
+	      .name		= "filesystem",
+	      .offset		= MTDPART_OFS_APPEND,
+	      .size		= MTDPART_SIZ_FULL,
+	      .mask_flags	= 0
+	}
+};
+
+static struct flash_platform_data h2_flash_data = {
+	.map_name	= "cfi_probe",
+	.width		= 2,
+	.parts		= h2_partitions,
+	.nr_parts	= ARRAY_SIZE(h2_partitions),
+};
+
+static struct resource h2_flash_resource = {
+	.start		= OMAP_CS2B_PHYS,
+	.end		= OMAP_CS2B_PHYS + OMAP_CS2B_SIZE - 1,
+	.flags		= IORESOURCE_MEM,
+};
+
+static struct platform_device h2_flash_device = {
+	.name		= "omapflash",
+	.id		= 0,
+	.dev		= {
+		.platform_data	= &h2_flash_data,
+	},
+	.num_resources	= 1,
+	.resource	= &h2_flash_resource,
+};
+
+static struct resource h2_smc91x_resources[] = {
+	[0] = {
+		.start	= OMAP1610_ETHR_START,		/* Physical */
+		.end	= OMAP1610_ETHR_START + 0xf,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= OMAP_GPIO_IRQ(0),
+		.end	= OMAP_GPIO_IRQ(0),
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device h2_smc91x_device = {
+	.name		= "smc91x",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(h2_smc91x_resources),
+	.resource	= h2_smc91x_resources,
+};
+
+static struct platform_device *h2_devices[] __initdata = {
+	&h2_flash_device,
+	&h2_smc91x_device,
+};
+
+static void __init h2_init_smc91x(void)
+{
+	if ((omap_request_gpio(0)) < 0) {
+		printk("Error requesting gpio 0 for smc91x irq\n");
+		return;
+	}
+	omap_set_gpio_edge_ctrl(0, OMAP_GPIO_FALLING_EDGE);
+}
+
+void h2_init_irq(void)
+{
+	omap_init_irq();
+	omap_gpio_init();
+	h2_init_smc91x();
+}
+
+static struct omap_usb_config h2_usb_config __initdata = {
+	/* usb1 has a Mini-AB port and external isp1301 transceiver */
+	.otg		= 2,
+
+#ifdef	CONFIG_USB_GADGET_OMAP
+	.hmc_mode	= 19,	// 0:host(off) 1:dev|otg 2:disabled
+	// .hmc_mode	= 21,	// 0:host(off) 1:dev(loopback) 2:host(loopback)
+#elif	defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
+	/* needs OTG cable, or NONSTANDARD (B-to-MiniB) */
+	.hmc_mode	= 20,	// 1:dev|otg(off) 1:host 2:disabled
+#endif
+
+	.pins[1]	= 3,
+};
+
+static struct omap_mmc_config h2_mmc_config __initdata = {
+	.mmc_blocks		= 1,
+	.mmc1_power_pin		= -1,	/* tps65010 gpio3 */
+	.mmc1_switch_pin	= OMAP_MPUIO(1),
+};
+
+static struct omap_board_config_kernel h2_config[] = {
+	{ OMAP_TAG_USB,           &h2_usb_config },
+	{ OMAP_TAG_MMC,           &h2_mmc_config },
+};
+
+static void __init h2_init(void)
+{
+	platform_add_devices(h2_devices, ARRAY_SIZE(h2_devices));
+	omap_board_config = h2_config;
+	omap_board_config_size = ARRAY_SIZE(h2_config);
+}
+
+static void __init h2_map_io(void)
+{
+	omap_map_common_io();
+	omap_serial_init(h2_serial_ports);
+}
+
+MACHINE_START(OMAP_H2, "TI-H2")
+	/* Maintainer: Imre Deak <imre.deak@nokia.com> */
+	.phys_ram	= 0x10000000,
+	.phys_io	= 0xfff00000,
+	.io_pg_offst	= ((0xfef00000) >> 18) & 0xfffc,
+	.boot_params	= 0x10000100,
+	.map_io		= h2_map_io,
+	.init_irq	= h2_init_irq,
+	.init_machine	= h2_init,
+	.timer		= &omap_timer,
+MACHINE_END
diff --git a/arch/arm/mach-omap1/board-h3.c b/arch/arm/mach-omap1/board-h3.c
new file mode 100644
--- /dev/null
+++ b/arch/arm/mach-omap1/board-h3.c
@@ -0,0 +1,206 @@
+/*
+ * linux/arch/arm/mach-omap1/board-h3.c
+ *
+ * This file contains OMAP1710 H3 specific code.
+ *
+ * Copyright (C) 2004 Texas Instruments, Inc.
+ * Copyright (C) 2002 MontaVista Software, Inc.
+ * Copyright (C) 2001 RidgeRun, Inc.
+ * Author: RidgeRun, Inc.
+ *         Greg Lonnon (glonnon@ridgerun.com) or info@ridgerun.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/major.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/setup.h>
+#include <asm/page.h>
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
+#include <asm/mach/map.h>
+
+#include <asm/arch/gpio.h>
+#include <asm/arch/irqs.h>
+#include <asm/arch/mux.h>
+#include <asm/arch/tc.h>
+#include <asm/arch/usb.h>
+#include <asm/arch/common.h>
+
+extern int omap_gpio_init(void);
+
+static int __initdata h3_serial_ports[OMAP_MAX_NR_PORTS] = {1, 1, 1};
+
+static struct mtd_partition h3_partitions[] = {
+	/* bootloader (U-Boot, etc) in first sector */
+	{
+	      .name		= "bootloader",
+	      .offset		= 0,
+	      .size		= SZ_128K,
+	      .mask_flags	= MTD_WRITEABLE, /* force read-only */
+	},
+	/* bootloader params in the next sector */
+	{
+	      .name		= "params",
+	      .offset		= MTDPART_OFS_APPEND,
+	      .size		= SZ_128K,
+	      .mask_flags	= 0,
+	},
+	/* kernel */
+	{
+	      .name		= "kernel",
+	      .offset		= MTDPART_OFS_APPEND,
+	      .size		= SZ_2M,
+	      .mask_flags	= 0
+	},
+	/* file system */
+	{
+	      .name		= "filesystem",
+	      .offset		= MTDPART_OFS_APPEND,
+	      .size		= MTDPART_SIZ_FULL,
+	      .mask_flags	= 0
+	}
+};
+
+static struct flash_platform_data h3_flash_data = {
+	.map_name	= "cfi_probe",
+	.width		= 2,
+	.parts		= h3_partitions,
+	.nr_parts	= ARRAY_SIZE(h3_partitions),
+};
+
+static struct resource h3_flash_resource = {
+	.start		= OMAP_CS2B_PHYS,
+	.end		= OMAP_CS2B_PHYS + OMAP_CS2B_SIZE - 1,
+	.flags		= IORESOURCE_MEM,
+};
+
+static struct platform_device flash_device = {
+	.name		= "omapflash",
+	.id		= 0,
+	.dev		= {
+		.platform_data	= &h3_flash_data,
+	},
+	.num_resources	= 1,
+	.resource	= &h3_flash_resource,
+};
+
+static struct resource smc91x_resources[] = {
+	[0] = {
+		.start	= OMAP1710_ETHR_START,		/* Physical */
+		.end	= OMAP1710_ETHR_START + 0xf,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= OMAP_GPIO_IRQ(40),
+		.end	= OMAP_GPIO_IRQ(40),
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device smc91x_device = {
+	.name		= "smc91x",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(smc91x_resources),
+	.resource	= smc91x_resources,
+};
+
+#define GPTIMER_BASE		0xFFFB1400
+#define GPTIMER_REGS(x)	(0xFFFB1400 + (x * 0x800))
+#define GPTIMER_REGS_SIZE	0x46
+
+static struct resource intlat_resources[] = {
+	[0] = {
+		.start  = GPTIMER_REGS(0),	      /* Physical */
+		.end    = GPTIMER_REGS(0) + GPTIMER_REGS_SIZE,
+		.flags  = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start  = INT_1610_GPTIMER1,
+		.end    = INT_1610_GPTIMER1,
+		.flags  = IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device intlat_device = {
+	.name	   = "omap_intlat",
+	.id	     = 0,
+	.num_resources  = ARRAY_SIZE(intlat_resources),
+	.resource       = intlat_resources,
+};
+
+static struct platform_device *devices[] __initdata = {
+	&flash_device,
+        &smc91x_device,
+	&intlat_device,
+};
+
+static struct omap_usb_config h3_usb_config __initdata = {
+	/* usb1 has a Mini-AB port and external isp1301 transceiver */
+	.otg	    = 2,
+
+#ifdef CONFIG_USB_GADGET_OMAP
+	.hmc_mode       = 19,   /* 0:host(off) 1:dev|otg 2:disabled */
+#elif  defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
+	/* NONSTANDARD CABLE NEEDED (B-to-Mini-B) */
+	.hmc_mode       = 20,   /* 1:dev|otg(off) 1:host 2:disabled */
+#endif
+
+	.pins[1]	= 3,
+};
+
+static struct omap_board_config_kernel h3_config[] = {
+	{ OMAP_TAG_USB,	 &h3_usb_config },
+};
+
+static void __init h3_init(void)
+{
+	(void) platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+static void __init h3_init_smc91x(void)
+{
+	omap_cfg_reg(W15_1710_GPIO40);
+	if (omap_request_gpio(40) < 0) {
+		printk("Error requesting gpio 40 for smc91x irq\n");
+		return;
+	}
+	omap_set_gpio_edge_ctrl(40, OMAP_GPIO_FALLING_EDGE);
+}
+
+void h3_init_irq(void)
+{
+	omap_init_irq();
+	omap_gpio_init();
+	h3_init_smc91x();
+}
+
+static void __init h3_map_io(void)
+{
+	omap_map_common_io();
+	omap_serial_init(h3_serial_ports);
+}
+
+MACHINE_START(OMAP_H3, "TI OMAP1710 H3 board")
+	/* Maintainer: Texas Instruments, Inc. */
+	.phys_ram	= 0x10000000,
+	.phys_io	= 0xfff00000,
+	.io_pg_offst	= ((0xfef00000) >> 18) & 0xfffc,
+	.boot_params	= 0x10000100,
+	.map_io		= h3_map_io,
+	.init_irq	= h3_init_irq,
+	.init_machine	= h3_init,
+	.timer		= &omap_timer,
+MACHINE_END
diff --git a/arch/arm/mach-omap1/board-innovator.c b/arch/arm/mach-omap1/board-innovator.c
new file mode 100644
--- /dev/null
+++ b/arch/arm/mach-omap1/board-innovator.c
@@ -0,0 +1,281 @@
+/*
+ * linux/arch/arm/mach-omap1/board-innovator.c
+ *
+ * Board specific inits for OMAP-1510 and OMAP-1610 Innovator
+ *
+ * Copyright (C) 2001 RidgeRun, Inc.
+ * Author: Greg Lonnon <glonnon@ridgerun.com>
+ *
+ * Copyright (C) 2002 MontaVista Software, Inc.
+ *
+ * Separated FPGA interrupts from innovator1510.c and cleaned up for 2.6
+ * Copyright (C) 2004 Nokia Corporation by Tony Lindrgen <tony@atomide.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/delay.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
+#include <asm/mach/map.h>
+
+#include <asm/arch/fpga.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/tc.h>
+#include <asm/arch/usb.h>
+#include <asm/arch/common.h>
+
+static int __initdata innovator_serial_ports[OMAP_MAX_NR_PORTS] = {1, 1, 1};
+
+static struct mtd_partition innovator_partitions[] = {
+	/* bootloader (U-Boot, etc) in first sector */
+	{
+	      .name		= "bootloader",
+	      .offset		= 0,
+	      .size		= SZ_128K,
+	      .mask_flags	= MTD_WRITEABLE, /* force read-only */
+	},
+	/* bootloader params in the next sector */
+	{
+	      .name		= "params",
+	      .offset		= MTDPART_OFS_APPEND,
+	      .size		= SZ_128K,
+	      .mask_flags	= 0,
+	},
+	/* kernel */
+	{
+	      .name		= "kernel",
+	      .offset		= MTDPART_OFS_APPEND,
+	      .size		= SZ_2M,
+	      .mask_flags	= 0
+	},
+	/* rest of flash1 is a file system */
+	{
+	      .name		= "rootfs",
+	      .offset		= MTDPART_OFS_APPEND,
+	      .size		= SZ_16M - SZ_2M - 2 * SZ_128K,
+	      .mask_flags	= 0
+	},
+	/* file system */
+	{
+	      .name		= "filesystem",
+	      .offset		= MTDPART_OFS_APPEND,
+	      .size		= MTDPART_SIZ_FULL,
+	      .mask_flags	= 0
+	}
+};
+
+static struct flash_platform_data innovator_flash_data = {
+	.map_name	= "cfi_probe",
+	.width		= 2,
+	.parts		= innovator_partitions,
+	.nr_parts	= ARRAY_SIZE(innovator_partitions),
+};
+
+static struct resource innovator_flash_resource = {
+	.start		= OMAP_CS0_PHYS,
+	.end		= OMAP_CS0_PHYS + SZ_32M - 1,
+	.flags		= IORESOURCE_MEM,
+};
+
+static struct platform_device innovator_flash_device = {
+	.name		= "omapflash",
+	.id		= 0,
+	.dev		= {
+		.platform_data	= &innovator_flash_data,
+	},
+	.num_resources	= 1,
+	.resource	= &innovator_flash_resource,
+};
+
+#ifdef CONFIG_ARCH_OMAP1510
+
+/* Only FPGA needs to be mapped here. All others are done with ioremap */
+static struct map_desc innovator1510_io_desc[] __initdata = {
+{ OMAP1510_FPGA_BASE, OMAP1510_FPGA_START, OMAP1510_FPGA_SIZE,
+	MT_DEVICE },
+};
+
+static struct resource innovator1510_smc91x_resources[] = {
+	[0] = {
+		.start	= OMAP1510_FPGA_ETHR_START,	/* Physical */
+		.end	= OMAP1510_FPGA_ETHR_START + 0xf,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= OMAP1510_INT_ETHER,
+		.end	= OMAP1510_INT_ETHER,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device innovator1510_smc91x_device = {
+	.name		= "smc91x",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(innovator1510_smc91x_resources),
+	.resource	= innovator1510_smc91x_resources,
+};
+
+static struct platform_device *innovator1510_devices[] __initdata = {
+	&innovator_flash_device,
+	&innovator1510_smc91x_device,
+};
+
+#endif /* CONFIG_ARCH_OMAP1510 */
+
+#ifdef CONFIG_ARCH_OMAP16XX
+
+static struct resource innovator1610_smc91x_resources[] = {
+	[0] = {
+		.start	= INNOVATOR1610_ETHR_START,		/* Physical */
+		.end	= INNOVATOR1610_ETHR_START + 0xf,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= OMAP_GPIO_IRQ(0),
+		.end	= OMAP_GPIO_IRQ(0),
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device innovator1610_smc91x_device = {
+	.name		= "smc91x",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(innovator1610_smc91x_resources),
+	.resource	= innovator1610_smc91x_resources,
+};
+
+static struct platform_device *innovator1610_devices[] __initdata = {
+	&innovator_flash_device,
+	&innovator1610_smc91x_device,
+};
+
+#endif /* CONFIG_ARCH_OMAP16XX */
+
+static void __init innovator_init_smc91x(void)
+{
+	if (cpu_is_omap1510()) {
+		fpga_write(fpga_read(OMAP1510_FPGA_RST) & ~1,
+			   OMAP1510_FPGA_RST);
+		udelay(750);
+	} else {
+		if ((omap_request_gpio(0)) < 0) {
+			printk("Error requesting gpio 0 for smc91x irq\n");
+			return;
+		}
+		omap_set_gpio_edge_ctrl(0, OMAP_GPIO_RISING_EDGE);
+	}
+}
+
+void innovator_init_irq(void)
+{
+	omap_init_irq();
+	omap_gpio_init();
+#ifdef CONFIG_ARCH_OMAP1510
+	if (cpu_is_omap1510()) {
+		omap1510_fpga_init_irq();
+	}
+#endif
+	innovator_init_smc91x();
+}
+
+#ifdef CONFIG_ARCH_OMAP1510
+static struct omap_usb_config innovator1510_usb_config __initdata = {
+	/* for bundled non-standard host and peripheral cables */
+	.hmc_mode	= 4,
+
+	.register_host	= 1,
+	.pins[1]	= 6,
+	.pins[2]	= 6,		/* Conflicts with UART2 */
+
+	.register_dev	= 1,
+	.pins[0]	= 2,
+};
+#endif
+
+#ifdef CONFIG_ARCH_OMAP16XX
+static struct omap_usb_config h2_usb_config __initdata = {
+	/* usb1 has a Mini-AB port and external isp1301 transceiver */
+	.otg		= 2,
+
+#ifdef	CONFIG_USB_GADGET_OMAP
+	.hmc_mode	= 19,	// 0:host(off) 1:dev|otg 2:disabled
+	// .hmc_mode	= 21,	// 0:host(off) 1:dev(loopback) 2:host(loopback)
+#elif	defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
+	/* NONSTANDARD CABLE NEEDED (B-to-Mini-B) */
+	.hmc_mode	= 20,	// 1:dev|otg(off) 1:host 2:disabled
+#endif
+
+	.pins[1]	= 3,
+};
+#endif
+
+static struct omap_board_config_kernel innovator_config[] = {
+	{ OMAP_TAG_USB,         NULL },
+};
+
+static void __init innovator_init(void)
+{
+#ifdef CONFIG_ARCH_OMAP1510
+	if (cpu_is_omap1510()) {
+		platform_add_devices(innovator1510_devices, ARRAY_SIZE(innovator1510_devices));
+	}
+#endif
+#ifdef CONFIG_ARCH_OMAP16XX
+	if (!cpu_is_omap1510()) {
+		platform_add_devices(innovator1610_devices, ARRAY_SIZE(innovator1610_devices));
+	}
+#endif
+
+#ifdef CONFIG_ARCH_OMAP1510
+	if (cpu_is_omap1510())
+		innovator_config[0].data = &innovator1510_usb_config;
+#endif
+#ifdef CONFIG_ARCH_OMAP16XX
+	if (cpu_is_omap1610())
+		innovator_config[0].data = &h2_usb_config;
+#endif
+	omap_board_config = innovator_config;
+	omap_board_config_size = ARRAY_SIZE(innovator_config);
+}
+
+static void __init innovator_map_io(void)
+{
+	omap_map_common_io();
+
+#ifdef CONFIG_ARCH_OMAP1510
+	if (cpu_is_omap1510()) {
+		iotable_init(innovator1510_io_desc, ARRAY_SIZE(innovator1510_io_desc));
+		udelay(10);	/* Delay needed for FPGA */
+
+		/* Dump the Innovator FPGA rev early - useful info for support. */
+		printk("Innovator FPGA Rev %d.%d Board Rev %d\n",
+		       fpga_read(OMAP1510_FPGA_REV_HIGH),
+		       fpga_read(OMAP1510_FPGA_REV_LOW),
+		       fpga_read(OMAP1510_FPGA_BOARD_REV));
+	}
+#endif
+	omap_serial_init(innovator_serial_ports);
+}
+
+MACHINE_START(OMAP_INNOVATOR, "TI-Innovator")
+	/* Maintainer: MontaVista Software, Inc. */
+	.phys_ram	= 0x10000000,
+	.phys_io	= 0xfff00000,
+	.io_pg_offst	= ((0xfef00000) >> 18) & 0xfffc,
+	.boot_params	= 0x10000100,
+	.map_io		= innovator_map_io,
+	.init_irq	= innovator_init_irq,
+	.init_machine	= innovator_init,
+	.timer		= &omap_timer,
+MACHINE_END
diff --git a/arch/arm/mach-omap1/board-netstar.c b/arch/arm/mach-omap1/board-netstar.c
new file mode 100644
--- /dev/null
+++ b/arch/arm/mach-omap1/board-netstar.c
@@ -0,0 +1,152 @@
+/*
+ * Modified from board-generic.c
+ *
+ * Copyright (C) 2004 2N Telekomunikace, Ladislav Michl <michl@2n.cz>
+ *
+ * Code for Netstar OMAP board.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/notifier.h>
+#include <linux/reboot.h>
+
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <asm/arch/gpio.h>
+#include <asm/arch/mux.h>
+#include <asm/arch/usb.h>
+#include <asm/arch/common.h>
+
+extern void __init omap_init_time(void);
+extern int omap_gpio_init(void);
+
+static struct resource netstar_smc91x_resources[] = {
+	[0] = {
+		.start	= OMAP_CS1_PHYS + 0x300,
+		.end	= OMAP_CS1_PHYS + 0x300 + 16,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= OMAP_GPIO_IRQ(8),
+		.end	= OMAP_GPIO_IRQ(8),
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device netstar_smc91x_device = {
+	.name		= "smc91x",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(netstar_smc91x_resources),
+	.resource	= netstar_smc91x_resources,
+};
+
+static struct platform_device *netstar_devices[] __initdata = {
+	&netstar_smc91x_device,
+};
+
+static void __init netstar_init_irq(void)
+{
+	omap_init_irq();
+	omap_gpio_init();
+}
+
+static void __init netstar_init(void)
+{
+	/* green LED */
+	omap_request_gpio(4);
+	omap_set_gpio_direction(4, 0);
+	/* smc91x reset */
+	omap_request_gpio(7);
+	omap_set_gpio_direction(7, 0);
+	omap_set_gpio_dataout(7, 1);
+	udelay(2);	/* wait at least 100ns */
+	omap_set_gpio_dataout(7, 0);
+	mdelay(50);	/* 50ms until PHY ready */
+	/* smc91x interrupt pin */
+	omap_request_gpio(8);
+	omap_set_gpio_edge_ctrl(8, OMAP_GPIO_RISING_EDGE);
+
+	omap_request_gpio(12);
+	omap_request_gpio(13);
+	omap_request_gpio(14);
+	omap_request_gpio(15);
+	omap_set_gpio_edge_ctrl(12, OMAP_GPIO_FALLING_EDGE);
+	omap_set_gpio_edge_ctrl(13, OMAP_GPIO_FALLING_EDGE);
+	omap_set_gpio_edge_ctrl(14, OMAP_GPIO_FALLING_EDGE);
+	omap_set_gpio_edge_ctrl(15, OMAP_GPIO_FALLING_EDGE);
+
+	platform_add_devices(netstar_devices, ARRAY_SIZE(netstar_devices));
+
+	/* Switch on green LED */
+	omap_set_gpio_dataout(4, 0);
+	/* Switch off red LED */
+	omap_writeb(0x00, OMAP_LPG1_PMR);	/* Disable clock */
+	omap_writeb(0x80, OMAP_LPG1_LCR);
+}
+
+static int __initdata omap_serial_ports[OMAP_MAX_NR_PORTS] = {1, 1, 1};
+
+static void __init netstar_map_io(void)
+{
+	omap_map_common_io();
+	omap_serial_init(omap_serial_ports);
+}
+
+#define MACHINE_PANICED		1
+#define MACHINE_REBOOTING	2
+#define MACHINE_REBOOT		4
+static unsigned long machine_state;
+
+static int panic_event(struct notifier_block *this, unsigned long event,
+	 void *ptr)
+{
+	if (test_and_set_bit(MACHINE_PANICED, &machine_state))
+		return NOTIFY_DONE;
+
+	/* Switch off green LED */
+	omap_set_gpio_dataout(4, 1);
+	/* Flash red LED */
+	omap_writeb(0x78, OMAP_LPG1_LCR);
+	omap_writeb(0x01, OMAP_LPG1_PMR);	/* Enable clock */
+
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block panic_block = {
+	.notifier_call	= panic_event,
+};
+
+static int __init netstar_late_init(void)
+{
+	/* TODO: Setup front panel switch here */
+
+	/* Setup panic notifier */
+	notifier_chain_register(&panic_notifier_list, &panic_block);
+
+	return 0;
+}
+
+postcore_initcall(netstar_late_init);
+
+MACHINE_START(NETSTAR, "NetStar OMAP5910")
+	/* Maintainer: Ladislav Michl <michl@2n.cz> */
+	.phys_ram	= 0x10000000,
+	.phys_io	= 0xfff00000,
+	.io_pg_offst	= ((0xfef00000) >> 18) & 0xfffc,
+	.boot_params	= 0x10000100,
+	.map_io		= netstar_map_io,
+	.init_irq	= netstar_init_irq,
+	.init_machine	= netstar_init,
+	.timer		= &omap_timer,
+MACHINE_END
diff --git a/arch/arm/mach-omap1/board-osk.c b/arch/arm/mach-omap1/board-osk.c
new file mode 100644
--- /dev/null
+++ b/arch/arm/mach-omap1/board-osk.c
@@ -0,0 +1,170 @@
+/*
+ * linux/arch/arm/mach-omap1/board-osk.c
+ *
+ * Board specific init for OMAP5912 OSK
+ *
+ * Written by Dirk Behme <dirk.behme@de.bosch.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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the  GNU General Public License along
+ * with this program; if not, write  to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/device.h>
+
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <asm/arch/gpio.h>
+#include <asm/arch/usb.h>
+#include <asm/arch/mux.h>
+#include <asm/arch/tc.h>
+#include <asm/arch/common.h>
+
+static struct map_desc osk5912_io_desc[] __initdata = {
+{ OMAP_OSK_NOR_FLASH_BASE, OMAP_OSK_NOR_FLASH_START, OMAP_OSK_NOR_FLASH_SIZE,
+	MT_DEVICE },
+};
+
+static int __initdata osk_serial_ports[OMAP_MAX_NR_PORTS] = {1, 0, 0};
+
+static struct resource osk5912_smc91x_resources[] = {
+	[0] = {
+		.start	= OMAP_OSK_ETHR_START,		/* Physical */
+		.end	= OMAP_OSK_ETHR_START + 0xf,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= OMAP_GPIO_IRQ(0),
+		.end	= OMAP_GPIO_IRQ(0),
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device osk5912_smc91x_device = {
+	.name		= "smc91x",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(osk5912_smc91x_resources),
+	.resource	= osk5912_smc91x_resources,
+};
+
+static struct resource osk5912_cf_resources[] = {
+	[0] = {
+		.start	= OMAP_GPIO_IRQ(62),
+		.end	= OMAP_GPIO_IRQ(62),
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device osk5912_cf_device = {
+	.name		= "omap_cf",
+	.id		= -1,
+	.dev = {
+		.platform_data	= (void *) 2 /* CS2 */,
+	},
+	.num_resources	= ARRAY_SIZE(osk5912_cf_resources),
+	.resource	= osk5912_cf_resources,
+};
+
+static struct platform_device *osk5912_devices[] __initdata = {
+	&osk5912_smc91x_device,
+	&osk5912_cf_device,
+};
+
+static void __init osk_init_smc91x(void)
+{
+	if ((omap_request_gpio(0)) < 0) {
+		printk("Error requesting gpio 0 for smc91x irq\n");
+		return;
+	}
+	omap_set_gpio_edge_ctrl(0, OMAP_GPIO_RISING_EDGE);
+
+	/* Check EMIFS wait states to fix errors with SMC_GET_PKT_HDR */
+	EMIFS_CCS(1) |= 0x2;
+}
+
+static void __init osk_init_cf(void)
+{
+	omap_cfg_reg(M7_1610_GPIO62);
+	if ((omap_request_gpio(62)) < 0) {
+		printk("Error requesting gpio 62 for CF irq\n");
+		return;
+	}
+	/* it's really active-low */
+	omap_set_gpio_edge_ctrl(62, OMAP_GPIO_FALLING_EDGE);
+}
+
+void osk_init_irq(void)
+{
+	omap_init_irq();
+	omap_gpio_init();
+	osk_init_smc91x();
+	osk_init_cf();
+}
+
+static struct omap_usb_config osk_usb_config __initdata = {
+	/* has usb host connector (A) ... for development it can also
+	 * be used, with a NONSTANDARD gender-bending cable/dongle, as
+	 * a peripheral.
+	 */
+#ifdef	CONFIG_USB_GADGET_OMAP
+	.register_dev	= 1,
+	.hmc_mode	= 0,
+#else
+	.register_host	= 1,
+	.hmc_mode	= 16,
+	.rwc		= 1,
+#endif
+	.pins[0]	= 2,
+};
+
+static struct omap_board_config_kernel osk_config[] = {
+	{ OMAP_TAG_USB,           &osk_usb_config },
+};
+
+static void __init osk_init(void)
+{
+	platform_add_devices(osk5912_devices, ARRAY_SIZE(osk5912_devices));
+	omap_board_config = osk_config;
+	omap_board_config_size = ARRAY_SIZE(osk_config);
+	USB_TRANSCEIVER_CTRL_REG |= (3 << 1);
+}
+
+static void __init osk_map_io(void)
+{
+	omap_map_common_io();
+	iotable_init(osk5912_io_desc, ARRAY_SIZE(osk5912_io_desc));
+	omap_serial_init(osk_serial_ports);
+}
+
+MACHINE_START(OMAP_OSK, "TI-OSK")
+	/* Maintainer: Dirk Behme <dirk.behme@de.bosch.com> */
+	.phys_ram	= 0x10000000,
+	.phys_io	= 0xfff00000,
+	.io_pg_offst	= ((0xfef00000) >> 18) & 0xfffc,
+	.boot_params	= 0x10000100,
+	.map_io		= osk_map_io,
+	.init_irq	= osk_init_irq,
+	.init_machine	= osk_init,
+	.timer		= &omap_timer,
+MACHINE_END
diff --git a/arch/arm/mach-omap1/board-perseus2.c b/arch/arm/mach-omap1/board-perseus2.c
new file mode 100644
--- /dev/null
+++ b/arch/arm/mach-omap1/board-perseus2.c
@@ -0,0 +1,190 @@
+/*
+ * linux/arch/arm/mach-omap1/board-perseus2.c
+ *
+ * Modified from board-generic.c
+ *
+ * Original OMAP730 support by Jean Pihet <j-pihet@ti.com>
+ * Updated for 2.6 by Kevin Hilman <kjh@hilman.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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/delay.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
+#include <asm/mach/map.h>
+
+#include <asm/arch/gpio.h>
+#include <asm/arch/mux.h>
+#include <asm/arch/fpga.h>
+#include <asm/arch/common.h>
+
+static struct resource smc91x_resources[] = {
+	[0] = {
+		.start	= H2P2_DBG_FPGA_ETHR_START,	/* Physical */
+		.end	= H2P2_DBG_FPGA_ETHR_START + 0xf,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= INT_730_MPU_EXT_NIRQ,
+		.end	= 0,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static int __initdata p2_serial_ports[OMAP_MAX_NR_PORTS] = {1, 1, 0};
+
+static struct mtd_partition p2_partitions[] = {
+	/* bootloader (U-Boot, etc) in first sector */
+	{
+	      .name		= "bootloader",
+	      .offset		= 0,
+	      .size		= SZ_128K,
+	      .mask_flags	= MTD_WRITEABLE, /* force read-only */
+	},
+	/* bootloader params in the next sector */
+	{
+	      .name		= "params",
+	      .offset		= MTDPART_OFS_APPEND,
+	      .size		= SZ_128K,
+	      .mask_flags	= 0,
+	},
+	/* kernel */
+	{
+	      .name		= "kernel",
+	      .offset		= MTDPART_OFS_APPEND,
+	      .size		= SZ_2M,
+	      .mask_flags	= 0
+	},
+	/* rest of flash is a file system */
+	{
+	      .name		= "rootfs",
+	      .offset		= MTDPART_OFS_APPEND,
+	      .size		= MTDPART_SIZ_FULL,
+	      .mask_flags	= 0
+	},
+};
+
+static struct flash_platform_data p2_flash_data = {
+	.map_name	= "cfi_probe",
+	.width		= 2,
+	.parts		= p2_partitions,
+	.nr_parts	= ARRAY_SIZE(p2_partitions),
+};
+
+static struct resource p2_flash_resource = {
+	.start		= OMAP_FLASH_0_START,
+	.end		= OMAP_FLASH_0_START + OMAP_FLASH_0_SIZE - 1,
+	.flags		= IORESOURCE_MEM,
+};
+
+static struct platform_device p2_flash_device = {
+	.name		= "omapflash",
+	.id		= 0,
+	.dev		= {
+		.platform_data	= &p2_flash_data,
+	},
+	.num_resources	= 1,
+	.resource	= &p2_flash_resource,
+};
+
+static struct platform_device smc91x_device = {
+	.name		= "smc91x",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(smc91x_resources),
+	.resource	= smc91x_resources,
+};
+
+static struct platform_device *devices[] __initdata = {
+	&p2_flash_device,
+	&smc91x_device,
+};
+
+static void __init omap_perseus2_init(void)
+{
+	(void) platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+static void __init perseus2_init_smc91x(void)
+{
+	fpga_write(1, H2P2_DBG_FPGA_LAN_RESET);
+	mdelay(50);
+	fpga_write(fpga_read(H2P2_DBG_FPGA_LAN_RESET) & ~1,
+		   H2P2_DBG_FPGA_LAN_RESET);
+	mdelay(50);
+}
+
+void omap_perseus2_init_irq(void)
+{
+	omap_init_irq();
+	omap_gpio_init();
+	perseus2_init_smc91x();
+}
+
+/* Only FPGA needs to be mapped here. All others are done with ioremap */
+static struct map_desc omap_perseus2_io_desc[] __initdata = {
+	{H2P2_DBG_FPGA_BASE, H2P2_DBG_FPGA_START, H2P2_DBG_FPGA_SIZE,
+	 MT_DEVICE},
+};
+
+static void __init omap_perseus2_map_io(void)
+{
+	omap_map_common_io();
+	iotable_init(omap_perseus2_io_desc,
+		     ARRAY_SIZE(omap_perseus2_io_desc));
+
+	/* Early, board-dependent init */
+
+	/*
+	 * Hold GSM Reset until needed
+	 */
+	omap_writew(omap_readw(OMAP730_DSP_M_CTL) & ~1, OMAP730_DSP_M_CTL);
+
+	/*
+	 * UARTs -> done automagically by 8250 driver
+	 */
+
+	/*
+	 * CSx timings, GPIO Mux ... setup
+	 */
+
+	/* Flash: CS0 timings setup */
+	omap_writel(0x0000fff3, OMAP730_FLASH_CFG_0);
+	omap_writel(0x00000088, OMAP730_FLASH_ACFG_0);
+
+	/*
+	 * Ethernet support trough the debug board
+	 * CS1 timings setup
+	 */
+	omap_writel(0x0000fff3, OMAP730_FLASH_CFG_1);
+	omap_writel(0x00000000, OMAP730_FLASH_ACFG_1);
+
+	/*
+	 * Configure MPU_EXT_NIRQ IO in IO_CONF9 register,
+	 * It is used as the Ethernet controller interrupt
+	 */
+	omap_writel(omap_readl(OMAP730_IO_CONF_9) & 0x1FFFFFFF, OMAP730_IO_CONF_9);
+	omap_serial_init(p2_serial_ports);
+}
+
+MACHINE_START(OMAP_PERSEUS2, "OMAP730 Perseus2")
+	/* Maintainer: Kevin Hilman <kjh@hilman.org> */
+	.phys_ram	= 0x10000000,
+	.phys_io	= 0xfff00000,
+	.io_pg_offst	= ((0xfef00000) >> 18) & 0xfffc,
+	.boot_params	= 0x10000100,
+	.map_io		= omap_perseus2_map_io,
+	.init_irq	= omap_perseus2_init_irq,
+	.init_machine	= omap_perseus2_init,
+	.timer		= &omap_timer,
+MACHINE_END
diff --git a/arch/arm/mach-omap1/board-voiceblue.c b/arch/arm/mach-omap1/board-voiceblue.c
new file mode 100644
--- /dev/null
+++ b/arch/arm/mach-omap1/board-voiceblue.c
@@ -0,0 +1,257 @@
+/*
+ * linux/arch/arm/mach-omap1/board-voiceblue.c
+ *
+ * Modified from board-generic.c
+ *
+ * Copyright (C) 2004 2N Telekomunikace, Ladislav Michl <michl@2n.cz>
+ *
+ * Code for OMAP5910 based VoiceBlue board (VoIP to GSM gateway).
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/notifier.h>
+#include <linux/reboot.h>
+#include <linux/serial_8250.h>
+#include <linux/serial_reg.h>
+
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <asm/arch/gpio.h>
+#include <asm/arch/tc.h>
+#include <asm/arch/mux.h>
+#include <asm/arch/usb.h>
+#include <asm/arch/common.h>
+
+extern void omap_init_time(void);
+extern int omap_gpio_init(void);
+
+static struct plat_serial8250_port voiceblue_ports[] = {
+	{
+		.mapbase	= (unsigned long)(OMAP_CS1_PHYS + 0x40000),
+		.irq		= OMAP_GPIO_IRQ(12),
+		.flags		= UPF_BOOT_AUTOCONF | UPF_IOREMAP,
+		.iotype		= UPIO_MEM,
+		.regshift	= 1,
+		.uartclk	= 3686400,
+	},
+	{
+		.mapbase	= (unsigned long)(OMAP_CS1_PHYS + 0x50000),
+		.irq		= OMAP_GPIO_IRQ(13),
+		.flags		= UPF_BOOT_AUTOCONF | UPF_IOREMAP,
+		.iotype		= UPIO_MEM,
+		.regshift	= 1,
+		.uartclk	= 3686400,
+	},
+	{
+		.mapbase	= (unsigned long)(OMAP_CS1_PHYS + 0x60000),
+		.irq		= OMAP_GPIO_IRQ(14),
+		.flags		= UPF_BOOT_AUTOCONF | UPF_IOREMAP,
+		.iotype		= UPIO_MEM,
+		.regshift	= 1,
+		.uartclk	= 3686400,
+	},
+	{
+		.mapbase	= (unsigned long)(OMAP_CS1_PHYS + 0x70000),
+		.irq		= OMAP_GPIO_IRQ(15),
+		.flags		= UPF_BOOT_AUTOCONF | UPF_IOREMAP,
+		.iotype		= UPIO_MEM,
+		.regshift	= 1,
+		.uartclk	= 3686400,
+	},
+	{ },
+};
+
+static struct platform_device serial_device = {
+	.name			= "serial8250",
+	.id			= 1,
+	.dev			= {
+		.platform_data	= voiceblue_ports,
+	},
+};
+
+static int __init ext_uart_init(void)
+{
+	return platform_device_register(&serial_device);
+}
+arch_initcall(ext_uart_init);
+
+static struct resource voiceblue_smc91x_resources[] = {
+	[0] = {
+		.start	= OMAP_CS2_PHYS + 0x300,
+		.end	= OMAP_CS2_PHYS + 0x300 + 16,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= OMAP_GPIO_IRQ(8),
+		.end	= OMAP_GPIO_IRQ(8),
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device voiceblue_smc91x_device = {
+	.name		= "smc91x",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(voiceblue_smc91x_resources),
+	.resource	= voiceblue_smc91x_resources,
+};
+
+static struct platform_device *voiceblue_devices[] __initdata = {
+	&voiceblue_smc91x_device,
+};
+
+static struct omap_usb_config voiceblue_usb_config __initdata = {
+	.hmc_mode	= 3,
+	.register_host	= 1,
+	.register_dev   = 1,
+	.pins[0]	= 2,
+	.pins[1]	= 6,
+	.pins[2]	= 6,
+};
+
+static struct omap_board_config_kernel voiceblue_config[] = {
+	{ OMAP_TAG_USB, &voiceblue_usb_config },
+};
+
+static void __init voiceblue_init_irq(void)
+{
+	omap_init_irq();
+	omap_gpio_init();
+}
+
+static void __init voiceblue_init(void)
+{
+	/* There is a good chance board is going up, so enable Power LED
+	 * (it is connected through invertor) */
+	omap_writeb(0x00, OMAP_LPG1_LCR);
+	/* Watchdog */
+	omap_request_gpio(0);
+	/* smc91x reset */
+	omap_request_gpio(7);
+	omap_set_gpio_direction(7, 0);
+	omap_set_gpio_dataout(7, 1);
+	udelay(2);	/* wait at least 100ns */
+	omap_set_gpio_dataout(7, 0);
+	mdelay(50);	/* 50ms until PHY ready */
+	/* smc91x interrupt pin */
+	omap_request_gpio(8);
+	omap_set_gpio_edge_ctrl(8, OMAP_GPIO_RISING_EDGE);
+	/* 16C554 reset*/
+	omap_request_gpio(6);
+	omap_set_gpio_direction(6, 0);
+	omap_set_gpio_dataout(6, 0);
+	/* 16C554 interrupt pins */
+	omap_request_gpio(12);
+	omap_request_gpio(13);
+	omap_request_gpio(14);
+	omap_request_gpio(15);
+	omap_set_gpio_edge_ctrl(12, OMAP_GPIO_RISING_EDGE);
+	omap_set_gpio_edge_ctrl(13, OMAP_GPIO_RISING_EDGE);
+	omap_set_gpio_edge_ctrl(14, OMAP_GPIO_RISING_EDGE);
+	omap_set_gpio_edge_ctrl(15, OMAP_GPIO_RISING_EDGE);
+
+	platform_add_devices(voiceblue_devices, ARRAY_SIZE(voiceblue_devices));
+	omap_board_config = voiceblue_config;
+	omap_board_config_size = ARRAY_SIZE(voiceblue_config);
+}
+
+static int __initdata omap_serial_ports[OMAP_MAX_NR_PORTS] = {1, 1, 1};
+
+static void __init voiceblue_map_io(void)
+{
+	omap_map_common_io();
+	omap_serial_init(omap_serial_ports);
+}
+
+#define MACHINE_PANICED		1
+#define MACHINE_REBOOTING	2
+#define MACHINE_REBOOT		4
+static unsigned long machine_state;
+
+static int panic_event(struct notifier_block *this, unsigned long event,
+	 void *ptr)
+{
+	if (test_and_set_bit(MACHINE_PANICED, &machine_state))
+		return NOTIFY_DONE;
+
+	/* Flash Power LED
+	 * (TODO: Enable clock right way (enabled in bootloader already)) */
+	omap_writeb(0x78, OMAP_LPG1_LCR);
+
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block panic_block = {
+	.notifier_call	= panic_event,
+};
+
+static int __init setup_notifier(void)
+{
+	/* Setup panic notifier */
+	notifier_chain_register(&panic_notifier_list, &panic_block);
+
+	return 0;
+}
+
+postcore_initcall(setup_notifier);
+
+static int wdt_gpio_state;
+
+void voiceblue_wdt_enable(void)
+{
+	omap_set_gpio_direction(0, 0);
+	omap_set_gpio_dataout(0, 0);
+	omap_set_gpio_dataout(0, 1);
+	omap_set_gpio_dataout(0, 0);
+	wdt_gpio_state = 0;
+}
+
+void voiceblue_wdt_disable(void)
+{
+	omap_set_gpio_dataout(0, 0);
+	omap_set_gpio_dataout(0, 1);
+	omap_set_gpio_dataout(0, 0);
+	omap_set_gpio_direction(0, 1);
+}
+
+void voiceblue_wdt_ping(void)
+{
+	if (test_bit(MACHINE_REBOOT, &machine_state))
+		return;
+
+	wdt_gpio_state = !wdt_gpio_state;
+	omap_set_gpio_dataout(0, wdt_gpio_state);
+}
+
+void voiceblue_reset(void)
+{
+	set_bit(MACHINE_REBOOT, &machine_state);
+	voiceblue_wdt_enable();
+	while (1) ;
+}
+
+EXPORT_SYMBOL(voiceblue_wdt_enable);
+EXPORT_SYMBOL(voiceblue_wdt_disable);
+EXPORT_SYMBOL(voiceblue_wdt_ping);
+
+MACHINE_START(VOICEBLUE, "VoiceBlue OMAP5910")
+	/* Maintainer: Ladislav Michl <michl@2n.cz> */
+	.phys_ram	= 0x10000000,
+	.phys_io	= 0xfff00000,
+	.io_pg_offst	= ((0xfef00000) >> 18) & 0xfffc,
+	.boot_params	= 0x10000100,
+	.map_io		= voiceblue_map_io,
+	.init_irq	= voiceblue_init_irq,
+	.init_machine	= voiceblue_init,
+	.timer		= &omap_timer,
+MACHINE_END
diff --git a/arch/arm/mach-omap1/fpga.c b/arch/arm/mach-omap1/fpga.c
new file mode 100644
--- /dev/null
+++ b/arch/arm/mach-omap1/fpga.c
@@ -0,0 +1,188 @@
+/*
+ * linux/arch/arm/mach-omap/fpga.c
+ *
+ * Interrupt handler for OMAP-1510 Innovator FPGA
+ *
+ * Copyright (C) 2001 RidgeRun, Inc.
+ * Author: Greg Lonnon <glonnon@ridgerun.com>
+ *
+ * Copyright (C) 2002 MontaVista Software, Inc.
+ *
+ * Separated FPGA interrupts from innovator1510.c and cleaned up for 2.6
+ * Copyright (C) 2004 Nokia Corporation by Tony Lindrgen <tony@atomide.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/mach/irq.h>
+
+#include <asm/arch/fpga.h>
+#include <asm/arch/gpio.h>
+
+static void fpga_mask_irq(unsigned int irq)
+{
+	irq -= OMAP1510_IH_FPGA_BASE;
+
+	if (irq < 8)
+		__raw_writeb((__raw_readb(OMAP1510_FPGA_IMR_LO)
+			      & ~(1 << irq)), OMAP1510_FPGA_IMR_LO);
+	else if (irq < 16)
+		__raw_writeb((__raw_readb(OMAP1510_FPGA_IMR_HI)
+			      & ~(1 << (irq - 8))), OMAP1510_FPGA_IMR_HI);
+	else
+		__raw_writeb((__raw_readb(INNOVATOR_FPGA_IMR2)
+			      & ~(1 << (irq - 16))), INNOVATOR_FPGA_IMR2);
+}
+
+
+static inline u32 get_fpga_unmasked_irqs(void)
+{
+	return
+		((__raw_readb(OMAP1510_FPGA_ISR_LO) &
+		  __raw_readb(OMAP1510_FPGA_IMR_LO))) |
+		((__raw_readb(OMAP1510_FPGA_ISR_HI) &
+		  __raw_readb(OMAP1510_FPGA_IMR_HI)) << 8) |
+		((__raw_readb(INNOVATOR_FPGA_ISR2) &
+		  __raw_readb(INNOVATOR_FPGA_IMR2)) << 16);
+}
+
+
+static void fpga_ack_irq(unsigned int irq)
+{
+	/* Don't need to explicitly ACK FPGA interrupts */
+}
+
+static void fpga_unmask_irq(unsigned int irq)
+{
+	irq -= OMAP1510_IH_FPGA_BASE;
+
+	if (irq < 8)
+		__raw_writeb((__raw_readb(OMAP1510_FPGA_IMR_LO) | (1 << irq)),
+		     OMAP1510_FPGA_IMR_LO);
+	else if (irq < 16)
+		__raw_writeb((__raw_readb(OMAP1510_FPGA_IMR_HI)
+			      | (1 << (irq - 8))), OMAP1510_FPGA_IMR_HI);
+	else
+		__raw_writeb((__raw_readb(INNOVATOR_FPGA_IMR2)
+			      | (1 << (irq - 16))), INNOVATOR_FPGA_IMR2);
+}
+
+static void fpga_mask_ack_irq(unsigned int irq)
+{
+	fpga_mask_irq(irq);
+	fpga_ack_irq(irq);
+}
+
+void innovator_fpga_IRQ_demux(unsigned int irq, struct irqdesc *desc,
+			      struct pt_regs *regs)
+{
+	struct irqdesc *d;
+	u32 stat;
+	int fpga_irq;
+
+	stat = get_fpga_unmasked_irqs();
+
+	if (!stat)
+		return;
+
+	for (fpga_irq = OMAP1510_IH_FPGA_BASE;
+	     (fpga_irq < (OMAP1510_IH_FPGA_BASE + NR_FPGA_IRQS)) && stat;
+	     fpga_irq++, stat >>= 1) {
+		if (stat & 1) {
+			d = irq_desc + fpga_irq;
+			d->handle(fpga_irq, d, regs);
+		}
+	}
+}
+
+static struct irqchip omap_fpga_irq_ack = {
+	.ack		= fpga_mask_ack_irq,
+	.mask		= fpga_mask_irq,
+	.unmask		= fpga_unmask_irq,
+};
+
+
+static struct irqchip omap_fpga_irq = {
+	.ack		= fpga_ack_irq,
+	.mask		= fpga_mask_irq,
+	.unmask		= fpga_unmask_irq,
+};
+
+/*
+ * All of the FPGA interrupt request inputs except for the touchscreen are
+ * edge-sensitive; the touchscreen is level-sensitive.  The edge-sensitive
+ * interrupts are acknowledged as a side-effect of reading the interrupt
+ * status register from the FPGA.  The edge-sensitive interrupt inputs
+ * cause a problem with level interrupt requests, such as Ethernet.  The
+ * problem occurs when a level interrupt request is asserted while its
+ * interrupt input is masked in the FPGA, which results in a missed
+ * interrupt.
+ *
+ * In an attempt to workaround the problem with missed interrupts, the
+ * mask_ack routine for all of the FPGA interrupts has been changed from
+ * fpga_mask_ack_irq() to fpga_ack_irq() so that the specific FPGA interrupt
+ * being serviced is left unmasked.  We can do this because the FPGA cascade
+ * interrupt is installed with the SA_INTERRUPT flag, which leaves all
+ * interrupts masked at the CPU while an FPGA interrupt handler executes.
+ *
+ * Limited testing indicates that this workaround appears to be effective
+ * for the smc9194 Ethernet driver used on the Innovator.  It should work
+ * on other FPGA interrupts as well, but any drivers that explicitly mask
+ * interrupts at the interrupt controller via disable_irq/enable_irq
+ * could pose a problem.
+ */
+void omap1510_fpga_init_irq(void)
+{
+	int i;
+
+	__raw_writeb(0, OMAP1510_FPGA_IMR_LO);
+	__raw_writeb(0, OMAP1510_FPGA_IMR_HI);
+	__raw_writeb(0, INNOVATOR_FPGA_IMR2);
+
+	for (i = OMAP1510_IH_FPGA_BASE; i < (OMAP1510_IH_FPGA_BASE + NR_FPGA_IRQS); i++) {
+
+		if (i == OMAP1510_INT_FPGA_TS) {
+			/*
+			 * The touchscreen interrupt is level-sensitive, so
+			 * we'll use the regular mask_ack routine for it.
+			 */
+			set_irq_chip(i, &omap_fpga_irq_ack);
+		}
+		else {
+			/*
+			 * All FPGA interrupts except the touchscreen are
+			 * edge-sensitive, so we won't mask them.
+			 */
+			set_irq_chip(i, &omap_fpga_irq);
+		}
+
+		set_irq_handler(i, do_edge_IRQ);
+		set_irq_flags(i, IRQF_VALID);
+	}
+
+	/*
+	 * The FPGA interrupt line is connected to GPIO13. Claim this pin for
+	 * the ARM.
+	 *
+	 * NOTE: For general GPIO/MPUIO access and interrupts, please see
+	 * gpio.[ch]
+	 */
+	omap_request_gpio(13);
+	omap_set_gpio_direction(13, 1);
+	omap_set_gpio_edge_ctrl(13, OMAP_GPIO_RISING_EDGE);
+	set_irq_chained_handler(OMAP1510_INT_FPGA, innovator_fpga_IRQ_demux);
+}
+
+EXPORT_SYMBOL(omap1510_fpga_init_irq);
diff --git a/arch/arm/mach-omap1/id.c b/arch/arm/mach-omap1/id.c
new file mode 100644
--- /dev/null
+++ b/arch/arm/mach-omap1/id.c
@@ -0,0 +1,188 @@
+/*
+ * linux/arch/arm/mach-omap1/id.c
+ *
+ * OMAP1 CPU identification code
+ *
+ * Copyright (C) 2004 Nokia Corporation
+ * Written by Tony Lindgren <tony@atomide.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/io.h>
+
+struct omap_id {
+	u16	jtag_id;	/* Used to determine OMAP type */
+	u8	die_rev;	/* Processor revision */
+	u32	omap_id;	/* OMAP revision */
+	u32	type;		/* Cpu id bits [31:08], cpu class bits [07:00] */
+};
+
+/* Register values to detect the OMAP version */
+static struct omap_id omap_ids[] __initdata = {
+	{ .jtag_id = 0x355f, .die_rev = 0x0, .omap_id = 0x03320000, .type = 0x07300100},
+	{ .jtag_id = 0xb55f, .die_rev = 0x0, .omap_id = 0x03320000, .type = 0x07300300},
+	{ .jtag_id = 0xb470, .die_rev = 0x0, .omap_id = 0x03310100, .type = 0x15100000},
+	{ .jtag_id = 0xb576, .die_rev = 0x0, .omap_id = 0x03320000, .type = 0x16100000},
+	{ .jtag_id = 0xb576, .die_rev = 0x2, .omap_id = 0x03320100, .type = 0x16110000},
+	{ .jtag_id = 0xb576, .die_rev = 0x3, .omap_id = 0x03320100, .type = 0x16100c00},
+	{ .jtag_id = 0xb576, .die_rev = 0x0, .omap_id = 0x03320200, .type = 0x16100d00},
+	{ .jtag_id = 0xb613, .die_rev = 0x0, .omap_id = 0x03320300, .type = 0x1610ef00},
+	{ .jtag_id = 0xb613, .die_rev = 0x0, .omap_id = 0x03320300, .type = 0x1610ef00},
+	{ .jtag_id = 0xb576, .die_rev = 0x1, .omap_id = 0x03320100, .type = 0x16110000},
+	{ .jtag_id = 0xb58c, .die_rev = 0x2, .omap_id = 0x03320200, .type = 0x16110b00},
+	{ .jtag_id = 0xb58c, .die_rev = 0x3, .omap_id = 0x03320200, .type = 0x16110c00},
+	{ .jtag_id = 0xb65f, .die_rev = 0x0, .omap_id = 0x03320400, .type = 0x16212300},
+	{ .jtag_id = 0xb65f, .die_rev = 0x1, .omap_id = 0x03320400, .type = 0x16212300},
+	{ .jtag_id = 0xb65f, .die_rev = 0x1, .omap_id = 0x03320500, .type = 0x16212300},
+	{ .jtag_id = 0xb5f7, .die_rev = 0x0, .omap_id = 0x03330000, .type = 0x17100000},
+	{ .jtag_id = 0xb5f7, .die_rev = 0x1, .omap_id = 0x03330100, .type = 0x17100000},
+	{ .jtag_id = 0xb5f7, .die_rev = 0x2, .omap_id = 0x03330100, .type = 0x17100000},
+};
+
+/*
+ * Get OMAP type from PROD_ID.
+ * 1710 has the PROD_ID in bits 15:00, not in 16:01 as documented in TRM.
+ * 1510 PROD_ID is empty, and 1610 PROD_ID does not make sense.
+ * Undocumented register in TEST BLOCK is used as fallback; This seems to
+ * work on 1510, 1610 & 1710. The official way hopefully will work in future
+ * processors.
+ */
+static u16 __init omap_get_jtag_id(void)
+{
+	u32 prod_id, omap_id;
+
+	prod_id = omap_readl(OMAP_PRODUCTION_ID_1);
+	omap_id = omap_readl(OMAP32_ID_1);
+
+	/* Check for unusable OMAP_PRODUCTION_ID_1 on 1611B/5912 and 730 */
+	if (((prod_id >> 20) == 0) || (prod_id == omap_id))
+		prod_id = 0;
+	else
+		prod_id &= 0xffff;
+
+	if (prod_id)
+		return prod_id;
+
+	/* Use OMAP32_ID_1 as fallback */
+	prod_id = ((omap_id >> 12) & 0xffff);
+
+	return prod_id;
+}
+
+/*
+ * Get OMAP revision from DIE_REV.
+ * Early 1710 processors may have broken OMAP_DIE_ID, it contains PROD_ID.
+ * Undocumented register in the TEST BLOCK is used as fallback.
+ * REVISIT: This does not seem to work on 1510
+ */
+static u8 __init omap_get_die_rev(void)
+{
+	u32 die_rev;
+
+	die_rev = omap_readl(OMAP_DIE_ID_1);
+
+	/* Check for broken OMAP_DIE_ID on early 1710 */
+	if (((die_rev >> 12) & 0xffff) == omap_get_jtag_id())
+		die_rev = 0;
+
+	die_rev = (die_rev >> 17) & 0xf;
+	if (die_rev)
+		return die_rev;
+
+	die_rev = (omap_readl(OMAP32_ID_1) >> 28) & 0xf;
+
+	return die_rev;
+}
+
+void __init omap_check_revision(void)
+{
+	int i;
+	u16 jtag_id;
+	u8 die_rev;
+	u32 omap_id;
+	u8 cpu_type;
+
+	jtag_id = omap_get_jtag_id();
+	die_rev = omap_get_die_rev();
+	omap_id = omap_readl(OMAP32_ID_0);
+
+#ifdef DEBUG
+	printk("OMAP_DIE_ID_0: 0x%08x\n", omap_readl(OMAP_DIE_ID_0));
+	printk("OMAP_DIE_ID_1: 0x%08x DIE_REV: %i\n",
+		omap_readl(OMAP_DIE_ID_1),
+	       (omap_readl(OMAP_DIE_ID_1) >> 17) & 0xf);
+	printk("OMAP_PRODUCTION_ID_0: 0x%08x\n", omap_readl(OMAP_PRODUCTION_ID_0));
+	printk("OMAP_PRODUCTION_ID_1: 0x%08x JTAG_ID: 0x%04x\n",
+		omap_readl(OMAP_PRODUCTION_ID_1),
+		omap_readl(OMAP_PRODUCTION_ID_1) & 0xffff);
+	printk("OMAP32_ID_0: 0x%08x\n", omap_readl(OMAP32_ID_0));
+	printk("OMAP32_ID_1: 0x%08x\n", omap_readl(OMAP32_ID_1));
+	printk("JTAG_ID: 0x%04x DIE_REV: %i\n", jtag_id, die_rev);
+#endif
+
+	system_serial_high = omap_readl(OMAP_DIE_ID_0);
+	system_serial_low = omap_readl(OMAP_DIE_ID_1);
+
+	/* First check only the major version in a safe way */
+	for (i = 0; i < ARRAY_SIZE(omap_ids); i++) {
+		if (jtag_id == (omap_ids[i].jtag_id)) {
+			system_rev = omap_ids[i].type;
+			break;
+		}
+	}
+
+	/* Check if we can find the die revision */
+	for (i = 0; i < ARRAY_SIZE(omap_ids); i++) {
+		if (jtag_id == omap_ids[i].jtag_id && die_rev == omap_ids[i].die_rev) {
+			system_rev = omap_ids[i].type;
+			break;
+		}
+	}
+
+	/* Finally check also the omap_id */
+	for (i = 0; i < ARRAY_SIZE(omap_ids); i++) {
+		if (jtag_id == omap_ids[i].jtag_id
+		    && die_rev == omap_ids[i].die_rev
+		    && omap_id == omap_ids[i].omap_id) {
+			system_rev = omap_ids[i].type;
+			break;
+		}
+	}
+
+	/* Add the cpu class info (7xx, 15xx, 16xx, 24xx) */
+	cpu_type = system_rev >> 24;
+
+	switch (cpu_type) {
+	case 0x07:
+		system_rev |= 0x07;
+		break;
+	case 0x15:
+		system_rev |= 0x15;
+		break;
+	case 0x16:
+	case 0x17:
+		system_rev |= 0x16;
+		break;
+	case 0x24:
+		system_rev |= 0x24;
+		break;
+	default:
+		printk("Unknown OMAP cpu type: 0x%02x\n", cpu_type);
+	}
+
+	printk("OMAP%04x", system_rev >> 16);
+	if ((system_rev >> 8) & 0xff)
+		printk("%x", (system_rev >> 8) & 0xff);
+	printk(" revision %i handled as %02xxx id: %08x%08x\n",
+	       die_rev, system_rev & 0xff, system_serial_low,
+	       system_serial_high);
+}
+
diff --git a/arch/arm/mach-omap1/io.c b/arch/arm/mach-omap1/io.c
new file mode 100644
--- /dev/null
+++ b/arch/arm/mach-omap1/io.c
@@ -0,0 +1,115 @@
+/*
+ * linux/arch/arm/mach-omap1/io.c
+ *
+ * OMAP1 I/O mapping code
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/mach/map.h>
+#include <asm/io.h>
+#include <asm/arch/tc.h>
+
+extern int clk_init(void);
+extern void omap_check_revision(void);
+
+/*
+ * The machine specific code may provide the extra mapping besides the
+ * default mapping provided here.
+ */
+static struct map_desc omap_io_desc[] __initdata = {
+ { IO_VIRT,      	IO_PHYS,             IO_SIZE,        	   MT_DEVICE },
+};
+
+#ifdef CONFIG_ARCH_OMAP730
+static struct map_desc omap730_io_desc[] __initdata = {
+ { OMAP730_DSP_BASE,    OMAP730_DSP_START,    OMAP730_DSP_SIZE,    MT_DEVICE },
+ { OMAP730_DSPREG_BASE, OMAP730_DSPREG_START, OMAP730_DSPREG_SIZE, MT_DEVICE },
+ { OMAP730_SRAM_BASE,   OMAP730_SRAM_START,   OMAP730_SRAM_SIZE,   MT_DEVICE }
+};
+#endif
+
+#ifdef CONFIG_ARCH_OMAP1510
+static struct map_desc omap1510_io_desc[] __initdata = {
+ { OMAP1510_DSP_BASE,    OMAP1510_DSP_START,    OMAP1510_DSP_SIZE,    MT_DEVICE },
+ { OMAP1510_DSPREG_BASE, OMAP1510_DSPREG_START, OMAP1510_DSPREG_SIZE, MT_DEVICE },
+ { OMAP1510_SRAM_BASE,   OMAP1510_SRAM_START,   OMAP1510_SRAM_SIZE,   MT_DEVICE }
+};
+#endif
+
+#if defined(CONFIG_ARCH_OMAP16XX)
+static struct map_desc omap1610_io_desc[] __initdata = {
+ { OMAP16XX_DSP_BASE,    OMAP16XX_DSP_START,    OMAP16XX_DSP_SIZE,    MT_DEVICE },
+ { OMAP16XX_DSPREG_BASE, OMAP16XX_DSPREG_START, OMAP16XX_DSPREG_SIZE, MT_DEVICE },
+ { OMAP16XX_SRAM_BASE,   OMAP16XX_SRAM_START,   OMAP1610_SRAM_SIZE,   MT_DEVICE }
+};
+
+static struct map_desc omap5912_io_desc[] __initdata = {
+ { OMAP16XX_DSP_BASE,    OMAP16XX_DSP_START,    OMAP16XX_DSP_SIZE,    MT_DEVICE },
+ { OMAP16XX_DSPREG_BASE, OMAP16XX_DSPREG_START, OMAP16XX_DSPREG_SIZE, MT_DEVICE },
+/*
+ * The OMAP5912 has 250kByte internal SRAM. Because the mapping is baseed on page
+ * size (4kByte), it seems that the last 2kByte (=0x800) of the 250kByte are not mapped.
+ * Add additional 2kByte (0x800) so that the last page is mapped and the last 2kByte
+ * can be used.
+ */
+ { OMAP16XX_SRAM_BASE,   OMAP16XX_SRAM_START,   OMAP5912_SRAM_SIZE + 0x800,   MT_DEVICE }
+};
+#endif
+
+static int initialized = 0;
+
+static void __init _omap_map_io(void)
+{
+	initialized = 1;
+
+	/* We have to initialize the IO space mapping before we can run
+	 * cpu_is_omapxxx() macros. */
+	iotable_init(omap_io_desc, ARRAY_SIZE(omap_io_desc));
+	omap_check_revision();
+
+#ifdef CONFIG_ARCH_OMAP730
+	if (cpu_is_omap730()) {
+		iotable_init(omap730_io_desc, ARRAY_SIZE(omap730_io_desc));
+	}
+#endif
+#ifdef CONFIG_ARCH_OMAP1510
+	if (cpu_is_omap1510()) {
+		iotable_init(omap1510_io_desc, ARRAY_SIZE(omap1510_io_desc));
+	}
+#endif
+#if defined(CONFIG_ARCH_OMAP16XX)
+	if (cpu_is_omap1610() || cpu_is_omap1710()) {
+		iotable_init(omap1610_io_desc, ARRAY_SIZE(omap1610_io_desc));
+	}
+	if (cpu_is_omap5912()) {
+		iotable_init(omap5912_io_desc, ARRAY_SIZE(omap5912_io_desc));
+	}
+#endif
+
+	/* REVISIT: Refer to OMAP5910 Errata, Advisory SYS_1: "Timeout Abort
+	 * on a Posted Write in the TIPB Bridge".
+	 */
+	omap_writew(0x0, MPU_PUBLIC_TIPB_CNTL);
+	omap_writew(0x0, MPU_PRIVATE_TIPB_CNTL);
+
+	/* Must init clocks early to assure that timer interrupt works
+	 */
+	clk_init();
+}
+
+/*
+ * This should only get called from board specific init
+ */
+void omap_map_common_io(void)
+{
+	if (!initialized)
+		_omap_map_io();
+}
diff --git a/arch/arm/mach-omap1/irq.c b/arch/arm/mach-omap1/irq.c
new file mode 100644
--- /dev/null
+++ b/arch/arm/mach-omap1/irq.c
@@ -0,0 +1,234 @@
+/*
+ * linux/arch/arm/mach-omap/irq.c
+ *
+ * Interrupt handler for all OMAP boards
+ *
+ * Copyright (C) 2004 Nokia Corporation
+ * Written by Tony Lindgren <tony@atomide.com>
+ * Major cleanups by Juha Yrjölä <juha.yrjola@nokia.com>
+ *
+ * Completely re-written to support various OMAP chips with bank specific
+ * interrupt handlers.
+ *
+ * Some snippets of the code taken from the older OMAP interrupt handler
+ * Copyright (C) 2001 RidgeRun, Inc. Greg Lonnon <glonnon@ridgerun.com>
+ *
+ * GPIO interrupt handler moved to gpio.c by Juha Yrjola
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the  GNU General Public License along
+ * with this program; if not, write  to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/ptrace.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/mach/irq.h>
+#include <asm/arch/gpio.h>
+
+#include <asm/io.h>
+
+#define IRQ_BANK(irq) ((irq) >> 5)
+#define IRQ_BIT(irq)  ((irq) & 0x1f)
+
+struct omap_irq_bank {
+	unsigned long base_reg;
+	unsigned long trigger_map;
+	unsigned long wake_enable;
+};
+
+static unsigned int irq_bank_count = 0;
+static struct omap_irq_bank *irq_banks;
+
+static inline unsigned int irq_bank_readl(int bank, int offset)
+{
+	return omap_readl(irq_banks[bank].base_reg + offset);
+}
+
+static inline void irq_bank_writel(unsigned long value, int bank, int offset)
+{
+	omap_writel(value, irq_banks[bank].base_reg + offset);
+}
+
+static void omap_ack_irq(unsigned int irq)
+{
+	if (irq > 31)
+		omap_writel(0x1, OMAP_IH2_BASE + IRQ_CONTROL_REG_OFFSET);
+
+	omap_writel(0x1, OMAP_IH1_BASE + IRQ_CONTROL_REG_OFFSET);
+}
+
+static void omap_mask_irq(unsigned int irq)
+{
+	int bank = IRQ_BANK(irq);
+	u32 l;
+
+	l = omap_readl(irq_banks[bank].base_reg + IRQ_MIR_REG_OFFSET);
+	l |= 1 << IRQ_BIT(irq);
+	omap_writel(l, irq_banks[bank].base_reg + IRQ_MIR_REG_OFFSET);
+}
+
+static void omap_unmask_irq(unsigned int irq)
+{
+	int bank = IRQ_BANK(irq);
+	u32 l;
+
+	l = omap_readl(irq_banks[bank].base_reg + IRQ_MIR_REG_OFFSET);
+	l &= ~(1 << IRQ_BIT(irq));
+	omap_writel(l, irq_banks[bank].base_reg + IRQ_MIR_REG_OFFSET);
+}
+
+static void omap_mask_ack_irq(unsigned int irq)
+{
+	omap_mask_irq(irq);
+	omap_ack_irq(irq);
+}
+
+static int omap_wake_irq(unsigned int irq, unsigned int enable)
+{
+	int bank = IRQ_BANK(irq);
+
+	if (enable)
+		irq_banks[bank].wake_enable |= IRQ_BIT(irq);
+	else
+		irq_banks[bank].wake_enable &= ~IRQ_BIT(irq);
+
+	return 0;
+}
+
+
+/*
+ * Allows tuning the IRQ type and priority
+ *
+ * NOTE: There is currently no OMAP fiq handler for Linux. Read the
+ *	 mailing list threads on FIQ handlers if you are planning to
+ *	 add a FIQ handler for OMAP.
+ */
+static void omap_irq_set_cfg(int irq, int fiq, int priority, int trigger)
+{
+	signed int bank;
+	unsigned long val, offset;
+
+	bank = IRQ_BANK(irq);
+	/* FIQ is only available on bank 0 interrupts */
+	fiq = bank ? 0 : (fiq & 0x1);
+	val = fiq | ((priority & 0x1f) << 2) | ((trigger & 0x1) << 1);
+	offset = IRQ_ILR0_REG_OFFSET + IRQ_BIT(irq) * 0x4;
+	irq_bank_writel(val, bank, offset);
+}
+
+#ifdef CONFIG_ARCH_OMAP730
+static struct omap_irq_bank omap730_irq_banks[] = {
+	{ .base_reg = OMAP_IH1_BASE, 		.trigger_map = 0xb3f8e22f },
+	{ .base_reg = OMAP_IH2_BASE, 		.trigger_map = 0xfdb9c1f2 },
+	{ .base_reg = OMAP_IH2_BASE + 0x100,	.trigger_map = 0x800040f3 },
+};
+#endif
+
+#ifdef CONFIG_ARCH_OMAP1510
+static struct omap_irq_bank omap1510_irq_banks[] = {
+	{ .base_reg = OMAP_IH1_BASE, 		.trigger_map = 0xb3febfff },
+	{ .base_reg = OMAP_IH2_BASE, 		.trigger_map = 0xffbfffed },
+};
+#endif
+
+#if defined(CONFIG_ARCH_OMAP16XX)
+
+static struct omap_irq_bank omap1610_irq_banks[] = {
+	{ .base_reg = OMAP_IH1_BASE, 		.trigger_map = 0xb3fefe8f },
+	{ .base_reg = OMAP_IH2_BASE, 		.trigger_map = 0xfdb7c1fd },
+	{ .base_reg = OMAP_IH2_BASE + 0x100,	.trigger_map = 0xffffb7ff },
+	{ .base_reg = OMAP_IH2_BASE + 0x200,	.trigger_map = 0xffffffff },
+};
+#endif
+
+static struct irqchip omap_irq_chip = {
+	.ack    = omap_mask_ack_irq,
+	.mask   = omap_mask_irq,
+	.unmask = omap_unmask_irq,
+	.wake	= omap_wake_irq,
+};
+
+void __init omap_init_irq(void)
+{
+	int i, j;
+
+#ifdef CONFIG_ARCH_OMAP730
+	if (cpu_is_omap730()) {
+		irq_banks = omap730_irq_banks;
+		irq_bank_count = ARRAY_SIZE(omap730_irq_banks);
+	}
+#endif
+#ifdef CONFIG_ARCH_OMAP1510
+	if (cpu_is_omap1510()) {
+		irq_banks = omap1510_irq_banks;
+		irq_bank_count = ARRAY_SIZE(omap1510_irq_banks);
+	}
+#endif
+#if defined(CONFIG_ARCH_OMAP16XX)
+	if (cpu_is_omap16xx()) {
+		irq_banks = omap1610_irq_banks;
+		irq_bank_count = ARRAY_SIZE(omap1610_irq_banks);
+	}
+#endif
+	printk("Total of %i interrupts in %i interrupt banks\n",
+	       irq_bank_count * 32, irq_bank_count);
+
+	/* Mask and clear all interrupts */
+	for (i = 0; i < irq_bank_count; i++) {
+		irq_bank_writel(~0x0, i, IRQ_MIR_REG_OFFSET);
+		irq_bank_writel(0x0, i, IRQ_ITR_REG_OFFSET);
+	}
+
+	/* Clear any pending interrupts */
+	irq_bank_writel(0x03, 0, IRQ_CONTROL_REG_OFFSET);
+	irq_bank_writel(0x03, 1, IRQ_CONTROL_REG_OFFSET);
+
+	/* Enable interrupts in global mask */
+	if (cpu_is_omap730()) {
+		irq_bank_writel(0x0, 0, IRQ_GMR_REG_OFFSET);
+	}
+
+	/* Install the interrupt handlers for each bank */
+	for (i = 0; i < irq_bank_count; i++) {
+		for (j = i * 32; j < (i + 1) * 32; j++) {
+			int irq_trigger;
+
+			irq_trigger = irq_banks[i].trigger_map >> IRQ_BIT(j);
+			omap_irq_set_cfg(j, 0, 0, irq_trigger);
+
+			set_irq_chip(j, &omap_irq_chip);
+			set_irq_handler(j, do_level_IRQ);
+			set_irq_flags(j, IRQF_VALID);
+		}
+	}
+
+	/* Unmask level 2 handler */
+	if (cpu_is_omap730()) {
+		omap_unmask_irq(INT_730_IH2_IRQ);
+	} else {
+		omap_unmask_irq(INT_IH2_IRQ);
+	}
+}
diff --git a/arch/arm/mach-omap1/leds-h2p2-debug.c b/arch/arm/mach-omap1/leds-h2p2-debug.c
new file mode 100644
--- /dev/null
+++ b/arch/arm/mach-omap1/leds-h2p2-debug.c
@@ -0,0 +1,143 @@
+/*
+ * linux/arch/arm/mach-omap/leds-h2p2-debug.c
+ *
+ * Copyright 2003 by Texas Instruments Incorporated
+ *
+ * There are 16 LEDs on the debug board (all green); four may be used
+ * for logical 'green', 'amber', 'red', and 'blue' (after "claiming").
+ *
+ * The "surfer" expansion board and H2 sample board also have two-color
+ * green+red LEDs (in parallel), used here for timer and idle indicators.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel_stat.h>
+#include <linux/sched.h>
+
+#include <asm/io.h>
+#include <asm/hardware.h>
+#include <asm/leds.h>
+#include <asm/system.h>
+
+#include <asm/arch/fpga.h>
+#include <asm/arch/gpio.h>
+
+#include "leds.h"
+
+
+#define GPIO_LED_RED		3
+#define GPIO_LED_GREEN		OMAP_MPUIO(4)
+
+
+#define LED_STATE_ENABLED	0x01
+#define LED_STATE_CLAIMED	0x02
+#define LED_TIMER_ON		0x04
+
+#define GPIO_IDLE		GPIO_LED_GREEN
+#define GPIO_TIMER		GPIO_LED_RED
+
+
+void h2p2_dbg_leds_event(led_event_t evt)
+{
+	unsigned long flags;
+
+	static struct h2p2_dbg_fpga __iomem *fpga;
+	static u16 led_state, hw_led_state;
+
+	local_irq_save(flags);
+
+	if (!(led_state & LED_STATE_ENABLED) && evt != led_start)
+		goto done;
+
+	switch (evt) {
+	case led_start:
+		if (!fpga)
+			fpga = ioremap(H2P2_DBG_FPGA_START,
+						H2P2_DBG_FPGA_SIZE);
+		if (fpga) {
+			led_state |= LED_STATE_ENABLED;
+			__raw_writew(~0, &fpga->leds);
+		}
+		break;
+
+	case led_stop:
+	case led_halted:
+		/* all leds off during suspend or shutdown */
+		omap_set_gpio_dataout(GPIO_TIMER, 0);
+		omap_set_gpio_dataout(GPIO_IDLE, 0);
+		__raw_writew(~0, &fpga->leds);
+		led_state &= ~LED_STATE_ENABLED;
+		if (evt == led_halted) {
+			iounmap(fpga);
+			fpga = NULL;
+		}
+		goto done;
+
+	case led_claim:
+		led_state |= LED_STATE_CLAIMED;
+		hw_led_state = 0;
+		break;
+
+	case led_release:
+		led_state &= ~LED_STATE_CLAIMED;
+		break;
+
+#ifdef CONFIG_LEDS_TIMER
+	case led_timer:
+		led_state ^= LED_TIMER_ON;
+		omap_set_gpio_dataout(GPIO_TIMER, led_state & LED_TIMER_ON);
+		goto done;
+#endif
+
+#ifdef CONFIG_LEDS_CPU
+	case led_idle_start:
+		omap_set_gpio_dataout(GPIO_IDLE, 1);
+		goto done;
+
+	case led_idle_end:
+		omap_set_gpio_dataout(GPIO_IDLE, 0);
+		goto done;
+#endif
+
+	case led_green_on:
+		hw_led_state |= H2P2_DBG_FPGA_LED_GREEN;
+		break;
+	case led_green_off:
+		hw_led_state &= ~H2P2_DBG_FPGA_LED_GREEN;
+		break;
+
+	case led_amber_on:
+		hw_led_state |= H2P2_DBG_FPGA_LED_AMBER;
+		break;
+	case led_amber_off:
+		hw_led_state &= ~H2P2_DBG_FPGA_LED_AMBER;
+		break;
+
+	case led_red_on:
+		hw_led_state |= H2P2_DBG_FPGA_LED_RED;
+		break;
+	case led_red_off:
+		hw_led_state &= ~H2P2_DBG_FPGA_LED_RED;
+		break;
+
+	case led_blue_on:
+		hw_led_state |= H2P2_DBG_FPGA_LED_BLUE;
+		break;
+	case led_blue_off:
+		hw_led_state &= ~H2P2_DBG_FPGA_LED_BLUE;
+		break;
+
+	default:
+		break;
+	}
+
+
+	/*
+	 *  Actually burn the LEDs
+	 */
+	if (led_state & LED_STATE_CLAIMED)
+		__raw_writew(~hw_led_state, &fpga->leds);
+
+done:
+	local_irq_restore(flags);
+}
diff --git a/arch/arm/mach-omap1/leds-innovator.c b/arch/arm/mach-omap1/leds-innovator.c
new file mode 100644
--- /dev/null
+++ b/arch/arm/mach-omap1/leds-innovator.c
@@ -0,0 +1,103 @@
+/*
+ * linux/arch/arm/mach-omap/leds-innovator.c
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/leds.h>
+#include <asm/system.h>
+
+#include "leds.h"
+
+
+#define LED_STATE_ENABLED	1
+#define LED_STATE_CLAIMED	2
+
+static unsigned int led_state;
+static unsigned int hw_led_state;
+
+void innovator_leds_event(led_event_t evt)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+
+	switch (evt) {
+	case led_start:
+		hw_led_state = 0;
+		led_state = LED_STATE_ENABLED;
+		break;
+
+	case led_stop:
+		led_state &= ~LED_STATE_ENABLED;
+		hw_led_state = 0;
+		break;
+
+	case led_claim:
+		led_state |= LED_STATE_CLAIMED;
+		hw_led_state = 0;
+		break;
+
+	case led_release:
+		led_state &= ~LED_STATE_CLAIMED;
+		hw_led_state = 0;
+		break;
+
+#ifdef CONFIG_LEDS_TIMER
+	case led_timer:
+		if (!(led_state & LED_STATE_CLAIMED))
+			hw_led_state ^= 0;
+		break;
+#endif
+
+#ifdef CONFIG_LEDS_CPU
+	case led_idle_start:
+		if (!(led_state & LED_STATE_CLAIMED))
+			hw_led_state |= 0;
+		break;
+
+	case led_idle_end:
+		if (!(led_state & LED_STATE_CLAIMED))
+			hw_led_state &= ~0;
+		break;
+#endif
+
+	case led_halted:
+		break;
+
+	case led_green_on:
+		if (led_state & LED_STATE_CLAIMED)
+			hw_led_state &= ~0;
+		break;
+
+	case led_green_off:
+		if (led_state & LED_STATE_CLAIMED)
+			hw_led_state |= 0;
+		break;
+
+	case led_amber_on:
+		break;
+
+	case led_amber_off:
+		break;
+
+	case led_red_on:
+		if (led_state & LED_STATE_CLAIMED)
+			hw_led_state &= ~0;
+		break;
+
+	case led_red_off:
+		if (led_state & LED_STATE_CLAIMED)
+			hw_led_state |= 0;
+		break;
+
+	default:
+		break;
+	}
+
+	if (led_state & LED_STATE_ENABLED)
+		;
+
+	local_irq_restore(flags);
+}
diff --git a/arch/arm/mach-omap1/leds-osk.c b/arch/arm/mach-omap1/leds-osk.c
new file mode 100644
--- /dev/null
+++ b/arch/arm/mach-omap1/leds-osk.c
@@ -0,0 +1,194 @@
+/*
+ * linux/arch/arm/mach-omap/leds-osk.c
+ *
+ * LED driver for OSK, and optionally Mistral QVGA, boards
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/workqueue.h>
+
+#include <asm/hardware.h>
+#include <asm/leds.h>
+#include <asm/system.h>
+
+#include <asm/arch/gpio.h>
+#include <asm/arch/tps65010.h>
+
+#include "leds.h"
+
+
+#define LED_STATE_ENABLED	(1 << 0)
+#define LED_STATE_CLAIMED	(1 << 1)
+static u8 led_state;
+
+#define	GREEN_LED		(1 << 0)	/* TPS65010 LED1 */
+#define	AMBER_LED		(1 << 1)	/* TPS65010 LED2 */
+#define	RED_LED			(1 << 2)	/* TPS65010 GPIO2 */
+#define	TIMER_LED		(1 << 3)	/* Mistral board */
+#define	IDLE_LED		(1 << 4)	/* Mistral board */
+static u8 hw_led_state;
+
+
+/* TPS65010 leds are changed using i2c -- from a task context.
+ * Using one of these for the "idle" LED would be impractical...
+ */
+#define	TPS_LEDS	(GREEN_LED | RED_LED | AMBER_LED)
+
+static u8 tps_leds_change;
+
+static void tps_work(void *unused)
+{
+	for (;;) {
+		u8	leds;
+
+		local_irq_disable();
+		leds = tps_leds_change;
+		tps_leds_change = 0;
+		local_irq_enable();
+
+		if (!leds)
+			break;
+
+		/* careful:  the set_led() value is on/off/blink */
+		if (leds & GREEN_LED)
+			tps65010_set_led(LED1, !!(hw_led_state & GREEN_LED));
+		if (leds & AMBER_LED)
+			tps65010_set_led(LED2, !!(hw_led_state & AMBER_LED));
+
+		/* the gpio led doesn't have that issue */
+		if (leds & RED_LED)
+			tps65010_set_gpio_out_value(GPIO2,
+					!(hw_led_state & RED_LED));
+	}
+}
+
+static DECLARE_WORK(work, tps_work, NULL);
+
+#ifdef	CONFIG_FB_OMAP
+
+/* For now, all system indicators require the Mistral board, since that
+ * LED can be manipulated without a task context.  This LED is either red,
+ * or green, but not both; it can't give the full "disco led" effect.
+ */
+
+#define GPIO_LED_RED		3
+#define GPIO_LED_GREEN		OMAP_MPUIO(4)
+
+static void mistral_setled(void)
+{
+	int	red = 0;
+	int	green = 0;
+
+	if (hw_led_state & TIMER_LED)
+		red = 1;
+	else if (hw_led_state & IDLE_LED)
+		green = 1;
+	// else both sides are disabled
+
+	omap_set_gpio_dataout(GPIO_LED_GREEN, green);
+	omap_set_gpio_dataout(GPIO_LED_RED, red);
+}
+
+#endif
+
+void osk_leds_event(led_event_t evt)
+{
+	unsigned long	flags;
+	u16		leds;
+
+	local_irq_save(flags);
+
+	if (!(led_state & LED_STATE_ENABLED) && evt != led_start)
+		goto done;
+
+	leds = hw_led_state;
+	switch (evt) {
+	case led_start:
+		led_state |= LED_STATE_ENABLED;
+		hw_led_state = 0;
+		leds = ~0;
+		break;
+
+	case led_halted:
+	case led_stop:
+		led_state &= ~LED_STATE_ENABLED;
+		hw_led_state = 0;
+		// NOTE:  work may still be pending!!
+		break;
+
+	case led_claim:
+		led_state |= LED_STATE_CLAIMED;
+		hw_led_state = 0;
+		leds = ~0;
+		break;
+
+	case led_release:
+		led_state &= ~LED_STATE_CLAIMED;
+		hw_led_state = 0;
+		break;
+
+#ifdef	CONFIG_FB_OMAP
+
+	case led_timer:
+		hw_led_state ^= TIMER_LED;
+		mistral_setled();
+		break;
+
+	case led_idle_start:
+		hw_led_state |= IDLE_LED;
+		mistral_setled();
+		break;
+
+	case led_idle_end:
+		hw_led_state &= ~IDLE_LED;
+		mistral_setled();
+		break;
+
+#endif	/* CONFIG_FB_OMAP */
+
+	/* "green" == tps LED1 (leftmost, normally power-good)
+	 * works only with DC adapter, not on battery power!
+	 */
+	case led_green_on:
+		if (led_state & LED_STATE_CLAIMED)
+			hw_led_state |= GREEN_LED;
+		break;
+	case led_green_off:
+		if (led_state & LED_STATE_CLAIMED)
+			hw_led_state &= ~GREEN_LED;
+		break;
+
+	/* "amber" == tps LED2 (middle) */
+	case led_amber_on:
+		if (led_state & LED_STATE_CLAIMED)
+			hw_led_state |= AMBER_LED;
+		break;
+	case led_amber_off:
+		if (led_state & LED_STATE_CLAIMED)
+			hw_led_state &= ~AMBER_LED;
+		break;
+
+	/* "red" == LED on tps gpio3 (rightmost) */
+	case led_red_on:
+		if (led_state & LED_STATE_CLAIMED)
+			hw_led_state |= RED_LED;
+		break;
+	case led_red_off:
+		if (led_state & LED_STATE_CLAIMED)
+			hw_led_state &= ~RED_LED;
+		break;
+
+	default:
+		break;
+	}
+
+	leds ^= hw_led_state;
+	leds &= TPS_LEDS;
+	if (leds && (led_state & LED_STATE_CLAIMED)) {
+		tps_leds_change |= leds;
+		schedule_work(&work);
+	}
+
+done:
+	local_irq_restore(flags);
+}
diff --git a/arch/arm/mach-omap1/leds.c b/arch/arm/mach-omap1/leds.c
new file mode 100644
--- /dev/null
+++ b/arch/arm/mach-omap1/leds.c
@@ -0,0 +1,61 @@
+/*
+ * linux/arch/arm/mach-omap/leds.c
+ *
+ * OMAP LEDs dispatcher
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/leds.h>
+#include <asm/mach-types.h>
+
+#include <asm/arch/gpio.h>
+#include <asm/arch/mux.h>
+
+#include "leds.h"
+
+static int __init
+omap_leds_init(void)
+{
+	if (machine_is_omap_innovator())
+		leds_event = innovator_leds_event;
+
+	else if (machine_is_omap_h2() || machine_is_omap_perseus2())
+		leds_event = h2p2_dbg_leds_event;
+
+	else if (machine_is_omap_osk())
+		leds_event = osk_leds_event;
+
+	else
+		return -1;
+
+	if (machine_is_omap_h2()
+			|| machine_is_omap_perseus2()
+			|| machine_is_omap_osk()) {
+
+		/* LED1/LED2 pins can be used as GPIO (as done here), or by
+		 * the LPG (works even in deep sleep!), to drive a bicolor
+		 * LED on the H2 sample board, and another on the H2/P2
+		 * "surfer" expansion board.
+		 *
+		 * The same pins drive a LED on the OSK Mistral board, but
+		 * that's a different kind of LED (just one color at a time).
+		 */
+		omap_cfg_reg(P18_1610_GPIO3);
+		if (omap_request_gpio(3) == 0)
+			omap_set_gpio_direction(3, 0);
+		else
+			printk(KERN_WARNING "LED: can't get GPIO3/red?\n");
+
+		omap_cfg_reg(MPUIO4);
+		if (omap_request_gpio(OMAP_MPUIO(4)) == 0)
+			omap_set_gpio_direction(OMAP_MPUIO(4), 0);
+		else
+			printk(KERN_WARNING "LED: can't get MPUIO4/green?\n");
+	}
+
+	leds_event(led_start);
+	return 0;
+}
+
+__initcall(omap_leds_init);
diff --git a/arch/arm/mach-omap1/leds.h b/arch/arm/mach-omap1/leds.h
new file mode 100644
--- /dev/null
+++ b/arch/arm/mach-omap1/leds.h
@@ -0,0 +1,3 @@
+extern void innovator_leds_event(led_event_t evt);
+extern void h2p2_dbg_leds_event(led_event_t evt);
+extern void osk_leds_event(led_event_t evt);
diff --git a/arch/arm/mach-omap1/serial.c b/arch/arm/mach-omap1/serial.c
new file mode 100644
--- /dev/null
+++ b/arch/arm/mach-omap1/serial.c
@@ -0,0 +1,200 @@
+/*
+ * linux/arch/arm/mach-omap1/id.c
+ *
+ * OMAP1 CPU identification code
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/serial.h>
+#include <linux/tty.h>
+#include <linux/serial_8250.h>
+#include <linux/serial_reg.h>
+
+#include <asm/io.h>
+#include <asm/mach-types.h>
+#include <asm/hardware/clock.h>
+
+#include <asm/arch/board.h>
+#include <asm/arch/mux.h>
+#include <asm/arch/fpga.h>
+
+static struct clk * uart1_ck = NULL;
+static struct clk * uart2_ck = NULL;
+static struct clk * uart3_ck = NULL;
+
+static inline unsigned int omap_serial_in(struct plat_serial8250_port *up,
+					  int offset)
+{
+	offset <<= up->regshift;
+	return (unsigned int)__raw_readb(up->membase + offset);
+}
+
+static inline void omap_serial_outp(struct plat_serial8250_port *p, int offset,
+				    int value)
+{
+	offset <<= p->regshift;
+	__raw_writeb(value, p->membase + offset);
+}
+
+/*
+ * Internal UARTs need to be initialized for the 8250 autoconfig to work
+ * properly. Note that the TX watermark initialization may not be needed
+ * once the 8250.c watermark handling code is merged.
+ */
+static void __init omap_serial_reset(struct plat_serial8250_port *p)
+{
+	omap_serial_outp(p, UART_OMAP_MDR1, 0x07);	/* disable UART */
+	omap_serial_outp(p, UART_OMAP_SCR, 0x08);	/* TX watermark */
+	omap_serial_outp(p, UART_OMAP_MDR1, 0x00);	/* enable UART */
+
+	if (!cpu_is_omap1510()) {
+		omap_serial_outp(p, UART_OMAP_SYSC, 0x01);
+		while (!(omap_serial_in(p, UART_OMAP_SYSC) & 0x01));
+	}
+}
+
+static struct plat_serial8250_port serial_platform_data[] = {
+	{
+		.membase	= (char*)IO_ADDRESS(OMAP_UART1_BASE),
+		.mapbase	= (unsigned long)OMAP_UART1_BASE,
+		.irq		= INT_UART1,
+		.flags		= UPF_BOOT_AUTOCONF,
+		.iotype		= UPIO_MEM,
+		.regshift	= 2,
+		.uartclk	= OMAP16XX_BASE_BAUD * 16,
+	},
+	{
+		.membase	= (char*)IO_ADDRESS(OMAP_UART2_BASE),
+		.mapbase	= (unsigned long)OMAP_UART2_BASE,
+		.irq		= INT_UART2,
+		.flags		= UPF_BOOT_AUTOCONF,
+		.iotype		= UPIO_MEM,
+		.regshift	= 2,
+		.uartclk	= OMAP16XX_BASE_BAUD * 16,
+	},
+	{
+		.membase	= (char*)IO_ADDRESS(OMAP_UART3_BASE),
+		.mapbase	= (unsigned long)OMAP_UART3_BASE,
+		.irq		= INT_UART3,
+		.flags		= UPF_BOOT_AUTOCONF,
+		.iotype		= UPIO_MEM,
+		.regshift	= 2,
+		.uartclk	= OMAP16XX_BASE_BAUD * 16,
+	},
+	{ },
+};
+
+static struct platform_device serial_device = {
+	.name			= "serial8250",
+	.id			= 0,
+	.dev			= {
+		.platform_data	= serial_platform_data,
+	},
+};
+
+/*
+ * Note that on Innovator-1510 UART2 pins conflict with USB2.
+ * By default UART2 does not work on Innovator-1510 if you have
+ * USB OHCI enabled. To use UART2, you must disable USB2 first.
+ */
+void __init omap_serial_init(int ports[OMAP_MAX_NR_PORTS])
+{
+	int i;
+
+	if (cpu_is_omap730()) {
+		serial_platform_data[0].regshift = 0;
+		serial_platform_data[1].regshift = 0;
+		serial_platform_data[0].irq = INT_730_UART_MODEM_1;
+		serial_platform_data[1].irq = INT_730_UART_MODEM_IRDA_2;
+	}
+
+	if (cpu_is_omap1510()) {
+		serial_platform_data[0].uartclk = OMAP1510_BASE_BAUD * 16;
+		serial_platform_data[1].uartclk = OMAP1510_BASE_BAUD * 16;
+		serial_platform_data[2].uartclk = OMAP1510_BASE_BAUD * 16;
+	}
+
+	for (i = 0; i < OMAP_MAX_NR_PORTS; i++) {
+		unsigned char reg;
+
+		if (ports[i] == 0) {
+			serial_platform_data[i].membase = NULL;
+			serial_platform_data[i].mapbase = 0;
+			continue;
+		}
+
+		switch (i) {
+		case 0:
+			uart1_ck = clk_get(NULL, "uart1_ck");
+			if (IS_ERR(uart1_ck))
+				printk("Could not get uart1_ck\n");
+			else {
+				clk_use(uart1_ck);
+				if (cpu_is_omap1510())
+					clk_set_rate(uart1_ck, 12000000);
+			}
+			if (cpu_is_omap1510()) {
+				omap_cfg_reg(UART1_TX);
+				omap_cfg_reg(UART1_RTS);
+				if (machine_is_omap_innovator()) {
+					reg = fpga_read(OMAP1510_FPGA_POWER);
+					reg |= OMAP1510_FPGA_PCR_COM1_EN;
+					fpga_write(reg, OMAP1510_FPGA_POWER);
+					udelay(10);
+				}
+			}
+			break;
+		case 1:
+			uart2_ck = clk_get(NULL, "uart2_ck");
+			if (IS_ERR(uart2_ck))
+				printk("Could not get uart2_ck\n");
+			else {
+				clk_use(uart2_ck);
+				if (cpu_is_omap1510())
+					clk_set_rate(uart2_ck, 12000000);
+				else
+					clk_set_rate(uart2_ck, 48000000);
+			}
+			if (cpu_is_omap1510()) {
+				omap_cfg_reg(UART2_TX);
+				omap_cfg_reg(UART2_RTS);
+				if (machine_is_omap_innovator()) {
+					reg = fpga_read(OMAP1510_FPGA_POWER);
+					reg |= OMAP1510_FPGA_PCR_COM2_EN;
+					fpga_write(reg, OMAP1510_FPGA_POWER);
+					udelay(10);
+				}
+			}
+			break;
+		case 2:
+			uart3_ck = clk_get(NULL, "uart3_ck");
+			if (IS_ERR(uart3_ck))
+				printk("Could not get uart3_ck\n");
+			else {
+				clk_use(uart3_ck);
+				if (cpu_is_omap1510())
+					clk_set_rate(uart3_ck, 12000000);
+			}
+			if (cpu_is_omap1510()) {
+				omap_cfg_reg(UART3_TX);
+				omap_cfg_reg(UART3_RX);
+			}
+			break;
+		}
+		omap_serial_reset(&serial_platform_data[i]);
+	}
+}
+
+static int __init omap_init(void)
+{
+	return platform_device_register(&serial_device);
+}
+arch_initcall(omap_init);
diff --git a/arch/arm/mach-omap1/time.c b/arch/arm/mach-omap1/time.c
new file mode 100644
--- /dev/null
+++ b/arch/arm/mach-omap1/time.c
@@ -0,0 +1,436 @@
+/*
+ * linux/arch/arm/mach-omap1/time.c
+ *
+ * OMAP Timers
+ *
+ * Copyright (C) 2004 Nokia Corporation
+ * Partial timer rewrite and additional dynamic tick timer support by
+ * Tony Lindgen <tony@atomide.com> and
+ * Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
+ *
+ * MPU timer code based on the older MPU timer code for OMAP
+ * Copyright (C) 2000 RidgeRun, Inc.
+ * Author: Greg Lonnon <glonnon@ridgerun.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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the  GNU General Public License along
+ * with this program; if not, write  to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+
+#include <asm/system.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/leds.h>
+#include <asm/irq.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/time.h>
+
+struct sys_timer omap_timer;
+
+#ifdef CONFIG_OMAP_MPU_TIMER
+
+/*
+ * ---------------------------------------------------------------------------
+ * MPU timer
+ * ---------------------------------------------------------------------------
+ */
+#define OMAP_MPU_TIMER_BASE		OMAP_MPU_TIMER1_BASE
+#define OMAP_MPU_TIMER_OFFSET		0x100
+
+/* cycles to nsec conversions taken from arch/i386/kernel/timers/timer_tsc.c,
+ * converted to use kHz by Kevin Hilman */
+/* convert from cycles(64bits) => nanoseconds (64bits)
+ *  basic equation:
+ *		ns = cycles / (freq / ns_per_sec)
+ *		ns = cycles * (ns_per_sec / freq)
+ *		ns = cycles * (10^9 / (cpu_khz * 10^3))
+ *		ns = cycles * (10^6 / cpu_khz)
+ *
+ *	Then we use scaling math (suggested by george at mvista.com) to get:
+ *		ns = cycles * (10^6 * SC / cpu_khz / SC
+ *		ns = cycles * cyc2ns_scale / SC
+ *
+ *	And since SC is a constant power of two, we can convert the div
+ *  into a shift.
+ *			-johnstul at us.ibm.com "math is hard, lets go shopping!"
+ */
+static unsigned long cyc2ns_scale;
+#define CYC2NS_SCALE_FACTOR 10 /* 2^10, carefully chosen */
+
+static inline void set_cyc2ns_scale(unsigned long cpu_khz)
+{
+	cyc2ns_scale = (1000000 << CYC2NS_SCALE_FACTOR)/cpu_khz;
+}
+
+static inline unsigned long long cycles_2_ns(unsigned long long cyc)
+{
+	return (cyc * cyc2ns_scale) >> CYC2NS_SCALE_FACTOR;
+}
+
+/*
+ * MPU_TICKS_PER_SEC must be an even number, otherwise machinecycles_to_usecs
+ * will break. On P2, the timer count rate is 6.5 MHz after programming PTV
+ * with 0. This divides the 13MHz input by 2, and is undocumented.
+ */
+#ifdef CONFIG_MACH_OMAP_PERSEUS2
+/* REVISIT: This ifdef construct should be replaced by a query to clock
+ * framework to see if timer base frequency is 12.0, 13.0 or 19.2 MHz.
+ */
+#define MPU_TICKS_PER_SEC		(13000000 / 2)
+#else
+#define MPU_TICKS_PER_SEC		(12000000 / 2)
+#endif
+
+#define MPU_TIMER_TICK_PERIOD		((MPU_TICKS_PER_SEC / HZ) - 1)
+
+typedef struct {
+	u32 cntl;			/* CNTL_TIMER, R/W */
+	u32 load_tim;			/* LOAD_TIM,   W */
+	u32 read_tim;			/* READ_TIM,   R */
+} omap_mpu_timer_regs_t;
+
+#define omap_mpu_timer_base(n)						\
+((volatile omap_mpu_timer_regs_t*)IO_ADDRESS(OMAP_MPU_TIMER_BASE +	\
+				 (n)*OMAP_MPU_TIMER_OFFSET))
+
+static inline unsigned long omap_mpu_timer_read(int nr)
+{
+	volatile omap_mpu_timer_regs_t* timer = omap_mpu_timer_base(nr);
+	return timer->read_tim;
+}
+
+static inline void omap_mpu_timer_start(int nr, unsigned long load_val)
+{
+	volatile omap_mpu_timer_regs_t* timer = omap_mpu_timer_base(nr);
+
+	timer->cntl = MPU_TIMER_CLOCK_ENABLE;
+	udelay(1);
+	timer->load_tim = load_val;
+        udelay(1);
+	timer->cntl = (MPU_TIMER_CLOCK_ENABLE | MPU_TIMER_AR | MPU_TIMER_ST);
+}
+
+unsigned long omap_mpu_timer_ticks_to_usecs(unsigned long nr_ticks)
+{
+	unsigned long long nsec;
+
+	nsec = cycles_2_ns((unsigned long long)nr_ticks);
+	return (unsigned long)nsec / 1000;
+}
+
+/*
+ * Last processed system timer interrupt
+ */
+static unsigned long omap_mpu_timer_last = 0;
+
+/*
+ * Returns elapsed usecs since last system timer interrupt
+ */
+static unsigned long omap_mpu_timer_gettimeoffset(void)
+{
+	unsigned long now = 0 - omap_mpu_timer_read(0);
+	unsigned long elapsed = now - omap_mpu_timer_last;
+
+	return omap_mpu_timer_ticks_to_usecs(elapsed);
+}
+
+/*
+ * Elapsed time between interrupts is calculated using timer0.
+ * Latency during the interrupt is calculated using timer1.
+ * Both timer0 and timer1 are counting at 6MHz (P2 6.5MHz).
+ */
+static irqreturn_t omap_mpu_timer_interrupt(int irq, void *dev_id,
+					struct pt_regs *regs)
+{
+	unsigned long now, latency;
+
+	write_seqlock(&xtime_lock);
+	now = 0 - omap_mpu_timer_read(0);
+	latency = MPU_TICKS_PER_SEC / HZ - omap_mpu_timer_read(1);
+	omap_mpu_timer_last = now - latency;
+	timer_tick(regs);
+	write_sequnlock(&xtime_lock);
+
+	return IRQ_HANDLED;
+}
+
+static struct irqaction omap_mpu_timer_irq = {
+	.name		= "mpu timer",
+	.flags		= SA_INTERRUPT | SA_TIMER,
+	.handler	= omap_mpu_timer_interrupt,
+};
+
+static unsigned long omap_mpu_timer1_overflows;
+static irqreturn_t omap_mpu_timer1_interrupt(int irq, void *dev_id,
+					     struct pt_regs *regs)
+{
+	omap_mpu_timer1_overflows++;
+	return IRQ_HANDLED;
+}
+
+static struct irqaction omap_mpu_timer1_irq = {
+	.name		= "mpu timer1 overflow",
+	.flags		= SA_INTERRUPT,
+	.handler	= omap_mpu_timer1_interrupt,
+};
+
+static __init void omap_init_mpu_timer(void)
+{
+	set_cyc2ns_scale(MPU_TICKS_PER_SEC / 1000);
+	omap_timer.offset = omap_mpu_timer_gettimeoffset;
+	setup_irq(INT_TIMER1, &omap_mpu_timer1_irq);
+	setup_irq(INT_TIMER2, &omap_mpu_timer_irq);
+	omap_mpu_timer_start(0, 0xffffffff);
+	omap_mpu_timer_start(1, MPU_TIMER_TICK_PERIOD);
+}
+
+/*
+ * Scheduler clock - returns current time in nanosec units.
+ */
+unsigned long long sched_clock(void)
+{
+	unsigned long ticks = 0 - omap_mpu_timer_read(0);
+	unsigned long long ticks64;
+
+	ticks64 = omap_mpu_timer1_overflows;
+	ticks64 <<= 32;
+	ticks64 |= ticks;
+
+	return cycles_2_ns(ticks64);
+}
+#endif	/* CONFIG_OMAP_MPU_TIMER */
+
+#ifdef CONFIG_OMAP_32K_TIMER
+
+#ifdef CONFIG_ARCH_OMAP1510
+#error OMAP 32KHz timer does not currently work on 1510!
+#endif
+
+/*
+ * ---------------------------------------------------------------------------
+ * 32KHz OS timer
+ *
+ * This currently works only on 16xx, as 1510 does not have the continuous
+ * 32KHz synchronous timer. The 32KHz synchronous timer is used to keep track
+ * of time in addition to the 32KHz OS timer. Using only the 32KHz OS timer
+ * on 1510 would be possible, but the timer would not be as accurate as
+ * with the 32KHz synchronized timer.
+ * ---------------------------------------------------------------------------
+ */
+#define OMAP_32K_TIMER_BASE		0xfffb9000
+#define OMAP_32K_TIMER_CR		0x08
+#define OMAP_32K_TIMER_TVR		0x00
+#define OMAP_32K_TIMER_TCR		0x04
+
+#define OMAP_32K_TICKS_PER_HZ		(32768 / HZ)
+#if (32768 % HZ) != 0
+/* We cannot ignore modulo.
+ * Potential error can be as high as several percent.
+ */
+#define OMAP_32K_TICK_MODULO		(32768 % HZ)
+static unsigned modulo_count = 0; /* Counts 1/HZ units */
+#endif
+
+/*
+ * TRM says 1 / HZ = ( TVR + 1) / 32768, so TRV = (32768 / HZ) - 1
+ * so with HZ = 100, TVR = 327.68.
+ */
+#define OMAP_32K_TIMER_TICK_PERIOD	((32768 / HZ) - 1)
+#define TIMER_32K_SYNCHRONIZED		0xfffbc410
+
+#define JIFFIES_TO_HW_TICKS(nr_jiffies, clock_rate)			\
+				(((nr_jiffies) * (clock_rate)) / HZ)
+
+static inline void omap_32k_timer_write(int val, int reg)
+{
+	omap_writew(val, reg + OMAP_32K_TIMER_BASE);
+}
+
+static inline unsigned long omap_32k_timer_read(int reg)
+{
+	return omap_readl(reg + OMAP_32K_TIMER_BASE) & 0xffffff;
+}
+
+/*
+ * The 32KHz synchronized timer is an additional timer on 16xx.
+ * It is always running.
+ */
+static inline unsigned long omap_32k_sync_timer_read(void)
+{
+	return omap_readl(TIMER_32K_SYNCHRONIZED);
+}
+
+static inline void omap_32k_timer_start(unsigned long load_val)
+{
+	omap_32k_timer_write(load_val, OMAP_32K_TIMER_TVR);
+	omap_32k_timer_write(0x0f, OMAP_32K_TIMER_CR);
+}
+
+static inline void omap_32k_timer_stop(void)
+{
+	omap_32k_timer_write(0x0, OMAP_32K_TIMER_CR);
+}
+
+/*
+ * Rounds down to nearest usec
+ */
+static inline unsigned long omap_32k_ticks_to_usecs(unsigned long ticks_32k)
+{
+	return (ticks_32k * 5*5*5*5*5*5) >> 9;
+}
+
+static unsigned long omap_32k_last_tick = 0;
+
+/*
+ * Returns elapsed usecs since last 32k timer interrupt
+ */
+static unsigned long omap_32k_timer_gettimeoffset(void)
+{
+	unsigned long now = omap_32k_sync_timer_read();
+	return omap_32k_ticks_to_usecs(now - omap_32k_last_tick);
+}
+
+/*
+ * Timer interrupt for 32KHz timer. When dynamic tick is enabled, this
+ * function is also called from other interrupts to remove latency
+ * issues with dynamic tick. In the dynamic tick case, we need to lock
+ * with irqsave.
+ */
+static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id,
+					    struct pt_regs *regs)
+{
+	unsigned long flags;
+	unsigned long now;
+
+	write_seqlock_irqsave(&xtime_lock, flags);
+	now = omap_32k_sync_timer_read();
+
+	while (now - omap_32k_last_tick >= OMAP_32K_TICKS_PER_HZ) {
+#ifdef OMAP_32K_TICK_MODULO
+		/* Modulo addition may put omap_32k_last_tick ahead of now
+		 * and cause unwanted repetition of the while loop.
+		 */
+		if (unlikely(now - omap_32k_last_tick == ~0))
+			break;
+
+		modulo_count += OMAP_32K_TICK_MODULO;
+		if (modulo_count > HZ) {
+			++omap_32k_last_tick;
+			modulo_count -= HZ;
+		}
+#endif
+		omap_32k_last_tick += OMAP_32K_TICKS_PER_HZ;
+		timer_tick(regs);
+	}
+
+	/* Restart timer so we don't drift off due to modulo or dynamic tick.
+	 * By default we program the next timer to be continuous to avoid
+	 * latencies during high system load. During dynamic tick operation the
+	 * continuous timer can be overridden from pm_idle to be longer.
+	 */
+	omap_32k_timer_start(omap_32k_last_tick + OMAP_32K_TICKS_PER_HZ - now);
+	write_sequnlock_irqrestore(&xtime_lock, flags);
+
+	return IRQ_HANDLED;
+}
+
+#ifdef CONFIG_NO_IDLE_HZ
+/*
+ * Programs the next timer interrupt needed. Called when dynamic tick is
+ * enabled, and to reprogram the ticks to skip from pm_idle. Note that
+ * we can keep the timer continuous, and don't need to set it to run in
+ * one-shot mode. This is because the timer will get reprogrammed again
+ * after next interrupt.
+ */
+void omap_32k_timer_reprogram(unsigned long next_tick)
+{
+	omap_32k_timer_start(JIFFIES_TO_HW_TICKS(next_tick, 32768) + 1);
+}
+
+static struct irqaction omap_32k_timer_irq;
+extern struct timer_update_handler timer_update;
+
+static int omap_32k_timer_enable_dyn_tick(void)
+{
+	/* No need to reprogram timer, just use the next interrupt */
+	return 0;
+}
+
+static int omap_32k_timer_disable_dyn_tick(void)
+{
+	omap_32k_timer_start(OMAP_32K_TIMER_TICK_PERIOD);
+	return 0;
+}
+
+static struct dyn_tick_timer omap_dyn_tick_timer = {
+	.enable		= omap_32k_timer_enable_dyn_tick,
+	.disable	= omap_32k_timer_disable_dyn_tick,
+	.reprogram	= omap_32k_timer_reprogram,
+	.handler	= omap_32k_timer_interrupt,
+};
+#endif	/* CONFIG_NO_IDLE_HZ */
+
+static struct irqaction omap_32k_timer_irq = {
+	.name		= "32KHz timer",
+	.flags		= SA_INTERRUPT | SA_TIMER,
+	.handler	= omap_32k_timer_interrupt,
+};
+
+static __init void omap_init_32k_timer(void)
+{
+
+#ifdef CONFIG_NO_IDLE_HZ
+	omap_timer.dyn_tick = &omap_dyn_tick_timer;
+#endif
+
+	setup_irq(INT_OS_TIMER, &omap_32k_timer_irq);
+	omap_timer.offset  = omap_32k_timer_gettimeoffset;
+	omap_32k_last_tick = omap_32k_sync_timer_read();
+	omap_32k_timer_start(OMAP_32K_TIMER_TICK_PERIOD);
+}
+#endif	/* CONFIG_OMAP_32K_TIMER */
+
+/*
+ * ---------------------------------------------------------------------------
+ * Timer initialization
+ * ---------------------------------------------------------------------------
+ */
+static void __init omap_timer_init(void)
+{
+#if defined(CONFIG_OMAP_MPU_TIMER)
+	omap_init_mpu_timer();
+#elif defined(CONFIG_OMAP_32K_TIMER)
+	omap_init_32k_timer();
+#else
+#error No system timer selected in Kconfig!
+#endif
+}
+
+struct sys_timer omap_timer = {
+	.init		= omap_timer_init,
+	.offset		= NULL,		/* Initialized later */
+};
diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile
--- a/arch/arm/mach-pxa/Makefile
+++ b/arch/arm/mach-pxa/Makefile
@@ -24,3 +24,7 @@ obj-$(CONFIG_LEDS) += $(led-y)
 
 # Misc features
 obj-$(CONFIG_PM) += pm.o sleep.o
+
+ifeq ($(CONFIG_PXA27x),y)
+obj-$(CONFIG_PM) += standby.o
+endif
diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c
--- a/arch/arm/mach-pxa/corgi.c
+++ b/arch/arm/mach-pxa/corgi.c
@@ -287,34 +287,40 @@ static void __init corgi_map_io(void)
 
 #ifdef CONFIG_MACH_CORGI
 MACHINE_START(CORGI, "SHARP Corgi")
-	BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000))
-	FIXUP(fixup_corgi)
-	MAPIO(corgi_map_io)
-	INITIRQ(corgi_init_irq)
-	.init_machine = corgi_init,
-	.timer = &pxa_timer,
+	.phys_ram	= 0xa0000000,
+	.phys_io	= 0x40000000,
+	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
+	.fixup		= fixup_corgi,
+	.map_io		= corgi_map_io,
+	.init_irq	= corgi_init_irq,
+	.init_machine	= corgi_init,
+	.timer		= &pxa_timer,
 MACHINE_END
 #endif
 
 #ifdef CONFIG_MACH_SHEPHERD
 MACHINE_START(SHEPHERD, "SHARP Shepherd")
-	BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000))
-	FIXUP(fixup_corgi)
-	MAPIO(corgi_map_io)
-	INITIRQ(corgi_init_irq)
-	.init_machine = corgi_init,
-	.timer = &pxa_timer,
+	.phys_ram	= 0xa0000000,
+	.phys_io	= 0x40000000,
+	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
+	.fixup		= fixup_corgi,
+	.map_io		= corgi_map_io,
+	.init_irq	= corgi_init_irq,
+	.init_machine	= corgi_init,
+	.timer		= &pxa_timer,
 MACHINE_END
 #endif
 
 #ifdef CONFIG_MACH_HUSKY
 MACHINE_START(HUSKY, "SHARP Husky")
-	BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000))
-	FIXUP(fixup_corgi)
-	MAPIO(corgi_map_io)
-	INITIRQ(corgi_init_irq)
-	.init_machine = corgi_init,
-	.timer = &pxa_timer,
+	.phys_ram	= 0xa0000000,
+	.phys_io	= 0x40000000,
+	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
+	.fixup		= fixup_corgi,
+	.map_io		= corgi_map_io,
+	.init_irq	= corgi_init_irq,
+	.init_machine	= corgi_init,
+	.timer		= &pxa_timer,
 MACHINE_END
 #endif
 
diff --git a/arch/arm/mach-pxa/idp.c b/arch/arm/mach-pxa/idp.c
--- a/arch/arm/mach-pxa/idp.c
+++ b/arch/arm/mach-pxa/idp.c
@@ -181,10 +181,12 @@ static void __init idp_map_io(void)
 
 
 MACHINE_START(PXA_IDP, "Vibren PXA255 IDP")
-	MAINTAINER("Vibren Technologies")
-	BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000))
-	MAPIO(idp_map_io)
-	INITIRQ(idp_init_irq)
+	/* Maintainer: Vibren Technologies */
+	.phys_ram	= 0xa0000000,
+	.phys_io	= 0x40000000,
+	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
+	.map_io		= idp_map_io,
+	.init_irq	= idp_init_irq,
 	.timer		= &pxa_timer,
-	INIT_MACHINE(idp_init)
+	.init_machine	= idp_init,
 MACHINE_END
diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c
--- a/arch/arm/mach-pxa/lubbock.c
+++ b/arch/arm/mach-pxa/lubbock.c
@@ -268,10 +268,12 @@ static void __init lubbock_map_io(void)
 }
 
 MACHINE_START(LUBBOCK, "Intel DBPXA250 Development Platform (aka Lubbock)")
-	MAINTAINER("MontaVista Software Inc.")
-	BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000))
-	MAPIO(lubbock_map_io)
-	INITIRQ(lubbock_init_irq)
+	/* Maintainer: MontaVista Software Inc. */
+	.phys_ram	= 0xa0000000,
+	.phys_io	= 0x40000000,
+	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
+	.map_io		= lubbock_map_io,
+	.init_irq	= lubbock_init_irq,
 	.timer		= &pxa_timer,
-	INIT_MACHINE(lubbock_init)
+	.init_machine	= lubbock_init,
 MACHINE_END
diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c
--- a/arch/arm/mach-pxa/mainstone.c
+++ b/arch/arm/mach-pxa/mainstone.c
@@ -345,10 +345,12 @@ static void __init mainstone_map_io(void
 }
 
 MACHINE_START(MAINSTONE, "Intel HCDDBBVA0 Development Platform (aka Mainstone)")
-	MAINTAINER("MontaVista Software Inc.")
-	BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000))
-	MAPIO(mainstone_map_io)
-	INITIRQ(mainstone_init_irq)
+	/* Maintainer: MontaVista Software Inc. */
+	.phys_ram	= 0xa0000000,
+	.phys_io	= 0x40000000,
+	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
+	.map_io		= mainstone_map_io,
+	.init_irq	= mainstone_init_irq,
 	.timer		= &pxa_timer,
-	INIT_MACHINE(mainstone_init)
+	.init_machine	= mainstone_init,
 MACHINE_END
diff --git a/arch/arm/mach-pxa/pm.c b/arch/arm/mach-pxa/pm.c
--- a/arch/arm/mach-pxa/pm.c
+++ b/arch/arm/mach-pxa/pm.c
@@ -133,6 +133,8 @@ static int pxa_pm_enter(suspend_state_t 
 	/* *** go zzz *** */
 	pxa_cpu_pm_enter(state);
 
+	cpu_init();
+
 	/* after sleeping, validate the checksum */
 	checksum = 0;
 	for (i = 0; i < SLEEP_SAVE_SIZE - 1; i++)
diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c
--- a/arch/arm/mach-pxa/poodle.c
+++ b/arch/arm/mach-pxa/poodle.c
@@ -180,10 +180,12 @@ static void __init poodle_map_io(void)
 }
 
 MACHINE_START(POODLE, "SHARP Poodle")
-	BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000))
-	FIXUP(fixup_poodle)
-	MAPIO(poodle_map_io)
-	INITIRQ(pxa_init_irq)
-	.timer = &pxa_timer,
-	.init_machine = poodle_init,
+	.phys_ram	= 0xa0000000,
+	.phys_io	= 0x40000000,
+	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
+	.fixup		= fixup_poodle,
+	.map_io		= poodle_map_io,
+	.init_irq	= pxa_init_irq,
+	.timer		= &pxa_timer,
+	.init_machine	= poodle_init,
 MACHINE_END
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c
--- a/arch/arm/mach-pxa/pxa27x.c
+++ b/arch/arm/mach-pxa/pxa27x.c
@@ -126,6 +126,7 @@ int pxa_cpu_pm_prepare(suspend_state_t s
 {
 	switch (state) {
 	case PM_SUSPEND_MEM:
+	case PM_SUSPEND_STANDBY:
 		return 0;
 	default:
 		return -EINVAL;
@@ -138,7 +139,10 @@ void pxa_cpu_pm_enter(suspend_state_t st
 	extern void pxa_cpu_suspend(unsigned int);
 	extern void pxa_cpu_resume(void);
 
-	CKEN = CKEN22_MEMC | CKEN9_OSTIMER;
+	if (state == PM_SUSPEND_STANDBY)
+		CKEN = CKEN22_MEMC | CKEN9_OSTIMER | CKEN16_LCD |CKEN0_PWM0;
+	else
+		CKEN = CKEN22_MEMC | CKEN9_OSTIMER;
 
 	/* ensure voltage-change sequencer not initiated, which hangs */
 	PCFR &= ~PCFR_FVC;
@@ -147,6 +151,9 @@ void pxa_cpu_pm_enter(suspend_state_t st
 	PEDR = 0xDF12FE1B;
 
 	switch (state) {
+	case PM_SUSPEND_STANDBY:
+		pxa_cpu_standby();
+		break;
 	case PM_SUSPEND_MEM:
 		/* set resume return address */
 		PSPR = virt_to_phys(pxa_cpu_resume);
diff --git a/arch/arm/mach-pxa/standby.S b/arch/arm/mach-pxa/standby.S
new file mode 100644
--- /dev/null
+++ b/arch/arm/mach-pxa/standby.S
@@ -0,0 +1,32 @@
+/*
+ * PXA27x standby mode
+ *
+ * Author: David Burrage
+ *
+ * 2005 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+
+#include <linux/config.h>
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/hardware.h>
+
+#include <asm/arch/pxa-regs.h>
+
+		.text
+
+ENTRY(pxa_cpu_standby)
+	ldr	r0, =PSSR
+	mov	r1, #(PSSR_PH | PSSR_STS)
+	mov	r2, #2
+	mov	r3, #UNCACHED_PHYS_0	@ Read mem context in.
+	ldr	ip, [r3]
+	b	1f
+
+	.align	5
+1:	mcr	p14, 0, r2, c7, c0, 0	@ put the system into Standby
+	str	r1, [r0]		@ make sure PSSR_PH/STS are clear
+	mov	pc, lr
diff --git a/arch/arm/mach-pxa/time.c b/arch/arm/mach-pxa/time.c
--- a/arch/arm/mach-pxa/time.c
+++ b/arch/arm/mach-pxa/time.c
@@ -105,8 +105,8 @@ pxa_timer_interrupt(int irq, void *dev_i
 
 static struct irqaction pxa_timer_irq = {
 	.name		= "PXA Timer Tick",
-	.flags		= SA_INTERRUPT,
-	.handler	= pxa_timer_interrupt
+	.flags		= SA_INTERRUPT | SA_TIMER,
+	.handler	= pxa_timer_interrupt,
 };
 
 static void __init pxa_timer_init(void)
diff --git a/arch/arm/mach-rpc/riscpc.c b/arch/arm/mach-rpc/riscpc.c
--- a/arch/arm/mach-rpc/riscpc.c
+++ b/arch/arm/mach-rpc/riscpc.c
@@ -32,10 +32,7 @@
 
 extern void rpc_init_irq(void);
 
-extern unsigned int vram_size;
-
-#if 0
-
+unsigned int vram_size;
 unsigned int memc_ctrl_reg;
 unsigned int number_mfm_drives;
 
@@ -63,8 +60,6 @@ static int __init parse_tag_acorn(const 
 
 __tagtable(ATAG_ACORN, parse_tag_acorn);
 
-#endif
-
 static struct map_desc rpc_io_desc[] __initdata = {
  { SCREEN_BASE,	SCREEN_START,	2*1048576, MT_DEVICE }, /* VRAM		*/
  { (u32)IO_BASE, IO_START,	IO_SIZE	 , MT_DEVICE }, /* IO space	*/
@@ -168,12 +163,14 @@ arch_initcall(rpc_init);
 extern struct sys_timer ioc_timer;
 
 MACHINE_START(RISCPC, "Acorn-RiscPC")
-	MAINTAINER("Russell King")
-	BOOT_MEM(0x10000000, 0x03000000, 0xe0000000)
-	BOOT_PARAMS(0x10000100)
-	DISABLE_PARPORT(0)
-	DISABLE_PARPORT(1)
-	MAPIO(rpc_map_io)
-	INITIRQ(rpc_init_irq)
+	/* Maintainer: Russell King */
+	.phys_ram	= 0x10000000,
+	.phys_io	= 0x03000000,
+	.io_pg_offst	= ((0xe0000000) >> 18) & 0xfffc,
+	.boot_params	= 0x10000100,
+	.reserve_lp0	= 1,
+	.reserve_lp1	= 1,
+	.map_io		= rpc_map_io,
+	.init_irq	= rpc_init_irq,
 	.timer		= &ioc_timer,
 MACHINE_END
diff --git a/arch/arm/mach-s3c2410/Kconfig b/arch/arm/mach-s3c2410/Kconfig
--- a/arch/arm/mach-s3c2410/Kconfig
+++ b/arch/arm/mach-s3c2410/Kconfig
@@ -154,6 +154,11 @@ config S3C2410_PM_CHECK_CHUNKSIZE
 	  the CRC data block will take more memory, but wil identify any
 	  faults with better precision.
 
+config PM_SIMTEC
+	bool
+	depends on PM && (ARCH_BAST || MACH_VR1000)
+	default y
+
 config S3C2410_LOWLEVEL_UART_PORT
 	int "S3C2410 UART to use for low-level messages"
 	default 0
diff --git a/arch/arm/mach-s3c2410/Makefile b/arch/arm/mach-s3c2410/Makefile
--- a/arch/arm/mach-s3c2410/Makefile
+++ b/arch/arm/mach-s3c2410/Makefile
@@ -18,10 +18,13 @@ obj-$(CONFIG_S3C2410_DMA)  += dma.o
 # Power Management support
 
 obj-$(CONFIG_PM)	   += pm.o sleep.o
+obj-$(CONFIG_PM_SIMTEC)	   += pm-simtec.o
 
 # S3C2440 support
 
 obj-$(CONFIG_CPU_S3C2440)  += s3c2440.o s3c2440-dsc.o
+obj-$(CONFIG_CPU_S3C2440)  += s3c2440-irq.o
+obj-$(CONFIG_CPU_S3C2440)  += s3c2440-clock.o
 
 # machine specific support
 
diff --git a/arch/arm/mach-s3c2410/clock.c b/arch/arm/mach-s3c2410/clock.c
--- a/arch/arm/mach-s3c2410/clock.c
+++ b/arch/arm/mach-s3c2410/clock.c
@@ -448,60 +448,3 @@ int __init s3c24xx_setup_clocks(unsigned
 
 	return 0;
 }
-
-/* S3C2440 extended clock support */
-
-#ifdef CONFIG_CPU_S3C2440
-
-static struct clk s3c2440_clk_upll = {
-	.name		= "upll",
-	.id		= -1,
-};
-
-static struct clk s3c2440_clk_cam = {
-	.name		= "camif",
-	.parent		= &clk_h,
-	.id		= -1,
-	.enable		= s3c24xx_clkcon_enable,
-	.ctrlbit	= S3C2440_CLKCON_CAMERA,
-};
-
-static struct clk s3c2440_clk_ac97 = {
-	.name		= "ac97",
-	.parent		= &clk_p,
-	.id		= -1,
-	.enable		= s3c24xx_clkcon_enable,
-	.ctrlbit	= S3C2440_CLKCON_CAMERA,
-};
-
-static int s3c2440_clk_add(struct sys_device *sysdev)
-{
-	unsigned long upllcon = __raw_readl(S3C2410_UPLLCON);
-
-	s3c2440_clk_upll.rate = s3c2410_get_pll(upllcon, clk_xtal.rate);
-
-	printk("S3C2440: Clock Support, UPLL %ld.%03ld MHz\n",
-	       print_mhz(s3c2440_clk_upll.rate));
-
-	s3c24xx_register_clock(&s3c2440_clk_ac97);
-	s3c24xx_register_clock(&s3c2440_clk_cam);
-	s3c24xx_register_clock(&s3c2440_clk_upll);
-
-	clk_disable(&s3c2440_clk_ac97);
-	clk_disable(&s3c2440_clk_cam);
-
-	return 0;
-}
-
-static struct sysdev_driver s3c2440_clk_driver = {
-	.add	= s3c2440_clk_add,
-};
-
-static int s3c24xx_clk_driver(void)
-{
-	return sysdev_driver_register(&s3c2440_sysclass, &s3c2440_clk_driver);
-}
-
-arch_initcall(s3c24xx_clk_driver);
-
-#endif /* CONFIG_CPU_S3C2440 */
diff --git a/arch/arm/mach-s3c2410/devs.c b/arch/arm/mach-s3c2410/devs.c
--- a/arch/arm/mach-s3c2410/devs.c
+++ b/arch/arm/mach-s3c2410/devs.c
@@ -96,8 +96,8 @@ struct platform_device s3c_device_lcd = 
 	.num_resources	  = ARRAY_SIZE(s3c_lcd_resource),
 	.resource	  = s3c_lcd_resource,
 	.dev              = {
-		.dma_mask = &s3c_device_lcd_dmamask,
-		.coherent_dma_mask = 0xffffffffUL
+		.dma_mask		= &s3c_device_lcd_dmamask,
+		.coherent_dma_mask	= 0xffffffffUL
 	}
 };
 
diff --git a/arch/arm/mach-s3c2410/dma.c b/arch/arm/mach-s3c2410/dma.c
--- a/arch/arm/mach-s3c2410/dma.c
+++ b/arch/arm/mach-s3c2410/dma.c
@@ -436,7 +436,7 @@ int s3c2410_dma_enqueue(unsigned int cha
 
 	buf = kmem_cache_alloc(dma_kmem, GFP_ATOMIC);
 	if (buf == NULL) {
-		pr_debug("%s: out of memory (%d alloc)\n",
+		pr_debug("%s: out of memory (%ld alloc)\n",
 			 __FUNCTION__, sizeof(*buf));
 		return -ENOMEM;
 	}
diff --git a/arch/arm/mach-s3c2410/irq.c b/arch/arm/mach-s3c2410/irq.c
--- a/arch/arm/mach-s3c2410/irq.c
+++ b/arch/arm/mach-s3c2410/irq.c
@@ -40,8 +40,14 @@
  *   04-Nov-2004  Ben Dooks
  *		  Fix standard IRQ wake for EINT0..4 and RTC
  *
- *   22-Feb-2004  Ben Dooks
+ *   22-Feb-2005  Ben Dooks
  *		  Fixed edge-triggering on ADC IRQ
+ *
+ *   28-Jun-2005  Ben Dooks
+ *		  Mark IRQ_LCD valid
+ *
+ *   25-Jul-2005  Ben Dooks
+ *		  Split the S3C2440 IRQ code to seperate file
 */
 
 #include <linux/init.h>
@@ -62,11 +68,7 @@
 
 #include "cpu.h"
 #include "pm.h"
-
-#define irqdbf(x...)
-#define irqdbf2(x...)
-
-#define EXTINT_OFF (IRQ_EINT4 - 4)
+#include "irq.h"
 
 /* wakeup irq control */
 
@@ -178,7 +180,7 @@ s3c_irq_unmask(unsigned int irqno)
 	__raw_writel(mask, S3C2410_INTMSK);
 }
 
-static struct irqchip s3c_irq_level_chip = {
+struct irqchip s3c_irq_level_chip = {
 	.ack	   = s3c_irq_maskack,
 	.mask	   = s3c_irq_mask,
 	.unmask	   = s3c_irq_unmask,
@@ -366,86 +368,7 @@ static struct irqchip s3c_irq_eint0t4 = 
 #define INTMSK_UART1	 (1UL << (IRQ_UART1 - IRQ_EINT0))
 #define INTMSK_UART2	 (1UL << (IRQ_UART2 - IRQ_EINT0))
 #define INTMSK_ADCPARENT (1UL << (IRQ_ADCPARENT - IRQ_EINT0))
-#define INTMSK_LCD	 (1UL << (IRQ_LCD - IRQ_EINT0))
-
-static inline void
-s3c_irqsub_mask(unsigned int irqno, unsigned int parentbit,
-		int subcheck)
-{
-	unsigned long mask;
-	unsigned long submask;
-
-	submask = __raw_readl(S3C2410_INTSUBMSK);
-	mask = __raw_readl(S3C2410_INTMSK);
-
-	submask |= (1UL << (irqno - IRQ_S3CUART_RX0));
-
-	/* check to see if we need to mask the parent IRQ */
-
-	if ((submask  & subcheck) == subcheck) {
-		__raw_writel(mask | parentbit, S3C2410_INTMSK);
-	}
-
-	/* write back masks */
-	__raw_writel(submask, S3C2410_INTSUBMSK);
-
-}
-
-static inline void
-s3c_irqsub_unmask(unsigned int irqno, unsigned int parentbit)
-{
-	unsigned long mask;
-	unsigned long submask;
-
-	submask = __raw_readl(S3C2410_INTSUBMSK);
-	mask = __raw_readl(S3C2410_INTMSK);
-
-	submask &= ~(1UL << (irqno - IRQ_S3CUART_RX0));
-	mask &= ~parentbit;
-
-	/* write back masks */
-	__raw_writel(submask, S3C2410_INTSUBMSK);
-	__raw_writel(mask, S3C2410_INTMSK);
-}
-
-
-static inline void
-s3c_irqsub_maskack(unsigned int irqno, unsigned int parentmask, unsigned int group)
-{
-	unsigned int bit = 1UL << (irqno - IRQ_S3CUART_RX0);
-
-	s3c_irqsub_mask(irqno, parentmask, group);
-
-	__raw_writel(bit, S3C2410_SUBSRCPND);
-
-	/* only ack parent if we've got all the irqs (seems we must
-	 * ack, all and hope that the irq system retriggers ok when
-	 * the interrupt goes off again)
-	 */
-
-	if (1) {
-		__raw_writel(parentmask, S3C2410_SRCPND);
-		__raw_writel(parentmask, S3C2410_INTPND);
-	}
-}
-
-static inline void
-s3c_irqsub_ack(unsigned int irqno, unsigned int parentmask, unsigned int group)
-{
-	unsigned int bit = 1UL << (irqno - IRQ_S3CUART_RX0);
-
-	__raw_writel(bit, S3C2410_SUBSRCPND);
 
-	/* only ack parent if we've got all the irqs (seems we must
-	 * ack, all and hope that the irq system retriggers ok when
-	 * the interrupt goes off again)
-	 */
-
-	if (1) {
-		__raw_writel(parentmask, S3C2410_SRCPND);
-		__raw_writel(parentmask, S3C2410_INTPND);
-	}
-}
 
 /* UART0 */
 
@@ -716,7 +639,6 @@ void __init s3c24xx_init_irq(void)
 		case IRQ_UART0:
 		case IRQ_UART1:
 		case IRQ_UART2:
-		case IRQ_LCD:
 		case IRQ_ADCPARENT:
 			set_irq_chip(irqno, &s3c_irq_level_chip);
 			set_irq_handler(irqno, do_level_IRQ);
@@ -793,174 +715,3 @@ void __init s3c24xx_init_irq(void)
 
 	irqdbf("s3c2410: registered interrupt handlers\n");
 }
-
-/* s3c2440 irq code
-*/
-
-#ifdef CONFIG_CPU_S3C2440
-
-/* WDT/AC97 */
-
-static void s3c_irq_demux_wdtac97(unsigned int irq,
-				  struct irqdesc *desc,
-				  struct pt_regs *regs)
-{
-	unsigned int subsrc, submsk;
-	struct irqdesc *mydesc;
-
-	/* read the current pending interrupts, and the mask
-	 * for what it is available */
-
-	subsrc = __raw_readl(S3C2410_SUBSRCPND);
-	submsk = __raw_readl(S3C2410_INTSUBMSK);
-
-	subsrc &= ~submsk;
-	subsrc >>= 13;
-	subsrc &= 3;
-
-	if (subsrc != 0) {
-		if (subsrc & 1) {
-			mydesc = irq_desc + IRQ_S3C2440_WDT;
-			mydesc->handle( IRQ_S3C2440_WDT, mydesc, regs);
-		}
-		if (subsrc & 2) {
-			mydesc = irq_desc + IRQ_S3C2440_AC97;
-			mydesc->handle(IRQ_S3C2440_AC97, mydesc, regs);
-		}
-	}
-}
-
-
-#define INTMSK_WDT	 (1UL << (IRQ_WDT - IRQ_EINT0))
-
-static void
-s3c_irq_wdtac97_mask(unsigned int irqno)
-{
-	s3c_irqsub_mask(irqno, INTMSK_WDT, 3<<13);
-}
-
-static void
-s3c_irq_wdtac97_unmask(unsigned int irqno)
-{
-	s3c_irqsub_unmask(irqno, INTMSK_WDT);
-}
-
-static void
-s3c_irq_wdtac97_ack(unsigned int irqno)
-{
-	s3c_irqsub_maskack(irqno, INTMSK_WDT, 3<<13);
-}
-
-static struct irqchip s3c_irq_wdtac97 = {
-	.mask	    = s3c_irq_wdtac97_mask,
-	.unmask	    = s3c_irq_wdtac97_unmask,
-	.ack	    = s3c_irq_wdtac97_ack,
-};
-
-/* camera irq */
-
-static void s3c_irq_demux_cam(unsigned int irq,
-			      struct irqdesc *desc,
-			      struct pt_regs *regs)
-{
-	unsigned int subsrc, submsk;
-	struct irqdesc *mydesc;
-
-	/* read the current pending interrupts, and the mask
-	 * for what it is available */
-
-	subsrc = __raw_readl(S3C2410_SUBSRCPND);
-	submsk = __raw_readl(S3C2410_INTSUBMSK);
-
-	subsrc &= ~submsk;
-	subsrc >>= 11;
-	subsrc &= 3;
-
-	if (subsrc != 0) {
-		if (subsrc & 1) {
-			mydesc = irq_desc + IRQ_S3C2440_CAM_C;
-			mydesc->handle( IRQ_S3C2440_WDT, mydesc, regs);
-		}
-		if (subsrc & 2) {
-			mydesc = irq_desc + IRQ_S3C2440_CAM_P;
-			mydesc->handle(IRQ_S3C2440_AC97, mydesc, regs);
-		}
-	}
-}
-
-#define INTMSK_CAM (1UL << (IRQ_CAM - IRQ_EINT0))
-
-static void
-s3c_irq_cam_mask(unsigned int irqno)
-{
-	s3c_irqsub_mask(irqno, INTMSK_CAM, 3<<11);
-}
-
-static void
-s3c_irq_cam_unmask(unsigned int irqno)
-{
-	s3c_irqsub_unmask(irqno, INTMSK_CAM);
-}
-
-static void
-s3c_irq_cam_ack(unsigned int irqno)
-{
-	s3c_irqsub_maskack(irqno, INTMSK_CAM, 3<<11);
-}
-
-static struct irqchip s3c_irq_cam = {
-	.mask	    = s3c_irq_cam_mask,
-	.unmask	    = s3c_irq_cam_unmask,
-	.ack	    = s3c_irq_cam_ack,
-};
-
-static int s3c2440_irq_add(struct sys_device *sysdev)
-{
-	unsigned int irqno;
-
-	printk("S3C2440: IRQ Support\n");
-
-	set_irq_chip(IRQ_NFCON, &s3c_irq_level_chip);
-	set_irq_handler(IRQ_NFCON, do_level_IRQ);
-	set_irq_flags(IRQ_NFCON, IRQF_VALID);
-
-	/* add new chained handler for wdt, ac7 */
-
-	set_irq_chip(IRQ_WDT, &s3c_irq_level_chip);
-	set_irq_handler(IRQ_WDT, do_level_IRQ);
-	set_irq_chained_handler(IRQ_WDT, s3c_irq_demux_wdtac97);
-
-	for (irqno = IRQ_S3C2440_WDT; irqno <= IRQ_S3C2440_AC97; irqno++) {
-		set_irq_chip(irqno, &s3c_irq_wdtac97);
-		set_irq_handler(irqno, do_level_IRQ);
-		set_irq_flags(irqno, IRQF_VALID);
-	}
-
-	/* add chained handler for camera */
-
-	set_irq_chip(IRQ_CAM, &s3c_irq_level_chip);
-	set_irq_handler(IRQ_CAM, do_level_IRQ);
-	set_irq_chained_handler(IRQ_CAM, s3c_irq_demux_cam);
-
-	for (irqno = IRQ_S3C2440_CAM_C; irqno <= IRQ_S3C2440_CAM_P; irqno++) {
-		set_irq_chip(irqno, &s3c_irq_cam);
-		set_irq_handler(irqno, do_level_IRQ);
-		set_irq_flags(irqno, IRQF_VALID);
-	}
-
-	return 0;
-}
-
-static struct sysdev_driver s3c2440_irq_driver = {
-	.add	= s3c2440_irq_add,
-};
-
-static int s3c24xx_irq_driver(void)
-{
-	return sysdev_driver_register(&s3c2440_sysclass, &s3c2440_irq_driver);
-}
-
-arch_initcall(s3c24xx_irq_driver);
-
-#endif /* CONFIG_CPU_S3C2440 */
-
diff --git a/arch/arm/mach-s3c2410/irq.h b/arch/arm/mach-s3c2410/irq.h
new file mode 100644
--- /dev/null
+++ b/arch/arm/mach-s3c2410/irq.h
@@ -0,0 +1,99 @@
+/* arch/arm/mach-s3c2410/irq.h
+ *
+ * Copyright (c) 2004-2005 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * Header file for S3C24XX CPU IRQ support
+ *
+ * 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.
+ *
+ * Modifications:
+*/
+
+#define irqdbf(x...)
+#define irqdbf2(x...)
+
+#define EXTINT_OFF (IRQ_EINT4 - 4)
+
+extern struct irqchip s3c_irq_level_chip;
+
+static inline void
+s3c_irqsub_mask(unsigned int irqno, unsigned int parentbit,
+		int subcheck)
+{
+	unsigned long mask;
+	unsigned long submask;
+
+	submask = __raw_readl(S3C2410_INTSUBMSK);
+	mask = __raw_readl(S3C2410_INTMSK);
+
+	submask |= (1UL << (irqno - IRQ_S3CUART_RX0));
+
+	/* check to see if we need to mask the parent IRQ */
+
+	if ((submask  & subcheck) == subcheck) {
+		__raw_writel(mask | parentbit, S3C2410_INTMSK);
+	}
+
+	/* write back masks */
+	__raw_writel(submask, S3C2410_INTSUBMSK);
+
+}
+
+static inline void
+s3c_irqsub_unmask(unsigned int irqno, unsigned int parentbit)
+{
+	unsigned long mask;
+	unsigned long submask;
+
+	submask = __raw_readl(S3C2410_INTSUBMSK);
+	mask = __raw_readl(S3C2410_INTMSK);
+
+	submask &= ~(1UL << (irqno - IRQ_S3CUART_RX0));
+	mask &= ~parentbit;
+
+	/* write back masks */
+	__raw_writel(submask, S3C2410_INTSUBMSK);
+	__raw_writel(mask, S3C2410_INTMSK);
+}
+
+
+static inline void
+s3c_irqsub_maskack(unsigned int irqno, unsigned int parentmask, unsigned int group)
+{
+	unsigned int bit = 1UL << (irqno - IRQ_S3CUART_RX0);
+
+	s3c_irqsub_mask(irqno, parentmask, group);
+
+	__raw_writel(bit, S3C2410_SUBSRCPND);
+
+	/* only ack parent if we've got all the irqs (seems we must
+	 * ack, all and hope that the irq system retriggers ok when
+	 * the interrupt goes off again)
+	 */
+
+	if (1) {
+		__raw_writel(parentmask, S3C2410_SRCPND);
+		__raw_writel(parentmask, S3C2410_INTPND);
+	}
+}
+
+static inline void
+s3c_irqsub_ack(unsigned int irqno, unsigned int parentmask, unsigned int group)
+{
+	unsigned int bit = 1UL << (irqno - IRQ_S3CUART_RX0);
+
+	__raw_writel(bit, S3C2410_SUBSRCPND);
+
+	/* only ack parent if we've got all the irqs (seems we must
+	 * ack, all and hope that the irq system retriggers ok when
+	 * the interrupt goes off again)
+	 */
+
+	if (1) {
+		__raw_writel(parentmask, S3C2410_SRCPND);
+		__raw_writel(parentmask, S3C2410_INTPND);
+	}
+}
diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c
--- a/arch/arm/mach-s3c2410/mach-bast.c
+++ b/arch/arm/mach-s3c2410/mach-bast.c
@@ -25,7 +25,12 @@
  *     14-Jan-2005 BJD  Add support for muitlple NAND devices
  *     03-Mar-2005 BJD  Ensured that bast-cpld.h is included
  *     10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA
- *     14-Mar-2006 BJD  Updated for __iomem changes
+ *     14-Mar-2005 BJD  Updated for __iomem changes
+ *     22-Jun-2005 BJD  Added DM9000 platform information
+ *     28-Jun-2005 BJD  Moved pm functionality out to common code
+ *     17-Jul-2005 BJD  Changed to platform device for SuperIO 16550s
+ *     25-Jul-2005 BJD  Removed ASIX static mappings
+ *     27-Jul-2005 BJD  Ensure maximum frequency of i2c bus
 */
 
 #include <linux/kernel.h>
@@ -35,6 +40,7 @@
 #include <linux/timer.h>
 #include <linux/init.h>
 #include <linux/device.h>
+#include <linux/dm9000.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -53,18 +59,21 @@
 #include <asm/arch/regs-serial.h>
 #include <asm/arch/regs-gpio.h>
 #include <asm/arch/regs-mem.h>
+#include <asm/arch/regs-lcd.h>
 #include <asm/arch/nand.h>
+#include <asm/arch/iic.h>
 
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/nand.h>
 #include <linux/mtd/nand_ecc.h>
 #include <linux/mtd/partitions.h>
 
+#include <linux/serial_8250.h>
+
 #include "clock.h"
 #include "devs.h"
 #include "cpu.h"
 #include "usb-simtec.h"
-#include "pm.h"
 
 #define COPYRIGHT ", (c) 2004-2005 Simtec Electronics"
 
@@ -110,9 +119,7 @@ static struct map_desc bast_iodesc[] __i
   /* slow, byte */
   { VA_C2(BAST_VA_ISAIO),   PA_CS2(BAST_PA_ISAIO),    SZ_16M, MT_DEVICE },
   { VA_C2(BAST_VA_ISAMEM),  PA_CS2(BAST_PA_ISAMEM),   SZ_16M, MT_DEVICE },
-  { VA_C2(BAST_VA_ASIXNET), PA_CS3(BAST_PA_ASIXNET),  SZ_1M,  MT_DEVICE },
   { VA_C2(BAST_VA_SUPERIO), PA_CS2(BAST_PA_SUPERIO),  SZ_1M,  MT_DEVICE },
-  { VA_C2(BAST_VA_DM9000),  PA_CS2(BAST_PA_DM9000),   SZ_1M,  MT_DEVICE },
   { VA_C2(BAST_VA_IDEPRI),  PA_CS3(BAST_PA_IDEPRI),   SZ_1M,  MT_DEVICE },
   { VA_C2(BAST_VA_IDESEC),  PA_CS3(BAST_PA_IDESEC),   SZ_1M,  MT_DEVICE },
   { VA_C2(BAST_VA_IDEPRIAUX), PA_CS3(BAST_PA_IDEPRIAUX), SZ_1M, MT_DEVICE },
@@ -121,9 +128,7 @@ static struct map_desc bast_iodesc[] __i
   /* slow, word */
   { VA_C3(BAST_VA_ISAIO),   PA_CS3(BAST_PA_ISAIO),    SZ_16M, MT_DEVICE },
   { VA_C3(BAST_VA_ISAMEM),  PA_CS3(BAST_PA_ISAMEM),   SZ_16M, MT_DEVICE },
-  { VA_C3(BAST_VA_ASIXNET), PA_CS3(BAST_PA_ASIXNET),  SZ_1M,  MT_DEVICE },
   { VA_C3(BAST_VA_SUPERIO), PA_CS3(BAST_PA_SUPERIO),  SZ_1M,  MT_DEVICE },
-  { VA_C3(BAST_VA_DM9000),  PA_CS3(BAST_PA_DM9000),   SZ_1M,  MT_DEVICE },
   { VA_C3(BAST_VA_IDEPRI),  PA_CS3(BAST_PA_IDEPRI),   SZ_1M,  MT_DEVICE },
   { VA_C3(BAST_VA_IDESEC),  PA_CS3(BAST_PA_IDESEC),   SZ_1M,  MT_DEVICE },
   { VA_C3(BAST_VA_IDEPRIAUX), PA_CS3(BAST_PA_IDEPRIAUX), SZ_1M, MT_DEVICE },
@@ -132,9 +137,7 @@ static struct map_desc bast_iodesc[] __i
   /* fast, byte */
   { VA_C4(BAST_VA_ISAIO),   PA_CS4(BAST_PA_ISAIO),    SZ_16M, MT_DEVICE },
   { VA_C4(BAST_VA_ISAMEM),  PA_CS4(BAST_PA_ISAMEM),   SZ_16M, MT_DEVICE },
-  { VA_C4(BAST_VA_ASIXNET), PA_CS5(BAST_PA_ASIXNET),  SZ_1M,  MT_DEVICE },
   { VA_C4(BAST_VA_SUPERIO), PA_CS4(BAST_PA_SUPERIO),  SZ_1M,  MT_DEVICE },
-  { VA_C4(BAST_VA_DM9000),  PA_CS4(BAST_PA_DM9000),   SZ_1M,  MT_DEVICE },
   { VA_C4(BAST_VA_IDEPRI),  PA_CS5(BAST_PA_IDEPRI),   SZ_1M,  MT_DEVICE },
   { VA_C4(BAST_VA_IDESEC),  PA_CS5(BAST_PA_IDESEC),   SZ_1M,  MT_DEVICE },
   { VA_C4(BAST_VA_IDEPRIAUX), PA_CS5(BAST_PA_IDEPRIAUX), SZ_1M, MT_DEVICE },
@@ -143,9 +146,7 @@ static struct map_desc bast_iodesc[] __i
   /* fast, word */
   { VA_C5(BAST_VA_ISAIO),   PA_CS5(BAST_PA_ISAIO),    SZ_16M, MT_DEVICE },
   { VA_C5(BAST_VA_ISAMEM),  PA_CS5(BAST_PA_ISAMEM),   SZ_16M, MT_DEVICE },
-  { VA_C5(BAST_VA_ASIXNET), PA_CS5(BAST_PA_ASIXNET),  SZ_1M,  MT_DEVICE },
   { VA_C5(BAST_VA_SUPERIO), PA_CS5(BAST_PA_SUPERIO),  SZ_1M,  MT_DEVICE },
-  { VA_C5(BAST_VA_DM9000),  PA_CS5(BAST_PA_DM9000),   SZ_1M,  MT_DEVICE },
   { VA_C5(BAST_VA_IDEPRI),  PA_CS5(BAST_PA_IDEPRI),   SZ_1M,  MT_DEVICE },
   { VA_C5(BAST_VA_IDESEC),  PA_CS5(BAST_PA_IDESEC),   SZ_1M,  MT_DEVICE },
   { VA_C5(BAST_VA_IDEPRIAUX), PA_CS5(BAST_PA_IDEPRIAUX), SZ_1M, MT_DEVICE },
@@ -305,7 +306,7 @@ static void bast_nand_select(struct s3c2
 }
 
 static struct s3c2410_platform_nand bast_nand_info = {
-	.tacls		= 80,
+	.tacls		= 40,
 	.twrph0		= 80,
 	.twrph1		= 80,
 	.nr_sets	= ARRAY_SIZE(bast_nand_sets),
@@ -313,6 +314,89 @@ static struct s3c2410_platform_nand bast
 	.select_chip	= bast_nand_select,
 };
 
+/* DM9000 */
+
+static struct resource bast_dm9k_resource[] = {
+	[0] = {
+		.start = S3C2410_CS5 + BAST_PA_DM9000,
+		.end   = S3C2410_CS5 + BAST_PA_DM9000 + 3,
+		.flags = IORESOURCE_MEM
+	},
+	[1] = {
+		.start = S3C2410_CS5 + BAST_PA_DM9000 + 0x40,
+		.end   = S3C2410_CS5 + BAST_PA_DM9000 + 0x40 + 0x3f,
+		.flags = IORESOURCE_MEM
+	},
+	[2] = {
+		.start = IRQ_DM9000,
+		.end   = IRQ_DM9000,
+		.flags = IORESOURCE_IRQ
+	}
+
+};
+
+/* for the moment we limit ourselves to 16bit IO until some
+ * better IO routines can be written and tested
+*/
+
+struct dm9000_plat_data bast_dm9k_platdata = {
+	.flags		= DM9000_PLATF_16BITONLY
+};
+
+static struct platform_device bast_device_dm9k = {
+	.name		= "dm9000",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(bast_dm9k_resource),
+	.resource	= bast_dm9k_resource,
+	.dev		= {
+		.platform_data = &bast_dm9k_platdata,
+	}
+};
+
+/* serial devices */
+
+#define SERIAL_BASE  (S3C2410_CS2 + BAST_PA_SUPERIO)
+#define SERIAL_FLAGS (UPF_BOOT_AUTOCONF | UPF_IOREMAP | UPF_SHARE_IRQ)
+#define SERIAL_CLK   (1843200)
+
+static struct plat_serial8250_port bast_sio_data[] = {
+	[0] = {
+		.mapbase	= SERIAL_BASE + 0x2f8,
+		.irq		= IRQ_PCSERIAL1,
+		.flags		= SERIAL_FLAGS,
+		.iotype		= UPIO_MEM,
+		.regshift	= 0,
+		.uartclk	= SERIAL_CLK,
+	},
+	[1] = {
+		.mapbase	= SERIAL_BASE + 0x3f8,
+		.irq		= IRQ_PCSERIAL2,
+		.flags		= SERIAL_FLAGS,
+		.iotype		= UPIO_MEM,
+		.regshift	= 0,
+		.uartclk	= SERIAL_CLK,
+	},
+	{ }
+};
+
+static struct platform_device bast_sio = {
+	.name			= "serial8250",
+	.id			= 0,
+	.dev			= {
+		.platform_data	= &bast_sio_data,
+	},
+};
+
+/* we have devices on the bus which cannot work much over the
+ * standard 100KHz i2c bus frequency
+*/
+
+static struct s3c2410_platform_i2c bast_i2c_info = {
+	.flags		= 0,
+	.slave_addr	= 0x10,
+	.bus_freq	= 100*1000,
+	.max_freq	= 130*1000,
+};
 
 /* Standard BAST devices */
 
@@ -324,7 +408,9 @@ static struct platform_device *bast_devi
 	&s3c_device_iis,
  	&s3c_device_rtc,
 	&s3c_device_nand,
-	&bast_device_nor
+	&bast_device_nor,
+	&bast_device_dm9k,
+	&bast_sio,
 };
 
 static struct clk *bast_clocks[] = {
@@ -358,6 +444,7 @@ void __init bast_map_io(void)
 	s3c24xx_uclk.parent  = &s3c24xx_clkout1;
 
 	s3c_device_nand.dev.platform_data = &bast_nand_info;
+	s3c_device_i2c.dev.platform_data = &bast_i2c_info;
 
 	s3c24xx_init_io(bast_iodesc, ARRAY_SIZE(bast_iodesc));
 	s3c24xx_init_clocks(0);
@@ -366,44 +453,14 @@ void __init bast_map_io(void)
 	usb_simtec_init();
 }
 
-void __init bast_init_irq(void)
-{
-	s3c24xx_init_irq();
-}
-
-#ifdef CONFIG_PM
-
-/* bast_init_machine
- *
- * enable the power management functions for the EB2410ITX
-*/
-
-static __init void bast_init_machine(void)
-{
-	unsigned long gstatus4;
-
-	printk(KERN_INFO "BAST Power Manangement" COPYRIGHT "\n");
-
-	gstatus4  = (__raw_readl(S3C2410_BANKCON7) & 0x3) << 30;
-	gstatus4 |= (__raw_readl(S3C2410_BANKCON6) & 0x3) << 28;
-	gstatus4 |= (__raw_readl(S3C2410_BANKSIZE) & S3C2410_BANKSIZE_MASK);
-
-	__raw_writel(gstatus4, S3C2410_GSTATUS4);
-
-	s3c2410_pm_init();
-}
-
-#else
-#define bast_init_machine NULL
-#endif
-
 
 MACHINE_START(BAST, "Simtec-BAST")
-     MAINTAINER("Ben Dooks <ben@simtec.co.uk>")
-     BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, (u32)S3C24XX_VA_UART)
-     BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100)
-     MAPIO(bast_map_io)
-     INITIRQ(bast_init_irq)
-	.init_machine	= bast_init_machine,
+	/* Maintainer: Ben Dooks <ben@simtec.co.uk> */
+	.phys_ram	= S3C2410_SDRAM_PA,
+	.phys_io	= S3C2410_PA_UART,
+	.io_pg_offst	= (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
+	.boot_params	= S3C2410_SDRAM_PA + 0x100,
+	.map_io		= bast_map_io,
+	.init_irq	= s3c24xx_init_irq,
 	.timer		= &s3c24xx_timer,
 MACHINE_END
diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c
--- a/arch/arm/mach-s3c2410/mach-h1940.c
+++ b/arch/arm/mach-s3c2410/mach-h1940.c
@@ -117,10 +117,12 @@ void __init h1940_init_irq(void)
 }
 
 MACHINE_START(H1940, "IPAQ-H1940")
-     MAINTAINER("Ben Dooks <ben@fluff.org>")
-     BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, (u32)S3C24XX_VA_UART)
-     BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100)
-     MAPIO(h1940_map_io)
-     INITIRQ(h1940_init_irq)
+	/* Maintainer: Ben Dooks <ben@fluff.org> */
+	.phys_ram	= S3C2410_SDRAM_PA,
+	.phys_io	= S3C2410_PA_UART,
+	.io_pg_offst	= (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
+	.boot_params	= S3C2410_SDRAM_PA + 0x100,
+	.map_io		= h1940_map_io,
+	.init_irq	= h1940_init_irq,
 	.timer		= &s3c24xx_timer,
 MACHINE_END
diff --git a/arch/arm/mach-s3c2410/mach-n30.c b/arch/arm/mach-s3c2410/mach-n30.c
--- a/arch/arm/mach-s3c2410/mach-n30.c
+++ b/arch/arm/mach-s3c2410/mach-n30.c
@@ -137,10 +137,11 @@ void __init n30_init(void)
 }
 
 MACHINE_START(N30, "Acer-N30")
-     MAINTAINER("Christer Weinigel <christer@weinigel.se>, Ben Dooks <ben-linux@fluff.org>")
-     BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, (u32)S3C24XX_VA_UART)
-     BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100)
-
+	/* Maintainer: Christer Weinigel <christer@weinigel.se>, Ben Dooks <ben-linux@fluff.org> */
+	.phys_ram	= S3C2410_SDRAM_PA,
+	.phys_io	= S3C2410_PA_UART,
+	.io_pg_offst	= (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
+	.boot_params	= S3C2410_SDRAM_PA + 0x100,
 	.timer		= &s3c24xx_timer,
 	.init_machine	= n30_init,
 	.init_irq	= n30_init_irq,
diff --git a/arch/arm/mach-s3c2410/mach-nexcoder.c b/arch/arm/mach-s3c2410/mach-nexcoder.c
--- a/arch/arm/mach-s3c2410/mach-nexcoder.c
+++ b/arch/arm/mach-s3c2410/mach-nexcoder.c
@@ -147,9 +147,11 @@ void __init nexcoder_map_io(void)
 
 
 MACHINE_START(NEXCODER_2440, "NexVision - Nexcoder 2440")
-     MAINTAINER("Guillaume GOURAT <guillaume.gourat@nexvision.tv>")
-     BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, (u32)S3C24XX_VA_UART)
-     BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100)
+	/* Maintainer: Guillaume GOURAT <guillaume.gourat@nexvision.tv> */
+	.phys_ram	= S3C2410_SDRAM_PA,
+	.phys_io	= S3C2410_PA_UART,
+	.io_pg_offst	= (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
+	.boot_params	= S3C2410_SDRAM_PA + 0x100,
 	.map_io		= nexcoder_map_io,
 	.init_irq	= s3c24xx_init_irq,
 	.timer		= &s3c24xx_timer,
diff --git a/arch/arm/mach-s3c2410/mach-otom.c b/arch/arm/mach-s3c2410/mach-otom.c
--- a/arch/arm/mach-s3c2410/mach-otom.c
+++ b/arch/arm/mach-s3c2410/mach-otom.c
@@ -115,9 +115,11 @@ void __init otom11_map_io(void)
 
 
 MACHINE_START(OTOM, "Nex Vision - Otom 1.1")
-     MAINTAINER("Guillaume GOURAT <guillaume.gourat@nexvision.tv>")
-     BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, (u32)S3C24XX_VA_UART)
-     BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100)
+	/* Maintainer: Guillaume GOURAT <guillaume.gourat@nexvision.tv> */
+	.phys_ram	= S3C2410_SDRAM_PA,
+	.phys_io	= S3C2410_PA_UART,
+	.io_pg_offst	= (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
+	.boot_params	= S3C2410_SDRAM_PA + 0x100,
 	.map_io		= otom11_map_io,
 	.init_irq	= s3c24xx_init_irq,
 	.timer		= &s3c24xx_timer,
diff --git a/arch/arm/mach-s3c2410/mach-rx3715.c b/arch/arm/mach-s3c2410/mach-rx3715.c
--- a/arch/arm/mach-s3c2410/mach-rx3715.c
+++ b/arch/arm/mach-s3c2410/mach-rx3715.c
@@ -131,11 +131,13 @@ static void __init rx3715_init_machine(v
 #endif
 
 MACHINE_START(RX3715, "IPAQ-RX3715")
-     MAINTAINER("Ben Dooks <ben@fluff.org>")
-     BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, (u32)S3C24XX_VA_UART)
-     BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100)
-     MAPIO(rx3715_map_io)
-     INITIRQ(rx3715_init_irq)
-     INIT_MACHINE(rx3715_init_machine)
+	/* Maintainer: Ben Dooks <ben@fluff.org> */
+	.phys_ram	= S3C2410_SDRAM_PA,
+	.phys_io	= S3C2410_PA_UART,
+	.io_pg_offst	= (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
+	.boot_params	= S3C2410_SDRAM_PA + 0x100,
+	.map_io		= rx3715_map_io,
+	.init_irq	= rx3715_init_irq,
+	.init_machine	= rx3715_init_machine,
 	.timer		= &s3c24xx_timer,
 MACHINE_END
diff --git a/arch/arm/mach-s3c2410/mach-smdk2410.c b/arch/arm/mach-s3c2410/mach-smdk2410.c
--- a/arch/arm/mach-s3c2410/mach-smdk2410.c
+++ b/arch/arm/mach-s3c2410/mach-smdk2410.c
@@ -112,11 +112,13 @@ void __init smdk2410_init_irq(void)
 
 MACHINE_START(SMDK2410, "SMDK2410") /* @TODO: request a new identifier and switch
 				    * to SMDK2410 */
-     MAINTAINER("Jonas Dietsche")
-     BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, (u32)S3C24XX_VA_UART)
-     BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100)
-     MAPIO(smdk2410_map_io)
-     INITIRQ(smdk2410_init_irq)
+	/* Maintainer: Jonas Dietsche */
+	.phys_ram	= S3C2410_SDRAM_PA,
+	.phys_io	= S3C2410_PA_UART,
+	.io_pg_offst	= (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
+	.boot_params	= S3C2410_SDRAM_PA + 0x100,
+	.map_io		= smdk2410_map_io,
+	.init_irq	= smdk2410_init_irq,
 	.timer		= &s3c24xx_timer,
 MACHINE_END
 
diff --git a/arch/arm/mach-s3c2410/mach-smdk2440.c b/arch/arm/mach-s3c2410/mach-smdk2440.c
--- a/arch/arm/mach-s3c2410/mach-smdk2440.c
+++ b/arch/arm/mach-s3c2410/mach-smdk2440.c
@@ -124,9 +124,11 @@ void __init smdk2440_machine_init(void)
 }
 
 MACHINE_START(S3C2440, "SMDK2440")
-	MAINTAINER("Ben Dooks <ben@fluff.org>")
-	BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, (u32)S3C24XX_VA_UART)
-	BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100)
+	/* Maintainer: Ben Dooks <ben@fluff.org> */
+	.phys_ram	= S3C2410_SDRAM_PA,
+	.phys_io	= S3C2410_PA_UART,
+	.io_pg_offst	= (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
+	.boot_params	= S3C2410_SDRAM_PA + 0x100,
 
 	.init_irq	= s3c24xx_init_irq,
 	.map_io		= smdk2440_map_io,
diff --git a/arch/arm/mach-s3c2410/mach-vr1000.c b/arch/arm/mach-s3c2410/mach-vr1000.c
--- a/arch/arm/mach-s3c2410/mach-vr1000.c
+++ b/arch/arm/mach-s3c2410/mach-vr1000.c
@@ -27,6 +27,7 @@
  *     10-Feb-2005 BJD  Added power-off capability
  *     10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA
  *     14-Mar-2006 BJD  void __iomem fixes
+ *     22-Jun-2006 BJD  Added DM9000 platform information
 */
 
 #include <linux/kernel.h>
@@ -35,6 +36,7 @@
 #include <linux/list.h>
 #include <linux/timer.h>
 #include <linux/init.h>
+#include <linux/dm9000.h>
 
 #include <linux/serial.h>
 #include <linux/tty.h>
@@ -98,28 +100,24 @@ static struct map_desc vr1000_iodesc[] _
    * are only 8bit */
 
   /* slow, byte */
-  { VA_C2(VR1000_VA_DM9000),  PA_CS2(VR1000_PA_DM9000),	  SZ_1M,  MT_DEVICE },
   { VA_C2(VR1000_VA_IDEPRI),  PA_CS3(VR1000_PA_IDEPRI),	  SZ_1M,  MT_DEVICE },
   { VA_C2(VR1000_VA_IDESEC),  PA_CS3(VR1000_PA_IDESEC),	  SZ_1M,  MT_DEVICE },
   { VA_C2(VR1000_VA_IDEPRIAUX), PA_CS3(VR1000_PA_IDEPRIAUX), SZ_1M, MT_DEVICE },
   { VA_C2(VR1000_VA_IDESECAUX), PA_CS3(VR1000_PA_IDESECAUX), SZ_1M, MT_DEVICE },
 
   /* slow, word */
-  { VA_C3(VR1000_VA_DM9000),  PA_CS3(VR1000_PA_DM9000),	  SZ_1M,  MT_DEVICE },
   { VA_C3(VR1000_VA_IDEPRI),  PA_CS3(VR1000_PA_IDEPRI),	  SZ_1M,  MT_DEVICE },
   { VA_C3(VR1000_VA_IDESEC),  PA_CS3(VR1000_PA_IDESEC),	  SZ_1M,  MT_DEVICE },
   { VA_C3(VR1000_VA_IDEPRIAUX), PA_CS3(VR1000_PA_IDEPRIAUX), SZ_1M, MT_DEVICE },
   { VA_C3(VR1000_VA_IDESECAUX), PA_CS3(VR1000_PA_IDESECAUX), SZ_1M, MT_DEVICE },
 
   /* fast, byte */
-  { VA_C4(VR1000_VA_DM9000),  PA_CS4(VR1000_PA_DM9000),	  SZ_1M,  MT_DEVICE },
   { VA_C4(VR1000_VA_IDEPRI),  PA_CS5(VR1000_PA_IDEPRI),	  SZ_1M,  MT_DEVICE },
   { VA_C4(VR1000_VA_IDESEC),  PA_CS5(VR1000_PA_IDESEC),	  SZ_1M,  MT_DEVICE },
   { VA_C4(VR1000_VA_IDEPRIAUX), PA_CS5(VR1000_PA_IDEPRIAUX), SZ_1M, MT_DEVICE },
   { VA_C4(VR1000_VA_IDESECAUX), PA_CS5(VR1000_PA_IDESECAUX), SZ_1M, MT_DEVICE },
 
   /* fast, word */
-  { VA_C5(VR1000_VA_DM9000),  PA_CS5(VR1000_PA_DM9000),	  SZ_1M,  MT_DEVICE },
   { VA_C5(VR1000_VA_IDEPRI),  PA_CS5(VR1000_PA_IDEPRI),	  SZ_1M,  MT_DEVICE },
   { VA_C5(VR1000_VA_IDESEC),  PA_CS5(VR1000_PA_IDESEC),	  SZ_1M,  MT_DEVICE },
   { VA_C5(VR1000_VA_IDEPRIAUX), PA_CS5(VR1000_PA_IDEPRIAUX), SZ_1M, MT_DEVICE },
@@ -246,6 +244,74 @@ static struct platform_device vr1000_nor
 	.resource	= vr1000_nor_resource,
 };
 
+/* DM9000 ethernet devices */
+
+static struct resource vr1000_dm9k0_resource[] = {
+	[0] = {
+		.start = S3C2410_CS5 + VR1000_PA_DM9000,
+		.end   = S3C2410_CS5 + VR1000_PA_DM9000 + 3,
+		.flags = IORESOURCE_MEM
+	},
+	[1] = {
+		.start = S3C2410_CS5 + VR1000_PA_DM9000 + 0x40,
+		.end   = S3C2410_CS5 + VR1000_PA_DM9000 + 0x7f,
+		.flags = IORESOURCE_MEM
+	},
+	[2] = {
+		.start = IRQ_VR1000_DM9000A,
+		.end   = IRQ_VR1000_DM9000A,
+		.flags = IORESOURCE_IRQ
+	}
+
+};
+
+static struct resource vr1000_dm9k1_resource[] = {
+	[0] = {
+		.start = S3C2410_CS5 + VR1000_PA_DM9000 + 0x80,
+		.end   = S3C2410_CS5 + VR1000_PA_DM9000 + 0x83,
+		.flags = IORESOURCE_MEM
+	},
+	[1] = {
+		.start = S3C2410_CS5 + VR1000_PA_DM9000 + 0xC0,
+		.end   = S3C2410_CS5 + VR1000_PA_DM9000 + 0xFF,
+		.flags = IORESOURCE_MEM
+	},
+	[2] = {
+		.start = IRQ_VR1000_DM9000N,
+		.end   = IRQ_VR1000_DM9000N,
+		.flags = IORESOURCE_IRQ
+	}
+};
+
+/* for the moment we limit ourselves to 16bit IO until some
+ * better IO routines can be written and tested
+*/
+
+struct dm9000_plat_data vr1000_dm9k_platdata = {
+	.flags		= DM9000_PLATF_16BITONLY,
+};
+
+static struct platform_device vr1000_dm9k0 = {
+	.name		= "dm9000",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(vr1000_dm9k0_resource),
+	.resource	= vr1000_dm9k0_resource,
+	.dev		= {
+		.platform_data = &vr1000_dm9k_platdata,
+	}
+};
+
+static struct platform_device vr1000_dm9k1 = {
+	.name		= "dm9000",
+	.id		= 1,
+	.num_resources	= ARRAY_SIZE(vr1000_dm9k1_resource),
+	.resource	= vr1000_dm9k1_resource,
+	.dev		= {
+		.platform_data = &vr1000_dm9k_platdata,
+	}
+};
+
+/* devices for this board */
 
 static struct platform_device *vr1000_devices[] __initdata = {
 	&s3c_device_usb,
@@ -253,8 +319,11 @@ static struct platform_device *vr1000_de
 	&s3c_device_wdt,
 	&s3c_device_i2c,
 	&s3c_device_iis,
+	&s3c_device_adc,
 	&serial_device,
 	&vr1000_nor,
+	&vr1000_dm9k0,
+	&vr1000_dm9k1
 };
 
 static struct clk *vr1000_clocks[] = {
@@ -302,16 +371,14 @@ void __init vr1000_map_io(void)
 	usb_simtec_init();
 }
 
-void __init vr1000_init_irq(void)
-{
-	s3c24xx_init_irq();
-}
 
 MACHINE_START(VR1000, "Thorcom-VR1000")
-     MAINTAINER("Ben Dooks <ben@simtec.co.uk>")
-     BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, (u32)S3C24XX_VA_UART)
-     BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100)
-     MAPIO(vr1000_map_io)
-     INITIRQ(vr1000_init_irq)
+	/* Maintainer: Ben Dooks <ben@simtec.co.uk> */
+	.phys_ram	= S3C2410_SDRAM_PA,
+	.phys_io	= S3C2410_PA_UART,
+	.io_pg_offst	= (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
+	.boot_params	= S3C2410_SDRAM_PA + 0x100,
+	.map_io		= vr1000_map_io,
+	.init_irq	= s3c24xx_init_irq,
 	.timer		= &s3c24xx_timer,
 MACHINE_END
diff --git a/arch/arm/mach-s3c2410/pm-simtec.c b/arch/arm/mach-s3c2410/pm-simtec.c
new file mode 100644
--- /dev/null
+++ b/arch/arm/mach-s3c2410/pm-simtec.c
@@ -0,0 +1,65 @@
+/* linux/arch/arm/mach-s3c2410/pm-simtec.c
+ *
+ * Copyright (c) 2004 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * http://armlinux.simtec.co.uk/
+ *
+ * Power Management helpers for Simtec S3C24XX implementations
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/device.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+
+#include <asm/arch/map.h>
+#include <asm/arch/regs-serial.h>
+#include <asm/arch/regs-gpio.h>
+#include <asm/arch/regs-mem.h>
+
+#include <asm/mach-types.h>
+
+#include "pm.h"
+
+#define COPYRIGHT ", (c) 2005 Simtec Electronics"
+
+/* pm_simtec_init
+ *
+ * enable the power management functions
+*/
+
+static __init int pm_simtec_init(void)
+{
+	unsigned long gstatus4;
+
+	/* check which machine we are running on */
+
+	if (!machine_is_bast() && !machine_is_vr1000())
+		return 0;
+
+	printk(KERN_INFO "Simtec Board Power Manangement" COPYRIGHT "\n");
+
+	gstatus4  = (__raw_readl(S3C2410_BANKCON7) & 0x3) << 30;
+	gstatus4 |= (__raw_readl(S3C2410_BANKCON6) & 0x3) << 28;
+	gstatus4 |= (__raw_readl(S3C2410_BANKSIZE) & S3C2410_BANKSIZE_MASK);
+
+	__raw_writel(gstatus4, S3C2410_GSTATUS4);
+
+	return s3c2410_pm_init();
+}
+
+arch_initcall(pm_simtec_init);
diff --git a/arch/arm/mach-s3c2410/s3c2410.c b/arch/arm/mach-s3c2410/s3c2410.c
--- a/arch/arm/mach-s3c2410/s3c2410.c
+++ b/arch/arm/mach-s3c2410/s3c2410.c
@@ -18,6 +18,7 @@
  *     28-Sep-2004 BJD  Updates for new serial port bits
  *     04-Nov-2004 BJD  Updated UART configuration process
  *     10-Jan-2005 BJD  Removed s3c2410_clock_tick_rate
+ *     13-Aug-2005 DA   Removed UART from initial I/O mappings
 */
 
 #include <linux/kernel.h>
@@ -49,10 +50,9 @@ static struct map_desc s3c2410_iodesc[] 
 	IODESC_ENT(USBHOST),
 	IODESC_ENT(CLKPWR),
 	IODESC_ENT(LCD),
-	IODESC_ENT(UART),
 	IODESC_ENT(TIMER),
 	IODESC_ENT(ADC),
-	IODESC_ENT(WATCHDOG)
+	IODESC_ENT(WATCHDOG),
 };
 
 static struct resource s3c_uart0_resource[] = {
diff --git a/arch/arm/mach-s3c2410/s3c2440-clock.c b/arch/arm/mach-s3c2410/s3c2440-clock.c
new file mode 100644
--- /dev/null
+++ b/arch/arm/mach-s3c2410/s3c2440-clock.c
@@ -0,0 +1,116 @@
+/* linux/arch/arm/mach-s3c2410/s3c2440-clock.c
+ *
+ * Copyright (c) 2004-2005 Simtec Electronics
+ *	http://armlinux.simtec.co.uk/
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2440 Clock support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/device.h>
+#include <linux/sysdev.h>
+
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+
+#include <asm/hardware.h>
+#include <asm/atomic.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+
+#include <asm/hardware/clock.h>
+#include <asm/arch/regs-clock.h>
+
+#include "clock.h"
+#include "cpu.h"
+
+/* S3C2440 extended clock support */
+
+static struct clk s3c2440_clk_upll = {
+	.name		= "upll",
+	.id		= -1,
+};
+
+static struct clk s3c2440_clk_cam = {
+	.name		= "camif",
+	.id		= -1,
+	.enable		= s3c24xx_clkcon_enable,
+	.ctrlbit	= S3C2440_CLKCON_CAMERA,
+};
+
+static struct clk s3c2440_clk_ac97 = {
+	.name		= "ac97",
+	.id		= -1,
+	.enable		= s3c24xx_clkcon_enable,
+	.ctrlbit	= S3C2440_CLKCON_CAMERA,
+};
+
+static int s3c2440_clk_add(struct sys_device *sysdev)
+{
+	unsigned long upllcon = __raw_readl(S3C2410_UPLLCON);
+	struct clk *clk_h;
+	struct clk *clk_p;
+	struct clk *clk_xtal;
+
+	clk_xtal = clk_get(NULL, "xtal");
+	if (IS_ERR(clk_xtal)) {
+		printk(KERN_ERR "S3C2440: Failed to get clk_xtal\n");
+		return -EINVAL;
+	}
+
+	s3c2440_clk_upll.rate = s3c2410_get_pll(upllcon, clk_xtal->rate);
+
+	printk("S3C2440: Clock Support, UPLL %ld.%03ld MHz\n",
+	       print_mhz(s3c2440_clk_upll.rate));
+
+	clk_p = clk_get(NULL, "pclk");
+	clk_h = clk_get(NULL, "hclk");
+
+	if (IS_ERR(clk_p) || IS_ERR(clk_h)) {
+		printk(KERN_ERR "S3C2440: Failed to get parent clocks\n");
+		return -EINVAL;
+	}
+
+	s3c2440_clk_cam.parent = clk_h;
+	s3c2440_clk_ac97.parent = clk_p;
+
+	s3c24xx_register_clock(&s3c2440_clk_ac97);
+	s3c24xx_register_clock(&s3c2440_clk_cam);
+	s3c24xx_register_clock(&s3c2440_clk_upll);
+
+	clk_disable(&s3c2440_clk_ac97);
+	clk_disable(&s3c2440_clk_cam);
+
+	return 0;
+}
+
+static struct sysdev_driver s3c2440_clk_driver = {
+	.add	= s3c2440_clk_add,
+};
+
+static __init int s3c24xx_clk_driver(void)
+{
+	return sysdev_driver_register(&s3c2440_sysclass, &s3c2440_clk_driver);
+}
+
+arch_initcall(s3c24xx_clk_driver);
diff --git a/arch/arm/mach-s3c2410/s3c2440-irq.c b/arch/arm/mach-s3c2410/s3c2440-irq.c
new file mode 100644
--- /dev/null
+++ b/arch/arm/mach-s3c2410/s3c2440-irq.c
@@ -0,0 +1,207 @@
+/* linux/arch/arm/mach-s3c2410/s3c2440-irq.c
+ *
+ * Copyright (c) 2003,2004 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Changelog:
+ *	25-Jul-2005 BJD		Split from irq.c
+ *
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/ptrace.h>
+#include <linux/sysdev.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+
+#include <asm/mach/irq.h>
+
+#include <asm/arch/regs-irq.h>
+#include <asm/arch/regs-gpio.h>
+
+#include "cpu.h"
+#include "pm.h"
+#include "irq.h"
+
+/* WDT/AC97 */
+
+static void s3c_irq_demux_wdtac97(unsigned int irq,
+				  struct irqdesc *desc,
+				  struct pt_regs *regs)
+{
+	unsigned int subsrc, submsk;
+	struct irqdesc *mydesc;
+
+	/* read the current pending interrupts, and the mask
+	 * for what it is available */
+
+	subsrc = __raw_readl(S3C2410_SUBSRCPND);
+	submsk = __raw_readl(S3C2410_INTSUBMSK);
+
+	subsrc &= ~submsk;
+	subsrc >>= 13;
+	subsrc &= 3;
+
+	if (subsrc != 0) {
+		if (subsrc & 1) {
+			mydesc = irq_desc + IRQ_S3C2440_WDT;
+			mydesc->handle( IRQ_S3C2440_WDT, mydesc, regs);
+		}
+		if (subsrc & 2) {
+			mydesc = irq_desc + IRQ_S3C2440_AC97;
+			mydesc->handle(IRQ_S3C2440_AC97, mydesc, regs);
+		}
+	}
+}
+
+
+#define INTMSK_WDT	 (1UL << (IRQ_WDT - IRQ_EINT0))
+
+static void
+s3c_irq_wdtac97_mask(unsigned int irqno)
+{
+	s3c_irqsub_mask(irqno, INTMSK_WDT, 3<<13);
+}
+
+static void
+s3c_irq_wdtac97_unmask(unsigned int irqno)
+{
+	s3c_irqsub_unmask(irqno, INTMSK_WDT);
+}
+
+static void
+s3c_irq_wdtac97_ack(unsigned int irqno)
+{
+	s3c_irqsub_maskack(irqno, INTMSK_WDT, 3<<13);
+}
+
+static struct irqchip s3c_irq_wdtac97 = {
+	.mask	    = s3c_irq_wdtac97_mask,
+	.unmask	    = s3c_irq_wdtac97_unmask,
+	.ack	    = s3c_irq_wdtac97_ack,
+};
+
+/* camera irq */
+
+static void s3c_irq_demux_cam(unsigned int irq,
+			      struct irqdesc *desc,
+			      struct pt_regs *regs)
+{
+	unsigned int subsrc, submsk;
+	struct irqdesc *mydesc;
+
+	/* read the current pending interrupts, and the mask
+	 * for what it is available */
+
+	subsrc = __raw_readl(S3C2410_SUBSRCPND);
+	submsk = __raw_readl(S3C2410_INTSUBMSK);
+
+	subsrc &= ~submsk;
+	subsrc >>= 11;
+	subsrc &= 3;
+
+	if (subsrc != 0) {
+		if (subsrc & 1) {
+			mydesc = irq_desc + IRQ_S3C2440_CAM_C;
+			mydesc->handle( IRQ_S3C2440_WDT, mydesc, regs);
+		}
+		if (subsrc & 2) {
+			mydesc = irq_desc + IRQ_S3C2440_CAM_P;
+			mydesc->handle(IRQ_S3C2440_AC97, mydesc, regs);
+		}
+	}
+}
+
+#define INTMSK_CAM (1UL << (IRQ_CAM - IRQ_EINT0))
+
+static void
+s3c_irq_cam_mask(unsigned int irqno)
+{
+	s3c_irqsub_mask(irqno, INTMSK_CAM, 3<<11);
+}
+
+static void
+s3c_irq_cam_unmask(unsigned int irqno)
+{
+	s3c_irqsub_unmask(irqno, INTMSK_CAM);
+}
+
+static void
+s3c_irq_cam_ack(unsigned int irqno)
+{
+	s3c_irqsub_maskack(irqno, INTMSK_CAM, 3<<11);
+}
+
+static struct irqchip s3c_irq_cam = {
+	.mask	    = s3c_irq_cam_mask,
+	.unmask	    = s3c_irq_cam_unmask,
+	.ack	    = s3c_irq_cam_ack,
+};
+
+static int s3c2440_irq_add(struct sys_device *sysdev)
+{
+	unsigned int irqno;
+
+	printk("S3C2440: IRQ Support\n");
+
+	set_irq_chip(IRQ_NFCON, &s3c_irq_level_chip);
+	set_irq_handler(IRQ_NFCON, do_level_IRQ);
+	set_irq_flags(IRQ_NFCON, IRQF_VALID);
+
+	/* add new chained handler for wdt, ac7 */
+
+	set_irq_chip(IRQ_WDT, &s3c_irq_level_chip);
+	set_irq_handler(IRQ_WDT, do_level_IRQ);
+	set_irq_chained_handler(IRQ_WDT, s3c_irq_demux_wdtac97);
+
+	for (irqno = IRQ_S3C2440_WDT; irqno <= IRQ_S3C2440_AC97; irqno++) {
+		set_irq_chip(irqno, &s3c_irq_wdtac97);
+		set_irq_handler(irqno, do_level_IRQ);
+		set_irq_flags(irqno, IRQF_VALID);
+	}
+
+	/* add chained handler for camera */
+
+	set_irq_chip(IRQ_CAM, &s3c_irq_level_chip);
+	set_irq_handler(IRQ_CAM, do_level_IRQ);
+	set_irq_chained_handler(IRQ_CAM, s3c_irq_demux_cam);
+
+	for (irqno = IRQ_S3C2440_CAM_C; irqno <= IRQ_S3C2440_CAM_P; irqno++) {
+		set_irq_chip(irqno, &s3c_irq_cam);
+		set_irq_handler(irqno, do_level_IRQ);
+		set_irq_flags(irqno, IRQF_VALID);
+	}
+
+	return 0;
+}
+
+static struct sysdev_driver s3c2440_irq_driver = {
+	.add	= s3c2440_irq_add,
+};
+
+static int s3c24xx_irq_driver(void)
+{
+	return sysdev_driver_register(&s3c2440_sysclass, &s3c2440_irq_driver);
+}
+
+arch_initcall(s3c24xx_irq_driver);
+
diff --git a/arch/arm/mach-s3c2410/time.c b/arch/arm/mach-s3c2410/time.c
--- a/arch/arm/mach-s3c2410/time.c
+++ b/arch/arm/mach-s3c2410/time.c
@@ -137,8 +137,8 @@ s3c2410_timer_interrupt(int irq, void *d
 
 static struct irqaction s3c2410_timer_irq = {
 	.name		= "S3C2410 Timer Tick",
-	.flags		= SA_INTERRUPT,
-	.handler	= s3c2410_timer_interrupt
+	.flags		= SA_INTERRUPT | SA_TIMER,
+	.handler	= s3c2410_timer_interrupt,
 };
 
 /*
diff --git a/arch/arm/mach-s3c2410/usb-simtec.c b/arch/arm/mach-s3c2410/usb-simtec.c
--- a/arch/arm/mach-s3c2410/usb-simtec.c
+++ b/arch/arm/mach-s3c2410/usb-simtec.c
@@ -1,6 +1,6 @@
 /* linux/arch/arm/mach-s3c2410/usb-simtec.c
  *
- * Copyright (c) 2004 Simtec Electronics
+ * Copyright (c) 2004,2005 Simtec Electronics
  *   Ben Dooks <ben@simtec.co.uk>
  *
  * http://www.simtec.co.uk/products/EB2410ITX/
@@ -14,6 +14,8 @@
  * Modifications:
  *	14-Sep-2004 BJD  Created
  *	18-Oct-2004 BJD  Cleanups, and added code to report OC cleared
+ *	09-Aug-2005 BJD  Renamed s3c2410_report_oc to s3c2410_usb_report_oc
+ *	09-Aug-2005 BJD  Ports powered only if both are enabled
 */
 
 #define DEBUG
@@ -47,13 +49,19 @@
  * designed boards.
 */
 
+static unsigned int power_state[2];
+
 static void
 usb_simtec_powercontrol(int port, int to)
 {
 	pr_debug("usb_simtec_powercontrol(%d,%d)\n", port, to);
 
-	if (port == 1)
-		s3c2410_gpio_setpin(S3C2410_GPB4, to ? 0:1);
+	power_state[port] = to;
+
+	if (power_state[0] && power_state[1])
+		s3c2410_gpio_setpin(S3C2410_GPB4, 0);
+	else
+		s3c2410_gpio_setpin(S3C2410_GPB4, 1);
 }
 
 static irqreturn_t
@@ -63,10 +71,10 @@ usb_simtec_ocirq(int irq, void *pw, stru
 
 	if (s3c2410_gpio_getpin(S3C2410_GPG10) == 0) {
 		pr_debug("usb_simtec: over-current irq (oc detected)\n");
-		s3c2410_report_oc(info, 3);
+		s3c2410_usb_report_oc(info, 3);
 	} else {
 		pr_debug("usb_simtec: over-current irq (oc cleared)\n");
-		s3c2410_report_oc(info, 0);
+		s3c2410_usb_report_oc(info, 0);
 	}
 
 	return IRQ_HANDLED;
diff --git a/arch/arm/mach-sa1100/assabet.c b/arch/arm/mach-sa1100/assabet.c
--- a/arch/arm/mach-sa1100/assabet.c
+++ b/arch/arm/mach-sa1100/assabet.c
@@ -431,11 +431,13 @@ static void __init assabet_map_io(void)
 
 
 MACHINE_START(ASSABET, "Intel-Assabet")
-	BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
-	BOOT_PARAMS(0xc0000100)
-	FIXUP(fixup_assabet)
-	MAPIO(assabet_map_io)
-	INITIRQ(sa1100_init_irq)
+	.phys_ram	= 0xc0000000,
+	.phys_io	= 0x80000000,
+	.io_pg_offst	= ((0xf8000000) >> 18) & 0xfffc,
+	.boot_params	= 0xc0000100,
+	.fixup		= fixup_assabet,
+	.map_io		= assabet_map_io,
+	.init_irq	= sa1100_init_irq,
 	.timer		= &sa1100_timer,
 	.init_machine	= assabet_init,
 MACHINE_END
diff --git a/arch/arm/mach-sa1100/badge4.c b/arch/arm/mach-sa1100/badge4.c
--- a/arch/arm/mach-sa1100/badge4.c
+++ b/arch/arm/mach-sa1100/badge4.c
@@ -285,9 +285,11 @@ static void __init badge4_map_io(void)
 }
 
 MACHINE_START(BADGE4, "Hewlett-Packard Laboratories BadgePAD 4")
-	BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
-	BOOT_PARAMS(0xc0000100)
-	MAPIO(badge4_map_io)
-	INITIRQ(sa1100_init_irq)
+	.phys_ram	= 0xc0000000,
+	.phys_io	= 0x80000000,
+	.io_pg_offst	= ((0xf8000000) >> 18) & 0xfffc,
+	.boot_params	= 0xc0000100,
+	.map_io		= badge4_map_io,
+	.init_irq	= sa1100_init_irq,
 	.timer		= &sa1100_timer,
 MACHINE_END
diff --git a/arch/arm/mach-sa1100/cerf.c b/arch/arm/mach-sa1100/cerf.c
--- a/arch/arm/mach-sa1100/cerf.c
+++ b/arch/arm/mach-sa1100/cerf.c
@@ -123,10 +123,12 @@ static void __init cerf_init(void)
 }
 
 MACHINE_START(CERF, "Intrinsyc CerfBoard/CerfCube")
-	MAINTAINER("support@intrinsyc.com")
-	BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
-	MAPIO(cerf_map_io)
-	INITIRQ(cerf_init_irq)
+	/* Maintainer: support@intrinsyc.com */
+	.phys_ram	= 0xc0000000,
+	.phys_io	= 0x80000000,
+	.io_pg_offst	= ((0xf8000000) >> 18) & 0xfffc,
+	.map_io		= cerf_map_io,
+	.init_irq	= cerf_init_irq,
 	.timer		= &sa1100_timer,
 	.init_machine	= cerf_init,
 MACHINE_END
diff --git a/arch/arm/mach-sa1100/collie.c b/arch/arm/mach-sa1100/collie.c
--- a/arch/arm/mach-sa1100/collie.c
+++ b/arch/arm/mach-sa1100/collie.c
@@ -184,9 +184,11 @@ static void __init collie_map_io(void)
 }
 
 MACHINE_START(COLLIE, "Sharp-Collie")
-	BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
-	MAPIO(collie_map_io)
-	INITIRQ(sa1100_init_irq)
+	.phys_ram	= 0xc0000000,
+	.phys_io	= 0x80000000,
+	.io_pg_offst	= ((0xf8000000) >> 18) & 0xfffc,
+	.map_io		= collie_map_io,
+	.init_irq	= sa1100_init_irq,
 	.timer		= &sa1100_timer,
 	.init_machine	= collie_init,
 MACHINE_END
diff --git a/arch/arm/mach-sa1100/cpu-sa1110.c b/arch/arm/mach-sa1100/cpu-sa1110.c
--- a/arch/arm/mach-sa1100/cpu-sa1110.c
+++ b/arch/arm/mach-sa1100/cpu-sa1110.c
@@ -271,8 +271,7 @@ static int sa1110_target(struct cpufreq_
 	 */
 	sdram_set_refresh(2);
 	if (!irqs_disabled()) {
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(20 * HZ / 1000);
+		msleep(20);
 	} else {
 		mdelay(20);
 	}
diff --git a/arch/arm/mach-sa1100/h3600.c b/arch/arm/mach-sa1100/h3600.c
--- a/arch/arm/mach-sa1100/h3600.c
+++ b/arch/arm/mach-sa1100/h3600.c
@@ -380,10 +380,12 @@ static void __init h3100_map_io(void)
 }
 
 MACHINE_START(H3100, "Compaq iPAQ H3100")
-	BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
-	BOOT_PARAMS(0xc0000100)
-	MAPIO(h3100_map_io)
-	INITIRQ(sa1100_init_irq)
+	.phys_ram	= 0xc0000000,
+	.phys_io	= 0x80000000,
+	.io_pg_offst	= ((0xf8000000) >> 18) & 0xfffc,
+	.boot_params	= 0xc0000100,
+	.map_io		= h3100_map_io,
+	.init_irq	= sa1100_init_irq,
 	.timer		= &sa1100_timer,
 	.init_machine	= h3xxx_mach_init,
 MACHINE_END
@@ -496,10 +498,12 @@ static void __init h3600_map_io(void)
 }
 
 MACHINE_START(H3600, "Compaq iPAQ H3600")
-	BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
-	BOOT_PARAMS(0xc0000100)
-	MAPIO(h3600_map_io)
-	INITIRQ(sa1100_init_irq)
+	.phys_ram	= 0xc0000000,
+	.phys_io	= 0x80000000,
+	.io_pg_offst	= ((0xf8000000) >> 18) & 0xfffc,
+	.boot_params	= 0xc0000100,
+	.map_io		= h3600_map_io,
+	.init_irq	= sa1100_init_irq,
 	.timer		= &sa1100_timer,
 	.init_machine	= h3xxx_mach_init,
 MACHINE_END
@@ -727,7 +731,7 @@ static void h3800_IRQ_demux(unsigned int
 static struct irqaction h3800_irq = {
 	.name		= "h3800_asic",
 	.handler	= h3800_IRQ_demux,
-	.flags		= SA_INTERRUPT,
+	.flags		= SA_INTERRUPT | SA_TIMER,
 };
 
 u32 kpio_int_shadow = 0;
@@ -881,10 +885,12 @@ static void __init h3800_map_io(void)
 }
 
 MACHINE_START(H3800, "Compaq iPAQ H3800")
-	BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
-	BOOT_PARAMS(0xc0000100)
-	MAPIO(h3800_map_io)
-	INITIRQ(h3800_init_irq)
+	.phys_ram	= 0xc0000000,
+	.phys_io	= 0x80000000,
+	.io_pg_offst	= ((0xf8000000) >> 18) & 0xfffc,
+	.boot_params	= 0xc0000100,
+	.map_io		= h3800_map_io,
+	.init_irq	= h3800_init_irq,
 	.timer		= &sa1100_timer,
 	.init_machine	= h3xxx_mach_init,
 MACHINE_END
diff --git a/arch/arm/mach-sa1100/hackkit.c b/arch/arm/mach-sa1100/hackkit.c
--- a/arch/arm/mach-sa1100/hackkit.c
+++ b/arch/arm/mach-sa1100/hackkit.c
@@ -191,10 +191,12 @@ static void __init hackkit_init(void)
  */
 
 MACHINE_START(HACKKIT, "HackKit Cpu Board")
-	BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
-	BOOT_PARAMS(0xc0000100)
-	MAPIO(hackkit_map_io)
-	INITIRQ(sa1100_init_irq)
+	.phys_ram	= 0xc0000000,
+	.phys_io	= 0x80000000,
+	.io_pg_offst	= ((0xf8000000) >> 18) & 0xfffc,
+	.boot_params	= 0xc0000100,
+	.map_io		= hackkit_map_io,
+	.init_irq	= sa1100_init_irq,
 	.timer		= &sa1100_timer,
 	.init_machine	= hackkit_init,
 MACHINE_END
diff --git a/arch/arm/mach-sa1100/jornada720.c b/arch/arm/mach-sa1100/jornada720.c
--- a/arch/arm/mach-sa1100/jornada720.c
+++ b/arch/arm/mach-sa1100/jornada720.c
@@ -97,9 +97,12 @@ static void __init jornada720_map_io(voi
 }
 
 MACHINE_START(JORNADA720, "HP Jornada 720")
-	BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
-	BOOT_PARAMS(0xc0000100)
-	MAPIO(jornada720_map_io)
-	INITIRQ(sa1100_init_irq)
+	/* Maintainer: Michael Gernoth <michael@gernoth.net> */
+	.phys_ram	= 0xc0000000,
+	.phys_io	= 0x80000000,
+	.io_pg_offst	= ((0xf8000000) >> 18) & 0xfffc,
+	.boot_params	= 0xc0000100,
+	.map_io		= jornada720_map_io,
+	.init_irq	= sa1100_init_irq,
 	.timer		= &sa1100_timer,
 MACHINE_END
diff --git a/arch/arm/mach-sa1100/lart.c b/arch/arm/mach-sa1100/lart.c
--- a/arch/arm/mach-sa1100/lart.c
+++ b/arch/arm/mach-sa1100/lart.c
@@ -41,9 +41,11 @@ static void __init lart_map_io(void)
 }
 
 MACHINE_START(LART, "LART")
-	BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
-	BOOT_PARAMS(0xc0000100)
-	MAPIO(lart_map_io)
-	INITIRQ(sa1100_init_irq)
+	.phys_ram	= 0xc0000000,
+	.phys_io	= 0x80000000,
+	.io_pg_offst	= ((0xf8000000) >> 18) & 0xfffc,
+	.boot_params	= 0xc0000100,
+	.map_io		= lart_map_io,
+	.init_irq	= sa1100_init_irq,
 	.timer		= &sa1100_timer,
 MACHINE_END
diff --git a/arch/arm/mach-sa1100/pleb.c b/arch/arm/mach-sa1100/pleb.c
--- a/arch/arm/mach-sa1100/pleb.c
+++ b/arch/arm/mach-sa1100/pleb.c
@@ -146,9 +146,11 @@ static void __init pleb_map_io(void)
 }
 
 MACHINE_START(PLEB, "PLEB")
-	BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
-	MAPIO(pleb_map_io)
-	INITIRQ(sa1100_init_irq)
+	.phys_ram	= 0xc0000000,
+	.phys_io	= 0x80000000,
+	.io_pg_offst	= ((0xf8000000) >> 18) & 0xfffc,
+	.map_io		= pleb_map_io,
+	.init_irq	= sa1100_init_irq,
 	.timer		= &sa1100_timer,
 	.init_machine   = pleb_init,
 MACHINE_END
diff --git a/arch/arm/mach-sa1100/pm.c b/arch/arm/mach-sa1100/pm.c
--- a/arch/arm/mach-sa1100/pm.c
+++ b/arch/arm/mach-sa1100/pm.c
@@ -88,6 +88,8 @@ static int sa11x0_pm_enter(suspend_state
 	/* go zzz */
 	sa1100_cpu_suspend();
 
+	cpu_init();
+
 	/*
 	 * Ensure not to come back here if it wasn't intended
 	 */
diff --git a/arch/arm/mach-sa1100/shannon.c b/arch/arm/mach-sa1100/shannon.c
--- a/arch/arm/mach-sa1100/shannon.c
+++ b/arch/arm/mach-sa1100/shannon.c
@@ -76,10 +76,12 @@ static void __init shannon_map_io(void)
 }
 
 MACHINE_START(SHANNON, "Shannon (AKA: Tuxscreen)")
-	BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
-	BOOT_PARAMS(0xc0000100)
-	MAPIO(shannon_map_io)
-	INITIRQ(sa1100_init_irq)
+	.phys_ram	= 0xc0000000,
+	.phys_io	= 0x80000000,
+	.io_pg_offst	= ((0xf8000000) >> 18) & 0xfffc,
+	.boot_params	= 0xc0000100,
+	.map_io		= shannon_map_io,
+	.init_irq	= sa1100_init_irq,
 	.timer		= &sa1100_timer,
 	.init_machine	= shannon_init,
 MACHINE_END
diff --git a/arch/arm/mach-sa1100/simpad.c b/arch/arm/mach-sa1100/simpad.c
--- a/arch/arm/mach-sa1100/simpad.c
+++ b/arch/arm/mach-sa1100/simpad.c
@@ -215,10 +215,12 @@ arch_initcall(simpad_init);
 
 
 MACHINE_START(SIMPAD, "Simpad")
-	MAINTAINER("Holger Freyther")
-	BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
-        BOOT_PARAMS(0xc0000100)
-	MAPIO(simpad_map_io)
-	INITIRQ(sa1100_init_irq)
+	/* Maintainer: Holger Freyther */
+	.phys_ram	= 0xc0000000,
+	.phys_io	= 0x80000000,
+	.io_pg_offst	= ((0xf8000000) >> 18) & 0xfffc,
+	.boot_params	= 0xc0000100,
+	.map_io		= simpad_map_io,
+	.init_irq	= sa1100_init_irq,
 	.timer		= &sa1100_timer,
 MACHINE_END
diff --git a/arch/arm/mach-sa1100/time.c b/arch/arm/mach-sa1100/time.c
--- a/arch/arm/mach-sa1100/time.c
+++ b/arch/arm/mach-sa1100/time.c
@@ -99,8 +99,8 @@ sa1100_timer_interrupt(int irq, void *de
 
 static struct irqaction sa1100_timer_irq = {
 	.name		= "SA11xx Timer Tick",
-	.flags		= SA_INTERRUPT,
-	.handler	= sa1100_timer_interrupt
+	.flags		= SA_INTERRUPT | SA_TIMER,
+	.handler	= sa1100_timer_interrupt,
 };
 
 static void __init sa1100_timer_init(void)
diff --git a/arch/arm/mach-shark/core.c b/arch/arm/mach-shark/core.c
--- a/arch/arm/mach-shark/core.c
+++ b/arch/arm/mach-shark/core.c
@@ -24,7 +24,7 @@ static struct plat_serial8250_port seria
 		.iobase		= 0x3f8,
 		.irq		= 4,
 		.uartclk	= 1843200,
-		.regshift	= 2,
+		.regshift	= 0,
 		.iotype		= UPIO_PORT,
 		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
 	},
@@ -32,7 +32,7 @@ static struct plat_serial8250_port seria
 		.iobase		= 0x2f8,
 		.irq		= 3,
 		.uartclk	= 1843200,
-		.regshift	= 2,
+		.regshift	= 0,
 		.iotype		= UPIO_PORT,
 		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
 	},
@@ -84,8 +84,8 @@ shark_timer_interrupt(int irq, void *dev
 
 static struct irqaction shark_timer_irq = {
 	.name		= "Shark Timer Tick",
-	.flags		= SA_INTERRUPT,
-	.handler	= shark_timer_interrupt
+	.flags		= SA_INTERRUPT | SA_TIMER,
+	.handler	= shark_timer_interrupt,
 };
 
 /*
@@ -105,10 +105,12 @@ static struct sys_timer shark_timer = {
 };
 
 MACHINE_START(SHARK, "Shark")
-	MAINTAINER("Alexander Schulz")
-	BOOT_MEM(0x08000000, 0x40000000, 0xe0000000)
-	BOOT_PARAMS(0x08003000)
-	MAPIO(shark_map_io)
-	INITIRQ(shark_init_irq)
+	/* Maintainer: Alexander Schulz */
+	.phys_ram	= 0x08000000,
+	.phys_io	= 0x40000000,
+	.io_pg_offst	= ((0xe0000000) >> 18) & 0xfffc,
+	.boot_params	= 0x08003000,
+	.map_io		= shark_map_io,
+	.init_irq	= shark_init_irq,
 	.timer		= &shark_timer,
 MACHINE_END
diff --git a/arch/arm/mach-versatile/Makefile b/arch/arm/mach-versatile/Makefile
--- a/arch/arm/mach-versatile/Makefile
+++ b/arch/arm/mach-versatile/Makefile
@@ -5,3 +5,4 @@
 obj-y					:= core.o clock.o
 obj-$(CONFIG_ARCH_VERSATILE_PB)		+= versatile_pb.o
 obj-$(CONFIG_MACH_VERSATILE_AB)		+= versatile_ab.o
+obj-$(CONFIG_PCI)			+= pci.o
diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c
--- a/arch/arm/mach-versatile/core.c
+++ b/arch/arm/mach-versatile/core.c
@@ -33,6 +33,7 @@
 #include <asm/mach-types.h>
 #include <asm/hardware/amba.h>
 #include <asm/hardware/amba_clcd.h>
+#include <asm/hardware/arm_timer.h>
 #include <asm/hardware/icst307.h>
 
 #include <asm/mach/arch.h>
@@ -196,11 +197,15 @@ static struct map_desc versatile_io_desc
 #ifdef CONFIG_DEBUG_LL
  { IO_ADDRESS(VERSATILE_UART0_BASE), VERSATILE_UART0_BASE, SZ_4K,      MT_DEVICE },
 #endif
-#ifdef FIXME
- { PCI_MEMORY_VADDR,		     PHYS_PCI_MEM_BASE,    SZ_16M,     MT_DEVICE },
- { PCI_CONFIG_VADDR,		     PHYS_PCI_CONFIG_BASE, SZ_16M,     MT_DEVICE },
- { PCI_V3_VADDR,		     PHYS_PCI_V3_BASE,     SZ_512K,    MT_DEVICE },
- { PCI_IO_VADDR,		     PHYS_PCI_IO_BASE,     SZ_64K,     MT_DEVICE },
+#ifdef CONFIG_PCI
+ { IO_ADDRESS(VERSATILE_PCI_CORE_BASE), VERSATILE_PCI_CORE_BASE, SZ_4K, MT_DEVICE },
+ { VERSATILE_PCI_VIRT_BASE,          VERSATILE_PCI_BASE,   VERSATILE_PCI_BASE_SIZE, MT_DEVICE },
+ { VERSATILE_PCI_CFG_VIRT_BASE,      VERSATILE_PCI_CFG_BASE, VERSATILE_PCI_CFG_BASE_SIZE, MT_DEVICE },
+#if 0
+ { VERSATILE_PCI_VIRT_MEM_BASE0,     VERSATILE_PCI_MEM_BASE0, SZ_16M,  MT_DEVICE },
+ { VERSATILE_PCI_VIRT_MEM_BASE1,     VERSATILE_PCI_MEM_BASE1, SZ_16M,  MT_DEVICE },
+ { VERSATILE_PCI_VIRT_MEM_BASE2,     VERSATILE_PCI_MEM_BASE2, SZ_16M,  MT_DEVICE },
+#endif
 #endif
 };
 
@@ -784,38 +789,25 @@ void __init versatile_init(void)
  */
 #define TIMER_INTERVAL	(TICKS_PER_uSEC * mSEC_10)
 #if TIMER_INTERVAL >= 0x100000
-#define TIMER_RELOAD	(TIMER_INTERVAL >> 8)		/* Divide by 256 */
-#define TIMER_CTRL	0x88				/* Enable, Clock / 256 */
+#define TIMER_RELOAD	(TIMER_INTERVAL >> 8)
+#define TIMER_DIVISOR	(TIMER_CTRL_DIV256)
 #define TICKS2USECS(x)	(256 * (x) / TICKS_PER_uSEC)
 #elif TIMER_INTERVAL >= 0x10000
 #define TIMER_RELOAD	(TIMER_INTERVAL >> 4)		/* Divide by 16 */
-#define TIMER_CTRL	0x84				/* Enable, Clock / 16 */
+#define TIMER_DIVISOR	(TIMER_CTRL_DIV16)
 #define TICKS2USECS(x)	(16 * (x) / TICKS_PER_uSEC)
 #else
 #define TIMER_RELOAD	(TIMER_INTERVAL)
-#define TIMER_CTRL	0x80				/* Enable */
+#define TIMER_DIVISOR	(TIMER_CTRL_DIV1)
 #define TICKS2USECS(x)	((x) / TICKS_PER_uSEC)
 #endif
 
-#define TIMER_CTRL_IE	(1 << 5)	/* Interrupt Enable */
-
-/*
- * What does it look like?
- */
-typedef struct TimerStruct {
-	unsigned long TimerLoad;
-	unsigned long TimerValue;
-	unsigned long TimerControl;
-	unsigned long TimerClear;
-} TimerStruct_t;
-
 /*
  * Returns number of ms since last clock interrupt.  Note that interrupts
  * will have been disabled by do_gettimeoffset()
  */
 static unsigned long versatile_gettimeoffset(void)
 {
-	volatile TimerStruct_t *timer0 = (TimerStruct_t *)TIMER0_VA_BASE;
 	unsigned long ticks1, ticks2, status;
 
 	/*
@@ -824,11 +816,11 @@ static unsigned long versatile_gettimeof
 	 * an interrupt.  We get around this by ensuring that the
 	 * counter has not reloaded between our two reads.
 	 */
-	ticks2 = timer0->TimerValue & 0xffff;
+	ticks2 = readl(TIMER0_VA_BASE + TIMER_VALUE) & 0xffff;
 	do {
 		ticks1 = ticks2;
 		status = __raw_readl(VA_IC_BASE + VIC_IRQ_RAW_STATUS);
-		ticks2 = timer0->TimerValue & 0xffff;
+		ticks2 = readl(TIMER0_VA_BASE + TIMER_VALUE) & 0xffff;
 	} while (ticks2 > ticks1);
 
 	/*
@@ -855,12 +847,10 @@ static unsigned long versatile_gettimeof
  */
 static irqreturn_t versatile_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-	volatile TimerStruct_t *timer0 = (volatile TimerStruct_t *)TIMER0_VA_BASE;
-
 	write_seqlock(&xtime_lock);
 
 	// ...clear the interrupt
-	timer0->TimerClear = 1;
+	writel(1, TIMER0_VA_BASE + TIMER_INTCLR);
 
 	timer_tick(regs);
 
@@ -871,8 +861,8 @@ static irqreturn_t versatile_timer_inter
 
 static struct irqaction versatile_timer_irq = {
 	.name		= "Versatile Timer Tick",
-	.flags		= SA_INTERRUPT,
-	.handler	= versatile_timer_interrupt
+	.flags		= SA_INTERRUPT | SA_TIMER,
+	.handler	= versatile_timer_interrupt,
 };
 
 /*
@@ -880,31 +870,32 @@ static struct irqaction versatile_timer_
  */
 static void __init versatile_timer_init(void)
 {
-	volatile TimerStruct_t *timer0 = (volatile TimerStruct_t *)TIMER0_VA_BASE;
-	volatile TimerStruct_t *timer1 = (volatile TimerStruct_t *)TIMER1_VA_BASE;
-	volatile TimerStruct_t *timer2 = (volatile TimerStruct_t *)TIMER2_VA_BASE;
-	volatile TimerStruct_t *timer3 = (volatile TimerStruct_t *)TIMER3_VA_BASE;
+	u32 val;
 
 	/* 
 	 * set clock frequency: 
 	 *	VERSATILE_REFCLK is 32KHz
 	 *	VERSATILE_TIMCLK is 1MHz
 	 */
-	*(volatile unsigned int *)IO_ADDRESS(VERSATILE_SCTL_BASE) |= 
-	  ((VERSATILE_TIMCLK << VERSATILE_TIMER1_EnSel) | (VERSATILE_TIMCLK << VERSATILE_TIMER2_EnSel) | 
-	   (VERSATILE_TIMCLK << VERSATILE_TIMER3_EnSel) | (VERSATILE_TIMCLK << VERSATILE_TIMER4_EnSel));
+	val = readl(IO_ADDRESS(VERSATILE_SCTL_BASE));
+	writel((VERSATILE_TIMCLK << VERSATILE_TIMER1_EnSel) |
+	       (VERSATILE_TIMCLK << VERSATILE_TIMER2_EnSel) | 
+	       (VERSATILE_TIMCLK << VERSATILE_TIMER3_EnSel) |
+	       (VERSATILE_TIMCLK << VERSATILE_TIMER4_EnSel) | val,
+	       IO_ADDRESS(VERSATILE_SCTL_BASE));
 
 	/*
 	 * Initialise to a known state (all timers off)
 	 */
-	timer0->TimerControl = 0;
-	timer1->TimerControl = 0;
-	timer2->TimerControl = 0;
-	timer3->TimerControl = 0;
-
-	timer0->TimerLoad    = TIMER_RELOAD;
-	timer0->TimerValue   = TIMER_RELOAD;
-	timer0->TimerControl = TIMER_CTRL | 0x40 | TIMER_CTRL_IE;  /* periodic + IE */
+	writel(0, TIMER0_VA_BASE + TIMER_CTRL);
+	writel(0, TIMER1_VA_BASE + TIMER_CTRL);
+	writel(0, TIMER2_VA_BASE + TIMER_CTRL);
+	writel(0, TIMER3_VA_BASE + TIMER_CTRL);
+
+	writel(TIMER_RELOAD, TIMER0_VA_BASE + TIMER_LOAD);
+	writel(TIMER_RELOAD, TIMER0_VA_BASE + TIMER_VALUE);
+	writel(TIMER_DIVISOR | TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC |
+	       TIMER_CTRL_IE, TIMER0_VA_BASE + TIMER_CTRL);
 
 	/* 
 	 * Make irqs happen for the system timer
diff --git a/arch/arm/mach-versatile/pci.c b/arch/arm/mach-versatile/pci.c
new file mode 100644
--- /dev/null
+++ b/arch/arm/mach-versatile/pci.c
@@ -0,0 +1,360 @@
+/*
+ *  linux/arch/arm/mach-versatile/pci.c
+ *
+ * (C) Copyright Koninklijke Philips Electronics NV 2004. All rights reserved.
+ * You can redistribute and/or modify this software under the terms of version 2
+ * of the GNU General Public License as published by the Free Software Foundation.
+ * THIS SOFTWARE IS PROVIDED "AS IS" 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.
+ * Koninklijke Philips Electronics nor its subsidiaries is obligated to provide any support for this software.
+ *
+ * ARM Versatile PCI driver.
+ *
+ * 14/04/2005 Initial version, colin.king@philips.com
+ *
+ */
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/mach/pci.h>
+#include <asm/mach-types.h>
+
+/*
+ * these spaces are mapped using the following base registers:
+ *
+ * Usage Local Bus Memory         Base/Map registers used
+ *
+ * Mem   50000000 - 5FFFFFFF      LB_BASE0/LB_MAP0,  non prefetch
+ * Mem   60000000 - 6FFFFFFF      LB_BASE1/LB_MAP1,  prefetch
+ * IO    44000000 - 4FFFFFFF      LB_BASE2/LB_MAP2,  IO
+ * Cfg   42000000 - 42FFFFFF	  PCI config
+ *
+ */
+#define SYS_PCICTL			IO_ADDRESS(VERSATILE_SYS_PCICTL)
+#define PCI_IMAP0			IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x0)
+#define PCI_IMAP1			IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x4)
+#define PCI_IMAP2			IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x8)
+#define PCI_SMAP0			IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x10)
+#define PCI_SMAP1			IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x14)
+#define PCI_SMAP2			IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x18)
+#define PCI_SELFID			IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0xc)
+
+#define DEVICE_ID_OFFSET		0x00
+#define CSR_OFFSET			0x04
+#define CLASS_ID_OFFSET			0x08
+
+#define VP_PCI_DEVICE_ID		0x030010ee
+#define VP_PCI_CLASS_ID			0x0b400000
+
+static unsigned long pci_slot_ignore = 0;
+
+static int __init versatile_pci_slot_ignore(char *str)
+{
+	int retval;
+	int slot;
+
+	while ((retval = get_option(&str,&slot))) {
+		if ((slot < 0) || (slot > 31)) {
+			printk("Illegal slot value: %d\n",slot);
+		} else {
+			pci_slot_ignore |= (1 << slot);
+		}
+	}
+	return 1;
+}
+
+__setup("pci_slot_ignore=", versatile_pci_slot_ignore);
+
+
+static unsigned long __pci_addr(struct pci_bus *bus,
+				unsigned int devfn, int offset)
+{
+	unsigned int busnr = bus->number;
+
+	/*
+	 * Trap out illegal values
+	 */
+	if (offset > 255)
+		BUG();
+	if (busnr > 255)
+		BUG();
+	if (devfn > 255)
+		BUG();
+
+	return (VERSATILE_PCI_CFG_VIRT_BASE | (busnr << 16) |
+		(PCI_SLOT(devfn) << 11) | (PCI_FUNC(devfn) << 8) | offset);
+}
+
+static int versatile_read_config(struct pci_bus *bus, unsigned int devfn, int where,
+				 int size, u32 *val)
+{
+	unsigned long addr = __pci_addr(bus, devfn, where);
+	u32 v;
+	int slot = PCI_SLOT(devfn);
+
+	if (pci_slot_ignore & (1 << slot)) {
+		/* Ignore this slot */
+		switch (size) {
+		case 1:
+			v = 0xff;
+			break;
+		case 2:
+			v = 0xffff;
+			break;
+		default:
+			v = 0xffffffff;
+		}
+	} else {
+		switch (size) {
+		case 1:
+			addr &= ~3;
+			v = __raw_readb(addr);
+			break;
+
+		case 2:
+			v = __raw_readl(addr & ~3);
+			if (addr & 2) v >>= 16;
+ 			v &= 0xffff;
+			break;
+
+		default:
+			addr &= ~3;
+			v = __raw_readl(addr);
+			break;
+		}
+	}
+
+	*val = v;
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int versatile_write_config(struct pci_bus *bus, unsigned int devfn, int where,
+				  int size, u32 val)
+{
+	unsigned long addr = __pci_addr(bus, devfn, where);
+	int slot = PCI_SLOT(devfn);
+
+	if (pci_slot_ignore & (1 << slot)) {
+		return PCIBIOS_SUCCESSFUL;
+	}
+
+	switch (size) {
+	case 1:
+		__raw_writeb((u8)val, addr);
+		break;
+
+	case 2:
+		__raw_writew((u16)val, addr);
+		break;
+
+	case 4:
+		__raw_writel(val, addr);
+		break;
+	}
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops pci_versatile_ops = {
+	.read	= versatile_read_config,
+	.write	= versatile_write_config,
+};
+
+static struct resource io_mem = {
+	.name	= "PCI I/O space",
+	.start	= VERSATILE_PCI_MEM_BASE0,
+	.end	= VERSATILE_PCI_MEM_BASE0+VERSATILE_PCI_MEM_BASE0_SIZE-1,
+	.flags	= IORESOURCE_IO,
+};
+
+static struct resource non_mem = {
+	.name	= "PCI non-prefetchable",
+	.start	= VERSATILE_PCI_MEM_BASE1,
+	.end	= VERSATILE_PCI_MEM_BASE1+VERSATILE_PCI_MEM_BASE1_SIZE-1,
+	.flags	= IORESOURCE_MEM,
+};
+
+static struct resource pre_mem = {
+	.name	= "PCI prefetchable",
+	.start	= VERSATILE_PCI_MEM_BASE2,
+	.end	= VERSATILE_PCI_MEM_BASE2+VERSATILE_PCI_MEM_BASE2_SIZE-1,
+	.flags	= IORESOURCE_MEM | IORESOURCE_PREFETCH,
+};
+
+static int __init pci_versatile_setup_resources(struct resource **resource)
+{
+	int ret = 0;
+
+	ret = request_resource(&iomem_resource, &io_mem);
+	if (ret) {
+		printk(KERN_ERR "PCI: unable to allocate I/O "
+		       "memory region (%d)\n", ret);
+		goto out;
+	}
+	ret = request_resource(&iomem_resource, &non_mem);
+	if (ret) {
+		printk(KERN_ERR "PCI: unable to allocate non-prefetchable "
+		       "memory region (%d)\n", ret);
+		goto release_io_mem;
+	}
+	ret = request_resource(&iomem_resource, &pre_mem);
+	if (ret) {
+		printk(KERN_ERR "PCI: unable to allocate prefetchable "
+		       "memory region (%d)\n", ret);
+		goto release_non_mem;
+	}
+
+	/*
+	 * bus->resource[0] is the IO resource for this bus
+	 * bus->resource[1] is the mem resource for this bus
+	 * bus->resource[2] is the prefetch mem resource for this bus
+	 */
+	resource[0] = &io_mem;
+	resource[1] = &non_mem;
+	resource[2] = &pre_mem;
+
+	goto out;
+
+ release_non_mem:
+	release_resource(&non_mem);
+ release_io_mem:
+	release_resource(&io_mem);
+ out:
+	return ret;
+}
+
+int __init pci_versatile_setup(int nr, struct pci_sys_data *sys)
+{
+	int ret = 0;
+        int i;
+        int myslot = -1;
+	unsigned long val;
+
+	if (nr == 0) {
+		sys->mem_offset = 0;
+		ret = pci_versatile_setup_resources(sys->resource);
+		if (ret < 0) {
+			printk("pci_versatile_setup: resources... oops?\n");
+			goto out;
+		}
+	} else {
+		printk("pci_versatile_setup: resources... nr == 0??\n");
+		goto out;
+	}
+
+	__raw_writel(VERSATILE_PCI_MEM_BASE0 >> 28,PCI_IMAP0);
+	__raw_writel(VERSATILE_PCI_MEM_BASE1 >> 28,PCI_IMAP1);
+	__raw_writel(VERSATILE_PCI_MEM_BASE2 >> 28,PCI_IMAP2);
+
+	__raw_writel(1, SYS_PCICTL);
+
+	val = __raw_readl(SYS_PCICTL);
+	if (!(val & 1)) {
+		printk("Not plugged into PCI backplane!\n");
+		ret = -EIO;
+		goto out;
+	}
+
+	/*
+	 *  We need to discover the PCI core first to configure itself
+	 *  before the main PCI probing is performed
+	 */
+	for (i=0; i<32; i++) {
+		if ((__raw_readl(VERSATILE_PCI_VIRT_BASE+(i<<11)+DEVICE_ID_OFFSET) == VP_PCI_DEVICE_ID) &&
+		    (__raw_readl(VERSATILE_PCI_VIRT_BASE+(i<<11)+CLASS_ID_OFFSET) == VP_PCI_CLASS_ID)) {
+			myslot = i;
+
+			__raw_writel(myslot, PCI_SELFID);
+			val = __raw_readl(VERSATILE_PCI_CFG_VIRT_BASE+(myslot<<11)+CSR_OFFSET);
+			val |= (1<<2);
+			__raw_writel(val, VERSATILE_PCI_CFG_VIRT_BASE+(myslot<<11)+CSR_OFFSET);
+			break;
+		}
+	}
+
+	if (myslot == -1) {
+		printk("Cannot find PCI core!\n");
+		ret = -EIO;
+	} else {
+		printk("PCI core found (slot %d)\n",myslot);
+		/* Do not to map Versatile FPGA PCI device
+		   into memory space as we are short of
+		   mappable memory */
+		pci_slot_ignore |= (1 << myslot);
+		ret = 1;
+	}
+
+ out:
+	return ret;
+}
+
+
+struct pci_bus *pci_versatile_scan_bus(int nr, struct pci_sys_data *sys)
+{
+	return pci_scan_bus(sys->busnr, &pci_versatile_ops, sys);
+}
+
+/*
+ * V3_LB_BASE? - local bus address
+ * V3_LB_MAP?  - pci bus address
+ */
+void __init pci_versatile_preinit(void)
+{
+}
+
+void __init pci_versatile_postinit(void)
+{
+}
+
+
+/*
+ * map the specified device/slot/pin to an IRQ.   Different backplanes may need to modify this.
+ */
+static int __init versatile_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	int irq;
+	int devslot = PCI_SLOT(dev->devfn);
+
+	/* slot,  pin,  irq
+	    24	  1	27
+	    25    1	28	untested
+	    26	  1	29
+	    27    1	30	untested
+	*/
+
+	irq = 27 + ((slot + pin + 2) % 3);	/* Fudged */
+
+	printk("map irq: slot %d, pin %d, devslot %d, irq: %d\n",slot,pin,devslot,irq);
+
+	return irq;
+}
+
+static struct hw_pci versatile_pci __initdata = {
+	.swizzle		= NULL,
+	.map_irq		= versatile_map_irq,
+	.nr_controllers		= 1,
+	.setup			= pci_versatile_setup,
+	.scan			= pci_versatile_scan_bus,
+	.preinit		= pci_versatile_preinit,
+	.postinit		= pci_versatile_postinit,
+};
+
+static int __init versatile_pci_init(void)
+{
+	pci_common_init(&versatile_pci);
+	return 0;
+}
+
+subsys_initcall(versatile_pci_init);
diff --git a/arch/arm/mach-versatile/versatile_ab.c b/arch/arm/mach-versatile/versatile_ab.c
--- a/arch/arm/mach-versatile/versatile_ab.c
+++ b/arch/arm/mach-versatile/versatile_ab.c
@@ -35,11 +35,13 @@
 #include "core.h"
 
 MACHINE_START(VERSATILE_AB, "ARM-Versatile AB")
-	MAINTAINER("ARM Ltd/Deep Blue Solutions Ltd")
-	BOOT_MEM(0x00000000, 0x101f1000, 0xf11f1000)
-	BOOT_PARAMS(0x00000100)
-	MAPIO(versatile_map_io)
-	INITIRQ(versatile_init_irq)
+	/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
+	.phys_ram	= 0x00000000,
+	.phys_io	= 0x101f1000,
+	.io_pg_offst	= ((0xf11f1000) >> 18) & 0xfffc,
+	.boot_params	= 0x00000100,
+	.map_io		= versatile_map_io,
+	.init_irq	= versatile_init_irq,
 	.timer		= &versatile_timer,
-	INIT_MACHINE(versatile_init)
+	.init_machine	= versatile_init,
 MACHINE_END
diff --git a/arch/arm/mach-versatile/versatile_pb.c b/arch/arm/mach-versatile/versatile_pb.c
--- a/arch/arm/mach-versatile/versatile_pb.c
+++ b/arch/arm/mach-versatile/versatile_pb.c
@@ -99,11 +99,13 @@ static int __init versatile_pb_init(void
 arch_initcall(versatile_pb_init);
 
 MACHINE_START(VERSATILE_PB, "ARM-Versatile PB")
-	MAINTAINER("ARM Ltd/Deep Blue Solutions Ltd")
-	BOOT_MEM(0x00000000, 0x101f1000, 0xf11f1000)
-	BOOT_PARAMS(0x00000100)
-	MAPIO(versatile_map_io)
-	INITIRQ(versatile_init_irq)
+	/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
+	.phys_ram	= 0x00000000,
+	.phys_io	= 0x101f1000,
+	.io_pg_offst	= ((0xf11f1000) >> 18) & 0xfffc,
+	.boot_params	= 0x00000100,
+	.map_io		= versatile_map_io,
+	.init_irq	= versatile_init_irq,
 	.timer		= &versatile_timer,
-	INIT_MACHINE(versatile_init)
+	.init_machine	= versatile_init,
 MACHINE_END
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -62,7 +62,7 @@ config CPU_ARM720T
 # ARM920T
 config CPU_ARM920T
 	bool "Support ARM920T processor" if !ARCH_S3C2410
-	depends on ARCH_INTEGRATOR || ARCH_S3C2410 || ARCH_IMX
+	depends on ARCH_INTEGRATOR || ARCH_S3C2410 || ARCH_IMX || ARCH_AAEC2000
 	default y if ARCH_S3C2410
 	select CPU_32v4
 	select CPU_ABRT_EV4T
@@ -101,7 +101,7 @@ config CPU_ARM922T
 
 # ARM925T
 config CPU_ARM925T
- 	bool "Support ARM925T processor" if ARCH_OMAP
+ 	bool "Support ARM925T processor" if ARCH_OMAP1
  	depends on ARCH_OMAP1510
  	default y if ARCH_OMAP1510
 	select CPU_32v4
@@ -384,7 +384,7 @@ config CPU_DCACHE_DISABLE
 
 config CPU_DCACHE_WRITETHROUGH
 	bool "Force write through D-cache"
-	depends on (CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM1020) && !CPU_DISABLE_DCACHE
+	depends on (CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM1020) && !CPU_DCACHE_DISABLE
 	default y if CPU_ARM925T
 	help
 	  Say Y here to use the data cache in writethrough mode. Unless you
diff --git a/arch/arm/mm/blockops.c b/arch/arm/mm/blockops.c
--- a/arch/arm/mm/blockops.c
+++ b/arch/arm/mm/blockops.c
@@ -25,13 +25,14 @@ blk_flush_kern_dcache_page(void *kaddr)
 {
 	asm(
 	"add	r1, r0, %0							\n\
+	sub	r1, r1, %1							\n\
 1:	.word	0xec401f0e	@ mcrr	p15, 0, r0, r1, c14, 0	@ blocking	\n\
 	mov	r0, #0								\n\
 	mcr	p15, 0, r0, c7, c5, 0						\n\
 	mcr	p15, 0, r0, c7, c10, 4						\n\
 	mov	pc, lr"
 	:
-	: "I" (PAGE_SIZE));
+	: "I" (PAGE_SIZE), "I" (L1_CACHE_BYTES));
 }
 
 /*
diff --git a/arch/arm/mm/copypage-v6.c b/arch/arm/mm/copypage-v6.c
--- a/arch/arm/mm/copypage-v6.c
+++ b/arch/arm/mm/copypage-v6.c
@@ -30,8 +30,6 @@
 
 static DEFINE_SPINLOCK(v6_lock);
 
-#define DCACHE_COLOUR(vaddr) ((vaddr & (SHMLBA - 1)) >> PAGE_SHIFT)
-
 /*
  * Copy the user page.  No aliasing to deal with so we can just
  * attack the kernel's existing mapping of these pages.
@@ -55,7 +53,7 @@ void v6_clear_user_page_nonaliasing(void
  */
 void v6_copy_user_page_aliasing(void *kto, const void *kfrom, unsigned long vaddr)
 {
-	unsigned int offset = DCACHE_COLOUR(vaddr);
+	unsigned int offset = CACHE_COLOUR(vaddr);
 	unsigned long from, to;
 
 	/*
@@ -95,7 +93,7 @@ void v6_copy_user_page_aliasing(void *kt
  */
 void v6_clear_user_page_aliasing(void *kaddr, unsigned long vaddr)
 {
-	unsigned int offset = DCACHE_COLOUR(vaddr);
+	unsigned int offset = CACHE_COLOUR(vaddr);
 	unsigned long to = to_address + (offset << PAGE_SHIFT);
 
 	/*
diff --git a/arch/arm/mm/fault-armv.c b/arch/arm/mm/fault-armv.c
--- a/arch/arm/mm/fault-armv.c
+++ b/arch/arm/mm/fault-armv.c
@@ -77,9 +77,8 @@ no_pmd:
 }
 
 static void
-make_coherent(struct vm_area_struct *vma, unsigned long addr, struct page *page, int dirty)
+make_coherent(struct address_space *mapping, struct vm_area_struct *vma, unsigned long addr, unsigned long pfn)
 {
-	struct address_space *mapping = page_mapping(page);
 	struct mm_struct *mm = vma->vm_mm;
 	struct vm_area_struct *mpnt;
 	struct prio_tree_iter iter;
@@ -87,9 +86,6 @@ make_coherent(struct vm_area_struct *vma
 	pgoff_t pgoff;
 	int aliases = 0;
 
-	if (!mapping)
-		return;
-
 	pgoff = vma->vm_pgoff + ((addr - vma->vm_start) >> PAGE_SHIFT);
 
 	/*
@@ -115,9 +111,11 @@ make_coherent(struct vm_area_struct *vma
 	if (aliases)
 		adjust_pte(vma, addr);
 	else
-		flush_cache_page(vma, addr, page_to_pfn(page));
+		flush_cache_page(vma, addr, pfn);
 }
 
+void __flush_dcache_page(struct address_space *mapping, struct page *page);
+
 /*
  * Take care of architecture specific things when placing a new PTE into
  * a page table, or changing an existing PTE.  Basically, there are two
@@ -134,29 +132,22 @@ make_coherent(struct vm_area_struct *vma
 void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr, pte_t pte)
 {
 	unsigned long pfn = pte_pfn(pte);
+	struct address_space *mapping;
 	struct page *page;
 
 	if (!pfn_valid(pfn))
 		return;
+
 	page = pfn_to_page(pfn);
-	if (page_mapping(page)) {
+	mapping = page_mapping(page);
+	if (mapping) {
 		int dirty = test_and_clear_bit(PG_dcache_dirty, &page->flags);
 
-		if (dirty) {
-			/*
-			 * This is our first userspace mapping of this page.
-			 * Ensure that the physical page is coherent with
-			 * the kernel mapping.
-			 *
-			 * FIXME: only need to do this on VIVT and aliasing
-			 *        VIPT cache architectures.  We can do that
-			 *	  by choosing whether to set this bit...
-			 */
-			__cpuc_flush_dcache_page(page_address(page));
-		}
+		if (dirty)
+			__flush_dcache_page(mapping, page);
 
 		if (cache_is_vivt())
-			make_coherent(vma, addr, page, dirty);
+			make_coherent(mapping, vma, addr, pfn);
 	}
 }
 
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
--- a/arch/arm/mm/fault.c
+++ b/arch/arm/mm/fault.c
@@ -238,9 +238,9 @@ do_page_fault(unsigned long addr, unsign
 	up_read(&mm->mmap_sem);
 
 	/*
-	 * Handle the "normal" case first
+	 * Handle the "normal" case first - VM_FAULT_MAJOR / VM_FAULT_MINOR
 	 */
-	if (fault > 0)
+	if (fault >= VM_FAULT_MINOR)
 		return 0;
 
 	/*
@@ -261,7 +261,7 @@ do_page_fault(unsigned long addr, unsign
 		do_exit(SIGKILL);
 		return 0;
 
-	case 0:
+	case VM_FAULT_SIGBUS:
 		/*
 		 * We had some memory, but were unable to
 		 * successfully fix up this page fault.
@@ -372,49 +372,50 @@ do_bad(unsigned long addr, unsigned int 
 static struct fsr_info {
 	int	(*fn)(unsigned long addr, unsigned int fsr, struct pt_regs *regs);
 	int	sig;
+	int	code;
 	const char *name;
 } fsr_info[] = {
 	/*
 	 * The following are the standard ARMv3 and ARMv4 aborts.  ARMv5
 	 * defines these to be "precise" aborts.
 	 */
-	{ do_bad,		SIGSEGV, "vector exception"		   },
-	{ do_bad,		SIGILL,	 "alignment exception"		   },
-	{ do_bad,		SIGKILL, "terminal exception"		   },
-	{ do_bad,		SIGILL,	 "alignment exception"		   },
-	{ do_bad,		SIGBUS,	 "external abort on linefetch"	   },
-	{ do_translation_fault,	SIGSEGV, "section translation fault"	   },
-	{ do_bad,		SIGBUS,	 "external abort on linefetch"	   },
-	{ do_page_fault,	SIGSEGV, "page translation fault"	   },
-	{ do_bad,		SIGBUS,	 "external abort on non-linefetch" },
-	{ do_bad,		SIGSEGV, "section domain fault"		   },
-	{ do_bad,		SIGBUS,	 "external abort on non-linefetch" },
-	{ do_bad,		SIGSEGV, "page domain fault"		   },
-	{ do_bad,		SIGBUS,	 "external abort on translation"   },
-	{ do_sect_fault,	SIGSEGV, "section permission fault"	   },
-	{ do_bad,		SIGBUS,	 "external abort on translation"   },
-	{ do_page_fault,	SIGSEGV, "page permission fault"	   },
+	{ do_bad,		SIGSEGV, 0,		"vector exception"		   },
+	{ do_bad,		SIGILL,	 BUS_ADRALN,	"alignment exception"		   },
+	{ do_bad,		SIGKILL, 0,		"terminal exception"		   },
+	{ do_bad,		SIGILL,	 BUS_ADRALN,	"alignment exception"		   },
+	{ do_bad,		SIGBUS,	 0,		"external abort on linefetch"	   },
+	{ do_translation_fault,	SIGSEGV, SEGV_MAPERR,	"section translation fault"	   },
+	{ do_bad,		SIGBUS,	 0,		"external abort on linefetch"	   },
+	{ do_page_fault,	SIGSEGV, SEGV_MAPERR,	"page translation fault"	   },
+	{ do_bad,		SIGBUS,	 0,		"external abort on non-linefetch"  },
+	{ do_bad,		SIGSEGV, SEGV_ACCERR,	"section domain fault"		   },
+	{ do_bad,		SIGBUS,	 0,		"external abort on non-linefetch"  },
+	{ do_bad,		SIGSEGV, SEGV_ACCERR,	"page domain fault"		   },
+	{ do_bad,		SIGBUS,	 0,		"external abort on translation"	   },
+	{ do_sect_fault,	SIGSEGV, SEGV_ACCERR,	"section permission fault"	   },
+	{ do_bad,		SIGBUS,	 0,		"external abort on translation"	   },
+	{ do_page_fault,	SIGSEGV, SEGV_ACCERR,	"page permission fault"		   },
 	/*
 	 * The following are "imprecise" aborts, which are signalled by bit
 	 * 10 of the FSR, and may not be recoverable.  These are only
 	 * supported if the CPU abort handler supports bit 10.
 	 */
-	{ do_bad,		SIGBUS,  "unknown 16"			   },
-	{ do_bad,		SIGBUS,  "unknown 17"			   },
-	{ do_bad,		SIGBUS,  "unknown 18"			   },
-	{ do_bad,		SIGBUS,  "unknown 19"			   },
-	{ do_bad,		SIGBUS,  "lock abort"			   }, /* xscale */
-	{ do_bad,		SIGBUS,  "unknown 21"			   },
-	{ do_bad,		SIGBUS,  "imprecise external abort"	   }, /* xscale */
-	{ do_bad,		SIGBUS,  "unknown 23"			   },
-	{ do_bad,		SIGBUS,  "dcache parity error"		   }, /* xscale */
-	{ do_bad,		SIGBUS,  "unknown 25"			   },
-	{ do_bad,		SIGBUS,  "unknown 26"			   },
-	{ do_bad,		SIGBUS,  "unknown 27"			   },
-	{ do_bad,		SIGBUS,  "unknown 28"			   },
-	{ do_bad,		SIGBUS,  "unknown 29"			   },
-	{ do_bad,		SIGBUS,  "unknown 30"			   },
-	{ do_bad,		SIGBUS,  "unknown 31"			   }
+	{ do_bad,		SIGBUS,  0,		"unknown 16"			   },
+	{ do_bad,		SIGBUS,  0,		"unknown 17"			   },
+	{ do_bad,		SIGBUS,  0,		"unknown 18"			   },
+	{ do_bad,		SIGBUS,  0,		"unknown 19"			   },
+	{ do_bad,		SIGBUS,  0,		"lock abort"			   }, /* xscale */
+	{ do_bad,		SIGBUS,  0,		"unknown 21"			   },
+	{ do_bad,		SIGBUS,  BUS_OBJERR,	"imprecise external abort"	   }, /* xscale */
+	{ do_bad,		SIGBUS,  0,		"unknown 23"			   },
+	{ do_bad,		SIGBUS,  0,		"dcache parity error"		   }, /* xscale */
+	{ do_bad,		SIGBUS,  0,		"unknown 25"			   },
+	{ do_bad,		SIGBUS,  0,		"unknown 26"			   },
+	{ do_bad,		SIGBUS,  0,		"unknown 27"			   },
+	{ do_bad,		SIGBUS,  0,		"unknown 28"			   },
+	{ do_bad,		SIGBUS,  0,		"unknown 29"			   },
+	{ do_bad,		SIGBUS,  0,		"unknown 30"			   },
+	{ do_bad,		SIGBUS,  0,		"unknown 31"			   }
 };
 
 void __init
@@ -435,15 +436,19 @@ asmlinkage void
 do_DataAbort(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
 {
 	const struct fsr_info *inf = fsr_info + (fsr & 15) + ((fsr & (1 << 10)) >> 6);
+	struct siginfo info;
 
 	if (!inf->fn(addr, fsr, regs))
 		return;
 
 	printk(KERN_ALERT "Unhandled fault: %s (0x%03x) at 0x%08lx\n",
 		inf->name, fsr, addr);
-	force_sig(inf->sig, current);
-	show_pte(current->mm, addr);
-	die_if_kernel("Oops", regs, 0);
+
+	info.si_signo = inf->sig;
+	info.si_errno = 0;
+	info.si_code  = inf->code;
+	info.si_addr  = (void __user *)addr;
+	notify_die("", regs, &info, fsr, 0);
 }
 
 asmlinkage void
diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c
--- a/arch/arm/mm/flush.c
+++ b/arch/arm/mm/flush.c
@@ -37,13 +37,8 @@ static void flush_pfn_alias(unsigned lon
 #define flush_pfn_alias(pfn,vaddr)	do { } while (0)
 #endif
 
-static void __flush_dcache_page(struct address_space *mapping, struct page *page)
+void __flush_dcache_page(struct address_space *mapping, struct page *page)
 {
-	struct mm_struct *mm = current->active_mm;
-	struct vm_area_struct *mpnt;
-	struct prio_tree_iter iter;
-	pgoff_t pgoff;
-
 	/*
 	 * Writeback any data associated with the kernel mapping of this
 	 * page.  This ensures that data in the physical page is mutually
@@ -52,24 +47,21 @@ static void __flush_dcache_page(struct a
 	__cpuc_flush_dcache_page(page_address(page));
 
 	/*
-	 * If there's no mapping pointer here, then this page isn't
-	 * visible to userspace yet, so there are no cache lines
-	 * associated with any other aliases.
-	 */
-	if (!mapping)
-		return;
-
-	/*
-	 * This is a page cache page.  If we have a VIPT cache, we
-	 * only need to do one flush - which would be at the relevant
+	 * If this is a page cache page, and we have an aliasing VIPT cache,
+	 * we only need to do one flush - which would be at the relevant
 	 * userspace colour, which is congruent with page->index.
 	 */
-	if (cache_is_vipt()) {
-		if (cache_is_vipt_aliasing())
-			flush_pfn_alias(page_to_pfn(page),
-					page->index << PAGE_CACHE_SHIFT);
-		return;
-	}
+	if (mapping && cache_is_vipt_aliasing())
+		flush_pfn_alias(page_to_pfn(page),
+				page->index << PAGE_CACHE_SHIFT);
+}
+
+static void __flush_dcache_aliases(struct address_space *mapping, struct page *page)
+{
+	struct mm_struct *mm = current->active_mm;
+	struct vm_area_struct *mpnt;
+	struct prio_tree_iter iter;
+	pgoff_t pgoff;
 
 	/*
 	 * There are possible user space mappings of this page:
@@ -116,12 +108,12 @@ void flush_dcache_page(struct page *page
 {
 	struct address_space *mapping = page_mapping(page);
 
-	if (cache_is_vipt_nonaliasing())
-		return;
-
 	if (mapping && !mapping_mapped(mapping))
 		set_bit(PG_dcache_dirty, &page->flags);
-	else
+	else {
 		__flush_dcache_page(mapping, page);
+		if (mapping && cache_is_vivt())
+			__flush_dcache_aliases(mapping, page);
+	}
 }
 EXPORT_SYMBOL(flush_dcache_page);
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -93,14 +93,7 @@ struct node_info {
 };
 
 #define O_PFN_DOWN(x)	((x) >> PAGE_SHIFT)
-#define V_PFN_DOWN(x)	O_PFN_DOWN(__pa(x))
-
 #define O_PFN_UP(x)	(PAGE_ALIGN(x) >> PAGE_SHIFT)
-#define V_PFN_UP(x)	O_PFN_UP(__pa(x))
-
-#define PFN_SIZE(x)	((x) >> PAGE_SHIFT)
-#define PFN_RANGE(s,e)	PFN_SIZE(PAGE_ALIGN((unsigned long)(e)) - \
-				(((unsigned long)(s)) & PAGE_MASK))
 
 /*
  * FIXME: We really want to avoid allocating the bootmap bitmap
@@ -113,7 +106,7 @@ find_bootmap_pfn(int node, struct meminf
 {
 	unsigned int start_pfn, bank, bootmap_pfn;
 
-	start_pfn   = V_PFN_UP(&_end);
+	start_pfn   = O_PFN_UP(__pa(&_end));
 	bootmap_pfn = 0;
 
 	for (bank = 0; bank < mi->nr_banks; bank ++) {
@@ -122,9 +115,9 @@ find_bootmap_pfn(int node, struct meminf
 		if (mi->bank[bank].node != node)
 			continue;
 
-		start = O_PFN_UP(mi->bank[bank].start);
-		end   = O_PFN_DOWN(mi->bank[bank].size +
-				   mi->bank[bank].start);
+		start = mi->bank[bank].start >> PAGE_SHIFT;
+		end   = (mi->bank[bank].size +
+			 mi->bank[bank].start) >> PAGE_SHIFT;
 
 		if (end < start_pfn)
 			continue;
@@ -191,8 +184,8 @@ find_memend_and_nodes(struct meminfo *mi
 		/*
 		 * Get the start and end pfns for this bank
 		 */
-		start = O_PFN_UP(mi->bank[i].start);
-		end   = O_PFN_DOWN(mi->bank[i].start + mi->bank[i].size);
+		start = mi->bank[i].start >> PAGE_SHIFT;
+		end   = (mi->bank[i].start + mi->bank[i].size) >> PAGE_SHIFT;
 
 		if (np[node].start > start)
 			np[node].start = start;
@@ -444,7 +437,7 @@ void __init paging_init(struct meminfo *
 	memtable_init(mi);
 	if (mdesc->map_io)
 		mdesc->map_io();
-	flush_tlb_all();
+	local_flush_tlb_all();
 
 	/*
 	 * initialise the zones within each node
@@ -529,6 +522,69 @@ static inline void free_area(unsigned lo
 		printk(KERN_INFO "Freeing %s memory: %dK\n", s, size);
 }
 
+static inline void
+free_memmap(int node, unsigned long start_pfn, unsigned long end_pfn)
+{
+	struct page *start_pg, *end_pg;
+	unsigned long pg, pgend;
+
+	/*
+	 * Convert start_pfn/end_pfn to a struct page pointer.
+	 */
+	start_pg = pfn_to_page(start_pfn);
+	end_pg = pfn_to_page(end_pfn);
+
+	/*
+	 * Convert to physical addresses, and
+	 * round start upwards and end downwards.
+	 */
+	pg = PAGE_ALIGN(__pa(start_pg));
+	pgend = __pa(end_pg) & PAGE_MASK;
+
+	/*
+	 * If there are free pages between these,
+	 * free the section of the memmap array.
+	 */
+	if (pg < pgend)
+		free_bootmem_node(NODE_DATA(node), pg, pgend - pg);
+}
+
+/*
+ * The mem_map array can get very big.  Free the unused area of the memory map.
+ */
+static void __init free_unused_memmap_node(int node, struct meminfo *mi)
+{
+	unsigned long bank_start, prev_bank_end = 0;
+	unsigned int i;
+
+	/*
+	 * [FIXME] This relies on each bank being in address order.  This
+	 * may not be the case, especially if the user has provided the
+	 * information on the command line.
+	 */
+	for (i = 0; i < mi->nr_banks; i++) {
+		if (mi->bank[i].size == 0 || mi->bank[i].node != node)
+			continue;
+
+		bank_start = mi->bank[i].start >> PAGE_SHIFT;
+		if (bank_start < prev_bank_end) {
+			printk(KERN_ERR "MEM: unordered memory banks.  "
+				"Not freeing memmap.\n");
+			break;
+		}
+
+		/*
+		 * If we had a previous bank, and there is a space
+		 * between the current bank and the previous, free it.
+		 */
+		if (prev_bank_end && prev_bank_end != bank_start)
+			free_memmap(node, prev_bank_end, bank_start);
+
+		prev_bank_end = (mi->bank[i].start +
+				 mi->bank[i].size) >> PAGE_SHIFT;
+	}
+}
+
 /*
  * mem_init() marks the free areas in the mem_map and tells us how much
  * memory is free.  This is done after various parts of the system have
@@ -547,16 +603,12 @@ void __init mem_init(void)
 	max_mapnr   = virt_to_page(high_memory) - mem_map;
 #endif
 
-	/*
-	 * We may have non-contiguous memory.
-	 */
-	if (meminfo.nr_banks != 1)
-		create_memmap_holes(&meminfo);
-
 	/* this will put all unused low memory onto the freelists */
 	for_each_online_node(node) {
 		pg_data_t *pgdat = NODE_DATA(node);
 
+		free_unused_memmap_node(node, &meminfo);
+
 		if (pgdat->node_spanned_pages != 0)
 			totalram_pages += free_all_bootmem_node(pgdat);
 	}
diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c
--- a/arch/arm/mm/ioremap.c
+++ b/arch/arm/mm/ioremap.c
@@ -170,3 +170,50 @@ void __iounmap(void __iomem *addr)
 	vfree((void *) (PAGE_MASK & (unsigned long) addr));
 }
 EXPORT_SYMBOL(__iounmap);
+
+#ifdef __io
+void __iomem *ioport_map(unsigned long port, unsigned int nr)
+{
+	return __io(port);
+}
+EXPORT_SYMBOL(ioport_map);
+
+void ioport_unmap(void __iomem *addr)
+{
+}
+EXPORT_SYMBOL(ioport_unmap);
+#endif
+
+#ifdef CONFIG_PCI
+#include <linux/pci.h>
+#include <linux/ioport.h>
+
+void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen)
+{
+	unsigned long start = pci_resource_start(dev, bar);
+	unsigned long len   = pci_resource_len(dev, bar);
+	unsigned long flags = pci_resource_flags(dev, bar);
+
+	if (!len || !start)
+		return NULL;
+	if (maxlen && len > maxlen)
+		len = maxlen;
+	if (flags & IORESOURCE_IO)
+		return ioport_map(start, len);
+	if (flags & IORESOURCE_MEM) {
+		if (flags & IORESOURCE_CACHEABLE)
+			return ioremap(start, len);
+		return ioremap_nocache(start, len);
+	}
+	return NULL;
+}
+EXPORT_SYMBOL(pci_iomap);
+
+void pci_iounmap(struct pci_dev *dev, void __iomem *addr)
+{
+	if ((unsigned long)addr >= VMALLOC_START &&
+	    (unsigned long)addr < VMALLOC_END)
+		iounmap(addr);
+}
+EXPORT_SYMBOL(pci_iounmap);
+#endif
diff --git a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c
--- a/arch/arm/mm/mm-armv.c
+++ b/arch/arm/mm/mm-armv.c
@@ -169,7 +169,14 @@ pgd_t *get_pgd_slow(struct mm_struct *mm
 
 	memzero(new_pgd, FIRST_KERNEL_PGD_NR * sizeof(pgd_t));
 
+	/*
+	 * Copy over the kernel and IO PGD entries
+	 */
 	init_pgd = pgd_offset_k(0);
+	memcpy(new_pgd + FIRST_KERNEL_PGD_NR, init_pgd + FIRST_KERNEL_PGD_NR,
+		       (PTRS_PER_PGD - FIRST_KERNEL_PGD_NR) * sizeof(pgd_t));
+
+	clean_dcache_area(new_pgd, PTRS_PER_PGD * sizeof(pgd_t));
 
 	if (!vectors_high()) {
 		/*
@@ -198,14 +205,6 @@ pgd_t *get_pgd_slow(struct mm_struct *mm
 		spin_unlock(&mm->page_table_lock);
 	}
 
-	/*
-	 * Copy over the kernel and IO PGD entries
-	 */
-	memcpy(new_pgd + FIRST_KERNEL_PGD_NR, init_pgd + FIRST_KERNEL_PGD_NR,
-		       (PTRS_PER_PGD - FIRST_KERNEL_PGD_NR) * sizeof(pgd_t));
-
-	clean_dcache_area(new_pgd, PTRS_PER_PGD * sizeof(pgd_t));
-
 	return new_pgd;
 
 no_pte:
@@ -384,6 +383,7 @@ static void __init build_mem_type_table(
 {
 	struct cachepolicy *cp;
 	unsigned int cr = get_cr();
+	unsigned int user_pgprot;
 	int cpu_arch = cpu_architecture();
 	int i;
 
@@ -400,7 +400,7 @@ static void __init build_mem_type_table(
 		ecc_mask = 0;
 	}
 
-	if (cpu_arch <= CPU_ARCH_ARMv5) {
+	if (cpu_arch <= CPU_ARCH_ARMv5TEJ) {
 		for (i = 0; i < ARRAY_SIZE(mem_types); i++) {
 			if (mem_types[i].prot_l1)
 				mem_types[i].prot_l1 |= PMD_BIT4;
@@ -409,6 +409,9 @@ static void __init build_mem_type_table(
 		}
 	}
 
+	cp = &cache_policies[cachepolicy];
+	user_pgprot = cp->pte;
+
 	/*
 	 * ARMv6 and above have extended page tables.
 	 */
@@ -426,9 +429,19 @@ static void __init build_mem_type_table(
 		mem_types[MT_ROM].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
 		mem_types[MT_MINICLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
 		mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
-	}
 
-	cp = &cache_policies[cachepolicy];
+		/*
+		 * Mark the device area as "shared device"
+		 */
+		mem_types[MT_DEVICE].prot_pte |= L_PTE_BUFFERABLE;
+		mem_types[MT_DEVICE].prot_sect |= PMD_SECT_BUFFERED;
+
+		/*
+		 * User pages need to be mapped with the ASID
+		 * (iow, non-global)
+		 */
+		user_pgprot |= L_PTE_ASID;
+	}
 
 	if (cpu_arch >= CPU_ARCH_ARMv5) {
 		mem_types[MT_LOW_VECTORS].prot_pte |= cp->pte & PTE_CACHEABLE;
@@ -446,7 +459,7 @@ static void __init build_mem_type_table(
 
 	for (i = 0; i < 16; i++) {
 		unsigned long v = pgprot_val(protection_map[i]);
-		v &= (~(PTE_BUFFERABLE|PTE_CACHEABLE)) | cp->pte;
+		v &= (~(PTE_BUFFERABLE|PTE_CACHEABLE)) | user_pgprot;
 		protection_map[i] = __pgprot(v);
 	}
 
@@ -585,7 +598,7 @@ void setup_mm_for_reboot(char mode)
 		pmdval = (i << PGDIR_SHIFT) |
 			 PMD_SECT_AP_WRITE | PMD_SECT_AP_READ |
 			 PMD_TYPE_SECT;
-		if (cpu_arch <= CPU_ARCH_ARMv5)
+		if (cpu_arch <= CPU_ARCH_ARMv5TEJ)
 			pmdval |= PMD_BIT4;
 		pmd = pmd_off(pgd, i << PGDIR_SHIFT);
 		pmd[0] = __pmd(pmdval);
@@ -683,7 +696,7 @@ void __init memtable_init(struct meminfo
 	}
 
 	flush_cache_all();
-	flush_tlb_all();
+	local_flush_tlb_all();
 
 	top_pmd = pmd_off_k(0xffff0000);
 }
@@ -698,75 +711,3 @@ void __init iotable_init(struct map_desc
 	for (i = 0; i < nr; i++)
 		create_mapping(io_desc + i);
 }
-
-static inline void
-free_memmap(int node, unsigned long start_pfn, unsigned long end_pfn)
-{
-	struct page *start_pg, *end_pg;
-	unsigned long pg, pgend;
-
-	/*
-	 * Convert start_pfn/end_pfn to a struct page pointer.
-	 */
-	start_pg = pfn_to_page(start_pfn);
-	end_pg = pfn_to_page(end_pfn);
-
-	/*
-	 * Convert to physical addresses, and
-	 * round start upwards and end downwards.
-	 */
-	pg = PAGE_ALIGN(__pa(start_pg));
-	pgend = __pa(end_pg) & PAGE_MASK;
-
-	/*
-	 * If there are free pages between these,
-	 * free the section of the memmap array.
-	 */
-	if (pg < pgend)
-		free_bootmem_node(NODE_DATA(node), pg, pgend - pg);
-}
-
-static inline void free_unused_memmap_node(int node, struct meminfo *mi)
-{
-	unsigned long bank_start, prev_bank_end = 0;
-	unsigned int i;
-
-	/*
-	 * [FIXME] This relies on each bank being in address order.  This
-	 * may not be the case, especially if the user has provided the
-	 * information on the command line.
-	 */
-	for (i = 0; i < mi->nr_banks; i++) {
-		if (mi->bank[i].size == 0 || mi->bank[i].node != node)
-			continue;
-
-		bank_start = mi->bank[i].start >> PAGE_SHIFT;
-		if (bank_start < prev_bank_end) {
-			printk(KERN_ERR "MEM: unordered memory banks.  "
-				"Not freeing memmap.\n");
-			break;
-		}
-
-		/*
-		 * If we had a previous bank, and there is a space
-		 * between the current bank and the previous, free it.
-		 */
-		if (prev_bank_end && prev_bank_end != bank_start)
-			free_memmap(node, prev_bank_end, bank_start);
-
-		prev_bank_end = PAGE_ALIGN(mi->bank[i].start +
-					   mi->bank[i].size) >> PAGE_SHIFT;
-	}
-}
-
-/*
- * The mem_map array can get very big.  Free
- * the unused area of the memory map.
- */
-void __init create_memmap_holes(struct meminfo *mi)
-{
-	int node;
-
-	for_each_online_node(node)
-		free_unused_memmap_node(node, mi);
-}
diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c
--- a/arch/arm/mm/mmap.c
+++ b/arch/arm/mm/mmap.c
@@ -73,7 +73,12 @@ arch_get_unmapped_area(struct file *filp
 		    (!vma || addr + len <= vma->vm_start))
 			return addr;
 	}
-	start_addr = addr = mm->free_area_cache;
+	if (len > mm->cached_hole_size) {
+	        start_addr = addr = mm->free_area_cache;
+	} else {
+	        start_addr = addr = TASK_UNMAPPED_BASE;
+	        mm->cached_hole_size = 0;
+	}
 
 full_search:
 	if (do_align)
@@ -90,6 +95,7 @@ full_search:
 			 */
 			if (start_addr != TASK_UNMAPPED_BASE) {
 				start_addr = addr = TASK_UNMAPPED_BASE;
+				mm->cached_hole_size = 0;
 				goto full_search;
 			}
 			return -ENOMEM;
@@ -101,6 +107,8 @@ full_search:
 			mm->free_area_cache = addr + len;
 			return addr;
 		}
+		if (addr + mm->cached_hole_size < vma->vm_start)
+		        mm->cached_hole_size = vma->vm_start - addr;
 		addr = vma->vm_end;
 		if (do_align)
 			addr = COLOUR_ALIGN(addr, pgoff);
diff --git a/arch/arm/mm/proc-arm1020.S b/arch/arm/mm/proc-arm1020.S
--- a/arch/arm/mm/proc-arm1020.S
+++ b/arch/arm/mm/proc-arm1020.S
@@ -445,14 +445,14 @@ __arm1020_setup:
 	/*
 	 *  R
 	 * .RVI ZFRS BLDP WCAM
-	 * .0.1 1001 ..11 0101	/* FIXME: why no V bit? */
+	 * .011 1001 ..11 0101
 	 */
 	.type	arm1020_cr1_clear, #object
 	.type	arm1020_cr1_set, #object
 arm1020_cr1_clear:
 	.word	0x593f
 arm1020_cr1_set:
-	.word	0x1935
+	.word	0x3935
 
 	__INITDATA
 
diff --git a/arch/arm/mm/proc-arm1020e.S b/arch/arm/mm/proc-arm1020e.S
--- a/arch/arm/mm/proc-arm1020e.S
+++ b/arch/arm/mm/proc-arm1020e.S
@@ -427,14 +427,14 @@ __arm1020e_setup:
 	/*
 	 *  R
 	 * .RVI ZFRS BLDP WCAM
-	 * .0.1 1001 ..11 0101	/* FIXME: why no V bit? */
+	 * .011 1001 ..11 0101
 	 */
 	.type	arm1020e_cr1_clear, #object
 	.type	arm1020e_cr1_set, #object
 arm1020e_cr1_clear:
 	.word	0x5f3f
 arm1020e_cr1_set:
-	.word	0x1935
+	.word	0x3935
 
 	__INITDATA
 
diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S
--- a/arch/arm/mm/proc-v6.S
+++ b/arch/arm/mm/proc-v6.S
@@ -105,18 +105,12 @@ ENTRY(cpu_v6_dcache_clean_area)
 ENTRY(cpu_v6_switch_mm)
 	mov	r2, #0
 	ldr	r1, [r1, #MM_CONTEXT_ID]	@ get mm->context.id
-	mcr     p15, 0, r2, c7, c5, 6           @ flush BTAC/BTB
+	mcr	p15, 0, r2, c7, c5, 6		@ flush BTAC/BTB
 	mcr	p15, 0, r2, c7, c10, 4		@ drain write buffer
 	mcr	p15, 0, r0, c2, c0, 0		@ set TTB 0
 	mcr	p15, 0, r1, c13, c0, 1		@ set context ID
 	mov	pc, lr
 
-#define nG	(1 << 11)
-#define APX	(1 << 9)
-#define AP1	(1 << 5)
-#define AP0	(1 << 4)
-#define XN	(1 << 0)
-
 /*
  *	cpu_v6_set_pte(ptep, pte)
  *
@@ -132,31 +126,31 @@ ENTRY(cpu_v6_switch_mm)
  *	  100x   1   0   1	r/o	no acc
  *	  10x0   1   0   1	r/o	no acc
  *	  1011   0   0   1	r/w	no acc
- *	  110x   1   1   0	r/o	r/o
- *	  11x0   1   1   0	r/o	r/o
+ *	  110x   0   1   0	r/w	r/o
+ *	  11x0   0   1   0	r/w	r/o
  *	  1111   0   1   1	r/w	r/w
  */
 ENTRY(cpu_v6_set_pte)
 	str	r1, [r0], #-2048		@ linux version
 
-	bic	r2, r1, #0x00000ff0
+	bic	r2, r1, #0x000007f0
 	bic	r2, r2, #0x00000003
-	orr	r2, r2, #AP0 | 2
+	orr	r2, r2, #PTE_EXT_AP0 | 2
 
 	tst	r1, #L_PTE_WRITE
 	tstne	r1, #L_PTE_DIRTY
-	orreq	r2, r2, #APX
+	orreq	r2, r2, #PTE_EXT_APX
 
 	tst	r1, #L_PTE_USER
-	orrne	r2, r2, #AP1 | nG
-	tstne	r2, #APX
-	eorne	r2, r2, #AP0
+	orrne	r2, r2, #PTE_EXT_AP1
+	tstne	r2, #PTE_EXT_APX
+	bicne	r2, r2, #PTE_EXT_APX | PTE_EXT_AP0
 
 	tst	r1, #L_PTE_YOUNG
-	biceq	r2, r2, #APX | AP1 | AP0
+	biceq	r2, r2, #PTE_EXT_APX | PTE_EXT_AP_MASK
 
 @	tst	r1, #L_PTE_EXEC
-@	orreq	r2, r2, #XN
+@	orreq	r2, r2, #PTE_EXT_XN
 
 	tst	r1, #L_PTE_PRESENT
 	moveq	r2, #0
@@ -200,7 +194,7 @@ __v6_setup:
 	mcr	p15, 0, r4, c2, c0, 1		@ load TTB1
 #ifdef CONFIG_VFP
 	mrc	p15, 0, r0, c1, c0, 2
-	orr	r0, r0, #(3 << 20)
+	orr	r0, r0, #(0xf << 20)
 	mcr	p15, 0, r0, c1, c0, 2		@ Enable full access to VFP
 #endif
 	mrc	p15, 0, r0, c1, c0, 0		@ read control register
diff --git a/arch/arm/mm/proc-xscale.S b/arch/arm/mm/proc-xscale.S
--- a/arch/arm/mm/proc-xscale.S
+++ b/arch/arm/mm/proc-xscale.S
@@ -370,142 +370,6 @@ ENTRY(cpu_xscale_dcache_clean_area)
 	bhi	1b
 	mov	pc, lr
 
-/* ================================ CACHE LOCKING============================
- *
- * The XScale MicroArchitecture implements support for locking entries into
- * the data and instruction cache.  The following functions implement the core
- * low level instructions needed to accomplish the locking.  The developer's
- * manual states that the code that performs the locking must be in non-cached
- * memory.  To accomplish this, the code in xscale-cache-lock.c copies the
- * following functions from the cache into a non-cached memory region that
- * is allocated through consistent_alloc().
- *
- */
-	.align	5
-/*
- * xscale_icache_lock
- *
- * r0: starting address to lock
- * r1: end address to lock
- */
-ENTRY(xscale_icache_lock)
-
-iLockLoop:
-	bic	r0, r0, #CACHELINESIZE - 1
-	mcr	p15, 0, r0, c9, c1, 0	@ lock into cache
-	cmp	r0, r1			@ are we done?
-	add	r0, r0, #CACHELINESIZE	@ advance to next cache line
-	bls	iLockLoop
-	mov	pc, lr
-
-/*
- * xscale_icache_unlock
- */
-ENTRY(xscale_icache_unlock)
-	mcr	p15, 0, r0, c9, c1, 1	@ Unlock icache
-	mov	pc, lr
-
-/*
- * xscale_dcache_lock
- *
- * r0: starting address to lock
- * r1: end address to lock
- */
-ENTRY(xscale_dcache_lock)
-	mcr	p15, 0, ip, c7, c10, 4		@ Drain Write (& Fill) Buffer
-	mov	r2, #1
-	mcr	p15, 0, r2, c9, c2, 0	@ Put dcache in lock mode
-	cpwait	ip			@ Wait for completion
-
-	mrs	r2, cpsr
-	orr	r3, r2, #PSR_F_BIT | PSR_I_BIT
-dLockLoop:
-	msr	cpsr_c, r3
-	mcr	p15, 0, r0, c7, c10, 1	@ Write back line if it is dirty
-	mcr	p15, 0, r0, c7, c6, 1	@ Flush/invalidate line
-	msr	cpsr_c, r2
-	ldr	ip, [r0], #CACHELINESIZE @ Preload 32 bytes into cache from
-					@ location [r0]. Post-increment
-					@ r3 to next cache line
-	cmp	r0, r1			@ Are we done?
-	bls	dLockLoop
-
-	mcr	p15, 0, ip, c7, c10, 4		@ Drain Write (& Fill) Buffer
-	mov	r2, #0
-	mcr	p15, 0, r2, c9, c2, 0	@ Get out of lock mode
-	cpwait_ret lr, ip
-
-/*
- * xscale_dcache_unlock
- */
-ENTRY(xscale_dcache_unlock)
-	mcr	p15, 0, ip, c7, c10, 4		@ Drain Write (& Fill) Buffer
-	mcr	p15, 0, ip, c9, c2, 1	@ Unlock cache
-	mov	pc, lr
-
-/*
- * Needed to determine the length of the code that needs to be copied.
- */
-	.align	5
-ENTRY(xscale_cache_dummy)
-	mov	pc, lr
-
-/* ================================ TLB LOCKING==============================
- *
- * The XScale MicroArchitecture implements support for locking entries into
- * the Instruction and Data TLBs.  The following functions provide the
- * low level support for supporting these under Linux.  xscale-lock.c
- * implements some higher level management code.  Most of the following
- * is taken straight out of the Developer's Manual.
- */
-
-/*
- * Lock I-TLB entry
- *
- * r0: Virtual address to translate and lock
- */
-	.align	5
-ENTRY(xscale_itlb_lock)
-	mrs	r2, cpsr
-	orr	r3, r2, #PSR_F_BIT | PSR_I_BIT
-	msr	cpsr_c, r3			@ Disable interrupts
-	mcr	p15, 0, r0, c8, c5, 1		@ Invalidate I-TLB entry
-	mcr	p15, 0, r0, c10, c4, 0		@ Translate and lock
-	msr	cpsr_c, r2			@ Restore interrupts
-	cpwait_ret lr, ip
-
-/*
- * Lock D-TLB entry
- *
- * r0: Virtual address to translate and lock
- */
-	.align	5
-ENTRY(xscale_dtlb_lock)
-	mrs	r2, cpsr
-	orr	r3, r2, #PSR_F_BIT | PSR_I_BIT
-	msr	cpsr_c, r3			@ Disable interrupts
-	mcr	p15, 0, r0, c8, c6, 1		@ Invalidate D-TLB entry
-	mcr	p15, 0, r0, c10, c8, 0		@ Translate and lock
-	msr	cpsr_c, r2			@ Restore interrupts
-	cpwait_ret lr, ip
-
-/*
- * Unlock all I-TLB entries
- */
-	.align	5
-ENTRY(xscale_itlb_unlock)
-	mcr	p15, 0, ip, c10, c4, 1		@ Unlock I-TLB
-	mcr	p15, 0, ip, c8, c5, 0		@ Invalidate I-TLB
-	cpwait_ret lr, ip
-
-/*
- * Unlock all D-TLB entries
- */
-ENTRY(xscale_dtlb_unlock)
-	mcr	p15, 0, ip, c10, c8, 1		@ Unlock D-TBL
-	mcr	p15, 0, ip, c8, c6, 0		@ Invalidate D-TLB
-	cpwait_ret lr, ip
-
 /* =============================== PageTable ============================== */
 
 #define PTE_CACHE_WRITE_ALLOCATE 0
diff --git a/arch/arm/nwfpe/double_cpdo.c b/arch/arm/nwfpe/double_cpdo.c
--- a/arch/arm/nwfpe/double_cpdo.c
+++ b/arch/arm/nwfpe/double_cpdo.c
@@ -40,17 +40,17 @@ float64 float64_arccos(float64 rFm);
 float64 float64_pow(float64 rFn, float64 rFm);
 float64 float64_pol(float64 rFn, float64 rFm);
 
-static float64 float64_rsf(float64 rFn, float64 rFm)
+static float64 float64_rsf(struct roundingData *roundData, float64 rFn, float64 rFm)
 {
-	return float64_sub(rFm, rFn);
+	return float64_sub(roundData, rFm, rFn);
 }
 
-static float64 float64_rdv(float64 rFn, float64 rFm)
+static float64 float64_rdv(struct roundingData *roundData, float64 rFn, float64 rFm)
 {
-	return float64_div(rFm, rFn);
+	return float64_div(roundData, rFm, rFn);
 }
 
-static float64 (*const dyadic_double[16])(float64 rFn, float64 rFm) = {
+static float64 (*const dyadic_double[16])(struct roundingData*, float64 rFn, float64 rFm) = {
 	[ADF_CODE >> 20] = float64_add,
 	[MUF_CODE >> 20] = float64_mul,
 	[SUF_CODE >> 20] = float64_sub,
@@ -65,12 +65,12 @@ static float64 (*const dyadic_double[16]
 	[FRD_CODE >> 20] = float64_rdv,
 };
 
-static float64 float64_mvf(float64 rFm)
+static float64 float64_mvf(struct roundingData *roundData,float64 rFm)
 {
 	return rFm;
 }
 
-static float64 float64_mnf(float64 rFm)
+static float64 float64_mnf(struct roundingData *roundData,float64 rFm)
 {
 	union float64_components u;
 
@@ -84,7 +84,7 @@ static float64 float64_mnf(float64 rFm)
 	return u.f64;
 }
 
-static float64 float64_abs(float64 rFm)
+static float64 float64_abs(struct roundingData *roundData,float64 rFm)
 {
 	union float64_components u;
 
@@ -98,7 +98,7 @@ static float64 float64_abs(float64 rFm)
 	return u.f64;
 }
 
-static float64 (*const monadic_double[16])(float64 rFm) = {
+static float64 (*const monadic_double[16])(struct roundingData *, float64 rFm) = {
 	[MVF_CODE >> 20] = float64_mvf,
 	[MNF_CODE >> 20] = float64_mnf,
 	[ABS_CODE >> 20] = float64_abs,
@@ -108,7 +108,7 @@ static float64 (*const monadic_double[16
 	[NRM_CODE >> 20] = float64_mvf,
 };
 
-unsigned int DoubleCPDO(const unsigned int opcode, FPREG * rFd)
+unsigned int DoubleCPDO(struct roundingData *roundData, const unsigned int opcode, FPREG * rFd)
 {
 	FPA11 *fpa11 = GET_FPA11();
 	float64 rFm;
@@ -151,13 +151,13 @@ unsigned int DoubleCPDO(const unsigned i
 		}
 
 		if (dyadic_double[opc_mask_shift]) {
-			rFd->fDouble = dyadic_double[opc_mask_shift](rFn, rFm);
+			rFd->fDouble = dyadic_double[opc_mask_shift](roundData, rFn, rFm);
 		} else {
 			return 0;
 		}
 	} else {
 		if (monadic_double[opc_mask_shift]) {
-			rFd->fDouble = monadic_double[opc_mask_shift](rFm);
+			rFd->fDouble = monadic_double[opc_mask_shift](roundData, rFm);
 		} else {
 			return 0;
 		}
diff --git a/arch/arm/nwfpe/extended_cpdo.c b/arch/arm/nwfpe/extended_cpdo.c
--- a/arch/arm/nwfpe/extended_cpdo.c
+++ b/arch/arm/nwfpe/extended_cpdo.c
@@ -35,17 +35,17 @@ floatx80 floatx80_arccos(floatx80 rFm);
 floatx80 floatx80_pow(floatx80 rFn, floatx80 rFm);
 floatx80 floatx80_pol(floatx80 rFn, floatx80 rFm);
 
-static floatx80 floatx80_rsf(floatx80 rFn, floatx80 rFm)
+static floatx80 floatx80_rsf(struct roundingData *roundData, floatx80 rFn, floatx80 rFm)
 {
-	return floatx80_sub(rFm, rFn);
+	return floatx80_sub(roundData, rFm, rFn);
 }
 
-static floatx80 floatx80_rdv(floatx80 rFn, floatx80 rFm)
+static floatx80 floatx80_rdv(struct roundingData *roundData, floatx80 rFn, floatx80 rFm)
 {
-	return floatx80_div(rFm, rFn);
+	return floatx80_div(roundData, rFm, rFn);
 }
 
-static floatx80 (*const dyadic_extended[16])(floatx80 rFn, floatx80 rFm) = {
+static floatx80 (*const dyadic_extended[16])(struct roundingData*, floatx80 rFn, floatx80 rFm) = {
 	[ADF_CODE >> 20] = floatx80_add,
 	[MUF_CODE >> 20] = floatx80_mul,
 	[SUF_CODE >> 20] = floatx80_sub,
@@ -60,24 +60,24 @@ static floatx80 (*const dyadic_extended[
 	[FRD_CODE >> 20] = floatx80_rdv,
 };
 
-static floatx80 floatx80_mvf(floatx80 rFm)
+static floatx80 floatx80_mvf(struct roundingData *roundData, floatx80 rFm)
 {
 	return rFm;
 }
 
-static floatx80 floatx80_mnf(floatx80 rFm)
+static floatx80 floatx80_mnf(struct roundingData *roundData, floatx80 rFm)
 {
 	rFm.high ^= 0x8000;
 	return rFm;
 }
 
-static floatx80 floatx80_abs(floatx80 rFm)
+static floatx80 floatx80_abs(struct roundingData *roundData, floatx80 rFm)
 {
 	rFm.high &= 0x7fff;
 	return rFm;
 }
 
-static floatx80 (*const monadic_extended[16])(floatx80 rFm) = {
+static floatx80 (*const monadic_extended[16])(struct roundingData*, floatx80 rFm) = {
 	[MVF_CODE >> 20] = floatx80_mvf,
 	[MNF_CODE >> 20] = floatx80_mnf,
 	[ABS_CODE >> 20] = floatx80_abs,
@@ -87,7 +87,7 @@ static floatx80 (*const monadic_extended
 	[NRM_CODE >> 20] = floatx80_mvf,
 };
 
-unsigned int ExtendedCPDO(const unsigned int opcode, FPREG * rFd)
+unsigned int ExtendedCPDO(struct roundingData *roundData, const unsigned int opcode, FPREG * rFd)
 {
 	FPA11 *fpa11 = GET_FPA11();
 	floatx80 rFm;
@@ -138,13 +138,13 @@ unsigned int ExtendedCPDO(const unsigned
 		}
 
 		if (dyadic_extended[opc_mask_shift]) {
-			rFd->fExtended = dyadic_extended[opc_mask_shift](rFn, rFm);
+			rFd->fExtended = dyadic_extended[opc_mask_shift](roundData, rFn, rFm);
 		} else {
 			return 0;
 		}
 	} else {
 		if (monadic_extended[opc_mask_shift]) {
-			rFd->fExtended = monadic_extended[opc_mask_shift](rFm);
+			rFd->fExtended = monadic_extended[opc_mask_shift](roundData, rFm);
 		} else {
 			return 0;
 		}
diff --git a/arch/arm/nwfpe/fpa11.c b/arch/arm/nwfpe/fpa11.c
--- a/arch/arm/nwfpe/fpa11.c
+++ b/arch/arm/nwfpe/fpa11.c
@@ -51,48 +51,42 @@ static void resetFPA11(void)
 	fpa11->fpsr = FP_EMULATOR | BIT_AC;
 }
 
-void SetRoundingMode(const unsigned int opcode)
+int8 SetRoundingMode(const unsigned int opcode)
 {
 	switch (opcode & MASK_ROUNDING_MODE) {
 	default:
 	case ROUND_TO_NEAREST:
-		float_rounding_mode = float_round_nearest_even;
-		break;
+		return float_round_nearest_even;
 
 	case ROUND_TO_PLUS_INFINITY:
-		float_rounding_mode = float_round_up;
-		break;
+		return float_round_up;
 
 	case ROUND_TO_MINUS_INFINITY:
-		float_rounding_mode = float_round_down;
-		break;
+		return float_round_down;
 
 	case ROUND_TO_ZERO:
-		float_rounding_mode = float_round_to_zero;
-		break;
+		return float_round_to_zero;
 	}
 }
 
-void SetRoundingPrecision(const unsigned int opcode)
+int8 SetRoundingPrecision(const unsigned int opcode)
 {
 #ifdef CONFIG_FPE_NWFPE_XP
 	switch (opcode & MASK_ROUNDING_PRECISION) {
 	case ROUND_SINGLE:
-		floatx80_rounding_precision = 32;
-		break;
+		return 32;
 
 	case ROUND_DOUBLE:
-		floatx80_rounding_precision = 64;
-		break;
+		return 64;
 
 	case ROUND_EXTENDED:
-		floatx80_rounding_precision = 80;
-		break;
+		return 80;
 
 	default:
-		floatx80_rounding_precision = 80;
+		return 80;
 	}
 #endif
+	return 80;
 }
 
 void nwfpe_init_fpa(union fp_state *fp)
@@ -103,8 +97,6 @@ void nwfpe_init_fpa(union fp_state *fp)
 #endif
  	memset(fpa11, 0, sizeof(FPA11));
 	resetFPA11();
-	SetRoundingMode(ROUND_TO_NEAREST);
-	SetRoundingPrecision(ROUND_EXTENDED);
 	fpa11->initflag = 1;
 }
 
diff --git a/arch/arm/nwfpe/fpa11.h b/arch/arm/nwfpe/fpa11.h
--- a/arch/arm/nwfpe/fpa11.h
+++ b/arch/arm/nwfpe/fpa11.h
@@ -29,9 +29,7 @@
  * stack+task struct.  Use the same method as 'current' uses to
  * reach them.
  */
-register unsigned long *user_registers asm("sl");
-
-#define GET_USERREG() (user_registers)
+#define GET_USERREG() ((struct pt_regs *)(THREAD_START_SP + (unsigned long)current_thread_info()) - 1)
 
 #include <linux/config.h>
 #include <linux/thread_info.h>
@@ -39,6 +37,13 @@ register unsigned long *user_registers a
 /* includes */
 #include "fpsr.h"		/* FP control and status register definitions */
 #include "milieu.h"
+
+struct roundingData {
+    int8 mode;
+    int8 precision;
+    signed char exception;
+};
+
 #include "softfloat.h"
 
 #define		typeNone		0x00
@@ -86,8 +91,8 @@ typedef struct tagFPA11 {
 				   initialised. */
 } FPA11;
 
-extern void SetRoundingMode(const unsigned int);
-extern void SetRoundingPrecision(const unsigned int);
+extern int8 SetRoundingMode(const unsigned int);
+extern int8 SetRoundingPrecision(const unsigned int);
 extern void nwfpe_init_fpa(union fp_state *fp);
 
 #endif
diff --git a/arch/arm/nwfpe/fpa11_cpdo.c b/arch/arm/nwfpe/fpa11_cpdo.c
--- a/arch/arm/nwfpe/fpa11_cpdo.c
+++ b/arch/arm/nwfpe/fpa11_cpdo.c
@@ -24,15 +24,16 @@
 #include "fpa11.h"
 #include "fpopcode.h"
 
-unsigned int SingleCPDO(const unsigned int opcode, FPREG * rFd);
-unsigned int DoubleCPDO(const unsigned int opcode, FPREG * rFd);
-unsigned int ExtendedCPDO(const unsigned int opcode, FPREG * rFd);
+unsigned int SingleCPDO(struct roundingData *roundData, const unsigned int opcode, FPREG * rFd);
+unsigned int DoubleCPDO(struct roundingData *roundData, const unsigned int opcode, FPREG * rFd);
+unsigned int ExtendedCPDO(struct roundingData *roundData, const unsigned int opcode, FPREG * rFd);
 
 unsigned int EmulateCPDO(const unsigned int opcode)
 {
 	FPA11 *fpa11 = GET_FPA11();
 	FPREG *rFd;
 	unsigned int nType, nDest, nRc;
+	struct roundingData roundData;
 
 	/* Get the destination size.  If not valid let Linux perform
 	   an invalid instruction trap. */
@@ -40,7 +41,9 @@ unsigned int EmulateCPDO(const unsigned 
 	if (typeNone == nDest)
 		return 0;
 
-	SetRoundingMode(opcode);
+	roundData.mode = SetRoundingMode(opcode);
+	roundData.precision = SetRoundingPrecision(opcode);
+	roundData.exception = 0;
 
 	/* Compare the size of the operands in Fn and Fm.
 	   Choose the largest size and perform operations in that size,
@@ -63,14 +66,14 @@ unsigned int EmulateCPDO(const unsigned 
 
 	switch (nType) {
 	case typeSingle:
-		nRc = SingleCPDO(opcode, rFd);
+		nRc = SingleCPDO(&roundData, opcode, rFd);
 		break;
 	case typeDouble:
-		nRc = DoubleCPDO(opcode, rFd);
+		nRc = DoubleCPDO(&roundData, opcode, rFd);
 		break;
 #ifdef CONFIG_FPE_NWFPE_XP
 	case typeExtended:
-		nRc = ExtendedCPDO(opcode, rFd);
+		nRc = ExtendedCPDO(&roundData, opcode, rFd);
 		break;
 #endif
 	default:
@@ -93,9 +96,9 @@ unsigned int EmulateCPDO(const unsigned 
 			case typeSingle:
 				{
 					if (typeDouble == nType)
-						rFd->fSingle = float64_to_float32(rFd->fDouble);
+						rFd->fSingle = float64_to_float32(&roundData, rFd->fDouble);
 					else
-						rFd->fSingle = floatx80_to_float32(rFd->fExtended);
+						rFd->fSingle = floatx80_to_float32(&roundData, rFd->fExtended);
 				}
 				break;
 
@@ -104,7 +107,7 @@ unsigned int EmulateCPDO(const unsigned 
 					if (typeSingle == nType)
 						rFd->fDouble = float32_to_float64(rFd->fSingle);
 					else
-						rFd->fDouble = floatx80_to_float64(rFd->fExtended);
+						rFd->fDouble = floatx80_to_float64(&roundData, rFd->fExtended);
 				}
 				break;
 
@@ -121,12 +124,15 @@ unsigned int EmulateCPDO(const unsigned 
 #else
 		if (nDest != nType) {
 			if (nDest == typeSingle)
-				rFd->fSingle = float64_to_float32(rFd->fDouble);
+				rFd->fSingle = float64_to_float32(&roundData, rFd->fDouble);
 			else
 				rFd->fDouble = float32_to_float64(rFd->fSingle);
 		}
 #endif
 	}
 
+	if (roundData.exception)
+		float_raise(roundData.exception);
+
 	return nRc;
 }
diff --git a/arch/arm/nwfpe/fpa11_cpdt.c b/arch/arm/nwfpe/fpa11_cpdt.c
--- a/arch/arm/nwfpe/fpa11_cpdt.c
+++ b/arch/arm/nwfpe/fpa11_cpdt.c
@@ -96,7 +96,7 @@ static inline void loadMultiple(const un
 	}
 }
 
-static inline void storeSingle(const unsigned int Fn, unsigned int __user *pMem)
+static inline void storeSingle(struct roundingData *roundData, const unsigned int Fn, unsigned int __user *pMem)
 {
 	FPA11 *fpa11 = GET_FPA11();
 	union {
@@ -106,12 +106,12 @@ static inline void storeSingle(const uns
 
 	switch (fpa11->fType[Fn]) {
 	case typeDouble:
-		val.f = float64_to_float32(fpa11->fpreg[Fn].fDouble);
+		val.f = float64_to_float32(roundData, fpa11->fpreg[Fn].fDouble);
 		break;
 
 #ifdef CONFIG_FPE_NWFPE_XP
 	case typeExtended:
-		val.f = floatx80_to_float32(fpa11->fpreg[Fn].fExtended);
+		val.f = floatx80_to_float32(roundData, fpa11->fpreg[Fn].fExtended);
 		break;
 #endif
 
@@ -122,7 +122,7 @@ static inline void storeSingle(const uns
 	put_user(val.i[0], pMem);
 }
 
-static inline void storeDouble(const unsigned int Fn, unsigned int __user *pMem)
+static inline void storeDouble(struct roundingData *roundData, const unsigned int Fn, unsigned int __user *pMem)
 {
 	FPA11 *fpa11 = GET_FPA11();
 	union {
@@ -137,7 +137,7 @@ static inline void storeDouble(const uns
 
 #ifdef CONFIG_FPE_NWFPE_XP
 	case typeExtended:
-		val.f = floatx80_to_float64(fpa11->fpreg[Fn].fExtended);
+		val.f = floatx80_to_float64(roundData, fpa11->fpreg[Fn].fExtended);
 		break;
 #endif
 
@@ -259,8 +259,11 @@ unsigned int PerformSTF(const unsigned i
 {
 	unsigned int __user *pBase, *pAddress, *pFinal;
 	unsigned int nRc = 1, write_back = WRITE_BACK(opcode);
+	struct roundingData roundData;
 
-	SetRoundingMode(ROUND_TO_NEAREST);
+	roundData.mode = SetRoundingMode(opcode);
+	roundData.precision = SetRoundingPrecision(opcode);
+	roundData.exception = 0;
 
 	pBase = (unsigned int __user *) readRegister(getRn(opcode));
 	if (REG_PC == getRn(opcode)) {
@@ -281,10 +284,10 @@ unsigned int PerformSTF(const unsigned i
 
 	switch (opcode & MASK_TRANSFER_LENGTH) {
 	case TRANSFER_SINGLE:
-		storeSingle(getFd(opcode), pAddress);
+		storeSingle(&roundData, getFd(opcode), pAddress);
 		break;
 	case TRANSFER_DOUBLE:
-		storeDouble(getFd(opcode), pAddress);
+		storeDouble(&roundData, getFd(opcode), pAddress);
 		break;
 #ifdef CONFIG_FPE_NWFPE_XP
 	case TRANSFER_EXTENDED:
@@ -295,6 +298,9 @@ unsigned int PerformSTF(const unsigned i
 		nRc = 0;
 	}
 
+	if (roundData.exception)
+		float_raise(roundData.exception);
+
 	if (write_back)
 		writeRegister(getRn(opcode), (unsigned long) pFinal);
 	return nRc;
diff --git a/arch/arm/nwfpe/fpa11_cprt.c b/arch/arm/nwfpe/fpa11_cprt.c
--- a/arch/arm/nwfpe/fpa11_cprt.c
+++ b/arch/arm/nwfpe/fpa11_cprt.c
@@ -33,8 +33,6 @@ extern flag floatx80_is_nan(floatx80);
 extern flag float64_is_nan(float64);
 extern flag float32_is_nan(float32);
 
-void SetRoundingMode(const unsigned int opcode);
-
 unsigned int PerformFLT(const unsigned int opcode);
 unsigned int PerformFIX(const unsigned int opcode);
 
@@ -77,14 +75,17 @@ unsigned int EmulateCPRT(const unsigned 
 unsigned int PerformFLT(const unsigned int opcode)
 {
 	FPA11 *fpa11 = GET_FPA11();
-	SetRoundingMode(opcode);
-	SetRoundingPrecision(opcode);
+	struct roundingData roundData;
+
+	roundData.mode = SetRoundingMode(opcode);
+	roundData.precision = SetRoundingPrecision(opcode);
+	roundData.exception = 0;
 
 	switch (opcode & MASK_ROUNDING_PRECISION) {
 	case ROUND_SINGLE:
 		{
 			fpa11->fType[getFn(opcode)] = typeSingle;
-			fpa11->fpreg[getFn(opcode)].fSingle = int32_to_float32(readRegister(getRd(opcode)));
+			fpa11->fpreg[getFn(opcode)].fSingle = int32_to_float32(&roundData, readRegister(getRd(opcode)));
 		}
 		break;
 
@@ -108,6 +109,9 @@ unsigned int PerformFLT(const unsigned i
 		return 0;
 	}
 
+	if (roundData.exception)
+		float_raise(roundData.exception);
+
 	return 1;
 }
 
@@ -115,26 +119,29 @@ unsigned int PerformFIX(const unsigned i
 {
 	FPA11 *fpa11 = GET_FPA11();
 	unsigned int Fn = getFm(opcode);
+	struct roundingData roundData;
 
-	SetRoundingMode(opcode);
+	roundData.mode = SetRoundingMode(opcode);
+	roundData.precision = SetRoundingPrecision(opcode);
+	roundData.exception = 0;
 
 	switch (fpa11->fType[Fn]) {
 	case typeSingle:
 		{
-			writeRegister(getRd(opcode), float32_to_int32(fpa11->fpreg[Fn].fSingle));
+			writeRegister(getRd(opcode), float32_to_int32(&roundData, fpa11->fpreg[Fn].fSingle));
 		}
 		break;
 
 	case typeDouble:
 		{
-			writeRegister(getRd(opcode), float64_to_int32(fpa11->fpreg[Fn].fDouble));
+			writeRegister(getRd(opcode), float64_to_int32(&roundData, fpa11->fpreg[Fn].fDouble));
 		}
 		break;
 
 #ifdef CONFIG_FPE_NWFPE_XP
 	case typeExtended:
 		{
-			writeRegister(getRd(opcode), floatx80_to_int32(fpa11->fpreg[Fn].fExtended));
+			writeRegister(getRd(opcode), floatx80_to_int32(&roundData, fpa11->fpreg[Fn].fExtended));
 		}
 		break;
 #endif
@@ -143,6 +150,9 @@ unsigned int PerformFIX(const unsigned i
 		return 0;
 	}
 
+	if (roundData.exception)
+		float_raise(roundData.exception);
+
 	return 1;
 }
 
diff --git a/arch/arm/nwfpe/fpmodule.c b/arch/arm/nwfpe/fpmodule.c
--- a/arch/arm/nwfpe/fpmodule.c
+++ b/arch/arm/nwfpe/fpmodule.c
@@ -24,7 +24,6 @@
 #include "fpa11.h"
 
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/config.h>
 
 /* XXX */
@@ -117,8 +116,6 @@ fpmodule.c to integrate with the NetBSD 
 code to access data in user space in some other source files at the 
 moment (grep for get_user / put_user calls).  --philb]
 
-float_exception_flags is a global variable in SoftFloat.
-
 This function is called by the SoftFloat routines to raise a floating
 point exception.  We check the trap enable byte in the FPSR, and raise
 a SIGFPE exception if necessary.  If not the relevant bits in the 
@@ -130,15 +127,14 @@ void float_raise(signed char flags)
 	register unsigned int fpsr, cumulativeTraps;
 
 #ifdef CONFIG_DEBUG_USER
-	printk(KERN_DEBUG
-	       "NWFPE: %s[%d] takes exception %08x at %p from %08lx\n",
-	       current->comm, current->pid, flags,
-	       __builtin_return_address(0), GET_USERREG()[15]);
+ 	/* Ignore inexact errors as there are far too many of them to log */
+ 	if (flags & ~BIT_IXC)
+ 		printk(KERN_DEBUG
+		       "NWFPE: %s[%d] takes exception %08x at %p from %08lx\n",
+		       current->comm, current->pid, flags,
+		       __builtin_return_address(0), GET_USERREG()->ARM_pc);
 #endif
 
-	/* Keep SoftFloat exception flags up to date.  */
-	float_exception_flags |= flags;
-
 	/* Read fpsr and initialize the cumulativeTraps.  */
 	fpsr = readFPSR();
 	cumulativeTraps = 0;
diff --git a/arch/arm/nwfpe/fpmodule.inl b/arch/arm/nwfpe/fpmodule.inl
--- a/arch/arm/nwfpe/fpmodule.inl
+++ b/arch/arm/nwfpe/fpmodule.inl
@@ -28,8 +28,8 @@ static inline unsigned long readRegister
 	   for this in this routine.  LDF/STF instructions with Rn = PC
 	   depend on the PC being correct, as they use PC+8 in their
 	   address calculations. */
-	unsigned long *userRegisters = GET_USERREG();
-	unsigned int val = userRegisters[nReg];
+	struct pt_regs *regs = GET_USERREG();
+	unsigned int val = regs->uregs[nReg];
 	if (REG_PC == nReg)
 		val -= 4;
 	return val;
@@ -38,8 +38,8 @@ static inline unsigned long readRegister
 static inline void
 writeRegister(const unsigned int nReg, const unsigned long val)
 {
-	unsigned long *userRegisters = GET_USERREG();
-	userRegisters[nReg] = val;
+	struct pt_regs *regs = GET_USERREG();
+	regs->uregs[nReg] = val;
 }
 
 static inline unsigned long readCPSR(void)
@@ -63,12 +63,12 @@ static inline unsigned long readConditio
 
 static inline void writeConditionCodes(const unsigned long val)
 {
-	unsigned long *userRegisters = GET_USERREG();
+	struct pt_regs *regs = GET_USERREG();
 	unsigned long rval;
 	/*
 	 * Operate directly on userRegisters since
 	 * the CPSR may be the PC register itself.
 	 */
-	rval = userRegisters[REG_CPSR] & ~CC_MASK;
-	userRegisters[REG_CPSR] = rval | (val & CC_MASK);
+	rval = regs->ARM_cpsr & ~CC_MASK;
+	regs->ARM_cpsr = rval | (val & CC_MASK);
 }
diff --git a/arch/arm/nwfpe/fpopcode.h b/arch/arm/nwfpe/fpopcode.h
--- a/arch/arm/nwfpe/fpopcode.h
+++ b/arch/arm/nwfpe/fpopcode.h
@@ -370,20 +370,20 @@ TABLE 5
 #define getRoundingMode(opcode)		((opcode & MASK_ROUNDING_MODE) >> 5)
 
 #ifdef CONFIG_FPE_NWFPE_XP
-static inline const floatx80 getExtendedConstant(const unsigned int nIndex)
+static inline __attribute_pure__ floatx80 getExtendedConstant(const unsigned int nIndex)
 {
 	extern const floatx80 floatx80Constant[];
 	return floatx80Constant[nIndex];
 }
 #endif
 
-static inline const float64 getDoubleConstant(const unsigned int nIndex)
+static inline __attribute_pure__ float64 getDoubleConstant(const unsigned int nIndex)
 {
 	extern const float64 float64Constant[];
 	return float64Constant[nIndex];
 }
 
-static inline const float32 getSingleConstant(const unsigned int nIndex)
+static inline __attribute_pure__ float32 getSingleConstant(const unsigned int nIndex)
 {
 	extern const float32 float32Constant[];
 	return float32Constant[nIndex];
diff --git a/arch/arm/nwfpe/single_cpdo.c b/arch/arm/nwfpe/single_cpdo.c
--- a/arch/arm/nwfpe/single_cpdo.c
+++ b/arch/arm/nwfpe/single_cpdo.c
@@ -36,17 +36,17 @@ float32 float32_arccos(float32 rFm);
 float32 float32_pow(float32 rFn, float32 rFm);
 float32 float32_pol(float32 rFn, float32 rFm);
 
-static float32 float32_rsf(float32 rFn, float32 rFm)
+static float32 float32_rsf(struct roundingData *roundData, float32 rFn, float32 rFm)
 {
-	return float32_sub(rFm, rFn);
+	return float32_sub(roundData, rFm, rFn);
 }
 
-static float32 float32_rdv(float32 rFn, float32 rFm)
+static float32 float32_rdv(struct roundingData *roundData, float32 rFn, float32 rFm)
 {
-	return float32_div(rFm, rFn);
+	return float32_div(roundData, rFm, rFn);
 }
 
-static float32 (*const dyadic_single[16])(float32 rFn, float32 rFm) = {
+static float32 (*const dyadic_single[16])(struct roundingData *, float32 rFn, float32 rFm) = {
 	[ADF_CODE >> 20] = float32_add,
 	[MUF_CODE >> 20] = float32_mul,
 	[SUF_CODE >> 20] = float32_sub,
@@ -60,22 +60,22 @@ static float32 (*const dyadic_single[16]
 	[FRD_CODE >> 20] = float32_rdv,
 };
 
-static float32 float32_mvf(float32 rFm)
+static float32 float32_mvf(struct roundingData *roundData, float32 rFm)
 {
 	return rFm;
 }
 
-static float32 float32_mnf(float32 rFm)
+static float32 float32_mnf(struct roundingData *roundData, float32 rFm)
 {
 	return rFm ^ 0x80000000;
 }
 
-static float32 float32_abs(float32 rFm)
+static float32 float32_abs(struct roundingData *roundData, float32 rFm)
 {
 	return rFm & 0x7fffffff;
 }
 
-static float32 (*const monadic_single[16])(float32 rFm) = {
+static float32 (*const monadic_single[16])(struct roundingData*, float32 rFm) = {
 	[MVF_CODE >> 20] = float32_mvf,
 	[MNF_CODE >> 20] = float32_mnf,
 	[ABS_CODE >> 20] = float32_abs,
@@ -85,7 +85,7 @@ static float32 (*const monadic_single[16
 	[NRM_CODE >> 20] = float32_mvf,
 };
 
-unsigned int SingleCPDO(const unsigned int opcode, FPREG * rFd)
+unsigned int SingleCPDO(struct roundingData *roundData, const unsigned int opcode, FPREG * rFd)
 {
 	FPA11 *fpa11 = GET_FPA11();
 	float32 rFm;
@@ -108,13 +108,13 @@ unsigned int SingleCPDO(const unsigned i
 		if (fpa11->fType[Fn] == typeSingle &&
 		    dyadic_single[opc_mask_shift]) {
 			rFn = fpa11->fpreg[Fn].fSingle;
-			rFd->fSingle = dyadic_single[opc_mask_shift](rFn, rFm);
+			rFd->fSingle = dyadic_single[opc_mask_shift](roundData, rFn, rFm);
 		} else {
 			return 0;
 		}
 	} else {
 		if (monadic_single[opc_mask_shift]) {
-			rFd->fSingle = monadic_single[opc_mask_shift](rFm);
+			rFd->fSingle = monadic_single[opc_mask_shift](roundData, rFm);
 		} else {
 			return 0;
 		}
diff --git a/arch/arm/nwfpe/softfloat-macros b/arch/arm/nwfpe/softfloat-macros
--- a/arch/arm/nwfpe/softfloat-macros
+++ b/arch/arm/nwfpe/softfloat-macros
@@ -563,8 +563,14 @@ static bits64 estimateDiv128To64( bits64
     bits64 rem0, rem1, term0, term1;
     bits64 z;
     if ( b <= a0 ) return LIT64( 0xFFFFFFFFFFFFFFFF );
-    b0 = b>>32;
-    z = ( b0<<32 <= a0 ) ? LIT64( 0xFFFFFFFF00000000 ) : ( a0 / b0 )<<32;
+    b0 = b>>32;  /* hence b0 is 32 bits wide now */
+    if ( b0<<32 <= a0 ) {
+        z = LIT64( 0xFFFFFFFF00000000 );
+    }  else {
+        z = a0;
+        do_div( z, b0 );
+        z <<= 32;
+    }
     mul64To128( b, z, &term0, &term1 );
     sub128( a0, a1, term0, term1, &rem0, &rem1 );
     while ( ( (sbits64) rem0 ) < 0 ) {
@@ -573,7 +579,12 @@ static bits64 estimateDiv128To64( bits64
         add128( rem0, rem1, b0, b1, &rem0, &rem1 );
     }
     rem0 = ( rem0<<32 ) | ( rem1>>32 );
-    z |= ( b0<<32 <= rem0 ) ? 0xFFFFFFFF : rem0 / b0;
+    if ( b0<<32 <= rem0 ) {
+        z |= 0xFFFFFFFF;
+    } else {
+        do_div( rem0, b0 );
+        z |= rem0;
+    }
     return z;
 
 }
@@ -601,6 +612,7 @@ static bits32 estimateSqrt32( int16 aExp
     };
     int8 index;
     bits32 z;
+    bits64 A;
 
     index = ( a>>27 ) & 15;
     if ( aExp & 1 ) {
@@ -614,7 +626,9 @@ static bits32 estimateSqrt32( int16 aExp
         z = ( 0x20000 <= z ) ? 0xFFFF8000 : ( z<<15 );
         if ( z <= a ) return (bits32) ( ( (sbits32) a )>>1 );
     }
-    return ( (bits32) ( ( ( (bits64) a )<<31 ) / z ) ) + ( z>>1 );
+    A = ( (bits64) a )<<31;
+    do_div( A, z );
+    return ( (bits32) A ) + ( z>>1 );
 
 }
 
diff --git a/arch/arm/nwfpe/softfloat.c b/arch/arm/nwfpe/softfloat.c
--- a/arch/arm/nwfpe/softfloat.c
+++ b/arch/arm/nwfpe/softfloat.c
@@ -28,22 +28,14 @@ this code that are retained.
 ===============================================================================
 */
 
+#include <asm/div64.h>
+
 #include "fpa11.h"
 //#include "milieu.h"
 //#include "softfloat.h"
 
 /*
 -------------------------------------------------------------------------------
-Floating-point rounding mode, extended double-precision rounding precision,
-and exception flags.
--------------------------------------------------------------------------------
-*/
-int8 float_rounding_mode = float_round_nearest_even;
-int8 floatx80_rounding_precision = 80;
-int8 float_exception_flags;
-
-/*
--------------------------------------------------------------------------------
 Primitive arithmetic functions, including multi-word arithmetic, and
 division and square root approximations.  (Can be specialized to target if
 desired.)
@@ -75,14 +67,14 @@ input is too large, however, the invalid
 positive or negative integer is returned.
 -------------------------------------------------------------------------------
 */
-static int32 roundAndPackInt32( flag zSign, bits64 absZ )
+static int32 roundAndPackInt32( struct roundingData *roundData, flag zSign, bits64 absZ )
 {
     int8 roundingMode;
     flag roundNearestEven;
     int8 roundIncrement, roundBits;
     int32 z;
 
-    roundingMode = float_rounding_mode;
+    roundingMode = roundData->mode;
     roundNearestEven = ( roundingMode == float_round_nearest_even );
     roundIncrement = 0x40;
     if ( ! roundNearestEven ) {
@@ -105,10 +97,10 @@ static int32 roundAndPackInt32( flag zSi
     z = absZ;
     if ( zSign ) z = - z;
     if ( ( absZ>>32 ) || ( z && ( ( z < 0 ) ^ zSign ) ) ) {
-        float_exception_flags |= float_flag_invalid;
+        roundData->exception |= float_flag_invalid;
         return zSign ? 0x80000000 : 0x7FFFFFFF;
     }
-    if ( roundBits ) float_exception_flags |= float_flag_inexact;
+    if ( roundBits ) roundData->exception |= float_flag_inexact;
     return z;
 
 }
@@ -222,14 +214,14 @@ The handling of underflow and overflow f
 Binary Floating-point Arithmetic.
 -------------------------------------------------------------------------------
 */
-static float32 roundAndPackFloat32( flag zSign, int16 zExp, bits32 zSig )
+static float32 roundAndPackFloat32( struct roundingData *roundData, flag zSign, int16 zExp, bits32 zSig )
 {
     int8 roundingMode;
     flag roundNearestEven;
     int8 roundIncrement, roundBits;
     flag isTiny;
 
-    roundingMode = float_rounding_mode;
+    roundingMode = roundData->mode;
     roundNearestEven = ( roundingMode == float_round_nearest_even );
     roundIncrement = 0x40;
     if ( ! roundNearestEven ) {
@@ -252,7 +244,7 @@ static float32 roundAndPackFloat32( flag
              || (    ( zExp == 0xFD )
                   && ( (sbits32) ( zSig + roundIncrement ) < 0 ) )
            ) {
-            float_raise( float_flag_overflow | float_flag_inexact );
+            roundData->exception |= float_flag_overflow | float_flag_inexact;
             return packFloat32( zSign, 0xFF, 0 ) - ( roundIncrement == 0 );
         }
         if ( zExp < 0 ) {
@@ -263,10 +255,10 @@ static float32 roundAndPackFloat32( flag
             shift32RightJamming( zSig, - zExp, &zSig );
             zExp = 0;
             roundBits = zSig & 0x7F;
-            if ( isTiny && roundBits ) float_raise( float_flag_underflow );
+            if ( isTiny && roundBits ) roundData->exception |= float_flag_underflow;
         }
     }
-    if ( roundBits ) float_exception_flags |= float_flag_inexact;
+    if ( roundBits ) roundData->exception |= float_flag_inexact;
     zSig = ( zSig + roundIncrement )>>7;
     zSig &= ~ ( ( ( roundBits ^ 0x40 ) == 0 ) & roundNearestEven );
     if ( zSig == 0 ) zExp = 0;
@@ -285,12 +277,12 @@ point exponent.
 -------------------------------------------------------------------------------
 */
 static float32
- normalizeRoundAndPackFloat32( flag zSign, int16 zExp, bits32 zSig )
+ normalizeRoundAndPackFloat32( struct roundingData *roundData, flag zSign, int16 zExp, bits32 zSig )
 {
     int8 shiftCount;
 
     shiftCount = countLeadingZeros32( zSig ) - 1;
-    return roundAndPackFloat32( zSign, zExp - shiftCount, zSig<<shiftCount );
+    return roundAndPackFloat32( roundData, zSign, zExp - shiftCount, zSig<<shiftCount );
 
 }
 
@@ -393,14 +385,14 @@ The handling of underflow and overflow f
 Binary Floating-point Arithmetic.
 -------------------------------------------------------------------------------
 */
-static float64 roundAndPackFloat64( flag zSign, int16 zExp, bits64 zSig )
+static float64 roundAndPackFloat64( struct roundingData *roundData, flag zSign, int16 zExp, bits64 zSig )
 {
     int8 roundingMode;
     flag roundNearestEven;
     int16 roundIncrement, roundBits;
     flag isTiny;
 
-    roundingMode = float_rounding_mode;
+    roundingMode = roundData->mode;
     roundNearestEven = ( roundingMode == float_round_nearest_even );
     roundIncrement = 0x200;
     if ( ! roundNearestEven ) {
@@ -425,7 +417,7 @@ static float64 roundAndPackFloat64( flag
            ) {
             //register int lr = __builtin_return_address(0);
             //printk("roundAndPackFloat64 called from 0x%08x\n",lr);
-            float_raise( float_flag_overflow | float_flag_inexact );
+            roundData->exception |= float_flag_overflow | float_flag_inexact;
             return packFloat64( zSign, 0x7FF, 0 ) - ( roundIncrement == 0 );
         }
         if ( zExp < 0 ) {
@@ -436,10 +428,10 @@ static float64 roundAndPackFloat64( flag
             shift64RightJamming( zSig, - zExp, &zSig );
             zExp = 0;
             roundBits = zSig & 0x3FF;
-            if ( isTiny && roundBits ) float_raise( float_flag_underflow );
+            if ( isTiny && roundBits ) roundData->exception |= float_flag_underflow;
         }
     }
-    if ( roundBits ) float_exception_flags |= float_flag_inexact;
+    if ( roundBits ) roundData->exception |= float_flag_inexact;
     zSig = ( zSig + roundIncrement )>>10;
     zSig &= ~ ( ( ( roundBits ^ 0x200 ) == 0 ) & roundNearestEven );
     if ( zSig == 0 ) zExp = 0;
@@ -458,12 +450,12 @@ point exponent.
 -------------------------------------------------------------------------------
 */
 static float64
- normalizeRoundAndPackFloat64( flag zSign, int16 zExp, bits64 zSig )
+ normalizeRoundAndPackFloat64( struct roundingData *roundData, flag zSign, int16 zExp, bits64 zSig )
 {
     int8 shiftCount;
 
     shiftCount = countLeadingZeros64( zSig ) - 1;
-    return roundAndPackFloat64( zSign, zExp - shiftCount, zSig<<shiftCount );
+    return roundAndPackFloat64( roundData, zSign, zExp - shiftCount, zSig<<shiftCount );
 
 }
 
@@ -570,14 +562,15 @@ Floating-point Arithmetic.
 */
 static floatx80
  roundAndPackFloatx80(
-     int8 roundingPrecision, flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1
+     struct roundingData *roundData, flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1
  )
 {
-    int8 roundingMode;
+    int8 roundingMode, roundingPrecision;
     flag roundNearestEven, increment, isTiny;
     int64 roundIncrement, roundMask, roundBits;
 
-    roundingMode = float_rounding_mode;
+    roundingMode = roundData->mode;
+    roundingPrecision = roundData->precision;
     roundNearestEven = ( roundingMode == float_round_nearest_even );
     if ( roundingPrecision == 80 ) goto precision80;
     if ( roundingPrecision == 64 ) {
@@ -621,8 +614,8 @@ static floatx80
             shift64RightJamming( zSig0, 1 - zExp, &zSig0 );
             zExp = 0;
             roundBits = zSig0 & roundMask;
-            if ( isTiny && roundBits ) float_raise( float_flag_underflow );
-            if ( roundBits ) float_exception_flags |= float_flag_inexact;
+            if ( isTiny && roundBits ) roundData->exception |= float_flag_underflow;
+            if ( roundBits ) roundData->exception |= float_flag_inexact;
             zSig0 += roundIncrement;
             if ( (sbits64) zSig0 < 0 ) zExp = 1;
             roundIncrement = roundMask + 1;
@@ -633,7 +626,7 @@ static floatx80
             return packFloatx80( zSign, zExp, zSig0 );
         }
     }
-    if ( roundBits ) float_exception_flags |= float_flag_inexact;
+    if ( roundBits ) roundData->exception |= float_flag_inexact;
     zSig0 += roundIncrement;
     if ( zSig0 < roundIncrement ) {
         ++zExp;
@@ -670,7 +663,7 @@ static floatx80
            ) {
             roundMask = 0;
  overflow:
-            float_raise( float_flag_overflow | float_flag_inexact );
+            roundData->exception |= float_flag_overflow | float_flag_inexact;
             if (    ( roundingMode == float_round_to_zero )
                  || ( zSign && ( roundingMode == float_round_up ) )
                  || ( ! zSign && ( roundingMode == float_round_down ) )
@@ -687,8 +680,8 @@ static floatx80
                 || ( zSig0 < LIT64( 0xFFFFFFFFFFFFFFFF ) );
             shift64ExtraRightJamming( zSig0, zSig1, 1 - zExp, &zSig0, &zSig1 );
             zExp = 0;
-            if ( isTiny && zSig1 ) float_raise( float_flag_underflow );
-            if ( zSig1 ) float_exception_flags |= float_flag_inexact;
+            if ( isTiny && zSig1 ) roundData->exception |= float_flag_underflow;
+            if ( zSig1 ) roundData->exception |= float_flag_inexact;
             if ( roundNearestEven ) {
                 increment = ( (sbits64) zSig1 < 0 );
             }
@@ -708,7 +701,7 @@ static floatx80
             return packFloatx80( zSign, zExp, zSig0 );
         }
     }
-    if ( zSig1 ) float_exception_flags |= float_flag_inexact;
+    if ( zSig1 ) roundData->exception |= float_flag_inexact;
     if ( increment ) {
         ++zSig0;
         if ( zSig0 == 0 ) {
@@ -738,7 +731,7 @@ normalized.
 */
 static floatx80
  normalizeRoundAndPackFloatx80(
-     int8 roundingPrecision, flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1
+     struct roundingData *roundData, flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1
  )
 {
     int8 shiftCount;
@@ -752,7 +745,7 @@ static floatx80
     shortShift128Left( zSig0, zSig1, shiftCount, &zSig0, &zSig1 );
     zExp -= shiftCount;
     return
-        roundAndPackFloatx80( roundingPrecision, zSign, zExp, zSig0, zSig1 );
+        roundAndPackFloatx80( roundData, zSign, zExp, zSig0, zSig1 );
 
 }
 
@@ -765,14 +758,14 @@ the single-precision floating-point form
 according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
 -------------------------------------------------------------------------------
 */
-float32 int32_to_float32( int32 a )
+float32 int32_to_float32(struct roundingData *roundData, int32 a)
 {
     flag zSign;
 
     if ( a == 0 ) return 0;
     if ( a == 0x80000000 ) return packFloat32( 1, 0x9E, 0 );
     zSign = ( a < 0 );
-    return normalizeRoundAndPackFloat32( zSign, 0x9C, zSign ? - a : a );
+    return normalizeRoundAndPackFloat32( roundData, zSign, 0x9C, zSign ? - a : a );
 
 }
 
@@ -838,7 +831,7 @@ positive integer is returned.  Otherwise
 largest integer with the same sign as `a' is returned.
 -------------------------------------------------------------------------------
 */
-int32 float32_to_int32( float32 a )
+int32 float32_to_int32( struct roundingData *roundData, float32 a )
 {
     flag aSign;
     int16 aExp, shiftCount;
@@ -854,7 +847,7 @@ int32 float32_to_int32( float32 a )
     zSig = aSig;
     zSig <<= 32;
     if ( 0 < shiftCount ) shift64RightJamming( zSig, shiftCount, &zSig );
-    return roundAndPackInt32( aSign, zSig );
+    return roundAndPackInt32( roundData, aSign, zSig );
 
 }
 
@@ -887,13 +880,13 @@ int32 float32_to_int32_round_to_zero( fl
         return 0x80000000;
     }
     else if ( aExp <= 0x7E ) {
-        if ( aExp | aSig ) float_exception_flags |= float_flag_inexact;
+        if ( aExp | aSig ) float_raise( float_flag_inexact );
         return 0;
     }
     aSig = ( aSig | 0x00800000 )<<8;
     z = aSig>>( - shiftCount );
     if ( (bits32) ( aSig<<( shiftCount & 31 ) ) ) {
-        float_exception_flags |= float_flag_inexact;
+        float_raise( float_flag_inexact );
     }
     return aSign ? - z : z;
 
@@ -971,7 +964,7 @@ operation is performed according to the 
 Floating-point Arithmetic.
 -------------------------------------------------------------------------------
 */
-float32 float32_round_to_int( float32 a )
+float32 float32_round_to_int( struct roundingData *roundData, float32 a )
 {
     flag aSign;
     int16 aExp;
@@ -986,11 +979,12 @@ float32 float32_round_to_int( float32 a 
         }
         return a;
     }
+    roundingMode = roundData->mode;
     if ( aExp <= 0x7E ) {
         if ( (bits32) ( a<<1 ) == 0 ) return a;
-        float_exception_flags |= float_flag_inexact;
+        roundData->exception |= float_flag_inexact;
         aSign = extractFloat32Sign( a );
-        switch ( float_rounding_mode ) {
+        switch ( roundingMode ) {
          case float_round_nearest_even:
             if ( ( aExp == 0x7E ) && extractFloat32Frac( a ) ) {
                 return packFloat32( aSign, 0x7F, 0 );
@@ -1007,7 +1001,6 @@ float32 float32_round_to_int( float32 a 
     lastBitMask <<= 0x96 - aExp;
     roundBitsMask = lastBitMask - 1;
     z = a;
-    roundingMode = float_rounding_mode;
     if ( roundingMode == float_round_nearest_even ) {
         z += lastBitMask>>1;
         if ( ( z & roundBitsMask ) == 0 ) z &= ~ lastBitMask;
@@ -1018,7 +1011,7 @@ float32 float32_round_to_int( float32 a 
         }
     }
     z &= ~ roundBitsMask;
-    if ( z != a ) float_exception_flags |= float_flag_inexact;
+    if ( z != a ) roundData->exception |= float_flag_inexact;
     return z;
 
 }
@@ -1032,7 +1025,7 @@ addition is performed according to the I
 Floating-point Arithmetic.
 -------------------------------------------------------------------------------
 */
-static float32 addFloat32Sigs( float32 a, float32 b, flag zSign )
+static float32 addFloat32Sigs( struct roundingData *roundData, float32 a, float32 b, flag zSign )
 {
     int16 aExp, bExp, zExp;
     bits32 aSig, bSig, zSig;
@@ -1091,7 +1084,7 @@ static float32 addFloat32Sigs( float32 a
         ++zExp;
     }
  roundAndPack:
-    return roundAndPackFloat32( zSign, zExp, zSig );
+    return roundAndPackFloat32( roundData, zSign, zExp, zSig );
 
 }
 
@@ -1104,7 +1097,7 @@ result is a NaN.  The subtraction is per
 Standard for Binary Floating-point Arithmetic.
 -------------------------------------------------------------------------------
 */
-static float32 subFloat32Sigs( float32 a, float32 b, flag zSign )
+static float32 subFloat32Sigs( struct roundingData *roundData, float32 a, float32 b, flag zSign )
 {
     int16 aExp, bExp, zExp;
     bits32 aSig, bSig, zSig;
@@ -1121,7 +1114,7 @@ static float32 subFloat32Sigs( float32 a
     if ( expDiff < 0 ) goto bExpBigger;
     if ( aExp == 0xFF ) {
         if ( aSig | bSig ) return propagateFloat32NaN( a, b );
-        float_raise( float_flag_invalid );
+        roundData->exception |= float_flag_invalid;
         return float32_default_nan;
     }
     if ( aExp == 0 ) {
@@ -1130,7 +1123,7 @@ static float32 subFloat32Sigs( float32 a
     }
     if ( bSig < aSig ) goto aBigger;
     if ( aSig < bSig ) goto bBigger;
-    return packFloat32( float_rounding_mode == float_round_down, 0, 0 );
+    return packFloat32( roundData->mode == float_round_down, 0, 0 );
  bExpBigger:
     if ( bExp == 0xFF ) {
         if ( bSig ) return propagateFloat32NaN( a, b );
@@ -1167,7 +1160,7 @@ static float32 subFloat32Sigs( float32 a
     zExp = aExp;
  normalizeRoundAndPack:
     --zExp;
-    return normalizeRoundAndPackFloat32( zSign, zExp, zSig );
+    return normalizeRoundAndPackFloat32( roundData, zSign, zExp, zSig );
 
 }
 
@@ -1178,17 +1171,17 @@ and `b'.  The operation is performed acc
 Binary Floating-point Arithmetic.
 -------------------------------------------------------------------------------
 */
-float32 float32_add( float32 a, float32 b )
+float32 float32_add( struct roundingData *roundData, float32 a, float32 b )
 {
     flag aSign, bSign;
 
     aSign = extractFloat32Sign( a );
     bSign = extractFloat32Sign( b );
     if ( aSign == bSign ) {
-        return addFloat32Sigs( a, b, aSign );
+        return addFloat32Sigs( roundData, a, b, aSign );
     }
     else {
-        return subFloat32Sigs( a, b, aSign );
+        return subFloat32Sigs( roundData, a, b, aSign );
     }
 
 }
@@ -1200,17 +1193,17 @@ Returns the result of subtracting the si
 for Binary Floating-point Arithmetic.
 -------------------------------------------------------------------------------
 */
-float32 float32_sub( float32 a, float32 b )
+float32 float32_sub( struct roundingData *roundData, float32 a, float32 b )
 {
     flag aSign, bSign;
 
     aSign = extractFloat32Sign( a );
     bSign = extractFloat32Sign( b );
     if ( aSign == bSign ) {
-        return subFloat32Sigs( a, b, aSign );
+        return subFloat32Sigs( roundData, a, b, aSign );
     }
     else {
-        return addFloat32Sigs( a, b, aSign );
+        return addFloat32Sigs( roundData, a, b, aSign );
     }
 
 }
@@ -1222,7 +1215,7 @@ Returns the result of multiplying the si
 for Binary Floating-point Arithmetic.
 -------------------------------------------------------------------------------
 */
-float32 float32_mul( float32 a, float32 b )
+float32 float32_mul( struct roundingData *roundData, float32 a, float32 b )
 {
     flag aSign, bSign, zSign;
     int16 aExp, bExp, zExp;
@@ -1242,7 +1235,7 @@ float32 float32_mul( float32 a, float32 
             return propagateFloat32NaN( a, b );
         }
         if ( ( bExp | bSig ) == 0 ) {
-            float_raise( float_flag_invalid );
+            roundData->exception |= float_flag_invalid;
             return float32_default_nan;
         }
         return packFloat32( zSign, 0xFF, 0 );
@@ -1250,7 +1243,7 @@ float32 float32_mul( float32 a, float32 
     if ( bExp == 0xFF ) {
         if ( bSig ) return propagateFloat32NaN( a, b );
         if ( ( aExp | aSig ) == 0 ) {
-            float_raise( float_flag_invalid );
+            roundData->exception |= float_flag_invalid;
             return float32_default_nan;
         }
         return packFloat32( zSign, 0xFF, 0 );
@@ -1272,7 +1265,7 @@ float32 float32_mul( float32 a, float32 
         zSig <<= 1;
         --zExp;
     }
-    return roundAndPackFloat32( zSign, zExp, zSig );
+    return roundAndPackFloat32( roundData, zSign, zExp, zSig );
 
 }
 
@@ -1283,7 +1276,7 @@ by the corresponding value `b'.  The ope
 IEC/IEEE Standard for Binary Floating-point Arithmetic.
 -------------------------------------------------------------------------------
 */
-float32 float32_div( float32 a, float32 b )
+float32 float32_div( struct roundingData *roundData, float32 a, float32 b )
 {
     flag aSign, bSign, zSign;
     int16 aExp, bExp, zExp;
@@ -1300,7 +1293,7 @@ float32 float32_div( float32 a, float32 
         if ( aSig ) return propagateFloat32NaN( a, b );
         if ( bExp == 0xFF ) {
             if ( bSig ) return propagateFloat32NaN( a, b );
-            float_raise( float_flag_invalid );
+            roundData->exception |= float_flag_invalid;
             return float32_default_nan;
         }
         return packFloat32( zSign, 0xFF, 0 );
@@ -1312,10 +1305,10 @@ float32 float32_div( float32 a, float32 
     if ( bExp == 0 ) {
         if ( bSig == 0 ) {
             if ( ( aExp | aSig ) == 0 ) {
-                float_raise( float_flag_invalid );
+                roundData->exception |= float_flag_invalid;
                 return float32_default_nan;
             }
-            float_raise( float_flag_divbyzero );
+            roundData->exception |= float_flag_divbyzero;
             return packFloat32( zSign, 0xFF, 0 );
         }
         normalizeFloat32Subnormal( bSig, &bExp, &bSig );
@@ -1331,11 +1324,15 @@ float32 float32_div( float32 a, float32 
         aSig >>= 1;
         ++zExp;
     }
-    zSig = ( ( (bits64) aSig )<<32 ) / bSig;
+    {
+        bits64 tmp = ( (bits64) aSig )<<32;
+        do_div( tmp, bSig );
+        zSig = tmp;
+    }
     if ( ( zSig & 0x3F ) == 0 ) {
         zSig |= ( ( (bits64) bSig ) * zSig != ( (bits64) aSig )<<32 );
     }
-    return roundAndPackFloat32( zSign, zExp, zSig );
+    return roundAndPackFloat32( roundData, zSign, zExp, zSig );
 
 }
 
@@ -1346,7 +1343,7 @@ with respect to the corresponding value 
 according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
 -------------------------------------------------------------------------------
 */
-float32 float32_rem( float32 a, float32 b )
+float32 float32_rem( struct roundingData *roundData, float32 a, float32 b )
 {
     flag aSign, bSign, zSign;
     int16 aExp, bExp, expDiff;
@@ -1366,7 +1363,7 @@ float32 float32_rem( float32 a, float32 
         if ( aSig || ( ( bExp == 0xFF ) && bSig ) ) {
             return propagateFloat32NaN( a, b );
         }
-        float_raise( float_flag_invalid );
+        roundData->exception |= float_flag_invalid;
         return float32_default_nan;
     }
     if ( bExp == 0xFF ) {
@@ -1375,7 +1372,7 @@ float32 float32_rem( float32 a, float32 
     }
     if ( bExp == 0 ) {
         if ( bSig == 0 ) {
-            float_raise( float_flag_invalid );
+            roundData->exception |= float_flag_invalid;
             return float32_default_nan;
         }
         normalizeFloat32Subnormal( bSig, &bExp, &bSig );
@@ -1397,7 +1394,9 @@ float32 float32_rem( float32 a, float32 
         q = ( bSig <= aSig );
         if ( q ) aSig -= bSig;
         if ( 0 < expDiff ) {
-            q = ( ( (bits64) aSig )<<32 ) / bSig;
+            bits64 tmp = ( (bits64) aSig )<<32;
+            do_div( tmp, bSig );
+            q = tmp;
             q >>= 32 - expDiff;
             bSig >>= 2;
             aSig = ( ( aSig>>1 )<<( expDiff - 1 ) ) - bSig * q;
@@ -1436,7 +1435,7 @@ float32 float32_rem( float32 a, float32 
     }
     zSign = ( (sbits32) aSig < 0 );
     if ( zSign ) aSig = - aSig;
-    return normalizeRoundAndPackFloat32( aSign ^ zSign, bExp, aSig );
+    return normalizeRoundAndPackFloat32( roundData, aSign ^ zSign, bExp, aSig );
 
 }
 
@@ -1447,7 +1446,7 @@ The operation is performed according to 
 Floating-point Arithmetic.
 -------------------------------------------------------------------------------
 */
-float32 float32_sqrt( float32 a )
+float32 float32_sqrt( struct roundingData *roundData, float32 a )
 {
     flag aSign;
     int16 aExp, zExp;
@@ -1460,12 +1459,12 @@ float32 float32_sqrt( float32 a )
     if ( aExp == 0xFF ) {
         if ( aSig ) return propagateFloat32NaN( a, 0 );
         if ( ! aSign ) return a;
-        float_raise( float_flag_invalid );
+        roundData->exception |= float_flag_invalid;
         return float32_default_nan;
     }
     if ( aSign ) {
         if ( ( aExp | aSig ) == 0 ) return a;
-        float_raise( float_flag_invalid );
+        roundData->exception |= float_flag_invalid;
         return float32_default_nan;
     }
     if ( aExp == 0 ) {
@@ -1491,7 +1490,7 @@ float32 float32_sqrt( float32 a )
         }
     }
     shift32RightJamming( zSig, 1, &zSig );
-    return roundAndPackFloat32( 0, zExp, zSig );
+    return roundAndPackFloat32( roundData, 0, zExp, zSig );
 
 }
 
@@ -1603,9 +1602,7 @@ flag float32_le_quiet( float32 a, float3
     if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
          || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
        ) {
-        if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) {
-            float_raise( float_flag_invalid );
-        }
+        /* Do nothing, even if NaN as we're quiet */
         return 0;
     }
     aSign = extractFloat32Sign( a );
@@ -1630,9 +1627,7 @@ flag float32_lt_quiet( float32 a, float3
     if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
          || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
        ) {
-        if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) {
-            float_raise( float_flag_invalid );
-        }
+        /* Do nothing, even if NaN as we're quiet */
         return 0;
     }
     aSign = extractFloat32Sign( a );
@@ -1653,7 +1648,7 @@ positive integer is returned.  Otherwise
 largest integer with the same sign as `a' is returned.
 -------------------------------------------------------------------------------
 */
-int32 float64_to_int32( float64 a )
+int32 float64_to_int32( struct roundingData *roundData, float64 a )
 {
     flag aSign;
     int16 aExp, shiftCount;
@@ -1666,7 +1661,7 @@ int32 float64_to_int32( float64 a )
     if ( aExp ) aSig |= LIT64( 0x0010000000000000 );
     shiftCount = 0x42C - aExp;
     if ( 0 < shiftCount ) shift64RightJamming( aSig, shiftCount, &aSig );
-    return roundAndPackInt32( aSign, aSig );
+    return roundAndPackInt32( roundData, aSign, aSig );
 
 }
 
@@ -1697,7 +1692,7 @@ int32 float64_to_int32_round_to_zero( fl
         goto invalid;
     }
     else if ( 52 < shiftCount ) {
-        if ( aExp || aSig ) float_exception_flags |= float_flag_inexact;
+        if ( aExp || aSig ) float_raise( float_flag_inexact );
         return 0;
     }
     aSig |= LIT64( 0x0010000000000000 );
@@ -1707,11 +1702,11 @@ int32 float64_to_int32_round_to_zero( fl
     if ( aSign ) z = - z;
     if ( ( z < 0 ) ^ aSign ) {
  invalid:
-        float_exception_flags |= float_flag_invalid;
+        float_raise( float_flag_invalid );
         return aSign ? 0x80000000 : 0x7FFFFFFF;
     }
     if ( ( aSig<<shiftCount ) != savedASig ) {
-        float_exception_flags |= float_flag_inexact;
+        float_raise( float_flag_inexact );
     }
     return z;
 
@@ -1728,7 +1723,7 @@ positive integer is returned.  Otherwise
 largest positive integer is returned.
 -------------------------------------------------------------------------------
 */
-int32 float64_to_uint32( float64 a )
+int32 float64_to_uint32( struct roundingData *roundData, float64 a )
 {
     flag aSign;
     int16 aExp, shiftCount;
@@ -1741,7 +1736,7 @@ int32 float64_to_uint32( float64 a )
     if ( aExp ) aSig |= LIT64( 0x0010000000000000 );
     shiftCount = 0x42C - aExp;
     if ( 0 < shiftCount ) shift64RightJamming( aSig, shiftCount, &aSig );
-    return roundAndPackInt32( aSign, aSig );
+    return roundAndPackInt32( roundData, aSign, aSig );
 }
 
 /*
@@ -1770,7 +1765,7 @@ int32 float64_to_uint32_round_to_zero( f
         goto invalid;
     }
     else if ( 52 < shiftCount ) {
-        if ( aExp || aSig ) float_exception_flags |= float_flag_inexact;
+        if ( aExp || aSig ) float_raise( float_flag_inexact );
         return 0;
     }
     aSig |= LIT64( 0x0010000000000000 );
@@ -1780,11 +1775,11 @@ int32 float64_to_uint32_round_to_zero( f
     if ( aSign ) z = - z;
     if ( ( z < 0 ) ^ aSign ) {
  invalid:
-        float_exception_flags |= float_flag_invalid;
+        float_raise( float_flag_invalid );
         return aSign ? 0x80000000 : 0x7FFFFFFF;
     }
     if ( ( aSig<<shiftCount ) != savedASig ) {
-        float_exception_flags |= float_flag_inexact;
+        float_raise( float_flag_inexact );
     }
     return z;
 }
@@ -1797,7 +1792,7 @@ performed according to the IEC/IEEE Stan
 Arithmetic.
 -------------------------------------------------------------------------------
 */
-float32 float64_to_float32( float64 a )
+float32 float64_to_float32( struct roundingData *roundData, float64 a )
 {
     flag aSign;
     int16 aExp;
@@ -1817,7 +1812,7 @@ float32 float64_to_float32( float64 a )
         zSig |= 0x40000000;
         aExp -= 0x381;
     }
-    return roundAndPackFloat32( aSign, aExp, zSig );
+    return roundAndPackFloat32( roundData, aSign, aExp, zSig );
 
 }
 
@@ -1864,7 +1859,7 @@ operation is performed according to the 
 Floating-point Arithmetic.
 -------------------------------------------------------------------------------
 */
-float64 float64_round_to_int( float64 a )
+float64 float64_round_to_int( struct roundingData *roundData, float64 a )
 {
     flag aSign;
     int16 aExp;
@@ -1881,9 +1876,9 @@ float64 float64_round_to_int( float64 a 
     }
     if ( aExp <= 0x3FE ) {
         if ( (bits64) ( a<<1 ) == 0 ) return a;
-        float_exception_flags |= float_flag_inexact;
+        roundData->exception |= float_flag_inexact;
         aSign = extractFloat64Sign( a );
-        switch ( float_rounding_mode ) {
+        switch ( roundData->mode ) {
          case float_round_nearest_even:
             if ( ( aExp == 0x3FE ) && extractFloat64Frac( a ) ) {
                 return packFloat64( aSign, 0x3FF, 0 );
@@ -1901,7 +1896,7 @@ float64 float64_round_to_int( float64 a 
     lastBitMask <<= 0x433 - aExp;
     roundBitsMask = lastBitMask - 1;
     z = a;
-    roundingMode = float_rounding_mode;
+    roundingMode = roundData->mode;
     if ( roundingMode == float_round_nearest_even ) {
         z += lastBitMask>>1;
         if ( ( z & roundBitsMask ) == 0 ) z &= ~ lastBitMask;
@@ -1912,7 +1907,7 @@ float64 float64_round_to_int( float64 a 
         }
     }
     z &= ~ roundBitsMask;
-    if ( z != a ) float_exception_flags |= float_flag_inexact;
+    if ( z != a ) roundData->exception |= float_flag_inexact;
     return z;
 
 }
@@ -1926,7 +1921,7 @@ addition is performed according to the I
 Floating-point Arithmetic.
 -------------------------------------------------------------------------------
 */
-static float64 addFloat64Sigs( float64 a, float64 b, flag zSign )
+static float64 addFloat64Sigs( struct roundingData *roundData, float64 a, float64 b, flag zSign )
 {
     int16 aExp, bExp, zExp;
     bits64 aSig, bSig, zSig;
@@ -1985,7 +1980,7 @@ static float64 addFloat64Sigs( float64 a
         ++zExp;
     }
  roundAndPack:
-    return roundAndPackFloat64( zSign, zExp, zSig );
+    return roundAndPackFloat64( roundData, zSign, zExp, zSig );
 
 }
 
@@ -1998,7 +1993,7 @@ result is a NaN.  The subtraction is per
 Standard for Binary Floating-point Arithmetic.
 -------------------------------------------------------------------------------
 */
-static float64 subFloat64Sigs( float64 a, float64 b, flag zSign )
+static float64 subFloat64Sigs( struct roundingData *roundData, float64 a, float64 b, flag zSign )
 {
     int16 aExp, bExp, zExp;
     bits64 aSig, bSig, zSig;
@@ -2015,7 +2010,7 @@ static float64 subFloat64Sigs( float64 a
     if ( expDiff < 0 ) goto bExpBigger;
     if ( aExp == 0x7FF ) {
         if ( aSig | bSig ) return propagateFloat64NaN( a, b );
-        float_raise( float_flag_invalid );
+        roundData->exception |= float_flag_invalid;
         return float64_default_nan;
     }
     if ( aExp == 0 ) {
@@ -2024,7 +2019,7 @@ static float64 subFloat64Sigs( float64 a
     }
     if ( bSig < aSig ) goto aBigger;
     if ( aSig < bSig ) goto bBigger;
-    return packFloat64( float_rounding_mode == float_round_down, 0, 0 );
+    return packFloat64( roundData->mode == float_round_down, 0, 0 );
  bExpBigger:
     if ( bExp == 0x7FF ) {
         if ( bSig ) return propagateFloat64NaN( a, b );
@@ -2061,7 +2056,7 @@ static float64 subFloat64Sigs( float64 a
     zExp = aExp;
  normalizeRoundAndPack:
     --zExp;
-    return normalizeRoundAndPackFloat64( zSign, zExp, zSig );
+    return normalizeRoundAndPackFloat64( roundData, zSign, zExp, zSig );
 
 }
 
@@ -2072,17 +2067,17 @@ and `b'.  The operation is performed acc
 Binary Floating-point Arithmetic.
 -------------------------------------------------------------------------------
 */
-float64 float64_add( float64 a, float64 b )
+float64 float64_add( struct roundingData *roundData, float64 a, float64 b )
 {
     flag aSign, bSign;
 
     aSign = extractFloat64Sign( a );
     bSign = extractFloat64Sign( b );
     if ( aSign == bSign ) {
-        return addFloat64Sigs( a, b, aSign );
+        return addFloat64Sigs( roundData, a, b, aSign );
     }
     else {
-        return subFloat64Sigs( a, b, aSign );
+        return subFloat64Sigs( roundData, a, b, aSign );
     }
 
 }
@@ -2094,17 +2089,17 @@ Returns the result of subtracting the do
 for Binary Floating-point Arithmetic.
 -------------------------------------------------------------------------------
 */
-float64 float64_sub( float64 a, float64 b )
+float64 float64_sub( struct roundingData *roundData, float64 a, float64 b )
 {
     flag aSign, bSign;
 
     aSign = extractFloat64Sign( a );
     bSign = extractFloat64Sign( b );
     if ( aSign == bSign ) {
-        return subFloat64Sigs( a, b, aSign );
+        return subFloat64Sigs( roundData, a, b, aSign );
     }
     else {
-        return addFloat64Sigs( a, b, aSign );
+        return addFloat64Sigs( roundData, a, b, aSign );
     }
 
 }
@@ -2116,7 +2111,7 @@ Returns the result of multiplying the do
 for Binary Floating-point Arithmetic.
 -------------------------------------------------------------------------------
 */
-float64 float64_mul( float64 a, float64 b )
+float64 float64_mul( struct roundingData *roundData, float64 a, float64 b )
 {
     flag aSign, bSign, zSign;
     int16 aExp, bExp, zExp;
@@ -2134,7 +2129,7 @@ float64 float64_mul( float64 a, float64 
             return propagateFloat64NaN( a, b );
         }
         if ( ( bExp | bSig ) == 0 ) {
-            float_raise( float_flag_invalid );
+            roundData->exception |= float_flag_invalid;
             return float64_default_nan;
         }
         return packFloat64( zSign, 0x7FF, 0 );
@@ -2142,7 +2137,7 @@ float64 float64_mul( float64 a, float64 
     if ( bExp == 0x7FF ) {
         if ( bSig ) return propagateFloat64NaN( a, b );
         if ( ( aExp | aSig ) == 0 ) {
-            float_raise( float_flag_invalid );
+            roundData->exception |= float_flag_invalid;
             return float64_default_nan;
         }
         return packFloat64( zSign, 0x7FF, 0 );
@@ -2164,7 +2159,7 @@ float64 float64_mul( float64 a, float64 
         zSig0 <<= 1;
         --zExp;
     }
-    return roundAndPackFloat64( zSign, zExp, zSig0 );
+    return roundAndPackFloat64( roundData, zSign, zExp, zSig0 );
 
 }
 
@@ -2175,7 +2170,7 @@ by the corresponding value `b'.  The ope
 the IEC/IEEE Standard for Binary Floating-point Arithmetic.
 -------------------------------------------------------------------------------
 */
-float64 float64_div( float64 a, float64 b )
+float64 float64_div( struct roundingData *roundData, float64 a, float64 b )
 {
     flag aSign, bSign, zSign;
     int16 aExp, bExp, zExp;
@@ -2194,7 +2189,7 @@ float64 float64_div( float64 a, float64 
         if ( aSig ) return propagateFloat64NaN( a, b );
         if ( bExp == 0x7FF ) {
             if ( bSig ) return propagateFloat64NaN( a, b );
-            float_raise( float_flag_invalid );
+            roundData->exception |= float_flag_invalid;
             return float64_default_nan;
         }
         return packFloat64( zSign, 0x7FF, 0 );
@@ -2206,10 +2201,10 @@ float64 float64_div( float64 a, float64 
     if ( bExp == 0 ) {
         if ( bSig == 0 ) {
             if ( ( aExp | aSig ) == 0 ) {
-                float_raise( float_flag_invalid );
+                roundData->exception |= float_flag_invalid;
                 return float64_default_nan;
             }
-            float_raise( float_flag_divbyzero );
+            roundData->exception |= float_flag_divbyzero;
             return packFloat64( zSign, 0x7FF, 0 );
         }
         normalizeFloat64Subnormal( bSig, &bExp, &bSig );
@@ -2235,7 +2230,7 @@ float64 float64_div( float64 a, float64 
         }
         zSig |= ( rem1 != 0 );
     }
-    return roundAndPackFloat64( zSign, zExp, zSig );
+    return roundAndPackFloat64( roundData, zSign, zExp, zSig );
 
 }
 
@@ -2246,7 +2241,7 @@ with respect to the corresponding value 
 according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
 -------------------------------------------------------------------------------
 */
-float64 float64_rem( float64 a, float64 b )
+float64 float64_rem( struct roundingData *roundData, float64 a, float64 b )
 {
     flag aSign, bSign, zSign;
     int16 aExp, bExp, expDiff;
@@ -2264,7 +2259,7 @@ float64 float64_rem( float64 a, float64 
         if ( aSig || ( ( bExp == 0x7FF ) && bSig ) ) {
             return propagateFloat64NaN( a, b );
         }
-        float_raise( float_flag_invalid );
+        roundData->exception |= float_flag_invalid;
         return float64_default_nan;
     }
     if ( bExp == 0x7FF ) {
@@ -2273,7 +2268,7 @@ float64 float64_rem( float64 a, float64 
     }
     if ( bExp == 0 ) {
         if ( bSig == 0 ) {
-            float_raise( float_flag_invalid );
+            roundData->exception |= float_flag_invalid;
             return float64_default_nan;
         }
         normalizeFloat64Subnormal( bSig, &bExp, &bSig );
@@ -2321,7 +2316,7 @@ float64 float64_rem( float64 a, float64 
     }
     zSign = ( (sbits64) aSig < 0 );
     if ( zSign ) aSig = - aSig;
-    return normalizeRoundAndPackFloat64( aSign ^ zSign, bExp, aSig );
+    return normalizeRoundAndPackFloat64( roundData, aSign ^ zSign, bExp, aSig );
 
 }
 
@@ -2332,7 +2327,7 @@ The operation is performed according to 
 Floating-point Arithmetic.
 -------------------------------------------------------------------------------
 */
-float64 float64_sqrt( float64 a )
+float64 float64_sqrt( struct roundingData *roundData, float64 a )
 {
     flag aSign;
     int16 aExp, zExp;
@@ -2346,12 +2341,12 @@ float64 float64_sqrt( float64 a )
     if ( aExp == 0x7FF ) {
         if ( aSig ) return propagateFloat64NaN( a, a );
         if ( ! aSign ) return a;
-        float_raise( float_flag_invalid );
+        roundData->exception |= float_flag_invalid;
         return float64_default_nan;
     }
     if ( aSign ) {
         if ( ( aExp | aSig ) == 0 ) return a;
-        float_raise( float_flag_invalid );
+        roundData->exception |= float_flag_invalid;
         return float64_default_nan;
     }
     if ( aExp == 0 ) {
@@ -2382,7 +2377,7 @@ float64 float64_sqrt( float64 a )
         }
     }
     shift64RightJamming( zSig, 1, &zSig );
-    return roundAndPackFloat64( 0, zExp, zSig );
+    return roundAndPackFloat64( roundData, 0, zExp, zSig );
 
 }
 
@@ -2494,9 +2489,7 @@ flag float64_le_quiet( float64 a, float6
     if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
          || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
        ) {
-        if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) {
-            float_raise( float_flag_invalid );
-        }
+        /* Do nothing, even if NaN as we're quiet */
         return 0;
     }
     aSign = extractFloat64Sign( a );
@@ -2521,9 +2514,7 @@ flag float64_lt_quiet( float64 a, float6
     if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
          || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
        ) {
-        if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) {
-            float_raise( float_flag_invalid );
-        }
+        /* Do nothing, even if NaN as we're quiet */
         return 0;
     }
     aSign = extractFloat64Sign( a );
@@ -2546,7 +2537,7 @@ largest positive integer is returned.  O
 overflows, the largest integer with the same sign as `a' is returned.
 -------------------------------------------------------------------------------
 */
-int32 floatx80_to_int32( floatx80 a )
+int32 floatx80_to_int32( struct roundingData *roundData, floatx80 a )
 {
     flag aSign;
     int32 aExp, shiftCount;
@@ -2559,7 +2550,7 @@ int32 floatx80_to_int32( floatx80 a )
     shiftCount = 0x4037 - aExp;
     if ( shiftCount <= 0 ) shiftCount = 1;
     shift64RightJamming( aSig, shiftCount, &aSig );
-    return roundAndPackInt32( aSign, aSig );
+    return roundAndPackInt32( roundData, aSign, aSig );
 
 }
 
@@ -2590,7 +2581,7 @@ int32 floatx80_to_int32_round_to_zero( f
         goto invalid;
     }
     else if ( 63 < shiftCount ) {
-        if ( aExp || aSig ) float_exception_flags |= float_flag_inexact;
+        if ( aExp || aSig ) float_raise( float_flag_inexact );
         return 0;
     }
     savedASig = aSig;
@@ -2599,11 +2590,11 @@ int32 floatx80_to_int32_round_to_zero( f
     if ( aSign ) z = - z;
     if ( ( z < 0 ) ^ aSign ) {
  invalid:
-        float_exception_flags |= float_flag_invalid;
+        float_raise( float_flag_invalid );
         return aSign ? 0x80000000 : 0x7FFFFFFF;
     }
     if ( ( aSig<<shiftCount ) != savedASig ) {
-        float_exception_flags |= float_flag_inexact;
+        float_raise( float_flag_inexact );
     }
     return z;
 
@@ -2617,7 +2608,7 @@ conversion is performed according to the
 Floating-point Arithmetic.
 -------------------------------------------------------------------------------
 */
-float32 floatx80_to_float32( floatx80 a )
+float32 floatx80_to_float32( struct roundingData *roundData, floatx80 a )
 {
     flag aSign;
     int32 aExp;
@@ -2634,7 +2625,7 @@ float32 floatx80_to_float32( floatx80 a 
     }
     shift64RightJamming( aSig, 33, &aSig );
     if ( aExp || aSig ) aExp -= 0x3F81;
-    return roundAndPackFloat32( aSign, aExp, aSig );
+    return roundAndPackFloat32( roundData, aSign, aExp, aSig );
 
 }
 
@@ -2646,7 +2637,7 @@ conversion is performed according to the
 Floating-point Arithmetic.
 -------------------------------------------------------------------------------
 */
-float64 floatx80_to_float64( floatx80 a )
+float64 floatx80_to_float64( struct roundingData *roundData, floatx80 a )
 {
     flag aSign;
     int32 aExp;
@@ -2663,7 +2654,7 @@ float64 floatx80_to_float64( floatx80 a 
     }
     shift64RightJamming( aSig, 1, &zSig );
     if ( aExp || aSig ) aExp -= 0x3C01;
-    return roundAndPackFloat64( aSign, aExp, zSig );
+    return roundAndPackFloat64( roundData, aSign, aExp, zSig );
 
 }
 
@@ -2675,7 +2666,7 @@ value.  The operation is performed accor
 Binary Floating-point Arithmetic.
 -------------------------------------------------------------------------------
 */
-floatx80 floatx80_round_to_int( floatx80 a )
+floatx80 floatx80_round_to_int( struct roundingData *roundData, floatx80 a )
 {
     flag aSign;
     int32 aExp;
@@ -2695,9 +2686,9 @@ floatx80 floatx80_round_to_int( floatx80
              && ( (bits64) ( extractFloatx80Frac( a )<<1 ) == 0 ) ) {
             return a;
         }
-        float_exception_flags |= float_flag_inexact;
+        roundData->exception |= float_flag_inexact;
         aSign = extractFloatx80Sign( a );
-        switch ( float_rounding_mode ) {
+        switch ( roundData->mode ) {
          case float_round_nearest_even:
             if ( ( aExp == 0x3FFE ) && (bits64) ( extractFloatx80Frac( a )<<1 )
                ) {
@@ -2721,7 +2712,7 @@ floatx80 floatx80_round_to_int( floatx80
     lastBitMask <<= 0x403E - aExp;
     roundBitsMask = lastBitMask - 1;
     z = a;
-    roundingMode = float_rounding_mode;
+    roundingMode = roundData->mode;
     if ( roundingMode == float_round_nearest_even ) {
         z.low += lastBitMask>>1;
         if ( ( z.low & roundBitsMask ) == 0 ) z.low &= ~ lastBitMask;
@@ -2736,7 +2727,7 @@ floatx80 floatx80_round_to_int( floatx80
         ++z.high;
         z.low = LIT64( 0x8000000000000000 );
     }
-    if ( z.low != a.low ) float_exception_flags |= float_flag_inexact;
+    if ( z.low != a.low ) roundData->exception |= float_flag_inexact;
     return z;
 
 }
@@ -2750,7 +2741,7 @@ The addition is performed according to t
 Floating-point Arithmetic.
 -------------------------------------------------------------------------------
 */
-static floatx80 addFloatx80Sigs( floatx80 a, floatx80 b, flag zSign )
+static floatx80 addFloatx80Sigs( struct roundingData *roundData, floatx80 a, floatx80 b, flag zSign )
 {
     int32 aExp, bExp, zExp;
     bits64 aSig, bSig, zSig0, zSig1;
@@ -2806,7 +2797,7 @@ static floatx80 addFloatx80Sigs( floatx8
  roundAndPack:
     return
         roundAndPackFloatx80(
-            floatx80_rounding_precision, zSign, zExp, zSig0, zSig1 );
+            roundData, zSign, zExp, zSig0, zSig1 );
 
 }
 
@@ -2819,7 +2810,7 @@ result is a NaN.  The subtraction is per
 Standard for Binary Floating-point Arithmetic.
 -------------------------------------------------------------------------------
 */
-static floatx80 subFloatx80Sigs( floatx80 a, floatx80 b, flag zSign )
+static floatx80 subFloatx80Sigs( struct roundingData *roundData, floatx80 a, floatx80 b, flag zSign )
 {
     int32 aExp, bExp, zExp;
     bits64 aSig, bSig, zSig0, zSig1;
@@ -2837,7 +2828,7 @@ static floatx80 subFloatx80Sigs( floatx8
         if ( (bits64) ( ( aSig | bSig )<<1 ) ) {
             return propagateFloatx80NaN( a, b );
         }
-        float_raise( float_flag_invalid );
+        roundData->exception |= float_flag_invalid;
         z.low = floatx80_default_nan_low;
         z.high = floatx80_default_nan_high;
         return z;
@@ -2849,7 +2840,7 @@ static floatx80 subFloatx80Sigs( floatx8
     zSig1 = 0;
     if ( bSig < aSig ) goto aBigger;
     if ( aSig < bSig ) goto bBigger;
-    return packFloatx80( float_rounding_mode == float_round_down, 0, 0 );
+    return packFloatx80( roundData->mode == float_round_down, 0, 0 );
  bExpBigger:
     if ( bExp == 0x7FFF ) {
         if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b );
@@ -2875,7 +2866,7 @@ static floatx80 subFloatx80Sigs( floatx8
  normalizeRoundAndPack:
     return
         normalizeRoundAndPackFloatx80(
-            floatx80_rounding_precision, zSign, zExp, zSig0, zSig1 );
+            roundData, zSign, zExp, zSig0, zSig1 );
 
 }
 
@@ -2886,17 +2877,17 @@ values `a' and `b'.  The operation is pe
 Standard for Binary Floating-point Arithmetic.
 -------------------------------------------------------------------------------
 */
-floatx80 floatx80_add( floatx80 a, floatx80 b )
+floatx80 floatx80_add( struct roundingData *roundData, floatx80 a, floatx80 b )
 {
     flag aSign, bSign;
     
     aSign = extractFloatx80Sign( a );
     bSign = extractFloatx80Sign( b );
     if ( aSign == bSign ) {
-        return addFloatx80Sigs( a, b, aSign );
+        return addFloatx80Sigs( roundData, a, b, aSign );
     }
     else {
-        return subFloatx80Sigs( a, b, aSign );
+        return subFloatx80Sigs( roundData, a, b, aSign );
     }
     
 }
@@ -2908,17 +2899,17 @@ point values `a' and `b'.  The operation
 IEC/IEEE Standard for Binary Floating-point Arithmetic.
 -------------------------------------------------------------------------------
 */
-floatx80 floatx80_sub( floatx80 a, floatx80 b )
+floatx80 floatx80_sub( struct roundingData *roundData, floatx80 a, floatx80 b )
 {
     flag aSign, bSign;
 
     aSign = extractFloatx80Sign( a );
     bSign = extractFloatx80Sign( b );
     if ( aSign == bSign ) {
-        return subFloatx80Sigs( a, b, aSign );
+        return subFloatx80Sigs( roundData, a, b, aSign );
     }
     else {
-        return addFloatx80Sigs( a, b, aSign );
+        return addFloatx80Sigs( roundData, a, b, aSign );
     }
 
 }
@@ -2930,7 +2921,7 @@ point values `a' and `b'.  The operation
 IEC/IEEE Standard for Binary Floating-point Arithmetic.
 -------------------------------------------------------------------------------
 */
-floatx80 floatx80_mul( floatx80 a, floatx80 b )
+floatx80 floatx80_mul( struct roundingData *roundData, floatx80 a, floatx80 b )
 {
     flag aSign, bSign, zSign;
     int32 aExp, bExp, zExp;
@@ -2956,7 +2947,7 @@ floatx80 floatx80_mul( floatx80 a, float
         if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b );
         if ( ( aExp | aSig ) == 0 ) {
  invalid:
-            float_raise( float_flag_invalid );
+            roundData->exception |= float_flag_invalid;
             z.low = floatx80_default_nan_low;
             z.high = floatx80_default_nan_high;
             return z;
@@ -2979,7 +2970,7 @@ floatx80 floatx80_mul( floatx80 a, float
     }
     return
         roundAndPackFloatx80(
-            floatx80_rounding_precision, zSign, zExp, zSig0, zSig1 );
+            roundData, zSign, zExp, zSig0, zSig1 );
 
 }
 
@@ -2990,7 +2981,7 @@ value `a' by the corresponding value `b'
 according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
 -------------------------------------------------------------------------------
 */
-floatx80 floatx80_div( floatx80 a, floatx80 b )
+floatx80 floatx80_div( struct roundingData *roundData, floatx80 a, floatx80 b )
 {
     flag aSign, bSign, zSign;
     int32 aExp, bExp, zExp;
@@ -3021,12 +3012,12 @@ floatx80 floatx80_div( floatx80 a, float
         if ( bSig == 0 ) {
             if ( ( aExp | aSig ) == 0 ) {
  invalid:
-                float_raise( float_flag_invalid );
+                roundData->exception |= float_flag_invalid;
                 z.low = floatx80_default_nan_low;
                 z.high = floatx80_default_nan_high;
                 return z;
             }
-            float_raise( float_flag_divbyzero );
+            roundData->exception |= float_flag_divbyzero;
             return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
         }
         normalizeFloatx80Subnormal( bSig, &bExp, &bSig );
@@ -3060,7 +3051,7 @@ floatx80 floatx80_div( floatx80 a, float
     }
     return
         roundAndPackFloatx80(
-            floatx80_rounding_precision, zSign, zExp, zSig0, zSig1 );
+            roundData, zSign, zExp, zSig0, zSig1 );
 
 }
 
@@ -3071,7 +3062,7 @@ Returns the remainder of the extended do
 according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
 -------------------------------------------------------------------------------
 */
-floatx80 floatx80_rem( floatx80 a, floatx80 b )
+floatx80 floatx80_rem( struct roundingData *roundData, floatx80 a, floatx80 b )
 {
     flag aSign, bSign, zSign;
     int32 aExp, bExp, expDiff;
@@ -3099,7 +3090,7 @@ floatx80 floatx80_rem( floatx80 a, float
     if ( bExp == 0 ) {
         if ( bSig == 0 ) {
  invalid:
-            float_raise( float_flag_invalid );
+            roundData->exception |= float_flag_invalid;
             z.low = floatx80_default_nan_low;
             z.high = floatx80_default_nan_high;
             return z;
@@ -3156,9 +3147,10 @@ floatx80 floatx80_rem( floatx80 a, float
         aSig1 = alternateASig1;
         zSign = ! zSign;
     }
+
     return
         normalizeRoundAndPackFloatx80(
-            80, zSign, bExp + expDiff, aSig0, aSig1 );
+            roundData, zSign, bExp + expDiff, aSig0, aSig1 );
 
 }
 
@@ -3169,7 +3161,7 @@ value `a'.  The operation is performed a
 for Binary Floating-point Arithmetic.
 -------------------------------------------------------------------------------
 */
-floatx80 floatx80_sqrt( floatx80 a )
+floatx80 floatx80_sqrt( struct roundingData *roundData, floatx80 a )
 {
     flag aSign;
     int32 aExp, zExp;
@@ -3189,7 +3181,7 @@ floatx80 floatx80_sqrt( floatx80 a )
     if ( aSign ) {
         if ( ( aExp | aSig0 ) == 0 ) return a;
  invalid:
-        float_raise( float_flag_invalid );
+        roundData->exception |= float_flag_invalid;
         z.low = floatx80_default_nan_low;
         z.high = floatx80_default_nan_high;
         return z;
@@ -3234,7 +3226,7 @@ floatx80 floatx80_sqrt( floatx80 a )
     }
     return
         roundAndPackFloatx80(
-            floatx80_rounding_precision, 0, zExp, zSig0, zSig1 );
+            roundData, 0, zExp, zSig0, zSig1 );
 
 }
 
@@ -3382,10 +3374,7 @@ flag floatx80_le_quiet( floatx80 a, floa
          || (    ( extractFloatx80Exp( b ) == 0x7FFF )
               && (bits64) ( extractFloatx80Frac( b )<<1 ) )
        ) {
-        if (    floatx80_is_signaling_nan( a )
-             || floatx80_is_signaling_nan( b ) ) {
-            float_raise( float_flag_invalid );
-        }
+        /* Do nothing, even if NaN as we're quiet */
         return 0;
     }
     aSign = extractFloatx80Sign( a );
@@ -3419,10 +3408,7 @@ flag floatx80_lt_quiet( floatx80 a, floa
          || (    ( extractFloatx80Exp( b ) == 0x7FFF )
               && (bits64) ( extractFloatx80Frac( b )<<1 ) )
        ) {
-        if (    floatx80_is_signaling_nan( a )
-             || floatx80_is_signaling_nan( b ) ) {
-            float_raise( float_flag_invalid );
-        }
+        /* Do nothing, even if NaN as we're quiet */
         return 0;
     }
     aSign = extractFloatx80Sign( a );
diff --git a/arch/arm/nwfpe/softfloat.h b/arch/arm/nwfpe/softfloat.h
--- a/arch/arm/nwfpe/softfloat.h
+++ b/arch/arm/nwfpe/softfloat.h
@@ -74,7 +74,7 @@ enum {
 Software IEC/IEEE floating-point rounding mode.
 -------------------------------------------------------------------------------
 */
-extern signed char float_rounding_mode;
+//extern int8 float_rounding_mode;
 enum {
     float_round_nearest_even = 0,
     float_round_to_zero      = 1,
@@ -86,7 +86,6 @@ enum {
 -------------------------------------------------------------------------------
 Software IEC/IEEE floating-point exception flags.
 -------------------------------------------------------------------------------
-extern signed char float_exception_flags;
 enum {
     float_flag_inexact   =  1,
     float_flag_underflow =  2,
@@ -99,7 +98,6 @@ ScottB: November 4, 1998
 Changed the enumeration to match the bit order in the FPA11.
 */
 
-extern signed char float_exception_flags;
 enum {
     float_flag_invalid   =  1,
     float_flag_divbyzero =  2,
@@ -121,7 +119,7 @@ void float_raise( signed char );
 Software IEC/IEEE integer-to-floating-point conversion routines.
 -------------------------------------------------------------------------------
 */
-float32 int32_to_float32( signed int );
+float32 int32_to_float32( struct roundingData *, signed int );
 float64 int32_to_float64( signed int );
 #ifdef FLOATX80
 floatx80 int32_to_floatx80( signed int );
@@ -132,7 +130,7 @@ floatx80 int32_to_floatx80( signed int )
 Software IEC/IEEE single-precision conversion routines.
 -------------------------------------------------------------------------------
 */
-signed int float32_to_int32( float32 );
+signed int float32_to_int32( struct roundingData *, float32 );
 signed int float32_to_int32_round_to_zero( float32 );
 float64 float32_to_float64( float32 );
 #ifdef FLOATX80
@@ -144,13 +142,13 @@ floatx80 float32_to_floatx80( float32 );
 Software IEC/IEEE single-precision operations.
 -------------------------------------------------------------------------------
 */
-float32 float32_round_to_int( float32 );
-float32 float32_add( float32, float32 );
-float32 float32_sub( float32, float32 );
-float32 float32_mul( float32, float32 );
-float32 float32_div( float32, float32 );
-float32 float32_rem( float32, float32 );
-float32 float32_sqrt( float32 );
+float32 float32_round_to_int( struct roundingData*, float32 );
+float32 float32_add( struct roundingData *, float32, float32 );
+float32 float32_sub( struct roundingData *, float32, float32 );
+float32 float32_mul( struct roundingData *, float32, float32 );
+float32 float32_div( struct roundingData *, float32, float32 );
+float32 float32_rem( struct roundingData *, float32, float32 );
+float32 float32_sqrt( struct roundingData*, float32 );
 char float32_eq( float32, float32 );
 char float32_le( float32, float32 );
 char float32_lt( float32, float32 );
@@ -164,9 +162,9 @@ char float32_is_signaling_nan( float32 )
 Software IEC/IEEE double-precision conversion routines.
 -------------------------------------------------------------------------------
 */
-signed int float64_to_int32( float64 );
+signed int float64_to_int32( struct roundingData *, float64 );
 signed int float64_to_int32_round_to_zero( float64 );
-float32 float64_to_float32( float64 );
+float32 float64_to_float32( struct roundingData *, float64 );
 #ifdef FLOATX80
 floatx80 float64_to_floatx80( float64 );
 #endif
@@ -176,13 +174,13 @@ floatx80 float64_to_floatx80( float64 );
 Software IEC/IEEE double-precision operations.
 -------------------------------------------------------------------------------
 */
-float64 float64_round_to_int( float64 );
-float64 float64_add( float64, float64 );
-float64 float64_sub( float64, float64 );
-float64 float64_mul( float64, float64 );
-float64 float64_div( float64, float64 );
-float64 float64_rem( float64, float64 );
-float64 float64_sqrt( float64 );
+float64 float64_round_to_int( struct roundingData *, float64 );
+float64 float64_add( struct roundingData *, float64, float64 );
+float64 float64_sub( struct roundingData *, float64, float64 );
+float64 float64_mul( struct roundingData *, float64, float64 );
+float64 float64_div( struct roundingData *, float64, float64 );
+float64 float64_rem( struct roundingData *, float64, float64 );
+float64 float64_sqrt( struct roundingData *, float64 );
 char float64_eq( float64, float64 );
 char float64_le( float64, float64 );
 char float64_lt( float64, float64 );
@@ -198,31 +196,23 @@ char float64_is_signaling_nan( float64 )
 Software IEC/IEEE extended double-precision conversion routines.
 -------------------------------------------------------------------------------
 */
-signed int floatx80_to_int32( floatx80 );
+signed int floatx80_to_int32( struct roundingData *, floatx80 );
 signed int floatx80_to_int32_round_to_zero( floatx80 );
-float32 floatx80_to_float32( floatx80 );
-float64 floatx80_to_float64( floatx80 );
-
-/*
--------------------------------------------------------------------------------
-Software IEC/IEEE extended double-precision rounding precision.  Valid
-values are 32, 64, and 80.
--------------------------------------------------------------------------------
-*/
-extern signed char floatx80_rounding_precision;
+float32 floatx80_to_float32( struct roundingData *, floatx80 );
+float64 floatx80_to_float64( struct roundingData *, floatx80 );
 
 /*
 -------------------------------------------------------------------------------
 Software IEC/IEEE extended double-precision operations.
 -------------------------------------------------------------------------------
 */
-floatx80 floatx80_round_to_int( floatx80 );
-floatx80 floatx80_add( floatx80, floatx80 );
-floatx80 floatx80_sub( floatx80, floatx80 );
-floatx80 floatx80_mul( floatx80, floatx80 );
-floatx80 floatx80_div( floatx80, floatx80 );
-floatx80 floatx80_rem( floatx80, floatx80 );
-floatx80 floatx80_sqrt( floatx80 );
+floatx80 floatx80_round_to_int( struct roundingData *, floatx80 );
+floatx80 floatx80_add( struct roundingData *, floatx80, floatx80 );
+floatx80 floatx80_sub( struct roundingData *, floatx80, floatx80 );
+floatx80 floatx80_mul( struct roundingData *, floatx80, floatx80 );
+floatx80 floatx80_div( struct roundingData *, floatx80, floatx80 );
+floatx80 floatx80_rem( struct roundingData *, floatx80, floatx80 );
+floatx80 floatx80_sqrt( struct roundingData *, floatx80 );
 char floatx80_eq( floatx80, floatx80 );
 char floatx80_le( floatx80, floatx80 );
 char floatx80_lt( floatx80, floatx80 );
diff --git a/arch/arm/oprofile/Makefile b/arch/arm/oprofile/Makefile
--- a/arch/arm/oprofile/Makefile
+++ b/arch/arm/oprofile/Makefile
@@ -6,6 +6,6 @@ DRIVER_OBJS = $(addprefix ../../../drive
 		oprofilefs.o oprofile_stats.o \
 		timer_int.o )
 
-oprofile-y				:= $(DRIVER_OBJS) init.o
+oprofile-y				:= $(DRIVER_OBJS) init.o backtrace.o
 oprofile-$(CONFIG_CPU_XSCALE)		+= common.o op_model_xscale.o
 
diff --git a/arch/arm/oprofile/backtrace.c b/arch/arm/oprofile/backtrace.c
new file mode 100644
--- /dev/null
+++ b/arch/arm/oprofile/backtrace.c
@@ -0,0 +1,144 @@
+/*
+ * Arm specific backtracing code for oprofile
+ *
+ * Copyright 2005 Openedhand Ltd.
+ *
+ * Author: Richard Purdie <rpurdie@openedhand.com>
+ *
+ * Based on i386 oprofile backtrace code by John Levon, David Smith
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/oprofile.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <asm/ptrace.h>
+#include <asm/uaccess.h>
+
+
+/*
+ * The registers we're interested in are at the end of the variable
+ * length saved register structure. The fp points at the end of this
+ * structure so the address of this struct is:
+ * (struct frame_tail *)(xxx->fp)-1
+ */
+struct frame_tail {
+	struct frame_tail *fp;
+	unsigned long sp;
+	unsigned long lr;
+} __attribute__((packed));
+
+
+#ifdef CONFIG_FRAME_POINTER
+static struct frame_tail* kernel_backtrace(struct frame_tail *tail)
+{
+	oprofile_add_trace(tail->lr);
+
+	/* frame pointers should strictly progress back up the stack
+	 * (towards higher addresses) */
+	if (tail >= tail->fp)
+		return NULL;
+
+	return tail->fp-1;
+}
+#endif
+
+static struct frame_tail* user_backtrace(struct frame_tail *tail)
+{
+	struct frame_tail buftail;
+
+	/* hardware pte might not be valid due to dirty/accessed bit emulation
+	 * so we use copy_from_user and benefit from exception fixups */
+	if (copy_from_user(&buftail, tail, sizeof(struct frame_tail)))
+		return NULL;
+
+	oprofile_add_trace(buftail.lr);
+
+	/* frame pointers should strictly progress back up the stack
+	 * (towards higher addresses) */
+	if (tail >= buftail.fp)
+		return NULL;
+
+	return buftail.fp-1;
+}
+
+/* Compare two addresses and see if they're on the same page */
+#define CMP_ADDR_EQUAL(x,y,offset) ((((unsigned long) x) >> PAGE_SHIFT) \
+	== ((((unsigned long) y) + offset) >> PAGE_SHIFT))
+
+/* check that the page(s) containing the frame tail are present */
+static int pages_present(struct frame_tail *tail)
+{
+	struct mm_struct * mm = current->mm;
+
+	if (!check_user_page_readable(mm, (unsigned long)tail))
+		return 0;
+
+	if (CMP_ADDR_EQUAL(tail, tail, 8))
+		return 1;
+
+	if (!check_user_page_readable(mm, ((unsigned long)tail) + 8))
+		return 0;
+
+	return 1;
+}
+
+/*
+ * |             | /\ Higher addresses
+ * |             |
+ * --------------- stack base (address of current_thread_info)
+ * | thread info |
+ * .             .
+ * |    stack    |
+ * --------------- saved regs->ARM_fp value if valid (frame_tail address)
+ * .             .
+ * --------------- struct pt_regs stored on stack (struct pt_regs *)
+ * |             |
+ * .             .
+ * |             |
+ * --------------- %esp
+ * |             |
+ * |             | \/ Lower addresses
+ *
+ * Thus, &pt_regs <-> stack base restricts the valid(ish) fp values
+ */
+static int valid_kernel_stack(struct frame_tail *tail, struct pt_regs *regs)
+{
+	unsigned long tailaddr = (unsigned long)tail;
+	unsigned long stack = (unsigned long)regs;
+	unsigned long stack_base = (stack & ~(THREAD_SIZE - 1)) + THREAD_SIZE;
+
+	return (tailaddr > stack) && (tailaddr < stack_base);
+}
+
+void arm_backtrace(struct pt_regs * const regs, unsigned int depth)
+{
+	struct frame_tail *tail;
+	unsigned long last_address = 0;
+
+	tail = ((struct frame_tail *) regs->ARM_fp) - 1;
+
+	if (!user_mode(regs)) {
+
+#ifdef CONFIG_FRAME_POINTER
+		while (depth-- && tail && valid_kernel_stack(tail, regs)) {
+			tail = kernel_backtrace(tail);
+		}
+#endif
+		return;
+	}
+
+	while (depth-- && tail && !((unsigned long) tail & 3)) {
+		if ((!CMP_ADDR_EQUAL(last_address, tail, 0)
+			|| !CMP_ADDR_EQUAL(last_address, tail, 8))
+				&& !pages_present(tail))
+			return;
+		last_address = (unsigned long) tail;
+		tail = user_backtrace(tail);
+	}
+}
+
diff --git a/arch/arm/oprofile/init.c b/arch/arm/oprofile/init.c
--- a/arch/arm/oprofile/init.c
+++ b/arch/arm/oprofile/init.c
@@ -20,6 +20,8 @@ int __init oprofile_arch_init(struct opr
 	ret = pmu_init(ops, &op_xscale_spec);
 #endif
 
+	ops->backtrace = arm_backtrace;
+
 	return ret;
 }
 
diff --git a/arch/arm/oprofile/op_arm_model.h b/arch/arm/oprofile/op_arm_model.h
--- a/arch/arm/oprofile/op_arm_model.h
+++ b/arch/arm/oprofile/op_arm_model.h
@@ -24,6 +24,8 @@ struct op_arm_model_spec {
 extern struct op_arm_model_spec op_xscale_spec;
 #endif
 
+extern void arm_backtrace(struct pt_regs * const regs, unsigned int depth);
+
 extern int __init pmu_init(struct oprofile_operations *ops, struct op_arm_model_spec *spec);
 extern void pmu_exit(void);
 #endif /* OP_ARM_MODEL_H */
diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig
new file mode 100644
--- /dev/null
+++ b/arch/arm/plat-omap/Kconfig
@@ -0,0 +1,112 @@
+if ARCH_OMAP
+
+menu "TI OMAP Implementations"
+
+config ARCH_OMAP_OTG
+	bool
+
+choice
+	prompt "OMAP System Type"
+	default ARCH_OMAP1
+
+config ARCH_OMAP1
+	bool "TI OMAP1"
+
+config ARCH_OMAP2
+	bool "TI OMAP2"
+
+endchoice
+
+comment "OMAP Feature Selections"
+
+config OMAP_RESET_CLOCKS
+	bool "Reset unused clocks during boot"
+	depends on ARCH_OMAP
+	default n
+	help
+	  Say Y if you want to reset unused clocks during boot.
+	  This option saves power, but assumes all drivers are
+	  using the clock framework. Broken drivers that do not
+	  yet use clock framework may not work with this option.
+	  If you are booting from another operating system, you
+	  probably do not want this option enabled until your
+	  device drivers work properly.
+
+config OMAP_MUX
+	bool "OMAP multiplexing support"
+        depends on ARCH_OMAP
+	default y
+        help
+          Pin multiplexing support for OMAP boards. If your bootloader
+          sets the multiplexing correctly, say N. Otherwise, or if unsure,
+          say Y.
+
+config OMAP_MUX_DEBUG
+	bool "Multiplexing debug output"
+        depends on OMAP_MUX
+        default n
+        help
+          Makes the multiplexing functions print out a lot of debug info.
+          This is useful if you want to find out the correct values of the
+          multiplexing registers.
+
+config OMAP_MUX_WARNINGS
+	bool "Warn about pins the bootloader didn't set up"
+        depends on OMAP_MUX
+        default y
+        help
+	  Choose Y here to warn whenever driver initialization logic needs
+	  to change the pin multiplexing setup.  When there are no warnings
+	  printed, it's safe to deselect OMAP_MUX for your product.
+
+choice
+        prompt "System timer"
+	default OMAP_MPU_TIMER
+
+config OMAP_MPU_TIMER
+	bool "Use mpu timer"
+	help
+	  Select this option if you want to use the OMAP mpu timer. This
+	  timer provides more intra-tick resolution than the 32KHz timer,
+	  but consumes more power.
+
+config OMAP_32K_TIMER
+	bool "Use 32KHz timer"
+	depends on ARCH_OMAP16XX
+	help
+	  Select this option if you want to enable the OMAP 32KHz timer.
+	  This timer saves power compared to the OMAP_MPU_TIMER, and has
+	  support for no tick during idle. The 32KHz timer provides less
+	  intra-tick resolution than OMAP_MPU_TIMER. The 32KHz timer is
+	  currently only available for OMAP-16xx.
+
+endchoice
+
+config OMAP_32K_TIMER_HZ
+       int "Kernel internal timer frequency for 32KHz timer"
+       range 32 1024
+       depends on OMAP_32K_TIMER
+       default "128"
+       help
+	  Kernel internal timer frequency should be a divisor of 32768,
+	  such as 64 or 128.
+
+choice
+	prompt "Low-level debug console UART"
+	depends on ARCH_OMAP
+	default OMAP_LL_DEBUG_UART1
+
+config OMAP_LL_DEBUG_UART1
+	bool "UART1"
+
+config OMAP_LL_DEBUG_UART2
+	bool "UART2"
+
+config OMAP_LL_DEBUG_UART3
+	bool "UART3"
+
+endchoice
+
+endmenu
+
+endif
diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile
new file mode 100644
--- /dev/null
+++ b/arch/arm/plat-omap/Makefile
@@ -0,0 +1,17 @@
+#
+# Makefile for the linux kernel.
+#
+
+# Common support
+obj-y := common.o dma.o clock.o mux.o gpio.o mcbsp.o usb.o
+obj-m :=
+obj-n :=
+obj-  :=
+
+# OCPI interconnect support for 1710, 1610 and 5912
+obj-$(CONFIG_ARCH_OMAP16XX) += ocpi.o
+
+# Power Management
+obj-$(CONFIG_PM) += pm.o sleep.o
+
+obj-$(CONFIG_CPU_FREQ) += cpu-omap.o
diff --git a/arch/arm/plat-omap/clock.c b/arch/arm/plat-omap/clock.c
new file mode 100644
--- /dev/null
+++ b/arch/arm/plat-omap/clock.c
@@ -0,0 +1,1323 @@
+/*
+ *  linux/arch/arm/plat-omap/clock.c
+ *
+ *  Copyright (C) 2004 Nokia corporation
+ *  Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+
+#include <asm/io.h>
+#include <asm/semaphore.h>
+#include <asm/hardware/clock.h>
+#include <asm/arch/board.h>
+#include <asm/arch/usb.h>
+
+#include "clock.h"
+
+static LIST_HEAD(clocks);
+static DECLARE_MUTEX(clocks_sem);
+static DEFINE_SPINLOCK(clockfw_lock);
+static void propagate_rate(struct clk *  clk);
+/* UART clock function */
+static int set_uart_rate(struct clk * clk, unsigned long rate);
+/* External clock (MCLK & BCLK) functions */
+static int set_ext_clk_rate(struct clk *  clk, unsigned long rate);
+static long round_ext_clk_rate(struct clk *  clk, unsigned long rate);
+static void init_ext_clk(struct clk *  clk);
+/* MPU virtual clock functions */
+static int select_table_rate(struct clk *  clk, unsigned long rate);
+static long round_to_table_rate(struct clk *  clk, unsigned long rate);
+void clk_setdpll(__u16, __u16);
+
+static struct mpu_rate rate_table[] = {
+	/* MPU MHz, xtal MHz, dpll1 MHz, CKCTL, DPLL_CTL
+	 * armdiv, dspdiv, dspmmu, tcdiv, perdiv, lcddiv
+	 */
+#if defined(CONFIG_OMAP_ARM_216MHZ)
+	{ 216000000, 12000000, 216000000, 0x050d, 0x2910 }, /* 1/1/2/2/2/8 */
+#endif
+#if defined(CONFIG_OMAP_ARM_195MHZ)
+	{ 195000000, 13000000, 195000000, 0x050e, 0x2790 }, /* 1/1/2/2/4/8 */
+#endif
+#if defined(CONFIG_OMAP_ARM_192MHZ)
+	{ 192000000, 19200000, 192000000, 0x050f, 0x2510 }, /* 1/1/2/2/8/8 */
+	{ 192000000, 12000000, 192000000, 0x050f, 0x2810 }, /* 1/1/2/2/8/8 */
+	{  96000000, 12000000, 192000000, 0x055f, 0x2810 }, /* 2/2/2/2/8/8 */
+	{  48000000, 12000000, 192000000, 0x0baf, 0x2810 }, /* 4/8/4/4/8/8 */
+	{  24000000, 12000000, 192000000, 0x0fff, 0x2810 }, /* 8/8/8/8/8/8 */
+#endif
+#if defined(CONFIG_OMAP_ARM_182MHZ)
+	{ 182000000, 13000000, 182000000, 0x050e, 0x2710 }, /* 1/1/2/2/4/8 */
+#endif
+#if defined(CONFIG_OMAP_ARM_168MHZ)
+	{ 168000000, 12000000, 168000000, 0x010f, 0x2710 }, /* 1/1/1/2/8/8 */
+#endif
+#if defined(CONFIG_OMAP_ARM_150MHZ)
+	{ 150000000, 12000000, 150000000, 0x010a, 0x2cb0 }, /* 1/1/1/2/4/4 */
+#endif
+#if defined(CONFIG_OMAP_ARM_120MHZ)
+	{ 120000000, 12000000, 120000000, 0x010a, 0x2510 }, /* 1/1/1/2/4/4 */
+#endif
+#if defined(CONFIG_OMAP_ARM_96MHZ)
+	{  96000000, 12000000,  96000000, 0x0005, 0x2410 }, /* 1/1/1/1/2/2 */
+#endif
+#if defined(CONFIG_OMAP_ARM_60MHZ)
+	{  60000000, 12000000,  60000000, 0x0005, 0x2290 }, /* 1/1/1/1/2/2 */
+#endif
+#if defined(CONFIG_OMAP_ARM_30MHZ)
+	{  30000000, 12000000,  60000000, 0x0555, 0x2290 }, /* 2/2/2/2/2/2 */
+#endif
+	{ 0, 0, 0, 0, 0 },
+};
+
+
+static void ckctl_recalc(struct clk *  clk);
+int __clk_enable(struct clk *clk);
+void __clk_disable(struct clk *clk);
+void __clk_unuse(struct clk *clk);
+int __clk_use(struct clk *clk);
+
+
+static void followparent_recalc(struct clk *  clk)
+{
+	clk->rate = clk->parent->rate;
+}
+
+
+static void watchdog_recalc(struct clk *  clk)
+{
+	clk->rate = clk->parent->rate / 14;
+}
+
+static void uart_recalc(struct clk * clk)
+{
+	unsigned int val = omap_readl(clk->enable_reg);
+	if (val & clk->enable_bit)
+		clk->rate = 48000000;
+	else
+		clk->rate = 12000000;
+}
+
+static struct clk ck_ref = {
+	.name		= "ck_ref",
+	.rate		= 12000000,
+	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
+			  ALWAYS_ENABLED,
+};
+
+static struct clk ck_dpll1 = {
+	.name		= "ck_dpll1",
+	.parent		= &ck_ref,
+	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
+			  RATE_PROPAGATES | ALWAYS_ENABLED,
+};
+
+static struct clk ck_dpll1out = {
+	.name		= "ck_dpll1out",
+	.parent		= &ck_dpll1,
+	.flags		= CLOCK_IN_OMAP16XX,
+	.enable_reg	= ARM_IDLECT2,
+	.enable_bit	= EN_CKOUT_ARM,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk arm_ck = {
+	.name		= "arm_ck",
+	.parent		= &ck_dpll1,
+	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
+			  RATE_CKCTL | RATE_PROPAGATES | ALWAYS_ENABLED,
+	.rate_offset	= CKCTL_ARMDIV_OFFSET,
+	.recalc		= &ckctl_recalc,
+};
+
+static struct clk armper_ck = {
+	.name		= "armper_ck",
+	.parent		= &ck_dpll1,
+	.flags		= CLOCK_IN_OMAP730 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
+			  RATE_CKCTL,
+	.enable_reg	= ARM_IDLECT2,
+	.enable_bit	= EN_PERCK,
+	.rate_offset	= CKCTL_PERDIV_OFFSET,
+	.recalc		= &ckctl_recalc,
+};
+
+static struct clk arm_gpio_ck = {
+	.name		= "arm_gpio_ck",
+	.parent		= &ck_dpll1,
+	.flags		= CLOCK_IN_OMAP1510,
+	.enable_reg	= ARM_IDLECT2,
+	.enable_bit	= EN_GPIOCK,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk armxor_ck = {
+	.name		= "armxor_ck",
+	.parent		= &ck_ref,
+	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
+	.enable_reg	= ARM_IDLECT2,
+	.enable_bit	= EN_XORPCK,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk armtim_ck = {
+	.name		= "armtim_ck",
+	.parent		= &ck_ref,
+	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
+	.enable_reg	= ARM_IDLECT2,
+	.enable_bit	= EN_TIMCK,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk armwdt_ck = {
+	.name		= "armwdt_ck",
+	.parent		= &ck_ref,
+	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
+	.enable_reg	= ARM_IDLECT2,
+	.enable_bit	= EN_WDTCK,
+	.recalc		= &watchdog_recalc,
+};
+
+static struct clk arminth_ck16xx = {
+	.name		= "arminth_ck",
+	.parent		= &arm_ck,
+	.flags		= CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
+	.recalc		= &followparent_recalc,
+	/* Note: On 16xx the frequency can be divided by 2 by programming
+	 * ARM_CKCTL:ARM_INTHCK_SEL(14) to 1
+	 *
+	 * 1510 version is in TC clocks.
+	 */
+};
+
+static struct clk dsp_ck = {
+	.name		= "dsp_ck",
+	.parent		= &ck_dpll1,
+	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
+			  RATE_CKCTL,
+	.enable_reg	= ARM_CKCTL,
+	.enable_bit	= EN_DSPCK,
+	.rate_offset	= CKCTL_DSPDIV_OFFSET,
+	.recalc		= &ckctl_recalc,
+};
+
+static struct clk dspmmu_ck = {
+	.name		= "dspmmu_ck",
+	.parent		= &ck_dpll1,
+	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
+			  RATE_CKCTL | ALWAYS_ENABLED,
+	.rate_offset	= CKCTL_DSPMMUDIV_OFFSET,
+	.recalc		= &ckctl_recalc,
+};
+
+static struct clk dspper_ck = {
+	.name		= "dspper_ck",
+	.parent		= &ck_dpll1,
+	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
+			  RATE_CKCTL | DSP_DOMAIN_CLOCK | VIRTUAL_IO_ADDRESS,
+	.enable_reg	= DSP_IDLECT2,
+	.enable_bit	= EN_PERCK,
+	.rate_offset	= CKCTL_PERDIV_OFFSET,
+	.recalc		= &followparent_recalc,
+	//.recalc		= &ckctl_recalc,
+};
+
+static struct clk dspxor_ck = {
+	.name		= "dspxor_ck",
+	.parent		= &ck_ref,
+	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
+			  DSP_DOMAIN_CLOCK | VIRTUAL_IO_ADDRESS,
+	.enable_reg	= DSP_IDLECT2,
+	.enable_bit	= EN_XORPCK,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk dsptim_ck = {
+	.name		= "dsptim_ck",
+	.parent		= &ck_ref,
+	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
+			  DSP_DOMAIN_CLOCK | VIRTUAL_IO_ADDRESS,
+	.enable_reg	= DSP_IDLECT2,
+	.enable_bit	= EN_DSPTIMCK,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk tc_ck = {
+	.name		= "tc_ck",
+	.parent		= &ck_dpll1,
+	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP730 |
+			  RATE_CKCTL | RATE_PROPAGATES | ALWAYS_ENABLED,
+	.rate_offset	= CKCTL_TCDIV_OFFSET,
+	.recalc		= &ckctl_recalc,
+};
+
+static struct clk arminth_ck1510 = {
+	.name		= "arminth_ck",
+	.parent		= &tc_ck,
+	.flags		= CLOCK_IN_OMAP1510 | ALWAYS_ENABLED,
+	.recalc		= &followparent_recalc,
+	/* Note: On 1510 the frequency follows TC_CK
+	 *
+	 * 16xx version is in MPU clocks.
+	 */
+};
+
+static struct clk tipb_ck = {
+	.name		= "tibp_ck",
+	.parent		= &tc_ck,
+	.flags		= CLOCK_IN_OMAP1510 | ALWAYS_ENABLED,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk l3_ocpi_ck = {
+	.name		= "l3_ocpi_ck",
+	.parent		= &tc_ck,
+	.flags		= CLOCK_IN_OMAP16XX,
+	.enable_reg	= ARM_IDLECT3,
+	.enable_bit	= EN_OCPI_CK,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk tc1_ck = {
+	.name		= "tc1_ck",
+	.parent		= &tc_ck,
+	.flags		= CLOCK_IN_OMAP16XX,
+	.enable_reg	= ARM_IDLECT3,
+	.enable_bit	= EN_TC1_CK,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk tc2_ck = {
+	.name		= "tc2_ck",
+	.parent		= &tc_ck,
+	.flags		= CLOCK_IN_OMAP16XX,
+	.enable_reg	= ARM_IDLECT3,
+	.enable_bit	= EN_TC2_CK,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk dma_ck = {
+	.name		= "dma_ck",
+	.parent		= &tc_ck,
+	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
+			  ALWAYS_ENABLED,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk dma_lcdfree_ck = {
+	.name		= "dma_lcdfree_ck",
+	.parent		= &tc_ck,
+	.flags		= CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk api_ck = {
+	.name		= "api_ck",
+	.parent		= &tc_ck,
+	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
+	.enable_reg	= ARM_IDLECT2,
+	.enable_bit	= EN_APICK,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk lb_ck = {
+	.name		= "lb_ck",
+	.parent		= &tc_ck,
+	.flags		= CLOCK_IN_OMAP1510,
+	.enable_reg	= ARM_IDLECT2,
+	.enable_bit	= EN_LBCK,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk rhea1_ck = {
+	.name		= "rhea1_ck",
+	.parent		= &tc_ck,
+	.flags		= CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk rhea2_ck = {
+	.name		= "rhea2_ck",
+	.parent		= &tc_ck,
+	.flags		= CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
+	.recalc		= &followparent_recalc,
+};
+
+static struct clk lcd_ck = {
+	.name		= "lcd_ck",
+	.parent		= &ck_dpll1,
+	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP730 |
+			  RATE_CKCTL,
+	.enable_reg	= ARM_IDLECT2,
+	.enable_bit	= EN_LCDCK,
+	.rate_offset	= CKCTL_LCDDIV_OFFSET,
+	.recalc		= &ckctl_recalc,
+};
+
+static struct clk uart1_1510 = {
+	.name		= "uart1_ck",
+	/* Direct from ULPD, no parent */
+	.rate		= 12000000,
+	.flags		= CLOCK_IN_OMAP1510 | ENABLE_REG_32BIT | ALWAYS_ENABLED,
+	.enable_reg	= MOD_CONF_CTRL_0,
+	.enable_bit	= 29,	/* Chooses between 12MHz and 48MHz */
+	.set_rate	= &set_uart_rate,
+	.recalc		= &uart_recalc,
+};
+
+static struct clk uart1_16xx = {
+	.name		= "uart1_ck",
+	/* Direct from ULPD, no parent */
+	.rate		= 48000000,
+	.flags		= CLOCK_IN_OMAP16XX | RATE_FIXED | ENABLE_REG_32BIT,
+	.enable_reg	= MOD_CONF_CTRL_0,
+	.enable_bit	= 29,
+};
+
+static struct clk uart2_ck = {
+	.name		= "uart2_ck",
+	/* Direct from ULPD, no parent */
+	.rate		= 12000000,
+	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | ENABLE_REG_32BIT,
+	.enable_reg	= MOD_CONF_CTRL_0,
+	.enable_bit	= 30,	/* Chooses between 12MHz and 48MHz */
+	.set_rate	= &set_uart_rate,
+	.recalc		= &uart_recalc,
+};
+
+static struct clk uart3_1510 = {
+	.name		= "uart3_ck",
+	/* Direct from ULPD, no parent */
+	.rate		= 12000000,
+	.flags		= CLOCK_IN_OMAP1510 | ENABLE_REG_32BIT | ALWAYS_ENABLED,
+	.enable_reg	= MOD_CONF_CTRL_0,
+	.enable_bit	= 31,	/* Chooses between 12MHz and 48MHz */
+	.set_rate	= &set_uart_rate,
+	.recalc		= &uart_recalc,
+};
+
+static struct clk uart3_16xx = {
+	.name		= "uart3_ck",
+	/* Direct from ULPD, no parent */
+	.rate		= 48000000,
+	.flags		= CLOCK_IN_OMAP16XX | RATE_FIXED | ENABLE_REG_32BIT,
+	.enable_reg	= MOD_CONF_CTRL_0,
+	.enable_bit	= 31,
+};
+
+static struct clk usb_clko = {	/* 6 MHz output on W4_USB_CLKO */
+	.name		= "usb_clko",
+	/* Direct from ULPD, no parent */
+	.rate		= 6000000,
+	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
+			  RATE_FIXED | ENABLE_REG_32BIT,
+	.enable_reg	= ULPD_CLOCK_CTRL,
+	.enable_bit	= USB_MCLK_EN_BIT,
+};
+
+static struct clk usb_hhc_ck1510 = {
+	.name		= "usb_hhc_ck",
+	/* Direct from ULPD, no parent */
+	.rate		= 48000000, /* Actually 2 clocks, 12MHz and 48MHz */
+	.flags		= CLOCK_IN_OMAP1510 |
+			  RATE_FIXED | ENABLE_REG_32BIT,
+	.enable_reg	= MOD_CONF_CTRL_0,
+	.enable_bit	= USB_HOST_HHC_UHOST_EN,
+};
+
+static struct clk usb_hhc_ck16xx = {
+	.name		= "usb_hhc_ck",
+	/* Direct from ULPD, no parent */
+	.rate		= 48000000,
+	/* OTG_SYSCON_2.OTG_PADEN == 0 (not 1510-compatible) */
+	.flags		= CLOCK_IN_OMAP16XX |
+			  RATE_FIXED | ENABLE_REG_32BIT,
+	.enable_reg	= OTG_BASE + 0x08 /* OTG_SYSCON_2 */,
+	.enable_bit	= 8 /* UHOST_EN */,
+};
+
+static struct clk mclk_1510 = {
+	.name		= "mclk",
+	/* Direct from ULPD, no parent. May be enabled by ext hardware. */
+	.rate		= 12000000,
+	.flags		= CLOCK_IN_OMAP1510 | RATE_FIXED,
+};
+
+static struct clk mclk_16xx = {
+	.name		= "mclk",
+	/* Direct from ULPD, no parent. May be enabled by ext hardware. */
+	.flags		= CLOCK_IN_OMAP16XX,
+	.enable_reg	= COM_CLK_DIV_CTRL_SEL,
+	.enable_bit	= COM_ULPD_PLL_CLK_REQ,
+	.set_rate	= &set_ext_clk_rate,
+	.round_rate	= &round_ext_clk_rate,
+	.init		= &init_ext_clk,
+};
+
+static struct clk bclk_1510 = {
+	.name		= "bclk",
+	/* Direct from ULPD, no parent. May be enabled by ext hardware. */
+	.rate		= 12000000,
+	.flags		= CLOCK_IN_OMAP1510 | RATE_FIXED,
+};
+
+static struct clk bclk_16xx = {
+	.name		= "bclk",
+	/* Direct from ULPD, no parent. May be enabled by ext hardware. */
+	.flags		= CLOCK_IN_OMAP16XX,
+	.enable_reg	= SWD_CLK_DIV_CTRL_SEL,
+	.enable_bit	= SWD_ULPD_PLL_CLK_REQ,
+	.set_rate	= &set_ext_clk_rate,
+	.round_rate	= &round_ext_clk_rate,
+	.init		= &init_ext_clk,
+};
+
+static struct clk mmc1_ck = {
+	.name		= "mmc1_ck",
+	/* Functional clock is direct from ULPD, interface clock is ARMPER */
+	.parent		= &armper_ck,
+	.rate		= 48000000,
+	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
+			  RATE_FIXED | ENABLE_REG_32BIT,
+	.enable_reg	= MOD_CONF_CTRL_0,
+	.enable_bit	= 23,
+};
+
+static struct clk mmc2_ck = {
+	.name		= "mmc2_ck",
+	/* Functional clock is direct from ULPD, interface clock is ARMPER */
+	.parent		= &armper_ck,
+	.rate		= 48000000,
+	.flags		= CLOCK_IN_OMAP16XX |
+			  RATE_FIXED | ENABLE_REG_32BIT,
+	.enable_reg	= MOD_CONF_CTRL_0,
+	.enable_bit	= 20,
+};
+
+static struct clk virtual_ck_mpu = {
+	.name		= "mpu",
+	.flags		= CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
+			  VIRTUAL_CLOCK | ALWAYS_ENABLED,
+	.parent		= &arm_ck, /* Is smarter alias for */
+	.recalc		= &followparent_recalc,
+	.set_rate	= &select_table_rate,
+	.round_rate	= &round_to_table_rate,
+};
+
+
+static struct clk *  onchip_clks[] = {
+	/* non-ULPD clocks */
+	&ck_ref,
+	&ck_dpll1,
+	/* CK_GEN1 clocks */
+	&ck_dpll1out,
+	&arm_ck,
+	&armper_ck,
+	&arm_gpio_ck,
+	&armxor_ck,
+	&armtim_ck,
+	&armwdt_ck,
+	&arminth_ck1510,  &arminth_ck16xx,
+	/* CK_GEN2 clocks */
+	&dsp_ck,
+	&dspmmu_ck,
+	&dspper_ck,
+	&dspxor_ck,
+	&dsptim_ck,
+	/* CK_GEN3 clocks */
+	&tc_ck,
+	&tipb_ck,
+	&l3_ocpi_ck,
+	&tc1_ck,
+	&tc2_ck,
+	&dma_ck,
+	&dma_lcdfree_ck,
+	&api_ck,
+	&lb_ck,
+	&rhea1_ck,
+	&rhea2_ck,
+	&lcd_ck,
+	/* ULPD clocks */
+	&uart1_1510,
+	&uart1_16xx,
+	&uart2_ck,
+	&uart3_1510,
+	&uart3_16xx,
+	&usb_clko,
+	&usb_hhc_ck1510, &usb_hhc_ck16xx,
+	&mclk_1510,  &mclk_16xx,
+	&bclk_1510,  &bclk_16xx,
+	&mmc1_ck,
+	&mmc2_ck,
+	/* Virtual clocks */
+	&virtual_ck_mpu,
+};
+
+struct clk *clk_get(struct device *dev, const char *id)
+{
+	struct clk *p, *clk = ERR_PTR(-ENOENT);
+
+	down(&clocks_sem);
+	list_for_each_entry(p, &clocks, node) {
+		if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
+			clk = p;
+			break;
+		}
+	}
+	up(&clocks_sem);
+
+	return clk;
+}
+EXPORT_SYMBOL(clk_get);
+
+
+void clk_put(struct clk *clk)
+{
+	if (clk && !IS_ERR(clk))
+		module_put(clk->owner);
+}
+EXPORT_SYMBOL(clk_put);
+
+
+int __clk_enable(struct clk *clk)
+{
+	__u16 regval16;
+	__u32 regval32;
+
+	if (clk->flags & ALWAYS_ENABLED)
+		return 0;
+
+	if (unlikely(clk->enable_reg == 0)) {
+		printk(KERN_ERR "clock.c: Enable for %s without enable code\n",
+		       clk->name);
+		return 0;
+	}
+
+	if (clk->flags & DSP_DOMAIN_CLOCK) {
+		__clk_use(&api_ck);
+	}
+
+	if (clk->flags & ENABLE_REG_32BIT) {
+		if (clk->flags & VIRTUAL_IO_ADDRESS) {
+			regval32 = __raw_readl(clk->enable_reg);
+			regval32 |= (1 << clk->enable_bit);
+			__raw_writel(regval32, clk->enable_reg);
+		} else {
+			regval32 = omap_readl(clk->enable_reg);
+			regval32 |= (1 << clk->enable_bit);
+			omap_writel(regval32, clk->enable_reg);
+		}
+	} else {
+		if (clk->flags & VIRTUAL_IO_ADDRESS) {
+			regval16 = __raw_readw(clk->enable_reg);
+			regval16 |= (1 << clk->enable_bit);
+			__raw_writew(regval16, clk->enable_reg);
+		} else {
+			regval16 = omap_readw(clk->enable_reg);
+			regval16 |= (1 << clk->enable_bit);
+			omap_writew(regval16, clk->enable_reg);
+		}
+	}
+
+	if (clk->flags & DSP_DOMAIN_CLOCK) {
+		__clk_unuse(&api_ck);
+	}
+
+	return 0;
+}
+
+
+void __clk_disable(struct clk *clk)
+{
+	__u16 regval16;
+	__u32 regval32;
+
+	if (clk->enable_reg == 0)
+		return;
+
+	if (clk->flags & DSP_DOMAIN_CLOCK) {
+		__clk_use(&api_ck);
+	}
+
+	if (clk->flags & ENABLE_REG_32BIT) {
+		if (clk->flags & VIRTUAL_IO_ADDRESS) {
+			regval32 = __raw_readl(clk->enable_reg);
+			regval32 &= ~(1 << clk->enable_bit);
+			__raw_writel(regval32, clk->enable_reg);
+		} else {
+			regval32 = omap_readl(clk->enable_reg);
+			regval32 &= ~(1 << clk->enable_bit);
+			omap_writel(regval32, clk->enable_reg);
+		}
+	} else {
+		if (clk->flags & VIRTUAL_IO_ADDRESS) {
+			regval16 = __raw_readw(clk->enable_reg);
+			regval16 &= ~(1 << clk->enable_bit);
+			__raw_writew(regval16, clk->enable_reg);
+		} else {
+			regval16 = omap_readw(clk->enable_reg);
+			regval16 &= ~(1 << clk->enable_bit);
+			omap_writew(regval16, clk->enable_reg);
+		}
+	}
+
+	if (clk->flags & DSP_DOMAIN_CLOCK) {
+		__clk_unuse(&api_ck);
+	}
+}
+
+
+void __clk_unuse(struct clk *clk)
+{
+	if (clk->usecount > 0 && !(--clk->usecount)) {
+		__clk_disable(clk);
+		if (likely(clk->parent))
+			__clk_unuse(clk->parent);
+	}
+}
+
+
+int __clk_use(struct clk *clk)
+{
+	int ret = 0;
+	if (clk->usecount++ == 0) {
+		if (likely(clk->parent))
+			ret = __clk_use(clk->parent);
+
+		if (unlikely(ret != 0)) {
+			clk->usecount--;
+			return ret;
+		}
+
+		ret = __clk_enable(clk);
+
+		if (unlikely(ret != 0) && clk->parent) {
+			__clk_unuse(clk->parent);
+			clk->usecount--;
+		}
+	}
+
+	return ret;
+}
+
+
+int clk_enable(struct clk *clk)
+{
+	unsigned long flags;
+	int ret;
+
+	spin_lock_irqsave(&clockfw_lock, flags);
+	ret = __clk_enable(clk);
+	spin_unlock_irqrestore(&clockfw_lock, flags);
+	return ret;
+}
+EXPORT_SYMBOL(clk_enable);
+
+
+void clk_disable(struct clk *clk)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&clockfw_lock, flags);
+	__clk_disable(clk);
+	spin_unlock_irqrestore(&clockfw_lock, flags);
+}
+EXPORT_SYMBOL(clk_disable);
+
+
+int clk_use(struct clk *clk)
+{
+	unsigned long flags;
+	int ret = 0;
+
+	spin_lock_irqsave(&clockfw_lock, flags);
+	ret = __clk_use(clk);
+	spin_unlock_irqrestore(&clockfw_lock, flags);
+	return ret;
+}
+EXPORT_SYMBOL(clk_use);
+
+
+void clk_unuse(struct clk *clk)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&clockfw_lock, flags);
+	__clk_unuse(clk);
+	spin_unlock_irqrestore(&clockfw_lock, flags);
+}
+EXPORT_SYMBOL(clk_unuse);
+
+
+int clk_get_usecount(struct clk *clk)
+{
+        return clk->usecount;
+}
+EXPORT_SYMBOL(clk_get_usecount);
+
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+	return clk->rate;
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+
+static __u16 verify_ckctl_value(__u16 newval)
+{
+	/* This function checks for following limitations set
+	 * by the hardware (all conditions must be true):
+	 * DSPMMU_CK == DSP_CK  or  DSPMMU_CK == DSP_CK/2
+	 * ARM_CK >= TC_CK
+	 * DSP_CK >= TC_CK
+	 * DSPMMU_CK >= TC_CK
+	 *
+	 * In addition following rules are enforced:
+	 * LCD_CK <= TC_CK
+	 * ARMPER_CK <= TC_CK
+	 *
+	 * However, maximum frequencies are not checked for!
+	 */
+	__u8 per_exp;
+	__u8 lcd_exp;
+	__u8 arm_exp;
+	__u8 dsp_exp;
+	__u8 tc_exp;
+	__u8 dspmmu_exp;
+
+	per_exp = (newval >> CKCTL_PERDIV_OFFSET) & 3;
+	lcd_exp = (newval >> CKCTL_LCDDIV_OFFSET) & 3;
+	arm_exp = (newval >> CKCTL_ARMDIV_OFFSET) & 3;
+	dsp_exp = (newval >> CKCTL_DSPDIV_OFFSET) & 3;
+	tc_exp = (newval >> CKCTL_TCDIV_OFFSET) & 3;
+	dspmmu_exp = (newval >> CKCTL_DSPMMUDIV_OFFSET) & 3;
+
+	if (dspmmu_exp < dsp_exp)
+		dspmmu_exp = dsp_exp;
+	if (dspmmu_exp > dsp_exp+1)
+		dspmmu_exp = dsp_exp+1;
+	if (tc_exp < arm_exp)
+		tc_exp = arm_exp;
+	if (tc_exp < dspmmu_exp)
+		tc_exp = dspmmu_exp;
+	if (tc_exp > lcd_exp)
+		lcd_exp = tc_exp;
+	if (tc_exp > per_exp)
+		per_exp = tc_exp;
+
+	newval &= 0xf000;
+	newval |= per_exp << CKCTL_PERDIV_OFFSET;
+	newval |= lcd_exp << CKCTL_LCDDIV_OFFSET;
+	newval |= arm_exp << CKCTL_ARMDIV_OFFSET;
+	newval |= dsp_exp << CKCTL_DSPDIV_OFFSET;
+	newval |= tc_exp << CKCTL_TCDIV_OFFSET;
+	newval |= dspmmu_exp << CKCTL_DSPMMUDIV_OFFSET;
+
+	return newval;
+}
+
+
+static int calc_dsor_exp(struct clk *clk, unsigned long rate)
+{
+	/* Note: If target frequency is too low, this function will return 4,
+	 * which is invalid value. Caller must check for this value and act
+	 * accordingly.
+	 *
+	 * Note: This function does not check for following limitations set
+	 * by the hardware (all conditions must be true):
+	 * DSPMMU_CK == DSP_CK  or  DSPMMU_CK == DSP_CK/2
+	 * ARM_CK >= TC_CK
+	 * DSP_CK >= TC_CK
+	 * DSPMMU_CK >= TC_CK
+	 */
+	unsigned long realrate;
+	struct clk *  parent;
+	unsigned  dsor_exp;
+
+	if (unlikely(!(clk->flags & RATE_CKCTL)))
+		return -EINVAL;
+
+	parent = clk->parent;
+	if (unlikely(parent == 0))
+		return -EIO;
+
+	realrate = parent->rate;
+	for (dsor_exp=0; dsor_exp<4; dsor_exp++) {
+		if (realrate <= rate)
+			break;
+
+		realrate /= 2;
+	}
+
+	return dsor_exp;
+}
+
+
+static void ckctl_recalc(struct clk *  clk)
+{
+	int dsor;
+
+	/* Calculate divisor encoded as 2-bit exponent */
+	if (clk->flags & DSP_DOMAIN_CLOCK) {
+		/* The clock control bits are in DSP domain,
+		 * so api_ck is needed for access.
+		 * Note that DSP_CKCTL virt addr = phys addr, so
+		 * we must use __raw_readw() instead of omap_readw().
+		 */
+		__clk_use(&api_ck);
+		dsor = 1 << (3 & (__raw_readw(DSP_CKCTL) >> clk->rate_offset));
+		__clk_unuse(&api_ck);
+	} else {
+		dsor = 1 << (3 & (omap_readw(ARM_CKCTL) >> clk->rate_offset));
+	}
+	if (unlikely(clk->rate == clk->parent->rate / dsor))
+		return; /* No change, quick exit */
+	clk->rate = clk->parent->rate / dsor;
+
+	if (unlikely(clk->flags & RATE_PROPAGATES))
+		propagate_rate(clk);
+}
+
+
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+	int dsor_exp;
+
+	if (clk->flags & RATE_FIXED)
+		return clk->rate;
+
+	if (clk->flags & RATE_CKCTL) {
+		dsor_exp = calc_dsor_exp(clk, rate);
+		if (dsor_exp < 0)
+			return dsor_exp;
+		if (dsor_exp > 3)
+			dsor_exp = 3;
+		return clk->parent->rate / (1 << dsor_exp);
+	}
+
+	if(clk->round_rate != 0)
+		return clk->round_rate(clk, rate);
+
+	return clk->rate;
+}
+EXPORT_SYMBOL(clk_round_rate);
+
+
+static void propagate_rate(struct clk *  clk)
+{
+	struct clk **  clkp;
+
+	for (clkp = onchip_clks; clkp < onchip_clks+ARRAY_SIZE(onchip_clks); clkp++) {
+		if (likely((*clkp)->parent != clk)) continue;
+		if (likely((*clkp)->recalc))
+			(*clkp)->recalc(*clkp);
+	}
+}
+
+
+static int select_table_rate(struct clk *  clk, unsigned long rate)
+{
+	/* Find the highest supported frequency <= rate and switch to it */
+	struct mpu_rate *  ptr;
+
+	if (clk != &virtual_ck_mpu)
+		return -EINVAL;
+
+	for (ptr = rate_table; ptr->rate; ptr++) {
+		if (ptr->xtal != ck_ref.rate)
+			continue;
+
+		/* DPLL1 cannot be reprogrammed without risking system crash */
+		if (likely(ck_dpll1.rate!=0) && ptr->pll_rate != ck_dpll1.rate)
+			continue;
+
+		/* Can check only after xtal frequency check */
+		if (ptr->rate <= rate)
+			break;
+	}
+
+	if (!ptr->rate)
+		return -EINVAL;
+
+	if (!ptr->rate)
+		return -EINVAL;
+
+	if (unlikely(ck_dpll1.rate == 0)) {
+		omap_writew(ptr->dpllctl_val, DPLL_CTL);
+		ck_dpll1.rate = ptr->pll_rate;
+	}
+	omap_writew(ptr->ckctl_val, ARM_CKCTL);
+	propagate_rate(&ck_dpll1);
+	return 0;
+}
+
+
+static long round_to_table_rate(struct clk *  clk, unsigned long rate)
+{
+	/* Find the highest supported frequency <= rate */
+	struct mpu_rate *  ptr;
+	long  highest_rate;
+
+	if (clk != &virtual_ck_mpu)
+		return -EINVAL;
+
+	highest_rate = -EINVAL;
+
+	for (ptr = rate_table; ptr->rate; ptr++) {
+		if (ptr->xtal != ck_ref.rate)
+			continue;
+
+		highest_rate = ptr->rate;
+
+		/* Can check only after xtal frequency check */
+		if (ptr->rate <= rate)
+			break;
+	}
+
+	return highest_rate;
+}
+
+
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+	int  ret = -EINVAL;
+	int  dsor_exp;
+	__u16  regval;
+	unsigned long  flags;
+
+	if (clk->flags & RATE_CKCTL) {
+		dsor_exp = calc_dsor_exp(clk, rate);
+		if (dsor_exp > 3)
+			dsor_exp = -EINVAL;
+		if (dsor_exp < 0)
+			return dsor_exp;
+
+		spin_lock_irqsave(&clockfw_lock, flags);
+		regval = omap_readw(ARM_CKCTL);
+		regval &= ~(3 << clk->rate_offset);
+		regval |= dsor_exp << clk->rate_offset;
+		regval = verify_ckctl_value(regval);
+		omap_writew(regval, ARM_CKCTL);
+		clk->rate = clk->parent->rate / (1 << dsor_exp);
+		spin_unlock_irqrestore(&clockfw_lock, flags);
+		ret = 0;
+	} else if(clk->set_rate != 0) {
+		spin_lock_irqsave(&clockfw_lock, flags);
+		ret = clk->set_rate(clk, rate);
+		spin_unlock_irqrestore(&clockfw_lock, flags);
+	}
+
+	if (unlikely(ret == 0 && (clk->flags & RATE_PROPAGATES)))
+		propagate_rate(clk);
+
+	return ret;
+}
+EXPORT_SYMBOL(clk_set_rate);
+
+
+static unsigned calc_ext_dsor(unsigned long rate)
+{
+	unsigned dsor;
+
+	/* MCLK and BCLK divisor selection is not linear:
+	 * freq = 96MHz / dsor
+	 *
+	 * RATIO_SEL range: dsor <-> RATIO_SEL
+	 * 0..6: (RATIO_SEL+2) <-> (dsor-2)
+	 * 6..48:  (8+(RATIO_SEL-6)*2) <-> ((dsor-8)/2+6)
+	 * Minimum dsor is 2 and maximum is 96. Odd divisors starting from 9
+	 * can not be used.
+	 */
+	for (dsor = 2; dsor < 96; ++dsor) {
+		if ((dsor & 1) && dsor > 8)
+		  	continue;
+		if (rate >= 96000000 / dsor)
+			break;
+	}
+	return dsor;
+}
+
+/* Only needed on 1510 */
+static int set_uart_rate(struct clk * clk, unsigned long rate)
+{
+	unsigned int val;
+
+	val = omap_readl(clk->enable_reg);
+	if (rate == 12000000)
+		val &= ~(1 << clk->enable_bit);
+	else if (rate == 48000000)
+		val |= (1 << clk->enable_bit);
+	else
+		return -EINVAL;
+	omap_writel(val, clk->enable_reg);
+	clk->rate = rate;
+
+	return 0;
+}
+
+static int set_ext_clk_rate(struct clk *  clk, unsigned long rate)
+{
+	unsigned dsor;
+	__u16 ratio_bits;
+
+	dsor = calc_ext_dsor(rate);
+	clk->rate = 96000000 / dsor;
+	if (dsor > 8)
+		ratio_bits = ((dsor - 8) / 2 + 6) << 2;
+	else
+		ratio_bits = (dsor - 2) << 2;
+
+	ratio_bits |= omap_readw(clk->enable_reg) & ~0xfd;
+	omap_writew(ratio_bits, clk->enable_reg);
+
+	return 0;
+}
+
+
+static long round_ext_clk_rate(struct clk *  clk, unsigned long rate)
+{
+	return 96000000 / calc_ext_dsor(rate);
+}
+
+
+static void init_ext_clk(struct clk *  clk)
+{
+	unsigned dsor;
+	__u16 ratio_bits;
+
+	/* Determine current rate and ensure clock is based on 96MHz APLL */
+	ratio_bits = omap_readw(clk->enable_reg) & ~1;
+	omap_writew(ratio_bits, clk->enable_reg);
+
+	ratio_bits = (ratio_bits & 0xfc) >> 2;
+	if (ratio_bits > 6)
+		dsor = (ratio_bits - 6) * 2 + 8;
+	else
+		dsor = ratio_bits + 2;
+
+	clk-> rate = 96000000 / dsor;
+}
+
+
+int clk_register(struct clk *clk)
+{
+	down(&clocks_sem);
+	list_add(&clk->node, &clocks);
+	if (clk->init)
+		clk->init(clk);
+	up(&clocks_sem);
+	return 0;
+}
+EXPORT_SYMBOL(clk_register);
+
+void clk_unregister(struct clk *clk)
+{
+	down(&clocks_sem);
+	list_del(&clk->node);
+	up(&clocks_sem);
+}
+EXPORT_SYMBOL(clk_unregister);
+
+#ifdef CONFIG_OMAP_RESET_CLOCKS
+/*
+ * Resets some clocks that may be left on from bootloader,
+ * but leaves serial clocks on. See also omap_late_clk_reset().
+ */
+static inline void omap_early_clk_reset(void)
+{
+	//omap_writel(0x3 << 29, MOD_CONF_CTRL_0);
+}
+#else
+#define omap_early_clk_reset()	{}
+#endif
+
+int __init clk_init(void)
+{
+	struct clk **  clkp;
+	const struct omap_clock_config *info;
+	int crystal_type = 0; /* Default 12 MHz */
+
+	omap_early_clk_reset();
+
+	for (clkp = onchip_clks; clkp < onchip_clks+ARRAY_SIZE(onchip_clks); clkp++) {
+		if (((*clkp)->flags &CLOCK_IN_OMAP1510) && cpu_is_omap1510()) {
+			clk_register(*clkp);
+			continue;
+		}
+
+		if (((*clkp)->flags &CLOCK_IN_OMAP16XX) && cpu_is_omap16xx()) {
+			clk_register(*clkp);
+			continue;
+		}
+
+		if (((*clkp)->flags &CLOCK_IN_OMAP730) && cpu_is_omap730()) {
+			clk_register(*clkp);
+			continue;
+		}
+	}
+
+	info = omap_get_config(OMAP_TAG_CLOCK, struct omap_clock_config);
+	if (info != NULL) {
+		if (!cpu_is_omap1510())
+			crystal_type = info->system_clock_type;
+	}
+
+#if defined(CONFIG_ARCH_OMAP730)
+	ck_ref.rate = 13000000;
+#elif defined(CONFIG_ARCH_OMAP16XX)
+	if (crystal_type == 2)
+		ck_ref.rate = 19200000;
+#endif
+
+	printk("Clocks: ARM_SYSST: 0x%04x DPLL_CTL: 0x%04x ARM_CKCTL: 0x%04x\n",
+	       omap_readw(ARM_SYSST), omap_readw(DPLL_CTL),
+	       omap_readw(ARM_CKCTL));
+
+	/* We want to be in syncronous scalable mode */
+	omap_writew(0x1000, ARM_SYSST);
+
+#ifdef CONFIG_OMAP_CLOCKS_SET_BY_BOOTLOADER
+	/* Use values set by bootloader. Determine PLL rate and recalculate
+	 * dependent clocks as if kernel had changed PLL or divisors.
+	 */
+	{
+		unsigned pll_ctl_val = omap_readw(DPLL_CTL);
+
+		ck_dpll1.rate = ck_ref.rate; /* Base xtal rate */
+		if (pll_ctl_val & 0x10) {
+			/* PLL enabled, apply multiplier and divisor */
+			if (pll_ctl_val & 0xf80)
+				ck_dpll1.rate *= (pll_ctl_val & 0xf80) >> 7;
+			ck_dpll1.rate /= ((pll_ctl_val & 0x60) >> 5) + 1;
+		} else {
+			/* PLL disabled, apply bypass divisor */
+			switch (pll_ctl_val & 0xc) {
+			case 0:
+				break;
+			case 0x4:
+				ck_dpll1.rate /= 2;
+				break;
+			default:
+				ck_dpll1.rate /= 4;
+				break;
+			}
+		}
+	}
+	propagate_rate(&ck_dpll1);
+#else
+	/* Find the highest supported frequency and enable it */
+	if (select_table_rate(&virtual_ck_mpu, ~0)) {
+		printk(KERN_ERR "System frequencies not set. Check your config.\n");
+		/* Guess sane values (60MHz) */
+		omap_writew(0x2290, DPLL_CTL);
+		omap_writew(0x1005, ARM_CKCTL);
+		ck_dpll1.rate = 60000000;
+		propagate_rate(&ck_dpll1);
+	}
+#endif
+	/* Cache rates for clocks connected to ck_ref (not dpll1) */
+	propagate_rate(&ck_ref);
+	printk(KERN_INFO "Clocking rate (xtal/DPLL1/MPU): %ld.%01ld/%ld/%ld MHz\n",
+	       ck_ref.rate / 1000000, (ck_ref.rate / 100000) % 10,
+	       ck_dpll1.rate, arm_ck.rate);
+
+#ifdef CONFIG_MACH_OMAP_PERSEUS2
+	/* Select slicer output as OMAP input clock */
+	omap_writew(omap_readw(OMAP730_PCC_UPLD_CTRL) & ~0x1, OMAP730_PCC_UPLD_CTRL);
+#endif
+
+	/* Turn off DSP and ARM_TIMXO. Make sure ARM_INTHCK is not divided */
+	omap_writew(omap_readw(ARM_CKCTL) & 0x0fff, ARM_CKCTL);
+
+	/* Put DSP/MPUI into reset until needed */
+	omap_writew(0, ARM_RSTCT1);
+	omap_writew(1, ARM_RSTCT2);
+	omap_writew(0x400, ARM_IDLECT1);
+
+	/*
+	 * According to OMAP5910 Erratum SYS_DMA_1, bit DMACK_REQ (bit 8)
+	 * of the ARM_IDLECT2 register must be set to zero. The power-on
+	 * default value of this bit is one.
+	 */
+	omap_writew(0x0000, ARM_IDLECT2);	/* Turn LCD clock off also */
+
+	/*
+	 * Only enable those clocks we will need, let the drivers
+	 * enable other clocks as necessary
+	 */
+	clk_use(&armper_ck);
+	clk_use(&armxor_ck);
+	clk_use(&armtim_ck);
+
+	if (cpu_is_omap1510())
+		clk_enable(&arm_gpio_ck);
+
+	return 0;
+}
+
+
+#ifdef CONFIG_OMAP_RESET_CLOCKS
+
+static int __init omap_late_clk_reset(void)
+{
+	/* Turn off all unused clocks */
+	struct clk *p;
+	__u32 regval32;
+
+	omap_writew(0, SOFT_REQ_REG);
+	omap_writew(0, SOFT_REQ_REG2);
+
+	list_for_each_entry(p, &clocks, node) {
+		if (p->usecount > 0 || (p->flags & ALWAYS_ENABLED) ||
+			p->enable_reg == 0)
+			continue;
+
+		/* Assume no DSP clocks have been activated by bootloader */
+		if (p->flags & DSP_DOMAIN_CLOCK)
+			continue;
+
+		/* Is the clock already disabled? */
+		if (p->flags & ENABLE_REG_32BIT) {
+			if (p->flags & VIRTUAL_IO_ADDRESS)
+				regval32 = __raw_readl(p->enable_reg);
+			else
+				regval32 = omap_readl(p->enable_reg);
+		} else {
+			if (p->flags & VIRTUAL_IO_ADDRESS)
+				regval32 = __raw_readw(p->enable_reg);
+			else
+				regval32 = omap_readw(p->enable_reg);
+		}
+
+		if ((regval32 & (1 << p->enable_bit)) == 0)
+			continue;
+
+		/* FIXME: This clock seems to be necessary but no-one
+		 * has asked for its activation. */
+		if (p == &tc2_ck         // FIX: pm.c (SRAM), CCP, Camera
+		    || p == &ck_dpll1out // FIX: SoSSI, SSR
+		    || p == &arm_gpio_ck // FIX: GPIO code for 1510
+		    ) {
+			printk(KERN_INFO "FIXME: Clock \"%s\" seems unused\n",
+			       p->name);
+			continue;
+		}
+
+		printk(KERN_INFO "Disabling unused clock \"%s\"... ", p->name);
+		__clk_disable(p);
+		printk(" done\n");
+	}
+
+	return 0;
+}
+
+late_initcall(omap_late_clk_reset);
+
+#endif
diff --git a/arch/arm/plat-omap/clock.h b/arch/arm/plat-omap/clock.h
new file mode 100644
--- /dev/null
+++ b/arch/arm/plat-omap/clock.h
@@ -0,0 +1,120 @@
+/*
+ *  linux/arch/arm/plat-omap/clock.h
+ *
+ *  Copyright (C) 2004 Nokia corporation
+ *  Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
+ *  Based on clocks.h by Tony Lindgren, Gordon McNutt and RidgeRun, Inc
+ *
+ * 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.
+ */
+
+#ifndef __ARCH_ARM_OMAP_CLOCK_H
+#define __ARCH_ARM_OMAP_CLOCK_H
+
+struct module;
+
+struct clk {
+	struct list_head	node;
+	struct module		*owner;
+	const char		*name;
+	struct clk		*parent;
+	unsigned long		rate;
+	__s8			usecount;
+	__u16			flags;
+	__u32			enable_reg;
+	__u8			enable_bit;
+	__u8			rate_offset;
+	void			(*recalc)(struct clk *);
+	int			(*set_rate)(struct clk *, unsigned long);
+	long			(*round_rate)(struct clk *, unsigned long);
+	void			(*init)(struct clk *);
+};
+
+
+struct mpu_rate {
+	unsigned long		rate;
+	unsigned long		xtal;
+	unsigned long		pll_rate;
+	__u16			ckctl_val;
+	__u16			dpllctl_val;
+};
+
+
+/* Clock flags */
+#define RATE_CKCTL		1
+#define RATE_FIXED		2
+#define RATE_PROPAGATES		4
+#define VIRTUAL_CLOCK		8
+#define ALWAYS_ENABLED		16
+#define ENABLE_REG_32BIT	32
+#define CLOCK_IN_OMAP16XX	64
+#define CLOCK_IN_OMAP1510	128
+#define CLOCK_IN_OMAP730	256
+#define DSP_DOMAIN_CLOCK	512
+#define VIRTUAL_IO_ADDRESS	1024
+
+/* ARM_CKCTL bit shifts */
+#define CKCTL_PERDIV_OFFSET	0
+#define CKCTL_LCDDIV_OFFSET	2
+#define CKCTL_ARMDIV_OFFSET	4
+#define CKCTL_DSPDIV_OFFSET	6
+#define CKCTL_TCDIV_OFFSET	8
+#define CKCTL_DSPMMUDIV_OFFSET	10
+/*#define ARM_TIMXO		12*/
+#define EN_DSPCK		13
+/*#define ARM_INTHCK_SEL	14*/ /* Divide-by-2 for mpu inth_ck */
+/* DSP_CKCTL bit shifts */
+#define CKCTL_DSPPERDIV_OFFSET	0
+
+/* ARM_IDLECT1 bit shifts */
+/*#define IDLWDT_ARM	0*/
+/*#define IDLXORP_ARM	1*/
+/*#define IDLPER_ARM	2*/
+/*#define IDLLCD_ARM	3*/
+/*#define IDLLB_ARM	4*/
+/*#define IDLHSAB_ARM	5*/
+/*#define IDLIF_ARM	6*/
+/*#define IDLDPLL_ARM	7*/
+/*#define IDLAPI_ARM	8*/
+/*#define IDLTIM_ARM	9*/
+/*#define SETARM_IDLE	11*/
+
+/* ARM_IDLECT2 bit shifts */
+#define EN_WDTCK	0
+#define EN_XORPCK	1
+#define EN_PERCK	2
+#define EN_LCDCK	3
+#define EN_LBCK		4 /* Not on 1610/1710 */
+/*#define EN_HSABCK	5*/
+#define EN_APICK	6
+#define EN_TIMCK	7
+#define DMACK_REQ	8
+#define EN_GPIOCK	9 /* Not on 1610/1710 */
+/*#define EN_LBFREECK	10*/
+#define EN_CKOUT_ARM	11
+
+/* ARM_IDLECT3 bit shifts */
+#define EN_OCPI_CK	0
+#define EN_TC1_CK	2
+#define EN_TC2_CK	4
+
+/* DSP_IDLECT2 bit shifts (0,1,2 are same as for ARM_IDLECT2) */
+#define EN_DSPTIMCK	5
+
+/* Various register defines for clock controls scattered around OMAP chip */
+#define USB_MCLK_EN_BIT		4	/* In ULPD_CLKC_CTRL */
+#define USB_HOST_HHC_UHOST_EN	9	/* In MOD_CONF_CTRL_0 */
+#define SWD_ULPD_PLL_CLK_REQ	1	/* In SWD_CLK_DIV_CTRL_SEL */
+#define COM_ULPD_PLL_CLK_REQ	1	/* In COM_CLK_DIV_CTRL_SEL */
+#define SWD_CLK_DIV_CTRL_SEL	0xfffe0874
+#define COM_CLK_DIV_CTRL_SEL	0xfffe0878
+#define SOFT_REQ_REG		0xfffe0834
+#define SOFT_REQ_REG2		0xfffe0880
+
+int clk_register(struct clk *clk);
+void clk_unregister(struct clk *clk);
+int clk_init(void);
+
+#endif
diff --git a/arch/arm/plat-omap/common.c b/arch/arm/plat-omap/common.c
new file mode 100644
--- /dev/null
+++ b/arch/arm/plat-omap/common.c
@@ -0,0 +1,135 @@
+/*
+ * linux/arch/arm/plat-omap/common.c
+ *
+ * Code common to all OMAP machines.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/console.h>
+#include <linux/serial.h>
+#include <linux/tty.h>
+#include <linux/serial_8250.h>
+#include <linux/serial_reg.h>
+
+#include <asm/hardware.h>
+#include <asm/system.h>
+#include <asm/pgtable.h>
+#include <asm/mach/map.h>
+#include <asm/hardware/clock.h>
+#include <asm/io.h>
+#include <asm/mach-types.h>
+
+#include <asm/arch/board.h>
+#include <asm/arch/mux.h>
+#include <asm/arch/fpga.h>
+
+#include "clock.h"
+
+#define NO_LENGTH_CHECK 0xffffffff
+
+extern int omap_bootloader_tag_len;
+extern u8 omap_bootloader_tag[];
+
+struct omap_board_config_kernel *omap_board_config;
+int omap_board_config_size = 0;
+
+static const void *get_config(u16 tag, size_t len, int skip, size_t *len_out)
+{
+	struct omap_board_config_kernel *kinfo = NULL;
+	int i;
+
+#ifdef CONFIG_OMAP_BOOT_TAG
+	struct omap_board_config_entry *info = NULL;
+
+	if (omap_bootloader_tag_len > 4)
+		info = (struct omap_board_config_entry *) omap_bootloader_tag;
+	while (info != NULL) {
+		u8 *next;
+
+		if (info->tag == tag) {
+			if (skip == 0)
+				break;
+			skip--;
+		}
+
+		if ((info->len & 0x03) != 0) {
+			/* We bail out to avoid an alignment fault */
+			printk(KERN_ERR "OMAP peripheral config: Length (%d) not word-aligned (tag %04x)\n",
+			       info->len, info->tag);
+			return NULL;
+		}
+		next = (u8 *) info + sizeof(*info) + info->len;
+		if (next >= omap_bootloader_tag + omap_bootloader_tag_len)
+			info = NULL;
+		else
+			info = (struct omap_board_config_entry *) next;
+	}
+	if (info != NULL) {
+		/* Check the length as a lame attempt to check for
+		 * binary inconsistancy. */
+		if (len != NO_LENGTH_CHECK) {
+			/* Word-align len */
+			if (len & 0x03)
+				len = (len + 3) & ~0x03;
+			if (info->len != len) {
+				printk(KERN_ERR "OMAP peripheral config: Length mismatch with tag %x (want %d, got %d)\n",
+				       tag, len, info->len);
+				return NULL;
+			}
+		}
+		if (len_out != NULL)
+			*len_out = info->len;
+		return info->data;
+	}
+#endif
+	/* Try to find the config from the board-specific structures
+	 * in the kernel. */
+	for (i = 0; i < omap_board_config_size; i++) {
+		if (omap_board_config[i].tag == tag) {
+			kinfo = &omap_board_config[i];
+			break;
+		}
+	}
+	if (kinfo == NULL)
+		return NULL;
+	return kinfo->data;
+}
+
+const void *__omap_get_config(u16 tag, size_t len, int nr)
+{
+        return get_config(tag, len, nr, NULL);
+}
+EXPORT_SYMBOL(__omap_get_config);
+
+const void *omap_get_var_config(u16 tag, size_t *len)
+{
+        return get_config(tag, NO_LENGTH_CHECK, 0, len);
+}
+EXPORT_SYMBOL(omap_get_var_config);
+
+static int __init omap_add_serial_console(void)
+{
+	const struct omap_serial_console_config *info;
+
+	info = omap_get_config(OMAP_TAG_SERIAL_CONSOLE,
+			       struct omap_serial_console_config);
+	if (info != NULL && info->console_uart) {
+		static char speed[11], *opt = NULL;
+
+		if (info->console_speed) {
+			snprintf(speed, sizeof(speed), "%u", info->console_speed);
+			opt = speed;
+		}
+		return add_preferred_console("ttyS", info->console_uart - 1, opt);
+	}
+	return 0;
+}
+console_initcall(omap_add_serial_console);
diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/plat-omap/cpu-omap.c
new file mode 100644
--- /dev/null
+++ b/arch/arm/plat-omap/cpu-omap.c
@@ -0,0 +1,128 @@
+/*
+ *  linux/arch/arm/plat-omap/cpu-omap.c
+ *
+ *  CPU frequency scaling for OMAP
+ *
+ *  Copyright (C) 2005 Nokia Corporation
+ *  Written by Tony Lindgren <tony@atomide.com>
+ *
+ *  Based on cpu-sa1110.c, Copyright (C) 2001 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/cpufreq.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/err.h>
+
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/io.h>
+#include <asm/system.h>
+
+#include <asm/hardware/clock.h>
+
+/* TODO: Add support for SDRAM timing changes */
+
+int omap_verify_speed(struct cpufreq_policy *policy)
+{
+	struct clk * mpu_clk;
+
+	if (policy->cpu)
+		return -EINVAL;
+
+	cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
+				     policy->cpuinfo.max_freq);
+	mpu_clk = clk_get(NULL, "mpu");
+	if (IS_ERR(mpu_clk))
+		return PTR_ERR(mpu_clk);
+	policy->min = clk_round_rate(mpu_clk, policy->min * 1000) / 1000;
+	policy->max = clk_round_rate(mpu_clk, policy->max * 1000) / 1000;
+	cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
+				     policy->cpuinfo.max_freq);
+	clk_put(mpu_clk);
+
+	return 0;
+}
+
+unsigned int omap_getspeed(unsigned int cpu)
+{
+	struct clk * mpu_clk;
+	unsigned long rate;
+
+	if (cpu)
+		return 0;
+
+	mpu_clk = clk_get(NULL, "mpu");
+	if (IS_ERR(mpu_clk))
+		return 0;
+	rate = clk_get_rate(mpu_clk) / 1000;
+	clk_put(mpu_clk);
+
+	return rate;
+}
+
+static int omap_target(struct cpufreq_policy *policy,
+		       unsigned int target_freq,
+		       unsigned int relation)
+{
+	struct clk * mpu_clk;
+	struct cpufreq_freqs freqs;
+	int ret = 0;
+
+	mpu_clk = clk_get(NULL, "mpu");
+	if (IS_ERR(mpu_clk))
+		return PTR_ERR(mpu_clk);
+
+	freqs.old = omap_getspeed(0);
+	freqs.new = clk_round_rate(mpu_clk, target_freq * 1000) / 1000;
+	freqs.cpu = 0;
+
+	cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+	ret = clk_set_rate(mpu_clk, target_freq * 1000);
+	cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+	clk_put(mpu_clk);
+
+	return ret;
+}
+
+static int __init omap_cpu_init(struct cpufreq_policy *policy)
+{
+	struct clk * mpu_clk;
+
+	mpu_clk = clk_get(NULL, "mpu");
+	if (IS_ERR(mpu_clk))
+		return PTR_ERR(mpu_clk);
+
+	if (policy->cpu != 0)
+		return -EINVAL;
+	policy->cur = policy->min = policy->max = omap_getspeed(0);
+	policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
+	policy->cpuinfo.min_freq = clk_round_rate(mpu_clk, 0) / 1000;
+	policy->cpuinfo.max_freq = clk_round_rate(mpu_clk, 216000000) / 1000;
+	policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
+	clk_put(mpu_clk);
+
+	return 0;
+}
+
+static struct cpufreq_driver omap_driver = {
+	.flags		= CPUFREQ_STICKY,
+	.verify		= omap_verify_speed,
+	.target		= omap_target,
+	.get		= omap_getspeed,
+	.init		= omap_cpu_init,
+	.name		= "omap",
+};
+
+static int __init omap_cpufreq_init(void)
+{
+	return cpufreq_register_driver(&omap_driver);
+}
+
+arch_initcall(omap_cpufreq_init);
diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c
new file mode 100644
--- /dev/null
+++ b/arch/arm/plat-omap/dma.c
@@ -0,0 +1,1116 @@
+/*
+ * linux/arch/arm/plat-omap/dma.c
+ *
+ * Copyright (C) 2003 Nokia Corporation
+ * Author: Juha Yrjölä <juha.yrjola@nokia.com>
+ * DMA channel linking for 1610 by Samuel Ortiz <samuel.ortiz@nokia.com>
+ * Graphics DMA and LCD DMA graphics tranformations
+ * by Imre Deak <imre.deak@nokia.com>
+ * Some functions based on earlier dma-omap.c Copyright (C) 2001 RidgeRun, Inc.
+ *
+ * Support functions for the OMAP internal DMA channels.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <asm/hardware.h>
+#include <asm/dma.h>
+#include <asm/io.h>
+
+#include <asm/arch/tc.h>
+
+#define OMAP_DMA_ACTIVE		0x01
+
+#define OMAP_DMA_CCR_EN		(1 << 7)
+
+#define OMAP_FUNC_MUX_ARM_BASE	(0xfffe1000 + 0xec)
+
+static int enable_1510_mode = 0;
+
+struct omap_dma_lch {
+	int next_lch;
+	int dev_id;
+	u16 saved_csr;
+	u16 enabled_irqs;
+	const char *dev_name;
+	void (* callback)(int lch, u16 ch_status, void *data);
+	void *data;
+	long flags;
+};
+
+static int dma_chan_count;
+
+static spinlock_t dma_chan_lock;
+static struct omap_dma_lch dma_chan[OMAP_LOGICAL_DMA_CH_COUNT];
+
+const static u8 dma_irq[OMAP_LOGICAL_DMA_CH_COUNT] = {
+	INT_DMA_CH0_6, INT_DMA_CH1_7, INT_DMA_CH2_8, INT_DMA_CH3,
+	INT_DMA_CH4, INT_DMA_CH5, INT_1610_DMA_CH6, INT_1610_DMA_CH7,
+	INT_1610_DMA_CH8, INT_1610_DMA_CH9, INT_1610_DMA_CH10,
+	INT_1610_DMA_CH11, INT_1610_DMA_CH12, INT_1610_DMA_CH13,
+	INT_1610_DMA_CH14, INT_1610_DMA_CH15, INT_DMA_LCD
+};
+
+static inline int get_gdma_dev(int req)
+{
+	u32 reg = OMAP_FUNC_MUX_ARM_BASE + ((req - 1) / 5) * 4;
+	int shift = ((req - 1) % 5) * 6;
+
+	return ((omap_readl(reg) >> shift) & 0x3f) + 1;
+}
+
+static inline void set_gdma_dev(int req, int dev)
+{
+	u32 reg = OMAP_FUNC_MUX_ARM_BASE + ((req - 1) / 5) * 4;
+	int shift = ((req - 1) % 5) * 6;
+	u32 l;
+
+	l = omap_readl(reg);
+	l &= ~(0x3f << shift);
+	l |= (dev - 1) << shift;
+	omap_writel(l, reg);
+}
+
+static void clear_lch_regs(int lch)
+{
+	int i;
+	u32 lch_base = OMAP_DMA_BASE + lch * 0x40;
+
+	for (i = 0; i < 0x2c; i += 2)
+		omap_writew(0, lch_base + i);
+}
+
+void omap_set_dma_priority(int dst_port, int priority)
+{
+	unsigned long reg;
+	u32 l;
+
+	switch (dst_port) {
+	case OMAP_DMA_PORT_OCP_T1:	/* FFFECC00 */
+		reg = OMAP_TC_OCPT1_PRIOR;
+		break;
+	case OMAP_DMA_PORT_OCP_T2:	/* FFFECCD0 */
+		reg = OMAP_TC_OCPT2_PRIOR;
+		break;
+	case OMAP_DMA_PORT_EMIFF:	/* FFFECC08 */
+		reg = OMAP_TC_EMIFF_PRIOR;
+		break;
+	case OMAP_DMA_PORT_EMIFS:	/* FFFECC04 */
+		reg = OMAP_TC_EMIFS_PRIOR;
+		break;
+	default:
+		BUG();
+		return;
+	}
+	l = omap_readl(reg);
+	l &= ~(0xf << 8);
+	l |= (priority & 0xf) << 8;
+	omap_writel(l, reg);
+}
+
+void omap_set_dma_transfer_params(int lch, int data_type, int elem_count,
+				  int frame_count, int sync_mode)
+{
+	u16 w;
+
+	w = omap_readw(OMAP_DMA_CSDP(lch));
+	w &= ~0x03;
+	w |= data_type;
+	omap_writew(w, OMAP_DMA_CSDP(lch));
+
+	w = omap_readw(OMAP_DMA_CCR(lch));
+	w &= ~(1 << 5);
+	if (sync_mode == OMAP_DMA_SYNC_FRAME)
+		w |= 1 << 5;
+	omap_writew(w, OMAP_DMA_CCR(lch));
+
+	w = omap_readw(OMAP_DMA_CCR2(lch));
+	w &= ~(1 << 2);
+	if (sync_mode == OMAP_DMA_SYNC_BLOCK)
+		w |= 1 << 2;
+	omap_writew(w, OMAP_DMA_CCR2(lch));
+
+	omap_writew(elem_count, OMAP_DMA_CEN(lch));
+	omap_writew(frame_count, OMAP_DMA_CFN(lch));
+
+}
+void omap_set_dma_color_mode(int lch, enum omap_dma_color_mode mode, u32 color)
+{
+	u16 w;
+
+	BUG_ON(omap_dma_in_1510_mode());
+
+	w = omap_readw(OMAP_DMA_CCR2(lch)) & ~0x03;
+	switch (mode) {
+	case OMAP_DMA_CONSTANT_FILL:
+		w |= 0x01;
+		break;
+	case OMAP_DMA_TRANSPARENT_COPY:
+		w |= 0x02;
+		break;
+	case OMAP_DMA_COLOR_DIS:
+		break;
+	default:
+		BUG();
+	}
+	omap_writew(w, OMAP_DMA_CCR2(lch));
+
+	w = omap_readw(OMAP_DMA_LCH_CTRL(lch)) & ~0x0f;
+	/* Default is channel type 2D */
+	if (mode) {
+		omap_writew((u16)color, OMAP_DMA_COLOR_L(lch));
+		omap_writew((u16)(color >> 16), OMAP_DMA_COLOR_U(lch));
+		w |= 1;		/* Channel type G */
+	}
+	omap_writew(w, OMAP_DMA_LCH_CTRL(lch));
+}
+
+
+void omap_set_dma_src_params(int lch, int src_port, int src_amode,
+			     unsigned long src_start)
+{
+	u16 w;
+
+	w = omap_readw(OMAP_DMA_CSDP(lch));
+	w &= ~(0x1f << 2);
+	w |= src_port << 2;
+	omap_writew(w, OMAP_DMA_CSDP(lch));
+
+	w = omap_readw(OMAP_DMA_CCR(lch));
+	w &= ~(0x03 << 12);
+	w |= src_amode << 12;
+	omap_writew(w, OMAP_DMA_CCR(lch));
+
+	omap_writew(src_start >> 16, OMAP_DMA_CSSA_U(lch));
+	omap_writew(src_start, OMAP_DMA_CSSA_L(lch));
+}
+
+void omap_set_dma_src_index(int lch, int eidx, int fidx)
+{
+	omap_writew(eidx, OMAP_DMA_CSEI(lch));
+	omap_writew(fidx, OMAP_DMA_CSFI(lch));
+}
+
+void omap_set_dma_src_data_pack(int lch, int enable)
+{
+	u16 w;
+
+	w = omap_readw(OMAP_DMA_CSDP(lch)) & ~(1 << 6);
+	w |= enable ? (1 << 6) : 0;
+	omap_writew(w, OMAP_DMA_CSDP(lch));
+}
+
+void omap_set_dma_src_burst_mode(int lch, enum omap_dma_burst_mode burst_mode)
+{
+	u16 w;
+
+	w = omap_readw(OMAP_DMA_CSDP(lch)) & ~(0x03 << 7);
+	switch (burst_mode) {
+	case OMAP_DMA_DATA_BURST_DIS:
+		break;
+	case OMAP_DMA_DATA_BURST_4:
+		w |= (0x01 << 7);
+		break;
+	case OMAP_DMA_DATA_BURST_8:
+		/* not supported by current hardware
+		 * w |= (0x03 << 7);
+		 * fall through
+		 */
+	default:
+		BUG();
+	}
+	omap_writew(w, OMAP_DMA_CSDP(lch));
+}
+
+void omap_set_dma_dest_params(int lch, int dest_port, int dest_amode,
+			      unsigned long dest_start)
+{
+	u16 w;
+
+	w = omap_readw(OMAP_DMA_CSDP(lch));
+	w &= ~(0x1f << 9);
+	w |= dest_port << 9;
+	omap_writew(w, OMAP_DMA_CSDP(lch));
+
+	w = omap_readw(OMAP_DMA_CCR(lch));
+	w &= ~(0x03 << 14);
+	w |= dest_amode << 14;
+	omap_writew(w, OMAP_DMA_CCR(lch));
+
+	omap_writew(dest_start >> 16, OMAP_DMA_CDSA_U(lch));
+	omap_writew(dest_start, OMAP_DMA_CDSA_L(lch));
+}
+
+void omap_set_dma_dest_index(int lch, int eidx, int fidx)
+{
+	omap_writew(eidx, OMAP_DMA_CDEI(lch));
+	omap_writew(fidx, OMAP_DMA_CDFI(lch));
+}
+
+void omap_set_dma_dest_data_pack(int lch, int enable)
+{
+	u16 w;
+
+	w = omap_readw(OMAP_DMA_CSDP(lch)) & ~(1 << 13);
+	w |= enable ? (1 << 13) : 0;
+	omap_writew(w, OMAP_DMA_CSDP(lch));
+}
+
+void omap_set_dma_dest_burst_mode(int lch, enum omap_dma_burst_mode burst_mode)
+{
+	u16 w;
+
+	w = omap_readw(OMAP_DMA_CSDP(lch)) & ~(0x03 << 14);
+	switch (burst_mode) {
+	case OMAP_DMA_DATA_BURST_DIS:
+		break;
+	case OMAP_DMA_DATA_BURST_4:
+		w |= (0x01 << 14);
+		break;
+	case OMAP_DMA_DATA_BURST_8:
+		w |= (0x03 << 14);
+		break;
+	default:
+		printk(KERN_ERR "Invalid DMA burst mode\n");
+		BUG();
+		return;
+	}
+	omap_writew(w, OMAP_DMA_CSDP(lch));
+}
+
+static inline void init_intr(int lch)
+{
+	u16 w;
+
+	/* Read CSR to make sure it's cleared. */
+	w = omap_readw(OMAP_DMA_CSR(lch));
+	/* Enable some nice interrupts. */
+	omap_writew(dma_chan[lch].enabled_irqs, OMAP_DMA_CICR(lch));
+	dma_chan[lch].flags |= OMAP_DMA_ACTIVE;
+}
+
+static inline void enable_lnk(int lch)
+{
+	u16 w;
+
+	/* Clear the STOP_LNK bits */
+	w = omap_readw(OMAP_DMA_CLNK_CTRL(lch));
+	w &= ~(1 << 14);
+	omap_writew(w, OMAP_DMA_CLNK_CTRL(lch));
+
+	/* And set the ENABLE_LNK bits */
+	if (dma_chan[lch].next_lch != -1)
+		omap_writew(dma_chan[lch].next_lch | (1 << 15),
+			    OMAP_DMA_CLNK_CTRL(lch));
+}
+
+static inline void disable_lnk(int lch)
+{
+	u16 w;
+
+	/* Disable interrupts */
+	omap_writew(0, OMAP_DMA_CICR(lch));
+
+	/* Set the STOP_LNK bit */
+	w = omap_readw(OMAP_DMA_CLNK_CTRL(lch));
+	w |= (1 << 14);
+	w = omap_writew(w, OMAP_DMA_CLNK_CTRL(lch));
+
+	dma_chan[lch].flags &= ~OMAP_DMA_ACTIVE;
+}
+
+void omap_start_dma(int lch)
+{
+	u16 w;
+
+	if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) {
+		int next_lch, cur_lch;
+		char dma_chan_link_map[OMAP_LOGICAL_DMA_CH_COUNT];
+
+		dma_chan_link_map[lch] = 1;
+		/* Set the link register of the first channel */
+		enable_lnk(lch);
+
+		memset(dma_chan_link_map, 0, sizeof(dma_chan_link_map));
+		cur_lch = dma_chan[lch].next_lch;
+		do {
+			next_lch = dma_chan[cur_lch].next_lch;
+
+                        /* The loop case: we've been here already */
+			if (dma_chan_link_map[cur_lch])
+				break;
+			/* Mark the current channel */
+			dma_chan_link_map[cur_lch] = 1;
+
+			enable_lnk(cur_lch);
+			init_intr(cur_lch);
+
+			cur_lch = next_lch;
+		} while (next_lch != -1);
+	}
+
+	init_intr(lch);
+
+	w = omap_readw(OMAP_DMA_CCR(lch));
+	w |= OMAP_DMA_CCR_EN;
+	omap_writew(w, OMAP_DMA_CCR(lch));
+	dma_chan[lch].flags |= OMAP_DMA_ACTIVE;
+}
+
+void omap_stop_dma(int lch)
+{
+	u16 w;
+
+	if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) {
+		int next_lch, cur_lch = lch;
+		char dma_chan_link_map[OMAP_LOGICAL_DMA_CH_COUNT];
+
+		memset(dma_chan_link_map, 0, sizeof(dma_chan_link_map));
+		do {
+			/* The loop case: we've been here already */
+			if (dma_chan_link_map[cur_lch])
+				break;
+			/* Mark the current channel */
+			dma_chan_link_map[cur_lch] = 1;
+
+			disable_lnk(cur_lch);
+
+			next_lch = dma_chan[cur_lch].next_lch;
+			cur_lch = next_lch;
+		} while (next_lch != -1);
+
+		return;
+	}
+	/* Disable all interrupts on the channel */
+	omap_writew(0, OMAP_DMA_CICR(lch));
+
+	w = omap_readw(OMAP_DMA_CCR(lch));
+	w &= ~OMAP_DMA_CCR_EN;
+	omap_writew(w, OMAP_DMA_CCR(lch));
+	dma_chan[lch].flags &= ~OMAP_DMA_ACTIVE;
+}
+
+void omap_enable_dma_irq(int lch, u16 bits)
+{
+	dma_chan[lch].enabled_irqs |= bits;
+}
+
+void omap_disable_dma_irq(int lch, u16 bits)
+{
+	dma_chan[lch].enabled_irqs &= ~bits;
+}
+
+static int dma_handle_ch(int ch)
+{
+	u16 csr;
+
+	if (enable_1510_mode && ch >= 6) {
+		csr = dma_chan[ch].saved_csr;
+		dma_chan[ch].saved_csr = 0;
+	} else
+		csr = omap_readw(OMAP_DMA_CSR(ch));
+	if (enable_1510_mode && ch <= 2 && (csr >> 7) != 0) {
+		dma_chan[ch + 6].saved_csr = csr >> 7;
+		csr &= 0x7f;
+	}
+	if (!csr)
+		return 0;
+	if (unlikely(dma_chan[ch].dev_id == -1)) {
+		printk(KERN_WARNING "Spurious interrupt from DMA channel %d (CSR %04x)\n",
+		       ch, csr);
+		return 0;
+	}
+	if (unlikely(csr & OMAP_DMA_TOUT_IRQ))
+		printk(KERN_WARNING "DMA timeout with device %d\n", dma_chan[ch].dev_id);
+	if (unlikely(csr & OMAP_DMA_DROP_IRQ))
+		printk(KERN_WARNING "DMA synchronization event drop occurred with device %d\n",
+		       dma_chan[ch].dev_id);
+	if (likely(csr & OMAP_DMA_BLOCK_IRQ))
+		dma_chan[ch].flags &= ~OMAP_DMA_ACTIVE;
+	if (likely(dma_chan[ch].callback != NULL))
+		dma_chan[ch].callback(ch, csr, dma_chan[ch].data);
+	return 1;
+}
+
+static irqreturn_t dma_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
+{
+	int ch = ((int) dev_id) - 1;
+	int handled = 0;
+
+	for (;;) {
+		int handled_now = 0;
+
+		handled_now += dma_handle_ch(ch);
+		if (enable_1510_mode && dma_chan[ch + 6].saved_csr)
+			handled_now += dma_handle_ch(ch + 6);
+		if (!handled_now)
+			break;
+		handled += handled_now;
+	}
+
+	return handled ? IRQ_HANDLED : IRQ_NONE;
+}
+
+int omap_request_dma(int dev_id, const char *dev_name,
+		     void (* callback)(int lch, u16 ch_status, void *data),
+		     void *data, int *dma_ch_out)
+{
+	int ch, free_ch = -1;
+	unsigned long flags;
+	struct omap_dma_lch *chan;
+
+	spin_lock_irqsave(&dma_chan_lock, flags);
+	for (ch = 0; ch < dma_chan_count; ch++) {
+		if (free_ch == -1 && dma_chan[ch].dev_id == -1) {
+			free_ch = ch;
+			if (dev_id == 0)
+				break;
+		}
+	}
+	if (free_ch == -1) {
+		spin_unlock_irqrestore(&dma_chan_lock, flags);
+		return -EBUSY;
+	}
+	chan = dma_chan + free_ch;
+	chan->dev_id = dev_id;
+	clear_lch_regs(free_ch);
+	spin_unlock_irqrestore(&dma_chan_lock, flags);
+
+	chan->dev_id = dev_id;
+	chan->dev_name = dev_name;
+	chan->callback = callback;
+	chan->data = data;
+	chan->enabled_irqs = OMAP_DMA_TOUT_IRQ | OMAP_DMA_DROP_IRQ | OMAP_DMA_BLOCK_IRQ;
+
+	if (cpu_is_omap16xx()) {
+		/* If the sync device is set, configure it dynamically. */
+		if (dev_id != 0) {
+			set_gdma_dev(free_ch + 1, dev_id);
+			dev_id = free_ch + 1;
+		}
+		/* Disable the 1510 compatibility mode and set the sync device
+		 * id. */
+		omap_writew(dev_id | (1 << 10), OMAP_DMA_CCR(free_ch));
+	} else {
+		omap_writew(dev_id, OMAP_DMA_CCR(free_ch));
+	}
+	*dma_ch_out = free_ch;
+
+	return 0;
+}
+
+void omap_free_dma(int ch)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&dma_chan_lock, flags);
+	if (dma_chan[ch].dev_id == -1) {
+		printk("omap_dma: trying to free nonallocated DMA channel %d\n", ch);
+		spin_unlock_irqrestore(&dma_chan_lock, flags);
+		return;
+	}
+	dma_chan[ch].dev_id = -1;
+	spin_unlock_irqrestore(&dma_chan_lock, flags);
+
+	/* Disable all DMA interrupts for the channel. */
+	omap_writew(0, OMAP_DMA_CICR(ch));
+	/* Make sure the DMA transfer is stopped. */
+	omap_writew(0, OMAP_DMA_CCR(ch));
+}
+
+int omap_dma_in_1510_mode(void)
+{
+	return enable_1510_mode;
+}
+
+/*
+ * lch_queue DMA will start right after lch_head one is finished.
+ * For this DMA link to start, you still need to start (see omap_start_dma)
+ * the first one. That will fire up the entire queue.
+ */
+void omap_dma_link_lch (int lch_head, int lch_queue)
+{
+	if (omap_dma_in_1510_mode()) {
+		printk(KERN_ERR "DMA linking is not supported in 1510 mode\n");
+		BUG();
+		return;
+	}
+
+	if ((dma_chan[lch_head].dev_id == -1) ||
+	    (dma_chan[lch_queue].dev_id == -1)) {
+		printk(KERN_ERR "omap_dma: trying to link non requested channels\n");
+		dump_stack();
+	}
+
+	dma_chan[lch_head].next_lch = lch_queue;
+}
+
+/*
+ * Once the DMA queue is stopped, we can destroy it.
+ */
+void omap_dma_unlink_lch (int lch_head, int lch_queue)
+{
+	if (omap_dma_in_1510_mode()) {
+		printk(KERN_ERR "DMA linking is not supported in 1510 mode\n");
+		BUG();
+		return;
+	}
+
+	if (dma_chan[lch_head].next_lch != lch_queue ||
+	    dma_chan[lch_head].next_lch == -1) {
+		printk(KERN_ERR "omap_dma: trying to unlink non linked channels\n");
+		dump_stack();
+	}
+
+
+	if ((dma_chan[lch_head].flags & OMAP_DMA_ACTIVE) ||
+	    (dma_chan[lch_head].flags & OMAP_DMA_ACTIVE)) {
+		printk(KERN_ERR "omap_dma: You need to stop the DMA channels before unlinking\n");
+		dump_stack();
+	}
+
+	dma_chan[lch_head].next_lch = -1;
+}
+
+
+static struct lcd_dma_info {
+	spinlock_t lock;
+	int reserved;
+	void (* callback)(u16 status, void *data);
+	void *cb_data;
+
+	int active;
+	unsigned long addr, size;
+	int rotate, data_type, xres, yres;
+	int vxres;
+	int mirror;
+	int xscale, yscale;
+	int ext_ctrl;
+	int src_port;
+	int single_transfer;
+} lcd_dma;
+
+void omap_set_lcd_dma_b1(unsigned long addr, u16 fb_xres, u16 fb_yres,
+			 int data_type)
+{
+	lcd_dma.addr = addr;
+	lcd_dma.data_type = data_type;
+	lcd_dma.xres = fb_xres;
+	lcd_dma.yres = fb_yres;
+}
+
+void omap_set_lcd_dma_src_port(int port)
+{
+	lcd_dma.src_port = port;
+}
+
+void omap_set_lcd_dma_ext_controller(int external)
+{
+	lcd_dma.ext_ctrl = external;
+}
+
+void omap_set_lcd_dma_single_transfer(int single)
+{
+	lcd_dma.single_transfer = single;
+}
+
+
+void omap_set_lcd_dma_b1_rotation(int rotate)
+{
+	if (omap_dma_in_1510_mode()) {
+		printk(KERN_ERR "DMA rotation is not supported in 1510 mode\n");
+		BUG();
+		return;
+	}
+	lcd_dma.rotate = rotate;
+}
+
+void omap_set_lcd_dma_b1_mirror(int mirror)
+{
+	if (omap_dma_in_1510_mode()) {
+		printk(KERN_ERR "DMA mirror is not supported in 1510 mode\n");
+		BUG();
+	}
+	lcd_dma.mirror = mirror;
+}
+
+void omap_set_lcd_dma_b1_vxres(unsigned long vxres)
+{
+	if (omap_dma_in_1510_mode()) {
+		printk(KERN_ERR "DMA virtual resulotion is not supported "
+				"in 1510 mode\n");
+		BUG();
+	}
+	lcd_dma.vxres = vxres;
+}
+
+void omap_set_lcd_dma_b1_scale(unsigned int xscale, unsigned int yscale)
+{
+	if (omap_dma_in_1510_mode()) {
+		printk(KERN_ERR "DMA scale is not supported in 1510 mode\n");
+		BUG();
+	}
+	lcd_dma.xscale = xscale;
+	lcd_dma.yscale = yscale;
+}
+
+static void set_b1_regs(void)
+{
+	unsigned long top, bottom;
+	int es;
+	u16 w;
+	unsigned long en, fn;
+	long ei, fi;
+	unsigned long vxres;
+	unsigned int xscale, yscale;
+
+	switch (lcd_dma.data_type) {
+	case OMAP_DMA_DATA_TYPE_S8:
+		es = 1;
+		break;
+	case OMAP_DMA_DATA_TYPE_S16:
+		es = 2;
+		break;
+	case OMAP_DMA_DATA_TYPE_S32:
+		es = 4;
+		break;
+	default:
+		BUG();
+		return;
+	}
+
+	vxres = lcd_dma.vxres ? lcd_dma.vxres : lcd_dma.xres;
+	xscale = lcd_dma.xscale ? lcd_dma.xscale : 1;
+	yscale = lcd_dma.yscale ? lcd_dma.yscale : 1;
+	BUG_ON(vxres < lcd_dma.xres);
+#define PIXADDR(x,y) (lcd_dma.addr + ((y) * vxres * yscale + (x) * xscale) * es)
+#define PIXSTEP(sx, sy, dx, dy) (PIXADDR(dx, dy) - PIXADDR(sx, sy) - es + 1)
+	switch (lcd_dma.rotate) {
+	case 0:
+		if (!lcd_dma.mirror) {
+			top = PIXADDR(0, 0);
+			bottom = PIXADDR(lcd_dma.xres - 1, lcd_dma.yres - 1);
+			/* 1510 DMA requires the bottom address to be 2 more
+			 * than the actual last memory access location. */
+			if (omap_dma_in_1510_mode() &&
+			    lcd_dma.data_type == OMAP_DMA_DATA_TYPE_S32)
+				bottom += 2;
+			ei = PIXSTEP(0, 0, 1, 0);
+			fi = PIXSTEP(lcd_dma.xres - 1, 0, 0, 1);
+		} else {
+			top = PIXADDR(lcd_dma.xres - 1, 0);
+			bottom = PIXADDR(0, lcd_dma.yres - 1);
+			ei = PIXSTEP(1, 0, 0, 0);
+			fi = PIXSTEP(0, 0, lcd_dma.xres - 1, 1);
+		}
+		en = lcd_dma.xres;
+		fn = lcd_dma.yres;
+		break;
+	case 90:
+		if (!lcd_dma.mirror) {
+			top = PIXADDR(0, lcd_dma.yres - 1);
+			bottom = PIXADDR(lcd_dma.xres - 1, 0);
+			ei = PIXSTEP(0, 1, 0, 0);
+			fi = PIXSTEP(0, 0, 1, lcd_dma.yres - 1);
+		} else {
+			top = PIXADDR(lcd_dma.xres - 1, lcd_dma.yres - 1);
+			bottom = PIXADDR(0, 0);
+			ei = PIXSTEP(0, 1, 0, 0);
+			fi = PIXSTEP(1, 0, 0, lcd_dma.yres - 1);
+		}
+		en = lcd_dma.yres;
+		fn = lcd_dma.xres;
+		break;
+	case 180:
+		if (!lcd_dma.mirror) {
+			top = PIXADDR(lcd_dma.xres - 1, lcd_dma.yres - 1);
+			bottom = PIXADDR(0, 0);
+			ei = PIXSTEP(1, 0, 0, 0);
+			fi = PIXSTEP(0, 1, lcd_dma.xres - 1, 0);
+		} else {
+			top = PIXADDR(0, lcd_dma.yres - 1);
+			bottom = PIXADDR(lcd_dma.xres - 1, 0);
+			ei = PIXSTEP(0, 0, 1, 0);
+			fi = PIXSTEP(lcd_dma.xres - 1, 1, 0, 0);
+		}
+		en = lcd_dma.xres;
+		fn = lcd_dma.yres;
+		break;
+	case 270:
+		if (!lcd_dma.mirror) {
+			top = PIXADDR(lcd_dma.xres - 1, 0);
+			bottom = PIXADDR(0, lcd_dma.yres - 1);
+			ei = PIXSTEP(0, 0, 0, 1);
+			fi = PIXSTEP(1, lcd_dma.yres - 1, 0, 0);
+		} else {
+			top = PIXADDR(0, 0);
+			bottom = PIXADDR(lcd_dma.xres - 1, lcd_dma.yres - 1);
+			ei = PIXSTEP(0, 0, 0, 1);
+			fi = PIXSTEP(0, lcd_dma.yres - 1, 1, 0);
+		}
+		en = lcd_dma.yres;
+		fn = lcd_dma.xres;
+		break;
+	default:
+		BUG();
+		return;	/* Supress warning about uninitialized vars */
+	}
+
+	if (omap_dma_in_1510_mode()) {
+		omap_writew(top >> 16, OMAP1510_DMA_LCD_TOP_F1_U);
+		omap_writew(top, OMAP1510_DMA_LCD_TOP_F1_L);
+		omap_writew(bottom >> 16, OMAP1510_DMA_LCD_BOT_F1_U);
+		omap_writew(bottom, OMAP1510_DMA_LCD_BOT_F1_L);
+
+		return;
+	}
+
+	/* 1610 regs */
+	omap_writew(top >> 16, OMAP1610_DMA_LCD_TOP_B1_U);
+	omap_writew(top, OMAP1610_DMA_LCD_TOP_B1_L);
+	omap_writew(bottom >> 16, OMAP1610_DMA_LCD_BOT_B1_U);
+	omap_writew(bottom, OMAP1610_DMA_LCD_BOT_B1_L);
+
+	omap_writew(en, OMAP1610_DMA_LCD_SRC_EN_B1);
+	omap_writew(fn, OMAP1610_DMA_LCD_SRC_FN_B1);
+
+	w = omap_readw(OMAP1610_DMA_LCD_CSDP);
+	w &= ~0x03;
+	w |= lcd_dma.data_type;
+	omap_writew(w, OMAP1610_DMA_LCD_CSDP);
+
+	w = omap_readw(OMAP1610_DMA_LCD_CTRL);
+	/* Always set the source port as SDRAM for now*/
+	w &= ~(0x03 << 6);
+	if (lcd_dma.callback != NULL)
+		w |= 1 << 1;            /* Block interrupt enable */
+	else
+		w &= ~(1 << 1);
+	omap_writew(w, OMAP1610_DMA_LCD_CTRL);
+
+	if (!(lcd_dma.rotate || lcd_dma.mirror ||
+	      lcd_dma.vxres || lcd_dma.xscale || lcd_dma.yscale))
+		return;
+
+	w = omap_readw(OMAP1610_DMA_LCD_CCR);
+	/* Set the double-indexed addressing mode */
+	w |= (0x03 << 12);
+	omap_writew(w, OMAP1610_DMA_LCD_CCR);
+
+	omap_writew(ei, OMAP1610_DMA_LCD_SRC_EI_B1);
+	omap_writew(fi >> 16, OMAP1610_DMA_LCD_SRC_FI_B1_U);
+	omap_writew(fi, OMAP1610_DMA_LCD_SRC_FI_B1_L);
+}
+
+static irqreturn_t lcd_dma_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
+{
+	u16 w;
+
+	w = omap_readw(OMAP1610_DMA_LCD_CTRL);
+	if (unlikely(!(w & (1 << 3)))) {
+		printk(KERN_WARNING "Spurious LCD DMA IRQ\n");
+		return IRQ_NONE;
+	}
+	/* Ack the IRQ */
+	w |= (1 << 3);
+	omap_writew(w, OMAP1610_DMA_LCD_CTRL);
+	lcd_dma.active = 0;
+	if (lcd_dma.callback != NULL)
+		lcd_dma.callback(w, lcd_dma.cb_data);
+
+	return IRQ_HANDLED;
+}
+
+int omap_request_lcd_dma(void (* callback)(u16 status, void *data),
+			 void *data)
+{
+	spin_lock_irq(&lcd_dma.lock);
+	if (lcd_dma.reserved) {
+		spin_unlock_irq(&lcd_dma.lock);
+		printk(KERN_ERR "LCD DMA channel already reserved\n");
+		BUG();
+		return -EBUSY;
+	}
+	lcd_dma.reserved = 1;
+	spin_unlock_irq(&lcd_dma.lock);
+	lcd_dma.callback = callback;
+	lcd_dma.cb_data = data;
+	lcd_dma.active = 0;
+	lcd_dma.single_transfer = 0;
+	lcd_dma.rotate = 0;
+	lcd_dma.vxres = 0;
+	lcd_dma.mirror = 0;
+	lcd_dma.xscale = 0;
+	lcd_dma.yscale = 0;
+	lcd_dma.ext_ctrl = 0;
+	lcd_dma.src_port = 0;
+
+	return 0;
+}
+
+void omap_free_lcd_dma(void)
+{
+	spin_lock(&lcd_dma.lock);
+	if (!lcd_dma.reserved) {
+		spin_unlock(&lcd_dma.lock);
+		printk(KERN_ERR "LCD DMA is not reserved\n");
+		BUG();
+		return;
+	}
+	if (!enable_1510_mode)
+		omap_writew(omap_readw(OMAP1610_DMA_LCD_CCR) & ~1, OMAP1610_DMA_LCD_CCR);
+	lcd_dma.reserved = 0;
+	spin_unlock(&lcd_dma.lock);
+}
+
+void omap_enable_lcd_dma(void)
+{
+	u16 w;
+
+	/* Set the Enable bit only if an external controller is
+	 * connected. Otherwise the OMAP internal controller will
+	 * start the transfer when it gets enabled.
+	 */
+	if (enable_1510_mode || !lcd_dma.ext_ctrl)
+		return;
+
+	w = omap_readw(OMAP1610_DMA_LCD_CTRL);
+	w |= 1 << 8;
+	omap_writew(w, OMAP1610_DMA_LCD_CTRL);
+
+	w = omap_readw(OMAP1610_DMA_LCD_CCR);
+	w |= 1 << 7;
+	omap_writew(w, OMAP1610_DMA_LCD_CCR);
+
+	lcd_dma.active = 1;
+}
+
+void omap_setup_lcd_dma(void)
+{
+	BUG_ON(lcd_dma.active);
+	if (!enable_1510_mode) {
+		/* Set some reasonable defaults */
+		omap_writew(0x5440, OMAP1610_DMA_LCD_CCR);
+		omap_writew(0x9102, OMAP1610_DMA_LCD_CSDP);
+		omap_writew(0x0004, OMAP1610_DMA_LCD_LCH_CTRL);
+	}
+	set_b1_regs();
+	if (!enable_1510_mode) {
+		u16 w;
+
+		w = omap_readw(OMAP1610_DMA_LCD_CCR);
+		/* If DMA was already active set the end_prog bit to have
+		 * the programmed register set loaded into the active
+		 * register set.
+		 */
+		w |= 1 << 11;		/* End_prog */
+		if (!lcd_dma.single_transfer)
+	        	w |= (3 << 8);	/* Auto_init, repeat */
+		omap_writew(w, OMAP1610_DMA_LCD_CCR);
+	}
+}
+
+void omap_stop_lcd_dma(void)
+{
+	u16 w;
+
+	lcd_dma.active = 0;
+	if (enable_1510_mode || !lcd_dma.ext_ctrl)
+		return;
+
+	w = omap_readw(OMAP1610_DMA_LCD_CCR);
+	w &= ~(1 << 7);
+	omap_writew(w, OMAP1610_DMA_LCD_CCR);
+
+	w = omap_readw(OMAP1610_DMA_LCD_CTRL);
+	w &= ~(1 << 8);
+	omap_writew(w, OMAP1610_DMA_LCD_CTRL);
+}
+
+/*
+ * Clears any DMA state so the DMA engine is ready to restart with new buffers
+ * through omap_start_dma(). Any buffers in flight are discarded.
+ */
+void omap_clear_dma(int lch)
+{
+	unsigned long flags;
+	int status;
+
+	local_irq_save(flags);
+	omap_writew(omap_readw(OMAP_DMA_CCR(lch)) & ~OMAP_DMA_CCR_EN,
+		    OMAP_DMA_CCR(lch));
+	status = OMAP_DMA_CSR(lch);	/* clear pending interrupts */
+	local_irq_restore(flags);
+}
+
+/*
+ * Returns current physical source address for the given DMA channel.
+ * If the channel is running the caller must disable interrupts prior calling
+ * this function and process the returned value before re-enabling interrupt to
+ * prevent races with the interrupt handler. Note that in continuous mode there
+ * is a chance for CSSA_L register overflow inbetween the two reads resulting
+ * in incorrect return value.
+ */
+dma_addr_t omap_get_dma_src_pos(int lch)
+{
+	return (dma_addr_t) (OMAP_DMA_CSSA_L(lch) |
+			     (OMAP_DMA_CSSA_U(lch) << 16));
+}
+
+/*
+ * Returns current physical destination address for the given DMA channel.
+ * If the channel is running the caller must disable interrupts prior calling
+ * this function and process the returned value before re-enabling interrupt to
+ * prevent races with the interrupt handler. Note that in continuous mode there
+ * is a chance for CDSA_L register overflow inbetween the two reads resulting
+ * in incorrect return value.
+ */
+dma_addr_t omap_get_dma_dst_pos(int lch)
+{
+	return (dma_addr_t) (OMAP_DMA_CDSA_L(lch) |
+			     (OMAP_DMA_CDSA_U(lch) << 16));
+}
+
+int omap_dma_running(void)
+{
+	int lch;
+
+	/* Check if LCD DMA is running */
+	if (cpu_is_omap16xx())
+		if (omap_readw(OMAP1610_DMA_LCD_CCR) & OMAP_DMA_CCR_EN)
+			return 1;
+
+	for (lch = 0; lch < dma_chan_count; lch++) {
+		u16 w;
+
+		w = omap_readw(OMAP_DMA_CCR(lch));
+		if (w & OMAP_DMA_CCR_EN)
+			return 1;
+	}
+	return 0;
+}
+
+static int __init omap_init_dma(void)
+{
+	int ch, r;
+
+	if (cpu_is_omap1510()) {
+		printk(KERN_INFO "DMA support for OMAP1510 initialized\n");
+		dma_chan_count = 9;
+		enable_1510_mode = 1;
+	} else if (cpu_is_omap16xx() || cpu_is_omap730()) {
+		printk(KERN_INFO "OMAP DMA hardware version %d\n",
+		       omap_readw(OMAP_DMA_HW_ID));
+		printk(KERN_INFO "DMA capabilities: %08x:%08x:%04x:%04x:%04x\n",
+		       (omap_readw(OMAP_DMA_CAPS_0_U) << 16) | omap_readw(OMAP_DMA_CAPS_0_L),
+		       (omap_readw(OMAP_DMA_CAPS_1_U) << 16) | omap_readw(OMAP_DMA_CAPS_1_L),
+		       omap_readw(OMAP_DMA_CAPS_2), omap_readw(OMAP_DMA_CAPS_3),
+		       omap_readw(OMAP_DMA_CAPS_4));
+		if (!enable_1510_mode) {
+			u16 w;
+
+			/* Disable OMAP 3.0/3.1 compatibility mode. */
+			w = omap_readw(OMAP_DMA_GSCR);
+			w |= 1 << 3;
+			omap_writew(w, OMAP_DMA_GSCR);
+			dma_chan_count = 16;
+		} else
+			dma_chan_count = 9;
+	} else {
+		dma_chan_count = 0;
+		return 0;
+	}
+
+	memset(&lcd_dma, 0, sizeof(lcd_dma));
+	spin_lock_init(&lcd_dma.lock);
+	spin_lock_init(&dma_chan_lock);
+	memset(&dma_chan, 0, sizeof(dma_chan));
+
+	for (ch = 0; ch < dma_chan_count; ch++) {
+		dma_chan[ch].dev_id = -1;
+		dma_chan[ch].next_lch = -1;
+
+		if (ch >= 6 && enable_1510_mode)
+			continue;
+
+		/* request_irq() doesn't like dev_id (ie. ch) being zero,
+		 * so we have to kludge around this. */
+		r = request_irq(dma_irq[ch], dma_irq_handler, 0, "DMA",
+				(void *) (ch + 1));
+		if (r != 0) {
+			int i;
+
+			printk(KERN_ERR "unable to request IRQ %d for DMA (error %d)\n",
+			       dma_irq[ch], r);
+			for (i = 0; i < ch; i++)
+				free_irq(dma_irq[i], (void *) (i + 1));
+			return r;
+		}
+	}
+	r = request_irq(INT_DMA_LCD, lcd_dma_irq_handler, 0, "LCD DMA", NULL);
+	if (r != 0) {
+		int i;
+
+		printk(KERN_ERR "unable to request IRQ for LCD DMA (error %d)\n", r);
+		for (i = 0; i < dma_chan_count; i++)
+			free_irq(dma_irq[i], (void *) (i + 1));
+		return r;
+	}
+	return 0;
+}
+
+arch_initcall(omap_init_dma);
+
+
+EXPORT_SYMBOL(omap_get_dma_src_pos);
+EXPORT_SYMBOL(omap_get_dma_dst_pos);
+EXPORT_SYMBOL(omap_clear_dma);
+EXPORT_SYMBOL(omap_set_dma_priority);
+EXPORT_SYMBOL(omap_request_dma);
+EXPORT_SYMBOL(omap_free_dma);
+EXPORT_SYMBOL(omap_start_dma);
+EXPORT_SYMBOL(omap_stop_dma);
+EXPORT_SYMBOL(omap_enable_dma_irq);
+EXPORT_SYMBOL(omap_disable_dma_irq);
+
+EXPORT_SYMBOL(omap_set_dma_transfer_params);
+EXPORT_SYMBOL(omap_set_dma_color_mode);
+
+EXPORT_SYMBOL(omap_set_dma_src_params);
+EXPORT_SYMBOL(omap_set_dma_src_index);
+EXPORT_SYMBOL(omap_set_dma_src_data_pack);
+EXPORT_SYMBOL(omap_set_dma_src_burst_mode);
+
+EXPORT_SYMBOL(omap_set_dma_dest_params);
+EXPORT_SYMBOL(omap_set_dma_dest_index);
+EXPORT_SYMBOL(omap_set_dma_dest_data_pack);
+EXPORT_SYMBOL(omap_set_dma_dest_burst_mode);
+
+EXPORT_SYMBOL(omap_dma_link_lch);
+EXPORT_SYMBOL(omap_dma_unlink_lch);
+
+EXPORT_SYMBOL(omap_request_lcd_dma);
+EXPORT_SYMBOL(omap_free_lcd_dma);
+EXPORT_SYMBOL(omap_enable_lcd_dma);
+EXPORT_SYMBOL(omap_setup_lcd_dma);
+EXPORT_SYMBOL(omap_stop_lcd_dma);
+EXPORT_SYMBOL(omap_set_lcd_dma_b1);
+EXPORT_SYMBOL(omap_set_lcd_dma_single_transfer);
+EXPORT_SYMBOL(omap_set_lcd_dma_ext_controller);
+EXPORT_SYMBOL(omap_set_lcd_dma_b1_rotation);
+EXPORT_SYMBOL(omap_set_lcd_dma_b1_vxres);
+EXPORT_SYMBOL(omap_set_lcd_dma_b1_scale);
+EXPORT_SYMBOL(omap_set_lcd_dma_b1_mirror);
+
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c
new file mode 100644
--- /dev/null
+++ b/arch/arm/plat-omap/gpio.c
@@ -0,0 +1,762 @@
+/*
+ *  linux/arch/arm/plat-omap/gpio.c
+ *
+ * Support functions for OMAP GPIO
+ *
+ * Copyright (C) 2003 Nokia Corporation
+ * Written by Juha Yrjölä <juha.yrjola@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/ptrace.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/arch/irqs.h>
+#include <asm/arch/gpio.h>
+#include <asm/mach/irq.h>
+
+#include <asm/io.h>
+
+/*
+ * OMAP1510 GPIO registers
+ */
+#define OMAP1510_GPIO_BASE		0xfffce000
+#define OMAP1510_GPIO_DATA_INPUT	0x00
+#define OMAP1510_GPIO_DATA_OUTPUT	0x04
+#define OMAP1510_GPIO_DIR_CONTROL	0x08
+#define OMAP1510_GPIO_INT_CONTROL	0x0c
+#define OMAP1510_GPIO_INT_MASK		0x10
+#define OMAP1510_GPIO_INT_STATUS	0x14
+#define OMAP1510_GPIO_PIN_CONTROL	0x18
+
+#define OMAP1510_IH_GPIO_BASE		64
+
+/*
+ * OMAP1610 specific GPIO registers
+ */
+#define OMAP1610_GPIO1_BASE		0xfffbe400
+#define OMAP1610_GPIO2_BASE		0xfffbec00
+#define OMAP1610_GPIO3_BASE		0xfffbb400
+#define OMAP1610_GPIO4_BASE		0xfffbbc00
+#define OMAP1610_GPIO_REVISION		0x0000
+#define OMAP1610_GPIO_SYSCONFIG		0x0010
+#define OMAP1610_GPIO_SYSSTATUS		0x0014
+#define OMAP1610_GPIO_IRQSTATUS1	0x0018
+#define OMAP1610_GPIO_IRQENABLE1	0x001c
+#define OMAP1610_GPIO_DATAIN		0x002c
+#define OMAP1610_GPIO_DATAOUT		0x0030
+#define OMAP1610_GPIO_DIRECTION		0x0034
+#define OMAP1610_GPIO_EDGE_CTRL1	0x0038
+#define OMAP1610_GPIO_EDGE_CTRL2	0x003c
+#define OMAP1610_GPIO_CLEAR_IRQENABLE1	0x009c
+#define OMAP1610_GPIO_CLEAR_DATAOUT	0x00b0
+#define OMAP1610_GPIO_SET_IRQENABLE1	0x00dc
+#define OMAP1610_GPIO_SET_DATAOUT	0x00f0
+
+/*
+ * OMAP730 specific GPIO registers
+ */
+#define OMAP730_GPIO1_BASE		0xfffbc000
+#define OMAP730_GPIO2_BASE		0xfffbc800
+#define OMAP730_GPIO3_BASE		0xfffbd000
+#define OMAP730_GPIO4_BASE		0xfffbd800
+#define OMAP730_GPIO5_BASE		0xfffbe000
+#define OMAP730_GPIO6_BASE		0xfffbe800
+#define OMAP730_GPIO_DATA_INPUT		0x00
+#define OMAP730_GPIO_DATA_OUTPUT	0x04
+#define OMAP730_GPIO_DIR_CONTROL	0x08
+#define OMAP730_GPIO_INT_CONTROL	0x0c
+#define OMAP730_GPIO_INT_MASK		0x10
+#define OMAP730_GPIO_INT_STATUS		0x14
+
+#define OMAP_MPUIO_MASK		(~OMAP_MAX_GPIO_LINES & 0xff)
+
+struct gpio_bank {
+	u32 base;
+	u16 irq;
+	u16 virtual_irq_start;
+	u8 method;
+	u32 reserved_map;
+	spinlock_t lock;
+};
+
+#define METHOD_MPUIO		0
+#define METHOD_GPIO_1510	1
+#define METHOD_GPIO_1610	2
+#define METHOD_GPIO_730		3
+
+#if defined(CONFIG_ARCH_OMAP16XX)
+static struct gpio_bank gpio_bank_1610[5] = {
+	{ OMAP_MPUIO_BASE,     INT_MPUIO,	    IH_MPUIO_BASE,     METHOD_MPUIO},
+	{ OMAP1610_GPIO1_BASE, INT_GPIO_BANK1,	    IH_GPIO_BASE,      METHOD_GPIO_1610 },
+	{ OMAP1610_GPIO2_BASE, INT_1610_GPIO_BANK2, IH_GPIO_BASE + 16, METHOD_GPIO_1610 },
+	{ OMAP1610_GPIO3_BASE, INT_1610_GPIO_BANK3, IH_GPIO_BASE + 32, METHOD_GPIO_1610 },
+	{ OMAP1610_GPIO4_BASE, INT_1610_GPIO_BANK4, IH_GPIO_BASE + 48, METHOD_GPIO_1610 },
+};
+#endif
+
+#ifdef CONFIG_ARCH_OMAP1510
+static struct gpio_bank gpio_bank_1510[2] = {
+	{ OMAP_MPUIO_BASE,    INT_MPUIO,      IH_MPUIO_BASE, METHOD_MPUIO },
+	{ OMAP1510_GPIO_BASE, INT_GPIO_BANK1, IH_GPIO_BASE,  METHOD_GPIO_1510 }
+};
+#endif
+
+#ifdef CONFIG_ARCH_OMAP730
+static struct gpio_bank gpio_bank_730[7] = {
+	{ OMAP_MPUIO_BASE,     INT_730_MPUIO,	    IH_MPUIO_BASE,	METHOD_MPUIO },
+	{ OMAP730_GPIO1_BASE,  INT_730_GPIO_BANK1,  IH_GPIO_BASE,	METHOD_GPIO_730 },
+	{ OMAP730_GPIO2_BASE,  INT_730_GPIO_BANK2,  IH_GPIO_BASE + 32,	METHOD_GPIO_730 },
+	{ OMAP730_GPIO3_BASE,  INT_730_GPIO_BANK3,  IH_GPIO_BASE + 64,	METHOD_GPIO_730 },
+	{ OMAP730_GPIO4_BASE,  INT_730_GPIO_BANK4,  IH_GPIO_BASE + 96,	METHOD_GPIO_730 },
+	{ OMAP730_GPIO5_BASE,  INT_730_GPIO_BANK5,  IH_GPIO_BASE + 128, METHOD_GPIO_730 },
+	{ OMAP730_GPIO6_BASE,  INT_730_GPIO_BANK6,  IH_GPIO_BASE + 160, METHOD_GPIO_730 },
+};
+#endif
+
+static struct gpio_bank *gpio_bank;
+static int gpio_bank_count;
+
+static inline struct gpio_bank *get_gpio_bank(int gpio)
+{
+#ifdef CONFIG_ARCH_OMAP1510
+	if (cpu_is_omap1510()) {
+		if (OMAP_GPIO_IS_MPUIO(gpio))
+			return &gpio_bank[0];
+		return &gpio_bank[1];
+	}
+#endif
+#if defined(CONFIG_ARCH_OMAP16XX)
+	if (cpu_is_omap16xx()) {
+		if (OMAP_GPIO_IS_MPUIO(gpio))
+			return &gpio_bank[0];
+		return &gpio_bank[1 + (gpio >> 4)];
+	}
+#endif
+#ifdef CONFIG_ARCH_OMAP730
+	if (cpu_is_omap730()) {
+		if (OMAP_GPIO_IS_MPUIO(gpio))
+			return &gpio_bank[0];
+		return &gpio_bank[1 + (gpio >> 5)];
+	}
+#endif
+}
+
+static inline int get_gpio_index(int gpio)
+{
+	if (cpu_is_omap730())
+		return gpio & 0x1f;
+	else
+		return gpio & 0x0f;
+}
+
+static inline int gpio_valid(int gpio)
+{
+	if (gpio < 0)
+		return -1;
+	if (OMAP_GPIO_IS_MPUIO(gpio)) {
+		if ((gpio & OMAP_MPUIO_MASK) > 16)
+			return -1;
+		return 0;
+	}
+#ifdef CONFIG_ARCH_OMAP1510
+	if (cpu_is_omap1510() && gpio < 16)
+		return 0;
+#endif
+#if defined(CONFIG_ARCH_OMAP16XX)
+	if ((cpu_is_omap16xx()) && gpio < 64)
+		return 0;
+#endif
+#ifdef CONFIG_ARCH_OMAP730
+	if (cpu_is_omap730() && gpio < 192)
+		return 0;
+#endif
+	return -1;
+}
+
+static int check_gpio(int gpio)
+{
+	if (unlikely(gpio_valid(gpio)) < 0) {
+		printk(KERN_ERR "omap-gpio: invalid GPIO %d\n", gpio);
+		dump_stack();
+		return -1;
+	}
+	return 0;
+}
+
+static void _set_gpio_direction(struct gpio_bank *bank, int gpio, int is_input)
+{
+	u32 reg = bank->base;
+	u32 l;
+
+	switch (bank->method) {
+	case METHOD_MPUIO:
+		reg += OMAP_MPUIO_IO_CNTL;
+		break;
+	case METHOD_GPIO_1510:
+		reg += OMAP1510_GPIO_DIR_CONTROL;
+		break;
+	case METHOD_GPIO_1610:
+		reg += OMAP1610_GPIO_DIRECTION;
+		break;
+	case METHOD_GPIO_730:
+		reg += OMAP730_GPIO_DIR_CONTROL;
+		break;
+	}
+	l = __raw_readl(reg);
+	if (is_input)
+		l |= 1 << gpio;
+	else
+		l &= ~(1 << gpio);
+	__raw_writel(l, reg);
+}
+
+void omap_set_gpio_direction(int gpio, int is_input)
+{
+	struct gpio_bank *bank;
+
+	if (check_gpio(gpio) < 0)
+		return;
+	bank = get_gpio_bank(gpio);
+	spin_lock(&bank->lock);
+	_set_gpio_direction(bank, get_gpio_index(gpio), is_input);
+	spin_unlock(&bank->lock);
+}
+
+static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable)
+{
+	u32 reg = bank->base;
+	u32 l = 0;
+
+	switch (bank->method) {
+	case METHOD_MPUIO:
+		reg += OMAP_MPUIO_OUTPUT;
+		l = __raw_readl(reg);
+		if (enable)
+			l |= 1 << gpio;
+		else
+			l &= ~(1 << gpio);
+		break;
+	case METHOD_GPIO_1510:
+		reg += OMAP1510_GPIO_DATA_OUTPUT;
+		l = __raw_readl(reg);
+		if (enable)
+			l |= 1 << gpio;
+		else
+			l &= ~(1 << gpio);
+		break;
+	case METHOD_GPIO_1610:
+		if (enable)
+			reg += OMAP1610_GPIO_SET_DATAOUT;
+		else
+			reg += OMAP1610_GPIO_CLEAR_DATAOUT;
+		l = 1 << gpio;
+		break;
+	case METHOD_GPIO_730:
+		reg += OMAP730_GPIO_DATA_OUTPUT;
+		l = __raw_readl(reg);
+		if (enable)
+			l |= 1 << gpio;
+		else
+			l &= ~(1 << gpio);
+		break;
+	default:
+		BUG();
+		return;
+	}
+	__raw_writel(l, reg);
+}
+
+void omap_set_gpio_dataout(int gpio, int enable)
+{
+	struct gpio_bank *bank;
+
+	if (check_gpio(gpio) < 0)
+		return;
+	bank = get_gpio_bank(gpio);
+	spin_lock(&bank->lock);
+	_set_gpio_dataout(bank, get_gpio_index(gpio), enable);
+	spin_unlock(&bank->lock);
+}
+
+int omap_get_gpio_datain(int gpio)
+{
+	struct gpio_bank *bank;
+	u32 reg;
+
+	if (check_gpio(gpio) < 0)
+		return -1;
+	bank = get_gpio_bank(gpio);
+	reg = bank->base;
+	switch (bank->method) {
+	case METHOD_MPUIO:
+		reg += OMAP_MPUIO_INPUT_LATCH;
+		break;
+	case METHOD_GPIO_1510:
+		reg += OMAP1510_GPIO_DATA_INPUT;
+		break;
+	case METHOD_GPIO_1610:
+		reg += OMAP1610_GPIO_DATAIN;
+		break;
+	case METHOD_GPIO_730:
+		reg += OMAP730_GPIO_DATA_INPUT;
+		break;
+	default:
+		BUG();
+		return -1;
+	}
+	return (__raw_readl(reg) & (1 << get_gpio_index(gpio))) != 0;
+}
+
+static void _set_gpio_edge_ctrl(struct gpio_bank *bank, int gpio, int edge)
+{
+	u32 reg = bank->base;
+	u32 l;
+
+	switch (bank->method) {
+	case METHOD_MPUIO:
+		reg += OMAP_MPUIO_GPIO_INT_EDGE;
+		l = __raw_readl(reg);
+		if (edge == OMAP_GPIO_RISING_EDGE)
+			l |= 1 << gpio;
+		else
+			l &= ~(1 << gpio);
+		__raw_writel(l, reg);
+		break;
+	case METHOD_GPIO_1510:
+		reg += OMAP1510_GPIO_INT_CONTROL;
+		l = __raw_readl(reg);
+		if (edge == OMAP_GPIO_RISING_EDGE)
+			l |= 1 << gpio;
+		else
+			l &= ~(1 << gpio);
+		__raw_writel(l, reg);
+		break;
+	case METHOD_GPIO_1610:
+		edge &= 0x03;
+		if (gpio & 0x08)
+			reg += OMAP1610_GPIO_EDGE_CTRL2;
+		else
+			reg += OMAP1610_GPIO_EDGE_CTRL1;
+		gpio &= 0x07;
+		l = __raw_readl(reg);
+		l &= ~(3 << (gpio << 1));
+		l |= edge << (gpio << 1);
+		__raw_writel(l, reg);
+		break;
+	case METHOD_GPIO_730:
+		reg += OMAP730_GPIO_INT_CONTROL;
+		l = __raw_readl(reg);
+		if (edge == OMAP_GPIO_RISING_EDGE)
+			l |= 1 << gpio;
+		else
+			l &= ~(1 << gpio);
+		__raw_writel(l, reg);
+		break;
+	default:
+		BUG();
+		return;
+	}
+}
+
+void omap_set_gpio_edge_ctrl(int gpio, int edge)
+{
+	struct gpio_bank *bank;
+
+	if (check_gpio(gpio) < 0)
+		return;
+	bank = get_gpio_bank(gpio);
+	spin_lock(&bank->lock);
+	_set_gpio_edge_ctrl(bank, get_gpio_index(gpio), edge);
+	spin_unlock(&bank->lock);
+}
+
+
+static int _get_gpio_edge_ctrl(struct gpio_bank *bank, int gpio)
+{
+	u32 reg = bank->base, l;
+
+	switch (bank->method) {
+	case METHOD_MPUIO:
+		l = __raw_readl(reg + OMAP_MPUIO_GPIO_INT_EDGE);
+		return (l & (1 << gpio)) ?
+			OMAP_GPIO_RISING_EDGE : OMAP_GPIO_FALLING_EDGE;
+	case METHOD_GPIO_1510:
+		l = __raw_readl(reg + OMAP1510_GPIO_INT_CONTROL);
+		return (l & (1 << gpio)) ?
+			OMAP_GPIO_RISING_EDGE : OMAP_GPIO_FALLING_EDGE;
+	case METHOD_GPIO_1610:
+		if (gpio & 0x08)
+			reg += OMAP1610_GPIO_EDGE_CTRL2;
+		else
+			reg += OMAP1610_GPIO_EDGE_CTRL1;
+		return (__raw_readl(reg) >> ((gpio & 0x07) << 1)) & 0x03;
+	case METHOD_GPIO_730:
+		l = __raw_readl(reg + OMAP730_GPIO_INT_CONTROL);
+		return (l & (1 << gpio)) ?
+			OMAP_GPIO_RISING_EDGE : OMAP_GPIO_FALLING_EDGE;
+	default:
+		BUG();
+		return -1;
+	}
+}
+
+static void _clear_gpio_irqbank(struct gpio_bank *bank, int gpio_mask)
+{
+	u32 reg = bank->base;
+
+	switch (bank->method) {
+	case METHOD_MPUIO:
+		/* MPUIO irqstatus is reset by reading the status register,
+		 * so do nothing here */
+		return;
+	case METHOD_GPIO_1510:
+		reg += OMAP1510_GPIO_INT_STATUS;
+		break;
+	case METHOD_GPIO_1610:
+		reg += OMAP1610_GPIO_IRQSTATUS1;
+		break;
+	case METHOD_GPIO_730:
+		reg += OMAP730_GPIO_INT_STATUS;
+		break;
+	default:
+		BUG();
+		return;
+	}
+	__raw_writel(gpio_mask, reg);
+}
+
+static inline void _clear_gpio_irqstatus(struct gpio_bank *bank, int gpio)
+{
+	_clear_gpio_irqbank(bank, 1 << get_gpio_index(gpio));
+}
+
+static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enable)
+{
+	u32 reg = bank->base;
+	u32 l;
+
+	switch (bank->method) {
+	case METHOD_MPUIO:
+		reg += OMAP_MPUIO_GPIO_MASKIT;
+		l = __raw_readl(reg);
+		if (enable)
+			l &= ~(gpio_mask);
+		else
+			l |= gpio_mask;
+		break;
+	case METHOD_GPIO_1510:
+		reg += OMAP1510_GPIO_INT_MASK;
+		l = __raw_readl(reg);
+		if (enable)
+			l &= ~(gpio_mask);
+		else
+			l |= gpio_mask;
+		break;
+	case METHOD_GPIO_1610:
+		if (enable)
+			reg += OMAP1610_GPIO_SET_IRQENABLE1;
+		else
+			reg += OMAP1610_GPIO_CLEAR_IRQENABLE1;
+		l = gpio_mask;
+		break;
+	case METHOD_GPIO_730:
+		reg += OMAP730_GPIO_INT_MASK;
+		l = __raw_readl(reg);
+		if (enable)
+			l &= ~(gpio_mask);
+		else
+			l |= gpio_mask;
+		break;
+	default:
+		BUG();
+		return;
+	}
+	__raw_writel(l, reg);
+}
+
+static inline void _set_gpio_irqenable(struct gpio_bank *bank, int gpio, int enable)
+{
+	_enable_gpio_irqbank(bank, 1 << get_gpio_index(gpio), enable);
+}
+
+int omap_request_gpio(int gpio)
+{
+	struct gpio_bank *bank;
+
+	if (check_gpio(gpio) < 0)
+		return -EINVAL;
+
+	bank = get_gpio_bank(gpio);
+	spin_lock(&bank->lock);
+	if (unlikely(bank->reserved_map & (1 << get_gpio_index(gpio)))) {
+		printk(KERN_ERR "omap-gpio: GPIO %d is already reserved!\n", gpio);
+		dump_stack();
+		spin_unlock(&bank->lock);
+		return -1;
+	}
+	bank->reserved_map |= (1 << get_gpio_index(gpio));
+#ifdef CONFIG_ARCH_OMAP1510
+	if (bank->method == METHOD_GPIO_1510) {
+		u32 reg;
+
+		/* Claim the pin for the ARM */
+		reg = bank->base + OMAP1510_GPIO_PIN_CONTROL;
+		__raw_writel(__raw_readl(reg) | (1 << get_gpio_index(gpio)), reg);
+	}
+#endif
+	spin_unlock(&bank->lock);
+
+	return 0;
+}
+
+void omap_free_gpio(int gpio)
+{
+	struct gpio_bank *bank;
+
+	if (check_gpio(gpio) < 0)
+		return;
+	bank = get_gpio_bank(gpio);
+	spin_lock(&bank->lock);
+	if (unlikely(!(bank->reserved_map & (1 << get_gpio_index(gpio))))) {
+		printk(KERN_ERR "omap-gpio: GPIO %d wasn't reserved!\n", gpio);
+		dump_stack();
+		spin_unlock(&bank->lock);
+		return;
+	}
+	bank->reserved_map &= ~(1 << get_gpio_index(gpio));
+	_set_gpio_direction(bank, get_gpio_index(gpio), 1);
+	_set_gpio_irqenable(bank, gpio, 0);
+	_clear_gpio_irqstatus(bank, gpio);
+	spin_unlock(&bank->lock);
+}
+
+/*
+ * We need to unmask the GPIO bank interrupt as soon as possible to
+ * avoid missing GPIO interrupts for other lines in the bank.
+ * Then we need to mask-read-clear-unmask the triggered GPIO lines
+ * in the bank to avoid missing nested interrupts for a GPIO line.
+ * If we wait to unmask individual GPIO lines in the bank after the
+ * line's interrupt handler has been run, we may miss some nested
+ * interrupts.
+ */
+static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc,
+			     struct pt_regs *regs)
+{
+	u32 isr_reg = 0;
+	u32 isr;
+	unsigned int gpio_irq;
+	struct gpio_bank *bank;
+
+	desc->chip->ack(irq);
+
+	bank = (struct gpio_bank *) desc->data;
+	if (bank->method == METHOD_MPUIO)
+		isr_reg = bank->base + OMAP_MPUIO_GPIO_INT;
+#ifdef CONFIG_ARCH_OMAP1510
+	if (bank->method == METHOD_GPIO_1510)
+		isr_reg = bank->base + OMAP1510_GPIO_INT_STATUS;
+#endif
+#if defined(CONFIG_ARCH_OMAP16XX)
+	if (bank->method == METHOD_GPIO_1610)
+		isr_reg = bank->base + OMAP1610_GPIO_IRQSTATUS1;
+#endif
+#ifdef CONFIG_ARCH_OMAP730
+	if (bank->method == METHOD_GPIO_730)
+		isr_reg = bank->base + OMAP730_GPIO_INT_STATUS;
+#endif
+
+	isr = __raw_readl(isr_reg);
+	_enable_gpio_irqbank(bank, isr, 0);
+	_clear_gpio_irqbank(bank, isr);
+	_enable_gpio_irqbank(bank, isr, 1);
+	desc->chip->unmask(irq);
+
+	if (unlikely(!isr))
+		return;
+
+	gpio_irq = bank->virtual_irq_start;
+	for (; isr != 0; isr >>= 1, gpio_irq++) {
+		struct irqdesc *d;
+		if (!(isr & 1))
+			continue;
+		d = irq_desc + gpio_irq;
+		d->handle(gpio_irq, d, regs);
+	}
+}
+
+static void gpio_ack_irq(unsigned int irq)
+{
+	unsigned int gpio = irq - IH_GPIO_BASE;
+	struct gpio_bank *bank = get_gpio_bank(gpio);
+
+	_clear_gpio_irqstatus(bank, gpio);
+}
+
+static void gpio_mask_irq(unsigned int irq)
+{
+	unsigned int gpio = irq - IH_GPIO_BASE;
+	struct gpio_bank *bank = get_gpio_bank(gpio);
+
+	_set_gpio_irqenable(bank, gpio, 0);
+}
+
+static void gpio_unmask_irq(unsigned int irq)
+{
+	unsigned int gpio = irq - IH_GPIO_BASE;
+	struct gpio_bank *bank = get_gpio_bank(gpio);
+
+	if (_get_gpio_edge_ctrl(bank, get_gpio_index(gpio)) == OMAP_GPIO_NO_EDGE) {
+		printk(KERN_ERR "OMAP GPIO %d: trying to enable GPIO IRQ while no edge is set\n",
+		       gpio);
+		_set_gpio_edge_ctrl(bank, get_gpio_index(gpio), OMAP_GPIO_RISING_EDGE);
+	}
+	_set_gpio_irqenable(bank, gpio, 1);
+}
+
+static void mpuio_ack_irq(unsigned int irq)
+{
+	/* The ISR is reset automatically, so do nothing here. */
+}
+
+static void mpuio_mask_irq(unsigned int irq)
+{
+	unsigned int gpio = OMAP_MPUIO(irq - IH_MPUIO_BASE);
+	struct gpio_bank *bank = get_gpio_bank(gpio);
+
+	_set_gpio_irqenable(bank, gpio, 0);
+}
+
+static void mpuio_unmask_irq(unsigned int irq)
+{
+	unsigned int gpio = OMAP_MPUIO(irq - IH_MPUIO_BASE);
+	struct gpio_bank *bank = get_gpio_bank(gpio);
+
+	_set_gpio_irqenable(bank, gpio, 1);
+}
+
+static struct irqchip gpio_irq_chip = {
+	.ack	= gpio_ack_irq,
+	.mask	= gpio_mask_irq,
+	.unmask = gpio_unmask_irq,
+};
+
+static struct irqchip mpuio_irq_chip = {
+	.ack	= mpuio_ack_irq,
+	.mask	= mpuio_mask_irq,
+	.unmask = mpuio_unmask_irq
+};
+
+static int initialized = 0;
+
+static int __init _omap_gpio_init(void)
+{
+	int i;
+	struct gpio_bank *bank;
+
+	initialized = 1;
+
+#ifdef CONFIG_ARCH_OMAP1510
+	if (cpu_is_omap1510()) {
+		printk(KERN_INFO "OMAP1510 GPIO hardware\n");
+		gpio_bank_count = 2;
+		gpio_bank = gpio_bank_1510;
+	}
+#endif
+#if defined(CONFIG_ARCH_OMAP16XX)
+	if (cpu_is_omap16xx()) {
+		int rev;
+
+		gpio_bank_count = 5;
+		gpio_bank = gpio_bank_1610;
+		rev = omap_readw(gpio_bank[1].base + OMAP1610_GPIO_REVISION);
+		printk(KERN_INFO "OMAP GPIO hardware version %d.%d\n",
+		       (rev >> 4) & 0x0f, rev & 0x0f);
+	}
+#endif
+#ifdef CONFIG_ARCH_OMAP730
+	if (cpu_is_omap730()) {
+		printk(KERN_INFO "OMAP730 GPIO hardware\n");
+		gpio_bank_count = 7;
+		gpio_bank = gpio_bank_730;
+	}
+#endif
+	for (i = 0; i < gpio_bank_count; i++) {
+		int j, gpio_count = 16;
+
+		bank = &gpio_bank[i];
+		bank->reserved_map = 0;
+		bank->base = IO_ADDRESS(bank->base);
+		spin_lock_init(&bank->lock);
+		if (bank->method == METHOD_MPUIO) {
+			omap_writew(0xFFFF, OMAP_MPUIO_BASE + OMAP_MPUIO_GPIO_MASKIT);
+		}
+#ifdef CONFIG_ARCH_OMAP1510
+		if (bank->method == METHOD_GPIO_1510) {
+			__raw_writew(0xffff, bank->base + OMAP1510_GPIO_INT_MASK);
+			__raw_writew(0x0000, bank->base + OMAP1510_GPIO_INT_STATUS);
+		}
+#endif
+#if defined(CONFIG_ARCH_OMAP16XX)
+		if (bank->method == METHOD_GPIO_1610) {
+			__raw_writew(0x0000, bank->base + OMAP1610_GPIO_IRQENABLE1);
+			__raw_writew(0xffff, bank->base + OMAP1610_GPIO_IRQSTATUS1);
+		}
+#endif
+#ifdef CONFIG_ARCH_OMAP730
+		if (bank->method == METHOD_GPIO_730) {
+			__raw_writel(0xffffffff, bank->base + OMAP730_GPIO_INT_MASK);
+			__raw_writel(0x00000000, bank->base + OMAP730_GPIO_INT_STATUS);
+
+			gpio_count = 32; /* 730 has 32-bit GPIOs */
+		}
+#endif
+		for (j = bank->virtual_irq_start;
+		     j < bank->virtual_irq_start + gpio_count; j++) {
+			if (bank->method == METHOD_MPUIO)
+				set_irq_chip(j, &mpuio_irq_chip);
+			else
+				set_irq_chip(j, &gpio_irq_chip);
+			set_irq_handler(j, do_simple_IRQ);
+			set_irq_flags(j, IRQF_VALID);
+		}
+		set_irq_chained_handler(bank->irq, gpio_irq_handler);
+		set_irq_data(bank->irq, bank);
+	}
+
+	/* Enable system clock for GPIO module.
+	 * The CAM_CLK_CTRL *is* really the right place. */
+	if (cpu_is_omap1610() || cpu_is_omap1710())
+		omap_writel(omap_readl(ULPD_CAM_CLK_CTRL) | 0x04, ULPD_CAM_CLK_CTRL);
+
+	return 0;
+}
+
+/*
+ * This may get called early from board specific init
+ */
+int omap_gpio_init(void)
+{
+	if (!initialized)
+		return _omap_gpio_init();
+	else
+		return 0;
+}
+
+EXPORT_SYMBOL(omap_request_gpio);
+EXPORT_SYMBOL(omap_free_gpio);
+EXPORT_SYMBOL(omap_set_gpio_direction);
+EXPORT_SYMBOL(omap_set_gpio_dataout);
+EXPORT_SYMBOL(omap_get_gpio_datain);
+EXPORT_SYMBOL(omap_set_gpio_edge_ctrl);
+
+arch_initcall(omap_gpio_init);
diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c
new file mode 100644
--- /dev/null
+++ b/arch/arm/plat-omap/mcbsp.c
@@ -0,0 +1,758 @@
+/*
+ * linux/arch/arm/plat-omap/mcbsp.c
+ *
+ * Copyright (C) 2004 Nokia Corporation
+ * Author: Samuel Ortiz <samuel.ortiz@nokia.com>
+ *
+ *
+ * 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.
+ *
+ * Multichannel mode not supported.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/wait.h>
+#include <linux/completion.h>
+#include <linux/interrupt.h>
+#include <linux/err.h>
+
+#include <asm/delay.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+
+#include <asm/arch/dma.h>
+#include <asm/arch/mux.h>
+#include <asm/arch/irqs.h>
+#include <asm/arch/mcbsp.h>
+
+#include <asm/hardware/clock.h>
+
+#ifdef CONFIG_MCBSP_DEBUG
+#define DBG(x...)	printk(x)
+#else
+#define DBG(x...)	do { } while (0)
+#endif
+
+struct omap_mcbsp {
+	u32                          io_base;
+	u8                           id;
+	u8                           free;
+	omap_mcbsp_word_length       rx_word_length;
+	omap_mcbsp_word_length       tx_word_length;
+
+	/* IRQ based TX/RX */
+	int                          rx_irq;
+	int                          tx_irq;
+
+	/* DMA stuff */
+	u8                           dma_rx_sync;
+	short                        dma_rx_lch;
+	u8                           dma_tx_sync;
+	short                        dma_tx_lch;
+
+	/* Completion queues */
+	struct completion            tx_irq_completion;
+	struct completion            rx_irq_completion;
+	struct completion            tx_dma_completion;
+	struct completion            rx_dma_completion;
+
+	spinlock_t                   lock;
+};
+
+static struct omap_mcbsp mcbsp[OMAP_MAX_MCBSP_COUNT];
+static struct clk *mcbsp_dsp_ck = 0;
+static struct clk *mcbsp_api_ck = 0;
+static struct clk *mcbsp_dspxor_ck = 0;
+
+
+static void omap_mcbsp_dump_reg(u8 id)
+{
+	DBG("**** MCBSP%d regs ****\n", mcbsp[id].id);
+	DBG("DRR2:  0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, DRR2));
+	DBG("DRR1:  0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, DRR1));
+	DBG("DXR2:  0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, DXR2));
+	DBG("DXR1:  0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, DXR1));
+	DBG("SPCR2: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, SPCR2));
+	DBG("SPCR1: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, SPCR1));
+	DBG("RCR2:  0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, RCR2));
+	DBG("RCR1:  0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, RCR1));
+	DBG("XCR2:  0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, XCR2));
+	DBG("XCR1:  0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, XCR1));
+	DBG("SRGR2: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, SRGR2));
+	DBG("SRGR1: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, SRGR1));
+	DBG("PCR0:  0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, PCR0));
+	DBG("***********************\n");
+}
+
+
+static irqreturn_t omap_mcbsp_tx_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct omap_mcbsp * mcbsp_tx = (struct omap_mcbsp *)(dev_id);
+
+	DBG("TX IRQ callback : 0x%x\n", OMAP_MCBSP_READ(mcbsp_tx->io_base, SPCR2));
+
+	complete(&mcbsp_tx->tx_irq_completion);
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t omap_mcbsp_rx_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct omap_mcbsp * mcbsp_rx = (struct omap_mcbsp *)(dev_id);
+
+	DBG("RX IRQ callback : 0x%x\n", OMAP_MCBSP_READ(mcbsp_rx->io_base, SPCR2));
+
+	complete(&mcbsp_rx->rx_irq_completion);
+	return IRQ_HANDLED;
+}
+
+
+static void omap_mcbsp_tx_dma_callback(int lch, u16 ch_status, void *data)
+{
+	struct omap_mcbsp * mcbsp_dma_tx = (struct omap_mcbsp *)(data);
+
+	DBG("TX DMA callback : 0x%x\n", OMAP_MCBSP_READ(mcbsp_dma_tx->io_base, SPCR2));
+
+	/* We can free the channels */
+	omap_free_dma(mcbsp_dma_tx->dma_tx_lch);
+	mcbsp_dma_tx->dma_tx_lch = -1;
+
+	complete(&mcbsp_dma_tx->tx_dma_completion);
+}
+
+static void omap_mcbsp_rx_dma_callback(int lch, u16 ch_status, void *data)
+{
+	struct omap_mcbsp * mcbsp_dma_rx = (struct omap_mcbsp *)(data);
+
+	DBG("RX DMA callback : 0x%x\n", OMAP_MCBSP_READ(mcbsp_dma_rx->io_base, SPCR2));
+
+	/* We can free the channels */
+	omap_free_dma(mcbsp_dma_rx->dma_rx_lch);
+	mcbsp_dma_rx->dma_rx_lch = -1;
+
+	complete(&mcbsp_dma_rx->rx_dma_completion);
+}
+
+
+/*
+ * omap_mcbsp_config simply write a config to the
+ * appropriate McBSP.
+ * You either call this function or set the McBSP registers
+ * by yourself before calling omap_mcbsp_start().
+ */
+
+void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg * config)
+{
+	u32 io_base = mcbsp[id].io_base;
+
+	DBG("OMAP-McBSP: McBSP%d  io_base: 0x%8x\n", id+1, io_base);
+
+	/* We write the given config */
+	OMAP_MCBSP_WRITE(io_base, SPCR2, config->spcr2);
+	OMAP_MCBSP_WRITE(io_base, SPCR1, config->spcr1);
+	OMAP_MCBSP_WRITE(io_base, RCR2, config->rcr2);
+	OMAP_MCBSP_WRITE(io_base, RCR1, config->rcr1);
+	OMAP_MCBSP_WRITE(io_base, XCR2, config->xcr2);
+	OMAP_MCBSP_WRITE(io_base, XCR1, config->xcr1);
+	OMAP_MCBSP_WRITE(io_base, SRGR2, config->srgr2);
+	OMAP_MCBSP_WRITE(io_base, SRGR1, config->srgr1);
+	OMAP_MCBSP_WRITE(io_base, MCR2, config->mcr2);
+	OMAP_MCBSP_WRITE(io_base, MCR1, config->mcr1);
+	OMAP_MCBSP_WRITE(io_base, PCR0, config->pcr0);
+}
+
+
+
+static int omap_mcbsp_check(unsigned int id)
+{
+	if (cpu_is_omap730()) {
+		if (id > OMAP_MAX_MCBSP_COUNT - 1) {
+		       printk(KERN_ERR "OMAP-McBSP: McBSP%d doesn't exist\n", id + 1);
+		       return -1;
+		}
+		return 0;
+	}
+
+	if (cpu_is_omap1510() || cpu_is_omap16xx()) {
+		if (id > OMAP_MAX_MCBSP_COUNT) {
+			printk(KERN_ERR "OMAP-McBSP: McBSP%d doesn't exist\n", id + 1);
+			return -1;
+		}
+		return 0;
+	}
+
+	return -1;
+}
+
+#define EN_XORPCK		1
+#define DSP_RSTCT2              0xe1008014
+
+static void omap_mcbsp_dsp_request(void)
+{
+	if (cpu_is_omap1510() || cpu_is_omap16xx()) {
+		clk_use(mcbsp_dsp_ck);
+		clk_use(mcbsp_api_ck);
+
+		/* enable 12MHz clock to mcbsp 1 & 3 */
+		clk_use(mcbsp_dspxor_ck);
+		__raw_writew(__raw_readw(DSP_RSTCT2) | 1 | 1 << 1,
+			     DSP_RSTCT2);
+	}
+}
+
+static void omap_mcbsp_dsp_free(void)
+{
+	if (cpu_is_omap1510() || cpu_is_omap16xx()) {
+		clk_unuse(mcbsp_dspxor_ck);
+		clk_unuse(mcbsp_dsp_ck);
+		clk_unuse(mcbsp_api_ck);
+	}
+}
+
+int omap_mcbsp_request(unsigned int id)
+{
+	int err;
+
+	if (omap_mcbsp_check(id) < 0)
+		return -EINVAL;
+
+	/*
+	 * On 1510, 1610 and 1710, McBSP1 and McBSP3
+	 * are DSP public peripherals.
+	 */
+	if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3)
+		omap_mcbsp_dsp_request();
+
+	spin_lock(&mcbsp[id].lock);
+	if (!mcbsp[id].free) {
+		printk (KERN_ERR "OMAP-McBSP: McBSP%d is currently in use\n", id + 1);
+		spin_unlock(&mcbsp[id].lock);
+		return -1;
+	}
+
+	mcbsp[id].free = 0;
+	spin_unlock(&mcbsp[id].lock);
+
+	/* We need to get IRQs here */
+	err = request_irq(mcbsp[id].tx_irq, omap_mcbsp_tx_irq_handler, 0,
+			  "McBSP",
+			  (void *) (&mcbsp[id]));
+	if (err != 0) {
+		printk(KERN_ERR "OMAP-McBSP: Unable to request TX IRQ %d for McBSP%d\n",
+		       mcbsp[id].tx_irq, mcbsp[id].id);
+		return err;
+	}
+
+	init_completion(&(mcbsp[id].tx_irq_completion));
+
+
+	err = request_irq(mcbsp[id].rx_irq, omap_mcbsp_rx_irq_handler, 0,
+			  "McBSP",
+			  (void *) (&mcbsp[id]));
+	if (err != 0) {
+		printk(KERN_ERR "OMAP-McBSP: Unable to request RX IRQ %d for McBSP%d\n",
+		       mcbsp[id].rx_irq, mcbsp[id].id);
+		free_irq(mcbsp[id].tx_irq, (void *) (&mcbsp[id]));
+		return err;
+	}
+
+	init_completion(&(mcbsp[id].rx_irq_completion));
+	return 0;
+
+}
+
+void omap_mcbsp_free(unsigned int id)
+{
+	if (omap_mcbsp_check(id) < 0)
+		return;
+
+	if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3)
+		omap_mcbsp_dsp_free();
+
+	spin_lock(&mcbsp[id].lock);
+	if (mcbsp[id].free) {
+		printk (KERN_ERR "OMAP-McBSP: McBSP%d was not reserved\n", id + 1);
+		spin_unlock(&mcbsp[id].lock);
+		return;
+	}
+
+	mcbsp[id].free = 1;
+	spin_unlock(&mcbsp[id].lock);
+
+	/* Free IRQs */
+	free_irq(mcbsp[id].rx_irq, (void *) (&mcbsp[id]));
+	free_irq(mcbsp[id].tx_irq, (void *) (&mcbsp[id]));
+}
+
+/*
+ * Here we start the McBSP, by enabling the sample
+ * generator, both transmitter and receivers,
+ * and the frame sync.
+ */
+void omap_mcbsp_start(unsigned int id)
+{
+	u32 io_base;
+	u16 w;
+
+	if (omap_mcbsp_check(id) < 0)
+		return;
+
+	io_base = mcbsp[id].io_base;
+
+	mcbsp[id].rx_word_length = ((OMAP_MCBSP_READ(io_base, RCR1) >> 5) & 0x7);
+	mcbsp[id].tx_word_length = ((OMAP_MCBSP_READ(io_base, XCR1) >> 5) & 0x7);
+
+	/* Start the sample generator */
+	w = OMAP_MCBSP_READ(io_base, SPCR2);
+	OMAP_MCBSP_WRITE(io_base, SPCR2, w | (1 << 6));
+
+	/* Enable transmitter and receiver */
+	w = OMAP_MCBSP_READ(io_base, SPCR2);
+	OMAP_MCBSP_WRITE(io_base, SPCR2, w | 1);
+
+	w = OMAP_MCBSP_READ(io_base, SPCR1);
+	OMAP_MCBSP_WRITE(io_base, SPCR1, w | 1);
+
+	udelay(100);
+
+	/* Start frame sync */
+	w = OMAP_MCBSP_READ(io_base, SPCR2);
+	OMAP_MCBSP_WRITE(io_base, SPCR2, w | (1 << 7));
+
+	/* Dump McBSP Regs */
+	omap_mcbsp_dump_reg(id);
+
+}
+
+void omap_mcbsp_stop(unsigned int id)
+{
+	u32 io_base;
+	u16 w;
+
+	if (omap_mcbsp_check(id) < 0)
+		return;
+
+	io_base = mcbsp[id].io_base;
+
+        /* Reset transmitter */
+	w = OMAP_MCBSP_READ(io_base, SPCR2);
+	OMAP_MCBSP_WRITE(io_base, SPCR2, w & ~(1));
+
+	/* Reset receiver */
+	w = OMAP_MCBSP_READ(io_base, SPCR1);
+	OMAP_MCBSP_WRITE(io_base, SPCR1, w & ~(1));
+
+	/* Reset the sample rate generator */
+	w = OMAP_MCBSP_READ(io_base, SPCR2);
+	OMAP_MCBSP_WRITE(io_base, SPCR2, w & ~(1 << 6));
+}
+
+
+/* polled mcbsp i/o operations */
+int omap_mcbsp_pollwrite(unsigned int id, u16 buf)
+{
+	u32 base = mcbsp[id].io_base;
+	writew(buf, base + OMAP_MCBSP_REG_DXR1);
+	/* if frame sync error - clear the error */
+	if (readw(base + OMAP_MCBSP_REG_SPCR2) & XSYNC_ERR) {
+		/* clear error */
+		writew(readw(base + OMAP_MCBSP_REG_SPCR2) & (~XSYNC_ERR),
+		       base + OMAP_MCBSP_REG_SPCR2);
+		/* resend */
+		return -1;
+	} else {
+		/* wait for transmit confirmation */
+		int attemps = 0;
+		while (!(readw(base + OMAP_MCBSP_REG_SPCR2) & XRDY)) {
+			if (attemps++ > 1000) {
+				writew(readw(base + OMAP_MCBSP_REG_SPCR2) &
+				       (~XRST),
+				       base + OMAP_MCBSP_REG_SPCR2);
+				udelay(10);
+				writew(readw(base + OMAP_MCBSP_REG_SPCR2) |
+				       (XRST),
+				       base + OMAP_MCBSP_REG_SPCR2);
+				udelay(10);
+				printk(KERN_ERR
+				       " Could not write to McBSP Register\n");
+				return -2;
+			}
+		}
+	}
+	return 0;
+}
+
+int omap_mcbsp_pollread(unsigned int id, u16 * buf)
+{
+	u32 base = mcbsp[id].io_base;
+	/* if frame sync error - clear the error */
+	if (readw(base + OMAP_MCBSP_REG_SPCR1) & RSYNC_ERR) {
+		/* clear error */
+		writew(readw(base + OMAP_MCBSP_REG_SPCR1) & (~RSYNC_ERR),
+		       base + OMAP_MCBSP_REG_SPCR1);
+		/* resend */
+		return -1;
+	} else {
+		/* wait for recieve confirmation */
+		int attemps = 0;
+		while (!(readw(base + OMAP_MCBSP_REG_SPCR1) & RRDY)) {
+			if (attemps++ > 1000) {
+				writew(readw(base + OMAP_MCBSP_REG_SPCR1) &
+				       (~RRST),
+				       base + OMAP_MCBSP_REG_SPCR1);
+				udelay(10);
+				writew(readw(base + OMAP_MCBSP_REG_SPCR1) |
+				       (RRST),
+				       base + OMAP_MCBSP_REG_SPCR1);
+				udelay(10);
+				printk(KERN_ERR
+				       " Could not read from McBSP Register\n");
+				return -2;
+			}
+		}
+	}
+	*buf = readw(base + OMAP_MCBSP_REG_DRR1);
+	return 0;
+}
+
+/*
+ * IRQ based word transmission.
+ */
+void omap_mcbsp_xmit_word(unsigned int id, u32 word)
+{
+	u32 io_base;
+	omap_mcbsp_word_length word_length = mcbsp[id].tx_word_length;
+
+	if (omap_mcbsp_check(id) < 0)
+		return;
+
+	io_base = mcbsp[id].io_base;
+
+	wait_for_completion(&(mcbsp[id].tx_irq_completion));
+
+	if (word_length > OMAP_MCBSP_WORD_16)
+		OMAP_MCBSP_WRITE(io_base, DXR2, word >> 16);
+	OMAP_MCBSP_WRITE(io_base, DXR1, word & 0xffff);
+}
+
+u32 omap_mcbsp_recv_word(unsigned int id)
+{
+	u32 io_base;
+	u16 word_lsb, word_msb = 0;
+	omap_mcbsp_word_length word_length = mcbsp[id].rx_word_length;
+
+	if (omap_mcbsp_check(id) < 0)
+		return -EINVAL;
+
+	io_base = mcbsp[id].io_base;
+
+	wait_for_completion(&(mcbsp[id].rx_irq_completion));
+
+	if (word_length > OMAP_MCBSP_WORD_16)
+		word_msb = OMAP_MCBSP_READ(io_base, DRR2);
+	word_lsb = OMAP_MCBSP_READ(io_base, DRR1);
+
+	return (word_lsb | (word_msb << 16));
+}
+
+
+/*
+ * Simple DMA based buffer rx/tx routines.
+ * Nothing fancy, just a single buffer tx/rx through DMA.
+ * The DMA resources are released once the transfer is done.
+ * For anything fancier, you should use your own customized DMA
+ * routines and callbacks.
+ */
+int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer, unsigned int length)
+{
+	int dma_tx_ch;
+
+	if (omap_mcbsp_check(id) < 0)
+		return -EINVAL;
+
+	if (omap_request_dma(mcbsp[id].dma_tx_sync, "McBSP TX", omap_mcbsp_tx_dma_callback,
+			     &mcbsp[id],
+			     &dma_tx_ch)) {
+		printk("OMAP-McBSP: Unable to request DMA channel for McBSP%d TX. Trying IRQ based TX\n", id+1);
+		return -EAGAIN;
+	}
+	mcbsp[id].dma_tx_lch = dma_tx_ch;
+
+	DBG("TX DMA on channel %d\n", dma_tx_ch);
+
+	init_completion(&(mcbsp[id].tx_dma_completion));
+
+	omap_set_dma_transfer_params(mcbsp[id].dma_tx_lch,
+				     OMAP_DMA_DATA_TYPE_S16,
+				     length >> 1, 1,
+				     OMAP_DMA_SYNC_ELEMENT);
+
+	omap_set_dma_dest_params(mcbsp[id].dma_tx_lch,
+				 OMAP_DMA_PORT_TIPB,
+				 OMAP_DMA_AMODE_CONSTANT,
+				 mcbsp[id].io_base + OMAP_MCBSP_REG_DXR1);
+
+	omap_set_dma_src_params(mcbsp[id].dma_tx_lch,
+				OMAP_DMA_PORT_EMIFF,
+				OMAP_DMA_AMODE_POST_INC,
+				buffer);
+
+	omap_start_dma(mcbsp[id].dma_tx_lch);
+	wait_for_completion(&(mcbsp[id].tx_dma_completion));
+	return 0;
+}
+
+
+int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer, unsigned int length)
+{
+	int dma_rx_ch;
+
+	if (omap_mcbsp_check(id) < 0)
+		return -EINVAL;
+
+	if (omap_request_dma(mcbsp[id].dma_rx_sync, "McBSP RX", omap_mcbsp_rx_dma_callback,
+			     &mcbsp[id],
+			     &dma_rx_ch)) {
+		printk("Unable to request DMA channel for McBSP%d RX. Trying IRQ based RX\n", id+1);
+		return -EAGAIN;
+	}
+	mcbsp[id].dma_rx_lch = dma_rx_ch;
+
+	DBG("RX DMA on channel %d\n", dma_rx_ch);
+
+	init_completion(&(mcbsp[id].rx_dma_completion));
+
+	omap_set_dma_transfer_params(mcbsp[id].dma_rx_lch,
+				     OMAP_DMA_DATA_TYPE_S16,
+				     length >> 1, 1,
+				     OMAP_DMA_SYNC_ELEMENT);
+
+	omap_set_dma_src_params(mcbsp[id].dma_rx_lch,
+				OMAP_DMA_PORT_TIPB,
+				OMAP_DMA_AMODE_CONSTANT,
+				mcbsp[id].io_base + OMAP_MCBSP_REG_DRR1);
+
+	omap_set_dma_dest_params(mcbsp[id].dma_rx_lch,
+				 OMAP_DMA_PORT_EMIFF,
+				 OMAP_DMA_AMODE_POST_INC,
+				 buffer);
+
+	omap_start_dma(mcbsp[id].dma_rx_lch);
+	wait_for_completion(&(mcbsp[id].rx_dma_completion));
+	return 0;
+}
+
+
+/*
+ * SPI wrapper.
+ * Since SPI setup is much simpler than the generic McBSP one,
+ * this wrapper just need an omap_mcbsp_spi_cfg structure as an input.
+ * Once this is done, you can call omap_mcbsp_start().
+ */
+void omap_mcbsp_set_spi_mode(unsigned int id, const struct omap_mcbsp_spi_cfg * spi_cfg)
+{
+	struct omap_mcbsp_reg_cfg mcbsp_cfg;
+
+	if (omap_mcbsp_check(id) < 0)
+		return;
+
+	memset(&mcbsp_cfg, 0, sizeof(struct omap_mcbsp_reg_cfg));
+
+	/* SPI has only one frame */
+	mcbsp_cfg.rcr1 |= (RWDLEN1(spi_cfg->word_length) | RFRLEN1(0));
+	mcbsp_cfg.xcr1 |= (XWDLEN1(spi_cfg->word_length) | XFRLEN1(0));
+
+        /* Clock stop mode */
+	if (spi_cfg->clk_stp_mode == OMAP_MCBSP_CLK_STP_MODE_NO_DELAY)
+		mcbsp_cfg.spcr1 |= (1 << 12);
+	else
+		mcbsp_cfg.spcr1 |= (3 << 11);
+
+	/* Set clock parities */
+	if (spi_cfg->rx_clock_polarity == OMAP_MCBSP_CLK_RISING)
+		mcbsp_cfg.pcr0 |= CLKRP;
+	else
+		mcbsp_cfg.pcr0 &= ~CLKRP;
+
+	if (spi_cfg->tx_clock_polarity == OMAP_MCBSP_CLK_RISING)
+		mcbsp_cfg.pcr0 &= ~CLKXP;
+	else
+		mcbsp_cfg.pcr0 |= CLKXP;
+
+	/* Set SCLKME to 0 and CLKSM to 1 */
+	mcbsp_cfg.pcr0 &= ~SCLKME;
+	mcbsp_cfg.srgr2 |= CLKSM;
+
+	/* Set FSXP */
+	if (spi_cfg->fsx_polarity == OMAP_MCBSP_FS_ACTIVE_HIGH)
+		mcbsp_cfg.pcr0 &= ~FSXP;
+	else
+		mcbsp_cfg.pcr0 |= FSXP;
+
+	if (spi_cfg->spi_mode == OMAP_MCBSP_SPI_MASTER) {
+		mcbsp_cfg.pcr0 |= CLKXM;
+		mcbsp_cfg.srgr1 |= CLKGDV(spi_cfg->clk_div -1);
+		mcbsp_cfg.pcr0 |= FSXM;
+		mcbsp_cfg.srgr2 &= ~FSGM;
+		mcbsp_cfg.xcr2 |= XDATDLY(1);
+		mcbsp_cfg.rcr2 |= RDATDLY(1);
+	}
+	else {
+		mcbsp_cfg.pcr0 &= ~CLKXM;
+		mcbsp_cfg.srgr1 |= CLKGDV(1);
+		mcbsp_cfg.pcr0 &= ~FSXM;
+		mcbsp_cfg.xcr2 &= ~XDATDLY(3);
+		mcbsp_cfg.rcr2 &= ~RDATDLY(3);
+	}
+
+	mcbsp_cfg.xcr2 &= ~XPHASE;
+	mcbsp_cfg.rcr2 &= ~RPHASE;
+
+	omap_mcbsp_config(id, &mcbsp_cfg);
+}
+
+
+/*
+ * McBSP1 and McBSP3 are directly mapped on 1610 and 1510.
+ * 730 has only 2 McBSP, and both of them are MPU peripherals.
+ */
+struct omap_mcbsp_info {
+	u32 virt_base;
+	u8 dma_rx_sync, dma_tx_sync;
+	u16 rx_irq, tx_irq;
+};
+
+#ifdef CONFIG_ARCH_OMAP730
+static const struct omap_mcbsp_info mcbsp_730[] = {
+	[0] = { .virt_base = io_p2v(OMAP730_MCBSP1_BASE),
+		.dma_rx_sync = OMAP_DMA_MCBSP1_RX,
+		.dma_tx_sync = OMAP_DMA_MCBSP1_TX,
+		.rx_irq = INT_730_McBSP1RX,
+		.tx_irq = INT_730_McBSP1TX },
+	[1] = { .virt_base = io_p2v(OMAP730_MCBSP2_BASE),
+		.dma_rx_sync = OMAP_DMA_MCBSP3_RX,
+		.dma_tx_sync = OMAP_DMA_MCBSP3_TX,
+		.rx_irq = INT_730_McBSP2RX,
+		.tx_irq = INT_730_McBSP2TX },
+};
+#endif
+
+#ifdef CONFIG_ARCH_OMAP1510
+static const struct omap_mcbsp_info mcbsp_1510[] = {
+	[0] = { .virt_base = OMAP1510_MCBSP1_BASE,
+		.dma_rx_sync = OMAP_DMA_MCBSP1_RX,
+		.dma_tx_sync = OMAP_DMA_MCBSP1_TX,
+		.rx_irq = INT_McBSP1RX,
+		.tx_irq = INT_McBSP1TX },
+	[1] = { .virt_base = io_p2v(OMAP1510_MCBSP2_BASE),
+		.dma_rx_sync = OMAP_DMA_MCBSP2_RX,
+		.dma_tx_sync = OMAP_DMA_MCBSP2_TX,
+		.rx_irq = INT_1510_SPI_RX,
+		.tx_irq = INT_1510_SPI_TX },
+	[2] = { .virt_base = OMAP1510_MCBSP3_BASE,
+		.dma_rx_sync = OMAP_DMA_MCBSP3_RX,
+		.dma_tx_sync = OMAP_DMA_MCBSP3_TX,
+		.rx_irq = INT_McBSP3RX,
+		.tx_irq = INT_McBSP3TX },
+};
+#endif
+
+#if defined(CONFIG_ARCH_OMAP16XX)
+static const struct omap_mcbsp_info mcbsp_1610[] = {
+	[0] = { .virt_base = OMAP1610_MCBSP1_BASE,
+		.dma_rx_sync = OMAP_DMA_MCBSP1_RX,
+		.dma_tx_sync = OMAP_DMA_MCBSP1_TX,
+		.rx_irq = INT_McBSP1RX,
+		.tx_irq = INT_McBSP1TX },
+	[1] = { .virt_base = io_p2v(OMAP1610_MCBSP2_BASE),
+		.dma_rx_sync = OMAP_DMA_MCBSP2_RX,
+		.dma_tx_sync = OMAP_DMA_MCBSP2_TX,
+		.rx_irq = INT_1610_McBSP2_RX,
+		.tx_irq = INT_1610_McBSP2_TX },
+	[2] = { .virt_base = OMAP1610_MCBSP3_BASE,
+		.dma_rx_sync = OMAP_DMA_MCBSP3_RX,
+		.dma_tx_sync = OMAP_DMA_MCBSP3_TX,
+		.rx_irq = INT_McBSP3RX,
+		.tx_irq = INT_McBSP3TX },
+};
+#endif
+
+static int __init omap_mcbsp_init(void)
+{
+	int mcbsp_count = 0, i;
+	static const struct omap_mcbsp_info *mcbsp_info;
+
+	printk("Initializing OMAP McBSP system\n");
+
+	mcbsp_dsp_ck = clk_get(0, "dsp_ck");
+	if (IS_ERR(mcbsp_dsp_ck)) {
+		printk(KERN_ERR "mcbsp: could not acquire dsp_ck handle.\n");
+		return PTR_ERR(mcbsp_dsp_ck);
+	}
+	mcbsp_api_ck = clk_get(0, "api_ck");
+	if (IS_ERR(mcbsp_api_ck)) {
+		printk(KERN_ERR "mcbsp: could not acquire api_ck handle.\n");
+		return PTR_ERR(mcbsp_api_ck);
+	}
+	mcbsp_dspxor_ck = clk_get(0, "dspxor_ck");
+	if (IS_ERR(mcbsp_dspxor_ck)) {
+		printk(KERN_ERR "mcbsp: could not acquire dspxor_ck handle.\n");
+		return PTR_ERR(mcbsp_dspxor_ck);
+	}
+
+#ifdef CONFIG_ARCH_OMAP730
+	if (cpu_is_omap730()) {
+		mcbsp_info = mcbsp_730;
+		mcbsp_count = ARRAY_SIZE(mcbsp_730);
+	}
+#endif
+#ifdef CONFIG_ARCH_OMAP1510
+	if (cpu_is_omap1510()) {
+		mcbsp_info = mcbsp_1510;
+		mcbsp_count = ARRAY_SIZE(mcbsp_1510);
+	}
+#endif
+#if defined(CONFIG_ARCH_OMAP16XX)
+	if (cpu_is_omap16xx()) {
+		mcbsp_info = mcbsp_1610;
+		mcbsp_count = ARRAY_SIZE(mcbsp_1610);
+	}
+#endif
+	for (i = 0; i < OMAP_MAX_MCBSP_COUNT ; i++) {
+		if (i >= mcbsp_count) {
+			mcbsp[i].io_base = 0;
+			mcbsp[i].free = 0;
+                        continue;
+		}
+		mcbsp[i].id = i + 1;
+		mcbsp[i].free = 1;
+		mcbsp[i].dma_tx_lch = -1;
+		mcbsp[i].dma_rx_lch = -1;
+
+		mcbsp[i].io_base = mcbsp_info[i].virt_base;
+		mcbsp[i].tx_irq = mcbsp_info[i].tx_irq;
+		mcbsp[i].rx_irq = mcbsp_info[i].rx_irq;
+		mcbsp[i].dma_rx_sync = mcbsp_info[i].dma_rx_sync;
+		mcbsp[i].dma_tx_sync = mcbsp_info[i].dma_tx_sync;
+		spin_lock_init(&mcbsp[i].lock);
+	}
+
+	return 0;
+}
+
+
+arch_initcall(omap_mcbsp_init);
+
+EXPORT_SYMBOL(omap_mcbsp_config);
+EXPORT_SYMBOL(omap_mcbsp_request);
+EXPORT_SYMBOL(omap_mcbsp_free);
+EXPORT_SYMBOL(omap_mcbsp_start);
+EXPORT_SYMBOL(omap_mcbsp_stop);
+EXPORT_SYMBOL(omap_mcbsp_xmit_word);
+EXPORT_SYMBOL(omap_mcbsp_recv_word);
+EXPORT_SYMBOL(omap_mcbsp_xmit_buffer);
+EXPORT_SYMBOL(omap_mcbsp_recv_buffer);
+EXPORT_SYMBOL(omap_mcbsp_set_spi_mode);
diff --git a/arch/arm/plat-omap/mux.c b/arch/arm/plat-omap/mux.c
new file mode 100644
--- /dev/null
+++ b/arch/arm/plat-omap/mux.c
@@ -0,0 +1,160 @@
+/*
+ * linux/arch/arm/plat-omap/mux.c
+ *
+ * Utility to set the Omap MUX and PULL_DWN registers from a table in mux.h
+ *
+ * Copyright (C) 2003 Nokia Corporation
+ *
+ * Written by Tony Lindgren <tony.lindgren@nokia.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/config.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include <linux/spinlock.h>
+
+#define __MUX_C__
+#include <asm/arch/mux.h>
+
+#ifdef CONFIG_OMAP_MUX
+
+/*
+ * Sets the Omap MUX and PULL_DWN registers based on the table
+ */
+int __init_or_module
+omap_cfg_reg(const reg_cfg_t reg_cfg)
+{
+	static DEFINE_SPINLOCK(mux_spin_lock);
+
+	unsigned long flags;
+	reg_cfg_set *cfg;
+	unsigned int reg_orig = 0, reg = 0, pu_pd_orig = 0, pu_pd = 0,
+		pull_orig = 0, pull = 0;
+	unsigned int mask, warn = 0;
+
+	if (reg_cfg > ARRAY_SIZE(reg_cfg_table)) {
+		printk(KERN_ERR "MUX: reg_cfg %d\n", reg_cfg);
+		return -EINVAL;
+	}
+
+	cfg = (reg_cfg_set *)&reg_cfg_table[reg_cfg];
+
+	/* Check the mux register in question */
+	if (cfg->mux_reg) {
+		unsigned	tmp1, tmp2;
+
+		spin_lock_irqsave(&mux_spin_lock, flags);
+		reg_orig = omap_readl(cfg->mux_reg);
+
+		/* The mux registers always seem to be 3 bits long */
+		mask = (0x7 << cfg->mask_offset);
+		tmp1 = reg_orig & mask;
+		reg = reg_orig & ~mask;
+
+		tmp2 = (cfg->mask << cfg->mask_offset);
+		reg |= tmp2;
+
+		if (tmp1 != tmp2)
+			warn = 1;
+
+		omap_writel(reg, cfg->mux_reg);
+		spin_unlock_irqrestore(&mux_spin_lock, flags);
+	}
+
+	/* Check for pull up or pull down selection on 1610 */
+	if (!cpu_is_omap1510()) {
+		if (cfg->pu_pd_reg && cfg->pull_val) {
+			spin_lock_irqsave(&mux_spin_lock, flags);
+			pu_pd_orig = omap_readl(cfg->pu_pd_reg);
+			mask = 1 << cfg->pull_bit;
+
+			if (cfg->pu_pd_val) {
+				if (!(pu_pd_orig & mask))
+					warn = 1;
+				/* Use pull up */
+				pu_pd = pu_pd_orig | mask;
+			} else {
+				if (pu_pd_orig & mask)
+					warn = 1;
+				/* Use pull down */
+				pu_pd = pu_pd_orig & ~mask;
+			}
+			omap_writel(pu_pd, cfg->pu_pd_reg);
+			spin_unlock_irqrestore(&mux_spin_lock, flags);
+		}
+	}
+
+	/* Check for an associated pull down register */
+	if (cfg->pull_reg) {
+		spin_lock_irqsave(&mux_spin_lock, flags);
+		pull_orig = omap_readl(cfg->pull_reg);
+		mask = 1 << cfg->pull_bit;
+
+		if (cfg->pull_val) {
+			if (pull_orig & mask)
+				warn = 1;
+			/* Low bit = pull enabled */
+			pull = pull_orig & ~mask;
+		} else {
+			if (!(pull_orig & mask))
+				warn = 1;
+			/* High bit = pull disabled */
+			pull = pull_orig | mask;
+		}
+
+		omap_writel(pull, cfg->pull_reg);
+		spin_unlock_irqrestore(&mux_spin_lock, flags);
+	}
+
+	if (warn) {
+#ifdef CONFIG_OMAP_MUX_WARNINGS
+		printk(KERN_WARNING "MUX: initialized %s\n", cfg->name);
+#endif
+	}
+
+#ifdef CONFIG_OMAP_MUX_DEBUG
+	if (cfg->debug || warn) {
+		printk("MUX: Setting register %s\n", cfg->name);
+		printk("      %s (0x%08x) = 0x%08x -> 0x%08x\n",
+		       cfg->mux_reg_name, cfg->mux_reg, reg_orig, reg);
+
+		if (!cpu_is_omap1510()) {
+			if (cfg->pu_pd_reg && cfg->pull_val) {
+				printk("      %s (0x%08x) = 0x%08x -> 0x%08x\n",
+				       cfg->pu_pd_name, cfg->pu_pd_reg,
+				       pu_pd_orig, pu_pd);
+			}
+		}
+
+		if (cfg->pull_reg)
+			printk("      %s (0x%08x) = 0x%08x -> 0x%08x\n",
+			       cfg->pull_name, cfg->pull_reg, pull_orig, pull);
+	}
+#endif
+
+#ifdef CONFIG_OMAP_MUX_ERRORS
+	return warn ? -ETXTBSY : 0;
+#else
+	return 0;
+#endif
+}
+
+EXPORT_SYMBOL(omap_cfg_reg);
+
+#endif	/* CONFIG_OMAP_MUX */
diff --git a/arch/arm/plat-omap/ocpi.c b/arch/arm/plat-omap/ocpi.c
new file mode 100644
--- /dev/null
+++ b/arch/arm/plat-omap/ocpi.c
@@ -0,0 +1,113 @@
+/*
+ * linux/arch/arm/plat-omap/ocpi.c
+ *
+ * Minimal OCP bus support for omap16xx
+ *
+ * Copyright (C) 2003 - 2005 Nokia Corporation
+ * Written by Tony Lindgren <tony@atomide.com>
+ *
+ * Modified for clock framework by Paul Mundt <paul.mundt@nokia.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/config.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/err.h>
+
+#include <asm/io.h>
+#include <asm/hardware/clock.h>
+#include <asm/arch/hardware.h>
+
+#define OCPI_BASE		0xfffec320
+#define OCPI_FAULT		(OCPI_BASE + 0x00)
+#define OCPI_CMD_FAULT		(OCPI_BASE + 0x04)
+#define OCPI_SINT0		(OCPI_BASE + 0x08)
+#define OCPI_TABORT		(OCPI_BASE + 0x0c)
+#define OCPI_SINT1		(OCPI_BASE + 0x10)
+#define OCPI_PROT		(OCPI_BASE + 0x14)
+#define OCPI_SEC		(OCPI_BASE + 0x18)
+
+/* USB OHCI OCPI access error registers */
+#define HOSTUEADDR	0xfffba0e0
+#define HOSTUESTATUS	0xfffba0e4
+
+static struct clk *ocpi_ck;
+
+/*
+ * Enables device access to OMAP buses via the OCPI bridge
+ * FIXME: Add locking
+ */
+int ocpi_enable(void)
+{
+	unsigned int val;
+
+	if (!cpu_is_omap16xx())
+		return -ENODEV;
+
+	/* Make sure there's clock for OCPI */
+	clk_enable(ocpi_ck);
+
+	/* Enable access for OHCI in OCPI */
+	val = omap_readl(OCPI_PROT);
+	val &= ~0xff;
+	//val &= (1 << 0);	/* Allow access only to EMIFS */
+	omap_writel(val, OCPI_PROT);
+
+	val = omap_readl(OCPI_SEC);
+	val &= ~0xff;
+	omap_writel(val, OCPI_SEC);
+
+	return 0;
+}
+EXPORT_SYMBOL(ocpi_enable);
+
+static int __init omap_ocpi_init(void)
+{
+	if (!cpu_is_omap16xx())
+		return -ENODEV;
+
+	ocpi_ck = clk_get(NULL, "l3_ocpi_ck");
+	if (IS_ERR(ocpi_ck))
+		return PTR_ERR(ocpi_ck);
+
+	clk_use(ocpi_ck);
+	ocpi_enable();
+	printk("OMAP OCPI interconnect driver loaded\n");
+
+	return 0;
+}
+
+static void __exit omap_ocpi_exit(void)
+{
+	/* REVISIT: Disable OCPI */
+
+	if (!cpu_is_omap16xx())
+		return;
+
+	clk_unuse(ocpi_ck);
+	clk_put(ocpi_ck);
+}
+
+MODULE_AUTHOR("Tony Lindgren <tony@atomide.com>");
+MODULE_DESCRIPTION("OMAP OCPI bus controller module");
+MODULE_LICENSE("GPL");
+module_init(omap_ocpi_init);
+module_exit(omap_ocpi_exit);
diff --git a/arch/arm/plat-omap/pm.c b/arch/arm/plat-omap/pm.c
new file mode 100644
--- /dev/null
+++ b/arch/arm/plat-omap/pm.c
@@ -0,0 +1,632 @@
+/*
+ * linux/arch/arm/plat-omap/pm.c
+ *
+ * OMAP Power Management Routines
+ *
+ * Original code for the SA11x0:
+ * Copyright (c) 2001 Cliff Brake <cbrake@accelent.com>
+ *
+ * Modified for the PXA250 by Nicolas Pitre:
+ * Copyright (c) 2002 Monta Vista Software, Inc.
+ *
+ * Modified for the OMAP1510 by David Singleton:
+ * Copyright (c) 2002 Monta Vista Software, Inc.
+ *
+ * Cleanup 2004 for OMAP1510/1610 by Dirk Behme <dirk.behme@de.bosch.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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/pm.h>
+#include <linux/sched.h>
+#include <linux/proc_fs.h>
+#include <linux/pm.h>
+
+#include <asm/io.h>
+#include <asm/mach/time.h>
+#include <asm/mach-types.h>
+
+#include <asm/arch/omap16xx.h>
+#include <asm/arch/pm.h>
+#include <asm/arch/mux.h>
+#include <asm/arch/tc.h>
+#include <asm/arch/tps65010.h>
+
+#include "clock.h"
+
+static unsigned int arm_sleep_save[ARM_SLEEP_SAVE_SIZE];
+static unsigned short ulpd_sleep_save[ULPD_SLEEP_SAVE_SIZE];
+static unsigned int mpui1510_sleep_save[MPUI1510_SLEEP_SAVE_SIZE];
+static unsigned int mpui1610_sleep_save[MPUI1610_SLEEP_SAVE_SIZE];
+
+/*
+ * Let's power down on idle, but only if we are really
+ * idle, because once we start down the path of
+ * going idle we continue to do idle even if we get
+ * a clock tick interrupt . .
+ */
+void omap_pm_idle(void)
+{
+	int (*func_ptr)(void) = 0;
+	unsigned int mask32 = 0;
+
+	/*
+	 * If the DSP is being used let's just idle the CPU, the overhead
+	 * to wake up from Big Sleep is big, milliseconds versus micro
+	 * seconds for wait for interrupt.
+	 */
+
+	local_irq_disable();
+	local_fiq_disable();
+	if (need_resched()) {
+		local_fiq_enable();
+		local_irq_enable();
+		return;
+	}
+	mask32 = omap_readl(ARM_SYSST);
+
+	/*
+	 * Since an interrupt may set up a timer, we don't want to
+	 * reprogram the hardware timer with interrupts enabled.
+	 * Re-enable interrupts only after returning from idle.
+	 */
+	timer_dyn_reprogram();
+
+	if ((mask32 & DSP_IDLE) == 0) {
+		__asm__ volatile ("mcr	p15, 0, r0, c7, c0, 4");
+	} else {
+
+		if (cpu_is_omap1510()) {
+			func_ptr = (void *)(OMAP1510_SRAM_IDLE_SUSPEND);
+		} else if (cpu_is_omap1610() || cpu_is_omap1710()) {
+			func_ptr = (void *)(OMAP1610_SRAM_IDLE_SUSPEND);
+		} else if (cpu_is_omap5912()) {
+			func_ptr = (void *)(OMAP5912_SRAM_IDLE_SUSPEND);
+		}
+
+		func_ptr();
+	}
+	local_fiq_enable();
+	local_irq_enable();
+}
+
+/*
+ * Configuration of the wakeup event is board specific. For the
+ * moment we put it into this helper function. Later it may move
+ * to board specific files.
+ */
+static void omap_pm_wakeup_setup(void)
+{
+	/*
+	 * Enable ARM XOR clock and release peripheral from reset by
+	 * writing 1 to PER_EN bit in ARM_RSTCT2, this is required
+	 * for UART configuration to use UART2 to wake up.
+	 */
+
+	omap_writel(omap_readl(ARM_IDLECT2) | ENABLE_XORCLK, ARM_IDLECT2);
+	omap_writel(omap_readl(ARM_RSTCT2) | PER_EN, ARM_RSTCT2);
+	omap_writew(MODEM_32K_EN, ULPD_CLOCK_CTRL);
+
+	/*
+	 * Turn off all interrupts except L1-2nd level cascade,
+	 * and the L2 wakeup interrupts: keypad and UART2.
+	 */
+
+	omap_writel(~IRQ_LEVEL2, OMAP_IH1_MIR);
+
+	if (cpu_is_omap1510()) {
+		omap_writel(~(IRQ_UART2 | IRQ_KEYBOARD),  OMAP_IH2_MIR);
+	}
+
+	if (cpu_is_omap16xx()) {
+		omap_writel(~(IRQ_UART2 | IRQ_KEYBOARD), OMAP_IH2_0_MIR);
+
+		omap_writel(~0x0, OMAP_IH2_1_MIR);
+		omap_writel(~0x0, OMAP_IH2_2_MIR);
+		omap_writel(~0x0, OMAP_IH2_3_MIR);
+	}
+
+	/*  New IRQ agreement */
+ 	omap_writel(1, OMAP_IH1_CONTROL);
+
+	/* external PULL to down, bit 22 = 0 */
+	omap_writel(omap_readl(PULL_DWN_CTRL_2) & ~(1<<22), PULL_DWN_CTRL_2);
+}
+
+void omap_pm_suspend(void)
+{
+	unsigned int mask32 = 0;
+	unsigned long arg0 = 0, arg1 = 0;
+	int (*func_ptr)(unsigned short, unsigned short) = 0;
+	unsigned short save_dsp_idlect2;
+
+	printk("PM: OMAP%x is entering deep sleep now ...\n", system_rev);
+
+	if (machine_is_omap_osk()) {
+		/* Stop LED1 (D9) blink */
+		tps65010_set_led(LED1, OFF);
+	}
+
+	/*
+	 * Step 1: turn off interrupts
+	 */
+
+	local_irq_disable();
+	local_fiq_disable();
+
+	/*
+	 * Step 2: save registers
+	 *
+	 * The omap is a strange/beautiful device. The caches, memory
+	 * and register state are preserved across power saves.
+	 * We have to save and restore very little register state to
+	 * idle the omap.
+         *
+ 	 * Save interrupt, MPUI, ARM and UPLD control registers.
+	 */
+
+	if (cpu_is_omap1510()) {
+		MPUI1510_SAVE(OMAP_IH1_MIR);
+		MPUI1510_SAVE(OMAP_IH2_MIR);
+		MPUI1510_SAVE(MPUI_CTRL);
+		MPUI1510_SAVE(MPUI_DSP_BOOT_CONFIG);
+		MPUI1510_SAVE(MPUI_DSP_API_CONFIG);
+		MPUI1510_SAVE(EMIFS_CONFIG);
+		MPUI1510_SAVE(EMIFF_SDRAM_CONFIG);
+	} else if (cpu_is_omap16xx()) {
+		MPUI1610_SAVE(OMAP_IH1_MIR);
+		MPUI1610_SAVE(OMAP_IH2_0_MIR);
+		MPUI1610_SAVE(OMAP_IH2_1_MIR);
+		MPUI1610_SAVE(OMAP_IH2_2_MIR);
+		MPUI1610_SAVE(OMAP_IH2_3_MIR);
+		MPUI1610_SAVE(MPUI_CTRL);
+		MPUI1610_SAVE(MPUI_DSP_BOOT_CONFIG);
+		MPUI1610_SAVE(MPUI_DSP_API_CONFIG);
+		MPUI1610_SAVE(EMIFS_CONFIG);
+		MPUI1610_SAVE(EMIFF_SDRAM_CONFIG);
+	}
+
+	ARM_SAVE(ARM_CKCTL);
+	ARM_SAVE(ARM_IDLECT1);
+	ARM_SAVE(ARM_IDLECT2);
+	ARM_SAVE(ARM_EWUPCT);
+	ARM_SAVE(ARM_RSTCT1);
+	ARM_SAVE(ARM_RSTCT2);
+	ARM_SAVE(ARM_SYSST);
+	ULPD_SAVE(ULPD_CLOCK_CTRL);
+	ULPD_SAVE(ULPD_STATUS_REQ);
+
+	/*
+	 * Step 3: LOW_PWR signal enabling
+	 *
+	 * Allow the LOW_PWR signal to be visible on MPUIO5 ball.
+	 */
+	if (cpu_is_omap1510()) {
+		/* POWER_CTRL_REG = 0x1 (LOW_POWER is available) */
+		omap_writew(omap_readw(ULPD_POWER_CTRL) |
+			    OMAP1510_ULPD_LOW_POWER_REQ, ULPD_POWER_CTRL);
+	} else if (cpu_is_omap16xx()) {
+		/* POWER_CTRL_REG = 0x1 (LOW_POWER is available) */
+		omap_writew(omap_readw(ULPD_POWER_CTRL) |
+			    OMAP1610_ULPD_LOW_POWER_REQ, ULPD_POWER_CTRL);
+	}
+
+	/* configure LOW_PWR pin */
+	omap_cfg_reg(T20_1610_LOW_PWR);
+
+	/*
+	 * Step 4: OMAP DSP Shutdown
+	 */
+
+	/* Set DSP_RST = 1 and DSP_EN = 0, put DSP block into reset */
+	omap_writel((omap_readl(ARM_RSTCT1) | DSP_RST) & ~DSP_ENABLE,
+		    ARM_RSTCT1);
+
+	/* Set DSP boot mode to DSP-IDLE, DSP_BOOT_MODE = 0x2 */
+        omap_writel(DSP_IDLE_MODE, MPUI_DSP_BOOT_CONFIG);
+
+	/* Set EN_DSPCK = 0, stop DSP block clock */
+	omap_writel(omap_readl(ARM_CKCTL) & ~DSP_CLOCK_ENABLE, ARM_CKCTL);
+
+	/* Stop any DSP domain clocks */
+	omap_writel(omap_readl(ARM_IDLECT2) | (1<<EN_APICK), ARM_IDLECT2);
+	save_dsp_idlect2 = __raw_readw(DSP_IDLECT2);
+	__raw_writew(0, DSP_IDLECT2);
+
+	/*
+	 * Step 5: Wakeup Event Setup
+	 */
+
+	omap_pm_wakeup_setup();
+
+	/*
+	 * Step 6a: ARM and Traffic controller shutdown
+	 *
+	 * Step 6 starts here with clock and watchdog disable
+	 */
+
+	/* stop clocks */
+	mask32 = omap_readl(ARM_IDLECT2);
+	mask32 &= ~(1<<EN_WDTCK);  /* bit 0 -> 0 (WDT clock) */
+	mask32 |=  (1<<EN_XORPCK); /* bit 1 -> 1 (XORPCK clock) */
+	mask32 &= ~(1<<EN_PERCK);  /* bit 2 -> 0 (MPUPER_CK clock) */
+	mask32 &= ~(1<<EN_LCDCK);  /* bit 3 -> 0 (LCDC clock) */
+	mask32 &= ~(1<<EN_LBCK);   /* bit 4 -> 0 (local bus clock) */
+	mask32 |=  (1<<EN_APICK);  /* bit 6 -> 1 (MPUI clock) */
+	mask32 &= ~(1<<EN_TIMCK);  /* bit 7 -> 0 (MPU timer clock) */
+	mask32 &= ~(1<<DMACK_REQ); /* bit 8 -> 0 (DMAC clock) */
+	mask32 &= ~(1<<EN_GPIOCK); /* bit 9 -> 0 (GPIO clock) */
+	omap_writel(mask32, ARM_IDLECT2);
+
+	/* disable ARM watchdog */
+	omap_writel(0x00F5, OMAP_WDT_TIMER_MODE);
+	omap_writel(0x00A0, OMAP_WDT_TIMER_MODE);
+
+	/*
+	 * Step 6b: ARM and Traffic controller shutdown
+	 *
+	 * Step 6 continues here. Prepare jump to power management
+	 * assembly code in internal SRAM.
+	 *
+	 * Since the omap_cpu_suspend routine has been copied to
+	 * SRAM, we'll do an indirect procedure call to it and pass the
+	 * contents of arm_idlect1 and arm_idlect2 so it can restore
+	 * them when it wakes up and it will return.
+	 */
+
+	arg0 = arm_sleep_save[ARM_SLEEP_SAVE_ARM_IDLECT1];
+	arg1 = arm_sleep_save[ARM_SLEEP_SAVE_ARM_IDLECT2];
+
+	if (cpu_is_omap1510()) {
+		func_ptr = (void *)(OMAP1510_SRAM_API_SUSPEND);
+	} else if (cpu_is_omap1610() || cpu_is_omap1710()) {
+		func_ptr = (void *)(OMAP1610_SRAM_API_SUSPEND);
+	} else if (cpu_is_omap5912()) {
+		func_ptr = (void *)(OMAP5912_SRAM_API_SUSPEND);
+	}
+
+	/*
+	 * Step 6c: ARM and Traffic controller shutdown
+	 *
+	 * Jump to assembly code. The processor will stay there
+ 	 * until wake up.
+	 */
+
+        func_ptr(arg0, arg1);
+
+	/*
+	 * If we are here, processor is woken up!
+	 */
+
+	if (cpu_is_omap1510()) {
+		/* POWER_CTRL_REG = 0x0 (LOW_POWER is disabled) */
+		omap_writew(omap_readw(ULPD_POWER_CTRL) &
+			    ~OMAP1510_ULPD_LOW_POWER_REQ, ULPD_POWER_CTRL);
+	} else if (cpu_is_omap16xx()) {
+		/* POWER_CTRL_REG = 0x0 (LOW_POWER is disabled) */
+		omap_writew(omap_readw(ULPD_POWER_CTRL) &
+			    ~OMAP1610_ULPD_LOW_POWER_REQ, ULPD_POWER_CTRL);
+	}
+
+
+	/* Restore DSP clocks */
+	omap_writel(omap_readl(ARM_IDLECT2) | (1<<EN_APICK), ARM_IDLECT2);
+	__raw_writew(save_dsp_idlect2, DSP_IDLECT2);
+	ARM_RESTORE(ARM_IDLECT2);
+
+	/*
+	 * Restore ARM state, except ARM_IDLECT1/2 which omap_cpu_suspend did
+	 */
+
+	ARM_RESTORE(ARM_CKCTL);
+	ARM_RESTORE(ARM_EWUPCT);
+	ARM_RESTORE(ARM_RSTCT1);
+	ARM_RESTORE(ARM_RSTCT2);
+	ARM_RESTORE(ARM_SYSST);
+	ULPD_RESTORE(ULPD_CLOCK_CTRL);
+	ULPD_RESTORE(ULPD_STATUS_REQ);
+
+	if (cpu_is_omap1510()) {
+		MPUI1510_RESTORE(MPUI_CTRL);
+		MPUI1510_RESTORE(MPUI_DSP_BOOT_CONFIG);
+		MPUI1510_RESTORE(MPUI_DSP_API_CONFIG);
+		MPUI1510_RESTORE(EMIFS_CONFIG);
+		MPUI1510_RESTORE(EMIFF_SDRAM_CONFIG);
+		MPUI1510_RESTORE(OMAP_IH1_MIR);
+		MPUI1510_RESTORE(OMAP_IH2_MIR);
+	} else if (cpu_is_omap16xx()) {
+		MPUI1610_RESTORE(MPUI_CTRL);
+		MPUI1610_RESTORE(MPUI_DSP_BOOT_CONFIG);
+		MPUI1610_RESTORE(MPUI_DSP_API_CONFIG);
+		MPUI1610_RESTORE(EMIFS_CONFIG);
+		MPUI1610_RESTORE(EMIFF_SDRAM_CONFIG);
+
+		MPUI1610_RESTORE(OMAP_IH1_MIR);
+		MPUI1610_RESTORE(OMAP_IH2_0_MIR);
+		MPUI1610_RESTORE(OMAP_IH2_1_MIR);
+		MPUI1610_RESTORE(OMAP_IH2_2_MIR);
+		MPUI1610_RESTORE(OMAP_IH2_3_MIR);
+	}
+
+	/*
+	 * Reenable interrupts
+	 */
+
+	local_irq_enable();
+	local_fiq_enable();
+
+	printk("PM: OMAP%x is re-starting from deep sleep...\n", system_rev);
+
+	if (machine_is_omap_osk()) {
+		/* Let LED1 (D9) blink again */
+		tps65010_set_led(LED1, BLINK);
+	}
+}
+
+#if defined(DEBUG) && defined(CONFIG_PROC_FS)
+static int g_read_completed;
+
+/*
+ * Read system PM registers for debugging
+ */
+static int omap_pm_read_proc(
+	char *page_buffer,
+	char **my_first_byte,
+	off_t virtual_start,
+	int length,
+	int *eof,
+	void *data)
+{
+	int my_buffer_offset = 0;
+	char * const my_base = page_buffer;
+
+	ARM_SAVE(ARM_CKCTL);
+	ARM_SAVE(ARM_IDLECT1);
+	ARM_SAVE(ARM_IDLECT2);
+	ARM_SAVE(ARM_EWUPCT);
+	ARM_SAVE(ARM_RSTCT1);
+	ARM_SAVE(ARM_RSTCT2);
+	ARM_SAVE(ARM_SYSST);
+
+	ULPD_SAVE(ULPD_IT_STATUS);
+	ULPD_SAVE(ULPD_CLOCK_CTRL);
+	ULPD_SAVE(ULPD_SOFT_REQ);
+	ULPD_SAVE(ULPD_STATUS_REQ);
+	ULPD_SAVE(ULPD_DPLL_CTRL);
+	ULPD_SAVE(ULPD_POWER_CTRL);
+
+	if (cpu_is_omap1510()) {
+		MPUI1510_SAVE(MPUI_CTRL);
+		MPUI1510_SAVE(MPUI_DSP_STATUS);
+		MPUI1510_SAVE(MPUI_DSP_BOOT_CONFIG);
+		MPUI1510_SAVE(MPUI_DSP_API_CONFIG);
+		MPUI1510_SAVE(EMIFF_SDRAM_CONFIG);
+		MPUI1510_SAVE(EMIFS_CONFIG);
+	} else if (cpu_is_omap16xx()) {
+		MPUI1610_SAVE(MPUI_CTRL);
+		MPUI1610_SAVE(MPUI_DSP_STATUS);
+		MPUI1610_SAVE(MPUI_DSP_BOOT_CONFIG);
+		MPUI1610_SAVE(MPUI_DSP_API_CONFIG);
+		MPUI1610_SAVE(EMIFF_SDRAM_CONFIG);
+		MPUI1610_SAVE(EMIFS_CONFIG);
+	}
+
+	if (virtual_start == 0) {
+		g_read_completed = 0;
+
+		my_buffer_offset += sprintf(my_base + my_buffer_offset,
+		   "ARM_CKCTL_REG:            0x%-8x     \n"
+		   "ARM_IDLECT1_REG:          0x%-8x     \n"
+		   "ARM_IDLECT2_REG:          0x%-8x     \n"
+		   "ARM_EWUPCT_REG:           0x%-8x     \n"
+		   "ARM_RSTCT1_REG:           0x%-8x     \n"
+		   "ARM_RSTCT2_REG:           0x%-8x     \n"
+		   "ARM_SYSST_REG:            0x%-8x     \n"
+		   "ULPD_IT_STATUS_REG:       0x%-4x     \n"
+		   "ULPD_CLOCK_CTRL_REG:      0x%-4x     \n"
+		   "ULPD_SOFT_REQ_REG:        0x%-4x     \n"
+		   "ULPD_DPLL_CTRL_REG:       0x%-4x     \n"
+		   "ULPD_STATUS_REQ_REG:      0x%-4x     \n"
+		   "ULPD_POWER_CTRL_REG:      0x%-4x     \n",
+		   ARM_SHOW(ARM_CKCTL),
+		   ARM_SHOW(ARM_IDLECT1),
+		   ARM_SHOW(ARM_IDLECT2),
+		   ARM_SHOW(ARM_EWUPCT),
+		   ARM_SHOW(ARM_RSTCT1),
+		   ARM_SHOW(ARM_RSTCT2),
+		   ARM_SHOW(ARM_SYSST),
+		   ULPD_SHOW(ULPD_IT_STATUS),
+		   ULPD_SHOW(ULPD_CLOCK_CTRL),
+		   ULPD_SHOW(ULPD_SOFT_REQ),
+		   ULPD_SHOW(ULPD_DPLL_CTRL),
+		   ULPD_SHOW(ULPD_STATUS_REQ),
+		   ULPD_SHOW(ULPD_POWER_CTRL));
+
+		if (cpu_is_omap1510()) {
+			my_buffer_offset += sprintf(my_base + my_buffer_offset,
+			   "MPUI1510_CTRL_REG             0x%-8x \n"
+			   "MPUI1510_DSP_STATUS_REG:      0x%-8x \n"
+			   "MPUI1510_DSP_BOOT_CONFIG_REG: 0x%-8x \n"
+		   	   "MPUI1510_DSP_API_CONFIG_REG:  0x%-8x \n"
+		   	   "MPUI1510_SDRAM_CONFIG_REG:    0x%-8x \n"
+		   	   "MPUI1510_EMIFS_CONFIG_REG:    0x%-8x \n",
+		   	   MPUI1510_SHOW(MPUI_CTRL),
+		   	   MPUI1510_SHOW(MPUI_DSP_STATUS),
+		   	   MPUI1510_SHOW(MPUI_DSP_BOOT_CONFIG),
+		   	   MPUI1510_SHOW(MPUI_DSP_API_CONFIG),
+		   	   MPUI1510_SHOW(EMIFF_SDRAM_CONFIG),
+		   	   MPUI1510_SHOW(EMIFS_CONFIG));
+		} else if (cpu_is_omap16xx()) {
+			my_buffer_offset += sprintf(my_base + my_buffer_offset,
+			   "MPUI1610_CTRL_REG             0x%-8x \n"
+			   "MPUI1610_DSP_STATUS_REG:      0x%-8x \n"
+			   "MPUI1610_DSP_BOOT_CONFIG_REG: 0x%-8x \n"
+		   	   "MPUI1610_DSP_API_CONFIG_REG:  0x%-8x \n"
+		   	   "MPUI1610_SDRAM_CONFIG_REG:    0x%-8x \n"
+		   	   "MPUI1610_EMIFS_CONFIG_REG:    0x%-8x \n",
+		   	   MPUI1610_SHOW(MPUI_CTRL),
+		   	   MPUI1610_SHOW(MPUI_DSP_STATUS),
+		   	   MPUI1610_SHOW(MPUI_DSP_BOOT_CONFIG),
+		   	   MPUI1610_SHOW(MPUI_DSP_API_CONFIG),
+		   	   MPUI1610_SHOW(EMIFF_SDRAM_CONFIG),
+		   	   MPUI1610_SHOW(EMIFS_CONFIG));
+		}
+
+		g_read_completed++;
+	} else if (g_read_completed >= 1) {
+		 *eof = 1;
+		 return 0;
+	}
+	g_read_completed++;
+
+	*my_first_byte = page_buffer;
+	return  my_buffer_offset;
+}
+
+static void omap_pm_init_proc(void)
+{
+	struct proc_dir_entry *entry;
+
+	entry = create_proc_read_entry("driver/omap_pm",
+				       S_IWUSR | S_IRUGO, NULL,
+				       omap_pm_read_proc, 0);
+}
+
+#endif /* DEBUG && CONFIG_PROC_FS */
+
+/*
+ *	omap_pm_prepare - Do preliminary suspend work.
+ *	@state:		suspend state we're entering.
+ *
+ */
+//#include <asm/arch/hardware.h>
+
+static int omap_pm_prepare(suspend_state_t state)
+{
+	int error = 0;
+
+	switch (state)
+	{
+	case PM_SUSPEND_STANDBY:
+	case PM_SUSPEND_MEM:
+		break;
+
+	case PM_SUSPEND_DISK:
+		return -ENOTSUPP;
+
+	default:
+		return -EINVAL;
+	}
+
+	return error;
+}
+
+
+/*
+ *	omap_pm_enter - Actually enter a sleep state.
+ *	@state:		State we're entering.
+ *
+ */
+
+static int omap_pm_enter(suspend_state_t state)
+{
+	switch (state)
+	{
+	case PM_SUSPEND_STANDBY:
+	case PM_SUSPEND_MEM:
+		omap_pm_suspend();
+		break;
+
+	case PM_SUSPEND_DISK:
+		return -ENOTSUPP;
+
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+
+/**
+ *	omap_pm_finish - Finish up suspend sequence.
+ *	@state:		State we're coming out of.
+ *
+ *	This is called after we wake back up (or if entering the sleep state
+ *	failed).
+ */
+
+static int omap_pm_finish(suspend_state_t state)
+{
+	return 0;
+}
+
+
+struct pm_ops omap_pm_ops ={
+	.pm_disk_mode = 0,
+        .prepare        = omap_pm_prepare,
+        .enter          = omap_pm_enter,
+        .finish         = omap_pm_finish,
+};
+
+static int __init omap_pm_init(void)
+{
+	printk("Power Management for TI OMAP.\n");
+	pm_idle = omap_pm_idle;
+	/*
+	 * We copy the assembler sleep/wakeup routines to SRAM.
+	 * These routines need to be in SRAM as that's the only
+	 * memory the MPU can see when it wakes up.
+	 */
+
+#ifdef	CONFIG_ARCH_OMAP1510
+	if (cpu_is_omap1510()) {
+		memcpy((void *)OMAP1510_SRAM_IDLE_SUSPEND,
+		       omap1510_idle_loop_suspend,
+		       omap1510_idle_loop_suspend_sz);
+		memcpy((void *)OMAP1510_SRAM_API_SUSPEND, omap1510_cpu_suspend,
+		       omap1510_cpu_suspend_sz);
+	} else
+#endif
+	if (cpu_is_omap1610() || cpu_is_omap1710()) {
+		memcpy((void *)OMAP1610_SRAM_IDLE_SUSPEND,
+		       omap1610_idle_loop_suspend,
+		       omap1610_idle_loop_suspend_sz);
+		memcpy((void *)OMAP1610_SRAM_API_SUSPEND, omap1610_cpu_suspend,
+		       omap1610_cpu_suspend_sz);
+	} else if (cpu_is_omap5912()) {
+		memcpy((void *)OMAP5912_SRAM_IDLE_SUSPEND,
+		       omap1610_idle_loop_suspend,
+		       omap1610_idle_loop_suspend_sz);
+		memcpy((void *)OMAP5912_SRAM_API_SUSPEND, omap1610_cpu_suspend,
+		       omap1610_cpu_suspend_sz);
+	}
+
+	pm_set_ops(&omap_pm_ops);
+
+#if defined(DEBUG) && defined(CONFIG_PROC_FS)
+	omap_pm_init_proc();
+#endif
+
+	return 0;
+}
+__initcall(omap_pm_init);
+
diff --git a/arch/arm/plat-omap/sleep.S b/arch/arm/plat-omap/sleep.S
new file mode 100644
--- /dev/null
+++ b/arch/arm/plat-omap/sleep.S
@@ -0,0 +1,314 @@
+/*
+ * linux/arch/arm/plat-omap/sleep.S
+ *
+ * Low-level OMAP1510/1610 sleep/wakeUp support
+ *
+ * Initial SA1110 code:
+ * Copyright (c) 2001 Cliff Brake <cbrake@accelent.com>
+ *
+ * Adapted for PXA by Nicolas Pitre:
+ * Copyright (c) 2002 Monta Vista Software, Inc.
+ *
+ * Support for OMAP1510/1610 by Dirk Behme <dirk.behme@de.bosch.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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/config.h>
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/arch/io.h>
+#include <asm/arch/pm.h>
+
+		.text
+
+/*
+ * Forces OMAP into idle state
+ *
+ * omapXXXX_idle_loop_suspend()
+ *
+ * Note: This code get's copied to internal SRAM at boot. When the OMAP
+ *	 wakes up it continues execution at the point it went to sleep.
+ *
+ * Note: Because of slightly different configuration values we have
+ *       processor specific functions here.
+ */
+
+#ifdef CONFIG_ARCH_OMAP1510
+ENTRY(omap1510_idle_loop_suspend)
+
+	stmfd	sp!, {r0 - r12, lr}		@ save registers on stack
+
+	@ load base address of ARM_IDLECT1 and ARM_IDLECT2
+	mov	r4, #CLKGEN_REG_ASM_BASE & 0xff000000
+	orr	r4, r4, #CLKGEN_REG_ASM_BASE & 0x00ff0000
+	orr	r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00
+
+	@ turn off clock domains
+	@ get ARM_IDLECT2 into r2
+	ldrh	r2, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
+	mov	r5, #OMAP1510_IDLE_CLOCK_DOMAINS & 0xff
+ 	orr	r5,r5, #OMAP1510_IDLE_CLOCK_DOMAINS & 0xff00
+	strh	r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
+
+	@ request ARM idle
+	@ get ARM_IDLECT1 into r1
+	ldrh	r1, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
+	orr	r3, r1, #OMAP1510_IDLE_LOOP_REQUEST & 0xffff
+	strh	r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
+
+	mov	r5, #IDLE_WAIT_CYCLES & 0xff
+	orr     r5, r5, #IDLE_WAIT_CYCLES & 0xff00
+l_1510:	subs	r5, r5, #1
+	bne	l_1510
+/*
+ * Let's wait for the next clock tick to wake us up.
+ */
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c0, 4		@ wait for interrupt
+/*
+ * omap1510_idle_loop_suspend()'s resume point.
+ *
+ * It will just start executing here, so we'll restore stuff from the
+ * stack, reset the ARM_IDLECT1 and ARM_IDLECT2.
+ */
+
+	@ restore ARM_IDLECT1 and ARM_IDLECT2 and return
+	@ r1 has ARM_IDLECT1 and r2 still has ARM_IDLECT2
+	strh	r2, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
+	strh	r1, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
+
+	ldmfd   sp!, {r0 - r12, pc}     @ restore regs and return
+
+ENTRY(omap1510_idle_loop_suspend_sz)
+	.word	. - omap1510_idle_loop_suspend
+#endif /* CONFIG_ARCH_OMAP1510 */
+
+#if defined(CONFIG_ARCH_OMAP16XX)
+ENTRY(omap1610_idle_loop_suspend)
+
+	stmfd	sp!, {r0 - r12, lr}		@ save registers on stack
+
+	@ load base address of ARM_IDLECT1 and ARM_IDLECT2
+	mov	r4, #CLKGEN_REG_ASM_BASE & 0xff000000
+	orr	r4, r4, #CLKGEN_REG_ASM_BASE & 0x00ff0000
+	orr	r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00
+
+	@ turn off clock domains
+	@ get ARM_IDLECT2 into r2
+	ldrh	r2, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
+	mov	r5, #OMAP1610_IDLE_CLOCK_DOMAINS & 0xff
+ 	orr	r5,r5, #OMAP1610_IDLE_CLOCK_DOMAINS & 0xff00
+	strh	r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
+
+	@ request ARM idle
+	@ get ARM_IDLECT1 into r1
+	ldrh	r1, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
+	orr	r3, r1, #OMAP1610_IDLE_LOOP_REQUEST & 0xffff
+	strh	r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
+
+	mov	r5, #IDLE_WAIT_CYCLES & 0xff
+	orr     r5, r5, #IDLE_WAIT_CYCLES & 0xff00
+l_1610:	subs	r5, r5, #1
+	bne	l_1610
+/*
+ * Let's wait for the next clock tick to wake us up.
+ */
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c0, 4		@ wait for interrupt
+/*
+ * omap1610_idle_loop_suspend()'s resume point.
+ *
+ * It will just start executing here, so we'll restore stuff from the
+ * stack, reset the ARM_IDLECT1 and ARM_IDLECT2.
+ */
+
+	@ restore ARM_IDLECT1 and ARM_IDLECT2 and return
+	@ r1 has ARM_IDLECT1 and r2 still has ARM_IDLECT2
+	strh	r2, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
+	strh	r1, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
+
+	ldmfd   sp!, {r0 - r12, pc}     @ restore regs and return
+
+ENTRY(omap1610_idle_loop_suspend_sz)
+	.word	. - omap1610_idle_loop_suspend
+#endif /* CONFIG_ARCH_OMAP16XX */
+
+/*
+ * Forces OMAP into deep sleep state
+ *
+ * omapXXXX_cpu_suspend()
+ *
+ * The values of the registers ARM_IDLECT1 and ARM_IDLECT2 are passed
+ * as arg0 and arg1 from caller. arg0 is stored in register r0 and arg1
+ * in register r1.
+ *
+ * Note: This code get's copied to internal SRAM at boot. When the OMAP
+ *	 wakes up it continues execution at the point it went to sleep.
+ *
+ * Note: Because of errata work arounds we have processor specific functions
+ *       here. They are mostly the same, but slightly different.
+ *
+ */
+
+#ifdef CONFIG_ARCH_OMAP1510
+ENTRY(omap1510_cpu_suspend)
+
+	@ save registers on stack
+	stmfd	sp!, {r0 - r12, lr}
+
+	@ load base address of Traffic Controller
+	mov	r4, #TCMIF_ASM_BASE & 0xff000000
+	orr	r4, r4, #TCMIF_ASM_BASE & 0x00ff0000
+	orr	r4, r4, #TCMIF_ASM_BASE & 0x0000ff00
+
+	@ work around errata of OMAP1510 PDE bit for TC shut down
+	@ clear PDE bit
+	ldr	r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
+	bic	r5, r5, #PDE_BIT & 0xff
+	str	r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
+
+	@ set PWD_EN bit
+	and	r5, r5, #PWD_EN_BIT & 0xff
+	str	r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
+
+	@ prepare to put SDRAM into self-refresh manually
+	ldr	r5, [r4, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
+	orr	r5, r5, #SELF_REFRESH_MODE & 0xff000000
+	orr	r5, r5, #SELF_REFRESH_MODE & 0x000000ff
+	str	r5, [r4, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
+
+	@ prepare to put EMIFS to Sleep
+	ldr	r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
+	orr	r5, r5, #IDLE_EMIFS_REQUEST & 0xff
+	str	r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
+
+	@ load base address of ARM_IDLECT1 and ARM_IDLECT2
+	mov	r4, #CLKGEN_REG_ASM_BASE & 0xff000000
+	orr	r4, r4, #CLKGEN_REG_ASM_BASE & 0x00ff0000
+	orr	r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00
+
+	@ turn off clock domains
+	mov	r5, #OMAP1510_IDLE_CLOCK_DOMAINS & 0xff
+ 	orr	r5,r5, #OMAP1510_IDLE_CLOCK_DOMAINS & 0xff00
+	strh	r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
+
+	@ request ARM idle
+	mov	r3, #OMAP1510_DEEP_SLEEP_REQUEST & 0xff
+	orr	r3, r3, #OMAP1510_DEEP_SLEEP_REQUEST & 0xff00
+	strh	r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
+
+	mov	r5, #IDLE_WAIT_CYCLES & 0xff
+	orr     r5, r5, #IDLE_WAIT_CYCLES & 0xff00
+l_1510_2:
+	subs	r5, r5, #1
+	bne	l_1510_2
+/*
+ * Let's wait for the next wake up event to wake us up. r0 can't be
+ * used here because r0 holds ARM_IDLECT1
+ */
+	mov	r2, #0
+	mcr	p15, 0, r2, c7, c0, 4		@ wait for interrupt
+/*
+ * omap1510_cpu_suspend()'s resume point.
+ *
+ * It will just start executing here, so we'll restore stuff from the
+ * stack, reset the ARM_IDLECT1 and ARM_IDLECT2.
+ */
+	strh	r1, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
+	strh	r0, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
+
+	@ restore regs and return
+	ldmfd   sp!, {r0 - r12, pc}
+
+ENTRY(omap1510_cpu_suspend_sz)
+	.word	. - omap1510_cpu_suspend
+#endif /* CONFIG_ARCH_OMAP1510 */
+
+#if defined(CONFIG_ARCH_OMAP16XX)
+ENTRY(omap1610_cpu_suspend)
+
+	@ save registers on stack
+	stmfd	sp!, {r0 - r12, lr}
+
+	@ load base address of Traffic Controller
+	mov	r4, #TCMIF_ASM_BASE & 0xff000000
+	orr	r4, r4, #TCMIF_ASM_BASE & 0x00ff0000
+	orr	r4, r4, #TCMIF_ASM_BASE & 0x0000ff00
+
+	@ prepare to put SDRAM into self-refresh manually
+	ldr	r5, [r4, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
+	orr	r5, r5, #SELF_REFRESH_MODE & 0xff000000
+	orr	r5, r5, #SELF_REFRESH_MODE & 0x000000ff
+	str	r5, [r4, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
+
+	@ prepare to put EMIFS to Sleep
+	ldr	r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
+	orr	r5, r5, #IDLE_EMIFS_REQUEST & 0xff
+	str	r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
+
+	@ load base address of ARM_IDLECT1 and ARM_IDLECT2
+	mov	r4, #CLKGEN_REG_ASM_BASE & 0xff000000
+	orr	r4, r4, #CLKGEN_REG_ASM_BASE & 0x00ff0000
+	orr	r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00
+
+	@ turn off clock domains
+	mov	r5, #OMAP1610_IDLE_CLOCK_DOMAINS & 0xff
+ 	orr	r5,r5, #OMAP1610_IDLE_CLOCK_DOMAINS & 0xff00
+	strh	r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
+
+	@ work around errata of OMAP1610/5912. Enable (!) peripheral
+	@ clock to let the chip go into deep sleep
+	ldrh	r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
+ 	orr	r5,r5, #EN_PERCK_BIT & 0xff
+	strh	r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
+
+	@ request ARM idle
+	mov	r3, #OMAP1610_DEEP_SLEEP_REQUEST & 0xff
+	orr	r3, r3, #OMAP1610_DEEP_SLEEP_REQUEST & 0xff00
+	strh	r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
+
+	mov	r5, #IDLE_WAIT_CYCLES & 0xff
+	orr     r5, r5, #IDLE_WAIT_CYCLES & 0xff00
+l_1610_2:
+	subs	r5, r5, #1
+	bne	l_1610_2
+/*
+ * Let's wait for the next wake up event to wake us up. r0 can't be
+ * used here because r0 holds ARM_IDLECT1
+ */
+	mov	r2, #0
+	mcr	p15, 0, r2, c7, c0, 4		@ wait for interrupt
+/*
+ * omap1610_cpu_suspend()'s resume point.
+ *
+ * It will just start executing here, so we'll restore stuff from the
+ * stack, reset the ARM_IDLECT1 and ARM_IDLECT2.
+ */
+	strh	r1, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
+	strh	r0, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
+
+	@ restore regs and return
+	ldmfd   sp!, {r0 - r12, pc}
+
+ENTRY(omap1610_cpu_suspend_sz)
+	.word	. - omap1610_cpu_suspend
+#endif /* CONFIG_ARCH_OMAP16XX */
diff --git a/arch/arm/plat-omap/usb.c b/arch/arm/plat-omap/usb.c
new file mode 100644
--- /dev/null
+++ b/arch/arm/plat-omap/usb.c
@@ -0,0 +1,593 @@
+/*
+ * arch/arm/plat-omap/usb.c -- platform level USB initialization
+ *
+ * Copyright (C) 2004 Texas Instruments, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#undef	DEBUG
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/usb_otg.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+
+#include <asm/arch/mux.h>
+#include <asm/arch/usb.h>
+#include <asm/arch/board.h>
+
+/* These routines should handle the standard chip-specific modes
+ * for usb0/1/2 ports, covering basic mux and transceiver setup.
+ *
+ * Some board-*.c files will need to set up additional mux options,
+ * like for suspend handling, vbus sensing, GPIOs, and the D+ pullup.
+ */
+
+/* TESTED ON:
+ *  - 1611B H2 (with usb1 mini-AB) using standard Mini-B or OTG cables
+ *  - 5912 OSK OHCI (with usb0 standard-A), standard A-to-B cables
+ *  - 5912 OSK UDC, with *nonstandard* A-to-A cable
+ *  - 1510 Innovator UDC with bundled usb0 cable
+ *  - 1510 Innovator OHCI with bundled usb1/usb2 cable
+ *  - 1510 Innovator OHCI with custom usb0 cable, feeding 5V VBUS
+ *  - 1710 custom development board using alternate pin group
+ *  - 1710 H3 (with usb1 mini-AB) using standard Mini-B or OTG cables
+ */
+
+/*-------------------------------------------------------------------------*/
+
+#ifdef	CONFIG_ARCH_OMAP_OTG
+
+static struct otg_transceiver *xceiv;
+
+/**
+ * otg_get_transceiver - find the (single) OTG transceiver driver
+ *
+ * Returns the transceiver driver, after getting a refcount to it; or
+ * null if there is no such transceiver.  The caller is responsible for
+ * releasing that count.
+ */
+struct otg_transceiver *otg_get_transceiver(void)
+{
+	if (xceiv)
+		get_device(xceiv->dev);
+	return xceiv;
+}
+EXPORT_SYMBOL(otg_get_transceiver);
+
+int otg_set_transceiver(struct otg_transceiver *x)
+{
+	if (xceiv && x)
+		return -EBUSY;
+	xceiv = x;
+	return 0;
+}
+EXPORT_SYMBOL(otg_set_transceiver);
+
+#endif
+
+/*-------------------------------------------------------------------------*/
+
+static u32 __init omap_usb0_init(unsigned nwires, unsigned is_device)
+{
+	u32	syscon1 = 0;
+
+	if (nwires == 0) {
+		if (!cpu_is_omap15xx()) {
+			/* pulldown D+/D- */
+			USB_TRANSCEIVER_CTRL_REG &= ~(3 << 1);
+		}
+		return 0;
+	}
+
+	if (is_device)
+		omap_cfg_reg(W4_USB_PUEN);
+
+	/* internal transceiver */
+	if (nwires == 2) {
+		// omap_cfg_reg(P9_USB_DP);
+		// omap_cfg_reg(R8_USB_DM);
+
+		if (cpu_is_omap15xx()) {
+			/* This works on 1510-Innovator */
+			return 0;
+		}
+
+		/* NOTES:
+		 *  - peripheral should configure VBUS detection!
+		 *  - only peripherals may use the internal D+/D- pulldowns
+		 *  - OTG support on this port not yet written
+		 */
+
+		USB_TRANSCEIVER_CTRL_REG &= ~(7 << 4);
+		if (!is_device)
+			USB_TRANSCEIVER_CTRL_REG |= (3 << 1);
+
+		return 3 << 16;
+	}
+
+	/* alternate pin config, external transceiver */
+	if (cpu_is_omap15xx()) {
+		printk(KERN_ERR "no usb0 alt pin config on 15xx\n");
+		return 0;
+	}
+
+	omap_cfg_reg(V6_USB0_TXD);
+	omap_cfg_reg(W9_USB0_TXEN);
+	omap_cfg_reg(W5_USB0_SE0);
+
+	/* NOTE:  SPEED and SUSP aren't configured here */
+
+	if (nwires != 3)
+		omap_cfg_reg(Y5_USB0_RCV);
+	if (nwires != 6)
+		USB_TRANSCEIVER_CTRL_REG &= ~CONF_USB2_UNI_R;
+
+	switch (nwires) {
+	case 3:
+		syscon1 = 2;
+		break;
+	case 4:
+		syscon1 = 1;
+		break;
+	case 6:
+		syscon1 = 3;
+		omap_cfg_reg(AA9_USB0_VP);
+		omap_cfg_reg(R9_USB0_VM);
+		USB_TRANSCEIVER_CTRL_REG |= CONF_USB2_UNI_R;
+		break;
+	default:
+		printk(KERN_ERR "illegal usb%d %d-wire transceiver\n",
+			0, nwires);
+	}
+	return syscon1 << 16;
+}
+
+static u32 __init omap_usb1_init(unsigned nwires)
+{
+	u32	syscon1 = 0;
+
+	if (nwires != 6 && !cpu_is_omap15xx())
+		USB_TRANSCEIVER_CTRL_REG &= ~CONF_USB1_UNI_R;
+	if (nwires == 0)
+		return 0;
+
+	/* external transceiver */
+	omap_cfg_reg(USB1_TXD);
+	omap_cfg_reg(USB1_TXEN);
+	if (cpu_is_omap15xx()) {
+		omap_cfg_reg(USB1_SEO);
+		omap_cfg_reg(USB1_SPEED);
+		// SUSP
+	} else if (cpu_is_omap1610() || cpu_is_omap5912()) {
+		omap_cfg_reg(W13_1610_USB1_SE0);
+		omap_cfg_reg(R13_1610_USB1_SPEED);
+		// SUSP
+	} else if (cpu_is_omap1710()) {
+		omap_cfg_reg(R13_1710_USB1_SE0);
+		// SUSP
+	} else {
+		pr_debug("usb unrecognized\n");
+	}
+	if (nwires != 3)
+		omap_cfg_reg(USB1_RCV);
+
+	switch (nwires) {
+	case 3:
+		syscon1 = 2;
+		break;
+	case 4:
+		syscon1 = 1;
+		break;
+	case 6:
+		syscon1 = 3;
+		omap_cfg_reg(USB1_VP);
+		omap_cfg_reg(USB1_VM);
+		if (!cpu_is_omap15xx())
+			USB_TRANSCEIVER_CTRL_REG |= CONF_USB1_UNI_R;
+		break;
+	default:
+		printk(KERN_ERR "illegal usb%d %d-wire transceiver\n",
+			1, nwires);
+	}
+	return syscon1 << 20;
+}
+
+static u32 __init omap_usb2_init(unsigned nwires, unsigned alt_pingroup)
+{
+	u32	syscon1 = 0;
+
+	/* NOTE erratum: must leave USB2_UNI_R set if usb0 in use */
+	if (alt_pingroup || nwires == 0)
+		return 0;
+	if (nwires != 6 && !cpu_is_omap15xx())
+		USB_TRANSCEIVER_CTRL_REG &= ~CONF_USB2_UNI_R;
+
+	/* external transceiver */
+	if (cpu_is_omap15xx()) {
+		omap_cfg_reg(USB2_TXD);
+		omap_cfg_reg(USB2_TXEN);
+		omap_cfg_reg(USB2_SEO);
+		if (nwires != 3)
+			omap_cfg_reg(USB2_RCV);
+		/* there is no USB2_SPEED */
+	} else if (cpu_is_omap16xx()) {
+		omap_cfg_reg(V6_USB2_TXD);
+		omap_cfg_reg(W9_USB2_TXEN);
+		omap_cfg_reg(W5_USB2_SE0);
+		if (nwires != 3)
+			omap_cfg_reg(Y5_USB2_RCV);
+		// FIXME omap_cfg_reg(USB2_SPEED);
+	} else {
+		pr_debug("usb unrecognized\n");
+	}
+	// omap_cfg_reg(USB2_SUSP);
+
+	switch (nwires) {
+	case 3:
+		syscon1 = 2;
+		break;
+	case 4:
+		syscon1 = 1;
+		break;
+	case 6:
+		syscon1 = 3;
+		if (cpu_is_omap15xx()) {
+			omap_cfg_reg(USB2_VP);
+			omap_cfg_reg(USB2_VM);
+		} else {
+			omap_cfg_reg(AA9_USB2_VP);
+			omap_cfg_reg(R9_USB2_VM);
+			USB_TRANSCEIVER_CTRL_REG |= CONF_USB2_UNI_R;
+		}
+		break;
+	default:
+		printk(KERN_ERR "illegal usb%d %d-wire transceiver\n",
+			2, nwires);
+	}
+	return syscon1 << 24;
+}
+
+/*-------------------------------------------------------------------------*/
+
+#if	defined(CONFIG_USB_GADGET_OMAP) || \
+	defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) || \
+	(defined(CONFIG_USB_OTG) && defined(CONFIG_ARCH_OMAP_OTG))
+static void usb_release(struct device *dev)
+{
+	/* normally not freed */
+}
+#endif
+
+#ifdef	CONFIG_USB_GADGET_OMAP
+
+static struct resource udc_resources[] = {
+	/* order is significant! */
+	{		/* registers */
+		.start		= UDC_BASE,
+		.end		= UDC_BASE + 0xff,
+		.flags		= IORESOURCE_MEM,
+	}, {		/* general IRQ */
+		.start		= IH2_BASE + 20,
+		.flags		= IORESOURCE_IRQ,
+	}, {		/* PIO IRQ */
+		.start		= IH2_BASE + 30,
+		.flags		= IORESOURCE_IRQ,
+	}, {		/* SOF IRQ */
+		.start		= IH2_BASE + 29,
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
+static u64 udc_dmamask = ~(u32)0;
+
+static struct platform_device udc_device = {
+	.name		= "omap_udc",
+	.id		= -1,
+	.dev = {
+		.release		= usb_release,
+		.dma_mask		= &udc_dmamask,
+		.coherent_dma_mask	= 0xffffffff,
+	},
+	.num_resources	= ARRAY_SIZE(udc_resources),
+	.resource	= udc_resources,
+};
+
+#endif
+
+#if	defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
+
+/* The dmamask must be set for OHCI to work */
+static u64 ohci_dmamask = ~(u32)0;
+
+static struct resource ohci_resources[] = {
+	{
+		.start	= OMAP_OHCI_BASE,
+		.end	= OMAP_OHCI_BASE + 4096 - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= INT_USB_HHC_1,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device ohci_device = {
+	.name			= "ohci",
+	.id			= -1,
+	.dev = {
+		.release		= usb_release,
+		.dma_mask		= &ohci_dmamask,
+		.coherent_dma_mask	= 0xffffffff,
+	},
+	.num_resources	= ARRAY_SIZE(ohci_resources),
+	.resource		= ohci_resources,
+};
+
+#endif
+
+#if	defined(CONFIG_USB_OTG) && defined(CONFIG_ARCH_OMAP_OTG)
+
+static struct resource otg_resources[] = {
+	/* order is significant! */
+	{
+		.start		= OTG_BASE,
+		.end		= OTG_BASE + 0xff,
+		.flags		= IORESOURCE_MEM,
+	}, {
+		.start		= IH2_BASE + 8,
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device otg_device = {
+	.name		= "omap_otg",
+	.id		= -1,
+	.dev = {
+		.release		= usb_release,
+	},
+	.num_resources	= ARRAY_SIZE(otg_resources),
+	.resource	= otg_resources,
+};
+
+#endif
+
+/*-------------------------------------------------------------------------*/
+
+#define ULPD_CLOCK_CTRL_REG	__REG16(ULPD_CLOCK_CTRL)
+#define ULPD_SOFT_REQ_REG	__REG16(ULPD_SOFT_REQ)
+
+
+// FIXME correct answer depends on hmc_mode,
+// as does any nonzero value for config->otg port number
+#ifdef	CONFIG_USB_GADGET_OMAP
+#define	is_usb0_device(config)	1
+#else
+#define	is_usb0_device(config)	0
+#endif
+
+/*-------------------------------------------------------------------------*/
+
+#ifdef	CONFIG_ARCH_OMAP_OTG
+
+void __init
+omap_otg_init(struct omap_usb_config *config)
+{
+	u32		syscon = OTG_SYSCON_1_REG & 0xffff;
+	int		status;
+	int		alt_pingroup = 0;
+
+	/* NOTE:  no bus or clock setup (yet?) */
+
+	syscon = OTG_SYSCON_1_REG & 0xffff;
+	if (!(syscon & OTG_RESET_DONE))
+		pr_debug("USB resets not complete?\n");
+
+	// OTG_IRQ_EN_REG = 0;
+
+	/* pin muxing and transceiver pinouts */
+	if (config->pins[0] > 2)	/* alt pingroup 2 */
+		alt_pingroup = 1;
+	syscon |= omap_usb0_init(config->pins[0], is_usb0_device(config));
+	syscon |= omap_usb1_init(config->pins[1]);
+	syscon |= omap_usb2_init(config->pins[2], alt_pingroup);
+	pr_debug("OTG_SYSCON_1_REG = %08x\n", syscon);
+	OTG_SYSCON_1_REG = syscon;
+
+	syscon = config->hmc_mode;
+	syscon |= USBX_SYNCHRO | (4 << 16) /* B_ASE0_BRST */;
+#ifdef	CONFIG_USB_OTG
+	if (config->otg)
+		syscon |= OTG_EN;
+#endif
+	pr_debug("USB_TRANSCEIVER_CTRL_REG = %03x\n", USB_TRANSCEIVER_CTRL_REG);
+	pr_debug("OTG_SYSCON_2_REG = %08x\n", syscon);
+	OTG_SYSCON_2_REG = syscon;
+
+	printk("USB: hmc %d", config->hmc_mode);
+	if (alt_pingroup)
+		printk(", usb2 alt %d wires", config->pins[2]);
+	else if (config->pins[0])
+		printk(", usb0 %d wires%s", config->pins[0],
+			is_usb0_device(config) ? " (dev)" : "");
+	if (config->pins[1])
+		printk(", usb1 %d wires", config->pins[1]);
+	if (!alt_pingroup && config->pins[2])
+		printk(", usb2 %d wires", config->pins[2]);
+	if (config->otg)
+		printk(", Mini-AB on usb%d", config->otg - 1);
+	printk("\n");
+
+	/* leave USB clocks/controllers off until needed */
+	ULPD_SOFT_REQ_REG &= ~SOFT_USB_CLK_REQ;
+	ULPD_CLOCK_CTRL_REG &= ~USB_MCLK_EN;
+	ULPD_CLOCK_CTRL_REG |= DIS_USB_PVCI_CLK;
+	syscon = OTG_SYSCON_1_REG;
+	syscon |= HST_IDLE_EN|DEV_IDLE_EN|OTG_IDLE_EN;
+
+#ifdef	CONFIG_USB_GADGET_OMAP
+	if (config->otg || config->register_dev) {
+		syscon &= ~DEV_IDLE_EN;
+		udc_device.dev.platform_data = config;
+		/* FIXME patch IRQ numbers for omap730 */
+		status = platform_device_register(&udc_device);
+		if (status)
+			pr_debug("can't register UDC device, %d\n", status);
+	}
+#endif
+
+#if	defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
+	if (config->otg || config->register_host) {
+		syscon &= ~HST_IDLE_EN;
+		ohci_device.dev.platform_data = config;
+		if (cpu_is_omap730())
+			ohci_resources[1].start = INT_730_USB_HHC_1;
+		status = platform_device_register(&ohci_device);
+		if (status)
+			pr_debug("can't register OHCI device, %d\n", status);
+	}
+#endif
+
+#ifdef	CONFIG_USB_OTG
+	if (config->otg) {
+		syscon &= ~OTG_IDLE_EN;
+		otg_device.dev.platform_data = config;
+		if (cpu_is_omap730())
+			otg_resources[1].start = INT_730_USB_OTG;
+		status = platform_device_register(&otg_device);
+		if (status)
+			pr_debug("can't register OTG device, %d\n", status);
+	}
+#endif
+	pr_debug("OTG_SYSCON_1_REG = %08x\n", syscon);
+	OTG_SYSCON_1_REG = syscon;
+
+	status = 0;
+}
+
+#else
+static inline void omap_otg_init(struct omap_usb_config *config) {}
+#endif
+
+/*-------------------------------------------------------------------------*/
+
+#ifdef	CONFIG_ARCH_OMAP1510
+
+#define ULPD_DPLL_CTRL_REG	__REG16(ULPD_DPLL_CTRL)
+#define DPLL_IOB		(1 << 13)
+#define DPLL_PLL_ENABLE		(1 << 4)
+#define DPLL_LOCK		(1 << 0)
+
+#define ULPD_APLL_CTRL_REG	__REG16(ULPD_APLL_CTRL)
+#define APLL_NDPLL_SWITCH	(1 << 0)
+
+
+static void __init omap_1510_usb_init(struct omap_usb_config *config)
+{
+	int status;
+	unsigned int val;
+
+	omap_usb0_init(config->pins[0], is_usb0_device(config));
+	omap_usb1_init(config->pins[1]);
+	omap_usb2_init(config->pins[2], 0);
+
+	val = omap_readl(MOD_CONF_CTRL_0) & ~(0x3f << 1);
+	val |= (config->hmc_mode << 1);
+	omap_writel(val, MOD_CONF_CTRL_0);
+
+	printk("USB: hmc %d", config->hmc_mode);
+	if (config->pins[0])
+		printk(", usb0 %d wires%s", config->pins[0],
+			is_usb0_device(config) ? " (dev)" : "");
+	if (config->pins[1])
+		printk(", usb1 %d wires", config->pins[1]);
+	if (config->pins[2])
+		printk(", usb2 %d wires", config->pins[2]);
+	printk("\n");
+
+	/* use DPLL for 48 MHz function clock */
+	pr_debug("APLL %04x DPLL %04x REQ %04x\n", ULPD_APLL_CTRL_REG,
+			ULPD_DPLL_CTRL_REG, ULPD_SOFT_REQ_REG);
+	ULPD_APLL_CTRL_REG &= ~APLL_NDPLL_SWITCH;
+	ULPD_DPLL_CTRL_REG |= DPLL_IOB | DPLL_PLL_ENABLE;
+	ULPD_SOFT_REQ_REG |= SOFT_UDC_REQ | SOFT_DPLL_REQ;
+	while (!(ULPD_DPLL_CTRL_REG & DPLL_LOCK))
+		cpu_relax();
+
+#ifdef	CONFIG_USB_GADGET_OMAP
+	if (config->register_dev) {
+		udc_device.dev.platform_data = config;
+		status = platform_device_register(&udc_device);
+		if (status)
+			pr_debug("can't register UDC device, %d\n", status);
+		/* udc driver gates 48MHz by D+ pullup */
+	}
+#endif
+
+#if	defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
+	if (config->register_host) {
+		ohci_device.dev.platform_data = config;
+		status = platform_device_register(&ohci_device);
+		if (status)
+			pr_debug("can't register OHCI device, %d\n", status);
+		/* hcd explicitly gates 48MHz */
+	}
+#endif
+}
+
+#else
+static inline void omap_1510_usb_init(struct omap_usb_config *config) {}
+#endif
+
+/*-------------------------------------------------------------------------*/
+
+static struct omap_usb_config platform_data;
+
+static int __init
+omap_usb_init(void)
+{
+	const struct omap_usb_config *config;
+
+	config = omap_get_config(OMAP_TAG_USB, struct omap_usb_config);
+	if (config == NULL) {
+		printk(KERN_ERR "USB: No board-specific "
+				"platform config found\n");
+		return -ENODEV;
+	}
+	platform_data = *config;
+
+	if (cpu_is_omap730() || cpu_is_omap16xx())
+		omap_otg_init(&platform_data);
+	else if (cpu_is_omap15xx())
+		omap_1510_usb_init(&platform_data);
+	else {
+		printk(KERN_ERR "USB: No init for your chip yet\n");
+		return -ENODEV;
+	}
+	return 0;
+}
+
+subsys_initcall(omap_usb_init);
diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types
--- a/arch/arm/tools/mach-types
+++ b/arch/arm/tools/mach-types
@@ -6,7 +6,7 @@
 # To add an entry into this database, please see Documentation/arm/README,
 # or contact rmk@arm.linux.org.uk
 #
-# Last update: Thu Mar 24 14:34:50 2005
+# Last update: Thu Jun 23 20:19:33 2005
 #
 # machine_is_xxx	CONFIG_xxxx		MACH_TYPE_xxx		number
 #
@@ -243,7 +243,7 @@ yoho			ARCH_YOHO		YOHO			231
 jasper			ARCH_JASPER		JASPER			232
 dsc25			ARCH_DSC25		DSC25			233
 omap_innovator		MACH_OMAP_INNOVATOR	OMAP_INNOVATOR		234
-ramses			ARCH_RAMSES		RAMSES			235
+mnci			ARCH_RAMSES		RAMSES			235
 s28x			ARCH_S28X		S28X			236
 mport3			ARCH_MPORT3		MPORT3			237
 pxa_eagle250		ARCH_PXA_EAGLE250	PXA_EAGLE250		238
@@ -323,7 +323,7 @@ nimbra29x		ARCH_NIMBRA29X		NIMBRA29X		31
 nimbra210		ARCH_NIMBRA210		NIMBRA210		312
 hhp_d95xx		ARCH_HHP_D95XX		HHP_D95XX		313
 labarm			ARCH_LABARM		LABARM			314
-m825xx			ARCH_M825XX		M825XX			315
+comcerto		ARCH_M825XX		M825XX			315
 m7100			SA1100_M7100		M7100			316
 nipc2			ARCH_NIPC2		NIPC2			317
 fu7202			ARCH_FU7202		FU7202			318
@@ -724,3 +724,66 @@ lpc22xx			MACH_LPC22XX		LPC22XX			715
 omap_comet3		MACH_COMET3		COMET3			716
 omap_comet4		MACH_COMET4		COMET4			717
 csb625			MACH_CSB625		CSB625			718
+fortunet2		MACH_FORTUNET2		FORTUNET2		719
+s5h2200			MACH_S5H2200		S5H2200			720
+optorm920		MACH_OPTORM920		OPTORM920		721
+adsbitsyxb		MACH_ADSBITSYXB		ADSBITSYXB		722
+adssphere		MACH_ADSSPHERE		ADSSPHERE		723
+adsportal		MACH_ADSPORTAL		ADSPORTAL		724
+ln2410sbc		MACH_LN2410SBC		LN2410SBC		725
+cb3rufc			MACH_CB3RUFC		CB3RUFC			726
+mp2usb			MACH_MP2USB		MP2USB			727
+ntnp425c		MACH_NTNP425C		NTNP425C		728
+colibri			MACH_COLIBRI		COLIBRI			729
+pcm7220			MACH_PCM7220		PCM7220			730
+gateway7001		MACH_GATEWAY7001	GATEWAY7001		731
+pcm027			MACH_PCM027		PCM027			732
+cmpxa			MACH_CMPXA		CMPXA			733
+anubis			MACH_ANUBIS		ANUBIS			734
+ite8152			MACH_ITE8152		ITE8152			735
+lpc3xxx			MACH_LPC3XXX		LPC3XXX			736
+puppeteer		MACH_PUPPETEER		PUPPETEER		737
+vt001			MACH_MACH_VADATECH	MACH_VADATECH		738
+e570			MACH_E570		E570			739
+x50			MACH_X50		X50			740
+recon			MACH_RECON		RECON			741
+xboardgp8		MACH_XBOARDGP8		XBOARDGP8		742
+fpic2			MACH_FPIC2		FPIC2			743
+akita			MACH_AKITA		AKITA			744
+a81			MACH_A81		A81			745
+svm_sc25x		MACH_SVM_SC25X		SVM_SC25X		746
+vt020			MACH_VADATECH020	VADATECH020		747
+tli			MACH_TLI		TLI			748
+edb9315lc		MACH_EDB9315LC		EDB9315LC		749
+passec			MACH_PASSEC		PASSEC			750
+ds_tiger		MACH_DS_TIGER		DS_TIGER		751
+e310			MACH_E310		E310			752
+e330			MACH_E330		E330			753
+rt3000			MACH_RT3000		RT3000			754
+nokia770		MACH_NOKIA770		NOKIA770		755
+pnx0106			MACH_PNX0106		PNX0106			756
+hx21xx			MACH_HX21XX		HX21XX			757
+faraday			MACH_FARADAY		FARADAY			758
+sbc9312			MACH_SBC9312		SBC9312			759
+batman			MACH_BATMAN		BATMAN			760
+jpd201			MACH_JPD201		JPD201			761
+mipsa			MACH_MIPSA		MIPSA			762
+kacom			MACH_KACOM		KACOM			763
+swarcocpu		MACH_SWARCOCPU		SWARCOCPU		764
+swarcodsl		MACH_SWARCODSL		SWARCODSL		765
+blueangel		MACH_BLUEANGEL		BLUEANGEL		766
+hairygrama		MACH_HAIRYGRAMA		HAIRYGRAMA		767
+banff			MACH_BANFF		BANFF			768
+carmeva			MACH_CARMEVA		CARMEVA			769
+sam255			MACH_SAM255		SAM255			770
+ppm10			MACH_PPM10		PPM10			771
+edb9315a		MACH_EDB9315A		EDB9315A		772
+sunset			MACH_SUNSET		SUNSET			773
+stargate2		MACH_STARGATE2		STARGATE2		774
+intelmote2		MACH_INTELMOTE2		INTELMOTE2		775
+trizeps4		MACH_TRIZEPS4		TRIZEPS4		776
+mainstone2		MACH_MAINSTONE2		MAINSTONE2		777
+ez_ixp42x		MACH_EZ_IXP42X		EZ_IXP42X		778
+tapwave_zodiac		MACH_TAPWAVE_ZODIAC	TAPWAVE_ZODIAC		779
+universalmeter		MACH_UNIVERSALMETER	UNIVERSALMETER		780
+hicoarm9		MACH_HICOARM9		HICOARM9		781
diff --git a/arch/arm/vfp/vfp.h b/arch/arm/vfp/vfp.h
--- a/arch/arm/vfp/vfp.h
+++ b/arch/arm/vfp/vfp.h
@@ -117,7 +117,13 @@ static inline u64 vfp_estimate_div128to6
 	if (nh >= m)
 		return ~0ULL;
 	mh = m >> 32;
-	z = (mh << 32 <= nh) ? 0xffffffff00000000ULL : (nh / mh) << 32;
+	if (mh << 32 <= nh) {
+		z = 0xffffffff00000000ULL;
+	} else {
+		z = nh;
+		do_div(z, mh);
+		z <<= 32;
+	}
 	mul64to128(&termh, &terml, m, z);
 	sub128(&remh, &reml, nh, nl, termh, terml);
 	ml = m << 32;
@@ -126,7 +132,12 @@ static inline u64 vfp_estimate_div128to6
 		add128(&remh, &reml, remh, reml, mh, ml);
 	}
 	remh = (remh << 32) | (reml >> 32);
-	z |= (mh << 32 <= remh) ? 0xffffffff : remh / mh;
+	if (mh << 32 <= remh) {
+		z |= 0xffffffff;
+	} else {
+		do_div(remh, mh);
+		z |= remh;
+	}
 	return z;
 }
 
diff --git a/arch/arm/vfp/vfpdouble.c b/arch/arm/vfp/vfpdouble.c
--- a/arch/arm/vfp/vfpdouble.c
+++ b/arch/arm/vfp/vfpdouble.c
@@ -32,6 +32,8 @@
  */
 #include <linux/kernel.h>
 #include <linux/bitops.h>
+
+#include <asm/div64.h>
 #include <asm/ptrace.h>
 #include <asm/vfp.h>
 
@@ -768,6 +770,9 @@ vfp_double_add(struct vfp_double *vdd, s
 		if ((s64)m_sig < 0) {
 			vdd->sign = vfp_sign_negate(vdd->sign);
 			m_sig = -m_sig;
+		} else if (m_sig == 0) {
+			vdd->sign = (fpscr & FPSCR_RMODE_MASK) ==
+				      FPSCR_ROUND_MINUSINF ? 0x8000 : 0;
 		}
 	} else {
 		m_sig += vdn->significand;
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c
--- a/arch/arm/vfp/vfpmodule.c
+++ b/arch/arm/vfp/vfpmodule.c
@@ -89,7 +89,7 @@ void vfp_raise_sigfpe(unsigned int sicod
 	current->thread.error_code = 0;
 	current->thread.trap_no = 6;
 
-	force_sig_info(SIGFPE, &info, current);
+	send_sig_info(SIGFPE, &info, current);
 }
 
 static void vfp_panic(char *reason)
diff --git a/arch/arm/vfp/vfpsingle.c b/arch/arm/vfp/vfpsingle.c
--- a/arch/arm/vfp/vfpsingle.c
+++ b/arch/arm/vfp/vfpsingle.c
@@ -32,6 +32,8 @@
  */
 #include <linux/kernel.h>
 #include <linux/bitops.h>
+
+#include <asm/div64.h>
 #include <asm/ptrace.h>
 #include <asm/vfp.h>
 
@@ -303,7 +305,11 @@ u32 vfp_estimate_sqrt_significand(u32 ex
 		if (z <= a)
 			return (s32)a >> 1;
 	}
-	return (u32)(((u64)a << 31) / z) + (z >> 1);
+	{
+		u64 v = (u64)a << 31;
+		do_div(v, z);
+		return v + (z >> 1);
+	}
 }
 
 static u32 vfp_single_fsqrt(int sd, int unused, s32 m, u32 fpscr)
@@ -1107,7 +1113,11 @@ static u32 vfp_single_fdiv(int sd, int s
 		vsn.significand >>= 1;
 		vsd.exponent++;
 	}
-	vsd.significand = ((u64)vsn.significand << 32) / vsm.significand;
+	{
+		u64 significand = (u64)vsn.significand << 32;
+		do_div(significand, vsm.significand);
+		vsd.significand = significand;
+	}
 	if ((vsd.significand & 0x3f) == 0)
 		vsd.significand |= ((u64)vsm.significand * vsd.significand != (u64)vsn.significand << 32);
 
diff --git a/arch/arm26/Kconfig b/arch/arm26/Kconfig
--- a/arch/arm26/Kconfig
+++ b/arch/arm26/Kconfig
@@ -179,8 +179,12 @@ config CMDLINE
 	  time by entering them here. As a minimum, you should specify the
 	  memory size and the root device (e.g., mem=64M root=/dev/nfs).
 
+source "mm/Kconfig"
+
 endmenu
 
+source "net/Kconfig"
+
 source "drivers/base/Kconfig"
 
 source "drivers/parport/Kconfig"
@@ -191,7 +195,7 @@ source "drivers/block/Kconfig"
 
 source "drivers/md/Kconfig"
 
-source "net/Kconfig"
+source "drivers/net/Kconfig"
 
 source "drivers/ide/Kconfig"
 
diff --git a/arch/arm26/boot/install.sh b/arch/arm26/boot/install.sh
--- a/arch/arm26/boot/install.sh
+++ b/arch/arm26/boot/install.sh
@@ -23,8 +23,8 @@
 
 # User may have a custom install script
 
-if [ -x /sbin/installkernel ]; then
-  exec /sbin/installkernel "$@"
+if [ -x /sbin/${CROSS_COMPILE}installkernel ]; then
+  exec /sbin/${CROSS_COMPILE}installkernel "$@"
 fi
 
 if [ "$2" = "zImage" ]; then
diff --git a/arch/arm26/kernel/ecard.c b/arch/arm26/kernel/ecard.c
--- a/arch/arm26/kernel/ecard.c
+++ b/arch/arm26/kernel/ecard.c
@@ -562,31 +562,31 @@ static void __init ecard_init_resources(
 	}
 }
 
-static ssize_t ecard_show_irq(struct device *dev, char *buf)
+static ssize_t ecard_show_irq(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct expansion_card *ec = ECARD_DEV(dev);
 	return sprintf(buf, "%u\n", ec->irq);
 }
 
-static ssize_t ecard_show_vendor(struct device *dev, char *buf)
+static ssize_t ecard_show_vendor(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct expansion_card *ec = ECARD_DEV(dev);
 	return sprintf(buf, "%u\n", ec->cid.manufacturer);
 }
 
-static ssize_t ecard_show_device(struct device *dev, char *buf)
+static ssize_t ecard_show_device(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct expansion_card *ec = ECARD_DEV(dev);
 	return sprintf(buf, "%u\n", ec->cid.product);
 }
 
-static ssize_t ecard_show_dma(struct device *dev, char *buf)
+static ssize_t ecard_show_dma(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct expansion_card *ec = ECARD_DEV(dev);
 	return sprintf(buf, "%u\n", ec->dma);
 }
 
-static ssize_t ecard_show_resources(struct device *dev, char *buf)
+static ssize_t ecard_show_resources(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct expansion_card *ec = ECARD_DEV(dev);
 	char *str = buf;
diff --git a/arch/arm26/kernel/process.c b/arch/arm26/kernel/process.c
--- a/arch/arm26/kernel/process.c
+++ b/arch/arm26/kernel/process.c
@@ -103,9 +103,6 @@ void machine_power_off(void)
 {
 }
 
-EXPORT_SYMBOL(machine_halt);
-EXPORT_SYMBOL(machine_power_off);
-
 void machine_restart(char * __unused)
 {
 	/*
@@ -136,8 +133,6 @@ void machine_restart(char * __unused)
 	while (1);
 }
 
-EXPORT_SYMBOL(machine_restart);
-
 void show_regs(struct pt_regs * regs)
 {
 	unsigned long flags;
diff --git a/arch/arm26/mm/fault.c b/arch/arm26/mm/fault.c
--- a/arch/arm26/mm/fault.c
+++ b/arch/arm26/mm/fault.c
@@ -176,12 +176,12 @@ survive:
 	 * Handle the "normal" cases first - successful and sigbus
 	 */
 	switch (fault) {
-	case 2:
+	case VM_FAULT_MAJOR:
 		tsk->maj_flt++;
 		return fault;
-	case 1:
+	case VM_FAULT_MINOR:
 		tsk->min_flt++;
-	case 0:
+	case VM_FAULT_SIGBUS:
 		return fault;
 	}
 
@@ -226,14 +226,11 @@ int do_page_fault(unsigned long addr, un
 	/*
 	 * Handle the "normal" case first
 	 */
-	if (fault > 0)
+	switch (fault) {
+	case VM_FAULT_MINOR:
+	case VM_FAULT_MAJOR:
 		return 0;
-
-	/*
-	 * We had some memory, but were unable to
-	 * successfully fix up this page fault.
-	 */
-	if (fault == 0){
+	case VM_FAULT_SIGBUS:
 		goto do_sigbus;
 	}
 
diff --git a/arch/cris/Kconfig b/arch/cris/Kconfig
--- a/arch/cris/Kconfig
+++ b/arch/cris/Kconfig
@@ -74,6 +74,8 @@ config PREEMPT
 	  Say Y here if you are building a kernel for a desktop, embedded
 	  or real-time system.  Say N if you are unsure.
 
+source mm/Kconfig
+
 endmenu
 
 menu "Hardware setup"
@@ -120,6 +122,8 @@ source arch/cris/arch-v10/Kconfig
 
 endmenu
 
+source "net/Kconfig"
+
 # bring in ETRAX built-in drivers
 menu "Drivers for built-in interfaces"
 source arch/cris/arch-v10/drivers/Kconfig
@@ -147,7 +151,7 @@ source "drivers/ieee1394/Kconfig"
 
 source "drivers/message/i2o/Kconfig"
 
-source "net/Kconfig"
+source "drivers/net/Kconfig"
 
 source "drivers/isdn/Kconfig"
 
diff --git a/arch/cris/Kconfig.debug b/arch/cris/Kconfig.debug
--- a/arch/cris/Kconfig.debug
+++ b/arch/cris/Kconfig.debug
@@ -38,4 +38,9 @@ config FRAME_POINTER
           If you don't debug the kernel, you can say N, but we may not be able
           to solve problems without frame pointers.
 
+config DEBUG_NMI_OOPS
+       bool "NMI causes oops printout"
+       help
+         If the system locks up without any debug information you can say Y
+         here to make it possible to dump an OOPS with an external NMI.
 endmenu
diff --git a/arch/cris/Makefile b/arch/cris/Makefile
--- a/arch/cris/Makefile
+++ b/arch/cris/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.23 2004/10/19 13:07:34 starvik Exp $
+# $Id: Makefile,v 1.28 2005/03/17 10:44:37 larsv Exp $
 # cris/Makefile
 #
 # This file is included by the global makefile so that you can add your own
@@ -15,6 +15,7 @@
 
 arch-y := v10
 arch-$(CONFIG_ETRAX_ARCH_V10) := v10
+arch-$(CONFIG_ETRAX_ARCH_V32) := v32
 
 # No config avaiable for make clean etc
 ifneq ($(arch-y),)
@@ -46,6 +47,21 @@ core-y		+= arch/$(ARCH)/$(SARCH)/kernel/
 drivers-y	+= arch/$(ARCH)/$(SARCH)/drivers/
 libs-y		+= arch/$(ARCH)/$(SARCH)/lib/ $(LIBGCC)
 
+# cris source path
+SRC_ARCH              = $(srctree)/arch/$(ARCH)
+# cris object files path
+OBJ_ARCH              = $(objtree)/arch/$(ARCH)
+
+target_boot_arch_dir  = $(OBJ_ARCH)/$(SARCH)/boot
+target_boot_dir       = $(OBJ_ARCH)/boot
+src_boot_dir          = $(SRC_ARCH)/boot
+target_compressed_dir = $(OBJ_ARCH)/boot/compressed
+src_compressed_dir    = $(SRC_ARCH)/boot/compressed
+target_rescue_dir     = $(OBJ_ARCH)/boot/rescue
+src_rescue_dir        = $(SRC_ARCH)/boot/rescue
+
+export target_boot_arch_dir target_boot_dir src_boot_dir target_compressed_dir src_compressed_dir target_rescue_dir src_rescue_dir
+
 vmlinux.bin: vmlinux
 	$(OBJCOPY) $(OBJCOPYFLAGS) vmlinux vmlinux.bin
 
@@ -65,44 +81,52 @@ cramfs:
 
 clinux: vmlinux.bin decompress.bin rescue.bin
 
-decompress.bin: FORCE
-	@make -C arch/$(ARCH)/boot/compressed decompress.bin
+decompress.bin: $(target_boot_dir)
+	@$(MAKE) -f $(src_compressed_dir)/Makefile $(target_compressed_dir)/decompress.bin
 
-rescue.bin: FORCE
-	@make -C arch/$(ARCH)/boot/rescue rescue.bin
+$(target_rescue_dir)/rescue.bin: $(target_boot_dir)
+	@$(MAKE) -f $(src_rescue_dir)/Makefile $(target_rescue_dir)/rescue.bin
 
-zImage: vmlinux.bin rescue.bin
+zImage: $(target_boot_dir) vmlinux.bin $(target_rescue_dir)/rescue.bin
 ## zImage     - Compressed kernel (gzip)
-	@make -C arch/$(ARCH)/boot/ zImage
+	@$(MAKE) -f $(src_boot_dir)/Makefile zImage
+
+$(target_boot_dir): $(target_boot_arch_dir)
+	ln -sfn $< $@
+
+$(target_boot_arch_dir):
+	mkdir -p $@
 
 compressed: zImage
 
 archmrproper:
 archclean:
-	$(Q)$(MAKE) $(clean)=arch/$(ARCH)/boot
+	@if [ -d arch/$(ARCH)/boot ]; then \
+		$(MAKE) $(clean)=arch/$(ARCH)/boot ; \
+	fi
 	rm -f timage vmlinux.bin decompress.bin rescue.bin cramfs.img
 	rm -rf $(LD_SCRIPT).tmp
 
-prepare: arch/$(ARCH)/.links include/asm-$(ARCH)/.arch \
+prepare: $(SRC_ARCH)/.links $(srctree)/include/asm-$(ARCH)/.arch \
 	 include/asm-$(ARCH)/$(SARCH)/offset.h
 
 # Create some links to make all tools happy
-arch/$(ARCH)/.links:
-	@rm -rf arch/$(ARCH)/drivers
-	@ln -sfn $(SARCH)/drivers arch/$(ARCH)/drivers
-	@rm -rf arch/$(ARCH)/boot
-	@ln -sfn $(SARCH)/boot arch/$(ARCH)/boot
-	@rm -rf arch/$(ARCH)/lib
-	@ln -sfn $(SARCH)/lib arch/$(ARCH)/lib
-	@ln -sfn $(SARCH) arch/$(ARCH)/arch
-	@ln -sfn ../$(SARCH)/vmlinux.lds.S arch/$(ARCH)/kernel/vmlinux.lds.S
+$(SRC_ARCH)/.links:
+	@rm -rf $(SRC_ARCH)/drivers
+	@ln -sfn $(SRC_ARCH)/$(SARCH)/drivers $(SRC_ARCH)/drivers
+	@rm -rf $(SRC_ARCH)/boot
+	@ln -sfn $(SRC_ARCH)/$(SARCH)/boot $(SRC_ARCH)/boot
+	@rm -rf $(SRC_ARCH)/lib
+	@ln -sfn $(SRC_ARCH)/$(SARCH)/lib $(SRC_ARCH)/lib
+	@ln -sfn $(SRC_ARCH)/$(SARCH) $(SRC_ARCH)/arch
+	@ln -sfn $(SRC_ARCH)/$(SARCH)/vmlinux.lds.S $(SRC_ARCH)/kernel/vmlinux.lds.S
 	@touch $@
 
 # Create link to sub arch includes
-include/asm-$(ARCH)/.arch: $(wildcard include/config/arch/*.h)
-	@echo '  Making asm-$(ARCH)/arch -> asm-$(ARCH)/$(SARCH) symlink'
+$(srctree)/include/asm-$(ARCH)/.arch: $(wildcard include/config/arch/*.h)
+	@echo '  Making $(srctree)/include/asm-$(ARCH)/arch -> $(srctree)/include/asm-$(ARCH)/$(SARCH) symlink'
 	@rm -f include/asm-$(ARCH)/arch
-	@ln -sf $(SARCH) include/asm-$(ARCH)/arch
+	@ln -sf $(srctree)/include/asm-$(ARCH)/$(SARCH) $(srctree)/include/asm-$(ARCH)/arch
 	@touch $@
 
 arch/$(ARCH)/$(SARCH)/kernel/asm-offsets.s: include/asm include/linux/version.h \
diff --git a/arch/cris/arch-v10/Kconfig b/arch/cris/arch-v10/Kconfig
--- a/arch/cris/arch-v10/Kconfig
+++ b/arch/cris/arch-v10/Kconfig
@@ -260,6 +260,37 @@ config ETRAX_DEBUG_PORT_NULL
 endchoice
 
 choice
+	prompt "Kernel GDB port"
+	depends on ETRAX_KGDB
+	default ETRAX_KGDB_PORT0
+	help
+	  Choose a serial port for kernel debugging.  NOTE: This port should
+	  not be enabled under Drivers for built-in interfaces (as it has its
+	  own initialization code) and should not be the same as the debug port.
+
+config ETRAX_KGDB_PORT0
+	bool "Serial-0"
+	help
+	  Use serial port 0 for kernel debugging.
+
+config ETRAX_KGDB_PORT1
+	bool "Serial-1"
+	help
+	  Use serial port 1 for kernel debugging.
+
+config ETRAX_KGDB_PORT2
+	bool "Serial-2"
+	help
+	  Use serial port 2 for kernel debugging.
+
+config ETRAX_KGDB_PORT3
+	bool "Serial-3"
+	help
+	  Use serial port 3 for kernel debugging.
+
+endchoice
+
+choice
 	prompt "Product rescue-port"
 	depends on ETRAX_ARCH_V10
 	default ETRAX_RESCUE_SER0
diff --git a/arch/cris/arch-v10/boot/Makefile b/arch/cris/arch-v10/boot/Makefile
--- a/arch/cris/arch-v10/boot/Makefile
+++ b/arch/cris/arch-v10/boot/Makefile
@@ -1,12 +1,13 @@
 #
 # arch/cris/boot/Makefile
 #
+target = $(target_boot_dir)
+src    = $(src_boot_dir)
 
 zImage: compressed/vmlinuz
 
-compressed/vmlinuz: $(TOPDIR)/vmlinux
-	@$(MAKE) -C compressed vmlinuz
+compressed/vmlinuz:
+	@$(MAKE) -f $(src)/compressed/Makefile $(target_compressed_dir)/vmlinuz
 
 clean:
-	rm -f zImage tools/build compressed/vmlinux.out
-	@$(MAKE) -C compressed clean
+	@$(MAKE) -f $(src)/compressed/Makefile clean
diff --git a/arch/cris/arch-v10/boot/compressed/Makefile b/arch/cris/arch-v10/boot/compressed/Makefile
--- a/arch/cris/arch-v10/boot/compressed/Makefile
+++ b/arch/cris/arch-v10/boot/compressed/Makefile
@@ -1,40 +1,45 @@
 #
-# linux/arch/etrax100/boot/compressed/Makefile
-#
-# create a compressed vmlinux image from the original vmlinux files and romfs
+# create a compressed vmlinuz image from the binary vmlinux.bin file
 #
+target = $(target_compressed_dir)
+src    = $(src_compressed_dir)
 
-CC = gcc-cris -melf -I $(TOPDIR)/include
+CC = gcc-cris -melf $(LINUXINCLUDE)
 CFLAGS = -O2
 LD = ld-cris
 OBJCOPY = objcopy-cris
 OBJCOPYFLAGS = -O binary --remove-section=.bss
-OBJECTS = head.o misc.o
+OBJECTS = $(target)/head.o $(target)/misc.o
 
 # files to compress
-SYSTEM = $(TOPDIR)/vmlinux.bin
+SYSTEM = $(objtree)/vmlinux.bin
 
-all: vmlinuz
+all: $(target_compressed_dir)/vmlinuz
 
-decompress.bin: $(OBJECTS)
-	$(LD) -T decompress.ld -o decompress.o $(OBJECTS)
-	$(OBJCOPY) $(OBJCOPYFLAGS) decompress.o decompress.bin
-# save it for mkprod in the topdir.
-	cp decompress.bin $(TOPDIR)
+$(target)/decompress.bin: $(OBJECTS)
+	$(LD) -T $(src)/decompress.ld -o $(target)/decompress.o $(OBJECTS)
+	$(OBJCOPY) $(OBJCOPYFLAGS) $(target)/decompress.o $(target)/decompress.bin
 
+# Create vmlinuz image in top-level build directory
+$(target_compressed_dir)/vmlinuz: $(target) piggy.img $(target)/decompress.bin
+	@echo "  COMPR   vmlinux.bin --> vmlinuz"
+	@cat $(target)/decompress.bin piggy.img > $(target_compressed_dir)/vmlinuz
+	@rm -f piggy.img
 
-vmlinuz: piggy.img decompress.bin
-	cat decompress.bin piggy.img > vmlinuz
-	rm -f piggy.img
+$(target)/head.o: $(src)/head.S
+	$(CC) -D__ASSEMBLY__ -traditional -c $< -o $@
 
-head.o: head.S
-	$(CC) -D__ASSEMBLY__ -traditional -c head.S -o head.o
+$(target)/misc.o: $(src)/misc.c
+	$(CC) -D__KERNEL__ -c $< -o $@
 
 # gzip the kernel image
 
 piggy.img: $(SYSTEM)
-	cat $(SYSTEM) | gzip -f -9 > piggy.img
+	@cat $(SYSTEM) | gzip -f -9 > piggy.img
+
+$(target):
+	mkdir -p $(target)
 
 clean:
-	rm -f piggy.img vmlinuz vmlinuz.o
+	rm -f piggy.img $(objtree)/vmlinuz
 
diff --git a/arch/cris/arch-v10/boot/compressed/head.S b/arch/cris/arch-v10/boot/compressed/head.S
--- a/arch/cris/arch-v10/boot/compressed/head.S
+++ b/arch/cris/arch-v10/boot/compressed/head.S
@@ -13,7 +13,8 @@
 #include <asm/arch/sv_addr_ag.h>
 
 #define RAM_INIT_MAGIC 0x56902387
-	
+#define COMMAND_LINE_MAGIC 0x87109563
+
 	;; Exported symbols
 	
 	.globl	_input_data
@@ -88,6 +89,12 @@ basse:	move.d	pc, r5
 	cmp.d	r2, r1
 	bcs	1b
 	nop
+
+	;;  Save command line magic and address.
+	move.d	_cmd_line_magic, $r12
+	move.d  $r10, [$r12]
+	move.d	_cmd_line_addr, $r12
+	move.d  $r11, [$r12]
 	
 	;; Do the decompression and save compressed size in _inptr
 
@@ -98,7 +105,13 @@ basse:	move.d	pc, r5
 
 	move.d	[_input_data], r9	; flash address of compressed kernel
 	add.d	[_inptr], r9		; size of compressed kernel
-	 
+
+	;; Restore command line magic and address.
+	move.d  _cmd_line_magic, $r10
+	move.d  [$r10], $r10
+	move.d  _cmd_line_addr, $r11
+	move.d  [$r11], $r11
+
 	;; Enter the decompressed kernel
 	move.d	RAM_INIT_MAGIC, r8	; Tell kernel that DRAM is initialized
 	jump	0x40004000	; kernel is linked to this address
@@ -107,5 +120,8 @@ basse:	move.d	pc, r5
 
 _input_data:
 	.dword	0		; used by the decompressor
-
+_cmd_line_magic:
+	.dword 0
+_cmd_line_addr:
+	.dword 0
 #include "../../lib/hw_settings.S"
diff --git a/arch/cris/arch-v10/boot/rescue/Makefile b/arch/cris/arch-v10/boot/rescue/Makefile
--- a/arch/cris/arch-v10/boot/rescue/Makefile
+++ b/arch/cris/arch-v10/boot/rescue/Makefile
@@ -1,52 +1,53 @@
 #
 # Makefile for rescue code
 #
-ifndef TOPDIR
-TOPDIR = ../../../..
-endif
-CC = gcc-cris -mlinux -I $(TOPDIR)/include
+target = $(target_rescue_dir)
+src    = $(src_rescue_dir)
+
+CC = gcc-cris -mlinux $(LINUXINCLUDE)
 CFLAGS = -O2
 LD = gcc-cris -mlinux -nostdlib
 OBJCOPY = objcopy-cris
 OBJCOPYFLAGS = -O binary --remove-section=.bss
 
-all: rescue.bin testrescue.bin kimagerescue.bin
-
-rescue: rescue.bin
-	# do nothing
+all: $(target)/rescue.bin $(target)/testrescue.bin $(target)/kimagerescue.bin
 
-rescue.bin: head.o
-	$(LD) -T rescue.ld -o rescue.o head.o
-	$(OBJCOPY) $(OBJCOPYFLAGS) rescue.o rescue.bin
-	cp rescue.bin $(TOPDIR)
+$(target)/rescue.bin: $(target) $(target)/head.o
+	$(LD) -T $(src)/rescue.ld -o $(target)/rescue.o $(target)/head.o
+	$(OBJCOPY) $(OBJCOPYFLAGS) $(target)/rescue.o $(target)/rescue.bin
+# Place a copy in top-level build directory
+	cp -p $(target)/rescue.bin $(objtree)
 
-testrescue.bin: testrescue.o
-	$(OBJCOPY) $(OBJCOPYFLAGS) testrescue.o tr.bin
+$(target)/testrescue.bin: $(target) $(target)/testrescue.o
+	$(OBJCOPY) $(OBJCOPYFLAGS) $(target)/testrescue.o tr.bin
 # Pad it to 784 bytes
 	dd if=/dev/zero of=tmp2423 bs=1 count=784
 	cat tr.bin tmp2423 >testrescue_tmp.bin
-	dd if=testrescue_tmp.bin of=testrescue.bin bs=1 count=784
+	dd if=testrescue_tmp.bin of=$(target)/testrescue.bin bs=1 count=784
 	rm tr.bin tmp2423 testrescue_tmp.bin
 
-kimagerescue.bin: kimagerescue.o
-	$(OBJCOPY) $(OBJCOPYFLAGS) kimagerescue.o ktr.bin
+$(target)/kimagerescue.bin: $(target) $(target)/kimagerescue.o
+	$(OBJCOPY) $(OBJCOPYFLAGS) $(target)/kimagerescue.o ktr.bin
 # Pad it to 784 bytes, that's what the rescue loader expects
 	dd if=/dev/zero of=tmp2423 bs=1 count=784
 	cat ktr.bin tmp2423 >kimagerescue_tmp.bin
-	dd if=kimagerescue_tmp.bin of=kimagerescue.bin bs=1 count=784
+	dd if=kimagerescue_tmp.bin of=$(target)/kimagerescue.bin bs=1 count=784
 	rm ktr.bin tmp2423 kimagerescue_tmp.bin
 
-head.o: head.S
+$(target):
+	mkdir -p $(target)
+
+$(target)/head.o: $(src)/head.S
 	$(CC) -D__ASSEMBLY__ -traditional -c $< -o $*.o
 
-testrescue.o: testrescue.S
+$(target)/testrescue.o: $(src)/testrescue.S
 	$(CC) -D__ASSEMBLY__ -traditional -c $< -o $*.o
 
-kimagerescue.o: kimagerescue.S
+$(target)/kimagerescue.o: $(src)/kimagerescue.S
 	$(CC) -D__ASSEMBLY__ -traditional -c $< -o $*.o
 
 clean:
-	rm -f *.o *.bin
+	rm -f $(target)/*.o $(target)/*.bin
 
 fastdep:
 
diff --git a/arch/cris/arch-v10/boot/rescue/head.S b/arch/cris/arch-v10/boot/rescue/head.S
--- a/arch/cris/arch-v10/boot/rescue/head.S
+++ b/arch/cris/arch-v10/boot/rescue/head.S
@@ -1,4 +1,4 @@
-/* $Id: head.S,v 1.6 2003/04/09 08:12:43 pkj Exp $
+/* $Id: head.S,v 1.7 2005/03/07 12:11:06 starvik Exp $
  * 
  * Rescue code, made to reside at the beginning of the
  * flash-memory. when it starts, it checks a partition
@@ -121,12 +121,13 @@
 	;; 0x80000000 if loaded in flash (as it should be)
 	;; since etrax actually starts at address 2 when booting from flash, we
 	;; put a nop (2 bytes) here first so we dont accidentally skip the di
-	
+
 	nop	
 	di
 
 	jump	in_cache	; enter cached area instead
-in_cache:	
+in_cache:
+
 
 	;; first put a jump test to give a possibility of upgrading the rescue code
 	;; without erasing/reflashing the sector. we put a longword of -1 here and if
@@ -325,9 +326,29 @@ flash_ok:
 	;; result will be in r0
 checksum:
 	moveq	0, $r0
-1:	addu.b	[$r1+], $r0
-	subq	1, $r2
-	bne	1b
+	moveq   CONFIG_ETRAX_FLASH1_SIZE, $r6
+
+	;; If the first physical flash memory is exceeded wrap to the second one.
+	btstq	26, $r1		; Are we addressing first flash?
+	bpl	1f
+	nop
+	clear.d	$r6
+
+1:	test.d  $r6		; 0 = no wrapping
+	beq	2f
+	nop
+	lslq	20, $r6		; Convert MB to bytes
+	sub.d	$r1, $r6
+
+2:	addu.b	[$r1+], $r0
+	subq	1, $r6		; Flash memory left
+	beq	3f
+	subq	1, $r2		; Length left
+	bne	2b
 	nop
 	ret
 	nop
+
+3:	move.d	MEM_CSE1_START, $r1 ; wrap to second flash
+	ba	2b
+	nop
diff --git a/arch/cris/arch-v10/drivers/Kconfig b/arch/cris/arch-v10/drivers/Kconfig
--- a/arch/cris/arch-v10/drivers/Kconfig
+++ b/arch/cris/arch-v10/drivers/Kconfig
@@ -1,17 +1,11 @@
 config ETRAX_ETHERNET
 	bool "Ethernet support"
 	depends on ETRAX_ARCH_V10
+	select NET_ETHERNET
 	help
 	  This option enables the ETRAX 100LX built-in 10/100Mbit Ethernet
 	  controller.
 
-# this is just so that the user does not have to go into the
-# normal ethernet driver section just to enable ethernetworking
-config NET_ETHERNET
-	bool
-	depends on ETRAX_ETHERNET
-	default y
-
 choice
 	prompt "Network LED behavior"
 	depends on ETRAX_ETHERNET
@@ -20,26 +14,26 @@ choice
 config ETRAX_NETWORK_LED_ON_WHEN_LINK
 	bool "LED_on_when_link"
 	help
-	  Selecting LED_on_when_link will light the LED when there is a 
-	  connection and will flash off when there is activity. 
+	  Selecting LED_on_when_link will light the LED when there is a
+	  connection and will flash off when there is activity.
 
-	  Selecting LED_on_when_activity will light the LED only when 
+	  Selecting LED_on_when_activity will light the LED only when
 	  there is activity.
 
-	  This setting will also affect the behaviour of other activity LEDs 
-	  e.g. Bluetooth. 
+	  This setting will also affect the behaviour of other activity LEDs
+	  e.g. Bluetooth.
 
 config ETRAX_NETWORK_LED_ON_WHEN_ACTIVITY
 	bool "LED_on_when_activity"
 	help
-	  Selecting LED_on_when_link will light the LED when there is a 
-	  connection and will flash off when there is activity. 
+	  Selecting LED_on_when_link will light the LED when there is a
+	  connection and will flash off when there is activity.
 
-	  Selecting LED_on_when_activity will light the LED only when 
+	  Selecting LED_on_when_activity will light the LED only when
 	  there is activity.
 
-	  This setting will also affect the behaviour of other activity LEDs 
-	  e.g. Bluetooth. 
+	  This setting will also affect the behaviour of other activity LEDs
+	  e.g. Bluetooth.
 
 endchoice
 
@@ -91,11 +85,11 @@ choice
 	depends on ETRAX_SERIAL_PORT0
 	default ETRAX_SERIAL_PORT0_DMA6_OUT
 
-config CONFIG_ETRAX_SERIAL_PORT0_NO_DMA_OUT
-       bool "No DMA out"
+config ETRAX_SERIAL_PORT0_NO_DMA_OUT
+	bool "No DMA out"
 
-config CONFIG_ETRAX_SERIAL_PORT0_DMA6_OUT
-       bool "DMA 6"
+config ETRAX_SERIAL_PORT0_DMA6_OUT
+	bool "DMA 6"
 
 endchoice
 
@@ -104,11 +98,11 @@ choice
 	depends on ETRAX_SERIAL_PORT0
 	default ETRAX_SERIAL_PORT0_DMA7_IN
 
-config CONFIG_ETRAX_SERIAL_PORT0_NO_DMA_IN
-       bool "No DMA in"
+config ETRAX_SERIAL_PORT0_NO_DMA_IN
+	bool "No DMA in"
 
-config CONFIG_ETRAX_SERIAL_PORT0_DMA7_IN
-       bool "DMA 7"
+config ETRAX_SERIAL_PORT0_DMA7_IN
+	bool "DMA 7"
 
 endchoice
 
@@ -205,11 +199,11 @@ choice
 	depends on ETRAX_SERIAL_PORT1
 	default ETRAX_SERIAL_PORT1_DMA8_OUT
 
-config CONFIG_ETRAX_SERIAL_PORT1_NO_DMA_OUT
-       bool "No DMA out"
+config ETRAX_SERIAL_PORT1_NO_DMA_OUT
+	bool "No DMA out"
 
-config CONFIG_ETRAX_SERIAL_PORT1_DMA8_OUT
-       bool "DMA 8"
+config ETRAX_SERIAL_PORT1_DMA8_OUT
+	bool "DMA 8"
 
 endchoice
 
@@ -218,11 +212,11 @@ choice
 	depends on ETRAX_SERIAL_PORT1
 	default ETRAX_SERIAL_PORT1_DMA9_IN
 
-config CONFIG_ETRAX_SERIAL_PORT1_NO_DMA_IN
-       bool "No DMA in"
+config ETRAX_SERIAL_PORT1_NO_DMA_IN
+	bool "No DMA in"
 
-config CONFIG_ETRAX_SERIAL_PORT1_DMA9_IN
-       bool "DMA 9"
+config ETRAX_SERIAL_PORT1_DMA9_IN
+	bool "DMA 9"
 
 endchoice
 
@@ -308,7 +302,7 @@ config ETRAX_SER1_CD_ON_PB_BIT
 	  Specify the pin of the PB port to carry the CD signal for serial
 	  port 1.
 
-comment "Make sure you dont have the same PB bits more than once!"
+comment "Make sure you do not have the same PB bits more than once!"
 	depends on ETRAX_SERIAL && ETRAX_SER0_DTR_RI_DSR_CD_ON_PB && ETRAX_SER1_DTR_RI_DSR_CD_ON_PB
 
 config ETRAX_SERIAL_PORT2
@@ -322,11 +316,11 @@ choice
 	depends on ETRAX_SERIAL_PORT2
 	default ETRAX_SERIAL_PORT2_DMA2_OUT
 
-config CONFIG_ETRAX_SERIAL_PORT2_NO_DMA_OUT
-       bool "No DMA out"
+config ETRAX_SERIAL_PORT2_NO_DMA_OUT
+	bool "No DMA out"
 
-config CONFIG_ETRAX_SERIAL_PORT2_DMA2_OUT
-       bool "DMA 2"
+config ETRAX_SERIAL_PORT2_DMA2_OUT
+	bool "DMA 2"
 
 endchoice
 
@@ -335,11 +329,11 @@ choice
 	depends on ETRAX_SERIAL_PORT2
 	default ETRAX_SERIAL_PORT2_DMA3_IN
 
-config CONFIG_ETRAX_SERIAL_PORT2_NO_DMA_IN
-       bool "No DMA in"
+config ETRAX_SERIAL_PORT2_NO_DMA_IN
+	bool "No DMA in"
 
-config CONFIG_ETRAX_SERIAL_PORT2_DMA3_IN
-       bool "DMA 3"
+config ETRAX_SERIAL_PORT2_DMA3_IN
+	bool "DMA 3"
 
 endchoice
 
@@ -436,11 +430,11 @@ choice
 	depends on ETRAX_SERIAL_PORT3
 	default ETRAX_SERIAL_PORT3_DMA4_OUT
 
-config CONFIG_ETRAX_SERIAL_PORT3_NO_DMA_OUT
-       bool "No DMA out"
+config ETRAX_SERIAL_PORT3_NO_DMA_OUT
+	bool "No DMA out"
 
-config CONFIG_ETRAX_SERIAL_PORT3_DMA4_OUT
-       bool "DMA 4"
+config ETRAX_SERIAL_PORT3_DMA4_OUT
+	bool "DMA 4"
 
 endchoice
 
@@ -449,11 +443,11 @@ choice
 	depends on ETRAX_SERIAL_PORT3
 	default ETRAX_SERIAL_PORT3_DMA5_IN
 
-config CONFIG_ETRAX_SERIAL_PORT3_NO_DMA_IN
-       bool "No DMA in"
+config ETRAX_SERIAL_PORT3_NO_DMA_IN
+	bool "No DMA in"
 
-config CONFIG_ETRAX_SERIAL_PORT3_DMA5_IN
-       bool "DMA 5"
+config ETRAX_SERIAL_PORT3_DMA5_IN
+	bool "DMA 5"
 
 endchoice
 
@@ -554,7 +548,6 @@ config ETRAX_IDE
 	select BLK_DEV_IDEDISK
 	select BLK_DEV_IDECD
 	select BLK_DEV_IDEDMA
-	select DMA_NONPCI
 	help
 	  Enable this to get support for ATA/IDE.
 	  You can't use paralell ports or SCSI ports
@@ -579,7 +572,7 @@ config ETRAX_IDE_PB7_RESET
 	  IDE reset on pin 7 on port B
 
 config ETRAX_IDE_G27_RESET
-        bool "Port_G_Bit_27"
+	bool "Port_G_Bit_27"
 	help
 	  IDE reset on pin 27 on port G
 
@@ -588,30 +581,36 @@ endchoice
 
 config ETRAX_USB_HOST
 	bool "USB host"
+	select USB
 	help
 	   This option enables the host functionality of the ETRAX 100LX
 	   built-in USB controller. In host mode the controller is designed
 	   for CTRL and BULK traffic only, INTR traffic may work as well
 	   however (depending on the requirements of timeliness).
 
-config USB
-       tristate
-       depends on ETRAX_USB_HOST
-       default y
-
 config ETRAX_USB_HOST_PORT1
-       bool "  USB port 1 enabled"
-       depends on ETRAX_USB_HOST
-       default n
+	bool "USB port 1 enabled"
+	depends on ETRAX_USB_HOST
+	default n
 
 config ETRAX_USB_HOST_PORT2
-       bool "  USB port 2 enabled"
-       depends on ETRAX_USB_HOST
-       default n
+	bool "USB port 2 enabled"
+	depends on ETRAX_USB_HOST
+	default n
 
 config ETRAX_AXISFLASHMAP
 	bool "Axis flash-map support"
 	depends on ETRAX_ARCH_V10
+	select MTD
+	select MTD_CFI
+	select MTD_CFI_AMDSTD
+	select MTD_OBSOLETE_CHIPS
+	select MTD_AMDSTD
+	select MTD_CHAR
+	select MTD_BLOCK
+	select MTD_PARTITIONS
+	select MTD_CONCAT
+	select MTD_COMPLEX_MAPPINGS
 	help
 	  This option enables MTD mapping of flash devices.  Needed to use
 	  flash memories.  If unsure, say Y.
@@ -627,119 +626,6 @@ config ETRAX_PTABLE_SECTOR
 	  for changing this is when the flash block size is bigger
 	  than 64kB (e.g. when using two parallel 16 bit flashes).
 
-# here we define the CONFIG_'s necessary to enable MTD support
-# for the flash
-config MTD
-	tristate
-	depends on ETRAX_AXISFLASHMAP
-	default y
-	help
-	  Memory Technology Devices are flash, RAM and similar chips, often
-	  used for solid state file systems on embedded devices. This option
-	  will provide the generic support for MTD drivers to register
-	  themselves with the kernel and for potential users of MTD devices
-	  to enumerate the devices which are present and obtain a handle on
-	  them. It will also allow you to select individual drivers for 
-	  particular hardware and users of MTD devices. If unsure, say N.
-
-config MTD_CFI
-	tristate
-	depends on ETRAX_AXISFLASHMAP
-	default y
-	help
-	  The Common Flash Interface specification was developed by Intel,
-	  AMD and other flash manufactures that provides a universal method
-	  for probing the capabilities of flash devices. If you wish to
-	  support any device that is CFI-compliant, you need to enable this
-	  option. Visit <http://www.amd.com/products/nvd/overview/cfi.html>
-	  for more information on CFI.
-
-config MTD_CFI_AMDSTD
-	tristate
-	depends on ETRAX_AXISFLASHMAP
-	default y
-	help
-	  The Common Flash Interface defines a number of different command
-	  sets which a CFI-compliant chip may claim to implement. This code
-	  provides support for one of those command sets, used on chips 
-	  chips including the AMD Am29LV320.
-
-config MTD_OBSOLETE_CHIPS
-	bool
-	depends on ETRAX_AXISFLASHMAP
-	default y
-	help
-	  This option does not enable any code directly, but will allow you to
-	  select some other chip drivers which are now considered obsolete,
-	  because the generic CONFIG_JEDEC_PROBE code above should now detect
-	  the chips which are supported by these drivers, and allow the generic
-	  CFI-compatible drivers to drive the chips. Say 'N' here unless you have
-	  already tried the CONFIG_JEDEC_PROBE method and reported its failure
-	  to the MTD mailing list at <linux-mtd@lists.infradead.org>
-
-config MTD_AMDSTD
-	tristate
-	depends on ETRAX_AXISFLASHMAP
-	default y
-	help
-	  This option enables support for flash chips using AMD-compatible
-	  commands, including some which are not CFI-compatible and hence 
-	  cannot be used with the CONFIG_MTD_CFI_AMDSTD option.
-
-	  It also works on AMD compatible chips that do conform to CFI.
-
-config MTD_CHAR
-	tristate
-	depends on ETRAX_AXISFLASHMAP
-	default y
-	help
-	  This provides a character device for each MTD device present in
-	  the system, allowing the user to read and write directly to the
-	  memory chips, and also use ioctl() to obtain information about
-	  the device, or to erase parts of it.
-
-config MTD_BLOCK
-	tristate
-	depends on ETRAX_AXISFLASHMAP
-	default y
-	---help---
-	  Although most flash chips have an erase size too large to be useful
-	  as block devices, it is possible to use MTD devices which are based
-	  on RAM chips in this manner. This block device is a user of MTD
-	  devices performing that function.
-
-	  At the moment, it is also required for the Journalling Flash File
-	  System(s) to obtain a handle on the MTD device when it's mounted
-	  (although JFFS and JFFS2 don't actually use any of the functionality
-	  of the mtdblock device).
-
-	  Later, it may be extended to perform read/erase/modify/write cycles
-	  on flash chips to emulate a smaller block size. Needless to say,
-	  this is very unsafe, but could be useful for file systems which are
-	  almost never written to.
-
-	  You do not need this option for use with the DiskOnChip devices. For
-	  those, enable NFTL support (CONFIG_NFTL) instead.
-
-config MTD_PARTITIONS
-	tristate
-	depends on ETRAX_AXISFLASHMAP
-	default y
-	help
-	  If you have a device which needs to divide its flash chip(s) up
-	  into multiple 'partitions', each of which appears to the user as
-	  a separate MTD device, you require this option to be enabled. If
-	  unsure, say 'Y'.
-
-	  Note, however, that you don't need this option for the DiskOnChip
-	  devices. Partitioning on NFTL 'devices' is a different - that's the
-	  'normal' form of partitioning used on a block device.
-
-config MTD_CONCAT
-	tristate
-	depends on ETRAX_AXISFLASHMAP
-	default y
-
 config ETRAX_I2C
 	bool "I2C support"
 	depends on ETRAX_ARCH_V10
@@ -752,7 +638,7 @@ config ETRAX_I2C
 	  val = ioctl(fd, _IO(ETRAXI2C_IOCTYPE, I2C_READREG), i2c_arg);
 
 # this is true for most products since PB-I2C seems to be somewhat
-# flawed.. 
+# flawed..
 config ETRAX_I2C_USES_PB_NOT_PB_I2C
 	bool "I2C uses PB not PB-I2C"
 	depends on ETRAX_I2C
@@ -886,7 +772,7 @@ config ETRAX_RTC
 	bool "Real Time Clock support"
 	depends on ETRAX_ARCH_V10
 	help
-	  Enables drivers for the Real-Time Clock battery-backed chips on 
+	  Enables drivers for the Real-Time Clock battery-backed chips on
 	  some products. The kernel reads the time when booting, and
 	  the date can be set using ioctl(fd, RTC_SET_TIME, &rt) with rt a
 	  rtc_time struct (see <file:include/asm-cris/rtc.h>) on the /dev/rtc
@@ -903,13 +789,13 @@ config ETRAX_DS1302
 	bool "DS1302"
 	help
 	  Enables the driver for the DS1302 Real-Time Clock battery-backed
-	  chip on some products. 
+	  chip on some products.
 
 config ETRAX_PCF8563
 	bool "PCF8563"
 	help
 	  Enables the driver for the PCF8563 Real-Time Clock battery-backed
-	  chip on some products.  
+	  chip on some products.
 
 endchoice
 
@@ -954,10 +840,8 @@ config ETRAX_DS1302_TRICKLE_CHARGE
 	help
 	  This controls the initial value of the trickle charge register.
 	  0 = disabled (use this if you are unsure or have a non rechargable battery)
-	  Otherwise the following values can be OR:ed together to control the 
+	  Otherwise the following values can be OR:ed together to control the
 	  charge current:
 	  1 = 2kohm, 2 = 4kohm, 3 = 4kohm
 	  4 = 1 diode, 8 = 2 diodes
 	  Allowed values are (increasing current): 0, 11, 10, 9, 7, 6, 5
-
-
diff --git a/arch/cris/arch-v10/drivers/axisflashmap.c b/arch/cris/arch-v10/drivers/axisflashmap.c
--- a/arch/cris/arch-v10/drivers/axisflashmap.c
+++ b/arch/cris/arch-v10/drivers/axisflashmap.c
@@ -11,6 +11,9 @@
  * partition split defined below.
  *
  * $Log: axisflashmap.c,v $
+ * Revision 1.11  2004/11/15 10:27:14  starvik
+ * Corrected typo (Thanks to Milton Miller <miltonm@bga.com>).
+ *
  * Revision 1.10  2004/08/16 12:37:22  starvik
  * Merge of Linux 2.6.8
  *
@@ -161,7 +164,7 @@
 #elif CONFIG_ETRAX_FLASH_BUSWIDTH==2
 #define flash_data __u16
 #elif CONFIG_ETRAX_FLASH_BUSWIDTH==4
-#define flash_data __u16
+#define flash_data __u32
 #endif
 
 /* From head.S */
diff --git a/arch/cris/arch-v10/drivers/ds1302.c b/arch/cris/arch-v10/drivers/ds1302.c
--- a/arch/cris/arch-v10/drivers/ds1302.c
+++ b/arch/cris/arch-v10/drivers/ds1302.c
@@ -7,6 +7,15 @@
 *! Functions exported: ds1302_readreg, ds1302_writereg, ds1302_init
 *!
 *! $Log: ds1302.c,v $
+*! Revision 1.18  2005/01/24 09:11:26  mikaelam
+*! Minor changes to get DS1302 RTC chip driver to work
+*!
+*! Revision 1.17  2005/01/05 06:11:22  starvik
+*! No need to do local_irq_disable after local_irq_save.
+*!
+*! Revision 1.16  2004/12/13 12:21:52  starvik
+*! Added I/O and DMA allocators from Linux 2.4
+*!
 *! Revision 1.14  2004/08/24 06:48:43  starvik
 *! Whitespace cleanup
 *!
@@ -124,9 +133,9 @@
 *!
 *! ---------------------------------------------------------------------------
 *!
-*! (C) Copyright 1999, 2000, 2001  Axis Communications AB, LUND, SWEDEN
+*! (C) Copyright 1999, 2000, 2001, 2002, 2003, 2004  Axis Communications AB, LUND, SWEDEN
 *!
-*! $Id: ds1302.c,v 1.14 2004/08/24 06:48:43 starvik Exp $
+*! $Id: ds1302.c,v 1.18 2005/01/24 09:11:26 mikaelam Exp $
 *!
 *!***************************************************************************/
 
@@ -145,6 +154,7 @@
 #include <asm/arch/svinto.h>
 #include <asm/io.h>
 #include <asm/rtc.h>
+#include <asm/arch/io_interface_mux.h>
 
 #define RTC_MAJOR_NR 121 /* local major, change later */
 
@@ -320,7 +330,6 @@ get_rtc_time(struct rtc_time *rtc_tm) 
 	unsigned long flags;
 
 	local_irq_save(flags);
-	local_irq_disable();
 
 	rtc_tm->tm_sec = CMOS_READ(RTC_SECONDS);
 	rtc_tm->tm_min = CMOS_READ(RTC_MINUTES);
@@ -358,7 +367,7 @@ static int
 rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
 	  unsigned long arg) 
 {
-        unsigned long flags;
+	unsigned long flags;
 
 	switch(cmd) {
 		case RTC_RD_TIME:	/* read the time/date from RTC	*/
@@ -382,7 +391,7 @@ rtc_ioctl(struct inode *inode, struct fi
 				return -EPERM;
 
 			if (copy_from_user(&rtc_tm, (struct rtc_time*)arg, sizeof(struct rtc_time)))
-				return -EFAULT;    	
+				return -EFAULT;
 
 			yrs = rtc_tm.tm_year + 1900;
 			mon = rtc_tm.tm_mon + 1;   /* tm_mon starts at zero */
@@ -419,7 +428,6 @@ rtc_ioctl(struct inode *inode, struct fi
 			BIN_TO_BCD(yrs);
 
 			local_irq_save(flags);
-			local_irq_disable();
 			CMOS_WRITE(yrs, RTC_YEAR);
 			CMOS_WRITE(mon, RTC_MONTH);
 			CMOS_WRITE(day, RTC_DAY_OF_MONTH);
@@ -438,7 +446,7 @@ rtc_ioctl(struct inode *inode, struct fi
 
 		case RTC_SET_CHARGE: /* set the RTC TRICKLE CHARGE register */
 		{
-			int tcs_val;                        
+			int tcs_val;
 
 			if (!capable(CAP_SYS_TIME))
 				return -EPERM;
@@ -492,8 +500,8 @@ print_rtc_status(void)
 /* The various file operations we support. */
 
 static struct file_operations rtc_fops = {
-        .owner          = THIS_MODULE,
-        .ioctl          = rtc_ioctl,	
+	.owner =	THIS_MODULE,
+	.ioctl =	rtc_ioctl,
 }; 
 
 /* Probe for the chip by writing something to its RAM and try reading it back. */
@@ -532,7 +540,7 @@ ds1302_probe(void) 
 		       "PB",
 #endif
 		       CONFIG_ETRAX_DS1302_RSTBIT);
-                print_rtc_status();
+		       print_rtc_status();
 		retval = 1;
 	} else {
 		stop();
@@ -548,7 +556,9 @@ ds1302_probe(void) 
 int __init
 ds1302_init(void) 
 {
+#ifdef CONFIG_ETRAX_I2C
 	i2c_init();
+#endif
 
 	if (!ds1302_probe()) {
 #ifdef CONFIG_ETRAX_DS1302_RST_ON_GENERIC_PORT
@@ -558,25 +568,42 @@ ds1302_init(void) 
 		 *
 		 * Make sure that R_GEN_CONFIG is setup correct.
 		 */
-    		genconfig_shadow = ((genconfig_shadow &
-				     ~IO_MASK(R_GEN_CONFIG, ata)) | 
-				   (IO_STATE(R_GEN_CONFIG, ata, select)));    
-    		*R_GEN_CONFIG = genconfig_shadow;
+		/* Allocating the ATA interface will grab almost all
+		 * pins in I/O groups a, b, c and d.  A consequence of
+		 * allocating the ATA interface is that the fixed
+		 * interfaces shared RAM, parallel port 0, parallel
+		 * port 1, parallel port W, SCSI-8 port 0, SCSI-8 port
+		 * 1, SCSI-W, serial port 2, serial port 3,
+		 * synchronous serial port 3 and USB port 2 and almost
+		 * all GPIO pins on port g cannot be used.
+		 */
+		if (cris_request_io_interface(if_ata, "ds1302/ATA")) {
+			printk(KERN_WARNING "ds1302: Failed to get IO interface\n");
+			return -1;
+		}
+
 #elif CONFIG_ETRAX_DS1302_RSTBIT == 0
-		
-		/* Set the direction of this bit to out. */		
-    		genconfig_shadow = ((genconfig_shadow &
-				     ~IO_MASK(R_GEN_CONFIG, g0dir)) | 
-				   (IO_STATE(R_GEN_CONFIG, g0dir, out)));    
-    		*R_GEN_CONFIG = genconfig_shadow;
+		if (cris_io_interface_allocate_pins(if_gpio_grp_a,
+						    'g',
+						    CONFIG_ETRAX_DS1302_RSTBIT,
+						    CONFIG_ETRAX_DS1302_RSTBIT)) {
+			printk(KERN_WARNING "ds1302: Failed to get IO interface\n");
+			return -1;
+		}
+
+		/* Set the direction of this bit to out. */
+		genconfig_shadow = ((genconfig_shadow &
+ 				     ~IO_MASK(R_GEN_CONFIG, g0dir)) |
+ 				   (IO_STATE(R_GEN_CONFIG, g0dir, out)));
+		*R_GEN_CONFIG = genconfig_shadow;
 #endif
 		if (!ds1302_probe()) {
 			printk(KERN_WARNING "%s: RTC not found.\n", ds1302_name);
-      			return -1;
+			return -1;
 		}
 #else
 		printk(KERN_WARNING "%s: RTC not found.\n", ds1302_name);
-    		return -1;
+		return -1;
 #endif
   	}
 	/* Initialise trickle charger */
diff --git a/arch/cris/arch-v10/drivers/eeprom.c b/arch/cris/arch-v10/drivers/eeprom.c
--- a/arch/cris/arch-v10/drivers/eeprom.c
+++ b/arch/cris/arch-v10/drivers/eeprom.c
@@ -20,6 +20,12 @@
 *!                                  in the spin-lock.
 *!
 *!  $Log: eeprom.c,v $
+*!  Revision 1.12  2005/06/19 17:06:46  starvik
+*!  Merge of Linux 2.6.12.
+*!
+*!  Revision 1.11  2005/01/26 07:14:46  starvik
+*!  Applied diff from kernel janitors (Nish Aravamudan).
+*!
 *!  Revision 1.10  2003/09/11 07:29:48  starvik
 *!  Merge of Linux 2.6.0-test5
 *!
@@ -94,6 +100,7 @@
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
+#include <linux/wait.h>
 #include <asm/uaccess.h>
 #include "i2c.h"
 
@@ -526,15 +533,10 @@ static ssize_t eeprom_read(struct file *
     return -EFAULT;
   }
   
-  while(eeprom.busy)
-  {
-    interruptible_sleep_on(&eeprom.wait_q);
+  wait_event_interruptible(eeprom.wait_q, !eeprom.busy);
+  if (signal_pending(current))
+    return -EINTR;
 
-    /* bail out if we get interrupted */
-    if (signal_pending(current))
-      return -EINTR;
-    
-  }
   eeprom.busy++;
 
   page = (unsigned char) (p >> 8);
@@ -604,13 +606,10 @@ static ssize_t eeprom_write(struct file 
     return -EFAULT;
   }
 
-  while(eeprom.busy)
-  {
-    interruptible_sleep_on(&eeprom.wait_q);
-    /* bail out if we get interrupted */
-    if (signal_pending(current))
-      return -EINTR;
-  }
+  wait_event_interruptible(eeprom.wait_q, !eeprom.busy);
+  /* bail out if we get interrupted */
+  if (signal_pending(current))
+    return -EINTR;
   eeprom.busy++;
   for(i = 0; (i < EEPROM_RETRIES) && (restart > 0); i++)
   {
diff --git a/arch/cris/arch-v10/drivers/gpio.c b/arch/cris/arch-v10/drivers/gpio.c
--- a/arch/cris/arch-v10/drivers/gpio.c
+++ b/arch/cris/arch-v10/drivers/gpio.c
@@ -1,4 +1,4 @@
-/* $Id: gpio.c,v 1.12 2004/08/24 07:19:59 starvik Exp $
+/* $Id: gpio.c,v 1.17 2005/06/19 17:06:46 starvik Exp $
  *
  * Etrax general port I/O device
  *
@@ -9,6 +9,18 @@
  *             Johan Adolfsson  (read/set directions, write, port G)
  *
  * $Log: gpio.c,v $
+ * Revision 1.17  2005/06/19 17:06:46  starvik
+ * Merge of Linux 2.6.12.
+ *
+ * Revision 1.16  2005/03/07 13:02:29  starvik
+ * Protect driver global states with spinlock
+ *
+ * Revision 1.15  2005/01/05 06:08:55  starvik
+ * No need to do local_irq_disable after local_irq_save.
+ *
+ * Revision 1.14  2004/12/13 12:21:52  starvik
+ * Added I/O and DMA allocators from Linux 2.4
+ *
  * Revision 1.12  2004/08/24 07:19:59  starvik
  * Whitespace cleanup
  *
@@ -142,6 +154,7 @@
 #include <asm/io.h>
 #include <asm/system.h>
 #include <asm/irq.h>
+#include <asm/arch/io_interface_mux.h>
 
 #define GPIO_MAJOR 120  /* experimental MAJOR number */
 
@@ -194,6 +207,8 @@ static struct gpio_private *alarmlist = 
 static int gpio_some_alarms = 0; /* Set if someone uses alarm */
 static unsigned long gpio_pa_irq_enabled_mask = 0;
 
+static DEFINE_SPINLOCK(gpio_lock); /* Protect directions etc */
+
 /* Port A and B use 8 bit access, but Port G is 32 bit */
 #define NUM_PORTS (GPIO_MINOR_B+1)
 
@@ -241,6 +256,9 @@ static volatile unsigned char *dir_shado
 	&port_pb_dir_shadow 
 };
 
+/* All bits in port g that can change dir. */
+static const unsigned long int changeable_dir_g_mask = 0x01FFFF01;
+
 /* Port G is 32 bit, handle it special, some bits are both inputs 
    and outputs at the same time, only some of the bits can change direction
    and some of them in groups of 8 bit. */
@@ -260,6 +278,7 @@ gpio_poll(struct file *file,
 	unsigned int mask = 0;
 	struct gpio_private *priv = (struct gpio_private *)file->private_data;
 	unsigned long data;
+	spin_lock(&gpio_lock);
 	poll_wait(file, &priv->alarm_wq, wait);
 	if (priv->minor == GPIO_MINOR_A) {
 		unsigned long flags;
@@ -270,10 +289,10 @@ gpio_poll(struct file *file,
 		 */
 		tmp = ~data & priv->highalarm & 0xFF;
 		tmp = (tmp << R_IRQ_MASK1_SET__pa0__BITNR);
-		save_flags(flags); cli();
+		local_irq_save(flags);
 		gpio_pa_irq_enabled_mask |= tmp;
 		*R_IRQ_MASK1_SET = tmp;
-		restore_flags(flags);
+		local_irq_restore(flags);
 
 	} else if (priv->minor == GPIO_MINOR_B)
 		data = *R_PORT_PB_DATA;
@@ -286,8 +305,11 @@ gpio_poll(struct file *file,
 	    (~data & priv->lowalarm)) {
 		mask = POLLIN|POLLRDNORM;
 	}
+
+	spin_unlock(&gpio_lock);
 	
 	DP(printk("gpio_poll ready: mask 0x%08X\n", mask));
+
 	return mask;
 }
 
@@ -296,6 +318,7 @@ int etrax_gpio_wake_up_check(void)
 	struct gpio_private *priv = alarmlist;
 	unsigned long data = 0;
         int ret = 0;
+	spin_lock(&gpio_lock);
 	while (priv) {
 		if (USE_PORTS(priv)) {
 			data = *priv->port;
@@ -310,6 +333,7 @@ int etrax_gpio_wake_up_check(void)
 		}
 		priv = priv->next;
 	}
+	spin_unlock(&gpio_lock);
         return ret;
 }
 
@@ -327,6 +351,7 @@ static irqreturn_t
 gpio_pa_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	unsigned long tmp;
+	spin_lock(&gpio_lock);
 	/* Find what PA interrupts are active */
 	tmp = (*R_IRQ_READ1);
 
@@ -337,6 +362,8 @@ gpio_pa_interrupt(int irq, void *dev_id,
 	*R_IRQ_MASK1_CLR = tmp;
 	gpio_pa_irq_enabled_mask &= ~tmp;
 
+	spin_unlock(&gpio_lock);
+
 	if (gpio_some_alarms) {
 		return IRQ_RETVAL(etrax_gpio_wake_up_check());
 	}
@@ -350,6 +377,9 @@ static ssize_t gpio_write(struct file * 
 	struct gpio_private *priv = (struct gpio_private *)file->private_data;
 	unsigned char data, clk_mask, data_mask, write_msb;
 	unsigned long flags;
+
+	spin_lock(&gpio_lock);
+
 	ssize_t retval = count;
 	if (priv->minor !=GPIO_MINOR_A && priv->minor != GPIO_MINOR_B) {
 		return -EFAULT;
@@ -372,7 +402,7 @@ static ssize_t gpio_write(struct file * 
 		data = *buf++;
 		if (priv->write_msb) {
 			for (i = 7; i >= 0;i--) {
-				local_irq_save(flags); local_irq_disable();
+				local_irq_save(flags);
 				*priv->port = *priv->shadow &= ~clk_mask;
 				if (data & 1<<i)
 					*priv->port = *priv->shadow |= data_mask;
@@ -384,7 +414,7 @@ static ssize_t gpio_write(struct file * 
 			}
 		} else {
 			for (i = 0; i <= 7;i++) {
-				local_irq_save(flags); local_irq_disable();
+				local_irq_save(flags);
 				*priv->port = *priv->shadow &= ~clk_mask;
 				if (data & 1<<i)
 					*priv->port = *priv->shadow |= data_mask;
@@ -396,6 +426,7 @@ static ssize_t gpio_write(struct file * 
 			}
 		}
 	}
+	spin_unlock(&gpio_lock);
 	return retval;
 }
 
@@ -452,9 +483,14 @@ gpio_open(struct inode *inode, struct fi
 static int
 gpio_release(struct inode *inode, struct file *filp)
 {
-	struct gpio_private *p = alarmlist;
-	struct gpio_private *todel = (struct gpio_private *)filp->private_data;
-	
+	struct gpio_private *p;
+	struct gpio_private *todel;
+
+	spin_lock(&gpio_lock);
+
+        p = alarmlist;
+        todel = (struct gpio_private *)filp->private_data;
+
 	/* unlink from alarmlist and free the private structure */
 
 	if (p == todel) {
@@ -476,7 +512,7 @@ gpio_release(struct inode *inode, struct
 		p = p->next;
 	}
 	gpio_some_alarms = 0;
-		
+	spin_unlock(&gpio_lock);
 	return 0;
 }
 
@@ -491,14 +527,14 @@ unsigned long inline setget_input(struct
 	 */
 	unsigned long flags;
 	if (USE_PORTS(priv)) {
-		local_irq_save(flags); local_irq_disable();
+		local_irq_save(flags);
 		*priv->dir = *priv->dir_shadow &= 
 		~((unsigned char)arg & priv->changeable_dir);
 		local_irq_restore(flags);
 		return ~(*priv->dir_shadow) & 0xFF; /* Only 8 bits */
 	} else if (priv->minor == GPIO_MINOR_G) {
 		/* We must fiddle with R_GEN_CONFIG to change dir */
-		save_flags(flags); cli();
+		local_irq_save(flags);
 		if (((arg & dir_g_in_bits) != arg) && 
 		    (arg & changeable_dir_g)) {
 			arg &= changeable_dir_g;
@@ -533,7 +569,7 @@ unsigned long inline setget_input(struct
 			/* Must be a >120 ns delay before writing this again */
 				
 		}
-		restore_flags(flags);
+		local_irq_restore(flags);
 		return dir_g_in_bits;
 	}
 	return 0;
@@ -543,14 +579,14 @@ unsigned long inline setget_output(struc
 {
 	unsigned long flags;
 	if (USE_PORTS(priv)) {
-		local_irq_save(flags); local_irq_disable();
+		local_irq_save(flags);
 		*priv->dir = *priv->dir_shadow |= 
 		  ((unsigned char)arg & priv->changeable_dir);
 		local_irq_restore(flags);
 		return *priv->dir_shadow;
 	} else if (priv->minor == GPIO_MINOR_G) {
 		/* We must fiddle with R_GEN_CONFIG to change dir */			
-		save_flags(flags); cli();
+		local_irq_save(flags);
 		if (((arg & dir_g_out_bits) != arg) &&
 		    (arg & changeable_dir_g)) {
 			/* Set bits in genconfig to set to output */
@@ -583,7 +619,7 @@ unsigned long inline setget_output(struc
 			*R_GEN_CONFIG = genconfig_shadow;
 			/* Must be a >120 ns delay before writing this again */
 		}
-		restore_flags(flags);
+		local_irq_restore(flags);
 		return dir_g_out_bits & 0x7FFFFFFF;
 	}
 	return 0;
@@ -598,22 +634,26 @@ gpio_ioctl(struct inode *inode, struct f
 {
 	unsigned long flags;
 	unsigned long val;
+        int ret = 0;
+
 	struct gpio_private *priv = (struct gpio_private *)file->private_data;
 	if (_IOC_TYPE(cmd) != ETRAXGPIO_IOCTYPE) {
 		return -EINVAL;
 	}
 
+	spin_lock(&gpio_lock);
+
 	switch (_IOC_NR(cmd)) {
 	case IO_READBITS: /* Use IO_READ_INBITS and IO_READ_OUTBITS instead */
 		// read the port
 		if (USE_PORTS(priv)) {
-			return *priv->port;
+			ret =  *priv->port;
 		} else if (priv->minor == GPIO_MINOR_G) {
-			return (*R_PORT_G_DATA) & 0x7FFFFFFF;
+			ret =  (*R_PORT_G_DATA) & 0x7FFFFFFF;
 		}
 		break;
 	case IO_SETBITS:
-		local_irq_save(flags); local_irq_disable();
+		local_irq_save(flags);
 		// set changeable bits with a 1 in arg
 		if (USE_PORTS(priv)) {
 			*priv->port = *priv->shadow |= 
@@ -624,7 +664,7 @@ gpio_ioctl(struct inode *inode, struct f
 		local_irq_restore(flags);
 		break;
 	case IO_CLRBITS:
-		local_irq_save(flags); local_irq_disable();
+		local_irq_save(flags);
 		// clear changeable bits with a 1 in arg
 		if (USE_PORTS(priv)) {
 			*priv->port = *priv->shadow &= 
@@ -666,33 +706,34 @@ gpio_ioctl(struct inode *inode, struct f
 	case IO_READDIR: /* Use IO_SETGET_INPUT/OUTPUT instead! */
 		/* Read direction 0=input 1=output */
 		if (USE_PORTS(priv)) {
-			return *priv->dir_shadow;
+			ret = *priv->dir_shadow;
 		} else if (priv->minor == GPIO_MINOR_G) {
 			/* Note: Some bits are both in and out,
 			 * Those that are dual is set here as well.
 			 */
-			return (dir_g_shadow | dir_g_out_bits) & 0x7FFFFFFF;
+			ret = (dir_g_shadow | dir_g_out_bits) & 0x7FFFFFFF;
 		}
+		break;
 	case IO_SETINPUT: /* Use IO_SETGET_INPUT instead! */
 		/* Set direction 0=unchanged 1=input, 
 		 * return mask with 1=input 
 		 */
-		return setget_input(priv, arg) & 0x7FFFFFFF;
+		ret = setget_input(priv, arg) & 0x7FFFFFFF;
 		break;
 	case IO_SETOUTPUT: /* Use IO_SETGET_OUTPUT instead! */
 		/* Set direction 0=unchanged 1=output, 
 		 * return mask with 1=output 
 		 */
-		return setget_output(priv, arg) & 0x7FFFFFFF;
-
+		ret =  setget_output(priv, arg) & 0x7FFFFFFF;
+		break;
 	case IO_SHUTDOWN:
 		SOFT_SHUTDOWN();
 		break;
 	case IO_GET_PWR_BT:
 #if defined (CONFIG_ETRAX_SOFT_SHUTDOWN)
-		return (*R_PORT_G_DATA & ( 1 << CONFIG_ETRAX_POWERBUTTON_BIT));
+		ret = (*R_PORT_G_DATA & ( 1 << CONFIG_ETRAX_POWERBUTTON_BIT));
 #else
-		return 0;
+		ret = 0;
 #endif
 		break;
 	case IO_CFG_WRITE_MODE:
@@ -709,7 +750,7 @@ gpio_ioctl(struct inode *inode, struct f
 		{
 			priv->clk_mask = 0;
 			priv->data_mask = 0;
-			return -EPERM;
+			ret = -EPERM;
 		}
 		break;
 	case IO_READ_INBITS: 
@@ -720,8 +761,7 @@ gpio_ioctl(struct inode *inode, struct f
 			val = *R_PORT_G_DATA;
 		}
 		if (copy_to_user((unsigned long*)arg, &val, sizeof(val)))
-			return -EFAULT;
-		return 0;
+			ret = -EFAULT;
 		break;
 	case IO_READ_OUTBITS:
 		 /* *arg is result of reading the output shadow */
@@ -731,36 +771,43 @@ gpio_ioctl(struct inode *inode, struct f
 			val = port_g_data_shadow;
 		}
 		if (copy_to_user((unsigned long*)arg, &val, sizeof(val)))
-			return -EFAULT;
+			ret = -EFAULT;
 		break;
 	case IO_SETGET_INPUT: 
 		/* bits set in *arg is set to input,
 		 * *arg updated with current input pins.
 		 */
 		if (copy_from_user(&val, (unsigned long*)arg, sizeof(val)))
-			return -EFAULT;
+		{
+			ret = -EFAULT;
+			break;
+		}
 		val = setget_input(priv, val);
 		if (copy_to_user((unsigned long*)arg, &val, sizeof(val)))
-			return -EFAULT;
+			ret = -EFAULT;
 		break;
 	case IO_SETGET_OUTPUT:
 		/* bits set in *arg is set to output,
 		 * *arg updated with current output pins.
 		 */
 		if (copy_from_user(&val, (unsigned long*)arg, sizeof(val)))
-			return -EFAULT;
+		{
+			ret = -EFAULT;
+			break;
+		}
 		val = setget_output(priv, val);
 		if (copy_to_user((unsigned long*)arg, &val, sizeof(val)))
-			return -EFAULT;
+			ret = -EFAULT;
 		break;
 	default:
 		if (priv->minor == GPIO_MINOR_LEDS)
-			return gpio_leds_ioctl(cmd, arg);
+			ret = gpio_leds_ioctl(cmd, arg);
 		else
-			return -EINVAL;
+			ret = -EINVAL;
 	} /* switch */
-	
-	return 0;
+
+	spin_unlock(&gpio_lock);
+	return ret;
 }
 
 static int
@@ -802,60 +849,20 @@ struct file_operations gpio_fops = {
 };
 
 
-static void __init gpio_init_port_g(void)
-{
-#define GROUPA (0x0000FF3F)
-#define GROUPB (1<<6 | 1<<7)
-#define GROUPC (1<<30 | 1<<31)
-#define GROUPD (0x3FFF0000)
-#define GROUPD_LOW (0x00FF0000)
-	unsigned long used_in_bits = 0;
-	unsigned long used_out_bits = 0;
-	if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, scsi0, select)){
-		used_in_bits  |= GROUPA | GROUPB | 0 | 0;
-		used_out_bits |= GROUPA | GROUPB | 0 | 0;
-	}
-	if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, ata, select)) {
-		used_in_bits  |= GROUPA | GROUPB | GROUPC | (GROUPD & ~(1<<25|1<<26));
-		used_out_bits |= GROUPA | GROUPB | GROUPC | GROUPD;
-	}
-
-	if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, par0, select)) {
-		used_in_bits  |= (GROUPA & ~(1<<0)) | 0 | 0 | 0;
-		used_out_bits |= (GROUPA & ~(1<<0)) | 0 | 0 | 0;
-	}
-	if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, ser2, select)) {
-		used_in_bits  |= 0 | GROUPB | 0 | 0;
-		used_out_bits |= 0 | GROUPB | 0 | 0;
-	}
-	/* mio same as shared RAM ? */
-	if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, mio, select)) {
-		used_in_bits  |= (GROUPA & ~(1<<0)) | 0 |0 |GROUPD_LOW;
-		used_out_bits |= (GROUPA & ~(1<<0|1<<1|1<<2)) | 0 |0 |GROUPD_LOW;
-	}
-	if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, scsi1, select)) {
-		used_in_bits  |= 0 | 0 | GROUPC | GROUPD;
-		used_out_bits |= 0 | 0 | GROUPC | GROUPD;
-	}
-	if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, scsi0w, select)) {
-		used_in_bits  |= GROUPA | GROUPB | 0 | (GROUPD_LOW | 1<<24);
-		used_out_bits |= GROUPA | GROUPB | 0 | (GROUPD_LOW | 1<<24 | 1<<25|1<<26);
-	}
-
-	if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, par1, select)) {
-		used_in_bits  |= 0 | 0 | 0 | (GROUPD & ~(1<<24));
-		used_out_bits |= 0 | 0 | 0 | (GROUPD & ~(1<<24));
-	}
-	if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, ser3, select)) {
-		used_in_bits  |= 0 | 0 | GROUPC | 0;
-		used_out_bits |= 0 | 0 | GROUPC | 0;
-	}
-	/* mio same as shared RAM-W? */
-	if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, mio_w, select)) {
-		used_in_bits  |= (GROUPA & ~(1<<0)) | 0 | 0 |GROUPD_LOW;
-		used_out_bits |= (GROUPA & ~(1<<0|1<<1|1<<2)) | 0 | 0 |GROUPD_LOW;
-	}
-	/* TODO: USB p2, parw, sync ser3? */
+void ioif_watcher(const unsigned int gpio_in_available,
+		  const unsigned int gpio_out_available,
+		  const unsigned char pa_available,
+		  const unsigned char pb_available)
+{
+	unsigned long int flags;
+	D(printk("gpio.c: ioif_watcher called\n"));
+	D(printk("gpio.c: G in: 0x%08x G out: 0x%08x PA: 0x%02x PB: 0x%02x\n",
+		 gpio_in_available, gpio_out_available, pa_available, pb_available));
+
+	spin_lock_irqsave(&gpio_lock, flags);
+
+	dir_g_in_bits = gpio_in_available;
+	dir_g_out_bits = gpio_out_available;
 
 	/* Initialise the dir_g_shadow etc. depending on genconfig */
 	/* 0=input 1=output */
@@ -868,10 +875,7 @@ static void __init gpio_init_port_g(void
 	if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, g24dir, out))
 		dir_g_shadow |= (1 << 24);
 
-	dir_g_in_bits = ~used_in_bits;
-	dir_g_out_bits = ~used_out_bits;
-
-	changeable_dir_g = 0x01FFFF01; /* all that can change dir */
+	changeable_dir_g = changeable_dir_g_mask;
 	changeable_dir_g &= dir_g_out_bits;
 	changeable_dir_g &= dir_g_in_bits;
 	/* Correct the bits that can change direction */ 
@@ -880,6 +884,7 @@ static void __init gpio_init_port_g(void
 	dir_g_in_bits &= ~changeable_dir_g;
 	dir_g_in_bits |= (~dir_g_shadow & changeable_dir_g);
 
+	spin_unlock_irqrestore(&gpio_lock, flags);
 
 	printk(KERN_INFO "GPIO port G: in_bits: 0x%08lX out_bits: 0x%08lX val: %08lX\n",
 	       dir_g_in_bits, dir_g_out_bits, (unsigned long)*R_PORT_G_DATA);
@@ -896,6 +901,7 @@ gpio_init(void)
 #if defined (CONFIG_ETRAX_CSP0_LEDS)
 	int i;
 #endif
+        printk("gpio init\n");
 
 	/* do the formalities */
 
@@ -919,8 +925,13 @@ gpio_init(void)
 #endif
 
 #endif
-	gpio_init_port_g();
-	printk(KERN_INFO "ETRAX 100LX GPIO driver v2.5, (c) 2001, 2002 Axis Communications AB\n");
+	/* The I/O interface allocation watcher will be called when
+	 * registering it. */
+	if (cris_io_interface_register_watcher(ioif_watcher)){
+		printk(KERN_WARNING "gpio_init: Failed to install IO if allocator watcher\n");
+	}
+
+	printk(KERN_INFO "ETRAX 100LX GPIO driver v2.5, (c) 2001, 2002, 2003, 2004 Axis Communications AB\n");
 	/* We call etrax_gpio_wake_up_check() from timer interrupt and
 	 * from cpu_idle() in kernel/process.c
 	 * The check in cpu_idle() reduces latency from ~15 ms to ~6 ms
diff --git a/arch/cris/arch-v10/drivers/i2c.c b/arch/cris/arch-v10/drivers/i2c.c
--- a/arch/cris/arch-v10/drivers/i2c.c
+++ b/arch/cris/arch-v10/drivers/i2c.c
@@ -12,6 +12,15 @@
 *!                                 don't use PB_I2C if DS1302 uses same bits,
 *!                                 use PB.
 *! $Log: i2c.c,v $
+*! Revision 1.13  2005/03/07 13:13:07  starvik
+*! Added spinlocks to protect states etc
+*!
+*! Revision 1.12  2005/01/05 06:11:22  starvik
+*! No need to do local_irq_disable after local_irq_save.
+*!
+*! Revision 1.11  2004/12/13 12:21:52  starvik
+*! Added I/O and DMA allocators from Linux 2.4
+*!
 *! Revision 1.9  2004/08/24 06:49:14  starvik
 *! Whitespace cleanup
 *!
@@ -75,7 +84,7 @@
 *! (C) Copyright 1999-2002 Axis Communications AB, LUND, SWEDEN
 *!
 *!***************************************************************************/
-/* $Id: i2c.c,v 1.9 2004/08/24 06:49:14 starvik Exp $ */
+/* $Id: i2c.c,v 1.13 2005/03/07 13:13:07 starvik Exp $ */
 
 /****************** INCLUDE FILES SECTION ***********************************/
 
@@ -95,6 +104,7 @@
 #include <asm/arch/svinto.h>
 #include <asm/io.h>
 #include <asm/delay.h>
+#include <asm/arch/io_interface_mux.h>
 
 #include "i2c.h"
 
@@ -184,6 +194,7 @@ static const char i2c_name[] = "i2c";
 
 #define i2c_delay(usecs) udelay(usecs)
 
+static DEFINE_SPINLOCK(i2c_lock); /* Protect directions etc */
 
 /****************** FUNCTION DEFINITION SECTION *************************/
 
@@ -488,13 +499,14 @@ i2c_writereg(unsigned char theSlave, uns
 	int error, cntr = 3;
 	unsigned long flags;
 
+	spin_lock(&i2c_lock);
+
 	do {
 		error = 0;
 		/*
 		 * we don't like to be interrupted
 		 */
 		local_irq_save(flags);
-		local_irq_disable();
 
 		i2c_start();
 		/*
@@ -538,6 +550,8 @@ i2c_writereg(unsigned char theSlave, uns
 
 	i2c_delay(CLOCK_LOW_TIME);
 
+	spin_unlock(&i2c_lock);
+
 	return -error;
 }
 
@@ -555,13 +569,14 @@ i2c_readreg(unsigned char theSlave, unsi
 	int error, cntr = 3;
 	unsigned long flags;
 
+	spin_lock(&i2c_lock);
+
 	do {
 		error = 0;
 		/*
 		 * we don't like to be interrupted
 		 */
 		local_irq_save(flags);
-		local_irq_disable();
 		/*
 		 * generate start condition
 		 */
@@ -620,6 +635,8 @@ i2c_readreg(unsigned char theSlave, unsi
 		
 	} while(error && cntr--);
 
+	spin_unlock(&i2c_lock);
+
 	return b;
 }
 
@@ -686,15 +703,26 @@ static struct file_operations i2c_fops =
 int __init
 i2c_init(void)
 {
+	static int res = 0;
+	static int first = 1;
+
+	if (!first) {
+		return res;
+	}
+
 	/* Setup and enable the Port B I2C interface */
 
 #ifndef CONFIG_ETRAX_I2C_USES_PB_NOT_PB_I2C
+	if ((res = cris_request_io_interface(if_i2c, "I2C"))) {
+		printk(KERN_CRIT "i2c_init: Failed to get IO interface\n");
+		return res;
+	}
+
 	*R_PORT_PB_I2C = port_pb_i2c_shadow |= 
 		IO_STATE(R_PORT_PB_I2C, i2c_en,  on) |
 		IO_FIELD(R_PORT_PB_I2C, i2c_d,   1)  |
 		IO_FIELD(R_PORT_PB_I2C, i2c_clk, 1)  |
 		IO_STATE(R_PORT_PB_I2C, i2c_oe_, enable);
-#endif
 
 	port_pb_dir_shadow &= ~IO_MASK(R_PORT_PB_DIR, dir0);
 	port_pb_dir_shadow &= ~IO_MASK(R_PORT_PB_DIR, dir1);
@@ -702,8 +730,26 @@ i2c_init(void)
 	*R_PORT_PB_DIR = (port_pb_dir_shadow |=
 			  IO_STATE(R_PORT_PB_DIR, dir0, input)  |
 			  IO_STATE(R_PORT_PB_DIR, dir1, output));
+#else
+        if ((res = cris_io_interface_allocate_pins(if_i2c,
+						   'b',
+                                                   CONFIG_ETRAX_I2C_DATA_PORT,
+						   CONFIG_ETRAX_I2C_DATA_PORT))) {
+		printk(KERN_WARNING "i2c_init: Failed to get IO pin for I2C data port\n");
+		return res;
+	} else if ((res = cris_io_interface_allocate_pins(if_i2c,
+							  'b',
+							  CONFIG_ETRAX_I2C_CLK_PORT,
+							  CONFIG_ETRAX_I2C_CLK_PORT))) {
+		cris_io_interface_free_pins(if_i2c,
+					    'b',
+					    CONFIG_ETRAX_I2C_DATA_PORT,
+					    CONFIG_ETRAX_I2C_DATA_PORT);
+		printk(KERN_WARNING "i2c_init: Failed to get IO pin for I2C clk port\n");
+	}
+#endif
 
-	return 0;
+	return res;
 }
 
 static int __init
@@ -711,14 +757,16 @@ i2c_register(void)
 {
 	int res;
 
-	i2c_init();
+	res = i2c_init();
+	if (res < 0)
+		return res;
   	res = register_chrdev(I2C_MAJOR, i2c_name, &i2c_fops);
 	if(res < 0) {
 		printk(KERN_ERR "i2c: couldn't get a major number.\n");
 		return res;
 	}
 
-	printk(KERN_INFO "I2C driver v2.2, (c) 1999-2001 Axis Communications AB\n");
+	printk(KERN_INFO "I2C driver v2.2, (c) 1999-2004 Axis Communications AB\n");
 	
 	return 0;
 }
diff --git a/arch/cris/arch-v10/drivers/pcf8563.c b/arch/cris/arch-v10/drivers/pcf8563.c
--- a/arch/cris/arch-v10/drivers/pcf8563.c
+++ b/arch/cris/arch-v10/drivers/pcf8563.c
@@ -15,7 +15,7 @@
  *
  * Author: Tobias Anderberg <tobiasa@axis.com>.
  *
- * $Id: pcf8563.c,v 1.8 2004/08/24 06:42:51 starvik Exp $
+ * $Id: pcf8563.c,v 1.11 2005/03/07 13:13:07 starvik Exp $
  */
 
 #include <linux/config.h>
@@ -40,7 +40,7 @@
 #define PCF8563_MAJOR 121		/* Local major number. */
 #define DEVICE_NAME "rtc"		/* Name which is registered in /proc/devices. */
 #define PCF8563_NAME "PCF8563"
-#define DRIVER_VERSION "$Revision: 1.8 $"
+#define DRIVER_VERSION "$Revision: 1.11 $"
 
 /* I2C bus slave registers. */
 #define RTC_I2C_READ		0xa3
@@ -49,6 +49,8 @@
 /* Two simple wrapper macros, saves a few keystrokes. */
 #define rtc_read(x) i2c_readreg(RTC_I2C_READ, x)
 #define rtc_write(x,y) i2c_writereg(RTC_I2C_WRITE, x, y)
+
+static DEFINE_SPINLOCK(rtc_lock); /* Protect state etc */
 	
 static const unsigned char days_in_month[] =
 	{ 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
@@ -125,9 +127,12 @@ get_rtc_time(struct rtc_time *tm)
 int __init
 pcf8563_init(void)
 {
-	unsigned char ret;
+	int ret;
 
-	i2c_init();
+	if ((ret = i2c_init())) {
+		printk(KERN_CRIT "pcf8563_init: failed to init i2c\n");
+		return ret;
+	}
 
 	/*
 	 * First of all we need to reset the chip. This is done by
@@ -200,12 +205,15 @@ pcf8563_ioctl(struct inode *inode, struc
 			{
 				struct rtc_time tm;
 
+				spin_lock(&rtc_lock);
 				get_rtc_time(&tm);
 
 				if (copy_to_user((struct rtc_time *) arg, &tm, sizeof(struct rtc_time))) {
+					spin_unlock(&rtc_lock);
 					return -EFAULT;
 				}
 
+				spin_unlock(&rtc_lock);
 				return 0;
 			}
 			break;
@@ -250,6 +258,8 @@ pcf8563_ioctl(struct inode *inode, struc
 				BIN_TO_BCD(tm.tm_min);
 				BIN_TO_BCD(tm.tm_sec);
 				tm.tm_mon |= century;
+
+				spin_lock(&rtc_lock);
 				
 				rtc_write(RTC_YEAR, tm.tm_year);
 				rtc_write(RTC_MONTH, tm.tm_mon);
@@ -258,6 +268,8 @@ pcf8563_ioctl(struct inode *inode, struc
 				rtc_write(RTC_MINUTES, tm.tm_min);
 				rtc_write(RTC_SECONDS, tm.tm_sec);
 
+				spin_unlock(&rtc_lock);
+
 				return 0;
 #endif /* !CONFIG_ETRAX_RTC_READONLY */
 			}
diff --git a/arch/cris/arch-v10/kernel/Makefile b/arch/cris/arch-v10/kernel/Makefile
--- a/arch/cris/arch-v10/kernel/Makefile
+++ b/arch/cris/arch-v10/kernel/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.5 2004/06/02 08:24:38 starvik Exp $
+# $Id: Makefile,v 1.6 2004/12/13 12:21:51 starvik Exp $
 #
 # Makefile for the linux kernel.
 #
@@ -7,7 +7,8 @@ extra-y	:= head.o
 
 
 obj-y   := entry.o traps.o shadows.o debugport.o irq.o \
-	   process.o setup.o signal.o traps.o time.o ptrace.o
+	   process.o setup.o signal.o traps.o time.o ptrace.o \
+	   dma.o io_interface_mux.o
 
 obj-$(CONFIG_ETRAX_KGDB) += kgdb.o
 obj-$(CONFIG_ETRAX_FAST_TIMER) += fasttimer.o
diff --git a/arch/cris/arch-v10/kernel/debugport.c b/arch/cris/arch-v10/kernel/debugport.c
--- a/arch/cris/arch-v10/kernel/debugport.c
+++ b/arch/cris/arch-v10/kernel/debugport.c
@@ -12,6 +12,31 @@
  *    init_etrax_debug()
  *
  * $Log: debugport.c,v $
+ * Revision 1.27  2005/06/10 10:34:14  starvik
+ * Real console support
+ *
+ * Revision 1.26  2005/06/07 07:06:07  starvik
+ * Added LF->CR translation to make ETRAX customers happy.
+ *
+ * Revision 1.25  2005/03/08 08:56:47  mikaelam
+ * Do only set index as port->index if port is defined, otherwise use the index from the command line
+ *
+ * Revision 1.24  2005/01/19 10:26:33  mikaelam
+ * Return the cris serial driver in console device driver callback function
+ *
+ * Revision 1.23  2005/01/14 10:12:17  starvik
+ * KGDB on separate port.
+ * Console fixes from 2.4.
+ *
+ * Revision 1.22  2005/01/11 16:06:13  starvik
+ * typo
+ *
+ * Revision 1.21  2005/01/11 13:49:14  starvik
+ * Added raw_printk to be used where we don't trust the console.
+ *
+ * Revision 1.20  2004/12/27 11:18:32  starvik
+ * Merge of Linux 2.6.10 (not functional yet).
+ *
  * Revision 1.19  2004/10/21 07:26:16  starvik
  * Made it possible to specify console settings on kernel command line.
  *
@@ -114,7 +139,11 @@ struct dbg_port ports[]=
     R_SERIAL0_BAUD,
     R_SERIAL0_TR_CTRL,
     R_SERIAL0_REC_CTRL,
-    IO_STATE(R_IRQ_MASK1_SET, ser0_data, set)
+    IO_STATE(R_IRQ_MASK1_SET, ser0_data, set),
+    0,
+    115200,
+    'N',
+    8
   },
   {
     1,
@@ -124,7 +153,11 @@ struct dbg_port ports[]=
     R_SERIAL1_BAUD,
     R_SERIAL1_TR_CTRL,
     R_SERIAL1_REC_CTRL,
-    IO_STATE(R_IRQ_MASK1_SET, ser1_data, set)
+    IO_STATE(R_IRQ_MASK1_SET, ser1_data, set),
+    0,
+    115200,
+    'N',
+    8
   },
   {
     2,
@@ -134,7 +167,11 @@ struct dbg_port ports[]=
     R_SERIAL2_BAUD,
     R_SERIAL2_TR_CTRL,
     R_SERIAL2_REC_CTRL,
-    IO_STATE(R_IRQ_MASK1_SET, ser2_data, set)
+    IO_STATE(R_IRQ_MASK1_SET, ser2_data, set),
+    0,
+    115200,
+    'N',
+    8
   },
   {
     3,
@@ -144,11 +181,15 @@ struct dbg_port ports[]=
     R_SERIAL3_BAUD,
     R_SERIAL3_TR_CTRL,
     R_SERIAL3_REC_CTRL,
-    IO_STATE(R_IRQ_MASK1_SET, ser3_data, set)
+    IO_STATE(R_IRQ_MASK1_SET, ser3_data, set),
+    0,
+    115200,
+    'N',
+    8
   }
 };
 
-static struct tty_driver *serial_driver;
+extern struct tty_driver *serial_driver;
 
 struct dbg_port* port =
 #if defined(CONFIG_ETRAX_DEBUG_PORT0)
@@ -162,37 +203,44 @@ struct dbg_port* port =
 #else
   NULL;
 #endif
-/* Used by serial.c to register a debug_write_function so that the normal
- * serial driver is used for kernel debug output
- */
-typedef int (*debugport_write_function)(int i, const char *buf, unsigned int len);
 
-debugport_write_function debug_write_function = NULL;
+static struct dbg_port* kgdb_port =
+#if defined(CONFIG_ETRAX_KGDB_PORT0)
+  &ports[0];
+#elif defined(CONFIG_ETRAX_KGDB_PORT1)
+  &ports[1];
+#elif defined(CONFIG_ETRAX_KGDB_PORT2)
+  &ports[2];
+#elif defined(CONFIG_ETRAX_KGDB_PORT3)
+  &ports[3];
+#else
+  NULL;
+#endif
 
 static void
-start_port(void)
+start_port(struct dbg_port* p)
 {
 	unsigned long rec_ctrl = 0;
 	unsigned long tr_ctrl = 0;
 
-	if (!port)
+	if (!p)
 		return;
 
-	if (port->started)
+	if (p->started)
 		return;
-	port->started = 1;
+	p->started = 1;
 
-	if (port->index == 0)
+	if (p->index == 0)
 	{
 		genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma6);
 		genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma6, unused);
 	}
-	else if (port->index == 1)
+	else if (p->index == 1)
 	{
 		genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma8);
 		genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma8, usb);
 	}
-	else if (port->index == 2)
+	else if (p->index == 2)
 	{
 		genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG, dma2);
 		genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma2, par0);
@@ -211,69 +259,69 @@ start_port(void)
 
 	*R_GEN_CONFIG = genconfig_shadow;
 
-	*port->xoff =
+	*p->xoff =
 		IO_STATE(R_SERIAL0_XOFF, tx_stop, enable) |
 		IO_STATE(R_SERIAL0_XOFF, auto_xoff, disable) |
 		IO_FIELD(R_SERIAL0_XOFF, xoff_char, 0);
 
-	switch (port->baudrate)
+	switch (p->baudrate)
 	{
 	case 0:
 	case 115200:
-		*port->baud =
+		*p->baud =
 		  IO_STATE(R_SERIAL0_BAUD, tr_baud, c115k2Hz) |
 		  IO_STATE(R_SERIAL0_BAUD, rec_baud, c115k2Hz);
 		break;
 	case 1200:
-		*port->baud =
+		*p->baud =
 		  IO_STATE(R_SERIAL0_BAUD, tr_baud, c1200Hz) |
 		  IO_STATE(R_SERIAL0_BAUD, rec_baud, c1200Hz);
 		break;
 	case 2400:
-		*port->baud =
+		*p->baud =
 		  IO_STATE(R_SERIAL0_BAUD, tr_baud, c2400Hz) |
 		  IO_STATE(R_SERIAL0_BAUD, rec_baud, c2400Hz);
 		break;
 	case 4800:
-		*port->baud =
+		*p->baud =
 		  IO_STATE(R_SERIAL0_BAUD, tr_baud, c4800Hz) |
 		  IO_STATE(R_SERIAL0_BAUD, rec_baud, c4800Hz);
 		break;
 	case 9600:
-		*port->baud =
+		*p->baud =
 		  IO_STATE(R_SERIAL0_BAUD, tr_baud, c9600Hz) |
 		  IO_STATE(R_SERIAL0_BAUD, rec_baud, c9600Hz);
 		  break;
 	case 19200:
-		*port->baud =
+		*p->baud =
 		  IO_STATE(R_SERIAL0_BAUD, tr_baud, c19k2Hz) |
 		  IO_STATE(R_SERIAL0_BAUD, rec_baud, c19k2Hz);
 		 break;
 	case 38400:
-		*port->baud =
+		*p->baud =
 		  IO_STATE(R_SERIAL0_BAUD, tr_baud, c38k4Hz) |
 		  IO_STATE(R_SERIAL0_BAUD, rec_baud, c38k4Hz);
 		break;
 	case 57600:
-		*port->baud =
+		*p->baud =
 		  IO_STATE(R_SERIAL0_BAUD, tr_baud, c57k6Hz) |
 		  IO_STATE(R_SERIAL0_BAUD, rec_baud, c57k6Hz);
 		break;
 	default:
-		*port->baud =
+		*p->baud =
 		  IO_STATE(R_SERIAL0_BAUD, tr_baud, c115k2Hz) |
 		  IO_STATE(R_SERIAL0_BAUD, rec_baud, c115k2Hz);
 		  break;
         }
 
-	if (port->parity == 'E') {
+	if (p->parity == 'E') {
 		rec_ctrl =
 		  IO_STATE(R_SERIAL0_REC_CTRL, rec_par, even) |
 		  IO_STATE(R_SERIAL0_REC_CTRL, rec_par_en, enable);
 		tr_ctrl =
 		  IO_STATE(R_SERIAL0_TR_CTRL, tr_par, even) |
 		  IO_STATE(R_SERIAL0_TR_CTRL, tr_par_en, enable);
-	} else if (port->parity == 'O') {
+	} else if (p->parity == 'O') {
 		rec_ctrl =
 		  IO_STATE(R_SERIAL0_REC_CTRL, rec_par, odd) |
 		  IO_STATE(R_SERIAL0_REC_CTRL, rec_par_en, enable);
@@ -288,8 +336,7 @@ start_port(void)
 		  IO_STATE(R_SERIAL0_TR_CTRL, tr_par, even) |
 		  IO_STATE(R_SERIAL0_TR_CTRL, tr_par_en, disable);
 	}
-
-	if (port->bits == 7)
+	if (p->bits == 7)
 	{
 		rec_ctrl |= IO_STATE(R_SERIAL0_REC_CTRL, rec_bitnr, rec_7bit);
 		tr_ctrl |= IO_STATE(R_SERIAL0_TR_CTRL, tr_bitnr, tr_7bit);
@@ -300,7 +347,7 @@ start_port(void)
 		tr_ctrl |= IO_STATE(R_SERIAL0_TR_CTRL, tr_bitnr, tr_8bit);
 	}
 
-	*port->rec_ctrl =
+	*p->rec_ctrl =
 		IO_STATE(R_SERIAL0_REC_CTRL, dma_err, stop) |
 		IO_STATE(R_SERIAL0_REC_CTRL, rec_enable, enable) |
 		IO_STATE(R_SERIAL0_REC_CTRL, rts_, active) |
@@ -308,7 +355,7 @@ start_port(void)
 		IO_STATE(R_SERIAL0_REC_CTRL, rec_stick_par, normal) |
 		rec_ctrl;
 
-	*port->tr_ctrl =
+	*p->tr_ctrl =
 		IO_FIELD(R_SERIAL0_TR_CTRL, txd, 0) |
 		IO_STATE(R_SERIAL0_TR_CTRL, tr_enable, enable) |
 		IO_STATE(R_SERIAL0_TR_CTRL, auto_cts, disabled) |
@@ -323,8 +370,18 @@ console_write_direct(struct console *co,
 	int i;
 	unsigned long flags;
 	local_irq_save(flags);
+
+        if (!port)
+		return;
+
 	/* Send data */
 	for (i = 0; i < len; i++) {
+		/* LF -> CRLF */
+		if (buf[i] == '\n') {
+			while (!(*port->read & IO_MASK(R_SERIAL0_READ, tr_ready)))
+			;
+			*port->write = '\r';
+		}
 		/* Wait until transmitter is ready and send.*/
 		while (!(*port->read & IO_MASK(R_SERIAL0_READ, tr_ready)))
 			;
@@ -333,6 +390,25 @@ console_write_direct(struct console *co,
 	local_irq_restore(flags);
 }
 
+int raw_printk(const char *fmt, ...)
+{
+	static char buf[1024];
+	int printed_len;
+	static int first = 1;
+	if (first) {
+		/* Force reinitialization of the port to get manual mode. */
+		port->started = 0;
+		start_port(port);
+		first = 0;
+	}
+	va_list args;
+	va_start(args, fmt);
+	printed_len = vsnprintf(buf, sizeof(buf), fmt, args);
+	va_end(args);
+	console_write_direct(NULL, buf, strlen(buf));
+	return printed_len;
+}
+
 static void
 console_write(struct console *co, const char *buf, unsigned int len)
 {
@@ -345,18 +421,7 @@ console_write(struct console *co, const 
 	return;
 #endif
 
-	start_port();
-
-#ifdef CONFIG_ETRAX_KGDB
-	/* kgdb needs to output debug info using the gdb protocol */
-	putDebugString(buf, len);
-	return;
-#endif
-
-	if (debug_write_function)
-		debug_write_function(co->index, buf, len);
-	else
-		console_write_direct(co, buf, len);
+        console_write_direct(co, buf, len);
 }
 
 /* legacy function */
@@ -374,8 +439,11 @@ getDebugChar(void)
 {
 	unsigned long readval;
 
+	if (!kgdb_port)
+		return 0;
+
 	do {
-		readval = *port->read;
+		readval = *kgdb_port->read;
 	} while (!(readval & IO_MASK(R_SERIAL0_READ, data_avail)));
 
 	return (readval & IO_MASK(R_SERIAL0_READ, data_in));
@@ -386,9 +454,12 @@ getDebugChar(void)
 void
 putDebugChar(int val)
 {
-	while (!(*port->read & IO_MASK(R_SERIAL0_READ, tr_ready)))
+	if (!kgdb_port)
+		return;
+
+	while (!(*kgdb_port->read & IO_MASK(R_SERIAL0_READ, tr_ready)))
 		;
-	*port->write = val;
+	*kgdb_port->write = val;
 }
 
 /* Enable irq for receiving chars on the debug port, used by kgdb */
@@ -396,19 +467,16 @@ putDebugChar(int val)
 void
 enableDebugIRQ(void)
 {
-	*R_IRQ_MASK1_SET = port->irq;
+	if (!kgdb_port)
+		return;
+
+	*R_IRQ_MASK1_SET = kgdb_port->irq;
 	/* use R_VECT_MASK directly, since we really bypass Linux normal
 	 * IRQ handling in kgdb anyway, we don't need to use enable_irq
 	 */
 	*R_VECT_MASK_SET = IO_STATE(R_VECT_MASK_SET, serial, set);
 
-	*port->rec_ctrl = IO_STATE(R_SERIAL0_REC_CTRL, rec_enable, enable);
-}
-
-static struct tty_driver*
-etrax_console_device(struct console* co, int *index)
-{
-	return serial_driver;
+	*kgdb_port->rec_ctrl = IO_STATE(R_SERIAL0_REC_CTRL, rec_enable, enable);
 }
 
 static int __init
@@ -428,11 +496,69 @@ console_setup(struct console *co, char *
 		if (*s) port->parity = *s++;
 		if (*s) port->bits   = *s++ - '0';
 		port->started = 0;
-		start_port();
+		start_port(0);
 	}
 	return 0;
 }
 
+/* This is a dummy serial device that throws away anything written to it.
+ * This is used when no debug output is wanted.
+ */
+static struct tty_driver dummy_driver;
+
+static int dummy_open(struct tty_struct *tty, struct file * filp)
+{
+	return 0;
+}
+
+static void dummy_close(struct tty_struct *tty, struct file * filp)
+{
+}
+
+static int dummy_write(struct tty_struct * tty,
+                       const unsigned char *buf, int count)
+{
+	return count;
+}
+
+static int
+dummy_write_room(struct tty_struct *tty)
+{
+	return 8192;
+}
+
+void __init
+init_dummy_console(void)
+{
+	memset(&dummy_driver, 0, sizeof(struct tty_driver));
+	dummy_driver.driver_name = "serial";
+	dummy_driver.name = "ttyS";
+	dummy_driver.major = TTY_MAJOR;
+	dummy_driver.minor_start = 68;
+	dummy_driver.num = 1;       /* etrax100 has 4 serial ports */
+	dummy_driver.type = TTY_DRIVER_TYPE_SERIAL;
+	dummy_driver.subtype = SERIAL_TYPE_NORMAL;
+	dummy_driver.init_termios = tty_std_termios;
+	dummy_driver.init_termios.c_cflag =
+		B115200 | CS8 | CREAD | HUPCL | CLOCAL; /* is normally B9600 default... */
+	dummy_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS;
+
+	dummy_driver.open = dummy_open;
+	dummy_driver.close = dummy_close;
+	dummy_driver.write = dummy_write;
+	dummy_driver.write_room = dummy_write_room;
+	if (tty_register_driver(&dummy_driver))
+		panic("Couldn't register dummy serial driver\n");
+}
+
+static struct tty_driver*
+etrax_console_device(struct console* co, int *index)
+{
+	if (port)
+		*index = port->index;
+        return port ? serial_driver : &dummy_driver;
+}
+
 static struct console sercons = {
 	name : "ttyS",
 	write: console_write,
@@ -504,28 +630,21 @@ init_etrax_debug(void)
 	static int first = 1;
 
 	if (!first) {
-		if (!port) {
-			register_console(&sercons0);
-			register_console(&sercons1);
-			register_console(&sercons2);
-			register_console(&sercons3);
-			unregister_console(&sercons);
-		}
+		unregister_console(&sercons);
+		register_console(&sercons0);
+		register_console(&sercons1);
+		register_console(&sercons2);
+		register_console(&sercons3);
+                init_dummy_console();
 		return 0;
 	}
-	first = 0;
-	if (port)
-		register_console(&sercons);
-	return 0;
-}
 
-int __init
-init_console(void)
-{
-	serial_driver = alloc_tty_driver(1);
-	if (!serial_driver)
-		return -ENOMEM;
+	first = 0;
+	register_console(&sercons);
+	start_port(port);
+#ifdef CONFIG_ETRAX_KGDB
+	start_port(kgdb_port);
+#endif
 	return 0;
 }
-
 __initcall(init_etrax_debug);
diff --git a/arch/cris/arch-v10/kernel/dma.c b/arch/cris/arch-v10/kernel/dma.c
new file mode 100644
--- /dev/null
+++ b/arch/cris/arch-v10/kernel/dma.c
@@ -0,0 +1,287 @@
+/* Wrapper for DMA channel allocator that updates DMA client muxing.
+ * Copyright 2004, Axis Communications AB
+ * $Id: dma.c,v 1.1 2004/12/13 12:21:51 starvik Exp $
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+
+#include <asm/dma.h>
+#include <asm/arch/svinto.h>
+
+/* Macro to access ETRAX 100 registers */
+#define SETS(var, reg, field, val) var = (var & ~IO_MASK_(reg##_, field##_)) | \
+					  IO_STATE_(reg##_, field##_, _##val)
+
+
+static char used_dma_channels[MAX_DMA_CHANNELS];
+static const char * used_dma_channels_users[MAX_DMA_CHANNELS];
+
+int cris_request_dma(unsigned int dmanr, const char * device_id,
+		     unsigned options, enum dma_owner owner)
+{
+	unsigned long flags;
+	unsigned long int gens;
+	int fail = -EINVAL;
+
+	if ((dmanr < 0) || (dmanr >= MAX_DMA_CHANNELS)) {
+		printk(KERN_CRIT "cris_request_dma: invalid DMA channel %u\n", dmanr);
+		return -EINVAL;
+	}
+
+	local_irq_save(flags);
+	if (used_dma_channels[dmanr]) {
+		local_irq_restore(flags);
+		if (options & DMA_VERBOSE_ON_ERROR) {
+			printk(KERN_CRIT "Failed to request DMA %i for %s, already allocated by %s\n", dmanr, device_id, used_dma_channels_users[dmanr]);
+		}
+		if (options & DMA_PANIC_ON_ERROR) {
+			panic("request_dma error!");
+		}
+		return -EBUSY;
+	}
+
+	gens = genconfig_shadow;
+
+	switch(owner)
+	{
+	case dma_eth:
+		if ((dmanr != NETWORK_TX_DMA_NBR) &&
+		    (dmanr != NETWORK_RX_DMA_NBR)) {
+			printk(KERN_CRIT "Invalid DMA channel for eth\n");
+			goto bail;
+		}
+		break;
+	case dma_ser0:
+		if (dmanr == SER0_TX_DMA_NBR) {
+			SETS(gens, R_GEN_CONFIG, dma6, serial0);
+		} else if (dmanr == SER0_RX_DMA_NBR) {
+			SETS(gens, R_GEN_CONFIG, dma7, serial0);
+		} else {
+			printk(KERN_CRIT "Invalid DMA channel for ser0\n");
+			goto bail;
+		}
+		break;
+	case dma_ser1:
+		if (dmanr == SER1_TX_DMA_NBR) {
+			SETS(gens, R_GEN_CONFIG, dma8, serial1);
+		} else if (dmanr == SER1_RX_DMA_NBR) {
+			SETS(gens, R_GEN_CONFIG, dma9, serial1);
+		} else {
+			printk(KERN_CRIT "Invalid DMA channel for ser1\n");
+			goto bail;
+		}
+		break;
+	case dma_ser2:
+		if (dmanr == SER2_TX_DMA_NBR) {
+			SETS(gens, R_GEN_CONFIG, dma2, serial2);
+		} else if (dmanr == SER2_RX_DMA_NBR) {
+			SETS(gens, R_GEN_CONFIG, dma3, serial2);
+		} else {
+			printk(KERN_CRIT "Invalid DMA channel for ser2\n");
+			goto bail;
+		}
+		break;
+	case dma_ser3:
+		if (dmanr == SER3_TX_DMA_NBR) {
+			SETS(gens, R_GEN_CONFIG, dma4, serial3);
+		} else if (dmanr == SER3_RX_DMA_NBR) {
+			SETS(gens, R_GEN_CONFIG, dma5, serial3);
+		} else {
+			printk(KERN_CRIT "Invalid DMA channel for ser3\n");
+			goto bail;
+		}
+		break;
+	case dma_ata:
+		if (dmanr == ATA_TX_DMA_NBR) {
+			SETS(gens, R_GEN_CONFIG, dma2, ata);
+		} else if (dmanr == ATA_RX_DMA_NBR) {
+			SETS(gens, R_GEN_CONFIG, dma3, ata);
+		} else {
+			printk(KERN_CRIT "Invalid DMA channel for ata\n");
+			goto bail;
+		}
+		break;
+	case dma_ext0:
+		if (dmanr == EXTDMA0_TX_DMA_NBR) {
+			SETS(gens, R_GEN_CONFIG, dma4, extdma0);
+		} else if (dmanr == EXTDMA0_RX_DMA_NBR) {
+			SETS(gens, R_GEN_CONFIG, dma5, extdma0);
+		} else {
+			printk(KERN_CRIT "Invalid DMA channel for ext0\n");
+			goto bail;
+		}
+		break;
+	case dma_ext1:
+		if (dmanr == EXTDMA1_TX_DMA_NBR) {
+			SETS(gens, R_GEN_CONFIG, dma6, extdma1);
+		} else if (dmanr == EXTDMA1_RX_DMA_NBR) {
+			SETS(gens, R_GEN_CONFIG, dma7, extdma1);
+		} else {
+			printk(KERN_CRIT "Invalid DMA channel for ext1\n");
+			goto bail;
+		}
+		break;
+	case dma_int6:
+		if (dmanr == MEM2MEM_RX_DMA_NBR) {
+			SETS(gens, R_GEN_CONFIG, dma7, intdma6);
+		} else {
+			printk(KERN_CRIT "Invalid DMA channel for int6\n");
+			goto bail;
+		}
+		break;
+	case dma_int7:
+		if (dmanr == MEM2MEM_TX_DMA_NBR) {
+			SETS(gens, R_GEN_CONFIG, dma6, intdma7);
+		} else {
+			printk(KERN_CRIT "Invalid DMA channel for int7\n");
+			goto bail;
+		}
+		break;
+	case dma_usb:
+		if (dmanr == USB_TX_DMA_NBR) {
+			SETS(gens, R_GEN_CONFIG, dma8, usb);
+		} else if (dmanr == USB_RX_DMA_NBR) {
+			SETS(gens, R_GEN_CONFIG, dma9, usb);
+		} else {
+			printk(KERN_CRIT "Invalid DMA channel for usb\n");
+			goto bail;
+		}
+		break;
+	case dma_scsi0:
+		if (dmanr == SCSI0_TX_DMA_NBR) {
+			SETS(gens, R_GEN_CONFIG, dma2, scsi0);
+		} else if (dmanr == SCSI0_RX_DMA_NBR) {
+			SETS(gens, R_GEN_CONFIG, dma3, scsi0);
+		} else {
+			printk(KERN_CRIT "Invalid DMA channel for scsi0\n");
+			goto bail;
+		}
+		break;
+	case dma_scsi1:
+		if (dmanr == SCSI1_TX_DMA_NBR) {
+			SETS(gens, R_GEN_CONFIG, dma4, scsi1);
+		} else if (dmanr == SCSI1_RX_DMA_NBR) {
+			SETS(gens, R_GEN_CONFIG, dma5, scsi1);
+		} else {
+			printk(KERN_CRIT "Invalid DMA channel for scsi1\n");
+			goto bail;
+		}
+		break;
+	case dma_par0:
+		if (dmanr == PAR0_TX_DMA_NBR) {
+			SETS(gens, R_GEN_CONFIG, dma2, par0);
+		} else if (dmanr == PAR0_RX_DMA_NBR) {
+			SETS(gens, R_GEN_CONFIG, dma3, par0);
+		} else {
+			printk(KERN_CRIT "Invalid DMA channel for par0\n");
+			goto bail;
+		}
+		break;
+	case dma_par1:
+		if (dmanr == PAR1_TX_DMA_NBR) {
+			SETS(gens, R_GEN_CONFIG, dma4, par1);
+		} else if (dmanr == PAR1_RX_DMA_NBR) {
+			SETS(gens, R_GEN_CONFIG, dma5, par1);
+		} else {
+			printk(KERN_CRIT "Invalid DMA channel for par1\n");
+			goto bail;
+		}
+		break;
+	default:
+		printk(KERN_CRIT "Invalid DMA owner.\n");
+		goto bail;
+	}
+
+	used_dma_channels[dmanr] = 1;
+	used_dma_channels_users[dmanr] = device_id;
+
+	{
+		volatile int i;
+		genconfig_shadow = gens;
+		*R_GEN_CONFIG = genconfig_shadow;
+		/* Wait 12 cycles before doing any DMA command */
+		for(i = 6; i > 0; i--)
+			nop();
+	}
+	fail = 0;
+ bail:
+	local_irq_restore(flags);
+	return fail;
+}
+
+void cris_free_dma(unsigned int dmanr, const char * device_id)
+{
+	unsigned long flags;
+	if ((dmanr < 0) || (dmanr >= MAX_DMA_CHANNELS)) {
+		printk(KERN_CRIT "cris_free_dma: invalid DMA channel %u\n", dmanr);
+		return;
+	}
+
+	local_irq_save(flags);
+	if (!used_dma_channels[dmanr]) {
+		printk(KERN_CRIT "cris_free_dma: DMA channel %u not allocated\n", dmanr);
+	} else if (device_id != used_dma_channels_users[dmanr]) {
+		printk(KERN_CRIT "cris_free_dma: DMA channel %u not allocated by device\n", dmanr);
+	} else {
+		switch(dmanr)
+		{
+		case 0:
+			*R_DMA_CH0_CMD = IO_STATE(R_DMA_CH0_CMD, cmd, reset);
+			while (IO_EXTRACT(R_DMA_CH0_CMD, cmd, *R_DMA_CH0_CMD) ==
+			       IO_STATE_VALUE(R_DMA_CH0_CMD, cmd, reset));
+			break;
+		case 1:
+			*R_DMA_CH1_CMD = IO_STATE(R_DMA_CH1_CMD, cmd, reset);
+			while (IO_EXTRACT(R_DMA_CH1_CMD, cmd, *R_DMA_CH1_CMD) ==
+			       IO_STATE_VALUE(R_DMA_CH1_CMD, cmd, reset));
+			break;
+		case 2:
+			*R_DMA_CH2_CMD = IO_STATE(R_DMA_CH2_CMD, cmd, reset);
+			while (IO_EXTRACT(R_DMA_CH2_CMD, cmd, *R_DMA_CH2_CMD) ==
+			       IO_STATE_VALUE(R_DMA_CH2_CMD, cmd, reset));
+			break;
+		case 3:
+			*R_DMA_CH3_CMD = IO_STATE(R_DMA_CH3_CMD, cmd, reset);
+			while (IO_EXTRACT(R_DMA_CH3_CMD, cmd, *R_DMA_CH3_CMD) ==
+			       IO_STATE_VALUE(R_DMA_CH3_CMD, cmd, reset));
+			break;
+		case 4:
+			*R_DMA_CH4_CMD = IO_STATE(R_DMA_CH4_CMD, cmd, reset);
+			while (IO_EXTRACT(R_DMA_CH4_CMD, cmd, *R_DMA_CH4_CMD) ==
+			       IO_STATE_VALUE(R_DMA_CH4_CMD, cmd, reset));
+			break;
+		case 5:
+			*R_DMA_CH5_CMD = IO_STATE(R_DMA_CH5_CMD, cmd, reset);
+			while (IO_EXTRACT(R_DMA_CH5_CMD, cmd, *R_DMA_CH5_CMD) ==
+			       IO_STATE_VALUE(R_DMA_CH5_CMD, cmd, reset));
+			break;
+		case 6:
+			*R_DMA_CH6_CMD = IO_STATE(R_DMA_CH6_CMD, cmd, reset);
+			while (IO_EXTRACT(R_DMA_CH6_CMD, cmd, *R_DMA_CH6_CMD) ==
+			       IO_STATE_VALUE(R_DMA_CH6_CMD, cmd, reset));
+			break;
+		case 7:
+			*R_DMA_CH7_CMD = IO_STATE(R_DMA_CH7_CMD, cmd, reset);
+			while (IO_EXTRACT(R_DMA_CH7_CMD, cmd, *R_DMA_CH7_CMD) ==
+			       IO_STATE_VALUE(R_DMA_CH7_CMD, cmd, reset));
+			break;
+		case 8:
+			*R_DMA_CH8_CMD = IO_STATE(R_DMA_CH8_CMD, cmd, reset);
+			while (IO_EXTRACT(R_DMA_CH8_CMD, cmd, *R_DMA_CH8_CMD) ==
+			       IO_STATE_VALUE(R_DMA_CH8_CMD, cmd, reset));
+			break;
+		case 9:
+			*R_DMA_CH9_CMD = IO_STATE(R_DMA_CH9_CMD, cmd, reset);
+			while (IO_EXTRACT(R_DMA_CH9_CMD, cmd, *R_DMA_CH9_CMD) ==
+			       IO_STATE_VALUE(R_DMA_CH9_CMD, cmd, reset));
+			break;
+		}
+		used_dma_channels[dmanr] = 0;
+	}
+	local_irq_restore(flags);
+}
+
+EXPORT_SYMBOL(cris_request_dma);
+EXPORT_SYMBOL(cris_free_dma);
diff --git a/arch/cris/arch-v10/kernel/entry.S b/arch/cris/arch-v10/kernel/entry.S
--- a/arch/cris/arch-v10/kernel/entry.S
+++ b/arch/cris/arch-v10/kernel/entry.S
@@ -1,4 +1,4 @@
-/* $Id: entry.S,v 1.23 2004/10/19 13:07:37 starvik Exp $
+/* $Id: entry.S,v 1.28 2005/06/20 05:06:30 starvik Exp $
  *
  *  linux/arch/cris/entry.S
  *
@@ -7,6 +7,22 @@
  *  Authors:	Bjorn Wesen (bjornw@axis.com)
  *
  *  $Log: entry.S,v $
+ *  Revision 1.28  2005/06/20 05:06:30  starvik
+ *  Remove unnecessary diff to kernel.org tree
+ *
+ *  Revision 1.27  2005/03/04 08:16:16  starvik
+ *  Merge of Linux 2.6.11.
+ *
+ *  Revision 1.26  2005/01/11 13:49:47  starvik
+ *  Added NMI handler.
+ *
+ *  Revision 1.25  2004/12/27 11:18:32  starvik
+ *  Merge of Linux 2.6.10 (not functional yet).
+ *
+ *  Revision 1.24  2004/12/22 10:41:23  starvik
+ *  Updates to make v10 compile with the latest SMP aware generic code (even
+ *  though v10 will never have SMP).
+ *
  *  Revision 1.23  2004/10/19 13:07:37  starvik
  *  Merge of Linux 2.6.9
  *
@@ -279,6 +295,7 @@
 #ifdef CONFIG_PREEMPT	
 	; Check if preemptive kernel scheduling should be done
 _resume_kernel:
+	di
 	; Load current task struct
 	movs.w	-8192, $r0	;  THREAD_SIZE = 8192
 	and.d	$sp, $r0
@@ -291,12 +308,7 @@ _need_resched:
 	bpl	_Rexit
 	nop
 	; Ok, lets's do some preemptive kernel scheduling
-	move.d	PREEMPT_ACTIVE, $r10
-	move.d	$r10, [$r0+TI_preempt_count] ; Mark as active
-	ei
-	jsr	schedule
-	clear.d	[$r0+TI_preempt_count] ;  Mark as inactive
-	di
+	jsr	preempt_schedule_irq
 	; Load new task struct
 	movs.w	-8192, $r0	;  THREAD_SIZE = 8192
 	and.d	$sp, $r0
@@ -590,15 +602,15 @@ mmu_bus_fault:
 	move.d	$r0, [$sp+16]
 1:	btstq	12, $r1		   ; Refill?
 	bpl	2f
-	lsrq	PMD_SHIFT, $r1     ; Get PMD index into PGD (bit 24-31)
-	move.d  [current_pgd], $r0 ; PGD for the current process
+	lsrq	24, $r1     ; Get PGD index (bit 24-31)
+	move.d  [per_cpu__current_pgd], $r0 ; PGD for the current process
 	move.d	[$r0+$r1.d], $r0   ; Get PMD
 	beq	2f
 	nop
 	and.w	PAGE_MASK, $r0	   ; Remove PMD flags
 	move.d  [R_MMU_CAUSE], $r1
 	lsrq	PAGE_SHIFT, $r1
-	and.d	0x7ff, $r1         ; Get PTE index into PMD (bit 13-24)
+	and.d	0x7ff, $r1         ; Get PTE index into PGD (bit 13-23)
 	move.d	[$r0+$r1.d], $r1   ; Get PTE
 	beq	2f
 	nop
@@ -656,11 +668,6 @@ hwbreakpoint:
 	nop
 	
 IRQ1_interrupt:
-
-#if defined(CONFIG_ETRAX_WATCHDOG) && !defined(CONFIG_SVINTO_SIM)
-;; If we receive a watchdog interrupt while it is not expected, then set
-;; up a canonical frame and dump register contents before dying.
-
 	;; this prologue MUST match the one in irq.h and the struct in ptregs.h!!!
 	move	$brp,[$sp=$sp-16]; instruction pointer and room for a fake SBFS frame
 	push	$srp
@@ -672,9 +679,16 @@ IRQ1_interrupt:
 	push	$r10		; push orig_r10
 	clear.d [$sp=$sp-4]	; frametype == 0, normal frame
 
-;; We don't check that we actually were bit by the watchdog as opposed to
-;; an external NMI, since there is currently no handler for external NMI.
-
+	move.d	[R_IRQ_MASK0_RD], $r1 ; External NMI or watchdog?
+	and.d   0x80000000, $r1
+	beq	wdog
+	move.d  $sp, $r10
+	jsr	handle_nmi
+	setf m			; Enable NMI again
+	retb			; Return from NMI
+	nop
+wdog:
+#if defined(CONFIG_ETRAX_WATCHDOG) && !defined(CONFIG_SVINTO_SIM)
 ;; Check if we're waiting for reset to happen, as signalled by
 ;; hard_reset_now setting cause_of_death to a magic value.  If so, just
 ;; get stuck until reset happens.
@@ -1118,6 +1132,10 @@ sys_call_table:	
 	.long sys_mq_getsetattr
 	.long sys_ni_syscall		/* reserved for kexec */
 	.long sys_waitid
+	.long sys_ni_syscall		/* 285 */ /* available */
+	.long sys_add_key
+	.long sys_request_key
+	.long sys_keyctl
 
         /*
          * NOTE!! This doesn't have to be exact - we just have
diff --git a/arch/cris/arch-v10/kernel/fasttimer.c b/arch/cris/arch-v10/kernel/fasttimer.c
--- a/arch/cris/arch-v10/kernel/fasttimer.c
+++ b/arch/cris/arch-v10/kernel/fasttimer.c
@@ -1,10 +1,20 @@
-/* $Id: fasttimer.c,v 1.6 2004/05/14 10:18:39 starvik Exp $
+/* $Id: fasttimer.c,v 1.9 2005/03/04 08:16:16 starvik Exp $
  * linux/arch/cris/kernel/fasttimer.c
  *
  * Fast timers for ETRAX100/ETRAX100LX
  * This may be useful in other OS than Linux so use 2 space indentation...
  *
  * $Log: fasttimer.c,v $
+ * Revision 1.9  2005/03/04 08:16:16  starvik
+ * Merge of Linux 2.6.11.
+ *
+ * Revision 1.8  2005/01/05 06:09:29  starvik
+ * cli()/sti() will be obsolete in 2.6.11.
+ *
+ * Revision 1.7  2005/01/03 13:35:46  starvik
+ * Removed obsolete stuff.
+ * Mark fast timer IRQ as not shared.
+ *
  * Revision 1.6  2004/05/14 10:18:39  starvik
  * Export fast_timer_list
  *
@@ -148,8 +158,7 @@ static int debug_log_cnt_wrapped = 0;
 #define DEBUG_LOG(string, value) \
 { \
   unsigned long log_flags; \
-  save_flags(log_flags); \
-  cli(); \
+  local_irq_save(log_flags); \
   debug_log_string[debug_log_cnt] = (string); \
   debug_log_value[debug_log_cnt] = (unsigned long)(value); \
   if (++debug_log_cnt >= DEBUG_LOG_MAX) \
@@ -157,7 +166,7 @@ static int debug_log_cnt_wrapped = 0;
     debug_log_cnt = debug_log_cnt % DEBUG_LOG_MAX; \
     debug_log_cnt_wrapped = 1; \
   } \
-  restore_flags(log_flags); \
+  local_irq_restore(log_flags); \
 }
 #else
 #define DEBUG_LOG(string, value)
@@ -320,8 +329,7 @@ void start_one_shot_timer(struct fast_ti
 
   D1(printk("sft %s %d us\n", name, delay_us));
 
-  save_flags(flags);
-  cli();
+  local_irq_save(flags);
 
   do_gettimeofday_fast(&t->tv_set);
   tmp = fast_timer_list;
@@ -395,7 +403,7 @@ void start_one_shot_timer(struct fast_ti
 
   D2(printk("start_one_shot_timer: %d us done\n", delay_us));
 
-  restore_flags(flags);
+  local_irq_restore(flags);
 } /* start_one_shot_timer */
 
 static inline int fast_timer_pending (const struct fast_timer * t)
@@ -425,11 +433,10 @@ int del_fast_timer(struct fast_timer * t
   unsigned long flags;
   int ret;
   
-  save_flags(flags);
-  cli();
+  local_irq_save(flags);
   ret = detach_fast_timer(t);
   t->next = t->prev = NULL;
-  restore_flags(flags);
+  local_irq_restore(flags);
   return ret;
 } /* del_fast_timer */
 
@@ -444,8 +451,7 @@ timer1_handler(int irq, void *dev_id, st
   struct fast_timer *t;
   unsigned long flags;
 
-  save_flags(flags);
-  cli();
+  local_irq_save(flags);
 
   /* Clear timer1 irq */
   *R_IRQ_MASK0_CLR = IO_STATE(R_IRQ_MASK0_CLR, timer1, clr);
@@ -462,7 +468,7 @@ timer1_handler(int irq, void *dev_id, st
   fast_timer_running = 0;
   fast_timer_ints++;
 
-  restore_flags(flags);
+  local_irq_restore(flags);
 
   t = fast_timer_list;
   while (t)
@@ -482,8 +488,7 @@ timer1_handler(int irq, void *dev_id, st
       fast_timers_expired++;
 
       /* Remove this timer before call, since it may reuse the timer */
-      save_flags(flags);
-      cli();
+      local_irq_save(flags);
       if (t->prev)
       {
         t->prev->next = t->next;
@@ -498,7 +503,7 @@ timer1_handler(int irq, void *dev_id, st
       }
       t->prev = NULL;
       t->next = NULL;
-      restore_flags(flags);
+      local_irq_restore(flags);
 
       if (t->function != NULL)
       {
@@ -515,8 +520,7 @@ timer1_handler(int irq, void *dev_id, st
       D1(printk(".\n"));
     }
 
-    save_flags(flags);
-    cli();
+    local_irq_save(flags);
     if ((t = fast_timer_list) != NULL)
     {
       /* Start next timer.. */
@@ -535,7 +539,7 @@ timer1_handler(int irq, void *dev_id, st
 #endif
           start_timer1(us);
         }
-        restore_flags(flags);
+        local_irq_restore(flags);
         break;
       }
       else
@@ -546,7 +550,7 @@ timer1_handler(int irq, void *dev_id, st
         D1(printk("e! %d\n", us));
       }
     }
-    restore_flags(flags);
+    local_irq_restore(flags);
   }
 
   if (!t)
@@ -748,13 +752,12 @@ static int proc_fasttimer_read(char *buf
 #endif
 
     used += sprintf(bigbuf + used, "Active timers:\n");
-    save_flags(flags);
-    cli();
+    local_irq_save(flags);
     t = fast_timer_list;
     while (t != NULL && (used+100 < BIG_BUF_SIZE))
     {
       nextt = t->next;
-      restore_flags(flags);
+      local_irq_restore(flags);
       used += sprintf(bigbuf + used, "%-14s s: %6lu.%06lu e: %6lu.%06lu "
                       "d: %6li us data: 0x%08lX"
 /*                      " func: 0x%08lX" */
@@ -768,14 +771,14 @@ static int proc_fasttimer_read(char *buf
                       t->data
 /*                      , t->function */
                       );
-      cli();
+      local_irq_disable();
       if (t->next != nextt)
       {
         printk(KERN_WARNING "timer removed!\n");
       }
       t = nextt;
     }
-    restore_flags(flags);
+    local_irq_restore(flags);
   }
 
   if (used - offset < len)
@@ -963,7 +966,7 @@ void fast_timer_init(void)
    if ((fasttimer_proc_entry = create_proc_entry( "fasttimer", 0, 0 )))
      fasttimer_proc_entry->read_proc = proc_fasttimer_read;
 #endif /* PROC_FS */
-    if(request_irq(TIMER1_IRQ_NBR, timer1_handler, SA_SHIRQ,
+    if(request_irq(TIMER1_IRQ_NBR, timer1_handler, 0,
                    "fast timer int", NULL))
     {
       printk("err: timer1 irq\n");
diff --git a/arch/cris/arch-v10/kernel/head.S b/arch/cris/arch-v10/kernel/head.S
--- a/arch/cris/arch-v10/kernel/head.S
+++ b/arch/cris/arch-v10/kernel/head.S
@@ -1,4 +1,4 @@
-/* $Id: head.S,v 1.7 2004/05/14 07:58:01 starvik Exp $
+/* $Id: head.S,v 1.10 2005/06/20 05:12:54 starvik Exp $
  * 
  * Head of the kernel - alter with care
  *
@@ -7,6 +7,16 @@
  * Authors:	Bjorn Wesen (bjornw@axis.com)
  * 
  * $Log: head.S,v $
+ * Revision 1.10  2005/06/20 05:12:54  starvik
+ * Remove unnecessary diff to kernel.org tree
+ *
+ * Revision 1.9  2004/12/13 12:21:51  starvik
+ * Added I/O and DMA allocators from Linux 2.4
+ *
+ * Revision 1.8  2004/11/22 11:41:14  starvik
+ * Kernel command line may be supplied to kernel. Not used by Axis but may
+ * be used by customers.
+ *
  * Revision 1.7  2004/05/14 07:58:01  starvik
  * Merge of changes from 2.4
  *
@@ -181,6 +191,7 @@
 
 #define CRAMFS_MAGIC 0x28cd3d45
 #define RAM_INIT_MAGIC 0x56902387
+#define COMMAND_LINE_MAGIC 0x87109563
 
 #define START_ETHERNET_CLOCK IO_STATE(R_NETWORK_GEN_CONFIG, enable, on) |\
                              IO_STATE(R_NETWORK_GEN_CONFIG, phy, mii_clk)
@@ -490,6 +501,23 @@ _no_romfs_in_flash:
 	
 _start_it:
 
+	;; Check if kernel command line is supplied
+	cmp.d	COMMAND_LINE_MAGIC, $r10
+	bne	no_command_line
+	nop
+
+	move.d	256, $r13
+	move.d  cris_command_line, $r10
+	or.d	0x80000000, $r11 ; Make it virtual
+1:
+	move.b  [$r11+], $r12
+	move.b  $r12, [$r10+]
+	subq	1, $r13
+	bne	1b
+	nop
+
+no_command_line:
+
 	;; the kernel stack is overlayed with the task structure for each
 	;; task. thus the initial kernel stack is in the same page as the
 	;; init_task (but starts in the top of the page, size 8192)
@@ -567,76 +595,32 @@ _start_it:
 	;; Etrax product HW genconfig setup
 
 	moveq	0,$r0
-#if (!defined(CONFIG_ETRAX_KGDB) || !defined(CONFIG_ETRAX_DEBUG_PORT0)) \
-	&& !defined(CONFIG_DMA_MEMCPY)
-	; DMA channels 6 and 7 to ser0, kgdb doesnt want DMA
-	or.d	  IO_STATE (R_GEN_CONFIG, dma7, serial0)	\
-		| IO_STATE (R_GEN_CONFIG, dma6, serial0),$r0
-#endif
-#if !defined(CONFIG_ETRAX_KGDB) || !defined(CONFIG_ETRAX_DEBUG_PORT1)
-	; DMA channels 8 and 9 to ser1, kgdb doesnt want DMA
-	or.d	  IO_STATE (R_GEN_CONFIG, dma9, serial1)	\
-		| IO_STATE (R_GEN_CONFIG, dma8, serial1),$r0
-#endif	
-#ifdef CONFIG_DMA_MEMCPY
-	; 6/7 memory-memory DMA
-	or.d	  IO_STATE (R_GEN_CONFIG, dma7, intdma6)	\
-		| IO_STATE (R_GEN_CONFIG, dma6, intdma7),$r0
-#endif
-#ifdef CONFIG_ETRAX_SERIAL_PORT2
-	; Enable serial port 2
-	or.w	IO_STATE (R_GEN_CONFIG, ser2, select),$r0
-#if !defined(CONFIG_ETRAX_KGDB) || !defined(CONFIG_ETRAX_DEBUG_PORT2)
-	; DMA channels 2 and 3 to ser2, kgdb doesnt want DMA
-	or.d	  IO_STATE (R_GEN_CONFIG, dma3, serial2)	\
-		| IO_STATE (R_GEN_CONFIG, dma2, serial2),$r0
-#endif
-#endif
-#if defined(CONFIG_ETRAX_SERIAL_PORT3) || defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT1)
-	; Enable serial port 3
-	or.w	IO_STATE (R_GEN_CONFIG, ser3, select),$r0
-#if !defined(CONFIG_ETRAX_KGDB) || !defined(CONFIG_ETRAX_DEBUG_PORT3)
-	; DMA channels 4 and 5 to ser3, kgdb doesnt want DMA
-	or.d	  IO_STATE (R_GEN_CONFIG, dma5, serial3)	\
-		| IO_STATE (R_GEN_CONFIG, dma4, serial3),$r0
-#endif
-#endif
-#if defined(CONFIG_ETRAX_PARALLEL_PORT0) || defined(CONFIG_ETRAX_ETHERNET_LPSLAVE)
-	; parport 0 enabled using DMA 2/3
-	or.w	IO_STATE (R_GEN_CONFIG, par0, select),$r0
-#endif
-#if defined(CONFIG_ETRAX_PARALLEL_PORT1) || defined(CONFIG_ETRAX_ETHERNET_LPSLAVE)
-	; parport 1 enabled using DMA 4/5
-	or.w	IO_STATE (R_GEN_CONFIG, par1, select),$r0
-#endif
-#ifdef CONFIG_ETRAX_IDE
-	; DMA channels 2 and 3 to ATA, ATA enabled
-	or.d	  IO_STATE (R_GEN_CONFIG, dma3, ata)	\
-		| IO_STATE (R_GEN_CONFIG, dma2, ata)	\
-		| IO_STATE (R_GEN_CONFIG, ata, select),$r0
-#endif
-	
-#ifdef CONFIG_ETRAX_USB_HOST_PORT1
-	; Set the USB port 1 enable bit
-	or.d	IO_STATE (R_GEN_CONFIG, usb1, select),$r0
-#endif
-#ifdef CONFIG_ETRAX_USB_HOST_PORT2
-	; Set the USB port 2 enable bit
-	or.d	IO_STATE (R_GEN_CONFIG, usb2, select),$r0
-#endif
-#ifdef CONFIG_ETRAX_USB_HOST
-	; Connect DMA channels 8 and 9 to USB
-	and.d	(~(IO_MASK (R_GEN_CONFIG, dma9)		\
-		   | IO_MASK (R_GEN_CONFIG, dma8)))	\
-		| IO_STATE (R_GEN_CONFIG, dma9, usb)	\
-		| IO_STATE (R_GEN_CONFIG, dma8, usb),$r0
-#endif
-	
-#ifdef CONFIG_JULIETTE
-	; DMA channels 4 and 5 to EXTDMA0, for Juliette
-	or.d	  IO_STATE (R_GEN_CONFIG, dma5, extdma0)	\
-		| IO_STATE (R_GEN_CONFIG, dma4, extdma0),$r0
-#endif
+
+	;; Init interfaces (disable them).
+	or.d	  IO_STATE (R_GEN_CONFIG, scsi0, disable) \
+		| IO_STATE (R_GEN_CONFIG, ata, disable) \
+		| IO_STATE (R_GEN_CONFIG, par0, disable) \
+		| IO_STATE (R_GEN_CONFIG, ser2, disable) \
+		| IO_STATE (R_GEN_CONFIG, mio, disable) \
+		| IO_STATE (R_GEN_CONFIG, scsi1, disable) \
+		| IO_STATE (R_GEN_CONFIG, scsi0w, disable) \
+		| IO_STATE (R_GEN_CONFIG, par1, disable) \
+		| IO_STATE (R_GEN_CONFIG, ser3, disable) \
+		| IO_STATE (R_GEN_CONFIG, mio_w, disable) \
+		| IO_STATE (R_GEN_CONFIG, usb1, disable) \
+		| IO_STATE (R_GEN_CONFIG, usb2, disable) \
+		| IO_STATE (R_GEN_CONFIG, par_w, disable),$r0
+
+	;; Init DMA channel muxing (set to unused clients).
+	or.d	  IO_STATE (R_GEN_CONFIG, dma2, ata)	\
+		| IO_STATE (R_GEN_CONFIG, dma3, ata) \
+		| IO_STATE (R_GEN_CONFIG, dma4, scsi1) \
+		| IO_STATE (R_GEN_CONFIG, dma5, scsi1) \
+		| IO_STATE (R_GEN_CONFIG, dma6, unused) \
+		| IO_STATE (R_GEN_CONFIG, dma7, unused) \
+		| IO_STATE (R_GEN_CONFIG, dma8, usb) \
+		| IO_STATE (R_GEN_CONFIG, dma9, usb),$r0
+
 
 #if defined(CONFIG_ETRAX_DEF_R_PORT_G0_DIR_OUT)
         or.d      IO_STATE (R_GEN_CONFIG, g0dir, out),$r0
diff --git a/arch/cris/arch-v10/kernel/io_interface_mux.c b/arch/cris/arch-v10/kernel/io_interface_mux.c
new file mode 100644
--- /dev/null
+++ b/arch/cris/arch-v10/kernel/io_interface_mux.c
@@ -0,0 +1,879 @@
+/* IO interface mux allocator for ETRAX100LX.
+ * Copyright 2004, Axis Communications AB
+ * $Id: io_interface_mux.c,v 1.2 2004/12/21 12:08:38 starvik Exp $
+ */
+
+
+/* C.f. ETRAX100LX Designer's Reference 20.9 */
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include <asm/arch/svinto.h>
+#include <asm/io.h>
+#include <asm/arch/io_interface_mux.h>
+
+
+#define DBG(s)
+
+/* Macro to access ETRAX 100 registers */
+#define SETS(var, reg, field, val) var = (var & ~IO_MASK_(reg##_, field##_)) | \
+					  IO_STATE_(reg##_, field##_, _##val)
+
+enum io_if_group {
+	group_a = (1<<0),
+	group_b = (1<<1),
+	group_c = (1<<2),
+	group_d = (1<<3),
+	group_e = (1<<4),
+	group_f = (1<<5)
+};
+
+struct watcher
+{
+	void (*notify)(const unsigned int gpio_in_available,
+		       const unsigned int gpio_out_available,
+		       const unsigned char pa_available,
+		       const unsigned char pb_available);
+	struct watcher *next;
+};
+
+
+struct if_group
+{
+	enum io_if_group        group;
+	unsigned char           used;
+	enum cris_io_interface  owner;
+};
+
+
+struct interface
+{
+	enum cris_io_interface   ioif;
+	unsigned char            groups;
+	unsigned char            used;
+	char                    *owner;
+	unsigned int             gpio_g_in;
+	unsigned int             gpio_g_out;
+	unsigned char            gpio_b;
+};
+
+static struct if_group if_groups[6] = {
+	{
+		.group = group_a,
+		.used = 0,
+	},
+	{
+		.group = group_b,
+		.used = 0,
+	},
+	{
+		.group = group_c,
+		.used = 0,
+	},
+	{
+		.group = group_d,
+		.used = 0,
+	},
+	{
+		.group = group_e,
+		.used = 0,
+	},
+	{
+		.group = group_f,
+		.used = 0,
+	}
+};
+
+/* The order in the array must match the order of enum
+ * cris_io_interface in io_interface_mux.h */
+static struct interface interfaces[] = {
+	/* Begin Non-multiplexed interfaces */
+	{
+		.ioif = if_eth,
+		.groups = 0,
+		.gpio_g_in = 0,
+		.gpio_g_out = 0,
+		.gpio_b = 0
+	},
+	{
+		.ioif = if_serial_0,
+		.groups = 0,
+		.gpio_g_in = 0,
+		.gpio_g_out = 0,
+		.gpio_b = 0
+	},
+	/* End Non-multiplexed interfaces */
+	{
+		.ioif = if_serial_1,
+		.groups = group_e,
+		.gpio_g_in =  0x00000000,
+		.gpio_g_out = 0x00000000,
+		.gpio_b = 0x00
+	},
+	{
+		.ioif = if_serial_2,
+		.groups = group_b,
+		.gpio_g_in =  0x000000c0,
+		.gpio_g_out = 0x000000c0,
+		.gpio_b = 0x00
+	},
+	{
+		.ioif = if_serial_3,
+		.groups = group_c,
+		.gpio_g_in =  0xc0000000,
+		.gpio_g_out = 0xc0000000,
+		.gpio_b = 0x00
+	},
+	{
+		.ioif = if_sync_serial_1,
+		.groups = group_e | group_f, /* if_sync_serial_1 and if_sync_serial_3
+					       can be used simultaneously */
+		.gpio_g_in =  0x00000000,
+		.gpio_g_out = 0x00000000,
+		.gpio_b = 0x10
+	},
+	{
+		.ioif = if_sync_serial_3,
+		.groups = group_c | group_f,
+		.gpio_g_in =  0xc0000000,
+		.gpio_g_out = 0xc0000000,
+		.gpio_b = 0x80
+	},
+	{
+		.ioif = if_shared_ram,
+		.groups = group_a,
+		.gpio_g_in =  0x0000ff3e,
+		.gpio_g_out = 0x0000ff38,
+		.gpio_b = 0x00
+	},
+	{
+		.ioif = if_shared_ram_w,
+		.groups = group_a | group_d,
+		.gpio_g_in =  0x00ffff3e,
+		.gpio_g_out = 0x00ffff38,
+		.gpio_b = 0x00
+	},
+	{
+		.ioif = if_par_0,
+		.groups = group_a,
+		.gpio_g_in =  0x0000ff3e,
+		.gpio_g_out = 0x0000ff3e,
+		.gpio_b = 0x00
+	},
+	{
+		.ioif = if_par_1,
+		.groups = group_d,
+		.gpio_g_in =  0x3eff0000,
+		.gpio_g_out = 0x3eff0000,
+		.gpio_b = 0x00
+	},
+	{
+		.ioif = if_par_w,
+		.groups = group_a | group_d,
+		.gpio_g_in =  0x00ffff3e,
+		.gpio_g_out = 0x00ffff3e,
+		.gpio_b = 0x00
+	},
+	{
+		.ioif = if_scsi8_0,
+		.groups = group_a | group_b | group_f, /* if_scsi8_0 and if_scsi8_1
+							  can be used simultaneously */
+		.gpio_g_in =  0x0000ffff,
+		.gpio_g_out = 0x0000ffff,
+		.gpio_b = 0x10
+	},
+	{
+		.ioif = if_scsi8_1,
+		.groups = group_c | group_d | group_f, /* if_scsi8_0 and if_scsi8_1
+							  can be used simultaneously */
+		.gpio_g_in =  0xffff0000,
+		.gpio_g_out = 0xffff0000,
+		.gpio_b = 0x80
+	},
+	{
+		.ioif = if_scsi_w,
+		.groups = group_a | group_b | group_d | group_f,
+		.gpio_g_in =  0x01ffffff,
+		.gpio_g_out = 0x07ffffff,
+		.gpio_b = 0x80
+	},
+	{
+		.ioif = if_ata,
+		.groups = group_a | group_b | group_c | group_d,
+		.gpio_g_in =  0xf9ffffff,
+		.gpio_g_out = 0xffffffff,
+		.gpio_b = 0x80
+	},
+	{
+		.ioif = if_csp,
+		.groups = group_f, /* if_csp and if_i2c can be used simultaneously */
+		.gpio_g_in =  0x00000000,
+		.gpio_g_out = 0x00000000,
+		.gpio_b = 0xfc
+	},
+	{
+		.ioif = if_i2c,
+		.groups = group_f, /* if_csp and if_i2c can be used simultaneously */
+		.gpio_g_in =  0x00000000,
+		.gpio_g_out = 0x00000000,
+		.gpio_b = 0x03
+	},
+	{
+		.ioif = if_usb_1,
+		.groups = group_e | group_f,
+		.gpio_g_in =  0x00000000,
+		.gpio_g_out = 0x00000000,
+		.gpio_b = 0x2c
+	},
+	{
+		.ioif = if_usb_2,
+		.groups = group_d,
+		.gpio_g_in =  0x0e000000,
+		.gpio_g_out = 0x3c000000,
+		.gpio_b = 0x00
+	},
+	/* GPIO pins */
+	{
+		.ioif = if_gpio_grp_a,
+		.groups = group_a,
+		.gpio_g_in =  0x0000ff3f,
+		.gpio_g_out = 0x0000ff3f,
+		.gpio_b = 0x00
+	},
+	{
+		.ioif = if_gpio_grp_b,
+		.groups = group_b,
+		.gpio_g_in =  0x000000c0,
+		.gpio_g_out = 0x000000c0,
+		.gpio_b = 0x00
+	},
+	{
+		.ioif = if_gpio_grp_c,
+		.groups = group_c,
+		.gpio_g_in =  0xc0000000,
+		.gpio_g_out = 0xc0000000,
+		.gpio_b = 0x00
+	},
+	{
+		.ioif = if_gpio_grp_d,
+		.groups = group_d,
+		.gpio_g_in =  0x3fff0000,
+		.gpio_g_out = 0x3fff0000,
+		.gpio_b = 0x00
+	},
+	{
+		.ioif = if_gpio_grp_e,
+		.groups = group_e,
+		.gpio_g_in =  0x00000000,
+		.gpio_g_out = 0x00000000,
+		.gpio_b = 0x00
+	},
+	{
+		.ioif = if_gpio_grp_f,
+		.groups = group_f,
+		.gpio_g_in =  0x00000000,
+		.gpio_g_out = 0x00000000,
+		.gpio_b = 0xff
+	}
+	/* Array end */
+};
+
+static struct watcher *watchers = NULL;
+
+static unsigned int gpio_in_pins =  0xffffffff;
+static unsigned int gpio_out_pins = 0xffffffff;
+static unsigned char gpio_pb_pins = 0xff;
+static unsigned char gpio_pa_pins = 0xff;
+
+static enum cris_io_interface gpio_pa_owners[8];
+static enum cris_io_interface gpio_pb_owners[8];
+static enum cris_io_interface gpio_pg_owners[32];
+
+static int cris_io_interface_init(void);
+
+static unsigned char clear_group_from_set(const unsigned char groups, struct if_group *group)
+{
+	return (groups & ~group->group);
+}
+
+
+static struct if_group *get_group(const unsigned char groups)
+{
+	int i;
+	for (i = 0; i < sizeof(if_groups)/sizeof(struct if_group); i++) {
+		if (groups & if_groups[i].group) {
+			return &if_groups[i];
+		}
+	}
+	return NULL;
+}
+
+
+static void notify_watchers(void)
+{
+	struct watcher *w = watchers;
+
+	DBG(printk("io_interface_mux: notifying watchers\n"));
+
+	while (NULL != w) {
+		w->notify((const unsigned int)gpio_in_pins,
+			  (const unsigned int)gpio_out_pins,
+			  (const unsigned char)gpio_pa_pins,
+			  (const unsigned char)gpio_pb_pins);
+		w = w->next;
+	}
+}
+
+
+int cris_request_io_interface(enum cris_io_interface ioif, const char *device_id)
+{
+	int set_gen_config = 0;
+	int set_gen_config_ii = 0;
+	unsigned long int gens;
+	unsigned long int gens_ii;
+	struct if_group *grp;
+	unsigned char group_set;
+	unsigned long flags;
+
+	(void)cris_io_interface_init();
+
+	DBG(printk("cris_request_io_interface(%d, \"%s\")\n", ioif, device_id));
+
+	if ((ioif >= if_max_interfaces) || (ioif < 0)) {
+		printk(KERN_CRIT "cris_request_io_interface: Bad interface %u submitted for %s\n",
+		       ioif,
+		       device_id);
+		return -EINVAL;
+	}
+
+	local_irq_save(flags);
+
+	if (interfaces[ioif].used) {
+		local_irq_restore(flags);
+		printk(KERN_CRIT "cris_io_interface: Cannot allocate interface for %s, in use by %s\n",
+		       device_id,
+		       interfaces[ioif].owner);
+		return -EBUSY;
+	}
+
+	/* Check that all required groups are free before allocating, */
+	group_set = interfaces[ioif].groups;
+	while (NULL != (grp = get_group(group_set))) {
+		if (grp->used) {
+			if (grp->group == group_f) {
+				if ((if_sync_serial_1 ==  ioif) ||
+				    (if_sync_serial_3 ==  ioif)) {
+					if ((grp->owner != if_sync_serial_1) &&
+					    (grp->owner != if_sync_serial_3)) {
+						local_irq_restore(flags);
+						return -EBUSY;
+					}
+				} else if ((if_scsi8_0 == ioif) ||
+					   (if_scsi8_1 == ioif)) {
+					if ((grp->owner != if_scsi8_0) &&
+					    (grp->owner != if_scsi8_1)) {
+						local_irq_restore(flags);
+						return -EBUSY;
+					}
+				}
+			} else {
+				local_irq_restore(flags);
+				return -EBUSY;
+			}
+		}
+		group_set = clear_group_from_set(group_set, grp);
+	}
+
+	/* Are the required GPIO pins available too? */
+	if (((interfaces[ioif].gpio_g_in & gpio_in_pins) != interfaces[ioif].gpio_g_in) ||
+	    ((interfaces[ioif].gpio_g_out & gpio_out_pins) != interfaces[ioif].gpio_g_out) ||
+	    ((interfaces[ioif].gpio_b & gpio_pb_pins) != interfaces[ioif].gpio_b)) {
+		printk(KERN_CRIT "cris_request_io_interface: Could not get required pins for interface %u\n",
+		       ioif);
+		return -EBUSY;
+	}
+
+	/* All needed I/O pins and pin groups are free, allocate. */
+	group_set = interfaces[ioif].groups;
+	while (NULL != (grp = get_group(group_set))) {
+		grp->used = 1;
+		grp->owner = ioif;
+		group_set = clear_group_from_set(group_set, grp);
+	}
+
+	gens = genconfig_shadow;
+	gens_ii = gen_config_ii_shadow;
+
+	set_gen_config = 1;
+	switch (ioif)
+	{
+	/* Begin Non-multiplexed interfaces */
+	case if_eth:
+		/* fall through */
+	case if_serial_0:
+		set_gen_config = 0;
+		break;
+	/* End Non-multiplexed interfaces */
+	case if_serial_1:
+		set_gen_config_ii = 1;
+		SETS(gens_ii, R_GEN_CONFIG_II, sermode1, async);
+		break;
+	case if_serial_2:
+		SETS(gens, R_GEN_CONFIG, ser2, select);
+		break;
+	case if_serial_3:
+		SETS(gens, R_GEN_CONFIG, ser3, select);
+		set_gen_config_ii = 1;
+		SETS(gens_ii, R_GEN_CONFIG_II, sermode3, async);
+		break;
+	case if_sync_serial_1:
+		set_gen_config_ii = 1;
+		SETS(gens_ii, R_GEN_CONFIG_II, sermode1, sync);
+		break;
+	case if_sync_serial_3:
+		SETS(gens, R_GEN_CONFIG, ser3, select);
+		set_gen_config_ii = 1;
+		SETS(gens_ii, R_GEN_CONFIG_II, sermode3, sync);
+		break;
+	case if_shared_ram:
+		SETS(gens, R_GEN_CONFIG, mio, select);
+		break;
+	case if_shared_ram_w:
+		SETS(gens, R_GEN_CONFIG, mio_w, select);
+		break;
+	case if_par_0:
+		SETS(gens, R_GEN_CONFIG, par0, select);
+		break;
+	case if_par_1:
+		SETS(gens, R_GEN_CONFIG, par1, select);
+		break;
+	case if_par_w:
+		SETS(gens, R_GEN_CONFIG, par0, select);
+		SETS(gens, R_GEN_CONFIG, par_w, select);
+		break;
+	case if_scsi8_0:
+		SETS(gens, R_GEN_CONFIG, scsi0, select);
+		break;
+	case if_scsi8_1:
+		SETS(gens, R_GEN_CONFIG, scsi1, select);
+		break;
+	case if_scsi_w:
+		SETS(gens, R_GEN_CONFIG, scsi0, select);
+		SETS(gens, R_GEN_CONFIG, scsi0w, select);
+		break;
+	case if_ata:
+		SETS(gens, R_GEN_CONFIG, ata, select);
+		break;
+	case if_csp:
+		/* fall through */
+	case if_i2c:
+		set_gen_config = 0;
+		break;
+	case if_usb_1:
+		SETS(gens, R_GEN_CONFIG, usb1, select);
+		break;
+	case if_usb_2:
+		SETS(gens, R_GEN_CONFIG, usb2, select);
+		break;
+	case if_gpio_grp_a:
+		/* GPIO groups are only accounted, don't do configuration changes. */
+		/* fall through */
+	case if_gpio_grp_b:
+		/* fall through */
+	case if_gpio_grp_c:
+		/* fall through */
+	case if_gpio_grp_d:
+		/* fall through */
+	case if_gpio_grp_e:
+		/* fall through */
+	case if_gpio_grp_f:
+		set_gen_config = 0;
+		break;
+	default:
+		panic("cris_request_io_interface: Bad interface %u submitted for %s\n",
+		      ioif,
+		      device_id);
+	}
+
+	interfaces[ioif].used = 1;
+	interfaces[ioif].owner = (char*)device_id;
+
+	if (set_gen_config) {
+		volatile int i;
+		genconfig_shadow = gens;
+		*R_GEN_CONFIG = genconfig_shadow;
+		/* Wait 12 cycles before doing any DMA command */
+		for(i = 6; i > 0; i--)
+			nop();
+	}
+	if (set_gen_config_ii) {
+		gen_config_ii_shadow = gens_ii;
+		*R_GEN_CONFIG_II = gen_config_ii_shadow;
+	}
+
+	DBG(printk("GPIO pins: available before: g_in=0x%08x g_out=0x%08x pb=0x%02x\n",
+		   gpio_in_pins, gpio_out_pins, gpio_pb_pins));
+	DBG(printk("grabbing pins: g_in=0x%08x g_out=0x%08x pb=0x%02x\n",
+		   interfaces[ioif].gpio_g_in,
+		   interfaces[ioif].gpio_g_out,
+		   interfaces[ioif].gpio_b));
+
+	gpio_in_pins &= ~interfaces[ioif].gpio_g_in;
+	gpio_out_pins &= ~interfaces[ioif].gpio_g_out;
+	gpio_pb_pins &= ~interfaces[ioif].gpio_b;
+
+	DBG(printk("GPIO pins: available after: g_in=0x%08x g_out=0x%08x pb=0x%02x\n",
+		   gpio_in_pins, gpio_out_pins, gpio_pb_pins));
+
+	local_irq_restore(flags);
+
+	notify_watchers();
+
+	return 0;
+}
+
+
+void cris_free_io_interface(enum cris_io_interface ioif)
+{
+	struct if_group *grp;
+	unsigned char group_set;
+	unsigned long flags;
+
+	(void)cris_io_interface_init();
+
+	if ((ioif >= if_max_interfaces) || (ioif < 0)) {
+		printk(KERN_CRIT "cris_free_io_interface: Bad interface %u\n",
+		       ioif);
+		return;
+	}
+	local_irq_save(flags);
+	if (!interfaces[ioif].used) {
+		printk(KERN_CRIT "cris_free_io_interface: Freeing free interface %u\n",
+		       ioif);
+		local_irq_restore(flags);
+		return;
+	}
+	group_set = interfaces[ioif].groups;
+	while (NULL != (grp = get_group(group_set))) {
+		if (grp->group == group_f) {
+			switch (ioif)
+			{
+			case if_sync_serial_1:
+				if ((grp->owner == if_sync_serial_1) &&
+				    interfaces[if_sync_serial_3].used) {
+					grp->owner = if_sync_serial_3;
+				} else
+					grp->used = 0;
+				break;
+			case if_sync_serial_3:
+				if ((grp->owner == if_sync_serial_3) &&
+				    interfaces[if_sync_serial_1].used) {
+					grp->owner = if_sync_serial_1;
+				} else
+					grp->used = 0;
+				break;
+			case if_scsi8_0:
+				if ((grp->owner == if_scsi8_0) &&
+				    interfaces[if_scsi8_1].used) {
+					grp->owner = if_scsi8_1;
+				} else
+					grp->used = 0;
+				break;
+			case if_scsi8_1:
+				if ((grp->owner == if_scsi8_1) &&
+				    interfaces[if_scsi8_0].used) {
+					grp->owner = if_scsi8_0;
+				} else
+					grp->used = 0;
+				break;
+			default:
+				grp->used = 0;
+			}
+		} else {
+			grp->used = 0;
+		}
+		group_set = clear_group_from_set(group_set, grp);
+	}
+	interfaces[ioif].used = 0;
+	interfaces[ioif].owner = NULL;
+
+	DBG(printk("GPIO pins: available before: g_in=0x%08x g_out=0x%08x pb=0x%02x\n",
+		   gpio_in_pins, gpio_out_pins, gpio_pb_pins));
+	DBG(printk("freeing pins: g_in=0x%08x g_out=0x%08x pb=0x%02x\n",
+		   interfaces[ioif].gpio_g_in,
+		   interfaces[ioif].gpio_g_out,
+		   interfaces[ioif].gpio_b));
+
+	gpio_in_pins |= interfaces[ioif].gpio_g_in;
+	gpio_out_pins |= interfaces[ioif].gpio_g_out;
+	gpio_pb_pins |= interfaces[ioif].gpio_b;
+
+	DBG(printk("GPIO pins: available after: g_in=0x%08x g_out=0x%08x pb=0x%02x\n",
+		   gpio_in_pins, gpio_out_pins, gpio_pb_pins));
+
+	local_irq_restore(flags);
+
+	notify_watchers();
+}
+
+/* Create a bitmask from bit 0 (inclusive) to bit stop_bit
+   (non-inclusive).  stop_bit == 0 returns 0x0 */
+static inline unsigned int create_mask(const unsigned stop_bit)
+{
+	/* Avoid overflow */
+	if (stop_bit >= 32) {
+		return 0xffffffff;
+	}
+	return (1<<stop_bit)-1;
+}
+
+
+/* port can be 'a', 'b' or 'g' */
+int cris_io_interface_allocate_pins(const enum cris_io_interface ioif,
+				    const char port,
+				    const unsigned start_bit,
+				    const unsigned stop_bit)
+{
+	unsigned int i;
+	unsigned int mask = 0;
+	unsigned int tmp_mask;
+	unsigned long int flags;
+	enum cris_io_interface *owners;
+
+	(void)cris_io_interface_init();
+
+	DBG(printk("cris_io_interface_allocate_pins: if=%d port=%c start=%u stop=%u\n",
+		   ioif, port, start_bit, stop_bit));
+
+	if (!((start_bit <= stop_bit) &&
+	      ((((port == 'a') || (port == 'b')) && (stop_bit < 8)) ||
+	       ((port == 'g') && (stop_bit < 32))))) {
+		return -EINVAL;
+	}
+
+	mask = create_mask(stop_bit + 1);
+	tmp_mask = create_mask(start_bit);
+	mask &= ~tmp_mask;
+
+	DBG(printk("cris_io_interface_allocate_pins: port=%c start=%u stop=%u mask=0x%08x\n",
+		   port, start_bit, stop_bit, mask));
+
+	local_irq_save(flags);
+
+	switch (port) {
+	case 'a':
+		if ((gpio_pa_pins & mask) != mask) {
+			local_irq_restore(flags);
+			return -EBUSY;
+		}
+		owners = gpio_pa_owners;
+		gpio_pa_pins &= ~mask;
+		break;
+	case 'b':
+		if ((gpio_pb_pins & mask) != mask) {
+			local_irq_restore(flags);
+			return -EBUSY;
+		}
+		owners = gpio_pb_owners;
+		gpio_pb_pins &= ~mask;
+		break;
+	case 'g':
+		if (((gpio_in_pins & mask) != mask) ||
+		    ((gpio_out_pins & mask) != mask)) {
+			local_irq_restore(flags);
+			return -EBUSY;
+		}
+		owners = gpio_pg_owners;
+		gpio_in_pins &= ~mask;
+		gpio_out_pins &= ~mask;
+		break;
+	default:
+		local_irq_restore(flags);
+		return -EINVAL;
+	}
+
+	for (i = start_bit; i <= stop_bit; i++) {
+		owners[i] = ioif;
+	}
+	local_irq_restore(flags);
+
+	notify_watchers();
+	return 0;
+}
+
+
+/* port can be 'a', 'b' or 'g' */
+int cris_io_interface_free_pins(const enum cris_io_interface ioif,
+                                const char port,
+                                const unsigned start_bit,
+                                const unsigned stop_bit)
+{
+	unsigned int i;
+	unsigned int mask = 0;
+	unsigned int tmp_mask;
+	unsigned long int flags;
+	enum cris_io_interface *owners;
+
+	(void)cris_io_interface_init();
+
+	if (!((start_bit <= stop_bit) &&
+	      ((((port == 'a') || (port == 'b')) && (stop_bit < 8)) ||
+	       ((port == 'g') && (stop_bit < 32))))) {
+		return -EINVAL;
+	}
+
+	mask = create_mask(stop_bit + 1);
+	tmp_mask = create_mask(start_bit);
+	mask &= ~tmp_mask;
+
+	DBG(printk("cris_io_interface_free_pins: port=%c start=%u stop=%u mask=0x%08x\n",
+		   port, start_bit, stop_bit, mask));
+
+	local_irq_save(flags);
+
+	switch (port) {
+	case 'a':
+		if ((~gpio_pa_pins & mask) != mask) {
+			local_irq_restore(flags);
+			printk(KERN_CRIT "cris_io_interface_free_pins: Freeing free pins");
+		}
+		owners = gpio_pa_owners;
+		break;
+	case 'b':
+		if ((~gpio_pb_pins & mask) != mask) {
+			local_irq_restore(flags);
+			printk(KERN_CRIT "cris_io_interface_free_pins: Freeing free pins");
+		}
+		owners = gpio_pb_owners;
+		break;
+	case 'g':
+		if (((~gpio_in_pins & mask) != mask) ||
+		    ((~gpio_out_pins & mask) != mask)) {
+			local_irq_restore(flags);
+			printk(KERN_CRIT "cris_io_interface_free_pins: Freeing free pins");
+		}
+		owners = gpio_pg_owners;
+		break;
+	default:
+		owners = NULL; /* Cannot happen. Shut up, gcc! */
+	}
+
+	for (i = start_bit; i <= stop_bit; i++) {
+		if (owners[i] != ioif) {
+			printk(KERN_CRIT "cris_io_interface_free_pins: Freeing unowned pins");
+		}
+	}
+
+	/* All was ok, change data. */
+	switch (port) {
+	case 'a':
+		gpio_pa_pins |= mask;
+		break;
+	case 'b':
+		gpio_pb_pins |= mask;
+		break;
+	case 'g':
+		gpio_in_pins |= mask;
+		gpio_out_pins |= mask;
+		break;
+	}
+
+	for (i = start_bit; i <= stop_bit; i++) {
+		owners[i] = if_unclaimed;
+	}
+	local_irq_restore(flags);
+	notify_watchers();
+
+        return 0;
+}
+
+
+int cris_io_interface_register_watcher(void (*notify)(const unsigned int gpio_in_available,
+                                                      const unsigned int gpio_out_available,
+                                                      const unsigned char pa_available,
+                                                      const unsigned char pb_available))
+{
+	struct watcher *w;
+
+	(void)cris_io_interface_init();
+
+	if (NULL == notify) {
+		return -EINVAL;
+	}
+	w = kmalloc(sizeof(*w), GFP_KERNEL);
+	if (!w) {
+		return -ENOMEM;
+	}
+	w->notify = notify;
+	w->next = watchers;
+	watchers = w;
+
+	w->notify((const unsigned int)gpio_in_pins,
+		  (const unsigned int)gpio_out_pins,
+		  (const unsigned char)gpio_pa_pins,
+		  (const unsigned char)gpio_pb_pins);
+
+	return 0;
+}
+
+void cris_io_interface_delete_watcher(void (*notify)(const unsigned int gpio_in_available,
+						     const unsigned int gpio_out_available,
+                                                     const unsigned char pa_available,
+						     const unsigned char pb_available))
+{
+	struct watcher *w = watchers, *prev = NULL;
+
+	(void)cris_io_interface_init();
+
+	while ((NULL != w) && (w->notify != notify)){
+		prev = w;
+		w = w->next;
+	}
+	if (NULL != w) {
+		if (NULL != prev) {
+			prev->next = w->next;
+		} else {
+			watchers = w->next;
+		}
+		kfree(w);
+		return;
+	}
+	printk(KERN_WARNING "cris_io_interface_delete_watcher: Deleting unknown watcher 0x%p\n", notify);
+}
+
+
+static int cris_io_interface_init(void)
+{
+	static int first = 1;
+	int i;
+
+	if (!first) {
+		return 0;
+	}
+	first = 0;
+
+	for (i = 0; i<8; i++) {
+		gpio_pa_owners[i] = if_unclaimed;
+		gpio_pb_owners[i] = if_unclaimed;
+		gpio_pg_owners[i] = if_unclaimed;
+	}
+	for (; i<32; i++) {
+		gpio_pg_owners[i] = if_unclaimed;
+	}
+	return 0;
+}
+
+
+module_init(cris_io_interface_init);
+
+
+EXPORT_SYMBOL(cris_request_io_interface);
+EXPORT_SYMBOL(cris_free_io_interface);
+EXPORT_SYMBOL(cris_io_interface_allocate_pins);
+EXPORT_SYMBOL(cris_io_interface_free_pins);
+EXPORT_SYMBOL(cris_io_interface_register_watcher);
+EXPORT_SYMBOL(cris_io_interface_delete_watcher);
diff --git a/arch/cris/arch-v10/kernel/irq.c b/arch/cris/arch-v10/kernel/irq.c
--- a/arch/cris/arch-v10/kernel/irq.c
+++ b/arch/cris/arch-v10/kernel/irq.c
@@ -1,4 +1,4 @@
-/* $Id: irq.c,v 1.2 2004/06/09 05:30:27 starvik Exp $
+/* $Id: irq.c,v 1.4 2005/01/04 12:22:28 starvik Exp $
  *
  *	linux/arch/cris/kernel/irq.c
  *
@@ -12,11 +12,13 @@
  */
 
 #include <asm/irq.h>
+#include <linux/irq.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/config.h>
 
-irqvectptr irq_shortcuts[NR_IRQS]; /* vector of shortcut jumps after the irq prologue */
+#define mask_irq(irq_nr) (*R_VECT_MASK_CLR = 1 << (irq_nr));
+#define unmask_irq(irq_nr) (*R_VECT_MASK_SET = 1 << (irq_nr));
 
 /* don't use set_int_vector, it bypasses the linux interrupt handlers. it is
  * global just so that the kernel gdb can use it.
@@ -102,41 +104,52 @@ static void (*interrupt[NR_IRQS])(void) 
 	IRQ31_interrupt
 };
 
-static void (*bad_interrupt[NR_IRQS])(void) = {
-        NULL, NULL,
-	NULL, bad_IRQ3_interrupt,
-	bad_IRQ4_interrupt, bad_IRQ5_interrupt,
-	bad_IRQ6_interrupt, bad_IRQ7_interrupt,
-	bad_IRQ8_interrupt, bad_IRQ9_interrupt,
-	bad_IRQ10_interrupt, bad_IRQ11_interrupt,
-	bad_IRQ12_interrupt, bad_IRQ13_interrupt,
-	NULL, NULL,
-	bad_IRQ16_interrupt, bad_IRQ17_interrupt,
-	bad_IRQ18_interrupt, bad_IRQ19_interrupt,
-	bad_IRQ20_interrupt, bad_IRQ21_interrupt,
-	bad_IRQ22_interrupt, bad_IRQ23_interrupt,
-	bad_IRQ24_interrupt, bad_IRQ25_interrupt,
-	NULL, NULL, NULL, NULL, NULL,
-	bad_IRQ31_interrupt
-};
+static void enable_crisv10_irq(unsigned int irq);
+
+static unsigned int startup_crisv10_irq(unsigned int irq)
+{
+	enable_crisv10_irq(irq);
+	return 0;
+}
+
+#define shutdown_crisv10_irq	disable_crisv10_irq
 
-void arch_setup_irq(int irq)
+static void enable_crisv10_irq(unsigned int irq)
 {
-  set_int_vector(irq, interrupt[irq]);
+	unmask_irq(irq);
 }
 
-void arch_free_irq(int irq)
+static void disable_crisv10_irq(unsigned int irq)
 {
-  set_int_vector(irq, bad_interrupt[irq]);
+	mask_irq(irq);
 }
 
+static void ack_crisv10_irq(unsigned int irq)
+{
+}
+
+static void end_crisv10_irq(unsigned int irq)
+{
+}
+
+static struct hw_interrupt_type crisv10_irq_type = {
+	.typename =    "CRISv10",
+	.startup =     startup_crisv10_irq,
+	.shutdown =    shutdown_crisv10_irq,
+	.enable =      enable_crisv10_irq,
+	.disable =     disable_crisv10_irq,
+	.ack =         ack_crisv10_irq,
+	.end =         end_crisv10_irq,
+	.set_affinity = NULL
+};
+
 void weird_irq(void);
 void system_call(void);  /* from entry.S */
 void do_sigtrap(void); /* from entry.S */
 void gdb_handle_breakpoint(void); /* from entry.S */
 
 /* init_IRQ() is called by start_kernel and is responsible for fixing IRQ masks and
-   setting the irq vector table to point to bad_interrupt ptrs.
+   setting the irq vector table.
 */
 
 void __init
@@ -154,14 +167,15 @@ init_IRQ(void)
 
 	*R_VECT_MASK_CLR = 0xffffffff;
 
-	/* clear the shortcut entry points */
-
-	for(i = 0; i < NR_IRQS; i++)
-		irq_shortcuts[i] = NULL;
-        
         for (i = 0; i < 256; i++)
                etrax_irv->v[i] = weird_irq;
 
+	/* Initialize IRQ handler descriptiors. */
+	for(i = 2; i < NR_IRQS; i++) {
+		irq_desc[i].handler = &crisv10_irq_type;
+		set_int_vector(i, interrupt[i]);
+	}
+
         /* the entries in the break vector contain actual code to be
            executed by the associated break handler, rather than just a jump
            address. therefore we need to setup a default breakpoint handler
@@ -170,10 +184,6 @@ init_IRQ(void)
 	for (i = 0; i < 16; i++)
                 set_break_vector(i, do_sigtrap);
         
-	/* set all etrax irq's to the bad handlers */
-	for (i = 2; i < NR_IRQS; i++)
-		set_int_vector(i, bad_interrupt[i]);
-        
 	/* except IRQ 15 which is the multiple-IRQ handler on Etrax100 */
 
 	set_int_vector(15, multiple_interrupt);
diff --git a/arch/cris/arch-v10/kernel/kgdb.c b/arch/cris/arch-v10/kernel/kgdb.c
--- a/arch/cris/arch-v10/kernel/kgdb.c
+++ b/arch/cris/arch-v10/kernel/kgdb.c
@@ -18,6 +18,10 @@
 *! Jul 21 1999  Bjorn Wesen     eLinux port
 *!
 *! $Log: kgdb.c,v $
+*! Revision 1.6  2005/01/14 10:12:17  starvik
+*! KGDB on separate port.
+*! Console fixes from 2.4.
+*!
 *! Revision 1.5  2004/10/07 13:59:08  starvik
 *! Corrected call to set_int_vector
 *!
@@ -71,7 +75,7 @@
 *!
 *!---------------------------------------------------------------------------
 *!
-*! $Id: kgdb.c,v 1.5 2004/10/07 13:59:08 starvik Exp $
+*! $Id: kgdb.c,v 1.6 2005/01/14 10:12:17 starvik Exp $
 *!
 *! (C) Copyright 1999, Axis Communications AB, LUND, SWEDEN
 *!
@@ -225,6 +229,7 @@
 #include <linux/kernel.h>
 #include <linux/delay.h>
 #include <linux/linkage.h>
+#include <linux/reboot.h>
 
 #include <asm/setup.h>
 #include <asm/ptrace.h>
@@ -1344,12 +1349,11 @@ handle_exception (int sigval)
 	}
 }
 
-/* The jump is to the address 0x00000002. Performs a complete re-start
-   from scratch. */
+/* Performs a complete re-start from scratch. */
 static void
 kill_restart ()
 {
-	__asm__ volatile ("jump 2");
+	machine_restart("");
 }
 
 /********************************** Breakpoint *******************************/
@@ -1506,6 +1510,11 @@ kgdb_handle_serial:
   bne goback
   nop
 
+  move.d  [reg+0x5E], $r10		; Get DCCR
+  btstq	   8, $r10			; Test the U-flag.
+  bmi	   goback
+  nop
+
 ;;
 ;; Handle the communication
 ;;
diff --git a/arch/cris/arch-v10/kernel/process.c b/arch/cris/arch-v10/kernel/process.c
--- a/arch/cris/arch-v10/kernel/process.c
+++ b/arch/cris/arch-v10/kernel/process.c
@@ -1,4 +1,4 @@
-/* $Id: process.c,v 1.9 2004/10/19 13:07:37 starvik Exp $
+/* $Id: process.c,v 1.12 2004/12/27 11:18:32 starvik Exp $
  * 
  *  linux/arch/cris/kernel/process.c
  *
@@ -101,6 +101,7 @@ int kernel_thread(int (*fn)(void *), voi
 	regs.r11 = (unsigned long)fn;
 	regs.r12 = (unsigned long)arg;
 	regs.irp = (unsigned long)kernel_thread_helper;
+	regs.dccr = 1 << I_DCCR_BITNR;
 
 	/* Ok, create the new process.. */
         return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
diff --git a/arch/cris/arch-v10/kernel/ptrace.c b/arch/cris/arch-v10/kernel/ptrace.c
--- a/arch/cris/arch-v10/kernel/ptrace.c
+++ b/arch/cris/arch-v10/kernel/ptrace.c
@@ -11,6 +11,7 @@
 #include <linux/ptrace.h>
 #include <linux/user.h>
 #include <linux/signal.h>
+#include <linux/security.h>
 
 #include <asm/uaccess.h>
 #include <asm/page.h>
@@ -86,9 +87,13 @@ sys_ptrace(long request, long pid, long 
 	ret = -EPERM;
 	
 	if (request == PTRACE_TRACEME) {
+		/* are we already being traced? */
 		if (current->ptrace & PT_PTRACED)
 			goto out;
-
+		ret = security_ptrace(current->parent, current);
+		if (ret)
+			goto out;
+		/* set the ptrace bit in the process flags. */
 		current->ptrace |= PT_PTRACED;
 		ret = 0;
 		goto out;
@@ -207,7 +212,7 @@ sys_ptrace(long request, long pid, long 
 		case PTRACE_KILL:
 			ret = 0;
 			
-			if (child->state == TASK_ZOMBIE)
+			if (child->exit_state == EXIT_ZOMBIE)
 				break;
 			
 			child->exit_code = SIGKILL;
diff --git a/arch/cris/arch-v10/kernel/shadows.c b/arch/cris/arch-v10/kernel/shadows.c
--- a/arch/cris/arch-v10/kernel/shadows.c
+++ b/arch/cris/arch-v10/kernel/shadows.c
@@ -1,4 +1,4 @@
-/* $Id: shadows.c,v 1.1 2001/12/17 13:59:27 bjornw Exp $
+/* $Id: shadows.c,v 1.2 2004/12/13 12:21:51 starvik Exp $
  * 
  * Various shadow registers. Defines for these are in include/asm-etrax100/io.h
  */
@@ -6,6 +6,7 @@
 /* Shadows for internal Etrax-registers */
 
 unsigned long genconfig_shadow;
+unsigned long gen_config_ii_shadow;
 unsigned long port_g_data_shadow;
 unsigned char port_pa_dir_shadow;
 unsigned char port_pa_data_shadow;
diff --git a/arch/cris/arch-v10/kernel/traps.c b/arch/cris/arch-v10/kernel/traps.c
--- a/arch/cris/arch-v10/kernel/traps.c
+++ b/arch/cris/arch-v10/kernel/traps.c
@@ -1,4 +1,4 @@
-/* $Id: traps.c,v 1.2 2003/07/04 08:27:41 starvik Exp $
+/* $Id: traps.c,v 1.4 2005/04/24 18:47:55 starvik Exp $
  *
  *  linux/arch/cris/arch-v10/traps.c
  *
@@ -16,6 +16,8 @@
 #include <asm/uaccess.h>
 #include <asm/arch/sv_addr_ag.h>
 
+extern int raw_printk(const char *fmt, ...);
+
 void 
 show_registers(struct pt_regs * regs)
 {
@@ -26,18 +28,18 @@ show_registers(struct pt_regs * regs)
 	   register.  */
 	unsigned long usp = rdusp();
 
-	printk("IRP: %08lx SRP: %08lx DCCR: %08lx USP: %08lx MOF: %08lx\n",
+	raw_printk("IRP: %08lx SRP: %08lx DCCR: %08lx USP: %08lx MOF: %08lx\n",
 	       regs->irp, regs->srp, regs->dccr, usp, regs->mof );
-	printk(" r0: %08lx  r1: %08lx   r2: %08lx  r3: %08lx\n",
+	raw_printk(" r0: %08lx  r1: %08lx   r2: %08lx  r3: %08lx\n",
 	       regs->r0, regs->r1, regs->r2, regs->r3);
-	printk(" r4: %08lx  r5: %08lx   r6: %08lx  r7: %08lx\n",
+	raw_printk(" r4: %08lx  r5: %08lx   r6: %08lx  r7: %08lx\n",
 	       regs->r4, regs->r5, regs->r6, regs->r7);
-	printk(" r8: %08lx  r9: %08lx  r10: %08lx r11: %08lx\n",
+	raw_printk(" r8: %08lx  r9: %08lx  r10: %08lx r11: %08lx\n",
 	       regs->r8, regs->r9, regs->r10, regs->r11);
-	printk("r12: %08lx r13: %08lx oR10: %08lx\n",
-	       regs->r12, regs->r13, regs->orig_r10);
-	printk("R_MMU_CAUSE: %08lx\n", (unsigned long)*R_MMU_CAUSE);
-	printk("Process %s (pid: %d, stackpage=%08lx)\n",
+	raw_printk("r12: %08lx r13: %08lx oR10: %08lx  sp: %08lx\n",
+	       regs->r12, regs->r13, regs->orig_r10, regs);
+	raw_printk("R_MMU_CAUSE: %08lx\n", (unsigned long)*R_MMU_CAUSE);
+	raw_printk("Process %s (pid: %d, stackpage=%08lx)\n",
 	       current->comm, current->pid, (unsigned long)current);
 
 	/*
@@ -53,7 +55,7 @@ show_registers(struct pt_regs * regs)
 		if (usp != 0)
 			show_stack (NULL, NULL);
 
-                printk("\nCode: ");
+                raw_printk("\nCode: ");
                 if(regs->irp < PAGE_OFFSET)
                         goto bad;
 
@@ -70,16 +72,16 @@ show_registers(struct pt_regs * regs)
                         unsigned char c;
                         if(__get_user(c, &((unsigned char*)regs->irp)[i])) {
 bad:
-                                printk(" Bad IP value.");
+                                raw_printk(" Bad IP value.");
                                 break;
                         }
 
 			if (i == 0)
-			  printk("(%02x) ", c);
+			  raw_printk("(%02x) ", c);
 			else
-			  printk("%02x ", c);
+			  raw_printk("%02x ", c);
                 }
-		printk("\n");
+		raw_printk("\n");
         }
 }
 
@@ -121,7 +123,7 @@ die_if_kernel(const char * str, struct p
 	stop_watchdog();
 #endif
 
-	printk("%s: %04lx\n", str, err & 0xffff);
+	raw_printk("%s: %04lx\n", str, err & 0xffff);
 
 	show_registers(regs);
 
@@ -130,3 +132,8 @@ die_if_kernel(const char * str, struct p
 #endif
 	do_exit(SIGSEGV);
 }
+
+void arch_enable_nmi(void)
+{
+  asm volatile("setf m");
+}
diff --git a/arch/cris/arch-v10/mm/fault.c b/arch/cris/arch-v10/mm/fault.c
--- a/arch/cris/arch-v10/mm/fault.c
+++ b/arch/cris/arch-v10/mm/fault.c
@@ -14,6 +14,7 @@
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
 #include <asm/arch/svinto.h>
+#include <asm/mmu_context.h>
 
 /* debug of low-level TLB reload */
 #undef DEBUG
@@ -24,8 +25,6 @@
 #define D(x)
 #endif
 
-extern volatile pgd_t *current_pgd;
-
 extern const struct exception_table_entry
 	*search_exception_tables(unsigned long addr);
 
@@ -46,7 +45,7 @@ handle_mmu_bus_fault(struct pt_regs *reg
 	int page_id;
 	int acc, inv;
 #endif
-	pgd_t* pgd = (pgd_t*)current_pgd;
+	pgd_t* pgd = (pgd_t*)per_cpu(current_pgd, smp_processor_id());
 	pmd_t *pmd;
 	pte_t pte;
 	int miss, we, writeac;
@@ -94,24 +93,3 @@ handle_mmu_bus_fault(struct pt_regs *reg
 	*R_TLB_LO = pte_val(pte);
 	local_irq_restore(flags);
 }
-
-/* Called from arch/cris/mm/fault.c to find fixup code. */
-int
-find_fixup_code(struct pt_regs *regs)
-{
-	const struct exception_table_entry *fixup;
-
-	if ((fixup = search_exception_tables(regs->irp)) != 0) {
-		/* Adjust the instruction pointer in the stackframe. */
-		regs->irp = fixup->fixup;
-		
-		/* 
-		 * Don't return by restoring the CPU state, so switch
-		 * frame-type. 
-		 */
-		regs->frametype = CRIS_FRAME_NORMAL;
-		return 1;
-	}
-
-	return 0;
-}
diff --git a/arch/cris/arch-v10/mm/init.c b/arch/cris/arch-v10/mm/init.c
--- a/arch/cris/arch-v10/mm/init.c
+++ b/arch/cris/arch-v10/mm/init.c
@@ -42,7 +42,7 @@ paging_init(void)
 	 *  switch_mm)
 	 */
 
-	current_pgd = init_mm.pgd;
+	per_cpu(current_pgd, smp_processor_id()) = init_mm.pgd;
 
 	/* initialise the TLB (tlb.c) */
 
diff --git a/arch/cris/arch-v10/mm/tlb.c b/arch/cris/arch-v10/mm/tlb.c
--- a/arch/cris/arch-v10/mm/tlb.c
+++ b/arch/cris/arch-v10/mm/tlb.c
@@ -139,53 +139,6 @@ flush_tlb_page(struct vm_area_struct *vm
 	local_irq_restore(flags);
 }
 
-/* invalidate a page range */
-
-void
-flush_tlb_range(struct vm_area_struct *vma, 
-		unsigned long start,
-		unsigned long end)
-{
-	struct mm_struct *mm = vma->vm_mm;
-	int page_id = mm->context.page_id;
-	int i;
-	unsigned long flags;
-
-	D(printk("tlb: flush range %p<->%p in context %d (%p)\n",
-		 start, end, page_id, mm));
-
-	if(page_id == NO_CONTEXT)
-		return;
-
-	start &= PAGE_MASK;  /* probably not necessary */
-	end &= PAGE_MASK;    /* dito */
-
-	/* invalidate those TLB entries that match both the mm context
-	 * and the virtual address range
-	 */
-
-	local_save_flags(flags);
-	local_irq_disable();
-	for(i = 0; i < NUM_TLB_ENTRIES; i++) {
-		unsigned long tlb_hi, vpn;
-		*R_TLB_SELECT = IO_FIELD(R_TLB_SELECT, index, i);
-		tlb_hi = *R_TLB_HI;
-		vpn = tlb_hi & PAGE_MASK;
-		if (IO_EXTRACT(R_TLB_HI, page_id, tlb_hi) == page_id &&
-		    vpn >= start && vpn < end) {
-			*R_TLB_HI = ( IO_FIELD(R_TLB_HI, page_id, INVALID_PAGEID ) |
-				      IO_FIELD(R_TLB_HI, vpn,     i & 0xf ) );
-			
-			*R_TLB_LO = ( IO_STATE(R_TLB_LO, global,no  ) |
-				      IO_STATE(R_TLB_LO, valid, no  ) |
-				      IO_STATE(R_TLB_LO, kernel,no  ) |
-				      IO_STATE(R_TLB_LO, we,    no  ) |
-				      IO_FIELD(R_TLB_LO, pfn,   0   ) );
-		}
-	}
-	local_irq_restore(flags);
-}
-
 /* dump the entire TLB for debug purposes */
 
 #if 0
@@ -237,7 +190,7 @@ switch_mm(struct mm_struct *prev, struct
 	 * the pgd.
 	 */
 
-	current_pgd = next->pgd;
+	per_cpu(current_pgd, smp_processor_id()) = next->pgd;
 
 	/* switch context in the MMU */
 	
diff --git a/arch/cris/arch-v32/Kconfig b/arch/cris/arch-v32/Kconfig
new file mode 100644
--- /dev/null
+++ b/arch/cris/arch-v32/Kconfig
@@ -0,0 +1,296 @@
+config ETRAX_DRAM_VIRTUAL_BASE
+	hex
+	depends on ETRAX_ARCH_V32
+	default "c0000000"
+
+config ETRAX_LED1G
+	string "First green LED bit"
+	depends on ETRAX_ARCH_V32
+	default "PA3"
+	help
+	  Bit to use for the first green LED (network LED).
+	  Most Axis products use bit A3 here.
+
+config ETRAX_LED1R
+	string "First red LED bit"
+	depends on ETRAX_ARCH_V32
+	default "PA4"
+	help
+	  Bit to use for the first red LED (network LED).
+	  Most Axis products use bit A4 here.
+
+config ETRAX_LED2G
+	string "Second green LED bit"
+	depends on ETRAX_ARCH_V32
+	default "PA5"
+	help
+	  Bit to use for the first green LED (status LED).
+	  Most Axis products use bit A5 here.
+
+config ETRAX_LED2R
+	string "Second red LED bit"
+	depends on ETRAX_ARCH_V32
+	default "PA6"
+	help
+	  Bit to use for the first red LED (network LED).
+	  Most Axis products use bit A6 here.
+
+config ETRAX_LED3G
+	string "Third green LED bit"
+	depends on ETRAX_ARCH_V32
+	default "PA7"
+	help
+	  Bit to use for the first green LED (drive/power LED).
+	  Most Axis products use bit A7 here.
+
+config ETRAX_LED3R
+	string "Third red LED bit"
+	depends on ETRAX_ARCH_V32
+	default "PA7"
+	help
+	  Bit to use for the first red LED (drive/power LED).
+	  Most Axis products use bit A7 here.
+
+choice
+	prompt "Product debug-port"
+	depends on ETRAX_ARCH_V32
+	default ETRAX_DEBUG_PORT0
+
+config ETRAX_DEBUG_PORT0
+	bool "Serial-0"
+	help
+	  Choose a serial port for the ETRAX debug console.  Default to
+	  port 0.
+
+config ETRAX_DEBUG_PORT1
+	bool "Serial-1"
+	help
+	  Use serial port 1 for the console.
+
+config ETRAX_DEBUG_PORT2
+	bool "Serial-2"
+	help
+	  Use serial port 2 for the console.
+
+config ETRAX_DEBUG_PORT3
+	bool "Serial-3"
+	help
+	  Use serial port 3 for the console.
+
+config ETRAX_DEBUG_PORT_NULL
+	bool "disabled"
+	help
+	  Disable serial-port debugging.
+
+endchoice
+
+choice
+	prompt "Kernel GDB port"
+	depends on ETRAX_KGDB
+	default ETRAX_KGDB_PORT0
+	help
+	  Choose a serial port for kernel debugging.  NOTE: This port should
+	  not be enabled under Drivers for built-in interfaces (as it has its
+	  own initialization code) and should not be the same as the debug port.
+
+config ETRAX_KGDB_PORT0
+	bool "Serial-0"
+	help
+	  Use serial port 0 for kernel debugging.
+
+config ETRAX_KGDB_PORT1
+	bool "Serial-1"
+	help
+	  Use serial port 1 for kernel debugging.
+
+config ETRAX_KGDB_PORT2
+	bool "Serial-2"
+	help
+	  Use serial port 2 for kernel debugging.
+
+config ETRAX_KGDB_PORT3
+	bool "Serial-3"
+	help
+	  Use serial port 3 for kernel debugging.
+
+endchoice
+
+config ETRAX_MEM_GRP1_CONFIG
+	hex "MEM_GRP1_CONFIG"
+	depends on ETRAX_ARCH_V32
+	default "4044a"
+	help
+	  Waitstates for flash. The default value is suitable for the
+	  standard flashes used in axis products (120 ns).
+
+config ETRAX_MEM_GRP2_CONFIG
+	hex "MEM_GRP2_CONFIG"
+	depends on ETRAX_ARCH_V32
+	default "0"
+	help
+	  Waitstates for SRAM. 0 is a good choice for most Axis products.
+
+config ETRAX_MEM_GRP3_CONFIG
+	hex "MEM_GRP3_CONFIG"
+	depends on ETRAX_ARCH_V32
+	default "0"
+	help
+	  Waitstates for CSP0-3. 0 is a good choice for most Axis products.
+	  It may need to be changed if external devices such as extra
+	  register-mapped LEDs are used.
+
+config ETRAX_MEM_GRP4_CONFIG
+	hex "MEM_GRP4_CONFIG"
+	depends on ETRAX_ARCH_V32
+	default "0"
+	help
+	  Waitstates for CSP4-6. 0 is a good choice for most Axis products.
+
+config ETRAX_SDRAM_GRP0_CONFIG
+	hex "SDRAM_GRP0_CONFIG"
+	depends on ETRAX_ARCH_V32
+	default "336"
+	help
+	  SDRAM configuration for group 0. The value depends on the
+	  hardware configuration. The default value is suitable
+	  for 32 MB organized as two 16 bits chips (e.g. Axis
+	  part number 18550) connected as one 32 bit device (i.e. in
+	  the same group).
+
+config ETRAX_SDRAM_GRP1_CONFIG
+	hex "SDRAM_GRP1_CONFIG"
+	depends on ETRAX_ARCH_V32
+	default "0"
+	help
+	  SDRAM configuration for group 1. The defult value is 0
+	  because group 1 is not used in the default configuration,
+	  described in the help for SDRAM_GRP0_CONFIG.
+
+config ETRAX_SDRAM_TIMING
+	hex "SDRAM_TIMING"
+	depends on ETRAX_ARCH_V32
+	default "104a"
+	help
+	  SDRAM timing parameters. The default value is ok for
+	  most hardwares but large SDRAMs may require a faster
+	  refresh (a.k.a 8K refresh). The default value implies
+	  100MHz clock and SDR mode.
+
+config ETRAX_SDRAM_COMMAND
+	hex "SDRAM_COMMAND"
+	depends on ETRAX_ARCH_V32
+	default "0"
+	help
+	  SDRAM command. Should be 0 unless you really know what
+	  you are doing (may be != 0 for unusual address line
+	  mappings such as in a MCM)..
+
+config ETRAX_DEF_GIO_PA_OE
+	hex "GIO_PA_OE"
+	depends on ETRAX_ARCH_V32
+	default "1c"
+	help
+	  Configures the direction of general port A bits.  1 is out, 0 is in.
+	  This is often totally different depending on the product used.
+	  There are some guidelines though - if you know that only LED's are
+	  connected to port PA, then they are usually connected to bits 2-4
+	  and you can therefore use 1c.  On other boards which don't have the
+	  LED's at the general ports, these bits are used for all kinds of
+	  stuff.  If you don't know what to use, it is always safe to put all
+	  as inputs, although floating inputs isn't good.
+
+config ETRAX_DEF_GIO_PA_OUT
+	hex "GIO_PA_OUT"
+	depends on ETRAX_ARCH_V32
+	default "00"
+	help
+	  Configures the initial data for the general port A bits.  Most
+	  products should use 00 here.
+
+config ETRAX_DEF_GIO_PB_OE
+	hex "GIO_PB_OE"
+	depends on ETRAX_ARCH_V32
+	default "00000"
+	help
+	  Configures the direction of general port B bits.  1 is out, 0 is in.
+	  This is often totally different depending on the product used.
+	  There are some guidelines though - if you know that only LED's are
+	  connected to port PA, then they are usually connected to bits 2-4
+	  and you can therefore use 1c.  On other boards which don't have the
+	  LED's at the general ports, these bits are used for all kinds of
+	  stuff.  If you don't know what to use, it is always safe to put all
+	  as inputs, although floating inputs isn't good.
+
+config ETRAX_DEF_GIO_PB_OUT
+	hex "GIO_PB_OUT"
+	depends on ETRAX_ARCH_V32
+	default "00000"
+	help
+	  Configures the initial data for the general port B bits.  Most
+	  products should use 00000 here.
+
+config ETRAX_DEF_GIO_PC_OE
+	hex "GIO_PC_OE"
+	depends on ETRAX_ARCH_V32
+	default "00000"
+	help
+	  Configures the direction of general port C bits.  1 is out, 0 is in.
+	  This is often totally different depending on the product used.
+	  There are some guidelines though - if you know that only LED's are
+	  connected to port PA, then they are usually connected to bits 2-4
+	  and you can therefore use 1c.  On other boards which don't have the
+	  LED's at the general ports, these bits are used for all kinds of
+	  stuff.  If you don't know what to use, it is always safe to put all
+	  as inputs, although floating inputs isn't good.
+
+config ETRAX_DEF_GIO_PC_OUT
+	hex "GIO_PC_OUT"
+	depends on ETRAX_ARCH_V32
+	default "00000"
+	help
+	  Configures the initial data for the general port C bits.  Most
+	  products should use 00000 here.
+
+config ETRAX_DEF_GIO_PD_OE
+	hex "GIO_PD_OE"
+	depends on ETRAX_ARCH_V32
+	default "00000"
+	help
+	  Configures the direction of general port D bits.  1 is out, 0 is in.
+	  This is often totally different depending on the product used.
+	  There are some guidelines though - if you know that only LED's are
+	  connected to port PA, then they are usually connected to bits 2-4
+	  and you can therefore use 1c.  On other boards which don't have the
+	  LED's at the general ports, these bits are used for all kinds of
+	  stuff.  If you don't know what to use, it is always safe to put all
+	  as inputs, although floating inputs isn't good.
+
+config ETRAX_DEF_GIO_PD_OUT
+	hex "GIO_PD_OUT"
+	depends on ETRAX_ARCH_V32
+	default "00000"
+	help
+	  Configures the initial data for the general port D bits.  Most
+	  products should use 00000 here.
+
+config ETRAX_DEF_GIO_PE_OE
+	hex "GIO_PE_OE"
+	depends on ETRAX_ARCH_V32
+	default "00000"
+	help
+	  Configures the direction of general port E bits.  1 is out, 0 is in.
+	  This is often totally different depending on the product used.
+	  There are some guidelines though - if you know that only LED's are
+	  connected to port PA, then they are usually connected to bits 2-4
+	  and you can therefore use 1c.  On other boards which don't have the
+	  LED's at the general ports, these bits are used for all kinds of
+	  stuff.  If you don't know what to use, it is always safe to put all
+	  as inputs, although floating inputs isn't good.
+
+config ETRAX_DEF_GIO_PE_OUT
+	hex "GIO_PE_OUT"
+	depends on ETRAX_ARCH_V32
+	default "00000"
+	help
+	  Configures the initial data for the general port E bits.  Most
+	  products should use 00000 here.
diff --git a/arch/cris/arch-v32/boot/Makefile b/arch/cris/arch-v32/boot/Makefile
new file mode 100644
--- /dev/null
+++ b/arch/cris/arch-v32/boot/Makefile
@@ -0,0 +1,14 @@
+#
+# arch/cris/arch-v32/boot/Makefile
+#
+target = $(target_boot_dir)
+src    = $(src_boot_dir)
+
+zImage: compressed/vmlinuz
+
+compressed/vmlinuz: $(objtree)/vmlinux
+	@$(MAKE) -f $(src)/compressed/Makefile $(objtree)/vmlinuz
+
+clean:
+	rm -f zImage tools/build compressed/vmlinux.out
+	@$(MAKE) -f $(src)/compressed/Makefile clean
diff --git a/arch/cris/arch-v32/boot/compressed/Makefile b/arch/cris/arch-v32/boot/compressed/Makefile
new file mode 100644
--- /dev/null
+++ b/arch/cris/arch-v32/boot/compressed/Makefile
@@ -0,0 +1,41 @@
+#
+# lx25/arch/cris/arch-v32/boot/compressed/Makefile
+#
+# create a compressed vmlinux image from the original vmlinux files and romfs
+#
+
+target = $(target_compressed_dir)
+src    = $(src_compressed_dir)
+
+CC = gcc-cris -mlinux -march=v32 -I $(TOPDIR)/include
+CFLAGS = -O2
+LD = gcc-cris -mlinux -march=v32 -nostdlib
+OBJCOPY = objcopy-cris
+OBJCOPYFLAGS = -O binary --remove-section=.bss
+OBJECTS = $(target)/head.o $(target)/misc.o
+
+# files to compress
+SYSTEM = $(objtree)/vmlinux.bin
+
+all: vmlinuz
+
+$(target)/decompress.bin: $(OBJECTS)
+	$(LD) -T $(src)/decompress.ld -o $(target)/decompress.o $(OBJECTS)
+	$(OBJCOPY) $(OBJCOPYFLAGS) $(target)/decompress.o $(target)/decompress.bin
+
+$(objtree)/vmlinuz: $(target) piggy.img $(target)/decompress.bin
+	cat $(target)/decompress.bin piggy.img > $(objtree)/vmlinuz
+	rm -f piggy.img
+	cp $(objtree)/vmlinuz $(src)
+
+$(target)/head.o: $(src)/head.S
+	$(CC) -D__ASSEMBLY__ -c $< -o $@
+
+# gzip the kernel image
+
+piggy.img: $(SYSTEM)
+	cat $(SYSTEM) | gzip -f -9 > piggy.img
+
+clean:
+	rm -f piggy.img $(objtree)/vmlinuz vmlinuz.o decompress.o decompress.bin $(OBJECTS)
+
diff --git a/arch/cris/arch-v32/boot/compressed/README b/arch/cris/arch-v32/boot/compressed/README
new file mode 100644
--- /dev/null
+++ b/arch/cris/arch-v32/boot/compressed/README
@@ -0,0 +1,25 @@
+Creation of the self-extracting compressed kernel image (vmlinuz)
+-----------------------------------------------------------------
+$Id: README,v 1.1 2003/08/21 09:37:03 johana Exp $
+
+This can be slightly confusing because it's a process with many steps.
+
+The kernel object built by the arch/etrax100/Makefile, vmlinux, is split
+by that makefile into text and data binary files, vmlinux.text and
+vmlinux.data.
+
+Those files together with a ROM filesystem can be catted together and
+burned into a flash or executed directly at the DRAM origin.
+
+They can also be catted together and compressed with gzip, which is what
+happens in this makefile. Together they make up piggy.img.
+
+The decompressor is built into the file decompress.o. It is turned into
+the binary file decompress.bin, which is catted together with piggy.img
+into the file vmlinuz. It can be executed in an arbitrary place in flash.
+
+Be careful - it assumes some things about free locations in DRAM. It
+assumes the DRAM starts at 0x40000000 and that it is at least 8 MB,
+so it puts its code at 0x40700000, and initial stack at 0x40800000.
+
+-Bjorn
diff --git a/arch/cris/arch-v32/boot/compressed/decompress.ld b/arch/cris/arch-v32/boot/compressed/decompress.ld
new file mode 100644
--- /dev/null
+++ b/arch/cris/arch-v32/boot/compressed/decompress.ld
@@ -0,0 +1,30 @@
+/*#OUTPUT_FORMAT(elf32-us-cris) */
+OUTPUT_ARCH (crisv32)
+
+MEMORY
+	{
+	dram : ORIGIN = 0x40700000,
+	       LENGTH = 0x00100000
+	}
+
+SECTIONS
+{
+	.text :
+	{
+		_stext = . ;
+		*(.text)
+		*(.rodata)
+		*(.rodata.*)
+		_etext = . ;
+	} > dram
+	.data :
+	{
+		*(.data)
+		_edata = . ;
+	} > dram
+	.bss :
+	{
+		*(.bss)
+		_end = ALIGN( 0x10 ) ;
+	} > dram
+}
diff --git a/arch/cris/arch-v32/boot/compressed/head.S b/arch/cris/arch-v32/boot/compressed/head.S
new file mode 100644
--- /dev/null
+++ b/arch/cris/arch-v32/boot/compressed/head.S
@@ -0,0 +1,193 @@
+/*
+ *  Code that sets up the DRAM registers, calls the
+ *  decompressor to unpack the piggybacked kernel, and jumps.
+ *
+ *  Copyright (C) 1999 - 2003, Axis Communications AB
+ */
+
+#include <linux/config.h>
+#define ASSEMBLER_MACROS_ONLY
+#include <asm/arch/hwregs/asm/reg_map_asm.h>
+#include <asm/arch/hwregs/asm/gio_defs_asm.h>
+#include <asm/arch/hwregs/asm/config_defs_asm.h>
+
+#define RAM_INIT_MAGIC 0x56902387
+#define COMMAND_LINE_MAGIC 0x87109563
+
+	;; Exported symbols
+
+	.globl	input_data
+
+	.text
+start:
+	di
+
+	;; Start clocks for used blocks.
+	move.d REG_ADDR(config, regi_config, rw_clk_ctrl), $r1
+	move.d [$r1], $r0
+	or.d   REG_STATE(config, rw_clk_ctrl, cpu, yes) | \
+	       REG_STATE(config, rw_clk_ctrl, bif, yes) | \
+	       REG_STATE(config, rw_clk_ctrl, fix_io, yes), $r0
+	move.d $r0, [$r1]
+
+	;; If booting from NAND flash we first have to copy some
+	;; data from NAND flash to internal RAM to get the code
+	;; that initializes the SDRAM. Lets copy 20 KB. This
+	;; code executes at 0x38010000 if booting from NAND and
+	;; we are guaranted that at least 0x200 bytes are good so
+	;; lets start from there. The first 8192 bytes in the nand
+	;; flash is spliced with zeroes and is thus 16384 bytes.
+	move.d 0x38010200, $r10
+	move.d 0x14200, $r11	; Start offset in NAND flash 0x10200 + 16384
+	move.d 0x5000, $r12	; Length of copy
+
+	;; Before this code the tools add a partitiontable so the PC
+	;; has an offset from the linked address.
+offset1:
+	lapcq  ., $r13		; get PC
+	add.d	first_copy_complete-offset1, $r13
+
+#include "../../lib/nand_init.S"
+
+first_copy_complete:
+	;; Initialze the DRAM registers.
+	cmp.d	RAM_INIT_MAGIC, $r8	; Already initialized?
+	beq	dram_init_finished
+	nop
+
+#include "../../lib/dram_init.S"
+
+dram_init_finished:
+	lapcq  ., $r13		; get PC
+	add.d	second_copy_complete-dram_init_finished, $r13
+
+	move.d REG_ADDR(config, regi_config, r_bootsel), $r0
+	move.d [$r0], $r0
+	and.d  REG_MASK(config, r_bootsel, boot_mode), $r0
+	cmp.d  REG_STATE(config, r_bootsel, boot_mode, nand), $r0
+	bne second_copy_complete ; No NAND boot
+	nop
+
+	;; Copy 2MB from NAND flash to SDRAM (at 2-4MB into the SDRAM)
+	move.d 0x40204000, $r10
+	move.d 0x8000, $r11
+	move.d 0x200000, $r12
+	ba copy_nand_to_ram
+	nop
+second_copy_complete:
+
+	;; Initiate the PA port.
+	move.d	CONFIG_ETRAX_DEF_GIO_PA_OUT, $r0
+	move.d	REG_ADDR(gio, regi_gio, rw_pa_dout), $r1
+	move.d	$r0, [$r1]
+
+	move.d	CONFIG_ETRAX_DEF_GIO_PA_OE, $r0
+	move.d	REG_ADDR(gio, regi_gio, rw_pa_oe), $r1
+	move.d	$r0, [$r1]
+
+	;; Setup the stack to a suitably high address.
+	;; We assume 8 MB is the minimum DRAM and put
+	;; the SP at the top for now.
+
+	move.d	0x40800000, $sp
+
+	;; Figure out where the compressed piggyback image is
+	;; in the flash (since we wont try to copy it to DRAM
+	;; before unpacking). It is at _edata, but in flash.
+	;; Use (_edata - herami) as offset to the current PC.
+
+	move.d REG_ADDR(config, regi_config, r_bootsel), $r0
+	move.d [$r0], $r0
+	and.d  REG_MASK(config, r_bootsel, boot_mode), $r0
+	cmp.d  REG_STATE(config, r_bootsel, boot_mode, nand), $r0
+	beq hereami2
+	nop
+hereami:
+	lapcq	., $r5		; get PC
+	and.d	0x7fffffff, $r5	; strip any non-cache bit
+	move.d	$r5, $r0	; save for later - flash address of 'herami'
+	add.d	_edata, $r5
+	sub.d	hereami, $r5	; r5 = flash address of '_edata'
+	move.d	hereami, $r1	; destination
+	ba 2f
+	nop
+hereami2:
+	lapcq	., $r5		; get PC
+	and.d	0x00ffffff, $r5	; strip any non-cache bit
+	move.d  $r5, $r6
+	or.d    0x40200000, $r6
+	move.d	$r6, $r0	; save for later - flash address of 'herami'
+	add.d	_edata, $r5
+	sub.d	hereami2, $r5	; r5 = flash address of '_edata'
+	add.d   0x40200000, $r5
+	move.d	hereami2, $r1	; destination
+2:
+	;; Copy text+data to DRAM
+
+	move.d	_edata, $r2	; end destination
+1:	move.w	[$r0+], $r3
+	move.w	$r3, [$r1+]
+	cmp.d	$r2, $r1
+	bcs	1b
+	nop
+
+	move.d	input_data, $r0 ; for the decompressor
+	move.d	$r5, [$r0]	; for the decompressor
+
+	;; Clear the decompressors BSS (between _edata and _end)
+
+	moveq	0, $r0
+	move.d	_edata, $r1
+	move.d	_end, $r2
+1:	move.w	$r0, [$r1+]
+	cmp.d	$r2, $r1
+	bcs	1b
+	nop
+
+	;;  Save command line magic and address.
+	move.d	_cmd_line_magic, $r12
+	move.d  $r10, [$r12]
+	move.d	_cmd_line_addr, $r12
+	move.d  $r11, [$r12]
+
+	;; Do the decompression and save compressed size in _inptr
+
+	jsr	decompress_kernel
+	nop
+
+	;; Restore command line magic and address.
+	move.d  _cmd_line_magic, $r10
+	move.d  [$r10], $r10
+	move.d  _cmd_line_addr, $r11
+	move.d  [$r11], $r11
+
+	;; Put start address of root partition in r9 so the kernel can use it
+	;; when mounting from flash
+	move.d  input_data, $r0
+	move.d	[$r0], $r9		; flash address of compressed kernel
+	move.d  inptr, $r0
+	add.d	[$r0], $r9		; size of compressed kernel
+	cmp.d   0x40200000, $r9
+	blo	enter_kernel
+	nop
+	sub.d   0x40200000, $r9
+	add.d   0x4000, $r9
+
+enter_kernel:
+	;; Enter the decompressed kernel
+	move.d	RAM_INIT_MAGIC, $r8	; Tell kernel that DRAM is initialized
+	jump	0x40004000	; kernel is linked to this address
+	nop
+
+	.data
+
+input_data:
+	.dword	0		; used by the decompressor
+_cmd_line_magic:
+	.dword 0
+_cmd_line_addr:
+	.dword 0
+is_nand_boot:
+	.dword  0
+
+#include "../../lib/hw_settings.S"
diff --git a/arch/cris/arch-v32/boot/compressed/misc.c b/arch/cris/arch-v32/boot/compressed/misc.c
new file mode 100644
--- /dev/null
+++ b/arch/cris/arch-v32/boot/compressed/misc.c
@@ -0,0 +1,318 @@
+/*
+ * misc.c
+ *
+ * $Id: misc.c,v 1.8 2005/04/24 18:34:29 starvik Exp $
+ *
+ * This is a collection of several routines from gzip-1.0.3
+ * adapted for Linux.
+ *
+ * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
+ * puts by Nick Holloway 1993, better puts by Martin Mares 1995
+ * adoptation for Linux/CRIS Axis Communications AB, 1999
+ *
+ */
+
+/* where the piggybacked kernel image expects itself to live.
+ * it is the same address we use when we network load an uncompressed
+ * image into DRAM, and it is the address the kernel is linked to live
+ * at by vmlinux.lds.S
+ */
+
+#define KERNEL_LOAD_ADR 0x40004000
+
+#include <linux/config.h>
+
+#include <linux/types.h>
+#include <asm/arch/hwregs/reg_rdwr.h>
+#include <asm/arch/hwregs/reg_map.h>
+#include <asm/arch/hwregs/ser_defs.h>
+
+/*
+ * gzip declarations
+ */
+
+#define OF(args)  args
+#define STATIC static
+
+void* memset(void* s, int c, size_t n);
+void* memcpy(void* __dest, __const void* __src,
+	     size_t __n);
+
+#define memzero(s, n)     memset ((s), 0, (n))
+
+
+typedef unsigned char  uch;
+typedef unsigned short ush;
+typedef unsigned long  ulg;
+
+#define WSIZE 0x8000		/* Window size must be at least 32k, */
+				/* and a power of two */
+
+static uch *inbuf;	     /* input buffer */
+static uch window[WSIZE];    /* Sliding window buffer */
+
+unsigned inptr = 0;	/* index of next byte to be processed in inbuf
+			 * After decompression it will contain the
+			 * compressed size, and head.S will read it.
+			 */
+
+static unsigned outcnt = 0;  /* bytes in output buffer */
+
+/* gzip flag byte */
+#define ASCII_FLAG   0x01 /* bit 0 set: file probably ascii text */
+#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */
+#define EXTRA_FIELD  0x04 /* bit 2 set: extra field present */
+#define ORIG_NAME    0x08 /* bit 3 set: original file name present */
+#define COMMENT      0x10 /* bit 4 set: file comment present */
+#define ENCRYPTED    0x20 /* bit 5 set: file is encrypted */
+#define RESERVED     0xC0 /* bit 6,7:   reserved */
+
+#define get_byte() inbuf[inptr++]
+
+/* Diagnostic functions */
+#ifdef DEBUG
+#  define Assert(cond,msg) {if(!(cond)) error(msg);}
+#  define Trace(x) fprintf x
+#  define Tracev(x) {if (verbose) fprintf x ;}
+#  define Tracevv(x) {if (verbose>1) fprintf x ;}
+#  define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
+#  define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
+#else
+#  define Assert(cond,msg)
+#  define Trace(x)
+#  define Tracev(x)
+#  define Tracevv(x)
+#  define Tracec(c,x)
+#  define Tracecv(c,x)
+#endif
+
+static int  fill_inbuf(void);
+static void flush_window(void);
+static void error(char *m);
+static void gzip_mark(void **);
+static void gzip_release(void **);
+
+extern char *input_data;  /* lives in head.S */
+
+static long bytes_out = 0;
+static uch *output_data;
+static unsigned long output_ptr = 0;
+
+static void *malloc(int size);
+static void free(void *where);
+static void error(char *m);
+static void gzip_mark(void **);
+static void gzip_release(void **);
+
+static void puts(const char *);
+
+/* the "heap" is put directly after the BSS ends, at end */
+
+extern int _end;
+static long free_mem_ptr = (long)&_end;
+
+#include "../../../../../lib/inflate.c"
+
+static void *malloc(int size)
+{
+	void *p;
+
+	if (size <0) error("Malloc error");
+
+	free_mem_ptr = (free_mem_ptr + 3) & ~3;	/* Align */
+
+	p = (void *)free_mem_ptr;
+	free_mem_ptr += size;
+
+	return p;
+}
+
+static void free(void *where)
+{	/* Don't care */
+}
+
+static void gzip_mark(void **ptr)
+{
+	*ptr = (void *) free_mem_ptr;
+}
+
+static void gzip_release(void **ptr)
+{
+	free_mem_ptr = (long) *ptr;
+}
+
+/* decompressor info and error messages to serial console */
+
+static inline void
+serout(const char *s, reg_scope_instances regi_ser)
+{
+	reg_ser_rs_stat_din rs;
+	reg_ser_rw_dout dout = {.data = *s};
+
+	do {
+		rs = REG_RD(ser, regi_ser, rs_stat_din);
+	}
+	while (!rs.tr_rdy);/* Wait for tranceiver. */
+
+	REG_WR(ser, regi_ser, rw_dout, dout);
+}
+
+static void
+puts(const char *s)
+{
+#ifndef CONFIG_ETRAX_DEBUG_PORT_NULL
+	while (*s) {
+#ifdef CONFIG_ETRAX_DEBUG_PORT0
+		serout(s, regi_ser0);
+#endif
+#ifdef CONFIG_ETRAX_DEBUG_PORT1
+		serout(s, regi_ser1);
+#endif
+#ifdef CONFIG_ETRAX_DEBUG_PORT2
+		serout(s, regi_ser2);
+#endif
+#ifdef CONFIG_ETRAX_DEBUG_PORT3
+		serout(s, regi_ser3);
+#endif
+		*s++;
+	}
+/* CONFIG_ETRAX_DEBUG_PORT_NULL */
+#endif
+}
+
+void*
+memset(void* s, int c, size_t n)
+{
+	int i;
+	char *ss = (char*)s;
+
+	for (i=0;i<n;i++) ss[i] = c;
+}
+
+void*
+memcpy(void* __dest, __const void* __src,
+			    size_t __n)
+{
+	int i;
+	char *d = (char *)__dest, *s = (char *)__src;
+
+	for (i=0;i<__n;i++) d[i] = s[i];
+}
+
+/* ===========================================================================
+ * Write the output window window[0..outcnt-1] and update crc and bytes_out.
+ * (Used for the decompressed data only.)
+ */
+
+static void
+flush_window()
+{
+    ulg c = crc;         /* temporary variable */
+    unsigned n;
+    uch *in, *out, ch;
+
+    in = window;
+    out = &output_data[output_ptr];
+    for (n = 0; n < outcnt; n++) {
+	    ch = *out++ = *in++;
+	    c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
+    }
+    crc = c;
+    bytes_out += (ulg)outcnt;
+    output_ptr += (ulg)outcnt;
+    outcnt = 0;
+}
+
+static void
+error(char *x)
+{
+	puts("\n\n");
+	puts(x);
+	puts("\n\n -- System halted\n");
+
+	while(1);	/* Halt */
+}
+
+void
+setup_normal_output_buffer()
+{
+	output_data = (char *)KERNEL_LOAD_ADR;
+}
+
+static inline void
+serial_setup(reg_scope_instances regi_ser)
+{
+	reg_ser_rw_xoff xoff;
+	reg_ser_rw_tr_ctrl tr_ctrl;
+	reg_ser_rw_rec_ctrl rec_ctrl;
+	reg_ser_rw_tr_baud_div tr_baud;
+	reg_ser_rw_rec_baud_div rec_baud;
+
+	/* Turn off XOFF. */
+	xoff = REG_RD(ser, regi_ser, rw_xoff);
+
+	xoff.chr = 0;
+	xoff.automatic = regk_ser_no;
+
+	REG_WR(ser, regi_ser, rw_xoff, xoff);
+
+	/* Set baudrate and stopbits. */
+	tr_ctrl = REG_RD(ser, regi_ser, rw_tr_ctrl);
+	rec_ctrl = REG_RD(ser, regi_ser, rw_rec_ctrl);
+	tr_baud = REG_RD(ser, regi_ser, rw_tr_baud_div);
+	rec_baud = REG_RD(ser, regi_ser, rw_rec_baud_div);
+
+	tr_ctrl.stop_bits = 1;	/* 2 stop bits. */
+
+	/*
+	 * The baudrate setup is a bit fishy, but in the end the tranceiver is
+	 * set to 4800 and the receiver to 115200. The magic value is
+	 * 29.493 MHz.
+	 */
+	tr_ctrl.base_freq = regk_ser_f29_493;
+	rec_ctrl.base_freq = regk_ser_f29_493;
+	tr_baud.div = (29493000 / 8) / 4800;
+	rec_baud.div = (29493000 / 8) / 115200;
+
+	REG_WR(ser, regi_ser, rw_tr_ctrl, tr_ctrl);
+	REG_WR(ser, regi_ser, rw_tr_baud_div, tr_baud);
+	REG_WR(ser, regi_ser, rw_rec_ctrl, rec_ctrl);
+	REG_WR(ser, regi_ser, rw_rec_baud_div, rec_baud);
+}
+
+void
+decompress_kernel()
+{
+	char revision;
+
+	/* input_data is set in head.S */
+	inbuf = input_data;
+
+#ifdef CONFIG_ETRAX_DEBUG_PORT0
+	serial_setup(regi_ser0);
+#endif
+#ifdef CONFIG_ETRAX_DEBUG_PORT1
+	serial_setup(regi_ser1);
+#endif
+#ifdef CONFIG_ETRAX_DEBUG_PORT2
+	serial_setup(regi_ser2);
+#endif
+#ifdef CONFIG_ETRAX_DEBUG_PORT3
+	serial_setup(regi_ser3);
+#endif
+
+	setup_normal_output_buffer();
+
+	makecrc();
+
+	__asm__ volatile ("move $vr,%0" : "=rm" (revision));
+	if (revision < 32)
+	{
+		puts("You need an ETRAX FS to run Linux 2.6/crisv32.\n");
+		while(1);
+	}
+
+	puts("Uncompressing Linux...\n");
+	gunzip();
+	puts("Done. Now booting the kernel.\n");
+}
diff --git a/arch/cris/arch-v32/boot/rescue/Makefile b/arch/cris/arch-v32/boot/rescue/Makefile
new file mode 100644
--- /dev/null
+++ b/arch/cris/arch-v32/boot/rescue/Makefile
@@ -0,0 +1,36 @@
+#
+# Makefile for rescue code
+#
+target = $(target_rescue_dir)
+src    = $(src_rescue_dir)
+
+CC = gcc-cris -mlinux -march=v32 $(LINUXINCLUDE)
+CFLAGS = -O2
+LD = gcc-cris -mlinux -march=v32 -nostdlib
+OBJCOPY = objcopy-cris
+OBJCOPYFLAGS = -O binary --remove-section=.bss
+
+all: $(target)/rescue.bin
+
+rescue: rescue.bin
+	# do nothing
+
+$(target)/rescue.bin: $(target) $(target)/head.o
+	$(LD) -T $(src)/rescue.ld -o $(target)/rescue.o $(target)/head.o
+	$(OBJCOPY) $(OBJCOPYFLAGS) $(target)/rescue.o $(target)/rescue.bin
+	cp -p $(target)/rescue.bin $(objtree)
+
+$(target):
+	mkdir -p $(target)
+
+$(target)/head.o: $(src)/head.S
+	$(CC) -D__ASSEMBLY__ -c $< -o $*.o
+
+clean:
+	rm -f $(target)/*.o $(target)/*.bin
+
+fastdep:
+
+modules:
+
+modules-install:
diff --git a/arch/cris/arch-v32/boot/rescue/head.S b/arch/cris/arch-v32/boot/rescue/head.S
new file mode 100644
--- /dev/null
+++ b/arch/cris/arch-v32/boot/rescue/head.S
@@ -0,0 +1,39 @@
+/* $Id: head.S,v 1.4 2004/11/01 16:10:28 starvik Exp $
+ *
+ * This used to be the rescue code but now that is handled by the
+ * RedBoot based RFL instead. Nothing to see here, move along.
+ */
+
+#include <linux/config.h>
+#include <asm/arch/hwregs/reg_map_asm.h>
+#include <asm/arch/hwregs/config_defs_asm.h>
+
+	.text
+
+	;; Start clocks for used blocks.
+	move.d REG_ADDR(config, regi_config, rw_clk_ctrl), $r1
+	move.d [$r1], $r0
+	or.d   REG_STATE(config, rw_clk_ctrl, cpu, yes) | \
+	       REG_STATE(config, rw_clk_ctrl, bif, yes) | \
+	       REG_STATE(config, rw_clk_ctrl, fix_io, yes), $r0
+	move.d $r0, [$r1]
+
+	;; Copy 68KB NAND flash to Internal RAM (if NAND boot)
+	move.d 0x38004000, $r10
+	move.d 0x8000, $r11
+	move.d 0x11000, $r12
+	move.d copy_complete, $r13
+	and.d  0x000fffff, $r13
+	or.d   0x38000000, $r13
+
+#include "../../lib/nand_init.S"
+
+	;; No NAND found
+	move.d	CONFIG_ETRAX_PTABLE_SECTOR, $r10
+	jump	$r10 ; Jump to decompresser
+	nop
+
+copy_complete:
+	move.d	0x38000000 + CONFIG_ETRAX_PTABLE_SECTOR, $r10
+	jump	$r10 ; Jump to decompresser
+	nop
diff --git a/arch/cris/arch-v32/boot/rescue/rescue.ld b/arch/cris/arch-v32/boot/rescue/rescue.ld
new file mode 100644
--- /dev/null
+++ b/arch/cris/arch-v32/boot/rescue/rescue.ld
@@ -0,0 +1,20 @@
+MEMORY
+	{
+	flash : ORIGIN = 0x00000000,
+	        LENGTH = 0x00100000
+	}
+
+SECTIONS
+{
+	.text :
+	{
+		stext = . ;
+		*(.text)
+		etext = . ;
+	} > flash
+	.data :
+	{
+		*(.data)
+		edata = . ;
+	} > flash
+}
diff --git a/arch/cris/arch-v32/drivers/Kconfig b/arch/cris/arch-v32/drivers/Kconfig
new file mode 100644
--- /dev/null
+++ b/arch/cris/arch-v32/drivers/Kconfig
@@ -0,0 +1,625 @@
+config ETRAX_ETHERNET
+	bool "Ethernet support"
+	depends on ETRAX_ARCH_V32
+	select NET_ETHERNET
+	help
+	  This option enables the ETRAX FS built-in 10/100Mbit Ethernet
+	  controller.
+
+config ETRAX_ETHERNET_HW_CSUM
+	bool "Hardware accelerated ethernet checksum and scatter/gather"
+	depends on ETRAX_ETHERNET
+	depends on ETRAX_STREAMCOPROC
+	default y
+	help
+	  Hardware acceleration of checksumming and scatter/gather
+
+config ETRAX_ETHERNET_IFACE0
+	depends on ETRAX_ETHERNET
+	bool "Enable network interface 0"
+
+config ETRAX_ETHERNET_IFACE1
+	depends on ETRAX_ETHERNET
+	bool "Enable network interface 1 (uses DMA6 and DMA7)"
+
+choice
+	prompt "Network LED behavior"
+	depends on ETRAX_ETHERNET
+	default ETRAX_NETWORK_LED_ON_WHEN_ACTIVITY
+
+config ETRAX_NETWORK_LED_ON_WHEN_LINK
+	bool "LED_on_when_link"
+	help
+	  Selecting LED_on_when_link will light the LED when there is a
+	  connection and will flash off when there is activity.
+
+	  Selecting LED_on_when_activity will light the LED only when
+	  there is activity.
+
+	  This setting will also affect the behaviour of other activity LEDs
+	  e.g. Bluetooth.
+
+config ETRAX_NETWORK_LED_ON_WHEN_ACTIVITY
+	bool "LED_on_when_activity"
+	help
+	  Selecting LED_on_when_link will light the LED when there is a
+	  connection and will flash off when there is activity.
+
+	  Selecting LED_on_when_activity will light the LED only when
+	  there is activity.
+
+	  This setting will also affect the behaviour of other activity LEDs
+	  e.g. Bluetooth.
+
+endchoice
+
+config ETRAXFS_SERIAL
+	bool "Serial-port support"
+	depends on ETRAX_ARCH_V32
+	help
+	  Enables the ETRAX FS serial driver for ser0 (ttyS0)
+	  You probably want this enabled.
+
+config ETRAX_SERIAL_PORT0
+	bool "Serial port 0 enabled"
+	depends on ETRAXFS_SERIAL
+	help
+	  Enables the ETRAX FS serial driver for ser0 (ttyS0)
+	  Normally you want this on. You can control what DMA channels to use
+	  if you do not need DMA to something else.
+	  ser0 can use dma4 or dma6 for output and dma5 or dma7 for input.
+
+choice
+	prompt "Ser0 DMA in channel "
+	depends on ETRAX_SERIAL_PORT0
+	default ETRAX_SERIAL_PORT0_NO_DMA_IN
+	help
+	  What DMA channel to use for ser0.
+
+
+config ETRAX_SERIAL_PORT0_NO_DMA_IN
+	bool "Ser0 uses no DMA for input"
+	help
+	  Do not use DMA for ser0 input.
+
+config ETRAX_SERIAL_PORT0_DMA7_IN
+	bool "Ser0 uses DMA7 for input"
+	depends on ETRAX_SERIAL_PORT0
+	help
+	  Enables the DMA7 input channel for ser0 (ttyS0).
+	  If you do not enable DMA, an interrupt for each character will be
+	  used when receiveing data.
+	  Normally you want to use DMA, unless you use the DMA channel for
+	  something else.
+
+endchoice
+
+choice
+	prompt "Ser0 DMA out channel"
+	depends on ETRAX_SERIAL_PORT0
+	default ETRAX_SERIAL_PORT0_NO_DMA_OUT
+
+config ETRAX_SERIAL_PORT0_NO_DMA_OUT
+	bool "Ser0 uses no DMA for output"
+	help
+	  Do not use DMA for ser0 output.
+
+config ETRAX_SERIAL_PORT0_DMA6_OUT
+	bool "Ser0 uses DMA6 for output"
+	depends on ETRAX_SERIAL_PORT0
+	help
+	  Enables the DMA6 output channel for ser0 (ttyS0).
+	  If you do not enable DMA, an interrupt for each character will be
+	  used when transmitting data.
+	  Normally you want to use DMA, unless you use the DMA channel for
+	  something else.
+
+endchoice
+
+config ETRAX_SER0_DTR_BIT
+	string "Ser 0 DTR bit (empty = not used)"
+	depends on ETRAX_SERIAL_PORT0
+
+config ETRAX_SER0_RI_BIT
+	string "Ser 0 RI bit (empty = not used)"
+	depends on ETRAX_SERIAL_PORT0
+
+config ETRAX_SER0_DSR_BIT
+	string "Ser 0 DSR bit (empty = not used)"
+	depends on ETRAX_SERIAL_PORT0
+
+config ETRAX_SER0_CD_BIT
+	string "Ser 0 CD bit (empty = not used)"
+	depends on ETRAX_SERIAL_PORT0
+
+config ETRAX_SERIAL_PORT1
+	bool "Serial port 1 enabled"
+	depends on ETRAXFS_SERIAL
+	help
+	  Enables the ETRAX FS serial driver for ser1 (ttyS1).
+
+choice
+	prompt "Ser1 DMA in channel "
+	depends on ETRAX_SERIAL_PORT1
+	default ETRAX_SERIAL_PORT1_NO_DMA_IN
+	help
+	  What DMA channel to use for ser1.
+
+
+config ETRAX_SERIAL_PORT1_NO_DMA_IN
+	bool "Ser1 uses no DMA for input"
+	help
+	  Do not use DMA for ser1 input.
+
+config ETRAX_SERIAL_PORT1_DMA5_IN
+	bool "Ser1 uses DMA5 for input"
+	depends on ETRAX_SERIAL_PORT1
+	help
+	  Enables the DMA5 input channel for ser1 (ttyS1).
+	  If you do not enable DMA, an interrupt for each character will be
+	  used when receiveing data.
+	  Normally you want this on, unless you use the DMA channel for
+	  something else.
+
+endchoice
+
+choice
+	prompt "Ser1 DMA out channel "
+	depends on ETRAX_SERIAL_PORT1
+	default ETRAX_SERIAL_PORT1_NO_DMA_OUT
+	help
+	  What DMA channel to use for ser1.
+
+config ETRAX_SERIAL_PORT1_NO_DMA_OUT
+	bool "Ser1 uses no DMA for output"
+	help
+	  Do not use DMA for ser1 output.
+
+config ETRAX_SERIAL_PORT1_DMA4_OUT
+	bool "Ser1 uses DMA4 for output"
+	depends on ETRAX_SERIAL_PORT1
+	help
+	  Enables the DMA4 output channel for ser1 (ttyS1).
+	  If you do not enable DMA, an interrupt for each character will be
+	  used when transmitting data.
+	  Normally you want this on, unless you use the DMA channel for
+	  something else.
+
+endchoice
+
+config ETRAX_SER1_DTR_BIT
+	string "Ser 1 DTR bit (empty = not used)"
+	depends on ETRAX_SERIAL_PORT1
+
+config ETRAX_SER1_RI_BIT
+	string "Ser 1 RI bit (empty = not used)"
+	depends on ETRAX_SERIAL_PORT1
+
+config ETRAX_SER1_DSR_BIT
+	string "Ser 1 DSR bit (empty = not used)"
+	depends on ETRAX_SERIAL_PORT1
+
+config ETRAX_SER1_CD_BIT
+	string "Ser 1 CD bit (empty = not used)"
+	depends on ETRAX_SERIAL_PORT1
+
+config ETRAX_SERIAL_PORT2
+	bool "Serial port 2 enabled"
+	depends on ETRAXFS_SERIAL
+	help
+	  Enables the ETRAX FS serial driver for ser2 (ttyS2).
+
+choice
+	prompt "Ser2 DMA in channel "
+	depends on ETRAX_SERIAL_PORT2
+	default ETRAX_SERIAL_PORT2_NO_DMA_IN
+	help
+	  What DMA channel to use for ser2.
+
+
+config ETRAX_SERIAL_PORT2_NO_DMA_IN
+	bool "Ser2 uses no DMA for input"
+	help
+	  Do not use DMA for ser2 input.
+
+config ETRAX_SERIAL_PORT2_DMA3_IN
+	bool "Ser2 uses DMA3 for input"
+	depends on ETRAX_SERIAL_PORT2
+	help
+	  Enables the DMA3 input channel for ser2 (ttyS2).
+	  If you do not enable DMA, an interrupt for each character will be
+	  used when receiveing data.
+	  Normally you want to use DMA, unless you use the DMA channel for
+	  something else.
+
+endchoice
+
+choice
+	prompt "Ser2 DMA out channel"
+	depends on ETRAX_SERIAL_PORT2
+	default ETRAX_SERIAL_PORT2_NO_DMA_OUT
+
+config ETRAX_SERIAL_PORT2_NO_DMA_OUT
+	bool "Ser2 uses no DMA for output"
+	help
+	  Do not use DMA for ser2 output.
+
+config ETRAX_SERIAL_PORT2_DMA2_OUT
+	bool "Ser2 uses DMA2 for output"
+	depends on ETRAX_SERIAL_PORT2
+	help
+	  Enables the DMA2 output channel for ser2 (ttyS2).
+	  If you do not enable DMA, an interrupt for each character will be
+	  used when transmitting data.
+	  Normally you want to use DMA, unless you use the DMA channel for
+	  something else.
+
+endchoice
+
+config ETRAX_SER2_DTR_BIT
+	string "Ser 2 DTR bit (empty = not used)"
+	depends on ETRAX_SERIAL_PORT2
+
+config ETRAX_SER2_RI_BIT
+	string "Ser 2 RI bit (empty = not used)"
+	depends on ETRAX_SERIAL_PORT2
+
+config ETRAX_SER2_DSR_BIT
+	string "Ser 2 DSR bit (empty = not used)"
+	depends on ETRAX_SERIAL_PORT2
+
+config ETRAX_SER2_CD_BIT
+	string "Ser 2 CD bit (empty = not used)"
+	depends on ETRAX_SERIAL_PORT2
+
+config ETRAX_SERIAL_PORT3
+	bool "Serial port 3 enabled"
+	depends on ETRAXFS_SERIAL
+	help
+	  Enables the ETRAX FS serial driver for ser3 (ttyS3).
+
+choice
+	prompt "Ser3 DMA in channel "
+	depends on ETRAX_SERIAL_PORT3
+	default ETRAX_SERIAL_PORT3_NO_DMA_IN
+	help
+	  What DMA channel to use for ser3.
+
+
+config ETRAX_SERIAL_PORT3_NO_DMA_IN
+	bool "Ser3 uses no DMA for input"
+	help
+	  Do not use DMA for ser3 input.
+
+config ETRAX_SERIAL_PORT3_DMA9_IN
+	bool "Ser3 uses DMA9 for input"
+	depends on ETRAX_SERIAL_PORT3
+	help
+	  Enables the DMA9 input channel for ser3 (ttyS3).
+	  If you do not enable DMA, an interrupt for each character will be
+	  used when receiveing data.
+	  Normally you want to use DMA, unless you use the DMA channel for
+	  something else.
+
+endchoice
+
+choice
+	prompt "Ser3 DMA out channel"
+	depends on ETRAX_SERIAL_PORT3
+	default ETRAX_SERIAL_PORT3_NO_DMA_OUT
+
+config ETRAX_SERIAL_PORT3_NO_DMA_OUT
+	bool "Ser3 uses no DMA for output"
+	help
+	  Do not use DMA for ser3 output.
+
+config ETRAX_SERIAL_PORT3_DMA8_OUT
+	bool "Ser3 uses DMA8 for output"
+	depends on ETRAX_SERIAL_PORT3
+	help
+	  Enables the DMA8 output channel for ser3 (ttyS3).
+	  If you do not enable DMA, an interrupt for each character will be
+	  used when transmitting data.
+	  Normally you want to use DMA, unless you use the DMA channel for
+	  something else.
+
+endchoice
+
+config ETRAX_SER3_DTR_BIT
+	string "Ser 3 DTR bit (empty = not used)"
+	depends on ETRAX_SERIAL_PORT3
+
+config ETRAX_SER3_RI_BIT
+	string "Ser 3 RI bit (empty = not used)"
+	depends on ETRAX_SERIAL_PORT3
+
+config ETRAX_SER3_DSR_BIT
+	string "Ser 3 DSR bit (empty = not used)"
+	depends on ETRAX_SERIAL_PORT3
+
+config ETRAX_SER3_CD_BIT
+	string "Ser 3 CD bit (empty = not used)"
+	depends on ETRAX_SERIAL_PORT3
+
+config ETRAX_RS485
+	bool "RS-485 support"
+	depends on ETRAX_SERIAL
+	help
+	  Enables support for RS-485 serial communication.  For a primer on
+	  RS-485, see <http://www.hw.cz/english/docs/rs485/rs485.html>.
+
+config ETRAX_RS485_DISABLE_RECEIVER
+	bool "Disable serial receiver"
+	depends on ETRAX_RS485
+	help
+	  It is necessary to disable the serial receiver to avoid serial
+	  loopback.  Not all products are able to do this in software only.
+	  Axis 2400/2401 must disable receiver.
+
+config ETRAX_AXISFLASHMAP
+	bool "Axis flash-map support"
+	depends on ETRAX_ARCH_V32
+	select MTD
+	select MTD_CFI
+	select MTD_CFI_AMDSTD
+	select MTD_OBSOLETE_CHIPS
+	select MTD_AMDSTD
+	select MTD_CHAR
+	select MTD_BLOCK
+	select MTD_PARTITIONS
+	select MTD_CONCAT
+	select MTD_COMPLEX_MAPPINGS
+	help
+	  This option enables MTD mapping of flash devices.  Needed to use
+	  flash memories.  If unsure, say Y.
+
+config ETRAX_SYNCHRONOUS_SERIAL
+	bool "Synchronous serial-port support"
+	depends on ETRAX_ARCH_V32
+	help
+	  Enables the ETRAX FS synchronous serial driver.
+
+config ETRAX_SYNCHRONOUS_SERIAL_PORT0
+         bool "Synchronous serial port 0 enabled"
+         depends on ETRAX_SYNCHRONOUS_SERIAL
+         help
+           Enabled synchronous serial port 0.
+
+config ETRAX_SYNCHRONOUS_SERIAL0_DMA
+         bool "Enable DMA on synchronous serial port 0."
+         depends on ETRAX_SYNCHRONOUS_SERIAL_PORT0
+         help
+           A synchronous serial port can run in manual or DMA mode.
+           Selecting this option will make it run in DMA mode.
+
+config ETRAX_SYNCHRONOUS_SERIAL_PORT1
+         bool "Synchronous serial port 1 enabled"
+         depends on ETRAX_SYNCHRONOUS_SERIAL
+         help
+           Enabled synchronous serial port 1.
+
+config ETRAX_SYNCHRONOUS_SERIAL1_DMA
+         bool "Enable DMA on synchronous serial port 1."
+         depends on ETRAX_SYNCHRONOUS_SERIAL_PORT1
+         help
+           A synchronous serial port can run in manual or DMA mode.
+           Selecting this option will make it run in DMA mode.
+
+config ETRAX_PTABLE_SECTOR
+	int "Byte-offset of partition table sector"
+	depends on ETRAX_AXISFLASHMAP
+	default "65536"
+	help
+	  Byte-offset of the partition table in the first flash chip.
+	  The default value is 64kB and should not be changed unless
+	  you know exactly what you are doing. The only valid reason
+	  for changing this is when the flash block size is bigger
+	  than 64kB (e.g. when using two parallel 16 bit flashes).
+
+config ETRAX_NANDFLASH
+	bool "NAND flash support"
+	depends on ETRAX_ARCH_V32
+	select MTD_NAND
+	select MTD_NAND_IDS
+	help
+	  This option enables MTD mapping of NAND flash devices.  Needed to use
+	  NAND flash memories.  If unsure, say Y.
+
+config ETRAX_I2C
+	bool "I2C driver"
+	depends on ETRAX_ARCH_V32
+	help
+	  This option enabled the I2C driver used by e.g. the RTC driver.
+
+config ETRAX_I2C_DATA_PORT
+	string "I2C data pin"
+	depends on ETRAX_I2C
+	help
+	  The pin to use for I2C data.
+
+config ETRAX_I2C_CLK_PORT
+	string "I2C clock pin"
+	depends on ETRAX_I2C
+	help
+	  The pin to use for I2C clock.
+
+config ETRAX_RTC
+	bool "Real Time Clock support"
+	depends on ETRAX_ARCH_V32
+	help
+	  Enabled RTC support.
+
+choice
+	prompt "RTC chip"
+	depends on ETRAX_RTC
+	default ETRAX_PCF8563
+
+config ETRAX_PCF8563
+	bool "PCF8563"
+	help
+	  Philips PCF8563 RTC
+
+endchoice
+
+config ETRAX_GPIO
+	bool "GPIO support"
+	depends on ETRAX_ARCH_V32
+	---help---
+	  Enables the ETRAX general port device (major 120, minors 0-4).
+	  You can use this driver to access the general port bits. It supports
+	  these ioctl's:
+	  #include <linux/etraxgpio.h>
+	  fd = open("/dev/gpioa", O_RDWR); // or /dev/gpiob
+	  ioctl(fd, _IO(ETRAXGPIO_IOCTYPE, IO_SETBITS), bits_to_set);
+	  ioctl(fd, _IO(ETRAXGPIO_IOCTYPE, IO_CLRBITS), bits_to_clear);
+	  err = ioctl(fd, _IO(ETRAXGPIO_IOCTYPE, IO_READ_INBITS), &val);
+	  Remember that you need to setup the port directions appropriately in
+	  the General configuration.
+
+config ETRAX_PA_BUTTON_BITMASK
+	hex "PA-buttons bitmask"
+	depends on ETRAX_GPIO
+	default "0x02"
+	help
+	  This is a bitmask (8 bits) with information about what bits on PA
+	  that are used for buttons.
+	  Most products has a so called TEST button on PA1, if that is true
+	  use 0x02 here.
+	  Use 00 if there are no buttons on PA.
+	  If the bitmask is <> 00 a button driver will be included in the gpio
+	  driver. ETRAX general I/O support must be enabled.
+
+config ETRAX_PA_CHANGEABLE_DIR
+	hex "PA user changeable dir mask"
+	depends on ETRAX_GPIO
+	default "0x00"
+	help
+	  This is a bitmask (8 bits) with information of what bits in PA that a
+	  user can change direction on using ioctl's.
+	  Bit set = changeable.
+	  You probably want 0x00 here, but it depends on your hardware.
+
+config ETRAX_PA_CHANGEABLE_BITS
+	hex "PA user changeable bits mask"
+	depends on ETRAX_GPIO
+	default "0x00"
+	help
+	  This is a bitmask (8 bits) with information of what bits in PA
+	  that a user can change the value on using ioctl's.
+	  Bit set = changeable.
+
+config ETRAX_PB_CHANGEABLE_DIR
+	hex "PB user changeable dir mask"
+	depends on ETRAX_GPIO
+	default "0x00000"
+	help
+	  This is a bitmask (18 bits) with information of what bits in PB
+	  that a user can change direction on using ioctl's.
+	  Bit set = changeable.
+	  You probably want 0x00000 here, but it depends on your hardware.
+
+config ETRAX_PB_CHANGEABLE_BITS
+	hex "PB user changeable bits mask"
+	depends on ETRAX_GPIO
+	default "0x00000"
+	help
+	  This is a bitmask (18 bits) with information of what bits in PB
+	  that a user can change the value on using ioctl's.
+	  Bit set = changeable.
+
+config ETRAX_PC_CHANGEABLE_DIR
+	hex "PC user changeable dir mask"
+	depends on ETRAX_GPIO
+	default "0x00000"
+	help
+	  This is a bitmask (18 bits) with information of what bits in PC
+	  that a user can change direction on using ioctl's.
+	  Bit set = changeable.
+	  You probably want 0x00000 here, but it depends on your hardware.
+
+config ETRAX_PC_CHANGEABLE_BITS
+	hex "PC user changeable bits mask"
+	depends on ETRAX_GPIO
+	default "0x00000"
+	help
+	  This is a bitmask (18 bits) with information of what bits in PC
+	  that a user can change the value on using ioctl's.
+	  Bit set = changeable.
+
+config ETRAX_PD_CHANGEABLE_DIR
+	hex "PD user changeable dir mask"
+	depends on ETRAX_GPIO
+	default "0x00000"
+	help
+	  This is a bitmask (18 bits) with information of what bits in PD
+	  that a user can change direction on using ioctl's.
+	  Bit set = changeable.
+	  You probably want 0x00000 here, but it depends on your hardware.
+
+config ETRAX_PD_CHANGEABLE_BITS
+	hex "PD user changeable bits mask"
+	depends on ETRAX_GPIO
+	default "0x00000"
+	help
+	  This is a bitmask (18 bits) with information of what bits in PD
+	  that a user can change the value on using ioctl's.
+	  Bit set = changeable.
+
+config ETRAX_PE_CHANGEABLE_DIR
+	hex "PE user changeable dir mask"
+	depends on ETRAX_GPIO
+	default "0x00000"
+	help
+	  This is a bitmask (18 bits) with information of what bits in PE
+	  that a user can change direction on using ioctl's.
+	  Bit set = changeable.
+	  You probably want 0x00000 here, but it depends on your hardware.
+
+config ETRAX_PE_CHANGEABLE_BITS
+	hex "PE user changeable bits mask"
+	depends on ETRAX_GPIO
+	default "0x00000"
+	help
+	  This is a bitmask (18 bits) with information of what bits in PE
+	  that a user can change the value on using ioctl's.
+	  Bit set = changeable.
+
+config ETRAX_IDE
+	bool "ATA/IDE support"
+	depends on ETRAX_ARCH_V32
+	select IDE
+	select BLK_DEV_IDE
+	select BLK_DEV_IDEDISK
+	select BLK_DEV_IDECD
+	select BLK_DEV_IDEDMA
+	help
+	  Enables the ETRAX IDE driver.
+
+config ETRAX_CARDBUS
+        bool "Cardbus support"
+        depends on ETRAX_ARCH_V32
+        select PCCARD
+        select CARDBUS
+        select HOTPLUG
+        select PCCARD_NONSTATIC
+        help
+	 Enabled the ETRAX Carbus driver.
+
+config PCI
+       bool
+       depends on ETRAX_CARDBUS
+       default y
+
+config ETRAX_IOP_FW_LOAD
+	tristate "IO-processor hotplug firmware loading support"
+	depends on ETRAX_ARCH_V32
+	select FW_LOADER
+	help
+	  Enables IO-processor hotplug firmware loading support.
+
+config ETRAX_STREAMCOPROC
+	tristate "Stream co-processor driver enabled"
+	depends on ETRAX_ARCH_V32
+	help
+	  This option enables a driver for the stream co-processor
+	  for cryptographic operations.
diff --git a/arch/cris/arch-v32/drivers/Makefile b/arch/cris/arch-v32/drivers/Makefile
new file mode 100644
--- /dev/null
+++ b/arch/cris/arch-v32/drivers/Makefile
@@ -0,0 +1,13 @@
+#
+# Makefile for Etrax-specific drivers
+#
+
+obj-$(CONFIG_ETRAX_STREAMCOPROC)        += cryptocop.o
+obj-$(CONFIG_ETRAX_AXISFLASHMAP)        += axisflashmap.o
+obj-$(CONFIG_ETRAX_NANDFLASH)           += nandflash.o
+obj-$(CONFIG_ETRAX_GPIO) 	        += gpio.o
+obj-$(CONFIG_ETRAX_IOP_FW_LOAD)         += iop_fw_load.o
+obj-$(CONFIG_ETRAX_PCF8563)		+= pcf8563.o
+obj-$(CONFIG_ETRAX_I2C)			+= i2c.o
+obj-$(CONFIG_ETRAX_SYNCHRONOUS_SERIAL)	+= sync_serial.o
+obj-$(CONFIG_PCI)			+= pci/
diff --git a/arch/cris/arch-v32/drivers/axisflashmap.c b/arch/cris/arch-v32/drivers/axisflashmap.c
new file mode 100644
--- /dev/null
+++ b/arch/cris/arch-v32/drivers/axisflashmap.c
@@ -0,0 +1,455 @@
+/*
+ * Physical mapping layer for MTD using the Axis partitiontable format
+ *
+ * Copyright (c) 2001, 2002, 2003 Axis Communications AB
+ *
+ * This file is under the GPL.
+ *
+ * First partition is always sector 0 regardless of if we find a partitiontable
+ * or not. In the start of the next sector, there can be a partitiontable that
+ * tells us what other partitions to define. If there isn't, we use a default
+ * partition split defined below.
+ *
+ * Copy of os/lx25/arch/cris/arch-v10/drivers/axisflashmap.c 1.5
+ * with minor changes.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/config.h>
+#include <linux/init.h>
+
+#include <linux/mtd/concat.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/mtdram.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/arch/hwregs/config_defs.h>
+#include <asm/axisflashmap.h>
+#include <asm/mmu.h>
+
+#define MEM_CSE0_SIZE (0x04000000)
+#define MEM_CSE1_SIZE (0x04000000)
+
+#define FLASH_UNCACHED_ADDR  KSEG_E
+#define FLASH_CACHED_ADDR    KSEG_F
+
+#if CONFIG_ETRAX_FLASH_BUSWIDTH==1
+#define flash_data __u8
+#elif CONFIG_ETRAX_FLASH_BUSWIDTH==2
+#define flash_data __u16
+#elif CONFIG_ETRAX_FLASH_BUSWIDTH==4
+#define flash_data __u16
+#endif
+
+/* From head.S */
+extern unsigned long romfs_start, romfs_length, romfs_in_flash;
+
+/* The master mtd for the entire flash. */
+struct mtd_info* axisflash_mtd = NULL;
+
+/* Map driver functions. */
+
+static map_word flash_read(struct map_info *map, unsigned long ofs)
+{
+	map_word tmp;
+	tmp.x[0] = *(flash_data *)(map->map_priv_1 + ofs);
+	return tmp;
+}
+
+static void flash_copy_from(struct map_info *map, void *to,
+			    unsigned long from, ssize_t len)
+{
+	memcpy(to, (void *)(map->map_priv_1 + from), len);
+}
+
+static void flash_write(struct map_info *map, map_word d, unsigned long adr)
+{
+	*(flash_data *)(map->map_priv_1 + adr) = (flash_data)d.x[0];
+}
+
+/*
+ * The map for chip select e0.
+ *
+ * We run into tricky coherence situations if we mix cached with uncached
+ * accesses to we only use the uncached version here.
+ *
+ * The size field is the total size where the flash chips may be mapped on the
+ * chip select. MTD probes should find all devices there and it does not matter
+ * if there are unmapped gaps or aliases (mirrors of flash devices). The MTD
+ * probes will ignore them.
+ *
+ * The start address in map_priv_1 is in virtual memory so we cannot use
+ * MEM_CSE0_START but must rely on that FLASH_UNCACHED_ADDR is the start
+ * address of cse0.
+ */
+static struct map_info map_cse0 = {
+	.name = "cse0",
+	.size = MEM_CSE0_SIZE,
+	.bankwidth = CONFIG_ETRAX_FLASH_BUSWIDTH,
+	.read = flash_read,
+	.copy_from = flash_copy_from,
+	.write = flash_write,
+	.map_priv_1 = FLASH_UNCACHED_ADDR
+};
+
+/*
+ * The map for chip select e1.
+ *
+ * If there was a gap between cse0 and cse1, map_priv_1 would get the wrong
+ * address, but there isn't.
+ */
+static struct map_info map_cse1 = {
+	.name = "cse1",
+	.size = MEM_CSE1_SIZE,
+	.bankwidth = CONFIG_ETRAX_FLASH_BUSWIDTH,
+	.read = flash_read,
+	.copy_from = flash_copy_from,
+	.write = flash_write,
+	.map_priv_1 = FLASH_UNCACHED_ADDR + MEM_CSE0_SIZE
+};
+
+/* If no partition-table was found, we use this default-set. */
+#define MAX_PARTITIONS         7
+#define NUM_DEFAULT_PARTITIONS 3
+
+/*
+ * Default flash size is 2MB. CONFIG_ETRAX_PTABLE_SECTOR is most likely the
+ * size of one flash block and "filesystem"-partition needs 5 blocks to be able
+ * to use JFFS.
+ */
+static struct mtd_partition axis_default_partitions[NUM_DEFAULT_PARTITIONS] = {
+	{
+		.name = "boot firmware",
+		.size = CONFIG_ETRAX_PTABLE_SECTOR,
+		.offset = 0
+	},
+	{
+		.name = "kernel",
+		.size = 0x200000 - (6 * CONFIG_ETRAX_PTABLE_SECTOR),
+		.offset = CONFIG_ETRAX_PTABLE_SECTOR
+	},
+	{
+		.name = "filesystem",
+		.size = 5 * CONFIG_ETRAX_PTABLE_SECTOR,
+		.offset = 0x200000 - (5 * CONFIG_ETRAX_PTABLE_SECTOR)
+	}
+};
+
+/* Initialize the ones normally used. */
+static struct mtd_partition axis_partitions[MAX_PARTITIONS] = {
+	{
+		.name = "part0",
+		.size = CONFIG_ETRAX_PTABLE_SECTOR,
+		.offset = 0
+	},
+	{
+		.name = "part1",
+		.size = 0,
+		.offset = 0
+	},
+	{
+		.name = "part2",
+		.size = 0,
+		.offset = 0
+	},
+	{
+		.name = "part3",
+		.size = 0,
+		.offset = 0
+	},
+	{
+		.name = "part4",
+		.size = 0,
+		.offset = 0
+	},
+	{
+		.name = "part5",
+		.size = 0,
+		.offset = 0
+	},
+	{
+		.name = "part6",
+		.size = 0,
+		.offset = 0
+	},
+};
+
+/*
+ * Probe a chip select for AMD-compatible (JEDEC) or CFI-compatible flash
+ * chips in that order (because the amd_flash-driver is faster).
+ */
+static struct mtd_info *probe_cs(struct map_info *map_cs)
+{
+	struct mtd_info *mtd_cs = NULL;
+
+	printk(KERN_INFO
+	       "%s: Probing a 0x%08lx bytes large window at 0x%08lx.\n",
+	       map_cs->name, map_cs->size, map_cs->map_priv_1);
+
+#ifdef CONFIG_MTD_AMDSTD
+	mtd_cs = do_map_probe("amd_flash", map_cs);
+#endif
+#ifdef CONFIG_MTD_CFI
+	if (!mtd_cs) {
+		mtd_cs = do_map_probe("cfi_probe", map_cs);
+	}
+#endif
+
+	return mtd_cs;
+}
+
+/*
+ * Probe each chip select individually for flash chips. If there are chips on
+ * both cse0 and cse1, the mtd_info structs will be concatenated to one struct
+ * so that MTD partitions can cross chip boundries.
+ *
+ * The only known restriction to how you can mount your chips is that each
+ * chip select must hold similar flash chips. But you need external hardware
+ * to do that anyway and you can put totally different chips on cse0 and cse1
+ * so it isn't really much of a restriction.
+ */
+extern struct mtd_info* __init crisv32_nand_flash_probe (void);
+static struct mtd_info *flash_probe(void)
+{
+	struct mtd_info *mtd_cse0;
+	struct mtd_info *mtd_cse1;
+	struct mtd_info *mtd_nand = NULL;
+	struct mtd_info *mtd_total;
+	struct mtd_info *mtds[3];
+	int count = 0;
+
+	if ((mtd_cse0 = probe_cs(&map_cse0)) != NULL)
+		mtds[count++] = mtd_cse0;
+	if ((mtd_cse1 = probe_cs(&map_cse1)) != NULL)
+		mtds[count++] = mtd_cse1;
+
+#ifdef CONFIG_ETRAX_NANDFLASH
+	if ((mtd_nand = crisv32_nand_flash_probe()) != NULL)
+		mtds[count++] = mtd_nand;
+#endif
+
+	if (!mtd_cse0 && !mtd_cse1 && !mtd_nand) {
+		/* No chip found. */
+		return NULL;
+	}
+
+	if (count > 1) {
+#ifdef CONFIG_MTD_CONCAT
+		/* Since the concatenation layer adds a small overhead we
+		 * could try to figure out if the chips in cse0 and cse1 are
+		 * identical and reprobe the whole cse0+cse1 window. But since
+		 * flash chips are slow, the overhead is relatively small.
+		 * So we use the MTD concatenation layer instead of further
+		 * complicating the probing procedure.
+		 */
+		mtd_total = mtd_concat_create(mtds,
+		                              count,
+		                              "cse0+cse1+nand");
+#else
+		printk(KERN_ERR "%s and %s: Cannot concatenate due to kernel "
+		       "(mis)configuration!\n", map_cse0.name, map_cse1.name);
+		mtd_toal = NULL;
+#endif
+		if (!mtd_total) {
+			printk(KERN_ERR "%s and %s: Concatenation failed!\n",
+			       map_cse0.name, map_cse1.name);
+
+			/* The best we can do now is to only use what we found
+			 * at cse0.
+			 */
+			mtd_total = mtd_cse0;
+			map_destroy(mtd_cse1);
+		}
+	} else {
+		mtd_total = mtd_cse0? mtd_cse0 : mtd_cse1 ? mtd_cse1 : mtd_nand;
+
+	}
+
+	return mtd_total;
+}
+
+extern unsigned long crisv32_nand_boot;
+extern unsigned long crisv32_nand_cramfs_offset;
+
+/*
+ * Probe the flash chip(s) and, if it succeeds, read the partition-table
+ * and register the partitions with MTD.
+ */
+static int __init init_axis_flash(void)
+{
+	struct mtd_info *mymtd;
+	int err = 0;
+	int pidx = 0;
+	struct partitiontable_head *ptable_head = NULL;
+	struct partitiontable_entry *ptable;
+	int use_default_ptable = 1; /* Until proven otherwise. */
+	const char *pmsg = KERN_INFO "  /dev/flash%d at 0x%08x, size 0x%08x\n";
+	static char page[512];
+	size_t len;
+
+#ifndef CONFIG_ETRAXFS_SIM
+	mymtd = flash_probe();
+	mymtd->read(mymtd, CONFIG_ETRAX_PTABLE_SECTOR, 512, &len, page);
+	ptable_head = (struct partitiontable_head *)(page + PARTITION_TABLE_OFFSET);
+
+	if (!mymtd) {
+		/* There's no reason to use this module if no flash chip can
+		 * be identified. Make sure that's understood.
+		 */
+		printk(KERN_INFO "axisflashmap: Found no flash chip.\n");
+	} else {
+		printk(KERN_INFO "%s: 0x%08x bytes of flash memory.\n",
+		       mymtd->name, mymtd->size);
+		axisflash_mtd = mymtd;
+	}
+
+	if (mymtd) {
+		mymtd->owner = THIS_MODULE;
+	}
+	pidx++;  /* First partition is always set to the default. */
+
+	if (ptable_head && (ptable_head->magic == PARTITION_TABLE_MAGIC)
+	    && (ptable_head->size <
+		(MAX_PARTITIONS * sizeof(struct partitiontable_entry) +
+		PARTITIONTABLE_END_MARKER_SIZE))
+	    && (*(unsigned long*)((void*)ptable_head + sizeof(*ptable_head) +
+				  ptable_head->size -
+				  PARTITIONTABLE_END_MARKER_SIZE)
+		== PARTITIONTABLE_END_MARKER)) {
+		/* Looks like a start, sane length and end of a
+		 * partition table, lets check csum etc.
+		 */
+		int ptable_ok = 0;
+		struct partitiontable_entry *max_addr =
+			(struct partitiontable_entry *)
+			((unsigned long)ptable_head + sizeof(*ptable_head) +
+			 ptable_head->size);
+		unsigned long offset = CONFIG_ETRAX_PTABLE_SECTOR;
+		unsigned char *p;
+		unsigned long csum = 0;
+
+		ptable = (struct partitiontable_entry *)
+			((unsigned long)ptable_head + sizeof(*ptable_head));
+
+		/* Lets be PARANOID, and check the checksum. */
+		p = (unsigned char*) ptable;
+
+		while (p <= (unsigned char*)max_addr) {
+			csum += *p++;
+			csum += *p++;
+			csum += *p++;
+			csum += *p++;
+		}
+		ptable_ok = (csum == ptable_head->checksum);
+
+		/* Read the entries and use/show the info.  */
+		printk(KERN_INFO " Found a%s partition table at 0x%p-0x%p.\n",
+		       (ptable_ok ? " valid" : "n invalid"), ptable_head,
+		       max_addr);
+
+		/* We have found a working bootblock.  Now read the
+		 * partition table.  Scan the table.  It ends when
+		 * there is 0xffffffff, that is, empty flash.
+		 */
+		while (ptable_ok
+		       && ptable->offset != 0xffffffff
+		       && ptable < max_addr
+		       && pidx < MAX_PARTITIONS) {
+
+			axis_partitions[pidx].offset = offset + ptable->offset + (crisv32_nand_boot ? 16384 : 0);
+			axis_partitions[pidx].size = ptable->size;
+
+			printk(pmsg, pidx, axis_partitions[pidx].offset,
+			       axis_partitions[pidx].size);
+			pidx++;
+			ptable++;
+		}
+		use_default_ptable = !ptable_ok;
+	}
+
+	if (romfs_in_flash) {
+		/* Add an overlapping device for the root partition (romfs). */
+
+		axis_partitions[pidx].name = "romfs";
+		if (crisv32_nand_boot) {
+			char* data = kmalloc(1024, GFP_KERNEL);
+			int len;
+			int offset = crisv32_nand_cramfs_offset & ~(1024-1);
+			char* tmp;
+
+			mymtd->read(mymtd, offset, 1024, &len, data);
+			tmp = &data[crisv32_nand_cramfs_offset % 512];
+			axis_partitions[pidx].size = *(unsigned*)(tmp + 4);
+			axis_partitions[pidx].offset = crisv32_nand_cramfs_offset;
+			kfree(data);
+		} else {
+			axis_partitions[pidx].size = romfs_length;
+			axis_partitions[pidx].offset = romfs_start - FLASH_CACHED_ADDR;
+		}
+
+		axis_partitions[pidx].mask_flags |= MTD_WRITEABLE;
+
+		printk(KERN_INFO
+                       " Adding readonly flash partition for romfs image:\n");
+		printk(pmsg, pidx, axis_partitions[pidx].offset,
+		       axis_partitions[pidx].size);
+		pidx++;
+	}
+
+        if (mymtd) {
+		if (use_default_ptable) {
+			printk(KERN_INFO " Using default partition table.\n");
+			err = add_mtd_partitions(mymtd, axis_default_partitions,
+						 NUM_DEFAULT_PARTITIONS);
+		} else {
+			err = add_mtd_partitions(mymtd, axis_partitions, pidx);
+		}
+
+		if (err) {
+			panic("axisflashmap could not add MTD partitions!\n");
+		}
+	}
+/* CONFIG_EXTRAXFS_SIM */
+#endif
+
+	if (!romfs_in_flash) {
+		/* Create an RAM device for the root partition (romfs). */
+
+#if !defined(CONFIG_MTD_MTDRAM) || (CONFIG_MTDRAM_TOTAL_SIZE != 0) || (CONFIG_MTDRAM_ABS_POS != 0)
+		/* No use trying to boot this kernel from RAM. Panic! */
+		printk(KERN_EMERG "axisflashmap: Cannot create an MTD RAM "
+		       "device due to kernel (mis)configuration!\n");
+		panic("This kernel cannot boot from RAM!\n");
+#else
+		struct mtd_info *mtd_ram;
+
+		mtd_ram = (struct mtd_info *)kmalloc(sizeof(struct mtd_info),
+						     GFP_KERNEL);
+		if (!mtd_ram) {
+			panic("axisflashmap couldn't allocate memory for "
+			      "mtd_info!\n");
+		}
+
+		printk(KERN_INFO " Adding RAM partition for romfs image:\n");
+		printk(pmsg, pidx, romfs_start, romfs_length);
+
+		err = mtdram_init_device(mtd_ram, (void*)romfs_start,
+		                         romfs_length, "romfs");
+		if (err) {
+			panic("axisflashmap could not initialize MTD RAM "
+			      "device!\n");
+		}
+#endif
+	}
+
+	return err;
+}
+
+/* This adds the above to the kernels init-call chain. */
+module_init(init_axis_flash);
+
+EXPORT_SYMBOL(axisflash_mtd);
diff --git a/arch/cris/arch-v32/drivers/cryptocop.c b/arch/cris/arch-v32/drivers/cryptocop.c
new file mode 100644
--- /dev/null
+++ b/arch/cris/arch-v32/drivers/cryptocop.c
@@ -0,0 +1,3522 @@
+/* $Id: cryptocop.c,v 1.13 2005/04/21 17:27:55 henriken Exp $
+ *
+ * Stream co-processor driver for the ETRAX FS
+ *
+ *    Copyright (C) 2003-2005  Axis Communications AB
+ */
+
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/spinlock.h>
+#include <linux/stddef.h>
+
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/atomic.h>
+
+#include <linux/list.h>
+#include <linux/interrupt.h>
+
+#include <asm/signal.h>
+#include <asm/irq.h>
+
+#include <asm/arch/dma.h>
+#include <asm/arch/hwregs/dma.h>
+#include <asm/arch/hwregs/reg_map.h>
+#include <asm/arch/hwregs/reg_rdwr.h>
+#include <asm/arch/hwregs/intr_vect_defs.h>
+
+#include <asm/arch/hwregs/strcop.h>
+#include <asm/arch/hwregs/strcop_defs.h>
+#include <asm/arch/cryptocop.h>
+
+
+
+#define DESCR_ALLOC_PAD  (31)
+
+struct cryptocop_dma_desc {
+	char *free_buf; /* If non-null will be kfreed in free_cdesc() */
+	dma_descr_data *dma_descr;
+
+	unsigned char dma_descr_buf[sizeof(dma_descr_data) + DESCR_ALLOC_PAD];
+
+	unsigned int from_pool:1; /* If 1 'allocated' from the descriptor pool. */
+	struct cryptocop_dma_desc *next;
+};
+
+
+struct cryptocop_int_operation{
+	void                        *alloc_ptr;
+	cryptocop_session_id        sid;
+
+	dma_descr_context           ctx_out;
+	dma_descr_context           ctx_in;
+
+	/* DMA descriptors allocated by driver. */
+	struct cryptocop_dma_desc   *cdesc_out;
+	struct cryptocop_dma_desc   *cdesc_in;
+
+	/* Strcop config to use. */
+	cryptocop_3des_mode         tdes_mode;
+	cryptocop_csum_type         csum_mode;
+
+	/* DMA descrs provided by consumer. */
+	dma_descr_data              *ddesc_out;
+	dma_descr_data              *ddesc_in;
+};
+
+
+struct cryptocop_tfrm_ctx {
+	cryptocop_tfrm_id tid;
+	unsigned int blocklength;
+
+	unsigned int start_ix;
+
+	struct cryptocop_tfrm_cfg *tcfg;
+	struct cryptocop_transform_ctx *tctx;
+
+	unsigned char previous_src;
+	unsigned char current_src;
+
+	/* Values to use in metadata out. */
+	unsigned char hash_conf;
+	unsigned char hash_mode;
+	unsigned char ciph_conf;
+	unsigned char cbcmode;
+	unsigned char decrypt;
+
+	unsigned int requires_padding:1;
+	unsigned int strict_block_length:1;
+	unsigned int active:1;
+	unsigned int done:1;
+	size_t consumed;
+	size_t produced;
+
+	/* Pad (input) descriptors to put in the DMA out list when the transform
+	 * output is put on the DMA in list. */
+	struct cryptocop_dma_desc *pad_descs;
+
+	struct cryptocop_tfrm_ctx *prev_src;
+	struct cryptocop_tfrm_ctx *curr_src;
+
+	/* Mapping to HW. */
+	unsigned char unit_no;
+};
+
+
+struct cryptocop_private{
+	cryptocop_session_id sid;
+	struct cryptocop_private *next;
+};
+
+/* Session list. */
+
+struct cryptocop_transform_ctx{
+	struct cryptocop_transform_init init;
+	unsigned char dec_key[CRYPTOCOP_MAX_KEY_LENGTH];
+	unsigned int dec_key_set:1;
+
+	struct cryptocop_transform_ctx *next;
+};
+
+
+struct cryptocop_session{
+	cryptocop_session_id sid;
+
+	struct cryptocop_transform_ctx *tfrm_ctx;
+
+	struct cryptocop_session *next;
+};
+
+/* Priority levels for jobs sent to the cryptocop.  Checksum operations from
+   kernel have highest priority since TCPIP stack processing must not
+   be a bottleneck. */
+typedef enum {
+	cryptocop_prio_kernel_csum = 0,
+	cryptocop_prio_kernel = 1,
+	cryptocop_prio_user = 2,
+	cryptocop_prio_no_prios = 3
+} cryptocop_queue_priority;
+
+struct cryptocop_prio_queue{
+	struct list_head jobs;
+	cryptocop_queue_priority prio;
+};
+
+struct cryptocop_prio_job{
+	struct list_head node;
+	cryptocop_queue_priority prio;
+
+	struct cryptocop_operation *oper;
+	struct cryptocop_int_operation *iop;
+};
+
+struct ioctl_job_cb_ctx {
+	unsigned int processed:1;
+};
+
+
+static struct cryptocop_session *cryptocop_sessions = NULL;
+spinlock_t cryptocop_sessions_lock;
+
+/* Next Session ID to assign. */
+static cryptocop_session_id next_sid = 1;
+
+/* Pad for checksum. */
+static const char csum_zero_pad[1] = {0x00};
+
+/* Trash buffer for mem2mem operations. */
+#define MEM2MEM_DISCARD_BUF_LENGTH  (512)
+static unsigned char mem2mem_discard_buf[MEM2MEM_DISCARD_BUF_LENGTH];
+
+/* Descriptor pool. */
+/* FIXME Tweak this value. */
+#define CRYPTOCOP_DESCRIPTOR_POOL_SIZE   (100)
+static struct cryptocop_dma_desc descr_pool[CRYPTOCOP_DESCRIPTOR_POOL_SIZE];
+static struct cryptocop_dma_desc *descr_pool_free_list;
+static int descr_pool_no_free;
+static spinlock_t descr_pool_lock;
+
+/* Lock to stop cryptocop to start processing of a new operation. The holder
+   of this lock MUST call cryptocop_start_job() after it is unlocked. */
+spinlock_t cryptocop_process_lock;
+
+static struct cryptocop_prio_queue cryptocop_job_queues[cryptocop_prio_no_prios];
+static spinlock_t cryptocop_job_queue_lock;
+static struct cryptocop_prio_job *cryptocop_running_job = NULL;
+static spinlock_t running_job_lock;
+
+/* The interrupt handler appends completed jobs to this list. The scehduled
+ * tasklet removes them upon sending the response to the crypto consumer. */
+static struct list_head cryptocop_completed_jobs;
+static spinlock_t cryptocop_completed_jobs_lock;
+
+DECLARE_WAIT_QUEUE_HEAD(cryptocop_ioc_process_wq);
+
+
+/** Local functions. **/
+
+static int cryptocop_open(struct inode *, struct file *);
+
+static int cryptocop_release(struct inode *, struct file *);
+
+static int cryptocop_ioctl(struct inode *inode, struct file *file,
+			   unsigned int cmd, unsigned long arg);
+
+static void cryptocop_start_job(void);
+
+static int cryptocop_job_queue_insert(cryptocop_queue_priority prio, struct cryptocop_operation *operation);
+static int cryptocop_job_setup(struct cryptocop_prio_job **pj, struct cryptocop_operation *operation);
+
+static int cryptocop_job_queue_init(void);
+static void cryptocop_job_queue_close(void);
+
+static int create_md5_pad(int alloc_flag, unsigned long long hashed_length, char **pad, size_t *pad_length);
+
+static int create_sha1_pad(int alloc_flag, unsigned long long hashed_length, char **pad, size_t *pad_length);
+
+static int transform_ok(struct cryptocop_transform_init *tinit);
+
+static struct cryptocop_session *get_session(cryptocop_session_id sid);
+
+static struct cryptocop_transform_ctx *get_transform_ctx(struct cryptocop_session *sess, cryptocop_tfrm_id tid);
+
+static void delete_internal_operation(struct cryptocop_int_operation *iop);
+
+static void get_aes_decrypt_key(unsigned char *dec_key, const unsigned  char *key, unsigned int keylength);
+
+static int init_stream_coprocessor(void);
+
+static void __exit exit_stream_coprocessor(void);
+
+/*#define LDEBUG*/
+#ifdef LDEBUG
+#define DEBUG(s) s
+#define DEBUG_API(s) s
+static void print_cryptocop_operation(struct cryptocop_operation *cop);
+static void print_dma_descriptors(struct cryptocop_int_operation *iop);
+static void print_strcop_crypto_op(struct strcop_crypto_op *cop);
+static void print_lock_status(void);
+static void print_user_dma_lists(struct cryptocop_dma_list_operation *dma_op);
+#define assert(s) do{if (!(s)) panic(#s);} while(0);
+#else
+#define DEBUG(s)
+#define DEBUG_API(s)
+#define assert(s)
+#endif
+
+
+/* Transform constants. */
+#define DES_BLOCK_LENGTH   (8)
+#define AES_BLOCK_LENGTH   (16)
+#define MD5_BLOCK_LENGTH   (64)
+#define SHA1_BLOCK_LENGTH  (64)
+#define CSUM_BLOCK_LENGTH  (2)
+#define MD5_STATE_LENGTH   (16)
+#define SHA1_STATE_LENGTH  (20)
+
+/* The device number. */
+#define CRYPTOCOP_MAJOR    (254)
+#define CRYPTOCOP_MINOR    (0)
+
+
+
+struct file_operations cryptocop_fops = {
+	owner: THIS_MODULE,
+	open: cryptocop_open,
+	release: cryptocop_release,
+	ioctl: cryptocop_ioctl
+};
+
+
+static void free_cdesc(struct cryptocop_dma_desc *cdesc)
+{
+	DEBUG(printk("free_cdesc: cdesc 0x%p, from_pool=%d\n", cdesc, cdesc->from_pool));
+	if (cdesc->free_buf) kfree(cdesc->free_buf);
+
+	if (cdesc->from_pool) {
+		unsigned long int flags;
+		spin_lock_irqsave(&descr_pool_lock, flags);
+		cdesc->next = descr_pool_free_list;
+		descr_pool_free_list = cdesc;
+		++descr_pool_no_free;
+		spin_unlock_irqrestore(&descr_pool_lock, flags);
+	} else {
+		kfree(cdesc);
+	}
+}
+
+
+static struct cryptocop_dma_desc *alloc_cdesc(int alloc_flag)
+{
+	int use_pool = (alloc_flag & GFP_ATOMIC) ? 1 : 0;
+	struct cryptocop_dma_desc *cdesc;
+
+	if (use_pool) {
+		unsigned long int flags;
+		spin_lock_irqsave(&descr_pool_lock, flags);
+		if (!descr_pool_free_list) {
+			spin_unlock_irqrestore(&descr_pool_lock, flags);
+			DEBUG_API(printk("alloc_cdesc: pool is empty\n"));
+			return NULL;
+		}
+		cdesc = descr_pool_free_list;
+		descr_pool_free_list = descr_pool_free_list->next;
+		--descr_pool_no_free;
+		spin_unlock_irqrestore(&descr_pool_lock, flags);
+		cdesc->from_pool = 1;
+	} else {
+		cdesc = kmalloc(sizeof(struct cryptocop_dma_desc), alloc_flag);
+		if (!cdesc) {
+			DEBUG_API(printk("alloc_cdesc: kmalloc\n"));
+			return NULL;
+		}
+		cdesc->from_pool = 0;
+	}
+	cdesc->dma_descr = (dma_descr_data*)(((unsigned long int)cdesc + offsetof(struct cryptocop_dma_desc, dma_descr_buf) + DESCR_ALLOC_PAD) & ~0x0000001F);
+
+	cdesc->next = NULL;
+
+	cdesc->free_buf = NULL;
+	cdesc->dma_descr->out_eop = 0;
+	cdesc->dma_descr->in_eop = 0;
+	cdesc->dma_descr->intr = 0;
+	cdesc->dma_descr->eol = 0;
+	cdesc->dma_descr->wait = 0;
+	cdesc->dma_descr->buf = NULL;
+	cdesc->dma_descr->after = NULL;
+
+	DEBUG_API(printk("alloc_cdesc: return 0x%p, cdesc->dma_descr=0x%p, from_pool=%d\n", cdesc, cdesc->dma_descr, cdesc->from_pool));
+	return cdesc;
+}
+
+
+static void setup_descr_chain(struct cryptocop_dma_desc *cd)
+{
+	DEBUG(printk("setup_descr_chain: entering\n"));
+	while (cd) {
+		if (cd->next) {
+			cd->dma_descr->next = (dma_descr_data*)virt_to_phys(cd->next->dma_descr);
+		} else {
+			cd->dma_descr->next = NULL;
+		}
+		cd = cd->next;
+	}
+	DEBUG(printk("setup_descr_chain: exit\n"));
+}
+
+
+/* Create a pad descriptor for the transform.
+ * Return -1 for error, 0 if pad created. */
+static int create_pad_descriptor(struct cryptocop_tfrm_ctx *tc, struct cryptocop_dma_desc **pad_desc, int alloc_flag)
+{
+	struct cryptocop_dma_desc        *cdesc = NULL;
+	int                              error = 0;
+	struct strcop_meta_out           mo = {
+		.ciphsel = src_none,
+		.hashsel = src_none,
+		.csumsel = src_none
+	};
+	char                             *pad;
+	size_t                           plen;
+
+	DEBUG(printk("create_pad_descriptor: start.\n"));
+	/* Setup pad descriptor. */
+
+	DEBUG(printk("create_pad_descriptor: setting up padding.\n"));
+	cdesc = alloc_cdesc(alloc_flag);
+	if (!cdesc){
+		DEBUG_API(printk("create_pad_descriptor: alloc pad desc\n"));
+		goto error_cleanup;
+	}
+	switch (tc->unit_no) {
+	case src_md5:
+		error = create_md5_pad(alloc_flag, tc->consumed, &pad, &plen);
+		if (error){
+			DEBUG_API(printk("create_pad_descriptor: create_md5_pad_failed\n"));
+			goto error_cleanup;
+		}
+		cdesc->free_buf = pad;
+		mo.hashsel = src_dma;
+		mo.hashconf = tc->hash_conf;
+		mo.hashmode = tc->hash_mode;
+		break;
+	case src_sha1:
+		error = create_sha1_pad(alloc_flag, tc->consumed, &pad, &plen);
+		if (error){
+			DEBUG_API(printk("create_pad_descriptor: create_sha1_pad_failed\n"));
+			goto error_cleanup;
+		}
+		cdesc->free_buf = pad;
+		mo.hashsel = src_dma;
+		mo.hashconf = tc->hash_conf;
+		mo.hashmode = tc->hash_mode;
+		break;
+	case src_csum:
+		if (tc->consumed % tc->blocklength){
+			pad = (char*)csum_zero_pad;
+			plen = 1;
+		} else {
+			pad = (char*)cdesc; /* Use any pointer. */
+			plen = 0;
+		}
+		mo.csumsel = src_dma;
+		break;
+	}
+	cdesc->dma_descr->wait = 1;
+	cdesc->dma_descr->out_eop = 1; /* Since this is a pad output is pushed.  EOP is ok here since the padded unit is the only one active. */
+	cdesc->dma_descr->buf = (char*)virt_to_phys((char*)pad);
+	cdesc->dma_descr->after = cdesc->dma_descr->buf + plen;
+
+	cdesc->dma_descr->md = REG_TYPE_CONV(unsigned short int, struct strcop_meta_out, mo);
+	*pad_desc = cdesc;
+
+	return 0;
+
+ error_cleanup:
+	if (cdesc) free_cdesc(cdesc);
+	return -1;
+}
+
+
+static int setup_key_dl_desc(struct cryptocop_tfrm_ctx *tc, struct cryptocop_dma_desc **kd, int alloc_flag)
+{
+	struct cryptocop_dma_desc  *key_desc = alloc_cdesc(alloc_flag);
+	struct strcop_meta_out     mo = {0};
+
+	DEBUG(printk("setup_key_dl_desc\n"));
+
+	if (!key_desc) {
+		DEBUG_API(printk("setup_key_dl_desc: failed descriptor allocation.\n"));
+		return -ENOMEM;
+	}
+
+	/* Download key. */
+	if ((tc->tctx->init.alg == cryptocop_alg_aes) && (tc->tcfg->flags & CRYPTOCOP_DECRYPT)) {
+		/* Precook the AES decrypt key. */
+		if (!tc->tctx->dec_key_set){
+			get_aes_decrypt_key(tc->tctx->dec_key, tc->tctx->init.key, tc->tctx->init.keylen);
+			tc->tctx->dec_key_set = 1;
+		}
+		key_desc->dma_descr->buf = (char*)virt_to_phys(tc->tctx->dec_key);
+		key_desc->dma_descr->after = key_desc->dma_descr->buf + tc->tctx->init.keylen/8;
+	} else {
+		key_desc->dma_descr->buf = (char*)virt_to_phys(tc->tctx->init.key);
+		key_desc->dma_descr->after = key_desc->dma_descr->buf + tc->tctx->init.keylen/8;
+	}
+	/* Setup metadata. */
+	mo.dlkey = 1;
+	switch (tc->tctx->init.keylen) {
+	case 64:
+		mo.decrypt = 0;
+		mo.hashmode = 0;
+		break;
+	case 128:
+		mo.decrypt = 0;
+		mo.hashmode = 1;
+		break;
+	case 192:
+		mo.decrypt = 1;
+		mo.hashmode = 0;
+		break;
+	case 256:
+		mo.decrypt = 1;
+		mo.hashmode = 1;
+		break;
+	default:
+		break;
+	}
+	mo.ciphsel = mo.hashsel = mo.csumsel = src_none;
+	key_desc->dma_descr->md = REG_TYPE_CONV(unsigned short int, struct strcop_meta_out, mo);
+
+	key_desc->dma_descr->out_eop = 1;
+	key_desc->dma_descr->wait = 1;
+	key_desc->dma_descr->intr = 0;
+
+	*kd = key_desc;
+	return 0;
+}
+
+static int setup_cipher_iv_desc(struct cryptocop_tfrm_ctx *tc, struct cryptocop_dma_desc **id, int alloc_flag)
+{
+	struct cryptocop_dma_desc  *iv_desc = alloc_cdesc(alloc_flag);
+	struct strcop_meta_out     mo = {0};
+
+	DEBUG(printk("setup_cipher_iv_desc\n"));
+
+	if (!iv_desc) {
+		DEBUG_API(printk("setup_cipher_iv_desc: failed CBC IV descriptor allocation.\n"));
+		return -ENOMEM;
+	}
+	/* Download IV. */
+	iv_desc->dma_descr->buf = (char*)virt_to_phys(tc->tcfg->iv);
+	iv_desc->dma_descr->after = iv_desc->dma_descr->buf + tc->blocklength;
+
+	/* Setup metadata. */
+	mo.hashsel = mo.csumsel = src_none;
+	mo.ciphsel = src_dma;
+	mo.ciphconf = tc->ciph_conf;
+	mo.cbcmode = tc->cbcmode;
+
+	iv_desc->dma_descr->md = REG_TYPE_CONV(unsigned short int, struct strcop_meta_out, mo);
+
+	iv_desc->dma_descr->out_eop = 0;
+	iv_desc->dma_descr->wait = 1;
+	iv_desc->dma_descr->intr = 0;
+
+	*id = iv_desc;
+	return 0;
+}
+
+/* Map the ouput length of the transform to operation output starting on the inject index. */
+static int create_input_descriptors(struct cryptocop_operation *operation, struct cryptocop_tfrm_ctx *tc, struct cryptocop_dma_desc **id, int alloc_flag)
+{
+	int                        err = 0;
+	struct cryptocop_dma_desc  head = {0};
+	struct cryptocop_dma_desc  *outdesc = &head;
+	size_t                     iov_offset = 0;
+	size_t                     out_ix = 0;
+	int                        outiov_ix = 0;
+	struct strcop_meta_in      mi = {0};
+
+	size_t                     out_length = tc->produced;
+	int                        rem_length;
+	int                        dlength;
+
+	assert(out_length != 0);
+	if (((tc->produced + tc->tcfg->inject_ix) > operation->tfrm_op.outlen) || (tc->produced && (operation->tfrm_op.outlen == 0))) {
+		DEBUG_API(printk("create_input_descriptors: operation outdata too small\n"));
+		return -EINVAL;
+	}
+	/* Traverse the out iovec until the result inject index is reached. */
+	while ((outiov_ix < operation->tfrm_op.outcount) && ((out_ix + operation->tfrm_op.outdata[outiov_ix].iov_len) <= tc->tcfg->inject_ix)){
+		out_ix += operation->tfrm_op.outdata[outiov_ix].iov_len;
+		outiov_ix++;
+	}
+	if (outiov_ix >= operation->tfrm_op.outcount){
+		DEBUG_API(printk("create_input_descriptors: operation outdata too small\n"));
+		return -EINVAL;
+	}
+	iov_offset = tc->tcfg->inject_ix - out_ix;
+	mi.dmasel = tc->unit_no;
+
+	/* Setup the output descriptors. */
+	while ((out_length > 0) && (outiov_ix < operation->tfrm_op.outcount)) {
+		outdesc->next = alloc_cdesc(alloc_flag);
+		if (!outdesc->next) {
+			DEBUG_API(printk("create_input_descriptors: alloc_cdesc\n"));
+			err = -ENOMEM;
+			goto error_cleanup;
+		}
+		outdesc = outdesc->next;
+		rem_length = operation->tfrm_op.outdata[outiov_ix].iov_len - iov_offset;
+		dlength = (out_length < rem_length) ? out_length : rem_length;
+
+		DEBUG(printk("create_input_descriptors:\n"
+			     "outiov_ix=%d, rem_length=%d, dlength=%d\n"
+			     "iov_offset=%d, outdata[outiov_ix].iov_len=%d\n"
+			     "outcount=%d, outiov_ix=%d\n",
+			     outiov_ix, rem_length, dlength, iov_offset, operation->tfrm_op.outdata[outiov_ix].iov_len, operation->tfrm_op.outcount, outiov_ix));
+
+		outdesc->dma_descr->buf = (char*)virt_to_phys(operation->tfrm_op.outdata[outiov_ix].iov_base + iov_offset);
+		outdesc->dma_descr->after = outdesc->dma_descr->buf + dlength;
+		outdesc->dma_descr->md = REG_TYPE_CONV(unsigned short int, struct strcop_meta_in, mi);
+
+		out_length -= dlength;
+		iov_offset += dlength;
+		if (iov_offset >= operation->tfrm_op.outdata[outiov_ix].iov_len) {
+			iov_offset = 0;
+			++outiov_ix;
+		}
+	}
+	if (out_length > 0){
+		DEBUG_API(printk("create_input_descriptors: not enough room for output, %d remained\n", out_length));
+		err = -EINVAL;
+		goto error_cleanup;
+	}
+	/* Set sync in last descriptor. */
+	mi.sync = 1;
+	outdesc->dma_descr->md = REG_TYPE_CONV(unsigned short int, struct strcop_meta_in, mi);
+
+	*id = head.next;
+	return 0;
+
+ error_cleanup:
+	while (head.next) {
+		outdesc = head.next->next;
+		free_cdesc(head.next);
+		head.next = outdesc;
+	}
+	return err;
+}
+
+
+static int create_output_descriptors(struct cryptocop_operation *operation, int *iniov_ix, int *iniov_offset, size_t desc_len, struct cryptocop_dma_desc **current_out_cdesc, struct strcop_meta_out *meta_out, int alloc_flag)
+{
+	while (desc_len != 0) {
+		struct cryptocop_dma_desc  *cdesc;
+		int                        rem_length = operation->tfrm_op.indata[*iniov_ix].iov_len - *iniov_offset;
+		int                        dlength = (desc_len < rem_length) ? desc_len : rem_length;
+
+		cdesc = alloc_cdesc(alloc_flag);
+		if (!cdesc) {
+			DEBUG_API(printk("create_output_descriptors: alloc_cdesc\n"));
+			return -ENOMEM;
+		}
+		(*current_out_cdesc)->next = cdesc;
+		(*current_out_cdesc) = cdesc;
+
+		cdesc->free_buf = NULL;
+
+		cdesc->dma_descr->buf = (char*)virt_to_phys(operation->tfrm_op.indata[*iniov_ix].iov_base + *iniov_offset);
+		cdesc->dma_descr->after = cdesc->dma_descr->buf + dlength;
+
+		desc_len -= dlength;
+		*iniov_offset += dlength;
+		assert(desc_len >= 0);
+		if (*iniov_offset >= operation->tfrm_op.indata[*iniov_ix].iov_len) {
+			*iniov_offset = 0;
+			++(*iniov_ix);
+			if (*iniov_ix > operation->tfrm_op.incount) {
+				DEBUG_API(printk("create_output_descriptors: not enough indata in operation."));
+				return  -EINVAL;
+			}
+		}
+		cdesc->dma_descr->md = REG_TYPE_CONV(unsigned short int, struct strcop_meta_out, (*meta_out));
+	} /* while (desc_len != 0) */
+	/* Last DMA descriptor gets a 'wait' bit to signal expected change in metadata. */
+	(*current_out_cdesc)->dma_descr->wait = 1; /* This will set extraneous WAIT in some situations, e.g. when padding hashes and checksums. */
+
+	return 0;
+}
+
+
+static int append_input_descriptors(struct cryptocop_operation *operation, struct cryptocop_dma_desc **current_in_cdesc, struct cryptocop_dma_desc **current_out_cdesc, struct cryptocop_tfrm_ctx *tc, int alloc_flag)
+{
+	DEBUG(printk("append_input_descriptors, tc=0x%p, unit_no=%d\n", tc, tc->unit_no));
+	if (tc->tcfg) {
+		int                        failed = 0;
+		struct cryptocop_dma_desc  *idescs = NULL;
+		DEBUG(printk("append_input_descriptors: pushing output, consumed %d produced %d bytes.\n", tc->consumed, tc->produced));
+		if (tc->pad_descs) {
+			DEBUG(printk("append_input_descriptors: append pad descriptors to DMA out list.\n"));
+			while (tc->pad_descs) {
+				DEBUG(printk("append descriptor 0x%p\n", tc->pad_descs));
+				(*current_out_cdesc)->next = tc->pad_descs;
+				tc->pad_descs = tc->pad_descs->next;
+				(*current_out_cdesc) = (*current_out_cdesc)->next;
+			}
+		}
+
+		/* Setup and append output descriptors to DMA in list. */
+		if (tc->unit_no == src_dma){
+			/* mem2mem.  Setup DMA in descriptors to discard all input prior to the requested mem2mem data. */
+			struct strcop_meta_in mi = {.sync = 0, .dmasel = src_dma};
+			unsigned int start_ix = tc->start_ix;
+			while (start_ix){
+				unsigned int desclen = start_ix < MEM2MEM_DISCARD_BUF_LENGTH ? start_ix : MEM2MEM_DISCARD_BUF_LENGTH;
+				(*current_in_cdesc)->next = alloc_cdesc(alloc_flag);
+				if (!(*current_in_cdesc)->next){
+					DEBUG_API(printk("append_input_descriptors: alloc_cdesc mem2mem discard failed\n"));
+					return -ENOMEM;
+				}
+				(*current_in_cdesc) = (*current_in_cdesc)->next;
+				(*current_in_cdesc)->dma_descr->buf = (char*)virt_to_phys(mem2mem_discard_buf);
+				(*current_in_cdesc)->dma_descr->after = (*current_in_cdesc)->dma_descr->buf + desclen;
+				(*current_in_cdesc)->dma_descr->md = REG_TYPE_CONV(unsigned short int, struct strcop_meta_in, mi);
+				start_ix -= desclen;
+			}
+			mi.sync = 1;
+			(*current_in_cdesc)->dma_descr->md = REG_TYPE_CONV(unsigned short int, struct strcop_meta_in, mi);
+		}
+
+		failed = create_input_descriptors(operation, tc, &idescs, alloc_flag);
+		if (failed){
+			DEBUG_API(printk("append_input_descriptors: output descriptor setup failed\n"));
+			return failed;
+		}
+		DEBUG(printk("append_input_descriptors: append output descriptors to DMA in list.\n"));
+		while (idescs) {
+			DEBUG(printk("append descriptor 0x%p\n", idescs));
+			(*current_in_cdesc)->next = idescs;
+			idescs = idescs->next;
+			(*current_in_cdesc) = (*current_in_cdesc)->next;
+		}
+	}
+	return 0;
+}
+
+
+
+static int cryptocop_setup_dma_list(struct cryptocop_operation *operation, struct cryptocop_int_operation **int_op, int alloc_flag)
+{
+	struct cryptocop_session *sess;
+	struct cryptocop_transform_ctx *tctx;
+
+	struct cryptocop_tfrm_ctx digest_ctx = {
+		.previous_src = src_none,
+		.current_src = src_none,
+		.start_ix = 0,
+		.requires_padding = 1,
+		.strict_block_length = 0,
+		.hash_conf = 0,
+		.hash_mode = 0,
+		.ciph_conf = 0,
+		.cbcmode = 0,
+		.decrypt = 0,
+		.consumed = 0,
+		.produced = 0,
+		.pad_descs = NULL,
+		.active = 0,
+		.done = 0,
+		.prev_src = NULL,
+		.curr_src = NULL,
+		.tcfg = NULL};
+	struct cryptocop_tfrm_ctx cipher_ctx = {
+		.previous_src = src_none,
+		.current_src = src_none,
+		.start_ix = 0,
+		.requires_padding = 0,
+		.strict_block_length = 1,
+		.hash_conf = 0,
+		.hash_mode = 0,
+		.ciph_conf = 0,
+		.cbcmode = 0,
+		.decrypt = 0,
+		.consumed = 0,
+		.produced = 0,
+		.pad_descs = NULL,
+		.active = 0,
+		.done = 0,
+		.prev_src = NULL,
+		.curr_src = NULL,
+		.tcfg = NULL};
+	struct cryptocop_tfrm_ctx csum_ctx = {
+		.previous_src = src_none,
+		.current_src = src_none,
+		.start_ix = 0,
+		.blocklength = 2,
+		.requires_padding = 1,
+		.strict_block_length = 0,
+		.hash_conf = 0,
+		.hash_mode = 0,
+		.ciph_conf = 0,
+		.cbcmode = 0,
+		.decrypt = 0,
+		.consumed = 0,
+		.produced = 0,
+		.pad_descs = NULL,
+		.active = 0,
+		.done = 0,
+		.tcfg = NULL,
+		.prev_src = NULL,
+		.curr_src = NULL,
+		.unit_no = src_csum};
+	struct cryptocop_tfrm_cfg *tcfg = operation->tfrm_op.tfrm_cfg;
+
+	unsigned int indata_ix = 0;
+
+	/* iovec accounting. */
+	int iniov_ix = 0;
+	int iniov_offset = 0;
+
+	/* Operation descriptor cfg traversal pointer. */
+	struct cryptocop_desc *odsc;
+
+	int failed = 0;
+	/* List heads for allocated descriptors. */
+	struct cryptocop_dma_desc out_cdesc_head = {0};
+	struct cryptocop_dma_desc in_cdesc_head = {0};
+
+	struct cryptocop_dma_desc *current_out_cdesc = &out_cdesc_head;
+	struct cryptocop_dma_desc *current_in_cdesc = &in_cdesc_head;
+
+	struct cryptocop_tfrm_ctx *output_tc = NULL;
+	void                      *iop_alloc_ptr;
+
+	assert(operation != NULL);
+	assert(int_op != NULL);
+
+	DEBUG(printk("cryptocop_setup_dma_list: start\n"));
+	DEBUG(print_cryptocop_operation(operation));
+
+	sess = get_session(operation->sid);
+	if (!sess) {
+		DEBUG_API(printk("cryptocop_setup_dma_list: no session found for operation.\n"));
+		failed = -EINVAL;
+		goto error_cleanup;
+	}
+	iop_alloc_ptr = kmalloc(DESCR_ALLOC_PAD + sizeof(struct cryptocop_int_operation), alloc_flag);
+	if (!iop_alloc_ptr) {
+		DEBUG_API(printk("cryptocop_setup_dma_list:  kmalloc cryptocop_int_operation\n"));
+		failed = -ENOMEM;
+		goto error_cleanup;
+	}
+	(*int_op) = (struct cryptocop_int_operation*)(((unsigned long int)(iop_alloc_ptr + DESCR_ALLOC_PAD + offsetof(struct cryptocop_int_operation, ctx_out)) & ~0x0000001F) - offsetof(struct cryptocop_int_operation, ctx_out));
+	DEBUG(memset((*int_op), 0xff, sizeof(struct cryptocop_int_operation)));
+	(*int_op)->alloc_ptr = iop_alloc_ptr;
+	DEBUG(printk("cryptocop_setup_dma_list: *int_op=0x%p, alloc_ptr=0x%p\n", *int_op, (*int_op)->alloc_ptr));
+
+	(*int_op)->sid = operation->sid;
+	(*int_op)->cdesc_out = NULL;
+	(*int_op)->cdesc_in = NULL;
+	(*int_op)->tdes_mode = cryptocop_3des_ede;
+	(*int_op)->csum_mode = cryptocop_csum_le;
+	(*int_op)->ddesc_out = NULL;
+	(*int_op)->ddesc_in = NULL;
+
+	/* Scan operation->tfrm_op.tfrm_cfg for bad configuration and set up the local contexts. */
+	if (!tcfg) {
+		DEBUG_API(printk("cryptocop_setup_dma_list: no configured transforms in operation.\n"));
+		failed = -EINVAL;
+		goto error_cleanup;
+	}
+	while (tcfg) {
+		tctx = get_transform_ctx(sess, tcfg->tid);
+		if (!tctx) {
+			DEBUG_API(printk("cryptocop_setup_dma_list: no transform id %d in session.\n", tcfg->tid));
+			failed = -EINVAL;
+			goto error_cleanup;
+		}
+		if (tcfg->inject_ix > operation->tfrm_op.outlen){
+			DEBUG_API(printk("cryptocop_setup_dma_list: transform id %d inject_ix (%d) > operation->tfrm_op.outlen(%d)", tcfg->tid, tcfg->inject_ix, operation->tfrm_op.outlen));
+			failed = -EINVAL;
+			goto error_cleanup;
+		}
+		switch (tctx->init.alg){
+		case cryptocop_alg_mem2mem:
+			if (cipher_ctx.tcfg != NULL){
+				DEBUG_API(printk("cryptocop_setup_dma_list: multiple ciphers in operation.\n"));
+				failed = -EINVAL;
+				goto error_cleanup;
+			}
+			/* mem2mem is handled as a NULL cipher. */
+			cipher_ctx.cbcmode = 0;
+			cipher_ctx.decrypt = 0;
+			cipher_ctx.blocklength = 1;
+			cipher_ctx.ciph_conf = 0;
+			cipher_ctx.unit_no = src_dma;
+			cipher_ctx.tcfg = tcfg;
+			cipher_ctx.tctx = tctx;
+			break;
+		case cryptocop_alg_des:
+		case cryptocop_alg_3des:
+		case cryptocop_alg_aes:
+			/* cipher */
+			if (cipher_ctx.tcfg != NULL){
+				DEBUG_API(printk("cryptocop_setup_dma_list: multiple ciphers in operation.\n"));
+				failed = -EINVAL;
+				goto error_cleanup;
+			}
+			cipher_ctx.tcfg = tcfg;
+			cipher_ctx.tctx = tctx;
+			if (cipher_ctx.tcfg->flags & CRYPTOCOP_DECRYPT){
+				cipher_ctx.decrypt = 1;
+			}
+			switch (tctx->init.cipher_mode) {
+			case cryptocop_cipher_mode_ecb:
+				cipher_ctx.cbcmode = 0;
+				break;
+			case cryptocop_cipher_mode_cbc:
+				cipher_ctx.cbcmode = 1;
+				break;
+			default:
+				DEBUG_API(printk("cryptocop_setup_dma_list: cipher_ctx, bad cipher mode==%d\n", tctx->init.cipher_mode));
+				failed = -EINVAL;
+				goto error_cleanup;
+			}
+			DEBUG(printk("cryptocop_setup_dma_list: cipher_ctx, set CBC mode==%d\n", cipher_ctx.cbcmode));
+			switch (tctx->init.alg){
+			case cryptocop_alg_des:
+				cipher_ctx.ciph_conf = 0;
+				cipher_ctx.unit_no = src_des;
+				cipher_ctx.blocklength = DES_BLOCK_LENGTH;
+				break;
+			case cryptocop_alg_3des:
+				cipher_ctx.ciph_conf = 1;
+				cipher_ctx.unit_no = src_des;
+				cipher_ctx.blocklength = DES_BLOCK_LENGTH;
+				break;
+			case cryptocop_alg_aes:
+				cipher_ctx.ciph_conf = 2;
+				cipher_ctx.unit_no = src_aes;
+				cipher_ctx.blocklength = AES_BLOCK_LENGTH;
+				break;
+			default:
+				panic("cryptocop_setup_dma_list: impossible algorithm %d\n", tctx->init.alg);
+			}
+			(*int_op)->tdes_mode = tctx->init.tdes_mode;
+			break;
+		case cryptocop_alg_md5:
+		case cryptocop_alg_sha1:
+			/* digest */
+			if (digest_ctx.tcfg != NULL){
+				DEBUG_API(printk("cryptocop_setup_dma_list: multiple digests in operation.\n"));
+				failed = -EINVAL;
+				goto error_cleanup;
+			}
+			digest_ctx.tcfg = tcfg;
+			digest_ctx.tctx = tctx;
+			digest_ctx.hash_mode = 0; /* Don't use explicit IV in this API. */
+			switch (tctx->init.alg){
+			case cryptocop_alg_md5:
+				digest_ctx.blocklength = MD5_BLOCK_LENGTH;
+				digest_ctx.unit_no = src_md5;
+				digest_ctx.hash_conf = 1; /* 1 => MD-5 */
+				break;
+			case cryptocop_alg_sha1:
+				digest_ctx.blocklength = SHA1_BLOCK_LENGTH;
+				digest_ctx.unit_no = src_sha1;
+				digest_ctx.hash_conf = 0; /* 0 => SHA-1 */
+				break;
+			default:
+				panic("cryptocop_setup_dma_list: impossible digest algorithm\n");
+			}
+			break;
+		case cryptocop_alg_csum:
+			/* digest */
+			if (csum_ctx.tcfg != NULL){
+				DEBUG_API(printk("cryptocop_setup_dma_list: multiple checksums in operation.\n"));
+				failed = -EINVAL;
+				goto error_cleanup;
+			}
+			(*int_op)->csum_mode = tctx->init.csum_mode;
+			csum_ctx.tcfg = tcfg;
+			csum_ctx.tctx = tctx;
+			break;
+		default:
+			/* no algorithm. */
+			DEBUG_API(printk("cryptocop_setup_dma_list: invalid algorithm %d specified in tfrm %d.\n", tctx->init.alg, tcfg->tid));
+			failed = -EINVAL;
+			goto error_cleanup;
+		}
+		tcfg = tcfg->next;
+	}
+	/* Download key if a cipher is used. */
+	if (cipher_ctx.tcfg && (cipher_ctx.tctx->init.alg != cryptocop_alg_mem2mem)){
+		struct cryptocop_dma_desc  *key_desc = NULL;
+
+		failed = setup_key_dl_desc(&cipher_ctx, &key_desc, alloc_flag);
+		if (failed) {
+			DEBUG_API(printk("cryptocop_setup_dma_list: setup key dl\n"));
+			goto error_cleanup;
+		}
+		current_out_cdesc->next = key_desc;
+		current_out_cdesc = key_desc;
+		indata_ix += (unsigned int)(key_desc->dma_descr->after - key_desc->dma_descr->buf);
+
+		/* Download explicit IV if a cipher is used and CBC mode and explicit IV selected. */
+		if ((cipher_ctx.tctx->init.cipher_mode == cryptocop_cipher_mode_cbc) && (cipher_ctx.tcfg->flags & CRYPTOCOP_EXPLICIT_IV)) {
+			struct cryptocop_dma_desc  *iv_desc = NULL;
+
+			DEBUG(printk("cryptocop_setup_dma_list: setup cipher CBC IV descriptor.\n"));
+
+			failed = setup_cipher_iv_desc(&cipher_ctx, &iv_desc, alloc_flag);
+			if (failed) {
+				DEBUG_API(printk("cryptocop_setup_dma_list: CBC IV descriptor.\n"));
+				goto error_cleanup;
+			}
+			current_out_cdesc->next = iv_desc;
+			current_out_cdesc = iv_desc;
+			indata_ix += (unsigned int)(iv_desc->dma_descr->after - iv_desc->dma_descr->buf);
+		}
+	}
+
+	/* Process descriptors. */
+	odsc = operation->tfrm_op.desc;
+	while (odsc) {
+		struct cryptocop_desc_cfg   *dcfg = odsc->cfg;
+		struct strcop_meta_out      meta_out = {0};
+		size_t                      desc_len = odsc->length;
+		int                         active_count, eop_needed_count;
+
+		output_tc = NULL;
+
+		DEBUG(printk("cryptocop_setup_dma_list: parsing an operation descriptor\n"));
+
+		while (dcfg) {
+			struct cryptocop_tfrm_ctx  *tc = NULL;
+
+			DEBUG(printk("cryptocop_setup_dma_list: parsing an operation descriptor configuration.\n"));
+			/* Get the local context for the transform and mark it as the output unit if it produces output. */
+			if (digest_ctx.tcfg && (digest_ctx.tcfg->tid == dcfg->tid)){
+				tc = &digest_ctx;
+			} else if (cipher_ctx.tcfg && (cipher_ctx.tcfg->tid == dcfg->tid)){
+				tc = &cipher_ctx;
+			} else if (csum_ctx.tcfg && (csum_ctx.tcfg->tid == dcfg->tid)){
+				tc = &csum_ctx;
+			}
+			if (!tc) {
+				DEBUG_API(printk("cryptocop_setup_dma_list: invalid transform %d specified in descriptor.\n", dcfg->tid));
+				failed = -EINVAL;
+				goto error_cleanup;
+			}
+			if (tc->done) {
+				DEBUG_API(printk("cryptocop_setup_dma_list: completed transform %d reused.\n", dcfg->tid));
+				failed = -EINVAL;
+				goto error_cleanup;
+			}
+			if (!tc->active) {
+				tc->start_ix = indata_ix;
+				tc->active = 1;
+			}
+
+			tc->previous_src = tc->current_src;
+			tc->prev_src = tc->curr_src;
+			/* Map source unit id to DMA source config. */
+			switch (dcfg->src){
+			case cryptocop_source_dma:
+				tc->current_src = src_dma;
+				break;
+			case cryptocop_source_des:
+				tc->current_src = src_des;
+				break;
+			case cryptocop_source_3des:
+				tc->current_src = src_des;
+				break;
+			case cryptocop_source_aes:
+				tc->current_src = src_aes;
+				break;
+			case cryptocop_source_md5:
+			case cryptocop_source_sha1:
+			case cryptocop_source_csum:
+			case cryptocop_source_none:
+			default:
+				/* We do not allow using accumulating style units (SHA-1, MD5, checksum) as sources to other units.
+				 */
+				DEBUG_API(printk("cryptocop_setup_dma_list: bad unit source configured %d.\n", dcfg->src));
+				failed = -EINVAL;
+				goto error_cleanup;
+			}
+			if (tc->current_src != src_dma) {
+				/* Find the unit we are sourcing from. */
+				if (digest_ctx.unit_no == tc->current_src){
+					tc->curr_src = &digest_ctx;
+				} else if (cipher_ctx.unit_no == tc->current_src){
+					tc->curr_src = &cipher_ctx;
+				} else if (csum_ctx.unit_no == tc->current_src){
+					tc->curr_src = &csum_ctx;
+				}
+				if ((tc->curr_src == tc) && (tc->unit_no != src_dma)){
+					DEBUG_API(printk("cryptocop_setup_dma_list: unit %d configured to source from itself.\n", tc->unit_no));
+					failed = -EINVAL;
+					goto error_cleanup;
+				}
+			} else {
+				tc->curr_src = NULL;
+			}
+
+			/* Detect source switch. */
+			DEBUG(printk("cryptocop_setup_dma_list: tc->active=%d tc->unit_no=%d tc->current_src=%d tc->previous_src=%d, tc->curr_src=0x%p, tc->prev_srv=0x%p\n", tc->active, tc->unit_no, tc->current_src, tc->previous_src, tc->curr_src, tc->prev_src));
+			if (tc->active && (tc->current_src != tc->previous_src)) {
+				/* Only allow source switch when both the old source unit and the new one have
+				 * no pending data to process (i.e. the consumed length must be a multiple of the
+				 * transform blocklength). */
+				/* Note: if the src == NULL we are actually sourcing from DMA out. */
+				if (((tc->prev_src != NULL) && (tc->prev_src->consumed % tc->prev_src->blocklength)) ||
+				    ((tc->curr_src != NULL) && (tc->curr_src->consumed % tc->curr_src->blocklength)))
+				{
+					DEBUG_API(printk("cryptocop_setup_dma_list: can only disconnect from or connect to a unit on a multiple of the blocklength, old: cons=%d, prod=%d, block=%d, new: cons=%d prod=%d, block=%d.\n", tc->prev_src ? tc->prev_src->consumed : INT_MIN, tc->prev_src ? tc->prev_src->produced : INT_MIN, tc->prev_src ? tc->prev_src->blocklength : INT_MIN, tc->curr_src ? tc->curr_src->consumed : INT_MIN, tc->curr_src ? tc->curr_src->produced : INT_MIN, tc->curr_src ? tc->curr_src->blocklength : INT_MIN));
+					failed = -EINVAL;
+					goto error_cleanup;
+				}
+			}
+			/* Detect unit deactivation. */
+			if (dcfg->last) {
+				/* Length check of this is handled below. */
+				tc->done = 1;
+			}
+			dcfg = dcfg->next;
+		} /* while (dcfg) */
+		DEBUG(printk("cryptocop_setup_dma_list: parsing operation descriptor configuration complete.\n"));
+
+		if (cipher_ctx.active && (cipher_ctx.curr_src != NULL) && !cipher_ctx.curr_src->active){
+			DEBUG_API(printk("cryptocop_setup_dma_list: cipher source from inactive unit %d\n", cipher_ctx.curr_src->unit_no));
+			failed = -EINVAL;
+			goto error_cleanup;
+		}
+		if (digest_ctx.active && (digest_ctx.curr_src != NULL) && !digest_ctx.curr_src->active){
+			DEBUG_API(printk("cryptocop_setup_dma_list: digest source from inactive unit %d\n", digest_ctx.curr_src->unit_no));
+			failed = -EINVAL;
+			goto error_cleanup;
+		}
+		if (csum_ctx.active && (csum_ctx.curr_src != NULL) && !csum_ctx.curr_src->active){
+			DEBUG_API(printk("cryptocop_setup_dma_list: cipher source from inactive unit %d\n", csum_ctx.curr_src->unit_no));
+			failed = -EINVAL;
+			goto error_cleanup;
+		}
+
+		/* Update consumed and produced lengths.
+
+		   The consumed length accounting here is actually cheating.  If a unit source from DMA (or any
+		   other unit that process data in blocks of one octet) it is correct, but if it source from a
+		   block processing unit, i.e. a cipher, it will be temporarily incorrect at some times.  However
+		   since it is only allowed--by the HW--to change source to or from a block processing unit at times where that
+		   unit has processed an exact multiple of its block length the end result will be correct.
+		   Beware that if the source change restriction change this code will need to be (much) reworked.
+		*/
+		DEBUG(printk("cryptocop_setup_dma_list: desc->length=%d, desc_len=%d.\n", odsc->length, desc_len));
+
+		if (csum_ctx.active) {
+			csum_ctx.consumed += desc_len;
+			if (csum_ctx.done) {
+				csum_ctx.produced = 2;
+			}
+			DEBUG(printk("cryptocop_setup_dma_list: csum_ctx producing: consumed=%d, produced=%d, blocklength=%d.\n", csum_ctx.consumed, csum_ctx.produced, csum_ctx.blocklength));
+		}
+		if (digest_ctx.active) {
+			digest_ctx.consumed += desc_len;
+			if (digest_ctx.done) {
+				if (digest_ctx.unit_no == src_md5) {
+					digest_ctx.produced = MD5_STATE_LENGTH;
+				} else {
+					digest_ctx.produced = SHA1_STATE_LENGTH;
+				}
+			}
+			DEBUG(printk("cryptocop_setup_dma_list: digest_ctx producing: consumed=%d, produced=%d, blocklength=%d.\n", digest_ctx.consumed, digest_ctx.produced, digest_ctx.blocklength));
+		}
+		if (cipher_ctx.active) {
+			/* Ciphers are allowed only to source from DMA out.  That is filtered above. */
+			assert(cipher_ctx.current_src == src_dma);
+			cipher_ctx.consumed += desc_len;
+			cipher_ctx.produced = cipher_ctx.blocklength * (cipher_ctx.consumed / cipher_ctx.blocklength);
+			if (cipher_ctx.cbcmode && !(cipher_ctx.tcfg->flags & CRYPTOCOP_EXPLICIT_IV) && cipher_ctx.produced){
+				cipher_ctx.produced -= cipher_ctx.blocklength; /* Compensate for CBC iv. */
+			}
+			DEBUG(printk("cryptocop_setup_dma_list: cipher_ctx producing: consumed=%d, produced=%d, blocklength=%d.\n", cipher_ctx.consumed, cipher_ctx.produced, cipher_ctx.blocklength));
+		}
+
+		/* Setup the DMA out descriptors. */
+		/* Configure the metadata. */
+		active_count = 0;
+		eop_needed_count = 0;
+		if (cipher_ctx.active) {
+			++active_count;
+			if (cipher_ctx.unit_no == src_dma){
+				/* mem2mem */
+				meta_out.ciphsel = src_none;
+			} else {
+				meta_out.ciphsel = cipher_ctx.current_src;
+			}
+			meta_out.ciphconf = cipher_ctx.ciph_conf;
+			meta_out.cbcmode = cipher_ctx.cbcmode;
+			meta_out.decrypt = cipher_ctx.decrypt;
+			DEBUG(printk("set ciphsel=%d ciphconf=%d cbcmode=%d decrypt=%d\n", meta_out.ciphsel, meta_out.ciphconf, meta_out.cbcmode, meta_out.decrypt));
+			if (cipher_ctx.done) ++eop_needed_count;
+		} else {
+			meta_out.ciphsel = src_none;
+		}
+
+		if (digest_ctx.active) {
+			++active_count;
+			meta_out.hashsel = digest_ctx.current_src;
+			meta_out.hashconf = digest_ctx.hash_conf;
+			meta_out.hashmode = 0; /* Explicit mode is not used here. */
+			DEBUG(printk("set hashsel=%d hashconf=%d hashmode=%d\n", meta_out.hashsel, meta_out.hashconf, meta_out.hashmode));
+			if (digest_ctx.done) {
+				assert(digest_ctx.pad_descs == NULL);
+				failed = create_pad_descriptor(&digest_ctx, &digest_ctx.pad_descs, alloc_flag);
+				if (failed) {
+					DEBUG_API(printk("cryptocop_setup_dma_list: failed digest pad creation.\n"));
+					goto error_cleanup;
+				}
+			}
+		} else {
+			meta_out.hashsel = src_none;
+		}
+
+		if (csum_ctx.active) {
+			++active_count;
+			meta_out.csumsel = csum_ctx.current_src;
+			if (csum_ctx.done) {
+				assert(csum_ctx.pad_descs == NULL);
+				failed = create_pad_descriptor(&csum_ctx, &csum_ctx.pad_descs, alloc_flag);
+				if (failed) {
+					DEBUG_API(printk("cryptocop_setup_dma_list: failed csum pad creation.\n"));
+					goto error_cleanup;
+				}
+			}
+		} else {
+			meta_out.csumsel = src_none;
+		}
+		DEBUG(printk("cryptocop_setup_dma_list: %d eop needed, %d active units\n", eop_needed_count, active_count));
+		/* Setup DMA out descriptors for the indata. */
+		failed = create_output_descriptors(operation, &iniov_ix, &iniov_offset, desc_len, &current_out_cdesc, &meta_out, alloc_flag);
+		if (failed) {
+			DEBUG_API(printk("cryptocop_setup_dma_list: create_output_descriptors %d\n", failed));
+			goto error_cleanup;
+		}
+		/* Setup out EOP.  If there are active units that are not done here they cannot get an EOP
+		 * so we ust setup a zero length descriptor to DMA to signal EOP only to done units.
+		 * If there is a pad descriptor EOP for the padded unit will be EOPed by it.
+		 */
+		assert(active_count >= eop_needed_count);
+		assert((eop_needed_count == 0) || (eop_needed_count == 1));
+		if (eop_needed_count) {
+			/* This means that the bulk operation (cipeher/m2m) is terminated. */
+			if (active_count > 1) {
+				/* Use zero length EOP descriptor. */
+				struct cryptocop_dma_desc *ed = alloc_cdesc(alloc_flag);
+				struct strcop_meta_out    ed_mo = {0};
+				if (!ed) {
+					DEBUG_API(printk("cryptocop_setup_dma_list: alloc EOP descriptor for cipher\n"));
+					failed = -ENOMEM;
+					goto error_cleanup;
+				}
+
+				assert(cipher_ctx.active && cipher_ctx.done);
+
+				if (cipher_ctx.unit_no == src_dma){
+					/* mem2mem */
+					ed_mo.ciphsel = src_none;
+				} else {
+					ed_mo.ciphsel = cipher_ctx.current_src;
+				}
+				ed_mo.ciphconf = cipher_ctx.ciph_conf;
+				ed_mo.cbcmode = cipher_ctx.cbcmode;
+				ed_mo.decrypt = cipher_ctx.decrypt;
+
+				ed->free_buf = NULL;
+				ed->dma_descr->wait = 1;
+				ed->dma_descr->out_eop = 1;
+
+				ed->dma_descr->buf = (char*)virt_to_phys(&ed); /* Use any valid physical address for zero length descriptor. */
+				ed->dma_descr->after = ed->dma_descr->buf;
+				ed->dma_descr->md = REG_TYPE_CONV(unsigned short int, struct strcop_meta_out, ed_mo);
+				current_out_cdesc->next = ed;
+				current_out_cdesc = ed;
+			} else {
+				/* Set EOP in the current out descriptor since the only active module is
+				 * the one needing the EOP. */
+
+				current_out_cdesc->dma_descr->out_eop = 1;
+			}
+		}
+
+		if (cipher_ctx.done && cipher_ctx.active) cipher_ctx.active = 0;
+		if (digest_ctx.done && digest_ctx.active) digest_ctx.active = 0;
+		if (csum_ctx.done && csum_ctx.active) csum_ctx.active = 0;
+		indata_ix += odsc->length;
+		odsc = odsc->next;
+	} /* while (odsc) */ /* Process descriptors. */
+	DEBUG(printk("cryptocop_setup_dma_list: done parsing operation descriptors\n"));
+	if (cipher_ctx.tcfg && (cipher_ctx.active || !cipher_ctx.done)){
+		DEBUG_API(printk("cryptocop_setup_dma_list: cipher operation not terminated.\n"));
+		failed = -EINVAL;
+		goto error_cleanup;
+	}
+	if (digest_ctx.tcfg && (digest_ctx.active || !digest_ctx.done)){
+		DEBUG_API(printk("cryptocop_setup_dma_list: digest operation not terminated.\n"));
+		failed = -EINVAL;
+		goto error_cleanup;
+	}
+	if (csum_ctx.tcfg && (csum_ctx.active || !csum_ctx.done)){
+		DEBUG_API(printk("cryptocop_setup_dma_list: csum operation not terminated.\n"));
+		failed = -EINVAL;
+		goto error_cleanup;
+	}
+
+	failed = append_input_descriptors(operation, &current_in_cdesc, &current_out_cdesc, &cipher_ctx, alloc_flag);
+	if (failed){
+		DEBUG_API(printk("cryptocop_setup_dma_list: append_input_descriptors cipher_ctx %d\n", failed));
+		goto error_cleanup;
+	}
+	failed = append_input_descriptors(operation, &current_in_cdesc, &current_out_cdesc, &digest_ctx, alloc_flag);
+	if (failed){
+		DEBUG_API(printk("cryptocop_setup_dma_list: append_input_descriptors cipher_ctx %d\n", failed));
+		goto error_cleanup;
+	}
+	failed = append_input_descriptors(operation, &current_in_cdesc, &current_out_cdesc, &csum_ctx, alloc_flag);
+	if (failed){
+		DEBUG_API(printk("cryptocop_setup_dma_list: append_input_descriptors cipher_ctx %d\n", failed));
+		goto error_cleanup;
+	}
+
+	DEBUG(printk("cryptocop_setup_dma_list: int_op=0x%p, *int_op=0x%p\n", int_op, *int_op));
+	(*int_op)->cdesc_out = out_cdesc_head.next;
+	(*int_op)->cdesc_in = in_cdesc_head.next;
+	DEBUG(printk("cryptocop_setup_dma_list: out_cdesc_head=0x%p in_cdesc_head=0x%p\n", (*int_op)->cdesc_out, (*int_op)->cdesc_in));
+
+	setup_descr_chain(out_cdesc_head.next);
+	setup_descr_chain(in_cdesc_head.next);
+
+	/* Last but not least: mark the last DMA in descriptor for a INTR and EOL and the the
+	 * last DMA out descriptor for EOL.
+	 */
+	current_in_cdesc->dma_descr->intr = 1;
+	current_in_cdesc->dma_descr->eol = 1;
+	current_out_cdesc->dma_descr->eol = 1;
+
+	/* Setup DMA contexts. */
+	(*int_op)->ctx_out.next = NULL;
+	(*int_op)->ctx_out.eol = 1;
+	(*int_op)->ctx_out.intr = 0;
+	(*int_op)->ctx_out.store_mode = 0;
+	(*int_op)->ctx_out.en = 0;
+	(*int_op)->ctx_out.dis = 0;
+	(*int_op)->ctx_out.md0 = 0;
+	(*int_op)->ctx_out.md1 = 0;
+	(*int_op)->ctx_out.md2 = 0;
+	(*int_op)->ctx_out.md3 = 0;
+	(*int_op)->ctx_out.md4 = 0;
+	(*int_op)->ctx_out.saved_data = (dma_descr_data*)virt_to_phys((*int_op)->cdesc_out->dma_descr);
+	(*int_op)->ctx_out.saved_data_buf = (*int_op)->cdesc_out->dma_descr->buf; /* Already physical address. */
+
+	(*int_op)->ctx_in.next = NULL;
+	(*int_op)->ctx_in.eol = 1;
+	(*int_op)->ctx_in.intr = 0;
+	(*int_op)->ctx_in.store_mode = 0;
+	(*int_op)->ctx_in.en = 0;
+	(*int_op)->ctx_in.dis = 0;
+	(*int_op)->ctx_in.md0 = 0;
+	(*int_op)->ctx_in.md1 = 0;
+	(*int_op)->ctx_in.md2 = 0;
+	(*int_op)->ctx_in.md3 = 0;
+	(*int_op)->ctx_in.md4 = 0;
+
+	(*int_op)->ctx_in.saved_data = (dma_descr_data*)virt_to_phys((*int_op)->cdesc_in->dma_descr);
+	(*int_op)->ctx_in.saved_data_buf = (*int_op)->cdesc_in->dma_descr->buf; /* Already physical address. */
+
+	DEBUG(printk("cryptocop_setup_dma_list: done\n"));
+	return 0;
+
+error_cleanup:
+	{
+		/* Free all allocated resources. */
+		struct cryptocop_dma_desc *tmp_cdesc;
+		while (digest_ctx.pad_descs){
+			tmp_cdesc = digest_ctx.pad_descs->next;
+			free_cdesc(digest_ctx.pad_descs);
+			digest_ctx.pad_descs = tmp_cdesc;
+		}
+		while (csum_ctx.pad_descs){
+			tmp_cdesc = csum_ctx.pad_descs->next;
+			free_cdesc(csum_ctx.pad_descs);
+			csum_ctx.pad_descs = tmp_cdesc;
+		}
+		assert(cipher_ctx.pad_descs == NULL); /* The ciphers are never padded. */
+
+		if (*int_op != NULL) delete_internal_operation(*int_op);
+	}
+	DEBUG_API(printk("cryptocop_setup_dma_list: done with error %d\n", failed));
+	return failed;
+}
+
+
+static void delete_internal_operation(struct cryptocop_int_operation *iop)
+{
+	void                      *ptr = iop->alloc_ptr;
+	struct cryptocop_dma_desc *cd = iop->cdesc_out;
+	struct cryptocop_dma_desc *next;
+
+	DEBUG(printk("delete_internal_operation: iop=0x%p, alloc_ptr=0x%p\n", iop, ptr));
+
+	while (cd) {
+		next = cd->next;
+		free_cdesc(cd);
+		cd = next;
+	}
+	cd = iop->cdesc_in;
+	while (cd) {
+		next = cd->next;
+		free_cdesc(cd);
+		cd = next;
+	}
+	kfree(ptr);
+}
+
+#define MD5_MIN_PAD_LENGTH (9)
+#define MD5_PAD_LENGTH_FIELD_LENGTH (8)
+
+static int create_md5_pad(int alloc_flag, unsigned long long hashed_length, char **pad, size_t *pad_length)
+{
+	size_t                  padlen = MD5_BLOCK_LENGTH - (hashed_length % MD5_BLOCK_LENGTH);
+	unsigned char           *p;
+	int                     i;
+	unsigned long long int  bit_length = hashed_length << 3;
+
+	if (padlen < MD5_MIN_PAD_LENGTH) padlen += MD5_BLOCK_LENGTH;
+
+	p = kmalloc(padlen, alloc_flag);
+	if (!pad) return -ENOMEM;
+
+	*p = 0x80;
+	memset(p+1, 0, padlen - 1);
+
+	DEBUG(printk("create_md5_pad: hashed_length=%lld bits == %lld bytes\n", bit_length, hashed_length));
+
+	i = padlen - MD5_PAD_LENGTH_FIELD_LENGTH;
+	while (bit_length != 0){
+		p[i++] = bit_length % 0x100;
+		bit_length >>= 8;
+	}
+
+	*pad = (char*)p;
+	*pad_length = padlen;
+
+	return 0;
+}
+
+#define SHA1_MIN_PAD_LENGTH (9)
+#define SHA1_PAD_LENGTH_FIELD_LENGTH (8)
+
+static int create_sha1_pad(int alloc_flag, unsigned long long hashed_length, char **pad, size_t *pad_length)
+{
+	size_t                  padlen = SHA1_BLOCK_LENGTH - (hashed_length % SHA1_BLOCK_LENGTH);
+	unsigned char           *p;
+	int                     i;
+	unsigned long long int  bit_length = hashed_length << 3;
+
+	if (padlen < SHA1_MIN_PAD_LENGTH) padlen += SHA1_BLOCK_LENGTH;
+
+	p = kmalloc(padlen, alloc_flag);
+	if (!pad) return -ENOMEM;
+
+	*p = 0x80;
+	memset(p+1, 0, padlen - 1);
+
+	DEBUG(printk("create_sha1_pad: hashed_length=%lld bits == %lld bytes\n", bit_length, hashed_length));
+
+	i = padlen - 1;
+	while (bit_length != 0){
+		p[i--] = bit_length % 0x100;
+		bit_length >>= 8;
+	}
+
+	*pad = (char*)p;
+	*pad_length = padlen;
+
+	return 0;
+}
+
+
+static int transform_ok(struct cryptocop_transform_init *tinit)
+{
+	switch (tinit->alg){
+	case cryptocop_alg_csum:
+		switch (tinit->csum_mode){
+		case cryptocop_csum_le:
+		case cryptocop_csum_be:
+			break;
+		default:
+			DEBUG_API(printk("transform_ok: Bad mode set for csum transform\n"));
+			return -EINVAL;
+		}
+	case cryptocop_alg_mem2mem:
+	case cryptocop_alg_md5:
+	case cryptocop_alg_sha1:
+		if (tinit->keylen != 0) {
+			DEBUG_API(printk("transform_ok: non-zero keylength, %d, for a digest/csum algorithm\n", tinit->keylen));
+			return -EINVAL; /* This check is a bit strict. */
+		}
+		break;
+	case cryptocop_alg_des:
+		if (tinit->keylen != 64) {
+			DEBUG_API(printk("transform_ok: keylen %d invalid for DES\n", tinit->keylen));
+			return -EINVAL;
+		}
+		break;
+	case cryptocop_alg_3des:
+		if (tinit->keylen != 192) {
+			DEBUG_API(printk("transform_ok: keylen %d invalid for 3DES\n", tinit->keylen));
+			return -EINVAL;
+		}
+		break;
+	case cryptocop_alg_aes:
+		if (tinit->keylen != 128 && tinit->keylen != 192 && tinit->keylen != 256) {
+			DEBUG_API(printk("transform_ok: keylen %d invalid for AES\n", tinit->keylen));
+			return -EINVAL;
+		}
+		break;
+	case cryptocop_no_alg:
+	default:
+		DEBUG_API(printk("transform_ok: no such algorithm %d\n", tinit->alg));
+		return -EINVAL;
+	}
+
+	switch (tinit->alg){
+	case cryptocop_alg_des:
+	case cryptocop_alg_3des:
+	case cryptocop_alg_aes:
+		if (tinit->cipher_mode != cryptocop_cipher_mode_ecb && tinit->cipher_mode != cryptocop_cipher_mode_cbc) return -EINVAL;
+	default:
+		 break;
+	}
+	return 0;
+}
+
+
+int cryptocop_new_session(cryptocop_session_id *sid, struct cryptocop_transform_init *tinit, int alloc_flag)
+{
+	struct cryptocop_session         *sess;
+	struct cryptocop_transform_init  *tfrm_in = tinit;
+	struct cryptocop_transform_init  *tmp_in;
+	int                              no_tfrms = 0;
+	int                              i;
+	unsigned long int                flags;
+
+	init_stream_coprocessor(); /* For safety if we are called early */
+
+	while (tfrm_in){
+		int err;
+		++no_tfrms;
+		if ((err = transform_ok(tfrm_in))) {
+			DEBUG_API(printk("cryptocop_new_session, bad transform\n"));
+			return err;
+		}
+		tfrm_in = tfrm_in->next;
+	}
+	if (0 == no_tfrms) {
+		DEBUG_API(printk("cryptocop_new_session, no transforms specified\n"));
+		return -EINVAL;
+	}
+
+	sess = kmalloc(sizeof(struct cryptocop_session), alloc_flag);
+	if (!sess){
+		DEBUG_API(printk("cryptocop_new_session, kmalloc cryptocop_session\n"));
+		return -ENOMEM;
+	}
+
+	sess->tfrm_ctx = kmalloc(no_tfrms * sizeof(struct cryptocop_transform_ctx), alloc_flag);
+	if (!sess->tfrm_ctx) {
+		DEBUG_API(printk("cryptocop_new_session, kmalloc cryptocop_transform_ctx\n"));
+		kfree(sess);
+		return -ENOMEM;
+	}
+
+	tfrm_in = tinit;
+	for (i = 0; i < no_tfrms; i++){
+		tmp_in = tfrm_in->next;
+		while (tmp_in){
+			if (tmp_in->tid == tfrm_in->tid) {
+				DEBUG_API(printk("cryptocop_new_session, duplicate transform ids\n"));
+				kfree(sess->tfrm_ctx);
+				kfree(sess);
+				return -EINVAL;
+			}
+			tmp_in = tmp_in->next;
+		}
+		memcpy(&sess->tfrm_ctx[i].init, tfrm_in, sizeof(struct cryptocop_transform_init));
+		sess->tfrm_ctx[i].dec_key_set = 0;
+		sess->tfrm_ctx[i].next = &sess->tfrm_ctx[i] + 1;
+
+		tfrm_in = tfrm_in->next;
+	}
+	sess->tfrm_ctx[i-1].next = NULL;
+
+	spin_lock_irqsave(&cryptocop_sessions_lock, flags);
+	sess->sid = next_sid;
+	next_sid++;
+	/* TODO If we are really paranoid we should do duplicate check to handle sid wraparound.
+	 *      OTOH 2^64 is a really large number of session. */
+	if (next_sid == 0) next_sid = 1;
+
+	/* Prepend to session list. */
+	sess->next = cryptocop_sessions;
+	cryptocop_sessions = sess;
+	spin_unlock_irqrestore(&cryptocop_sessions_lock, flags);
+	*sid = sess->sid;
+	return 0;
+}
+
+
+int cryptocop_free_session(cryptocop_session_id sid)
+{
+	struct cryptocop_transform_ctx    *tc;
+	struct cryptocop_session          *sess = NULL;
+	struct cryptocop_session          *psess = NULL;
+	unsigned long int                 flags;
+	int                               i;
+	LIST_HEAD(remove_list);
+	struct list_head                  *node, *tmp;
+	struct cryptocop_prio_job         *pj;
+
+	DEBUG(printk("cryptocop_free_session: sid=%lld\n", sid));
+
+	spin_lock_irqsave(&cryptocop_sessions_lock, flags);
+	sess = cryptocop_sessions;
+	while (sess && sess->sid != sid){
+		psess = sess;
+		sess = sess->next;
+	}
+	if (sess){
+		if (psess){
+			psess->next = sess->next;
+		} else {
+			cryptocop_sessions = sess->next;
+		}
+	}
+	spin_unlock_irqrestore(&cryptocop_sessions_lock, flags);
+
+	if (!sess) return -EINVAL;
+
+	/* Remove queued jobs. */
+	spin_lock_irqsave(&cryptocop_job_queue_lock, flags);
+
+	for (i = 0; i < cryptocop_prio_no_prios; i++){
+		if (!list_empty(&(cryptocop_job_queues[i].jobs))){
+			list_for_each_safe(node, tmp, &(cryptocop_job_queues[i].jobs)) {
+				pj = list_entry(node, struct cryptocop_prio_job, node);
+				if (pj->oper->sid == sid) {
+					list_move_tail(node, &remove_list);
+				}
+			}
+		}
+	}
+	spin_unlock_irqrestore(&cryptocop_job_queue_lock, flags);
+
+	list_for_each_safe(node, tmp, &remove_list) {
+		list_del(node);
+		pj = list_entry(node, struct cryptocop_prio_job, node);
+		pj->oper->operation_status = -EAGAIN;  /* EAGAIN is not ideal for job/session terminated but it's the best choice I know of. */
+		DEBUG(printk("cryptocop_free_session: pj=0x%p, pj->oper=0x%p, pj->iop=0x%p\n", pj, pj->oper, pj->iop));
+		pj->oper->cb(pj->oper, pj->oper->cb_data);
+		delete_internal_operation(pj->iop);
+		kfree(pj);
+	}
+
+	tc = sess->tfrm_ctx;
+	/* Erase keying data. */
+	while (tc){
+		DEBUG(printk("cryptocop_free_session: memset keys, tfrm id=%d\n", tc->init.tid));
+		memset(tc->init.key, 0xff, CRYPTOCOP_MAX_KEY_LENGTH);
+		memset(tc->dec_key, 0xff, CRYPTOCOP_MAX_KEY_LENGTH);
+		tc = tc->next;
+	}
+	kfree(sess->tfrm_ctx);
+	kfree(sess);
+
+	return 0;
+}
+
+static struct cryptocop_session *get_session(cryptocop_session_id sid)
+{
+	struct cryptocop_session    *sess;
+	unsigned long int           flags;
+
+	spin_lock_irqsave(&cryptocop_sessions_lock, flags);
+	sess = cryptocop_sessions;
+	while (sess && (sess->sid != sid)){
+		sess = sess->next;
+	}
+	spin_unlock_irqrestore(&cryptocop_sessions_lock, flags);
+
+	return sess;
+}
+
+static struct cryptocop_transform_ctx *get_transform_ctx(struct cryptocop_session *sess, cryptocop_tfrm_id tid)
+{
+	struct cryptocop_transform_ctx *tc = sess->tfrm_ctx;
+
+	DEBUG(printk("get_transform_ctx, sess=0x%p, tid=%d\n", sess, tid));
+	assert(sess != NULL);
+	while (tc && tc->init.tid != tid){
+		DEBUG(printk("tc=0x%p, tc->next=0x%p\n", tc, tc->next));
+		tc = tc->next;
+	}
+	DEBUG(printk("get_transform_ctx, returning tc=0x%p\n", tc));
+	return tc;
+}
+
+
+
+/* The AES s-transform matrix (s-box). */
+static const u8 aes_sbox[256] = {
+	99,  124, 119, 123, 242, 107, 111, 197, 48,  1,   103, 43,  254, 215, 171, 118,
+	202, 130, 201, 125, 250, 89,  71,  240, 173, 212, 162, 175, 156, 164, 114, 192,
+	183, 253, 147, 38,  54,  63,  247, 204, 52,  165, 229, 241, 113, 216, 49,  21,
+	4,   199, 35,  195, 24,  150, 5,   154, 7,   18,  128, 226, 235, 39,  178, 117,
+	9,   131, 44,  26,  27,  110, 90,  160, 82,  59,  214, 179, 41,  227, 47,  132,
+	83,  209, 0,   237, 32,  252, 177, 91,  106, 203, 190, 57,  74,  76,  88,  207,
+	208, 239, 170, 251, 67,  77,  51,  133, 69,  249, 2,   127, 80,  60,  159, 168,
+	81,  163, 64,  143, 146, 157, 56,  245, 188, 182, 218, 33,  16,  255, 243, 210,
+	205, 12,  19,  236, 95,  151, 68,  23,  196, 167, 126, 61,  100, 93,  25,  115,
+	96,  129, 79,  220, 34,  42,  144, 136, 70,  238, 184, 20,  222, 94,  11,  219,
+	224, 50,  58,  10,  73,  6,   36,  92,  194, 211, 172, 98,  145, 149, 228, 121,
+	231, 200, 55,  109, 141, 213, 78,  169, 108, 86,  244, 234, 101, 122, 174, 8,
+	186, 120, 37,  46,  28,  166, 180, 198, 232, 221, 116, 31,  75,  189, 139, 138,
+	112, 62,  181, 102, 72,  3,   246, 14,  97,  53,  87,  185, 134, 193, 29,  158,
+	225, 248, 152, 17,  105, 217, 142, 148, 155, 30,  135, 233, 206, 85,  40,  223,
+	140, 161, 137, 13,  191, 230, 66,  104, 65,  153, 45,  15,  176, 84,  187, 22
+};
+
+/* AES has a 32 bit word round constants for each round in the
+ * key schedule.  round_constant[i] is really Rcon[i+1] in FIPS187.
+ */
+static u32 round_constant[11] = {
+	0x01000000, 0x02000000, 0x04000000, 0x08000000,
+	0x10000000, 0x20000000, 0x40000000, 0x80000000,
+	0x1B000000, 0x36000000, 0x6C000000
+};
+
+/* Apply the s-box to each of the four occtets in w. */
+static u32 aes_ks_subword(const u32 w)
+{
+	u8 bytes[4];
+
+	*(u32*)(&bytes[0]) = w;
+	bytes[0] = aes_sbox[bytes[0]];
+	bytes[1] = aes_sbox[bytes[1]];
+	bytes[2] = aes_sbox[bytes[2]];
+	bytes[3] = aes_sbox[bytes[3]];
+	return *(u32*)(&bytes[0]);
+}
+
+/* The encrypt (forward) Rijndael key schedule algorithm pseudo code:
+ * (Note that AES words are 32 bit long)
+ *
+ * KeyExpansion(byte key[4*Nk], word w[Nb*(Nr+1)], Nk){
+ * word temp
+ * i = 0
+ * while (i < Nk) {
+ *   w[i] = word(key[4*i, 4*i + 1, 4*i + 2, 4*i + 3])
+ *   i = i + 1
+ * }
+ * i = Nk
+ *
+ * while (i < (Nb * (Nr + 1))) {
+ *   temp = w[i - 1]
+ *   if ((i mod Nk) == 0) {
+ *     temp = SubWord(RotWord(temp)) xor Rcon[i/Nk]
+ *   }
+ *   else if ((Nk > 6) && ((i mod Nk) == 4)) {
+ *     temp = SubWord(temp)
+ *   }
+ *   w[i] = w[i - Nk] xor temp
+ * }
+ * RotWord(t) does a 8 bit cyclic shift left on a 32 bit word.
+ * SubWord(t) applies the AES s-box individually to each octet
+ * in a 32 bit word.
+ *
+ * For AES Nk can have the values 4, 6, and 8 (corresponding to
+ * values for Nr of 10, 12, and 14).  Nb is always 4.
+ *
+ * To construct w[i], w[i - 1] and w[i - Nk] must be
+ * available.  Consequently we must keep a state of the last Nk words
+ * to be able to create the last round keys.
+ */
+static void get_aes_decrypt_key(unsigned char *dec_key, const unsigned  char *key, unsigned int keylength)
+{
+	u32 temp;
+	u32 w_ring[8]; /* nk is max 8, use elements 0..(nk - 1) as a ringbuffer */
+	u8  w_last_ix;
+	int i;
+	u8  nr, nk;
+
+	switch (keylength){
+	case 128:
+		nk = 4;
+		nr = 10;
+		break;
+	case 192:
+		nk = 6;
+		nr = 12;
+		break;
+	case 256:
+		nk = 8;
+		nr = 14;
+		break;
+	default:
+		panic("stream co-processor: bad aes key length in get_aes_decrypt_key\n");
+	};
+
+	/* Need to do host byte order correction here since key is byte oriented and the
+	 * kx algorithm is word (u32) oriented. */
+	for (i = 0; i < nk; i+=1) {
+		w_ring[i] = be32_to_cpu(*(u32*)&key[4*i]);
+	}
+
+	i = (int)nk;
+	w_last_ix = i - 1;
+	while (i < (4 * (nr + 2))) {
+		temp = w_ring[w_last_ix];
+		if (!(i % nk)) {
+			/* RotWord(temp) */
+			temp = (temp << 8) | (temp >> 24);
+			temp = aes_ks_subword(temp);
+			temp ^= round_constant[i/nk - 1];
+		} else if ((nk > 6) && ((i % nk) == 4)) {
+			temp = aes_ks_subword(temp);
+		}
+		w_last_ix = (w_last_ix + 1) % nk; /* This is the same as (i-Nk) mod Nk */
+		temp ^= w_ring[w_last_ix];
+		w_ring[w_last_ix] = temp;
+
+		/* We need the round keys for round Nr+1 and Nr+2 (round key
+		 * Nr+2 is the round key beyond the last one used when
+		 * encrypting).  Rounds are numbered starting from 0, Nr=10
+		 * implies 11 rounds are used in encryption/decryption.
+		 */
+		if (i >= (4 * nr)) {
+			/* Need to do host byte order correction here, the key
+			 * is byte oriented. */
+			*(u32*)dec_key = cpu_to_be32(temp);
+			dec_key += 4;
+		}
+		++i;
+	}
+}
+
+
+/**** Job/operation management. ****/
+
+int cryptocop_job_queue_insert_csum(struct cryptocop_operation *operation)
+{
+	return cryptocop_job_queue_insert(cryptocop_prio_kernel_csum, operation);
+}
+
+int cryptocop_job_queue_insert_crypto(struct cryptocop_operation *operation)
+{
+	return cryptocop_job_queue_insert(cryptocop_prio_kernel, operation);
+}
+
+int cryptocop_job_queue_insert_user_job(struct cryptocop_operation *operation)
+{
+	return cryptocop_job_queue_insert(cryptocop_prio_user, operation);
+}
+
+static int cryptocop_job_queue_insert(cryptocop_queue_priority prio, struct cryptocop_operation *operation)
+{
+	int                           ret;
+	struct cryptocop_prio_job     *pj = NULL;
+	unsigned long int             flags;
+
+	DEBUG(printk("cryptocop_job_queue_insert(%d, 0x%p)\n", prio, operation));
+
+	if (!operation || !operation->cb){
+		DEBUG_API(printk("cryptocop_job_queue_insert oper=0x%p, NULL operation or callback\n", operation));
+		return -EINVAL;
+	}
+
+	if ((ret = cryptocop_job_setup(&pj, operation)) != 0){
+		DEBUG_API(printk("cryptocop_job_queue_insert: job setup failed\n"));
+		return ret;
+	}
+	assert(pj != NULL);
+
+	spin_lock_irqsave(&cryptocop_job_queue_lock, flags);
+	list_add_tail(&pj->node, &cryptocop_job_queues[prio].jobs);
+	spin_unlock_irqrestore(&cryptocop_job_queue_lock, flags);
+
+	/* Make sure a job is running */
+	cryptocop_start_job();
+	return 0;
+}
+
+static void cryptocop_do_tasklet(unsigned long unused);
+DECLARE_TASKLET (cryptocop_tasklet, cryptocop_do_tasklet, 0);
+
+static void cryptocop_do_tasklet(unsigned long unused)
+{
+	struct list_head             *node;
+	struct cryptocop_prio_job    *pj = NULL;
+	unsigned long                flags;
+
+	DEBUG(printk("cryptocop_do_tasklet: entering\n"));
+
+	do {
+		spin_lock_irqsave(&cryptocop_completed_jobs_lock, flags);
+		if (!list_empty(&cryptocop_completed_jobs)){
+			node = cryptocop_completed_jobs.next;
+			list_del(node);
+			pj = list_entry(node, struct cryptocop_prio_job, node);
+		} else {
+			pj = NULL;
+		}
+		spin_unlock_irqrestore(&cryptocop_completed_jobs_lock, flags);
+		if (pj) {
+			assert(pj->oper != NULL);
+
+			/* Notify consumer of operation completeness. */
+			DEBUG(printk("cryptocop_do_tasklet: callback 0x%p, data 0x%p\n", pj->oper->cb, pj->oper->cb_data));
+
+			pj->oper->operation_status = 0; /* Job is completed. */
+			pj->oper->cb(pj->oper, pj->oper->cb_data);
+			delete_internal_operation(pj->iop);
+			kfree(pj);
+		}
+	} while (pj != NULL);
+
+	DEBUG(printk("cryptocop_do_tasklet: exiting\n"));
+}
+
+static irqreturn_t
+dma_done_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+{
+	struct cryptocop_prio_job *done_job;
+	reg_dma_rw_ack_intr ack_intr = {
+		.data = 1,
+	};
+
+	REG_WR (dma, regi_dma9, rw_ack_intr, ack_intr);
+
+	DEBUG(printk("cryptocop DMA done\n"));
+
+	spin_lock(&running_job_lock);
+	if (cryptocop_running_job == NULL){
+		printk("stream co-processor got interrupt when not busy\n");
+		spin_unlock(&running_job_lock);
+		return IRQ_HANDLED;
+	}
+	done_job = cryptocop_running_job;
+	cryptocop_running_job = NULL;
+	spin_unlock(&running_job_lock);
+
+	/* Start processing a job. */
+	if (!spin_trylock(&cryptocop_process_lock)){
+		DEBUG(printk("cryptocop irq handler, not starting a job\n"));
+	} else {
+		cryptocop_start_job();
+		spin_unlock(&cryptocop_process_lock);
+	}
+
+	done_job->oper->operation_status = 0; /* Job is completed. */
+	if (done_job->oper->fast_callback){
+		/* This operation wants callback from interrupt. */
+		done_job->oper->cb(done_job->oper, done_job->oper->cb_data);
+		delete_internal_operation(done_job->iop);
+		kfree(done_job);
+	} else {
+		spin_lock(&cryptocop_completed_jobs_lock);
+		list_add_tail(&(done_job->node), &cryptocop_completed_jobs);
+		spin_unlock(&cryptocop_completed_jobs_lock);
+		tasklet_schedule(&cryptocop_tasklet);
+	}
+
+	DEBUG(printk("cryptocop leave irq handler\n"));
+	return IRQ_HANDLED;
+}
+
+
+/* Setup interrupts and DMA channels. */
+static int init_cryptocop(void)
+{
+	unsigned long          flags;
+	reg_intr_vect_rw_mask  intr_mask;
+	reg_dma_rw_cfg         dma_cfg = {.en = 1};
+	reg_dma_rw_intr_mask   intr_mask_in = {.data = regk_dma_yes}; /* Only want descriptor interrupts from the DMA in channel. */
+	reg_dma_rw_ack_intr    ack_intr = {.data = 1,.in_eop = 1 };
+	reg_strcop_rw_cfg      strcop_cfg = {
+		.ipend = regk_strcop_little,
+		.td1 = regk_strcop_e,
+		.td2 = regk_strcop_d,
+		.td3 = regk_strcop_e,
+		.ignore_sync = 0,
+		.en = 1
+	};
+
+	if (request_irq(DMA9_INTR_VECT, dma_done_interrupt, 0, "stream co-processor DMA", NULL)) panic("request_irq stream co-processor irq dma9");
+
+	(void)crisv32_request_dma(8, "strcop", DMA_PANIC_ON_ERROR, 0, dma_strp);
+	(void)crisv32_request_dma(9, "strcop", DMA_PANIC_ON_ERROR, 0, dma_strp);
+
+	local_irq_save(flags);
+
+	/* Reset and enable the cryptocop. */
+	strcop_cfg.en = 0;
+	REG_WR(strcop, regi_strcop, rw_cfg, strcop_cfg);
+	strcop_cfg.en = 1;
+	REG_WR(strcop, regi_strcop, rw_cfg, strcop_cfg);
+
+	/* Enable DMA9 interrupt */
+	intr_mask = REG_RD(intr_vect, regi_irq, rw_mask);
+	intr_mask.dma9 = 1;
+	REG_WR(intr_vect, regi_irq, rw_mask, intr_mask);
+
+	/* Enable DMAs. */
+	REG_WR(dma, regi_dma9, rw_cfg, dma_cfg); /* input DMA */
+	REG_WR(dma, regi_dma8, rw_cfg, dma_cfg); /* output DMA */
+
+	/* Set up wordsize = 4 for DMAs. */
+	DMA_WR_CMD (regi_dma8, regk_dma_set_w_size4);
+	DMA_WR_CMD (regi_dma9, regk_dma_set_w_size4);
+
+	/* Enable interrupts. */
+	REG_WR(dma, regi_dma9, rw_intr_mask, intr_mask_in);
+
+	/* Clear intr ack. */
+	REG_WR(dma, regi_dma9, rw_ack_intr, ack_intr);
+
+	local_irq_restore(flags);
+
+	return 0;
+}
+
+/* Free used cryptocop hw resources (interrupt and DMA channels). */
+static void release_cryptocop(void)
+{
+	unsigned long          flags;
+	reg_intr_vect_rw_mask  intr_mask;
+	reg_dma_rw_cfg         dma_cfg = {.en = 0};
+	reg_dma_rw_intr_mask   intr_mask_in = {0};
+	reg_dma_rw_ack_intr    ack_intr = {.data = 1,.in_eop = 1 };
+
+	local_irq_save(flags);
+
+	/* Clear intr ack. */
+	REG_WR(dma, regi_dma9, rw_ack_intr, ack_intr);
+
+	/* Disable DMA9 interrupt */
+	intr_mask = REG_RD(intr_vect, regi_irq, rw_mask);
+	intr_mask.dma9 = 0;
+	REG_WR(intr_vect, regi_irq, rw_mask, intr_mask);
+
+	/* Disable DMAs. */
+	REG_WR(dma, regi_dma9, rw_cfg, dma_cfg); /* input DMA */
+	REG_WR(dma, regi_dma8, rw_cfg, dma_cfg); /* output DMA */
+
+	/* Disable interrupts. */
+	REG_WR(dma, regi_dma9, rw_intr_mask, intr_mask_in);
+
+	local_irq_restore(flags);
+
+	free_irq(DMA9_INTR_VECT, NULL);
+
+	(void)crisv32_free_dma(8);
+	(void)crisv32_free_dma(9);
+}
+
+
+/* Init job queue. */
+static int cryptocop_job_queue_init(void)
+{
+	int i;
+
+	INIT_LIST_HEAD(&cryptocop_completed_jobs);
+
+	for (i = 0; i < cryptocop_prio_no_prios; i++){
+		cryptocop_job_queues[i].prio = (cryptocop_queue_priority)i;
+		INIT_LIST_HEAD(&cryptocop_job_queues[i].jobs);
+	}
+	return 0;
+}
+
+
+static void cryptocop_job_queue_close(void)
+{
+	struct list_head               *node, *tmp;
+	struct cryptocop_prio_job      *pj = NULL;
+	unsigned long int              process_flags, flags;
+	int                            i;
+
+	/* FIXME: This is as yet untested code. */
+
+	/* Stop strcop from getting an operation to process while we are closing the
+	   module. */
+	spin_lock_irqsave(&cryptocop_process_lock, process_flags);
+
+	/* Empty the job queue. */
+	spin_lock_irqsave(&cryptocop_process_lock, process_flags);
+	for (i = 0; i < cryptocop_prio_no_prios; i++){
+		if (!list_empty(&(cryptocop_job_queues[i].jobs))){
+			list_for_each_safe(node, tmp, &(cryptocop_job_queues[i].jobs)) {
+				pj = list_entry(node, struct cryptocop_prio_job, node);
+				list_del(node);
+
+				/* Call callback to notify consumer of job removal. */
+				DEBUG(printk("cryptocop_job_queue_close: callback 0x%p, data 0x%p\n", pj->oper->cb, pj->oper->cb_data));
+				pj->oper->operation_status = -EINTR; /* Job is terminated without completion. */
+				pj->oper->cb(pj->oper, pj->oper->cb_data);
+
+				delete_internal_operation(pj->iop);
+				kfree(pj);
+			}
+		}
+	}
+	spin_unlock_irqrestore(&cryptocop_process_lock, process_flags);
+
+	/* Remove the running job, if any. */
+	spin_lock_irqsave(&running_job_lock, flags);
+	if (cryptocop_running_job){
+		reg_strcop_rw_cfg rw_cfg;
+		reg_dma_rw_cfg    dma_out_cfg, dma_in_cfg;
+
+		/* Stop DMA. */
+		dma_out_cfg = REG_RD(dma, regi_dma8, rw_cfg);
+		dma_out_cfg.en = regk_dma_no;
+		REG_WR(dma, regi_dma8, rw_cfg, dma_out_cfg);
+
+		dma_in_cfg = REG_RD(dma, regi_dma9, rw_cfg);
+		dma_in_cfg.en = regk_dma_no;
+		REG_WR(dma, regi_dma9, rw_cfg, dma_in_cfg);
+
+		/* Disble the cryptocop. */
+		rw_cfg = REG_RD(strcop, regi_strcop, rw_cfg);
+		rw_cfg.en = 0;
+		REG_WR(strcop, regi_strcop, rw_cfg, rw_cfg);
+
+		pj = cryptocop_running_job;
+		cryptocop_running_job = NULL;
+
+		/* Call callback to notify consumer of job removal. */
+		DEBUG(printk("cryptocop_job_queue_close: callback 0x%p, data 0x%p\n", pj->oper->cb, pj->oper->cb_data));
+		pj->oper->operation_status = -EINTR; /* Job is terminated without completion. */
+		pj->oper->cb(pj->oper, pj->oper->cb_data);
+
+		delete_internal_operation(pj->iop);
+		kfree(pj);
+	}
+	spin_unlock_irqrestore(&running_job_lock, flags);
+
+	/* Remove completed jobs, if any. */
+	spin_lock_irqsave(&cryptocop_completed_jobs_lock, flags);
+
+	list_for_each_safe(node, tmp, &cryptocop_completed_jobs) {
+		pj = list_entry(node, struct cryptocop_prio_job, node);
+		list_del(node);
+		/* Call callback to notify consumer of job removal. */
+		DEBUG(printk("cryptocop_job_queue_close: callback 0x%p, data 0x%p\n", pj->oper->cb, pj->oper->cb_data));
+		pj->oper->operation_status = -EINTR; /* Job is terminated without completion. */
+		pj->oper->cb(pj->oper, pj->oper->cb_data);
+
+		delete_internal_operation(pj->iop);
+		kfree(pj);
+	}
+	spin_unlock_irqrestore(&cryptocop_completed_jobs_lock, flags);
+}
+
+
+static void cryptocop_start_job(void)
+{
+	int                          i;
+	struct cryptocop_prio_job    *pj;
+	unsigned long int            flags;
+	unsigned long int            running_job_flags;
+	reg_strcop_rw_cfg            rw_cfg = {.en = 1, .ignore_sync = 0};
+
+	DEBUG(printk("cryptocop_start_job: entering\n"));
+
+	spin_lock_irqsave(&running_job_lock, running_job_flags);
+	if (cryptocop_running_job != NULL){
+		/* Already running. */
+		DEBUG(printk("cryptocop_start_job: already running, exit\n"));
+		spin_unlock_irqrestore(&running_job_lock, running_job_flags);
+		return;
+	}
+	spin_lock_irqsave(&cryptocop_job_queue_lock, flags);
+
+	/* Check the queues in priority order. */
+	for (i = cryptocop_prio_kernel_csum; (i < cryptocop_prio_no_prios) && list_empty(&cryptocop_job_queues[i].jobs); i++);
+	if (i == cryptocop_prio_no_prios) {
+		spin_unlock_irqrestore(&cryptocop_job_queue_lock, flags);
+		spin_unlock_irqrestore(&running_job_lock, running_job_flags);
+		DEBUG(printk("cryptocop_start_job: no jobs to run\n"));
+		return; /* No jobs to run */
+	}
+	DEBUG(printk("starting job for prio %d\n", i));
+
+	/* TODO: Do not starve lower priority jobs.  Let in a lower
+	 * prio job for every N-th processed higher prio job or some
+	 * other scheduling policy.  This could reasonably be
+	 * tweakable since the optimal balance would depend on the
+	 * type of load on the system. */
+
+	/* Pull the DMA lists from the job and start the DMA client. */
+	pj = list_entry(cryptocop_job_queues[i].jobs.next, struct cryptocop_prio_job, node);
+	list_del(&pj->node);
+	spin_unlock_irqrestore(&cryptocop_job_queue_lock, flags);
+	cryptocop_running_job = pj;
+
+	/* Set config register (3DES and CSUM modes). */
+	switch (pj->iop->tdes_mode){
+	case cryptocop_3des_eee:
+		rw_cfg.td1 = regk_strcop_e;
+		rw_cfg.td2 = regk_strcop_e;
+		rw_cfg.td3 = regk_strcop_e;
+		break;
+	case cryptocop_3des_eed:
+		rw_cfg.td1 = regk_strcop_e;
+		rw_cfg.td2 = regk_strcop_e;
+		rw_cfg.td3 = regk_strcop_d;
+		break;
+	case cryptocop_3des_ede:
+		rw_cfg.td1 = regk_strcop_e;
+		rw_cfg.td2 = regk_strcop_d;
+		rw_cfg.td3 = regk_strcop_e;
+		break;
+	case cryptocop_3des_edd:
+		rw_cfg.td1 = regk_strcop_e;
+		rw_cfg.td2 = regk_strcop_d;
+		rw_cfg.td3 = regk_strcop_d;
+		break;
+	case cryptocop_3des_dee:
+		rw_cfg.td1 = regk_strcop_d;
+		rw_cfg.td2 = regk_strcop_e;
+		rw_cfg.td3 = regk_strcop_e;
+		break;
+	case cryptocop_3des_ded:
+		rw_cfg.td1 = regk_strcop_d;
+		rw_cfg.td2 = regk_strcop_e;
+		rw_cfg.td3 = regk_strcop_d;
+		break;
+	case cryptocop_3des_dde:
+		rw_cfg.td1 = regk_strcop_d;
+		rw_cfg.td2 = regk_strcop_d;
+		rw_cfg.td3 = regk_strcop_e;
+		break;
+	case cryptocop_3des_ddd:
+		rw_cfg.td1 = regk_strcop_d;
+		rw_cfg.td2 = regk_strcop_d;
+		rw_cfg.td3 = regk_strcop_d;
+		break;
+	default:
+		DEBUG(printk("cryptocop_setup_dma_list: bad 3DES mode\n"));
+	}
+	switch (pj->iop->csum_mode){
+	case cryptocop_csum_le:
+		rw_cfg.ipend = regk_strcop_little;
+		break;
+	case cryptocop_csum_be:
+		rw_cfg.ipend = regk_strcop_big;
+		break;
+	default:
+		DEBUG(printk("cryptocop_setup_dma_list: bad checksum mode\n"));
+	}
+	REG_WR(strcop, regi_strcop, rw_cfg, rw_cfg);
+
+	DEBUG(printk("cryptocop_start_job: starting DMA, new cryptocop_running_job=0x%p\n"
+		     "ctx_in: 0x%p, phys: 0x%p\n"
+		     "ctx_out: 0x%p, phys: 0x%p\n",
+		     pj,
+		     &pj->iop->ctx_in, (char*)virt_to_phys(&pj->iop->ctx_in),
+		     &pj->iop->ctx_out, (char*)virt_to_phys(&pj->iop->ctx_out)));
+
+	/* Start input DMA. */
+	DMA_START_CONTEXT(regi_dma9, virt_to_phys(&pj->iop->ctx_in));
+
+	/* Start output DMA. */
+	DMA_START_CONTEXT(regi_dma8, virt_to_phys(&pj->iop->ctx_out));
+
+	spin_unlock_irqrestore(&running_job_lock, running_job_flags);
+	DEBUG(printk("cryptocop_start_job: exiting\n"));
+}
+
+
+static int cryptocop_job_setup(struct cryptocop_prio_job **pj, struct cryptocop_operation *operation)
+{
+	int  err;
+	int  alloc_flag = operation->in_interrupt ? GFP_ATOMIC : GFP_KERNEL;
+	void *iop_alloc_ptr = NULL;
+
+	*pj = kmalloc(sizeof (struct cryptocop_prio_job), alloc_flag);
+	if (!*pj) return -ENOMEM;
+
+	DEBUG(printk("cryptocop_job_setup: operation=0x%p\n", operation));
+
+	(*pj)->oper = operation;
+	DEBUG(printk("cryptocop_job_setup, cb=0x%p cb_data=0x%p\n",  (*pj)->oper->cb, (*pj)->oper->cb_data));
+
+	if (operation->use_dmalists) {
+		DEBUG(print_user_dma_lists(&operation->list_op));
+		if (!operation->list_op.inlist || !operation->list_op.outlist || !operation->list_op.out_data_buf || !operation->list_op.in_data_buf){
+			DEBUG_API(printk("cryptocop_job_setup: bad indata (use_dmalists)\n"));
+			kfree(*pj);
+			return -EINVAL;
+		}
+		iop_alloc_ptr = kmalloc(DESCR_ALLOC_PAD + sizeof(struct cryptocop_int_operation), alloc_flag);
+		if (!iop_alloc_ptr) {
+			DEBUG_API(printk("cryptocop_job_setup: kmalloc cryptocop_int_operation\n"));
+			kfree(*pj);
+			return -ENOMEM;
+		}
+		(*pj)->iop = (struct cryptocop_int_operation*)(((unsigned long int)(iop_alloc_ptr + DESCR_ALLOC_PAD + offsetof(struct cryptocop_int_operation, ctx_out)) & ~0x0000001F) - offsetof(struct cryptocop_int_operation, ctx_out));
+		DEBUG(memset((*pj)->iop, 0xff, sizeof(struct cryptocop_int_operation)));
+		(*pj)->iop->alloc_ptr = iop_alloc_ptr;
+		(*pj)->iop->sid = operation->sid;
+		(*pj)->iop->cdesc_out = NULL;
+		(*pj)->iop->cdesc_in = NULL;
+		(*pj)->iop->tdes_mode = operation->list_op.tdes_mode;
+		(*pj)->iop->csum_mode = operation->list_op.csum_mode;
+		(*pj)->iop->ddesc_out = operation->list_op.outlist;
+		(*pj)->iop->ddesc_in = operation->list_op.inlist;
+
+		/* Setup DMA contexts. */
+		(*pj)->iop->ctx_out.next = NULL;
+		(*pj)->iop->ctx_out.eol = 1;
+		(*pj)->iop->ctx_out.saved_data = operation->list_op.outlist;
+		(*pj)->iop->ctx_out.saved_data_buf = operation->list_op.out_data_buf;
+
+		(*pj)->iop->ctx_in.next = NULL;
+		(*pj)->iop->ctx_in.eol = 1;
+		(*pj)->iop->ctx_in.saved_data = operation->list_op.inlist;
+		(*pj)->iop->ctx_in.saved_data_buf = operation->list_op.in_data_buf;
+	} else {
+		if ((err = cryptocop_setup_dma_list(operation, &(*pj)->iop, alloc_flag))) {
+			DEBUG_API(printk("cryptocop_job_setup: cryptocop_setup_dma_list failed %d\n", err));
+			kfree(*pj);
+			return err;
+		}
+	}
+	DEBUG(print_dma_descriptors((*pj)->iop));
+
+	DEBUG(printk("cryptocop_job_setup, DMA list setup successful\n"));
+
+	return 0;
+}
+
+
+static int cryptocop_open(struct inode *inode, struct file *filp)
+{
+	int p = MINOR(inode->i_rdev);
+
+	if (p != CRYPTOCOP_MINOR) return -EINVAL;
+
+	filp->private_data = NULL;
+	return 0;
+}
+
+
+static int cryptocop_release(struct inode *inode, struct file *filp)
+{
+	struct cryptocop_private *dev = filp->private_data;
+	struct cryptocop_private *dev_next;
+
+	while (dev){
+		dev_next = dev->next;
+		if (dev->sid != CRYPTOCOP_SESSION_ID_NONE) {
+			(void)cryptocop_free_session(dev->sid);
+		}
+		kfree(dev);
+		dev = dev_next;
+	}
+
+	return 0;
+}
+
+
+static int cryptocop_ioctl_close_session(struct inode *inode, struct file *filp,
+					 unsigned int cmd, unsigned long arg)
+{
+	struct cryptocop_private  *dev = filp->private_data;
+	struct cryptocop_private  *prev_dev = NULL;
+	struct strcop_session_op  *sess_op = (struct strcop_session_op *)arg;
+	struct strcop_session_op  sop;
+	int                       err;
+
+	DEBUG(printk("cryptocop_ioctl_close_session\n"));
+
+	if (!access_ok(VERIFY_READ, sess_op, sizeof(struct strcop_session_op)))
+		return -EFAULT;
+	err = copy_from_user(&sop, sess_op, sizeof(struct strcop_session_op));
+	if (err) return -EFAULT;
+
+	while (dev && (dev->sid != sop.ses_id)) {
+		prev_dev = dev;
+		dev = dev->next;
+	}
+	if (dev){
+		if (prev_dev){
+			prev_dev->next = dev->next;
+		} else {
+			filp->private_data = dev->next;
+		}
+		err = cryptocop_free_session(dev->sid);
+		if (err) return -EFAULT;
+	} else {
+		DEBUG_API(printk("cryptocop_ioctl_close_session: session %lld not found\n", sop.ses_id));
+		return -EINVAL;
+	}
+	return 0;
+}
+
+
+static void ioctl_process_job_callback(struct cryptocop_operation *op, void*cb_data)
+{
+	struct ioctl_job_cb_ctx *jc = (struct ioctl_job_cb_ctx *)cb_data;
+
+	DEBUG(printk("ioctl_process_job_callback: op=0x%p, cb_data=0x%p\n", op, cb_data));
+
+	jc->processed = 1;
+	wake_up(&cryptocop_ioc_process_wq);
+}
+
+
+#define CRYPTOCOP_IOCTL_CIPHER_TID  (1)
+#define CRYPTOCOP_IOCTL_DIGEST_TID  (2)
+#define CRYPTOCOP_IOCTL_CSUM_TID    (3)
+
+static size_t first_cfg_change_ix(struct strcop_crypto_op *crp_op)
+{
+	size_t ch_ix = 0;
+
+	if (crp_op->do_cipher) ch_ix = crp_op->cipher_start;
+	if (crp_op->do_digest && (crp_op->digest_start < ch_ix)) ch_ix = crp_op->digest_start;
+	if (crp_op->do_csum && (crp_op->csum_start < ch_ix)) ch_ix = crp_op->csum_start;
+
+	DEBUG(printk("first_cfg_change_ix: ix=%d\n", ch_ix));
+	return ch_ix;
+}
+
+
+static size_t next_cfg_change_ix(struct strcop_crypto_op *crp_op, size_t ix)
+{
+	size_t ch_ix = INT_MAX;
+	size_t tmp_ix = 0;
+
+	if (crp_op->do_cipher && ((crp_op->cipher_start + crp_op->cipher_len) > ix)){
+		if (crp_op->cipher_start > ix) {
+			ch_ix = crp_op->cipher_start;
+		} else {
+			ch_ix = crp_op->cipher_start + crp_op->cipher_len;
+		}
+	}
+	if (crp_op->do_digest && ((crp_op->digest_start + crp_op->digest_len) > ix)){
+		if (crp_op->digest_start > ix) {
+			tmp_ix = crp_op->digest_start;
+		} else {
+			tmp_ix = crp_op->digest_start + crp_op->digest_len;
+		}
+		if (tmp_ix < ch_ix) ch_ix = tmp_ix;
+	}
+	if (crp_op->do_csum && ((crp_op->csum_start + crp_op->csum_len) > ix)){
+		if (crp_op->csum_start > ix) {
+			tmp_ix = crp_op->csum_start;
+		} else {
+			tmp_ix = crp_op->csum_start + crp_op->csum_len;
+		}
+		if (tmp_ix < ch_ix) ch_ix = tmp_ix;
+	}
+	if (ch_ix == INT_MAX) ch_ix = ix;
+	DEBUG(printk("next_cfg_change_ix prev ix=%d, next ix=%d\n", ix, ch_ix));
+	return ch_ix;
+}
+
+
+/* Map map_length bytes from the pages starting on *pageix and *pageoffset to iovecs starting on *iovix.
+ * Return -1 for ok, 0 for fail. */
+static int map_pages_to_iovec(struct iovec *iov, int iovlen, int *iovix, struct page **pages, int nopages, int *pageix, int *pageoffset, int map_length )
+{
+	int tmplen;
+
+	assert(iov != NULL);
+	assert(iovix != NULL);
+	assert(pages != NULL);
+	assert(pageix != NULL);
+	assert(pageoffset != NULL);
+
+	DEBUG(printk("map_pages_to_iovec, map_length=%d, iovlen=%d, *iovix=%d, nopages=%d, *pageix=%d, *pageoffset=%d\n", map_length, iovlen, *iovix, nopages, *pageix, *pageoffset));
+
+	while (map_length > 0){
+		DEBUG(printk("map_pages_to_iovec, map_length=%d, iovlen=%d, *iovix=%d, nopages=%d, *pageix=%d, *pageoffset=%d\n", map_length, iovlen, *iovix, nopages, *pageix, *pageoffset));
+		if (*iovix >= iovlen){
+			DEBUG_API(printk("map_page_to_iovec: *iovix=%d >= iovlen=%d\n", *iovix, iovlen));
+			return 0;
+		}
+		if (*pageix >= nopages){
+			DEBUG_API(printk("map_page_to_iovec: *pageix=%d >= nopages=%d\n", *pageix, nopages));
+			return 0;
+		}
+		iov[*iovix].iov_base = (unsigned char*)page_address(pages[*pageix]) + *pageoffset;
+		tmplen = PAGE_SIZE - *pageoffset;
+		if (tmplen < map_length){
+			(*pageoffset) = 0;
+			(*pageix)++;
+		} else {
+			tmplen = map_length;
+			(*pageoffset) += map_length;
+		}
+		DEBUG(printk("mapping %d bytes from page %d (or %d) to iovec %d\n", tmplen, *pageix, *pageix-1, *iovix));
+		iov[*iovix].iov_len = tmplen;
+		map_length -= tmplen;
+		(*iovix)++;
+	}
+	DEBUG(printk("map_page_to_iovec, exit, *iovix=%d\n", *iovix));
+	return -1;
+}
+
+
+
+static int cryptocop_ioctl_process(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
+{
+	int                             i;
+	struct cryptocop_private        *dev = filp->private_data;
+	struct strcop_crypto_op         *crp_oper = (struct strcop_crypto_op *)arg;
+	struct strcop_crypto_op         oper = {0};
+	int                             err = 0;
+	struct cryptocop_operation      *cop = NULL;
+
+	struct ioctl_job_cb_ctx         *jc = NULL;
+
+	struct page                     **inpages = NULL;
+	struct page                     **outpages = NULL;
+	int                             noinpages = 0;
+	int                             nooutpages = 0;
+
+	struct cryptocop_desc           descs[5]; /* Max 5 descriptors are needed, there are three transforms that
+						   * can get connected/disconnected on different places in the indata. */
+	struct cryptocop_desc_cfg       dcfgs[5*3];
+	int                             desc_ix = 0;
+	int                             dcfg_ix = 0;
+	struct cryptocop_tfrm_cfg       ciph_tcfg = {0};
+	struct cryptocop_tfrm_cfg       digest_tcfg = {0};
+	struct cryptocop_tfrm_cfg       csum_tcfg = {0};
+
+	unsigned char                   *digest_result = NULL;
+	int                             digest_length = 0;
+	int                             cblocklen = 0;
+	unsigned char                   csum_result[CSUM_BLOCK_LENGTH];
+	struct cryptocop_session        *sess;
+
+	int    iovlen = 0;
+	int    iovix = 0;
+	int    pageix = 0;
+	int    pageoffset = 0;
+
+	size_t prev_ix = 0;
+	size_t next_ix;
+
+	int    cipher_active, digest_active, csum_active;
+	int    end_digest, end_csum;
+	int    digest_done = 0;
+	int    cipher_done = 0;
+	int    csum_done = 0;
+
+	DEBUG(printk("cryptocop_ioctl_process\n"));
+
+	if (!access_ok(VERIFY_WRITE, crp_oper, sizeof(struct strcop_crypto_op))){
+		DEBUG_API(printk("cryptocop_ioctl_process: !access_ok crp_oper!\n"));
+		return -EFAULT;
+	}
+	if (copy_from_user(&oper, crp_oper, sizeof(struct strcop_crypto_op))) {
+		DEBUG_API(printk("cryptocop_ioctl_process: copy_from_user\n"));
+		return -EFAULT;
+	}
+	DEBUG(print_strcop_crypto_op(&oper));
+
+	while (dev && dev->sid != oper.ses_id) dev = dev->next;
+	if (!dev){
+		DEBUG_API(printk("cryptocop_ioctl_process: session %lld not found\n", oper.ses_id));
+		return -EINVAL;
+	}
+
+	/* Check buffers. */
+	if (((oper.indata + oper.inlen) < oper.indata) || ((oper.cipher_outdata + oper.cipher_outlen) < oper.cipher_outdata)){
+		DEBUG_API(printk("cryptocop_ioctl_process: user buffers wrapped around, bad user!\n"));
+		return -EINVAL;
+	}
+
+	if (!access_ok(VERIFY_WRITE, oper.cipher_outdata, oper.cipher_outlen)){
+		DEBUG_API(printk("cryptocop_ioctl_process: !access_ok out data!\n"));
+		return -EFAULT;
+	}
+	if (!access_ok(VERIFY_READ, oper.indata, oper.inlen)){
+		DEBUG_API(printk("cryptocop_ioctl_process: !access_ok in data!\n"));
+		return -EFAULT;
+	}
+
+	cop = kmalloc(sizeof(struct cryptocop_operation), GFP_KERNEL);
+	if (!cop) {
+		DEBUG_API(printk("cryptocop_ioctl_process: kmalloc\n"));
+		return -ENOMEM;
+	}
+	jc = kmalloc(sizeof(struct ioctl_job_cb_ctx), GFP_KERNEL);
+	if (!jc) {
+		DEBUG_API(printk("cryptocop_ioctl_process: kmalloc\n"));
+		err = -ENOMEM;
+		goto error_cleanup;
+	}
+	jc->processed = 0;
+
+	cop->cb_data = jc;
+	cop->cb = ioctl_process_job_callback;
+	cop->operation_status = 0;
+	cop->use_dmalists = 0;
+	cop->in_interrupt = 0;
+	cop->fast_callback = 0;
+	cop->tfrm_op.tfrm_cfg = NULL;
+	cop->tfrm_op.desc = NULL;
+	cop->tfrm_op.indata = NULL;
+	cop->tfrm_op.incount = 0;
+	cop->tfrm_op.inlen = 0;
+	cop->tfrm_op.outdata = NULL;
+	cop->tfrm_op.outcount = 0;
+	cop->tfrm_op.outlen = 0;
+
+	sess = get_session(oper.ses_id);
+	if (!sess){
+		DEBUG_API(printk("cryptocop_ioctl_process: bad session id.\n"));
+		kfree(cop);
+		kfree(jc);
+		return -EINVAL;
+	}
+
+	if (oper.do_cipher) {
+		unsigned int                    cipher_outlen = 0;
+		struct cryptocop_transform_ctx  *tc = get_transform_ctx(sess, CRYPTOCOP_IOCTL_CIPHER_TID);
+		if (!tc) {
+			DEBUG_API(printk("cryptocop_ioctl_process: no cipher transform in session.\n"));
+			err = -EINVAL;
+			goto error_cleanup;
+		}
+		ciph_tcfg.tid = CRYPTOCOP_IOCTL_CIPHER_TID;
+		ciph_tcfg.inject_ix = 0;
+		ciph_tcfg.flags = 0;
+		if ((oper.cipher_start < 0) || (oper.cipher_len <= 0) || (oper.cipher_start > oper.inlen) || ((oper.cipher_start + oper.cipher_len) > oper.inlen)){
+			DEBUG_API(printk("cryptocop_ioctl_process: bad cipher length\n"));
+			kfree(cop);
+			kfree(jc);
+			return -EINVAL;
+		}
+		cblocklen = tc->init.alg == cryptocop_alg_aes ? AES_BLOCK_LENGTH : DES_BLOCK_LENGTH;
+		if (oper.cipher_len % cblocklen) {
+			kfree(cop);
+			kfree(jc);
+			DEBUG_API(printk("cryptocop_ioctl_process: cipher inlength not multiple of block length.\n"));
+			return -EINVAL;
+		}
+		cipher_outlen = oper.cipher_len;
+		if (tc->init.cipher_mode == cryptocop_cipher_mode_cbc){
+			if (oper.cipher_explicit) {
+				ciph_tcfg.flags |= CRYPTOCOP_EXPLICIT_IV;
+				memcpy(ciph_tcfg.iv, oper.cipher_iv, cblocklen);
+			} else {
+				cipher_outlen = oper.cipher_len - cblocklen;
+			}
+		} else {
+			if (oper.cipher_explicit){
+				kfree(cop);
+				kfree(jc);
+				DEBUG_API(printk("cryptocop_ioctl_process: explicit_iv when not CBC mode\n"));
+				return -EINVAL;
+			}
+		}
+		if (oper.cipher_outlen != cipher_outlen) {
+			kfree(cop);
+			kfree(jc);
+			DEBUG_API(printk("cryptocop_ioctl_process: cipher_outlen incorrect, should be %d not %d.\n", cipher_outlen, oper.cipher_outlen));
+			return -EINVAL;
+		}
+
+		if (oper.decrypt){
+			ciph_tcfg.flags |= CRYPTOCOP_DECRYPT;
+		} else {
+			ciph_tcfg.flags |= CRYPTOCOP_ENCRYPT;
+		}
+		ciph_tcfg.next = cop->tfrm_op.tfrm_cfg;
+		cop->tfrm_op.tfrm_cfg = &ciph_tcfg;
+	}
+	if (oper.do_digest){
+		struct cryptocop_transform_ctx *tc = get_transform_ctx(sess, CRYPTOCOP_IOCTL_DIGEST_TID);
+		if (!tc) {
+			DEBUG_API(printk("cryptocop_ioctl_process: no digest transform in session.\n"));
+			err = -EINVAL;
+			goto error_cleanup;
+		}
+		digest_length = tc->init.alg == cryptocop_alg_md5 ? 16 : 20;
+		digest_result = kmalloc(digest_length, GFP_KERNEL);
+		if (!digest_result) {
+			DEBUG_API(printk("cryptocop_ioctl_process: kmalloc digest_result\n"));
+			err = -EINVAL;
+			goto error_cleanup;
+		}
+		DEBUG(memset(digest_result, 0xff, digest_length));
+
+		digest_tcfg.tid = CRYPTOCOP_IOCTL_DIGEST_TID;
+		digest_tcfg.inject_ix = 0;
+		ciph_tcfg.inject_ix += digest_length;
+		if ((oper.digest_start < 0) || (oper.digest_len <= 0) || (oper.digest_start > oper.inlen) || ((oper.digest_start + oper.digest_len) > oper.inlen)){
+			DEBUG_API(printk("cryptocop_ioctl_process: bad digest length\n"));
+			err = -EINVAL;
+			goto error_cleanup;
+		}
+
+		digest_tcfg.next = cop->tfrm_op.tfrm_cfg;
+		cop->tfrm_op.tfrm_cfg = &digest_tcfg;
+	}
+	if (oper.do_csum){
+		csum_tcfg.tid = CRYPTOCOP_IOCTL_CSUM_TID;
+		csum_tcfg.inject_ix = digest_length;
+		ciph_tcfg.inject_ix += 2;
+
+		if ((oper.csum_start < 0) || (oper.csum_len <= 0) || (oper.csum_start > oper.inlen) || ((oper.csum_start + oper.csum_len) > oper.inlen)){
+			DEBUG_API(printk("cryptocop_ioctl_process: bad csum length\n"));
+			kfree(cop);
+			kfree(jc);
+			return -EINVAL;
+		}
+
+		csum_tcfg.next = cop->tfrm_op.tfrm_cfg;
+		cop->tfrm_op.tfrm_cfg = &csum_tcfg;
+	}
+
+	prev_ix = first_cfg_change_ix(&oper);
+	if (prev_ix > oper.inlen) {
+		DEBUG_API(printk("cryptocop_ioctl_process: length mismatch\n"));
+		nooutpages = noinpages = 0;
+		err = -EINVAL;
+		goto error_cleanup;
+	}
+	DEBUG(printk("cryptocop_ioctl_process: inlen=%d, cipher_outlen=%d\n", oper.inlen, oper.cipher_outlen));
+
+	/* Map user pages for in and out data of the operation. */
+	noinpages = (((unsigned long int)(oper.indata + prev_ix) & ~PAGE_MASK) + oper.inlen - 1 - prev_ix + ~PAGE_MASK) >> PAGE_SHIFT;
+	DEBUG(printk("cryptocop_ioctl_process: noinpages=%d\n", noinpages));
+	inpages = kmalloc(noinpages * sizeof(struct page*), GFP_KERNEL);
+	if (!inpages){
+		DEBUG_API(printk("cryptocop_ioctl_process: kmalloc inpages\n"));
+		nooutpages = noinpages = 0;
+		err = -ENOMEM;
+		goto error_cleanup;
+	}
+	if (oper.do_cipher){
+		nooutpages = (((unsigned long int)oper.cipher_outdata & ~PAGE_MASK) + oper.cipher_outlen - 1 + ~PAGE_MASK) >> PAGE_SHIFT;
+		DEBUG(printk("cryptocop_ioctl_process: nooutpages=%d\n", nooutpages));
+		outpages = kmalloc(nooutpages * sizeof(struct page*), GFP_KERNEL);
+		if (!outpages){
+			DEBUG_API(printk("cryptocop_ioctl_process: kmalloc outpages\n"));
+			nooutpages = noinpages = 0;
+			err = -ENOMEM;
+			goto error_cleanup;
+		}
+	}
+
+	/* Acquire the mm page semaphore. */
+	down_read(&current->mm->mmap_sem);
+
+	err = get_user_pages(current,
+			     current->mm,
+			     (unsigned long int)(oper.indata + prev_ix),
+			     noinpages,
+			     0,  /* read access only for in data */
+			     0, /* no force */
+			     inpages,
+			     NULL);
+
+	if (err < 0) {
+		up_read(&current->mm->mmap_sem);
+		nooutpages = noinpages = 0;
+		DEBUG_API(printk("cryptocop_ioctl_process: get_user_pages indata\n"));
+		goto error_cleanup;
+	}
+	noinpages = err;
+	if (oper.do_cipher){
+		err = get_user_pages(current,
+				     current->mm,
+				     (unsigned long int)oper.cipher_outdata,
+				     nooutpages,
+				     1, /* write access for out data */
+				     0, /* no force */
+				     outpages,
+				     NULL);
+		up_read(&current->mm->mmap_sem);
+		if (err < 0) {
+			nooutpages = 0;
+			DEBUG_API(printk("cryptocop_ioctl_process: get_user_pages outdata\n"));
+			goto error_cleanup;
+		}
+		nooutpages = err;
+	} else {
+		up_read(&current->mm->mmap_sem);
+	}
+
+	/* Add 6 to nooutpages to make room for possibly inserted buffers for storing digest and
+	 * csum output and splits when units are (dis-)connected. */
+	cop->tfrm_op.indata = kmalloc((noinpages) * sizeof(struct iovec), GFP_KERNEL);
+	cop->tfrm_op.outdata = kmalloc((6 + nooutpages) * sizeof(struct iovec), GFP_KERNEL);
+	if (!cop->tfrm_op.indata || !cop->tfrm_op.outdata) {
+		DEBUG_API(printk("cryptocop_ioctl_process: kmalloc iovecs\n"));
+		err = -ENOMEM;
+		goto error_cleanup;
+	}
+
+	cop->tfrm_op.inlen = oper.inlen - prev_ix;
+	cop->tfrm_op.outlen = 0;
+	if (oper.do_cipher) cop->tfrm_op.outlen += oper.cipher_outlen;
+	if (oper.do_digest) cop->tfrm_op.outlen += digest_length;
+	if (oper.do_csum) cop->tfrm_op.outlen += 2;
+
+	/* Setup the in iovecs. */
+	cop->tfrm_op.incount = noinpages;
+	if (noinpages > 1){
+		size_t tmplen = cop->tfrm_op.inlen;
+
+		cop->tfrm_op.indata[0].iov_len = PAGE_SIZE - ((unsigned long int)(oper.indata + prev_ix) & ~PAGE_MASK);
+		cop->tfrm_op.indata[0].iov_base = (unsigned char*)page_address(inpages[0]) + ((unsigned long int)(oper.indata + prev_ix) & ~PAGE_MASK);
+		tmplen -= cop->tfrm_op.indata[0].iov_len;
+		for (i = 1; i<noinpages; i++){
+			cop->tfrm_op.indata[i].iov_len = tmplen < PAGE_SIZE ? tmplen : PAGE_SIZE;
+			cop->tfrm_op.indata[i].iov_base = (unsigned char*)page_address(inpages[i]);
+			tmplen -= PAGE_SIZE;
+		}
+	} else {
+		cop->tfrm_op.indata[0].iov_len = oper.inlen - prev_ix;
+		cop->tfrm_op.indata[0].iov_base = (unsigned char*)page_address(inpages[0]) + ((unsigned long int)(oper.indata + prev_ix) & ~PAGE_MASK);
+	}
+
+	iovlen = nooutpages + 6;
+	pageoffset = oper.do_cipher ? ((unsigned long int)oper.cipher_outdata & ~PAGE_MASK) : 0;
+
+	next_ix = next_cfg_change_ix(&oper, prev_ix);
+	if (prev_ix == next_ix){
+		DEBUG_API(printk("cryptocop_ioctl_process: length configuration broken.\n"));
+		err = -EINVAL;  /* This should be impossible barring bugs. */
+		goto error_cleanup;
+	}
+	while (prev_ix != next_ix){
+		end_digest = end_csum = cipher_active = digest_active = csum_active = 0;
+		descs[desc_ix].cfg = NULL;
+		descs[desc_ix].length = next_ix - prev_ix;
+
+		if (oper.do_cipher && (oper.cipher_start < next_ix) && (prev_ix < (oper.cipher_start + oper.cipher_len))) {
+			dcfgs[dcfg_ix].tid = CRYPTOCOP_IOCTL_CIPHER_TID;
+			dcfgs[dcfg_ix].src = cryptocop_source_dma;
+			cipher_active = 1;
+
+			if (next_ix == (oper.cipher_start + oper.cipher_len)){
+				cipher_done = 1;
+				dcfgs[dcfg_ix].last = 1;
+			} else {
+				dcfgs[dcfg_ix].last = 0;
+			}
+			dcfgs[dcfg_ix].next = descs[desc_ix].cfg;
+			descs[desc_ix].cfg = &dcfgs[dcfg_ix];
+			++dcfg_ix;
+		}
+		if (oper.do_digest && (oper.digest_start < next_ix) && (prev_ix < (oper.digest_start + oper.digest_len))) {
+			digest_active = 1;
+			dcfgs[dcfg_ix].tid = CRYPTOCOP_IOCTL_DIGEST_TID;
+			dcfgs[dcfg_ix].src = cryptocop_source_dma;
+			if (next_ix == (oper.digest_start + oper.digest_len)){
+				assert(!digest_done);
+				digest_done = 1;
+				dcfgs[dcfg_ix].last = 1;
+			} else {
+				dcfgs[dcfg_ix].last = 0;
+			}
+			dcfgs[dcfg_ix].next = descs[desc_ix].cfg;
+			descs[desc_ix].cfg = &dcfgs[dcfg_ix];
+			++dcfg_ix;
+		}
+		if (oper.do_csum && (oper.csum_start < next_ix) && (prev_ix < (oper.csum_start + oper.csum_len))){
+			csum_active = 1;
+			dcfgs[dcfg_ix].tid = CRYPTOCOP_IOCTL_CSUM_TID;
+			dcfgs[dcfg_ix].src = cryptocop_source_dma;
+			if (next_ix == (oper.csum_start + oper.csum_len)){
+				csum_done = 1;
+				dcfgs[dcfg_ix].last = 1;
+			} else {
+				dcfgs[dcfg_ix].last = 0;
+			}
+			dcfgs[dcfg_ix].next = descs[desc_ix].cfg;
+			descs[desc_ix].cfg = &dcfgs[dcfg_ix];
+			++dcfg_ix;
+		}
+		if (!descs[desc_ix].cfg){
+			DEBUG_API(printk("cryptocop_ioctl_process: data segment %d (%d to %d) had no active transforms\n", desc_ix, prev_ix, next_ix));
+			err = -EINVAL;
+			goto error_cleanup;
+		}
+		descs[desc_ix].next = &(descs[desc_ix]) + 1;
+		++desc_ix;
+		prev_ix = next_ix;
+		next_ix = next_cfg_change_ix(&oper, prev_ix);
+	}
+	if (desc_ix > 0){
+		descs[desc_ix-1].next = NULL;
+	} else {
+		descs[0].next = NULL;
+	}
+	if (oper.do_digest) {
+		DEBUG(printk("cryptocop_ioctl_process: mapping %d byte digest output to iovec %d\n", digest_length, iovix));
+		/* Add outdata iovec, length == <length of type of digest> */
+		cop->tfrm_op.outdata[iovix].iov_base = digest_result;
+		cop->tfrm_op.outdata[iovix].iov_len = digest_length;
+		++iovix;
+	}
+	if (oper.do_csum) {
+		/* Add outdata iovec, length == 2, the length of csum. */
+		DEBUG(printk("cryptocop_ioctl_process: mapping 2 byte csum output to iovec %d\n", iovix));
+		/* Add outdata iovec, length == <length of type of digest> */
+		cop->tfrm_op.outdata[iovix].iov_base = csum_result;
+		cop->tfrm_op.outdata[iovix].iov_len = 2;
+		++iovix;
+	}
+	if (oper.do_cipher) {
+		if (!map_pages_to_iovec(cop->tfrm_op.outdata, iovlen, &iovix, outpages, nooutpages, &pageix, &pageoffset, oper.cipher_outlen)){
+			DEBUG_API(printk("cryptocop_ioctl_process: failed to map pages to iovec.\n"));
+			err = -ENOSYS; /* This should be impossible barring bugs. */
+			goto error_cleanup;
+		}
+	}
+	DEBUG(printk("cryptocop_ioctl_process: setting cop->tfrm_op.outcount %d\n", iovix));
+	cop->tfrm_op.outcount = iovix;
+	assert(iovix <= (nooutpages + 6));
+
+	cop->sid = oper.ses_id;
+	cop->tfrm_op.desc = &descs[0];
+
+	DEBUG(printk("cryptocop_ioctl_process: inserting job, cb_data=0x%p\n", cop->cb_data));
+
+	if ((err = cryptocop_job_queue_insert_user_job(cop)) != 0) {
+		DEBUG_API(printk("cryptocop_ioctl_process: insert job %d\n", err));
+		err = -EINVAL;
+		goto error_cleanup;
+	}
+
+	DEBUG(printk("cryptocop_ioctl_process: begin wait for result\n"));
+
+	wait_event(cryptocop_ioc_process_wq, (jc->processed != 0));
+	DEBUG(printk("cryptocop_ioctl_process: end wait for result\n"));
+        if (!jc->processed){
+		printk(KERN_WARNING "cryptocop_ioctl_process: job not processed at completion\n");
+		err = -EIO;
+		goto error_cleanup;
+	}
+
+	/* Job process done.  Cipher output should already be correct in job so no post processing of outdata. */
+	DEBUG(printk("cryptocop_ioctl_process: operation_status = %d\n", cop->operation_status));
+	if (cop->operation_status == 0){
+		if (oper.do_digest){
+			DEBUG(printk("cryptocop_ioctl_process: copy %d bytes digest to user\n", digest_length));
+			err = copy_to_user((unsigned char*)crp_oper + offsetof(struct strcop_crypto_op, digest), digest_result, digest_length);
+			if (0 != err){
+				DEBUG_API(printk("cryptocop_ioctl_process: copy_to_user, digest length %d, err %d\n", digest_length, err));
+				err = -EFAULT;
+				goto error_cleanup;
+			}
+		}
+		if (oper.do_csum){
+			DEBUG(printk("cryptocop_ioctl_process: copy 2 bytes checksum to user\n"));
+			err = copy_to_user((unsigned char*)crp_oper + offsetof(struct strcop_crypto_op, csum), csum_result, 2);
+			if (0 != err){
+				DEBUG_API(printk("cryptocop_ioctl_process: copy_to_user, csum, err %d\n", err));
+				err = -EFAULT;
+				goto error_cleanup;
+			}
+		}
+		err = 0;
+	} else {
+		DEBUG(printk("cryptocop_ioctl_process: returning err = operation_status = %d\n", cop->operation_status));
+		err = cop->operation_status;
+	}
+
+ error_cleanup:
+	/* Release page caches. */
+	for (i = 0; i < noinpages; i++){
+		put_page(inpages[i]);
+	}
+	for (i = 0; i < nooutpages; i++){
+		int spdl_err;
+		/* Mark output pages dirty. */
+		spdl_err = set_page_dirty_lock(outpages[i]);
+		DEBUG(if (spdl_err)printk("cryptocop_ioctl_process: set_page_dirty_lock returned %d\n", spdl_err));
+	}
+	for (i = 0; i < nooutpages; i++){
+		put_page(outpages[i]);
+	}
+
+	if (digest_result) kfree(digest_result);
+	if (inpages) kfree(inpages);
+	if (outpages) kfree(outpages);
+	if (cop){
+		if (cop->tfrm_op.indata) kfree(cop->tfrm_op.indata);
+		if (cop->tfrm_op.outdata) kfree(cop->tfrm_op.outdata);
+		kfree(cop);
+	}
+	if (jc) kfree(jc);
+
+	DEBUG(print_lock_status());
+
+	return err;
+}
+
+
+static int cryptocop_ioctl_create_session(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
+{
+	cryptocop_session_id             sid;
+	int                              err;
+	struct cryptocop_private         *dev;
+	struct strcop_session_op         *sess_op = (struct strcop_session_op *)arg;
+	struct strcop_session_op         sop;
+	struct cryptocop_transform_init  *tis = NULL;
+	struct cryptocop_transform_init  ti_cipher = {0};
+	struct cryptocop_transform_init  ti_digest = {0};
+	struct cryptocop_transform_init  ti_csum = {0};
+
+	if (!access_ok(VERIFY_WRITE, sess_op, sizeof(struct strcop_session_op)))
+		return -EFAULT;
+	err = copy_from_user(&sop, sess_op, sizeof(struct strcop_session_op));
+	if (err) return -EFAULT;
+	if (sop.cipher != cryptocop_cipher_none) {
+		if (!access_ok(VERIFY_READ, sop.key, sop.keylen)) return -EFAULT;
+	}
+	DEBUG(printk("cryptocop_ioctl_create_session, sess_op:\n"));
+
+	DEBUG(printk("\tcipher:%d\n"
+		     "\tcipher_mode:%d\n"
+		     "\tdigest:%d\n"
+		     "\tcsum:%d\n",
+		     (int)sop.cipher,
+		     (int)sop.cmode,
+		     (int)sop.digest,
+		     (int)sop.csum));
+
+	if (sop.cipher != cryptocop_cipher_none){
+		/* Init the cipher. */
+		switch (sop.cipher){
+		case cryptocop_cipher_des:
+			ti_cipher.alg = cryptocop_alg_des;
+			break;
+		case cryptocop_cipher_3des:
+			ti_cipher.alg = cryptocop_alg_3des;
+			break;
+		case cryptocop_cipher_aes:
+			ti_cipher.alg = cryptocop_alg_aes;
+			break;
+		default:
+			DEBUG_API(printk("create session, bad cipher algorithm %d\n", sop.cipher));
+			return -EINVAL;
+		};
+		DEBUG(printk("setting cipher transform %d\n", ti_cipher.alg));
+		copy_from_user(ti_cipher.key, sop.key, sop.keylen/8);
+		ti_cipher.keylen = sop.keylen;
+		switch (sop.cmode){
+		case cryptocop_cipher_mode_cbc:
+		case cryptocop_cipher_mode_ecb:
+			ti_cipher.cipher_mode = sop.cmode;
+			break;
+		default:
+			DEBUG_API(printk("create session, bad cipher mode %d\n", sop.cmode));
+			return -EINVAL;
+		}
+		DEBUG(printk("cryptocop_ioctl_create_session: setting CBC mode %d\n", ti_cipher.cipher_mode));
+		switch (sop.des3_mode){
+		case cryptocop_3des_eee:
+		case cryptocop_3des_eed:
+		case cryptocop_3des_ede:
+		case cryptocop_3des_edd:
+		case cryptocop_3des_dee:
+		case cryptocop_3des_ded:
+		case cryptocop_3des_dde:
+		case cryptocop_3des_ddd:
+			ti_cipher.tdes_mode = sop.des3_mode;
+			break;
+		default:
+			DEBUG_API(printk("create session, bad 3DES mode %d\n", sop.des3_mode));
+			return -EINVAL;
+		}
+		ti_cipher.tid = CRYPTOCOP_IOCTL_CIPHER_TID;
+		ti_cipher.next = tis;
+		tis = &ti_cipher;
+	} /* if (sop.cipher != cryptocop_cipher_none) */
+	if (sop.digest != cryptocop_digest_none){
+		DEBUG(printk("setting digest transform\n"));
+		switch (sop.digest){
+		case cryptocop_digest_md5:
+			ti_digest.alg = cryptocop_alg_md5;
+			break;
+		case cryptocop_digest_sha1:
+			ti_digest.alg = cryptocop_alg_sha1;
+			break;
+		default:
+			DEBUG_API(printk("create session, bad digest algorithm %d\n", sop.digest));
+			return -EINVAL;
+		}
+		ti_digest.tid = CRYPTOCOP_IOCTL_DIGEST_TID;
+		ti_digest.next = tis;
+		tis = &ti_digest;
+	} /* if (sop.digest != cryptocop_digest_none) */
+	if (sop.csum != cryptocop_csum_none){
+		DEBUG(printk("setting csum transform\n"));
+		switch (sop.csum){
+		case cryptocop_csum_le:
+		case cryptocop_csum_be:
+			ti_csum.csum_mode = sop.csum;
+			break;
+		default:
+			DEBUG_API(printk("create session, bad checksum algorithm %d\n", sop.csum));
+			return -EINVAL;
+		}
+		ti_csum.alg = cryptocop_alg_csum;
+		ti_csum.tid = CRYPTOCOP_IOCTL_CSUM_TID;
+		ti_csum.next = tis;
+		tis = &ti_csum;
+	} /* (sop.csum != cryptocop_csum_none) */
+	dev = kmalloc(sizeof(struct cryptocop_private), GFP_KERNEL);
+	if (!dev){
+		DEBUG_API(printk("create session, alloc dev\n"));
+		return -ENOMEM;
+	}
+
+	err = cryptocop_new_session(&sid, tis, GFP_KERNEL);
+	DEBUG({ if (err) printk("create session, cryptocop_new_session %d\n", err);});
+
+	if (err) {
+		kfree(dev);
+		return err;
+	}
+	sess_op->ses_id = sid;
+	dev->sid = sid;
+	dev->next = filp->private_data;
+	filp->private_data = dev;
+
+	return 0;
+}
+
+static int cryptocop_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
+{
+	int err = 0;
+	if (_IOC_TYPE(cmd) != ETRAXCRYPTOCOP_IOCTYPE) {
+		DEBUG_API(printk("cryptocop_ioctl: wrong type\n"));
+		return -ENOTTY;
+	}
+	if (_IOC_NR(cmd) > CRYPTOCOP_IO_MAXNR){
+		return -ENOTTY;
+	}
+	/* Access check of the argument.  Some commands, e.g. create session and process op,
+	   needs additional checks.  Those are handled in the command handling functions. */
+	if (_IOC_DIR(cmd) & _IOC_READ)
+		err = !access_ok(VERIFY_WRITE, (void *)arg, _IOC_SIZE(cmd));
+	else if (_IOC_DIR(cmd) & _IOC_WRITE)
+		err = !access_ok(VERIFY_READ, (void *)arg, _IOC_SIZE(cmd));
+	if (err) return -EFAULT;
+
+	switch (cmd) {
+	case CRYPTOCOP_IO_CREATE_SESSION:
+		return cryptocop_ioctl_create_session(inode, filp, cmd, arg);
+	case CRYPTOCOP_IO_CLOSE_SESSION:
+		return cryptocop_ioctl_close_session(inode, filp, cmd, arg);
+	case CRYPTOCOP_IO_PROCESS_OP:
+		return cryptocop_ioctl_process(inode, filp, cmd, arg);
+	default:
+		DEBUG_API(printk("cryptocop_ioctl: unknown command\n"));
+		return -ENOTTY;
+	}
+	return 0;
+}
+
+
+#ifdef LDEBUG
+static void print_dma_descriptors(struct cryptocop_int_operation *iop)
+{
+	struct cryptocop_dma_desc *cdesc_out = iop->cdesc_out;
+	struct cryptocop_dma_desc *cdesc_in = iop->cdesc_in;
+	int                       i;
+
+	printk("print_dma_descriptors start\n");
+
+	printk("iop:\n");
+	printk("\tsid: 0x%lld\n", iop->sid);
+
+	printk("\tcdesc_out: 0x%p\n", iop->cdesc_out);
+	printk("\tcdesc_in: 0x%p\n", iop->cdesc_in);
+	printk("\tddesc_out: 0x%p\n", iop->ddesc_out);
+	printk("\tddesc_in: 0x%p\n", iop->ddesc_in);
+
+	printk("\niop->ctx_out: 0x%p phys: 0x%p\n", &iop->ctx_out, (char*)virt_to_phys(&iop->ctx_out));
+	printk("\tnext: 0x%p\n"
+	       "\tsaved_data: 0x%p\n"
+	       "\tsaved_data_buf: 0x%p\n",
+	       iop->ctx_out.next,
+	       iop->ctx_out.saved_data,
+	       iop->ctx_out.saved_data_buf);
+
+	printk("\niop->ctx_in: 0x%p phys: 0x%p\n", &iop->ctx_in, (char*)virt_to_phys(&iop->ctx_in));
+	printk("\tnext: 0x%p\n"
+	       "\tsaved_data: 0x%p\n"
+	       "\tsaved_data_buf: 0x%p\n",
+	       iop->ctx_in.next,
+	       iop->ctx_in.saved_data,
+	       iop->ctx_in.saved_data_buf);
+
+	i = 0;
+	while (cdesc_out) {
+		dma_descr_data *td;
+		printk("cdesc_out %d, desc=0x%p\n", i, cdesc_out->dma_descr);
+		printk("\n\tvirt_to_phys(desc): 0x%p\n", (char*)virt_to_phys(cdesc_out->dma_descr));
+		td = cdesc_out->dma_descr;
+		printk("\n\tbuf: 0x%p\n"
+		       "\tafter: 0x%p\n"
+		       "\tmd: 0x%04x\n"
+		       "\tnext: 0x%p\n",
+		       td->buf,
+		       td->after,
+		       td->md,
+		       td->next);
+		printk("flags:\n"
+		       "\twait:\t%d\n"
+		       "\teol:\t%d\n"
+		       "\touteop:\t%d\n"
+		       "\tineop:\t%d\n"
+		       "\tintr:\t%d\n",
+		       td->wait,
+		       td->eol,
+		       td->out_eop,
+		       td->in_eop,
+		       td->intr);
+		cdesc_out = cdesc_out->next;
+		i++;
+	}
+	i = 0;
+	while (cdesc_in) {
+		dma_descr_data *td;
+		printk("cdesc_in %d, desc=0x%p\n", i, cdesc_in->dma_descr);
+		printk("\n\tvirt_to_phys(desc): 0x%p\n", (char*)virt_to_phys(cdesc_in->dma_descr));
+		td = cdesc_in->dma_descr;
+		printk("\n\tbuf: 0x%p\n"
+		       "\tafter: 0x%p\n"
+		       "\tmd: 0x%04x\n"
+		       "\tnext: 0x%p\n",
+		       td->buf,
+		       td->after,
+		       td->md,
+		       td->next);
+		printk("flags:\n"
+		       "\twait:\t%d\n"
+		       "\teol:\t%d\n"
+		       "\touteop:\t%d\n"
+		       "\tineop:\t%d\n"
+		       "\tintr:\t%d\n",
+		       td->wait,
+		       td->eol,
+		       td->out_eop,
+		       td->in_eop,
+		       td->intr);
+		cdesc_in = cdesc_in->next;
+		i++;
+	}
+
+	printk("print_dma_descriptors end\n");
+}
+
+
+static void print_strcop_crypto_op(struct strcop_crypto_op *cop)
+{
+	printk("print_strcop_crypto_op, 0x%p\n", cop);
+
+	/* Indata. */
+	printk("indata=0x%p\n"
+	       "inlen=%d\n"
+	       "do_cipher=%d\n"
+	       "decrypt=%d\n"
+	       "cipher_explicit=%d\n"
+	       "cipher_start=%d\n"
+	       "cipher_len=%d\n"
+	       "outdata=0x%p\n"
+	       "outlen=%d\n",
+	       cop->indata,
+	       cop->inlen,
+	       cop->do_cipher,
+	       cop->decrypt,
+	       cop->cipher_explicit,
+	       cop->cipher_start,
+	       cop->cipher_len,
+	       cop->cipher_outdata,
+	       cop->cipher_outlen);
+
+	printk("do_digest=%d\n"
+	       "digest_start=%d\n"
+	       "digest_len=%d\n",
+	       cop->do_digest,
+	       cop->digest_start,
+	       cop->digest_len);
+
+	printk("do_csum=%d\n"
+	       "csum_start=%d\n"
+	       "csum_len=%d\n",
+	       cop->do_csum,
+	       cop->csum_start,
+	       cop->csum_len);
+}
+
+static void print_cryptocop_operation(struct cryptocop_operation *cop)
+{
+	struct cryptocop_desc      *d;
+	struct cryptocop_tfrm_cfg  *tc;
+	struct cryptocop_desc_cfg  *dc;
+	int                        i;
+
+	printk("print_cryptocop_operation, cop=0x%p\n\n", cop);
+	printk("sid: %lld\n", cop->sid);
+	printk("operation_status=%d\n"
+	       "use_dmalists=%d\n"
+	       "in_interrupt=%d\n"
+	       "fast_callback=%d\n",
+	       cop->operation_status,
+	       cop->use_dmalists,
+	       cop->in_interrupt,
+	       cop->fast_callback);
+
+	if (cop->use_dmalists){
+		print_user_dma_lists(&cop->list_op);
+	} else {
+		printk("cop->tfrm_op\n"
+		       "tfrm_cfg=0x%p\n"
+		       "desc=0x%p\n"
+		       "indata=0x%p\n"
+		       "incount=%d\n"
+		       "inlen=%d\n"
+		       "outdata=0x%p\n"
+		       "outcount=%d\n"
+		       "outlen=%d\n\n",
+		       cop->tfrm_op.tfrm_cfg,
+		       cop->tfrm_op.desc,
+		       cop->tfrm_op.indata,
+		       cop->tfrm_op.incount,
+		       cop->tfrm_op.inlen,
+		       cop->tfrm_op.outdata,
+		       cop->tfrm_op.outcount,
+		       cop->tfrm_op.outlen);
+
+		tc = cop->tfrm_op.tfrm_cfg;
+		while (tc){
+			printk("tfrm_cfg, 0x%p\n"
+			       "tid=%d\n"
+			       "flags=%d\n"
+			       "inject_ix=%d\n"
+			       "next=0x%p\n",
+			       tc,
+			       tc->tid,
+			       tc->flags,
+			       tc->inject_ix,
+			       tc->next);
+			tc = tc->next;
+		}
+		d = cop->tfrm_op.desc;
+		while (d){
+			printk("\n======================desc, 0x%p\n"
+			       "length=%d\n"
+			       "cfg=0x%p\n"
+			       "next=0x%p\n",
+			       d,
+			       d->length,
+			       d->cfg,
+			       d->next);
+			dc = d->cfg;
+			while (dc){
+				printk("=========desc_cfg, 0x%p\n"
+				       "tid=%d\n"
+				       "src=%d\n"
+				       "last=%d\n"
+				       "next=0x%p\n",
+				       dc,
+				       dc->tid,
+				       dc->src,
+				       dc->last,
+				       dc->next);
+				dc = dc->next;
+			}
+			d = d->next;
+		}
+		printk("\n====iniov\n");
+		for (i = 0; i < cop->tfrm_op.incount; i++){
+			printk("indata[%d]\n"
+			       "base=0x%p\n"
+			       "len=%d\n",
+			       i,
+			       cop->tfrm_op.indata[i].iov_base,
+			       cop->tfrm_op.indata[i].iov_len);
+		}
+		printk("\n====outiov\n");
+		for (i = 0; i < cop->tfrm_op.outcount; i++){
+			printk("outdata[%d]\n"
+			       "base=0x%p\n"
+			       "len=%d\n",
+			       i,
+			       cop->tfrm_op.outdata[i].iov_base,
+			       cop->tfrm_op.outdata[i].iov_len);
+		}
+	}
+	printk("------------end print_cryptocop_operation\n");
+}
+
+
+static void print_user_dma_lists(struct cryptocop_dma_list_operation *dma_op)
+{
+	dma_descr_data *dd;
+	int i;
+
+	printk("print_user_dma_lists, dma_op=0x%p\n", dma_op);
+
+	printk("out_data_buf = 0x%p, phys_to_virt(out_data_buf) = 0x%p\n", dma_op->out_data_buf, phys_to_virt((unsigned long int)dma_op->out_data_buf));
+	printk("in_data_buf = 0x%p, phys_to_virt(in_data_buf) = 0x%p\n", dma_op->in_data_buf, phys_to_virt((unsigned long int)dma_op->in_data_buf));
+
+	printk("##############outlist\n");
+	dd = phys_to_virt((unsigned long int)dma_op->outlist);
+	i = 0;
+	while (dd != NULL) {
+		printk("#%d phys_to_virt(desc) 0x%p\n", i, dd);
+		printk("\n\tbuf: 0x%p\n"
+		       "\tafter: 0x%p\n"
+		       "\tmd: 0x%04x\n"
+		       "\tnext: 0x%p\n",
+		       dd->buf,
+		       dd->after,
+		       dd->md,
+		       dd->next);
+		printk("flags:\n"
+		       "\twait:\t%d\n"
+		       "\teol:\t%d\n"
+		       "\touteop:\t%d\n"
+		       "\tineop:\t%d\n"
+		       "\tintr:\t%d\n",
+		       dd->wait,
+		       dd->eol,
+		       dd->out_eop,
+		       dd->in_eop,
+		       dd->intr);
+		if (dd->eol)
+			dd = NULL;
+		else
+			dd = phys_to_virt((unsigned long int)dd->next);
+		++i;
+	}
+
+	printk("##############inlist\n");
+	dd = phys_to_virt((unsigned long int)dma_op->inlist);
+	i = 0;
+	while (dd != NULL) {
+		printk("#%d phys_to_virt(desc) 0x%p\n", i, dd);
+		printk("\n\tbuf: 0x%p\n"
+		       "\tafter: 0x%p\n"
+		       "\tmd: 0x%04x\n"
+		       "\tnext: 0x%p\n",
+		       dd->buf,
+		       dd->after,
+		       dd->md,
+		       dd->next);
+		printk("flags:\n"
+		       "\twait:\t%d\n"
+		       "\teol:\t%d\n"
+		       "\touteop:\t%d\n"
+		       "\tineop:\t%d\n"
+		       "\tintr:\t%d\n",
+		       dd->wait,
+		       dd->eol,
+		       dd->out_eop,
+		       dd->in_eop,
+		       dd->intr);
+		if (dd->eol)
+			dd = NULL;
+		else
+			dd = phys_to_virt((unsigned long int)dd->next);
+		++i;
+	}
+}
+
+
+static void print_lock_status(void)
+{
+	printk("**********************print_lock_status\n");
+	printk("cryptocop_completed_jobs_lock %d\n", spin_is_locked(&cryptocop_completed_jobs_lock));
+	printk("cryptocop_job_queue_lock %d\n", spin_is_locked(&cryptocop_job_queue_lock));
+	printk("descr_pool_lock %d\n", spin_is_locked(&descr_pool_lock));
+	printk("cryptocop_sessions_lock %d\n", spin_is_locked(cryptocop_sessions_lock));
+	printk("running_job_lock %d\n", spin_is_locked(running_job_lock));
+	printk("cryptocop_process_lock %d\n", spin_is_locked(cryptocop_process_lock));
+}
+#endif /* LDEBUG */
+
+
+static const char cryptocop_name[] = "ETRAX FS stream co-processor";
+
+static int init_stream_coprocessor(void)
+{
+	int err;
+	int i;
+	static int initialized = 0;
+
+	if (initialized)
+		return 0;
+
+	initialized = 1;
+
+	printk("ETRAX FS stream co-processor driver v0.01, (c) 2003 Axis Communications AB\n");
+
+	err = register_chrdev(CRYPTOCOP_MAJOR, cryptocop_name, &cryptocop_fops);
+	if (err < 0) {
+		printk(KERN_ERR "stream co-processor: could not get major number.\n");
+		return err;
+	}
+
+	err = init_cryptocop();
+	if (err) {
+		(void)unregister_chrdev(CRYPTOCOP_MAJOR, cryptocop_name);
+		return err;
+	}
+	err = cryptocop_job_queue_init();
+	if (err) {
+		release_cryptocop();
+		(void)unregister_chrdev(CRYPTOCOP_MAJOR, cryptocop_name);
+		return err;
+	}
+	/* Init the descriptor pool. */
+	for (i = 0; i < CRYPTOCOP_DESCRIPTOR_POOL_SIZE - 1; i++) {
+		descr_pool[i].from_pool = 1;
+		descr_pool[i].next = &descr_pool[i + 1];
+	}
+	descr_pool[i].from_pool = 1;
+	descr_pool[i].next = NULL;
+	descr_pool_free_list = &descr_pool[0];
+	descr_pool_no_free = CRYPTOCOP_DESCRIPTOR_POOL_SIZE;
+
+	spin_lock_init(&cryptocop_completed_jobs_lock);
+	spin_lock_init(&cryptocop_job_queue_lock);
+	spin_lock_init(&descr_pool_lock);
+	spin_lock_init(&cryptocop_sessions_lock);
+	spin_lock_init(&running_job_lock);
+	spin_lock_init(&cryptocop_process_lock);
+
+	cryptocop_sessions = NULL;
+	next_sid = 1;
+
+	cryptocop_running_job = NULL;
+
+	printk("stream co-processor: init done.\n");
+	return 0;
+}
+
+static void __exit exit_stream_coprocessor(void)
+{
+	release_cryptocop();
+	cryptocop_job_queue_close();
+}
+
+module_init(init_stream_coprocessor);
+module_exit(exit_stream_coprocessor);
+
diff --git a/arch/cris/arch-v32/drivers/gpio.c b/arch/cris/arch-v32/drivers/gpio.c
new file mode 100644
--- /dev/null
+++ b/arch/cris/arch-v32/drivers/gpio.c
@@ -0,0 +1,766 @@
+/* $Id: gpio.c,v 1.16 2005/06/19 17:06:49 starvik Exp $
+ *
+ * ETRAX CRISv32 general port I/O device
+ *
+ * Copyright (c) 1999, 2000, 2001, 2002, 2003 Axis Communications AB
+ *
+ * Authors:    Bjorn Wesen      (initial version)
+ *             Ola Knutsson     (LED handling)
+ *             Johan Adolfsson  (read/set directions, write, port G,
+ *                               port to ETRAX FS.
+ *
+ * $Log: gpio.c,v $
+ * Revision 1.16  2005/06/19 17:06:49  starvik
+ * Merge of Linux 2.6.12.
+ *
+ * Revision 1.15  2005/05/25 08:22:20  starvik
+ * Changed GPIO port order to fit packages/devices/axis-2.4.
+ *
+ * Revision 1.14  2005/04/24 18:35:08  starvik
+ * Updated with final register headers.
+ *
+ * Revision 1.13  2005/03/15 15:43:00  starvik
+ * dev_id needs to be supplied for shared IRQs.
+ *
+ * Revision 1.12  2005/03/10 17:12:00  starvik
+ * Protect alarm list with spinlock.
+ *
+ * Revision 1.11  2005/01/05 06:08:59  starvik
+ * No need to do local_irq_disable after local_irq_save.
+ *
+ * Revision 1.10  2004/11/19 08:38:31  starvik
+ * Removed old crap.
+ *
+ * Revision 1.9  2004/05/14 07:58:02  starvik
+ * Merge of changes from 2.4
+ *
+ * Revision 1.8  2003/09/11 07:29:50  starvik
+ * Merge of Linux 2.6.0-test5
+ *
+ * Revision 1.7  2003/07/10 13:25:46  starvik
+ * Compiles for 2.5.74
+ * Lindented ethernet.c
+ *
+ * Revision 1.6  2003/07/04 08:27:46  starvik
+ * Merge of Linux 2.5.74
+ *
+ * Revision 1.5  2003/06/10 08:26:37  johana
+ * Etrax -> ETRAX CRISv32
+ *
+ * Revision 1.4  2003/06/05 14:22:48  johana
+ * Initialise some_alarms.
+ *
+ * Revision 1.3  2003/06/05 10:15:46  johana
+ * New INTR_VECT macros.
+ * Enable interrupts in global config.
+ *
+ * Revision 1.2  2003/06/03 15:52:50  johana
+ * Initial CRIS v32 version.
+ *
+ * Revision 1.1  2003/06/03 08:53:15  johana
+ * Copy of os/lx25/arch/cris/arch-v10/drivers/gpio.c version 1.7.
+ *
+ */
+
+#include <linux/config.h>
+
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/ioport.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/string.h>
+#include <linux/poll.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+
+#include <asm/etraxgpio.h>
+#include <asm/arch/hwregs/reg_map.h>
+#include <asm/arch/hwregs/reg_rdwr.h>
+#include <asm/arch/hwregs/gio_defs.h>
+#include <asm/arch/hwregs/intr_vect_defs.h>
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/irq.h>
+
+/* The following gio ports on ETRAX FS is available:
+ * pa  8 bits, supports interrupts off, hi, low, set, posedge, negedge anyedge
+ * pb 18 bits
+ * pc 18 bits
+ * pd 18 bits
+ * pe 18 bits
+ * each port has a rw_px_dout, r_px_din and rw_px_oe register.
+ */
+
+#define GPIO_MAJOR 120  /* experimental MAJOR number */
+
+#define D(x)
+
+#if 0
+static int dp_cnt;
+#define DP(x) do { dp_cnt++; if (dp_cnt % 1000 == 0) x; }while(0)
+#else
+#define DP(x)
+#endif
+
+static char gpio_name[] = "etrax gpio";
+
+#if 0
+static wait_queue_head_t *gpio_wq;
+#endif
+
+static int gpio_ioctl(struct inode *inode, struct file *file,
+		      unsigned int cmd, unsigned long arg);
+static ssize_t gpio_write(struct file * file, const char * buf, size_t count,
+                          loff_t *off);
+static int gpio_open(struct inode *inode, struct file *filp);
+static int gpio_release(struct inode *inode, struct file *filp);
+static unsigned int gpio_poll(struct file *filp, struct poll_table_struct *wait);
+
+/* private data per open() of this driver */
+
+struct gpio_private {
+	struct gpio_private *next;
+	/* The IO_CFG_WRITE_MODE_VALUE only support 8 bits: */
+	unsigned char clk_mask;
+	unsigned char data_mask;
+	unsigned char write_msb;
+	unsigned char pad1;
+	/* These fields are generic */
+	unsigned long highalarm, lowalarm;
+	wait_queue_head_t alarm_wq;
+	int minor;
+};
+
+/* linked list of alarms to check for */
+
+static struct gpio_private *alarmlist = 0;
+
+static int gpio_some_alarms = 0; /* Set if someone uses alarm */
+static unsigned long gpio_pa_high_alarms = 0;
+static unsigned long gpio_pa_low_alarms = 0;
+
+static DEFINE_SPINLOCK(alarm_lock);
+
+#define NUM_PORTS (GPIO_MINOR_LAST+1)
+#define GIO_REG_RD_ADDR(reg) (volatile unsigned long*) (regi_gio + REG_RD_ADDR_gio_##reg )
+#define GIO_REG_WR_ADDR(reg) (volatile unsigned long*) (regi_gio + REG_RD_ADDR_gio_##reg )
+unsigned long led_dummy;
+
+static volatile unsigned long *data_out[NUM_PORTS] = {
+	GIO_REG_WR_ADDR(rw_pa_dout),
+	GIO_REG_WR_ADDR(rw_pb_dout),
+	&led_dummy,
+	GIO_REG_WR_ADDR(rw_pc_dout),
+	GIO_REG_WR_ADDR(rw_pd_dout),
+	GIO_REG_WR_ADDR(rw_pe_dout),
+};
+
+static volatile unsigned long *data_in[NUM_PORTS] = {
+	GIO_REG_RD_ADDR(r_pa_din),
+	GIO_REG_RD_ADDR(r_pb_din),
+	&led_dummy,
+	GIO_REG_RD_ADDR(r_pc_din),
+	GIO_REG_RD_ADDR(r_pd_din),
+	GIO_REG_RD_ADDR(r_pe_din),
+};
+
+static unsigned long changeable_dir[NUM_PORTS] = {
+	CONFIG_ETRAX_PA_CHANGEABLE_DIR,
+	CONFIG_ETRAX_PB_CHANGEABLE_DIR,
+	0,
+	CONFIG_ETRAX_PC_CHANGEABLE_DIR,
+	CONFIG_ETRAX_PD_CHANGEABLE_DIR,
+	CONFIG_ETRAX_PE_CHANGEABLE_DIR,
+};
+
+static unsigned long changeable_bits[NUM_PORTS] = {
+	CONFIG_ETRAX_PA_CHANGEABLE_BITS,
+	CONFIG_ETRAX_PB_CHANGEABLE_BITS,
+	0,
+	CONFIG_ETRAX_PC_CHANGEABLE_BITS,
+	CONFIG_ETRAX_PD_CHANGEABLE_BITS,
+	CONFIG_ETRAX_PE_CHANGEABLE_BITS,
+};
+
+static volatile unsigned long *dir_oe[NUM_PORTS] = {
+	GIO_REG_WR_ADDR(rw_pa_oe),
+	GIO_REG_WR_ADDR(rw_pb_oe),
+	&led_dummy,
+	GIO_REG_WR_ADDR(rw_pc_oe),
+	GIO_REG_WR_ADDR(rw_pd_oe),
+	GIO_REG_WR_ADDR(rw_pe_oe),
+};
+
+
+
+static unsigned int
+gpio_poll(struct file *file,
+	  poll_table *wait)
+{
+	unsigned int mask = 0;
+	struct gpio_private *priv = (struct gpio_private *)file->private_data;
+	unsigned long data;
+	poll_wait(file, &priv->alarm_wq, wait);
+	if (priv->minor == GPIO_MINOR_A) {
+		reg_gio_rw_intr_cfg intr_cfg;
+		unsigned long tmp;
+		unsigned long flags;
+
+		local_irq_save(flags);
+		data = REG_TYPE_CONV(unsigned long, reg_gio_r_pa_din, REG_RD(gio, regi_gio, r_pa_din));
+		/* PA has support for interrupt
+		 * lets activate high for those low and with highalarm set
+		 */
+		intr_cfg = REG_RD(gio, regi_gio, rw_intr_cfg);
+
+		tmp = ~data & priv->highalarm & 0xFF;
+                if (tmp & (1 << 0)) {
+			intr_cfg.pa0 = regk_gio_hi;
+		}
+                if (tmp & (1 << 1)) {
+			intr_cfg.pa1 = regk_gio_hi;
+		}
+                if (tmp & (1 << 2)) {
+			intr_cfg.pa2 = regk_gio_hi;
+		}
+                if (tmp & (1 << 3)) {
+			intr_cfg.pa3 = regk_gio_hi;
+		}
+                if (tmp & (1 << 4)) {
+			intr_cfg.pa4 = regk_gio_hi;
+		}
+                if (tmp & (1 << 5)) {
+			intr_cfg.pa5 = regk_gio_hi;
+		}
+                if (tmp & (1 << 6)) {
+			intr_cfg.pa6 = regk_gio_hi;
+		}
+                if (tmp & (1 << 7)) {
+			intr_cfg.pa7 = regk_gio_hi;
+		}
+		/*
+		 * lets activate low for those high and with lowalarm set
+		 */
+		tmp = data & priv->lowalarm & 0xFF;
+                if (tmp & (1 << 0)) {
+			intr_cfg.pa0 = regk_gio_lo;
+		}
+                if (tmp & (1 << 1)) {
+			intr_cfg.pa1 = regk_gio_lo;
+		}
+                if (tmp & (1 << 2)) {
+			intr_cfg.pa2 = regk_gio_lo;
+		}
+                if (tmp & (1 << 3)) {
+			intr_cfg.pa3 = regk_gio_lo;
+		}
+                if (tmp & (1 << 4)) {
+			intr_cfg.pa4 = regk_gio_lo;
+		}
+                if (tmp & (1 << 5)) {
+			intr_cfg.pa5 = regk_gio_lo;
+		}
+                if (tmp & (1 << 6)) {
+			intr_cfg.pa6 = regk_gio_lo;
+		}
+                if (tmp & (1 << 7)) {
+			intr_cfg.pa7 = regk_gio_lo;
+		}
+
+		REG_WR(gio, regi_gio, rw_intr_cfg, intr_cfg);
+		local_irq_restore(flags);
+	} else if (priv->minor <= GPIO_MINOR_E)
+		data = *data_in[priv->minor];
+	else
+		return 0;
+
+	if ((data & priv->highalarm) ||
+	    (~data & priv->lowalarm)) {
+		mask = POLLIN|POLLRDNORM;
+	}
+
+	DP(printk("gpio_poll ready: mask 0x%08X\n", mask));
+	return mask;
+}
+
+int etrax_gpio_wake_up_check(void)
+{
+	struct gpio_private *priv = alarmlist;
+	unsigned long data = 0;
+        int ret = 0;
+	while (priv) {
+		data = *data_in[priv->minor];
+		if ((data & priv->highalarm) ||
+		    (~data & priv->lowalarm)) {
+			DP(printk("etrax_gpio_wake_up_check %i\n",priv->minor));
+			wake_up_interruptible(&priv->alarm_wq);
+                        ret = 1;
+		}
+		priv = priv->next;
+	}
+        return ret;
+}
+
+static irqreturn_t
+gpio_poll_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	if (gpio_some_alarms) {
+		return IRQ_RETVAL(etrax_gpio_wake_up_check());
+	}
+        return IRQ_NONE;
+}
+
+static irqreturn_t
+gpio_pa_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	reg_gio_rw_intr_mask intr_mask;
+	reg_gio_r_masked_intr masked_intr;
+	reg_gio_rw_ack_intr ack_intr;
+	unsigned long tmp;
+	unsigned long tmp2;
+
+	/* Find what PA interrupts are active */
+	masked_intr = REG_RD(gio, regi_gio, r_masked_intr);
+	tmp = REG_TYPE_CONV(unsigned long, reg_gio_r_masked_intr, masked_intr);
+
+	/* Find those that we have enabled */
+	spin_lock(&alarm_lock);
+	tmp &= (gpio_pa_high_alarms | gpio_pa_low_alarms);
+	spin_unlock(&alarm_lock);
+
+	/* Ack them */
+	ack_intr = REG_TYPE_CONV(reg_gio_rw_ack_intr, unsigned long, tmp);
+	REG_WR(gio, regi_gio, rw_ack_intr, ack_intr);
+
+	/* Disable those interrupts.. */
+	intr_mask = REG_RD(gio, regi_gio, rw_intr_mask);
+	tmp2 = REG_TYPE_CONV(unsigned long, reg_gio_rw_intr_mask, intr_mask);
+	tmp2 &= ~tmp;
+	intr_mask = REG_TYPE_CONV(reg_gio_rw_intr_mask, unsigned long, tmp2);
+	REG_WR(gio, regi_gio, rw_intr_mask, intr_mask);
+
+	if (gpio_some_alarms) {
+		return IRQ_RETVAL(etrax_gpio_wake_up_check());
+	}
+        return IRQ_NONE;
+}
+
+
+static ssize_t gpio_write(struct file * file, const char * buf, size_t count,
+                          loff_t *off)
+{
+	struct gpio_private *priv = (struct gpio_private *)file->private_data;
+	unsigned char data, clk_mask, data_mask, write_msb;
+	unsigned long flags;
+	unsigned long shadow;
+	volatile unsigned long *port;
+	ssize_t retval = count;
+	/* Only bits 0-7 may be used for write operations but allow all
+	   devices except leds... */
+	if (priv->minor == GPIO_MINOR_LEDS) {
+		return -EFAULT;
+	}
+
+	if (!access_ok(VERIFY_READ, buf, count)) {
+		return -EFAULT;
+	}
+	clk_mask = priv->clk_mask;
+	data_mask = priv->data_mask;
+	/* It must have been configured using the IO_CFG_WRITE_MODE */
+	/* Perhaps a better error code? */
+	if (clk_mask == 0 || data_mask == 0) {
+		return -EPERM;
+	}
+	write_msb = priv->write_msb;
+	D(printk("gpio_write: %lu to data 0x%02X clk 0x%02X msb: %i\n",count, data_mask, clk_mask, write_msb));
+	port = data_out[priv->minor];
+
+	while (count--) {
+		int i;
+		data = *buf++;
+		if (priv->write_msb) {
+			for (i = 7; i >= 0;i--) {
+				local_irq_save(flags);
+				shadow = *port;
+				*port = shadow &= ~clk_mask;
+				if (data & 1<<i)
+					*port = shadow |= data_mask;
+				else
+					*port = shadow &= ~data_mask;
+			/* For FPGA: min 5.0ns (DCC) before CCLK high */
+				*port = shadow |= clk_mask;
+				local_irq_restore(flags);
+			}
+		} else {
+			for (i = 0; i <= 7;i++) {
+				local_irq_save(flags);
+				shadow = *port;
+				*port = shadow &= ~clk_mask;
+				if (data & 1<<i)
+					*port = shadow |= data_mask;
+				else
+					*port = shadow &= ~data_mask;
+			/* For FPGA: min 5.0ns (DCC) before CCLK high */
+				*port = shadow |= clk_mask;
+				local_irq_restore(flags);
+			}
+		}
+	}
+	return retval;
+}
+
+
+
+static int
+gpio_open(struct inode *inode, struct file *filp)
+{
+	struct gpio_private *priv;
+	int p = MINOR(inode->i_rdev);
+
+	if (p > GPIO_MINOR_LAST)
+		return -EINVAL;
+
+	priv = (struct gpio_private *)kmalloc(sizeof(struct gpio_private),
+					      GFP_KERNEL);
+
+	if (!priv)
+		return -ENOMEM;
+
+	priv->minor = p;
+
+	/* initialize the io/alarm struct and link it into our alarmlist */
+
+	priv->next = alarmlist;
+	alarmlist = priv;
+	priv->clk_mask = 0;
+	priv->data_mask = 0;
+	priv->highalarm = 0;
+	priv->lowalarm = 0;
+	init_waitqueue_head(&priv->alarm_wq);
+
+	filp->private_data = (void *)priv;
+
+	return 0;
+}
+
+static int
+gpio_release(struct inode *inode, struct file *filp)
+{
+	struct gpio_private *p = alarmlist;
+	struct gpio_private *todel = (struct gpio_private *)filp->private_data;
+	/* local copies while updating them: */
+	unsigned long a_high, a_low;
+	unsigned long some_alarms;
+
+	/* unlink from alarmlist and free the private structure */
+
+	if (p == todel) {
+		alarmlist = todel->next;
+	} else {
+		while (p->next != todel)
+			p = p->next;
+		p->next = todel->next;
+	}
+
+	kfree(todel);
+	/* Check if there are still any alarms set */
+	p = alarmlist;
+        some_alarms = 0;
+	a_high = 0;
+	a_low = 0;
+	while (p) {
+		if (p->minor == GPIO_MINOR_A) {
+			a_high |= p->highalarm;
+			a_low |= p->lowalarm;
+		}
+
+		if (p->highalarm | p->lowalarm) {
+			some_alarms = 1;
+		}
+		p = p->next;
+	}
+
+	spin_lock(&alarm_lock);
+	gpio_some_alarms = some_alarms;
+	gpio_pa_high_alarms = a_high;
+	gpio_pa_low_alarms = a_low;
+	spin_unlock(&alarm_lock);
+
+	return 0;
+}
+
+/* Main device API. ioctl's to read/set/clear bits, as well as to
+ * set alarms to wait for using a subsequent select().
+ */
+
+unsigned long inline setget_input(struct gpio_private *priv, unsigned long arg)
+{
+	/* Set direction 0=unchanged 1=input,
+	 * return mask with 1=input
+	 */
+	unsigned long flags;
+	unsigned long dir_shadow;
+
+	local_irq_save(flags);
+	dir_shadow = *dir_oe[priv->minor];
+	dir_shadow &= ~(arg & changeable_dir[priv->minor]);
+	*dir_oe[priv->minor] = dir_shadow;
+	local_irq_restore(flags);
+
+	if (priv->minor == GPIO_MINOR_A)
+		dir_shadow ^= 0xFF;    /* Only 8 bits */
+	else
+		dir_shadow ^= 0x3FFFF; /* Only 18 bits */
+	return dir_shadow;
+
+} /* setget_input */
+
+unsigned long inline setget_output(struct gpio_private *priv, unsigned long arg)
+{
+	unsigned long flags;
+	unsigned long dir_shadow;
+
+	local_irq_save(flags);
+	dir_shadow = *dir_oe[priv->minor];
+	dir_shadow |=  (arg & changeable_dir[priv->minor]);
+	*dir_oe[priv->minor] = dir_shadow;
+	local_irq_restore(flags);
+	return dir_shadow;
+} /* setget_output */
+
+static int
+gpio_leds_ioctl(unsigned int cmd, unsigned long arg);
+
+static int
+gpio_ioctl(struct inode *inode, struct file *file,
+	   unsigned int cmd, unsigned long arg)
+{
+	unsigned long flags;
+	unsigned long val;
+	unsigned long shadow;
+	struct gpio_private *priv = (struct gpio_private *)file->private_data;
+	if (_IOC_TYPE(cmd) != ETRAXGPIO_IOCTYPE) {
+		return -EINVAL;
+	}
+
+	switch (_IOC_NR(cmd)) {
+	case IO_READBITS: /* Use IO_READ_INBITS and IO_READ_OUTBITS instead */
+		// read the port
+		return *data_in[priv->minor];
+		break;
+	case IO_SETBITS:
+		local_irq_save(flags);
+                if (arg & 0x04)
+                  printk("GPIO SET 2\n");
+		// set changeable bits with a 1 in arg
+		shadow = *data_out[priv->minor];
+		shadow |=  (arg & changeable_bits[priv->minor]);
+		*data_out[priv->minor] = shadow;
+		local_irq_restore(flags);
+		break;
+	case IO_CLRBITS:
+		local_irq_save(flags);
+                if (arg & 0x04)
+                  printk("GPIO CLR 2\n");
+		// clear changeable bits with a 1 in arg
+		shadow = *data_out[priv->minor];
+		shadow &=  ~(arg & changeable_bits[priv->minor]);
+		*data_out[priv->minor] = shadow;
+		local_irq_restore(flags);
+		break;
+	case IO_HIGHALARM:
+		// set alarm when bits with 1 in arg go high
+		priv->highalarm |= arg;
+		spin_lock(&alarm_lock);
+		gpio_some_alarms = 1;
+		if (priv->minor == GPIO_MINOR_A) {
+			gpio_pa_high_alarms |= arg;
+		}
+		spin_unlock(&alarm_lock);
+		break;
+	case IO_LOWALARM:
+		// set alarm when bits with 1 in arg go low
+		priv->lowalarm |= arg;
+		spin_lock(&alarm_lock);
+		gpio_some_alarms = 1;
+		if (priv->minor == GPIO_MINOR_A) {
+			gpio_pa_low_alarms |= arg;
+		}
+		spin_unlock(&alarm_lock);
+		break;
+	case IO_CLRALARM:
+		// clear alarm for bits with 1 in arg
+		priv->highalarm &= ~arg;
+		priv->lowalarm  &= ~arg;
+		spin_lock(&alarm_lock);
+		if (priv->minor == GPIO_MINOR_A) {
+			if (gpio_pa_high_alarms & arg ||
+			    gpio_pa_low_alarms & arg) {
+				/* Must update the gpio_pa_*alarms masks */
+			}
+		}
+		spin_unlock(&alarm_lock);
+		break;
+	case IO_READDIR: /* Use IO_SETGET_INPUT/OUTPUT instead! */
+		/* Read direction 0=input 1=output */
+		return *dir_oe[priv->minor];
+	case IO_SETINPUT: /* Use IO_SETGET_INPUT instead! */
+		/* Set direction 0=unchanged 1=input,
+		 * return mask with 1=input
+		 */
+		return setget_input(priv, arg);
+		break;
+	case IO_SETOUTPUT: /* Use IO_SETGET_OUTPUT instead! */
+		/* Set direction 0=unchanged 1=output,
+		 * return mask with 1=output
+		 */
+		return setget_output(priv, arg);
+
+	case IO_CFG_WRITE_MODE:
+	{
+		unsigned long dir_shadow;
+		dir_shadow = *dir_oe[priv->minor];
+
+		priv->clk_mask = arg & 0xFF;
+		priv->data_mask = (arg >> 8) & 0xFF;
+		priv->write_msb = (arg >> 16) & 0x01;
+		/* Check if we're allowed to change the bits and
+		 * the direction is correct
+		 */
+		if (!((priv->clk_mask & changeable_bits[priv->minor]) &&
+		      (priv->data_mask & changeable_bits[priv->minor]) &&
+		      (priv->clk_mask & dir_shadow) &&
+		      (priv->data_mask & dir_shadow)))
+		{
+			priv->clk_mask = 0;
+			priv->data_mask = 0;
+			return -EPERM;
+		}
+		break;
+	}
+	case IO_READ_INBITS:
+		/* *arg is result of reading the input pins */
+		val = *data_in[priv->minor];
+		if (copy_to_user((unsigned long*)arg, &val, sizeof(val)))
+			return -EFAULT;
+		return 0;
+		break;
+	case IO_READ_OUTBITS:
+		 /* *arg is result of reading the output shadow */
+		val = *data_out[priv->minor];
+		if (copy_to_user((unsigned long*)arg, &val, sizeof(val)))
+			return -EFAULT;
+		break;
+	case IO_SETGET_INPUT:
+		/* bits set in *arg is set to input,
+		 * *arg updated with current input pins.
+		 */
+		if (copy_from_user(&val, (unsigned long*)arg, sizeof(val)))
+			return -EFAULT;
+		val = setget_input(priv, val);
+		if (copy_to_user((unsigned long*)arg, &val, sizeof(val)))
+			return -EFAULT;
+		break;
+	case IO_SETGET_OUTPUT:
+		/* bits set in *arg is set to output,
+		 * *arg updated with current output pins.
+		 */
+		if (copy_from_user(&val, (unsigned long*)arg, sizeof(val)))
+			return -EFAULT;
+		val = setget_output(priv, val);
+		if (copy_to_user((unsigned long*)arg, &val, sizeof(val)))
+			return -EFAULT;
+		break;
+	default:
+		if (priv->minor == GPIO_MINOR_LEDS)
+			return gpio_leds_ioctl(cmd, arg);
+		else
+			return -EINVAL;
+	} /* switch */
+
+	return 0;
+}
+
+static int
+gpio_leds_ioctl(unsigned int cmd, unsigned long arg)
+{
+	unsigned char green;
+	unsigned char red;
+
+	switch (_IOC_NR(cmd)) {
+	case IO_LEDACTIVE_SET:
+		green = ((unsigned char) arg) & 1;
+		red   = (((unsigned char) arg) >> 1) & 1;
+		LED_ACTIVE_SET_G(green);
+		LED_ACTIVE_SET_R(red);
+		break;
+
+	default:
+		return -EINVAL;
+	} /* switch */
+
+	return 0;
+}
+
+struct file_operations gpio_fops = {
+	.owner       = THIS_MODULE,
+	.poll        = gpio_poll,
+	.ioctl       = gpio_ioctl,
+	.write       = gpio_write,
+	.open        = gpio_open,
+	.release     = gpio_release,
+};
+
+
+/* main driver initialization routine, called from mem.c */
+
+static __init int
+gpio_init(void)
+{
+	int res;
+	reg_intr_vect_rw_mask intr_mask;
+
+	/* do the formalities */
+
+	res = register_chrdev(GPIO_MAJOR, gpio_name, &gpio_fops);
+	if (res < 0) {
+		printk(KERN_ERR "gpio: couldn't get a major number.\n");
+		return res;
+	}
+
+	/* Clear all leds */
+	LED_NETWORK_SET(0);
+	LED_ACTIVE_SET(0);
+	LED_DISK_READ(0);
+	LED_DISK_WRITE(0);
+
+	printk("ETRAX FS GPIO driver v2.5, (c) 2003-2005 Axis Communications AB\n");
+	/* We call etrax_gpio_wake_up_check() from timer interrupt and
+	 * from cpu_idle() in kernel/process.c
+	 * The check in cpu_idle() reduces latency from ~15 ms to ~6 ms
+	 * in some tests.
+	 */
+	if (request_irq(TIMER_INTR_VECT, gpio_poll_timer_interrupt,
+			SA_SHIRQ | SA_INTERRUPT,"gpio poll", &alarmlist)) {
+		printk("err: timer0 irq for gpio\n");
+	}
+	if (request_irq(GEN_IO_INTR_VECT, gpio_pa_interrupt,
+			SA_SHIRQ | SA_INTERRUPT,"gpio PA", &alarmlist)) {
+		printk("err: PA irq for gpio\n");
+	}
+	/* enable the gio and timer irq in global config */
+	intr_mask = REG_RD(intr_vect, regi_irq, rw_mask);
+	intr_mask.timer = 1;
+	intr_mask.gen_io = 1;
+	REG_WR(intr_vect, regi_irq, rw_mask, intr_mask);
+
+	return res;
+}
+
+/* this makes sure that gpio_init is called during kernel boot */
+
+module_init(gpio_init);
diff --git a/arch/cris/arch-v32/drivers/i2c.c b/arch/cris/arch-v32/drivers/i2c.c
new file mode 100644
--- /dev/null
+++ b/arch/cris/arch-v32/drivers/i2c.c
@@ -0,0 +1,611 @@
+/*!***************************************************************************
+*!
+*! FILE NAME  : i2c.c
+*!
+*! DESCRIPTION: implements an interface for IIC/I2C, both directly from other
+*!              kernel modules (i2c_writereg/readreg) and from userspace using
+*!              ioctl()'s
+*!
+*! Nov 30 1998  Torbjorn Eliasson  Initial version.
+*!              Bjorn Wesen        Elinux kernel version.
+*! Jan 14 2000  Johan Adolfsson    Fixed PB shadow register stuff -
+*!                                 don't use PB_I2C if DS1302 uses same bits,
+*!                                 use PB.
+*| June 23 2003 Pieter Grimmerink  Added 'i2c_sendnack'. i2c_readreg now
+*|                                 generates nack on last received byte,
+*|                                 instead of ack.
+*|                                 i2c_getack changed data level while clock
+*|                                 was high, causing DS75 to see  a stop condition
+*!
+*! ---------------------------------------------------------------------------
+*!
+*! (C) Copyright 1999-2002 Axis Communications AB, LUND, SWEDEN
+*!
+*!***************************************************************************/
+/* $Id: i2c.c,v 1.2 2005/05/09 15:29:49 starvik Exp $ */
+/****************** INCLUDE FILES SECTION ***********************************/
+
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/config.h>
+
+#include <asm/etraxi2c.h>
+
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/delay.h>
+
+#include "i2c.h"
+
+/****************** I2C DEFINITION SECTION *************************/
+
+#define D(x)
+
+#define I2C_MAJOR 123  /* LOCAL/EXPERIMENTAL */
+static const char i2c_name[] = "i2c";
+
+#define CLOCK_LOW_TIME            8
+#define CLOCK_HIGH_TIME           8
+#define START_CONDITION_HOLD_TIME 8
+#define STOP_CONDITION_HOLD_TIME  8
+#define ENABLE_OUTPUT 0x01
+#define ENABLE_INPUT 0x00
+#define I2C_CLOCK_HIGH 1
+#define I2C_CLOCK_LOW 0
+#define I2C_DATA_HIGH 1
+#define I2C_DATA_LOW 0
+
+#define i2c_enable()
+#define i2c_disable()
+
+/* enable or disable output-enable, to select output or input on the i2c bus */
+
+#define i2c_dir_out() crisv32_io_set_dir(&cris_i2c_data, crisv32_io_dir_out)
+#define i2c_dir_in() crisv32_io_set_dir(&cris_i2c_data, crisv32_io_dir_in)
+
+/* control the i2c clock and data signals */
+
+#define i2c_clk(x) crisv32_io_set(&cris_i2c_clk, x)
+#define i2c_data(x) crisv32_io_set(&cris_i2c_data, x)
+
+/* read a bit from the i2c interface */
+
+#define i2c_getbit() crisv32_io_rd(&cris_i2c_data)
+
+#define i2c_delay(usecs) udelay(usecs)
+
+/****************** VARIABLE SECTION ************************************/
+
+static struct crisv32_iopin cris_i2c_clk;
+static struct crisv32_iopin cris_i2c_data;
+
+/****************** FUNCTION DEFINITION SECTION *************************/
+
+
+/* generate i2c start condition */
+
+void
+i2c_start(void)
+{
+	/*
+	 * SCL=1 SDA=1
+	 */
+	i2c_dir_out();
+	i2c_delay(CLOCK_HIGH_TIME/6);
+	i2c_data(I2C_DATA_HIGH);
+	i2c_clk(I2C_CLOCK_HIGH);
+	i2c_delay(CLOCK_HIGH_TIME);
+	/*
+	 * SCL=1 SDA=0
+	 */
+	i2c_data(I2C_DATA_LOW);
+	i2c_delay(START_CONDITION_HOLD_TIME);
+	/*
+	 * SCL=0 SDA=0
+	 */
+	i2c_clk(I2C_CLOCK_LOW);
+	i2c_delay(CLOCK_LOW_TIME);
+}
+
+/* generate i2c stop condition */
+
+void
+i2c_stop(void)
+{
+	i2c_dir_out();
+
+	/*
+	 * SCL=0 SDA=0
+	 */
+	i2c_clk(I2C_CLOCK_LOW);
+	i2c_data(I2C_DATA_LOW);
+	i2c_delay(CLOCK_LOW_TIME*2);
+	/*
+	 * SCL=1 SDA=0
+	 */
+	i2c_clk(I2C_CLOCK_HIGH);
+	i2c_delay(CLOCK_HIGH_TIME*2);
+	/*
+	 * SCL=1 SDA=1
+	 */
+	i2c_data(I2C_DATA_HIGH);
+	i2c_delay(STOP_CONDITION_HOLD_TIME);
+
+	i2c_dir_in();
+}
+
+/* write a byte to the i2c interface */
+
+void
+i2c_outbyte(unsigned char x)
+{
+	int i;
+
+	i2c_dir_out();
+
+	for (i = 0; i < 8; i++) {
+		if (x & 0x80) {
+			i2c_data(I2C_DATA_HIGH);
+		} else {
+			i2c_data(I2C_DATA_LOW);
+		}
+
+		i2c_delay(CLOCK_LOW_TIME/2);
+		i2c_clk(I2C_CLOCK_HIGH);
+		i2c_delay(CLOCK_HIGH_TIME);
+		i2c_clk(I2C_CLOCK_LOW);
+		i2c_delay(CLOCK_LOW_TIME/2);
+		x <<= 1;
+	}
+	i2c_data(I2C_DATA_LOW);
+	i2c_delay(CLOCK_LOW_TIME/2);
+
+	/*
+	 * enable input
+	 */
+	i2c_dir_in();
+}
+
+/* read a byte from the i2c interface */
+
+unsigned char
+i2c_inbyte(void)
+{
+	unsigned char aBitByte = 0;
+	int i;
+
+	/* Switch off I2C to get bit */
+	i2c_disable();
+	i2c_dir_in();
+	i2c_delay(CLOCK_HIGH_TIME/2);
+
+	/* Get bit */
+	aBitByte |= i2c_getbit();
+
+	/* Enable I2C */
+	i2c_enable();
+	i2c_delay(CLOCK_LOW_TIME/2);
+
+	for (i = 1; i < 8; i++) {
+		aBitByte <<= 1;
+		/* Clock pulse */
+		i2c_clk(I2C_CLOCK_HIGH);
+		i2c_delay(CLOCK_HIGH_TIME);
+		i2c_clk(I2C_CLOCK_LOW);
+		i2c_delay(CLOCK_LOW_TIME);
+
+		/* Switch off I2C to get bit */
+		i2c_disable();
+		i2c_dir_in();
+		i2c_delay(CLOCK_HIGH_TIME/2);
+
+		/* Get bit */
+		aBitByte |= i2c_getbit();
+
+		/* Enable I2C */
+		i2c_enable();
+		i2c_delay(CLOCK_LOW_TIME/2);
+	}
+	i2c_clk(I2C_CLOCK_HIGH);
+	i2c_delay(CLOCK_HIGH_TIME);
+
+	/*
+	 * we leave the clock low, getbyte is usually followed
+	 * by sendack/nack, they assume the clock to be low
+	 */
+	i2c_clk(I2C_CLOCK_LOW);
+	return aBitByte;
+}
+
+/*#---------------------------------------------------------------------------
+*#
+*# FUNCTION NAME: i2c_getack
+*#
+*# DESCRIPTION  : checks if ack was received from ic2
+*#
+*#--------------------------------------------------------------------------*/
+
+int
+i2c_getack(void)
+{
+	int ack = 1;
+	/*
+	 * enable output
+	 */
+	i2c_dir_out();
+	/*
+	 * Release data bus by setting
+	 * data high
+	 */
+	i2c_data(I2C_DATA_HIGH);
+	/*
+	 * enable input
+	 */
+	i2c_dir_in();
+	i2c_delay(CLOCK_HIGH_TIME/4);
+	/*
+	 * generate ACK clock pulse
+	 */
+	i2c_clk(I2C_CLOCK_HIGH);
+	/*
+	 * Use PORT PB instead of I2C
+	 * for input. (I2C not working)
+	 */
+	i2c_clk(1);
+	i2c_data(1);
+	/*
+	 * switch off I2C
+	 */
+	i2c_data(1);
+	i2c_disable();
+	i2c_dir_in();
+	/*
+	 * now wait for ack
+	 */
+	i2c_delay(CLOCK_HIGH_TIME/2);
+	/*
+	 * check for ack
+	 */
+	if(i2c_getbit())
+		ack = 0;
+	i2c_delay(CLOCK_HIGH_TIME/2);
+	if(!ack){
+		if(!i2c_getbit()) /* receiver pulld SDA low */
+			ack = 1;
+		i2c_delay(CLOCK_HIGH_TIME/2);
+	}
+
+   /*
+    * our clock is high now, make sure data is low
+    * before we enable our output. If we keep data high
+    * and enable output, we would generate a stop condition.
+    */
+   i2c_data(I2C_DATA_LOW);
+
+	/*
+	 * end clock pulse
+	 */
+	i2c_enable();
+	i2c_dir_out();
+	i2c_clk(I2C_CLOCK_LOW);
+	i2c_delay(CLOCK_HIGH_TIME/4);
+	/*
+	 * enable output
+	 */
+	i2c_dir_out();
+	/*
+	 * remove ACK clock pulse
+	 */
+	i2c_data(I2C_DATA_HIGH);
+	i2c_delay(CLOCK_LOW_TIME/2);
+	return ack;
+}
+
+/*#---------------------------------------------------------------------------
+*#
+*# FUNCTION NAME: I2C::sendAck
+*#
+*# DESCRIPTION  : Send ACK on received data
+*#
+*#--------------------------------------------------------------------------*/
+void
+i2c_sendack(void)
+{
+	/*
+	 * enable output
+	 */
+	i2c_delay(CLOCK_LOW_TIME);
+	i2c_dir_out();
+	/*
+	 * set ack pulse high
+	 */
+	i2c_data(I2C_DATA_LOW);
+	/*
+	 * generate clock pulse
+	 */
+	i2c_delay(CLOCK_HIGH_TIME/6);
+	i2c_clk(I2C_CLOCK_HIGH);
+	i2c_delay(CLOCK_HIGH_TIME);
+	i2c_clk(I2C_CLOCK_LOW);
+	i2c_delay(CLOCK_LOW_TIME/6);
+	/*
+	 * reset data out
+	 */
+	i2c_data(I2C_DATA_HIGH);
+	i2c_delay(CLOCK_LOW_TIME);
+
+	i2c_dir_in();
+}
+
+/*#---------------------------------------------------------------------------
+*#
+*# FUNCTION NAME: i2c_sendnack
+*#
+*# DESCRIPTION  : Sends NACK on received data
+*#
+*#--------------------------------------------------------------------------*/
+void
+i2c_sendnack(void)
+{
+	/*
+	 * enable output
+	 */
+	i2c_delay(CLOCK_LOW_TIME);
+	i2c_dir_out();
+	/*
+	 * set data high
+	 */
+	i2c_data(I2C_DATA_HIGH);
+	/*
+	 * generate clock pulse
+	 */
+	i2c_delay(CLOCK_HIGH_TIME/6);
+	i2c_clk(I2C_CLOCK_HIGH);
+	i2c_delay(CLOCK_HIGH_TIME);
+	i2c_clk(I2C_CLOCK_LOW);
+	i2c_delay(CLOCK_LOW_TIME);
+
+	i2c_dir_in();
+}
+
+/*#---------------------------------------------------------------------------
+*#
+*# FUNCTION NAME: i2c_writereg
+*#
+*# DESCRIPTION  : Writes a value to an I2C device
+*#
+*#--------------------------------------------------------------------------*/
+int
+i2c_writereg(unsigned char theSlave, unsigned char theReg,
+	     unsigned char theValue)
+{
+	int error, cntr = 3;
+	unsigned long flags;
+
+	do {
+		error = 0;
+		/*
+		 * we don't like to be interrupted
+		 */
+                local_irq_save(flags);
+
+		i2c_start();
+		/*
+		 * send slave address
+		 */
+		i2c_outbyte((theSlave & 0xfe));
+		/*
+		 * wait for ack
+		 */
+		if(!i2c_getack())
+			error = 1;
+		/*
+		 * now select register
+		 */
+		i2c_dir_out();
+		i2c_outbyte(theReg);
+		/*
+		 * now it's time to wait for ack
+		 */
+		if(!i2c_getack())
+			error |= 2;
+		/*
+		 * send register register data
+		 */
+		i2c_outbyte(theValue);
+		/*
+		 * now it's time to wait for ack
+		 */
+		if(!i2c_getack())
+			error |= 4;
+		/*
+		 * end byte stream
+		 */
+		i2c_stop();
+		/*
+		 * enable interrupt again
+		 */
+		local_irq_restore(flags);
+
+	} while(error && cntr--);
+
+	i2c_delay(CLOCK_LOW_TIME);
+
+	return -error;
+}
+
+/*#---------------------------------------------------------------------------
+*#
+*# FUNCTION NAME: i2c_readreg
+*#
+*# DESCRIPTION  : Reads a value from the decoder registers.
+*#
+*#--------------------------------------------------------------------------*/
+unsigned char
+i2c_readreg(unsigned char theSlave, unsigned char theReg)
+{
+	unsigned char b = 0;
+	int error, cntr = 3;
+	unsigned long flags;
+
+	do {
+		error = 0;
+		/*
+		 * we don't like to be interrupted
+		 */
+                local_irq_save(flags);
+		/*
+		 * generate start condition
+		 */
+		i2c_start();
+
+		/*
+		 * send slave address
+		 */
+		i2c_outbyte((theSlave & 0xfe));
+		/*
+		 * wait for ack
+		 */
+		if(!i2c_getack())
+			error = 1;
+		/*
+		 * now select register
+		 */
+		i2c_dir_out();
+		i2c_outbyte(theReg);
+		/*
+		 * now it's time to wait for ack
+		 */
+		if(!i2c_getack())
+			error = 1;
+		/*
+		 * repeat start condition
+		 */
+		i2c_delay(CLOCK_LOW_TIME);
+		i2c_start();
+		/*
+		 * send slave address
+		 */
+		i2c_outbyte(theSlave | 0x01);
+		/*
+		 * wait for ack
+		 */
+		if(!i2c_getack())
+			error = 1;
+		/*
+		 * fetch register
+		 */
+		b = i2c_inbyte();
+		/*
+		 * last received byte needs to be nacked
+		 * instead of acked
+		 */
+		i2c_sendnack();
+		/*
+		 * end sequence
+		 */
+		i2c_stop();
+		/*
+		 * enable interrupt again
+		 */
+		local_irq_restore(flags);
+
+	} while(error && cntr--);
+
+	return b;
+}
+
+static int
+i2c_open(struct inode *inode, struct file *filp)
+{
+	return 0;
+}
+
+static int
+i2c_release(struct inode *inode, struct file *filp)
+{
+	return 0;
+}
+
+/* Main device API. ioctl's to write or read to/from i2c registers.
+ */
+
+static int
+i2c_ioctl(struct inode *inode, struct file *file,
+	  unsigned int cmd, unsigned long arg)
+{
+	if(_IOC_TYPE(cmd) != ETRAXI2C_IOCTYPE) {
+		return -EINVAL;
+	}
+
+	switch (_IOC_NR(cmd)) {
+		case I2C_WRITEREG:
+			/* write to an i2c slave */
+			D(printk("i2cw %d %d %d\n",
+				 I2C_ARGSLAVE(arg),
+				 I2C_ARGREG(arg),
+				 I2C_ARGVALUE(arg)));
+
+			return i2c_writereg(I2C_ARGSLAVE(arg),
+					    I2C_ARGREG(arg),
+					    I2C_ARGVALUE(arg));
+		case I2C_READREG:
+		{
+			unsigned char val;
+			/* read from an i2c slave */
+			D(printk("i2cr %d %d ",
+				I2C_ARGSLAVE(arg),
+				I2C_ARGREG(arg)));
+			val = i2c_readreg(I2C_ARGSLAVE(arg), I2C_ARGREG(arg));
+			D(printk("= %d\n", val));
+			return val;
+		}
+		default:
+			return -EINVAL;
+
+	}
+
+	return 0;
+}
+
+static struct file_operations i2c_fops = {
+	owner:    THIS_MODULE,
+	ioctl:    i2c_ioctl,
+	open:     i2c_open,
+	release:  i2c_release,
+};
+
+int __init
+i2c_init(void)
+{
+	int res;
+
+	/* Setup and enable the Port B I2C interface */
+
+        crisv32_io_get_name(&cris_i2c_data, CONFIG_ETRAX_I2C_DATA_PORT);
+        crisv32_io_get_name(&cris_i2c_clk, CONFIG_ETRAX_I2C_CLK_PORT);
+
+	/* register char device */
+
+	res = register_chrdev(I2C_MAJOR, i2c_name, &i2c_fops);
+	if(res < 0) {
+		printk(KERN_ERR "i2c: couldn't get a major number.\n");
+		return res;
+	}
+
+	printk(KERN_INFO "I2C driver v2.2, (c) 1999-2001 Axis Communications AB\n");
+
+	return 0;
+}
+
+/* this makes sure that i2c_init is called during boot */
+
+module_init(i2c_init);
+
+/****************** END OF FILE i2c.c ********************************/
diff --git a/arch/cris/arch-v32/drivers/i2c.h b/arch/cris/arch-v32/drivers/i2c.h
new file mode 100644
--- /dev/null
+++ b/arch/cris/arch-v32/drivers/i2c.h
@@ -0,0 +1,15 @@
+
+#include <linux/init.h>
+
+/* High level I2C actions */
+int __init i2c_init(void);
+int i2c_writereg(unsigned char theSlave, unsigned char theReg, unsigned char theValue);
+unsigned char i2c_readreg(unsigned char theSlave, unsigned char theReg);
+
+/* Low level I2C */
+void i2c_start(void);
+void i2c_stop(void);
+void i2c_outbyte(unsigned char x);
+unsigned char i2c_inbyte(void);
+int i2c_getack(void);
+void i2c_sendack(void);
diff --git a/arch/cris/arch-v32/drivers/iop_fw_load.c b/arch/cris/arch-v32/drivers/iop_fw_load.c
new file mode 100644
--- /dev/null
+++ b/arch/cris/arch-v32/drivers/iop_fw_load.c
@@ -0,0 +1,219 @@
+/* $Id: iop_fw_load.c,v 1.4 2005/04/07 09:27:46 larsv Exp $
+ *
+ * Firmware loader for ETRAX FS IO-Processor
+ *
+ * Copyright (C) 2004  Axis Communications AB
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/firmware.h>
+
+#include <asm/arch/hwregs/reg_map.h>
+#include <asm/arch/hwregs/iop/iop_reg_space.h>
+#include <asm/arch/hwregs/iop/iop_mpu_macros.h>
+#include <asm/arch/hwregs/iop/iop_mpu_defs.h>
+#include <asm/arch/hwregs/iop/iop_spu_defs.h>
+#include <asm/arch/hwregs/iop/iop_sw_cpu_defs.h>
+
+#define IOP_TIMEOUT 100
+
+static struct device iop_spu_device[2] = {
+	{ .bus_id =     "iop-spu0", },
+	{ .bus_id =     "iop-spu1", },
+};
+
+static struct device iop_mpu_device = {
+	.bus_id =       "iop-mpu",
+};
+
+static int wait_mpu_idle(void)
+{
+	reg_iop_mpu_r_stat mpu_stat;
+	unsigned int timeout = IOP_TIMEOUT;
+
+	do {
+		mpu_stat = REG_RD(iop_mpu, regi_iop_mpu, r_stat);
+	} while (mpu_stat.instr_reg_busy == regk_iop_mpu_yes && --timeout > 0);
+	if (timeout == 0) {
+		printk(KERN_ERR "Timeout waiting for MPU to be idle\n");
+		return -EBUSY;
+	}
+	return 0;
+}
+
+int iop_fw_load_spu(const unsigned char *fw_name, unsigned int spu_inst)
+{
+	reg_iop_sw_cpu_rw_mc_ctrl mc_ctrl = {
+		.wr_spu0_mem =    regk_iop_sw_cpu_no,
+		.wr_spu1_mem =    regk_iop_sw_cpu_no,
+		.size =           4,
+		.cmd =            regk_iop_sw_cpu_reg_copy,
+		.keep_owner =     regk_iop_sw_cpu_yes
+	};
+	reg_iop_spu_rw_ctrl spu_ctrl = {
+		.en  =            regk_iop_spu_no,
+		.fsm =            regk_iop_spu_no,
+	};
+	reg_iop_sw_cpu_r_mc_stat mc_stat;
+        const struct firmware *fw_entry;
+	u32 *data;
+	unsigned int timeout;
+	int retval, i;
+
+	if (spu_inst > 1)
+		return -ENODEV;
+
+	/* get firmware */
+	retval = request_firmware(&fw_entry,
+				  fw_name,
+				  &iop_spu_device[spu_inst]);
+	if (retval != 0)
+	{
+		printk(KERN_ERR
+		       "iop_load_spu: Failed to load firmware \"%s\"\n",
+		       fw_name);
+		return retval;
+	}
+	data = (u32 *) fw_entry->data;
+
+	/* acquire ownership of memory controller */
+	switch (spu_inst) {
+	case 0:
+		mc_ctrl.wr_spu0_mem = regk_iop_sw_cpu_yes;
+		REG_WR(iop_spu, regi_iop_spu0, rw_ctrl, spu_ctrl);
+		break;
+	case 1:
+		mc_ctrl.wr_spu1_mem = regk_iop_sw_cpu_yes;
+		REG_WR(iop_spu, regi_iop_spu1, rw_ctrl, spu_ctrl);
+		break;
+	}
+	timeout = IOP_TIMEOUT;
+	do {
+		REG_WR(iop_sw_cpu, regi_iop_sw_cpu, rw_mc_ctrl, mc_ctrl);
+		mc_stat = REG_RD(iop_sw_cpu, regi_iop_sw_cpu, r_mc_stat);
+	} while (mc_stat.owned_by_cpu == regk_iop_sw_cpu_no && --timeout > 0);
+	if (timeout == 0) {
+		printk(KERN_ERR "Timeout waiting to acquire MC\n");
+		retval = -EBUSY;
+		goto out;
+	}
+
+	/* write to SPU memory */
+	for (i = 0; i < (fw_entry->size/4); i++) {
+		switch (spu_inst) {
+		case 0:
+			REG_WR_INT(iop_spu, regi_iop_spu0, rw_seq_pc, (i*4));
+			break;
+		case 1:
+			REG_WR_INT(iop_spu, regi_iop_spu1, rw_seq_pc, (i*4));
+			break;
+		}
+		REG_WR_INT(iop_sw_cpu, regi_iop_sw_cpu, rw_mc_data, *data);
+		data++;
+	}
+
+	/* release ownership of memory controller */
+	(void) REG_RD(iop_sw_cpu, regi_iop_sw_cpu, rs_mc_data);
+
+ out:
+	release_firmware(fw_entry);
+	return retval;
+}
+
+int iop_fw_load_mpu(unsigned char *fw_name)
+{
+	const unsigned int start_addr = 0;
+	reg_iop_mpu_rw_ctrl mpu_ctrl;
+        const struct firmware *fw_entry;
+	u32 *data;
+	int retval, i;
+
+	/* get firmware */
+	retval = request_firmware(&fw_entry, fw_name, &iop_mpu_device);
+	if (retval != 0)
+	{
+		printk(KERN_ERR
+		       "iop_load_spu: Failed to load firmware \"%s\"\n",
+		       fw_name);
+		return retval;
+	}
+	data = (u32 *) fw_entry->data;
+
+	/* disable MPU */
+	mpu_ctrl.en = regk_iop_mpu_no;
+	REG_WR(iop_mpu, regi_iop_mpu, rw_ctrl, mpu_ctrl);
+	/* put start address in R0 */
+	REG_WR_VECT(iop_mpu, regi_iop_mpu, rw_r, 0, start_addr);
+	/* write to memory by executing 'SWX i, 4, R0' for each word */
+	if ((retval = wait_mpu_idle()) != 0)
+		goto out;
+	REG_WR(iop_mpu, regi_iop_mpu, rw_instr, MPU_SWX_IIR_INSTR(0, 4, 0));
+	for (i = 0; i < (fw_entry->size / 4); i++) {
+		REG_WR_INT(iop_mpu, regi_iop_mpu, rw_immediate, *data);
+		if ((retval = wait_mpu_idle()) != 0)
+			goto out;
+		data++;
+	}
+
+ out:
+	release_firmware(fw_entry);
+	return retval;
+}
+
+int iop_start_mpu(unsigned int start_addr)
+{
+	reg_iop_mpu_rw_ctrl mpu_ctrl = { .en = regk_iop_mpu_yes };
+	int retval;
+
+	/* disable MPU */
+	if ((retval = wait_mpu_idle()) != 0)
+		goto out;
+	REG_WR(iop_mpu, regi_iop_mpu, rw_instr, MPU_HALT());
+	if ((retval = wait_mpu_idle()) != 0)
+		goto out;
+	/* set PC and wait for it to bite */
+	if ((retval = wait_mpu_idle()) != 0)
+		goto out;
+	REG_WR_INT(iop_mpu, regi_iop_mpu, rw_instr, MPU_BA_I(start_addr));
+	if ((retval = wait_mpu_idle()) != 0)
+		goto out;
+	/* make sure the MPU starts executing with interrupts disabled */
+	REG_WR(iop_mpu, regi_iop_mpu, rw_instr, MPU_DI());
+	if ((retval = wait_mpu_idle()) != 0)
+		goto out;
+	/* enable MPU */
+	REG_WR(iop_mpu, regi_iop_mpu, rw_ctrl, mpu_ctrl);
+ out:
+	return retval;
+}
+
+static int __init iop_fw_load_init(void)
+{
+	device_initialize(&iop_spu_device[0]);
+	kobject_set_name(&iop_spu_device[0].kobj, "iop-spu0");
+	kobject_add(&iop_spu_device[0].kobj);
+	device_initialize(&iop_spu_device[1]);
+	kobject_set_name(&iop_spu_device[1].kobj, "iop-spu1");
+	kobject_add(&iop_spu_device[1].kobj);
+	device_initialize(&iop_mpu_device);
+	kobject_set_name(&iop_mpu_device.kobj, "iop-mpu");
+	kobject_add(&iop_mpu_device.kobj);
+	return 0;
+}
+
+static void __exit iop_fw_load_exit(void)
+{
+}
+
+module_init(iop_fw_load_init);
+module_exit(iop_fw_load_exit);
+
+MODULE_DESCRIPTION("ETRAX FS IO-Processor Firmware Loader");
+MODULE_LICENSE("GPL");
+
+EXPORT_SYMBOL(iop_fw_load_spu);
+EXPORT_SYMBOL(iop_fw_load_mpu);
+EXPORT_SYMBOL(iop_start_mpu);
diff --git a/arch/cris/arch-v32/drivers/nandflash.c b/arch/cris/arch-v32/drivers/nandflash.c
new file mode 100644
--- /dev/null
+++ b/arch/cris/arch-v32/drivers/nandflash.c
@@ -0,0 +1,157 @@
+/*
+ *  arch/cris/arch-v32/drivers/nandflash.c
+ *
+ *  Copyright (c) 2004
+ *
+ *  Derived from drivers/mtd/nand/spia.c
+ * 	  Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com)
+ *
+ * $Id: nandflash.c,v 1.3 2005/06/01 10:57:12 starvik Exp $
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/version.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+#include <asm/arch/memmap.h>
+#include <asm/arch/hwregs/reg_map.h>
+#include <asm/arch/hwregs/reg_rdwr.h>
+#include <asm/arch/hwregs/gio_defs.h>
+#include <asm/arch/hwregs/bif_core_defs.h>
+#include <asm/io.h>
+
+#define CE_BIT 4
+#define CLE_BIT 5
+#define ALE_BIT 6
+#define BY_BIT 7
+
+static struct mtd_info *crisv32_mtd = NULL;
+/*
+ *	hardware specific access to control-lines
+*/
+static void crisv32_hwcontrol(struct mtd_info *mtd, int cmd)
+{
+	unsigned long flags;
+	reg_gio_rw_pa_dout dout = REG_RD(gio, regi_gio, rw_pa_dout);
+
+	local_irq_save(flags);
+	switch(cmd){
+		case NAND_CTL_SETCLE:
+		     dout.data |= (1<<CLE_BIT);
+		     break;
+		case NAND_CTL_CLRCLE:
+		     dout.data &= ~(1<<CLE_BIT);
+		     break;
+		case NAND_CTL_SETALE:
+		     dout.data |= (1<<ALE_BIT);
+		     break;
+		case NAND_CTL_CLRALE:
+		     dout.data &= ~(1<<ALE_BIT);
+		     break;
+		case NAND_CTL_SETNCE:
+		     dout.data |= (1<<CE_BIT);
+		     break;
+		case NAND_CTL_CLRNCE:
+		     dout.data &= ~(1<<CE_BIT);
+		     break;
+	}
+	REG_WR(gio, regi_gio, rw_pa_dout, dout);
+	local_irq_restore(flags);
+}
+
+/*
+*	read device ready pin
+*/
+int crisv32_device_ready(struct mtd_info *mtd)
+{
+	reg_gio_r_pa_din din = REG_RD(gio, regi_gio, r_pa_din);
+	return ((din.data & (1 << BY_BIT)) >> BY_BIT);
+}
+
+/*
+ * Main initialization routine
+ */
+struct mtd_info* __init crisv32_nand_flash_probe (void)
+{
+	void __iomem *read_cs;
+	void __iomem *write_cs;
+
+	reg_bif_core_rw_grp3_cfg bif_cfg = REG_RD(bif_core, regi_bif_core, rw_grp3_cfg);
+	reg_gio_rw_pa_oe pa_oe = REG_RD(gio, regi_gio, rw_pa_oe);
+	struct nand_chip *this;
+	int err = 0;
+
+	/* Allocate memory for MTD device structure and private data */
+	crisv32_mtd = kmalloc (sizeof(struct mtd_info) + sizeof (struct nand_chip),
+				GFP_KERNEL);
+	if (!crisv32_mtd) {
+		printk ("Unable to allocate CRISv32 NAND MTD device structure.\n");
+		err = -ENOMEM;
+		return NULL;
+	}
+
+	read_cs = ioremap(MEM_CSP0_START | MEM_NON_CACHEABLE, 8192);
+	write_cs = ioremap(MEM_CSP1_START | MEM_NON_CACHEABLE, 8192);
+
+	if (!read_cs || !write_cs) {
+		printk("CRISv32 NAND ioremap failed\n");
+		err = -EIO;
+		goto out_mtd;
+	}
+
+	/* Get pointer to private data */
+	this = (struct nand_chip *) (&crisv32_mtd[1]);
+
+	pa_oe.oe |= 1 << CE_BIT;
+	pa_oe.oe |= 1 << ALE_BIT;
+	pa_oe.oe |= 1 << CLE_BIT;
+	pa_oe.oe &= ~ (1 << BY_BIT);
+	REG_WR(gio, regi_gio, rw_pa_oe, pa_oe);
+
+	bif_cfg.gated_csp0 = regk_bif_core_rd;
+	bif_cfg.gated_csp1 = regk_bif_core_wr;
+	REG_WR(bif_core, regi_bif_core, rw_grp3_cfg, bif_cfg);
+
+	/* Initialize structures */
+	memset((char *) crisv32_mtd, 0, sizeof(struct mtd_info));
+	memset((char *) this, 0, sizeof(struct nand_chip));
+
+	/* Link the private data with the MTD structure */
+	crisv32_mtd->priv = this;
+
+	/* Set address of NAND IO lines */
+	this->IO_ADDR_R = read_cs;
+	this->IO_ADDR_W = write_cs;
+	this->hwcontrol = crisv32_hwcontrol;
+	this->dev_ready = crisv32_device_ready;
+	/* 20 us command delay time */
+	this->chip_delay = 20;
+	this->eccmode = NAND_ECC_SOFT;
+
+	/* Enable the following for a flash based bad block table */
+	this->options = NAND_USE_FLASH_BBT;
+
+	/* Scan to find existance of the device */
+	if (nand_scan (crisv32_mtd, 1)) {
+		err = -ENXIO;
+		goto out_ior;
+	}
+
+	return crisv32_mtd;
+
+out_ior:
+	iounmap((void *)read_cs);
+	iounmap((void *)write_cs);
+out_mtd:
+	kfree (crisv32_mtd);
+        return NULL;
+}
+
diff --git a/arch/cris/arch-v32/drivers/pcf8563.c b/arch/cris/arch-v32/drivers/pcf8563.c
new file mode 100644
--- /dev/null
+++ b/arch/cris/arch-v32/drivers/pcf8563.c
@@ -0,0 +1,341 @@
+/*
+ * PCF8563 RTC
+ *
+ * From Phillips' datasheet:
+ *
+ * The PCF8563 is a CMOS real-time clock/calendar optimized for low power
+ * consumption. A programmable clock output, interupt output and voltage
+ * low detector are also provided. All address and data are transferred
+ * serially via two-line bidirectional I2C-bus. Maximum bus speed is
+ * 400 kbits/s. The built-in word address register is incremented
+ * automatically after each written or read byte.
+ *
+ * Copyright (c) 2002-2003, Axis Communications AB
+ * All rights reserved.
+ *
+ * Author: Tobias Anderberg <tobiasa@axis.com>.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/ioctl.h>
+#include <linux/delay.h>
+#include <linux/bcd.h>
+
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/rtc.h>
+
+#include "i2c.h"
+
+#define PCF8563_MAJOR	121	/* Local major number. */
+#define DEVICE_NAME	"rtc"	/* Name which is registered in /proc/devices. */
+#define PCF8563_NAME	"PCF8563"
+#define DRIVER_VERSION	"$Revision: 1.1 $"
+
+/* Two simple wrapper macros, saves a few keystrokes. */
+#define rtc_read(x) i2c_readreg(RTC_I2C_READ, x)
+#define rtc_write(x,y) i2c_writereg(RTC_I2C_WRITE, x, y)
+
+static const unsigned char days_in_month[] =
+	{ 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+
+int pcf8563_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
+int pcf8563_open(struct inode *, struct file *);
+int pcf8563_release(struct inode *, struct file *);
+
+static struct file_operations pcf8563_fops = {
+	owner: THIS_MODULE,
+	ioctl: pcf8563_ioctl,
+	open: pcf8563_open,
+	release: pcf8563_release,
+};
+
+unsigned char
+pcf8563_readreg(int reg)
+{
+	unsigned char res = rtc_read(reg);
+
+	/* The PCF8563 does not return 0 for unimplemented bits */
+	switch (reg) {
+		case RTC_SECONDS:
+		case RTC_MINUTES:
+			res &= 0x7F;
+			break;
+		case RTC_HOURS:
+		case RTC_DAY_OF_MONTH:
+			res &= 0x3F;
+			break;
+		case RTC_WEEKDAY:
+			res &= 0x07;
+			break;
+		case RTC_MONTH:
+			res &= 0x1F;
+			break;
+		case RTC_CONTROL1:
+			res &= 0xA8;
+			break;
+		case RTC_CONTROL2:
+			res &= 0x1F;
+			break;
+		case RTC_CLOCKOUT_FREQ:
+		case RTC_TIMER_CONTROL:
+			res &= 0x83;
+			break;
+	}
+	return res;
+}
+
+void
+pcf8563_writereg(int reg, unsigned char val)
+{
+#ifdef CONFIG_ETRAX_RTC_READONLY
+	if (reg == RTC_CONTROL1 || (reg >= RTC_SECONDS && reg <= RTC_YEAR))
+		return;
+#endif
+
+	rtc_write(reg, val);
+}
+
+void
+get_rtc_time(struct rtc_time *tm)
+{
+	tm->tm_sec  = rtc_read(RTC_SECONDS);
+	tm->tm_min  = rtc_read(RTC_MINUTES);
+	tm->tm_hour = rtc_read(RTC_HOURS);
+	tm->tm_mday = rtc_read(RTC_DAY_OF_MONTH);
+	tm->tm_wday = rtc_read(RTC_WEEKDAY);
+	tm->tm_mon  = rtc_read(RTC_MONTH);
+	tm->tm_year = rtc_read(RTC_YEAR);
+
+	if (tm->tm_sec & 0x80)
+		printk(KERN_WARNING "%s: RTC Voltage Low - reliable date/time "
+		       "information is no longer guaranteed!\n", PCF8563_NAME);
+
+	tm->tm_year  = BCD_TO_BIN(tm->tm_year) + ((tm->tm_mon & 0x80) ? 100 : 0);
+	tm->tm_sec  &= 0x7F;
+	tm->tm_min  &= 0x7F;
+	tm->tm_hour &= 0x3F;
+	tm->tm_mday &= 0x3F;
+	tm->tm_wday &= 0x07; /* Not coded in BCD. */
+	tm->tm_mon  &= 0x1F;
+
+	BCD_TO_BIN(tm->tm_sec);
+	BCD_TO_BIN(tm->tm_min);
+	BCD_TO_BIN(tm->tm_hour);
+	BCD_TO_BIN(tm->tm_mday);
+	BCD_TO_BIN(tm->tm_mon);
+	tm->tm_mon--; /* Month is 1..12 in RTC but 0..11 in linux */
+}
+
+int __init
+pcf8563_init(void)
+{
+	/* Initiate the i2c protocol. */
+	i2c_init();
+
+	/*
+	 * First of all we need to reset the chip. This is done by
+	 * clearing control1, control2 and clk freq and resetting
+	 * all alarms.
+	 */
+	if (rtc_write(RTC_CONTROL1, 0x00) < 0)
+		goto err;
+
+	if (rtc_write(RTC_CONTROL2, 0x00) < 0)
+		goto err;
+
+	if (rtc_write(RTC_CLOCKOUT_FREQ, 0x00) < 0)
+		goto err;
+
+	if (rtc_write(RTC_TIMER_CONTROL, 0x03) < 0)
+		goto err;
+
+	/* Reset the alarms. */
+	if (rtc_write(RTC_MINUTE_ALARM, 0x80) < 0)
+		goto err;
+
+	if (rtc_write(RTC_HOUR_ALARM, 0x80) < 0)
+		goto err;
+
+	if (rtc_write(RTC_DAY_ALARM, 0x80) < 0)
+		goto err;
+
+	if (rtc_write(RTC_WEEKDAY_ALARM, 0x80) < 0)
+		goto err;
+
+	if (register_chrdev(PCF8563_MAJOR, DEVICE_NAME, &pcf8563_fops) < 0) {
+		printk(KERN_INFO "%s: Unable to get major numer %d for RTC device.\n",
+		       PCF8563_NAME, PCF8563_MAJOR);
+		return -1;
+	}
+
+	printk(KERN_INFO "%s Real-Time Clock Driver, %s\n", PCF8563_NAME, DRIVER_VERSION);
+
+	/* Check for low voltage, and warn about it.. */
+	if (rtc_read(RTC_SECONDS) & 0x80)
+		printk(KERN_WARNING "%s: RTC Voltage Low - reliable date/time "
+		       "information is no longer guaranteed!\n", PCF8563_NAME);
+
+	return 0;
+
+err:
+	printk(KERN_INFO "%s: Error initializing chip.\n", PCF8563_NAME);
+	return -1;
+}
+
+void __exit
+pcf8563_exit(void)
+{
+	if (unregister_chrdev(PCF8563_MAJOR, DEVICE_NAME) < 0) {
+		printk(KERN_INFO "%s: Unable to unregister device.\n", PCF8563_NAME);
+	}
+}
+
+/*
+ * ioctl calls for this driver. Why return -ENOTTY upon error? Because
+ * POSIX says so!
+ */
+int
+pcf8563_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
+{
+	/* Some sanity checks. */
+	if (_IOC_TYPE(cmd) != RTC_MAGIC)
+		return -ENOTTY;
+
+	if (_IOC_NR(cmd) > RTC_MAX_IOCTL)
+		return -ENOTTY;
+
+	switch (cmd) {
+		case RTC_RD_TIME:
+		{
+			struct rtc_time tm;
+
+			memset(&tm, 0, sizeof (struct rtc_time));
+			get_rtc_time(&tm);
+
+			if (copy_to_user((struct rtc_time *) arg, &tm, sizeof tm)) {
+				return -EFAULT;
+			}
+
+			return 0;
+		}
+
+		case RTC_SET_TIME:
+		{
+#ifdef CONFIG_ETRAX_RTC_READONLY
+			return -EPERM;
+#else
+			int leap;
+			int year;
+			int century;
+			struct rtc_time tm;
+
+			if (!capable(CAP_SYS_TIME))
+				return -EPERM;
+
+			if (copy_from_user(&tm, (struct rtc_time *) arg, sizeof tm))
+				return -EFAULT;
+
+			/* Convert from struct tm to struct rtc_time. */
+			tm.tm_year += 1900;
+			tm.tm_mon += 1;
+
+			/*
+			 * Check if tm.tm_year is a leap year. A year is a leap
+			 * year if it is divisible by 4 but not 100, except
+			 * that years divisible by 400 _are_ leap years.
+			 */
+			year = tm.tm_year;
+			leap = (tm.tm_mon == 2) && ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0);
+
+			/* Perform some sanity checks. */
+			if ((tm.tm_year < 1970) ||
+			    (tm.tm_mon > 12) ||
+			    (tm.tm_mday == 0) ||
+			    (tm.tm_mday > days_in_month[tm.tm_mon] + leap) ||
+			    (tm.tm_wday >= 7) ||
+			    (tm.tm_hour >= 24) ||
+			    (tm.tm_min >= 60) ||
+			    (tm.tm_sec >= 60))
+				return -EINVAL;
+
+			century = (tm.tm_year >= 2000) ? 0x80 : 0;
+			tm.tm_year = tm.tm_year % 100;
+
+			BIN_TO_BCD(tm.tm_year);
+			BIN_TO_BCD(tm.tm_mday);
+			BIN_TO_BCD(tm.tm_hour);
+			BIN_TO_BCD(tm.tm_min);
+			BIN_TO_BCD(tm.tm_sec);
+			tm.tm_mon |= century;
+
+			rtc_write(RTC_YEAR, tm.tm_year);
+			rtc_write(RTC_MONTH, tm.tm_mon);
+			rtc_write(RTC_WEEKDAY, tm.tm_wday); /* Not coded in BCD. */
+			rtc_write(RTC_DAY_OF_MONTH, tm.tm_mday);
+			rtc_write(RTC_HOURS, tm.tm_hour);
+			rtc_write(RTC_MINUTES, tm.tm_min);
+			rtc_write(RTC_SECONDS, tm.tm_sec);
+
+			return 0;
+#endif /* !CONFIG_ETRAX_RTC_READONLY */
+		}
+
+		case RTC_VLOW_RD:
+		{
+			int vl_bit = 0;
+
+			if (rtc_read(RTC_SECONDS) & 0x80) {
+				vl_bit = 1;
+				printk(KERN_WARNING "%s: RTC Voltage Low - reliable "
+				       "date/time information is no longer guaranteed!\n",
+				       PCF8563_NAME);
+			}
+			if (copy_to_user((int *) arg, &vl_bit, sizeof(int)))
+				return -EFAULT;
+
+			return 0;
+		}
+
+		case RTC_VLOW_SET:
+		{
+			/* Clear the VL bit in the seconds register */
+			int ret = rtc_read(RTC_SECONDS);
+
+			rtc_write(RTC_SECONDS, (ret & 0x7F));
+
+			return 0;
+		}
+
+		default:
+			return -ENOTTY;
+	}
+
+	return 0;
+}
+
+int
+pcf8563_open(struct inode *inode, struct file *filp)
+{
+	MOD_INC_USE_COUNT;
+	return 0;
+}
+
+int
+pcf8563_release(struct inode *inode, struct file *filp)
+{
+	MOD_DEC_USE_COUNT;
+	return 0;
+}
+
+module_init(pcf8563_init);
+module_exit(pcf8563_exit);
diff --git a/arch/cris/arch-v32/drivers/pci/Makefile b/arch/cris/arch-v32/drivers/pci/Makefile
new file mode 100644
--- /dev/null
+++ b/arch/cris/arch-v32/drivers/pci/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for Etrax cardbus driver
+#
+
+obj-$(CONFIG_ETRAX_CARDBUS)        += bios.o dma.o
diff --git a/arch/cris/arch-v32/drivers/pci/bios.c b/arch/cris/arch-v32/drivers/pci/bios.c
new file mode 100644
--- /dev/null
+++ b/arch/cris/arch-v32/drivers/pci/bios.c
@@ -0,0 +1,131 @@
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <asm/arch/hwregs/intr_vect.h>
+
+void __devinit  pcibios_fixup_bus(struct pci_bus *b)
+{
+}
+
+char * __devinit  pcibios_setup(char *str)
+{
+	return NULL;
+}
+
+void pcibios_set_master(struct pci_dev *dev)
+{
+	u8 lat;
+	pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
+	printk(KERN_DEBUG "PCI: Setting latency timer of device %s to %d\n", pci_name(dev), lat);
+	pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
+}
+
+int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
+			enum pci_mmap_state mmap_state, int write_combine)
+{
+	unsigned long prot;
+
+	/* Leave vm_pgoff as-is, the PCI space address is the physical
+	 * address on this platform.
+	 */
+	vma->vm_flags |= (VM_SHM | VM_LOCKED | VM_IO);
+
+	prot = pgprot_val(vma->vm_page_prot);
+	vma->vm_page_prot = __pgprot(prot);
+
+	/* Write-combine setting is ignored, it is changed via the mtrr
+	 * interfaces on this platform.
+	 */
+	if (remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
+			     vma->vm_end - vma->vm_start,
+			     vma->vm_page_prot))
+		return -EAGAIN;
+
+	return 0;
+}
+
+void
+pcibios_align_resource(void *data, struct resource *res,
+		       unsigned long size, unsigned long align)
+{
+	if (res->flags & IORESOURCE_IO) {
+		unsigned long start = res->start;
+
+		if (start & 0x300) {
+			start = (start + 0x3ff) & ~0x3ff;
+			res->start = start;
+		}
+	}
+}
+
+int pcibios_enable_resources(struct pci_dev *dev, int mask)
+{
+	u16 cmd, old_cmd;
+	int idx;
+	struct resource *r;
+
+	pci_read_config_word(dev, PCI_COMMAND, &cmd);
+	old_cmd = cmd;
+	for(idx=0; idx<6; idx++) {
+		/* Only set up the requested stuff */
+		if (!(mask & (1<<idx)))
+			continue;
+
+		r = &dev->resource[idx];
+		if (!r->start && r->end) {
+			printk(KERN_ERR "PCI: Device %s not available because of resource collisions\n", pci_name(dev));
+			return -EINVAL;
+		}
+		if (r->flags & IORESOURCE_IO)
+			cmd |= PCI_COMMAND_IO;
+		if (r->flags & IORESOURCE_MEM)
+			cmd |= PCI_COMMAND_MEMORY;
+	}
+	if (dev->resource[PCI_ROM_RESOURCE].start)
+		cmd |= PCI_COMMAND_MEMORY;
+	if (cmd != old_cmd) {
+		printk("PCI: Enabling device %s (%04x -> %04x)\n", pci_name(dev), old_cmd, cmd);
+		pci_write_config_word(dev, PCI_COMMAND, cmd);
+	}
+	return 0;
+}
+
+int pcibios_enable_irq(struct pci_dev *dev)
+{
+	dev->irq = EXT_INTR_VECT;
+	return 0;
+}
+
+int pcibios_enable_device(struct pci_dev *dev, int mask)
+{
+	int err;
+
+	if ((err = pcibios_enable_resources(dev, mask)) < 0)
+		return err;
+
+	return pcibios_enable_irq(dev);
+}
+
+int pcibios_assign_resources(void)
+{
+	struct pci_dev *dev = NULL;
+	int idx;
+	struct resource *r;
+
+	while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
+		int class = dev->class >> 8;
+
+		/* Don't touch classless devices and host bridges */
+		if (!class || class == PCI_CLASS_BRIDGE_HOST)
+			continue;
+
+		for(idx=0; idx<6; idx++) {
+			r = &dev->resource[idx];
+
+			if (!r->start && r->end)
+				pci_assign_resource(dev, idx);
+		}
+	}
+	return 0;
+}
+
+EXPORT_SYMBOL(pcibios_assign_resources);
diff --git a/arch/cris/arch-v32/drivers/pci/dma.c b/arch/cris/arch-v32/drivers/pci/dma.c
new file mode 100644
--- /dev/null
+++ b/arch/cris/arch-v32/drivers/pci/dma.c
@@ -0,0 +1,149 @@
+/*
+ * Dynamic DMA mapping support.
+ *
+ * On cris there is no hardware dynamic DMA address translation,
+ * so consistent alloc/free are merely page allocation/freeing.
+ * The rest of the dynamic DMA mapping interface is implemented
+ * in asm/pci.h.
+ *
+ * Borrowed from i386.
+ */
+
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/pci.h>
+#include <asm/io.h>
+
+struct dma_coherent_mem {
+	void		*virt_base;
+	u32		device_base;
+	int		size;
+	int		flags;
+	unsigned long	*bitmap;
+};
+
+void *dma_alloc_coherent(struct device *dev, size_t size,
+			   dma_addr_t *dma_handle, unsigned int __nocast gfp)
+{
+	void *ret;
+	struct dma_coherent_mem *mem = dev ? dev->dma_mem : NULL;
+	int order = get_order(size);
+	/* ignore region specifiers */
+	gfp &= ~(__GFP_DMA | __GFP_HIGHMEM);
+
+	if (mem) {
+		int page = bitmap_find_free_region(mem->bitmap, mem->size,
+						     order);
+		if (page >= 0) {
+			*dma_handle = mem->device_base + (page << PAGE_SHIFT);
+			ret = mem->virt_base + (page << PAGE_SHIFT);
+			memset(ret, 0, size);
+			return ret;
+		}
+		if (mem->flags & DMA_MEMORY_EXCLUSIVE)
+			return NULL;
+	}
+
+	if (dev == NULL || (dev->coherent_dma_mask < 0xffffffff))
+		gfp |= GFP_DMA;
+
+	ret = (void *)__get_free_pages(gfp, order);
+
+	if (ret != NULL) {
+		memset(ret, 0, size);
+		*dma_handle = virt_to_phys(ret);
+	}
+	return ret;
+}
+
+void dma_free_coherent(struct device *dev, size_t size,
+			 void *vaddr, dma_addr_t dma_handle)
+{
+	struct dma_coherent_mem *mem = dev ? dev->dma_mem : NULL;
+	int order = get_order(size);
+
+	if (mem && vaddr >= mem->virt_base && vaddr < (mem->virt_base + (mem->size << PAGE_SHIFT))) {
+		int page = (vaddr - mem->virt_base) >> PAGE_SHIFT;
+
+		bitmap_release_region(mem->bitmap, page, order);
+	} else
+		free_pages((unsigned long)vaddr, order);
+}
+
+int dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr,
+				dma_addr_t device_addr, size_t size, int flags)
+{
+	void __iomem *mem_base;
+	int pages = size >> PAGE_SHIFT;
+	int bitmap_size = (pages + 31)/32;
+
+	if ((flags & (DMA_MEMORY_MAP | DMA_MEMORY_IO)) == 0)
+		goto out;
+	if (!size)
+		goto out;
+	if (dev->dma_mem)
+		goto out;
+
+	/* FIXME: this routine just ignores DMA_MEMORY_INCLUDES_CHILDREN */
+
+	mem_base = ioremap(bus_addr, size);
+	if (!mem_base)
+		goto out;
+
+	dev->dma_mem = kmalloc(sizeof(struct dma_coherent_mem), GFP_KERNEL);
+	if (!dev->dma_mem)
+		goto out;
+	memset(dev->dma_mem, 0, sizeof(struct dma_coherent_mem));
+	dev->dma_mem->bitmap = kmalloc(bitmap_size, GFP_KERNEL);
+	if (!dev->dma_mem->bitmap)
+		goto free1_out;
+	memset(dev->dma_mem->bitmap, 0, bitmap_size);
+
+	dev->dma_mem->virt_base = mem_base;
+	dev->dma_mem->device_base = device_addr;
+	dev->dma_mem->size = pages;
+	dev->dma_mem->flags = flags;
+
+	if (flags & DMA_MEMORY_MAP)
+		return DMA_MEMORY_MAP;
+
+	return DMA_MEMORY_IO;
+
+ free1_out:
+	kfree(dev->dma_mem->bitmap);
+ out:
+	return 0;
+}
+EXPORT_SYMBOL(dma_declare_coherent_memory);
+
+void dma_release_declared_memory(struct device *dev)
+{
+	struct dma_coherent_mem *mem = dev->dma_mem;
+
+	if(!mem)
+		return;
+	dev->dma_mem = NULL;
+	iounmap(mem->virt_base);
+	kfree(mem->bitmap);
+	kfree(mem);
+}
+EXPORT_SYMBOL(dma_release_declared_memory);
+
+void *dma_mark_declared_memory_occupied(struct device *dev,
+					dma_addr_t device_addr, size_t size)
+{
+	struct dma_coherent_mem *mem = dev->dma_mem;
+	int pages = (size + (device_addr & ~PAGE_MASK) + PAGE_SIZE - 1) >> PAGE_SHIFT;
+	int pos, err;
+
+	if (!mem)
+		return ERR_PTR(-EINVAL);
+
+	pos = (device_addr - mem->device_base) >> PAGE_SHIFT;
+	err = bitmap_allocate_region(mem->bitmap, pos, get_order(pages));
+	if (err != 0)
+		return ERR_PTR(err);
+	return mem->virt_base + (pos << PAGE_SHIFT);
+}
+EXPORT_SYMBOL(dma_mark_declared_memory_occupied);
diff --git a/arch/cris/arch-v32/drivers/sync_serial.c b/arch/cris/arch-v32/drivers/sync_serial.c
new file mode 100644
--- /dev/null
+++ b/arch/cris/arch-v32/drivers/sync_serial.c
@@ -0,0 +1,1283 @@
+/*
+ * Simple synchronous serial port driver for ETRAX FS.
+ *
+ * Copyright (c) 2005 Axis Communications AB
+ *
+ * Author: Mikael Starvik
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/major.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/poll.h>
+#include <linux/init.h>
+#include <linux/timer.h>
+#include <linux/spinlock.h>
+
+#include <asm/io.h>
+#include <asm/arch/dma.h>
+#include <asm/arch/pinmux.h>
+#include <asm/arch/hwregs/reg_rdwr.h>
+#include <asm/arch/hwregs/sser_defs.h>
+#include <asm/arch/hwregs/dma_defs.h>
+#include <asm/arch/hwregs/dma.h>
+#include <asm/arch/hwregs/intr_vect_defs.h>
+#include <asm/arch/hwregs/intr_vect.h>
+#include <asm/arch/hwregs/reg_map.h>
+#include <asm/sync_serial.h>
+
+/* The receiver is a bit tricky beacuse of the continuous stream of data.*/
+/*                                                                       */
+/* Three DMA descriptors are linked together. Each DMA descriptor is     */
+/* responsible for port->bufchunk of a common buffer.                    */
+/*                                                                       */
+/* +---------------------------------------------+                       */
+/* |   +----------+   +----------+   +----------+ |                      */
+/* +-> | Descr[0] |-->| Descr[1] |-->| Descr[2] |-+                      */
+/*     +----------+   +----------+   +----------+                        */
+/*         |            |              |                                 */
+/*         v            v              v                                 */
+/*   +-------------------------------------+                             */
+/*   |        BUFFER                       |                             */
+/*   +-------------------------------------+                             */
+/*      |<- data_avail ->|                                               */
+/*    readp          writep                                              */
+/*                                                                       */
+/* If the application keeps up the pace readp will be right after writep.*/
+/* If the application can't keep the pace we have to throw away data.    */
+/* The idea is that readp should be ready with the data pointed out by	 */
+/* Descr[i] when the DMA has filled in Descr[i+1].                       */
+/* Otherwise we will discard	                                         */
+/* the rest of the data pointed out by Descr1 and set readp to the start */
+/* of Descr2                                                             */
+
+#define SYNC_SERIAL_MAJOR 125
+
+/* IN_BUFFER_SIZE should be a multiple of 6 to make sure that 24 bit */
+/* words can be handled */
+#define IN_BUFFER_SIZE 12288
+#define IN_DESCR_SIZE 256
+#define NUM_IN_DESCR (IN_BUFFER_SIZE/IN_DESCR_SIZE)
+#define OUT_BUFFER_SIZE 4096
+
+#define DEFAULT_FRAME_RATE 0
+#define DEFAULT_WORD_RATE 7
+
+/* NOTE: Enabling some debug will likely cause overrun or underrun,
+ * especially if manual mode is use.
+ */
+#define DEBUG(x)
+#define DEBUGREAD(x)
+#define DEBUGWRITE(x)
+#define DEBUGPOLL(x)
+#define DEBUGRXINT(x)
+#define DEBUGTXINT(x)
+
+typedef struct sync_port
+{
+	reg_scope_instances regi_sser;
+	reg_scope_instances regi_dmain;
+	reg_scope_instances regi_dmaout;
+
+	char started; /* 1 if port has been started */
+	char port_nbr; /* Port 0 or 1 */
+	char busy; /* 1 if port is busy */
+
+	char enabled;  /* 1 if port is enabled */
+	char use_dma;  /* 1 if port uses dma */
+	char tr_running;
+
+	char init_irqs;
+	int output;
+	int input;
+
+	volatile unsigned int out_count; /* Remaining bytes for current transfer */
+	unsigned char* outp; /* Current position in out_buffer */
+	volatile unsigned char* volatile readp;  /* Next byte to be read by application */
+	volatile unsigned char* volatile writep; /* Next byte to be written by etrax */
+	unsigned int in_buffer_size;
+	unsigned int inbufchunk;
+	unsigned char out_buffer[OUT_BUFFER_SIZE] __attribute__ ((aligned(32)));
+	unsigned char in_buffer[IN_BUFFER_SIZE]__attribute__ ((aligned(32)));
+	unsigned char flip[IN_BUFFER_SIZE] __attribute__ ((aligned(32)));
+	struct dma_descr_data* next_rx_desc;
+	struct dma_descr_data* prev_rx_desc;
+	int full;
+
+	dma_descr_data in_descr[NUM_IN_DESCR] __attribute__ ((__aligned__(16)));
+	dma_descr_context in_context __attribute__ ((__aligned__(32)));
+	dma_descr_data out_descr __attribute__ ((__aligned__(16)));
+	dma_descr_context out_context __attribute__ ((__aligned__(32)));
+	wait_queue_head_t out_wait_q;
+	wait_queue_head_t in_wait_q;
+
+	spinlock_t lock;
+} sync_port;
+
+static int etrax_sync_serial_init(void);
+static void initialize_port(int portnbr);
+static inline int sync_data_avail(struct sync_port *port);
+
+static int sync_serial_open(struct inode *, struct file*);
+static int sync_serial_release(struct inode*, struct file*);
+static unsigned int sync_serial_poll(struct file *filp, poll_table *wait);
+
+static int sync_serial_ioctl(struct inode*, struct file*,
+			     unsigned int cmd, unsigned long arg);
+static ssize_t sync_serial_write(struct file * file, const char * buf,
+				 size_t count, loff_t *ppos);
+static ssize_t sync_serial_read(struct file *file, char *buf,
+				size_t count, loff_t *ppos);
+
+#if (defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT0) && \
+     defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL0_DMA)) || \
+    (defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT1) && \
+     defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL1_DMA))
+#define SYNC_SER_DMA
+#endif
+
+static void send_word(sync_port* port);
+static void start_dma(struct sync_port *port, const char* data, int count);
+static void start_dma_in(sync_port* port);
+#ifdef SYNC_SER_DMA
+static irqreturn_t tr_interrupt(int irq, void *dev_id, struct pt_regs * regs);
+static irqreturn_t rx_interrupt(int irq, void *dev_id, struct pt_regs * regs);
+#endif
+
+#if (defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT0) && \
+     !defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL0_DMA)) || \
+    (defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT1) && \
+     !defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL1_DMA))
+#define SYNC_SER_MANUAL
+#endif
+#ifdef SYNC_SER_MANUAL
+static irqreturn_t manual_interrupt(int irq, void *dev_id, struct pt_regs * regs);
+#endif
+
+/* The ports */
+static struct sync_port ports[]=
+{
+	{
+		.regi_sser             = regi_sser0,
+		.regi_dmaout           = regi_dma4,
+		.regi_dmain            = regi_dma5,
+#if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL0_DMA)
+                .use_dma               = 1,
+#else
+                .use_dma               = 0,
+#endif
+	},
+	{
+		.regi_sser             = regi_sser1,
+		.regi_dmaout           = regi_dma6,
+		.regi_dmain            = regi_dma7,
+#if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL1_DMA)
+                .use_dma               = 1,
+#else
+                .use_dma               = 0,
+#endif
+	}
+};
+
+#define NUMBER_OF_PORTS (sizeof(ports)/sizeof(sync_port))
+
+static struct file_operations sync_serial_fops = {
+	.owner   = THIS_MODULE,
+	.write   = sync_serial_write,
+	.read    = sync_serial_read,
+	.poll    = sync_serial_poll,
+	.ioctl   = sync_serial_ioctl,
+	.open    = sync_serial_open,
+	.release = sync_serial_release
+};
+
+static int __init etrax_sync_serial_init(void)
+{
+	ports[0].enabled = 0;
+	ports[1].enabled = 0;
+
+	if (register_chrdev(SYNC_SERIAL_MAJOR,"sync serial", &sync_serial_fops) <0 )
+	{
+		printk("unable to get major for synchronous serial port\n");
+		return -EBUSY;
+	}
+
+	/* Initialize Ports */
+#if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT0)
+	if (crisv32_pinmux_alloc_fixed(pinmux_sser0))
+	{
+		printk("Unable to allocate pins for syncrhronous serial port 0\n");
+		return -EIO;
+	}
+	ports[0].enabled = 1;
+	initialize_port(0);
+#endif
+
+#if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT1)
+	if (crisv32_pinmux_alloc_fixed(pinmux_sser1))
+	{
+		printk("Unable to allocate pins for syncrhronous serial port 0\n");
+		return -EIO;
+	}
+	ports[1].enabled = 1;
+	initialize_port(1);
+#endif
+
+	printk("ETRAX FS synchronous serial port driver\n");
+	return 0;
+}
+
+static void __init initialize_port(int portnbr)
+{
+	struct sync_port* port = &ports[portnbr];
+	reg_sser_rw_cfg cfg = {0};
+	reg_sser_rw_frm_cfg frm_cfg = {0};
+	reg_sser_rw_tr_cfg tr_cfg = {0};
+	reg_sser_rw_rec_cfg rec_cfg = {0};
+
+	DEBUG(printk("Init sync serial port %d\n", portnbr));
+
+	port->port_nbr = portnbr;
+	port->init_irqs = 1;
+
+	port->outp = port->out_buffer;
+	port->output = 1;
+	port->input = 0;
+
+	port->readp = port->flip;
+	port->writep = port->flip;
+	port->in_buffer_size = IN_BUFFER_SIZE;
+	port->inbufchunk = IN_DESCR_SIZE;
+	port->next_rx_desc = &port->in_descr[0];
+	port->prev_rx_desc = &port->in_descr[NUM_IN_DESCR-1];
+	port->prev_rx_desc->eol = 1;
+
+	init_waitqueue_head(&port->out_wait_q);
+	init_waitqueue_head(&port->in_wait_q);
+
+	spin_lock_init(&port->lock);
+
+	cfg.out_clk_src = regk_sser_intern_clk;
+	cfg.out_clk_pol = regk_sser_pos;
+	cfg.clk_od_mode = regk_sser_no;
+	cfg.clk_dir = regk_sser_out;
+	cfg.gate_clk = regk_sser_no;
+	cfg.base_freq = regk_sser_f29_493;
+	cfg.clk_div = 256;
+	REG_WR(sser, port->regi_sser, rw_cfg, cfg);
+
+	frm_cfg.wordrate = DEFAULT_WORD_RATE;
+	frm_cfg.type = regk_sser_edge;
+	frm_cfg.frame_pin_dir = regk_sser_out;
+	frm_cfg.frame_pin_use = regk_sser_frm;
+	frm_cfg.status_pin_dir = regk_sser_in;
+	frm_cfg.status_pin_use = regk_sser_hold;
+	frm_cfg.out_on = regk_sser_tr;
+	frm_cfg.tr_delay = 1;
+	REG_WR(sser, port->regi_sser, rw_frm_cfg, frm_cfg);
+
+	tr_cfg.urun_stop = regk_sser_no;
+	tr_cfg.sample_size = 7;
+	tr_cfg.sh_dir = regk_sser_msbfirst;
+	tr_cfg.use_dma = port->use_dma ? regk_sser_yes : regk_sser_no;
+	tr_cfg.rate_ctrl = regk_sser_bulk;
+	tr_cfg.data_pin_use = regk_sser_dout;
+	tr_cfg.bulk_wspace = 1;
+	REG_WR(sser, port->regi_sser, rw_tr_cfg, tr_cfg);
+
+	rec_cfg.sample_size = 7;
+	rec_cfg.sh_dir = regk_sser_msbfirst;
+	rec_cfg.use_dma = port->use_dma ? regk_sser_yes : regk_sser_no;
+	rec_cfg.fifo_thr = regk_sser_inf;
+	REG_WR(sser, port->regi_sser, rw_rec_cfg, rec_cfg);
+}
+
+static inline int sync_data_avail(struct sync_port *port)
+{
+	int avail;
+	unsigned char *start;
+	unsigned char *end;
+
+	start = (unsigned char*)port->readp; /* cast away volatile */
+	end = (unsigned char*)port->writep;  /* cast away volatile */
+	/* 0123456789  0123456789
+	 *  -----      -    -----
+	 *  ^rp  ^wp    ^wp ^rp
+	 */
+
+  	if (end >= start)
+		avail = end - start;
+	else
+		avail = port->in_buffer_size - (start - end);
+	return avail;
+}
+
+static inline int sync_data_avail_to_end(struct sync_port *port)
+{
+	int avail;
+	unsigned char *start;
+	unsigned char *end;
+
+	start = (unsigned char*)port->readp; /* cast away volatile */
+	end = (unsigned char*)port->writep;  /* cast away volatile */
+	/* 0123456789  0123456789
+	 *  -----           -----
+	 *  ^rp  ^wp    ^wp ^rp
+	 */
+
+  	if (end >= start)
+		avail = end - start;
+	else
+		avail = port->flip + port->in_buffer_size - start;
+	return avail;
+}
+
+static int sync_serial_open(struct inode *inode, struct file *file)
+{
+	int dev = MINOR(inode->i_rdev);
+	sync_port* port;
+	reg_dma_rw_cfg cfg = {.en = regk_dma_yes};
+	reg_dma_rw_intr_mask intr_mask = {.data = regk_dma_yes};
+
+	DEBUG(printk("Open sync serial port %d\n", dev));
+
+	if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled)
+	{
+		DEBUG(printk("Invalid minor %d\n", dev));
+		return -ENODEV;
+	}
+	port = &ports[dev];
+	/* Allow open this device twice (assuming one reader and one writer) */
+	if (port->busy == 2)
+	{
+		DEBUG(printk("Device is busy.. \n"));
+		return -EBUSY;
+	}
+	if (port->init_irqs) {
+		if (port->use_dma) {
+			if (port == &ports[0]){
+#ifdef SYNC_SER_DMA
+				if(request_irq(DMA4_INTR_VECT,
+					       tr_interrupt,
+					       0,
+					       "synchronous serial 0 dma tr",
+					       &ports[0])) {
+					printk(KERN_CRIT "Can't allocate sync serial port 0 IRQ");
+					return -EBUSY;
+				} else if(request_irq(DMA5_INTR_VECT,
+						      rx_interrupt,
+						      0,
+						      "synchronous serial 1 dma rx",
+						      &ports[0])) {
+					free_irq(DMA4_INTR_VECT, &port[0]);
+					printk(KERN_CRIT "Can't allocate sync serial port 0 IRQ");
+					return -EBUSY;
+				} else if (crisv32_request_dma(SYNC_SER0_TX_DMA_NBR,
+                                                               "synchronous serial 0 dma tr",
+                                                               DMA_VERBOSE_ON_ERROR,
+                                                               0,
+                                                               dma_sser0)) {
+					free_irq(DMA4_INTR_VECT, &port[0]);
+					free_irq(DMA5_INTR_VECT, &port[0]);
+					printk(KERN_CRIT "Can't allocate sync serial port 0 TX DMA channel");
+					return -EBUSY;
+				} else if (crisv32_request_dma(SYNC_SER0_RX_DMA_NBR,
+                                                               "synchronous serial 0 dma rec",
+                                                               DMA_VERBOSE_ON_ERROR,
+                                                               0,
+                                                               dma_sser0)) {
+					crisv32_free_dma(SYNC_SER0_TX_DMA_NBR);
+					free_irq(DMA4_INTR_VECT, &port[0]);
+					free_irq(DMA5_INTR_VECT, &port[0]);
+					printk(KERN_CRIT "Can't allocate sync serial port 1 RX DMA channel");
+					return -EBUSY;
+				}
+#endif
+			}
+			else if (port == &ports[1]){
+#ifdef SYNC_SER_DMA
+				if (request_irq(DMA6_INTR_VECT,
+						tr_interrupt,
+						0,
+						"synchronous serial 1 dma tr",
+						&ports[1])) {
+					printk(KERN_CRIT "Can't allocate sync serial port 1 IRQ");
+					return -EBUSY;
+				} else if (request_irq(DMA7_INTR_VECT,
+						       rx_interrupt,
+						       0,
+						       "synchronous serial 1 dma rx",
+						       &ports[1])) {
+					free_irq(DMA6_INTR_VECT, &ports[1]);
+					printk(KERN_CRIT "Can't allocate sync serial port 3 IRQ");
+					return -EBUSY;
+				} else if (crisv32_request_dma(SYNC_SER1_TX_DMA_NBR,
+                                                               "synchronous serial 1 dma tr",
+                                                               DMA_VERBOSE_ON_ERROR,
+                                                               0,
+                                                               dma_sser1)) {
+					free_irq(21, &ports[1]);
+					free_irq(20, &ports[1]);
+					printk(KERN_CRIT "Can't allocate sync serial port 3 TX DMA channel");
+					return -EBUSY;
+				} else if (crisv32_request_dma(SYNC_SER1_RX_DMA_NBR,
+							    "synchronous serial 3 dma rec",
+							    DMA_VERBOSE_ON_ERROR,
+							    0,
+							    dma_sser1)) {
+					crisv32_free_dma(SYNC_SER1_TX_DMA_NBR);
+					free_irq(DMA6_INTR_VECT, &ports[1]);
+					free_irq(DMA7_INTR_VECT, &ports[1]);
+					printk(KERN_CRIT "Can't allocate sync serial port 3 RX DMA channel");
+					return -EBUSY;
+				}
+#endif
+			}
+
+                        /* Enable DMAs */
+			REG_WR(dma, port->regi_dmain, rw_cfg, cfg);
+			REG_WR(dma, port->regi_dmaout, rw_cfg, cfg);
+			/* Enable DMA IRQs */
+			REG_WR(dma, port->regi_dmain, rw_intr_mask, intr_mask);
+			REG_WR(dma, port->regi_dmaout, rw_intr_mask, intr_mask);
+			/* Set up wordsize = 2 for DMAs. */
+			DMA_WR_CMD (port->regi_dmain, regk_dma_set_w_size1);
+			DMA_WR_CMD (port->regi_dmaout, regk_dma_set_w_size1);
+
+			start_dma_in(port);
+			port->init_irqs = 0;
+		} else { /* !port->use_dma */
+#ifdef SYNC_SER_MANUAL
+			if (port == &ports[0]) {
+				if (request_irq(SSER0_INTR_VECT,
+						manual_interrupt,
+						0,
+						"synchronous serial manual irq",
+						&ports[0])) {
+					printk("Can't allocate sync serial manual irq");
+					return -EBUSY;
+				}
+			} else if (port == &ports[1]) {
+				if (request_irq(SSER1_INTR_VECT,
+						manual_interrupt,
+						0,
+						"synchronous serial manual irq",
+						&ports[1])) {
+					printk(KERN_CRIT "Can't allocate sync serial manual irq");
+					return -EBUSY;
+				}
+			}
+			port->init_irqs = 0;
+#else
+			panic("sync_serial: Manual mode not supported.\n");
+#endif /* SYNC_SER_MANUAL */
+		}
+	} /* port->init_irqs */
+
+	port->busy++;
+	return 0;
+}
+
+static int sync_serial_release(struct inode *inode, struct file *file)
+{
+	int dev = MINOR(inode->i_rdev);
+	sync_port* port;
+
+	if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled)
+	{
+		DEBUG(printk("Invalid minor %d\n", dev));
+		return -ENODEV;
+	}
+	port = &ports[dev];
+	if (port->busy)
+		port->busy--;
+	if (!port->busy)
+          /* XXX */ ;
+	return 0;
+}
+
+static unsigned int sync_serial_poll(struct file *file, poll_table *wait)
+{
+	int dev = MINOR(file->f_dentry->d_inode->i_rdev);
+	unsigned int mask = 0;
+	sync_port* port;
+	DEBUGPOLL( static unsigned int prev_mask = 0; );
+
+	port = &ports[dev];
+	poll_wait(file, &port->out_wait_q, wait);
+	poll_wait(file, &port->in_wait_q, wait);
+	/* Some room to write */
+	if (port->out_count < OUT_BUFFER_SIZE)
+		mask |=  POLLOUT | POLLWRNORM;
+	/* At least an inbufchunk of data */
+	if (sync_data_avail(port) >= port->inbufchunk)
+		mask |= POLLIN | POLLRDNORM;
+
+	DEBUGPOLL(if (mask != prev_mask)
+	      printk("sync_serial_poll: mask 0x%08X %s %s\n", mask,
+		     mask&POLLOUT?"POLLOUT":"", mask&POLLIN?"POLLIN":"");
+	      prev_mask = mask;
+	      );
+	return mask;
+}
+
+static int sync_serial_ioctl(struct inode *inode, struct file *file,
+		  unsigned int cmd, unsigned long arg)
+{
+	int return_val = 0;
+	int dev = MINOR(file->f_dentry->d_inode->i_rdev);
+	sync_port* port;
+	reg_sser_rw_tr_cfg tr_cfg;
+	reg_sser_rw_rec_cfg rec_cfg;
+	reg_sser_rw_frm_cfg frm_cfg;
+	reg_sser_rw_cfg gen_cfg;
+	reg_sser_rw_intr_mask intr_mask;
+
+	if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled)
+	{
+		DEBUG(printk("Invalid minor %d\n", dev));
+		return -1;
+	}
+        port = &ports[dev];
+	spin_lock_irq(&port->lock);
+
+	tr_cfg = REG_RD(sser, port->regi_sser, rw_tr_cfg);
+	rec_cfg = REG_RD(sser, port->regi_sser, rw_rec_cfg);
+	frm_cfg = REG_RD(sser, port->regi_sser, rw_frm_cfg);
+	gen_cfg = REG_RD(sser, port->regi_sser, rw_cfg);
+	intr_mask = REG_RD(sser, port->regi_sser, rw_intr_mask);
+
+	switch(cmd)
+	{
+	case SSP_SPEED:
+		if (GET_SPEED(arg) == CODEC)
+		{
+			gen_cfg.base_freq = regk_sser_f32;
+			/* FREQ = 0 => 4 MHz => clk_div = 7*/
+			gen_cfg.clk_div = 6 + (1 << GET_FREQ(arg));
+		}
+		else
+		{
+			gen_cfg.base_freq = regk_sser_f29_493;
+			switch (GET_SPEED(arg))
+			{
+				case SSP150:
+					gen_cfg.clk_div = 29493000 / (150 * 8) - 1;
+					break;
+				case SSP300:
+					gen_cfg.clk_div = 29493000 / (300 * 8) - 1;
+					break;
+				case SSP600:
+					gen_cfg.clk_div = 29493000 / (600 * 8) - 1;
+					break;
+				case SSP1200:
+					gen_cfg.clk_div = 29493000 / (1200 * 8) - 1;
+					break;
+				case SSP2400:
+					gen_cfg.clk_div = 29493000 / (2400 * 8) - 1;
+					break;
+				case SSP4800:
+					gen_cfg.clk_div = 29493000 / (4800 * 8) - 1;
+					break;
+				case SSP9600:
+					gen_cfg.clk_div = 29493000 / (9600 * 8) - 1;
+					break;
+				case SSP19200:
+					gen_cfg.clk_div = 29493000 / (19200 * 8) - 1;
+					break;
+				case SSP28800:
+					gen_cfg.clk_div = 29493000 / (28800 * 8) - 1;
+					break;
+				case SSP57600:
+					gen_cfg.clk_div = 29493000 / (57600 * 8) - 1;
+					break;
+				case SSP115200:
+					gen_cfg.clk_div = 29493000 / (115200 * 8) - 1;
+					break;
+				case SSP230400:
+					gen_cfg.clk_div = 29493000 / (230400 * 8) - 1;
+					break;
+				case SSP460800:
+					gen_cfg.clk_div = 29493000 / (460800 * 8) - 1;
+					break;
+				case SSP921600:
+					gen_cfg.clk_div = 29493000 / (921600 * 8) - 1;
+					break;
+				case SSP3125000:
+					gen_cfg.base_freq = regk_sser_f100;
+					gen_cfg.clk_div = 100000000 / (3125000 * 8) - 1;
+					break;
+
+			}
+		}
+		frm_cfg.wordrate = GET_WORD_RATE(arg);
+
+		break;
+	case SSP_MODE:
+		switch(arg)
+		{
+			case MASTER_OUTPUT:
+				port->output = 1;
+				port->input = 0;
+				gen_cfg.clk_dir = regk_sser_out;
+				break;
+			case SLAVE_OUTPUT:
+				port->output = 1;
+				port->input = 0;
+				gen_cfg.clk_dir = regk_sser_in;
+				break;
+			case MASTER_INPUT:
+				port->output = 0;
+				port->input = 1;
+				gen_cfg.clk_dir = regk_sser_out;
+				break;
+			case SLAVE_INPUT:
+				port->output = 0;
+				port->input = 1;
+				gen_cfg.clk_dir = regk_sser_in;
+				break;
+			case MASTER_BIDIR:
+				port->output = 1;
+				port->input = 1;
+				gen_cfg.clk_dir = regk_sser_out;
+				break;
+			case SLAVE_BIDIR:
+				port->output = 1;
+				port->input = 1;
+				gen_cfg.clk_dir = regk_sser_in;
+				break;
+			default:
+				spin_unlock_irq(&port->lock);
+				return -EINVAL;
+
+		}
+		if (!port->use_dma || (arg == MASTER_OUTPUT || arg == SLAVE_OUTPUT))
+			intr_mask.rdav = regk_sser_yes;
+		break;
+	case SSP_FRAME_SYNC:
+		if (arg & NORMAL_SYNC)
+			frm_cfg.tr_delay = 1;
+		else if (arg & EARLY_SYNC)
+			frm_cfg.tr_delay = 0;
+
+		tr_cfg.bulk_wspace = frm_cfg.tr_delay;
+		frm_cfg.early_wend = regk_sser_yes;
+		if (arg & BIT_SYNC)
+			frm_cfg.type = regk_sser_edge;
+		else if (arg & WORD_SYNC)
+			frm_cfg.type = regk_sser_level;
+		else if (arg & EXTENDED_SYNC)
+			frm_cfg.early_wend = regk_sser_no;
+
+		if (arg & SYNC_ON)
+			frm_cfg.frame_pin_use = regk_sser_frm;
+		else if (arg & SYNC_OFF)
+			frm_cfg.frame_pin_use = regk_sser_gio0;
+
+		if (arg & WORD_SIZE_8)
+			rec_cfg.sample_size = tr_cfg.sample_size = 7;
+		else if (arg & WORD_SIZE_12)
+			rec_cfg.sample_size = tr_cfg.sample_size = 11;
+		else if (arg & WORD_SIZE_16)
+			rec_cfg.sample_size = tr_cfg.sample_size = 15;
+		else if (arg & WORD_SIZE_24)
+			rec_cfg.sample_size = tr_cfg.sample_size = 23;
+		else if (arg & WORD_SIZE_32)
+			rec_cfg.sample_size = tr_cfg.sample_size = 31;
+
+		if (arg & BIT_ORDER_MSB)
+			rec_cfg.sh_dir = tr_cfg.sh_dir = regk_sser_msbfirst;
+		else if (arg & BIT_ORDER_LSB)
+			rec_cfg.sh_dir = tr_cfg.sh_dir = regk_sser_lsbfirst;
+
+		if (arg & FLOW_CONTROL_ENABLE)
+			rec_cfg.fifo_thr = regk_sser_thr16;
+		else if (arg & FLOW_CONTROL_DISABLE)
+			rec_cfg.fifo_thr = regk_sser_inf;
+
+		if (arg & CLOCK_NOT_GATED)
+			gen_cfg.gate_clk = regk_sser_no;
+		else if (arg & CLOCK_GATED)
+			gen_cfg.gate_clk = regk_sser_yes;
+
+		break;
+	case SSP_IPOLARITY:
+		/* NOTE!! negedge is considered NORMAL */
+		if (arg & CLOCK_NORMAL)
+			rec_cfg.clk_pol = regk_sser_neg;
+		else if (arg & CLOCK_INVERT)
+			rec_cfg.clk_pol = regk_sser_pos;
+
+		if (arg & FRAME_NORMAL)
+			frm_cfg.level = regk_sser_pos_hi;
+		else if (arg & FRAME_INVERT)
+			frm_cfg.level = regk_sser_neg_lo;
+
+		if (arg & STATUS_NORMAL)
+			gen_cfg.hold_pol = regk_sser_pos;
+		else if (arg & STATUS_INVERT)
+			gen_cfg.hold_pol = regk_sser_neg;
+		break;
+	case SSP_OPOLARITY:
+		if (arg & CLOCK_NORMAL)
+			gen_cfg.out_clk_pol = regk_sser_neg;
+		else if (arg & CLOCK_INVERT)
+			gen_cfg.out_clk_pol = regk_sser_pos;
+
+		if (arg & FRAME_NORMAL)
+			frm_cfg.level = regk_sser_pos_hi;
+		else if (arg & FRAME_INVERT)
+			frm_cfg.level = regk_sser_neg_lo;
+
+		if (arg & STATUS_NORMAL)
+			gen_cfg.hold_pol = regk_sser_pos;
+		else if (arg & STATUS_INVERT)
+			gen_cfg.hold_pol = regk_sser_neg;
+		break;
+	case SSP_SPI:
+		rec_cfg.fifo_thr = regk_sser_inf;
+		rec_cfg.sh_dir = tr_cfg.sh_dir = regk_sser_msbfirst;
+		rec_cfg.sample_size = tr_cfg.sample_size = 7;
+		frm_cfg.frame_pin_use = regk_sser_frm;
+		frm_cfg.type = regk_sser_level;
+		frm_cfg.tr_delay = 1;
+		frm_cfg.level = regk_sser_neg_lo;
+		if (arg & SPI_SLAVE)
+		{
+			rec_cfg.clk_pol = regk_sser_neg;
+			gen_cfg.clk_dir = regk_sser_in;
+			port->input = 1;
+			port->output = 0;
+		}
+		else
+		{
+			gen_cfg.out_clk_pol = regk_sser_pos;
+			port->input = 0;
+			port->output = 1;
+			gen_cfg.clk_dir = regk_sser_out;
+		}
+		break;
+	case SSP_INBUFCHUNK:
+		break;
+	default:
+		return_val = -1;
+	}
+
+
+	if (port->started)
+	{
+		tr_cfg.tr_en = port->output;
+		rec_cfg.rec_en = port->input;
+	}
+
+	REG_WR(sser, port->regi_sser, rw_tr_cfg, tr_cfg);
+	REG_WR(sser, port->regi_sser, rw_rec_cfg, rec_cfg);
+	REG_WR(sser, port->regi_sser, rw_frm_cfg, frm_cfg);
+	REG_WR(sser, port->regi_sser, rw_intr_mask, intr_mask);
+	REG_WR(sser, port->regi_sser, rw_cfg, gen_cfg);
+
+	spin_unlock_irq(&port->lock);
+	return return_val;
+}
+
+static ssize_t sync_serial_write(struct file * file, const char * buf,
+                                 size_t count, loff_t *ppos)
+{
+	int dev = MINOR(file->f_dentry->d_inode->i_rdev);
+	DECLARE_WAITQUEUE(wait, current);
+	sync_port *port;
+	unsigned long c, c1;
+	unsigned long free_outp;
+	unsigned long outp;
+	unsigned long out_buffer;
+	unsigned long flags;
+
+	if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled)
+	{
+		DEBUG(printk("Invalid minor %d\n", dev));
+		return -ENODEV;
+	}
+	port = &ports[dev];
+
+	DEBUGWRITE(printk("W d%d c %lu (%d/%d)\n", port->port_nbr, count, port->out_count, OUT_BUFFER_SIZE));
+	/* Space to end of buffer */
+	/*
+	 * out_buffer <c1>012345<-   c    ->OUT_BUFFER_SIZE
+	 *            outp^    +out_count
+	                        ^free_outp
+	 * out_buffer 45<-     c      ->0123OUT_BUFFER_SIZE
+	 *             +out_count   outp^
+	 *              free_outp
+	 *
+	 */
+
+	/* Read variables that may be updated by interrupts */
+	spin_lock_irqsave(&port->lock, flags);
+	count = count > OUT_BUFFER_SIZE - port->out_count ? OUT_BUFFER_SIZE  - port->out_count : count;
+	outp = (unsigned long)port->outp;
+	free_outp = outp + port->out_count;
+	spin_unlock_irqrestore(&port->lock, flags);
+	out_buffer = (unsigned long)port->out_buffer;
+
+	/* Find out where and how much to write */
+	if (free_outp >= out_buffer + OUT_BUFFER_SIZE)
+		free_outp -= OUT_BUFFER_SIZE;
+	if (free_outp >= outp)
+		c = out_buffer + OUT_BUFFER_SIZE - free_outp;
+	else
+		c = outp - free_outp;
+	if (c > count)
+		c = count;
+
+//	DEBUGWRITE(printk("w op %08lX fop %08lX c %lu\n", outp, free_outp, c));
+	if (copy_from_user((void*)free_outp, buf, c))
+		return -EFAULT;
+
+	if (c != count) {
+		buf += c;
+		c1 = count - c;
+		DEBUGWRITE(printk("w2 fi %lu c %lu c1 %lu\n", free_outp-out_buffer, c, c1));
+		if (copy_from_user((void*)out_buffer, buf, c1))
+			return -EFAULT;
+	}
+	spin_lock_irqsave(&port->lock, flags);
+	port->out_count += count;
+	spin_unlock_irqrestore(&port->lock, flags);
+
+	/* Make sure transmitter/receiver is running */
+	if (!port->started)
+	{
+		reg_sser_rw_cfg cfg = REG_RD(sser, port->regi_sser, rw_cfg);
+		reg_sser_rw_tr_cfg tr_cfg = REG_RD(sser, port->regi_sser, rw_tr_cfg);
+		reg_sser_rw_rec_cfg rec_cfg = REG_RD(sser, port->regi_sser, rw_rec_cfg);
+		cfg.en = regk_sser_yes;
+		tr_cfg.tr_en = port->output;
+		rec_cfg.rec_en = port->input;
+		REG_WR(sser, port->regi_sser, rw_cfg, cfg);
+		REG_WR(sser, port->regi_sser, rw_tr_cfg, tr_cfg);
+		REG_WR(sser, port->regi_sser, rw_rec_cfg, rec_cfg);
+		port->started = 1;
+	}
+
+	if (file->f_flags & O_NONBLOCK)	{
+		spin_lock_irqsave(&port->lock, flags);
+		if (!port->tr_running) {
+			if (!port->use_dma) {
+				reg_sser_rw_intr_mask intr_mask;
+				intr_mask = REG_RD(sser, port->regi_sser, rw_intr_mask);
+				/* Start sender by writing data */
+				send_word(port);
+				/* and enable transmitter ready IRQ */
+				intr_mask.trdy = 1;
+				REG_WR(sser, port->regi_sser, rw_intr_mask, intr_mask);
+			} else {
+				start_dma(port, (unsigned char* volatile )port->outp, c);
+			}
+		}
+		spin_unlock_irqrestore(&port->lock, flags);
+		DEBUGWRITE(printk("w d%d c %lu NB\n",
+				  port->port_nbr, count));
+		return count;
+	}
+
+	/* Sleep until all sent */
+
+	add_wait_queue(&port->out_wait_q, &wait);
+	set_current_state(TASK_INTERRUPTIBLE);
+	spin_lock_irqsave(&port->lock, flags);
+	if (!port->tr_running) {
+		if (!port->use_dma) {
+			reg_sser_rw_intr_mask intr_mask;
+			intr_mask = REG_RD(sser, port->regi_sser, rw_intr_mask);
+			/* Start sender by writing data */
+			send_word(port);
+			/* and enable transmitter ready IRQ */
+			intr_mask.trdy = 1;
+			REG_WR(sser, port->regi_sser, rw_intr_mask, intr_mask);
+		} else {
+			start_dma(port, port->outp, c);
+		}
+	}
+	spin_unlock_irqrestore(&port->lock, flags);
+	schedule();
+	set_current_state(TASK_RUNNING);
+	remove_wait_queue(&port->out_wait_q, &wait);
+	if (signal_pending(current))
+	{
+		return -EINTR;
+	}
+	DEBUGWRITE(printk("w d%d c %lu\n", port->port_nbr, count));
+	return count;
+}
+
+static ssize_t sync_serial_read(struct file * file, char * buf,
+				size_t count, loff_t *ppos)
+{
+	int dev = MINOR(file->f_dentry->d_inode->i_rdev);
+	int avail;
+	sync_port *port;
+	unsigned char* start;
+	unsigned char* end;
+	unsigned long flags;
+
+	if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled)
+	{
+		DEBUG(printk("Invalid minor %d\n", dev));
+		return -ENODEV;
+	}
+	port = &ports[dev];
+
+	DEBUGREAD(printk("R%d c %d ri %lu wi %lu /%lu\n", dev, count, port->readp - port->flip, port->writep - port->flip, port->in_buffer_size));
+
+	if (!port->started)
+	{
+		reg_sser_rw_cfg cfg = REG_RD(sser, port->regi_sser, rw_cfg);
+		reg_sser_rw_tr_cfg tr_cfg = REG_RD(sser, port->regi_sser, rw_tr_cfg);
+		reg_sser_rw_rec_cfg rec_cfg = REG_RD(sser, port->regi_sser, rw_rec_cfg);
+		cfg.en = regk_sser_yes;
+		tr_cfg.tr_en = regk_sser_yes;
+		rec_cfg.rec_en = regk_sser_yes;
+		REG_WR(sser, port->regi_sser, rw_cfg, cfg);
+		REG_WR(sser, port->regi_sser, rw_tr_cfg, tr_cfg);
+		REG_WR(sser, port->regi_sser, rw_rec_cfg, rec_cfg);
+		port->started = 1;
+	}
+
+
+	/* Calculate number of available bytes */
+	/* Save pointers to avoid that they are modified by interrupt */
+	spin_lock_irqsave(&port->lock, flags);
+	start = (unsigned char*)port->readp; /* cast away volatile */
+	end = (unsigned char*)port->writep;  /* cast away volatile */
+	spin_unlock_irqrestore(&port->lock, flags);
+	while ((start == end) && !port->full) /* No data */
+	{
+		if (file->f_flags & O_NONBLOCK)
+		{
+			return -EAGAIN;
+		}
+
+		interruptible_sleep_on(&port->in_wait_q);
+		if (signal_pending(current))
+		{
+			return -EINTR;
+		}
+		spin_lock_irqsave(&port->lock, flags);
+		start = (unsigned char*)port->readp; /* cast away volatile */
+		end = (unsigned char*)port->writep;  /* cast away volatile */
+		spin_unlock_irqrestore(&port->lock, flags);
+	}
+
+	/* Lazy read, never return wrapped data. */
+	if (port->full)
+		avail = port->in_buffer_size;
+	else if (end > start)
+		avail = end - start;
+	else
+		avail = port->flip + port->in_buffer_size - start;
+
+	count = count > avail ? avail : count;
+	if (copy_to_user(buf, start, count))
+		return -EFAULT;
+	/* Disable interrupts while updating readp */
+	spin_lock_irqsave(&port->lock, flags);
+	port->readp += count;
+	if (port->readp >= port->flip + port->in_buffer_size) /* Wrap? */
+		port->readp = port->flip;
+	port->full = 0;
+	spin_unlock_irqrestore(&port->lock, flags);
+	DEBUGREAD(printk("r %d\n", count));
+	return count;
+}
+
+static void send_word(sync_port* port)
+{
+	reg_sser_rw_tr_cfg tr_cfg = REG_RD(sser, port->regi_sser, rw_tr_cfg);
+	reg_sser_rw_tr_data tr_data =  {0};
+
+	switch(tr_cfg.sample_size)
+	{
+	 case 8:
+		 port->out_count--;
+		 tr_data.data = *port->outp++;
+		 REG_WR(sser, port->regi_sser, rw_tr_data, tr_data);
+		 if (port->outp >= port->out_buffer + OUT_BUFFER_SIZE)
+			 port->outp = port->out_buffer;
+		 break;
+	 case 12:
+	 {
+		int data = (*port->outp++) << 8;
+		data |= *port->outp++;
+		port->out_count-=2;
+		tr_data.data = data;
+		REG_WR(sser, port->regi_sser, rw_tr_data, tr_data);
+		if (port->outp >= port->out_buffer + OUT_BUFFER_SIZE)
+			port->outp = port->out_buffer;
+	}
+	break;
+	case 16:
+		port->out_count-=2;
+		tr_data.data = *(unsigned short *)port->outp;
+		REG_WR(sser, port->regi_sser, rw_tr_data, tr_data);
+		port->outp+=2;
+		if (port->outp >= port->out_buffer + OUT_BUFFER_SIZE)
+			port->outp = port->out_buffer;
+		break;
+	case 24:
+		port->out_count-=3;
+		tr_data.data = *(unsigned short *)port->outp;
+		REG_WR(sser, port->regi_sser, rw_tr_data, tr_data);
+		port->outp+=2;
+		tr_data.data = *port->outp++;
+		REG_WR(sser, port->regi_sser, rw_tr_data, tr_data);
+		if (port->outp >= port->out_buffer + OUT_BUFFER_SIZE)
+			port->outp = port->out_buffer;
+		break;
+	case 32:
+		port->out_count-=4;
+		tr_data.data = *(unsigned short *)port->outp;
+		REG_WR(sser, port->regi_sser, rw_tr_data, tr_data);
+		port->outp+=2;
+		tr_data.data = *(unsigned short *)port->outp;
+		REG_WR(sser, port->regi_sser, rw_tr_data, tr_data);
+		port->outp+=2;
+		if (port->outp >= port->out_buffer + OUT_BUFFER_SIZE)
+			port->outp = port->out_buffer;
+		break;
+	}
+}
+
+
+static void start_dma(struct sync_port* port, const char* data, int count)
+{
+	port->tr_running = 1;
+	port->out_descr.buf = (char*)virt_to_phys((char*)data);
+	port->out_descr.after = port->out_descr.buf + count;
+	port->out_descr.eol = port->out_descr.intr = 1;
+
+	port->out_context.saved_data = (dma_descr_data*)virt_to_phys(&port->out_descr);
+	port->out_context.saved_data_buf = port->out_descr.buf;
+
+	DMA_START_CONTEXT(port->regi_dmaout, virt_to_phys((char*)&port->out_context));
+	DEBUGTXINT(printk("dma %08lX c %d\n", (unsigned long)data, count));
+}
+
+static void start_dma_in(sync_port* port)
+{
+	int i;
+	char* buf;
+	port->writep = port->flip;
+
+	if (port->writep > port->flip + port->in_buffer_size)
+	{
+		panic("Offset too large in sync serial driver\n");
+		return;
+	}
+	buf = (char*)virt_to_phys(port->in_buffer);
+	for (i = 0; i < NUM_IN_DESCR; i++) {
+		port->in_descr[i].buf = buf;
+		port->in_descr[i].after = buf + port->inbufchunk;
+		port->in_descr[i].intr = 1;
+		port->in_descr[i].next = (dma_descr_data*)virt_to_phys(&port->in_descr[i+1]);
+		port->in_descr[i].buf = buf;
+		buf += port->inbufchunk;
+	}
+	/* Link the last descriptor to the first */
+	port->in_descr[i-1].next = (dma_descr_data*)virt_to_phys(&port->in_descr[0]);
+	port->in_descr[i-1].eol = regk_sser_yes;
+	port->next_rx_desc = &port->in_descr[0];
+	port->prev_rx_desc = &port->in_descr[NUM_IN_DESCR - 1];
+	port->in_context.saved_data = (dma_descr_data*)virt_to_phys(&port->in_descr[0]);
+	port->in_context.saved_data_buf = port->in_descr[0].buf;
+	DMA_START_CONTEXT(port->regi_dmain, virt_to_phys(&port->in_context));
+}
+
+#ifdef SYNC_SER_DMA
+static irqreturn_t tr_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+{
+	reg_dma_r_masked_intr masked;
+	reg_dma_rw_ack_intr ack_intr = {.data = regk_dma_yes};
+	int i;
+	struct dma_descr_data *descr;
+	unsigned int sentl;
+	int found = 0;
+
+	for (i = 0; i < NUMBER_OF_PORTS; i++)
+	{
+		sync_port *port = &ports[i];
+		if (!port->enabled  || !port->use_dma )
+			continue;
+
+		masked = REG_RD(dma, port->regi_dmaout, r_masked_intr);
+
+		if (masked.data) /* IRQ active for the port? */
+		{
+			found = 1;
+			/* Clear IRQ */
+			REG_WR(dma, port->regi_dmaout, rw_ack_intr, ack_intr);
+			descr = &port->out_descr;
+			sentl = descr->after - descr->buf;
+			port->out_count -= sentl;
+			port->outp += sentl;
+			if (port->outp >= port->out_buffer + OUT_BUFFER_SIZE)
+				port->outp = port->out_buffer;
+			if (port->out_count)  {
+				int c;
+				c = port->out_buffer + OUT_BUFFER_SIZE - port->outp;
+				if (c > port->out_count)
+					c = port->out_count;
+				DEBUGTXINT(printk("tx_int DMAWRITE %i %i\n", sentl, c));
+				start_dma(port, port->outp, c);
+			} else  {
+				DEBUGTXINT(printk("tx_int DMA stop %i\n", sentl));
+				port->tr_running = 0;
+			}
+			wake_up_interruptible(&port->out_wait_q); /* wake up the waiting process */
+		}
+	}
+	return IRQ_RETVAL(found);
+} /* tr_interrupt */
+
+static irqreturn_t rx_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+{
+	reg_dma_r_masked_intr masked;
+	reg_dma_rw_ack_intr ack_intr = {.data = regk_dma_yes};
+
+	int i;
+	int found = 0;
+
+	for (i = 0; i < NUMBER_OF_PORTS; i++)
+	{
+		sync_port *port = &ports[i];
+
+		if (!port->enabled || !port->use_dma )
+			continue;
+
+		masked = REG_RD(dma, port->regi_dmain, r_masked_intr);
+
+		if (masked.data) /* Descriptor interrupt */
+		{
+			found = 1;
+			while (REG_RD(dma, port->regi_dmain, rw_data) !=
+			       virt_to_phys(port->next_rx_desc)) {
+
+				if (port->writep + port->inbufchunk > port->flip + port->in_buffer_size) {
+					int first_size = port->flip + port->in_buffer_size - port->writep;
+					memcpy((char*)port->writep, phys_to_virt((unsigned)port->next_rx_desc->buf), first_size);
+					memcpy(port->flip, phys_to_virt((unsigned)port->next_rx_desc->buf+first_size), port->inbufchunk - first_size);
+					port->writep = port->flip + port->inbufchunk - first_size;
+				} else {
+					memcpy((char*)port->writep,
+					       phys_to_virt((unsigned)port->next_rx_desc->buf),
+					       port->inbufchunk);
+					port->writep += port->inbufchunk;
+					if (port->writep >= port->flip + port->in_buffer_size)
+						port->writep = port->flip;
+				}
+                                if (port->writep == port->readp)
+                                {
+				  port->full = 1;
+                                }
+
+				port->next_rx_desc->eol = 0;
+				port->prev_rx_desc->eol = 1;
+				port->prev_rx_desc = phys_to_virt((unsigned)port->next_rx_desc);
+				port->next_rx_desc = phys_to_virt((unsigned)port->next_rx_desc->next);
+				wake_up_interruptible(&port->in_wait_q); /* wake up the waiting process */
+				DMA_CONTINUE(port->regi_dmain);
+				REG_WR(dma, port->regi_dmain, rw_ack_intr, ack_intr);
+
+			}
+		}
+	}
+	return IRQ_RETVAL(found);
+} /* rx_interrupt */
+#endif /* SYNC_SER_DMA */
+
+#ifdef SYNC_SER_MANUAL
+static irqreturn_t manual_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+{
+	int i;
+	int found = 0;
+	reg_sser_r_masked_intr masked;
+
+	for (i = 0; i < NUMBER_OF_PORTS; i++)
+	{
+		sync_port* port = &ports[i];
+
+		if (!port->enabled || port->use_dma)
+		{
+			continue;
+		}
+
+		masked = REG_RD(sser, port->regi_sser, r_masked_intr);
+		if (masked.rdav)	/* Data received? */
+		{
+			reg_sser_rw_rec_cfg rec_cfg = REG_RD(sser, port->regi_sser, rw_rec_cfg);
+			reg_sser_r_rec_data data = REG_RD(sser, port->regi_sser, r_rec_data);
+			found = 1;
+			/* Read data */
+			switch(rec_cfg.sample_size)
+			{
+			case 8:
+				*port->writep++ = data.data & 0xff;
+				break;
+			case 12:
+				*port->writep = (data.data & 0x0ff0) >> 4;
+				*(port->writep + 1) = data.data & 0x0f;
+				port->writep+=2;
+				break;
+			case 16:
+				*(unsigned short*)port->writep = data.data;
+				port->writep+=2;
+				break;
+			case 24:
+				*(unsigned int*)port->writep = data.data;
+				port->writep+=3;
+				break;
+			case 32:
+				*(unsigned int*)port->writep = data.data;
+				port->writep+=4;
+				break;
+			}
+
+			if (port->writep >= port->flip + port->in_buffer_size) /* Wrap? */
+				port->writep = port->flip;
+			if (port->writep == port->readp) {
+				/* receive buffer overrun, discard oldest data
+				 */
+				port->readp++;
+				if (port->readp >= port->flip + port->in_buffer_size) /* Wrap? */
+					port->readp = port->flip;
+			}
+			if (sync_data_avail(port) >= port->inbufchunk)
+				wake_up_interruptible(&port->in_wait_q); /* Wake up application */
+		}
+
+		if (masked.trdy) /* Transmitter ready? */
+		{
+			found = 1;
+			if (port->out_count > 0) /* More data to send */
+				send_word(port);
+			else /* transmission finished */
+			{
+				reg_sser_rw_intr_mask intr_mask;
+				intr_mask = REG_RD(sser, port->regi_sser, rw_intr_mask);
+				intr_mask.trdy = 0;
+				REG_WR(sser, port->regi_sser, rw_intr_mask, intr_mask);
+				wake_up_interruptible(&port->out_wait_q); /* Wake up application */
+			}
+		}
+	}
+	return IRQ_RETVAL(found);
+}
+#endif
+
+module_init(etrax_sync_serial_init);
diff --git a/arch/cris/arch-v32/kernel/Makefile b/arch/cris/arch-v32/kernel/Makefile
new file mode 100644
--- /dev/null
+++ b/arch/cris/arch-v32/kernel/Makefile
@@ -0,0 +1,21 @@
+# $Id: Makefile,v 1.11 2004/12/17 10:16:13 starvik Exp $
+#
+# Makefile for the linux kernel.
+#
+
+extra-y	:= head.o
+
+
+obj-y   := entry.o traps.o irq.o debugport.o dma.o pinmux.o \
+	   process.o ptrace.o setup.o signal.o traps.o time.o \
+	   arbiter.o io.o
+
+obj-$(CONFIG_ETRAXFS_SIM) += vcs_hook.o
+
+obj-$(CONFIG_SMP) += smp.o
+obj-$(CONFIG_ETRAX_KGDB) += kgdb.o kgdb_asm.o
+obj-$(CONFIG_ETRAX_FAST_TIMER) += fasttimer.o
+obj-$(CONFIG_MODULES)    += crisksyms.o
+
+clean:
+
diff --git a/arch/cris/arch-v32/kernel/arbiter.c b/arch/cris/arch-v32/kernel/arbiter.c
new file mode 100644
--- /dev/null
+++ b/arch/cris/arch-v32/kernel/arbiter.c
@@ -0,0 +1,297 @@
+/*
+ * Memory arbiter functions. Allocates bandwith through the
+ * arbiter and sets up arbiter breakpoints.
+ *
+ * The algorithm first assigns slots to the clients that has specified
+ * bandwith (e.g. ethernet) and then the remaining slots are divided
+ * on all the active clients.
+ *
+ * Copyright (c) 2004, 2005 Axis Communications AB.
+ */
+
+#include <linux/config.h>
+#include <asm/arch/hwregs/reg_map.h>
+#include <asm/arch/hwregs/reg_rdwr.h>
+#include <asm/arch/hwregs/marb_defs.h>
+#include <asm/arch/arbiter.h>
+#include <asm/arch/hwregs/intr_vect.h>
+#include <linux/interrupt.h>
+#include <linux/signal.h>
+#include <linux/errno.h>
+#include <linux/spinlock.h>
+#include <asm/io.h>
+
+struct crisv32_watch_entry
+{
+  unsigned long instance;
+  watch_callback* cb;
+  unsigned long start;
+  unsigned long end;
+  int used;
+};
+
+#define NUMBER_OF_BP 4
+#define NBR_OF_CLIENTS 14
+#define NBR_OF_SLOTS 64
+#define SDRAM_BANDWIDTH 100000000 /* Some kind of expected value */
+#define INTMEM_BANDWIDTH 400000000
+#define NBR_OF_REGIONS 2
+
+static struct crisv32_watch_entry watches[NUMBER_OF_BP] =
+{
+  {regi_marb_bp0},
+  {regi_marb_bp1},
+  {regi_marb_bp2},
+  {regi_marb_bp3}
+};
+
+static int requested_slots[NBR_OF_REGIONS][NBR_OF_CLIENTS];
+static int active_clients[NBR_OF_REGIONS][NBR_OF_CLIENTS];
+static int max_bandwidth[NBR_OF_REGIONS] = {SDRAM_BANDWIDTH, INTMEM_BANDWIDTH};
+
+DEFINE_SPINLOCK(arbiter_lock);
+
+static irqreturn_t
+crisv32_arbiter_irq(int irq, void* dev_id, struct pt_regs* regs);
+
+static void crisv32_arbiter_config(int region)
+{
+	int slot;
+	int client;
+	int interval = 0;
+	int val[NBR_OF_SLOTS];
+
+	for (slot = 0; slot < NBR_OF_SLOTS; slot++)
+	    val[slot] = NBR_OF_CLIENTS + 1;
+
+	for (client = 0; client < NBR_OF_CLIENTS; client++)
+	{
+	    int pos;
+	    if (!requested_slots[region][client])
+	       continue;
+	    interval = NBR_OF_SLOTS / requested_slots[region][client];
+	    pos = 0;
+	    while (pos < NBR_OF_SLOTS)
+	    {
+		if (val[pos] != NBR_OF_CLIENTS + 1)
+		   pos++;
+		else
+		{
+			val[pos] = client;
+			pos += interval;
+		}
+	    }
+	}
+
+	client = 0;
+	for (slot = 0; slot < NBR_OF_SLOTS; slot++)
+	{
+		if (val[slot] == NBR_OF_CLIENTS + 1)
+		{
+			int first = client;
+			while(!active_clients[region][client]) {
+				client = (client + 1) % NBR_OF_CLIENTS;
+				if (client == first)
+				   break;
+			}
+			val[slot] = client;
+			client = (client + 1) % NBR_OF_CLIENTS;
+		}
+		if (region == EXT_REGION)
+		   REG_WR_INT_VECT(marb, regi_marb, rw_ext_slots, slot, val[slot]);
+		else if (region == INT_REGION)
+		   REG_WR_INT_VECT(marb, regi_marb, rw_int_slots, slot, val[slot]);
+	}
+}
+
+extern char _stext, _etext;
+
+static void crisv32_arbiter_init(void)
+{
+	static int initialized = 0;
+
+	if (initialized)
+		return;
+
+	initialized = 1;
+
+	/* CPU caches are active. */
+	active_clients[EXT_REGION][10] = active_clients[EXT_REGION][11] = 1;
+        crisv32_arbiter_config(EXT_REGION);
+        crisv32_arbiter_config(INT_REGION);
+
+	if (request_irq(MEMARB_INTR_VECT, crisv32_arbiter_irq, SA_INTERRUPT,
+                        "arbiter", NULL))
+		printk(KERN_ERR "Couldn't allocate arbiter IRQ\n");
+
+#ifndef CONFIG_ETRAX_KGDB
+        /* Global watch for writes to kernel text segment. */
+        crisv32_arbiter_watch(virt_to_phys(&_stext), &_etext - &_stext,
+                              arbiter_all_clients, arbiter_all_write, NULL);
+#endif
+}
+
+
+
+int crisv32_arbiter_allocate_bandwith(int client, int region,
+	                              unsigned long bandwidth)
+{
+	int i;
+	int total_assigned = 0;
+	int total_clients = 0;
+	int req;
+
+	crisv32_arbiter_init();
+
+	for (i = 0; i < NBR_OF_CLIENTS; i++)
+	{
+		total_assigned += requested_slots[region][i];
+		total_clients += active_clients[region][i];
+	}
+	req = NBR_OF_SLOTS / (max_bandwidth[region] / bandwidth);
+
+	if (total_assigned + total_clients + req + 1 > NBR_OF_SLOTS)
+	   return -ENOMEM;
+
+	active_clients[region][client] = 1;
+	requested_slots[region][client] = req;
+	crisv32_arbiter_config(region);
+
+	return 0;
+}
+
+int crisv32_arbiter_watch(unsigned long start, unsigned long size,
+                          unsigned long clients, unsigned long accesses,
+                          watch_callback* cb)
+{
+	int i;
+
+	crisv32_arbiter_init();
+
+	if (start > 0x80000000) {
+		printk("Arbiter: %lX doesn't look like a physical address", start);
+		return -EFAULT;
+	}
+
+	spin_lock(&arbiter_lock);
+
+	for (i = 0; i < NUMBER_OF_BP; i++) {
+		if (!watches[i].used) {
+			reg_marb_rw_intr_mask intr_mask = REG_RD(marb, regi_marb, rw_intr_mask);
+
+			watches[i].used = 1;
+			watches[i].start = start;
+			watches[i].end = start + size;
+			watches[i].cb = cb;
+
+			REG_WR_INT(marb_bp, watches[i].instance, rw_first_addr, watches[i].start);
+			REG_WR_INT(marb_bp, watches[i].instance, rw_last_addr, watches[i].end);
+			REG_WR_INT(marb_bp, watches[i].instance, rw_op, accesses);
+			REG_WR_INT(marb_bp, watches[i].instance, rw_clients, clients);
+
+			if (i == 0)
+				intr_mask.bp0 = regk_marb_yes;
+			else if (i == 1)
+				intr_mask.bp1 = regk_marb_yes;
+			else if (i == 2)
+				intr_mask.bp2 = regk_marb_yes;
+			else if (i == 3)
+				intr_mask.bp3 = regk_marb_yes;
+
+			REG_WR(marb, regi_marb, rw_intr_mask, intr_mask);
+			spin_unlock(&arbiter_lock);
+
+			return i;
+		}
+	}
+	spin_unlock(&arbiter_lock);
+	return -ENOMEM;
+}
+
+int crisv32_arbiter_unwatch(int id)
+{
+	reg_marb_rw_intr_mask intr_mask = REG_RD(marb, regi_marb, rw_intr_mask);
+
+	crisv32_arbiter_init();
+
+	spin_lock(&arbiter_lock);
+
+	if ((id < 0) || (id >= NUMBER_OF_BP) || (!watches[id].used)) {
+		spin_unlock(&arbiter_lock);
+		return -EINVAL;
+	}
+
+	memset(&watches[id], 0, sizeof(struct crisv32_watch_entry));
+
+	if (id == 0)
+		intr_mask.bp0 = regk_marb_no;
+	else if (id == 1)
+		intr_mask.bp2 = regk_marb_no;
+	else if (id == 2)
+		intr_mask.bp2 = regk_marb_no;
+	else if (id == 3)
+		intr_mask.bp3 = regk_marb_no;
+
+	REG_WR(marb, regi_marb, rw_intr_mask, intr_mask);
+
+	spin_unlock(&arbiter_lock);
+	return 0;
+}
+
+extern void show_registers(struct pt_regs *regs);
+
+static irqreturn_t
+crisv32_arbiter_irq(int irq, void* dev_id, struct pt_regs* regs)
+{
+	reg_marb_r_masked_intr masked_intr = REG_RD(marb, regi_marb, r_masked_intr);
+	reg_marb_bp_r_brk_clients r_clients;
+	reg_marb_bp_r_brk_addr r_addr;
+	reg_marb_bp_r_brk_op r_op;
+	reg_marb_bp_r_brk_first_client r_first;
+	reg_marb_bp_r_brk_size r_size;
+	reg_marb_bp_rw_ack ack = {0};
+	reg_marb_rw_ack_intr ack_intr = {.bp0=1,.bp1=1,.bp2=1,.bp3=1};
+	struct crisv32_watch_entry* watch;
+
+	if (masked_intr.bp0) {
+		watch = &watches[0];
+		ack_intr.bp0 = regk_marb_yes;
+	} else if (masked_intr.bp1) {
+		watch = &watches[1];
+		ack_intr.bp1 = regk_marb_yes;
+	} else if (masked_intr.bp2) {
+		watch = &watches[2];
+		ack_intr.bp2 = regk_marb_yes;
+	} else if (masked_intr.bp3) {
+		watch = &watches[3];
+		ack_intr.bp3 = regk_marb_yes;
+	} else {
+		return IRQ_NONE;
+	}
+
+	/* Retrieve all useful information and print it. */
+	r_clients = REG_RD(marb_bp, watch->instance, r_brk_clients);
+	r_addr = REG_RD(marb_bp, watch->instance, r_brk_addr);
+	r_op = REG_RD(marb_bp, watch->instance, r_brk_op);
+	r_first = REG_RD(marb_bp, watch->instance, r_brk_first_client);
+	r_size = REG_RD(marb_bp, watch->instance, r_brk_size);
+
+	printk("Arbiter IRQ\n");
+	printk("Clients %X addr %X op %X first %X size %X\n",
+	       REG_TYPE_CONV(int, reg_marb_bp_r_brk_clients, r_clients),
+	       REG_TYPE_CONV(int, reg_marb_bp_r_brk_addr, r_addr),
+	       REG_TYPE_CONV(int, reg_marb_bp_r_brk_op, r_op),
+	       REG_TYPE_CONV(int, reg_marb_bp_r_brk_first_client, r_first),
+	       REG_TYPE_CONV(int, reg_marb_bp_r_brk_size, r_size));
+
+	REG_WR(marb_bp, watch->instance, rw_ack, ack);
+	REG_WR(marb, regi_marb, rw_ack_intr, ack_intr);
+
+	printk("IRQ occured at %lX\n", regs->erp);
+
+	if (watch->cb)
+		watch->cb();
+
+
+	return IRQ_HANDLED;
+}
diff --git a/arch/cris/arch-v32/kernel/asm-offsets.c b/arch/cris/arch-v32/kernel/asm-offsets.c
new file mode 100644
--- /dev/null
+++ b/arch/cris/arch-v32/kernel/asm-offsets.c
@@ -0,0 +1,49 @@
+#include <linux/sched.h>
+#include <asm/thread_info.h>
+
+/*
+ * Generate definitions needed by assembly language modules.
+ * This code generates raw asm output which is post-processed to extract
+ * and format the required data.
+ */
+
+#define DEFINE(sym, val) \
+        asm volatile("\n->" #sym " %0 " #val : : "i" (val))
+
+#define BLANK() asm volatile("\n->" : : )
+
+int main(void)
+{
+#define ENTRY(entry) DEFINE(PT_ ## entry, offsetof(struct pt_regs, entry))
+	ENTRY(orig_r10);
+	ENTRY(r13);
+	ENTRY(r12);
+	ENTRY(r11);
+        ENTRY(r10);
+        ENTRY(r9);
+	ENTRY(acr);
+	ENTRY(srs);
+        ENTRY(mof);
+        ENTRY(ccs);
+        ENTRY(srp);
+	BLANK();
+#undef ENTRY
+#define ENTRY(entry) DEFINE(TI_ ## entry, offsetof(struct thread_info, entry))
+        ENTRY(task);
+        ENTRY(flags);
+        ENTRY(preempt_count);
+        BLANK();
+#undef ENTRY
+#define ENTRY(entry) DEFINE(THREAD_ ## entry, offsetof(struct thread_struct, entry))
+	ENTRY(ksp);
+        ENTRY(usp);
+        ENTRY(ccs);
+        BLANK();
+#undef ENTRY
+#define ENTRY(entry) DEFINE(TASK_ ## entry, offsetof(struct task_struct, entry))
+        ENTRY(pid);
+        BLANK();
+        DEFINE(LCLONE_VM, CLONE_VM);
+        DEFINE(LCLONE_UNTRACED, CLONE_UNTRACED);
+        return 0;
+}
diff --git a/arch/cris/arch-v32/kernel/crisksyms.c b/arch/cris/arch-v32/kernel/crisksyms.c
new file mode 100644
--- /dev/null
+++ b/arch/cris/arch-v32/kernel/crisksyms.c
@@ -0,0 +1,24 @@
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/irq.h>
+#include <asm/arch/dma.h>
+#include <asm/arch/intmem.h>
+#include <asm/arch/pinmux.h>
+
+/* Functions for allocating DMA channels */
+EXPORT_SYMBOL(crisv32_request_dma);
+EXPORT_SYMBOL(crisv32_free_dma);
+
+/* Functions for handling internal RAM */
+EXPORT_SYMBOL(crisv32_intmem_alloc);
+EXPORT_SYMBOL(crisv32_intmem_free);
+EXPORT_SYMBOL(crisv32_intmem_phys_to_virt);
+EXPORT_SYMBOL(crisv32_intmem_virt_to_phys);
+
+/* Functions for handling pinmux */
+EXPORT_SYMBOL(crisv32_pinmux_alloc);
+EXPORT_SYMBOL(crisv32_pinmux_dealloc);
+
+/* Functions masking/unmasking interrupts */
+EXPORT_SYMBOL(mask_irq);
+EXPORT_SYMBOL(unmask_irq);
diff --git a/arch/cris/arch-v32/kernel/debugport.c b/arch/cris/arch-v32/kernel/debugport.c
new file mode 100644
--- /dev/null
+++ b/arch/cris/arch-v32/kernel/debugport.c
@@ -0,0 +1,461 @@
+/*
+ * Copyright (C) 2003, Axis Communications AB.
+ */
+
+#include <linux/config.h>
+#include <linux/console.h>
+#include <linux/init.h>
+#include <linux/major.h>
+#include <linux/delay.h>
+#include <linux/tty.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/arch/hwregs/ser_defs.h>
+#include <asm/arch/hwregs/dma_defs.h>
+#include <asm/arch/pinmux.h>
+
+#include <asm/irq.h>
+#include <asm/arch/hwregs/intr_vect_defs.h>
+
+struct dbg_port
+{
+	unsigned char nbr;
+	unsigned long instance;
+	unsigned int started;
+	unsigned long baudrate;
+	unsigned char parity;
+	unsigned int bits;
+};
+
+struct dbg_port ports[] =
+{
+  {
+    0,
+    regi_ser0,
+    0,
+    115200,
+    'N',
+    8
+  },
+  {
+    1,
+    regi_ser1,
+    0,
+    115200,
+    'N',
+    8
+  },
+  {
+    2,
+    regi_ser2,
+    0,
+    115200,
+    'N',
+    8
+  },
+  {
+    3,
+    regi_ser3,
+    0,
+    115200,
+    'N',
+    8
+  }
+};
+static struct dbg_port *port =
+#if defined(CONFIG_ETRAX_DEBUG_PORT0)
+&ports[0];
+#elif defined(CONFIG_ETRAX_DEBUG_PORT1)
+&ports[1];
+#elif defined(CONFIG_ETRAX_DEBUG_PORT2)
+&ports[2];
+#elif defined(CONFIG_ETRAX_DEBUG_PORT3)
+&ports[3];
+#else
+NULL;
+#endif
+
+#ifdef CONFIG_ETRAX_KGDB
+static struct dbg_port *kgdb_port =
+#if defined(CONFIG_ETRAX_KGDB_PORT0)
+&ports[0];
+#elif defined(CONFIG_ETRAX_KGDB_PORT1)
+&ports[1];
+#elif defined(CONFIG_ETRAX_KGDB_PORT2)
+&ports[2];
+#elif defined(CONFIG_ETRAX_KGDB_PORT3)
+&ports[3];
+#else
+NULL;
+#endif
+#endif
+
+#ifdef CONFIG_ETRAXFS_SIM
+extern void print_str( const char *str );
+static char buffer[1024];
+static char msg[] = "Debug: ";
+static int buffer_pos = sizeof(msg) - 1;
+#endif
+
+extern struct tty_driver *serial_driver;
+
+static void
+start_port(struct dbg_port* p)
+{
+	if (!p)
+		return;
+
+	if (p->started)
+		return;
+	p->started = 1;
+
+	if (p->nbr == 1)
+		crisv32_pinmux_alloc_fixed(pinmux_ser1);
+	else if (p->nbr == 2)
+		crisv32_pinmux_alloc_fixed(pinmux_ser2);
+	else if (p->nbr == 3)
+		crisv32_pinmux_alloc_fixed(pinmux_ser3);
+
+	/* Set up serial port registers */
+	reg_ser_rw_tr_ctrl tr_ctrl = {0};
+	reg_ser_rw_tr_dma_en tr_dma_en = {0};
+
+	reg_ser_rw_rec_ctrl rec_ctrl = {0};
+	reg_ser_rw_tr_baud_div tr_baud_div = {0};
+	reg_ser_rw_rec_baud_div rec_baud_div = {0};
+
+	tr_ctrl.base_freq = rec_ctrl.base_freq = regk_ser_f29_493;
+	tr_dma_en.en = rec_ctrl.dma_mode = regk_ser_no;
+	tr_baud_div.div = rec_baud_div.div = 29493000 / p->baudrate / 8;
+	tr_ctrl.en = rec_ctrl.en = 1;
+
+	if (p->parity == 'O')
+	{
+		tr_ctrl.par_en = regk_ser_yes;
+		tr_ctrl.par = regk_ser_odd;
+		rec_ctrl.par_en = regk_ser_yes;
+		rec_ctrl.par = regk_ser_odd;
+	}
+	else if (p->parity == 'E')
+	{
+		tr_ctrl.par_en = regk_ser_yes;
+		tr_ctrl.par = regk_ser_even;
+		rec_ctrl.par_en = regk_ser_yes;
+		rec_ctrl.par = regk_ser_odd;
+	}
+
+	if (p->bits == 7)
+	{
+		tr_ctrl.data_bits = regk_ser_bits7;
+		rec_ctrl.data_bits = regk_ser_bits7;
+	}
+
+	REG_WR (ser, p->instance, rw_tr_baud_div, tr_baud_div);
+	REG_WR (ser, p->instance, rw_rec_baud_div, rec_baud_div);
+	REG_WR (ser, p->instance, rw_tr_dma_en, tr_dma_en);
+	REG_WR (ser, p->instance, rw_tr_ctrl, tr_ctrl);
+	REG_WR (ser, p->instance, rw_rec_ctrl, rec_ctrl);
+}
+
+/* No debug */
+#ifdef CONFIG_ETRAX_DEBUG_PORT_NULL
+
+static void
+console_write(struct console *co, const char *buf, unsigned int len)
+{
+	return;
+}
+
+/* Target debug */
+#elif !defined(CONFIG_ETRAXFS_SIM)
+
+static void
+console_write_direct(struct console *co, const char *buf, unsigned int len)
+{
+	int i;
+	reg_ser_r_stat_din stat;
+	reg_ser_rw_tr_dma_en tr_dma_en, old;
+
+	/* Switch to manual mode */
+	tr_dma_en = old = REG_RD (ser, port->instance, rw_tr_dma_en);
+	if (tr_dma_en.en == regk_ser_yes) {
+		tr_dma_en.en = regk_ser_no;
+		REG_WR(ser, port->instance, rw_tr_dma_en, tr_dma_en);
+	}
+
+	/* Send data */
+	for (i = 0; i < len; i++) {
+		/* LF -> CRLF */
+		if (buf[i] == '\n') {
+			do {
+				stat = REG_RD (ser, port->instance, r_stat_din);
+			} while (!stat.tr_rdy);
+			REG_WR_INT (ser, port->instance, rw_dout, '\r');
+		}
+		/* Wait until transmitter is ready and send.*/
+		do {
+			stat = REG_RD (ser, port->instance, r_stat_din);
+		} while (!stat.tr_rdy);
+		REG_WR_INT (ser, port->instance, rw_dout, buf[i]);
+	}
+
+	/* Restore mode */
+	if (tr_dma_en.en != old.en)
+		REG_WR(ser, port->instance, rw_tr_dma_en, old);
+}
+
+static void
+console_write(struct console *co, const char *buf, unsigned int len)
+{
+	if (!port)
+		return;
+        console_write_direct(co, buf, len);
+}
+
+
+
+#else
+
+/* VCS debug */
+
+static void
+console_write(struct console *co, const char *buf, unsigned int len)
+{
+	char* pos;
+	pos = memchr(buf, '\n', len);
+	if (pos) {
+		int l = ++pos - buf;
+		memcpy(buffer + buffer_pos, buf, l);
+		memcpy(buffer, msg, sizeof(msg) - 1);
+		buffer[buffer_pos + l] = '\0';
+		print_str(buffer);
+		buffer_pos = sizeof(msg) - 1;
+		if (pos - buf != len) {
+			memcpy(buffer + buffer_pos, pos, len - l);
+			buffer_pos += len - l;
+		}
+	} else {
+		memcpy(buffer + buffer_pos, buf, len);
+		buffer_pos += len;
+	}
+}
+
+#endif
+
+int raw_printk(const char *fmt, ...)
+{
+	static char buf[1024];
+	int printed_len;
+	va_list args;
+	va_start(args, fmt);
+	printed_len = vsnprintf(buf, sizeof(buf), fmt, args);
+	va_end(args);
+	console_write(NULL, buf, strlen(buf));
+	return printed_len;
+}
+
+void
+stupid_debug(char* buf)
+{
+  console_write(NULL, buf, strlen(buf));
+}
+
+#ifdef CONFIG_ETRAX_KGDB
+/* Use polling to get a single character from the kernel debug port */
+int
+getDebugChar(void)
+{
+	reg_ser_rs_status_data stat;
+	reg_ser_rw_ack_intr ack_intr = { 0 };
+
+	do {
+		stat = REG_RD(ser, kgdb_instance, rs_status_data);
+	} while (!stat.data_avail);
+
+	/* Ack the data_avail interrupt. */
+	ack_intr.data_avail = 1;
+	REG_WR(ser, kgdb_instance, rw_ack_intr, ack_intr);
+
+	return stat.data;
+}
+
+/* Use polling to put a single character to the kernel debug port */
+void
+putDebugChar(int val)
+{
+	reg_ser_r_status_data stat;
+	do {
+		stat = REG_RD (ser, kgdb_instance, r_status_data);
+	} while (!stat.tr_ready);
+	REG_WR (ser, kgdb_instance, rw_data_out, REG_TYPE_CONV(reg_ser_rw_data_out, int, val));
+}
+#endif /* CONFIG_ETRAX_KGDB */
+
+static int __init
+console_setup(struct console *co, char *options)
+{
+	char* s;
+
+	if (options) {
+		port = &ports[co->index];
+		port->baudrate = 115200;
+		port->parity = 'N';
+		port->bits = 8;
+		port->baudrate = simple_strtoul(options, NULL, 10);
+		s = options;
+		while(*s >= '0' && *s <= '9')
+			s++;
+		if (*s) port->parity = *s++;
+		if (*s) port->bits   = *s++ - '0';
+		port->started = 0;
+		start_port(port);
+	}
+	return 0;
+}
+
+/* This is a dummy serial device that throws away anything written to it.
+ * This is used when no debug output is wanted.
+ */
+static struct tty_driver dummy_driver;
+
+static int dummy_open(struct tty_struct *tty, struct file * filp)
+{
+	return 0;
+}
+
+static void dummy_close(struct tty_struct *tty, struct file * filp)
+{
+}
+
+static int dummy_write(struct tty_struct * tty,
+                       const unsigned char *buf, int count)
+{
+	return count;
+}
+
+static int
+dummy_write_room(struct tty_struct *tty)
+{
+	return 8192;
+}
+
+void __init
+init_dummy_console(void)
+{
+	memset(&dummy_driver, 0, sizeof(struct tty_driver));
+	dummy_driver.driver_name = "serial";
+	dummy_driver.name = "ttyS";
+	dummy_driver.major = TTY_MAJOR;
+	dummy_driver.minor_start = 68;
+	dummy_driver.num = 1;       /* etrax100 has 4 serial ports */
+	dummy_driver.type = TTY_DRIVER_TYPE_SERIAL;
+	dummy_driver.subtype = SERIAL_TYPE_NORMAL;
+	dummy_driver.init_termios = tty_std_termios;
+	dummy_driver.init_termios.c_cflag =
+		B115200 | CS8 | CREAD | HUPCL | CLOCAL; /* is normally B9600 default... */
+	dummy_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS;
+
+	dummy_driver.open = dummy_open;
+	dummy_driver.close = dummy_close;
+	dummy_driver.write = dummy_write;
+	dummy_driver.write_room = dummy_write_room;
+	if (tty_register_driver(&dummy_driver))
+		panic("Couldn't register dummy serial driver\n");
+}
+
+static struct tty_driver*
+crisv32_console_device(struct console* co, int *index)
+{
+	if (port)
+		*index = port->nbr;
+        return port ? serial_driver : &dummy_driver;
+}
+
+static struct console sercons = {
+	name : "ttyS",
+	write: console_write,
+	read : NULL,
+	device : crisv32_console_device,
+	unblank : NULL,
+	setup : console_setup,
+	flags : CON_PRINTBUFFER,
+	index : -1,
+	cflag : 0,
+	next : NULL
+};
+static struct console sercons0 = {
+	name : "ttyS",
+	write: console_write,
+	read : NULL,
+	device : crisv32_console_device,
+	unblank : NULL,
+	setup : console_setup,
+	flags : CON_PRINTBUFFER,
+	index : 0,
+	cflag : 0,
+	next : NULL
+};
+
+static struct console sercons1 = {
+	name : "ttyS",
+	write: console_write,
+	read : NULL,
+	device : crisv32_console_device,
+	unblank : NULL,
+	setup : console_setup,
+	flags : CON_PRINTBUFFER,
+	index : 1,
+	cflag : 0,
+	next : NULL
+};
+static struct console sercons2 = {
+	name : "ttyS",
+	write: console_write,
+	read : NULL,
+	device : crisv32_console_device,
+	unblank : NULL,
+	setup : console_setup,
+	flags : CON_PRINTBUFFER,
+	index : 2,
+	cflag : 0,
+	next : NULL
+};
+static struct console sercons3 = {
+	name : "ttyS",
+	write: console_write,
+	read : NULL,
+	device : crisv32_console_device,
+	unblank : NULL,
+	setup : console_setup,
+	flags : CON_PRINTBUFFER,
+	index : 3,
+	cflag : 0,
+	next : NULL
+};
+
+/* Register console for printk's, etc. */
+int __init
+init_etrax_debug(void)
+{
+  	static int first = 1;
+
+	if (!first) {
+		unregister_console(&sercons);
+		register_console(&sercons0);
+		register_console(&sercons1);
+		register_console(&sercons2);
+		register_console(&sercons3);
+		init_dummy_console();
+		return 0;
+	}
+	first = 0;
+        register_console(&sercons);
+        start_port(port);
+
+#ifdef CONFIG_ETRAX_KGDB
+	start_port(kgdb_port);
+#endif /* CONFIG_ETRAX_KGDB */
+	return 0;
+}
+
+__initcall(init_etrax_debug);
diff --git a/arch/cris/arch-v32/kernel/dma.c b/arch/cris/arch-v32/kernel/dma.c
new file mode 100644
--- /dev/null
+++ b/arch/cris/arch-v32/kernel/dma.c
@@ -0,0 +1,224 @@
+/* Wrapper for DMA channel allocator that starts clocks etc */
+
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+#include <asm/dma.h>
+#include <asm/arch/hwregs/reg_map.h>
+#include <asm/arch/hwregs/reg_rdwr.h>
+#include <asm/arch/hwregs/marb_defs.h>
+#include <asm/arch/hwregs/config_defs.h>
+#include <asm/arch/hwregs/strmux_defs.h>
+#include <linux/errno.h>
+#include <asm/system.h>
+#include <asm/arch/arbiter.h>
+
+static char used_dma_channels[MAX_DMA_CHANNELS];
+static const char * used_dma_channels_users[MAX_DMA_CHANNELS];
+
+static DEFINE_SPINLOCK(dma_lock);
+
+int crisv32_request_dma(unsigned int dmanr, const char * device_id,
+                        unsigned options, unsigned int bandwidth,
+			enum dma_owner owner)
+{
+	unsigned long flags;
+	reg_config_rw_clk_ctrl clk_ctrl;
+	reg_strmux_rw_cfg strmux_cfg;
+
+        if (crisv32_arbiter_allocate_bandwith(dmanr,
+                                              options & DMA_INT_MEM ? INT_REGION : EXT_REGION,
+                                              bandwidth))
+          return -ENOMEM;
+
+	spin_lock_irqsave(&dma_lock, flags);
+
+	if (used_dma_channels[dmanr]) {
+		spin_unlock_irqrestore(&dma_lock, flags);
+		if (options & DMA_VERBOSE_ON_ERROR) {
+			printk("Failed to request DMA %i for %s, already allocated by %s\n", dmanr, device_id, used_dma_channels_users[dmanr]);
+		}
+		if (options & DMA_PANIC_ON_ERROR)
+			panic("request_dma error!");
+		return -EBUSY;
+	}
+	clk_ctrl = REG_RD(config, regi_config, rw_clk_ctrl);
+	strmux_cfg = REG_RD(strmux, regi_strmux, rw_cfg);
+
+	switch(dmanr)
+	{
+	case 0:
+	case 1:
+		clk_ctrl.dma01_eth0 = 1;
+		break;
+	case 2:
+	case 3:
+		clk_ctrl.dma23 = 1;
+		break;
+	case 4:
+	case 5:
+		clk_ctrl.dma45 = 1;
+		break;
+	case 6:
+	case 7:
+		clk_ctrl.dma67 = 1;
+		break;
+	case 8:
+	case 9:
+		clk_ctrl.dma89_strcop = 1;
+		break;
+#if MAX_DMA_CHANNELS-1 != 9
+#error Check dma.c
+#endif
+	default:
+		spin_unlock_irqrestore(&dma_lock, flags);
+		if (options & DMA_VERBOSE_ON_ERROR) {
+			printk("Failed to request DMA %i for %s, only 0-%i valid)\n", dmanr, device_id, MAX_DMA_CHANNELS-1);
+		}
+
+		if (options & DMA_PANIC_ON_ERROR)
+			panic("request_dma error!");
+		return -EINVAL;
+	}
+
+	switch(owner)
+	{
+	case dma_eth0:
+		if (dmanr == 0)
+			strmux_cfg.dma0 = regk_strmux_eth0;
+		else if (dmanr == 1)
+			strmux_cfg.dma1 = regk_strmux_eth0;
+		else
+			panic("Invalid DMA channel for eth0\n");
+		break;
+	case dma_eth1:
+		if (dmanr == 6)
+			strmux_cfg.dma6 = regk_strmux_eth1;
+		else if (dmanr == 7)
+			strmux_cfg.dma7 = regk_strmux_eth1;
+		else
+			panic("Invalid DMA channel for eth1\n");
+		break;
+	case dma_iop0:
+		if (dmanr == 2)
+			strmux_cfg.dma2 = regk_strmux_iop0;
+		else if (dmanr == 3)
+			strmux_cfg.dma3 = regk_strmux_iop0;
+		else
+			panic("Invalid DMA channel for iop0\n");
+		break;
+	case dma_iop1:
+		if (dmanr == 4)
+			strmux_cfg.dma4 = regk_strmux_iop1;
+		else if (dmanr == 5)
+			strmux_cfg.dma5 = regk_strmux_iop1;
+		else
+			panic("Invalid DMA channel for iop1\n");
+		break;
+	case dma_ser0:
+		if (dmanr == 6)
+			strmux_cfg.dma6 = regk_strmux_ser0;
+		else if (dmanr == 7)
+			strmux_cfg.dma7 = regk_strmux_ser0;
+		else
+			panic("Invalid DMA channel for ser0\n");
+		break;
+	case dma_ser1:
+		if (dmanr == 4)
+			strmux_cfg.dma4 = regk_strmux_ser1;
+		else if (dmanr == 5)
+			strmux_cfg.dma5 = regk_strmux_ser1;
+		else
+			panic("Invalid DMA channel for ser1\n");
+		break;
+	case dma_ser2:
+		if (dmanr == 2)
+			strmux_cfg.dma2 = regk_strmux_ser2;
+		else if (dmanr == 3)
+			strmux_cfg.dma3 = regk_strmux_ser2;
+		else
+			panic("Invalid DMA channel for ser2\n");
+		break;
+	case dma_ser3:
+		if (dmanr == 8)
+			strmux_cfg.dma8 = regk_strmux_ser3;
+		else if (dmanr == 9)
+			strmux_cfg.dma9 = regk_strmux_ser3;
+		else
+			panic("Invalid DMA channel for ser3\n");
+		break;
+	case dma_sser0:
+		if (dmanr == 4)
+			strmux_cfg.dma4 = regk_strmux_sser0;
+		else if (dmanr == 5)
+			strmux_cfg.dma5 = regk_strmux_sser0;
+		else
+			panic("Invalid DMA channel for sser0\n");
+		break;
+	case dma_sser1:
+		if (dmanr == 6)
+			strmux_cfg.dma6 = regk_strmux_sser1;
+		else if (dmanr == 7)
+			strmux_cfg.dma7 = regk_strmux_sser1;
+		else
+			panic("Invalid DMA channel for sser1\n");
+		break;
+	case dma_ata:
+		if (dmanr == 2)
+			strmux_cfg.dma2 = regk_strmux_ata;
+		else if (dmanr == 3)
+			strmux_cfg.dma3 = regk_strmux_ata;
+		else
+			panic("Invalid DMA channel for ata\n");
+		break;
+	case dma_strp:
+		if (dmanr == 8)
+			strmux_cfg.dma8 = regk_strmux_strcop;
+		else if (dmanr == 9)
+			strmux_cfg.dma9 = regk_strmux_strcop;
+		else
+			panic("Invalid DMA channel for strp\n");
+		break;
+	case dma_ext0:
+		if (dmanr == 6)
+			strmux_cfg.dma6 = regk_strmux_ext0;
+		else
+			panic("Invalid DMA channel for ext0\n");
+		break;
+	case dma_ext1:
+		if (dmanr == 7)
+			strmux_cfg.dma7 = regk_strmux_ext1;
+		else
+			panic("Invalid DMA channel for ext1\n");
+		break;
+	case dma_ext2:
+		if (dmanr == 2)
+			strmux_cfg.dma2 = regk_strmux_ext2;
+		else if (dmanr == 8)
+			strmux_cfg.dma8 = regk_strmux_ext2;
+		else
+			panic("Invalid DMA channel for ext2\n");
+		break;
+	case dma_ext3:
+		if (dmanr == 3)
+			strmux_cfg.dma3 = regk_strmux_ext3;
+		else if (dmanr == 9)
+			strmux_cfg.dma9 = regk_strmux_ext2;
+		else
+			panic("Invalid DMA channel for ext2\n");
+		break;
+	}
+
+	used_dma_channels[dmanr] = 1;
+	used_dma_channels_users[dmanr] = device_id;
+	REG_WR(config, regi_config, rw_clk_ctrl, clk_ctrl);
+	REG_WR(strmux, regi_strmux, rw_cfg, strmux_cfg);
+	spin_unlock_irqrestore(&dma_lock,flags);
+	return 0;
+}
+
+void crisv32_free_dma(unsigned int dmanr)
+{
+	spin_lock(&dma_lock);
+	used_dma_channels[dmanr] = 0;
+	spin_unlock(&dma_lock);
+}
diff --git a/arch/cris/arch-v32/kernel/entry.S b/arch/cris/arch-v32/kernel/entry.S
new file mode 100644
--- /dev/null
+++ b/arch/cris/arch-v32/kernel/entry.S
@@ -0,0 +1,820 @@
+/*
+ *  Copyright (C) 2000-2003 Axis Communications AB
+ *
+ *  Authors:	Bjorn Wesen (bjornw@axis.com)
+ *              Tobias Anderberg (tobiasa@axis.com), CRISv32 port.
+ *
+ * Code for the system-call and fault low-level handling routines.
+ *
+ * NOTE: This code handles signal-recognition, which happens every time
+ * after a timer-interrupt and after each system call.
+ *
+ * Stack layout in 'ret_from_system_call':
+ * 	ptrace needs to have all regs on the stack.
+ *	if the order here is changed, it needs to be
+ *	updated in fork.c:copy_process, signal.c:do_signal,
+ *	ptrace.c and ptrace.h
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/linkage.h>
+#include <linux/sys.h>
+#include <asm/unistd.h>
+#include <asm/errno.h>
+#include <asm/thread_info.h>
+#include <asm/arch/offset.h>
+
+#include <asm/arch/hwregs/asm/reg_map_asm.h>
+#include <asm/arch/hwregs/asm/intr_vect_defs_asm.h>
+
+	;; Exported functions.
+	.globl system_call
+	.globl ret_from_intr
+	.globl ret_from_fork
+	.globl resume
+	.globl multiple_interrupt
+	.globl nmi_interrupt
+	.globl spurious_interrupt
+	.globl do_sigtrap
+	.globl gdb_handle_exception
+	.globl sys_call_table
+
+	; Check if preemptive kernel scheduling should be done.
+#ifdef CONFIG_PREEMPT
+_resume_kernel:
+	di
+	; Load current task struct.
+	movs.w	-8192, $r0		; THREAD_SIZE = 8192
+	and.d	$sp, $r0
+
+	addoq	+TI_preempt_count, $r0, $acr
+	move.d	[$acr], $r10		; Preemption disabled?
+	bne	_Rexit
+	nop
+
+_need_resched:
+	addoq	+TI_flags, $r0, $acr
+	move.d	[$acr], $r10
+	btstq	TIF_NEED_RESCHED, $r10	; Check if need_resched is set.
+	bpl	_Rexit
+	nop
+
+	; Do preemptive kernel scheduling.
+	jsr	preempt_schedule_irq
+	nop
+
+	; Load new task struct.
+	movs.w	-8192, $r0		; THREAD_SIZE = 8192.
+	and.d	$sp, $r0
+
+	; One more time with new task.
+	ba	_need_resched
+	nop
+#else
+#define _resume_kernel _Rexit
+#endif
+
+	; Called at exit from fork. schedule_tail must be called to drop
+	; spinlock if CONFIG_PREEMPT.
+ret_from_fork:
+	jsr schedule_tail
+	nop
+	ba  ret_from_sys_call
+	nop
+
+ret_from_intr:
+	;; Check for resched if preemptive kernel, or if we're going back to
+	;; user-mode. This test matches the user_regs(regs) macro. Don't simply
+	;; test CCS since that doesn't necessarily reflect what mode we'll
+	;; return into.
+	addoq	+PT_ccs, $sp, $acr
+	move.d	[$acr], $r0
+	btstq	16, $r0			; User-mode flag.
+	bpl	_resume_kernel
+
+	; Note that di below is in delay slot.
+
+_resume_userspace:
+	di			; So need_resched and sigpending don't change.
+
+	movs.w	-8192, $r0		; THREAD_SIZE == 8192
+	and.d	$sp, $r0
+
+	addoq	+TI_flags, $r0, $acr	; current->work
+	move.d	[$acr], $r10
+	and.d	_TIF_WORK_MASK, $r10	; Work to be done on return?
+	bne	_work_pending
+	nop
+	ba	_Rexit
+	nop
+
+	;; The system_call is called by a BREAK instruction, which looks pretty
+	;; much like any other exception.
+	;;
+	;; System calls can't be made from interrupts but we still stack ERP
+	;; to have a complete stack frame.
+	;;
+	;; In r9 we have the wanted syscall number. Arguments come in r10,r11,r12,
+	;; r13,mof,srp
+	;;
+	;; This function looks on the _surface_ like spaghetti programming, but it's
+	;; really designed so that the fast-path does not force cache-loading of
+	;; non-used instructions. Only the non-common cases cause the outlined code
+	;; to run..
+
+system_call:
+	;; Stack-frame similar to the irq heads, which is reversed in
+	;; ret_from_sys_call.
+	subq	12, $sp		; Skip EXS, EDA.
+	move	$erp, [$sp]
+	subq	4, $sp
+	move	$srp, [$sp]
+	subq	4, $sp
+	move	$ccs, [$sp]
+	subq	4, $sp
+	ei			; Allow IRQs while handling system call
+	move	$spc, [$sp]
+	subq	4, $sp
+	move	$mof, [$sp]
+	subq	4, $sp
+	move	$srs, [$sp]
+	subq	4, $sp
+	move.d	$acr, [$sp]
+	subq	14*4, $sp	; Make room for R0-R13.
+	movem	$r13, [$sp]	; Push R0-R13
+	subq	4, $sp
+	move.d	$r10, [$sp]	; Push orig_r10.
+
+; Set S-bit when kernel debugging to keep hardware breakpoints active.
+#ifdef CONFIG_ETRAX_KGDB
+	move $ccs, $r0
+	or.d (1<<9), $r0
+	move $r0, $ccs
+#endif
+
+	movs.w	-ENOSYS, $r0
+	addoq	+PT_r10, $sp, $acr
+	move.d	$r0, [$acr]
+
+	;; Check if this process is syscall-traced.
+	movs.w	-8192, $r0	; THREAD_SIZE == 8192
+	and.d	$sp, $r0
+
+	addoq	+TI_flags, $r0, $acr
+	move.d	[$acr], $r0
+	btstq	TIF_SYSCALL_TRACE, $r0
+	bmi	_syscall_trace_entry
+	nop
+
+_syscall_traced:
+	;; Check for sanity in the requested syscall number.
+	cmpu.w	NR_syscalls, $r9
+	bhs	ret_from_sys_call
+	lslq	2, $r9		;  Multiply by 4, in the delay slot.
+
+	;; The location on the stack for the register structure is passed as a
+	;; seventh argument. Some system calls need this.
+	move.d  $sp, $r0
+	subq	4, $sp
+	move.d	$r0, [$sp]
+
+	;; The registers carrying parameters (R10-R13) are intact. The optional
+	;; fifth and sixth parameters is in MOF and SRP respectivly. Put them
+	;; back on the stack.
+	subq	4, $sp
+	move	$srp, [$sp]
+	subq	4, $sp
+	move	$mof, [$sp]
+
+	;; Actually to the system call.
+	addo.d	+sys_call_table, $r9, $acr
+	move.d	[$acr], $acr
+	jsr	$acr
+	nop
+
+	addq	3*4, $sp		; Pop the mof, srp and regs parameters.
+	addoq	+PT_r10, $sp, $acr
+	move.d	$r10, [$acr]		; Save the return value.
+
+	moveq	1, $r9			; "Parameter" to ret_from_sys_call to
+					; show it was a sys call.
+
+	;; Fall through into ret_from_sys_call to return.
+
+ret_from_sys_call:
+	;; R9 is a parameter:
+	;;  >= 1 from syscall
+	;;     0 from irq
+
+	;; Get the current task-struct pointer.
+	movs.w	-8192, $r0	; THREAD_SIZE == 8192
+	and.d	$sp, $r0
+
+	di		; Make sure need_resched and sigpending don't change.
+
+	addoq	+TI_flags, $r0, $acr
+	move.d	[$acr], $r1
+	and.d	_TIF_ALLWORK_MASK, $r1
+	bne	_syscall_exit_work
+	nop
+
+_Rexit:
+	;; This epilogue MUST match the prologues in multiple_interrupt, irq.h
+	;; and ptregs.h.
+	addq	4, $sp		; Skip orig_r10.
+	movem	[$sp+], $r13	; Registers R0-R13.
+	move.d	[$sp+], $acr
+	move	[$sp], $srs
+	addq	4, $sp
+	move	[$sp+], $mof
+	move	[$sp+], $spc
+	move	[$sp+], $ccs
+	move	[$sp+], $srp
+	move	[$sp+], $erp
+	addq    8, $sp		; Skip EXS, EDA.
+	jump	$erp
+	rfe			; Restore condition code stack in delay-slot.
+
+	;; We get here after doing a syscall if extra work might need to be done
+	;; perform syscall exit tracing if needed.
+
+_syscall_exit_work:
+	;; R0 contains current at this point and irq's are disabled.
+
+	addoq	+TI_flags, $r0, $acr
+	move.d	[$acr], $r1
+	btstq	TIF_SYSCALL_TRACE, $r1
+	bpl	_work_pending
+	nop
+	ei
+	move.d	$r9, $r1		; Preserve R9.
+	jsr	do_syscall_trace
+	nop
+	move.d	$r1, $r9
+	ba	_resume_userspace
+	nop
+
+_work_pending:
+	addoq	+TI_flags, $r0, $acr
+	move.d	[$acr], $r10
+	btstq	TIF_NEED_RESCHED, $r10	; Need resched?
+	bpl	_work_notifysig		; No, must be signal/notify.
+	nop
+
+_work_resched:
+	move.d	$r9, $r1		; Preserve R9.
+	jsr	schedule
+	nop
+	move.d	$r1, $r9
+	di
+
+	addoq	+TI_flags, $r0, $acr
+	move.d	[$acr], $r1
+	and.d	_TIF_WORK_MASK, $r1	; Ignore sycall trace counter.
+	beq	_Rexit
+	nop
+	btstq	TIF_NEED_RESCHED, $r1
+	bmi	_work_resched		; current->work.need_resched.
+	nop
+
+_work_notifysig:
+	;; Deal with pending signals and notify-resume requests.
+
+	addoq	+TI_flags, $r0, $acr
+	move.d	[$acr], $r13		; The thread_info_flags parameter.
+	move.d	$r9, $r10		; do_notify_resume syscall/irq param.
+	moveq	0, $r11			; oldset param - 0 in this case.
+	move.d	$sp, $r12		; The regs param.
+	jsr	do_notify_resume
+	nop
+
+	ba _Rexit
+	nop
+
+	;; We get here as a sidetrack when we've entered a syscall with the
+	;; trace-bit set. We need to call do_syscall_trace and then continue
+	;; with the call.
+
+_syscall_trace_entry:
+	;; PT_r10 in the frame contains -ENOSYS as required, at this point.
+
+	jsr	do_syscall_trace
+	nop
+
+	;; Now re-enter the syscall code to do the syscall itself. We need to
+	;; restore R9 here to contain the wanted syscall, and the other
+	;; parameter-bearing registers.
+	addoq	+PT_r9, $sp, $acr
+	move.d	[$acr], $r9
+	addoq	+PT_orig_r10, $sp, $acr
+	move.d	[$acr], $r10		; PT_r10 is already -ENOSYS.
+	addoq	+PT_r11, $sp, $acr
+	move.d	[$acr], $r11
+	addoq	+PT_r12, $sp, $acr
+	move.d	[$acr], $r12
+	addoq	+PT_r13, $sp, $acr
+	move.d	[$acr], $r13
+	addoq	+PT_mof, $sp, $acr
+	move	[$acr], $mof
+	addoq	+PT_srp, $sp, $acr
+	move	[$acr], $srp
+
+	ba	_syscall_traced
+	nop
+
+	;; Resume performs the actual task-switching, by switching stack
+	;; pointers. Input arguments are:
+	;;
+	;; R10 = prev
+	;; R11 = next
+	;; R12 = thread offset in task struct.
+	;;
+	;; Returns old current in R10.
+
+resume:
+	subq	4, $sp
+	move	$srp, [$sp]		; Keep old/new PC on the stack.
+	add.d	$r12, $r10		; R10 = current tasks tss.
+	addoq	+THREAD_ccs, $r10, $acr
+	move	$ccs, [$acr]		; Save IRQ enable state.
+	di
+
+	addoq	+THREAD_usp, $r10, $acr
+	move	$usp, [$acr]		; Save user-mode stackpointer.
+
+	;; See copy_thread for the reason why register R9 is saved.
+	subq	10*4, $sp
+	movem	$r9, [$sp]		; Save non-scratch registers and R9.
+
+	addoq	+THREAD_ksp, $r10, $acr
+	move.d	$sp, [$acr]		; Save kernel SP for old task.
+
+	move.d	$sp, $r10		; Return last running task in R10.
+	and.d   -8192, $r10		; Get thread_info from stackpointer.
+	addoq	+TI_task, $r10, $acr
+	move.d	[$acr], $r10		; Get task.
+	add.d	$r12, $r11		; Find the new tasks tss.
+	addoq	+THREAD_ksp, $r11, $acr
+	move.d	[$acr], $sp		; Switch to new stackframe.
+	movem	[$sp+], $r9		; Restore non-scratch registers and R9.
+
+	addoq	+THREAD_usp, $r11, $acr
+	move	[$acr], $usp		; Restore user-mode stackpointer.
+
+	addoq	+THREAD_ccs, $r11, $acr
+	move	[$acr], $ccs		; Restore IRQ enable status.
+	move.d	[$sp+], $acr
+	jump	$acr			; Restore PC.
+	nop
+
+nmi_interrupt:
+
+;; If we receive a watchdog interrupt while it is not expected, then set
+;; up a canonical frame and dump register contents before dying.
+
+	;; This prologue MUST match the one in irq.h and the struct in ptregs.h!
+	subq	12, $sp		;  Skip EXS, EDA.
+	move	$nrp, [$sp]
+	subq	4, $sp
+	move	$srp, [$sp]
+	subq	4, $sp
+	move	$ccs, [$sp]
+	subq	4, $sp
+	move	$spc, [$sp]
+	subq	4, $sp
+	move	$mof, [$sp]
+	subq	4, $sp
+	move	$srs, [$sp]
+	subq	4, $sp
+	move.d	$acr, [$sp]
+	subq	14*4, $sp		; Make room for R0-R13.
+	movem	$r13, [$sp]		; Push R0-R13.
+	subq	4, $sp
+	move.d	$r10, [$sp]		; Push orig_r10.
+	move.d  REG_ADDR(intr_vect, regi_irq, r_nmi), $r0
+	move.d  [$r0], $r0
+	btstq	REG_BIT(intr_vect, r_nmi, watchdog), $r0
+	bpl     1f
+	nop
+	jsr 	handle_watchdog_bite	; In time.c.
+        move.d	$sp, $r10		; Pointer to registers
+1:	btstq	REG_BIT(intr_vect, r_nmi, ext), $r0
+	bpl     1f
+	nop
+	jsr	handle_nmi
+	move.d	$sp, $r10		; Pointer to registers
+1:	addq    4, $sp			; Skip orig_r10
+	movem   [$sp+], $r13
+	move.d  [$sp+], $acr
+	move    [$sp], $srs
+	addq    4, $sp
+	move    [$sp+], $mof
+	move    [$sp+], $spc
+	move    [$sp+], $ccs
+	move	[$sp+], $srp
+	move	[$sp+], $nrp
+	addq    8, $sp			; Skip EXS, EDA.
+	jump    $nrp
+	rfn
+
+	.comm	cause_of_death, 4	;; Don't declare this anywhere.
+
+spurious_interrupt:
+	di
+	jump hard_reset_now
+	nop
+
+	;; This handles the case when multiple interrupts arrive at the same
+	;; time. Jump to the first set interrupt bit in a priotiry fashion. The
+	;; hardware will call the unserved interrupts after the handler
+	;; finishes.
+multiple_interrupt:
+	;; This prologue MUST match the one in irq.h and the struct in ptregs.h!
+	subq	12, $sp		; Skip EXS, EDA.
+	move	$erp, [$sp]
+	subq	4, $sp
+	move	$srp, [$sp]
+	subq	4, $sp
+	move	$ccs, [$sp]
+	subq	4, $sp
+	move	$spc, [$sp]
+	subq	4, $sp
+	move	$mof, [$sp]
+	subq	4, $sp
+	move	$srs, [$sp]
+	subq	4, $sp
+	move.d	$acr, [$sp]
+	subq	14*4, $sp	; Make room for R0-R13.
+	movem	$r13, [$sp]	; Push R0-R13.
+	subq	4, $sp
+	move.d	$r10, [$sp]	; Push orig_r10.
+
+; Set S-bit when kernel debugging to keep hardware breakpoints active.
+#ifdef CONFIG_ETRAX_KGDB
+	move $ccs, $r0
+	or.d (1<<9), $r0
+	move $r0, $ccs
+#endif
+
+	jsr	crisv32_do_multiple
+	move.d	$sp, $r10
+	jump    ret_from_intr
+	nop
+
+do_sigtrap:
+	;; Sigtraps the process that executed the BREAK instruction. Creates a
+	;; frame that Rexit expects.
+	subq	4, $sp
+	move    $eda, [$sp]
+	subq    4, $sp
+	move    $exs, [$sp]
+	subq    4, $sp
+	move	$erp, [$sp]
+	subq	4, $sp
+	move	$srp, [$sp]
+	subq	4, $sp
+	move	$ccs, [$sp]
+	subq	4, $sp
+	move	$spc, [$sp]
+	subq	4, $sp
+	move	$mof, [$sp]
+	subq	4, $sp
+	move	$srs, [$sp]
+	subq	4, $sp
+	move.d	$acr, [$sp]
+	di				; Need to disable irq's at this point.
+	subq	14*4, $sp		; Make room for r0-r13.
+	movem	$r13, [$sp]		; Push the r0-r13 registers.
+	subq	4, $sp
+	move.d	$r10, [$sp]		; Push orig_r10.
+
+	movs.w	-8192, $r9		; THREAD_SIZE == 8192
+	and.d	$sp, $r9
+
+	;; thread_info as first parameter
+	move.d  $r9, $r10
+	moveq	5, $r11			; SIGTRAP as second argument.
+	jsr	ugdb_trap_user
+	nop
+	jump	ret_from_intr		; Use the return routine for interrupts.
+	nop
+
+gdb_handle_exception:
+	subq	4, $sp
+	move.d	$r0, [$sp]
+#ifdef CONFIG_ETRAX_KGDB
+	move	$ccs, $r0		; U-flag not affected by previous insns.
+	btstq	16, $r0			; Test the U-flag.
+	bmi	_ugdb_handle_exception	; Go to user mode debugging.
+	nop				; Empty delay-slot (cannot pop R0 here).
+	ba	kgdb_handle_exception	; Go to kernel debugging.
+	move.d	[$sp+], $r0		; Restore R0 in delay slot.
+#endif
+
+_ugdb_handle_exception:
+	ba	do_sigtrap		; SIGTRAP the offending process.
+	move.d	[$sp+], $r0		; Restore R0 in delay slot.
+
+	.data
+
+	.section .rodata,"a"
+sys_call_table:
+	.long sys_restart_syscall	; 0 - old "setup()" system call, used
+					; for restarting.
+	.long sys_exit
+	.long sys_fork
+	.long sys_read
+	.long sys_write
+	.long sys_open		/* 5 */
+	.long sys_close
+	.long sys_waitpid
+	.long sys_creat
+	.long sys_link
+	.long sys_unlink	/* 10 */
+	.long sys_execve
+	.long sys_chdir
+	.long sys_time
+	.long sys_mknod
+	.long sys_chmod		/* 15 */
+	.long sys_lchown16
+	.long sys_ni_syscall	/* old break syscall holder */
+	.long sys_stat
+	.long sys_lseek
+	.long sys_getpid	/* 20 */
+	.long sys_mount
+	.long sys_oldumount
+	.long sys_setuid16
+	.long sys_getuid16
+	.long sys_stime		/* 25 */
+	.long sys_ptrace
+	.long sys_alarm
+	.long sys_fstat
+	.long sys_pause
+	.long sys_utime		/* 30 */
+	.long sys_ni_syscall	/* old stty syscall holder */
+	.long sys_ni_syscall	/* old gtty syscall holder */
+	.long sys_access
+	.long sys_nice
+	.long sys_ni_syscall	/* 35  old ftime syscall holder */
+	.long sys_sync
+	.long sys_kill
+	.long sys_rename
+	.long sys_mkdir
+	.long sys_rmdir		/* 40 */
+	.long sys_dup
+	.long sys_pipe
+	.long sys_times
+	.long sys_ni_syscall	/* old prof syscall holder */
+	.long sys_brk		/* 45 */
+	.long sys_setgid16
+	.long sys_getgid16
+	.long sys_signal
+	.long sys_geteuid16
+	.long sys_getegid16	/* 50 */
+	.long sys_acct
+	.long sys_umount	/* recycled never used phys( */
+	.long sys_ni_syscall	/* old lock syscall holder */
+	.long sys_ioctl
+	.long sys_fcntl		/* 55 */
+	.long sys_ni_syscall	/* old mpx syscall holder */
+	.long sys_setpgid
+	.long sys_ni_syscall	/* old ulimit syscall holder */
+	.long sys_ni_syscall	/* old sys_olduname holder */
+	.long sys_umask		/* 60 */
+	.long sys_chroot
+	.long sys_ustat
+	.long sys_dup2
+	.long sys_getppid
+	.long sys_getpgrp	/* 65 */
+	.long sys_setsid
+	.long sys_sigaction
+	.long sys_sgetmask
+	.long sys_ssetmask
+	.long sys_setreuid16	/* 70 */
+	.long sys_setregid16
+	.long sys_sigsuspend
+	.long sys_sigpending
+	.long sys_sethostname
+	.long sys_setrlimit	/* 75 */
+	.long sys_old_getrlimit
+	.long sys_getrusage
+	.long sys_gettimeofday
+	.long sys_settimeofday
+	.long sys_getgroups16	/* 80 */
+	.long sys_setgroups16
+	.long sys_select	/* was old_select in Linux/E100 */
+	.long sys_symlink
+	.long sys_lstat
+	.long sys_readlink	/* 85 */
+	.long sys_uselib
+	.long sys_swapon
+	.long sys_reboot
+	.long old_readdir
+	.long old_mmap		/* 90 */
+	.long sys_munmap
+	.long sys_truncate
+	.long sys_ftruncate
+	.long sys_fchmod
+	.long sys_fchown16	/* 95 */
+	.long sys_getpriority
+	.long sys_setpriority
+	.long sys_ni_syscall	/* old profil syscall holder */
+	.long sys_statfs
+	.long sys_fstatfs	/* 100 */
+	.long sys_ni_syscall	/* sys_ioperm in i386 */
+	.long sys_socketcall
+	.long sys_syslog
+	.long sys_setitimer
+	.long sys_getitimer	/* 105 */
+	.long sys_newstat
+	.long sys_newlstat
+	.long sys_newfstat
+	.long sys_ni_syscall	/* old sys_uname holder */
+	.long sys_ni_syscall	/* sys_iopl in i386 */
+	.long sys_vhangup
+	.long sys_ni_syscall	/* old "idle" system call */
+	.long sys_ni_syscall	/* vm86old in i386 */
+	.long sys_wait4
+	.long sys_swapoff	/* 115 */
+	.long sys_sysinfo
+	.long sys_ipc
+	.long sys_fsync
+	.long sys_sigreturn
+	.long sys_clone		/* 120 */
+	.long sys_setdomainname
+	.long sys_newuname
+	.long sys_ni_syscall	/* sys_modify_ldt */
+	.long sys_adjtimex
+	.long sys_mprotect	/* 125 */
+	.long sys_sigprocmask
+	.long sys_ni_syscall	/* old "create_module" */
+	.long sys_init_module
+	.long sys_delete_module
+	.long sys_ni_syscall	/* 130:	old "get_kernel_syms" */
+	.long sys_quotactl
+	.long sys_getpgid
+	.long sys_fchdir
+	.long sys_bdflush
+	.long sys_sysfs		/* 135 */
+	.long sys_personality
+	.long sys_ni_syscall	/* for afs_syscall */
+	.long sys_setfsuid16
+	.long sys_setfsgid16
+	.long sys_llseek	/* 140 */
+	.long sys_getdents
+	.long sys_select
+	.long sys_flock
+	.long sys_msync
+	.long sys_readv		/* 145 */
+	.long sys_writev
+	.long sys_getsid
+	.long sys_fdatasync
+	.long sys_sysctl
+	.long sys_mlock		/* 150 */
+	.long sys_munlock
+	.long sys_mlockall
+	.long sys_munlockall
+	.long sys_sched_setparam
+	.long sys_sched_getparam	/* 155 */
+	.long sys_sched_setscheduler
+	.long sys_sched_getscheduler
+	.long sys_sched_yield
+	.long sys_sched_get_priority_max
+	.long sys_sched_get_priority_min	/* 160 */
+	.long sys_sched_rr_get_interval
+	.long sys_nanosleep
+	.long sys_mremap
+	.long sys_setresuid16
+	.long sys_getresuid16	/* 165 */
+	.long sys_ni_syscall	/* sys_vm86 */
+	.long sys_ni_syscall	/* Old sys_query_module */
+	.long sys_poll
+	.long sys_nfsservctl
+	.long sys_setresgid16	/* 170 */
+	.long sys_getresgid16
+	.long sys_prctl
+	.long sys_rt_sigreturn
+	.long sys_rt_sigaction
+	.long sys_rt_sigprocmask	/* 175 */
+	.long sys_rt_sigpending
+	.long sys_rt_sigtimedwait
+	.long sys_rt_sigqueueinfo
+	.long sys_rt_sigsuspend
+	.long sys_pread64	/* 180 */
+	.long sys_pwrite64
+	.long sys_chown16
+	.long sys_getcwd
+	.long sys_capget
+	.long sys_capset	/* 185 */
+	.long sys_sigaltstack
+	.long sys_sendfile
+	.long sys_ni_syscall	/* streams1 */
+	.long sys_ni_syscall	/* streams2 */
+	.long sys_vfork		/* 190 */
+	.long sys_getrlimit
+	.long sys_mmap2
+	.long sys_truncate64
+	.long sys_ftruncate64
+	.long sys_stat64	/* 195 */
+	.long sys_lstat64
+	.long sys_fstat64
+	.long sys_lchown
+	.long sys_getuid
+	.long sys_getgid	/* 200 */
+	.long sys_geteuid
+	.long sys_getegid
+	.long sys_setreuid
+	.long sys_setregid
+	.long sys_getgroups	/* 205 */
+	.long sys_setgroups
+	.long sys_fchown
+	.long sys_setresuid
+	.long sys_getresuid
+	.long sys_setresgid	/* 210 */
+	.long sys_getresgid
+	.long sys_chown
+	.long sys_setuid
+	.long sys_setgid
+	.long sys_setfsuid	/* 215 */
+	.long sys_setfsgid
+	.long sys_pivot_root
+	.long sys_mincore
+	.long sys_madvise
+	.long sys_getdents64	/* 220 */
+	.long sys_fcntl64
+	.long sys_ni_syscall	/* reserved for TUX */
+	.long sys_ni_syscall
+	.long sys_gettid
+	.long sys_readahead	/* 225 */
+	.long sys_setxattr
+	.long sys_lsetxattr
+	.long sys_fsetxattr
+	.long sys_getxattr
+	.long sys_lgetxattr	/* 230 */
+	.long sys_fgetxattr
+	.long sys_listxattr
+	.long sys_llistxattr
+	.long sys_flistxattr
+	.long sys_removexattr	/* 235 */
+	.long sys_lremovexattr
+	.long sys_fremovexattr
+	.long sys_tkill
+	.long sys_sendfile64
+	.long sys_futex		/* 240 */
+	.long sys_sched_setaffinity
+	.long sys_sched_getaffinity
+	.long sys_ni_syscall	/* sys_set_thread_area */
+	.long sys_ni_syscall	/* sys_get_thread_area */
+	.long sys_io_setup	/* 245 */
+	.long sys_io_destroy
+	.long sys_io_getevents
+	.long sys_io_submit
+	.long sys_io_cancel
+	.long sys_fadvise64	/* 250 */
+	.long sys_ni_syscall
+	.long sys_exit_group
+	.long sys_lookup_dcookie
+	.long sys_epoll_create
+	.long sys_epoll_ctl	/* 255 */
+	.long sys_epoll_wait
+	.long sys_remap_file_pages
+ 	.long sys_set_tid_address
+ 	.long sys_timer_create
+ 	.long sys_timer_settime		/* 260 */
+ 	.long sys_timer_gettime
+ 	.long sys_timer_getoverrun
+ 	.long sys_timer_delete
+ 	.long sys_clock_settime
+ 	.long sys_clock_gettime		/* 265 */
+ 	.long sys_clock_getres
+ 	.long sys_clock_nanosleep
+	.long sys_statfs64
+	.long sys_fstatfs64
+	.long sys_tgkill	/* 270 */
+	.long sys_utimes
+ 	.long sys_fadvise64_64
+	.long sys_ni_syscall	/* sys_vserver */
+	.long sys_ni_syscall	/* sys_mbind */
+	.long sys_ni_syscall	/* 275 sys_get_mempolicy */
+	.long sys_ni_syscall	/* sys_set_mempolicy */
+	.long sys_mq_open
+	.long sys_mq_unlink
+	.long sys_mq_timedsend
+	.long sys_mq_timedreceive	/* 280 */
+	.long sys_mq_notify
+	.long sys_mq_getsetattr
+	.long sys_ni_syscall		/* reserved for kexec */
+	.long sys_waitid
+
+        /*
+         * NOTE!! This doesn't have to be exact - we just have
+         * to make sure we have _enough_ of the "sys_ni_syscall"
+         * entries. Don't panic if you notice that this hasn't
+         * been shrunk every time we add a new system call.
+         */
+
+	.rept NR_syscalls - (.-sys_call_table) / 4
+		.long sys_ni_syscall
+	.endr
+
diff --git a/arch/cris/arch-v32/kernel/fasttimer.c b/arch/cris/arch-v32/kernel/fasttimer.c
new file mode 100644
--- /dev/null
+++ b/arch/cris/arch-v32/kernel/fasttimer.c
@@ -0,0 +1,996 @@
+/* $Id: fasttimer.c,v 1.11 2005/01/04 11:15:46 starvik Exp $
+ * linux/arch/cris/kernel/fasttimer.c
+ *
+ * Fast timers for ETRAX FS
+ * This may be useful in other OS than Linux so use 2 space indentation...
+ *
+ * $Log: fasttimer.c,v $
+ * Revision 1.11  2005/01/04 11:15:46  starvik
+ * Don't share timer IRQ.
+ *
+ * Revision 1.10  2004/12/07 09:19:38  starvik
+ * Corrected includes.
+ * Use correct interrupt macros.
+ *
+ * Revision 1.9  2004/05/14 10:18:58  starvik
+ * Export fast_timer_list
+ *
+ * Revision 1.8  2004/05/14 07:58:03  starvik
+ * Merge of changes from 2.4
+ *
+ * Revision 1.7  2003/07/10 12:06:14  starvik
+ * Return IRQ_NONE if irq wasn't handled
+ *
+ * Revision 1.6  2003/07/04 08:27:49  starvik
+ * Merge of Linux 2.5.74
+ *
+ * Revision 1.5  2003/06/05 10:16:22  johana
+ * New INTR_VECT macros.
+ *
+ * Revision 1.4  2003/06/03 08:49:45  johana
+ * Fixed typo.
+ *
+ * Revision 1.3  2003/06/02 12:51:27  johana
+ * Now compiles.
+ * Commented some include files that probably can be removed.
+ *
+ * Revision 1.2  2003/06/02 12:09:41  johana
+ * Ported to ETRAX FS using the trig interrupt instead of timer1.
+ *
+ * Revision 1.3  2002/12/12 08:26:32  starvik
+ * Don't use C-comments inside CVS comments
+ *
+ * Revision 1.2  2002/12/11 15:42:02  starvik
+ * Extracted v10 (ETRAX 100LX) specific stuff from arch/cris/kernel/
+ *
+ * Revision 1.1  2002/11/18 07:58:06  starvik
+ * Fast timers (from Linux 2.4)
+ *
+ * Revision 1.5  2002/10/15 06:21:39  starvik
+ * Added call to init_waitqueue_head
+ *
+ * Revision 1.4  2002/05/28 17:47:59  johana
+ * Added del_fast_timer()
+ *
+ * Revision 1.3  2002/05/28 16:16:07  johana
+ * Handle empty fast_timer_list
+ *
+ * Revision 1.2  2002/05/27 15:38:42  johana
+ * Made it compile without warnings on Linux 2.4.
+ * (includes, wait_queue, PROC_FS and snprintf)
+ *
+ * Revision 1.1  2002/05/27 15:32:25  johana
+ * arch/etrax100/kernel/fasttimer.c v1.8 from the elinux tree.
+ *
+ * Revision 1.8  2001/11/27 13:50:40  pkj
+ * Disable interrupts while stopping the timer and while modifying the
+ * list of active timers in timer1_handler() as it may be interrupted
+ * by other interrupts (e.g., the serial interrupt) which may add fast
+ * timers.
+ *
+ * Revision 1.7  2001/11/22 11:50:32  pkj
+ * * Only store information about the last 16 timers.
+ * * proc_fasttimer_read() now uses an allocated buffer, since it
+ *   requires more space than just a page even for only writing the
+ *   last 16 timers. The buffer is only allocated on request, so
+ *   unless /proc/fasttimer is read, it is never allocated.
+ * * Renamed fast_timer_started to fast_timers_started to match
+ *   fast_timers_added and fast_timers_expired.
+ * * Some clean-up.
+ *
+ * Revision 1.6  2000/12/13 14:02:08  johana
+ * Removed volatile for fast_timer_list
+ *
+ * Revision 1.5  2000/12/13 13:55:35  johana
+ * Added DEBUG_LOG, added som cli() and cleanup
+ *
+ * Revision 1.4  2000/12/05 13:48:50  johana
+ * Added range check when writing proc file, modified timer int handling
+ *
+ * Revision 1.3  2000/11/23 10:10:20  johana
+ * More debug/logging possibilities.
+ * Moved GET_JIFFIES_USEC() to timex.h and time.c
+ *
+ * Revision 1.2  2000/11/01 13:41:04  johana
+ * Clean up and bugfixes.
+ * Created new do_gettimeofday_fast() that gets a timeval struct
+ * with time based on jiffies and *R_TIMER0_DATA, uses a table
+ * for fast conversion of timer value to microseconds.
+ * (Much faster the standard do_gettimeofday() and we don't really
+ * wan't to use the true time - we wan't the "uptime" so timers don't screw up
+ * when we change the time.
+ * TODO: Add efficient support for continuous timers as well.
+ *
+ * Revision 1.1  2000/10/26 15:49:16  johana
+ * Added fasttimer, highresolution timers.
+ *
+ * Copyright (C) 2000,2001 2002, 2003 Axis Communications AB, Lund, Sweden
+ */
+
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/string.h>
+#include <linux/vmalloc.h>
+#include <linux/interrupt.h>
+#include <linux/time.h>
+#include <linux/delay.h>
+
+#include <asm/irq.h>
+#include <asm/system.h>
+
+#include <linux/config.h>
+#include <linux/version.h>
+
+#include <asm/arch/hwregs/reg_map.h>
+#include <asm/arch/hwregs/reg_rdwr.h>
+#include <asm/arch/hwregs/timer_defs.h>
+#include <asm/fasttimer.h>
+#include <linux/proc_fs.h>
+
+/*
+ * timer0 is running at 100MHz and generating jiffies timer ticks
+ * at 100 or 1000 HZ.
+ * fasttimer gives an API that gives timers that expire "between" the jiffies
+ * giving microsecond resolution (10 ns).
+ * fasttimer uses reg_timer_rw_trig register to get interrupt when
+ * r_time reaches a certain value.
+ */
+
+
+#define DEBUG_LOG_INCLUDED
+#define FAST_TIMER_LOG
+//#define FAST_TIMER_TEST
+
+#define FAST_TIMER_SANITY_CHECKS
+
+#ifdef FAST_TIMER_SANITY_CHECKS
+#define SANITYCHECK(x) x
+static int sanity_failed = 0;
+#else
+#define SANITYCHECK(x)
+#endif
+
+#define D1(x)
+#define D2(x)
+#define DP(x)
+
+#define __INLINE__ inline
+
+static int fast_timer_running = 0;
+static int fast_timers_added = 0;
+static int fast_timers_started = 0;
+static int fast_timers_expired = 0;
+static int fast_timers_deleted = 0;
+static int fast_timer_is_init = 0;
+static int fast_timer_ints = 0;
+
+struct fast_timer *fast_timer_list = NULL;
+
+#ifdef DEBUG_LOG_INCLUDED
+#define DEBUG_LOG_MAX 128
+static const char * debug_log_string[DEBUG_LOG_MAX];
+static unsigned long debug_log_value[DEBUG_LOG_MAX];
+static int debug_log_cnt = 0;
+static int debug_log_cnt_wrapped = 0;
+
+#define DEBUG_LOG(string, value) \
+{ \
+  unsigned long log_flags; \
+  local_irq_save(log_flags); \
+  debug_log_string[debug_log_cnt] = (string); \
+  debug_log_value[debug_log_cnt] = (unsigned long)(value); \
+  if (++debug_log_cnt >= DEBUG_LOG_MAX) \
+  { \
+    debug_log_cnt = debug_log_cnt % DEBUG_LOG_MAX; \
+    debug_log_cnt_wrapped = 1; \
+  } \
+  local_irq_restore(log_flags); \
+}
+#else
+#define DEBUG_LOG(string, value)
+#endif
+
+
+#define NUM_TIMER_STATS 16
+#ifdef FAST_TIMER_LOG
+struct fast_timer timer_added_log[NUM_TIMER_STATS];
+struct fast_timer timer_started_log[NUM_TIMER_STATS];
+struct fast_timer timer_expired_log[NUM_TIMER_STATS];
+#endif
+
+int timer_div_settings[NUM_TIMER_STATS];
+int timer_delay_settings[NUM_TIMER_STATS];
+
+
+static void
+timer_trig_handler(void);
+
+
+
+/* Not true gettimeofday, only checks the jiffies (uptime) + useconds */
+void __INLINE__ do_gettimeofday_fast(struct timeval *tv)
+{
+  unsigned long sec = jiffies;
+  unsigned long usec = GET_JIFFIES_USEC();
+
+  usec += (sec % HZ) * (1000000 / HZ);
+  sec = sec / HZ;
+
+  if (usec > 1000000)
+  {
+    usec -= 1000000;
+    sec++;
+  }
+  tv->tv_sec = sec;
+  tv->tv_usec = usec;
+}
+
+int __INLINE__ timeval_cmp(struct timeval *t0, struct timeval *t1)
+{
+  if (t0->tv_sec < t1->tv_sec)
+  {
+    return -1;
+  }
+  else if (t0->tv_sec > t1->tv_sec)
+  {
+    return 1;
+  }
+  if (t0->tv_usec < t1->tv_usec)
+  {
+    return -1;
+  }
+  else if (t0->tv_usec > t1->tv_usec)
+  {
+    return 1;
+  }
+  return 0;
+}
+
+/* Called with ints off */
+void __INLINE__ start_timer_trig(unsigned long delay_us)
+{
+  reg_timer_rw_ack_intr ack_intr = { 0 };
+  reg_timer_rw_intr_mask intr_mask;
+  reg_timer_rw_trig trig;
+  reg_timer_rw_trig_cfg trig_cfg = { 0 };
+  reg_timer_r_time r_time;
+
+  r_time = REG_RD(timer, regi_timer, r_time);
+
+  D1(printk("start_timer_trig : %d us freq: %i div: %i\n",
+            delay_us, freq_index, div));
+  /* Clear trig irq */
+  intr_mask = REG_RD(timer, regi_timer, rw_intr_mask);
+  intr_mask.trig = 0;
+  REG_WR(timer, regi_timer, rw_intr_mask, intr_mask);
+
+  /* Set timer values */
+  /* r_time is 100MHz (10 ns resolution) */
+  trig = r_time + delay_us*(1000/10);
+
+  timer_div_settings[fast_timers_started % NUM_TIMER_STATS] = trig;
+  timer_delay_settings[fast_timers_started % NUM_TIMER_STATS] = delay_us;
+
+  /* Ack interrupt */
+  ack_intr.trig = 1;
+  REG_WR(timer, regi_timer, rw_ack_intr, ack_intr);
+
+  /* Start timer */
+  REG_WR(timer, regi_timer, rw_trig, trig);
+  trig_cfg.tmr = regk_timer_time;
+  REG_WR(timer, regi_timer, rw_trig_cfg, trig_cfg);
+
+  /* Check if we have already passed the trig time */
+  r_time = REG_RD(timer, regi_timer, r_time);
+  if (r_time < trig) {
+    /* No, Enable trig irq */
+    intr_mask = REG_RD(timer, regi_timer, rw_intr_mask);
+    intr_mask.trig = 1;
+    REG_WR(timer, regi_timer, rw_intr_mask, intr_mask);
+    fast_timers_started++;
+    fast_timer_running = 1;
+  }
+  else
+  {
+    /* We have passed the time, disable trig point, ack intr */
+    trig_cfg.tmr = regk_timer_off;
+    REG_WR(timer, regi_timer, rw_trig_cfg, trig_cfg);
+    REG_WR(timer, regi_timer, rw_ack_intr, ack_intr);
+    /* call the int routine directly */
+    timer_trig_handler();
+  }
+
+}
+
+/* In version 1.4 this function takes 27 - 50 us */
+void start_one_shot_timer(struct fast_timer *t,
+                          fast_timer_function_type *function,
+                          unsigned long data,
+                          unsigned long delay_us,
+                          const char *name)
+{
+  unsigned long flags;
+  struct fast_timer *tmp;
+
+  D1(printk("sft %s %d us\n", name, delay_us));
+
+  local_irq_save(flags);
+
+  do_gettimeofday_fast(&t->tv_set);
+  tmp = fast_timer_list;
+
+  SANITYCHECK({ /* Check so this is not in the list already... */
+    while (tmp != NULL)
+    {
+      if (tmp == t)
+      {
+        printk("timer name: %s data: 0x%08lX already in list!\n", name, data);
+        sanity_failed++;
+        return;
+      }
+      else
+      {
+        tmp = tmp->next;
+      }
+    }
+    tmp = fast_timer_list;
+  });
+
+  t->delay_us = delay_us;
+  t->function = function;
+  t->data = data;
+  t->name = name;
+
+  t->tv_expires.tv_usec = t->tv_set.tv_usec + delay_us % 1000000;
+  t->tv_expires.tv_sec  = t->tv_set.tv_sec  + delay_us / 1000000;
+  if (t->tv_expires.tv_usec > 1000000)
+  {
+    t->tv_expires.tv_usec -= 1000000;
+    t->tv_expires.tv_sec++;
+  }
+#ifdef FAST_TIMER_LOG
+  timer_added_log[fast_timers_added % NUM_TIMER_STATS] = *t;
+#endif
+  fast_timers_added++;
+
+  /* Check if this should timeout before anything else */
+  if (tmp == NULL || timeval_cmp(&t->tv_expires, &tmp->tv_expires) < 0)
+  {
+    /* Put first in list and modify the timer value */
+    t->prev = NULL;
+    t->next = fast_timer_list;
+    if (fast_timer_list)
+    {
+      fast_timer_list->prev = t;
+    }
+    fast_timer_list = t;
+#ifdef FAST_TIMER_LOG
+    timer_started_log[fast_timers_started % NUM_TIMER_STATS] = *t;
+#endif
+    start_timer_trig(delay_us);
+  } else {
+    /* Put in correct place in list */
+    while (tmp->next &&
+           timeval_cmp(&t->tv_expires, &tmp->next->tv_expires) > 0)
+    {
+      tmp = tmp->next;
+    }
+    /* Insert t after tmp */
+    t->prev = tmp;
+    t->next = tmp->next;
+    if (tmp->next)
+    {
+      tmp->next->prev = t;
+    }
+    tmp->next = t;
+  }
+
+  D2(printk("start_one_shot_timer: %d us done\n", delay_us));
+
+  local_irq_restore(flags);
+} /* start_one_shot_timer */
+
+static inline int fast_timer_pending (const struct fast_timer * t)
+{
+  return (t->next != NULL) || (t->prev != NULL) || (t == fast_timer_list);
+}
+
+static inline int detach_fast_timer (struct fast_timer *t)
+{
+  struct fast_timer *next, *prev;
+  if (!fast_timer_pending(t))
+    return 0;
+  next = t->next;
+  prev = t->prev;
+  if (next)
+    next->prev = prev;
+  if (prev)
+    prev->next = next;
+  else
+    fast_timer_list = next;
+  fast_timers_deleted++;
+  return 1;
+}
+
+int del_fast_timer(struct fast_timer * t)
+{
+  unsigned long flags;
+  int ret;
+
+  local_irq_save(flags);
+  ret = detach_fast_timer(t);
+  t->next = t->prev = NULL;
+  local_irq_restore(flags);
+  return ret;
+} /* del_fast_timer */
+
+
+/* Interrupt routines or functions called in interrupt context */
+
+/* Timer interrupt handler for trig interrupts */
+
+static irqreturn_t
+timer_trig_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+  reg_timer_r_masked_intr masked_intr;
+
+  /* Check if the timer interrupt is for us (a trig int) */
+  masked_intr = REG_RD(timer, regi_timer, r_masked_intr);
+  if (!masked_intr.trig)
+    return IRQ_NONE;
+  timer_trig_handler();
+  return IRQ_HANDLED;
+}
+
+static void timer_trig_handler(void)
+{
+  reg_timer_rw_ack_intr ack_intr = { 0 };
+  reg_timer_rw_intr_mask intr_mask;
+  reg_timer_rw_trig_cfg trig_cfg = { 0 };
+  struct fast_timer *t;
+  unsigned long flags;
+
+  local_irq_save(flags);
+
+  /* Clear timer trig interrupt */
+  intr_mask = REG_RD(timer, regi_timer, rw_intr_mask);
+  intr_mask.trig = 0;
+  REG_WR(timer, regi_timer, rw_intr_mask, intr_mask);
+
+  /* First stop timer, then ack interrupt */
+  /* Stop timer */
+  trig_cfg.tmr = regk_timer_off;
+  REG_WR(timer, regi_timer, rw_trig_cfg, trig_cfg);
+
+  /* Ack interrupt */
+  ack_intr.trig = 1;
+  REG_WR(timer, regi_timer, rw_ack_intr, ack_intr);
+
+  fast_timer_running = 0;
+  fast_timer_ints++;
+
+  local_irq_restore(flags);
+
+  t = fast_timer_list;
+  while (t)
+  {
+    struct timeval tv;
+
+    /* Has it really expired? */
+    do_gettimeofday_fast(&tv);
+    D1(printk("t: %is %06ius\n", tv.tv_sec, tv.tv_usec));
+
+    if (timeval_cmp(&t->tv_expires, &tv) <= 0)
+    {
+      /* Yes it has expired */
+#ifdef FAST_TIMER_LOG
+      timer_expired_log[fast_timers_expired % NUM_TIMER_STATS] = *t;
+#endif
+      fast_timers_expired++;
+
+      /* Remove this timer before call, since it may reuse the timer */
+      local_irq_save(flags);
+      if (t->prev)
+      {
+        t->prev->next = t->next;
+      }
+      else
+      {
+        fast_timer_list = t->next;
+      }
+      if (t->next)
+      {
+        t->next->prev = t->prev;
+      }
+      t->prev = NULL;
+      t->next = NULL;
+      local_irq_restore(flags);
+
+      if (t->function != NULL)
+      {
+        t->function(t->data);
+      }
+      else
+      {
+        DEBUG_LOG("!trimertrig %i function==NULL!\n", fast_timer_ints);
+      }
+    }
+    else
+    {
+      /* Timer is to early, let's set it again using the normal routines */
+      D1(printk(".\n"));
+    }
+
+    local_irq_save(flags);
+    if ((t = fast_timer_list) != NULL)
+    {
+      /* Start next timer.. */
+      long us;
+      struct timeval tv;
+
+      do_gettimeofday_fast(&tv);
+      us = ((t->tv_expires.tv_sec - tv.tv_sec) * 1000000 +
+            t->tv_expires.tv_usec - tv.tv_usec);
+      if (us > 0)
+      {
+        if (!fast_timer_running)
+        {
+#ifdef FAST_TIMER_LOG
+          timer_started_log[fast_timers_started % NUM_TIMER_STATS] = *t;
+#endif
+          start_timer_trig(us);
+        }
+        local_irq_restore(flags);
+        break;
+      }
+      else
+      {
+        /* Timer already expired, let's handle it better late than never.
+         * The normal loop handles it
+         */
+        D1(printk("e! %d\n", us));
+      }
+    }
+    local_irq_restore(flags);
+  }
+
+  if (!t)
+  {
+    D1(printk("ttrig stop!\n"));
+  }
+}
+
+static void wake_up_func(unsigned long data)
+{
+#ifdef DECLARE_WAITQUEUE
+  wait_queue_head_t  *sleep_wait_p = (wait_queue_head_t*)data;
+#else
+  struct wait_queue **sleep_wait_p = (struct wait_queue **)data;
+#endif
+  wake_up(sleep_wait_p);
+}
+
+
+/* Useful API */
+
+void schedule_usleep(unsigned long us)
+{
+  struct fast_timer t;
+#ifdef DECLARE_WAITQUEUE
+  wait_queue_head_t sleep_wait;
+  init_waitqueue_head(&sleep_wait);
+  {
+  DECLARE_WAITQUEUE(wait, current);
+#else
+  struct wait_queue *sleep_wait = NULL;
+  struct wait_queue wait = { current, NULL };
+#endif
+
+  D1(printk("schedule_usleep(%d)\n", us));
+  add_wait_queue(&sleep_wait, &wait);
+  set_current_state(TASK_INTERRUPTIBLE);
+  start_one_shot_timer(&t, wake_up_func, (unsigned long)&sleep_wait, us,
+                       "usleep");
+  schedule();
+  set_current_state(TASK_RUNNING);
+  remove_wait_queue(&sleep_wait, &wait);
+  D1(printk("done schedule_usleep(%d)\n", us));
+#ifdef DECLARE_WAITQUEUE
+  }
+#endif
+}
+
+#ifdef CONFIG_PROC_FS
+static int proc_fasttimer_read(char *buf, char **start, off_t offset, int len
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
+                       ,int *eof, void *data_unused
+#else
+                        ,int unused
+#endif
+                               );
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
+static struct proc_dir_entry *fasttimer_proc_entry;
+#else
+static struct proc_dir_entry fasttimer_proc_entry =
+{
+  0, 9, "fasttimer",
+  S_IFREG | S_IRUGO, 1, 0, 0,
+  0, NULL /* ops -- default to array */,
+  &proc_fasttimer_read /* get_info */,
+};
+#endif
+#endif /* CONFIG_PROC_FS */
+
+#ifdef CONFIG_PROC_FS
+
+/* This value is very much based on testing */
+#define BIG_BUF_SIZE (500 + NUM_TIMER_STATS * 300)
+
+static int proc_fasttimer_read(char *buf, char **start, off_t offset, int len
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
+                       ,int *eof, void *data_unused
+#else
+                        ,int unused
+#endif
+                               )
+{
+  unsigned long flags;
+  int i = 0;
+  int num_to_show;
+  struct timeval tv;
+  struct fast_timer *t, *nextt;
+  static char *bigbuf = NULL;
+  static unsigned long used;
+
+  if (!bigbuf && !(bigbuf = vmalloc(BIG_BUF_SIZE)))
+  {
+    used = 0;
+    bigbuf[0] = '\0';
+    return 0;
+  }
+
+  if (!offset || !used)
+  {
+    do_gettimeofday_fast(&tv);
+
+    used = 0;
+    used += sprintf(bigbuf + used, "Fast timers added:     %i\n",
+                    fast_timers_added);
+    used += sprintf(bigbuf + used, "Fast timers started:   %i\n",
+                    fast_timers_started);
+    used += sprintf(bigbuf + used, "Fast timer interrupts: %i\n",
+                    fast_timer_ints);
+    used += sprintf(bigbuf + used, "Fast timers expired:   %i\n",
+                    fast_timers_expired);
+    used += sprintf(bigbuf + used, "Fast timers deleted:   %i\n",
+                    fast_timers_deleted);
+    used += sprintf(bigbuf + used, "Fast timer running:    %s\n",
+                    fast_timer_running ? "yes" : "no");
+    used += sprintf(bigbuf + used, "Current time:          %lu.%06lu\n",
+                    (unsigned long)tv.tv_sec,
+                    (unsigned long)tv.tv_usec);
+#ifdef FAST_TIMER_SANITY_CHECKS
+    used += sprintf(bigbuf + used, "Sanity failed:         %i\n",
+                    sanity_failed);
+#endif
+    used += sprintf(bigbuf + used, "\n");
+
+#ifdef DEBUG_LOG_INCLUDED
+    {
+      int end_i = debug_log_cnt;
+      i = 0;
+
+      if (debug_log_cnt_wrapped)
+      {
+        i = debug_log_cnt;
+      }
+
+      while ((i != end_i || (debug_log_cnt_wrapped && !used)) &&
+             used+100 < BIG_BUF_SIZE)
+      {
+        used += sprintf(bigbuf + used, debug_log_string[i],
+                        debug_log_value[i]);
+        i = (i+1) % DEBUG_LOG_MAX;
+      }
+    }
+    used += sprintf(bigbuf + used, "\n");
+#endif
+
+    num_to_show = (fast_timers_started < NUM_TIMER_STATS ? fast_timers_started:
+                   NUM_TIMER_STATS);
+    used += sprintf(bigbuf + used, "Timers started: %i\n", fast_timers_started);
+    for (i = 0; i < num_to_show && (used+100 < BIG_BUF_SIZE) ; i++)
+    {
+      int cur = (fast_timers_started - i - 1) % NUM_TIMER_STATS;
+
+#if 1 //ndef FAST_TIMER_LOG
+      used += sprintf(bigbuf + used, "div: %i delay: %i"
+                      "\n",
+                      timer_div_settings[cur],
+                      timer_delay_settings[cur]
+                      );
+#endif
+#ifdef FAST_TIMER_LOG
+      t = &timer_started_log[cur];
+      used += sprintf(bigbuf + used, "%-14s s: %6lu.%06lu e: %6lu.%06lu "
+                      "d: %6li us data: 0x%08lX"
+                      "\n",
+                      t->name,
+                      (unsigned long)t->tv_set.tv_sec,
+                      (unsigned long)t->tv_set.tv_usec,
+                      (unsigned long)t->tv_expires.tv_sec,
+                      (unsigned long)t->tv_expires.tv_usec,
+                      t->delay_us,
+                      t->data
+                      );
+#endif
+    }
+    used += sprintf(bigbuf + used, "\n");
+
+#ifdef FAST_TIMER_LOG
+    num_to_show = (fast_timers_added < NUM_TIMER_STATS ? fast_timers_added:
+                   NUM_TIMER_STATS);
+    used += sprintf(bigbuf + used, "Timers added: %i\n", fast_timers_added);
+    for (i = 0; i < num_to_show && (used+100 < BIG_BUF_SIZE); i++)
+    {
+      t = &timer_added_log[(fast_timers_added - i - 1) % NUM_TIMER_STATS];
+      used += sprintf(bigbuf + used, "%-14s s: %6lu.%06lu e: %6lu.%06lu "
+                      "d: %6li us data: 0x%08lX"
+                      "\n",
+                      t->name,
+                      (unsigned long)t->tv_set.tv_sec,
+                      (unsigned long)t->tv_set.tv_usec,
+                      (unsigned long)t->tv_expires.tv_sec,
+                      (unsigned long)t->tv_expires.tv_usec,
+                      t->delay_us,
+                      t->data
+                      );
+    }
+    used += sprintf(bigbuf + used, "\n");
+
+    num_to_show = (fast_timers_expired < NUM_TIMER_STATS ? fast_timers_expired:
+                   NUM_TIMER_STATS);
+    used += sprintf(bigbuf + used, "Timers expired: %i\n", fast_timers_expired);
+    for (i = 0; i < num_to_show && (used+100 < BIG_BUF_SIZE); i++)
+    {
+      t = &timer_expired_log[(fast_timers_expired - i - 1) % NUM_TIMER_STATS];
+      used += sprintf(bigbuf + used, "%-14s s: %6lu.%06lu e: %6lu.%06lu "
+                      "d: %6li us data: 0x%08lX"
+                      "\n",
+                      t->name,
+                      (unsigned long)t->tv_set.tv_sec,
+                      (unsigned long)t->tv_set.tv_usec,
+                      (unsigned long)t->tv_expires.tv_sec,
+                      (unsigned long)t->tv_expires.tv_usec,
+                      t->delay_us,
+                      t->data
+                      );
+    }
+    used += sprintf(bigbuf + used, "\n");
+#endif
+
+    used += sprintf(bigbuf + used, "Active timers:\n");
+    local_irq_save(flags);
+    local_irq_save(flags);
+    t = fast_timer_list;
+    while (t != NULL && (used+100 < BIG_BUF_SIZE))
+    {
+      nextt = t->next;
+      local_irq_restore(flags);
+      used += sprintf(bigbuf + used, "%-14s s: %6lu.%06lu e: %6lu.%06lu "
+                      "d: %6li us data: 0x%08lX"
+/*                      " func: 0x%08lX" */
+                      "\n",
+                      t->name,
+                      (unsigned long)t->tv_set.tv_sec,
+                      (unsigned long)t->tv_set.tv_usec,
+                      (unsigned long)t->tv_expires.tv_sec,
+                      (unsigned long)t->tv_expires.tv_usec,
+                      t->delay_us,
+                      t->data
+/*                      , t->function */
+                      );
+      local_irq_disable();
+      if (t->next != nextt)
+      {
+        printk("timer removed!\n");
+      }
+      t = nextt;
+    }
+    local_irq_restore(flags);
+  }
+
+  if (used - offset < len)
+  {
+    len = used - offset;
+  }
+
+  memcpy(buf, bigbuf + offset, len);
+  *start = buf;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
+  *eof = 1;
+#endif
+
+  return len;
+}
+#endif /* PROC_FS */
+
+#ifdef FAST_TIMER_TEST
+static volatile unsigned long i = 0;
+static volatile int num_test_timeout = 0;
+static struct fast_timer tr[10];
+static int exp_num[10];
+
+static struct timeval tv_exp[100];
+
+static void test_timeout(unsigned long data)
+{
+  do_gettimeofday_fast(&tv_exp[data]);
+  exp_num[data] = num_test_timeout;
+
+  num_test_timeout++;
+}
+
+static void test_timeout1(unsigned long data)
+{
+  do_gettimeofday_fast(&tv_exp[data]);
+  exp_num[data] = num_test_timeout;
+  if (data < 7)
+  {
+    start_one_shot_timer(&tr[i], test_timeout1, i, 1000, "timeout1");
+    i++;
+  }
+  num_test_timeout++;
+}
+
+DP(
+static char buf0[2000];
+static char buf1[2000];
+static char buf2[2000];
+static char buf3[2000];
+static char buf4[2000];
+);
+
+static char buf5[6000];
+static int j_u[1000];
+
+static void fast_timer_test(void)
+{
+  int prev_num;
+  int j;
+
+  struct timeval tv, tv0, tv1, tv2;
+
+  printk("fast_timer_test() start\n");
+  do_gettimeofday_fast(&tv);
+
+  for (j = 0; j < 1000; j++)
+  {
+    j_u[j] = GET_JIFFIES_USEC();
+  }
+  for (j = 0; j < 100; j++)
+  {
+    do_gettimeofday_fast(&tv_exp[j]);
+  }
+  printk("fast_timer_test() %is %06i\n", tv.tv_sec, tv.tv_usec);
+
+  for (j = 0; j < 1000; j++)
+  {
+    printk("%i %i %i %i %i\n",j_u[j], j_u[j+1], j_u[j+2], j_u[j+3], j_u[j+4]);
+    j += 4;
+  }
+  for (j = 0; j < 100; j++)
+  {
+    printk("%i.%i %i.%i %i.%i %i.%i %i.%i\n",
+           tv_exp[j].tv_sec,tv_exp[j].tv_usec,
+           tv_exp[j+1].tv_sec,tv_exp[j+1].tv_usec,
+           tv_exp[j+2].tv_sec,tv_exp[j+2].tv_usec,
+           tv_exp[j+3].tv_sec,tv_exp[j+3].tv_usec,
+           tv_exp[j+4].tv_sec,tv_exp[j+4].tv_usec);
+    j += 4;
+  }
+  do_gettimeofday_fast(&tv0);
+  start_one_shot_timer(&tr[i], test_timeout, i, 50000, "test0");
+  DP(proc_fasttimer_read(buf0, NULL, 0, 0, 0));
+  i++;
+  start_one_shot_timer(&tr[i], test_timeout, i, 70000, "test1");
+  DP(proc_fasttimer_read(buf1, NULL, 0, 0, 0));
+  i++;
+  start_one_shot_timer(&tr[i], test_timeout, i, 40000, "test2");
+  DP(proc_fasttimer_read(buf2, NULL, 0, 0, 0));
+  i++;
+  start_one_shot_timer(&tr[i], test_timeout, i, 60000, "test3");
+  DP(proc_fasttimer_read(buf3, NULL, 0, 0, 0));
+  i++;
+  start_one_shot_timer(&tr[i], test_timeout1, i, 55000, "test4xx");
+  DP(proc_fasttimer_read(buf4, NULL, 0, 0, 0));
+  i++;
+  do_gettimeofday_fast(&tv1);
+
+  proc_fasttimer_read(buf5, NULL, 0, 0, 0);
+
+  prev_num = num_test_timeout;
+  while (num_test_timeout < i)
+  {
+    if (num_test_timeout != prev_num)
+    {
+      prev_num = num_test_timeout;
+    }
+  }
+  do_gettimeofday_fast(&tv2);
+  printk("Timers started    %is %06i\n", tv0.tv_sec, tv0.tv_usec);
+  printk("Timers started at %is %06i\n", tv1.tv_sec, tv1.tv_usec);
+  printk("Timers done       %is %06i\n", tv2.tv_sec, tv2.tv_usec);
+  DP(printk("buf0:\n");
+     printk(buf0);
+     printk("buf1:\n");
+     printk(buf1);
+     printk("buf2:\n");
+     printk(buf2);
+     printk("buf3:\n");
+     printk(buf3);
+     printk("buf4:\n");
+     printk(buf4);
+  );
+  printk("buf5:\n");
+  printk(buf5);
+
+  printk("timers set:\n");
+  for(j = 0; j<i; j++)
+  {
+    struct fast_timer *t = &tr[j];
+    printk("%-10s set: %6is %06ius exp: %6is %06ius "
+           "data: 0x%08X func: 0x%08X\n",
+           t->name,
+           t->tv_set.tv_sec,
+           t->tv_set.tv_usec,
+           t->tv_expires.tv_sec,
+           t->tv_expires.tv_usec,
+           t->data,
+           t->function
+           );
+
+    printk("           del: %6ius     did exp: %6is %06ius as #%i error: %6li\n",
+           t->delay_us,
+           tv_exp[j].tv_sec,
+           tv_exp[j].tv_usec,
+           exp_num[j],
+           (tv_exp[j].tv_sec - t->tv_expires.tv_sec)*1000000 + tv_exp[j].tv_usec - t->tv_expires.tv_usec);
+  }
+  proc_fasttimer_read(buf5, NULL, 0, 0, 0);
+  printk("buf5 after all done:\n");
+  printk(buf5);
+  printk("fast_timer_test() done\n");
+}
+#endif
+
+
+void fast_timer_init(void)
+{
+  /* For some reason, request_irq() hangs when called froom time_init() */
+  if (!fast_timer_is_init)
+  {
+    printk("fast_timer_init()\n");
+
+#ifdef CONFIG_PROC_FS
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
+   if ((fasttimer_proc_entry = create_proc_entry( "fasttimer", 0, 0 )))
+     fasttimer_proc_entry->read_proc = proc_fasttimer_read;
+#else
+    proc_register_dynamic(&proc_root, &fasttimer_proc_entry);
+#endif
+#endif /* PROC_FS */
+    if(request_irq(TIMER_INTR_VECT, timer_trig_interrupt, SA_INTERRUPT,
+                   "fast timer int", NULL))
+    {
+      printk("err: timer1 irq\n");
+    }
+    fast_timer_is_init = 1;
+#ifdef FAST_TIMER_TEST
+    printk("do test\n");
+    fast_timer_test();
+#endif
+  }
+}
diff --git a/arch/cris/arch-v32/kernel/head.S b/arch/cris/arch-v32/kernel/head.S
new file mode 100644
--- /dev/null
+++ b/arch/cris/arch-v32/kernel/head.S
@@ -0,0 +1,448 @@
+/*
+ * CRISv32 kernel startup code.
+ *
+ * Copyright (C) 2003, Axis Communications AB
+ */
+
+#include <linux/config.h>
+
+#define ASSEMBLER_MACROS_ONLY
+
+/*
+ * The macros found in mmu_defs_asm.h uses the ## concatenation operator, so
+ * -traditional must not be used when assembling this file.
+ */
+#include <asm/arch/hwregs/reg_rdwr.h>
+#include <asm/arch/hwregs/asm/mmu_defs_asm.h>
+#include <asm/arch/hwregs/asm/reg_map_asm.h>
+#include <asm/arch/hwregs/asm/config_defs_asm.h>
+#include <asm/arch/hwregs/asm/bif_core_defs_asm.h>
+
+#define CRAMFS_MAGIC 0x28cd3d45
+#define RAM_INIT_MAGIC 0x56902387
+#define COMMAND_LINE_MAGIC 0x87109563
+
+	;; NOTE: R8 and R9 carry information from the decompressor (if the
+	;; kernel was compressed). They must not be used in the code below
+	;; until they are read!
+
+	;; Exported symbols.
+	.global etrax_irv
+	.global romfs_start
+	.global romfs_length
+	.global romfs_in_flash
+	.global swapper_pg_dir
+	.global crisv32_nand_boot
+	.global crisv32_nand_cramfs_offset
+
+	;; Dummy section to make it bootable with current VCS simulator
+#ifdef CONFIG_ETRAXFS_SIM
+	.section ".boot", "ax"
+	ba tstart
+	nop
+#endif
+
+	.text
+tstart:
+	;; This is the entry point of the kernel. The CPU is currently in
+	;; supervisor mode.
+	;;
+	;; 0x00000000 if flash.
+	;; 0x40004000 if DRAM.
+	;;
+	di
+
+	;; Start clocks for used blocks.
+	move.d REG_ADDR(config, regi_config, rw_clk_ctrl), $r1
+	move.d [$r1], $r0
+	or.d   REG_STATE(config, rw_clk_ctrl, cpu, yes) | \
+	       REG_STATE(config, rw_clk_ctrl, bif, yes) | \
+	       REG_STATE(config, rw_clk_ctrl, fix_io, yes), $r0
+	move.d $r0, [$r1]
+
+	;; Set up waitstates etc
+	move.d   REG_ADDR(bif_core, regi_bif_core, rw_grp1_cfg), $r0
+	move.d   CONFIG_ETRAX_MEM_GRP1_CONFIG, $r1
+	move.d   $r1, [$r0]
+	move.d   REG_ADDR(bif_core, regi_bif_core, rw_grp2_cfg), $r0
+	move.d   CONFIG_ETRAX_MEM_GRP2_CONFIG, $r1
+	move.d   $r1, [$r0]
+	move.d   REG_ADDR(bif_core, regi_bif_core, rw_grp3_cfg), $r0
+	move.d   CONFIG_ETRAX_MEM_GRP3_CONFIG, $r1
+	move.d   $r1, [$r0]
+	move.d   REG_ADDR(bif_core, regi_bif_core, rw_grp4_cfg), $r0
+	move.d   CONFIG_ETRAX_MEM_GRP4_CONFIG, $r1
+	move.d   $r1, [$r0]
+
+#ifdef CONFIG_ETRAXFS_SIM
+	;; Set up minimal flash waitstates
+	move.d 0, $r10
+	move.d REG_ADDR(bif_core, regi_bif_core, rw_grp1_cfg), $r11
+	move.d $r10, [$r11]
+#endif
+
+	;; Setup and enable the MMU. Use same configuration for both the data
+	;; and the instruction MMU.
+	;;
+	;; Note; 3 cycles is needed for a bank-select to take effect. Further;
+	;; bank 1 is the instruction MMU, bank 2 is the data MMU.
+#ifndef CONFIG_ETRAXFS_SIM
+	move.d	REG_FIELD(mmu, rw_mm_kbase_hi, base_e, 8)	\
+		| REG_FIELD(mmu, rw_mm_kbase_hi, base_c, 4)	\
+		| REG_FIELD(mmu, rw_mm_kbase_hi, base_b, 0xb), $r0
+#else
+	;; Map the virtual DRAM to the RW eprom area at address 0.
+	;; Also map 0xa for the hook calls,
+	move.d	REG_FIELD(mmu, rw_mm_kbase_hi, base_e, 8)	\
+		| REG_FIELD(mmu, rw_mm_kbase_hi, base_c, 0)	\
+		| REG_FIELD(mmu, rw_mm_kbase_hi, base_b, 0xb)   \
+		| REG_FIELD(mmu, rw_mm_kbase_hi, base_a, 0xa), $r0
+#endif
+
+	;; Temporary map of 0x40 -> 0x40 and 0x00 -> 0x00.
+	move.d	REG_FIELD(mmu, rw_mm_kbase_lo, base_4, 4)  \
+		| REG_FIELD(mmu, rw_mm_kbase_lo, base_0, 0), $r1
+
+	;; Enable certain page protections and setup linear mapping
+	;; for f,e,c,b,4,0.
+#ifndef CONFIG_ETRAXFS_SIM
+	move.d	REG_STATE(mmu, rw_mm_cfg, we, on)		\
+		| REG_STATE(mmu, rw_mm_cfg, acc, on)		\
+		| REG_STATE(mmu, rw_mm_cfg, ex, on)		\
+		| REG_STATE(mmu, rw_mm_cfg, inv, on)		\
+		| REG_STATE(mmu, rw_mm_cfg, seg_f, linear)	\
+		| REG_STATE(mmu, rw_mm_cfg, seg_e, linear)	\
+		| REG_STATE(mmu, rw_mm_cfg, seg_d, page)	\
+		| REG_STATE(mmu, rw_mm_cfg, seg_c, linear)	\
+		| REG_STATE(mmu, rw_mm_cfg, seg_b, linear)	\
+		| REG_STATE(mmu, rw_mm_cfg, seg_a, page)	\
+		| REG_STATE(mmu, rw_mm_cfg, seg_9, page)	\
+		| REG_STATE(mmu, rw_mm_cfg, seg_8, page)	\
+		| REG_STATE(mmu, rw_mm_cfg, seg_7, page)	\
+		| REG_STATE(mmu, rw_mm_cfg, seg_6, page)	\
+		| REG_STATE(mmu, rw_mm_cfg, seg_5, page)	\
+		| REG_STATE(mmu, rw_mm_cfg, seg_4, linear)	\
+		| REG_STATE(mmu, rw_mm_cfg, seg_3, page)	\
+		| REG_STATE(mmu, rw_mm_cfg, seg_2, page)	\
+		| REG_STATE(mmu, rw_mm_cfg, seg_1, page)	\
+		| REG_STATE(mmu, rw_mm_cfg, seg_0, linear), $r2
+#else
+	move.d	REG_STATE(mmu, rw_mm_cfg, we, on)		\
+		| REG_STATE(mmu, rw_mm_cfg, acc, on)		\
+		| REG_STATE(mmu, rw_mm_cfg, ex, on)		\
+		| REG_STATE(mmu, rw_mm_cfg, inv, on)		\
+		| REG_STATE(mmu, rw_mm_cfg, seg_f, linear)	\
+		| REG_STATE(mmu, rw_mm_cfg, seg_e, linear)	\
+		| REG_STATE(mmu, rw_mm_cfg, seg_d, page)	\
+		| REG_STATE(mmu, rw_mm_cfg, seg_c, linear)	\
+		| REG_STATE(mmu, rw_mm_cfg, seg_b, linear)	\
+		| REG_STATE(mmu, rw_mm_cfg, seg_a, linear)	\
+		| REG_STATE(mmu, rw_mm_cfg, seg_9, page)	\
+		| REG_STATE(mmu, rw_mm_cfg, seg_8, page)	\
+		| REG_STATE(mmu, rw_mm_cfg, seg_7, page)	\
+		| REG_STATE(mmu, rw_mm_cfg, seg_6, page)	\
+		| REG_STATE(mmu, rw_mm_cfg, seg_5, page)	\
+		| REG_STATE(mmu, rw_mm_cfg, seg_4, linear)	\
+		| REG_STATE(mmu, rw_mm_cfg, seg_3, page)	\
+		| REG_STATE(mmu, rw_mm_cfg, seg_2, page)	\
+		| REG_STATE(mmu, rw_mm_cfg, seg_1, page)	\
+		| REG_STATE(mmu, rw_mm_cfg, seg_0, linear), $r2
+#endif
+
+	;; Update instruction MMU.
+	move	1, $srs
+	nop
+	nop
+	nop
+	move	$r0, $s2	; kbase_hi.
+	move	$r1, $s1	; kbase_lo.
+	move	$r2, $s0	; mm_cfg, virtual memory configuration.
+
+	;; Update data MMU.
+	move	2, $srs
+	nop
+	nop
+	nop
+	move	$r0, $s2	; kbase_hi.
+	move	$r1, $s1	; kbase_lo
+	move	$r2, $s0	; mm_cfg, virtual memory configuration.
+
+	;; Enable data and instruction MMU.
+	move	0, $srs
+	moveq	0xf, $r0	;  IMMU, DMMU, DCache, Icache on
+	nop
+	nop
+	nop
+	move	$r0, $s0
+	nop
+	nop
+	nop
+
+#ifdef CONFIG_SMP
+	;; Read CPU ID
+	move    0, $srs
+	nop
+	nop
+	nop
+	move    $s10, $r0
+	cmpq    0, $r0
+	beq	master_cpu
+	nop
+slave_cpu:
+	; A slave waits for cpu_now_booting to be equal to CPU ID.
+	move.d	cpu_now_booting, $r1
+slave_wait:
+	cmp.d	[$r1], $r0
+	bne	slave_wait
+	nop
+	; Time to boot-up. Get stack location provided by master CPU.
+	move.d  smp_init_current_idle_thread, $r1
+	move.d  [$r1], $sp
+	add.d	8192, $sp
+	move.d	ebp_start, $r0	; Defined in linker-script.
+	move	$r0, $ebp
+	jsr	smp_callin
+	nop
+master_cpu:
+#endif
+#ifndef CONFIG_ETRAXFS_SIM
+	;; Check if starting from DRAM or flash.
+	lapcq	., $r0
+	and.d	0x7fffffff, $r0 ; Mask off the non-cache bit.
+	cmp.d	0x10000, $r0	; Arbitrary, something above this code.
+	blo	_inflash0
+	nop
+#endif
+
+	jump	_inram		; Jump to cached RAM.
+	nop
+
+	;; Jumpgate.
+_inflash0:
+	jump _inflash
+	nop
+
+	;; Put the following in a section so that storage for it can be
+	;; reclaimed after init is finished.
+	.section ".init.text", "ax"
+
+_inflash:
+
+	;; Initialize DRAM.
+	cmp.d	RAM_INIT_MAGIC, $r8 ; Already initialized?
+	beq	_dram_initialized
+	nop
+
+#include "../lib/dram_init.S"
+
+_dram_initialized:
+	;; Copy the text and data section to DRAM. This depends on that the
+	;; variables used below are correctly set up by the linker script.
+	;; The calculated value stored in R4 is used below.
+	moveq	0, $r0		; Source.
+	move.d	text_start, $r1	; Destination.
+	move.d	__vmlinux_end, $r2
+	move.d	$r2, $r4
+	sub.d	$r1, $r4
+1:	move.w	[$r0+], $r3
+	move.w	$r3, [$r1+]
+	cmp.d	$r2, $r1
+	blo	1b
+	nop
+
+	;; Keep CRAMFS in flash.
+	moveq	0, $r0
+	move.d	romfs_length, $r1
+	move.d	$r0, [$r1]
+	move.d	[$r4], $r0	; cramfs_super.magic
+	cmp.d	CRAMFS_MAGIC, $r0
+	bne 1f
+	nop
+
+	addoq	+4, $r4, $acr
+	move.d	[$acr], $r0
+	move.d	romfs_length, $r1
+	move.d	$r0, [$r1]
+	add.d	0xf0000000, $r4	; Add cached flash start in virtual memory.
+	move.d	romfs_start, $r1
+	move.d	$r4, [$r1]
+1:	moveq	1, $r0
+	move.d	romfs_in_flash, $r1
+	move.d	$r0, [$r1]
+
+	jump	_start_it	; Jump to cached code.
+	nop
+
+_inram:
+	;; Check if booting from NAND flash (in that case we just remember the offset
+	;; into the flash where cramfs should be).
+	move.d	REG_ADDR(config, regi_config, r_bootsel), $r0
+	move.d	[$r0], $r0
+	and.d	REG_MASK(config, r_bootsel, boot_mode), $r0
+	cmp.d	REG_STATE(config, r_bootsel, boot_mode, nand), $r0
+	bne	move_cramfs
+	moveq	1,$r0
+	move.d	crisv32_nand_boot, $r1
+	move.d	$r0, [$r1]
+	move.d	crisv32_nand_cramfs_offset, $r1
+	move.d	$r9, [$r1]
+	moveq	1, $r0
+	move.d	romfs_in_flash, $r1
+	move.d	$r0, [$r1]
+	jump	_start_it
+	nop
+
+move_cramfs:
+	;; Move the cramfs after BSS.
+	moveq	0, $r0
+	move.d	romfs_length, $r1
+	move.d	$r0, [$r1]
+
+#ifndef CONFIG_ETRAXFS_SIM
+	;; The kernel could have been unpacked to DRAM by the loader, but
+	;; the cramfs image could still be inte the flash immediately
+	;; following the compressed kernel image. The loaded passes the address
+	;; of the bute succeeding the last compressed byte in the flash in
+	;; register R9 when starting the kernel.
+	cmp.d	0x0ffffff8, $r9
+	bhs	_no_romfs_in_flash ; R9 points outside the flash area.
+	nop
+#else
+	ba _no_romfs_in_flash
+	nop
+#endif
+	move.d	[$r9], $r0	; cramfs_super.magic
+	cmp.d	CRAMFS_MAGIC, $r0
+	bne	_no_romfs_in_flash
+	nop
+
+	addoq	+4, $r9, $acr
+	move.d	[$acr], $r0
+	move.d	romfs_length, $r1
+	move.d	$r0, [$r1]
+	add.d	0xf0000000, $r9	; Add cached flash start in virtual memory.
+	move.d	romfs_start, $r1
+	move.d	$r9, [$r1]
+	moveq	1, $r0
+	move.d	romfs_in_flash, $r1
+	move.d	$r0, [$r1]
+
+	jump	_start_it	; Jump to cached code.
+	nop
+
+_no_romfs_in_flash:
+	;; Look for cramfs.
+#ifndef CONFIG_ETRAXFS_SIM
+	move.d	__vmlinux_end, $r0
+#else
+	move.d	__end, $r0
+#endif
+	move.d	[$r0], $r1
+	cmp.d	CRAMFS_MAGIC, $r1
+	bne	2f
+	nop
+
+	addoq	+4, $r0, $acr
+	move.d	[$acr], $r2
+	move.d	_end, $r1
+	move.d	romfs_start, $r3
+	move.d	$r1, [$r3]
+	move.d	romfs_length, $r3
+	move.d	$r2, [$r3]
+
+#ifndef CONFIG_ETRAXFS_SIM
+	add.d	$r2, $r0
+	add.d	$r2, $r1
+
+	lsrq	1, $r2		; Size is in bytes, we copy words.
+	addq    1, $r2
+1:
+	move.w	[$r0], $r3
+	move.w	$r3, [$r1]
+	subq	2, $r0
+	subq	2, $r1
+	subq	1, $r2
+	bne	1b
+	nop
+#endif
+
+2:
+	moveq	0, $r0
+	move.d	romfs_in_flash, $r1
+	move.d	$r0, [$r1]
+
+	jump	_start_it	; Jump to cached code.
+	nop
+
+_start_it:
+
+	;; Check if kernel command line is supplied
+	cmp.d	COMMAND_LINE_MAGIC, $r10
+	bne	no_command_line
+	nop
+
+	move.d	256, $r13
+	move.d  cris_command_line, $r10
+	or.d	0x80000000, $r11 ; Make it virtual
+1:
+	move.b  [$r11+], $r12
+	move.b  $r12, [$r10+]
+	subq	1, $r13
+	bne	1b
+	nop
+
+no_command_line:
+
+	;; The kernel stack contains a task structure for each task. This
+	;; the initial kernel stack is in the same page as the init_task,
+	;; but starts at the top of the page, i.e. + 8192 bytes.
+	move.d	init_thread_union + 8192, $sp
+	move.d	ebp_start, $r0	; Defined in linker-script.
+	move	$r0, $ebp
+	move.d	etrax_irv, $r1	; Set the exception base register and pointer.
+	move.d	$r0, [$r1]
+
+#ifndef CONFIG_ETRAXFS_SIM
+	;; Clear the BSS region from _bss_start to _end.
+	move.d	__bss_start, $r0
+	move.d	_end, $r1
+1:	clear.d	[$r0+]
+	cmp.d	$r1, $r0
+	blo 1b
+	nop
+#endif
+
+#ifdef CONFIG_ETRAXFS_SIM
+	/* Set the watchdog timeout to something big. Will be removed when */
+	/* watchdog can be disabled with command line option */
+	move.d  0x7fffffff, $r10
+	jsr     CPU_WATCHDOG_TIMEOUT
+	nop
+#endif
+
+	; Initialize registers to increase determinism
+	move.d __bss_start, $r0
+	movem [$r0], $r13
+
+	jump	start_kernel	; Jump to start_kernel() in init/main.c.
+	nop
+
+	.data
+etrax_irv:
+	.dword 0
+romfs_start:
+	.dword 0
+romfs_length:
+	.dword 0
+romfs_in_flash:
+	.dword 0
+crisv32_nand_boot:
+	.dword 0
+crisv32_nand_cramfs_offset:
+	.dword 0
+
+swapper_pg_dir = 0xc0002000
+
+	.section ".init.data", "aw"
+
+#include "../lib/hw_settings.S"
diff --git a/arch/cris/arch-v32/kernel/io.c b/arch/cris/arch-v32/kernel/io.c
new file mode 100644
--- /dev/null
+++ b/arch/cris/arch-v32/kernel/io.c
@@ -0,0 +1,154 @@
+/*
+ * Helper functions for I/O pins.
+ *
+ * Copyright (c) 2004 Axis Communications AB.
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/ctype.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <asm/io.h>
+#include <asm/arch/pinmux.h>
+#include <asm/arch/hwregs/gio_defs.h>
+
+struct crisv32_ioport crisv32_ioports[] =
+{
+	{
+		(unsigned long*)REG_ADDR(gio, regi_gio, rw_pa_oe),
+		(unsigned long*)REG_ADDR(gio, regi_gio, rw_pa_dout),
+		(unsigned long*)REG_ADDR(gio, regi_gio, r_pa_din),
+		8
+	},
+	{
+		(unsigned long*)REG_ADDR(gio, regi_gio, rw_pb_oe),
+		(unsigned long*)REG_ADDR(gio, regi_gio, rw_pb_dout),
+		(unsigned long*)REG_ADDR(gio, regi_gio, r_pb_din),
+		18
+	},
+	{
+		(unsigned long*)REG_ADDR(gio, regi_gio, rw_pc_oe),
+		(unsigned long*)REG_ADDR(gio, regi_gio, rw_pc_dout),
+		(unsigned long*)REG_ADDR(gio, regi_gio, r_pc_din),
+		18
+	},
+	{
+		(unsigned long*)REG_ADDR(gio, regi_gio, rw_pd_oe),
+		(unsigned long*)REG_ADDR(gio, regi_gio, rw_pd_dout),
+		(unsigned long*)REG_ADDR(gio, regi_gio, r_pd_din),
+		18
+	},
+	{
+		(unsigned long*)REG_ADDR(gio, regi_gio, rw_pe_oe),
+		(unsigned long*)REG_ADDR(gio, regi_gio, rw_pe_dout),
+		(unsigned long*)REG_ADDR(gio, regi_gio, r_pe_din),
+		18
+	}
+};
+
+#define NBR_OF_PORTS sizeof(crisv32_ioports)/sizeof(struct crisv32_ioport)
+
+struct crisv32_iopin crisv32_led1_green;
+struct crisv32_iopin crisv32_led1_red;
+struct crisv32_iopin crisv32_led2_green;
+struct crisv32_iopin crisv32_led2_red;
+struct crisv32_iopin crisv32_led3_green;
+struct crisv32_iopin crisv32_led3_red;
+
+/* Dummy port used when green LED and red LED is on the same bit */
+static unsigned long io_dummy;
+static struct crisv32_ioport dummy_port =
+{
+	&io_dummy,
+	&io_dummy,
+	&io_dummy,
+	18
+};
+static struct crisv32_iopin dummy_led =
+{
+	&dummy_port,
+	0
+};
+
+static int __init crisv32_io_init(void)
+{
+	int ret = 0;
+	/* Initialize LEDs */
+	ret += crisv32_io_get_name(&crisv32_led1_green, CONFIG_ETRAX_LED1G);
+	ret += crisv32_io_get_name(&crisv32_led1_red, CONFIG_ETRAX_LED1R);
+	ret += crisv32_io_get_name(&crisv32_led2_green, CONFIG_ETRAX_LED2G);
+	ret += crisv32_io_get_name(&crisv32_led2_red, CONFIG_ETRAX_LED2R);
+	ret += crisv32_io_get_name(&crisv32_led3_green, CONFIG_ETRAX_LED3G);
+	ret += crisv32_io_get_name(&crisv32_led3_red, CONFIG_ETRAX_LED3R);
+	crisv32_io_set_dir(&crisv32_led1_green, crisv32_io_dir_out);
+	crisv32_io_set_dir(&crisv32_led1_red, crisv32_io_dir_out);
+	crisv32_io_set_dir(&crisv32_led2_green, crisv32_io_dir_out);
+	crisv32_io_set_dir(&crisv32_led2_red, crisv32_io_dir_out);
+	crisv32_io_set_dir(&crisv32_led3_green, crisv32_io_dir_out);
+	crisv32_io_set_dir(&crisv32_led3_red, crisv32_io_dir_out);
+
+	if (!strcmp(CONFIG_ETRAX_LED1G, CONFIG_ETRAX_LED1R))
+		crisv32_led1_red = dummy_led;
+	if (!strcmp(CONFIG_ETRAX_LED2G, CONFIG_ETRAX_LED2R))
+		crisv32_led2_red = dummy_led;
+
+	return ret;
+}
+
+__initcall(crisv32_io_init);
+
+int crisv32_io_get(struct crisv32_iopin* iopin,
+                   unsigned int port, unsigned int pin)
+{
+	if (port > NBR_OF_PORTS)
+		return -EINVAL;
+	if (port > crisv32_ioports[port].pin_count)
+		return -EINVAL;
+
+	iopin->bit = 1 << pin;
+	iopin->port = &crisv32_ioports[port];
+
+	if (crisv32_pinmux_alloc(port, pin, pin, pinmux_gpio))
+		return -EIO;
+
+	return 0;
+}
+
+int crisv32_io_get_name(struct crisv32_iopin* iopin,
+                         char* name)
+{
+	int port;
+	int pin;
+
+	if (toupper(*name) == 'P')
+		name++;
+
+	if (toupper(*name) < 'A' || toupper(*name) > 'E')
+		return -EINVAL;
+
+	port = toupper(*name) - 'A';
+	name++;
+	pin = simple_strtoul(name, NULL, 10);
+
+	if (pin < 0 || pin > crisv32_ioports[port].pin_count)
+		return -EINVAL;
+
+	iopin->bit = 1 << pin;
+	iopin->port = &crisv32_ioports[port];
+
+	if (crisv32_pinmux_alloc(port, pin, pin, pinmux_gpio))
+		return -EIO;
+
+	return 0;
+}
+
+#ifdef CONFIG_PCI
+/* PCI I/O access stuff */
+struct cris_io_operations* cris_iops = NULL;
+EXPORT_SYMBOL(cris_iops);
+#endif
+
diff --git a/arch/cris/arch-v32/kernel/irq.c b/arch/cris/arch-v32/kernel/irq.c
new file mode 100644
--- /dev/null
+++ b/arch/cris/arch-v32/kernel/irq.c
@@ -0,0 +1,413 @@
+/*
+ * Copyright (C) 2003, Axis Communications AB.
+ */
+
+#include <asm/irq.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/smp.h>
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/profile.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include <linux/threads.h>
+#include <linux/spinlock.h>
+#include <linux/kernel_stat.h>
+#include <asm/arch/hwregs/reg_map.h>
+#include <asm/arch/hwregs/reg_rdwr.h>
+#include <asm/arch/hwregs/intr_vect.h>
+#include <asm/arch/hwregs/intr_vect_defs.h>
+
+#define CPU_FIXED -1
+
+/* IRQ masks (refer to comment for crisv32_do_multiple) */
+#define TIMER_MASK (1 << (TIMER_INTR_VECT - FIRST_IRQ))
+#ifdef CONFIG_ETRAX_KGDB
+#if defined(CONFIG_ETRAX_KGDB_PORT0)
+#define IGNOREMASK (1 << (SER0_INTR_VECT - FIRST_IRQ))
+#elif defined(CONFIG_ETRAX_KGDB_PORT1)
+#define IGNOREMASK (1 << (SER1_INTR_VECT - FIRST_IRQ))
+#elif defined(CONFIG_ETRAX_KGB_PORT2)
+#define IGNOREMASK (1 << (SER2_INTR_VECT - FIRST_IRQ))
+#elif defined(CONFIG_ETRAX_KGDB_PORT3)
+#define IGNOREMASK (1 << (SER3_INTR_VECT - FIRST_IRQ))
+#endif
+#endif
+
+DEFINE_SPINLOCK(irq_lock);
+
+struct cris_irq_allocation
+{
+  int cpu; /* The CPU to which the IRQ is currently allocated. */
+  cpumask_t mask; /* The CPUs to which the IRQ may be allocated. */
+};
+
+struct cris_irq_allocation irq_allocations[NR_IRQS] =
+  {[0 ... NR_IRQS - 1] = {0, CPU_MASK_ALL}};
+
+static unsigned long irq_regs[NR_CPUS] =
+{
+  regi_irq,
+#ifdef CONFIG_SMP
+  regi_irq2,
+#endif
+};
+
+unsigned long cpu_irq_counters[NR_CPUS];
+unsigned long irq_counters[NR_REAL_IRQS];
+
+/* From irq.c. */
+extern void weird_irq(void);
+
+/* From entry.S. */
+extern void system_call(void);
+extern void nmi_interrupt(void);
+extern void multiple_interrupt(void);
+extern void gdb_handle_exception(void);
+extern void i_mmu_refill(void);
+extern void i_mmu_invalid(void);
+extern void i_mmu_access(void);
+extern void i_mmu_execute(void);
+extern void d_mmu_refill(void);
+extern void d_mmu_invalid(void);
+extern void d_mmu_access(void);
+extern void d_mmu_write(void);
+
+/* From kgdb.c. */
+extern void kgdb_init(void);
+extern void breakpoint(void);
+
+/*
+ * Build the IRQ handler stubs using macros from irq.h. First argument is the
+ * IRQ number, the second argument is the corresponding bit in
+ * intr_rw_vect_mask found in asm/arch/hwregs/intr_vect_defs.h.
+ */
+BUILD_IRQ(0x31, (1 << 0))	/* memarb */
+BUILD_IRQ(0x32, (1 << 1))	/* gen_io */
+BUILD_IRQ(0x33, (1 << 2))	/* iop0 */
+BUILD_IRQ(0x34, (1 << 3))	/* iop1 */
+BUILD_IRQ(0x35, (1 << 4))	/* iop2 */
+BUILD_IRQ(0x36, (1 << 5))	/* iop3 */
+BUILD_IRQ(0x37, (1 << 6))	/* dma0 */
+BUILD_IRQ(0x38, (1 << 7))	/* dma1 */
+BUILD_IRQ(0x39, (1 << 8))	/* dma2 */
+BUILD_IRQ(0x3a, (1 << 9))	/* dma3 */
+BUILD_IRQ(0x3b, (1 << 10))	/* dma4 */
+BUILD_IRQ(0x3c, (1 << 11))	/* dma5 */
+BUILD_IRQ(0x3d, (1 << 12))	/* dma6 */
+BUILD_IRQ(0x3e, (1 << 13))	/* dma7 */
+BUILD_IRQ(0x3f, (1 << 14))	/* dma8 */
+BUILD_IRQ(0x40, (1 << 15))	/* dma9 */
+BUILD_IRQ(0x41, (1 << 16))	/* ata */
+BUILD_IRQ(0x42, (1 << 17))	/* sser0 */
+BUILD_IRQ(0x43, (1 << 18))	/* sser1 */
+BUILD_IRQ(0x44, (1 << 19))	/* ser0 */
+BUILD_IRQ(0x45, (1 << 20))	/* ser1 */
+BUILD_IRQ(0x46, (1 << 21))	/* ser2 */
+BUILD_IRQ(0x47, (1 << 22))	/* ser3 */
+BUILD_IRQ(0x48, (1 << 23))
+BUILD_IRQ(0x49, (1 << 24))	/* eth0 */
+BUILD_IRQ(0x4a, (1 << 25))	/* eth1 */
+BUILD_TIMER_IRQ(0x4b, (1 << 26))/* timer */
+BUILD_IRQ(0x4c, (1 << 27))	/* bif_arb */
+BUILD_IRQ(0x4d, (1 << 28))	/* bif_dma */
+BUILD_IRQ(0x4e, (1 << 29))	/* ext */
+BUILD_IRQ(0x4f, (1 << 29))	/* ipi */
+
+/* Pointers to the low-level handlers. */
+static void (*interrupt[NR_IRQS])(void) = {
+	IRQ0x31_interrupt, IRQ0x32_interrupt, IRQ0x33_interrupt,
+	IRQ0x34_interrupt, IRQ0x35_interrupt, IRQ0x36_interrupt,
+	IRQ0x37_interrupt, IRQ0x38_interrupt, IRQ0x39_interrupt,
+	IRQ0x3a_interrupt, IRQ0x3b_interrupt, IRQ0x3c_interrupt,
+	IRQ0x3d_interrupt, IRQ0x3e_interrupt, IRQ0x3f_interrupt,
+	IRQ0x40_interrupt, IRQ0x41_interrupt, IRQ0x42_interrupt,
+	IRQ0x43_interrupt, IRQ0x44_interrupt, IRQ0x45_interrupt,
+	IRQ0x46_interrupt, IRQ0x47_interrupt, IRQ0x48_interrupt,
+	IRQ0x49_interrupt, IRQ0x4a_interrupt, IRQ0x4b_interrupt,
+	IRQ0x4c_interrupt, IRQ0x4d_interrupt, IRQ0x4e_interrupt,
+	IRQ0x4f_interrupt
+};
+
+void
+block_irq(int irq, int cpu)
+{
+	int intr_mask;
+        unsigned long flags;
+
+        spin_lock_irqsave(&irq_lock, flags);
+        intr_mask = REG_RD_INT(intr_vect, irq_regs[cpu], rw_mask);
+
+	/* Remember; 1 let thru, 0 block. */
+	intr_mask &= ~(1 << (irq - FIRST_IRQ));
+
+	REG_WR_INT(intr_vect, irq_regs[cpu], rw_mask, intr_mask);
+        spin_unlock_irqrestore(&irq_lock, flags);
+}
+
+void
+unblock_irq(int irq, int cpu)
+{
+	int intr_mask;
+        unsigned long flags;
+
+        spin_lock_irqsave(&irq_lock, flags);
+        intr_mask = REG_RD_INT(intr_vect, irq_regs[cpu], rw_mask);
+
+	/* Remember; 1 let thru, 0 block. */
+	intr_mask |= (1 << (irq - FIRST_IRQ));
+
+	REG_WR_INT(intr_vect, irq_regs[cpu], rw_mask, intr_mask);
+        spin_unlock_irqrestore(&irq_lock, flags);
+}
+
+/* Find out which CPU the irq should be allocated to. */
+static int irq_cpu(int irq)
+{
+	int cpu;
+        unsigned long flags;
+
+        spin_lock_irqsave(&irq_lock, flags);
+        cpu = irq_allocations[irq - FIRST_IRQ].cpu;
+
+	/* Fixed interrupts stay on the local CPU. */
+	if (cpu == CPU_FIXED)
+        {
+		spin_unlock_irqrestore(&irq_lock, flags);
+		return smp_processor_id();
+        }
+
+
+	/* Let the interrupt stay if possible */
+	if (cpu_isset(cpu, irq_allocations[irq - FIRST_IRQ].mask))
+		goto out;
+
+	/* IRQ must be moved to another CPU. */
+	cpu = first_cpu(irq_allocations[irq - FIRST_IRQ].mask);
+	irq_allocations[irq - FIRST_IRQ].cpu = cpu;
+out:
+	spin_unlock_irqrestore(&irq_lock, flags);
+	return cpu;
+}
+
+void
+mask_irq(int irq)
+{
+	int cpu;
+
+	for (cpu = 0; cpu < NR_CPUS; cpu++)
+		block_irq(irq, cpu);
+}
+
+void
+unmask_irq(int irq)
+{
+	unblock_irq(irq, irq_cpu(irq));
+}
+
+
+static unsigned int startup_crisv32_irq(unsigned int irq)
+{
+	unmask_irq(irq);
+	return 0;
+}
+
+static void shutdown_crisv32_irq(unsigned int irq)
+{
+	mask_irq(irq);
+}
+
+static void enable_crisv32_irq(unsigned int irq)
+{
+	unmask_irq(irq);
+}
+
+static void disable_crisv32_irq(unsigned int irq)
+{
+	mask_irq(irq);
+}
+
+static void ack_crisv32_irq(unsigned int irq)
+{
+}
+
+static void end_crisv32_irq(unsigned int irq)
+{
+}
+
+void set_affinity_crisv32_irq(unsigned int irq, cpumask_t dest)
+{
+	unsigned long flags;
+	spin_lock_irqsave(&irq_lock, flags);
+	irq_allocations[irq - FIRST_IRQ].mask = dest;
+	spin_unlock_irqrestore(&irq_lock, flags);
+}
+
+static struct hw_interrupt_type crisv32_irq_type = {
+	.typename =    "CRISv32",
+	.startup =     startup_crisv32_irq,
+	.shutdown =    shutdown_crisv32_irq,
+	.enable =      enable_crisv32_irq,
+	.disable =     disable_crisv32_irq,
+	.ack =         ack_crisv32_irq,
+	.end =         end_crisv32_irq,
+	.set_affinity = set_affinity_crisv32_irq
+};
+
+void
+set_exception_vector(int n, irqvectptr addr)
+{
+	etrax_irv->v[n] = (irqvectptr) addr;
+}
+
+extern void do_IRQ(int irq, struct pt_regs * regs);
+
+void
+crisv32_do_IRQ(int irq, int block, struct pt_regs* regs)
+{
+	/* Interrupts that may not be moved to another CPU and
+         * are SA_INTERRUPT may skip blocking. This is currently
+         * only valid for the timer IRQ and the IPI and is used
+         * for the timer interrupt to avoid watchdog starvation.
+         */
+	if (!block) {
+		do_IRQ(irq, regs);
+		return;
+	}
+
+	block_irq(irq, smp_processor_id());
+	do_IRQ(irq, regs);
+
+	unblock_irq(irq, irq_cpu(irq));
+}
+
+/* If multiple interrupts occur simultaneously we get a multiple
+ * interrupt from the CPU and software has to sort out which
+ * interrupts that happened. There are two special cases here:
+ *
+ * 1. Timer interrupts may never be blocked because of the
+ *    watchdog (refer to comment in include/asr/arch/irq.h)
+ * 2. GDB serial port IRQs are unhandled here and will be handled
+ *    as a single IRQ when it strikes again because the GDB
+ *    stubb wants to save the registers in its own fashion.
+ */
+void
+crisv32_do_multiple(struct pt_regs* regs)
+{
+	int cpu;
+	int mask;
+	int masked;
+	int bit;
+
+	cpu = smp_processor_id();
+
+	/* An extra irq_enter here to prevent softIRQs to run after
+         * each do_IRQ. This will decrease the interrupt latency.
+	 */
+	irq_enter();
+
+	/* Get which IRQs that happend. */
+	masked = REG_RD_INT(intr_vect, irq_regs[cpu], r_masked_vect);
+
+	/* Calculate new IRQ mask with these IRQs disabled. */
+	mask = REG_RD_INT(intr_vect, irq_regs[cpu], rw_mask);
+	mask &= ~masked;
+
+	/* Timer IRQ is never masked */
+	if (masked & TIMER_MASK)
+		mask |= TIMER_MASK;
+
+	/* Block all the IRQs */
+	REG_WR_INT(intr_vect, irq_regs[cpu], rw_mask, mask);
+
+	/* Check for timer IRQ and handle it special. */
+	if (masked & TIMER_MASK) {
+	        masked &= ~TIMER_MASK;
+		do_IRQ(TIMER_INTR_VECT, regs);
+	}
+
+#ifdef IGNORE_MASK
+	/* Remove IRQs that can't be handled as multiple. */
+	masked &= ~IGNORE_MASK;
+#endif
+
+	/* Handle the rest of the IRQs. */
+	for (bit = 0; bit < 32; bit++)
+	{
+		if (masked & (1 << bit))
+			do_IRQ(bit + FIRST_IRQ, regs);
+	}
+
+	/* Unblock all the IRQs. */
+	mask = REG_RD_INT(intr_vect, irq_regs[cpu], rw_mask);
+	mask |= masked;
+	REG_WR_INT(intr_vect, irq_regs[cpu], rw_mask, mask);
+
+	/* This irq_exit() will trigger the soft IRQs. */
+	irq_exit();
+}
+
+/*
+ * This is called by start_kernel. It fixes the IRQ masks and setup the
+ * interrupt vector table to point to bad_interrupt pointers.
+ */
+void __init
+init_IRQ(void)
+{
+	int i;
+	int j;
+	reg_intr_vect_rw_mask vect_mask = {0};
+
+	/* Clear all interrupts masks. */
+	REG_WR(intr_vect, regi_irq, rw_mask, vect_mask);
+
+	for (i = 0; i < 256; i++)
+		etrax_irv->v[i] = weird_irq;
+
+	/* Point all IRQ's to bad handlers. */
+	for (i = FIRST_IRQ, j = 0; j < NR_IRQS; i++, j++) {
+		irq_desc[j].handler = &crisv32_irq_type;
+		set_exception_vector(i, interrupt[j]);
+	}
+
+        /* Mark Timer and IPI IRQs as CPU local */
+	irq_allocations[TIMER_INTR_VECT - FIRST_IRQ].cpu = CPU_FIXED;
+	irq_desc[TIMER_INTR_VECT].status |= IRQ_PER_CPU;
+	irq_allocations[IPI_INTR_VECT - FIRST_IRQ].cpu = CPU_FIXED;
+	irq_desc[IPI_INTR_VECT].status |= IRQ_PER_CPU;
+
+	set_exception_vector(0x00, nmi_interrupt);
+	set_exception_vector(0x30, multiple_interrupt);
+
+	/* Set up handler for various MMU bus faults. */
+	set_exception_vector(0x04, i_mmu_refill);
+	set_exception_vector(0x05, i_mmu_invalid);
+	set_exception_vector(0x06, i_mmu_access);
+	set_exception_vector(0x07, i_mmu_execute);
+	set_exception_vector(0x08, d_mmu_refill);
+	set_exception_vector(0x09, d_mmu_invalid);
+	set_exception_vector(0x0a, d_mmu_access);
+	set_exception_vector(0x0b, d_mmu_write);
+
+	/* The system-call trap is reached by "break 13". */
+	set_exception_vector(0x1d, system_call);
+
+	/* Exception handlers for debugging, both user-mode and kernel-mode. */
+
+	/* Break 8. */
+	set_exception_vector(0x18, gdb_handle_exception);
+	/* Hardware single step. */
+	set_exception_vector(0x3, gdb_handle_exception);
+	/* Hardware breakpoint. */
+	set_exception_vector(0xc, gdb_handle_exception);
+
+#ifdef CONFIG_ETRAX_KGDB
+	kgdb_init();
+	/* Everything is set up; now trap the kernel. */
+	breakpoint();
+#endif
+}
+
diff --git a/arch/cris/arch-v32/kernel/kgdb.c b/arch/cris/arch-v32/kernel/kgdb.c
new file mode 100644
--- /dev/null
+++ b/arch/cris/arch-v32/kernel/kgdb.c
@@ -0,0 +1,1660 @@
+/*
+ *  arch/cris/arch-v32/kernel/kgdb.c
+ *
+ *  CRIS v32 version by Orjan Friberg, Axis Communications AB.
+ *
+ *  S390 version
+ *    Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
+ *    Author(s): Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com),
+ *
+ *  Originally written by Glenn Engel, Lake Stevens Instrument Division
+ *
+ *  Contributed by HP Systems
+ *
+ *  Modified for SPARC by Stu Grossman, Cygnus Support.
+ *
+ *  Modified for Linux/MIPS (and MIPS in general) by Andreas Busse
+ *  Send complaints, suggestions etc. to <andy@waldorf-gmbh.de>
+ *
+ *  Copyright (C) 1995 Andreas Busse
+ */
+
+/* FIXME: Check the documentation. */
+
+/*
+ *  kgdb usage notes:
+ *  -----------------
+ *
+ * If you select CONFIG_ETRAX_KGDB in the configuration, the kernel will be
+ * built with different gcc flags: "-g" is added to get debug infos, and
+ * "-fomit-frame-pointer" is omitted to make debugging easier. Since the
+ * resulting kernel will be quite big (approx. > 7 MB), it will be stripped
+ * before compresion. Such a kernel will behave just as usually, except if
+ * given a "debug=<device>" command line option. (Only serial devices are
+ * allowed for <device>, i.e. no printers or the like; possible values are
+ * machine depedend and are the same as for the usual debug device, the one
+ * for logging kernel messages.) If that option is given and the device can be
+ * initialized, the kernel will connect to the remote gdb in trap_init(). The
+ * serial parameters are fixed to 8N1 and 115200 bps, for easyness of
+ * implementation.
+ *
+ * To start a debugging session, start that gdb with the debugging kernel
+ * image (the one with the symbols, vmlinux.debug) named on the command line.
+ * This file will be used by gdb to get symbol and debugging infos about the
+ * kernel. Next, select remote debug mode by
+ *    target remote <device>
+ * where <device> is the name of the serial device over which the debugged
+ * machine is connected. Maybe you have to adjust the baud rate by
+ *    set remotebaud <rate>
+ * or also other parameters with stty:
+ *    shell stty ... </dev/...
+ * If the kernel to debug has already booted, it waited for gdb and now
+ * connects, and you'll see a breakpoint being reported. If the kernel isn't
+ * running yet, start it now. The order of gdb and the kernel doesn't matter.
+ * Another thing worth knowing about in the getting-started phase is how to
+ * debug the remote protocol itself. This is activated with
+ *    set remotedebug 1
+ * gdb will then print out each packet sent or received. You'll also get some
+ * messages about the gdb stub on the console of the debugged machine.
+ *
+ * If all that works, you can use lots of the usual debugging techniques on
+ * the kernel, e.g. inspecting and changing variables/memory, setting
+ * breakpoints, single stepping and so on. It's also possible to interrupt the
+ * debugged kernel by pressing C-c in gdb. Have fun! :-)
+ *
+ * The gdb stub is entered (and thus the remote gdb gets control) in the
+ * following situations:
+ *
+ *  - If breakpoint() is called. This is just after kgdb initialization, or if
+ *    a breakpoint() call has been put somewhere into the kernel source.
+ *    (Breakpoints can of course also be set the usual way in gdb.)
+ *    In eLinux, we call breakpoint() in init/main.c after IRQ initialization.
+ *
+ *  - If there is a kernel exception, i.e. bad_super_trap() or die_if_kernel()
+ *    are entered. All the CPU exceptions are mapped to (more or less..., see
+ *    the hard_trap_info array below) appropriate signal, which are reported
+ *    to gdb. die_if_kernel() is usually called after some kind of access
+ *    error and thus is reported as SIGSEGV.
+ *
+ *  - When panic() is called. This is reported as SIGABRT.
+ *
+ *  - If C-c is received over the serial line, which is treated as
+ *    SIGINT.
+ *
+ * Of course, all these signals are just faked for gdb, since there is no
+ * signal concept as such for the kernel. It also isn't possible --obviously--
+ * to set signal handlers from inside gdb, or restart the kernel with a
+ * signal.
+ *
+ * Current limitations:
+ *
+ *  - While the kernel is stopped, interrupts are disabled for safety reasons
+ *    (i.e., variables not changing magically or the like). But this also
+ *    means that the clock isn't running anymore, and that interrupts from the
+ *    hardware may get lost/not be served in time. This can cause some device
+ *    errors...
+ *
+ *  - When single-stepping, only one instruction of the current thread is
+ *    executed, but interrupts are allowed for that time and will be serviced
+ *    if pending. Be prepared for that.
+ *
+ *  - All debugging happens in kernel virtual address space. There's no way to
+ *    access physical memory not mapped in kernel space, or to access user
+ *    space. A way to work around this is using get_user_long & Co. in gdb
+ *    expressions, but only for the current process.
+ *
+ *  - Interrupting the kernel only works if interrupts are currently allowed,
+ *    and the interrupt of the serial line isn't blocked by some other means
+ *    (IPL too high, disabled, ...)
+ *
+ *  - The gdb stub is currently not reentrant, i.e. errors that happen therein
+ *    (e.g. accessing invalid memory) may not be caught correctly. This could
+ *    be removed in future by introducing a stack of struct registers.
+ *
+ */
+
+/*
+ *  To enable debugger support, two things need to happen.  One, a
+ *  call to kgdb_init() is necessary in order to allow any breakpoints
+ *  or error conditions to be properly intercepted and reported to gdb.
+ *  Two, a breakpoint needs to be generated to begin communication.  This
+ *  is most easily accomplished by a call to breakpoint().
+ *
+ *    The following gdb commands are supported:
+ *
+ * command          function                               Return value
+ *
+ *    g             return the value of the CPU registers  hex data or ENN
+ *    G             set the value of the CPU registers     OK or ENN
+ *
+ *    mAA..AA,LLLL  Read LLLL bytes at address AA..AA      hex data or ENN
+ *    MAA..AA,LLLL: Write LLLL bytes at address AA.AA      OK or ENN
+ *
+ *    c             Resume at current address              SNN   ( signal NN)
+ *    cAA..AA       Continue at address AA..AA             SNN
+ *
+ *    s             Step one instruction                   SNN
+ *    sAA..AA       Step one instruction from AA..AA       SNN
+ *
+ *    k             kill
+ *
+ *    ?             What was the last sigval ?             SNN   (signal NN)
+ *
+ *    bBB..BB	    Set baud rate to BB..BB		   OK or BNN, then sets
+ *							   baud rate
+ *
+ * All commands and responses are sent with a packet which includes a
+ * checksum.  A packet consists of
+ *
+ * $<packet info>#<checksum>.
+ *
+ * where
+ * <packet info> :: <characters representing the command or response>
+ * <checksum>    :: < two hex digits computed as modulo 256 sum of <packetinfo>>
+ *
+ * When a packet is received, it is first acknowledged with either '+' or '-'.
+ * '+' indicates a successful transfer.  '-' indicates a failed transfer.
+ *
+ * Example:
+ *
+ * Host:                  Reply:
+ * $m0,10#2a               +$00010203040506070809101112131415#42
+ *
+ */
+
+
+#include <linux/string.h>
+#include <linux/signal.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/linkage.h>
+#include <linux/reboot.h>
+
+#include <asm/setup.h>
+#include <asm/ptrace.h>
+
+#include <asm/irq.h>
+#include <asm/arch/hwregs/reg_map.h>
+#include <asm/arch/hwregs/reg_rdwr.h>
+#include <asm/arch/hwregs/intr_vect_defs.h>
+#include <asm/arch/hwregs/ser_defs.h>
+
+/* From entry.S. */
+extern void gdb_handle_exception(void);
+/* From kgdb_asm.S. */
+extern void kgdb_handle_exception(void);
+
+static int kgdb_started = 0;
+
+/********************************* Register image ****************************/
+
+typedef
+struct register_image
+{
+	                      /* Offset */
+	unsigned int   r0;    /* 0x00 */
+	unsigned int   r1;    /* 0x04 */
+	unsigned int   r2;    /* 0x08 */
+	unsigned int   r3;    /* 0x0C */
+	unsigned int   r4;    /* 0x10 */
+	unsigned int   r5;    /* 0x14 */
+	unsigned int   r6;    /* 0x18 */
+	unsigned int   r7;    /* 0x1C */
+	unsigned int   r8;    /* 0x20; Frame pointer (if any) */
+	unsigned int   r9;    /* 0x24 */
+	unsigned int   r10;   /* 0x28 */
+	unsigned int   r11;   /* 0x2C */
+	unsigned int   r12;   /* 0x30 */
+	unsigned int   r13;   /* 0x34 */
+	unsigned int   sp;    /* 0x38; R14, Stack pointer */
+	unsigned int   acr;   /* 0x3C; R15, Address calculation register. */
+
+	unsigned char  bz;    /* 0x40; P0, 8-bit zero register */
+	unsigned char  vr;    /* 0x41; P1, Version register (8-bit) */
+	unsigned int   pid;   /* 0x42; P2, Process ID */
+	unsigned char  srs;   /* 0x46; P3, Support register select (8-bit) */
+        unsigned short wz;    /* 0x47; P4, 16-bit zero register */
+	unsigned int   exs;   /* 0x49; P5, Exception status */
+	unsigned int   eda;   /* 0x4D; P6, Exception data address */
+	unsigned int   mof;   /* 0x51; P7, Multiply overflow register */
+	unsigned int   dz;    /* 0x55; P8, 32-bit zero register */
+	unsigned int   ebp;   /* 0x59; P9, Exception base pointer */
+	unsigned int   erp;   /* 0x5D; P10, Exception return pointer. Contains the PC we are interested in. */
+	unsigned int   srp;   /* 0x61; P11, Subroutine return pointer */
+	unsigned int   nrp;   /* 0x65; P12, NMI return pointer */
+	unsigned int   ccs;   /* 0x69; P13, Condition code stack */
+	unsigned int   usp;   /* 0x6D; P14, User mode stack pointer */
+	unsigned int   spc;   /* 0x71; P15, Single step PC */
+	unsigned int   pc;    /* 0x75; Pseudo register (for the most part set to ERP). */
+
+} registers;
+
+typedef
+struct bp_register_image
+{
+	/* Support register bank 0. */
+	unsigned int   s0_0;
+	unsigned int   s1_0;
+	unsigned int   s2_0;
+	unsigned int   s3_0;
+	unsigned int   s4_0;
+	unsigned int   s5_0;
+	unsigned int   s6_0;
+	unsigned int   s7_0;
+	unsigned int   s8_0;
+	unsigned int   s9_0;
+	unsigned int   s10_0;
+	unsigned int   s11_0;
+	unsigned int   s12_0;
+	unsigned int   s13_0;
+	unsigned int   s14_0;
+	unsigned int   s15_0;
+
+	/* Support register bank 1. */
+	unsigned int   s0_1;
+	unsigned int   s1_1;
+	unsigned int   s2_1;
+	unsigned int   s3_1;
+	unsigned int   s4_1;
+	unsigned int   s5_1;
+	unsigned int   s6_1;
+	unsigned int   s7_1;
+	unsigned int   s8_1;
+	unsigned int   s9_1;
+	unsigned int   s10_1;
+	unsigned int   s11_1;
+	unsigned int   s12_1;
+	unsigned int   s13_1;
+	unsigned int   s14_1;
+	unsigned int   s15_1;
+
+	/* Support register bank 2. */
+	unsigned int   s0_2;
+	unsigned int   s1_2;
+	unsigned int   s2_2;
+	unsigned int   s3_2;
+	unsigned int   s4_2;
+	unsigned int   s5_2;
+	unsigned int   s6_2;
+	unsigned int   s7_2;
+	unsigned int   s8_2;
+	unsigned int   s9_2;
+	unsigned int   s10_2;
+	unsigned int   s11_2;
+	unsigned int   s12_2;
+	unsigned int   s13_2;
+	unsigned int   s14_2;
+	unsigned int   s15_2;
+
+	/* Support register bank 3. */
+	unsigned int   s0_3; /* BP_CTRL */
+	unsigned int   s1_3; /* BP_I0_START */
+	unsigned int   s2_3; /* BP_I0_END */
+	unsigned int   s3_3; /* BP_D0_START */
+	unsigned int   s4_3; /* BP_D0_END */
+	unsigned int   s5_3; /* BP_D1_START */
+	unsigned int   s6_3; /* BP_D1_END */
+	unsigned int   s7_3; /* BP_D2_START */
+	unsigned int   s8_3; /* BP_D2_END */
+	unsigned int   s9_3; /* BP_D3_START */
+	unsigned int   s10_3; /* BP_D3_END */
+	unsigned int   s11_3; /* BP_D4_START */
+	unsigned int   s12_3; /* BP_D4_END */
+	unsigned int   s13_3; /* BP_D5_START */
+	unsigned int   s14_3; /* BP_D5_END */
+	unsigned int   s15_3; /* BP_RESERVED */
+
+} support_registers;
+
+enum register_name
+{
+	R0,  R1,  R2,  R3,
+	R4,  R5,  R6,  R7,
+	R8,  R9,  R10, R11,
+	R12, R13, SP,  ACR,
+
+	BZ,  VR,  PID, SRS,
+	WZ,  EXS, EDA, MOF,
+	DZ,  EBP, ERP, SRP,
+	NRP, CCS, USP, SPC,
+	PC,
+
+	S0,  S1,  S2,  S3,
+	S4,  S5,  S6,  S7,
+	S8,  S9,  S10, S11,
+	S12, S13, S14, S15
+
+};
+
+/* The register sizes of the registers in register_name. An unimplemented register
+   is designated by size 0 in this array. */
+static int register_size[] =
+{
+	4, 4, 4, 4,
+	4, 4, 4, 4,
+	4, 4, 4, 4,
+	4, 4, 4, 4,
+
+	1, 1, 4, 1,
+	2, 4, 4, 4,
+	4, 4, 4, 4,
+	4, 4, 4, 4,
+
+	4,
+
+	4, 4, 4, 4,
+	4, 4, 4, 4,
+	4, 4, 4, 4,
+	4, 4, 4
+
+};
+
+/* Contains the register image of the kernel.
+   (Global so that they can be reached from assembler code.) */
+registers reg;
+support_registers sreg;
+
+/************** Prototypes for local library functions ***********************/
+
+/* Copy of strcpy from libc. */
+static char *gdb_cris_strcpy(char *s1, const char *s2);
+
+/* Copy of strlen from libc. */
+static int gdb_cris_strlen(const char *s);
+
+/* Copy of memchr from libc. */
+static void *gdb_cris_memchr(const void *s, int c, int n);
+
+/* Copy of strtol from libc. Does only support base 16. */
+static int gdb_cris_strtol(const char *s, char **endptr, int base);
+
+/********************** Prototypes for local functions. **********************/
+
+/* Write a value to a specified register regno in the register image
+   of the current thread. */
+static int write_register(int regno, char *val);
+
+/* Read a value from a specified register in the register image. Returns the
+   status of the read operation. The register value is returned in valptr. */
+static int read_register(char regno, unsigned int *valptr);
+
+/* Serial port, reads one character. ETRAX 100 specific. from debugport.c */
+int getDebugChar(void);
+
+#ifdef CONFIG_ETRAXFS_SIM
+int getDebugChar(void)
+{
+  return socketread();
+}
+#endif
+
+/* Serial port, writes one character. ETRAX 100 specific. from debugport.c */
+void putDebugChar(int val);
+
+#ifdef CONFIG_ETRAXFS_SIM
+void putDebugChar(int val)
+{
+  socketwrite((char *)&val, 1);
+}
+#endif
+
+/* Returns the character equivalent of a nibble, bit 7, 6, 5, and 4 of a byte,
+   represented by int x. */
+static char highhex(int x);
+
+/* Returns the character equivalent of a nibble, bit 3, 2, 1, and 0 of a byte,
+   represented by int x. */
+static char lowhex(int x);
+
+/* Returns the integer equivalent of a hexadecimal character. */
+static int hex(char ch);
+
+/* Convert the memory, pointed to by mem into hexadecimal representation.
+   Put the result in buf, and return a pointer to the last character
+   in buf (null). */
+static char *mem2hex(char *buf, unsigned char *mem, int count);
+
+/* Convert the array, in hexadecimal representation, pointed to by buf into
+   binary representation. Put the result in mem, and return a pointer to
+   the character after the last byte written. */
+static unsigned char *hex2mem(unsigned char *mem, char *buf, int count);
+
+/* Put the content of the array, in binary representation, pointed to by buf
+   into memory pointed to by mem, and return a pointer to
+   the character after the last byte written. */
+static unsigned char *bin2mem(unsigned char *mem, unsigned char *buf, int count);
+
+/* Await the sequence $<data>#<checksum> and store <data> in the array buffer
+   returned. */
+static void getpacket(char *buffer);
+
+/* Send $<data>#<checksum> from the <data> in the array buffer. */
+static void putpacket(char *buffer);
+
+/* Build and send a response packet in order to inform the host the
+   stub is stopped. */
+static void stub_is_stopped(int sigval);
+
+/* All expected commands are sent from remote.c. Send a response according
+   to the description in remote.c. Not static since it needs to be reached
+   from assembler code. */
+void handle_exception(int sigval);
+
+/* Performs a complete re-start from scratch. ETRAX specific. */
+static void kill_restart(void);
+
+/******************** Prototypes for global functions. ***********************/
+
+/* The string str is prepended with the GDB printout token and sent. */
+void putDebugString(const unsigned char *str, int len);
+
+/* A static breakpoint to be used at startup. */
+void breakpoint(void);
+
+/* Avoid warning as the internal_stack is not used in the C-code. */
+#define USEDVAR(name)    { if (name) { ; } }
+#define USEDFUN(name) { void (*pf)(void) = (void *)name; USEDVAR(pf) }
+
+/********************************** Packet I/O ******************************/
+/* BUFMAX defines the maximum number of characters in
+   inbound/outbound buffers */
+/* FIXME: How do we know it's enough? */
+#define BUFMAX 512
+
+/* Run-length encoding maximum length. Send 64 at most. */
+#define RUNLENMAX 64
+
+/* Definition of all valid hexadecimal characters */
+static const char hexchars[] = "0123456789abcdef";
+
+/* The inbound/outbound buffers used in packet I/O */
+static char input_buffer[BUFMAX];
+static char output_buffer[BUFMAX];
+
+/* Error and warning messages. */
+enum error_type
+{
+	SUCCESS, E01, E02, E03, E04, E05, E06,
+};
+
+static char *error_message[] =
+{
+	"",
+	"E01 Set current or general thread - H[c,g] - internal error.",
+	"E02 Change register content - P - cannot change read-only register.",
+	"E03 Thread is not alive.", /* T, not used. */
+	"E04 The command is not supported - [s,C,S,!,R,d,r] - internal error.",
+	"E05 Change register content - P - the register is not implemented..",
+	"E06 Change memory content - M - internal error.",
+};
+
+/********************************** Breakpoint *******************************/
+/* Use an internal stack in the breakpoint and interrupt response routines.
+   FIXME: How do we know the size of this stack is enough?
+   Global so it can be reached from assembler code. */
+#define INTERNAL_STACK_SIZE 1024
+char internal_stack[INTERNAL_STACK_SIZE];
+
+/* Due to the breakpoint return pointer, a state variable is needed to keep
+   track of whether it is a static (compiled) or dynamic (gdb-invoked)
+   breakpoint to be handled. A static breakpoint uses the content of register
+   ERP as it is whereas a dynamic breakpoint requires subtraction with 2
+   in order to execute the instruction. The first breakpoint is static; all
+   following are assumed to be dynamic. */
+static int dynamic_bp = 0;
+
+/********************************* String library ****************************/
+/* Single-step over library functions creates trap loops. */
+
+/* Copy char s2[] to s1[]. */
+static char*
+gdb_cris_strcpy(char *s1, const char *s2)
+{
+	char *s = s1;
+
+	for (s = s1; (*s++ = *s2++) != '\0'; )
+		;
+	return s1;
+}
+
+/* Find length of s[]. */
+static int
+gdb_cris_strlen(const char *s)
+{
+	const char *sc;
+
+	for (sc = s; *sc != '\0'; sc++)
+		;
+	return (sc - s);
+}
+
+/* Find first occurrence of c in s[n]. */
+static void*
+gdb_cris_memchr(const void *s, int c, int n)
+{
+	const unsigned char uc = c;
+	const unsigned char *su;
+
+	for (su = s; 0 < n; ++su, --n)
+		if (*su == uc)
+			return (void *)su;
+	return NULL;
+}
+/******************************* Standard library ****************************/
+/* Single-step over library functions creates trap loops. */
+/* Convert string to long. */
+static int
+gdb_cris_strtol(const char *s, char **endptr, int base)
+{
+	char *s1;
+	char *sd;
+	int x = 0;
+
+	for (s1 = (char*)s; (sd = gdb_cris_memchr(hexchars, *s1, base)) != NULL; ++s1)
+		x = x * base + (sd - hexchars);
+
+        if (endptr) {
+                /* Unconverted suffix is stored in endptr unless endptr is NULL. */
+                *endptr = s1;
+        }
+
+	return x;
+}
+
+/********************************* Register image ****************************/
+
+/* Write a value to a specified register in the register image of the current
+   thread. Returns status code SUCCESS, E02 or E05. */
+static int
+write_register(int regno, char *val)
+{
+	int status = SUCCESS;
+
+        if (regno >= R0 && regno <= ACR) {
+		/* Consecutive 32-bit registers. */
+		hex2mem((unsigned char *)&reg.r0 + (regno - R0) * sizeof(unsigned int),
+			val, sizeof(unsigned int));
+
+	} else if (regno == BZ || regno == VR || regno == WZ || regno == DZ) {
+		/* Read-only registers. */
+		status = E02;
+
+	} else if (regno == PID) {
+		/* 32-bit register. (Even though we already checked SRS and WZ, we cannot
+		   combine this with the EXS - SPC write since SRS and WZ have different size.) */
+		hex2mem((unsigned char *)&reg.pid, val, sizeof(unsigned int));
+
+	} else if (regno == SRS) {
+		/* 8-bit register. */
+		hex2mem((unsigned char *)&reg.srs, val, sizeof(unsigned char));
+
+	} else if (regno >= EXS && regno <= SPC) {
+		/* Consecutive 32-bit registers. */
+		hex2mem((unsigned char *)&reg.exs + (regno - EXS) * sizeof(unsigned int),
+			 val, sizeof(unsigned int));
+
+       } else if (regno == PC) {
+               /* Pseudo-register. Treat as read-only. */
+               status = E02;
+
+       } else if (regno >= S0 && regno <= S15) {
+               /* 32-bit registers. */
+               hex2mem((unsigned char *)&sreg.s0_0 + (reg.srs * 16 * sizeof(unsigned int)) + (regno - S0) * sizeof(unsigned int), val, sizeof(unsigned int));
+	} else {
+		/* Non-existing register. */
+		status = E05;
+	}
+	return status;
+}
+
+/* Read a value from a specified register in the register image. Returns the
+   value in the register or -1 for non-implemented registers. */
+static int
+read_register(char regno, unsigned int *valptr)
+{
+	int status = SUCCESS;
+
+	/* We read the zero registers from the register struct (instead of just returning 0)
+	   to catch errors. */
+
+	if (regno >= R0 && regno <= ACR) {
+		/* Consecutive 32-bit registers. */
+		*valptr = *(unsigned int *)((char *)&reg.r0 + (regno - R0) * sizeof(unsigned int));
+
+	} else if (regno == BZ || regno == VR) {
+		/* Consecutive 8-bit registers. */
+		*valptr = (unsigned int)(*(unsigned char *)
+                                         ((char *)&reg.bz + (regno - BZ) * sizeof(char)));
+
+	} else if (regno == PID) {
+		/* 32-bit register. */
+		*valptr =  *(unsigned int *)((char *)&reg.pid);
+
+	} else if (regno == SRS) {
+		/* 8-bit register. */
+		*valptr = (unsigned int)(*(unsigned char *)((char *)&reg.srs));
+
+	} else if (regno == WZ) {
+		/* 16-bit register. */
+		*valptr = (unsigned int)(*(unsigned short *)(char *)&reg.wz);
+
+	} else if (regno >= EXS && regno <= PC) {
+		/* Consecutive 32-bit registers. */
+		*valptr = *(unsigned int *)((char *)&reg.exs + (regno - EXS) * sizeof(unsigned int));
+
+	} else if (regno >= S0 && regno <= S15) {
+		/* Consecutive 32-bit registers, located elsewhere. */
+		*valptr = *(unsigned int *)((char *)&sreg.s0_0 + (reg.srs * 16 * sizeof(unsigned int)) + (regno - S0) * sizeof(unsigned int));
+
+	} else {
+		/* Non-existing register. */
+		status = E05;
+	}
+	return status;
+
+}
+
+/********************************** Packet I/O ******************************/
+/* Returns the character equivalent of a nibble, bit 7, 6, 5, and 4 of a byte,
+   represented by int x. */
+static inline char
+highhex(int x)
+{
+	return hexchars[(x >> 4) & 0xf];
+}
+
+/* Returns the character equivalent of a nibble, bit 3, 2, 1, and 0 of a byte,
+   represented by int x. */
+static inline char
+lowhex(int x)
+{
+	return hexchars[x & 0xf];
+}
+
+/* Returns the integer equivalent of a hexadecimal character. */
+static int
+hex(char ch)
+{
+	if ((ch >= 'a') && (ch <= 'f'))
+		return (ch - 'a' + 10);
+	if ((ch >= '0') && (ch <= '9'))
+		return (ch - '0');
+	if ((ch >= 'A') && (ch <= 'F'))
+		return (ch - 'A' + 10);
+	return -1;
+}
+
+/* Convert the memory, pointed to by mem into hexadecimal representation.
+   Put the result in buf, and return a pointer to the last character
+   in buf (null). */
+
+static char *
+mem2hex(char *buf, unsigned char *mem, int count)
+{
+	int i;
+	int ch;
+
+        if (mem == NULL) {
+		/* Invalid address, caught by 'm' packet handler. */
+                for (i = 0; i < count; i++) {
+                        *buf++ = '0';
+                        *buf++ = '0';
+                }
+        } else {
+                /* Valid mem address. */
+		for (i = 0; i < count; i++) {
+			ch = *mem++;
+			*buf++ = highhex (ch);
+			*buf++ = lowhex (ch);
+		}
+        }
+        /* Terminate properly. */
+	*buf = '\0';
+	return buf;
+}
+
+/* Same as mem2hex, but puts it in network byte order. */
+static char *
+mem2hex_nbo(char *buf, unsigned char *mem, int count)
+{
+	int i;
+	int ch;
+
+	mem += count - 1;
+	for (i = 0; i < count; i++) {
+		ch = *mem--;
+		*buf++ = highhex (ch);
+		*buf++ = lowhex (ch);
+        }
+
+        /* Terminate properly. */
+	*buf = '\0';
+	return buf;
+}
+
+/* Convert the array, in hexadecimal representation, pointed to by buf into
+   binary representation. Put the result in mem, and return a pointer to
+   the character after the last byte written. */
+static unsigned char*
+hex2mem(unsigned char *mem, char *buf, int count)
+{
+	int i;
+	unsigned char ch;
+	for (i = 0; i < count; i++) {
+		ch = hex (*buf++) << 4;
+		ch = ch + hex (*buf++);
+		*mem++ = ch;
+	}
+	return mem;
+}
+
+/* Put the content of the array, in binary representation, pointed to by buf
+   into memory pointed to by mem, and return a pointer to the character after
+   the last byte written.
+   Gdb will escape $, #, and the escape char (0x7d). */
+static unsigned char*
+bin2mem(unsigned char *mem, unsigned char *buf, int count)
+{
+	int i;
+	unsigned char *next;
+	for (i = 0; i < count; i++) {
+		/* Check for any escaped characters. Be paranoid and
+		   only unescape chars that should be escaped. */
+		if (*buf == 0x7d) {
+			next = buf + 1;
+			if (*next == 0x3 || *next == 0x4 || *next == 0x5D) {
+				 /* #, $, ESC */
+				buf++;
+				*buf += 0x20;
+			}
+		}
+		*mem++ = *buf++;
+	}
+	return mem;
+}
+
+/* Await the sequence $<data>#<checksum> and store <data> in the array buffer
+   returned. */
+static void
+getpacket(char *buffer)
+{
+	unsigned char checksum;
+	unsigned char xmitcsum;
+	int i;
+	int count;
+	char ch;
+
+	do {
+		while((ch = getDebugChar ()) != '$')
+			/* Wait for the start character $ and ignore all other characters */;
+		checksum = 0;
+		xmitcsum = -1;
+		count = 0;
+		/* Read until a # or the end of the buffer is reached */
+		while (count < BUFMAX) {
+			ch = getDebugChar();
+			if (ch == '#')
+				break;
+			checksum = checksum + ch;
+			buffer[count] = ch;
+			count = count + 1;
+		}
+
+		if (count >= BUFMAX)
+			continue;
+
+		buffer[count] = 0;
+
+		if (ch == '#') {
+			xmitcsum = hex(getDebugChar()) << 4;
+			xmitcsum += hex(getDebugChar());
+			if (checksum != xmitcsum) {
+				/* Wrong checksum */
+				putDebugChar('-');
+			} else {
+				/* Correct checksum */
+				putDebugChar('+');
+				/* If sequence characters are received, reply with them */
+				if (buffer[2] == ':') {
+					putDebugChar(buffer[0]);
+					putDebugChar(buffer[1]);
+					/* Remove the sequence characters from the buffer */
+					count = gdb_cris_strlen(buffer);
+					for (i = 3; i <= count; i++)
+						buffer[i - 3] = buffer[i];
+				}
+			}
+		}
+	} while (checksum != xmitcsum);
+}
+
+/* Send $<data>#<checksum> from the <data> in the array buffer. */
+
+static void
+putpacket(char *buffer)
+{
+	int checksum;
+	int runlen;
+	int encode;
+
+	do {
+		char *src = buffer;
+		putDebugChar('$');
+		checksum = 0;
+		while (*src) {
+			/* Do run length encoding */
+			putDebugChar(*src);
+			checksum += *src;
+			runlen = 0;
+			while (runlen < RUNLENMAX && *src == src[runlen]) {
+				runlen++;
+			}
+			if (runlen > 3) {
+				/* Got a useful amount */
+				putDebugChar ('*');
+				checksum += '*';
+				encode = runlen + ' ' - 4;
+				putDebugChar(encode);
+				checksum += encode;
+				src += runlen;
+			} else {
+				src++;
+			}
+		}
+		putDebugChar('#');
+		putDebugChar(highhex (checksum));
+		putDebugChar(lowhex (checksum));
+	} while(kgdb_started && (getDebugChar() != '+'));
+}
+
+/* The string str is prepended with the GDB printout token and sent. Required
+   in traditional implementations. */
+void
+putDebugString(const unsigned char *str, int len)
+{
+	/* Move SPC forward if we are single-stepping. */
+	asm("spchere:");
+	asm("move $spc, $r10");
+	asm("cmp.d spchere, $r10");
+	asm("bne nosstep");
+	asm("nop");
+	asm("move.d spccont, $r10");
+	asm("move $r10, $spc");
+	asm("nosstep:");
+
+        output_buffer[0] = 'O';
+        mem2hex(&output_buffer[1], (unsigned char *)str, len);
+        putpacket(output_buffer);
+
+	asm("spccont:");
+}
+
+/********************************** Handle exceptions ************************/
+/* Build and send a response packet in order to inform the host the
+   stub is stopped. TAAn...:r...;n...:r...;n...:r...;
+                    AA = signal number
+                    n... = register number (hex)
+                    r... = register contents
+                    n... = `thread'
+                    r... = thread process ID.  This is a hex integer.
+                    n... = other string not starting with valid hex digit.
+                    gdb should ignore this n,r pair and go on to the next.
+                    This way we can extend the protocol. */
+static void
+stub_is_stopped(int sigval)
+{
+	char *ptr = output_buffer;
+	unsigned int reg_cont;
+
+	/* Send trap type (converted to signal) */
+
+	*ptr++ = 'T';
+	*ptr++ = highhex(sigval);
+	*ptr++ = lowhex(sigval);
+
+	if (((reg.exs & 0xff00) >> 8) == 0xc) {
+
+		/* Some kind of hardware watchpoint triggered. Find which one
+		   and determine its type (read/write/access).  */
+		int S, bp, trig_bits = 0, rw_bits = 0;
+		int trig_mask = 0;
+		unsigned int *bp_d_regs = &sreg.s3_3;
+		/* In a lot of cases, the stopped data address will simply be EDA.
+		   In some cases, we adjust it to match the watched data range.
+		   (We don't want to change the actual EDA though). */
+		unsigned int stopped_data_address;
+		/* The S field of EXS. */
+		S = (reg.exs & 0xffff0000) >> 16;
+
+		if (S & 1) {
+			/* Instruction watchpoint. */
+			/* FIXME: Check against, and possibly adjust reported EDA. */
+		} else {
+			/* Data watchpoint.  Find the one that triggered. */
+			for (bp = 0; bp < 6; bp++) {
+
+				/* Dx_RD, Dx_WR in the S field of EXS for this BP. */
+				int bitpos_trig = 1 + bp * 2;
+				/* Dx_BPRD, Dx_BPWR in BP_CTRL for this BP. */
+				int bitpos_config = 2 + bp * 4;
+
+				/* Get read/write trig bits for this BP. */
+				trig_bits = (S & (3 << bitpos_trig)) >> bitpos_trig;
+
+				/* Read/write config bits for this BP. */
+				rw_bits = (sreg.s0_3 & (3 << bitpos_config)) >> bitpos_config;
+				if (trig_bits) {
+					/* Sanity check: the BP shouldn't trigger for accesses
+					   that it isn't configured for. */
+					if ((rw_bits == 0x1 && trig_bits != 0x1) ||
+					    (rw_bits == 0x2 && trig_bits != 0x2))
+						panic("Invalid r/w trigging for this BP");
+
+					/* Mark this BP as trigged for future reference. */
+					trig_mask |= (1 << bp);
+
+					if (reg.eda >= bp_d_regs[bp * 2] &&
+					    reg.eda <= bp_d_regs[bp * 2 + 1]) {
+						/* EDA withing range for this BP; it must be the one
+						   we're looking for. */
+						stopped_data_address = reg.eda;
+						break;
+					}
+				}
+			}
+			if (bp < 6) {
+				/* Found a trigged BP with EDA within its configured data range. */
+			} else if (trig_mask) {
+				/* Something triggered, but EDA doesn't match any BP's range. */
+				for (bp = 0; bp < 6; bp++) {
+					/* Dx_BPRD, Dx_BPWR in BP_CTRL for this BP. */
+					int bitpos_config = 2 + bp * 4;
+
+					/* Read/write config bits for this BP (needed later). */
+					rw_bits = (sreg.s0_3 & (3 << bitpos_config)) >> bitpos_config;
+
+					if (trig_mask & (1 << bp)) {
+						/* EDA within 31 bytes of the configured start address? */
+						if (reg.eda + 31 >= bp_d_regs[bp * 2]) {
+							/* Changing the reported address to match
+							   the start address of the first applicable BP. */
+							stopped_data_address = bp_d_regs[bp * 2];
+							break;
+						} else {
+							/* We continue since we might find another useful BP. */
+							printk("EDA doesn't match trigged BP's range");
+						}
+					}
+				}
+			}
+
+			/* No match yet? */
+			BUG_ON(bp >= 6);
+			/* Note that we report the type according to what the BP is configured
+			   for (otherwise we'd never report an 'awatch'), not according to how
+			   it trigged. We did check that the trigged bits match what the BP is
+			   configured for though. */
+			if (rw_bits == 0x1) {
+				/* read */
+				strncpy(ptr, "rwatch", 6);
+				ptr += 6;
+			} else if (rw_bits == 0x2) {
+				/* write */
+				strncpy(ptr, "watch", 5);
+				ptr += 5;
+			} else if (rw_bits == 0x3) {
+				/* access */
+				strncpy(ptr, "awatch", 6);
+				ptr += 6;
+			} else {
+				panic("Invalid r/w bits for this BP.");
+			}
+
+			*ptr++ = ':';
+			/* Note that we don't read_register(EDA, ...) */
+			ptr = mem2hex_nbo(ptr, (unsigned char *)&stopped_data_address, register_size[EDA]);
+			*ptr++ = ';';
+		}
+	}
+	/* Only send PC, frame and stack pointer. */
+	read_register(PC, &reg_cont);
+	*ptr++ = highhex(PC);
+	*ptr++ = lowhex(PC);
+	*ptr++ = ':';
+	ptr = mem2hex(ptr, (unsigned char *)&reg_cont, register_size[PC]);
+	*ptr++ = ';';
+
+	read_register(R8, &reg_cont);
+	*ptr++ = highhex(R8);
+	*ptr++ = lowhex(R8);
+	*ptr++ = ':';
+	ptr = mem2hex(ptr, (unsigned char *)&reg_cont, register_size[R8]);
+	*ptr++ = ';';
+
+	read_register(SP, &reg_cont);
+	*ptr++ = highhex(SP);
+	*ptr++ = lowhex(SP);
+	*ptr++ = ':';
+	ptr = mem2hex(ptr, (unsigned char *)&reg_cont, register_size[SP]);
+	*ptr++ = ';';
+
+	/* Send ERP as well; this will save us an entire register fetch in some cases. */
+        read_register(ERP, &reg_cont);
+        *ptr++ = highhex(ERP);
+        *ptr++ = lowhex(ERP);
+        *ptr++ = ':';
+        ptr = mem2hex(ptr, (unsigned char *)&reg_cont, register_size[ERP]);
+        *ptr++ = ';';
+
+	/* null-terminate and send it off */
+	*ptr = 0;
+	putpacket(output_buffer);
+}
+
+/* Returns the size of an instruction that has a delay slot. */
+
+int insn_size(unsigned long pc)
+{
+	unsigned short opcode = *(unsigned short *)pc;
+	int size = 0;
+
+	switch ((opcode & 0x0f00) >> 8) {
+	case 0x0:
+	case 0x9:
+	case 0xb:
+		size = 2;
+		break;
+	case 0xe:
+	case 0xf:
+		size = 6;
+		break;
+	case 0xd:
+		/* Could be 4 or 6; check more bits. */
+		if ((opcode & 0xff) == 0xff)
+			size = 4;
+		else
+			size = 6;
+		break;
+	default:
+		panic("Couldn't find size of opcode 0x%x at 0x%lx\n", opcode, pc);
+	}
+
+	return size;
+}
+
+void register_fixup(int sigval)
+{
+	/* Compensate for ACR push at the beginning of exception handler. */
+	reg.sp += 4;
+
+	/* Standard case. */
+	reg.pc = reg.erp;
+	if (reg.erp & 0x1) {
+		/* Delay slot bit set.  Report as stopped on proper instruction.  */
+		if (reg.spc) {
+			/* Rely on SPC if set. */
+			reg.pc = reg.spc;
+		} else {
+			/* Calculate the PC from the size of the instruction
+			   that the delay slot we're in belongs to. */
+			reg.pc += insn_size(reg.erp & ~1) - 1 ;
+		}
+	}
+
+	if ((reg.exs & 0x3) == 0x0) {
+		/* Bits 1 - 0 indicate the type of memory operation performed
+		   by the interrupted instruction. 0 means no memory operation,
+		   and EDA is undefined in that case. We zero it to avoid confusion. */
+		reg.eda = 0;
+	}
+
+	if (sigval == SIGTRAP) {
+		/* Break 8, single step or hardware breakpoint exception. */
+
+		/* Check IDX field of EXS. */
+		if (((reg.exs & 0xff00) >> 8) == 0x18) {
+
+			/* Break 8. */
+
+                        /* Static (compiled) breakpoints must return to the next instruction
+			   in order to avoid infinite loops (default value of ERP). Dynamic
+			   (gdb-invoked) must subtract the size of the break instruction from
+			   the ERP so that the instruction that was originally in the break
+			   instruction's place will be run when we return from the exception. */
+			if (!dynamic_bp) {
+				/* Assuming that all breakpoints are dynamic from now on. */
+				dynamic_bp = 1;
+			} else {
+
+				/* Only if not in a delay slot. */
+				if (!(reg.erp & 0x1)) {
+					reg.erp -= 2;
+					reg.pc -= 2;
+				}
+			}
+
+		} else if (((reg.exs & 0xff00) >> 8) == 0x3) {
+			/* Single step. */
+			/* Don't fiddle with S1. */
+
+		} else if (((reg.exs & 0xff00) >> 8) == 0xc) {
+
+			/* Hardware watchpoint exception. */
+
+			/* SPC has been updated so that we will get a single step exception
+			   when we return, but we don't want that. */
+			reg.spc = 0;
+
+			/* Don't fiddle with S1. */
+		}
+
+	} else if (sigval == SIGINT) {
+		/* Nothing special. */
+	}
+}
+
+static void insert_watchpoint(char type, int addr, int len)
+{
+	/* Breakpoint/watchpoint types (GDB terminology):
+	   0 = memory breakpoint for instructions
+	   (not supported; done via memory write instead)
+	   1 = hardware breakpoint for instructions (supported)
+	   2 = write watchpoint (supported)
+	   3 = read watchpoint (supported)
+	   4 = access watchpoint (supported) */
+
+	if (type < '1' || type > '4') {
+		output_buffer[0] = 0;
+		return;
+	}
+
+	/* Read watchpoints are set as access watchpoints, because of GDB's
+	   inability to deal with pure read watchpoints. */
+	if (type == '3')
+		type = '4';
+
+	if (type == '1') {
+		/* Hardware (instruction) breakpoint. */
+		/* Bit 0 in BP_CTRL holds the configuration for I0. */
+		if (sreg.s0_3 & 0x1) {
+			/* Already in use. */
+			gdb_cris_strcpy(output_buffer, error_message[E04]);
+			return;
+		}
+		/* Configure. */
+		sreg.s1_3 = addr;
+		sreg.s2_3 = (addr + len - 1);
+		sreg.s0_3 |= 1;
+	} else {
+		int bp;
+		unsigned int *bp_d_regs = &sreg.s3_3;
+
+		/* The watchpoint allocation scheme is the simplest possible.
+		   For example, if a region is watched for read and
+		   a write watch is requested, a new watchpoint will
+		   be used. Also, if a watch for a region that is already
+		   covered by one or more existing watchpoints, a new
+		   watchpoint will be used. */
+
+		/* First, find a free data watchpoint. */
+		for (bp = 0; bp < 6; bp++) {
+			/* Each data watchpoint's control registers occupy 2 bits
+			   (hence the 3), starting at bit 2 for D0 (hence the 2)
+			   with 4 bits between for each watchpoint (yes, the 4). */
+			if (!(sreg.s0_3 & (0x3 << (2 + (bp * 4))))) {
+				break;
+			}
+		}
+
+		if (bp > 5) {
+			/* We're out of watchpoints. */
+			gdb_cris_strcpy(output_buffer, error_message[E04]);
+			return;
+		}
+
+		/* Configure the control register first. */
+		if (type == '3' || type == '4') {
+			/* Trigger on read. */
+			sreg.s0_3 |= (1 << (2 + bp * 4));
+		}
+		if (type == '2' || type == '4') {
+			/* Trigger on write. */
+			sreg.s0_3 |= (2 << (2 + bp * 4));
+		}
+
+		/* Ugly pointer arithmetics to configure the watched range. */
+		bp_d_regs[bp * 2] = addr;
+		bp_d_regs[bp * 2 + 1] = (addr + len - 1);
+	}
+
+	/* Set the S1 flag to enable watchpoints. */
+	reg.ccs |= (1 << (S_CCS_BITNR + CCS_SHIFT));
+	gdb_cris_strcpy(output_buffer, "OK");
+}
+
+static void remove_watchpoint(char type, int addr, int len)
+{
+	/* Breakpoint/watchpoint types:
+	   0 = memory breakpoint for instructions
+	   (not supported; done via memory write instead)
+	   1 = hardware breakpoint for instructions (supported)
+	   2 = write watchpoint (supported)
+	   3 = read watchpoint (supported)
+	   4 = access watchpoint (supported) */
+	if (type < '1' || type > '4') {
+		output_buffer[0] = 0;
+		return;
+	}
+
+	/* Read watchpoints are set as access watchpoints, because of GDB's
+	   inability to deal with pure read watchpoints. */
+	if (type == '3')
+		type = '4';
+
+	if (type == '1') {
+		/* Hardware breakpoint. */
+		/* Bit 0 in BP_CTRL holds the configuration for I0. */
+		if (!(sreg.s0_3 & 0x1)) {
+			/* Not in use. */
+			gdb_cris_strcpy(output_buffer, error_message[E04]);
+			return;
+		}
+		/* Deconfigure. */
+		sreg.s1_3 = 0;
+		sreg.s2_3 = 0;
+		sreg.s0_3 &= ~1;
+	} else {
+		int bp;
+		unsigned int *bp_d_regs = &sreg.s3_3;
+		/* Try to find a watchpoint that is configured for the
+		   specified range, then check that read/write also matches. */
+
+		/* Ugly pointer arithmetic, since I cannot rely on a
+		   single switch (addr) as there may be several watchpoints with
+		   the same start address for example. */
+
+		for (bp = 0; bp < 6; bp++) {
+			if (bp_d_regs[bp * 2] == addr &&
+			    bp_d_regs[bp * 2 + 1] == (addr + len - 1)) {
+				/* Matching range. */
+				int bitpos = 2 + bp * 4;
+				int rw_bits;
+
+				/* Read/write bits for this BP. */
+				rw_bits = (sreg.s0_3 & (0x3 << bitpos)) >> bitpos;
+
+				if ((type == '3' && rw_bits == 0x1) ||
+				    (type == '2' && rw_bits == 0x2) ||
+				    (type == '4' && rw_bits == 0x3)) {
+					/* Read/write matched. */
+					break;
+				}
+			}
+		}
+
+		if (bp > 5) {
+			/* No watchpoint matched. */
+			gdb_cris_strcpy(output_buffer, error_message[E04]);
+			return;
+		}
+
+		/* Found a matching watchpoint. Now, deconfigure it by
+		   both disabling read/write in bp_ctrl and zeroing its
+		   start/end addresses. */
+		sreg.s0_3 &= ~(3 << (2 + (bp * 4)));
+		bp_d_regs[bp * 2] = 0;
+		bp_d_regs[bp * 2 + 1] = 0;
+	}
+
+	/* Note that we don't clear the S1 flag here. It's done when continuing.  */
+	gdb_cris_strcpy(output_buffer, "OK");
+}
+
+
+
+/* All expected commands are sent from remote.c. Send a response according
+   to the description in remote.c. */
+void
+handle_exception(int sigval)
+{
+	/* Avoid warning of not used. */
+
+	USEDFUN(handle_exception);
+	USEDVAR(internal_stack[0]);
+
+	register_fixup(sigval);
+
+	/* Send response. */
+	stub_is_stopped(sigval);
+
+	for (;;) {
+		output_buffer[0] = '\0';
+		getpacket(input_buffer);
+		switch (input_buffer[0]) {
+			case 'g':
+				/* Read registers: g
+				   Success: Each byte of register data is described by two hex digits.
+				   Registers are in the internal order for GDB, and the bytes
+				   in a register  are in the same order the machine uses.
+				   Failure: void. */
+			{
+				char *buf;
+				/* General and special registers. */
+				buf = mem2hex(output_buffer, (char *)&reg, sizeof(registers));
+				/* Support registers. */
+				/* -1 because of the null termination that mem2hex adds. */
+				mem2hex(buf,
+					(char *)&sreg + (reg.srs * 16 * sizeof(unsigned int)),
+					16 * sizeof(unsigned int));
+				break;
+			}
+			case 'G':
+				/* Write registers. GXX..XX
+				   Each byte of register data  is described by two hex digits.
+				   Success: OK
+				   Failure: void. */
+				/* General and special registers. */
+				hex2mem((char *)&reg, &input_buffer[1], sizeof(registers));
+				/* Support registers. */
+				hex2mem((char *)&sreg + (reg.srs * 16 * sizeof(unsigned int)),
+					&input_buffer[1] + sizeof(registers),
+					16 * sizeof(unsigned int));
+				gdb_cris_strcpy(output_buffer, "OK");
+				break;
+
+			case 'P':
+				/* Write register. Pn...=r...
+				   Write register n..., hex value without 0x, with value r...,
+				   which contains a hex value without 0x and two hex digits
+				   for each byte in the register (target byte order). P1f=11223344 means
+				   set register 31 to 44332211.
+				   Success: OK
+				   Failure: E02, E05 */
+				{
+					char *suffix;
+					int regno = gdb_cris_strtol(&input_buffer[1], &suffix, 16);
+					int status;
+
+					status = write_register(regno, suffix+1);
+
+					switch (status) {
+						case E02:
+							/* Do not support read-only registers. */
+							gdb_cris_strcpy(output_buffer, error_message[E02]);
+							break;
+						case E05:
+							/* Do not support non-existing registers. */
+							gdb_cris_strcpy(output_buffer, error_message[E05]);
+							break;
+						default:
+							/* Valid register number. */
+							gdb_cris_strcpy(output_buffer, "OK");
+							break;
+					}
+				}
+				break;
+
+			case 'm':
+				/* Read from memory. mAA..AA,LLLL
+				   AA..AA is the address and LLLL is the length.
+				   Success: XX..XX is the memory content.  Can be fewer bytes than
+				   requested if only part of the data may be read. m6000120a,6c means
+				   retrieve 108 byte from base address 6000120a.
+				   Failure: void. */
+				{
+                                        char *suffix;
+					unsigned char *addr = (unsigned char *)gdb_cris_strtol(&input_buffer[1],
+                                                                                               &suffix, 16);
+					int len = gdb_cris_strtol(suffix+1, 0, 16);
+
+					/* Bogus read (i.e. outside the kernel's
+					   segment)? . */
+					if (!((unsigned int)addr >= 0xc0000000 &&
+					      (unsigned int)addr < 0xd0000000))
+						addr = NULL;
+
+                                        mem2hex(output_buffer, addr, len);
+                                }
+				break;
+
+			case 'X':
+				/* Write to memory. XAA..AA,LLLL:XX..XX
+				   AA..AA is the start address,  LLLL is the number of bytes, and
+				   XX..XX is the binary data.
+				   Success: OK
+				   Failure: void. */
+			case 'M':
+				/* Write to memory. MAA..AA,LLLL:XX..XX
+				   AA..AA is the start address,  LLLL is the number of bytes, and
+				   XX..XX is the hexadecimal data.
+				   Success: OK
+				   Failure: void. */
+				{
+					char *lenptr;
+					char *dataptr;
+					unsigned char *addr = (unsigned char *)gdb_cris_strtol(&input_buffer[1],
+										      &lenptr, 16);
+					int len = gdb_cris_strtol(lenptr+1, &dataptr, 16);
+					if (*lenptr == ',' && *dataptr == ':') {
+						if (input_buffer[0] == 'M') {
+							hex2mem(addr, dataptr + 1, len);
+						} else /* X */ {
+							bin2mem(addr, dataptr + 1, len);
+						}
+						gdb_cris_strcpy(output_buffer, "OK");
+					}
+					else {
+						gdb_cris_strcpy(output_buffer, error_message[E06]);
+					}
+				}
+				break;
+
+			case 'c':
+				/* Continue execution. cAA..AA
+				   AA..AA is the address where execution is resumed. If AA..AA is
+				   omitted, resume at the present address.
+				   Success: return to the executing thread.
+				   Failure: will never know. */
+
+				if (input_buffer[1] != '\0') {
+					/* FIXME: Doesn't handle address argument. */
+					gdb_cris_strcpy(output_buffer, error_message[E04]);
+					break;
+				}
+
+				/* Before continuing, make sure everything is set up correctly. */
+
+				/* Set the SPC to some unlikely value.  */
+				reg.spc = 0;
+				/* Set the S1 flag to 0 unless some watchpoint is enabled (since setting
+				   S1 to 0 would also disable watchpoints). (Note that bits 26-31 in BP_CTRL
+				   are reserved, so don't check against those). */
+				if ((sreg.s0_3 & 0x3fff) == 0) {
+					reg.ccs &= ~(1 << (S_CCS_BITNR + CCS_SHIFT));
+				}
+
+				return;
+
+			case 's':
+				/* Step. sAA..AA
+				   AA..AA is the address where execution is resumed. If AA..AA is
+				   omitted, resume at the present address. Success: return to the
+				   executing thread. Failure: will never know. */
+
+				if (input_buffer[1] != '\0') {
+					/* FIXME: Doesn't handle address argument. */
+					gdb_cris_strcpy(output_buffer, error_message[E04]);
+					break;
+				}
+
+				/* Set the SPC to PC, which is where we'll return
+				   (deduced previously). */
+				reg.spc = reg.pc;
+
+				/* Set the S1 (first stacked, not current) flag, which will
+				   kick into action when we rfe. */
+				reg.ccs |= (1 << (S_CCS_BITNR + CCS_SHIFT));
+				return;
+
+                       case 'Z':
+
+                               /* Insert breakpoint or watchpoint, Ztype,addr,length.
+                                  Remote protocol says: A remote target shall return an empty string
+                                  for an unrecognized breakpoint or watchpoint packet type. */
+                               {
+                                       char *lenptr;
+                                       char *dataptr;
+                                       int addr = gdb_cris_strtol(&input_buffer[3], &lenptr, 16);
+                                       int len = gdb_cris_strtol(lenptr + 1, &dataptr, 16);
+                                       char type = input_buffer[1];
+
+				       insert_watchpoint(type, addr, len);
+                                       break;
+                               }
+
+                       case 'z':
+                               /* Remove breakpoint or watchpoint, Ztype,addr,length.
+                                  Remote protocol says: A remote target shall return an empty string
+                                  for an unrecognized breakpoint or watchpoint packet type. */
+                               {
+                                       char *lenptr;
+                                       char *dataptr;
+                                       int addr = gdb_cris_strtol(&input_buffer[3], &lenptr, 16);
+                                       int len = gdb_cris_strtol(lenptr + 1, &dataptr, 16);
+                                       char type = input_buffer[1];
+
+                                       remove_watchpoint(type, addr, len);
+                                       break;
+                               }
+
+
+			case '?':
+				/* The last signal which caused a stop. ?
+				   Success: SAA, where AA is the signal number.
+				   Failure: void. */
+				output_buffer[0] = 'S';
+				output_buffer[1] = highhex(sigval);
+				output_buffer[2] = lowhex(sigval);
+				output_buffer[3] = 0;
+				break;
+
+			case 'D':
+				/* Detach from host. D
+				   Success: OK, and return to the executing thread.
+				   Failure: will never know */
+				putpacket("OK");
+				return;
+
+			case 'k':
+			case 'r':
+				/* kill request or reset request.
+				   Success: restart of target.
+				   Failure: will never know. */
+				kill_restart();
+				break;
+
+			case 'C':
+			case 'S':
+			case '!':
+			case 'R':
+			case 'd':
+				/* Continue with signal sig. Csig;AA..AA
+				   Step with signal sig. Ssig;AA..AA
+				   Use the extended remote protocol. !
+				   Restart the target system. R0
+				   Toggle debug flag. d
+				   Search backwards. tAA:PP,MM
+				   Not supported: E04 */
+
+				/* FIXME: What's the difference between not supported
+				   and ignored (below)? */
+				gdb_cris_strcpy(output_buffer, error_message[E04]);
+				break;
+
+			default:
+				/* The stub should ignore other request and send an empty
+				   response ($#<checksum>). This way we can extend the protocol and GDB
+				   can tell whether the stub it is talking to uses the old or the new. */
+				output_buffer[0] = 0;
+				break;
+		}
+		putpacket(output_buffer);
+	}
+}
+
+void
+kgdb_init(void)
+{
+	reg_intr_vect_rw_mask intr_mask;
+	reg_ser_rw_intr_mask ser_intr_mask;
+
+	/* Configure the kgdb serial port. */
+#if defined(CONFIG_ETRAX_KGDB_PORT0)
+	/* Note: no shortcut registered (not handled by multiple_interrupt).
+	   See entry.S.  */
+	set_exception_vector(SER0_INTR_VECT, kgdb_handle_exception);
+	/* Enable the ser irq in the global config. */
+	intr_mask = REG_RD(intr_vect, regi_irq, rw_mask);
+	intr_mask.ser0 = 1;
+	REG_WR(intr_vect, regi_irq, rw_mask, intr_mask);
+
+	ser_intr_mask = REG_RD(ser, regi_ser0, rw_intr_mask);
+	ser_intr_mask.data_avail = regk_ser_yes;
+	REG_WR(ser, regi_ser0, rw_intr_mask, ser_intr_mask);
+#elif defined(CONFIG_ETRAX_KGDB_PORT1)
+	/* Note: no shortcut registered (not handled by multiple_interrupt).
+	   See entry.S.  */
+	set_exception_vector(SER1_INTR_VECT, kgdb_handle_exception);
+	/* Enable the ser irq in the global config. */
+	intr_mask = REG_RD(intr_vect, regi_irq, rw_mask);
+	intr_mask.ser1 = 1;
+	REG_WR(intr_vect, regi_irq, rw_mask, intr_mask);
+
+	ser_intr_mask = REG_RD(ser, regi_ser1, rw_intr_mask);
+	ser_intr_mask.data_avail = regk_ser_yes;
+	REG_WR(ser, regi_ser1, rw_intr_mask, ser_intr_mask);
+#elif defined(CONFIG_ETRAX_KGDB_PORT2)
+	/* Note: no shortcut registered (not handled by multiple_interrupt).
+	   See entry.S.  */
+	set_exception_vector(SER2_INTR_VECT, kgdb_handle_exception);
+	/* Enable the ser irq in the global config. */
+	intr_mask = REG_RD(intr_vect, regi_irq, rw_mask);
+	intr_mask.ser2 = 1;
+	REG_WR(intr_vect, regi_irq, rw_mask, intr_mask);
+
+	ser_intr_mask = REG_RD(ser, regi_ser2, rw_intr_mask);
+	ser_intr_mask.data_avail = regk_ser_yes;
+	REG_WR(ser, regi_ser2, rw_intr_mask, ser_intr_mask);
+#elif defined(CONFIG_ETRAX_KGDB_PORT3)
+	/* Note: no shortcut registered (not handled by multiple_interrupt).
+	   See entry.S.  */
+	set_exception_vector(SER3_INTR_VECT, kgdb_handle_exception);
+	/* Enable the ser irq in the global config. */
+	intr_mask = REG_RD(intr_vect, regi_irq, rw_mask);
+	intr_mask.ser3 = 1;
+	REG_WR(intr_vect, regi_irq, rw_mask, intr_mask);
+
+	ser_intr_mask = REG_RD(ser, regi_ser3, rw_intr_mask);
+	ser_intr_mask.data_avail = regk_ser_yes;
+	REG_WR(ser, regi_ser3, rw_intr_mask, ser_intr_mask);
+#endif
+
+}
+/* Performs a complete re-start from scratch. */
+static void
+kill_restart(void)
+{
+	machine_restart("");
+}
+
+/* Use this static breakpoint in the start-up only. */
+
+void
+breakpoint(void)
+{
+	kgdb_started = 1;
+	dynamic_bp = 0;     /* This is a static, not a dynamic breakpoint. */
+	__asm__ volatile ("break 8"); /* Jump to kgdb_handle_breakpoint. */
+}
+
+/****************************** End of file **********************************/
diff --git a/arch/cris/arch-v32/kernel/kgdb_asm.S b/arch/cris/arch-v32/kernel/kgdb_asm.S
new file mode 100644
--- /dev/null
+++ b/arch/cris/arch-v32/kernel/kgdb_asm.S
@@ -0,0 +1,552 @@
+/*
+ *  Copyright (C) 2004 Axis Communications AB
+ *
+ * Code for handling break 8, hardware breakpoint, single step, and serial
+ * port exceptions for kernel debugging purposes.
+ */
+
+#include <linux/config.h>
+#include <asm/arch/hwregs/intr_vect.h>
+
+	;; Exported functions.
+	.globl kgdb_handle_exception
+
+kgdb_handle_exception:
+
+;; Create a register image of the caller.
+;;
+;; First of all, save the ACR on the stack since we need it for address calculations.
+;; We put it into the register struct later.
+
+  subq     4, $sp
+  move.d   $acr, [$sp]
+
+;; Now we are free to use ACR all we want.
+;; If we were running this handler with interrupts on, we would have to be careful
+;; to save and restore CCS manually, but since we aren't we treat it like every other
+;; register.
+
+  move.d   reg,  $acr
+  move.d   $r0,  [$acr]        ; Save R0 (start of register struct)
+  addq     4,    $acr
+  move.d   $r1,  [$acr]        ; Save R1
+  addq     4,    $acr
+  move.d   $r2,  [$acr]        ; Save R2
+  addq     4,    $acr
+  move.d   $r3,  [$acr]        ; Save R3
+  addq     4,    $acr
+  move.d   $r4,  [$acr]        ; Save R4
+  addq     4,    $acr
+  move.d   $r5,  [$acr]        ; Save R5
+  addq     4,    $acr
+  move.d   $r6,  [$acr]        ; Save R6
+  addq     4,    $acr
+  move.d   $r7,  [$acr]        ; Save R7
+  addq     4,    $acr
+  move.d   $r8,  [$acr]        ; Save R8
+  addq     4,    $acr
+  move.d   $r9,  [$acr]        ; Save R9
+  addq     4,    $acr
+  move.d   $r10, [$acr]        ; Save R10
+  addq     4,    $acr
+  move.d   $r11, [$acr]        ; Save R11
+  addq     4,    $acr
+  move.d   $r12, [$acr]        ; Save R12
+  addq     4,    $acr
+  move.d   $r13, [$acr]        ; Save R13
+  addq     4,    $acr
+  move.d   $sp,  [$acr]        ; Save SP (R14)
+  addq     4,    $acr
+
+  ;; The ACR register is already saved on the stack, so pop it from there.
+  move.d   [$sp],$r0
+  move.d   $r0,  [$acr]
+  addq     4,    $acr
+
+  move     $bz,  [$acr]
+  addq     1,    $acr
+  move     $vr,  [$acr]
+  addq     1,    $acr
+  move     $pid, [$acr]
+  addq     4,    $acr
+  move     $srs, [$acr]
+  addq     1,    $acr
+  move     $wz,  [$acr]
+  addq     2,    $acr
+  move     $exs, [$acr]
+  addq     4,    $acr
+  move     $eda, [$acr]
+  addq     4,    $acr
+  move     $mof, [$acr]
+  addq     4,    $acr
+  move     $dz,  [$acr]
+  addq     4,    $acr
+  move     $ebp, [$acr]
+  addq     4,    $acr
+  move     $erp, [$acr]
+  addq     4,    $acr
+  move     $srp, [$acr]
+  addq     4,    $acr
+  move     $nrp, [$acr]
+  addq     4,    $acr
+  move     $ccs, [$acr]
+  addq     4,    $acr
+  move     $usp, [$acr]
+  addq     4,    $acr
+  move     $spc, [$acr]
+  addq     4,     $acr
+
+;; Skip the pseudo-PC.
+  addq     4,     $acr
+
+;; Save the support registers in bank 0 - 3.
+  clear.d $r1 ; Bank counter
+  move.d  sreg, $acr
+
+;; Bank 0
+  move    $r1,  $srs
+  nop
+  nop
+  nop
+  move    $s0,   $r0
+  move.d  $r0,   [$acr]
+  addq    4,     $acr
+  move    $s1,   $r0
+  move.d  $r0,   [$acr]
+  addq    4,     $acr
+  move    $s2,   $r0
+  move.d  $r0,   [$acr]
+  addq    4,     $acr
+  move    $s3,   $r0
+  move.d  $r0,   [$acr]
+  addq    4,     $acr
+  move    $s4,   $r0
+  move.d  $r0,   [$acr]
+  addq    4,     $acr
+  move    $s5,   $r0
+  move.d  $r0,   [$acr]
+  addq    4,     $acr
+  move    $s6,   $r0
+  move.d  $r0,   [$acr]
+  addq    4,     $acr
+  move    $s7,   $r0
+  move.d  $r0,   [$acr]
+  addq    4,     $acr
+  move    $s8,   $r0
+  move.d  $r0,   [$acr]
+  addq    4,     $acr
+  move    $s9,   $r0
+  move.d  $r0,   [$acr]
+  addq    4,     $acr
+  move    $s10,  $r0
+  move.d  $r0,   [$acr]
+  addq    4,     $acr
+  move    $s11,  $r0
+  move.d  $r0,   [$acr]
+  addq    4,     $acr
+  move    $s12,  $r0
+  move.d  $r0,   [$acr]
+  addq    4,     $acr
+
+  ;; Nothing in S13 - S15, bank 0
+  clear.d [$acr]
+  addq    4,     $acr
+  clear.d [$acr]
+  addq    4,     $acr
+  clear.d [$acr]
+  addq    4,     $acr
+
+;; Bank 1 and bank 2 have the same layout, hence the loop.
+  addq    1, $r1
+1:
+  move    $r1,  $srs
+  nop
+  nop
+  nop
+  move    $s0,   $r0
+  move.d  $r0,   [$acr]
+  addq    4,     $acr
+  move    $s1,   $r0
+  move.d  $r0,   [$acr]
+  addq    4,     $acr
+  move    $s2,   $r0
+  move.d  $r0,   [$acr]
+  addq    4,     $acr
+  move    $s3,   $r0
+  move.d  $r0,   [$acr]
+  addq    4,     $acr
+  move    $s4,   $r0
+  move.d  $r0,   [$acr]
+  addq    4,     $acr
+  move    $s5,   $r0
+  move.d  $r0,   [$acr]
+  addq    4,     $acr
+  move    $s6,   $r0
+  move.d  $r0,   [$acr]
+  addq    4,     $acr
+
+  ;; Nothing in S7 - S15, bank 1 and 2
+  clear.d [$acr]
+  addq    4,     $acr
+  clear.d [$acr]
+  addq    4,     $acr
+  clear.d [$acr]
+  addq    4,     $acr
+  clear.d [$acr]
+  addq    4,     $acr
+  clear.d [$acr]
+  addq    4,     $acr
+  clear.d [$acr]
+  addq    4,     $acr
+  clear.d [$acr]
+  addq    4,     $acr
+  clear.d [$acr]
+  addq    4,     $acr
+  clear.d [$acr]
+  addq    4,     $acr
+
+  addq 1, $r1
+  cmpq 3, $r1
+  bne 1b
+  nop
+
+;; Bank 3
+  move    $r1,  $srs
+  nop
+  nop
+  nop
+  move    $s0,   $r0
+  move.d  $r0,   [$acr]
+  addq    4,     $acr
+  move    $s1,   $r0
+  move.d  $r0,   [$acr]
+  addq    4,     $acr
+  move    $s2,   $r0
+  move.d  $r0,   [$acr]
+  addq    4,     $acr
+  move    $s3,   $r0
+  move.d  $r0,   [$acr]
+  addq    4,     $acr
+  move    $s4,   $r0
+  move.d  $r0,   [$acr]
+  addq    4,     $acr
+  move    $s5,   $r0
+  move.d  $r0,   [$acr]
+  addq    4,     $acr
+  move    $s6,   $r0
+  move.d  $r0,   [$acr]
+  addq    4,     $acr
+  move    $s7,   $r0
+  move.d  $r0,   [$acr]
+  addq    4,     $acr
+  move    $s8,   $r0
+  move.d  $r0,   [$acr]
+  addq    4,     $acr
+  move    $s9,   $r0
+  move.d  $r0,   [$acr]
+  addq    4,     $acr
+  move    $s10,  $r0
+  move.d  $r0,   [$acr]
+  addq    4,     $acr
+  move    $s11,  $r0
+  move.d  $r0,   [$acr]
+  addq    4,     $acr
+  move    $s12,  $r0
+  move.d  $r0,   [$acr]
+  addq    4,     $acr
+  move    $s13,  $r0
+  move.d  $r0,   [$acr]
+  addq    4,     $acr
+  move    $s14,  $r0
+  move.d  $r0,   [$acr]
+  addq    4,     $acr
+;; Nothing in S15, bank 3
+  clear.d [$acr]
+  addq    4,     $acr
+
+;; Check what got us here: get IDX field of EXS.
+  move $exs,    $r10
+  and.d 0xff00, $r10
+  lsrq 8,       $r10
+#if defined(CONFIG_ETRAX_KGDB_PORT0)
+  cmp.d SER0_INTR_VECT,   $r10 ; IRQ for serial port 0
+  beq sigint
+  nop
+#elif defined(CONFIG_ETRAX_KGDB_PORT1)
+  cmp.d SER1_INTR_VECT,   $r10 ; IRQ for serial port 1
+  beq sigint
+  nop
+#elif defined(CONFIG_ETRAX_KGDB_PORT2)
+  cmp.d SER2_INTR_VECT,   $r10 ; IRQ for serial port 2
+  beq sigint
+  nop
+#elif defined(CONFIG_ETRAX_KGDB_PORT3)
+  cmp.d SER3_INTR_VECT,   $r10 ; IRQ for serial port 3
+  beq sigint
+  nop
+#endif
+;; Multiple interrupt must be due to serial break.
+  cmp.d 0x30,   $r10 ; Multiple interrupt
+  beq sigint
+  nop
+;; Neither of those? Then it's a sigtrap.
+  ba handle_comm
+  moveq 5, $r10      ; Set SIGTRAP (delay slot)
+
+sigint:
+  ;; Serial interrupt; get character
+  jsr getDebugChar
+  nop                ; Delay slot
+  cmp.b 3, $r10      ; \003 (Ctrl-C)?
+  bne return         ; No, get out of here
+  nop
+  moveq 2, $r10      ; Set SIGINT
+
+;;
+;; Handle the communication
+;;
+handle_comm:
+  move.d   internal_stack+1020, $sp ; Use the internal stack which grows upwards
+  jsr      handle_exception         ; Interactive routine
+  nop
+
+;;
+;; Return to the caller
+;;
+return:
+
+;; First of all, write the support registers.
+  clear.d $r1 ; Bank counter
+  move.d  sreg, $acr
+
+;; Bank 0
+  move    $r1,  $srs
+  nop
+  nop
+  nop
+  move.d  [$acr], $r0
+  move    $r0,    $s0
+  addq    4,      $acr
+  move.d  [$acr], $r0
+  move    $r0,    $s1
+  addq    4,      $acr
+  move.d  [$acr], $r0
+  move    $r0,    $s2
+  addq    4,      $acr
+  move.d  [$acr], $r0
+  move    $r0,    $s3
+  addq    4,      $acr
+  move.d  [$acr], $r0
+  move    $r0,    $s4
+  addq    4,      $acr
+  move.d  [$acr], $r0
+  move    $r0,    $s5
+  addq    4,      $acr
+
+;; Nothing in S6 - S7, bank 0.
+  addq    4,      $acr
+  addq    4,      $acr
+
+  move.d  [$acr], $r0
+  move    $r0,    $s8
+  addq    4,      $acr
+  move.d  [$acr], $r0
+  move    $r0,    $s9
+  addq    4,      $acr
+  move.d  [$acr], $r0
+  move    $r0,    $s10
+  addq    4,      $acr
+  move.d  [$acr], $r0
+  move    $r0,    $s11
+  addq    4,      $acr
+  move.d  [$acr], $r0
+  move    $r0,    $s12
+  addq    4,      $acr
+
+;; Nothing in S13 - S15, bank 0
+  addq    4,      $acr
+  addq    4,      $acr
+  addq    4,      $acr
+
+;; Bank 1 and bank 2 have the same layout, hence the loop.
+  addq    1, $r1
+2:
+  move    $r1,  $srs
+  nop
+  nop
+  nop
+  move.d  [$acr], $r0
+  move    $r0,    $s0
+  addq    4,      $acr
+  move.d  [$acr], $r0
+  move    $r0,    $s1
+  addq    4,      $acr
+  move.d  [$acr], $r0
+  move    $r0,    $s2
+  addq    4,      $acr
+
+;; S3 (MM_CAUSE) is read-only.
+  addq    4,      $acr
+
+  move.d  [$acr], $r0
+  move    $r0,    $s4
+  addq    4,      $acr
+
+;; FIXME: Actually write S5/S6? (Affects MM_CAUSE.)
+  addq    4,      $acr
+  addq    4,      $acr
+
+;; Nothing in S7 - S15, bank 1 and 2
+  addq    4,      $acr
+  addq    4,      $acr
+  addq    4,      $acr
+  addq    4,      $acr
+  addq    4,      $acr
+  addq    4,      $acr
+  addq    4,      $acr
+  addq    4,      $acr
+  addq    4,      $acr
+
+  addq 1, $r1
+  cmpq 3, $r1
+  bne 2b
+  nop
+
+;; Bank 3
+  move    $r1,  $srs
+  nop
+  nop
+  nop
+  move.d  [$acr], $r0
+  move    $r0,    $s0
+  addq    4,      $acr
+  move.d  [$acr], $r0
+  move    $r0,    $s1
+  addq    4,      $acr
+  move.d  [$acr], $r0
+  move    $r0,    $s2
+  addq    4,      $acr
+  move.d  [$acr], $r0
+  move    $r0,    $s3
+  addq    4,      $acr
+  move.d  [$acr], $r0
+  move    $r0,    $s4
+  addq    4,      $acr
+  move.d  [$acr], $r0
+  move    $r0,    $s5
+  addq    4,      $acr
+  move.d  [$acr], $r0
+  move    $r0,    $s6
+  addq    4,      $acr
+  move.d  [$acr], $r0
+  move    $r0,    $s7
+  addq    4,      $acr
+  move.d  [$acr], $r0
+  move    $r0,    $s8
+  addq    4,      $acr
+  move.d  [$acr], $r0
+  move    $r0,    $s9
+  addq    4,      $acr
+  move.d  [$acr], $r0
+  move    $r0,    $s10
+  addq    4,      $acr
+  move.d  [$acr], $r0
+  move    $r0,    $s11
+  addq    4,      $acr
+  move.d  [$acr], $r0
+  move    $r0,    $s12
+  addq    4,      $acr
+  move.d  [$acr], $r0
+  move    $r0,    $s13
+  addq    4,      $acr
+  move.d  [$acr], $r0
+  move    $r0,    $s14
+  addq    4,      $acr
+
+;; Nothing in S15, bank 3
+  addq    4,      $acr
+
+;; Now, move on to the regular register restoration process.
+
+   move.d  reg,    $acr   ; Reset ACR to point at the beginning of the register image
+   move.d  [$acr], $r0    ; Restore R0
+   addq    4,      $acr
+   move.d  [$acr], $r1    ; Restore R1
+   addq    4,      $acr
+   move.d  [$acr], $r2    ; Restore R2
+   addq    4,      $acr
+   move.d  [$acr], $r3    ; Restore R3
+   addq    4,      $acr
+   move.d  [$acr], $r4    ; Restore R4
+   addq    4,      $acr
+   move.d  [$acr], $r5    ; Restore R5
+   addq    4,      $acr
+   move.d  [$acr], $r6    ; Restore R6
+   addq    4,      $acr
+   move.d  [$acr], $r7    ; Restore R7
+   addq    4,      $acr
+   move.d  [$acr], $r8    ; Restore R8
+   addq    4,      $acr
+   move.d  [$acr], $r9    ; Restore R9
+   addq    4,      $acr
+   move.d  [$acr], $r10   ; Restore R10
+   addq    4,      $acr
+   move.d  [$acr], $r11   ; Restore R11
+   addq    4,      $acr
+   move.d  [$acr], $r12   ; Restore R12
+   addq    4,      $acr
+   move.d  [$acr], $r13   ; Restore R13
+
+;;
+;; We restore all registers, even though some of them probably haven't changed.
+;;
+
+   addq    4,      $acr
+   move.d  [$acr], $sp    ; Restore SP (R14)
+
+   ;; ACR cannot be restored just yet.
+   addq    8,      $acr
+
+   ;; Skip BZ, VR.
+   addq    2,      $acr
+
+   move    [$acr], $pid   ; Restore PID
+   addq    4,      $acr
+   move    [$acr], $srs   ; Restore SRS
+   nop
+   nop
+   nop
+   addq    1,      $acr
+
+   ;; Skip WZ.
+   addq    2,      $acr
+
+   move    [$acr], $exs    ; Restore EXS.
+   addq    4,      $acr
+   move    [$acr], $eda    ; Restore EDA.
+   addq    4,      $acr
+   move    [$acr], $mof    ; Restore MOF.
+
+   ;; Skip DZ.
+   addq    8,      $acr
+
+   move    [$acr], $ebp    ; Restore EBP.
+   addq    4,      $acr
+   move    [$acr], $erp    ; Restore ERP.
+   addq    4,      $acr
+   move    [$acr], $srp    ; Restore SRP.
+   addq    4,      $acr
+   move    [$acr], $nrp    ; Restore NRP.
+   addq    4,      $acr
+   move    [$acr], $ccs    ; Restore CCS like an ordinary register.
+   addq    4,      $acr
+   move    [$acr], $usp    ; Restore USP
+   addq    4,      $acr
+   move    [$acr], $spc    ; Restore SPC
+                           ; No restoration of pseudo-PC of course.
+
+   move.d  reg,    $acr    ; Reset ACR to point at the beginning of the register image
+   add.d   15*4,   $acr
+   move.d  [$acr], $acr    ; Finally, restore ACR.
+   rete                    ; Same as jump ERP
+   rfe                     ; Shifts CCS
diff --git a/arch/cris/arch-v32/kernel/pinmux.c b/arch/cris/arch-v32/kernel/pinmux.c
new file mode 100644
--- /dev/null
+++ b/arch/cris/arch-v32/kernel/pinmux.c
@@ -0,0 +1,229 @@
+/*
+ * Allocator for I/O pins. All pins are allocated to GPIO at bootup.
+ * Unassigned pins and GPIO pins can be allocated to a fixed interface
+ * or the I/O processor instead.
+ *
+ * Copyright (c) 2004 Axis Communications AB.
+ */
+
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/spinlock.h>
+#include <asm/arch/hwregs/reg_map.h>
+#include <asm/arch/hwregs/reg_rdwr.h>
+#include <asm/arch/pinmux.h>
+#include <asm/arch/hwregs/pinmux_defs.h>
+
+#undef DEBUG
+
+#define PORT_PINS 18
+#define PORTS 4
+
+static char pins[PORTS][PORT_PINS];
+static DEFINE_SPINLOCK(pinmux_lock);
+
+static void crisv32_pinmux_set(int port);
+
+int
+crisv32_pinmux_init(void)
+{
+	static int initialized = 0;
+
+	if (!initialized) {
+		reg_pinmux_rw_pa pa = REG_RD(pinmux, regi_pinmux, rw_pa);
+		initialized = 1;
+		pa.pa0 = pa.pa1 = pa.pa2 = pa.pa3 =
+		pa.pa4 = pa.pa5 = pa.pa6 = pa.pa7 = regk_pinmux_yes;
+		REG_WR(pinmux, regi_pinmux, rw_pa, pa);
+		crisv32_pinmux_alloc(PORT_B, 0, PORT_PINS - 1, pinmux_gpio);
+		crisv32_pinmux_alloc(PORT_C, 0, PORT_PINS - 1, pinmux_gpio);
+		crisv32_pinmux_alloc(PORT_D, 0, PORT_PINS - 1, pinmux_gpio);
+		crisv32_pinmux_alloc(PORT_E, 0, PORT_PINS - 1, pinmux_gpio);
+	}
+
+	return 0;
+}
+
+int
+crisv32_pinmux_alloc(int port, int first_pin, int last_pin, enum pin_mode mode)
+{
+	int i;
+	unsigned long flags;
+
+	crisv32_pinmux_init();
+
+	if (port > PORTS)
+		return -EINVAL;
+
+	spin_lock_irqsave(&pinmux_lock, flags);
+
+	for (i = first_pin; i <= last_pin; i++)
+	{
+		if ((pins[port][i] != pinmux_none) && (pins[port][i] != pinmux_gpio) &&
+		    (pins[port][i] != mode))
+		{
+			spin_unlock_irqrestore(&pinmux_lock, flags);
+#ifdef DEBUG
+			panic("Pinmux alloc failed!\n");
+#endif
+			return -EPERM;
+		}
+	}
+
+	for (i = first_pin; i <= last_pin; i++)
+		pins[port][i] = mode;
+
+	crisv32_pinmux_set(port);
+
+	spin_unlock_irqrestore(&pinmux_lock, flags);
+
+	return 0;
+}
+
+int
+crisv32_pinmux_alloc_fixed(enum fixed_function function)
+{
+	int ret = -EINVAL;
+	char saved[sizeof pins];
+	unsigned long flags;
+
+	spin_lock_irqsave(&pinmux_lock, flags);
+
+	/* Save internal data for recovery */
+	memcpy(saved, pins, sizeof pins);
+
+	reg_pinmux_rw_hwprot hwprot = REG_RD(pinmux, regi_pinmux, rw_hwprot);
+
+	switch(function)
+	{
+	case pinmux_ser1:
+		ret = crisv32_pinmux_alloc(PORT_C, 4, 7, pinmux_fixed);
+		hwprot.ser1 = regk_pinmux_yes;
+		break;
+	case pinmux_ser2:
+		ret = crisv32_pinmux_alloc(PORT_C, 8, 11, pinmux_fixed);
+		hwprot.ser2 = regk_pinmux_yes;
+		break;
+	case pinmux_ser3:
+		ret = crisv32_pinmux_alloc(PORT_C, 12, 15, pinmux_fixed);
+		hwprot.ser3 = regk_pinmux_yes;
+		break;
+	case pinmux_sser0:
+		ret = crisv32_pinmux_alloc(PORT_C, 0, 3, pinmux_fixed);
+		ret |= crisv32_pinmux_alloc(PORT_C, 16, 16, pinmux_fixed);
+		hwprot.sser0 = regk_pinmux_yes;
+		break;
+	case pinmux_sser1:
+		ret = crisv32_pinmux_alloc(PORT_D, 0, 4, pinmux_fixed);
+		hwprot.sser1 = regk_pinmux_yes;
+		break;
+	case pinmux_ata0:
+		ret = crisv32_pinmux_alloc(PORT_D, 5, 7, pinmux_fixed);
+		ret |= crisv32_pinmux_alloc(PORT_D, 15, 17, pinmux_fixed);
+		hwprot.ata0 = regk_pinmux_yes;
+		break;
+	case pinmux_ata1:
+		ret = crisv32_pinmux_alloc(PORT_D, 0, 4, pinmux_fixed);
+		ret |= crisv32_pinmux_alloc(PORT_E, 17, 17, pinmux_fixed);
+		hwprot.ata1 = regk_pinmux_yes;
+		break;
+	case pinmux_ata2:
+		ret = crisv32_pinmux_alloc(PORT_C, 11, 15, pinmux_fixed);
+		ret |= crisv32_pinmux_alloc(PORT_E, 3, 3, pinmux_fixed);
+		hwprot.ata2 = regk_pinmux_yes;
+		break;
+	case pinmux_ata3:
+		ret = crisv32_pinmux_alloc(PORT_C, 8, 10, pinmux_fixed);
+		ret |= crisv32_pinmux_alloc(PORT_C, 0, 2, pinmux_fixed);
+		hwprot.ata2 = regk_pinmux_yes;
+		break;
+	case pinmux_ata:
+		ret = crisv32_pinmux_alloc(PORT_B, 0, 15, pinmux_fixed);
+		ret |= crisv32_pinmux_alloc(PORT_D, 8, 15, pinmux_fixed);
+		hwprot.ata = regk_pinmux_yes;
+		break;
+	case pinmux_eth1:
+		ret = crisv32_pinmux_alloc(PORT_E, 0, 17, pinmux_fixed);
+		hwprot.eth1 = regk_pinmux_yes;
+		hwprot.eth1_mgm = regk_pinmux_yes;
+		break;
+	case pinmux_timer:
+		ret = crisv32_pinmux_alloc(PORT_C, 16, 16, pinmux_fixed);
+		hwprot.timer = regk_pinmux_yes;
+		spin_unlock_irqrestore(&pinmux_lock, flags);
+		return ret;
+	}
+
+	if (!ret)
+		REG_WR(pinmux, regi_pinmux, rw_hwprot, hwprot);
+	else
+		memcpy(pins, saved, sizeof pins);
+
+  spin_unlock_irqrestore(&pinmux_lock, flags);
+
+  return ret;
+}
+
+void
+crisv32_pinmux_set(int port)
+{
+	int i;
+	int gpio_val = 0;
+	int iop_val = 0;
+
+	for (i = 0; i < PORT_PINS; i++)
+	{
+		if (pins[port][i] == pinmux_gpio)
+			gpio_val |= (1 << i);
+		else if (pins[port][i] == pinmux_iop)
+			iop_val |= (1 << i);
+	}
+
+	REG_WRITE(int, regi_pinmux + REG_RD_ADDR_pinmux_rw_pb_gio + 8*port, gpio_val);
+	REG_WRITE(int, regi_pinmux + REG_RD_ADDR_pinmux_rw_pb_iop + 8*port, iop_val);
+
+#ifdef DEBUG
+       crisv32_pinmux_dump();
+#endif
+}
+
+int
+crisv32_pinmux_dealloc(int port, int first_pin, int last_pin)
+{
+	int i;
+	unsigned long flags;
+
+	crisv32_pinmux_init();
+
+	if (port > PORTS)
+		return -EINVAL;
+
+	spin_lock_irqsave(&pinmux_lock, flags);
+
+	for (i = first_pin; i <= last_pin; i++)
+		pins[port][i] = pinmux_none;
+
+	crisv32_pinmux_set(port);
+	spin_unlock_irqrestore(&pinmux_lock, flags);
+
+	return 0;
+}
+
+void
+crisv32_pinmux_dump(void)
+{
+	int i, j;
+
+	crisv32_pinmux_init();
+
+	for (i = 0; i < PORTS; i++)
+	{
+		printk("Port %c\n", 'B'+i);
+		for (j = 0; j < PORT_PINS; j++)
+			printk("  Pin %d = %d\n", j, pins[i][j]);
+	}
+}
+
+__initcall(crisv32_pinmux_init);
diff --git a/arch/cris/arch-v32/kernel/process.c b/arch/cris/arch-v32/kernel/process.c
new file mode 100644
--- /dev/null
+++ b/arch/cris/arch-v32/kernel/process.c
@@ -0,0 +1,270 @@
+/*
+ *  Copyright (C) 2000-2003  Axis Communications AB
+ *
+ *  Authors:   Bjorn Wesen (bjornw@axis.com)
+ *             Mikael Starvik (starvik@axis.com)
+ *             Tobias Anderberg (tobiasa@axis.com), CRISv32 port.
+ *
+ * This file handles the architecture-dependent parts of process handling..
+ */
+
+#include <linux/config.h>
+#include <linux/sched.h>
+#include <linux/err.h>
+#include <linux/fs.h>
+#include <linux/slab.h>
+#include <asm/arch/hwregs/reg_rdwr.h>
+#include <asm/arch/hwregs/reg_map.h>
+#include <asm/arch/hwregs/timer_defs.h>
+#include <asm/arch/hwregs/intr_vect_defs.h>
+
+extern void stop_watchdog(void);
+
+#ifdef CONFIG_ETRAX_GPIO
+extern void etrax_gpio_wake_up_check(void); /* Defined in drivers/gpio.c. */
+#endif
+
+extern int cris_hlt_counter;
+
+/* We use this if we don't have any better idle routine. */
+void default_idle(void)
+{
+	local_irq_disable();
+	if (!need_resched() && !cris_hlt_counter) {
+	        /* Halt until exception. */
+		__asm__ volatile("ei    \n\t"
+                                 "halt      ");
+	}
+	local_irq_enable();
+}
+
+/*
+ * Free current thread data structures etc..
+ */
+
+extern void deconfigure_bp(long pid);
+void exit_thread(void)
+{
+	deconfigure_bp(current->pid);
+}
+
+/*
+ * If the watchdog is enabled, disable interrupts and enter an infinite loop.
+ * The watchdog will reset the CPU after 0.1s. If the watchdog isn't enabled
+ * then enable it and wait.
+ */
+extern void arch_enable_nmi(void);
+
+void
+hard_reset_now(void)
+{
+	/*
+	 * Don't declare this variable elsewhere.  We don't want any other
+	 * code to know about it than the watchdog handler in entry.S and
+	 * this code, implementing hard reset through the watchdog.
+	 */
+#if defined(CONFIG_ETRAX_WATCHDOG)
+	extern int cause_of_death;
+#endif
+
+	printk("*** HARD RESET ***\n");
+	local_irq_disable();
+
+#if defined(CONFIG_ETRAX_WATCHDOG)
+	cause_of_death = 0xbedead;
+#else
+{
+	reg_timer_rw_wd_ctrl wd_ctrl = {0};
+
+	stop_watchdog();
+
+	wd_ctrl.key = 16;	/* Arbitrary key. */
+	wd_ctrl.cnt = 1;	/* Minimum time. */
+	wd_ctrl.cmd = regk_timer_start;
+
+        arch_enable_nmi();
+	REG_WR(timer, regi_timer, rw_wd_ctrl, wd_ctrl);
+}
+#endif
+
+	while (1)
+		; /* Wait for reset. */
+}
+
+/*
+ * Return saved PC of a blocked thread.
+ */
+unsigned long thread_saved_pc(struct task_struct *t)
+{
+	return (unsigned long)user_regs(t->thread_info)->erp;
+}
+
+static void
+kernel_thread_helper(void* dummy, int (*fn)(void *), void * arg)
+{
+	fn(arg);
+	do_exit(-1); /* Should never be called, return bad exit value. */
+}
+
+/* Create a kernel thread. */
+int
+kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
+{
+	struct pt_regs regs;
+
+	memset(&regs, 0, sizeof(regs));
+
+        /* Don't use r10 since that is set to 0 in copy_thread. */
+	regs.r11 = (unsigned long) fn;
+	regs.r12 = (unsigned long) arg;
+	regs.erp = (unsigned long) kernel_thread_helper;
+	regs.ccs = 1 << (I_CCS_BITNR + CCS_SHIFT);
+
+	/* Create the new process. */
+        return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
+}
+
+/*
+ * Setup the child's kernel stack with a pt_regs and call switch_stack() on it.
+ * It will be unnested during _resume and _ret_from_sys_call when the new thread
+ * is scheduled.
+ *
+ * Also setup the thread switching structure which is used to keep
+ * thread-specific data during _resumes.
+ */
+
+extern asmlinkage void ret_from_fork(void);
+
+int
+copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
+	unsigned long unused,
+	struct task_struct *p, struct pt_regs *regs)
+{
+	struct pt_regs *childregs;
+	struct switch_stack *swstack;
+
+	/*
+	 * Put the pt_regs structure at the end of the new kernel stack page and
+	 * fix it up. Note: the task_struct doubles as the kernel stack for the
+	 * task.
+	 */
+	childregs = user_regs(p->thread_info);
+	*childregs = *regs;	/* Struct copy of pt_regs. */
+        p->set_child_tid = p->clear_child_tid = NULL;
+        childregs->r10 = 0;	/* Child returns 0 after a fork/clone. */
+
+	/* Set a new TLS ?
+	 * The TLS is in $mof beacuse it is the 5th argument to sys_clone.
+	 */
+	if (p->mm && (clone_flags & CLONE_SETTLS)) {
+		p->thread_info->tls = regs->mof;
+	}
+
+	/* Put the switch stack right below the pt_regs. */
+	swstack = ((struct switch_stack *) childregs) - 1;
+
+	/* Paramater to ret_from_sys_call. 0 is don't restart the syscall. */
+	swstack->r9 = 0;
+
+	/*
+	 * We want to return into ret_from_sys_call after the _resume.
+	 * ret_from_fork will call ret_from_sys_call.
+	 */
+	swstack->return_ip = (unsigned long) ret_from_fork;
+
+	/* Fix the user-mode and kernel-mode stackpointer. */
+	p->thread.usp = usp;
+	p->thread.ksp = (unsigned long) swstack;
+
+	return 0;
+}
+
+/*
+ * Be aware of the "magic" 7th argument in the four system-calls below.
+ * They need the latest stackframe, which is put as the 7th argument by
+ * entry.S. The previous arguments are dummies or actually used, but need
+ * to be defined to reach the 7th argument.
+ *
+ * N.B.: Another method to get the stackframe is to use current_regs(). But
+ * it returns the latest stack-frame stacked when going from _user mode_ and
+ * some of these (at least sys_clone) are called from kernel-mode sometimes
+ * (for example during kernel_thread, above) and thus cannot use it. Thus,
+ * to be sure not to get any surprises, we use the method for the other calls
+ * as well.
+ */
+asmlinkage int
+sys_fork(long r10, long r11, long r12, long r13, long mof, long srp,
+	struct pt_regs *regs)
+{
+	return do_fork(SIGCHLD, rdusp(), regs, 0, NULL, NULL);
+}
+
+/* FIXME: Is parent_tid/child_tid really third/fourth argument? Update lib? */
+asmlinkage int
+sys_clone(unsigned long newusp, unsigned long flags, int *parent_tid, int *child_tid,
+	unsigned long tls, long srp, struct pt_regs *regs)
+{
+	if (!newusp)
+		newusp = rdusp();
+
+	return do_fork(flags, newusp, regs, 0, parent_tid, child_tid);
+}
+
+/*
+ * vfork is a system call in i386 because of register-pressure - maybe
+ * we can remove it and handle it in libc but we put it here until then.
+ */
+asmlinkage int
+sys_vfork(long r10, long r11, long r12, long r13, long mof, long srp,
+	struct pt_regs *regs)
+{
+	return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, rdusp(), regs, 0, NULL, NULL);
+}
+
+/* sys_execve() executes a new program. */
+asmlinkage int
+sys_execve(const char *fname, char **argv, char **envp, long r13, long mof, long srp,
+	struct pt_regs *regs)
+{
+	int error;
+	char *filename;
+
+	filename = getname(fname);
+	error = PTR_ERR(filename);
+
+	if (IS_ERR(filename))
+	        goto out;
+
+	error = do_execve(filename, argv, envp, regs);
+	putname(filename);
+ out:
+	return error;
+}
+
+unsigned long
+get_wchan(struct task_struct *p)
+{
+	/* TODO */
+	return 0;
+}
+#undef last_sched
+#undef first_sched
+
+void show_regs(struct pt_regs * regs)
+{
+	unsigned long usp = rdusp();
+        printk("ERP: %08lx SRP: %08lx  CCS: %08lx USP: %08lx MOF: %08lx\n",
+		regs->erp, regs->srp, regs->ccs, usp, regs->mof);
+
+	printk(" r0: %08lx  r1: %08lx   r2: %08lx  r3: %08lx\n",
+		regs->r0, regs->r1, regs->r2, regs->r3);
+
+	printk(" r4: %08lx  r5: %08lx   r6: %08lx  r7: %08lx\n",
+		regs->r4, regs->r5, regs->r6, regs->r7);
+
+	printk(" r8: %08lx  r9: %08lx  r10: %08lx r11: %08lx\n",
+		regs->r8, regs->r9, regs->r10, regs->r11);
+
+	printk("r12: %08lx r13: %08lx oR10: %08lx\n",
+		regs->r12, regs->r13, regs->orig_r10);
+}
diff --git a/arch/cris/arch-v32/kernel/ptrace.c b/arch/cris/arch-v32/kernel/ptrace.c
new file mode 100644
--- /dev/null
+++ b/arch/cris/arch-v32/kernel/ptrace.c
@@ -0,0 +1,597 @@
+/*
+ * Copyright (C) 2000-2003, Axis Communications AB.
+ */
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/errno.h>
+#include <linux/ptrace.h>
+#include <linux/user.h>
+#include <linux/signal.h>
+#include <linux/security.h>
+
+#include <asm/uaccess.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/processor.h>
+#include <asm/arch/hwregs/supp_reg.h>
+
+/*
+ * Determines which bits in CCS the user has access to.
+ * 1 = access, 0 = no access.
+ */
+#define CCS_MASK 0x00087c00     /* SXNZVC */
+
+#define SBIT_USER (1 << (S_CCS_BITNR + CCS_SHIFT))
+
+static int put_debugreg(long pid, unsigned int regno, long data);
+static long get_debugreg(long pid, unsigned int regno);
+static unsigned long get_pseudo_pc(struct task_struct *child);
+void deconfigure_bp(long pid);
+
+extern unsigned long cris_signal_return_page;
+
+/*
+ * Get contents of register REGNO in task TASK.
+ */
+long get_reg(struct task_struct *task, unsigned int regno)
+{
+	/* USP is a special case, it's not in the pt_regs struct but
+	 * in the tasks thread struct
+	 */
+	unsigned long ret;
+
+	if (regno <= PT_EDA)
+		ret = ((unsigned long *)user_regs(task->thread_info))[regno];
+	else if (regno == PT_USP)
+		ret = task->thread.usp;
+	else if (regno == PT_PPC)
+		ret = get_pseudo_pc(task);
+	else if (regno <= PT_MAX)
+		ret = get_debugreg(task->pid, regno);
+	else
+		ret = 0;
+
+	return ret;
+}
+
+/*
+ * Write contents of register REGNO in task TASK.
+ */
+int put_reg(struct task_struct *task, unsigned int regno, unsigned long data)
+{
+	if (regno <= PT_EDA)
+		((unsigned long *)user_regs(task->thread_info))[regno] = data;
+	else if (regno == PT_USP)
+		task->thread.usp = data;
+	else if (regno == PT_PPC) {
+		/* Write pseudo-PC to ERP only if changed. */
+		if (data != get_pseudo_pc(task))
+			((unsigned long *)user_regs(task->thread_info))[PT_ERP] = data;
+	} else if (regno <= PT_MAX)
+		return put_debugreg(task->pid, regno, data);
+	else
+		return -1;
+	return 0;
+}
+
+/*
+ * Called by kernel/ptrace.c when detaching.
+ *
+ * Make sure the single step bit is not set.
+ */
+void
+ptrace_disable(struct task_struct *child)
+{
+	unsigned long tmp;
+
+	/* Deconfigure SPC and S-bit. */
+	tmp = get_reg(child, PT_CCS) & ~SBIT_USER;
+	put_reg(child, PT_CCS, tmp);
+	put_reg(child, PT_SPC, 0);
+
+	/* Deconfigure any watchpoints associated with the child. */
+	deconfigure_bp(child->pid);
+}
+
+
+asmlinkage int
+sys_ptrace(long request, long pid, long addr, long data)
+{
+	struct task_struct *child;
+	int ret;
+	unsigned long __user *datap = (unsigned long __user *)data;
+
+	lock_kernel();
+	ret = -EPERM;
+
+	if (request == PTRACE_TRACEME) {
+		/* are we already being traced? */
+		if (current->ptrace & PT_PTRACED)
+			goto out;
+		ret = security_ptrace(current->parent, current);
+		if (ret)
+			goto out;
+		/* set the ptrace bit in the process flags. */
+		current->ptrace |= PT_PTRACED;
+		ret = 0;
+		goto out;
+	}
+
+	ret = -ESRCH;
+	read_lock(&tasklist_lock);
+	child = find_task_by_pid(pid);
+
+	if (child)
+		get_task_struct(child);
+
+	read_unlock(&tasklist_lock);
+
+	if (!child)
+		goto out;
+
+	ret = -EPERM;
+
+	if (pid == 1)		/* Leave the init process alone! */
+		goto out_tsk;
+
+	if (request == PTRACE_ATTACH) {
+		ret = ptrace_attach(child);
+		goto out_tsk;
+	}
+
+	ret = ptrace_check_attach(child, request == PTRACE_KILL);
+	if (ret < 0)
+		goto out_tsk;
+
+	switch (request) {
+		/* Read word at location address. */
+		case PTRACE_PEEKTEXT:
+		case PTRACE_PEEKDATA: {
+			unsigned long tmp;
+			int copied;
+
+			ret = -EIO;
+
+			/* The signal trampoline page is outside the normal user-addressable
+			 * space but still accessible. This is hack to make it possible to
+			 * access the signal handler code in GDB.
+			 */
+			if ((addr & PAGE_MASK) == cris_signal_return_page) {
+				/* The trampoline page is globally mapped, no page table to traverse.*/
+				tmp = *(unsigned long*)addr;
+			} else {
+				copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
+
+				if (copied != sizeof(tmp))
+					break;
+			}
+
+			ret = put_user(tmp,datap);
+			break;
+		}
+
+		/* Read the word at location address in the USER area. */
+		case PTRACE_PEEKUSR: {
+			unsigned long tmp;
+
+			ret = -EIO;
+			if ((addr & 3) || addr < 0 || addr > PT_MAX << 2)
+				break;
+
+			tmp = get_reg(child, addr >> 2);
+			ret = put_user(tmp, datap);
+			break;
+		}
+
+		/* Write the word at location address. */
+		case PTRACE_POKETEXT:
+		case PTRACE_POKEDATA:
+			ret = 0;
+
+			if (access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data))
+				break;
+
+			ret = -EIO;
+			break;
+
+ 		/* Write the word at location address in the USER area. */
+		case PTRACE_POKEUSR:
+			ret = -EIO;
+			if ((addr & 3) || addr < 0 || addr > PT_MAX << 2)
+				break;
+
+			addr >>= 2;
+
+			if (addr == PT_CCS) {
+				/* don't allow the tracing process to change stuff like
+				 * interrupt enable, kernel/user bit, dma enables etc.
+				 */
+				data &= CCS_MASK;
+				data |= get_reg(child, PT_CCS) & ~CCS_MASK;
+			}
+			if (put_reg(child, addr, data))
+				break;
+			ret = 0;
+			break;
+
+		case PTRACE_SYSCALL:
+		case PTRACE_CONT:
+			ret = -EIO;
+
+			if (!valid_signal(data))
+				break;
+
+			/* Continue means no single-step. */
+			put_reg(child, PT_SPC, 0);
+
+			if (!get_debugreg(child->pid, PT_BP_CTRL)) {
+				unsigned long tmp;
+				/* If no h/w bp configured, disable S bit. */
+				tmp = get_reg(child, PT_CCS) & ~SBIT_USER;
+				put_reg(child, PT_CCS, tmp);
+			}
+
+			if (request == PTRACE_SYSCALL) {
+				set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
+			}
+			else {
+				clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
+			}
+
+			child->exit_code = data;
+
+			/* TODO: make sure any pending breakpoint is killed */
+			wake_up_process(child);
+			ret = 0;
+
+			break;
+
+ 		/* Make the child exit by sending it a sigkill. */
+		case PTRACE_KILL:
+			ret = 0;
+
+			if (child->exit_state == EXIT_ZOMBIE)
+				break;
+
+			child->exit_code = SIGKILL;
+
+			/* Deconfigure single-step and h/w bp. */
+			ptrace_disable(child);
+
+			/* TODO: make sure any pending breakpoint is killed */
+			wake_up_process(child);
+			break;
+
+		/* Set the trap flag. */
+		case PTRACE_SINGLESTEP:	{
+			unsigned long tmp;
+			ret = -EIO;
+
+			/* Set up SPC if not set already (in which case we have
+			   no other choice but to trust it). */
+			if (!get_reg(child, PT_SPC)) {
+				/* In case we're stopped in a delay slot. */
+				tmp = get_reg(child, PT_ERP) & ~1;
+				put_reg(child, PT_SPC, tmp);
+			}
+			tmp = get_reg(child, PT_CCS) | SBIT_USER;
+			put_reg(child, PT_CCS, tmp);
+
+			if (!valid_signal(data))
+				break;
+
+			clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
+
+			/* TODO: set some clever breakpoint mechanism... */
+
+			child->exit_code = data;
+			wake_up_process(child);
+			ret = 0;
+			break;
+
+		}
+		case PTRACE_DETACH:
+			ret = ptrace_detach(child, data);
+			break;
+
+		/* Get all GP registers from the child. */
+		case PTRACE_GETREGS: {
+		  	int i;
+			unsigned long tmp;
+
+			for (i = 0; i <= PT_MAX; i++) {
+				tmp = get_reg(child, i);
+
+				if (put_user(tmp, datap)) {
+					ret = -EFAULT;
+					goto out_tsk;
+				}
+
+				datap++;
+			}
+
+			ret = 0;
+			break;
+		}
+
+		/* Set all GP registers in the child. */
+		case PTRACE_SETREGS: {
+			int i;
+			unsigned long tmp;
+
+			for (i = 0; i <= PT_MAX; i++) {
+				if (get_user(tmp, datap)) {
+					ret = -EFAULT;
+					goto out_tsk;
+				}
+
+				if (i == PT_CCS) {
+					tmp &= CCS_MASK;
+					tmp |= get_reg(child, PT_CCS) & ~CCS_MASK;
+				}
+
+				put_reg(child, i, tmp);
+				datap++;
+			}
+
+			ret = 0;
+			break;
+		}
+
+		default:
+			ret = ptrace_request(child, request, addr, data);
+			break;
+	}
+out_tsk:
+	put_task_struct(child);
+out:
+	unlock_kernel();
+	return ret;
+}
+
+void do_syscall_trace(void)
+{
+	if (!test_thread_flag(TIF_SYSCALL_TRACE))
+		return;
+
+	if (!(current->ptrace & PT_PTRACED))
+		return;
+
+	/* the 0x80 provides a way for the tracing parent to distinguish
+	   between a syscall stop and SIGTRAP delivery */
+	ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
+				 ? 0x80 : 0));
+
+	/*
+	 * This isn't the same as continuing with a signal, but it will do for
+	 * normal use.
+	 */
+	if (current->exit_code) {
+		send_sig(current->exit_code, current, 1);
+		current->exit_code = 0;
+	}
+}
+
+/* Returns the size of an instruction that has a delay slot. */
+
+static int insn_size(struct task_struct *child, unsigned long pc)
+{
+  unsigned long opcode;
+  int copied;
+  int opsize = 0;
+
+  /* Read the opcode at pc (do what PTRACE_PEEKTEXT would do). */
+  copied = access_process_vm(child, pc, &opcode, sizeof(opcode), 0);
+  if (copied != sizeof(opcode))
+    return 0;
+
+  switch ((opcode & 0x0f00) >> 8) {
+  case 0x0:
+  case 0x9:
+  case 0xb:
+	  opsize = 2;
+	  break;
+  case 0xe:
+  case 0xf:
+	  opsize = 6;
+	  break;
+  case 0xd:
+	  /* Could be 4 or 6; check more bits. */
+	  if ((opcode & 0xff) == 0xff)
+		  opsize = 4;
+	  else
+		  opsize = 6;
+	  break;
+  default:
+	  panic("ERROR: Couldn't find size of opcode 0x%lx at 0x%lx\n",
+		opcode, pc);
+  }
+
+  return opsize;
+}
+
+static unsigned long get_pseudo_pc(struct task_struct *child)
+{
+	/* Default value for PC is ERP. */
+	unsigned long pc = get_reg(child, PT_ERP);
+
+	if (pc & 0x1) {
+		unsigned long spc = get_reg(child, PT_SPC);
+		/* Delay slot bit set. Report as stopped on proper
+		   instruction. */
+		if (spc) {
+			/* Rely on SPC if set. FIXME: We might want to check
+			   that EXS indicates we stopped due to a single-step
+			   exception. */
+			pc = spc;
+		} else {
+			/* Calculate the PC from the size of the instruction
+			   that the delay slot we're in belongs to. */
+			pc += insn_size(child, pc & ~1) - 1;
+		}
+	}
+	return pc;
+}
+
+static long bp_owner = 0;
+
+/* Reachable from exit_thread in signal.c, so not static. */
+void deconfigure_bp(long pid)
+{
+	int bp;
+
+	/* Only deconfigure if the pid is the owner. */
+	if (bp_owner != pid)
+		return;
+
+	for (bp = 0; bp < 6; bp++) {
+		unsigned long tmp;
+		/* Deconfigure start and end address (also gets rid of ownership). */
+		put_debugreg(pid, PT_BP + 3 + (bp * 2), 0);
+		put_debugreg(pid, PT_BP + 4 + (bp * 2), 0);
+
+		/* Deconfigure relevant bits in control register. */
+		tmp = get_debugreg(pid, PT_BP_CTRL) & ~(3 << (2 + (bp * 4)));
+		put_debugreg(pid, PT_BP_CTRL, tmp);
+	}
+	/* No owner now. */
+	bp_owner = 0;
+}
+
+static int put_debugreg(long pid, unsigned int regno, long data)
+{
+	int ret = 0;
+	register int old_srs;
+
+#ifdef CONFIG_ETRAX_KGDB
+	/* Ignore write, but pretend it was ok if value is 0
+	   (we don't want POKEUSR/SETREGS failing unnessecarily). */
+	return (data == 0) ? ret : -1;
+#endif
+
+	/* Simple owner management. */
+	if (!bp_owner)
+		bp_owner = pid;
+	else if (bp_owner != pid) {
+		/* Ignore write, but pretend it was ok if value is 0
+		   (we don't want POKEUSR/SETREGS failing unnessecarily). */
+		return (data == 0) ? ret : -1;
+	}
+
+	/* Remember old SRS. */
+	SPEC_REG_RD(SPEC_REG_SRS, old_srs);
+	/* Switch to BP bank. */
+	SUPP_BANK_SEL(BANK_BP);
+
+	switch (regno - PT_BP) {
+	case 0:
+		SUPP_REG_WR(0, data); break;
+	case 1:
+	case 2:
+		if (data)
+			ret = -1;
+		break;
+	case 3:
+		SUPP_REG_WR(3, data); break;
+	case 4:
+		SUPP_REG_WR(4, data); break;
+	case 5:
+		SUPP_REG_WR(5, data); break;
+	case 6:
+		SUPP_REG_WR(6, data); break;
+	case 7:
+		SUPP_REG_WR(7, data); break;
+	case 8:
+		SUPP_REG_WR(8, data); break;
+	case 9:
+		SUPP_REG_WR(9, data); break;
+	case 10:
+		SUPP_REG_WR(10, data); break;
+	case 11:
+		SUPP_REG_WR(11, data); break;
+	case 12:
+		SUPP_REG_WR(12, data); break;
+	case 13:
+		SUPP_REG_WR(13, data); break;
+	case 14:
+		SUPP_REG_WR(14, data); break;
+	default:
+		ret = -1;
+		break;
+	}
+
+	/* Restore SRS. */
+	SPEC_REG_WR(SPEC_REG_SRS, old_srs);
+	/* Just for show. */
+	NOP();
+	NOP();
+	NOP();
+
+	return ret;
+}
+
+static long get_debugreg(long pid, unsigned int regno)
+{
+	register int old_srs;
+	register long data;
+
+	if (pid != bp_owner) {
+		return 0;
+	}
+
+	/* Remember old SRS. */
+	SPEC_REG_RD(SPEC_REG_SRS, old_srs);
+	/* Switch to BP bank. */
+	SUPP_BANK_SEL(BANK_BP);
+
+	switch (regno - PT_BP) {
+	case 0:
+		SUPP_REG_RD(0, data); break;
+	case 1:
+	case 2:
+		/* error return value? */
+		data = 0;
+		break;
+	case 3:
+		SUPP_REG_RD(3, data); break;
+	case 4:
+		SUPP_REG_RD(4, data); break;
+	case 5:
+		SUPP_REG_RD(5, data); break;
+	case 6:
+		SUPP_REG_RD(6, data); break;
+	case 7:
+		SUPP_REG_RD(7, data); break;
+	case 8:
+		SUPP_REG_RD(8, data); break;
+	case 9:
+		SUPP_REG_RD(9, data); break;
+	case 10:
+		SUPP_REG_RD(10, data); break;
+	case 11:
+		SUPP_REG_RD(11, data); break;
+	case 12:
+		SUPP_REG_RD(12, data); break;
+	case 13:
+		SUPP_REG_RD(13, data); break;
+	case 14:
+		SUPP_REG_RD(14, data); break;
+	default:
+		/* error return value? */
+		data = 0;
+	}
+
+	/* Restore SRS. */
+	SPEC_REG_WR(SPEC_REG_SRS, old_srs);
+	/* Just for show. */
+	NOP();
+	NOP();
+	NOP();
+
+	return data;
+}
diff --git a/arch/cris/arch-v32/kernel/setup.c b/arch/cris/arch-v32/kernel/setup.c
new file mode 100644
--- /dev/null
+++ b/arch/cris/arch-v32/kernel/setup.c
@@ -0,0 +1,118 @@
+/*
+ * Display CPU info in /proc/cpuinfo.
+ *
+ * Copyright (C) 2003, Axis Communications AB.
+ */
+
+#include <linux/config.h>
+#include <linux/seq_file.h>
+#include <linux/proc_fs.h>
+#include <linux/delay.h>
+#include <linux/param.h>
+
+#ifdef CONFIG_PROC_FS
+
+#define HAS_FPU         0x0001
+#define HAS_MMU         0x0002
+#define HAS_ETHERNET100 0x0004
+#define HAS_TOKENRING   0x0008
+#define HAS_SCSI        0x0010
+#define HAS_ATA         0x0020
+#define HAS_USB         0x0040
+#define HAS_IRQ_BUG     0x0080
+#define HAS_MMU_BUG     0x0100
+
+struct cpu_info {
+	char *cpu_model;
+	unsigned short rev;
+	unsigned short cache_size;
+	unsigned short flags;
+};
+
+/* Some of these model are here for historical reasons only. */
+static struct cpu_info cpinfo[] = {
+	{"ETRAX 1", 0, 0, 0},
+	{"ETRAX 2", 1, 0, 0},
+	{"ETRAX 3", 2, 0, 0},
+	{"ETRAX 4", 3, 0, 0},
+	{"Simulator", 7, 8, HAS_ETHERNET100 | HAS_SCSI | HAS_ATA},
+	{"ETRAX 100", 8, 8, HAS_ETHERNET100 | HAS_SCSI | HAS_ATA | HAS_IRQ_BUG},
+	{"ETRAX 100", 9, 8, HAS_ETHERNET100 | HAS_SCSI | HAS_ATA},
+
+	{"ETRAX 100LX", 10, 8, HAS_ETHERNET100 | HAS_SCSI | HAS_ATA | HAS_USB
+			     | HAS_MMU | HAS_MMU_BUG},
+
+	{"ETRAX 100LX v2", 11, 8, HAS_ETHERNET100 | HAS_SCSI | HAS_ATA | HAS_USB
+			        | HAS_MMU},
+
+	{"ETRAX FS", 32, 32, HAS_ETHERNET100 | HAS_ATA | HAS_MMU},
+
+	{"Unknown", 0, 0, 0}
+};
+
+int
+show_cpuinfo(struct seq_file *m, void *v)
+{
+	int i;
+	int cpu = (int)v - 1;
+	int entries;
+	unsigned long revision;
+	struct cpu_info *info;
+
+	entries = sizeof cpinfo / sizeof(struct cpu_info);
+	info = &cpinfo[entries - 1];
+
+#ifdef CONFIG_SMP
+	if (!cpu_online(cpu))
+		return 0;
+#endif
+
+	revision = rdvr();
+
+	for (i = 0; i < entries; i++) {
+		if (cpinfo[i].rev == revision) {
+			info = &cpinfo[i];
+			break;
+		}
+	}
+
+	return seq_printf(m,
+		"processor\t: %d\n"
+		"cpu\t\t: CRIS\n"
+		"cpu revision\t: %lu\n"
+		"cpu model\t: %s\n"
+		"cache size\t: %d KB\n"
+		"fpu\t\t: %s\n"
+		"mmu\t\t: %s\n"
+		"mmu DMA bug\t: %s\n"
+		"ethernet\t: %s Mbps\n"
+		"token ring\t: %s\n"
+		"scsi\t\t: %s\n"
+		"ata\t\t: %s\n"
+		"usb\t\t: %s\n"
+		"bogomips\t: %lu.%02lu\n\n",
+
+		cpu,
+		revision,
+		info->cpu_model,
+		info->cache_size,
+		info->flags & HAS_FPU ? "yes" : "no",
+		info->flags & HAS_MMU ? "yes" : "no",
+		info->flags & HAS_MMU_BUG ? "yes" : "no",
+		info->flags & HAS_ETHERNET100 ? "10/100" : "10",
+		info->flags & HAS_TOKENRING ? "4/16 Mbps" : "no",
+		info->flags & HAS_SCSI ? "yes" : "no",
+		info->flags & HAS_ATA ? "yes" : "no",
+		info->flags & HAS_USB ? "yes" : "no",
+		(loops_per_jiffy * HZ + 500) / 500000,
+		((loops_per_jiffy * HZ + 500) / 5000) % 100);
+}
+
+#endif /* CONFIG_PROC_FS */
+
+void
+show_etrax_copyright(void)
+{
+	printk(KERN_INFO
+               "Linux/CRISv32 port on ETRAX FS (C) 2003, 2004 Axis Communications AB\n");
+}
diff --git a/arch/cris/arch-v32/kernel/signal.c b/arch/cris/arch-v32/kernel/signal.c
new file mode 100644
--- /dev/null
+++ b/arch/cris/arch-v32/kernel/signal.c
@@ -0,0 +1,708 @@
+/*
+ * Copyright (C) 2003, Axis Communications AB.
+ */
+
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/kernel.h>
+#include <linux/signal.h>
+#include <linux/errno.h>
+#include <linux/wait.h>
+#include <linux/ptrace.h>
+#include <linux/unistd.h>
+#include <linux/stddef.h>
+#include <linux/syscalls.h>
+#include <linux/vmalloc.h>
+
+#include <asm/io.h>
+#include <asm/processor.h>
+#include <asm/ucontext.h>
+#include <asm/uaccess.h>
+#include <asm/arch/ptrace.h>
+#include <asm/arch/hwregs/cpu_vect.h>
+
+extern unsigned long cris_signal_return_page;
+
+/* Flag to check if a signal is blockable. */
+#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
+
+/*
+ * A syscall in CRIS is really a "break 13" instruction, which is 2
+ * bytes. The registers is manipulated so upon return the instruction
+ * will be executed again.
+ *
+ * This relies on that PC points to the instruction after the break call.
+ */
+#define RESTART_CRIS_SYS(regs) regs->r10 = regs->orig_r10; regs->erp -= 2;
+
+/* Signal frames. */
+struct signal_frame {
+	struct sigcontext sc;
+	unsigned long extramask[_NSIG_WORDS - 1];
+	unsigned char retcode[8];	/* Trampoline code. */
+};
+
+struct rt_signal_frame {
+	struct siginfo *pinfo;
+	void *puc;
+	struct siginfo info;
+	struct ucontext uc;
+	unsigned char retcode[8];	/* Trampoline code. */
+};
+
+int do_signal(int restart, sigset_t *oldset, struct pt_regs *regs);
+void keep_debug_flags(unsigned long oldccs, unsigned long oldspc,
+		      struct pt_regs *regs);
+/*
+ * Swap in the new signal mask, and wait for a signal. Define some
+ * dummy arguments to be able to reach the regs argument.
+ */
+int
+sys_sigsuspend(old_sigset_t mask, long r11, long r12, long r13, long mof,
+	       long srp, struct pt_regs *regs)
+{
+	sigset_t saveset;
+
+	mask &= _BLOCKABLE;
+
+	spin_lock_irq(&current->sighand->siglock);
+
+	saveset = current->blocked;
+
+	siginitset(&current->blocked, mask);
+
+	recalc_sigpending();
+	spin_unlock_irq(&current->sighand->siglock);
+
+	regs->r10 = -EINTR;
+
+	while (1) {
+		current->state = TASK_INTERRUPTIBLE;
+		schedule();
+
+		if (do_signal(0, &saveset, regs)) {
+			/*
+			 * This point is reached twice: once to call
+			 * the signal handler, then again to return
+			 * from the sigsuspend system call. When
+			 * calling the signal handler, R10 hold the
+			 * signal number as set by do_signal(). The
+			 * sigsuspend  call will always return with
+			 * the restored value above; -EINTR.
+			 */
+			return regs->r10;
+		}
+	}
+}
+
+/* Define some dummy arguments to be able to reach the regs argument. */
+int
+sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize, long r12, long r13,
+		  long mof, long srp, struct pt_regs *regs)
+{
+	sigset_t saveset;
+	sigset_t newset;
+
+	if (sigsetsize != sizeof(sigset_t))
+		return -EINVAL;
+
+	if (copy_from_user(&newset, unewset, sizeof(newset)))
+		return -EFAULT;
+
+	sigdelsetmask(&newset, ~_BLOCKABLE);
+	spin_lock_irq(&current->sighand->siglock);
+
+	saveset = current->blocked;
+	current->blocked = newset;
+
+	recalc_sigpending();
+	spin_unlock_irq(&current->sighand->siglock);
+
+	regs->r10 = -EINTR;
+
+	while (1) {
+		current->state = TASK_INTERRUPTIBLE;
+		schedule();
+
+		if (do_signal(0, &saveset, regs)) {
+			/* See comment in function above. */
+			return regs->r10;
+		}
+	}
+}
+
+int
+sys_sigaction(int signal, const struct old_sigaction *act,
+	      struct old_sigaction *oact)
+{
+	int retval;
+	struct k_sigaction newk;
+	struct k_sigaction oldk;
+
+	if (act) {
+		old_sigset_t mask;
+
+		if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
+		    __get_user(newk.sa.sa_handler, &act->sa_handler) ||
+		    __get_user(newk.sa.sa_restorer, &act->sa_restorer))
+			return -EFAULT;
+
+		__get_user(newk.sa.sa_flags, &act->sa_flags);
+		__get_user(mask, &act->sa_mask);
+		siginitset(&newk.sa.sa_mask, mask);
+	}
+
+	retval = do_sigaction(signal, act ? &newk : NULL, oact ? &oldk : NULL);
+
+	if (!retval && oact) {
+		if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
+		    __put_user(oldk.sa.sa_handler, &oact->sa_handler) ||
+		    __put_user(oldk.sa.sa_restorer, &oact->sa_restorer))
+			return -EFAULT;
+
+		__put_user(oldk.sa.sa_flags, &oact->sa_flags);
+		__put_user(oldk.sa.sa_mask.sig[0], &oact->sa_mask);
+	}
+
+	return retval;
+}
+
+int
+sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss)
+{
+	return do_sigaltstack(uss, uoss, rdusp());
+}
+
+static int
+restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
+{
+	unsigned int err = 0;
+	unsigned long old_usp;
+
+        /* Always make any pending restarted system calls return -EINTR */
+	current_thread_info()->restart_block.fn = do_no_restart_syscall;
+
+	/*
+	 * Restore the registers from &sc->regs. sc is already checked
+	 * for VERIFY_READ since the signal_frame was previously
+	 * checked in sys_sigreturn().
+	 */
+	if (__copy_from_user(regs, sc, sizeof(struct pt_regs)))
+		goto badframe;
+
+	/* Make that the user-mode flag is set. */
+	regs->ccs |= (1 << (U_CCS_BITNR + CCS_SHIFT));
+
+	/* Restore the old USP. */
+	err |= __get_user(old_usp, &sc->usp);
+	wrusp(old_usp);
+
+	return err;
+
+badframe:
+	return 1;
+}
+
+/* Define some dummy arguments to be able to reach the regs argument. */
+asmlinkage int
+sys_sigreturn(long r10, long r11, long r12, long r13, long mof, long srp,
+	      struct pt_regs *regs)
+{
+	sigset_t set;
+	struct signal_frame __user *frame;
+	unsigned long oldspc = regs->spc;
+	unsigned long oldccs = regs->ccs;
+
+	frame = (struct signal_frame *) rdusp();
+
+	/*
+	 * Since the signal is stacked on a dword boundary, the frame
+	 * should be dword aligned here as well. It it's not, then the
+	 * user is trying some funny business.
+	 */
+	if (((long)frame) & 3)
+		goto badframe;
+
+	if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
+		goto badframe;
+
+	if (__get_user(set.sig[0], &frame->sc.oldmask) ||
+	    (_NSIG_WORDS > 1 && __copy_from_user(&set.sig[1],
+						 frame->extramask,
+						 sizeof(frame->extramask))))
+		goto badframe;
+
+	sigdelsetmask(&set, ~_BLOCKABLE);
+	spin_lock_irq(&current->sighand->siglock);
+
+	current->blocked = set;
+
+	recalc_sigpending();
+	spin_unlock_irq(&current->sighand->siglock);
+
+	if (restore_sigcontext(regs, &frame->sc))
+		goto badframe;
+
+	keep_debug_flags(oldccs, oldspc, regs);
+
+	return regs->r10;
+
+badframe:
+	force_sig(SIGSEGV, current);
+	return 0;
+}
+
+/* Define some dummy variables to be able to reach the regs argument. */
+asmlinkage int
+sys_rt_sigreturn(long r10, long r11, long r12, long r13, long mof, long srp,
+		 struct pt_regs *regs)
+{
+	sigset_t set;
+	struct rt_signal_frame __user *frame;
+	unsigned long oldspc = regs->spc;
+	unsigned long oldccs = regs->ccs;
+
+	frame = (struct rt_signal_frame *) rdusp();
+
+	/*
+	 * Since the signal is stacked on a dword boundary, the frame
+	 * should be dword aligned here as well. It it's not, then the
+	 * user is trying some funny business.
+	 */
+	if (((long)frame) & 3)
+		goto badframe;
+
+	if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
+		goto badframe;
+
+	if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
+		goto badframe;
+
+	sigdelsetmask(&set, ~_BLOCKABLE);
+	spin_lock_irq(&current->sighand->siglock);
+
+	current->blocked = set;
+
+	recalc_sigpending();
+	spin_unlock_irq(&current->sighand->siglock);
+
+	if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
+		goto badframe;
+
+	if (do_sigaltstack(&frame->uc.uc_stack, NULL, rdusp()) == -EFAULT)
+ 		goto badframe;
+
+	keep_debug_flags(oldccs, oldspc, regs);
+
+	return regs->r10;
+
+badframe:
+	force_sig(SIGSEGV, current);
+	return 0;
+}
+
+/* Setup a signal frame. */
+static int
+setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
+		 unsigned long mask)
+{
+	int err;
+	unsigned long usp;
+
+	err = 0;
+	usp = rdusp();
+
+	/*
+	 * Copy the registers. They are located first in sc, so it's
+	 * possible to use sc directly.
+	 */
+	err |= __copy_to_user(sc, regs, sizeof(struct pt_regs));
+
+	err |= __put_user(mask, &sc->oldmask);
+	err |= __put_user(usp, &sc->usp);
+
+	return err;
+}
+
+/* Figure out where to put the new signal frame - usually on the stack. */
+static inline void __user *
+get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
+{
+	unsigned long sp;
+
+	sp = rdusp();
+
+	/* This is the X/Open sanctioned signal stack switching. */
+	if (ka->sa.sa_flags & SA_ONSTACK) {
+		if (!on_sig_stack(sp))
+			sp = current->sas_ss_sp + current->sas_ss_size;
+	}
+
+	/* Make sure the frame is dword-aligned. */
+	sp &= ~3;
+
+	return (void __user *)(sp - frame_size);
+}
+
+/* Grab and setup a signal frame.
+ *
+ * Basically a lot of state-info is stacked, and arranged for the
+ * user-mode program to return to the kernel using either a trampiline
+ * which performs the syscall sigreturn(), or a provided user-mode
+ * trampoline.
+  */
+static void
+setup_frame(int sig, struct k_sigaction *ka,  sigset_t *set,
+	    struct pt_regs * regs)
+{
+	int err;
+	unsigned long return_ip;
+	struct signal_frame __user *frame;
+
+	err = 0;
+	frame = get_sigframe(ka, regs, sizeof(*frame));
+
+	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
+		goto give_sigsegv;
+
+	err |= setup_sigcontext(&frame->sc, regs, set->sig[0]);
+
+	if (err)
+		goto give_sigsegv;
+
+	if (_NSIG_WORDS > 1) {
+		err |= __copy_to_user(frame->extramask, &set->sig[1],
+				      sizeof(frame->extramask));
+	}
+
+	if (err)
+		goto give_sigsegv;
+
+	/*
+	 * Set up to return from user-space. If provided, use a stub
+	 * already located in user-space.
+	 */
+	if (ka->sa.sa_flags & SA_RESTORER) {
+		return_ip = (unsigned long)ka->sa.sa_restorer;
+	} else {
+		/* Trampoline - the desired return ip is in the signal return page. */
+		return_ip = cris_signal_return_page;
+
+		/*
+		 * This is movu.w __NR_sigreturn, r9; break 13;
+		 *
+		 * WE DO NOT USE IT ANY MORE! It's only left here for historical
+		 * reasons and because gdb uses it as a signature to notice
+		 * signal handler stack frames.
+		 */
+		err |= __put_user(0x9c5f,         (short __user*)(frame->retcode+0));
+		err |= __put_user(__NR_sigreturn, (short __user*)(frame->retcode+2));
+		err |= __put_user(0xe93d,         (short __user*)(frame->retcode+4));
+	}
+
+	if (err)
+		goto give_sigsegv;
+
+	/*
+	 * Set up registers for signal handler.
+	 *
+	 * Where the code enters now.
+	 * Where the code enter later.
+	 * First argument, signo.
+	 */
+	regs->erp = (unsigned long) ka->sa.sa_handler;
+	regs->srp = return_ip;
+	regs->r10 = sig;
+
+	/* Actually move the USP to reflect the stacked frame. */
+	wrusp((unsigned long)frame);
+
+	return;
+
+give_sigsegv:
+	if (sig == SIGSEGV)
+		ka->sa.sa_handler = SIG_DFL;
+
+	force_sig(SIGSEGV, current);
+}
+
+static void
+setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
+	       sigset_t *set, struct pt_regs * regs)
+{
+	int err;
+	unsigned long return_ip;
+	struct rt_signal_frame __user *frame;
+
+	err = 0;
+	frame = get_sigframe(ka, regs, sizeof(*frame));
+
+	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
+		goto give_sigsegv;
+
+	/* TODO: what is the current->exec_domain stuff and invmap ? */
+
+	err |= __put_user(&frame->info, &frame->pinfo);
+	err |= __put_user(&frame->uc, &frame->puc);
+	err |= copy_siginfo_to_user(&frame->info, info);
+
+	if (err)
+		goto give_sigsegv;
+
+	/* Clear all the bits of the ucontext we don't use.  */
+	err |= __clear_user(&frame->uc, offsetof(struct ucontext, uc_mcontext));
+	err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0]);
+	err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
+
+	if (err)
+		goto give_sigsegv;
+
+	/*
+	 * Set up to return from user-space. If provided, use a stub
+	 * already located in user-space.
+	 */
+	if (ka->sa.sa_flags & SA_RESTORER) {
+		return_ip = (unsigned long) ka->sa.sa_restorer;
+	} else {
+		/* Trampoline - the desired return ip is in the signal return page. */
+		return_ip = cris_signal_return_page + 6;
+
+		/*
+		 * This is movu.w __NR_rt_sigreturn, r9; break 13;
+		 *
+		 * WE DO NOT USE IT ANY MORE! It's only left here for historical
+		 * reasons and because gdb uses it as a signature to notice
+		 * signal handler stack frames.
+		 */
+		err |= __put_user(0x9c5f, (short __user*)(frame->retcode+0));
+
+		err |= __put_user(__NR_rt_sigreturn,
+				  (short __user*)(frame->retcode+2));
+
+		err |= __put_user(0xe93d, (short __user*)(frame->retcode+4));
+	}
+
+	if (err)
+		goto give_sigsegv;
+
+	/*
+	 * Set up registers for signal handler.
+	 *
+	 * Where the code enters now.
+	 * Where the code enters later.
+	 * First argument is signo.
+	 * Second argument is (siginfo_t *).
+	 * Third argument is unused.
+	 */
+	regs->erp = (unsigned long) ka->sa.sa_handler;
+	regs->srp = return_ip;
+	regs->r10 = sig;
+	regs->r11 = (unsigned long) &frame->info;
+	regs->r12 = 0;
+
+	/* Actually move the usp to reflect the stacked frame. */
+	wrusp((unsigned long)frame);
+
+	return;
+
+give_sigsegv:
+	if (sig == SIGSEGV)
+		ka->sa.sa_handler = SIG_DFL;
+
+	force_sig(SIGSEGV, current);
+}
+
+/* Invoke a singal handler to, well, handle the signal. */
+extern inline void
+handle_signal(int canrestart, unsigned long sig,
+	      siginfo_t *info, struct k_sigaction *ka,
+              sigset_t *oldset, struct pt_regs * regs)
+{
+	/* Check if this got called from a system call. */
+	if (canrestart) {
+		/* If so, check system call restarting. */
+		switch (regs->r10) {
+			case -ERESTART_RESTARTBLOCK:
+			case -ERESTARTNOHAND:
+				/*
+				 * This means that the syscall should
+				 * only be restarted if there was no
+				 * handler for the signal, and since
+				 * this point isn't reached unless
+				 * there is a handler, there's no need
+				 * to restart.
+				 */
+				regs->r10 = -EINTR;
+				break;
+
+                        case -ERESTARTSYS:
+				/*
+				 * This means restart the syscall if
+                                 * there is no handler, or the handler
+                                 * was registered with SA_RESTART.
+				 */
+				if (!(ka->sa.sa_flags & SA_RESTART)) {
+					regs->r10 = -EINTR;
+					break;
+				}
+
+				/* Fall through. */
+
+			case -ERESTARTNOINTR:
+				/*
+				 * This means that the syscall should
+                                 * be called again after the signal
+                                 * handler returns.
+				 */
+				RESTART_CRIS_SYS(regs);
+				break;
+                }
+        }
+
+	/* Set up the stack frame. */
+	if (ka->sa.sa_flags & SA_SIGINFO)
+		setup_rt_frame(sig, ka, info, oldset, regs);
+	else
+		setup_frame(sig, ka, oldset, regs);
+
+	if (ka->sa.sa_flags & SA_ONESHOT)
+		ka->sa.sa_handler = SIG_DFL;
+
+	if (!(ka->sa.sa_flags & SA_NODEFER)) {
+		spin_lock_irq(&current->sighand->siglock);
+		sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
+		sigaddset(&current->blocked,sig);
+		recalc_sigpending();
+		spin_unlock_irq(&current->sighand->siglock);
+	}
+}
+
+/*
+ * Note that 'init' is a special process: it doesn't get signals it doesn't
+ * want to handle. Thus you cannot kill init even with a SIGKILL even by
+ * mistake.
+ *
+ * Also note that the regs structure given here as an argument, is the latest
+ * pushed pt_regs. It may or may not be the same as the first pushed registers
+ * when the initial usermode->kernelmode transition took place. Therefore
+ * we can use user_mode(regs) to see if we came directly from kernel or user
+ * mode below.
+ */
+int
+do_signal(int canrestart, sigset_t *oldset, struct pt_regs *regs)
+{
+	int signr;
+	siginfo_t info;
+        struct k_sigaction ka;
+
+	/*
+	 * The common case should go fast, which is why this point is
+	 * reached from kernel-mode. If that's the case, just return
+	 * without doing anything.
+	 */
+	if (!user_mode(regs))
+		return 1;
+
+	if (!oldset)
+		oldset = &current->blocked;
+
+	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
+
+	if (signr > 0) {
+		/* Deliver the signal. */
+		handle_signal(canrestart, signr, &info, &ka, oldset, regs);
+		return 1;
+	}
+
+	/* Got here from a system call? */
+	if (canrestart) {
+		/* Restart the system call - no handlers present. */
+		if (regs->r10 == -ERESTARTNOHAND ||
+		    regs->r10 == -ERESTARTSYS ||
+		    regs->r10 == -ERESTARTNOINTR) {
+			RESTART_CRIS_SYS(regs);
+		}
+
+		if (regs->r10 == -ERESTART_RESTARTBLOCK){
+			regs->r10 = __NR_restart_syscall;
+			regs->erp -= 2;
+		}
+	}
+
+	return 0;
+}
+
+asmlinkage void
+ugdb_trap_user(struct thread_info *ti, int sig)
+{
+	if (((user_regs(ti)->exs & 0xff00) >> 8) != SINGLE_STEP_INTR_VECT) {
+		/* Zero single-step PC if the reason we stopped wasn't a single
+		   step exception. This is to avoid relying on it when it isn't
+		   reliable. */
+		user_regs(ti)->spc = 0;
+	}
+	/* FIXME: Filter out false h/w breakpoint hits (i.e. EDA
+	   not withing any configured h/w breakpoint range). Synchronize with
+	   what already exists for kernel debugging.  */
+	if (((user_regs(ti)->exs & 0xff00) >> 8) == BREAK_8_INTR_VECT) {
+		/* Break 8: subtract 2 from ERP unless in a delay slot. */
+		if (!(user_regs(ti)->erp & 0x1))
+			user_regs(ti)->erp -= 2;
+	}
+	sys_kill(ti->task->pid, sig);
+}
+
+void
+keep_debug_flags(unsigned long oldccs, unsigned long oldspc,
+		 struct pt_regs *regs)
+{
+	if (oldccs & (1 << Q_CCS_BITNR)) {
+		/* Pending single step due to single-stepping the break 13
+		   in the signal trampoline: keep the Q flag. */
+		regs->ccs |= (1 << Q_CCS_BITNR);
+		/* S flag should be set - complain if it's not. */
+		if (!(oldccs & (1 << (S_CCS_BITNR + CCS_SHIFT)))) {
+			printk("Q flag but no S flag?");
+		}
+		regs->ccs |= (1 << (S_CCS_BITNR + CCS_SHIFT));
+		/* Assume the SPC is valid and interesting. */
+		regs->spc = oldspc;
+
+	} else if (oldccs & (1 << (S_CCS_BITNR + CCS_SHIFT))) {
+		/* If a h/w bp was set in the signal handler we need
+		   to keep the S flag. */
+		regs->ccs |= (1 << (S_CCS_BITNR + CCS_SHIFT));
+		/* Don't keep the old SPC though; if we got here due to
+		   a single-step, the Q flag should have been set. */
+	} else if (regs->spc) {
+		/* If we were single-stepping *before* the signal was taken,
+		   we don't want to restore that state now, because GDB will
+		   have forgotten all about it. */
+		regs->spc = 0;
+		regs->ccs &= ~(1 << (S_CCS_BITNR + CCS_SHIFT));
+	}
+}
+
+/* Set up the trampolines on the signal return page. */
+int __init
+cris_init_signal(void)
+{
+	u16* data = (u16*)kmalloc(PAGE_SIZE, GFP_KERNEL);
+
+	/* This is movu.w __NR_sigreturn, r9; break 13; */
+	data[0] = 0x9c5f;
+	data[1] = __NR_sigreturn;
+	data[2] = 0xe93d;
+	/* This is movu.w __NR_rt_sigreturn, r9; break 13; */
+	data[3] = 0x9c5f;
+	data[4] = __NR_rt_sigreturn;
+	data[5] = 0xe93d;
+
+	/* Map to userspace with appropriate permissions (no write access...) */
+	cris_signal_return_page = (unsigned long)
+          __ioremap_prot(virt_to_phys(data), PAGE_SIZE, PAGE_SIGNAL_TRAMPOLINE);
+
+	return 0;
+}
+
+__initcall(cris_init_signal);
diff --git a/arch/cris/arch-v32/kernel/smp.c b/arch/cris/arch-v32/kernel/smp.c
new file mode 100644
--- /dev/null
+++ b/arch/cris/arch-v32/kernel/smp.c
@@ -0,0 +1,348 @@
+#include <asm/delay.h>
+#include <asm/arch/irq.h>
+#include <asm/arch/hwregs/intr_vect.h>
+#include <asm/arch/hwregs/intr_vect_defs.h>
+#include <asm/tlbflush.h>
+#include <asm/mmu_context.h>
+#include <asm/arch/hwregs/mmu_defs_asm.h>
+#include <asm/arch/hwregs/supp_reg.h>
+#include <asm/atomic.h>
+
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/timex.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/cpumask.h>
+#include <linux/interrupt.h>
+
+#define IPI_SCHEDULE 1
+#define IPI_CALL 2
+#define IPI_FLUSH_TLB 4
+
+#define FLUSH_ALL (void*)0xffffffff
+
+/* Vector of locks used for various atomic operations */
+spinlock_t cris_atomic_locks[] = { [0 ... LOCK_COUNT - 1] = SPIN_LOCK_UNLOCKED};
+
+/* CPU masks */
+cpumask_t cpu_online_map = CPU_MASK_NONE;
+cpumask_t phys_cpu_present_map = CPU_MASK_NONE;
+
+/* Variables used during SMP boot */
+volatile int cpu_now_booting = 0;
+volatile struct thread_info *smp_init_current_idle_thread;
+
+/* Variables used during IPI */
+static DEFINE_SPINLOCK(call_lock);
+static DEFINE_SPINLOCK(tlbstate_lock);
+
+struct call_data_struct {
+	void (*func) (void *info);
+	void *info;
+	int wait;
+};
+
+static struct call_data_struct * call_data;
+
+static struct mm_struct* flush_mm;
+static struct vm_area_struct* flush_vma;
+static unsigned long flush_addr;
+
+extern int setup_irq(int, struct irqaction *);
+
+/* Mode registers */
+static unsigned long irq_regs[NR_CPUS] =
+{
+  regi_irq,
+  regi_irq2
+};
+
+static irqreturn_t crisv32_ipi_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static int send_ipi(int vector, int wait, cpumask_t cpu_mask);
+static struct irqaction irq_ipi  = { crisv32_ipi_interrupt, SA_INTERRUPT,
+                                     CPU_MASK_NONE, "ipi", NULL, NULL};
+
+extern void cris_mmu_init(void);
+extern void cris_timer_init(void);
+
+/* SMP initialization */
+void __init smp_prepare_cpus(unsigned int max_cpus)
+{
+	int i;
+
+	/* From now on we can expect IPIs so set them up */
+	setup_irq(IPI_INTR_VECT, &irq_ipi);
+
+	/* Mark all possible CPUs as present */
+	for (i = 0; i < max_cpus; i++)
+	    cpu_set(i, phys_cpu_present_map);
+}
+
+void __devinit smp_prepare_boot_cpu(void)
+{
+	/* PGD pointer has moved after per_cpu initialization so
+	 * update the MMU.
+	 */
+  	pgd_t **pgd;
+	pgd = (pgd_t**)&per_cpu(current_pgd, smp_processor_id());
+
+	SUPP_BANK_SEL(1);
+	SUPP_REG_WR(RW_MM_TLB_PGD, pgd);
+	SUPP_BANK_SEL(2);
+	SUPP_REG_WR(RW_MM_TLB_PGD, pgd);
+
+	cpu_set(0, cpu_online_map);
+	cpu_set(0, phys_cpu_present_map);
+}
+
+void __init smp_cpus_done(unsigned int max_cpus)
+{
+}
+
+/* Bring one cpu online.*/
+static int __init
+smp_boot_one_cpu(int cpuid)
+{
+	unsigned timeout;
+	struct task_struct *idle;
+
+	idle = fork_idle(cpuid);
+	if (IS_ERR(idle))
+		panic("SMP: fork failed for CPU:%d", cpuid);
+
+	idle->thread_info->cpu = cpuid;
+
+	/* Information to the CPU that is about to boot */
+	smp_init_current_idle_thread = idle->thread_info;
+	cpu_now_booting = cpuid;
+
+	/* Wait for CPU to come online */
+	for (timeout = 0; timeout < 10000; timeout++) {
+		if(cpu_online(cpuid)) {
+			cpu_now_booting = 0;
+			smp_init_current_idle_thread = NULL;
+			return 0; /* CPU online */
+		}
+		udelay(100);
+		barrier();
+	}
+
+	put_task_struct(idle);
+	idle = NULL;
+
+	printk(KERN_CRIT "SMP: CPU:%d is stuck.\n", cpuid);
+	return -1;
+}
+
+/* Secondary CPUs starts uing C here. Here we need to setup CPU
+ * specific stuff such as the local timer and the MMU. */
+void __init smp_callin(void)
+{
+	extern void cpu_idle(void);
+
+	int cpu = cpu_now_booting;
+	reg_intr_vect_rw_mask vect_mask = {0};
+
+	/* Initialise the idle task for this CPU */
+	atomic_inc(&init_mm.mm_count);
+	current->active_mm = &init_mm;
+
+	/* Set up MMU */
+	cris_mmu_init();
+	__flush_tlb_all();
+
+	/* Setup local timer. */
+	cris_timer_init();
+
+	/* Enable IRQ and idle */
+	REG_WR(intr_vect, irq_regs[cpu], rw_mask, vect_mask);
+	unmask_irq(IPI_INTR_VECT);
+	unmask_irq(TIMER_INTR_VECT);
+	local_irq_enable();
+
+	cpu_set(cpu, cpu_online_map);
+	cpu_idle();
+}
+
+/* Stop execution on this CPU.*/
+void stop_this_cpu(void* dummy)
+{
+	local_irq_disable();
+	asm volatile("halt");
+}
+
+/* Other calls */
+void smp_send_stop(void)
+{
+	smp_call_function(stop_this_cpu, NULL, 1, 0);
+}
+
+int setup_profiling_timer(unsigned int multiplier)
+{
+	return -EINVAL;
+}
+
+
+/* cache_decay_ticks is used by the scheduler to decide if a process
+ * is "hot" on one CPU. A higher value means a higher penalty to move
+ * a process to another CPU. Our cache is rather small so we report
+ * 1 tick.
+ */
+unsigned long cache_decay_ticks = 1;
+
+int __devinit __cpu_up(unsigned int cpu)
+{
+	smp_boot_one_cpu(cpu);
+	return cpu_online(cpu) ? 0 : -ENOSYS;
+}
+
+void smp_send_reschedule(int cpu)
+{
+	cpumask_t cpu_mask = CPU_MASK_NONE;
+	cpu_set(cpu, cpu_mask);
+	send_ipi(IPI_SCHEDULE, 0, cpu_mask);
+}
+
+/* TLB flushing
+ *
+ * Flush needs to be done on the local CPU and on any other CPU that
+ * may have the same mapping. The mm->cpu_vm_mask is used to keep track
+ * of which CPUs that a specific process has been executed on.
+ */
+void flush_tlb_common(struct mm_struct* mm, struct vm_area_struct* vma, unsigned long addr)
+{
+	unsigned long flags;
+	cpumask_t cpu_mask;
+
+	spin_lock_irqsave(&tlbstate_lock, flags);
+	cpu_mask = (mm == FLUSH_ALL ? CPU_MASK_ALL : mm->cpu_vm_mask);
+	cpu_clear(smp_processor_id(), cpu_mask);
+	flush_mm = mm;
+	flush_vma = vma;
+	flush_addr = addr;
+	send_ipi(IPI_FLUSH_TLB, 1, cpu_mask);
+	spin_unlock_irqrestore(&tlbstate_lock, flags);
+}
+
+void flush_tlb_all(void)
+{
+	__flush_tlb_all();
+	flush_tlb_common(FLUSH_ALL, FLUSH_ALL, 0);
+}
+
+void flush_tlb_mm(struct mm_struct *mm)
+{
+	__flush_tlb_mm(mm);
+	flush_tlb_common(mm, FLUSH_ALL, 0);
+	/* No more mappings in other CPUs */
+	cpus_clear(mm->cpu_vm_mask);
+	cpu_set(smp_processor_id(), mm->cpu_vm_mask);
+}
+
+void flush_tlb_page(struct vm_area_struct *vma,
+			   unsigned long addr)
+{
+	__flush_tlb_page(vma, addr);
+	flush_tlb_common(vma->vm_mm, vma, addr);
+}
+
+/* Inter processor interrupts
+ *
+ * The IPIs are used for:
+ *   * Force a schedule on a CPU
+ *   * FLush TLB on other CPUs
+ *   * Call a function on other CPUs
+ */
+
+int send_ipi(int vector, int wait, cpumask_t cpu_mask)
+{
+	int i = 0;
+	reg_intr_vect_rw_ipi ipi = REG_RD(intr_vect, irq_regs[i], rw_ipi);
+	int ret = 0;
+
+	/* Calculate CPUs to send to. */
+	cpus_and(cpu_mask, cpu_mask, cpu_online_map);
+
+	/* Send the IPI. */
+	for_each_cpu_mask(i, cpu_mask)
+	{
+		ipi.vector |= vector;
+		REG_WR(intr_vect, irq_regs[i], rw_ipi, ipi);
+	}
+
+	/* Wait for IPI to finish on other CPUS */
+	if (wait) {
+		for_each_cpu_mask(i, cpu_mask) {
+                        int j;
+                        for (j = 0 ; j < 1000; j++) {
+				ipi = REG_RD(intr_vect, irq_regs[i], rw_ipi);
+				if (!ipi.vector)
+					break;
+				udelay(100);
+			}
+
+			/* Timeout? */
+			if (ipi.vector) {
+				printk("SMP call timeout from %d to %d\n", smp_processor_id(), i);
+				ret = -ETIMEDOUT;
+				dump_stack();
+			}
+		}
+	}
+	return ret;
+}
+
+/*
+ * You must not call this function with disabled interrupts or from a
+ * hardware interrupt handler or from a bottom half handler.
+ */
+int smp_call_function(void (*func)(void *info), void *info,
+		      int nonatomic, int wait)
+{
+	cpumask_t cpu_mask = CPU_MASK_ALL;
+	struct call_data_struct data;
+	int ret;
+
+	cpu_clear(smp_processor_id(), cpu_mask);
+
+	WARN_ON(irqs_disabled());
+
+	data.func = func;
+	data.info = info;
+	data.wait = wait;
+
+	spin_lock(&call_lock);
+	call_data = &data;
+	ret = send_ipi(IPI_CALL, wait, cpu_mask);
+	spin_unlock(&call_lock);
+
+	return ret;
+}
+
+irqreturn_t crisv32_ipi_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	void (*func) (void *info) = call_data->func;
+	void *info = call_data->info;
+	reg_intr_vect_rw_ipi ipi;
+
+	ipi = REG_RD(intr_vect, irq_regs[smp_processor_id()], rw_ipi);
+
+	if (ipi.vector & IPI_CALL) {
+	         func(info);
+	}
+	if (ipi.vector & IPI_FLUSH_TLB) {
+		     if (flush_mm == FLUSH_ALL)
+			 __flush_tlb_all();
+		     else if (flush_vma == FLUSH_ALL)
+			__flush_tlb_mm(flush_mm);
+		     else
+			__flush_tlb_page(flush_vma, flush_addr);
+	}
+
+	ipi.vector = 0;
+	REG_WR(intr_vect, irq_regs[smp_processor_id()], rw_ipi, ipi);
+
+	return IRQ_HANDLED;
+}
+
diff --git a/arch/cris/arch-v32/kernel/time.c b/arch/cris/arch-v32/kernel/time.c
new file mode 100644
--- /dev/null
+++ b/arch/cris/arch-v32/kernel/time.c
@@ -0,0 +1,341 @@
+/* $Id: time.c,v 1.19 2005/04/29 05:40:09 starvik Exp $
+ *
+ *  linux/arch/cris/arch-v32/kernel/time.c
+ *
+ *  Copyright (C) 2003 Axis Communications AB
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/timex.h>
+#include <linux/time.h>
+#include <linux/jiffies.h>
+#include <linux/interrupt.h>
+#include <linux/swap.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/threads.h>
+#include <asm/types.h>
+#include <asm/signal.h>
+#include <asm/io.h>
+#include <asm/delay.h>
+#include <asm/rtc.h>
+#include <asm/irq.h>
+
+#include <asm/arch/hwregs/reg_map.h>
+#include <asm/arch/hwregs/reg_rdwr.h>
+#include <asm/arch/hwregs/timer_defs.h>
+#include <asm/arch/hwregs/intr_vect_defs.h>
+
+/* Watchdog defines */
+#define ETRAX_WD_KEY_MASK 0x7F /* key is 7 bit */
+#define ETRAX_WD_HZ       763 /* watchdog counts at 763 Hz */
+#define ETRAX_WD_CNT      ((2*ETRAX_WD_HZ)/HZ + 1) /* Number of 763 counts before watchdog bites */
+
+unsigned long timer_regs[NR_CPUS] =
+{
+  regi_timer,
+#ifdef CONFIG_SMP
+  regi_timer2
+#endif
+};
+
+extern void update_xtime_from_cmos(void);
+extern int set_rtc_mmss(unsigned long nowtime);
+extern int setup_irq(int, struct irqaction *);
+extern int have_rtc;
+
+unsigned long get_ns_in_jiffie(void)
+{
+	reg_timer_r_tmr0_data data;
+	unsigned long ns;
+
+	data = REG_RD(timer, regi_timer, r_tmr0_data);
+	ns = (TIMER0_DIV - data) * 10;
+	return ns;
+}
+
+unsigned long do_slow_gettimeoffset(void)
+{
+	unsigned long count;
+	unsigned long usec_count = 0;
+
+	static unsigned long count_p = TIMER0_DIV;/* for the first call after boot */
+	static unsigned long jiffies_p = 0;
+
+	/*
+	 * cache volatile jiffies temporarily; we have IRQs turned off.
+	 */
+	unsigned long jiffies_t;
+
+	/* The timer interrupt comes from Etrax timer 0. In order to get
+	 * better precision, we check the current value. It might have
+	 * underflowed already though.
+	 */
+
+	count = REG_RD(timer, regi_timer, r_tmr0_data);
+ 	jiffies_t = jiffies;
+
+	/*
+	 * avoiding timer inconsistencies (they are rare, but they happen)...
+	 * there are one problem that must be avoided here:
+	 *  1. the timer counter underflows
+	 */
+	if( jiffies_t == jiffies_p ) {
+		if( count > count_p ) {
+			/* Timer wrapped, use new count and prescale
+			 * increase the time corresponding to one jiffie
+			 */
+			usec_count = 1000000/HZ;
+		}
+	} else
+		jiffies_p = jiffies_t;
+        count_p = count;
+	/* Convert timer value to usec */
+	/* 100 MHz timer, divide by 100 to get usec */
+	usec_count +=  (TIMER0_DIV - count) / 100;
+	return usec_count;
+}
+
+/* From timer MDS describing the hardware watchdog:
+ * 4.3.1 Watchdog Operation
+ * The watchdog timer is an 8-bit timer with a configurable start value.
+ * Once started the whatchdog counts downwards with a frequency of 763 Hz
+ * (100/131072 MHz). When the watchdog counts down to 1, it generates an
+ * NMI (Non Maskable Interrupt), and when it counts down to 0, it resets the
+ * chip.
+ */
+/* This gives us 1.3 ms to do something useful when the NMI comes */
+
+/* right now, starting the watchdog is the same as resetting it */
+#define start_watchdog reset_watchdog
+
+#if defined(CONFIG_ETRAX_WATCHDOG)
+static short int watchdog_key = 42;  /* arbitrary 7 bit number */
+#endif
+
+/* number of pages to consider "out of memory". it is normal that the memory
+ * is used though, so put this really low.
+ */
+
+#define WATCHDOG_MIN_FREE_PAGES 8
+
+void
+reset_watchdog(void)
+{
+#if defined(CONFIG_ETRAX_WATCHDOG)
+	reg_timer_rw_wd_ctrl wd_ctrl = { 0 };
+
+	/* only keep watchdog happy as long as we have memory left! */
+	if(nr_free_pages() > WATCHDOG_MIN_FREE_PAGES) {
+		/* reset the watchdog with the inverse of the old key */
+		watchdog_key ^= ETRAX_WD_KEY_MASK; /* invert key, which is 7 bits */
+		wd_ctrl.cnt = ETRAX_WD_CNT;
+		wd_ctrl.cmd = regk_timer_start;
+		wd_ctrl.key = watchdog_key;
+		REG_WR(timer, regi_timer, rw_wd_ctrl, wd_ctrl);
+	}
+#endif
+}
+
+/* stop the watchdog - we still need the correct key */
+
+void
+stop_watchdog(void)
+{
+#if defined(CONFIG_ETRAX_WATCHDOG)
+	reg_timer_rw_wd_ctrl wd_ctrl = { 0 };
+	watchdog_key ^= ETRAX_WD_KEY_MASK; /* invert key, which is 7 bits */
+	wd_ctrl.cnt = ETRAX_WD_CNT;
+	wd_ctrl.cmd = regk_timer_stop;
+	wd_ctrl.key = watchdog_key;
+	REG_WR(timer, regi_timer, rw_wd_ctrl, wd_ctrl);
+#endif
+}
+
+extern void show_registers(struct pt_regs *regs);
+
+void
+handle_watchdog_bite(struct pt_regs* regs)
+{
+#if defined(CONFIG_ETRAX_WATCHDOG)
+	extern int cause_of_death;
+
+	raw_printk("Watchdog bite\n");
+
+	/* Check if forced restart or unexpected watchdog */
+	if (cause_of_death == 0xbedead) {
+		while(1);
+	}
+
+	/* Unexpected watchdog, stop the watchdog and dump registers*/
+	stop_watchdog();
+	raw_printk("Oops: bitten by watchdog\n");
+        show_registers(regs);
+#ifndef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY
+	reset_watchdog();
+#endif
+	while(1) /* nothing */;
+#endif
+}
+
+/* last time the cmos clock got updated */
+static long last_rtc_update = 0;
+
+/*
+ * timer_interrupt() needs to keep up the real-time clock,
+ * as well as call the "do_timer()" routine every clocktick
+ */
+
+//static unsigned short myjiff; /* used by our debug routine print_timestamp */
+
+extern void cris_do_profile(struct pt_regs *regs);
+
+static inline irqreturn_t
+timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	int cpu = smp_processor_id();
+	reg_timer_r_masked_intr masked_intr;
+	reg_timer_rw_ack_intr ack_intr = { 0 };
+
+	/* Check if the timer interrupt is for us (a tmr0 int) */
+	masked_intr = REG_RD(timer, timer_regs[cpu], r_masked_intr);
+	if (!masked_intr.tmr0)
+		return IRQ_NONE;
+
+	/* acknowledge the timer irq */
+	ack_intr.tmr0 = 1;
+	REG_WR(timer, timer_regs[cpu], rw_ack_intr, ack_intr);
+
+	/* reset watchdog otherwise it resets us! */
+	reset_watchdog();
+
+        /* Update statistics. */
+	update_process_times(user_mode(regs));
+
+	cris_do_profile(regs); /* Save profiling information */
+
+	/* The master CPU is responsible for the time keeping. */
+	if (cpu != 0)
+		return IRQ_HANDLED;
+
+	/* call the real timer interrupt handler */
+	do_timer(regs);
+
+	/*
+	 * If we have an externally synchronized Linux clock, then update
+	 * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
+	 * called as close as possible to 500 ms before the new second starts.
+	 *
+	 * The division here is not time critical since it will run once in
+	 * 11 minutes
+	 */
+	if ((time_status & STA_UNSYNC) == 0 &&
+	    xtime.tv_sec > last_rtc_update + 660 &&
+	    (xtime.tv_nsec / 1000) >= 500000 - (tick_nsec / 1000) / 2 &&
+	    (xtime.tv_nsec / 1000) <= 500000 + (tick_nsec / 1000) / 2) {
+		if (set_rtc_mmss(xtime.tv_sec) == 0)
+			last_rtc_update = xtime.tv_sec;
+		else
+			last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */
+	}
+        return IRQ_HANDLED;
+}
+
+/* timer is SA_SHIRQ so drivers can add stuff to the timer irq chain
+ * it needs to be SA_INTERRUPT to make the jiffies update work properly
+ */
+
+static struct irqaction irq_timer  = { timer_interrupt, SA_SHIRQ | SA_INTERRUPT,
+				  CPU_MASK_NONE, "timer", NULL, NULL};
+
+void __init
+cris_timer_init(void)
+{
+	int cpu = smp_processor_id();
+  	reg_timer_rw_tmr0_ctrl tmr0_ctrl = { 0 };
+       	reg_timer_rw_tmr0_div tmr0_div = TIMER0_DIV;
+	reg_timer_rw_intr_mask timer_intr_mask;
+
+	/* Setup the etrax timers
+	 * Base frequency is 100MHz, divider 1000000 -> 100 HZ
+	 * We use timer0, so timer1 is free.
+	 * The trig timer is used by the fasttimer API if enabled.
+	 */
+
+       	tmr0_ctrl.op = regk_timer_ld;
+	tmr0_ctrl.freq = regk_timer_f100;
+       	REG_WR(timer, timer_regs[cpu], rw_tmr0_div, tmr0_div);
+       	REG_WR(timer, timer_regs[cpu], rw_tmr0_ctrl, tmr0_ctrl); /* Load */
+       	tmr0_ctrl.op = regk_timer_run;
+       	REG_WR(timer, timer_regs[cpu], rw_tmr0_ctrl, tmr0_ctrl); /* Start */
+
+       	/* enable the timer irq */
+       	timer_intr_mask = REG_RD(timer, timer_regs[cpu], rw_intr_mask);
+       	timer_intr_mask.tmr0 = 1;
+       	REG_WR(timer, timer_regs[cpu], rw_intr_mask, timer_intr_mask);
+}
+
+void __init
+time_init(void)
+{
+	reg_intr_vect_rw_mask intr_mask;
+
+	/* probe for the RTC and read it if it exists
+	 * Before the RTC can be probed the loops_per_usec variable needs
+	 * to be initialized to make usleep work. A better value for
+	 * loops_per_usec is calculated by the kernel later once the
+	 * clock has started.
+	 */
+	loops_per_usec = 50;
+
+	if(RTC_INIT() < 0) {
+		/* no RTC, start at 1980 */
+		xtime.tv_sec = 0;
+		xtime.tv_nsec = 0;
+		have_rtc = 0;
+	} else {
+		/* get the current time */
+		have_rtc = 1;
+		update_xtime_from_cmos();
+	}
+
+	/*
+	 * Initialize wall_to_monotonic such that adding it to xtime will yield zero, the
+	 * tv_nsec field must be normalized (i.e., 0 <= nsec < NSEC_PER_SEC).
+	 */
+	set_normalized_timespec(&wall_to_monotonic, -xtime.tv_sec, -xtime.tv_nsec);
+
+	/* Start CPU local timer */
+	cris_timer_init();
+
+	/* enable the timer irq in global config */
+	intr_mask = REG_RD(intr_vect, regi_irq, rw_mask);
+	intr_mask.timer = 1;
+	REG_WR(intr_vect, regi_irq, rw_mask, intr_mask);
+
+	/* now actually register the timer irq handler that calls timer_interrupt() */
+
+	setup_irq(TIMER_INTR_VECT, &irq_timer);
+
+	/* enable watchdog if we should use one */
+
+#if defined(CONFIG_ETRAX_WATCHDOG)
+	printk("Enabling watchdog...\n");
+	start_watchdog();
+
+	/* If we use the hardware watchdog, we want to trap it as an NMI
+	   and dump registers before it resets us.  For this to happen, we
+	   must set the "m" NMI enable flag (which once set, is unset only
+	   when an NMI is taken).
+
+	   The same goes for the external NMI, but that doesn't have any
+	   driver or infrastructure support yet.  */
+        {
+          unsigned long flags;
+          local_save_flags(flags);
+          flags |= (1<<30); /* NMI M flag is at bit 30 */
+          local_irq_restore(flags);
+        }
+#endif
+}
diff --git a/arch/cris/arch-v32/kernel/traps.c b/arch/cris/arch-v32/kernel/traps.c
new file mode 100644
--- /dev/null
+++ b/arch/cris/arch-v32/kernel/traps.c
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2003, Axis Communications AB.
+ */
+
+#include <linux/config.h>
+#include <linux/ptrace.h>
+#include <asm/uaccess.h>
+
+#include <asm/arch/hwregs/supp_reg.h>
+
+extern void reset_watchdog(void);
+extern void stop_watchdog(void);
+
+extern int raw_printk(const char *fmt, ...);
+
+void
+show_registers(struct pt_regs *regs)
+{
+	/*
+	 * It's possible to use either the USP register or current->thread.usp.
+	 * USP might not correspond to the current proccess for all cases this
+	 * function is called, and current->thread.usp isn't up to date for the
+	 * current proccess. Experience shows that using USP is the way to go.
+	 */
+	unsigned long usp;
+	unsigned long d_mmu_cause;
+	unsigned long i_mmu_cause;
+
+	usp = rdusp();
+
+	raw_printk("CPU: %d\n", smp_processor_id());
+
+	raw_printk("ERP: %08lx SRP: %08lx  CCS: %08lx USP: %08lx MOF: %08lx\n",
+		regs->erp, regs->srp, regs->ccs, usp, regs->mof);
+
+	raw_printk(" r0: %08lx  r1: %08lx   r2: %08lx  r3: %08lx\n",
+		regs->r0, regs->r1, regs->r2, regs->r3);
+
+	raw_printk(" r4: %08lx  r5: %08lx   r6: %08lx  r7: %08lx\n",
+		regs->r4, regs->r5, regs->r6, regs->r7);
+
+	raw_printk(" r8: %08lx  r9: %08lx  r10: %08lx r11: %08lx\n",
+		regs->r8, regs->r9, regs->r10, regs->r11);
+
+	raw_printk("r12: %08lx r13: %08lx oR10: %08lx acr: %08lx\n",
+		regs->r12, regs->r13, regs->orig_r10, regs->acr);
+
+	raw_printk("sp: %08lx\n", regs);
+
+	SUPP_BANK_SEL(BANK_IM);
+	SUPP_REG_RD(RW_MM_CAUSE, i_mmu_cause);
+
+	SUPP_BANK_SEL(BANK_DM);
+	SUPP_REG_RD(RW_MM_CAUSE, d_mmu_cause);
+
+	raw_printk("       Data MMU Cause: %08lx\n", d_mmu_cause);
+	raw_printk("Instruction MMU Cause: %08lx\n", i_mmu_cause);
+
+	raw_printk("Process %s (pid: %d, stackpage: %08lx)\n",
+		current->comm, current->pid, (unsigned long) current);
+
+	/* Show additional info if in kernel-mode. */
+	if (!user_mode(regs)) {
+		int i;
+		unsigned char c;
+
+		show_stack(NULL, (unsigned long *) usp);
+
+		/*
+		 * If the previous stack-dump wasn't a kernel one, dump the
+		 * kernel stack now.
+		 */
+		if (usp != 0)
+			show_stack(NULL, NULL);
+
+		raw_printk("\nCode: ");
+
+		if (regs->erp < PAGE_OFFSET)
+			goto bad_value;
+
+		/*
+		 * Quite often the value at regs->erp doesn't point to the
+		 * interesting instruction, which often is the previous
+		 * instruction. So dump at an offset large enough that the
+		 * instruction decoding should be in sync at the interesting
+		 * point, but small enough to fit on a row. The regs->erp
+		 * location is pointed out in a ksymoops-friendly way by
+		 * wrapping the byte for that address in parenthesis.
+		 */
+		for (i = -12; i < 12; i++) {
+			if (__get_user(c, &((unsigned char *) regs->erp)[i])) {
+bad_value:
+				raw_printk(" Bad IP value.");
+				break;
+			}
+
+			if (i == 0)
+				raw_printk("(%02x) ", c);
+			else
+				raw_printk("%02x ", c);
+		}
+
+		raw_printk("\n");
+	}
+}
+
+/*
+ * This gets called from entry.S when the watchdog has bitten. Show something
+ * similiar to an Oops dump, and if the kernel if configured to be a nice doggy;
+ * halt instead of reboot.
+ */
+void
+watchdog_bite_hook(struct pt_regs *regs)
+{
+#ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY
+	local_irq_disable();
+	stop_watchdog();
+	show_registers(regs);
+
+	while (1)
+		; /* Do nothing. */
+#else
+	show_registers(regs);
+#endif
+}
+
+/* This is normally the Oops function. */
+void
+die_if_kernel(const char *str, struct pt_regs *regs, long err)
+{
+	if (user_mode(regs))
+		return;
+
+#ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY
+	/*
+	 * This printout might take too long and could trigger
+	 * the watchdog normally. If NICE_DOGGY is set, simply
+	 * stop the watchdog during the printout.
+	 */
+	stop_watchdog();
+#endif
+
+	raw_printk("%s: %04lx\n", str, err & 0xffff);
+
+	show_registers(regs);
+
+#ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY
+	reset_watchdog();
+#endif
+
+	do_exit(SIGSEGV);
+}
+
+void arch_enable_nmi(void)
+{
+	unsigned long flags;
+	local_save_flags(flags);
+	flags |= (1<<30); /* NMI M flag is at bit 30 */
+	local_irq_restore(flags);
+}
diff --git a/arch/cris/arch-v32/kernel/vcs_hook.c b/arch/cris/arch-v32/kernel/vcs_hook.c
new file mode 100644
--- /dev/null
+++ b/arch/cris/arch-v32/kernel/vcs_hook.c
@@ -0,0 +1,96 @@
+// $Id: vcs_hook.c,v 1.2 2003/08/12 12:01:06 starvik Exp $
+//
+// Call simulator hook. This is the part running in the
+// simulated program.
+//
+
+#include "vcs_hook.h"
+#include <stdarg.h>
+#include <asm/arch-v32/hwregs/reg_map.h>
+#include <asm/arch-v32/hwregs/intr_vect_defs.h>
+
+#define HOOK_TRIG_ADDR     0xb7000000   /* hook cvlog model reg address */
+#define HOOK_MEM_BASE_ADDR 0xa0000000   /* csp4 (shared mem) base addr */
+
+#define HOOK_DATA(offset) ((unsigned*) HOOK_MEM_BASE_ADDR)[offset]
+#define VHOOK_DATA(offset) ((volatile unsigned*) HOOK_MEM_BASE_ADDR)[offset]
+#define HOOK_TRIG(funcid) do { *((unsigned *) HOOK_TRIG_ADDR) = funcid; } while(0)
+#define HOOK_DATA_BYTE(offset) ((unsigned char*) HOOK_MEM_BASE_ADDR)[offset]
+
+
+// ------------------------------------------------------------------ hook_call
+int hook_call( unsigned id, unsigned pcnt, ...) {
+  va_list ap;
+  unsigned i;
+  unsigned ret;
+#ifdef USING_SOS
+  PREEMPT_OFF_SAVE();
+#endif
+
+  // pass parameters
+  HOOK_DATA(0) = id;
+
+  /* Have to make hook_print_str a special case since we call with a
+     parameter of byte type. Should perhaps be a separate
+     hook_call. */
+
+  if (id == hook_print_str) {
+    int i;
+    char *str;
+
+    HOOK_DATA(1) = pcnt;
+
+    va_start(ap, pcnt);
+    str = (char*)va_arg(ap,unsigned);
+
+    for (i=0; i!=pcnt; i++) {
+      HOOK_DATA_BYTE(8+i) = str[i];
+    }
+    HOOK_DATA_BYTE(8+i) = 0;	/* null byte */
+  }
+  else {
+    va_start(ap, pcnt);
+    for( i = 1; i <= pcnt; i++ ) HOOK_DATA(i) = va_arg(ap,unsigned);
+    va_end(ap);
+  }
+
+  // read from mem to make sure data has propagated to memory before trigging
+  *((volatile unsigned*) HOOK_MEM_BASE_ADDR);
+
+  // trigger hook
+  HOOK_TRIG(id);
+
+  // wait for call to finish
+  while( VHOOK_DATA(0) > 0 ) {}
+
+  // extract return value
+
+  ret = VHOOK_DATA(1);
+
+#ifdef USING_SOS
+  PREEMPT_RESTORE();
+#endif
+  return ret;
+}
+
+unsigned
+hook_buf(unsigned i)
+{
+  return (HOOK_DATA(i));
+}
+
+void print_str( const char *str ) {
+  int i;
+  for (i=1; str[i]; i++);         /* find null at end of string */
+  hook_call(hook_print_str, i, str);
+}
+
+// --------------------------------------------------------------- CPU_KICK_DOG
+void CPU_KICK_DOG(void) {
+  (void) hook_call( hook_kick_dog, 0 );
+}
+
+// ------------------------------------------------------- CPU_WATCHDOG_TIMEOUT
+void CPU_WATCHDOG_TIMEOUT( unsigned t ) {
+  (void) hook_call( hook_dog_timeout, 1, t );
+}
diff --git a/arch/cris/arch-v32/kernel/vcs_hook.h b/arch/cris/arch-v32/kernel/vcs_hook.h
new file mode 100644
--- /dev/null
+++ b/arch/cris/arch-v32/kernel/vcs_hook.h
@@ -0,0 +1,42 @@
+// $Id: vcs_hook.h,v 1.1 2003/08/12 12:01:06 starvik Exp $
+//
+// Call simulator hook functions
+
+#ifndef HOOK_H
+#define HOOK_H
+
+int hook_call( unsigned id, unsigned pcnt, ...);
+
+enum hook_ids {
+  hook_debug_on = 1,
+  hook_debug_off,
+  hook_stop_sim_ok,
+  hook_stop_sim_fail,
+  hook_alloc_shared,
+  hook_ptr_shared,
+  hook_free_shared,
+  hook_file2shared,
+  hook_cmp_shared,
+  hook_print_params,
+  hook_sim_time,
+  hook_stop_sim,
+  hook_kick_dog,
+  hook_dog_timeout,
+  hook_rand,
+  hook_srand,
+  hook_rand_range,
+  hook_print_str,
+  hook_print_hex,
+  hook_cmp_offset_shared,
+  hook_fill_random_shared,
+  hook_alloc_random_data,
+  hook_calloc_random_data,
+  hook_print_int,
+  hook_print_uint,
+  hook_fputc,
+  hook_init_fd,
+  hook_sbrk
+
+};
+
+#endif
diff --git a/arch/cris/arch-v32/lib/Makefile b/arch/cris/arch-v32/lib/Makefile
new file mode 100644
--- /dev/null
+++ b/arch/cris/arch-v32/lib/Makefile
@@ -0,0 +1,6 @@
+#
+# Makefile for Etrax-specific library files..
+#
+
+lib-y  = checksum.o checksumcopy.o string.o usercopy.o memset.o csumcpfruser.o spinlock.o
+
diff --git a/arch/cris/arch-v32/lib/checksum.S b/arch/cris/arch-v32/lib/checksum.S
new file mode 100644
--- /dev/null
+++ b/arch/cris/arch-v32/lib/checksum.S
@@ -0,0 +1,111 @@
+/*
+ * A fast checksum routine using movem
+ * Copyright (c) 1998-2001, 2003 Axis Communications AB
+ *
+ * csum_partial(const unsigned char * buff, int len, unsigned int sum)
+ */
+
+	.globl	csum_partial
+csum_partial:
+
+	;; r10 - src
+	;; r11 - length
+	;; r12 - checksum
+
+	;; check for breakeven length between movem and normal word looping versions
+	;; we also do _NOT_ want to compute a checksum over more than the
+	;; actual length when length < 40
+
+	cmpu.w	80,$r11
+	blo	_word_loop
+	nop
+
+	;; need to save the registers we use below in the movem loop
+	;; this overhead is why we have a check above for breakeven length
+	;; only r0 - r8 have to be saved, the other ones are clobber-able
+	;; according to the ABI
+
+	subq	9*4,$sp
+	subq	10*4,$r11	; update length for the first loop
+	movem	$r8,[$sp]
+
+	;; do a movem checksum
+
+_mloop:	movem	[$r10+],$r9	; read 10 longwords
+
+	;; perform dword checksumming on the 10 longwords
+
+	add.d	$r0,$r12
+	addc	$r1,$r12
+	addc	$r2,$r12
+	addc	$r3,$r12
+	addc	$r4,$r12
+	addc	$r5,$r12
+	addc	$r6,$r12
+	addc	$r7,$r12
+	addc	$r8,$r12
+	addc	$r9,$r12
+
+	;; fold the carry into the checksum, to avoid having to loop the carry
+	;; back into the top
+
+	addc	0,$r12
+	addc	0,$r12		; do it again, since we might have generated a carry
+
+	subq	10*4,$r11
+	bge	_mloop
+	nop
+
+	addq	10*4,$r11	; compensate for last loop underflowing length
+
+	movem	[$sp+],$r8	; restore regs
+
+_word_loop:
+	;; only fold if there is anything to fold.
+
+	cmpq	0,$r12
+	beq	_no_fold
+
+	;; fold 32-bit checksum into a 16-bit checksum, to avoid carries below.
+	;; r9 and r13 can be used as temporaries.
+
+	moveq	-1,$r9		; put 0xffff in r9, faster than move.d 0xffff,r9
+	lsrq	16,$r9
+
+	move.d	$r12,$r13
+	lsrq	16,$r13		; r13 = checksum >> 16
+	and.d	$r9,$r12		; checksum = checksum & 0xffff
+	add.d	$r13,$r12		; checksum += r13
+	move.d	$r12,$r13		; do the same again, maybe we got a carry last add
+	lsrq	16,$r13
+	and.d	$r9,$r12
+	add.d	$r13,$r12
+
+_no_fold:
+	cmpq	2,$r11
+	blt	_no_words
+	nop
+
+	;; checksum the rest of the words
+
+	subq	2,$r11
+
+_wloop:	subq	2,$r11
+	bge	_wloop
+	addu.w	[$r10+],$r12
+
+	addq	2,$r11
+
+_no_words:
+	;; see if we have one odd byte more
+	cmpq	1,$r11
+	beq	_do_byte
+	nop
+	ret
+	move.d	$r12,$r10
+
+_do_byte:
+	;; copy and checksum the last byte
+	addu.b	[$r10],$r12
+	ret
+	move.d	$r12,$r10
diff --git a/arch/cris/arch-v32/lib/checksumcopy.S b/arch/cris/arch-v32/lib/checksumcopy.S
new file mode 100644
--- /dev/null
+++ b/arch/cris/arch-v32/lib/checksumcopy.S
@@ -0,0 +1,120 @@
+/*
+ * A fast checksum+copy routine using movem
+ * Copyright (c) 1998, 2001, 2003 Axis Communications AB
+ *
+ * Authors:	Bjorn Wesen
+ *
+ * csum_partial_copy_nocheck(const char *src, char *dst,
+ *		             int len, unsigned int sum)
+ */
+
+	.globl	csum_partial_copy_nocheck
+csum_partial_copy_nocheck:
+
+	;; r10 - src
+	;; r11 - dst
+	;; r12 - length
+	;; r13 - checksum
+
+	;; check for breakeven length between movem and normal word looping versions
+	;; we also do _NOT_ want to compute a checksum over more than the
+	;; actual length when length < 40
+
+	cmpu.w	80,$r12
+	blo	_word_loop
+	nop
+
+	;; need to save the registers we use below in the movem loop
+	;; this overhead is why we have a check above for breakeven length
+	;; only r0 - r8 have to be saved, the other ones are clobber-able
+	;; according to the ABI
+
+	subq	9*4,$sp
+	subq	10*4,$r12	; update length for the first loop
+	movem	$r8,[$sp]
+
+	;; do a movem copy and checksum
+
+1:	;; A failing userspace access (the read) will have this as PC.
+_mloop:	movem	[$r10+],$r9	; read 10 longwords
+	movem	$r9,[$r11+]	; write 10 longwords
+
+	;; perform dword checksumming on the 10 longwords
+
+	add.d	$r0,$r13
+	addc	$r1,$r13
+	addc	$r2,$r13
+	addc	$r3,$r13
+	addc	$r4,$r13
+	addc	$r5,$r13
+	addc	$r6,$r13
+	addc	$r7,$r13
+	addc	$r8,$r13
+	addc	$r9,$r13
+
+	;; fold the carry into the checksum, to avoid having to loop the carry
+	;; back into the top
+
+	addc	0,$r13
+	addc	0,$r13		; do it again, since we might have generated a carry
+
+	subq	10*4,$r12
+	bge	_mloop
+	nop
+
+	addq	10*4,$r12	; compensate for last loop underflowing length
+
+	movem	[$sp+],$r8	; restore regs
+
+_word_loop:
+	;; only fold if there is anything to fold.
+
+	cmpq	0,$r13
+	beq	_no_fold
+
+	;; fold 32-bit checksum into a 16-bit checksum, to avoid carries below
+	;; r9 can be used as temporary.
+
+	move.d	$r13,$r9
+	lsrq	16,$r9		; r0 = checksum >> 16
+	and.d	0xffff,$r13	; checksum = checksum & 0xffff
+	add.d	$r9,$r13	; checksum += r0
+	move.d	$r13,$r9	; do the same again, maybe we got a carry last add
+	lsrq	16,$r9
+	and.d	0xffff,$r13
+	add.d	$r9,$r13
+
+_no_fold:
+	cmpq	2,$r12
+	blt	_no_words
+	nop
+
+	;; copy and checksum the rest of the words
+
+	subq	2,$r12
+
+2:	;; A failing userspace access for the read below will have this as PC.
+_wloop:	move.w	[$r10+],$r9
+	addu.w	$r9,$r13
+	subq	2,$r12
+	bge	_wloop
+	move.w	$r9,[$r11+]
+
+	addq	2,$r12
+
+_no_words:
+	;; see if we have one odd byte more
+	cmpq	1,$r12
+	beq	_do_byte
+	nop
+	ret
+	move.d	$r13,$r10
+
+_do_byte:
+	;; copy and checksum the last byte
+3:	;; A failing userspace access for the read below will have this as PC.
+	move.b	[$r10],$r9
+	addu.b	$r9,$r13
+	move.b	$r9,[$r11]
+	ret
+	move.d	$r13,$r10
diff --git a/arch/cris/arch-v32/lib/csumcpfruser.S b/arch/cris/arch-v32/lib/csumcpfruser.S
new file mode 100644
--- /dev/null
+++ b/arch/cris/arch-v32/lib/csumcpfruser.S
@@ -0,0 +1,69 @@
+/*
+ * Add-on to transform csum_partial_copy_nocheck in checksumcopy.S into
+ * csum_partial_copy_from_user by adding exception records.
+ *
+ * Copyright (C) 2001, 2003 Axis Communications AB.
+ *
+ * Author: Hans-Peter Nilsson.
+ */
+
+#include <asm/errno.h>
+
+/* Same function body, but a different name.  If we just added exception
+   records to _csum_partial_copy_nocheck and made it generic, we wouldn't
+   know a user fault from a kernel fault and we would have overhead in
+   each kernel caller for the error-pointer argument.
+
+   unsigned int csum_partial_copy_from_user
+     (const char *src, char *dst, int len, unsigned int sum, int *errptr);
+
+   Note that the errptr argument is only set if we encounter an error.
+   It is conveniently located on the stack, so the normal function body
+   does not have to handle it.  */
+
+#define csum_partial_copy_nocheck csum_partial_copy_from_user
+
+/* There are local labels numbered 1, 2 and 3 present to mark the
+   different from-user accesses.  */
+#include "checksumcopy.S"
+
+	.section .fixup,"ax"
+
+;; Here from the movem loop; restore stack.
+4:
+	movem	[$sp+],$r8
+;; r12 is already decremented.  Add back chunk_size-2.
+	addq	40-2,$r12
+
+;; Here from the word loop; r12 is off by 2; add it back.
+5:
+	addq	2,$r12
+
+;; Here from a failing single byte.
+6:
+
+;; Signal in *errptr that we had a failing access.
+	move.d	[$sp],$acr
+	moveq	-EFAULT,$r9
+	subq	4,$sp
+	move.d	$r9,[$acr]
+
+;; Clear the rest of the destination area using memset.  Preserve the
+;; checksum for the readable bytes.
+	move.d	$r13,[$sp]
+	subq	4,$sp
+	move.d	$r11,$r10
+	move	$srp,[$sp]
+	jsr	memset
+	clear.d	$r11
+
+	move	[$sp+],$srp
+	ret
+	move.d	[$sp+],$r10
+
+	.previous
+	.section __ex_table,"a"
+	.dword 1b,4b
+	.dword 2b,5b
+	.dword 3b,6b
+	.previous
diff --git a/arch/cris/arch-v32/lib/dram_init.S b/arch/cris/arch-v32/lib/dram_init.S
new file mode 100644
--- /dev/null
+++ b/arch/cris/arch-v32/lib/dram_init.S
@@ -0,0 +1,120 @@
+/* $Id: dram_init.S,v 1.4 2005/04/24 18:48:32 starvik Exp $
+ *
+ * DRAM/SDRAM initialization - alter with care
+ * This file is intended to be included from other assembler files
+ *
+ * Note: This file may not modify r8 or r9 because they are used to
+ * carry information from the decompresser to the kernel
+ *
+ * Copyright (C) 2000-2003 Axis Communications AB
+ *
+ * Authors:  Mikael Starvik (starvik@axis.com)
+ */
+
+/* Just to be certain the config file is included, we include it here
+ * explicitely instead of depending on it being included in the file that
+ * uses this code.
+ */
+
+#include <linux/config.h>
+#include <asm/arch/hwregs/asm/reg_map_asm.h>
+#include <asm/arch/hwregs/asm/bif_core_defs_asm.h>
+
+	;; WARNING! The registers r8 and r9 are used as parameters carrying
+	;; information from the decompressor (if the kernel was compressed).
+	;; They should not be used in the code below.
+
+	; Refer to BIF MDS for a description of SDRAM initialization
+
+	; Bank configuration
+	move.d   REG_ADDR(bif_core, regi_bif_core, rw_sdram_cfg_grp0), $r0
+	move.d   CONFIG_ETRAX_SDRAM_GRP0_CONFIG, $r1
+	move.d   $r1, [$r0]
+	move.d   REG_ADDR(bif_core, regi_bif_core, rw_sdram_cfg_grp1), $r0
+	move.d   CONFIG_ETRAX_SDRAM_GRP1_CONFIG, $r1
+	move.d   $r1, [$r0]
+
+	; Calculate value of mrs_data
+	; CAS latency = 2 && bus_width = 32 => 0x40
+	; CAS latency = 3 && bus_width = 32 => 0x60
+	; CAS latency = 2 && bus_width = 16 => 0x20
+	; CAS latency = 3 && bus_width = 16 => 0x30
+
+	; Check if value is already supplied in kernel config
+	move.d   CONFIG_ETRAX_SDRAM_COMMAND, $r2
+	bne	 _set_timing
+	nop
+
+	move.d   0x40, $r4       ; Assume 32 bits and CAS latency = 2
+	move.d   CONFIG_ETRAX_SDRAM_TIMING, $r1
+ 	and.d    0x07, $r1       ; Get CAS latency
+	cmpq	 2, $r1		 ; CL = 2 ?
+	beq	 _bw_check
+	nop
+	move.d   0x60, $r4
+
+_bw_check:
+	; Assume that group 0 width is equal to group 1. This assumption
+	; is wrong for a group 1 only hardware (such as the grand old
+	; StorPoint+).
+	move.d   CONFIG_ETRAX_SDRAM_GRP0_CONFIG, $r1
+	and.d    0x200, $r1	; DRAM width is bit 9
+	beq      _set_timing
+	lslq	 2, $r4		;  mrs_data starts at bit 2
+	lsrq     1, $r4		;  16 bits. Shift down value.
+
+	; Set timing parameters (refresh off to avoid Guinness TR 83)
+_set_timing:
+	move.d   CONFIG_ETRAX_SDRAM_TIMING, $r1
+	and.d    ~(3 << reg_bif_core_rw_sdram_timing___ref___lsb), $r1
+	move.d   REG_ADDR(bif_core, regi_bif_core, rw_sdram_timing), $r0
+	move.d   $r1, [$r0]
+
+	; Issue NOP command
+	move.d REG_ADDR(bif_core, regi_bif_core, rw_sdram_cmd), $r5
+	moveq regk_bif_core_nop, $r1
+	move.d $r1, [$r5]
+
+	; Wait 200us
+	move.d   10000, $r2
+1:	bne      1b
+	subq     1, $r2
+
+	; Issue initialization command sequence
+	move.d   _sdram_commands_start, $r2
+	and.d    0x000fffff, $r2 ; Make sure commands are read from flash
+	move.d   _sdram_commands_end,  $r3
+	and.d    0x000fffff, $r3
+1:	clear.d  $r6
+	move.b   [$r2+], $r6 	; Load command
+	or.d     $r4, $r6	; Add calculated mrs
+	move.d   $r6, [$r5]	; Write rw_sdram_cmd
+	; Wait 80 ns between each command
+	move.d	 4000, $r7
+2:	bne	 2b
+	subq	 1, $r7
+	cmp.d    $r2, $r3	; Last command?
+	bne      1b
+	nop
+
+	; Start refresh
+	move.d   CONFIG_ETRAX_SDRAM_TIMING, $r1
+	move.d   REG_ADDR(bif_core, regi_bif_core, rw_sdram_timing), $r0
+	move.d   $r1, [$r0]
+
+	; Initialization finished
+	ba       _sdram_commands_end
+	nop
+
+_sdram_commands_start:
+	.byte   regk_bif_core_pre ; Precharge
+	.byte   regk_bif_core_ref ; refresh
+	.byte   regk_bif_core_ref ; refresh
+	.byte   regk_bif_core_ref ; refresh
+	.byte   regk_bif_core_ref ; refresh
+	.byte   regk_bif_core_ref ; refresh
+	.byte   regk_bif_core_ref ; refresh
+	.byte   regk_bif_core_ref ; refresh
+	.byte   regk_bif_core_ref ; refresh
+	.byte   regk_bif_core_mrs ; mrs
+_sdram_commands_end:
diff --git a/arch/cris/arch-v32/lib/hw_settings.S b/arch/cris/arch-v32/lib/hw_settings.S
new file mode 100644
--- /dev/null
+++ b/arch/cris/arch-v32/lib/hw_settings.S
@@ -0,0 +1,73 @@
+/*
+ * $Id: hw_settings.S,v 1.3 2005/04/24 18:36:57 starvik Exp $
+ *
+ * This table is used by some tools to extract hardware parameters.
+ * The table should be included in the kernel and the decompressor.
+ * Don't forget to update the tools if you change this table.
+ *
+ * Copyright (C) 2001 Axis Communications AB
+ *
+ * Authors:  Mikael Starvik (starvik@axis.com)
+ */
+
+#include <linux/config.h>
+#include <asm/arch/hwregs/asm/reg_map_asm.h>
+#include <asm/arch/hwregs/asm/bif_core_defs_asm.h>
+#include <asm/arch/hwregs/asm/gio_defs_asm.h>
+
+	.ascii "HW_PARAM_MAGIC" ; Magic number
+	.dword 0xc0004000	; Kernel start address
+
+	; Debug port
+#ifdef CONFIG_ETRAX_DEBUG_PORT0
+	.dword 0
+#elif defined(CONFIG_ETRAX_DEBUG_PORT1)
+	.dword 1
+#elif defined(CONFIG_ETRAX_DEBUG_PORT2)
+	.dword 2
+#elif defined(CONFIG_ETRAX_DEBUG_PORT3)
+	.dword 3
+#else
+	.dword 4 ; No debug
+#endif
+
+	; Register values
+	.dword REG_ADDR(bif_core, regi_bif_core, rw_grp1_cfg)
+	.dword CONFIG_ETRAX_MEM_GRP1_CONFIG
+	.dword REG_ADDR(bif_core, regi_bif_core, rw_grp2_cfg)
+	.dword CONFIG_ETRAX_MEM_GRP2_CONFIG
+	.dword REG_ADDR(bif_core, regi_bif_core, rw_grp3_cfg)
+	.dword CONFIG_ETRAX_MEM_GRP3_CONFIG
+	.dword REG_ADDR(bif_core, regi_bif_core, rw_grp4_cfg)
+	.dword CONFIG_ETRAX_MEM_GRP4_CONFIG
+	.dword REG_ADDR(bif_core, regi_bif_core, rw_sdram_cfg_grp0)
+	.dword CONFIG_ETRAX_SDRAM_GRP0_CONFIG
+	.dword REG_ADDR(bif_core, regi_bif_core, rw_sdram_cfg_grp1)
+	.dword CONFIG_ETRAX_SDRAM_GRP1_CONFIG
+	.dword REG_ADDR(bif_core, regi_bif_core, rw_sdram_timing)
+	.dword CONFIG_ETRAX_SDRAM_TIMING
+	.dword REG_ADDR(bif_core, regi_bif_core, rw_sdram_cmd)
+	.dword CONFIG_ETRAX_SDRAM_COMMAND
+
+	.dword REG_ADDR(gio, regi_gio, rw_pa_dout)
+	.dword CONFIG_ETRAX_DEF_GIO_PA_OUT
+	.dword REG_ADDR(gio, regi_gio, rw_pa_oe)
+	.dword CONFIG_ETRAX_DEF_GIO_PA_OE
+	.dword REG_ADDR(gio, regi_gio, rw_pb_dout)
+	.dword CONFIG_ETRAX_DEF_GIO_PB_OUT
+	.dword REG_ADDR(gio, regi_gio, rw_pb_oe)
+	.dword CONFIG_ETRAX_DEF_GIO_PB_OE
+	.dword REG_ADDR(gio, regi_gio, rw_pc_dout)
+	.dword CONFIG_ETRAX_DEF_GIO_PC_OUT
+	.dword REG_ADDR(gio, regi_gio, rw_pc_oe)
+	.dword CONFIG_ETRAX_DEF_GIO_PC_OE
+	.dword REG_ADDR(gio, regi_gio, rw_pd_dout)
+	.dword CONFIG_ETRAX_DEF_GIO_PD_OUT
+	.dword REG_ADDR(gio, regi_gio, rw_pd_oe)
+	.dword CONFIG_ETRAX_DEF_GIO_PD_OE
+	.dword REG_ADDR(gio, regi_gio, rw_pe_dout)
+	.dword CONFIG_ETRAX_DEF_GIO_PE_OUT
+	.dword REG_ADDR(gio, regi_gio, rw_pe_oe)
+	.dword CONFIG_ETRAX_DEF_GIO_PE_OE
+
+	.dword 0 ; No more register values
diff --git a/arch/cris/arch-v32/lib/memset.c b/arch/cris/arch-v32/lib/memset.c
new file mode 100644
--- /dev/null
+++ b/arch/cris/arch-v32/lib/memset.c
@@ -0,0 +1,253 @@
+/*#************************************************************************#*/
+/*#-------------------------------------------------------------------------*/
+/*#                                                                         */
+/*# FUNCTION NAME: memset()                                                 */
+/*#                                                                         */
+/*# PARAMETERS:  void* dst;   Destination address.                          */
+/*#              int     c;   Value of byte to write.                       */
+/*#              int   len;   Number of bytes to write.                     */
+/*#                                                                         */
+/*# RETURNS:     dst.                                                       */
+/*#                                                                         */
+/*# DESCRIPTION: Sets the memory dst of length len bytes to c, as standard. */
+/*#              Framework taken from memcpy.  This routine is              */
+/*#              very sensitive to compiler changes in register allocation. */
+/*#              Should really be rewritten to avoid this problem.          */
+/*#                                                                         */
+/*#-------------------------------------------------------------------------*/
+/*#                                                                         */
+/*# HISTORY                                                                 */
+/*#                                                                         */
+/*# DATE      NAME            CHANGES                                       */
+/*# ----      ----            -------                                       */
+/*# 990713    HP              Tired of watching this function (or           */
+/*#                           really, the nonoptimized generic              */
+/*#                           implementation) take up 90% of simulator      */
+/*#                           output.  Measurements needed.                 */
+/*#                                                                         */
+/*#-------------------------------------------------------------------------*/
+
+#include <linux/types.h>
+
+/* No, there's no macro saying 12*4, since it is "hard" to get it into
+   the asm in a good way.  Thus better to expose the problem everywhere.
+   */
+
+/* Assuming 1 cycle per dword written or read (ok, not really true), and
+   one per instruction, then 43+3*(n/48-1) <= 24+24*(n/48-1)
+   so n >= 45.7; n >= 0.9; we win on the first full 48-byte block to set. */
+
+#define ZERO_BLOCK_SIZE (1*12*4)
+
+void *memset(void *pdst,
+             int c,
+             size_t plen)
+{
+  /* Ok.  Now we want the parameters put in special registers.
+     Make sure the compiler is able to make something useful of this. */
+
+  register char *return_dst __asm__ ("r10") = pdst;
+  register int n __asm__ ("r12") = plen;
+  register int lc __asm__ ("r11") = c;
+
+  /* Most apps use memset sanely.  Only those memsetting about 3..4
+     bytes or less get penalized compared to the generic implementation
+     - and that's not really sane use. */
+
+  /* Ugh.  This is fragile at best.  Check with newer GCC releases, if
+     they compile cascaded "x |= x << 8" sanely! */
+  __asm__("movu.b %0,$r13	\n\
+           lslq 8,$r13		\n\
+	   move.b %0,$r13	\n\
+	   move.d $r13,%0	\n\
+	   lslq 16,$r13		\n\
+	   or.d $r13,%0"
+          : "=r" (lc) : "0" (lc) : "r13");
+
+  {
+    register char *dst __asm__ ("r13") = pdst;
+
+  /* This is NONPORTABLE, but since this whole routine is     */
+  /* grossly nonportable that doesn't matter.                 */
+
+  if (((unsigned long) pdst & 3) != 0
+     /* Oops! n=0 must be a legal call, regardless of alignment. */
+      && n >= 3)
+  {
+    if ((unsigned long)dst & 1)
+    {
+      *dst = (char) lc;
+      n--;
+      dst++;
+    }
+
+    if ((unsigned long)dst & 2)
+    {
+      *(short *)dst = lc;
+      n -= 2;
+      dst += 2;
+    }
+  }
+
+  /* Now the fun part.  For the threshold value of this, check the equation
+     above. */
+  /* Decide which copying method to use. */
+  if (n >= ZERO_BLOCK_SIZE)
+  {
+    /* For large copies we use 'movem' */
+
+  /* It is not optimal to tell the compiler about clobbering any
+     registers; that will move the saving/restoring of those registers
+     to the function prologue/epilogue, and make non-movem sizes
+     suboptimal.
+
+      This method is not foolproof; it assumes that the "asm reg"
+     declarations at the beginning of the function really are used
+     here (beware: they may be moved to temporary registers).
+      This way, we do not have to save/move the registers around into
+     temporaries; we can safely use them straight away.
+
+      If you want to check that the allocation was right; then
+      check the equalities in the first comment.  It should say
+      "r13=r13, r12=r12, r11=r11" */
+    __asm__ volatile ("							\n\
+        ;; Check that the register asm declaration got right.		\n\
+        ;; The GCC manual says it will work, but there *has* been bugs.	\n\
+	.ifnc %0-%1-%4,$r13-$r12-$r11					\n\
+	.err								\n\
+	.endif								\n\
+									\n\
+	;; Save the registers we'll clobber in the movem process	\n\
+	;; on the stack.  Don't mention them to gcc, it will only be	\n\
+	;; upset.							\n\
+	subq 	11*4,$sp						\n\
+        movem   $r10,[$sp]						\n\
+									\n\
+        move.d  $r11,$r0						\n\
+        move.d  $r11,$r1						\n\
+        move.d  $r11,$r2						\n\
+        move.d  $r11,$r3						\n\
+        move.d  $r11,$r4						\n\
+        move.d  $r11,$r5						\n\
+        move.d  $r11,$r6						\n\
+        move.d  $r11,$r7						\n\
+        move.d  $r11,$r8						\n\
+        move.d  $r11,$r9						\n\
+        move.d  $r11,$r10						\n\
+									\n\
+        ;; Now we've got this:						\n\
+	;; r13 - dst							\n\
+	;; r12 - n							\n\
+									\n\
+        ;; Update n for the first loop					\n\
+        subq    12*4,$r12						\n\
+0:									\n\
+        subq   12*4,$r12						\n\
+        bge     0b							\n\
+	movem	$r11,[$r13+]						\n\
+									\n\
+        addq   12*4,$r12  ;; compensate for last loop underflowing n	\n\
+									\n\
+	;; Restore registers from stack					\n\
+        movem [$sp+],$r10"
+
+     /* Outputs */ : "=r" (dst), "=r" (n)
+     /* Inputs */ : "0" (dst), "1" (n), "r" (lc));
+  }
+
+    /* Either we directly starts copying, using dword copying
+       in a loop, or we copy as much as possible with 'movem'
+       and then the last block (<44 bytes) is copied here.
+       This will work since 'movem' will have updated src,dst,n. */
+
+    while ( n >= 16 )
+    {
+      *((long*)dst)++ = lc;
+      *((long*)dst)++ = lc;
+      *((long*)dst)++ = lc;
+      *((long*)dst)++ = lc;
+      n -= 16;
+    }
+
+    /* A switch() is definitely the fastest although it takes a LOT of code.
+     * Particularly if you inline code this.
+     */
+    switch (n)
+    {
+      case 0:
+        break;
+      case 1:
+        *(char*)dst = (char) lc;
+        break;
+      case 2:
+        *(short*)dst = (short) lc;
+        break;
+      case 3:
+        *((short*)dst)++ = (short) lc;
+        *(char*)dst = (char) lc;
+        break;
+      case 4:
+        *((long*)dst)++ = lc;
+        break;
+      case 5:
+        *((long*)dst)++ = lc;
+        *(char*)dst = (char) lc;
+        break;
+      case 6:
+        *((long*)dst)++ = lc;
+        *(short*)dst = (short) lc;
+        break;
+      case 7:
+        *((long*)dst)++ = lc;
+        *((short*)dst)++ = (short) lc;
+        *(char*)dst = (char) lc;
+        break;
+      case 8:
+        *((long*)dst)++ = lc;
+        *((long*)dst)++ = lc;
+        break;
+      case 9:
+        *((long*)dst)++ = lc;
+        *((long*)dst)++ = lc;
+        *(char*)dst = (char) lc;
+        break;
+      case 10:
+        *((long*)dst)++ = lc;
+        *((long*)dst)++ = lc;
+        *(short*)dst = (short) lc;
+        break;
+      case 11:
+        *((long*)dst)++ = lc;
+        *((long*)dst)++ = lc;
+        *((short*)dst)++ = (short) lc;
+        *(char*)dst = (char) lc;
+        break;
+      case 12:
+        *((long*)dst)++ = lc;
+        *((long*)dst)++ = lc;
+        *((long*)dst)++ = lc;
+        break;
+      case 13:
+        *((long*)dst)++ = lc;
+        *((long*)dst)++ = lc;
+        *((long*)dst)++ = lc;
+        *(char*)dst = (char) lc;
+        break;
+      case 14:
+        *((long*)dst)++ = lc;
+        *((long*)dst)++ = lc;
+        *((long*)dst)++ = lc;
+        *(short*)dst = (short) lc;
+        break;
+      case 15:
+        *((long*)dst)++ = lc;
+        *((long*)dst)++ = lc;
+        *((long*)dst)++ = lc;
+        *((short*)dst)++ = (short) lc;
+        *(char*)dst = (char) lc;
+        break;
+    }
+  }
+
+  return return_dst; /* destination pointer. */
+} /* memset() */
diff --git a/arch/cris/arch-v32/lib/nand_init.S b/arch/cris/arch-v32/lib/nand_init.S
new file mode 100644
--- /dev/null
+++ b/arch/cris/arch-v32/lib/nand_init.S
@@ -0,0 +1,179 @@
+##=============================================================================
+##
+##      nand_init.S
+##
+##      The bootrom copies data from the NAND flash to the internal RAM but
+##      due to a bug/feature we can only trust the 256 first bytes. So this
+##      code copies more data from NAND flash to internal RAM. Obvioulsy this
+##      code must fit in the first 256 bytes so alter with care.
+##
+##	Some notes about the bug/feature for future reference:
+##        The bootrom copies the first 127 KB from NAND flash to internal
+##        memory. The problem is that it does a bytewise copy. NAND flashes
+##        does autoincrement on the address so for a 16-bite device each
+##        read/write increases the address by two. So the copy loop in the
+##        bootrom will discard every second byte. This is solved by inserting
+##        zeroes in every second byte in the first erase block.
+##
+##        The bootrom also incorrectly assumes that it can read the flash
+##        linear with only one read command but the flash will actually
+##        switch between normal area and spare area if you do that so we
+##        can't trust more than the first 256 bytes.
+##
+##=============================================================================
+
+#include <asm/arch/hwregs/asm/reg_map_asm.h>
+#include <asm/arch/hwregs/asm/gio_defs_asm.h>
+#include <asm/arch/hwregs/asm/pinmux_defs_asm.h>
+#include <asm/arch/hwregs/asm/bif_core_defs_asm.h>
+#include <asm/arch/hwregs/asm/config_defs_asm.h>
+#include <linux/config.h>
+
+;; There are 8-bit NAND flashes and 16-bit NAND flashes.
+;; We need to treat them slightly different.
+#if CONFIG_ETRAX_FLASH_BUSWIDTH==2
+#define PAGE_SIZE 256
+#else
+#error 2
+#define PAGE_SIZE 512
+#endif
+#define ERASE_BLOCK 16384
+
+;; GPIO pins connected to NAND flash
+#define CE 4
+#define CLE 5
+#define ALE 6
+#define BY 7
+
+;; Address space for NAND flash
+#define NAND_RD_ADDR 0x90000000
+#define NAND_WR_ADDR 0x94000000
+
+#define READ_CMD 0x00
+
+;; Readability macros
+#define CSP_MASK \
+	REG_MASK(bif_core, rw_grp3_cfg, gated_csp0) | \
+	REG_MASK(bif_core, rw_grp3_cfg, gated_csp1)
+#define CSP_VAL \
+	REG_STATE(bif_core, rw_grp3_cfg, gated_csp0, rd) | \
+	REG_STATE(bif_core, rw_grp3_cfg, gated_csp1, wr)
+
+;;----------------------------------------------------------------------------
+;; Macros to set/clear GPIO bits
+
+.macro SET x
+	or.b   (1<<\x),$r9
+	move.d $r9, [$r2]
+.endm
+
+.macro CLR x
+	and.b  ~(1<<\x),$r9
+	move.d $r9, [$r2]
+.endm
+
+;;----------------------------------------------------------------------------
+
+nand_boot:
+	;; Check if nand boot was selected
+	move.d REG_ADDR(config, regi_config, r_bootsel), $r0
+	move.d [$r0], $r0
+	and.d  REG_MASK(config, r_bootsel, boot_mode), $r0
+	cmp.d  REG_STATE(config, r_bootsel, boot_mode, nand), $r0
+	bne normal_boot ; No NAND boot
+	nop
+
+copy_nand_to_ram:
+	;; copy_nand_to_ram
+	;; Arguments
+	;;   r10 - destination
+	;;   r11 - source offset
+	;;   r12 - size
+	;;   r13 - Address to jump to after completion
+	;; Note : r10-r12 are clobbered on return
+	;; Registers used:
+	;;   r0 - NAND_RD_ADDR
+	;;   r1 - NAND_WR_ADDR
+	;;   r2 - reg_gio_rw_pa_dout
+	;;   r3 - reg_gio_r_pa_din
+	;;   r4 - tmp
+	;;   r5 - byte counter within a page
+	;;   r6 - reg_pinmux_rw_pa
+	;;   r7 - reg_gio_rw_pa_oe
+	;;   r8 - reg_bif_core_rw_grp3_cfg
+	;;   r9 - reg_gio_rw_pa_dout shadow
+	move.d 0x90000000, $r0
+	move.d 0x94000000, $r1
+	move.d REG_ADDR(gio, regi_gio, rw_pa_dout), $r2
+	move.d REG_ADDR(gio, regi_gio, r_pa_din), $r3
+	move.d REG_ADDR(pinmux, regi_pinmux, rw_pa), $r6
+	move.d REG_ADDR(gio, regi_gio, rw_pa_oe), $r7
+	move.d REG_ADDR(bif_core, regi_bif_core, rw_grp3_cfg), $r8
+
+#if CONFIG_ETRAX_FLASH_BUSWIDTH==2
+	lsrq	1, $r11
+#endif
+	;; Set up GPIO
+	move.d [$r2], $r9
+	move.d [$r7], $r4
+	or.b (1<<ALE) | (1 << CLE) | (1<<CE), $r4
+	move.d $r4, [$r7]
+
+	;; Set up bif
+	move.d [$r8], $r4
+	and.d CSP_MASK, $r4
+	or.d CSP_VAL, $r4
+	move.d $r4, [$r8]
+
+1:	;; Copy one page
+	CLR CE
+	SET CLE
+	moveq	READ_CMD, $r4
+	move.b	$r4, [$r1]
+	moveq	20, $r4
+2:	bne	2b
+	subq	1, $r4
+	CLR CLE
+	SET ALE
+	clear.w [$r1] 		; Column address = 0
+	move.d	$r11, $r4
+	lsrq	8, $r4
+	move.b	$r4, [$r1]	; Row address
+	lsrq	8, $r4
+	move.b	$r4, [$r1]	; Row adddress
+	moveq	20, $r4
+2:	bne	2b
+	subq	1, $r4
+	CLR ALE
+2:	move.d	[$r3], $r4
+	and.d	1 << BY, $r4
+	beq 2b
+	movu.w  PAGE_SIZE, $r5
+2:	; Copy one byte/word
+#if CONFIG_ETRAX_FLASH_BUSWIDTH==2
+	move.w  [$r0], $r4
+#else
+	move.b  [$r0], $r4
+#endif
+	subq	1, $r5
+	bne	2b
+#if CONFIG_ETRAX_FLASH_BUSWIDTH==2
+	move.w  $r4, [$r10+]
+	subu.w	PAGE_SIZE*2, $r12
+#else
+	move.b  $r4, [$r10+]
+	subu.w	PAGE_SIZE, $r12
+#endif
+	bpl	1b
+	addu.w	PAGE_SIZE, $r11
+
+	;; End of copy
+	jump	$r13
+	nop
+
+	;; This will warn if the code above is too large. If you consider
+	;; to remove this you don't understand the bug/feature.
+	.org 256
+	.org ERASE_BLOCK
+
+normal_boot:
diff --git a/arch/cris/arch-v32/lib/spinlock.S b/arch/cris/arch-v32/lib/spinlock.S
new file mode 100644
--- /dev/null
+++ b/arch/cris/arch-v32/lib/spinlock.S
@@ -0,0 +1,33 @@
+;; Core of the spinlock implementation
+;;
+;; Copyright (C) 2004 Axis Communications AB.
+;;
+;; Author: Mikael Starvik
+
+
+	.global cris_spin_lock
+	.global cris_spin_trylock
+
+	.text
+
+cris_spin_lock:
+	clearf	p
+1:	test.d	[$r10]
+	beq	1b
+	clearf	p
+	ax
+	clear.d [$r10]
+	bcs     1b
+	clearf	p
+	ret
+	nop
+
+cris_spin_trylock:
+	clearf	p
+1:	move.d	[$r10], $r11
+	ax
+	clear.d [$r10]
+        bcs	1b
+        clearf	p
+	ret
+	move.d	$r11,$r10
diff --git a/arch/cris/arch-v32/lib/string.c b/arch/cris/arch-v32/lib/string.c
new file mode 100644
--- /dev/null
+++ b/arch/cris/arch-v32/lib/string.c
@@ -0,0 +1,219 @@
+/*#************************************************************************#*/
+/*#-------------------------------------------------------------------------*/
+/*#                                                                         */
+/*# FUNCTION NAME: memcpy()                                                 */
+/*#                                                                         */
+/*# PARAMETERS:  void* dst;   Destination address.                          */
+/*#              void* src;   Source address.                               */
+/*#              int   len;   Number of bytes to copy.                      */
+/*#                                                                         */
+/*# RETURNS:     dst.                                                       */
+/*#                                                                         */
+/*# DESCRIPTION: Copies len bytes of memory from src to dst.  No guarantees */
+/*#              about copying of overlapping memory areas. This routine is */
+/*#              very sensitive to compiler changes in register allocation. */
+/*#              Should really be rewritten to avoid this problem.          */
+/*#                                                                         */
+/*#-------------------------------------------------------------------------*/
+/*#                                                                         */
+/*# HISTORY                                                                 */
+/*#                                                                         */
+/*# DATE      NAME            CHANGES                                       */
+/*# ----      ----            -------                                       */
+/*# 941007    Kenny R         Creation                                      */
+/*# 941011    Kenny R         Lots of optimizations and inlining.           */
+/*# 941129    Ulf A           Adapted for use in libc.                      */
+/*# 950216    HP              N==0 forgotten if non-aligned src/dst.        */
+/*#                           Added some optimizations.                     */
+/*# 001025    HP              Make src and dst char *.  Align dst to	    */
+/*#			      dword, not just word-if-both-src-and-dst-	    */
+/*#			      are-misaligned.				    */
+/*#                                                                         */
+/*#-------------------------------------------------------------------------*/
+
+#include <linux/types.h>
+
+void *memcpy(void *pdst,
+             const void *psrc,
+             size_t pn)
+{
+  /* Ok.  Now we want the parameters put in special registers.
+     Make sure the compiler is able to make something useful of this.
+      As it is now: r10 -> r13; r11 -> r11 (nop); r12 -> r12 (nop).
+
+     If gcc was allright, it really would need no temporaries, and no
+     stack space to save stuff on. */
+
+  register void *return_dst __asm__ ("r10") = pdst;
+  register char *dst __asm__ ("r13") = pdst;
+  register const char *src __asm__ ("r11") = psrc;
+  register int n __asm__ ("r12") = pn;
+
+
+  /* When src is aligned but not dst, this makes a few extra needless
+     cycles.  I believe it would take as many to check that the
+     re-alignment was unnecessary.  */
+  if (((unsigned long) dst & 3) != 0
+      /* Don't align if we wouldn't copy more than a few bytes; so we
+	 don't have to check further for overflows.  */
+      && n >= 3)
+  {
+    if ((unsigned long) dst & 1)
+    {
+      n--;
+      *(char*)dst = *(char*)src;
+      src++;
+      dst++;
+    }
+
+    if ((unsigned long) dst & 2)
+    {
+      n -= 2;
+      *(short*)dst = *(short*)src;
+      src += 2;
+      dst += 2;
+    }
+  }
+
+  /* Decide which copying method to use.  Movem is dirt cheap, so the
+     overheap is low enough to always use the minimum block size as the
+     threshold.  */
+  if (n >= 44)
+  {
+    /* For large copies we use 'movem' */
+
+  /* It is not optimal to tell the compiler about clobbering any
+     registers; that will move the saving/restoring of those registers
+     to the function prologue/epilogue, and make non-movem sizes
+     suboptimal.  */
+    __asm__ volatile ("							\n\
+        ;; Check that the register asm declaration got right.		\n\
+        ;; The GCC manual explicitly says TRT will happen.		\n\
+	.ifnc %0-%1-%2,$r13-$r11-$r12					\n\
+	.err								\n\
+	.endif								\n\
+									\n\
+	;; Save the registers we'll use in the movem process		\n\
+									\n\
+	;; on the stack.						\n\
+	subq 	11*4,$sp						\n\
+	movem	$r10,[$sp]						\n\
+									\n\
+        ;; Now we've got this:						\n\
+	;; r11 - src							\n\
+	;; r13 - dst							\n\
+	;; r12 - n							\n\
+									\n\
+        ;; Update n for the first loop					\n\
+        subq    44,$r12							\n\
+0:									\n\
+	movem	[$r11+],$r10						\n\
+        subq   44,$r12							\n\
+        bge     0b							\n\
+	movem	$r10,[$r13+]						\n\
+									\n\
+        addq   44,$r12  ;; compensate for last loop underflowing n	\n\
+									\n\
+	;; Restore registers from stack					\n\
+        movem [$sp+],$r10"
+
+     /* Outputs */ : "=r" (dst), "=r" (src), "=r" (n)
+     /* Inputs */ : "0" (dst), "1" (src), "2" (n));
+
+  }
+
+  /* Either we directly starts copying, using dword copying
+     in a loop, or we copy as much as possible with 'movem'
+     and then the last block (<44 bytes) is copied here.
+     This will work since 'movem' will have updated src,dst,n. */
+
+  while ( n >= 16 )
+  {
+    *((long*)dst)++ = *((long*)src)++;
+    *((long*)dst)++ = *((long*)src)++;
+    *((long*)dst)++ = *((long*)src)++;
+    *((long*)dst)++ = *((long*)src)++;
+    n -= 16;
+  }
+
+  /* A switch() is definitely the fastest although it takes a LOT of code.
+   * Particularly if you inline code this.
+   */
+  switch (n)
+  {
+    case 0:
+      break;
+    case 1:
+      *(char*)dst = *(char*)src;
+      break;
+    case 2:
+      *(short*)dst = *(short*)src;
+      break;
+    case 3:
+      *((short*)dst)++ = *((short*)src)++;
+      *(char*)dst = *(char*)src;
+      break;
+    case 4:
+      *((long*)dst)++ = *((long*)src)++;
+      break;
+    case 5:
+      *((long*)dst)++ = *((long*)src)++;
+      *(char*)dst = *(char*)src;
+      break;
+    case 6:
+      *((long*)dst)++ = *((long*)src)++;
+      *(short*)dst = *(short*)src;
+      break;
+    case 7:
+      *((long*)dst)++ = *((long*)src)++;
+      *((short*)dst)++ = *((short*)src)++;
+      *(char*)dst = *(char*)src;
+      break;
+    case 8:
+      *((long*)dst)++ = *((long*)src)++;
+      *((long*)dst)++ = *((long*)src)++;
+      break;
+    case 9:
+      *((long*)dst)++ = *((long*)src)++;
+      *((long*)dst)++ = *((long*)src)++;
+      *(char*)dst = *(char*)src;
+      break;
+    case 10:
+      *((long*)dst)++ = *((long*)src)++;
+      *((long*)dst)++ = *((long*)src)++;
+      *(short*)dst = *(short*)src;
+      break;
+    case 11:
+      *((long*)dst)++ = *((long*)src)++;
+      *((long*)dst)++ = *((long*)src)++;
+      *((short*)dst)++ = *((short*)src)++;
+      *(char*)dst = *(char*)src;
+      break;
+    case 12:
+      *((long*)dst)++ = *((long*)src)++;
+      *((long*)dst)++ = *((long*)src)++;
+      *((long*)dst)++ = *((long*)src)++;
+      break;
+    case 13:
+      *((long*)dst)++ = *((long*)src)++;
+      *((long*)dst)++ = *((long*)src)++;
+      *((long*)dst)++ = *((long*)src)++;
+      *(char*)dst = *(char*)src;
+      break;
+    case 14:
+      *((long*)dst)++ = *((long*)src)++;
+      *((long*)dst)++ = *((long*)src)++;
+      *((long*)dst)++ = *((long*)src)++;
+      *(short*)dst = *(short*)src;
+      break;
+    case 15:
+      *((long*)dst)++ = *((long*)src)++;
+      *((long*)dst)++ = *((long*)src)++;
+      *((long*)dst)++ = *((long*)src)++;
+      *((short*)dst)++ = *((short*)src)++;
+      *(char*)dst = *(char*)src;
+      break;
+  }
+
+  return return_dst; /* destination pointer. */
+} /* memcpy() */
diff --git a/arch/cris/arch-v32/lib/usercopy.c b/arch/cris/arch-v32/lib/usercopy.c
new file mode 100644
--- /dev/null
+++ b/arch/cris/arch-v32/lib/usercopy.c
@@ -0,0 +1,470 @@
+/*
+ * User address space access functions.
+ * The non-inlined parts of asm-cris/uaccess.h are here.
+ *
+ * Copyright (C) 2000, 2003 Axis Communications AB.
+ *
+ * Written by Hans-Peter Nilsson.
+ * Pieces used from memcpy, originally by Kenny Ranerup long time ago.
+ */
+
+#include <asm/uaccess.h>
+
+/* Asm:s have been tweaked (within the domain of correctness) to give
+   satisfactory results for "gcc version 3.2.1 Axis release R53/1.53-v32".
+
+   Check regularly...
+
+   Note that for CRISv32, the PC saved at a bus-fault is the address
+   *at* the faulting instruction, with a special case for instructions
+   in delay slots: then it's the address of the branch.  Note also that
+   in contrast to v10, a postincrement in the instruction is *not*
+   performed at a bus-fault; the register is seen having the original
+   value in fault handlers.  */
+
+
+/* Copy to userspace.  This is based on the memcpy used for
+   kernel-to-kernel copying; see "string.c".  */
+
+unsigned long
+__copy_user (void __user *pdst, const void *psrc, unsigned long pn)
+{
+  /* We want the parameters put in special registers.
+     Make sure the compiler is able to make something useful of this.
+     As it is now: r10 -> r13; r11 -> r11 (nop); r12 -> r12 (nop).
+
+     FIXME: Comment for old gcc version.  Check.
+     If gcc was allright, it really would need no temporaries, and no
+     stack space to save stuff on. */
+
+  register char *dst __asm__ ("r13") = pdst;
+  register const char *src __asm__ ("r11") = psrc;
+  register int n __asm__ ("r12") = pn;
+  register int retn __asm__ ("r10") = 0;
+
+
+  /* When src is aligned but not dst, this makes a few extra needless
+     cycles.  I believe it would take as many to check that the
+     re-alignment was unnecessary.  */
+  if (((unsigned long) dst & 3) != 0
+      /* Don't align if we wouldn't copy more than a few bytes; so we
+	 don't have to check further for overflows.  */
+      && n >= 3)
+  {
+    if ((unsigned long) dst & 1)
+    {
+      __asm_copy_to_user_1 (dst, src, retn);
+      n--;
+    }
+
+    if ((unsigned long) dst & 2)
+    {
+      __asm_copy_to_user_2 (dst, src, retn);
+      n -= 2;
+    }
+  }
+
+  /* Movem is dirt cheap.  The overheap is low enough to always use the
+     minimum possible block size as the threshold.  */
+  if (n >= 44)
+  {
+    /* For large copies we use 'movem'.  */
+
+    /* It is not optimal to tell the compiler about clobbering any
+       registers; that will move the saving/restoring of those registers
+       to the function prologue/epilogue, and make non-movem sizes
+       suboptimal.  */
+    __asm__ volatile ("\
+        ;; Check that the register asm declaration got right.		\n\
+        ;; The GCC manual explicitly says TRT will happen.		\n\
+	.ifnc %0%1%2%3,$r13$r11$r12$r10					\n\
+	.err								\n\
+	.endif								\n\
+									\n\
+	;; Save the registers we'll use in the movem process		\n\
+	;; on the stack.						\n\
+	subq	11*4,$sp						\n\
+	movem	$r10,[$sp]						\n\
+									\n\
+	;; Now we've got this:						\n\
+	;; r11 - src							\n\
+	;; r13 - dst							\n\
+	;; r12 - n							\n\
+									\n\
+	;; Update n for the first loop					\n\
+	subq	44,$r12							\n\
+0:									\n\
+	movem	[$r11+],$r10						\n\
+	subq   44,$r12							\n\
+1:	bge	0b							\n\
+	movem	$r10,[$r13+]						\n\
+3:									\n\
+	addq   44,$r12  ;; compensate for last loop underflowing n	\n\
+									\n\
+	;; Restore registers from stack					\n\
+	movem [$sp+],$r10						\n\
+2:									\n\
+	.section .fixup,\"ax\"						\n\
+4:									\n\
+; When failing on any of the 1..44 bytes in a chunk, we adjust back the	\n\
+; source pointer and just drop through	to the by-16 and by-4 loops to	\n\
+; get the correct number of failing bytes.  This necessarily means a	\n\
+; few extra exceptions, but invalid user pointers shouldn't happen in	\n\
+; time-critical code anyway.						\n\
+	jump 3b								\n\
+	subq 44,$r11							\n\
+									\n\
+	.previous							\n\
+	.section __ex_table,\"a\"					\n\
+	.dword 1b,4b							\n\
+	.previous"
+
+     /* Outputs */ : "=r" (dst), "=r" (src), "=r" (n), "=r" (retn)
+     /* Inputs */ : "0" (dst), "1" (src), "2" (n), "3" (retn));
+
+  }
+
+  while (n >= 16)
+  {
+    __asm_copy_to_user_16 (dst, src, retn);
+    n -= 16;
+  }
+
+  /* Having a separate by-four loops cuts down on cache footprint.
+     FIXME:  Test with and without; increasing switch to be 0..15.  */
+  while (n >= 4)
+  {
+    __asm_copy_to_user_4 (dst, src, retn);
+    n -= 4;
+  }
+
+  switch (n)
+  {
+    case 0:
+      break;
+    case 1:
+      __asm_copy_to_user_1 (dst, src, retn);
+      break;
+    case 2:
+      __asm_copy_to_user_2 (dst, src, retn);
+      break;
+    case 3:
+      __asm_copy_to_user_3 (dst, src, retn);
+      break;
+  }
+
+  return retn;
+}
+
+/* Copy from user to kernel, zeroing the bytes that were inaccessible in
+   userland.  The return-value is the number of bytes that were
+   inaccessible.  */
+
+unsigned long
+__copy_user_zeroing (void __user *pdst, const void *psrc, unsigned long pn)
+{
+  /* We want the parameters put in special registers.
+     Make sure the compiler is able to make something useful of this.
+     As it is now: r10 -> r13; r11 -> r11 (nop); r12 -> r12 (nop).
+
+     FIXME: Comment for old gcc version.  Check.
+     If gcc was allright, it really would need no temporaries, and no
+     stack space to save stuff on.  */
+
+  register char *dst __asm__ ("r13") = pdst;
+  register const char *src __asm__ ("r11") = psrc;
+  register int n __asm__ ("r12") = pn;
+  register int retn __asm__ ("r10") = 0;
+
+  /* The best reason to align src is that we then know that a read-fault
+     was for aligned bytes; there's no 1..3 remaining good bytes to
+     pickle.  */
+  if (((unsigned long) src & 3) != 0)
+  {
+    if (((unsigned long) src & 1) && n != 0)
+    {
+      __asm_copy_from_user_1 (dst, src, retn);
+      n--;
+    }
+
+    if (((unsigned long) src & 2) && n >= 2)
+    {
+      __asm_copy_from_user_2 (dst, src, retn);
+      n -= 2;
+    }
+
+    /* We only need one check after the unalignment-adjustments, because
+       if both adjustments were done, either both or neither reference
+       had an exception.  */
+    if (retn != 0)
+      goto copy_exception_bytes;
+  }
+
+  /* Movem is dirt cheap.  The overheap is low enough to always use the
+     minimum possible block size as the threshold.  */
+  if (n >= 44)
+  {
+    /* It is not optimal to tell the compiler about clobbering any
+       registers; that will move the saving/restoring of those registers
+       to the function prologue/epilogue, and make non-movem sizes
+       suboptimal.  */
+    __asm__ volatile ("\
+	.ifnc %0%1%2%3,$r13$r11$r12$r10					\n\
+	.err								\n\
+	.endif								\n\
+									\n\
+	;; Save the registers we'll use in the movem process		\n\
+	;; on the stack.						\n\
+	subq	11*4,$sp						\n\
+	movem	$r10,[$sp]						\n\
+									\n\
+	;; Now we've got this:						\n\
+	;; r11 - src							\n\
+	;; r13 - dst							\n\
+	;; r12 - n							\n\
+									\n\
+	;; Update n for the first loop					\n\
+	subq	44,$r12							\n\
+0:									\n\
+	movem	[$r11+],$r10						\n\
+									\n\
+	subq   44,$r12							\n\
+	bge	0b							\n\
+	movem	$r10,[$r13+]						\n\
+									\n\
+4:									\n\
+	addq   44,$r12  ;; compensate for last loop underflowing n	\n\
+									\n\
+	;; Restore registers from stack					\n\
+	movem [$sp+],$r10						\n\
+	.section .fixup,\"ax\"						\n\
+									\n\
+;; Do not jump back into the loop if we fail.  For some uses, we get a	\n\
+;; page fault somewhere on the line.  Without checking for page limits,	\n\
+;; we don't know where, but we need to copy accurately and keep an	\n\
+;; accurate count; not just clear the whole line.  To do that, we fall	\n\
+;; down in the code below, proceeding with smaller amounts.  It should	\n\
+;; be kept in mind that we have to cater to code like what at one time	\n\
+;; was in fs/super.c:							\n\
+;;  i = size - copy_from_user((void *)page, data, size);		\n\
+;; which would cause repeated faults while clearing the remainder of	\n\
+;; the SIZE bytes at PAGE after the first fault.			\n\
+;; A caveat here is that we must not fall through from a failing page	\n\
+;; to a valid page.							\n\
+									\n\
+3:									\n\
+	jump	4b ;; Fall through, pretending the fault didn't happen.	\n\
+	nop								\n\
+									\n\
+	.previous							\n\
+	.section __ex_table,\"a\"					\n\
+	.dword 0b,3b							\n\
+	.previous"
+
+     /* Outputs */ : "=r" (dst), "=r" (src), "=r" (n), "=r" (retn)
+     /* Inputs */ : "0" (dst), "1" (src), "2" (n), "3" (retn));
+  }
+
+  /* Either we directly start copying here, using dword copying in a loop,
+     or we copy as much as possible with 'movem' and then the last block
+     (<44 bytes) is copied here.  This will work since 'movem' will have
+     updated src, dst and n.  (Except with failing src.)
+
+     Since we want to keep src accurate, we can't use
+     __asm_copy_from_user_N with N != (1, 2, 4); it updates dst and
+     retn, but not src (by design; it's value is ignored elsewhere).  */
+
+  while (n >= 4)
+  {
+    __asm_copy_from_user_4 (dst, src, retn);
+    n -= 4;
+
+    if (retn)
+      goto copy_exception_bytes;
+  }
+
+  /* If we get here, there were no memory read faults.  */
+  switch (n)
+  {
+    /* These copies are at least "naturally aligned" (so we don't have
+       to check each byte), due to the src alignment code before the
+       movem loop.  The *_3 case *will* get the correct count for retn.  */
+    case 0:
+      /* This case deliberately left in (if you have doubts check the
+	 generated assembly code).  */
+      break;
+    case 1:
+      __asm_copy_from_user_1 (dst, src, retn);
+      break;
+    case 2:
+      __asm_copy_from_user_2 (dst, src, retn);
+      break;
+    case 3:
+      __asm_copy_from_user_3 (dst, src, retn);
+      break;
+  }
+
+  /* If we get here, retn correctly reflects the number of failing
+     bytes.  */
+  return retn;
+
+copy_exception_bytes:
+  /* We already have "retn" bytes cleared, and need to clear the
+     remaining "n" bytes.  A non-optimized simple byte-for-byte in-line
+     memset is preferred here, since this isn't speed-critical code and
+     we'd rather have this a leaf-function than calling memset.  */
+  {
+    char *endp;
+    for (endp = dst + n; dst < endp; dst++)
+      *dst = 0;
+  }
+
+  return retn + n;
+}
+
+/* Zero userspace.  */
+
+unsigned long
+__do_clear_user (void __user *pto, unsigned long pn)
+{
+  /* We want the parameters put in special registers.
+     Make sure the compiler is able to make something useful of this.
+      As it is now: r10 -> r13; r11 -> r11 (nop); r12 -> r12 (nop).
+
+     FIXME: Comment for old gcc version.  Check.
+     If gcc was allright, it really would need no temporaries, and no
+     stack space to save stuff on. */
+
+  register char *dst __asm__ ("r13") = pto;
+  register int n __asm__ ("r12") = pn;
+  register int retn __asm__ ("r10") = 0;
+
+
+  if (((unsigned long) dst & 3) != 0
+     /* Don't align if we wouldn't copy more than a few bytes.  */
+      && n >= 3)
+  {
+    if ((unsigned long) dst & 1)
+    {
+      __asm_clear_1 (dst, retn);
+      n--;
+    }
+
+    if ((unsigned long) dst & 2)
+    {
+      __asm_clear_2 (dst, retn);
+      n -= 2;
+    }
+  }
+
+  /* Decide which copying method to use.
+     FIXME: This number is from the "ordinary" kernel memset.  */
+  if (n >= 48)
+  {
+    /* For large clears we use 'movem' */
+
+    /* It is not optimal to tell the compiler about clobbering any
+       call-saved registers; that will move the saving/restoring of
+       those registers to the function prologue/epilogue, and make
+       non-movem sizes suboptimal.
+
+       This method is not foolproof; it assumes that the "asm reg"
+       declarations at the beginning of the function really are used
+       here (beware: they may be moved to temporary registers).
+       This way, we do not have to save/move the registers around into
+       temporaries; we can safely use them straight away.
+
+      If you want to check that the allocation was right; then
+      check the equalities in the first comment.  It should say
+      something like "r13=r13, r11=r11, r12=r12". */
+    __asm__ volatile ("\
+	.ifnc %0%1%2,$r13$r12$r10					\n\
+	.err								\n\
+	.endif								\n\
+									\n\
+	;; Save the registers we'll clobber in the movem process	\n\
+	;; on the stack.  Don't mention them to gcc, it will only be	\n\
+	;; upset.							\n\
+	subq	11*4,$sp						\n\
+	movem	$r10,[$sp]						\n\
+									\n\
+	clear.d $r0							\n\
+	clear.d $r1							\n\
+	clear.d $r2							\n\
+	clear.d $r3							\n\
+	clear.d $r4							\n\
+	clear.d $r5							\n\
+	clear.d $r6							\n\
+	clear.d $r7							\n\
+	clear.d $r8							\n\
+	clear.d $r9							\n\
+	clear.d $r10							\n\
+	clear.d $r11							\n\
+									\n\
+	;; Now we've got this:						\n\
+	;; r13 - dst							\n\
+	;; r12 - n							\n\
+									\n\
+	;; Update n for the first loop					\n\
+	subq	12*4,$r12						\n\
+0:									\n\
+	subq   12*4,$r12						\n\
+1:									\n\
+	bge	0b							\n\
+	movem	$r11,[$r13+]						\n\
+									\n\
+	addq   12*4,$r12 ;; compensate for last loop underflowing n	\n\
+									\n\
+	;; Restore registers from stack					\n\
+	movem [$sp+],$r10						\n\
+2:									\n\
+	.section .fixup,\"ax\"						\n\
+3:									\n\
+	movem [$sp],$r10						\n\
+	addq 12*4,$r10							\n\
+	addq 12*4,$r13							\n\
+	movem $r10,[$sp]						\n\
+	jump 0b								\n\
+	clear.d $r10							\n\
+									\n\
+	.previous							\n\
+	.section __ex_table,\"a\"					\n\
+	.dword 1b,3b							\n\
+	.previous"
+
+     /* Outputs */ : "=r" (dst), "=r" (n), "=r" (retn)
+     /* Inputs */ : "0" (dst), "1" (n), "2" (retn)
+     /* Clobber */ : "r11");
+  }
+
+  while (n >= 16)
+  {
+    __asm_clear_16 (dst, retn);
+    n -= 16;
+  }
+
+  /* Having a separate by-four loops cuts down on cache footprint.
+     FIXME:  Test with and without; increasing switch to be 0..15.  */
+  while (n >= 4)
+  {
+    __asm_clear_4 (dst, retn);
+    n -= 4;
+  }
+
+  switch (n)
+  {
+    case 0:
+      break;
+    case 1:
+      __asm_clear_1 (dst, retn);
+      break;
+    case 2:
+      __asm_clear_2 (dst, retn);
+      break;
+    case 3:
+      __asm_clear_3 (dst, retn);
+      break;
+  }
+
+  return retn;
+}
diff --git a/arch/cris/arch-v32/mm/Makefile b/arch/cris/arch-v32/mm/Makefile
new file mode 100644
--- /dev/null
+++ b/arch/cris/arch-v32/mm/Makefile
@@ -0,0 +1,3 @@
+# Makefile for the Linux/cris parts of the memory manager.
+
+obj-y	 := mmu.o init.o tlb.o intmem.o
diff --git a/arch/cris/arch-v32/mm/init.c b/arch/cris/arch-v32/mm/init.c
new file mode 100644
--- /dev/null
+++ b/arch/cris/arch-v32/mm/init.c
@@ -0,0 +1,174 @@
+/*
+ * Set up paging and the MMU.
+ *
+ * Copyright (C) 2000-2003, Axis Communications AB.
+ *
+ * Authors:   Bjorn Wesen <bjornw@axis.com>
+ *            Tobias Anderberg <tobiasa@axis.com>, CRISv32 port.
+ */
+#include <linux/config.h>
+#include <linux/mmzone.h>
+#include <linux/init.h>
+#include <linux/bootmem.h>
+#include <linux/mm.h>
+#include <linux/config.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/types.h>
+#include <asm/mmu.h>
+#include <asm/io.h>
+#include <asm/mmu_context.h>
+#include <asm/arch/hwregs/asm/mmu_defs_asm.h>
+#include <asm/arch/hwregs/supp_reg.h>
+
+extern void tlb_init(void);
+
+/*
+ * The kernel is already mapped with linear mapping at kseg_c so there's no
+ * need to map it with a page table. However, head.S also temporarily mapped it
+ * at kseg_4 thus the ksegs are set up again. Also clear the TLB and do various
+ * other paging stuff.
+ */
+void __init
+cris_mmu_init(void)
+{
+	unsigned long mmu_config;
+	unsigned long mmu_kbase_hi;
+	unsigned long mmu_kbase_lo;
+	unsigned short mmu_page_id;
+
+	/*
+	 * Make sure the current pgd table points to something sane, even if it
+	 * is most probably not used until the next switch_mm.
+	 */
+	per_cpu(current_pgd, smp_processor_id()) = init_mm.pgd;
+
+#ifdef CONFIG_SMP
+	{
+		pgd_t **pgd;
+		pgd = (pgd_t**)&per_cpu(current_pgd, smp_processor_id());
+		SUPP_BANK_SEL(1);
+		SUPP_REG_WR(RW_MM_TLB_PGD, pgd);
+		SUPP_BANK_SEL(2);
+		SUPP_REG_WR(RW_MM_TLB_PGD, pgd);
+	}
+#endif
+
+	/* Initialise the TLB. Function found in tlb.c. */
+	tlb_init();
+
+	/* Enable exceptions and initialize the kernel segments. */
+	mmu_config = ( REG_STATE(mmu, rw_mm_cfg, we, on)        |
+		       REG_STATE(mmu, rw_mm_cfg, acc, on)       |
+		       REG_STATE(mmu, rw_mm_cfg, ex, on)        |
+		       REG_STATE(mmu, rw_mm_cfg, inv, on)       |
+		       REG_STATE(mmu, rw_mm_cfg, seg_f, linear) |
+		       REG_STATE(mmu, rw_mm_cfg, seg_e, linear) |
+		       REG_STATE(mmu, rw_mm_cfg, seg_d, page)   |
+		       REG_STATE(mmu, rw_mm_cfg, seg_c, linear) |
+		       REG_STATE(mmu, rw_mm_cfg, seg_b, linear) |
+#ifndef CONFIG_ETRAXFS_SIM
+                       REG_STATE(mmu, rw_mm_cfg, seg_a, page)   |
+#else
+		       REG_STATE(mmu, rw_mm_cfg, seg_a, linear) |
+#endif
+		       REG_STATE(mmu, rw_mm_cfg, seg_9, page)   |
+		       REG_STATE(mmu, rw_mm_cfg, seg_8, page)   |
+		       REG_STATE(mmu, rw_mm_cfg, seg_7, page)   |
+		       REG_STATE(mmu, rw_mm_cfg, seg_6, page)   |
+		       REG_STATE(mmu, rw_mm_cfg, seg_5, page)   |
+		       REG_STATE(mmu, rw_mm_cfg, seg_4, page)   |
+		       REG_STATE(mmu, rw_mm_cfg, seg_3, page)   |
+		       REG_STATE(mmu, rw_mm_cfg, seg_2, page)   |
+		       REG_STATE(mmu, rw_mm_cfg, seg_1, page)   |
+		       REG_STATE(mmu, rw_mm_cfg, seg_0, page));
+
+	mmu_kbase_hi = ( REG_FIELD(mmu, rw_mm_kbase_hi, base_f, 0x0) |
+			 REG_FIELD(mmu, rw_mm_kbase_hi, base_e, 0x8) |
+			 REG_FIELD(mmu, rw_mm_kbase_hi, base_d, 0x0) |
+#ifndef CONFIG_ETRAXFS_SIM
+                         REG_FIELD(mmu, rw_mm_kbase_hi, base_c, 0x4) |
+#else
+			 REG_FIELD(mmu, rw_mm_kbase_hi, base_c, 0x0) |
+#endif
+			 REG_FIELD(mmu, rw_mm_kbase_hi, base_b, 0xb) |
+#ifndef CONFIG_ETRAXFS_SIM
+			 REG_FIELD(mmu, rw_mm_kbase_hi, base_a, 0x0) |
+#else
+                         REG_FIELD(mmu, rw_mm_kbase_hi, base_a, 0xa) |
+#endif
+			 REG_FIELD(mmu, rw_mm_kbase_hi, base_9, 0x0) |
+			 REG_FIELD(mmu, rw_mm_kbase_hi, base_8, 0x0));
+
+	mmu_kbase_lo = ( REG_FIELD(mmu, rw_mm_kbase_lo, base_7, 0x0) |
+			 REG_FIELD(mmu, rw_mm_kbase_lo, base_6, 0x0) |
+			 REG_FIELD(mmu, rw_mm_kbase_lo, base_5, 0x0) |
+			 REG_FIELD(mmu, rw_mm_kbase_lo, base_4, 0x0) |
+			 REG_FIELD(mmu, rw_mm_kbase_lo, base_3, 0x0) |
+			 REG_FIELD(mmu, rw_mm_kbase_lo, base_2, 0x0) |
+			 REG_FIELD(mmu, rw_mm_kbase_lo, base_1, 0x0) |
+			 REG_FIELD(mmu, rw_mm_kbase_lo, base_0, 0x0));
+
+	mmu_page_id = REG_FIELD(mmu, rw_mm_tlb_hi, pid, 0);
+
+	/* Update the instruction MMU. */
+	SUPP_BANK_SEL(BANK_IM);
+	SUPP_REG_WR(RW_MM_CFG, mmu_config);
+	SUPP_REG_WR(RW_MM_KBASE_HI, mmu_kbase_hi);
+	SUPP_REG_WR(RW_MM_KBASE_LO, mmu_kbase_lo);
+	SUPP_REG_WR(RW_MM_TLB_HI, mmu_page_id);
+
+	/* Update the data MMU. */
+	SUPP_BANK_SEL(BANK_DM);
+	SUPP_REG_WR(RW_MM_CFG, mmu_config);
+	SUPP_REG_WR(RW_MM_KBASE_HI, mmu_kbase_hi);
+	SUPP_REG_WR(RW_MM_KBASE_LO, mmu_kbase_lo);
+	SUPP_REG_WR(RW_MM_TLB_HI, mmu_page_id);
+
+	SPEC_REG_WR(SPEC_REG_PID, 0);
+
+	/*
+	 * The MMU has been enabled ever since head.S but just to make it
+	 * totally obvious enable it here as well.
+	 */
+	SUPP_BANK_SEL(BANK_GC);
+	SUPP_REG_WR(RW_GC_CFG, 0xf); /* IMMU, DMMU, ICache, DCache on */
+}
+
+void __init
+paging_init(void)
+{
+	int i;
+	unsigned long zones_size[MAX_NR_ZONES];
+
+	printk("Setting up paging and the MMU.\n");
+
+	/* Clear out the init_mm.pgd that will contain the kernel's mappings. */
+	for(i = 0; i < PTRS_PER_PGD; i++)
+		swapper_pg_dir[i] = __pgd(0);
+
+	cris_mmu_init();
+
+	/*
+	 * Initialize the bad page table and bad page to point to a couple of
+	 * allocated pages.
+	 */
+	empty_zero_page = (unsigned long) alloc_bootmem_pages(PAGE_SIZE);
+	memset((void *) empty_zero_page, 0, PAGE_SIZE);
+
+	/* All pages are DMA'able in Etrax, so put all in the DMA'able zone. */
+	zones_size[0] = ((unsigned long) high_memory - PAGE_OFFSET) >> PAGE_SHIFT;
+
+	for (i = 1; i < MAX_NR_ZONES; i++)
+		zones_size[i] = 0;
+
+	/*
+	 * Use free_area_init_node instead of free_area_init, because it is
+	 * designed for systems where the DRAM starts at an address
+	 * substantially higher than 0, like us (we start at PAGE_OFFSET). This
+	 * saves space in the mem_map page array.
+	 */
+	free_area_init_node(0, &contig_page_data, zones_size, PAGE_OFFSET >> PAGE_SHIFT, 0);
+
+	mem_map = contig_page_data.node_mem_map;
+}
diff --git a/arch/cris/arch-v32/mm/intmem.c b/arch/cris/arch-v32/mm/intmem.c
new file mode 100644
--- /dev/null
+++ b/arch/cris/arch-v32/mm/intmem.c
@@ -0,0 +1,139 @@
+/*
+ * Simple allocator for internal RAM in ETRAX FS
+ *
+ * Copyright (c) 2004 Axis Communications AB.
+ */
+
+#include <linux/list.h>
+#include <linux/slab.h>
+#include <asm/io.h>
+#include <asm/arch/memmap.h>
+
+#define STATUS_FREE 0
+#define STATUS_ALLOCATED 1
+
+struct intmem_allocation {
+	struct list_head entry;
+	unsigned int size;
+	unsigned offset;
+	char status;
+};
+
+
+static struct list_head intmem_allocations;
+static void* intmem_virtual;
+
+static void crisv32_intmem_init(void)
+{
+	static int initiated = 0;
+	if (!initiated) {
+		struct intmem_allocation* alloc =
+		  (struct intmem_allocation*)kmalloc(sizeof *alloc, GFP_KERNEL);
+		INIT_LIST_HEAD(&intmem_allocations);
+		intmem_virtual = ioremap(MEM_INTMEM_START, MEM_INTMEM_SIZE);
+		initiated = 1;
+		alloc->size = MEM_INTMEM_SIZE;
+		alloc->offset = 0;
+		alloc->status = STATUS_FREE;
+		list_add_tail(&alloc->entry, &intmem_allocations);
+	}
+}
+
+void* crisv32_intmem_alloc(unsigned size, unsigned align)
+{
+	struct intmem_allocation* allocation;
+	struct intmem_allocation* tmp;
+	void* ret = NULL;
+
+	preempt_disable();
+	crisv32_intmem_init();
+
+	list_for_each_entry_safe(allocation, tmp, &intmem_allocations, entry) {
+		int alignment = allocation->offset % align;
+		alignment = alignment ? align - alignment : alignment;
+
+		if (allocation->status == STATUS_FREE &&
+		    allocation->size >= size + alignment) {
+			if (allocation->size > size + alignment) {
+				struct intmem_allocation* alloc =
+					(struct intmem_allocation*)
+					kmalloc(sizeof *alloc, GFP_ATOMIC);
+				alloc->status = STATUS_FREE;
+				alloc->size = allocation->size - size - alignment;
+				alloc->offset = allocation->offset + size;
+				list_add(&alloc->entry, &allocation->entry);
+
+				if (alignment) {
+					struct intmem_allocation* tmp;
+					tmp = (struct intmem_allocation*)
+						kmalloc(sizeof *tmp, GFP_ATOMIC);
+					tmp->offset = allocation->offset;
+					tmp->size = alignment;
+					tmp->status = STATUS_FREE;
+					allocation->offset += alignment;
+					list_add_tail(&tmp->entry, &allocation->entry);
+				}
+			}
+			allocation->status = STATUS_ALLOCATED;
+			allocation->size = size;
+			ret = (void*)((int)intmem_virtual + allocation->offset);
+		}
+	}
+	preempt_enable();
+	return ret;
+}
+
+void crisv32_intmem_free(void* addr)
+{
+	struct intmem_allocation* allocation;
+	struct intmem_allocation* tmp;
+
+	if (addr == NULL)
+		return;
+
+	preempt_disable();
+	crisv32_intmem_init();
+
+	list_for_each_entry_safe(allocation, tmp, &intmem_allocations, entry) {
+		if (allocation->offset == (int)(addr - intmem_virtual)) {
+			struct intmem_allocation* prev =
+			  list_entry(allocation->entry.prev,
+			             struct intmem_allocation, entry);
+			struct intmem_allocation* next =
+			  list_entry(allocation->entry.next,
+				     struct intmem_allocation, entry);
+
+			allocation->status = STATUS_FREE;
+			/* Join with prev and/or next if also free */
+			if (prev->status == STATUS_FREE) {
+				prev->size += allocation->size;
+				list_del(&allocation->entry);
+				kfree(allocation);
+				allocation = prev;
+			}
+			if (next->status == STATUS_FREE) {
+				allocation->size += next->size;
+				list_del(&next->entry);
+				kfree(next);
+			}
+			preempt_enable();
+			return;
+		}
+	}
+	preempt_enable();
+}
+
+void* crisv32_intmem_phys_to_virt(unsigned long addr)
+{
+	return (void*)(addr - MEM_INTMEM_START+
+	               (unsigned long)intmem_virtual);
+}
+
+unsigned long crisv32_intmem_virt_to_phys(void* addr)
+{
+	return (unsigned long)((unsigned long )addr -
+	  (unsigned long)intmem_virtual + MEM_INTMEM_START);
+}
+
+
+
diff --git a/arch/cris/arch-v32/mm/mmu.S b/arch/cris/arch-v32/mm/mmu.S
new file mode 100644
--- /dev/null
+++ b/arch/cris/arch-v32/mm/mmu.S
@@ -0,0 +1,141 @@
+/*
+ *  Copyright (C) 2003 Axis Communications AB
+ *
+ *  Authors:	Mikael Starvik (starvik@axis.com)
+ *
+ * Code for the fault low-level handling routines.
+ *
+ */
+
+#include <asm/page.h>
+#include <asm/pgtable.h>
+
+; Save all register. Must save in same order as struct pt_regs.
+.macro SAVE_ALL
+	subq	12, $sp
+	move	$erp, [$sp]
+	subq	4, $sp
+	move	$srp, [$sp]
+	subq	4, $sp
+	move	$ccs, [$sp]
+	subq	4, $sp
+	move	$spc, [$sp]
+	subq	4, $sp
+	move	$mof, [$sp]
+	subq	4, $sp
+	move	$srs, [$sp]
+	subq	4, $sp
+	move.d	$acr, [$sp]
+	subq	14*4, $sp
+	movem	$r13, [$sp]
+	subq	4, $sp
+	move.d	$r10, [$sp]
+.endm
+
+; Bus fault handler. Extracts relevant information and calls mm subsystem
+; to handle the fault.
+.macro	MMU_BUS_FAULT_HANDLER handler, mmu, we, ex
+	.globl	\handler
+\handler:
+	SAVE_ALL
+	move	\mmu, $srs	; Select MMU support register bank
+	move.d  $sp, $r11	; regs
+	moveq	1, $r12		; protection fault
+	moveq   \we, $r13	; write exception?
+	orq	\ex << 1, $r13	; execute?
+	move    $s3, $r10	; rw_mm_cause
+	and.d	~8191, $r10	; Get faulting page start address
+
+	jsr	do_page_fault
+	nop
+	ba	ret_from_intr
+	nop
+.endm
+
+; Refill handler. Three cases may occur:
+;   1. PMD and PTE exists in mm subsystem but not in TLB
+;   2. PMD exists but not PTE
+;   3. PMD doesn't exist
+; The code below handles case 1 and calls the mm subsystem for case 2 and 3.
+; Do not touch this code without very good reasons and extensive testing.
+; Note that the code is optimized to minimize stalls (makes the code harder
+; to read).
+;
+; Each page is 8 KB. Each PMD holds 8192/4 PTEs (each PTE is 4 bytes) so each
+; PMD holds 16 MB of virtual memory.
+;   Bits  0-12 : Offset within a page
+;   Bits 13-23 : PTE offset within a PMD
+;   Bits 24-31 : PMD offset within the PGD
+
+.macro MMU_REFILL_HANDLER handler, mmu
+	.globl \handler
+\handler:
+	subq	4, $sp
+; (The pipeline stalls for one cycle; $sp used as address in the next cycle.)
+	move	$srs, [$sp]
+	subq	4, $sp
+	move	\mmu, $srs	; Select MMU support register bank
+	move.d	$acr, [$sp]
+	subq	4, $sp
+	move.d	$r0, [$sp]
+#ifdef CONFIG_SMP
+	move    $s7, $acr	; PGD
+#else
+	move.d  per_cpu__current_pgd, $acr ; PGD
+#endif
+	; Look up PMD in PGD
+	move	$s3, $r0	; rw_mm_cause
+	lsrq	24, $r0	; Get PMD index into PGD (bit 24-31)
+	move.d  [$acr], $acr	; PGD for the current process
+	addi	$r0.d, $acr, $acr
+	move	$s3, $r0	; rw_mm_cause
+	move.d  [$acr], $acr	; Get PMD
+	beq	1f
+	; Look up PTE in PMD
+	lsrq	PAGE_SHIFT, $r0
+	and.w	PAGE_MASK, $acr	; Remove PMD flags
+	and.d	0x7ff, $r0	; Get PTE index into PMD (bit 13-23)
+	addi    $r0.d, $acr, $acr
+	move.d  [$acr], $acr	; Get PTE
+	beq	2f
+	move.d  [$sp+], $r0	; Pop r0 in delayslot
+	; Store in TLB
+	move	$acr, $s5
+	; Return
+	move.d	[$sp+], $acr
+	move  	[$sp], $srs
+	addq	4, $sp
+	rete
+	rfe
+1:	; PMD missing, let the mm subsystem fix it up.
+	move.d  [$sp+], $r0	; Pop r0
+2:      ; PTE missing, let the mm subsystem fix it up.
+	move.d	[$sp+], $acr
+	move  	[$sp], $srs
+	addq	4, $sp
+	SAVE_ALL
+	move    \mmu, $srs
+	move.d	$sp, $r11	; regs
+	clear.d	$r12		; Not a protection fault
+	move.w  PAGE_MASK, $acr
+	move    $s3, $r10	; rw_mm_cause
+	btstq   9, $r10		; Check if write access
+	smi     $r13
+	and.w	PAGE_MASK, $r10	; Get VPN (virtual address)
+	jsr	do_page_fault
+	and.w   $acr, $r10
+	; Return
+	ba	ret_from_intr
+	nop
+.endm
+
+	; This is the MMU bus fault handlers.
+
+MMU_REFILL_HANDLER i_mmu_refill, 1
+MMU_BUS_FAULT_HANDLER i_mmu_invalid, 1, 0, 0
+MMU_BUS_FAULT_HANDLER i_mmu_access,  1, 0, 0
+MMU_BUS_FAULT_HANDLER i_mmu_execute, 1, 0, 1
+MMU_REFILL_HANDLER d_mmu_refill,  2
+MMU_BUS_FAULT_HANDLER d_mmu_invalid, 2, 0, 0
+MMU_BUS_FAULT_HANDLER d_mmu_access,  2, 0, 0
+MMU_BUS_FAULT_HANDLER d_mmu_write,   2, 1, 0
diff --git a/arch/cris/arch-v32/mm/tlb.c b/arch/cris/arch-v32/mm/tlb.c
new file mode 100644
--- /dev/null
+++ b/arch/cris/arch-v32/mm/tlb.c
@@ -0,0 +1,208 @@
+/*
+ * Low level TLB handling.
+ *
+ * Copyright (C) 2000-2003, Axis Communications AB.
+ *
+ * Authors:   Bjorn Wesen <bjornw@axis.com>
+ *            Tobias Anderberg <tobiasa@axis.com>, CRISv32 port.
+ */
+
+#include <asm/tlb.h>
+#include <asm/mmu_context.h>
+#include <asm/arch/hwregs/asm/mmu_defs_asm.h>
+#include <asm/arch/hwregs/supp_reg.h>
+
+#define UPDATE_TLB_SEL_IDX(val)					\
+do { 								\
+	unsigned long tlb_sel; 					\
+								\
+	tlb_sel = REG_FIELD(mmu, rw_mm_tlb_sel, idx, val);	\
+	SUPP_REG_WR(RW_MM_TLB_SEL, tlb_sel);			\
+} while(0)
+
+#define UPDATE_TLB_HILO(tlb_hi, tlb_lo)		\
+do {						\
+	SUPP_REG_WR(RW_MM_TLB_HI, tlb_hi);	\
+	SUPP_REG_WR(RW_MM_TLB_LO, tlb_lo);	\
+} while(0)
+
+/*
+ * The TLB can host up to 256 different mm contexts at the same time. The running
+ * context is found in the PID register. Each TLB entry contains a page_id that
+ * has to match the PID register to give a hit. page_id_map keeps track of which
+ * mm's is assigned to which page_id's, making sure it's known when to
+ * invalidate TLB entries.
+ *
+ * The last page_id is never running, it is used as an invalid page_id so that
+ * it's possible to make TLB entries that will nerver match.
+ *
+ * Note; the flushes needs to be atomic otherwise an interrupt hander that uses
+ * vmalloc'ed memory might cause a TLB load in the middle of a flush.
+ */
+
+/* Flush all TLB entries. */
+void
+__flush_tlb_all(void)
+{
+	int i;
+	int mmu;
+	unsigned long flags;
+	unsigned long mmu_tlb_hi;
+	unsigned long mmu_tlb_sel;
+
+	/*
+	 * Mask with 0xf so similar TLB entries aren't written in the same 4-way
+	 * entry group.
+	 */
+	local_save_flags(flags);
+	local_irq_disable();
+
+	for (mmu = 1; mmu <= 2; mmu++) {
+		SUPP_BANK_SEL(mmu); /* Select the MMU */
+		for (i = 0; i < NUM_TLB_ENTRIES; i++) {
+			/* Store invalid entry */
+			mmu_tlb_sel = REG_FIELD(mmu, rw_mm_tlb_sel, idx, i);
+
+			mmu_tlb_hi = (REG_FIELD(mmu, rw_mm_tlb_hi, pid, INVALID_PAGEID)
+				    | REG_FIELD(mmu, rw_mm_tlb_hi, vpn, i & 0xf));
+
+			SUPP_REG_WR(RW_MM_TLB_SEL, mmu_tlb_sel);
+			SUPP_REG_WR(RW_MM_TLB_HI, mmu_tlb_hi);
+			SUPP_REG_WR(RW_MM_TLB_LO, 0);
+		}
+	}
+
+	local_irq_restore(flags);
+}
+
+/* Flush an entire user address space. */
+void
+__flush_tlb_mm(struct mm_struct *mm)
+{
+	int i;
+	int mmu;
+	unsigned long flags;
+	unsigned long page_id;
+	unsigned long tlb_hi;
+	unsigned long mmu_tlb_hi;
+
+	page_id = mm->context.page_id;
+
+	if (page_id == NO_CONTEXT)
+		return;
+
+	/* Mark the TLB entries that match the page_id as invalid. */
+	local_save_flags(flags);
+	local_irq_disable();
+
+	for (mmu = 1; mmu <= 2; mmu++) {
+		SUPP_BANK_SEL(mmu);
+		for (i = 0; i < NUM_TLB_ENTRIES; i++) {
+			UPDATE_TLB_SEL_IDX(i);
+
+			/* Get the page_id */
+			SUPP_REG_RD(RW_MM_TLB_HI, tlb_hi);
+
+			/* Check if the page_id match. */
+			if ((tlb_hi & 0xff) == page_id) {
+				mmu_tlb_hi = (REG_FIELD(mmu, rw_mm_tlb_hi, pid,
+				                        INVALID_PAGEID)
+				            | REG_FIELD(mmu, rw_mm_tlb_hi, vpn,
+				                        i & 0xf));
+
+				UPDATE_TLB_HILO(mmu_tlb_hi, 0);
+			}
+		}
+	}
+
+	local_irq_restore(flags);
+}
+
+/* Invalidate a single page. */
+void
+__flush_tlb_page(struct vm_area_struct *vma, unsigned long addr)
+{
+	int i;
+	int mmu;
+	unsigned long page_id;
+	unsigned long flags;
+	unsigned long tlb_hi;
+	unsigned long mmu_tlb_hi;
+
+	page_id = vma->vm_mm->context.page_id;
+
+	if (page_id == NO_CONTEXT)
+		return;
+
+	addr &= PAGE_MASK;
+
+	/*
+	 * Invalidate those TLB entries that match both the mm context and the
+	 * requested virtual address.
+	 */
+	local_save_flags(flags);
+	local_irq_disable();
+
+	for (mmu = 1; mmu <= 2; mmu++) {
+		SUPP_BANK_SEL(mmu);
+		for (i = 0; i < NUM_TLB_ENTRIES; i++) {
+			UPDATE_TLB_SEL_IDX(i);
+			SUPP_REG_RD(RW_MM_TLB_HI, tlb_hi);
+
+			/* Check if page_id and address matches */
+			if (((tlb_hi & 0xff) == page_id) &&
+			    ((tlb_hi & PAGE_MASK) == addr)) {
+				mmu_tlb_hi = REG_FIELD(mmu, rw_mm_tlb_hi, pid,
+				                       INVALID_PAGEID) | addr;
+
+				UPDATE_TLB_HILO(mmu_tlb_hi, 0);
+			}
+		}
+	}
+
+	local_irq_restore(flags);
+}
+
+/*
+ * Initialize the context related info for a new mm_struct
+ * instance.
+ */
+
+int
+init_new_context(struct task_struct *tsk, struct mm_struct *mm)
+{
+	mm->context.page_id = NO_CONTEXT;
+	return 0;
+}
+
+/* Called in schedule() just before actually doing the switch_to. */
+void
+switch_mm(struct mm_struct *prev, struct mm_struct *next,
+	  struct task_struct *tsk)
+{
+	int cpu = smp_processor_id();
+
+	/* Make sure there is a MMU context. */
+	spin_lock(&next->page_table_lock);
+	get_mmu_context(next);
+	cpu_set(cpu, next->cpu_vm_mask);
+	spin_unlock(&next->page_table_lock);
+
+	/*
+	 * Remember the pgd for the fault handlers. Keep a seperate copy of it
+	 * because current and active_mm might be invalid at points where
+	 * there's still a need to derefer the pgd.
+	 */
+	per_cpu(current_pgd, cpu) = next->pgd;
+
+	/* Switch context in the MMU. */
+        if (tsk && tsk->thread_info)
+        {
+          SPEC_REG_WR(SPEC_REG_PID, next->context.page_id | tsk->thread_info->tls);
+        }
+        else
+        {
+          SPEC_REG_WR(SPEC_REG_PID, next->context.page_id);
+        }
+}
+
diff --git a/arch/cris/arch-v32/output_arch.ld b/arch/cris/arch-v32/output_arch.ld
new file mode 100644
--- /dev/null
+++ b/arch/cris/arch-v32/output_arch.ld
@@ -0,0 +1,2 @@
+/* At the time of this writing, there's no equivalent ld option. */
+OUTPUT_ARCH (crisv32)
diff --git a/arch/cris/arch-v32/vmlinux.lds.S b/arch/cris/arch-v32/vmlinux.lds.S
new file mode 100644
--- /dev/null
+++ b/arch/cris/arch-v32/vmlinux.lds.S
@@ -0,0 +1,134 @@
+/* ld script to make the Linux/CRIS kernel
+ * Authors: Bjorn Wesen (bjornw@axis.com)
+ *
+ * It is VERY DANGEROUS to fiddle around with the symbols in this
+ * script. It is for example quite vital that all generated sections
+ * that are used are actually named here, otherwise the linker will
+ * put them at the end, where the init stuff is which is FREED after
+ * the kernel has booted.
+ */
+
+#include <linux/config.h>
+#include <asm-generic/vmlinux.lds.h>
+
+jiffies = jiffies_64;
+SECTIONS
+{
+	. = DRAM_VIRTUAL_BASE;
+	dram_start = .;
+	ebp_start = .;
+
+	/* The boot section is only necessary until the VCS top level testbench */
+	/* includes both flash and DRAM. */
+	.boot : { *(.boot) }
+
+	. = DRAM_VIRTUAL_BASE + 0x4000;		/* See head.S and pages reserved at the start. */
+
+	_text = .;		/* Text and read-only data. */
+	text_start = .;		/* Lots of aliases. */
+	_stext = .;
+	__stext = .;
+	.text : {
+		*(.text)
+		SCHED_TEXT
+		LOCK_TEXT
+		*(.fixup)
+		*(.text.__*)
+	}
+
+	_etext = . ;		/* End of text section. */
+	__etext = .;
+
+	. = ALIGN(4);		/* Exception table. */
+  	__start___ex_table = .;
+  	__ex_table : { *(__ex_table) }
+  	__stop___ex_table = .;
+
+	RODATA
+
+	. = ALIGN (4);
+	___data_start = . ;
+	__Sdata = . ;
+	.data : {                     /* Data */
+		*(.data)
+	}
+	__edata = . ;		/* End of data section. */
+	_edata = . ;
+
+	. = ALIGN(8192);	/* init_task and stack, must be aligned. */
+  	.data.init_task : { *(.data.init_task) }
+
+  	. = ALIGN(8192);	/* Init code and data. */
+  	__init_begin = .;
+	.init.text : {
+		   _sinittext = .;
+		   *(.init.text)
+		   _einittext = .;
+	}
+  	.init.data : { *(.init.data) }
+  	. = ALIGN(16);
+  	__setup_start = .;
+  	.init.setup : { *(.init.setup) }
+  	__setup_end = .;
+	__start___param = .;
+	__param : { *(__param) }
+	__stop___param = .;
+  	.initcall.init : {
+		__initcall_start = .;
+		*(.initcall1.init);
+		*(.initcall2.init);
+		*(.initcall3.init);
+		*(.initcall4.init);
+		*(.initcall5.init);
+		*(.initcall6.init);
+		*(.initcall7.init);
+		__initcall_end = .;
+	}
+
+	.con_initcall.init : {
+		__con_initcall_start = .;
+		*(.con_initcall.init)
+		__con_initcall_end = .;
+	}
+	SECURITY_INIT
+
+	__per_cpu_start = .;
+	.data.percpu  : { *(.data.percpu) }
+	__per_cpu_end = .;
+
+	.init.ramfs : {
+		__initramfs_start = .;
+		*(.init.ramfs)
+		__initramfs_end = .;
+		/*
+		 * We fill to the next page, so we can discard all init
+		 * pages without needing to consider what payload might be
+		 * appended to the kernel image.
+		 */
+		FILL (0);
+		. = ALIGN (8192);
+	}
+
+	__vmlinux_end = .;	/* Last address of the physical file. */
+  	__init_end = .;
+
+	__data_end = . ;	/* Move to _edata? */
+	__bss_start = .;	/* BSS. */
+	.bss : {
+		*(COMMON)
+		*(.bss)
+	}
+
+	. =  ALIGN (0x20);
+	_end = .;
+	__end = .;
+
+	/* Sections to be discarded */
+  	/DISCARD/ : {
+        	*(.text.exit)
+        	*(.data.exit)
+		*(.exitcall.exit)
+        }
+
+	dram_end = dram_start + CONFIG_ETRAX_DRAM_SIZE*1024*1024;
+}
diff --git a/arch/cris/defconfig b/arch/cris/defconfig
--- a/arch/cris/defconfig
+++ b/arch/cris/defconfig
@@ -1,22 +1,27 @@
 #
 # Automatically generated make config: don't edit
+# Linux kernel version: 2.6.11
+# Mon Jun 20 13:42:02 2005
 #
 CONFIG_MMU=y
 CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_IOMAP=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_CRIS=y
 
 #
 # Code maturity level options
 #
 CONFIG_EXPERIMENTAL=y
 CONFIG_CLEAN_COMPILE=y
-CONFIG_STANDALONE=y
 CONFIG_BROKEN_ON_SMP=y
 
 #
 # General setup
 #
-CONFIG_SWAP=y
+CONFIG_LOCALVERSION=""
+# CONFIG_SWAP is not set
 # CONFIG_SYSVIPC is not set
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
@@ -24,16 +29,19 @@ CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
 CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_HOTPLUG is not set
+CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
 CONFIG_EMBEDDED=y
 # CONFIG_KALLSYMS is not set
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
 
 #
 # Loadable module support
@@ -45,23 +53,28 @@ CONFIG_IOSCHED_CFQ=y
 #
 CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
+CONFIG_GENERIC_HARDIRQS=y
+# CONFIG_SMP is not set
 CONFIG_ETRAX_CMDLINE="root=/dev/mtdblock3 init=/linuxrc"
-CONFIG_ETRAX_WATCHDOG=y
-CONFIG_ETRAX_WATCHDOG_NICE_DOGGY=y
+# CONFIG_ETRAX_WATCHDOG is not set
 CONFIG_ETRAX_FAST_TIMER=y
 # CONFIG_PREEMPT is not set
+# CONFIG_OOM_REBOOT is not set
 
 #
 # Hardware setup
 #
-CONFIG_ETRAX100LX=y
-# CONFIG_ETRAX100LX_V2 is not set
+# CONFIG_ETRAX100LX is not set
+CONFIG_ETRAX100LX_V2=y
 # CONFIG_SVINTO_SIM is not set
+# CONFIG_ETRAXFS is not set
+# CONFIG_ETRAXFS_SIM is not set
 CONFIG_ETRAX_ARCH_V10=y
-CONFIG_ETRAX_DRAM_SIZE=16
+# CONFIG_ETRAX_ARCH_V32 is not set
+CONFIG_ETRAX_DRAM_SIZE=32
 CONFIG_ETRAX_FLASH_BUSWIDTH=2
-CONFIG_CRIS_LOW_MAP=y
-CONFIG_ETRAX_DRAM_VIRTUAL_BASE=60000000
+CONFIG_ETRAX_FLASH1_SIZE=4
+CONFIG_ETRAX_DRAM_VIRTUAL_BASE=c0000000
 CONFIG_ETRAX_PA_LEDS=y
 # CONFIG_ETRAX_PB_LEDS is not set
 # CONFIG_ETRAX_CSP0_LEDS is not set
@@ -81,13 +94,13 @@ CONFIG_ETRAX_RESCUE_SER0=y
 # CONFIG_ETRAX_RESCUE_SER1 is not set
 # CONFIG_ETRAX_RESCUE_SER2 is not set
 # CONFIG_ETRAX_RESCUE_SER3 is not set
-CONFIG_ETRAX_DEF_R_WAITSTATES=0x95f8
-CONFIG_ETRAX_DEF_R_BUS_CONFIG=0x104
+CONFIG_ETRAX_DEF_R_WAITSTATES=0x95a6
+CONFIG_ETRAX_DEF_R_BUS_CONFIG=0x4
 CONFIG_ETRAX_SDRAM=y
-CONFIG_ETRAX_DEF_R_SDRAM_CONFIG=0x00e03636
+CONFIG_ETRAX_DEF_R_SDRAM_CONFIG=0x09e05757
 CONFIG_ETRAX_DEF_R_SDRAM_TIMING=0x80008002
 CONFIG_ETRAX_DEF_R_PORT_PA_DIR=0x1d
-CONFIG_ETRAX_DEF_R_PORT_PA_DATA=0xf0
+CONFIG_ETRAX_DEF_R_PORT_PA_DATA=0x00
 CONFIG_ETRAX_DEF_R_PORT_PB_CONFIG=0x00
 CONFIG_ETRAX_DEF_R_PORT_PB_DIR=0x1e
 CONFIG_ETRAX_DEF_R_PORT_PB_DATA=0xf3
@@ -97,16 +110,17 @@ CONFIG_ETRAX_DEF_R_PORT_PB_DATA=0xf3
 # Drivers for built-in interfaces
 #
 CONFIG_ETRAX_ETHERNET=y
-CONFIG_NET_ETHERNET=y
 # CONFIG_ETRAX_NETWORK_LED_ON_WHEN_LINK is not set
 CONFIG_ETRAX_NETWORK_LED_ON_WHEN_ACTIVITY=y
 CONFIG_ETRAX_SERIAL=y
-CONFIG_ETRAX_SERIAL_FAST_TIMER=y
+# CONFIG_ETRAX_SERIAL_FAST_TIMER is not set
+# CONFIG_ETRAX_SERIAL_FLUSH_DMA_FAST is not set
+CONFIG_ETRAX_SERIAL_RX_TIMEOUT_TICKS=5
 CONFIG_ETRAX_SERIAL_PORT0=y
-# CONFIG_CONFIG_ETRAX_SERIAL_PORT0_NO_DMA_OUT is not set
-CONFIG_CONFIG_ETRAX_SERIAL_PORT0_DMA6_OUT=y
-# CONFIG_CONFIG_ETRAX_SERIAL_PORT0_NO_DMA_IN is not set
-CONFIG_CONFIG_ETRAX_SERIAL_PORT0_DMA7_IN=y
+# CONFIG_ETRAX_SERIAL_PORT0_NO_DMA_OUT is not set
+CONFIG_ETRAX_SERIAL_PORT0_DMA6_OUT=y
+# CONFIG_ETRAX_SERIAL_PORT0_NO_DMA_IN is not set
+CONFIG_ETRAX_SERIAL_PORT0_DMA7_IN=y
 CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_ON_NONE=y
 # CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_ON_PA is not set
 # CONFIG_ETRAX_SER0_DTR_RI_DSR_CD_ON_PB is not set
@@ -121,10 +135,10 @@ CONFIG_ETRAX_SER0_DSR_ON_PB_BIT=-1
 CONFIG_ETRAX_SER0_CD_ON_PB_BIT=-1
 # CONFIG_ETRAX_SERIAL_PORT1 is not set
 CONFIG_ETRAX_SERIAL_PORT2=y
-# CONFIG_CONFIG_ETRAX_SERIAL_PORT2_NO_DMA_OUT is not set
-CONFIG_CONFIG_ETRAX_SERIAL_PORT2_DMA2_OUT=y
-# CONFIG_CONFIG_ETRAX_SERIAL_PORT2_NO_DMA_IN is not set
-CONFIG_CONFIG_ETRAX_SERIAL_PORT2_DMA3_IN=y
+# CONFIG_ETRAX_SERIAL_PORT2_NO_DMA_OUT is not set
+CONFIG_ETRAX_SERIAL_PORT2_DMA2_OUT=y
+# CONFIG_ETRAX_SERIAL_PORT2_NO_DMA_IN is not set
+CONFIG_ETRAX_SERIAL_PORT2_DMA3_IN=y
 CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_ON_NONE=y
 # CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_ON_PA is not set
 # CONFIG_ETRAX_SER2_DTR_RI_DSR_CD_ON_PB is not set
@@ -138,44 +152,51 @@ CONFIG_ETRAX_SER2_RI_ON_PB_BIT=-1
 CONFIG_ETRAX_SER2_DSR_ON_PB_BIT=-1
 CONFIG_ETRAX_SER2_CD_ON_PB_BIT=-1
 # CONFIG_ETRAX_SERIAL_PORT3 is not set
-# CONFIG_ETRAX_RS485 is not set
-# CONFIG_ETRAX_IDE is not set
-# CONFIG_IDE is not set
-# CONFIG_ETRAX_USB_HOST is not set
+CONFIG_ETRAX_RS485=y
+# CONFIG_ETRAX_RS485_ON_PA is not set
+# CONFIG_ETRAX_RS485_DISABLE_RECEIVER is not set
+CONFIG_ETRAX_IDE=y
+CONFIG_ETRAX_IDE_DELAY=15
+CONFIG_ETRAX_IDE_PB7_RESET=y
+# CONFIG_ETRAX_IDE_G27_RESET is not set
+CONFIG_ETRAX_USB_HOST=y
+CONFIG_ETRAX_USB_HOST_PORT1=y
+CONFIG_ETRAX_USB_HOST_PORT2=y
 CONFIG_ETRAX_AXISFLASHMAP=y
 CONFIG_ETRAX_PTABLE_SECTOR=65536
-CONFIG_MTD=y
-CONFIG_MTD_CFI=y
-CONFIG_MTD_CFI_AMDSTD=y
-CONFIG_MTD_OBSOLETE_CHIPS=y
-CONFIG_MTD_AMDSTD=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CONCAT=y
 # CONFIG_ETRAX_I2C is not set
-CONFIG_ETRAX_GPIO=y
-CONFIG_ETRAX_PA_BUTTON_BITMASK=0x02
-CONFIG_ETRAX_PA_CHANGEABLE_DIR=0x00
-CONFIG_ETRAX_PA_CHANGEABLE_BITS=0xFF
-CONFIG_ETRAX_PB_CHANGEABLE_DIR=0x00
-CONFIG_ETRAX_PB_CHANGEABLE_BITS=0xFF
-# CONFIG_ETRAX_RTC is not set
+# CONFIG_ETRAX_GPIO is not set
+CONFIG_ETRAX_RTC=y
+CONFIG_ETRAX_DS1302=y
+# CONFIG_ETRAX_PCF8563 is not set
+CONFIG_ETRAX_DS1302_RST_ON_GENERIC_PORT=y
+CONFIG_ETRAX_DS1302_RSTBIT=0
+CONFIG_ETRAX_DS1302_SCLBIT=1
+CONFIG_ETRAX_DS1302_SDABIT=0
+CONFIG_ETRAX_DS1302_TRICKLE_CHARGE=0
 
 #
 # Generic Driver Options
 #
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
 
 #
 # Memory Technology Devices (MTD)
 #
+CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CONCAT=y
 # CONFIG_MTD_REDBOOT_PARTS is not set
 # CONFIG_MTD_CMDLINE_PARTS is not set
 
 #
 # User Modules And Translation Layers
 #
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
 # CONFIG_FTL is not set
 # CONFIG_NFTL is not set
 # CONFIG_INFTL is not set
@@ -183,14 +204,30 @@ CONFIG_ETRAX_PB_CHANGEABLE_BITS=0xFF
 #
 # RAM/ROM/Flash chip drivers
 #
+CONFIG_MTD_CFI=y
 # CONFIG_MTD_JEDECPROBE is not set
 CONFIG_MTD_GEN_PROBE=y
 # CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
 # CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_CFI_AMDSTD_RETRY=0
 # CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
 CONFIG_MTD_RAM=y
 # CONFIG_MTD_ROM is not set
 # CONFIG_MTD_ABSENT is not set
+CONFIG_MTD_OBSOLETE_CHIPS=y
+CONFIG_MTD_AMDSTD=y
 # CONFIG_MTD_SHARP is not set
 # CONFIG_MTD_JEDEC is not set
 
@@ -204,11 +241,13 @@ CONFIG_MTD_COMPLEX_MAPPINGS=y
 # Self-contained MTD device drivers
 #
 # CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
 CONFIG_MTD_MTDRAM=y
 CONFIG_MTDRAM_TOTAL_SIZE=0
 CONFIG_MTDRAM_ERASE_SIZE=64
 CONFIG_MTDRAM_ABS_POS=0x0
 # CONFIG_MTD_BLKMTD is not set
+# CONFIG_MTD_BLOCK2MTD is not set
 
 #
 # Disk-On-Chip Device Drivers
@@ -235,11 +274,25 @@ CONFIG_MTDRAM_ABS_POS=0x0
 # Block devices
 #
 # CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
 CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=4096
 # CONFIG_BLK_DEV_INITRD is not set
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CDROM_PKTCDVD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_AS is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_ATA_OVER_ETH is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -249,6 +302,28 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
 #
 # ATA/ATAPI/MFM/RLL support
 #
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+CONFIG_BLK_DEV_IDECD=y
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+# CONFIG_IDE_GENERIC is not set
+# CONFIG_IDE_ARM is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_BLK_DEV_HD is not set
 
 #
 # SCSI device support
@@ -258,7 +333,6 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
 #
 # IEEE 1394 (FireWire) support
 #
-# CONFIG_IEEE1394 is not set
 
 #
 # I2O device support
@@ -288,6 +362,9 @@ CONFIG_INET=y
 # CONFIG_INET_AH is not set
 # CONFIG_INET_ESP is not set
 # CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_IP_TCPDIAG=y
+# CONFIG_IP_TCPDIAG_IPV6 is not set
 
 #
 # IP: Virtual Server Configuration
@@ -301,11 +378,10 @@ CONFIG_NETFILTER=y
 # IP: Netfilter Configuration
 #
 # CONFIG_IP_NF_CONNTRACK is not set
+# CONFIG_IP_NF_CONNTRACK_MARK is not set
 # CONFIG_IP_NF_QUEUE is not set
 # CONFIG_IP_NF_IPTABLES is not set
 # CONFIG_IP_NF_ARPTABLES is not set
-# CONFIG_IP_NF_COMPAT_IPCHAINS is not set
-# CONFIG_IP_NF_COMPAT_IPFWADM is not set
 
 #
 # SCTP Configuration (EXPERIMENTAL)
@@ -323,12 +399,12 @@ CONFIG_NETFILTER=y
 # CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_HW_FLOWCONTROL is not set
 
 #
 # QoS and/or fair queueing
 #
 # CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
 
 #
 # Network testing
@@ -338,7 +414,26 @@ CONFIG_NETFILTER=y
 # CONFIG_NET_POLL_CONTROLLER is not set
 # CONFIG_HAMRADIO is not set
 # CONFIG_IRDA is not set
-# CONFIG_BT is not set
+CONFIG_BT=y
+CONFIG_BT_L2CAP=y
+# CONFIG_BT_SCO is not set
+CONFIG_BT_RFCOMM=y
+# CONFIG_BT_RFCOMM_TTY is not set
+CONFIG_BT_BNEP=y
+# CONFIG_BT_BNEP_MC_FILTER is not set
+# CONFIG_BT_BNEP_PROTO_FILTER is not set
+# CONFIG_BT_HIDP is not set
+
+#
+# Bluetooth device drivers
+#
+CONFIG_BT_HCIUSB=y
+# CONFIG_BT_HCIUSB_SCO is not set
+# CONFIG_BT_HCIUART is not set
+# CONFIG_BT_HCIBCM203X is not set
+# CONFIG_BT_HCIBPA10X is not set
+# CONFIG_BT_HCIBFUSB is not set
+# CONFIG_BT_HCIVHCI is not set
 CONFIG_NETDEVICES=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
@@ -348,6 +443,7 @@ CONFIG_NETDEVICES=y
 #
 # Ethernet (10 or 100Mbit)
 #
+CONFIG_NET_ETHERNET=y
 # CONFIG_MII is not set
 
 #
@@ -389,11 +485,19 @@ CONFIG_NETDEVICES=y
 #
 # Input device support
 #
-# CONFIG_INPUT is not set
+CONFIG_INPUT=y
 
 #
 # Userland interfaces
 #
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
 
 #
 # Input I/O drivers
@@ -404,10 +508,25 @@ CONFIG_SERIO=y
 # CONFIG_SERIO_I8042 is not set
 # CONFIG_SERIO_SERPORT is not set
 # CONFIG_SERIO_CT82C710 is not set
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
 
 #
 # Input Device Drivers
 #
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
 
 #
 # Character devices
@@ -426,7 +545,6 @@ CONFIG_SERIO=y
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
-# CONFIG_QIC02_TAPE is not set
 
 #
 # IPMI
@@ -441,13 +559,10 @@ CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_GEN_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
-# CONFIG_APPLICOM is not set
 
 #
 # Ftape, the floppy tape device driver
 #
-# CONFIG_FTAPE is not set
-# CONFIG_AGP is not set
 # CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 
@@ -469,10 +584,15 @@ CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_JBD is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
+
+#
+# XFS support
+#
 # CONFIG_XFS_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
 # CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
 
@@ -485,7 +605,8 @@ CONFIG_LEGACY_PTY_COUNT=256
 #
 # DOS/FAT/NT Filesystems
 #
-# CONFIG_FAT_FS is not set
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
 # CONFIG_NTFS_FS is not set
 
 #
@@ -497,6 +618,7 @@ CONFIG_SYSFS=y
 # CONFIG_DEVFS_FS is not set
 # CONFIG_DEVPTS_FS_XATTR is not set
 CONFIG_TMPFS=y
+# CONFIG_TMPFS_XATTR is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
 
@@ -512,7 +634,15 @@ CONFIG_RAMFS=y
 # CONFIG_EFS_FS is not set
 CONFIG_JFFS_FS=y
 CONFIG_JFFS_FS_VERBOSE=0
-# CONFIG_JFFS2_FS is not set
+# CONFIG_JFFS_PROC_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+# CONFIG_JFFS2_FS_NAND is not set
+# CONFIG_JFFS2_FS_NOR_ECC is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
 CONFIG_CRAMFS=y
 # CONFIG_VXFS_FS is not set
 # CONFIG_HPFS_FS is not set
@@ -530,14 +660,13 @@ CONFIG_NFS_V3=y
 # CONFIG_NFSD is not set
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
-# CONFIG_EXPORTFS is not set
 CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
-# CONFIG_INTERMEZZO_FS is not set
 # CONFIG_AFS_FS is not set
 
 #
@@ -557,8 +686,120 @@ CONFIG_MSDOS_PARTITION=y
 # CONFIG_SOUND is not set
 
 #
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
+#
+
+#
 # USB support
 #
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_BANDWIDTH is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+# CONFIG_USB_ARCH_HAS_HCD is not set
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_SL811_HCD is not set
+
+#
+# USB Device Class drivers
+#
+
+#
+# USB Bluetooth TTY can only be used with disabled Bluetooth subsystem
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+#
+# CONFIG_USB_STORAGE is not set
+
+#
+# USB Input Devices
+#
+# CONFIG_USB_HID is not set
+
+#
+# USB HID Boot Protocol drivers
+#
+# CONFIG_USB_KBD is not set
+# CONFIG_USB_MOUSE is not set
+# CONFIG_USB_AIPTEK is not set
+# CONFIG_USB_WACOM is not set
+# CONFIG_USB_KBTAB is not set
+# CONFIG_USB_POWERMATE is not set
+# CONFIG_USB_MTOUCH is not set
+# CONFIG_USB_EGALAX is not set
+# CONFIG_USB_XPAD is not set
+# CONFIG_USB_ATI_REMOTE is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+
+#
+# USB Multimedia devices
+#
+# CONFIG_USB_DABUSB is not set
+
+#
+# Video4Linux support is needed for USB Multimedia device support
+#
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+CONFIG_USB_RTL8150=y
+# CONFIG_USB_USBNET is not set
+
+#
+# USB port drivers
+#
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGETKIT is not set
+# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_TEST is not set
+
+#
+# USB ATM/DSL drivers
+#
 
 #
 # USB Gadget Support
@@ -568,14 +809,17 @@ CONFIG_MSDOS_PARTITION=y
 #
 # Kernel hacking
 #
-# CONFIG_PROFILE is not set
+# CONFIG_PROFILING is not set
+# CONFIG_SYSTEM_PROFILER is not set
 # CONFIG_ETRAX_KGDB is not set
 # CONFIG_DEBUG_INFO is not set
 # CONFIG_FRAME_POINTER is not set
+# CONFIG_DEBUG_NMI_OOPS is not set
 
 #
 # Security options
 #
+# CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 
 #
@@ -584,8 +828,14 @@ CONFIG_MSDOS_PARTITION=y
 # CONFIG_CRYPTO is not set
 
 #
+# Hardware crypto devices
+#
+
+#
 # Library routines
 #
-# CONFIG_CRC32 is not set
+# CONFIG_CRC_CCITT is not set
+CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
diff --git a/arch/cris/kernel/Makefile b/arch/cris/kernel/Makefile
--- a/arch/cris/kernel/Makefile
+++ b/arch/cris/kernel/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.10 2004/05/14 10:18:12 starvik Exp $
+# $Id: Makefile,v 1.12 2004/10/19 13:07:43 starvik Exp $
 #
 # Makefile for the linux kernel.
 #
@@ -10,6 +10,7 @@ obj-y   := process.o traps.o irq.o ptrac
 
 obj-$(CONFIG_MODULES)    += crisksyms.o
 obj-$(CONFIG_MODULES)	 += module.o
+obj-$(CONFIG_SYSTEM_PROFILER)   += profile.o
 
 clean:
 
diff --git a/arch/cris/kernel/crisksyms.c b/arch/cris/kernel/crisksyms.c
--- a/arch/cris/kernel/crisksyms.c
+++ b/arch/cris/kernel/crisksyms.c
@@ -27,13 +27,13 @@ extern void __Udiv(void);
 extern void __Umod(void);
 extern void __Div(void);
 extern void __Mod(void);
+extern void __ashldi3(void);
 extern void __ashrdi3(void);
-extern void iounmap(void *addr);
+extern void __lshrdi3(void);
+extern void iounmap(volatile void * __iomem);
 
 /* Platform dependent support */
 EXPORT_SYMBOL(dump_thread);
-EXPORT_SYMBOL(enable_irq);
-EXPORT_SYMBOL(disable_irq);
 EXPORT_SYMBOL(kernel_thread);
 EXPORT_SYMBOL(get_cmos_time);
 EXPORT_SYMBOL(loops_per_usec);
@@ -57,7 +57,9 @@ EXPORT_SYMBOL(__Udiv);
 EXPORT_SYMBOL(__Umod);
 EXPORT_SYMBOL(__Div);
 EXPORT_SYMBOL(__Mod);
+EXPORT_SYMBOL(__ashldi3);
 EXPORT_SYMBOL(__ashrdi3);
+EXPORT_SYMBOL(__lshrdi3);
 
 /* Memory functions */
 EXPORT_SYMBOL(__ioremap);
@@ -69,23 +71,10 @@ EXPORT_SYMBOL(__down);
 EXPORT_SYMBOL(__down_interruptible);
 EXPORT_SYMBOL(__down_trylock);
 
-/* Export shadow registers for the CPU I/O pins */
-EXPORT_SYMBOL(genconfig_shadow);
-EXPORT_SYMBOL(port_pa_data_shadow);
-EXPORT_SYMBOL(port_pa_dir_shadow);
-EXPORT_SYMBOL(port_pb_data_shadow);
-EXPORT_SYMBOL(port_pb_dir_shadow);
-EXPORT_SYMBOL(port_pb_config_shadow);
-EXPORT_SYMBOL(port_g_data_shadow);
-
 /* Userspace access functions */
 EXPORT_SYMBOL(__copy_user_zeroing);
 EXPORT_SYMBOL(__copy_user);
 
-/* Cache flush functions */
-EXPORT_SYMBOL(flush_etrax_cache);
-EXPORT_SYMBOL(prepare_rx_descriptor);
-
 #undef memcpy
 #undef memset
 extern void * memset(void *, int, __kernel_size_t);
diff --git a/arch/cris/kernel/irq.c b/arch/cris/kernel/irq.c
--- a/arch/cris/kernel/irq.c
+++ b/arch/cris/kernel/irq.c
@@ -12,8 +12,6 @@
  * shouldn't result in any weird surprises, and installing new handlers
  * should be easier.
  *
- * Notice Linux/CRIS: these routines do not care about SMP
- *
  */
 
 /*
@@ -24,6 +22,7 @@
 #include <linux/config.h>
 #include <linux/module.h>
 #include <linux/ptrace.h>
+#include <linux/irq.h>
 
 #include <linux/kernel_stat.h>
 #include <linux/signal.h>
@@ -36,84 +35,56 @@
 #include <linux/init.h>
 #include <linux/seq_file.h>
 #include <linux/errno.h>
-#include <linux/bitops.h>
+#include <linux/spinlock.h>
 
 #include <asm/io.h>
 
-/* Defined in arch specific irq.c */
-extern void arch_setup_irq(int irq);
-extern void arch_free_irq(int irq);
-
-void
-disable_irq(unsigned int irq_nr)
-{
-	unsigned long flags;
-	
-	local_save_flags(flags);
-	local_irq_disable();
-	mask_irq(irq_nr);
-	local_irq_restore(flags);
-}
-
-void
-enable_irq(unsigned int irq_nr)
-{
-	unsigned long flags;
-	local_save_flags(flags);
-	local_irq_disable();
-	unmask_irq(irq_nr);
-	local_irq_restore(flags);
-}
-
-unsigned long
-probe_irq_on()
+void ack_bad_irq(unsigned int irq)
 {
-	return 0;
+	printk("unexpected IRQ trap at vector %02x\n", irq);
 }
 
-EXPORT_SYMBOL(probe_irq_on);
-
-int
-probe_irq_off(unsigned long x)
-{
-	return 0;
-}
-
-EXPORT_SYMBOL(probe_irq_off);
-
-/*
- * Initial irq handlers.
- */
-
-static struct irqaction *irq_action[NR_IRQS];
-
 int show_interrupts(struct seq_file *p, void *v)
 {
-	int i = *(loff_t *) v;
+	int i = *(loff_t *) v, j;
 	struct irqaction * action;
 	unsigned long flags;
 
+	if (i == 0) {
+		seq_printf(p, "           ");
+		for (j=0; j<NR_CPUS; j++)
+			if (cpu_online(j))
+				seq_printf(p, "CPU%d       ",j);
+		seq_putc(p, '\n');
+	}
+
 	if (i < NR_IRQS) {
-		local_irq_save(flags);
-		action = irq_action[i];
-		if (!action) 
+		spin_lock_irqsave(&irq_desc[i].lock, flags);
+		action = irq_desc[i].action;
+		if (!action)
 			goto skip;
-		seq_printf(p, "%2d: %10u %c %s",
-			i, kstat_this_cpu.irqs[i],
-			(action->flags & SA_INTERRUPT) ? '+' : ' ',
-			action->name);
-		for (action = action->next; action; action = action->next) {
-			seq_printf(p, ",%s %s",
-				(action->flags & SA_INTERRUPT) ? " +" : "",
-				action->name);
-		}
+		seq_printf(p, "%3d: ",i);
+#ifndef CONFIG_SMP
+		seq_printf(p, "%10u ", kstat_irqs(i));
+#else
+		for (j = 0; j < NR_CPUS; j++)
+			if (cpu_online(j))
+				seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
+#endif
+		seq_printf(p, " %14s", irq_desc[i].handler->typename);
+		seq_printf(p, "  %s", action->name);
+
+		for (action=action->next; action; action = action->next)
+			seq_printf(p, ", %s", action->name);
+
 		seq_putc(p, '\n');
 skip:
-		local_irq_restore(flags);
+		spin_unlock_irqrestore(&irq_desc[i].lock, flags);
 	}
 	return 0;
 }
 
+
 /* called by the assembler IRQ entry functions defined in irq.h
  * to dispatch the interrupts to registred handlers
  * interrupts are disabled upon entry - depending on if the
@@ -123,164 +94,17 @@ skip:
 
 asmlinkage void do_IRQ(int irq, struct pt_regs * regs)
 {
-	struct irqaction *action;
-	int do_random, cpu;
-        int ret, retval = 0;
-
-        cpu = smp_processor_id();
-        irq_enter();
-	kstat_cpu(cpu).irqs[irq - FIRST_IRQ]++;
-	action = irq_action[irq - FIRST_IRQ];
-
-        if (action) {
-                if (!(action->flags & SA_INTERRUPT))
-                        local_irq_enable();
-                do_random = 0;
-                do {
-			ret = action->handler(irq, action->dev_id, regs);
-			if (ret == IRQ_HANDLED)
-				do_random |= action->flags;
-                        retval |= ret;
-                        action = action->next;
-                } while (action);
-
-                if (retval != 1) {
-			if (retval) {
-				printk("irq event %d: bogus retval mask %x\n",
-					irq, retval);
-			} else {
-				printk("irq %d: nobody cared\n", irq);
-			}
-		}
-
-                if (do_random & SA_SAMPLE_RANDOM)
-                        add_interrupt_randomness(irq);
-		local_irq_disable();
-        }
-        irq_exit();
-}
-
-/* this function links in a handler into the chain of handlers for the
-   given irq, and if the irq has never been registred, the appropriate
-   handler is entered into the interrupt vector
-*/
-
-int setup_irq(int irq, struct irqaction * new)
-{
-	int shared = 0;
-	struct irqaction *old, **p;
-	unsigned long flags;
-
-	p = irq_action + irq - FIRST_IRQ;
-	if ((old = *p) != NULL) {
-		/* Can't share interrupts unless both agree to */
-		if (!(old->flags & new->flags & SA_SHIRQ))
-			return -EBUSY;
-
-		/* Can't share interrupts unless both are same type */
-		if ((old->flags ^ new->flags) & SA_INTERRUPT)
-			return -EBUSY;
-
-		/* add new interrupt at end of irq queue */
-		do {
-			p = &old->next;
-			old = *p;
-		} while (old);
-		shared = 1;
-	}
-
-	if (new->flags & SA_SAMPLE_RANDOM)
-		rand_initialize_irq(irq);
-
-	local_save_flags(flags);
-	local_irq_disable();
-	*p = new;
-
-	if (!shared) {
-		/* if the irq wasn't registred before, enter it into the vector table
-		   and unmask it physically 
-		*/
-		arch_setup_irq(irq);
-		unmask_irq(irq);
+	unsigned long sp;
+	irq_enter();
+	sp = rdsp();
+	if (unlikely((sp & (PAGE_SIZE - 1)) < (PAGE_SIZE/8))) {
+		printk("do_IRQ: stack overflow: %lX\n", sp);
+		show_stack(NULL, (unsigned long *)sp);
 	}
-	
-	local_irq_restore(flags);
-	return 0;
-}
-
-/* this function is called by a driver to register an irq handler
-   Valid flags:
-   SA_INTERRUPT -> it's a fast interrupt, handler called with irq disabled and
-                   no signal checking etc is performed upon exit
-   SA_SHIRQ -> the interrupt can be shared between different handlers, the handler
-                is required to check if the irq was "aimed" at it explicitely
-   SA_RANDOM -> the interrupt will add to the random generators entropy
-*/
-
-int request_irq(unsigned int irq, 
-		irqreturn_t (*handler)(int, void *, struct pt_regs *),
-		unsigned long irqflags, 
-		const char * devname,
-		void *dev_id)
-{
-	int retval;
-	struct irqaction * action;
-
-	if(!handler)
-		return -EINVAL;
-
-	/* allocate and fill in a handler structure and setup the irq */
-
-	action = (struct irqaction *)kmalloc(sizeof(struct irqaction), GFP_KERNEL);
-	if (!action)
-		return -ENOMEM;
-
-	action->handler = handler;
-	action->flags = irqflags;
-	cpus_clear(action->mask);
-	action->name = devname;
-	action->next = NULL;
-	action->dev_id = dev_id;
-
-	retval = setup_irq(irq, action);
-
-	if (retval)
-		kfree(action);
-	return retval;
-}
-
-EXPORT_SYMBOL(request_irq);
-		
-void free_irq(unsigned int irq, void *dev_id)
-{
-	struct irqaction * action, **p;
-	unsigned long flags;
-
-	if (irq >= NR_IRQS) {
-		printk("Trying to free IRQ%d\n",irq);
-		return;
-	}
-	for (p = irq - FIRST_IRQ + irq_action; (action = *p) != NULL; p = &action->next) {
-		if (action->dev_id != dev_id)
-			continue;
-
-		/* Found it - now free it */
-		local_save_flags(flags);
-		local_irq_disable();
-		*p = action->next;
-		if (!irq_action[irq - FIRST_IRQ]) {
-			mask_irq(irq);
-			arch_free_irq(irq);
-		}
-		local_irq_restore(flags);
-		kfree(action);
-		return;
-	}
-	printk("Trying to free free IRQ%d\n",irq);
+	__do_IRQ(irq, regs);
+        irq_exit();
 }
 
-EXPORT_SYMBOL(free_irq);
-
 void weird_irq(void)
 {
 	local_irq_disable();
@@ -288,10 +112,3 @@ void weird_irq(void)
 	while(1);
 }
 
-#if defined(CONFIG_PROC_FS) && defined(CONFIG_SYSCTL)
-/* Used by other archs to show/control IRQ steering during SMP */
-void __init
-init_irq_proc(void)
-{
-}
-#endif
diff --git a/arch/cris/kernel/module.c b/arch/cris/kernel/module.c
--- a/arch/cris/kernel/module.c
+++ b/arch/cris/kernel/module.c
@@ -32,7 +32,7 @@ void *module_alloc(unsigned long size)
 {
 	if (size == 0)
 		return NULL;
-	return vmalloc(size);
+	return vmalloc_exec(size);
 }
 
 
@@ -59,26 +59,8 @@ int apply_relocate(Elf32_Shdr *sechdrs,
 		   unsigned int relsec,
 		   struct module *me)
 {
-	unsigned int i;
-	Elf32_Rel *rel = (void *)sechdrs[relsec].sh_addr;
-	Elf32_Sym *sym;
-	uint32_t *location;
-
-	DEBUGP("Applying relocate section %u to %u\n", relsec,
-	       sechdrs[relsec].sh_info);
-	for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
-		/* This is where to make the change */
-		location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_offset
-			+ rel[i].r_offset;
-		/* This is the symbol it is referring to.  Note that all
-		   undefined symbols have been resolved.  */
-		sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
-			+ ELF32_R_SYM(rel[i].r_info);
-
-                /* We add the value into the location given */
-                *location += sym->st_value;
-	}
-	return 0;
+	printk(KERN_ERR "module %s: REL relocation unsupported\n", me->name);
+	return -ENOEXEC;
 }
 
 int apply_relocate_add(Elf32_Shdr *sechdrs,
@@ -90,7 +72,7 @@ int apply_relocate_add(Elf32_Shdr *sechd
   	unsigned int i;
 	Elf32_Rela *rela = (void *)sechdrs[relsec].sh_addr;
 
-	DEBUGP ("Applying relocate section %u to %u\n", relsec,
+	DEBUGP ("Applying add relocate section %u to %u\n", relsec,
 		sechdrs[relsec].sh_info);
 
 	for (i = 0; i < sechdrs[relsec].sh_size / sizeof (*rela); i++) {
@@ -103,7 +85,18 @@ int apply_relocate_add(Elf32_Shdr *sechd
 		Elf32_Sym *sym
 			= ((Elf32_Sym *)sechdrs[symindex].sh_addr
 			   + ELF32_R_SYM (rela[i].r_info));
-		*loc = sym->st_value + rela[i].r_addend;
+		switch (ELF32_R_TYPE(rela[i].r_info)) {
+		case R_CRIS_32:
+			*loc = sym->st_value + rela[i].r_addend;
+			break;
+		case R_CRIS_32_PCREL:
+			*loc = sym->st_value - (unsigned)loc + rela[i].r_addend - 4;
+			 break;
+		default:
+			printk(KERN_ERR "module %s: Unknown relocation: %u\n",
+			       me->name, ELF32_R_TYPE(rela[i].r_info));
+			return -ENOEXEC;
+		}
 	}
 
 	return 0;
diff --git a/arch/cris/kernel/process.c b/arch/cris/kernel/process.c
--- a/arch/cris/kernel/process.c
+++ b/arch/cris/kernel/process.c
@@ -1,4 +1,4 @@
-/* $Id: process.c,v 1.17 2004/04/05 13:53:48 starvik Exp $
+/* $Id: process.c,v 1.21 2005/03/04 08:16:17 starvik Exp $
  * 
  *  linux/arch/cris/kernel/process.c
  *
@@ -8,6 +8,18 @@
  *  Authors:   Bjorn Wesen (bjornw@axis.com)
  *
  *  $Log: process.c,v $
+ *  Revision 1.21  2005/03/04 08:16:17  starvik
+ *  Merge of Linux 2.6.11.
+ *
+ *  Revision 1.20  2005/01/18 05:57:22  starvik
+ *  Renamed hlt_counter to cris_hlt_counter and made it global.
+ *
+ *  Revision 1.19  2004/10/19 13:07:43  starvik
+ *  Merge of Linux 2.6.9
+ *
+ *  Revision 1.18  2004/08/16 12:37:23  starvik
+ *  Merge of Linux 2.6.8
+ *
  *  Revision 1.17  2004/04/05 13:53:48  starvik
  *  Merge of Linux 2.6.5
  *
@@ -113,6 +125,7 @@
 #include <linux/user.h>
 #include <linux/elfcore.h>
 #include <linux/mqueue.h>
+#include <linux/reboot.h>
 
 //#define DEBUG
 
@@ -160,18 +173,18 @@ EXPORT_SYMBOL(init_task);
  * region by enable_hlt/disable_hlt.
  */
 
-static int hlt_counter=0;
+int cris_hlt_counter=0;
 
 void disable_hlt(void)
 {
-	hlt_counter++;
+	cris_hlt_counter++;
 }
 
 EXPORT_SYMBOL(disable_hlt);
 
 void enable_hlt(void)
 {
-	hlt_counter--;
+	cris_hlt_counter--;
 }
 
 EXPORT_SYMBOL(enable_hlt);
@@ -194,27 +207,28 @@ void cpu_idle (void)
 	/* endless idle loop with no priority at all */
 	while (1) {
 		while (!need_resched()) {
-			void (*idle)(void) = pm_idle;
-
+			void (*idle)(void);
+			/*
+			 * Mark this as an RCU critical section so that
+			 * synchronize_kernel() in the unload path waits
+			 * for our completion.
+			 */
+			idle = pm_idle;
 			if (!idle)
 				idle = default_idle;
-
 			idle();
 		}
 		schedule();
 	}
-
 }
 
 void hard_reset_now (void);
 
-void machine_restart(void)
+void machine_restart(char *cmd)
 {
 	hard_reset_now();
 }
 
-EXPORT_SYMBOL(machine_restart);
-
 /*
  * Similar to machine_power_off, but don't shut off power.  Add code
  * here to freeze the system for e.g. post-mortem debug purpose when
@@ -225,16 +239,12 @@ void machine_halt(void)
 {
 }
 
-EXPORT_SYMBOL(machine_halt);
-
 /* If or when software power-off is implemented, add code here.  */
 
 void machine_power_off(void)
 {
 }
 
-EXPORT_SYMBOL(machine_power_off);
-
 /*
  * When a process does an "exec", machine state like FPU and debug
  * registers need to be reset.  This is a hook function for that.
diff --git a/arch/cris/kernel/profile.c b/arch/cris/kernel/profile.c
new file mode 100644
--- /dev/null
+++ b/arch/cris/kernel/profile.c
@@ -0,0 +1,73 @@
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/proc_fs.h>
+#include <linux/types.h>
+#include <asm/ptrace.h>
+#include <asm/uaccess.h>
+
+#define SAMPLE_BUFFER_SIZE 8192
+
+static char* sample_buffer;
+static char* sample_buffer_pos;
+static int prof_running = 0;
+
+void
+cris_profile_sample(struct pt_regs* regs)
+{
+  if (!prof_running)
+    return;
+  if (user_mode(regs))
+    *(unsigned int*)sample_buffer_pos = current->pid;
+  else
+    *(unsigned int*)sample_buffer_pos = 0;
+  *(unsigned int*)(sample_buffer_pos + 4) = instruction_pointer(regs);
+  sample_buffer_pos += 8;
+  if (sample_buffer_pos == sample_buffer + SAMPLE_BUFFER_SIZE)
+    sample_buffer_pos = sample_buffer;
+}
+
+static ssize_t
+read_cris_profile(struct file *file, char __user *buf, size_t count, loff_t *ppos)
+{
+  unsigned long p = *ppos;
+  if (p > SAMPLE_BUFFER_SIZE)
+    return 0;
+  if (p + count > SAMPLE_BUFFER_SIZE)
+    count = SAMPLE_BUFFER_SIZE - p;
+  if (copy_to_user(buf, sample_buffer + p,count))
+		return -EFAULT;
+  memset(sample_buffer + p, 0, count);
+  *ppos += count;
+  return count;
+}
+
+static ssize_t
+write_cris_profile(struct file *file, const char __user *buf,
+              size_t count, loff_t *ppos)
+{
+  sample_buffer_pos = sample_buffer;
+  memset(sample_buffer, 0, SAMPLE_BUFFER_SIZE);
+}
+
+static struct file_operations cris_proc_profile_operations = {
+	.read		= read_cris_profile,
+	.write		= write_cris_profile,
+};
+
+static int
+__init init_cris_profile(void)
+{
+  struct proc_dir_entry *entry;
+  sample_buffer = (char*)kmalloc(SAMPLE_BUFFER_SIZE, GFP_KERNEL);
+  sample_buffer_pos = sample_buffer;
+  entry = create_proc_entry("system_profile", S_IWUSR | S_IRUGO, NULL);
+  if (entry) {
+    entry->proc_fops = &cris_proc_profile_operations;
+    entry->size = SAMPLE_BUFFER_SIZE;
+  }
+  prof_running = 1;
+  return 0;
+}
+
+__initcall(init_cris_profile);
diff --git a/arch/cris/kernel/ptrace.c b/arch/cris/kernel/ptrace.c
--- a/arch/cris/kernel/ptrace.c
+++ b/arch/cris/kernel/ptrace.c
@@ -8,6 +8,12 @@
  * Authors:   Bjorn Wesen
  *
  * $Log: ptrace.c,v $
+ * Revision 1.10  2004/09/22 11:50:01  orjanf
+ * * Moved get_reg/put_reg to arch-specific files.
+ * * Added functions to access debug registers (CRISv32).
+ * * Added support for PTRACE_SINGLESTEP (CRISv32).
+ * * Added S flag to CCS_MASK (CRISv32).
+ *
  * Revision 1.9  2003/07/04 12:56:11  tobiasa
  * Moved arch-specific code to arch-specific files.
  *
@@ -72,37 +78,6 @@
 #include <asm/system.h>
 #include <asm/processor.h>
 
-/*
- * Get contents of register REGNO in task TASK.
- */
-inline long get_reg(struct task_struct *task, unsigned int regno)
-{
-	/* USP is a special case, it's not in the pt_regs struct but
-	 * in the tasks thread struct
-	 */
-
-	if (regno == PT_USP)
-		return task->thread.usp;
-	else if (regno < PT_MAX)
-		return ((unsigned long *)user_regs(task->thread_info))[regno];
-	else
-		return 0;
-}
-
-/*
- * Write contents of register REGNO in task TASK.
- */
-inline int put_reg(struct task_struct *task, unsigned int regno,
-			  unsigned long data)
-{
-	if (regno == PT_USP)
-		task->thread.usp = data;
-	else if (regno < PT_MAX)
-		((unsigned long *)user_regs(task->thread_info))[regno] = data;
-	else
-		return -1;
-	return 0;
-}
 
 /* notification of userspace execution resumption
  * - triggered by current->work.notify_resume
diff --git a/arch/cris/kernel/setup.c b/arch/cris/kernel/setup.c
--- a/arch/cris/kernel/setup.c
+++ b/arch/cris/kernel/setup.c
@@ -17,6 +17,7 @@
 #include <asm/pgtable.h>
 #include <linux/seq_file.h>
 #include <linux/tty.h>
+#include <linux/utsname.h>
 
 #include <asm/setup.h>
 
@@ -29,7 +30,7 @@ struct screen_info screen_info;
 extern int root_mountflags;
 extern char _etext, _edata, _end;
 
-static char command_line[COMMAND_LINE_SIZE] = { 0, };
+char cris_command_line[COMMAND_LINE_SIZE] = { 0, };
 
 extern const unsigned long text_start, edata; /* set by the linker script */
 extern unsigned long dram_start, dram_end;
@@ -147,34 +148,35 @@ setup_arch(char **cmdline_p)
 
 	paging_init();
 
-	/* We don't use a command line yet, so just re-initialize it without
-	   saving anything that might be there.  */
-
-	*cmdline_p = command_line;
+	*cmdline_p = cris_command_line;
 
 #ifdef CONFIG_ETRAX_CMDLINE
-	strlcpy(command_line, CONFIG_ETRAX_CMDLINE, COMMAND_LINE_SIZE);
-	command_line[COMMAND_LINE_SIZE - 1] = '\0';
+        if (!strcmp(cris_command_line, "")) {
+		strlcpy(cris_command_line, CONFIG_ETRAX_CMDLINE, COMMAND_LINE_SIZE);
+		cris_command_line[COMMAND_LINE_SIZE - 1] = '\0';
+	}
+#endif
 
 	/* Save command line for future references. */
-	memcpy(saved_command_line, command_line, COMMAND_LINE_SIZE);
+	memcpy(saved_command_line, cris_command_line, COMMAND_LINE_SIZE);
 	saved_command_line[COMMAND_LINE_SIZE - 1] = '\0';
-#endif
 
 	/* give credit for the CRIS port */
 	show_etrax_copyright();
+
+	/* Setup utsname */
+	strcpy(system_utsname.machine, cris_machine_name);
 }
 
 static void *c_start(struct seq_file *m, loff_t *pos)
 {
-	/* We only got one CPU... */
-	return *pos < 1 ? (void *)1 : NULL;
+	return *pos < NR_CPUS ? (void *)(int)(*pos + 1): NULL;
 }
 
 static void *c_next(struct seq_file *m, void *v, loff_t *pos)
 {
 	++*pos;
-	return NULL;
+	return c_start(m, pos);
 }
 
 static void c_stop(struct seq_file *m, void *v)
diff --git a/arch/cris/kernel/time.c b/arch/cris/kernel/time.c
--- a/arch/cris/kernel/time.c
+++ b/arch/cris/kernel/time.c
@@ -1,4 +1,4 @@
-/* $Id: time.c,v 1.14 2004/06/01 05:38:11 starvik Exp $
+/* $Id: time.c,v 1.18 2005/03/04 08:16:17 starvik Exp $
  *
  *  linux/arch/cris/kernel/time.c
  *
@@ -30,6 +30,7 @@
 #include <linux/bcd.h>
 #include <linux/timex.h>
 #include <linux/init.h>
+#include <linux/profile.h>
 
 u64 jiffies_64 = INITIAL_JIFFIES;
 
@@ -214,6 +215,21 @@ update_xtime_from_cmos(void)
 	}
 }
 
+extern void cris_profile_sample(struct pt_regs* regs);
+
+void
+cris_do_profile(struct pt_regs* regs)
+{
+
+#if CONFIG_SYSTEM_PROFILER
+        cris_profile_sample(regs);
+#endif
+
+#if CONFIG_PROFILING
+        profile_tick(CPU_PROFILING, regs);
+#endif
+}
+
 /*
  * Scheduler clock - returns current time in nanosec units.
  */
diff --git a/arch/cris/kernel/traps.c b/arch/cris/kernel/traps.c
--- a/arch/cris/kernel/traps.c
+++ b/arch/cris/kernel/traps.c
@@ -1,4 +1,4 @@
-/* $Id: traps.c,v 1.9 2004/05/11 12:28:26 starvik Exp $
+/* $Id: traps.c,v 1.11 2005/01/24 16:03:19 orjanf Exp $
  *
  *  linux/arch/cris/traps.c
  *
@@ -20,13 +20,15 @@
 
 static int kstack_depth_to_print = 24;
 
+extern int raw_printk(const char *fmt, ...);
+
 void show_trace(unsigned long * stack)
 {
 	unsigned long addr, module_start, module_end;
 	extern char _stext, _etext;
 	int i;
 
-        printk("\nCall Trace: ");
+        raw_printk("\nCall Trace: ");
 
         i = 1;
         module_start = VMALLOC_START;
@@ -37,7 +39,7 @@ void show_trace(unsigned long * stack)
 			/* This message matches "failing address" marked
 			   s390 in ksymoops, so lines containing it will
 			   not be filtered out by ksymoops.  */
-			printk ("Failing address 0x%lx\n", (unsigned long)stack);
+			raw_printk ("Failing address 0x%lx\n", (unsigned long)stack);
 			break;
 		}
 		stack++;
@@ -54,8 +56,8 @@ void show_trace(unsigned long * stack)
                      (addr <= (unsigned long) &_etext)) ||
                     ((addr >= module_start) && (addr <= module_end))) {
                         if (i && ((i % 8) == 0))
-                                printk("\n       ");
-                        printk("[<%08lx>] ", addr);
+                                raw_printk("\n       ");
+                        raw_printk("[<%08lx>] ", addr);
                         i++;
                 }
         }
@@ -96,25 +98,59 @@ show_stack(struct task_struct *task, uns
 
         stack = sp;
 
-	printk("\nStack from %08lx:\n       ", (unsigned long)stack);
+	raw_printk("\nStack from %08lx:\n       ", (unsigned long)stack);
         for(i = 0; i < kstack_depth_to_print; i++) {
                 if (((long) stack & (THREAD_SIZE-1)) == 0)
                         break;
                 if (i && ((i % 8) == 0))
-                        printk("\n       ");
+                        raw_printk("\n       ");
 		if (__get_user (addr, stack)) {
 			/* This message matches "failing address" marked
 			   s390 in ksymoops, so lines containing it will
 			   not be filtered out by ksymoops.  */
-			printk ("Failing address 0x%lx\n", (unsigned long)stack);
+			raw_printk ("Failing address 0x%lx\n", (unsigned long)stack);
 			break;
 		}
 		stack++;
-		printk("%08lx ", addr);
+		raw_printk("%08lx ", addr);
         }
 	show_trace(sp);
 }
 
+static void (*nmi_handler)(struct pt_regs*);
+extern void arch_enable_nmi(void);
+
+void set_nmi_handler(void (*handler)(struct pt_regs*))
+{
+  nmi_handler = handler;
+  arch_enable_nmi();
+}
+
+void handle_nmi(struct pt_regs* regs)
+{
+  if (nmi_handler)
+    nmi_handler(regs);
+}
+
+#ifdef CONFIG_DEBUG_NMI_OOPS
+void oops_nmi_handler(struct pt_regs* regs)
+{
+  stop_watchdog();
+  raw_printk("NMI!\n");
+  show_registers(regs);
+}
+
+static int
+__init oops_nmi_register(void)
+{
+  set_nmi_handler(oops_nmi_handler);
+  return 0;
+}
+
+__initcall(oops_nmi_register);
+
+#endif
+
 #if 0
 /* displays a short stack trace */
 
@@ -123,9 +159,9 @@ show_stack()
 {
 	unsigned long *sp = (unsigned long *)rdusp();
 	int i;
-	printk("Stack dump [0x%08lx]:\n", (unsigned long)sp);
+	raw_printk("Stack dump [0x%08lx]:\n", (unsigned long)sp);
 	for(i = 0; i < 16; i++)
-		printk("sp + %d: 0x%08lx\n", i*4, sp[i]);
+		raw_printk("sp + %d: 0x%08lx\n", i*4, sp[i]);
 	return 0;
 }
 #endif
@@ -142,3 +178,9 @@ trap_init(void)
 {
 	/* Nothing needs to be done */
 }
+
+void spinning_cpu(void* addr)
+{
+  raw_printk("CPU %d spinning on %X\n", smp_processor_id(), addr);
+  dump_stack();
+}
diff --git a/arch/cris/mm/fault.c b/arch/cris/mm/fault.c
--- a/arch/cris/mm/fault.c
+++ b/arch/cris/mm/fault.c
@@ -6,6 +6,38 @@
  *  Authors:  Bjorn Wesen 
  * 
  *  $Log: fault.c,v $
+ *  Revision 1.20  2005/03/04 08:16:18  starvik
+ *  Merge of Linux 2.6.11.
+ *
+ *  Revision 1.19  2005/01/14 10:07:59  starvik
+ *  Fixed warning.
+ *
+ *  Revision 1.18  2005/01/12 08:10:14  starvik
+ *  Readded the change of frametype when handling kernel page fault fixup
+ *  for v10. This is necessary to avoid that the CPU remakes the faulting
+ *  access.
+ *
+ *  Revision 1.17  2005/01/11 13:53:05  starvik
+ *  Use raw_printk.
+ *
+ *  Revision 1.16  2004/12/17 11:39:41  starvik
+ *  SMP support.
+ *
+ *  Revision 1.15  2004/11/23 18:36:18  starvik
+ *  Stack is now non-executable.
+ *  Signal handler trampolines are placed in a reserved page mapped into all
+ *  processes.
+ *
+ *  Revision 1.14  2004/11/23 07:10:21  starvik
+ *  Moved find_fixup_code to generic code.
+ *
+ *  Revision 1.13  2004/11/23 07:00:54  starvik
+ *  Actually use the execute permission bit in the MMU. This makes it possible
+ *  to prevent e.g. attacks where executable code is put on the stack.
+ *
+ *  Revision 1.12  2004/09/29 06:16:04  starvik
+ *  Use instruction_pointer
+ *
  *  Revision 1.11  2004/05/14 07:58:05  starvik
  *  Merge of changes from 2.4
  *
@@ -103,6 +135,7 @@
 
 extern int find_fixup_code(struct pt_regs *);
 extern void die_if_kernel(const char *, struct pt_regs *, long);
+extern int raw_printk(const char *fmt, ...);
 
 /* debug of low-level TLB reload */
 #undef DEBUG
@@ -118,7 +151,8 @@ extern void die_if_kernel(const char *, 
 
 /* current active page directory */
 
-volatile pgd_t *current_pgd;
+volatile DEFINE_PER_CPU(pgd_t *,current_pgd);
+unsigned long cris_signal_return_page;
 
 /*
  * This routine handles page faults.  It determines the address,
@@ -146,8 +180,9 @@ do_page_fault(unsigned long address, str
 	struct vm_area_struct * vma;
 	siginfo_t info;
 
-        D(printk("Page fault for %X at %X, prot %d write %d\n",
-                 address, regs->erp, protection, writeaccess));
+        D(printk("Page fault for %lX on %X at %lX, prot %d write %d\n",
+                 address, smp_processor_id(), instruction_pointer(regs),
+                 protection, writeaccess));
 
 	tsk = current;
 
@@ -175,8 +210,19 @@ do_page_fault(unsigned long address, str
 	    !user_mode(regs))
 		goto vmalloc_fault;
 
+	/* When stack execution is not allowed we store the signal
+	 * trampolines in the reserved cris_signal_return_page.
+	 * Handle this in the exact same way as vmalloc (we know
+	 * that the mapping is there and is valid so no need to
+	 * call handle_mm_fault).
+	 */
+	if (cris_signal_return_page &&
+	    address == cris_signal_return_page &&
+	    !protection && user_mode(regs))
+		goto vmalloc_fault;
+
 	/* we can and should enable interrupts at this point */
-	sti();
+	local_irq_enable();
 
 	mm = tsk->mm;
 	info.si_code = SEGV_MAPERR;
@@ -220,7 +266,10 @@ do_page_fault(unsigned long address, str
 
 	/* first do some preliminary protection checks */
 
-	if (writeaccess) {
+	if (writeaccess == 2){
+		if (!(vma->vm_flags & VM_EXEC))
+			goto bad_area;
+	} else if (writeaccess == 1) {
 		if (!(vma->vm_flags & VM_WRITE))
 			goto bad_area;
 	} else {
@@ -234,14 +283,14 @@ do_page_fault(unsigned long address, str
 	 * the fault.
 	 */
 
-	switch (handle_mm_fault(mm, vma, address, writeaccess)) {
-	case 1:
+	switch (handle_mm_fault(mm, vma, address, writeaccess & 1)) {
+	case VM_FAULT_MINOR:
 		tsk->min_flt++;
 		break;
-	case 2:
+	case VM_FAULT_MAJOR:
 		tsk->maj_flt++;
 		break;
-	case 0:
+	case VM_FAULT_SIGBUS:
 		goto do_sigbus;
 	default:
 		goto out_of_memory;
@@ -292,10 +341,10 @@ do_page_fault(unsigned long address, str
 	 */
 
 	if ((unsigned long) (address) < PAGE_SIZE)
-		printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference");
+		raw_printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference");
 	else
-		printk(KERN_ALERT "Unable to handle kernel access");
-	printk(" at virtual address %08lx\n",address);
+		raw_printk(KERN_ALERT "Unable to handle kernel access");
+	raw_printk(" at virtual address %08lx\n",address);
 
 	die_if_kernel("Oops", regs, (writeaccess << 1) | protection);
 
@@ -346,10 +395,11 @@ vmalloc_fault:
 
 		int offset = pgd_index(address);
 		pgd_t *pgd, *pgd_k;
+		pud_t *pud, *pud_k;
 		pmd_t *pmd, *pmd_k;
 		pte_t *pte_k;
 
-		pgd = (pgd_t *)current_pgd + offset;
+		pgd = (pgd_t *)per_cpu(current_pgd, smp_processor_id()) + offset;
 		pgd_k = init_mm.pgd + offset;
 
 		/* Since we're two-level, we don't need to do both
@@ -364,8 +414,13 @@ vmalloc_fault:
 		 * it exists.
 		 */
 
-		pmd = pmd_offset(pgd, address);
-		pmd_k = pmd_offset(pgd_k, address);
+		pud = pud_offset(pgd, address);
+		pud_k = pud_offset(pgd_k, address);
+		if (!pud_present(*pud_k))
+			goto no_context;
+
+		pmd = pmd_offset(pud, address);
+		pmd_k = pmd_offset(pud_k, address);
 
 		if (!pmd_present(*pmd_k))
 			goto bad_area_nosemaphore;
@@ -385,3 +440,19 @@ vmalloc_fault:
 		return;
 	}
 }
+
+/* Find fixup code. */
+int
+find_fixup_code(struct pt_regs *regs)
+{
+	const struct exception_table_entry *fixup;
+
+	if ((fixup = search_exception_tables(instruction_pointer(regs))) != 0) {
+		/* Adjust the instruction pointer in the stackframe. */
+		instruction_pointer(regs) = fixup->fixup;
+		arch_fixup(regs);
+		return 1;
+	}
+
+	return 0;
+}
diff --git a/arch/cris/mm/ioremap.c b/arch/cris/mm/ioremap.c
--- a/arch/cris/mm/ioremap.c
+++ b/arch/cris/mm/ioremap.c
@@ -14,9 +14,10 @@
 #include <asm/pgalloc.h>
 #include <asm/cacheflush.h>
 #include <asm/tlbflush.h>
+#include <asm/arch/memmap.h>
 
 extern inline void remap_area_pte(pte_t * pte, unsigned long address, unsigned long size,
-	unsigned long phys_addr, unsigned long flags)
+	unsigned long phys_addr, pgprot_t prot)
 {
 	unsigned long end;
 
@@ -31,9 +32,7 @@ extern inline void remap_area_pte(pte_t 
 			printk("remap_area_pte: page already exists\n");
 			BUG();
 		}
-		set_pte(pte, mk_pte_phys(phys_addr, __pgprot(_PAGE_PRESENT | __READABLE | 
-							     __WRITEABLE | _PAGE_GLOBAL |
-							     _PAGE_KERNEL | flags)));
+		set_pte(pte, mk_pte_phys(phys_addr, prot));
 		address += PAGE_SIZE;
 		phys_addr += PAGE_SIZE;
 		pte++;
@@ -41,7 +40,7 @@ extern inline void remap_area_pte(pte_t 
 }
 
 static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size,
-	unsigned long phys_addr, unsigned long flags)
+	unsigned long phys_addr, pgprot_t prot)
 {
 	unsigned long end;
 
@@ -56,7 +55,7 @@ static inline int remap_area_pmd(pmd_t *
 		pte_t * pte = pte_alloc_kernel(&init_mm, pmd, address);
 		if (!pte)
 			return -ENOMEM;
-		remap_area_pte(pte, address, end - address, address + phys_addr, flags);
+		remap_area_pte(pte, address, end - address, address + phys_addr, prot);
 		address = (address + PMD_SIZE) & PMD_MASK;
 		pmd++;
 	} while (address && (address < end));
@@ -64,7 +63,7 @@ static inline int remap_area_pmd(pmd_t *
 }
 
 static int remap_area_pages(unsigned long address, unsigned long phys_addr,
-				 unsigned long size, unsigned long flags)
+				 unsigned long size, pgprot_t prot)
 {
 	int error;
 	pgd_t * dir;
@@ -77,13 +76,19 @@ static int remap_area_pages(unsigned lon
 		BUG();
 	spin_lock(&init_mm.page_table_lock);
 	do {
+		pud_t *pud;
 		pmd_t *pmd;
-		pmd = pmd_alloc(&init_mm, dir, address);
+
 		error = -ENOMEM;
+		pud = pud_alloc(&init_mm, dir, address);
+		if (!pud)
+			break;
+		pmd = pmd_alloc(&init_mm, pud, address);
+
 		if (!pmd)
 			break;
 		if (remap_area_pmd(pmd, address, end - address,
-				   phys_addr + address, flags))
+				   phys_addr + address, prot))
 			break;
 		error = 0;
 		address = (address + PGDIR_SIZE) & PGDIR_MASK;
@@ -107,9 +112,9 @@ static int remap_area_pages(unsigned lon
  * have to convert them into an offset in a page-aligned mapping, but the
  * caller shouldn't need to know that small detail.
  */
-void * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags)
+void __iomem * __ioremap_prot(unsigned long phys_addr, unsigned long size, pgprot_t prot)
 {
-	void * addr;
+	void __iomem * addr;
 	struct vm_struct * area;
 	unsigned long offset, last_addr;
 
@@ -131,15 +136,36 @@ void * __ioremap(unsigned long phys_addr
 	area = get_vm_area(size, VM_IOREMAP);
 	if (!area)
 		return NULL;
-	addr = area->addr;
-	if (remap_area_pages((unsigned long) addr, phys_addr, size, flags)) {
-		vfree(addr);
+	addr = (void __iomem *)area->addr;
+	if (remap_area_pages((unsigned long) addr, phys_addr, size, prot)) {
+		vfree((void __force *)addr);
 		return NULL;
 	}
-	return (void *) (offset + (char *)addr);
+	return (void __iomem *) (offset + (char __iomem *)addr);
+}
+
+void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags)
+{
+	return __ioremap_prot(phys_addr, size,
+		              __pgprot(_PAGE_PRESENT | __READABLE |
+				       __WRITEABLE | _PAGE_GLOBAL |
+				       _PAGE_KERNEL | flags));
+}
+
+/**
+ * ioremap_nocache     -   map bus memory into CPU space
+ * @offset:    bus address of the memory
+ * @size:      size of the resource to map
+ *
+ * Must be freed with iounmap.
+ */
+
+void __iomem *ioremap_nocache (unsigned long phys_addr, unsigned long size)
+{
+        return __ioremap(phys_addr | MEM_NON_CACHEABLE, size, 0);
 }
 
-void iounmap(void *addr)
+void iounmap(volatile void __iomem *addr)
 {
 	if (addr > high_memory)
 		return vfree((void *) (PAGE_MASK & (unsigned long) addr));
diff --git a/arch/cris/mm/tlb.c b/arch/cris/mm/tlb.c
--- a/arch/cris/mm/tlb.c
+++ b/arch/cris/mm/tlb.c
@@ -29,18 +29,6 @@
 struct mm_struct *page_id_map[NUM_PAGEID];
 static int map_replace_ptr = 1;  /* which page_id_map entry to replace next */
 
-/*
- * Initialize the context related info for a new mm_struct
- * instance.
- */
-
-int
-init_new_context(struct task_struct *tsk, struct mm_struct *mm)
-{
-	mm->context = NO_CONTEXT;
-	return 0;
-}
-
 /* the following functions are similar to those used in the PPC port */
 
 static inline void
@@ -60,12 +48,12 @@ alloc_context(struct mm_struct *mm)
 		 */
 		flush_tlb_mm(old_mm);
 
-		old_mm->context = NO_CONTEXT;
+		old_mm->context.page_id = NO_CONTEXT;
 	}
 
 	/* insert it into the page_id_map */
 
-	mm->context = map_replace_ptr;
+	mm->context.page_id = map_replace_ptr;
 	page_id_map[map_replace_ptr] = mm;
 
 	map_replace_ptr++;
@@ -81,7 +69,7 @@ alloc_context(struct mm_struct *mm)
 void
 get_mmu_context(struct mm_struct *mm)
 {
-	if(mm->context == NO_CONTEXT)
+	if(mm->context.page_id == NO_CONTEXT)
 		alloc_context(mm);
 }
 
@@ -96,11 +84,10 @@ get_mmu_context(struct mm_struct *mm)
 void
 destroy_context(struct mm_struct *mm)
 {
-	if(mm->context != NO_CONTEXT) {
-		D(printk("destroy_context %d (%p)\n", mm->context, mm));
+	if(mm->context.page_id != NO_CONTEXT) {
+		D(printk("destroy_context %d (%p)\n", mm->context.page_id, mm));
 		flush_tlb_mm(mm);  /* TODO this might be redundant ? */
-		page_id_map[mm->context] = NULL;
-		/* mm->context = NO_CONTEXT; redundant.. mm will be freed */
+		page_id_map[mm->context.page_id] = NULL;
 	}
 }
 
diff --git a/arch/frv/Kconfig b/arch/frv/Kconfig
--- a/arch/frv/Kconfig
+++ b/arch/frv/Kconfig
@@ -74,6 +74,8 @@ config HIGHPTE
 	  with a lot of RAM, this can be wasteful of precious low memory.
 	  Setting this option will put user-space page tables in high memory.
 
+source "mm/Kconfig"
+
 choice
 	prompt "uClinux kernel load address"
 	depends on !MMU
@@ -344,6 +346,8 @@ source "fs/Kconfig.binfmt"
 
 endmenu
 
+source "net/Kconfig"
+
 source "drivers/Kconfig"
 
 source "fs/Kconfig"
diff --git a/arch/frv/defconfig b/arch/frv/defconfig
new file mode 100644
--- /dev/null
+++ b/arch/frv/defconfig
@@ -0,0 +1,627 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.11.8
+# Fri May 13 17:16:03 2005
+#
+CONFIG_FRV=y
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+# CONFIG_GENERIC_CALIBRATE_DELAY is not set
+# CONFIG_GENERIC_HARDIRQS is not set
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+# CONFIG_HOTPLUG is not set
+# CONFIG_KOBJECT_UEVENT is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# Fujitsu FR-V system setup
+#
+CONFIG_MMU=y
+CONFIG_FRV_OUTOFLINE_ATOMIC_OPS=y
+CONFIG_HIGHMEM=y
+CONFIG_HIGHPTE=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_FRV_DEFL_CACHE_WBACK is not set
+# CONFIG_FRV_DEFL_CACHE_WBEHIND is not set
+CONFIG_FRV_DEFL_CACHE_WTHRU=y
+# CONFIG_FRV_DEFL_CACHE_DISABLED is not set
+
+#
+# CPU core support
+#
+CONFIG_CPU_FR451=y
+CONFIG_CPU_FR451_COMPILE=y
+CONFIG_FRV_L1_CACHE_SHIFT=5
+CONFIG_MB93091_VDK=y
+# CONFIG_MB93093_PDK is not set
+CONFIG_MB93090_MB00=y
+# CONFIG_MB93091_NO_MB is not set
+# CONFIG_GPREL_DATA_8 is not set
+CONFIG_GPREL_DATA_4=y
+# CONFIG_GPREL_DATA_NONE is not set
+CONFIG_PCI=y
+# CONFIG_PCI_LEGACY_PROC is not set
+# CONFIG_PCI_NAMES is not set
+# CONFIG_PCI_DEBUG is not set
+# CONFIG_PCMCIA is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+
+#
+# Executable formats
+#
+# CONFIG_BINFMT_ELF is not set
+CONFIG_BINFMT_ELF_FDPIC=y
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+# CONFIG_STANDALONE is not set
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+# CONFIG_FORK_CONNECTOR is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_RAM is not set
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CDROM_PKTCDVD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_SCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Networking support
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_TUNNEL is not set
+# CONFIG_IP_TCPDIAG is not set
+# CONFIG_IP_TCPDIAG_IPV6 is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_KGDBOE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NETPOLL_RX is not set
+# CONFIG_NETPOLL_TRAP is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+CONFIG_NET_PCI=y
+# CONFIG_PCNET32 is not set
+# CONFIG_AMD8111_ETH is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_B44 is not set
+# CONFIG_FORCEDETH is not set
+# CONFIG_DGRS is not set
+# CONFIG_EEPRO100 is not set
+# CONFIG_E100 is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+CONFIG_NE2K_PCI=y
+# CONFIG_8139CP is not set
+# CONFIG_8139TOO 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
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_VIA_VELOCITY is not set
+# CONFIG_TIGON3 is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_CHELSIO_T1 is not set
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+# CONFIG_INPUT is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=1
+CONFIG_SERIAL_8250_EXTENDED=y
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_MULTIPORT is not set
+# CONFIG_SERIAL_8250_RSA is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+# CONFIG_USB is not set
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# File systems
+#
+# CONFIG_EXT2_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_REISER4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+
+#
+# XFS support
+#
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+# CONFIG_PROC_KCORE is not set
+CONFIG_SYSFS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVPTS_FS_XATTR is not set
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_XATTR is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+# CONFIG_RELAYFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_MAGIC_SYSRQ is not set
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_HIGHMEM is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_FRAME_POINTER is not set
+# CONFIG_EARLY_PRINTK is not set
+CONFIG_DEBUG_STACKOVERFLOW=y
+# CONFIG_DEBUG_PAGEALLOC is not set
+# CONFIG_GDBSTUB is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
diff --git a/arch/frv/kernel/setup.c b/arch/frv/kernel/setup.c
--- a/arch/frv/kernel/setup.c
+++ b/arch/frv/kernel/setup.c
@@ -790,12 +790,10 @@ void __init setup_arch(char **cmdline_p)
 #ifndef CONFIG_GDBSTUB_UART0
 	__reg(UART0_BASE + UART_IER * 8) = 0;
 	early_serial_setup(&__frv_uart0);
-//	register_serial(&__frv_uart0);
 #endif
 #ifndef CONFIG_GDBSTUB_UART1
 	__reg(UART1_BASE + UART_IER * 8) = 0;
 	early_serial_setup(&__frv_uart1);
-//	register_serial(&__frv_uart1);
 #endif
 
 #if defined(CONFIG_CHR_DEV_FLASH) || defined(CONFIG_BLK_DEV_FLASH)
diff --git a/arch/frv/kernel/signal.c b/arch/frv/kernel/signal.c
--- a/arch/frv/kernel/signal.c
+++ b/arch/frv/kernel/signal.c
@@ -536,10 +536,8 @@ int do_signal(struct pt_regs *regs, sigs
 	if (!user_mode(regs))
 		return 1;
 
-	if (current->flags & PF_FREEZE) {
-		refrigerator(0);
+	if (try_to_freeze())
 		goto no_signal;
-	}
 
 	if (!oldset)
 		oldset = &current->blocked;
diff --git a/arch/frv/mb93090-mb00/pci-irq.c b/arch/frv/mb93090-mb00/pci-irq.c
--- a/arch/frv/mb93090-mb00/pci-irq.c
+++ b/arch/frv/mb93090-mb00/pci-irq.c
@@ -60,7 +60,7 @@ void __init pcibios_fixup_irqs(void)
 	}
 }
 
-void __init pcibios_penalize_isa_irq(int irq)
+void __init pcibios_penalize_isa_irq(int irq, int active)
 {
 }
 
diff --git a/arch/frv/mm/fault.c b/arch/frv/mm/fault.c
--- a/arch/frv/mm/fault.c
+++ b/arch/frv/mm/fault.c
@@ -163,13 +163,13 @@ asmlinkage void do_page_fault(int datamm
 	 * the fault.
 	 */
 	switch (handle_mm_fault(mm, vma, ear0, write)) {
-	case 1:
+	case VM_FAULT_MINOR:
 		current->min_flt++;
 		break;
-	case 2:
+	case VM_FAULT_MAJOR:
 		current->maj_flt++;
 		break;
-	case 0:
+	case VM_FAULT_SIGBUS:
 		goto do_sigbus;
 	default:
 		goto out_of_memory;
diff --git a/arch/frv/mm/init.c b/arch/frv/mm/init.c
--- a/arch/frv/mm/init.c
+++ b/arch/frv/mm/init.c
@@ -169,7 +169,6 @@ void __init mem_init(void)
 		struct page *page = &mem_map[pfn];
 
 		ClearPageReserved(page);
-		set_bit(PG_highmem, &page->flags);
 		set_page_count(page, 1);
 		__free_page(page);
 		totalram_pages++;
diff --git a/arch/h8300/Kconfig b/arch/h8300/Kconfig
--- a/arch/h8300/Kconfig
+++ b/arch/h8300/Kconfig
@@ -55,6 +55,8 @@ source "fs/Kconfig.binfmt"
 
 endmenu
 
+source "net/Kconfig"
+
 source "drivers/base/Kconfig"
 
 source "drivers/mtd/Kconfig"
@@ -65,7 +67,7 @@ source "drivers/ide/Kconfig"
 
 source "arch/h8300/Kconfig.ide"
 
-source "net/Kconfig"
+source "drivers/net/Kconfig"
 
 #
 # input - input/joystick depends on it. As does USB.
@@ -179,6 +181,8 @@ source "drivers/serial/Kconfig"
 
 source "drivers/i2c/Kconfig"
 
+source "drivers/hwmon/Kconfig"
+
 source "drivers/usb/Kconfig"
 
 endmenu
diff --git a/arch/h8300/Kconfig.cpu b/arch/h8300/Kconfig.cpu
--- a/arch/h8300/Kconfig.cpu
+++ b/arch/h8300/Kconfig.cpu
@@ -180,4 +180,7 @@ config CPU_H8S
 config PREEMPT
 	bool "Preemptible Kernel"
 	default n
+
+source "mm/Kconfig"
+
 endmenu
diff --git a/arch/h8300/kernel/process.c b/arch/h8300/kernel/process.c
--- a/arch/h8300/kernel/process.c
+++ b/arch/h8300/kernel/process.c
@@ -90,8 +90,6 @@ void machine_restart(char * __unused)
 	__asm__("jmp @@0"); 
 }
 
-EXPORT_SYMBOL(machine_restart);
-
 void machine_halt(void)
 {
 	local_irq_disable();
@@ -99,8 +97,6 @@ void machine_halt(void)
 	for (;;);
 }
 
-EXPORT_SYMBOL(machine_halt);
-
 void machine_power_off(void)
 {
 	local_irq_disable();
@@ -108,8 +104,6 @@ void machine_power_off(void)
 	for (;;);
 }
 
-EXPORT_SYMBOL(machine_power_off);
-
 void show_regs(struct pt_regs * regs)
 {
 	printk("\nPC: %08lx  Status: %02x",
diff --git a/arch/h8300/kernel/signal.c b/arch/h8300/kernel/signal.c
--- a/arch/h8300/kernel/signal.c
+++ b/arch/h8300/kernel/signal.c
@@ -517,10 +517,8 @@ asmlinkage int do_signal(struct pt_regs 
 	if ((regs->ccr & 0x10))
 		return 1;
 
-	if (current->flags & PF_FREEZE) {
-		refrigerator(0);
+	if (try_to_freeze())
 		goto no_signal;
-	}
 
 	current->thread.esp0 = (unsigned long) regs;
 
diff --git a/arch/h8300/platform/h8300h/ptrace_h8300h.c b/arch/h8300/platform/h8300h/ptrace_h8300h.c
--- a/arch/h8300/platform/h8300h/ptrace_h8300h.c
+++ b/arch/h8300/platform/h8300h/ptrace_h8300h.c
@@ -245,12 +245,12 @@ static unsigned short *getnextpc(struct 
 						addr = h8300_get_reg(child, regno-1+PT_ER1);
 					return (unsigned short *)addr;
 				case relb:
-					if ((inst = 0x55) || isbranch(child,inst & 0x0f))
+					if (inst == 0x55 || isbranch(child,inst & 0x0f))
 						pc = (unsigned short *)((unsigned long)pc +
 								       ((signed char)(*fetch_p)));
 					return pc+1; /* skip myself */
 				case relw:
-					if ((inst = 0x5c) || isbranch(child,(*fetch_p & 0xf0) >> 4))
+					if (inst == 0x5c || isbranch(child,(*fetch_p & 0xf0) >> 4))
 						pc = (unsigned short *)((unsigned long)pc +
 								       ((signed short)(*(pc+1))));
 					return pc+2; /* skip myself */
diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig
--- a/arch/i386/Kconfig
+++ b/arch/i386/Kconfig
@@ -68,7 +68,6 @@ config X86_VOYAGER
 
 config X86_NUMAQ
 	bool "NUMAQ (IBM/Sequent)"
-	select DISCONTIGMEM
 	select NUMA
 	help
 	  This option is used for getting Linux to run on a (IBM/Sequent) NUMA
@@ -455,8 +454,9 @@ config HPET_TIMER
 	  Choose N to continue using the legacy 8254 timer.
 
 config HPET_EMULATE_RTC
-	bool "Provide RTC interrupt"
+	bool
 	depends on HPET_TIMER && RTC=y
+	default y
 
 config SMP
 	bool "Symmetric multi-processing support"
@@ -511,28 +511,7 @@ config SCHED_SMT
 	  cost of slightly increased overhead in some places. If unsure say
 	  N here.
 
-config PREEMPT
-	bool "Preemptible Kernel"
-	help
-	  This option reduces the latency of the kernel when reacting to
-	  real-time or interactive events by allowing a low priority process to
-	  be preempted even if it is in kernel mode executing a system call.
-	  This allows applications to run more reliably even when the system is
-	  under load.
-
-	  Say Y here if you are building a kernel for a desktop, embedded
-	  or real-time system.  Say N if you are unsure.
-
-config PREEMPT_BKL
-	bool "Preempt The Big Kernel Lock"
-	depends on PREEMPT
-	default y
-	help
-	  This option reduces the latency of the kernel by making the
-	  big kernel lock preemptible.
-
-	  Say Y here if you are building a kernel for a desktop system.
-	  Say N if you are unsure.
+source "kernel/Kconfig.preempt"
 
 config X86_UP_APIC
 	bool "Local APIC support on uniprocessors"
@@ -783,26 +762,49 @@ comment "NUMA (NUMA-Q) requires SMP, 64G
 comment "NUMA (Summit) requires SMP, 64GB highmem support, ACPI"
 	depends on X86_SUMMIT && (!HIGHMEM64G || !ACPI)
 
-config DISCONTIGMEM
-	bool
-	depends on NUMA
-	default y
-
 config HAVE_ARCH_BOOTMEM_NODE
 	bool
 	depends on NUMA
 	default y
 
-config HAVE_MEMORY_PRESENT
+config ARCH_HAVE_MEMORY_PRESENT
 	bool
 	depends on DISCONTIGMEM
 	default y
 
 config NEED_NODE_MEMMAP_SIZE
 	bool
-	depends on DISCONTIGMEM
+	depends on DISCONTIGMEM || SPARSEMEM
+	default y
+
+config HAVE_ARCH_ALLOC_REMAP
+	bool
+	depends on NUMA
 	default y
 
+config ARCH_DISCONTIGMEM_ENABLE
+	def_bool y
+	depends on NUMA
+
+config ARCH_DISCONTIGMEM_DEFAULT
+	def_bool y
+	depends on NUMA
+
+config ARCH_SPARSEMEM_ENABLE
+	def_bool y
+	depends on NUMA
+
+config ARCH_SELECT_MEMORY_MODEL
+	def_bool y
+	depends on ARCH_SPARSEMEM_ENABLE
+
+source "mm/Kconfig"
+
+config HAVE_ARCH_EARLY_PFN_TO_NID
+	bool
+	default y
+	depends on NUMA
+
 config HIGHPTE
 	bool "Allocate 3rd-level pagetables from highmem"
 	depends on HIGHMEM4G || HIGHMEM64G
@@ -939,6 +941,43 @@ config SECCOMP
 
 	  If unsure, say Y. Only embedded should say N here.
 
+source kernel/Kconfig.hz
+
+config PHYSICAL_START
+	hex "Physical address where the kernel is loaded" if EMBEDDED
+	default "0x100000"
+	help
+	  This gives the physical address where the kernel is loaded.
+	  Primarily used in the case of kexec on panic where the
+	  fail safe kernel needs to run at a different address than
+	  the panic-ed kernel.
+
+	  Don't change this unless you know what you are doing.
+
+config KEXEC
+	bool "kexec system call (EXPERIMENTAL)"
+	depends on EXPERIMENTAL
+	help
+	  kexec is a system call that implements the ability to shutdown your
+	  current kernel, and to start another kernel.  It is like a reboot
+	  but it is indepedent of the system firmware.   And like a reboot
+	  you can start any kernel with it, not just Linux.
+
+	  The name comes from the similiarity to the exec system call.
+
+	  It is an ongoing process to be certain the hardware in a machine
+	  is properly shutdown, so do not be surprised if this code does not
+	  initially work for you.  It may help to enable device hotplugging
+	  support.  As of this writing the exact hardware interface is
+	  strongly in flux, so no good recommendation can be made.
+
+config CRASH_DUMP
+	bool "kernel crash dumps (EXPERIMENTAL)"
+	depends on EMBEDDED
+	depends on EXPERIMENTAL
+	depends on HIGHMEM
+	help
+	  Generate crash dump after being started by kexec.
 endmenu
 
 
@@ -1226,6 +1265,15 @@ config SCx200
 	  This support is also available as a module.  If compiled as a
 	  module, it will be called scx200.
 
+config HOTPLUG_CPU
+	bool "Support for hot-pluggable CPUs (EXPERIMENTAL)"
+	depends on SMP && HOTPLUG && EXPERIMENTAL
+	---help---
+	  Say Y here to experiment with turning CPUs off and on.  CPUs
+	  can be controlled through /sys/devices/system/cpu.
+
+	  Say N.
+
 source "drivers/pcmcia/Kconfig"
 
 source "drivers/pci/hotplug/Kconfig"
@@ -1238,6 +1286,8 @@ source "fs/Kconfig.binfmt"
 
 endmenu
 
+source "net/Kconfig"
+
 source "drivers/Kconfig"
 
 source "fs/Kconfig"
diff --git a/arch/i386/Kconfig.debug b/arch/i386/Kconfig.debug
--- a/arch/i386/Kconfig.debug
+++ b/arch/i386/Kconfig.debug
@@ -18,6 +18,9 @@ config EARLY_PRINTK
 config DEBUG_STACKOVERFLOW
 	bool "Check for stack overflows"
 	depends on DEBUG_KERNEL
+	help
+	  This option will cause messages to be printed if free stack space
+	  drops below a certain limit.
 
 config KPROBES
 	bool "Kprobes"
diff --git a/arch/i386/Makefile b/arch/i386/Makefile
--- a/arch/i386/Makefile
+++ b/arch/i386/Makefile
@@ -17,6 +17,13 @@
 # 20050320  Kianusch Sayah Karadji <kianusch@sk-tech.net>
 #           Added support for GEODE CPU
 
+HAS_BIARCH      := $(call cc-option-yn, -m32)
+ifeq ($(HAS_BIARCH),y)
+AS              := $(AS) --32
+LD              := $(LD) -m elf_i386
+CC              := $(CC) -m32
+endif
+
 LDFLAGS		:= -m elf_i386
 OBJCOPYFLAGS	:= -O binary -R .note -R .comment -S
 LDFLAGS_vmlinux :=
diff --git a/arch/i386/boot/Makefile b/arch/i386/boot/Makefile
--- a/arch/i386/boot/Makefile
+++ b/arch/i386/boot/Makefile
@@ -25,8 +25,8 @@ SVGA_MODE := -DSVGA_MODE=NORMAL_VGA
 
 #RAMDISK := -DRAMDISK=512
 
-targets		:= vmlinux.bin bootsect bootsect.o setup setup.o \
-		   zImage bzImage
+targets		:= vmlinux.bin bootsect bootsect.o \
+		   setup setup.o zImage bzImage
 subdir- 	:= compressed
 
 hostprogs-y	:= tools/build
@@ -48,7 +48,7 @@ cmd_image = $(obj)/tools/build $(BUILDFL
 $(obj)/zImage $(obj)/bzImage: $(obj)/bootsect $(obj)/setup \
 			      $(obj)/vmlinux.bin $(obj)/tools/build FORCE
 	$(call if_changed,image)
-	@echo 'Kernel: $@ is ready'
+	@echo 'Kernel: $@ is ready' ' (#'`cat .version`')'
 
 $(obj)/vmlinux.bin: $(obj)/compressed/vmlinux FORCE
 	$(call if_changed,objcopy)
diff --git a/arch/i386/boot/compressed/head.S b/arch/i386/boot/compressed/head.S
--- a/arch/i386/boot/compressed/head.S
+++ b/arch/i386/boot/compressed/head.S
@@ -25,6 +25,7 @@
 
 #include <linux/linkage.h>
 #include <asm/segment.h>
+#include <asm/page.h>
 
 	.globl startup_32
 	
@@ -74,7 +75,7 @@ startup_32:
 	popl %esi	# discard address
 	popl %esi	# real mode pointer
 	xorl %ebx,%ebx
-	ljmp $(__BOOT_CS), $0x100000
+	ljmp $(__BOOT_CS), $__PHYSICAL_START
 
 /*
  * We come here, if we were loaded high.
@@ -99,7 +100,7 @@ startup_32:
 	popl %ecx	# lcount
 	popl %edx	# high_buffer_start
 	popl %eax	# hcount
-	movl $0x100000,%edi
+	movl $__PHYSICAL_START,%edi
 	cli		# make sure we don't get interrupted
 	ljmp $(__BOOT_CS), $0x1000 # and jump to the move routine
 
@@ -124,5 +125,5 @@ move_routine_start:
 	movsl
 	movl %ebx,%esi	# Restore setup pointer
 	xorl %ebx,%ebx
-	ljmp $(__BOOT_CS), $0x100000
+	ljmp $(__BOOT_CS), $__PHYSICAL_START
 move_routine_end:
diff --git a/arch/i386/boot/compressed/misc.c b/arch/i386/boot/compressed/misc.c
--- a/arch/i386/boot/compressed/misc.c
+++ b/arch/i386/boot/compressed/misc.c
@@ -13,6 +13,7 @@
 #include <linux/vmalloc.h>
 #include <linux/tty.h>
 #include <asm/io.h>
+#include <asm/page.h>
 
 /*
  * gzip declarations
@@ -308,7 +309,7 @@ static void setup_normal_output_buffer(v
 #else
 	if ((RM_ALT_MEM_K > RM_EXT_MEM_K ? RM_ALT_MEM_K : RM_EXT_MEM_K) < 1024) error("Less than 2MB of memory");
 #endif
-	output_data = (char *)0x100000; /* Points to 1M */
+	output_data = (char *)__PHYSICAL_START; /* Normally Points to 1M */
 	free_mem_end_ptr = (long)real_mode;
 }
 
@@ -333,8 +334,8 @@ static void setup_output_buffer_if_we_ru
 	low_buffer_size = low_buffer_end - LOW_BUFFER_START;
 	high_loaded = 1;
 	free_mem_end_ptr = (long)high_buffer_start;
-	if ( (0x100000 + low_buffer_size) > ((ulg)high_buffer_start)) {
-		high_buffer_start = (uch *)(0x100000 + low_buffer_size);
+	if ( (__PHYSICAL_START + low_buffer_size) > ((ulg)high_buffer_start)) {
+		high_buffer_start = (uch *)(__PHYSICAL_START + low_buffer_size);
 		mv->hcount = 0; /* say: we need not to move high_buffer */
 	}
 	else mv->hcount = -1;
@@ -353,7 +354,6 @@ static void close_output_buffer_if_we_ru
 	}
 }
 
-
 asmlinkage int decompress_kernel(struct moveparams *mv, void *rmode)
 {
 	real_mode = rmode;
diff --git a/arch/i386/boot/edd.S b/arch/i386/boot/edd.S
--- a/arch/i386/boot/edd.S
+++ b/arch/i386/boot/edd.S
@@ -6,7 +6,7 @@
  *   projects 1572D, 1484D, 1386D, 1226DT
  * disk signature read by Matt Domsch <Matt_Domsch@dell.com>
  *	and Andrew Wilks <Andrew_Wilks@dell.com> September 2003, June 2004
- * legacy CHS retreival by Patrick J. LoPresti <patl@users.sourceforge.net>
+ * legacy CHS retrieval by Patrick J. LoPresti <patl@users.sourceforge.net>
  *      March 2004
  * Command line option parsing, Matt Domsch, November 2004
  */
diff --git a/arch/i386/boot/install.sh b/arch/i386/boot/install.sh
--- a/arch/i386/boot/install.sh
+++ b/arch/i386/boot/install.sh
@@ -21,8 +21,8 @@
 
 # User may have a custom install script
 
-if [ -x ~/bin/installkernel ]; then exec ~/bin/installkernel "$@"; fi
-if [ -x /sbin/installkernel ]; then exec /sbin/installkernel "$@"; fi
+if [ -x ~/bin/${CROSS_COMPILE}installkernel ]; then exec ~/bin/${CROSS_COMPILE}installkernel "$@"; fi
+if [ -x /sbin/${CROSS_COMPILE}installkernel ]; then exec /sbin/${CROSS_COMPILE}installkernel "$@"; fi
 
 # Default install - same as make zlilo
 
diff --git a/arch/i386/boot/setup.S b/arch/i386/boot/setup.S
--- a/arch/i386/boot/setup.S
+++ b/arch/i386/boot/setup.S
@@ -33,7 +33,7 @@
  * Transcribed from Intel (as86) -> AT&T (gas) by Chris Noe, May 1999.
  * <stiker@northlink.com>
  *
- * Fix to work around buggy BIOSes which dont use carry bit correctly
+ * Fix to work around buggy BIOSes which don't use carry bit correctly
  * and/or report extended memory in CX/DX for e801h memory size detection 
  * call.  As a result the kernel got wrong figures.  The int15/e801h docs
  * from Ralf Brown interrupt list seem to indicate AX/BX should be used
@@ -357,7 +357,7 @@ bail820:
 
 meme801:
 	stc					# fix to work around buggy
-	xorw	%cx,%cx				# BIOSes which dont clear/set
+	xorw	%cx,%cx				# BIOSes which don't clear/set
 	xorw	%dx,%dx				# carry on pass/error of
 						# e801h memory size call
 						# or merely pass cx,dx though
@@ -847,7 +847,7 @@ flush_instr:
 #
 #	but we yet haven't reloaded the CS register, so the default size 
 #	of the target offset still is 16 bit.
-#       However, using an operand prefix (0x66), the CPU will properly
+#	However, using an operand prefix (0x66), the CPU will properly
 #	take our 48 bit far pointer. (INTeL 80386 Programmer's Reference
 #	Manual, Mixing 16-bit and 32-bit code, page 16-6)
 
diff --git a/arch/i386/boot/tools/build.c b/arch/i386/boot/tools/build.c
--- a/arch/i386/boot/tools/build.c
+++ b/arch/i386/boot/tools/build.c
@@ -1,6 +1,4 @@
 /*
- *  $Id: build.c,v 1.5 1997/05/19 12:29:58 mj Exp $
- *
  *  Copyright (C) 1991, 1992  Linus Torvalds
  *  Copyright (C) 1997 Martin Mares
  */
@@ -8,7 +6,8 @@
 /*
  * This file builds a disk-image from three different files:
  *
- * - bootsect: exactly 512 bytes of 8086 machine code, loads the rest
+ * - bootsect: compatibility mbr which prints an error message if
+ *             someone tries to boot the kernel directly.
  * - setup: 8086 machine code, sets up system parm
  * - system: 80386 code for actual system
  *
@@ -71,7 +70,8 @@ void usage(void)
 
 int main(int argc, char ** argv)
 {
-	unsigned int i, c, sz, setup_sectors;
+	unsigned int i, sz, setup_sectors;
+	int c;
 	u32 sys_size;
 	byte major_root, minor_root;
 	struct stat sb;
diff --git a/arch/i386/crypto/aes.c b/arch/i386/crypto/aes.c
--- a/arch/i386/crypto/aes.c
+++ b/arch/i386/crypto/aes.c
@@ -59,7 +59,7 @@ struct aes_ctx {
 };
 
 #define WPOLY 0x011b
-#define u32_in(x) le32_to_cpu(*(const u32 *)(x))
+#define u32_in(x) le32_to_cpup((const __le32 *)(x))
 #define bytes2word(b0, b1, b2, b3)  \
 	(((u32)(b3) << 24) | ((u32)(b2) << 16) | ((u32)(b1) << 8) | (b0))
 
diff --git a/arch/i386/defconfig b/arch/i386/defconfig
--- a/arch/i386/defconfig
+++ b/arch/i386/defconfig
@@ -126,7 +126,6 @@ CONFIG_HAVE_DEC_LOCK=y
 #
 CONFIG_PM=y
 CONFIG_SOFTWARE_SUSPEND=y
-# CONFIG_PM_DISK is not set
 
 #
 # ACPI (Advanced Configuration and Power Interface) Support
diff --git a/arch/i386/kernel/Makefile b/arch/i386/kernel/Makefile
--- a/arch/i386/kernel/Makefile
+++ b/arch/i386/kernel/Makefile
@@ -24,6 +24,7 @@ obj-$(CONFIG_X86_MPPARSE)	+= mpparse.o
 obj-$(CONFIG_X86_LOCAL_APIC)	+= apic.o nmi.o
 obj-$(CONFIG_X86_IO_APIC)	+= io_apic.o
 obj-$(CONFIG_X86_REBOOTFIXUPS)	+= reboot_fixups.o
+obj-$(CONFIG_KEXEC)		+= machine_kexec.o relocate_kernel.o crash.o
 obj-$(CONFIG_X86_NUMAQ)		+= numaq.o
 obj-$(CONFIG_X86_SUMMIT_NUMA)	+= summit.o
 obj-$(CONFIG_KPROBES)		+= kprobes.o
diff --git a/arch/i386/kernel/acpi/Makefile b/arch/i386/kernel/acpi/Makefile
--- a/arch/i386/kernel/acpi/Makefile
+++ b/arch/i386/kernel/acpi/Makefile
@@ -2,3 +2,7 @@ obj-$(CONFIG_ACPI_BOOT)		:= boot.o
 obj-$(CONFIG_X86_IO_APIC)	+= earlyquirk.o
 obj-$(CONFIG_ACPI_SLEEP)	+= sleep.o wakeup.o
 
+ifneq ($(CONFIG_ACPI_PROCESSOR),)
+obj-y				+= cstate.o
+endif
+
diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c
--- a/arch/i386/kernel/acpi/boot.c
+++ b/arch/i386/kernel/acpi/boot.c
@@ -29,6 +29,7 @@
 #include <linux/efi.h>
 #include <linux/irq.h>
 #include <linux/module.h>
+#include <linux/dmi.h>
 
 #include <asm/pgtable.h>
 #include <asm/io_apic.h>
@@ -158,9 +159,15 @@ char *__acpi_map_table(unsigned long phy
 #endif
 
 #ifdef CONFIG_PCI_MMCONFIG
-static int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size)
+/* The physical address of the MMCONFIG aperture.  Set from ACPI tables. */
+struct acpi_table_mcfg_config *pci_mmcfg_config;
+int pci_mmcfg_config_num;
+
+int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size)
 {
 	struct acpi_table_mcfg *mcfg;
+	unsigned long i;
+	int config_size;
 
 	if (!phys_addr || !size)
 		return -EINVAL;
@@ -171,18 +178,38 @@ static int __init acpi_parse_mcfg(unsign
 		return -ENODEV;
 	}
 
-	if (mcfg->base_reserved) {
-		printk(KERN_ERR PREFIX "MMCONFIG not in low 4GB of memory\n");
+	/* how many config structures do we have */
+	pci_mmcfg_config_num = 0;
+	i = size - sizeof(struct acpi_table_mcfg);
+	while (i >= sizeof(struct acpi_table_mcfg_config)) {
+		++pci_mmcfg_config_num;
+		i -= sizeof(struct acpi_table_mcfg_config);
+	};
+	if (pci_mmcfg_config_num == 0) {
+		printk(KERN_ERR PREFIX "MMCONFIG has no entries\n");
 		return -ENODEV;
 	}
 
-	pci_mmcfg_base_addr = mcfg->base_address;
+	config_size = pci_mmcfg_config_num * sizeof(*pci_mmcfg_config);
+	pci_mmcfg_config = kmalloc(config_size, GFP_KERNEL);
+	if (!pci_mmcfg_config) {
+		printk(KERN_WARNING PREFIX
+		       "No memory for MCFG config tables\n");
+		return -ENOMEM;
+	}
+
+	memcpy(pci_mmcfg_config, &mcfg->config, config_size);
+	for (i = 0; i < pci_mmcfg_config_num; ++i) {
+		if (mcfg->config[i].base_reserved) {
+			printk(KERN_ERR PREFIX
+			       "MMCONFIG not in low 4GB of memory\n");
+			return -ENODEV;
+		}
+	}
 
 	return 0;
 }
-#else
-#define	acpi_parse_mcfg NULL
-#endif /* !CONFIG_PCI_MMCONFIG */
+#endif /* CONFIG_PCI_MMCONFIG */
 
 #ifdef CONFIG_X86_LOCAL_APIC
 static int __init
@@ -506,6 +533,22 @@ acpi_unmap_lsapic(int cpu)
 EXPORT_SYMBOL(acpi_unmap_lsapic);
 #endif /* CONFIG_ACPI_HOTPLUG_CPU */
 
+int
+acpi_register_ioapic(acpi_handle handle, u64 phys_addr, u32 gsi_base)
+{
+	/* TBD */
+	return -EINVAL;
+}
+EXPORT_SYMBOL(acpi_register_ioapic);
+
+int
+acpi_unregister_ioapic(acpi_handle handle, u32 gsi_base)
+{
+	/* TBD */
+	return -EINVAL;
+}
+EXPORT_SYMBOL(acpi_unregister_ioapic);
+
 static unsigned long __init
 acpi_scan_rsdp (
 	unsigned long		start,
@@ -815,6 +858,219 @@ acpi_process_madt(void)
 	return;
 }
 
+extern int acpi_force;
+
+#ifdef __i386__
+
+#ifdef	CONFIG_ACPI_PCI
+static int __init disable_acpi_irq(struct dmi_system_id *d)
+{
+	if (!acpi_force) {
+		printk(KERN_NOTICE "%s detected: force use of acpi=noirq\n",
+		       d->ident);
+		acpi_noirq_set();
+	}
+	return 0;
+}
+
+static int __init disable_acpi_pci(struct dmi_system_id *d)
+{
+	if (!acpi_force) {
+		printk(KERN_NOTICE "%s detected: force use of pci=noacpi\n",
+		       d->ident);
+		acpi_disable_pci();
+	}
+	return 0;
+}
+#endif
+
+static int __init dmi_disable_acpi(struct dmi_system_id *d)
+{
+	if (!acpi_force) {
+		printk(KERN_NOTICE "%s detected: acpi off\n",d->ident);
+		disable_acpi();
+	} else {
+		printk(KERN_NOTICE
+		       "Warning: DMI blacklist says broken, but acpi forced\n");
+	}
+	return 0;
+}
+
+/*
+ * Limit ACPI to CPU enumeration for HT
+ */
+static int __init force_acpi_ht(struct dmi_system_id *d)
+{
+	if (!acpi_force) {
+		printk(KERN_NOTICE "%s detected: force use of acpi=ht\n", d->ident);
+		disable_acpi();
+		acpi_ht = 1;
+	} else {
+		printk(KERN_NOTICE
+		       "Warning: acpi=force overrules DMI blacklist: acpi=ht\n");
+	}
+	return 0;
+}
+
+/*
+ * If your system is blacklisted here, but you find that acpi=force
+ * works for you, please contact acpi-devel@sourceforge.net
+ */
+static struct dmi_system_id __initdata acpi_dmi_table[] = {
+	/*
+	 * Boxes that need ACPI disabled
+	 */
+	{
+		.callback = dmi_disable_acpi,
+		.ident = "IBM Thinkpad",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "IBM"),
+			DMI_MATCH(DMI_BOARD_NAME, "2629H1G"),
+		},
+	},
+
+	/*
+	 * Boxes that need acpi=ht
+	 */
+	{
+		.callback = force_acpi_ht,
+		.ident = "FSC Primergy T850",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "PRIMERGY T850"),
+		},
+	},
+	{
+		.callback = force_acpi_ht,
+		.ident = "DELL GX240",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "Dell Computer Corporation"),
+			DMI_MATCH(DMI_BOARD_NAME, "OptiPlex GX240"),
+		},
+	},
+	{
+		.callback = force_acpi_ht,
+		.ident = "HP VISUALIZE NT Workstation",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "HP VISUALIZE NT Workstation"),
+		},
+	},
+	{
+		.callback = force_acpi_ht,
+		.ident = "Compaq Workstation W8000",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Compaq"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Workstation W8000"),
+		},
+	},
+	{
+		.callback = force_acpi_ht,
+		.ident = "ASUS P4B266",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
+			DMI_MATCH(DMI_BOARD_NAME, "P4B266"),
+		},
+	},
+	{
+		.callback = force_acpi_ht,
+		.ident = "ASUS P2B-DS",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
+			DMI_MATCH(DMI_BOARD_NAME, "P2B-DS"),
+		},
+	},
+	{
+		.callback = force_acpi_ht,
+		.ident = "ASUS CUR-DLS",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
+			DMI_MATCH(DMI_BOARD_NAME, "CUR-DLS"),
+		},
+	},
+	{
+		.callback = force_acpi_ht,
+		.ident = "ABIT i440BX-W83977",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "ABIT <http://www.abit.com>"),
+			DMI_MATCH(DMI_BOARD_NAME, "i440BX-W83977 (BP6)"),
+		},
+	},
+	{
+		.callback = force_acpi_ht,
+		.ident = "IBM Bladecenter",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "IBM"),
+			DMI_MATCH(DMI_BOARD_NAME, "IBM eServer BladeCenter HS20"),
+		},
+	},
+	{
+		.callback = force_acpi_ht,
+		.ident = "IBM eServer xSeries 360",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "IBM"),
+			DMI_MATCH(DMI_BOARD_NAME, "eServer xSeries 360"),
+		},
+	},
+	{
+		.callback = force_acpi_ht,
+		.ident = "IBM eserver xSeries 330",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "IBM"),
+			DMI_MATCH(DMI_BOARD_NAME, "eserver xSeries 330"),
+		},
+	},
+	{
+		.callback = force_acpi_ht,
+		.ident = "IBM eserver xSeries 440",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "IBM"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "eserver xSeries 440"),
+		},
+	},
+
+#ifdef	CONFIG_ACPI_PCI
+	/*
+	 * Boxes that need ACPI PCI IRQ routing disabled
+	 */
+	{
+		.callback = disable_acpi_irq,
+		.ident = "ASUS A7V",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC"),
+			DMI_MATCH(DMI_BOARD_NAME, "<A7V>"),
+			/* newer BIOS, Revision 1011, does work */
+			DMI_MATCH(DMI_BIOS_VERSION, "ASUS A7V ACPI BIOS Revision 1007"),
+		},
+	},
+
+	/*
+	 * Boxes that need ACPI PCI IRQ routing and PCI scan disabled
+	 */
+	{	/* _BBN 0 bug */
+		.callback = disable_acpi_pci,
+		.ident = "ASUS PR-DLS",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
+			DMI_MATCH(DMI_BOARD_NAME, "PR-DLS"),
+			DMI_MATCH(DMI_BIOS_VERSION, "ASUS PR-DLS ACPI BIOS Revision 1010"),
+			DMI_MATCH(DMI_BIOS_DATE, "03/21/2003")
+		},
+	},
+	{
+		.callback = disable_acpi_pci,
+		.ident = "Acer TravelMate 36x Laptop",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+ 			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"),
+		},
+	},
+#endif
+	{ }
+};
+
+#endif	/* __i386__ */
+
 /*
  * acpi_boot_table_init() and acpi_boot_init()
  *  called from setup_arch(), always.
@@ -843,6 +1099,10 @@ acpi_boot_table_init(void)
 {
 	int error;
 
+#ifdef __i386__
+	dmi_check_system(acpi_dmi_table);
+#endif
+
 	/*
 	 * If acpi_disabled, bail out
 	 * One exception: acpi=ht continues far enough to enumerate LAPICs
@@ -870,8 +1130,6 @@ acpi_boot_table_init(void)
 	 */
 	error = acpi_blacklisted();
 	if (error) {
-		extern int acpi_force;
-
 		if (acpi_force) {
 			printk(KERN_WARNING PREFIX "acpi=force override\n");
 		} else {
@@ -907,7 +1165,6 @@ int __init acpi_boot_init(void)
 	acpi_process_madt();
 
 	acpi_table_parse(ACPI_HPET, acpi_parse_hpet);
-	acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg);
 
 	return 0;
 }
diff --git a/arch/i386/kernel/acpi/cstate.c b/arch/i386/kernel/acpi/cstate.c
new file mode 100644
--- /dev/null
+++ b/arch/i386/kernel/acpi/cstate.c
@@ -0,0 +1,103 @@
+/*
+ * arch/i386/kernel/acpi/cstate.c
+ *
+ * Copyright (C) 2005 Intel Corporation
+ * 	Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
+ * 	- Added _PDC for SMP C-states on Intel CPUs
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/acpi.h>
+
+#include <acpi/processor.h>
+#include <asm/acpi.h>
+
+static void acpi_processor_power_init_intel_pdc(struct acpi_processor_power
+						*pow)
+{
+	struct acpi_object_list *obj_list;
+	union acpi_object *obj;
+	u32 *buf;
+
+	/* allocate and initialize pdc. It will be used later. */
+	obj_list = kmalloc(sizeof(struct acpi_object_list), GFP_KERNEL);
+	if (!obj_list) {
+		printk(KERN_ERR "Memory allocation error\n");
+		return;
+	}
+
+	obj = kmalloc(sizeof(union acpi_object), GFP_KERNEL);
+	if (!obj) {
+		printk(KERN_ERR "Memory allocation error\n");
+		kfree(obj_list);
+		return;
+	}
+
+	buf = kmalloc(12, GFP_KERNEL);
+	if (!buf) {
+		printk(KERN_ERR "Memory allocation error\n");
+		kfree(obj);
+		kfree(obj_list);
+		return;
+	}
+
+	buf[0] = ACPI_PDC_REVISION_ID;
+	buf[1] = 1;
+	buf[2] = ACPI_PDC_C_CAPABILITY_SMP;
+
+	obj->type = ACPI_TYPE_BUFFER;
+	obj->buffer.length = 12;
+	obj->buffer.pointer = (u8 *) buf;
+	obj_list->count = 1;
+	obj_list->pointer = obj;
+	pow->pdc = obj_list;
+
+	return;
+}
+
+/* Initialize _PDC data based on the CPU vendor */
+void acpi_processor_power_init_pdc(struct acpi_processor_power *pow,
+				   unsigned int cpu)
+{
+	struct cpuinfo_x86 *c = cpu_data + cpu;
+
+	pow->pdc = NULL;
+	if (c->x86_vendor == X86_VENDOR_INTEL)
+		acpi_processor_power_init_intel_pdc(pow);
+
+	return;
+}
+
+EXPORT_SYMBOL(acpi_processor_power_init_pdc);
+
+/*
+ * Initialize bm_flags based on the CPU cache properties
+ * On SMP it depends on cache configuration
+ * - When cache is not shared among all CPUs, we flush cache
+ *   before entering C3.
+ * - When cache is shared among all CPUs, we use bm_check
+ *   mechanism as in UP case
+ *
+ * This routine is called only after all the CPUs are online
+ */
+void acpi_processor_power_init_bm_check(struct acpi_processor_flags *flags,
+					unsigned int cpu)
+{
+	struct cpuinfo_x86 *c = cpu_data + cpu;
+
+	flags->bm_check = 0;
+	if (num_online_cpus() == 1)
+		flags->bm_check = 1;
+	else if (c->x86_vendor == X86_VENDOR_INTEL) {
+		/*
+		 * Today all CPUs that support C3 share cache.
+		 * TBD: This needs to look at cache shared map, once
+		 * multi-core detection patch makes to the base.
+		 */
+		flags->bm_check = 1;
+	}
+}
+
+EXPORT_SYMBOL(acpi_processor_power_init_bm_check);
diff --git a/arch/i386/kernel/acpi/sleep.c b/arch/i386/kernel/acpi/sleep.c
--- a/arch/i386/kernel/acpi/sleep.c
+++ b/arch/i386/kernel/acpi/sleep.c
@@ -7,6 +7,7 @@
 
 #include <linux/acpi.h>
 #include <linux/bootmem.h>
+#include <linux/dmi.h>
 #include <asm/smp.h>
 #include <asm/tlbflush.h>
 
@@ -91,3 +92,29 @@ static int __init acpi_sleep_setup(char 
 
 
 __setup("acpi_sleep=", acpi_sleep_setup);
+
+
+static __init int reset_videomode_after_s3(struct dmi_system_id *d)
+{
+	acpi_video_flags |= 2;
+	return 0;
+}
+
+static __initdata struct dmi_system_id acpisleep_dmi_table[] = {
+	{	/* Reset video mode after returning from ACPI S3 sleep */
+		.callback = reset_videomode_after_s3,
+		.ident = "Toshiba Satellite 4030cdt",
+		.matches = {
+			DMI_MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"),
+		},
+	},
+	{ }
+};
+
+static int __init acpisleep_dmi_init(void)
+{
+	dmi_check_system(acpisleep_dmi_table);
+	return 0;
+}
+
+core_initcall(acpisleep_dmi_init);
diff --git a/arch/i386/kernel/acpi/wakeup.S b/arch/i386/kernel/acpi/wakeup.S
--- a/arch/i386/kernel/acpi/wakeup.S
+++ b/arch/i386/kernel/acpi/wakeup.S
@@ -74,8 +74,9 @@ wakeup_code:
 	movw	%ax,%fs
 	movw	$0x0e00 + 'i', %fs:(0x12)
 	
-	# need a gdt
-	lgdt	real_save_gdt - wakeup_code
+	# need a gdt -- use lgdtl to force 32-bit operands, in case
+	# the GDT is located past 16 megabytes.
+	lgdtl	real_save_gdt - wakeup_code
 
 	movl	real_save_cr0 - wakeup_code, %eax
 	movl	%eax, %cr0
diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c
--- a/arch/i386/kernel/apic.c
+++ b/arch/i386/kernel/apic.c
@@ -26,6 +26,7 @@
 #include <linux/mc146818rtc.h>
 #include <linux/kernel_stat.h>
 #include <linux/sysdev.h>
+#include <linux/cpu.h>
 
 #include <asm/atomic.h>
 #include <asm/smp.h>
@@ -34,12 +35,18 @@
 #include <asm/desc.h>
 #include <asm/arch_hooks.h>
 #include <asm/hpet.h>
+#include <asm/i8253.h>
 
 #include <mach_apic.h>
 
 #include "io_ports.h"
 
 /*
+ * Knob to control our willingness to enable the local APIC.
+ */
+int enable_local_apic __initdata = 0; /* -1=force-disable, +1=force-enable */
+
+/*
  * Debug level
  */
 int apic_verbosity;
@@ -205,7 +212,7 @@ void __init connect_bsp_APIC(void)
 	enable_apic_mode();
 }
 
-void disconnect_bsp_APIC(void)
+void disconnect_bsp_APIC(int virt_wire_setup)
 {
 	if (pic_mode) {
 		/*
@@ -219,6 +226,42 @@ void disconnect_bsp_APIC(void)
 		outb(0x70, 0x22);
 		outb(0x00, 0x23);
 	}
+	else {
+		/* Go back to Virtual Wire compatibility mode */
+		unsigned long value;
+
+		/* For the spurious interrupt use vector F, and enable it */
+		value = apic_read(APIC_SPIV);
+		value &= ~APIC_VECTOR_MASK;
+		value |= APIC_SPIV_APIC_ENABLED;
+		value |= 0xf;
+		apic_write_around(APIC_SPIV, value);
+
+		if (!virt_wire_setup) {
+			/* For LVT0 make it edge triggered, active high, external and enabled */
+			value = apic_read(APIC_LVT0);
+			value &= ~(APIC_MODE_MASK | APIC_SEND_PENDING |
+				APIC_INPUT_POLARITY | APIC_LVT_REMOTE_IRR |
+				APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED );
+			value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING;
+			value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_EXTINT);
+			apic_write_around(APIC_LVT0, value);
+		}
+		else {
+			/* Disable LVT0 */
+			apic_write_around(APIC_LVT0, APIC_LVT_MASKED);
+		}
+
+		/* For LVT1 make it edge triggered, active high, nmi and enabled */
+		value = apic_read(APIC_LVT1);
+		value &= ~(
+			APIC_MODE_MASK | APIC_SEND_PENDING |
+			APIC_INPUT_POLARITY | APIC_LVT_REMOTE_IRR |
+			APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED);
+		value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING;
+		value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_NMI);
+		apic_write_around(APIC_LVT1, value);
+	}
 }
 
 void disable_local_APIC(void)
@@ -363,7 +406,7 @@ void __init init_bsp_APIC(void)
 	apic_write_around(APIC_LVT1, value);
 }
 
-void __init setup_local_APIC (void)
+void __devinit setup_local_APIC(void)
 {
 	unsigned long oldvalue, value, ver, maxlvt;
 
@@ -634,7 +677,7 @@ static struct sys_device device_lapic = 
 	.cls	= &lapic_sysclass,
 };
 
-static void __init apic_pm_activate(void)
+static void __devinit apic_pm_activate(void)
 {
 	apic_pm_state.active = 1;
 }
@@ -665,26 +708,6 @@ static void apic_pm_activate(void) { }
  * Original code written by Keir Fraser.
  */
 
-/*
- * Knob to control our willingness to enable the local APIC.
- */
-int enable_local_apic __initdata = 0; /* -1=force-disable, +1=force-enable */
-
-static int __init lapic_disable(char *str)
-{
-	enable_local_apic = -1;
-	clear_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability);
-	return 0;
-}
-__setup("nolapic", lapic_disable);
-
-static int __init lapic_enable(char *str)
-{
-	enable_local_apic = 1;
-	return 0;
-}
-__setup("lapic", lapic_enable);
-
 static int __init apic_set_verbosity(char *str)
 {
 	if (strcmp("debug", str) == 0)
@@ -703,15 +726,11 @@ __setup("apic=", apic_set_verbosity);
 static int __init detect_init_APIC (void)
 {
 	u32 h, l, features;
-	extern void get_cpu_vendor(struct cpuinfo_x86*);
 
 	/* Disabled by kernel option? */
 	if (enable_local_apic < 0)
 		return -1;
 
-	/* Workaround for us being called before identify_cpu(). */
-	get_cpu_vendor(&boot_cpu_data);
-
 	switch (boot_cpu_data.x86_vendor) {
 	case X86_VENDOR_AMD:
 		if ((boot_cpu_data.x86 == 6 && boot_cpu_data.x86_model > 1) ||
@@ -855,9 +874,8 @@ fake_ioapic_page:
  * but we do not accept timer interrupts yet. We only allow the BP
  * to calibrate.
  */
-static unsigned int __init get_8254_timer_count(void)
+static unsigned int __devinit get_8254_timer_count(void)
 {
-	extern spinlock_t i8253_lock;
 	unsigned long flags;
 
 	unsigned int count;
@@ -874,7 +892,7 @@ static unsigned int __init get_8254_time
 }
 
 /* next tick in 8254 can be caught by catching timer wraparound */
-static void __init wait_8254_wraparound(void)
+static void __devinit wait_8254_wraparound(void)
 {
 	unsigned int curr_count, prev_count;
 
@@ -894,7 +912,7 @@ static void __init wait_8254_wraparound(
  * Default initialization for 8254 timers. If we use other timers like HPET,
  * we override this later
  */
-void (*wait_timer_tick)(void) __initdata = wait_8254_wraparound;
+void (*wait_timer_tick)(void) __devinitdata = wait_8254_wraparound;
 
 /*
  * This function sets up the local APIC timer, with a timeout of
@@ -930,7 +948,7 @@ static void __setup_APIC_LVTT(unsigned i
 	apic_write_around(APIC_TMICT, clocks/APIC_DIVISOR);
 }
 
-static void __init setup_APIC_timer(unsigned int clocks)
+static void __devinit setup_APIC_timer(unsigned int clocks)
 {
 	unsigned long flags;
 
@@ -1043,12 +1061,12 @@ void __init setup_boot_APIC_clock(void)
 	local_irq_enable();
 }
 
-void __init setup_secondary_APIC_clock(void)
+void __devinit setup_secondary_APIC_clock(void)
 {
 	setup_APIC_timer(calibration_result);
 }
 
-void __init disable_APIC_timer(void)
+void __devinit disable_APIC_timer(void)
 {
 	if (using_apic_timer) {
 		unsigned long v;
@@ -1133,7 +1151,7 @@ inline void smp_local_timer_interrupt(st
 		}
 
 #ifdef CONFIG_SMP
-		update_process_times(user_mode(regs));
+		update_process_times(user_mode_vm(regs));
 #endif
 	}
 
diff --git a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c
--- a/arch/i386/kernel/apm.c
+++ b/arch/i386/kernel/apm.c
@@ -228,10 +228,10 @@
 #include <asm/system.h>
 #include <asm/uaccess.h>
 #include <asm/desc.h>
+#include <asm/i8253.h>
 
 #include "io_ports.h"
 
-extern spinlock_t i8253_lock;
 extern unsigned long get_cmos_time(void);
 extern void machine_real_restart(unsigned char *, int);
 
@@ -346,10 +346,10 @@ extern int (*console_blank_hook)(int);
 struct apm_user {
 	int		magic;
 	struct apm_user *	next;
-	int		suser: 1;
-	int		writer: 1;
-	int		reader: 1;
-	int		suspend_wait: 1;
+	unsigned int	suser: 1;
+	unsigned int	writer: 1;
+	unsigned int	reader: 1;
+	unsigned int	suspend_wait: 1;
 	int		suspend_result;
 	int		suspends_pending;
 	int		standbys_pending;
@@ -911,14 +911,7 @@ static void apm_power_off(void)
 		0xcd, 0x15		/* int   $0x15       */
 	};
 
-	/*
-	 * This may be called on an SMP machine.
-	 */
-#ifdef CONFIG_SMP
 	/* Some bioses don't like being called from CPU != 0 */
-	set_cpus_allowed(current, cpumask_of_cpu(0));
-	BUG_ON(smp_processor_id() != 0);
-#endif
 	if (apm_info.realmode_power_off)
 	{
 		(void)apm_save_cpus();
@@ -1168,8 +1161,7 @@ static void get_time_diff(void)
 static void reinit_timer(void)
 {
 #ifdef INIT_TIMER_AFTER_SUSPEND
-	unsigned long	flags;
-	extern spinlock_t i8253_lock;
+	unsigned long flags;
 
 	spin_lock_irqsave(&i8253_lock, flags);
 	/* set the clock to 100 Hz */
diff --git a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c
--- a/arch/i386/kernel/cpu/common.c
+++ b/arch/i386/kernel/cpu/common.c
@@ -24,9 +24,9 @@ EXPORT_PER_CPU_SYMBOL(cpu_gdt_table);
 DEFINE_PER_CPU(unsigned char, cpu_16bit_stack[CPU_16BIT_STACK_SIZE]);
 EXPORT_PER_CPU_SYMBOL(cpu_16bit_stack);
 
-static int cachesize_override __initdata = -1;
-static int disable_x86_fxsr __initdata = 0;
-static int disable_x86_serial_nr __initdata = 1;
+static int cachesize_override __devinitdata = -1;
+static int disable_x86_fxsr __devinitdata = 0;
+static int disable_x86_serial_nr __devinitdata = 1;
 
 struct cpu_dev * cpu_devs[X86_VENDOR_NUM] = {};
 
@@ -59,7 +59,7 @@ static int __init cachesize_setup(char *
 }
 __setup("cachesize=", cachesize_setup);
 
-int __init get_model_name(struct cpuinfo_x86 *c)
+int __devinit get_model_name(struct cpuinfo_x86 *c)
 {
 	unsigned int *v;
 	char *p, *q;
@@ -89,7 +89,7 @@ int __init get_model_name(struct cpuinfo
 }
 
 
-void __init display_cacheinfo(struct cpuinfo_x86 *c)
+void __devinit display_cacheinfo(struct cpuinfo_x86 *c)
 {
 	unsigned int n, dummy, ecx, edx, l2size;
 
@@ -130,7 +130,7 @@ void __init display_cacheinfo(struct cpu
 /* in particular, if CPUID levels 0x80000002..4 are supported, this isn't used */
 
 /* Look up CPU names by table lookup. */
-static char __init *table_lookup_model(struct cpuinfo_x86 *c)
+static char __devinit *table_lookup_model(struct cpuinfo_x86 *c)
 {
 	struct cpu_model_info *info;
 
@@ -151,7 +151,7 @@ static char __init *table_lookup_model(s
 }
 
 
-void __init get_cpu_vendor(struct cpuinfo_x86 *c, int early)
+void __devinit get_cpu_vendor(struct cpuinfo_x86 *c, int early)
 {
 	char *v = c->x86_vendor_id;
 	int i;
@@ -202,7 +202,7 @@ static inline int flag_is_changeable_p(u
 
 
 /* Probe for the CPUID instruction */
-static int __init have_cpuid_p(void)
+static int __devinit have_cpuid_p(void)
 {
 	return flag_is_changeable_p(X86_EFLAGS_ID);
 }
@@ -249,7 +249,7 @@ static void __init early_cpu_detect(void
 #endif
 }
 
-void __init generic_identify(struct cpuinfo_x86 * c)
+void __devinit generic_identify(struct cpuinfo_x86 * c)
 {
 	u32 tfms, xlvl;
 	int junk;
@@ -296,7 +296,7 @@ void __init generic_identify(struct cpui
 	}
 }
 
-static void __init squash_the_stupid_serial_number(struct cpuinfo_x86 *c)
+static void __devinit squash_the_stupid_serial_number(struct cpuinfo_x86 *c)
 {
 	if (cpu_has(c, X86_FEATURE_PN) && disable_x86_serial_nr ) {
 		/* Disable processor serial number */
@@ -324,7 +324,7 @@ __setup("serialnumber", x86_serial_nr_se
 /*
  * This does the hard work of actually picking apart the CPU stuff...
  */
-void __init identify_cpu(struct cpuinfo_x86 *c)
+void __devinit identify_cpu(struct cpuinfo_x86 *c)
 {
 	int i;
 
@@ -432,10 +432,18 @@ void __init identify_cpu(struct cpuinfo_
 #ifdef CONFIG_X86_MCE
 	mcheck_init(c);
 #endif
+	if (c == &boot_cpu_data)
+		sysenter_setup();
+	enable_sep_cpu();
+
+	if (c == &boot_cpu_data)
+		mtrr_bp_init();
+	else
+		mtrr_ap_init();
 }
 
 #ifdef CONFIG_X86_HT
-void __init detect_ht(struct cpuinfo_x86 *c)
+void __devinit detect_ht(struct cpuinfo_x86 *c)
 {
 	u32 	eax, ebx, ecx, edx;
 	int 	index_msb, tmp;
@@ -490,7 +498,7 @@ void __init detect_ht(struct cpuinfo_x86
 }
 #endif
 
-void __init print_cpu_info(struct cpuinfo_x86 *c)
+void __devinit print_cpu_info(struct cpuinfo_x86 *c)
 {
 	char *vendor = NULL;
 
@@ -513,7 +521,7 @@ void __init print_cpu_info(struct cpuinf
 		printk("\n");
 }
 
-cpumask_t cpu_initialized __initdata = CPU_MASK_NONE;
+cpumask_t cpu_initialized __devinitdata = CPU_MASK_NONE;
 
 /* This is hacky. :)
  * We're emulating future behavior.
@@ -560,7 +568,7 @@ void __init early_cpu_init(void)
  * and IDT. We reload them nevertheless, this function acts as a
  * 'CPU state barrier', nothing should get across.
  */
-void __init cpu_init (void)
+void __devinit cpu_init(void)
 {
 	int cpu = smp_processor_id();
 	struct tss_struct * t = &per_cpu(init_tss, cpu);
@@ -635,7 +643,7 @@ void __init cpu_init (void)
 
 	/* Clear all 6 debug registers: */
 
-#define CD(register) __asm__("movl %0,%%db" #register ::"r"(0) );
+#define CD(register) set_debugreg(0, register)
 
 	CD(0); CD(1); CD(2); CD(3); /* no db4 and db5 */; CD(6); CD(7);
 
@@ -648,3 +656,15 @@ void __init cpu_init (void)
 	clear_used_math();
 	mxcsr_feature_mask_init();
 }
+
+#ifdef CONFIG_HOTPLUG_CPU
+void __devinit cpu_uninit(void)
+{
+	int cpu = raw_smp_processor_id();
+	cpu_clear(cpu, cpu_initialized);
+
+	/* lazy TLB state */
+	per_cpu(cpu_tlbstate, cpu).state = 0;
+	per_cpu(cpu_tlbstate, cpu).active_mm = &init_mm;
+}
+#endif
diff --git a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
--- a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
+++ b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
@@ -442,6 +442,13 @@ acpi_cpufreq_cpu_init (
 			(u32) data->acpi_data.states[i].transition_latency);
 
 	cpufreq_frequency_table_get_attr(data->freq_table, policy->cpu);
+	
+	/*
+	 * the first call to ->target() should result in us actually
+	 * writing something to the appropriate registers.
+	 */
+	data->resume = 1;
+	
 	return (result);
 
  err_freqfree:
diff --git a/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c b/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c
--- a/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c
+++ b/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c
@@ -190,7 +190,7 @@ static __init struct pci_dev *gx_detect_
 
 	/* detect which companion chip is used */
 	while ((gx_pci = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, gx_pci)) != NULL) {
-		if ((pci_match_device (gx_chipset_tbl, gx_pci)) != NULL) {
+		if ((pci_match_id(gx_chipset_tbl, gx_pci)) != NULL) {
 			return gx_pci;
 		}
 	}
diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k7.c b/arch/i386/kernel/cpu/cpufreq/powernow-k7.c
--- a/arch/i386/kernel/cpu/cpufreq/powernow-k7.c
+++ b/arch/i386/kernel/cpu/cpufreq/powernow-k7.c
@@ -648,9 +648,7 @@ static int powernow_cpu_exit (struct cpu
 	}
 #endif
 
-	if (powernow_table)
-		kfree(powernow_table);
-
+	kfree(powernow_table);
 	return 0;
 }
 
diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c
--- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c
+++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c
@@ -1,5 +1,5 @@
 /*
- *   (c) 2003, 2004 Advanced Micro Devices, Inc.
+ *   (c) 2003, 2004, 2005 Advanced Micro Devices, Inc.
  *  Your use of this code is subject to the terms and conditions of the
  *  GNU general public license version 2. See "COPYING" or
  *  http://www.gnu.org/licenses/gpl.html
@@ -44,7 +44,7 @@
 
 #define PFX "powernow-k8: "
 #define BFX PFX "BIOS error: "
-#define VERSION "version 1.40.2"
+#define VERSION "version 1.50.3"
 #include "powernow-k8.h"
 
 /* serialize freq changes  */
@@ -110,14 +110,13 @@ static int query_current_values_with_pen
 	u32 lo, hi;
 	u32 i = 0;
 
-	lo = MSR_S_LO_CHANGE_PENDING;
-	while (lo & MSR_S_LO_CHANGE_PENDING) {
+	do {
 		if (i++ > 0x1000000) {
 			printk(KERN_ERR PFX "detected change pending stuck\n");
 			return 1;
 		}
 		rdmsr(MSR_FIDVID_STATUS, lo, hi);
-	}
+	} while (lo & MSR_S_LO_CHANGE_PENDING);
 
 	data->currvid = hi & MSR_S_HI_CURRENT_VID;
 	data->currfid = lo & MSR_S_LO_CURRENT_FID;
@@ -232,7 +231,7 @@ static int write_new_vid(struct powernow
 /*
  * Reduce the vid by the max of step or reqvid.
  * Decreasing vid codes represent increasing voltages:
- * vid of 0 is 1.550V, vid of 0x1e is 0.800V, vid of 0x1f is off.
+ * vid of 0 is 1.550V, vid of 0x1e is 0.800V, vid of VID_OFF is off.
  */
 static int decrease_vid_code_by_step(struct powernow_k8_data *data, u32 reqvid, u32 step)
 {
@@ -467,7 +466,7 @@ static int check_supported_cpu(unsigned 
 	eax = cpuid_eax(CPUID_PROCESSOR_SIGNATURE);
 	if (((eax & CPUID_USE_XFAM_XMOD) != CPUID_USE_XFAM_XMOD) ||
 	    ((eax & CPUID_XFAM) != CPUID_XFAM_K8) ||
-	    ((eax & CPUID_XMOD) > CPUID_XMOD_REV_E)) {
+	    ((eax & CPUID_XMOD) > CPUID_XMOD_REV_F)) {
 		printk(KERN_INFO PFX "Processor cpuid %x not supported\n", eax);
 		goto out;
 	}
@@ -696,6 +695,7 @@ static void powernow_k8_acpi_pst_values(
 
 	data->irt = (data->acpi_data.states[index].control >> IRT_SHIFT) & IRT_MASK;
 	data->rvo = (data->acpi_data.states[index].control >> RVO_SHIFT) & RVO_MASK;
+	data->exttype = (data->acpi_data.states[index].control >> EXT_TYPE_SHIFT) & EXT_TYPE_MASK;
 	data->plllock = (data->acpi_data.states[index].control >> PLL_L_SHIFT) & PLL_L_MASK;
 	data->vidmvs = 1 << ((data->acpi_data.states[index].control >> MVS_SHIFT) & MVS_MASK);
 	data->vstable = (data->acpi_data.states[index].control >> VST_SHIFT) & VST_MASK;
@@ -735,8 +735,16 @@ static int powernow_k8_cpu_init_acpi(str
 	}
 
 	for (i = 0; i < data->acpi_data.state_count; i++) {
-		u32 fid = data->acpi_data.states[i].control & FID_MASK;
-		u32 vid = (data->acpi_data.states[i].control >> VID_SHIFT) & VID_MASK;
+		u32 fid;
+		u32 vid;
+
+		if (data->exttype) {
+			fid = data->acpi_data.states[i].status & FID_MASK;
+			vid = (data->acpi_data.states[i].status >> VID_SHIFT) & VID_MASK;
+		} else {
+			fid = data->acpi_data.states[i].control & FID_MASK;
+			vid = (data->acpi_data.states[i].control >> VID_SHIFT) & VID_MASK;
+		}
 
 		dprintk("   %d : fid 0x%x, vid 0x%x\n", i, fid, vid);
 
@@ -753,7 +761,7 @@ static int powernow_k8_cpu_init_acpi(str
 		}
 
 		/* verify voltage is OK - BIOSs are using "off" to indicate invalid */
-		if (vid == 0x1f) {
+		if (vid == VID_OFF) {
 			dprintk("invalid vid %u, ignoring\n", vid);
 			powernow_table[i].frequency = CPUFREQ_ENTRY_INVALID;
 			continue;
@@ -930,15 +938,6 @@ static int powernowk8_target(struct cpuf
 
 	down(&fidvid_sem);
 
-	for_each_cpu_mask(i, cpu_core_map[pol->cpu]) {
-		/* make sure the sibling is initialized */
-		if (!powernow_data[i]) {
-                        ret = 0;
-                        up(&fidvid_sem);
-                        goto err_out;
-                }
-	}
-
 	powernow_k8_acpi_pst_values(data, newstate);
 
 	if (transition_frequency(data, newstate)) {
@@ -978,7 +977,7 @@ static int __init powernowk8_cpu_init(st
 {
 	struct powernow_k8_data *data;
 	cpumask_t oldmask = CPU_MASK_ALL;
-	int rc;
+	int rc, i;
 
 	if (!check_supported_cpu(pol->cpu))
 		return -ENODEV;
@@ -1064,7 +1063,9 @@ static int __init powernowk8_cpu_init(st
 	printk("cpu_init done, current fid 0x%x, vid 0x%x\n",
 	       data->currfid, data->currvid);
 
-	powernow_data[pol->cpu] = data;
+	for_each_cpu_mask(i, cpu_core_map[pol->cpu]) {
+		powernow_data[i] = data;
+	}
 
 	return 0;
 
diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k8.h b/arch/i386/kernel/cpu/cpufreq/powernow-k8.h
--- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.h
+++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.h
@@ -1,5 +1,5 @@
 /*
- *  (c) 2003, 2004 Advanced Micro Devices, Inc.
+ *  (c) 2003, 2004, 2005 Advanced Micro Devices, Inc.
  *  Your use of this code is subject to the terms and conditions of the
  *  GNU general public license version 2. See "COPYING" or
  *  http://www.gnu.org/licenses/gpl.html
@@ -19,6 +19,7 @@ struct powernow_k8_data {
 	u32 vidmvs;  /* usable value calculated from mvs */
 	u32 vstable; /* voltage stabilization time, units 20 us */
 	u32 plllock; /* pll lock time, units 1 us */
+        u32 exttype; /* extended interface = 1 */
 
 	/* keep track of the current fid / vid */
 	u32 currvid, currfid;
@@ -41,7 +42,7 @@ struct powernow_k8_data {
 #define CPUID_XFAM			0x0ff00000	/* extended family */
 #define CPUID_XFAM_K8			0
 #define CPUID_XMOD			0x000f0000	/* extended model */
-#define CPUID_XMOD_REV_E		0x00020000
+#define CPUID_XMOD_REV_F		0x00040000
 #define CPUID_USE_XFAM_XMOD		0x00000f00
 #define CPUID_GET_MAX_CAPABILITIES	0x80000000
 #define CPUID_FREQ_VOLT_CAPABILITIES	0x80000007
@@ -57,25 +58,26 @@ struct powernow_k8_data {
 
 /* Field definitions within the FID VID Low Control MSR : */
 #define MSR_C_LO_INIT_FID_VID     0x00010000
-#define MSR_C_LO_NEW_VID          0x00001f00
-#define MSR_C_LO_NEW_FID          0x0000002f
+#define MSR_C_LO_NEW_VID          0x00003f00
+#define MSR_C_LO_NEW_FID          0x0000003f
 #define MSR_C_LO_VID_SHIFT        8
 
 /* Field definitions within the FID VID High Control MSR : */
-#define MSR_C_HI_STP_GNT_TO       0x000fffff
+#define MSR_C_HI_STP_GNT_TO 	  0x000fffff
 
 /* Field definitions within the FID VID Low Status MSR : */
-#define MSR_S_LO_CHANGE_PENDING   0x80000000	/* cleared when completed */
-#define MSR_S_LO_MAX_RAMP_VID     0x1f000000
+#define MSR_S_LO_CHANGE_PENDING   0x80000000   /* cleared when completed */
+#define MSR_S_LO_MAX_RAMP_VID     0x3f000000
 #define MSR_S_LO_MAX_FID          0x003f0000
 #define MSR_S_LO_START_FID        0x00003f00
 #define MSR_S_LO_CURRENT_FID      0x0000003f
 
 /* Field definitions within the FID VID High Status MSR : */
-#define MSR_S_HI_MAX_WORKING_VID  0x001f0000
-#define MSR_S_HI_START_VID        0x00001f00
-#define MSR_S_HI_CURRENT_VID      0x0000001f
-#define MSR_C_HI_STP_GNT_BENIGN   0x00000001
+#define MSR_S_HI_MIN_WORKING_VID  0x3f000000
+#define MSR_S_HI_MAX_WORKING_VID  0x003f0000
+#define MSR_S_HI_START_VID        0x00003f00
+#define MSR_S_HI_CURRENT_VID      0x0000003f
+#define MSR_C_HI_STP_GNT_BENIGN	  0x00000001
 
 /*
  * There are restrictions frequencies have to follow:
@@ -99,13 +101,15 @@ struct powernow_k8_data {
 #define MIN_FREQ_RESOLUTION  200 /* fids jump by 2 matching freq jumps by 200 */
 
 #define MAX_FID 0x2a	/* Spec only gives FID values as far as 5 GHz */
-#define LEAST_VID 0x1e	/* Lowest (numerically highest) useful vid value */
+#define LEAST_VID 0x3e	/* Lowest (numerically highest) useful vid value */
 
 #define MIN_FREQ 800	/* Min and max freqs, per spec */
 #define MAX_FREQ 5000
 
 #define INVALID_FID_MASK 0xffffffc1  /* not a valid fid if these bits are set */
-#define INVALID_VID_MASK 0xffffffe0  /* not a valid vid if these bits are set */
+#define INVALID_VID_MASK 0xffffffc0  /* not a valid vid if these bits are set */
+
+#define VID_OFF 0x3f
 
 #define STOP_GRANT_5NS 1 /* min poss memory access latency for voltage change */
 
@@ -121,12 +125,14 @@ struct powernow_k8_data {
                                                                                                     
 #define IRT_SHIFT      30
 #define RVO_SHIFT      28
+#define EXT_TYPE_SHIFT 27
 #define PLL_L_SHIFT    20
 #define MVS_SHIFT      18
 #define VST_SHIFT      11
 #define VID_SHIFT       6
 #define IRT_MASK        3
 #define RVO_MASK        3
+#define EXT_TYPE_MASK   1
 #define PLL_L_MASK   0x7f
 #define MVS_MASK        3
 #define VST_MASK     0x7f
diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
--- a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
+++ b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
@@ -375,7 +375,7 @@ static int centrino_cpu_init_acpi(struct
 	arg0.buffer.pointer = (u8 *) arg0_buf;
 	arg0_buf[0] = ACPI_PDC_REVISION_ID;
 	arg0_buf[1] = 1;
-	arg0_buf[2] = ACPI_PDC_EST_CAPABILITY_SMP | ACPI_PDC_EST_CAPABILITY_MSR;
+	arg0_buf[2] = ACPI_PDC_EST_CAPABILITY_SMP_MSR;
 
 	p.pdc = &arg_list;
 
diff --git a/arch/i386/kernel/cpu/intel.c b/arch/i386/kernel/cpu/intel.c
--- a/arch/i386/kernel/cpu/intel.c
+++ b/arch/i386/kernel/cpu/intel.c
@@ -25,10 +25,10 @@ extern int trap_init_f00f_bug(void);
 /*
  * Alignment at which movsl is preferred for bulk memory copies.
  */
-struct movsl_mask movsl_mask;
+struct movsl_mask movsl_mask __read_mostly;
 #endif
 
-void __init early_intel_workaround(struct cpuinfo_x86 *c)
+void __devinit early_intel_workaround(struct cpuinfo_x86 *c)
 {
 	if (c->x86_vendor != X86_VENDOR_INTEL)
 		return;
@@ -43,7 +43,7 @@ void __init early_intel_workaround(struc
  *	This is called before we do cpu ident work
  */
  
-int __init ppro_with_ram_bug(void)
+int __devinit ppro_with_ram_bug(void)
 {
 	/* Uses data from early_cpu_detect now */
 	if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL &&
@@ -61,7 +61,7 @@ int __init ppro_with_ram_bug(void)
  * P4 Xeon errata 037 workaround.
  * Hardware prefetcher may cause stale data to be loaded into the cache.
  */
-static void __init Intel_errata_workarounds(struct cpuinfo_x86 *c)
+static void __devinit Intel_errata_workarounds(struct cpuinfo_x86 *c)
 {
 	unsigned long lo, hi;
 
@@ -80,7 +80,7 @@ static void __init Intel_errata_workarou
 /*
  * find out the number of processor cores on the die
  */
-static int __init num_cpu_cores(struct cpuinfo_x86 *c)
+static int __devinit num_cpu_cores(struct cpuinfo_x86 *c)
 {
 	unsigned int eax;
 
@@ -98,7 +98,7 @@ static int __init num_cpu_cores(struct c
 		return 1;
 }
 
-static void __init init_intel(struct cpuinfo_x86 *c)
+static void __devinit init_intel(struct cpuinfo_x86 *c)
 {
 	unsigned int l2 = 0;
 	char *p = NULL;
@@ -204,7 +204,7 @@ static unsigned int intel_size_cache(str
 	return size;
 }
 
-static struct cpu_dev intel_cpu_dev __initdata = {
+static struct cpu_dev intel_cpu_dev __devinitdata = {
 	.c_vendor	= "Intel",
 	.c_ident 	= { "GenuineIntel" },
 	.c_models = {
diff --git a/arch/i386/kernel/cpu/intel_cacheinfo.c b/arch/i386/kernel/cpu/intel_cacheinfo.c
--- a/arch/i386/kernel/cpu/intel_cacheinfo.c
+++ b/arch/i386/kernel/cpu/intel_cacheinfo.c
@@ -28,7 +28,7 @@ struct _cache_table
 };
 
 /* all the cache descriptor types we care about (no TLB or trace cache entries) */
-static struct _cache_table cache_table[] __initdata =
+static struct _cache_table cache_table[] __devinitdata =
 {
 	{ 0x06, LVL_1_INST, 8 },	/* 4-way set assoc, 32 byte line size */
 	{ 0x08, LVL_1_INST, 16 },	/* 4-way set assoc, 32 byte line size */
@@ -128,7 +128,7 @@ static int __devinit cpuid4_cache_lookup
 	cpuid_count(4, index, &eax, &ebx, &ecx, &edx);
 	cache_eax.full = eax;
 	if (cache_eax.split.type == CACHE_TYPE_NULL)
-		return -1;
+		return -EIO; /* better error ? */
 
 	this_leaf->eax.full = eax;
 	this_leaf->ebx.full = ebx;
@@ -160,7 +160,7 @@ static int __init find_num_cache_leaves(
 	return retval;
 }
 
-unsigned int __init init_intel_cacheinfo(struct cpuinfo_x86 *c)
+unsigned int __devinit init_intel_cacheinfo(struct cpuinfo_x86 *c)
 {
 	unsigned int trace = 0, l1i = 0, l1d = 0, l2 = 0, l3 = 0; /* Cache sizes */
 	unsigned int new_l1d = 0, new_l1i = 0; /* Cache sizes from cpuid(4) */
@@ -334,6 +334,7 @@ static int __devinit detect_cache_attrib
 	struct _cpuid4_info	*this_leaf;
 	unsigned long 		j;
 	int 			retval;
+	cpumask_t		oldmask;
 
 	if (num_cache_leaves == 0)
 		return -ENOENT;
@@ -345,19 +346,26 @@ static int __devinit detect_cache_attrib
 	memset(cpuid4_info[cpu], 0,
 	    sizeof(struct _cpuid4_info) * num_cache_leaves);
 
+	oldmask = current->cpus_allowed;
+	retval = set_cpus_allowed(current, cpumask_of_cpu(cpu));
+	if (retval)
+		goto out;
+
 	/* Do cpuid and store the results */
+	retval = 0;
 	for (j = 0; j < num_cache_leaves; j++) {
 		this_leaf = CPUID4_INFO_IDX(cpu, j);
 		retval = cpuid4_cache_lookup(j, this_leaf);
 		if (unlikely(retval < 0))
-			goto err_out;
+			break;
 		cache_shared_cpu_map_setup(cpu, j);
 	}
-	return 0;
+	set_cpus_allowed(current, oldmask);
 
-err_out:
-	free_cache_attributes(cpu);
-	return -ENOMEM;
+out:
+	if (retval)
+		free_cache_attributes(cpu);
+	return retval;
 }
 
 #ifdef CONFIG_SYSFS
diff --git a/arch/i386/kernel/cpu/mcheck/k7.c b/arch/i386/kernel/cpu/mcheck/k7.c
--- a/arch/i386/kernel/cpu/mcheck/k7.c
+++ b/arch/i386/kernel/cpu/mcheck/k7.c
@@ -69,7 +69,7 @@ static fastcall void k7_machine_check(st
 
 
 /* AMD K7 machine check is Intel like */
-void __init amd_mcheck_init(struct cpuinfo_x86 *c)
+void __devinit amd_mcheck_init(struct cpuinfo_x86 *c)
 {
 	u32 l, h;
 	int i;
diff --git a/arch/i386/kernel/cpu/mcheck/mce.c b/arch/i386/kernel/cpu/mcheck/mce.c
--- a/arch/i386/kernel/cpu/mcheck/mce.c
+++ b/arch/i386/kernel/cpu/mcheck/mce.c
@@ -16,7 +16,7 @@
 
 #include "mce.h"
 
-int mce_disabled __initdata = 0;
+int mce_disabled __devinitdata = 0;
 int nr_mce_banks;
 
 EXPORT_SYMBOL_GPL(nr_mce_banks);	/* non-fatal.o */
@@ -31,7 +31,7 @@ static fastcall void unexpected_machine_
 void fastcall (*machine_check_vector)(struct pt_regs *, long error_code) = unexpected_machine_check;
 
 /* This has to be run for each processor */
-void __init mcheck_init(struct cpuinfo_x86 *c)
+void __devinit mcheck_init(struct cpuinfo_x86 *c)
 {
 	if (mce_disabled==1)
 		return;
diff --git a/arch/i386/kernel/cpu/mcheck/p4.c b/arch/i386/kernel/cpu/mcheck/p4.c
--- a/arch/i386/kernel/cpu/mcheck/p4.c
+++ b/arch/i386/kernel/cpu/mcheck/p4.c
@@ -78,7 +78,7 @@ fastcall void smp_thermal_interrupt(stru
 }
 
 /* P4/Xeon Thermal regulation detect and init */
-static void __init intel_init_thermal(struct cpuinfo_x86 *c)
+static void __devinit intel_init_thermal(struct cpuinfo_x86 *c)
 {
 	u32 l, h;
 	unsigned int cpu = smp_processor_id();
@@ -232,7 +232,7 @@ static fastcall void intel_machine_check
 }
 
 
-void __init intel_p4_mcheck_init(struct cpuinfo_x86 *c)
+void __devinit intel_p4_mcheck_init(struct cpuinfo_x86 *c)
 {
 	u32 l, h;
 	int i;
diff --git a/arch/i386/kernel/cpu/mcheck/p5.c b/arch/i386/kernel/cpu/mcheck/p5.c
--- a/arch/i386/kernel/cpu/mcheck/p5.c
+++ b/arch/i386/kernel/cpu/mcheck/p5.c
@@ -29,7 +29,7 @@ static fastcall void pentium_machine_che
 }
 
 /* Set up machine check reporting for processors with Intel style MCE */
-void __init intel_p5_mcheck_init(struct cpuinfo_x86 *c)
+void __devinit intel_p5_mcheck_init(struct cpuinfo_x86 *c)
 {
 	u32 l, h;
 	
diff --git a/arch/i386/kernel/cpu/mcheck/p6.c b/arch/i386/kernel/cpu/mcheck/p6.c
--- a/arch/i386/kernel/cpu/mcheck/p6.c
+++ b/arch/i386/kernel/cpu/mcheck/p6.c
@@ -80,7 +80,7 @@ static fastcall void intel_machine_check
 }
 
 /* Set up machine check reporting for processors with Intel style MCE */
-void __init intel_p6_mcheck_init(struct cpuinfo_x86 *c)
+void __devinit intel_p6_mcheck_init(struct cpuinfo_x86 *c)
 {
 	u32 l, h;
 	int i;
diff --git a/arch/i386/kernel/cpu/mcheck/winchip.c b/arch/i386/kernel/cpu/mcheck/winchip.c
--- a/arch/i386/kernel/cpu/mcheck/winchip.c
+++ b/arch/i386/kernel/cpu/mcheck/winchip.c
@@ -23,7 +23,7 @@ static fastcall void winchip_machine_che
 }
 
 /* Set up machine check reporting on the Winchip C6 series */
-void __init winchip_mcheck_init(struct cpuinfo_x86 *c)
+void __devinit winchip_mcheck_init(struct cpuinfo_x86 *c)
 {
 	u32 lo, hi;
 	machine_check_vector = winchip_machine_check;
diff --git a/arch/i386/kernel/cpu/mtrr/generic.c b/arch/i386/kernel/cpu/mtrr/generic.c
--- a/arch/i386/kernel/cpu/mtrr/generic.c
+++ b/arch/i386/kernel/cpu/mtrr/generic.c
@@ -67,14 +67,6 @@ void __init get_mtrr_state(void)
 	mtrr_state.enabled = (lo & 0xc00) >> 10;
 }
 
-/*  Free resources associated with a struct mtrr_state  */
-void __init finalize_mtrr_state(void)
-{
-	if (mtrr_state.var_ranges)
-		kfree(mtrr_state.var_ranges);
-	mtrr_state.var_ranges = NULL;
-}
-
 /*  Some BIOS's are fucked and don't set all MTRRs the same!  */
 void __init mtrr_state_warn(void)
 {
@@ -335,6 +327,9 @@ static void generic_set_mtrr(unsigned in
 */
 {
 	unsigned long flags;
+	struct mtrr_var_range *vr;
+
+	vr = &mtrr_state.var_ranges[reg];
 
 	local_irq_save(flags);
 	prepare_set();
@@ -343,11 +338,15 @@ static void generic_set_mtrr(unsigned in
 		/* The invalid bit is kept in the mask, so we simply clear the
 		   relevant mask register to disable a range. */
 		mtrr_wrmsr(MTRRphysMask_MSR(reg), 0, 0);
+		memset(vr, 0, sizeof(struct mtrr_var_range));
 	} else {
-		mtrr_wrmsr(MTRRphysBase_MSR(reg), base << PAGE_SHIFT | type,
-		      (base & size_and_mask) >> (32 - PAGE_SHIFT));
-		mtrr_wrmsr(MTRRphysMask_MSR(reg), -size << PAGE_SHIFT | 0x800,
-		      (-size & size_and_mask) >> (32 - PAGE_SHIFT));
+		vr->base_lo = base << PAGE_SHIFT | type;
+		vr->base_hi = (base & size_and_mask) >> (32 - PAGE_SHIFT);
+		vr->mask_lo = -size << PAGE_SHIFT | 0x800;
+		vr->mask_hi = (-size & size_and_mask) >> (32 - PAGE_SHIFT);
+
+		mtrr_wrmsr(MTRRphysBase_MSR(reg), vr->base_lo, vr->base_hi);
+		mtrr_wrmsr(MTRRphysMask_MSR(reg), vr->mask_lo, vr->mask_hi);
 	}
 
 	post_set();
diff --git a/arch/i386/kernel/cpu/mtrr/main.c b/arch/i386/kernel/cpu/mtrr/main.c
--- a/arch/i386/kernel/cpu/mtrr/main.c
+++ b/arch/i386/kernel/cpu/mtrr/main.c
@@ -332,6 +332,8 @@ int mtrr_add_page(unsigned long base, un
 
 	error = -EINVAL;
 
+	/* No CPU hotplug when we change MTRR entries */
+	lock_cpu_hotplug();
 	/*  Search for existing MTRR  */
 	down(&main_lock);
 	for (i = 0; i < num_var_ranges; ++i) {
@@ -372,9 +374,23 @@ int mtrr_add_page(unsigned long base, un
 	error = i;
  out:
 	up(&main_lock);
+	unlock_cpu_hotplug();
 	return error;
 }
 
+static int mtrr_check(unsigned long base, unsigned long size)
+{
+	if ((base & (PAGE_SIZE - 1)) || (size & (PAGE_SIZE - 1))) {
+		printk(KERN_WARNING
+			"mtrr: size and base must be multiples of 4 kiB\n");
+		printk(KERN_DEBUG
+			"mtrr: size: 0x%lx  base: 0x%lx\n", size, base);
+		dump_stack();
+		return -1;
+	}
+	return 0;
+}
+
 /**
  *	mtrr_add - Add a memory type region
  *	@base: Physical base address of region
@@ -415,11 +431,8 @@ int
 mtrr_add(unsigned long base, unsigned long size, unsigned int type,
 	 char increment)
 {
-	if ((base & (PAGE_SIZE - 1)) || (size & (PAGE_SIZE - 1))) {
-		printk(KERN_WARNING "mtrr: size and base must be multiples of 4 kiB\n");
-		printk(KERN_DEBUG "mtrr: size: 0x%lx  base: 0x%lx\n", size, base);
+	if (mtrr_check(base, size))
 		return -EINVAL;
-	}
 	return mtrr_add_page(base >> PAGE_SHIFT, size >> PAGE_SHIFT, type,
 			     increment);
 }
@@ -451,6 +464,8 @@ int mtrr_del_page(int reg, unsigned long
 		return -ENXIO;
 
 	max = num_var_ranges;
+	/* No CPU hotplug when we change MTRR entries */
+	lock_cpu_hotplug();
 	down(&main_lock);
 	if (reg < 0) {
 		/*  Search for existing MTRR  */
@@ -491,6 +506,7 @@ int mtrr_del_page(int reg, unsigned long
 	error = reg;
  out:
 	up(&main_lock);
+	unlock_cpu_hotplug();
 	return error;
 }
 /**
@@ -511,11 +527,8 @@ int mtrr_del_page(int reg, unsigned long
 int
 mtrr_del(int reg, unsigned long base, unsigned long size)
 {
-	if ((base & (PAGE_SIZE - 1)) || (size & (PAGE_SIZE - 1))) {
-		printk(KERN_INFO "mtrr: size and base must be multiples of 4 kiB\n");
-		printk(KERN_DEBUG "mtrr: size: 0x%lx  base: 0x%lx\n", size, base);
+	if (mtrr_check(base, size))
 		return -EINVAL;
-	}
 	return mtrr_del_page(reg, base >> PAGE_SHIFT, size >> PAGE_SHIFT);
 }
 
@@ -537,21 +550,9 @@ static void __init init_ifs(void)
 	centaur_init_mtrr();
 }
 
-static void __init init_other_cpus(void)
-{
-	if (use_intel())
-		get_mtrr_state();
-
-	/* bring up the other processors */
-	set_mtrr(~0U,0,0,0);
-
-	if (use_intel()) {
-		finalize_mtrr_state();
-		mtrr_state_warn();
-	}
-}
-
-
+/* The suspend/resume methods are only for CPU without MTRR. CPU using generic
+ * MTRR driver doesn't require this
+ */
 struct mtrr_value {
 	mtrr_type	ltype;
 	unsigned long	lbase;
@@ -604,13 +605,13 @@ static struct sysdev_driver mtrr_sysdev_
 
 
 /**
- * mtrr_init - initialize mtrrs on the boot CPU
+ * mtrr_bp_init - initialize mtrrs on the boot CPU
  *
  * This needs to be called early; before any of the other CPUs are 
  * initialized (i.e. before smp_init()).
  * 
  */
-static int __init mtrr_init(void)
+void __init mtrr_bp_init(void)
 {
 	init_ifs();
 
@@ -667,12 +668,48 @@ static int __init mtrr_init(void)
 	if (mtrr_if) {
 		set_num_var_ranges();
 		init_table();
-		init_other_cpus();
-
-		return sysdev_driver_register(&cpu_sysdev_class,
-					      &mtrr_sysdev_driver);
+		if (use_intel())
+			get_mtrr_state();
 	}
-	return -ENXIO;
 }
 
-subsys_initcall(mtrr_init);
+void mtrr_ap_init(void)
+{
+	unsigned long flags;
+
+	if (!mtrr_if || !use_intel())
+		return;
+	/*
+	 * Ideally we should hold main_lock here to avoid mtrr entries changed,
+	 * but this routine will be called in cpu boot time, holding the lock
+	 * breaks it. This routine is called in two cases: 1.very earily time
+	 * of software resume, when there absolutely isn't mtrr entry changes;
+	 * 2.cpu hotadd time. We let mtrr_add/del_page hold cpuhotplug lock to
+	 * prevent mtrr entry changes
+	 */
+	local_irq_save(flags);
+
+	mtrr_if->set_all();
+
+	local_irq_restore(flags);
+}
+
+static int __init mtrr_init_finialize(void)
+{
+	if (!mtrr_if)
+		return 0;
+	if (use_intel())
+		mtrr_state_warn();
+	else {
+		/* The CPUs haven't MTRR and seemes not support SMP. They have
+		 * specific drivers, we use a tricky method to support
+		 * suspend/resume for them.
+		 * TBD: is there any system with such CPU which supports
+		 * suspend/resume?  if no, we should remove the code.
+		 */
+		sysdev_driver_register(&cpu_sysdev_class,
+			&mtrr_sysdev_driver);
+	}
+	return 0;
+}
+subsys_initcall(mtrr_init_finialize);
diff --git a/arch/i386/kernel/cpu/mtrr/mtrr.h b/arch/i386/kernel/cpu/mtrr/mtrr.h
--- a/arch/i386/kernel/cpu/mtrr/mtrr.h
+++ b/arch/i386/kernel/cpu/mtrr/mtrr.h
@@ -91,7 +91,6 @@ extern struct mtrr_ops * mtrr_if;
 
 extern unsigned int num_var_ranges;
 
-void finalize_mtrr_state(void);
 void mtrr_state_warn(void);
 char *mtrr_attrib_to_str(int x);
 void mtrr_wrmsr(unsigned, unsigned, unsigned);
diff --git a/arch/i386/kernel/cpu/proc.c b/arch/i386/kernel/cpu/proc.c
--- a/arch/i386/kernel/cpu/proc.c
+++ b/arch/i386/kernel/cpu/proc.c
@@ -86,7 +86,7 @@ static int show_cpuinfo(struct seq_file 
 		seq_printf(m, "stepping\t: unknown\n");
 
 	if ( cpu_has(c, X86_FEATURE_TSC) ) {
-		seq_printf(m, "cpu MHz\t\t: %lu.%03lu\n",
+		seq_printf(m, "cpu MHz\t\t: %u.%03u\n",
 			cpu_khz / 1000, (cpu_khz % 1000));
 	}
 
diff --git a/arch/i386/kernel/cpu/transmeta.c b/arch/i386/kernel/cpu/transmeta.c
--- a/arch/i386/kernel/cpu/transmeta.c
+++ b/arch/i386/kernel/cpu/transmeta.c
@@ -76,6 +76,12 @@ static void __init init_transmeta(struct
 #define USER686 (X86_FEATURE_TSC|X86_FEATURE_CX8|X86_FEATURE_CMOV)
         if ( c->x86 == 5 && (c->x86_capability[0] & USER686) == USER686 )
 		c->x86 = 6;
+
+#ifdef CONFIG_SYSCTL
+	/* randomize_va_space slows us down enormously;
+	   it probably triggers retranslation of x86->native bytecode */
+	randomize_va_space = 0;
+#endif
 }
 
 static void transmeta_identify(struct cpuinfo_x86 * c)
diff --git a/arch/i386/kernel/cpuid.c b/arch/i386/kernel/cpuid.c
--- a/arch/i386/kernel/cpuid.c
+++ b/arch/i386/kernel/cpuid.c
@@ -45,7 +45,7 @@
 #include <asm/uaccess.h>
 #include <asm/system.h>
 
-static struct class_simple *cpuid_class;
+static struct class *cpuid_class;
 
 #ifdef CONFIG_SMP
 
@@ -158,12 +158,12 @@ static struct file_operations cpuid_fops
 	.open = cpuid_open,
 };
 
-static int cpuid_class_simple_device_add(int i) 
+static int cpuid_class_device_create(int i)
 {
 	int err = 0;
 	struct class_device *class_err;
 
-	class_err = class_simple_device_add(cpuid_class, MKDEV(CPUID_MAJOR, i), NULL, "cpu%d",i);
+	class_err = class_device_create(cpuid_class, MKDEV(CPUID_MAJOR, i), NULL, "cpu%d",i);
 	if (IS_ERR(class_err))
 		err = PTR_ERR(class_err);
 	return err;
@@ -175,10 +175,10 @@ static int __devinit cpuid_class_cpu_cal
 
 	switch (action) {
 	case CPU_ONLINE:
-		cpuid_class_simple_device_add(cpu);
+		cpuid_class_device_create(cpu);
 		break;
 	case CPU_DEAD:
-		class_simple_device_remove(MKDEV(CPUID_MAJOR, cpu));
+		class_device_destroy(cpuid_class, MKDEV(CPUID_MAJOR, cpu));
 		break;
 	}
 	return NOTIFY_OK;
@@ -200,13 +200,13 @@ static int __init cpuid_init(void)
 		err = -EBUSY;
 		goto out;
 	}
-	cpuid_class = class_simple_create(THIS_MODULE, "cpuid");
+	cpuid_class = class_create(THIS_MODULE, "cpuid");
 	if (IS_ERR(cpuid_class)) {
 		err = PTR_ERR(cpuid_class);
 		goto out_chrdev;
 	}
 	for_each_online_cpu(i) {
-		err = cpuid_class_simple_device_add(i);
+		err = cpuid_class_device_create(i);
 		if (err != 0) 
 			goto out_class;
 	}
@@ -218,9 +218,9 @@ static int __init cpuid_init(void)
 out_class:
 	i = 0;
 	for_each_online_cpu(i) {
-		class_simple_device_remove(MKDEV(CPUID_MAJOR, i));
+		class_device_destroy(cpuid_class, MKDEV(CPUID_MAJOR, i));
 	}
-	class_simple_destroy(cpuid_class);
+	class_destroy(cpuid_class);
 out_chrdev:
 	unregister_chrdev(CPUID_MAJOR, "cpu/cpuid");	
 out:
@@ -232,8 +232,8 @@ static void __exit cpuid_exit(void)
 	int cpu = 0;
 
 	for_each_online_cpu(cpu)
-		class_simple_device_remove(MKDEV(CPUID_MAJOR, cpu));
-	class_simple_destroy(cpuid_class);
+		class_device_destroy(cpuid_class, MKDEV(CPUID_MAJOR, cpu));
+	class_destroy(cpuid_class);
 	unregister_chrdev(CPUID_MAJOR, "cpu/cpuid");
 	unregister_cpu_notifier(&cpuid_class_cpu_notifier);
 }
diff --git a/arch/i386/kernel/crash.c b/arch/i386/kernel/crash.c
new file mode 100644
--- /dev/null
+++ b/arch/i386/kernel/crash.c
@@ -0,0 +1,223 @@
+/*
+ * Architecture specific (i386) functions for kexec based crash dumps.
+ *
+ * Created by: Hariprasad Nellitheertha (hari@in.ibm.com)
+ *
+ * Copyright (C) IBM Corporation, 2004. All rights reserved.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/smp.h>
+#include <linux/irq.h>
+#include <linux/reboot.h>
+#include <linux/kexec.h>
+#include <linux/irq.h>
+#include <linux/delay.h>
+#include <linux/elf.h>
+#include <linux/elfcore.h>
+
+#include <asm/processor.h>
+#include <asm/hardirq.h>
+#include <asm/nmi.h>
+#include <asm/hw_irq.h>
+#include <asm/apic.h>
+#include <mach_ipi.h>
+
+
+note_buf_t crash_notes[NR_CPUS];
+/* This keeps a track of which one is crashing cpu. */
+static int crashing_cpu;
+
+static u32 *append_elf_note(u32 *buf, char *name, unsigned type, void *data,
+							       size_t data_len)
+{
+	struct elf_note note;
+
+	note.n_namesz = strlen(name) + 1;
+	note.n_descsz = data_len;
+	note.n_type   = type;
+	memcpy(buf, &note, sizeof(note));
+	buf += (sizeof(note) +3)/4;
+	memcpy(buf, name, note.n_namesz);
+	buf += (note.n_namesz + 3)/4;
+	memcpy(buf, data, note.n_descsz);
+	buf += (note.n_descsz + 3)/4;
+
+	return buf;
+}
+
+static void final_note(u32 *buf)
+{
+	struct elf_note note;
+
+	note.n_namesz = 0;
+	note.n_descsz = 0;
+	note.n_type   = 0;
+	memcpy(buf, &note, sizeof(note));
+}
+
+static void crash_save_this_cpu(struct pt_regs *regs, int cpu)
+{
+	struct elf_prstatus prstatus;
+	u32 *buf;
+
+	if ((cpu < 0) || (cpu >= NR_CPUS))
+		return;
+
+	/* Using ELF notes here is opportunistic.
+	 * I need a well defined structure format
+	 * for the data I pass, and I need tags
+	 * on the data to indicate what information I have
+	 * squirrelled away.  ELF notes happen to provide
+	 * all of that that no need to invent something new.
+	 */
+	buf = &crash_notes[cpu][0];
+	memset(&prstatus, 0, sizeof(prstatus));
+	prstatus.pr_pid = current->pid;
+	elf_core_copy_regs(&prstatus.pr_reg, regs);
+	buf = append_elf_note(buf, "CORE", NT_PRSTATUS, &prstatus,
+				sizeof(prstatus));
+	final_note(buf);
+}
+
+static void crash_get_current_regs(struct pt_regs *regs)
+{
+	__asm__ __volatile__("movl %%ebx,%0" : "=m"(regs->ebx));
+	__asm__ __volatile__("movl %%ecx,%0" : "=m"(regs->ecx));
+	__asm__ __volatile__("movl %%edx,%0" : "=m"(regs->edx));
+	__asm__ __volatile__("movl %%esi,%0" : "=m"(regs->esi));
+	__asm__ __volatile__("movl %%edi,%0" : "=m"(regs->edi));
+	__asm__ __volatile__("movl %%ebp,%0" : "=m"(regs->ebp));
+	__asm__ __volatile__("movl %%eax,%0" : "=m"(regs->eax));
+	__asm__ __volatile__("movl %%esp,%0" : "=m"(regs->esp));
+	__asm__ __volatile__("movw %%ss, %%ax;" :"=a"(regs->xss));
+	__asm__ __volatile__("movw %%cs, %%ax;" :"=a"(regs->xcs));
+	__asm__ __volatile__("movw %%ds, %%ax;" :"=a"(regs->xds));
+	__asm__ __volatile__("movw %%es, %%ax;" :"=a"(regs->xes));
+	__asm__ __volatile__("pushfl; popl %0" :"=m"(regs->eflags));
+
+	regs->eip = (unsigned long)current_text_addr();
+}
+
+/* CPU does not save ss and esp on stack if execution is already
+ * running in kernel mode at the time of NMI occurrence. This code
+ * fixes it.
+ */
+static void crash_setup_regs(struct pt_regs *newregs, struct pt_regs *oldregs)
+{
+	memcpy(newregs, oldregs, sizeof(*newregs));
+	newregs->esp = (unsigned long)&(oldregs->esp);
+	__asm__ __volatile__("xorl %eax, %eax;");
+	__asm__ __volatile__ ("movw %%ss, %%ax;" :"=a"(newregs->xss));
+}
+
+/* We may have saved_regs from where the error came from
+ * or it is NULL if via a direct panic().
+ */
+static void crash_save_self(struct pt_regs *saved_regs)
+{
+	struct pt_regs regs;
+	int cpu;
+
+	cpu = smp_processor_id();
+	if (saved_regs)
+		crash_setup_regs(&regs, saved_regs);
+	else
+		crash_get_current_regs(&regs);
+	crash_save_this_cpu(&regs, cpu);
+}
+
+#ifdef CONFIG_SMP
+static atomic_t waiting_for_crash_ipi;
+
+static int crash_nmi_callback(struct pt_regs *regs, int cpu)
+{
+	struct pt_regs fixed_regs;
+
+	/* Don't do anything if this handler is invoked on crashing cpu.
+	 * Otherwise, system will completely hang. Crashing cpu can get
+	 * an NMI if system was initially booted with nmi_watchdog parameter.
+	 */
+	if (cpu == crashing_cpu)
+		return 1;
+	local_irq_disable();
+
+	if (!user_mode(regs)) {
+		crash_setup_regs(&fixed_regs, regs);
+		regs = &fixed_regs;
+	}
+	crash_save_this_cpu(regs, cpu);
+	disable_local_APIC();
+	atomic_dec(&waiting_for_crash_ipi);
+	/* Assume hlt works */
+	__asm__("hlt");
+	for(;;);
+
+	return 1;
+}
+
+/*
+ * By using the NMI code instead of a vector we just sneak thru the
+ * word generator coming out with just what we want.  AND it does
+ * not matter if clustered_apic_mode is set or not.
+ */
+static void smp_send_nmi_allbutself(void)
+{
+	send_IPI_allbutself(APIC_DM_NMI);
+}
+
+static void nmi_shootdown_cpus(void)
+{
+	unsigned long msecs;
+
+	atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1);
+	/* Would it be better to replace the trap vector here? */
+	set_nmi_callback(crash_nmi_callback);
+	/* Ensure the new callback function is set before sending
+	 * out the NMI
+	 */
+	wmb();
+
+	smp_send_nmi_allbutself();
+
+	msecs = 1000; /* Wait at most a second for the other cpus to stop */
+	while ((atomic_read(&waiting_for_crash_ipi) > 0) && msecs) {
+		mdelay(1);
+		msecs--;
+	}
+
+	/* Leave the nmi callback set */
+	disable_local_APIC();
+}
+#else
+static void nmi_shootdown_cpus(void)
+{
+	/* There are no cpus to shootdown */
+}
+#endif
+
+void machine_crash_shutdown(struct pt_regs *regs)
+{
+	/* This function is only called after the system
+	 * has paniced or is otherwise in a critical state.
+	 * The minimum amount of code to allow a kexec'd kernel
+	 * to run successfully needs to happen here.
+	 *
+	 * In practice this means shooting down the other cpus in
+	 * an SMP system.
+	 */
+	/* The kernel is broken so disable interrupts */
+	local_irq_disable();
+
+	/* Make a note of crashing cpu. Will be used in NMI callback.*/
+	crashing_cpu = smp_processor_id();
+	nmi_shootdown_cpus();
+	lapic_shutdown();
+#if defined(CONFIG_X86_IO_APIC)
+	disable_IO_APIC();
+#endif
+	crash_save_self(regs);
+}
diff --git a/arch/i386/kernel/dmi_scan.c b/arch/i386/kernel/dmi_scan.c
--- a/arch/i386/kernel/dmi_scan.c
+++ b/arch/i386/kernel/dmi_scan.c
@@ -1,22 +1,15 @@
 #include <linux/types.h>
-#include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/init.h>
 #include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/acpi.h>
-#include <asm/io.h>
-#include <linux/pm.h>
-#include <asm/system.h>
 #include <linux/dmi.h>
 #include <linux/bootmem.h>
 
 
-struct dmi_header
-{
-	u8	type;
-	u8	length;
-	u16	handle;
+struct dmi_header {
+	u8 type;
+	u8 length;
+	u16 handle;
 };
 
 #undef DMI_DEBUG
@@ -29,15 +22,13 @@ struct dmi_header
 
 static char * __init dmi_string(struct dmi_header *dm, u8 s)
 {
-	u8 *bp=(u8 *)dm;
-	bp+=dm->length;
-	if(!s)
+	u8 *bp = ((u8 *) dm) + dm->length;
+
+	if (!s)
 		return "";
 	s--;
-	while(s>0 && *bp)
-	{
-		bp+=strlen(bp);
-		bp++;
+	while (s > 0 && *bp) {
+		bp += strlen(bp) + 1;
 		s--;
 	}
 	return bp;
@@ -47,16 +38,14 @@ static char * __init dmi_string(struct d
  *	We have to be cautious here. We have seen BIOSes with DMI pointers
  *	pointing to completely the wrong place for example
  */
- 
-static int __init dmi_table(u32 base, int len, int num, void (*decode)(struct dmi_header *))
+static int __init dmi_table(u32 base, int len, int num,
+			    void (*decode)(struct dmi_header *))
 {
-	u8 *buf;
-	struct dmi_header *dm;
-	u8 *data;
-	int i=0;
+	u8 *buf, *data;
+	int i = 0;
 		
 	buf = bt_ioremap(base, len);
-	if(buf==NULL)
+	if (buf == NULL)
 		return -1;
 
 	data = buf;
@@ -65,36 +54,34 @@ static int __init dmi_table(u32 base, in
  	 *	Stop when we see all the items the table claimed to have
  	 *	OR we run off the end of the table (also happens)
  	 */
- 
-	while(i<num && data-buf+sizeof(struct dmi_header)<=len)
-	{
-		dm=(struct dmi_header *)data;
+	while ((i < num) && (data - buf + sizeof(struct dmi_header)) <= len) {
+		struct dmi_header *dm = (struct dmi_header *)data;
 		/*
 		 *  We want to know the total length (formated area and strings)
 		 *  before decoding to make sure we won't run off the table in
 		 *  dmi_decode or dmi_string
 		 */
-		data+=dm->length;
-		while(data-buf<len-1 && (data[0] || data[1]))
+		data += dm->length;
+		while ((data - buf < len - 1) && (data[0] || data[1]))
 			data++;
-		if(data-buf<len-1)
+		if (data - buf < len - 1)
 			decode(dm);
-		data+=2;
+		data += 2;
 		i++;
 	}
 	bt_iounmap(buf, len);
 	return 0;
 }
 
-
-inline static int __init dmi_checksum(u8 *buf)
+static int __init dmi_checksum(u8 *buf)
 {
-	u8 sum=0;
+	u8 sum = 0;
 	int a;
 	
-	for(a=0; a<15; a++)
-		sum+=buf[a];
-	return (sum==0);
+	for (a = 0; a < 15; a++)
+		sum += buf[a];
+
+	return sum == 0;
 }
 
 static int __init dmi_iterate(void (*decode)(struct dmi_header *))
@@ -110,28 +97,30 @@ static int __init dmi_iterate(void (*dec
 	p = ioremap(0xF0000, 0x10000);
 	if (p == NULL)
 		return -1;
+
 	for (q = p; q < p + 0x10000; q += 16) {
 		memcpy_fromio(buf, q, 15);
-		if(memcmp(buf, "_DMI_", 5)==0 && dmi_checksum(buf))
-		{
-			u16 num=buf[13]<<8|buf[12];
-			u16 len=buf[7]<<8|buf[6];
-			u32 base=buf[11]<<24|buf[10]<<16|buf[9]<<8|buf[8];
+		if ((memcmp(buf, "_DMI_", 5) == 0) && dmi_checksum(buf)) {
+			u16 num = (buf[13] << 8) | buf[12];
+			u16 len = (buf[7] << 8) | buf[6];
+			u32 base = (buf[11] << 24) | (buf[10] << 16) |
+				   (buf[9] << 8) | buf[8];
 
 			/*
 			 * DMI version 0.0 means that the real version is taken from
 			 * the SMBIOS version, which we don't know at this point.
 			 */
-			if(buf[14]!=0)
+			if (buf[14] != 0)
 				printk(KERN_INFO "DMI %d.%d present.\n",
-					buf[14]>>4, buf[14]&0x0F);
+					buf[14] >> 4, buf[14] & 0xF);
 			else
 				printk(KERN_INFO "DMI present.\n");
+
 			dmi_printk((KERN_INFO "%d structures occupying %d bytes.\n",
 				num, len));
-			dmi_printk((KERN_INFO "DMI table at 0x%08X.\n",
-				base));
-			if(dmi_table(base,len, num, decode)==0)
+			dmi_printk((KERN_INFO "DMI table at 0x%08X.\n", base));
+
+			if (dmi_table(base,len, num, decode) == 0)
 				return 0;
 		}
 	}
@@ -143,16 +132,17 @@ static char *dmi_ident[DMI_STRING_MAX];
 /*
  *	Save a DMI string
  */
- 
 static void __init dmi_save_ident(struct dmi_header *dm, int slot, int string)
 {
 	char *d = (char*)dm;
 	char *p = dmi_string(dm, d[string]);
-	if(p==NULL || *p == 0)
+
+	if (p == NULL || *p == 0)
 		return;
 	if (dmi_ident[slot])
 		return;
-	dmi_ident[slot] = alloc_bootmem(strlen(p)+1);
+
+	dmi_ident[slot] = alloc_bootmem(strlen(p) + 1);
 	if(dmi_ident[slot])
 		strcpy(dmi_ident[slot], p);
 	else
@@ -160,281 +150,47 @@ static void __init dmi_save_ident(struct
 }
 
 /*
- * Ugly compatibility crap.
- */
-#define dmi_blacklist	dmi_system_id
-#define NO_MATCH	{ DMI_NONE, NULL}
-#define MATCH		DMI_MATCH
-
-/*
- * Toshiba keyboard likes to repeat keys when they are not repeated.
- */
-
-static __init int broken_toshiba_keyboard(struct dmi_blacklist *d)
-{
-	printk(KERN_WARNING "Toshiba with broken keyboard detected. If your keyboard sometimes generates 3 keypresses instead of one, see http://davyd.ucc.asn.au/projects/toshiba/README\n");
-	return 0;
-}
-
-
-#ifdef CONFIG_ACPI_SLEEP
-static __init int reset_videomode_after_s3(struct dmi_blacklist *d)
-{
-	/* See acpi_wakeup.S */
-	extern long acpi_video_flags;
-	acpi_video_flags |= 2;
-	return 0;
-}
-#endif
-
-
-#ifdef	CONFIG_ACPI_BOOT
-extern int acpi_force;
-
-static __init __attribute__((unused)) int dmi_disable_acpi(struct dmi_blacklist *d) 
-{ 
-	if (!acpi_force) { 
-		printk(KERN_NOTICE "%s detected: acpi off\n",d->ident); 
-		disable_acpi();
-	} else { 
-		printk(KERN_NOTICE 
-		       "Warning: DMI blacklist says broken, but acpi forced\n"); 
-	}
-	return 0;
-} 
-
-/*
- * Limit ACPI to CPU enumeration for HT
- */
-static __init __attribute__((unused)) int force_acpi_ht(struct dmi_blacklist *d) 
-{ 
-	if (!acpi_force) { 
-		printk(KERN_NOTICE "%s detected: force use of acpi=ht\n", d->ident); 
-		disable_acpi();
-		acpi_ht = 1; 
-	} else { 
-		printk(KERN_NOTICE 
-		       "Warning: acpi=force overrules DMI blacklist: acpi=ht\n"); 
-	}
-	return 0;
-} 
-#endif
-
-#ifdef	CONFIG_ACPI_PCI
-static __init int disable_acpi_irq(struct dmi_blacklist *d) 
-{
-	if (!acpi_force) {
-		printk(KERN_NOTICE "%s detected: force use of acpi=noirq\n",
-		       d->ident); 	
-		acpi_noirq_set();
-	}
-	return 0;
-}
-static __init int disable_acpi_pci(struct dmi_blacklist *d) 
-{
-	if (!acpi_force) {
-		printk(KERN_NOTICE "%s detected: force use of pci=noacpi\n",
-		       d->ident); 	
-		acpi_disable_pci();
-	}
-	return 0;
-}  
-#endif
-
-/*
- *	Process the DMI blacklists
- */
- 
-
-/*
- *	This will be expanded over time to force things like the APM 
- *	interrupt mask settings according to the laptop
- */
- 
-static __initdata struct dmi_blacklist dmi_blacklist[]={
-
-	{ broken_toshiba_keyboard, "Toshiba Satellite 4030cdt", { /* Keyboard generates spurious repeats */
-			MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"),
-			NO_MATCH, NO_MATCH, NO_MATCH
-			} },
-#ifdef CONFIG_ACPI_SLEEP
-	{ reset_videomode_after_s3, "Toshiba Satellite 4030cdt", { /* Reset video mode after returning from ACPI S3 sleep */
-			MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"),
-			NO_MATCH, NO_MATCH, NO_MATCH
-			} },
-#endif
-
-#ifdef	CONFIG_ACPI_BOOT
-	/*
-	 * If your system is blacklisted here, but you find that acpi=force
-	 * works for you, please contact acpi-devel@sourceforge.net
-	 */
-
-	/*
-	 *	Boxes that need ACPI disabled
-	 */
-
-	{ dmi_disable_acpi, "IBM Thinkpad", {
-			MATCH(DMI_BOARD_VENDOR, "IBM"),
-			MATCH(DMI_BOARD_NAME, "2629H1G"),
-			NO_MATCH, NO_MATCH }},
-
-	/*
-	 *	Boxes that need acpi=ht 
-	 */
-
-	{ force_acpi_ht, "FSC Primergy T850", {
-			MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
-			MATCH(DMI_PRODUCT_NAME, "PRIMERGY T850"),
-			NO_MATCH, NO_MATCH }},
-
-	{ force_acpi_ht, "DELL GX240", {
-			MATCH(DMI_BOARD_VENDOR, "Dell Computer Corporation"),
-			MATCH(DMI_BOARD_NAME, "OptiPlex GX240"),
-			NO_MATCH, NO_MATCH }},
-
-	{ force_acpi_ht, "HP VISUALIZE NT Workstation", {
-			MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"),
-			MATCH(DMI_PRODUCT_NAME, "HP VISUALIZE NT Workstation"),
-			NO_MATCH, NO_MATCH }},
-
-	{ force_acpi_ht, "Compaq Workstation W8000", {
-			MATCH(DMI_SYS_VENDOR, "Compaq"),
-			MATCH(DMI_PRODUCT_NAME, "Workstation W8000"),
-			NO_MATCH, NO_MATCH }},
-
-	{ force_acpi_ht, "ASUS P4B266", {
-			MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
-			MATCH(DMI_BOARD_NAME, "P4B266"),
-			NO_MATCH, NO_MATCH }},
-
-	{ force_acpi_ht, "ASUS P2B-DS", {
-			MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
-			MATCH(DMI_BOARD_NAME, "P2B-DS"),
-			NO_MATCH, NO_MATCH }},
-
-	{ force_acpi_ht, "ASUS CUR-DLS", {
-			MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
-			MATCH(DMI_BOARD_NAME, "CUR-DLS"),
-			NO_MATCH, NO_MATCH }},
-
-	{ force_acpi_ht, "ABIT i440BX-W83977", {
-			MATCH(DMI_BOARD_VENDOR, "ABIT <http://www.abit.com>"),
-			MATCH(DMI_BOARD_NAME, "i440BX-W83977 (BP6)"),
-			NO_MATCH, NO_MATCH }},
-
-	{ force_acpi_ht, "IBM Bladecenter", {
-			MATCH(DMI_BOARD_VENDOR, "IBM"),
-			MATCH(DMI_BOARD_NAME, "IBM eServer BladeCenter HS20"),
-			NO_MATCH, NO_MATCH }},
-
-	{ force_acpi_ht, "IBM eServer xSeries 360", {
-			MATCH(DMI_BOARD_VENDOR, "IBM"),
-			MATCH(DMI_BOARD_NAME, "eServer xSeries 360"),
-			NO_MATCH, NO_MATCH }},
-
-	{ force_acpi_ht, "IBM eserver xSeries 330", {
-			MATCH(DMI_BOARD_VENDOR, "IBM"),
-			MATCH(DMI_BOARD_NAME, "eserver xSeries 330"),
-			NO_MATCH, NO_MATCH }},
-
-	{ force_acpi_ht, "IBM eserver xSeries 440", {
-			MATCH(DMI_BOARD_VENDOR, "IBM"),
-			MATCH(DMI_PRODUCT_NAME, "eserver xSeries 440"),
-			NO_MATCH, NO_MATCH }},
-
-#endif	// CONFIG_ACPI_BOOT
-
-#ifdef	CONFIG_ACPI_PCI
-	/*
-	 *	Boxes that need ACPI PCI IRQ routing disabled
-	 */
-
-	{ disable_acpi_irq, "ASUS A7V", {
-			MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC"),
-			MATCH(DMI_BOARD_NAME, "<A7V>"),
-			/* newer BIOS, Revision 1011, does work */
-			MATCH(DMI_BIOS_VERSION, "ASUS A7V ACPI BIOS Revision 1007"),
-			NO_MATCH }},
-
-	/*
-	 *	Boxes that need ACPI PCI IRQ routing and PCI scan disabled
-	 */
-	{ disable_acpi_pci, "ASUS PR-DLS", {	/* _BBN 0 bug */
-			MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
-			MATCH(DMI_BOARD_NAME, "PR-DLS"),
-			MATCH(DMI_BIOS_VERSION, "ASUS PR-DLS ACPI BIOS Revision 1010"),
-			MATCH(DMI_BIOS_DATE, "03/21/2003") }},
-
- 	{ disable_acpi_pci, "Acer TravelMate 36x Laptop", {
- 			MATCH(DMI_SYS_VENDOR, "Acer"),
- 			MATCH(DMI_PRODUCT_NAME, "TravelMate 360"),
- 			NO_MATCH, NO_MATCH
- 			} },
-
-#endif
-
-	{ NULL, }
-};
-
-/*
  *	Process a DMI table entry. Right now all we care about are the BIOS
  *	and machine entries. For 2.5 we should pull the smbus controller info
  *	out of here.
  */
-
 static void __init dmi_decode(struct dmi_header *dm)
 {
-#ifdef DMI_DEBUG
-	u8 *data = (u8 *)dm;
-#endif
+	u8 *data __attribute__((__unused__)) = (u8 *)dm;
 	
-	switch(dm->type)
-	{
-		case  0:
-			dmi_printk(("BIOS Vendor: %s\n",
-				dmi_string(dm, data[4])));
-			dmi_save_ident(dm, DMI_BIOS_VENDOR, 4);
-			dmi_printk(("BIOS Version: %s\n", 
-				dmi_string(dm, data[5])));
-			dmi_save_ident(dm, DMI_BIOS_VERSION, 5);
-			dmi_printk(("BIOS Release: %s\n",
-				dmi_string(dm, data[8])));
-			dmi_save_ident(dm, DMI_BIOS_DATE, 8);
-			break;
-		case 1:
-			dmi_printk(("System Vendor: %s\n",
-				dmi_string(dm, data[4])));
-			dmi_save_ident(dm, DMI_SYS_VENDOR, 4);
-			dmi_printk(("Product Name: %s\n",
-				dmi_string(dm, data[5])));
-			dmi_save_ident(dm, DMI_PRODUCT_NAME, 5);
-			dmi_printk(("Version: %s\n",
-				dmi_string(dm, data[6])));
-			dmi_save_ident(dm, DMI_PRODUCT_VERSION, 6);
-			dmi_printk(("Serial Number: %s\n",
-				dmi_string(dm, data[7])));
-			break;
-		case 2:
-			dmi_printk(("Board Vendor: %s\n",
-				dmi_string(dm, data[4])));
-			dmi_save_ident(dm, DMI_BOARD_VENDOR, 4);
-			dmi_printk(("Board Name: %s\n",
-				dmi_string(dm, data[5])));
-			dmi_save_ident(dm, DMI_BOARD_NAME, 5);
-			dmi_printk(("Board Version: %s\n",
-				dmi_string(dm, data[6])));
-			dmi_save_ident(dm, DMI_BOARD_VERSION, 6);
-			break;
+	switch(dm->type) {
+	case  0:
+		dmi_printk(("BIOS Vendor: %s\n", dmi_string(dm, data[4])));
+		dmi_save_ident(dm, DMI_BIOS_VENDOR, 4);
+		dmi_printk(("BIOS Version: %s\n", dmi_string(dm, data[5])));
+		dmi_save_ident(dm, DMI_BIOS_VERSION, 5);
+		dmi_printk(("BIOS Release: %s\n", dmi_string(dm, data[8])));
+		dmi_save_ident(dm, DMI_BIOS_DATE, 8);
+		break;
+	case 1:
+		dmi_printk(("System Vendor: %s\n", dmi_string(dm, data[4])));
+		dmi_save_ident(dm, DMI_SYS_VENDOR, 4);
+		dmi_printk(("Product Name: %s\n", dmi_string(dm, data[5])));
+		dmi_save_ident(dm, DMI_PRODUCT_NAME, 5);
+		dmi_printk(("Version: %s\n", dmi_string(dm, data[6])));
+		dmi_save_ident(dm, DMI_PRODUCT_VERSION, 6);
+		dmi_printk(("Serial Number: %s\n", dmi_string(dm, data[7])));
+		dmi_save_ident(dm, DMI_PRODUCT_SERIAL, 7);
+		break;
+	case 2:
+		dmi_printk(("Board Vendor: %s\n", dmi_string(dm, data[4])));
+		dmi_save_ident(dm, DMI_BOARD_VENDOR, 4);
+		dmi_printk(("Board Name: %s\n", dmi_string(dm, data[5])));
+		dmi_save_ident(dm, DMI_BOARD_NAME, 5);
+		dmi_printk(("Board Version: %s\n", dmi_string(dm, data[6])));
+		dmi_save_ident(dm, DMI_BOARD_VERSION, 6);
+		break;
 	}
 }
 
 void __init dmi_scan_machine(void)
 {
-	int err = dmi_iterate(dmi_decode);
-	if(err == 0)
- 		dmi_check_system(dmi_blacklist);
-	else
+	if (dmi_iterate(dmi_decode))
 		printk(KERN_INFO "DMI not present.\n");
 }
 
@@ -470,7 +226,6 @@ fail:		d++;
 
 	return count;
 }
-
 EXPORT_SYMBOL(dmi_check_system);
 
 /**
@@ -480,8 +235,8 @@ EXPORT_SYMBOL(dmi_check_system);
  *	Returns one DMI data value, can be used to perform
  *	complex DMI data checks.
  */
-char * dmi_get_system_info(int field)
+char *dmi_get_system_info(int field)
 {
 	return dmi_ident[field];
 }
-
+EXPORT_SYMBOL(dmi_get_system_info);
diff --git a/arch/i386/kernel/efi.c b/arch/i386/kernel/efi.c
--- a/arch/i386/kernel/efi.c
+++ b/arch/i386/kernel/efi.c
@@ -30,6 +30,7 @@
 #include <linux/ioport.h>
 #include <linux/module.h>
 #include <linux/efi.h>
+#include <linux/kexec.h>
 
 #include <asm/setup.h>
 #include <asm/io.h>
@@ -598,6 +599,9 @@ efi_initialize_iomem_resources(struct re
 		if (md->type == EFI_CONVENTIONAL_MEMORY) {
 			request_resource(res, code_resource);
 			request_resource(res, data_resource);
+#ifdef CONFIG_KEXEC
+			request_resource(res, &crashk_res);
+#endif
 		}
 	}
 }
diff --git a/arch/i386/kernel/head.S b/arch/i386/kernel/head.S
--- a/arch/i386/kernel/head.S
+++ b/arch/i386/kernel/head.S
@@ -299,7 +299,6 @@ is386:	movl $2,%ecx		# set MP
 	movl %eax,%cr0
 
 	call check_x87
-	incb ready
 	lgdt cpu_gdt_descr
 	lidt idt_descr
 	ljmp $(__KERNEL_CS),$1f
@@ -316,8 +315,9 @@ is386:	movl $2,%ecx		# set MP
 	lldt %ax
 	cld			# gcc2 wants the direction flag cleared at all times
 #ifdef CONFIG_SMP
-	movb ready, %cl	
-	cmpb $1,%cl
+	movb ready, %cl
+	movb $1, ready
+	cmpb $0,%cl
 	je 1f			# the first CPU calls start_kernel
 				# all other CPUs call initialize_secondary
 	call initialize_secondary
diff --git a/arch/i386/kernel/i386_ksyms.c b/arch/i386/kernel/i386_ksyms.c
--- a/arch/i386/kernel/i386_ksyms.c
+++ b/arch/i386/kernel/i386_ksyms.c
@@ -1,97 +1,17 @@
 #include <linux/config.h>
 #include <linux/module.h>
-#include <linux/smp.h>
-#include <linux/user.h>
-#include <linux/elfcore.h>
-#include <linux/mca.h>
-#include <linux/sched.h>
-#include <linux/in6.h>
-#include <linux/interrupt.h>
-#include <linux/smp_lock.h>
-#include <linux/pm.h>
-#include <linux/pci.h>
-#include <linux/apm_bios.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/tty.h>
-#include <linux/highmem.h>
-#include <linux/time.h>
-
-#include <asm/semaphore.h>
-#include <asm/processor.h>
-#include <asm/i387.h>
-#include <asm/uaccess.h>
 #include <asm/checksum.h>
-#include <asm/io.h>
-#include <asm/delay.h>
-#include <asm/irq.h>
-#include <asm/mmx.h>
 #include <asm/desc.h>
-#include <asm/pgtable.h>
-#include <asm/tlbflush.h>
-#include <asm/nmi.h>
-#include <asm/ist.h>
-#include <asm/kdebug.h>
-
-extern void dump_thread(struct pt_regs *, struct user *);
-extern spinlock_t rtc_lock;
 
 /* This is definitely a GPL-only symbol */
 EXPORT_SYMBOL_GPL(cpu_gdt_table);
 
-#if defined(CONFIG_APM_MODULE)
-extern void machine_real_restart(unsigned char *, int);
-EXPORT_SYMBOL(machine_real_restart);
-extern void default_idle(void);
-EXPORT_SYMBOL(default_idle);
-#endif
-
-#ifdef CONFIG_SMP
-extern void FASTCALL( __write_lock_failed(rwlock_t *rw));
-extern void FASTCALL( __read_lock_failed(rwlock_t *rw));
-#endif
-
-#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_HD) || defined(CONFIG_BLK_DEV_IDE_MODULE) || defined(CONFIG_BLK_DEV_HD_MODULE)
-extern struct drive_info_struct drive_info;
-EXPORT_SYMBOL(drive_info);
-#endif
-
-extern unsigned long cpu_khz;
-extern unsigned long get_cmos_time(void);
-
-/* platform dependent support */
-EXPORT_SYMBOL(boot_cpu_data);
-#ifdef CONFIG_DISCONTIGMEM
-EXPORT_SYMBOL(node_data);
-EXPORT_SYMBOL(physnode_map);
-#endif
-#ifdef CONFIG_X86_NUMAQ
-EXPORT_SYMBOL(xquad_portio);
-#endif
-EXPORT_SYMBOL(dump_thread);
-EXPORT_SYMBOL(dump_fpu);
-EXPORT_SYMBOL_GPL(kernel_fpu_begin);
-EXPORT_SYMBOL(__ioremap);
-EXPORT_SYMBOL(ioremap_nocache);
-EXPORT_SYMBOL(iounmap);
-EXPORT_SYMBOL(kernel_thread);
-EXPORT_SYMBOL(pm_idle);
-EXPORT_SYMBOL(pm_power_off);
-EXPORT_SYMBOL(get_cmos_time);
-EXPORT_SYMBOL(cpu_khz);
-EXPORT_SYMBOL(apm_info);
-
 EXPORT_SYMBOL(__down_failed);
 EXPORT_SYMBOL(__down_failed_interruptible);
 EXPORT_SYMBOL(__down_failed_trylock);
 EXPORT_SYMBOL(__up_wakeup);
 /* Networking helper routines. */
 EXPORT_SYMBOL(csum_partial_copy_generic);
-/* Delay loops */
-EXPORT_SYMBOL(__ndelay);
-EXPORT_SYMBOL(__udelay);
-EXPORT_SYMBOL(__delay);
-EXPORT_SYMBOL(__const_udelay);
 
 EXPORT_SYMBOL(__get_user_1);
 EXPORT_SYMBOL(__get_user_2);
@@ -105,87 +25,11 @@ EXPORT_SYMBOL(__put_user_8);
 EXPORT_SYMBOL(strpbrk);
 EXPORT_SYMBOL(strstr);
 
-EXPORT_SYMBOL(strncpy_from_user);
-EXPORT_SYMBOL(__strncpy_from_user);
-EXPORT_SYMBOL(clear_user);
-EXPORT_SYMBOL(__clear_user);
-EXPORT_SYMBOL(__copy_from_user_ll);
-EXPORT_SYMBOL(__copy_to_user_ll);
-EXPORT_SYMBOL(strnlen_user);
-
-EXPORT_SYMBOL(dma_alloc_coherent);
-EXPORT_SYMBOL(dma_free_coherent);
-
-#ifdef CONFIG_PCI
-EXPORT_SYMBOL(pci_mem_start);
-#endif
-
-#ifdef CONFIG_PCI_BIOS
-EXPORT_SYMBOL(pcibios_set_irq_routing);
-EXPORT_SYMBOL(pcibios_get_irq_routing_table);
-#endif
-
-#ifdef CONFIG_X86_USE_3DNOW
-EXPORT_SYMBOL(_mmx_memcpy);
-EXPORT_SYMBOL(mmx_clear_page);
-EXPORT_SYMBOL(mmx_copy_page);
-#endif
-
-#ifdef CONFIG_X86_HT
-EXPORT_SYMBOL(smp_num_siblings);
-EXPORT_SYMBOL(cpu_sibling_map);
-#endif
-
 #ifdef CONFIG_SMP
-EXPORT_SYMBOL(cpu_data);
-EXPORT_SYMBOL(cpu_online_map);
-EXPORT_SYMBOL(cpu_callout_map);
+extern void FASTCALL( __write_lock_failed(rwlock_t *rw));
+extern void FASTCALL( __read_lock_failed(rwlock_t *rw));
 EXPORT_SYMBOL(__write_lock_failed);
 EXPORT_SYMBOL(__read_lock_failed);
-
-/* Global SMP stuff */
-EXPORT_SYMBOL(smp_call_function);
-
-/* TLB flushing */
-EXPORT_SYMBOL(flush_tlb_page);
-#endif
-
-#ifdef CONFIG_X86_IO_APIC
-EXPORT_SYMBOL(IO_APIC_get_PCI_irq_vector);
-#endif
-
-#ifdef CONFIG_MCA
-EXPORT_SYMBOL(machine_id);
-#endif
-
-#ifdef CONFIG_VT
-EXPORT_SYMBOL(screen_info);
-#endif
-
-EXPORT_SYMBOL(get_wchan);
-
-EXPORT_SYMBOL(rtc_lock);
-
-EXPORT_SYMBOL_GPL(set_nmi_callback);
-EXPORT_SYMBOL_GPL(unset_nmi_callback);
-
-EXPORT_SYMBOL(register_die_notifier);
-#ifdef CONFIG_HAVE_DEC_LOCK
-EXPORT_SYMBOL(_atomic_dec_and_lock);
-#endif
-
-EXPORT_SYMBOL(__PAGE_KERNEL);
-
-#ifdef CONFIG_HIGHMEM
-EXPORT_SYMBOL(kmap);
-EXPORT_SYMBOL(kunmap);
-EXPORT_SYMBOL(kmap_atomic);
-EXPORT_SYMBOL(kunmap_atomic);
-EXPORT_SYMBOL(kmap_atomic_to_page);
-#endif
-
-#if defined(CONFIG_X86_SPEEDSTEP_SMI) || defined(CONFIG_X86_SPEEDSTEP_SMI_MODULE)
-EXPORT_SYMBOL(ist_info);
 #endif
 
 EXPORT_SYMBOL(csum_partial);
diff --git a/arch/i386/kernel/i387.c b/arch/i386/kernel/i387.c
--- a/arch/i386/kernel/i387.c
+++ b/arch/i386/kernel/i387.c
@@ -10,6 +10,7 @@
 
 #include <linux/config.h>
 #include <linux/sched.h>
+#include <linux/module.h>
 #include <asm/processor.h>
 #include <asm/i387.h>
 #include <asm/math_emu.h>
@@ -79,17 +80,7 @@ void kernel_fpu_begin(void)
 	}
 	clts();
 }
-
-void restore_fpu( struct task_struct *tsk )
-{
-	if ( cpu_has_fxsr ) {
-		asm volatile( "fxrstor %0"
-			      : : "m" (tsk->thread.i387.fxsave) );
-	} else {
-		asm volatile( "frstor %0"
-			      : : "m" (tsk->thread.i387.fsave) );
-	}
-}
+EXPORT_SYMBOL_GPL(kernel_fpu_begin);
 
 /*
  * FPU tag word conversions.
@@ -526,6 +517,7 @@ int dump_fpu( struct pt_regs *regs, stru
 
 	return fpvalid;
 }
+EXPORT_SYMBOL(dump_fpu);
 
 int dump_task_fpu(struct task_struct *tsk, struct user_i387_struct *fpu)
 {
diff --git a/arch/i386/kernel/i8259.c b/arch/i386/kernel/i8259.c
--- a/arch/i386/kernel/i8259.c
+++ b/arch/i386/kernel/i8259.c
@@ -268,10 +268,22 @@ static int i8259A_suspend(struct sys_dev
 	return 0;
 }
 
+static int i8259A_shutdown(struct sys_device *dev)
+{
+	/* Put the i8259A into a quiescent state that
+	 * the kernel initialization code can get it
+	 * out of.
+	 */
+	outb(0xff, 0x21);	/* mask all of 8259A-1 */
+	outb(0xff, 0xA1);	/* mask all of 8259A-1 */
+	return 0;
+}
+
 static struct sysdev_class i8259_sysdev_class = {
 	set_kset_name("i8259"),
 	.suspend = i8259A_suspend,
 	.resume = i8259A_resume,
+	.shutdown = i8259A_shutdown,
 };
 
 static struct sys_device device_i8259A = {
diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c
--- a/arch/i386/kernel/io_apic.c
+++ b/arch/i386/kernel/io_apic.c
@@ -31,12 +31,13 @@
 #include <linux/mc146818rtc.h>
 #include <linux/compiler.h>
 #include <linux/acpi.h>
-
+#include <linux/module.h>
 #include <linux/sysdev.h>
 #include <asm/io.h>
 #include <asm/smp.h>
 #include <asm/desc.h>
 #include <asm/timer.h>
+#include <asm/i8259.h>
 
 #include <mach_apic.h>
 
@@ -573,12 +574,14 @@ static int balanced_irq(void *unused)
 	for ( ; ; ) {
 		set_current_state(TASK_INTERRUPTIBLE);
 		time_remaining = schedule_timeout(time_remaining);
-		try_to_freeze(PF_FREEZE);
+		try_to_freeze();
 		if (time_after(jiffies,
 				prev_balance_time+balanced_irq_interval)) {
+			preempt_disable();
 			do_irq_balance();
 			prev_balance_time = jiffies;
 			time_remaining = balanced_irq_interval;
+			preempt_enable();
 		}
 	}
 	return 0;
@@ -630,10 +633,8 @@ static int __init balanced_irq_init(void
 		printk(KERN_ERR "balanced_irq_init: failed to spawn balanced_irq");
 failed:
 	for (i = 0; i < NR_CPUS; i++) {
-		if(irq_cpu_data[i].irq_delta)
-			kfree(irq_cpu_data[i].irq_delta);
-		if(irq_cpu_data[i].last_irq)
-			kfree(irq_cpu_data[i].last_irq);
+		kfree(irq_cpu_data[i].irq_delta);
+		kfree(irq_cpu_data[i].last_irq);
 	}
 	return 0;
 }
@@ -812,6 +813,7 @@ int IO_APIC_get_PCI_irq_vector(int bus, 
 	}
 	return best_guess;
 }
+EXPORT_SYMBOL(IO_APIC_get_PCI_irq_vector);
 
 /*
  * This function currently is only a helper for the i386 smp boot process where 
@@ -1565,7 +1567,6 @@ void print_all_local_APICs (void)
 
 void /*__init*/ print_PIC(void)
 {
-	extern spinlock_t i8259A_lock;
 	unsigned int v;
 	unsigned long flags;
 
@@ -1633,12 +1634,43 @@ static void __init enable_IO_APIC(void)
  */
 void disable_IO_APIC(void)
 {
+	int pin;
 	/*
 	 * Clear the IO-APIC before rebooting:
 	 */
 	clear_IO_APIC();
 
-	disconnect_bsp_APIC();
+	/*
+	 * If the i82559 is routed through an IOAPIC
+	 * Put that IOAPIC in virtual wire mode
+	 * so legacy interrups can be delivered.
+	 */
+	pin = find_isa_irq_pin(0, mp_ExtINT);
+	if (pin != -1) {
+		struct IO_APIC_route_entry entry;
+		unsigned long flags;
+
+		memset(&entry, 0, sizeof(entry));
+		entry.mask            = 0; /* Enabled */
+		entry.trigger         = 0; /* Edge */
+		entry.irr             = 0;
+		entry.polarity        = 0; /* High */
+		entry.delivery_status = 0;
+		entry.dest_mode       = 0; /* Physical */
+		entry.delivery_mode   = 7; /* ExtInt */
+		entry.vector          = 0;
+		entry.dest.physical.physical_dest = 0;
+
+
+		/*
+		 * Add it to the IO-APIC irq-routing table:
+		 */
+		spin_lock_irqsave(&ioapic_lock, flags);
+		io_apic_write(0, 0x11+2*pin, *(((int *)&entry)+1));
+		io_apic_write(0, 0x10+2*pin, *(((int *)&entry)+0));
+		spin_unlock_irqrestore(&ioapic_lock, flags);
+	}
+	disconnect_bsp_APIC(pin != -1);
 }
 
 /*
@@ -1659,6 +1691,12 @@ static void __init setup_ioapic_ids_from
 	unsigned long flags;
 
 	/*
+	 * Don't check I/O APIC IDs for xAPIC systems.  They have
+	 * no meaning without the serial APIC bus.
+	 */
+	if (!(boot_cpu_data.x86_vendor == X86_VENDOR_INTEL && boot_cpu_data.x86 < 15))
+		return;
+	/*
 	 * This is broken; anything with a real cpu count has to
 	 * circumvent this idiocy regardless.
 	 */
@@ -1684,10 +1722,6 @@ static void __init setup_ioapic_ids_from
 			mp_ioapics[apic].mpc_apicid = reg_00.bits.ID;
 		}
 
-		/* Don't check I/O APIC IDs for some xAPIC systems.  They have
-		 * no meaning without the serial APIC bus. */
-		if (NO_IOAPIC_CHECK)
-			continue;
 		/*
 		 * Sanity check, is the ID really free? Every APIC in a
 		 * system must have a unique ID or we get lots of nice
diff --git a/arch/i386/kernel/irq.c b/arch/i386/kernel/irq.c
--- a/arch/i386/kernel/irq.c
+++ b/arch/i386/kernel/irq.c
@@ -15,6 +15,9 @@
 #include <linux/seq_file.h>
 #include <linux/interrupt.h>
 #include <linux/kernel_stat.h>
+#include <linux/notifier.h>
+#include <linux/cpu.h>
+#include <linux/delay.h>
 
 DEFINE_PER_CPU(irq_cpustat_t, irq_stat) ____cacheline_maxaligned_in_smp;
 EXPORT_PER_CPU_SYMBOL(irq_stat);
@@ -153,6 +156,11 @@ void irq_ctx_init(int cpu)
 		cpu,hardirq_ctx[cpu],softirq_ctx[cpu]);
 }
 
+void irq_ctx_exit(int cpu)
+{
+	hardirq_ctx[cpu] = NULL;
+}
+
 extern asmlinkage void __do_softirq(void);
 
 asmlinkage void do_softirq(void)
@@ -210,9 +218,8 @@ int show_interrupts(struct seq_file *p, 
 
 	if (i == 0) {
 		seq_printf(p, "           ");
-		for (j=0; j<NR_CPUS; j++)
-			if (cpu_online(j))
-				seq_printf(p, "CPU%d       ",j);
+		for_each_cpu(j)
+			seq_printf(p, "CPU%d       ",j);
 		seq_putc(p, '\n');
 	}
 
@@ -225,9 +232,8 @@ int show_interrupts(struct seq_file *p, 
 #ifndef CONFIG_SMP
 		seq_printf(p, "%10u ", kstat_irqs(i));
 #else
-		for (j = 0; j < NR_CPUS; j++)
-			if (cpu_online(j))
-				seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
+		for_each_cpu(j)
+			seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
 #endif
 		seq_printf(p, " %14s", irq_desc[i].handler->typename);
 		seq_printf(p, "  %s", action->name);
@@ -240,16 +246,14 @@ skip:
 		spin_unlock_irqrestore(&irq_desc[i].lock, flags);
 	} else if (i == NR_IRQS) {
 		seq_printf(p, "NMI: ");
-		for (j = 0; j < NR_CPUS; j++)
-			if (cpu_online(j))
-				seq_printf(p, "%10u ", nmi_count(j));
+		for_each_cpu(j)
+			seq_printf(p, "%10u ", nmi_count(j));
 		seq_putc(p, '\n');
 #ifdef CONFIG_X86_LOCAL_APIC
 		seq_printf(p, "LOC: ");
-		for (j = 0; j < NR_CPUS; j++)
-			if (cpu_online(j))
-				seq_printf(p, "%10u ",
-					per_cpu(irq_stat,j).apic_timer_irqs);
+		for_each_cpu(j)
+			seq_printf(p, "%10u ",
+				per_cpu(irq_stat,j).apic_timer_irqs);
 		seq_putc(p, '\n');
 #endif
 		seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count));
@@ -259,3 +263,45 @@ skip:
 	}
 	return 0;
 }
+
+#ifdef CONFIG_HOTPLUG_CPU
+#include <mach_apic.h>
+
+void fixup_irqs(cpumask_t map)
+{
+	unsigned int irq;
+	static int warned;
+
+	for (irq = 0; irq < NR_IRQS; irq++) {
+		cpumask_t mask;
+		if (irq == 2)
+			continue;
+
+		cpus_and(mask, irq_affinity[irq], map);
+		if (any_online_cpu(mask) == NR_CPUS) {
+			printk("Breaking affinity for irq %i\n", irq);
+			mask = map;
+		}
+		if (irq_desc[irq].handler->set_affinity)
+			irq_desc[irq].handler->set_affinity(irq, mask);
+		else if (irq_desc[irq].action && !(warned++))
+			printk("Cannot set affinity for irq %i\n", irq);
+	}
+
+#if 0
+	barrier();
+	/* Ingo Molnar says: "after the IO-APIC masks have been redirected
+	   [note the nop - the interrupt-enable boundary on x86 is two
+	   instructions from sti] - to flush out pending hardirqs and
+	   IPIs. After this point nothing is supposed to reach this CPU." */
+	__asm__ __volatile__("sti; nop; cli");
+	barrier();
+#else
+	/* That doesn't seem sufficient.  Give it 1ms. */
+	local_irq_enable();
+	mdelay(1);
+	local_irq_disable();
+#endif
+}
+#endif
+
diff --git a/arch/i386/kernel/kprobes.c b/arch/i386/kernel/kprobes.c
--- a/arch/i386/kernel/kprobes.c
+++ b/arch/i386/kernel/kprobes.c
@@ -23,6 +23,9 @@
  *		Rusty Russell).
  * 2004-July	Suparna Bhattacharya <suparna@in.ibm.com> added jumper probes
  *		interface to access function arguments.
+ * 2005-May	Hien Nguyen <hien@us.ibm.com>, Jim Keniston
+ *		<jkenisto@us.ibm.com> and Prasanna S Panchamukhi
+ *		<prasanna@in.ibm.com> added function-return probes.
  */
 
 #include <linux/config.h>
@@ -30,15 +33,14 @@
 #include <linux/ptrace.h>
 #include <linux/spinlock.h>
 #include <linux/preempt.h>
+#include <asm/cacheflush.h>
 #include <asm/kdebug.h>
 #include <asm/desc.h>
 
-/* kprobe_status settings */
-#define KPROBE_HIT_ACTIVE	0x00000001
-#define KPROBE_HIT_SS		0x00000002
-
 static struct kprobe *current_kprobe;
 static unsigned long kprobe_status, kprobe_old_eflags, kprobe_saved_eflags;
+static struct kprobe *kprobe_prev;
+static unsigned long kprobe_status_prev, kprobe_old_eflags_prev, kprobe_saved_eflags_prev;
 static struct pt_regs jprobe_saved_regs;
 static long *jprobe_saved_esp;
 /* copy of the kernel stack at the probe fire time */
@@ -68,16 +70,50 @@ int arch_prepare_kprobe(struct kprobe *p
 void arch_copy_kprobe(struct kprobe *p)
 {
 	memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
+	p->opcode = *p->addr;
 }
 
-void arch_remove_kprobe(struct kprobe *p)
+void arch_arm_kprobe(struct kprobe *p)
 {
+	*p->addr = BREAKPOINT_INSTRUCTION;
+	flush_icache_range((unsigned long) p->addr,
+			   (unsigned long) p->addr + sizeof(kprobe_opcode_t));
 }
 
-static inline void disarm_kprobe(struct kprobe *p, struct pt_regs *regs)
+void arch_disarm_kprobe(struct kprobe *p)
 {
 	*p->addr = p->opcode;
-	regs->eip = (unsigned long)p->addr;
+	flush_icache_range((unsigned long) p->addr,
+			   (unsigned long) p->addr + sizeof(kprobe_opcode_t));
+}
+
+void arch_remove_kprobe(struct kprobe *p)
+{
+}
+
+static inline void save_previous_kprobe(void)
+{
+	kprobe_prev = current_kprobe;
+	kprobe_status_prev = kprobe_status;
+	kprobe_old_eflags_prev = kprobe_old_eflags;
+	kprobe_saved_eflags_prev = kprobe_saved_eflags;
+}
+
+static inline void restore_previous_kprobe(void)
+{
+	current_kprobe = kprobe_prev;
+	kprobe_status = kprobe_status_prev;
+	kprobe_old_eflags = kprobe_old_eflags_prev;
+	kprobe_saved_eflags = kprobe_saved_eflags_prev;
+}
+
+static inline void set_current_kprobe(struct kprobe *p, struct pt_regs *regs)
+{
+	current_kprobe = p;
+	kprobe_saved_eflags = kprobe_old_eflags
+		= (regs->eflags & (TF_MASK | IF_MASK));
+	if (is_IF_modifier(p->opcode))
+		kprobe_saved_eflags &= ~IF_MASK;
 }
 
 static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
@@ -91,6 +127,25 @@ static inline void prepare_singlestep(st
 		regs->eip = (unsigned long)&p->ainsn.insn;
 }
 
+void arch_prepare_kretprobe(struct kretprobe *rp, struct pt_regs *regs)
+{
+	unsigned long *sara = (unsigned long *)&regs->esp;
+        struct kretprobe_instance *ri;
+
+        if ((ri = get_free_rp_inst(rp)) != NULL) {
+                ri->rp = rp;
+                ri->task = current;
+		ri->ret_addr = (kprobe_opcode_t *) *sara;
+
+		/* Replace the return addr with trampoline addr */
+		*sara = (unsigned long) &kretprobe_trampoline;
+
+                add_rp_inst(ri);
+        } else {
+                rp->nmissed++;
+        }
+}
+
 /*
  * Interrupts are disabled on entry as trap3 is an interrupt gate and they
  * remain disabled thorough out this function.
@@ -127,8 +182,18 @@ static int kprobe_handler(struct pt_regs
 				unlock_kprobes();
 				goto no_kprobe;
 			}
-			disarm_kprobe(p, regs);
-			ret = 1;
+			/* We have reentered the kprobe_handler(), since
+			 * another probe was hit while within the handler.
+			 * We here save the original kprobes variables and
+			 * just single step on the instruction of the new probe
+			 * without calling any user handlers.
+			 */
+			save_previous_kprobe();
+			set_current_kprobe(p, regs);
+			p->nmissed++;
+			prepare_singlestep(p, regs);
+			kprobe_status = KPROBE_REENTER;
+			return 1;
 		} else {
 			p = current_kprobe;
 			if (p->break_handler && p->break_handler(p, regs)) {
@@ -163,11 +228,7 @@ static int kprobe_handler(struct pt_regs
 	}
 
 	kprobe_status = KPROBE_HIT_ACTIVE;
-	current_kprobe = p;
-	kprobe_saved_eflags = kprobe_old_eflags
-	    = (regs->eflags & (TF_MASK | IF_MASK));
-	if (is_IF_modifier(p->opcode))
-		kprobe_saved_eflags &= ~IF_MASK;
+	set_current_kprobe(p, regs);
 
 	if (p->pre_handler && p->pre_handler(p, regs))
 		/* handler has already set things up, so skip ss setup */
@@ -184,6 +245,78 @@ no_kprobe:
 }
 
 /*
+ * For function-return probes, init_kprobes() establishes a probepoint
+ * here. When a retprobed function returns, this probe is hit and
+ * trampoline_probe_handler() runs, calling the kretprobe's handler.
+ */
+ void kretprobe_trampoline_holder(void)
+ {
+ 	asm volatile (  ".global kretprobe_trampoline\n"
+ 			"kretprobe_trampoline: \n"
+ 			"nop\n");
+ }
+
+/*
+ * Called when we hit the probe point at kretprobe_trampoline
+ */
+int trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
+{
+        struct kretprobe_instance *ri = NULL;
+        struct hlist_head *head;
+        struct hlist_node *node, *tmp;
+	unsigned long orig_ret_address = 0;
+	unsigned long trampoline_address =(unsigned long)&kretprobe_trampoline;
+
+        head = kretprobe_inst_table_head(current);
+
+	/*
+	 * It is possible to have multiple instances associated with a given
+	 * task either because an multiple functions in the call path
+	 * have a return probe installed on them, and/or more then one return
+	 * return probe was registered for a target function.
+	 *
+	 * We can handle this because:
+	 *     - instances are always inserted at the head of the list
+	 *     - when multiple return probes are registered for the same
+         *       function, the first instance's ret_addr will point to the
+	 *       real return address, and all the rest will point to
+	 *       kretprobe_trampoline
+	 */
+	hlist_for_each_entry_safe(ri, node, tmp, head, hlist) {
+                if (ri->task != current)
+			/* another task is sharing our hash bucket */
+                        continue;
+
+		if (ri->rp && ri->rp->handler)
+			ri->rp->handler(ri, regs);
+
+		orig_ret_address = (unsigned long)ri->ret_addr;
+		recycle_rp_inst(ri);
+
+		if (orig_ret_address != trampoline_address)
+			/*
+			 * This is the real return address. Any other
+			 * instances associated with this task are for
+			 * other calls deeper on the call stack
+			 */
+			break;
+	}
+
+	BUG_ON(!orig_ret_address || (orig_ret_address == trampoline_address));
+	regs->eip = orig_ret_address;
+
+	unlock_kprobes();
+	preempt_enable_no_resched();
+
+        /*
+         * By returning a non-zero value, we are telling
+         * kprobe_handler() that we have handled unlocking
+         * and re-enabling preemption.
+         */
+        return 1;
+}
+
+/*
  * Called after single-stepping.  p->addr is the address of the
  * instruction whose first byte has been replaced by the "int 3"
  * instruction.  To avoid the SMP problems that can occur when we
@@ -263,13 +396,21 @@ static inline int post_kprobe_handler(st
 	if (!kprobe_running())
 		return 0;
 
-	if (current_kprobe->post_handler)
+	if ((kprobe_status != KPROBE_REENTER) && current_kprobe->post_handler) {
+		kprobe_status = KPROBE_HIT_SSDONE;
 		current_kprobe->post_handler(current_kprobe, regs, 0);
+	}
 
 	resume_execution(current_kprobe, regs);
 	regs->eflags |= kprobe_saved_eflags;
 
+	/*Restore back the original saved kprobes variables and continue. */
+	if (kprobe_status == KPROBE_REENTER) {
+		restore_previous_kprobe();
+		goto out;
+	}
 	unlock_kprobes();
+out:
 	preempt_enable_no_resched();
 
 	/*
@@ -390,3 +531,13 @@ int longjmp_break_handler(struct kprobe 
 	}
 	return 0;
 }
+
+static struct kprobe trampoline_p = {
+	.addr = (kprobe_opcode_t *) &kretprobe_trampoline,
+	.pre_handler = trampoline_probe_handler
+};
+
+int __init arch_init_kprobes(void)
+{
+	return register_kprobe(&trampoline_p);
+}
diff --git a/arch/i386/kernel/machine_kexec.c b/arch/i386/kernel/machine_kexec.c
new file mode 100644
--- /dev/null
+++ b/arch/i386/kernel/machine_kexec.c
@@ -0,0 +1,226 @@
+/*
+ * machine_kexec.c - handle transition of Linux booting another kernel
+ * Copyright (C) 2002-2005 Eric Biederman  <ebiederm@xmission.com>
+ *
+ * This source code is licensed under the GNU General Public License,
+ * Version 2.  See the file COPYING for more details.
+ */
+
+#include <linux/mm.h>
+#include <linux/kexec.h>
+#include <linux/delay.h>
+#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
+#include <asm/tlbflush.h>
+#include <asm/mmu_context.h>
+#include <asm/io.h>
+#include <asm/apic.h>
+#include <asm/cpufeature.h>
+#include <asm/desc.h>
+
+static inline unsigned long read_cr3(void)
+{
+	unsigned long cr3;
+	asm volatile("movl %%cr3,%0": "=r"(cr3));
+	return cr3;
+}
+
+#define PAGE_ALIGNED __attribute__ ((__aligned__(PAGE_SIZE)))
+
+#define L0_ATTR (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY)
+#define L1_ATTR (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY)
+#define L2_ATTR (_PAGE_PRESENT)
+
+#define LEVEL0_SIZE (1UL << 12UL)
+
+#ifndef CONFIG_X86_PAE
+#define LEVEL1_SIZE (1UL << 22UL)
+static u32 pgtable_level1[1024] PAGE_ALIGNED;
+
+static void identity_map_page(unsigned long address)
+{
+	unsigned long level1_index, level2_index;
+	u32 *pgtable_level2;
+
+	/* Find the current page table */
+	pgtable_level2 = __va(read_cr3());
+
+	/* Find the indexes of the physical address to identity map */
+	level1_index = (address % LEVEL1_SIZE)/LEVEL0_SIZE;
+	level2_index = address / LEVEL1_SIZE;
+
+	/* Identity map the page table entry */
+	pgtable_level1[level1_index] = address | L0_ATTR;
+	pgtable_level2[level2_index] = __pa(pgtable_level1) | L1_ATTR;
+
+	/* Flush the tlb so the new mapping takes effect.
+	 * Global tlb entries are not flushed but that is not an issue.
+	 */
+	load_cr3(pgtable_level2);
+}
+
+#else
+#define LEVEL1_SIZE (1UL << 21UL)
+#define LEVEL2_SIZE (1UL << 30UL)
+static u64 pgtable_level1[512] PAGE_ALIGNED;
+static u64 pgtable_level2[512] PAGE_ALIGNED;
+
+static void identity_map_page(unsigned long address)
+{
+	unsigned long level1_index, level2_index, level3_index;
+	u64 *pgtable_level3;
+
+	/* Find the current page table */
+	pgtable_level3 = __va(read_cr3());
+
+	/* Find the indexes of the physical address to identity map */
+	level1_index = (address % LEVEL1_SIZE)/LEVEL0_SIZE;
+	level2_index = (address % LEVEL2_SIZE)/LEVEL1_SIZE;
+	level3_index = address / LEVEL2_SIZE;
+
+	/* Identity map the page table entry */
+	pgtable_level1[level1_index] = address | L0_ATTR;
+	pgtable_level2[level2_index] = __pa(pgtable_level1) | L1_ATTR;
+	set_64bit(&pgtable_level3[level3_index],
+					       __pa(pgtable_level2) | L2_ATTR);
+
+	/* Flush the tlb so the new mapping takes effect.
+	 * Global tlb entries are not flushed but that is not an issue.
+	 */
+	load_cr3(pgtable_level3);
+}
+#endif
+
+static void set_idt(void *newidt, __u16 limit)
+{
+	struct Xgt_desc_struct curidt;
+
+	/* ia32 supports unaliged loads & stores */
+	curidt.size    = limit;
+	curidt.address = (unsigned long)newidt;
+
+	__asm__ __volatile__ (
+		"lidtl %0\n"
+		: : "m" (curidt)
+		);
+};
+
+
+static void set_gdt(void *newgdt, __u16 limit)
+{
+	struct Xgt_desc_struct curgdt;
+
+	/* ia32 supports unaligned loads & stores */
+	curgdt.size    = limit;
+	curgdt.address = (unsigned long)newgdt;
+
+	__asm__ __volatile__ (
+		"lgdtl %0\n"
+		: : "m" (curgdt)
+		);
+};
+
+static void load_segments(void)
+{
+#define __STR(X) #X
+#define STR(X) __STR(X)
+
+	__asm__ __volatile__ (
+		"\tljmp $"STR(__KERNEL_CS)",$1f\n"
+		"\t1:\n"
+		"\tmovl $"STR(__KERNEL_DS)",%eax\n"
+		"\tmovl %eax,%ds\n"
+		"\tmovl %eax,%es\n"
+		"\tmovl %eax,%fs\n"
+		"\tmovl %eax,%gs\n"
+		"\tmovl %eax,%ss\n"
+		);
+#undef STR
+#undef __STR
+}
+
+typedef asmlinkage NORET_TYPE void (*relocate_new_kernel_t)(
+					unsigned long indirection_page,
+					unsigned long reboot_code_buffer,
+					unsigned long start_address,
+					unsigned int has_pae) ATTRIB_NORET;
+
+const extern unsigned char relocate_new_kernel[];
+extern void relocate_new_kernel_end(void);
+const extern unsigned int relocate_new_kernel_size;
+
+/*
+ * A architecture hook called to validate the
+ * proposed image and prepare the control pages
+ * as needed.  The pages for KEXEC_CONTROL_CODE_SIZE
+ * have been allocated, but the segments have yet
+ * been copied into the kernel.
+ *
+ * Do what every setup is needed on image and the
+ * reboot code buffer to allow us to avoid allocations
+ * later.
+ *
+ * Currently nothing.
+ */
+int machine_kexec_prepare(struct kimage *image)
+{
+	return 0;
+}
+
+/*
+ * Undo anything leftover by machine_kexec_prepare
+ * when an image is freed.
+ */
+void machine_kexec_cleanup(struct kimage *image)
+{
+}
+
+/*
+ * Do not allocate memory (or fail in any way) in machine_kexec().
+ * We are past the point of no return, committed to rebooting now.
+ */
+NORET_TYPE void machine_kexec(struct kimage *image)
+{
+	unsigned long page_list;
+	unsigned long reboot_code_buffer;
+
+	relocate_new_kernel_t rnk;
+
+	/* Interrupts aren't acceptable while we reboot */
+	local_irq_disable();
+
+	/* Compute some offsets */
+	reboot_code_buffer = page_to_pfn(image->control_code_page)
+								<< PAGE_SHIFT;
+	page_list = image->head;
+
+	/* Set up an identity mapping for the reboot_code_buffer */
+	identity_map_page(reboot_code_buffer);
+
+	/* copy it out */
+	memcpy((void *)reboot_code_buffer, relocate_new_kernel,
+						relocate_new_kernel_size);
+
+	/* The segment registers are funny things, they are
+	 * automatically loaded from a table, in memory wherever you
+	 * set them to a specific selector, but this table is never
+	 * accessed again you set the segment to a different selector.
+	 *
+	 * The more common model is are caches where the behide
+	 * the scenes work is done, but is also dropped at arbitrary
+	 * times.
+	 *
+	 * I take advantage of this here by force loading the
+	 * segments, before I zap the gdt with an invalid value.
+	 */
+	load_segments();
+	/* The gdt & idt are now invalid.
+	 * If you want to load them you must set up your own idt & gdt.
+	 */
+	set_gdt(phys_to_virt(0),0);
+	set_idt(phys_to_virt(0),0);
+
+	/* now call it */
+	rnk = (relocate_new_kernel_t) reboot_code_buffer;
+	(*rnk)(page_list, reboot_code_buffer, image->start, cpu_has_pae);
+}
diff --git a/arch/i386/kernel/mpparse.c b/arch/i386/kernel/mpparse.c
--- a/arch/i386/kernel/mpparse.c
+++ b/arch/i386/kernel/mpparse.c
@@ -67,7 +67,6 @@ unsigned long mp_lapic_addr;
 
 /* Processor that is doing the boot up */
 unsigned int boot_cpu_physical_apicid = -1U;
-unsigned int boot_cpu_logical_apicid = -1U;
 /* Internal processor count */
 static unsigned int __initdata num_processors;
 
@@ -180,7 +179,6 @@ static void __init MP_processor_info (st
 	if (m->mpc_cpuflag & CPU_BOOTPROCESSOR) {
 		Dprintk("    Bootup CPU\n");
 		boot_cpu_physical_apicid = m->mpc_apicid;
-		boot_cpu_logical_apicid = apicid;
 	}
 
 	if (num_processors >= NR_CPUS) {
@@ -914,7 +912,10 @@ void __init mp_register_ioapic (
 	mp_ioapics[idx].mpc_apicaddr = address;
 
 	set_fixmap_nocache(FIX_IO_APIC_BASE_0 + idx, address);
-	mp_ioapics[idx].mpc_apicid = io_apic_get_unique_id(idx, id);
+	if ((boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) && (boot_cpu_data.x86 < 15))
+		mp_ioapics[idx].mpc_apicid = io_apic_get_unique_id(idx, id);
+	else
+		mp_ioapics[idx].mpc_apicid = id;
 	mp_ioapics[idx].mpc_apicver = io_apic_get_version(idx);
 	
 	/* 
@@ -1055,11 +1056,20 @@ void __init mp_config_acpi_legacy_irqs (
 	}
 }
 
+#define MAX_GSI_NUM	4096
+
 int mp_register_gsi (u32 gsi, int edge_level, int active_high_low)
 {
 	int			ioapic = -1;
 	int			ioapic_pin = 0;
 	int			idx, bit = 0;
+	static int		pci_irq = 16;
+	/*
+	 * Mapping between Global System Interrups, which
+	 * represent all possible interrupts, and IRQs
+	 * assigned to actual devices.
+	 */
+	static int		gsi_to_irq[MAX_GSI_NUM];
 
 #ifdef CONFIG_ACPI_BUS
 	/* Don't set up the ACPI SCI because it's already set up */
@@ -1094,11 +1104,34 @@ int mp_register_gsi (u32 gsi, int edge_l
 	if ((1<<bit) & mp_ioapic_routing[ioapic].pin_programmed[idx]) {
 		Dprintk(KERN_DEBUG "Pin %d-%d already programmed\n",
 			mp_ioapic_routing[ioapic].apic_id, ioapic_pin);
-		return gsi;
+		return gsi_to_irq[gsi];
 	}
 
 	mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<<bit);
 
+	if (edge_level) {
+		/*
+		 * For PCI devices assign IRQs in order, avoiding gaps
+		 * due to unused I/O APIC pins.
+		 */
+		int irq = gsi;
+		if (gsi < MAX_GSI_NUM) {
+			if (gsi > 15)
+				gsi = pci_irq++;
+#ifdef CONFIG_ACPI_BUS
+			/*
+			 * Don't assign IRQ used by ACPI SCI
+			 */
+			if (gsi == acpi_fadt.sci_int)
+				gsi = pci_irq++;
+#endif
+			gsi_to_irq[irq] = gsi;
+		} else {
+			printk(KERN_ERR "GSI %u is too high\n", gsi);
+			return gsi;
+		}
+	}
+
 	io_apic_set_pci_routing(ioapic, ioapic_pin, gsi,
 		    edge_level == ACPI_EDGE_SENSITIVE ? 0 : 1,
 		    active_high_low == ACPI_ACTIVE_HIGH ? 0 : 1);
diff --git a/arch/i386/kernel/msr.c b/arch/i386/kernel/msr.c
--- a/arch/i386/kernel/msr.c
+++ b/arch/i386/kernel/msr.c
@@ -44,7 +44,7 @@
 #include <asm/uaccess.h>
 #include <asm/system.h>
 
-static struct class_simple *msr_class;
+static struct class *msr_class;
 
 /* Note: "err" is handled in a funny way below.  Otherwise one version
    of gcc or another breaks. */
@@ -260,12 +260,12 @@ static struct file_operations msr_fops =
 	.open = msr_open,
 };
 
-static int msr_class_simple_device_add(int i)
+static int msr_class_device_create(int i)
 {
 	int err = 0;
 	struct class_device *class_err;
 
-	class_err = class_simple_device_add(msr_class, MKDEV(MSR_MAJOR, i), NULL, "msr%d",i);
+	class_err = class_device_create(msr_class, MKDEV(MSR_MAJOR, i), NULL, "msr%d",i);
 	if (IS_ERR(class_err)) 
 		err = PTR_ERR(class_err);
 	return err;
@@ -277,10 +277,10 @@ static int __devinit msr_class_cpu_callb
 
 	switch (action) {
 	case CPU_ONLINE:
-		msr_class_simple_device_add(cpu);
+		msr_class_device_create(cpu);
 		break;
 	case CPU_DEAD:
-		class_simple_device_remove(MKDEV(MSR_MAJOR, cpu));	
+		class_device_destroy(msr_class, MKDEV(MSR_MAJOR, cpu));
 		break;
 	}
 	return NOTIFY_OK;
@@ -302,13 +302,13 @@ static int __init msr_init(void)
 		err = -EBUSY;
 		goto out;
 	}
-	msr_class = class_simple_create(THIS_MODULE, "msr");
+	msr_class = class_create(THIS_MODULE, "msr");
 	if (IS_ERR(msr_class)) {
 		err = PTR_ERR(msr_class);
 		goto out_chrdev;
 	}
 	for_each_online_cpu(i) {
-		err = msr_class_simple_device_add(i);
+		err = msr_class_device_create(i);
 		if (err != 0)
 			goto out_class;
 	}
@@ -320,8 +320,8 @@ static int __init msr_init(void)
 out_class:
 	i = 0;
 	for_each_online_cpu(i)
-		class_simple_device_remove(MKDEV(MSR_MAJOR, i));
-	class_simple_destroy(msr_class);
+		class_device_destroy(msr_class, MKDEV(MSR_MAJOR, i));
+	class_destroy(msr_class);
 out_chrdev:
 	unregister_chrdev(MSR_MAJOR, "cpu/msr");
 out:
@@ -332,8 +332,8 @@ static void __exit msr_exit(void)
 {
 	int cpu = 0;
 	for_each_online_cpu(cpu)
-		class_simple_device_remove(MKDEV(MSR_MAJOR, cpu));
-	class_simple_destroy(msr_class);
+		class_device_destroy(msr_class, MKDEV(MSR_MAJOR, cpu));
+	class_destroy(msr_class);
 	unregister_chrdev(MSR_MAJOR, "cpu/msr");
 	unregister_cpu_notifier(&msr_class_cpu_notifier);
 }
diff --git a/arch/i386/kernel/nmi.c b/arch/i386/kernel/nmi.c
--- a/arch/i386/kernel/nmi.c
+++ b/arch/i386/kernel/nmi.c
@@ -28,8 +28,7 @@
 #include <linux/sysctl.h>
 
 #include <asm/smp.h>
-#include <asm/mtrr.h>
-#include <asm/mpspec.h>
+#include <asm/div64.h>
 #include <asm/nmi.h>
 
 #include "mach_traps.h"
@@ -196,7 +195,7 @@ static void disable_lapic_nmi_watchdog(v
 			wrmsr(MSR_P6_EVNTSEL0, 0, 0);
 			break;
 		case 15:
-			if (boot_cpu_data.x86_model > 0x3)
+			if (boot_cpu_data.x86_model > 0x4)
 				break;
 
 			wrmsr(MSR_P4_IQ_CCCR0, 0, 0);
@@ -324,6 +323,16 @@ static void clear_msr_range(unsigned int
 		wrmsr(base+i, 0, 0);
 }
 
+static inline void write_watchdog_counter(const char *descr)
+{
+	u64 count = (u64)cpu_khz * 1000;
+
+	do_div(count, nmi_hz);
+	if(descr)
+		Dprintk("setting %s to -0x%08Lx\n", descr, count);
+	wrmsrl(nmi_perfctr_msr, 0 - count);
+}
+
 static void setup_k7_watchdog(void)
 {
 	unsigned int evntsel;
@@ -339,8 +348,7 @@ static void setup_k7_watchdog(void)
 		| K7_NMI_EVENT;
 
 	wrmsr(MSR_K7_EVNTSEL0, evntsel, 0);
-	Dprintk("setting K7_PERFCTR0 to %08lx\n", -(cpu_khz/nmi_hz*1000));
-	wrmsr(MSR_K7_PERFCTR0, -(cpu_khz/nmi_hz*1000), -1);
+	write_watchdog_counter("K7_PERFCTR0");
 	apic_write(APIC_LVTPC, APIC_DM_NMI);
 	evntsel |= K7_EVNTSEL_ENABLE;
 	wrmsr(MSR_K7_EVNTSEL0, evntsel, 0);
@@ -361,8 +369,7 @@ static void setup_p6_watchdog(void)
 		| P6_NMI_EVENT;
 
 	wrmsr(MSR_P6_EVNTSEL0, evntsel, 0);
-	Dprintk("setting P6_PERFCTR0 to %08lx\n", -(cpu_khz/nmi_hz*1000));
-	wrmsr(MSR_P6_PERFCTR0, -(cpu_khz/nmi_hz*1000), 0);
+	write_watchdog_counter("P6_PERFCTR0");
 	apic_write(APIC_LVTPC, APIC_DM_NMI);
 	evntsel |= P6_EVNTSEL0_ENABLE;
 	wrmsr(MSR_P6_EVNTSEL0, evntsel, 0);
@@ -402,8 +409,7 @@ static int setup_p4_watchdog(void)
 
 	wrmsr(MSR_P4_CRU_ESCR0, P4_NMI_CRU_ESCR0, 0);
 	wrmsr(MSR_P4_IQ_CCCR0, P4_NMI_IQ_CCCR0 & ~P4_CCCR_ENABLE, 0);
-	Dprintk("setting P4_IQ_COUNTER0 to 0x%08lx\n", -(cpu_khz/nmi_hz*1000));
-	wrmsr(MSR_P4_IQ_COUNTER0, -(cpu_khz/nmi_hz*1000), -1);
+	write_watchdog_counter("P4_IQ_COUNTER0");
 	apic_write(APIC_LVTPC, APIC_DM_NMI);
 	wrmsr(MSR_P4_IQ_CCCR0, nmi_p4_cccr_val, 0);
 	return 1;
@@ -426,7 +432,7 @@ void setup_apic_nmi_watchdog (void)
 			setup_p6_watchdog();
 			break;
 		case 15:
-			if (boot_cpu_data.x86_model > 0x3)
+			if (boot_cpu_data.x86_model > 0x4)
 				return;
 
 			if (!setup_p4_watchdog())
@@ -518,7 +524,7 @@ void nmi_watchdog_tick (struct pt_regs *
 			 * other P6 variant */
 			apic_write(APIC_LVTPC, APIC_DM_NMI);
 		}
-		wrmsr(nmi_perfctr_msr, -(cpu_khz/nmi_hz*1000), -1);
+		write_watchdog_counter(NULL);
 	}
 }
 
diff --git a/arch/i386/kernel/numaq.c b/arch/i386/kernel/numaq.c
--- a/arch/i386/kernel/numaq.c
+++ b/arch/i386/kernel/numaq.c
@@ -31,6 +31,7 @@
 #include <linux/nodemask.h>
 #include <asm/numaq.h>
 #include <asm/topology.h>
+#include <asm/processor.h>
 
 #define	MB_TO_PAGES(addr) ((addr) << (20 - PAGE_SHIFT))
 
@@ -77,3 +78,11 @@ int __init get_memcfg_numaq(void)
 	smp_dump_qct();
 	return 1;
 }
+
+static int __init numaq_dsc_disable(void)
+{
+	printk(KERN_DEBUG "NUMAQ: disabling TSC\n");
+	tsc_disable = 1;
+	return 0;
+}
+core_initcall(numaq_dsc_disable);
diff --git a/arch/i386/kernel/pci-dma.c b/arch/i386/kernel/pci-dma.c
--- a/arch/i386/kernel/pci-dma.c
+++ b/arch/i386/kernel/pci-dma.c
@@ -11,6 +11,7 @@
 #include <linux/mm.h>
 #include <linux/string.h>
 #include <linux/pci.h>
+#include <linux/module.h>
 #include <asm/io.h>
 
 struct dma_coherent_mem {
@@ -54,6 +55,7 @@ void *dma_alloc_coherent(struct device *
 	}
 	return ret;
 }
+EXPORT_SYMBOL(dma_alloc_coherent);
 
 void dma_free_coherent(struct device *dev, size_t size,
 			 void *vaddr, dma_addr_t dma_handle)
@@ -68,6 +70,7 @@ void dma_free_coherent(struct device *de
 	} else
 		free_pages((unsigned long)vaddr, order);
 }
+EXPORT_SYMBOL(dma_free_coherent);
 
 int dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr,
 				dma_addr_t device_addr, size_t size, int flags)
diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c
--- a/arch/i386/kernel/process.c
+++ b/arch/i386/kernel/process.c
@@ -13,6 +13,7 @@
 
 #include <stdarg.h>
 
+#include <linux/cpu.h>
 #include <linux/errno.h>
 #include <linux/sched.h>
 #include <linux/fs.h>
@@ -37,6 +38,7 @@
 #include <linux/kallsyms.h>
 #include <linux/ptrace.h>
 #include <linux/random.h>
+#include <linux/kprobes.h>
 
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
@@ -54,6 +56,9 @@
 #include <linux/irq.h>
 #include <linux/err.h>
 
+#include <asm/tlbflush.h>
+#include <asm/cpu.h>
+
 asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
 
 static int hlt_counter;
@@ -73,6 +78,7 @@ unsigned long thread_saved_pc(struct tas
  * Powermanagement idle function, if any..
  */
 void (*pm_idle)(void);
+EXPORT_SYMBOL(pm_idle);
 static DEFINE_PER_CPU(unsigned int, cpu_idle_state);
 
 void disable_hlt(void)
@@ -105,6 +111,9 @@ void default_idle(void)
 		cpu_relax();
 	}
 }
+#ifdef CONFIG_APM_MODULE
+EXPORT_SYMBOL(default_idle);
+#endif
 
 /*
  * On SMP it's slightly faster (but much more power-consuming!)
@@ -138,14 +147,42 @@ static void poll_idle (void)
 	}
 }
 
+#ifdef CONFIG_HOTPLUG_CPU
+#include <asm/nmi.h>
+/* We don't actually take CPU down, just spin without interrupts. */
+static inline void play_dead(void)
+{
+	/* This must be done before dead CPU ack */
+	cpu_exit_clear();
+	wbinvd();
+	mb();
+	/* Ack it */
+	__get_cpu_var(cpu_state) = CPU_DEAD;
+
+	/*
+	 * With physical CPU hotplug, we should halt the cpu
+	 */
+	local_irq_disable();
+	while (1)
+		__asm__ __volatile__("hlt":::"memory");
+}
+#else
+static inline void play_dead(void)
+{
+	BUG();
+}
+#endif /* CONFIG_HOTPLUG_CPU */
+
 /*
  * The idle thread. There's no useful work to be
  * done, so just try to conserve power and have a
  * low exit latency (ie sit in a loop waiting for
  * somebody to say that they'd like to reschedule)
  */
-void cpu_idle (void)
+void cpu_idle(void)
 {
+	int cpu = raw_smp_processor_id();
+
 	/* endless idle loop with no priority at all */
 	while (1) {
 		while (!need_resched()) {
@@ -160,6 +197,9 @@ void cpu_idle (void)
 			if (!idle)
 				idle = default_idle;
 
+			if (cpu_is_offline(cpu))
+				play_dead();
+
 			__get_cpu_var(irq_stat).idle_timestamp = jiffies;
 			idle();
 		}
@@ -218,7 +258,7 @@ static void mwait_idle(void)
 	}
 }
 
-void __init select_idle_routine(const struct cpuinfo_x86 *c)
+void __devinit select_idle_routine(const struct cpuinfo_x86 *c)
 {
 	if (cpu_has(c, X86_FEATURE_MWAIT)) {
 		printk("monitor/mwait feature present.\n");
@@ -262,7 +302,7 @@ void show_regs(struct pt_regs * regs)
 	printk("EIP: %04x:[<%08lx>] CPU: %d\n",0xffff & regs->xcs,regs->eip, smp_processor_id());
 	print_symbol("EIP is at %s\n", regs->eip);
 
-	if (regs->xcs & 3)
+	if (user_mode(regs))
 		printk(" ESP: %04x:%08lx",0xffff & regs->xss,regs->esp);
 	printk(" EFLAGS: %08lx    %s  (%s)\n",
 	       regs->eflags, print_tainted(), system_utsname.release);
@@ -325,6 +365,7 @@ int kernel_thread(int (*fn)(void *), voi
 	/* Ok, create the new process.. */
 	return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
 }
+EXPORT_SYMBOL(kernel_thread);
 
 /*
  * Free current thread data structures etc..
@@ -334,6 +375,13 @@ void exit_thread(void)
 	struct task_struct *tsk = current;
 	struct thread_struct *t = &tsk->thread;
 
+	/*
+	 * Remove function-return probe instances associated with this task
+	 * and put them back on the free list. Do not insert an exit probe for
+	 * this function, it will be disabled by kprobe_flush_task if you do.
+	 */
+	kprobe_flush_task(tsk);
+
 	/* The process may have allocated an io port bitmap... nuke it. */
 	if (unlikely(NULL != t->io_bitmap_ptr)) {
 		int cpu = get_cpu();
@@ -357,6 +405,13 @@ void flush_thread(void)
 {
 	struct task_struct *tsk = current;
 
+	/*
+	 * Remove function-return probe instances associated with this task
+	 * and put them back on the free list. Do not insert an exit probe for
+	 * this function, it will be disabled by kprobe_flush_task if you do.
+	 */
+	kprobe_flush_task(tsk);
+
 	memset(tsk->thread.debugreg, 0, sizeof(unsigned long)*8);
 	memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array));	
 	/*
@@ -508,6 +563,7 @@ void dump_thread(struct pt_regs * regs, 
 
 	dump->u_fpvalid = dump_fpu (regs, &dump->i387);
 }
+EXPORT_SYMBOL(dump_thread);
 
 /* 
  * Capture the user space registers if the task is not running (in user space)
@@ -561,6 +617,33 @@ handle_io_bitmap(struct thread_struct *n
 }
 
 /*
+ * This function selects if the context switch from prev to next
+ * has to tweak the TSC disable bit in the cr4.
+ */
+static inline void disable_tsc(struct task_struct *prev_p,
+			       struct task_struct *next_p)
+{
+	struct thread_info *prev, *next;
+
+	/*
+	 * gcc should eliminate the ->thread_info dereference if
+	 * has_secure_computing returns 0 at compile time (SECCOMP=n).
+	 */
+	prev = prev_p->thread_info;
+	next = next_p->thread_info;
+
+	if (has_secure_computing(prev) || has_secure_computing(next)) {
+		/* slow path here */
+		if (has_secure_computing(prev) &&
+		    !has_secure_computing(next)) {
+			write_cr4(read_cr4() & ~X86_CR4_TSD);
+		} else if (!has_secure_computing(prev) &&
+			   has_secure_computing(next))
+			write_cr4(read_cr4() | X86_CR4_TSD);
+	}
+}
+
+/*
  *	switch_to(x,yn) should switch tasks from x to y.
  *
  * We fsave/fwait so that an exception goes off at the right time
@@ -617,28 +700,34 @@ struct task_struct fastcall * __switch_t
 
 	/*
 	 * Restore %fs and %gs if needed.
+	 *
+	 * Glibc normally makes %fs be zero, and %gs is one of
+	 * the TLS segments.
 	 */
-	if (unlikely(prev->fs | prev->gs | next->fs | next->gs)) {
+	if (unlikely(prev->fs | next->fs))
 		loadsegment(fs, next->fs);
+
+	if (prev->gs | next->gs)
 		loadsegment(gs, next->gs);
-	}
 
 	/*
 	 * Now maybe reload the debug registers
 	 */
 	if (unlikely(next->debugreg[7])) {
-		loaddebug(next, 0);
-		loaddebug(next, 1);
-		loaddebug(next, 2);
-		loaddebug(next, 3);
+		set_debugreg(next->debugreg[0], 0);
+		set_debugreg(next->debugreg[1], 1);
+		set_debugreg(next->debugreg[2], 2);
+		set_debugreg(next->debugreg[3], 3);
 		/* no 4 and 5 */
-		loaddebug(next, 6);
-		loaddebug(next, 7);
+		set_debugreg(next->debugreg[6], 6);
+		set_debugreg(next->debugreg[7], 7);
 	}
 
 	if (unlikely(prev->io_bitmap_ptr || next->io_bitmap_ptr))
 		handle_io_bitmap(next, tss);
 
+	disable_tsc(prev_p, next_p);
+
 	return prev_p;
 }
 
@@ -731,6 +820,7 @@ unsigned long get_wchan(struct task_stru
 	} while (count++ < 16);
 	return 0;
 }
+EXPORT_SYMBOL(get_wchan);
 
 /*
  * sys_alloc_thread_area: get a yet unused TLS descriptor index.
@@ -827,6 +917,8 @@ asmlinkage int sys_get_thread_area(struc
 	if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
 		return -EINVAL;
 
+	memset(&info, 0, sizeof(info));
+
 	desc = current->thread.tls_array + idx - GDT_ENTRY_TLS_MIN;
 
 	info.entry_number = idx;
diff --git a/arch/i386/kernel/ptrace.c b/arch/i386/kernel/ptrace.c
--- a/arch/i386/kernel/ptrace.c
+++ b/arch/i386/kernel/ptrace.c
@@ -668,7 +668,7 @@ void send_sigtrap(struct task_struct *ts
 	info.si_code = TRAP_BRKPT;
 
 	/* User-mode eip? */
-	info.si_addr = user_mode(regs) ? (void __user *) regs->eip : NULL;
+	info.si_addr = user_mode_vm(regs) ? (void __user *) regs->eip : NULL;
 
 	/* Send us the fakey SIGTRAP */
 	force_sig_info(SIGTRAP, &info, tsk);
diff --git a/arch/i386/kernel/reboot.c b/arch/i386/kernel/reboot.c
--- a/arch/i386/kernel/reboot.c
+++ b/arch/i386/kernel/reboot.c
@@ -2,6 +2,7 @@
  *  linux/arch/i386/kernel/reboot.c
  */
 
+#include <linux/config.h>
 #include <linux/mm.h>
 #include <linux/module.h>
 #include <linux/delay.h>
@@ -19,12 +20,12 @@
  * Power off function, if any
  */
 void (*pm_power_off)(void);
+EXPORT_SYMBOL(pm_power_off);
 
 static int reboot_mode;
 static int reboot_thru_bios;
 
 #ifdef CONFIG_SMP
-int reboot_smp = 0;
 static int reboot_cpu = -1;
 /* shamelessly grabbed from lib/vsprintf.c for readability */
 #define is_digit(c)	((c) >= '0' && (c) <= '9')
@@ -47,7 +48,6 @@ static int __init reboot_setup(char *str
 			break;
 #ifdef CONFIG_SMP
 		case 's': /* "smp" reboot by executing reset on BSP or other CPU*/
-			reboot_smp = 1;
 			if (is_digit(*(str+1))) {
 				reboot_cpu = (int) (*(str+1) - '0');
 				if (is_digit(*(str+2))) 
@@ -86,33 +86,9 @@ static int __init set_bios_reboot(struct
 	return 0;
 }
 
-/*
- * Some machines require the "reboot=s"  commandline option, this quirk makes that automatic.
- */
-static int __init set_smp_reboot(struct dmi_system_id *d)
-{
-#ifdef CONFIG_SMP
-	if (!reboot_smp) {
-		reboot_smp = 1;
-		printk(KERN_INFO "%s series board detected. Selecting SMP-method for reboots.\n", d->ident);
-	}
-#endif
-	return 0;
-}
-
-/*
- * Some machines require the "reboot=b,s"  commandline option, this quirk makes that automatic.
- */
-static int __init set_smp_bios_reboot(struct dmi_system_id *d)
-{
-	set_smp_reboot(d);
-	set_bios_reboot(d);
-	return 0;
-}
-
 static struct dmi_system_id __initdata reboot_dmi_table[] = {
 	{	/* Handle problems with rebooting on Dell 1300's */
-		.callback = set_smp_bios_reboot,
+		.callback = set_bios_reboot,
 		.ident = "Dell PowerEdge 1300",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
@@ -295,42 +271,36 @@ void machine_real_restart(unsigned char 
 				:
 				: "i" ((void *) (0x1000 - sizeof (real_mode_switch) - 100)));
 }
+#ifdef CONFIG_APM_MODULE
+EXPORT_SYMBOL(machine_real_restart);
+#endif
 
-void machine_restart(char * __unused)
+void machine_shutdown(void)
 {
 #ifdef CONFIG_SMP
-	int cpuid;
-	
-	cpuid = GET_APIC_ID(apic_read(APIC_ID));
-
-	if (reboot_smp) {
-
-		/* check to see if reboot_cpu is valid 
-		   if its not, default to the BSP */
-		if ((reboot_cpu == -1) ||  
-		      (reboot_cpu > (NR_CPUS -1))  || 
-		      !physid_isset(cpuid, phys_cpu_present_map))
-			reboot_cpu = boot_cpu_physical_apicid;
-
-		reboot_smp = 0;  /* use this as a flag to only go through this once*/
-		/* re-run this function on the other CPUs
-		   it will fall though this section since we have 
-		   cleared reboot_smp, and do the reboot if it is the
-		   correct CPU, otherwise it halts. */
-		if (reboot_cpu != cpuid)
-			smp_call_function((void *)machine_restart , NULL, 1, 0);
+	int reboot_cpu_id;
+
+	/* The boot cpu is always logical cpu 0 */
+	reboot_cpu_id = 0;
+
+	/* See if there has been given a command line override */
+	if ((reboot_cpu != -1) && (reboot_cpu < NR_CPUS) &&
+		cpu_isset(reboot_cpu, cpu_online_map)) {
+		reboot_cpu_id = reboot_cpu;
 	}
 
-	/* if reboot_cpu is still -1, then we want a tradional reboot, 
-	   and if we are not running on the reboot_cpu,, halt */
-	if ((reboot_cpu != -1) && (cpuid != reboot_cpu)) {
-		for (;;)
-		__asm__ __volatile__ ("hlt");
+	/* Make certain the cpu I'm rebooting on is online */
+	if (!cpu_isset(reboot_cpu_id, cpu_online_map)) {
+		reboot_cpu_id = smp_processor_id();
 	}
-	/*
-	 * Stop all CPUs and turn off local APICs and the IO-APIC, so
-	 * other OSs see a clean IRQ state.
+
+	/* Make certain I only run on the appropriate processor */
+	set_cpus_allowed(current, cpumask_of_cpu(reboot_cpu_id));
+
+	/* O.K. Now that I'm on the appropriate processor, stop
+	 * all of the others, and disable their local APICs.
 	 */
+
 	smp_send_stop();
 #endif /* CONFIG_SMP */
 
@@ -339,7 +309,10 @@ void machine_restart(char * __unused)
 #ifdef CONFIG_X86_IO_APIC
 	disable_IO_APIC();
 #endif
+}
 
+void machine_emergency_restart(void)
+{
 	if (!reboot_thru_bios) {
 		if (efi_enabled) {
 			efi.reset_system(EFI_RESET_COLD, EFI_SUCCESS, 0, NULL);
@@ -362,23 +335,22 @@ void machine_restart(char * __unused)
 	machine_real_restart(jump_to_bios, sizeof(jump_to_bios));
 }
 
-EXPORT_SYMBOL(machine_restart);
+void machine_restart(char * __unused)
+{
+	machine_shutdown();
+	machine_emergency_restart();
+}
 
 void machine_halt(void)
 {
 }
 
-EXPORT_SYMBOL(machine_halt);
-
 void machine_power_off(void)
 {
-	lapic_shutdown();
+	machine_shutdown();
 
-	if (efi_enabled)
-		efi.reset_system(EFI_RESET_SHUTDOWN, EFI_SUCCESS, 0, NULL);
 	if (pm_power_off)
 		pm_power_off();
 }
 
-EXPORT_SYMBOL(machine_power_off);
 
diff --git a/arch/i386/kernel/relocate_kernel.S b/arch/i386/kernel/relocate_kernel.S
new file mode 100644
--- /dev/null
+++ b/arch/i386/kernel/relocate_kernel.S
@@ -0,0 +1,120 @@
+/*
+ * relocate_kernel.S - put the kernel image in place to boot
+ * Copyright (C) 2002-2004 Eric Biederman  <ebiederm@xmission.com>
+ *
+ * This source code is licensed under the GNU General Public License,
+ * Version 2.  See the file COPYING for more details.
+ */
+
+#include <linux/linkage.h>
+
+	/*
+	 * Must be relocatable PIC code callable as a C function, that once
+	 * it starts can not use the previous processes stack.
+	 */
+	.globl relocate_new_kernel
+relocate_new_kernel:
+	/* read the arguments and say goodbye to the stack */
+	movl  4(%esp), %ebx /* page_list */
+	movl  8(%esp), %ebp /* reboot_code_buffer */
+	movl  12(%esp), %edx /* start address */
+	movl  16(%esp), %ecx /* cpu_has_pae */
+
+	/* zero out flags, and disable interrupts */
+	pushl $0
+	popfl
+
+	/* set a new stack at the bottom of our page... */
+	lea   4096(%ebp), %esp
+
+	/* store the parameters back on the stack */
+	pushl   %edx /* store the start address */
+
+	/* Set cr0 to a known state:
+	 * 31 0 == Paging disabled
+	 * 18 0 == Alignment check disabled
+	 * 16 0 == Write protect disabled
+	 * 3  0 == No task switch
+	 * 2  0 == Don't do FP software emulation.
+	 * 0  1 == Proctected mode enabled
+	 */
+	movl	%cr0, %eax
+	andl	$~((1<<31)|(1<<18)|(1<<16)|(1<<3)|(1<<2)), %eax
+	orl	$(1<<0), %eax
+	movl	%eax, %cr0
+
+	/* clear cr4 if applicable */
+	testl	%ecx, %ecx
+	jz	1f
+	/* Set cr4 to a known state:
+	 * Setting everything to zero seems safe.
+	 */
+	movl	%cr4, %eax
+	andl	$0, %eax
+	movl	%eax, %cr4
+
+	jmp 1f
+1:
+
+	/* Flush the TLB (needed?) */
+	xorl	%eax, %eax
+	movl	%eax, %cr3
+
+	/* Do the copies */
+	movl	%ebx, %ecx
+	jmp	1f
+
+0:	/* top, read another word from the indirection page */
+	movl	(%ebx), %ecx
+	addl	$4, %ebx
+1:
+	testl	$0x1,   %ecx  /* is it a destination page */
+	jz	2f
+	movl	%ecx,	%edi
+	andl	$0xfffff000, %edi
+	jmp     0b
+2:
+	testl	$0x2,	%ecx  /* is it an indirection page */
+	jz	2f
+	movl	%ecx,	%ebx
+	andl	$0xfffff000, %ebx
+	jmp     0b
+2:
+	testl   $0x4,   %ecx /* is it the done indicator */
+	jz      2f
+	jmp     3f
+2:
+	testl   $0x8,   %ecx /* is it the source indicator */
+	jz      0b	     /* Ignore it otherwise */
+	movl    %ecx,   %esi /* For every source page do a copy */
+	andl    $0xfffff000, %esi
+
+	movl    $1024, %ecx
+	rep ; movsl
+	jmp     0b
+
+3:
+
+	/* To be certain of avoiding problems with self-modifying code
+	 * I need to execute a serializing instruction here.
+	 * So I flush the TLB, it's handy, and not processor dependent.
+	 */
+	xorl	%eax, %eax
+	movl	%eax, %cr3
+
+	/* set all of the registers to known values */
+	/* leave %esp alone */
+
+	xorl	%eax, %eax
+	xorl	%ebx, %ebx
+	xorl    %ecx, %ecx
+	xorl    %edx, %edx
+	xorl    %esi, %esi
+	xorl    %edi, %edi
+	xorl    %ebp, %ebp
+	ret
+relocate_new_kernel_end:
+
+	.globl relocate_new_kernel_size
+relocate_new_kernel_size:
+	.long relocate_new_kernel_end - relocate_new_kernel
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c
--- a/arch/i386/kernel/setup.c
+++ b/arch/i386/kernel/setup.c
@@ -23,8 +23,10 @@
  * This file handles the architecture-dependent parts of initialization
  */
 
+#include <linux/config.h>
 #include <linux/sched.h>
 #include <linux/mm.h>
+#include <linux/mmzone.h>
 #include <linux/tty.h>
 #include <linux/ioport.h>
 #include <linux/acpi.h>
@@ -41,7 +43,12 @@
 #include <linux/init.h>
 #include <linux/edd.h>
 #include <linux/nodemask.h>
+#include <linux/kexec.h>
+#include <linux/crash_dump.h>
+
 #include <video/edid.h>
+
+#include <asm/apic.h>
 #include <asm/e820.h>
 #include <asm/mpspec.h>
 #include <asm/setup.h>
@@ -53,12 +60,15 @@
 #include "setup_arch_pre.h"
 #include <bios_ebda.h>
 
+/* Forward Declaration. */
+void __init find_max_pfn(void);
+
 /* This value is set up by the early boot code to point to the value
    immediately after the boot time page tables.  It contains a *physical*
    address, and must not be in the .bss segment! */
 unsigned long init_pg_tables_end __initdata = ~0UL;
 
-int disable_pse __initdata = 0;
+int disable_pse __devinitdata = 0;
 
 /*
  * Machine setup..
@@ -73,6 +83,7 @@ EXPORT_SYMBOL(efi_enabled);
 struct cpuinfo_x86 new_cpu_data __initdata = { 0, 0, 0, 0, -1, 1, 0, 0, -1 };
 /* common cpu data for all cpus */
 struct cpuinfo_x86 boot_cpu_data = { 0, 0, 0, 0, -1, 1, 0, 0, -1 };
+EXPORT_SYMBOL(boot_cpu_data);
 
 unsigned long mmu_cr4_features;
 
@@ -90,12 +101,18 @@ extern acpi_interrupt_flags	acpi_sci_fla
 
 /* for MCA, but anyone else can use it if they want */
 unsigned int machine_id;
+#ifdef CONFIG_MCA
+EXPORT_SYMBOL(machine_id);
+#endif
 unsigned int machine_submodel_id;
 unsigned int BIOS_revision;
 unsigned int mca_pentium_flag;
 
 /* For PCI or other memory-mapped resources */
 unsigned long pci_mem_start = 0x10000000;
+#ifdef CONFIG_PCI
+EXPORT_SYMBOL(pci_mem_start);
+#endif
 
 /* Boot loader ID as an integer, for the benefit of proc_dointvec */
 int bootloader_type;
@@ -107,14 +124,26 @@ static unsigned int highmem_pages = -1;
  * Setup options
  */
 struct drive_info_struct { char dummy[32]; } drive_info;
+#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_HD) || \
+    defined(CONFIG_BLK_DEV_IDE_MODULE) || defined(CONFIG_BLK_DEV_HD_MODULE)
+EXPORT_SYMBOL(drive_info);
+#endif
 struct screen_info screen_info;
+#ifdef CONFIG_VT
+EXPORT_SYMBOL(screen_info);
+#endif
 struct apm_info apm_info;
+EXPORT_SYMBOL(apm_info);
 struct sys_desc_table_struct {
 	unsigned short length;
 	unsigned char table[0];
 };
 struct edid_info edid_info;
 struct ist_info ist_info;
+#if defined(CONFIG_X86_SPEEDSTEP_SMI) || \
+	defined(CONFIG_X86_SPEEDSTEP_SMI_MODULE)
+EXPORT_SYMBOL(ist_info);
+#endif
 struct e820map e820;
 
 extern void early_cpu_init(void);
@@ -711,6 +740,15 @@ static void __init parse_cmdline_early (
 			if (to != command_line)
 				to--;
 			if (!memcmp(from+7, "exactmap", 8)) {
+#ifdef CONFIG_CRASH_DUMP
+				/* If we are doing a crash dump, we
+				 * still need to know the real mem
+				 * size before original memory map is
+				 * reset.
+				 */
+				find_max_pfn();
+				saved_max_pfn = max_pfn;
+#endif
 				from += 8+7;
 				e820.nr_map = 0;
 				userdef = 1;
@@ -814,6 +852,44 @@ static void __init parse_cmdline_early (
 #endif /* CONFIG_X86_LOCAL_APIC */
 #endif /* CONFIG_ACPI_BOOT */
 
+#ifdef CONFIG_X86_LOCAL_APIC
+		/* enable local APIC */
+		else if (!memcmp(from, "lapic", 5))
+			lapic_enable();
+
+		/* disable local APIC */
+		else if (!memcmp(from, "nolapic", 6))
+			lapic_disable();
+#endif /* CONFIG_X86_LOCAL_APIC */
+
+#ifdef CONFIG_KEXEC
+		/* crashkernel=size@addr specifies the location to reserve for
+		 * a crash kernel.  By reserving this memory we guarantee
+		 * that linux never set's it up as a DMA target.
+		 * Useful for holding code to do something appropriate
+		 * after a kernel panic.
+		 */
+		else if (!memcmp(from, "crashkernel=", 12)) {
+			unsigned long size, base;
+			size = memparse(from+12, &from);
+			if (*from == '@') {
+				base = memparse(from+1, &from);
+				/* FIXME: Do I want a sanity check
+				 * to validate the memory range?
+				 */
+				crashk_res.start = base;
+				crashk_res.end   = base + size - 1;
+			}
+		}
+#endif
+#ifdef CONFIG_CRASH_DUMP
+		/* elfcorehdr= specifies the location of elf core header
+		 * stored by the crashed kernel.
+		 */
+		else if (!memcmp(from, "elfcorehdr=", 11))
+			elfcorehdr_addr = memparse(from+11, &from);
+#endif
+
 		/*
 		 * highmem=size forces highmem to be exactly 'size' bytes.
 		 * This works even on boxes that have no highmem otherwise.
@@ -1022,7 +1098,7 @@ static void __init reserve_ebda_region(v
 		reserve_bootmem(addr, PAGE_SIZE);	
 }
 
-#ifndef CONFIG_DISCONTIGMEM
+#ifndef CONFIG_NEED_MULTIPLE_NODES
 void __init setup_bootmem_allocator(void);
 static unsigned long __init setup_memory(void)
 {
@@ -1072,9 +1148,9 @@ void __init zone_sizes_init(void)
 	free_area_init(zones_size);
 }
 #else
-extern unsigned long setup_memory(void);
+extern unsigned long __init setup_memory(void);
 extern void zone_sizes_init(void);
-#endif /* !CONFIG_DISCONTIGMEM */
+#endif /* !CONFIG_NEED_MULTIPLE_NODES */
 
 void __init setup_bootmem_allocator(void)
 {
@@ -1092,8 +1168,8 @@ void __init setup_bootmem_allocator(void
 	 * the (very unlikely) case of us accidentally initializing the
 	 * bootmem allocator with an invalid RAM area.
 	 */
-	reserve_bootmem(HIGH_MEMORY, (PFN_PHYS(min_low_pfn) +
-			 bootmap_size + PAGE_SIZE-1) - (HIGH_MEMORY));
+	reserve_bootmem(__PHYSICAL_START, (PFN_PHYS(min_low_pfn) +
+			 bootmap_size + PAGE_SIZE-1) - (__PHYSICAL_START));
 
 	/*
 	 * reserve physical page 0 - it's a special BIOS page on many boxes,
@@ -1149,6 +1225,11 @@ void __init setup_bootmem_allocator(void
 		}
 	}
 #endif
+#ifdef CONFIG_KEXEC
+	if (crashk_res.start != crashk_res.end)
+		reserve_bootmem(crashk_res.start,
+			crashk_res.end - crashk_res.start + 1);
+#endif
 }
 
 /*
@@ -1202,6 +1283,9 @@ legacy_init_iomem_resources(struct resou
 			 */
 			request_resource(res, code_resource);
 			request_resource(res, data_resource);
+#ifdef CONFIG_KEXEC
+			request_resource(res, &crashk_res);
+#endif
 		}
 	}
 }
@@ -1330,7 +1414,7 @@ static struct nop { 
    This runs before SMP is initialized to avoid SMP problems with
    self modifying code. This implies that assymetric systems where
    APs have less capabilities than the boot processor are not handled. 
-   In this case boot with "noreplacement". */ 
+   Tough. Make sure you disable such features by hand. */ 
 void apply_alternatives(void *start, void *end) 
 { 
 	struct alt_instr *a; 
@@ -1358,24 +1442,12 @@ void apply_alternatives(void *start, voi
 	}
 } 
 
-static int no_replacement __initdata = 0; 
- 
 void __init alternative_instructions(void)
 {
 	extern struct alt_instr __alt_instructions[], __alt_instructions_end[];
-	if (no_replacement) 
-		return;
 	apply_alternatives(__alt_instructions, __alt_instructions_end);
 }
 
-static int __init noreplacement_setup(char *s)
-{ 
-     no_replacement = 1; 
-     return 0; 
-} 
-
-__setup("noreplacement", noreplacement_setup); 
-
 static char * __init machine_specific_memory_setup(void);
 
 #ifdef CONFIG_MCA
@@ -1475,6 +1547,7 @@ void __init setup_arch(char **cmdline_p)
 #endif
 	paging_init();
 	remapped_pgdat_init();
+	sparse_init();
 	zone_sizes_init();
 
 	/*
diff --git a/arch/i386/kernel/signal.c b/arch/i386/kernel/signal.c
--- a/arch/i386/kernel/signal.c
+++ b/arch/i386/kernel/signal.c
@@ -346,8 +346,8 @@ get_sigframe(struct k_sigaction *ka, str
 extern void __user __kernel_sigreturn;
 extern void __user __kernel_rt_sigreturn;
 
-static void setup_frame(int sig, struct k_sigaction *ka,
-			sigset_t *set, struct pt_regs * regs)
+static int setup_frame(int sig, struct k_sigaction *ka,
+		       sigset_t *set, struct pt_regs * regs)
 {
 	void __user *restorer;
 	struct sigframe __user *frame;
@@ -429,13 +429,14 @@ static void setup_frame(int sig, struct 
 		current->comm, current->pid, frame, regs->eip, frame->pretcode);
 #endif
 
-	return;
+	return 1;
 
 give_sigsegv:
 	force_sigsegv(sig, current);
+	return 0;
 }
 
-static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
+static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
 			   sigset_t *set, struct pt_regs * regs)
 {
 	void __user *restorer;
@@ -522,20 +523,23 @@ static void setup_rt_frame(int sig, stru
 		current->comm, current->pid, frame, regs->eip, frame->pretcode);
 #endif
 
-	return;
+	return 1;
 
 give_sigsegv:
 	force_sigsegv(sig, current);
+	return 0;
 }
 
 /*
  * OK, we're invoking a handler
  */	
 
-static void
+static int
 handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
 	      sigset_t *oldset,	struct pt_regs * regs)
 {
+	int ret;
+
 	/* Are we from a system call? */
 	if (regs->orig_eax >= 0) {
 		/* If so, check system call restarting.. */
@@ -569,17 +573,19 @@ handle_signal(unsigned long sig, siginfo
 
 	/* Set up the stack frame */
 	if (ka->sa.sa_flags & SA_SIGINFO)
-		setup_rt_frame(sig, ka, info, oldset, regs);
+		ret = setup_rt_frame(sig, ka, info, oldset, regs);
 	else
-		setup_frame(sig, ka, oldset, regs);
+		ret = setup_frame(sig, ka, oldset, regs);
 
-	if (!(ka->sa.sa_flags & SA_NODEFER)) {
+	if (ret && !(ka->sa.sa_flags & SA_NODEFER)) {
 		spin_lock_irq(&current->sighand->siglock);
 		sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
 		sigaddset(&current->blocked,sig);
 		recalc_sigpending();
 		spin_unlock_irq(&current->sighand->siglock);
 	}
+
+	return ret;
 }
 
 /*
@@ -599,13 +605,11 @@ int fastcall do_signal(struct pt_regs *r
 	 * kernel mode. Just return without doing anything
 	 * if so.
 	 */
-	if ((regs->xcs & 3) != 3)
+	if (!user_mode(regs))
 		return 1;
 
-	if (current->flags & PF_FREEZE) {
-		refrigerator(0);
+	if (try_to_freeze())
 		goto no_signal;
-	}
 
 	if (!oldset)
 		oldset = &current->blocked;
@@ -618,12 +622,11 @@ int fastcall do_signal(struct pt_regs *r
 		 * inside the kernel.
 		 */
 		if (unlikely(current->thread.debugreg[7])) {
-			loaddebug(&current->thread, 7);
+			set_debugreg(current->thread.debugreg[7], 7);
 		}
 
 		/* Whee!  Actually deliver the signal.  */
-		handle_signal(signr, &info, &ka, oldset, regs);
-		return 1;
+		return handle_signal(signr, &info, &ka, oldset, regs);
 	}
 
  no_signal:
diff --git a/arch/i386/kernel/smp.c b/arch/i386/kernel/smp.c
--- a/arch/i386/kernel/smp.c
+++ b/arch/i386/kernel/smp.c
@@ -19,6 +19,8 @@
 #include <linux/mc146818rtc.h>
 #include <linux/cache.h>
 #include <linux/interrupt.h>
+#include <linux/cpu.h>
+#include <linux/module.h>
 
 #include <asm/mtrr.h>
 #include <asm/tlbflush.h>
@@ -163,7 +165,7 @@ void send_IPI_mask_bitmask(cpumask_t cpu
 	unsigned long flags;
 
 	local_irq_save(flags);
-		
+	WARN_ON(mask & ~cpus_addr(cpu_online_map)[0]);
 	/*
 	 * Wait for idle.
 	 */
@@ -345,21 +347,21 @@ out:
 static void flush_tlb_others(cpumask_t cpumask, struct mm_struct *mm,
 						unsigned long va)
 {
-	cpumask_t tmp;
 	/*
 	 * A couple of (to be removed) sanity checks:
 	 *
-	 * - we do not send IPIs to not-yet booted CPUs.
 	 * - current CPU must not be in mask
 	 * - mask must exist :)
 	 */
 	BUG_ON(cpus_empty(cpumask));
-
-	cpus_and(tmp, cpumask, cpu_online_map);
-	BUG_ON(!cpus_equal(cpumask, tmp));
 	BUG_ON(cpu_isset(smp_processor_id(), cpumask));
 	BUG_ON(!mm);
 
+	/* If a CPU which we ran on has gone down, OK. */
+	cpus_and(cpumask, cpumask, cpu_online_map);
+	if (cpus_empty(cpumask))
+		return;
+
 	/*
 	 * i'm not happy about this global shared spinlock in the
 	 * MM hot path, but we'll see how contended it is.
@@ -452,6 +454,7 @@ void flush_tlb_page(struct vm_area_struc
 
 	preempt_enable();
 }
+EXPORT_SYMBOL(flush_tlb_page);
 
 static void do_flush_tlb_all(void* info)
 {
@@ -474,6 +477,7 @@ void flush_tlb_all(void)
  */
 void smp_send_reschedule(int cpu)
 {
+	WARN_ON(cpu_is_offline(cpu));
 	send_IPI_mask(cpumask_of_cpu(cpu), RESCHEDULE_VECTOR);
 }
 
@@ -491,6 +495,16 @@ struct call_data_struct {
 	int wait;
 };
 
+void lock_ipi_call_lock(void)
+{
+	spin_lock_irq(&call_lock);
+}
+
+void unlock_ipi_call_lock(void)
+{
+	spin_unlock_irq(&call_lock);
+}
+
 static struct call_data_struct * call_data;
 
 /*
@@ -514,10 +528,15 @@ int smp_call_function (void (*func) (voi
  */
 {
 	struct call_data_struct data;
-	int cpus = num_online_cpus()-1;
+	int cpus;
 
-	if (!cpus)
+	/* Holding any lock stops cpus from going down. */
+	spin_lock(&call_lock);
+	cpus = num_online_cpus() - 1;
+	if (!cpus) {
+		spin_unlock(&call_lock);
 		return 0;
+	}
 
 	/* Can deadlock when called with interrupts disabled */
 	WARN_ON(irqs_disabled());
@@ -529,7 +548,6 @@ int smp_call_function (void (*func) (voi
 	if (wait)
 		atomic_set(&data.finished, 0);
 
-	spin_lock(&call_lock);
 	call_data = &data;
 	mb();
 	
@@ -547,6 +565,7 @@ int smp_call_function (void (*func) (voi
 
 	return 0;
 }
+EXPORT_SYMBOL(smp_call_function);
 
 static void stop_this_cpu (void * dummy)
 {
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c
--- a/arch/i386/kernel/smpboot.c
+++ b/arch/i386/kernel/smpboot.c
@@ -44,6 +44,9 @@
 #include <linux/smp_lock.h>
 #include <linux/irq.h>
 #include <linux/bootmem.h>
+#include <linux/notifier.h>
+#include <linux/cpu.h>
+#include <linux/percpu.h>
 
 #include <linux/delay.h>
 #include <linux/mc146818rtc.h>
@@ -56,26 +59,48 @@
 #include <smpboot_hooks.h>
 
 /* Set if we find a B stepping CPU */
-static int __initdata smp_b_stepping;
+static int __devinitdata smp_b_stepping;
 
 /* Number of siblings per CPU package */
 int smp_num_siblings = 1;
-int phys_proc_id[NR_CPUS]; /* Package ID of each logical CPU */
+#ifdef CONFIG_X86_HT
+EXPORT_SYMBOL(smp_num_siblings);
+#endif
+
+/* Package ID of each logical CPU */
+int phys_proc_id[NR_CPUS] __read_mostly = {[0 ... NR_CPUS-1] = BAD_APICID};
 EXPORT_SYMBOL(phys_proc_id);
-int cpu_core_id[NR_CPUS]; /* Core ID of each logical CPU */
+
+/* Core ID of each logical CPU */
+int cpu_core_id[NR_CPUS] __read_mostly = {[0 ... NR_CPUS-1] = BAD_APICID};
 EXPORT_SYMBOL(cpu_core_id);
 
+cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly;
+EXPORT_SYMBOL(cpu_sibling_map);
+
+cpumask_t cpu_core_map[NR_CPUS] __read_mostly;
+EXPORT_SYMBOL(cpu_core_map);
+
 /* bitmap of online cpus */
-cpumask_t cpu_online_map;
+cpumask_t cpu_online_map __read_mostly;
+EXPORT_SYMBOL(cpu_online_map);
 
 cpumask_t cpu_callin_map;
 cpumask_t cpu_callout_map;
+EXPORT_SYMBOL(cpu_callout_map);
 static cpumask_t smp_commenced_mask;
 
+/* TSC's upper 32 bits can't be written in eariler CPU (before prescott), there
+ * is no way to resync one AP against BP. TBD: for prescott and above, we
+ * should use IA64's algorithm
+ */
+static int __devinitdata tsc_sync_disabled;
+
 /* Per CPU bogomips and other parameters */
 struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned;
+EXPORT_SYMBOL(cpu_data);
 
-u8 x86_cpu_to_apicid[NR_CPUS] =
+u8 x86_cpu_to_apicid[NR_CPUS] __read_mostly =
 			{ [0 ... NR_CPUS-1] = 0xff };
 EXPORT_SYMBOL(x86_cpu_to_apicid);
 
@@ -90,13 +115,16 @@ static int trampoline_exec;
 
 static void map_cpu_to_logical_apicid(void);
 
+/* State of each CPU. */
+DEFINE_PER_CPU(int, cpu_state) = { 0 };
+
 /*
  * Currently trivial. Write the real->protected mode
  * bootstrap into the page concerned. The caller
  * has made sure it's suitably aligned.
  */
 
-static unsigned long __init setup_trampoline(void)
+static unsigned long __devinit setup_trampoline(void)
 {
 	memcpy(trampoline_base, trampoline_data, trampoline_end - trampoline_data);
 	return virt_to_phys(trampoline_base);
@@ -126,7 +154,7 @@ void __init smp_alloc_memory(void)
  * a given CPU
  */
 
-static void __init smp_store_cpu_info(int id)
+static void __devinit smp_store_cpu_info(int id)
 {
 	struct cpuinfo_x86 *c = cpu_data + id;
 
@@ -199,7 +227,7 @@ static void __init synchronize_tsc_bp (v
 	unsigned long long t0;
 	unsigned long long sum, avg;
 	long long delta;
-	unsigned long one_usec;
+	unsigned int one_usec;
 	int buggy = 0;
 
 	printk(KERN_INFO "checking TSC synchronization across %u CPUs: ", num_booting_cpus());
@@ -320,7 +348,7 @@ extern void calibrate_delay(void);
 
 static atomic_t init_deasserted;
 
-static void __init smp_callin(void)
+static void __devinit smp_callin(void)
 {
 	int cpuid, phys_id;
 	unsigned long timeout;
@@ -405,16 +433,48 @@ static void __init smp_callin(void)
 	/*
 	 *      Synchronize the TSC with the BP
 	 */
-	if (cpu_has_tsc && cpu_khz)
+	if (cpu_has_tsc && cpu_khz && !tsc_sync_disabled)
 		synchronize_tsc_ap();
 }
 
 static int cpucount;
 
+static inline void
+set_cpu_sibling_map(int cpu)
+{
+	int i;
+
+	if (smp_num_siblings > 1) {
+		for (i = 0; i < NR_CPUS; i++) {
+			if (!cpu_isset(i, cpu_callout_map))
+				continue;
+			if (cpu_core_id[cpu] == cpu_core_id[i]) {
+				cpu_set(i, cpu_sibling_map[cpu]);
+				cpu_set(cpu, cpu_sibling_map[i]);
+			}
+		}
+	} else {
+		cpu_set(cpu, cpu_sibling_map[cpu]);
+	}
+
+	if (current_cpu_data.x86_num_cores > 1) {
+		for (i = 0; i < NR_CPUS; i++) {
+			if (!cpu_isset(i, cpu_callout_map))
+				continue;
+			if (phys_proc_id[cpu] == phys_proc_id[i]) {
+				cpu_set(i, cpu_core_map[cpu]);
+				cpu_set(cpu, cpu_core_map[i]);
+			}
+		}
+	} else {
+		cpu_core_map[cpu] = cpu_sibling_map[cpu];
+	}
+}
+
 /*
  * Activate a secondary processor.
  */
-static void __init start_secondary(void *unused)
+static void __devinit start_secondary(void *unused)
 {
 	/*
 	 * Dont put anything before smp_callin(), SMP
@@ -437,7 +497,23 @@ static void __init start_secondary(void 
 	 * the local TLBs too.
 	 */
 	local_flush_tlb();
+
+	/* This must be done before setting cpu_online_map */
+	set_cpu_sibling_map(raw_smp_processor_id());
+	wmb();
+
+	/*
+	 * We need to hold call_lock, so there is no inconsistency
+	 * between the time smp_call_function() determines number of
+	 * IPI receipients, and the time when the determination is made
+	 * for which cpus receive the IPI. Holding this
+	 * lock helps us to not include this cpu in a currently in progress
+	 * smp_call_function().
+	 */
+	lock_ipi_call_lock();
 	cpu_set(smp_processor_id(), cpu_online_map);
+	unlock_ipi_call_lock();
+	per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE;
 
 	/* We can take interrupts now: we're officially "up". */
 	local_irq_enable();
@@ -452,7 +528,7 @@ static void __init start_secondary(void 
  * from the task structure
  * This function must not return.
  */
-void __init initialize_secondary(void)
+void __devinit initialize_secondary(void)
 {
 	/*
 	 * We don't actually need to load the full TSS,
@@ -474,10 +550,10 @@ extern struct {
 #ifdef CONFIG_NUMA
 
 /* which logical CPUs are on which nodes */
-cpumask_t node_2_cpu_mask[MAX_NUMNODES] =
+cpumask_t node_2_cpu_mask[MAX_NUMNODES] __read_mostly =
 				{ [0 ... MAX_NUMNODES-1] = CPU_MASK_NONE };
 /* which node each logical CPU is on */
-int cpu_2_node[NR_CPUS] = { [0 ... NR_CPUS-1] = 0 };
+int cpu_2_node[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = 0 };
 EXPORT_SYMBOL(cpu_2_node);
 
 /* set up a mapping between cpu and node. */
@@ -505,7 +581,7 @@ static inline void unmap_cpu_to_node(int
 
 #endif /* CONFIG_NUMA */
 
-u8 cpu_2_logical_apicid[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID };
+u8 cpu_2_logical_apicid[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = BAD_APICID };
 
 static void map_cpu_to_logical_apicid(void)
 {
@@ -566,7 +642,7 @@ static inline void __inquire_remote_apic
  * INIT, INIT, STARTUP sequence will reset the chip hard for us, and this
  * won't ... remember to clear down the APIC, etc later.
  */
-static int __init
+static int __devinit
 wakeup_secondary_cpu(int logical_apicid, unsigned long start_eip)
 {
 	unsigned long send_status = 0, accept_status = 0;
@@ -612,7 +688,7 @@ wakeup_secondary_cpu(int logical_apicid,
 #endif	/* WAKE_SECONDARY_VIA_NMI */
 
 #ifdef WAKE_SECONDARY_VIA_INIT
-static int __init
+static int __devinit
 wakeup_secondary_cpu(int phys_apicid, unsigned long start_eip)
 {
 	unsigned long send_status = 0, accept_status = 0;
@@ -747,8 +823,43 @@ wakeup_secondary_cpu(int phys_apicid, un
 #endif	/* WAKE_SECONDARY_VIA_INIT */
 
 extern cpumask_t cpu_initialized;
+static inline int alloc_cpu_id(void)
+{
+	cpumask_t	tmp_map;
+	int cpu;
+	cpus_complement(tmp_map, cpu_present_map);
+	cpu = first_cpu(tmp_map);
+	if (cpu >= NR_CPUS)
+		return -ENODEV;
+	return cpu;
+}
+
+#ifdef CONFIG_HOTPLUG_CPU
+static struct task_struct * __devinitdata cpu_idle_tasks[NR_CPUS];
+static inline struct task_struct * alloc_idle_task(int cpu)
+{
+	struct task_struct *idle;
+
+	if ((idle = cpu_idle_tasks[cpu]) != NULL) {
+		/* initialize thread_struct.  we really want to avoid destroy
+		 * idle tread
+		 */
+		idle->thread.esp = (unsigned long)(((struct pt_regs *)
+			(THREAD_SIZE + (unsigned long) idle->thread_info)) - 1);
+		init_idle(idle, cpu);
+		return idle;
+	}
+	idle = fork_idle(cpu);
+
+	if (!IS_ERR(idle))
+		cpu_idle_tasks[cpu] = idle;
+	return idle;
+}
+#else
+#define alloc_idle_task(cpu) fork_idle(cpu)
+#endif
 
-static int __init do_boot_cpu(int apicid)
+static int __devinit do_boot_cpu(int apicid, int cpu)
 /*
  * NOTE - on most systems this is a PHYSICAL apic ID, but on multiquad
  * (ie clustered apic addressing mode), this is a LOGICAL apic ID.
@@ -757,16 +868,17 @@ static int __init do_boot_cpu(int apicid
 {
 	struct task_struct *idle;
 	unsigned long boot_error;
-	int timeout, cpu;
+	int timeout;
 	unsigned long start_eip;
 	unsigned short nmi_high = 0, nmi_low = 0;
 
-	cpu = ++cpucount;
+	++cpucount;
+
 	/*
 	 * We can't use kernel_thread since we must avoid to
 	 * reschedule the child.
 	 */
-	idle = fork_idle(cpu);
+	idle = alloc_idle_task(cpu);
 	if (IS_ERR(idle))
 		panic("failed fork for CPU %d", cpu);
 	idle->thread.eip = (unsigned long) start_secondary;
@@ -833,13 +945,16 @@ static int __init do_boot_cpu(int apicid
 			inquire_remote_apic(apicid);
 		}
 	}
-	x86_cpu_to_apicid[cpu] = apicid;
+
 	if (boot_error) {
 		/* Try to put things back the way they were before ... */
 		unmap_cpu_to_logical_apicid(cpu);
 		cpu_clear(cpu, cpu_callout_map); /* was set here (do_boot_cpu()) */
 		cpu_clear(cpu, cpu_initialized); /* was set by cpu_init() */
 		cpucount--;
+	} else {
+		x86_cpu_to_apicid[cpu] = apicid;
+		cpu_set(cpu, cpu_present_map);
 	}
 
 	/* mark "stuck" area as not stuck */
@@ -848,6 +963,75 @@ static int __init do_boot_cpu(int apicid
 	return boot_error;
 }
 
+#ifdef CONFIG_HOTPLUG_CPU
+void cpu_exit_clear(void)
+{
+	int cpu = raw_smp_processor_id();
+
+	idle_task_exit();
+
+	cpucount --;
+	cpu_uninit();
+	irq_ctx_exit(cpu);
+
+	cpu_clear(cpu, cpu_callout_map);
+	cpu_clear(cpu, cpu_callin_map);
+	cpu_clear(cpu, cpu_present_map);
+
+	cpu_clear(cpu, smp_commenced_mask);
+	unmap_cpu_to_logical_apicid(cpu);
+}
+
+struct warm_boot_cpu_info {
+	struct completion *complete;
+	int apicid;
+	int cpu;
+};
+
+static void __devinit do_warm_boot_cpu(void *p)
+{
+	struct warm_boot_cpu_info *info = p;
+	do_boot_cpu(info->apicid, info->cpu);
+	complete(info->complete);
+}
+
+int __devinit smp_prepare_cpu(int cpu)
+{
+	DECLARE_COMPLETION(done);
+	struct warm_boot_cpu_info info;
+	struct work_struct task;
+	int	apicid, ret;
+
+	lock_cpu_hotplug();
+	apicid = x86_cpu_to_apicid[cpu];
+	if (apicid == BAD_APICID) {
+		ret = -ENODEV;
+		goto exit;
+	}
+
+	info.complete = &done;
+	info.apicid = apicid;
+	info.cpu = cpu;
+	INIT_WORK(&task, do_warm_boot_cpu, &info);
+
+	tsc_sync_disabled = 1;
+
+	/* init low mem mapping */
+	memcpy(swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS,
+			sizeof(swapper_pg_dir[0]) * KERNEL_PGD_PTRS);
+	flush_tlb_all();
+	schedule_work(&task);
+	wait_for_completion(&done);
+
+	tsc_sync_disabled = 0;
+	zap_low_mappings();
+	ret = 0;
+exit:
+	unlock_cpu_hotplug();
+	return ret;
+}
+#endif
+
 static void smp_tune_scheduling (void)
 {
 	unsigned long cachesize;       /* kB   */
@@ -885,10 +1069,9 @@ static void smp_tune_scheduling (void)
 static int boot_cpu_logical_apicid;
 /* Where the IO area was mapped on multiquad, always 0 otherwise */
 void *xquad_portio;
-
-cpumask_t cpu_sibling_map[NR_CPUS] __cacheline_aligned;
-cpumask_t cpu_core_map[NR_CPUS] __cacheline_aligned;
-EXPORT_SYMBOL(cpu_core_map);
+#ifdef CONFIG_X86_NUMAQ
+EXPORT_SYMBOL(xquad_portio);
+#endif
 
 static void __init smp_boot_cpus(unsigned int max_cpus)
 {
@@ -1001,7 +1184,7 @@ static void __init smp_boot_cpus(unsigne
 		if (max_cpus <= cpucount+1)
 			continue;
 
-		if (do_boot_cpu(apicid))
+		if (((cpu = alloc_cpu_id()) <= 0) || do_boot_cpu(apicid, cpu))
 			printk("CPU #%d not responding - cannot use it.\n",
 								apicid);
 		else
@@ -1053,44 +1236,8 @@ static void __init smp_boot_cpus(unsigne
 		cpus_clear(cpu_core_map[cpu]);
 	}
 
-	for (cpu = 0; cpu < NR_CPUS; cpu++) {
-		struct cpuinfo_x86 *c = cpu_data + cpu;
-		int siblings = 0;
-		int i;
-		if (!cpu_isset(cpu, cpu_callout_map))
-			continue;
-
-		if (smp_num_siblings > 1) {
-			for (i = 0; i < NR_CPUS; i++) {
-				if (!cpu_isset(i, cpu_callout_map))
-					continue;
-				if (cpu_core_id[cpu] == cpu_core_id[i]) {
-					siblings++;
-					cpu_set(i, cpu_sibling_map[cpu]);
-				}
-			}
-		} else {
-			siblings++;
-			cpu_set(cpu, cpu_sibling_map[cpu]);
-		}
-
-		if (siblings != smp_num_siblings) {
-			printk(KERN_WARNING "WARNING: %d siblings found for CPU%d, should be %d\n", siblings, cpu, smp_num_siblings);
-			smp_num_siblings = siblings;
-		}
-
-		if (c->x86_num_cores > 1) {
-			for (i = 0; i < NR_CPUS; i++) {
-				if (!cpu_isset(i, cpu_callout_map))
-					continue;
-				if (phys_proc_id[cpu] == phys_proc_id[i]) {
-					cpu_set(i, cpu_core_map[cpu]);
-				}
-			}
-		} else {
-			cpu_core_map[cpu] = cpu_sibling_map[cpu];
-		}
-	}
+	cpu_set(0, cpu_sibling_map[0]);
+	cpu_set(0, cpu_core_map[0]);
 
 	smpboot_setup_io_apic();
 
@@ -1107,6 +1254,9 @@ static void __init smp_boot_cpus(unsigne
    who understands all this stuff should rewrite it properly. --RR 15/Jul/02 */
 void __init smp_prepare_cpus(unsigned int max_cpus)
 {
+	smp_commenced_mask = cpumask_of_cpu(0);
+	cpu_callin_map = cpumask_of_cpu(0);
+	mb();
 	smp_boot_cpus(max_cpus);
 }
 
@@ -1114,23 +1264,98 @@ void __devinit smp_prepare_boot_cpu(void
 {
 	cpu_set(smp_processor_id(), cpu_online_map);
 	cpu_set(smp_processor_id(), cpu_callout_map);
+	cpu_set(smp_processor_id(), cpu_present_map);
+	per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE;
 }
 
-int __devinit __cpu_up(unsigned int cpu)
+#ifdef CONFIG_HOTPLUG_CPU
+static void
+remove_siblinginfo(int cpu)
 {
-	/* This only works at boot for x86.  See "rewrite" above. */
-	if (cpu_isset(cpu, smp_commenced_mask)) {
-		local_irq_enable();
-		return -ENOSYS;
+	int sibling;
+
+	for_each_cpu_mask(sibling, cpu_sibling_map[cpu])
+		cpu_clear(cpu, cpu_sibling_map[sibling]);
+	for_each_cpu_mask(sibling, cpu_core_map[cpu])
+		cpu_clear(cpu, cpu_core_map[sibling]);
+	cpus_clear(cpu_sibling_map[cpu]);
+	cpus_clear(cpu_core_map[cpu]);
+	phys_proc_id[cpu] = BAD_APICID;
+	cpu_core_id[cpu] = BAD_APICID;
+}
+
+int __cpu_disable(void)
+{
+	cpumask_t map = cpu_online_map;
+	int cpu = smp_processor_id();
+
+	/*
+	 * Perhaps use cpufreq to drop frequency, but that could go
+	 * into generic code.
+ 	 *
+	 * We won't take down the boot processor on i386 due to some
+	 * interrupts only being able to be serviced by the BSP.
+	 * Especially so if we're not using an IOAPIC	-zwane
+	 */
+	if (cpu == 0)
+		return -EBUSY;
+
+	/* We enable the timer again on the exit path of the death loop */
+	disable_APIC_timer();
+	/* Allow any queued timer interrupts to get serviced */
+	local_irq_enable();
+	mdelay(1);
+	local_irq_disable();
+
+	remove_siblinginfo(cpu);
+
+	cpu_clear(cpu, map);
+	fixup_irqs(map);
+	/* It's now safe to remove this processor from the online map */
+	cpu_clear(cpu, cpu_online_map);
+	return 0;
+}
+
+void __cpu_die(unsigned int cpu)
+{
+	/* We don't do anything here: idle task is faking death itself. */
+	unsigned int i;
+
+	for (i = 0; i < 10; i++) {
+		/* They ack this in play_dead by setting CPU_DEAD */
+		if (per_cpu(cpu_state, cpu) == CPU_DEAD) {
+			printk ("CPU %d is now offline\n", cpu);
+			return;
+		}
+		current->state = TASK_UNINTERRUPTIBLE;
+		schedule_timeout(HZ/10);
 	}
+ 	printk(KERN_ERR "CPU %u didn't die...\n", cpu);
+}
+#else /* ... !CONFIG_HOTPLUG_CPU */
+int __cpu_disable(void)
+{
+	return -ENOSYS;
+}
+
+void __cpu_die(unsigned int cpu)
+{
+	/* We said "no" in __cpu_disable */
+	BUG();
+}
+#endif /* CONFIG_HOTPLUG_CPU */
 
+int __devinit __cpu_up(unsigned int cpu)
+{
 	/* In case one didn't come up */
 	if (!cpu_isset(cpu, cpu_callin_map)) {
+		printk(KERN_DEBUG "skipping cpu%d, didn't come online\n", cpu);
 		local_irq_enable();
 		return -EIO;
 	}
 
 	local_irq_enable();
+	per_cpu(cpu_state, cpu) = CPU_UP_PREPARE;
 	/* Unleash the CPU! */
 	cpu_set(cpu, smp_commenced_mask);
 	while (!cpu_isset(cpu, cpu_online_map))
@@ -1144,10 +1369,12 @@ void __init smp_cpus_done(unsigned int m
 	setup_ioapic_dest();
 #endif
 	zap_low_mappings();
+#ifndef CONFIG_HOTPLUG_CPU
 	/*
 	 * Disable executability of the SMP trampoline:
 	 */
 	set_kernel_exec((unsigned long)trampoline_base, trampoline_exec);
+#endif
 }
 
 void __init smp_intr_init(void)
diff --git a/arch/i386/kernel/syscall_table.S b/arch/i386/kernel/syscall_table.S
--- a/arch/i386/kernel/syscall_table.S
+++ b/arch/i386/kernel/syscall_table.S
@@ -283,9 +283,14 @@ ENTRY(sys_call_table)
 	.long sys_mq_timedreceive	/* 280 */
 	.long sys_mq_notify
 	.long sys_mq_getsetattr
-	.long sys_ni_syscall		/* reserved for kexec */
+	.long sys_kexec_load
 	.long sys_waitid
 	.long sys_ni_syscall		/* 285 */ /* available */
 	.long sys_add_key
 	.long sys_request_key
 	.long sys_keyctl
+	.long sys_ioprio_set
+	.long sys_ioprio_get		/* 290 */
+	.long sys_inotify_init
+	.long sys_inotify_add_watch
+	.long sys_inotify_rm_watch
diff --git a/arch/i386/kernel/sysenter.c b/arch/i386/kernel/sysenter.c
--- a/arch/i386/kernel/sysenter.c
+++ b/arch/i386/kernel/sysenter.c
@@ -21,11 +21,16 @@
 
 extern asmlinkage void sysenter_entry(void);
 
-void enable_sep_cpu(void *info)
+void enable_sep_cpu(void)
 {
 	int cpu = get_cpu();
 	struct tss_struct *tss = &per_cpu(init_tss, cpu);
 
+	if (!boot_cpu_has(X86_FEATURE_SEP)) {
+		put_cpu();
+		return;
+	}
+
 	tss->ss1 = __KERNEL_CS;
 	tss->esp1 = sizeof(struct tss_struct) + (unsigned long) tss;
 	wrmsr(MSR_IA32_SYSENTER_CS, __KERNEL_CS, 0);
@@ -41,7 +46,7 @@ void enable_sep_cpu(void *info)
 extern const char vsyscall_int80_start, vsyscall_int80_end;
 extern const char vsyscall_sysenter_start, vsyscall_sysenter_end;
 
-static int __init sysenter_setup(void)
+int __init sysenter_setup(void)
 {
 	void *page = (void *)get_zeroed_page(GFP_ATOMIC);
 
@@ -58,8 +63,5 @@ static int __init sysenter_setup(void)
 	       &vsyscall_sysenter_start,
 	       &vsyscall_sysenter_end - &vsyscall_sysenter_start);
 
-	on_each_cpu(enable_sep_cpu, NULL, 1, 1);
 	return 0;
 }
-
-__initcall(sysenter_setup);
diff --git a/arch/i386/kernel/time.c b/arch/i386/kernel/time.c
--- a/arch/i386/kernel/time.c
+++ b/arch/i386/kernel/time.c
@@ -68,7 +68,8 @@
 
 #include "io_ports.h"
 
-extern spinlock_t i8259A_lock;
+#include <asm/i8259.h>
+
 int pit_latch_buggy;              /* extern */
 
 #include "do_timer.h"
@@ -77,16 +78,20 @@ u64 jiffies_64 = INITIAL_JIFFIES;
 
 EXPORT_SYMBOL(jiffies_64);
 
-unsigned long cpu_khz;	/* Detected as we calibrate the TSC */
+unsigned int cpu_khz;	/* Detected as we calibrate the TSC */
+EXPORT_SYMBOL(cpu_khz);
 
 extern unsigned long wall_jiffies;
 
 DEFINE_SPINLOCK(rtc_lock);
+EXPORT_SYMBOL(rtc_lock);
+
+#include <asm/i8253.h>
 
 DEFINE_SPINLOCK(i8253_lock);
 EXPORT_SYMBOL(i8253_lock);
 
-struct timer_opts *cur_timer = &timer_none;
+struct timer_opts *cur_timer __read_mostly = &timer_none;
 
 /*
  * This is a special lock that is owned by the CPU and holds the index
@@ -324,6 +329,8 @@ unsigned long get_cmos_time(void)
 
 	return retval;
 }
+EXPORT_SYMBOL(get_cmos_time);
+
 static void sync_cmos_clock(unsigned long dummy);
 
 static struct timer_list sync_cmos_timer =
diff --git a/arch/i386/kernel/time_hpet.c b/arch/i386/kernel/time_hpet.c
--- a/arch/i386/kernel/time_hpet.c
+++ b/arch/i386/kernel/time_hpet.c
@@ -50,7 +50,7 @@ static void hpet_writel(unsigned long d,
  * comparator value and continue. Next tick can be caught by checking
  * for a change in the comparator value. Used in apic.c.
  */
-static void __init wait_hpet_tick(void)
+static void __devinit wait_hpet_tick(void)
 {
 	unsigned int start_cmp_val, end_cmp_val;
 
diff --git a/arch/i386/kernel/timers/common.c b/arch/i386/kernel/timers/common.c
--- a/arch/i386/kernel/timers/common.c
+++ b/arch/i386/kernel/timers/common.c
@@ -86,7 +86,7 @@ bad_ctc:
 #define CALIBRATE_CNT_HPET 	(5 * hpet_tick)
 #define CALIBRATE_TIME_HPET 	(5 * KERNEL_TICK_USEC)
 
-unsigned long __init calibrate_tsc_hpet(unsigned long *tsc_hpet_quotient_ptr)
+unsigned long __devinit calibrate_tsc_hpet(unsigned long *tsc_hpet_quotient_ptr)
 {
 	unsigned long tsc_startlow, tsc_starthigh;
 	unsigned long tsc_endlow, tsc_endhigh;
@@ -139,6 +139,15 @@ bad_calibration:
 }
 #endif
 
+
+unsigned long read_timer_tsc(void)
+{
+	unsigned long retval;
+	rdtscl(retval);
+	return retval;
+}
+
+
 /* calculate cpu_khz */
 void init_cpu_khz(void)
 {
@@ -154,7 +163,8 @@ void init_cpu_khz(void)
 		       		:"=a" (cpu_khz), "=d" (edx)
         	       		:"r" (tsc_quotient),
 	                	"0" (eax), "1" (edx));
-				printk("Detected %lu.%03lu MHz processor.\n", cpu_khz / 1000, cpu_khz % 1000);
+				printk("Detected %u.%03u MHz processor.\n",
+					cpu_khz / 1000, cpu_khz % 1000);
 			}
 		}
 	}
diff --git a/arch/i386/kernel/timers/timer.c b/arch/i386/kernel/timers/timer.c
--- a/arch/i386/kernel/timers/timer.c
+++ b/arch/i386/kernel/timers/timer.c
@@ -64,3 +64,12 @@ struct timer_opts* __init select_timer(v
 	panic("select_timer: Cannot find a suitable timer\n");
 	return NULL;
 }
+
+int read_current_timer(unsigned long *timer_val)
+{
+	if (cur_timer->read_timer) {
+		*timer_val = cur_timer->read_timer();
+		return 0;
+	}
+	return -1;
+}
diff --git a/arch/i386/kernel/timers/timer_cyclone.c b/arch/i386/kernel/timers/timer_cyclone.c
--- a/arch/i386/kernel/timers/timer_cyclone.c
+++ b/arch/i386/kernel/timers/timer_cyclone.c
@@ -17,9 +17,9 @@
 #include <asm/io.h>
 #include <asm/pgtable.h>
 #include <asm/fixmap.h>
-#include "io_ports.h"
+#include <asm/i8253.h>
 
-extern spinlock_t i8253_lock;
+#include "io_ports.h"
 
 /* Number of usecs that the last interrupt was delayed */
 static int delay_at_last_interrupt;
diff --git a/arch/i386/kernel/timers/timer_hpet.c b/arch/i386/kernel/timers/timer_hpet.c
--- a/arch/i386/kernel/timers/timer_hpet.c
+++ b/arch/i386/kernel/timers/timer_hpet.c
@@ -18,7 +18,7 @@
 #include "mach_timer.h"
 #include <asm/hpet.h>
 
-static unsigned long hpet_usec_quotient;	/* convert hpet clks to usec */
+static unsigned long __read_mostly hpet_usec_quotient;	/* convert hpet clks to usec */
 static unsigned long tsc_hpet_quotient;		/* convert tsc to hpet clks */
 static unsigned long hpet_last; 	/* hpet counter value at last tick*/
 static unsigned long last_tsc_low;	/* lsb 32 bits of Time Stamp Counter */
@@ -158,7 +158,7 @@ static int __init init_hpet(char* overri
 			{	unsigned long eax=0, edx=1000;
 				ASM_DIV64_REG(cpu_khz, edx, tsc_quotient,
 						eax, edx);
-				printk("Detected %lu.%03lu MHz processor.\n",
+				printk("Detected %u.%03u MHz processor.\n",
 					cpu_khz / 1000, cpu_khz % 1000);
 			}
 			set_cyc2ns_scale(cpu_khz/1000);
@@ -180,12 +180,13 @@ static int __init init_hpet(char* overri
 /************************************************************/
 
 /* tsc timer_opts struct */
-static struct timer_opts timer_hpet = {
+static struct timer_opts timer_hpet __read_mostly = {
 	.name = 		"hpet",
 	.mark_offset =		mark_offset_hpet,
 	.get_offset =		get_offset_hpet,
 	.monotonic_clock =	monotonic_clock_hpet,
 	.delay = 		delay_hpet,
+	.read_timer = 		read_timer_tsc,
 };
 
 struct init_timer_opts __initdata timer_hpet_init = {
diff --git a/arch/i386/kernel/timers/timer_pit.c b/arch/i386/kernel/timers/timer_pit.c
--- a/arch/i386/kernel/timers/timer_pit.c
+++ b/arch/i386/kernel/timers/timer_pit.c
@@ -15,9 +15,8 @@
 #include <asm/smp.h>
 #include <asm/io.h>
 #include <asm/arch_hooks.h>
+#include <asm/i8253.h>
 
-extern spinlock_t i8259A_lock;
-extern spinlock_t i8253_lock;
 #include "do_timer.h"
 #include "io_ports.h"
 
@@ -166,7 +165,6 @@ struct init_timer_opts __initdata timer_
 
 void setup_pit_timer(void)
 {
-	extern spinlock_t i8253_lock;
 	unsigned long flags;
 
 	spin_lock_irqsave(&i8253_lock, flags);
diff --git a/arch/i386/kernel/timers/timer_pm.c b/arch/i386/kernel/timers/timer_pm.c
--- a/arch/i386/kernel/timers/timer_pm.c
+++ b/arch/i386/kernel/timers/timer_pm.c
@@ -246,6 +246,7 @@ static struct timer_opts timer_pmtmr = {
 	.get_offset		= get_offset_pmtmr,
 	.monotonic_clock 	= monotonic_clock_pmtmr,
 	.delay 			= delay_pmtmr,
+	.read_timer 		= read_timer_tsc,
 };
 
 struct init_timer_opts __initdata timer_pmtmr_init = {
diff --git a/arch/i386/kernel/timers/timer_tsc.c b/arch/i386/kernel/timers/timer_tsc.c
--- a/arch/i386/kernel/timers/timer_tsc.c
+++ b/arch/i386/kernel/timers/timer_tsc.c
@@ -24,6 +24,7 @@
 #include "mach_timer.h"
 
 #include <asm/hpet.h>
+#include <asm/i8253.h>
 
 #ifdef CONFIG_HPET_TIMER
 static unsigned long hpet_usec_quotient;
@@ -33,9 +34,7 @@ static struct timer_opts timer_tsc;
 
 static inline void cpufreq_delayed_get(void);
 
-int tsc_disable __initdata = 0;
-
-extern spinlock_t i8253_lock;
+int tsc_disable __devinitdata = 0;
 
 static int use_tsc;
 /* Number of usecs that the last interrupt was delayed */
@@ -256,7 +255,7 @@ static unsigned long loops_per_jiffy_ref
 
 #ifndef CONFIG_SMP
 static unsigned long fast_gettimeoffset_ref = 0;
-static unsigned long cpu_khz_ref = 0;
+static unsigned int cpu_khz_ref = 0;
 #endif
 
 static int
@@ -323,7 +322,7 @@ static inline void cpufreq_delayed_get(v
 int recalibrate_cpu_khz(void)
 {
 #ifndef CONFIG_SMP
-	unsigned long cpu_khz_old = cpu_khz;
+	unsigned int cpu_khz_old = cpu_khz;
 
 	if (cpu_has_tsc) {
 		init_cpu_khz();
@@ -534,7 +533,8 @@ static int __init init_tsc(char* overrid
 		       		:"=a" (cpu_khz), "=d" (edx)
         	       		:"r" (tsc_quotient),
 	                	"0" (eax), "1" (edx));
-				printk("Detected %lu.%03lu MHz processor.\n", cpu_khz / 1000, cpu_khz % 1000);
+				printk("Detected %u.%03u MHz processor.\n",
+					cpu_khz / 1000, cpu_khz % 1000);
 			}
 			set_cyc2ns_scale(cpu_khz/1000);
 			return 0;
@@ -572,6 +572,7 @@ static struct timer_opts timer_tsc = {
 	.get_offset = get_offset_tsc,
 	.monotonic_clock = monotonic_clock_tsc,
 	.delay = delay_tsc,
+	.read_timer = read_timer_tsc,
 };
 
 struct init_timer_opts __initdata timer_tsc_init = {
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c
--- a/arch/i386/kernel/traps.c
+++ b/arch/i386/kernel/traps.c
@@ -27,6 +27,7 @@
 #include <linux/ptrace.h>
 #include <linux/utsname.h>
 #include <linux/kprobes.h>
+#include <linux/kexec.h>
 
 #ifdef CONFIG_EISA
 #include <linux/ioport.h>
@@ -104,6 +105,7 @@ int register_die_notifier(struct notifie
 	spin_unlock_irqrestore(&die_notifier_lock, flags);
 	return err;
 }
+EXPORT_SYMBOL(register_die_notifier);
 
 static inline int valid_stack_ptr(struct thread_info *tinfo, void *p)
 {
@@ -209,7 +211,7 @@ void show_registers(struct pt_regs *regs
 
 	esp = (unsigned long) (&regs->esp);
 	ss = __KERNEL_DS;
-	if (regs->xcs & 3) {
+	if (user_mode(regs)) {
 		in_kernel = 0;
 		esp = regs->esp;
 		ss = regs->xss & 0xffff;
@@ -233,22 +235,22 @@ void show_registers(struct pt_regs *regs
 	 * time of the fault..
 	 */
 	if (in_kernel) {
-		u8 *eip;
+		u8 __user *eip;
 
 		printk("\nStack: ");
 		show_stack(NULL, (unsigned long*)esp);
 
 		printk("Code: ");
 
-		eip = (u8 *)regs->eip - 43;
+		eip = (u8 __user *)regs->eip - 43;
 		for (i = 0; i < 64; i++, eip++) {
 			unsigned char c;
 
-			if (eip < (u8 *)PAGE_OFFSET || __get_user(c, eip)) {
+			if (eip < (u8 __user *)PAGE_OFFSET || __get_user(c, eip)) {
 				printk(" Bad EIP value.");
 				break;
 			}
-			if (eip == (u8 *)regs->eip)
+			if (eip == (u8 __user *)regs->eip)
 				printk("<%02x> ", c);
 			else
 				printk("%02x ", c);
@@ -265,20 +267,20 @@ static void handle_BUG(struct pt_regs *r
 	char c;
 	unsigned long eip;
 
-	if (regs->xcs & 3)
+	if (user_mode(regs))
 		goto no_bug;		/* Not in kernel */
 
 	eip = regs->eip;
 
 	if (eip < PAGE_OFFSET)
 		goto no_bug;
-	if (__get_user(ud2, (unsigned short *)eip))
+	if (__get_user(ud2, (unsigned short __user *)eip))
 		goto no_bug;
 	if (ud2 != 0x0b0f)
 		goto no_bug;
-	if (__get_user(line, (unsigned short *)(eip + 2)))
+	if (__get_user(line, (unsigned short __user *)(eip + 2)))
 		goto bug;
-	if (__get_user(file, (char **)(eip + 4)) ||
+	if (__get_user(file, (char * __user *)(eip + 4)) ||
 		(unsigned long)file < PAGE_OFFSET || __get_user(c, file))
 		file = "<bad filename>";
 
@@ -293,6 +295,9 @@ bug:
 	printk("Kernel BUG\n");
 }
 
+/* This is gone through when something in the kernel
+ * has done something bad and is about to be terminated.
+*/
 void die(const char * str, struct pt_regs * regs, long err)
 {
 	static struct {
@@ -306,7 +311,7 @@ void die(const char * str, struct pt_reg
 	};
 	static int die_counter;
 
-	if (die.lock_owner != _smp_processor_id()) {
+	if (die.lock_owner != raw_smp_processor_id()) {
 		console_verbose();
 		spin_lock_irq(&die.lock);
 		die.lock_owner = smp_processor_id();
@@ -340,6 +345,10 @@ void die(const char * str, struct pt_reg
 	bust_spinlocks(0);
 	die.lock_owner = -1;
 	spin_unlock_irq(&die.lock);
+
+	if (kexec_should_crash(current))
+		crash_kexec(regs);
+
 	if (in_interrupt())
 		panic("Fatal exception in interrupt");
 
@@ -353,26 +362,27 @@ void die(const char * str, struct pt_reg
 
 static inline void die_if_kernel(const char * str, struct pt_regs * regs, long err)
 {
-	if (!(regs->eflags & VM_MASK) && !(3 & regs->xcs))
+	if (!user_mode_vm(regs))
 		die(str, regs, err);
 }
 
 static void do_trap(int trapnr, int signr, char *str, int vm86,
 			   struct pt_regs * regs, long error_code, siginfo_t *info)
 {
+	struct task_struct *tsk = current;
+	tsk->thread.error_code = error_code;
+	tsk->thread.trap_no = trapnr;
+
 	if (regs->eflags & VM_MASK) {
 		if (vm86)
 			goto vm86_trap;
 		goto trap_signal;
 	}
 
-	if (!(regs->xcs & 3))
+	if (!user_mode(regs))
 		goto kernel_trap;
 
 	trap_signal: {
-		struct task_struct *tsk = current;
-		tsk->thread.error_code = error_code;
-		tsk->thread.trap_no = trapnr;
 		if (info)
 			force_sig_info(signr, info, tsk);
 		else
@@ -485,10 +495,13 @@ fastcall void do_general_protection(stru
 	}
 	put_cpu();
 
+	current->thread.error_code = error_code;
+	current->thread.trap_no = 13;
+
 	if (regs->eflags & VM_MASK)
 		goto gp_in_vm86;
 
-	if (!(regs->xcs & 3))
+	if (!user_mode(regs))
 		goto gp_in_kernel;
 
 	current->thread.error_code = error_code;
@@ -569,6 +582,15 @@ void die_nmi (struct pt_regs *regs, cons
 	console_silent();
 	spin_unlock(&nmi_print_lock);
 	bust_spinlocks(0);
+
+	/* If we are in kernel we are probably nested up pretty bad
+	 * and might aswell get out now while we still can.
+	*/
+	if (!user_mode(regs)) {
+		current->thread.trap_no = 2;
+		crash_kexec(regs);
+	}
+
 	do_exit(SIGSEGV);
 }
 
@@ -624,6 +646,14 @@ fastcall void do_nmi(struct pt_regs * re
 	nmi_enter();
 
 	cpu = smp_processor_id();
+
+#ifdef CONFIG_HOTPLUG_CPU
+	if (!cpu_online(cpu)) {
+		nmi_exit();
+		return;
+	}
+#endif
+
 	++nmi_count(cpu);
 
 	if (!nmi_callback(regs, cpu))
@@ -636,11 +666,13 @@ void set_nmi_callback(nmi_callback_t cal
 {
 	nmi_callback = callback;
 }
+EXPORT_SYMBOL_GPL(set_nmi_callback);
 
 void unset_nmi_callback(void)
 {
 	nmi_callback = dummy_nmi_callback;
 }
+EXPORT_SYMBOL_GPL(unset_nmi_callback);
 
 #ifdef CONFIG_KPROBES
 fastcall void do_int3(struct pt_regs *regs, long error_code)
@@ -682,7 +714,7 @@ fastcall void do_debug(struct pt_regs * 
 	unsigned int condition;
 	struct task_struct *tsk = current;
 
-	__asm__ __volatile__("movl %%db6,%0" : "=r" (condition));
+	get_debugreg(condition, 6);
 
 	if (notify_die(DIE_DEBUG, "debug", regs, condition, error_code,
 					SIGTRAP) == NOTIFY_STOP)
@@ -713,7 +745,7 @@ fastcall void do_debug(struct pt_regs * 
 		 * check for kernel mode by just checking the CPL
 		 * of CS.
 		 */
-		if ((regs->xcs & 3) == 0)
+		if (!user_mode(regs))
 			goto clear_TF_reenable;
 	}
 
@@ -724,9 +756,7 @@ fastcall void do_debug(struct pt_regs * 
 	 * the signal is delivered.
 	 */
 clear_dr7:
-	__asm__("movl %0,%%db7"
-		: /* no output */
-		: "r" (0));
+	set_debugreg(0, 7);
 	return;
 
 debug_vm86:
@@ -773,15 +803,17 @@ void math_error(void __user *eip)
 	 */
 	cwd = get_fpu_cwd(task);
 	swd = get_fpu_swd(task);
-	switch (((~cwd) & swd & 0x3f) | (swd & 0x240)) {
+	switch (swd & ~cwd & 0x3f) {
 		case 0x000:
 		default:
 			break;
 		case 0x001: /* Invalid Op */
-		case 0x041: /* Stack Fault */
-		case 0x241: /* Stack Fault | Direction */
+			/*
+			 * swd & 0x240 == 0x040: Stack Underflow
+			 * swd & 0x240 == 0x240: Stack Overflow
+			 * User must clear the SF bit (0x40) if set
+			 */
 			info.si_code = FPE_FLTINV;
-			/* Should we clear the SF or let user space do it ???? */
 			break;
 		case 0x002: /* Denormalize */
 		case 0x010: /* Underflow */
@@ -871,9 +903,9 @@ fastcall void do_simd_coprocessor_error(
 					  error_code);
 			return;
 		}
-		die_if_kernel("cache flush denied", regs, error_code);
 		current->thread.trap_no = 19;
 		current->thread.error_code = error_code;
+		die_if_kernel("cache flush denied", regs, error_code);
 		force_sig(SIGSEGV, current);
 	}
 }
diff --git a/arch/i386/kernel/vmlinux.lds.S b/arch/i386/kernel/vmlinux.lds.S
--- a/arch/i386/kernel/vmlinux.lds.S
+++ b/arch/i386/kernel/vmlinux.lds.S
@@ -2,20 +2,23 @@
  * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>;
  */
 
+#define LOAD_OFFSET __PAGE_OFFSET
+
 #include <asm-generic/vmlinux.lds.h>
 #include <asm/thread_info.h>
 #include <asm/page.h>
 
 OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
 OUTPUT_ARCH(i386)
-ENTRY(startup_32)
+ENTRY(phys_startup_32)
 jiffies = jiffies_64;
 SECTIONS
 {
-  . = __PAGE_OFFSET + 0x100000;
+  . = __KERNEL_START;
+  phys_startup_32 = startup_32 - LOAD_OFFSET;
   /* read-only */
   _text = .;			/* Text and read-only data */
-  .text : {
+  .text : AT(ADDR(.text) - LOAD_OFFSET) {
 	*(.text)
 	SCHED_TEXT
 	LOCK_TEXT
@@ -27,49 +30,58 @@ SECTIONS
 
   . = ALIGN(16);		/* Exception table */
   __start___ex_table = .;
-  __ex_table : { *(__ex_table) }
+  __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { *(__ex_table) }
   __stop___ex_table = .;
 
   RODATA
 
   /* writeable */
-  .data : {			/* Data */
+  .data : AT(ADDR(.data) - LOAD_OFFSET) {	/* Data */
 	*(.data)
 	CONSTRUCTORS
 	}
 
   . = ALIGN(4096);
   __nosave_begin = .;
-  .data_nosave : { *(.data.nosave) }
+  .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { *(.data.nosave) }
   . = ALIGN(4096);
   __nosave_end = .;
 
   . = ALIGN(4096);
-  .data.page_aligned : { *(.data.idt) }
+  .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
+	*(.data.idt)
+  }
 
   . = ALIGN(32);
-  .data.cacheline_aligned : { *(.data.cacheline_aligned) }
+  .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
+	*(.data.cacheline_aligned)
+  }
 
+  /* rarely changed data like cpu maps */
+  . = ALIGN(32);
+  .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) { *(.data.read_mostly) }
   _edata = .;			/* End of data section */
 
   . = ALIGN(THREAD_SIZE);	/* init_task */
-  .data.init_task : { *(.data.init_task) }
+  .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
+	*(.data.init_task)
+  }
 
   /* will be freed after init */
   . = ALIGN(4096);		/* Init code and data */
   __init_begin = .;
-  .init.text : { 
+  .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {
 	_sinittext = .;
 	*(.init.text)
 	_einittext = .;
   }
-  .init.data : { *(.init.data) }
+  .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) { *(.init.data) }
   . = ALIGN(16);
   __setup_start = .;
-  .init.setup : { *(.init.setup) }
+  .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) { *(.init.setup) }
   __setup_end = .;
   __initcall_start = .;
-  .initcall.init : {
+  .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) {
 	*(.initcall1.init) 
 	*(.initcall2.init) 
 	*(.initcall3.init) 
@@ -80,33 +92,41 @@ SECTIONS
   }
   __initcall_end = .;
   __con_initcall_start = .;
-  .con_initcall.init : { *(.con_initcall.init) }
+  .con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET) {
+	*(.con_initcall.init)
+  }
   __con_initcall_end = .;
   SECURITY_INIT
   . = ALIGN(4);
   __alt_instructions = .;
-  .altinstructions : { *(.altinstructions) } 
+  .altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) {
+	*(.altinstructions)
+  }
   __alt_instructions_end = .; 
- .altinstr_replacement : { *(.altinstr_replacement) } 
+  .altinstr_replacement : AT(ADDR(.altinstr_replacement) - LOAD_OFFSET) {
+	*(.altinstr_replacement)
+  }
   /* .exit.text is discard at runtime, not link time, to deal with references
      from .altinstructions and .eh_frame */
-  .exit.text : { *(.exit.text) }
-  .exit.data : { *(.exit.data) }
+  .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) { *(.exit.text) }
+  .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) { *(.exit.data) }
   . = ALIGN(4096);
   __initramfs_start = .;
-  .init.ramfs : { *(.init.ramfs) }
+  .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) { *(.init.ramfs) }
   __initramfs_end = .;
   . = ALIGN(32);
   __per_cpu_start = .;
-  .data.percpu  : { *(.data.percpu) }
+  .data.percpu  : AT(ADDR(.data.percpu) - LOAD_OFFSET) { *(.data.percpu) }
   __per_cpu_end = .;
   . = ALIGN(4096);
   __init_end = .;
   /* freed after init ends here */
 	
   __bss_start = .;		/* BSS */
-  .bss : {
+  .bss.page_aligned : AT(ADDR(.bss.page_aligned) - LOAD_OFFSET) {
 	*(.bss.page_aligned)
+  }
+  .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
 	*(.bss)
   }
   . = ALIGN(4);
diff --git a/arch/i386/lib/dec_and_lock.c b/arch/i386/lib/dec_and_lock.c
--- a/arch/i386/lib/dec_and_lock.c
+++ b/arch/i386/lib/dec_and_lock.c
@@ -8,6 +8,7 @@
  */
 
 #include <linux/spinlock.h>
+#include <linux/module.h>
 #include <asm/atomic.h>
 
 int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock)
@@ -38,3 +39,4 @@ slow_path:
 	spin_unlock(lock);
 	return 0;
 }
+EXPORT_SYMBOL(_atomic_dec_and_lock);
diff --git a/arch/i386/lib/delay.c b/arch/i386/lib/delay.c
--- a/arch/i386/lib/delay.c
+++ b/arch/i386/lib/delay.c
@@ -13,6 +13,7 @@
 #include <linux/config.h>
 #include <linux/sched.h>
 #include <linux/delay.h>
+#include <linux/module.h>
 #include <asm/processor.h>
 #include <asm/delay.h>
 #include <asm/timer.h>
@@ -34,7 +35,7 @@ inline void __const_udelay(unsigned long
 	xloops *= 4;
 	__asm__("mull %0"
 		:"=d" (xloops), "=&a" (d0)
-		:"1" (xloops),"0" (cpu_data[_smp_processor_id()].loops_per_jiffy * (HZ/4)));
+		:"1" (xloops),"0" (cpu_data[raw_smp_processor_id()].loops_per_jiffy * (HZ/4)));
         __delay(++xloops);
 }
 
@@ -47,3 +48,8 @@ void __ndelay(unsigned long nsecs)
 {
 	__const_udelay(nsecs * 0x00005);  /* 2**32 / 1000000000 (rounded up) */
 }
+
+EXPORT_SYMBOL(__delay);
+EXPORT_SYMBOL(__const_udelay);
+EXPORT_SYMBOL(__udelay);
+EXPORT_SYMBOL(__ndelay);
diff --git a/arch/i386/lib/mmx.c b/arch/i386/lib/mmx.c
--- a/arch/i386/lib/mmx.c
+++ b/arch/i386/lib/mmx.c
@@ -3,6 +3,7 @@
 #include <linux/string.h>
 #include <linux/sched.h>
 #include <linux/hardirq.h>
+#include <linux/module.h>
 
 #include <asm/i387.h>
 
@@ -397,3 +398,7 @@ void mmx_copy_page(void *to, void *from)
 	else
 		fast_copy_page(to, from);
 }
+
+EXPORT_SYMBOL(_mmx_memcpy);
+EXPORT_SYMBOL(mmx_clear_page);
+EXPORT_SYMBOL(mmx_copy_page);
diff --git a/arch/i386/lib/usercopy.c b/arch/i386/lib/usercopy.c
--- a/arch/i386/lib/usercopy.c
+++ b/arch/i386/lib/usercopy.c
@@ -84,6 +84,7 @@ __strncpy_from_user(char *dst, const cha
 	__do_strncpy_from_user(dst, src, count, res);
 	return res;
 }
+EXPORT_SYMBOL(__strncpy_from_user);
 
 /**
  * strncpy_from_user: - Copy a NUL terminated string from userspace.
@@ -111,7 +112,7 @@ strncpy_from_user(char *dst, const char 
 		__do_strncpy_from_user(dst, src, count, res);
 	return res;
 }
-
+EXPORT_SYMBOL(strncpy_from_user);
 
 /*
  * Zero Userspace
@@ -157,6 +158,7 @@ clear_user(void __user *to, unsigned lon
 		__do_clear_user(to, n);
 	return n;
 }
+EXPORT_SYMBOL(clear_user);
 
 /**
  * __clear_user: - Zero a block of memory in user space, with less checking.
@@ -175,6 +177,7 @@ __clear_user(void __user *to, unsigned l
 	__do_clear_user(to, n);
 	return n;
 }
+EXPORT_SYMBOL(__clear_user);
 
 /**
  * strlen_user: - Get the size of a string in user space.
@@ -218,6 +221,7 @@ long strnlen_user(const char __user *s, 
 		:"cc");
 	return res & mask;
 }
+EXPORT_SYMBOL(strnlen_user);
 
 #ifdef CONFIG_X86_INTEL_USERCOPY
 static unsigned long
@@ -570,6 +574,7 @@ survive:
 		n = __copy_user_intel(to, from, n);
 	return n;
 }
+EXPORT_SYMBOL(__copy_to_user_ll);
 
 unsigned long
 __copy_from_user_ll(void *to, const void __user *from, unsigned long n)
@@ -581,6 +586,7 @@ __copy_from_user_ll(void *to, const void
 		n = __copy_user_zeroing_intel(to, from, n);
 	return n;
 }
+EXPORT_SYMBOL(__copy_from_user_ll);
 
 /**
  * copy_to_user: - Copy a block of data into user space.
diff --git a/arch/i386/mach-default/setup.c b/arch/i386/mach-default/setup.c
--- a/arch/i386/mach-default/setup.c
+++ b/arch/i386/mach-default/setup.c
@@ -10,6 +10,14 @@
 #include <asm/acpi.h>
 #include <asm/arch_hooks.h>
 
+#ifdef CONFIG_HOTPLUG_CPU
+#define DEFAULT_SEND_IPI	(1)
+#else
+#define DEFAULT_SEND_IPI	(0)
+#endif
+
+int no_broadcast=DEFAULT_SEND_IPI;
+
 /**
  * pre_intr_init_hook - initialisation prior to setting up interrupt vectors
  *
@@ -104,3 +112,22 @@ void __init mca_nmi_hook(void)
 	printk("NMI generated from unknown source!\n");
 }
 #endif
+
+static __init int no_ipi_broadcast(char *str)
+{
+	get_option(&str, &no_broadcast);
+	printk ("Using %s mode\n", no_broadcast ? "No IPI Broadcast" :
+											"IPI Broadcast");
+	return 1;
+}
+
+__setup("no_ipi_broadcast", no_ipi_broadcast);
+
+static int __init print_ipi_mode(void)
+{
+	printk ("Using IPI %s mode\n", no_broadcast ? "No-Shortcut" :
+											"Shortcut");
+	return 0;
+}
+
+late_initcall(print_ipi_mode);
diff --git a/arch/i386/mach-default/topology.c b/arch/i386/mach-default/topology.c
--- a/arch/i386/mach-default/topology.c
+++ b/arch/i386/mach-default/topology.c
@@ -73,12 +73,11 @@ static int __init topology_init(void)
 {
 	int i;
 
-	for (i = 0; i < MAX_NUMNODES; i++) {
-		if (node_online(i))
-			arch_register_node(i);
-	}
-	for (i = 0; i < NR_CPUS; i++)
-		if (cpu_possible(i)) arch_register_cpu(i);
+	for_each_online_node(i)
+		arch_register_node(i);
+
+	for_each_cpu(i)
+		arch_register_cpu(i);
 	return 0;
 }
 
@@ -88,8 +87,8 @@ static int __init topology_init(void)
 {
 	int i;
 
-	for (i = 0; i < NR_CPUS; i++)
-		if (cpu_possible(i)) arch_register_cpu(i);
+	for_each_cpu(i)
+		arch_register_cpu(i);
 	return 0;
 }
 
diff --git a/arch/i386/mach-visws/mpparse.c b/arch/i386/mach-visws/mpparse.c
--- a/arch/i386/mach-visws/mpparse.c
+++ b/arch/i386/mach-visws/mpparse.c
@@ -23,7 +23,6 @@ unsigned long mp_lapic_addr;
 
 /* Processor that is doing the boot up */
 unsigned int boot_cpu_physical_apicid = -1U;
-unsigned int boot_cpu_logical_apicid = -1U;
 
 /* Bitmask of physically existing CPUs */
 physid_mask_t phys_cpu_present_map;
@@ -52,10 +51,8 @@ static void __init MP_processor_info (st
 		(m->mpc_cpufeature & CPU_MODEL_MASK) >> 4,
 		m->mpc_apicver);
 
-	if (m->mpc_cpuflag & CPU_BOOTPROCESSOR) {
+	if (m->mpc_cpuflag & CPU_BOOTPROCESSOR)
 		boot_cpu_physical_apicid = m->mpc_apicid;
-		boot_cpu_logical_apicid = logical_apicid;
-	}
 
 	ver = m->mpc_apicver;
 	if ((ver >= 0x14 && m->mpc_apicid >= 0xff) || m->mpc_apicid >= 0xf) {
diff --git a/arch/i386/mach-visws/reboot.c b/arch/i386/mach-visws/reboot.c
--- a/arch/i386/mach-visws/reboot.c
+++ b/arch/i386/mach-visws/reboot.c
@@ -7,13 +7,17 @@
 #include "piix4.h"
 
 void (*pm_power_off)(void);
+EXPORT_SYMBOL(pm_power_off);
 
-void machine_restart(char * __unused)
+void machine_shutdown(void)
 {
 #ifdef CONFIG_SMP
 	smp_send_stop();
 #endif
+}
 
+void machine_emergency_restart(void)
+{
 	/*
 	 * Visual Workstations restart after this
 	 * register is poked on the PIIX4
@@ -21,7 +25,11 @@ void machine_restart(char * __unused)
 	outb(PIIX4_RESET_VAL, PIIX4_RESET_PORT);
 }
 
-EXPORT_SYMBOL(machine_restart);
+void machine_restart(char * __unused)
+{
+	machine_shutdown();
+	machine_emergency_restart();
+}
 
 void machine_power_off(void)
 {
@@ -42,10 +50,7 @@ void machine_power_off(void)
 	outl(PIIX_SPECIAL_STOP, 0xCFC);
 }
 
-EXPORT_SYMBOL(machine_power_off);
-
 void machine_halt(void)
 {
 }
 
-EXPORT_SYMBOL(machine_halt);
diff --git a/arch/i386/mach-visws/setup.c b/arch/i386/mach-visws/setup.c
--- a/arch/i386/mach-visws/setup.c
+++ b/arch/i386/mach-visws/setup.c
@@ -14,6 +14,8 @@
 #include "cobalt.h"
 #include "piix4.h"
 
+int no_broadcast;
+
 char visws_board_type = -1;
 char visws_board_rev = -1;
 
diff --git a/arch/i386/mach-voyager/voyager_basic.c b/arch/i386/mach-voyager/voyager_basic.c
--- a/arch/i386/mach-voyager/voyager_basic.c
+++ b/arch/i386/mach-voyager/voyager_basic.c
@@ -30,11 +30,13 @@
 #include <linux/irq.h>
 #include <asm/tlbflush.h>
 #include <asm/arch_hooks.h>
+#include <asm/i8253.h>
 
 /*
  * Power off function, if any
  */
 void (*pm_power_off)(void);
+EXPORT_SYMBOL(pm_power_off);
 
 int voyager_level = 0;
 
@@ -182,7 +184,6 @@ voyager_timer_interrupt(struct pt_regs *
 		 * and swiftly introduce it to something sharp and
 		 * pointy.  */
 		__u16 val;
-		extern spinlock_t i8253_lock;
 
 		spin_lock(&i8253_lock);
 		
@@ -251,6 +252,12 @@ kb_wait(void)
 }
 
 void
+machine_shutdown(void)
+{
+	/* Architecture specific shutdown needed before a kexec */
+}
+
+void
 machine_restart(char *cmd)
 {
 	printk("Voyager Warm Restart\n");
@@ -277,7 +284,12 @@ machine_restart(char *cmd)
 	}
 }
 
-EXPORT_SYMBOL(machine_restart);
+void
+machine_emergency_restart(void)
+{
+	/*for now, just hook this to a warm restart */
+	machine_restart(NULL);
+}
 
 void
 mca_nmi_hook(void)
@@ -314,12 +326,9 @@ machine_halt(void)
 	machine_power_off();
 }
 
-EXPORT_SYMBOL(machine_halt);
-
 void machine_power_off(void)
 {
 	if (pm_power_off)
 		pm_power_off();
 }
 
-EXPORT_SYMBOL(machine_power_off);
diff --git a/arch/i386/mach-voyager/voyager_smp.c b/arch/i386/mach-voyager/voyager_smp.c
--- a/arch/i386/mach-voyager/voyager_smp.c
+++ b/arch/i386/mach-voyager/voyager_smp.c
@@ -10,6 +10,7 @@
  * the voyager hal to provide the functionality
  */
 #include <linux/config.h>
+#include <linux/module.h>
 #include <linux/mm.h>
 #include <linux/kernel_stat.h>
 #include <linux/delay.h>
@@ -40,6 +41,7 @@ static unsigned long cpu_irq_affinity[NR
 /* per CPU data structure (for /proc/cpuinfo et al), visible externally
  * indexed physically */
 struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned;
+EXPORT_SYMBOL(cpu_data);
 
 /* physical ID of the CPU used to boot the system */
 unsigned char boot_cpu_id;
@@ -72,6 +74,7 @@ static volatile unsigned long smp_invali
 /* Bitmask of currently online CPUs - used by setup.c for
    /proc/cpuinfo, visible externally but still physical */
 cpumask_t cpu_online_map = CPU_MASK_NONE;
+EXPORT_SYMBOL(cpu_online_map);
 
 /* Bitmask of CPUs present in the system - exported by i386_syms.c, used
  * by scheduler but indexed physically */
@@ -238,6 +241,7 @@ static cpumask_t smp_commenced_mask = CP
 /* This is for the new dynamic CPU boot code */
 cpumask_t cpu_callin_map = CPU_MASK_NONE;
 cpumask_t cpu_callout_map = CPU_MASK_NONE;
+EXPORT_SYMBOL(cpu_callout_map);
 
 /* The per processor IRQ masks (these are usually kept in sync) */
 static __u16 vic_irq_mask[NR_CPUS] __cacheline_aligned;
@@ -978,6 +982,7 @@ void flush_tlb_page(struct vm_area_struc
 
 	preempt_enable();
 }
+EXPORT_SYMBOL(flush_tlb_page);
 
 /* enable the requested IRQs */
 static void
@@ -1109,6 +1114,7 @@ smp_call_function (void (*func) (void *i
 
 	return 0;
 }
+EXPORT_SYMBOL(smp_call_function);
 
 /* Sorry about the name.  In an APIC based system, the APICs
  * themselves are programmed to send a timer interrupt.  This is used
@@ -1288,7 +1294,7 @@ smp_local_timer_interrupt(struct pt_regs
 						per_cpu(prof_counter, cpu);
 		}
 
-		update_process_times(user_mode(regs));
+		update_process_times(user_mode_vm(regs));
 	}
 
 	if( ((1<<cpu) & voyager_extended_vic_processors) == 0)
diff --git a/arch/i386/mm/Makefile b/arch/i386/mm/Makefile
--- a/arch/i386/mm/Makefile
+++ b/arch/i386/mm/Makefile
@@ -4,7 +4,7 @@
 
 obj-y	:= init.o pgtable.o fault.o ioremap.o extable.o pageattr.o mmap.o
 
-obj-$(CONFIG_DISCONTIGMEM)	+= discontig.o
+obj-$(CONFIG_NUMA) += discontig.o
 obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
 obj-$(CONFIG_HIGHMEM) += highmem.o
 obj-$(CONFIG_BOOT_IOREMAP) += boot_ioremap.o
diff --git a/arch/i386/mm/discontig.c b/arch/i386/mm/discontig.c
--- a/arch/i386/mm/discontig.c
+++ b/arch/i386/mm/discontig.c
@@ -29,12 +29,16 @@
 #include <linux/highmem.h>
 #include <linux/initrd.h>
 #include <linux/nodemask.h>
+#include <linux/module.h>
+#include <linux/kexec.h>
+
 #include <asm/e820.h>
 #include <asm/setup.h>
 #include <asm/mmzone.h>
 #include <bios_ebda.h>
 
 struct pglist_data *node_data[MAX_NUMNODES];
+EXPORT_SYMBOL(node_data);
 bootmem_data_t node0_bdata;
 
 /*
@@ -42,12 +46,16 @@ bootmem_data_t node0_bdata;
  *                  populated the following initialisation.
  *
  * 1) node_online_map  - the map of all nodes configured (online) in the system
- * 2) physnode_map     - the mapping between a pfn and owning node
- * 3) node_start_pfn   - the starting page frame number for a node
+ * 2) node_start_pfn   - the starting page frame number for a node
  * 3) node_end_pfn     - the ending page fram number for a node
  */
+unsigned long node_start_pfn[MAX_NUMNODES];
+unsigned long node_end_pfn[MAX_NUMNODES];
 
+
+#ifdef CONFIG_DISCONTIGMEM
 /*
+ * 4) physnode_map     - the mapping between a pfn and owning node
  * physnode_map keeps track of the physical memory layout of a generic
  * numa node on a 256Mb break (each element of the array will
  * represent 256Mb of memory and will be marked by the node id.  so,
@@ -59,6 +67,7 @@ bootmem_data_t node0_bdata;
  *     physnode_map[8- ] = -1;
  */
 s8 physnode_map[MAX_ELEMENTS] = { [0 ... (MAX_ELEMENTS - 1)] = -1};
+EXPORT_SYMBOL(physnode_map);
 
 void memory_present(int nid, unsigned long start, unsigned long end)
 {
@@ -85,9 +94,7 @@ unsigned long node_memmap_size_bytes(int
 
 	return (nr_pages + 1) * sizeof(struct page);
 }
-
-unsigned long node_start_pfn[MAX_NUMNODES];
-unsigned long node_end_pfn[MAX_NUMNODES];
+#endif
 
 extern unsigned long find_max_low_pfn(void);
 extern void find_max_pfn(void);
@@ -108,6 +115,9 @@ unsigned long node_remap_offset[MAX_NUMN
 void *node_remap_start_vaddr[MAX_NUMNODES];
 void set_pmd_pfn(unsigned long vaddr, unsigned long pfn, pgprot_t flags);
 
+void *node_remap_end_vaddr[MAX_NUMNODES];
+void *node_remap_alloc_vaddr[MAX_NUMNODES];
+
 /*
  * FLAT - support for basic PC memory model with discontig enabled, essentially
  *        a single node with all available processors in it with a flat
@@ -146,6 +156,21 @@ static void __init find_max_pfn_node(int
 		BUG();
 }
 
+/* Find the owning node for a pfn. */
+int early_pfn_to_nid(unsigned long pfn)
+{
+	int nid;
+
+	for_each_node(nid) {
+		if (node_end_pfn[nid] == 0)
+			break;
+		if (node_start_pfn[nid] <= pfn && node_end_pfn[nid] >= pfn)
+			return nid;
+	}
+
+	return 0;
+}
+
 /* 
  * Allocate memory for the pg_data_t for this node via a crude pre-bootmem
  * method.  For node zero take this from the bottom of memory, for
@@ -163,6 +188,21 @@ static void __init allocate_pgdat(int ni
 	}
 }
 
+void *alloc_remap(int nid, unsigned long size)
+{
+	void *allocation = node_remap_alloc_vaddr[nid];
+
+	size = ALIGN(size, L1_CACHE_BYTES);
+
+	if (!allocation || (allocation + size) >= node_remap_end_vaddr[nid])
+		return 0;
+
+	node_remap_alloc_vaddr[nid] += size;
+	memset(allocation, 0, size);
+
+	return allocation;
+}
+
 void __init remap_numa_kva(void)
 {
 	void *vaddr;
@@ -170,8 +210,6 @@ void __init remap_numa_kva(void)
 	int node;
 
 	for_each_online_node(node) {
-		if (node == 0)
-			continue;
 		for (pfn=0; pfn < node_remap_size[node]; pfn += PTRS_PER_PTE) {
 			vaddr = node_remap_start_vaddr[node]+(pfn<<PAGE_SHIFT);
 			set_pmd_pfn((ulong) vaddr, 
@@ -185,13 +223,9 @@ static unsigned long calculate_numa_rema
 {
 	int nid;
 	unsigned long size, reserve_pages = 0;
+	unsigned long pfn;
 
 	for_each_online_node(nid) {
-		if (nid == 0)
-			continue;
-		if (!node_remap_size[nid])
-			continue;
-
 		/*
 		 * The acpi/srat node info can show hot-add memroy zones
 		 * where memory could be added but not currently present.
@@ -208,13 +242,37 @@ static unsigned long calculate_numa_rema
 		size = (size + LARGE_PAGE_BYTES - 1) / LARGE_PAGE_BYTES;
 		/* now the roundup is correct, convert to PAGE_SIZE pages */
 		size = size * PTRS_PER_PTE;
+
+		/*
+		 * Validate the region we are allocating only contains valid
+		 * pages.
+		 */
+		for (pfn = node_end_pfn[nid] - size;
+		     pfn < node_end_pfn[nid]; pfn++)
+			if (!page_is_ram(pfn))
+				break;
+
+		if (pfn != node_end_pfn[nid])
+			size = 0;
+
 		printk("Reserving %ld pages of KVA for lmem_map of node %d\n",
 				size, nid);
 		node_remap_size[nid] = size;
-		reserve_pages += size;
 		node_remap_offset[nid] = reserve_pages;
+		reserve_pages += size;
 		printk("Shrinking node %d from %ld pages to %ld pages\n",
 			nid, node_end_pfn[nid], node_end_pfn[nid] - size);
+
+		if (node_end_pfn[nid] & (PTRS_PER_PTE-1)) {
+			/*
+			 * Align node_end_pfn[] and node_remap_start_pfn[] to
+			 * pmd boundary. remap_numa_kva will barf otherwise.
+			 */
+			printk("Shrinking node %d further by %ld pages for proper alignment\n",
+				nid, node_end_pfn[nid] & (PTRS_PER_PTE-1));
+			size +=  node_end_pfn[nid] & (PTRS_PER_PTE-1);
+		}
+
 		node_end_pfn[nid] -= size;
 		node_remap_start_pfn[nid] = node_end_pfn[nid];
 	}
@@ -265,12 +323,18 @@ unsigned long __init setup_memory(void)
 			(ulong) pfn_to_kaddr(max_low_pfn));
 	for_each_online_node(nid) {
 		node_remap_start_vaddr[nid] = pfn_to_kaddr(
-			(highstart_pfn + reserve_pages) - node_remap_offset[nid]);
+				highstart_pfn + node_remap_offset[nid]);
+		/* Init the node remap allocator */
+		node_remap_end_vaddr[nid] = node_remap_start_vaddr[nid] +
+			(node_remap_size[nid] * PAGE_SIZE);
+		node_remap_alloc_vaddr[nid] = node_remap_start_vaddr[nid] +
+			ALIGN(sizeof(pg_data_t), PAGE_SIZE);
+
 		allocate_pgdat(nid);
 		printk ("node %d will remap to vaddr %08lx - %08lx\n", nid,
 			(ulong) node_remap_start_vaddr[nid],
-			(ulong) pfn_to_kaddr(highstart_pfn + reserve_pages
-			    - node_remap_offset[nid] + node_remap_size[nid]));
+			(ulong) pfn_to_kaddr(highstart_pfn
+			   + node_remap_offset[nid] + node_remap_size[nid]));
 	}
 	printk("High memory starts at vaddr %08lx\n",
 			(ulong) pfn_to_kaddr(highstart_pfn));
@@ -333,23 +397,9 @@ void __init zone_sizes_init(void)
 		}
 
 		zholes_size = get_zholes_size(nid);
-		/*
-		 * We let the lmem_map for node 0 be allocated from the
-		 * normal bootmem allocator, but other nodes come from the
-		 * remapped KVA area - mbligh
-		 */
-		if (!nid)
-			free_area_init_node(nid, NODE_DATA(nid),
-					zones_size, start, zholes_size);
-		else {
-			unsigned long lmem_map;
-			lmem_map = (unsigned long)node_remap_start_vaddr[nid];
-			lmem_map += sizeof(pg_data_t) + PAGE_SIZE - 1;
-			lmem_map &= PAGE_MASK;
-			NODE_DATA(nid)->node_mem_map = (struct page *)lmem_map;
-			free_area_init_node(nid, NODE_DATA(nid), zones_size,
-				start, zholes_size);
-		}
+
+		free_area_init_node(nid, NODE_DATA(nid), zones_size, start,
+				zholes_size);
 	}
 	return;
 }
@@ -358,24 +408,26 @@ void __init set_highmem_pages_init(int b
 {
 #ifdef CONFIG_HIGHMEM
 	struct zone *zone;
+	struct page *page;
 
 	for_each_zone(zone) {
-		unsigned long node_pfn, node_high_size, zone_start_pfn;
-		struct page * zone_mem_map;
-		
+		unsigned long node_pfn, zone_start_pfn, zone_end_pfn;
+
 		if (!is_highmem(zone))
 			continue;
 
-		printk("Initializing %s for node %d\n", zone->name,
-			zone->zone_pgdat->node_id);
-
-		node_high_size = zone->spanned_pages;
-		zone_mem_map = zone->zone_mem_map;
 		zone_start_pfn = zone->zone_start_pfn;
+		zone_end_pfn = zone_start_pfn + zone->spanned_pages;
 
-		for (node_pfn = 0; node_pfn < node_high_size; node_pfn++) {
-			one_highpage_init((struct page *)(zone_mem_map + node_pfn),
-					  zone_start_pfn + node_pfn, bad_ppro);
+		printk("Initializing %s for node %d (%08lx:%08lx)\n",
+				zone->name, zone->zone_pgdat->node_id,
+				zone_start_pfn, zone_end_pfn);
+
+		for (node_pfn = zone_start_pfn; node_pfn < zone_end_pfn; node_pfn++) {
+			if (!pfn_valid(node_pfn))
+				continue;
+			page = pfn_to_page(node_pfn);
+			one_highpage_init(page, node_pfn, bad_ppro);
 		}
 	}
 	totalram_pages += totalhigh_pages;
diff --git a/arch/i386/mm/fault.c b/arch/i386/mm/fault.c
--- a/arch/i386/mm/fault.c
+++ b/arch/i386/mm/fault.c
@@ -146,7 +146,7 @@ static int __is_prefetch(struct pt_regs 
 
 		if (instr > limit)
 			break;
-		if (__get_user(opcode, (unsigned char *) instr))
+		if (__get_user(opcode, (unsigned char __user *) instr))
 			break; 
 
 		instr_hi = opcode & 0xf0; 
@@ -173,7 +173,7 @@ static int __is_prefetch(struct pt_regs 
 			scan_more = 0;
 			if (instr > limit)
 				break;
-			if (__get_user(opcode, (unsigned char *) instr)) 
+			if (__get_user(opcode, (unsigned char __user *) instr))
 				break;
 			prefetch = (instr_lo == 0xF) &&
 				(opcode == 0x0D || opcode == 0x18);
@@ -463,6 +463,9 @@ no_context:
 		printk(KERN_ALERT "*pte = %08lx\n", page);
 	}
 #endif
+	tsk->thread.cr2 = address;
+	tsk->thread.trap_no = 14;
+	tsk->thread.error_code = error_code;
 	die("Oops", regs, error_code);
 	bust_spinlocks(0);
 	do_exit(SIGKILL);
diff --git a/arch/i386/mm/highmem.c b/arch/i386/mm/highmem.c
--- a/arch/i386/mm/highmem.c
+++ b/arch/i386/mm/highmem.c
@@ -1,4 +1,5 @@
 #include <linux/highmem.h>
+#include <linux/module.h>
 
 void *kmap(struct page *page)
 {
@@ -74,6 +75,24 @@ void kunmap_atomic(void *kvaddr, enum km
 	preempt_check_resched();
 }
 
+/* This is the same as kmap_atomic() but can map memory that doesn't
+ * have a struct page associated with it.
+ */
+void *kmap_atomic_pfn(unsigned long pfn, enum km_type type)
+{
+	enum fixed_addresses idx;
+	unsigned long vaddr;
+
+	inc_preempt_count();
+
+	idx = type + KM_TYPE_NR*smp_processor_id();
+	vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
+	set_pte(kmap_pte-idx, pfn_pte(pfn, kmap_prot));
+	__flush_tlb_one(vaddr);
+
+	return (void*) vaddr;
+}
+
 struct page *kmap_atomic_to_page(void *ptr)
 {
 	unsigned long idx, vaddr = (unsigned long)ptr;
@@ -87,3 +106,8 @@ struct page *kmap_atomic_to_page(void *p
 	return pte_page(*pte);
 }
 
+EXPORT_SYMBOL(kmap);
+EXPORT_SYMBOL(kunmap);
+EXPORT_SYMBOL(kmap_atomic);
+EXPORT_SYMBOL(kunmap_atomic);
+EXPORT_SYMBOL(kmap_atomic_to_page);
diff --git a/arch/i386/mm/hugetlbpage.c b/arch/i386/mm/hugetlbpage.c
--- a/arch/i386/mm/hugetlbpage.c
+++ b/arch/i386/mm/hugetlbpage.c
@@ -18,7 +18,7 @@
 #include <asm/tlb.h>
 #include <asm/tlbflush.h>
 
-static pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr)
+pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr)
 {
 	pgd_t *pgd;
 	pud_t *pud;
@@ -30,7 +30,7 @@ static pte_t *huge_pte_alloc(struct mm_s
 	return (pte_t *) pmd;
 }
 
-static pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr)
+pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr)
 {
 	pgd_t *pgd;
 	pud_t *pud;
@@ -42,21 +42,6 @@ static pte_t *huge_pte_offset(struct mm_
 	return (pte_t *) pmd;
 }
 
-static void set_huge_pte(struct mm_struct *mm, struct vm_area_struct *vma, struct page *page, pte_t * page_table, int write_access)
-{
-	pte_t entry;
-
-	add_mm_counter(mm, rss, HPAGE_SIZE / PAGE_SIZE);
-	if (write_access) {
-		entry =
-		    pte_mkwrite(pte_mkdirty(mk_pte(page, vma->vm_page_prot)));
-	} else
-		entry = pte_wrprotect(mk_pte(page, vma->vm_page_prot));
-	entry = pte_mkyoung(entry);
-	mk_pte_huge(entry);
-	set_pte(page_table, entry);
-}
-
 /*
  * This function checks for proper alignment of input addr and len parameters.
  */
@@ -69,77 +54,6 @@ int is_aligned_hugepage_range(unsigned l
 	return 0;
 }
 
-int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src,
-			struct vm_area_struct *vma)
-{
-	pte_t *src_pte, *dst_pte, entry;
-	struct page *ptepage;
-	unsigned long addr = vma->vm_start;
-	unsigned long end = vma->vm_end;
-
-	while (addr < end) {
-		dst_pte = huge_pte_alloc(dst, addr);
-		if (!dst_pte)
-			goto nomem;
-		src_pte = huge_pte_offset(src, addr);
-		entry = *src_pte;
-		ptepage = pte_page(entry);
-		get_page(ptepage);
-		set_pte(dst_pte, entry);
-		add_mm_counter(dst, rss, HPAGE_SIZE / PAGE_SIZE);
-		addr += HPAGE_SIZE;
-	}
-	return 0;
-
-nomem:
-	return -ENOMEM;
-}
-
-int
-follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma,
-		    struct page **pages, struct vm_area_struct **vmas,
-		    unsigned long *position, int *length, int i)
-{
-	unsigned long vpfn, vaddr = *position;
-	int remainder = *length;
-
-	WARN_ON(!is_vm_hugetlb_page(vma));
-
-	vpfn = vaddr/PAGE_SIZE;
-	while (vaddr < vma->vm_end && remainder) {
-
-		if (pages) {
-			pte_t *pte;
-			struct page *page;
-
-			pte = huge_pte_offset(mm, vaddr);
-
-			/* hugetlb should be locked, and hence, prefaulted */
-			WARN_ON(!pte || pte_none(*pte));
-
-			page = &pte_page(*pte)[vpfn % (HPAGE_SIZE/PAGE_SIZE)];
-
-			WARN_ON(!PageCompound(page));
-
-			get_page(page);
-			pages[i] = page;
-		}
-
-		if (vmas)
-			vmas[i] = vma;
-
-		vaddr += PAGE_SIZE;
-		++vpfn;
-		--remainder;
-		++i;
-	}
-
-	*length = remainder;
-	*position = vaddr;
-
-	return i;
-}
-
 #if 0	/* This is just for testing */
 struct page *
 follow_huge_addr(struct mm_struct *mm, unsigned long address, int write)
@@ -204,83 +118,15 @@ follow_huge_pmd(struct mm_struct *mm, un
 }
 #endif
 
-void unmap_hugepage_range(struct vm_area_struct *vma,
-		unsigned long start, unsigned long end)
+void hugetlb_clean_stale_pgtable(pte_t *pte)
 {
-	struct mm_struct *mm = vma->vm_mm;
-	unsigned long address;
-	pte_t pte, *ptep;
+	pmd_t *pmd = (pmd_t *) pte;
 	struct page *page;
 
-	BUG_ON(start & (HPAGE_SIZE - 1));
-	BUG_ON(end & (HPAGE_SIZE - 1));
-
-	for (address = start; address < end; address += HPAGE_SIZE) {
-		ptep = huge_pte_offset(mm, address);
-		if (!ptep)
-			continue;
-		pte = ptep_get_and_clear(mm, address, ptep);
-		if (pte_none(pte))
-			continue;
-		page = pte_page(pte);
-		put_page(page);
-	}
-	add_mm_counter(mm ,rss, -((end - start) >> PAGE_SHIFT));
-	flush_tlb_range(vma, start, end);
-}
-
-int hugetlb_prefault(struct address_space *mapping, struct vm_area_struct *vma)
-{
-	struct mm_struct *mm = current->mm;
-	unsigned long addr;
-	int ret = 0;
-
-	BUG_ON(vma->vm_start & ~HPAGE_MASK);
-	BUG_ON(vma->vm_end & ~HPAGE_MASK);
-
-	spin_lock(&mm->page_table_lock);
-	for (addr = vma->vm_start; addr < vma->vm_end; addr += HPAGE_SIZE) {
-		unsigned long idx;
-		pte_t *pte = huge_pte_alloc(mm, addr);
-		struct page *page;
-
-		if (!pte) {
-			ret = -ENOMEM;
-			goto out;
-		}
-
-		if (!pte_none(*pte))
-			continue;
-
-		idx = ((addr - vma->vm_start) >> HPAGE_SHIFT)
-			+ (vma->vm_pgoff >> (HPAGE_SHIFT - PAGE_SHIFT));
-		page = find_get_page(mapping, idx);
-		if (!page) {
-			/* charge the fs quota first */
-			if (hugetlb_get_quota(mapping)) {
-				ret = -ENOMEM;
-				goto out;
-			}
-			page = alloc_huge_page();
-			if (!page) {
-				hugetlb_put_quota(mapping);
-				ret = -ENOMEM;
-				goto out;
-			}
-			ret = add_to_page_cache(page, mapping, idx, GFP_ATOMIC);
-			if (! ret) {
-				unlock_page(page);
-			} else {
-				hugetlb_put_quota(mapping);
-				free_huge_page(page);
-				goto out;
-			}
-		}
-		set_huge_pte(mm, vma, page, pte, vma->vm_flags & VM_WRITE);
-	}
-out:
-	spin_unlock(&mm->page_table_lock);
-	return ret;
+	page = pmd_page(*pmd);
+	pmd_clear(pmd);
+	dec_page_state(nr_page_table_pages);
+	page_cache_release(page);
 }
 
 /* x86_64 also uses this file */
@@ -294,7 +140,12 @@ static unsigned long hugetlb_get_unmappe
 	struct vm_area_struct *vma;
 	unsigned long start_addr;
 
-	start_addr = mm->free_area_cache;
+	if (len > mm->cached_hole_size) {
+	        start_addr = mm->free_area_cache;
+	} else {
+	        start_addr = TASK_UNMAPPED_BASE;
+	        mm->cached_hole_size = 0;
+	}
 
 full_search:
 	addr = ALIGN(start_addr, HPAGE_SIZE);
@@ -308,6 +159,7 @@ full_search:
 			 */
 			if (start_addr != TASK_UNMAPPED_BASE) {
 				start_addr = TASK_UNMAPPED_BASE;
+				mm->cached_hole_size = 0;
 				goto full_search;
 			}
 			return -ENOMEM;
@@ -316,6 +168,8 @@ full_search:
 			mm->free_area_cache = addr + len;
 			return addr;
 		}
+		if (addr + mm->cached_hole_size < vma->vm_start)
+		        mm->cached_hole_size = vma->vm_start - addr;
 		addr = ALIGN(vma->vm_end, HPAGE_SIZE);
 	}
 }
@@ -327,12 +181,17 @@ static unsigned long hugetlb_get_unmappe
 	struct mm_struct *mm = current->mm;
 	struct vm_area_struct *vma, *prev_vma;
 	unsigned long base = mm->mmap_base, addr = addr0;
+	unsigned long largest_hole = mm->cached_hole_size;
 	int first_time = 1;
 
 	/* don't allow allocations above current base */
 	if (mm->free_area_cache > base)
 		mm->free_area_cache = base;
 
+	if (len <= largest_hole) {
+	        largest_hole = 0;
+		mm->free_area_cache  = base;
+	}
 try_again:
 	/* make sure it can fit in the remaining address space */
 	if (mm->free_area_cache < len)
@@ -353,13 +212,21 @@ try_again:
 		 * vma->vm_start, use it:
 		 */
 		if (addr + len <= vma->vm_start &&
-				(!prev_vma || (addr >= prev_vma->vm_end)))
+		            (!prev_vma || (addr >= prev_vma->vm_end))) {
 			/* remember the address as a hint for next time */
-			return (mm->free_area_cache = addr);
-		else
+		        mm->cached_hole_size = largest_hole;
+		        return (mm->free_area_cache = addr);
+		} else {
 			/* pull free_area_cache down to the first hole */
-			if (mm->free_area_cache == vma->vm_end)
+		        if (mm->free_area_cache == vma->vm_end) {
 				mm->free_area_cache = vma->vm_start;
+				mm->cached_hole_size = largest_hole;
+			}
+		}
+
+		/* remember the largest hole we saw so far */
+		if (addr + largest_hole < vma->vm_start)
+		        largest_hole = vma->vm_start - addr;
 
 		/* try just below the current vma->vm_start */
 		addr = (vma->vm_start - len) & HPAGE_MASK;
@@ -372,6 +239,7 @@ fail:
 	 */
 	if (first_time) {
 		mm->free_area_cache = base;
+		largest_hole = 0;
 		first_time = 0;
 		goto try_again;
 	}
@@ -382,6 +250,7 @@ fail:
 	 * allocations.
 	 */
 	mm->free_area_cache = TASK_UNMAPPED_BASE;
+	mm->cached_hole_size = ~0UL;
 	addr = hugetlb_get_unmapped_area_bottomup(file, addr0,
 			len, pgoff, flags);
 
@@ -389,6 +258,7 @@ fail:
 	 * Restore the topdown base:
 	 */
 	mm->free_area_cache = base;
+	mm->cached_hole_size = ~0UL;
 
 	return addr;
 }
diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c
--- a/arch/i386/mm/init.c
+++ b/arch/i386/mm/init.c
@@ -191,7 +191,7 @@ static inline int page_kills_ppro(unsign
 
 extern int is_available_memory(efi_memory_desc_t *);
 
-static inline int page_is_ram(unsigned long pagenr)
+int page_is_ram(unsigned long pagenr)
 {
 	int i;
 	unsigned long addr, end;
@@ -269,7 +269,6 @@ void __init one_highpage_init(struct pag
 {
 	if (page_is_ram(pfn) && !(bad_ppro && page_kills_ppro(pfn))) {
 		ClearPageReserved(page);
-		set_bit(PG_highmem, &page->flags);
 		set_page_count(page, 1);
 		__free_page(page);
 		totalhigh_pages++;
@@ -277,7 +276,9 @@ void __init one_highpage_init(struct pag
 		SetPageReserved(page);
 }
 
-#ifndef CONFIG_DISCONTIGMEM
+#ifdef CONFIG_NUMA
+extern void set_highmem_pages_init(int);
+#else
 static void __init set_highmem_pages_init(int bad_ppro)
 {
 	int pfn;
@@ -285,9 +286,7 @@ static void __init set_highmem_pages_ini
 		one_highpage_init(pfn_to_page(pfn), pfn, bad_ppro);
 	totalram_pages += totalhigh_pages;
 }
-#else
-extern void set_highmem_pages_init(int);
-#endif /* !CONFIG_DISCONTIGMEM */
+#endif /* CONFIG_FLATMEM */
 
 #else
 #define kmap_init() do { } while (0)
@@ -296,12 +295,13 @@ extern void set_highmem_pages_init(int);
 #endif /* CONFIG_HIGHMEM */
 
 unsigned long long __PAGE_KERNEL = _PAGE_KERNEL;
+EXPORT_SYMBOL(__PAGE_KERNEL);
 unsigned long long __PAGE_KERNEL_EXEC = _PAGE_KERNEL_EXEC;
 
-#ifndef CONFIG_DISCONTIGMEM
-#define remap_numa_kva() do {} while (0)
-#else
+#ifdef CONFIG_NUMA
 extern void __init remap_numa_kva(void);
+#else
+#define remap_numa_kva() do {} while (0)
 #endif
 
 static void __init pagetable_init (void)
@@ -352,7 +352,7 @@ static void __init pagetable_init (void)
 #endif
 }
 
-#if defined(CONFIG_PM_DISK) || defined(CONFIG_SOFTWARE_SUSPEND)
+#ifdef CONFIG_SOFTWARE_SUSPEND
 /*
  * Swap suspend & friends need this for resume because things like the intel-agp
  * driver might have split up a kernel 4MB mapping.
@@ -526,7 +526,7 @@ static void __init set_max_mapnr_init(vo
 #else
 	num_physpages = max_low_pfn;
 #endif
-#ifndef CONFIG_DISCONTIGMEM
+#ifdef CONFIG_FLATMEM
 	max_mapnr = num_physpages;
 #endif
 }
@@ -540,7 +540,7 @@ void __init mem_init(void)
 	int tmp;
 	int bad_ppro;
 
-#ifndef CONFIG_DISCONTIGMEM
+#ifdef CONFIG_FLATMEM
 	if (!mem_map)
 		BUG();
 #endif
diff --git a/arch/i386/mm/ioremap.c b/arch/i386/mm/ioremap.c
--- a/arch/i386/mm/ioremap.c
+++ b/arch/i386/mm/ioremap.c
@@ -11,6 +11,7 @@
 #include <linux/vmalloc.h>
 #include <linux/init.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 #include <asm/io.h>
 #include <asm/fixmap.h>
 #include <asm/cacheflush.h>
@@ -165,7 +166,7 @@ void __iomem * __ioremap(unsigned long p
 	}
 	return (void __iomem *) (offset + (char __iomem *)addr);
 }
-
+EXPORT_SYMBOL(__ioremap);
 
 /**
  * ioremap_nocache     -   map bus memory into CPU space
@@ -222,11 +223,13 @@ void __iomem *ioremap_nocache (unsigned 
 
 	return p;					
 }
+EXPORT_SYMBOL(ioremap_nocache);
 
 void iounmap(volatile void __iomem *addr)
 {
 	struct vm_struct *p;
-	if ((void __force *) addr <= high_memory) 
+
+	if ((void __force *)addr <= high_memory)
 		return;
 
 	/*
@@ -239,9 +242,10 @@ void iounmap(volatile void __iomem *addr
 		return;
 
 	write_lock(&vmlist_lock);
-	p = __remove_vm_area((void *) (PAGE_MASK & (unsigned long __force) addr));
+	p = __remove_vm_area((void *)(PAGE_MASK & (unsigned long __force)addr));
 	if (!p) { 
-		printk("iounmap: bad address %p\n", addr);
+		printk(KERN_WARNING "iounmap: bad address %p\n", addr);
+		dump_stack();
 		goto out_unlock;
 	}
 
@@ -255,6 +259,7 @@ out_unlock:
 	write_unlock(&vmlist_lock);
 	kfree(p); 
 }
+EXPORT_SYMBOL(iounmap);
 
 void __init *bt_ioremap(unsigned long phys_addr, unsigned long size)
 {
diff --git a/arch/i386/mm/pgtable.c b/arch/i386/mm/pgtable.c
--- a/arch/i386/mm/pgtable.c
+++ b/arch/i386/mm/pgtable.c
@@ -30,13 +30,14 @@ void show_mem(void)
 	struct page *page;
 	pg_data_t *pgdat;
 	unsigned long i;
+	struct page_state ps;
 
-	printk("Mem-info:\n");
+	printk(KERN_INFO "Mem-info:\n");
 	show_free_areas();
-	printk("Free swap:       %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
+	printk(KERN_INFO "Free swap:       %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
 	for_each_pgdat(pgdat) {
 		for (i = 0; i < pgdat->node_spanned_pages; ++i) {
-			page = pgdat->node_mem_map + i;
+			page = pgdat_page_nr(pgdat, i);
 			total++;
 			if (PageHighMem(page))
 				highmem++;
@@ -48,11 +49,18 @@ void show_mem(void)
 				shared += page_count(page) - 1;
 		}
 	}
-	printk("%d pages of RAM\n", total);
-	printk("%d pages of HIGHMEM\n",highmem);
-	printk("%d reserved pages\n",reserved);
-	printk("%d pages shared\n",shared);
-	printk("%d pages swap cached\n",cached);
+	printk(KERN_INFO "%d pages of RAM\n", total);
+	printk(KERN_INFO "%d pages of HIGHMEM\n", highmem);
+	printk(KERN_INFO "%d reserved pages\n", reserved);
+	printk(KERN_INFO "%d pages shared\n", shared);
+	printk(KERN_INFO "%d pages swap cached\n", cached);
+
+	get_page_state(&ps);
+	printk(KERN_INFO "%lu pages dirty\n", ps.nr_dirty);
+	printk(KERN_INFO "%lu pages writeback\n", ps.nr_writeback);
+	printk(KERN_INFO "%lu pages mapped\n", ps.nr_mapped);
+	printk(KERN_INFO "%lu pages slab\n", ps.nr_slab);
+	printk(KERN_INFO "%lu pages pagetables\n", ps.nr_page_table_pages);
 }
 
 /*
@@ -105,16 +113,16 @@ void set_pmd_pfn(unsigned long vaddr, un
 	pmd_t *pmd;
 
 	if (vaddr & (PMD_SIZE-1)) {		/* vaddr is misaligned */
-		printk ("set_pmd_pfn: vaddr misaligned\n");
+		printk(KERN_WARNING "set_pmd_pfn: vaddr misaligned\n");
 		return; /* BUG(); */
 	}
 	if (pfn & (PTRS_PER_PTE-1)) {		/* pfn is misaligned */
-		printk ("set_pmd_pfn: pfn misaligned\n");
+		printk(KERN_WARNING "set_pmd_pfn: pfn misaligned\n");
 		return; /* BUG(); */
 	}
 	pgd = swapper_pg_dir + pgd_index(vaddr);
 	if (pgd_none(*pgd)) {
-		printk ("set_pmd_pfn: pgd_none\n");
+		printk(KERN_WARNING "set_pmd_pfn: pgd_none\n");
 		return; /* BUG(); */
 	}
 	pud = pud_offset(pgd, vaddr);
diff --git a/arch/i386/oprofile/backtrace.c b/arch/i386/oprofile/backtrace.c
--- a/arch/i386/oprofile/backtrace.c
+++ b/arch/i386/oprofile/backtrace.c
@@ -91,7 +91,7 @@ x86_backtrace(struct pt_regs * const reg
 	head = (struct frame_head *)regs->ebp;
 #endif
 
-	if (!user_mode(regs)) {
+	if (!user_mode_vm(regs)) {
 		while (depth-- && valid_kernel_stack(head, regs))
 			head = dump_backtrace(head);
 		return;
diff --git a/arch/i386/pci/acpi.c b/arch/i386/pci/acpi.c
--- a/arch/i386/pci/acpi.c
+++ b/arch/i386/pci/acpi.c
@@ -30,6 +30,7 @@ static int __init pci_acpi_init(void)
 	acpi_irq_penalty_init();
 	pcibios_scanned++;
 	pcibios_enable_irq = acpi_pci_irq_enable;
+	pcibios_disable_irq = acpi_pci_irq_disable;
 
 	if (pci_routeirq) {
 		/*
diff --git a/arch/i386/pci/common.c b/arch/i386/pci/common.c
--- a/arch/i386/pci/common.c
+++ b/arch/i386/pci/common.c
@@ -25,7 +25,8 @@ unsigned int pci_probe = PCI_PROBE_BIOS 
 
 int pci_routeirq;
 int pcibios_last_bus = -1;
-struct pci_bus *pci_root_bus = NULL;
+unsigned long pirq_table_addr;
+struct pci_bus *pci_root_bus;
 struct pci_raw_ops *raw_pci_ops;
 
 static int pci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value)
@@ -133,7 +134,7 @@ struct pci_bus * __devinit pcibios_scan_
 
 	printk("PCI: Probing PCI hardware (bus %02x)\n", busnum);
 
-	return pci_scan_bus(busnum, &pci_root_ops, NULL);
+	return pci_scan_bus_parented(NULL, busnum, &pci_root_ops, NULL);
 }
 
 extern u8 pci_cache_line_size;
@@ -164,6 +165,7 @@ static int __init pcibios_init(void)
 	if ((pci_probe & PCI_BIOS_SORT) && !(pci_probe & PCI_NO_SORT))
 		pcibios_sort();
 #endif
+	pci_assign_unassigned_resources();
 	return 0;
 }
 
@@ -188,6 +190,9 @@ char * __devinit  pcibios_setup(char *st
 	} else if (!strcmp(str, "biosirq")) {
 		pci_probe |= PCI_BIOS_IRQ_SCAN;
 		return NULL;
+	} else if (!strncmp(str, "pirqaddr=", 9)) {
+		pirq_table_addr = simple_strtoul(str+9, NULL, 0);
+		return NULL;
 	}
 #endif
 #ifdef CONFIG_PCI_DIRECT
@@ -249,3 +254,9 @@ int pcibios_enable_device(struct pci_dev
 
 	return pcibios_enable_irq(dev);
 }
+
+void pcibios_disable_device (struct pci_dev *dev)
+{
+	if (pcibios_disable_irq)
+		pcibios_disable_irq(dev);
+}
diff --git a/arch/i386/pci/i386.c b/arch/i386/pci/i386.c
--- a/arch/i386/pci/i386.c
+++ b/arch/i386/pci/i386.c
@@ -106,11 +106,16 @@ static void __init pcibios_allocate_bus_
 		if ((dev = bus->self)) {
 			for (idx = PCI_BRIDGE_RESOURCES; idx < PCI_NUM_RESOURCES; idx++) {
 				r = &dev->resource[idx];
-				if (!r->start)
+				if (!r->flags)
 					continue;
 				pr = pci_find_parent_resource(dev, r);
-				if (!pr || request_resource(pr, r) < 0)
+				if (!r->start || !pr || request_resource(pr, r) < 0) {
 					printk(KERN_ERR "PCI: Cannot allocate resource region %d of bridge %s\n", idx, pci_name(dev));
+					/* Something is wrong with the region.
+					   Invalidate the resource to prevent child
+					   resource allocations in this range. */
+					r->flags = 0;
+				}
 			}
 		}
 		pcibios_allocate_bus_resources(&bus->children);
@@ -227,7 +232,7 @@ int pcibios_enable_resources(struct pci_
 
 	pci_read_config_word(dev, PCI_COMMAND, &cmd);
 	old_cmd = cmd;
-	for(idx=0; idx<6; idx++) {
+	for(idx = 0; idx < PCI_NUM_RESOURCES; idx++) {
 		/* Only set up the requested stuff */
 		if (!(mask & (1<<idx)))
 			continue;
diff --git a/arch/i386/pci/irq.c b/arch/i386/pci/irq.c
--- a/arch/i386/pci/irq.c
+++ b/arch/i386/pci/irq.c
@@ -56,6 +56,36 @@ struct irq_router_handler {
 };
 
 int (*pcibios_enable_irq)(struct pci_dev *dev) = NULL;
+void (*pcibios_disable_irq)(struct pci_dev *dev) = NULL;
+
+/*
+ *  Check passed address for the PCI IRQ Routing Table signature
+ *  and perform checksum verification.
+ */
+
+static inline struct irq_routing_table * pirq_check_routing_table(u8 *addr)
+{
+	struct irq_routing_table *rt;
+	int i;
+	u8 sum;
+
+	rt = (struct irq_routing_table *) addr;
+	if (rt->signature != PIRQ_SIGNATURE ||
+	    rt->version != PIRQ_VERSION ||
+	    rt->size % 16 ||
+	    rt->size < sizeof(struct irq_routing_table))
+		return NULL;
+	sum = 0;
+	for (i=0; i < rt->size; i++)
+		sum += addr[i];
+	if (!sum) {
+		DBG("PCI: Interrupt Routing Table found at 0x%p\n", rt);
+		return rt;
+	}
+	return NULL;
+}
+
+
 
 /*
  *  Search 0xf0000 -- 0xfffff for the PCI IRQ Routing Table.
@@ -65,23 +95,17 @@ static struct irq_routing_table * __init
 {
 	u8 *addr;
 	struct irq_routing_table *rt;
-	int i;
-	u8 sum;
 
+	if (pirq_table_addr) {
+		rt = pirq_check_routing_table((u8 *) __va(pirq_table_addr));
+		if (rt)
+			return rt;
+		printk(KERN_WARNING "PCI: PIRQ table NOT found at pirqaddr\n");
+	}
 	for(addr = (u8 *) __va(0xf0000); addr < (u8 *) __va(0x100000); addr += 16) {
-		rt = (struct irq_routing_table *) addr;
-		if (rt->signature != PIRQ_SIGNATURE ||
-		    rt->version != PIRQ_VERSION ||
-		    rt->size % 16 ||
-		    rt->size < sizeof(struct irq_routing_table))
-			continue;
-		sum = 0;
-		for(i=0; i<rt->size; i++)
-			sum += addr[i];
-		if (!sum) {
-			DBG("PCI: Interrupt Routing Table found at 0x%p\n", rt);
+		rt = pirq_check_routing_table(addr);
+		if (rt)
 			return rt;
-		}
 	}
 	return NULL;
 }
@@ -227,6 +251,24 @@ static int pirq_via_set(struct pci_dev *
 }
 
 /*
+ * The VIA pirq rules are nibble-based, like ALI,
+ * but without the ugly irq number munging.
+ * However, for 82C586, nibble map is different .
+ */
+static int pirq_via586_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
+{
+	static unsigned int pirqmap[4] = { 3, 2, 5, 1 };
+	return read_config_nybble(router, 0x55, pirqmap[pirq-1]);
+}
+
+static int pirq_via586_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
+{
+	static unsigned int pirqmap[4] = { 3, 2, 5, 1 };
+	write_config_nybble(router, 0x55, pirqmap[pirq-1], irq);
+	return 1;
+}
+
+/*
  * ITE 8330G pirq rules are nibble-based
  * FIXME: pirqmap may be { 1, 0, 3, 2 },
  * 	  2+3 are both mapped to irq 9 on my system
@@ -509,9 +551,20 @@ static __init int intel_router_probe(str
 static __init int via_router_probe(struct irq_router *r, struct pci_dev *router, u16 device)
 {
 	/* FIXME: We should move some of the quirk fixup stuff here */
+
+	if (router->device == PCI_DEVICE_ID_VIA_82C686 &&
+			device == PCI_DEVICE_ID_VIA_82C586_0) {
+		/* Asus k7m bios wrongly reports 82C686A as 586-compatible */
+		device = PCI_DEVICE_ID_VIA_82C686;
+	}
+
 	switch(device)
 	{
 		case PCI_DEVICE_ID_VIA_82C586_0:
+			r->name = "VIA";
+			r->get = pirq_via586_get;
+			r->set = pirq_via586_set;
+			return 1;
 		case PCI_DEVICE_ID_VIA_82C596:
 		case PCI_DEVICE_ID_VIA_82C686:
 		case PCI_DEVICE_ID_VIA_8231:
@@ -1006,24 +1059,28 @@ static int __init pcibios_irq_init(void)
 subsys_initcall(pcibios_irq_init);
 
 
-static void pirq_penalize_isa_irq(int irq)
+static void pirq_penalize_isa_irq(int irq, int active)
 {
 	/*
 	 *  If any ISAPnP device reports an IRQ in its list of possible
 	 *  IRQ's, we try to avoid assigning it to PCI devices.
 	 */
-	if (irq < 16)
-		pirq_penalty[irq] += 100;
+	if (irq < 16) {
+		if (active)
+			pirq_penalty[irq] += 1000;
+		else
+			pirq_penalty[irq] += 100;
+	}
 }
 
-void pcibios_penalize_isa_irq(int irq)
+void pcibios_penalize_isa_irq(int irq, int active)
 {
 #ifdef CONFIG_ACPI_PCI
 	if (!acpi_noirq)
-		acpi_penalize_isa_irq(irq);
+		acpi_penalize_isa_irq(irq, active);
 	else
 #endif
-		pirq_penalize_isa_irq(irq);
+		pirq_penalize_isa_irq(irq, active);
 }
 
 static int pirq_enable_irq(struct pci_dev *dev)
diff --git a/arch/i386/pci/legacy.c b/arch/i386/pci/legacy.c
--- a/arch/i386/pci/legacy.c
+++ b/arch/i386/pci/legacy.c
@@ -45,6 +45,8 @@ static int __init pci_legacy_init(void)
 
 	printk("PCI: Probing PCI hardware\n");
 	pci_root_bus = pcibios_scan_root(0);
+	if (pci_root_bus)
+		pci_bus_add_devices(pci_root_bus);
 
 	pcibios_fixup_peer_bridges();
 
diff --git a/arch/i386/pci/mmconfig.c b/arch/i386/pci/mmconfig.c
--- a/arch/i386/pci/mmconfig.c
+++ b/arch/i386/pci/mmconfig.c
@@ -11,11 +11,9 @@
 
 #include <linux/pci.h>
 #include <linux/init.h>
+#include <linux/acpi.h>
 #include "pci.h"
 
-/* The physical address of the MMCONFIG aperture.  Set from ACPI tables. */
-u32 pci_mmcfg_base_addr;
-
 #define mmcfg_virt_addr ((void __iomem *) fix_to_virt(FIX_PCIE_MCFG))
 
 /* The base address of the last MMCONFIG device accessed */
@@ -24,10 +22,31 @@ static u32 mmcfg_last_accessed_device;
 /*
  * Functions for accessing PCI configuration space with MMCONFIG accesses
  */
+static u32 get_base_addr(unsigned int seg, int bus)
+{
+	int cfg_num = -1;
+	struct acpi_table_mcfg_config *cfg;
+
+	while (1) {
+		++cfg_num;
+		if (cfg_num >= pci_mmcfg_config_num) {
+			/* something bad is going on, no cfg table is found. */
+			/* so we fall back to the old way we used to do this */
+			/* and just rely on the first entry to be correct. */
+			return pci_mmcfg_config[0].base_address;
+		}
+		cfg = &pci_mmcfg_config[cfg_num];
+		if (cfg->pci_segment_group_number != seg)
+			continue;
+		if ((cfg->start_bus_number <= bus) &&
+		    (cfg->end_bus_number >= bus))
+			return cfg->base_address;
+	}
+}
 
-static inline void pci_exp_set_dev_base(int bus, int devfn)
+static inline void pci_exp_set_dev_base(unsigned int seg, int bus, int devfn)
 {
-	u32 dev_base = pci_mmcfg_base_addr | (bus << 20) | (devfn << 12);
+	u32 dev_base = get_base_addr(seg, bus) | (bus << 20) | (devfn << 12);
 	if (dev_base != mmcfg_last_accessed_device) {
 		mmcfg_last_accessed_device = dev_base;
 		set_fixmap_nocache(FIX_PCIE_MCFG, dev_base);
@@ -44,7 +63,7 @@ static int pci_mmcfg_read(unsigned int s
 
 	spin_lock_irqsave(&pci_config_lock, flags);
 
-	pci_exp_set_dev_base(bus, devfn);
+	pci_exp_set_dev_base(seg, bus, devfn);
 
 	switch (len) {
 	case 1:
@@ -73,7 +92,7 @@ static int pci_mmcfg_write(unsigned int 
 
 	spin_lock_irqsave(&pci_config_lock, flags);
 
-	pci_exp_set_dev_base(bus, devfn);
+	pci_exp_set_dev_base(seg, bus, devfn);
 
 	switch (len) {
 	case 1:
@@ -101,7 +120,11 @@ static int __init pci_mmcfg_init(void)
 {
 	if ((pci_probe & PCI_PROBE_MMCONF) == 0)
 		goto out;
-	if (!pci_mmcfg_base_addr)
+
+	acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg);
+	if ((pci_mmcfg_config_num == 0) ||
+	    (pci_mmcfg_config == NULL) ||
+	    (pci_mmcfg_config[0].base_address == 0))
 		goto out;
 
 	/* Kludge for now. Don't use mmconfig on AMD systems because
diff --git a/arch/i386/pci/numa.c b/arch/i386/pci/numa.c
--- a/arch/i386/pci/numa.c
+++ b/arch/i386/pci/numa.c
@@ -115,6 +115,8 @@ static int __init pci_numa_init(void)
 		return 0;
 
 	pci_root_bus = pcibios_scan_root(0);
+	if (pci_root_bus)
+		pci_bus_add_devices(pci_root_bus);
 	if (num_online_nodes() > 1)
 		for_each_online_node(quad) {
 			if (quad == 0)
diff --git a/arch/i386/pci/pcbios.c b/arch/i386/pci/pcbios.c
--- a/arch/i386/pci/pcbios.c
+++ b/arch/i386/pci/pcbios.c
@@ -4,6 +4,7 @@
 
 #include <linux/pci.h>
 #include <linux/init.h>
+#include <linux/module.h>
 #include "pci.h"
 #include "pci-functions.h"
 
@@ -456,7 +457,7 @@ struct irq_routing_table * __devinit pci
 	free_page(page);
 	return rt;
 }
-
+EXPORT_SYMBOL(pcibios_get_irq_routing_table);
 
 int pcibios_set_irq_routing(struct pci_dev *dev, int pin, int irq)
 {
@@ -473,6 +474,7 @@ int pcibios_set_irq_routing(struct pci_d
 		  "S" (&pci_indirect));
 	return !(ret & 0xff00);
 }
+EXPORT_SYMBOL(pcibios_set_irq_routing);
 
 static int __init pci_pcbios_init(void)
 {
diff --git a/arch/i386/pci/pci.h b/arch/i386/pci/pci.h
--- a/arch/i386/pci/pci.h
+++ b/arch/i386/pci/pci.h
@@ -27,6 +27,7 @@
 #define PCI_ASSIGN_ALL_BUSSES	0x4000
 
 extern unsigned int pci_probe;
+extern unsigned long pirq_table_addr;
 
 /* pci-i386.c */
 
@@ -72,3 +73,4 @@ extern int pcibios_scanned;
 extern spinlock_t pci_config_lock;
 
 extern int (*pcibios_enable_irq)(struct pci_dev *dev);
+extern void (*pcibios_disable_irq)(struct pci_dev *dev);
diff --git a/arch/i386/pci/visws.c b/arch/i386/pci/visws.c
--- a/arch/i386/pci/visws.c
+++ b/arch/i386/pci/visws.c
@@ -18,10 +18,12 @@
 extern struct pci_raw_ops pci_direct_conf1;
 
 static int pci_visws_enable_irq(struct pci_dev *dev) { return 0; }
+static void pci_visws_disable_irq(struct pci_dev *dev) { }
 
 int (*pcibios_enable_irq)(struct pci_dev *dev) = &pci_visws_enable_irq;
+void (*pcibios_disable_irq)(struct pci_dev *dev) = &pci_visws_disable_irq;
 
-void __init pcibios_penalize_isa_irq(int irq) {}
+void __init pcibios_penalize_isa_irq(int irq, int active) {}
 
 
 unsigned int pci_bus0, pci_bus1;
diff --git a/arch/i386/power/cpu.c b/arch/i386/power/cpu.c
--- a/arch/i386/power/cpu.c
+++ b/arch/i386/power/cpu.c
@@ -22,9 +22,11 @@
 #include <linux/device.h>
 #include <linux/suspend.h>
 #include <linux/acpi.h>
+
 #include <asm/uaccess.h>
 #include <asm/acpi.h>
 #include <asm/tlbflush.h>
+#include <asm/processor.h>
 
 static struct saved_context saved_context;
 
@@ -33,8 +35,6 @@ unsigned long saved_context_esp, saved_c
 unsigned long saved_context_esi, saved_context_edi;
 unsigned long saved_context_eflags;
 
-extern void enable_sep_cpu(void *);
-
 void __save_processor_state(struct saved_context *ctxt)
 {
 	kernel_fpu_begin();
@@ -44,7 +44,6 @@ void __save_processor_state(struct saved
 	 */
 	asm volatile ("sgdt %0" : "=m" (ctxt->gdt_limit));
 	asm volatile ("sidt %0" : "=m" (ctxt->idt_limit));
-	asm volatile ("sldt %0" : "=m" (ctxt->ldt));
 	asm volatile ("str %0"  : "=m" (ctxt->tr));
 
 	/*
@@ -94,20 +93,19 @@ static void fix_processor_context(void)
 	 * 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);
+		set_debugreg(current->thread.debugreg[0], 0);
+		set_debugreg(current->thread.debugreg[1], 1);
+		set_debugreg(current->thread.debugreg[2], 2);
+		set_debugreg(current->thread.debugreg[3], 3);
+		/* no 4 and 5 */
+		set_debugreg(current->thread.debugreg[6], 6);
+		set_debugreg(current->thread.debugreg[7], 7);
 	}
 
 }
 
 void __restore_processor_state(struct saved_context *ctxt)
 {
-
 	/*
 	 * control registers
 	 */
@@ -117,6 +115,13 @@ void __restore_processor_state(struct sa
 	asm volatile ("movl %0, %%cr0" :: "r" (ctxt->cr0));
 
 	/*
+	 * now restore the descriptor tables to their proper values
+	 * ltr is done i fix_processor_context().
+	 */
+	asm volatile ("lgdt %0" :: "m" (ctxt->gdt_limit));
+	asm volatile ("lidt %0" :: "m" (ctxt->idt_limit));
+
+	/*
 	 * segment registers
 	 */
 	asm volatile ("movw %0, %%es" :: "r" (ctxt->es));
@@ -125,21 +130,14 @@ void __restore_processor_state(struct sa
 	asm volatile ("movw %0, %%ss" :: "r" (ctxt->ss));
 
 	/*
-	 * now restore the descriptor tables to their proper values
-	 * ltr is done i fix_processor_context().
-	 */
-	asm volatile ("lgdt %0" :: "m" (ctxt->gdt_limit));
-	asm volatile ("lidt %0" :: "m" (ctxt->idt_limit));
-	asm volatile ("lldt %0" :: "m" (ctxt->ldt));
-
-	/*
 	 * sysenter MSRs
 	 */
 	if (boot_cpu_has(X86_FEATURE_SEP))
-		enable_sep_cpu(NULL);
+		enable_sep_cpu();
 
 	fix_processor_context();
 	do_fpu_end();
+	mtrr_ap_init();
 }
 
 void restore_processor_state(void)
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
--- a/arch/ia64/Kconfig
+++ b/arch/ia64/Kconfig
@@ -50,6 +50,10 @@ config SCHED_NO_NO_OMIT_FRAME_POINTER
 	bool
 	default y
 
+config IA64_UNCACHED_ALLOCATOR
+	bool
+	select GENERIC_ALLOCATOR
+
 choice
 	prompt "System type"
 	default IA64_GENERIC
@@ -157,6 +161,8 @@ config IA64_PAGE_SIZE_64KB
 
 endchoice
 
+source kernel/Kconfig.hz
+
 config IA64_BRL_EMU
 	bool
 	depends on ITANIUM
@@ -193,7 +199,7 @@ config HOLES_IN_ZONE
 	bool
 	default y if VIRTUAL_MEM_MAP
 
-config DISCONTIGMEM
+config ARCH_DISCONTIGMEM_ENABLE
 	bool "Discontiguous memory support"
 	depends on (IA64_DIG || IA64_SGI_SN2 || IA64_GENERIC || IA64_HP_ZX1 || IA64_HP_ZX1_SWIOTLB) && NUMA && VIRTUAL_MEM_MAP
 	default y if (IA64_SGI_SN2 || IA64_GENERIC) && NUMA
@@ -214,16 +220,9 @@ config IOSAPIC
 	depends on !IA64_HP_SIM
 	default y
 
-config IA64_SGI_SN_SIM
-	bool "SGI Medusa Simulator Support"
-	depends on IA64_SGI_SN2
-	help
-	  If you are compiling a kernel that will run under SGI's IA-64
-	  simulator (Medusa) then say Y, otherwise say N.
-
 config IA64_SGI_SN_XP
 	tristate "Support communication between SGI SSIs"
-	depends on MSPEC
+	select IA64_UNCACHED_ALLOCATOR
 	help
 	  An SGI machine can be divided into multiple Single System
 	  Images which act independently of each other and have
@@ -296,6 +295,8 @@ config PREEMPT
           Say Y here if you are building a kernel for a desktop, embedded
           or real-time system.  Say N if you are unsure.
 
+source "mm/Kconfig"
+
 config HAVE_DEC_LOCK
 	bool
 	depends on (SMP || PREEMPT)
@@ -391,15 +392,8 @@ menu "Bus options (PCI, PCMCIA)"
 config PCI
 	bool "PCI support"
 	help
-	  Find out whether you have a PCI motherboard. PCI is the name of a
-	  bus system, i.e. the way the CPU talks to the other stuff inside
-	  your box. Other bus systems are ISA, EISA, MicroChannel (MCA) or
-	  VESA. If you have PCI, say Y, otherwise N.
-
-	  The PCI-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>, contains valuable
-	  information about which PCI hardware does work under Linux and which
-	  doesn't.
+	  Real IA-64 machines all have PCI/PCI-X/PCI Express busses.  Say Y
+	  here unless you are using a simulator without PCI support.
 
 config PCI_DOMAINS
 	bool
@@ -415,6 +409,8 @@ endmenu
 
 endif
 
+source "net/Kconfig"
+
 source "drivers/Kconfig"
 
 source "fs/Kconfig"
diff --git a/arch/ia64/Kconfig.debug b/arch/ia64/Kconfig.debug
--- a/arch/ia64/Kconfig.debug
+++ b/arch/ia64/Kconfig.debug
@@ -2,6 +2,17 @@ menu "Kernel hacking"
 
 source "lib/Kconfig.debug"
 
+config KPROBES
+        bool "Kprobes"
+        depends on DEBUG_KERNEL
+        help
+          Kprobes allows you to trap at almost any kernel address and
+          execute a callback function.  register_kprobe() establishes
+          a probepoint and specifies the callback.  Kprobes is useful
+          for kernel debugging, non-intrusive instrumentation and testing.
+          If in doubt, say "N".
+
+
 choice
 	prompt "Physical memory granularity"
 	default IA64_GRANULE_64MB
diff --git a/arch/ia64/configs/sn2_defconfig b/arch/ia64/configs/sn2_defconfig
--- a/arch/ia64/configs/sn2_defconfig
+++ b/arch/ia64/configs/sn2_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10
-# Mon Jan 10 13:57:35 2005
+# Linux kernel version: 2.6.13-rc6
+# Tue Aug 16 14:40:41 2005
 #
 
 #
@@ -10,6 +10,7 @@
 CONFIG_EXPERIMENTAL=y
 CONFIG_CLEAN_COMPILE=y
 CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
@@ -21,24 +22,26 @@ CONFIG_POSIX_MQUEUE=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=20
 CONFIG_HOTPLUG=y
 CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
+CONFIG_CPUSETS=y
 # CONFIG_EMBEDDED is not set
 CONFIG_KALLSYMS=y
 CONFIG_KALLSYMS_ALL=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-CONFIG_CPUSETS=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
 # CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
 
 #
 # Loadable module support
@@ -63,9 +66,12 @@ CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_TIME_INTERPOLATION=y
 CONFIG_EFI=y
 CONFIG_GENERIC_IOMAP=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_IA64_UNCACHED_ALLOCATOR=y
 # CONFIG_IA64_GENERIC is not set
 # CONFIG_IA64_DIG is not set
 # CONFIG_IA64_HP_ZX1 is not set
+# CONFIG_IA64_HP_ZX1_SWIOTLB is not set
 CONFIG_IA64_SGI_SN2=y
 # CONFIG_IA64_HP_SIM is not set
 # CONFIG_ITANIUM is not set
@@ -74,19 +80,31 @@ CONFIG_MCKINLEY=y
 # CONFIG_IA64_PAGE_SIZE_8KB is not set
 CONFIG_IA64_PAGE_SIZE_16KB=y
 # CONFIG_IA64_PAGE_SIZE_64KB is not set
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
 CONFIG_IA64_L1_CACHE_SHIFT=7
 CONFIG_NUMA=y
 CONFIG_VIRTUAL_MEM_MAP=y
 CONFIG_HOLES_IN_ZONE=y
-CONFIG_DISCONTIGMEM=y
+CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
 # CONFIG_IA64_CYCLONE is not set
 CONFIG_IOSAPIC=y
-CONFIG_IA64_SGI_SN_SIM=y
+CONFIG_IA64_SGI_SN_XP=m
 CONFIG_FORCE_MAX_ZONEORDER=18
 CONFIG_SMP=y
 CONFIG_NR_CPUS=512
 # CONFIG_HOTPLUG_CPU is not set
+CONFIG_SCHED_SMT=y
 CONFIG_PREEMPT=y
+CONFIG_SELECT_MEMORY_MODEL=y
+# CONFIG_FLATMEM_MANUAL is not set
+CONFIG_DISCONTIGMEM_MANUAL=y
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_DISCONTIGMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_NEED_MULTIPLE_NODES=y
 CONFIG_HAVE_DEC_LOCK=y
 CONFIG_IA32_SUPPORT=y
 CONFIG_COMPAT=y
@@ -99,13 +117,14 @@ CONFIG_ACPI_DEALLOCATE_IRQ=y
 # Firmware Drivers
 #
 CONFIG_EFI_VARS=y
-# CONFIG_EFI_PCDP is not set
+CONFIG_EFI_PCDP=y
 CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
 
 #
 # Power management and ACPI
 #
+CONFIG_PM=y
 CONFIG_ACPI=y
 
 #
@@ -115,6 +134,7 @@ CONFIG_ACPI_BOOT=y
 CONFIG_ACPI_INTERPRETER=y
 # CONFIG_ACPI_BUTTON is not set
 CONFIG_ACPI_VIDEO=m
+CONFIG_ACPI_HOTKEY=m
 # CONFIG_ACPI_FAN is not set
 # CONFIG_ACPI_PROCESSOR is not set
 CONFIG_ACPI_NUMA=y
@@ -134,6 +154,7 @@ CONFIG_PCI_DOMAINS=y
 # CONFIG_PCI_MSI is not set
 CONFIG_PCI_LEGACY_PROC=y
 CONFIG_PCI_NAMES=y
+# CONFIG_PCI_DEBUG is not set
 
 #
 # PCI Hotplug Support
@@ -142,7 +163,6 @@ CONFIG_HOTPLUG_PCI=y
 # CONFIG_HOTPLUG_PCI_FAKE is not set
 # CONFIG_HOTPLUG_PCI_ACPI is not set
 # CONFIG_HOTPLUG_PCI_CPCI is not set
-# CONFIG_HOTPLUG_PCI_PCIE is not set
 # CONFIG_HOTPLUG_PCI_SHPC is not set
 CONFIG_HOTPLUG_PCI_SGI=y
 
@@ -152,8 +172,70 @@ CONFIG_HOTPLUG_PCI_SGI=y
 # CONFIG_PCCARD is not set
 
 #
-# PC-card bridges
+# Networking
 #
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_IP_TCPDIAG=y
+# CONFIG_IP_TCPDIAG_IPV6 is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+CONFIG_IPV6=m
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_IPV6_TUNNEL is not set
+# CONFIG_NETFILTER is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
 
 #
 # Device Drivers
@@ -164,7 +246,7 @@ CONFIG_HOTPLUG_PCI_SGI=y
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-CONFIG_FW_LOADER=m
+CONFIG_FW_LOADER=y
 # CONFIG_DEBUG_DRIVER is not set
 
 #
@@ -189,6 +271,7 @@ CONFIG_FW_LOADER=m
 # CONFIG_BLK_CPQ_CISS_DA is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_CRYPTOLOOP=m
 CONFIG_BLK_DEV_NBD=m
@@ -253,6 +336,7 @@ CONFIG_IDEDMA_PCI_AUTO=y
 # CONFIG_BLK_DEV_HPT366 is not set
 # CONFIG_BLK_DEV_SC1200 is not set
 # CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_BLK_DEV_IT821X is not set
 # CONFIG_BLK_DEV_NS87415 is not set
 # CONFIG_BLK_DEV_PDC202XX_OLD is not set
 # CONFIG_BLK_DEV_PDC202XX_NEW is not set
@@ -283,6 +367,7 @@ CONFIG_CHR_DEV_ST=m
 CONFIG_BLK_DEV_SR=m
 # CONFIG_BLK_DEV_SR_VENDOR is not set
 CONFIG_CHR_DEV_SG=m
+CONFIG_CHR_DEV_SCH=m
 
 #
 # Some SCSI devices (e.g. CD jukebox) support multiple LUNs
@@ -316,24 +401,20 @@ CONFIG_SCSI_SATA=y
 # CONFIG_SCSI_ATA_PIIX is not set
 # CONFIG_SCSI_SATA_NV is not set
 # CONFIG_SCSI_SATA_PROMISE is not set
+# CONFIG_SCSI_SATA_QSTOR is not set
 # CONFIG_SCSI_SATA_SX4 is not set
 # CONFIG_SCSI_SATA_SIL is not set
 # CONFIG_SCSI_SATA_SIS is not set
 # CONFIG_SCSI_SATA_ULI is not set
 # CONFIG_SCSI_SATA_VIA is not set
 CONFIG_SCSI_SATA_VITESSE=y
-# CONFIG_SCSI_BUSLOGIC is not set
 # CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_EATA_PIO is not set
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_GDTH is not set
 # CONFIG_SCSI_IPS is not set
 # CONFIG_SCSI_INITIO is not set
 # CONFIG_SCSI_INIA100 is not set
 # CONFIG_SCSI_SYM53C8XX_2 is not set
 # CONFIG_SCSI_IPR is not set
-# CONFIG_SCSI_QLOGIC_ISP is not set
 # CONFIG_SCSI_QLOGIC_FC is not set
 CONFIG_SCSI_QLOGIC_1280=y
 # CONFIG_SCSI_QLOGIC_1280_1040 is not set
@@ -343,6 +424,8 @@ CONFIG_SCSI_QLA22XX=y
 CONFIG_SCSI_QLA2300=y
 CONFIG_SCSI_QLA2322=y
 # CONFIG_SCSI_QLA6312 is not set
+# CONFIG_SCSI_QLA24XX is not set
+# CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_DEBUG is not set
@@ -365,11 +448,15 @@ CONFIG_DM_CRYPT=m
 CONFIG_DM_SNAPSHOT=m
 CONFIG_DM_MIRROR=m
 CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_DM_MULTIPATH_EMC=m
 
 #
 # Fusion MPT device support
 #
 CONFIG_FUSION=y
+CONFIG_FUSION_SPI=y
+CONFIG_FUSION_FC=y
 CONFIG_FUSION_MAX_SGE=128
 CONFIG_FUSION_CTL=m
 
@@ -384,82 +471,13 @@ CONFIG_FUSION_CTL=m
 # CONFIG_I2O is not set
 
 #
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
+# Network device support
 #
-CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
-CONFIG_NETLINK_DEV=y
-CONFIG_UNIX=y
-# CONFIG_NET_KEY is not set
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-# CONFIG_IP_PNP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
-# CONFIG_ARPD is not set
-CONFIG_SYN_COOKIES=y
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_TUNNEL is not set
-CONFIG_IP_TCPDIAG=y
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-CONFIG_IPV6=m
-# CONFIG_IPV6_PRIVACY is not set
-# CONFIG_INET6_AH is not set
-# CONFIG_INET6_ESP is not set
-# CONFIG_INET6_IPCOMP is not set
-# CONFIG_INET6_TUNNEL is not set
-# CONFIG_IPV6_TUNNEL is not set
-# CONFIG_NETFILTER is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-CONFIG_NETPOLL=y
-# CONFIG_NETPOLL_RX is not set
-# CONFIG_NETPOLL_TRAP is not set
-CONFIG_NET_POLL_CONTROLLER=y
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
 CONFIG_NETDEVICES=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
 
 #
 # ARCnet devices
@@ -481,8 +499,10 @@ CONFIG_NETDEVICES=y
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
 # CONFIG_R8169 is not set
+# CONFIG_SKGE is not set
 # CONFIG_SK98LIN is not set
 CONFIG_TIGON3=y
+# CONFIG_BNX2 is not set
 
 #
 # Ethernet (10000 Mbit)
@@ -513,6 +533,10 @@ CONFIG_S2IO=m
 # CONFIG_NET_FC is not set
 # CONFIG_SHAPER is not set
 CONFIG_NETCONSOLE=y
+CONFIG_NETPOLL=y
+# CONFIG_NETPOLL_RX is not set
+# CONFIG_NETPOLL_TRAP is not set
+CONFIG_NET_POLL_CONTROLLER=y
 
 #
 # ISDN subsystem
@@ -542,14 +566,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 # CONFIG_INPUT_EVBUG is not set
 
 #
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-# CONFIG_SERIO is not set
-# CONFIG_SERIO_I8042 is not set
-
-#
 # Input Device Drivers
 #
 # CONFIG_INPUT_KEYBOARD is not set
@@ -559,6 +575,12 @@ CONFIG_SOUND_GAMEPORT=y
 # CONFIG_INPUT_MISC is not set
 
 #
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
 # Character devices
 #
 CONFIG_VT=y
@@ -569,9 +591,10 @@ CONFIG_SERIAL_NONSTANDARD=y
 # CONFIG_CYCLADES is not set
 # CONFIG_MOXA_SMARTIO is not set
 # CONFIG_ISI is not set
-# CONFIG_SYNCLINK is not set
 # CONFIG_SYNCLINKMP is not set
 # CONFIG_N_HDLC is not set
+# CONFIG_SPECIALIX is not set
+# CONFIG_SX is not set
 # CONFIG_STALDRV is not set
 CONFIG_SGI_SNSC=y
 CONFIG_SGI_TIOCX=y
@@ -588,6 +611,8 @@ CONFIG_SGI_MBCS=m
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_SERIAL_SGI_L1_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+CONFIG_SERIAL_SGI_IOC4=y
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -615,12 +640,19 @@ CONFIG_EFI_RTC=y
 CONFIG_RAW_DRIVER=m
 # CONFIG_HPET is not set
 CONFIG_MAX_RAW_DEVS=256
+# CONFIG_HANGCHECK_TIMER is not set
 CONFIG_MMTIMER=y
 
 #
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
 # I2C support
 #
 # CONFIG_I2C is not set
+# CONFIG_I2C_SENSOR is not set
 
 #
 # Dallas's 1-wire bus
@@ -628,6 +660,11 @@ CONFIG_MMTIMER=y
 # CONFIG_W1 is not set
 
 #
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+
+#
 # Misc devices
 #
 
@@ -649,7 +686,7 @@ CONFIG_MMTIMER=y
 #
 # Console display driver support
 #
-# CONFIG_VGA_CONSOLE is not set
+CONFIG_VGA_CONSOLE=y
 CONFIG_DUMMY_CONSOLE=y
 
 #
@@ -660,6 +697,8 @@ CONFIG_DUMMY_CONSOLE=y
 #
 # USB support
 #
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
 CONFIG_USB=m
 # CONFIG_USB_DEBUG is not set
 
@@ -669,9 +708,8 @@ CONFIG_USB=m
 # CONFIG_USB_DEVICEFS is not set
 # CONFIG_USB_BANDWIDTH is not set
 # CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_SUSPEND is not set
 # CONFIG_USB_OTG is not set
-CONFIG_USB_ARCH_HAS_HCD=y
-CONFIG_USB_ARCH_HAS_OHCI=y
 
 #
 # USB Host Controller Drivers
@@ -679,7 +717,10 @@ CONFIG_USB_ARCH_HAS_OHCI=y
 CONFIG_USB_EHCI_HCD=m
 # CONFIG_USB_EHCI_SPLIT_ISO is not set
 # CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+# CONFIG_USB_ISP116X_HCD is not set
 CONFIG_USB_OHCI_HCD=m
+# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 CONFIG_USB_UHCI_HCD=m
 # CONFIG_USB_SL811_HCD is not set
 
@@ -710,12 +751,15 @@ CONFIG_USB_HIDINPUT=y
 # CONFIG_USB_MOUSE is not set
 # CONFIG_USB_AIPTEK is not set
 # CONFIG_USB_WACOM is not set
+# CONFIG_USB_ACECAD is not set
 # CONFIG_USB_KBTAB is not set
 # CONFIG_USB_POWERMATE is not set
 # CONFIG_USB_MTOUCH is not set
+# CONFIG_USB_ITMTOUCH is not set
 # CONFIG_USB_EGALAX is not set
 # CONFIG_USB_XPAD is not set
 # CONFIG_USB_ATI_REMOTE is not set
+# CONFIG_USB_KEYSPAN_REMOTE is not set
 
 #
 # USB Imaging devices
@@ -740,6 +784,7 @@ CONFIG_USB_HIDINPUT=y
 # CONFIG_USB_PEGASUS is not set
 # CONFIG_USB_RTL8150 is not set
 # CONFIG_USB_USBNET is not set
+CONFIG_USB_MON=y
 
 #
 # USB port drivers
@@ -763,9 +808,12 @@ CONFIG_USB_HIDINPUT=y
 # CONFIG_USB_CYTHERM is not set
 # CONFIG_USB_PHIDGETKIT is not set
 # CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
 
 #
-# USB ATM/DSL drivers
+# USB DSL modem support
 #
 
 #
@@ -782,18 +830,25 @@ CONFIG_USB_HIDINPUT=y
 # InfiniBand support
 #
 CONFIG_INFINIBAND=m
+CONFIG_INFINIBAND_USER_VERBS=m
 CONFIG_INFINIBAND_MTHCA=m
 # CONFIG_INFINIBAND_MTHCA_DEBUG is not set
 CONFIG_INFINIBAND_IPOIB=m
 # CONFIG_INFINIBAND_IPOIB_DEBUG is not set
 
 #
+# SN Devices
+#
+CONFIG_SGI_IOC4=y
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
 CONFIG_EXT2_FS_XATTR=y
 CONFIG_EXT2_FS_POSIX_ACL=y
 CONFIG_EXT2_FS_SECURITY=y
+# CONFIG_EXT2_FS_XIP is not set
 CONFIG_EXT3_FS=y
 CONFIG_EXT3_FS_XATTR=y
 CONFIG_EXT3_FS_POSIX_ACL=y
@@ -809,13 +864,19 @@ CONFIG_REISERFS_FS_POSIX_ACL=y
 CONFIG_REISERFS_FS_SECURITY=y
 # CONFIG_JFS_FS is not set
 CONFIG_FS_POSIX_ACL=y
+
+#
+# XFS support
+#
 CONFIG_XFS_FS=y
+CONFIG_XFS_EXPORT=y
 CONFIG_XFS_RT=y
 CONFIG_XFS_QUOTA=y
 # CONFIG_XFS_SECURITY is not set
 CONFIG_XFS_POSIX_ACL=y
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
 CONFIG_QUOTA=y
 # CONFIG_QFMT_V1 is not set
 # CONFIG_QFMT_V2 is not set
@@ -849,7 +910,6 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
 CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
 # CONFIG_DEVPTS_FS_XATTR is not set
 CONFIG_TMPFS=y
 CONFIG_TMPFS_XATTR=y
@@ -880,15 +940,18 @@ CONFIG_RAMFS=y
 #
 CONFIG_NFS_FS=m
 CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
 CONFIG_NFS_V4=y
 CONFIG_NFS_DIRECTIO=y
 CONFIG_NFSD=m
 CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
 CONFIG_NFSD_V4=y
 CONFIG_NFSD_TCP=y
 CONFIG_LOCKD=m
 CONFIG_LOCKD_V4=y
-CONFIG_EXPORTFS=m
+CONFIG_EXPORTFS=y
+CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=m
 CONFIG_SUNRPC_GSS=m
 CONFIG_RPCSEC_GSS_KRB5=m
@@ -975,6 +1038,9 @@ CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=m
 CONFIG_ZLIB_DEFLATE=m
+CONFIG_GENERIC_ALLOCATOR=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
 
 #
 # Profiling support
@@ -984,15 +1050,19 @@ CONFIG_ZLIB_DEFLATE=m
 #
 # Kernel hacking
 #
+# CONFIG_PRINTK_TIME is not set
 CONFIG_DEBUG_KERNEL=y
 CONFIG_MAGIC_SYSRQ=y
+CONFIG_LOG_BUF_SHIFT=20
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_DEBUG_SLAB is not set
+CONFIG_DEBUG_PREEMPT=y
 # CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_KOBJECT is not set
 CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_FS is not set
+# CONFIG_KPROBES is not set
 CONFIG_IA64_GRANULE_16MB=y
 # CONFIG_IA64_GRANULE_64MB is not set
 # CONFIG_IA64_PRINT_HAZARDS is not set
@@ -1014,11 +1084,12 @@ CONFIG_CRYPTO=y
 CONFIG_CRYPTO_HMAC=y
 # CONFIG_CRYPTO_NULL is not set
 # CONFIG_CRYPTO_MD4 is not set
-CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_MD5=y
 CONFIG_CRYPTO_SHA1=m
 # CONFIG_CRYPTO_SHA256 is not set
 # CONFIG_CRYPTO_SHA512 is not set
 # CONFIG_CRYPTO_WP512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
 CONFIG_CRYPTO_DES=m
 # CONFIG_CRYPTO_BLOWFISH is not set
 # CONFIG_CRYPTO_TWOFISH is not set
diff --git a/arch/ia64/configs/tiger_defconfig b/arch/ia64/configs/tiger_defconfig
--- a/arch/ia64/configs/tiger_defconfig
+++ b/arch/ia64/configs/tiger_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc3
-# Tue May  3 15:55:04 2005
+# Linux kernel version: 2.6.13-rc6-tiger-smp
+# Wed Aug 17 10:19:51 2005
 #
 
 #
@@ -67,6 +67,7 @@ CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_TIME_INTERPOLATION=y
 CONFIG_EFI=y
 CONFIG_GENERIC_IOMAP=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
 # CONFIG_IA64_GENERIC is not set
 CONFIG_IA64_DIG=y
 # CONFIG_IA64_HP_ZX1 is not set
@@ -79,18 +80,29 @@ CONFIG_MCKINLEY=y
 # CONFIG_IA64_PAGE_SIZE_8KB is not set
 CONFIG_IA64_PAGE_SIZE_16KB=y
 # CONFIG_IA64_PAGE_SIZE_64KB is not set
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
 CONFIG_IA64_L1_CACHE_SHIFT=7
 # CONFIG_NUMA is not set
 CONFIG_VIRTUAL_MEM_MAP=y
 CONFIG_HOLES_IN_ZONE=y
 CONFIG_IA64_CYCLONE=y
 CONFIG_IOSAPIC=y
+# CONFIG_IA64_SGI_SN_XP is not set
 CONFIG_FORCE_MAX_ZONEORDER=18
 CONFIG_SMP=y
 CONFIG_NR_CPUS=4
 CONFIG_HOTPLUG_CPU=y
 # CONFIG_SCHED_SMT is not set
 # CONFIG_PREEMPT is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_HAVE_DEC_LOCK=y
 CONFIG_IA32_SUPPORT=y
 CONFIG_COMPAT=y
@@ -120,6 +132,7 @@ CONFIG_ACPI_BOOT=y
 CONFIG_ACPI_INTERPRETER=y
 CONFIG_ACPI_BUTTON=m
 # CONFIG_ACPI_VIDEO is not set
+# CONFIG_ACPI_HOTKEY is not set
 CONFIG_ACPI_FAN=m
 CONFIG_ACPI_PROCESSOR=m
 # CONFIG_ACPI_HOTPLUG_CPU is not set
@@ -158,6 +171,66 @@ CONFIG_HOTPLUG_PCI_ACPI=m
 # CONFIG_PCCARD is not set
 
 #
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+CONFIG_ARPD=y
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_IP_TCPDIAG=y
+# CONFIG_IP_TCPDIAG_IPV6 is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+
+#
 # Device Drivers
 #
 
@@ -166,7 +239,7 @@ CONFIG_HOTPLUG_PCI_ACPI=m
 #
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+CONFIG_FW_LOADER=m
 # CONFIG_DEBUG_DRIVER is not set
 
 #
@@ -256,6 +329,7 @@ CONFIG_BLK_DEV_CMD64X=y
 # CONFIG_BLK_DEV_HPT366 is not set
 # CONFIG_BLK_DEV_SC1200 is not set
 CONFIG_BLK_DEV_PIIX=y
+# CONFIG_BLK_DEV_IT821X is not set
 # CONFIG_BLK_DEV_NS87415 is not set
 # CONFIG_BLK_DEV_PDC202XX_OLD is not set
 # CONFIG_BLK_DEV_PDC202XX_NEW is not set
@@ -285,6 +359,7 @@ CONFIG_CHR_DEV_ST=m
 CONFIG_BLK_DEV_SR=m
 # CONFIG_BLK_DEV_SR_VENDOR is not set
 CONFIG_CHR_DEV_SG=m
+# CONFIG_CHR_DEV_SCH is not set
 
 #
 # Some SCSI devices (e.g. CD jukebox) support multiple LUNs
@@ -313,11 +388,8 @@ CONFIG_SCSI_FC_ATTRS=y
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
 # CONFIG_SCSI_SATA is not set
-# CONFIG_SCSI_BUSLOGIC is not set
 # CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_EATA is not set
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_GDTH is not set
 # CONFIG_SCSI_IPS is not set
 # CONFIG_SCSI_INITIO is not set
 # CONFIG_SCSI_INIA100 is not set
@@ -337,6 +409,7 @@ CONFIG_SCSI_QLA22XX=m
 CONFIG_SCSI_QLA2300=m
 CONFIG_SCSI_QLA2322=m
 # CONFIG_SCSI_QLA6312 is not set
+# CONFIG_SCSI_QLA24XX is not set
 # CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
@@ -366,8 +439,10 @@ CONFIG_DM_ZERO=m
 # Fusion MPT device support
 #
 CONFIG_FUSION=y
-CONFIG_FUSION_MAX_SGE=40
-# CONFIG_FUSION_CTL is not set
+CONFIG_FUSION_SPI=y
+CONFIG_FUSION_FC=y
+CONFIG_FUSION_MAX_SGE=128
+CONFIG_FUSION_CTL=y
 
 #
 # IEEE 1394 (FireWire) support
@@ -380,69 +455,8 @@ CONFIG_FUSION_MAX_SGE=40
 # CONFIG_I2O is not set
 
 #
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-CONFIG_UNIX=y
-# CONFIG_NET_KEY is not set
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-# CONFIG_IP_PNP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
-CONFIG_ARPD=y
-CONFIG_SYN_COOKIES=y
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_TUNNEL is not set
-CONFIG_IP_TCPDIAG=y
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
+# Network device support
 #
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-CONFIG_NETPOLL=y
-# CONFIG_NETPOLL_RX is not set
-# CONFIG_NETPOLL_TRAP is not set
-CONFIG_NET_POLL_CONTROLLER=y
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
 CONFIG_NETDEVICES=y
 CONFIG_DUMMY=m
 # CONFIG_BONDING is not set
@@ -506,9 +520,11 @@ CONFIG_E1000=y
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
 # CONFIG_R8169 is not set
+# CONFIG_SKGE is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_VIA_VELOCITY is not set
 CONFIG_TIGON3=y
+# CONFIG_BNX2 is not set
 
 #
 # Ethernet (10000 Mbit)
@@ -537,6 +553,10 @@ CONFIG_TIGON3=y
 # CONFIG_NET_FC is not set
 # CONFIG_SHAPER is not set
 CONFIG_NETCONSOLE=y
+CONFIG_NETPOLL=y
+# CONFIG_NETPOLL_RX is not set
+# CONFIG_NETPOLL_TRAP is not set
+CONFIG_NET_POLL_CONTROLLER=y
 
 #
 # ISDN subsystem
@@ -595,10 +615,7 @@ CONFIG_GAMEPORT=m
 # CONFIG_GAMEPORT_NS558 is not set
 # CONFIG_GAMEPORT_L4 is not set
 # CONFIG_GAMEPORT_EMU10K1 is not set
-# CONFIG_GAMEPORT_VORTEX is not set
 # CONFIG_GAMEPORT_FM801 is not set
-# CONFIG_GAMEPORT_CS461X is not set
-CONFIG_SOUND_GAMEPORT=m
 
 #
 # Character devices
@@ -611,7 +628,6 @@ CONFIG_SERIAL_NONSTANDARD=y
 # CONFIG_CYCLADES is not set
 # CONFIG_MOXA_SMARTIO is not set
 # CONFIG_ISI is not set
-# CONFIG_SYNCLINK is not set
 # CONFIG_SYNCLINKMP is not set
 # CONFIG_N_HDLC is not set
 # CONFIG_SPECIALIX is not set
@@ -628,7 +644,6 @@ CONFIG_SERIAL_8250_NR_UARTS=6
 CONFIG_SERIAL_8250_EXTENDED=y
 CONFIG_SERIAL_8250_SHARE_IRQ=y
 # CONFIG_SERIAL_8250_DETECT_IRQ is not set
-# CONFIG_SERIAL_8250_MULTIPORT is not set
 # CONFIG_SERIAL_8250_RSA is not set
 
 #
@@ -667,6 +682,7 @@ CONFIG_DRM_R128=m
 CONFIG_DRM_RADEON=m
 CONFIG_DRM_MGA=m
 CONFIG_DRM_SIS=m
+# CONFIG_DRM_VIA is not set
 CONFIG_RAW_DRIVER=m
 CONFIG_HPET=y
 # CONFIG_HPET_RTC_IRQ is not set
@@ -683,6 +699,7 @@ CONFIG_MAX_RAW_DEVS=256
 # I2C support
 #
 # CONFIG_I2C is not set
+# CONFIG_I2C_SENSOR is not set
 
 #
 # Dallas's 1-wire bus
@@ -690,6 +707,12 @@ CONFIG_MAX_RAW_DEVS=256
 # CONFIG_W1 is not set
 
 #
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
 # Misc devices
 #
 
@@ -742,6 +765,7 @@ CONFIG_USB_DEVICEFS=y
 CONFIG_USB_EHCI_HCD=m
 # CONFIG_USB_EHCI_SPLIT_ISO is not set
 # CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+# CONFIG_USB_ISP116X_HCD is not set
 CONFIG_USB_OHCI_HCD=m
 # CONFIG_USB_OHCI_BIG_ENDIAN is not set
 CONFIG_USB_OHCI_LITTLE_ENDIAN=y
@@ -778,12 +802,15 @@ CONFIG_USB_HIDINPUT=y
 # CONFIG_USB_HIDDEV is not set
 # CONFIG_USB_AIPTEK is not set
 # CONFIG_USB_WACOM is not set
+# CONFIG_USB_ACECAD is not set
 # CONFIG_USB_KBTAB is not set
 # CONFIG_USB_POWERMATE is not set
 # CONFIG_USB_MTOUCH is not set
+# CONFIG_USB_ITMTOUCH is not set
 # CONFIG_USB_EGALAX is not set
 # CONFIG_USB_XPAD is not set
 # CONFIG_USB_ATI_REMOTE is not set
+# CONFIG_USB_KEYSPAN_REMOTE is not set
 
 #
 # USB Imaging devices
@@ -834,10 +861,11 @@ CONFIG_USB_HIDINPUT=y
 # CONFIG_USB_PHIDGETSERVO is not set
 # CONFIG_USB_IDMOUSE is not set
 # CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
 # CONFIG_USB_TEST is not set
 
 #
-# USB ATM/DSL drivers
+# USB DSL modem support
 #
 
 #
@@ -856,12 +884,17 @@ CONFIG_USB_HIDINPUT=y
 # CONFIG_INFINIBAND is not set
 
 #
+# SN Devices
+#
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
 CONFIG_EXT2_FS_XATTR=y
 CONFIG_EXT2_FS_POSIX_ACL=y
 CONFIG_EXT2_FS_SECURITY=y
+# CONFIG_EXT2_FS_XIP is not set
 CONFIG_EXT3_FS=y
 CONFIG_EXT3_FS_XATTR=y
 CONFIG_EXT3_FS_POSIX_ACL=y
@@ -889,6 +922,7 @@ CONFIG_XFS_EXPORT=y
 # CONFIG_XFS_POSIX_ACL is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
 # CONFIG_QUOTA is not set
 CONFIG_DNOTIFY=y
 CONFIG_AUTOFS_FS=y
@@ -921,7 +955,6 @@ CONFIG_NTFS_FS=m
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
 CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
 # CONFIG_DEVPTS_FS_XATTR is not set
 CONFIG_TMPFS=y
 CONFIG_TMPFS_XATTR=y
@@ -952,15 +985,18 @@ CONFIG_RAMFS=y
 #
 CONFIG_NFS_FS=m
 CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
 CONFIG_NFS_V4=y
 CONFIG_NFS_DIRECTIO=y
 CONFIG_NFSD=m
 CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
 CONFIG_NFSD_V4=y
 CONFIG_NFSD_TCP=y
 CONFIG_LOCKD=m
 CONFIG_LOCKD_V4=y
 CONFIG_EXPORTFS=y
+CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=m
 CONFIG_SUNRPC_GSS=m
 CONFIG_RPCSEC_GSS_KRB5=m
@@ -1068,6 +1104,7 @@ CONFIG_LOG_BUF_SHIFT=20
 # CONFIG_DEBUG_KOBJECT is not set
 # CONFIG_DEBUG_INFO is not set
 # CONFIG_DEBUG_FS is not set
+# CONFIG_KPROBES is not set
 CONFIG_IA64_GRANULE_16MB=y
 # CONFIG_IA64_GRANULE_64MB is not set
 # CONFIG_IA64_PRINT_HAZARDS is not set
@@ -1089,7 +1126,7 @@ CONFIG_CRYPTO=y
 # CONFIG_CRYPTO_HMAC is not set
 # CONFIG_CRYPTO_NULL is not set
 # CONFIG_CRYPTO_MD4 is not set
-CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_MD5=y
 # CONFIG_CRYPTO_SHA1 is not set
 # CONFIG_CRYPTO_SHA256 is not set
 # CONFIG_CRYPTO_SHA512 is not set
diff --git a/arch/ia64/configs/zx1_defconfig b/arch/ia64/configs/zx1_defconfig
--- a/arch/ia64/configs/zx1_defconfig
+++ b/arch/ia64/configs/zx1_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10
-# Wed Dec 29 09:05:48 2004
+# Linux kernel version: 2.6.13-rc6
+# Wed Aug 17 10:02:43 2005
 #
 
 #
@@ -12,6 +12,7 @@ CONFIG_EXPERIMENTAL=y
 CONFIG_BROKEN=y
 CONFIG_BROKEN_ON_SMP=y
 CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
@@ -24,23 +25,26 @@ CONFIG_BSD_PROCESS_ACCT=y
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=17
 CONFIG_HOTPLUG=y
 CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
+# CONFIG_CPUSETS is not set
 # CONFIG_EMBEDDED is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
 # CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
 
 #
 # Loadable module support
@@ -59,12 +63,15 @@ CONFIG_IA64=y
 CONFIG_64BIT=y
 CONFIG_MMU=y
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_TIME_INTERPOLATION=y
 CONFIG_EFI=y
 CONFIG_GENERIC_IOMAP=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
 # CONFIG_IA64_GENERIC is not set
 # CONFIG_IA64_DIG is not set
 CONFIG_IA64_HP_ZX1=y
+# CONFIG_IA64_HP_ZX1_SWIOTLB is not set
 # CONFIG_IA64_SGI_SN2 is not set
 # CONFIG_IA64_HP_SIM is not set
 # CONFIG_ITANIUM is not set
@@ -73,22 +80,36 @@ CONFIG_MCKINLEY=y
 # CONFIG_IA64_PAGE_SIZE_8KB is not set
 CONFIG_IA64_PAGE_SIZE_16KB=y
 # CONFIG_IA64_PAGE_SIZE_64KB is not set
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
 CONFIG_IA64_L1_CACHE_SHIFT=7
 # CONFIG_NUMA is not set
 CONFIG_VIRTUAL_MEM_MAP=y
+CONFIG_HOLES_IN_ZONE=y
 # CONFIG_IA64_CYCLONE is not set
 CONFIG_IOSAPIC=y
+# CONFIG_IA64_SGI_SN_XP is not set
 CONFIG_FORCE_MAX_ZONEORDER=18
 CONFIG_SMP=y
 CONFIG_NR_CPUS=16
 # CONFIG_HOTPLUG_CPU is not set
+# CONFIG_SCHED_SMT is not set
 # CONFIG_PREEMPT is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_HAVE_DEC_LOCK=y
 CONFIG_IA32_SUPPORT=y
 CONFIG_COMPAT=y
 CONFIG_IA64_MCA_RECOVERY=y
 CONFIG_PERFMON=y
 CONFIG_IA64_PALINFO=y
+CONFIG_ACPI_DEALLOCATE_IRQ=y
 
 #
 # Firmware Drivers
@@ -111,6 +132,7 @@ CONFIG_ACPI_BOOT=y
 CONFIG_ACPI_INTERPRETER=y
 CONFIG_ACPI_BUTTON=y
 CONFIG_ACPI_VIDEO=m
+CONFIG_ACPI_HOTKEY=m
 CONFIG_ACPI_FAN=y
 CONFIG_ACPI_PROCESSOR=y
 CONFIG_ACPI_THERMAL=y
@@ -120,6 +142,7 @@ CONFIG_ACPI_BUS=y
 CONFIG_ACPI_POWER=y
 CONFIG_ACPI_PCI=y
 CONFIG_ACPI_SYSTEM=y
+# CONFIG_ACPI_CONTAINER is not set
 
 #
 # Bus options (PCI, PCMCIA)
@@ -129,6 +152,7 @@ CONFIG_PCI_DOMAINS=y
 # CONFIG_PCI_MSI is not set
 CONFIG_PCI_LEGACY_PROC=y
 CONFIG_PCI_NAMES=y
+# CONFIG_PCI_DEBUG is not set
 
 #
 # PCI Hotplug Support
@@ -138,7 +162,6 @@ CONFIG_HOTPLUG_PCI=y
 CONFIG_HOTPLUG_PCI_ACPI=y
 # CONFIG_HOTPLUG_PCI_ACPI_IBM is not set
 # CONFIG_HOTPLUG_PCI_CPCI is not set
-# CONFIG_HOTPLUG_PCI_PCIE is not set
 # CONFIG_HOTPLUG_PCI_SHPC is not set
 
 #
@@ -147,8 +170,81 @@ CONFIG_HOTPLUG_PCI_ACPI=y
 # CONFIG_PCCARD is not set
 
 #
-# PC-card bridges
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_TUNNEL is not set
+# CONFIG_IP_TCPDIAG is not set
+# CONFIG_IP_TCPDIAG_IPV6 is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS is not set
+# CONFIG_IPV6 is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+
+#
+# IP: Netfilter Configuration
 #
+# CONFIG_IP_NF_CONNTRACK is not set
+# CONFIG_IP_NF_CONNTRACK_MARK is not set
+# CONFIG_IP_NF_QUEUE is not set
+# CONFIG_IP_NF_IPTABLES is not set
+CONFIG_IP_NF_ARPTABLES=y
+# CONFIG_IP_NF_ARPFILTER is not set
+# CONFIG_IP_NF_ARP_MANGLE is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
 
 #
 # Device Drivers
@@ -184,6 +280,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_BLK_CPQ_CISS_DA is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
@@ -203,6 +300,7 @@ CONFIG_IOSCHED_NOOP=y
 CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
+# CONFIG_ATA_OVER_ETH is not set
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -246,6 +344,7 @@ CONFIG_BLK_DEV_CMD64X=y
 # CONFIG_BLK_DEV_HPT366 is not set
 # CONFIG_BLK_DEV_SC1200 is not set
 # CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_BLK_DEV_IT821X is not set
 # CONFIG_BLK_DEV_NS87415 is not set
 # CONFIG_BLK_DEV_PDC202XX_OLD is not set
 # CONFIG_BLK_DEV_PDC202XX_NEW is not set
@@ -275,6 +374,7 @@ CONFIG_CHR_DEV_OSST=y
 CONFIG_BLK_DEV_SR=y
 CONFIG_BLK_DEV_SR_VENDOR=y
 CONFIG_CHR_DEV_SG=y
+# CONFIG_CHR_DEV_SCH is not set
 
 #
 # Some SCSI devices (e.g. CD jukebox) support multiple LUNs
@@ -288,6 +388,7 @@ CONFIG_SCSI_LOGGING=y
 #
 CONFIG_SCSI_SPI_ATTRS=y
 # CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
 
 #
 # SCSI low-level drivers
@@ -303,13 +404,10 @@ CONFIG_SCSI_SPI_ATTRS=y
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
 # CONFIG_SCSI_SATA is not set
-# CONFIG_SCSI_BUSLOGIC is not set
 # CONFIG_SCSI_CPQFCTS is not set
 # CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_EATA is not set
 # CONFIG_SCSI_EATA_PIO is not set
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_GDTH is not set
 # CONFIG_SCSI_IPS is not set
 # CONFIG_SCSI_INITIO is not set
 # CONFIG_SCSI_INIA100 is not set
@@ -319,8 +417,6 @@ CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
 CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
 # CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
 # CONFIG_SCSI_IPR is not set
-# CONFIG_SCSI_PCI2000 is not set
-# CONFIG_SCSI_PCI2220I is not set
 # CONFIG_SCSI_QLOGIC_ISP is not set
 # CONFIG_SCSI_QLOGIC_FC is not set
 CONFIG_SCSI_QLOGIC_1280=y
@@ -331,7 +427,8 @@ CONFIG_SCSI_QLA2XXX=y
 # CONFIG_SCSI_QLA2300 is not set
 # CONFIG_SCSI_QLA2322 is not set
 # CONFIG_SCSI_QLA6312 is not set
-# CONFIG_SCSI_QLA6322 is not set
+# CONFIG_SCSI_QLA24XX is not set
+# CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_DEBUG is not set
@@ -345,8 +442,10 @@ CONFIG_SCSI_QLA2XXX=y
 # Fusion MPT device support
 #
 CONFIG_FUSION=y
-CONFIG_FUSION_MAX_SGE=40
-# CONFIG_FUSION_CTL is not set
+CONFIG_FUSION_SPI=y
+CONFIG_FUSION_FC=y
+CONFIG_FUSION_MAX_SGE=128
+CONFIG_FUSION_CTL=m
 
 #
 # IEEE 1394 (FireWire) support
@@ -359,87 +458,8 @@ CONFIG_FUSION_MAX_SGE=40
 # CONFIG_I2O is not set
 
 #
-# Networking support
+# Network device support
 #
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK_DEV is not set
-CONFIG_UNIX=y
-# CONFIG_NET_KEY is not set
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-# CONFIG_IP_PNP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_TUNNEL is not set
-# CONFIG_IP_TCPDIAG is not set
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-
-#
-# IP: Virtual Server Configuration
-#
-# CONFIG_IP_VS is not set
-# CONFIG_IPV6 is not set
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-
-#
-# IP: Netfilter Configuration
-#
-# CONFIG_IP_NF_CONNTRACK is not set
-# CONFIG_IP_NF_CONNTRACK_MARK is not set
-# CONFIG_IP_NF_QUEUE is not set
-# CONFIG_IP_NF_IPTABLES is not set
-CONFIG_IP_NF_ARPTABLES=y
-# CONFIG_IP_NF_ARPFILTER is not set
-# CONFIG_IP_NF_ARP_MANGLE is not set
-# CONFIG_IP_NF_COMPAT_IPCHAINS is not set
-# CONFIG_IP_NF_COMPAT_IPFWADM is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
 CONFIG_NETDEVICES=y
 CONFIG_DUMMY=y
 # CONFIG_BONDING is not set
@@ -483,7 +503,6 @@ CONFIG_NET_PCI=y
 # CONFIG_DGRS is not set
 # CONFIG_EEPRO100 is not set
 CONFIG_E100=y
-# CONFIG_E100_NAPI is not set
 # CONFIG_FEALNX is not set
 # CONFIG_NATSEMI is not set
 # CONFIG_NE2K_PCI is not set
@@ -505,9 +524,11 @@ CONFIG_E1000=y
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
 # CONFIG_R8169 is not set
+# CONFIG_SKGE is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_VIA_VELOCITY is not set
 CONFIG_TIGON3=y
+# CONFIG_BNX2 is not set
 
 #
 # Ethernet (10000 Mbit)
@@ -536,6 +557,8 @@ CONFIG_TIGON3=y
 # CONFIG_NET_FC is not set
 # CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
 
 #
 # ISDN subsystem
@@ -565,18 +588,6 @@ CONFIG_INPUT_EVDEV=y
 # CONFIG_INPUT_EVBUG is not set
 
 #
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-# CONFIG_SERIO_SERPORT is not set
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PCIPS2 is not set
-# CONFIG_SERIO_RAW is not set
-
-#
 # Input Device Drivers
 #
 # CONFIG_INPUT_KEYBOARD is not set
@@ -586,6 +597,16 @@ CONFIG_SERIO=y
 # CONFIG_INPUT_MISC is not set
 
 #
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+# CONFIG_SERIO_SERPORT is not set
+# CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
 # Character devices
 #
 CONFIG_VT=y
@@ -603,7 +624,6 @@ CONFIG_SERIAL_8250_NR_UARTS=8
 CONFIG_SERIAL_8250_EXTENDED=y
 CONFIG_SERIAL_8250_SHARE_IRQ=y
 # CONFIG_SERIAL_8250_DETECT_IRQ is not set
-# CONFIG_SERIAL_8250_MULTIPORT is not set
 # CONFIG_SERIAL_8250_RSA is not set
 
 #
@@ -611,6 +631,7 @@ CONFIG_SERIAL_8250_SHARE_IRQ=y
 #
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -642,8 +663,15 @@ CONFIG_DRM=y
 CONFIG_DRM_RADEON=y
 # CONFIG_DRM_MGA is not set
 # CONFIG_DRM_SIS is not set
+# CONFIG_DRM_VIA is not set
 # CONFIG_RAW_DRIVER is not set
 # CONFIG_HPET is not set
+# CONFIG_HANGCHECK_TIMER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
 
 #
 # I2C support
@@ -668,6 +696,7 @@ CONFIG_I2C_ALGOPCF=y
 # CONFIG_I2C_AMD8111 is not set
 # CONFIG_I2C_I801 is not set
 # CONFIG_I2C_I810 is not set
+# CONFIG_I2C_PIIX4 is not set
 # CONFIG_I2C_ISA is not set
 # CONFIG_I2C_NFORCE2 is not set
 # CONFIG_I2C_PARPORT_LIGHT is not set
@@ -682,44 +711,19 @@ CONFIG_I2C_ALGOPCF=y
 # CONFIG_I2C_VIAPRO is not set
 # CONFIG_I2C_VOODOO3 is not set
 # CONFIG_I2C_PCA_ISA is not set
-
-#
-# Hardware Sensors Chip support
-#
 # CONFIG_I2C_SENSOR is not set
-# CONFIG_SENSORS_ADM1021 is not set
-# CONFIG_SENSORS_ADM1025 is not set
-# CONFIG_SENSORS_ADM1026 is not set
-# CONFIG_SENSORS_ADM1031 is not set
-# CONFIG_SENSORS_ASB100 is not set
-# CONFIG_SENSORS_DS1621 is not set
-# CONFIG_SENSORS_FSCHER is not set
-# CONFIG_SENSORS_GL518SM is not set
-# CONFIG_SENSORS_IT87 is not set
-# CONFIG_SENSORS_LM63 is not set
-# CONFIG_SENSORS_LM75 is not set
-# CONFIG_SENSORS_LM77 is not set
-# CONFIG_SENSORS_LM78 is not set
-# CONFIG_SENSORS_LM80 is not set
-# CONFIG_SENSORS_LM83 is not set
-# CONFIG_SENSORS_LM85 is not set
-# CONFIG_SENSORS_LM87 is not set
-# CONFIG_SENSORS_LM90 is not set
-# CONFIG_SENSORS_MAX1619 is not set
-# CONFIG_SENSORS_PC87360 is not set
-# CONFIG_SENSORS_SMSC47M1 is not set
-# CONFIG_SENSORS_VIA686A is not set
-# CONFIG_SENSORS_W83781D is not set
-# CONFIG_SENSORS_W83L785TS is not set
-# CONFIG_SENSORS_W83627HF is not set
 
 #
-# Other I2C Chip support
+# Miscellaneous I2C Chip support
 #
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
 # CONFIG_SENSORS_EEPROM is not set
 # CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_SENSORS_PCA9539 is not set
 # CONFIG_SENSORS_PCF8591 is not set
 # CONFIG_SENSORS_RTC8564 is not set
+# CONFIG_SENSORS_MAX6875 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
@@ -731,6 +735,11 @@ CONFIG_I2C_ALGOPCF=y
 # CONFIG_W1 is not set
 
 #
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+
+#
 # Misc devices
 #
 
@@ -778,6 +787,11 @@ CONFIG_VIDEO_DEV=y
 # Graphics support
 #
 CONFIG_FB=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+CONFIG_FB_SOFT_CURSOR=y
+# CONFIG_FB_MACMODES is not set
 CONFIG_FB_MODE_HELPERS=y
 # CONFIG_FB_TILEBLITTING is not set
 # CONFIG_FB_CIRRUS is not set
@@ -785,6 +799,7 @@ CONFIG_FB_MODE_HELPERS=y
 # CONFIG_FB_CYBER2000 is not set
 # CONFIG_FB_ASILIANT is not set
 # CONFIG_FB_IMSTT is not set
+# CONFIG_FB_NVIDIA is not set
 # CONFIG_FB_RIVA is not set
 # CONFIG_FB_MATROX is not set
 # CONFIG_FB_RADEON_OLD is not set
@@ -801,6 +816,7 @@ CONFIG_FB_RADEON_DEBUG=y
 # CONFIG_FB_VOODOO1 is not set
 # CONFIG_FB_TRIDENT is not set
 # CONFIG_FB_PM3 is not set
+# CONFIG_FB_S1D13XXX is not set
 # CONFIG_FB_VIRTUAL is not set
 
 #
@@ -820,6 +836,7 @@ CONFIG_LOGO=y
 # CONFIG_LOGO_LINUX_MONO is not set
 # CONFIG_LOGO_LINUX_VGA16 is not set
 CONFIG_LOGO_LINUX_CLUT224=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -869,6 +886,8 @@ CONFIG_SND_AC97_CODEC=y
 # CONFIG_SND_CS46XX is not set
 # CONFIG_SND_CS4281 is not set
 # CONFIG_SND_EMU10K1 is not set
+# CONFIG_SND_EMU10K1X is not set
+# CONFIG_SND_CA0106 is not set
 # CONFIG_SND_KORG1212 is not set
 # CONFIG_SND_MIXART is not set
 # CONFIG_SND_NM256 is not set
@@ -876,6 +895,7 @@ CONFIG_SND_AC97_CODEC=y
 # CONFIG_SND_RME96 is not set
 # CONFIG_SND_RME9652 is not set
 # CONFIG_SND_HDSP is not set
+# CONFIG_SND_HDSPM is not set
 # CONFIG_SND_TRIDENT is not set
 # CONFIG_SND_YMFPCI is not set
 # CONFIG_SND_ALS4000 is not set
@@ -893,13 +913,14 @@ CONFIG_SND_FM801_TEA575X=y
 # CONFIG_SND_INTEL8X0M is not set
 # CONFIG_SND_SONICVIBES is not set
 # CONFIG_SND_VIA82XX is not set
+# CONFIG_SND_VIA82XX_MODEM is not set
 # CONFIG_SND_VX222 is not set
+# CONFIG_SND_HDA_INTEL is not set
 
 #
 # USB devices
 #
 # CONFIG_SND_USB_AUDIO is not set
-# CONFIG_SND_USB_USX2Y is not set
 
 #
 # Open Sound System
@@ -909,6 +930,8 @@ CONFIG_SND_FM801_TEA575X=y
 #
 # USB support
 #
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
 CONFIG_USB=y
 # CONFIG_USB_DEBUG is not set
 
@@ -920,8 +943,6 @@ CONFIG_USB_BANDWIDTH=y
 # CONFIG_USB_DYNAMIC_MINORS is not set
 # CONFIG_USB_SUSPEND is not set
 # CONFIG_USB_OTG is not set
-CONFIG_USB_ARCH_HAS_HCD=y
-CONFIG_USB_ARCH_HAS_OHCI=y
 
 #
 # USB Host Controller Drivers
@@ -929,7 +950,10 @@ CONFIG_USB_ARCH_HAS_OHCI=y
 CONFIG_USB_EHCI_HCD=y
 # CONFIG_USB_EHCI_SPLIT_ISO is not set
 # CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+# CONFIG_USB_ISP116X_HCD is not set
 CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 CONFIG_USB_UHCI_HCD=y
 # CONFIG_USB_SL811_HCD is not set
 
@@ -947,12 +971,11 @@ CONFIG_USB_UHCI_HCD=y
 #
 CONFIG_USB_STORAGE=y
 # CONFIG_USB_STORAGE_DEBUG is not set
-# CONFIG_USB_STORAGE_RW_DETECT is not set
 # CONFIG_USB_STORAGE_DATAFAB is not set
 # CONFIG_USB_STORAGE_FREECOM is not set
 # CONFIG_USB_STORAGE_ISD200 is not set
 # CONFIG_USB_STORAGE_DPCM is not set
-# CONFIG_USB_STORAGE_HP8200e is not set
+# CONFIG_USB_STORAGE_USBAT is not set
 # CONFIG_USB_STORAGE_SDDR09 is not set
 # CONFIG_USB_STORAGE_SDDR55 is not set
 # CONFIG_USB_STORAGE_JUMPSHOT is not set
@@ -966,19 +989,21 @@ CONFIG_USB_HIDINPUT=y
 CONFIG_USB_HIDDEV=y
 # CONFIG_USB_AIPTEK is not set
 # CONFIG_USB_WACOM is not set
+# CONFIG_USB_ACECAD is not set
 # CONFIG_USB_KBTAB is not set
 # CONFIG_USB_POWERMATE is not set
 # CONFIG_USB_MTOUCH is not set
+# CONFIG_USB_ITMTOUCH is not set
 # CONFIG_USB_EGALAX is not set
 # CONFIG_USB_XPAD is not set
 # CONFIG_USB_ATI_REMOTE is not set
+# CONFIG_USB_KEYSPAN_REMOTE is not set
 
 #
 # USB Imaging devices
 #
 # CONFIG_USB_MDC800 is not set
 # CONFIG_USB_MICROTEK is not set
-# CONFIG_USB_HPUSBSCSI is not set
 
 #
 # USB Multimedia devices
@@ -992,6 +1017,7 @@ CONFIG_USB_HIDDEV=y
 # CONFIG_USB_SE401 is not set
 # CONFIG_USB_SN9C102 is not set
 # CONFIG_USB_STV680 is not set
+# CONFIG_USB_PWC is not set
 
 #
 # USB Network Adapters
@@ -1001,6 +1027,7 @@ CONFIG_USB_HIDDEV=y
 # CONFIG_USB_PEGASUS is not set
 # CONFIG_USB_RTL8150 is not set
 # CONFIG_USB_USBNET is not set
+CONFIG_USB_MON=y
 
 #
 # USB port drivers
@@ -1016,7 +1043,6 @@ CONFIG_USB_HIDDEV=y
 #
 # CONFIG_USB_EMI62 is not set
 # CONFIG_USB_EMI26 is not set
-# CONFIG_USB_TIGL is not set
 # CONFIG_USB_AUERSWALD is not set
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
@@ -1025,9 +1051,12 @@ CONFIG_USB_HIDDEV=y
 # CONFIG_USB_CYTHERM is not set
 # CONFIG_USB_PHIDGETKIT is not set
 # CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
 
 #
-# USB ATM/DSL drivers
+# USB DSL modem support
 #
 
 #
@@ -1041,12 +1070,22 @@ CONFIG_USB_HIDDEV=y
 # CONFIG_MMC is not set
 
 #
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# SN Devices
+#
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
 CONFIG_EXT2_FS_XATTR=y
 # CONFIG_EXT2_FS_POSIX_ACL is not set
 # CONFIG_EXT2_FS_SECURITY is not set
+# CONFIG_EXT2_FS_XIP is not set
 CONFIG_EXT3_FS=y
 CONFIG_EXT3_FS_XATTR=y
 # CONFIG_EXT3_FS_POSIX_ACL is not set
@@ -1056,9 +1095,15 @@ CONFIG_JBD=y
 CONFIG_FS_MBCACHE=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+
+#
+# XFS support
+#
 # CONFIG_XFS_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
+# CONFIG_INOTIFY is not set
 # CONFIG_QUOTA is not set
 CONFIG_DNOTIFY=y
 CONFIG_AUTOFS_FS=y
@@ -1089,7 +1134,6 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
 CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
 # CONFIG_DEVPTS_FS_XATTR is not set
 CONFIG_TMPFS=y
 CONFIG_TMPFS_XATTR=y
@@ -1120,15 +1164,18 @@ CONFIG_RAMFS=y
 #
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
 CONFIG_NFS_V4=y
 # CONFIG_NFS_DIRECTIO is not set
 CONFIG_NFSD=y
 CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
 # CONFIG_NFSD_V4 is not set
 # CONFIG_NFSD_TCP is not set
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_EXPORTFS=y
+CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
@@ -1209,6 +1256,8 @@ CONFIG_NLS_UTF8=y
 # CONFIG_CRC_CCITT is not set
 CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
 
 #
 # Profiling support
@@ -1218,14 +1267,18 @@ CONFIG_CRC32=y
 #
 # Kernel hacking
 #
+# CONFIG_PRINTK_TIME is not set
 CONFIG_DEBUG_KERNEL=y
 CONFIG_MAGIC_SYSRQ=y
+CONFIG_LOG_BUF_SHIFT=17
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_DEBUG_SLAB is not set
 # CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_KOBJECT is not set
 # CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_FS is not set
+CONFIG_KPROBES=y
 CONFIG_IA64_GRANULE_16MB=y
 # CONFIG_IA64_GRANULE_64MB is not set
 CONFIG_IA64_PRINT_HAZARDS=y
@@ -1252,6 +1305,7 @@ CONFIG_CRYPTO_MD5=y
 # CONFIG_CRYPTO_SHA256 is not set
 # CONFIG_CRYPTO_SHA512 is not set
 # CONFIG_CRYPTO_WP512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
 CONFIG_CRYPTO_DES=y
 # CONFIG_CRYPTO_BLOWFISH is not set
 # CONFIG_CRYPTO_TWOFISH is not set
diff --git a/arch/ia64/defconfig b/arch/ia64/defconfig
--- a/arch/ia64/defconfig
+++ b/arch/ia64/defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10
-# Thu Jan  6 11:13:13 2005
+# Linux kernel version: 2.6.12
+# Tue Jun 21 11:30:42 2005
 #
 
 #
@@ -10,6 +10,7 @@
 CONFIG_EXPERIMENTAL=y
 CONFIG_CLEAN_COMPILE=y
 CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
@@ -21,24 +22,27 @@ CONFIG_POSIX_MQUEUE=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=20
 CONFIG_HOTPLUG=y
 CONFIG_KOBJECT_UEVENT=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
+# CONFIG_CPUSETS is not set
 # CONFIG_EMBEDDED is not set
 CONFIG_KALLSYMS=y
 CONFIG_KALLSYMS_ALL=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
 # CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
 
 #
 # Loadable module support
@@ -63,9 +67,11 @@ CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_TIME_INTERPOLATION=y
 CONFIG_EFI=y
 CONFIG_GENERIC_IOMAP=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
 CONFIG_IA64_GENERIC=y
 # CONFIG_IA64_DIG is not set
 # CONFIG_IA64_HP_ZX1 is not set
+# CONFIG_IA64_HP_ZX1_SWIOTLB is not set
 # CONFIG_IA64_SGI_SN2 is not set
 # CONFIG_IA64_HP_SIM is not set
 # CONFIG_ITANIUM is not set
@@ -77,13 +83,15 @@ CONFIG_IA64_PAGE_SIZE_16KB=y
 CONFIG_IA64_L1_CACHE_SHIFT=7
 CONFIG_NUMA=y
 CONFIG_VIRTUAL_MEM_MAP=y
-CONFIG_DISCONTIGMEM=y
+CONFIG_HOLES_IN_ZONE=y
+CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
 CONFIG_IA64_CYCLONE=y
 CONFIG_IOSAPIC=y
 CONFIG_FORCE_MAX_ZONEORDER=18
 CONFIG_SMP=y
 CONFIG_NR_CPUS=512
 CONFIG_HOTPLUG_CPU=y
+# CONFIG_SCHED_SMT is not set
 # CONFIG_PREEMPT is not set
 CONFIG_HAVE_DEC_LOCK=y
 CONFIG_IA32_SUPPORT=y
@@ -135,6 +143,7 @@ CONFIG_PCI_DOMAINS=y
 # CONFIG_PCI_MSI is not set
 CONFIG_PCI_LEGACY_PROC=y
 CONFIG_PCI_NAMES=y
+# CONFIG_PCI_DEBUG is not set
 
 #
 # PCI Hotplug Support
@@ -144,7 +153,6 @@ CONFIG_HOTPLUG_PCI=m
 CONFIG_HOTPLUG_PCI_ACPI=m
 # CONFIG_HOTPLUG_PCI_ACPI_IBM is not set
 # CONFIG_HOTPLUG_PCI_CPCI is not set
-# CONFIG_HOTPLUG_PCI_PCIE is not set
 # CONFIG_HOTPLUG_PCI_SHPC is not set
 
 #
@@ -153,10 +161,6 @@ CONFIG_HOTPLUG_PCI_ACPI=m
 # CONFIG_PCCARD is not set
 
 #
-# PC-card bridges
-#
-
-#
 # Device Drivers
 #
 
@@ -190,6 +194,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_BLK_CPQ_CISS_DA is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=m
 CONFIG_BLK_DEV_CRYPTOLOOP=m
 CONFIG_BLK_DEV_NBD=m
@@ -209,6 +214,7 @@ CONFIG_IOSCHED_NOOP=y
 CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
+# CONFIG_ATA_OVER_ETH is not set
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -283,6 +289,7 @@ CONFIG_CHR_DEV_ST=m
 CONFIG_BLK_DEV_SR=m
 # CONFIG_BLK_DEV_SR_VENDOR is not set
 CONFIG_CHR_DEV_SG=m
+# CONFIG_CHR_DEV_SCH is not set
 
 #
 # Some SCSI devices (e.g. CD jukebox) support multiple LUNs
@@ -310,13 +317,21 @@ CONFIG_SCSI_FC_ATTRS=y
 # CONFIG_SCSI_AIC79XX is not set
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
-# CONFIG_SCSI_SATA is not set
-# CONFIG_SCSI_BUSLOGIC is not set
+CONFIG_SCSI_SATA=y
+# CONFIG_SCSI_SATA_AHCI is not set
+# CONFIG_SCSI_SATA_SVW is not set
+# CONFIG_SCSI_ATA_PIIX is not set
+# CONFIG_SCSI_SATA_NV is not set
+# CONFIG_SCSI_SATA_PROMISE is not set
+# CONFIG_SCSI_SATA_QSTOR is not set
+# CONFIG_SCSI_SATA_SX4 is not set
+# CONFIG_SCSI_SATA_SIL is not set
+# CONFIG_SCSI_SATA_SIS is not set
+# CONFIG_SCSI_SATA_ULI is not set
+# CONFIG_SCSI_SATA_VIA is not set
+CONFIG_SCSI_SATA_VITESSE=y
 # CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_EATA_PIO is not set
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_GDTH is not set
 # CONFIG_SCSI_IPS is not set
 # CONFIG_SCSI_INITIO is not set
 # CONFIG_SCSI_INIA100 is not set
@@ -326,7 +341,6 @@ CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
 CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
 # CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
 # CONFIG_SCSI_IPR is not set
-# CONFIG_SCSI_QLOGIC_ISP is not set
 CONFIG_SCSI_QLOGIC_FC=y
 # CONFIG_SCSI_QLOGIC_FC_FIRMWARE is not set
 CONFIG_SCSI_QLOGIC_1280=y
@@ -337,6 +351,7 @@ CONFIG_SCSI_QLA22XX=m
 CONFIG_SCSI_QLA2300=m
 CONFIG_SCSI_QLA2322=m
 # CONFIG_SCSI_QLA6312 is not set
+# CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_DEBUG is not set
@@ -359,12 +374,16 @@ CONFIG_DM_CRYPT=m
 CONFIG_DM_SNAPSHOT=m
 CONFIG_DM_MIRROR=m
 CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+# CONFIG_DM_MULTIPATH_EMC is not set
 
 #
 # Fusion MPT device support
 #
 CONFIG_FUSION=y
-CONFIG_FUSION_MAX_SGE=40
+CONFIG_FUSION_SPI=y
+CONFIG_FUSION_FC=m
+CONFIG_FUSION_MAX_SGE=128
 # CONFIG_FUSION_CTL is not set
 
 #
@@ -387,7 +406,6 @@ CONFIG_NET=y
 #
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
-CONFIG_NETLINK_DEV=y
 CONFIG_UNIX=y
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
@@ -447,7 +465,6 @@ CONFIG_DUMMY=m
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
 
 #
 # ARCnet devices
@@ -484,9 +501,7 @@ CONFIG_NET_PCI=y
 # CONFIG_FORCEDETH is not set
 # CONFIG_DGRS is not set
 CONFIG_EEPRO100=m
-# CONFIG_EEPRO100_PIO is not set
 CONFIG_E100=m
-# CONFIG_E100_NAPI is not set
 # CONFIG_FEALNX is not set
 # CONFIG_NATSEMI is not set
 # CONFIG_NE2K_PCI is not set
@@ -508,9 +523,11 @@ CONFIG_E1000=y
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
 # CONFIG_R8169 is not set
+# CONFIG_SKGE is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_VIA_VELOCITY is not set
 CONFIG_TIGON3=y
+# CONFIG_BNX2 is not set
 
 #
 # Ethernet (10000 Mbit)
@@ -568,25 +585,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 # CONFIG_INPUT_EVBUG is not set
 
 #
-# Input I/O drivers
-#
-CONFIG_GAMEPORT=m
-CONFIG_SOUND_GAMEPORT=m
-# CONFIG_GAMEPORT_NS558 is not set
-# CONFIG_GAMEPORT_L4 is not set
-# CONFIG_GAMEPORT_EMU10K1 is not set
-# CONFIG_GAMEPORT_VORTEX is not set
-# CONFIG_GAMEPORT_FM801 is not set
-# CONFIG_GAMEPORT_CS461x is not set
-CONFIG_SERIO=y
-CONFIG_SERIO_I8042=y
-# CONFIG_SERIO_SERPORT is not set
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PCIPS2 is not set
-CONFIG_SERIO_LIBPS2=y
-# CONFIG_SERIO_RAW is not set
-
-#
 # Input Device Drivers
 #
 CONFIG_INPUT_KEYBOARD=y
@@ -604,6 +602,23 @@ CONFIG_MOUSE_PS2=y
 # CONFIG_INPUT_MISC is not set
 
 #
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+# CONFIG_SERIO_SERPORT is not set
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+CONFIG_GAMEPORT=m
+# CONFIG_GAMEPORT_NS558 is not set
+# CONFIG_GAMEPORT_L4 is not set
+# CONFIG_GAMEPORT_EMU10K1 is not set
+# CONFIG_GAMEPORT_VORTEX is not set
+# CONFIG_GAMEPORT_FM801 is not set
+# CONFIG_GAMEPORT_CS461X is not set
+
+#
 # Character devices
 #
 CONFIG_VT=y
@@ -613,11 +628,15 @@ CONFIG_SERIAL_NONSTANDARD=y
 # CONFIG_ROCKETPORT is not set
 # CONFIG_CYCLADES is not set
 # CONFIG_MOXA_SMARTIO is not set
-# CONFIG_SYNCLINK is not set
+# CONFIG_ISI is not set
 # CONFIG_SYNCLINKMP is not set
 # CONFIG_N_HDLC is not set
+# CONFIG_SPECIALIX is not set
+# CONFIG_SX is not set
 # CONFIG_STALDRV is not set
 CONFIG_SGI_SNSC=y
+CONFIG_SGI_TIOCX=y
+CONFIG_SGI_MBCS=m
 
 #
 # Serial drivers
@@ -638,6 +657,8 @@ CONFIG_SERIAL_8250_SHARE_IRQ=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_SERIAL_SGI_L1_CONSOLE=y
+CONFIG_SERIAL_SGI_IOC4=y
+# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -663,6 +684,7 @@ CONFIG_EFI_RTC=y
 CONFIG_AGP=m
 CONFIG_AGP_I460=m
 CONFIG_AGP_HP_ZX1=m
+CONFIG_AGP_SGI_TIOCA=m
 CONFIG_DRM=m
 CONFIG_DRM_TDFX=m
 CONFIG_DRM_R128=m
@@ -674,9 +696,15 @@ CONFIG_HPET=y
 # CONFIG_HPET_RTC_IRQ is not set
 CONFIG_HPET_MMAP=y
 CONFIG_MAX_RAW_DEVS=256
+# CONFIG_HANGCHECK_TIMER is not set
 CONFIG_MMTIMER=y
 
 #
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
 # I2C support
 #
 # CONFIG_I2C is not set
@@ -760,6 +788,8 @@ CONFIG_SND_CS46XX=m
 CONFIG_SND_CS46XX_NEW_DSP=y
 CONFIG_SND_CS4281=m
 CONFIG_SND_EMU10K1=m
+# CONFIG_SND_EMU10K1X is not set
+# CONFIG_SND_CA0106 is not set
 # CONFIG_SND_KORG1212 is not set
 # CONFIG_SND_MIXART is not set
 # CONFIG_SND_NM256 is not set
@@ -784,13 +814,14 @@ CONFIG_SND_FM801=m
 # CONFIG_SND_INTEL8X0M is not set
 # CONFIG_SND_SONICVIBES is not set
 # CONFIG_SND_VIA82XX is not set
+# CONFIG_SND_VIA82XX_MODEM is not set
 # CONFIG_SND_VX222 is not set
+# CONFIG_SND_HDA_INTEL is not set
 
 #
 # USB devices
 #
 # CONFIG_SND_USB_AUDIO is not set
-# CONFIG_SND_USB_USX2Y is not set
 
 #
 # Open Sound System
@@ -800,6 +831,8 @@ CONFIG_SND_FM801=m
 #
 # USB support
 #
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
 CONFIG_USB=m
 # CONFIG_USB_DEBUG is not set
 
@@ -811,8 +844,6 @@ CONFIG_USB_DEVICEFS=y
 # CONFIG_USB_DYNAMIC_MINORS is not set
 # CONFIG_USB_SUSPEND is not set
 # CONFIG_USB_OTG is not set
-CONFIG_USB_ARCH_HAS_HCD=y
-CONFIG_USB_ARCH_HAS_OHCI=y
 
 #
 # USB Host Controller Drivers
@@ -821,6 +852,8 @@ CONFIG_USB_EHCI_HCD=m
 # CONFIG_USB_EHCI_SPLIT_ISO is not set
 # CONFIG_USB_EHCI_ROOT_HUB_TT is not set
 CONFIG_USB_OHCI_HCD=m
+# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 CONFIG_USB_UHCI_HCD=m
 # CONFIG_USB_SL811_HCD is not set
 
@@ -838,12 +871,11 @@ CONFIG_USB_UHCI_HCD=m
 #
 CONFIG_USB_STORAGE=m
 # CONFIG_USB_STORAGE_DEBUG is not set
-# CONFIG_USB_STORAGE_RW_DETECT is not set
 # CONFIG_USB_STORAGE_DATAFAB is not set
 # CONFIG_USB_STORAGE_FREECOM is not set
 # CONFIG_USB_STORAGE_ISD200 is not set
 # CONFIG_USB_STORAGE_DPCM is not set
-# CONFIG_USB_STORAGE_HP8200e is not set
+# CONFIG_USB_STORAGE_USBAT is not set
 # CONFIG_USB_STORAGE_SDDR09 is not set
 # CONFIG_USB_STORAGE_SDDR55 is not set
 # CONFIG_USB_STORAGE_JUMPSHOT is not set
@@ -893,6 +925,7 @@ CONFIG_USB_HIDINPUT=y
 # CONFIG_USB_PEGASUS is not set
 # CONFIG_USB_RTL8150 is not set
 # CONFIG_USB_USBNET is not set
+CONFIG_USB_MON=m
 
 #
 # USB port drivers
@@ -908,7 +941,6 @@ CONFIG_USB_HIDINPUT=y
 #
 # CONFIG_USB_EMI62 is not set
 # CONFIG_USB_EMI26 is not set
-# CONFIG_USB_TIGL is not set
 # CONFIG_USB_AUERSWALD is not set
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
@@ -917,6 +949,8 @@ CONFIG_USB_HIDINPUT=y
 # CONFIG_USB_CYTHERM is not set
 # CONFIG_USB_PHIDGETKIT is not set
 # CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_SISUSBVGA is not set
 # CONFIG_USB_TEST is not set
 
 #
@@ -943,6 +977,11 @@ CONFIG_INFINIBAND_IPOIB=m
 # CONFIG_INFINIBAND_IPOIB_DEBUG is not set
 
 #
+# SN Devices
+#
+CONFIG_SGI_IOC4=y
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
@@ -964,7 +1003,12 @@ CONFIG_REISERFS_FS_POSIX_ACL=y
 CONFIG_REISERFS_FS_SECURITY=y
 # CONFIG_JFS_FS is not set
 CONFIG_FS_POSIX_ACL=y
+
+#
+# XFS support
+#
 CONFIG_XFS_FS=y
+CONFIG_XFS_EXPORT=y
 # CONFIG_XFS_RT is not set
 # CONFIG_XFS_QUOTA is not set
 # CONFIG_XFS_SECURITY is not set
@@ -1042,7 +1086,7 @@ CONFIG_NFSD_V4=y
 CONFIG_NFSD_TCP=y
 CONFIG_LOCKD=m
 CONFIG_LOCKD_V4=y
-CONFIG_EXPORTFS=m
+CONFIG_EXPORTFS=y
 CONFIG_SUNRPC=m
 CONFIG_SUNRPC_GSS=m
 CONFIG_RPCSEC_GSS_KRB5=m
@@ -1128,6 +1172,8 @@ CONFIG_NLS_UTF8=m
 # CONFIG_CRC_CCITT is not set
 CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
 
 #
 # HP Simulator drivers
@@ -1144,14 +1190,17 @@ CONFIG_CRC32=y
 #
 # Kernel hacking
 #
+# CONFIG_PRINTK_TIME is not set
 CONFIG_DEBUG_KERNEL=y
 CONFIG_MAGIC_SYSRQ=y
+CONFIG_LOG_BUF_SHIFT=20
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_DEBUG_SLAB is not set
 # CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_KOBJECT is not set
 # CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_FS is not set
 CONFIG_IA64_GRANULE_16MB=y
 # CONFIG_IA64_GRANULE_64MB is not set
 # CONFIG_IA64_PRINT_HAZARDS is not set
@@ -1178,6 +1227,7 @@ CONFIG_CRYPTO_MD5=m
 # CONFIG_CRYPTO_SHA256 is not set
 # CONFIG_CRYPTO_SHA512 is not set
 # CONFIG_CRYPTO_WP512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
 CONFIG_CRYPTO_DES=m
 # CONFIG_CRYPTO_BLOWFISH is not set
 # CONFIG_CRYPTO_TWOFISH is not set
diff --git a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c
--- a/arch/ia64/hp/common/sba_iommu.c
+++ b/arch/ia64/hp/common/sba_iommu.c
@@ -156,10 +156,13 @@
 */
 #define DELAYED_RESOURCE_CNT	64
 
+#define PCI_DEVICE_ID_HP_SX2000_IOC	0x12ec
+
 #define ZX1_IOC_ID	((PCI_DEVICE_ID_HP_ZX1_IOC << 16) | PCI_VENDOR_ID_HP)
 #define ZX2_IOC_ID	((PCI_DEVICE_ID_HP_ZX2_IOC << 16) | PCI_VENDOR_ID_HP)
 #define REO_IOC_ID	((PCI_DEVICE_ID_HP_REO_IOC << 16) | PCI_VENDOR_ID_HP)
 #define SX1000_IOC_ID	((PCI_DEVICE_ID_HP_SX1000_IOC << 16) | PCI_VENDOR_ID_HP)
+#define SX2000_IOC_ID	((PCI_DEVICE_ID_HP_SX2000_IOC << 16) | PCI_VENDOR_ID_HP)
 
 #define ZX1_IOC_OFFSET	0x1000	/* ACPI reports SBA, we want IOC */
 
@@ -1726,6 +1729,7 @@ static struct ioc_iommu ioc_iommu_info[]
 	{ ZX1_IOC_ID, "zx1", ioc_zx1_init },
 	{ ZX2_IOC_ID, "zx2", NULL },
 	{ SX1000_IOC_ID, "sx1000", NULL },
+	{ SX2000_IOC_ID, "sx2000", NULL },
 };
 
 static struct ioc * __init
diff --git a/arch/ia64/hp/sim/boot/boot_head.S b/arch/ia64/hp/sim/boot/boot_head.S
--- a/arch/ia64/hp/sim/boot/boot_head.S
+++ b/arch/ia64/hp/sim/boot/boot_head.S
@@ -22,7 +22,7 @@ GLOBAL_ENTRY(_start)
 	.save rp, r0
 	.body
 	movl gp = __gp
-	movl sp = stack_mem
+	movl sp = stack_mem+16384-16
 	bsw.1
 	br.call.sptk.many rp=start_bootloader
 END(_start)
diff --git a/arch/ia64/hp/sim/simeth.c b/arch/ia64/hp/sim/simeth.c
--- a/arch/ia64/hp/sim/simeth.c
+++ b/arch/ia64/hp/sim/simeth.c
@@ -191,7 +191,7 @@ simeth_probe1(void)
 	unsigned char mac_addr[ETH_ALEN];
 	struct simeth_local *local;
 	struct net_device *dev;
-	int fd, i, err;
+	int fd, i, err, rc;
 
 	/*
 	 * XXX Fix me
@@ -228,7 +228,9 @@ simeth_probe1(void)
 		return err;
 	}
 
-	dev->irq = assign_irq_vector(AUTO_ASSIGN);
+	if ((rc = assign_irq_vector(AUTO_ASSIGN)) < 0)
+		panic("%s: out of interrupt vectors!\n", __FUNCTION__);
+	dev->irq = rc;
 
 	/*
 	 * attach the interrupt in the simulator, this does enable interrupts
diff --git a/arch/ia64/hp/sim/simserial.c b/arch/ia64/hp/sim/simserial.c
--- a/arch/ia64/hp/sim/simserial.c
+++ b/arch/ia64/hp/sim/simserial.c
@@ -30,6 +30,7 @@
 #include <linux/module.h>
 #include <linux/serial.h>
 #include <linux/serialP.h>
+#include <linux/sysrq.h>
 
 #include <asm/irq.h>
 #include <asm/hw_irq.h>
@@ -149,12 +150,17 @@ static  void receive_chars(struct tty_st
 				seen_esc = 2;
 				continue;
 			} else if ( seen_esc == 2 ) {
-				if ( ch == 'P' ) show_state();		/* F1 key */
-#ifdef CONFIG_KDB
-				if ( ch == 'S' )
-					kdb(KDB_REASON_KEYBOARD, 0, (kdb_eframe_t) regs);
+				if ( ch == 'P' ) /* F1 */
+					show_state();
+#ifdef CONFIG_MAGIC_SYSRQ
+				if ( ch == 'S' ) { /* F4 */
+					do
+						ch = ia64_ssc(0, 0, 0, 0,
+							      SSC_GETCHAR);
+					while (!ch);
+					handle_sysrq(ch, regs, NULL);
+				}
 #endif
-
 				seen_esc = 0;
 				continue;
 			}
@@ -976,7 +982,7 @@ static struct tty_operations hp_ops = {
 static int __init
 simrs_init (void)
 {
-	int			i;
+	int			i, rc;
 	struct serial_state	*state;
 
 	if (!ia64_platform_is("hpsim"))
@@ -1011,7 +1017,10 @@ simrs_init (void)
 		if (state->type == PORT_UNKNOWN) continue;
 
 		if (!state->irq) {
-			state->irq = assign_irq_vector(AUTO_ASSIGN);
+			if ((rc = assign_irq_vector(AUTO_ASSIGN)) < 0)
+				panic("%s: out of interrupt vectors!\n",
+				      __FUNCTION__);
+			state->irq = rc;
 			ia64_ssc_connect_irq(KEYBOARD_INTR, state->irq);
 		}
 
diff --git a/arch/ia64/ia32/ia32priv.h b/arch/ia64/ia32/ia32priv.h
--- a/arch/ia64/ia32/ia32priv.h
+++ b/arch/ia64/ia32/ia32priv.h
@@ -241,7 +241,7 @@ typedef struct compat_siginfo {
 
 		/* POSIX.1b timers */
 		struct {
-			timer_t _tid;		/* timer id */
+			compat_timer_t _tid;		/* timer id */
 			int _overrun;		/* overrun count */
 			char _pad[sizeof(unsigned int) - sizeof(int)];
 			compat_sigval_t _sigval;	/* same as below */
diff --git a/arch/ia64/kernel/Makefile b/arch/ia64/kernel/Makefile
--- a/arch/ia64/kernel/Makefile
+++ b/arch/ia64/kernel/Makefile
@@ -17,9 +17,12 @@ obj-$(CONFIG_IA64_PALINFO)	+= palinfo.o
 obj-$(CONFIG_IOSAPIC)		+= iosapic.o
 obj-$(CONFIG_MODULES)		+= module.o
 obj-$(CONFIG_SMP)		+= smp.o smpboot.o domain.o
+obj-$(CONFIG_NUMA)		+= numa.o
 obj-$(CONFIG_PERFMON)		+= perfmon_default_smpl.o
 obj-$(CONFIG_IA64_CYCLONE)	+= cyclone.o
 obj-$(CONFIG_IA64_MCA_RECOVERY)	+= mca_recovery.o
+obj-$(CONFIG_KPROBES)		+= kprobes.o jprobes.o
+obj-$(CONFIG_IA64_UNCACHED_ALLOCATOR)	+= uncached.o
 mca_recovery-y			+= mca_drv.o mca_drv_asm.o
 
 # The gate DSO image is built using a special linker script.
diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c
--- a/arch/ia64/kernel/acpi.c
+++ b/arch/ia64/kernel/acpi.c
@@ -11,6 +11,7 @@
  *  Copyright (C) 2001 Jenna Hall <jenna.s.hall@intel.com>
  *  Copyright (C) 2001 Takayoshi Kochi <t-kochi@bq.jp.nec.com>
  *  Copyright (C) 2002 Erich Focht <efocht@ess.nec.de>
+ *  Copyright (C) 2004 Ashok Raj <ashok.raj@intel.com>
  *
  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  *
@@ -67,6 +68,11 @@ EXPORT_SYMBOL(pm_power_off);
 unsigned char acpi_kbd_controller_present = 1;
 unsigned char acpi_legacy_devices;
 
+static unsigned int __initdata acpi_madt_rev;
+
+unsigned int acpi_cpei_override;
+unsigned int acpi_cpei_phys_cpuid;
+
 #define MAX_SAPICS 256
 u16 ia64_acpiid_to_sapicid[MAX_SAPICS] =
 	{ [0 ... MAX_SAPICS - 1] = -1 };
@@ -236,9 +242,7 @@ acpi_parse_iosapic (acpi_table_entry_hea
 	if (BAD_MADT_ENTRY(iosapic, end))
 		return -EINVAL;
 
-	iosapic_init(iosapic->address, iosapic->global_irq_base);
-
-	return 0;
+	return iosapic_init(iosapic->address, iosapic->global_irq_base);
 }
 
 
@@ -267,10 +271,56 @@ acpi_parse_plat_int_src (
 						(plintsrc->flags.trigger == 1) ? IOSAPIC_EDGE : IOSAPIC_LEVEL);
 
 	platform_intr_list[plintsrc->type] = vector;
+	if (acpi_madt_rev > 1) {
+		acpi_cpei_override = plintsrc->plint_flags.cpei_override_flag;
+	}
+
+	/*
+	 * Save the physical id, so we can check when its being removed
+	 */
+	acpi_cpei_phys_cpuid = ((plintsrc->id << 8) | (plintsrc->eid)) & 0xffff;
+
 	return 0;
 }
 
 
+unsigned int can_cpei_retarget(void)
+{
+	extern int cpe_vector;
+
+	/*
+	 * Only if CPEI is supported and the override flag
+	 * is present, otherwise return that its re-targettable
+	 * if we are in polling mode.
+	 */
+	if (cpe_vector > 0 && !acpi_cpei_override)
+		return 0;
+	else
+		return 1;
+}
+
+unsigned int is_cpu_cpei_target(unsigned int cpu)
+{
+	unsigned int logical_id;
+
+	logical_id = cpu_logical_id(acpi_cpei_phys_cpuid);
+
+	if (logical_id == cpu)
+		return 1;
+	else
+		return 0;
+}
+
+void set_cpei_target_cpu(unsigned int cpu)
+{
+	acpi_cpei_phys_cpuid = cpu_physical_id(cpu);
+}
+
+unsigned int get_cpei_target_cpu(void)
+{
+	return acpi_cpei_phys_cpuid;
+}
+
 static int __init
 acpi_parse_int_src_ovr (
 	acpi_table_entry_header *header, const unsigned long end)
@@ -328,6 +378,8 @@ acpi_parse_madt (unsigned long phys_addr
 
 	acpi_madt = (struct acpi_table_madt *) __va(phys_addr);
 
+	acpi_madt_rev = acpi_madt->header.revision;
+
 	/* remember the value for reference after free_initmem() */
 #ifdef CONFIG_ITANIUM
 	has_8259 = 1; /* Firmware on old Itanium systems is broken */
@@ -642,9 +694,11 @@ acpi_boot_init (void)
 			if (smp_boot_data.cpu_phys_id[cpu] != hard_smp_processor_id())
 				node_cpuid[i++].phys_id = smp_boot_data.cpu_phys_id[cpu];
 	}
-	build_cpu_to_node_map();
 # endif
 #endif
+#ifdef CONFIG_ACPI_NUMA
+	build_cpu_to_node_map();
+#endif
 	/* Make boot-up look pretty */
 	printk(KERN_INFO "%d CPUs available, %d CPUs total\n", available_cpus, total_cpus);
 	return 0;
@@ -772,7 +826,7 @@ EXPORT_SYMBOL(acpi_unmap_lsapic);
  
 
 #ifdef CONFIG_ACPI_NUMA
-acpi_status __init
+acpi_status __devinit
 acpi_map_iosapic (acpi_handle handle, u32 depth, void *context, void **ret)
 {
 	struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
@@ -825,4 +879,28 @@ acpi_map_iosapic (acpi_handle handle, u3
 	return AE_OK;
 }
 #endif /* CONFIG_NUMA */
+
+int
+acpi_register_ioapic (acpi_handle handle, u64 phys_addr, u32 gsi_base)
+{
+	int err;
+
+	if ((err = iosapic_init(phys_addr, gsi_base)))
+		return err;
+
+#if CONFIG_ACPI_NUMA
+	acpi_map_iosapic(handle, 0, NULL, NULL);
+#endif /* CONFIG_ACPI_NUMA */
+
+	return 0;
+}
+EXPORT_SYMBOL(acpi_register_ioapic);
+
+int
+acpi_unregister_ioapic (acpi_handle handle, u32 gsi_base)
+{
+	return iosapic_remove(gsi_base);
+}
+EXPORT_SYMBOL(acpi_unregister_ioapic);
+
 #endif /* CONFIG_ACPI_BOOT */
diff --git a/arch/ia64/kernel/domain.c b/arch/ia64/kernel/domain.c
--- a/arch/ia64/kernel/domain.c
+++ b/arch/ia64/kernel/domain.c
@@ -14,7 +14,7 @@
 #include <linux/topology.h>
 #include <linux/nodemask.h>
 
-#define SD_NODES_PER_DOMAIN 6
+#define SD_NODES_PER_DOMAIN 16
 
 #ifdef CONFIG_NUMA
 /**
@@ -27,7 +27,7 @@
  *
  * Should use nodemask_t.
  */
-static int __devinit find_next_best_node(int node, unsigned long *used_nodes)
+static int find_next_best_node(int node, unsigned long *used_nodes)
 {
 	int i, n, val, min_val, best_node = 0;
 
@@ -66,7 +66,7 @@ static int __devinit find_next_best_node
  * should be one that prevents unnecessary balancing, but also spreads tasks
  * out optimally.
  */
-static cpumask_t __devinit sched_domain_node_span(int node)
+static cpumask_t sched_domain_node_span(int node)
 {
 	int i;
 	cpumask_t span, nodemask;
@@ -96,7 +96,7 @@ static cpumask_t __devinit sched_domain_
 #ifdef CONFIG_SCHED_SMT
 static DEFINE_PER_CPU(struct sched_domain, cpu_domains);
 static struct sched_group sched_group_cpus[NR_CPUS];
-static int __devinit cpu_to_cpu_group(int cpu)
+static int cpu_to_cpu_group(int cpu)
 {
 	return cpu;
 }
@@ -104,7 +104,7 @@ static int __devinit cpu_to_cpu_group(in
 
 static DEFINE_PER_CPU(struct sched_domain, phys_domains);
 static struct sched_group sched_group_phys[NR_CPUS];
-static int __devinit cpu_to_phys_group(int cpu)
+static int cpu_to_phys_group(int cpu)
 {
 #ifdef CONFIG_SCHED_SMT
 	return first_cpu(cpu_sibling_map[cpu]);
@@ -125,44 +125,36 @@ static struct sched_group *sched_group_n
 static DEFINE_PER_CPU(struct sched_domain, allnodes_domains);
 static struct sched_group sched_group_allnodes[MAX_NUMNODES];
 
-static int __devinit cpu_to_allnodes_group(int cpu)
+static int cpu_to_allnodes_group(int cpu)
 {
 	return cpu_to_node(cpu);
 }
 #endif
 
 /*
- * Set up scheduler domains and groups.  Callers must hold the hotplug lock.
+ * Build sched domains for a given set of cpus and attach the sched domains
+ * to the individual cpus
  */
-void __devinit arch_init_sched_domains(void)
+void build_sched_domains(const cpumask_t *cpu_map)
 {
 	int i;
-	cpumask_t cpu_default_map;
 
 	/*
-	 * Setup mask for cpus without special case scheduling requirements.
-	 * For now this just excludes isolated cpus, but could be used to
-	 * exclude other special cases in the future.
+	 * Set up domains for cpus specified by the cpu_map.
 	 */
-	cpus_complement(cpu_default_map, cpu_isolated_map);
-	cpus_and(cpu_default_map, cpu_default_map, cpu_online_map);
-
-	/*
-	 * Set up domains. Isolated domains just stay on the dummy domain.
-	 */
-	for_each_cpu_mask(i, cpu_default_map) {
+	for_each_cpu_mask(i, *cpu_map) {
 		int group;
 		struct sched_domain *sd = NULL, *p;
 		cpumask_t nodemask = node_to_cpumask(cpu_to_node(i));
 
-		cpus_and(nodemask, nodemask, cpu_default_map);
+		cpus_and(nodemask, nodemask, *cpu_map);
 
 #ifdef CONFIG_NUMA
 		if (num_online_cpus()
 				> SD_NODES_PER_DOMAIN*cpus_weight(nodemask)) {
 			sd = &per_cpu(allnodes_domains, i);
 			*sd = SD_ALLNODES_INIT;
-			sd->span = cpu_default_map;
+			sd->span = *cpu_map;
 			group = cpu_to_allnodes_group(i);
 			sd->groups = &sched_group_allnodes[group];
 			p = sd;
@@ -173,7 +165,7 @@ void __devinit arch_init_sched_domains(v
 		*sd = SD_NODE_INIT;
 		sd->span = sched_domain_node_span(cpu_to_node(i));
 		sd->parent = p;
-		cpus_and(sd->span, sd->span, cpu_default_map);
+		cpus_and(sd->span, sd->span, *cpu_map);
 #endif
 
 		p = sd;
@@ -190,7 +182,7 @@ void __devinit arch_init_sched_domains(v
 		group = cpu_to_cpu_group(i);
 		*sd = SD_SIBLING_INIT;
 		sd->span = cpu_sibling_map[i];
-		cpus_and(sd->span, sd->span, cpu_default_map);
+		cpus_and(sd->span, sd->span, *cpu_map);
 		sd->parent = p;
 		sd->groups = &sched_group_cpus[group];
 #endif
@@ -198,9 +190,9 @@ void __devinit arch_init_sched_domains(v
 
 #ifdef CONFIG_SCHED_SMT
 	/* Set up CPU (sibling) groups */
-	for_each_cpu_mask(i, cpu_default_map) {
+	for_each_cpu_mask(i, *cpu_map) {
 		cpumask_t this_sibling_map = cpu_sibling_map[i];
-		cpus_and(this_sibling_map, this_sibling_map, cpu_default_map);
+		cpus_and(this_sibling_map, this_sibling_map, *cpu_map);
 		if (i != first_cpu(this_sibling_map))
 			continue;
 
@@ -213,7 +205,7 @@ void __devinit arch_init_sched_domains(v
 	for (i = 0; i < MAX_NUMNODES; i++) {
 		cpumask_t nodemask = node_to_cpumask(i);
 
-		cpus_and(nodemask, nodemask, cpu_default_map);
+		cpus_and(nodemask, nodemask, *cpu_map);
 		if (cpus_empty(nodemask))
 			continue;
 
@@ -222,7 +214,7 @@ void __devinit arch_init_sched_domains(v
 	}
 
 #ifdef CONFIG_NUMA
-	init_sched_build_groups(sched_group_allnodes, cpu_default_map,
+	init_sched_build_groups(sched_group_allnodes, *cpu_map,
 				&cpu_to_allnodes_group);
 
 	for (i = 0; i < MAX_NUMNODES; i++) {
@@ -233,12 +225,12 @@ void __devinit arch_init_sched_domains(v
 		cpumask_t covered = CPU_MASK_NONE;
 		int j;
 
-		cpus_and(nodemask, nodemask, cpu_default_map);
+		cpus_and(nodemask, nodemask, *cpu_map);
 		if (cpus_empty(nodemask))
 			continue;
 
 		domainspan = sched_domain_node_span(i);
-		cpus_and(domainspan, domainspan, cpu_default_map);
+		cpus_and(domainspan, domainspan, *cpu_map);
 
 		sg = kmalloc(sizeof(struct sched_group), GFP_KERNEL);
 		sched_group_nodes[i] = sg;
@@ -266,7 +258,7 @@ void __devinit arch_init_sched_domains(v
 			int n = (i + j) % MAX_NUMNODES;
 
 			cpus_complement(notcovered, covered);
-			cpus_and(tmp, notcovered, cpu_default_map);
+			cpus_and(tmp, notcovered, *cpu_map);
 			cpus_and(tmp, tmp, domainspan);
 			if (cpus_empty(tmp))
 				break;
@@ -293,7 +285,7 @@ void __devinit arch_init_sched_domains(v
 #endif
 
 	/* Calculate CPU power for physical packages and nodes */
-	for_each_cpu_mask(i, cpu_default_map) {
+	for_each_cpu_mask(i, *cpu_map) {
 		int power;
 		struct sched_domain *sd;
 #ifdef CONFIG_SCHED_SMT
@@ -349,7 +341,7 @@ next_sg:
 #endif
 
 	/* Attach the domains */
-	for_each_online_cpu(i) {
+	for_each_cpu_mask(i, *cpu_map) {
 		struct sched_domain *sd;
 #ifdef CONFIG_SCHED_SMT
 		sd = &per_cpu(cpu_domains, i);
@@ -359,13 +351,35 @@ next_sg:
 		cpu_attach_domain(sd, i);
 	}
 }
+/*
+ * Set up scheduler domains and groups.  Callers must hold the hotplug lock.
+ */
+void arch_init_sched_domains(const cpumask_t *cpu_map)
+{
+	cpumask_t cpu_default_map;
+
+	/*
+	 * Setup mask for cpus without special case scheduling requirements.
+	 * For now this just excludes isolated cpus, but could be used to
+	 * exclude other special cases in the future.
+	 */
+	cpus_andnot(cpu_default_map, *cpu_map, cpu_isolated_map);
+
+	build_sched_domains(&cpu_default_map);
+}
 
-void __devinit arch_destroy_sched_domains(void)
+void arch_destroy_sched_domains(const cpumask_t *cpu_map)
 {
 #ifdef CONFIG_NUMA
 	int i;
 	for (i = 0; i < MAX_NUMNODES; i++) {
+		cpumask_t nodemask = node_to_cpumask(i);
 		struct sched_group *oldsg, *sg = sched_group_nodes[i];
+
+		cpus_and(nodemask, nodemask, *cpu_map);
+		if (cpus_empty(nodemask))
+			continue;
+
 		if (sg == NULL)
 			continue;
 		sg = sg->next;
diff --git a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c
--- a/arch/ia64/kernel/efi.c
+++ b/arch/ia64/kernel/efi.c
@@ -410,6 +410,38 @@ efi_memmap_walk (efi_freemem_callback_t 
 }
 
 /*
+ * Walk the EFI memory map to pull out leftover pages in the lower
+ * memory regions which do not end up in the regular memory map and
+ * stick them into the uncached allocator
+ *
+ * The regular walk function is significantly more complex than the
+ * uncached walk which means it really doesn't make sense to try and
+ * marge the two.
+ */
+void __init
+efi_memmap_walk_uc (efi_freemem_callback_t callback)
+{
+	void *efi_map_start, *efi_map_end, *p;
+	efi_memory_desc_t *md;
+	u64 efi_desc_size, start, end;
+
+	efi_map_start = __va(ia64_boot_param->efi_memmap);
+	efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size;
+	efi_desc_size = ia64_boot_param->efi_memdesc_size;
+
+	for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
+		md = p;
+		if (md->attribute == EFI_MEMORY_UC) {
+			start = PAGE_ALIGN(md->phys_addr);
+			end = PAGE_ALIGN((md->phys_addr+(md->num_pages << EFI_PAGE_SHIFT)) & PAGE_MASK);
+			if ((*callback)(start, end, NULL) < 0)
+				return;
+		}
+	}
+}
+
+
+/*
  * Look for the PAL_CODE region reported by EFI and maps it using an
  * ITR to enable safe PAL calls in virtual mode.  See IA-64 Processor
  * Abstraction Layer chapter 11 in ADAG
diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S
--- a/arch/ia64/kernel/entry.S
+++ b/arch/ia64/kernel/entry.S
@@ -470,18 +470,6 @@ ENTRY(load_switch_stack)
 	br.cond.sptk.many b7
 END(load_switch_stack)
 
-GLOBAL_ENTRY(__ia64_syscall)
-	.regstk 6,0,0,0
-	mov r15=in5				// put syscall number in place
-	break __BREAK_SYSCALL
-	movl r2=errno
-	cmp.eq p6,p7=-1,r10
-	;;
-(p6)	st4 [r2]=r8
-(p6)	mov r8=-1
-	br.ret.sptk.many rp
-END(__ia64_syscall)
-
 GLOBAL_ENTRY(execve)
 	mov r15=__NR_execve			// put syscall number in place
 	break __BREAK_SYSCALL
@@ -637,7 +625,7 @@ END(ia64_ret_from_syscall)
  *	      r8-r11: restored (syscall return value(s))
  *		 r12: restored (user-level stack pointer)
  *		 r13: restored (user-level thread pointer)
- *		 r14: cleared
+ *		 r14: set to __kernel_syscall_via_epc
  *		 r15: restored (syscall #)
  *	     r16-r17: cleared
  *		 r18: user-level b6
@@ -658,7 +646,7 @@ END(ia64_ret_from_syscall)
  *		  pr: restored (user-level pr)
  *		  b0: restored (user-level rp)
  *	          b6: restored
- *		  b7: cleared
+ *		  b7: set to __kernel_syscall_via_epc
  *	     ar.unat: restored (user-level ar.unat)
  *	      ar.pfs: restored (user-level ar.pfs)
  *	      ar.rsc: restored (user-level ar.rsc)
@@ -704,72 +692,79 @@ ENTRY(ia64_leave_syscall)
 	;;
 (p6)	ld4 r31=[r18]				// load current_thread_info()->flags
 	ld8 r19=[r2],PT(B6)-PT(LOADRS)		// load ar.rsc value for "loadrs"
-	mov b7=r0		// clear b7
+	nop.i 0
 	;;
-	ld8 r23=[r3],PT(R11)-PT(AR_BSPSTORE)	// load ar.bspstore (may be garbage)
+	mov r16=ar.bsp				// M2  get existing backing store pointer
 	ld8 r18=[r2],PT(R9)-PT(B6)		// load b6
 (p6)	and r15=TIF_WORK_MASK,r31		// any work other than TIF_SYSCALL_TRACE?
 	;;
-	mov r16=ar.bsp				// M2  get existing backing store pointer
+	ld8 r23=[r3],PT(R11)-PT(AR_BSPSTORE)	// load ar.bspstore (may be garbage)
 (p6)	cmp4.ne.unc p6,p0=r15, r0		// any special work pending?
 (p6)	br.cond.spnt .work_pending_syscall
 	;;
 	// start restoring the state saved on the kernel stack (struct pt_regs):
 	ld8 r9=[r2],PT(CR_IPSR)-PT(R9)
 	ld8 r11=[r3],PT(CR_IIP)-PT(R11)
-	mov f6=f0		// clear f6
+(pNonSys) break 0		//      bug check: we shouldn't be here if pNonSys is TRUE!
 	;;
 	invala			// M0|1 invalidate ALAT
-	rsm psr.i | psr.ic	// M2 initiate turning off of interrupt and interruption collection
-	mov f9=f0		// clear f9
+	rsm psr.i | psr.ic	// M2   turn off interrupts and interruption collection
+	cmp.eq p9,p0=r0,r0	// A    set p9 to indicate that we should restore cr.ifs
 
-	ld8 r29=[r2],16		// load cr.ipsr
-	ld8 r28=[r3],16			// load cr.iip
-	mov f8=f0		// clear f8
+	ld8 r29=[r2],16		// M0|1 load cr.ipsr
+	ld8 r28=[r3],16		// M0|1 load cr.iip
+	mov r22=r0		// A    clear r22
 	;;
 	ld8 r30=[r2],16		// M0|1 load cr.ifs
 	ld8 r25=[r3],16		// M0|1 load ar.unat
-	cmp.eq p9,p0=r0,r0	// set p9 to indicate that we should restore cr.ifs
+(pUStk) add r14=IA64_TASK_THREAD_ON_USTACK_OFFSET,r13
 	;;
 	ld8 r26=[r2],PT(B0)-PT(AR_PFS)	// M0|1 load ar.pfs
-(pKStk)	mov r22=psr		// M2 read PSR now that interrupts are disabled
-	mov f10=f0		// clear f10
-	;;
-	ld8 r21=[r2],PT(AR_RNAT)-PT(B0) // load b0
-	ld8 r27=[r3],PT(PR)-PT(AR_RSC)	// load ar.rsc
-	mov f11=f0		// clear f11
+(pKStk)	mov r22=psr			// M2   read PSR now that interrupts are disabled
+	nop 0
 	;;
-	ld8 r24=[r2],PT(AR_FPSR)-PT(AR_RNAT)	// load ar.rnat (may be garbage)
-	ld8 r31=[r3],PT(R1)-PT(PR)		// load predicates
-(pUStk) add r14=IA64_TASK_THREAD_ON_USTACK_OFFSET,r13
+	ld8 r21=[r2],PT(AR_RNAT)-PT(B0) // M0|1 load b0
+	ld8 r27=[r3],PT(PR)-PT(AR_RSC)	// M0|1 load ar.rsc
+	mov f6=f0			// F    clear f6
+	;;
+	ld8 r24=[r2],PT(AR_FPSR)-PT(AR_RNAT)	// M0|1 load ar.rnat (may be garbage)
+	ld8 r31=[r3],PT(R1)-PT(PR)		// M0|1 load predicates
+	mov f7=f0				// F    clear f7
+	;;
+	ld8 r20=[r2],PT(R12)-PT(AR_FPSR)	// M0|1 load ar.fpsr
+	ld8.fill r1=[r3],16			// M0|1 load r1
+(pUStk) mov r17=1				// A
+	;;
+(pUStk) st1 [r14]=r17				// M2|3
+	ld8.fill r13=[r3],16			// M0|1
+	mov f8=f0				// F    clear f8
+	;;
+	ld8.fill r12=[r2]			// M0|1 restore r12 (sp)
+	ld8.fill r15=[r3]			// M0|1 restore r15
+	mov b6=r18				// I0   restore b6
+
+	addl r17=THIS_CPU(ia64_phys_stacked_size_p8),r0 // A
+	mov f9=f0					// F    clear f9
+(pKStk) br.cond.dpnt.many skip_rbs_switch		// B
+
+	srlz.d				// M0   ensure interruption collection is off (for cover)
+	shr.u r18=r19,16		// I0|1 get byte size of existing "dirty" partition
+	cover				// B    add current frame into dirty partition & set cr.ifs
+	;;
+(pUStk) ld4 r17=[r17]			// M0|1 r17 = cpu_data->phys_stacked_size_p8
+	mov r19=ar.bsp			// M2   get new backing store pointer
+	mov f10=f0			// F    clear f10
+
+	nop.m 0
+	movl r14=__kernel_syscall_via_epc // X
 	;;
-	ld8 r20=[r2],PT(R12)-PT(AR_FPSR)	// load ar.fpsr
-	ld8.fill r1=[r3],16	// load r1
-(pUStk) mov r17=1
-	;;
-	srlz.d			// M0  ensure interruption collection is off
-	ld8.fill r13=[r3],16
-	mov f7=f0		// clear f7
-	;;
-	ld8.fill r12=[r2]	// restore r12 (sp)
-	mov.m ar.ssd=r0		// M2 clear ar.ssd
-	mov r22=r0		// clear r22
-
-	ld8.fill r15=[r3]	// restore r15
-(pUStk) st1 [r14]=r17
-	addl r3=THIS_CPU(ia64_phys_stacked_size_p8),r0
-	;;
-(pUStk)	ld4 r17=[r3]		// r17 = cpu_data->phys_stacked_size_p8
-	mov.m ar.csd=r0		// M2 clear ar.csd
-	mov b6=r18		// I0  restore b6
-	;;
-	mov r14=r0		// clear r14
-	shr.u r18=r19,16	// I0|1 get byte size of existing "dirty" partition
-(pKStk) br.cond.dpnt.many skip_rbs_switch
-
-	mov.m ar.ccv=r0		// clear ar.ccv
-(pNonSys) br.cond.dpnt.many dont_preserve_current_frame
-	br.cond.sptk.many rbs_switch
+	mov.m ar.csd=r0			// M2   clear ar.csd
+	mov.m ar.ccv=r0			// M2   clear ar.ccv
+	mov b7=r14			// I0   clear b7 (hint with __kernel_syscall_via_epc)
+
+	mov.m ar.ssd=r0			// M2   clear ar.ssd
+	mov f11=f0			// F    clear f11
+	br.cond.sptk.many rbs_switch	// B
 END(ia64_leave_syscall)
 
 #ifdef CONFIG_IA32_SUPPORT
@@ -885,7 +880,7 @@ GLOBAL_ENTRY(ia64_leave_kernel)
 	ldf.fill f7=[r2],PT(F11)-PT(F7)
 	ldf.fill f8=[r3],32
 	;;
-	srlz.i			// ensure interruption collection is off
+	srlz.d	// ensure that inter. collection is off (VHPT is don't care, since text is pinned)
 	mov ar.ccv=r15
 	;;
 	ldf.fill f11=[r2]
@@ -945,11 +940,10 @@ GLOBAL_ENTRY(ia64_leave_kernel)
 	 * NOTE: alloc, loadrs, and cover can't be predicated.
 	 */
 (pNonSys) br.cond.dpnt dont_preserve_current_frame
-
-rbs_switch:
 	cover				// add current frame into dirty partition and set cr.ifs
 	;;
 	mov r19=ar.bsp			// get new backing store pointer
+rbs_switch:
 	sub r16=r16,r18			// krbs = old bsp - size of dirty partition
 	cmp.ne p9,p0=r0,r0		// clear p9 to skip restore of cr.ifs
 	;;
@@ -1024,14 +1018,14 @@ rse_clear_invalid:
 	mov loc5=0
 	mov loc6=0
 	mov loc7=0
-(pRecurse) br.call.sptk.few b0=rse_clear_invalid
+(pRecurse) br.call.dptk.few b0=rse_clear_invalid
 	;;
 	mov loc8=0
 	mov loc9=0
 	cmp.ne pReturn,p0=r0,in1	// if recursion count != 0, we need to do a br.ret
 	mov loc10=0
 	mov loc11=0
-(pReturn) br.ret.sptk.many b0
+(pReturn) br.ret.dptk.many b0
 #endif /* !CONFIG_ITANIUM */
 #	undef pRecurse
 #	undef pReturn
@@ -1255,7 +1249,7 @@ ENTRY(sys_rt_sigreturn)
  	stf.spill [r17]=f11
 	adds out0=16,sp				// out0 = &sigscratch
 	br.call.sptk.many rp=ia64_rt_sigreturn
-.ret19:	.restore sp 0
+.ret19:	.restore sp,0
 	adds sp=16,sp
 	;;
 	ld8 r9=[sp]				// load new ar.unat
@@ -1577,11 +1571,11 @@ sys_call_table:
 	data8 sys_add_key
 	data8 sys_request_key
 	data8 sys_keyctl
+	data8 sys_ioprio_set
+	data8 sys_ioprio_get			// 1275
 	data8 sys_ni_syscall
-	data8 sys_ni_syscall			// 1275
-	data8 sys_ni_syscall
-	data8 sys_ni_syscall
-	data8 sys_ni_syscall
-	data8 sys_ni_syscall
+	data8 sys_inotify_init
+	data8 sys_inotify_add_watch
+	data8 sys_inotify_rm_watch
 
 	.org sys_call_table + 8*NR_syscalls	// guard against failures to increase NR_syscalls
diff --git a/arch/ia64/kernel/entry.h b/arch/ia64/kernel/entry.h
--- a/arch/ia64/kernel/entry.h
+++ b/arch/ia64/kernel/entry.h
@@ -60,7 +60,7 @@
 	.spillsp @priunat,SW(AR_UNAT)+16+(off);					\
 	.spillsp ar.rnat,SW(AR_RNAT)+16+(off);					\
 	.spillsp ar.bspstore,SW(AR_BSPSTORE)+16+(off);				\
-	.spillsp pr,SW(PR)+16+(off))
+	.spillsp pr,SW(PR)+16+(off)
 
 #define DO_SAVE_SWITCH_STACK			\
 	movl r28=1f;				\
diff --git a/arch/ia64/kernel/fsys.S b/arch/ia64/kernel/fsys.S
--- a/arch/ia64/kernel/fsys.S
+++ b/arch/ia64/kernel/fsys.S
@@ -531,93 +531,114 @@ GLOBAL_ENTRY(fsys_bubble_down)
 	.altrp b6
 	.body
 	/*
-	 * We get here for syscalls that don't have a lightweight handler.  For those, we
-	 * need to bubble down into the kernel and that requires setting up a minimal
-	 * pt_regs structure, and initializing the CPU state more or less as if an
-	 * interruption had occurred.  To make syscall-restarts work, we setup pt_regs
-	 * such that cr_iip points to the second instruction in syscall_via_break.
-	 * Decrementing the IP hence will restart the syscall via break and not
-	 * decrementing IP will return us to the caller, as usual.  Note that we preserve
-	 * the value of psr.pp rather than initializing it from dcr.pp.  This makes it
-	 * possible to distinguish fsyscall execution from other privileged execution.
+	 * We get here for syscalls that don't have a lightweight
+	 * handler.  For those, we need to bubble down into the kernel
+	 * and that requires setting up a minimal pt_regs structure,
+	 * and initializing the CPU state more or less as if an
+	 * interruption had occurred.  To make syscall-restarts work,
+	 * we setup pt_regs such that cr_iip points to the second
+	 * instruction in syscall_via_break.  Decrementing the IP
+	 * hence will restart the syscall via break and not
+	 * decrementing IP will return us to the caller, as usual.
+	 * Note that we preserve the value of psr.pp rather than
+	 * initializing it from dcr.pp.  This makes it possible to
+	 * distinguish fsyscall execution from other privileged
+	 * execution.
 	 *
 	 * On entry:
-	 *	- normal fsyscall handler register usage, except that we also have:
+	 *	- normal fsyscall handler register usage, except
+	 *	  that we also have:
 	 *	- r18: address of syscall entry point
 	 *	- r21: ar.fpsr
 	 *	- r26: ar.pfs
 	 *	- r27: ar.rsc
 	 *	- r29: psr
+	 *
+	 * We used to clear some PSR bits here but that requires slow
+	 * serialization.  Fortuntely, that isn't really necessary.
+	 * The rationale is as follows: we used to clear bits
+	 * ~PSR_PRESERVED_BITS in PSR.L.  Since
+	 * PSR_PRESERVED_BITS==PSR.{UP,MFL,MFH,PK,DT,PP,SP,RT,IC}, we
+	 * ended up clearing PSR.{BE,AC,I,DFL,DFH,DI,DB,SI,TB}.
+	 * However,
+	 *
+	 * PSR.BE : already is turned off in __kernel_syscall_via_epc()
+	 * PSR.AC : don't care (kernel normally turns PSR.AC on)
+	 * PSR.I  : already turned off by the time fsys_bubble_down gets
+	 *	    invoked
+	 * PSR.DFL: always 0 (kernel never turns it on)
+	 * PSR.DFH: don't care --- kernel never touches f32-f127 on its own
+	 *	    initiative
+	 * PSR.DI : always 0 (kernel never turns it on)
+	 * PSR.SI : always 0 (kernel never turns it on)
+	 * PSR.DB : don't care --- kernel never enables kernel-level
+	 *	    breakpoints
+	 * PSR.TB : must be 0 already; if it wasn't zero on entry to
+	 *          __kernel_syscall_via_epc, the branch to fsys_bubble_down
+	 *          will trigger a taken branch; the taken-trap-handler then
+	 *          converts the syscall into a break-based system-call.
 	 */
-#	define PSR_PRESERVED_BITS	(IA64_PSR_UP | IA64_PSR_MFL | IA64_PSR_MFH | IA64_PSR_PK \
-					 | IA64_PSR_DT | IA64_PSR_PP | IA64_PSR_SP | IA64_PSR_RT \
-					 | IA64_PSR_IC)
 	/*
-	 * Reading psr.l gives us only bits 0-31, psr.it, and psr.mc.  The rest we have
-	 * to synthesize.
+	 * Reading psr.l gives us only bits 0-31, psr.it, and psr.mc.
+	 * The rest we have to synthesize.
 	 */
-#	define PSR_ONE_BITS		((3 << IA64_PSR_CPL0_BIT) | (0x1 << IA64_PSR_RI_BIT) \
+#	define PSR_ONE_BITS		((3 << IA64_PSR_CPL0_BIT)	\
+					 | (0x1 << IA64_PSR_RI_BIT)	\
 					 | IA64_PSR_BN | IA64_PSR_I)
 
-	invala
-	movl r8=PSR_ONE_BITS
-
-	mov r25=ar.unat			// save ar.unat (5 cyc)
-	movl r9=PSR_PRESERVED_BITS
+	invala					// M0|1
+	movl r14=ia64_ret_from_syscall		// X
 
-	mov ar.rsc=0			// set enforced lazy mode, pl 0, little-endian, loadrs=0
-	movl r28=__kernel_syscall_via_break
+	nop.m 0
+	movl r28=__kernel_syscall_via_break	// X	create cr.iip
 	;;
-	mov r23=ar.bspstore		// save ar.bspstore (12 cyc)
-	mov r31=pr			// save pr (2 cyc)
-	mov r20=r1			// save caller's gp in r20
+
+	mov r2=r16				// A    get task addr to addl-addressable register
+	adds r16=IA64_TASK_THREAD_ON_USTACK_OFFSET,r16 // A
+	mov r31=pr				// I0   save pr (2 cyc)
 	;;
-	mov r2=r16			// copy current task addr to addl-addressable register
-	and r9=r9,r29
-	mov r19=b6			// save b6 (2 cyc)
+	st1 [r16]=r0				// M2|3 clear current->thread.on_ustack flag
+	addl r22=IA64_RBS_OFFSET,r2		// A    compute base of RBS
+	add r3=TI_FLAGS+IA64_TASK_SIZE,r2	// A
 	;;
-	mov psr.l=r9			// slam the door (17 cyc to srlz.i)
-	or r29=r8,r29			// construct cr.ipsr value to save
-	addl r22=IA64_RBS_OFFSET,r2	// compute base of RBS
+	ld4 r3=[r3]				// M0|1 r3 = current_thread_info()->flags
+	lfetch.fault.excl.nt1 [r22]		// M0|1 prefetch register backing-store
+	nop.i 0
 	;;
-	// GAS reports a spurious RAW hazard on the read of ar.rnat because it thinks
-	// we may be reading ar.itc after writing to psr.l.  Avoid that message with
-	// this directive:
-	dv_serialize_data
-	mov.m r24=ar.rnat		// read ar.rnat (5 cyc lat)
-	lfetch.fault.excl.nt1 [r22]
-	adds r16=IA64_TASK_THREAD_ON_USTACK_OFFSET,r2
-
-	// ensure previous insn group is issued before we stall for srlz.i:
+	mov ar.rsc=0				// M2   set enforced lazy mode, pl 0, LE, loadrs=0
+	nop.m 0
+	nop.i 0
 	;;
-	srlz.i				// ensure new psr.l has been established
-	/////////////////////////////////////////////////////////////////////////////
-	////////// from this point on, execution is not interruptible anymore
-	/////////////////////////////////////////////////////////////////////////////
-	addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r2	// compute base of memory stack
-	cmp.ne pKStk,pUStk=r0,r0	// set pKStk <- 0, pUStk <- 1
+	mov r23=ar.bspstore			// M2 (12 cyc) save ar.bspstore
+	mov.m r24=ar.rnat			// M2 (5 cyc) read ar.rnat (dual-issues!)
+	nop.i 0
 	;;
-	st1 [r16]=r0			// clear current->thread.on_ustack flag
-	mov ar.bspstore=r22		// switch to kernel RBS
-	mov b6=r18			// copy syscall entry-point to b6 (7 cyc)
-	add r3=TI_FLAGS+IA64_TASK_SIZE,r2
+	mov ar.bspstore=r22			// M2 (6 cyc) switch to kernel RBS
+	movl r8=PSR_ONE_BITS			// X
 	;;
-	ld4 r3=[r3]				// r2 = current_thread_info()->flags
-	mov r18=ar.bsp			// save (kernel) ar.bsp (12 cyc)
-	mov ar.rsc=0x3			// set eager mode, pl 0, little-endian, loadrs=0
-	br.call.sptk.many b7=ia64_syscall_setup
+	mov r25=ar.unat				// M2 (5 cyc) save ar.unat
+	mov r19=b6				// I0   save b6 (2 cyc)
+	mov r20=r1				// A    save caller's gp in r20
 	;;
-	ssm psr.i
-	movl r2=ia64_ret_from_syscall
+	or r29=r8,r29				// A    construct cr.ipsr value to save
+	mov b6=r18				// I0   copy syscall entry-point to b6 (7 cyc)
+	addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r2 // A compute base of memory stack
+
+	mov r18=ar.bsp				// M2   save (kernel) ar.bsp (12 cyc)
+	cmp.ne pKStk,pUStk=r0,r0		// A    set pKStk <- 0, pUStk <- 1
+	br.call.sptk.many b7=ia64_syscall_setup	// B
 	;;
-	mov rp=r2				// set the real return addr
-	and r3=_TIF_SYSCALL_TRACEAUDIT,r3
+	mov ar.rsc=0x3				// M2   set eager mode, pl 0, LE, loadrs=0
+	mov rp=r14				// I0   set the real return addr
+	and r3=_TIF_SYSCALL_TRACEAUDIT,r3	// A
 	;;
-	cmp.eq p8,p0=r3,r0
+	ssm psr.i				// M2   we're on kernel stacks now, reenable irqs
+	cmp.eq p8,p0=r3,r0			// A
+(p10)	br.cond.spnt.many ia64_ret_from_syscall	// B    return if bad call-frame or r15 is a NaT
 
-(p10)	br.cond.spnt.many ia64_ret_from_syscall	// p10==true means out registers are more than 8
-(p8)	br.call.sptk.many b6=b6		// ignore this return addr
-	br.cond.sptk ia64_trace_syscall
+	nop.m 0
+(p8)	br.call.sptk.many b6=b6			// B    (ignore return address)
+	br.cond.spnt ia64_trace_syscall		// B
 END(fsys_bubble_down)
 
 	.rodata
diff --git a/arch/ia64/kernel/gate.S b/arch/ia64/kernel/gate.S
--- a/arch/ia64/kernel/gate.S
+++ b/arch/ia64/kernel/gate.S
@@ -72,38 +72,40 @@ GLOBAL_ENTRY(__kernel_syscall_via_epc)
 	 * bundle get executed.  The remaining code must be safe even if
 	 * they do not get executed.
 	 */
-	adds r17=-1024,r15
-	mov r10=0				// default to successful syscall execution
-	epc
+	adds r17=-1024,r15			// A
+	mov r10=0				// A    default to successful syscall execution
+	epc					// B	causes split-issue
 }
 	;;
-	rsm psr.be // note: on McKinley "rsm psr.be/srlz.d" is slightly faster than "rum psr.be"
-	LOAD_FSYSCALL_TABLE(r14)
-
-	mov r16=IA64_KR(CURRENT)		// 12 cycle read latency
-	tnat.nz p10,p9=r15
-	mov r19=NR_syscalls-1
-	;;
-	shladd r18=r17,3,r14
-
-	srlz.d
-	cmp.ne p8,p0=r0,r0			// p8 <- FALSE
-	/* Note: if r17 is a NaT, p6 will be set to zero.  */
-	cmp.geu p6,p7=r19,r17			// (syscall > 0 && syscall < 1024+NR_syscalls)?
-	;;
-(p6)	ld8 r18=[r18]
-	mov r21=ar.fpsr
-	add r14=-8,r14				// r14 <- addr of fsys_bubble_down entry
+	rsm psr.be | psr.i			// M2 (5 cyc to srlz.d)
+	LOAD_FSYSCALL_TABLE(r14)		// X
 	;;
-(p6)	mov b7=r18
-(p6)	tbit.z p8,p0=r18,0
-(p8)	br.dptk.many b7
+	mov r16=IA64_KR(CURRENT)		// M2 (12 cyc)
+	shladd r18=r17,3,r14			// A
+	mov r19=NR_syscalls-1			// A
+	;;
+	lfetch [r18]				// M0|1
+	mov r29=psr				// M2 (12 cyc)
+	// If r17 is a NaT, p6 will be zero
+	cmp.geu p6,p7=r19,r17			// A    (sysnr > 0 && sysnr < 1024+NR_syscalls)?
+	;;
+	mov r21=ar.fpsr				// M2 (12 cyc)
+	tnat.nz p10,p9=r15			// I0
+	mov.i r26=ar.pfs			// I0 (would stall anyhow due to srlz.d...)
+	;;
+	srlz.d					// M0 (forces split-issue) ensure PSR.BE==0
+(p6)	ld8 r18=[r18]				// M0|1
+	nop.i 0
+	;;
+	nop.m 0
+(p6)	tbit.z.unc p8,p0=r18,0			// I0 (dual-issues with "mov b7=r18"!)
+	nop.i 0
+	;;
+(p8)	ssm psr.i
+(p6)	mov b7=r18				// I0
+(p8)	br.dptk.many b7				// B
 
-(p6)	rsm psr.i
-	mov r27=ar.rsc
-	mov r26=ar.pfs
-	;;
-	mov r29=psr				// read psr (12 cyc load latency)
+	mov r27=ar.rsc				// M2 (12 cyc)
 /*
  * brl.cond doesn't work as intended because the linker would convert this branch
  * into a branch to a PLT.  Perhaps there will be a way to avoid this with some
@@ -111,6 +113,8 @@ GLOBAL_ENTRY(__kernel_syscall_via_epc)
  * instead.
  */
 #ifdef CONFIG_ITANIUM
+(p6)	add r14=-8,r14				// r14 <- addr of fsys_bubble_down entry
+	;;
 (p6)	ld8 r14=[r14]				// r14 <- fsys_bubble_down
 	;;
 (p6)	mov b7=r14
@@ -118,7 +122,7 @@ GLOBAL_ENTRY(__kernel_syscall_via_epc)
 #else
 	BRL_COND_FSYS_BUBBLE_DOWN(p6)
 #endif
-
+	ssm psr.i
 	mov r10=-1
 (p10)	mov r8=EINVAL
 (p9)	mov r8=ENOSYS
diff --git a/arch/ia64/kernel/ia64_ksyms.c b/arch/ia64/kernel/ia64_ksyms.c
--- a/arch/ia64/kernel/ia64_ksyms.c
+++ b/arch/ia64/kernel/ia64_ksyms.c
@@ -58,9 +58,6 @@ EXPORT_SYMBOL(__strlen_user);
 EXPORT_SYMBOL(__strncpy_from_user);
 EXPORT_SYMBOL(__strnlen_user);
 
-#include <asm/unistd.h>
-EXPORT_SYMBOL(__ia64_syscall);
-
 /* from arch/ia64/lib */
 extern void __divsi3(void);
 extern void __udivsi3(void);
diff --git a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c
--- a/arch/ia64/kernel/iosapic.c
+++ b/arch/ia64/kernel/iosapic.c
@@ -129,14 +129,13 @@ static struct iosapic {
 	char __iomem	*addr;		/* base address of IOSAPIC */
 	unsigned int 	gsi_base;	/* first GSI assigned to this IOSAPIC */
 	unsigned short 	num_rte;	/* number of RTE in this IOSAPIC */
+	int		rtes_inuse;	/* # of RTEs in use on this IOSAPIC */
 #ifdef CONFIG_NUMA
 	unsigned short	node;		/* numa node association via pxm */
 #endif
 } iosapic_lists[NR_IOSAPICS];
 
-static int num_iosapic;
-
-static unsigned char pcat_compat __initdata;	/* 8259 compatibility flag */
+static unsigned char pcat_compat __devinitdata;	/* 8259 compatibility flag */
 
 static int iosapic_kmalloc_ok;
 static LIST_HEAD(free_rte_list);
@@ -149,7 +148,7 @@ find_iosapic (unsigned int gsi)
 {
 	int i;
 
-	for (i = 0; i < num_iosapic; i++) {
+	for (i = 0; i < NR_IOSAPICS; i++) {
 		if ((unsigned) (gsi - iosapic_lists[i].gsi_base) < iosapic_lists[i].num_rte)
 			return i;
 	}
@@ -490,8 +489,6 @@ static int iosapic_find_sharable_vector 
 			}
 		}
 	}
-	if (vector < 0)
-		panic("%s: out of interrupt vectors!\n", __FUNCTION__);
 
 	return vector;
 }
@@ -507,6 +504,8 @@ iosapic_reassign_vector (int vector)
 
 	if (!list_empty(&iosapic_intr_info[vector].rtes)) {
 		new_vector = assign_irq_vector(AUTO_ASSIGN);
+		if (new_vector < 0)
+			panic("%s: out of interrupt vectors!\n", __FUNCTION__);
 		printk(KERN_INFO "Reassigning vector %d to %d\n", vector, new_vector);
 		memcpy(&iosapic_intr_info[new_vector], &iosapic_intr_info[vector],
 		       sizeof(struct iosapic_intr_info));
@@ -598,6 +597,7 @@ register_intr (unsigned int gsi, int vec
 		rte->refcnt++;
 		list_add_tail(&rte->rte_list, &iosapic_intr_info[vector].rtes);
 		iosapic_intr_info[vector].count++;
+		iosapic_lists[index].rtes_inuse++;
 	}
 	else if (vector_is_shared(vector)) {
 		struct iosapic_intr_info *info = &iosapic_intr_info[vector];
@@ -734,9 +734,12 @@ again:
 	spin_unlock_irqrestore(&iosapic_lock, flags);
 
 	/* If vector is running out, we try to find a sharable vector */
-	vector = assign_irq_vector_nopanic(AUTO_ASSIGN);
-	if (vector < 0)
+	vector = assign_irq_vector(AUTO_ASSIGN);
+	if (vector < 0) {
 		vector = iosapic_find_sharable_vector(trigger, polarity);
+		if (vector < 0)
+			panic("%s: out of interrupt vectors!\n", __FUNCTION__);
+	}
 
 	spin_lock_irqsave(&irq_descp(vector)->lock, flags);
 	spin_lock(&iosapic_lock);
@@ -778,7 +781,7 @@ void
 iosapic_unregister_intr (unsigned int gsi)
 {
 	unsigned long flags;
-	int irq, vector;
+	int irq, vector, index;
 	irq_desc_t *idesc;
 	u32 low32;
 	unsigned long trigger, polarity;
@@ -819,6 +822,9 @@ iosapic_unregister_intr (unsigned int gs
 		list_del(&rte->rte_list);
 		iosapic_intr_info[vector].count--;
 		iosapic_free_rte(rte);
+		index = find_iosapic(gsi);
+		iosapic_lists[index].rtes_inuse--;
+		WARN_ON(iosapic_lists[index].rtes_inuse < 0);
 
 		trigger	 = iosapic_intr_info[vector].trigger;
 		polarity = iosapic_intr_info[vector].polarity;
@@ -881,6 +887,8 @@ iosapic_register_platform_intr (u32 int_
 		break;
 	      case ACPI_INTERRUPT_INIT:
 		vector = assign_irq_vector(AUTO_ASSIGN);
+		if (vector < 0)
+			panic("%s: out of interrupt vectors!\n", __FUNCTION__);
 		delivery = IOSAPIC_INIT;
 		break;
 	      case ACPI_INTERRUPT_CPEI:
@@ -952,30 +960,86 @@ iosapic_system_init (int system_pcat_com
 	}
 }
 
-void __init
+static inline int
+iosapic_alloc (void)
+{
+	int index;
+
+	for (index = 0; index < NR_IOSAPICS; index++)
+		if (!iosapic_lists[index].addr)
+			return index;
+
+	printk(KERN_WARNING "%s: failed to allocate iosapic\n", __FUNCTION__);
+	return -1;
+}
+
+static inline void
+iosapic_free (int index)
+{
+	memset(&iosapic_lists[index], 0, sizeof(iosapic_lists[0]));
+}
+
+static inline int
+iosapic_check_gsi_range (unsigned int gsi_base, unsigned int ver)
+{
+	int index;
+	unsigned int gsi_end, base, end;
+
+	/* check gsi range */
+	gsi_end = gsi_base + ((ver >> 16) & 0xff);
+	for (index = 0; index < NR_IOSAPICS; index++) {
+		if (!iosapic_lists[index].addr)
+			continue;
+
+		base = iosapic_lists[index].gsi_base;
+		end  = base + iosapic_lists[index].num_rte - 1;
+
+		if (gsi_base < base && gsi_end < base)
+			continue;/* OK */
+
+		if (gsi_base > end && gsi_end > end)
+			continue; /* OK */
+
+		return -EBUSY;
+	}
+	return 0;
+}
+
+int __devinit
 iosapic_init (unsigned long phys_addr, unsigned int gsi_base)
 {
-	int num_rte;
+	int num_rte, err, index;
 	unsigned int isa_irq, ver;
 	char __iomem *addr;
+	unsigned long flags;
 
-	addr = ioremap(phys_addr, 0);
-	ver = iosapic_version(addr);
+	spin_lock_irqsave(&iosapic_lock, flags);
+	{
+		addr = ioremap(phys_addr, 0);
+		ver = iosapic_version(addr);
 
-	/*
-	 * The MAX_REDIR register holds the highest input pin
-	 * number (starting from 0).
-	 * We add 1 so that we can use it for number of pins (= RTEs)
-	 */
-	num_rte = ((ver >> 16) & 0xff) + 1;
+		if ((err = iosapic_check_gsi_range(gsi_base, ver))) {
+			iounmap(addr);
+			spin_unlock_irqrestore(&iosapic_lock, flags);
+			return err;
+		}
+
+		/*
+		 * The MAX_REDIR register holds the highest input pin
+		 * number (starting from 0).
+		 * We add 1 so that we can use it for number of pins (= RTEs)
+		 */
+		num_rte = ((ver >> 16) & 0xff) + 1;
 
-	iosapic_lists[num_iosapic].addr = addr;
-	iosapic_lists[num_iosapic].gsi_base = gsi_base;
-	iosapic_lists[num_iosapic].num_rte = num_rte;
+		index = iosapic_alloc();
+		iosapic_lists[index].addr = addr;
+		iosapic_lists[index].gsi_base = gsi_base;
+		iosapic_lists[index].num_rte = num_rte;
 #ifdef CONFIG_NUMA
-	iosapic_lists[num_iosapic].node = MAX_NUMNODES;
+		iosapic_lists[index].node = MAX_NUMNODES;
 #endif
-	num_iosapic++;
+	}
+	spin_unlock_irqrestore(&iosapic_lock, flags);
 
 	if ((gsi_base == 0) && pcat_compat) {
 		/*
@@ -986,10 +1050,43 @@ iosapic_init (unsigned long phys_addr, u
 		for (isa_irq = 0; isa_irq < 16; ++isa_irq)
 			iosapic_override_isa_irq(isa_irq, isa_irq, IOSAPIC_POL_HIGH, IOSAPIC_EDGE);
 	}
+	return 0;
+}
+
+#ifdef CONFIG_HOTPLUG
+int
+iosapic_remove (unsigned int gsi_base)
+{
+	int index, err = 0;
+	unsigned long flags;
+
+	spin_lock_irqsave(&iosapic_lock, flags);
+	{
+		index = find_iosapic(gsi_base);
+		if (index < 0) {
+			printk(KERN_WARNING "%s: No IOSAPIC for GSI base %u\n",
+			       __FUNCTION__, gsi_base);
+			goto out;
+		}
+
+		if (iosapic_lists[index].rtes_inuse) {
+			err = -EBUSY;
+			printk(KERN_WARNING "%s: IOSAPIC for GSI base %u is busy\n",
+			       __FUNCTION__, gsi_base);
+			goto out;
+		}
+
+		iounmap(iosapic_lists[index].addr);
+		iosapic_free(index);
+	}
+ out:
+	spin_unlock_irqrestore(&iosapic_lock, flags);
+	return err;
 }
+#endif /* CONFIG_HOTPLUG */
 
 #ifdef CONFIG_NUMA
-void __init
+void __devinit
 map_iosapic_to_node(unsigned int gsi_base, int node)
 {
 	int index;
diff --git a/arch/ia64/kernel/irq_ia64.c b/arch/ia64/kernel/irq_ia64.c
--- a/arch/ia64/kernel/irq_ia64.c
+++ b/arch/ia64/kernel/irq_ia64.c
@@ -63,30 +63,19 @@ EXPORT_SYMBOL(isa_irq_to_vector_map);
 static unsigned long ia64_vector_mask[BITS_TO_LONGS(IA64_NUM_DEVICE_VECTORS)];
 
 int
-assign_irq_vector_nopanic (int irq)
+assign_irq_vector (int irq)
 {
 	int pos, vector;
  again:
 	pos = find_first_zero_bit(ia64_vector_mask, IA64_NUM_DEVICE_VECTORS);
 	vector = IA64_FIRST_DEVICE_VECTOR + pos;
 	if (vector > IA64_LAST_DEVICE_VECTOR)
-		return -1;
+		return -ENOSPC;
 	if (test_and_set_bit(pos, ia64_vector_mask))
 		goto again;
 	return vector;
 }
 
-int
-assign_irq_vector (int irq)
-{
-	int vector = assign_irq_vector_nopanic(irq);
-
-	if (vector < 0)
-		panic("assign_irq_vector: out of interrupt vectors!");
-
-	return vector;
-}
-
 void
 free_irq_vector (int vector)
 {
diff --git a/arch/ia64/kernel/ivt.S b/arch/ia64/kernel/ivt.S
--- a/arch/ia64/kernel/ivt.S
+++ b/arch/ia64/kernel/ivt.S
@@ -1,7 +1,7 @@
 /*
  * arch/ia64/kernel/ivt.S
  *
- * Copyright (C) 1998-2001, 2003 Hewlett-Packard Co
+ * Copyright (C) 1998-2001, 2003, 2005 Hewlett-Packard Co
  *	Stephane Eranian <eranian@hpl.hp.com>
  *	David Mosberger <davidm@hpl.hp.com>
  * Copyright (C) 2000, 2002-2003 Intel Co
@@ -405,17 +405,22 @@ ENTRY(nested_dtlb_miss)
 	 *		r30:	continuation address
 	 *		r31:	saved pr
 	 *
-	 * Clobbered:	b0, r18, r19, r21, psr.dt (cleared)
+	 * Clobbered:	b0, r18, r19, r21, r22, psr.dt (cleared)
 	 */
 	rsm psr.dt				// switch to using physical data addressing
 	mov r19=IA64_KR(PT_BASE)		// get the page table base address
 	shl r21=r16,3				// shift bit 60 into sign bit
+	mov r18=cr.itir
 	;;
 	shr.u r17=r16,61			// get the region number into r17
+	extr.u r18=r18,2,6			// get the faulting page size
 	;;
 	cmp.eq p6,p7=5,r17			// is faulting address in region 5?
-	shr.u r18=r16,PGDIR_SHIFT		// get bits 33-63 of faulting address
+	add r22=-PAGE_SHIFT,r18			// adjustment for hugetlb address
+	add r18=PGDIR_SHIFT-PAGE_SHIFT,r18
 	;;
+	shr.u r22=r16,r22
+	shr.u r18=r16,r18
 (p7)	dep r17=r17,r19,(PAGE_SHIFT-3),3	// put region number bits in place
 
 	srlz.d
@@ -428,7 +433,7 @@ ENTRY(nested_dtlb_miss)
 (p6)	dep r17=r18,r19,3,(PAGE_SHIFT-3)	// r17=PTA + IFA(33,42)*8
 (p7)	dep r17=r18,r17,3,(PAGE_SHIFT-6)	// r17=PTA + (((IFA(61,63) << 7) | IFA(33,39))*8)
 	cmp.eq p7,p6=0,r21			// unused address bits all zeroes?
-	shr.u r18=r16,PMD_SHIFT			// shift L2 index into position
+	shr.u r18=r22,PMD_SHIFT			// shift L2 index into position
 	;;
 	ld8 r17=[r17]				// fetch the L1 entry (may be 0)
 	;;
@@ -436,7 +441,7 @@ ENTRY(nested_dtlb_miss)
 	dep r17=r18,r17,3,(PAGE_SHIFT-3)	// compute address of L2 page table entry
 	;;
 (p7)	ld8 r17=[r17]				// fetch the L2 entry (may be 0)
-	shr.u r19=r16,PAGE_SHIFT		// shift L3 index into position
+	shr.u r19=r22,PAGE_SHIFT		// shift L3 index into position
 	;;
 (p7)	cmp.eq.or.andcm p6,p7=r17,r0		// was L2 entry NULL?
 	dep r17=r19,r17,3,(PAGE_SHIFT-3)	// compute address of L3 page table entry
@@ -687,82 +692,118 @@ ENTRY(break_fault)
 	 * to prevent leaking bits from kernel to user level.
 	 */
 	DBG_FAULT(11)
-	mov r16=IA64_KR(CURRENT)		// r16 = current task; 12 cycle read lat.
-	mov r17=cr.iim
-	mov r18=__IA64_BREAK_SYSCALL
-	mov r21=ar.fpsr
-	mov r29=cr.ipsr
-	mov r19=b6
-	mov r25=ar.unat
-	mov r27=ar.rsc
-	mov r26=ar.pfs
-	mov r28=cr.iip
-	mov r31=pr				// prepare to save predicates
-	mov r20=r1
-	;;
+	mov.m r16=IA64_KR(CURRENT)		// M2 r16 <- current task (12 cyc)
+	mov r29=cr.ipsr				// M2 (12 cyc)
+	mov r31=pr				// I0 (2 cyc)
+
+	mov r17=cr.iim				// M2 (2 cyc)
+	mov.m r27=ar.rsc			// M2 (12 cyc)
+	mov r18=__IA64_BREAK_SYSCALL		// A
+
+	mov.m ar.rsc=0				// M2
+	mov.m r21=ar.fpsr			// M2 (12 cyc)
+	mov r19=b6				// I0 (2 cyc)
+	;;
+	mov.m r23=ar.bspstore			// M2 (12 cyc)
+	mov.m r24=ar.rnat			// M2 (5 cyc)
+	mov.i r26=ar.pfs			// I0 (2 cyc)
+
+	invala					// M0|1
+	nop.m 0					// M
+	mov r20=r1				// A			save r1
+
+	nop.m 0
+	movl r30=sys_call_table			// X
+
+	mov r28=cr.iip				// M2 (2 cyc)
+	cmp.eq p0,p7=r18,r17			// I0 is this a system call?
+(p7)	br.cond.spnt non_syscall		// B  no ->
+	//
+	// From this point on, we are definitely on the syscall-path
+	// and we can use (non-banked) scratch registers.
+	//
+///////////////////////////////////////////////////////////////////////
+	mov r1=r16				// A    move task-pointer to "addl"-addressable reg
+	mov r2=r16				// A    setup r2 for ia64_syscall_setup
+	add r9=TI_FLAGS+IA64_TASK_SIZE,r16	// A	r9 = &current_thread_info()->flags
+
 	adds r16=IA64_TASK_THREAD_ON_USTACK_OFFSET,r16
-	cmp.eq p0,p7=r18,r17			// is this a system call? (p7 <- false, if so)
-(p7)	br.cond.spnt non_syscall
+	adds r15=-1024,r15			// A    subtract 1024 from syscall number
+	mov r3=NR_syscalls - 1
 	;;
-	ld1 r17=[r16]				// load current->thread.on_ustack flag
-	st1 [r16]=r0				// clear current->thread.on_ustack flag
-	add r1=-IA64_TASK_THREAD_ON_USTACK_OFFSET,r16	// set r1 for MINSTATE_START_SAVE_MIN_VIRT
+	ld1.bias r17=[r16]			// M0|1 r17 = current->thread.on_ustack flag
+	ld4 r9=[r9]				// M0|1 r9 = current_thread_info()->flags
+	extr.u r8=r29,41,2			// I0   extract ei field from cr.ipsr
+
+	shladd r30=r15,3,r30			// A    r30 = sys_call_table + 8*(syscall-1024)
+	addl r22=IA64_RBS_OFFSET,r1		// A    compute base of RBS
+	cmp.leu p6,p7=r15,r3			// A    syscall number in range?
 	;;
-	invala
 
-	/* adjust return address so we skip over the break instruction: */
+	lfetch.fault.excl.nt1 [r22]		// M0|1 prefetch RBS
+(p6)	ld8 r30=[r30]				// M0|1 load address of syscall entry point
+	tnat.nz.or p7,p0=r15			// I0	is syscall nr a NaT?
 
-	extr.u r8=r29,41,2			// extract ei field from cr.ipsr
-	;;
-	cmp.eq p6,p7=2,r8			// isr.ei==2?
-	mov r2=r1				// setup r2 for ia64_syscall_setup
-	;;
-(p6)	mov r8=0				// clear ei to 0
-(p6)	adds r28=16,r28				// switch cr.iip to next bundle cr.ipsr.ei wrapped
-(p7)	adds r8=1,r8				// increment ei to next slot
-	;;
-	cmp.eq pKStk,pUStk=r0,r17		// are we in kernel mode already?
-	dep r29=r8,r29,41,2			// insert new ei into cr.ipsr
+	mov.m ar.bspstore=r22			// M2   switch to kernel RBS
+	cmp.eq p8,p9=2,r8			// A    isr.ei==2?
 	;;
 
-	// switch from user to kernel RBS:
-	MINSTATE_START_SAVE_MIN_VIRT
-	br.call.sptk.many b7=ia64_syscall_setup
-	;;
-	MINSTATE_END_SAVE_MIN_VIRT		// switch to bank 1
-	ssm psr.ic | PSR_DEFAULT_BITS
-	;;
-	srlz.i					// guarantee that interruption collection is on
-	mov r3=NR_syscalls - 1
-	;;
-(p15)	ssm psr.i				// restore psr.i
-	// p10==true means out registers are more than 8 or r15's Nat is true
-(p10)	br.cond.spnt.many ia64_ret_from_syscall
-	;;
-	movl r16=sys_call_table
+(p8)	mov r8=0				// A    clear ei to 0
+(p7)	movl r30=sys_ni_syscall			// X
 
-	adds r15=-1024,r15			// r15 contains the syscall number---subtract 1024
-	movl r2=ia64_ret_from_syscall
-	;;
-	shladd r20=r15,3,r16			// r20 = sys_call_table + 8*(syscall-1024)
-	cmp.leu p6,p7=r15,r3			// (syscall > 0 && syscall < 1024 + NR_syscalls) ?
-	mov rp=r2				// set the real return addr
+(p8)	adds r28=16,r28				// A    switch cr.iip to next bundle
+(p9)	adds r8=1,r8				// A    increment ei to next slot
+	nop.i 0
 	;;
-(p6)	ld8 r20=[r20]				// load address of syscall entry point
-(p7)	movl r20=sys_ni_syscall
 
-	add r2=TI_FLAGS+IA64_TASK_SIZE,r13
-	;;
-	ld4 r2=[r2]				// r2 = current_thread_info()->flags
-	;;
-	and r2=_TIF_SYSCALL_TRACEAUDIT,r2	// mask trace or audit
+	mov.m r25=ar.unat			// M2 (5 cyc)
+	dep r29=r8,r29,41,2			// I0   insert new ei into cr.ipsr
+	adds r15=1024,r15			// A    restore original syscall number
+	//
+	// If any of the above loads miss in L1D, we'll stall here until
+	// the data arrives.
+	//
+///////////////////////////////////////////////////////////////////////
+	st1 [r16]=r0				// M2|3 clear current->thread.on_ustack flag
+	mov b6=r30				// I0   setup syscall handler branch reg early
+	cmp.eq pKStk,pUStk=r0,r17		// A    were we on kernel stacks already?
+
+	and r9=_TIF_SYSCALL_TRACEAUDIT,r9	// A    mask trace or audit
+	mov r18=ar.bsp				// M2 (12 cyc)
+(pKStk)	br.cond.spnt .break_fixup		// B	we're already in kernel-mode -- fix up RBS
+	;;
+.back_from_break_fixup:
+(pUStk)	addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r1 // A    compute base of memory stack
+	cmp.eq p14,p0=r9,r0			// A    are syscalls being traced/audited?
+	br.call.sptk.many b7=ia64_syscall_setup	// B
+1:
+	mov ar.rsc=0x3				// M2   set eager mode, pl 0, LE, loadrs=0
+	nop 0
+	bsw.1					// B (6 cyc) regs are saved, switch to bank 1
 	;;
-	cmp.eq p8,p0=r2,r0
-	mov b6=r20
+
+	ssm psr.ic | PSR_DEFAULT_BITS		// M2	now it's safe to re-enable intr.-collection
+	movl r3=ia64_ret_from_syscall		// X
 	;;
-(p8)	br.call.sptk.many b6=b6			// ignore this return addr
-	br.cond.sptk ia64_trace_syscall
+
+	srlz.i					// M0   ensure interruption collection is on
+	mov rp=r3				// I0   set the real return addr
+(p10)	br.cond.spnt.many ia64_ret_from_syscall	// B    return if bad call-frame or r15 is a NaT
+
+(p15)	ssm psr.i				// M2   restore psr.i
+(p14)	br.call.sptk.many b6=b6			// B    invoke syscall-handker (ignore return addr)
+	br.cond.spnt.many ia64_trace_syscall	// B	do syscall-tracing thingamagic
 	// NOT REACHED
+///////////////////////////////////////////////////////////////////////
+	// On entry, we optimistically assumed that we're coming from user-space.
+	// For the rare cases where a system-call is done from within the kernel,
+	// we fix things up at this point:
+.break_fixup:
+	add r1=-IA64_PT_REGS_SIZE,sp		// A    allocate space for pt_regs structure
+	mov ar.rnat=r24				// M2	restore kernel's AR.RNAT
+	;;
+	mov ar.bspstore=r23			// M2	restore kernel's AR.BSPSTORE
+	br.cond.sptk .back_from_break_fixup
 END(break_fault)
 
 	.org ia64_ivt+0x3000
@@ -837,8 +878,6 @@ END(interrupt)
 	 *	- r31: saved pr
 	 *	-  b0: original contents (to be saved)
 	 * On exit:
-	 *	- executing on bank 1 registers
-	 *	- psr.ic enabled, interrupts restored
 	 *	-  p10: TRUE if syscall is invoked with more than 8 out
 	 *		registers or r15's Nat is true
 	 *	-  r1: kernel's gp
@@ -846,8 +885,11 @@ END(interrupt)
 	 *	-  r8: -EINVAL if p10 is true
 	 *	- r12: points to kernel stack
 	 *	- r13: points to current task
+	 *	- r14: preserved (same as on entry)
+	 *	- p13: preserved
 	 *	- p15: TRUE if interrupts need to be re-enabled
 	 *	- ar.fpsr: set to kernel settings
+	 *	-  b6: preserved (same as on entry)
 	 */
 GLOBAL_ENTRY(ia64_syscall_setup)
 #if PT(B6) != 0
@@ -915,10 +957,10 @@ GLOBAL_ENTRY(ia64_syscall_setup)
 (p13)	mov in5=-1
 	;;
 	st8 [r16]=r21,PT(R8)-PT(AR_FPSR)	// save ar.fpsr
-	tnat.nz p14,p0=in6
+	tnat.nz p13,p0=in6
 	cmp.lt p10,p9=r11,r8	// frame size can't be more than local+8
 	;;
-	stf8 [r16]=f1		// ensure pt_regs.r8 != 0 (see handle_syscall_error)
+	mov r8=1
 (p9)	tnat.nz p10,p0=r15
 	adds r12=-16,r1		// switch to kernel memory stack (with 16 bytes of scratch)
 
@@ -929,9 +971,9 @@ GLOBAL_ENTRY(ia64_syscall_setup)
 	mov r13=r2				// establish `current'
 	movl r1=__gp				// establish kernel global pointer
 	;;
-(p14)	mov in6=-1
+	st8 [r16]=r8		// ensure pt_regs.r8 != 0 (see handle_syscall_error)
+(p13)	mov in6=-1
 (p8)	mov in7=-1
-	nop.i 0
 
 	cmp.eq pSys,pNonSys=r0,r0		// set pSys=1, pNonSys=0
 	movl r17=FPSR_DEFAULT
@@ -1002,6 +1044,8 @@ END(dispatch_illegal_op_fault)
 	FAULT(17)
 
 ENTRY(non_syscall)
+	mov ar.rsc=r27			// restore ar.rsc before SAVE_MIN_WITH_COVER
+	;;
 	SAVE_MIN_WITH_COVER
 
 	// There is no particular reason for this code to be here, other than that
@@ -1199,6 +1243,25 @@ END(disabled_fp_reg)
 // 0x5600 Entry 26 (size 16 bundles) Nat Consumption (11,23,37,50)
 ENTRY(nat_consumption)
 	DBG_FAULT(26)
+
+	mov r16=cr.ipsr
+	mov r17=cr.isr
+	mov r31=pr				// save PR
+	;;
+	and r18=0xf,r17				// r18 = cr.ipsr.code{3:0}
+	tbit.z p6,p0=r17,IA64_ISR_NA_BIT
+	;;
+	cmp.ne.or p6,p0=IA64_ISR_CODE_LFETCH,r18
+	dep r16=-1,r16,IA64_PSR_ED_BIT,1
+(p6)	br.cond.spnt 1f		// branch if (cr.ispr.na == 0 || cr.ipsr.code{3:0} != LFETCH)
+	;;
+	mov cr.ipsr=r16		// set cr.ipsr.na
+	mov pr=r31,-1
+	;;
+	rfi
+
+1:	mov pr=r31,-1
+	;;
 	FAULT(26)
 END(nat_consumption)
 
diff --git a/arch/ia64/kernel/jprobes.S b/arch/ia64/kernel/jprobes.S
new file mode 100644
--- /dev/null
+++ b/arch/ia64/kernel/jprobes.S
@@ -0,0 +1,61 @@
+/*
+ * Jprobe specific operations
+ *
+ * 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.
+ *
+ * Copyright (C) Intel Corporation, 2005
+ *
+ * 2005-May     Rusty Lynch <rusty.lynch@intel.com> and Anil S Keshavamurthy
+ *              <anil.s.keshavamurthy@intel.com> initial implementation
+ *
+ * Jprobes (a.k.a. "jump probes" which is built on-top of kprobes) allow a
+ * probe to be inserted into the beginning of a function call.  The fundamental
+ * difference between a jprobe and a kprobe is the jprobe handler is executed
+ * in the same context as the target function, while the kprobe handlers
+ * are executed in interrupt context.
+ *
+ * For jprobes we initially gain control by placing a break point in the
+ * first instruction of the targeted function.  When we catch that specific
+ * break, we:
+ *        * set the return address to our jprobe_inst_return() function
+ *        * jump to the jprobe handler function
+ *
+ * Since we fixed up the return address, the jprobe handler will return to our
+ * jprobe_inst_return() function, giving us control again.  At this point we
+ * are back in the parents frame marker, so we do yet another call to our
+ * jprobe_break() function to fix up the frame marker as it would normally
+ * exist in the target function.
+ *
+ * Our jprobe_return function then transfers control back to kprobes.c by
+ * executing a break instruction using one of our reserved numbers.  When we
+ * catch that break in kprobes.c, we continue like we do for a normal kprobe
+ * by single stepping the emulated instruction, and then returning execution
+ * to the correct location.
+ */
+#include <asm/asmmacro.h>
+
+	/*
+	 * void jprobe_break(void)
+	 */
+ENTRY(jprobe_break)
+	break.m 0x80300
+END(jprobe_break)
+
+	/*
+	 * void jprobe_inst_return(void)
+	 */
+GLOBAL_ENTRY(jprobe_inst_return)
+	br.call.sptk.many b0=jprobe_break
+END(jprobe_inst_return)
diff --git a/arch/ia64/kernel/kprobes.c b/arch/ia64/kernel/kprobes.c
new file mode 100644
--- /dev/null
+++ b/arch/ia64/kernel/kprobes.c
@@ -0,0 +1,721 @@
+/*
+ *  Kernel Probes (KProbes)
+ *  arch/ia64/kernel/kprobes.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This 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.
+ *
+ * Copyright (C) IBM Corporation, 2002, 2004
+ * Copyright (C) Intel Corporation, 2005
+ *
+ * 2005-Apr     Rusty Lynch <rusty.lynch@intel.com> and Anil S Keshavamurthy
+ *              <anil.s.keshavamurthy@intel.com> adapted from i386
+ */
+
+#include <linux/config.h>
+#include <linux/kprobes.h>
+#include <linux/ptrace.h>
+#include <linux/spinlock.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/preempt.h>
+#include <linux/moduleloader.h>
+
+#include <asm/pgtable.h>
+#include <asm/kdebug.h>
+#include <asm/sections.h>
+
+extern void jprobe_inst_return(void);
+
+/* kprobe_status settings */
+#define KPROBE_HIT_ACTIVE	0x00000001
+#define KPROBE_HIT_SS		0x00000002
+
+static struct kprobe *current_kprobe, *kprobe_prev;
+static unsigned long kprobe_status, kprobe_status_prev;
+static struct pt_regs jprobe_saved_regs;
+
+enum instruction_type {A, I, M, F, B, L, X, u};
+static enum instruction_type bundle_encoding[32][3] = {
+  { M, I, I },				/* 00 */
+  { M, I, I },				/* 01 */
+  { M, I, I },				/* 02 */
+  { M, I, I },				/* 03 */
+  { M, L, X },				/* 04 */
+  { M, L, X },				/* 05 */
+  { u, u, u },  			/* 06 */
+  { u, u, u },  			/* 07 */
+  { M, M, I },				/* 08 */
+  { M, M, I },				/* 09 */
+  { M, M, I },				/* 0A */
+  { M, M, I },				/* 0B */
+  { M, F, I },				/* 0C */
+  { M, F, I },				/* 0D */
+  { M, M, F },				/* 0E */
+  { M, M, F },				/* 0F */
+  { M, I, B },				/* 10 */
+  { M, I, B },				/* 11 */
+  { M, B, B },				/* 12 */
+  { M, B, B },				/* 13 */
+  { u, u, u },  			/* 14 */
+  { u, u, u },  			/* 15 */
+  { B, B, B },				/* 16 */
+  { B, B, B },				/* 17 */
+  { M, M, B },				/* 18 */
+  { M, M, B },				/* 19 */
+  { u, u, u },  			/* 1A */
+  { u, u, u },  			/* 1B */
+  { M, F, B },				/* 1C */
+  { M, F, B },				/* 1D */
+  { u, u, u },  			/* 1E */
+  { u, u, u },  			/* 1F */
+};
+
+/*
+ * In this function we check to see if the instruction
+ * is IP relative instruction and update the kprobe
+ * inst flag accordingly
+ */
+static void update_kprobe_inst_flag(uint template, uint  slot, uint major_opcode,
+	unsigned long kprobe_inst, struct kprobe *p)
+{
+	p->ainsn.inst_flag = 0;
+	p->ainsn.target_br_reg = 0;
+
+	if (bundle_encoding[template][slot] == B) {
+		switch (major_opcode) {
+		  case INDIRECT_CALL_OPCODE:
+	 		p->ainsn.inst_flag |= INST_FLAG_FIX_BRANCH_REG;
+ 			p->ainsn.target_br_reg = ((kprobe_inst >> 6) & 0x7);
+ 			break;
+		  case IP_RELATIVE_PREDICT_OPCODE:
+		  case IP_RELATIVE_BRANCH_OPCODE:
+			p->ainsn.inst_flag |= INST_FLAG_FIX_RELATIVE_IP_ADDR;
+ 			break;
+		  case IP_RELATIVE_CALL_OPCODE:
+ 			p->ainsn.inst_flag |= INST_FLAG_FIX_RELATIVE_IP_ADDR;
+ 			p->ainsn.inst_flag |= INST_FLAG_FIX_BRANCH_REG;
+ 			p->ainsn.target_br_reg = ((kprobe_inst >> 6) & 0x7);
+ 			break;
+		}
+ 	} else if (bundle_encoding[template][slot] == X) {
+		switch (major_opcode) {
+		  case LONG_CALL_OPCODE:
+			p->ainsn.inst_flag |= INST_FLAG_FIX_BRANCH_REG;
+			p->ainsn.target_br_reg = ((kprobe_inst >> 6) & 0x7);
+		  break;
+		}
+	}
+	return;
+}
+
+/*
+ * In this function we check to see if the instruction
+ * on which we are inserting kprobe is supported.
+ * Returns 0 if supported
+ * Returns -EINVAL if unsupported
+ */
+static int unsupported_inst(uint template, uint  slot, uint major_opcode,
+	unsigned long kprobe_inst, struct kprobe *p)
+{
+	unsigned long addr = (unsigned long)p->addr;
+
+	if (bundle_encoding[template][slot] == I) {
+		switch (major_opcode) {
+			case 0x0: //I_UNIT_MISC_OPCODE:
+			/*
+			 * Check for Integer speculation instruction
+			 * - Bit 33-35 to be equal to 0x1
+			 */
+			if (((kprobe_inst >> 33) & 0x7) == 1) {
+				printk(KERN_WARNING
+					"Kprobes on speculation inst at <0x%lx> not supported\n",
+					addr);
+				return -EINVAL;
+			}
+
+			/*
+			 * IP relative mov instruction
+			 *  - Bit 27-35 to be equal to 0x30
+			 */
+			if (((kprobe_inst >> 27) & 0x1FF) == 0x30) {
+				printk(KERN_WARNING
+					"Kprobes on \"mov r1=ip\" at <0x%lx> not supported\n",
+					addr);
+				return -EINVAL;
+
+			}
+		}
+	}
+	return 0;
+}
+
+
+/*
+ * In this function we check to see if the instruction
+ * (qp) cmpx.crel.ctype p1,p2=r2,r3
+ * on which we are inserting kprobe is cmp instruction
+ * with ctype as unc.
+ */
+static uint is_cmp_ctype_unc_inst(uint template, uint slot, uint major_opcode,
+unsigned long kprobe_inst)
+{
+	cmp_inst_t cmp_inst;
+	uint ctype_unc = 0;
+
+	if (!((bundle_encoding[template][slot] == I) ||
+		(bundle_encoding[template][slot] == M)))
+		goto out;
+
+	if (!((major_opcode == 0xC) || (major_opcode == 0xD) ||
+		(major_opcode == 0xE)))
+		goto out;
+
+	cmp_inst.l = kprobe_inst;
+	if ((cmp_inst.f.x2 == 0) || (cmp_inst.f.x2 == 1)) {
+		/* Integere compare - Register Register (A6 type)*/
+		if ((cmp_inst.f.tb == 0) && (cmp_inst.f.ta == 0)
+				&&(cmp_inst.f.c == 1))
+			ctype_unc = 1;
+	} else if ((cmp_inst.f.x2 == 2)||(cmp_inst.f.x2 == 3)) {
+		/* Integere compare - Immediate Register (A8 type)*/
+		if ((cmp_inst.f.ta == 0) &&(cmp_inst.f.c == 1))
+			ctype_unc = 1;
+	}
+out:
+	return ctype_unc;
+}
+
+/*
+ * In this function we override the bundle with
+ * the break instruction at the given slot.
+ */
+static void prepare_break_inst(uint template, uint  slot, uint major_opcode,
+	unsigned long kprobe_inst, struct kprobe *p)
+{
+	unsigned long break_inst = BREAK_INST;
+	bundle_t *bundle = &p->ainsn.insn.bundle;
+
+	/*
+	 * Copy the original kprobe_inst qualifying predicate(qp)
+	 * to the break instruction iff !is_cmp_ctype_unc_inst
+	 * because for cmp instruction with ctype equal to unc,
+	 * which is a special instruction always needs to be
+	 * executed regradless of qp
+	 */
+	if (!is_cmp_ctype_unc_inst(template, slot, major_opcode, kprobe_inst))
+		break_inst |= (0x3f & kprobe_inst);
+
+	switch (slot) {
+	  case 0:
+		bundle->quad0.slot0 = break_inst;
+		break;
+	  case 1:
+		bundle->quad0.slot1_p0 = break_inst;
+		bundle->quad1.slot1_p1 = break_inst >> (64-46);
+		break;
+	  case 2:
+		bundle->quad1.slot2 = break_inst;
+		break;
+	}
+
+	/*
+	 * Update the instruction flag, so that we can
+	 * emulate the instruction properly after we
+	 * single step on original instruction
+	 */
+	update_kprobe_inst_flag(template, slot, major_opcode, kprobe_inst, p);
+}
+
+static inline void get_kprobe_inst(bundle_t *bundle, uint slot,
+	       	unsigned long *kprobe_inst, uint *major_opcode)
+{
+	unsigned long kprobe_inst_p0, kprobe_inst_p1;
+	unsigned int template;
+
+	template = bundle->quad0.template;
+
+	switch (slot) {
+	  case 0:
+ 		*major_opcode = (bundle->quad0.slot0 >> SLOT0_OPCODE_SHIFT);
+ 		*kprobe_inst = bundle->quad0.slot0;
+		break;
+	  case 1:
+ 		*major_opcode = (bundle->quad1.slot1_p1 >> SLOT1_p1_OPCODE_SHIFT);
+  		kprobe_inst_p0 = bundle->quad0.slot1_p0;
+  		kprobe_inst_p1 = bundle->quad1.slot1_p1;
+  		*kprobe_inst = kprobe_inst_p0 | (kprobe_inst_p1 << (64-46));
+		break;
+	  case 2:
+ 		*major_opcode = (bundle->quad1.slot2 >> SLOT2_OPCODE_SHIFT);
+ 		*kprobe_inst = bundle->quad1.slot2;
+		break;
+	}
+}
+
+/* Returns non-zero if the addr is in the Interrupt Vector Table */
+static inline int in_ivt_functions(unsigned long addr)
+{
+	return (addr >= (unsigned long)__start_ivt_text
+		&& addr < (unsigned long)__end_ivt_text);
+}
+
+static int valid_kprobe_addr(int template, int slot, unsigned long addr)
+{
+	if ((slot > 2) || ((bundle_encoding[template][1] == L) && slot > 1)) {
+		printk(KERN_WARNING "Attempting to insert unaligned kprobe "
+				"at 0x%lx\n", addr);
+		return -EINVAL;
+	}
+
+ 	if (in_ivt_functions(addr)) {
+ 		printk(KERN_WARNING "Kprobes can't be inserted inside "
+				"IVT functions at 0x%lx\n", addr);
+ 		return -EINVAL;
+ 	}
+
+	if (slot == 1 && bundle_encoding[template][1] != L) {
+		printk(KERN_WARNING "Inserting kprobes on slot #1 "
+		       "is not supported\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static inline void save_previous_kprobe(void)
+{
+	kprobe_prev = current_kprobe;
+	kprobe_status_prev = kprobe_status;
+}
+
+static inline void restore_previous_kprobe(void)
+{
+	current_kprobe = kprobe_prev;
+	kprobe_status = kprobe_status_prev;
+}
+
+static inline void set_current_kprobe(struct kprobe *p)
+{
+	current_kprobe = p;
+}
+
+static void kretprobe_trampoline(void)
+{
+}
+
+/*
+ * At this point the target function has been tricked into
+ * returning into our trampoline.  Lookup the associated instance
+ * and then:
+ *    - call the handler function
+ *    - cleanup by marking the instance as unused
+ *    - long jump back to the original return address
+ */
+int trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
+{
+	struct kretprobe_instance *ri = NULL;
+	struct hlist_head *head;
+	struct hlist_node *node, *tmp;
+	unsigned long orig_ret_address = 0;
+	unsigned long trampoline_address =
+		((struct fnptr *)kretprobe_trampoline)->ip;
+
+        head = kretprobe_inst_table_head(current);
+
+	/*
+	 * It is possible to have multiple instances associated with a given
+	 * task either because an multiple functions in the call path
+	 * have a return probe installed on them, and/or more then one return
+	 * return probe was registered for a target function.
+	 *
+	 * We can handle this because:
+	 *     - instances are always inserted at the head of the list
+	 *     - when multiple return probes are registered for the same
+	 *       function, the first instance's ret_addr will point to the
+	 *       real return address, and all the rest will point to
+	 *       kretprobe_trampoline
+	 */
+	hlist_for_each_entry_safe(ri, node, tmp, head, hlist) {
+                if (ri->task != current)
+			/* another task is sharing our hash bucket */
+                        continue;
+
+		if (ri->rp && ri->rp->handler)
+			ri->rp->handler(ri, regs);
+
+		orig_ret_address = (unsigned long)ri->ret_addr;
+		recycle_rp_inst(ri);
+
+		if (orig_ret_address != trampoline_address)
+			/*
+			 * This is the real return address. Any other
+			 * instances associated with this task are for
+			 * other calls deeper on the call stack
+			 */
+			break;
+	}
+
+	BUG_ON(!orig_ret_address || (orig_ret_address == trampoline_address));
+	regs->cr_iip = orig_ret_address;
+
+	unlock_kprobes();
+	preempt_enable_no_resched();
+
+        /*
+         * By returning a non-zero value, we are telling
+         * kprobe_handler() that we have handled unlocking
+         * and re-enabling preemption.
+         */
+        return 1;
+}
+
+void arch_prepare_kretprobe(struct kretprobe *rp, struct pt_regs *regs)
+{
+	struct kretprobe_instance *ri;
+
+	if ((ri = get_free_rp_inst(rp)) != NULL) {
+		ri->rp = rp;
+		ri->task = current;
+		ri->ret_addr = (kprobe_opcode_t *)regs->b0;
+
+		/* Replace the return addr with trampoline addr */
+		regs->b0 = ((struct fnptr *)kretprobe_trampoline)->ip;
+
+		add_rp_inst(ri);
+	} else {
+		rp->nmissed++;
+	}
+}
+
+int arch_prepare_kprobe(struct kprobe *p)
+{
+	unsigned long addr = (unsigned long) p->addr;
+	unsigned long *kprobe_addr = (unsigned long *)(addr & ~0xFULL);
+	unsigned long kprobe_inst=0;
+	unsigned int slot = addr & 0xf, template, major_opcode = 0;
+	bundle_t *bundle = &p->ainsn.insn.bundle;
+
+	memcpy(&p->opcode.bundle, kprobe_addr, sizeof(bundle_t));
+	memcpy(&p->ainsn.insn.bundle, kprobe_addr, sizeof(bundle_t));
+
+ 	template = bundle->quad0.template;
+
+	if(valid_kprobe_addr(template, slot, addr))
+		return -EINVAL;
+
+	/* Move to slot 2, if bundle is MLX type and kprobe slot is 1 */
+ 	if (slot == 1 && bundle_encoding[template][1] == L)
+  		slot++;
+
+	/* Get kprobe_inst and major_opcode from the bundle */
+	get_kprobe_inst(bundle, slot, &kprobe_inst, &major_opcode);
+
+	if (unsupported_inst(template, slot, major_opcode, kprobe_inst, p))
+			return -EINVAL;
+
+	prepare_break_inst(template, slot, major_opcode, kprobe_inst, p);
+
+	return 0;
+}
+
+void arch_arm_kprobe(struct kprobe *p)
+{
+	unsigned long addr = (unsigned long)p->addr;
+	unsigned long arm_addr = addr & ~0xFULL;
+
+	memcpy((char *)arm_addr, &p->ainsn.insn.bundle, sizeof(bundle_t));
+	flush_icache_range(arm_addr, arm_addr + sizeof(bundle_t));
+}
+
+void arch_disarm_kprobe(struct kprobe *p)
+{
+	unsigned long addr = (unsigned long)p->addr;
+	unsigned long arm_addr = addr & ~0xFULL;
+
+	/* p->opcode contains the original unaltered bundle */
+	memcpy((char *) arm_addr, (char *) &p->opcode.bundle, sizeof(bundle_t));
+	flush_icache_range(arm_addr, arm_addr + sizeof(bundle_t));
+}
+
+void arch_remove_kprobe(struct kprobe *p)
+{
+}
+
+/*
+ * We are resuming execution after a single step fault, so the pt_regs
+ * structure reflects the register state after we executed the instruction
+ * located in the kprobe (p->ainsn.insn.bundle).  We still need to adjust
+ * the ip to point back to the original stack address. To set the IP address
+ * to original stack address, handle the case where we need to fixup the
+ * relative IP address and/or fixup branch register.
+ */
+static void resume_execution(struct kprobe *p, struct pt_regs *regs)
+{
+  	unsigned long bundle_addr = ((unsigned long) (&p->opcode.bundle)) & ~0xFULL;
+  	unsigned long resume_addr = (unsigned long)p->addr & ~0xFULL;
+ 	unsigned long template;
+ 	int slot = ((unsigned long)p->addr & 0xf);
+
+	template = p->opcode.bundle.quad0.template;
+
+ 	if (slot == 1 && bundle_encoding[template][1] == L)
+ 		slot = 2;
+
+	if (p->ainsn.inst_flag) {
+
+		if (p->ainsn.inst_flag & INST_FLAG_FIX_RELATIVE_IP_ADDR) {
+			/* Fix relative IP address */
+ 			regs->cr_iip = (regs->cr_iip - bundle_addr) + resume_addr;
+		}
+
+		if (p->ainsn.inst_flag & INST_FLAG_FIX_BRANCH_REG) {
+		/*
+		 * Fix target branch register, software convention is
+		 * to use either b0 or b6 or b7, so just checking
+		 * only those registers
+		 */
+			switch (p->ainsn.target_br_reg) {
+			case 0:
+				if ((regs->b0 == bundle_addr) ||
+					(regs->b0 == bundle_addr + 0x10)) {
+					regs->b0 = (regs->b0 - bundle_addr) +
+						resume_addr;
+				}
+				break;
+			case 6:
+				if ((regs->b6 == bundle_addr) ||
+					(regs->b6 == bundle_addr + 0x10)) {
+					regs->b6 = (regs->b6 - bundle_addr) +
+						resume_addr;
+				}
+				break;
+			case 7:
+				if ((regs->b7 == bundle_addr) ||
+					(regs->b7 == bundle_addr + 0x10)) {
+					regs->b7 = (regs->b7 - bundle_addr) +
+						resume_addr;
+				}
+				break;
+			} /* end switch */
+		}
+		goto turn_ss_off;
+	}
+
+	if (slot == 2) {
+ 		if (regs->cr_iip == bundle_addr + 0x10) {
+ 			regs->cr_iip = resume_addr + 0x10;
+ 		}
+ 	} else {
+ 		if (regs->cr_iip == bundle_addr) {
+ 			regs->cr_iip = resume_addr;
+ 		}
+	}
+
+turn_ss_off:
+  	/* Turn off Single Step bit */
+  	ia64_psr(regs)->ss = 0;
+}
+
+static void prepare_ss(struct kprobe *p, struct pt_regs *regs)
+{
+	unsigned long bundle_addr = (unsigned long) &p->opcode.bundle;
+	unsigned long slot = (unsigned long)p->addr & 0xf;
+
+	/* Update instruction pointer (IIP) and slot number (IPSR.ri) */
+	regs->cr_iip = bundle_addr & ~0xFULL;
+
+	if (slot > 2)
+		slot = 0;
+
+	ia64_psr(regs)->ri = slot;
+
+	/* turn on single stepping */
+	ia64_psr(regs)->ss = 1;
+}
+
+static int pre_kprobes_handler(struct die_args *args)
+{
+	struct kprobe *p;
+	int ret = 0;
+	struct pt_regs *regs = args->regs;
+	kprobe_opcode_t *addr = (kprobe_opcode_t *)instruction_pointer(regs);
+
+	preempt_disable();
+
+	/* Handle recursion cases */
+	if (kprobe_running()) {
+		p = get_kprobe(addr);
+		if (p) {
+			if (kprobe_status == KPROBE_HIT_SS) {
+				unlock_kprobes();
+				goto no_kprobe;
+			}
+			/* We have reentered the pre_kprobe_handler(), since
+			 * another probe was hit while within the handler.
+			 * We here save the original kprobes variables and
+			 * just single step on the instruction of the new probe
+			 * without calling any user handlers.
+			 */
+			save_previous_kprobe();
+			set_current_kprobe(p);
+			p->nmissed++;
+			prepare_ss(p, regs);
+			kprobe_status = KPROBE_REENTER;
+			return 1;
+		} else if (args->err == __IA64_BREAK_JPROBE) {
+			/*
+			 * jprobe instrumented function just completed
+			 */
+			p = current_kprobe;
+			if (p->break_handler && p->break_handler(p, regs)) {
+				goto ss_probe;
+			}
+		} else {
+			/* Not our break */
+			goto no_kprobe;
+		}
+	}
+
+	lock_kprobes();
+	p = get_kprobe(addr);
+	if (!p) {
+		unlock_kprobes();
+		goto no_kprobe;
+	}
+
+	kprobe_status = KPROBE_HIT_ACTIVE;
+	set_current_kprobe(p);
+
+	if (p->pre_handler && p->pre_handler(p, regs))
+		/*
+		 * Our pre-handler is specifically requesting that we just
+		 * do a return.  This is used for both the jprobe pre-handler
+		 * and the kretprobe trampoline
+		 */
+		return 1;
+
+ss_probe:
+	prepare_ss(p, regs);
+	kprobe_status = KPROBE_HIT_SS;
+	return 1;
+
+no_kprobe:
+	preempt_enable_no_resched();
+	return ret;
+}
+
+static int post_kprobes_handler(struct pt_regs *regs)
+{
+	if (!kprobe_running())
+		return 0;
+
+	if ((kprobe_status != KPROBE_REENTER) && current_kprobe->post_handler) {
+		kprobe_status = KPROBE_HIT_SSDONE;
+		current_kprobe->post_handler(current_kprobe, regs, 0);
+	}
+
+	resume_execution(current_kprobe, regs);
+
+	/*Restore back the original saved kprobes variables and continue. */
+	if (kprobe_status == KPROBE_REENTER) {
+		restore_previous_kprobe();
+		goto out;
+	}
+
+	unlock_kprobes();
+
+out:
+	preempt_enable_no_resched();
+	return 1;
+}
+
+static int kprobes_fault_handler(struct pt_regs *regs, int trapnr)
+{
+	if (!kprobe_running())
+		return 0;
+
+	if (current_kprobe->fault_handler &&
+	    current_kprobe->fault_handler(current_kprobe, regs, trapnr))
+		return 1;
+
+	if (kprobe_status & KPROBE_HIT_SS) {
+		resume_execution(current_kprobe, regs);
+		unlock_kprobes();
+		preempt_enable_no_resched();
+	}
+
+	return 0;
+}
+
+int kprobe_exceptions_notify(struct notifier_block *self, unsigned long val,
+			     void *data)
+{
+	struct die_args *args = (struct die_args *)data;
+	switch(val) {
+	case DIE_BREAK:
+		if (pre_kprobes_handler(args))
+			return NOTIFY_STOP;
+		break;
+	case DIE_SS:
+		if (post_kprobes_handler(args->regs))
+			return NOTIFY_STOP;
+		break;
+	case DIE_PAGE_FAULT:
+		if (kprobes_fault_handler(args->regs, args->trapnr))
+			return NOTIFY_STOP;
+	default:
+		break;
+	}
+	return NOTIFY_DONE;
+}
+
+int setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
+{
+	struct jprobe *jp = container_of(p, struct jprobe, kp);
+	unsigned long addr = ((struct fnptr *)(jp->entry))->ip;
+
+	/* save architectural state */
+	jprobe_saved_regs = *regs;
+
+	/* after rfi, execute the jprobe instrumented function */
+	regs->cr_iip = addr & ~0xFULL;
+	ia64_psr(regs)->ri = addr & 0xf;
+	regs->r1 = ((struct fnptr *)(jp->entry))->gp;
+
+	/*
+	 * fix the return address to our jprobe_inst_return() function
+	 * in the jprobes.S file
+	 */
+ 	regs->b0 = ((struct fnptr *)(jprobe_inst_return))->ip;
+
+	return 1;
+}
+
+int longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
+{
+	*regs = jprobe_saved_regs;
+	return 1;
+}
+
+static struct kprobe trampoline_p = {
+	.pre_handler = trampoline_probe_handler
+};
+
+int __init arch_init_kprobes(void)
+{
+	trampoline_p.addr =
+		(kprobe_opcode_t *)((struct fnptr *)kretprobe_trampoline)->ip;
+	return register_kprobe(&trampoline_p);
+}
diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c
--- a/arch/ia64/kernel/mca.c
+++ b/arch/ia64/kernel/mca.c
@@ -271,7 +271,7 @@ ia64_mca_log_sal_error_record(int sal_in
 
 #ifdef CONFIG_ACPI
 
-static int cpe_vector = -1;
+int cpe_vector = -1;
 
 static irqreturn_t
 ia64_mca_cpe_int_handler (int cpe_irq, void *arg, struct pt_regs *ptregs)
diff --git a/arch/ia64/kernel/numa.c b/arch/ia64/kernel/numa.c
new file mode 100644
--- /dev/null
+++ b/arch/ia64/kernel/numa.c
@@ -0,0 +1,57 @@
+/*
+ * 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
+ *
+ * ia64 kernel NUMA specific stuff
+ *
+ * Copyright (C) 2002 Erich Focht <efocht@ess.nec.de>
+ * Copyright (C) 2004 Silicon Graphics, Inc.
+ *   Jesse Barnes <jbarnes@sgi.com>
+ */
+#include <linux/config.h>
+#include <linux/topology.h>
+#include <linux/module.h>
+#include <asm/processor.h>
+#include <asm/smp.h>
+
+u8 cpu_to_node_map[NR_CPUS] __cacheline_aligned;
+EXPORT_SYMBOL(cpu_to_node_map);
+
+cpumask_t node_to_cpu_mask[MAX_NUMNODES] __cacheline_aligned;
+
+/**
+ * build_cpu_to_node_map - setup cpu to node and node to cpumask arrays
+ *
+ * Build cpu to node mapping and initialize the per node cpu masks using
+ * info from the node_cpuid array handed to us by ACPI.
+ */
+void __init build_cpu_to_node_map(void)
+{
+	int cpu, i, node;
+
+	for(node=0; node < MAX_NUMNODES; node++)
+		cpus_clear(node_to_cpu_mask[node]);
+
+	for(cpu = 0; cpu < NR_CPUS; ++cpu) {
+		node = -1;
+		for (i = 0; i < NR_CPUS; ++i)
+			if (cpu_physical_id(cpu) == node_cpuid[i].phys_id) {
+				node = node_cpuid[i].nid;
+				break;
+			}
+		cpu_to_node_map[cpu] = (node >= 0) ? node : 0;
+		if (node >= 0)
+			cpu_set(cpu, node_to_cpu_mask[node]);
+	}
+}
diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c
--- a/arch/ia64/kernel/perfmon.c
+++ b/arch/ia64/kernel/perfmon.c
@@ -37,7 +37,6 @@
 #include <linux/vfs.h>
 #include <linux/pagemap.h>
 #include <linux/mount.h>
-#include <linux/version.h>
 #include <linux/bitops.h>
 
 #include <asm/errno.h>
@@ -4313,6 +4312,7 @@ pfm_context_load(pfm_context_t *ctx, voi
 	DPRINT(("before cmpxchg() old_ctx=%p new_ctx=%p\n",
 		thread->pfm_context, ctx));
 
+	ret = -EBUSY;
 	old = ia64_cmpxchg(acq, &thread->pfm_context, NULL, ctx, sizeof(pfm_context_t *));
 	if (old != NULL) {
 		DPRINT(("load_pid [%d] already has a context\n", req->load_pid));
diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c
--- a/arch/ia64/kernel/process.c
+++ b/arch/ia64/kernel/process.c
@@ -27,6 +27,7 @@
 #include <linux/efi.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
+#include <linux/kprobes.h>
 
 #include <asm/cpu.h>
 #include <asm/delay.h>
@@ -178,7 +179,7 @@ static int can_do_pal_halt = 1;
 
 static int __init nohalt_setup(char * str)
 {
-	pal_halt = 0;
+	pal_halt = can_do_pal_halt = 0;
 	return 1;
 }
 __setup("nohalt", nohalt_setup);
@@ -195,6 +196,7 @@ update_pal_halt_status(int status)
 void
 default_idle (void)
 {
+	local_irq_enable();
 	while (!need_resched())
 		if (can_do_pal_halt)
 			safe_halt();
@@ -707,6 +709,13 @@ kernel_thread_helper (int (*fn)(void *),
 void
 flush_thread (void)
 {
+	/*
+	 * Remove function-return probe instances associated with this task
+	 * and put them back on the free list. Do not insert an exit probe for
+	 * this function, it will be disabled by kprobe_flush_task if you do.
+	 */
+	kprobe_flush_task(current);
+
 	/* drop floating-point and debug-register state if it exists: */
 	current->thread.flags &= ~(IA64_THREAD_FPH_VALID | IA64_THREAD_DBG_VALID);
 	ia64_drop_fpu(current);
@@ -721,6 +730,14 @@ flush_thread (void)
 void
 exit_thread (void)
 {
+
+	/*
+	 * Remove function-return probe instances associated with this task
+	 * and put them back on the free list. Do not insert an exit probe for
+	 * this function, it will be disabled by kprobe_flush_task if you do.
+	 */
+	kprobe_flush_task(current);
+
 	ia64_drop_fpu(current);
 #ifdef CONFIG_PERFMON
        /* if needed, stop monitoring and flush state to perfmon context */
@@ -790,16 +807,12 @@ machine_restart (char *restart_cmd)
 	(*efi.reset_system)(EFI_RESET_WARM, 0, 0, NULL);
 }
 
-EXPORT_SYMBOL(machine_restart);
-
 void
 machine_halt (void)
 {
 	cpu_halt();
 }
 
-EXPORT_SYMBOL(machine_halt);
-
 void
 machine_power_off (void)
 {
@@ -808,4 +821,3 @@ machine_power_off (void)
 	machine_halt();
 }
 
-EXPORT_SYMBOL(machine_power_off);
diff --git a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c
--- a/arch/ia64/kernel/ptrace.c
+++ b/arch/ia64/kernel/ptrace.c
@@ -725,12 +725,32 @@ convert_to_non_syscall (struct task_stru
 			break;
 	}
 
+	/*
+	 * Note: at the time of this call, the target task is blocked
+	 * in notify_resume_user() and by clearling PRED_LEAVE_SYSCALL
+	 * (aka, "pLvSys") we redirect execution from
+	 * .work_pending_syscall_end to .work_processed_kernel.
+	 */
 	unw_get_pr(&prev_info, &pr);
-	pr &= ~(1UL << PRED_SYSCALL);
+	pr &= ~((1UL << PRED_SYSCALL) | (1UL << PRED_LEAVE_SYSCALL));
 	pr |=  (1UL << PRED_NON_SYSCALL);
 	unw_set_pr(&prev_info, pr);
 
 	pt->cr_ifs = (1UL << 63) | cfm;
+	/*
+	 * Clear the memory that is NOT written on syscall-entry to
+	 * ensure we do not leak kernel-state to user when execution
+	 * resumes.
+	 */
+	pt->r2 = 0;
+	pt->r3 = 0;
+	pt->r14 = 0;
+	memset(&pt->r16, 0, 16*8);	/* clear r16-r31 */
+	memset(&pt->f6, 0, 6*16);	/* clear f6-f11 */
+	pt->b7 = 0;
+	pt->ar_ccv = 0;
+	pt->ar_csd = 0;
+	pt->ar_ssd = 0;
 }
 
 static int
@@ -945,6 +965,13 @@ access_uarea (struct task_struct *child,
 				*data = (pt->cr_ipsr & IPSR_MASK);
 			return 0;
 
+		      case PT_AR_RSC:
+			if (write_access)
+				pt->ar_rsc = *data | (3 << 2); /* force PL3 */
+			else
+				*data = pt->ar_rsc;
+			return 0;
+
 		      case PT_AR_RNAT:
 			urbs_end = ia64_get_user_rbs_end(child, pt, NULL);
 			rnat_addr = (long) ia64_rse_rnat_addr((long *)
@@ -996,9 +1023,6 @@ access_uarea (struct task_struct *child,
 		      case PT_AR_BSPSTORE:
 			ptr = pt_reg_addr(pt, ar_bspstore);
 			break;
-		      case PT_AR_RSC:
-			ptr = pt_reg_addr(pt, ar_rsc);
-			break;
 		      case PT_AR_UNAT:
 			ptr = pt_reg_addr(pt, ar_unat);
 			break;
@@ -1234,7 +1258,7 @@ ptrace_getregs (struct task_struct *chil
 static long
 ptrace_setregs (struct task_struct *child, struct pt_all_user_regs __user *ppr)
 {
-	unsigned long psr, ec, lc, rnat, bsp, cfm, nat_bits, val = 0;
+	unsigned long psr, rsc, ec, lc, rnat, bsp, cfm, nat_bits, val = 0;
 	struct unw_frame_info info;
 	struct switch_stack *sw;
 	struct ia64_fpreg fpval;
@@ -1267,7 +1291,7 @@ ptrace_setregs (struct task_struct *chil
 	/* app regs */
 
 	retval |= __get_user(pt->ar_pfs, &ppr->ar[PT_AUR_PFS]);
-	retval |= __get_user(pt->ar_rsc, &ppr->ar[PT_AUR_RSC]);
+	retval |= __get_user(rsc, &ppr->ar[PT_AUR_RSC]);
 	retval |= __get_user(pt->ar_bspstore, &ppr->ar[PT_AUR_BSPSTORE]);
 	retval |= __get_user(pt->ar_unat, &ppr->ar[PT_AUR_UNAT]);
 	retval |= __get_user(pt->ar_ccv, &ppr->ar[PT_AUR_CCV]);
@@ -1365,6 +1389,7 @@ ptrace_setregs (struct task_struct *chil
 	retval |= __get_user(nat_bits, &ppr->nat);
 
 	retval |= access_uarea(child, PT_CR_IPSR, &psr, 1);
+	retval |= access_uarea(child, PT_AR_RSC, &rsc, 1);
 	retval |= access_uarea(child, PT_AR_EC, &ec, 1);
 	retval |= access_uarea(child, PT_AR_LC, &lc, 1);
 	retval |= access_uarea(child, PT_AR_RNAT, &rnat, 1);
diff --git a/arch/ia64/kernel/salinfo.c b/arch/ia64/kernel/salinfo.c
--- a/arch/ia64/kernel/salinfo.c
+++ b/arch/ia64/kernel/salinfo.c
@@ -143,7 +143,8 @@ struct salinfo_data {
 
 static struct salinfo_data salinfo_data[ARRAY_SIZE(salinfo_log_name)];
 
-static spinlock_t data_lock, data_saved_lock;
+static DEFINE_SPINLOCK(data_lock);
+static DEFINE_SPINLOCK(data_saved_lock);
 
 /** salinfo_platform_oemdata - optional callback to decode oemdata from an error
  * record.
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c
--- a/arch/ia64/kernel/setup.c
+++ b/arch/ia64/kernel/setup.c
@@ -20,6 +20,7 @@
  * 02/01/00 R.Seth	fixed get_cpuinfo for SMP
  * 01/07/99 S.Eranian	added the support for command line argument
  * 06/24/99 W.Drummond	added boot_cpu_data.
+ * 05/28/05 Z. Menyhart	Dynamic stride size for "flush_icache_range()"
  */
 #include <linux/config.h>
 #include <linux/module.h>
@@ -40,6 +41,8 @@
 #include <linux/serial_core.h>
 #include <linux/efi.h>
 #include <linux/initrd.h>
+#include <linux/platform.h>
+#include <linux/pm.h>
 
 #include <asm/ia32.h>
 #include <asm/machvec.h>
@@ -72,6 +75,8 @@ DEFINE_PER_CPU(unsigned long, ia64_phys_
 unsigned long ia64_cycles_per_usec;
 struct ia64_boot_param *ia64_boot_param;
 struct screen_info screen_info;
+unsigned long vga_console_iobase;
+unsigned long vga_console_membase;
 
 unsigned long ia64_max_cacheline_size;
 unsigned long ia64_iobase;	/* virtual address for I/O accesses */
@@ -81,6 +86,13 @@ EXPORT_SYMBOL(io_space);
 unsigned int num_io_spaces;
 
 /*
+ * "flush_icache_range()" needs to know what processor dependent stride size to use
+ * when it makes i-cache(s) coherent with d-caches.
+ */
+#define	I_CACHE_STRIDE_SHIFT	5	/* Safest way to go: 32 bytes by 32 bytes */
+unsigned long ia64_i_cache_stride_shift = ~0;
+
+/*
  * The merge_mask variable needs to be set to (max(iommu_page_size(iommu)) - 1).  This
  * mask specifies a mask of address bits that must be 0 in order for two buffers to be
  * mergeable by the I/O MMU (i.e., the end address of the first buffer and the start
@@ -273,23 +285,25 @@ io_port_init (void)
 static inline int __init
 early_console_setup (char *cmdline)
 {
+	int earlycons = 0;
+
 #ifdef CONFIG_SERIAL_SGI_L1_CONSOLE
 	{
 		extern int sn_serial_console_early_setup(void);
 		if (!sn_serial_console_early_setup())
-			return 0;
+			earlycons++;
 	}
 #endif
 #ifdef CONFIG_EFI_PCDP
 	if (!efi_setup_pcdp_console(cmdline))
-		return 0;
+		earlycons++;
 #endif
 #ifdef CONFIG_SERIAL_8250_CONSOLE
 	if (!early_serial_console_init(cmdline))
-		return 0;
+		earlycons++;
 #endif
 
-	return -1;
+	return (earlycons) ? 0 : -1;
 }
 
 static inline void
@@ -622,6 +636,12 @@ setup_per_cpu_areas (void)
 	/* start_kernel() requires this... */
 }
 
+/*
+ * Calculate the max. cache line size.
+ *
+ * In addition, the minimum of the i-cache stride sizes is calculated for
+ * "flush_icache_range()".
+ */
 static void
 get_max_cacheline_size (void)
 {
@@ -635,6 +655,8 @@ get_max_cacheline_size (void)
                 printk(KERN_ERR "%s: ia64_pal_cache_summary() failed (status=%ld)\n",
                        __FUNCTION__, status);
                 max = SMP_CACHE_BYTES;
+		/* Safest setup for "flush_icache_range()" */
+		ia64_i_cache_stride_shift = I_CACHE_STRIDE_SHIFT;
 		goto out;
         }
 
@@ -643,14 +665,31 @@ get_max_cacheline_size (void)
 						    &cci);
 		if (status != 0) {
 			printk(KERN_ERR
-			       "%s: ia64_pal_cache_config_info(l=%lu) failed (status=%ld)\n",
+			       "%s: ia64_pal_cache_config_info(l=%lu, 2) failed (status=%ld)\n",
 			       __FUNCTION__, l, status);
 			max = SMP_CACHE_BYTES;
+			/* The safest setup for "flush_icache_range()" */
+			cci.pcci_stride = I_CACHE_STRIDE_SHIFT;
+			cci.pcci_unified = 1;
 		}
 		line_size = 1 << cci.pcci_line_size;
 		if (line_size > max)
 			max = line_size;
-        }
+		if (!cci.pcci_unified) {
+			status = ia64_pal_cache_config_info(l,
+						    /* cache_type (instruction)= */ 1,
+						    &cci);
+			if (status != 0) {
+				printk(KERN_ERR
+				"%s: ia64_pal_cache_config_info(l=%lu, 1) failed (status=%ld)\n",
+					__FUNCTION__, l, status);
+				/* The safest setup for "flush_icache_range()" */
+				cci.pcci_stride = I_CACHE_STRIDE_SHIFT;
+			}
+		}
+		if (cci.pcci_stride < ia64_i_cache_stride_shift)
+			ia64_i_cache_stride_shift = cci.pcci_stride;
+	}
   out:
 	if (max > ia64_max_cacheline_size)
 		ia64_max_cacheline_size = max;
@@ -779,6 +818,7 @@ cpu_init (void)
 	/* size of physical stacked register partition plus 8 bytes: */
 	__get_cpu_var(ia64_phys_stacked_size_p8) = num_phys_stacked*8 + 8;
 	platform_cpu_init();
+	pm_idle = default_idle;
 }
 
 void
diff --git a/arch/ia64/kernel/signal.c b/arch/ia64/kernel/signal.c
--- a/arch/ia64/kernel/signal.c
+++ b/arch/ia64/kernel/signal.c
@@ -94,7 +94,7 @@ sys_sigaltstack (const stack_t __user *u
 static long
 restore_sigcontext (struct sigcontext __user *sc, struct sigscratch *scr)
 {
-	unsigned long ip, flags, nat, um, cfm;
+	unsigned long ip, flags, nat, um, cfm, rsc;
 	long err;
 
 	/* Always make any pending restarted system calls return -EINTR */
@@ -106,7 +106,7 @@ restore_sigcontext (struct sigcontext __
 	err |= __get_user(ip, &sc->sc_ip);			/* instruction pointer */
 	err |= __get_user(cfm, &sc->sc_cfm);
 	err |= __get_user(um, &sc->sc_um);			/* user mask */
-	err |= __get_user(scr->pt.ar_rsc, &sc->sc_ar_rsc);
+	err |= __get_user(rsc, &sc->sc_ar_rsc);
 	err |= __get_user(scr->pt.ar_unat, &sc->sc_ar_unat);
 	err |= __get_user(scr->pt.ar_fpsr, &sc->sc_ar_fpsr);
 	err |= __get_user(scr->pt.ar_pfs, &sc->sc_ar_pfs);
@@ -119,6 +119,7 @@ restore_sigcontext (struct sigcontext __
 	err |= __copy_from_user(&scr->pt.r15, &sc->sc_gr[15], 8);	/* r15 */
 
 	scr->pt.cr_ifs = cfm | (1UL << 63);
+	scr->pt.ar_rsc = rsc | (3 << 2); /* force PL3 */
 
 	/* establish new instruction pointer: */
 	scr->pt.cr_iip = ip & ~0x3UL;
@@ -142,6 +143,7 @@ restore_sigcontext (struct sigcontext __
 
 		__copy_from_user(current->thread.fph, &sc->sc_fr[32], 96*16);
 		psr->mfh = 0;	/* drop signal handler's fph contents... */
+		preempt_disable();
 		if (psr->dfh)
 			ia64_drop_fpu(current);
 		else {
@@ -149,6 +151,7 @@ restore_sigcontext (struct sigcontext __
 			__ia64_load_fpu(current->thread.fph);
 			ia64_set_local_fpu_owner(current);
 		}
+		preempt_enable();
 	}
 	return err;
 }
diff --git a/arch/ia64/kernel/smp.c b/arch/ia64/kernel/smp.c
--- a/arch/ia64/kernel/smp.c
+++ b/arch/ia64/kernel/smp.c
@@ -231,13 +231,16 @@ smp_flush_tlb_all (void)
 void
 smp_flush_tlb_mm (struct mm_struct *mm)
 {
+	preempt_disable();
 	/* this happens for the common case of a single-threaded fork():  */
 	if (likely(mm == current->active_mm && atomic_read(&mm->mm_users) == 1))
 	{
 		local_finish_flush_tlb_mm(mm);
+		preempt_enable();
 		return;
 	}
 
+	preempt_enable();
 	/*
 	 * We could optimize this further by using mm->cpu_vm_mask to track which CPUs
 	 * have been running in the address space.  It's not clear that this is worth the
@@ -269,7 +272,7 @@ smp_call_function_single (int cpuid, voi
 	int me = get_cpu(); /* prevent preemption and reschedule on another processor */
 
 	if (cpuid == me) {
-		printk("%s: trying to call self\n", __FUNCTION__);
+		printk(KERN_INFO "%s: trying to call self\n", __FUNCTION__);
 		put_cpu();
 		return -EBUSY;
 	}
diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c
--- a/arch/ia64/kernel/smpboot.c
+++ b/arch/ia64/kernel/smpboot.c
@@ -346,6 +346,7 @@ smp_callin (void)
 	lock_ipi_calllock();
 	cpu_set(cpuid, cpu_online_map);
 	unlock_ipi_calllock();
+	per_cpu(cpu_state, cpuid) = CPU_ONLINE;
 
 	smp_setup_percpu_timer();
 
@@ -524,47 +525,6 @@ smp_build_cpu_map (void)
 	}
 }
 
-#ifdef CONFIG_NUMA
-
-/* on which node is each logical CPU (one cacheline even for 64 CPUs) */
-u8 cpu_to_node_map[NR_CPUS] __cacheline_aligned;
-EXPORT_SYMBOL(cpu_to_node_map);
-/* which logical CPUs are on which nodes */
-cpumask_t node_to_cpu_mask[MAX_NUMNODES] __cacheline_aligned;
-
-/*
- * Build cpu to node mapping and initialize the per node cpu masks.
- */
-void __init
-build_cpu_to_node_map (void)
-{
-	int cpu, i, node;
-
-	for(node=0; node<MAX_NUMNODES; node++)
-		cpus_clear(node_to_cpu_mask[node]);
-	for(cpu = 0; cpu < NR_CPUS; ++cpu) {
-		/*
-		 * All Itanium NUMA platforms I know use ACPI, so maybe we
-		 * can drop this ifdef completely.                    [EF]
-		 */
-#ifdef CONFIG_ACPI_NUMA
-		node = -1;
-		for (i = 0; i < NR_CPUS; ++i)
-			if (cpu_physical_id(cpu) == node_cpuid[i].phys_id) {
-				node = node_cpuid[i].nid;
-				break;
-			}
-#else
-#		error Fixme: Dunno how to build CPU-to-node map.
-#endif
-		cpu_to_node_map[cpu] = (node >= 0) ? node : 0;
-		if (node >= 0)
-			cpu_set(cpu, node_to_cpu_mask[node]);
-	}
-}
-
-#endif /* CONFIG_NUMA */
-
 /*
  * Cycle through the APs sending Wakeup IPIs to boot each.
  */
@@ -611,6 +571,7 @@ void __devinit smp_prepare_boot_cpu(void
 {
 	cpu_set(smp_processor_id(), cpu_online_map);
 	cpu_set(smp_processor_id(), cpu_callin_map);
+	per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE;
 }
 
 /*
@@ -688,6 +649,7 @@ int __cpu_disable(void)
 		return -EBUSY;
 
 	remove_siblinginfo(cpu);
+	cpu_clear(cpu, cpu_online_map);
 	fixup_irqs();
 	local_flush_tlb_all();
 	cpu_clear(cpu, cpu_callin_map);
@@ -774,6 +736,7 @@ __cpu_up (unsigned int cpu)
 	if (cpu_isset(cpu, cpu_callin_map))
 		return -EINVAL;
 
+	per_cpu(cpu_state, cpu) = CPU_UP_PREPARE;
 	/* Processor goes to start_secondary(), sets online flag */
 	ret = do_boot_cpu(sapicid, cpu);
 	if (ret < 0)
diff --git a/arch/ia64/kernel/topology.c b/arch/ia64/kernel/topology.c
--- a/arch/ia64/kernel/topology.c
+++ b/arch/ia64/kernel/topology.c
@@ -36,6 +36,15 @@ int arch_register_cpu(int num)
 	parent = &sysfs_nodes[cpu_to_node(num)];
 #endif /* CONFIG_NUMA */
 
+#ifdef CONFIG_ACPI_BOOT
+	/*
+	 * If CPEI cannot be re-targetted, and this is
+	 * CPEI target, then dont create the control file
+	 */
+	if (!can_cpei_retarget() && is_cpu_cpei_target(num))
+		sysfs_cpus[num].cpu.no_control = 1;
+#endif
+
 	return register_cpu(&sysfs_cpus[num].cpu, num, parent);
 }
 
diff --git a/arch/ia64/kernel/traps.c b/arch/ia64/kernel/traps.c
--- a/arch/ia64/kernel/traps.c
+++ b/arch/ia64/kernel/traps.c
@@ -21,12 +21,26 @@
 #include <asm/intrinsics.h>
 #include <asm/processor.h>
 #include <asm/uaccess.h>
+#include <asm/kdebug.h>
 
 extern spinlock_t timerlist_lock;
 
 fpswa_interface_t *fpswa_interface;
 EXPORT_SYMBOL(fpswa_interface);
 
+struct notifier_block *ia64die_chain;
+static DEFINE_SPINLOCK(die_notifier_lock);
+
+int register_die_notifier(struct notifier_block *nb)
+{
+	int err = 0;
+	unsigned long flags;
+	spin_lock_irqsave(&die_notifier_lock, flags);
+	err = notifier_chain_register(&ia64die_chain, nb);
+	spin_unlock_irqrestore(&die_notifier_lock, flags);
+	return err;
+}
+
 void __init
 trap_init (void)
 {
@@ -76,14 +90,16 @@ die (const char *str, struct pt_regs *re
 		.lock_owner_depth =	0
 	};
 	static int die_counter;
+	int cpu = get_cpu();
 
-	if (die.lock_owner != smp_processor_id()) {
+	if (die.lock_owner != cpu) {
 		console_verbose();
 		spin_lock_irq(&die.lock);
-		die.lock_owner = smp_processor_id();
+		die.lock_owner = cpu;
 		die.lock_owner_depth = 0;
 		bust_spinlocks(1);
 	}
+	put_cpu();
 
 	if (++die.lock_owner_depth < 3) {
 		printk("%s[%d]: %s %ld [%d]\n",
@@ -137,6 +153,10 @@ ia64_bad_break (unsigned long break_num,
 
 	switch (break_num) {
 	      case 0: /* unknown error (used by GCC for __builtin_abort()) */
+		if (notify_die(DIE_BREAK, "break 0", regs, break_num, TRAP_BRKPT, SIGTRAP)
+			       	== NOTIFY_STOP) {
+			return;
+		}
 		die_if_kernel("bugcheck!", regs, break_num);
 		sig = SIGILL; code = ILL_ILLOPC;
 		break;
@@ -189,6 +209,15 @@ ia64_bad_break (unsigned long break_num,
 		sig = SIGILL; code = __ILL_BNDMOD;
 		break;
 
+	      case 0x80200:
+	      case 0x80300:
+		if (notify_die(DIE_BREAK, "kprobe", regs, break_num, TRAP_BRKPT, SIGTRAP)
+			       	== NOTIFY_STOP) {
+			return;
+		}
+		sig = SIGTRAP; code = TRAP_BRKPT;
+		break;
+
 	      default:
 		if (break_num < 0x40000 || break_num > 0x100000)
 			die_if_kernel("Bad break", regs, break_num);
@@ -548,7 +577,11 @@ ia64_fault (unsigned long vector, unsign
 #endif
 			break;
 		      case 35: siginfo.si_code = TRAP_BRANCH; ifa = 0; break;
-		      case 36: siginfo.si_code = TRAP_TRACE; ifa = 0; break;
+		      case 36:
+			      if (notify_die(DIE_SS, "ss", &regs, vector,
+					     vector, SIGTRAP) == NOTIFY_STOP)
+				      return;
+			      siginfo.si_code = TRAP_TRACE; ifa = 0; break;
 		}
 		siginfo.si_signo = SIGTRAP;
 		siginfo.si_errno = 0;
diff --git a/arch/ia64/kernel/uncached.c b/arch/ia64/kernel/uncached.c
new file mode 100644
--- /dev/null
+++ b/arch/ia64/kernel/uncached.c
@@ -0,0 +1,246 @@
+/*
+ * Copyright (C) 2001-2005 Silicon Graphics, Inc.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ *
+ * A simple uncached page allocator using the generic allocator. This
+ * allocator first utilizes the spare (spill) pages found in the EFI
+ * memmap and will then start converting cached pages to uncached ones
+ * at a granule at a time. Node awareness is implemented by having a
+ * pool of pages per node.
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/efi.h>
+#include <linux/genalloc.h>
+#include <asm/page.h>
+#include <asm/pal.h>
+#include <asm/system.h>
+#include <asm/pgtable.h>
+#include <asm/atomic.h>
+#include <asm/tlbflush.h>
+#include <asm/sn/arch.h>
+
+#define DEBUG	0
+
+#if DEBUG
+#define dprintk			printk
+#else
+#define dprintk(x...)		do { } while (0)
+#endif
+
+void __init efi_memmap_walk_uc (efi_freemem_callback_t callback);
+
+#define MAX_UNCACHED_GRANULES	5
+static int allocated_granules;
+
+struct gen_pool *uncached_pool[MAX_NUMNODES];
+
+
+static void uncached_ipi_visibility(void *data)
+{
+	int status;
+
+	status = ia64_pal_prefetch_visibility(PAL_VISIBILITY_PHYSICAL);
+	if ((status != PAL_VISIBILITY_OK) &&
+	    (status != PAL_VISIBILITY_OK_REMOTE_NEEDED))
+		printk(KERN_DEBUG "pal_prefetch_visibility() returns %i on "
+		       "CPU %i\n", status, get_cpu());
+}
+
+
+static void uncached_ipi_mc_drain(void *data)
+{
+	int status;
+	status = ia64_pal_mc_drain();
+	if (status)
+		printk(KERN_WARNING "ia64_pal_mc_drain() failed with %i on "
+		       "CPU %i\n", status, get_cpu());
+}
+
+
+static unsigned long
+uncached_get_new_chunk(struct gen_pool *poolp)
+{
+	struct page *page;
+	void *tmp;
+	int status, i;
+	unsigned long addr, node;
+
+	if (allocated_granules >= MAX_UNCACHED_GRANULES)
+		return 0;
+
+	node = poolp->private;
+	page = alloc_pages_node(node, GFP_KERNEL | __GFP_ZERO,
+				IA64_GRANULE_SHIFT-PAGE_SHIFT);
+
+	dprintk(KERN_INFO "get_new_chunk page %p, addr %lx\n",
+		page, (unsigned long)(page-vmem_map) << PAGE_SHIFT);
+
+	/*
+	 * Do magic if no mem on local node! XXX
+	 */
+	if (!page)
+		return 0;
+	tmp = page_address(page);
+
+	/*
+	 * There's a small race here where it's possible for someone to
+	 * access the page through /dev/mem halfway through the conversion
+	 * to uncached - not sure it's really worth bothering about
+	 */
+	for (i = 0; i < (IA64_GRANULE_SIZE / PAGE_SIZE); i++)
+		SetPageUncached(&page[i]);
+
+	flush_tlb_kernel_range(tmp, tmp + IA64_GRANULE_SIZE);
+
+	status = ia64_pal_prefetch_visibility(PAL_VISIBILITY_PHYSICAL);
+
+	dprintk(KERN_INFO "pal_prefetch_visibility() returns %i on cpu %i\n",
+		status, get_cpu());
+
+	if (!status) {
+		status = smp_call_function(uncached_ipi_visibility, NULL, 0, 1);
+		if (status)
+			printk(KERN_WARNING "smp_call_function failed for "
+			       "uncached_ipi_visibility! (%i)\n", status);
+	}
+
+	if (ia64_platform_is("sn2"))
+		sn_flush_all_caches((unsigned long)tmp, IA64_GRANULE_SIZE);
+	else
+		flush_icache_range((unsigned long)tmp,
+				   (unsigned long)tmp+IA64_GRANULE_SIZE);
+
+	ia64_pal_mc_drain();
+	status = smp_call_function(uncached_ipi_mc_drain, NULL, 0, 1);
+	if (status)
+		printk(KERN_WARNING "smp_call_function failed for "
+		       "uncached_ipi_mc_drain! (%i)\n", status);
+
+	addr = (unsigned long)tmp - PAGE_OFFSET + __IA64_UNCACHED_OFFSET;
+
+	allocated_granules++;
+	return addr;
+}
+
+
+/*
+ * uncached_alloc_page
+ *
+ * Allocate 1 uncached page. Allocates on the requested node. If no
+ * uncached pages are available on the requested node, roundrobin starting
+ * with higher nodes.
+ */
+unsigned long
+uncached_alloc_page(int nid)
+{
+	unsigned long maddr;
+
+	maddr = gen_pool_alloc(uncached_pool[nid], PAGE_SIZE);
+
+	dprintk(KERN_DEBUG "uncached_alloc_page returns %lx on node %i\n",
+		maddr, nid);
+
+	/*
+	 * If no memory is availble on our local node, try the
+	 * remaining nodes in the system.
+	 */
+	if (!maddr) {
+		int i;
+
+		for (i = MAX_NUMNODES - 1; i >= 0; i--) {
+			if (i == nid || !node_online(i))
+				continue;
+			maddr = gen_pool_alloc(uncached_pool[i], PAGE_SIZE);
+			dprintk(KERN_DEBUG "uncached_alloc_page alternate search "
+				"returns %lx on node %i\n", maddr, i);
+			if (maddr) {
+				break;
+			}
+		}
+	}
+
+	return maddr;
+}
+EXPORT_SYMBOL(uncached_alloc_page);
+
+
+/*
+ * uncached_free_page
+ *
+ * Free a single uncached page.
+ */
+void
+uncached_free_page(unsigned long maddr)
+{
+	int node;
+
+	node = nasid_to_cnodeid(NASID_GET(maddr));
+
+	dprintk(KERN_DEBUG "uncached_free_page(%lx) on node %i\n", maddr, node);
+
+	if ((maddr & (0XFUL << 60)) != __IA64_UNCACHED_OFFSET)
+		panic("uncached_free_page invalid address %lx\n", maddr);
+
+	gen_pool_free(uncached_pool[node], maddr, PAGE_SIZE);
+}
+EXPORT_SYMBOL(uncached_free_page);
+
+
+/*
+ * uncached_build_memmap,
+ *
+ * Called at boot time to build a map of pages that can be used for
+ * memory special operations.
+ */
+static int __init
+uncached_build_memmap(unsigned long start, unsigned long end, void *arg)
+{
+	long length;
+	unsigned long vstart, vend;
+	int node;
+
+	length = end - start;
+	vstart = start + __IA64_UNCACHED_OFFSET;
+	vend = end + __IA64_UNCACHED_OFFSET;
+
+	dprintk(KERN_ERR "uncached_build_memmap(%lx %lx)\n", start, end);
+
+	memset((char *)vstart, 0, length);
+
+	node = nasid_to_cnodeid(NASID_GET(start));
+
+	for (; vstart < vend ; vstart += PAGE_SIZE) {
+		dprintk(KERN_INFO "sticking %lx into the pool!\n", vstart);
+		gen_pool_free(uncached_pool[node], vstart, PAGE_SIZE);
+	}
+
+	return 0;
+}
+
+
+static int __init uncached_init(void) {
+	int i;
+
+	for (i = 0; i < MAX_NUMNODES; i++) {
+		if (!node_online(i))
+			continue;
+		uncached_pool[i] = gen_pool_create(0, IA64_GRANULE_SHIFT,
+						   &uncached_get_new_chunk, i);
+	}
+
+	efi_memmap_walk_uc(uncached_build_memmap);
+
+	return 0;
+}
+
+__initcall(uncached_init);
diff --git a/arch/ia64/kernel/unwind.c b/arch/ia64/kernel/unwind.c
--- a/arch/ia64/kernel/unwind.c
+++ b/arch/ia64/kernel/unwind.c
@@ -362,7 +362,7 @@ unw_access_gr (struct unw_frame_info *in
 			if (info->pri_unat_loc)
 				nat_addr = info->pri_unat_loc;
 			else
-				nat_addr = &info->sw->ar_unat;
+				nat_addr = &info->sw->caller_unat;
 			nat_mask = (1UL << ((long) addr & 0x1f8)/8);
 		}
 	} else {
@@ -524,7 +524,7 @@ unw_access_ar (struct unw_frame_info *in
 	      case UNW_AR_UNAT:
 		addr = info->unat_loc;
 		if (!addr)
-			addr = &info->sw->ar_unat;
+			addr = &info->sw->caller_unat;
 		break;
 
 	      case UNW_AR_LC:
@@ -1775,7 +1775,7 @@ run_script (struct unw_script *script, s
 
 		      case UNW_INSN_SETNAT_MEMSTK:
 			if (!state->pri_unat_loc)
-				state->pri_unat_loc = &state->sw->ar_unat;
+				state->pri_unat_loc = &state->sw->caller_unat;
 			/* register off. is a multiple of 8, so the least 3 bits (type) are 0 */
 			s[dst+1] = ((unsigned long) state->pri_unat_loc - s[dst]) | UNW_NAT_MEMSTK;
 			break;
@@ -2243,11 +2243,11 @@ unw_init (void)
 	if (8*sizeof(unw_hash_index_t) < UNW_LOG_HASH_SIZE)
 		unw_hash_index_t_is_too_narrow();
 
-	unw.sw_off[unw.preg_index[UNW_REG_PRI_UNAT_GR]] = SW(AR_UNAT);
+	unw.sw_off[unw.preg_index[UNW_REG_PRI_UNAT_GR]] = SW(CALLER_UNAT);
 	unw.sw_off[unw.preg_index[UNW_REG_BSPSTORE]] = SW(AR_BSPSTORE);
-	unw.sw_off[unw.preg_index[UNW_REG_PFS]] = SW(AR_UNAT);
+	unw.sw_off[unw.preg_index[UNW_REG_PFS]] = SW(AR_PFS);
 	unw.sw_off[unw.preg_index[UNW_REG_RP]] = SW(B0);
-	unw.sw_off[unw.preg_index[UNW_REG_UNAT]] = SW(AR_UNAT);
+	unw.sw_off[unw.preg_index[UNW_REG_UNAT]] = SW(CALLER_UNAT);
 	unw.sw_off[unw.preg_index[UNW_REG_PR]] = SW(PR);
 	unw.sw_off[unw.preg_index[UNW_REG_LC]] = SW(AR_LC);
 	unw.sw_off[unw.preg_index[UNW_REG_FPSR]] = SW(AR_FPSR);
diff --git a/arch/ia64/kernel/vmlinux.lds.S b/arch/ia64/kernel/vmlinux.lds.S
--- a/arch/ia64/kernel/vmlinux.lds.S
+++ b/arch/ia64/kernel/vmlinux.lds.S
@@ -8,6 +8,11 @@
 #define LOAD_OFFSET	(KERNEL_START - KERNEL_TR_PAGE_SIZE)
 #include <asm-generic/vmlinux.lds.h>
 
+#define IVT_TEXT							\
+		VMLINUX_SYMBOL(__start_ivt_text) = .;			\
+		*(.text.ivt)						\
+		VMLINUX_SYMBOL(__end_ivt_text) = .;
+
 OUTPUT_FORMAT("elf64-ia64-little")
 OUTPUT_ARCH(ia64)
 ENTRY(phys_start)
@@ -39,7 +44,7 @@ SECTIONS
 
   .text : AT(ADDR(.text) - LOAD_OFFSET)
     {
-	*(.text.ivt)
+	IVT_TEXT
 	*(.text)
 	SCHED_TEXT
 	LOCK_TEXT
diff --git a/arch/ia64/lib/flush.S b/arch/ia64/lib/flush.S
--- a/arch/ia64/lib/flush.S
+++ b/arch/ia64/lib/flush.S
@@ -3,37 +3,59 @@
  *
  * Copyright (C) 1999-2001, 2005 Hewlett-Packard Co
  *	David Mosberger-Tang <davidm@hpl.hp.com>
+ *
+ * 05/28/05 Zoltan Menyhart	Dynamic stride size
  */
+
 #include <asm/asmmacro.h>
-#include <asm/page.h>
+
 
 	/*
 	 * flush_icache_range(start,end)
-	 *	Must flush range from start to end-1 but nothing else (need to
+	 *
+	 *	Make i-cache(s) coherent with d-caches.
+	 *
+	 *	Must deal with range from start to end-1 but nothing else (need to
 	 *	be careful not to touch addresses that may be unmapped).
+	 *
+	 *	Note: "in0" and "in1" are preserved for debugging purposes.
 	 */
 GLOBAL_ENTRY(flush_icache_range)
+
 	.prologue
-	alloc r2=ar.pfs,2,0,0,0
-	sub r8=in1,in0,1
-	;;
-	shr.u r8=r8,5			// we flush 32 bytes per iteration
-	.save ar.lc, r3
-	mov r3=ar.lc			// save ar.lc
+	alloc	r2=ar.pfs,2,0,0,0
+	movl	r3=ia64_i_cache_stride_shift
+ 	mov	r21=1
+	;;
+	ld8	r20=[r3]		// r20: stride shift
+	sub	r22=in1,r0,1		// last byte address
+	;;
+	shr.u	r23=in0,r20		// start / (stride size)
+	shr.u	r22=r22,r20		// (last byte address) / (stride size)
+	shl	r21=r21,r20		// r21: stride size of the i-cache(s)
+	;;
+	sub	r8=r22,r23		// number of strides - 1
+	shl	r24=r23,r20		// r24: addresses for "fc.i" =
+					//	"start" rounded down to stride boundary
+	.save	ar.lc,r3
+	mov	r3=ar.lc		// save ar.lc
 	;;
 
 	.body
-
-	mov ar.lc=r8
+	mov	ar.lc=r8
 	;;
-.Loop:	fc.i in0			// issuable on M2 only
-	add in0=32,in0
+	/*
+	 * 32 byte aligned loop, even number of (actually 2) bundles
+	 */
+.Loop:	fc.i	r24			// issuable on M0 only
+	add	r24=r21,r24		// we flush "stride size" bytes per iteration
+	nop.i	0
 	br.cloop.sptk.few .Loop
 	;;
 	sync.i
 	;;
 	srlz.i
 	;;
-	mov ar.lc=r3			// restore ar.lc
+	mov	ar.lc=r3		// restore ar.lc
 	br.ret.sptk.many rp
 END(flush_icache_range)
diff --git a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c
--- a/arch/ia64/mm/discontig.c
+++ b/arch/ia64/mm/discontig.c
@@ -44,150 +44,7 @@ struct early_node_data {
 };
 
 static struct early_node_data mem_data[MAX_NUMNODES] __initdata;
-
-/**
- * reassign_cpu_only_nodes - called from find_memory to move CPU-only nodes to a memory node
- *
- * This function will move nodes with only CPUs (no memory)
- * to a node with memory which is at the minimum numa_slit distance.
- * Any reassigments will result in the compression of the nodes
- * and renumbering the nid values where appropriate.
- * The static declarations below are to avoid large stack size which
- * makes the code not re-entrant.
- */
-static void __init reassign_cpu_only_nodes(void)
-{
-	struct node_memblk_s *p;
-	int i, j, k, nnode, nid, cpu, cpunid, pxm;
-	u8 cslit, slit;
-	static DECLARE_BITMAP(nodes_with_mem, MAX_NUMNODES) __initdata;
-	static u8 numa_slit_fix[MAX_NUMNODES * MAX_NUMNODES] __initdata;
-	static int node_flip[MAX_NUMNODES] __initdata;
-	static int old_nid_map[NR_CPUS] __initdata;
-
-	for (nnode = 0, p = &node_memblk[0]; p < &node_memblk[num_node_memblks]; p++)
-		if (!test_bit(p->nid, (void *) nodes_with_mem)) {
-			set_bit(p->nid, (void *) nodes_with_mem);
-			nnode++;
-		}
-
-	/*
-	 * All nids with memory.
-	 */
-	if (nnode == num_online_nodes())
-		return;
-
-	/*
-	 * Change nids and attempt to migrate CPU-only nodes
-	 * to the best numa_slit (closest neighbor) possible.
-	 * For reassigned CPU nodes a nid can't be arrived at
-	 * until after this loop because the target nid's new
-	 * identity might not have been established yet. So
-	 * new nid values are fabricated above num_online_nodes() and
-	 * mapped back later to their true value.
-	 */
-	/* MCD - This code is a bit complicated, but may be unnecessary now.
-	 * We can now handle much more interesting node-numbering.
-	 * The old requirement that 0 <= nid <= numnodes <= MAX_NUMNODES
-	 * and that there be no holes in the numbering 0..numnodes
-	 * has become simply 0 <= nid <= MAX_NUMNODES.
-	 */
-	nid = 0;
-	for_each_online_node(i)  {
-		if (test_bit(i, (void *) nodes_with_mem)) {
-			/*
-			 * Save original nid value for numa_slit
-			 * fixup and node_cpuid reassignments.
-			 */
-			node_flip[nid] = i;
-
-			if (i == nid) {
-				nid++;
-				continue;
-			}
-
-			for (p = &node_memblk[0]; p < &node_memblk[num_node_memblks]; p++)
-				if (p->nid == i)
-					p->nid = nid;
-
-			cpunid = nid;
-			nid++;
-		} else
-			cpunid = MAX_NUMNODES;
-
-		for (cpu = 0; cpu < NR_CPUS; cpu++)
-			if (node_cpuid[cpu].nid == i) {
-				/*
-				 * For nodes not being reassigned just
-				 * fix the cpu's nid and reverse pxm map
-				 */
-				if (cpunid < MAX_NUMNODES) {
-					pxm = nid_to_pxm_map[i];
-					pxm_to_nid_map[pxm] =
-					          node_cpuid[cpu].nid = cpunid;
-					continue;
-				}
-
-				/*
-				 * For nodes being reassigned, find best node by
-				 * numa_slit information and then make a temporary
-				 * nid value based on current nid and num_online_nodes().
-				 */
-				slit = 0xff;
-				k = 2*num_online_nodes();
-				for_each_online_node(j) {
-					if (i == j)
-						continue;
-					else if (test_bit(j, (void *) nodes_with_mem)) {
-						cslit = numa_slit[i * num_online_nodes() + j];
-						if (cslit < slit) {
-							k = num_online_nodes() + j;
-							slit = cslit;
-						}
-					}
-				}
-
-				/* save old nid map so we can update the pxm */
-				old_nid_map[cpu] = node_cpuid[cpu].nid;
-				node_cpuid[cpu].nid = k;
-			}
-	}
-
-	/*
-	 * Fixup temporary nid values for CPU-only nodes.
-	 */
-	for (cpu = 0; cpu < NR_CPUS; cpu++)
-		if (node_cpuid[cpu].nid == (2*num_online_nodes())) {
-			pxm = nid_to_pxm_map[old_nid_map[cpu]];
-			pxm_to_nid_map[pxm] = node_cpuid[cpu].nid = nnode - 1;
-		} else {
-			for (i = 0; i < nnode; i++) {
-				if (node_flip[i] != (node_cpuid[cpu].nid - num_online_nodes()))
-					continue;
-
-				pxm = nid_to_pxm_map[old_nid_map[cpu]];
-				pxm_to_nid_map[pxm] = node_cpuid[cpu].nid = i;
-				break;
-			}
-		}
-
-	/*
-	 * Fix numa_slit by compressing from larger
-	 * nid array to reduced nid array.
-	 */
-	for (i = 0; i < nnode; i++)
-		for (j = 0; j < nnode; j++)
-			numa_slit_fix[i * nnode + j] =
-				numa_slit[node_flip[i] * num_online_nodes() + node_flip[j]];
-
-	memcpy(numa_slit, numa_slit_fix, sizeof (numa_slit));
-
-	nodes_clear(node_online_map);
-	for (i = 0; i < nnode; i++)
-		node_set_online(i);
-
-	return;
-}
+static nodemask_t memory_less_mask __initdata;
 
 /*
  * To prevent cache aliasing effects, align per-node structures so that they
@@ -233,44 +90,101 @@ static int __init build_node_maps(unsign
 }
 
 /**
- * early_nr_phys_cpus_node - return number of physical cpus on a given node
+ * early_nr_cpus_node - return number of cpus on a given node
  * @node: node to check
  *
- * Count the number of physical cpus on @node.  These are cpus that actually
- * exist.  We can't use nr_cpus_node() yet because
+ * Count the number of cpus on @node.  We can't use nr_cpus_node() yet because
  * acpi_boot_init() (which builds the node_to_cpu_mask array) hasn't been
- * called yet.
+ * called yet.  Note that node 0 will also count all non-existent cpus.
  */
-static int early_nr_phys_cpus_node(int node)
+static int __init early_nr_cpus_node(int node)
 {
 	int cpu, n = 0;
 
 	for (cpu = 0; cpu < NR_CPUS; cpu++)
 		if (node == node_cpuid[cpu].nid)
-			if ((cpu == 0) || node_cpuid[cpu].phys_id)
-				n++;
+			n++;
 
 	return n;
 }
 
+/**
+ * compute_pernodesize - compute size of pernode data
+ * @node: the node id.
+ */
+static unsigned long __init compute_pernodesize(int node)
+{
+	unsigned long pernodesize = 0, cpus;
+
+	cpus = early_nr_cpus_node(node);
+	pernodesize += PERCPU_PAGE_SIZE * cpus;
+	pernodesize += node * L1_CACHE_BYTES;
+	pernodesize += L1_CACHE_ALIGN(sizeof(pg_data_t));
+	pernodesize += L1_CACHE_ALIGN(sizeof(struct ia64_node_data));
+	pernodesize = PAGE_ALIGN(pernodesize);
+	return pernodesize;
+}
 
 /**
- * early_nr_cpus_node - return number of cpus on a given node
- * @node: node to check
+ * per_cpu_node_setup - setup per-cpu areas on each node
+ * @cpu_data: per-cpu area on this node
+ * @node: node to setup
  *
- * Count the number of cpus on @node.  We can't use nr_cpus_node() yet because
- * acpi_boot_init() (which builds the node_to_cpu_mask array) hasn't been
- * called yet.  Note that node 0 will also count all non-existent cpus.
+ * Copy the static per-cpu data into the region we just set aside and then
+ * setup __per_cpu_offset for each CPU on this node.  Return a pointer to
+ * the end of the area.
  */
-static int early_nr_cpus_node(int node)
+static void *per_cpu_node_setup(void *cpu_data, int node)
 {
-	int cpu, n = 0;
+#ifdef CONFIG_SMP
+	int cpu;
 
-	for (cpu = 0; cpu < NR_CPUS; cpu++)
-		if (node == node_cpuid[cpu].nid)
-			n++;
+	for (cpu = 0; cpu < NR_CPUS; cpu++) {
+		if (node == node_cpuid[cpu].nid) {
+			memcpy(__va(cpu_data), __phys_per_cpu_start,
+			       __per_cpu_end - __per_cpu_start);
+			__per_cpu_offset[cpu] = (char*)__va(cpu_data) -
+				__per_cpu_start;
+			cpu_data += PERCPU_PAGE_SIZE;
+		}
+	}
+#endif
+	return cpu_data;
+}
 
-	return n;
+/**
+ * fill_pernode - initialize pernode data.
+ * @node: the node id.
+ * @pernode: physical address of pernode data
+ * @pernodesize: size of the pernode data
+ */
+static void __init fill_pernode(int node, unsigned long pernode,
+	unsigned long pernodesize)
+{
+	void *cpu_data;
+	int cpus = early_nr_cpus_node(node);
+	struct bootmem_data *bdp = &mem_data[node].bootmem_data;
+
+	mem_data[node].pernode_addr = pernode;
+	mem_data[node].pernode_size = pernodesize;
+	memset(__va(pernode), 0, pernodesize);
+
+	cpu_data = (void *)pernode;
+	pernode += PERCPU_PAGE_SIZE * cpus;
+	pernode += node * L1_CACHE_BYTES;
+
+	mem_data[node].pgdat = __va(pernode);
+	pernode += L1_CACHE_ALIGN(sizeof(pg_data_t));
+
+	mem_data[node].node_data = __va(pernode);
+	pernode += L1_CACHE_ALIGN(sizeof(struct ia64_node_data));
+
+	mem_data[node].pgdat->bdata = bdp;
+	pernode += L1_CACHE_ALIGN(sizeof(pg_data_t));
+
+	cpu_data = per_cpu_node_setup(cpu_data, node);
+
+	return;
 }
 
 /**
@@ -304,9 +218,8 @@ static int early_nr_cpus_node(int node)
 static int __init find_pernode_space(unsigned long start, unsigned long len,
 				     int node)
 {
-	unsigned long epfn, cpu, cpus, phys_cpus;
+	unsigned long epfn;
 	unsigned long pernodesize = 0, pernode, pages, mapsize;
-	void *cpu_data;
 	struct bootmem_data *bdp = &mem_data[node].bootmem_data;
 
 	epfn = (start + len) >> PAGE_SHIFT;
@@ -329,49 +242,12 @@ static int __init find_pernode_space(uns
 	 * Calculate total size needed, incl. what's necessary
 	 * for good alignment and alias prevention.
 	 */
-	cpus = early_nr_cpus_node(node);
-	phys_cpus = early_nr_phys_cpus_node(node);
-	pernodesize += PERCPU_PAGE_SIZE * cpus;
-	pernodesize += node * L1_CACHE_BYTES;
-	pernodesize += L1_CACHE_ALIGN(sizeof(pg_data_t));
-	pernodesize += L1_CACHE_ALIGN(sizeof(struct ia64_node_data));
-	pernodesize = PAGE_ALIGN(pernodesize);
+	pernodesize = compute_pernodesize(node);
 	pernode = NODEDATA_ALIGN(start, node);
 
 	/* Is this range big enough for what we want to store here? */
-	if (start + len > (pernode + pernodesize + mapsize)) {
-		mem_data[node].pernode_addr = pernode;
-		mem_data[node].pernode_size = pernodesize;
-		memset(__va(pernode), 0, pernodesize);
-
-		cpu_data = (void *)pernode;
-		pernode += PERCPU_PAGE_SIZE * cpus;
-		pernode += node * L1_CACHE_BYTES;
-
-		mem_data[node].pgdat = __va(pernode);
-		pernode += L1_CACHE_ALIGN(sizeof(pg_data_t));
-
-		mem_data[node].node_data = __va(pernode);
-		pernode += L1_CACHE_ALIGN(sizeof(struct ia64_node_data));
-
-		mem_data[node].pgdat->bdata = bdp;
-		pernode += L1_CACHE_ALIGN(sizeof(pg_data_t));
-
-		/*
-		 * Copy the static per-cpu data into the region we
-		 * just set aside and then setup __per_cpu_offset
-		 * for each CPU on this node.
-		 */
-		for (cpu = 0; cpu < NR_CPUS; cpu++) {
-			if (node == node_cpuid[cpu].nid) {
-				memcpy(__va(cpu_data), __phys_per_cpu_start,
-				       __per_cpu_end - __per_cpu_start);
-				__per_cpu_offset[cpu] = (char*)__va(cpu_data) -
-					__per_cpu_start;
-				cpu_data += PERCPU_PAGE_SIZE;
-			}
-		}
-	}
+	if (start + len > (pernode + pernodesize + mapsize))
+		fill_pernode(node, pernode, pernodesize);
 
 	return 0;
 }
@@ -411,6 +287,9 @@ static void __init reserve_pernode_space
 	for_each_online_node(node) {
 		pg_data_t *pdp = mem_data[node].pgdat;
 
+		if (node_isset(node, memory_less_mask))
+			continue;
+
 		bdp = pdp->bdata;
 
 		/* First the bootmem_map itself */
@@ -436,8 +315,8 @@ static void __init reserve_pernode_space
  */
 static void __init initialize_pernode_data(void)
 {
-	int cpu, node;
 	pg_data_t *pgdat_list[MAX_NUMNODES];
+	int cpu, node;
 
 	for_each_online_node(node)
 		pgdat_list[node] = mem_data[node].pgdat;
@@ -447,12 +326,99 @@ static void __init initialize_pernode_da
 		memcpy(mem_data[node].node_data->pg_data_ptrs, pgdat_list,
 		       sizeof(pgdat_list));
 	}
-
+#ifdef CONFIG_SMP
 	/* Set the node_data pointer for each per-cpu struct */
 	for (cpu = 0; cpu < NR_CPUS; cpu++) {
 		node = node_cpuid[cpu].nid;
 		per_cpu(cpu_info, cpu).node_data = mem_data[node].node_data;
 	}
+#else
+	{
+		struct cpuinfo_ia64 *cpu0_cpu_info;
+		cpu = 0;
+		node = node_cpuid[cpu].nid;
+		cpu0_cpu_info = (struct cpuinfo_ia64 *)(__phys_per_cpu_start +
+			((char *)&per_cpu__cpu_info - __per_cpu_start));
+		cpu0_cpu_info->node_data = mem_data[node].node_data;
+	}
+#endif /* CONFIG_SMP */
+}
+
+/**
+ * memory_less_node_alloc - * attempt to allocate memory on the best NUMA slit
+ * 	node but fall back to any other node when __alloc_bootmem_node fails
+ *	for best.
+ * @nid: node id
+ * @pernodesize: size of this node's pernode data
+ * @align: alignment to use for this node's pernode data
+ */
+static void __init *memory_less_node_alloc(int nid, unsigned long pernodesize,
+	unsigned long align)
+{
+	void *ptr = NULL;
+	u8 best = 0xff;
+	int bestnode = -1, node;
+
+	for_each_online_node(node) {
+		if (node_isset(node, memory_less_mask))
+			continue;
+		else if (node_distance(nid, node) < best) {
+			best = node_distance(nid, node);
+			bestnode = node;
+		}
+	}
+
+	ptr = __alloc_bootmem_node(mem_data[bestnode].pgdat,
+		pernodesize, align, __pa(MAX_DMA_ADDRESS));
+
+	if (!ptr)
+		panic("NO memory for memory less node\n");
+	return ptr;
+}
+
+/**
+ * pgdat_insert - insert the pgdat into global pgdat_list
+ * @pgdat: the pgdat for a node.
+ */
+static void __init pgdat_insert(pg_data_t *pgdat)
+{
+	pg_data_t *prev = NULL, *next;
+
+	for_each_pgdat(next)
+		if (pgdat->node_id < next->node_id)
+			break;
+		else
+			prev = next;
+
+	if (prev) {
+		prev->pgdat_next = pgdat;
+		pgdat->pgdat_next = next;
+	} else {
+		pgdat->pgdat_next = pgdat_list;
+		pgdat_list = pgdat;
+	}
+
+	return;
+}
+
+/**
+ * memory_less_nodes - allocate and initialize CPU only nodes pernode
+ *	information.
+ */
+static void __init memory_less_nodes(void)
+{
+	unsigned long pernodesize;
+	void *pernode;
+	int node;
+
+	for_each_node_mask(node, memory_less_mask) {
+		pernodesize = compute_pernodesize(node);
+		pernode = memory_less_node_alloc(node, pernodesize,
+			(node) ? (node * PERCPU_PAGE_SIZE) : (1024*1024));
+		fill_pernode(node, __pa(pernode), pernodesize);
+	}
+
+	return;
 }
 
 /**
@@ -472,16 +438,19 @@ void __init find_memory(void)
 		node_set_online(0);
 	}
 
+	nodes_or(memory_less_mask, memory_less_mask, node_online_map);
 	min_low_pfn = -1;
 	max_low_pfn = 0;
 
-	if (num_online_nodes() > 1)
-		reassign_cpu_only_nodes();
-
 	/* These actually end up getting called by call_pernode_memory() */
 	efi_memmap_walk(filter_rsvd_memory, build_node_maps);
 	efi_memmap_walk(filter_rsvd_memory, find_pernode_space);
 
+	for_each_online_node(node)
+		if (mem_data[node].bootmem_data.node_low_pfn) {
+			node_clear(node, memory_less_mask);
+			mem_data[node].min_pfn = ~0UL;
+		}
 	/*
 	 * Initialize the boot memory maps in reverse order since that's
 	 * what the bootmem allocator expects
@@ -492,17 +461,14 @@ void __init find_memory(void)
 
 		if (!node_online(node))
 			continue;
+		else if (node_isset(node, memory_less_mask))
+			continue;
 
 		bdp = &mem_data[node].bootmem_data;
 		pernode = mem_data[node].pernode_addr;
 		pernodesize = mem_data[node].pernode_size;
 		map = pernode + pernodesize;
 
-		/* Sanity check... */
-		if (!pernode)
-			panic("pernode space for node %d "
-			      "could not be allocated!", node);
-
 		init_bootmem_node(mem_data[node].pgdat,
 				  map>>PAGE_SHIFT,
 				  bdp->node_boot_start>>PAGE_SHIFT,
@@ -512,6 +478,7 @@ void __init find_memory(void)
 	efi_memmap_walk(filter_rsvd_memory, free_node_bootmem);
 
 	reserve_pernode_space();
+	memory_less_nodes();
 	initialize_pernode_data();
 
 	max_pfn = max_low_pfn;
@@ -519,6 +486,7 @@ void __init find_memory(void)
 	find_initrd();
 }
 
+#ifdef CONFIG_SMP
 /**
  * per_cpu_init - setup per-cpu variables
  *
@@ -529,15 +497,15 @@ void *per_cpu_init(void)
 {
 	int cpu;
 
-	if (smp_processor_id() == 0) {
-		for (cpu = 0; cpu < NR_CPUS; cpu++) {
-			per_cpu(local_per_cpu_offset, cpu) =
-				__per_cpu_offset[cpu];
-		}
-	}
+	if (smp_processor_id() != 0)
+		return __per_cpu_start + __per_cpu_offset[smp_processor_id()];
+
+	for (cpu = 0; cpu < NR_CPUS; cpu++)
+		per_cpu(local_per_cpu_offset, cpu) = __per_cpu_offset[cpu];
 
 	return __per_cpu_start + __per_cpu_offset[smp_processor_id()];
 }
+#endif /* CONFIG_SMP */
 
 /**
  * show_mem - give short summary of memory stats
@@ -560,14 +528,15 @@ void show_mem(void)
 		int shared = 0, cached = 0, reserved = 0;
 		printk("Node ID: %d\n", pgdat->node_id);
 		for(i = 0; i < pgdat->node_spanned_pages; i++) {
+			struct page *page = pgdat_page_nr(pgdat, i);
 			if (!ia64_pfn_valid(pgdat->node_start_pfn+i))
 				continue;
-			if (PageReserved(pgdat->node_mem_map+i))
+			if (PageReserved(page))
 				reserved++;
-			else if (PageSwapCache(pgdat->node_mem_map+i))
+			else if (PageSwapCache(page))
 				cached++;
-			else if (page_count(pgdat->node_mem_map+i))
-				shared += page_count(pgdat->node_mem_map+i)-1;
+			else if (page_count(page))
+				shared += page_count(page)-1;
 		}
 		total_present += present;
 		total_reserved += reserved;
@@ -679,12 +648,13 @@ void __init paging_init(void)
 
 	max_dma = virt_to_phys((void *) MAX_DMA_ADDRESS) >> PAGE_SHIFT;
 
-	/* so min() will work in count_node_pages */
-	for_each_online_node(node)
-		mem_data[node].min_pfn = ~0UL;
-
 	efi_memmap_walk(filter_rsvd_memory, count_node_pages);
 
+	vmalloc_end -= PAGE_ALIGN(max_low_pfn * sizeof(struct page));
+	vmem_map = (struct page *) vmalloc_end;
+	efi_memmap_walk(create_mem_map_page_table, NULL);
+	printk("Virtual mem_map starts at 0x%p\n", vmem_map);
+
 	for_each_online_node(node) {
 		memset(zones_size, 0, sizeof(zones_size));
 		memset(zholes_size, 0, sizeof(zholes_size));
@@ -718,15 +688,6 @@ void __init paging_init(void)
 				 mem_data[node].num_dma_physpages);
 		}
 
-		if (node == 0) {
-			vmalloc_end -=
-				PAGE_ALIGN(max_low_pfn * sizeof(struct page));
-			vmem_map = (struct page *) vmalloc_end;
-
-			efi_memmap_walk(create_mem_map_page_table, NULL);
-			printk("Virtual mem_map starts at 0x%p\n", vmem_map);
-		}
-
 		pfn_offset = mem_data[node].min_pfn;
 
 		NODE_DATA(node)->node_mem_map = vmem_map + pfn_offset;
@@ -734,5 +695,11 @@ void __init paging_init(void)
 				    pfn_offset, zholes_size);
 	}
 
+	/*
+	 * Make memory less nodes become a member of the known nodes.
+	 */
+	for_each_node_mask(node, memory_less_mask)
+		pgdat_insert(mem_data[node].pgdat);
+
 	zero_page_memmap_ptr = virt_to_page(ia64_imva(empty_zero_page));
 }
diff --git a/arch/ia64/mm/fault.c b/arch/ia64/mm/fault.c
--- a/arch/ia64/mm/fault.c
+++ b/arch/ia64/mm/fault.c
@@ -14,6 +14,7 @@
 #include <asm/processor.h>
 #include <asm/system.h>
 #include <asm/uaccess.h>
+#include <asm/kdebug.h>
 
 extern void die (char *, struct pt_regs *, long);
 
@@ -102,6 +103,13 @@ ia64_do_page_fault (unsigned long addres
 		goto bad_area_no_up;
 #endif
 
+	/*
+	 * This is to handle the kprobes on user space access instructions
+	 */
+	if (notify_die(DIE_PAGE_FAULT, "page fault", regs, code, TRAP_BRKPT,
+					SIGSEGV) == NOTIFY_STOP)
+		return;
+
 	down_read(&mm->mmap_sem);
 
 	vma = find_vma_prev(mm, address, &prev_vma);
diff --git a/arch/ia64/mm/hugetlbpage.c b/arch/ia64/mm/hugetlbpage.c
--- a/arch/ia64/mm/hugetlbpage.c
+++ b/arch/ia64/mm/hugetlbpage.c
@@ -24,7 +24,7 @@
 
 unsigned int hpage_shift=HPAGE_SHIFT_DEFAULT;
 
-static pte_t *
+pte_t *
 huge_pte_alloc (struct mm_struct *mm, unsigned long addr)
 {
 	unsigned long taddr = htlbpage_to_page(addr);
@@ -43,7 +43,7 @@ huge_pte_alloc (struct mm_struct *mm, un
 	return pte;
 }
 
-static pte_t *
+pte_t *
 huge_pte_offset (struct mm_struct *mm, unsigned long addr)
 {
 	unsigned long taddr = htlbpage_to_page(addr);
@@ -67,23 +67,6 @@ huge_pte_offset (struct mm_struct *mm, u
 
 #define mk_pte_huge(entry) { pte_val(entry) |= _PAGE_P; }
 
-static void
-set_huge_pte (struct mm_struct *mm, struct vm_area_struct *vma,
-	      struct page *page, pte_t * page_table, int write_access)
-{
-	pte_t entry;
-
-	add_mm_counter(mm, rss, HPAGE_SIZE / PAGE_SIZE);
-	if (write_access) {
-		entry =
-		    pte_mkwrite(pte_mkdirty(mk_pte(page, vma->vm_page_prot)));
-	} else
-		entry = pte_wrprotect(mk_pte(page, vma->vm_page_prot));
-	entry = pte_mkyoung(entry);
-	mk_pte_huge(entry);
-	set_pte(page_table, entry);
-	return;
-}
 /*
  * This function checks for proper alignment of input addr and len parameters.
  */
@@ -99,68 +82,6 @@ int is_aligned_hugepage_range(unsigned l
 	return 0;
 }
 
-int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src,
-			struct vm_area_struct *vma)
-{
-	pte_t *src_pte, *dst_pte, entry;
-	struct page *ptepage;
-	unsigned long addr = vma->vm_start;
-	unsigned long end = vma->vm_end;
-
-	while (addr < end) {
-		dst_pte = huge_pte_alloc(dst, addr);
-		if (!dst_pte)
-			goto nomem;
-		src_pte = huge_pte_offset(src, addr);
-		entry = *src_pte;
-		ptepage = pte_page(entry);
-		get_page(ptepage);
-		set_pte(dst_pte, entry);
-		add_mm_counter(dst, rss, HPAGE_SIZE / PAGE_SIZE);
-		addr += HPAGE_SIZE;
-	}
-	return 0;
-nomem:
-	return -ENOMEM;
-}
-
-int
-follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma,
-		    struct page **pages, struct vm_area_struct **vmas,
-		    unsigned long *st, int *length, int i)
-{
-	pte_t *ptep, pte;
-	unsigned long start = *st;
-	unsigned long pstart;
-	int len = *length;
-	struct page *page;
-
-	do {
-		pstart = start & HPAGE_MASK;
-		ptep = huge_pte_offset(mm, start);
-		pte = *ptep;
-
-back1:
-		page = pte_page(pte);
-		if (pages) {
-			page += ((start & ~HPAGE_MASK) >> PAGE_SHIFT);
-			get_page(page);
-			pages[i] = page;
-		}
-		if (vmas)
-			vmas[i] = vma;
-		i++;
-		len--;
-		start += PAGE_SIZE;
-		if (((start & HPAGE_MASK) == pstart) && len &&
-				(start < vma->vm_end))
-			goto back1;
-	} while (len && start < vma->vm_end);
-	*length = len;
-	*st = start;
-	return i;
-}
-
 struct page *follow_huge_addr(struct mm_struct *mm, unsigned long addr, int write)
 {
 	struct page *page;
@@ -212,81 +133,6 @@ void hugetlb_free_pgd_range(struct mmu_g
 	free_pgd_range(tlb, addr, end, floor, ceiling);
 }
 
-void unmap_hugepage_range(struct vm_area_struct *vma, unsigned long start, unsigned long end)
-{
-	struct mm_struct *mm = vma->vm_mm;
-	unsigned long address;
-	pte_t *pte;
-	struct page *page;
-
-	BUG_ON(start & (HPAGE_SIZE - 1));
-	BUG_ON(end & (HPAGE_SIZE - 1));
-
-	for (address = start; address < end; address += HPAGE_SIZE) {
-		pte = huge_pte_offset(mm, address);
-		if (pte_none(*pte))
-			continue;
-		page = pte_page(*pte);
-		put_page(page);
-		pte_clear(mm, address, pte);
-	}
-	add_mm_counter(mm, rss, - ((end - start) >> PAGE_SHIFT));
-	flush_tlb_range(vma, start, end);
-}
-
-int hugetlb_prefault(struct address_space *mapping, struct vm_area_struct *vma)
-{
-	struct mm_struct *mm = current->mm;
-	unsigned long addr;
-	int ret = 0;
-
-	BUG_ON(vma->vm_start & ~HPAGE_MASK);
-	BUG_ON(vma->vm_end & ~HPAGE_MASK);
-
-	spin_lock(&mm->page_table_lock);
-	for (addr = vma->vm_start; addr < vma->vm_end; addr += HPAGE_SIZE) {
-		unsigned long idx;
-		pte_t *pte = huge_pte_alloc(mm, addr);
-		struct page *page;
-
-		if (!pte) {
-			ret = -ENOMEM;
-			goto out;
-		}
-		if (!pte_none(*pte))
-			continue;
-
-		idx = ((addr - vma->vm_start) >> HPAGE_SHIFT)
-			+ (vma->vm_pgoff >> (HPAGE_SHIFT - PAGE_SHIFT));
-		page = find_get_page(mapping, idx);
-		if (!page) {
-			/* charge the fs quota first */
-			if (hugetlb_get_quota(mapping)) {
-				ret = -ENOMEM;
-				goto out;
-			}
-			page = alloc_huge_page();
-			if (!page) {
-				hugetlb_put_quota(mapping);
-				ret = -ENOMEM;
-				goto out;
-			}
-			ret = add_to_page_cache(page, mapping, idx, GFP_ATOMIC);
-			if (! ret) {
-				unlock_page(page);
-			} else {
-				hugetlb_put_quota(mapping);
-				page_cache_release(page);
-				goto out;
-			}
-		}
-		set_huge_pte(mm, vma, page, pte, vma->vm_flags & VM_WRITE);
-	}
-out:
-	spin_unlock(&mm->page_table_lock);
-	return ret;
-}
-
 unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr, unsigned long len,
 		unsigned long pgoff, unsigned long flags)
 {
diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c
--- a/arch/ia64/mm/init.c
+++ b/arch/ia64/mm/init.c
@@ -597,7 +597,8 @@ mem_init (void)
 	kclist_add(&kcore_kernel, _stext, _end - _stext);
 
 	for_each_pgdat(pgdat)
-		totalram_pages += free_all_bootmem_node(pgdat);
+		if (pgdat->bdata->node_bootmem_map)
+			totalram_pages += free_all_bootmem_node(pgdat);
 
 	reserved_pages = 0;
 	efi_memmap_walk(count_reserved_pages, &reserved_pages);
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c
--- a/arch/ia64/pci/pci.c
+++ b/arch/ia64/pci/pci.c
@@ -33,8 +33,6 @@
 #include <asm/hw_irq.h>
 
 
-static int pci_routeirq;
-
 /*
  * Low-level SAL-based PCI configuration access functions. Note that SAL
  * calls are already serialized (via sal_lock), so we don't need another
@@ -139,24 +137,8 @@ static void acpi_map_iosapics(void)
 static int __init
 pci_acpi_init (void)
 {
-	struct pci_dev *dev = NULL;
-
-	printk(KERN_INFO "PCI: Using ACPI for IRQ routing\n");
-
 	acpi_map_iosapics();
 
-	if (pci_routeirq) {
-		/*
-		 * PCI IRQ routing is set up by pci_enable_device(), but we
-		 * also do it here in case there are still broken drivers that
-		 * don't use pci_enable_device().
-		 */
-		printk(KERN_INFO "PCI: Routing interrupts for all devices because \"pci=routeirq\" specified\n");
-		for_each_pci_dev(dev)
-			acpi_pci_irq_enable(dev);
-	} else
-		printk(KERN_INFO "PCI: If a device doesn't work, try \"pci=routeirq\".  If it helps, post a report\n");
-
 	return 0;
 }
 
@@ -175,6 +157,7 @@ alloc_pci_controller (int seg)
 
 	memset(controller, 0, sizeof(*controller));
 	controller->segment = seg;
+	controller->node = -1;
 	return controller;
 }
 
@@ -306,6 +289,7 @@ pci_acpi_scan_root(struct acpi_device *d
 	unsigned int windows = 0;
 	struct pci_bus *pbus;
 	char *name;
+	int pxm;
 
 	controller = alloc_pci_controller(domain);
 	if (!controller)
@@ -313,10 +297,16 @@ pci_acpi_scan_root(struct acpi_device *d
 
 	controller->acpi_handle = device->handle;
 
+	pxm = acpi_get_pxm(controller->acpi_handle);
+#ifdef CONFIG_NUMA
+	if (pxm >= 0)
+		controller->node = pxm_to_nid_map[pxm];
+#endif
+
 	acpi_walk_resources(device->handle, METHOD_NAME__CRS, count_window,
 			&windows);
-	controller->window = kmalloc(sizeof(*controller->window) * windows,
-			GFP_KERNEL);
+	controller->window = kmalloc_node(sizeof(*controller->window) * windows,
+			GFP_KERNEL, controller->node);
 	if (!controller->window)
 		goto out2;
 
@@ -330,7 +320,7 @@ pci_acpi_scan_root(struct acpi_device *d
 	acpi_walk_resources(device->handle, METHOD_NAME__CRS, add_window,
 			&info);
 
-	pbus = pci_scan_bus(bus, &pci_root_ops, controller);
+	pbus = pci_scan_bus_parented(NULL, bus, &pci_root_ops, controller);
 	if (pbus)
 		pcibios_setup_root_windows(pbus, controller);
 
@@ -390,6 +380,26 @@ void pcibios_bus_to_resource(struct pci_
 	res->start = region->start + offset;
 	res->end = region->end + offset;
 }
+EXPORT_SYMBOL(pcibios_bus_to_resource);
+
+static int __devinit is_valid_resource(struct pci_dev *dev, int idx)
+{
+	unsigned int i, type_mask = IORESOURCE_IO | IORESOURCE_MEM;
+	struct resource *devr = &dev->resource[idx];
+
+	if (!dev->bus)
+		return 0;
+	for (i=0; i<PCI_BUS_NUM_RESOURCES; i++) {
+		struct resource *busr = dev->bus->resource[i];
+
+		if (!busr || ((busr->flags ^ devr->flags) & type_mask))
+			continue;
+		if ((devr->start) && (devr->start >= busr->start) &&
+				(devr->end <= busr->end))
+			return 1;
+	}
+	return 0;
+}
 
 static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev)
 {
@@ -404,7 +414,8 @@ static void __devinit pcibios_fixup_devi
 		region.start = dev->resource[i].start;
 		region.end = dev->resource[i].end;
 		pcibios_bus_to_resource(dev, &dev->resource[i], &region);
-		pci_claim_resource(dev, i);
+		if ((is_valid_resource(dev, i)))
+			pci_claim_resource(dev, i);
 	}
 }
 
@@ -416,6 +427,10 @@ pcibios_fixup_bus (struct pci_bus *b)
 {
 	struct pci_dev *dev;
 
+	if (b->self) {
+		pci_read_bridge_bases(b);
+		pcibios_fixup_device_resources(b->self);
+	}
 	list_for_each_entry(dev, &b->devices, bus_list)
 		pcibios_fixup_device_resources(dev);
 
@@ -436,18 +451,24 @@ pcibios_enable_resources (struct pci_dev
 	u16 cmd, old_cmd;
 	int idx;
 	struct resource *r;
+	unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM;
 
 	if (!dev)
 		return -EINVAL;
 
 	pci_read_config_word(dev, PCI_COMMAND, &cmd);
 	old_cmd = cmd;
-	for (idx=0; idx<6; idx++) {
+	for (idx=0; idx<PCI_NUM_RESOURCES; idx++) {
 		/* Only set up the desired resources.  */
 		if (!(mask & (1 << idx)))
 			continue;
 
 		r = &dev->resource[idx];
+		if (!(r->flags & type_mask))
+			continue;
+		if ((idx == PCI_ROM_RESOURCE) &&
+				(!(r->flags & IORESOURCE_ROM_ENABLE)))
+			continue;
 		if (!r->start && r->end) {
 			printk(KERN_ERR
 			       "PCI: Device %s not available because of resource collisions\n",
@@ -459,8 +480,6 @@ pcibios_enable_resources (struct pci_dev
 		if (r->flags & IORESOURCE_MEM)
 			cmd |= PCI_COMMAND_MEMORY;
 	}
-	if (dev->resource[PCI_ROM_RESOURCE].start)
-		cmd |= PCI_COMMAND_MEMORY;
 	if (cmd != old_cmd) {
 		printk("PCI: Enabling device %s (%04x -> %04x)\n", pci_name(dev), old_cmd, cmd);
 		pci_write_config_word(dev, PCI_COMMAND, cmd);
@@ -500,8 +519,6 @@ pcibios_align_resource (void *data, stru
 char * __init
 pcibios_setup (char *str)
 {
-	if (!strcmp(str, "routeirq"))
-		pci_routeirq = 1;
 	return NULL;
 }
 
diff --git a/arch/ia64/sn/include/pci/pcibr_provider.h b/arch/ia64/sn/include/pci/pcibr_provider.h
deleted file mode 100644
--- a/arch/ia64/sn/include/pci/pcibr_provider.h
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992-1997,2000-2004 Silicon Graphics, Inc. All rights reserved.
- */
-#ifndef _ASM_IA64_SN_PCI_PCIBR_PROVIDER_H
-#define _ASM_IA64_SN_PCI_PCIBR_PROVIDER_H
-
-/* Workarounds */
-#define PV907516 (1 << 1) /* TIOCP: Don't write the write buffer flush reg */
-
-#define BUSTYPE_MASK                    0x1
-
-/* Macros given a pcibus structure */
-#define IS_PCIX(ps)     ((ps)->pbi_bridge_mode & BUSTYPE_MASK)
-#define IS_PCI_BRIDGE_ASIC(asic) (asic == PCIIO_ASIC_TYPE_PIC || \
-                asic == PCIIO_ASIC_TYPE_TIOCP)
-#define IS_PIC_SOFT(ps)     (ps->pbi_bridge_type == PCIBR_BRIDGETYPE_PIC)
-
-
-/* 
- * The different PCI Bridge types supported on the SGI Altix platforms
- */
-#define PCIBR_BRIDGETYPE_UNKNOWN       -1
-#define PCIBR_BRIDGETYPE_PIC            2
-#define PCIBR_BRIDGETYPE_TIOCP          3
-
-/*
- * Bridge 64bit Direct Map Attributes
- */
-#define PCI64_ATTR_PREF                 (1ull << 59)
-#define PCI64_ATTR_PREC                 (1ull << 58)
-#define PCI64_ATTR_VIRTUAL              (1ull << 57)
-#define PCI64_ATTR_BAR                  (1ull << 56)
-#define PCI64_ATTR_SWAP                 (1ull << 55)
-#define PCI64_ATTR_VIRTUAL1             (1ull << 54)
-
-#define PCI32_LOCAL_BASE                0
-#define PCI32_MAPPED_BASE               0x40000000
-#define PCI32_DIRECT_BASE               0x80000000
-
-#define IS_PCI32_MAPPED(x)              ((uint64_t)(x) < PCI32_DIRECT_BASE && \
-                                         (uint64_t)(x) >= PCI32_MAPPED_BASE)
-#define IS_PCI32_DIRECT(x)              ((uint64_t)(x) >= PCI32_MAPPED_BASE)
-
-
-/*
- * Bridge PMU Address Transaltion Entry Attibutes
- */
-#define PCI32_ATE_V                     (0x1 << 0)
-#define PCI32_ATE_CO                    (0x1 << 1)
-#define PCI32_ATE_PREC                  (0x1 << 2)
-#define PCI32_ATE_PREF                  (0x1 << 3)
-#define PCI32_ATE_BAR                   (0x1 << 4)
-#define PCI32_ATE_ADDR_SHFT             12
-
-#define MINIMAL_ATES_REQUIRED(addr, size) \
-	(IOPG(IOPGOFF(addr) + (size) - 1) == IOPG((size) - 1))
-
-#define MINIMAL_ATE_FLAG(addr, size) \
-	(MINIMAL_ATES_REQUIRED((uint64_t)addr, size) ? 1 : 0)
-
-/* bit 29 of the pci address is the SWAP bit */
-#define ATE_SWAPSHIFT                   29
-#define ATE_SWAP_ON(x)                  ((x) |= (1 << ATE_SWAPSHIFT))
-#define ATE_SWAP_OFF(x)                 ((x) &= ~(1 << ATE_SWAPSHIFT))
-
-/*
- * I/O page size
- */
-#if PAGE_SIZE < 16384
-#define IOPFNSHIFT                      12      /* 4K per mapped page */
-#else
-#define IOPFNSHIFT                      14      /* 16K per mapped page */
-#endif
-
-#define IOPGSIZE                        (1 << IOPFNSHIFT)
-#define IOPG(x)                         ((x) >> IOPFNSHIFT)
-#define IOPGOFF(x)                      ((x) & (IOPGSIZE-1))
-
-#define PCIBR_DEV_SWAP_DIR              (1ull << 19)
-#define PCIBR_CTRL_PAGE_SIZE            (0x1 << 21)
-
-/*
- * PMU resources.
- */
-struct ate_resource{
-	uint64_t *ate;
-	uint64_t num_ate;
-	uint64_t lowest_free_index;
-};
-
-struct pcibus_info {
-	struct pcibus_bussoft	pbi_buscommon;   /* common header */
-	uint32_t                pbi_moduleid;
-	short                   pbi_bridge_type;
-	short                   pbi_bridge_mode;
-
-	struct ate_resource     pbi_int_ate_resource;
-	uint64_t                pbi_int_ate_size;
-	
-	uint64_t                pbi_dir_xbase;
-	char                    pbi_hub_xid;
-
-	uint64_t                pbi_devreg[8];
-	spinlock_t              pbi_lock;
-
-	uint32_t		pbi_valid_devices;
-	uint32_t		pbi_enabled_devices;
-};
-
-/*
- * pcibus_info structure locking macros
- */
-inline static unsigned long
-pcibr_lock(struct pcibus_info *pcibus_info)
-{
-	unsigned long flag;
-	spin_lock_irqsave(&pcibus_info->pbi_lock, flag);
-	return(flag);
-}
-#define pcibr_unlock(pcibus_info, flag)  spin_unlock_irqrestore(&pcibus_info->pbi_lock, flag)
-
-extern int  pcibr_init_provider(void);
-extern void *pcibr_bus_fixup(struct pcibus_bussoft *);
-extern dma_addr_t pcibr_dma_map(struct pci_dev *, unsigned long, size_t);
-extern dma_addr_t pcibr_dma_map_consistent(struct pci_dev *, unsigned long, size_t);
-extern void pcibr_dma_unmap(struct pci_dev *, dma_addr_t, int);
-
-/*
- * prototypes for the bridge asic register access routines in pcibr_reg.c
- */
-extern void             pcireg_control_bit_clr(struct pcibus_info *, uint64_t);
-extern void             pcireg_control_bit_set(struct pcibus_info *, uint64_t);
-extern uint64_t         pcireg_tflush_get(struct pcibus_info *);
-extern uint64_t         pcireg_intr_status_get(struct pcibus_info *);
-extern void             pcireg_intr_enable_bit_clr(struct pcibus_info *, uint64_t);
-extern void             pcireg_intr_enable_bit_set(struct pcibus_info *, uint64_t);
-extern void             pcireg_intr_addr_addr_set(struct pcibus_info *, int, uint64_t);
-extern void             pcireg_force_intr_set(struct pcibus_info *, int);
-extern uint64_t         pcireg_wrb_flush_get(struct pcibus_info *, int);
-extern void             pcireg_int_ate_set(struct pcibus_info *, int, uint64_t);
-extern uint64_t *	pcireg_int_ate_addr(struct pcibus_info *, int);
-extern void 		pcibr_force_interrupt(struct sn_irq_info *sn_irq_info);
-extern void 		pcibr_change_devices_irq(struct sn_irq_info *sn_irq_info);
-extern int 		pcibr_ate_alloc(struct pcibus_info *, int);
-extern void 		pcibr_ate_free(struct pcibus_info *, int);
-extern void 		ate_write(struct pcibus_info *, int, int, uint64_t);
-#endif
diff --git a/arch/ia64/sn/include/pci/pic.h b/arch/ia64/sn/include/pci/pic.h
deleted file mode 100644
--- a/arch/ia64/sn/include/pci/pic.h
+++ /dev/null
@@ -1,261 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
- */
-#ifndef _ASM_IA64_SN_PCI_PIC_H
-#define _ASM_IA64_SN_PCI_PIC_H
-
-/*
- * PIC AS DEVICE ZERO
- * ------------------
- *
- * PIC handles PCI/X busses.  PCI/X requires that the 'bridge' (i.e. PIC)
- * be designated as 'device 0'.   That is a departure from earlier SGI
- * PCI bridges.  Because of that we use config space 1 to access the
- * config space of the first actual PCI device on the bus. 
- * Here's what the PIC manual says:
- *
- *     The current PCI-X bus specification now defines that the parent
- *     hosts bus bridge (PIC for example) must be device 0 on bus 0. PIC
- *     reduced the total number of devices from 8 to 4 and removed the
- *     device registers and windows, now only supporting devices 0,1,2, and
- *     3. PIC did leave all 8 configuration space windows. The reason was
- *     there was nothing to gain by removing them. Here in lies the problem.
- *     The device numbering we do using 0 through 3 is unrelated to the device
- *     numbering which PCI-X requires in configuration space. In the past we
- *     correlated Configs pace and our device space 0 <-> 0, 1 <-> 1, etc.
- *     PCI-X requires we start a 1, not 0 and currently the PX brick
- *     does associate our:
- * 
- *         device 0 with configuration space window 1,
- *         device 1 with configuration space window 2, 
- *         device 2 with configuration space window 3,
- *         device 3 with configuration space window 4.
- *
- * The net effect is that all config space access are off-by-one with 
- * relation to other per-slot accesses on the PIC.   
- * Here is a table that shows some of that:
- *
- *                               Internal Slot#
- *           |
- *           |     0         1        2         3
- * ----------|---------------------------------------
- * config    |  0x21000   0x22000  0x23000   0x24000
- *           |
- * even rrb  |  0[0]      n/a      1[0]      n/a	[] == implied even/odd
- *           |
- * odd rrb   |  n/a       0[1]     n/a       1[1]
- *           |
- * int dev   |  00       01        10        11
- *           |
- * ext slot# |  1        2         3         4
- * ----------|---------------------------------------
- */
-
-#define PIC_ATE_TARGETID_SHFT           8
-#define PIC_HOST_INTR_ADDR              0x0000FFFFFFFFFFFFUL
-#define PIC_PCI64_ATTR_TARG_SHFT        60
-
-
-/*****************************************************************************
- *********************** PIC MMR structure mapping ***************************
- *****************************************************************************/
-
-/* NOTE: PIC WAR. PV#854697.  PIC does not allow writes just to [31:0]
- * of a 64-bit register.  When writing PIC registers, always write the 
- * entire 64 bits.
- */
-
-struct pic {
-
-    /* 0x000000-0x00FFFF -- Local Registers */
-
-    /* 0x000000-0x000057 -- Standard Widget Configuration */
-    uint64_t		p_wid_id;			/* 0x000000 */
-    uint64_t		p_wid_stat;			/* 0x000008 */
-    uint64_t		p_wid_err_upper;		/* 0x000010 */
-    uint64_t		p_wid_err_lower;		/* 0x000018 */
-    #define p_wid_err p_wid_err_lower
-    uint64_t		p_wid_control;			/* 0x000020 */
-    uint64_t		p_wid_req_timeout;		/* 0x000028 */
-    uint64_t		p_wid_int_upper;		/* 0x000030 */
-    uint64_t		p_wid_int_lower;		/* 0x000038 */
-    #define p_wid_int p_wid_int_lower
-    uint64_t		p_wid_err_cmdword;		/* 0x000040 */
-    uint64_t		p_wid_llp;			/* 0x000048 */
-    uint64_t		p_wid_tflush;			/* 0x000050 */
-
-    /* 0x000058-0x00007F -- Bridge-specific Widget Configuration */
-    uint64_t		p_wid_aux_err;			/* 0x000058 */
-    uint64_t		p_wid_resp_upper;		/* 0x000060 */
-    uint64_t		p_wid_resp_lower;		/* 0x000068 */
-    #define p_wid_resp p_wid_resp_lower
-    uint64_t		p_wid_tst_pin_ctrl;		/* 0x000070 */
-    uint64_t		p_wid_addr_lkerr;		/* 0x000078 */
-
-    /* 0x000080-0x00008F -- PMU & MAP */
-    uint64_t		p_dir_map;			/* 0x000080 */
-    uint64_t		_pad_000088;			/* 0x000088 */
-
-    /* 0x000090-0x00009F -- SSRAM */
-    uint64_t		p_map_fault;			/* 0x000090 */
-    uint64_t		_pad_000098;			/* 0x000098 */
-
-    /* 0x0000A0-0x0000AF -- Arbitration */
-    uint64_t		p_arb;				/* 0x0000A0 */
-    uint64_t		_pad_0000A8;			/* 0x0000A8 */
-
-    /* 0x0000B0-0x0000BF -- Number In A Can or ATE Parity Error */
-    uint64_t		p_ate_parity_err;		/* 0x0000B0 */
-    uint64_t		_pad_0000B8;			/* 0x0000B8 */
-
-    /* 0x0000C0-0x0000FF -- PCI/GIO */
-    uint64_t		p_bus_timeout;			/* 0x0000C0 */
-    uint64_t		p_pci_cfg;			/* 0x0000C8 */
-    uint64_t		p_pci_err_upper;		/* 0x0000D0 */
-    uint64_t		p_pci_err_lower;		/* 0x0000D8 */
-    #define p_pci_err p_pci_err_lower
-    uint64_t		_pad_0000E0[4];			/* 0x0000{E0..F8} */
-
-    /* 0x000100-0x0001FF -- Interrupt */
-    uint64_t		p_int_status;			/* 0x000100 */
-    uint64_t		p_int_enable;			/* 0x000108 */
-    uint64_t		p_int_rst_stat;			/* 0x000110 */
-    uint64_t		p_int_mode;			/* 0x000118 */
-    uint64_t		p_int_device;			/* 0x000120 */
-    uint64_t		p_int_host_err;			/* 0x000128 */
-    uint64_t		p_int_addr[8];			/* 0x0001{30,,,68} */
-    uint64_t		p_err_int_view;			/* 0x000170 */
-    uint64_t		p_mult_int;			/* 0x000178 */
-    uint64_t		p_force_always[8];		/* 0x0001{80,,,B8} */
-    uint64_t		p_force_pin[8];			/* 0x0001{C0,,,F8} */
-
-    /* 0x000200-0x000298 -- Device */
-    uint64_t		p_device[4];			/* 0x0002{00,,,18} */
-    uint64_t		_pad_000220[4];			/* 0x0002{20,,,38} */
-    uint64_t		p_wr_req_buf[4];		/* 0x0002{40,,,58} */
-    uint64_t		_pad_000260[4];			/* 0x0002{60,,,78} */
-    uint64_t		p_rrb_map[2];			/* 0x0002{80,,,88} */
-    #define p_even_resp p_rrb_map[0]			/* 0x000280 */
-    #define p_odd_resp  p_rrb_map[1]			/* 0x000288 */
-    uint64_t		p_resp_status;			/* 0x000290 */
-    uint64_t		p_resp_clear;			/* 0x000298 */
-
-    uint64_t		_pad_0002A0[12];		/* 0x0002{A0..F8} */
-
-    /* 0x000300-0x0003F8 -- Buffer Address Match Registers */
-    struct {
-	uint64_t	upper;				/* 0x0003{00,,,F0} */
-	uint64_t	lower;				/* 0x0003{08,,,F8} */
-    } p_buf_addr_match[16];
-
-    /* 0x000400-0x0005FF -- Performance Monitor Registers (even only) */
-    struct {
-	uint64_t	flush_w_touch;			/* 0x000{400,,,5C0} */
-	uint64_t	flush_wo_touch;			/* 0x000{408,,,5C8} */
-	uint64_t	inflight;			/* 0x000{410,,,5D0} */
-	uint64_t	prefetch;			/* 0x000{418,,,5D8} */
-	uint64_t	total_pci_retry;		/* 0x000{420,,,5E0} */
-	uint64_t	max_pci_retry;			/* 0x000{428,,,5E8} */
-	uint64_t	max_latency;			/* 0x000{430,,,5F0} */
-	uint64_t	clear_all;			/* 0x000{438,,,5F8} */
-    } p_buf_count[8];
-
-    
-    /* 0x000600-0x0009FF -- PCI/X registers */
-    uint64_t		p_pcix_bus_err_addr;		/* 0x000600 */
-    uint64_t		p_pcix_bus_err_attr;		/* 0x000608 */
-    uint64_t		p_pcix_bus_err_data;		/* 0x000610 */
-    uint64_t		p_pcix_pio_split_addr;		/* 0x000618 */
-    uint64_t		p_pcix_pio_split_attr;		/* 0x000620 */
-    uint64_t		p_pcix_dma_req_err_attr;	/* 0x000628 */
-    uint64_t		p_pcix_dma_req_err_addr;	/* 0x000630 */
-    uint64_t		p_pcix_timeout;			/* 0x000638 */
-
-    uint64_t		_pad_000640[120];		/* 0x000{640,,,9F8} */
-
-    /* 0x000A00-0x000BFF -- PCI/X Read&Write Buffer */
-    struct {
-	uint64_t	p_buf_addr;			/* 0x000{A00,,,AF0} */
-	uint64_t	p_buf_attr;			/* 0X000{A08,,,AF8} */
-    } p_pcix_read_buf_64[16];
-
-    struct {
-	uint64_t	p_buf_addr;			/* 0x000{B00,,,BE0} */
-	uint64_t	p_buf_attr;			/* 0x000{B08,,,BE8} */
-	uint64_t	p_buf_valid;			/* 0x000{B10,,,BF0} */
-	uint64_t	__pad1;				/* 0x000{B18,,,BF8} */
-    } p_pcix_write_buf_64[8];
-
-    /* End of Local Registers -- Start of Address Map space */
-
-    char		_pad_000c00[0x010000 - 0x000c00];
-
-    /* 0x010000-0x011fff -- Internal ATE RAM (Auto Parity Generation) */
-    uint64_t		p_int_ate_ram[1024];		/* 0x010000-0x011fff */
-
-    /* 0x012000-0x013fff -- Internal ATE RAM (Manual Parity Generation) */
-    uint64_t		p_int_ate_ram_mp[1024];		/* 0x012000-0x013fff */
-
-    char		_pad_014000[0x18000 - 0x014000];
-
-    /* 0x18000-0x197F8 -- PIC Write Request Ram */
-    uint64_t		p_wr_req_lower[256];		/* 0x18000 - 0x187F8 */
-    uint64_t		p_wr_req_upper[256];		/* 0x18800 - 0x18FF8 */
-    uint64_t		p_wr_req_parity[256];		/* 0x19000 - 0x197F8 */
-
-    char		_pad_019800[0x20000 - 0x019800];
-
-    /* 0x020000-0x027FFF -- PCI Device Configuration Spaces */
-    union {
-	uint8_t		c[0x1000 / 1];			/* 0x02{0000,,,7FFF} */
-	uint16_t	s[0x1000 / 2];			/* 0x02{0000,,,7FFF} */
-	uint32_t	l[0x1000 / 4];			/* 0x02{0000,,,7FFF} */
-	uint64_t	d[0x1000 / 8];			/* 0x02{0000,,,7FFF} */
-	union {
-	    uint8_t	c[0x100 / 1];
-	    uint16_t	s[0x100 / 2];
-	    uint32_t	l[0x100 / 4];
-	    uint64_t	d[0x100 / 8];
-	} f[8];
-    } p_type0_cfg_dev[8];				/* 0x02{0000,,,7FFF} */
-
-    /* 0x028000-0x028FFF -- PCI Type 1 Configuration Space */
-    union {
-	uint8_t		c[0x1000 / 1];			/* 0x028000-0x029000 */
-	uint16_t	s[0x1000 / 2];			/* 0x028000-0x029000 */
-	uint32_t	l[0x1000 / 4];			/* 0x028000-0x029000 */
-	uint64_t	d[0x1000 / 8];			/* 0x028000-0x029000 */
-	union {
-	    uint8_t	c[0x100 / 1];
-	    uint16_t	s[0x100 / 2];
-	    uint32_t	l[0x100 / 4];
-	    uint64_t	d[0x100 / 8];
-	} f[8];
-    } p_type1_cfg;					/* 0x028000-0x029000 */
-
-    char		_pad_029000[0x030000-0x029000];
-
-    /* 0x030000-0x030007 -- PCI Interrupt Acknowledge Cycle */
-    union {
-	uint8_t		c[8 / 1];
-	uint16_t	s[8 / 2];
-	uint32_t	l[8 / 4];
-	uint64_t	d[8 / 8];
-    } p_pci_iack;					/* 0x030000-0x030007 */
-
-    char		_pad_030007[0x040000-0x030008];
-
-    /* 0x040000-0x030007 -- PCIX Special Cycle */
-    union {
-	uint8_t		c[8 / 1];
-	uint16_t	s[8 / 2];
-	uint32_t	l[8 / 4];
-	uint64_t	d[8 / 8];
-    } p_pcix_cycle;					/* 0x040000-0x040007 */
-};
-
-#endif                          /* _ASM_IA64_SN_PCI_PIC_H */
diff --git a/arch/ia64/sn/include/pci/tiocp.h b/arch/ia64/sn/include/pci/tiocp.h
deleted file mode 100644
--- a/arch/ia64/sn/include/pci/tiocp.h
+++ /dev/null
@@ -1,256 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2003-2004 Silicon Graphics, Inc. All rights reserved.
- */
-#ifndef _ASM_IA64_SN_PCI_TIOCP_H
-#define _ASM_IA64_SN_PCI_TIOCP_H
-
-#define TIOCP_HOST_INTR_ADDR            0x003FFFFFFFFFFFFFUL
-#define TIOCP_PCI64_CMDTYPE_MEM         (0x1ull << 60)
-
-
-/*****************************************************************************
- *********************** TIOCP MMR structure mapping ***************************
- *****************************************************************************/
-
-struct tiocp{
-
-    /* 0x000000-0x00FFFF -- Local Registers */
-
-    /* 0x000000-0x000057 -- (Legacy Widget Space) Configuration */
-    uint64_t		cp_id;				/* 0x000000 */
-    uint64_t		cp_stat;			/* 0x000008 */
-    uint64_t		cp_err_upper;			/* 0x000010 */
-    uint64_t		cp_err_lower;			/* 0x000018 */
-    #define cp_err cp_err_lower
-    uint64_t		cp_control;			/* 0x000020 */
-    uint64_t		cp_req_timeout;			/* 0x000028 */
-    uint64_t		cp_intr_upper;			/* 0x000030 */
-    uint64_t		cp_intr_lower;			/* 0x000038 */
-    #define cp_intr cp_intr_lower
-    uint64_t		cp_err_cmdword;			/* 0x000040 */
-    uint64_t		_pad_000048;			/* 0x000048 */
-    uint64_t		cp_tflush;			/* 0x000050 */
-
-    /* 0x000058-0x00007F -- Bridge-specific Configuration */
-    uint64_t		cp_aux_err;			/* 0x000058 */
-    uint64_t		cp_resp_upper;			/* 0x000060 */
-    uint64_t		cp_resp_lower;			/* 0x000068 */
-    #define cp_resp cp_resp_lower
-    uint64_t		cp_tst_pin_ctrl;		/* 0x000070 */
-    uint64_t		cp_addr_lkerr;			/* 0x000078 */
-
-    /* 0x000080-0x00008F -- PMU & MAP */
-    uint64_t		cp_dir_map;			/* 0x000080 */
-    uint64_t		_pad_000088;			/* 0x000088 */
-
-    /* 0x000090-0x00009F -- SSRAM */
-    uint64_t		cp_map_fault;			/* 0x000090 */
-    uint64_t		_pad_000098;			/* 0x000098 */
-
-    /* 0x0000A0-0x0000AF -- Arbitration */
-    uint64_t		cp_arb;				/* 0x0000A0 */
-    uint64_t		_pad_0000A8;			/* 0x0000A8 */
-
-    /* 0x0000B0-0x0000BF -- Number In A Can or ATE Parity Error */
-    uint64_t		cp_ate_parity_err;		/* 0x0000B0 */
-    uint64_t		_pad_0000B8;			/* 0x0000B8 */
-
-    /* 0x0000C0-0x0000FF -- PCI/GIO */
-    uint64_t		cp_bus_timeout;			/* 0x0000C0 */
-    uint64_t		cp_pci_cfg;			/* 0x0000C8 */
-    uint64_t		cp_pci_err_upper;		/* 0x0000D0 */
-    uint64_t		cp_pci_err_lower;		/* 0x0000D8 */
-    #define cp_pci_err cp_pci_err_lower
-    uint64_t		_pad_0000E0[4];			/* 0x0000{E0..F8} */
-
-    /* 0x000100-0x0001FF -- Interrupt */
-    uint64_t		cp_int_status;			/* 0x000100 */
-    uint64_t		cp_int_enable;			/* 0x000108 */
-    uint64_t		cp_int_rst_stat;		/* 0x000110 */
-    uint64_t		cp_int_mode;			/* 0x000118 */
-    uint64_t		cp_int_device;			/* 0x000120 */
-    uint64_t		cp_int_host_err;		/* 0x000128 */
-    uint64_t		cp_int_addr[8];			/* 0x0001{30,,,68} */
-    uint64_t		cp_err_int_view;		/* 0x000170 */
-    uint64_t		cp_mult_int;			/* 0x000178 */
-    uint64_t		cp_force_always[8];		/* 0x0001{80,,,B8} */
-    uint64_t		cp_force_pin[8];		/* 0x0001{C0,,,F8} */
-
-    /* 0x000200-0x000298 -- Device */
-    uint64_t		cp_device[4];			/* 0x0002{00,,,18} */
-    uint64_t		_pad_000220[4];			/* 0x0002{20,,,38} */
-    uint64_t		cp_wr_req_buf[4];		/* 0x0002{40,,,58} */
-    uint64_t		_pad_000260[4];			/* 0x0002{60,,,78} */
-    uint64_t		cp_rrb_map[2];			/* 0x0002{80,,,88} */
-    #define cp_even_resp cp_rrb_map[0]			/* 0x000280 */
-    #define cp_odd_resp  cp_rrb_map[1]			/* 0x000288 */
-    uint64_t		cp_resp_status;			/* 0x000290 */
-    uint64_t		cp_resp_clear;			/* 0x000298 */
-
-    uint64_t		_pad_0002A0[12];		/* 0x0002{A0..F8} */
-
-    /* 0x000300-0x0003F8 -- Buffer Address Match Registers */
-    struct {
-	uint64_t	upper;				/* 0x0003{00,,,F0} */
-	uint64_t	lower;				/* 0x0003{08,,,F8} */
-    } cp_buf_addr_match[16];
-
-    /* 0x000400-0x0005FF -- Performance Monitor Registers (even only) */
-    struct {
-	uint64_t	flush_w_touch;			/* 0x000{400,,,5C0} */
-	uint64_t	flush_wo_touch;			/* 0x000{408,,,5C8} */
-	uint64_t	inflight;			/* 0x000{410,,,5D0} */
-	uint64_t	prefetch;			/* 0x000{418,,,5D8} */
-	uint64_t	total_pci_retry;		/* 0x000{420,,,5E0} */
-	uint64_t	max_pci_retry;			/* 0x000{428,,,5E8} */
-	uint64_t	max_latency;			/* 0x000{430,,,5F0} */
-	uint64_t	clear_all;			/* 0x000{438,,,5F8} */
-    } cp_buf_count[8];
-
-    
-    /* 0x000600-0x0009FF -- PCI/X registers */
-    uint64_t		cp_pcix_bus_err_addr;		/* 0x000600 */
-    uint64_t		cp_pcix_bus_err_attr;		/* 0x000608 */
-    uint64_t		cp_pcix_bus_err_data;		/* 0x000610 */
-    uint64_t		cp_pcix_pio_split_addr;		/* 0x000618 */
-    uint64_t		cp_pcix_pio_split_attr;		/* 0x000620 */
-    uint64_t		cp_pcix_dma_req_err_attr;	/* 0x000628 */
-    uint64_t		cp_pcix_dma_req_err_addr;	/* 0x000630 */
-    uint64_t		cp_pcix_timeout;		/* 0x000638 */
-
-    uint64_t		_pad_000640[24];		/* 0x000{640,,,6F8} */
-
-    /* 0x000700-0x000737 -- Debug Registers */
-    uint64_t		cp_ct_debug_ctl;		/* 0x000700 */
-    uint64_t		cp_br_debug_ctl;		/* 0x000708 */
-    uint64_t		cp_mux3_debug_ctl;		/* 0x000710 */
-    uint64_t		cp_mux4_debug_ctl;		/* 0x000718 */
-    uint64_t		cp_mux5_debug_ctl;		/* 0x000720 */
-    uint64_t		cp_mux6_debug_ctl;		/* 0x000728 */
-    uint64_t		cp_mux7_debug_ctl;		/* 0x000730 */
-
-    uint64_t		_pad_000738[89];		/* 0x000{738,,,9F8} */
-
-    /* 0x000A00-0x000BFF -- PCI/X Read&Write Buffer */
-    struct {
-	uint64_t	cp_buf_addr;			/* 0x000{A00,,,AF0} */
-	uint64_t	cp_buf_attr;			/* 0X000{A08,,,AF8} */
-    } cp_pcix_read_buf_64[16];
-
-    struct {
-	uint64_t	cp_buf_addr;			/* 0x000{B00,,,BE0} */
-	uint64_t	cp_buf_attr;			/* 0x000{B08,,,BE8} */
-	uint64_t	cp_buf_valid;			/* 0x000{B10,,,BF0} */
-	uint64_t	__pad1;				/* 0x000{B18,,,BF8} */
-    } cp_pcix_write_buf_64[8];
-
-    /* End of Local Registers -- Start of Address Map space */
-
-    char		_pad_000c00[0x010000 - 0x000c00];
-
-    /* 0x010000-0x011FF8 -- Internal ATE RAM (Auto Parity Generation) */
-    uint64_t		cp_int_ate_ram[1024];		/* 0x010000-0x011FF8 */
-
-    char		_pad_012000[0x14000 - 0x012000];
-
-    /* 0x014000-0x015FF8 -- Internal ATE RAM (Manual Parity Generation) */
-    uint64_t		cp_int_ate_ram_mp[1024];	/* 0x014000-0x015FF8 */
-
-    char		_pad_016000[0x18000 - 0x016000];
-
-    /* 0x18000-0x197F8 -- TIOCP Write Request Ram */
-    uint64_t		cp_wr_req_lower[256];		/* 0x18000 - 0x187F8 */
-    uint64_t		cp_wr_req_upper[256];		/* 0x18800 - 0x18FF8 */
-    uint64_t		cp_wr_req_parity[256];		/* 0x19000 - 0x197F8 */
-
-    char		_pad_019800[0x1C000 - 0x019800];
-
-    /* 0x1C000-0x1EFF8 -- TIOCP Read Response Ram */
-    uint64_t		cp_rd_resp_lower[512];		/* 0x1C000 - 0x1CFF8 */
-    uint64_t		cp_rd_resp_upper[512];		/* 0x1D000 - 0x1DFF8 */
-    uint64_t		cp_rd_resp_parity[512];		/* 0x1E000 - 0x1EFF8 */
-
-    char		_pad_01F000[0x20000 - 0x01F000];
-
-    /* 0x020000-0x021FFF -- Host Device (CP) Configuration Space (not used)  */
-    char		_pad_020000[0x021000 - 0x20000];
-
-    /* 0x021000-0x027FFF -- PCI Device Configuration Spaces */
-    union {
-	uint8_t		c[0x1000 / 1];			/* 0x02{0000,,,7FFF} */
-	uint16_t	s[0x1000 / 2];			/* 0x02{0000,,,7FFF} */
-	uint32_t	l[0x1000 / 4];			/* 0x02{0000,,,7FFF} */
-	uint64_t	d[0x1000 / 8];			/* 0x02{0000,,,7FFF} */
-	union {
-	    uint8_t	c[0x100 / 1];
-	    uint16_t	s[0x100 / 2];
-	    uint32_t	l[0x100 / 4];
-	    uint64_t	d[0x100 / 8];
-	} f[8];
-    } cp_type0_cfg_dev[7];				/* 0x02{1000,,,7FFF} */
-
-    /* 0x028000-0x028FFF -- PCI Type 1 Configuration Space */
-    union {
-	uint8_t		c[0x1000 / 1];			/* 0x028000-0x029000 */
-	uint16_t	s[0x1000 / 2];			/* 0x028000-0x029000 */
-	uint32_t	l[0x1000 / 4];			/* 0x028000-0x029000 */
-	uint64_t	d[0x1000 / 8];			/* 0x028000-0x029000 */
-	union {
-	    uint8_t	c[0x100 / 1];
-	    uint16_t	s[0x100 / 2];
-	    uint32_t	l[0x100 / 4];
-	    uint64_t	d[0x100 / 8];
-	} f[8];
-    } cp_type1_cfg;					/* 0x028000-0x029000 */
-
-    char		_pad_029000[0x030000-0x029000];
-
-    /* 0x030000-0x030007 -- PCI Interrupt Acknowledge Cycle */
-    union {
-	uint8_t		c[8 / 1];
-	uint16_t	s[8 / 2];
-	uint32_t	l[8 / 4];
-	uint64_t	d[8 / 8];
-    } cp_pci_iack;					/* 0x030000-0x030007 */
-
-    char		_pad_030007[0x040000-0x030008];
-
-    /* 0x040000-0x040007 -- PCIX Special Cycle */
-    union {
-	uint8_t		c[8 / 1];
-	uint16_t	s[8 / 2];
-	uint32_t	l[8 / 4];
-	uint64_t	d[8 / 8];
-    } cp_pcix_cycle;					/* 0x040000-0x040007 */
-
-    char		_pad_040007[0x200000-0x040008];
-
-    /* 0x200000-0x7FFFFF -- PCI/GIO Device Spaces */
-    union {
-	uint8_t		c[0x100000 / 1];
-	uint16_t	s[0x100000 / 2];
-	uint32_t	l[0x100000 / 4];
-	uint64_t	d[0x100000 / 8];
-    } cp_devio_raw[6];					/* 0x200000-0x7FFFFF */
-
-    #define cp_devio(n)  cp_devio_raw[((n)<2)?(n*2):(n+2)]
-
-    char		_pad_800000[0xA00000-0x800000];
-
-    /* 0xA00000-0xBFFFFF -- PCI/GIO Device Spaces w/flush  */
-    union {
-	uint8_t		c[0x100000 / 1];
-	uint16_t	s[0x100000 / 2];
-	uint32_t	l[0x100000 / 4];
-	uint64_t	d[0x100000 / 8];
-    } cp_devio_raw_flush[6];				/* 0xA00000-0xBFFFFF */
-
-    #define cp_devio_flush(n)  cp_devio_raw_flush[((n)<2)?(n*2):(n+2)]
-
-};
-
-#endif 	/* _ASM_IA64_SN_PCI_TIOCP_H */
diff --git a/arch/ia64/sn/include/xtalk/hubdev.h b/arch/ia64/sn/include/xtalk/hubdev.h
--- a/arch/ia64/sn/include/xtalk/hubdev.h
+++ b/arch/ia64/sn/include/xtalk/hubdev.h
@@ -8,6 +8,8 @@
 #ifndef _ASM_IA64_SN_XTALK_HUBDEV_H
 #define _ASM_IA64_SN_XTALK_HUBDEV_H
 
+#include "xtalk/xwidgetdev.h"
+
 #define HUB_WIDGET_ID_MAX 0xf
 #define DEV_PER_WIDGET (2*2*8)
 #define IIO_ITTE_WIDGET_BITS    4       /* size of widget field */
diff --git a/arch/ia64/sn/kernel/io_init.c b/arch/ia64/sn/kernel/io_init.c
--- a/arch/ia64/sn/kernel/io_init.c
+++ b/arch/ia64/sn/kernel/io_init.c
@@ -9,21 +9,28 @@
 #include <linux/bootmem.h>
 #include <linux/nodemask.h>
 #include <asm/sn/types.h>
-#include <asm/sn/sn_sal.h>
 #include <asm/sn/addrs.h>
-#include <asm/sn/pcibus_provider_defs.h>
-#include <asm/sn/pcidev.h>
-#include "pci/pcibr_provider.h"
-#include "xtalk/xwidgetdev.h"
 #include <asm/sn/geo.h>
-#include "xtalk/hubdev.h"
 #include <asm/sn/io.h>
+#include <asm/sn/pcibr_provider.h>
+#include <asm/sn/pcibus_provider_defs.h>
+#include <asm/sn/pcidev.h>
 #include <asm/sn/simulator.h>
+#include <asm/sn/sn_sal.h>
 #include <asm/sn/tioca_provider.h>
+#include "xtalk/hubdev.h"
+#include "xtalk/xwidgetdev.h"
 
-char master_baseio_wid;
 nasid_t master_nasid = INVALID_NASID;	/* Partition Master */
 
+static struct list_head sn_sysdata_list;
+
+/* sysdata list struct */
+struct sysdata_el {
+	struct list_head entry;
+	void *sysdata;
+};
+
 struct slab_info {
 	struct hubdev_info hubdev;
 };
@@ -54,7 +61,7 @@ sn_default_pci_unmap(struct pci_dev *pde
 }
 
 static void *
-sn_default_pci_bus_fixup(struct pcibus_bussoft *soft)
+sn_default_pci_bus_fixup(struct pcibus_bussoft *soft, struct pci_controller *controller)
 {
 	return NULL;
 }
@@ -138,23 +145,6 @@ sal_get_pcidev_info(u64 segment, u64 bus
 }
 
 /*
- * sn_alloc_pci_sysdata() - This routine allocates a pci controller
- *	which is expected as the pci_dev and pci_bus sysdata by the Linux
- *	PCI infrastructure.
- */
-static inline struct pci_controller *sn_alloc_pci_sysdata(void)
-{
-	struct pci_controller *pci_sysdata;
-
-	pci_sysdata = kmalloc(sizeof(*pci_sysdata), GFP_KERNEL);
-	if (!pci_sysdata)
-		BUG();
-
-	memset(pci_sysdata, 0, sizeof(*pci_sysdata));
-	return pci_sysdata;
-}
-
-/*
  * sn_fixup_ionodes() - This routine initializes the HUB data strcuture for 
  *	each node in the system.
  */
@@ -213,6 +203,7 @@ static void sn_fixup_ionodes(void)
 				continue;
 			}
 
+			spin_lock_init(&sn_flush_device_list->sfdl_flush_lock);
 			hubdev->hdi_flush_nasid_list.widget_p[widget] =
 			    sn_flush_device_list;
 		}
@@ -221,22 +212,34 @@ static void sn_fixup_ionodes(void)
 
 }
 
+void sn_pci_unfixup_slot(struct pci_dev *dev)
+{
+	struct pci_dev *host_pci_dev = SN_PCIDEV_INFO(dev)->host_pci_dev;
+
+	sn_irq_unfixup(dev);
+	pci_dev_put(host_pci_dev);
+	pci_dev_put(dev);
+}
+
 /*
  * sn_pci_fixup_slot() - This routine sets up a slot's resources
  * consistent with the Linux PCI abstraction layer.  Resources acquired
  * from our PCI provider include PIO maps to BAR space and interrupt
  * objects.
  */
-static void sn_pci_fixup_slot(struct pci_dev *dev)
+void sn_pci_fixup_slot(struct pci_dev *dev)
 {
 	int idx;
 	int segment = 0;
-	uint64_t size;
-	struct sn_irq_info *sn_irq_info;
-	struct pci_dev *host_pci_dev;
 	int status = 0;
 	struct pcibus_bussoft *bs;
+ 	struct pci_bus *host_pci_bus;
+ 	struct pci_dev *host_pci_dev;
+ 	struct sn_irq_info *sn_irq_info;
+ 	unsigned long size;
+ 	unsigned int bus_no, devfn;
 
+	pci_dev_get(dev); /* for the sysdata pointer */
 	dev->sysdata = kmalloc(sizeof(struct pcidev_info), GFP_KERNEL);
 	if (SN_PCIDEV_INFO(dev) <= 0)
 		BUG();		/* Cannot afford to run out of memory */
@@ -253,7 +256,7 @@ static void sn_pci_fixup_slot(struct pci
 				     (u64) __pa(SN_PCIDEV_INFO(dev)),
 				     (u64) __pa(sn_irq_info));
 	if (status)
-		BUG();		/* Cannot get platform pci device information information */
+		BUG(); /* Cannot get platform pci device information */
 
 	/* Copy over PIO Mapped Addresses */
 	for (idx = 0; idx <= PCI_ROM_RESOURCE; idx++) {
@@ -275,15 +278,21 @@ static void sn_pci_fixup_slot(struct pci
 			dev->resource[idx].parent = &iomem_resource;
 	}
 
-	/* set up host bus linkages */
-	bs = SN_PCIBUS_BUSSOFT(dev->bus);
-	host_pci_dev =
-	    pci_find_slot(SN_PCIDEV_INFO(dev)->pdi_slot_host_handle >> 32,
-			  SN_PCIDEV_INFO(dev)->
-			  pdi_slot_host_handle & 0xffffffff);
+	/*
+	 * Using the PROMs values for the PCI host bus, get the Linux
+ 	 * PCI host_pci_dev struct and set up host bus linkages
+ 	 */
+
+ 	bus_no = SN_PCIDEV_INFO(dev)->pdi_slot_host_handle >> 32;
+ 	devfn = SN_PCIDEV_INFO(dev)->pdi_slot_host_handle & 0xffffffff;
+ 	host_pci_bus = pci_find_bus(pci_domain_nr(dev->bus), bus_no);
+ 	host_pci_dev = pci_get_slot(host_pci_bus, devfn);
+
+	SN_PCIDEV_INFO(dev)->host_pci_dev = host_pci_dev;
 	SN_PCIDEV_INFO(dev)->pdi_host_pcidev_info =
-	    SN_PCIDEV_INFO(host_pci_dev);
+	    					SN_PCIDEV_INFO(host_pci_dev);
 	SN_PCIDEV_INFO(dev)->pdi_linux_pcidev = dev;
+	bs = SN_PCIBUS_BUSSOFT(dev->bus);
 	SN_PCIDEV_INFO(dev)->pdi_pcibus_info = bs;
 
 	if (bs && bs->bs_asic_type < PCIIO_ASIC_MAX_TYPES) {
@@ -297,6 +306,9 @@ static void sn_pci_fixup_slot(struct pci
 		SN_PCIDEV_INFO(dev)->pdi_sn_irq_info = sn_irq_info;
 		dev->irq = SN_PCIDEV_INFO(dev)->pdi_sn_irq_info->irq_irq;
 		sn_irq_fixup(dev, sn_irq_info);
+	} else {
+		SN_PCIDEV_INFO(dev)->pdi_sn_irq_info = NULL;
+		kfree(sn_irq_info);
 	}
 }
 
@@ -304,54 +316,59 @@ static void sn_pci_fixup_slot(struct pci
  * sn_pci_controller_fixup() - This routine sets up a bus's resources
  * consistent with the Linux PCI abstraction layer.
  */
-static void sn_pci_controller_fixup(int segment, int busnum)
+void sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus)
 {
 	int status = 0;
 	int nasid, cnode;
-	struct pci_bus *bus;
 	struct pci_controller *controller;
 	struct pcibus_bussoft *prom_bussoft_ptr;
 	struct hubdev_info *hubdev_info;
-	void *provider_soft;
+	void *provider_soft = NULL;
 	struct sn_pcibus_provider *provider;
 
-	status =
-	    sal_get_pcibus_info((u64) segment, (u64) busnum,
-				(u64) ia64_tpa(&prom_bussoft_ptr));
-	if (status > 0) {
-		return;		/* bus # does not exist */
-	}
-
+ 	status = sal_get_pcibus_info((u64) segment, (u64) busnum,
+ 				     (u64) ia64_tpa(&prom_bussoft_ptr));
+ 	if (status > 0)
+		return;		/*bus # does not exist */
 	prom_bussoft_ptr = __va(prom_bussoft_ptr);
-	controller = sn_alloc_pci_sysdata();
-	/* controller non-zero is BUG'd in sn_alloc_pci_sysdata */
 
-	bus = pci_scan_bus(busnum, &pci_root_ops, controller);
+ 	controller = kcalloc(1,sizeof(struct pci_controller), GFP_KERNEL);
+ 	if (!controller)
+ 		BUG();
+
 	if (bus == NULL) {
-		return;		/* error, or bus already scanned */
+ 		bus = pci_scan_bus(busnum, &pci_root_ops, controller);
+ 		if (bus == NULL)
+ 			goto error_return; /* error, or bus already scanned */
+ 		bus->sysdata = NULL;
 	}
 
+	if (bus->sysdata)
+		goto error_return; /* sysdata already alloc'd */
+
 	/*
 	 * Per-provider fixup.  Copies the contents from prom to local
 	 * area and links SN_PCIBUS_BUSSOFT().
 	 */
 
-	if (prom_bussoft_ptr->bs_asic_type >= PCIIO_ASIC_MAX_TYPES) {
-		return;		/* unsupported asic type */
-	}
+	if (prom_bussoft_ptr->bs_asic_type >= PCIIO_ASIC_MAX_TYPES)
+		goto error_return; /* unsupported asic type */
+
+	if (prom_bussoft_ptr->bs_asic_type == PCIIO_ASIC_TYPE_PPB)
+		goto error_return; /* no further fixup necessary */
 
 	provider = sn_pci_provider[prom_bussoft_ptr->bs_asic_type];
-	if (provider == NULL) {
-		return;		/* no provider registerd for this asic */
-	}
+	if (provider == NULL)
+		goto error_return; /* no provider registerd for this asic */
 
-	provider_soft = NULL;
-	if (provider->bus_fixup) {
-		provider_soft = (*provider->bus_fixup) (prom_bussoft_ptr);
-	}
+	bus->sysdata = controller;
+	if (provider->bus_fixup)
+		provider_soft = (*provider->bus_fixup) (prom_bussoft_ptr, controller);
 
 	if (provider_soft == NULL) {
-		return;		/* fixup failed or not applicable */
+		/* fixup failed or not applicable */
+		bus->sysdata = NULL;
+		goto error_return;
 	}
 
 	/*
@@ -359,14 +376,64 @@ static void sn_pci_controller_fixup(int 
 	 * after this point.
 	 */
 
-	bus->sysdata = controller;
 	PCI_CONTROLLER(bus)->platform_data = provider_soft;
-
 	nasid = NASID_GET(SN_PCIBUS_BUSSOFT(bus)->bs_base);
 	cnode = nasid_to_cnodeid(nasid);
 	hubdev_info = (struct hubdev_info *)(NODEPDA(cnode)->pdinfo);
 	SN_PCIBUS_BUSSOFT(bus)->bs_xwidget_info =
 	    &(hubdev_info->hdi_xwidget_info[SN_PCIBUS_BUSSOFT(bus)->bs_xid]);
+
+	/*
+	 * If the node information we obtained during the fixup phase is invalid
+	 * then set controller->node to -1 (undetermined)
+	 */
+	if (controller->node >= num_online_nodes()) {
+		struct pcibus_bussoft *b = SN_PCIBUS_BUSSOFT(bus);
+
+		printk(KERN_WARNING "Device ASIC=%u XID=%u PBUSNUM=%lu"
+				    "L_IO=%lx L_MEM=%lx BASE=%lx\n",
+			b->bs_asic_type, b->bs_xid, b->bs_persist_busnum,
+			b->bs_legacy_io, b->bs_legacy_mem, b->bs_base);
+		printk(KERN_WARNING "on node %d but only %d nodes online."
+			"Association set to undetermined.\n",
+			controller->node, num_online_nodes());
+		controller->node = -1;
+	}
+	return;
+
+error_return:
+
+	kfree(controller);
+	return;
+}
+
+void sn_bus_store_sysdata(struct pci_dev *dev)
+{
+	struct sysdata_el *element;
+
+	element = kcalloc(1, sizeof(struct sysdata_el), GFP_KERNEL);
+	if (!element) {
+		dev_dbg(dev, "%s: out of memory!\n", __FUNCTION__);
+		return;
+	}
+	element->sysdata = dev->sysdata;
+	list_add(&element->entry, &sn_sysdata_list);
+}
+
+void sn_bus_free_sysdata(void)
+{
+	struct sysdata_el *element;
+	struct list_head *list;
+
+sn_sysdata_free_start:
+	list_for_each(list, &sn_sysdata_list) {
+		element = list_entry(list, struct sysdata_el, entry);
+		list_del(&element->entry);
+		kfree(element->sysdata);
+		kfree(element);
+		goto sn_sysdata_free_start;
+	}
+	return;
 }
 
 /*
@@ -384,7 +451,7 @@ static int __init sn_pci_init(void)
 	extern void register_sn_procfs(void);
 #endif
 
-	if (!ia64_platform_is("sn2") || IS_RUNNING_ON_SIMULATOR())
+	if (!ia64_platform_is("sn2") || IS_RUNNING_ON_FAKE_PROM())
 		return 0;
 
 	/*
@@ -403,20 +470,17 @@ static int __init sn_pci_init(void)
 	 */
 	ia64_max_iommu_merge_mask = ~PAGE_MASK;
 	sn_fixup_ionodes();
-	sn_irq = kmalloc(sizeof(struct sn_irq_info *) * NR_IRQS, GFP_KERNEL);
-	if (sn_irq <= 0)
-		BUG();		/* Canno afford to run out of memory. */
-	memset(sn_irq, 0, sizeof(struct sn_irq_info *) * NR_IRQS);
-
+	sn_irq_lh_init();
+	INIT_LIST_HEAD(&sn_sysdata_list);
 	sn_init_cpei_timer();
 
 #ifdef CONFIG_PROC_FS
 	register_sn_procfs();
 #endif
 
-	for (i = 0; i < PCI_BUSES_TO_SCAN; i++) {
-		sn_pci_controller_fixup(0, i);
-	}
+	/* busses are not known yet ... */
+	for (i = 0; i < PCI_BUSES_TO_SCAN; i++)
+		sn_pci_controller_fixup(0, i, NULL);
 
 	/*
 	 * Generic Linux PCI Layer has created the pci_bus and pci_dev 
@@ -425,9 +489,8 @@ static int __init sn_pci_init(void)
 	 */
 
 	while ((pci_dev =
-		pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pci_dev)) != NULL) {
+		pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pci_dev)) != NULL)
 		sn_pci_fixup_slot(pci_dev);
-	}
 
 	sn_ioif_inited = 1;	/* sn I/O infrastructure now initialized */
 
@@ -469,3 +532,8 @@ cnodeid_get_geoid(cnodeid_t cnode)
 }
 
 subsys_initcall(sn_pci_init);
+EXPORT_SYMBOL(sn_pci_fixup_slot);
+EXPORT_SYMBOL(sn_pci_unfixup_slot);
+EXPORT_SYMBOL(sn_pci_controller_fixup);
+EXPORT_SYMBOL(sn_bus_store_sysdata);
+EXPORT_SYMBOL(sn_bus_free_sysdata);
diff --git a/arch/ia64/sn/kernel/iomv.c b/arch/ia64/sn/kernel/iomv.c
--- a/arch/ia64/sn/kernel/iomv.c
+++ b/arch/ia64/sn/kernel/iomv.c
@@ -9,12 +9,16 @@
 #include <linux/module.h>
 #include <asm/io.h>
 #include <asm/delay.h>
+#include <asm/vga.h>
 #include <asm/sn/nodepda.h>
 #include <asm/sn/simulator.h>
 #include <asm/sn/pda.h>
 #include <asm/sn/sn_cpuid.h>
 #include <asm/sn/shub_mmr.h>
 
+#define IS_LEGACY_VGA_IOPORT(p) \
+	(((p) >= 0x3b0 && (p) <= 0x3bb) || ((p) >= 0x3c0 && (p) <= 0x3df))
+
 /**
  * sn_io_addr - convert an in/out port to an i/o address
  * @port: port to convert
@@ -26,6 +30,8 @@
 void *sn_io_addr(unsigned long port)
 {
 	if (!IS_RUNNING_ON_SIMULATOR()) {
+		if (IS_LEGACY_VGA_IOPORT(port))
+			port += vga_console_iobase;
 		/* On sn2, legacy I/O ports don't point at anything */
 		if (port < (64 * 1024))
 			return NULL;
diff --git a/arch/ia64/sn/kernel/irq.c b/arch/ia64/sn/kernel/irq.c
--- a/arch/ia64/sn/kernel/irq.c
+++ b/arch/ia64/sn/kernel/irq.c
@@ -9,13 +9,13 @@
  */
 
 #include <linux/irq.h>
-#include <asm/sn/intr.h>
+#include <linux/spinlock.h>
 #include <asm/sn/addrs.h>
 #include <asm/sn/arch.h>
-#include "xtalk/xwidgetdev.h"
+#include <asm/sn/intr.h>
+#include <asm/sn/pcibr_provider.h>
 #include <asm/sn/pcibus_provider_defs.h>
 #include <asm/sn/pcidev.h>
-#include "pci/pcibr_provider.h"
 #include <asm/sn/shub_mmr.h>
 #include <asm/sn/sn_sal.h>
 
@@ -25,7 +25,8 @@ static void unregister_intr_pda(struct s
 
 extern int sn_force_interrupt_flag;
 extern int sn_ioif_inited;
-struct sn_irq_info **sn_irq;
+static struct list_head **sn_irq_lh;
+static spinlock_t sn_irq_info_lock = SPIN_LOCK_UNLOCKED; /* non-IRQ lock */
 
 static inline uint64_t sn_intr_alloc(nasid_t local_nasid, int local_widget,
 				     u64 sn_irq_info,
@@ -101,7 +102,7 @@ static void sn_end_irq(unsigned int irq)
 		nasid = get_nasid();
 		event_occurred = HUB_L((uint64_t *) GLOBAL_MMR_ADDR
 				       (nasid, SH_EVENT_OCCURRED));
-		/* If the UART bit is set here, we may have received an 
+		/* If the UART bit is set here, we may have received an
 		 * interrupt from the UART that the driver missed.  To
 		 * make sure, we IPI ourselves to force us to look again.
 		 */
@@ -115,82 +116,84 @@ static void sn_end_irq(unsigned int irq)
 		force_interrupt(irq);
 }
 
+static void sn_irq_info_free(struct rcu_head *head);
+
 static void sn_set_affinity_irq(unsigned int irq, cpumask_t mask)
 {
-	struct sn_irq_info *sn_irq_info = sn_irq[irq];
-	struct sn_irq_info *tmp_sn_irq_info;
+	struct sn_irq_info *sn_irq_info, *sn_irq_info_safe;
 	int cpuid, cpuphys;
-	nasid_t t_nasid;	/* nasid to target */
-	int t_slice;		/* slice to target */
-
-	/* allocate a temp sn_irq_info struct to get new target info */
-	tmp_sn_irq_info = kmalloc(sizeof(*tmp_sn_irq_info), GFP_KERNEL);
-	if (!tmp_sn_irq_info)
-		return;
 
 	cpuid = first_cpu(mask);
 	cpuphys = cpu_physical_id(cpuid);
-	t_nasid = cpuid_to_nasid(cpuid);
-	t_slice = cpuid_to_slice(cpuid);
 
-	while (sn_irq_info) {
-		int status;
-		int local_widget;
-		uint64_t bridge = (uint64_t) sn_irq_info->irq_bridge;
-		nasid_t local_nasid = NASID_GET(bridge);
+	list_for_each_entry_safe(sn_irq_info, sn_irq_info_safe,
+				 sn_irq_lh[irq], list) {
+		uint64_t bridge;
+		int local_widget, status;
+		nasid_t local_nasid;
+		struct sn_irq_info *new_irq_info;
+
+		new_irq_info = kmalloc(sizeof(struct sn_irq_info), GFP_ATOMIC);
+		if (new_irq_info == NULL)
+			break;
+		memcpy(new_irq_info, sn_irq_info, sizeof(struct sn_irq_info));
+
+		bridge = (uint64_t) new_irq_info->irq_bridge;
+		if (!bridge) {
+			kfree(new_irq_info);
+			break; /* irq is not a device interrupt */
+		}
 
-		if (!bridge)
-			break;	/* irq is not a device interrupt */
+		local_nasid = NASID_GET(bridge);
 
 		if (local_nasid & 1)
 			local_widget = TIO_SWIN_WIDGETNUM(bridge);
 		else
 			local_widget = SWIN_WIDGETNUM(bridge);
 
-		/* Free the old PROM sn_irq_info structure */
-		sn_intr_free(local_nasid, local_widget, sn_irq_info);
+		/* Free the old PROM new_irq_info structure */
+		sn_intr_free(local_nasid, local_widget, new_irq_info);
+		/* Update kernels new_irq_info with new target info */
+		unregister_intr_pda(new_irq_info);
 
-		/* allocate a new PROM sn_irq_info struct */
+		/* allocate a new PROM new_irq_info struct */
 		status = sn_intr_alloc(local_nasid, local_widget,
-				       __pa(tmp_sn_irq_info), irq, t_nasid,
-				       t_slice);
+				       __pa(new_irq_info), irq,
+				       cpuid_to_nasid(cpuid),
+				       cpuid_to_slice(cpuid));
+
+		/* SAL call failed */
+		if (status) {
+			kfree(new_irq_info);
+			break;
+		}
 
-		if (status == 0) {
-			/* Update kernels sn_irq_info with new target info */
-			unregister_intr_pda(sn_irq_info);
-			sn_irq_info->irq_cpuid = cpuid;
-			sn_irq_info->irq_nasid = t_nasid;
-			sn_irq_info->irq_slice = t_slice;
-			sn_irq_info->irq_xtalkaddr =
-			    tmp_sn_irq_info->irq_xtalkaddr;
-			sn_irq_info->irq_cookie = tmp_sn_irq_info->irq_cookie;
-			register_intr_pda(sn_irq_info);
+		new_irq_info->irq_cpuid = cpuid;
+		register_intr_pda(new_irq_info);
 
-			if (IS_PCI_BRIDGE_ASIC(sn_irq_info->irq_bridge_type)) {
-				pcibr_change_devices_irq(sn_irq_info);
-			}
+		if (IS_PCI_BRIDGE_ASIC(new_irq_info->irq_bridge_type))
+			pcibr_change_devices_irq(new_irq_info);
 
-			sn_irq_info = sn_irq_info->irq_next;
+		spin_lock(&sn_irq_info_lock);
+		list_replace_rcu(&sn_irq_info->list, &new_irq_info->list);
+		spin_unlock(&sn_irq_info_lock);
+		call_rcu(&sn_irq_info->rcu, sn_irq_info_free);
 
 #ifdef CONFIG_SMP
-			set_irq_affinity_info((irq & 0xff), cpuphys, 0);
+		set_irq_affinity_info((irq & 0xff), cpuphys, 0);
 #endif
-		} else {
-			break;	/* snp_affinity failed the intr_alloc */
-		}
 	}
-	kfree(tmp_sn_irq_info);
 }
 
 struct hw_interrupt_type irq_type_sn = {
-	"SN hub",
-	sn_startup_irq,
-	sn_shutdown_irq,
-	sn_enable_irq,
-	sn_disable_irq,
-	sn_ack_irq,
-	sn_end_irq,
-	sn_set_affinity_irq
+	.typename	= "SN hub",
+	.startup	= sn_startup_irq,
+	.shutdown	= sn_shutdown_irq,
+	.enable		= sn_enable_irq,
+	.disable	= sn_disable_irq,
+	.ack		= sn_ack_irq,
+	.end		= sn_end_irq,
+	.set_affinity	= sn_set_affinity_irq
 };
 
 unsigned int sn_local_vector_to_irq(u8 vector)
@@ -231,19 +234,18 @@ static void unregister_intr_pda(struct s
 	struct sn_irq_info *tmp_irq_info;
 	int i, foundmatch;
 
+	rcu_read_lock();
 	if (pdacpu(cpu)->sn_last_irq == irq) {
 		foundmatch = 0;
-		for (i = pdacpu(cpu)->sn_last_irq - 1; i; i--) {
-			tmp_irq_info = sn_irq[i];
-			while (tmp_irq_info) {
+		for (i = pdacpu(cpu)->sn_last_irq - 1;
+		     i && !foundmatch; i--) {
+			list_for_each_entry_rcu(tmp_irq_info,
+						sn_irq_lh[i],
+						list) {
 				if (tmp_irq_info->irq_cpuid == cpu) {
-					foundmatch++;
+					foundmatch = 1;
 					break;
 				}
-				tmp_irq_info = tmp_irq_info->irq_next;
-			}
-			if (foundmatch) {
-				break;
 			}
 		}
 		pdacpu(cpu)->sn_last_irq = i;
@@ -251,60 +253,27 @@ static void unregister_intr_pda(struct s
 
 	if (pdacpu(cpu)->sn_first_irq == irq) {
 		foundmatch = 0;
-		for (i = pdacpu(cpu)->sn_first_irq + 1; i < NR_IRQS; i++) {
-			tmp_irq_info = sn_irq[i];
-			while (tmp_irq_info) {
+		for (i = pdacpu(cpu)->sn_first_irq + 1;
+		     i < NR_IRQS && !foundmatch; i++) {
+			list_for_each_entry_rcu(tmp_irq_info,
+						sn_irq_lh[i],
+						list) {
 				if (tmp_irq_info->irq_cpuid == cpu) {
-					foundmatch++;
+					foundmatch = 1;
 					break;
 				}
-				tmp_irq_info = tmp_irq_info->irq_next;
-			}
-			if (foundmatch) {
-				break;
 			}
 		}
 		pdacpu(cpu)->sn_first_irq = ((i == NR_IRQS) ? 0 : i);
 	}
+	rcu_read_unlock();
 }
 
-struct sn_irq_info *sn_irq_alloc(nasid_t local_nasid, int local_widget, int irq,
-				 nasid_t nasid, int slice)
+static void sn_irq_info_free(struct rcu_head *head)
 {
 	struct sn_irq_info *sn_irq_info;
-	int status;
-
-	sn_irq_info = kmalloc(sizeof(*sn_irq_info), GFP_KERNEL);
-	if (sn_irq_info == NULL)
-		return NULL;
-
-	memset(sn_irq_info, 0x0, sizeof(*sn_irq_info));
-
-	status =
-	    sn_intr_alloc(local_nasid, local_widget, __pa(sn_irq_info), irq,
-			  nasid, slice);
-
-	if (status) {
-		kfree(sn_irq_info);
-		return NULL;
-	} else {
-		return sn_irq_info;
-	}
-}
-
-void sn_irq_free(struct sn_irq_info *sn_irq_info)
-{
-	uint64_t bridge = (uint64_t) sn_irq_info->irq_bridge;
-	nasid_t local_nasid = NASID_GET(bridge);
-	int local_widget;
-
-	if (local_nasid & 1)	/* tio check */
-		local_widget = TIO_SWIN_WIDGETNUM(bridge);
-	else
-		local_widget = SWIN_WIDGETNUM(bridge);
-
-	sn_intr_free(local_nasid, local_widget, sn_irq_info);
 
+	sn_irq_info = container_of(head, struct sn_irq_info, rcu);
 	kfree(sn_irq_info);
 }
 
@@ -314,30 +283,54 @@ void sn_irq_fixup(struct pci_dev *pci_de
 	int slice = sn_irq_info->irq_slice;
 	int cpu = nasid_slice_to_cpuid(nasid, slice);
 
+	pci_dev_get(pci_dev);
 	sn_irq_info->irq_cpuid = cpu;
 	sn_irq_info->irq_pciioinfo = SN_PCIDEV_INFO(pci_dev);
 
 	/* link it into the sn_irq[irq] list */
-	sn_irq_info->irq_next = sn_irq[sn_irq_info->irq_irq];
-	sn_irq[sn_irq_info->irq_irq] = sn_irq_info;
+	spin_lock(&sn_irq_info_lock);
+	list_add_rcu(&sn_irq_info->list, sn_irq_lh[sn_irq_info->irq_irq]);
+	spin_unlock(&sn_irq_info_lock);
 
 	(void)register_intr_pda(sn_irq_info);
 }
 
+void sn_irq_unfixup(struct pci_dev *pci_dev)
+{
+	struct sn_irq_info *sn_irq_info;
+
+	/* Only cleanup IRQ stuff if this device has a host bus context */
+	if (!SN_PCIDEV_BUSSOFT(pci_dev))
+		return;
+
+	sn_irq_info = SN_PCIDEV_INFO(pci_dev)->pdi_sn_irq_info;
+	if (!sn_irq_info || !sn_irq_info->irq_irq) {
+		kfree(sn_irq_info);
+		return;
+	}
+
+	unregister_intr_pda(sn_irq_info);
+	spin_lock(&sn_irq_info_lock);
+	list_del_rcu(&sn_irq_info->list);
+	spin_unlock(&sn_irq_info_lock);
+	call_rcu(&sn_irq_info->rcu, sn_irq_info_free);
+	pci_dev_put(pci_dev);
+}
+
 static void force_interrupt(int irq)
 {
 	struct sn_irq_info *sn_irq_info;
 
 	if (!sn_ioif_inited)
 		return;
-	sn_irq_info = sn_irq[irq];
-	while (sn_irq_info) {
+
+	rcu_read_lock();
+	list_for_each_entry_rcu(sn_irq_info, sn_irq_lh[irq], list) {
 		if (IS_PCI_BRIDGE_ASIC(sn_irq_info->irq_bridge_type) &&
-		    (sn_irq_info->irq_bridge != NULL)) {
+		    (sn_irq_info->irq_bridge != NULL))
 			pcibr_force_interrupt(sn_irq_info);
-		}
-		sn_irq_info = sn_irq_info->irq_next;
 	}
+	rcu_read_unlock();
 }
 
 /*
@@ -402,19 +395,41 @@ static void sn_check_intr(int irq, struc
 
 void sn_lb_int_war_check(void)
 {
+	struct sn_irq_info *sn_irq_info;
 	int i;
 
 	if (!sn_ioif_inited || pda->sn_first_irq == 0)
 		return;
+
+	rcu_read_lock();
 	for (i = pda->sn_first_irq; i <= pda->sn_last_irq; i++) {
-		struct sn_irq_info *sn_irq_info = sn_irq[i];
-		while (sn_irq_info) {
-			/* Only call for PCI bridges that are fully initialized. */
+		list_for_each_entry_rcu(sn_irq_info, sn_irq_lh[i], list) {
+			/*
+			 * Only call for PCI bridges that are fully
+			 * initialized.
+			 */
 			if (IS_PCI_BRIDGE_ASIC(sn_irq_info->irq_bridge_type) &&
-			    (sn_irq_info->irq_bridge != NULL)) {
+			    (sn_irq_info->irq_bridge != NULL))
 				sn_check_intr(i, sn_irq_info);
-			}
-			sn_irq_info = sn_irq_info->irq_next;
 		}
 	}
+	rcu_read_unlock();
+}
+
+void sn_irq_lh_init(void)
+{
+	int i;
+
+	sn_irq_lh = kmalloc(sizeof(struct list_head *) * NR_IRQS, GFP_KERNEL);
+	if (!sn_irq_lh)
+		panic("SN PCI INIT: Failed to allocate memory for PCI init\n");
+
+	for (i = 0; i < NR_IRQS; i++) {
+		sn_irq_lh[i] = kmalloc(sizeof(struct list_head), GFP_KERNEL);
+		if (!sn_irq_lh[i])
+			panic("SN PCI INIT: Failed IRQ memory allocation\n");
+
+		INIT_LIST_HEAD(sn_irq_lh[i]);
+	}
+
 }
diff --git a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c
--- a/arch/ia64/sn/kernel/setup.c
+++ b/arch/ia64/sn/kernel/setup.c
@@ -36,6 +36,7 @@
 #include <asm/machvec.h>
 #include <asm/system.h>
 #include <asm/processor.h>
+#include <asm/vga.h>
 #include <asm/sn/arch.h>
 #include <asm/sn/addrs.h>
 #include <asm/sn/pda.h>
@@ -95,6 +96,7 @@ u8 sn_coherency_id;
 EXPORT_SYMBOL(sn_coherency_id);
 u8 sn_region_size;
 EXPORT_SYMBOL(sn_region_size);
+int sn_prom_type;	/* 0=hardware, 1=medusa/realprom, 2=medusa/fakeprom */
 
 short physical_node_map[MAX_PHYSNODE_ID];
 
@@ -268,19 +270,22 @@ void __init sn_setup(char **cmdline_p)
 {
 	long status, ticks_per_sec, drift;
 	int pxm;
-	int major = sn_sal_rev_major(), minor = sn_sal_rev_minor();
+	u32 version = sn_sal_rev();
 	extern void sn_cpu_init(void);
 
 	ia64_sn_plat_set_error_handling_features();
 
+#if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE)
 	/*
-	 * If the generic code has enabled vga console support - lets
-	 * get rid of it again. This is a kludge for the fact that ACPI
-	 * currtently has no way of informing us if legacy VGA is available
-	 * or not.
+	 * If there was a primary vga adapter identified through the
+	 * EFI PCDP table, make it the preferred console.  Otherwise
+	 * zero out conswitchp.
 	 */
-#if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE)
-	if (conswitchp == &vga_con) {
+
+	if (vga_console_membase) {
+		/* usable vga ... make tty0 the preferred default console */
+		add_preferred_console("tty", 0, NULL);
+	} else {
 		printk(KERN_DEBUG "SGI: Disabling VGA console\n");
 #ifdef CONFIG_DUMMY_CONSOLE
 		conswitchp = &dummy_con;
@@ -303,22 +308,21 @@ void __init sn_setup(char **cmdline_p)
 	 * support here so we don't have to listen to failed keyboard probe
 	 * messages.
 	 */
-	if ((major < 2 || (major == 2 && minor <= 9)) &&
-	    acpi_kbd_controller_present) {
+	if (version <= 0x0209 && acpi_kbd_controller_present) {
 		printk(KERN_INFO "Disabling legacy keyboard support as prom "
 		       "is too old and doesn't provide FADT\n");
 		acpi_kbd_controller_present = 0;
 	}
 
-	printk("SGI SAL version %x.%02x\n", major, minor);
+	printk("SGI SAL version %x.%02x\n", version >> 8, version & 0x00FF);
 
 	/*
 	 * Confirm the SAL we're running on is recent enough...
 	 */
-	if ((major < SN_SAL_MIN_MAJOR) || (major == SN_SAL_MIN_MAJOR &&
-					   minor < SN_SAL_MIN_MINOR)) {
+	if (version < SN_SAL_MIN_VERSION) {
 		printk(KERN_ERR "This kernel needs SGI SAL version >= "
-		       "%x.%02x\n", SN_SAL_MIN_MAJOR, SN_SAL_MIN_MINOR);
+		       "%x.%02x\n", SN_SAL_MIN_VERSION >> 8,
+		        SN_SAL_MIN_VERSION & 0x00FF);
 		panic("PROM version too old\n");
 	}
 
@@ -350,7 +354,7 @@ void __init sn_setup(char **cmdline_p)
 
 	ia64_mark_idle = &snidle;
 
-	/* 
+	/*
 	 * For the bootcpu, we do this here. All other cpus will make the
 	 * call as part of cpu_init in slave cpu initialization.
 	 */
@@ -397,7 +401,7 @@ static void __init sn_init_pdas(char **c
 		nodepdaindr[cnode] =
 		    alloc_bootmem_node(NODE_DATA(cnode), sizeof(nodepda_t));
 		memset(nodepdaindr[cnode], 0, sizeof(nodepda_t));
-		memset(nodepdaindr[cnode]->phys_cpuid, -1, 
+		memset(nodepdaindr[cnode]->phys_cpuid, -1,
 		    sizeof(nodepdaindr[cnode]->phys_cpuid));
 	}
 
@@ -427,7 +431,7 @@ static void __init sn_init_pdas(char **c
 	}
 
 	/*
-	 * Initialize the per node hubdev.  This includes IO Nodes and 
+	 * Initialize the per node hubdev.  This includes IO Nodes and
 	 * headless/memless nodes.
 	 */
 	for (cnode = 0; cnode < numionodes; cnode++) {
@@ -455,6 +459,14 @@ void __init sn_cpu_init(void)
 	int i;
 	static int wars_have_been_checked;
 
+	if (smp_processor_id() == 0 && IS_MEDUSA()) {
+		if (ia64_sn_is_fake_prom())
+			sn_prom_type = 2;
+		else
+			sn_prom_type = 1;
+		printk("Running on medusa with %s PROM\n", (sn_prom_type == 1) ? "real" : "fake");
+	}
+
 	memset(pda, 0, sizeof(pda));
 	if (ia64_sn_get_sn_info(0, &sn_hub_info->shub2, &sn_hub_info->nasid_bitmask, &sn_hub_info->nasid_shift,
 				&sn_system_size, &sn_sharing_domain_size, &sn_partition_id,
@@ -520,7 +532,7 @@ void __init sn_cpu_init(void)
 	 */
 	{
 		u64 pio1[] = {SH1_PIO_WRITE_STATUS_0, 0, SH1_PIO_WRITE_STATUS_1, 0};
-		u64 pio2[] = {SH2_PIO_WRITE_STATUS_0, SH2_PIO_WRITE_STATUS_1, 
+		u64 pio2[] = {SH2_PIO_WRITE_STATUS_0, SH2_PIO_WRITE_STATUS_1,
 			SH2_PIO_WRITE_STATUS_2, SH2_PIO_WRITE_STATUS_3};
 		u64 *pio;
 		pio = is_shub1() ? pio1 : pio2;
@@ -552,6 +564,10 @@ static void __init scan_for_ionodes(void
 	int nasid = 0;
 	lboard_t *brd;
 
+	/* fakeprom does not support klgraph */
+	if (IS_RUNNING_ON_FAKE_PROM())
+		return;
+
 	/* Setup ionodes with memory */
 	for (nasid = 0; nasid < MAX_PHYSNODE_ID; nasid += 2) {
 		char *klgraph_header;
@@ -563,8 +579,6 @@ static void __init scan_for_ionodes(void
 		cnodeid = -1;
 		klgraph_header = __va(ia64_sn_get_klconfig_addr(nasid));
 		if (!klgraph_header) {
-			if (IS_RUNNING_ON_SIMULATOR())
-				continue;
 			BUG();	/* All nodes must have klconfig tables! */
 		}
 		cnodeid = nasid_to_cnodeid(nasid);
@@ -630,8 +644,8 @@ int
 nasid_slice_to_cpuid(int nasid, int slice)
 {
 	long cpu;
-	
-	for (cpu=0; cpu < NR_CPUS; cpu++) 
+
+	for (cpu=0; cpu < NR_CPUS; cpu++)
 		if (cpuid_to_nasid(cpu) == nasid &&
 					cpuid_to_slice(cpu) == slice)
 			return cpu;
diff --git a/arch/ia64/sn/kernel/sn2/ptc_deadlock.S b/arch/ia64/sn/kernel/sn2/ptc_deadlock.S
--- a/arch/ia64/sn/kernel/sn2/ptc_deadlock.S
+++ b/arch/ia64/sn/kernel/sn2/ptc_deadlock.S
@@ -6,6 +6,7 @@
  * Copyright (C) 2000-2004 Silicon Graphics, Inc. All rights reserved.
  */
 
+#include <asm/types.h>
 #include <asm/sn/shub_mmr.h>
 
 #define DEADLOCKBIT	SH_PIO_WRITE_STATUS_WRITE_DEADLOCK_SHFT
diff --git a/arch/ia64/sn/kernel/tiocx.c b/arch/ia64/sn/kernel/tiocx.c
--- a/arch/ia64/sn/kernel/tiocx.c
+++ b/arch/ia64/sn/kernel/tiocx.c
@@ -8,12 +8,12 @@
 
 #include <linux/module.h>
 #include <linux/kernel.h>
-#include <linux/version.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/proc_fs.h>
 #include <linux/device.h>
 #include <linux/delay.h>
+#include <asm/system.h>
 #include <asm/uaccess.h>
 #include <asm/sn/sn_sal.h>
 #include <asm/sn/addrs.h>
@@ -204,8 +204,8 @@ cx_device_register(nasid_t nasid, int pa
 	cx_dev->dev.parent = NULL;
 	cx_dev->dev.bus = &tiocx_bus_type;
 	cx_dev->dev.release = tiocx_bus_release;
-	snprintf(cx_dev->dev.bus_id, BUS_ID_SIZE, "%d.0x%x",
-		 cx_dev->cx_id.nasid, cx_dev->cx_id.part_num);
+	snprintf(cx_dev->dev.bus_id, BUS_ID_SIZE, "%d",
+		 cx_dev->cx_id.nasid);
 	device_register(&cx_dev->dev);
 	get_device(&cx_dev->dev);
 
@@ -236,7 +236,6 @@ int cx_device_unregister(struct cx_dev *
  */
 static int cx_device_reload(struct cx_dev *cx_dev)
 {
-	device_remove_file(&cx_dev->dev, &dev_attr_cxdev_control);
 	cx_device_unregister(cx_dev);
 	return cx_device_register(cx_dev->cx_id.nasid, cx_dev->cx_id.part_num,
 				  cx_dev->cx_id.mfg_num, cx_dev->hubdev);
@@ -383,6 +382,7 @@ static int is_fpga_brick(int nasid)
 	switch (tiocx_btchar_get(nasid)) {
 	case L1_BRICKTYPE_SA:
 	case L1_BRICKTYPE_ATHENA:
+	case L1_BRICKTYPE_DAYTONA:
 		return 1;
 	}
 	return 0;
@@ -409,7 +409,7 @@ static int tiocx_reload(struct cx_dev *c
 		uint64_t cx_id;
 
 		cx_id =
-		    *(volatile int32_t *)(TIO_SWIN_BASE(nasid, TIOCX_CORELET) +
+		    *(volatile uint64_t *)(TIO_SWIN_BASE(nasid, TIOCX_CORELET) +
 					  WIDGET_ID);
 		part_num = XWIDGET_PART_NUM(cx_id);
 		mfg_num = XWIDGET_MFG_NUM(cx_id);
@@ -432,7 +432,7 @@ static int tiocx_reload(struct cx_dev *c
 	return cx_device_reload(cx_dev);
 }
 
-static ssize_t show_cxdev_control(struct device *dev, char *buf)
+static ssize_t show_cxdev_control(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct cx_dev *cx_dev = to_cx_dev(dev);
 
@@ -442,7 +442,7 @@ static ssize_t show_cxdev_control(struct
 		       tiocx_btchar_get(cx_dev->cx_id.nasid));
 }
 
-static ssize_t store_cxdev_control(struct device *dev, const char *buf,
+static ssize_t store_cxdev_control(struct device *dev, struct device_attribute *attr, const char *buf,
 				   size_t count)
 {
 	int n;
@@ -458,6 +458,10 @@ static ssize_t store_cxdev_control(struc
 
 	switch (n) {
 	case 1:
+		tio_corelet_reset(cx_dev->cx_id.nasid, TIOCX_CORELET);
+		tiocx_reload(cx_dev);
+		break;
+	case 2:
 		tiocx_reload(cx_dev);
 		break;
 	case 3:
@@ -477,6 +481,9 @@ static int __init tiocx_init(void)
 	cnodeid_t cnodeid;
 	int found_tiocx_device = 0;
 
+	if (!ia64_platform_is("sn2"))
+		return -ENODEV;
+
 	bus_register(&tiocx_bus_type);
 
 	for (cnodeid = 0; cnodeid < MAX_COMPACT_NODES; cnodeid++) {
@@ -518,29 +525,26 @@ static int __init tiocx_init(void)
 	return 0;
 }
 
-static void __exit tiocx_exit(void)
+static int cx_remove_device(struct device * dev, void * data)
 {
-	struct device *dev;
-	struct device *tdev;
+	struct cx_dev *cx_dev = to_cx_dev(dev);
+	device_remove_file(dev, &dev_attr_cxdev_control);
+	cx_device_unregister(cx_dev);
+	return 0;
+}
 
+static void __exit tiocx_exit(void)
+{
 	DBG("tiocx_exit\n");
 
 	/*
 	 * Unregister devices.
 	 */
-	list_for_each_entry_safe(dev, tdev, &tiocx_bus_type.devices.list,
-				 bus_list) {
-		if (dev) {
-			struct cx_dev *cx_dev = to_cx_dev(dev);
-			device_remove_file(dev, &dev_attr_cxdev_control);
-			cx_device_unregister(cx_dev);
-		}
-	}
-
+	bus_for_each_dev(&tiocx_bus_type, NULL, NULL, cx_remove_device);
 	bus_unregister(&tiocx_bus_type);
 }
 
-module_init(tiocx_init);
+subsys_initcall(tiocx_init);
 module_exit(tiocx_exit);
 
 /************************************************************************
diff --git a/arch/ia64/sn/kernel/xpc.h b/arch/ia64/sn/kernel/xpc.h
--- a/arch/ia64/sn/kernel/xpc.h
+++ b/arch/ia64/sn/kernel/xpc.h
@@ -87,7 +87,7 @@ struct xpc_rsvd_page {
 	u8 partid;		/* partition ID from SAL */
 	u8 version;
 	u8 pad[6];		/* pad to u64 align */
-	u64 vars_pa;
+	volatile u64 vars_pa;
 	u64 part_nasids[XP_NASID_MASK_WORDS] ____cacheline_aligned;
 	u64 mach_nasids[XP_NASID_MASK_WORDS] ____cacheline_aligned;
 };
@@ -138,7 +138,7 @@ struct xpc_vars {
  * occupies half a cacheline.
  */
 struct xpc_vars_part {
-	u64 magic;
+	volatile u64 magic;
 
 	u64 openclose_args_pa;	/* physical address of open and close args */
 	u64 GPs_pa;		/* physical address of Get/Put values */
@@ -185,8 +185,8 @@ struct xpc_vars_part {
  * Define a Get/Put value pair (pointers) used with a message queue.
  */
 struct xpc_gp {
-	s64 get;	/* Get value */
-	s64 put;	/* Put value */
+	volatile s64 get;	/* Get value */
+	volatile s64 put;	/* Put value */
 };
 
 #define XPC_GP_SIZE \
@@ -231,7 +231,7 @@ struct xpc_openclose_args {
  */
 struct xpc_notify {
 	struct semaphore sema;		/* notify semaphore */
-	u8 type;			/* type of notification */
+	volatile u8 type;			/* type of notification */
 
 	/* the following two fields are only used if type == XPC_N_CALL */
 	xpc_notify_func func;		/* user's notify function */
@@ -439,7 +439,7 @@ struct xpc_partition {
 
 	/* XPC infrastructure referencing and teardown control */
 
-	u8 setup_state;			/* infrastructure setup state */
+	volatile u8 setup_state;			/* infrastructure setup state */
 	wait_queue_head_t teardown_wq;	/* kthread waiting to teardown infra */
 	atomic_t references;		/* #of references to infrastructure */
 
diff --git a/arch/ia64/sn/kernel/xpc_channel.c b/arch/ia64/sn/kernel/xpc_channel.c
--- a/arch/ia64/sn/kernel/xpc_channel.c
+++ b/arch/ia64/sn/kernel/xpc_channel.c
@@ -72,7 +72,7 @@ xpc_initialize_channels(struct xpc_parti
 enum xpc_retval
 xpc_setup_infrastructure(struct xpc_partition *part)
 {
-	int ret;
+	int ret, cpuid;
 	struct timer_list *timer;
 	partid_t partid = XPC_PARTID(part);
 
@@ -209,7 +209,7 @@ xpc_setup_infrastructure(struct xpc_part
 	 * With the setting of the partition setup_state to XPC_P_SETUP, we're
 	 * declaring that this partition is ready to go.
 	 */
-	(volatile u8) part->setup_state = XPC_P_SETUP;
+	part->setup_state = XPC_P_SETUP;
 
 
 	/*
@@ -223,11 +223,11 @@ xpc_setup_infrastructure(struct xpc_part
 	xpc_vars_part[partid].openclose_args_pa =
 					__pa(part->local_openclose_args);
 	xpc_vars_part[partid].IPI_amo_pa = __pa(part->local_IPI_amo_va);
-	xpc_vars_part[partid].IPI_nasid = cpuid_to_nasid(smp_processor_id());
-	xpc_vars_part[partid].IPI_phys_cpuid =
-					cpu_physical_id(smp_processor_id());
+	cpuid = raw_smp_processor_id();	/* any CPU in this partition will do */
+	xpc_vars_part[partid].IPI_nasid = cpuid_to_nasid(cpuid);
+	xpc_vars_part[partid].IPI_phys_cpuid = cpu_physical_id(cpuid);
 	xpc_vars_part[partid].nchannels = part->nchannels;
-	(volatile u64) xpc_vars_part[partid].magic = XPC_VP_MAGIC1;
+	xpc_vars_part[partid].magic = XPC_VP_MAGIC1;
 
 	return xpcSuccess;
 }
@@ -355,7 +355,7 @@ xpc_pull_remote_vars_part(struct xpc_par
 
 		/* let the other side know that we've pulled their variables */
 
-		(volatile u64) xpc_vars_part[partid].magic = XPC_VP_MAGIC2;
+		xpc_vars_part[partid].magic = XPC_VP_MAGIC2;
 	}
 
 	if (pulled_entry->magic == XPC_VP_MAGIC1) {
@@ -1183,7 +1183,7 @@ xpc_process_msg_IPI(struct xpc_partition
 		 */
 		xpc_clear_local_msgqueue_flags(ch);
 
-		(volatile s64) ch->w_remote_GP.get = ch->remote_GP.get;
+		ch->w_remote_GP.get = ch->remote_GP.get;
 
 		dev_dbg(xpc_chan, "w_remote_GP.get changed to %ld, partid=%d, "
 			"channel=%d\n", ch->w_remote_GP.get, ch->partid,
@@ -1211,7 +1211,7 @@ xpc_process_msg_IPI(struct xpc_partition
 		 */
 		xpc_clear_remote_msgqueue_flags(ch);
 
-		(volatile s64) ch->w_remote_GP.put = ch->remote_GP.put;
+		ch->w_remote_GP.put = ch->remote_GP.put;
 
 		dev_dbg(xpc_chan, "w_remote_GP.put changed to %ld, partid=%d, "
 			"channel=%d\n", ch->w_remote_GP.put, ch->partid,
@@ -1875,7 +1875,7 @@ xpc_send_msg(struct xpc_channel *ch, str
 		notify = &ch->notify_queue[msg_number % ch->local_nentries];
 		notify->func = func;
 		notify->key = key;
-		(volatile u8) notify->type = notify_type;
+		notify->type = notify_type;
 
 		// >>> is a mb() needed here?
 
diff --git a/arch/ia64/sn/kernel/xpc_main.c b/arch/ia64/sn/kernel/xpc_main.c
--- a/arch/ia64/sn/kernel/xpc_main.c
+++ b/arch/ia64/sn/kernel/xpc_main.c
@@ -53,6 +53,7 @@
 #include <linux/cache.h>
 #include <linux/interrupt.h>
 #include <linux/slab.h>
+#include <linux/delay.h>
 #include <asm/sn/intr.h>
 #include <asm/sn/sn_sal.h>
 #include <asm/uaccess.h>
@@ -308,8 +309,7 @@ xpc_make_first_contact(struct xpc_partit
 			"partition %d\n", XPC_PARTID(part));
 
 		/* wait a 1/4 of a second or so */
-		set_current_state(TASK_INTERRUPTIBLE);
-		(void) schedule_timeout(0.25 * HZ);
+		msleep_interruptible(250);
 
 		if (part->act_state == XPC_P_DEACTIVATING) {
 			return part->reason;
@@ -420,7 +420,7 @@ xpc_activating(void *__partid)
 	partid_t partid = (u64) __partid;
 	struct xpc_partition *part = &xpc_partitions[partid];
 	unsigned long irq_flags;
-	struct sched_param param = { sched_priority: MAX_USER_RT_PRIO - 1 };
+	struct sched_param param = { sched_priority: MAX_RT_PRIO - 1 };
 	int ret;
 
 
@@ -841,9 +841,7 @@ xpc_do_exit(void)
 	down(&xpc_discovery_exited);
 
 
-	set_current_state(TASK_INTERRUPTIBLE);
-	schedule_timeout(0.3 * HZ);
-	set_current_state(TASK_RUNNING);
+	msleep_interruptible(300);
 
 
 	/* wait for all partitions to become inactive */
@@ -860,12 +858,8 @@ xpc_do_exit(void)
 			}
 		}
 
-		if (active_part_count) {
-			set_current_state(TASK_INTERRUPTIBLE);
-			schedule_timeout(0.3 * HZ);
-			set_current_state(TASK_RUNNING);
-		}
-
+		if (active_part_count)
+			msleep_interruptible(300);
 	} while (active_part_count > 0);
 
 
diff --git a/arch/ia64/sn/kernel/xpc_partition.c b/arch/ia64/sn/kernel/xpc_partition.c
--- a/arch/ia64/sn/kernel/xpc_partition.c
+++ b/arch/ia64/sn/kernel/xpc_partition.c
@@ -22,6 +22,7 @@
 #include <linux/cache.h>
 #include <linux/mmzone.h>
 #include <linux/nodemask.h>
+#include <asm/uncached.h>
 #include <asm/sn/bte.h>
 #include <asm/sn/intr.h>
 #include <asm/sn/sn_sal.h>
@@ -183,7 +184,7 @@ xpc_rsvd_page_init(void)
 	 * memory protections are never restricted.
 	 */
 	if ((amos_page = xpc_vars->amos_page) == NULL) {
-		amos_page = (AMO_t *) mspec_kalloc_page(0);
+		amos_page = (AMO_t *) TO_AMO(uncached_alloc_page(0));
 		if (amos_page == NULL) {
 			dev_err(xpc_part, "can't allocate page of AMOs\n");
 			return NULL;
@@ -200,7 +201,8 @@ xpc_rsvd_page_init(void)
 			if (ret != 0) {
 				dev_err(xpc_part, "can't change memory "
 					"protections\n");
-				mspec_kfree_page((unsigned long) amos_page);
+				uncached_free_page(__IA64_UNCACHED_OFFSET |
+						   TO_PHYS((u64) amos_page));
 				return NULL;
 			}
 		}
@@ -251,7 +253,7 @@ xpc_rsvd_page_init(void)
 	 * This signifies to the remote partition that our reserved
 	 * page is initialized.
 	 */
-	(volatile u64) rp->vars_pa = __pa(xpc_vars);
+	rp->vars_pa = __pa(xpc_vars);
 
 	return rp;
 }
diff --git a/arch/ia64/sn/pci/pci_dma.c b/arch/ia64/sn/pci/pci_dma.c
--- a/arch/ia64/sn/pci/pci_dma.c
+++ b/arch/ia64/sn/pci/pci_dma.c
@@ -11,9 +11,10 @@
 
 #include <linux/module.h>
 #include <asm/dma.h>
-#include <asm/sn/sn_sal.h>
+#include <asm/sn/pcibr_provider.h>
 #include <asm/sn/pcibus_provider_defs.h>
 #include <asm/sn/pcidev.h>
+#include <asm/sn/sn_sal.h>
 
 #define SG_ENT_VIRT_ADDRESS(sg)	(page_address((sg)->page) + (sg)->offset)
 #define SG_ENT_PHYS_ADDRESS(SG)	virt_to_phys(SG_ENT_VIRT_ADDRESS(SG))
@@ -78,6 +79,7 @@ void *sn_dma_alloc_coherent(struct devic
 {
 	void *cpuaddr;
 	unsigned long phys_addr;
+	int node;
 	struct pci_dev *pdev = to_pci_dev(dev);
 	struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev);
 
@@ -85,10 +87,19 @@ void *sn_dma_alloc_coherent(struct devic
 
 	/*
 	 * Allocate the memory.
-	 * FIXME: We should be doing alloc_pages_node for the node closest
-	 *        to the PCI device.
 	 */
-	if (!(cpuaddr = (void *)__get_free_pages(GFP_ATOMIC, get_order(size))))
+	node = pcibus_to_node(pdev->bus);
+	if (likely(node >=0)) {
+		struct page *p = alloc_pages_node(node, GFP_ATOMIC, get_order(size));
+
+		if (likely(p))
+			cpuaddr = page_address(p);
+		else
+			return NULL;
+	} else
+		cpuaddr = (void *)__get_free_pages(GFP_ATOMIC, get_order(size));
+
+	if (unlikely(!cpuaddr))
 		return NULL;
 
 	memset(cpuaddr, 0x0, size);
diff --git a/arch/ia64/sn/pci/pcibr/pcibr_ate.c b/arch/ia64/sn/pci/pcibr/pcibr_ate.c
--- a/arch/ia64/sn/pci/pcibr/pcibr_ate.c
+++ b/arch/ia64/sn/pci/pcibr/pcibr_ate.c
@@ -8,9 +8,9 @@
 
 #include <linux/types.h>
 #include <asm/sn/sn_sal.h>
+#include <asm/sn/pcibr_provider.h>
 #include <asm/sn/pcibus_provider_defs.h>
 #include <asm/sn/pcidev.h>
-#include "pci/pcibr_provider.h"
 
 int pcibr_invalidate_ate = 0;	/* by default don't invalidate ATE on free */
 
diff --git a/arch/ia64/sn/pci/pcibr/pcibr_dma.c b/arch/ia64/sn/pci/pcibr/pcibr_dma.c
--- a/arch/ia64/sn/pci/pcibr/pcibr_dma.c
+++ b/arch/ia64/sn/pci/pcibr/pcibr_dma.c
@@ -8,18 +8,17 @@
 
 #include <linux/types.h>
 #include <linux/pci.h>
-#include <asm/sn/sn_sal.h>
+#include <asm/sn/addrs.h>
 #include <asm/sn/geo.h>
-#include "xtalk/xwidgetdev.h"
-#include "xtalk/hubdev.h"
+#include <asm/sn/pcibr_provider.h>
 #include <asm/sn/pcibus_provider_defs.h>
 #include <asm/sn/pcidev.h>
-#include "pci/tiocp.h"
-#include "pci/pic.h"
-#include "pci/pcibr_provider.h"
-#include "pci/tiocp.h"
+#include <asm/sn/pic.h>
+#include <asm/sn/sn_sal.h>
+#include <asm/sn/tiocp.h>
 #include "tio.h"
-#include <asm/sn/addrs.h>
+#include "xtalk/xwidgetdev.h"
+#include "xtalk/hubdev.h"
 
 extern int sn_ioif_inited;
 
diff --git a/arch/ia64/sn/pci/pcibr/pcibr_provider.c b/arch/ia64/sn/pci/pcibr/pcibr_provider.c
--- a/arch/ia64/sn/pci/pcibr/pcibr_provider.c
+++ b/arch/ia64/sn/pci/pcibr/pcibr_provider.c
@@ -6,18 +6,51 @@
  * Copyright (C) 2001-2004 Silicon Graphics, Inc. All rights reserved.
  */
 
-#include <linux/types.h>
 #include <linux/interrupt.h>
+#include <linux/types.h>
 #include <linux/pci.h>
-#include <asm/sn/sn_sal.h>
-#include "xtalk/xwidgetdev.h"
+#include <asm/sn/addrs.h>
 #include <asm/sn/geo.h>
-#include "xtalk/hubdev.h"
+#include <asm/sn/pcibr_provider.h>
 #include <asm/sn/pcibus_provider_defs.h>
 #include <asm/sn/pcidev.h>
-#include "pci/pcibr_provider.h"
-#include <asm/sn/addrs.h>
+#include <asm/sn/sn_sal.h>
+#include "xtalk/xwidgetdev.h"
+#include "xtalk/hubdev.h"
+
+int
+sal_pcibr_slot_enable(struct pcibus_info *soft, int device, void *resp)
+{
+	struct ia64_sal_retval ret_stuff;
+	uint64_t busnum;
+
+	ret_stuff.status = 0;
+	ret_stuff.v0 = 0;
 
+	busnum = soft->pbi_buscommon.bs_persist_busnum;
+	SAL_CALL_NOLOCK(ret_stuff, (u64) SN_SAL_IOIF_SLOT_ENABLE, (u64) busnum,
+			(u64) device, (u64) resp, 0, 0, 0, 0);
+
+	return (int)ret_stuff.v0;
+}
+
+int
+sal_pcibr_slot_disable(struct pcibus_info *soft, int device, int action,
+		       void *resp)
+{
+	struct ia64_sal_retval ret_stuff;
+	uint64_t busnum;
+
+	ret_stuff.status = 0;
+	ret_stuff.v0 = 0;
+
+	busnum = soft->pbi_buscommon.bs_persist_busnum;
+	SAL_CALL_NOLOCK(ret_stuff, (u64) SN_SAL_IOIF_SLOT_DISABLE,
+			(u64) busnum, (u64) device, (u64) action,
+			(u64) resp, 0, 0, 0);
+
+	return (int)ret_stuff.v0;
+}
 
 static int sal_pcibr_error_interrupt(struct pcibus_info *soft)
 {
@@ -52,7 +85,7 @@ pcibr_error_intr_handler(int irq, void *
 }
 
 void *
-pcibr_bus_fixup(struct pcibus_bussoft *prom_bussoft)
+pcibr_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *controller)
 {
 	int nasid, cnode, j;
 	struct hubdev_info *hubdev_info;
@@ -125,6 +158,14 @@ pcibr_bus_fixup(struct pcibus_bussoft *p
 	memset(soft->pbi_int_ate_resource.ate, 0,
  	       (soft->pbi_int_ate_size * sizeof(uint64_t)));
 
+	if (prom_bussoft->bs_asic_type == PCIIO_ASIC_TYPE_TIOCP)
+		/*
+		 * TIO PCI Bridge with no closest node information.
+		 * FIXME: Find another way to determine the closest node
+		 */
+		controller->node = -1;
+	else
+		controller->node = cnode;
 	return soft;
 }
 
@@ -188,3 +229,6 @@ pcibr_init_provider(void)
 
 	return 0;
 }
+
+EXPORT_SYMBOL_GPL(sal_pcibr_slot_enable);
+EXPORT_SYMBOL_GPL(sal_pcibr_slot_disable);
diff --git a/arch/ia64/sn/pci/pcibr/pcibr_reg.c b/arch/ia64/sn/pci/pcibr/pcibr_reg.c
--- a/arch/ia64/sn/pci/pcibr/pcibr_reg.c
+++ b/arch/ia64/sn/pci/pcibr/pcibr_reg.c
@@ -6,13 +6,13 @@
  * Copyright (C) 2004 Silicon Graphics, Inc. All rights reserved.
  */
 
-#include <linux/types.h>
 #include <linux/interrupt.h>
+#include <linux/types.h>
+#include <asm/sn/pcibr_provider.h>
 #include <asm/sn/pcibus_provider_defs.h>
 #include <asm/sn/pcidev.h>
-#include "pci/tiocp.h"
-#include "pci/pic.h"
-#include "pci/pcibr_provider.h"
+#include <asm/sn/pic.h>
+#include <asm/sn/tiocp.h>
 
 union br_ptr {
 	struct tiocp tio;
diff --git a/arch/ia64/sn/pci/tioca_provider.c b/arch/ia64/sn/pci/tioca_provider.c
--- a/arch/ia64/sn/pci/tioca_provider.c
+++ b/arch/ia64/sn/pci/tioca_provider.c
@@ -336,7 +336,7 @@ tioca_dma_d48(struct pci_dev *pdev, uint
 	if (!ct_addr)
 		return 0;
 
-	bus_addr = (dma_addr_t) (ct_addr & 0xffffffffffff);
+	bus_addr = (dma_addr_t) (ct_addr & 0xffffffffffffUL);
 	node_upper = ct_addr >> 48;
 
 	if (node_upper > 64) {
@@ -464,7 +464,7 @@ map_return:
  * For mappings created using the direct modes (64 or 48) there are no
  * resources to release.
  */
-void
+static void
 tioca_dma_unmap(struct pci_dev *pdev, dma_addr_t bus_addr, int dir)
 {
 	int i, entry;
@@ -514,7 +514,7 @@ tioca_dma_unmap(struct pci_dev *pdev, dm
  * The mapping mode used is based on the devices dma_mask.  As a last resort
  * use the GART mapped mode.
  */
-uint64_t
+static uint64_t
 tioca_dma_map(struct pci_dev *pdev, uint64_t paddr, size_t byte_count)
 {
 	uint64_t mapaddr;
@@ -580,8 +580,8 @@ tioca_error_intr_handler(int irq, void *
  * On successful setup, returns the kernel version of tioca_common back to
  * the caller.
  */
-void *
-tioca_bus_fixup(struct pcibus_bussoft *prom_bussoft)
+static void *
+tioca_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *controller)
 {
 	struct tioca_common *tioca_common;
 	struct tioca_kernel *tioca_kern;
@@ -589,8 +589,7 @@ tioca_bus_fixup(struct pcibus_bussoft *p
 
 	/* sanity check prom rev */
 
-	if (sn_sal_rev_major() < 4 ||
-	    (sn_sal_rev_major() == 4 && sn_sal_rev_minor() < 6)) {
+	if (sn_sal_rev() < 0x0406) {
 		printk
 		    (KERN_ERR "%s:  SGI prom rev 4.06 or greater required "
 		     "for tioca support\n", __FUNCTION__);
@@ -647,6 +646,8 @@ tioca_bus_fixup(struct pcibus_bussoft *p
 		       __FUNCTION__, SGI_TIOCA_ERROR,
 		       (int)tioca_common->ca_common.bs_persist_busnum);
 
+	/* Setup locality information */
+	controller->node = tioca_kern->ca_closest_node;
 	return tioca_common;
 }
 
diff --git a/arch/m32r/Kconfig b/arch/m32r/Kconfig
--- a/arch/m32r/Kconfig
+++ b/arch/m32r/Kconfig
@@ -78,6 +78,9 @@ config PLAT_OAKS32R
 config PLAT_MAPPI2
        bool "Mappi-II(M3A-ZA36/M3A-ZA52)"
 
+config PLAT_MAPPI3
+       bool "Mappi-III(M3A-2170)"
+
 endchoice
 
 choice
@@ -134,6 +137,7 @@ config BUS_CLOCK
 	int "Bus Clock [Hz] (integer)"
 	default "70000000" if PLAT_MAPPI
 	default "25000000" if PLAT_USRV
+	default "50000000" if PLAT_MAPPI3
 	default "50000000" if PLAT_M32700UT
 	default "50000000" if PLAT_OPSPUT
 	default "33333333" if PLAT_OAKS32R
@@ -149,7 +153,7 @@ config CPU_LITTLE_ENDIAN
 
 config MEMORY_START
 	hex "Physical memory start address (hex)"
-	default "08000000" if PLAT_MAPPI || PLAT_MAPPI2
+	default "08000000" if PLAT_MAPPI || PLAT_MAPPI2 || PLAT_MAPPI3
 	default "08000000" if PLAT_USRV
 	default "08000000" if PLAT_M32700UT
 	default "08000000" if PLAT_OPSPUT
@@ -157,6 +161,7 @@ config MEMORY_START
 
 config MEMORY_SIZE
 	hex "Physical memory size (hex)"
+	default "08000000" if PLAT_MAPPI3
 	default "04000000" if PLAT_MAPPI || PLAT_MAPPI2
 	default "02000000" if PLAT_USRV
 	default "01000000" if PLAT_M32700UT
@@ -167,11 +172,13 @@ config NOHIGHMEM
 	bool
 	default y
 
-config DISCONTIGMEM
+config ARCH_DISCONTIGMEM_ENABLE
 	bool "Internal RAM Support"
 	depends on CHIP_M32700 || CHIP_M32102 || CHIP_VDEC2 || CHIP_OPSP
 	default y
 
+source "mm/Kconfig"
+
 config IRAM_START
 	hex "Internal memory start address (hex)"
 	default "00f00000"
@@ -262,7 +269,7 @@ config NR_CPUS
 # Common NUMA Features
 config NUMA
 	bool "Numa Memory Allocation Support"
-	depends on SMP
+	depends on SMP && BROKEN
 	default n
 
 # turning this on wastes a bunch of space.
@@ -279,6 +286,7 @@ menu "Bus options (PCI, PCMCIA, EISA, MC
 
 config PCI
 	bool "PCI support"
+	depends on BROKEN
 	default n
 	help
 	  Find out whether you have a PCI motherboard. PCI is the name of a
@@ -352,6 +360,8 @@ source "fs/Kconfig.binfmt"
 
 endmenu
 
+source "net/Kconfig"
+
 source "drivers/Kconfig"
 
 source "fs/Kconfig"
diff --git a/arch/m32r/Kconfig.debug b/arch/m32r/Kconfig.debug
--- a/arch/m32r/Kconfig.debug
+++ b/arch/m32r/Kconfig.debug
@@ -5,6 +5,9 @@ source "lib/Kconfig.debug"
 config DEBUG_STACKOVERFLOW
 	bool "Check for stack overflows"
 	depends on DEBUG_KERNEL
+	help
+	  This option will cause messages to be printed if free stack space
+	  drops below a certain limit.
 
 config DEBUG_STACK_USAGE
 	bool "Stack utilization instrumentation"
@@ -17,7 +20,7 @@ config DEBUG_STACK_USAGE
 
 config DEBUG_PAGEALLOC
 	bool "Page alloc debugging"
-	depends on DEBUG_KERNEL
+	depends on DEBUG_KERNEL && BROKEN
 	help
 	  Unmap pages from the kernel linear mapping after free_pages().
 	  This results in a large slowdown, but helps to find certain types
diff --git a/arch/m32r/boot/compressed/m32r_sio.c b/arch/m32r/boot/compressed/m32r_sio.c
--- a/arch/m32r/boot/compressed/m32r_sio.c
+++ b/arch/m32r/boot/compressed/m32r_sio.c
@@ -6,6 +6,7 @@
  */
 
 #include <linux/config.h>
+#include <asm/processor.h>
 
 static void putc(char c);
 
@@ -38,16 +39,17 @@ static int puts(const char *s)
 
 static void putc(char c)
 {
-
-	while ((*BOOT_SIO0STS & 0x3) != 0x3) ;
+	while ((*BOOT_SIO0STS & 0x3) != 0x3)
+		cpu_relax();
 	if (c == '\n') {
 		*BOOT_SIO0TXB = '\r';
-		while ((*BOOT_SIO0STS & 0x3) != 0x3) ;
+		while ((*BOOT_SIO0STS & 0x3) != 0x3)
+			cpu_relax();
 	}
 	*BOOT_SIO0TXB = c;
 }
-#else /* defined(CONFIG_PLAT_M32700UT_Alpha) || defined(CONFIG_PLAT_M32700UT) */
-#ifdef CONFIG_MMU
+#else /* !(CONFIG_PLAT_M32700UT_Alpha) && !(CONFIG_PLAT_M32700UT) */
+#if defined(CONFIG_PLAT_MAPPI2)
 #define SIO0STS	(volatile unsigned short *)(0xa0efd000 + 14)
 #define SIO0TXB	(volatile unsigned short *)(0xa0efd000 + 30)
 #else
@@ -57,11 +59,12 @@ static void putc(char c)
 
 static void putc(char c)
 {
-
-	while ((*SIO0STS & 0x1) == 0) ;
+	while ((*SIO0STS & 0x1) == 0)
+		cpu_relax();
 	if (c == '\n') {
 		*SIO0TXB = '\r';
-		while ((*SIO0STS & 0x1) == 0) ;
+		while ((*SIO0STS & 0x1) == 0)
+			cpu_relax();
 	}
 	*SIO0TXB = c;
 }
diff --git a/arch/m32r/defconfig b/arch/m32r/defconfig
--- a/arch/m32r/defconfig
+++ b/arch/m32r/defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc4
-# Wed Feb 16 21:10:44 2005
+# Linux kernel version: 2.6.12-rc5
+# Fri Jun  3 16:20:11 2005
 #
 CONFIG_M32R=y
 # CONFIG_UID16 is not set
@@ -16,6 +16,7 @@ CONFIG_EXPERIMENTAL=y
 CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
 CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
@@ -28,13 +29,15 @@ CONFIG_BSD_PROCESS_ACCT=y
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
 CONFIG_HOTPLUG=y
 CONFIG_KOBJECT_UEVENT=y
 CONFIG_IKCONFIG=y
 # CONFIG_IKCONFIG_PROC is not set
 CONFIG_EMBEDDED=y
 # CONFIG_KALLSYMS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
 # CONFIG_FUTEX is not set
 # CONFIG_EPOLL is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -44,6 +47,7 @@ CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
 # CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
 
 #
 # Loadable module support
@@ -65,6 +69,7 @@ CONFIG_PLAT_M32700UT=y
 # CONFIG_PLAT_OPSPUT is not set
 # CONFIG_PLAT_OAKS32R is not set
 # CONFIG_PLAT_MAPPI2 is not set
+# CONFIG_PLAT_MAPPI3 is not set
 CONFIG_CHIP_M32700=y
 # CONFIG_CHIP_M32102 is not set
 # CONFIG_CHIP_VDEC2 is not set
@@ -268,7 +273,6 @@ CONFIG_NET=y
 #
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK_DEV is not set
 CONFIG_UNIX=y
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
@@ -393,18 +397,6 @@ CONFIG_INPUT=y
 # CONFIG_INPUT_EVBUG is not set
 
 #
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-# CONFIG_SERIO_RAW is not set
-
-#
 # Input Device Drivers
 #
 # CONFIG_INPUT_KEYBOARD is not set
@@ -414,6 +406,17 @@ CONFIG_SERIO_SERPORT=y
 # CONFIG_INPUT_MISC is not set
 
 #
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_LIBPS2 is not set
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+
+#
 # Character devices
 #
 CONFIG_VT=y
@@ -465,6 +468,10 @@ CONFIG_DS1302=y
 # CONFIG_RAW_DRIVER is not set
 
 #
+# TPM devices
+#
+
+#
 # I2C support
 #
 # CONFIG_I2C is not set
@@ -508,8 +515,14 @@ CONFIG_VIDEO_M32R_AR_M64278=y
 # Graphics support
 #
 CONFIG_FB=y
+# CONFIG_FB_CFB_FILLRECT is not set
+# CONFIG_FB_CFB_COPYAREA is not set
+# CONFIG_FB_CFB_IMAGEBLIT is not set
+# CONFIG_FB_SOFT_CURSOR is not set
+# CONFIG_FB_MACMODES is not set
 # CONFIG_FB_MODE_HELPERS is not set
 # CONFIG_FB_TILEBLITTING is not set
+# CONFIG_FB_S1D13XXX is not set
 # CONFIG_FB_VIRTUAL is not set
 
 #
@@ -543,10 +556,6 @@ CONFIG_LOGO_LINUX_CLUT224=y
 # CONFIG_USB_ARCH_HAS_OHCI is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
-
-#
 # USB Gadget Support
 #
 # CONFIG_USB_GADGET is not set
@@ -719,8 +728,9 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 #
 # Kernel hacking
 #
+# CONFIG_PRINTK_TIME is not set
 # CONFIG_DEBUG_KERNEL is not set
-CONFIG_DEBUG_PREEMPT=y
+CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_DEBUG_BUGVERBOSE is not set
 # CONFIG_FRAME_POINTER is not set
 
diff --git a/arch/m32r/kernel/Makefile b/arch/m32r/kernel/Makefile
--- a/arch/m32r/kernel/Makefile
+++ b/arch/m32r/kernel/Makefile
@@ -10,6 +10,7 @@ obj-y	:= process.o entry.o traps.o align
 obj-$(CONFIG_SMP)		+= smp.o smpboot.o
 obj-$(CONFIG_PLAT_MAPPI)	+= setup_mappi.o io_mappi.o
 obj-$(CONFIG_PLAT_MAPPI2)	+= setup_mappi2.o io_mappi2.o
+obj-$(CONFIG_PLAT_MAPPI3)	+= setup_mappi3.o io_mappi3.o
 obj-$(CONFIG_PLAT_USRV)		+= setup_usrv.o io_usrv.o
 obj-$(CONFIG_PLAT_M32700UT)	+= setup_m32700ut.o io_m32700ut.o
 obj-$(CONFIG_PLAT_OPSPUT)	+= setup_opsput.o io_opsput.o
@@ -17,4 +18,3 @@ obj-$(CONFIG_MODULES)		+= module.o
 obj-$(CONFIG_PLAT_OAKS32R)	+= setup_oaks32r.o io_oaks32r.o
 
 EXTRA_AFLAGS	:= -traditional
-
diff --git a/arch/m32r/kernel/io_m32700ut.c b/arch/m32r/kernel/io_m32700ut.c
--- a/arch/m32r/kernel/io_m32700ut.c
+++ b/arch/m32r/kernel/io_m32700ut.c
@@ -3,8 +3,8 @@
  *
  *  Typical I/O routines for M32700UT board.
  *
- *  Copyright (c) 2001, 2002  Hiroyuki Kondo, Hirokazu Takata,
- *                            Hitoshi Yamamoto, Takeo Takahashi
+ *  Copyright (c) 2001-2005  Hiroyuki Kondo, Hirokazu Takata,
+ *                           Hitoshi Yamamoto, Takeo Takahashi
  *
  *  This file is subject to the terms and conditions of the GNU General
  *  Public License.  See the file "COPYING" in the main directory of this
@@ -172,64 +172,21 @@ unsigned long _inl(unsigned long port)
 
 unsigned char _inb_p(unsigned long port)
 {
-	unsigned char  v;
-
-	if (port >= LAN_IOSTART && port < LAN_IOEND)
-		v = _ne_inb(PORT2ADDR_NE(port));
-	else
-#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
-	if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) {
-		return *(volatile unsigned char *)__port2addr_ata(port);
-	} else
-#endif
-#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC)
-	if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
-		unsigned char b;
-		pcc_ioread_byte(0, port, &b, sizeof(b), 1, 0);
-		return b;
-	} else
-#endif
-		v = *(volatile unsigned char *)PORT2ADDR(port);
-
+	unsigned char v = _inb(port);
 	delay();
 	return (v);
 }
 
 unsigned short _inw_p(unsigned long port)
 {
-	unsigned short  v;
-
-	if (port >= LAN_IOSTART && port < LAN_IOEND)
-		v = _ne_inw(PORT2ADDR_NE(port));
-	else
-#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
-	if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) {
-		return *(volatile unsigned short *)__port2addr_ata(port);
-	} else
-#endif
-#if defined(CONFIG_USB)
-	if(port >= 0x340 && port < 0x3a0)
-		return *(volatile unsigned short *)PORT2ADDR_USB(port);
-	else
-#endif
-#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC)
-	if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
-		unsigned short w;
-		pcc_ioread_word(0, port, &w, sizeof(w), 1, 0);
-		return w;
-	} else
-#endif
-		v = *(volatile unsigned short *)PORT2ADDR(port);
-
+	unsigned short v = _inw(port);
 	delay();
 	return (v);
 }
 
 unsigned long _inl_p(unsigned long port)
 {
-	unsigned long  v;
-
-	v = *(volatile unsigned long *)PORT2ADDR(port);
+	unsigned long v = _inl(port);
 	delay();
 	return (v);
 }
@@ -287,52 +244,19 @@ void _outl(unsigned long l, unsigned lon
 
 void _outb_p(unsigned char b, unsigned long port)
 {
-	if (port >= LAN_IOSTART && port < LAN_IOEND)
-		_ne_outb(b, PORT2ADDR_NE(port));
-	else
-#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
-	if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) {
-		*(volatile unsigned char *)__port2addr_ata(port) = b;
-	} else
-#endif
-#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC)
-	if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
-		pcc_iowrite_byte(0, port, &b, sizeof(b), 1, 0);
-	} else
-#endif
-		*(volatile unsigned char *)PORT2ADDR(port) = b;
-
+	_outb(b, port);
 	delay();
 }
 
 void _outw_p(unsigned short w, unsigned long port)
 {
-	if (port >= LAN_IOSTART && port < LAN_IOEND)
-		_ne_outw(w, PORT2ADDR_NE(port));
-	else
-#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
-	if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) {
-		*(volatile unsigned short *)__port2addr_ata(port) = w;
-	} else
-#endif
-#if defined(CONFIG_USB)
-	if(port >= 0x340 && port < 0x3a0)
-		*(volatile unsigned short *)PORT2ADDR_USB(port) = w;
-	else
-#endif
-#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC)
-	if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
-		pcc_iowrite_word(0, port, &w, sizeof(w), 1, 0);
-	} else
-#endif
-		*(volatile unsigned short *)PORT2ADDR(port) = w;
-
+	_outw(w, port);
 	delay();
 }
 
 void _outl_p(unsigned long l, unsigned long port)
 {
-	*(volatile unsigned long *)PORT2ADDR(port) = l;
+	_outl(l, port);
 	delay();
 }
 
diff --git a/arch/m32r/kernel/io_mappi.c b/arch/m32r/kernel/io_mappi.c
--- a/arch/m32r/kernel/io_mappi.c
+++ b/arch/m32r/kernel/io_mappi.c
@@ -3,8 +3,8 @@
  *
  *  Typical I/O routines for Mappi board.
  *
- *  Copyright (c) 2001, 2002  Hiroyuki Kondo, Hirokazu Takata,
- *                            Hitoshi Yamamoto
+ *  Copyright (c) 2001-2005  Hiroyuki Kondo, Hirokazu Takata,
+ *                           Hitoshi Yamamoto
  */
 
 #include <linux/config.h>
@@ -130,57 +130,21 @@ unsigned long _inl(unsigned long port)
 
 unsigned char _inb_p(unsigned long port)
 {
-	unsigned char  v;
-
-	if (port >= 0x300 && port < 0x320)
-		v = _ne_inb(PORT2ADDR_NE(port));
-	else
-#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC)
-	if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
-		unsigned char b;
-		pcc_ioread(0, port, &b, sizeof(b), 1, 0);
-		return b;
-	} else 	if (port >= M32R_PCC_IOSTART1 && port <= M32R_PCC_IOEND1) {
-		unsigned char b;
-		pcc_ioread(1, port, &b, sizeof(b), 1, 0);
-		return b;
-	} else
-#endif
-		v = *(volatile unsigned char *)PORT2ADDR(port);
-
+	unsigned char v = _inb(port);
 	delay();
 	return (v);
 }
 
 unsigned short _inw_p(unsigned long port)
 {
-	unsigned short  v;
-
-	if (port >= 0x300 && port < 0x320)
-		v = _ne_inw(PORT2ADDR_NE(port));
-	else
-#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC)
-	if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
-		unsigned short w;
-		pcc_ioread(0, port, &w, sizeof(w), 1, 0);
-		return w;
-	} else 	if (port >= M32R_PCC_IOSTART1 && port <= M32R_PCC_IOEND1) {
-		unsigned short w;
-		pcc_ioread(1, port, &w, sizeof(w), 1, 0);
-		return w;
-	} else
-#endif
-		v = *(volatile unsigned short *)PORT2ADDR(port);
-
+	unsigned short v = _inw(port);
 	delay();
 	return (v);
 }
 
 unsigned long _inl_p(unsigned long port)
 {
-	unsigned long  v;
-
-	v = *(volatile unsigned long *)PORT2ADDR(port);
+	unsigned long v = _inl(port);
 	delay();
 	return (v);
 }
@@ -229,41 +193,19 @@ void _outl(unsigned long l, unsigned lon
 
 void _outb_p(unsigned char b, unsigned long port)
 {
-	if (port >= 0x300 && port < 0x320)
-		_ne_outb(b, PORT2ADDR_NE(port));
-	else
-#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC)
-	if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
-		pcc_iowrite(0, port, &b, sizeof(b), 1, 0);
-	} else 	if (port >= M32R_PCC_IOSTART1 && port <= M32R_PCC_IOEND1) {
-		pcc_iowrite(1, port, &b, sizeof(b), 1, 0);
-	} else
-#endif
-		*(volatile unsigned char *)PORT2ADDR(port) = b;
-
+	_outb(b, port);
 	delay();
 }
 
 void _outw_p(unsigned short w, unsigned long port)
 {
-	if (port >= 0x300 && port < 0x320)
-		_ne_outw(w, PORT2ADDR_NE(port));
-	else
-#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC)
-	if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
-		pcc_iowrite(0, port, &w, sizeof(w), 1, 0);
-	} else 	if (port >= M32R_PCC_IOSTART1 && port <= M32R_PCC_IOEND1) {
-		pcc_iowrite(1, port, &w, sizeof(w), 1, 0);
-	} else
-#endif
-		*(volatile unsigned short *)PORT2ADDR(port) = w;
-
+	_outw(w, port);
 	delay();
 }
 
 void _outl_p(unsigned long l, unsigned long port)
 {
-	*(volatile unsigned long *)PORT2ADDR(port) = l;
+	_outl(l, port);
 	delay();
 }
 
diff --git a/arch/m32r/kernel/io_mappi2.c b/arch/m32r/kernel/io_mappi2.c
--- a/arch/m32r/kernel/io_mappi2.c
+++ b/arch/m32r/kernel/io_mappi2.c
@@ -3,7 +3,7 @@
  *
  *  Typical I/O routines for Mappi2 board.
  *
- *  Copyright (c) 2001-2003  Hiroyuki Kondo, Hirokazu Takata,
+ *  Copyright (c) 2001-2005  Hiroyuki Kondo, Hirokazu Takata,
  *                           Hitoshi Yamamoto, Mamoru Sakugawa
  */
 
@@ -25,7 +25,7 @@ extern void pcc_ioread_byte(int, unsigne
 extern void pcc_ioread_word(int, unsigned long, void *, size_t, size_t, int);
 extern void pcc_iowrite_byte(int, unsigned long, void *, size_t, size_t, int);
 extern void pcc_iowrite_word(int, unsigned long, void *, size_t, size_t, int);
-#endif /* CONFIG_PCMCIA && CONFIG_MAPPI2_CFC */
+#endif /* CONFIG_PCMCIA && CONFIG_M32R_CFC */
 
 #define PORT2ADDR(port)      _port2addr(port)
 #define PORT2ADDR_NE(port)   _port2addr_ne(port)
@@ -169,64 +169,21 @@ unsigned long _inl(unsigned long port)
 
 unsigned char _inb_p(unsigned long port)
 {
-	unsigned char  v;
-
-	if (port >= LAN_IOSTART && port < LAN_IOEND)
-		v = _ne_inb(PORT2ADDR_NE(port));
-	else
-#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
-	if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) {
-		return *(volatile unsigned char *)__port2addr_ata(port);
-	} else
-#endif
-#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC)
-	if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
-		unsigned char b;
-		pcc_ioread_byte(0, port, &b, sizeof(b), 1, 0);
-		return b;
-	} else
-#endif
-		v = *(volatile unsigned char *)PORT2ADDR(port);
-
+	unsigned char v = _inb(port);
 	delay();
 	return (v);
 }
 
 unsigned short _inw_p(unsigned long port)
 {
-	unsigned short  v;
-
-	if (port >= LAN_IOSTART && port < LAN_IOEND)
-		v = _ne_inw(PORT2ADDR_NE(port));
-	else
-#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
-	if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) {
-		return *(volatile unsigned short *)__port2addr_ata(port);
-	} else
-#endif
-#if defined(CONFIG_USB)
-	if (port >= 0x340 && port < 0x3a0)
-		v = *(volatile unsigned short *)PORT2ADDR_USB(port);
-	else
-#endif
-#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC)
-	if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
-		unsigned short w;
-		pcc_ioread_word(0, port, &w, sizeof(w), 1, 0);
-		return w;
-	} else
-#endif
-		v = *(volatile unsigned short *)PORT2ADDR(port);
-
+	unsigned short v = _inw(port);
 	delay();
 	return (v);
 }
 
 unsigned long _inl_p(unsigned long port)
 {
-	unsigned long  v;
-
-	v = *(volatile unsigned long *)PORT2ADDR(port);
+	unsigned long v = _inl(port);
 	delay();
 	return (v);
 }
@@ -284,52 +241,19 @@ void _outl(unsigned long l, unsigned lon
 
 void _outb_p(unsigned char b, unsigned long port)
 {
-	if (port >= LAN_IOSTART && port < LAN_IOEND)
-		_ne_outb(b, PORT2ADDR_NE(port));
-	else
-#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
-	if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) {
-		*(volatile unsigned char *)__port2addr_ata(port) = b;
-	} else
-#endif
-#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC)
-	if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
-		pcc_iowrite_byte(0, port, &b, sizeof(b), 1, 0);
-	} else
-#endif
-		*(volatile unsigned char *)PORT2ADDR(port) = b;
-
+	_outb(b, port);
 	delay();
 }
 
 void _outw_p(unsigned short w, unsigned long port)
 {
-	if (port >= LAN_IOSTART && port < LAN_IOEND)
-		_ne_outw(w, PORT2ADDR_NE(port));
-	else
-#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
-	if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) {
-		*(volatile unsigned short *)__port2addr_ata(port) = w;
-	} else
-#endif
-#if defined(CONFIG_USB)
-	  if (port >= 0x340 && port < 0x3a0)
-		*(volatile unsigned short *)PORT2ADDR_USB(port) = w;
-	else
-#endif
-#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC)
-	if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
-		pcc_iowrite_word(0, port, &w, sizeof(w), 1, 0);
-	} else
-#endif
-		*(volatile unsigned short *)PORT2ADDR(port) = w;
-
+	_outw(w, port);
 	delay();
 }
 
 void _outl_p(unsigned long l, unsigned long port)
 {
-	*(volatile unsigned long *)PORT2ADDR(port) = l;
+	_outl(l, port);
 	delay();
 }
 
diff --git a/arch/m32r/kernel/io_mappi3.c b/arch/m32r/kernel/io_mappi3.c
new file mode 100644
--- /dev/null
+++ b/arch/m32r/kernel/io_mappi3.c
@@ -0,0 +1,378 @@
+/*
+ *  linux/arch/m32r/kernel/io_mappi3.c
+ *
+ *  Typical I/O routines for Mappi3 board.
+ *
+ *  Copyright (c) 2001-2005  Hiroyuki Kondo, Hirokazu Takata,
+ *                           Hitoshi Yamamoto, Mamoru Sakugawa
+ */
+
+#include <linux/config.h>
+#include <asm/m32r.h>
+#include <asm/page.h>
+#include <asm/io.h>
+#include <asm/byteorder.h>
+
+#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC)
+#include <linux/types.h>
+
+#define M32R_PCC_IOMAP_SIZE 0x1000
+
+#define M32R_PCC_IOSTART0 0x1000
+#define M32R_PCC_IOEND0   (M32R_PCC_IOSTART0 + M32R_PCC_IOMAP_SIZE - 1)
+
+extern void pcc_ioread_byte(int, unsigned long, void *, size_t, size_t, int);
+extern void pcc_ioread_word(int, unsigned long, void *, size_t, size_t, int);
+extern void pcc_iowrite_byte(int, unsigned long, void *, size_t, size_t, int);
+extern void pcc_iowrite_word(int, unsigned long, void *, size_t, size_t, int);
+#endif /* CONFIG_PCMCIA && CONFIG_M32R_CFC */
+
+#define PORT2ADDR(port)      _port2addr(port)
+#define PORT2ADDR_NE(port)   _port2addr_ne(port)
+#define PORT2ADDR_USB(port)  _port2addr_usb(port)
+
+static inline void *_port2addr(unsigned long port)
+{
+	return (void *)(port + NONCACHE_OFFSET);
+}
+
+#define LAN_IOSTART	0x300
+#define LAN_IOEND	0x320
+
+#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
+static inline void *__port2addr_ata(unsigned long port)
+{
+	static int	dummy_reg;
+
+	switch (port) {
+	case 0x1f0:	return (void *)0xb4002000;
+	case 0x1f1:	return (void *)0xb4012800;
+	case 0x1f2:	return (void *)0xb4012002;
+	case 0x1f3:	return (void *)0xb4012802;
+	case 0x1f4:	return (void *)0xb4012004;
+	case 0x1f5:	return (void *)0xb4012804;
+	case 0x1f6:	return (void *)0xb4012006;
+	case 0x1f7:	return (void *)0xb4012806;
+	case 0x3f6:	return (void *)0xb401200e;
+	default: 	return (void *)&dummy_reg;
+	}
+}
+#endif
+
+static inline void *_port2addr_ne(unsigned long port)
+{
+	return (void *)(port + NONCACHE_OFFSET + 0x10000000);
+}
+
+static inline void *_port2addr_usb(unsigned long port)
+{
+	return (void *)(port + NONCACHE_OFFSET + 0x12000000);
+}
+static inline void delay(void)
+{
+	__asm__ __volatile__ ("push r0; \n\t pop r0;" : : :"memory");
+}
+
+/*
+ * NIC I/O function
+ */
+
+static inline unsigned char _ne_inb(void *portp)
+{
+	return (unsigned char) *(volatile unsigned char *)portp;
+}
+
+static inline unsigned short _ne_inw(void *portp)
+{
+	return (unsigned short)le16_to_cpu(*(volatile unsigned short *)portp);
+}
+
+static inline void _ne_insb(void *portp, void * addr, unsigned long count)
+{
+	unsigned char *buf = addr;
+
+	while (count--)
+		*buf++ = *(volatile unsigned char *)portp;
+}
+
+static inline void _ne_outb(unsigned char b, void *portp)
+{
+	*(volatile unsigned char *)portp = (unsigned char)b;
+}
+
+static inline void _ne_outw(unsigned short w, void *portp)
+{
+	*(volatile unsigned short *)portp = cpu_to_le16(w);
+}
+
+unsigned char _inb(unsigned long port)
+{
+	if (port >= LAN_IOSTART && port < LAN_IOEND)
+		return _ne_inb(PORT2ADDR_NE(port));
+#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
+	else if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) {
+		return *(volatile unsigned char *)__port2addr_ata(port);
+	}
+#endif
+#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC)
+	else if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
+		unsigned char b;
+		pcc_ioread_byte(0, port, &b, sizeof(b), 1, 0);
+		return b;
+	} else
+#endif
+	return *(volatile unsigned char *)PORT2ADDR(port);
+}
+
+unsigned short _inw(unsigned long port)
+{
+	if (port >= LAN_IOSTART && port < LAN_IOEND)
+		return _ne_inw(PORT2ADDR_NE(port));
+#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
+	else if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) {
+		return *(volatile unsigned short *)__port2addr_ata(port);
+	}
+#endif
+#if defined(CONFIG_USB)
+	else if (port >= 0x340 && port < 0x3a0)
+		return *(volatile unsigned short *)PORT2ADDR_USB(port);
+#endif
+
+#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC)
+	else if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
+		unsigned short w;
+		pcc_ioread_word(0, port, &w, sizeof(w), 1, 0);
+		return w;
+	} else
+#endif
+	return *(volatile unsigned short *)PORT2ADDR(port);
+}
+
+unsigned long _inl(unsigned long port)
+{
+#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC)
+	if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
+		unsigned long l;
+		pcc_ioread_word(0, port, &l, sizeof(l), 1, 0);
+		return l;
+	} else
+#endif
+	return *(volatile unsigned long *)PORT2ADDR(port);
+}
+
+unsigned char _inb_p(unsigned long port)
+{
+	unsigned char v = _inb(port);
+	delay();
+	return (v);
+}
+
+unsigned short _inw_p(unsigned long port)
+{
+	unsigned short v = _inw(port);
+	delay();
+	return (v);
+}
+
+unsigned long _inl_p(unsigned long port)
+{
+	unsigned long v = _inl(port);
+	delay();
+	return (v);
+}
+
+void _outb(unsigned char b, unsigned long port)
+{
+	if (port >= LAN_IOSTART && port < LAN_IOEND)
+		_ne_outb(b, PORT2ADDR_NE(port));
+	else
+#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
+	if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) {
+		*(volatile unsigned char *)__port2addr_ata(port) = b;
+	} else
+#endif
+#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC)
+	if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
+		pcc_iowrite_byte(0, port, &b, sizeof(b), 1, 0);
+	} else
+#endif
+		*(volatile unsigned char *)PORT2ADDR(port) = b;
+}
+
+void _outw(unsigned short w, unsigned long port)
+{
+	if (port >= LAN_IOSTART && port < LAN_IOEND)
+		_ne_outw(w, PORT2ADDR_NE(port));
+	else
+#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
+	if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) {
+		*(volatile unsigned short *)__port2addr_ata(port) = w;
+	} else
+#endif
+#if defined(CONFIG_USB)
+	if (port >= 0x340 && port < 0x3a0)
+		*(volatile unsigned short *)PORT2ADDR_USB(port) = w;
+	else
+#endif
+#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC)
+	if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
+		pcc_iowrite_word(0, port, &w, sizeof(w), 1, 0);
+	} else
+#endif
+		*(volatile unsigned short *)PORT2ADDR(port) = w;
+}
+
+void _outl(unsigned long l, unsigned long port)
+{
+#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC)
+	if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
+		pcc_iowrite_word(0, port, &l, sizeof(l), 1, 0);
+	} else
+#endif
+	*(volatile unsigned long *)PORT2ADDR(port) = l;
+}
+
+void _outb_p(unsigned char b, unsigned long port)
+{
+	_outb(b, port);
+	delay();
+}
+
+void _outw_p(unsigned short w, unsigned long port)
+{
+	_outw(w, port);
+	delay();
+}
+
+void _outl_p(unsigned long l, unsigned long port)
+{
+	_outl(l, port);
+	delay();
+}
+
+void _insb(unsigned int port, void * addr, unsigned long count)
+{
+	if (port >= LAN_IOSTART && port < LAN_IOEND)
+		_ne_insb(PORT2ADDR_NE(port), addr, count);
+#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
+	else if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) {
+		unsigned char *buf = addr;
+		unsigned char *portp = __port2addr_ata(port);
+		while (count--)
+			*buf++ = *(volatile unsigned char *)portp;
+	}
+#endif
+#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC)
+	else if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
+		pcc_ioread_byte(0, port, (void *)addr, sizeof(unsigned char),
+				count, 1);
+	}
+#endif
+	else {
+		unsigned char *buf = addr;
+		unsigned char *portp = PORT2ADDR(port);
+		while (count--)
+			*buf++ = *(volatile unsigned char *)portp;
+	}
+}
+
+void _insw(unsigned int port, void * addr, unsigned long count)
+{
+	unsigned short *buf = addr;
+	unsigned short *portp;
+
+	if (port >= LAN_IOSTART && port < LAN_IOEND) {
+		portp = PORT2ADDR_NE(port);
+		while (count--)
+			*buf++ = *(volatile unsigned short *)portp;
+#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC)
+	} else if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
+		pcc_ioread_word(9, port, (void *)addr, sizeof(unsigned short),
+				count, 1);
+#endif
+#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
+	} else if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) {
+		portp = __port2addr_ata(port);
+		while (count--)
+			*buf++ = *(volatile unsigned short *)portp;
+#endif
+	} else {
+		portp = PORT2ADDR(port);
+		while (count--)
+			*buf++ = *(volatile unsigned short *)portp;
+	}
+}
+
+void _insl(unsigned int port, void * addr, unsigned long count)
+{
+	unsigned long *buf = addr;
+	unsigned long *portp;
+
+	portp = PORT2ADDR(port);
+	while (count--)
+		*buf++ = *(volatile unsigned long *)portp;
+}
+
+void _outsb(unsigned int port, const void * addr, unsigned long count)
+{
+	const unsigned char *buf = addr;
+	unsigned char *portp;
+
+	if (port >= LAN_IOSTART && port < LAN_IOEND) {
+		portp = PORT2ADDR_NE(port);
+		while (count--)
+			_ne_outb(*buf++, portp);
+#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
+	} else if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) {
+		portp = __port2addr_ata(port);
+		while (count--)
+			*(volatile unsigned char *)portp = *buf++;
+#endif
+#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC)
+	} else if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
+		pcc_iowrite_byte(0, port, (void *)addr, sizeof(unsigned char),
+				 count, 1);
+#endif
+	} else {
+		portp = PORT2ADDR(port);
+		while (count--)
+			*(volatile unsigned char *)portp = *buf++;
+	}
+}
+
+void _outsw(unsigned int port, const void * addr, unsigned long count)
+{
+	const unsigned short *buf = addr;
+	unsigned short *portp;
+
+	if (port >= LAN_IOSTART && port < LAN_IOEND) {
+		portp = PORT2ADDR_NE(port);
+		while (count--)
+			*(volatile unsigned short *)portp = *buf++;
+#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
+	} else if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) {
+		portp = __port2addr_ata(port);
+		while (count--)
+			*(volatile unsigned short *)portp = *buf++;
+#endif
+#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC)
+	} else if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
+		pcc_iowrite_word(9, port, (void *)addr, sizeof(unsigned short),
+				 count, 1);
+#endif
+	} else {
+		portp = PORT2ADDR(port);
+		while (count--)
+			*(volatile unsigned short *)portp = *buf++;
+	}
+}
+
+void _outsl(unsigned int port, const void * addr, unsigned long count)
+{
+	const unsigned long *buf = addr;
+	unsigned char *portp;
+
+	portp = PORT2ADDR(port);
+	while (count--)
+		*(volatile unsigned long *)portp = *buf++;
+}
diff --git a/arch/m32r/kernel/io_oaks32r.c b/arch/m32r/kernel/io_oaks32r.c
--- a/arch/m32r/kernel/io_oaks32r.c
+++ b/arch/m32r/kernel/io_oaks32r.c
@@ -3,7 +3,7 @@
  *
  *  Typical I/O routines for OAKS32R board.
  *
- *  Copyright (c) 2001-2004  Hiroyuki Kondo, Hirokazu Takata,
+ *  Copyright (c) 2001-2005  Hiroyuki Kondo, Hirokazu Takata,
  *                           Hitoshi Yamamoto, Mamoru Sakugawa
  */
 
@@ -90,35 +90,21 @@ unsigned long _inl(unsigned long port)
 
 unsigned char _inb_p(unsigned long port)
 {
-	unsigned char  v;
-
-	if (port >= 0x300 && port < 0x320)
-		v = _ne_inb(PORT2ADDR_NE(port));
-	else
-		v = *(volatile unsigned char *)PORT2ADDR(port);
-
+	unsigned char v = _inb(port);
 	delay();
 	return (v);
 }
 
 unsigned short _inw_p(unsigned long port)
 {
-	unsigned short  v;
-
-	if (port >= 0x300 && port < 0x320)
-		v = _ne_inw(PORT2ADDR_NE(port));
-	else
-		v = *(volatile unsigned short *)PORT2ADDR(port);
-
+	unsigned short v = _inw(port);
 	delay();
 	return (v);
 }
 
 unsigned long _inl_p(unsigned long port)
 {
-	unsigned long  v;
-
-	v = *(volatile unsigned long *)PORT2ADDR(port);
+	unsigned long v = _inl(port);
 	delay();
 	return (v);
 }
@@ -146,27 +132,19 @@ void _outl(unsigned long l, unsigned lon
 
 void _outb_p(unsigned char b, unsigned long port)
 {
-	if (port >= 0x300 && port < 0x320)
-		_ne_outb(b, PORT2ADDR_NE(port));
-	else
-		*(volatile unsigned char *)PORT2ADDR(port) = b;
-
+	_outb(b, port);
 	delay();
 }
 
 void _outw_p(unsigned short w, unsigned long port)
 {
-	if (port >= 0x300 && port < 0x320)
-		_ne_outw(w, PORT2ADDR_NE(port));
-	else
-		*(volatile unsigned short *)PORT2ADDR(port) = w;
-
+	_outw(w, port);
 	delay();
 }
 
 void _outl_p(unsigned long l, unsigned long port)
 {
-	*(volatile unsigned long *)PORT2ADDR(port) = l;
+	_outl(l, port);
 	delay();
 }
 
diff --git a/arch/m32r/kernel/io_opsput.c b/arch/m32r/kernel/io_opsput.c
--- a/arch/m32r/kernel/io_opsput.c
+++ b/arch/m32r/kernel/io_opsput.c
@@ -1,10 +1,10 @@
 /*
- *  linux/arch/m32r/kernel/io_mappi.c
+ *  linux/arch/m32r/kernel/io_opsput.c
  *
  *  Typical I/O routines for OPSPUT board.
  *
- *  Copyright (c) 2001, 2002  Hiroyuki Kondo, Hirokazu Takata,
- *                            Hitoshi Yamamoto, Takeo Takahashi
+ *  Copyright (c) 2001-2005  Hiroyuki Kondo, Hirokazu Takata,
+ *                           Hitoshi Yamamoto, Takeo Takahashi
  *
  *  This file is subject to the terms and conditions of the GNU General
  *  Public License.  See the file "COPYING" in the main directory of this
@@ -98,7 +98,6 @@ unsigned char _inb(unsigned long port)
 {
 	if (port >= LAN_IOSTART && port < LAN_IOEND)
 		return _ne_inb(PORT2ADDR_NE(port));
-
 #if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC)
 	else if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
 		unsigned char b;
@@ -118,7 +117,6 @@ unsigned short _inw(unsigned long port)
 	else if(port >= 0x340 && port < 0x3a0)
 		return *(volatile unsigned short *)PORT2ADDR_USB(port);
 #endif
-
 #if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC)
 	else if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
 		unsigned short w;
@@ -143,55 +141,21 @@ unsigned long _inl(unsigned long port)
 
 unsigned char _inb_p(unsigned long port)
 {
-	unsigned char  v;
-
-	if (port >= LAN_IOSTART && port < LAN_IOEND)
-		v = _ne_inb(PORT2ADDR_NE(port));
-	else
-#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC)
-	if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
-		unsigned char b;
-		pcc_ioread_byte(0, port, &b, sizeof(b), 1, 0);
-		return b;
-	} else
-#endif
-		v = *(volatile unsigned char *)PORT2ADDR(port);
-
+	unsigned char v = _inb(port);
 	delay();
 	return (v);
 }
 
 unsigned short _inw_p(unsigned long port)
 {
-	unsigned short  v;
-
-	if (port >= LAN_IOSTART && port < LAN_IOEND)
-		v = _ne_inw(PORT2ADDR_NE(port));
-	else
-#if defined(CONFIG_USB)
-	if(port >= 0x340 && port < 0x3a0)
-		return *(volatile unsigned short *)PORT2ADDR_USB(port);
-	else
-#endif
-
-#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC)
-	if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
-		unsigned short w;
-		pcc_ioread_word(0, port, &w, sizeof(w), 1, 0);
-		return w;
-	} else
-#endif
-		v = *(volatile unsigned short *)PORT2ADDR(port);
-
+	unsigned short v = _inw(port);
 	delay();
 	return (v);
 }
 
 unsigned long _inl_p(unsigned long port)
 {
-	unsigned long  v;
-
-	v = *(volatile unsigned long *)PORT2ADDR(port);
+	unsigned long v = _inl(port);
 	delay();
 	return (v);
 }
@@ -219,7 +183,6 @@ void _outw(unsigned short w, unsigned lo
 		*(volatile unsigned short *)PORT2ADDR_USB(port) = w;
 	else
 #endif
-
 #if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC)
 	if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
 		pcc_iowrite_word(0, port, &w, sizeof(w), 1, 0);
@@ -240,43 +203,19 @@ void _outl(unsigned long l, unsigned lon
 
 void _outb_p(unsigned char b, unsigned long port)
 {
-	if (port >= LAN_IOSTART && port < LAN_IOEND)
-		_ne_outb(b, PORT2ADDR_NE(port));
-	else
-#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC)
-	if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
-		pcc_iowrite_byte(0, port, &b, sizeof(b), 1, 0);
-	} else
-#endif
-		*(volatile unsigned char *)PORT2ADDR(port) = b;
-
+	_outb(b, port);
 	delay();
 }
 
 void _outw_p(unsigned short w, unsigned long port)
 {
-	if (port >= LAN_IOSTART && port < LAN_IOEND)
-		_ne_outw(w, PORT2ADDR_NE(port));
-	else
-#if defined(CONFIG_USB)
-	if(port >= 0x340 && port < 0x3a0)
-		*(volatile unsigned short *)PORT2ADDR_USB(port) = w;
-	else
-#endif
-
-#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC)
-	if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
-		pcc_iowrite_word(0, port, &w, sizeof(w), 1, 0);
-	} else
-#endif
-		*(volatile unsigned short *)PORT2ADDR(port) = w;
-
+	_outw(w, port);
 	delay();
 }
 
 void _outl_p(unsigned long l, unsigned long port)
 {
-	*(volatile unsigned long *)PORT2ADDR(port) = l;
+	_outl(l, port);
 	delay();
 }
 
diff --git a/arch/m32r/kernel/io_usrv.c b/arch/m32r/kernel/io_usrv.c
--- a/arch/m32r/kernel/io_usrv.c
+++ b/arch/m32r/kernel/io_usrv.c
@@ -3,8 +3,8 @@
  *
  *  Typical I/O routines for uServer board.
  *
- *  Copyright (c) 2001 - 2003  Hiroyuki Kondo, Hirokazu Takata,
- *                             Hitoshi Yamamoto, Takeo Takahashi
+ *  Copyright (c) 2001-2005  Hiroyuki Kondo, Hirokazu Takata,
+ *                           Hitoshi Yamamoto, Takeo Takahashi
  *
  *  This file is subject to the terms and conditions of the GNU General
  *  Public License.  See the file "COPYING" in the main directory of this
@@ -39,7 +39,7 @@ extern void pcc_iowrite_word(int, unsign
 
 #define PORT2ADDR(port)	_port2addr(port)
 
-static __inline__ void *_port2addr(unsigned long port)
+static inline void *_port2addr(unsigned long port)
 {
 #if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE)
 	if (port >= UART0_IOSTART && port <= UART0_IOEND)
@@ -50,7 +50,7 @@ static __inline__ void *_port2addr(unsig
 	return (void *)(port + NONCACHE_OFFSET);
 }
 
-static __inline__ void delay(void)
+static inline void delay(void)
 {
 	__asm__ __volatile__ ("push r0; \n\t pop r0;" : : :"memory");
 }
@@ -87,39 +87,22 @@ unsigned long _inl(unsigned long port)
 
 unsigned char _inb_p(unsigned long port)
 {
-	unsigned char b;
-
-	if (port >= CFC_IOSTART && port <= CFC_IOEND) {
-		pcc_ioread_byte(0, port, &b, sizeof(b), 1, 0);
-		return b;
-	} else {
-		b = *(volatile unsigned char *)PORT2ADDR(port);
-		delay();
-		return b;
-	}
+	unsigned char v = _inb(port);
+	delay();
+	return v;
 }
 
 unsigned short _inw_p(unsigned long port)
 {
-	unsigned short w;
-
-	if (port >= CFC_IOSTART && port <= CFC_IOEND) {
-		pcc_ioread_word(0, port, &w, sizeof(w), 1, 0);
-		return w;
-	} else {
-		w = *(volatile unsigned short *)PORT2ADDR(port);
-		delay();
-		return w;
-	}
+	unsigned short v = _inw(port);
+	delay();
+	return v;
 }
 
 unsigned long _inl_p(unsigned long port)
 {
-	unsigned long v;
-
-	v = *(volatile unsigned long *)PORT2ADDR(port);
+	unsigned long v = _inl(port);
 	delay();
-
 	return v;
 }
 
@@ -149,25 +132,19 @@ void _outl(unsigned long l, unsigned lon
 
 void _outb_p(unsigned char b, unsigned long port)
 {
-	if (port >= CFC_IOSTART && port <= CFC_IOEND)
-		pcc_iowrite_byte(0, port, &b, sizeof(b), 1, 0);
-	else
-		*(volatile unsigned char *)PORT2ADDR(port) = b;
+	_outb(b, port);
 	delay();
 }
 
 void _outw_p(unsigned short w, unsigned long port)
 {
-	if (port >= CFC_IOSTART && port <= CFC_IOEND)
-		pcc_iowrite_word(0, port, &w, sizeof(w), 1, 0);
-	else
-		*(volatile unsigned short *)PORT2ADDR(port) = w;
+	_outw(w, port);
 	delay();
 }
 
 void _outl_p(unsigned long l, unsigned long port)
 {
-	*(volatile unsigned long *)PORT2ADDR(port) = l;
+	_outl(l, port);
 	delay();
 }
 
diff --git a/arch/m32r/kernel/process.c b/arch/m32r/kernel/process.c
--- a/arch/m32r/kernel/process.c
+++ b/arch/m32r/kernel/process.c
@@ -115,8 +115,6 @@ void machine_restart(char *__unused)
 		cpu_relax();
 }
 
-EXPORT_SYMBOL(machine_restart);
-
 void machine_halt(void)
 {
 	printk("Please push reset button!\n");
@@ -124,15 +122,11 @@ void machine_halt(void)
 		cpu_relax();
 }
 
-EXPORT_SYMBOL(machine_halt);
-
 void machine_power_off(void)
 {
 	/* M32R_FIXME */
 }
 
-EXPORT_SYMBOL(machine_power_off);
-
 static int __init idle_setup (char *str)
 {
 	if (!strncmp(str, "poll", 4)) {
diff --git a/arch/m32r/kernel/setup.c b/arch/m32r/kernel/setup.c
--- a/arch/m32r/kernel/setup.c
+++ b/arch/m32r/kernel/setup.c
@@ -330,6 +330,8 @@ static int show_cpuinfo(struct seq_file 
 	seq_printf(m, "Machine\t\t: Mappi Evaluation board\n");
 #elif CONFIG_PLAT_MAPPI2
 	seq_printf(m, "Machine\t\t: Mappi-II Evaluation board\n");
+#elif CONFIG_PLAT_MAPPI3
+	seq_printf(m, "Machine\t\t: Mappi-III Evaluation board\n");
 #elif  CONFIG_PLAT_M32700UT
 	seq_printf(m, "Machine\t\t: M32700UT Evaluation board\n");
 #elif  CONFIG_PLAT_OPSPUT
diff --git a/arch/m32r/kernel/setup_m32700ut.c b/arch/m32r/kernel/setup_m32700ut.c
--- a/arch/m32r/kernel/setup_m32700ut.c
+++ b/arch/m32r/kernel/setup_m32700ut.c
@@ -3,8 +3,8 @@
  *
  *  Setup routines for Renesas M32700UT Board
  *
- *  Copyright (c) 2002 	Hiroyuki Kondo, Hirokazu Takata,
- *                      Hitoshi Yamamoto, Takeo Takahashi
+ *  Copyright (c) 2002-2005  Hiroyuki Kondo, Hirokazu Takata,
+ *                           Hitoshi Yamamoto, Takeo Takahashi
  *
  *  This file is subject to the terms and conditions of the GNU General
  *  Public License.  See the file "COPYING" in the main directory of this
@@ -30,9 +30,11 @@
 typedef struct {
 	unsigned long icucr;  /* ICU Control Register */
 } icu_data_t;
+static icu_data_t icu_data[M32700UT_NUM_CPU_IRQ];
+#else
+icu_data_t icu_data[M32700UT_NUM_CPU_IRQ];
 #endif /* CONFIG_SMP */
 
-static icu_data_t icu_data[M32700UT_NUM_CPU_IRQ];
 
 static void disable_m32700ut_irq(unsigned int irq)
 {
@@ -78,13 +80,13 @@ static void shutdown_m32700ut_irq(unsign
 
 static struct hw_interrupt_type m32700ut_irq_type =
 {
-	"M32700UT-IRQ",
-	startup_m32700ut_irq,
-	shutdown_m32700ut_irq,
-	enable_m32700ut_irq,
-	disable_m32700ut_irq,
-	mask_and_ack_m32700ut,
-	end_m32700ut_irq
+	.typename = "M32700UT-IRQ",
+	.startup = startup_m32700ut_irq,
+	.shutdown = shutdown_m32700ut_irq,
+	.enable = enable_m32700ut_irq,
+	.disable = disable_m32700ut_irq,
+	.ack = mask_and_ack_m32700ut,
+	.end = end_m32700ut_irq
 };
 
 /*
@@ -155,13 +157,13 @@ static void shutdown_m32700ut_pld_irq(un
 
 static struct hw_interrupt_type m32700ut_pld_irq_type =
 {
-	"M32700UT-PLD-IRQ",
-	startup_m32700ut_pld_irq,
-	shutdown_m32700ut_pld_irq,
-	enable_m32700ut_pld_irq,
-	disable_m32700ut_pld_irq,
-	mask_and_ack_m32700ut_pld,
-	end_m32700ut_pld_irq
+	.typename = "M32700UT-PLD-IRQ",
+	.startup = startup_m32700ut_pld_irq,
+	.shutdown = shutdown_m32700ut_pld_irq,
+	.enable = enable_m32700ut_pld_irq,
+	.disable = disable_m32700ut_pld_irq,
+	.ack = mask_and_ack_m32700ut_pld,
+	.end = end_m32700ut_pld_irq
 };
 
 /*
@@ -224,13 +226,13 @@ static void shutdown_m32700ut_lanpld_irq
 
 static struct hw_interrupt_type m32700ut_lanpld_irq_type =
 {
-	"M32700UT-PLD-LAN-IRQ",
-	startup_m32700ut_lanpld_irq,
-	shutdown_m32700ut_lanpld_irq,
-	enable_m32700ut_lanpld_irq,
-	disable_m32700ut_lanpld_irq,
-	mask_and_ack_m32700ut_lanpld,
-	end_m32700ut_lanpld_irq
+	.typename = "M32700UT-PLD-LAN-IRQ",
+	.startup = startup_m32700ut_lanpld_irq,
+	.shutdown = shutdown_m32700ut_lanpld_irq,
+	.enable = enable_m32700ut_lanpld_irq,
+	.disable = disable_m32700ut_lanpld_irq,
+	.ack = mask_and_ack_m32700ut_lanpld,
+	.end = end_m32700ut_lanpld_irq
 };
 
 /*
@@ -293,13 +295,13 @@ static void shutdown_m32700ut_lcdpld_irq
 
 static struct hw_interrupt_type m32700ut_lcdpld_irq_type =
 {
-	"M32700UT-PLD-LCD-IRQ",
-	startup_m32700ut_lcdpld_irq,
-	shutdown_m32700ut_lcdpld_irq,
-	enable_m32700ut_lcdpld_irq,
-	disable_m32700ut_lcdpld_irq,
-	mask_and_ack_m32700ut_lcdpld,
-	end_m32700ut_lcdpld_irq
+	.typename = "M32700UT-PLD-LCD-IRQ",
+	.startup = startup_m32700ut_lcdpld_irq,
+	.shutdown = shutdown_m32700ut_lcdpld_irq,
+	.enable = enable_m32700ut_lcdpld_irq,
+	.disable = disable_m32700ut_lcdpld_irq,
+	.ack = mask_and_ack_m32700ut_lcdpld,
+	.end = end_m32700ut_lcdpld_irq
 };
 
 void __init init_IRQ(void)
@@ -435,7 +437,7 @@ void __init init_IRQ(void)
 	icu_data[M32R_IRQ_INT2].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD01;
 	enable_m32700ut_irq(M32R_IRQ_INT2);
 
-//#if defined(CONFIG_VIDEO_M32R_AR)
+#if defined(CONFIG_VIDEO_M32R_AR)
 	/*
 	 * INT3# is used for AR
 	 */
@@ -445,9 +447,11 @@ void __init init_IRQ(void)
 	irq_desc[M32R_IRQ_INT3].depth = 1;
 	icu_data[M32R_IRQ_INT3].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10;
 	disable_m32700ut_irq(M32R_IRQ_INT3);
-//#endif	/* CONFIG_VIDEO_M32R_AR */
+#endif	/* CONFIG_VIDEO_M32R_AR */
 }
 
+#if defined(CONFIG_SMC91X)
+
 #define LAN_IOSTART     0x300
 #define LAN_IOEND       0x320
 static struct resource smc91x_resources[] = {
@@ -469,10 +473,55 @@ static struct platform_device smc91x_dev
 	.num_resources  = ARRAY_SIZE(smc91x_resources),
 	.resource       = smc91x_resources,
 };
+#endif
+
+#if defined(CONFIG_FB_S1D13XXX)
+
+#include <video/s1d13xxxfb.h>
+#include <asm/s1d13806.h>
+
+static struct s1d13xxxfb_pdata s1d13xxxfb_data = {
+	.initregs		= s1d13xxxfb_initregs,
+	.initregssize		= ARRAY_SIZE(s1d13xxxfb_initregs),
+	.platform_init_video	= NULL,
+#ifdef CONFIG_PM
+	.platform_suspend_video	= NULL,
+	.platform_resume_video	= NULL,
+#endif
+};
+
+static struct resource s1d13xxxfb_resources[] = {
+	[0] = {
+		.start  = 0x10600000UL,
+		.end    = 0x1073FFFFUL,
+		.flags  = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start  = 0x10400000UL,
+		.end    = 0x104001FFUL,
+		.flags  = IORESOURCE_MEM,
+	}
+};
+
+static struct platform_device s1d13xxxfb_device = {
+	.name		= S1D_DEVICENAME,
+	.id		= 0,
+	.dev            = {
+		.platform_data  = &s1d13xxxfb_data,
+	},
+	.num_resources  = ARRAY_SIZE(s1d13xxxfb_resources),
+	.resource       = s1d13xxxfb_resources,
+};
+#endif
 
 static int __init platform_init(void)
 {
+#if defined(CONFIG_SMC91X)
 	platform_device_register(&smc91x_device);
+#endif
+#if defined(CONFIG_FB_S1D13XXX)
+	platform_device_register(&s1d13xxxfb_device);
+#endif
 	return 0;
 }
 arch_initcall(platform_init);
diff --git a/arch/m32r/kernel/setup_mappi.c b/arch/m32r/kernel/setup_mappi.c
--- a/arch/m32r/kernel/setup_mappi.c
+++ b/arch/m32r/kernel/setup_mappi.c
@@ -3,14 +3,15 @@
  *
  *  Setup routines for Renesas MAPPI Board
  *
- *  Copyright (c) 2001, 2002  Hiroyuki Kondo, Hirokazu Takata,
- *                            Hitoshi Yamamoto
+ *  Copyright (c) 2001-2005  Hiroyuki Kondo, Hirokazu Takata,
+ *                           Hitoshi Yamamoto
  */
 
 #include <linux/config.h>
 #include <linux/irq.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
+#include <linux/device.h>
 
 #include <asm/system.h>
 #include <asm/m32r.h>
@@ -70,13 +71,13 @@ static void shutdown_mappi_irq(unsigned 
 
 static struct hw_interrupt_type mappi_irq_type =
 {
-	"MAPPI-IRQ",
-	startup_mappi_irq,
-	shutdown_mappi_irq,
-	enable_mappi_irq,
-	disable_mappi_irq,
-	mask_and_ack_mappi,
-	end_mappi_irq
+	.typename = "MAPPI-IRQ",
+	.startup = startup_mappi_irq,
+	.shutdown = shutdown_mappi_irq,
+	.enable = enable_mappi_irq,
+	.disable = disable_mappi_irq,
+	.ack = mask_and_ack_mappi,
+	.end = end_mappi_irq
 };
 
 void __init init_IRQ(void)
@@ -158,3 +159,49 @@ void __init init_IRQ(void)
 	disable_mappi_irq(M32R_IRQ_INT2);
 #endif /* CONFIG_M32RPCC */
 }
+
+#if defined(CONFIG_FB_S1D13XXX)
+
+#include <video/s1d13xxxfb.h>
+#include <asm/s1d13806.h>
+
+static struct s1d13xxxfb_pdata s1d13xxxfb_data = {
+	.initregs		= s1d13xxxfb_initregs,
+	.initregssize		= ARRAY_SIZE(s1d13xxxfb_initregs),
+	.platform_init_video	= NULL,
+#ifdef CONFIG_PM
+	.platform_suspend_video	= NULL,
+	.platform_resume_video	= NULL,
+#endif
+};
+
+static struct resource s1d13xxxfb_resources[] = {
+	[0] = {
+		.start  = 0x10200000UL,
+		.end    = 0x1033FFFFUL,
+		.flags  = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start  = 0x10000000UL,
+		.end    = 0x100001FFUL,
+		.flags  = IORESOURCE_MEM,
+	}
+};
+
+static struct platform_device s1d13xxxfb_device = {
+	.name		= S1D_DEVICENAME,
+	.id		= 0,
+	.dev            = {
+		.platform_data  = &s1d13xxxfb_data,
+	},
+	.num_resources  = ARRAY_SIZE(s1d13xxxfb_resources),
+	.resource       = s1d13xxxfb_resources,
+};
+
+static int __init platform_init(void)
+{
+	platform_device_register(&s1d13xxxfb_device);
+	return 0;
+}
+arch_initcall(platform_init);
+#endif
diff --git a/arch/m32r/kernel/setup_mappi2.c b/arch/m32r/kernel/setup_mappi2.c
--- a/arch/m32r/kernel/setup_mappi2.c
+++ b/arch/m32r/kernel/setup_mappi2.c
@@ -1,10 +1,10 @@
 /*
- *  linux/arch/m32r/kernel/setup_mappi.c
+ *  linux/arch/m32r/kernel/setup_mappi2.c
  *
  *  Setup routines for Renesas MAPPI-II(M3A-ZA36) Board
  *
- *  Copyright (c) 2001, 2002  Hiroyuki Kondo, Hirokazu Takata,
- *                            Hitoshi Yamamoto, Mamoru Sakugawa
+ *  Copyright (c) 2001-2005  Hiroyuki Kondo, Hirokazu Takata,
+ *                           Hitoshi Yamamoto, Mamoru Sakugawa
  */
 
 #include <linux/config.h>
@@ -79,13 +79,13 @@ static void shutdown_mappi2_irq(unsigned
 
 static struct hw_interrupt_type mappi2_irq_type =
 {
-	"MAPPI2-IRQ",
-	startup_mappi2_irq,
-	shutdown_mappi2_irq,
-	enable_mappi2_irq,
-	disable_mappi2_irq,
-	mask_and_ack_mappi2,
-	end_mappi2_irq
+	.typename = "MAPPI2-IRQ",
+	.startup = startup_mappi2_irq,
+	.shutdown = shutdown_mappi2_irq,
+	.enable = enable_mappi2_irq,
+	.disable = disable_mappi2_irq,
+	.ack = mask_and_ack_mappi2,
+	.end = end_mappi2_irq
 };
 
 void __init init_IRQ(void)
@@ -156,7 +156,6 @@ void __init init_IRQ(void)
 	irq_desc[PLD_IRQ_CFIREQ].handler = &mappi2_irq_type;
 	irq_desc[PLD_IRQ_CFIREQ].action = 0;
 	irq_desc[PLD_IRQ_CFIREQ].depth = 1;	/* disable nested irq */
-//	icu_data[PLD_IRQ_CFIREQ].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD00;
 	icu_data[PLD_IRQ_CFIREQ].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD01;
 	disable_mappi2_irq(PLD_IRQ_CFIREQ);
 
@@ -167,7 +166,6 @@ void __init init_IRQ(void)
 	irq_desc[PLD_IRQ_CFC_INSERT].action = 0;
 	irq_desc[PLD_IRQ_CFC_INSERT].depth = 1;	/* disable nested irq */
 	icu_data[PLD_IRQ_CFC_INSERT].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD00;
-//	icu_data[PLD_IRQ_CFC_INSERT].icucr = 0;
 	disable_mappi2_irq(PLD_IRQ_CFC_INSERT);
 
 	/* ICUCR42: CFC Eject */
@@ -176,9 +174,7 @@ void __init init_IRQ(void)
 	irq_desc[PLD_IRQ_CFC_EJECT].action = 0;
 	irq_desc[PLD_IRQ_CFC_EJECT].depth = 1;	/* disable nested irq */
 	icu_data[PLD_IRQ_CFC_EJECT].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10;
-//	icu_data[PLD_IRQ_CFC_EJECT].icucr = 0;
 	disable_mappi2_irq(PLD_IRQ_CFC_EJECT);
-
 #endif /* CONFIG_MAPPI2_CFC */
 }
 
diff --git a/arch/m32r/kernel/setup_mappi3.c b/arch/m32r/kernel/setup_mappi3.c
new file mode 100644
--- /dev/null
+++ b/arch/m32r/kernel/setup_mappi3.c
@@ -0,0 +1,256 @@
+/*
+ *  linux/arch/m32r/kernel/setup_mappi3.c
+ *
+ *  Setup routines for Renesas MAPPI-III(M3A-2170) Board
+ *
+ *  Copyright (c) 2001-2005  Hiroyuki Kondo, Hirokazu Takata,
+ *                           Hitoshi Yamamoto, Mamoru Sakugawa
+ */
+
+#include <linux/config.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/device.h>
+
+#include <asm/system.h>
+#include <asm/m32r.h>
+#include <asm/io.h>
+
+#define irq2port(x) (M32R_ICU_CR1_PORTL + ((x - 1) * sizeof(unsigned long)))
+
+#ifndef CONFIG_SMP
+typedef struct {
+	unsigned long icucr;  /* ICU Control Register */
+} icu_data_t;
+#endif /* CONFIG_SMP */
+
+icu_data_t icu_data[NR_IRQS];
+
+static void disable_mappi3_irq(unsigned int irq)
+{
+	unsigned long port, data;
+
+	if ((irq == 0) ||(irq >= NR_IRQS))  {
+		printk("bad irq 0x%08x\n", irq);
+		return;
+	}
+	port = irq2port(irq);
+	data = icu_data[irq].icucr|M32R_ICUCR_ILEVEL7;
+	outl(data, port);
+}
+
+static void enable_mappi3_irq(unsigned int irq)
+{
+	unsigned long port, data;
+
+	if ((irq == 0) ||(irq >= NR_IRQS))  {
+		printk("bad irq 0x%08x\n", irq);
+		return;
+	}
+	port = irq2port(irq);
+	data = icu_data[irq].icucr|M32R_ICUCR_IEN|M32R_ICUCR_ILEVEL6;
+	outl(data, port);
+}
+
+static void mask_and_ack_mappi3(unsigned int irq)
+{
+	disable_mappi3_irq(irq);
+}
+
+static void end_mappi3_irq(unsigned int irq)
+{
+	enable_mappi3_irq(irq);
+}
+
+static unsigned int startup_mappi3_irq(unsigned int irq)
+{
+	enable_mappi3_irq(irq);
+	return (0);
+}
+
+static void shutdown_mappi3_irq(unsigned int irq)
+{
+	unsigned long port;
+
+	port = irq2port(irq);
+	outl(M32R_ICUCR_ILEVEL7, port);
+}
+
+static struct hw_interrupt_type mappi3_irq_type =
+{
+	.typename = "MAPPI3-IRQ",
+	.startup = startup_mappi3_irq,
+	.shutdown = shutdown_mappi3_irq,
+	.enable = enable_mappi3_irq,
+	.disable = disable_mappi3_irq,
+	.ack = mask_and_ack_mappi3,
+	.end = end_mappi3_irq
+};
+
+void __init init_IRQ(void)
+{
+#if defined(CONFIG_SMC91X)
+	/* INT0 : LAN controller (SMC91111) */
+	irq_desc[M32R_IRQ_INT0].status = IRQ_DISABLED;
+	irq_desc[M32R_IRQ_INT0].handler = &mappi3_irq_type;
+	irq_desc[M32R_IRQ_INT0].action = 0;
+	irq_desc[M32R_IRQ_INT0].depth = 1;
+	icu_data[M32R_IRQ_INT0].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10;
+	disable_mappi3_irq(M32R_IRQ_INT0);
+#endif  /* CONFIG_SMC91X */
+
+	/* MFT2 : system timer */
+	irq_desc[M32R_IRQ_MFT2].status = IRQ_DISABLED;
+	irq_desc[M32R_IRQ_MFT2].handler = &mappi3_irq_type;
+	irq_desc[M32R_IRQ_MFT2].action = 0;
+	irq_desc[M32R_IRQ_MFT2].depth = 1;
+	icu_data[M32R_IRQ_MFT2].icucr = M32R_ICUCR_IEN;
+	disable_mappi3_irq(M32R_IRQ_MFT2);
+
+#ifdef CONFIG_SERIAL_M32R_SIO
+	/* SIO0_R : uart receive data */
+	irq_desc[M32R_IRQ_SIO0_R].status = IRQ_DISABLED;
+	irq_desc[M32R_IRQ_SIO0_R].handler = &mappi3_irq_type;
+	irq_desc[M32R_IRQ_SIO0_R].action = 0;
+	irq_desc[M32R_IRQ_SIO0_R].depth = 1;
+	icu_data[M32R_IRQ_SIO0_R].icucr = 0;
+	disable_mappi3_irq(M32R_IRQ_SIO0_R);
+
+	/* SIO0_S : uart send data */
+	irq_desc[M32R_IRQ_SIO0_S].status = IRQ_DISABLED;
+	irq_desc[M32R_IRQ_SIO0_S].handler = &mappi3_irq_type;
+	irq_desc[M32R_IRQ_SIO0_S].action = 0;
+	irq_desc[M32R_IRQ_SIO0_S].depth = 1;
+	icu_data[M32R_IRQ_SIO0_S].icucr = 0;
+	disable_mappi3_irq(M32R_IRQ_SIO0_S);
+	/* SIO1_R : uart receive data */
+	irq_desc[M32R_IRQ_SIO1_R].status = IRQ_DISABLED;
+	irq_desc[M32R_IRQ_SIO1_R].handler = &mappi3_irq_type;
+	irq_desc[M32R_IRQ_SIO1_R].action = 0;
+	irq_desc[M32R_IRQ_SIO1_R].depth = 1;
+	icu_data[M32R_IRQ_SIO1_R].icucr = 0;
+	disable_mappi3_irq(M32R_IRQ_SIO1_R);
+
+	/* SIO1_S : uart send data */
+	irq_desc[M32R_IRQ_SIO1_S].status = IRQ_DISABLED;
+	irq_desc[M32R_IRQ_SIO1_S].handler = &mappi3_irq_type;
+	irq_desc[M32R_IRQ_SIO1_S].action = 0;
+	irq_desc[M32R_IRQ_SIO1_S].depth = 1;
+	icu_data[M32R_IRQ_SIO1_S].icucr = 0;
+	disable_mappi3_irq(M32R_IRQ_SIO1_S);
+#endif  /* CONFIG_M32R_USE_DBG_CONSOLE */
+
+#if defined(CONFIG_USB)
+	/* INT1 : USB Host controller interrupt */
+	irq_desc[M32R_IRQ_INT1].status = IRQ_DISABLED;
+	irq_desc[M32R_IRQ_INT1].handler = &mappi3_irq_type;
+	irq_desc[M32R_IRQ_INT1].action = 0;
+	irq_desc[M32R_IRQ_INT1].depth = 1;
+	icu_data[M32R_IRQ_INT1].icucr = M32R_ICUCR_ISMOD01;
+	disable_mappi3_irq(M32R_IRQ_INT1);
+#endif /* CONFIG_USB */
+
+	/* ICUCR40: CFC IREQ */
+	irq_desc[PLD_IRQ_CFIREQ].status = IRQ_DISABLED;
+	irq_desc[PLD_IRQ_CFIREQ].handler = &mappi3_irq_type;
+	irq_desc[PLD_IRQ_CFIREQ].action = 0;
+	irq_desc[PLD_IRQ_CFIREQ].depth = 1;	/* disable nested irq */
+	icu_data[PLD_IRQ_CFIREQ].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD01;
+	disable_mappi3_irq(PLD_IRQ_CFIREQ);
+
+#if defined(CONFIG_M32R_CFC)
+	/* ICUCR41: CFC Insert */
+	irq_desc[PLD_IRQ_CFC_INSERT].status = IRQ_DISABLED;
+	irq_desc[PLD_IRQ_CFC_INSERT].handler = &mappi3_irq_type;
+	irq_desc[PLD_IRQ_CFC_INSERT].action = 0;
+	irq_desc[PLD_IRQ_CFC_INSERT].depth = 1;	/* disable nested irq */
+	icu_data[PLD_IRQ_CFC_INSERT].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD00;
+	disable_mappi3_irq(PLD_IRQ_CFC_INSERT);
+
+	/* ICUCR42: CFC Eject */
+	irq_desc[PLD_IRQ_CFC_EJECT].status = IRQ_DISABLED;
+	irq_desc[PLD_IRQ_CFC_EJECT].handler = &mappi3_irq_type;
+	irq_desc[PLD_IRQ_CFC_EJECT].action = 0;
+	irq_desc[PLD_IRQ_CFC_EJECT].depth = 1;	/* disable nested irq */
+	icu_data[PLD_IRQ_CFC_EJECT].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10;
+	disable_mappi3_irq(PLD_IRQ_CFC_EJECT);
+#endif /* CONFIG_M32R_CFC */
+}
+
+#if defined(CONFIG_SMC91X)
+
+#define LAN_IOSTART     0x300
+#define LAN_IOEND       0x320
+static struct resource smc91x_resources[] = {
+	[0] = {
+		.start  = (LAN_IOSTART),
+		.end    = (LAN_IOEND),
+		.flags  = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start  = M32R_IRQ_INT0,
+		.end    = M32R_IRQ_INT0,
+		.flags  = IORESOURCE_IRQ,
+	}
+};
+
+static struct platform_device smc91x_device = {
+	.name		= "smc91x",
+	.id		= 0,
+	.num_resources  = ARRAY_SIZE(smc91x_resources),
+	.resource       = smc91x_resources,
+};
+
+#endif
+
+#if defined(CONFIG_FB_S1D13XXX)
+
+#include <video/s1d13xxxfb.h>
+#include <asm/s1d13806.h>
+
+static struct s1d13xxxfb_pdata s1d13xxxfb_data = {
+	.initregs		= s1d13xxxfb_initregs,
+	.initregssize		= ARRAY_SIZE(s1d13xxxfb_initregs),
+	.platform_init_video	= NULL,
+#ifdef CONFIG_PM
+	.platform_suspend_video	= NULL,
+	.platform_resume_video	= NULL,
+#endif
+};
+
+static struct resource s1d13xxxfb_resources[] = {
+	[0] = {
+		.start  = 0x1d600000UL,
+		.end    = 0x1d73FFFFUL,
+		.flags  = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start  = 0x1d400000UL,
+		.end    = 0x1d4001FFUL,
+		.flags  = IORESOURCE_MEM,
+	}
+};
+
+static struct platform_device s1d13xxxfb_device = {
+	.name		= S1D_DEVICENAME,
+	.id		= 0,
+	.dev            = {
+		.platform_data  = &s1d13xxxfb_data,
+	},
+	.num_resources  = ARRAY_SIZE(s1d13xxxfb_resources),
+	.resource       = s1d13xxxfb_resources,
+};
+#endif
+
+static int __init platform_init(void)
+{
+#if defined(CONFIG_SMC91X)
+	platform_device_register(&smc91x_device);
+#endif
+#if defined(CONFIG_FB_S1D13XXX)
+	platform_device_register(&s1d13xxxfb_device);
+#endif
+	return 0;
+}
+arch_initcall(platform_init);
diff --git a/arch/m32r/kernel/setup_oaks32r.c b/arch/m32r/kernel/setup_oaks32r.c
--- a/arch/m32r/kernel/setup_oaks32r.c
+++ b/arch/m32r/kernel/setup_oaks32r.c
@@ -3,8 +3,8 @@
  *
  *  Setup routines for OAKS32R Board
  *
- *  Copyright (c) 2002-2004   Hiroyuki Kondo, Hirokazu Takata,
- *                            Hitoshi Yamamoto, Mamoru Sakugawa
+ *  Copyright (c) 2002-2005  Hiroyuki Kondo, Hirokazu Takata,
+ *                           Hitoshi Yamamoto, Mamoru Sakugawa
  */
 
 #include <linux/config.h>
@@ -70,13 +70,13 @@ static void shutdown_oaks32r_irq(unsigne
 
 static struct hw_interrupt_type oaks32r_irq_type =
 {
-	"OAKS32R-IRQ",
-	startup_oaks32r_irq,
-	shutdown_oaks32r_irq,
-	enable_oaks32r_irq,
-	disable_oaks32r_irq,
-	mask_and_ack_mappi,
-	end_oaks32r_irq
+	.typename = "OAKS32R-IRQ",
+	.startup = startup_oaks32r_irq,
+	.shutdown = shutdown_oaks32r_irq,
+	.enable = enable_oaks32r_irq,
+	.disable = disable_oaks32r_irq,
+	.ack = mask_and_ack_mappi,
+	.end = end_oaks32r_irq
 };
 
 void __init init_IRQ(void)
@@ -139,5 +139,4 @@ void __init init_IRQ(void)
 	icu_data[M32R_IRQ_SIO1_S].icucr = 0;
 	disable_oaks32r_irq(M32R_IRQ_SIO1_S);
 #endif /* CONFIG_SERIAL_M32R_SIO */
-
 }
diff --git a/arch/m32r/kernel/setup_opsput.c b/arch/m32r/kernel/setup_opsput.c
--- a/arch/m32r/kernel/setup_opsput.c
+++ b/arch/m32r/kernel/setup_opsput.c
@@ -3,7 +3,7 @@
  *
  *  Setup routines for Renesas OPSPUT Board
  *
- *  Copyright (c) 2002-2004
+ *  Copyright (c) 2002-2005
  * 	Hiroyuki Kondo, Hirokazu Takata,
  *      Hitoshi Yamamoto, Takeo Takahashi, Mamoru Sakugawa
  *
@@ -31,9 +31,11 @@
 typedef struct {
 	unsigned long icucr;  /* ICU Control Register */
 } icu_data_t;
+static icu_data_t icu_data[OPSPUT_NUM_CPU_IRQ];
+#else
+icu_data_t icu_data[OPSPUT_NUM_CPU_IRQ];
 #endif /* CONFIG_SMP */
 
-static icu_data_t icu_data[OPSPUT_NUM_CPU_IRQ];
 
 static void disable_opsput_irq(unsigned int irq)
 {
@@ -79,13 +81,13 @@ static void shutdown_opsput_irq(unsigned
 
 static struct hw_interrupt_type opsput_irq_type =
 {
-	"OPSPUT-IRQ",
-	startup_opsput_irq,
-	shutdown_opsput_irq,
-	enable_opsput_irq,
-	disable_opsput_irq,
-	mask_and_ack_opsput,
-	end_opsput_irq
+	.typename = "OPSPUT-IRQ",
+	.startup = startup_opsput_irq,
+	.shutdown = shutdown_opsput_irq,
+	.enable = enable_opsput_irq,
+	.disable = disable_opsput_irq,
+	.ack = mask_and_ack_opsput,
+	.end = end_opsput_irq
 };
 
 /*
@@ -156,13 +158,13 @@ static void shutdown_opsput_pld_irq(unsi
 
 static struct hw_interrupt_type opsput_pld_irq_type =
 {
-	"OPSPUT-PLD-IRQ",
-	startup_opsput_pld_irq,
-	shutdown_opsput_pld_irq,
-	enable_opsput_pld_irq,
-	disable_opsput_pld_irq,
-	mask_and_ack_opsput_pld,
-	end_opsput_pld_irq
+	.typename = "OPSPUT-PLD-IRQ",
+	.startup = startup_opsput_pld_irq,
+	.shutdown = shutdown_opsput_pld_irq,
+	.enable = enable_opsput_pld_irq,
+	.disable = disable_opsput_pld_irq,
+	.ack = mask_and_ack_opsput_pld,
+	.end = end_opsput_pld_irq
 };
 
 /*
@@ -439,7 +441,7 @@ void __init init_IRQ(void)
 	icu_data[M32R_IRQ_INT2].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD01;
 	enable_opsput_irq(M32R_IRQ_INT2);
 
-//#if defined(CONFIG_VIDEO_M32R_AR)
+#if defined(CONFIG_VIDEO_M32R_AR)
 	/*
 	 * INT3# is used for AR
 	 */
@@ -449,9 +451,11 @@ void __init init_IRQ(void)
 	irq_desc[M32R_IRQ_INT3].depth = 1;
 	icu_data[M32R_IRQ_INT3].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10;
 	disable_opsput_irq(M32R_IRQ_INT3);
-//#endif	/* CONFIG_VIDEO_M32R_AR */
+#endif /* CONFIG_VIDEO_M32R_AR */
 }
 
+#if defined(CONFIG_SMC91X)
+
 #define LAN_IOSTART     0x300
 #define LAN_IOEND       0x320
 static struct resource smc91x_resources[] = {
@@ -473,10 +477,55 @@ static struct platform_device smc91x_dev
 	.num_resources  = ARRAY_SIZE(smc91x_resources),
 	.resource       = smc91x_resources,
 };
+#endif
+
+#if defined(CONFIG_FB_S1D13XXX)
+
+#include <video/s1d13xxxfb.h>
+#include <asm/s1d13806.h>
+
+static struct s1d13xxxfb_pdata s1d13xxxfb_data = {
+	.initregs		= s1d13xxxfb_initregs,
+	.initregssize		= ARRAY_SIZE(s1d13xxxfb_initregs),
+	.platform_init_video	= NULL,
+#ifdef CONFIG_PM
+	.platform_suspend_video	= NULL,
+	.platform_resume_video	= NULL,
+#endif
+};
+
+static struct resource s1d13xxxfb_resources[] = {
+	[0] = {
+		.start  = 0x10600000UL,
+		.end    = 0x1073FFFFUL,
+		.flags  = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start  = 0x10400000UL,
+		.end    = 0x104001FFUL,
+		.flags  = IORESOURCE_MEM,
+	}
+};
+
+static struct platform_device s1d13xxxfb_device = {
+	.name		= S1D_DEVICENAME,
+	.id		= 0,
+	.dev            = {
+		.platform_data  = &s1d13xxxfb_data,
+	},
+	.num_resources  = ARRAY_SIZE(s1d13xxxfb_resources),
+	.resource       = s1d13xxxfb_resources,
+};
+#endif
 
 static int __init platform_init(void)
 {
+#if defined(CONFIG_SMC91X)
 	platform_device_register(&smc91x_device);
+#endif
+#if defined(CONFIG_FB_S1D13XXX)
+	platform_device_register(&s1d13xxxfb_device);
+#endif
 	return 0;
 }
 arch_initcall(platform_init);
diff --git a/arch/m32r/kernel/setup_usrv.c b/arch/m32r/kernel/setup_usrv.c
--- a/arch/m32r/kernel/setup_usrv.c
+++ b/arch/m32r/kernel/setup_usrv.c
@@ -70,13 +70,13 @@ static void shutdown_mappi_irq(unsigned 
 
 static struct hw_interrupt_type mappi_irq_type =
 {
-	"M32700-IRQ",
-	startup_mappi_irq,
-	shutdown_mappi_irq,
-	enable_mappi_irq,
-	disable_mappi_irq,
-	mask_and_ack_mappi,
-	end_mappi_irq
+	.typename = "M32700-IRQ",
+	.startup = startup_mappi_irq,
+	.shutdown = shutdown_mappi_irq,
+	.enable = enable_mappi_irq,
+	.disable = disable_mappi_irq,
+	.ack = mask_and_ack_mappi,
+	.end = end_mappi_irq
 };
 
 /*
@@ -143,13 +143,13 @@ static void shutdown_m32700ut_pld_irq(un
 
 static struct hw_interrupt_type m32700ut_pld_irq_type =
 {
-	"USRV-PLD-IRQ",
-	startup_m32700ut_pld_irq,
-	shutdown_m32700ut_pld_irq,
-	enable_m32700ut_pld_irq,
-	disable_m32700ut_pld_irq,
-	mask_and_ack_m32700ut_pld,
-	end_m32700ut_pld_irq
+	.typename = "USRV-PLD-IRQ",
+	.startup = startup_m32700ut_pld_irq,
+	.shutdown = shutdown_m32700ut_pld_irq,
+	.enable = enable_m32700ut_pld_irq,
+	.disable = disable_m32700ut_pld_irq,
+	.ack = mask_and_ack_m32700ut_pld,
+	.end = end_m32700ut_pld_irq
 };
 
 void __init init_IRQ(void)
diff --git a/arch/m32r/kernel/signal.c b/arch/m32r/kernel/signal.c
--- a/arch/m32r/kernel/signal.c
+++ b/arch/m32r/kernel/signal.c
@@ -371,10 +371,8 @@ int do_signal(struct pt_regs *regs, sigs
 	if (!user_mode(regs))
 		return 1;
 
-	if (current->flags & PF_FREEZE) {
-		refrigerator(0);
+	if (try_to_freeze()) 
 		goto no_signal;
-	}
 
 	if (!oldset)
 		oldset = &current->blocked;
diff --git a/arch/m32r/kernel/smpboot.c b/arch/m32r/kernel/smpboot.c
--- a/arch/m32r/kernel/smpboot.c
+++ b/arch/m32r/kernel/smpboot.c
@@ -91,6 +91,7 @@ extern struct {
 
 /* which physical physical ID maps to which logical CPU number */
 static volatile int physid_2_cpu[NR_CPUS];
+#define physid_to_cpu(physid)	physid_2_cpu[physid]
 
 /* which logical CPU number maps to which physical ID */
 volatile int cpu_2_physid[NR_CPUS];
diff --git a/arch/m32r/kernel/time.c b/arch/m32r/kernel/time.c
--- a/arch/m32r/kernel/time.c
+++ b/arch/m32r/kernel/time.c
@@ -205,8 +205,7 @@ static long last_rtc_update = 0;
  * timer_interrupt() needs to keep up the real-time clock,
  * as well as call the "do_timer()" routine every clocktick
  */
-static inline void
-do_timer_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 #ifndef CONFIG_SMP
 	profile_tick(CPU_PROFILING, regs);
@@ -221,6 +220,7 @@ do_timer_interrupt(int irq, void *dev_id
 	 * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
 	 * called as close as possible to 500 ms before the new second starts.
 	 */
+	write_seqlock(&xtime_lock);
 	if ((time_status & STA_UNSYNC) == 0
 		&& xtime.tv_sec > last_rtc_update + 660
 		&& (xtime.tv_nsec / 1000) >= 500000 - ((unsigned)TICK_SIZE) / 2
@@ -231,6 +231,7 @@ do_timer_interrupt(int irq, void *dev_id
 		else	/* do it again in 60 s */
 			last_rtc_update = xtime.tv_sec - 600;
 	}
+	write_sequnlock(&xtime_lock);
 	/* As we return to user mode fire off the other CPU schedulers..
 	   this is basically because we don't yet share IRQ's around.
 	   This message is rigged to be safe on the 386 - basically it's
@@ -238,14 +239,8 @@ do_timer_interrupt(int irq, void *dev_id
 
 #ifdef CONFIG_SMP
 	smp_local_timer_interrupt(regs);
+	smp_send_timer();
 #endif
-}
-
-irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
-	write_seqlock(&xtime_lock);
-	do_timer_interrupt(irq, NULL, regs);
-	write_sequnlock(&xtime_lock);
 
 	return IRQ_HANDLED;
 }
diff --git a/arch/m32r/lib/csum_partial_copy.c b/arch/m32r/lib/csum_partial_copy.c
--- a/arch/m32r/lib/csum_partial_copy.c
+++ b/arch/m32r/lib/csum_partial_copy.c
@@ -58,3 +58,4 @@ csum_partial_copy_from_user (const unsig
 	return csum_partial(dst, len-missing, sum);
 }
 EXPORT_SYMBOL(csum_partial_copy_from_user);
+EXPORT_SYMBOL(csum_partial);
diff --git a/arch/m32r/m32700ut/defconfig.m32700ut.smp b/arch/m32r/m32700ut/defconfig.m32700ut.smp
--- a/arch/m32r/m32700ut/defconfig.m32700ut.smp
+++ b/arch/m32r/m32700ut/defconfig.m32700ut.smp
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc4
-# Wed Feb 16 21:10:50 2005
+# Linux kernel version: 2.6.12-rc5
+# Fri Jun  3 16:20:58 2005
 #
 CONFIG_M32R=y
 # CONFIG_UID16 is not set
@@ -15,6 +15,7 @@ CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_EXPERIMENTAL=y
 CONFIG_CLEAN_COMPILE=y
 CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
@@ -27,13 +28,16 @@ CONFIG_BSD_PROCESS_ACCT=y
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=15
 CONFIG_HOTPLUG=y
 CONFIG_KOBJECT_UEVENT=y
 CONFIG_IKCONFIG=y
 # CONFIG_IKCONFIG_PROC is not set
+# CONFIG_CPUSETS is not set
 CONFIG_EMBEDDED=y
 # CONFIG_KALLSYMS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
 # CONFIG_FUTEX is not set
 # CONFIG_EPOLL is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -43,6 +47,7 @@ CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
 # CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
 
 #
 # Loadable module support
@@ -65,6 +70,7 @@ CONFIG_PLAT_M32700UT=y
 # CONFIG_PLAT_OPSPUT is not set
 # CONFIG_PLAT_OAKS32R is not set
 # CONFIG_PLAT_MAPPI2 is not set
+# CONFIG_PLAT_MAPPI3 is not set
 CONFIG_CHIP_M32700=y
 # CONFIG_CHIP_M32102 is not set
 # CONFIG_CHIP_VDEC2 is not set
@@ -271,7 +277,6 @@ CONFIG_NET=y
 #
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK_DEV is not set
 CONFIG_UNIX=y
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
@@ -396,18 +401,6 @@ CONFIG_INPUT=y
 # CONFIG_INPUT_EVBUG is not set
 
 #
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-# CONFIG_SERIO_RAW is not set
-
-#
 # Input Device Drivers
 #
 # CONFIG_INPUT_KEYBOARD is not set
@@ -417,6 +410,17 @@ CONFIG_SERIO_SERPORT=y
 # CONFIG_INPUT_MISC is not set
 
 #
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_LIBPS2 is not set
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+
+#
 # Character devices
 #
 CONFIG_VT=y
@@ -468,6 +472,10 @@ CONFIG_DS1302=y
 # CONFIG_RAW_DRIVER is not set
 
 #
+# TPM devices
+#
+
+#
 # I2C support
 #
 # CONFIG_I2C is not set
@@ -511,8 +519,14 @@ CONFIG_VIDEO_M32R_AR_M64278=y
 # Graphics support
 #
 CONFIG_FB=y
+# CONFIG_FB_CFB_FILLRECT is not set
+# CONFIG_FB_CFB_COPYAREA is not set
+# CONFIG_FB_CFB_IMAGEBLIT is not set
+# CONFIG_FB_SOFT_CURSOR is not set
+# CONFIG_FB_MACMODES is not set
 # CONFIG_FB_MODE_HELPERS is not set
 # CONFIG_FB_TILEBLITTING is not set
+# CONFIG_FB_S1D13XXX is not set
 # CONFIG_FB_VIRTUAL is not set
 
 #
@@ -546,10 +560,6 @@ CONFIG_LOGO_LINUX_CLUT224=y
 # CONFIG_USB_ARCH_HAS_OHCI is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
-
-#
 # USB Gadget Support
 #
 # CONFIG_USB_GADGET is not set
@@ -722,8 +732,9 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 #
 # Kernel hacking
 #
+# CONFIG_PRINTK_TIME is not set
 # CONFIG_DEBUG_KERNEL is not set
-CONFIG_DEBUG_PREEMPT=y
+CONFIG_LOG_BUF_SHIFT=15
 # CONFIG_DEBUG_BUGVERBOSE is not set
 # CONFIG_FRAME_POINTER is not set
 
diff --git a/arch/m32r/m32700ut/defconfig.m32700ut.up b/arch/m32r/m32700ut/defconfig.m32700ut.up
--- a/arch/m32r/m32700ut/defconfig.m32700ut.up
+++ b/arch/m32r/m32700ut/defconfig.m32700ut.up
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc4
-# Wed Feb 16 21:10:54 2005
+# Linux kernel version: 2.6.12-rc5
+# Fri Jun  3 16:21:34 2005
 #
 CONFIG_M32R=y
 # CONFIG_UID16 is not set
@@ -16,6 +16,7 @@ CONFIG_EXPERIMENTAL=y
 CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
 CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
@@ -28,13 +29,15 @@ CONFIG_BSD_PROCESS_ACCT=y
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
 CONFIG_HOTPLUG=y
 CONFIG_KOBJECT_UEVENT=y
 CONFIG_IKCONFIG=y
 # CONFIG_IKCONFIG_PROC is not set
 CONFIG_EMBEDDED=y
 # CONFIG_KALLSYMS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
 # CONFIG_FUTEX is not set
 # CONFIG_EPOLL is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -44,6 +47,7 @@ CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
 # CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
 
 #
 # Loadable module support
@@ -65,6 +69,7 @@ CONFIG_PLAT_M32700UT=y
 # CONFIG_PLAT_OPSPUT is not set
 # CONFIG_PLAT_OAKS32R is not set
 # CONFIG_PLAT_MAPPI2 is not set
+# CONFIG_PLAT_MAPPI3 is not set
 CONFIG_CHIP_M32700=y
 # CONFIG_CHIP_M32102 is not set
 # CONFIG_CHIP_VDEC2 is not set
@@ -268,7 +273,6 @@ CONFIG_NET=y
 #
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK_DEV is not set
 CONFIG_UNIX=y
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
@@ -393,18 +397,6 @@ CONFIG_INPUT=y
 # CONFIG_INPUT_EVBUG is not set
 
 #
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-# CONFIG_SERIO_RAW is not set
-
-#
 # Input Device Drivers
 #
 # CONFIG_INPUT_KEYBOARD is not set
@@ -414,6 +406,17 @@ CONFIG_SERIO_SERPORT=y
 # CONFIG_INPUT_MISC is not set
 
 #
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_LIBPS2 is not set
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+
+#
 # Character devices
 #
 CONFIG_VT=y
@@ -465,6 +468,10 @@ CONFIG_DS1302=y
 # CONFIG_RAW_DRIVER is not set
 
 #
+# TPM devices
+#
+
+#
 # I2C support
 #
 # CONFIG_I2C is not set
@@ -508,8 +515,14 @@ CONFIG_VIDEO_M32R_AR_M64278=y
 # Graphics support
 #
 CONFIG_FB=y
+# CONFIG_FB_CFB_FILLRECT is not set
+# CONFIG_FB_CFB_COPYAREA is not set
+# CONFIG_FB_CFB_IMAGEBLIT is not set
+# CONFIG_FB_SOFT_CURSOR is not set
+# CONFIG_FB_MACMODES is not set
 # CONFIG_FB_MODE_HELPERS is not set
 # CONFIG_FB_TILEBLITTING is not set
+# CONFIG_FB_S1D13XXX is not set
 # CONFIG_FB_VIRTUAL is not set
 
 #
@@ -543,10 +556,6 @@ CONFIG_LOGO_LINUX_CLUT224=y
 # CONFIG_USB_ARCH_HAS_OHCI is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
-
-#
 # USB Gadget Support
 #
 # CONFIG_USB_GADGET is not set
@@ -719,8 +728,9 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 #
 # Kernel hacking
 #
+# CONFIG_PRINTK_TIME is not set
 # CONFIG_DEBUG_KERNEL is not set
-CONFIG_DEBUG_PREEMPT=y
+CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_DEBUG_BUGVERBOSE is not set
 # CONFIG_FRAME_POINTER is not set
 
diff --git a/arch/m32r/mappi/defconfig.nommu b/arch/m32r/mappi/defconfig.nommu
--- a/arch/m32r/mappi/defconfig.nommu
+++ b/arch/m32r/mappi/defconfig.nommu
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc4
-# Wed Feb 16 21:10:57 2005
+# Linux kernel version: 2.6.12-rc5
+# Fri Jun  3 16:21:46 2005
 #
 CONFIG_M32R=y
 # CONFIG_UID16 is not set
@@ -16,6 +16,7 @@ CONFIG_EXPERIMENTAL=y
 CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
 CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
@@ -26,13 +27,15 @@ CONFIG_BSD_PROCESS_ACCT=y
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
 CONFIG_HOTPLUG=y
 CONFIG_KOBJECT_UEVENT=y
 CONFIG_IKCONFIG=y
 # CONFIG_IKCONFIG_PROC is not set
 CONFIG_EMBEDDED=y
 # CONFIG_KALLSYMS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
 # CONFIG_FUTEX is not set
 # CONFIG_EPOLL is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -41,6 +44,7 @@ CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
 CONFIG_TINY_SHMEM=y
+CONFIG_BASE_SMALL=0
 
 #
 # Loadable module support
@@ -62,6 +66,7 @@ CONFIG_PLAT_MAPPI=y
 # CONFIG_PLAT_OPSPUT is not set
 # CONFIG_PLAT_OAKS32R is not set
 # CONFIG_PLAT_MAPPI2 is not set
+# CONFIG_PLAT_MAPPI3 is not set
 CONFIG_CHIP_M32700=y
 # CONFIG_CHIP_M32102 is not set
 # CONFIG_CHIP_VDEC2 is not set
@@ -202,7 +207,6 @@ CONFIG_NET=y
 #
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK_DEV is not set
 CONFIG_UNIX=y
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
@@ -325,18 +329,6 @@ CONFIG_INPUT=y
 # CONFIG_INPUT_EVBUG is not set
 
 #
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-# CONFIG_SERIO_RAW is not set
-
-#
 # Input Device Drivers
 #
 # CONFIG_INPUT_KEYBOARD is not set
@@ -346,6 +338,17 @@ CONFIG_SERIO_SERPORT=y
 # CONFIG_INPUT_MISC is not set
 
 #
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_LIBPS2 is not set
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+
+#
 # Character devices
 #
 # CONFIG_VT is not set
@@ -394,6 +397,10 @@ CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_RAW_DRIVER is not set
 
 #
+# TPM devices
+#
+
+#
 # I2C support
 #
 # CONFIG_I2C is not set
@@ -434,10 +441,6 @@ CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_USB_ARCH_HAS_OHCI is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
-
-#
 # USB Gadget Support
 #
 # CONFIG_USB_GADGET is not set
@@ -595,8 +598,9 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 #
 # Kernel hacking
 #
+# CONFIG_PRINTK_TIME is not set
 # CONFIG_DEBUG_KERNEL is not set
-CONFIG_DEBUG_PREEMPT=y
+CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_DEBUG_BUGVERBOSE is not set
 # CONFIG_FRAME_POINTER is not set
 
diff --git a/arch/m32r/mappi/defconfig.smp b/arch/m32r/mappi/defconfig.smp
--- a/arch/m32r/mappi/defconfig.smp
+++ b/arch/m32r/mappi/defconfig.smp
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc4
-# Wed Feb 16 21:11:02 2005
+# Linux kernel version: 2.6.12-rc5
+# Fri Jun  3 16:21:52 2005
 #
 CONFIG_M32R=y
 # CONFIG_UID16 is not set
@@ -17,6 +17,7 @@ CONFIG_EXPERIMENTAL=y
 CONFIG_BROKEN=y
 CONFIG_BROKEN_ON_SMP=y
 CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
@@ -28,13 +29,16 @@ CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=15
 CONFIG_HOTPLUG=y
 CONFIG_KOBJECT_UEVENT=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
+# CONFIG_CPUSETS is not set
 CONFIG_EMBEDDED=y
 # CONFIG_KALLSYMS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
 # CONFIG_FUTEX is not set
 # CONFIG_EPOLL is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -44,6 +48,7 @@ CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
 # CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
 
 #
 # Loadable module support
@@ -66,6 +71,7 @@ CONFIG_PLAT_MAPPI=y
 # CONFIG_PLAT_OPSPUT is not set
 # CONFIG_PLAT_OAKS32R is not set
 # CONFIG_PLAT_MAPPI2 is not set
+# CONFIG_PLAT_MAPPI3 is not set
 CONFIG_CHIP_M32700=y
 # CONFIG_CHIP_M32102 is not set
 # CONFIG_CHIP_VDEC2 is not set
@@ -139,8 +145,8 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 #
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
-CONFIG_MTD_PARTITIONS=y
 # CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_REDBOOT_PARTS=y
 CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
 # CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set
@@ -294,7 +300,6 @@ CONFIG_NET=y
 # Networking options
 #
 # CONFIG_PACKET is not set
-# CONFIG_NETLINK_DEV is not set
 CONFIG_UNIX=y
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
@@ -420,18 +425,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 # CONFIG_INPUT_EVBUG is not set
 
 #
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-# CONFIG_SERIO_SERPORT is not set
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-# CONFIG_SERIO_RAW is not set
-
-#
 # Input Device Drivers
 #
 # CONFIG_INPUT_KEYBOARD is not set
@@ -441,6 +434,17 @@ CONFIG_SERIO=y
 # CONFIG_INPUT_MISC is not set
 
 #
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+# CONFIG_SERIO_SERPORT is not set
+# CONFIG_SERIO_LIBPS2 is not set
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+
+#
 # Character devices
 #
 # CONFIG_VT is not set
@@ -489,6 +493,10 @@ CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_RAW_DRIVER is not set
 
 #
+# TPM devices
+#
+
+#
 # I2C support
 #
 # CONFIG_I2C is not set
@@ -529,10 +537,6 @@ CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_USB_ARCH_HAS_OHCI is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
-
-#
 # USB Gadget Support
 #
 # CONFIG_USB_GADGET is not set
@@ -708,8 +712,9 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 #
 # Kernel hacking
 #
+# CONFIG_PRINTK_TIME is not set
 # CONFIG_DEBUG_KERNEL is not set
-CONFIG_DEBUG_PREEMPT=y
+CONFIG_LOG_BUF_SHIFT=15
 # CONFIG_DEBUG_BUGVERBOSE is not set
 # CONFIG_FRAME_POINTER is not set
 
diff --git a/arch/m32r/mappi/defconfig.up b/arch/m32r/mappi/defconfig.up
--- a/arch/m32r/mappi/defconfig.up
+++ b/arch/m32r/mappi/defconfig.up
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc4
-# Wed Feb 16 21:11:07 2005
+# Linux kernel version: 2.6.12-rc5
+# Fri Jun  3 16:21:59 2005
 #
 CONFIG_M32R=y
 # CONFIG_UID16 is not set
@@ -17,6 +17,7 @@ CONFIG_EXPERIMENTAL=y
 CONFIG_BROKEN=y
 CONFIG_BROKEN_ON_SMP=y
 CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
@@ -28,13 +29,15 @@ CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
 CONFIG_HOTPLUG=y
 CONFIG_KOBJECT_UEVENT=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_EMBEDDED=y
 # CONFIG_KALLSYMS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
 # CONFIG_FUTEX is not set
 # CONFIG_EPOLL is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -44,6 +47,7 @@ CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
 # CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
 
 #
 # Loadable module support
@@ -65,6 +69,7 @@ CONFIG_PLAT_MAPPI=y
 # CONFIG_PLAT_OPSPUT is not set
 # CONFIG_PLAT_OAKS32R is not set
 # CONFIG_PLAT_MAPPI2 is not set
+# CONFIG_PLAT_MAPPI3 is not set
 CONFIG_CHIP_M32700=y
 # CONFIG_CHIP_M32102 is not set
 # CONFIG_CHIP_VDEC2 is not set
@@ -135,8 +140,8 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 #
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
-CONFIG_MTD_PARTITIONS=y
 # CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_REDBOOT_PARTS=y
 CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
 # CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set
@@ -290,7 +295,6 @@ CONFIG_NET=y
 # Networking options
 #
 # CONFIG_PACKET is not set
-# CONFIG_NETLINK_DEV is not set
 CONFIG_UNIX=y
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
@@ -416,18 +420,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 # CONFIG_INPUT_EVBUG is not set
 
 #
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-# CONFIG_SERIO_SERPORT is not set
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-# CONFIG_SERIO_RAW is not set
-
-#
 # Input Device Drivers
 #
 # CONFIG_INPUT_KEYBOARD is not set
@@ -437,6 +429,17 @@ CONFIG_SERIO=y
 # CONFIG_INPUT_MISC is not set
 
 #
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+# CONFIG_SERIO_SERPORT is not set
+# CONFIG_SERIO_LIBPS2 is not set
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+
+#
 # Character devices
 #
 # CONFIG_VT is not set
@@ -485,6 +488,10 @@ CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_RAW_DRIVER is not set
 
 #
+# TPM devices
+#
+
+#
 # I2C support
 #
 # CONFIG_I2C is not set
@@ -525,10 +532,6 @@ CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_USB_ARCH_HAS_OHCI is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
-
-#
 # USB Gadget Support
 #
 # CONFIG_USB_GADGET is not set
@@ -704,8 +707,9 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 #
 # Kernel hacking
 #
+# CONFIG_PRINTK_TIME is not set
 # CONFIG_DEBUG_KERNEL is not set
-CONFIG_DEBUG_PREEMPT=y
+CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_DEBUG_BUGVERBOSE is not set
 # CONFIG_FRAME_POINTER is not set
 
diff --git a/arch/m32r/mappi2/defconfig.vdec2 b/arch/m32r/mappi2/defconfig.vdec2
--- a/arch/m32r/mappi2/defconfig.vdec2
+++ b/arch/m32r/mappi2/defconfig.vdec2
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc4
-# Wed Feb 16 21:11:10 2005
+# Linux kernel version: 2.6.12-rc5
+# Fri Jun  3 16:22:02 2005
 #
 CONFIG_M32R=y
 # CONFIG_UID16 is not set
@@ -16,6 +16,7 @@ CONFIG_EXPERIMENTAL=y
 CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
 CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
@@ -28,13 +29,15 @@ CONFIG_BSD_PROCESS_ACCT=y
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
 CONFIG_HOTPLUG=y
 CONFIG_KOBJECT_UEVENT=y
 CONFIG_IKCONFIG=y
 # CONFIG_IKCONFIG_PROC is not set
 CONFIG_EMBEDDED=y
 # CONFIG_KALLSYMS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
 # CONFIG_FUTEX is not set
 # CONFIG_EPOLL is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -44,6 +47,7 @@ CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
 # CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
 
 #
 # Loadable module support
@@ -65,6 +69,7 @@ CONFIG_KMOD=y
 # CONFIG_PLAT_OPSPUT is not set
 # CONFIG_PLAT_OAKS32R is not set
 CONFIG_PLAT_MAPPI2=y
+# CONFIG_PLAT_MAPPI3 is not set
 # CONFIG_CHIP_M32700 is not set
 # CONFIG_CHIP_M32102 is not set
 CONFIG_CHIP_VDEC2=y
@@ -264,7 +269,6 @@ CONFIG_NET=y
 #
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK_DEV is not set
 CONFIG_UNIX=y
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
@@ -389,18 +393,6 @@ CONFIG_INPUT=y
 # CONFIG_INPUT_EVBUG is not set
 
 #
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-# CONFIG_SERIO_RAW is not set
-
-#
 # Input Device Drivers
 #
 # CONFIG_INPUT_KEYBOARD is not set
@@ -410,6 +402,17 @@ CONFIG_SERIO_SERPORT=y
 # CONFIG_INPUT_MISC is not set
 
 #
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_LIBPS2 is not set
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+
+#
 # Character devices
 #
 CONFIG_VT=y
@@ -460,6 +463,10 @@ CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_RAW_DRIVER is not set
 
 #
+# TPM devices
+#
+
+#
 # I2C support
 #
 # CONFIG_I2C is not set
@@ -521,10 +528,6 @@ CONFIG_DUMMY_CONSOLE=y
 # CONFIG_USB_ARCH_HAS_OHCI is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
-
-#
 # USB Gadget Support
 #
 # CONFIG_USB_GADGET is not set
@@ -697,8 +700,9 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 #
 # Kernel hacking
 #
+# CONFIG_PRINTK_TIME is not set
 # CONFIG_DEBUG_KERNEL is not set
-CONFIG_DEBUG_PREEMPT=y
+CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_DEBUG_BUGVERBOSE is not set
 # CONFIG_FRAME_POINTER is not set
 
diff --git a/arch/m32r/mappi3/defconfig.smp b/arch/m32r/mappi3/defconfig.smp
new file mode 100644
--- /dev/null
+++ b/arch/m32r/mappi3/defconfig.smp
@@ -0,0 +1,751 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.12-rc5
+# Tue May 31 17:55:34 2005
+#
+CONFIG_M32R=y
+# CONFIG_UID16 is not set
+CONFIG_GENERIC_ISA_DMA=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+# CONFIG_CLEAN_COMPILE is not set
+CONFIG_BROKEN=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+# CONFIG_CPUSETS is not set
+CONFIG_EMBEDDED=y
+# CONFIG_KALLSYMS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+# CONFIG_FUTEX is not set
+# CONFIG_EPOLL is not set
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+CONFIG_STOP_MACHINE=y
+
+#
+# Processor type and features
+#
+# CONFIG_PLAT_MAPPI is not set
+# CONFIG_PLAT_USRV is not set
+# CONFIG_PLAT_M32700UT is not set
+# CONFIG_PLAT_OPSPUT is not set
+# CONFIG_PLAT_OAKS32R is not set
+# CONFIG_PLAT_MAPPI2 is not set
+CONFIG_PLAT_MAPPI3=y
+CONFIG_CHIP_M32700=y
+# CONFIG_CHIP_M32102 is not set
+# CONFIG_CHIP_VDEC2 is not set
+# CONFIG_CHIP_OPSP is not set
+CONFIG_MMU=y
+CONFIG_TLB_ENTRIES=32
+CONFIG_ISA_M32R2=y
+CONFIG_ISA_DSP_LEVEL2=y
+CONFIG_ISA_DUAL_ISSUE=y
+CONFIG_BUS_CLOCK=10000000
+CONFIG_TIMER_DIVIDE=128
+# CONFIG_CPU_LITTLE_ENDIAN is not set
+CONFIG_MEMORY_START=0x08000000
+CONFIG_MEMORY_SIZE=0x08000000
+CONFIG_NOHIGHMEM=y
+CONFIG_DISCONTIGMEM=y
+CONFIG_IRAM_START=0x00f00000
+CONFIG_IRAM_SIZE=0x00080000
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_PREEMPT=y
+# CONFIG_HAVE_DEC_LOCK is not set
+CONFIG_SMP=y
+# CONFIG_CHIP_M32700_TS1 is not set
+CONFIG_NR_CPUS=2
+# CONFIG_NUMA is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
+#
+# CONFIG_PCI is not set
+# CONFIG_ISA is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+CONFIG_PCCARD=y
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_PCMCIA=y
+
+#
+# PC-card bridges
+#
+# CONFIG_TCIC is not set
+# CONFIG_M32R_PCC is not set
+# CONFIG_M32R_CFC is not set
+
+#
+# PCI Hotplug Support
+#
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_REDBOOT_PARTS=y
+CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
+# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set
+# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CDROM_PKTCDVD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_AS is not set
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+CONFIG_BLK_DEV_IDECS=y
+CONFIG_BLK_DEV_IDECD=m
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+# CONFIG_IDE_ARM is not set
+# CONFIG_BLK_DEV_IDEDMA is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+# CONFIG_SCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+
+#
+# Networking support
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_PACKET is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_IP_TCPDIAG=y
+# CONFIG_IP_TCPDIAG_IPV6 is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_SMC91X=y
+# CONFIG_NE2000 is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+
+#
+# Ethernet (10000 Mbit)
+#
+
+#
+# Token Ring devices
+#
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# PCMCIA network device support
+#
+# CONFIG_NET_PCMCIA is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+# CONFIG_SERIO_SERPORT is not set
+# CONFIG_SERIO_LIBPS2 is not set
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_SERIAL_M32R_SIO=y
+CONFIG_SERIAL_M32R_SIO_CONSOLE=y
+# CONFIG_SERIAL_M32R_PLDSIO is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_DRM is not set
+
+#
+# PCMCIA character devices
+#
+# CONFIG_SYNCLINK_CS is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB_ARCH_HAS_HCD is not set
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+
+#
+# XFS support
+#
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+CONFIG_ROMFS_FS=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=y
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+CONFIG_DEVFS_FS=y
+CONFIG_DEVFS_MOUNT=y
+# CONFIG_DEVFS_DEBUG is not set
+# CONFIG_DEVPTS_FS_XATTR is not set
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_XATTR is not set
+# CONFIG_HUGETLBFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS_FS=y
+CONFIG_JFFS_FS_VERBOSE=0
+CONFIG_JFFS_PROC_FS=y
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+# CONFIG_JFFS2_FS_NAND is not set
+# CONFIG_JFFS2_FS_NOR_ECC is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=15
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_FRAME_POINTER is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
diff --git a/arch/m32r/mappi3/dot.gdbinit b/arch/m32r/mappi3/dot.gdbinit
new file mode 100644
--- /dev/null
+++ b/arch/m32r/mappi3/dot.gdbinit
@@ -0,0 +1,224 @@
+# .gdbinit file
+# $Id: dot.gdbinit,v 1.1 2005/04/11 02:21:08 sakugawa Exp $
+
+# setting
+set width 0d70
+set radix 0d16
+use_debug_dma
+
+# Initialize SDRAM controller for Mappi
+define sdram_init
+  # SDIR0
+  set *(unsigned long *)0x00ef6008 = 0x00000182
+  # SDIR1
+  set *(unsigned long *)0x00ef600c = 0x00000001
+  # Initialize wait
+  shell sleep 0.1
+  # MOD
+  set *(unsigned long *)0x00ef602c = 0x00000020
+  set *(unsigned long *)0x00ef604c = 0x00000020
+  # TR
+  set *(unsigned long *)0x00ef6028 = 0x00051502
+  set *(unsigned long *)0x00ef6048 = 0x00051502
+  # ADR
+  set *(unsigned long *)0x00ef6020 = 0x08000004
+  set *(unsigned long *)0x00ef6040 = 0x0c000004
+  # AutoRef On
+  set *(unsigned long *)0x00ef6004 = 0x00010517
+  # Access enable
+  set *(unsigned long *)0x00ef6024 = 0x00000001
+  set *(unsigned long *)0x00ef6044 = 0x00000001
+end
+
+# Initialize LAN controller for Mappi
+define lanc_init
+  # Set BSEL4
+  #set *(unsigned long *)0x00ef5004 = 0x0fff330f
+  #set *(unsigned long *)0x00ef5004 = 0x01113301
+
+#  set *(unsigned long *)0x00ef5004 = 0x02011101
+#  set *(unsigned long *)0x00ef5004 = 0x04441104
+end
+
+define clock_init
+  set *(unsigned long *)0x00ef4010 = 2
+  set *(unsigned long *)0x00ef4014 = 2
+  set *(unsigned long *)0x00ef4020 = 3
+  set *(unsigned long *)0x00ef4024 = 3
+  set *(unsigned long *)0x00ef4004 = 0x7
+#  shell sleep 0.1
+#  set *(unsigned long *)0x00ef4004 = 0x5
+  shell sleep 0.1
+  set *(unsigned long *)0x00ef4008 = 0x0200
+end
+
+define port_init
+  set $sfrbase = 0x00ef0000
+  set *(unsigned short *)0x00ef1060 = 0x5555
+  set *(unsigned short *)0x00ef1062 = 0x5555
+  set *(unsigned short *)0x00ef1064 = 0x5555
+  set *(unsigned short *)0x00ef1066 = 0x5555
+  set *(unsigned short *)0x00ef1068 = 0x5555
+  set *(unsigned short *)0x00ef106a = 0x0000
+  set *(unsigned short *)0x00ef106e = 0x5555
+  set *(unsigned short *)0x00ef1070 = 0x5555
+end
+
+# MMU enable
+define mmu_enable
+  set $evb=0x88000000
+  set *(unsigned long *)0xffff0024=1
+end
+
+# MMU disable
+define mmu_disable
+  set $evb=0
+  set *(unsigned long *)0xffff0024=0
+end
+
+# Show TLB entries
+define show_tlb_entries
+  set $i = 0
+  set $addr = $arg0
+  while ($i < 0d16 )
+    set $tlb_tag = *(unsigned long*)$addr
+    set $tlb_data = *(unsigned long*)($addr + 4)
+    printf " [%2d] 0x%08lx : 0x%08lx - 0x%08lx\n", $i, $addr, $tlb_tag, $tlb_data
+    set $i = $i + 1
+    set $addr = $addr + 8
+  end
+end
+define itlb
+  set $itlb=0xfe000000
+  show_tlb_entries $itlb
+end
+define dtlb
+  set $dtlb=0xfe000800
+  show_tlb_entries $dtlb
+end
+
+# Cache ON
+define set_cache_type
+  set $mctype = (void*)0xfffffff8
+# chaos
+# set *(unsigned long *)($mctype) = 0x0000c000
+# m32102 i-cache only
+  set *(unsigned long *)($mctype) = 0x00008000
+# m32102 d-cache only
+#  set *(unsigned long *)($mctype) = 0x00004000
+end
+define cache_on
+  set $param = (void*)0x08001000
+  set *(unsigned long *)($param) = 0x60ff6102
+end
+
+
+# Show current task structure
+define show_current
+  set $current = $spi & 0xffffe000
+  printf "$current=0x%08lX\n",$current
+  print *(struct task_struct *)$current
+end
+
+# Show user assigned task structure
+define show_task
+  set $task = $arg0 & 0xffffe000
+  printf "$task=0x%08lX\n",$task
+  print *(struct task_struct *)$task
+end
+document show_task
+  Show user assigned task structure
+  arg0 : task structure address
+end
+
+# Show M32R registers
+define show_regs
+  printf " R0[0x%08lX]   R1[0x%08lX]   R2[0x%08lX]   R3[0x%08lX]\n",$r0,$r1,$r2,$r3
+  printf " R4[0x%08lX]   R5[0x%08lX]   R6[0x%08lX]   R7[0x%08lX]\n",$r4,$r5,$r6,$r7
+  printf " R8[0x%08lX]   R9[0x%08lX]  R10[0x%08lX]  R11[0x%08lX]\n",$r8,$r9,$r10,$r11
+  printf "R12[0x%08lX]   FP[0x%08lX]   LR[0x%08lX]   SP[0x%08lX]\n",$r12,$fp,$lr,$sp
+  printf "PSW[0x%08lX]  CBR[0x%08lX]  SPI[0x%08lX]  SPU[0x%08lX]\n",$psw,$cbr,$spi,$spu
+  printf "BPC[0x%08lX]   PC[0x%08lX] ACCL[0x%08lX] ACCH[0x%08lX]\n",$bpc,$pc,$accl,$acch
+  printf "EVB[0x%08lX]\n",$evb
+
+  set $mests = *(unsigned long *)0xffff000c
+  set $mdeva = *(unsigned long *)0xffff0010
+  printf "MESTS[0x%08lX] MDEVA[0x%08lX]\n",$mests,$mdeva
+end
+
+
+# Setup all
+define setup
+  clock_init
+  shell sleep 0.1
+  port_init
+  sdram_init
+#  lanc_init
+#  dispc_init
+#  set $evb=0x08000000
+end
+
+# Load modules
+define load_modules
+  use_debug_dma
+  load
+#  load busybox.mot
+end
+
+# Set kernel parameters
+define set_kernel_parameters
+  set $param = (void*)0x08001000
+
+  ## MOUNT_ROOT_RDONLY
+  set {long}($param+0x00)=0
+  ## RAMDISK_FLAGS
+  #set {long}($param+0x04)=0
+  ## ORIG_ROOT_DEV
+  #set {long}($param+0x08)=0x00000100
+  ## LOADER_TYPE
+  #set {long}($param+0x0C)=0
+  ## INITRD_START
+  set {long}($param+0x10)=0x082a0000
+  ## INITRD_SIZE
+  set {long}($param+0x14)=0d6200000
+
+  # M32R_CPUCLK
+  set *(unsigned long *)($param + 0x0018) = 0d100000000
+  # M32R_BUSCLK
+  set *(unsigned long *)($param + 0x001c) = 0d50000000
+  # M32R_TIMER_DIVIDE
+  set *(unsigned long *)($param + 0x0020) = 0d128
+
+
+ set {char[0x200]}($param + 0x100) = "console=ttyS0,115200n8x root=/dev/nfsroot nfsroot=192.168.0.1:/project/m32r-linux/export/root.2.6_04 nfsaddrs=192.168.0.102:192.168.0.1:192.168.0.1:255.255.255.0:mappi: \0"
+
+
+end
+
+# Boot
+define boot
+  set_kernel_parameters
+  debug_chaos
+  set *(unsigned long *)0x00f00000=0x08002000
+  set $pc=0x08002000
+  set $fp=0
+  del b
+  si
+end
+
+# Restart
+define restart
+  sdireset
+  sdireset
+  setup
+  load_modules
+  boot
+end
+
+sdireset
+sdireset
+file vmlinux
+target m32rsdi
+
+restart
+boot
diff --git a/arch/m32r/mm/discontig.c b/arch/m32r/mm/discontig.c
--- a/arch/m32r/mm/discontig.c
+++ b/arch/m32r/mm/discontig.c
@@ -12,12 +12,14 @@
 #include <linux/mmzone.h>
 #include <linux/initrd.h>
 #include <linux/nodemask.h>
+#include <linux/module.h>
 
 #include <asm/setup.h>
 
 extern char _end[];
 
 struct pglist_data *node_data[MAX_NUMNODES];
+EXPORT_SYMBOL(node_data);
 static bootmem_data_t node_bdata[MAX_NUMNODES] __initdata;
 
 pg_data_t m32r_node_data[MAX_NUMNODES];
diff --git a/arch/m32r/mm/extable.c b/arch/m32r/mm/extable.c
--- a/arch/m32r/mm/extable.c
+++ b/arch/m32r/mm/extable.c
@@ -1,10 +1,8 @@
 /*
- * linux/arch/i386/mm/extable.c
+ * linux/arch/m32r/mm/extable.c
  */
 
-#include <linux/config.h>
 #include <linux/module.h>
-#include <linux/spinlock.h>
 #include <asm/uaccess.h>
 
 int fixup_exception(struct pt_regs *regs)
@@ -19,4 +17,3 @@ int fixup_exception(struct pt_regs *regs
 
 	return 0;
 }
-
diff --git a/arch/m32r/mm/init.c b/arch/m32r/mm/init.c
--- a/arch/m32r/mm/init.c
+++ b/arch/m32r/mm/init.c
@@ -49,7 +49,7 @@ void show_mem(void)
 	printk("Free swap:       %6ldkB\n",nr_swap_pages<<(PAGE_SHIFT-10));
 	for_each_pgdat(pgdat) {
 		for (i = 0; i < pgdat->node_spanned_pages; ++i) {
-			page = pgdat->node_mem_map + i;
+			page = pgdat_page_nr(pgdat, i);
 			total++;
 			if (PageHighMem(page))
 				highmem++;
@@ -152,7 +152,7 @@ int __init reservedpages_count(void)
 	reservedpages = 0;
 	for_each_online_node(nid)
 		for (i = 0 ; i < MAX_LOW_PFN(nid) - START_PFN(nid) ; i++)
-			if (PageReserved(NODE_DATA(nid)->node_mem_map + i))
+			if (PageReserved(nid_page_nr(nid, i)))
 				reservedpages++;
 
 	return reservedpages;
diff --git a/arch/m32r/oaks32r/defconfig.nommu b/arch/m32r/oaks32r/defconfig.nommu
--- a/arch/m32r/oaks32r/defconfig.nommu
+++ b/arch/m32r/oaks32r/defconfig.nommu
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc4
-# Wed Feb 16 21:11:13 2005
+# Linux kernel version: 2.6.12-rc5
+# Fri Jun  3 16:22:04 2005
 #
 CONFIG_M32R=y
 # CONFIG_UID16 is not set
@@ -16,6 +16,7 @@ CONFIG_EXPERIMENTAL=y
 CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
 CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
@@ -26,12 +27,14 @@ CONFIG_BSD_PROCESS_ACCT=y
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
 CONFIG_HOTPLUG=y
 CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
 CONFIG_EMBEDDED=y
 # CONFIG_KALLSYMS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
 # CONFIG_FUTEX is not set
 # CONFIG_EPOLL is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -40,6 +43,7 @@ CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
 CONFIG_TINY_SHMEM=y
+CONFIG_BASE_SMALL=0
 
 #
 # Loadable module support
@@ -61,6 +65,7 @@ CONFIG_KMOD=y
 # CONFIG_PLAT_OPSPUT is not set
 CONFIG_PLAT_OAKS32R=y
 # CONFIG_PLAT_MAPPI2 is not set
+# CONFIG_PLAT_MAPPI3 is not set
 # CONFIG_CHIP_M32700 is not set
 CONFIG_CHIP_M32102=y
 # CONFIG_CHIP_VDEC2 is not set
@@ -92,10 +97,6 @@ CONFIG_PREEMPT=y
 # CONFIG_PCCARD is not set
 
 #
-# PC-card bridges
-#
-
-#
 # PCI Hotplug Support
 #
 
@@ -193,7 +194,6 @@ CONFIG_NET=y
 #
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK_DEV is not set
 CONFIG_UNIX=y
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
@@ -311,18 +311,6 @@ CONFIG_INPUT=y
 # CONFIG_INPUT_EVBUG is not set
 
 #
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-# CONFIG_SERIO_RAW is not set
-
-#
 # Input Device Drivers
 #
 # CONFIG_INPUT_KEYBOARD is not set
@@ -332,6 +320,17 @@ CONFIG_SERIO_SERPORT=y
 # CONFIG_INPUT_MISC is not set
 
 #
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_LIBPS2 is not set
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+
+#
 # Character devices
 #
 # CONFIG_VT is not set
@@ -375,6 +374,10 @@ CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_RAW_DRIVER is not set
 
 #
+# TPM devices
+#
+
+#
 # I2C support
 #
 # CONFIG_I2C is not set
@@ -415,10 +418,6 @@ CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_USB_ARCH_HAS_OHCI is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
-
-#
 # USB Gadget Support
 #
 # CONFIG_USB_GADGET is not set
@@ -574,8 +573,9 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 #
 # Kernel hacking
 #
+# CONFIG_PRINTK_TIME is not set
 # CONFIG_DEBUG_KERNEL is not set
-CONFIG_DEBUG_PREEMPT=y
+CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_DEBUG_BUGVERBOSE is not set
 # CONFIG_FRAME_POINTER is not set
 
diff --git a/arch/m32r/opsput/defconfig.opsput b/arch/m32r/opsput/defconfig.opsput
--- a/arch/m32r/opsput/defconfig.opsput
+++ b/arch/m32r/opsput/defconfig.opsput
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc4
-# Wed Feb 16 21:11:41 2005
+# Linux kernel version: 2.6.12-rc5
+# Fri Jun  3 16:22:06 2005
 #
 CONFIG_M32R=y
 # CONFIG_UID16 is not set
@@ -15,6 +15,7 @@ CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_EXPERIMENTAL=y
 CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
@@ -27,13 +28,15 @@ CONFIG_BSD_PROCESS_ACCT=y
 # CONFIG_BSD_PROCESS_ACCT_V3 is not set
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
 CONFIG_HOTPLUG=y
 CONFIG_KOBJECT_UEVENT=y
 CONFIG_IKCONFIG=y
 # CONFIG_IKCONFIG_PROC is not set
 CONFIG_EMBEDDED=y
 # CONFIG_KALLSYMS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
 # CONFIG_FUTEX is not set
 # CONFIG_EPOLL is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -43,6 +46,7 @@ CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
 # CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
 
 #
 # Loadable module support
@@ -64,6 +68,7 @@ CONFIG_KMOD=y
 CONFIG_PLAT_OPSPUT=y
 # CONFIG_PLAT_OAKS32R is not set
 # CONFIG_PLAT_MAPPI2 is not set
+# CONFIG_PLAT_MAPPI3 is not set
 # CONFIG_CHIP_M32700 is not set
 # CONFIG_CHIP_M32102 is not set
 # CONFIG_CHIP_VDEC2 is not set
@@ -243,7 +248,6 @@ CONFIG_NET=y
 #
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK_DEV is not set
 CONFIG_UNIX=y
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
@@ -368,18 +372,6 @@ CONFIG_INPUT=y
 # CONFIG_INPUT_EVBUG is not set
 
 #
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_LIBPS2 is not set
-# CONFIG_SERIO_RAW is not set
-
-#
 # Input Device Drivers
 #
 # CONFIG_INPUT_KEYBOARD is not set
@@ -389,6 +381,17 @@ CONFIG_SERIO_SERPORT=y
 # CONFIG_INPUT_MISC is not set
 
 #
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_LIBPS2 is not set
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+
+#
 # Character devices
 #
 # CONFIG_VT is not set
@@ -438,6 +441,10 @@ CONFIG_DS1302=y
 # CONFIG_RAW_DRIVER is not set
 
 #
+# TPM devices
+#
+
+#
 # I2C support
 #
 # CONFIG_I2C is not set
@@ -478,10 +485,6 @@ CONFIG_DS1302=y
 # CONFIG_USB_ARCH_HAS_OHCI is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
-
-#
 # USB Gadget Support
 #
 # CONFIG_USB_GADGET is not set
@@ -654,8 +657,10 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 #
 # Kernel hacking
 #
+# CONFIG_PRINTK_TIME is not set
 CONFIG_DEBUG_KERNEL=y
 # CONFIG_MAGIC_SYSRQ is not set
+CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_DEBUG_SLAB is not set
 # CONFIG_DEBUG_SPINLOCK is not set
diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig
--- a/arch/m68k/Kconfig
+++ b/arch/m68k/Kconfig
@@ -357,6 +357,8 @@ config 060_WRITETHROUGH
 	  is hardwired on.  The 53c710 SCSI driver is known to suffer from
 	  this problem.
 
+source "mm/Kconfig"
+
 endmenu
 
 menu "General setup"
@@ -448,6 +450,8 @@ source "drivers/zorro/Kconfig"
 
 endmenu
 
+source "net/Kconfig"
+
 source "drivers/Kconfig"
 
 menu "Character devices"
diff --git a/arch/m68k/kernel/process.c b/arch/m68k/kernel/process.c
--- a/arch/m68k/kernel/process.c
+++ b/arch/m68k/kernel/process.c
@@ -113,8 +113,6 @@ void machine_restart(char * __unused)
 	for (;;);
 }
 
-EXPORT_SYMBOL(machine_restart);
-
 void machine_halt(void)
 {
 	if (mach_halt)
@@ -122,8 +120,6 @@ void machine_halt(void)
 	for (;;);
 }
 
-EXPORT_SYMBOL(machine_halt);
-
 void machine_power_off(void)
 {
 	if (mach_power_off)
@@ -131,8 +127,6 @@ void machine_power_off(void)
 	for (;;);
 }
 
-EXPORT_SYMBOL(machine_power_off);
-
 void show_regs(struct pt_regs * regs)
 {
 	printk("\n");
diff --git a/arch/m68k/mm/fault.c b/arch/m68k/mm/fault.c
--- a/arch/m68k/mm/fault.c
+++ b/arch/m68k/mm/fault.c
@@ -160,13 +160,13 @@ good_area:
 	printk("handle_mm_fault returns %d\n",fault);
 #endif
 	switch (fault) {
-	case 1:
+	case VM_FAULT_MINOR:
 		current->min_flt++;
 		break;
-	case 2:
+	case VM_FAULT_MAJOR:
 		current->maj_flt++;
 		break;
-	case 0:
+	case VM_FAULT_SIGBUS:
 		goto bus_err;
 	default:
 		goto out_of_memory;
diff --git a/arch/m68knommu/Kconfig b/arch/m68knommu/Kconfig
--- a/arch/m68knommu/Kconfig
+++ b/arch/m68knommu/Kconfig
@@ -532,6 +532,8 @@ config ROMKERNEL
 
 endchoice
 
+source "mm/Kconfig"
+
 endmenu
 
 config ISA_DMA_API
@@ -573,6 +575,8 @@ config PM
 
 endmenu
 
+source "net/Kconfig"
+
 source "drivers/Kconfig"
 
 source "fs/Kconfig"
diff --git a/arch/m68knommu/kernel/process.c b/arch/m68knommu/kernel/process.c
--- a/arch/m68knommu/kernel/process.c
+++ b/arch/m68knommu/kernel/process.c
@@ -80,8 +80,6 @@ void machine_restart(char * __unused)
 	for (;;);
 }
 
-EXPORT_SYMBOL(machine_restart);
-
 void machine_halt(void)
 {
 	if (mach_halt)
@@ -89,8 +87,6 @@ void machine_halt(void)
 	for (;;);
 }
 
-EXPORT_SYMBOL(machine_halt);
-
 void machine_power_off(void)
 {
 	if (mach_power_off)
@@ -98,8 +94,6 @@ void machine_power_off(void)
 	for (;;);
 }
 
-EXPORT_SYMBOL(machine_power_off);
-
 void show_regs(struct pt_regs * regs)
 {
 	printk(KERN_NOTICE "\n");
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -492,7 +492,7 @@ config SGI_SN0_N_MODE
 	  which allows for more memory.  Your system is most probably
 	  running in M-Mode, so you should say N here.
 
-config DISCONTIGMEM
+config ARCH_DISCONTIGMEM_ENABLE
 	bool
 	default y if SGI_IP27
 	help
@@ -1088,41 +1088,6 @@ config ARC32
 	depends on MACH_JAZZ || SNI_RM200_PCI || SGI_IP22 || SGI_IP32
 	default y
 
-config FB
-	bool
-	depends on MIPS_MAGNUM_4000 || OLIVETTI_M700
-	default y
-	---help---
-	  The frame buffer device provides an abstraction for the graphics
-	  hardware. It represents the frame buffer of some video hardware and
-	  allows application software to access the graphics hardware through
-	  a well-defined interface, so the software doesn't need to know
-	  anything about the low-level (hardware register) stuff.
-
-	  Frame buffer devices work identically across the different
-	  architectures supported by Linux and make the implementation of
-	  application programs easier and more portable; at this point, an X
-	  server exists which uses the frame buffer device exclusively.
-	  On several non-X86 architectures, the frame buffer device is the
-	  only way to use the graphics hardware.
-
-	  The device is accessed through special device nodes, usually located
-	  in the /dev directory, i.e. /dev/fb*.
-
-	  You need an utility program called fbset to make full use of frame
-	  buffer devices. Please read <file:Documentation/fb/framebuffer.txt>
-	  and the Framebuffer-HOWTO at <http://www.tldp.org/docs.html#howto>
-	  for more information.
-
-	  Say Y here and to the driver for your graphics board below if you
-	  are compiling a kernel for a non-x86 architecture.
-
-	  If you are compiling for the x86 architecture, you can say Y if you
-	  want to play with it, but it is not essential. Please note that
-	  running graphical applications that directly touch the hardware
-	  (e.g. an accelerated X server) and that are not frame buffer
-	  device-aware may cause unexpected results. If unsure, say N.
-
 config HAVE_STD_PC_SERIAL_PORT
 	bool
 
@@ -1416,6 +1381,12 @@ config HIGHMEM
 	bool "High Memory Support"
 	depends on MIPS32 && (CPU_R3000 || CPU_SB1 || CPU_R7000 || CPU_RM9000 || CPU_R10000) && !(MACH_DECSTATION || MOMENCO_JAGUAR_ATX)
 
+config ARCH_FLATMEM_ENABLE
+	def_bool y
+	depends on !NUMA
+
+source "mm/Kconfig"
+
 config SMP
 	bool "Multi-Processing support"
 	depends on CPU_RM9000 || (SIBYTE_SB1250 && !SIBYTE_STANDALONE) || SGI_IP27
@@ -1634,6 +1605,8 @@ config PM
 
 endmenu
 
+source "net/Kconfig"
+
 source "drivers/Kconfig"
 
 source "fs/Kconfig"
diff --git a/arch/mips/configs/ip27_defconfig b/arch/mips/configs/ip27_defconfig
--- a/arch/mips/configs/ip27_defconfig
+++ b/arch/mips/configs/ip27_defconfig
@@ -82,7 +82,7 @@ CONFIG_STOP_MACHINE=y
 # CONFIG_SGI_IP22 is not set
 CONFIG_SGI_IP27=y
 # CONFIG_SGI_SN0_N_MODE is not set
-CONFIG_DISCONTIGMEM=y
+CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
 CONFIG_NUMA=y
 # CONFIG_MAPPED_KERNEL is not set
 # CONFIG_REPLICATE_KTEXT is not set
diff --git a/arch/mips/kernel/irixsig.c b/arch/mips/kernel/irixsig.c
--- a/arch/mips/kernel/irixsig.c
+++ b/arch/mips/kernel/irixsig.c
@@ -178,7 +178,7 @@ asmlinkage int do_irix_signal(sigset_t *
 	if (!user_mode(regs))
 		return 1;
 
-	if (try_to_freeze(0))
+	if (try_to_freeze())
 		goto no_signal;
 
 	if (!oldset)
diff --git a/arch/mips/kernel/reset.c b/arch/mips/kernel/reset.c
--- a/arch/mips/kernel/reset.c
+++ b/arch/mips/kernel/reset.c
@@ -26,18 +26,13 @@ void machine_restart(char *command)
 	_machine_restart(command);
 }
 
-EXPORT_SYMBOL(machine_restart);
-
 void machine_halt(void)
 {
 	_machine_halt();
 }
 
-EXPORT_SYMBOL(machine_halt);
-
 void machine_power_off(void)
 {
 	_machine_power_off();
 }
 
-EXPORT_SYMBOL(machine_power_off);
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -33,6 +33,7 @@
 #include <linux/root_dev.h>
 #include <linux/highmem.h>
 #include <linux/console.h>
+#include <linux/mmzone.h>
 
 #include <asm/addrspace.h>
 #include <asm/bootinfo.h>
@@ -356,6 +357,8 @@ static inline void bootmem_init(void)
 	}
 #endif
 
+	memory_present(0, first_usable_pfn, max_low_pfn);
+
 	/* Initialize the boot-time allocator with low memory only.  */
 	bootmap_size = init_bootmem(first_usable_pfn, max_low_pfn);
 
@@ -557,6 +560,7 @@ void __init setup_arch(char **cmdline_p)
 
 	parse_cmdline_early();
 	bootmem_init();
+	sparse_init();
 	paging_init();
 	resource_init();
 }
diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c
--- a/arch/mips/kernel/signal.c
+++ b/arch/mips/kernel/signal.c
@@ -457,7 +457,7 @@ static int do_signal(sigset_t *oldset, s
 	if (!user_mode(regs))
 		return 1;
 
-	if (try_to_freeze(0))
+	if (try_to_freeze())
 		goto no_signal;
 
 	if (!oldset)
diff --git a/arch/mips/kernel/signal32.c b/arch/mips/kernel/signal32.c
--- a/arch/mips/kernel/signal32.c
+++ b/arch/mips/kernel/signal32.c
@@ -774,7 +774,7 @@ int do_signal32(sigset_t *oldset, struct
 	if (!user_mode(regs))
 		return 1;
 
-	if (try_to_freeze(0))
+	if (try_to_freeze())
 		goto no_signal;
 
 	if (!oldset)
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
--- a/arch/mips/mm/init.c
+++ b/arch/mips/mm/init.c
@@ -128,7 +128,7 @@ static void __init fixrange_init(unsigne
 #endif /* CONFIG_MIPS64 */
 #endif /* CONFIG_HIGHMEM */
 
-#ifndef CONFIG_DISCONTIGMEM
+#ifndef CONFIG_NEED_MULTIPLE_NODES
 extern void pagetable_init(void);
 
 void __init paging_init(void)
@@ -232,7 +232,6 @@ void __init mem_init(void)
 #ifdef CONFIG_LIMITED_DMA
 		set_page_address(page, lowmem_page_address(page));
 #endif
-		set_bit(PG_highmem, &page->flags);
 		set_page_count(page, 1);
 		__free_page(page);
 		totalhigh_pages++;
@@ -254,7 +253,7 @@ void __init mem_init(void)
 	       initsize >> 10,
 	       (unsigned long) (totalhigh_pages << (PAGE_SHIFT-10)));
 }
-#endif /* !CONFIG_DISCONTIGMEM */
+#endif /* !CONFIG_NEED_MULTIPLE_NODES */
 
 #ifdef CONFIG_BLK_DEV_INITRD
 void free_initrd_mem(unsigned long start, unsigned long end)
diff --git a/arch/mips/mm/pgtable.c b/arch/mips/mm/pgtable.c
--- a/arch/mips/mm/pgtable.c
+++ b/arch/mips/mm/pgtable.c
@@ -5,7 +5,7 @@
 
 void show_mem(void)
 {
-#ifndef CONFIG_DISCONTIGMEM  /* XXX(hch): later.. */
+#ifndef CONFIG_NEED_MULTIPLE_NODES  /* XXX(hch): later.. */
 	int pfn, total = 0, reserved = 0;
 	int shared = 0, cached = 0;
 	int highmem = 0;
diff --git a/arch/mips/sgi-ip27/ip27-memory.c b/arch/mips/sgi-ip27/ip27-memory.c
--- a/arch/mips/sgi-ip27/ip27-memory.c
+++ b/arch/mips/sgi-ip27/ip27-memory.c
@@ -549,9 +549,8 @@ void __init mem_init(void)
 		 */
 		numslots = node_getlastslot(node);
 		for (slot = 1; slot <= numslots; slot++) {
-			p = NODE_DATA(node)->node_mem_map +
-				(slot_getbasepfn(node, slot) -
-				 slot_getbasepfn(node, 0));
+			p = nid_page_nr(node, slot_getbasepfn(node, slot) -
+					      slot_getbasepfn(node, 0));
 
 			/*
 			 * Free valid memory in current slot.
diff --git a/arch/mips/vr41xx/common/Makefile b/arch/mips/vr41xx/common/Makefile
--- a/arch/mips/vr41xx/common/Makefile
+++ b/arch/mips/vr41xx/common/Makefile
@@ -2,7 +2,7 @@
 # Makefile for common code of the NEC VR4100 series.
 #
 
-obj-y				+= bcu.o cmu.o giu.o icu.o init.o int-handler.o pmu.o
+obj-y				+= bcu.o cmu.o icu.o init.o int-handler.o pmu.o
 obj-$(CONFIG_VRC4173)		+= vrc4173.o
 
 EXTRA_AFLAGS := $(CFLAGS)
diff --git a/arch/mips/vr41xx/common/giu.c b/arch/mips/vr41xx/common/giu.c
deleted file mode 100644
--- a/arch/mips/vr41xx/common/giu.c
+++ /dev/null
@@ -1,455 +0,0 @@
-/*
- *  giu.c, General-purpose I/O Unit Interrupt routines for NEC VR4100 series.
- *
- *  Copyright (C) 2002 MontaVista Software Inc.
- *    Author: Yoichi Yuasa <yyuasa@mvista.com or source@mvista.com>
- *  Copyright (C) 2003-2004  Yoichi Yuasa <yuasa@hh.iij4u.or.jp>
- *  Copyright (C) 2005 Ralf Baechle (ralf@linux-mips.org)
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-/*
- * Changes:
- *  MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com>
- *  - New creation, NEC VR4111, VR4121, VR4122 and VR4131 are supported.
- *
- *  Yoichi Yuasa <yuasa@hh.iij4u.or.jp>
- *  - Added support for NEC VR4133.
- *  - Removed board_irq_init.
- */
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/irq.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/smp.h>
-#include <linux/types.h>
-
-#include <asm/cpu.h>
-#include <asm/io.h>
-#include <asm/vr41xx/vr41xx.h>
-
-#define GIUIOSELL_TYPE1	KSEG1ADDR(0x0b000100)
-#define GIUIOSELL_TYPE2	KSEG1ADDR(0x0f000140)
-
-#define GIUIOSELL	0x00
-#define GIUIOSELH	0x02
-#define GIUINTSTATL	0x08
-#define GIUINTSTATH	0x0a
-#define GIUINTENL	0x0c
-#define GIUINTENH	0x0e
-#define GIUINTTYPL	0x10
-#define GIUINTTYPH	0x12
-#define GIUINTALSELL	0x14
-#define GIUINTALSELH	0x16
-#define GIUINTHTSELL	0x18
-#define GIUINTHTSELH	0x1a
-#define GIUFEDGEINHL	0x20
-#define GIUFEDGEINHH	0x22
-#define GIUREDGEINHL	0x24
-#define GIUREDGEINHH	0x26
-
-static uint32_t giu_base;
-
-static struct irqaction giu_cascade = {
-	.handler	= no_action,
-	.mask		= CPU_MASK_NONE,
-	.name		= "cascade",
-};
-
-#define read_giuint(offset)		readw(giu_base + (offset))
-#define write_giuint(val, offset)	writew((val), giu_base + (offset))
-
-#define GIUINT_HIGH_OFFSET	16
-
-static inline uint16_t set_giuint(uint8_t offset, uint16_t set)
-{
-	uint16_t res;
-
-	res = read_giuint(offset);
-	res |= set;
-	write_giuint(res, offset);
-
-	return res;
-}
-
-static inline uint16_t clear_giuint(uint8_t offset, uint16_t clear)
-{
-	uint16_t res;
-
-	res = read_giuint(offset);
-	res &= ~clear;
-	write_giuint(res, offset);
-
-	return res;
-}
-
-static unsigned int startup_giuint_low_irq(unsigned int irq)
-{
-	unsigned int pin;
-
-	pin = GIU_IRQ_TO_PIN(irq);
-	write_giuint((uint16_t)1 << pin, GIUINTSTATL);
-	set_giuint(GIUINTENL, (uint16_t)1 << pin);
-
-	return 0;
-}
-
-static void shutdown_giuint_low_irq(unsigned int irq)
-{
-	clear_giuint(GIUINTENL, (uint16_t)1 << GIU_IRQ_TO_PIN(irq));
-}
-
-static void enable_giuint_low_irq(unsigned int irq)
-{
-	set_giuint(GIUINTENL, (uint16_t)1 << GIU_IRQ_TO_PIN(irq));
-}
-
-#define disable_giuint_low_irq	shutdown_giuint_low_irq
-
-static void ack_giuint_low_irq(unsigned int irq)
-{
-	unsigned int pin;
-
-	pin = GIU_IRQ_TO_PIN(irq);
-	clear_giuint(GIUINTENL, (uint16_t)1 << pin);
-	write_giuint((uint16_t)1 << pin, GIUINTSTATL);
-}
-
-static void end_giuint_low_irq(unsigned int irq)
-{
-	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
-		set_giuint(GIUINTENL, (uint16_t)1 << GIU_IRQ_TO_PIN(irq));
-}
-
-static struct hw_interrupt_type giuint_low_irq_type = {
-	.typename	= "GIUINTL",
-	.startup	= startup_giuint_low_irq,
-	.shutdown	= shutdown_giuint_low_irq,
-	.enable		= enable_giuint_low_irq,
-	.disable	= disable_giuint_low_irq,
-	.ack		= ack_giuint_low_irq,
-	.end		= end_giuint_low_irq,
-};
-
-static unsigned int startup_giuint_high_irq(unsigned int irq)
-{
-	unsigned int pin;
-
-	pin = GIU_IRQ_TO_PIN(irq - GIUINT_HIGH_OFFSET);
-	write_giuint((uint16_t)1 << pin, GIUINTSTATH);
-	set_giuint(GIUINTENH, (uint16_t)1 << pin);
-
-	return 0;
-}
-
-static void shutdown_giuint_high_irq(unsigned int irq)
-{
-	clear_giuint(GIUINTENH, (uint16_t)1 << GIU_IRQ_TO_PIN(irq - GIUINT_HIGH_OFFSET));
-}
-
-static void enable_giuint_high_irq(unsigned int irq)
-{
-	set_giuint(GIUINTENH, (uint16_t)1 << GIU_IRQ_TO_PIN(irq - GIUINT_HIGH_OFFSET));
-}
-
-#define disable_giuint_high_irq	shutdown_giuint_high_irq
-
-static void ack_giuint_high_irq(unsigned int irq)
-{
-	unsigned int pin;
-
-	pin = GIU_IRQ_TO_PIN(irq - GIUINT_HIGH_OFFSET);
-	clear_giuint(GIUINTENH, (uint16_t)1 << pin);
-	write_giuint((uint16_t)1 << pin, GIUINTSTATH);
-}
-
-static void end_giuint_high_irq(unsigned int irq)
-{
-	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
-		set_giuint(GIUINTENH, (uint16_t)1 << GIU_IRQ_TO_PIN(irq - GIUINT_HIGH_OFFSET));
-}
-
-static struct hw_interrupt_type giuint_high_irq_type = {
-	.typename	= "GIUINTH",
-	.startup	= startup_giuint_high_irq,
-	.shutdown	= shutdown_giuint_high_irq,
-	.enable		= enable_giuint_high_irq,
-	.disable	= disable_giuint_high_irq,
-	.ack		= ack_giuint_high_irq,
-	.end		= end_giuint_high_irq,
-};
-
-void __init init_vr41xx_giuint_irq(void)
-{
-	int i;
-
-	for (i = GIU_IRQ_BASE; i <= GIU_IRQ_LAST; i++) {
-		if (i < (GIU_IRQ_BASE + GIUINT_HIGH_OFFSET))
-			irq_desc[i].handler = &giuint_low_irq_type;
-		else
-			irq_desc[i].handler = &giuint_high_irq_type;
-	}
-
-	setup_irq(GIUINT_CASCADE_IRQ, &giu_cascade);
-}
-
-void vr41xx_set_irq_trigger(int pin, int trigger, int hold)
-{
-	uint16_t mask;
-
-	if (pin < GIUINT_HIGH_OFFSET) {
-		mask = (uint16_t)1 << pin;
-		if (trigger != TRIGGER_LEVEL) {
-        		set_giuint(GIUINTTYPL, mask);
-			if (hold == SIGNAL_HOLD)
-				set_giuint(GIUINTHTSELL, mask);
-			else
-				clear_giuint(GIUINTHTSELL, mask);
-			if (current_cpu_data.cputype == CPU_VR4133) {
-				switch (trigger) {
-				case TRIGGER_EDGE_FALLING:
-					set_giuint(GIUFEDGEINHL, mask);
-					clear_giuint(GIUREDGEINHL, mask);
-					break;
-				case TRIGGER_EDGE_RISING:
-					clear_giuint(GIUFEDGEINHL, mask);
-					set_giuint(GIUREDGEINHL, mask);
-					break;
-				default:
-					set_giuint(GIUFEDGEINHL, mask);
-					set_giuint(GIUREDGEINHL, mask);
-					break;
-				}
-			}
-		} else {
-			clear_giuint(GIUINTTYPL, mask);
-			clear_giuint(GIUINTHTSELL, mask);
-		}
-		write_giuint(mask, GIUINTSTATL);
-	} else {
-		mask = (uint16_t)1 << (pin - GIUINT_HIGH_OFFSET);
-		if (trigger != TRIGGER_LEVEL) {
-			set_giuint(GIUINTTYPH, mask);
-			if (hold == SIGNAL_HOLD)
-				set_giuint(GIUINTHTSELH, mask);
-			else
-				clear_giuint(GIUINTHTSELH, mask);
-			if (current_cpu_data.cputype == CPU_VR4133) {
-				switch (trigger) {
-				case TRIGGER_EDGE_FALLING:
-					set_giuint(GIUFEDGEINHH, mask);
-					clear_giuint(GIUREDGEINHH, mask);
-					break;
-				case TRIGGER_EDGE_RISING:
-					clear_giuint(GIUFEDGEINHH, mask);
-					set_giuint(GIUREDGEINHH, mask);
-					break;
-				default:
-					set_giuint(GIUFEDGEINHH, mask);
-					set_giuint(GIUREDGEINHH, mask);
-					break;
-				}
-			}
-		} else {
-			clear_giuint(GIUINTTYPH, mask);
-			clear_giuint(GIUINTHTSELH, mask);
-		}
-		write_giuint(mask, GIUINTSTATH);
-	}
-}
-
-EXPORT_SYMBOL(vr41xx_set_irq_trigger);
-
-void vr41xx_set_irq_level(int pin, int level)
-{
-	uint16_t mask;
-
-	if (pin < GIUINT_HIGH_OFFSET) {
-		mask = (uint16_t)1 << pin;
-		if (level == LEVEL_HIGH)
-			set_giuint(GIUINTALSELL, mask);
-		else
-			clear_giuint(GIUINTALSELL, mask);
-		write_giuint(mask, GIUINTSTATL);
-	} else {
-		mask = (uint16_t)1 << (pin - GIUINT_HIGH_OFFSET);
-		if (level == LEVEL_HIGH)
-			set_giuint(GIUINTALSELH, mask);
-		else
-			clear_giuint(GIUINTALSELH, mask);
-		write_giuint(mask, GIUINTSTATH);
-	}
-}
-
-EXPORT_SYMBOL(vr41xx_set_irq_level);
-
-#define GIUINT_NR_IRQS		32
-
-enum {
-	GIUINT_NO_CASCADE,
-	GIUINT_CASCADE
-};
-
-struct vr41xx_giuint_cascade {
-	unsigned int flag;
-	int (*get_irq_number)(int irq);
-};
-
-static struct vr41xx_giuint_cascade giuint_cascade[GIUINT_NR_IRQS];
-
-static int no_irq_number(int irq)
-{
-	return -EINVAL;
-}
-
-int vr41xx_cascade_irq(unsigned int irq, int (*get_irq_number)(int irq))
-{
-	unsigned int pin;
-	int retval;
-
-	if (irq < GIU_IRQ(0) || irq > GIU_IRQ(31))
-		return -EINVAL;
-
-	if(!get_irq_number)
-		return -EINVAL;
-
-	pin = GIU_IRQ_TO_PIN(irq);
-	giuint_cascade[pin].flag = GIUINT_CASCADE;
-	giuint_cascade[pin].get_irq_number = get_irq_number;
-
-	retval = setup_irq(irq, &giu_cascade);
-	if (retval != 0) {
-		giuint_cascade[pin].flag = GIUINT_NO_CASCADE;
-		giuint_cascade[pin].get_irq_number = no_irq_number;
-	}
-
-	return retval;
-}
-
-EXPORT_SYMBOL(vr41xx_cascade_irq);
-
-static inline int get_irq_pin_number(void)
-{
-	uint16_t pendl, pendh, maskl, maskh;
-	int i;
-
-	pendl = read_giuint(GIUINTSTATL);
-	pendh = read_giuint(GIUINTSTATH);
-	maskl = read_giuint(GIUINTENL);
-	maskh = read_giuint(GIUINTENH);
-
-	maskl &= pendl;
-	maskh &= pendh;
-
-	if (maskl) {
-		for (i = 0; i < 16; i++) {
-			if (maskl & ((uint16_t)1 << i))
-				return i;
-		}
-	} else if (maskh) {
-		for (i = 0; i < 16; i++) {
-			if (maskh & ((uint16_t)1 << i))
-				return i + GIUINT_HIGH_OFFSET;
-		}
-	}
-
-	printk(KERN_ERR "spurious GIU interrupt: %04x(%04x),%04x(%04x)\n",
-	       maskl, pendl, maskh, pendh);
-
-	atomic_inc(&irq_err_count);
-
-	return -1;
-}
-
-static inline void ack_giuint_irq(int pin)
-{
-	if (pin < GIUINT_HIGH_OFFSET) {
-		clear_giuint(GIUINTENL, (uint16_t)1 << pin);
-		write_giuint((uint16_t)1 << pin, GIUINTSTATL);
-	} else {
-		pin -= GIUINT_HIGH_OFFSET;
-		clear_giuint(GIUINTENH, (uint16_t)1 << pin);
-		write_giuint((uint16_t)1 << pin, GIUINTSTATH);
-	}
-}
-
-static inline void end_giuint_irq(int pin)
-{
-	if (pin < GIUINT_HIGH_OFFSET)
-		set_giuint(GIUINTENL, (uint16_t)1 << pin);
-	else
-		set_giuint(GIUINTENH, (uint16_t)1 << (pin - GIUINT_HIGH_OFFSET));
-}
-
-void giuint_irq_dispatch(struct pt_regs *regs)
-{
-	struct vr41xx_giuint_cascade *cascade;
-	unsigned int giuint_irq;
-	int pin;
-
-	pin = get_irq_pin_number();
-	if (pin < 0)
-		return;
-
-	disable_irq(GIUINT_CASCADE_IRQ);
-
-	cascade = &giuint_cascade[pin];
-	giuint_irq = GIU_IRQ(pin);
-	if (cascade->flag == GIUINT_CASCADE) {
-		int irq = cascade->get_irq_number(giuint_irq);
-		ack_giuint_irq(pin);
-		if (irq >= 0)
-			do_IRQ(irq, regs);
-		end_giuint_irq(pin);
-	} else {
-		do_IRQ(giuint_irq, regs);
-	}
-
-	enable_irq(GIUINT_CASCADE_IRQ);
-}
-
-static int __init vr41xx_giu_init(void)
-{
-	int i;
-
-	switch (current_cpu_data.cputype) {
-	case CPU_VR4111:
-	case CPU_VR4121:
-		giu_base = GIUIOSELL_TYPE1;
-		break;
-	case CPU_VR4122:
-	case CPU_VR4131:
-	case CPU_VR4133:
-		giu_base = GIUIOSELL_TYPE2;
-		break;
-	default:
-		printk(KERN_ERR "GIU: Unexpected CPU of NEC VR4100 series\n");
-		return -EINVAL;
-	}
-
-	for (i = 0; i < GIUINT_NR_IRQS; i++) {
-		if (i < GIUINT_HIGH_OFFSET)
-			clear_giuint(GIUINTENL, (uint16_t)1 << i);
-		else
-			clear_giuint(GIUINTENH, (uint16_t)1 << (i - GIUINT_HIGH_OFFSET));
-		giuint_cascade[i].flag = GIUINT_NO_CASCADE;
-		giuint_cascade[i].get_irq_number = no_irq_number;
-	}
-
-	return 0;
-}
-
-early_initcall(vr41xx_giu_init);
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
--- a/arch/parisc/Kconfig
+++ b/arch/parisc/Kconfig
@@ -148,7 +148,7 @@ config HOTPLUG_CPU
 	default y if SMP
 	select HOTPLUG
 
-config DISCONTIGMEM
+config ARCH_DISCONTIGMEM_ENABLE
 	bool "Discontiguous memory support (EXPERIMENTAL)"
 	depends on EXPERIMENTAL
 	help
@@ -157,6 +157,8 @@ config DISCONTIGMEM
 	  or have huge holes in the physical address space for other reasons.
 	  See <file:Documentation/vm/numa> for more.
 
+source "mm/Kconfig"
+
 config PREEMPT
 	bool
 #	bool "Preemptible Kernel"
@@ -188,6 +190,8 @@ source "fs/Kconfig.binfmt"
 
 endmenu
 
+source "net/Kconfig"
+
 source "drivers/Kconfig"
 
 source "fs/Kconfig"
diff --git a/arch/parisc/configs/712_defconfig b/arch/parisc/configs/712_defconfig
--- a/arch/parisc/configs/712_defconfig
+++ b/arch/parisc/configs/712_defconfig
@@ -506,7 +506,7 @@ CONFIG_HW_CONSOLE=y
 #
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=8
+CONFIG_SERIAL_8250_NR_UARTS=17
 CONFIG_SERIAL_8250_EXTENDED=y
 CONFIG_SERIAL_8250_MANY_PORTS=y
 CONFIG_SERIAL_8250_SHARE_IRQ=y
diff --git a/arch/parisc/configs/a500_defconfig b/arch/parisc/configs/a500_defconfig
--- a/arch/parisc/configs/a500_defconfig
+++ b/arch/parisc/configs/a500_defconfig
@@ -662,7 +662,7 @@ CONFIG_HW_CONSOLE=y
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_8250_CS=m
-CONFIG_SERIAL_8250_NR_UARTS=8
+CONFIG_SERIAL_8250_NR_UARTS=17
 CONFIG_SERIAL_8250_EXTENDED=y
 CONFIG_SERIAL_8250_MANY_PORTS=y
 CONFIG_SERIAL_8250_SHARE_IRQ=y
diff --git a/arch/parisc/configs/b180_defconfig b/arch/parisc/configs/b180_defconfig
--- a/arch/parisc/configs/b180_defconfig
+++ b/arch/parisc/configs/b180_defconfig
@@ -514,7 +514,7 @@ CONFIG_HW_CONSOLE=y
 #
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_NR_UARTS=13
 CONFIG_SERIAL_8250_EXTENDED=y
 CONFIG_SERIAL_8250_MANY_PORTS=y
 CONFIG_SERIAL_8250_SHARE_IRQ=y
diff --git a/arch/parisc/configs/c3000_defconfig b/arch/parisc/configs/c3000_defconfig
--- a/arch/parisc/configs/c3000_defconfig
+++ b/arch/parisc/configs/c3000_defconfig
@@ -661,7 +661,7 @@ CONFIG_HW_CONSOLE=y
 #
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_NR_UARTS=13
 CONFIG_SERIAL_8250_EXTENDED=y
 CONFIG_SERIAL_8250_MANY_PORTS=y
 CONFIG_SERIAL_8250_SHARE_IRQ=y
diff --git a/arch/parisc/defconfig b/arch/parisc/defconfig
--- a/arch/parisc/defconfig
+++ b/arch/parisc/defconfig
@@ -517,7 +517,7 @@ CONFIG_HW_CONSOLE=y
 #
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_NR_UARTS=13
 CONFIG_SERIAL_8250_EXTENDED=y
 CONFIG_SERIAL_8250_MANY_PORTS=y
 CONFIG_SERIAL_8250_SHARE_IRQ=y
diff --git a/arch/parisc/kernel/drivers.c b/arch/parisc/kernel/drivers.c
--- a/arch/parisc/kernel/drivers.c
+++ b/arch/parisc/kernel/drivers.c
@@ -466,7 +466,7 @@ static int parisc_generic_match(struct d
 }
 
 #define pa_dev_attr(name, field, format_string)				\
-static ssize_t name##_show(struct device *dev, char *buf)		\
+static ssize_t name##_show(struct device *dev, struct device_attribute *attr, char *buf)		\
 {									\
 	struct parisc_device *padev = to_parisc_device(dev);		\
 	return sprintf(buf, format_string, padev->field);		\
diff --git a/arch/parisc/kernel/pci.c b/arch/parisc/kernel/pci.c
--- a/arch/parisc/kernel/pci.c
+++ b/arch/parisc/kernel/pci.c
@@ -255,8 +255,26 @@ void __devinit pcibios_resource_to_bus(s
 	pcibios_link_hba_resources(&hba->lmmio_space, bus->resource[1]);
 }
 
+void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
+			      struct pci_bus_region *region)
+{
+	struct pci_bus *bus = dev->bus;
+	struct pci_hba_data *hba = HBA_DATA(bus->bridge->platform_data);
+
+	if (res->flags & IORESOURCE_MEM) {
+		res->start = PCI_HOST_ADDR(hba, region->start);
+		res->end = PCI_HOST_ADDR(hba, region->end);
+	}
+
+	if (res->flags & IORESOURCE_IO) {
+		res->start = region->start;
+		res->end = region->end;
+	}
+}
+
 #ifdef CONFIG_HOTPLUG
 EXPORT_SYMBOL(pcibios_resource_to_bus);
+EXPORT_SYMBOL(pcibios_bus_to_resource);
 #endif
 
 /*
diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c
--- a/arch/parisc/kernel/process.c
+++ b/arch/parisc/kernel/process.c
@@ -150,8 +150,6 @@ void machine_restart(char *cmd)
 
 }
 
-EXPORT_SYMBOL(machine_restart);
-
 void machine_halt(void)
 {
 	/*
@@ -160,8 +158,6 @@ void machine_halt(void)
 	*/
 }
 
-EXPORT_SYMBOL(machine_halt);
-
 
 /*
  * This routine is called from sys_reboot to actually turn off the
@@ -187,8 +183,6 @@ void machine_power_off(void)
 	       KERN_EMERG "Please power this system off now.");
 }
 
-EXPORT_SYMBOL(machine_power_off);
-
 
 /*
  * Create a kernel thread
diff --git a/arch/parisc/mm/fault.c b/arch/parisc/mm/fault.c
--- a/arch/parisc/mm/fault.c
+++ b/arch/parisc/mm/fault.c
@@ -178,17 +178,17 @@ good_area:
 	 */
 
 	switch (handle_mm_fault(mm, vma, address, (acc_type & VM_WRITE) != 0)) {
-	      case 1:
+	      case VM_FAULT_MINOR:
 		++current->min_flt;
 		break;
-	      case 2:
+	      case VM_FAULT_MAJOR:
 		++current->maj_flt;
 		break;
-	      case 0:
+	      case VM_FAULT_SIGBUS:
 		/*
-		 * We ran out of memory, or some other thing happened
-		 * to us that made us unable to handle the page fault
-		 * gracefully.
+		 * We hit a hared mapping outside of the file, or some
+		 * other thing happened to us that made us unable to
+		 * handle the page fault gracefully.
 		 */
 		goto bad_area;
 	      default:
diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c
--- a/arch/parisc/mm/init.c
+++ b/arch/parisc/mm/init.c
@@ -506,7 +506,7 @@ void show_mem(void)
 		for (j = node_start_pfn(i); j < node_end_pfn(i); j++) {
 			struct page *p;
 
-			p = node_mem_map(i) + j - node_start_pfn(i);
+			p = nid_page_nr(i, j) - node_start_pfn(i);
 
 			total++;
 			if (PageReserved(p))
diff --git a/arch/ppc/8xx_io/Kconfig b/arch/ppc/8xx_io/Kconfig
--- a/arch/ppc/8xx_io/Kconfig
+++ b/arch/ppc/8xx_io/Kconfig
@@ -69,9 +69,9 @@ config FEC_QS6612
 	
 config ENET_BIG_BUFFERS
 	bool "Use Big CPM Ethernet Buffers"
-	depends on NET_ETHERNET
+	depends on SCC_ENET || FEC_ENET
 	help
-	  Allocate large buffers for MPC8xx Etherenet.  Increases throughput
+	  Allocate large buffers for MPC8xx Ethernet. Increases throughput
 	  and decreases the likelihood of dropped packets, but costs memory.
 
 config HTDMSOUND
diff --git a/arch/ppc/8xx_io/commproc.c b/arch/ppc/8xx_io/commproc.c
--- a/arch/ppc/8xx_io/commproc.c
+++ b/arch/ppc/8xx_io/commproc.c
@@ -39,8 +39,6 @@
 #include <asm/tlbflush.h>
 #include <asm/rheap.h>
 
-extern int get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep);
-
 static void m8xx_cpm_dpinit(void);
 static	uint	host_buffer;	/* One page of host buffer */
 static	uint	host_end;	/* end + 1 */
@@ -108,14 +106,11 @@ struct hw_interrupt_type cpm_pic = {
 	.end		= cpm_eoi,
 };
 
-extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr);
-
 void
-m8xx_cpm_reset(uint bootpage)
+m8xx_cpm_reset(void)
 {
 	volatile immap_t	 *imp;
 	volatile cpm8xx_t	*commproc;
-	pte_t *pte;
 
 	imp = (immap_t *)IMAP_ADDR;
 	commproc = (cpm8xx_t *)&imp->im_cpm;
@@ -143,17 +138,6 @@ m8xx_cpm_reset(uint bootpage)
 	/* Reclaim the DP memory for our use. */
 	m8xx_cpm_dpinit();
 
-	/* get the PTE for the bootpage */
-	if (!get_pteptr(&init_mm, bootpage, &pte))
-	       panic("get_pteptr failed\n");
-																							
-	/* and make it uncachable */
-	pte_val(*pte) |= _PAGE_NO_CACHE;
-	_tlbie(bootpage);
-
-	host_buffer = bootpage;
-	host_end = host_buffer + PAGE_SIZE;
-
 	/* Tell everyone where the comm processor resides.
 	*/
 	cpmp = (cpm8xx_t *)commproc;
@@ -384,8 +368,6 @@ static rh_info_t cpm_dpmem_info;
 
 void m8xx_cpm_dpinit(void)
 {
-	cpm8xx_t *cp = &((immap_t *)IMAP_ADDR)->im_cpm;
-
 	spin_lock_init(&cpm_dpmem_lock);
 
 	/* Initialize the info header */
diff --git a/arch/ppc/8xx_io/enet.c b/arch/ppc/8xx_io/enet.c
--- a/arch/ppc/8xx_io/enet.c
+++ b/arch/ppc/8xx_io/enet.c
@@ -714,16 +714,24 @@ static int __init scc_enet_init(void)
 	immap->im_ioport.iop_pcdat &= ~PC_ENET_LBK;	/* Disable Loopback */
 #endif	/* PC_ENET_LBK */
 
-	/* Configure port C pins to enable CLSN and RENA.
+#ifdef PE_ENET_TCLK
+	/* Configure port E for TCLK and RCLK.
 	*/
-	immap->im_ioport.iop_pcpar &= ~(PC_ENET_CLSN | PC_ENET_RENA);
-	immap->im_ioport.iop_pcdir &= ~(PC_ENET_CLSN | PC_ENET_RENA);
-	immap->im_ioport.iop_pcso  |=  (PC_ENET_CLSN | PC_ENET_RENA);
-
+	cp->cp_pepar |=  (PE_ENET_TCLK | PE_ENET_RCLK);
+	cp->cp_pedir &= ~(PE_ENET_TCLK | PE_ENET_RCLK);
+	cp->cp_peso  &= ~(PE_ENET_TCLK | PE_ENET_RCLK);
+#else
 	/* Configure port A for TCLK and RCLK.
 	*/
 	immap->im_ioport.iop_papar |=  (PA_ENET_TCLK | PA_ENET_RCLK);
 	immap->im_ioport.iop_padir &= ~(PA_ENET_TCLK | PA_ENET_RCLK);
+#endif
+
+	/* Configure port C pins to enable CLSN and RENA.
+	*/
+	immap->im_ioport.iop_pcpar &= ~(PC_ENET_CLSN | PC_ENET_RENA);
+	immap->im_ioport.iop_pcdir &= ~(PC_ENET_CLSN | PC_ENET_RENA);
+	immap->im_ioport.iop_pcso  |=  (PC_ENET_CLSN | PC_ENET_RENA);
 
 	/* Configure Serial Interface clock routing.
 	 * First, clear all SCC bits to zero, then set the ones we want.
@@ -896,14 +904,18 @@ static int __init scc_enet_init(void)
 	/* It is now OK to enable the Ethernet transmitter.
 	 * Unfortunately, there are board implementation differences here.
 	 */
-#if   (!defined (PB_ENET_TENA) &&  defined (PC_ENET_TENA))
+#if   (!defined (PB_ENET_TENA) &&  defined (PC_ENET_TENA) && !defined (PE_ENET_TENA))
 	immap->im_ioport.iop_pcpar |=  PC_ENET_TENA;
 	immap->im_ioport.iop_pcdir &= ~PC_ENET_TENA;
-#elif ( defined (PB_ENET_TENA) && !defined (PC_ENET_TENA))
+#elif ( defined (PB_ENET_TENA) && !defined (PC_ENET_TENA) && !defined (PE_ENET_TENA))
 	cp->cp_pbpar |= PB_ENET_TENA;
 	cp->cp_pbdir |= PB_ENET_TENA;
+#elif ( !defined (PB_ENET_TENA) && !defined (PC_ENET_TENA) && defined (PE_ENET_TENA))
+	cp->cp_pepar |=  PE_ENET_TENA;
+	cp->cp_pedir &= ~PE_ENET_TENA;
+	cp->cp_peso  |=  PE_ENET_TENA;
 #else
-#error Configuration Error: define exactly ONE of PB_ENET_TENA, PC_ENET_TENA
+#error Configuration Error: define exactly ONE of PB_ENET_TENA, PC_ENET_TENA, PE_ENET_TENA
 #endif
 
 #if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC)
@@ -936,6 +948,29 @@ static int __init scc_enet_init(void)
 	*((volatile uint *)BCSR1) &= ~BCSR1_ETHEN;
 #endif
 
+#ifdef CONFIG_MPC885ADS
+
+	/* Deassert PHY reset and enable the PHY.
+	 */
+	{
+		volatile uint __iomem *bcsr = ioremap(BCSR_ADDR, BCSR_SIZE);
+		uint tmp;
+
+		tmp = in_be32(bcsr + 1 /* BCSR1 */);
+		tmp |= BCSR1_ETHEN;
+		out_be32(bcsr + 1, tmp);
+		tmp = in_be32(bcsr + 4 /* BCSR4 */);
+		tmp |= BCSR4_ETH10_RST;
+		out_be32(bcsr + 4, tmp);
+		iounmap(bcsr);
+	}
+
+	/* On MPC885ADS SCC ethernet PHY defaults to the full duplex mode
+	 * upon reset. SCC is set to half duplex by default. So this
+	 * inconsistency should be better fixed by the software.
+	 */
+#endif
+
 	dev->base_addr = (unsigned long)ep;
 #if 0
 	dev->name = "CPM_ENET";
@@ -969,3 +1004,4 @@ static int __init scc_enet_init(void)
 }
 
 module_init(scc_enet_init);
+
diff --git a/arch/ppc/8xx_io/fec.c b/arch/ppc/8xx_io/fec.c
--- a/arch/ppc/8xx_io/fec.c
+++ b/arch/ppc/8xx_io/fec.c
@@ -173,7 +173,7 @@ struct fec_enet_private {
 	uint	phy_status;
 	uint	phy_speed;
 	phy_info_t	*phy;
-	struct tq_struct phy_task;
+	struct work_struct phy_task;
 
 	uint	sequence_done;
 
@@ -199,7 +199,8 @@ static int fec_enet_start_xmit(struct sk
 #ifdef	CONFIG_USE_MDIO
 static void fec_enet_mii(struct net_device *dev);
 #endif	/* CONFIG_USE_MDIO */
-static void fec_enet_interrupt(int irq, void * dev_id, struct pt_regs * regs);
+static irqreturn_t fec_enet_interrupt(int irq, void * dev_id,
+		       					struct pt_regs * regs);
 #ifdef CONFIG_FEC_PACKETHOOK
 static void  fec_enet_tx(struct net_device *dev, __u32 regval);
 static void  fec_enet_rx(struct net_device *dev, __u32 regval);
@@ -471,7 +472,7 @@ fec_timeout(struct net_device *dev)
 /* The interrupt handler.
  * This is called from the MPC core interrupt.
  */
-static	void
+static	irqreturn_t
 fec_enet_interrupt(int irq, void * dev_id, struct pt_regs * regs)
 {
 	struct	net_device *dev = dev_id;
@@ -525,6 +526,7 @@ printk("%s[%d] %s: unexpected FEC_ENET_M
 		}
 
 	}
+	return IRQ_RETVAL(IRQ_HANDLED);
 }
 
 
@@ -1263,8 +1265,9 @@ static void mii_display_status(struct ne
 	printk(".\n");
 }
 
-static void mii_display_config(struct net_device *dev)
+static void mii_display_config(void *priv)
 {
+	struct net_device *dev = (struct net_device *)priv;
 	struct fec_enet_private *fep = dev->priv;
 	volatile uint *s = &(fep->phy_status);
 
@@ -1294,8 +1297,9 @@ static void mii_display_config(struct ne
 	fep->sequence_done = 1;
 }
 
-static void mii_relink(struct net_device *dev)
+static void mii_relink(void *priv)
 {
+	struct net_device *dev = (struct net_device *)priv;
 	struct fec_enet_private *fep = dev->priv;
 	int duplex;
 
@@ -1323,18 +1327,16 @@ static void mii_queue_relink(uint mii_re
 {
 	struct fec_enet_private *fep = dev->priv;
 
-	fep->phy_task.routine = (void *)mii_relink;
-	fep->phy_task.data = dev;
-	schedule_task(&fep->phy_task);
+	INIT_WORK(&fep->phy_task, mii_relink, (void *)dev);
+	schedule_work(&fep->phy_task);
 }
 
 static void mii_queue_config(uint mii_reg, struct net_device *dev)
 {
 	struct fec_enet_private *fep = dev->priv;
 
-	fep->phy_task.routine = (void *)mii_display_config;
-	fep->phy_task.data = dev;
-	schedule_task(&fep->phy_task);
+	INIT_WORK(&fep->phy_task, mii_display_config, (void *)dev);
+	schedule_work(&fep->phy_task);
 }
 
 
@@ -1403,11 +1405,11 @@ mii_discover_phy(uint mii_reg, struct ne
 
 /* This interrupt occurs when the PHY detects a link change.
 */
-static void
+static
 #ifdef CONFIG_RPXCLASSIC
-mii_link_interrupt(void *dev_id)
+void mii_link_interrupt(void *dev_id)
 #else
-mii_link_interrupt(int irq, void * dev_id, struct pt_regs * regs)
+irqreturn_t mii_link_interrupt(int irq, void * dev_id, struct pt_regs * regs)
 #endif
 {
 #ifdef	CONFIG_USE_MDIO
@@ -1440,6 +1442,9 @@ mii_link_interrupt(int irq, void * dev_i
 printk("%s[%d] %s: unexpected Link interrupt\n", __FILE__,__LINE__,__FUNCTION__);
 #endif	/* CONFIG_USE_MDIO */
 
+#ifndef CONFIG_RPXCLASSIC
+	return IRQ_RETVAL(IRQ_HANDLED);
+#endif	/* CONFIG_RPXCLASSIC */
 }
 
 static int
@@ -1575,7 +1580,7 @@ static int __init fec_enet_init(void)
 	struct fec_enet_private *fep;
 	int i, j, k, err;
 	unsigned char	*eap, *iap, *ba;
-	unsigned long	mem_addr;
+	dma_addr_t	mem_addr;
 	volatile	cbd_t	*bdp;
 	cbd_t		*cbd_base;
 	volatile	immap_t	*immap;
@@ -1640,7 +1645,8 @@ static int __init fec_enet_init(void)
 		printk("FEC initialization failed.\n");
 		return 1;
 	}
-	cbd_base = (cbd_t *)consistent_alloc(GFP_KERNEL, PAGE_SIZE, &mem_addr);
+	cbd_base = (cbd_t *)dma_alloc_coherent(dev->class_dev.dev, PAGE_SIZE,
+					       &mem_addr, GFP_KERNEL);
 
 	/* Set receive and transmit descriptor base.
 	*/
@@ -1657,7 +1663,10 @@ static int __init fec_enet_init(void)
 
 		/* Allocate a page.
 		*/
-		ba = (unsigned char *)consistent_alloc(GFP_KERNEL, PAGE_SIZE, &mem_addr);
+		ba = (unsigned char *)dma_alloc_coherent(dev->class_dev.dev,
+							 PAGE_SIZE,
+							 &mem_addr,
+							 GFP_KERNEL);
 		/* BUG: no check for failure */
 
 		/* Initialize the BD for every fragment in the page.
diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig
--- a/arch/ppc/Kconfig
+++ b/arch/ppc/Kconfig
@@ -85,9 +85,11 @@ config POWER4
 	bool "POWER4 and 970 (G5)"
 
 config 8xx
-	depends on BROKEN
 	bool "8xx"
 
+config E200
+	bool "e200"
+
 config E500
 	bool "e500"
 
@@ -98,12 +100,12 @@ config PPC_FPU
 
 config BOOKE
 	bool
-	depends on E500
+	depends on E200 || E500
 	default y
 
 config FSL_BOOKE
 	bool
-	depends on E500
+	depends on E200 || E500
 	default y
 
 config PTE_64BIT
@@ -141,16 +143,16 @@ config ALTIVEC
 
 config SPE
 	bool "SPE Support"
-	depends on E500
+	depends on E200 || E500
 	---help---
 	  This option enables kernel support for the Signal Processing
 	  Extensions (SPE) to the PowerPC processor. The kernel currently
 	  supports saving and restoring SPE registers, and turning on the
 	  'spe enable' bit so user processes can execute SPE instructions.
 
-	  This option is only usefully if you have a processor that supports
+	  This option is only useful if you have a processor that supports
 	  SPE (e500, otherwise known as 85xx series), but does not have any
-	  affect on a non-spe cpu (it does, however add code to the kernel).
+	  effect on a non-spe cpu (it does, however add code to the kernel).
 
 	  If in doubt, say Y here.
 
@@ -200,7 +202,7 @@ config TAU_AVERAGE
 
 config MATH_EMULATION
 	bool "Math emulation"
-	depends on 4xx || 8xx || E500
+	depends on 4xx || 8xx || E200 || E500
 	---help---
 	  Some PowerPC chips designed for embedded applications do not have
 	  a floating-point unit and therefore do not implement the
@@ -214,6 +216,26 @@ config MATH_EMULATION
 	  here.  Saying Y here will not hurt performance (on any machine) but
 	  will increase the size of the kernel.
 
+config KEXEC
+	bool "kexec system call (EXPERIMENTAL)"
+	depends on EXPERIMENTAL
+	help
+	  kexec is a system call that implements the ability to shutdown your
+	  current kernel, and to start another kernel.  It is like a reboot
+	  but it is indepedent of the system firmware.   And like a reboot
+	  you can start any kernel with it, not just Linux.
+
+	  The name comes from the similiarity to the exec system call.
+
+	  It is an ongoing process to be certain the hardware in a machine
+	  is properly shutdown, so do not be surprised if this code does not
+	  initially work for you.  It may help to enable device hotplugging
+	  support.  As of this writing the exact hardware interface is
+	  strongly in flux, so no good recommendation can be made.
+
+	  In the GameCube implementation, kexec allows you to load and
+	  run DOL files, including kernel and homebrew DOLs.
+
 source "drivers/cpufreq/Kconfig"
 
 config CPU_FREQ_PMAC
@@ -254,13 +276,16 @@ config PPC_STD_MMU
 
 config NOT_COHERENT_CACHE
 	bool
-	depends on 4xx || 8xx
+	depends on 4xx || 8xx || E200
 	default y
 
 endmenu
 
 menu "Platform options"
 
+config FADS
+	bool
+
 choice
 	prompt "8xx Machine Type"
 	depends on 8xx
@@ -376,8 +401,25 @@ config BSEIP
 	  26MB DRAM, 4MB flash, Ethernet, a 16K-gate FPGA, USB, an LCD/video
 	  controller, and two RS232 ports.
 
-config FADS
+config MPC8XXFADS
 	bool "FADS"
+	select FADS
+
+config MPC86XADS
+	bool "MPC86XADS"
+	help
+	  MPC86x Application Development System by Freescale Semiconductor.
+	  The MPC86xADS is meant to serve as a platform for s/w and h/w
+	  development around the MPC86X processor families.
+	select FADS
+
+config MPC885ADS
+	bool "MPC885ADS"
+	help
+	  Freescale Semiconductor MPC885 Application Development System (ADS).
+	  Also known as DUET.
+	  The MPC885ADS is meant to serve as a platform for s/w and h/w
+	  development around the MPC885 processor family.
 
 config TQM823L
 	bool "TQM823L"
@@ -516,6 +558,7 @@ config PPC_MULTIPLATFORM
 
 config APUS
 	bool "Amiga-APUS"
+	depends on BROKEN
 	help
 	  Select APUS if configuring for a PowerUP Amiga.
 	  More information is available at:
@@ -605,6 +648,7 @@ config PAL4
 
 config GEMINI
 	bool "Synergy-Gemini"
+	depends on BROKEN
 	help
 	  Select Gemini if configuring for a Synergy Microsystems' Gemini
 	  series Single Board Computer.  More information is available at:
@@ -826,11 +870,6 @@ config MPC10X_BRIDGE
 	depends on PCORE || POWERPMC250 || LOPEC || SANDPOINT
 	default y
 
-config FSL_OCP
-	bool
-	depends on MPC10X_BRIDGE
-	default y
-
 config MPC10X_OPENPIC
 	bool
 	depends on POWERPMC250 || LOPEC || SANDPOINT
@@ -840,6 +879,13 @@ config MPC10X_STORE_GATHERING
 	bool "Enable MPC10x store gathering"
 	depends on MPC10X_BRIDGE
 
+config SANDPOINT_ENABLE_UART1
+	bool "Enable DUART mode on Sandpoint"
+	depends on SANDPOINT
+	help
+	  If this option is enabled then the MPC824x processor will run
+	  in DUART mode instead of UART mode.
+
 config CPC710_DATA_GATHERING
 	bool "Enable CPC710 data gathering"
 	depends on K2
@@ -865,6 +911,7 @@ config PPCBUG_NVRAM
 	default y if PPC_PREP
 
 config SMP
+	depends on PPC_STD_MMU
 	bool "Symmetric multi-processing support"
 	---help---
 	  This enables support for systems with more than one CPU. If you have
@@ -884,7 +931,7 @@ config SMP
 
 config IRQ_ALL_CPUS
 	bool "Distribute interrupts on all CPUs by default"
-	depends on SMP
+	depends on SMP && !MV64360
 	help
 	  This option gives the kernel permission to distribute IRQs across
 	  multiple CPUs.  Saying N here will route all IRQs to the first
@@ -897,19 +944,13 @@ config NR_CPUS
 	depends on SMP
 	default "4"
 
-config PREEMPT
-	bool "Preemptible Kernel"
-	help
-	  This option reduces the latency of the kernel when reacting to
-	  real-time or interactive events by allowing a low priority process to
-	  be preempted even if it is in kernel mode executing a system call.
-
-	  Say Y here if you are building a kernel for a desktop, embedded
-	  or real-time system.  Say N if you are unsure.
-
 config HIGHMEM
 	bool "High memory support"
 
+source kernel/Kconfig.hz
+source kernel/Kconfig.preempt
+source "mm/Kconfig"
+
 source "fs/Kconfig.binfmt"
 
 config PROC_DEVICETREE
@@ -1081,7 +1122,26 @@ config PROC_HARDWARE
 
 source "drivers/zorro/Kconfig"
 
+if !44x || BROKEN
 source kernel/power/Kconfig
+endif
+
+config SECCOMP
+	bool "Enable seccomp to safely compute untrusted bytecode"
+	depends on PROC_FS
+	default y
+	help
+	  This kernel feature is useful for number crunching applications
+	  that may need to compute untrusted bytecode during their
+	  execution. By using pipes or other transports made available to
+	  the process as file descriptors supporting the read/write
+	  syscalls, it's possible to isolate those applications in
+	  their own address space using seccomp. Once seccomp is
+	  enabled via /proc/<pid>/seccomp, it cannot be disabled
+	  and the task is only allowed to execute a few safe syscalls
+	  defined by each seccomp mode.
+
+	  If unsure, say Y. Only embedded should say N here.
 
 endmenu
 
@@ -1298,6 +1358,8 @@ config PIN_TLB
 	depends on ADVANCED_OPTIONS && 8xx
 endmenu
 
+source "net/Kconfig"
+
 source "drivers/Kconfig"
 
 source "fs/Kconfig"
diff --git a/arch/ppc/Kconfig.debug b/arch/ppc/Kconfig.debug
--- a/arch/ppc/Kconfig.debug
+++ b/arch/ppc/Kconfig.debug
@@ -66,7 +66,7 @@ config SERIAL_TEXT_DEBUG
 
 config PPC_OCP
 	bool
-	depends on IBM_OCP || FSL_OCP || XILINX_OCP
+	depends on IBM_OCP || XILINX_OCP
 	default y
 
 endmenu
diff --git a/arch/ppc/Makefile b/arch/ppc/Makefile
--- a/arch/ppc/Makefile
+++ b/arch/ppc/Makefile
@@ -29,7 +29,7 @@ CPP		= $(CC) -E $(CFLAGS)
 
 CHECKFLAGS	+= -D__powerpc__
 
-ifndef CONFIG_E500
+ifndef CONFIG_FSL_BOOKE
 CFLAGS		+= -mstring
 endif
 
@@ -38,6 +38,7 @@ cpu-as-$(CONFIG_4xx)		+= -Wa,-m405
 cpu-as-$(CONFIG_6xx)		+= -Wa,-maltivec
 cpu-as-$(CONFIG_POWER4)		+= -Wa,-maltivec
 cpu-as-$(CONFIG_E500)		+= -Wa,-me500
+cpu-as-$(CONFIG_E200)		+= -Wa,-me200
 
 AFLAGS += $(cpu-as-y)
 CFLAGS += $(cpu-as-y)
diff --git a/arch/ppc/boot/images/Makefile b/arch/ppc/boot/images/Makefile
--- a/arch/ppc/boot/images/Makefile
+++ b/arch/ppc/boot/images/Makefile
@@ -6,12 +6,17 @@ MKIMAGE		:= $(srctree)/scripts/mkuboot.s
 
 extra-y		:= vmlinux.bin vmlinux.gz
 
+# two make processes may write to vmlinux.gz at the same time with make -j
+quiet_cmd_mygzip = GZIP    $@
+cmd_mygzip = gzip -f -9 < $< > $@.$$$$ && mv $@.$$$$ $@
+
+
 OBJCOPYFLAGS_vmlinux.bin := -O binary
 $(obj)/vmlinux.bin: vmlinux FORCE
 	$(call if_changed,objcopy)
 
 $(obj)/vmlinux.gz: $(obj)/vmlinux.bin FORCE
-	$(call if_changed,gzip)
+	$(call if_changed,mygzip)
 
 quiet_cmd_uimage = UIMAGE  $@
       cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A ppc -O linux -T kernel \
diff --git a/arch/ppc/boot/ld.script b/arch/ppc/boot/ld.script
--- a/arch/ppc/boot/ld.script
+++ b/arch/ppc/boot/ld.script
@@ -58,9 +58,6 @@ SECTIONS
     *(.ramdisk)
     __ramdisk_end = .;
     . = ALIGN(4096);
-    __sysmap_begin = .;
-    *(.sysmap)
-    __sysmap_end = .;
     CONSTRUCTORS
   }
   _edata  =  .;
diff --git a/arch/ppc/boot/openfirmware/Makefile b/arch/ppc/boot/openfirmware/Makefile
--- a/arch/ppc/boot/openfirmware/Makefile
+++ b/arch/ppc/boot/openfirmware/Makefile
@@ -54,13 +54,10 @@ $(images)/ramdisk.image.gz:
 	@echo '          RAM disk image must be provided separately'
 	@/bin/false
 
-objcpxmon-$(CONFIG_XMON) := --add-section=.sysmap=System.map \
-	--set-section-flags=.sysmap=contents,alloc,load,readonly,data
 quiet_cmd_genimage = GEN     $@
       cmd_genimage = $(OBJCOPY) -R .comment       \
 	--add-section=.image=$(images)/vmlinux.gz \
-	--set-section-flags=.image=contents,alloc,load,readonly,data \
-	$(objcpxmon-y) $< $@
+	--set-section-flags=.image=contents,alloc,load,readonly,data $< $@
 
 targets += image.o
 $(obj)/image.o: $(obj)/dummy.o $(images)/vmlinux.gz FORCE
diff --git a/arch/ppc/boot/openfirmware/chrpmain.c b/arch/ppc/boot/openfirmware/chrpmain.c
--- a/arch/ppc/boot/openfirmware/chrpmain.c
+++ b/arch/ppc/boot/openfirmware/chrpmain.c
@@ -39,7 +39,7 @@ char *avail_high;
 
 #define SCRATCH_SIZE	(128 << 10)
 
-static char scratch[SCRATCH_SIZE];	/* 1MB of scratch space for gunzip */
+static char scratch[SCRATCH_SIZE];	/* 128k of scratch space for gunzip */
 
 typedef void (*kernel_start_t)(int, int, void *, unsigned int, unsigned int);
 
diff --git a/arch/ppc/boot/openfirmware/common.c b/arch/ppc/boot/openfirmware/common.c
--- a/arch/ppc/boot/openfirmware/common.c
+++ b/arch/ppc/boot/openfirmware/common.c
@@ -15,7 +15,6 @@
 #include <asm/page.h>
 
 /* Information from the linker */
-extern char __sysmap_begin, __sysmap_end;
 
 extern int strcmp(const char *s1, const char *s2);
 extern char *avail_ram, *avail_high;
@@ -116,14 +115,8 @@ void gunzip(void *dst, int dstlen, unsig
 void make_bi_recs(unsigned long addr, char *name, unsigned int mach,
 		unsigned long progend)
 {
-	unsigned long sysmap_size;
 	struct bi_record *rec;
 
-	/* Figure out the size of a possible System.map we're going to
-	 * pass along.
-	 * */
-	sysmap_size = (unsigned long)(&__sysmap_end) -
-		(unsigned long)(&__sysmap_begin);
 
 	/* leave a 1MB gap then align to the next 1MB boundary */
 	addr = _ALIGN(addr+ (1<<20) - 1, (1<<20));
@@ -147,15 +140,6 @@ void make_bi_recs(unsigned long addr, ch
 	rec->size = sizeof(struct bi_record) + 2 * sizeof(unsigned long);
 	rec = (struct bi_record *)((unsigned long)rec + rec->size);
 
-	if (sysmap_size) {
-		rec->tag = BI_SYSMAP;
-		rec->data[0] = (unsigned long)(&__sysmap_begin);
-		rec->data[1] = sysmap_size;
-		rec->size = sizeof(struct bi_record) + 2 *
-			sizeof(unsigned long);
-		rec = (struct bi_record *)((unsigned long)rec + rec->size);
-	}
-
 	rec->tag = BI_LAST;
 	rec->size = sizeof(struct bi_record);
 	rec = (struct bi_record *)((unsigned long)rec + rec->size);
diff --git a/arch/ppc/boot/simple/Makefile b/arch/ppc/boot/simple/Makefile
--- a/arch/ppc/boot/simple/Makefile
+++ b/arch/ppc/boot/simple/Makefile
@@ -61,6 +61,12 @@ zimageinitrd-$(CONFIG_IBM_OPENBIOS)	:= z
          end-$(CONFIG_EMBEDDEDBOOT)	:= embedded
         misc-$(CONFIG_EMBEDDEDBOOT)	:= misc-embedded.o
 
+      zimage-$(CONFIG_BAMBOO)		:= zImage-TREE
+zimageinitrd-$(CONFIG_BAMBOO)		:= zImage.initrd-TREE
+         end-$(CONFIG_BAMBOO)		:= bamboo
+  entrypoint-$(CONFIG_BAMBOO)		:= 0x01000000
+     extra.o-$(CONFIG_BAMBOO)		:= pibs.o
+
       zimage-$(CONFIG_EBONY)		:= zImage-TREE
 zimageinitrd-$(CONFIG_EBONY)		:= zImage.initrd-TREE
          end-$(CONFIG_EBONY)		:= ebony
@@ -203,7 +209,7 @@ $(obj)/zvmlinux: $(OBJS) $(LIBS) $(srctr
 		$(obj)/dummy.o $(obj)/image.o
 	$(LD) $(LD_ARGS) -o $@ $(OBJS) $(obj)/image.o $(LIBS)
 	$(OBJCOPY) $(OBJCOPY_ARGS) $@ $@ -R .comment -R .stab \
-		-R .stabstr -R .ramdisk -R .sysmap
+		-R .stabstr -R .ramdisk
 
 $(obj)/zvmlinux.initrd: $(OBJS) $(LIBS) $(srctree)/$(boot)/ld.script \
 		$(images)/vmlinux.gz $(obj)/dummy.o
@@ -215,7 +221,7 @@ $(obj)/zvmlinux.initrd: $(OBJS) $(LIBS) 
 		$(obj)/dummy.o $(obj)/image.o
 	$(LD) $(LD_ARGS) -o $@ $(OBJS) $(obj)/image.o $(LIBS)
 	$(OBJCOPY) $(OBJCOPY_ARGS) $@ $@ -R .comment -R .stab \
-		-R .stabstr -R .sysmap
+		-R .stabstr
 
 # Sort-of dummy rules, that let us format the image we want.
 zImage: $(images)/$(zimage-y) $(obj)/zvmlinux
diff --git a/arch/ppc/boot/simple/misc.c b/arch/ppc/boot/simple/misc.c
--- a/arch/ppc/boot/simple/misc.c
+++ b/arch/ppc/boot/simple/misc.c
@@ -222,7 +222,7 @@ decompress_kernel(unsigned long load_add
 	puts("\n");
 
 	puts("Uncompressing Linux...");
-	gunzip(0x0, 0x400000, zimage_start, &zimage_size);
+	gunzip(NULL, 0x400000, zimage_start, &zimage_size);
 	puts("done.\n");
 
 	/* get the bi_rec address */
diff --git a/arch/ppc/boot/simple/mpc10x_memory.c b/arch/ppc/boot/simple/mpc10x_memory.c
--- a/arch/ppc/boot/simple/mpc10x_memory.c
+++ b/arch/ppc/boot/simple/mpc10x_memory.c
@@ -33,7 +33,7 @@
 
 #define MPC10X_PCI_OP(rw, size, type, op, mask)			 	\
 static void								\
-mpc10x_##rw##_config_##size(unsigned int *cfg_addr, 			\
+mpc10x_##rw##_config_##size(unsigned int __iomem *cfg_addr, 			\
 		unsigned int *cfg_data, int devfn, int offset,		\
 		type val)						\
 {									\
diff --git a/arch/ppc/boot/simple/pibs.c b/arch/ppc/boot/simple/pibs.c
--- a/arch/ppc/boot/simple/pibs.c
+++ b/arch/ppc/boot/simple/pibs.c
@@ -91,9 +91,11 @@ load_kernel(unsigned long load_addr, int
 
 	mac64 = simple_strtoull((char *)PIBS_MAC_BASE, 0, 16);
 	memcpy(hold_residual->bi_enetaddr, (char *)&mac64+2, 6);
-#ifdef CONFIG_440GX
+#if defined(CONFIG_440GX) || defined(CONFIG_440EP)
 	mac64 = simple_strtoull((char *)(PIBS_MAC_BASE+PIBS_MAC_OFFSET), 0, 16);
 	memcpy(hold_residual->bi_enet1addr, (char *)&mac64+2, 6);
+#endif
+#ifdef CONFIG_440GX
 	mac64 = simple_strtoull((char *)(PIBS_MAC_BASE+PIBS_MAC_OFFSET*2), 0, 16);
 	memcpy(hold_residual->bi_enet2addr, (char *)&mac64+2, 6);
 	mac64 = simple_strtoull((char *)(PIBS_MAC_BASE+PIBS_MAC_OFFSET*3), 0, 16);
diff --git a/arch/ppc/boot/utils/addSystemMap.c b/arch/ppc/boot/utils/addSystemMap.c
deleted file mode 100644
--- a/arch/ppc/boot/utils/addSystemMap.c
+++ /dev/null
@@ -1,186 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <byteswap.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-void xlate( char * inb, char * trb, unsigned len )
-{
-    unsigned i;
-    for (  i=0; i<len; ++i ) {
-	char c = *inb++;
-	char c1 = c >> 4;
-	char c2 = c & 0xf;
-	if ( c1 > 9 )
-	    c1 = c1 + 'A' - 10;
-	else
-	    c1 = c1 + '0';
-	if ( c2 > 9 )
-	    c2 = c2 + 'A' - 10;
-	else
-	    c2 = c2 + '0';
-	*trb++ = c1;
-	*trb++ = c2;
-    }
-    *trb = 0;
-}
-
-#define ElfHeaderSize  (64 * 1024)
-#define ElfPages  (ElfHeaderSize / 4096)
-#define KERNELBASE (0xc0000000)
-
-void get4k( /*istream *inf*/FILE *file, char *buf )
-{
-    unsigned j;
-    unsigned num = fread(buf, 1, 4096, file);
-    for (  j=num; j<4096; ++j )
-	buf[j] = 0;
-}
-
-void put4k( /*ostream *outf*/FILE *file, char *buf )
-{
-    fwrite(buf, 1, 4096, file);
-}
-
-int main(int argc, char **argv)
-{
-    char inbuf[4096];
-    FILE *ramDisk = NULL;
-    FILE *inputVmlinux = NULL;
-    FILE *outputVmlinux = NULL;
-    unsigned i = 0;
-    unsigned long ramFileLen = 0;
-    unsigned long ramLen = 0;
-    unsigned long roundR = 0;
-    unsigned long kernelLen = 0;
-    unsigned long actualKernelLen = 0;
-    unsigned long round = 0;
-    unsigned long roundedKernelLen = 0;
-    unsigned long ramStartOffs = 0;
-    unsigned long ramPages = 0;
-    unsigned long roundedKernelPages = 0;
-    if ( argc < 2 ) {
-	printf("Name of System Map file missing.\n");
-	exit(1);
-    }
-
-    if ( argc < 3 ) {
-	printf("Name of vmlinux file missing.\n");
-	exit(1);
-    }
-
-    if ( argc < 4 ) {
-	printf("Name of vmlinux output file missing.\n");
-	exit(1);
-    }
-
-    ramDisk = fopen(argv[1], "r");
-    if ( ! ramDisk ) {
-	printf("System Map file \"%s\" failed to open.\n", argv[1]);
-	exit(1);
-    }
-    inputVmlinux = fopen(argv[2], "r");
-    if ( ! inputVmlinux ) {
-	printf("vmlinux file \"%s\" failed to open.\n", argv[2]);
-	exit(1);
-    }
-    outputVmlinux = fopen(argv[3], "w");
-    if ( ! outputVmlinux ) {
-	printf("output vmlinux file \"%s\" failed to open.\n", argv[3]);
-	exit(1);
-    }
-    fseek(ramDisk, 0, SEEK_END);
-    ramFileLen = ftell(ramDisk);
-    fseek(ramDisk, 0, SEEK_SET);
-    printf("%s file size = %ld\n", argv[1], ramFileLen);
-
-    ramLen = ramFileLen;
-
-    roundR = 4096 - (ramLen % 4096);
-    if ( roundR ) {
-	printf("Rounding System Map file up to a multiple of 4096, adding %ld\n", roundR);
-	ramLen += roundR;
-    }
-
-    printf("Rounded System Map size is %ld\n", ramLen);
-    fseek(inputVmlinux, 0, SEEK_END);
-    kernelLen = ftell(inputVmlinux);
-    fseek(inputVmlinux, 0, SEEK_SET);
-    printf("kernel file size = %ld\n", kernelLen);
-    if ( kernelLen == 0 ) {
-	printf("You must have a linux kernel specified as argv[2]\n");
-	exit(1);
-    }
-
-    actualKernelLen = kernelLen - ElfHeaderSize;
-
-    printf("actual kernel length (minus ELF header) = %ld\n", actualKernelLen);
-
-    round = actualKernelLen % 4096;
-    roundedKernelLen = actualKernelLen;
-    if ( round )
-	roundedKernelLen += (4096 - round);
-
-    printf("actual kernel length rounded up to a 4k multiple = %ld\n", roundedKernelLen);
-
-    ramStartOffs = roundedKernelLen;
-    ramPages = ramLen / 4096;
-
-    printf("System map pages to copy = %ld\n", ramPages);
-
-    // Copy 64K ELF header
-      for (i=0; i<(ElfPages); ++i) {
-	  get4k( inputVmlinux, inbuf );
-	  put4k( outputVmlinux, inbuf );
-      }
-
-
-
-    roundedKernelPages = roundedKernelLen / 4096;
-
-    fseek(inputVmlinux, ElfHeaderSize, SEEK_SET);
-
-    {
-	for ( i=0; i<roundedKernelPages; ++i ) {
-	    get4k( inputVmlinux, inbuf );
-	    if ( i == 0 ) {
-		unsigned long * p;
-		printf("Storing embedded_sysmap_start at 0x3c\n");
-		p = (unsigned long *)(inbuf + 0x3c);
-
-#if (BYTE_ORDER == __BIG_ENDIAN)
-		*p = ramStartOffs;
-#else
-		*p = bswap_32(ramStartOffs);
-#endif
-
-		printf("Storing embedded_sysmap_end at 0x44\n");
-		p = (unsigned long *)(inbuf + 0x44);
-#if (BYTE_ORDER == __BIG_ENDIAN)
-		*p = ramStartOffs + ramFileLen;
-#else
-		*p = bswap_32(ramStartOffs + ramFileLen);
-#endif
-	    }
-	    put4k( outputVmlinux, inbuf );
-	}
-    }
-
-    {
-	for ( i=0; i<ramPages; ++i ) {
-	    get4k( ramDisk, inbuf );
-	    put4k( outputVmlinux, inbuf );
-	}
-    }
-
-
-    fclose(ramDisk);
-    fclose(inputVmlinux);
-    fclose(outputVmlinux);
-    /* Set permission to executable */
-    chmod(argv[3], S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH);
-
-    return 0;
-
-}
-
diff --git a/arch/ppc/configs/bamboo_defconfig b/arch/ppc/configs/bamboo_defconfig
new file mode 100644
--- /dev/null
+++ b/arch/ppc/configs/bamboo_defconfig
@@ -0,0 +1,943 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.12
+# Tue Jun 28 15:24:25 2005
+#
+CONFIG_MMU=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_HAVE_DEC_LOCK=y
+CONFIG_PPC=y
+CONFIG_PPC32=y
+CONFIG_GENERIC_NVRAM=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+# CONFIG_HOTPLUG is not set
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+
+#
+# Processor
+#
+# CONFIG_6xx is not set
+# CONFIG_40x is not set
+CONFIG_44x=y
+# CONFIG_POWER3 is not set
+# CONFIG_POWER4 is not set
+# CONFIG_8xx is not set
+# CONFIG_E200 is not set
+# CONFIG_E500 is not set
+CONFIG_PPC_FPU=y
+CONFIG_BOOKE=y
+CONFIG_PTE_64BIT=y
+CONFIG_PHYS_64BIT=y
+# CONFIG_MATH_EMULATION is not set
+# CONFIG_KEXEC is not set
+# CONFIG_CPU_FREQ is not set
+CONFIG_4xx=y
+
+#
+# IBM 4xx options
+#
+CONFIG_BAMBOO=y
+# CONFIG_EBONY is not set
+# CONFIG_LUAN is not set
+# CONFIG_OCOTEA is not set
+CONFIG_440EP=y
+CONFIG_440=y
+CONFIG_IBM440EP_ERR42=y
+CONFIG_IBM_OCP=y
+# CONFIG_PPC4xx_DMA is not set
+CONFIG_PPC_GEN550=y
+# CONFIG_PM is not set
+CONFIG_NOT_COHERENT_CACHE=y
+
+#
+# Platform options
+#
+# CONFIG_PC_KEYBOARD is not set
+# CONFIG_SMP is not set
+# CONFIG_PREEMPT is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="ip=on"
+CONFIG_SECCOMP=y
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus options
+#
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+# CONFIG_PCI_LEGACY_PROC is not set
+# CONFIG_PCI_NAMES is not set
+# CONFIG_PCI_DEBUG is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# Advanced setup
+#
+# CONFIG_ADVANCED_OPTIONS is not set
+
+#
+# Default settings for advanced configuration options are used
+#
+CONFIG_HIGHMEM_START=0xfe000000
+CONFIG_LOWMEM_SIZE=0x30000000
+CONFIG_KERNEL_START=0xc0000000
+CONFIG_TASK_SIZE=0x80000000
+CONFIG_CONSISTENT_START=0xff100000
+CONFIG_CONSISTENT_SIZE=0x00200000
+CONFIG_BOOT_LOAD=0x01000000
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+# CONFIG_STANDALONE is not set
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_UB is not set
+# CONFIG_BLK_DEV_RAM is not set
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_LBD is not set
+# CONFIG_CDROM_PKTCDVD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+# CONFIG_BLK_DEV_IDECD is not set
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_BLK_DEV_IDESCSI is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+CONFIG_BLK_DEV_IDEPCI=y
+# CONFIG_IDEPCI_SHARE_IRQ is not set
+# CONFIG_BLK_DEV_OFFBOARD is not set
+# CONFIG_BLK_DEV_GENERIC is not set
+# CONFIG_BLK_DEV_OPTI621 is not set
+# CONFIG_BLK_DEV_SL82C105 is not set
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
+# CONFIG_IDEDMA_PCI_AUTO is not set
+# CONFIG_BLK_DEV_AEC62XX is not set
+# CONFIG_BLK_DEV_ALI15X3 is not set
+# CONFIG_BLK_DEV_AMD74XX is not set
+CONFIG_BLK_DEV_CMD64X=y
+# CONFIG_BLK_DEV_TRIFLEX is not set
+# CONFIG_BLK_DEV_CY82C693 is not set
+# CONFIG_BLK_DEV_CS5520 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_HPT34X is not set
+# CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_SC1200 is not set
+# CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_BLK_DEV_IT821X is not set
+# CONFIG_BLK_DEV_NS87415 is not set
+# CONFIG_BLK_DEV_PDC202XX_OLD is not set
+# CONFIG_BLK_DEV_PDC202XX_NEW is not set
+# CONFIG_BLK_DEV_SVWKS is not set
+# CONFIG_BLK_DEV_SIIMAGE is not set
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+# CONFIG_BLK_DEV_VIA82CXXX is not set
+# CONFIG_IDE_ARM is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_IVB is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+CONFIG_SCSI=y
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+# CONFIG_BLK_DEV_SD is not set
+CONFIG_CHR_DEV_ST=y
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+
+#
+# SCSI Transport Attributes
+#
+CONFIG_SCSI_SPI_ATTRS=y
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_EATA is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_GDTH is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+CONFIG_SCSI_SYM53C8XX_2=y
+CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1
+CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
+CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
+# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
+# CONFIG_SCSI_IPR is not set
+# CONFIG_SCSI_QLOGIC_FC is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+CONFIG_SCSI_QLA2XXX=y
+# CONFIG_SCSI_QLA21XX is not set
+# CONFIG_SCSI_QLA22XX is not set
+# CONFIG_SCSI_QLA2300 is not set
+# CONFIG_SCSI_QLA2322 is not set
+# CONFIG_SCSI_QLA6312 is not set
+# CONFIG_SCSI_LPFC is not set
+# CONFIG_SCSI_DC395x is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_NSP32 is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+# CONFIG_FUSION_SPI is not set
+# CONFIG_FUSION_FC is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Macintosh device drivers
+#
+
+#
+# Networking support
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_IP_TCPDIAG=y
+# CONFIG_IP_TCPDIAG_IPV6 is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS is not set
+# CONFIG_IPV6 is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+
+#
+# IP: Netfilter Configuration
+#
+# CONFIG_IP_NF_CONNTRACK is not set
+# CONFIG_IP_NF_CONNTRACK_MARK is not set
+# CONFIG_IP_NF_QUEUE is not set
+# CONFIG_IP_NF_IPTABLES is not set
+# CONFIG_IP_NF_ARPTABLES is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+CONFIG_IBM_EMAC=y
+# CONFIG_IBM_EMAC_ERRMSG is not set
+CONFIG_IBM_EMAC_RXB=64
+CONFIG_IBM_EMAC_TXB=8
+CONFIG_IBM_EMAC_FGAP=8
+CONFIG_IBM_EMAC_SKBRES=0
+CONFIG_NET_PCI=y
+# CONFIG_PCNET32 is not set
+# CONFIG_AMD8111_ETH is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_B44 is not set
+# CONFIG_FORCEDETH is not set
+# CONFIG_DGRS is not set
+CONFIG_EEPRO100=y
+# CONFIG_E100 is not set
+# CONFIG_FEALNX is not set
+CONFIG_NATSEMI=y
+# CONFIG_NE2K_PCI is not set
+# CONFIG_8139CP is not set
+# CONFIG_8139TOO 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
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+CONFIG_E1000=y
+# CONFIG_E1000_NAPI is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_VIA_VELOCITY is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NET_FC is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+# CONFIG_SERIO_SERPORT is not set
+# CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_EXTENDED=y
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_RSA is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB=y
+CONFIG_USB_DEBUG=y
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEVICEFS is not set
+# CONFIG_USB_BANDWIDTH is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_EHCI_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_OHCI_HCD is not set
+# CONFIG_USB_UHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_BLUETOOTH_TTY is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+#
+# CONFIG_USB_STORAGE is not set
+
+#
+# USB Input Devices
+#
+# CONFIG_USB_HID is not set
+
+#
+# USB HID Boot Protocol drivers
+#
+# CONFIG_USB_KBD is not set
+# CONFIG_USB_MOUSE is not set
+# CONFIG_USB_AIPTEK is not set
+# CONFIG_USB_WACOM is not set
+# CONFIG_USB_ACECAD is not set
+# CONFIG_USB_KBTAB is not set
+# CONFIG_USB_POWERMATE is not set
+# CONFIG_USB_MTOUCH is not set
+# CONFIG_USB_ITMTOUCH is not set
+# CONFIG_USB_EGALAX is not set
+# CONFIG_USB_XPAD is not set
+# CONFIG_USB_ATI_REMOTE is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB Multimedia devices
+#
+# CONFIG_USB_DABUSB is not set
+
+#
+# Video4Linux support is needed for USB Multimedia device support
+#
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+CONFIG_USB_PEGASUS=y
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+CONFIG_USB_MON=y
+
+#
+# USB port drivers
+#
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGETKIT is not set
+# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_IDMOUSE is not set
+
+#
+# USB DSL modem support
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# SN Devices
+#
+
+#
+# File systems
+#
+# CONFIG_EXT2_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+
+#
+# XFS support
+#
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+# CONFIG_DEVPTS_FS_XATTR is not set
+# CONFIG_TMPFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_FS is not set
+# CONFIG_KGDB is not set
+# CONFIG_XMON is not set
+CONFIG_BDI_SWITCH=y
+# CONFIG_SERIAL_TEXT_DEBUG is not set
+CONFIG_PPC_OCP=y
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
diff --git a/arch/ppc/configs/common_defconfig b/arch/ppc/configs/common_defconfig
--- a/arch/ppc/configs/common_defconfig
+++ b/arch/ppc/configs/common_defconfig
@@ -1,15 +1,17 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc2
-# Thu Nov 18 08:22:35 2004
+# Linux kernel version: 2.6.13-rc3
+# Wed Jul 13 13:34:24 2005
 #
 CONFIG_MMU=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_HAVE_DEC_LOCK=y
 CONFIG_PPC=y
 CONFIG_PPC32=y
 CONFIG_GENERIC_NVRAM=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
 
 #
 # Code maturity level options
@@ -17,6 +19,7 @@ CONFIG_GENERIC_NVRAM=y
 CONFIG_EXPERIMENTAL=y
 CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
@@ -28,30 +31,33 @@ CONFIG_POSIX_MQUEUE=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
 CONFIG_HOTPLUG=y
 CONFIG_KOBJECT_UEVENT=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 # CONFIG_EMBEDDED is not set
 CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
 # CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
 
 #
 # Loadable module support
 #
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
-CONFIG_MODULE_FORCE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
 CONFIG_OBSOLETE_MODPARM=y
 CONFIG_MODVERSIONS=y
 # CONFIG_MODULE_SRCVERSION_ALL is not set
@@ -66,22 +72,27 @@ CONFIG_6xx=y
 # CONFIG_POWER3 is not set
 # CONFIG_POWER4 is not set
 # CONFIG_8xx is not set
+# CONFIG_E200 is not set
 # CONFIG_E500 is not set
+CONFIG_PPC_FPU=y
 CONFIG_ALTIVEC=y
 CONFIG_TAU=y
 # CONFIG_TAU_INT is not set
 # CONFIG_TAU_AVERAGE is not set
+# CONFIG_KEXEC is not set
 CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=y
 # CONFIG_CPU_FREQ_DEBUG is not set
-CONFIG_CPU_FREQ_PROC_INTF=y
+CONFIG_CPU_FREQ_STAT=m
+CONFIG_CPU_FREQ_STAT_DETAILS=y
 CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
 # CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
 CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
-# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
-# CONFIG_CPU_FREQ_GOV_USERSPACE is not set
-# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set
+CONFIG_CPU_FREQ_GOV_POWERSAVE=m
+CONFIG_CPU_FREQ_GOV_USERSPACE=m
+CONFIG_CPU_FREQ_GOV_ONDEMAND=m
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
 CONFIG_CPU_FREQ_PMAC=y
-CONFIG_CPU_FREQ_TABLE=y
 CONFIG_PPC601_SYNC_FIX=y
 CONFIG_PM=y
 CONFIG_PPC_STD_MMU=y
@@ -91,11 +102,15 @@ CONFIG_PPC_STD_MMU=y
 #
 CONFIG_PPC_MULTIPLATFORM=y
 # CONFIG_APUS is not set
+# CONFIG_KATANA is not set
 # CONFIG_WILLOW is not set
+# CONFIG_CPCI690 is not set
 # CONFIG_PCORE is not set
 # CONFIG_POWERPMC250 is not set
-# CONFIG_EV64260 is not set
+# CONFIG_CHESTNUT is not set
 # CONFIG_SPRUCE is not set
+# CONFIG_HDPU is not set
+# CONFIG_EV64260 is not set
 # CONFIG_LOPEC is not set
 # CONFIG_MCPN765 is not set
 # CONFIG_MVME5100 is not set
@@ -103,6 +118,7 @@ CONFIG_PPC_MULTIPLATFORM=y
 # CONFIG_PRPMC750 is not set
 # CONFIG_PRPMC800 is not set
 # CONFIG_SANDPOINT is not set
+# CONFIG_RADSTONE_PPC7D is not set
 # CONFIG_ADIR is not set
 # CONFIG_K2 is not set
 # CONFIG_PAL4 is not set
@@ -113,22 +129,40 @@ CONFIG_PPC_MULTIPLATFORM=y
 # CONFIG_RPX8260 is not set
 # CONFIG_TQM8260 is not set
 # CONFIG_ADS8272 is not set
+# CONFIG_PQ2FADS is not set
 # CONFIG_LITE5200 is not set
+# CONFIG_MPC834x_SYS is not set
 CONFIG_PPC_CHRP=y
 CONFIG_PPC_PMAC=y
 CONFIG_PPC_PREP=y
 CONFIG_PPC_OF=y
 CONFIG_PPCBUG_NVRAM=y
 # CONFIG_SMP is not set
-# CONFIG_PREEMPT is not set
 # CONFIG_HIGHMEM is not set
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_BINFMT_ELF=y
 CONFIG_BINFMT_MISC=m
 CONFIG_PROC_DEVICETREE=y
 CONFIG_PREP_RESIDUAL=y
 CONFIG_PROC_PREPRESIDUAL=y
-CONFIG_CMDLINE_BOOL=y
-CONFIG_CMDLINE="console=ttyS0,9600 console=tty0 root=/dev/sda2"
+# CONFIG_CMDLINE_BOOL is not set
+# CONFIG_PM_DEBUG is not set
+CONFIG_SOFTWARE_SUSPEND=y
+CONFIG_PM_STD_PARTITION=""
+# CONFIG_SECCOMP is not set
+CONFIG_ISA_DMA_API=y
 
 #
 # Bus options
@@ -137,18 +171,24 @@ CONFIG_ISA=y
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PCI=y
 CONFIG_PCI_DOMAINS=y
-CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
+# CONFIG_PCI_LEGACY_PROC is not set
+# CONFIG_PCI_NAMES is not set
+# CONFIG_PCI_DEBUG is not set
 
 #
 # PCCARD (PCMCIA/CardBus) support
 #
-# CONFIG_PCCARD is not set
+CONFIG_PCCARD=m
+# CONFIG_PCMCIA_DEBUG is not set
+# CONFIG_PCMCIA is not set
+CONFIG_CARDBUS=y
 
 #
 # PC-card bridges
 #
+CONFIG_YENTA=m
 CONFIG_PCMCIA_PROBE=y
+CONFIG_PCCARD_NONSTATIC=m
 
 #
 # Advanced setup
@@ -165,6 +205,143 @@ CONFIG_TASK_SIZE=0x80000000
 CONFIG_BOOT_LOAD=0x00800000
 
 #
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_IP_TCPDIAG=y
+# CONFIG_IP_TCPDIAG_IPV6 is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS is not set
+# CONFIG_IPV6 is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_IP_NF_CONNTRACK=m
+# CONFIG_IP_NF_CT_ACCT is not set
+CONFIG_IP_NF_CONNTRACK_MARK=y
+# CONFIG_IP_NF_CT_PROTO_SCTP is not set
+CONFIG_IP_NF_FTP=m
+CONFIG_IP_NF_IRC=m
+CONFIG_IP_NF_TFTP=m
+CONFIG_IP_NF_AMANDA=m
+CONFIG_IP_NF_QUEUE=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_LIMIT=m
+CONFIG_IP_NF_MATCH_IPRANGE=m
+CONFIG_IP_NF_MATCH_MAC=m
+CONFIG_IP_NF_MATCH_PKTTYPE=m
+CONFIG_IP_NF_MATCH_MARK=m
+CONFIG_IP_NF_MATCH_MULTIPORT=m
+CONFIG_IP_NF_MATCH_TOS=m
+CONFIG_IP_NF_MATCH_RECENT=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_DSCP=m
+CONFIG_IP_NF_MATCH_AH_ESP=m
+CONFIG_IP_NF_MATCH_LENGTH=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_MATCH_TCPMSS=m
+CONFIG_IP_NF_MATCH_HELPER=m
+CONFIG_IP_NF_MATCH_STATE=m
+CONFIG_IP_NF_MATCH_CONNTRACK=m
+CONFIG_IP_NF_MATCH_OWNER=m
+CONFIG_IP_NF_MATCH_ADDRTYPE=m
+CONFIG_IP_NF_MATCH_REALM=m
+CONFIG_IP_NF_MATCH_SCTP=m
+CONFIG_IP_NF_MATCH_COMMENT=m
+CONFIG_IP_NF_MATCH_CONNMARK=m
+CONFIG_IP_NF_MATCH_HASHLIMIT=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_LOG=m
+CONFIG_IP_NF_TARGET_ULOG=m
+CONFIG_IP_NF_TARGET_TCPMSS=m
+CONFIG_IP_NF_NAT=m
+CONFIG_IP_NF_NAT_NEEDED=y
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_TARGET_REDIRECT=m
+CONFIG_IP_NF_TARGET_NETMAP=m
+CONFIG_IP_NF_TARGET_SAME=m
+CONFIG_IP_NF_NAT_SNMP_BASIC=m
+CONFIG_IP_NF_NAT_IRC=m
+CONFIG_IP_NF_NAT_FTP=m
+CONFIG_IP_NF_NAT_TFTP=m
+CONFIG_IP_NF_NAT_AMANDA=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_TOS=m
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_DSCP=m
+CONFIG_IP_NF_TARGET_MARK=m
+CONFIG_IP_NF_TARGET_CLASSIFY=m
+CONFIG_IP_NF_TARGET_CONNMARK=m
+CONFIG_IP_NF_TARGET_CLUSTERIP=m
+CONFIG_IP_NF_RAW=m
+CONFIG_IP_NF_TARGET_NOTRACK=m
+CONFIG_IP_NF_ARPTABLES=m
+# CONFIG_IP_NF_ARPFILTER is not set
+# CONFIG_IP_NF_ARP_MANGLE is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+CONFIG_NET_CLS_ROUTE=y
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+CONFIG_NETPOLL=y
+# CONFIG_NETPOLL_RX is not set
+# CONFIG_NETPOLL_TRAP is not set
+CONFIG_NET_POLL_CONTROLLER=y
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+
+#
 # Device Drivers
 #
 
@@ -173,7 +350,8 @@ CONFIG_BOOT_LOAD=0x00800000
 #
 # CONFIG_STANDALONE is not set
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+CONFIG_FW_LOADER=m
+# CONFIG_DEBUG_DRIVER is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -183,7 +361,13 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 #
 # Parallel port support
 #
-# CONFIG_PARPORT is not set
+CONFIG_PARPORT=m
+CONFIG_PARPORT_PC=m
+CONFIG_PARPORT_SERIAL=m
+CONFIG_PARPORT_PC_FIFO=y
+CONFIG_PARPORT_PC_SUPERIO=y
+# CONFIG_PARPORT_GSC is not set
+CONFIG_PARPORT_1284=y
 
 #
 # Plug and Play support
@@ -194,18 +378,21 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # Block devices
 #
 CONFIG_BLK_DEV_FD=m
-# CONFIG_MAC_FLOPPY is not set
+CONFIG_MAC_FLOPPY=m
 # CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_UB is not set
 CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=4096
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
@@ -219,6 +406,7 @@ CONFIG_IOSCHED_NOOP=y
 CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
+# CONFIG_ATA_OVER_ETH is not set
 
 #
 # ATA/ATAPI/MFM/RLL support
@@ -247,7 +435,7 @@ CONFIG_IDEPCI_SHARE_IRQ=y
 # CONFIG_BLK_DEV_OFFBOARD is not set
 CONFIG_BLK_DEV_GENERIC=y
 # CONFIG_BLK_DEV_OPTI621 is not set
-CONFIG_BLK_DEV_SL82C105=y
+# CONFIG_BLK_DEV_SL82C105 is not set
 CONFIG_BLK_DEV_IDEDMA_PCI=y
 # CONFIG_BLK_DEV_IDEDMA_FORCED is not set
 CONFIG_IDEDMA_PCI_AUTO=y
@@ -264,6 +452,7 @@ CONFIG_BLK_DEV_CMD64X=y
 # CONFIG_BLK_DEV_HPT366 is not set
 # CONFIG_BLK_DEV_SC1200 is not set
 # CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_BLK_DEV_IT821X is not set
 # CONFIG_BLK_DEV_NS87415 is not set
 # CONFIG_BLK_DEV_PDC202XX_OLD is not set
 CONFIG_BLK_DEV_PDC202XX_NEW=y
@@ -299,19 +488,21 @@ CONFIG_CHR_DEV_ST=y
 CONFIG_BLK_DEV_SR=y
 CONFIG_BLK_DEV_SR_VENDOR=y
 CONFIG_CHR_DEV_SG=y
+# CONFIG_CHR_DEV_SCH is not set
 
 #
 # Some SCSI devices (e.g. CD jukebox) support multiple LUNs
 #
 # CONFIG_SCSI_MULTI_LUN is not set
 CONFIG_SCSI_CONSTANTS=y
-# CONFIG_SCSI_LOGGING is not set
+CONFIG_SCSI_LOGGING=y
 
 #
 # SCSI Transport Attributes
 #
 CONFIG_SCSI_SPI_ATTRS=y
 # CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
 
 #
 # SCSI low-level drivers
@@ -340,7 +531,6 @@ CONFIG_SCSI_AIC7XXX_OLD=m
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_DTC3280 is not set
 # CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_EATA_PIO is not set
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
 # CONFIG_SCSI_GDTH is not set
 # CONFIG_SCSI_GENERIC_NCR5380 is not set
@@ -348,6 +538,8 @@ CONFIG_SCSI_AIC7XXX_OLD=m
 # CONFIG_SCSI_IPS is not set
 # CONFIG_SCSI_INITIO is not set
 # CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_PPA is not set
+# CONFIG_SCSI_IMM is not set
 # CONFIG_SCSI_NCR53C406A is not set
 CONFIG_SCSI_SYM53C8XX_2=y
 CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0
@@ -358,17 +550,15 @@ CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
 # CONFIG_SCSI_PAS16 is not set
 # CONFIG_SCSI_PSI240I is not set
 # CONFIG_SCSI_QLOGIC_FAS is not set
-# CONFIG_SCSI_QLOGIC_ISP is not set
 # CONFIG_SCSI_QLOGIC_FC is not set
 # CONFIG_SCSI_QLOGIC_1280 is not set
-# CONFIG_SCSI_QLOGIC_1280_1040 is not set
 CONFIG_SCSI_QLA2XXX=y
 # CONFIG_SCSI_QLA21XX is not set
 # CONFIG_SCSI_QLA22XX is not set
 # CONFIG_SCSI_QLA2300 is not set
 # CONFIG_SCSI_QLA2322 is not set
 # CONFIG_SCSI_QLA6312 is not set
-# CONFIG_SCSI_QLA6322 is not set
+# CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_SYM53C416 is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
@@ -395,11 +585,40 @@ CONFIG_SCSI_MAC53C94=y
 # Fusion MPT device support
 #
 # CONFIG_FUSION is not set
+# CONFIG_FUSION_SPI is not set
+# CONFIG_FUSION_FC is not set
 
 #
 # IEEE 1394 (FireWire) support
 #
-# CONFIG_IEEE1394 is not set
+CONFIG_IEEE1394=m
+
+#
+# Subsystem Options
+#
+# CONFIG_IEEE1394_VERBOSEDEBUG is not set
+CONFIG_IEEE1394_OUI_DB=y
+CONFIG_IEEE1394_EXTRA_CONFIG_ROMS=y
+CONFIG_IEEE1394_CONFIG_ROM_IP1394=y
+# CONFIG_IEEE1394_EXPORT_FULL_API is not set
+
+#
+# Device Drivers
+#
+# CONFIG_IEEE1394_PCILYNX is not set
+CONFIG_IEEE1394_OHCI1394=m
+
+#
+# Protocol Drivers
+#
+CONFIG_IEEE1394_VIDEO1394=m
+CONFIG_IEEE1394_SBP2=m
+# CONFIG_IEEE1394_SBP2_PHYS_DMA is not set
+CONFIG_IEEE1394_ETH1394=m
+CONFIG_IEEE1394_DV1394=m
+CONFIG_IEEE1394_RAWIO=m
+CONFIG_IEEE1394_CMP=m
+CONFIG_IEEE1394_AMDTP=m
 
 #
 # I2O device support
@@ -412,8 +631,8 @@ CONFIG_SCSI_MAC53C94=y
 CONFIG_ADB=y
 CONFIG_ADB_CUDA=y
 CONFIG_ADB_PMU=y
-CONFIG_PMAC_PBOOK=y
 CONFIG_PMAC_APM_EMU=y
+CONFIG_PMAC_MEDIABAY=y
 CONFIG_PMAC_BACKLIGHT=y
 CONFIG_ADB_MACIO=y
 CONFIG_INPUT_ADBHID=y
@@ -423,138 +642,13 @@ CONFIG_THERM_ADT746X=m
 # CONFIG_ANSLCD is not set
 
 #
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK_DEV is not set
-CONFIG_UNIX=y
-# CONFIG_NET_KEY is not set
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-# CONFIG_IP_PNP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
-# CONFIG_ARPD is not set
-CONFIG_SYN_COOKIES=y
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_TUNNEL is not set
-CONFIG_IP_TCPDIAG=y
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-
-#
-# IP: Virtual Server Configuration
-#
-# CONFIG_IP_VS is not set
-# CONFIG_IPV6 is not set
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-
-#
-# IP: Netfilter Configuration
+# Network device support
 #
-CONFIG_IP_NF_CONNTRACK=m
-# CONFIG_IP_NF_CT_ACCT is not set
-# CONFIG_IP_NF_CONNTRACK_MARK is not set
-# CONFIG_IP_NF_CT_PROTO_SCTP is not set
-CONFIG_IP_NF_FTP=m
-CONFIG_IP_NF_IRC=m
-CONFIG_IP_NF_TFTP=m
-CONFIG_IP_NF_AMANDA=m
-# CONFIG_IP_NF_QUEUE is not set
-CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_MATCH_LIMIT=m
-CONFIG_IP_NF_MATCH_IPRANGE=m
-CONFIG_IP_NF_MATCH_MAC=m
-CONFIG_IP_NF_MATCH_PKTTYPE=m
-CONFIG_IP_NF_MATCH_MARK=m
-CONFIG_IP_NF_MATCH_MULTIPORT=m
-CONFIG_IP_NF_MATCH_TOS=m
-CONFIG_IP_NF_MATCH_RECENT=m
-CONFIG_IP_NF_MATCH_ECN=m
-CONFIG_IP_NF_MATCH_DSCP=m
-CONFIG_IP_NF_MATCH_AH_ESP=m
-CONFIG_IP_NF_MATCH_LENGTH=m
-CONFIG_IP_NF_MATCH_TTL=m
-CONFIG_IP_NF_MATCH_TCPMSS=m
-CONFIG_IP_NF_MATCH_HELPER=m
-CONFIG_IP_NF_MATCH_STATE=m
-CONFIG_IP_NF_MATCH_CONNTRACK=m
-CONFIG_IP_NF_MATCH_OWNER=m
-# CONFIG_IP_NF_MATCH_ADDRTYPE is not set
-# CONFIG_IP_NF_MATCH_REALM is not set
-# CONFIG_IP_NF_MATCH_SCTP is not set
-# CONFIG_IP_NF_MATCH_COMMENT is not set
-# CONFIG_IP_NF_MATCH_HASHLIMIT is not set
-CONFIG_IP_NF_FILTER=m
-CONFIG_IP_NF_TARGET_REJECT=m
-# CONFIG_IP_NF_TARGET_LOG is not set
-CONFIG_IP_NF_TARGET_ULOG=m
-CONFIG_IP_NF_TARGET_TCPMSS=m
-CONFIG_IP_NF_NAT=m
-CONFIG_IP_NF_NAT_NEEDED=y
-CONFIG_IP_NF_TARGET_MASQUERADE=m
-CONFIG_IP_NF_TARGET_REDIRECT=m
-CONFIG_IP_NF_TARGET_NETMAP=m
-CONFIG_IP_NF_TARGET_SAME=m
-CONFIG_IP_NF_NAT_SNMP_BASIC=m
-CONFIG_IP_NF_NAT_IRC=m
-CONFIG_IP_NF_NAT_FTP=m
-CONFIG_IP_NF_NAT_TFTP=m
-CONFIG_IP_NF_NAT_AMANDA=m
-# CONFIG_IP_NF_MANGLE is not set
-CONFIG_IP_NF_RAW=m
-CONFIG_IP_NF_TARGET_NOTRACK=m
-# CONFIG_IP_NF_ARPTABLES is not set
-CONFIG_IP_NF_COMPAT_IPCHAINS=m
-# CONFIG_IP_NF_COMPAT_IPFWADM is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
 CONFIG_NETDEVICES=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
+CONFIG_TUN=m
 
 #
 # ARCnet devices
@@ -588,6 +682,8 @@ CONFIG_TULIP_MMIO=y
 CONFIG_DE4X5=m
 # CONFIG_WINBOND_840 is not set
 # CONFIG_DM9102 is not set
+# CONFIG_PCMCIA_XIRCOM is not set
+# CONFIG_PCMCIA_XIRTULIP is not set
 # CONFIG_AT1700 is not set
 # CONFIG_DEPCA is not set
 # CONFIG_HP100 is not set
@@ -626,9 +722,12 @@ CONFIG_PCNET32=y
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
 # CONFIG_R8169 is not set
+# CONFIG_SKGE is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+# CONFIG_MV643XX_ETH is not set
 
 #
 # Ethernet (10000 Mbit)
@@ -676,18 +775,19 @@ CONFIG_NET_WIRELESS=y
 # CONFIG_WAN is not set
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
 CONFIG_PPP=y
 CONFIG_PPP_MULTILINK=y
 CONFIG_PPP_FILTER=y
 CONFIG_PPP_ASYNC=y
 # CONFIG_PPP_SYNC_TTY is not set
 CONFIG_PPP_DEFLATE=y
-# CONFIG_PPP_BSDCOMP is not set
-# CONFIG_PPPOE is not set
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPPOE=m
 # CONFIG_SLIP is not set
 # CONFIG_NET_FC is not set
 # CONFIG_SHAPER is not set
-# CONFIG_NETCONSOLE is not set
+CONFIG_NETCONSOLE=m
 
 #
 # ISDN subsystem
@@ -708,7 +808,7 @@ CONFIG_INPUT=y
 # Userland interfaces
 #
 CONFIG_INPUT_MOUSEDEV=y
-CONFIG_INPUT_MOUSEDEV_PSAUX=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
 CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
 CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 # CONFIG_INPUT_JOYDEV is not set
@@ -717,18 +817,6 @@ CONFIG_INPUT_EVDEV=y
 CONFIG_INPUT_EVBUG=m
 
 #
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-CONFIG_SERIO_I8042=y
-# CONFIG_SERIO_SERPORT is not set
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PCIPS2 is not set
-# CONFIG_SERIO_RAW is not set
-
-#
 # Input Device Drivers
 #
 CONFIG_INPUT_KEYBOARD=y
@@ -751,6 +839,18 @@ CONFIG_INPUT_MISC=y
 CONFIG_INPUT_UINPUT=m
 
 #
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+# CONFIG_SERIO_SERPORT is not set
+# CONFIG_SERIO_PARKBD is not set
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
 # Character devices
 #
 CONFIG_VT=y
@@ -761,7 +861,8 @@ CONFIG_HW_CONSOLE=y
 #
 # Serial drivers
 #
-CONFIG_SERIAL_8250=m
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_8250_NR_UARTS=4
 # CONFIG_SERIAL_8250_EXTENDED is not set
 
@@ -769,11 +870,16 @@ CONFIG_SERIAL_8250_NR_UARTS=4
 # Non-8250 serial port support
 #
 CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_SERIAL_PMACZILOG=y
-# CONFIG_SERIAL_PMACZILOG_CONSOLE is not set
+CONFIG_SERIAL_PMACZILOG_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_PRINTER is not set
+# CONFIG_PPDEV is not set
+# CONFIG_TIPAR is not set
 
 #
 # IPMI
@@ -794,11 +900,23 @@ CONFIG_GEN_RTC=y
 #
 # Ftape, the floppy tape device driver
 #
-# CONFIG_AGP is not set
-# CONFIG_DRM is not set
+CONFIG_AGP=m
+CONFIG_AGP_UNINORTH=m
+CONFIG_DRM=m
+# CONFIG_DRM_TDFX is not set
+CONFIG_DRM_R128=m
+CONFIG_DRM_RADEON=m
+# CONFIG_DRM_MGA is not set
+# CONFIG_DRM_SIS is not set
+# CONFIG_DRM_VIA is not set
 # CONFIG_RAW_DRIVER is not set
 
 #
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
 # I2C support
 #
 CONFIG_I2C=y
@@ -823,11 +941,13 @@ CONFIG_I2C_ALGOBIT=y
 CONFIG_I2C_HYDRA=y
 # CONFIG_I2C_I801 is not set
 # CONFIG_I2C_I810 is not set
+# CONFIG_I2C_PIIX4 is not set
 # CONFIG_I2C_ISA is not set
 CONFIG_I2C_KEYWEST=m
+# CONFIG_I2C_MPC is not set
 # CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_PARPORT is not set
 # CONFIG_I2C_PARPORT_LIGHT is not set
-# CONFIG_I2C_PIIX4 is not set
 # CONFIG_I2C_PROSAVAGE is not set
 # CONFIG_I2C_SAVAGE4 is not set
 # CONFIG_SCx200_ACB is not set
@@ -839,43 +959,20 @@ CONFIG_I2C_KEYWEST=m
 # CONFIG_I2C_VIAPRO is not set
 # CONFIG_I2C_VOODOO3 is not set
 # CONFIG_I2C_PCA_ISA is not set
-
-#
-# Hardware Sensors Chip support
-#
 # CONFIG_I2C_SENSOR is not set
-# CONFIG_SENSORS_ADM1021 is not set
-# CONFIG_SENSORS_ADM1025 is not set
-# CONFIG_SENSORS_ADM1031 is not set
-# CONFIG_SENSORS_ASB100 is not set
-# CONFIG_SENSORS_DS1621 is not set
-# CONFIG_SENSORS_FSCHER is not set
-# CONFIG_SENSORS_GL518SM is not set
-# CONFIG_SENSORS_IT87 is not set
-# CONFIG_SENSORS_LM63 is not set
-# CONFIG_SENSORS_LM75 is not set
-# CONFIG_SENSORS_LM77 is not set
-# CONFIG_SENSORS_LM78 is not set
-# CONFIG_SENSORS_LM80 is not set
-# CONFIG_SENSORS_LM83 is not set
-# CONFIG_SENSORS_LM85 is not set
-# CONFIG_SENSORS_LM87 is not set
-# CONFIG_SENSORS_LM90 is not set
-# CONFIG_SENSORS_MAX1619 is not set
-# CONFIG_SENSORS_PC87360 is not set
-# CONFIG_SENSORS_SMSC47M1 is not set
-# CONFIG_SENSORS_VIA686A is not set
-# CONFIG_SENSORS_W83781D is not set
-# CONFIG_SENSORS_W83L785TS is not set
-# CONFIG_SENSORS_W83627HF is not set
 
 #
-# Other I2C Chip support
+# Miscellaneous I2C Chip support
 #
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
 # CONFIG_SENSORS_EEPROM is not set
 # CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_SENSORS_PCA9539 is not set
 # CONFIG_SENSORS_PCF8591 is not set
 # CONFIG_SENSORS_RTC8564 is not set
+# CONFIG_SENSORS_M41T00 is not set
+# CONFIG_SENSORS_MAX6875 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
@@ -887,6 +984,11 @@ CONFIG_I2C_KEYWEST=m
 # CONFIG_W1 is not set
 
 #
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+
+#
 # Misc devices
 #
 
@@ -904,8 +1006,13 @@ CONFIG_I2C_KEYWEST=m
 # Graphics support
 #
 CONFIG_FB=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+CONFIG_FB_SOFT_CURSOR=y
+CONFIG_FB_MACMODES=y
 CONFIG_FB_MODE_HELPERS=y
-# CONFIG_FB_TILEBLITTING is not set
+CONFIG_FB_TILEBLITTING=y
 # CONFIG_FB_CIRRUS is not set
 # CONFIG_FB_PM2 is not set
 # CONFIG_FB_CYBER2000 is not set
@@ -917,13 +1024,16 @@ CONFIG_FB_CT65550=y
 # CONFIG_FB_ASILIANT is not set
 CONFIG_FB_IMSTT=y
 # CONFIG_FB_VGA16 is not set
-# CONFIG_FB_RIVA is not set
+# CONFIG_FB_NVIDIA is not set
+CONFIG_FB_RIVA=y
+CONFIG_FB_RIVA_I2C=y
+# CONFIG_FB_RIVA_DEBUG is not set
 CONFIG_FB_MATROX=y
 CONFIG_FB_MATROX_MILLENIUM=y
 CONFIG_FB_MATROX_MYSTIQUE=y
-# CONFIG_FB_MATROX_G450 is not set
-# CONFIG_FB_MATROX_G100A is not set
+CONFIG_FB_MATROX_G=y
 CONFIG_FB_MATROX_I2C=y
+CONFIG_FB_MATROX_MAVEN=m
 # CONFIG_FB_MATROX_MULTIHEAD is not set
 # CONFIG_FB_RADEON_OLD is not set
 CONFIG_FB_RADEON=y
@@ -932,8 +1042,8 @@ CONFIG_FB_RADEON_I2C=y
 CONFIG_FB_ATY128=y
 CONFIG_FB_ATY=y
 CONFIG_FB_ATY_CT=y
-# CONFIG_FB_ATY_GENERIC_LCD is not set
-# CONFIG_FB_ATY_XL_INIT is not set
+CONFIG_FB_ATY_GENERIC_LCD=y
+CONFIG_FB_ATY_XL_INIT=y
 CONFIG_FB_ATY_GX=y
 # CONFIG_FB_SAVAGE is not set
 # CONFIG_FB_SIS is not set
@@ -943,6 +1053,7 @@ CONFIG_FB_3DFX=y
 # CONFIG_FB_3DFX_ACCEL is not set
 # CONFIG_FB_VOODOO1 is not set
 # CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_S1D13XXX is not set
 # CONFIG_FB_VIRTUAL is not set
 
 #
@@ -960,9 +1071,10 @@ CONFIG_FONT_8x16=y
 # Logo configuration
 #
 CONFIG_LOGO=y
-CONFIG_LOGO_LINUX_MONO=y
-CONFIG_LOGO_LINUX_VGA16=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
 CONFIG_LOGO_LINUX_CLUT224=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -987,6 +1099,7 @@ CONFIG_SND_PCM_OSS=m
 CONFIG_SND_SEQUENCER_OSS=y
 # CONFIG_SND_VERBOSE_PRINTK is not set
 # CONFIG_SND_DEBUG is not set
+CONFIG_SND_GENERIC_PM=y
 
 #
 # Generic devices
@@ -1002,6 +1115,7 @@ CONFIG_SND_OPL3_LIB=m
 #
 # ISA devices
 #
+CONFIG_SND_CS4231_LIB=m
 # CONFIG_SND_AD1848 is not set
 # CONFIG_SND_CS4231 is not set
 CONFIG_SND_CS4232=m
@@ -1039,6 +1153,8 @@ CONFIG_SND_CS4232=m
 # CONFIG_SND_CS46XX is not set
 # CONFIG_SND_CS4281 is not set
 # CONFIG_SND_EMU10K1 is not set
+# CONFIG_SND_EMU10K1X is not set
+# CONFIG_SND_CA0106 is not set
 # CONFIG_SND_KORG1212 is not set
 # CONFIG_SND_MIXART is not set
 # CONFIG_SND_NM256 is not set
@@ -1046,6 +1162,7 @@ CONFIG_SND_CS4232=m
 # CONFIG_SND_RME96 is not set
 # CONFIG_SND_RME9652 is not set
 # CONFIG_SND_HDSP is not set
+# CONFIG_SND_HDSPM is not set
 # CONFIG_SND_TRIDENT is not set
 # CONFIG_SND_YMFPCI is not set
 # CONFIG_SND_ALS4000 is not set
@@ -1062,7 +1179,9 @@ CONFIG_SND_CS4232=m
 # CONFIG_SND_INTEL8X0M is not set
 # CONFIG_SND_SONICVIBES is not set
 # CONFIG_SND_VIA82XX is not set
+# CONFIG_SND_VIA82XX_MODEM is not set
 # CONFIG_SND_VX222 is not set
+# CONFIG_SND_HDA_INTEL is not set
 
 #
 # ALSA PowerMac devices
@@ -1083,6 +1202,8 @@ CONFIG_SND_USB_AUDIO=m
 #
 # USB support
 #
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
 CONFIG_USB=y
 # CONFIG_USB_DEBUG is not set
 
@@ -1094,15 +1215,19 @@ CONFIG_USB_DEVICEFS=y
 # CONFIG_USB_DYNAMIC_MINORS is not set
 # CONFIG_USB_SUSPEND is not set
 # CONFIG_USB_OTG is not set
-CONFIG_USB_ARCH_HAS_HCD=y
-CONFIG_USB_ARCH_HAS_OHCI=y
 
 #
 # USB Host Controller Drivers
 #
-# CONFIG_USB_EHCI_HCD is not set
+CONFIG_USB_EHCI_HCD=m
+CONFIG_USB_EHCI_SPLIT_ISO=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+# CONFIG_USB_ISP116X_HCD is not set
 CONFIG_USB_OHCI_HCD=y
-# CONFIG_USB_UHCI_HCD is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+CONFIG_USB_UHCI_HCD=m
+# CONFIG_USB_SL811_HCD is not set
 
 #
 # USB Device Class drivers
@@ -1112,17 +1237,20 @@ CONFIG_USB_OHCI_HCD=y
 # CONFIG_USB_MIDI is not set
 CONFIG_USB_ACM=m
 CONFIG_USB_PRINTER=m
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+#
 CONFIG_USB_STORAGE=m
 # CONFIG_USB_STORAGE_DEBUG is not set
-# CONFIG_USB_STORAGE_RW_DETECT is not set
-# CONFIG_USB_STORAGE_DATAFAB is not set
+CONFIG_USB_STORAGE_DATAFAB=y
 CONFIG_USB_STORAGE_FREECOM=y
-# CONFIG_USB_STORAGE_ISD200 is not set
+CONFIG_USB_STORAGE_ISD200=y
 CONFIG_USB_STORAGE_DPCM=y
-# CONFIG_USB_STORAGE_HP8200e is not set
-# CONFIG_USB_STORAGE_SDDR09 is not set
-# CONFIG_USB_STORAGE_SDDR55 is not set
-# CONFIG_USB_STORAGE_JUMPSHOT is not set
+CONFIG_USB_STORAGE_USBAT=y
+CONFIG_USB_STORAGE_SDDR09=y
+CONFIG_USB_STORAGE_SDDR55=y
+CONFIG_USB_STORAGE_JUMPSHOT=y
 
 #
 # USB Input Devices
@@ -1130,22 +1258,24 @@ CONFIG_USB_STORAGE_DPCM=y
 CONFIG_USB_HID=y
 CONFIG_USB_HIDINPUT=y
 # CONFIG_HID_FF is not set
-# CONFIG_USB_HIDDEV is not set
+CONFIG_USB_HIDDEV=y
 # CONFIG_USB_AIPTEK is not set
 # CONFIG_USB_WACOM is not set
+# CONFIG_USB_ACECAD is not set
 # CONFIG_USB_KBTAB is not set
 # CONFIG_USB_POWERMATE is not set
 # CONFIG_USB_MTOUCH is not set
+# CONFIG_USB_ITMTOUCH is not set
 # CONFIG_USB_EGALAX is not set
 # CONFIG_USB_XPAD is not set
 # CONFIG_USB_ATI_REMOTE is not set
+# CONFIG_USB_KEYSPAN_REMOTE is not set
 
 #
 # USB Imaging devices
 #
 # CONFIG_USB_MDC800 is not set
 # CONFIG_USB_MICROTEK is not set
-# CONFIG_USB_HPUSBSCSI is not set
 
 #
 # USB Multimedia devices
@@ -1161,22 +1291,27 @@ CONFIG_USB_HIDINPUT=y
 #
 # CONFIG_USB_CATC is not set
 # CONFIG_USB_KAWETH is not set
-# CONFIG_USB_PEGASUS is not set
+CONFIG_USB_PEGASUS=m
 # CONFIG_USB_RTL8150 is not set
 # CONFIG_USB_USBNET is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_USB_MON is not set
 
 #
 # USB port drivers
 #
+# CONFIG_USB_USS720 is not set
 
 #
 # USB Serial Converter support
 #
 CONFIG_USB_SERIAL=m
 # CONFIG_USB_SERIAL_GENERIC is not set
+# CONFIG_USB_SERIAL_AIRPRIME is not set
 # CONFIG_USB_SERIAL_BELKIN is not set
 # CONFIG_USB_SERIAL_WHITEHEAT is not set
 # CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_CP2101 is not set
 # CONFIG_USB_SERIAL_CYPRESS_M8 is not set
 # CONFIG_USB_SERIAL_EMPEG is not set
 # CONFIG_USB_SERIAL_FTDI_SIO is not set
@@ -1185,28 +1320,32 @@ CONFIG_USB_SERIAL_VISOR=m
 # CONFIG_USB_SERIAL_IR is not set
 # CONFIG_USB_SERIAL_EDGEPORT is not set
 # CONFIG_USB_SERIAL_EDGEPORT_TI is not set
+# CONFIG_USB_SERIAL_GARMIN is not set
 # CONFIG_USB_SERIAL_IPW is not set
 # CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
 CONFIG_USB_SERIAL_KEYSPAN=m
-# CONFIG_USB_SERIAL_KEYSPAN_MPR is not set
+CONFIG_USB_SERIAL_KEYSPAN_MPR=y
 CONFIG_USB_SERIAL_KEYSPAN_USA28=y
 CONFIG_USB_SERIAL_KEYSPAN_USA28X=y
-# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
+CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y
 CONFIG_USB_SERIAL_KEYSPAN_USA19=y
 CONFIG_USB_SERIAL_KEYSPAN_USA18X=y
 CONFIG_USB_SERIAL_KEYSPAN_USA19W=y
 CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y
 CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y
 CONFIG_USB_SERIAL_KEYSPAN_USA49W=y
-# CONFIG_USB_SERIAL_KEYSPAN_USA49WLC is not set
+CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y
 # CONFIG_USB_SERIAL_KLSI is not set
 # CONFIG_USB_SERIAL_KOBIL_SCT is not set
 # CONFIG_USB_SERIAL_MCT_U232 is not set
 # CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_HP4X is not set
 # CONFIG_USB_SERIAL_SAFE is not set
+# CONFIG_USB_SERIAL_TI is not set
 # CONFIG_USB_SERIAL_CYBERJACK is not set
 # CONFIG_USB_SERIAL_XIRCOM is not set
+# CONFIG_USB_SERIAL_OPTION is not set
 # CONFIG_USB_SERIAL_OMNINET is not set
 CONFIG_USB_EZUSB=y
 
@@ -1215,7 +1354,6 @@ CONFIG_USB_EZUSB=y
 #
 # CONFIG_USB_EMI62 is not set
 # CONFIG_USB_EMI26 is not set
-# CONFIG_USB_TIGL is not set
 # CONFIG_USB_AUERSWALD is not set
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
@@ -1224,10 +1362,13 @@ CONFIG_USB_EZUSB=y
 # CONFIG_USB_CYTHERM is not set
 # CONFIG_USB_PHIDGETKIT is not set
 # CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
 # CONFIG_USB_TEST is not set
 
 #
-# USB ATM/DSL drivers
+# USB DSL modem support
 #
 
 #
@@ -1236,21 +1377,63 @@ CONFIG_USB_EZUSB=y
 # CONFIG_USB_GADGET is not set
 
 #
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# SN Devices
+#
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
-# CONFIG_EXT2_FS_XATTR is not set
-# CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
-# CONFIG_REISERFS_FS is not set
-# CONFIG_JFS_FS is not set
-# CONFIG_XFS_FS is not set
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+CONFIG_REISERFS_FS=y
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+CONFIG_REISERFS_FS_XATTR=y
+CONFIG_REISERFS_FS_POSIX_ACL=y
+CONFIG_REISERFS_FS_SECURITY=y
+CONFIG_JFS_FS=m
+CONFIG_JFS_POSIX_ACL=y
+CONFIG_JFS_SECURITY=y
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+CONFIG_FS_POSIX_ACL=y
+
+#
+# XFS support
+#
+CONFIG_XFS_FS=m
+CONFIG_XFS_EXPORT=y
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_QUOTA is not set
+CONFIG_XFS_SECURITY=y
+CONFIG_XFS_POSIX_ACL=y
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
 # CONFIG_QUOTA is not set
 CONFIG_DNOTIFY=y
 # CONFIG_AUTOFS_FS is not set
-# CONFIG_AUTOFS4_FS is not set
+CONFIG_AUTOFS4_FS=m
 
 #
 # CD-ROM/DVD Filesystems
@@ -1258,7 +1441,8 @@ CONFIG_DNOTIFY=y
 CONFIG_ISO9660_FS=y
 # CONFIG_JOLIET is not set
 # CONFIG_ZISOFS is not set
-# CONFIG_UDF_FS is not set
+CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
 
 #
 # DOS/FAT/NT Filesystems
@@ -1276,12 +1460,11 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
 CONFIG_SYSFS=y
-CONFIG_DEVFS_FS=y
-# CONFIG_DEVFS_MOUNT is not set
-# CONFIG_DEVFS_DEBUG is not set
-# CONFIG_DEVPTS_FS_XATTR is not set
+CONFIG_DEVPTS_FS_XATTR=y
+CONFIG_DEVPTS_FS_SECURITY=y
 CONFIG_TMPFS=y
-# CONFIG_TMPFS_XATTR is not set
+CONFIG_TMPFS_XATTR=y
+CONFIG_TMPFS_SECURITY=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
 
@@ -1295,27 +1478,33 @@ CONFIG_HFSPLUS_FS=m
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
-# CONFIG_CRAMFS is not set
+CONFIG_CRAMFS=m
 # CONFIG_VXFS_FS is not set
 # CONFIG_HPFS_FS is not set
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_SYSV_FS is not set
-# CONFIG_UFS_FS is not set
+CONFIG_UFS_FS=m
+# CONFIG_UFS_FS_WRITE is not set
 
 #
 # Network File Systems
 #
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
 # CONFIG_NFS_V4 is not set
 # CONFIG_NFS_DIRECTIO is not set
 CONFIG_NFSD=y
+CONFIG_NFSD_V2_ACL=y
 CONFIG_NFSD_V3=y
+CONFIG_NFSD_V3_ACL=y
 # CONFIG_NFSD_V4 is not set
 CONFIG_NFSD_TCP=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_EXPORTFS=y
+CONFIG_NFS_ACL_SUPPORT=y
+CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -1348,46 +1537,46 @@ CONFIG_MSDOS_PARTITION=y
 #
 # Native Language Support
 #
-CONFIG_NLS=y
+CONFIG_NLS=m
 CONFIG_NLS_DEFAULT="iso8859-1"
-# CONFIG_NLS_CODEPAGE_437 is not set
-# CONFIG_NLS_CODEPAGE_737 is not set
-# CONFIG_NLS_CODEPAGE_775 is not set
-# CONFIG_NLS_CODEPAGE_850 is not set
-# CONFIG_NLS_CODEPAGE_852 is not set
-# CONFIG_NLS_CODEPAGE_855 is not set
-# CONFIG_NLS_CODEPAGE_857 is not set
-# CONFIG_NLS_CODEPAGE_860 is not set
-# CONFIG_NLS_CODEPAGE_861 is not set
-# CONFIG_NLS_CODEPAGE_862 is not set
-# CONFIG_NLS_CODEPAGE_863 is not set
-# CONFIG_NLS_CODEPAGE_864 is not set
-# CONFIG_NLS_CODEPAGE_865 is not set
-# CONFIG_NLS_CODEPAGE_866 is not set
-# CONFIG_NLS_CODEPAGE_869 is not set
-# CONFIG_NLS_CODEPAGE_936 is not set
-# CONFIG_NLS_CODEPAGE_950 is not set
-# CONFIG_NLS_CODEPAGE_932 is not set
-# CONFIG_NLS_CODEPAGE_949 is not set
-# CONFIG_NLS_CODEPAGE_874 is not set
-# CONFIG_NLS_ISO8859_8 is not set
-# CONFIG_NLS_CODEPAGE_1250 is not set
-# CONFIG_NLS_CODEPAGE_1251 is not set
-# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=m
 CONFIG_NLS_ISO8859_1=m
-# CONFIG_NLS_ISO8859_2 is not set
-# CONFIG_NLS_ISO8859_3 is not set
-# CONFIG_NLS_ISO8859_4 is not set
-# CONFIG_NLS_ISO8859_5 is not set
-# CONFIG_NLS_ISO8859_6 is not set
-# CONFIG_NLS_ISO8859_7 is not set
-# CONFIG_NLS_ISO8859_9 is not set
-# CONFIG_NLS_ISO8859_13 is not set
-# CONFIG_NLS_ISO8859_14 is not set
-# CONFIG_NLS_ISO8859_15 is not set
-# CONFIG_NLS_KOI8_R is not set
-# CONFIG_NLS_KOI8_U is not set
-# CONFIG_NLS_UTF8 is not set
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
 
 #
 # Library routines
@@ -1406,7 +1595,19 @@ CONFIG_ZLIB_DEFLATE=y
 #
 # Kernel hacking
 #
-# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_PRINTK_TIME is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_XMON is not set
+# CONFIG_BDI_SWITCH is not set
 CONFIG_BOOTX_TEXT=y
 
 #
@@ -1419,3 +1620,7 @@ CONFIG_BOOTX_TEXT=y
 # Cryptographic options
 #
 # CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
diff --git a/arch/ppc/configs/mpc8548_cds_defconfig b/arch/ppc/configs/mpc8548_cds_defconfig
new file mode 100644
--- /dev/null
+++ b/arch/ppc/configs/mpc8548_cds_defconfig
@@ -0,0 +1,659 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.12-rc4
+# Tue May 24 22:36:27 2005
+#
+CONFIG_MMU=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_HAVE_DEC_LOCK=y
+CONFIG_PPC=y
+CONFIG_PPC32=y
+CONFIG_GENERIC_NVRAM=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+# CONFIG_HOTPLUG is not set
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_EMBEDDED=y
+# CONFIG_KALLSYMS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+# CONFIG_EPOLL is not set
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# Processor
+#
+# CONFIG_6xx is not set
+# CONFIG_40x is not set
+# CONFIG_44x is not set
+# CONFIG_POWER3 is not set
+# CONFIG_POWER4 is not set
+# CONFIG_8xx is not set
+CONFIG_E500=y
+CONFIG_BOOKE=y
+CONFIG_FSL_BOOKE=y
+# CONFIG_PHYS_64BIT is not set
+CONFIG_SPE=y
+CONFIG_MATH_EMULATION=y
+# CONFIG_CPU_FREQ is not set
+# CONFIG_PM is not set
+CONFIG_85xx=y
+CONFIG_PPC_INDIRECT_PCI_BE=y
+
+#
+# Freescale 85xx options
+#
+# CONFIG_MPC8540_ADS is not set
+CONFIG_MPC8548_CDS=y
+# CONFIG_MPC8555_CDS is not set
+# CONFIG_MPC8560_ADS is not set
+# CONFIG_SBC8560 is not set
+# CONFIG_STX_GP3 is not set
+CONFIG_MPC8548=y
+
+#
+# Platform options
+#
+# CONFIG_SMP is not set
+# CONFIG_PREEMPT is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_CMDLINE_BOOL is not set
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus options
+#
+# CONFIG_PCI is not set
+# CONFIG_PCI_DOMAINS is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# Advanced setup
+#
+# CONFIG_ADVANCED_OPTIONS is not set
+
+#
+# Default settings for advanced configuration options are used
+#
+CONFIG_HIGHMEM_START=0xfe000000
+CONFIG_LOWMEM_SIZE=0x30000000
+CONFIG_KERNEL_START=0xc0000000
+CONFIG_TASK_SIZE=0x80000000
+CONFIG_BOOT_LOAD=0x00800000
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=32768
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_LBD is not set
+# CONFIG_CDROM_PKTCDVD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_SCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# I2O device support
+#
+
+#
+# Macintosh device drivers
+#
+
+#
+# Networking support
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_IP_TCPDIAG=y
+# CONFIG_IP_TCPDIAG_IPV6 is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+
+#
+# Ethernet (1000 Mbit)
+#
+CONFIG_GIANFAR=y
+CONFIG_GFAR_NAPI=y
+
+#
+# Ethernet (10000 Mbit)
+#
+
+#
+# Token Ring devices
+#
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_NVRAM is not set
+CONFIG_GEN_RTC=y
+# CONFIG_GEN_RTC_X is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+
+#
+# I2C support
+#
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+
+#
+# I2C Algorithms
+#
+# CONFIG_I2C_ALGOBIT is not set
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+
+#
+# I2C Hardware Bus support
+#
+# CONFIG_I2C_ISA is not set
+CONFIG_I2C_MPC=y
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_PCA_ISA is not set
+
+#
+# Hardware Sensors Chip support
+#
+# CONFIG_I2C_SENSOR is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ASB100 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_FSCHER is not set
+# CONFIG_SENSORS_FSCPOS is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83627HF is not set
+
+#
+# Other I2C Chip support
+#
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_RTC8564 is not set
+# CONFIG_SENSORS_M41T00 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB_ARCH_HAS_HCD is not set
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+
+#
+# XFS support
+#
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVPTS_FS_XATTR is not set
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_XATTR is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+# CONFIG_MSDOS_PARTITION is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
diff --git a/arch/ppc/configs/mpc86x_ads_defconfig b/arch/ppc/configs/mpc86x_ads_defconfig
new file mode 100644
--- /dev/null
+++ b/arch/ppc/configs/mpc86x_ads_defconfig
@@ -0,0 +1,633 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.12-rc4
+# Tue Jun 14 13:36:35 2005
+#
+CONFIG_MMU=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_HAVE_DEC_LOCK=y
+CONFIG_PPC=y
+CONFIG_PPC32=y
+CONFIG_GENERIC_NVRAM=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+# CONFIG_CLEAN_COMPILE is not set
+CONFIG_BROKEN=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+# CONFIG_HOTPLUG is not set
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_EMBEDDED=y
+# CONFIG_KALLSYMS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+# CONFIG_BASE_FULL is not set
+CONFIG_FUTEX=y
+# CONFIG_EPOLL is not set
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+# CONFIG_SHMEM is not set
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_TINY_SHMEM=y
+CONFIG_BASE_SMALL=1
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODULE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+# CONFIG_KMOD is not set
+
+#
+# Processor
+#
+# CONFIG_6xx is not set
+# CONFIG_40x is not set
+# CONFIG_44x is not set
+# CONFIG_POWER3 is not set
+# CONFIG_POWER4 is not set
+CONFIG_8xx=y
+# CONFIG_E500 is not set
+# CONFIG_MATH_EMULATION is not set
+# CONFIG_CPU_FREQ is not set
+CONFIG_EMBEDDEDBOOT=y
+# CONFIG_PM is not set
+CONFIG_NOT_COHERENT_CACHE=y
+
+#
+# Platform options
+#
+CONFIG_FADS=y
+# CONFIG_RPXLITE is not set
+# CONFIG_RPXCLASSIC is not set
+# CONFIG_BSEIP is not set
+# CONFIG_MPC8XXFADS is not set
+CONFIG_MPC86XADS=y
+# CONFIG_TQM823L is not set
+# CONFIG_TQM850L is not set
+# CONFIG_TQM855L is not set
+# CONFIG_TQM860L is not set
+# CONFIG_FPS850L is not set
+# CONFIG_SPD823TS is not set
+# CONFIG_IVMS8 is not set
+# CONFIG_IVML24 is not set
+# CONFIG_SM850 is not set
+# CONFIG_HERMES_PRO is not set
+# CONFIG_IP860 is not set
+# CONFIG_LWMON is not set
+# CONFIG_PCU_E is not set
+# CONFIG_CCM is not set
+# CONFIG_LANTEC is not set
+# CONFIG_MBX is not set
+# CONFIG_WINCEPT is not set
+# CONFIG_SMP is not set
+# CONFIG_PREEMPT is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_CMDLINE_BOOL is not set
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus options
+#
+# CONFIG_PCI is not set
+# CONFIG_PCI_DOMAINS is not set
+# CONFIG_PCI_QSPAN is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# Advanced setup
+#
+# CONFIG_ADVANCED_OPTIONS is not set
+
+#
+# Default settings for advanced configuration options are used
+#
+CONFIG_HIGHMEM_START=0xfe000000
+CONFIG_LOWMEM_SIZE=0x30000000
+CONFIG_KERNEL_START=0xc0000000
+CONFIG_TASK_SIZE=0x80000000
+CONFIG_CONSISTENT_START=0xff100000
+CONFIG_CONSISTENT_SIZE=0x00200000
+CONFIG_BOOT_LOAD=0x00400000
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+# CONFIG_STANDALONE is not set
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_RAM is not set
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_LBD is not set
+# CONFIG_CDROM_PKTCDVD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_SCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+
+#
+# Macintosh device drivers
+#
+
+#
+# Networking support
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_IP_TCPDIAG=y
+# CONFIG_IP_TCPDIAG_IPV6 is not set
+CONFIG_IPV6=m
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_IPV6_TUNNEL is not set
+# CONFIG_NETFILTER is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_MII is not set
+# CONFIG_OAKNET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+
+#
+# Ethernet (10000 Mbit)
+#
+
+#
+# Token Ring devices
+#
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+# CONFIG_INPUT is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_SERIAL_CPM=y
+CONFIG_SERIAL_CPM_CONSOLE=y
+# CONFIG_SERIAL_CPM_SCC1 is not set
+# CONFIG_SERIAL_CPM_SCC2 is not set
+# CONFIG_SERIAL_CPM_SCC3 is not set
+# CONFIG_SERIAL_CPM_SCC4 is not set
+CONFIG_SERIAL_CPM_SMC1=y
+# CONFIG_SERIAL_CPM_SMC2 is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB_ARCH_HAS_HCD is not set
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# File systems
+#
+# CONFIG_EXT2_FS is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_FS_XATTR is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+
+#
+# XFS support
+#
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_QUOTA is not set
+# CONFIG_DNOTIFY is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVPTS_FS_XATTR is not set
+# CONFIG_TMPFS is not set
+# CONFIG_HUGETLBFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V4=y
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+CONFIG_RPCSEC_GSS_KRB5=y
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+
+#
+# MPC8xx CPM Options
+#
+CONFIG_SCC_ENET=y
+CONFIG_SCC1_ENET=y
+# CONFIG_SCC2_ENET is not set
+# CONFIG_SCC3_ENET is not set
+# CONFIG_FEC_ENET is not set
+# CONFIG_ENET_BIG_BUFFERS is not set
+
+#
+# Generic MPC8xx Options
+#
+# CONFIG_8xx_COPYBACK is not set
+# CONFIG_8xx_CPU6 is not set
+CONFIG_NO_UCODE_PATCH=y
+# CONFIG_USB_SOF_UCODE_PATCH is not set
+# CONFIG_I2C_SPI_UCODE_PATCH is not set
+# CONFIG_I2C_SPI_SMC1_UCODE_PATCH is not set
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC32 is not set
+# CONFIG_LIBCRC32C is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_WP512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Hardware crypto devices
+#
diff --git a/arch/ppc/configs/mpc885ads_defconfig b/arch/ppc/configs/mpc885ads_defconfig
new file mode 100644
--- /dev/null
+++ b/arch/ppc/configs/mpc885ads_defconfig
@@ -0,0 +1,622 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.12-rc6
+# Thu Jun  9 21:17:29 2005
+#
+CONFIG_MMU=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_HAVE_DEC_LOCK=y
+CONFIG_PPC=y
+CONFIG_PPC32=y
+CONFIG_GENERIC_NVRAM=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+# CONFIG_CLEAN_COMPILE is not set
+CONFIG_BROKEN=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_EMBEDDED=y
+# CONFIG_KALLSYMS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+# CONFIG_EPOLL is not set
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# Processor
+#
+# CONFIG_6xx is not set
+# CONFIG_40x is not set
+# CONFIG_44x is not set
+# CONFIG_POWER3 is not set
+# CONFIG_POWER4 is not set
+CONFIG_8xx=y
+# CONFIG_E500 is not set
+# CONFIG_MATH_EMULATION is not set
+# CONFIG_CPU_FREQ is not set
+CONFIG_EMBEDDEDBOOT=y
+# CONFIG_PM is not set
+CONFIG_NOT_COHERENT_CACHE=y
+
+#
+# Platform options
+#
+# CONFIG_RPXLITE is not set
+# CONFIG_RPXCLASSIC is not set
+# CONFIG_BSEIP is not set
+# CONFIG_FADS is not set
+CONFIG_MPC885ADS=y
+# CONFIG_TQM823L is not set
+# CONFIG_TQM850L is not set
+# CONFIG_TQM855L is not set
+# CONFIG_TQM860L is not set
+# CONFIG_FPS850L is not set
+# CONFIG_SPD823TS is not set
+# CONFIG_IVMS8 is not set
+# CONFIG_IVML24 is not set
+# CONFIG_SM850 is not set
+# CONFIG_HERMES_PRO is not set
+# CONFIG_IP860 is not set
+# CONFIG_LWMON is not set
+# CONFIG_PCU_E is not set
+# CONFIG_CCM is not set
+# CONFIG_LANTEC is not set
+# CONFIG_MBX is not set
+# CONFIG_WINCEPT is not set
+# CONFIG_SMP is not set
+# CONFIG_PREEMPT is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_CMDLINE_BOOL is not set
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus options
+#
+# CONFIG_PCI is not set
+# CONFIG_PCI_DOMAINS is not set
+# CONFIG_PCI_QSPAN is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# Advanced setup
+#
+# CONFIG_ADVANCED_OPTIONS is not set
+
+#
+# Default settings for advanced configuration options are used
+#
+CONFIG_HIGHMEM_START=0xfe000000
+CONFIG_LOWMEM_SIZE=0x30000000
+CONFIG_KERNEL_START=0xc0000000
+CONFIG_TASK_SIZE=0x80000000
+CONFIG_CONSISTENT_START=0xff100000
+CONFIG_CONSISTENT_SIZE=0x00200000
+CONFIG_BOOT_LOAD=0x00400000
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_RAM is not set
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_LBD is not set
+# CONFIG_CDROM_PKTCDVD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_AS is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_SCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+
+#
+# Macintosh device drivers
+#
+
+#
+# Networking support
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_IP_TCPDIAG=y
+# CONFIG_IP_TCPDIAG_IPV6 is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_OAKNET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+
+#
+# Ethernet (10000 Mbit)
+#
+
+#
+# Token Ring devices
+#
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+CONFIG_PPP=y
+# CONFIG_PPP_MULTILINK is not set
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=y
+CONFIG_PPP_SYNC_TTY=y
+CONFIG_PPP_DEFLATE=y
+# CONFIG_PPP_BSDCOMP is not set
+# CONFIG_PPPOE is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+# CONFIG_INPUT is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_SERIAL_CPM=y
+CONFIG_SERIAL_CPM_CONSOLE=y
+# CONFIG_SERIAL_CPM_SCC1 is not set
+# CONFIG_SERIAL_CPM_SCC2 is not set
+# CONFIG_SERIAL_CPM_SCC3 is not set
+# CONFIG_SERIAL_CPM_SCC4 is not set
+CONFIG_SERIAL_CPM_SMC1=y
+CONFIG_SERIAL_CPM_SMC2=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB_ARCH_HAS_HCD is not set
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+# CONFIG_EXT2_FS_POSIX_ACL is not set
+# CONFIG_EXT2_FS_SECURITY is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+
+#
+# XFS support
+#
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_QUOTA is not set
+# CONFIG_DNOTIFY is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+# CONFIG_PROC_KCORE is not set
+CONFIG_SYSFS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVPTS_FS_XATTR is not set
+# CONFIG_TMPFS is not set
+# CONFIG_HUGETLBFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+
+#
+# MPC8xx CPM Options
+#
+CONFIG_SCC_ENET=y
+# CONFIG_SCC1_ENET is not set
+# CONFIG_SCC2_ENET is not set
+CONFIG_SCC3_ENET=y
+# CONFIG_FEC_ENET is not set
+# CONFIG_ENET_BIG_BUFFERS is not set
+
+#
+# Generic MPC8xx Options
+#
+CONFIG_8xx_COPYBACK=y
+CONFIG_8xx_CPU6=y
+CONFIG_NO_UCODE_PATCH=y
+# CONFIG_USB_SOF_UCODE_PATCH is not set
+# CONFIG_I2C_SPI_UCODE_PATCH is not set
+# CONFIG_I2C_SPI_SMC1_UCODE_PATCH is not set
+
+#
+# Library routines
+#
+CONFIG_CRC_CCITT=y
+# CONFIG_CRC32 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
diff --git a/arch/ppc/configs/pmac_defconfig b/arch/ppc/configs/pmac_defconfig
--- a/arch/ppc/configs/pmac_defconfig
+++ b/arch/ppc/configs/pmac_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc4
-# Sun Feb 13 14:56:58 2005
+# Linux kernel version: 2.6.13-rc3
+# Wed Jul 13 14:13:13 2005
 #
 CONFIG_MMU=y
 CONFIG_GENERIC_HARDIRQS=y
@@ -11,6 +11,7 @@ CONFIG_HAVE_DEC_LOCK=y
 CONFIG_PPC=y
 CONFIG_PPC32=y
 CONFIG_GENERIC_NVRAM=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
 
 #
 # Code maturity level options
@@ -18,6 +19,7 @@ CONFIG_GENERIC_NVRAM=y
 CONFIG_EXPERIMENTAL=y
 CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
@@ -28,7 +30,7 @@ CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
-CONFIG_LOG_BUF_SHIFT=16
+# CONFIG_AUDIT is not set
 CONFIG_HOTPLUG=y
 CONFIG_KOBJECT_UEVENT=y
 CONFIG_IKCONFIG=y
@@ -37,15 +39,18 @@ CONFIG_IKCONFIG_PROC=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
 # CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
 
 #
 # Loadable module support
@@ -67,12 +72,16 @@ CONFIG_6xx=y
 # CONFIG_POWER3 is not set
 # CONFIG_POWER4 is not set
 # CONFIG_8xx is not set
+# CONFIG_E200 is not set
 # CONFIG_E500 is not set
+CONFIG_PPC_FPU=y
 CONFIG_ALTIVEC=y
 CONFIG_TAU=y
 # CONFIG_TAU_INT is not set
 # CONFIG_TAU_AVERAGE is not set
+# CONFIG_KEXEC is not set
 CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=y
 # CONFIG_CPU_FREQ_DEBUG is not set
 CONFIG_CPU_FREQ_STAT=m
 CONFIG_CPU_FREQ_STAT_DETAILS=y
@@ -82,8 +91,8 @@ CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
 CONFIG_CPU_FREQ_GOV_POWERSAVE=m
 CONFIG_CPU_FREQ_GOV_USERSPACE=m
 CONFIG_CPU_FREQ_GOV_ONDEMAND=m
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
 CONFIG_CPU_FREQ_PMAC=y
-CONFIG_CPU_FREQ_TABLE=y
 CONFIG_PPC601_SYNC_FIX=y
 CONFIG_PM=y
 CONFIG_PPC_STD_MMU=y
@@ -100,6 +109,7 @@ CONFIG_PPC_MULTIPLATFORM=y
 # CONFIG_POWERPMC250 is not set
 # CONFIG_CHESTNUT is not set
 # CONFIG_SPRUCE is not set
+# CONFIG_HDPU is not set
 # CONFIG_EV64260 is not set
 # CONFIG_LOPEC is not set
 # CONFIG_MCPN765 is not set
@@ -108,6 +118,7 @@ CONFIG_PPC_MULTIPLATFORM=y
 # CONFIG_PRPMC750 is not set
 # CONFIG_PRPMC800 is not set
 # CONFIG_SANDPOINT is not set
+# CONFIG_RADSTONE_PPC7D is not set
 # CONFIG_ADIR is not set
 # CONFIG_K2 is not set
 # CONFIG_PAL4 is not set
@@ -120,19 +131,37 @@ CONFIG_PPC_MULTIPLATFORM=y
 # CONFIG_ADS8272 is not set
 # CONFIG_PQ2FADS is not set
 # CONFIG_LITE5200 is not set
+# CONFIG_MPC834x_SYS is not set
 CONFIG_PPC_CHRP=y
 CONFIG_PPC_PMAC=y
 CONFIG_PPC_PREP=y
 CONFIG_PPC_OF=y
 CONFIG_PPCBUG_NVRAM=y
 # CONFIG_SMP is not set
-# CONFIG_PREEMPT is not set
 # CONFIG_HIGHMEM is not set
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_BINFMT_ELF=y
 CONFIG_BINFMT_MISC=m
 CONFIG_PROC_DEVICETREE=y
 # CONFIG_PREP_RESIDUAL is not set
 # CONFIG_CMDLINE_BOOL is not set
+# CONFIG_PM_DEBUG is not set
+CONFIG_SOFTWARE_SUSPEND=y
+CONFIG_PM_STD_PARTITION=""
+# CONFIG_SECCOMP is not set
+CONFIG_ISA_DMA_API=y
 
 #
 # Bus options
@@ -143,6 +172,7 @@ CONFIG_PCI=y
 CONFIG_PCI_DOMAINS=y
 CONFIG_PCI_LEGACY_PROC=y
 CONFIG_PCI_NAMES=y
+# CONFIG_PCI_DEBUG is not set
 
 #
 # PCCARD (PCMCIA/CardBus) support
@@ -150,6 +180,8 @@ CONFIG_PCI_NAMES=y
 CONFIG_PCCARD=m
 # CONFIG_PCMCIA_DEBUG is not set
 CONFIG_PCMCIA=m
+# CONFIG_PCMCIA_LOAD_CIS is not set
+# CONFIG_PCMCIA_IOCTL is not set
 CONFIG_CARDBUS=y
 
 #
@@ -175,6 +207,194 @@ CONFIG_TASK_SIZE=0xc0000000
 CONFIG_BOOT_LOAD=0x00800000
 
 #
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_IP_TCPDIAG=y
+# CONFIG_IP_TCPDIAG_IPV6 is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS is not set
+# CONFIG_IPV6 is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_IP_NF_CONNTRACK=m
+CONFIG_IP_NF_CT_ACCT=y
+CONFIG_IP_NF_CONNTRACK_MARK=y
+CONFIG_IP_NF_CT_PROTO_SCTP=m
+CONFIG_IP_NF_FTP=m
+CONFIG_IP_NF_IRC=m
+CONFIG_IP_NF_TFTP=m
+CONFIG_IP_NF_AMANDA=m
+CONFIG_IP_NF_QUEUE=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_LIMIT=m
+CONFIG_IP_NF_MATCH_IPRANGE=m
+CONFIG_IP_NF_MATCH_MAC=m
+CONFIG_IP_NF_MATCH_PKTTYPE=m
+CONFIG_IP_NF_MATCH_MARK=m
+CONFIG_IP_NF_MATCH_MULTIPORT=m
+CONFIG_IP_NF_MATCH_TOS=m
+CONFIG_IP_NF_MATCH_RECENT=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_DSCP=m
+CONFIG_IP_NF_MATCH_AH_ESP=m
+CONFIG_IP_NF_MATCH_LENGTH=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_MATCH_TCPMSS=m
+CONFIG_IP_NF_MATCH_HELPER=m
+CONFIG_IP_NF_MATCH_STATE=m
+CONFIG_IP_NF_MATCH_CONNTRACK=m
+CONFIG_IP_NF_MATCH_OWNER=m
+CONFIG_IP_NF_MATCH_ADDRTYPE=m
+CONFIG_IP_NF_MATCH_REALM=m
+CONFIG_IP_NF_MATCH_SCTP=m
+CONFIG_IP_NF_MATCH_COMMENT=m
+CONFIG_IP_NF_MATCH_CONNMARK=m
+CONFIG_IP_NF_MATCH_HASHLIMIT=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_LOG=m
+CONFIG_IP_NF_TARGET_ULOG=m
+CONFIG_IP_NF_TARGET_TCPMSS=m
+CONFIG_IP_NF_NAT=m
+CONFIG_IP_NF_NAT_NEEDED=y
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_TARGET_REDIRECT=m
+CONFIG_IP_NF_TARGET_NETMAP=m
+CONFIG_IP_NF_TARGET_SAME=m
+CONFIG_IP_NF_NAT_SNMP_BASIC=m
+CONFIG_IP_NF_NAT_IRC=m
+CONFIG_IP_NF_NAT_FTP=m
+CONFIG_IP_NF_NAT_TFTP=m
+CONFIG_IP_NF_NAT_AMANDA=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_TOS=m
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_DSCP=m
+CONFIG_IP_NF_TARGET_MARK=m
+CONFIG_IP_NF_TARGET_CLASSIFY=m
+CONFIG_IP_NF_TARGET_CONNMARK=m
+CONFIG_IP_NF_TARGET_CLUSTERIP=m
+CONFIG_IP_NF_RAW=m
+CONFIG_IP_NF_TARGET_NOTRACK=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+CONFIG_NET_CLS_ROUTE=y
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+CONFIG_NETPOLL=y
+# CONFIG_NETPOLL_RX is not set
+# CONFIG_NETPOLL_TRAP is not set
+CONFIG_NET_POLL_CONTROLLER=y
+# CONFIG_HAMRADIO is not set
+CONFIG_IRDA=m
+
+#
+# IrDA protocols
+#
+CONFIG_IRLAN=m
+CONFIG_IRNET=m
+CONFIG_IRCOMM=m
+# CONFIG_IRDA_ULTRA is not set
+
+#
+# IrDA options
+#
+CONFIG_IRDA_CACHE_LAST_LSAP=y
+CONFIG_IRDA_FAST_RR=y
+# CONFIG_IRDA_DEBUG is not set
+
+#
+# Infrared-port device drivers
+#
+
+#
+# SIR device drivers
+#
+CONFIG_IRTTY_SIR=m
+
+#
+# Dongle support
+#
+# CONFIG_DONGLE is not set
+
+#
+# Old SIR device drivers
+#
+# CONFIG_IRPORT_SIR is not set
+
+#
+# Old Serial dongle support
+#
+
+#
+# FIR device drivers
+#
+# CONFIG_USB_IRDA is not set
+# CONFIG_SIGMATEL_FIR is not set
+# CONFIG_NSC_FIR is not set
+# CONFIG_WINBOND_FIR is not set
+# CONFIG_TOSHIBA_FIR is not set
+# CONFIG_SMC_IRCC_FIR is not set
+# CONFIG_ALI_FIR is not set
+# CONFIG_VLSI_FIR is not set
+# CONFIG_VIA_FIR is not set
+# CONFIG_BT is not set
+
+#
 # Device Drivers
 #
 
@@ -183,7 +403,7 @@ CONFIG_BOOT_LOAD=0x00800000
 #
 # CONFIG_STANDALONE is not set
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+CONFIG_FW_LOADER=m
 # CONFIG_DEBUG_DRIVER is not set
 
 #
@@ -279,6 +499,7 @@ CONFIG_BLK_DEV_CMD64X=y
 # CONFIG_BLK_DEV_HPT366 is not set
 # CONFIG_BLK_DEV_SC1200 is not set
 # CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_BLK_DEV_IT821X is not set
 # CONFIG_BLK_DEV_NS87415 is not set
 # CONFIG_BLK_DEV_PDC202XX_OLD is not set
 CONFIG_BLK_DEV_PDC202XX_NEW=y
@@ -313,6 +534,7 @@ CONFIG_CHR_DEV_ST=y
 CONFIG_BLK_DEV_SR=y
 CONFIG_BLK_DEV_SR_VENDOR=y
 CONFIG_CHR_DEV_SG=y
+# CONFIG_CHR_DEV_SCH is not set
 
 #
 # Some SCSI devices (e.g. CD jukebox) support multiple LUNs
@@ -350,7 +572,6 @@ CONFIG_SCSI_AIC7XXX_OLD=m
 # CONFIG_SCSI_BUSLOGIC is not set
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_EATA_PIO is not set
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
 # CONFIG_SCSI_GDTH is not set
 # CONFIG_SCSI_IPS is not set
@@ -362,7 +583,6 @@ CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
 CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
 # CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
 # CONFIG_SCSI_IPR is not set
-# CONFIG_SCSI_QLOGIC_ISP is not set
 # CONFIG_SCSI_QLOGIC_FC is not set
 # CONFIG_SCSI_QLOGIC_1280 is not set
 CONFIG_SCSI_QLA2XXX=y
@@ -371,6 +591,7 @@ CONFIG_SCSI_QLA2XXX=y
 # CONFIG_SCSI_QLA2300 is not set
 # CONFIG_SCSI_QLA2322 is not set
 # CONFIG_SCSI_QLA6312 is not set
+# CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_NSP32 is not set
@@ -398,6 +619,8 @@ CONFIG_SCSI_MAC53C94=y
 # Fusion MPT device support
 #
 # CONFIG_FUSION is not set
+# CONFIG_FUSION_SPI is not set
+# CONFIG_FUSION_FC is not set
 
 #
 # IEEE 1394 (FireWire) support
@@ -411,6 +634,7 @@ CONFIG_IEEE1394=m
 # CONFIG_IEEE1394_OUI_DB is not set
 CONFIG_IEEE1394_EXTRA_CONFIG_ROMS=y
 CONFIG_IEEE1394_CONFIG_ROM_IP1394=y
+# CONFIG_IEEE1394_EXPORT_FULL_API is not set
 
 #
 # Device Drivers
@@ -441,8 +665,8 @@ CONFIG_IEEE1394_AMDTP=m
 CONFIG_ADB=y
 CONFIG_ADB_CUDA=y
 CONFIG_ADB_PMU=y
-CONFIG_PMAC_PBOOK=y
 CONFIG_PMAC_APM_EMU=y
+CONFIG_PMAC_MEDIABAY=y
 CONFIG_PMAC_BACKLIGHT=y
 CONFIG_ADB_MACIO=y
 CONFIG_INPUT_ADBHID=y
@@ -452,192 +676,13 @@ CONFIG_THERM_ADT746X=m
 # CONFIG_ANSLCD is not set
 
 #
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK_DEV is not set
-CONFIG_UNIX=y
-# CONFIG_NET_KEY is not set
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-# CONFIG_IP_PNP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
-# CONFIG_ARPD is not set
-CONFIG_SYN_COOKIES=y
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_TUNNEL is not set
-CONFIG_IP_TCPDIAG=y
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-
-#
-# IP: Virtual Server Configuration
-#
-# CONFIG_IP_VS is not set
-# CONFIG_IPV6 is not set
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-
-#
-# IP: Netfilter Configuration
-#
-CONFIG_IP_NF_CONNTRACK=m
-CONFIG_IP_NF_CT_ACCT=y
-CONFIG_IP_NF_CONNTRACK_MARK=y
-CONFIG_IP_NF_CT_PROTO_SCTP=m
-CONFIG_IP_NF_FTP=m
-CONFIG_IP_NF_IRC=m
-CONFIG_IP_NF_TFTP=m
-CONFIG_IP_NF_AMANDA=m
-CONFIG_IP_NF_QUEUE=m
-CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_MATCH_LIMIT=m
-CONFIG_IP_NF_MATCH_IPRANGE=m
-CONFIG_IP_NF_MATCH_MAC=m
-CONFIG_IP_NF_MATCH_PKTTYPE=m
-CONFIG_IP_NF_MATCH_MARK=m
-CONFIG_IP_NF_MATCH_MULTIPORT=m
-CONFIG_IP_NF_MATCH_TOS=m
-CONFIG_IP_NF_MATCH_RECENT=m
-CONFIG_IP_NF_MATCH_ECN=m
-CONFIG_IP_NF_MATCH_DSCP=m
-CONFIG_IP_NF_MATCH_AH_ESP=m
-CONFIG_IP_NF_MATCH_LENGTH=m
-CONFIG_IP_NF_MATCH_TTL=m
-CONFIG_IP_NF_MATCH_TCPMSS=m
-CONFIG_IP_NF_MATCH_HELPER=m
-CONFIG_IP_NF_MATCH_STATE=m
-CONFIG_IP_NF_MATCH_CONNTRACK=m
-CONFIG_IP_NF_MATCH_OWNER=m
-CONFIG_IP_NF_MATCH_ADDRTYPE=m
-CONFIG_IP_NF_MATCH_REALM=m
-CONFIG_IP_NF_MATCH_SCTP=m
-CONFIG_IP_NF_MATCH_COMMENT=m
-CONFIG_IP_NF_MATCH_CONNMARK=m
-CONFIG_IP_NF_MATCH_HASHLIMIT=m
-CONFIG_IP_NF_FILTER=m
-CONFIG_IP_NF_TARGET_REJECT=m
-CONFIG_IP_NF_TARGET_LOG=m
-CONFIG_IP_NF_TARGET_ULOG=m
-CONFIG_IP_NF_TARGET_TCPMSS=m
-CONFIG_IP_NF_NAT=m
-CONFIG_IP_NF_NAT_NEEDED=y
-CONFIG_IP_NF_TARGET_MASQUERADE=m
-CONFIG_IP_NF_TARGET_REDIRECT=m
-CONFIG_IP_NF_TARGET_NETMAP=m
-CONFIG_IP_NF_TARGET_SAME=m
-CONFIG_IP_NF_NAT_SNMP_BASIC=m
-CONFIG_IP_NF_NAT_IRC=m
-CONFIG_IP_NF_NAT_FTP=m
-CONFIG_IP_NF_NAT_TFTP=m
-CONFIG_IP_NF_NAT_AMANDA=m
-CONFIG_IP_NF_MANGLE=m
-CONFIG_IP_NF_TARGET_TOS=m
-CONFIG_IP_NF_TARGET_ECN=m
-CONFIG_IP_NF_TARGET_DSCP=m
-CONFIG_IP_NF_TARGET_MARK=m
-CONFIG_IP_NF_TARGET_CLASSIFY=m
-CONFIG_IP_NF_TARGET_CONNMARK=m
-CONFIG_IP_NF_TARGET_CLUSTERIP=m
-CONFIG_IP_NF_RAW=m
-CONFIG_IP_NF_TARGET_NOTRACK=m
-CONFIG_IP_NF_ARPTABLES=m
-CONFIG_IP_NF_ARPFILTER=m
-CONFIG_IP_NF_ARP_MANGLE=m
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-CONFIG_NET_CLS_ROUTE=y
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-CONFIG_IRDA=m
-
-#
-# IrDA protocols
-#
-CONFIG_IRLAN=m
-CONFIG_IRNET=m
-CONFIG_IRCOMM=m
-# CONFIG_IRDA_ULTRA is not set
-
-#
-# IrDA options
-#
-CONFIG_IRDA_CACHE_LAST_LSAP=y
-CONFIG_IRDA_FAST_RR=y
-# CONFIG_IRDA_DEBUG is not set
-
-#
-# Infrared-port device drivers
-#
-
-#
-# SIR device drivers
-#
-CONFIG_IRTTY_SIR=m
-
-#
-# Dongle support
-#
-# CONFIG_DONGLE is not set
-
-#
-# Old SIR device drivers
-#
-# CONFIG_IRPORT_SIR is not set
-
-#
-# Old Serial dongle support
-#
-
-#
-# FIR device drivers
+# Network device support
 #
-# CONFIG_USB_IRDA is not set
-# CONFIG_SIGMATEL_FIR is not set
-# CONFIG_TOSHIBA_FIR is not set
-# CONFIG_VLSI_FIR is not set
-# CONFIG_BT is not set
 CONFIG_NETDEVICES=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
+CONFIG_TUN=m
 
 #
 # ARCnet devices
@@ -691,9 +736,12 @@ CONFIG_PCNET32=y
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
 # CONFIG_R8169 is not set
+# CONFIG_SKGE is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+# CONFIG_MV643XX_ETH is not set
 
 #
 # Ethernet (10000 Mbit)
@@ -768,7 +816,7 @@ CONFIG_PPPOE=m
 # CONFIG_SLIP is not set
 # CONFIG_NET_FC is not set
 # CONFIG_SHAPER is not set
-# CONFIG_NETCONSOLE is not set
+CONFIG_NETCONSOLE=m
 
 #
 # ISDN subsystem
@@ -798,14 +846,6 @@ CONFIG_INPUT_EVDEV=y
 # CONFIG_INPUT_EVBUG is not set
 
 #
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-# CONFIG_SERIO is not set
-# CONFIG_SERIO_I8042 is not set
-
-#
 # Input Device Drivers
 #
 CONFIG_INPUT_KEYBOARD=y
@@ -823,6 +863,12 @@ CONFIG_INPUT_MOUSE=y
 # CONFIG_INPUT_MISC is not set
 
 #
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
 # Character devices
 #
 CONFIG_VT=y
@@ -845,6 +891,7 @@ CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_SERIAL_PMACZILOG=y
 CONFIG_SERIAL_PMACZILOG_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -876,6 +923,7 @@ CONFIG_DRM_R128=m
 CONFIG_DRM_RADEON=m
 # CONFIG_DRM_MGA is not set
 # CONFIG_DRM_SIS is not set
+# CONFIG_DRM_VIA is not set
 
 #
 # PCMCIA character devices
@@ -884,6 +932,11 @@ CONFIG_DRM_RADEON=m
 # CONFIG_RAW_DRIVER is not set
 
 #
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
 # I2C support
 #
 CONFIG_I2C=y
@@ -907,12 +960,12 @@ CONFIG_I2C_ALGOBIT=y
 # CONFIG_I2C_HYDRA is not set
 # CONFIG_I2C_I801 is not set
 # CONFIG_I2C_I810 is not set
+# CONFIG_I2C_PIIX4 is not set
 # CONFIG_I2C_ISA is not set
 CONFIG_I2C_KEYWEST=m
 # CONFIG_I2C_MPC is not set
 # CONFIG_I2C_NFORCE2 is not set
 # CONFIG_I2C_PARPORT_LIGHT is not set
-# CONFIG_I2C_PIIX4 is not set
 # CONFIG_I2C_PROSAVAGE is not set
 # CONFIG_I2C_SAVAGE4 is not set
 # CONFIG_SCx200_ACB is not set
@@ -924,45 +977,20 @@ CONFIG_I2C_KEYWEST=m
 # CONFIG_I2C_VIAPRO is not set
 # CONFIG_I2C_VOODOO3 is not set
 # CONFIG_I2C_PCA_ISA is not set
-
-#
-# Hardware Sensors Chip support
-#
 # CONFIG_I2C_SENSOR is not set
-# CONFIG_SENSORS_ADM1021 is not set
-# CONFIG_SENSORS_ADM1025 is not set
-# CONFIG_SENSORS_ADM1026 is not set
-# CONFIG_SENSORS_ADM1031 is not set
-# CONFIG_SENSORS_ASB100 is not set
-# CONFIG_SENSORS_DS1621 is not set
-# CONFIG_SENSORS_FSCHER is not set
-# CONFIG_SENSORS_GL518SM is not set
-# CONFIG_SENSORS_IT87 is not set
-# CONFIG_SENSORS_LM63 is not set
-# CONFIG_SENSORS_LM75 is not set
-# CONFIG_SENSORS_LM77 is not set
-# CONFIG_SENSORS_LM78 is not set
-# CONFIG_SENSORS_LM80 is not set
-# CONFIG_SENSORS_LM83 is not set
-# CONFIG_SENSORS_LM85 is not set
-# CONFIG_SENSORS_LM87 is not set
-# CONFIG_SENSORS_LM90 is not set
-# CONFIG_SENSORS_MAX1619 is not set
-# CONFIG_SENSORS_PC87360 is not set
-# CONFIG_SENSORS_SMSC47B397 is not set
-# CONFIG_SENSORS_SMSC47M1 is not set
-# CONFIG_SENSORS_VIA686A is not set
-# CONFIG_SENSORS_W83781D is not set
-# CONFIG_SENSORS_W83L785TS is not set
-# CONFIG_SENSORS_W83627HF is not set
 
 #
-# Other I2C Chip support
+# Miscellaneous I2C Chip support
 #
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
 # CONFIG_SENSORS_EEPROM is not set
 # CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_SENSORS_PCA9539 is not set
 # CONFIG_SENSORS_PCF8591 is not set
 # CONFIG_SENSORS_RTC8564 is not set
+# CONFIG_SENSORS_M41T00 is not set
+# CONFIG_SENSORS_MAX6875 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
@@ -974,6 +1002,11 @@ CONFIG_I2C_KEYWEST=m
 # CONFIG_W1 is not set
 
 #
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+
+#
 # Misc devices
 #
 
@@ -991,6 +1024,11 @@ CONFIG_I2C_KEYWEST=m
 # Graphics support
 #
 CONFIG_FB=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+CONFIG_FB_SOFT_CURSOR=y
+CONFIG_FB_MACMODES=y
 CONFIG_FB_MODE_HELPERS=y
 CONFIG_FB_TILEBLITTING=y
 # CONFIG_FB_CIRRUS is not set
@@ -1004,6 +1042,7 @@ CONFIG_FB_CT65550=y
 # CONFIG_FB_ASILIANT is not set
 CONFIG_FB_IMSTT=y
 # CONFIG_FB_VGA16 is not set
+# CONFIG_FB_NVIDIA is not set
 # CONFIG_FB_RIVA is not set
 CONFIG_FB_MATROX=y
 CONFIG_FB_MATROX_MILLENIUM=y
@@ -1029,6 +1068,7 @@ CONFIG_FB_3DFX=y
 CONFIG_FB_3DFX_ACCEL=y
 # CONFIG_FB_VOODOO1 is not set
 # CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_S1D13XXX is not set
 # CONFIG_FB_VIRTUAL is not set
 
 #
@@ -1110,6 +1150,7 @@ CONFIG_SND_DUMMY=m
 # CONFIG_SND_RME96 is not set
 # CONFIG_SND_RME9652 is not set
 # CONFIG_SND_HDSP is not set
+# CONFIG_SND_HDSPM is not set
 # CONFIG_SND_TRIDENT is not set
 # CONFIG_SND_YMFPCI is not set
 # CONFIG_SND_ALS4000 is not set
@@ -1128,6 +1169,7 @@ CONFIG_SND_DUMMY=m
 # CONFIG_SND_VIA82XX is not set
 # CONFIG_SND_VIA82XX_MODEM is not set
 # CONFIG_SND_VX222 is not set
+# CONFIG_SND_HDA_INTEL is not set
 
 #
 # ALSA PowerMac devices
@@ -1152,6 +1194,8 @@ CONFIG_SND_USB_USX2Y=m
 #
 # USB support
 #
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
 CONFIG_USB=y
 # CONFIG_USB_DEBUG is not set
 
@@ -1163,14 +1207,15 @@ CONFIG_USB_DEVICEFS=y
 CONFIG_USB_DYNAMIC_MINORS=y
 CONFIG_USB_SUSPEND=y
 # CONFIG_USB_OTG is not set
-CONFIG_USB_ARCH_HAS_HCD=y
-CONFIG_USB_ARCH_HAS_OHCI=y
 
 #
 # USB Host Controller Drivers
 #
 # CONFIG_USB_EHCI_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
 CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 # CONFIG_USB_UHCI_HCD is not set
 # CONFIG_USB_SL811_HCD is not set
 
@@ -1197,12 +1242,15 @@ CONFIG_USB_HIDINPUT=y
 CONFIG_USB_HIDDEV=y
 # CONFIG_USB_AIPTEK is not set
 # CONFIG_USB_WACOM is not set
+# CONFIG_USB_ACECAD is not set
 # CONFIG_USB_KBTAB is not set
 # CONFIG_USB_POWERMATE is not set
 # CONFIG_USB_MTOUCH is not set
+# CONFIG_USB_ITMTOUCH is not set
 # CONFIG_USB_EGALAX is not set
 # CONFIG_USB_XPAD is not set
 # CONFIG_USB_ATI_REMOTE is not set
+# CONFIG_USB_KEYSPAN_REMOTE is not set
 
 #
 # USB Imaging devices
@@ -1227,6 +1275,8 @@ CONFIG_USB_HIDDEV=y
 CONFIG_USB_PEGASUS=m
 # CONFIG_USB_RTL8150 is not set
 # CONFIG_USB_USBNET is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_USB_MON is not set
 
 #
 # USB port drivers
@@ -1237,9 +1287,11 @@ CONFIG_USB_PEGASUS=m
 #
 CONFIG_USB_SERIAL=m
 # CONFIG_USB_SERIAL_GENERIC is not set
+# CONFIG_USB_SERIAL_AIRPRIME is not set
 # CONFIG_USB_SERIAL_BELKIN is not set
 # CONFIG_USB_SERIAL_WHITEHEAT is not set
 # CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_CP2101 is not set
 # CONFIG_USB_SERIAL_CYPRESS_M8 is not set
 # CONFIG_USB_SERIAL_EMPEG is not set
 # CONFIG_USB_SERIAL_FTDI_SIO is not set
@@ -1268,10 +1320,12 @@ CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y
 # CONFIG_USB_SERIAL_KOBIL_SCT is not set
 # CONFIG_USB_SERIAL_MCT_U232 is not set
 # CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_HP4X is not set
 # CONFIG_USB_SERIAL_SAFE is not set
 # CONFIG_USB_SERIAL_TI is not set
 # CONFIG_USB_SERIAL_CYBERJACK is not set
 # CONFIG_USB_SERIAL_XIRCOM is not set
+# CONFIG_USB_SERIAL_OPTION is not set
 # CONFIG_USB_SERIAL_OMNINET is not set
 CONFIG_USB_EZUSB=y
 
@@ -1289,10 +1343,11 @@ CONFIG_USB_EZUSB=y
 # CONFIG_USB_PHIDGETKIT is not set
 # CONFIG_USB_PHIDGETSERVO is not set
 # CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_LD is not set
 # CONFIG_USB_TEST is not set
 
 #
-# USB ATM/DSL drivers
+# USB DSL modem support
 #
 
 #
@@ -1311,12 +1366,17 @@ CONFIG_USB_EZUSB=y
 # CONFIG_INFINIBAND is not set
 
 #
+# SN Devices
+#
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
 CONFIG_EXT2_FS_XATTR=y
 # CONFIG_EXT2_FS_POSIX_ACL is not set
 # CONFIG_EXT2_FS_SECURITY is not set
+# CONFIG_EXT2_FS_XIP is not set
 CONFIG_EXT3_FS=y
 CONFIG_EXT3_FS_XATTR=y
 # CONFIG_EXT3_FS_POSIX_ACL is not set
@@ -1326,6 +1386,7 @@ CONFIG_JBD=y
 CONFIG_FS_MBCACHE=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
 
 #
 # XFS support
@@ -1333,6 +1394,7 @@ CONFIG_FS_MBCACHE=y
 # CONFIG_XFS_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
 # CONFIG_QUOTA is not set
 CONFIG_DNOTIFY=y
 # CONFIG_AUTOFS_FS is not set
@@ -1363,7 +1425,6 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
 CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
 CONFIG_DEVPTS_FS_XATTR=y
 CONFIG_DEVPTS_FS_SECURITY=y
 CONFIG_TMPFS=y
@@ -1394,15 +1455,20 @@ CONFIG_CRAMFS=m
 #
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
 # CONFIG_NFS_V4 is not set
 # CONFIG_NFS_DIRECTIO is not set
 CONFIG_NFSD=y
+CONFIG_NFSD_V2_ACL=y
 CONFIG_NFSD_V3=y
+CONFIG_NFSD_V3_ACL=y
 # CONFIG_NFSD_V4 is not set
 CONFIG_NFSD_TCP=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_EXPORTFS=y
+CONFIG_NFS_ACL_SUPPORT=y
+CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -1494,8 +1560,10 @@ CONFIG_ZLIB_DEFLATE=y
 #
 # Kernel hacking
 #
+# CONFIG_PRINTK_TIME is not set
 CONFIG_DEBUG_KERNEL=y
 CONFIG_MAGIC_SYSRQ=y
+CONFIG_LOG_BUF_SHIFT=16
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_DEBUG_SLAB is not set
 # CONFIG_DEBUG_SPINLOCK is not set
diff --git a/arch/ppc/configs/radstone_ppc7d_defconfig b/arch/ppc/configs/radstone_ppc7d_defconfig
--- a/arch/ppc/configs/radstone_ppc7d_defconfig
+++ b/arch/ppc/configs/radstone_ppc7d_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11
-# Tue Mar 15 14:31:19 2005
+# Linux kernel version: 2.6.13-rc3
+# Tue Jul 26 00:02:09 2005
 #
 CONFIG_MMU=y
 CONFIG_GENERIC_HARDIRQS=y
@@ -11,6 +11,7 @@ CONFIG_HAVE_DEC_LOCK=y
 CONFIG_PPC=y
 CONFIG_PPC32=y
 CONFIG_GENERIC_NVRAM=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
 
 #
 # Code maturity level options
@@ -18,6 +19,7 @@ CONFIG_GENERIC_NVRAM=y
 CONFIG_EXPERIMENTAL=y
 CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
@@ -35,6 +37,8 @@ CONFIG_KOBJECT_UEVENT=y
 CONFIG_EMBEDDED=y
 CONFIG_KALLSYMS=y
 CONFIG_KALLSYMS_EXTRA_PASS=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
@@ -67,9 +71,12 @@ CONFIG_6xx=y
 # CONFIG_POWER3 is not set
 # CONFIG_POWER4 is not set
 # CONFIG_8xx is not set
+# CONFIG_E200 is not set
 # CONFIG_E500 is not set
+CONFIG_PPC_FPU=y
 CONFIG_ALTIVEC=y
 # CONFIG_TAU is not set
+# CONFIG_KEXEC is not set
 # CONFIG_CPU_FREQ is not set
 CONFIG_PPC_GEN550=y
 # CONFIG_PM is not set
@@ -84,21 +91,18 @@ CONFIG_PPC_STD_MMU=y
 # CONFIG_KATANA is not set
 # CONFIG_WILLOW is not set
 # CONFIG_CPCI690 is not set
-# CONFIG_PCORE is not set
 # CONFIG_POWERPMC250 is not set
 # CONFIG_CHESTNUT is not set
 # CONFIG_SPRUCE is not set
+# CONFIG_HDPU is not set
 # CONFIG_EV64260 is not set
 # CONFIG_LOPEC is not set
-# CONFIG_MCPN765 is not set
 # CONFIG_MVME5100 is not set
 # CONFIG_PPLUS is not set
 # CONFIG_PRPMC750 is not set
 # CONFIG_PRPMC800 is not set
 # CONFIG_SANDPOINT is not set
 CONFIG_RADSTONE_PPC7D=y
-# CONFIG_ADIR is not set
-# CONFIG_K2 is not set
 # CONFIG_PAL4 is not set
 # CONFIG_GEMINI is not set
 # CONFIG_EST8260 is not set
@@ -121,10 +125,18 @@ CONFIG_MV64X60_NEW_BASE=0xfef00000
 # CONFIG_SMP is not set
 # CONFIG_PREEMPT is not set
 # CONFIG_HIGHMEM is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_BINFMT_ELF=y
 CONFIG_BINFMT_MISC=y
 CONFIG_CMDLINE_BOOL=y
 CONFIG_CMDLINE="console=ttyS0,9600"
+CONFIG_SECCOMP=y
+CONFIG_ISA_DMA_API=y
 
 #
 # Bus options
@@ -155,6 +167,69 @@ CONFIG_TASK_SIZE=0x80000000
 CONFIG_BOOT_LOAD=0x00800000
 
 #
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_IP_TCPDIAG=y
+# CONFIG_IP_TCPDIAG_IPV6 is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+CONFIG_BRIDGE=y
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+
+#
 # Device Drivers
 #
 
@@ -203,6 +278,7 @@ CONFIG_MTD_CFI_I1=y
 CONFIG_MTD_CFI_I2=y
 # CONFIG_MTD_CFI_I4 is not set
 # CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_OTP is not set
 CONFIG_MTD_CFI_INTELEXT=y
 # CONFIG_MTD_CFI_AMDSTD is not set
 # CONFIG_MTD_CFI_STAA is not set
@@ -210,13 +286,13 @@ CONFIG_MTD_CFI_UTIL=y
 # CONFIG_MTD_RAM is not set
 # CONFIG_MTD_ROM is not set
 # CONFIG_MTD_ABSENT is not set
-# CONFIG_MTD_XIP is not set
 
 #
 # Mapping drivers for chip access
 #
 # CONFIG_MTD_COMPLEX_MAPPINGS is not set
 # CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_PLATRAM is not set
 
 #
 # Self-contained MTD device drivers
@@ -299,6 +375,7 @@ CONFIG_BLK_DEV_SD=y
 CONFIG_BLK_DEV_SR=y
 CONFIG_BLK_DEV_SR_VENDOR=y
 CONFIG_CHR_DEV_SG=y
+# CONFIG_CHR_DEV_SCH is not set
 
 #
 # Some SCSI devices (e.g. CD jukebox) support multiple LUNs
@@ -331,7 +408,6 @@ CONFIG_SCSI_SPI_ATTRS=y
 # CONFIG_SCSI_BUSLOGIC is not set
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_EATA_PIO is not set
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
 # CONFIG_SCSI_GDTH is not set
 # CONFIG_SCSI_IPS is not set
@@ -343,7 +419,6 @@ CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
 CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
 # CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
 # CONFIG_SCSI_IPR is not set
-# CONFIG_SCSI_QLOGIC_ISP is not set
 # CONFIG_SCSI_QLOGIC_FC is not set
 # CONFIG_SCSI_QLOGIC_1280 is not set
 CONFIG_SCSI_QLA2XXX=y
@@ -352,6 +427,7 @@ CONFIG_SCSI_QLA2XXX=y
 # CONFIG_SCSI_QLA2300 is not set
 # CONFIG_SCSI_QLA2322 is not set
 # CONFIG_SCSI_QLA6312 is not set
+# CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_NSP32 is not set
@@ -366,6 +442,8 @@ CONFIG_SCSI_QLA2XXX=y
 # Fusion MPT device support
 #
 # CONFIG_FUSION is not set
+# CONFIG_FUSION_SPI is not set
+# CONFIG_FUSION_FC is not set
 
 #
 # IEEE 1394 (FireWire) support
@@ -382,71 +460,8 @@ CONFIG_SCSI_QLA2XXX=y
 #
 
 #
-# Networking support
+# Network device support
 #
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK_DEV is not set
-CONFIG_UNIX=y
-# CONFIG_NET_KEY is not set
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
-# CONFIG_ARPD is not set
-CONFIG_SYN_COOKIES=y
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_TUNNEL is not set
-CONFIG_IP_TCPDIAG=y
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-CONFIG_BRIDGE=y
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
 CONFIG_NETDEVICES=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
@@ -511,9 +526,11 @@ CONFIG_E100=y
 # CONFIG_YELLOWFIN is not set
 CONFIG_R8169=y
 CONFIG_R8169_NAPI=y
+# CONFIG_SKGE is not set
 CONFIG_SK98LIN=y
 # CONFIG_VIA_VELOCITY is not set
 CONFIG_TIGON3=y
+# CONFIG_BNX2 is not set
 CONFIG_MV643XX_ETH=y
 CONFIG_MV643XX_ETH_0=y
 CONFIG_MV643XX_ETH_1=y
@@ -546,6 +563,8 @@ CONFIG_MV643XX_ETH_1=y
 # CONFIG_NET_FC is not set
 # CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
 
 #
 # ISDN subsystem
@@ -598,7 +617,6 @@ CONFIG_SERIO_SERPORT=y
 CONFIG_SERIO_LIBPS2=y
 # CONFIG_SERIO_RAW is not set
 # CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
 
 #
 # Character devices
@@ -623,6 +641,7 @@ CONFIG_SERIAL_MPSC=y
 # CONFIG_SERIAL_MPSC_CONSOLE is not set
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -690,11 +709,11 @@ CONFIG_I2C_CHARDEV=y
 # CONFIG_I2C_AMD8111 is not set
 # CONFIG_I2C_I801 is not set
 # CONFIG_I2C_I810 is not set
+# CONFIG_I2C_PIIX4 is not set
 # CONFIG_I2C_ISA is not set
 # CONFIG_I2C_MPC is not set
 # CONFIG_I2C_NFORCE2 is not set
 # CONFIG_I2C_PARPORT_LIGHT is not set
-# CONFIG_I2C_PIIX4 is not set
 # CONFIG_I2C_PROSAVAGE is not set
 # CONFIG_I2C_SAVAGE4 is not set
 # CONFIG_SCx200_ACB is not set
@@ -707,16 +726,41 @@ CONFIG_I2C_CHARDEV=y
 # CONFIG_I2C_VOODOO3 is not set
 # CONFIG_I2C_PCA_ISA is not set
 CONFIG_I2C_MV64XXX=y
+CONFIG_I2C_SENSOR=y
 
 #
-# Hardware Sensors Chip support
+# Miscellaneous I2C Chip support
 #
-CONFIG_I2C_SENSOR=y
+CONFIG_SENSORS_DS1337=y
+# CONFIG_SENSORS_DS1374 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_RTC8564 is not set
+# CONFIG_SENSORS_M41T00 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1021 is not set
 # CONFIG_SENSORS_ADM1025 is not set
 # CONFIG_SENSORS_ADM1026 is not set
 # CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
 # CONFIG_SENSORS_ASB100 is not set
+# CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_FSCHER is not set
 # CONFIG_SENSORS_FSCPOS is not set
@@ -732,33 +776,18 @@ CONFIG_I2C_SENSOR=y
 # CONFIG_SENSORS_LM85 is not set
 # CONFIG_SENSORS_LM87 is not set
 CONFIG_SENSORS_LM90=y
+# CONFIG_SENSORS_LM92 is not set
 # CONFIG_SENSORS_MAX1619 is not set
 # CONFIG_SENSORS_PC87360 is not set
-# CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_SIS5595 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_VIA686A is not set
 # CONFIG_SENSORS_W83781D is not set
 # CONFIG_SENSORS_W83L785TS is not set
 # CONFIG_SENSORS_W83627HF is not set
-
-#
-# Other I2C Chip support
-#
-# CONFIG_SENSORS_EEPROM is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_SENSORS_PCF8591 is not set
-# CONFIG_SENSORS_RTC8564 is not set
-# CONFIG_SENSORS_M41T00 is not set
-# CONFIG_I2C_DEBUG_CORE is not set
-# CONFIG_I2C_DEBUG_ALGO is not set
-# CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
-
-#
-# Dallas's 1-wire bus
-#
-# CONFIG_W1 is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
 
 #
 # Misc devices
@@ -813,14 +842,20 @@ CONFIG_USB_ARCH_HAS_OHCI=y
 # CONFIG_INFINIBAND is not set
 
 #
+# SN Devices
+#
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
 # CONFIG_JBD is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
 
 #
 # XFS support
@@ -828,6 +863,7 @@ CONFIG_EXT2_FS=y
 # CONFIG_XFS_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
 # CONFIG_QUOTA is not set
 CONFIG_DNOTIFY=y
 # CONFIG_AUTOFS_FS is not set
@@ -854,7 +890,6 @@ CONFIG_ISO9660_FS=y
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
 CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
 # CONFIG_DEVPTS_FS_XATTR is not set
 CONFIG_TMPFS=y
 # CONFIG_TMPFS_XATTR is not set
@@ -874,8 +909,7 @@ CONFIG_RAMFS=y
 # CONFIG_JFFS_FS is not set
 CONFIG_JFFS2_FS=y
 CONFIG_JFFS2_FS_DEBUG=0
-# CONFIG_JFFS2_FS_NAND is not set
-# CONFIG_JFFS2_FS_NOR_ECC is not set
+CONFIG_JFFS2_FS_WRITEBUFFER=y
 # CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
 CONFIG_JFFS2_ZLIB=y
 CONFIG_JFFS2_RTIME=y
@@ -892,12 +926,14 @@ CONFIG_JFFS2_RTIME=y
 #
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
 # CONFIG_NFS_V4 is not set
 # CONFIG_NFS_DIRECTIO is not set
 # CONFIG_NFSD is not set
 CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
diff --git a/arch/ppc/configs/sandpoint_defconfig b/arch/ppc/configs/sandpoint_defconfig
--- a/arch/ppc/configs/sandpoint_defconfig
+++ b/arch/ppc/configs/sandpoint_defconfig
@@ -437,7 +437,7 @@ CONFIG_SOUND_GAMEPORT=y
 #
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=2
+CONFIG_SERIAL_8250_NR_UARTS=4
 # CONFIG_SERIAL_8250_EXTENDED is not set
 
 #
diff --git a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile
--- a/arch/ppc/kernel/Makefile
+++ b/arch/ppc/kernel/Makefile
@@ -26,7 +26,10 @@ obj-$(CONFIG_KGDB)		+= ppc-stub.o
 obj-$(CONFIG_SMP)		+= smp.o smp-tbsync.o
 obj-$(CONFIG_TAU)		+= temp.o
 obj-$(CONFIG_ALTIVEC)		+= vecemu.o vector.o
+ifndef CONFIG_E200
 obj-$(CONFIG_FSL_BOOKE)		+= perfmon_fsl_booke.o
+endif
+obj-$(CONFIG_KEXEC)		+= machine_kexec.o relocate_kernel.o
 
 ifndef CONFIG_MATH_EMULATION
 obj-$(CONFIG_8xx)		+= softemu8xx.o
diff --git a/arch/ppc/kernel/cputable.c b/arch/ppc/kernel/cputable.c
--- a/arch/ppc/kernel/cputable.c
+++ b/arch/ppc/kernel/cputable.c
@@ -852,6 +852,26 @@ struct cpu_spec	cpu_specs[] = {
 
 #endif /* CONFIG_40x */
 #ifdef CONFIG_44x
+	{
+		.pvr_mask		= 0xf0000fff,
+		.pvr_value		= 0x40000850,
+		.cpu_name		= "440EP Rev. A",
+		.cpu_features		= CPU_FTR_SPLIT_ID_CACHE |
+			CPU_FTR_USE_TB,
+		.cpu_user_features	= COMMON_PPC, /* 440EP has an FPU */
+		.icache_bsize		= 32,
+		.dcache_bsize		= 32,
+	},
+	{
+		.pvr_mask		= 0xf0000fff,
+		.pvr_value		= 0x400008d3,
+		.cpu_name		= "440EP Rev. B",
+		.cpu_features		= CPU_FTR_SPLIT_ID_CACHE |
+			CPU_FTR_USE_TB,
+		.cpu_user_features	= COMMON_PPC, /* 440EP has an FPU */
+		.icache_bsize		= 32,
+		.dcache_bsize		= 32,
+	},
 	{ 	/* 440GP Rev. B */
 		.pvr_mask		= 0xf0000fff,
 		.pvr_value		= 0x40000440,
@@ -903,7 +923,30 @@ struct cpu_spec	cpu_specs[] = {
 		.dcache_bsize		= 32,
 	},
 #endif /* CONFIG_44x */
-#ifdef CONFIG_E500
+#ifdef CONFIG_FSL_BOOKE
+	{ 	/* e200z5 */
+		.pvr_mask		= 0xfff00000,
+		.pvr_value		= 0x81000000,
+		.cpu_name		= "e200z5",
+		/* xxx - galak: add CPU_FTR_MAYBE_CAN_DOZE */
+		.cpu_features		= CPU_FTR_USE_TB,
+		.cpu_user_features	= PPC_FEATURE_32 |
+			PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_EFP_SINGLE |
+			PPC_FEATURE_UNIFIED_CACHE,
+		.dcache_bsize		= 32,
+	},
+	{ 	/* e200z6 */
+		.pvr_mask		= 0xfff00000,
+		.pvr_value		= 0x81100000,
+		.cpu_name		= "e200z6",
+		/* xxx - galak: add CPU_FTR_MAYBE_CAN_DOZE */
+		.cpu_features		= CPU_FTR_USE_TB,
+		.cpu_user_features	= PPC_FEATURE_32 |
+			PPC_FEATURE_HAS_MMU | PPC_FEATURE_SPE_COMP |
+			PPC_FEATURE_HAS_EFP_SINGLE |
+			PPC_FEATURE_UNIFIED_CACHE,
+		.dcache_bsize		= 32,
+	},
 	{ 	/* e500 */
 		.pvr_mask		= 0xffff0000,
 		.pvr_value		= 0x80200000,
@@ -918,6 +961,20 @@ struct cpu_spec	cpu_specs[] = {
 		.dcache_bsize		= 32,
 		.num_pmcs		= 4,
 	},
+	{ 	/* e500v2 */
+		.pvr_mask		= 0xffff0000,
+		.pvr_value		= 0x80210000,
+		.cpu_name		= "e500v2",
+		/* xxx - galak: add CPU_FTR_MAYBE_CAN_DOZE */
+		.cpu_features		= CPU_FTR_SPLIT_ID_CACHE |
+			CPU_FTR_USE_TB | CPU_FTR_BIG_PHYS,
+		.cpu_user_features	= PPC_FEATURE_32 |
+			PPC_FEATURE_HAS_MMU | PPC_FEATURE_SPE_COMP |
+			PPC_FEATURE_HAS_EFP_SINGLE | PPC_FEATURE_HAS_EFP_DOUBLE,
+		.icache_bsize		= 32,
+		.dcache_bsize		= 32,
+		.num_pmcs		= 4,
+	},
 #endif
 #if !CLASSIC_PPC
 	{	/* default match */
diff --git a/arch/ppc/kernel/entry.S b/arch/ppc/kernel/entry.S
--- a/arch/ppc/kernel/entry.S
+++ b/arch/ppc/kernel/entry.S
@@ -46,26 +46,28 @@
 
 #ifdef CONFIG_BOOKE
 #include "head_booke.h"
+#define TRANSFER_TO_HANDLER_EXC_LEVEL(exc_level)	\
+	mtspr	exc_level##_SPRG,r8;			\
+	BOOKE_LOAD_EXC_LEVEL_STACK(exc_level);		\
+	lwz	r0,GPR10-INT_FRAME_SIZE(r8);		\
+	stw	r0,GPR10(r11);				\
+	lwz	r0,GPR11-INT_FRAME_SIZE(r8);		\
+	stw	r0,GPR11(r11);				\
+	mfspr	r8,exc_level##_SPRG
+
 	.globl	mcheck_transfer_to_handler
 mcheck_transfer_to_handler:
-	mtspr	MCHECK_SPRG,r8
-	BOOKE_LOAD_MCHECK_STACK
-	lwz	r0,GPR10-INT_FRAME_SIZE(r8)
-	stw	r0,GPR10(r11)
-	lwz	r0,GPR11-INT_FRAME_SIZE(r8)
-	stw	r0,GPR11(r11)
-	mfspr	r8,MCHECK_SPRG
+	TRANSFER_TO_HANDLER_EXC_LEVEL(MCHECK)
+	b	transfer_to_handler_full
+
+	.globl	debug_transfer_to_handler
+debug_transfer_to_handler:
+	TRANSFER_TO_HANDLER_EXC_LEVEL(DEBUG)
 	b	transfer_to_handler_full
 
 	.globl	crit_transfer_to_handler
 crit_transfer_to_handler:
-	mtspr	CRIT_SPRG,r8
-	BOOKE_LOAD_CRIT_STACK
-	lwz	r0,GPR10-INT_FRAME_SIZE(r8)
-	stw	r0,GPR10(r11)
-	lwz	r0,GPR11-INT_FRAME_SIZE(r8)
-	stw	r0,GPR11(r11)
-	mfspr	r8,CRIT_SPRG
+	TRANSFER_TO_HANDLER_EXC_LEVEL(CRIT)
 	/* fall through */
 #endif
 
@@ -202,7 +204,7 @@ _GLOBAL(DoSyscall)
 	rlwinm	r11,r11,0,~_TIFL_FORCE_NOERROR
 	stw	r11,TI_LOCAL_FLAGS(r10)
 	lwz	r11,TI_FLAGS(r10)
-	andi.	r11,r11,_TIF_SYSCALL_TRACE
+	andi.	r11,r11,_TIF_SYSCALL_T_OR_A
 	bne-	syscall_dotrace
 syscall_dotrace_cont:
 	cmplwi	0,r0,NR_syscalls
@@ -213,6 +215,7 @@ syscall_dotrace_cont:
 	lwzx	r10,r10,r0	/* Fetch system call handler [ptr] */
 	mtlr	r10
 	addi	r9,r1,STACK_FRAME_OVERHEAD
+	PPC440EP_ERR42
 	blrl			/* Call handler */
 	.globl	ret_from_syscall
 ret_from_syscall:
@@ -237,7 +240,7 @@ ret_from_syscall:
 	SYNC
 	MTMSRD(r10)
 	lwz	r9,TI_FLAGS(r12)
-	andi.	r0,r9,(_TIF_SYSCALL_TRACE|_TIF_SIGPENDING|_TIF_NEED_RESCHED)
+	andi.	r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SIGPENDING|_TIF_NEED_RESCHED)
 	bne-	syscall_exit_work
 syscall_exit_cont:
 #if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
@@ -277,7 +280,8 @@ syscall_dotrace:
 	SAVE_NVGPRS(r1)
 	li	r0,0xc00
 	stw	r0,TRAP(r1)
-	bl	do_syscall_trace
+	addi	r3,r1,STACK_FRAME_OVERHEAD
+	bl	do_syscall_trace_enter
 	lwz	r0,GPR0(r1)	/* Restore original registers */
 	lwz	r3,GPR3(r1)
 	lwz	r4,GPR4(r1)
@@ -291,7 +295,7 @@ syscall_dotrace:
 syscall_exit_work:
 	stw	r6,RESULT(r1)	/* Save result */
 	stw	r3,GPR3(r1)	/* Update return value */
-	andi.	r0,r9,_TIF_SYSCALL_TRACE
+	andi.	r0,r9,_TIF_SYSCALL_T_OR_A
 	beq	5f
 	ori	r10,r10,MSR_EE
 	SYNC
@@ -303,7 +307,8 @@ syscall_exit_work:
 	li	r4,0xc00
 	stw	r4,TRAP(r1)
 4:
-	bl	do_syscall_trace
+	addi	r3,r1,STACK_FRAME_OVERHEAD
+	bl	do_syscall_trace_leave
 	REST_NVGPRS(r1)
 2:
 	lwz	r3,GPR3(r1)
@@ -627,8 +632,8 @@ sigreturn_exit:
 	subi	r1,r3,STACK_FRAME_OVERHEAD
 	rlwinm	r12,r1,0,0,18	/* current_thread_info() */
 	lwz	r9,TI_FLAGS(r12)
-	andi.	r0,r9,_TIF_SYSCALL_TRACE
-	bnel-	do_syscall_trace
+	andi.	r0,r9,_TIF_SYSCALL_T_OR_A
+	bnel-	do_syscall_trace_leave
 	/* fall through */
 
 	.globl	ret_from_except_full
@@ -781,99 +786,68 @@ exc_exit_restart_end:
  * time of the critical interrupt.
  *
  */
-	.globl	ret_from_crit_exc
-ret_from_crit_exc:
-	REST_NVGPRS(r1)
-	lwz	r3,_MSR(r1)
-	andi.	r3,r3,MSR_PR
-	LOAD_MSR_KERNEL(r10,MSR_KERNEL)
-	bne	user_exc_return
-
-	lwz	r0,GPR0(r1)
-	lwz	r2,GPR2(r1)
-	REST_4GPRS(3, r1)
-	REST_2GPRS(7, r1)
-
-	lwz	r10,_XER(r1)
-	lwz	r11,_CTR(r1)
-	mtspr	SPRN_XER,r10
-	mtctr	r11
-
-	PPC405_ERR77(0,r1)
-	stwcx.	r0,0,r1			/* to clear the reservation */
-
-	lwz	r11,_LINK(r1)
-	mtlr	r11
-	lwz	r10,_CCR(r1)
-	mtcrf	0xff,r10
 #ifdef CONFIG_40x
-	/* avoid any possible TLB misses here by turning off MSR.DR, we
-	 * assume the instructions here are mapped by a pinned TLB entry */
-	li	r10,MSR_IR
-	mtmsr	r10
-	isync
-	tophys(r1, r1)
+#define PPC_40x_TURN_OFF_MSR_DR						    \
+	/* avoid any possible TLB misses here by turning off MSR.DR, we	    \
+	 * assume the instructions here are mapped by a pinned TLB entry */ \
+	li	r10,MSR_IR;						    \
+	mtmsr	r10;							    \
+	isync;								    \
+	tophys(r1, r1);
+#else
+#define PPC_40x_TURN_OFF_MSR_DR
 #endif
-	lwz	r9,_DEAR(r1)
-	lwz	r10,_ESR(r1)
-	mtspr	SPRN_DEAR,r9
-	mtspr	SPRN_ESR,r10
-	lwz	r11,_NIP(r1)
-	lwz	r12,_MSR(r1)
-	mtspr	SPRN_CSRR0,r11
-	mtspr	SPRN_CSRR1,r12
-	lwz	r9,GPR9(r1)
-	lwz	r12,GPR12(r1)
-	lwz	r10,GPR10(r1)
-	lwz	r11,GPR11(r1)
-	lwz	r1,GPR1(r1)
-	PPC405_ERR77_SYNC
-	rfci
-	b	.		/* prevent prefetch past rfci */
 
-#ifdef CONFIG_BOOKE
-/*
- * Return from a machine check interrupt, similar to a critical
- * interrupt.
- */
-	.globl	ret_from_mcheck_exc
-ret_from_mcheck_exc:
-	REST_NVGPRS(r1)
-	lwz	r3,_MSR(r1)
-	andi.	r3,r3,MSR_PR
-	LOAD_MSR_KERNEL(r10,MSR_KERNEL)
-	bne	user_exc_return
-
-	lwz	r0,GPR0(r1)
-	lwz	r2,GPR2(r1)
-	REST_4GPRS(3, r1)
-	REST_2GPRS(7, r1)
+#define RET_FROM_EXC_LEVEL(exc_lvl_srr0, exc_lvl_srr1, exc_lvl_rfi)	\
+	REST_NVGPRS(r1);						\
+	lwz	r3,_MSR(r1);						\
+	andi.	r3,r3,MSR_PR;						\
+	LOAD_MSR_KERNEL(r10,MSR_KERNEL);				\
+	bne	user_exc_return;					\
+	lwz	r0,GPR0(r1);						\
+	lwz	r2,GPR2(r1);						\
+	REST_4GPRS(3, r1);						\
+	REST_2GPRS(7, r1);						\
+	lwz	r10,_XER(r1);						\
+	lwz	r11,_CTR(r1);						\
+	mtspr	SPRN_XER,r10;						\
+	mtctr	r11;							\
+	PPC405_ERR77(0,r1);						\
+	stwcx.	r0,0,r1;		/* to clear the reservation */	\
+	lwz	r11,_LINK(r1);						\
+	mtlr	r11;							\
+	lwz	r10,_CCR(r1);						\
+	mtcrf	0xff,r10;						\
+	PPC_40x_TURN_OFF_MSR_DR;					\
+	lwz	r9,_DEAR(r1);						\
+	lwz	r10,_ESR(r1);						\
+	mtspr	SPRN_DEAR,r9;						\
+	mtspr	SPRN_ESR,r10;						\
+	lwz	r11,_NIP(r1);						\
+	lwz	r12,_MSR(r1);						\
+	mtspr	exc_lvl_srr0,r11;					\
+	mtspr	exc_lvl_srr1,r12;					\
+	lwz	r9,GPR9(r1);						\
+	lwz	r12,GPR12(r1);						\
+	lwz	r10,GPR10(r1);						\
+	lwz	r11,GPR11(r1);						\
+	lwz	r1,GPR1(r1);						\
+	PPC405_ERR77_SYNC;						\
+	exc_lvl_rfi;							\
+	b	.;		/* prevent prefetch past exc_lvl_rfi */
 
-	lwz	r10,_XER(r1)
-	lwz	r11,_CTR(r1)
-	mtspr	SPRN_XER,r10
-	mtctr	r11
+	.globl	ret_from_crit_exc
+ret_from_crit_exc:
+	RET_FROM_EXC_LEVEL(SPRN_CSRR0, SPRN_CSRR1, RFCI)
 
-	stwcx.	r0,0,r1			/* to clear the reservation */
+#ifdef CONFIG_BOOKE
+	.globl	ret_from_debug_exc
+ret_from_debug_exc:
+	RET_FROM_EXC_LEVEL(SPRN_DSRR0, SPRN_DSRR1, RFDI)
 
-	lwz	r11,_LINK(r1)
-	mtlr	r11
-	lwz	r10,_CCR(r1)
-	mtcrf	0xff,r10
-	lwz	r9,_DEAR(r1)
-	lwz	r10,_ESR(r1)
-	mtspr	SPRN_DEAR,r9
-	mtspr	SPRN_ESR,r10
-	lwz	r11,_NIP(r1)
-	lwz	r12,_MSR(r1)
-	mtspr	SPRN_MCSRR0,r11
-	mtspr	SPRN_MCSRR1,r12
-	lwz	r9,GPR9(r1)
-	lwz	r12,GPR12(r1)
-	lwz	r10,GPR10(r1)
-	lwz	r11,GPR11(r1)
-	lwz	r1,GPR1(r1)
-	RFMCI
+	.globl	ret_from_mcheck_exc
+ret_from_mcheck_exc:
+	RET_FROM_EXC_LEVEL(SPRN_MCSRR0, SPRN_MCSRR1, RFMCI)
 #endif /* CONFIG_BOOKE */
 
 /*
diff --git a/arch/ppc/kernel/head_44x.S b/arch/ppc/kernel/head_44x.S
--- a/arch/ppc/kernel/head_44x.S
+++ b/arch/ppc/kernel/head_44x.S
@@ -179,24 +179,26 @@ skpinv:	addi	r4,r4,1				/* Increment */
 4:
 #ifdef CONFIG_SERIAL_TEXT_DEBUG
 	/*
-	 * Add temporary UART mapping for early debug.  This
-	 * mapping must be identical to that used by the early
-	 * bootloader code since the same asm/serial.h parameters
-	 * are used for polled operation.
+	 * Add temporary UART mapping for early debug.
+	 * We can map UART registers wherever we want as long as they don't
+	 * interfere with other system mappings (e.g. with pinned entries).
+	 * For an example of how we handle this - see ocotea.h.       --ebs
 	 */
  	/* pageid fields */
 	lis	r3,UART0_IO_BASE@h
-	ori	r3,r3,PPC44x_TLB_VALID | PPC44x_TLB_256M
+	ori	r3,r3,PPC44x_TLB_VALID | PPC44x_TLB_4K
 
 	/* xlat fields */
 	lis	r4,UART0_PHYS_IO_BASE@h		/* RPN depends on SoC */
+#ifndef CONFIG_440EP
 	ori	r4,r4,0x0001		/* ERPN is 1 for second 4GB page */
+#endif
 
 	/* attrib fields */
 	li	r5,0
 	ori	r5,r5,(PPC44x_TLB_SW | PPC44x_TLB_SR | PPC44x_TLB_I | PPC44x_TLB_G)
 
-        li      r0,1                    /* TLB slot 1 */
+        li      r0,0                    /* TLB slot 0 */
 
 	tlbwe	r3,r0,PPC44x_TLB_PAGEID	/* Load the pageid fields */
 	tlbwe	r4,r0,PPC44x_TLB_XLAT	/* Load the translation fields */
@@ -228,6 +230,16 @@ skpinv:	addi	r4,r4,1				/* Increment */
 	lis	r4,interrupt_base@h	/* IVPR only uses the high 16-bits */
 	mtspr	SPRN_IVPR,r4
 
+#ifdef CONFIG_440EP
+	/* Clear DAPUIB flag in CCR0 (enable APU between CPU and FPU) */
+	mfspr	r2,SPRN_CCR0
+	lis	r3,0xffef
+	ori	r3,r3,0xffff
+	and	r2,r2,r3
+	mtspr	SPRN_CCR0,r2
+	isync
+#endif
+
 	/*
 	 * This is where the main kernel code starts.
 	 */
diff --git a/arch/ppc/kernel/head_4xx.S b/arch/ppc/kernel/head_4xx.S
--- a/arch/ppc/kernel/head_4xx.S
+++ b/arch/ppc/kernel/head_4xx.S
@@ -291,8 +291,9 @@ label:
 	/* If we are faulting a kernel address, we have to use the
 	 * kernel page tables.
 	 */
-	andis.	r11, r10, 0x8000
-	beq	3f
+	lis	r11, TASK_SIZE@h
+	cmplw	r10, r11
+	blt+	3f
 	lis	r11, swapper_pg_dir@h
 	ori	r11, r11, swapper_pg_dir@l
 	li	r9, 0
@@ -479,8 +480,9 @@ label:
 	/* If we are faulting a kernel address, we have to use the
 	 * kernel page tables.
 	 */
-	andis.	r11, r10, 0x8000
-	beq	3f
+	lis	r11, TASK_SIZE@h
+	cmplw	r10, r11
+	blt+	3f
 	lis	r11, swapper_pg_dir@h
 	ori	r11, r11, swapper_pg_dir@l
 	li	r9, 0
@@ -578,8 +580,9 @@ label:
 	/* If we are faulting a kernel address, we have to use the
 	 * kernel page tables.
 	 */
-	andis.	r11, r10, 0x8000
-	beq	3f
+	lis	r11, TASK_SIZE@h
+	cmplw	r10, r11
+	blt+	3f
 	lis	r11, swapper_pg_dir@h
 	ori	r11, r11, swapper_pg_dir@l
 	li	r9, 0
diff --git a/arch/ppc/kernel/head_8xx.S b/arch/ppc/kernel/head_8xx.S
--- a/arch/ppc/kernel/head_8xx.S
+++ b/arch/ppc/kernel/head_8xx.S
@@ -288,13 +288,11 @@ SystemCall:
  * For the MPC8xx, this is a software tablewalk to load the instruction
  * TLB.  It is modelled after the example in the Motorola manual.  The task
  * switch loads the M_TWB register with the pointer to the first level table.
- * If we discover there is no second level table (the value is zero), the
- * plan was to load that into the TLB, which causes another fault into the
- * TLB Error interrupt where we can handle such problems.  However, that did
- * not work, so if we discover there is no second level table, we restore
- * registers and branch to the error exception.  We have to use the MD_xxx
- * registers for the tablewalk because the equivalent MI_xxx registers
- * only perform the attribute functions.
+ * If we discover there is no second level table (value is zero) or if there
+ * is an invalid pte, we load that into the TLB, which causes another fault
+ * into the TLB Error interrupt where we can handle such problems.
+ * We have to use the MD_xxx registers for the tablewalk because the
+ * equivalent MI_xxx registers only perform the attribute functions.
  */
 InstructionTLBMiss:
 #ifdef CONFIG_8xx_CPU6
diff --git a/arch/ppc/kernel/head_booke.h b/arch/ppc/kernel/head_booke.h
--- a/arch/ppc/kernel/head_booke.h
+++ b/arch/ppc/kernel/head_booke.h
@@ -49,6 +49,7 @@
  *
  * On 40x critical is the only additional level
  * On 44x/e500 we have critical and machine check
+ * On e200 we have critical and debug (machine check occurs via critical)
  *
  * Additionally we reserve a SPRG for each priority level so we can free up a
  * GPR to use as the base for indirect access to the exception stacks.  This
@@ -60,53 +61,47 @@
 
 /* CRIT_SPRG only used in critical exception handling */
 #define CRIT_SPRG	SPRN_SPRG2
-/* MCHECK_SPRG only used in critical exception handling */
+/* MCHECK_SPRG only used in machine check exception handling */
 #define MCHECK_SPRG	SPRN_SPRG6W
 
 #define MCHECK_STACK_TOP	(exception_stack_top - 4096)
 #define CRIT_STACK_TOP		(exception_stack_top)
 
+/* only on e200 for now */
+#define DEBUG_STACK_TOP		(exception_stack_top - 4096)
+#define DEBUG_SPRG		SPRN_SPRG6W
+
 #ifdef CONFIG_SMP
-#define BOOKE_LOAD_CRIT_STACK				\
+#define BOOKE_LOAD_EXC_LEVEL_STACK(level)		\
 	mfspr	r8,SPRN_PIR;				\
 	mulli	r8,r8,BOOKE_EXCEPTION_STACK_SIZE;	\
 	neg	r8,r8;					\
-	addis	r8,r8,CRIT_STACK_TOP@ha;		\
-	addi	r8,r8,CRIT_STACK_TOP@l
-#define BOOKE_LOAD_MCHECK_STACK				\
-	mfspr	r8,SPRN_PIR;				\
-	mulli	r8,r8,BOOKE_EXCEPTION_STACK_SIZE;	\
-	neg	r8,r8;					\
-	addis	r8,r8,MCHECK_STACK_TOP@ha;		\
-	addi	r8,r8,MCHECK_STACK_TOP@l
+	addis	r8,r8,level##_STACK_TOP@ha;		\
+	addi	r8,r8,level##_STACK_TOP@l
 #else
-#define BOOKE_LOAD_CRIT_STACK				\
-	lis	r8,CRIT_STACK_TOP@h;			\
-	ori	r8,r8,CRIT_STACK_TOP@l
-#define BOOKE_LOAD_MCHECK_STACK				\
-	lis	r8,MCHECK_STACK_TOP@h;			\
-	ori	r8,r8,MCHECK_STACK_TOP@l
+#define BOOKE_LOAD_EXC_LEVEL_STACK(level)		\
+	lis	r8,level##_STACK_TOP@h;			\
+	ori	r8,r8,level##_STACK_TOP@l
 #endif
 
 /*
- * Exception prolog for critical exceptions.  This is a little different
- * from the normal exception prolog above since a critical exception
- * can potentially occur at any point during normal exception processing.
- * Thus we cannot use the same SPRG registers as the normal prolog above.
- * Instead we use a portion of the critical exception stack at low physical
- * addresses.
+ * Exception prolog for critical/machine check exceptions.  This is a
+ * little different from the normal exception prolog above since a
+ * critical/machine check exception can potentially occur at any point
+ * during normal exception processing. Thus we cannot use the same SPRG
+ * registers as the normal prolog above. Instead we use a portion of the
+ * critical/machine check exception stack at low physical addresses.
  */
-
-#define CRITICAL_EXCEPTION_PROLOG					     \
-	mtspr	CRIT_SPRG,r8;						     \
-	BOOKE_LOAD_CRIT_STACK;		/* r8 points to the crit stack */    \
+#define EXC_LEVEL_EXCEPTION_PROLOG(exc_level, exc_level_srr0, exc_level_srr1) \
+	mtspr	exc_level##_SPRG,r8;					     \
+	BOOKE_LOAD_EXC_LEVEL_STACK(exc_level);/* r8 points to the exc_level stack*/ \
 	stw	r10,GPR10-INT_FRAME_SIZE(r8);				     \
 	stw	r11,GPR11-INT_FRAME_SIZE(r8);				     \
 	mfcr	r10;			/* save CR in r10 for now	   */\
-	mfspr	r11,SPRN_CSRR1;		/* check whether user or kernel    */\
+	mfspr	r11,exc_level_srr1;	/* check whether user or kernel    */\
 	andi.	r11,r11,MSR_PR;						     \
 	mr	r11,r8;							     \
-	mfspr	r8,CRIT_SPRG;						     \
+	mfspr	r8,exc_level##_SPRG;					     \
 	beq	1f;							     \
 	/* COMING FROM USER MODE */					     \
 	mfspr	r11,SPRN_SPRG3;		/* if from user, start at top of   */\
@@ -122,9 +117,9 @@
 	stw	r12,_DEAR(r11);		/* since they may have had stuff   */\
 	mfspr	r9,SPRN_ESR;		/* in them at the point where the  */\
 	stw	r9,_ESR(r11);		/* exception was taken		   */\
-	mfspr	r12,SPRN_CSRR0;						     \
+	mfspr	r12,exc_level_srr0;					     \
 	stw	r1,GPR1(r11);						     \
-	mfspr	r9,SPRN_CSRR1;						     \
+	mfspr	r9,exc_level_srr1;					     \
 	stw	r1,0(r11);						     \
 	mr	r1,r11;							     \
 	rlwinm	r9,r9,0,14,12;		/* clear MSR_WE (necessary?)	   */\
@@ -132,45 +127,12 @@
 	SAVE_4GPRS(3, r11);						     \
 	SAVE_2GPRS(7, r11)
 
-/*
- * Exception prolog for machine check exceptions.  This is similar to
- * the critical exception prolog, except that machine check exceptions
- * have their stack.
- */
-#define MCHECK_EXCEPTION_PROLOG					     \
-	mtspr	MCHECK_SPRG,r8;						     \
-	BOOKE_LOAD_MCHECK_STACK;	/* r8 points to the mcheck stack   */\
-	stw	r10,GPR10-INT_FRAME_SIZE(r8);				     \
-	stw	r11,GPR11-INT_FRAME_SIZE(r8);				     \
-	mfcr	r10;			/* save CR in r10 for now	   */\
-	mfspr	r11,SPRN_MCSRR1;	/* check whether user or kernel    */\
-	andi.	r11,r11,MSR_PR;						     \
-	mr	r11,r8;							     \
-	mfspr	r8,MCHECK_SPRG;						     \
-	beq	1f;							     \
-	/* COMING FROM USER MODE */					     \
-	mfspr	r11,SPRN_SPRG3;		/* if from user, start at top of   */\
-	lwz	r11,THREAD_INFO-THREAD(r11); /* this thread's kernel stack */\
-	addi	r11,r11,THREAD_SIZE;					     \
-1:	subi	r11,r11,INT_FRAME_SIZE;	/* Allocate an exception frame     */\
-	stw	r10,_CCR(r11);          /* save various registers	   */\
-	stw	r12,GPR12(r11);						     \
-	stw	r9,GPR9(r11);						     \
-	mflr	r10;							     \
-	stw	r10,_LINK(r11);						     \
-	mfspr	r12,SPRN_DEAR;		/* save DEAR and ESR in the frame  */\
-	stw	r12,_DEAR(r11);		/* since they may have had stuff   */\
-	mfspr	r9,SPRN_ESR;		/* in them at the point where the  */\
-	stw	r9,_ESR(r11);		/* exception was taken		   */\
-	mfspr	r12,SPRN_MCSRR0;					     \
-	stw	r1,GPR1(r11);						     \
-	mfspr	r9,SPRN_MCSRR1;						     \
-	stw	r1,0(r11);						     \
-	mr	r1,r11;							     \
-	rlwinm	r9,r9,0,14,12;		/* clear MSR_WE (necessary?)	   */\
-	stw	r0,GPR0(r11);						     \
-	SAVE_4GPRS(3, r11);						     \
-	SAVE_2GPRS(7, r11)
+#define CRITICAL_EXCEPTION_PROLOG \
+		EXC_LEVEL_EXCEPTION_PROLOG(CRIT, SPRN_CSRR0, SPRN_CSRR1)
+#define DEBUG_EXCEPTION_PROLOG \
+		EXC_LEVEL_EXCEPTION_PROLOG(DEBUG, SPRN_DSRR0, SPRN_DSRR1)
+#define MCHECK_EXCEPTION_PROLOG \
+		EXC_LEVEL_EXCEPTION_PROLOG(MCHECK, SPRN_MCSRR0, SPRN_MCSRR1)
 
 /*
  * Exception vectors.
@@ -237,7 +199,6 @@ label:
 	EXC_XFER_TEMPLATE(hdlr, n+1, MSR_KERNEL, COPY_EE, transfer_to_handler, \
 			  ret_from_except)
 
-
 /* Check for a single step debug exception while in an exception
  * handler before state has been saved.  This is to catch the case
  * where an instruction that we are trying to single step causes
@@ -251,6 +212,60 @@ label:
  * save (and later restore) the MSR via SPRN_CSRR1, which will still have
  * the MSR_DE bit set.
  */
+#ifdef CONFIG_E200
+#define DEBUG_EXCEPTION							      \
+	START_EXCEPTION(Debug);						      \
+	DEBUG_EXCEPTION_PROLOG;						      \
+									      \
+	/*								      \
+	 * If there is a single step or branch-taken exception in an	      \
+	 * exception entry sequence, it was probably meant to apply to	      \
+	 * the code where the exception occurred (since exception entry	      \
+	 * doesn't turn off DE automatically).  We simulate the effect	      \
+	 * of turning off DE on entry to an exception handler by turning      \
+	 * off DE in the CSRR1 value and clearing the debug status.	      \
+	 */								      \
+	mfspr	r10,SPRN_DBSR;		/* check single-step/branch taken */  \
+	andis.	r10,r10,DBSR_IC@h;					      \
+	beq+	2f;							      \
+									      \
+	lis	r10,KERNELBASE@h;	/* check if exception in vectors */   \
+	ori	r10,r10,KERNELBASE@l;					      \
+	cmplw	r12,r10;						      \
+	blt+	2f;			/* addr below exception vectors */    \
+									      \
+	lis	r10,Debug@h;						      \
+	ori	r10,r10,Debug@l;					      \
+	cmplw	r12,r10;						      \
+	bgt+	2f;			/* addr above exception vectors */    \
+									      \
+	/* here it looks like we got an inappropriate debug exception. */     \
+1:	rlwinm	r9,r9,0,~MSR_DE;	/* clear DE in the CDRR1 value */     \
+	lis	r10,DBSR_IC@h;		/* clear the IC event */	      \
+	mtspr	SPRN_DBSR,r10;						      \
+	/* restore state and get out */					      \
+	lwz	r10,_CCR(r11);						      \
+	lwz	r0,GPR0(r11);						      \
+	lwz	r1,GPR1(r11);						      \
+	mtcrf	0x80,r10;						      \
+	mtspr	SPRN_DSRR0,r12;						      \
+	mtspr	SPRN_DSRR1,r9;						      \
+	lwz	r9,GPR9(r11);						      \
+	lwz	r12,GPR12(r11);						      \
+	mtspr	DEBUG_SPRG,r8;						      \
+	BOOKE_LOAD_EXC_LEVEL_STACK(DEBUG); /* r8 points to the debug stack */ \
+	lwz	r10,GPR10-INT_FRAME_SIZE(r8);				      \
+	lwz	r11,GPR11-INT_FRAME_SIZE(r8);				      \
+	mfspr	r8,DEBUG_SPRG;						      \
+									      \
+	RFDI;								      \
+	b	.;							      \
+									      \
+	/* continue normal handling for a critical exception... */	      \
+2:	mfspr	r4,SPRN_DBSR;						      \
+	addi	r3,r1,STACK_FRAME_OVERHEAD;				      \
+	EXC_XFER_TEMPLATE(DebugException, 0x2002, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), NOCOPY, debug_transfer_to_handler, ret_from_debug_exc)
+#else
 #define DEBUG_EXCEPTION							      \
 	START_EXCEPTION(Debug);						      \
 	CRITICAL_EXCEPTION_PROLOG;					      \
@@ -291,7 +306,7 @@ label:
 	lwz	r9,GPR9(r11);						      \
 	lwz	r12,GPR12(r11);						      \
 	mtspr	CRIT_SPRG,r8;						      \
-	BOOKE_LOAD_CRIT_STACK;		/* r8 points to the crit stack */     \
+	BOOKE_LOAD_EXC_LEVEL_STACK(CRIT); /* r8 points to the debug stack */  \
 	lwz	r10,GPR10-INT_FRAME_SIZE(r8);				      \
 	lwz	r11,GPR11-INT_FRAME_SIZE(r8);				      \
 	mfspr	r8,CRIT_SPRG;						      \
@@ -303,6 +318,7 @@ label:
 2:	mfspr	r4,SPRN_DBSR;						      \
 	addi	r3,r1,STACK_FRAME_OVERHEAD;				      \
 	EXC_XFER_TEMPLATE(DebugException, 0x2002, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), NOCOPY, crit_transfer_to_handler, ret_from_crit_exc)
+#endif
 
 #define INSTRUCTION_STORAGE_EXCEPTION					      \
 	START_EXCEPTION(InstructionStorage)				      \
diff --git a/arch/ppc/kernel/head_fsl_booke.S b/arch/ppc/kernel/head_fsl_booke.S
--- a/arch/ppc/kernel/head_fsl_booke.S
+++ b/arch/ppc/kernel/head_fsl_booke.S
@@ -102,6 +102,7 @@ invstr:	mflr	r6				/* Make it accessible
 	or	r7,r7,r4
 	mtspr	SPRN_MAS6,r7
 	tlbsx	0,r6				/* search MSR[IS], SPID=PID0 */
+#ifndef CONFIG_E200
 	mfspr	r7,SPRN_MAS1
 	andis.	r7,r7,MAS1_VALID@h
 	bne	match_TLB
@@ -118,6 +119,7 @@ invstr:	mflr	r6				/* Make it accessible
 	or	r7,r7,r4
 	mtspr	SPRN_MAS6,r7
 	tlbsx	0,r6				/* Fall through, we had to match */
+#endif
 match_TLB:
 	mfspr	r7,SPRN_MAS0
 	rlwinm	r3,r7,16,20,31			/* Extract MAS0(Entry) */
@@ -196,8 +198,10 @@ skpinv:	addi	r6,r6,1				/* Increment */
 /* 4. Clear out PIDs & Search info */
 	li	r6,0
 	mtspr	SPRN_PID0,r6
+#ifndef CONFIG_E200
 	mtspr	SPRN_PID1,r6
 	mtspr	SPRN_PID2,r6
+#endif
 	mtspr	SPRN_MAS6,r6
 
 /* 5. Invalidate mapping we started in */
@@ -277,7 +281,9 @@ skpinv:	addi	r6,r6,1				/* Increment */
 	SET_IVOR(32, SPEUnavailable);
 	SET_IVOR(33, SPEFloatingPointData);
 	SET_IVOR(34, SPEFloatingPointRound);
+#ifndef CONFIG_E200
 	SET_IVOR(35, PerformanceMonitor);
+#endif
 
 	/* Establish the interrupt vector base */
 	lis	r4,interrupt_base@h	/* IVPR only uses the high 16-bits */
@@ -285,6 +291,9 @@ skpinv:	addi	r6,r6,1				/* Increment */
 
 	/* Setup the defaults for TLB entries */
 	li	r2,(MAS4_TSIZED(BOOKE_PAGESZ_4K))@l
+#ifdef CONFIG_E200
+	oris	r2,r2,MAS4_TLBSELD(1)@h
+#endif
    	mtspr	SPRN_MAS4, r2
 
 #if 0
@@ -293,6 +302,12 @@ skpinv:	addi	r6,r6,1				/* Increment */
 	oris	r2,r2,HID0_DOZE@h
 	mtspr	SPRN_HID0, r2
 #endif
+#ifdef CONFIG_E200
+	/* enable dedicated debug exception handling resources (Debug APU) */
+	mfspr	r2,SPRN_HID0
+	ori 	r2,r2,HID0_DAPUEN@l
+	mtspr	SPRN_HID0,r2
+#endif
 
 #if !defined(CONFIG_BDI_SWITCH)
 	/*
@@ -414,7 +429,12 @@ interrupt_base:
 	CRITICAL_EXCEPTION(0x0100, CriticalInput, UnknownException)
 
 	/* Machine Check Interrupt */
+#ifdef CONFIG_E200
+	/* no RFMCI, MCSRRs on E200 */
+	CRITICAL_EXCEPTION(0x0200, MachineCheck, MachineCheckException)
+#else
 	MCHECK_EXCEPTION(0x0200, MachineCheck, MachineCheckException)
+#endif
 
 	/* Data Storage Interrupt */
 	START_EXCEPTION(DataStorage)
@@ -520,8 +540,13 @@ interrupt_base:
 #ifdef CONFIG_PPC_FPU
 	FP_UNAVAILABLE_EXCEPTION
 #else
+#ifdef CONFIG_E200
+	/* E200 treats 'normal' floating point instructions as FP Unavail exception */
+	EXCEPTION(0x0800, FloatingPointUnavailable, ProgramCheckException, EXC_XFER_EE)
+#else
 	EXCEPTION(0x0800, FloatingPointUnavailable, UnknownException, EXC_XFER_EE)
 #endif
+#endif
 
 	/* System Call Interrupt */
 	START_EXCEPTION(SystemCall)
@@ -691,6 +716,7 @@ interrupt_base:
 /*
  * Local functions
  */
+
 	/*
 	 * Data TLB exceptions will bail out to this point
 	 * if they can't resolve the lightweight TLB fault.
@@ -761,6 +787,31 @@ END_FTR_SECTION_IFSET(CPU_FTR_BIG_PHYS)
 2:	rlwimi	r11, r12, 0, 20, 31	/* Extract RPN from PTE and merge with perms */
 	mtspr	SPRN_MAS3, r11
 #endif
+#ifdef CONFIG_E200
+	/* Round robin TLB1 entries assignment */
+	mfspr	r12, SPRN_MAS0
+
+	/* Extract TLB1CFG(NENTRY) */
+	mfspr	r11, SPRN_TLB1CFG
+	andi.	r11, r11, 0xfff
+
+	/* Extract MAS0(NV) */
+	andi.	r13, r12, 0xfff
+	addi	r13, r13, 1
+	cmpw	0, r13, r11
+	addi	r12, r12, 1
+
+	/* check if we need to wrap */
+	blt	7f
+
+	/* wrap back to first free tlbcam entry */
+	lis	r13, tlbcam_index@ha
+	lwz	r13, tlbcam_index@l(r13)
+	rlwimi	r12, r13, 0, 20, 31
+7:
+	mtspr   SPRN_MAS0,r12
+#endif /* CONFIG_E200 */
+
 	tlbwe
 
 	/* Done...restore registers and get out of here.  */
diff --git a/arch/ppc/kernel/machine_kexec.c b/arch/ppc/kernel/machine_kexec.c
new file mode 100644
--- /dev/null
+++ b/arch/ppc/kernel/machine_kexec.c
@@ -0,0 +1,124 @@
+/*
+ * machine_kexec.c - handle transition of Linux booting another kernel
+ * Copyright (C) 2002-2003 Eric Biederman  <ebiederm@xmission.com>
+ *
+ * GameCube/ppc32 port Copyright (C) 2004 Albert Herranz
+ *
+ * This source code is licensed under the GNU General Public License,
+ * Version 2.  See the file COPYING for more details.
+ */
+
+#include <linux/mm.h>
+#include <linux/kexec.h>
+#include <linux/delay.h>
+#include <linux/reboot.h>
+#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
+#include <asm/mmu_context.h>
+#include <asm/io.h>
+#include <asm/hw_irq.h>
+#include <asm/cacheflush.h>
+#include <asm/machdep.h>
+
+typedef NORET_TYPE void (*relocate_new_kernel_t)(
+				unsigned long indirection_page,
+				unsigned long reboot_code_buffer,
+				unsigned long start_address) ATTRIB_NORET;
+
+const extern unsigned char relocate_new_kernel[];
+const extern unsigned int relocate_new_kernel_size;
+
+/*
+ * Provide a dummy crash_notes definition while crash dump arrives to ppc.
+ * This prevents breakage of crash_notes attribute in kernel/ksysfs.c.
+ */
+void *crash_notes = NULL;
+
+void machine_shutdown(void)
+{
+	if (ppc_md.machine_shutdown)
+		ppc_md.machine_shutdown();
+}
+
+void machine_crash_shutdown(struct pt_regs *regs)
+{
+	if (ppc_md.machine_crash_shutdown)
+		ppc_md.machine_crash_shutdown();
+}
+
+/*
+ * Do what every setup is needed on image and the
+ * reboot code buffer to allow us to avoid allocations
+ * later.
+ */
+int machine_kexec_prepare(struct kimage *image)
+{
+	if (ppc_md.machine_kexec_prepare)
+		return ppc_md.machine_kexec_prepare(image);
+	/*
+	 * Fail if platform doesn't provide its own machine_kexec_prepare
+	 * implementation.
+	 */
+	return -ENOSYS;
+}
+
+void machine_kexec_cleanup(struct kimage *image)
+{
+	if (ppc_md.machine_kexec_cleanup)
+		ppc_md.machine_kexec_cleanup(image);
+}
+
+/*
+ * Do not allocate memory (or fail in any way) in machine_kexec().
+ * We are past the point of no return, committed to rebooting now.
+ */
+NORET_TYPE void machine_kexec(struct kimage *image)
+{
+	if (ppc_md.machine_kexec)
+		ppc_md.machine_kexec(image);
+	else {
+		/*
+		 * Fall back to normal restart if platform doesn't provide
+		 * its own kexec function, and user insist to kexec...
+		 */
+		machine_restart(NULL);
+	}
+	for(;;);
+}
+
+/*
+ * This is a generic machine_kexec function suitable at least for
+ * non-OpenFirmware embedded platforms.
+ * It merely copies the image relocation code to the control page and
+ * jumps to it.
+ * A platform specific function may just call this one.
+ */
+void machine_kexec_simple(struct kimage *image)
+{
+	unsigned long page_list;
+	unsigned long reboot_code_buffer, reboot_code_buffer_phys;
+	relocate_new_kernel_t rnk;
+
+	/* Interrupts aren't acceptable while we reboot */
+	local_irq_disable();
+
+	page_list = image->head;
+
+	/* we need both effective and real address here */
+	reboot_code_buffer =
+			(unsigned long)page_address(image->control_code_page);
+	reboot_code_buffer_phys = virt_to_phys((void *)reboot_code_buffer);
+
+	/* copy our kernel relocation code to the control code page */
+	memcpy((void *)reboot_code_buffer, relocate_new_kernel,
+						relocate_new_kernel_size);
+
+	flush_icache_range(reboot_code_buffer,
+				reboot_code_buffer + KEXEC_CONTROL_CODE_SIZE);
+	printk(KERN_INFO "Bye!\n");
+
+	/* now call it */
+	rnk = (relocate_new_kernel_t) reboot_code_buffer;
+	(*rnk)(page_list, reboot_code_buffer_phys, image->start);
+}
+
diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S
--- a/arch/ppc/kernel/misc.S
+++ b/arch/ppc/kernel/misc.S
@@ -593,6 +593,14 @@ _GLOBAL(flush_instruction_cache)
 	iccci	0,r3
 #endif
 #elif CONFIG_FSL_BOOKE
+BEGIN_FTR_SECTION
+	mfspr   r3,SPRN_L1CSR0
+	ori     r3,r3,L1CSR0_CFI|L1CSR0_CLFC
+	/* msync; isync recommended here */
+	mtspr   SPRN_L1CSR0,r3
+	isync
+	blr
+END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE)
 	mfspr	r3,SPRN_L1CSR1
 	ori	r3,r3,L1CSR1_ICFI|L1CSR1_ICLFR
 	mtspr	SPRN_L1CSR1,r3
@@ -1137,6 +1145,7 @@ _GLOBAL(kernel_thread)
 	stwu	r0,-16(r1)
 	mtlr	r30		/* fn addr in lr */
 	mr	r3,r31		/* load arg and call fn */
+	PPC440EP_ERR42
 	blrl
 	li	r0,__NR_exit	/* exit if function returns */
 	li	r3,0
@@ -1436,8 +1445,13 @@ _GLOBAL(sys_call_table)
 	.long sys_mq_timedreceive	/* 265 */
 	.long sys_mq_notify
 	.long sys_mq_getsetattr
-	.long sys_ni_syscall		/* 268 reserved for sys_kexec_load */
+	.long sys_kexec_load
 	.long sys_add_key
 	.long sys_request_key		/* 270 */
 	.long sys_keyctl
 	.long sys_waitid
+	.long sys_ioprio_set
+	.long sys_ioprio_get
+	.long sys_inotify_init		/* 275 */
+	.long sys_inotify_add_watch
+	.long sys_inotify_rm_watch
diff --git a/arch/ppc/kernel/pci.c b/arch/ppc/kernel/pci.c
--- a/arch/ppc/kernel/pci.c
+++ b/arch/ppc/kernel/pci.c
@@ -160,6 +160,21 @@ void pcibios_resource_to_bus(struct pci_
 }
 EXPORT_SYMBOL(pcibios_resource_to_bus);
 
+void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
+			     struct pci_bus_region *region)
+{
+	unsigned long offset = 0;
+	struct pci_controller *hose = dev->sysdata;
+
+	if (hose && res->flags & IORESOURCE_IO)
+		offset = (unsigned long)hose->io_base_virt - isa_io_base;
+	else if (hose && res->flags & IORESOURCE_MEM)
+		offset = hose->pci_mem_offset;
+	res->start = region->start + offset;
+	res->end = region->end + offset;
+}
+EXPORT_SYMBOL(pcibios_bus_to_resource);
+
 /*
  * We need to avoid collisions with `mirrored' VGA ports
  * and other strange ISA hardware, so we always want the
@@ -1003,7 +1018,7 @@ pci_create_OF_bus_map(void)
 	}
 }
 
-static ssize_t pci_show_devspec(struct device *dev, char *buf)
+static ssize_t pci_show_devspec(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct pci_dev *pdev;
 	struct device_node *np;
@@ -1495,7 +1510,7 @@ static struct resource *__pci_mmap_make_
 		*offset += hose->pci_mem_offset;
 		res_bit = IORESOURCE_MEM;
 	} else {
-		io_offset = (unsigned long)hose->io_base_virt;
+		io_offset = hose->io_base_virt - ___IO_BASE;
 		*offset += io_offset;
 		res_bit = IORESOURCE_IO;
 	}
@@ -1522,7 +1537,7 @@ static struct resource *__pci_mmap_make_
 
 		/* found it! construct the final physical address */
 		if (mmap_state == pci_mmap_io)
-			*offset += hose->io_base_phys - _IO_BASE;
+			*offset += hose->io_base_phys - io_offset;
 		return rp;
 	}
 
@@ -1739,6 +1754,23 @@ long sys_pciconfig_iobase(long which, un
 	return result;
 }
 
+void pci_resource_to_user(const struct pci_dev *dev, int bar,
+			  const struct resource *rsrc,
+			  u64 *start, u64 *end)
+{
+	struct pci_controller *hose = pci_bus_to_hose(dev->bus->number);
+	unsigned long offset = 0;
+
+	if (hose == NULL)
+		return;
+
+	if (rsrc->flags & IORESOURCE_IO)
+		offset = ___IO_BASE - hose->io_base_virt + hose->io_base_phys;
+
+	*start = rsrc->start + offset;
+	*end = rsrc->end + offset;
+}
+
 void __init
 pci_init_resource(struct resource *res, unsigned long start, unsigned long end,
 		  int flags, char *name)
diff --git a/arch/ppc/kernel/perfmon.c b/arch/ppc/kernel/perfmon.c
--- a/arch/ppc/kernel/perfmon.c
+++ b/arch/ppc/kernel/perfmon.c
@@ -36,7 +36,7 @@
 /* A lock to regulate grabbing the interrupt */
 DEFINE_SPINLOCK(perfmon_lock);
 
-#ifdef CONFIG_FSL_BOOKE
+#if defined (CONFIG_FSL_BOOKE) && !defined (CONFIG_E200)
 static void dummy_perf(struct pt_regs *regs)
 {
 	unsigned int pmgc0 = mfpmr(PMRN_PMGC0);
diff --git a/arch/ppc/kernel/ppc_ksyms.c b/arch/ppc/kernel/ppc_ksyms.c
--- a/arch/ppc/kernel/ppc_ksyms.c
+++ b/arch/ppc/kernel/ppc_ksyms.c
@@ -55,7 +55,6 @@
 #define EXPORT_SYMTAB_STROPS
 
 extern void transfer_to_handler(void);
-extern void do_syscall_trace(void);
 extern void do_IRQ(struct pt_regs *regs);
 extern void MachineCheckException(struct pt_regs *regs);
 extern void AlignmentException(struct pt_regs *regs);
@@ -74,7 +73,6 @@ extern unsigned long mm_ptov (unsigned l
 EXPORT_SYMBOL(clear_pages);
 EXPORT_SYMBOL(clear_user_page);
 EXPORT_SYMBOL(do_signal);
-EXPORT_SYMBOL(do_syscall_trace);
 EXPORT_SYMBOL(transfer_to_handler);
 EXPORT_SYMBOL(do_IRQ);
 EXPORT_SYMBOL(MachineCheckException);
@@ -326,7 +324,7 @@ EXPORT_SYMBOL(__res);
 
 EXPORT_SYMBOL(next_mmu_context);
 EXPORT_SYMBOL(set_context);
-EXPORT_SYMBOL(handle_mm_fault); /* For MOL */
+EXPORT_SYMBOL_GPL(__handle_mm_fault); /* For MOL */
 EXPORT_SYMBOL(disarm_decr);
 #ifdef CONFIG_PPC_STD_MMU
 extern long mol_trampoline;
diff --git a/arch/ppc/kernel/ptrace.c b/arch/ppc/kernel/ptrace.c
--- a/arch/ppc/kernel/ptrace.c
+++ b/arch/ppc/kernel/ptrace.c
@@ -27,6 +27,9 @@
 #include <linux/user.h>
 #include <linux/security.h>
 #include <linux/signal.h>
+#include <linux/seccomp.h>
+#include <linux/audit.h>
+#include <linux/module.h>
 
 #include <asm/uaccess.h>
 #include <asm/page.h>
@@ -455,11 +458,10 @@ out:
 	return ret;
 }
 
-void do_syscall_trace(void)
+static void do_syscall_trace(void)
 {
-        if (!test_thread_flag(TIF_SYSCALL_TRACE)
-	    || !(current->ptrace & PT_PTRACED))
-		return;
+	/* the 0x80 provides a way for the tracing parent to distinguish
+	   between a syscall stop and SIGTRAP delivery */
 	ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
 				 ? 0x80 : 0));
 
@@ -473,3 +475,33 @@ void do_syscall_trace(void)
 		current->exit_code = 0;
 	}
 }
+
+void do_syscall_trace_enter(struct pt_regs *regs)
+{
+	if (test_thread_flag(TIF_SYSCALL_TRACE)
+	    && (current->ptrace & PT_PTRACED))
+		do_syscall_trace();
+
+	if (unlikely(current->audit_context))
+		audit_syscall_entry(current, AUDIT_ARCH_PPC,
+				    regs->gpr[0],
+				    regs->gpr[3], regs->gpr[4],
+				    regs->gpr[5], regs->gpr[6]);
+}
+
+void do_syscall_trace_leave(struct pt_regs *regs)
+{
+	secure_computing(regs->gpr[0]);
+
+	if (unlikely(current->audit_context))
+		audit_syscall_exit(current,
+				   (regs->ccr&0x1000)?AUDITSC_FAILURE:AUDITSC_SUCCESS,
+				   regs->result);
+
+	if ((test_thread_flag(TIF_SYSCALL_TRACE))
+	    && (current->ptrace & PT_PTRACED))
+		do_syscall_trace();
+}
+
+EXPORT_SYMBOL(do_syscall_trace_enter);
+EXPORT_SYMBOL(do_syscall_trace_leave);
diff --git a/arch/ppc/kernel/relocate_kernel.S b/arch/ppc/kernel/relocate_kernel.S
new file mode 100644
--- /dev/null
+++ b/arch/ppc/kernel/relocate_kernel.S
@@ -0,0 +1,123 @@
+/*
+ * relocate_kernel.S - put the kernel image in place to boot
+ * Copyright (C) 2002-2003 Eric Biederman  <ebiederm@xmission.com>
+ *
+ * GameCube/ppc32 port Copyright (C) 2004 Albert Herranz
+ *
+ * This source code is licensed under the GNU General Public License,
+ * Version 2.  See the file COPYING for more details.
+ */
+
+#include <asm/reg.h>
+#include <asm/ppc_asm.h>
+#include <asm/processor.h>
+
+#include <asm/kexec.h>
+
+#define PAGE_SIZE      4096 /* must be same value as in <asm/page.h> */
+
+	/*
+	 * Must be relocatable PIC code callable as a C function.
+	 */
+	.globl relocate_new_kernel
+relocate_new_kernel:
+	/* r3 = page_list   */
+	/* r4 = reboot_code_buffer */
+	/* r5 = start_address      */
+
+	li	r0, 0
+
+	/*
+	 * Set Machine Status Register to a known status,
+	 * switch the MMU off and jump to 1: in a single step.
+	 */
+
+	mr	r8, r0
+	ori     r8, r8, MSR_RI|MSR_ME
+	mtspr	SPRN_SRR1, r8
+	addi	r8, r4, 1f - relocate_new_kernel
+	mtspr	SPRN_SRR0, r8
+	sync
+	rfi
+
+1:
+	/* from this point address translation is turned off */
+	/* and interrupts are disabled */
+
+	/* set a new stack at the bottom of our page... */
+	/* (not really needed now) */
+	addi	r1, r4, KEXEC_CONTROL_CODE_SIZE - 8 /* for LR Save+Back Chain */
+	stw	r0, 0(r1)
+
+	/* Do the copies */
+	li	r6, 0 /* checksum */
+	mr	r0, r3
+	b	1f
+
+0:	/* top, read another word for the indirection page */
+	lwzu	r0, 4(r3)
+
+1:
+	/* is it a destination page? (r8) */
+	rlwinm.	r7, r0, 0, 31, 31 /* IND_DESTINATION (1<<0) */
+	beq	2f
+
+	rlwinm	r8, r0, 0, 0, 19 /* clear kexec flags, page align */
+	b	0b
+
+2:	/* is it an indirection page? (r3) */
+	rlwinm.	r7, r0, 0, 30, 30 /* IND_INDIRECTION (1<<1) */
+	beq	2f
+
+	rlwinm	r3, r0, 0, 0, 19 /* clear kexec flags, page align */
+	subi	r3, r3, 4
+	b	0b
+
+2:	/* are we done? */
+	rlwinm.	r7, r0, 0, 29, 29 /* IND_DONE (1<<2) */
+	beq	2f
+	b	3f
+
+2:	/* is it a source page? (r9) */
+	rlwinm.	r7, r0, 0, 28, 28 /* IND_SOURCE (1<<3) */
+	beq	0b
+
+	rlwinm	r9, r0, 0, 0, 19 /* clear kexec flags, page align */
+
+	li	r7, PAGE_SIZE / 4
+	mtctr   r7
+	subi    r9, r9, 4
+	subi    r8, r8, 4
+9:
+	lwzu    r0, 4(r9)  /* do the copy */
+	xor	r6, r6, r0
+	stwu    r0, 4(r8)
+	dcbst	0, r8
+	sync
+	icbi	0, r8
+	bdnz    9b
+
+	addi    r9, r9, 4
+	addi    r8, r8, 4
+	b	0b
+
+3:
+
+	/* To be certain of avoiding problems with self-modifying code
+	 * execute a serializing instruction here.
+	 */
+	isync
+	sync
+
+	/* jump to the entry point, usually the setup routine */
+	mtlr	r5
+	blrl
+
+1:	b	1b
+
+relocate_new_kernel_end:
+
+	.globl relocate_new_kernel_size
+relocate_new_kernel_size:
+	.long relocate_new_kernel_end - relocate_new_kernel
+
diff --git a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c
--- a/arch/ppc/kernel/setup.c
+++ b/arch/ppc/kernel/setup.c
@@ -41,7 +41,7 @@
 #include <asm/xmon.h>
 #include <asm/ocp.h>
 
-#if defined(CONFIG_85xx) || defined(CONFIG_83xx)
+#if defined(CONFIG_85xx) || defined(CONFIG_83xx) || defined(CONFIG_MPC10X_BRIDGE)
 #include <asm/ppc_sys.h>
 #endif
 
@@ -61,8 +61,6 @@ extern void power4_idle(void);
 
 extern boot_infos_t *boot_infos;
 struct ide_machdep_calls ppc_ide_md;
-char *sysmap;
-unsigned long sysmap_size;
 
 /* Used with the BI_MEMSIZE bootinfo parameter to store the memory
    size value reported by the boot loader. */
@@ -123,8 +121,6 @@ void machine_restart(char *cmd)
 	ppc_md.restart(cmd);
 }
 
-EXPORT_SYMBOL(machine_restart);
-
 void machine_power_off(void)
 {
 #ifdef CONFIG_NVRAM
@@ -133,8 +129,6 @@ void machine_power_off(void)
 	ppc_md.power_off();
 }
 
-EXPORT_SYMBOL(machine_power_off);
-
 void machine_halt(void)
 {
 #ifdef CONFIG_NVRAM
@@ -143,8 +137,6 @@ void machine_halt(void)
 	ppc_md.halt();
 }
 
-EXPORT_SYMBOL(machine_halt);
-
 void (*pm_power_off)(void) = machine_power_off;
 
 #ifdef CONFIG_TAU
@@ -249,7 +241,7 @@ int show_cpuinfo(struct seq_file *m, voi
 	seq_printf(m, "bogomips\t: %lu.%02lu\n",
 		   lpj / (500000/HZ), (lpj / (5000/HZ)) % 100);
 
-#if defined(CONFIG_85xx) || defined(CONFIG_83xx)
+#if defined(CONFIG_85xx) || defined(CONFIG_83xx) || defined(CONFIG_MPC10X_BRIDGE)
 	if (cur_ppc_sys_spec->ppc_sys_name)
 		seq_printf(m, "chipset\t\t: %s\n",
 			cur_ppc_sys_spec->ppc_sys_name);
@@ -578,11 +570,6 @@ void parse_bootinfo(struct bi_record *re
 		case BI_CMD_LINE:
 			strlcpy(cmd_line, (void *)data, sizeof(cmd_line));
 			break;
-		case BI_SYSMAP:
-			sysmap = (char *)((data[0] >= (KERNELBASE)) ? data[0] :
-					  (data[0]+KERNELBASE));
-			sysmap_size = data[1];
-			break;
 #ifdef CONFIG_BLK_DEV_INITRD
 		case BI_INITRD:
 			initrd_start = data[0] + KERNELBASE;
diff --git a/arch/ppc/kernel/signal.c b/arch/ppc/kernel/signal.c
--- a/arch/ppc/kernel/signal.c
+++ b/arch/ppc/kernel/signal.c
@@ -705,8 +705,7 @@ int do_signal(sigset_t *oldset, struct p
 	unsigned long frame, newsp;
 	int signr, ret;
 
-	if (current->flags & PF_FREEZE) {
-		refrigerator(PF_FREEZE);
+	if (try_to_freeze()) {
 		signr = 0;
 		if (!signal_pending(current))
 			goto no_signal;
diff --git a/arch/ppc/kernel/time.c b/arch/ppc/kernel/time.c
--- a/arch/ppc/kernel/time.c
+++ b/arch/ppc/kernel/time.c
@@ -89,6 +89,9 @@ unsigned long tb_to_ns_scale;
 
 extern unsigned long wall_jiffies;
 
+/* used for timezone offset */
+static long timezone_offset;
+
 DEFINE_SPINLOCK(rtc_lock);
 
 EXPORT_SYMBOL(rtc_lock);
@@ -170,7 +173,7 @@ void timer_interrupt(struct pt_regs * re
 		     xtime.tv_sec - last_rtc_update >= 659 &&
 		     abs((xtime.tv_nsec / 1000) - (1000000-1000000/HZ)) < 500000/HZ &&
 		     jiffies - wall_jiffies == 1) {
-		  	if (ppc_md.set_rtc_time(xtime.tv_sec+1 + time_offset) == 0)
+		  	if (ppc_md.set_rtc_time(xtime.tv_sec+1 + timezone_offset) == 0)
 				last_rtc_update = xtime.tv_sec+1;
 			else
 				/* Try again one minute later */
@@ -286,7 +289,7 @@ void __init time_init(void)
 	unsigned old_stamp, stamp, elapsed;
 
         if (ppc_md.time_init != NULL)
-                time_offset = ppc_md.time_init();
+                timezone_offset = ppc_md.time_init();
 
 	if (__USE_RTC()) {
 		/* 601 processor: dec counts down by 128 every 128ns */
@@ -331,10 +334,10 @@ void __init time_init(void)
 	set_dec(tb_ticks_per_jiffy);
 
 	/* If platform provided a timezone (pmac), we correct the time */
-        if (time_offset) {
-		sys_tz.tz_minuteswest = -time_offset / 60;
+        if (timezone_offset) {
+		sys_tz.tz_minuteswest = -timezone_offset / 60;
 		sys_tz.tz_dsttime = 0;
-		xtime.tv_sec -= time_offset;
+		xtime.tv_sec -= timezone_offset;
         }
         set_normalized_timespec(&wall_to_monotonic,
                                 -xtime.tv_sec, -xtime.tv_nsec);
diff --git a/arch/ppc/kernel/traps.c b/arch/ppc/kernel/traps.c
--- a/arch/ppc/kernel/traps.c
+++ b/arch/ppc/kernel/traps.c
@@ -81,8 +81,10 @@ void die(const char * str, struct pt_reg
 	console_verbose();
 	spin_lock_irq(&die_lock);
 #ifdef CONFIG_PMAC_BACKLIGHT
-	set_backlight_enable(1);
-	set_backlight_level(BACKLIGHT_MAX);
+	if (_machine == _MACH_Pmac) {
+		set_backlight_enable(1);
+		set_backlight_level(BACKLIGHT_MAX);
+	}
 #endif
 	printk("Oops: %s, sig: %ld [#%d]\n", str, err, ++die_counter);
 #ifdef CONFIG_PREEMPT
@@ -171,13 +173,13 @@ static inline int check_io_access(struct
 /* On 4xx, the reason for the machine check or program exception
    is in the ESR. */
 #define get_reason(regs)	((regs)->dsisr)
-#ifndef CONFIG_E500
+#ifndef CONFIG_FSL_BOOKE
 #define get_mc_reason(regs)	((regs)->dsisr)
 #else
 #define get_mc_reason(regs)	(mfspr(SPRN_MCSR))
 #endif
 #define REASON_FP		ESR_FP
-#define REASON_ILLEGAL		ESR_PIL
+#define REASON_ILLEGAL		(ESR_PIL | ESR_PUO)
 #define REASON_PRIVILEGED	ESR_PPR
 #define REASON_TRAP		ESR_PTR
 
@@ -300,7 +302,25 @@ void MachineCheckException(struct pt_reg
 		printk("Bus - Instruction Parity Error\n");
 	if (reason & MCSR_BUS_RPERR)
 		printk("Bus - Read Parity Error\n");
-#else /* !CONFIG_4xx && !CONFIG_E500 */
+#elif defined (CONFIG_E200)
+	printk("Machine check in kernel mode.\n");
+	printk("Caused by (from MCSR=%lx): ", reason);
+
+	if (reason & MCSR_MCP)
+		printk("Machine Check Signal\n");
+	if (reason & MCSR_CP_PERR)
+		printk("Cache Push Parity Error\n");
+	if (reason & MCSR_CPERR)
+		printk("Cache Parity Error\n");
+	if (reason & MCSR_EXCP_ERR)
+		printk("ISI, ITLB, or Bus Error on first instruction fetch for an exception handler\n");
+	if (reason & MCSR_BUS_IRERR)
+		printk("Bus - Read Bus Error on instruction fetch\n");
+	if (reason & MCSR_BUS_DRERR)
+		printk("Bus - Read Bus Error on data load\n");
+	if (reason & MCSR_BUS_WRERR)
+		printk("Bus - Write Bus Error on buffered store or cache line push\n");
+#else /* !CONFIG_4xx && !CONFIG_E500 && !CONFIG_E200 */
 	printk("Machine check in kernel mode.\n");
 	printk("Caused by (from SRR1=%lx): ", reason);
 	switch (reason & 0x601F0000) {
diff --git a/arch/ppc/lib/locks.c b/arch/ppc/lib/locks.c
--- a/arch/ppc/lib/locks.c
+++ b/arch/ppc/lib/locks.c
@@ -130,7 +130,7 @@ void _raw_read_lock(rwlock_t *rw)
 		while (!read_can_lock(rw)) {
 			if (--stuck == 0) {
 				printk("_read_lock(%p) CPU#%d lock %d\n",
-				       rw, _smp_processor_id(), rw->lock);
+				       rw, raw_smp_processor_id(), rw->lock);
 				stuck = INIT_STUCK;
 			}
 		}
@@ -158,7 +158,7 @@ void _raw_write_lock(rwlock_t *rw)
 		while (!write_can_lock(rw)) {
 			if (--stuck == 0) {
 				printk("write_lock(%p) CPU#%d lock %d)\n",
-				       rw, _smp_processor_id(), rw->lock);
+				       rw, raw_smp_processor_id(), rw->lock);
 				stuck = INIT_STUCK;
 			}
 		}
diff --git a/arch/ppc/mm/44x_mmu.c b/arch/ppc/mm/44x_mmu.c
--- a/arch/ppc/mm/44x_mmu.c
+++ b/arch/ppc/mm/44x_mmu.c
@@ -39,7 +39,6 @@
 #include <linux/vmalloc.h>
 #include <linux/init.h>
 #include <linux/delay.h>
-#include <linux/bootmem.h>
 #include <linux/highmem.h>
 
 #include <asm/pgalloc.h>
diff --git a/arch/ppc/mm/4xx_mmu.c b/arch/ppc/mm/4xx_mmu.c
--- a/arch/ppc/mm/4xx_mmu.c
+++ b/arch/ppc/mm/4xx_mmu.c
@@ -36,7 +36,6 @@
 #include <linux/vmalloc.h>
 #include <linux/init.h>
 #include <linux/delay.h>
-#include <linux/bootmem.h>
 #include <linux/highmem.h>
 
 #include <asm/pgalloc.h>
diff --git a/arch/ppc/mm/fsl_booke_mmu.c b/arch/ppc/mm/fsl_booke_mmu.c
--- a/arch/ppc/mm/fsl_booke_mmu.c
+++ b/arch/ppc/mm/fsl_booke_mmu.c
@@ -41,7 +41,6 @@
 #include <linux/vmalloc.h>
 #include <linux/init.h>
 #include <linux/delay.h>
-#include <linux/bootmem.h>
 #include <linux/highmem.h>
 
 #include <asm/pgalloc.h>
@@ -64,6 +63,8 @@ extern unsigned long total_lowmem;
 extern unsigned long __max_low_memory;
 #define MAX_LOW_MEM	CONFIG_LOWMEM_SIZE
 
+#define NUM_TLBCAMS	(16)
+
 struct tlbcam {
    	u32	MAS0;
 	u32	MAS1;
@@ -124,7 +125,7 @@ void settlbcam(int index, unsigned long 
 		flags |= _PAGE_COHERENT;
 #endif
 
-	TLBCAM[index].MAS0 = MAS0_TLBSEL(1) | MAS0_ESEL(index);
+	TLBCAM[index].MAS0 = MAS0_TLBSEL(1) | MAS0_ESEL(index) | MAS0_NV(index+1);
 	TLBCAM[index].MAS1 = MAS1_VALID | MAS1_IPROT | MAS1_TSIZE(tsize) | MAS1_TID(pid);
 	TLBCAM[index].MAS2 = virt & PAGE_MASK;
 
diff --git a/arch/ppc/mm/init.c b/arch/ppc/mm/init.c
--- a/arch/ppc/mm/init.c
+++ b/arch/ppc/mm/init.c
@@ -96,9 +96,6 @@ extern struct task_struct *current_set[N
 char *klimit = _end;
 struct mem_pieces phys_avail;
 
-extern char *sysmap;
-extern unsigned long sysmap_size;
-
 /*
  * this tells the system to map all of ram with the segregs
  * (i.e. page tables) instead of the bats.
@@ -442,12 +439,6 @@ void __init mem_init(void)
 	if (agp_special_page)
 		SetPageReserved(virt_to_page(agp_special_page));
 #endif
-	if ( sysmap )
-		for (addr = (unsigned long)sysmap;
-		     addr < PAGE_ALIGN((unsigned long)sysmap+sysmap_size) ;
-		     addr += PAGE_SIZE)
-			SetPageReserved(virt_to_page(addr));
-
 	for (addr = PAGE_OFFSET; addr < (unsigned long)high_memory;
 	     addr += PAGE_SIZE) {
 		if (!PageReserved(virt_to_page(addr)))
@@ -469,7 +460,6 @@ void __init mem_init(void)
 			struct page *page = mem_map + pfn;
 
 			ClearPageReserved(page);
-			set_bit(PG_highmem, &page->flags);
 			set_page_count(page, 1);
 			__free_page(page);
 			totalhigh_pages++;
@@ -483,9 +473,7 @@ void __init mem_init(void)
 	       codepages<< (PAGE_SHIFT-10), datapages<< (PAGE_SHIFT-10),
 	       initpages<< (PAGE_SHIFT-10),
 	       (unsigned long) (totalhigh_pages << (PAGE_SHIFT-10)));
-	if (sysmap)
-		printk("System.map loaded at 0x%08x for debugger, size: %ld bytes\n",
-			(unsigned int)sysmap, sysmap_size);
+
 #ifdef CONFIG_PPC_PMAC
 	if (agp_special_page)
 		printk(KERN_INFO "AGP special page: 0x%08lx\n", agp_special_page);
@@ -535,9 +523,6 @@ set_phys_avail(unsigned long total_memor
 	if (rtas_data)
 		mem_pieces_remove(&phys_avail, rtas_data, rtas_size, 1);
 #endif
-	/* remove the sysmap pages from the available memory */
-	if (sysmap)
-		mem_pieces_remove(&phys_avail, __pa(sysmap), sysmap_size, 1);
 #ifdef CONFIG_PPC_PMAC
 	/* Because of some uninorth weirdness, we need a page of
 	 * memory as high as possible (it must be outside of the
@@ -577,6 +562,9 @@ void flush_dcache_icache_page(struct pag
 #ifdef CONFIG_BOOKE
 	__flush_dcache_icache(kmap(page));
 	kunmap(page);
+#elif CONFIG_8xx
+	/* On 8xx there is no need to kmap since highmem is not supported */
+	__flush_dcache_icache(page_address(page)); 
 #else
 	__flush_dcache_icache_phys(page_to_pfn(page) << PAGE_SHIFT);
 #endif
@@ -621,9 +609,19 @@ void update_mmu_cache(struct vm_area_str
 		struct page *page = pfn_to_page(pfn);
 		if (!PageReserved(page)
 		    && !test_bit(PG_arch_1, &page->flags)) {
-			if (vma->vm_mm == current->active_mm)
+			if (vma->vm_mm == current->active_mm) {
+#ifdef CONFIG_8xx
+			/* On 8xx, cache control instructions (particularly 
+		 	 * "dcbst" from flush_dcache_icache) fault as write 
+			 * operation if there is an unpopulated TLB entry 
+			 * for the address in question. To workaround that, 
+			 * we invalidate the TLB here, thus avoiding dcbst 
+			 * misbehaviour.
+			 */
+				_tlbie(address);
+#endif
 				__flush_dcache_icache((void *) address);
-			else
+			} else
 				flush_dcache_icache_page(page);
 			set_bit(PG_arch_1, &page->flags);
 		}
diff --git a/arch/ppc/mm/mmu_decl.h b/arch/ppc/mm/mmu_decl.h
--- a/arch/ppc/mm/mmu_decl.h
+++ b/arch/ppc/mm/mmu_decl.h
@@ -43,6 +43,8 @@ extern int mem_init_done;
 extern PTE *Hash, *Hash_end;
 extern unsigned long Hash_size, Hash_mask;
 
+extern unsigned int num_tlbcam_entries;
+
 /* ...and now those things that may be slightly different between processor
  * architectures.  -- Dan
  */
diff --git a/arch/ppc/mm/pgtable.c b/arch/ppc/mm/pgtable.c
--- a/arch/ppc/mm/pgtable.c
+++ b/arch/ppc/mm/pgtable.c
@@ -66,7 +66,6 @@ void setbat(int index, unsigned long vir
 
 #ifdef HAVE_TLBCAM
 extern unsigned int tlbcam_index;
-extern unsigned int num_tlbcam_entries;
 extern unsigned long v_mapped_by_tlbcam(unsigned long va);
 extern unsigned long p_mapped_by_tlbcam(unsigned long pa);
 #else /* !HAVE_TLBCAM */
diff --git a/arch/ppc/platforms/4xx/Kconfig b/arch/ppc/platforms/4xx/Kconfig
--- a/arch/ppc/platforms/4xx/Kconfig
+++ b/arch/ppc/platforms/4xx/Kconfig
@@ -3,6 +3,11 @@ config 4xx
 	depends on 40x || 44x
 	default y
 
+config WANT_EARLY_SERIAL
+	bool
+	select SERIAL_8250
+	default n
+
 menu "IBM 4xx options"
 	depends on 4xx
 
@@ -18,6 +23,7 @@ config ASH
 
 config BUBINGA
 	bool "Bubinga"
+	select WANT_EARLY_SERIAL
 	help
 	  This option enables support for the IBM 405EP evaluation board.
 
@@ -68,18 +74,27 @@ choice
 	depends on 44x
 	default EBONY
 
+config BAMBOO
+	bool "Bamboo"
+	select WANT_EARLY_SERIAL
+	help
+	  This option enables support for the IBM PPC440EP evaluation board.
+
 config EBONY
 	bool "Ebony"
+	select WANT_EARLY_SERIAL
 	help
 	  This option enables support for the IBM PPC440GP evaluation board.
 
 config LUAN
 	bool "Luan"
+	select WANT_EARLY_SERIAL
 	help
 	  This option enables support for the IBM PPC440SP evaluation board.
 
 config OCOTEA
 	bool "Ocotea"
+	select WANT_EARLY_SERIAL
 	help
 	  This option enables support for the IBM PPC440GX evaluation board.
 
@@ -98,6 +113,12 @@ config NP405H
 	depends on ASH
 	default y
 
+config 440EP
+	bool
+	depends on BAMBOO
+	select PPC_FPU
+	default y
+
 config 440GP
 	bool
 	depends on EBONY
@@ -115,7 +136,7 @@ config 440SP
 
 config 440
 	bool
-	depends on 440GP || 440SP
+	depends on 440GP || 440SP || 440EP
 	default y
 
 config 440A
@@ -123,6 +144,11 @@ config 440A
 	depends on 440GX
 	default y
 
+config IBM440EP_ERR42
+	bool
+	depends on 440EP
+	default y
+
 # All 405-based cores up until the 405GPR and 405EP have this errata.
 config IBM405_ERR77
 	bool
@@ -142,7 +168,7 @@ config BOOKE
 
 config IBM_OCP
 	bool
-	depends on ASH || BUBINGA || CPCI405 || EBONY || EP405 || LUAN || OCOTEA || REDWOOD_5 || REDWOOD_6 || SYCAMORE || WALNUT
+	depends on ASH || BAMBOO || BUBINGA || CPCI405 || EBONY || EP405 || LUAN || OCOTEA || REDWOOD_5 || REDWOOD_6 || SYCAMORE || WALNUT
 	default y
 
 config XILINX_OCP
@@ -214,10 +240,6 @@ config PPC_GEN550
 	depends on 4xx
 	default y
 
-config PM
-	bool "Power Management support (EXPERIMENTAL)"
-	depends on 4xx && EXPERIMENTAL
-
 choice
 	prompt "TTYS0 device and default console"
 	depends on 40x
diff --git a/arch/ppc/platforms/4xx/Makefile b/arch/ppc/platforms/4xx/Makefile
--- a/arch/ppc/platforms/4xx/Makefile
+++ b/arch/ppc/platforms/4xx/Makefile
@@ -2,6 +2,7 @@
 # Makefile for the PowerPC 4xx linux kernel.
 
 obj-$(CONFIG_ASH)		+= ash.o
+obj-$(CONFIG_BAMBOO)		+= bamboo.o
 obj-$(CONFIG_CPCI405)		+= cpci405.o
 obj-$(CONFIG_EBONY)		+= ebony.o
 obj-$(CONFIG_EP405)		+= ep405.o
@@ -19,6 +20,7 @@ obj-$(CONFIG_405GP)		+= ibm405gp.o
 obj-$(CONFIG_REDWOOD_5)		+= ibmstb4.o
 obj-$(CONFIG_NP405H)		+= ibmnp405h.o
 obj-$(CONFIG_REDWOOD_6)		+= ibmstbx25.o
+obj-$(CONFIG_440EP)		+= ibm440ep.o
 obj-$(CONFIG_440GP)		+= ibm440gp.o
 obj-$(CONFIG_440GX)		+= ibm440gx.o
 obj-$(CONFIG_440SP)		+= ibm440sp.o
diff --git a/arch/ppc/platforms/4xx/bamboo.c b/arch/ppc/platforms/4xx/bamboo.c
new file mode 100644
--- /dev/null
+++ b/arch/ppc/platforms/4xx/bamboo.c
@@ -0,0 +1,427 @@
+/*
+ * arch/ppc/platforms/4xx/bamboo.c
+ *
+ * Bamboo board specific routines
+ *
+ * Wade Farnsworth <wfarnsworth@mvista.com>
+ * Copyright 2004 MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/config.h>
+#include <linux/stddef.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/reboot.h>
+#include <linux/pci.h>
+#include <linux/kdev_t.h>
+#include <linux/types.h>
+#include <linux/major.h>
+#include <linux/blkdev.h>
+#include <linux/console.h>
+#include <linux/delay.h>
+#include <linux/ide.h>
+#include <linux/initrd.h>
+#include <linux/irq.h>
+#include <linux/seq_file.h>
+#include <linux/root_dev.h>
+#include <linux/tty.h>
+#include <linux/serial.h>
+#include <linux/serial_core.h>
+#include <linux/ethtool.h>
+
+#include <asm/system.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/dma.h>
+#include <asm/io.h>
+#include <asm/machdep.h>
+#include <asm/ocp.h>
+#include <asm/pci-bridge.h>
+#include <asm/time.h>
+#include <asm/todc.h>
+#include <asm/bootinfo.h>
+#include <asm/ppc4xx_pic.h>
+#include <asm/ppcboot.h>
+
+#include <syslib/gen550.h>
+#include <syslib/ibm440gx_common.h>
+
+/*
+ * This is a horrible kludge, we eventually need to abstract this
+ * generic PHY stuff, so the  standard phy mode defines can be
+ * easily used from arch code.
+ */
+#include "../../../../drivers/net/ibm_emac/ibm_emac_phy.h"
+
+bd_t __res;
+
+static struct ibm44x_clocks clocks __initdata;
+
+/*
+ * Bamboo external IRQ triggering/polarity settings
+ */
+unsigned char ppc4xx_uic_ext_irq_cfg[] __initdata = {
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ0: Ethernet transceiver */
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* IRQ1: Expansion connector */
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ2: PCI slot 0 */
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ3: PCI slot 1 */
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ4: PCI slot 2 */
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ5: PCI slot 3 */
+	(IRQ_SENSE_EDGE  | IRQ_POLARITY_NEGATIVE), /* IRQ6: SMI pushbutton */
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ7: EXT */
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ8: EXT */
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ9: EXT */
+};
+
+static void __init
+bamboo_calibrate_decr(void)
+{
+	unsigned int freq;
+
+	if (mfspr(SPRN_CCR1) & CCR1_TCS)
+		freq = BAMBOO_TMRCLK;
+	else
+		freq = clocks.cpu;
+
+	ibm44x_calibrate_decr(freq);
+
+}
+
+static int
+bamboo_show_cpuinfo(struct seq_file *m)
+{
+	seq_printf(m, "vendor\t\t: IBM\n");
+	seq_printf(m, "machine\t\t: PPC440EP EVB (Bamboo)\n");
+
+	return 0;
+}
+
+static inline int
+bamboo_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
+{
+	static char pci_irq_table[][4] =
+	/*
+	 *	PCI IDSEL/INTPIN->INTLINE
+	 * 	   A   B   C   D
+	 */
+	{
+		{ 28, 28, 28, 28 },	/* IDSEL 1 - PCI Slot 0 */
+		{ 27, 27, 27, 27 },	/* IDSEL 2 - PCI Slot 1 */
+		{ 26, 26, 26, 26 },	/* IDSEL 3 - PCI Slot 2 */
+		{ 25, 25, 25, 25 },	/* IDSEL 4 - PCI Slot 3 */
+	};
+
+	const long min_idsel = 1, max_idsel = 4, irqs_per_slot = 4;
+	return PCI_IRQ_TABLE_LOOKUP;
+}
+
+static void __init bamboo_set_emacdata(void)
+{
+	unsigned char * selection1_base;
+	struct ocp_def *def;
+	struct ocp_func_emac_data *emacdata;
+	u8 selection1_val;
+	int mode;
+
+	selection1_base = ioremap64(BAMBOO_FPGA_SELECTION1_REG_ADDR, 16);
+	selection1_val = readb(selection1_base);
+	iounmap((void *) selection1_base);
+	if (BAMBOO_SEL_MII(selection1_val))
+		mode = PHY_MODE_MII;
+	else if (BAMBOO_SEL_RMII(selection1_val))
+		mode = PHY_MODE_RMII;
+	else
+		mode = PHY_MODE_SMII;
+
+	/* Set mac_addr and phy mode for each EMAC */
+
+	def = ocp_get_one_device(OCP_VENDOR_IBM, OCP_FUNC_EMAC, 0);
+	emacdata = def->additions;
+	memcpy(emacdata->mac_addr, __res.bi_enetaddr, 6);
+	emacdata->phy_mode = mode;
+
+	def = ocp_get_one_device(OCP_VENDOR_IBM, OCP_FUNC_EMAC, 1);
+	emacdata = def->additions;
+	memcpy(emacdata->mac_addr, __res.bi_enet1addr, 6);
+	emacdata->phy_mode = mode;
+}
+
+static int
+bamboo_exclude_device(unsigned char bus, unsigned char devfn)
+{
+	return (bus == 0 && devfn == 0);
+}
+
+#define PCI_READW(offset) \
+        (readw((void *)((u32)pci_reg_base+offset)))
+
+#define PCI_WRITEW(value, offset) \
+	(writew(value, (void *)((u32)pci_reg_base+offset)))
+
+#define PCI_WRITEL(value, offset) \
+	(writel(value, (void *)((u32)pci_reg_base+offset)))
+
+static void __init
+bamboo_setup_pci(void)
+{
+	void *pci_reg_base;
+	unsigned long memory_size;
+	memory_size = ppc_md.find_end_of_memory();
+
+	pci_reg_base = ioremap64(BAMBOO_PCIL0_BASE, BAMBOO_PCIL0_SIZE);
+
+	/* Enable PCI I/O, Mem, and Busmaster cycles */
+	PCI_WRITEW(PCI_READW(PCI_COMMAND) |
+		   PCI_COMMAND_MEMORY |
+		   PCI_COMMAND_MASTER, PCI_COMMAND);
+
+	/* Disable region first */
+	PCI_WRITEL(0, BAMBOO_PCIL0_PMM0MA);
+
+	/* PLB starting addr: 0x00000000A0000000 */
+	PCI_WRITEL(BAMBOO_PCI_PHY_MEM_BASE, BAMBOO_PCIL0_PMM0LA);
+
+	/* PCI start addr, 0xA0000000 (PCI Address) */
+	PCI_WRITEL(BAMBOO_PCI_MEM_BASE, BAMBOO_PCIL0_PMM0PCILA);
+	PCI_WRITEL(0, BAMBOO_PCIL0_PMM0PCIHA);
+
+	/* Enable no pre-fetch, enable region */
+	PCI_WRITEL(((0xffffffff -
+		     (BAMBOO_PCI_UPPER_MEM - BAMBOO_PCI_MEM_BASE)) | 0x01),
+		      BAMBOO_PCIL0_PMM0MA);
+
+	/* Disable region one */
+	PCI_WRITEL(0, BAMBOO_PCIL0_PMM1MA);
+	PCI_WRITEL(0, BAMBOO_PCIL0_PMM1LA);
+	PCI_WRITEL(0, BAMBOO_PCIL0_PMM1PCILA);
+	PCI_WRITEL(0, BAMBOO_PCIL0_PMM1PCIHA);
+	PCI_WRITEL(0, BAMBOO_PCIL0_PMM1MA);
+
+	/* Disable region two */
+	PCI_WRITEL(0, BAMBOO_PCIL0_PMM2MA);
+	PCI_WRITEL(0, BAMBOO_PCIL0_PMM2LA);
+	PCI_WRITEL(0, BAMBOO_PCIL0_PMM2PCILA);
+	PCI_WRITEL(0, BAMBOO_PCIL0_PMM2PCIHA);
+	PCI_WRITEL(0, BAMBOO_PCIL0_PMM2MA);
+
+	/* Now configure the PCI->PLB windows, we only use PTM1
+	 *
+	 * For Inbound flow, set the window size to all available memory
+	 * This is required because if size is smaller,
+	 * then Eth/PCI DD would fail as PCI card not able to access
+	 * the memory allocated by DD.
+	 */
+
+	PCI_WRITEL(0, BAMBOO_PCIL0_PTM1MS);	/* disabled region 1 */
+	PCI_WRITEL(0, BAMBOO_PCIL0_PTM1LA);	/* begin of address map */
+
+	memory_size = 1 << fls(memory_size - 1);
+
+	/* Size low + Enabled */
+	PCI_WRITEL((0xffffffff - (memory_size - 1)) | 0x1, BAMBOO_PCIL0_PTM1MS);
+
+	eieio();
+	iounmap(pci_reg_base);
+}
+
+static void __init
+bamboo_setup_hose(void)
+{
+	unsigned int bar_response, bar;
+	struct pci_controller *hose;
+
+	bamboo_setup_pci();
+
+	hose = pcibios_alloc_controller();
+
+	if (!hose)
+		return;
+
+	hose->first_busno = 0;
+	hose->last_busno = 0xff;
+
+	hose->pci_mem_offset = BAMBOO_PCI_MEM_OFFSET;
+
+	pci_init_resource(&hose->io_resource,
+			BAMBOO_PCI_LOWER_IO,
+			BAMBOO_PCI_UPPER_IO,
+			IORESOURCE_IO,
+			"PCI host bridge");
+
+	pci_init_resource(&hose->mem_resources[0],
+			BAMBOO_PCI_LOWER_MEM,
+			BAMBOO_PCI_UPPER_MEM,
+			IORESOURCE_MEM,
+			"PCI host bridge");
+
+	ppc_md.pci_exclude_device = bamboo_exclude_device;
+
+	hose->io_space.start = BAMBOO_PCI_LOWER_IO;
+	hose->io_space.end = BAMBOO_PCI_UPPER_IO;
+	hose->mem_space.start = BAMBOO_PCI_LOWER_MEM;
+	hose->mem_space.end = BAMBOO_PCI_UPPER_MEM;
+	isa_io_base =
+		(unsigned long)ioremap64(BAMBOO_PCI_IO_BASE, BAMBOO_PCI_IO_SIZE);
+	hose->io_base_virt = (void *)isa_io_base;
+
+	setup_indirect_pci(hose,
+			BAMBOO_PCI_CFGA_PLB32,
+			BAMBOO_PCI_CFGD_PLB32);
+	hose->set_cfg_type = 1;
+
+	/* Zero config bars */
+	for (bar = PCI_BASE_ADDRESS_1; bar <= PCI_BASE_ADDRESS_2; bar += 4) {
+		early_write_config_dword(hose, hose->first_busno,
+					 PCI_FUNC(hose->first_busno), bar,
+					 0x00000000);
+		early_read_config_dword(hose, hose->first_busno,
+					PCI_FUNC(hose->first_busno), bar,
+					&bar_response);
+	}
+
+	hose->last_busno = pciauto_bus_scan(hose, hose->first_busno);
+
+	ppc_md.pci_swizzle = common_swizzle;
+	ppc_md.pci_map_irq = bamboo_map_irq;
+}
+
+TODC_ALLOC();
+
+static void __init
+bamboo_early_serial_map(void)
+{
+	struct uart_port port;
+
+	/* Setup ioremapped serial port access */
+	memset(&port, 0, sizeof(port));
+	port.membase = ioremap64(PPC440EP_UART0_ADDR, 8);
+	port.irq = 0;
+	port.uartclk = clocks.uart0;
+	port.regshift = 0;
+	port.iotype = SERIAL_IO_MEM;
+	port.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST;
+	port.line = 0;
+
+	if (early_serial_setup(&port) != 0) {
+		printk("Early serial init of port 0 failed\n");
+	}
+
+#if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB)
+	/* Configure debug serial access */
+	gen550_init(0, &port);
+#endif
+
+	port.membase = ioremap64(PPC440EP_UART1_ADDR, 8);
+	port.irq = 1;
+	port.uartclk = clocks.uart1;
+	port.line = 1;
+
+	if (early_serial_setup(&port) != 0) {
+		printk("Early serial init of port 1 failed\n");
+	}
+
+#if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB)
+	/* Configure debug serial access */
+	gen550_init(1, &port);
+#endif
+
+	port.membase = ioremap64(PPC440EP_UART2_ADDR, 8);
+	port.irq = 3;
+	port.uartclk = clocks.uart2;
+	port.line = 2;
+
+	if (early_serial_setup(&port) != 0) {
+		printk("Early serial init of port 2 failed\n");
+	}
+
+#if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB)
+	/* Configure debug serial access */
+	gen550_init(2, &port);
+#endif
+
+	port.membase = ioremap64(PPC440EP_UART3_ADDR, 8);
+	port.irq = 4;
+	port.uartclk = clocks.uart3;
+	port.line = 3;
+
+	if (early_serial_setup(&port) != 0) {
+		printk("Early serial init of port 3 failed\n");
+	}
+}
+
+static void __init
+bamboo_setup_arch(void)
+{
+
+	bamboo_set_emacdata();
+
+	ibm440gx_get_clocks(&clocks, 33333333, 6 * 1843200);
+	ocp_sys_info.opb_bus_freq = clocks.opb;
+
+	/* Setup TODC access */
+	TODC_INIT(TODC_TYPE_DS1743,
+			0,
+			0,
+			ioremap64(BAMBOO_RTC_ADDR, BAMBOO_RTC_SIZE),
+			8);
+
+	/* init to some ~sane value until calibrate_delay() runs */
+        loops_per_jiffy = 50000000/HZ;
+
+	/* Setup PCI host bridge */
+	bamboo_setup_hose();
+
+#ifdef CONFIG_BLK_DEV_INITRD
+	if (initrd_start)
+		ROOT_DEV = Root_RAM0;
+	else
+#endif
+#ifdef CONFIG_ROOT_NFS
+		ROOT_DEV = Root_NFS;
+#else
+		ROOT_DEV = Root_HDA1;
+#endif
+
+	bamboo_early_serial_map();
+
+	/* Identify the system */
+	printk("IBM Bamboo port (MontaVista Software, Inc. (source@mvista.com))\n");
+}
+
+void __init platform_init(unsigned long r3, unsigned long r4,
+		unsigned long r5, unsigned long r6, unsigned long r7)
+{
+	parse_bootinfo(find_bootinfo());
+
+	/*
+	 * If we were passed in a board information, copy it into the
+	 * residual data area.
+	 */
+	if (r3)
+		__res = *(bd_t *)(r3 + KERNELBASE);
+
+
+	ibm44x_platform_init();
+
+	ppc_md.setup_arch = bamboo_setup_arch;
+	ppc_md.show_cpuinfo = bamboo_show_cpuinfo;
+	ppc_md.get_irq = NULL;		/* Set in ppc4xx_pic_init() */
+
+	ppc_md.calibrate_decr = bamboo_calibrate_decr;
+	ppc_md.time_init = todc_time_init;
+	ppc_md.set_rtc_time = todc_set_rtc_time;
+	ppc_md.get_rtc_time = todc_get_rtc_time;
+
+	ppc_md.nvram_read_val = todc_direct_read_val;
+	ppc_md.nvram_write_val = todc_direct_write_val;
+#ifdef CONFIG_KGDB
+	ppc_md.early_serial_map = bamboo_early_serial_map;
+#endif
+}
+
diff --git a/arch/ppc/platforms/4xx/bamboo.h b/arch/ppc/platforms/4xx/bamboo.h
new file mode 100644
--- /dev/null
+++ b/arch/ppc/platforms/4xx/bamboo.h
@@ -0,0 +1,136 @@
+/*
+ * arch/ppc/platforms/bamboo.h
+ *
+ * Bamboo board definitions
+ *
+ * Wade Farnsworth <wfarnsworth@mvista.com>
+ *
+ * Copyright 2004 MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#ifdef __KERNEL__
+#ifndef __ASM_BAMBOO_H__
+#define __ASM_BAMBOO_H__
+
+#include <linux/config.h>
+#include <platforms/4xx/ibm440ep.h>
+
+/* F/W TLB mapping used in bootloader glue to reset EMAC */
+#define PPC44x_EMAC0_MR0		0x0EF600E00
+
+/* Location of MAC addresses in PIBS image */
+#define PIBS_FLASH_BASE			0xfff00000
+#define PIBS_MAC_BASE			(PIBS_FLASH_BASE+0xc0400)
+#define PIBS_MAC_SIZE			0x200
+#define PIBS_MAC_OFFSET			0x100
+
+/* Default clock rate */
+#define BAMBOO_TMRCLK			25000000
+
+/* RTC/NVRAM location */
+#define BAMBOO_RTC_ADDR			0x080000000ULL
+#define BAMBOO_RTC_SIZE			0x2000
+
+/* FPGA Registers */
+#define BAMBOO_FPGA_ADDR		0x080002000ULL
+
+#define BAMBOO_FPGA_CONFIG2_REG_ADDR	(BAMBOO_FPGA_ADDR + 0x1)
+#define BAMBOO_FULL_DUPLEX_EN(x)	(x & 0x08)
+#define BAMBOO_FORCE_100Mbps(x)		(x & 0x04)
+#define BAMBOO_AUTONEGOTIATE(x)		(x & 0x02)
+
+#define BAMBOO_FPGA_SETTING_REG_ADDR	(BAMBOO_FPGA_ADDR + 0x3)
+#define BAMBOO_BOOT_SMALL_FLASH(x)	(!(x & 0x80))
+#define BAMBOO_LARGE_FLASH_EN(x)	(!(x & 0x40))
+#define BAMBOO_BOOT_NAND_FLASH(x)	(!(x & 0x20))
+
+#define BAMBOO_FPGA_SELECTION1_REG_ADDR (BAMBOO_FPGA_ADDR + 0x4)
+#define BAMBOO_SEL_MII(x)		(x & 0x80)
+#define BAMBOO_SEL_RMII(x)		(x & 0x40)
+#define BAMBOO_SEL_SMII(x)		(x & 0x20)
+
+/* Flash */
+#define BAMBOO_SMALL_FLASH_LOW		0x087f00000ULL
+#define BAMBOO_SMALL_FLASH_HIGH		0x0fff00000ULL
+#define BAMBOO_SMALL_FLASH_SIZE		0x100000
+#define BAMBOO_LARGE_FLASH_LOW		0x087800000ULL
+#define BAMBOO_LARGE_FLASH_HIGH1	0x0ff800000ULL
+#define BAMBOO_LARGE_FLASH_HIGH2	0x0ffc00000ULL
+#define BAMBOO_LARGE_FLASH_SIZE		0x400000
+#define BAMBOO_SRAM_LOW			0x087f00000ULL
+#define BAMBOO_SRAM_HIGH1		0x0fff00000ULL
+#define BAMBOO_SRAM_HIGH2		0x0ff800000ULL
+#define BAMBOO_SRAM_SIZE		0x100000
+#define BAMBOO_NAND_FLASH_REG_ADDR	0x090000000ULL
+#define BAMBOO_NAND_FLASH_REG_SIZE	0x2000
+
+/*
+ * Serial port defines
+ */
+#define RS_TABLE_SIZE			4
+
+#define UART0_IO_BASE			0xEF600300
+#define UART1_IO_BASE			0xEF600400
+#define UART2_IO_BASE			0xEF600500
+#define UART3_IO_BASE			0xEF600600
+
+#define BASE_BAUD			33177600/3/16
+#define UART0_INT			0
+#define UART1_INT			1
+#define UART2_INT			3
+#define UART3_INT			4
+
+#define STD_UART_OP(num)					\
+	{ 0, BASE_BAUD, 0, UART##num##_INT,			\
+		(ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST),	\
+		iomem_base: UART##num##_IO_BASE,		\
+		io_type: SERIAL_IO_MEM},
+
+#define SERIAL_PORT_DFNS	\
+	STD_UART_OP(0)		\
+	STD_UART_OP(1)		\
+	STD_UART_OP(2)		\
+	STD_UART_OP(3)
+
+/* PCI support */
+#define BAMBOO_PCI_CFGA_PLB32		0xeec00000
+#define BAMBOO_PCI_CFGD_PLB32		0xeec00004
+
+#define BAMBOO_PCI_IO_BASE		0x00000000e8000000ULL
+#define BAMBOO_PCI_IO_SIZE		0x00010000
+#define BAMBOO_PCI_MEM_OFFSET		0x00000000
+#define BAMBOO_PCI_PHY_MEM_BASE		0x00000000a0000000ULL
+
+#define BAMBOO_PCI_LOWER_IO		0x00000000
+#define BAMBOO_PCI_UPPER_IO		0x0000ffff
+#define BAMBOO_PCI_LOWER_MEM		0xa0000000
+#define BAMBOO_PCI_UPPER_MEM		0xafffffff
+#define BAMBOO_PCI_MEM_BASE		0xa0000000
+
+#define BAMBOO_PCIL0_BASE		0x00000000ef400000ULL
+#define BAMBOO_PCIL0_SIZE		0x40
+
+#define BAMBOO_PCIL0_PMM0LA		0x000
+#define BAMBOO_PCIL0_PMM0MA		0x004
+#define BAMBOO_PCIL0_PMM0PCILA		0x008
+#define BAMBOO_PCIL0_PMM0PCIHA		0x00C
+#define BAMBOO_PCIL0_PMM1LA		0x010
+#define BAMBOO_PCIL0_PMM1MA		0x014
+#define BAMBOO_PCIL0_PMM1PCILA		0x018
+#define BAMBOO_PCIL0_PMM1PCIHA		0x01C
+#define BAMBOO_PCIL0_PMM2LA		0x020
+#define BAMBOO_PCIL0_PMM2MA		0x024
+#define BAMBOO_PCIL0_PMM2PCILA		0x028
+#define BAMBOO_PCIL0_PMM2PCIHA		0x02C
+#define BAMBOO_PCIL0_PTM1MS		0x030
+#define BAMBOO_PCIL0_PTM1LA		0x034
+#define BAMBOO_PCIL0_PTM2MS		0x038
+#define BAMBOO_PCIL0_PTM2LA		0x03C
+
+#endif                          /* __ASM_BAMBOO_H__ */
+#endif                          /* __KERNEL__ */
diff --git a/arch/ppc/platforms/4xx/ebony.c b/arch/ppc/platforms/4xx/ebony.c
--- a/arch/ppc/platforms/4xx/ebony.c
+++ b/arch/ppc/platforms/4xx/ebony.c
@@ -7,7 +7,7 @@
  * Copyright 2002-2005 MontaVista Software Inc.
  *
  * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
- * Copyright (c) 2003, 2004 Zultys Technologies
+ * Copyright (c) 2003-2005 Zultys Technologies
  *
  * 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
@@ -50,6 +50,7 @@
 #include <asm/bootinfo.h>
 #include <asm/ppc4xx_pic.h>
 #include <asm/ppcboot.h>
+#include <asm/tlbflush.h>
 
 #include <syslib/gen550.h>
 #include <syslib/ibm440gp_common.h>
@@ -248,6 +249,9 @@ ebony_early_serial_map(void)
 #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB)
 	/* Configure debug serial access */
 	gen550_init(0, &port);
+
+	/* Purge TLB entry added in head_44x.S for early serial access */
+	_tlbie(UART0_IO_BASE);
 #endif
 
 	port.membase = ioremap64(PPC440GP_UART1_ADDR, 8);
diff --git a/arch/ppc/platforms/4xx/ebony.h b/arch/ppc/platforms/4xx/ebony.h
--- a/arch/ppc/platforms/4xx/ebony.h
+++ b/arch/ppc/platforms/4xx/ebony.h
@@ -56,9 +56,18 @@
  * Serial port defines
  */
 
-/* OpenBIOS defined UART mappings, used before early_serial_setup */
+#if defined(__BOOTER__)
+/* OpenBIOS defined UART mappings, used by bootloader shim */
 #define UART0_IO_BASE	0xE0000200
 #define UART1_IO_BASE	0xE0000300
+#else
+/* head_44x.S created UART mapping, used before early_serial_setup.
+ * We cannot use default OpenBIOS UART mappings because they
+ * don't work for configurations with more than 512M RAM.    --ebs
+ */
+#define UART0_IO_BASE	0xF0000200
+#define UART1_IO_BASE	0xF0000300
+#endif
 
 /* external Epson SG-615P */
 #define BASE_BAUD	691200
@@ -66,7 +75,7 @@
 #define STD_UART_OP(num)					\
 	{ 0, BASE_BAUD, 0, UART##num##_INT,			\
 		(ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST),	\
-		iomem_base: UART##num##_IO_BASE,		\
+		iomem_base: (void*)UART##num##_IO_BASE,		\
 		io_type: SERIAL_IO_MEM},
 
 #define SERIAL_PORT_DFNS	\
diff --git a/arch/ppc/platforms/4xx/ibm440ep.c b/arch/ppc/platforms/4xx/ibm440ep.c
new file mode 100644
--- /dev/null
+++ b/arch/ppc/platforms/4xx/ibm440ep.c
@@ -0,0 +1,220 @@
+/*
+ * arch/ppc/platforms/4xx/ibm440ep.c
+ *
+ * PPC440EP I/O descriptions
+ *
+ * Wade Farnsworth <wfarnsworth@mvista.com>
+ * Copyright 2004 MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ */
+#include <linux/init.h>
+#include <linux/module.h>
+#include <platforms/4xx/ibm440ep.h>
+#include <asm/ocp.h>
+#include <asm/ppc4xx_pic.h>
+
+static struct ocp_func_emac_data ibm440ep_emac0_def = {
+	.rgmii_idx	= -1,           /* No RGMII */
+	.rgmii_mux	= -1,           /* No RGMII */
+	.zmii_idx       = 0,            /* ZMII device index */
+	.zmii_mux       = 0,            /* ZMII input of this EMAC */
+	.mal_idx        = 0,            /* MAL device index */
+	.mal_rx_chan    = 0,            /* MAL rx channel number */
+	.mal_tx_chan    = 0,            /* MAL tx channel number */
+	.wol_irq        = 61,		/* WOL interrupt number */
+	.mdio_idx       = -1,           /* No shared MDIO */
+	.tah_idx	= -1,           /* No TAH */
+};
+
+static struct ocp_func_emac_data ibm440ep_emac1_def = {
+	.rgmii_idx	= -1,           /* No RGMII */
+	.rgmii_mux	= -1,           /* No RGMII */
+	.zmii_idx       = 0,            /* ZMII device index */
+	.zmii_mux       = 1,            /* ZMII input of this EMAC */
+	.mal_idx        = 0,            /* MAL device index */
+	.mal_rx_chan    = 1,            /* MAL rx channel number */
+	.mal_tx_chan    = 2,            /* MAL tx channel number */
+	.wol_irq        = 63,  		/* WOL interrupt number */
+	.mdio_idx       = -1,           /* No shared MDIO */
+	.tah_idx	= -1,           /* No TAH */
+};
+OCP_SYSFS_EMAC_DATA()
+
+static struct ocp_func_mal_data ibm440ep_mal0_def = {
+	.num_tx_chans   = 4,  		/* Number of TX channels */
+	.num_rx_chans   = 2,    	/* Number of RX channels */
+	.txeob_irq	= 10,		/* TX End Of Buffer IRQ  */
+	.rxeob_irq	= 11,		/* RX End Of Buffer IRQ  */
+	.txde_irq	= 33,		/* TX Descriptor Error IRQ */
+	.rxde_irq	= 34,		/* RX Descriptor Error IRQ */
+	.serr_irq	= 32,		/* MAL System Error IRQ    */
+};
+OCP_SYSFS_MAL_DATA()
+
+static struct ocp_func_iic_data ibm440ep_iic0_def = {
+	.fast_mode	= 0,		/* Use standad mode (100Khz) */
+};
+
+static struct ocp_func_iic_data ibm440ep_iic1_def = {
+	.fast_mode	= 0,		/* Use standad mode (100Khz) */
+};
+OCP_SYSFS_IIC_DATA()
+
+struct ocp_def core_ocp[] = {
+	{ .vendor	= OCP_VENDOR_IBM,
+	  .function	= OCP_FUNC_OPB,
+	  .index	= 0,
+	  .paddr	= 0x0EF600000ULL,
+	  .irq		= OCP_IRQ_NA,
+	  .pm		= OCP_CPM_NA,
+	},
+	{ .vendor	= OCP_VENDOR_IBM,
+	  .function	= OCP_FUNC_16550,
+	  .index	= 0,
+	  .paddr	= PPC440EP_UART0_ADDR,
+	  .irq		= UART0_INT,
+	  .pm		= IBM_CPM_UART0,
+	},
+	{ .vendor	= OCP_VENDOR_IBM,
+	  .function	= OCP_FUNC_16550,
+	  .index	= 1,
+	  .paddr	= PPC440EP_UART1_ADDR,
+	  .irq		= UART1_INT,
+	  .pm		= IBM_CPM_UART1,
+	},
+	{ .vendor	= OCP_VENDOR_IBM,
+	  .function	= OCP_FUNC_16550,
+	  .index	= 2,
+	  .paddr	= PPC440EP_UART2_ADDR,
+	  .irq		= UART2_INT,
+	  .pm		= IBM_CPM_UART2,
+	},
+	{ .vendor	= OCP_VENDOR_IBM,
+	  .function	= OCP_FUNC_16550,
+	  .index	= 3,
+	  .paddr	= PPC440EP_UART3_ADDR,
+	  .irq		= UART3_INT,
+	  .pm		= IBM_CPM_UART3,
+	},
+	{ .vendor	= OCP_VENDOR_IBM,
+	  .function	= OCP_FUNC_IIC,
+	  .index	= 0,
+	  .paddr	= 0x0EF600700ULL,
+	  .irq		= 2,
+	  .pm		= IBM_CPM_IIC0,
+	  .additions	= &ibm440ep_iic0_def,
+	  .show		= &ocp_show_iic_data
+	},
+	{ .vendor	= OCP_VENDOR_IBM,
+	  .function	= OCP_FUNC_IIC,
+	  .index	= 1,
+	  .paddr	= 0x0EF600800ULL,
+	  .irq		= 7,
+	  .pm		= IBM_CPM_IIC1,
+	  .additions	= &ibm440ep_iic1_def,
+	  .show		= &ocp_show_iic_data
+	},
+	{ .vendor	= OCP_VENDOR_IBM,
+	  .function	= OCP_FUNC_GPIO,
+	  .index	= 0,
+	  .paddr	= 0x0EF600B00ULL,
+	  .irq		= OCP_IRQ_NA,
+	  .pm		= IBM_CPM_GPIO0,
+	},
+	{ .vendor	= OCP_VENDOR_IBM,
+	  .function	= OCP_FUNC_GPIO,
+	  .index	= 1,
+	  .paddr	= 0x0EF600C00ULL,
+	  .irq		= OCP_IRQ_NA,
+	  .pm		= OCP_CPM_NA,
+	},
+	{ .vendor	= OCP_VENDOR_IBM,
+	  .function	= OCP_FUNC_MAL,
+	  .paddr	= OCP_PADDR_NA,
+	  .irq		= OCP_IRQ_NA,
+	  .pm		= OCP_CPM_NA,
+	  .additions	= &ibm440ep_mal0_def,
+	  .show		= &ocp_show_mal_data,
+	},
+	{ .vendor	= OCP_VENDOR_IBM,
+	  .function	= OCP_FUNC_EMAC,
+	  .index	= 0,
+	  .paddr	= 0x0EF600E00ULL,
+	  .irq		= 60,
+	  .pm		= OCP_CPM_NA,
+	  .additions	= &ibm440ep_emac0_def,
+	  .show		= &ocp_show_emac_data,
+	},
+	{ .vendor	= OCP_VENDOR_IBM,
+	  .function	= OCP_FUNC_EMAC,
+	  .index	= 1,
+	  .paddr	= 0x0EF600F00ULL,
+	  .irq		= 62,
+	  .pm		= OCP_CPM_NA,
+	  .additions	= &ibm440ep_emac1_def,
+	  .show		= &ocp_show_emac_data,
+	},
+	{ .vendor	= OCP_VENDOR_IBM,
+	  .function	= OCP_FUNC_ZMII,
+	  .paddr	= 0x0EF600D00ULL,
+	  .irq		= OCP_IRQ_NA,
+	  .pm		= OCP_CPM_NA,
+	},
+	{ .vendor	= OCP_VENDOR_INVALID
+	}
+};
+
+/* Polarity and triggering settings for internal interrupt sources */
+struct ppc4xx_uic_settings ppc4xx_core_uic_cfg[] __initdata = {
+	{ .polarity	= 0xffbffe03,
+	  .triggering   = 0xfffffe00,
+	  .ext_irq_mask = 0x000001fc,	/* IRQ0 - IRQ6 */
+	},
+	{ .polarity	= 0xffffc6ef,
+	  .triggering	= 0xffffc7ff,
+	  .ext_irq_mask = 0x00003800,	/* IRQ7 - IRQ9 */
+	},
+};
+
+static struct resource usb_gadget_resources[] = {
+	[0] = {
+		.start	= 0x050000100ULL,
+		.end 	= 0x05000017FULL,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= 55,
+		.end	= 55,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static u64 dma_mask = 0xffffffffULL;
+
+static struct platform_device usb_gadget_device = {
+	.name		= "musbhsfc",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(usb_gadget_resources),
+	.resource       = usb_gadget_resources,
+	.dev		= {
+		.dma_mask = &dma_mask,
+		.coherent_dma_mask = 0xffffffffULL,
+	}
+};
+
+static struct platform_device *ibm440ep_devs[] __initdata = {
+	&usb_gadget_device,
+};
+
+static int __init
+ibm440ep_platform_add_devices(void)
+{
+	return platform_add_devices(ibm440ep_devs, ARRAY_SIZE(ibm440ep_devs));
+}
+arch_initcall(ibm440ep_platform_add_devices);
+
diff --git a/arch/ppc/platforms/4xx/ibm440ep.h b/arch/ppc/platforms/4xx/ibm440ep.h
new file mode 100644
--- /dev/null
+++ b/arch/ppc/platforms/4xx/ibm440ep.h
@@ -0,0 +1,76 @@
+/*
+ * arch/ppc/platforms/4xx/ibm440ep.h
+ *
+ * PPC440EP definitions
+ *
+ * Wade Farnsworth <wfarnsworth@mvista.com>
+ *
+ * Copyright 2002 Roland Dreier
+ * Copyright 2004 MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ */
+
+#ifdef __KERNEL__
+#ifndef __PPC_PLATFORMS_IBM440EP_H
+#define __PPC_PLATFORMS_IBM440EP_H
+
+#include <linux/config.h>
+#include <asm/ibm44x.h>
+
+/* UART */
+#define PPC440EP_UART0_ADDR		0x0EF600300
+#define PPC440EP_UART1_ADDR		0x0EF600400
+#define PPC440EP_UART2_ADDR		0x0EF600500
+#define PPC440EP_UART3_ADDR		0x0EF600600
+#define UART0_INT			0
+#define UART1_INT			1
+#define UART2_INT			3
+#define UART3_INT			4
+
+/* Clock and Power Management */
+#define IBM_CPM_IIC0		0x80000000	/* IIC interface */
+#define IBM_CPM_IIC1		0x40000000	/* IIC interface */
+#define IBM_CPM_PCI		0x20000000	/* PCI bridge */
+#define IBM_CPM_USB1H		0x08000000	/* USB 1.1 Host */
+#define IBM_CPM_FPU		0x04000000	/* floating point unit */
+#define IBM_CPM_CPU		0x02000000	/* processor core */
+#define IBM_CPM_DMA		0x01000000	/* DMA controller */
+#define IBM_CPM_BGO		0x00800000	/* PLB to OPB bus arbiter */
+#define IBM_CPM_BGI		0x00400000	/* OPB to PLB bridge */
+#define IBM_CPM_EBC		0x00200000	/* External Bus Controller */
+#define IBM_CPM_EBM		0x00100000	/* Ext Bus Master Interface */
+#define IBM_CPM_DMC		0x00080000	/* SDRAM peripheral controller */
+#define IBM_CPM_PLB4		0x00040000	/* PLB4 bus arbiter */
+#define IBM_CPM_PLB4x3		0x00020000	/* PLB4 to PLB3 bridge controller */
+#define IBM_CPM_PLB3x4		0x00010000	/* PLB3 to PLB4 bridge controller */
+#define IBM_CPM_PLB3		0x00008000	/* PLB3 bus arbiter */
+#define IBM_CPM_PPM		0x00002000	/* PLB Performance Monitor */
+#define IBM_CPM_UIC1		0x00001000	/* Universal Interrupt Controller */
+#define IBM_CPM_GPIO0		0x00000800	/* General Purpose IO (??) */
+#define IBM_CPM_GPT		0x00000400	/* General Purpose Timers  */
+#define IBM_CPM_UART0		0x00000200	/* serial port 0 */
+#define IBM_CPM_UART1		0x00000100	/* serial port 1 */
+#define IBM_CPM_UIC0		0x00000080	/* Universal Interrupt Controller */
+#define IBM_CPM_TMRCLK		0x00000040	/* CPU timers */
+#define IBM_CPM_EMAC0		0x00000020	/* ethernet port 0 */
+#define IBM_CPM_EMAC1		0x00000010	/* ethernet port 1 */
+#define IBM_CPM_UART2		0x00000008	/* serial port 2 */
+#define IBM_CPM_UART3		0x00000004	/* serial port 3 */
+#define IBM_CPM_USB2D		0x00000002	/* USB 2.0 Device */
+#define IBM_CPM_USB2H		0x00000001	/* USB 2.0 Host */
+
+#define DFLT_IBM4xx_PM		~(IBM_CPM_UIC0 | IBM_CPM_UIC1 | IBM_CPM_CPU \
+				| IBM_CPM_EBC | IBM_CPM_BGO | IBM_CPM_FPU \
+				| IBM_CPM_EBM | IBM_CPM_PLB4 | IBM_CPM_3x4 \
+				| IBM_CPM_PLB3 | IBM_CPM_PLB4x3 \
+				| IBM_CPM_EMAC0 | IBM_CPM_TMRCLK \
+				| IBM_CPM_DMA | IBM_CPM_PCI | IBM_CPM_EMAC1)
+
+
+#endif /* __PPC_PLATFORMS_IBM440EP_H */
+#endif /* __KERNEL__ */
diff --git a/arch/ppc/platforms/4xx/ibm440sp.c b/arch/ppc/platforms/4xx/ibm440sp.c
--- a/arch/ppc/platforms/4xx/ibm440sp.c
+++ b/arch/ppc/platforms/4xx/ibm440sp.c
@@ -36,8 +36,8 @@ static struct ocp_func_emac_data ibm440s
 OCP_SYSFS_EMAC_DATA()
 
 static struct ocp_func_mal_data ibm440sp_mal0_def = {
-	.num_tx_chans   = 4,    	/* Number of TX channels */
-	.num_rx_chans   = 4,    	/* Number of RX channels */
+	.num_tx_chans   = 1,    	/* Number of TX channels */
+	.num_rx_chans   = 1,    	/* Number of RX channels */
 	.txeob_irq	= 38,		/* TX End Of Buffer IRQ  */
 	.rxeob_irq	= 39,		/* RX End Of Buffer IRQ  */
 	.txde_irq	= 34,		/* TX Descriptor Error IRQ */
diff --git a/arch/ppc/platforms/4xx/ocotea.c b/arch/ppc/platforms/4xx/ocotea.c
--- a/arch/ppc/platforms/4xx/ocotea.c
+++ b/arch/ppc/platforms/4xx/ocotea.c
@@ -48,6 +48,7 @@
 #include <asm/bootinfo.h>
 #include <asm/ppc4xx_pic.h>
 #include <asm/ppcboot.h>
+#include <asm/tlbflush.h>
 
 #include <syslib/gen550.h>
 #include <syslib/ibm440gx_common.h>
@@ -266,6 +267,9 @@ ocotea_early_serial_map(void)
 #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB)
 	/* Configure debug serial access */
 	gen550_init(0, &port);
+
+	/* Purge TLB entry added in head_44x.S for early serial access */
+	_tlbie(UART0_IO_BASE);
 #endif
 
 	port.membase = ioremap64(PPC440GX_UART1_ADDR, 8);
diff --git a/arch/ppc/platforms/4xx/ocotea.h b/arch/ppc/platforms/4xx/ocotea.h
--- a/arch/ppc/platforms/4xx/ocotea.h
+++ b/arch/ppc/platforms/4xx/ocotea.h
@@ -55,15 +55,24 @@
  */
 #define RS_TABLE_SIZE	2
 
-/* OpenBIOS defined UART mappings, used before early_serial_setup */
+#if defined(__BOOTER__)
+/* OpenBIOS defined UART mappings, used by bootloader shim */
 #define UART0_IO_BASE	0xE0000200
 #define UART1_IO_BASE	0xE0000300
+#else
+/* head_44x.S created UART mapping, used before early_serial_setup.
+ * We cannot use default OpenBIOS UART mappings because they
+ * don't work for configurations with more than 512M RAM.    --ebs
+ */
+#define UART0_IO_BASE	0xF0000200
+#define UART1_IO_BASE	0xF0000300
+#endif
 
 #define BASE_BAUD	11059200/16
 #define STD_UART_OP(num)					\
 	{ 0, BASE_BAUD, 0, UART##num##_INT,			\
 		(ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST),	\
-		iomem_base: UART##num##_IO_BASE,		\
+		iomem_base: (void*)UART##num##_IO_BASE,		\
 		io_type: SERIAL_IO_MEM},
 
 #define SERIAL_PORT_DFNS	\
diff --git a/arch/ppc/platforms/83xx/mpc834x_sys.c b/arch/ppc/platforms/83xx/mpc834x_sys.c
--- a/arch/ppc/platforms/83xx/mpc834x_sys.c
+++ b/arch/ppc/platforms/83xx/mpc834x_sys.c
@@ -41,7 +41,6 @@
 #include <asm/time.h>
 #include <asm/io.h>
 #include <asm/machdep.h>
-#include <asm/prom.h>
 #include <asm/ipic.h>
 #include <asm/bootinfo.h>
 #include <asm/pci-bridge.h>
@@ -95,20 +94,24 @@ mpc834x_sys_setup_arch(void)
 
 	/* setup the board related information for the enet controllers */
 	pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC83xx_TSEC1);
-	pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
-	pdata->interruptPHY = MPC83xx_IRQ_EXT1;
-	pdata->phyid = 0;
-	/* fixup phy address */
-	pdata->phy_reg_addr += binfo->bi_immr_base;
-	memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6);
+	if (pdata) {
+		pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
+		pdata->interruptPHY = MPC83xx_IRQ_EXT1;
+		pdata->phyid = 0;
+		/* fixup phy address */
+		pdata->phy_reg_addr += binfo->bi_immr_base;
+		memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6);
+	}
 
 	pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC83xx_TSEC2);
-	pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
-	pdata->interruptPHY = MPC83xx_IRQ_EXT2;
-	pdata->phyid = 1;
-	/* fixup phy address */
-	pdata->phy_reg_addr += binfo->bi_immr_base;
-	memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6);
+	if (pdata) {
+		pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
+		pdata->interruptPHY = MPC83xx_IRQ_EXT2;
+		pdata->phyid = 1;
+		/* fixup phy address */
+		pdata->phy_reg_addr += binfo->bi_immr_base;
+		memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6);
+	}
 
 #ifdef CONFIG_BLK_DEV_INITRD
 	if (initrd_start)
@@ -186,6 +189,26 @@ mpc834x_sys_init_IRQ(void)
 	ipic_set_default_priority();
 }
 
+#if defined(CONFIG_I2C_MPC) && defined(CONFIG_SENSORS_DS1374)
+extern ulong	ds1374_get_rtc_time(void);
+extern int	ds1374_set_rtc_time(ulong);
+
+static int __init
+mpc834x_rtc_hookup(void)
+{
+	struct timespec	tv;
+
+	ppc_md.get_rtc_time = ds1374_get_rtc_time;
+	ppc_md.set_rtc_time = ds1374_set_rtc_time;
+
+	tv.tv_nsec = 0;
+	tv.tv_sec = (ppc_md.get_rtc_time)();
+	do_settimeofday(&tv);
+
+	return 0;
+}
+late_initcall(mpc834x_rtc_hookup);
+#endif
 static __inline__ void
 mpc834x_sys_set_bat(void)
 {
diff --git a/arch/ppc/platforms/85xx/Kconfig b/arch/ppc/platforms/85xx/Kconfig
--- a/arch/ppc/platforms/85xx/Kconfig
+++ b/arch/ppc/platforms/85xx/Kconfig
@@ -21,6 +21,11 @@ config MPC8540_ADS
 	help
 	  This option enables support for the MPC 8540 ADS evaluation board.
 
+config MPC8548_CDS
+	bool "Freescale MPC8548 CDS"
+	help
+	  This option enablese support for the MPC8548 CDS evaluation board.
+
 config MPC8555_CDS
 	bool "Freescale MPC8555 CDS"
 	help
@@ -53,6 +58,11 @@ config MPC8540
 	depends on MPC8540_ADS
 	default y
 
+config MPC8548
+	bool
+	depends on MPC8548_CDS
+	default y
+
 config MPC8555
 	bool
 	depends on MPC8555_CDS
diff --git a/arch/ppc/platforms/85xx/Makefile b/arch/ppc/platforms/85xx/Makefile
--- a/arch/ppc/platforms/85xx/Makefile
+++ b/arch/ppc/platforms/85xx/Makefile
@@ -2,6 +2,7 @@
 # Makefile for the PowerPC 85xx linux kernel.
 #
 obj-$(CONFIG_MPC8540_ADS)	+= mpc85xx_ads_common.o mpc8540_ads.o
+obj-$(CONFIG_MPC8548_CDS)	+= mpc85xx_cds_common.o
 obj-$(CONFIG_MPC8555_CDS)	+= mpc85xx_cds_common.o
 obj-$(CONFIG_MPC8560_ADS)	+= mpc85xx_ads_common.o mpc8560_ads.o
 obj-$(CONFIG_SBC8560)		+= sbc85xx.o sbc8560.o
diff --git a/arch/ppc/platforms/85xx/mpc8540_ads.c b/arch/ppc/platforms/85xx/mpc8540_ads.c
--- a/arch/ppc/platforms/85xx/mpc8540_ads.c
+++ b/arch/ppc/platforms/85xx/mpc8540_ads.c
@@ -41,7 +41,6 @@
 #include <asm/time.h>
 #include <asm/io.h>
 #include <asm/machdep.h>
-#include <asm/prom.h>
 #include <asm/open_pic.h>
 #include <asm/bootinfo.h>
 #include <asm/pci-bridge.h>
@@ -88,33 +87,39 @@ mpc8540ads_setup_arch(void)
 #ifdef CONFIG_SERIAL_TEXT_DEBUG
 	/* Invalidate the entry we stole earlier the serial ports
 	 * should be properly mapped */
-	invalidate_tlbcam_entry(NUM_TLBCAMS - 1);
+	invalidate_tlbcam_entry(num_tlbcam_entries - 1);
 #endif
 
 	/* setup the board related information for the enet controllers */
 	pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1);
-	pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
-	pdata->interruptPHY = MPC85xx_IRQ_EXT5;
-	pdata->phyid = 0;
-	/* fixup phy address */
-	pdata->phy_reg_addr += binfo->bi_immr_base;
-	memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6);
+	if (pdata) {
+		pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
+		pdata->interruptPHY = MPC85xx_IRQ_EXT5;
+		pdata->phyid = 0;
+		/* fixup phy address */
+		pdata->phy_reg_addr += binfo->bi_immr_base;
+		memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6);
+	}
 
 	pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2);
-	pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
-	pdata->interruptPHY = MPC85xx_IRQ_EXT5;
-	pdata->phyid = 1;
-	/* fixup phy address */
-	pdata->phy_reg_addr += binfo->bi_immr_base;
-	memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6);
+	if (pdata) {
+		pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
+		pdata->interruptPHY = MPC85xx_IRQ_EXT5;
+		pdata->phyid = 1;
+		/* fixup phy address */
+		pdata->phy_reg_addr += binfo->bi_immr_base;
+		memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6);
+	}
 
 	pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_FEC);
-	pdata->board_flags = 0;
-	pdata->interruptPHY = MPC85xx_IRQ_EXT5;
-	pdata->phyid = 3;
-	/* fixup phy address */
-	pdata->phy_reg_addr += binfo->bi_immr_base;
-	memcpy(pdata->mac_addr, binfo->bi_enet2addr, 6);
+	if (pdata) {
+		pdata->board_flags = 0;
+		pdata->interruptPHY = MPC85xx_IRQ_EXT5;
+		pdata->phyid = 3;
+		/* fixup phy address */
+		pdata->phy_reg_addr += binfo->bi_immr_base;
+		memcpy(pdata->mac_addr, binfo->bi_enet2addr, 6);
+	}
 
 #ifdef CONFIG_BLK_DEV_INITRD
 	if (initrd_start)
@@ -150,7 +155,7 @@ platform_init(unsigned long r3, unsigned
 		struct uart_port p;
 
 		/* Use the last TLB entry to map CCSRBAR to allow access to DUART regs */
-		settlbcam(NUM_TLBCAMS - 1, binfo->bi_immr_base,
+		settlbcam(num_tlbcam_entries - 1, binfo->bi_immr_base,
 			  binfo->bi_immr_base, MPC85xx_CCSRBAR_SIZE, _PAGE_IO, 0);
 
 		memset(&p, 0, sizeof (p));
diff --git a/arch/ppc/platforms/85xx/mpc8560_ads.c b/arch/ppc/platforms/85xx/mpc8560_ads.c
--- a/arch/ppc/platforms/85xx/mpc8560_ads.c
+++ b/arch/ppc/platforms/85xx/mpc8560_ads.c
@@ -41,7 +41,6 @@
 #include <asm/time.h>
 #include <asm/io.h>
 #include <asm/machdep.h>
-#include <asm/prom.h>
 #include <asm/open_pic.h>
 #include <asm/bootinfo.h>
 #include <asm/pci-bridge.h>
@@ -57,7 +56,6 @@
 #include <syslib/ppc85xx_common.h>
 #include <syslib/ppc85xx_setup.h>
 
-extern void cpm2_reset(void);
 
 /* ************************************************************************
  *
@@ -91,20 +89,24 @@ mpc8560ads_setup_arch(void)
 
 	/* setup the board related information for the enet controllers */
 	pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1);
-	pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
-	pdata->interruptPHY = MPC85xx_IRQ_EXT5;
-	pdata->phyid = 0;
-	/* fixup phy address */
-	pdata->phy_reg_addr += binfo->bi_immr_base;
-	memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6);
+	if (pdata) {
+		pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
+		pdata->interruptPHY = MPC85xx_IRQ_EXT5;
+		pdata->phyid = 0;
+		/* fixup phy address */
+		pdata->phy_reg_addr += binfo->bi_immr_base;
+		memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6);
+	}
 
 	pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2);
-	pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
-	pdata->interruptPHY = MPC85xx_IRQ_EXT5;
-	pdata->phyid = 1;
-	/* fixup phy address */
-	pdata->phy_reg_addr += binfo->bi_immr_base;
-	memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6);
+	if (pdata) {
+		pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
+		pdata->interruptPHY = MPC85xx_IRQ_EXT5;
+		pdata->phyid = 1;
+		/* fixup phy address */
+		pdata->phy_reg_addr += binfo->bi_immr_base;
+		memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6);
+	}
 
 #ifdef CONFIG_BLK_DEV_INITRD
 	if (initrd_start)
diff --git a/arch/ppc/platforms/85xx/mpc85xx_ads_common.c b/arch/ppc/platforms/85xx/mpc85xx_ads_common.c
--- a/arch/ppc/platforms/85xx/mpc85xx_ads_common.c
+++ b/arch/ppc/platforms/85xx/mpc85xx_ads_common.c
@@ -36,7 +36,6 @@
 #include <asm/time.h>
 #include <asm/io.h>
 #include <asm/machdep.h>
-#include <asm/prom.h>
 #include <asm/open_pic.h>
 #include <asm/bootinfo.h>
 #include <asm/pci-bridge.h>
@@ -59,40 +58,8 @@ extern unsigned long total_memory;	/* in
 unsigned char __res[sizeof (bd_t)];
 
 /* Internal interrupts are all Level Sensitive, and Positive Polarity */
-
 static u_char mpc85xx_ads_openpic_initsenses[] __initdata = {
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal  0: L2 Cache */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal  1: ECM */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal  2: DDR DRAM */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal  3: LBIU */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal  4: DMA 0 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal  5: DMA 1 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal  6: DMA 2 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal  7: DMA 3 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal  8: PCI/PCI-X */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal  9: RIO Inbound Port Write Error */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 10: RIO Doorbell Inbound */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 11: RIO Outbound Message */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 12: RIO Inbound Message */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 13: TSEC 0 Transmit */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 14: TSEC 0 Receive */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 15: Unused */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 16: Unused */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 17: Unused */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 18: TSEC 0 Receive/Transmit Error */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 19: TSEC 1 Transmit */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 20: TSEC 1 Receive */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 21: Unused */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 22: Unused */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 23: Unused */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 24: TSEC 1 Receive/Transmit Error */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 25: Fast Ethernet */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 26: DUART */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 27: I2C */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 28: Performance Monitor */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 29: Unused */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 30: CPM */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 31: Unused */
+	MPC85XX_INTERNAL_IRQ_SENSES,
 	0x0,						/* External  0: */
 #if defined(CONFIG_PCI)
 	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* External 1: PCI slot 0 */
@@ -159,7 +126,7 @@ mpc85xx_ads_init_IRQ(void)
 	/* Skip reserved space and internal sources */
 	openpic_set_sources(0, 32, OpenPIC_Addr + 0x10200);
 	/* Map PIC IRQs 0-11 */
-	openpic_set_sources(32, 12, OpenPIC_Addr + 0x10000);
+	openpic_set_sources(48, 12, OpenPIC_Addr + 0x10000);
 
 	/* we let openpic interrupts starting from an offset, to
 	 * leave space for cascading interrupts underneath.
diff --git a/arch/ppc/platforms/85xx/mpc85xx_cds_common.c b/arch/ppc/platforms/85xx/mpc85xx_cds_common.c
--- a/arch/ppc/platforms/85xx/mpc85xx_cds_common.c
+++ b/arch/ppc/platforms/85xx/mpc85xx_cds_common.c
@@ -42,7 +42,6 @@
 #include <asm/todc.h>
 #include <asm/io.h>
 #include <asm/machdep.h>
-#include <asm/prom.h>
 #include <asm/open_pic.h>
 #include <asm/i8259.h>
 #include <asm/bootinfo.h>
@@ -50,7 +49,7 @@
 #include <asm/mpc85xx.h>
 #include <asm/irq.h>
 #include <asm/immap_85xx.h>
-#include <asm/immap_cpm2.h>
+#include <asm/cpm2.h>
 #include <asm/ppc_sys.h>
 #include <asm/kgdb.h>
 
@@ -73,40 +72,8 @@ static int cds_pci_slot = 2;
 static volatile u8 * cadmus;
 
 /* Internal interrupts are all Level Sensitive, and Positive Polarity */
-
 static u_char mpc85xx_cds_openpic_initsenses[] __initdata = {
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal  0: L2 Cache */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal  1: ECM */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal  2: DDR DRAM */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal  3: LBIU */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal  4: DMA 0 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal  5: DMA 1 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal  6: DMA 2 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal  7: DMA 3 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal  8: PCI/PCI-X */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal  9: RIO Inbound Port Write Error */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 10: RIO Doorbell Inbound */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 11: RIO Outbound Message */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 12: RIO Inbound Message */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 13: TSEC 0 Transmit */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 14: TSEC 0 Receive */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 15: Unused */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 16: Unused */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 17: Unused */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 18: TSEC 0 Receive/Transmit Error */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 19: TSEC 1 Transmit */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 20: TSEC 1 Receive */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 21: Unused */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 22: Unused */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 23: Unused */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 24: TSEC 1 Receive/Transmit Error */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 25: Fast Ethernet */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 26: DUART */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 27: I2C */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 28: Performance Monitor */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 29: Unused */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 30: CPM */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 31: Unused */
+	MPC85XX_INTERNAL_IRQ_SENSES,
 #if defined(CONFIG_PCI)
 	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* External 0: PCI1 slot */
 	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* External 1: PCI1 slot */
@@ -191,9 +158,13 @@ mpc85xx_cds_init_IRQ(void)
 	OpenPIC_NumInitSenses = sizeof (mpc85xx_cds_openpic_initsenses);
 
 	/* Skip reserved space and internal sources */
+#ifdef CONFIG_MPC8548
+	openpic_set_sources(0, 48, OpenPIC_Addr + 0x10200);
+#else
 	openpic_set_sources(0, 32, OpenPIC_Addr + 0x10200);
+#endif
 	/* Map PIC IRQs 0-11 */
-	openpic_set_sources(32, 12, OpenPIC_Addr + 0x10000);
+	openpic_set_sources(48, 12, OpenPIC_Addr + 0x10000);
 
 	/* we let openpic interrupts starting from an offset, to
 	 * leave space for cascading interrupts underneath.
@@ -475,26 +446,52 @@ mpc85xx_cds_setup_arch(void)
 #ifdef CONFIG_SERIAL_TEXT_DEBUG
 	/* Invalidate the entry we stole earlier the serial ports
 	 * should be properly mapped */
-	invalidate_tlbcam_entry(NUM_TLBCAMS - 1);
+	invalidate_tlbcam_entry(num_tlbcam_entries - 1);
 #endif
 
 	/* setup the board related information for the enet controllers */
 	pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1);
-	pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
-	pdata->interruptPHY = MPC85xx_IRQ_EXT5;
-	pdata->phyid = 0;
-	/* fixup phy address */
-	pdata->phy_reg_addr += binfo->bi_immr_base;
-	memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6);
+	if (pdata) {
+		pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
+		pdata->interruptPHY = MPC85xx_IRQ_EXT5;
+		pdata->phyid = 0;
+		/* fixup phy address */
+		pdata->phy_reg_addr += binfo->bi_immr_base;
+		memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6);
+	}
 
 	pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2);
-	pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
-	pdata->interruptPHY = MPC85xx_IRQ_EXT5;
-	pdata->phyid = 1;
-	/* fixup phy address */
-	pdata->phy_reg_addr += binfo->bi_immr_base;
-	memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6);
+	if (pdata) {
+		pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
+		pdata->interruptPHY = MPC85xx_IRQ_EXT5;
+		pdata->phyid = 1;
+		/* fixup phy address */
+		pdata->phy_reg_addr += binfo->bi_immr_base;
+		memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6);
+	}
+
+	pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_eTSEC1);
+	if (pdata) {
+		pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
+		pdata->interruptPHY = MPC85xx_IRQ_EXT5;
+		pdata->phyid = 0;
+		/* fixup phy address */
+		pdata->phy_reg_addr += binfo->bi_immr_base;
+		memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6);
+	}
+
+	pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_eTSEC2);
+	if (pdata) {
+		pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
+		pdata->interruptPHY = MPC85xx_IRQ_EXT5;
+		pdata->phyid = 1;
+		/* fixup phy address */
+		pdata->phy_reg_addr += binfo->bi_immr_base;
+		memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6);
+	}
 
+	ppc_sys_device_remove(MPC85xx_eTSEC3);
+	ppc_sys_device_remove(MPC85xx_eTSEC4);
 
 #ifdef CONFIG_BLK_DEV_INITRD
 	if (initrd_start)
@@ -531,7 +528,7 @@ platform_init(unsigned long r3, unsigned
 		struct uart_port p;
 
 		/* Use the last TLB entry to map CCSRBAR to allow access to DUART regs */
-		settlbcam(NUM_TLBCAMS - 1, binfo->bi_immr_base,
+		settlbcam(num_tlbcam_entries - 1, binfo->bi_immr_base,
 				binfo->bi_immr_base, MPC85xx_CCSRBAR_SIZE, _PAGE_IO, 0);
 
 		memset(&p, 0, sizeof (p));
diff --git a/arch/ppc/platforms/85xx/sbc8560.c b/arch/ppc/platforms/85xx/sbc8560.c
--- a/arch/ppc/platforms/85xx/sbc8560.c
+++ b/arch/ppc/platforms/85xx/sbc8560.c
@@ -41,7 +41,6 @@
 #include <asm/time.h>
 #include <asm/io.h>
 #include <asm/machdep.h>
-#include <asm/prom.h>
 #include <asm/open_pic.h>
 #include <asm/bootinfo.h>
 #include <asm/pci-bridge.h>
@@ -125,25 +124,29 @@ sbc8560_setup_arch(void)
 #ifdef CONFIG_SERIAL_TEXT_DEBUG
 	/* Invalidate the entry we stole earlier the serial ports
 	 * should be properly mapped */ 
-	invalidate_tlbcam_entry(NUM_TLBCAMS - 1);
+	invalidate_tlbcam_entry(num_tlbcam_entries - 1);
 #endif
 
 	/* setup the board related information for the enet controllers */
 	pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1);
-	pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
-	pdata->interruptPHY = MPC85xx_IRQ_EXT6;
-	pdata->phyid = 25;
-	/* fixup phy address */
-	pdata->phy_reg_addr += binfo->bi_immr_base;
-	memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6);
+	if (pdata) {
+		pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
+		pdata->interruptPHY = MPC85xx_IRQ_EXT6;
+		pdata->phyid = 25;
+		/* fixup phy address */
+		pdata->phy_reg_addr += binfo->bi_immr_base;
+		memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6);
+	}
 
 	pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2);
-	pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
-	pdata->interruptPHY = MPC85xx_IRQ_EXT7;
-	pdata->phyid = 26;
-	/* fixup phy address */
-	pdata->phy_reg_addr += binfo->bi_immr_base;
-	memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6);
+	if (pdata) {
+		pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
+		pdata->interruptPHY = MPC85xx_IRQ_EXT7;
+		pdata->phyid = 26;
+		/* fixup phy address */
+		pdata->phy_reg_addr += binfo->bi_immr_base;
+		memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6);
+	}
 
 #ifdef CONFIG_BLK_DEV_INITRD
 	if (initrd_start)
@@ -176,7 +179,7 @@ platform_init(unsigned long r3, unsigned
 
 #ifdef CONFIG_SERIAL_TEXT_DEBUG
 	/* Use the last TLB entry to map CCSRBAR to allow access to DUART regs */
-	settlbcam(NUM_TLBCAMS - 1, UARTA_ADDR,
+	settlbcam(num_tlbcam_entries - 1, UARTA_ADDR,
 		  UARTA_ADDR, 0x1000, _PAGE_IO, 0);
 #endif
 
diff --git a/arch/ppc/platforms/85xx/sbc85xx.c b/arch/ppc/platforms/85xx/sbc85xx.c
--- a/arch/ppc/platforms/85xx/sbc85xx.c
+++ b/arch/ppc/platforms/85xx/sbc85xx.c
@@ -35,7 +35,6 @@
 #include <asm/time.h>
 #include <asm/io.h>
 #include <asm/machdep.h>
-#include <asm/prom.h>
 #include <asm/open_pic.h>
 #include <asm/bootinfo.h>
 #include <asm/pci-bridge.h>
@@ -59,40 +58,8 @@ unsigned long pci_dram_offset = 0;
 extern unsigned long total_memory;	/* in mm/init */
 
 /* Internal interrupts are all Level Sensitive, and Positive Polarity */
-
 static u_char sbc8560_openpic_initsenses[] __initdata = {
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal  0: L2 Cache */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal  1: ECM */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal  2: DDR DRAM */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal  3: LBIU */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal  4: DMA 0 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal  5: DMA 1 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal  6: DMA 2 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal  7: DMA 3 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal  8: PCI/PCI-X */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal  9: RIO Inbound Port Write Error */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 10: RIO Doorbell Inbound */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 11: RIO Outbound Message */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 12: RIO Inbound Message */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 13: TSEC 0 Transmit */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 14: TSEC 0 Receive */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 15: Unused */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 16: Unused */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 17: Unused */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 18: TSEC 0 Receive/Transmit Error */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 19: TSEC 1 Transmit */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 20: TSEC 1 Receive */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 21: Unused */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 22: Unused */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 23: Unused */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 24: TSEC 1 Receive/Transmit Error */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 25: Fast Ethernet */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 26: DUART */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 27: I2C */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 28: Performance Monitor */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 29: Unused */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 30: CPM */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 31: Unused */
+	MPC85XX_INTERNAL_IRQ_SENSES,
 	0x0,				/* External  0: */
 	0x0,				/* External  1: */
 #if defined(CONFIG_PCI)
@@ -159,7 +126,7 @@ sbc8560_init_IRQ(void)
 	/* Skip reserved space and internal sources */
 	openpic_set_sources(0, 32, OpenPIC_Addr + 0x10200);
 	/* Map PIC IRQs 0-11 */
-	openpic_set_sources(32, 12, OpenPIC_Addr + 0x10000);
+	openpic_set_sources(48, 12, OpenPIC_Addr + 0x10000);
 
 	/* we let openpic interrupts starting from an offset, to 
 	 * leave space for cascading interrupts underneath.
diff --git a/arch/ppc/platforms/85xx/stx_gp3.c b/arch/ppc/platforms/85xx/stx_gp3.c
--- a/arch/ppc/platforms/85xx/stx_gp3.c
+++ b/arch/ppc/platforms/85xx/stx_gp3.c
@@ -46,21 +46,19 @@
 #include <asm/time.h>
 #include <asm/io.h>
 #include <asm/machdep.h>
-#include <asm/prom.h>
 #include <asm/open_pic.h>
 #include <asm/bootinfo.h>
 #include <asm/pci-bridge.h>
 #include <asm/mpc85xx.h>
 #include <asm/irq.h>
 #include <asm/immap_85xx.h>
-#include <asm/immap_cpm2.h>
+#include <asm/cpm2.h>
 #include <asm/mpc85xx.h>
 #include <asm/ppc_sys.h>
 
 #include <syslib/cpm2_pic.h>
 #include <syslib/ppc85xx_common.h>
 
-extern void cpm2_reset(void);
 
 unsigned char __res[sizeof(bd_t)];
 
@@ -72,38 +70,7 @@ unsigned long pci_dram_offset = 0;
 
 /* Internal interrupts are all Level Sensitive, and Positive Polarity */
 static u8 gp3_openpic_initsenses[] __initdata = {
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal  0: L2 Cache */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal  1: ECM */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal  2: DDR DRAM */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal  3: LBIU */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal  4: DMA 0 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal  5: DMA 1 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal  6: DMA 2 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal  7: DMA 3 */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal  8: PCI/PCI-X */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal  9: RIO Inbound Port Write Error */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 10: RIO Doorbell Inbound */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 11: RIO Outbound Message */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 12: RIO Inbound Message */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 13: TSEC 0 Transmit */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 14: TSEC 0 Receive */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 15: Unused */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 16: Unused */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 17: Unused */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 18: TSEC 0 Receive/Transmit Error */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 19: TSEC 1 Transmit */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 20: TSEC 1 Receive */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 21: Unused */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 22: Unused */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 23: Unused */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 24: TSEC 1 Receive/Transmit Error */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 25: Fast Ethernet */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 26: DUART */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 27: I2C */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 28: Performance Monitor */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 29: Unused */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 30: CPM */
-	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 31: Unused */
+	MPC85XX_INTERNAL_IRQ_SENSES,
 	0x0,						/* External  0: */
 #if defined(CONFIG_PCI)
 	(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),	/* External 1: PCI slot 0 */
@@ -154,19 +121,23 @@ gp3_setup_arch(void)
 
 	/* setup the board related information for the enet controllers */
 	pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1);
-/*	pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; */
-	pdata->interruptPHY = MPC85xx_IRQ_EXT5;
-	pdata->phyid = 2;
-	pdata->phy_reg_addr += binfo->bi_immr_base;
-	memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6);
+	if (pdata) {
+	/*	pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; */
+		pdata->interruptPHY = MPC85xx_IRQ_EXT5;
+		pdata->phyid = 2;
+		pdata->phy_reg_addr += binfo->bi_immr_base;
+		memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6);
+	}
 
 	pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2);
-/*	pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; */
-	pdata->interruptPHY = MPC85xx_IRQ_EXT5;
-	pdata->phyid = 4;
-	/* fixup phy address */
-	pdata->phy_reg_addr += binfo->bi_immr_base;
-	memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6);
+	if (pdata) {
+	/*	pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; */
+		pdata->interruptPHY = MPC85xx_IRQ_EXT5;
+		pdata->phyid = 4;
+		/* fixup phy address */
+		pdata->phy_reg_addr += binfo->bi_immr_base;
+		memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6);
+	}
 
 #ifdef CONFIG_BLK_DEV_INITRD
 	if (initrd_start)
@@ -200,7 +171,6 @@ static struct irqaction cpm2_irqaction =
 static void __init
 gp3_init_IRQ(void)
 {
-	int i;
 	bd_t *binfo = (bd_t *) __res;
 
 	/*
@@ -218,7 +188,7 @@ gp3_init_IRQ(void)
 	openpic_set_sources(0, 32, OpenPIC_Addr + 0x10200);
 
 	/* Map PIC IRQs 0-11 */
-	openpic_set_sources(32, 12, OpenPIC_Addr + 0x10000);
+	openpic_set_sources(48, 12, OpenPIC_Addr + 0x10000);
 
 	/*
 	 * Let openpic interrupts starting from an offset, to
diff --git a/arch/ppc/platforms/chrp_pci.c b/arch/ppc/platforms/chrp_pci.c
--- a/arch/ppc/platforms/chrp_pci.c
+++ b/arch/ppc/platforms/chrp_pci.c
@@ -9,7 +9,6 @@
 #include <linux/string.h>
 #include <linux/init.h>
 #include <linux/ide.h>
-#include <linux/bootmem.h>
 
 #include <asm/io.h>
 #include <asm/pgtable.h>
diff --git a/arch/ppc/platforms/fads.h b/arch/ppc/platforms/fads.h
--- a/arch/ppc/platforms/fads.h
+++ b/arch/ppc/platforms/fads.h
@@ -3,7 +3,18 @@
  * the Motorola 860T FADS board.  Copied from the MBX stuff.
  *
  * Copyright (c) 1998 Dan Malek (dmalek@jlc.net)
+ *
+ * Added MPC86XADS support.
+ * The MPC86xADS manual says the board "is compatible with the MPC8xxFADS
+ * for SW point of view". This is 99% correct.
+ *
+ * Author: MontaVista Software, Inc.
+ *         source@mvista.com
+ * 2005 (c) MontaVista Software, Inc.  This file is licensed under the
+ * terms of the GNU General Public License version 2.  This program is licensed
+ * "as is" without any warranty of any kind, whether express or implied.
  */
+
 #ifdef __KERNEL__
 #ifndef __ASM_FADS_H__
 #define __ASM_FADS_H__
@@ -12,18 +23,45 @@
 
 #include <asm/ppcboot.h>
 
+#if defined(CONFIG_MPC86XADS)
+
+/* U-Boot maps BCSR to 0xff080000 */
+#define BCSR_ADDR		((uint)0xff080000)
+
+/* MPC86XADS has one more CPLD and an additional BCSR.
+ */
+#define CFG_PHYDEV_ADDR		((uint)0xff0a0000)
+#define BCSR5			((uint)(CFG_PHYDEV_ADDR + 0x300))
+
+#define BCSR5_T1_RST		0x10
+#define BCSR5_ATM155_RST	0x08
+#define BCSR5_ATM25_RST		0x04
+#define BCSR5_MII1_EN		0x02
+#define BCSR5_MII1_RST		0x01
+
+/* There is no PHY link change interrupt */
+#define PHY_INTERRUPT	(-1)
+
+#else /* FADS */
+
 /* Memory map is configured by the PROM startup.
  * I tried to follow the FADS manual, although the startup PROM
  * dictates this and we simply have to move some of the physical
  * addresses for Linux.
  */
 #define BCSR_ADDR		((uint)0xff010000)
+
+/* PHY link change interrupt */
+#define PHY_INTERRUPT	SIU_IRQ2
+
+#endif /* CONFIG_MPC86XADS */
+
 #define BCSR_SIZE		((uint)(64 * 1024))
-#define	BCSR0			((uint)0xff010000)
-#define	BCSR1			((uint)0xff010004)
-#define	BCSR2			((uint)0xff010008)
-#define	BCSR3			((uint)0xff01000c)
-#define	BCSR4			((uint)0xff010010)
+#define BCSR0			((uint)(BCSR_ADDR + 0x00))
+#define BCSR1			((uint)(BCSR_ADDR + 0x04))
+#define BCSR2			((uint)(BCSR_ADDR + 0x08))
+#define BCSR3			((uint)(BCSR_ADDR + 0x0c))
+#define BCSR4			((uint)(BCSR_ADDR + 0x10))
 
 #define IMAP_ADDR		((uint)0xff000000)
 #define IMAP_SIZE		((uint)(64 * 1024))
@@ -34,8 +72,17 @@
 /* Bits of interest in the BCSRs.
  */
 #define BCSR1_ETHEN		((uint)0x20000000)
+#define BCSR1_IRDAEN		((uint)0x10000000)
 #define BCSR1_RS232EN_1		((uint)0x01000000)
+#define BCSR1_PCCEN		((uint)0x00800000)
+#define BCSR1_PCCVCC0		((uint)0x00400000)
+#define BCSR1_PCCVPP0		((uint)0x00200000)
+#define BCSR1_PCCVPP1		((uint)0x00100000)
+#define BCSR1_PCCVPP_MASK	(BCSR1_PCCVPP0 | BCSR1_PCCVPP1)
 #define BCSR1_RS232EN_2		((uint)0x00040000)
+#define BCSR1_PCCVCC1		((uint)0x00010000)
+#define BCSR1_PCCVCC_MASK	(BCSR1_PCCVCC0 | BCSR1_PCCVCC1)
+
 #define BCSR4_ETHLOOP		((uint)0x80000000)	/* EEST Loopback */
 #define BCSR4_EEFDX		((uint)0x40000000)	/* EEST FDX enable */
 #define BCSR4_FETH_EN		((uint)0x08000000)	/* PHY enable */
@@ -44,14 +91,64 @@
 #define BCSR4_FETHFDE		((uint)0x02000000)	/* PHY FDX advertise */
 #define BCSR4_FETHRST		((uint)0x00200000)	/* PHY Reset */
 
+/* IO_BASE definition for pcmcia.
+ */
+#define _IO_BASE	0x80000000
+#define _IO_BASE_SIZE	0x1000
+
+#ifdef CONFIG_IDE
+#define MAX_HWIFS 1
+#endif
+
 /* Interrupt level assignments.
  */
 #define FEC_INTERRUPT	SIU_LEVEL1	/* FEC interrupt */
-#define PHY_INTERRUPT	SIU_IRQ2	/* PHY link change interrupt */
 
 /* We don't use the 8259.
  */
 #define NR_8259_INTS	0
 
+/* CPM Ethernet through SCC1 or SCC2 */
+
+#ifdef CONFIG_SCC1_ENET		/* Probably 860 variant */
+/* Bits in parallel I/O port registers that have to be set/cleared
+ * to configure the pins for SCC1 use.
+ * TCLK - CLK1, RCLK - CLK2.
+ */
+#define PA_ENET_RXD	((ushort)0x0001)
+#define PA_ENET_TXD	((ushort)0x0002)
+#define PA_ENET_TCLK	((ushort)0x0100)
+#define PA_ENET_RCLK	((ushort)0x0200)
+#define PB_ENET_TENA	((uint)0x00001000)
+#define PC_ENET_CLSN	((ushort)0x0010)
+#define PC_ENET_RENA	((ushort)0x0020)
+
+/* Control bits in the SICR to route TCLK (CLK1) and RCLK (CLK2) to
+ * SCC1.  Also, make sure GR1 (bit 24) and SC1 (bit 25) are zero.
+ */
+#define SICR_ENET_MASK	((uint)0x000000ff)
+#define SICR_ENET_CLKRT	((uint)0x0000002c)
+#endif /* CONFIG_SCC1_ENET */
+
+#ifdef CONFIG_SCC2_ENET		/* Probably 823/850 variant */
+/* Bits in parallel I/O port registers that have to be set/cleared
+ * to configure the pins for SCC1 use.
+ * TCLK - CLK1, RCLK - CLK2.
+ */
+#define PA_ENET_RXD	((ushort)0x0004)
+#define PA_ENET_TXD	((ushort)0x0008)
+#define PA_ENET_TCLK	((ushort)0x0400)
+#define PA_ENET_RCLK	((ushort)0x0200)
+#define PB_ENET_TENA	((uint)0x00002000)
+#define PC_ENET_CLSN	((ushort)0x0040)
+#define PC_ENET_RENA	((ushort)0x0080)
+
+/* Control bits in the SICR to route TCLK and RCLK to
+ * SCC2.  Also, make sure GR1 (bit 24) and SC1 (bit 25) are zero.
+ */
+#define SICR_ENET_MASK	((uint)0x0000ff00)
+#define SICR_ENET_CLKRT	((uint)0x00002e00)
+#endif /* CONFIG_SCC2_ENET */
+
 #endif /* __ASM_FADS_H__ */
 #endif /* __KERNEL__ */
diff --git a/arch/ppc/platforms/katana.c b/arch/ppc/platforms/katana.c
--- a/arch/ppc/platforms/katana.c
+++ b/arch/ppc/platforms/katana.c
@@ -27,12 +27,12 @@
 #include <linux/root_dev.h>
 #include <linux/delay.h>
 #include <linux/seq_file.h>
-#include <linux/bootmem.h>
 #include <linux/mtd/physmap.h>
 #include <linux/mv643xx.h>
 #ifdef CONFIG_BOOTIMG
 #include <linux/bootimg.h>
 #endif
+#include <asm/io.h>
 #include <asm/page.h>
 #include <asm/time.h>
 #include <asm/smp.h>
diff --git a/arch/ppc/platforms/mpc885ads.h b/arch/ppc/platforms/mpc885ads.h
new file mode 100644
--- /dev/null
+++ b/arch/ppc/platforms/mpc885ads.h
@@ -0,0 +1,92 @@
+/*
+ * A collection of structures, addresses, and values associated with
+ * the Freescale MPC885ADS board.
+ * Copied from the FADS stuff.
+ *
+ * Author: MontaVista Software, Inc.
+ *         source@mvista.com
+ *
+ * 2005 (c) MontaVista Software, Inc.  This file is licensed under the
+ * terms of the GNU General Public License version 2.  This program is licensed
+ * "as is" without any warranty of any kind, whether express or implied.
+ */
+
+#ifdef __KERNEL__
+#ifndef __ASM_MPC885ADS_H__
+#define __ASM_MPC885ADS_H__
+
+#include <linux/config.h>
+
+#include <asm/ppcboot.h>
+
+/* U-Boot maps BCSR to 0xff080000 */
+#define BCSR_ADDR		((uint)0xff080000)
+#define BCSR_SIZE		((uint)32)
+#define BCSR0			((uint)(BCSR_ADDR + 0x00))
+#define BCSR1			((uint)(BCSR_ADDR + 0x04))
+#define BCSR2			((uint)(BCSR_ADDR + 0x08))
+#define BCSR3			((uint)(BCSR_ADDR + 0x0c))
+#define BCSR4			((uint)(BCSR_ADDR + 0x10))
+
+#define CFG_PHYDEV_ADDR		((uint)0xff0a0000)
+#define BCSR5			((uint)(CFG_PHYDEV_ADDR + 0x300))
+
+#define IMAP_ADDR		((uint)0xff000000)
+#define IMAP_SIZE		((uint)(64 * 1024))
+
+#define PCMCIA_MEM_ADDR		((uint)0xff020000)
+#define PCMCIA_MEM_SIZE		((uint)(64 * 1024))
+
+/* Bits of interest in the BCSRs.
+ */
+#define BCSR1_ETHEN		((uint)0x20000000)
+#define BCSR1_IRDAEN		((uint)0x10000000)
+#define BCSR1_RS232EN_1		((uint)0x01000000)
+#define BCSR1_PCCEN		((uint)0x00800000)
+#define BCSR1_PCCVCC0		((uint)0x00400000)
+#define BCSR1_PCCVPP0		((uint)0x00200000)
+#define BCSR1_PCCVPP1		((uint)0x00100000)
+#define BCSR1_PCCVPP_MASK	(BCSR1_PCCVPP0 | BCSR1_PCCVPP1)
+#define BCSR1_RS232EN_2		((uint)0x00040000)
+#define BCSR1_PCCVCC1		((uint)0x00010000)
+#define BCSR1_PCCVCC_MASK	(BCSR1_PCCVCC0 | BCSR1_PCCVCC1)
+
+#define BCSR4_ETH10_RST		((uint)0x80000000)	/* 10Base-T PHY reset*/
+#define BCSR4_USB_LO_SPD	((uint)0x04000000)
+#define BCSR4_USB_VCC		((uint)0x02000000)
+#define BCSR4_USB_FULL_SPD	((uint)0x00040000)
+#define BCSR4_USB_EN		((uint)0x00020000)
+
+#define BCSR5_MII2_EN		0x40
+#define BCSR5_MII2_RST		0x20
+#define BCSR5_T1_RST		0x10
+#define BCSR5_ATM155_RST	0x08
+#define BCSR5_ATM25_RST		0x04
+#define BCSR5_MII1_EN		0x02
+#define BCSR5_MII1_RST		0x01
+
+/* Interrupt level assignments */
+#define PHY_INTERRUPT	SIU_IRQ7	/* PHY link change interrupt */
+#define SIU_INT_FEC1	SIU_LEVEL1	/* FEC1 interrupt */
+#define SIU_INT_FEC2	SIU_LEVEL3	/* FEC2 interrupt */
+#define FEC_INTERRUPT	SIU_INT_FEC1	/* FEC interrupt */
+
+/* We don't use the 8259 */
+#define NR_8259_INTS	0
+
+/* CPM Ethernet through SCC3 */
+#define PA_ENET_RXD	((ushort)0x0040)
+#define PA_ENET_TXD	((ushort)0x0080)
+#define PE_ENET_TCLK	((uint)0x00004000)
+#define PE_ENET_RCLK	((uint)0x00008000)
+#define PE_ENET_TENA	((uint)0x00000010)
+#define PC_ENET_CLSN	((ushort)0x0400)
+#define PC_ENET_RENA	((ushort)0x0800)
+
+/* Control bits in the SICR to route TCLK (CLK5) and RCLK (CLK6) to
+ * SCC3.  Also, make sure GR3 (bit 8) and SC3 (bit 9) are zero */
+#define SICR_ENET_MASK	((uint)0x00ff0000)
+#define SICR_ENET_CLKRT	((uint)0x002c0000)
+
+#endif /* __ASM_MPC885ADS_H__ */
+#endif /* __KERNEL__ */
diff --git a/arch/ppc/platforms/pmac_cpufreq.c b/arch/ppc/platforms/pmac_cpufreq.c
--- a/arch/ppc/platforms/pmac_cpufreq.c
+++ b/arch/ppc/platforms/pmac_cpufreq.c
@@ -452,7 +452,7 @@ static u32 __pmac read_gpio(struct devic
 	return offset;
 }
 
-static int __pmac pmac_cpufreq_suspend(struct cpufreq_policy *policy, u32 state)
+static int __pmac pmac_cpufreq_suspend(struct cpufreq_policy *policy, pm_message_t pmsg)
 {
 	/* Ok, this could be made a bit smarter, but let's be robust for now. We
 	 * always force a speed change to high speed before sleep, to make sure
diff --git a/arch/ppc/platforms/pmac_pci.c b/arch/ppc/platforms/pmac_pci.c
--- a/arch/ppc/platforms/pmac_pci.c
+++ b/arch/ppc/platforms/pmac_pci.c
@@ -17,7 +17,6 @@
 #include <linux/delay.h>
 #include <linux/string.h>
 #include <linux/init.h>
-#include <linux/bootmem.h>
 
 #include <asm/sections.h>
 #include <asm/io.h>
diff --git a/arch/ppc/platforms/pmac_setup.c b/arch/ppc/platforms/pmac_setup.c
--- a/arch/ppc/platforms/pmac_setup.c
+++ b/arch/ppc/platforms/pmac_setup.c
@@ -113,7 +113,7 @@ extern int pmac_newworld;
 extern void zs_kgdb_hook(int tty_num);
 static void ohare_init(void);
 #ifdef CONFIG_BOOTX_TEXT
-void pmac_progress(char *s, unsigned short hex);
+static void pmac_progress(char *s, unsigned short hex);
 #endif
 
 sys_ctrler_t sys_ctrler = SYS_CTRLER_UNKNOWN;
@@ -123,7 +123,7 @@ extern struct smp_ops_t psurge_smp_ops;
 extern struct smp_ops_t core99_smp_ops;
 #endif /* CONFIG_SMP */
 
-int __pmac
+static int __pmac
 pmac_show_cpuinfo(struct seq_file *m)
 {
 	struct device_node *np;
@@ -227,7 +227,7 @@ pmac_show_cpuinfo(struct seq_file *m)
 	return 0;
 }
 
-int __openfirmware
+static int __openfirmware
 pmac_show_percpuinfo(struct seq_file *m, int i)
 {
 #ifdef CONFIG_CPU_FREQ_PMAC
@@ -415,7 +415,7 @@ find_ide_boot(void)
 }
 #endif /* CONFIG_BLK_DEV_IDE && CONFIG_BLK_DEV_IDE_PMAC */
 
-void __init
+static void __init
 find_boot_device(void)
 {
 #if defined(CONFIG_BLK_DEV_IDE) && defined(CONFIG_BLK_DEV_IDE_PMAC)
@@ -512,7 +512,7 @@ note_bootable_part(dev_t dev, int part, 
 	}
 }
 
-void __pmac
+static void __pmac
 pmac_restart(char *cmd)
 {
 #ifdef CONFIG_ADB_CUDA
@@ -537,7 +537,7 @@ pmac_restart(char *cmd)
 	}
 }
 
-void __pmac
+static void __pmac
 pmac_power_off(void)
 {
 #ifdef CONFIG_ADB_CUDA
@@ -562,7 +562,7 @@ pmac_power_off(void)
 	}
 }
 
-void __pmac
+static void __pmac
 pmac_halt(void)
 {
    pmac_power_off();
@@ -700,7 +700,7 @@ pmac_init(unsigned long r3, unsigned lon
 }
 
 #ifdef CONFIG_BOOTX_TEXT
-void __init
+static void __init
 pmac_progress(char *s, unsigned short hex)
 {
 	if (boot_text_mapped) {
diff --git a/arch/ppc/platforms/pmac_sleep.S b/arch/ppc/platforms/pmac_sleep.S
--- a/arch/ppc/platforms/pmac_sleep.S
+++ b/arch/ppc/platforms/pmac_sleep.S
@@ -46,7 +46,7 @@
 	.section .text
 	.align	5
 
-#if defined(CONFIG_PMAC_PBOOK) || defined(CONFIG_CPU_FREQ_PMAC)
+#if defined(CONFIG_PM) || defined(CONFIG_CPU_FREQ_PMAC)
 
 /* This gets called by via-pmu.c late during the sleep process.
  * The PMU was already send the sleep command and will shut us down
@@ -382,7 +382,7 @@ turn_on_mmu:
 	isync
 	rfi
 
-#endif /* defined(CONFIG_PMAC_PBOOK) || defined(CONFIG_CPU_FREQ) */
+#endif /* defined(CONFIG_PM) || defined(CONFIG_CPU_FREQ) */
 
 	.section .data
 	.balign	L1_CACHE_LINE_SIZE
diff --git a/arch/ppc/platforms/pmac_time.c b/arch/ppc/platforms/pmac_time.c
--- a/arch/ppc/platforms/pmac_time.c
+++ b/arch/ppc/platforms/pmac_time.c
@@ -206,7 +206,7 @@ via_calibrate_decr(void)
 	return 1;
 }
 
-#ifdef CONFIG_PMAC_PBOOK
+#ifdef CONFIG_PM
 /*
  * Reset the time after a sleep.
  */
@@ -238,7 +238,7 @@ time_sleep_notify(struct pmu_sleep_notif
 static struct pmu_sleep_notifier time_sleep_notifier __pmacdata = {
 	time_sleep_notify, SLEEP_LEVEL_MISC,
 };
-#endif /* CONFIG_PMAC_PBOOK */
+#endif /* CONFIG_PM */
 
 /*
  * Query the OF and get the decr frequency.
@@ -251,9 +251,9 @@ pmac_calibrate_decr(void)
 	struct device_node *cpu;
 	unsigned int freq, *fp;
 
-#ifdef CONFIG_PMAC_PBOOK
+#ifdef CONFIG_PM
 	pmu_register_sleep_notifier(&time_sleep_notifier);
-#endif /* CONFIG_PMAC_PBOOK */
+#endif /* CONFIG_PM */
 
 	/* We assume MacRISC2 machines have correct device-tree
 	 * calibration. That's better since the VIA itself seems
diff --git a/arch/ppc/platforms/prpmc750.c b/arch/ppc/platforms/prpmc750.c
--- a/arch/ppc/platforms/prpmc750.c
+++ b/arch/ppc/platforms/prpmc750.c
@@ -29,6 +29,7 @@
 #include <linux/ide.h>
 #include <linux/root_dev.h>
 #include <linux/slab.h>
+#include <linux/serial_reg.h>
 
 #include <asm/byteorder.h>
 #include <asm/system.h>
diff --git a/arch/ppc/platforms/sandpoint.c b/arch/ppc/platforms/sandpoint.c
--- a/arch/ppc/platforms/sandpoint.c
+++ b/arch/ppc/platforms/sandpoint.c
@@ -81,6 +81,7 @@
 #include <linux/serial.h>
 #include <linux/tty.h>	/* for linux/serial_core.h */
 #include <linux/serial_core.h>
+#include <linux/serial_8250.h>
 
 #include <asm/system.h>
 #include <asm/pgtable.h>
@@ -99,6 +100,7 @@
 #include <asm/mpc10x.h>
 #include <asm/pci-bridge.h>
 #include <asm/kgdb.h>
+#include <asm/ppc_sys.h>
 
 #include "sandpoint.h"
 
@@ -305,6 +307,28 @@ sandpoint_setup_arch(void)
 	/* Lookup PCI host bridges */
 	sandpoint_find_bridges();
 
+	if (strncmp (cur_ppc_sys_spec->ppc_sys_name, "8245", 4) == 0)
+	{
+		bd_t *bp = (bd_t *)__res;
+		struct plat_serial8250_port *pdata;
+
+		pdata = (struct plat_serial8250_port *) ppc_sys_get_pdata(MPC10X_UART0);
+		if (pdata)
+		{
+			pdata[0].uartclk = bp->bi_busfreq;
+		}
+
+#ifdef CONFIG_SANDPOINT_ENABLE_UART1
+		pdata = (struct plat_serial8250_port *) ppc_sys_get_pdata(MPC10X_UART1);
+		if (pdata)
+		{
+			pdata[0].uartclk = bp->bi_busfreq;
+		}
+#else
+		ppc_sys_device_remove(MPC10X_UART1);
+#endif
+	}
+
 	printk(KERN_INFO "Motorola SPS Sandpoint Test Platform\n");
 	printk(KERN_INFO "Port by MontaVista Software, Inc. (source@mvista.com)\n");
 
diff --git a/arch/ppc/platforms/tqm8260_setup.c b/arch/ppc/platforms/tqm8260_setup.c
--- a/arch/ppc/platforms/tqm8260_setup.c
+++ b/arch/ppc/platforms/tqm8260_setup.c
@@ -16,8 +16,8 @@
 
 #include <linux/init.h>
 
-#include <asm/immap_cpm2.h>
 #include <asm/mpc8260.h>
+#include <asm/cpm2.h>
 #include <asm/machdep.h>
 
 static int
diff --git a/arch/ppc/syslib/Makefile b/arch/ppc/syslib/Makefile
--- a/arch/ppc/syslib/Makefile
+++ b/arch/ppc/syslib/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_PPCBUG_NVRAM)	+= prep_nvram
 obj-$(CONFIG_PPC_OCP)		+= ocp.o
 obj-$(CONFIG_IBM_OCP)		+= ibm_ocp.o
 obj-$(CONFIG_44x)		+= ibm44x_common.o
+obj-$(CONFIG_440EP)		+= ibm440gx_common.o
 obj-$(CONFIG_440GP)		+= ibm440gp_common.o
 obj-$(CONFIG_440GX)		+= ibm440gx_common.o
 obj-$(CONFIG_440SP)		+= ibm440gx_common.o ibm440sp_common.o
@@ -44,6 +45,7 @@ obj-$(CONFIG_PPC_CHRP)		+= open_pic.o in
 obj-$(CONFIG_PPC_PREP)		+= open_pic.o indirect_pci.o i8259.o todc_time.o
 obj-$(CONFIG_ADIR)		+= i8259.o indirect_pci.o pci_auto.o \
 					todc_time.o
+obj-$(CONFIG_BAMBOO)		+= indirect_pci.o pci_auto.o todc_time.o
 obj-$(CONFIG_CPCI690)		+= todc_time.o pci_auto.o
 obj-$(CONFIG_EBONY)		+= indirect_pci.o pci_auto.o todc_time.o
 obj-$(CONFIG_EV64260)		+= todc_time.o pci_auto.o
@@ -92,7 +94,7 @@ ifeq ($(CONFIG_SERIAL_MPSC_CONSOLE),y)
 obj-$(CONFIG_SERIAL_TEXT_DEBUG)	+= mv64x60_dbg.o
 endif
 obj-$(CONFIG_BOOTX_TEXT)	+= btext.o
-obj-$(CONFIG_MPC10X_BRIDGE)     += mpc10x_common.o indirect_pci.o
+obj-$(CONFIG_MPC10X_BRIDGE)	+= mpc10x_common.o indirect_pci.o ppc_sys.o
 obj-$(CONFIG_MPC10X_OPENPIC)	+= open_pic.o
 obj-$(CONFIG_40x)		+= dcr.o
 obj-$(CONFIG_BOOKE)		+= dcr.o
@@ -107,6 +109,7 @@ obj-$(CONFIG_83xx)		+= ipic.o ppc83xx_se
 ifeq ($(CONFIG_83xx),y)
 obj-$(CONFIG_PCI)		+= indirect_pci.o pci_auto.o
 endif
+obj-$(CONFIG_MPC8548_CDS)	+= todc_time.o
 obj-$(CONFIG_MPC8555_CDS)	+= todc_time.o
 obj-$(CONFIG_PPC_MPC52xx)	+= mpc52xx_setup.o mpc52xx_pic.o \
 					mpc52xx_sys.o mpc52xx_devices.o ppc_sys.o
diff --git a/arch/ppc/syslib/cpm2_common.c b/arch/ppc/syslib/cpm2_common.c
--- a/arch/ppc/syslib/cpm2_common.c
+++ b/arch/ppc/syslib/cpm2_common.c
@@ -21,13 +21,12 @@
 #include <linux/string.h>
 #include <linux/mm.h>
 #include <linux/interrupt.h>
-#include <linux/bootmem.h>
 #include <linux/module.h>
+#include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/mpc8260.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
-#include <asm/immap_cpm2.h>
 #include <asm/cpm2.h>
 #include <asm/rheap.h>
 
diff --git a/arch/ppc/syslib/ibm440gx_common.c b/arch/ppc/syslib/ibm440gx_common.c
--- a/arch/ppc/syslib/ibm440gx_common.c
+++ b/arch/ppc/syslib/ibm440gx_common.c
@@ -34,6 +34,10 @@ void __init ibm440gx_get_clocks(struct i
 	u32 plld  = CPR_READ(DCRN_CPR_PLLD);
 	u32 uart0 = SDR_READ(DCRN_SDR_UART0);
 	u32 uart1 = SDR_READ(DCRN_SDR_UART1);
+#ifdef CONFIG_440EP
+	u32 uart2 = SDR_READ(DCRN_SDR_UART2);
+	u32 uart3 = SDR_READ(DCRN_SDR_UART3);
+#endif
 
 	/* Dividers */
 	u32 fbdv   = __fix_zero((plld >> 24) & 0x1f, 32);
@@ -96,6 +100,17 @@ bypass:
 		p->uart1 = ser_clk;
 	else
 		p->uart1 = p->plb / __fix_zero(uart1 & 0xff, 256);
+#ifdef CONFIG_440EP
+	if (uart2 & 0x00800000)
+		p->uart2 = ser_clk;
+	else
+		p->uart2 = p->plb / __fix_zero(uart2 & 0xff, 256);
+
+	if (uart3 & 0x00800000)
+		p->uart3 = ser_clk;
+	else
+		p->uart3 = p->plb / __fix_zero(uart3 & 0xff, 256);
+#endif
 }
 
 /* Issue L2C diagnostic command */
diff --git a/arch/ppc/syslib/ibm44x_common.h b/arch/ppc/syslib/ibm44x_common.h
--- a/arch/ppc/syslib/ibm44x_common.h
+++ b/arch/ppc/syslib/ibm44x_common.h
@@ -29,6 +29,10 @@ struct ibm44x_clocks {
 	unsigned int ebc;	/* PerClk */
 	unsigned int uart0;
 	unsigned int uart1;
+#ifdef CONFIG_440EP
+	unsigned int uart2;
+	unsigned int uart3;
+#endif
 };
 
 /* common 44x platform init */
diff --git a/arch/ppc/syslib/indirect_pci.c b/arch/ppc/syslib/indirect_pci.c
--- a/arch/ppc/syslib/indirect_pci.c
+++ b/arch/ppc/syslib/indirect_pci.c
@@ -14,7 +14,6 @@
 #include <linux/delay.h>
 #include <linux/string.h>
 #include <linux/init.h>
-#include <linux/bootmem.h>
 
 #include <asm/io.h>
 #include <asm/prom.h>
diff --git a/arch/ppc/syslib/ipic.c b/arch/ppc/syslib/ipic.c
--- a/arch/ppc/syslib/ipic.c
+++ b/arch/ppc/syslib/ipic.c
@@ -79,7 +79,7 @@ static struct ipic_info ipic_info[] = {
 		.prio_mask = 7,
 	},
 	[17] = {
-		.pend	= IPIC_SIPNR_H,
+		.pend	= IPIC_SEPNR,
 		.mask	= IPIC_SEMSR,
 		.prio	= IPIC_SMPRR_A,
 		.force	= IPIC_SEFCR,
@@ -87,7 +87,7 @@ static struct ipic_info ipic_info[] = {
 		.prio_mask = 5,
 	},
 	[18] = {
-		.pend	= IPIC_SIPNR_H,
+		.pend	= IPIC_SEPNR,
 		.mask	= IPIC_SEMSR,
 		.prio	= IPIC_SMPRR_A,
 		.force	= IPIC_SEFCR,
@@ -95,7 +95,7 @@ static struct ipic_info ipic_info[] = {
 		.prio_mask = 6,
 	},
 	[19] = {
-		.pend	= IPIC_SIPNR_H,
+		.pend	= IPIC_SEPNR,
 		.mask	= IPIC_SEMSR,
 		.prio	= IPIC_SMPRR_A,
 		.force	= IPIC_SEFCR,
@@ -103,7 +103,7 @@ static struct ipic_info ipic_info[] = {
 		.prio_mask = 7,
 	},
 	[20] = {
-		.pend	= IPIC_SIPNR_H,
+		.pend	= IPIC_SEPNR,
 		.mask	= IPIC_SEMSR,
 		.prio	= IPIC_SMPRR_B,
 		.force	= IPIC_SEFCR,
@@ -111,7 +111,7 @@ static struct ipic_info ipic_info[] = {
 		.prio_mask = 4,
 	},
 	[21] = {
-		.pend	= IPIC_SIPNR_H,
+		.pend	= IPIC_SEPNR,
 		.mask	= IPIC_SEMSR,
 		.prio	= IPIC_SMPRR_B,
 		.force	= IPIC_SEFCR,
@@ -119,7 +119,7 @@ static struct ipic_info ipic_info[] = {
 		.prio_mask = 5,
 	},
 	[22] = {
-		.pend	= IPIC_SIPNR_H,
+		.pend	= IPIC_SEPNR,
 		.mask	= IPIC_SEMSR,
 		.prio	= IPIC_SMPRR_B,
 		.force	= IPIC_SEFCR,
@@ -127,7 +127,7 @@ static struct ipic_info ipic_info[] = {
 		.prio_mask = 6,
 	},
 	[23] = {
-		.pend	= IPIC_SIPNR_H,
+		.pend	= IPIC_SEPNR,
 		.mask	= IPIC_SEMSR,
 		.prio	= IPIC_SMPRR_B,
 		.force	= IPIC_SEFCR,
diff --git a/arch/ppc/syslib/m8260_setup.c b/arch/ppc/syslib/m8260_setup.c
--- a/arch/ppc/syslib/m8260_setup.c
+++ b/arch/ppc/syslib/m8260_setup.c
@@ -24,7 +24,7 @@
 #include <asm/io.h>
 #include <asm/pgtable.h>
 #include <asm/mpc8260.h>
-#include <asm/immap_cpm2.h>
+#include <asm/cpm2.h>
 #include <asm/machdep.h>
 #include <asm/bootinfo.h>
 #include <asm/time.h>
@@ -33,7 +33,6 @@
 
 unsigned char __res[sizeof(bd_t)];
 
-extern void cpm2_reset(void);
 extern void pq2_find_bridges(void);
 extern void pq2pci_init_irq(void);
 extern void idma_pci9_init(void);
diff --git a/arch/ppc/syslib/m82xx_pci.c b/arch/ppc/syslib/m82xx_pci.c
--- a/arch/ppc/syslib/m82xx_pci.c
+++ b/arch/ppc/syslib/m82xx_pci.c
@@ -238,9 +238,9 @@ pq2ads_setup_pci(struct pci_controller *
 	 * Setting required to enable IRQ1-IRQ7 (SIUMCR [DPPC]),
 	 * and local bus for PCI (SIUMCR [LBPC]).
 	 */
-	immap->im_siu_conf.siu_82xx.sc_siumcr = (immap->im_siu_conf.sc_siumcr &
-				~(SIUMCR_L2PC11 | SIUMCR_LBPC11 | SIUMCR_CS10PC11 | SIUMCR_APPC11) |
-				SIUMCR_BBD | SIUMCR_LBPC01 | SIUMCR_DPPC11 | SIUMCR_APPC10;
+	immap->im_siu_conf.siu_82xx.sc_siumcr = (immap->im_siu_conf.siu_82xx.sc_siumcr &
+				~(SIUMCR_L2CPC11 | SIUMCR_LBPC11 | SIUMCR_CS10PC11 | SIUMCR_APPC11) |
+				SIUMCR_BBD | SIUMCR_LBPC01 | SIUMCR_DPPC11 | SIUMCR_APPC10);
 #endif
 	/* Enable PCI  */
 	immap->im_pci.pci_gcr = cpu_to_le32(PCIGCR_PCI_BUS_EN);
diff --git a/arch/ppc/syslib/m8xx_setup.c b/arch/ppc/syslib/m8xx_setup.c
--- a/arch/ppc/syslib/m8xx_setup.c
+++ b/arch/ppc/syslib/m8xx_setup.c
@@ -57,7 +57,7 @@ unsigned char __res[sizeof(bd_t)];
 extern void m8xx_ide_init(void);
 
 extern unsigned long find_available_memory(void);
-extern void m8xx_cpm_reset(uint cpm_page);
+extern void m8xx_cpm_reset();
 extern void m8xx_wdt_handler_install(bd_t *bp);
 extern void rpxfb_alloc_pages(void);
 extern void cpm_interrupt_init(void);
@@ -70,13 +70,9 @@ board_init(void)
 void __init
 m8xx_setup_arch(void)
 {
-	int	cpm_page;
-
-	cpm_page = (int) alloc_bootmem_pages(PAGE_SIZE);
-
 	/* Reset the Communication Processor Module.
 	*/
-	m8xx_cpm_reset(cpm_page);
+	m8xx_cpm_reset();
 
 #ifdef CONFIG_FB_RPX
 	rpxfb_alloc_pages();
@@ -427,7 +423,7 @@ platform_init(unsigned long r3, unsigned
 	ppc_md.find_end_of_memory	= m8xx_find_end_of_memory;
 	ppc_md.setup_io_mappings	= m8xx_map_io;
 
-#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
+#if defined(CONFIG_BLK_DEV_MPC8xx_IDE)
 	m8xx_ide_init();
 #endif
 }
diff --git a/arch/ppc/syslib/mpc10x_common.c b/arch/ppc/syslib/mpc10x_common.c
--- a/arch/ppc/syslib/mpc10x_common.c
+++ b/arch/ppc/syslib/mpc10x_common.c
@@ -21,6 +21,9 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/slab.h>
+#include <linux/serial_8250.h>
+#include <linux/fsl_devices.h>
+#include <linux/device.h>
 
 #include <asm/byteorder.h>
 #include <asm/io.h>
@@ -30,16 +33,7 @@
 #include <asm/pci-bridge.h>
 #include <asm/open_pic.h>
 #include <asm/mpc10x.h>
-#include <asm/ocp.h>
-
-/* The OCP structure is fixed by code below, before OCP initialises.
-   paddr depends on where the board places the EUMB.
-    - fixed in mpc10x_bridge_init().
-   irq depends on two things:
-    > does the board use the EPIC at all? (PCORE does not).
-    > is the EPIC in serial or parallel mode?
-    - fixed in mpc10x_set_openpic().
-*/
+#include <asm/ppc_sys.h>
 
 #ifdef CONFIG_MPC10X_OPENPIC
 #ifdef CONFIG_EPIC_SERIAL_MODE
@@ -50,37 +44,172 @@
 #define MPC10X_I2C_IRQ (EPIC_IRQ_BASE + NUM_8259_INTERRUPTS)
 #define MPC10X_DMA0_IRQ (EPIC_IRQ_BASE + 1 + NUM_8259_INTERRUPTS)
 #define MPC10X_DMA1_IRQ (EPIC_IRQ_BASE + 2 + NUM_8259_INTERRUPTS)
+#define MPC10X_UART0_IRQ (EPIC_IRQ_BASE + 4 + NUM_8259_INTERRUPTS)
+#define MPC10X_UART1_IRQ (EPIC_IRQ_BASE + 5 + NUM_8259_INTERRUPTS)
 #else
-#define MPC10X_I2C_IRQ OCP_IRQ_NA
-#define MPC10X_DMA0_IRQ OCP_IRQ_NA
-#define MPC10X_DMA1_IRQ OCP_IRQ_NA
+#define MPC10X_I2C_IRQ -1
+#define MPC10X_DMA0_IRQ -1
+#define MPC10X_DMA1_IRQ -1
+#define MPC10X_UART0_IRQ -1
+#define MPC10X_UART1_IRQ -1
 #endif
 
-
-struct ocp_def core_ocp[] = {
-	{ .vendor	= OCP_VENDOR_INVALID
-	}
+static struct fsl_i2c_platform_data mpc10x_i2c_pdata = {
+	.device_flags		= 0,
 };
 
-static struct ocp_fs_i2c_data mpc10x_i2c_data = {
-	.flags		= 0
+static struct plat_serial8250_port serial_plat_uart0[] = {
+	[0] = {
+		.mapbase	= 0x4500,
+		.iotype		= UPIO_MEM,
+		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+	},
+	{ },
 };
-static struct ocp_def mpc10x_i2c_ocp = {
-	.vendor		= OCP_VENDOR_MOTOROLA,
-	.function	= OCP_FUNC_IIC,
-	.index		= 0,
-	.additions	= &mpc10x_i2c_data
+static struct plat_serial8250_port serial_plat_uart1[] = {
+	[0] = {
+		.mapbase	= 0x4600,
+		.iotype		= UPIO_MEM,
+		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+	},
+	{ },
+};
+
+struct platform_device ppc_sys_platform_devices[] = {
+	[MPC10X_IIC1] = {
+		.name 	= "fsl-i2c",
+		.id	= 1,
+		.dev.platform_data = &mpc10x_i2c_pdata,
+		.num_resources = 2,
+		.resource = (struct resource[]) {
+			{
+				.start 	= MPC10X_EUMB_I2C_OFFSET,
+				.end	= MPC10X_EUMB_I2C_OFFSET +
+		                            MPC10X_EUMB_I2C_SIZE - 1,
+				.flags	= IORESOURCE_MEM,
+			},
+			{
+				.flags 	= IORESOURCE_IRQ
+			},
+		},
+	},
+	[MPC10X_DMA0] = {
+		.name	= "fsl-dma",
+		.id	= 0,
+		.num_resources = 2,
+		.resource = (struct resource[]) {
+			{
+				.start 	= MPC10X_EUMB_DMA_OFFSET + 0x10,
+				.end	= MPC10X_EUMB_DMA_OFFSET + 0x1f,
+				.flags	= IORESOURCE_MEM,
+			},
+			{
+				.flags	= IORESOURCE_IRQ,
+			},
+		},
+	},
+	[MPC10X_DMA1] = {
+		.name	= "fsl-dma",
+		.id	= 1,
+		.num_resources = 2,
+		.resource = (struct resource[]) {
+			{
+				.start	= MPC10X_EUMB_DMA_OFFSET + 0x20,
+				.end	= MPC10X_EUMB_DMA_OFFSET + 0x2f,
+				.flags	= IORESOURCE_MEM,
+			},
+			{
+				.flags	= IORESOURCE_IRQ,
+			},
+		},
+	},
+	[MPC10X_DMA1] = {
+		.name	= "fsl-dma",
+		.id	= 1,
+		.num_resources = 2,
+		.resource = (struct resource[]) {
+			{
+				.start	= MPC10X_EUMB_DMA_OFFSET + 0x20,
+				.end	= MPC10X_EUMB_DMA_OFFSET + 0x2f,
+				.flags	= IORESOURCE_MEM,
+			},
+			{
+				.flags	= IORESOURCE_IRQ,
+			},
+		},
+	},
+	[MPC10X_UART0] = {
+		.name = "serial8250",
+		.id	= 0,
+		.dev.platform_data = serial_plat_uart0,
+	},
+	[MPC10X_UART1] = {
+		.name = "serial8250",
+		.id	= 1,
+		.dev.platform_data = serial_plat_uart1,
+	},
+
 };
 
-static struct ocp_def mpc10x_dma_ocp[2] = {
-{	.vendor		= OCP_VENDOR_MOTOROLA,
-	.function	= OCP_FUNC_DMA,
-	.index		= 0 },
-{	.vendor		= OCP_VENDOR_MOTOROLA,
-	.function	= OCP_FUNC_DMA,
-	.index		= 1 }
+/* We use the PCI ID to match on */
+struct ppc_sys_spec *cur_ppc_sys_spec;
+struct ppc_sys_spec ppc_sys_specs[] = {
+	{
+		.ppc_sys_name 	= "8245",
+		.mask		= 0xFFFFFFFF,
+		.value		= MPC10X_BRIDGE_8245,
+		.num_devices	= 5,
+		.device_list	= (enum ppc_sys_devices[])
+		{
+			MPC10X_IIC1, MPC10X_DMA0, MPC10X_DMA1, MPC10X_UART0, MPC10X_UART1,
+		},
+	},
+	{
+		.ppc_sys_name 	= "8240",
+		.mask		= 0xFFFFFFFF,
+		.value		= MPC10X_BRIDGE_8240,
+		.num_devices	= 3,
+		.device_list	= (enum ppc_sys_devices[])
+		{
+			MPC10X_IIC1, MPC10X_DMA0, MPC10X_DMA1,
+		},
+	},
+	{
+		.ppc_sys_name	= "107",
+		.mask		= 0xFFFFFFFF,
+		.value		= MPC10X_BRIDGE_107,
+		.num_devices	= 3,
+		.device_list	= (enum ppc_sys_devices[])
+		{
+			MPC10X_IIC1, MPC10X_DMA0, MPC10X_DMA1,
+		},
+	},
+	{       /* default match */
+		.ppc_sys_name   = "",
+		.mask           = 0x00000000,
+		.value          = 0x00000000,
+	},
 };
 
+/*
+ * mach_mpc10x_fixup: This function enables DUART mode if it detects
+ * if it detects two UARTS in the platform device entries.
+ */
+static int __init mach_mpc10x_fixup(struct platform_device *pdev)
+{
+	if (strncmp (pdev->name, "serial8250", 10) == 0 && pdev->id == 1)
+		writeb(readb(serial_plat_uart1[0].membase + 0x11) | 0x1,
+				serial_plat_uart1[0].membase + 0x11);
+	return 0;
+}
+
+static int __init mach_mpc10x_init(void)
+{
+	ppc_sys_device_fixup = mach_mpc10x_fixup;
+	return 0;
+}
+postcore_initcall(mach_mpc10x_init);
+
 /* Set resources to match bridge memory map */
 void __init
 mpc10x_bridge_set_resources(int map, struct pci_controller *hose)
@@ -120,6 +249,7 @@ mpc10x_bridge_set_resources(int map, str
 				ppc_md.progress("mpc10x:exit1", 0x100);
 	}
 }
+
 /*
  * Do some initialization and put the EUMB registers at the specified address
  * (also map the EPIC registers into virtual space--OpenPIC_Addr will be set).
@@ -132,7 +262,7 @@ mpc10x_bridge_init(struct pci_controller
 		   uint new_map,
 		   uint phys_eumb_base)
 {
-	int	host_bridge, picr1, picr1_bit;
+	int	host_bridge, picr1, picr1_bit, i;
 	ulong	pci_config_addr, pci_config_data;
 	u_char	pir, byte;
 
@@ -273,7 +403,7 @@ mpc10x_bridge_init(struct pci_controller
 			printk("Host bridge in Agent mode\n");
 			/* Read or Set LMBAR & PCSRBAR? */
 		}
-		
+
 		/* Set base addr of the 8240/107 EUMB.  */
 		early_write_config_dword(hose,
 					 0,
@@ -287,17 +417,6 @@ mpc10x_bridge_init(struct pci_controller
 			ioremap(phys_eumb_base + MPC10X_EUMB_EPIC_OFFSET,
 				MPC10X_EUMB_EPIC_SIZE);
 #endif
-		mpc10x_i2c_ocp.paddr = phys_eumb_base + MPC10X_EUMB_I2C_OFFSET;
-		mpc10x_i2c_ocp.irq = MPC10X_I2C_IRQ;
-		ocp_add_one_device(&mpc10x_i2c_ocp);
-		mpc10x_dma_ocp[0].paddr = phys_eumb_base +
-					MPC10X_EUMB_DMA_OFFSET + 0x100;
-		mpc10x_dma_ocp[0].irq = MPC10X_DMA0_IRQ;
-		ocp_add_one_device(&mpc10x_dma_ocp[0]);
-		mpc10x_dma_ocp[1].paddr = phys_eumb_base +
-					MPC10X_EUMB_DMA_OFFSET + 0x200;
-		mpc10x_dma_ocp[1].irq = MPC10X_DMA1_IRQ;
-		ocp_add_one_device(&mpc10x_dma_ocp[1]);
 	}
 
 #ifdef CONFIG_MPC10X_STORE_GATHERING
@@ -306,6 +425,31 @@ mpc10x_bridge_init(struct pci_controller
 	mpc10x_disable_store_gathering(hose);
 #endif
 
+	/* setup platform devices for MPC10x bridges */
+	identify_ppc_sys_by_id (host_bridge);
+
+	for (i = 0; i < cur_ppc_sys_spec->num_devices; i++) {
+		unsigned int dev_id = cur_ppc_sys_spec->device_list[i];
+		ppc_sys_fixup_mem_resource(&ppc_sys_platform_devices[dev_id],
+			phys_eumb_base);
+	}
+
+	/* IRQ's are determined at runtime */
+	ppc_sys_platform_devices[MPC10X_IIC1].resource[1].start = MPC10X_I2C_IRQ;
+	ppc_sys_platform_devices[MPC10X_IIC1].resource[1].end = MPC10X_I2C_IRQ;
+	ppc_sys_platform_devices[MPC10X_DMA0].resource[1].start = MPC10X_DMA0_IRQ;
+	ppc_sys_platform_devices[MPC10X_DMA0].resource[1].end = MPC10X_DMA0_IRQ;
+	ppc_sys_platform_devices[MPC10X_DMA1].resource[1].start = MPC10X_DMA1_IRQ;
+	ppc_sys_platform_devices[MPC10X_DMA1].resource[1].end = MPC10X_DMA1_IRQ;
+
+	serial_plat_uart0[0].mapbase += phys_eumb_base;
+	serial_plat_uart0[0].irq = MPC10X_UART0_IRQ;
+	serial_plat_uart0[0].membase = ioremap(serial_plat_uart0[0].mapbase, 0x100);
+
+	serial_plat_uart1[0].mapbase += phys_eumb_base;
+	serial_plat_uart1[0].irq = MPC10X_UART1_IRQ;
+	serial_plat_uart1[0].membase = ioremap(serial_plat_uart1[0].mapbase, 0x100);
+
 	/*
 	 * 8240 erratum 26, 8241/8245 erratum 29, 107 erratum 23: speculative
 	 * PCI reads may return stale data so turn off.
@@ -330,7 +474,7 @@ mpc10x_bridge_init(struct pci_controller
 	 * 8245 (Rev 2., dated 10/2003) says PICR2[0] is reserverd.
 	 */
 	if (host_bridge == MPC10X_BRIDGE_8245) {
-		ulong	picr2;
+		u32	picr2;
 
 		early_read_config_dword(hose, 0, PCI_DEVFN(0,0),
 			MPC10X_CFG_PICR2_REG, &picr2);
@@ -504,6 +648,8 @@ void __init mpc10x_set_openpic(void)
 	openpic_set_sources(EPIC_IRQ_BASE, 3, OpenPIC_Addr + 0x11020);
 	/* Skip reserved space and map Message Unit Interrupt (I2O) */
 	openpic_set_sources(EPIC_IRQ_BASE + 3, 1, OpenPIC_Addr + 0x110C0);
+	/* Skip reserved space and map Serial Interupts */
+	openpic_set_sources(EPIC_IRQ_BASE + 4, 2, OpenPIC_Addr + 0x11120);
 
 	openpic_init(NUM_8259_INTERRUPTS);
 }
diff --git a/arch/ppc/syslib/mpc83xx_devices.c b/arch/ppc/syslib/mpc83xx_devices.c
--- a/arch/ppc/syslib/mpc83xx_devices.c
+++ b/arch/ppc/syslib/mpc83xx_devices.c
@@ -191,8 +191,8 @@ struct platform_device ppc_sys_platform_
 		.num_resources	 = 2,
 		.resource = (struct resource[]) {
 			{
-				.start	= 0x22000,
-				.end	= 0x22fff,
+				.start	= 0x23000,
+				.end	= 0x23fff,
 				.flags	= IORESOURCE_MEM,
 			},
 			{
@@ -208,8 +208,8 @@ struct platform_device ppc_sys_platform_
 		.num_resources	 = 2,
 		.resource = (struct resource[]) {
 			{
-				.start	= 0x23000,
-				.end	= 0x23fff,
+				.start	= 0x22000,
+				.end	= 0x22fff,
 				.flags	= IORESOURCE_MEM,
 			},
 			{
diff --git a/arch/ppc/syslib/mpc85xx_devices.c b/arch/ppc/syslib/mpc85xx_devices.c
--- a/arch/ppc/syslib/mpc85xx_devices.c
+++ b/arch/ppc/syslib/mpc85xx_devices.c
@@ -40,6 +40,42 @@ static struct gianfar_platform_data mpc8
 	.phy_reg_addr = MPC85xx_ENET1_OFFSET,
 };
 
+static struct gianfar_platform_data mpc85xx_etsec1_pdata = {
+	.device_flags = FSL_GIANFAR_DEV_HAS_GIGABIT |
+	    FSL_GIANFAR_DEV_HAS_COALESCE | FSL_GIANFAR_DEV_HAS_RMON |
+	    FSL_GIANFAR_DEV_HAS_MULTI_INTR |
+	    FSL_GIANFAR_DEV_HAS_CSUM | FSL_GIANFAR_DEV_HAS_VLAN |
+	    FSL_GIANFAR_DEV_HAS_EXTENDED_HASH,
+	.phy_reg_addr = MPC85xx_ENET1_OFFSET,
+};
+
+static struct gianfar_platform_data mpc85xx_etsec2_pdata = {
+	.device_flags = FSL_GIANFAR_DEV_HAS_GIGABIT |
+	    FSL_GIANFAR_DEV_HAS_COALESCE | FSL_GIANFAR_DEV_HAS_RMON |
+	    FSL_GIANFAR_DEV_HAS_MULTI_INTR |
+	    FSL_GIANFAR_DEV_HAS_CSUM | FSL_GIANFAR_DEV_HAS_VLAN |
+	    FSL_GIANFAR_DEV_HAS_EXTENDED_HASH,
+	.phy_reg_addr = MPC85xx_ENET1_OFFSET,
+};
+
+static struct gianfar_platform_data mpc85xx_etsec3_pdata = {
+	.device_flags = FSL_GIANFAR_DEV_HAS_GIGABIT |
+	    FSL_GIANFAR_DEV_HAS_COALESCE | FSL_GIANFAR_DEV_HAS_RMON |
+	    FSL_GIANFAR_DEV_HAS_MULTI_INTR |
+	    FSL_GIANFAR_DEV_HAS_CSUM | FSL_GIANFAR_DEV_HAS_VLAN |
+	    FSL_GIANFAR_DEV_HAS_EXTENDED_HASH,
+	.phy_reg_addr = MPC85xx_ENET1_OFFSET,
+};
+
+static struct gianfar_platform_data mpc85xx_etsec4_pdata = {
+	.device_flags = FSL_GIANFAR_DEV_HAS_GIGABIT |
+	    FSL_GIANFAR_DEV_HAS_COALESCE | FSL_GIANFAR_DEV_HAS_RMON |
+	    FSL_GIANFAR_DEV_HAS_MULTI_INTR |
+	    FSL_GIANFAR_DEV_HAS_CSUM | FSL_GIANFAR_DEV_HAS_VLAN |
+	    FSL_GIANFAR_DEV_HAS_EXTENDED_HASH,
+	.phy_reg_addr = MPC85xx_ENET1_OFFSET,
+};
+
 static struct gianfar_platform_data mpc85xx_fec_pdata = {
 	.phy_reg_addr = MPC85xx_ENET1_OFFSET,
 };
@@ -48,6 +84,10 @@ static struct fsl_i2c_platform_data mpc8
 	.device_flags = FSL_I2C_DEV_SEPARATE_DFSRR,
 };
 
+static struct fsl_i2c_platform_data mpc85xx_fsl_i2c2_pdata = {
+	.device_flags = FSL_I2C_DEV_SEPARATE_DFSRR,
+};
+
 static struct plat_serial8250_port serial_platform_data[] = {
 	[0] = {
 		.mapbase	= 0x4500,
@@ -281,7 +321,6 @@ struct platform_device ppc_sys_platform_
 			},
 		},
 	},
-#ifdef CONFIG_CPM2
 	[MPC85xx_CPM_FCC1] = {
 		.name = "fsl-cpm-fcc",
 		.id	= 1,
@@ -535,7 +574,151 @@ struct platform_device ppc_sys_platform_
 			},
 		},
 	},
-#endif /* CONFIG_CPM2 */
+	[MPC85xx_eTSEC1] = {
+		.name = "fsl-gianfar",
+		.id	= 1,
+		.dev.platform_data = &mpc85xx_etsec1_pdata,
+		.num_resources	 = 4,
+		.resource = (struct resource[]) {
+			{
+				.start	= MPC85xx_ENET1_OFFSET,
+				.end	= MPC85xx_ENET1_OFFSET +
+						MPC85xx_ENET1_SIZE - 1,
+				.flags	= IORESOURCE_MEM,
+			},
+			{
+				.name	= "tx",
+				.start	= MPC85xx_IRQ_TSEC1_TX,
+				.end	= MPC85xx_IRQ_TSEC1_TX,
+				.flags	= IORESOURCE_IRQ,
+			},
+			{
+				.name	= "rx",
+				.start	= MPC85xx_IRQ_TSEC1_RX,
+				.end	= MPC85xx_IRQ_TSEC1_RX,
+				.flags	= IORESOURCE_IRQ,
+			},
+			{
+				.name	= "error",
+				.start	= MPC85xx_IRQ_TSEC1_ERROR,
+				.end	= MPC85xx_IRQ_TSEC1_ERROR,
+				.flags	= IORESOURCE_IRQ,
+			},
+		},
+	},
+	[MPC85xx_eTSEC2] = {
+		.name = "fsl-gianfar",
+		.id	= 2,
+		.dev.platform_data = &mpc85xx_etsec2_pdata,
+		.num_resources	 = 4,
+		.resource = (struct resource[]) {
+			{
+				.start	= MPC85xx_ENET2_OFFSET,
+				.end	= MPC85xx_ENET2_OFFSET +
+						MPC85xx_ENET2_SIZE - 1,
+				.flags	= IORESOURCE_MEM,
+			},
+			{
+				.name	= "tx",
+				.start	= MPC85xx_IRQ_TSEC2_TX,
+				.end	= MPC85xx_IRQ_TSEC2_TX,
+				.flags	= IORESOURCE_IRQ,
+			},
+			{
+				.name	= "rx",
+				.start	= MPC85xx_IRQ_TSEC2_RX,
+				.end	= MPC85xx_IRQ_TSEC2_RX,
+				.flags	= IORESOURCE_IRQ,
+			},
+			{
+				.name	= "error",
+				.start	= MPC85xx_IRQ_TSEC2_ERROR,
+				.end	= MPC85xx_IRQ_TSEC2_ERROR,
+				.flags	= IORESOURCE_IRQ,
+			},
+		},
+	},
+	[MPC85xx_eTSEC3] = {
+		.name = "fsl-gianfar",
+		.id	= 3,
+		.dev.platform_data = &mpc85xx_etsec3_pdata,
+		.num_resources	 = 4,
+		.resource = (struct resource[]) {
+			{
+				.start	= MPC85xx_ENET3_OFFSET,
+				.end	= MPC85xx_ENET3_OFFSET +
+						MPC85xx_ENET3_SIZE - 1,
+				.flags	= IORESOURCE_MEM,
+			},
+			{
+				.name	= "tx",
+				.start	= MPC85xx_IRQ_TSEC3_TX,
+				.end	= MPC85xx_IRQ_TSEC3_TX,
+				.flags	= IORESOURCE_IRQ,
+			},
+			{
+				.name	= "rx",
+				.start	= MPC85xx_IRQ_TSEC3_RX,
+				.end	= MPC85xx_IRQ_TSEC3_RX,
+				.flags	= IORESOURCE_IRQ,
+			},
+			{
+				.name	= "error",
+				.start	= MPC85xx_IRQ_TSEC3_ERROR,
+				.end	= MPC85xx_IRQ_TSEC3_ERROR,
+				.flags	= IORESOURCE_IRQ,
+			},
+		},
+	},
+	[MPC85xx_eTSEC4] = {
+		.name = "fsl-gianfar",
+		.id	= 4,
+		.dev.platform_data = &mpc85xx_etsec4_pdata,
+		.num_resources	 = 4,
+		.resource = (struct resource[]) {
+			{
+				.start	= 0x27000,
+				.end	= 0x27fff,
+				.flags	= IORESOURCE_MEM,
+			},
+			{
+				.name	= "tx",
+				.start	= MPC85xx_IRQ_TSEC4_TX,
+				.end	= MPC85xx_IRQ_TSEC4_TX,
+				.flags	= IORESOURCE_IRQ,
+			},
+			{
+				.name	= "rx",
+				.start	= MPC85xx_IRQ_TSEC4_RX,
+				.end	= MPC85xx_IRQ_TSEC4_RX,
+				.flags	= IORESOURCE_IRQ,
+			},
+			{
+				.name	= "error",
+				.start	= MPC85xx_IRQ_TSEC4_ERROR,
+				.end	= MPC85xx_IRQ_TSEC4_ERROR,
+				.flags	= IORESOURCE_IRQ,
+			},
+		},
+	},
+	[MPC85xx_IIC2] = {
+		.name = "fsl-i2c",
+		.id	= 2,
+		.dev.platform_data = &mpc85xx_fsl_i2c2_pdata,
+		.num_resources	 = 2,
+		.resource = (struct resource[]) {
+			{
+				.start	= 0x03100,
+				.end	= 0x031ff,
+				.flags	= IORESOURCE_MEM,
+			},
+			{
+				.start	= MPC85xx_IRQ_IIC1,
+				.end	= MPC85xx_IRQ_IIC1,
+				.flags	= IORESOURCE_IRQ,
+			},
+		},
+	},
 };
 
 static int __init mach_mpc85xx_fixup(struct platform_device *pdev)
diff --git a/arch/ppc/syslib/mpc85xx_sys.c b/arch/ppc/syslib/mpc85xx_sys.c
--- a/arch/ppc/syslib/mpc85xx_sys.c
+++ b/arch/ppc/syslib/mpc85xx_sys.c
@@ -110,6 +110,111 @@ struct ppc_sys_spec ppc_sys_specs[] = {
 			MPC85xx_CPM_USB,
 		},
 	},
+	/* SVRs on 8548 rev1.0 matches for 8548/8547/8545 */
+	{
+		.ppc_sys_name	= "8548E",
+		.mask 		= 0xFFFF00F0,
+		.value 		= 0x80390010,
+		.num_devices	= 13,
+		.device_list	= (enum ppc_sys_devices[])
+		{
+			MPC85xx_eTSEC1, MPC85xx_eTSEC2, MPC85xx_eTSEC3,
+			MPC85xx_eTSEC4, MPC85xx_IIC1, MPC85xx_IIC2,
+			MPC85xx_DMA0, MPC85xx_DMA1, MPC85xx_DMA2, MPC85xx_DMA3,
+			MPC85xx_PERFMON, MPC85xx_DUART, MPC85xx_SEC2,
+		},
+	},
+	{
+		.ppc_sys_name	= "8548",
+		.mask 		= 0xFFFF00F0,
+		.value 		= 0x80310010,
+		.num_devices	= 12,
+		.device_list	= (enum ppc_sys_devices[])
+		{
+			MPC85xx_eTSEC1, MPC85xx_eTSEC2, MPC85xx_eTSEC3,
+			MPC85xx_eTSEC4, MPC85xx_IIC1, MPC85xx_IIC2,
+			MPC85xx_DMA0, MPC85xx_DMA1, MPC85xx_DMA2, MPC85xx_DMA3,
+			MPC85xx_PERFMON, MPC85xx_DUART,
+		},
+	},
+	{
+		.ppc_sys_name	= "8547E",
+		.mask 		= 0xFFFF00F0,
+		.value 		= 0x80390010,
+		.num_devices	= 13,
+		.device_list	= (enum ppc_sys_devices[])
+		{
+			MPC85xx_eTSEC1, MPC85xx_eTSEC2, MPC85xx_eTSEC3,
+			MPC85xx_eTSEC4, MPC85xx_IIC1, MPC85xx_IIC2,
+			MPC85xx_DMA0, MPC85xx_DMA1, MPC85xx_DMA2, MPC85xx_DMA3,
+			MPC85xx_PERFMON, MPC85xx_DUART, MPC85xx_SEC2,
+		},
+	},
+	{
+		.ppc_sys_name	= "8547",
+		.mask 		= 0xFFFF00F0,
+		.value 		= 0x80310010,
+		.num_devices	= 12,
+		.device_list	= (enum ppc_sys_devices[])
+		{
+			MPC85xx_eTSEC1, MPC85xx_eTSEC2, MPC85xx_eTSEC3,
+			MPC85xx_eTSEC4, MPC85xx_IIC1, MPC85xx_IIC2,
+			MPC85xx_DMA0, MPC85xx_DMA1, MPC85xx_DMA2, MPC85xx_DMA3,
+			MPC85xx_PERFMON, MPC85xx_DUART,
+		},
+	},
+	{
+		.ppc_sys_name	= "8545E",
+		.mask 		= 0xFFFF00F0,
+		.value 		= 0x80390010,
+		.num_devices	= 11,
+		.device_list	= (enum ppc_sys_devices[])
+		{
+			MPC85xx_eTSEC1, MPC85xx_eTSEC2,
+			MPC85xx_IIC1, MPC85xx_IIC2,
+			MPC85xx_DMA0, MPC85xx_DMA1, MPC85xx_DMA2, MPC85xx_DMA3,
+			MPC85xx_PERFMON, MPC85xx_DUART, MPC85xx_SEC2,
+		},
+	},
+	{
+		.ppc_sys_name	= "8545",
+		.mask 		= 0xFFFF00F0,
+		.value 		= 0x80310010,
+		.num_devices	= 10,
+		.device_list	= (enum ppc_sys_devices[])
+		{
+			MPC85xx_eTSEC1, MPC85xx_eTSEC2,
+			MPC85xx_IIC1, MPC85xx_IIC2,
+			MPC85xx_DMA0, MPC85xx_DMA1, MPC85xx_DMA2, MPC85xx_DMA3,
+			MPC85xx_PERFMON, MPC85xx_DUART,
+		},
+	},
+	{
+		.ppc_sys_name	= "8543E",
+		.mask 		= 0xFFFF00F0,
+		.value 		= 0x803A0010,
+		.num_devices	= 11,
+		.device_list	= (enum ppc_sys_devices[])
+		{
+			MPC85xx_eTSEC1, MPC85xx_eTSEC2,
+			MPC85xx_IIC1, MPC85xx_IIC2,
+			MPC85xx_DMA0, MPC85xx_DMA1, MPC85xx_DMA2, MPC85xx_DMA3,
+			MPC85xx_PERFMON, MPC85xx_DUART, MPC85xx_SEC2,
+		},
+	},
+	{
+		.ppc_sys_name	= "8543",
+		.mask 		= 0xFFFF00F0,
+		.value 		= 0x80320010,
+		.num_devices	= 10,
+		.device_list	= (enum ppc_sys_devices[])
+		{
+			MPC85xx_eTSEC1, MPC85xx_eTSEC2,
+			MPC85xx_IIC1, MPC85xx_IIC2,
+			MPC85xx_DMA0, MPC85xx_DMA1, MPC85xx_DMA2, MPC85xx_DMA3,
+			MPC85xx_PERFMON, MPC85xx_DUART,
+		},
+	},
 	{	/* default match */
 		.ppc_sys_name	= "",
 		.mask 		= 0x00000000,
diff --git a/arch/ppc/syslib/mv64x60.c b/arch/ppc/syslib/mv64x60.c
--- a/arch/ppc/syslib/mv64x60.c
+++ b/arch/ppc/syslib/mv64x60.c
@@ -17,7 +17,6 @@
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/string.h>
-#include <linux/bootmem.h>
 #include <linux/spinlock.h>
 #include <linux/mv643xx.h>
 
diff --git a/arch/ppc/syslib/mv64x60_win.c b/arch/ppc/syslib/mv64x60_win.c
--- a/arch/ppc/syslib/mv64x60_win.c
+++ b/arch/ppc/syslib/mv64x60_win.c
@@ -17,7 +17,6 @@
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/string.h>
-#include <linux/bootmem.h>
 #include <linux/mv643xx.h>
 
 #include <asm/byteorder.h>
diff --git a/arch/ppc/syslib/ocp.c b/arch/ppc/syslib/ocp.c
--- a/arch/ppc/syslib/ocp.c
+++ b/arch/ppc/syslib/ocp.c
@@ -68,7 +68,7 @@ static int ocp_inited;
 /* Sysfs support */
 #define OCP_DEF_ATTR(field, format_string)				\
 static ssize_t								\
-show_##field(struct device *dev, char *buf)				\
+show_##field(struct device *dev, struct device_attribute *attr, char *buf)				\
 {									\
 	struct ocp_device *odev = to_ocp_dev(dev);			\
 									\
diff --git a/arch/ppc/syslib/of_device.c b/arch/ppc/syslib/of_device.c
--- a/arch/ppc/syslib/of_device.c
+++ b/arch/ppc/syslib/of_device.c
@@ -3,6 +3,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/mod_devicetable.h>
 #include <asm/errno.h>
 #include <asm/of_device.h>
 
@@ -15,20 +16,20 @@
  * Used by a driver to check whether an of_device present in the
  * system is in its list of supported devices.
  */
-const struct of_match * of_match_device(const struct of_match *matches,
+const struct of_device_id * of_match_device(const struct of_device_id *matches,
 					const struct of_device *dev)
 {
 	if (!dev->node)
 		return NULL;
-	while (matches->name || matches->type || matches->compatible) {
+	while (matches->name[0] || matches->type[0] || matches->compatible[0]) {
 		int match = 1;
-		if (matches->name && matches->name != OF_ANY_MATCH)
+		if (matches->name[0])
 			match &= dev->node->name
 				&& !strcmp(matches->name, dev->node->name);
-		if (matches->type && matches->type != OF_ANY_MATCH)
+		if (matches->type[0])
 			match &= dev->node->type
 				&& !strcmp(matches->type, dev->node->type);
-		if (matches->compatible && matches->compatible != OF_ANY_MATCH)
+		if (matches->compatible[0])
 			match &= device_is_compatible(dev->node,
 				matches->compatible);
 		if (match)
@@ -42,7 +43,7 @@ static int of_platform_bus_match(struct 
 {
 	struct of_device * of_dev = to_of_device(dev);
 	struct of_platform_driver * of_drv = to_of_platform_driver(drv);
-	const struct of_match * matches = of_drv->match_table;
+	const struct of_device_id * matches = of_drv->match_table;
 
 	if (!matches)
 		return 0;
@@ -75,7 +76,7 @@ static int of_device_probe(struct device
 	int error = -ENODEV;
 	struct of_platform_driver *drv;
 	struct of_device *of_dev;
-	const struct of_match *match;
+	const struct of_device_id *match;
 
 	drv = to_of_platform_driver(dev->driver);
 	of_dev = to_of_device(dev);
@@ -161,7 +162,7 @@ void of_unregister_driver(struct of_plat
 }
 
 
-static ssize_t dev_show_devspec(struct device *dev, char *buf)
+static ssize_t dev_show_devspec(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct of_device *ofdev;
 
diff --git a/arch/ppc/syslib/open_pic.c b/arch/ppc/syslib/open_pic.c
--- a/arch/ppc/syslib/open_pic.c
+++ b/arch/ppc/syslib/open_pic.c
@@ -21,7 +21,6 @@
 #include <asm/signal.h>
 #include <asm/io.h>
 #include <asm/irq.h>
-#include <asm/prom.h>
 #include <asm/sections.h>
 #include <asm/open_pic.h>
 #include <asm/i8259.h>
@@ -371,8 +370,9 @@ void __init openpic_init(int offset)
 	/* Initialize IPI interrupts */
 	if ( ppc_md.progress ) ppc_md.progress("openpic: ipi",0x3bb);
 	for (i = 0; i < OPENPIC_NUM_IPI; i++) {
-		/* Disabled, Priority 10..13 */
-		openpic_initipi(i, 10+i, OPENPIC_VEC_IPI+i+offset);
+		/* Disabled, increased priorities 10..13 */
+		openpic_initipi(i, OPENPIC_PRIORITY_IPI_BASE+i,
+				OPENPIC_VEC_IPI+i+offset);
 		/* IPIs are per-CPU */
 		irq_desc[OPENPIC_VEC_IPI+i+offset].status |= IRQ_PER_CPU;
 		irq_desc[OPENPIC_VEC_IPI+i+offset].handler = &open_pic_ipi;
@@ -400,8 +400,9 @@ void __init openpic_init(int offset)
 		if (sense & IRQ_SENSE_MASK)
 			irq_desc[i+offset].status = IRQ_LEVEL;
 
-		/* Enabled, Priority 8 */
-		openpic_initirq(i, 8, i+offset, (sense & IRQ_POLARITY_MASK),
+		/* Enabled, Default priority */
+		openpic_initirq(i, OPENPIC_PRIORITY_DEFAULT, i+offset,
+				(sense & IRQ_POLARITY_MASK),
 				(sense & IRQ_SENSE_MASK));
 		/* Processor 0 */
 		openpic_mapirq(i, CPU_MASK_CPU0, CPU_MASK_NONE);
@@ -657,6 +658,18 @@ static void __init openpic_maptimer(u_in
 }
 
 /*
+ * Change the priority of an interrupt
+ */
+void __init
+openpic_set_irq_priority(u_int irq, u_int pri)
+{
+	check_arg_irq(irq);
+	openpic_safe_writefield(&ISR[irq - open_pic_irq_offset]->Vector_Priority,
+				OPENPIC_PRIORITY_MASK,
+				pri << OPENPIC_PRIORITY_SHIFT);
+}
+
+/*
  * Initalize the interrupt source which will generate an NMI.
  * This raises the interrupt's priority from 8 to 9.
  *
@@ -666,9 +679,7 @@ void __init
 openpic_init_nmi_irq(u_int irq)
 {
 	check_arg_irq(irq);
-	openpic_safe_writefield(&ISR[irq - open_pic_irq_offset]->Vector_Priority,
-				OPENPIC_PRIORITY_MASK,
-				9 << OPENPIC_PRIORITY_SHIFT);
+	openpic_set_irq_priority(irq, OPENPIC_PRIORITY_NMI);
 }
 
 /*
diff --git a/arch/ppc/syslib/open_pic2.c b/arch/ppc/syslib/open_pic2.c
--- a/arch/ppc/syslib/open_pic2.c
+++ b/arch/ppc/syslib/open_pic2.c
@@ -25,7 +25,6 @@
 #include <asm/signal.h>
 #include <asm/io.h>
 #include <asm/irq.h>
-#include <asm/prom.h>
 #include <asm/sections.h>
 #include <asm/open_pic.h>
 #include <asm/i8259.h>
diff --git a/arch/ppc/syslib/ppc4xx_dma.c b/arch/ppc/syslib/ppc4xx_dma.c
--- a/arch/ppc/syslib/ppc4xx_dma.c
+++ b/arch/ppc/syslib/ppc4xx_dma.c
@@ -620,6 +620,7 @@ ppc4xx_clr_dma_status(unsigned int dmanr
 	return DMA_STATUS_GOOD;
 }
 
+#ifdef CONFIG_PPC4xx_EDMA
 /*
  * Enables the burst on the channel (BTEN bit in the control/count register)
  * Note:
@@ -685,6 +686,11 @@ ppc4xx_set_burst_size(unsigned int dmanr
 	return DMA_STATUS_GOOD;
 }
 
+EXPORT_SYMBOL(ppc4xx_enable_burst);
+EXPORT_SYMBOL(ppc4xx_disable_burst);
+EXPORT_SYMBOL(ppc4xx_set_burst_size);
+#endif /* CONFIG_PPC4xx_EDMA */
+
 EXPORT_SYMBOL(ppc4xx_init_dma_channel);
 EXPORT_SYMBOL(ppc4xx_get_channel_config);
 EXPORT_SYMBOL(ppc4xx_set_channel_priority);
@@ -703,6 +709,4 @@ EXPORT_SYMBOL(ppc4xx_enable_dma_interrup
 EXPORT_SYMBOL(ppc4xx_disable_dma_interrupt);
 EXPORT_SYMBOL(ppc4xx_get_dma_status);
 EXPORT_SYMBOL(ppc4xx_clr_dma_status);
-EXPORT_SYMBOL(ppc4xx_enable_burst);
-EXPORT_SYMBOL(ppc4xx_disable_burst);
-EXPORT_SYMBOL(ppc4xx_set_burst_size);
+
diff --git a/arch/ppc/syslib/ppc4xx_kgdb.c b/arch/ppc/syslib/ppc4xx_kgdb.c
deleted file mode 100644
--- a/arch/ppc/syslib/ppc4xx_kgdb.c
+++ /dev/null
@@ -1,124 +0,0 @@
-#include <linux/config.h>
-#include <linux/types.h>
-#include <asm/ibm4xx.h>
-#include <linux/kernel.h>
-
-
-
-#define LSR_DR		0x01 /* Data ready */
-#define LSR_OE		0x02 /* Overrun */
-#define LSR_PE		0x04 /* Parity error */
-#define LSR_FE		0x08 /* Framing error */
-#define LSR_BI		0x10 /* Break */
-#define LSR_THRE	0x20 /* Xmit holding register empty */
-#define LSR_TEMT	0x40 /* Xmitter empty */
-#define LSR_ERR		0x80 /* Error */
-
-#include <platforms/4xx/ibm_ocp.h>
-
-extern struct NS16550* COM_PORTS[];
-#ifndef NULL
-#define NULL 0x00
-#endif
-
-static volatile struct NS16550 *kgdb_debugport = NULL;
-
-volatile struct NS16550 *
-NS16550_init(int chan)
-{
-	volatile struct NS16550 *com_port;
-	int quot;
-#ifdef BASE_BAUD
-	quot = BASE_BAUD / 9600;
-#else
-	quot = 0x000c; /* 0xc = 9600 baud (on a pc) */
-#endif
-
-	com_port = (struct NS16550 *) COM_PORTS[chan];
-
-	com_port->lcr = 0x00;
-	com_port->ier = 0xFF;
-	com_port->ier = 0x00;
-	com_port->lcr = com_port->lcr | 0x80; /* Access baud rate */
-	com_port->dll = ( quot & 0x00ff ); /* 0xc = 9600 baud */
-	com_port->dlm = ( quot & 0xff00 ) >> 8;
-	com_port->lcr = 0x03; /* 8 data, 1 stop, no parity */
-	com_port->mcr = 0x00; /* RTS/DTR */
-	com_port->fcr = 0x07; /* Clear & enable FIFOs */
-
-	return( com_port );
-}
-
-
-void
-NS16550_putc(volatile struct NS16550 *com_port, unsigned char c)
-{
-	while ((com_port->lsr & LSR_THRE) == 0)
-		;
-	com_port->thr = c;
-	return;
-}
-
-unsigned char
-NS16550_getc(volatile struct NS16550 *com_port)
-{
-	while ((com_port->lsr & LSR_DR) == 0)
-		;
-	return (com_port->rbr);
-}
-
-unsigned char
-NS16550_tstc(volatile struct NS16550 *com_port)
-{
-	return ((com_port->lsr & LSR_DR) != 0);
-}
-
-
-#if defined(CONFIG_KGDB_TTYS0)
-#define KGDB_PORT 0
-#elif defined(CONFIG_KGDB_TTYS1)
-#define KGDB_PORT 1
-#elif defined(CONFIG_KGDB_TTYS2)
-#define KGDB_PORT 2
-#elif defined(CONFIG_KGDB_TTYS3)
-#define KGDB_PORT 3
-#else
-#error "invalid kgdb_tty port"
-#endif
-
-void putDebugChar( unsigned char c )
-{
-	if ( kgdb_debugport == NULL )
-		kgdb_debugport = NS16550_init(KGDB_PORT);
-	NS16550_putc( kgdb_debugport, c );
-}
-
-int getDebugChar( void )
-{
-	if (kgdb_debugport == NULL)
-		kgdb_debugport = NS16550_init(KGDB_PORT);
-
-	return(NS16550_getc(kgdb_debugport));
-}
-
-void kgdb_interruptible(int enable)
-{
-	return;
-}
-
-void putDebugString(char* str)
-{
-	while (*str != '\0') {
-		putDebugChar(*str);
-		str++;
-	}
-	putDebugChar('\r');
-	return;
-}
-
-void
-kgdb_map_scc(void)
-{
-	printk("kgdb init \n");
-	kgdb_debugport = NS16550_init(KGDB_PORT);
-}
diff --git a/arch/ppc/syslib/ppc4xx_pic.c b/arch/ppc/syslib/ppc4xx_pic.c
--- a/arch/ppc/syslib/ppc4xx_pic.c
+++ b/arch/ppc/syslib/ppc4xx_pic.c
@@ -110,6 +110,10 @@ static int ppc4xx_pic_get_irq(struct pt_
 
 static void __init ppc4xx_pic_impl_init(void)
 {
+#if defined(CONFIG_440GX)
+	/* Disable 440GP compatibility mode if it was enabled in firmware */
+	SDR_WRITE(DCRN_SDR_MFR, SDR_READ(DCRN_SDR_MFR) & ~DCRN_SDR_MFR_PCM);
+#endif
 	/* Configure Base UIC */
 	mtdcr(DCRN_UIC_CR(UICB), 0);
 	mtdcr(DCRN_UIC_TR(UICB), 0);
diff --git a/arch/ppc/syslib/ppc83xx_setup.c b/arch/ppc/syslib/ppc83xx_setup.c
--- a/arch/ppc/syslib/ppc83xx_setup.c
+++ b/arch/ppc/syslib/ppc83xx_setup.c
@@ -23,7 +23,6 @@
 #include <linux/serial_core.h>
 #include <linux/serial_8250.h>
 
-#include <asm/prom.h>
 #include <asm/time.h>
 #include <asm/mpc83xx.h>
 #include <asm/mmu.h>
diff --git a/arch/ppc/syslib/ppc85xx_setup.c b/arch/ppc/syslib/ppc85xx_setup.c
--- a/arch/ppc/syslib/ppc85xx_setup.c
+++ b/arch/ppc/syslib/ppc85xx_setup.c
@@ -23,7 +23,6 @@
 #include <linux/serial_core.h>
 #include <linux/serial_8250.h>
 
-#include <asm/prom.h>
 #include <asm/time.h>
 #include <asm/mpc85xx.h>
 #include <asm/immap_85xx.h>
@@ -33,6 +32,8 @@
 
 #include <syslib/ppc85xx_setup.h>
 
+extern void abort(void);
+
 /* Return the amount of memory */
 unsigned long __init
 mpc85xx_find_end_of_memory(void)
@@ -133,7 +134,7 @@ mpc85xx_halt(void)
 
 #ifdef CONFIG_PCI
 
-#if defined(CONFIG_MPC8555_CDS)
+#if defined(CONFIG_MPC8555_CDS) || defined(CONFIG_MPC8548_CDS)
 extern void mpc85xx_cds_enable_via(struct pci_controller *hose);
 extern void mpc85xx_cds_fixup_via(struct pci_controller *hose);
 #endif
@@ -232,14 +233,14 @@ mpc85xx_setup_pci2(struct pci_controller
 	pci->powbar1 = (MPC85XX_PCI2_LOWER_MEM >> 12) & 0x000fffff;
 	/* Enable, Mem R/W */
 	pci->powar1 = 0x80044000 |
-	   (__ilog2(MPC85XX_PCI1_UPPER_MEM - MPC85XX_PCI1_LOWER_MEM + 1) - 1);
+	   (__ilog2(MPC85XX_PCI2_UPPER_MEM - MPC85XX_PCI2_LOWER_MEM + 1) - 1);
 
 	/* Setup outboud IO windows @ MPC85XX_PCI2_IO_BASE */
 	pci->potar2 = 0x00000000;
 	pci->potear2 = 0x00000000;
 	pci->powbar2 = (MPC85XX_PCI2_IO_BASE >> 12) & 0x000fffff;
 	/* Enable, IO R/W */
-	pci->powar2 = 0x80088000 | (__ilog2(MPC85XX_PCI1_IO_SIZE) - 1);
+	pci->powar2 = 0x80088000 | (__ilog2(MPC85XX_PCI2_IO_SIZE) - 1);
 
 	/* Setup 2G inbound Memory Window @ 0 */
 	pci->pitar1 = 0x00000000;
@@ -308,14 +309,14 @@ mpc85xx_setup_hose(void)
 
 	ppc_md.pci_exclude_device = mpc85xx_exclude_device;
 
-#if defined(CONFIG_MPC8555_CDS)
+#if defined(CONFIG_MPC8555_CDS) || defined(CONFIG_MPC8548_CDS)
 	/* Pre pciauto_bus_scan VIA init */
 	mpc85xx_cds_enable_via(hose_a);
 #endif
 
 	hose_a->last_busno = pciauto_bus_scan(hose_a, hose_a->first_busno);
 
-#if defined(CONFIG_MPC8555_CDS)
+#if defined(CONFIG_MPC8555_CDS) || defined(CONFIG_MPC8548_CDS)
 	/* Post pciauto_bus_scan VIA fixup */
 	mpc85xx_cds_fixup_via(hose_a);
 #endif
diff --git a/arch/ppc/xmon/xmon.c b/arch/ppc/xmon/xmon.c
--- a/arch/ppc/xmon/xmon.c
+++ b/arch/ppc/xmon/xmon.c
@@ -9,6 +9,7 @@
 #include <linux/smp.h>
 #include <linux/interrupt.h>
 #include <linux/bitops.h>
+#include <linux/kallsyms.h>
 #include <asm/ptrace.h>
 #include <asm/string.h>
 #include <asm/prom.h>
@@ -93,8 +94,7 @@ static void take_input(char *);
 static unsigned read_spr(int);
 static void write_spr(int, unsigned);
 static void super_regs(void);
-static void print_sysmap(void);
-static void sysmap_lookup(void);
+static void symbol_lookup(void);
 static void remove_bpts(void);
 static void insert_bpts(void);
 static struct bpt *at_breakpoint(unsigned pc);
@@ -103,7 +103,6 @@ static void cacheflush(void);
 #ifdef CONFIG_SMP
 static void cpu_cmd(void);
 #endif /* CONFIG_SMP */
-static int pretty_print_addr(unsigned long addr);
 static void csum(void);
 #ifdef CONFIG_BOOTX_TEXT
 static void vidcmds(void);
@@ -120,8 +119,6 @@ extern void longjmp(u_int *, int);
 
 extern void xmon_enter(void);
 extern void xmon_leave(void);
-extern char* xmon_find_symbol(unsigned long addr, unsigned long* saddr);
-extern unsigned long xmon_symbol_to_addr(char* symbol);
 
 static unsigned start_tb[NR_CPUS][2];
 static unsigned stop_tb[NR_CPUS][2];
@@ -148,7 +145,6 @@ Commands:\n\
   mm	move a block of memory\n\
   ms	set a block of memory\n\
   md	compare two blocks of memory\n\
-  M	print System.map\n\
   r	print registers\n\
   S	print special registers\n\
   t	print backtrace\n\
@@ -175,6 +171,35 @@ extern inline void __delay(unsigned int 
 				     "r" (loops) : "ctr");
 }
 
+/* Print an address in numeric and symbolic form (if possible) */
+static void xmon_print_symbol(unsigned long address, const char *mid,
+			      const char *after)
+{
+	char *modname;
+	const char *name = NULL;
+	unsigned long offset, size;
+	static char tmpstr[128];
+
+	printf("%.8lx", address);
+	if (setjmp(bus_error_jmp) == 0) {
+		debugger_fault_handler = handle_fault;
+		sync();
+		name = kallsyms_lookup(address, &size, &offset, &modname,
+				       tmpstr);
+		sync();
+		/* wait a little while to see if we get a machine check */
+		__delay(200);
+	}
+	debugger_fault_handler = NULL;
+
+	if (name) {
+		printf("%s%s+%#lx/%#lx", mid, name, offset, size);
+		if (modname)
+			printf(" [%s]", modname);
+	}
+	printf("%s", after);
+}
+
 static void get_tb(unsigned *p)
 {
 	unsigned hi, lo, hiagain;
@@ -454,7 +479,7 @@ cmds(struct pt_regs *excp)
 			dump();
 			break;
 		case 'l':
-			sysmap_lookup();
+			symbol_lookup();
 			break;
 		case 'r':
 			if (excp != NULL)
@@ -466,9 +491,6 @@ cmds(struct pt_regs *excp)
 			else
 				excprint(excp);
 			break;
-		case 'M':
-			print_sysmap();
-			break;
 		case 'S':
 			super_regs();
 			break;
@@ -825,20 +847,19 @@ backtrace(struct pt_regs *excp)
 	for (; sp != 0; sp = stack[0]) {
 		if (mread(sp, stack, sizeof(stack)) != sizeof(stack))
 			break;
-		pretty_print_addr(stack[1]);
-		printf(" ");
+		printf("[%.8lx] ", stack);
+		xmon_print_symbol(stack[1], " ", "\n");
 		if (stack[1] == (unsigned) &ret_from_except
 		    || stack[1] == (unsigned) &ret_from_except_full
 		    || stack[1] == (unsigned) &ret_from_syscall) {
 			if (mread(sp+16, &regs, sizeof(regs)) != sizeof(regs))
 				break;
-			printf("\nexception:%x [%x] %x ", regs.trap, sp+16,
+			printf("exception:%x [%x] %x\n", regs.trap, sp+16,
 			       regs.nip);
 			sp = regs.gpr[1];
 			if (mread(sp, stack, sizeof(stack)) != sizeof(stack))
 				break;
 		}
-		printf("\n");
 	}
 }
 
@@ -859,11 +880,10 @@ excprint(struct pt_regs *fp)
 #ifdef CONFIG_SMP
 	printf("cpu %d: ", smp_processor_id());
 #endif /* CONFIG_SMP */
-	printf("vector: %x at pc = ", fp->trap);
-	pretty_print_addr(fp->nip);
-	printf(", lr = ");
-	pretty_print_addr(fp->link);
-	printf("\nmsr = %x, sp = %x [%x]\n", fp->msr, fp->gpr[1], fp);
+	printf("vector: %x at pc=", fp->trap);
+	xmon_print_symbol(fp->nip, ": ", ", lr=");
+	xmon_print_symbol(fp->link, ": ", "\n");
+	printf("msr = %x, sp = %x [%x]\n", fp->msr, fp->gpr[1], fp);
 	trap = TRAP(fp);
 	if (trap == 0x300 || trap == 0x600)
 		printf("dar = %x, dsisr = %x\n", fp->dar, fp->dsisr);
@@ -951,24 +971,6 @@ extern char exc_prolog;
 extern char dec_exc;
 
 void
-print_sysmap(void)
-{
-	extern char *sysmap;
-	if ( sysmap ) {
-		printf("System.map: \n");
-		if( setjmp(bus_error_jmp) == 0 ) {
-			debugger_fault_handler = handle_fault;
-			sync();
-			xmon_puts(sysmap);
-			sync();
-		}
-		debugger_fault_handler = NULL;
-	}
-	else
-		printf("No System.map\n");
-}
-
-void
 super_regs(void)
 {
 	int i, cmd;
@@ -1738,7 +1740,7 @@ scanhex(unsigned *vp)
 		printf("invalid register name '%%%s'\n", regname);
 		return 0;
 	} else if (c == '$') {
-		static char symname[64];
+		static char symname[128];
 		int i;
 		for (i=0; i<63; i++) {
 			c = inchar();
@@ -1749,7 +1751,14 @@ scanhex(unsigned *vp)
 			symname[i] = c;
 		}
 		symname[i++] = 0;
-		*vp = xmon_symbol_to_addr(symname);
+		*vp = 0;
+		if (setjmp(bus_error_jmp) == 0) {
+			debugger_fault_handler = handle_fault;
+			sync();
+			*vp = kallsyms_lookup_name(symname);
+			sync();
+		}
+		debugger_fault_handler = NULL;
 		if (!(*vp)) {
 			printf("unknown symbol\n");
 			return 0;
@@ -1840,169 +1849,34 @@ take_input(char *str)
 	lineptr = str;
 }
 
-void
-sysmap_lookup(void)
+static void
+symbol_lookup(void)
 {
 	int type = inchar();
 	unsigned addr;
-	static char tmp[64];
-	char* cur;
-
-	extern char *sysmap;
-	extern unsigned long sysmap_size;
-	if ( !sysmap || !sysmap_size )
-		return;
-
-	switch(type) {
-		case 'a':
-			if (scanhex(&addr)) {
-				pretty_print_addr(addr);
-				printf("\n");
-			}
-			termch = 0;
-			break;
-		case 's':
-			getstring(tmp, 64);
-			if( setjmp(bus_error_jmp) == 0 ) {
-				debugger_fault_handler = handle_fault;
-				sync();
-				cur = sysmap;
-				do {
-					cur = strstr(cur, tmp);
-					if (cur) {
-						static char res[64];
-						char *p, *d;
-						p = cur;
-						while(p > sysmap && *p != 10)
-							p--;
-						if (*p == 10) p++;
-						d = res;
-						while(*p && p < (sysmap + sysmap_size) && *p != 10)
-							*(d++) = *(p++);
-						*(d++) = 0;
-						printf("%s\n", res);
-						cur++;
-					}
-				} while (cur);
-				sync();
-			}
-			debugger_fault_handler = NULL;
-			termch = 0;
-			break;
-	}
-}
+	static char tmp[128];
 
-static int
-pretty_print_addr(unsigned long addr)
-{
-	char *sym;
-	unsigned long saddr;
-	
-	printf("%08x", addr);
-	sym = xmon_find_symbol(addr, &saddr);
-	if (sym)
-		printf(" (%s+0x%x)", sym, addr-saddr);
-	return (sym != 0);
-}
-
-char*
-xmon_find_symbol(unsigned long addr, unsigned long* saddr)
-{
-	static char rbuffer[64];
-	char *p, *ep, *limit;
-	unsigned long prev, next;
-	char* psym;
-
-	extern char *sysmap;
-	extern unsigned long sysmap_size;
-	if ( !sysmap || !sysmap_size )
-		return NULL;
-	
-	prev = 0;
-	psym = NULL;
-	p = sysmap;
-	limit = p + sysmap_size;
-	if( setjmp(bus_error_jmp) == 0 ) {
-		debugger_fault_handler = handle_fault;
-		sync();
-		do {
-			next = simple_strtoul(p, &p, 16);
-			if (next > addr && prev <= addr) {
-				if (!psym)
-					goto bail;
-				ep = rbuffer;
-				p = psym;
-				while(*p && p < limit && *p == 32)
-					p++;
-				while(*p && p < limit && *p != 10 && (ep - rbuffer) < 63)
-					*(ep++) = *(p++);
-				*(ep++) = 0;
-				if (saddr)
-					*saddr = prev;
-				debugger_fault_handler = NULL;
-				return rbuffer;
-			}
-			prev = next;
-			psym = p;
-			while(*p && p < limit && *p != 10)
-				p++;
-			if (*p) p++;
-		} while(*p && p < limit && next);
-bail:
-		sync();
+	switch (type) {
+	case 'a':
+		if (scanhex(&addr))
+			xmon_print_symbol(addr, ": ", "\n");
+		termch = 0;
+		break;
+	case 's':
+		getstring(tmp, 64);
+		if (setjmp(bus_error_jmp) == 0) {
+			debugger_fault_handler = handle_fault;
+			sync();
+			addr = kallsyms_lookup_name(tmp);
+			if (addr)
+				printf("%s: %lx\n", tmp, addr);
+			else
+				printf("Symbol '%s' not found.\n", tmp);
+			sync();
+		}
+		debugger_fault_handler = NULL;
+		termch = 0;
+		break;
 	}
-	debugger_fault_handler = NULL;
-	return NULL;
 }
 
-unsigned long
-xmon_symbol_to_addr(char* symbol)
-{
-	char *p, *cur;
-	char *match = NULL;
-	int goodness = 0;
-	int result = 0;
-	
-	extern char *sysmap;
-	extern unsigned long sysmap_size;
-	if ( !sysmap || !sysmap_size )
-		return 0;
-
-	if( setjmp(bus_error_jmp) == 0 ) {
-		debugger_fault_handler = handle_fault;
-		sync();
-		cur = sysmap;
-		while(cur) {
-			cur = strstr(cur, symbol);
-			if (cur) {
-				int gd = 1;
-
-				/* best match if equal, better match if
-				 * begins with
-				 */
-				if (cur == sysmap || *(cur-1) == ' ') {
-					gd++;
-					if (cur[strlen(symbol)] == 10)
-						gd++;
-				}
-				if (gd > goodness) {
-					match = cur;
-					goodness = gd;
-					if (gd == 3)
-						break;
-				}
-				cur++;
-			}
-		}	
-		if (goodness) {
-			p = match;
-			while(p > sysmap && *p != 10)
-				p--;
-			if (*p == 10) p++;
-			result = simple_strtoul(p, &p, 16);
-		}
-		sync();
-	}
-	debugger_fault_handler = NULL;
-	return result;
-}		
diff --git a/arch/ppc64/Kconfig b/arch/ppc64/Kconfig
--- a/arch/ppc64/Kconfig
+++ b/arch/ppc64/Kconfig
@@ -77,6 +77,10 @@ config PPC_PSERIES
 	bool "  IBM pSeries & new iSeries"
 	default y
 
+config PPC_BPA
+	bool "  Broadband Processor Architecture"
+	depends on PPC_MULTIPLATFORM
+
 config PPC_PMAC
 	depends on PPC_MULTIPLATFORM
 	bool "  Apple G5 based machines"
@@ -106,6 +110,21 @@ config PPC_OF
 	bool
 	default y
 
+config XICS
+	depends on PPC_PSERIES
+	bool
+	default y
+
+config MPIC
+	depends on PPC_PSERIES || PPC_PMAC || PPC_MAPLE
+	bool
+	default y
+
+config BPA_IIC
+	depends on PPC_BPA
+	bool
+	default y
+
 # VMX is pSeries only for now until somebody writes the iSeries
 # exception vectors for it
 config ALTIVEC
@@ -123,6 +142,23 @@ config PPC_SPLPAR
 	  processors, that is, which share physical processors between
 	  two or more partitions.
 
+config KEXEC
+	bool "kexec system call (EXPERIMENTAL)"
+	depends on PPC_MULTIPLATFORM && EXPERIMENTAL
+	help
+	  kexec is a system call that implements the ability to shutdown your
+	  current kernel, and to start another kernel.  It is like a reboot
+	  but it is indepedent of the system firmware.  And like a reboot
+	  you can start any kernel with it, not just Linux.
+
+	  The name comes from the similiarity to the exec system call.
+
+	  It is an ongoing process to be certain the hardware in a machine
+	  is properly shutdown, so do not be surprised if this code does not
+	  initially work for you.  It may help to enable device hotplugging
+	  support.  As of this writing the exact hardware interface is
+	  strongly in flux, so no good recommendation can be made.
+
 config IBMVIO
 	depends on PPC_PSERIES || PPC_ISERIES
 	bool
@@ -198,13 +234,49 @@ config HMT
 	  This option enables hardware multithreading on RS64 cpus.
 	  pSeries systems p620 and p660 have such a cpu type.
 
-config DISCONTIGMEM
-	bool "Discontiguous Memory Support"
+config ARCH_SELECT_MEMORY_MODEL
+	def_bool y
+
+config ARCH_FLATMEM_ENABLE
+       def_bool y
+       depends on !NUMA
+
+config ARCH_DISCONTIGMEM_ENABLE
+	def_bool y
 	depends on SMP && PPC_PSERIES
 
+config ARCH_DISCONTIGMEM_DEFAULT
+	def_bool y
+	depends on ARCH_DISCONTIGMEM_ENABLE
+
+config ARCH_FLATMEM_ENABLE
+	def_bool y
+
+config ARCH_SPARSEMEM_ENABLE
+	def_bool y
+	depends on ARCH_DISCONTIGMEM_ENABLE
+
+source "mm/Kconfig"
+
+config HAVE_ARCH_EARLY_PFN_TO_NID
+	def_bool y
+	depends on NEED_MULTIPLE_NODES
+
+# Some NUMA nodes have memory ranges that span
+# other nodes.  Even though a pfn is valid and
+# between a node's start and end pfns, it may not
+# reside on that node.
+#
+# This is a relatively temporary hack that should
+# be able to go away when sparsemem is fully in
+# place
+config NODES_SPAN_OTHER_NODES
+	def_bool y
+	depends on NEED_MULTIPLE_NODES
+
 config NUMA
 	bool "NUMA support"
-	depends on DISCONTIGMEM
+	default y if DISCONTIGMEM || SPARSEMEM
 
 config SCHED_SMT
 	bool "SMT (Hyperthreading) scheduler support"
@@ -215,26 +287,8 @@ config SCHED_SMT
 	  when dealing with POWER5 cpus at a cost of slightly increased
 	  overhead in some places. If unsure say N here.
 
-config PREEMPT
-	bool "Preemptible Kernel"
-	help
-	  This option reduces the latency of the kernel when reacting to
-	  real-time or interactive events by allowing a low priority process to
-	  be preempted even if it is in kernel mode executing a system call.
-
-	  Say Y here if you are building a kernel for a desktop, embedded
-	  or real-time system.  Say N if you are unsure.
-
-config PREEMPT_BKL
-	bool "Preempt The Big Kernel Lock"
-	depends on PREEMPT
-	default y
-	help
-	  This option reduces the latency of the kernel by making the
-	  big kernel lock preemptible.
-
-	  Say Y here if you are building a kernel for a desktop system.
-	  Say N if you are unsure.
+source "kernel/Kconfig.preempt"
+source kernel/Kconfig.hz
 
 config EEH
 	bool "PCI Extended Error Handling (EEH)" if EMBEDDED
@@ -256,7 +310,7 @@ config MSCHUNKS
 
 config PPC_RTAS
 	bool
-	depends on PPC_PSERIES
+	depends on PPC_PSERIES || PPC_BPA
 	default y
 
 config RTAS_PROC
@@ -323,7 +377,7 @@ config EISA
 	bool
 
 config PCI
-	bool
+	bool "support for PCI devices" if (EMBEDDED && PPC_ISERIES)
 	default y
 	help
 	  Find out whether your system includes a PCI bus. PCI is the name of
@@ -376,6 +430,8 @@ config CMDLINE
 
 endmenu
 
+source "net/Kconfig"
+
 source "drivers/Kconfig"
 
 source "fs/Kconfig"
diff --git a/arch/ppc64/Makefile b/arch/ppc64/Makefile
--- a/arch/ppc64/Makefile
+++ b/arch/ppc64/Makefile
@@ -35,9 +35,9 @@ CROSS32AS	:= $(AS) -a32
 CROSS32LD	:= $(LD) -m elf32ppc
 CROSS32OBJCOPY	:= $(OBJCOPY)
 endif
-AS              := $(AS) -a64
-LD              := $(LD) -m elf64ppc
-CC		:= $(CC) -m64
+override AS	+= -a64
+override LD	+= -m elf64ppc
+override CC	+= -m64
 endif
 
 export CROSS32CC CROSS32AS CROSS32LD CROSS32OBJCOPY
@@ -90,12 +90,14 @@ boot := arch/ppc64/boot
 boottarget-$(CONFIG_PPC_PSERIES) := zImage zImage.initrd
 boottarget-$(CONFIG_PPC_MAPLE) := zImage zImage.initrd
 boottarget-$(CONFIG_PPC_ISERIES) := vmlinux.sminitrd vmlinux.initrd vmlinux.sm
+boottarget-$(CONFIG_PPC_BPA) := zImage zImage.initrd
 $(boottarget-y): vmlinux
 	$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
 
 bootimage-$(CONFIG_PPC_PSERIES) := $(boot)/zImage
 bootimage-$(CONFIG_PPC_PMAC) := vmlinux
 bootimage-$(CONFIG_PPC_MAPLE) := $(boot)/zImage
+bootimage-$(CONFIG_PPC_BPA) := zImage
 bootimage-$(CONFIG_PPC_ISERIES) := vmlinux
 BOOTIMAGE := $(bootimage-y)
 install: vmlinux
diff --git a/arch/ppc64/boot/Makefile b/arch/ppc64/boot/Makefile
--- a/arch/ppc64/boot/Makefile
+++ b/arch/ppc64/boot/Makefile
@@ -52,7 +52,7 @@ obj-sec = $(foreach section, $(1), $(pat
 src-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.c, $(section)))
 gz-sec  = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.gz, $(section)))
 
-hostprogs-y		:= piggy addnote addRamDisk
+hostprogs-y		:= addnote addRamDisk
 targets 		+= zImage zImage.initrd imagesize.c \
 			   $(patsubst $(obj)/%,%, $(call obj-sec, $(required) $(initrd))) \
 			   $(patsubst $(obj)/%,%, $(call src-sec, $(required) $(initrd))) \
@@ -78,9 +78,6 @@ addsection = $(CROSS32OBJCOPY) $(1) \
 quiet_cmd_addnote = ADDNOTE $@ 
       cmd_addnote = $(CROSS32LD) $(BOOTLFLAGS) -o $@ $(obj-boot) && $(obj)/addnote $@
 
-quiet_cmd_piggy = PIGGY   $@
-      cmd_piggy = $(obj)/piggyback $(@:.o=) < $< | $(CROSS32AS) -o $@
-
 $(call gz-sec, $(required)): $(obj)/kernel-%.gz: % FORCE
 	$(call if_changed,gzip)
 
diff --git a/arch/ppc64/boot/install.sh b/arch/ppc64/boot/install.sh
--- a/arch/ppc64/boot/install.sh
+++ b/arch/ppc64/boot/install.sh
@@ -22,8 +22,8 @@
 
 # User may have a custom install script
 
-if [ -x ~/bin/installkernel ]; then exec ~/bin/installkernel "$@"; fi
-if [ -x /sbin/installkernel ]; then exec /sbin/installkernel "$@"; fi
+if [ -x ~/bin/${CROSS_COMPILE}installkernel ]; then exec ~/bin/${CROSS_COMPILE}installkernel "$@"; fi
+if [ -x /sbin/${CROSS_COMPILE}installkernel ]; then exec /sbin/${CROSS_COMPILE}installkernel "$@"; fi
 
 # Default install
 
diff --git a/arch/ppc64/boot/main.c b/arch/ppc64/boot/main.c
--- a/arch/ppc64/boot/main.c
+++ b/arch/ppc64/boot/main.c
@@ -17,7 +17,6 @@
 
 extern void *finddevice(const char *);
 extern int getprop(void *, const char *, void *, int);
-extern void printk(char *fmt, ...);
 extern void printf(const char *fmt, ...);
 extern int sprintf(char *buf, const char *fmt, ...);
 void gunzip(void *, int, unsigned char *, int *);
@@ -147,10 +146,10 @@ void start(unsigned long a1, unsigned lo
 		}
 		a1 = initrd.addr;
 		a2 = initrd.size;
-		printf("initial ramdisk moving 0x%lx <- 0x%lx (%lx bytes)\n\r",
+		printf("initial ramdisk moving 0x%lx <- 0x%lx (0x%lx bytes)\n\r",
 		       initrd.addr, (unsigned long)_initrd_start, initrd.size);
 		memmove((void *)initrd.addr, (void *)_initrd_start, initrd.size);
-		printf("initrd head: 0x%lx\n\r", *((u32 *)initrd.addr));
+		printf("initrd head: 0x%lx\n\r", *((unsigned long *)initrd.addr));
 	}
 
 	/* Eventually gunzip the kernel */
@@ -201,9 +200,6 @@ void start(unsigned long a1, unsigned lo
 
 	flush_cache((void *)vmlinux.addr, vmlinux.size);
 
-	if (a1)
-		printf("initrd head: 0x%lx\n\r", *((u32 *)initrd.addr));
-
 	kernel_entry = (kernel_entry_t)vmlinux.addr;
 #ifdef DEBUG
 	printf( "kernel:\n\r"
diff --git a/arch/ppc64/boot/mknote.c b/arch/ppc64/boot/mknote.c
deleted file mode 100644
--- a/arch/ppc64/boot/mknote.c
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) Cort Dougan 1999.
- *
- * 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.
- *
- * Generate a note section as per the CHRP specification.
- *
- */
-
-#include <stdio.h>
-
-#define PL(x) printf("%c%c%c%c", ((x)>>24)&0xff, ((x)>>16)&0xff, ((x)>>8)&0xff, (x)&0xff );
-
-int main(void)
-{
-/* header */
-	/* namesz */
-	PL(strlen("PowerPC")+1);
-	/* descrsz */
-	PL(6*4);
-	/* type */
-	PL(0x1275);
-	/* name */
-	printf("PowerPC"); printf("%c", 0);
-	
-/* descriptor */
-	/* real-mode */
-	PL(0xffffffff);
-	/* real-base */
-	PL(0x00c00000);
-	/* real-size */
-	PL(0xffffffff);
-	/* virt-base */
-	PL(0xffffffff);
-	/* virt-size */
-	PL(0xffffffff);
-	/* load-base */
-	PL(0x4000);
-	return 0;
-}
diff --git a/arch/ppc64/boot/piggyback.c b/arch/ppc64/boot/piggyback.c
deleted file mode 100644
--- a/arch/ppc64/boot/piggyback.c
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright 2001 IBM Corp 
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-#include <stdio.h>
-#include <unistd.h>
-#include <string.h>
-
-extern long ce_exec_config[];
-
-int main(int argc, char *argv[])
-{
-	int i, cnt, pos, len;
-	unsigned int cksum, val;
-	unsigned char *lp;
-	unsigned char buf[8192];
-	char *varname;
-	if (argc != 2)
-	{
-		fprintf(stderr, "usage: %s name <in-file >out-file\n",
-			argv[0]);
-		exit(1);
-	}
-
-	varname = strrchr(argv[1], '/');
-	if (varname)
-		varname++;
-	else
-		varname = argv[1];
-
-	fprintf(stdout, "#\n");
-	fprintf(stdout, "# Miscellaneous data structures:\n");
-	fprintf(stdout, "# WARNING - this file is automatically generated!\n");
-	fprintf(stdout, "#\n");
-	fprintf(stdout, "\n");
-	fprintf(stdout, "\t.data\n");
-	fprintf(stdout, "\t.globl %s_data\n", varname);
-	fprintf(stdout, "%s_data:\n", varname);
-	pos = 0;
-	cksum = 0;
-	while ((len = read(0, buf, sizeof(buf))) > 0)
-	{
-		cnt = 0;
-		lp = (unsigned char *)buf;
-		len = (len + 3) & ~3;  /* Round up to longwords */
-		for (i = 0;  i < len;  i += 4)
-		{
-			if (cnt == 0)
-			{
-				fprintf(stdout, "\t.long\t");
-			}
-			fprintf(stdout, "0x%02X%02X%02X%02X", lp[0], lp[1], lp[2], lp[3]);
-			val = *(unsigned long *)lp;
-			cksum ^= val;
-			lp += 4;
-			if (++cnt == 4)
-			{
-				cnt = 0;
-				fprintf(stdout, " # %x \n", pos+i-12);
-				fflush(stdout);
-			} else
-			{
-				fprintf(stdout, ",");
-			}
-		}
-		if (cnt)
-		{
-			fprintf(stdout, "0\n");
-		}
-		pos += len;
-	}
-	fprintf(stdout, "\t.globl %s_len\n", varname);
-	fprintf(stdout, "%s_len:\t.long\t0x%x\n", varname, pos);
-	fflush(stdout);
-	fclose(stdout);
-	fprintf(stderr, "cksum = %x\n", cksum);
-	exit(0);
-}
-
diff --git a/arch/ppc64/boot/prom.c b/arch/ppc64/boot/prom.c
--- a/arch/ppc64/boot/prom.c
+++ b/arch/ppc64/boot/prom.c
@@ -40,7 +40,7 @@ void *finddevice(const char *name);
 int getprop(void *phandle, const char *name, void *buf, int buflen);
 void chrpboot(int a1, int a2, void *prom);	/* in main.c */
 
-void printk(char *fmt, ...);
+int printf(char *fmt, ...);
 
 /* there is no convenient header to get this from...  -- paulus */
 extern unsigned long strlen(const char *);
@@ -220,7 +220,7 @@ readchar(void)
 		case 1:
 			return ch;
 		case -1:
-			printk("read(stdin) returned -1\r\n");
+			printf("read(stdin) returned -1\r\n");
 			return -1;
 		}
 	}
@@ -627,18 +627,6 @@ int sprintf(char * buf, const char *fmt,
 
 static char sprint_buf[1024];
 
-void
-printk(char *fmt, ...)
-{
-	va_list args;
-	int n;
-
-	va_start(args, fmt);
-	n = vsprintf(sprint_buf, fmt, args);
-	va_end(args);
-	write(stdout, sprint_buf, n);
-}
-
 int
 printf(char *fmt, ...)
 {
diff --git a/arch/ppc64/boot/zlib.c b/arch/ppc64/boot/zlib.c
--- a/arch/ppc64/boot/zlib.c
+++ b/arch/ppc64/boot/zlib.c
@@ -1307,7 +1307,7 @@ local int huft_build(
   {
     *t = (inflate_huft *)Z_NULL;
     *m = 0;
-    return Z_OK;
+    return Z_DATA_ERROR;
   }
 
 
@@ -1351,6 +1351,7 @@ local int huft_build(
     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 */
diff --git a/arch/ppc64/configs/bpa_defconfig b/arch/ppc64/configs/bpa_defconfig
new file mode 100644
--- /dev/null
+++ b/arch/ppc64/configs/bpa_defconfig
@@ -0,0 +1,987 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.13-rc6
+# Mon Aug  8 14:12:19 2005
+#
+CONFIG_64BIT=y
+CONFIG_MMU=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_ISA_DMA=y
+CONFIG_HAVE_DEC_LOCK=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_COMPAT=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_FORCE_MAX_ZONEORDER=13
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+# CONFIG_CPUSETS is not set
+# CONFIG_EMBEDDED is not set
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+# CONFIG_KMOD is not set
+CONFIG_STOP_MACHINE=y
+CONFIG_SYSVIPC_COMPAT=y
+
+#
+# Platform support
+#
+# CONFIG_PPC_ISERIES is not set
+CONFIG_PPC_MULTIPLATFORM=y
+# CONFIG_PPC_PSERIES is not set
+CONFIG_PPC_BPA=y
+# CONFIG_PPC_PMAC is not set
+# CONFIG_PPC_MAPLE is not set
+CONFIG_PPC=y
+CONFIG_PPC64=y
+CONFIG_PPC_OF=y
+CONFIG_BPA_IIC=y
+CONFIG_ALTIVEC=y
+CONFIG_KEXEC=y
+# CONFIG_U3_DART is not set
+# CONFIG_BOOTX_TEXT is not set
+# CONFIG_POWER4_ONLY is not set
+# CONFIG_IOMMU_VMERGE is not set
+CONFIG_SMP=y
+CONFIG_NR_CPUS=4
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_NUMA is not set
+CONFIG_SCHED_SMT=y
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_PREEMPT_BKL=y
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_PPC_RTAS=y
+CONFIG_RTAS_PROC=y
+CONFIG_RTAS_FLASH=y
+CONFIG_SECCOMP=y
+CONFIG_ISA_DMA_API=y
+
+#
+# General setup
+#
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_PCI_LEGACY_PROC=y
+CONFIG_PCI_NAMES=y
+# CONFIG_PCI_DEBUG is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+CONFIG_PROC_DEVICETREE=y
+# CONFIG_CMDLINE_BOOL is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_PNP is not set
+CONFIG_NET_IPIP=y
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=y
+CONFIG_IP_TCPDIAG=y
+CONFIG_IP_TCPDIAG_IPV6=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS is not set
+CONFIG_IPV6=y
+# CONFIG_IPV6_PRIVACY is not set
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_INET6_TUNNEL=m
+CONFIG_IPV6_TUNNEL=m
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_IP_NF_CONNTRACK=y
+# CONFIG_IP_NF_CT_ACCT is not set
+# CONFIG_IP_NF_CONNTRACK_MARK is not set
+CONFIG_IP_NF_CT_PROTO_SCTP=y
+CONFIG_IP_NF_FTP=m
+CONFIG_IP_NF_IRC=m
+CONFIG_IP_NF_TFTP=m
+CONFIG_IP_NF_AMANDA=m
+CONFIG_IP_NF_QUEUE=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_LIMIT=m
+CONFIG_IP_NF_MATCH_IPRANGE=m
+CONFIG_IP_NF_MATCH_MAC=m
+CONFIG_IP_NF_MATCH_PKTTYPE=m
+CONFIG_IP_NF_MATCH_MARK=m
+CONFIG_IP_NF_MATCH_MULTIPORT=m
+CONFIG_IP_NF_MATCH_TOS=m
+CONFIG_IP_NF_MATCH_RECENT=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_DSCP=m
+CONFIG_IP_NF_MATCH_AH_ESP=m
+CONFIG_IP_NF_MATCH_LENGTH=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_MATCH_TCPMSS=m
+CONFIG_IP_NF_MATCH_HELPER=m
+CONFIG_IP_NF_MATCH_STATE=m
+CONFIG_IP_NF_MATCH_CONNTRACK=m
+CONFIG_IP_NF_MATCH_OWNER=m
+CONFIG_IP_NF_MATCH_ADDRTYPE=m
+CONFIG_IP_NF_MATCH_REALM=m
+CONFIG_IP_NF_MATCH_SCTP=m
+CONFIG_IP_NF_MATCH_COMMENT=m
+CONFIG_IP_NF_MATCH_HASHLIMIT=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_LOG=m
+CONFIG_IP_NF_TARGET_ULOG=m
+CONFIG_IP_NF_TARGET_TCPMSS=m
+CONFIG_IP_NF_NAT=m
+CONFIG_IP_NF_NAT_NEEDED=y
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_TARGET_REDIRECT=m
+CONFIG_IP_NF_TARGET_NETMAP=m
+CONFIG_IP_NF_TARGET_SAME=m
+CONFIG_IP_NF_NAT_SNMP_BASIC=m
+CONFIG_IP_NF_NAT_IRC=m
+CONFIG_IP_NF_NAT_FTP=m
+CONFIG_IP_NF_NAT_TFTP=m
+CONFIG_IP_NF_NAT_AMANDA=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_TOS=m
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_DSCP=m
+CONFIG_IP_NF_TARGET_MARK=m
+CONFIG_IP_NF_TARGET_CLASSIFY=m
+CONFIG_IP_NF_RAW=m
+CONFIG_IP_NF_TARGET_NOTRACK=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+
+#
+# IPv6: Netfilter Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP6_NF_QUEUE is not set
+# CONFIG_IP6_NF_IPTABLES is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+CONFIG_NET_CLS_ROUTE=y
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+# CONFIG_DEBUG_DRIVER is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+CONFIG_BLK_DEV_NBD=y
+# CONFIG_BLK_DEV_SX8 is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=131072
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CDROM_PKTCDVD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=y
+CONFIG_IDEDISK_MULTI_MODE=y
+# CONFIG_BLK_DEV_IDECD is not set
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+CONFIG_BLK_DEV_IDEPCI=y
+CONFIG_IDEPCI_SHARE_IRQ=y
+# CONFIG_BLK_DEV_OFFBOARD is not set
+CONFIG_BLK_DEV_GENERIC=y
+# CONFIG_BLK_DEV_OPTI621 is not set
+# CONFIG_BLK_DEV_SL82C105 is not set
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
+CONFIG_IDEDMA_PCI_AUTO=y
+# CONFIG_IDEDMA_ONLYDISK is not set
+CONFIG_BLK_DEV_AEC62XX=y
+# CONFIG_BLK_DEV_ALI15X3 is not set
+# CONFIG_BLK_DEV_AMD74XX is not set
+# CONFIG_BLK_DEV_CMD64X is not set
+# CONFIG_BLK_DEV_TRIFLEX is not set
+# CONFIG_BLK_DEV_CY82C693 is not set
+# CONFIG_BLK_DEV_CS5520 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_HPT34X is not set
+# CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_SC1200 is not set
+# CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_BLK_DEV_IT821X is not set
+# CONFIG_BLK_DEV_NS87415 is not set
+# CONFIG_BLK_DEV_PDC202XX_OLD is not set
+# CONFIG_BLK_DEV_PDC202XX_NEW is not set
+# CONFIG_BLK_DEV_SVWKS is not set
+CONFIG_BLK_DEV_SIIMAGE=y
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+# CONFIG_BLK_DEV_VIA82CXXX is not set
+# CONFIG_IDE_ARM is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_IVB is not set
+CONFIG_IDEDMA_AUTO=y
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+# CONFIG_SCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Macintosh device drivers
+#
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_PCI is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+CONFIG_E1000=m
+# CONFIG_E1000_NAPI is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+CONFIG_SKGE=m
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+# CONFIG_MV643XX_ETH is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_SERIAL_NONSTANDARD=y
+# CONFIG_ROCKETPORT is not set
+# CONFIG_CYCLADES is not set
+# CONFIG_MOXA_SMARTIO is not set
+# CONFIG_ISI is not set
+# CONFIG_SYNCLINK is not set
+# CONFIG_SYNCLINKMP is not set
+# CONFIG_N_HDLC is not set
+# CONFIG_SPECIALIX is not set
+# CONFIG_SX is not set
+# CONFIG_STALDRV is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_WATCHDOG_RTAS=y
+
+#
+# PCI-based Watchdog Cards
+#
+# CONFIG_PCIPCWATCHDOG is not set
+# CONFIG_WDTPCI is not set
+# CONFIG_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_HANGCHECK_TIMER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
+# I2C support
+#
+CONFIG_I2C=y
+# CONFIG_I2C_CHARDEV is not set
+
+#
+# I2C Algorithms
+#
+CONFIG_I2C_ALGOBIT=y
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+
+#
+# I2C Hardware Bus support
+#
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+# CONFIG_I2C_AMD8111 is not set
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_I810 is not set
+# CONFIG_I2C_PIIX4 is not set
+# CONFIG_I2C_ISA is not set
+# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_PROSAVAGE is not set
+# CONFIG_I2C_SAVAGE4 is not set
+# CONFIG_SCx200_ACB is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+# CONFIG_I2C_VOODOO3 is not set
+# CONFIG_I2C_PCA_ISA is not set
+# CONFIG_I2C_SENSOR is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_RTC8564 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+# CONFIG_USB is not set
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# SN Devices
+#
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+
+#
+# XFS support
+#
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+# CONFIG_ZISOFS is not set
+CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+# CONFIG_DEVPTS_FS_XATTR is not set
+CONFIG_TMPFS=y
+CONFIG_TMPFS_XATTR=y
+# CONFIG_TMPFS_SECURITY is not set
+CONFIG_HUGETLBFS=y
+CONFIG_HUGETLB_PAGE=y
+CONFIG_RAMFS=y
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+CONFIG_NFSD=m
+CONFIG_NFSD_V2_ACL=y
+CONFIG_NFSD_V3=y
+CONFIG_NFSD_V3_ACL=y
+# CONFIG_NFSD_V4 is not set
+CONFIG_NFSD_TCP=y
+CONFIG_LOCKD=m
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
+CONFIG_NFS_ACL_SUPPORT=m
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=m
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+CONFIG_EFI_PARTITION=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS=m
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_LOG_BUF_SHIFT=15
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+CONFIG_DEBUG_SPINLOCK_SLEEP=y
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_INFO is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_DEBUG_STACKOVERFLOW is not set
+# CONFIG_KPROBES is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+CONFIG_DEBUGGER=y
+# CONFIG_XMON is not set
+# CONFIG_PPCDBG is not set
+CONFIG_IRQSTACKS=y
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=m
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_WP512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+CONFIG_CRYPTO_DES=m
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+CONFIG_CRYPTO_DEFLATE=m
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
diff --git a/arch/ppc64/configs/g5_defconfig b/arch/ppc64/configs/g5_defconfig
--- a/arch/ppc64/configs/g5_defconfig
+++ b/arch/ppc64/configs/g5_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc6
-# Tue Jun 14 16:59:20 2005
+# Linux kernel version: 2.6.13-rc6
+# Mon Aug  8 14:16:59 2005
 #
 CONFIG_64BIT=y
 CONFIG_MMU=y
@@ -73,12 +73,15 @@ CONFIG_SYSVIPC_COMPAT=y
 # CONFIG_PPC_ISERIES is not set
 CONFIG_PPC_MULTIPLATFORM=y
 # CONFIG_PPC_PSERIES is not set
+# CONFIG_PPC_BPA is not set
 CONFIG_PPC_PMAC=y
 # CONFIG_PPC_MAPLE is not set
 CONFIG_PPC=y
 CONFIG_PPC64=y
 CONFIG_PPC_OF=y
+CONFIG_MPIC=y
 CONFIG_ALTIVEC=y
+CONFIG_KEXEC=y
 CONFIG_U3_DART=y
 CONFIG_PPC_PMAC64=y
 CONFIG_BOOTX_TEXT=y
@@ -86,8 +89,24 @@ CONFIG_POWER4_ONLY=y
 CONFIG_IOMMU_VMERGE=y
 CONFIG_SMP=y
 CONFIG_NR_CPUS=2
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_NUMA is not set
 # CONFIG_SCHED_SMT is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+# CONFIG_PREEMPT_BKL is not set
+CONFIG_HZ_100=y
+# CONFIG_HZ_250 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=100
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_SECCOMP=y
 CONFIG_ISA_DMA_API=y
@@ -117,6 +136,142 @@ CONFIG_PROC_DEVICETREE=y
 # CONFIG_CMDLINE_BOOL is not set
 
 #
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=m
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_PNP is not set
+CONFIG_NET_IPIP=y
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_TUNNEL=y
+CONFIG_IP_TCPDIAG=m
+# CONFIG_IP_TCPDIAG_IPV6 is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS is not set
+# CONFIG_IPV6 is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_IP_NF_CONNTRACK=m
+CONFIG_IP_NF_CT_ACCT=y
+CONFIG_IP_NF_CONNTRACK_MARK=y
+CONFIG_IP_NF_CT_PROTO_SCTP=m
+CONFIG_IP_NF_FTP=m
+CONFIG_IP_NF_IRC=m
+CONFIG_IP_NF_TFTP=m
+CONFIG_IP_NF_AMANDA=m
+CONFIG_IP_NF_QUEUE=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_LIMIT=m
+CONFIG_IP_NF_MATCH_IPRANGE=m
+CONFIG_IP_NF_MATCH_MAC=m
+CONFIG_IP_NF_MATCH_PKTTYPE=m
+CONFIG_IP_NF_MATCH_MARK=m
+CONFIG_IP_NF_MATCH_MULTIPORT=m
+CONFIG_IP_NF_MATCH_TOS=m
+CONFIG_IP_NF_MATCH_RECENT=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_DSCP=m
+CONFIG_IP_NF_MATCH_AH_ESP=m
+CONFIG_IP_NF_MATCH_LENGTH=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_MATCH_TCPMSS=m
+CONFIG_IP_NF_MATCH_HELPER=m
+CONFIG_IP_NF_MATCH_STATE=m
+CONFIG_IP_NF_MATCH_CONNTRACK=m
+CONFIG_IP_NF_MATCH_OWNER=m
+CONFIG_IP_NF_MATCH_ADDRTYPE=m
+CONFIG_IP_NF_MATCH_REALM=m
+CONFIG_IP_NF_MATCH_SCTP=m
+CONFIG_IP_NF_MATCH_COMMENT=m
+CONFIG_IP_NF_MATCH_CONNMARK=m
+CONFIG_IP_NF_MATCH_HASHLIMIT=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_LOG=m
+CONFIG_IP_NF_TARGET_ULOG=m
+CONFIG_IP_NF_TARGET_TCPMSS=m
+CONFIG_IP_NF_NAT=m
+CONFIG_IP_NF_NAT_NEEDED=y
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_TARGET_REDIRECT=m
+CONFIG_IP_NF_TARGET_NETMAP=m
+CONFIG_IP_NF_TARGET_SAME=m
+CONFIG_IP_NF_NAT_SNMP_BASIC=m
+CONFIG_IP_NF_NAT_IRC=m
+CONFIG_IP_NF_NAT_FTP=m
+CONFIG_IP_NF_NAT_TFTP=m
+CONFIG_IP_NF_NAT_AMANDA=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_TOS=m
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_DSCP=m
+CONFIG_IP_NF_TARGET_MARK=m
+CONFIG_IP_NF_TARGET_CLASSIFY=m
+CONFIG_IP_NF_TARGET_CONNMARK=m
+CONFIG_IP_NF_TARGET_CLUSTERIP=m
+CONFIG_IP_NF_RAW=m
+CONFIG_IP_NF_TARGET_NOTRACK=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+CONFIG_LLC=y
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+CONFIG_NET_CLS_ROUTE=y
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+
+#
 # Device Drivers
 #
 
@@ -218,6 +373,7 @@ CONFIG_IDEDMA_PCI_AUTO=y
 # CONFIG_BLK_DEV_HPT366 is not set
 # CONFIG_BLK_DEV_SC1200 is not set
 # CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_BLK_DEV_IT821X is not set
 # CONFIG_BLK_DEV_NS87415 is not set
 # CONFIG_BLK_DEV_PDC202XX_OLD is not set
 # CONFIG_BLK_DEV_PDC202XX_NEW is not set
@@ -251,6 +407,7 @@ CONFIG_CHR_DEV_ST=y
 CONFIG_BLK_DEV_SR=y
 CONFIG_BLK_DEV_SR_VENDOR=y
 CONFIG_CHR_DEV_SG=y
+# CONFIG_CHR_DEV_SCH is not set
 
 #
 # Some SCSI devices (e.g. CD jukebox) support multiple LUNs
@@ -309,6 +466,7 @@ CONFIG_SCSI_QLA2XXX=y
 # CONFIG_SCSI_QLA2300 is not set
 # CONFIG_SCSI_QLA2322 is not set
 # CONFIG_SCSI_QLA6312 is not set
+# CONFIG_SCSI_QLA24XX is not set
 # CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
@@ -338,6 +496,8 @@ CONFIG_DM_ZERO=m
 # Fusion MPT device support
 #
 # CONFIG_FUSION is not set
+# CONFIG_FUSION_SPI is not set
+# CONFIG_FUSION_FC is not set
 
 #
 # IEEE 1394 (FireWire) support
@@ -351,6 +511,7 @@ CONFIG_IEEE1394=y
 CONFIG_IEEE1394_OUI_DB=y
 CONFIG_IEEE1394_EXTRA_CONFIG_ROMS=y
 CONFIG_IEEE1394_CONFIG_ROM_IP1394=y
+# CONFIG_IEEE1394_EXPORT_FULL_API is not set
 
 #
 # Device Drivers
@@ -377,152 +538,14 @@ CONFIG_IEEE1394_RAWIO=y
 #
 # Macintosh device drivers
 #
-CONFIG_ADB=y
 CONFIG_ADB_PMU=y
 CONFIG_PMAC_SMU=y
-# CONFIG_PMAC_PBOOK is not set
 # CONFIG_PMAC_BACKLIGHT is not set
-# CONFIG_INPUT_ADBHID is not set
 CONFIG_THERM_PM72=y
 
 #
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
+# Network device support
 #
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-CONFIG_UNIX=y
-CONFIG_NET_KEY=m
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-# CONFIG_IP_PNP is not set
-CONFIG_NET_IPIP=y
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
-# CONFIG_ARPD is not set
-CONFIG_SYN_COOKIES=y
-CONFIG_INET_AH=m
-CONFIG_INET_ESP=m
-CONFIG_INET_IPCOMP=m
-CONFIG_INET_TUNNEL=y
-CONFIG_IP_TCPDIAG=m
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-
-#
-# IP: Virtual Server Configuration
-#
-# CONFIG_IP_VS is not set
-# CONFIG_IPV6 is not set
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-
-#
-# IP: Netfilter Configuration
-#
-CONFIG_IP_NF_CONNTRACK=m
-CONFIG_IP_NF_CT_ACCT=y
-CONFIG_IP_NF_CONNTRACK_MARK=y
-CONFIG_IP_NF_CT_PROTO_SCTP=m
-CONFIG_IP_NF_FTP=m
-CONFIG_IP_NF_IRC=m
-CONFIG_IP_NF_TFTP=m
-CONFIG_IP_NF_AMANDA=m
-CONFIG_IP_NF_QUEUE=m
-CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_MATCH_LIMIT=m
-CONFIG_IP_NF_MATCH_IPRANGE=m
-CONFIG_IP_NF_MATCH_MAC=m
-CONFIG_IP_NF_MATCH_PKTTYPE=m
-CONFIG_IP_NF_MATCH_MARK=m
-CONFIG_IP_NF_MATCH_MULTIPORT=m
-CONFIG_IP_NF_MATCH_TOS=m
-CONFIG_IP_NF_MATCH_RECENT=m
-CONFIG_IP_NF_MATCH_ECN=m
-CONFIG_IP_NF_MATCH_DSCP=m
-CONFIG_IP_NF_MATCH_AH_ESP=m
-CONFIG_IP_NF_MATCH_LENGTH=m
-CONFIG_IP_NF_MATCH_TTL=m
-CONFIG_IP_NF_MATCH_TCPMSS=m
-CONFIG_IP_NF_MATCH_HELPER=m
-CONFIG_IP_NF_MATCH_STATE=m
-CONFIG_IP_NF_MATCH_CONNTRACK=m
-CONFIG_IP_NF_MATCH_OWNER=m
-CONFIG_IP_NF_MATCH_ADDRTYPE=m
-CONFIG_IP_NF_MATCH_REALM=m
-CONFIG_IP_NF_MATCH_SCTP=m
-CONFIG_IP_NF_MATCH_COMMENT=m
-CONFIG_IP_NF_MATCH_CONNMARK=m
-CONFIG_IP_NF_MATCH_HASHLIMIT=m
-CONFIG_IP_NF_FILTER=m
-CONFIG_IP_NF_TARGET_REJECT=m
-CONFIG_IP_NF_TARGET_LOG=m
-CONFIG_IP_NF_TARGET_ULOG=m
-CONFIG_IP_NF_TARGET_TCPMSS=m
-CONFIG_IP_NF_NAT=m
-CONFIG_IP_NF_NAT_NEEDED=y
-CONFIG_IP_NF_TARGET_MASQUERADE=m
-CONFIG_IP_NF_TARGET_REDIRECT=m
-CONFIG_IP_NF_TARGET_NETMAP=m
-CONFIG_IP_NF_TARGET_SAME=m
-CONFIG_IP_NF_NAT_SNMP_BASIC=m
-CONFIG_IP_NF_NAT_IRC=m
-CONFIG_IP_NF_NAT_FTP=m
-CONFIG_IP_NF_NAT_TFTP=m
-CONFIG_IP_NF_NAT_AMANDA=m
-CONFIG_IP_NF_MANGLE=m
-CONFIG_IP_NF_TARGET_TOS=m
-CONFIG_IP_NF_TARGET_ECN=m
-CONFIG_IP_NF_TARGET_DSCP=m
-CONFIG_IP_NF_TARGET_MARK=m
-CONFIG_IP_NF_TARGET_CLASSIFY=m
-CONFIG_IP_NF_TARGET_CONNMARK=m
-CONFIG_IP_NF_TARGET_CLUSTERIP=m
-CONFIG_IP_NF_RAW=m
-CONFIG_IP_NF_TARGET_NOTRACK=m
-CONFIG_IP_NF_ARPTABLES=m
-CONFIG_IP_NF_ARPFILTER=m
-CONFIG_IP_NF_ARP_MANGLE=m
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-CONFIG_LLC=y
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-CONFIG_NET_CLS_ROUTE=y
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
 CONFIG_NETDEVICES=y
 CONFIG_DUMMY=m
 CONFIG_BONDING=m
@@ -562,6 +585,7 @@ CONFIG_E1000=y
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
 # CONFIG_R8169 is not set
+# CONFIG_SKGE is not set
 # CONFIG_SK98LIN is not set
 CONFIG_TIGON3=m
 # CONFIG_BNX2 is not set
@@ -604,6 +628,8 @@ CONFIG_PPPOE=m
 # CONFIG_NET_FC is not set
 # CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
 
 #
 # ISDN subsystem
@@ -691,7 +717,6 @@ CONFIG_LEGACY_PTY_COUNT=256
 #
 # CONFIG_WATCHDOG is not set
 # CONFIG_RTC is not set
-# CONFIG_GEN_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -750,50 +775,19 @@ CONFIG_I2C_KEYWEST=y
 # CONFIG_I2C_VIAPRO is not set
 # CONFIG_I2C_VOODOO3 is not set
 # CONFIG_I2C_PCA_ISA is not set
-
-#
-# Hardware Sensors Chip support
-#
 # CONFIG_I2C_SENSOR is not set
-# CONFIG_SENSORS_ADM1021 is not set
-# CONFIG_SENSORS_ADM1025 is not set
-# CONFIG_SENSORS_ADM1026 is not set
-# CONFIG_SENSORS_ADM1031 is not set
-# CONFIG_SENSORS_ASB100 is not set
-# CONFIG_SENSORS_DS1621 is not set
-# CONFIG_SENSORS_FSCHER is not set
-# CONFIG_SENSORS_FSCPOS is not set
-# CONFIG_SENSORS_GL518SM is not set
-# CONFIG_SENSORS_GL520SM is not set
-# CONFIG_SENSORS_IT87 is not set
-# CONFIG_SENSORS_LM63 is not set
-# CONFIG_SENSORS_LM75 is not set
-# CONFIG_SENSORS_LM77 is not set
-# CONFIG_SENSORS_LM78 is not set
-# CONFIG_SENSORS_LM80 is not set
-# CONFIG_SENSORS_LM83 is not set
-# CONFIG_SENSORS_LM85 is not set
-# CONFIG_SENSORS_LM87 is not set
-# CONFIG_SENSORS_LM90 is not set
-# CONFIG_SENSORS_LM92 is not set
-# CONFIG_SENSORS_MAX1619 is not set
-# CONFIG_SENSORS_PC87360 is not set
-# CONFIG_SENSORS_SMSC47B397 is not set
-# CONFIG_SENSORS_SIS5595 is not set
-# CONFIG_SENSORS_SMSC47M1 is not set
-# CONFIG_SENSORS_VIA686A is not set
-# CONFIG_SENSORS_W83781D is not set
-# CONFIG_SENSORS_W83L785TS is not set
-# CONFIG_SENSORS_W83627HF is not set
 
 #
-# Other I2C Chip support
+# Miscellaneous I2C Chip support
 #
 # CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
 # CONFIG_SENSORS_EEPROM is not set
 # CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_SENSORS_PCA9539 is not set
 # CONFIG_SENSORS_PCF8591 is not set
 # CONFIG_SENSORS_RTC8564 is not set
+# CONFIG_SENSORS_MAX6875 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
@@ -805,6 +799,11 @@ CONFIG_I2C_KEYWEST=y
 # CONFIG_W1 is not set
 
 #
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+
+#
 # Misc devices
 #
 
@@ -911,6 +910,7 @@ CONFIG_USB_DEVICEFS=y
 CONFIG_USB_EHCI_HCD=y
 # CONFIG_USB_EHCI_SPLIT_ISO is not set
 # CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+# CONFIG_USB_ISP116X_HCD is not set
 CONFIG_USB_OHCI_HCD=y
 # CONFIG_USB_OHCI_BIG_ENDIAN is not set
 CONFIG_USB_OHCI_LITTLE_ENDIAN=y
@@ -950,12 +950,15 @@ CONFIG_THRUSTMASTER_FF=y
 CONFIG_USB_HIDDEV=y
 # CONFIG_USB_AIPTEK is not set
 # CONFIG_USB_WACOM is not set
+# CONFIG_USB_ACECAD is not set
 # CONFIG_USB_KBTAB is not set
 # CONFIG_USB_POWERMATE is not set
 # CONFIG_USB_MTOUCH is not set
+# CONFIG_USB_ITMTOUCH is not set
 # CONFIG_USB_EGALAX is not set
 # CONFIG_USB_XPAD is not set
 # CONFIG_USB_ATI_REMOTE is not set
+# CONFIG_USB_KEYSPAN_REMOTE is not set
 
 #
 # USB Imaging devices
@@ -1071,10 +1074,11 @@ CONFIG_USB_EZUSB=y
 # CONFIG_USB_PHIDGETSERVO is not set
 # CONFIG_USB_IDMOUSE is not set
 # CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
 # CONFIG_USB_TEST is not set
 
 #
-# USB ATM/DSL drivers
+# USB DSL modem support
 #
 
 #
@@ -1093,12 +1097,18 @@ CONFIG_USB_EZUSB=y
 # CONFIG_INFINIBAND is not set
 
 #
+# SN Devices
+#
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
 CONFIG_EXT2_FS_XATTR=y
 CONFIG_EXT2_FS_POSIX_ACL=y
 CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT2_FS_XIP=y
+CONFIG_FS_XIP=y
 CONFIG_EXT3_FS=y
 CONFIG_EXT3_FS_XATTR=y
 CONFIG_EXT3_FS_POSIX_ACL=y
@@ -1126,6 +1136,7 @@ CONFIG_XFS_SECURITY=y
 CONFIG_XFS_POSIX_ACL=y
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
 # CONFIG_QUOTA is not set
 CONFIG_DNOTIFY=y
 CONFIG_AUTOFS_FS=m
@@ -1157,7 +1168,6 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
 CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
 CONFIG_DEVPTS_FS_XATTR=y
 # CONFIG_DEVPTS_FS_SECURITY is not set
 CONFIG_TMPFS=y
@@ -1189,15 +1199,20 @@ CONFIG_CRAMFS=y
 #
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
 CONFIG_NFS_V4=y
 # CONFIG_NFS_DIRECTIO is not set
 CONFIG_NFSD=y
+CONFIG_NFSD_V2_ACL=y
 CONFIG_NFSD_V3=y
+CONFIG_NFSD_V3_ACL=y
 CONFIG_NFSD_V4=y
 CONFIG_NFSD_TCP=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_EXPORTFS=y
+CONFIG_NFS_ACL_SUPPORT=y
+CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
diff --git a/arch/ppc64/configs/iSeries_defconfig b/arch/ppc64/configs/iSeries_defconfig
--- a/arch/ppc64/configs/iSeries_defconfig
+++ b/arch/ppc64/configs/iSeries_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc6
-# Tue Jun 14 17:01:28 2005
+# Linux kernel version: 2.6.13-rc6
+# Mon Aug  8 14:17:02 2005
 #
 CONFIG_64BIT=y
 CONFIG_MMU=y
@@ -80,8 +80,24 @@ CONFIG_IBMVIO=y
 CONFIG_IOMMU_VMERGE=y
 CONFIG_SMP=y
 CONFIG_NR_CPUS=32
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_NUMA is not set
 # CONFIG_SCHED_SMT is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+# CONFIG_PREEMPT_BKL is not set
+CONFIG_HZ_100=y
+# CONFIG_HZ_250 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=100
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_MSCHUNKS=y
 CONFIG_LPARCFG=y
@@ -110,6 +126,142 @@ CONFIG_PCI_NAMES=y
 # CONFIG_HOTPLUG_PCI is not set
 
 #
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=m
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_PNP is not set
+CONFIG_NET_IPIP=y
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_TUNNEL=y
+CONFIG_IP_TCPDIAG=m
+# CONFIG_IP_TCPDIAG_IPV6 is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS is not set
+# CONFIG_IPV6 is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_IP_NF_CONNTRACK=m
+CONFIG_IP_NF_CT_ACCT=y
+CONFIG_IP_NF_CONNTRACK_MARK=y
+CONFIG_IP_NF_CT_PROTO_SCTP=m
+CONFIG_IP_NF_FTP=m
+CONFIG_IP_NF_IRC=m
+CONFIG_IP_NF_TFTP=m
+CONFIG_IP_NF_AMANDA=m
+CONFIG_IP_NF_QUEUE=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_LIMIT=m
+CONFIG_IP_NF_MATCH_IPRANGE=m
+CONFIG_IP_NF_MATCH_MAC=m
+CONFIG_IP_NF_MATCH_PKTTYPE=m
+CONFIG_IP_NF_MATCH_MARK=m
+CONFIG_IP_NF_MATCH_MULTIPORT=m
+CONFIG_IP_NF_MATCH_TOS=m
+CONFIG_IP_NF_MATCH_RECENT=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_DSCP=m
+CONFIG_IP_NF_MATCH_AH_ESP=m
+CONFIG_IP_NF_MATCH_LENGTH=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_MATCH_TCPMSS=m
+CONFIG_IP_NF_MATCH_HELPER=m
+CONFIG_IP_NF_MATCH_STATE=m
+CONFIG_IP_NF_MATCH_CONNTRACK=m
+CONFIG_IP_NF_MATCH_OWNER=m
+CONFIG_IP_NF_MATCH_ADDRTYPE=m
+CONFIG_IP_NF_MATCH_REALM=m
+CONFIG_IP_NF_MATCH_SCTP=m
+CONFIG_IP_NF_MATCH_COMMENT=m
+CONFIG_IP_NF_MATCH_CONNMARK=m
+CONFIG_IP_NF_MATCH_HASHLIMIT=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_LOG=m
+CONFIG_IP_NF_TARGET_ULOG=m
+CONFIG_IP_NF_TARGET_TCPMSS=m
+CONFIG_IP_NF_NAT=m
+CONFIG_IP_NF_NAT_NEEDED=y
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_TARGET_REDIRECT=m
+CONFIG_IP_NF_TARGET_NETMAP=m
+CONFIG_IP_NF_TARGET_SAME=m
+CONFIG_IP_NF_NAT_SNMP_BASIC=m
+CONFIG_IP_NF_NAT_IRC=m
+CONFIG_IP_NF_NAT_FTP=m
+CONFIG_IP_NF_NAT_TFTP=m
+CONFIG_IP_NF_NAT_AMANDA=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_TOS=m
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_DSCP=m
+CONFIG_IP_NF_TARGET_MARK=m
+CONFIG_IP_NF_TARGET_CLASSIFY=m
+CONFIG_IP_NF_TARGET_CONNMARK=m
+CONFIG_IP_NF_TARGET_CLUSTERIP=m
+CONFIG_IP_NF_RAW=m
+CONFIG_IP_NF_TARGET_NOTRACK=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+CONFIG_LLC=y
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+CONFIG_NET_CLS_ROUTE=y
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+
+#
 # Device Drivers
 #
 
@@ -184,6 +336,7 @@ CONFIG_CHR_DEV_ST=y
 CONFIG_BLK_DEV_SR=y
 CONFIG_BLK_DEV_SR_VENDOR=y
 CONFIG_CHR_DEV_SG=y
+# CONFIG_CHR_DEV_SCH is not set
 
 #
 # Some SCSI devices (e.g. CD jukebox) support multiple LUNs
@@ -231,6 +384,7 @@ CONFIG_SCSI_QLA2XXX=y
 # CONFIG_SCSI_QLA2300 is not set
 # CONFIG_SCSI_QLA2322 is not set
 # CONFIG_SCSI_QLA6312 is not set
+# CONFIG_SCSI_QLA24XX is not set
 # CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
@@ -260,6 +414,8 @@ CONFIG_DM_ZERO=m
 # Fusion MPT device support
 #
 # CONFIG_FUSION is not set
+# CONFIG_FUSION_SPI is not set
+# CONFIG_FUSION_FC is not set
 
 #
 # IEEE 1394 (FireWire) support
@@ -276,145 +432,8 @@ CONFIG_DM_ZERO=m
 #
 
 #
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-CONFIG_UNIX=y
-CONFIG_NET_KEY=m
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-# CONFIG_IP_PNP is not set
-CONFIG_NET_IPIP=y
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
-# CONFIG_ARPD is not set
-CONFIG_SYN_COOKIES=y
-CONFIG_INET_AH=m
-CONFIG_INET_ESP=m
-CONFIG_INET_IPCOMP=m
-CONFIG_INET_TUNNEL=y
-CONFIG_IP_TCPDIAG=m
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-
-#
-# IP: Virtual Server Configuration
-#
-# CONFIG_IP_VS is not set
-# CONFIG_IPV6 is not set
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-
+# Network device support
 #
-# IP: Netfilter Configuration
-#
-CONFIG_IP_NF_CONNTRACK=m
-CONFIG_IP_NF_CT_ACCT=y
-CONFIG_IP_NF_CONNTRACK_MARK=y
-CONFIG_IP_NF_CT_PROTO_SCTP=m
-CONFIG_IP_NF_FTP=m
-CONFIG_IP_NF_IRC=m
-CONFIG_IP_NF_TFTP=m
-CONFIG_IP_NF_AMANDA=m
-CONFIG_IP_NF_QUEUE=m
-CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_MATCH_LIMIT=m
-CONFIG_IP_NF_MATCH_IPRANGE=m
-CONFIG_IP_NF_MATCH_MAC=m
-CONFIG_IP_NF_MATCH_PKTTYPE=m
-CONFIG_IP_NF_MATCH_MARK=m
-CONFIG_IP_NF_MATCH_MULTIPORT=m
-CONFIG_IP_NF_MATCH_TOS=m
-CONFIG_IP_NF_MATCH_RECENT=m
-CONFIG_IP_NF_MATCH_ECN=m
-CONFIG_IP_NF_MATCH_DSCP=m
-CONFIG_IP_NF_MATCH_AH_ESP=m
-CONFIG_IP_NF_MATCH_LENGTH=m
-CONFIG_IP_NF_MATCH_TTL=m
-CONFIG_IP_NF_MATCH_TCPMSS=m
-CONFIG_IP_NF_MATCH_HELPER=m
-CONFIG_IP_NF_MATCH_STATE=m
-CONFIG_IP_NF_MATCH_CONNTRACK=m
-CONFIG_IP_NF_MATCH_OWNER=m
-CONFIG_IP_NF_MATCH_ADDRTYPE=m
-CONFIG_IP_NF_MATCH_REALM=m
-CONFIG_IP_NF_MATCH_SCTP=m
-CONFIG_IP_NF_MATCH_COMMENT=m
-CONFIG_IP_NF_MATCH_CONNMARK=m
-CONFIG_IP_NF_MATCH_HASHLIMIT=m
-CONFIG_IP_NF_FILTER=m
-CONFIG_IP_NF_TARGET_REJECT=m
-CONFIG_IP_NF_TARGET_LOG=m
-CONFIG_IP_NF_TARGET_ULOG=m
-CONFIG_IP_NF_TARGET_TCPMSS=m
-CONFIG_IP_NF_NAT=m
-CONFIG_IP_NF_NAT_NEEDED=y
-CONFIG_IP_NF_TARGET_MASQUERADE=m
-CONFIG_IP_NF_TARGET_REDIRECT=m
-CONFIG_IP_NF_TARGET_NETMAP=m
-CONFIG_IP_NF_TARGET_SAME=m
-CONFIG_IP_NF_NAT_SNMP_BASIC=m
-CONFIG_IP_NF_NAT_IRC=m
-CONFIG_IP_NF_NAT_FTP=m
-CONFIG_IP_NF_NAT_TFTP=m
-CONFIG_IP_NF_NAT_AMANDA=m
-CONFIG_IP_NF_MANGLE=m
-CONFIG_IP_NF_TARGET_TOS=m
-CONFIG_IP_NF_TARGET_ECN=m
-CONFIG_IP_NF_TARGET_DSCP=m
-CONFIG_IP_NF_TARGET_MARK=m
-CONFIG_IP_NF_TARGET_CLASSIFY=m
-CONFIG_IP_NF_TARGET_CONNMARK=m
-CONFIG_IP_NF_TARGET_CLUSTERIP=m
-CONFIG_IP_NF_RAW=m
-CONFIG_IP_NF_TARGET_NOTRACK=m
-CONFIG_IP_NF_ARPTABLES=m
-CONFIG_IP_NF_ARPFILTER=m
-CONFIG_IP_NF_ARP_MANGLE=m
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-CONFIG_LLC=y
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-CONFIG_NET_CLS_ROUTE=y
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-CONFIG_NETPOLL=y
-CONFIG_NETPOLL_RX=y
-CONFIG_NETPOLL_TRAP=y
-CONFIG_NET_POLL_CONTROLLER=y
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
 CONFIG_NETDEVICES=y
 CONFIG_DUMMY=m
 CONFIG_BONDING=m
@@ -471,6 +490,7 @@ CONFIG_E1000=m
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
 # CONFIG_R8169 is not set
+# CONFIG_SKGE is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
@@ -514,6 +534,10 @@ CONFIG_PPPOE=m
 # CONFIG_NET_FC is not set
 # CONFIG_SHAPER is not set
 CONFIG_NETCONSOLE=y
+CONFIG_NETPOLL=y
+CONFIG_NETPOLL_RX=y
+CONFIG_NETPOLL_TRAP=y
+CONFIG_NET_POLL_CONTROLLER=y
 
 #
 # ISDN subsystem
@@ -587,7 +611,6 @@ CONFIG_LEGACY_PTY_COUNT=256
 #
 # CONFIG_WATCHDOG is not set
 # CONFIG_RTC is not set
-# CONFIG_GEN_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -610,6 +633,7 @@ CONFIG_MAX_RAW_DEVS=256
 # I2C support
 #
 # CONFIG_I2C is not set
+# CONFIG_I2C_SENSOR is not set
 
 #
 # Dallas's 1-wire bus
@@ -617,6 +641,11 @@ CONFIG_MAX_RAW_DEVS=256
 # CONFIG_W1 is not set
 
 #
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+
+#
 # Misc devices
 #
 
@@ -663,12 +692,18 @@ CONFIG_USB_ARCH_HAS_OHCI=y
 # CONFIG_INFINIBAND is not set
 
 #
+# SN Devices
+#
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
 CONFIG_EXT2_FS_XATTR=y
 CONFIG_EXT2_FS_POSIX_ACL=y
 CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT2_FS_XIP=y
+CONFIG_FS_XIP=y
 CONFIG_EXT3_FS=y
 CONFIG_EXT3_FS_XATTR=y
 CONFIG_EXT3_FS_POSIX_ACL=y
@@ -700,6 +735,7 @@ CONFIG_XFS_SECURITY=y
 CONFIG_XFS_POSIX_ACL=y
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
 # CONFIG_QUOTA is not set
 CONFIG_DNOTIFY=y
 CONFIG_AUTOFS_FS=m
@@ -731,7 +767,6 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
 CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
 CONFIG_DEVPTS_FS_XATTR=y
 CONFIG_DEVPTS_FS_SECURITY=y
 CONFIG_TMPFS=y
@@ -763,15 +798,20 @@ CONFIG_CRAMFS=y
 #
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
 CONFIG_NFS_V4=y
 # CONFIG_NFS_DIRECTIO is not set
 CONFIG_NFSD=m
+CONFIG_NFSD_V2_ACL=y
 CONFIG_NFSD_V3=y
+CONFIG_NFSD_V3_ACL=y
 CONFIG_NFSD_V4=y
 CONFIG_NFSD_TCP=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_EXPORTFS=m
+CONFIG_NFS_ACL_SUPPORT=y
+CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
diff --git a/arch/ppc64/configs/maple_defconfig b/arch/ppc64/configs/maple_defconfig
--- a/arch/ppc64/configs/maple_defconfig
+++ b/arch/ppc64/configs/maple_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc6
-# Tue Jun 14 17:12:48 2005
+# Linux kernel version: 2.6.13-rc6
+# Mon Aug  8 14:17:04 2005
 #
 CONFIG_64BIT=y
 CONFIG_MMU=y
@@ -73,12 +73,15 @@ CONFIG_SYSVIPC_COMPAT=y
 # CONFIG_PPC_ISERIES is not set
 CONFIG_PPC_MULTIPLATFORM=y
 # CONFIG_PPC_PSERIES is not set
+# CONFIG_PPC_BPA is not set
 # CONFIG_PPC_PMAC is not set
 CONFIG_PPC_MAPLE=y
 CONFIG_PPC=y
 CONFIG_PPC64=y
 CONFIG_PPC_OF=y
+CONFIG_MPIC=y
 # CONFIG_ALTIVEC is not set
+CONFIG_KEXEC=y
 CONFIG_U3_DART=y
 CONFIG_MPIC_BROKEN_U3=y
 CONFIG_BOOTX_TEXT=y
@@ -86,8 +89,24 @@ CONFIG_POWER4_ONLY=y
 CONFIG_IOMMU_VMERGE=y
 CONFIG_SMP=y
 CONFIG_NR_CPUS=2
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_NUMA is not set
 # CONFIG_SCHED_SMT is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+# CONFIG_PREEMPT_BKL is not set
+CONFIG_HZ_100=y
+# CONFIG_HZ_250 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=100
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_SECCOMP=y
 CONFIG_ISA_DMA_API=y
@@ -116,6 +135,69 @@ CONFIG_PROC_DEVICETREE=y
 # CONFIG_CMDLINE_BOOL is not set
 
 #
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_IP_TCPDIAG=y
+# CONFIG_IP_TCPDIAG_IPV6 is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+
+#
 # Device Drivers
 #
 
@@ -213,6 +295,7 @@ CONFIG_BLK_DEV_AMD74XX=y
 # CONFIG_BLK_DEV_HPT366 is not set
 # CONFIG_BLK_DEV_SC1200 is not set
 # CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_BLK_DEV_IT821X is not set
 # CONFIG_BLK_DEV_NS87415 is not set
 # CONFIG_BLK_DEV_PDC202XX_OLD is not set
 # CONFIG_BLK_DEV_PDC202XX_NEW is not set
@@ -240,6 +323,7 @@ CONFIG_IDEDMA_AUTO=y
 #
 # Fusion MPT device support
 #
+# CONFIG_FUSION is not set
 
 #
 # IEEE 1394 (FireWire) support
@@ -256,70 +340,8 @@ CONFIG_IDEDMA_AUTO=y
 #
 
 #
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
+# Network device support
 #
-CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
-CONFIG_UNIX=y
-# CONFIG_NET_KEY is not set
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-# CONFIG_IP_PNP_BOOTP is not set
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_TUNNEL is not set
-CONFIG_IP_TCPDIAG=y
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
 CONFIG_NETDEVICES=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
@@ -376,6 +398,7 @@ CONFIG_E1000=y
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
 # CONFIG_R8169 is not set
+# CONFIG_SKGE is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
@@ -408,6 +431,8 @@ CONFIG_E1000=y
 # CONFIG_SLIP is not set
 # CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
 
 #
 # ISDN subsystem
@@ -487,7 +512,6 @@ CONFIG_LEGACY_PTY_COUNT=256
 #
 # CONFIG_WATCHDOG is not set
 # CONFIG_RTC is not set
-# CONFIG_GEN_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -543,50 +567,19 @@ CONFIG_I2C_AMD8111=y
 # CONFIG_I2C_VIAPRO is not set
 # CONFIG_I2C_VOODOO3 is not set
 # CONFIG_I2C_PCA_ISA is not set
-
-#
-# Hardware Sensors Chip support
-#
 # CONFIG_I2C_SENSOR is not set
-# CONFIG_SENSORS_ADM1021 is not set
-# CONFIG_SENSORS_ADM1025 is not set
-# CONFIG_SENSORS_ADM1026 is not set
-# CONFIG_SENSORS_ADM1031 is not set
-# CONFIG_SENSORS_ASB100 is not set
-# CONFIG_SENSORS_DS1621 is not set
-# CONFIG_SENSORS_FSCHER is not set
-# CONFIG_SENSORS_FSCPOS is not set
-# CONFIG_SENSORS_GL518SM is not set
-# CONFIG_SENSORS_GL520SM is not set
-# CONFIG_SENSORS_IT87 is not set
-# CONFIG_SENSORS_LM63 is not set
-# CONFIG_SENSORS_LM75 is not set
-# CONFIG_SENSORS_LM77 is not set
-# CONFIG_SENSORS_LM78 is not set
-# CONFIG_SENSORS_LM80 is not set
-# CONFIG_SENSORS_LM83 is not set
-# CONFIG_SENSORS_LM85 is not set
-# CONFIG_SENSORS_LM87 is not set
-# CONFIG_SENSORS_LM90 is not set
-# CONFIG_SENSORS_LM92 is not set
-# CONFIG_SENSORS_MAX1619 is not set
-# CONFIG_SENSORS_PC87360 is not set
-# CONFIG_SENSORS_SMSC47B397 is not set
-# CONFIG_SENSORS_SIS5595 is not set
-# CONFIG_SENSORS_SMSC47M1 is not set
-# CONFIG_SENSORS_VIA686A is not set
-# CONFIG_SENSORS_W83781D is not set
-# CONFIG_SENSORS_W83L785TS is not set
-# CONFIG_SENSORS_W83627HF is not set
 
 #
-# Other I2C Chip support
+# Miscellaneous I2C Chip support
 #
 # CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
 # CONFIG_SENSORS_EEPROM is not set
 # CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_SENSORS_PCA9539 is not set
 # CONFIG_SENSORS_PCF8591 is not set
 # CONFIG_SENSORS_RTC8564 is not set
+# CONFIG_SENSORS_MAX6875 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
@@ -598,6 +591,11 @@ CONFIG_I2C_AMD8111=y
 # CONFIG_W1 is not set
 
 #
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+
+#
 # Misc devices
 #
 
@@ -649,6 +647,7 @@ CONFIG_USB_DEVICEFS=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_EHCI_SPLIT_ISO=y
 CONFIG_USB_EHCI_ROOT_HUB_TT=y
+# CONFIG_USB_ISP116X_HCD is not set
 CONFIG_USB_OHCI_HCD=y
 # CONFIG_USB_OHCI_BIG_ENDIAN is not set
 CONFIG_USB_OHCI_LITTLE_ENDIAN=y
@@ -676,12 +675,15 @@ CONFIG_USB_HIDINPUT=y
 # CONFIG_USB_HIDDEV is not set
 # CONFIG_USB_AIPTEK is not set
 # CONFIG_USB_WACOM is not set
+# CONFIG_USB_ACECAD is not set
 # CONFIG_USB_KBTAB is not set
 # CONFIG_USB_POWERMATE is not set
 # CONFIG_USB_MTOUCH is not set
+# CONFIG_USB_ITMTOUCH is not set
 # CONFIG_USB_EGALAX is not set
 # CONFIG_USB_XPAD is not set
 # CONFIG_USB_ATI_REMOTE is not set
+# CONFIG_USB_KEYSPAN_REMOTE is not set
 
 #
 # USB Imaging devices
@@ -772,10 +774,11 @@ CONFIG_USB_EZUSB=y
 # CONFIG_USB_PHIDGETSERVO is not set
 # CONFIG_USB_IDMOUSE is not set
 # CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
 # CONFIG_USB_TEST is not set
 
 #
-# USB ATM/DSL drivers
+# USB DSL modem support
 #
 
 #
@@ -794,16 +797,23 @@ CONFIG_USB_EZUSB=y
 # CONFIG_INFINIBAND is not set
 
 #
+# SN Devices
+#
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
+CONFIG_EXT2_FS_XIP=y
+CONFIG_FS_XIP=y
 CONFIG_EXT3_FS=y
 # CONFIG_EXT3_FS_XATTR is not set
 CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
 
 #
 # XFS support
@@ -811,6 +821,7 @@ CONFIG_JBD=y
 # CONFIG_XFS_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
 # CONFIG_QUOTA is not set
 CONFIG_DNOTIFY=y
 # CONFIG_AUTOFS_FS is not set
@@ -838,7 +849,6 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
 CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
 CONFIG_DEVPTS_FS_XATTR=y
 # CONFIG_DEVPTS_FS_SECURITY is not set
 CONFIG_TMPFS=y
@@ -870,12 +880,15 @@ CONFIG_CRAMFS=y
 #
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
 CONFIG_NFS_V4=y
 # CONFIG_NFS_DIRECTIO is not set
 # CONFIG_NFSD is not set
 CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
+CONFIG_NFS_ACL_SUPPORT=y
+CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
diff --git a/arch/ppc64/configs/pSeries_defconfig b/arch/ppc64/configs/pSeries_defconfig
--- a/arch/ppc64/configs/pSeries_defconfig
+++ b/arch/ppc64/configs/pSeries_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc6
-# Tue Jun 14 17:13:47 2005
+# Linux kernel version: 2.6.13-rc6
+# Mon Aug  8 14:17:07 2005
 #
 CONFIG_64BIT=y
 CONFIG_MMU=y
@@ -74,13 +74,17 @@ CONFIG_SYSVIPC_COMPAT=y
 # CONFIG_PPC_ISERIES is not set
 CONFIG_PPC_MULTIPLATFORM=y
 CONFIG_PPC_PSERIES=y
+# CONFIG_PPC_BPA is not set
 # CONFIG_PPC_PMAC is not set
 # CONFIG_PPC_MAPLE is not set
 CONFIG_PPC=y
 CONFIG_PPC64=y
 CONFIG_PPC_OF=y
+CONFIG_XICS=y
+CONFIG_MPIC=y
 CONFIG_ALTIVEC=y
 CONFIG_PPC_SPLPAR=y
+CONFIG_KEXEC=y
 CONFIG_IBMVIO=y
 # CONFIG_U3_DART is not set
 # CONFIG_BOOTX_TEXT is not set
@@ -88,10 +92,30 @@ CONFIG_IBMVIO=y
 CONFIG_IOMMU_VMERGE=y
 CONFIG_SMP=y
 CONFIG_NR_CPUS=128
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
+CONFIG_ARCH_DISCONTIGMEM_DEFAULT=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_SELECT_MEMORY_MODEL=y
+# CONFIG_FLATMEM_MANUAL is not set
+CONFIG_DISCONTIGMEM_MANUAL=y
+# CONFIG_SPARSEMEM_MANUAL is not set
 CONFIG_DISCONTIGMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_NEED_MULTIPLE_NODES=y
+CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y
+CONFIG_NODES_SPAN_OTHER_NODES=y
 CONFIG_NUMA=y
 CONFIG_SCHED_SMT=y
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+# CONFIG_PREEMPT_BKL is not set
+CONFIG_HZ_100=y
+# CONFIG_HZ_250 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=100
 CONFIG_EEH=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_PPC_RTAS=y
@@ -132,6 +156,142 @@ CONFIG_PROC_DEVICETREE=y
 # CONFIG_CMDLINE_BOOL is not set
 
 #
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=m
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_PNP is not set
+CONFIG_NET_IPIP=y
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_TUNNEL=y
+CONFIG_IP_TCPDIAG=m
+# CONFIG_IP_TCPDIAG_IPV6 is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS is not set
+# CONFIG_IPV6 is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_IP_NF_CONNTRACK=m
+CONFIG_IP_NF_CT_ACCT=y
+CONFIG_IP_NF_CONNTRACK_MARK=y
+CONFIG_IP_NF_CT_PROTO_SCTP=m
+CONFIG_IP_NF_FTP=m
+CONFIG_IP_NF_IRC=m
+CONFIG_IP_NF_TFTP=m
+CONFIG_IP_NF_AMANDA=m
+CONFIG_IP_NF_QUEUE=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_LIMIT=m
+CONFIG_IP_NF_MATCH_IPRANGE=m
+CONFIG_IP_NF_MATCH_MAC=m
+CONFIG_IP_NF_MATCH_PKTTYPE=m
+CONFIG_IP_NF_MATCH_MARK=m
+CONFIG_IP_NF_MATCH_MULTIPORT=m
+CONFIG_IP_NF_MATCH_TOS=m
+CONFIG_IP_NF_MATCH_RECENT=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_DSCP=m
+CONFIG_IP_NF_MATCH_AH_ESP=m
+CONFIG_IP_NF_MATCH_LENGTH=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_MATCH_TCPMSS=m
+CONFIG_IP_NF_MATCH_HELPER=m
+CONFIG_IP_NF_MATCH_STATE=m
+CONFIG_IP_NF_MATCH_CONNTRACK=m
+CONFIG_IP_NF_MATCH_OWNER=m
+CONFIG_IP_NF_MATCH_ADDRTYPE=m
+CONFIG_IP_NF_MATCH_REALM=m
+CONFIG_IP_NF_MATCH_SCTP=m
+CONFIG_IP_NF_MATCH_COMMENT=m
+CONFIG_IP_NF_MATCH_CONNMARK=m
+CONFIG_IP_NF_MATCH_HASHLIMIT=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_LOG=m
+CONFIG_IP_NF_TARGET_ULOG=m
+CONFIG_IP_NF_TARGET_TCPMSS=m
+CONFIG_IP_NF_NAT=m
+CONFIG_IP_NF_NAT_NEEDED=y
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_TARGET_REDIRECT=m
+CONFIG_IP_NF_TARGET_NETMAP=m
+CONFIG_IP_NF_TARGET_SAME=m
+CONFIG_IP_NF_NAT_SNMP_BASIC=m
+CONFIG_IP_NF_NAT_IRC=m
+CONFIG_IP_NF_NAT_FTP=m
+CONFIG_IP_NF_NAT_TFTP=m
+CONFIG_IP_NF_NAT_AMANDA=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_TOS=m
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_DSCP=m
+CONFIG_IP_NF_TARGET_MARK=m
+CONFIG_IP_NF_TARGET_CLASSIFY=m
+CONFIG_IP_NF_TARGET_CONNMARK=m
+CONFIG_IP_NF_TARGET_CLUSTERIP=m
+CONFIG_IP_NF_RAW=m
+CONFIG_IP_NF_TARGET_NOTRACK=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+CONFIG_LLC=y
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+CONFIG_NET_CLS_ROUTE=y
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+
+#
 # Device Drivers
 #
 
@@ -238,6 +398,7 @@ CONFIG_BLK_DEV_AMD74XX=y
 # CONFIG_BLK_DEV_HPT366 is not set
 # CONFIG_BLK_DEV_SC1200 is not set
 # CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_BLK_DEV_IT821X is not set
 # CONFIG_BLK_DEV_NS87415 is not set
 # CONFIG_BLK_DEV_PDC202XX_OLD is not set
 # CONFIG_BLK_DEV_PDC202XX_NEW is not set
@@ -267,6 +428,7 @@ CONFIG_CHR_DEV_ST=y
 CONFIG_BLK_DEV_SR=y
 CONFIG_BLK_DEV_SR_VENDOR=y
 CONFIG_CHR_DEV_SG=y
+# CONFIG_CHR_DEV_SCH is not set
 
 #
 # Some SCSI devices (e.g. CD jukebox) support multiple LUNs
@@ -322,6 +484,7 @@ CONFIG_SCSI_QLA22XX=m
 CONFIG_SCSI_QLA2300=m
 CONFIG_SCSI_QLA2322=m
 CONFIG_SCSI_QLA6312=m
+CONFIG_SCSI_QLA24XX=m
 CONFIG_SCSI_LPFC=m
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
@@ -352,6 +515,8 @@ CONFIG_DM_MULTIPATH_EMC=m
 # Fusion MPT device support
 #
 # CONFIG_FUSION is not set
+# CONFIG_FUSION_SPI is not set
+# CONFIG_FUSION_FC is not set
 
 #
 # IEEE 1394 (FireWire) support
@@ -368,145 +533,8 @@ CONFIG_DM_MULTIPATH_EMC=m
 #
 
 #
-# Networking support
+# Network device support
 #
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-CONFIG_UNIX=y
-CONFIG_NET_KEY=m
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-# CONFIG_IP_PNP is not set
-CONFIG_NET_IPIP=y
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
-# CONFIG_ARPD is not set
-CONFIG_SYN_COOKIES=y
-CONFIG_INET_AH=m
-CONFIG_INET_ESP=m
-CONFIG_INET_IPCOMP=m
-CONFIG_INET_TUNNEL=y
-CONFIG_IP_TCPDIAG=m
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-
-#
-# IP: Virtual Server Configuration
-#
-# CONFIG_IP_VS is not set
-# CONFIG_IPV6 is not set
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-
-#
-# IP: Netfilter Configuration
-#
-CONFIG_IP_NF_CONNTRACK=m
-CONFIG_IP_NF_CT_ACCT=y
-CONFIG_IP_NF_CONNTRACK_MARK=y
-CONFIG_IP_NF_CT_PROTO_SCTP=m
-CONFIG_IP_NF_FTP=m
-CONFIG_IP_NF_IRC=m
-CONFIG_IP_NF_TFTP=m
-CONFIG_IP_NF_AMANDA=m
-CONFIG_IP_NF_QUEUE=m
-CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_MATCH_LIMIT=m
-CONFIG_IP_NF_MATCH_IPRANGE=m
-CONFIG_IP_NF_MATCH_MAC=m
-CONFIG_IP_NF_MATCH_PKTTYPE=m
-CONFIG_IP_NF_MATCH_MARK=m
-CONFIG_IP_NF_MATCH_MULTIPORT=m
-CONFIG_IP_NF_MATCH_TOS=m
-CONFIG_IP_NF_MATCH_RECENT=m
-CONFIG_IP_NF_MATCH_ECN=m
-CONFIG_IP_NF_MATCH_DSCP=m
-CONFIG_IP_NF_MATCH_AH_ESP=m
-CONFIG_IP_NF_MATCH_LENGTH=m
-CONFIG_IP_NF_MATCH_TTL=m
-CONFIG_IP_NF_MATCH_TCPMSS=m
-CONFIG_IP_NF_MATCH_HELPER=m
-CONFIG_IP_NF_MATCH_STATE=m
-CONFIG_IP_NF_MATCH_CONNTRACK=m
-CONFIG_IP_NF_MATCH_OWNER=m
-CONFIG_IP_NF_MATCH_ADDRTYPE=m
-CONFIG_IP_NF_MATCH_REALM=m
-CONFIG_IP_NF_MATCH_SCTP=m
-CONFIG_IP_NF_MATCH_COMMENT=m
-CONFIG_IP_NF_MATCH_CONNMARK=m
-CONFIG_IP_NF_MATCH_HASHLIMIT=m
-CONFIG_IP_NF_FILTER=m
-CONFIG_IP_NF_TARGET_REJECT=m
-CONFIG_IP_NF_TARGET_LOG=m
-CONFIG_IP_NF_TARGET_ULOG=m
-CONFIG_IP_NF_TARGET_TCPMSS=m
-CONFIG_IP_NF_NAT=m
-CONFIG_IP_NF_NAT_NEEDED=y
-CONFIG_IP_NF_TARGET_MASQUERADE=m
-CONFIG_IP_NF_TARGET_REDIRECT=m
-CONFIG_IP_NF_TARGET_NETMAP=m
-CONFIG_IP_NF_TARGET_SAME=m
-CONFIG_IP_NF_NAT_SNMP_BASIC=m
-CONFIG_IP_NF_NAT_IRC=m
-CONFIG_IP_NF_NAT_FTP=m
-CONFIG_IP_NF_NAT_TFTP=m
-CONFIG_IP_NF_NAT_AMANDA=m
-CONFIG_IP_NF_MANGLE=m
-CONFIG_IP_NF_TARGET_TOS=m
-CONFIG_IP_NF_TARGET_ECN=m
-CONFIG_IP_NF_TARGET_DSCP=m
-CONFIG_IP_NF_TARGET_MARK=m
-CONFIG_IP_NF_TARGET_CLASSIFY=m
-CONFIG_IP_NF_TARGET_CONNMARK=m
-CONFIG_IP_NF_TARGET_CLUSTERIP=m
-CONFIG_IP_NF_RAW=m
-CONFIG_IP_NF_TARGET_NOTRACK=m
-CONFIG_IP_NF_ARPTABLES=m
-CONFIG_IP_NF_ARPFILTER=m
-CONFIG_IP_NF_ARP_MANGLE=m
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-CONFIG_LLC=y
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-CONFIG_NET_CLS_ROUTE=y
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-CONFIG_NETPOLL=y
-CONFIG_NETPOLL_RX=y
-CONFIG_NETPOLL_TRAP=y
-CONFIG_NET_POLL_CONTROLLER=y
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
 CONFIG_NETDEVICES=y
 CONFIG_DUMMY=m
 CONFIG_BONDING=m
@@ -566,6 +594,7 @@ CONFIG_E1000=y
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
 # CONFIG_R8169 is not set
+# CONFIG_SKGE is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_VIA_VELOCITY is not set
 CONFIG_TIGON3=y
@@ -613,6 +642,10 @@ CONFIG_PPPOE=m
 # CONFIG_NET_FC is not set
 # CONFIG_SHAPER is not set
 CONFIG_NETCONSOLE=y
+CONFIG_NETPOLL=y
+CONFIG_NETPOLL_RX=y
+CONFIG_NETPOLL_TRAP=y
+CONFIG_NET_POLL_CONTROLLER=y
 
 #
 # ISDN subsystem
@@ -714,7 +747,6 @@ CONFIG_HVCS=m
 #
 # CONFIG_WATCHDOG is not set
 # CONFIG_RTC is not set
-# CONFIG_GEN_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -772,50 +804,19 @@ CONFIG_I2C_ALGOBIT=y
 # CONFIG_I2C_VIAPRO is not set
 # CONFIG_I2C_VOODOO3 is not set
 # CONFIG_I2C_PCA_ISA is not set
-
-#
-# Hardware Sensors Chip support
-#
 # CONFIG_I2C_SENSOR is not set
-# CONFIG_SENSORS_ADM1021 is not set
-# CONFIG_SENSORS_ADM1025 is not set
-# CONFIG_SENSORS_ADM1026 is not set
-# CONFIG_SENSORS_ADM1031 is not set
-# CONFIG_SENSORS_ASB100 is not set
-# CONFIG_SENSORS_DS1621 is not set
-# CONFIG_SENSORS_FSCHER is not set
-# CONFIG_SENSORS_FSCPOS is not set
-# CONFIG_SENSORS_GL518SM is not set
-# CONFIG_SENSORS_GL520SM is not set
-# CONFIG_SENSORS_IT87 is not set
-# CONFIG_SENSORS_LM63 is not set
-# CONFIG_SENSORS_LM75 is not set
-# CONFIG_SENSORS_LM77 is not set
-# CONFIG_SENSORS_LM78 is not set
-# CONFIG_SENSORS_LM80 is not set
-# CONFIG_SENSORS_LM83 is not set
-# CONFIG_SENSORS_LM85 is not set
-# CONFIG_SENSORS_LM87 is not set
-# CONFIG_SENSORS_LM90 is not set
-# CONFIG_SENSORS_LM92 is not set
-# CONFIG_SENSORS_MAX1619 is not set
-# CONFIG_SENSORS_PC87360 is not set
-# CONFIG_SENSORS_SMSC47B397 is not set
-# CONFIG_SENSORS_SIS5595 is not set
-# CONFIG_SENSORS_SMSC47M1 is not set
-# CONFIG_SENSORS_VIA686A is not set
-# CONFIG_SENSORS_W83781D is not set
-# CONFIG_SENSORS_W83L785TS is not set
-# CONFIG_SENSORS_W83627HF is not set
 
 #
-# Other I2C Chip support
+# Miscellaneous I2C Chip support
 #
 # CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
 # CONFIG_SENSORS_EEPROM is not set
 # CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_SENSORS_PCA9539 is not set
 # CONFIG_SENSORS_PCF8591 is not set
 # CONFIG_SENSORS_RTC8564 is not set
+# CONFIG_SENSORS_MAX6875 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
@@ -827,6 +828,11 @@ CONFIG_I2C_ALGOBIT=y
 # CONFIG_W1 is not set
 
 #
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+
+#
 # Misc devices
 #
 
@@ -933,6 +939,7 @@ CONFIG_USB_DEVICEFS=y
 CONFIG_USB_EHCI_HCD=y
 # CONFIG_USB_EHCI_SPLIT_ISO is not set
 # CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+# CONFIG_USB_ISP116X_HCD is not set
 CONFIG_USB_OHCI_HCD=y
 # CONFIG_USB_OHCI_BIG_ENDIAN is not set
 CONFIG_USB_OHCI_LITTLE_ENDIAN=y
@@ -969,12 +976,15 @@ CONFIG_USB_HIDINPUT=y
 CONFIG_USB_HIDDEV=y
 # CONFIG_USB_AIPTEK is not set
 # CONFIG_USB_WACOM is not set
+# CONFIG_USB_ACECAD is not set
 # CONFIG_USB_KBTAB is not set
 # CONFIG_USB_POWERMATE is not set
 # CONFIG_USB_MTOUCH is not set
+# CONFIG_USB_ITMTOUCH is not set
 # CONFIG_USB_EGALAX is not set
 # CONFIG_USB_XPAD is not set
 # CONFIG_USB_ATI_REMOTE is not set
+# CONFIG_USB_KEYSPAN_REMOTE is not set
 
 #
 # USB Imaging devices
@@ -1026,10 +1036,11 @@ CONFIG_USB_MON=y
 # CONFIG_USB_PHIDGETSERVO is not set
 # CONFIG_USB_IDMOUSE is not set
 # CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
 # CONFIG_USB_TEST is not set
 
 #
-# USB ATM/DSL drivers
+# USB DSL modem support
 #
 
 #
@@ -1046,18 +1057,25 @@ CONFIG_USB_MON=y
 # InfiniBand support
 #
 CONFIG_INFINIBAND=m
+CONFIG_INFINIBAND_USER_VERBS=m
 CONFIG_INFINIBAND_MTHCA=m
 # CONFIG_INFINIBAND_MTHCA_DEBUG is not set
 CONFIG_INFINIBAND_IPOIB=m
 # CONFIG_INFINIBAND_IPOIB_DEBUG is not set
 
 #
+# SN Devices
+#
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
 CONFIG_EXT2_FS_XATTR=y
 CONFIG_EXT2_FS_POSIX_ACL=y
 CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT2_FS_XIP=y
+CONFIG_FS_XIP=y
 CONFIG_EXT3_FS=y
 CONFIG_EXT3_FS_XATTR=y
 CONFIG_EXT3_FS_POSIX_ACL=y
@@ -1089,6 +1107,7 @@ CONFIG_XFS_SECURITY=y
 CONFIG_XFS_POSIX_ACL=y
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
 # CONFIG_QUOTA is not set
 CONFIG_DNOTIFY=y
 CONFIG_AUTOFS_FS=m
@@ -1120,7 +1139,6 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
 CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
 CONFIG_DEVPTS_FS_XATTR=y
 CONFIG_DEVPTS_FS_SECURITY=y
 CONFIG_TMPFS=y
@@ -1152,15 +1170,20 @@ CONFIG_CRAMFS=y
 #
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
 CONFIG_NFS_V4=y
 # CONFIG_NFS_DIRECTIO is not set
 CONFIG_NFSD=y
+CONFIG_NFSD_V2_ACL=y
 CONFIG_NFSD_V3=y
+CONFIG_NFSD_V3_ACL=y
 CONFIG_NFSD_V4=y
 CONFIG_NFSD_TCP=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_EXPORTFS=y
+CONFIG_NFS_ACL_SUPPORT=y
+CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
diff --git a/arch/ppc64/defconfig b/arch/ppc64/defconfig
--- a/arch/ppc64/defconfig
+++ b/arch/ppc64/defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc5-git9
-# Sun Jun  5 09:26:47 2005
+# Linux kernel version: 2.6.13-rc6
+# Mon Aug  8 14:16:54 2005
 #
 CONFIG_64BIT=y
 CONFIG_MMU=y
@@ -73,13 +73,18 @@ CONFIG_SYSVIPC_COMPAT=y
 # CONFIG_PPC_ISERIES is not set
 CONFIG_PPC_MULTIPLATFORM=y
 CONFIG_PPC_PSERIES=y
+CONFIG_PPC_BPA=y
 CONFIG_PPC_PMAC=y
 CONFIG_PPC_MAPLE=y
 CONFIG_PPC=y
 CONFIG_PPC64=y
 CONFIG_PPC_OF=y
+CONFIG_XICS=y
+CONFIG_MPIC=y
+CONFIG_BPA_IIC=y
 CONFIG_ALTIVEC=y
 CONFIG_PPC_SPLPAR=y
+CONFIG_KEXEC=y
 CONFIG_IBMVIO=y
 CONFIG_U3_DART=y
 CONFIG_MPIC_BROKEN_U3=y
@@ -89,10 +94,30 @@ CONFIG_BOOTX_TEXT=y
 CONFIG_IOMMU_VMERGE=y
 CONFIG_SMP=y
 CONFIG_NR_CPUS=32
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
+CONFIG_ARCH_DISCONTIGMEM_DEFAULT=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_SELECT_MEMORY_MODEL=y
+# CONFIG_FLATMEM_MANUAL is not set
+CONFIG_DISCONTIGMEM_MANUAL=y
+# CONFIG_SPARSEMEM_MANUAL is not set
 CONFIG_DISCONTIGMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_NEED_MULTIPLE_NODES=y
+CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y
+CONFIG_NODES_SPAN_OTHER_NODES=y
 # CONFIG_NUMA is not set
 # CONFIG_SCHED_SMT is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
+# CONFIG_PREEMPT_BKL is not set
+CONFIG_HZ_100=y
+# CONFIG_HZ_250 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=100
 CONFIG_EEH=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_PPC_RTAS=y
@@ -133,6 +158,142 @@ CONFIG_PROC_DEVICETREE=y
 # CONFIG_CMDLINE_BOOL is not set
 
 #
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=m
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_PNP is not set
+CONFIG_NET_IPIP=y
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_TUNNEL=y
+# CONFIG_IP_TCPDIAG is not set
+# CONFIG_IP_TCPDIAG_IPV6 is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS is not set
+# CONFIG_IPV6 is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_IP_NF_CONNTRACK=m
+CONFIG_IP_NF_CT_ACCT=y
+CONFIG_IP_NF_CONNTRACK_MARK=y
+CONFIG_IP_NF_CT_PROTO_SCTP=m
+CONFIG_IP_NF_FTP=m
+CONFIG_IP_NF_IRC=m
+CONFIG_IP_NF_TFTP=m
+CONFIG_IP_NF_AMANDA=m
+CONFIG_IP_NF_QUEUE=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_LIMIT=m
+CONFIG_IP_NF_MATCH_IPRANGE=m
+CONFIG_IP_NF_MATCH_MAC=m
+CONFIG_IP_NF_MATCH_PKTTYPE=m
+CONFIG_IP_NF_MATCH_MARK=m
+CONFIG_IP_NF_MATCH_MULTIPORT=m
+CONFIG_IP_NF_MATCH_TOS=m
+CONFIG_IP_NF_MATCH_RECENT=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_DSCP=m
+CONFIG_IP_NF_MATCH_AH_ESP=m
+CONFIG_IP_NF_MATCH_LENGTH=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_MATCH_TCPMSS=m
+CONFIG_IP_NF_MATCH_HELPER=m
+CONFIG_IP_NF_MATCH_STATE=m
+CONFIG_IP_NF_MATCH_CONNTRACK=m
+CONFIG_IP_NF_MATCH_OWNER=m
+CONFIG_IP_NF_MATCH_ADDRTYPE=m
+CONFIG_IP_NF_MATCH_REALM=m
+CONFIG_IP_NF_MATCH_SCTP=m
+CONFIG_IP_NF_MATCH_COMMENT=m
+CONFIG_IP_NF_MATCH_CONNMARK=m
+CONFIG_IP_NF_MATCH_HASHLIMIT=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_LOG=m
+CONFIG_IP_NF_TARGET_ULOG=m
+CONFIG_IP_NF_TARGET_TCPMSS=m
+CONFIG_IP_NF_NAT=m
+CONFIG_IP_NF_NAT_NEEDED=y
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_TARGET_REDIRECT=m
+CONFIG_IP_NF_TARGET_NETMAP=m
+CONFIG_IP_NF_TARGET_SAME=m
+CONFIG_IP_NF_NAT_SNMP_BASIC=m
+CONFIG_IP_NF_NAT_IRC=m
+CONFIG_IP_NF_NAT_FTP=m
+CONFIG_IP_NF_NAT_TFTP=m
+CONFIG_IP_NF_NAT_AMANDA=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_TOS=m
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_DSCP=m
+CONFIG_IP_NF_TARGET_MARK=m
+CONFIG_IP_NF_TARGET_CLASSIFY=m
+CONFIG_IP_NF_TARGET_CONNMARK=m
+CONFIG_IP_NF_TARGET_CLUSTERIP=m
+CONFIG_IP_NF_RAW=m
+CONFIG_IP_NF_TARGET_NOTRACK=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+CONFIG_LLC=y
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+CONFIG_NET_CLS_ROUTE=y
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+
+#
 # Device Drivers
 #
 
@@ -239,6 +400,7 @@ CONFIG_BLK_DEV_AMD74XX=y
 # CONFIG_BLK_DEV_HPT366 is not set
 # CONFIG_BLK_DEV_SC1200 is not set
 # CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_BLK_DEV_IT821X is not set
 # CONFIG_BLK_DEV_NS87415 is not set
 # CONFIG_BLK_DEV_PDC202XX_OLD is not set
 # CONFIG_BLK_DEV_PDC202XX_NEW is not set
@@ -272,6 +434,7 @@ CONFIG_CHR_DEV_ST=y
 CONFIG_BLK_DEV_SR=y
 CONFIG_BLK_DEV_SR_VENDOR=y
 CONFIG_CHR_DEV_SG=y
+# CONFIG_CHR_DEV_SCH is not set
 
 #
 # Some SCSI devices (e.g. CD jukebox) support multiple LUNs
@@ -339,6 +502,7 @@ CONFIG_SCSI_QLA22XX=m
 CONFIG_SCSI_QLA2300=m
 CONFIG_SCSI_QLA2322=m
 CONFIG_SCSI_QLA6312=m
+CONFIG_SCSI_QLA24XX=m
 CONFIG_SCSI_LPFC=m
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
@@ -369,6 +533,8 @@ CONFIG_DM_MULTIPATH_EMC=m
 # Fusion MPT device support
 #
 # CONFIG_FUSION is not set
+# CONFIG_FUSION_SPI is not set
+# CONFIG_FUSION_FC is not set
 
 #
 # IEEE 1394 (FireWire) support
@@ -382,6 +548,7 @@ CONFIG_IEEE1394=y
 # CONFIG_IEEE1394_OUI_DB is not set
 CONFIG_IEEE1394_EXTRA_CONFIG_ROMS=y
 CONFIG_IEEE1394_CONFIG_ROM_IP1394=y
+# CONFIG_IEEE1394_EXPORT_FULL_API is not set
 
 #
 # Device Drivers
@@ -409,154 +576,14 @@ CONFIG_IEEE1394_AMDTP=m
 #
 # Macintosh device drivers
 #
-CONFIG_ADB=y
 CONFIG_ADB_PMU=y
 CONFIG_PMAC_SMU=y
-# CONFIG_PMAC_PBOOK is not set
 # CONFIG_PMAC_BACKLIGHT is not set
-# CONFIG_INPUT_ADBHID is not set
 CONFIG_THERM_PM72=y
 
 #
-# Networking support
+# Network device support
 #
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-CONFIG_UNIX=y
-CONFIG_NET_KEY=m
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-# CONFIG_IP_PNP is not set
-CONFIG_NET_IPIP=y
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
-# CONFIG_ARPD is not set
-CONFIG_SYN_COOKIES=y
-CONFIG_INET_AH=m
-CONFIG_INET_ESP=m
-CONFIG_INET_IPCOMP=m
-CONFIG_INET_TUNNEL=y
-# CONFIG_IP_TCPDIAG is not set
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-
-#
-# IP: Virtual Server Configuration
-#
-# CONFIG_IP_VS is not set
-# CONFIG_IPV6 is not set
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-
-#
-# IP: Netfilter Configuration
-#
-CONFIG_IP_NF_CONNTRACK=m
-CONFIG_IP_NF_CT_ACCT=y
-CONFIG_IP_NF_CONNTRACK_MARK=y
-CONFIG_IP_NF_CT_PROTO_SCTP=m
-CONFIG_IP_NF_FTP=m
-CONFIG_IP_NF_IRC=m
-CONFIG_IP_NF_TFTP=m
-CONFIG_IP_NF_AMANDA=m
-CONFIG_IP_NF_QUEUE=m
-CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_MATCH_LIMIT=m
-CONFIG_IP_NF_MATCH_IPRANGE=m
-CONFIG_IP_NF_MATCH_MAC=m
-CONFIG_IP_NF_MATCH_PKTTYPE=m
-CONFIG_IP_NF_MATCH_MARK=m
-CONFIG_IP_NF_MATCH_MULTIPORT=m
-CONFIG_IP_NF_MATCH_TOS=m
-CONFIG_IP_NF_MATCH_RECENT=m
-CONFIG_IP_NF_MATCH_ECN=m
-CONFIG_IP_NF_MATCH_DSCP=m
-CONFIG_IP_NF_MATCH_AH_ESP=m
-CONFIG_IP_NF_MATCH_LENGTH=m
-CONFIG_IP_NF_MATCH_TTL=m
-CONFIG_IP_NF_MATCH_TCPMSS=m
-CONFIG_IP_NF_MATCH_HELPER=m
-CONFIG_IP_NF_MATCH_STATE=m
-CONFIG_IP_NF_MATCH_CONNTRACK=m
-CONFIG_IP_NF_MATCH_OWNER=m
-CONFIG_IP_NF_MATCH_ADDRTYPE=m
-CONFIG_IP_NF_MATCH_REALM=m
-CONFIG_IP_NF_MATCH_SCTP=m
-CONFIG_IP_NF_MATCH_COMMENT=m
-CONFIG_IP_NF_MATCH_CONNMARK=m
-CONFIG_IP_NF_MATCH_HASHLIMIT=m
-CONFIG_IP_NF_FILTER=m
-CONFIG_IP_NF_TARGET_REJECT=m
-CONFIG_IP_NF_TARGET_LOG=m
-CONFIG_IP_NF_TARGET_ULOG=m
-CONFIG_IP_NF_TARGET_TCPMSS=m
-CONFIG_IP_NF_NAT=m
-CONFIG_IP_NF_NAT_NEEDED=y
-CONFIG_IP_NF_TARGET_MASQUERADE=m
-CONFIG_IP_NF_TARGET_REDIRECT=m
-CONFIG_IP_NF_TARGET_NETMAP=m
-CONFIG_IP_NF_TARGET_SAME=m
-CONFIG_IP_NF_NAT_SNMP_BASIC=m
-CONFIG_IP_NF_NAT_IRC=m
-CONFIG_IP_NF_NAT_FTP=m
-CONFIG_IP_NF_NAT_TFTP=m
-CONFIG_IP_NF_NAT_AMANDA=m
-CONFIG_IP_NF_MANGLE=m
-CONFIG_IP_NF_TARGET_TOS=m
-CONFIG_IP_NF_TARGET_ECN=m
-CONFIG_IP_NF_TARGET_DSCP=m
-CONFIG_IP_NF_TARGET_MARK=m
-CONFIG_IP_NF_TARGET_CLASSIFY=m
-CONFIG_IP_NF_TARGET_CONNMARK=m
-CONFIG_IP_NF_TARGET_CLUSTERIP=m
-CONFIG_IP_NF_RAW=m
-CONFIG_IP_NF_TARGET_NOTRACK=m
-CONFIG_IP_NF_ARPTABLES=m
-CONFIG_IP_NF_ARPFILTER=m
-CONFIG_IP_NF_ARP_MANGLE=m
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-CONFIG_LLC=y
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-CONFIG_NET_CLS_ROUTE=y
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-CONFIG_NETPOLL=y
-CONFIG_NETPOLL_RX=y
-CONFIG_NETPOLL_TRAP=y
-CONFIG_NET_POLL_CONTROLLER=y
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
 CONFIG_NETDEVICES=y
 CONFIG_DUMMY=m
 CONFIG_BONDING=m
@@ -616,6 +643,7 @@ CONFIG_E1000=y
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
 # CONFIG_R8169 is not set
+# CONFIG_SKGE is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_VIA_VELOCITY is not set
 CONFIG_TIGON3=y
@@ -661,6 +689,10 @@ CONFIG_PPPOE=m
 # CONFIG_NET_FC is not set
 # CONFIG_SHAPER is not set
 CONFIG_NETCONSOLE=y
+CONFIG_NETPOLL=y
+CONFIG_NETPOLL_RX=y
+CONFIG_NETPOLL_TRAP=y
+CONFIG_NET_POLL_CONTROLLER=y
 
 #
 # ISDN subsystem
@@ -764,7 +796,6 @@ CONFIG_HVCS=m
 #
 # CONFIG_WATCHDOG is not set
 # CONFIG_RTC is not set
-# CONFIG_GEN_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -823,50 +854,19 @@ CONFIG_I2C_KEYWEST=y
 # CONFIG_I2C_VIAPRO is not set
 # CONFIG_I2C_VOODOO3 is not set
 # CONFIG_I2C_PCA_ISA is not set
-
-#
-# Hardware Sensors Chip support
-#
 # CONFIG_I2C_SENSOR is not set
-# CONFIG_SENSORS_ADM1021 is not set
-# CONFIG_SENSORS_ADM1025 is not set
-# CONFIG_SENSORS_ADM1026 is not set
-# CONFIG_SENSORS_ADM1031 is not set
-# CONFIG_SENSORS_ASB100 is not set
-# CONFIG_SENSORS_DS1621 is not set
-# CONFIG_SENSORS_FSCHER is not set
-# CONFIG_SENSORS_FSCPOS is not set
-# CONFIG_SENSORS_GL518SM is not set
-# CONFIG_SENSORS_GL520SM is not set
-# CONFIG_SENSORS_IT87 is not set
-# CONFIG_SENSORS_LM63 is not set
-# CONFIG_SENSORS_LM75 is not set
-# CONFIG_SENSORS_LM77 is not set
-# CONFIG_SENSORS_LM78 is not set
-# CONFIG_SENSORS_LM80 is not set
-# CONFIG_SENSORS_LM83 is not set
-# CONFIG_SENSORS_LM85 is not set
-# CONFIG_SENSORS_LM87 is not set
-# CONFIG_SENSORS_LM90 is not set
-# CONFIG_SENSORS_LM92 is not set
-# CONFIG_SENSORS_MAX1619 is not set
-# CONFIG_SENSORS_PC87360 is not set
-# CONFIG_SENSORS_SMSC47B397 is not set
-# CONFIG_SENSORS_SIS5595 is not set
-# CONFIG_SENSORS_SMSC47M1 is not set
-# CONFIG_SENSORS_VIA686A is not set
-# CONFIG_SENSORS_W83781D is not set
-# CONFIG_SENSORS_W83L785TS is not set
-# CONFIG_SENSORS_W83627HF is not set
 
 #
-# Other I2C Chip support
+# Miscellaneous I2C Chip support
 #
 # CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
 # CONFIG_SENSORS_EEPROM is not set
 # CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_SENSORS_PCA9539 is not set
 # CONFIG_SENSORS_PCF8591 is not set
 # CONFIG_SENSORS_RTC8564 is not set
+# CONFIG_SENSORS_MAX6875 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
@@ -878,6 +878,11 @@ CONFIG_I2C_KEYWEST=y
 # CONFIG_W1 is not set
 
 #
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+
+#
 # Misc devices
 #
 
@@ -988,6 +993,7 @@ CONFIG_USB_DEVICEFS=y
 CONFIG_USB_EHCI_HCD=y
 # CONFIG_USB_EHCI_SPLIT_ISO is not set
 # CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+# CONFIG_USB_ISP116X_HCD is not set
 CONFIG_USB_OHCI_HCD=y
 # CONFIG_USB_OHCI_BIG_ENDIAN is not set
 CONFIG_USB_OHCI_LITTLE_ENDIAN=y
@@ -1024,12 +1030,15 @@ CONFIG_USB_HIDINPUT=y
 CONFIG_USB_HIDDEV=y
 # CONFIG_USB_AIPTEK is not set
 # CONFIG_USB_WACOM is not set
+# CONFIG_USB_ACECAD is not set
 # CONFIG_USB_KBTAB is not set
 # CONFIG_USB_POWERMATE is not set
 # CONFIG_USB_MTOUCH is not set
+# CONFIG_USB_ITMTOUCH is not set
 # CONFIG_USB_EGALAX is not set
 # CONFIG_USB_XPAD is not set
 # CONFIG_USB_ATI_REMOTE is not set
+# CONFIG_USB_KEYSPAN_REMOTE is not set
 
 #
 # USB Imaging devices
@@ -1081,10 +1090,11 @@ CONFIG_USB_PEGASUS=y
 # CONFIG_USB_PHIDGETSERVO is not set
 # CONFIG_USB_IDMOUSE is not set
 # CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
 # CONFIG_USB_TEST is not set
 
 #
-# USB ATM/DSL drivers
+# USB DSL modem support
 #
 
 #
@@ -1101,18 +1111,25 @@ CONFIG_USB_PEGASUS=y
 # InfiniBand support
 #
 CONFIG_INFINIBAND=m
+CONFIG_INFINIBAND_USER_VERBS=m
 CONFIG_INFINIBAND_MTHCA=m
 # CONFIG_INFINIBAND_MTHCA_DEBUG is not set
 CONFIG_INFINIBAND_IPOIB=m
 # CONFIG_INFINIBAND_IPOIB_DEBUG is not set
 
 #
+# SN Devices
+#
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=y
 CONFIG_EXT2_FS_XATTR=y
 CONFIG_EXT2_FS_POSIX_ACL=y
 CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT2_FS_XIP=y
+CONFIG_FS_XIP=y
 CONFIG_EXT3_FS=y
 CONFIG_EXT3_FS_XATTR=y
 CONFIG_EXT3_FS_POSIX_ACL=y
@@ -1144,6 +1161,7 @@ CONFIG_XFS_SECURITY=y
 CONFIG_XFS_POSIX_ACL=y
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
 # CONFIG_QUOTA is not set
 CONFIG_DNOTIFY=y
 CONFIG_AUTOFS_FS=y
@@ -1174,7 +1192,6 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
 CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
 CONFIG_DEVPTS_FS_XATTR=y
 CONFIG_DEVPTS_FS_SECURITY=y
 CONFIG_TMPFS=y
@@ -1206,15 +1223,20 @@ CONFIG_CRAMFS=y
 #
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
 CONFIG_NFS_V4=y
 # CONFIG_NFS_DIRECTIO is not set
 CONFIG_NFSD=m
+CONFIG_NFSD_V2_ACL=y
 CONFIG_NFSD_V3=y
+CONFIG_NFSD_V3_ACL=y
 CONFIG_NFSD_V4=y
 CONFIG_NFSD_TCP=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_EXPORTFS=m
+CONFIG_NFS_ACL_SUPPORT=y
+CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 CONFIG_SUNRPC_GSS=y
 CONFIG_RPCSEC_GSS_KRB5=y
diff --git a/arch/ppc64/kernel/HvLpEvent.c b/arch/ppc64/kernel/HvLpEvent.c
--- a/arch/ppc64/kernel/HvLpEvent.c
+++ b/arch/ppc64/kernel/HvLpEvent.c
@@ -12,7 +12,7 @@
 #include <asm/system.h>
 #include <asm/iSeries/HvLpEvent.h>
 #include <asm/iSeries/HvCallEvent.h>
-#include <asm/iSeries/LparData.h>
+#include <asm/iSeries/ItLpNaca.h>
 
 /* Array of LpEvent handler functions */
 LpEventHandler lpEventHandler[HvLpEvent_Type_NumTypes];
diff --git a/arch/ppc64/kernel/ItLpQueue.c b/arch/ppc64/kernel/ItLpQueue.c
--- a/arch/ppc64/kernel/ItLpQueue.c
+++ b/arch/ppc64/kernel/ItLpQueue.c
@@ -1,7 +1,7 @@
 /*
  * ItLpQueue.c
  * Copyright (C) 2001 Mike Corrigan  IBM Corporation
- * 
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
@@ -11,157 +11,252 @@
 #include <linux/stddef.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
+#include <linux/bootmem.h>
+#include <linux/seq_file.h>
+#include <linux/proc_fs.h>
 #include <asm/system.h>
 #include <asm/paca.h>
 #include <asm/iSeries/ItLpQueue.h>
 #include <asm/iSeries/HvLpEvent.h>
 #include <asm/iSeries/HvCallEvent.h>
-#include <asm/iSeries/LparData.h>
 
-static __inline__ int set_inUse( struct ItLpQueue * lpQueue )
-{
-	int t;
-	u32 * inUseP = &(lpQueue->xInUseWord);
+/*
+ * The LpQueue is used to pass event data from the hypervisor to
+ * the partition.  This is where I/O interrupt events are communicated.
+ *
+ * It is written to by the hypervisor so cannot end up in the BSS.
+ */
+struct hvlpevent_queue hvlpevent_queue __attribute__((__section__(".data")));
 
-	__asm__ __volatile__("\n\
-1:	lwarx	%0,0,%2		\n\
-	cmpwi	0,%0,0		\n\
-	li	%0,0		\n\
-	bne-	2f		\n\
-	addi	%0,%0,1		\n\
-	stwcx.	%0,0,%2		\n\
-	bne-	1b		\n\
-2:	eieio"
-	: "=&r" (t), "=m" (lpQueue->xInUseWord)
-	: "r" (inUseP), "m" (lpQueue->xInUseWord)
-	: "cc");
+DEFINE_PER_CPU(unsigned long[HvLpEvent_Type_NumTypes], hvlpevent_counts);
 
-	return t;
-}
-
-static __inline__ void clear_inUse( struct ItLpQueue * lpQueue )
-{
-	lpQueue->xInUseWord = 0;
-}
+static char *event_types[HvLpEvent_Type_NumTypes] = {
+	"Hypervisor",
+	"Machine Facilities",
+	"Session Manager",
+	"SPD I/O",
+	"Virtual Bus",
+	"PCI I/O",
+	"RIO I/O",
+	"Virtual Lan",
+	"Virtual I/O"
+};
 
 /* Array of LpEvent handler functions */
 extern LpEventHandler lpEventHandler[HvLpEvent_Type_NumTypes];
-unsigned long ItLpQueueInProcess = 0;
 
-struct HvLpEvent * ItLpQueue_getNextLpEvent( struct ItLpQueue * lpQueue )
+static struct HvLpEvent * get_next_hvlpevent(void)
 {
-	struct HvLpEvent * nextLpEvent = 
-		(struct HvLpEvent *)lpQueue->xSlicCurEventPtr;
-	if ( nextLpEvent->xFlags.xValid ) {
+	struct HvLpEvent * event;
+	event = (struct HvLpEvent *)hvlpevent_queue.xSlicCurEventPtr;
+
+	if (event->xFlags.xValid) {
 		/* rmb() needed only for weakly consistent machines (regatta) */
 		rmb();
 		/* Set pointer to next potential event */
-		lpQueue->xSlicCurEventPtr += ((nextLpEvent->xSizeMinus1 +
-				      LpEventAlign ) /
-				      LpEventAlign ) *
-				      LpEventAlign;
+		hvlpevent_queue.xSlicCurEventPtr += ((event->xSizeMinus1 +
+				LpEventAlign) / LpEventAlign) * LpEventAlign;
+
 		/* Wrap to beginning if no room at end */
-		if (lpQueue->xSlicCurEventPtr > lpQueue->xSlicLastValidEventPtr)
-			lpQueue->xSlicCurEventPtr = lpQueue->xSlicEventStackPtr;
+		if (hvlpevent_queue.xSlicCurEventPtr >
+				hvlpevent_queue.xSlicLastValidEventPtr) {
+			hvlpevent_queue.xSlicCurEventPtr =
+				hvlpevent_queue.xSlicEventStackPtr;
+		}
+	} else {
+		event = NULL;
 	}
-	else 
-		nextLpEvent = NULL;
 
-	return nextLpEvent;
+	return event;
+}
+
+static unsigned long spread_lpevents = NR_CPUS;
+
+int hvlpevent_is_pending(void)
+{
+	struct HvLpEvent *next_event;
+
+	if (smp_processor_id() >= spread_lpevents)
+		return 0;
+
+	next_event = (struct HvLpEvent *)hvlpevent_queue.xSlicCurEventPtr;
+
+	return next_event->xFlags.xValid |
+		hvlpevent_queue.xPlicOverflowIntPending;
 }
 
-int ItLpQueue_isLpIntPending( struct ItLpQueue * lpQueue )
-{
-	int retval = 0;
-	struct HvLpEvent * nextLpEvent;
-	if ( lpQueue ) {
-		nextLpEvent = (struct HvLpEvent *)lpQueue->xSlicCurEventPtr;
-		retval = nextLpEvent->xFlags.xValid | lpQueue->xPlicOverflowIntPending;
-	}
-	return retval;
-}
-
-void ItLpQueue_clearValid( struct HvLpEvent * event )
-{
-	/* Clear the valid bit of the event
-	 * Also clear bits within this event that might
-	 * look like valid bits (on 64-byte boundaries)
-   	 */
-	unsigned extra = (( event->xSizeMinus1 + LpEventAlign ) /
-						 LpEventAlign ) - 1;
-	switch ( extra ) {
-	  case 3:
-	   ((struct HvLpEvent*)((char*)event+3*LpEventAlign))->xFlags.xValid=0;
-	  case 2:
-	   ((struct HvLpEvent*)((char*)event+2*LpEventAlign))->xFlags.xValid=0;
-	  case 1:
-	   ((struct HvLpEvent*)((char*)event+1*LpEventAlign))->xFlags.xValid=0;
-	  case 0:
-	   ;	
+static void hvlpevent_clear_valid(struct HvLpEvent * event)
+{
+	/* Tell the Hypervisor that we're done with this event.
+	 * Also clear bits within this event that might look like valid bits.
+	 * ie. on 64-byte boundaries.
+	 */
+	struct HvLpEvent *tmp;
+	unsigned extra = ((event->xSizeMinus1 + LpEventAlign) /
+						 LpEventAlign) - 1;
+
+	switch (extra) {
+	case 3:
+		tmp = (struct HvLpEvent*)((char*)event + 3 * LpEventAlign);
+		tmp->xFlags.xValid = 0;
+	case 2:
+		tmp = (struct HvLpEvent*)((char*)event + 2 * LpEventAlign);
+		tmp->xFlags.xValid = 0;
+	case 1:
+		tmp = (struct HvLpEvent*)((char*)event + 1 * LpEventAlign);
+		tmp->xFlags.xValid = 0;
 	}
+
 	mb();
+
 	event->xFlags.xValid = 0;
 }
 
-unsigned ItLpQueue_process( struct ItLpQueue * lpQueue, struct pt_regs *regs )
+void process_hvlpevents(struct pt_regs *regs)
 {
-	unsigned numIntsProcessed = 0;
-	struct HvLpEvent * nextLpEvent;
+	struct HvLpEvent * event;
 
 	/* If we have recursed, just return */
-	if ( !set_inUse( lpQueue ) )
-		return 0;
-	
-	if (ItLpQueueInProcess == 0)
-		ItLpQueueInProcess = 1;
-	else
-		BUG();
+	if (!spin_trylock(&hvlpevent_queue.lock))
+		return;
 
 	for (;;) {
-		nextLpEvent = ItLpQueue_getNextLpEvent( lpQueue );
-		if ( nextLpEvent ) {
-			/* Count events to return to caller
-			 * and count processed events in lpQueue
- 			 */
-			++numIntsProcessed;
-			lpQueue->xLpIntCount++;		
-			/* Call appropriate handler here, passing 
+		event = get_next_hvlpevent();
+		if (event) {
+			/* Call appropriate handler here, passing
 			 * a pointer to the LpEvent.  The handler
 			 * must make a copy of the LpEvent if it
 			 * needs it in a bottom half. (perhaps for
 			 * an ACK)
-			 *	
-			 *  Handlers are responsible for ACK processing 
+			 *
+			 *  Handlers are responsible for ACK processing
 			 *
 			 * The Hypervisor guarantees that LpEvents will
 			 * only be delivered with types that we have
 			 * registered for, so no type check is necessary
 			 * here!
-  			 */
-			if ( nextLpEvent->xType < HvLpEvent_Type_NumTypes )
-				lpQueue->xLpIntCountByType[nextLpEvent->xType]++;
-			if ( nextLpEvent->xType < HvLpEvent_Type_NumTypes &&
-			     lpEventHandler[nextLpEvent->xType] ) 
-				lpEventHandler[nextLpEvent->xType](nextLpEvent, regs);
+			 */
+			if (event->xType < HvLpEvent_Type_NumTypes)
+				__get_cpu_var(hvlpevent_counts)[event->xType]++;
+			if (event->xType < HvLpEvent_Type_NumTypes &&
+					lpEventHandler[event->xType])
+				lpEventHandler[event->xType](event, regs);
 			else
-				printk(KERN_INFO "Unexpected Lp Event type=%d\n", nextLpEvent->xType );
-			
-			ItLpQueue_clearValid( nextLpEvent );
-		} else if ( lpQueue->xPlicOverflowIntPending )
+				printk(KERN_INFO "Unexpected Lp Event type=%d\n", event->xType );
+
+			hvlpevent_clear_valid(event);
+		} else if (hvlpevent_queue.xPlicOverflowIntPending)
 			/*
 			 * No more valid events. If overflow events are
 			 * pending process them
 			 */
-			HvCallEvent_getOverflowLpEvents( lpQueue->xIndex);
+			HvCallEvent_getOverflowLpEvents(hvlpevent_queue.xIndex);
 		else
 			break;
 	}
 
-	ItLpQueueInProcess = 0;
-	mb();
-	clear_inUse( lpQueue );
+	spin_unlock(&hvlpevent_queue.lock);
+}
 
-	get_paca()->lpevent_count += numIntsProcessed;
+static int set_spread_lpevents(char *str)
+{
+	unsigned long val = simple_strtoul(str, NULL, 0);
 
-	return numIntsProcessed;
+	/*
+	 * The parameter is the number of processors to share in processing
+	 * lp events.
+	 */
+	if (( val > 0) && (val <= NR_CPUS)) {
+		spread_lpevents = val;
+		printk("lpevent processing spread over %ld processors\n", val);
+	} else {
+		printk("invalid spread_lpevents %ld\n", val);
+	}
+
+	return 1;
 }
+__setup("spread_lpevents=", set_spread_lpevents);
+
+void setup_hvlpevent_queue(void)
+{
+	void *eventStack;
+
+	/*
+	 * Allocate a page for the Event Stack. The Hypervisor needs the
+	 * absolute real address, so we subtract out the KERNELBASE and add
+	 * in the absolute real address of the kernel load area.
+	 */
+	eventStack = alloc_bootmem_pages(LpEventStackSize);
+	memset(eventStack, 0, LpEventStackSize);
+
+	/* Invoke the hypervisor to initialize the event stack */
+	HvCallEvent_setLpEventStack(0, eventStack, LpEventStackSize);
+
+	hvlpevent_queue.xSlicEventStackPtr = (char *)eventStack;
+	hvlpevent_queue.xSlicCurEventPtr = (char *)eventStack;
+	hvlpevent_queue.xSlicLastValidEventPtr = (char *)eventStack +
+					(LpEventStackSize - LpEventMaxSize);
+	hvlpevent_queue.xIndex = 0;
+}
+
+static int proc_lpevents_show(struct seq_file *m, void *v)
+{
+	int cpu, i;
+	unsigned long sum;
+	static unsigned long cpu_totals[NR_CPUS];
+
+	/* FIXME: do we care that there's no locking here? */
+	sum = 0;
+	for_each_online_cpu(cpu) {
+		cpu_totals[cpu] = 0;
+		for (i = 0; i < HvLpEvent_Type_NumTypes; i++) {
+			cpu_totals[cpu] += per_cpu(hvlpevent_counts, cpu)[i];
+		}
+		sum += cpu_totals[cpu];
+	}
+
+	seq_printf(m, "LpEventQueue 0\n");
+	seq_printf(m, "  events processed:\t%lu\n", sum);
+
+	for (i = 0; i < HvLpEvent_Type_NumTypes; ++i) {
+		sum = 0;
+		for_each_online_cpu(cpu) {
+			sum += per_cpu(hvlpevent_counts, cpu)[i];
+		}
+
+		seq_printf(m, "    %-20s %10lu\n", event_types[i], sum);
+	}
+
+	seq_printf(m, "\n  events processed by processor:\n");
+
+	for_each_online_cpu(cpu) {
+		seq_printf(m, "    CPU%02d  %10lu\n", cpu, cpu_totals[cpu]);
+	}
+
+	return 0;
+}
+
+static int proc_lpevents_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, proc_lpevents_show, NULL);
+}
+
+static struct file_operations proc_lpevents_operations = {
+	.open		= proc_lpevents_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static int __init proc_lpevents_init(void)
+{
+	struct proc_dir_entry *e;
+
+	e = create_proc_entry("iSeries/lpevents", S_IFREG|S_IRUGO, NULL);
+	if (e)
+		e->proc_fops = &proc_lpevents_operations;
+
+	return 0;
+}
+__initcall(proc_lpevents_init);
+
diff --git a/arch/ppc64/kernel/LparData.c b/arch/ppc64/kernel/LparData.c
--- a/arch/ppc64/kernel/LparData.c
+++ b/arch/ppc64/kernel/LparData.c
@@ -28,29 +28,21 @@
 #include <asm/iSeries/IoHriProcessorVpd.h>
 #include <asm/iSeries/ItSpCommArea.h>
 
-/* The LpQueue is used to pass event data from the hypervisor to
- * the partition.  This is where I/O interrupt events are communicated.
- */
-
-/* May be filled in by the hypervisor so cannot end up in the BSS */
-struct ItLpQueue xItLpQueue __attribute__((__section__(".data")));
-
 
 /* The HvReleaseData is the root of the information shared between 
  * the hypervisor and Linux.  
  */
-
 struct HvReleaseData hvReleaseData = {
 	.xDesc = 0xc8a5d9c4,	/* "HvRD" ebcdic */
 	.xSize = sizeof(struct HvReleaseData),
 	.xVpdAreasPtrOffset = offsetof(struct naca_struct, xItVpdAreas),
 	.xSlicNacaAddr = &naca,		/* 64-bit Naca address */
-	.xMsNucDataOffset = 0x4800,	/* offset of LparMap within loadarea (see head.S) */
-	.xTagsMode = 1,			/* tags inactive       */
-	.xAddressSize = 0,		/* 64 bit              */
-	.xNoSharedProcs = 0,		/* shared processors   */
-	.xNoHMT = 0,			/* HMT allowed         */
-	.xRsvd2 = 6,			/* TEMP: This allows non-GA driver */
+	.xMsNucDataOffset = LPARMAP_PHYS,
+	.xFlags = HVREL_TAGSINACTIVE	/* tags inactive       */
+					/* 64 bit              */
+					/* shared processors   */
+					/* HMT allowed         */
+		  | 6,			/* TEMP: This allows non-GA driver */
 	.xVrmIndex = 4,			/* We are v5r2m0               */
 	.xMinSupportedPlicVrmIndex = 3,		/* v5r1m0 */
 	.xMinCompatablePlicVrmIndex = 3,	/* v5r1m0 */
@@ -200,7 +192,7 @@ struct ItVpdAreas itVpdAreas = {
 		0,0,0,			/* 13 - 15 */
 		sizeof(struct IoHriProcessorVpd),/* 16 length of Proc Vpd */
 		0,0,0,0,0,0,		/* 17 - 22  */
-		sizeof(struct ItLpQueue),/*     23 length of Lp Queue */
+		sizeof(struct hvlpevent_queue),	/* 23 length of Lp Queue */
 		0,0			/* 24 - 25 */
 		},
 	.xSlicVpdAdrs = {			/* VPD addresses */
@@ -218,7 +210,7 @@ struct ItVpdAreas itVpdAreas = {
 		0,0,0,			/* 13 - 15 */
 		&xIoHriProcessorVpd,	/*      16 Proc Vpd */
 		0,0,0,0,0,0,		/* 17 - 22 */
-		&xItLpQueue,		/*      23 Lp Queue */
+		&hvlpevent_queue,	/*      23 Lp Queue */
 		0,0
 	}
 };
diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile
--- a/arch/ppc64/kernel/Makefile
+++ b/arch/ppc64/kernel/Makefile
@@ -16,29 +16,33 @@ obj-y += vdso32/ vdso64/
 
 obj-$(CONFIG_PPC_OF) +=	of_device.o
 
-pci-obj-$(CONFIG_PPC_ISERIES)	+= iSeries_pci.o iSeries_pci_reset.o
+pci-obj-$(CONFIG_PPC_ISERIES)	+= iSeries_pci.o iSeries_irq.o \
+				iSeries_VpdInfo.o
 pci-obj-$(CONFIG_PPC_MULTIPLATFORM)	+= pci_dn.o pci_direct_iommu.o
 
 obj-$(CONFIG_PCI)	+= pci.o pci_iommu.o iomap.o $(pci-obj-y)
 
-obj-$(CONFIG_PPC_ISERIES) += iSeries_irq.o \
-			     iSeries_VpdInfo.o XmPciLpEvent.o \
-			     HvCall.o HvLpConfig.o LparData.o \
+obj-$(CONFIG_PPC_ISERIES) += HvCall.o HvLpConfig.o LparData.o \
 			     iSeries_setup.o ItLpQueue.o hvCall.o \
 			     mf.o HvLpEvent.o iSeries_proc.o iSeries_htab.o \
 			     iSeries_iommu.o
 
-obj-$(CONFIG_PPC_MULTIPLATFORM) += nvram.o i8259.o prom_init.o prom.o mpic.o
+obj-$(CONFIG_PPC_MULTIPLATFORM) += nvram.o i8259.o prom_init.o prom.o
 
 obj-$(CONFIG_PPC_PSERIES) += pSeries_pci.o pSeries_lpar.o pSeries_hvCall.o \
 			     pSeries_nvram.o rtasd.o ras.o pSeries_reconfig.o \
-			     xics.o rtas.o pSeries_setup.o pSeries_iommu.o
+			     pSeries_setup.o pSeries_iommu.o
 
+obj-$(CONFIG_PPC_BPA) += bpa_setup.o bpa_iommu.o bpa_nvram.o \
+			 bpa_iic.o spider-pic.o
+
+obj-$(CONFIG_KEXEC)		+= machine_kexec.o
 obj-$(CONFIG_EEH)		+= eeh.o
 obj-$(CONFIG_PROC_FS)		+= proc_ppc64.o
 obj-$(CONFIG_RTAS_FLASH)	+= rtas_flash.o
 obj-$(CONFIG_SMP)		+= smp.o
 obj-$(CONFIG_MODULES)		+= module.o ppc_ksyms.o
+obj-$(CONFIG_PPC_RTAS)		+= rtas.o rtas_pci.o
 obj-$(CONFIG_RTAS_PROC)		+= rtas-proc.o
 obj-$(CONFIG_SCANLOG)		+= scanlog.o
 obj-$(CONFIG_VIOPATH)		+= viopath.o
@@ -47,6 +51,8 @@ obj-$(CONFIG_HVC_CONSOLE)	+= hvconsole.o
 obj-$(CONFIG_BOOTX_TEXT)	+= btext.o
 obj-$(CONFIG_HVCS)		+= hvcserver.o
 obj-$(CONFIG_IBMVIO)		+= vio.o
+obj-$(CONFIG_XICS)		+= xics.o
+obj-$(CONFIG_MPIC)		+= mpic.o
 
 obj-$(CONFIG_PPC_PMAC)		+= pmac_setup.o pmac_feature.o pmac_pci.o \
 				   pmac_time.o pmac_nvram.o pmac_low_i2c.o
@@ -59,6 +65,7 @@ ifdef CONFIG_SMP
 obj-$(CONFIG_PPC_PMAC)		+= pmac_smp.o smp-tbsync.o
 obj-$(CONFIG_PPC_ISERIES)	+= iSeries_smp.o
 obj-$(CONFIG_PPC_PSERIES)	+= pSeries_smp.o
+obj-$(CONFIG_PPC_BPA)		+= pSeries_smp.o
 obj-$(CONFIG_PPC_MAPLE)		+= smp-tbsync.o
 endif
 
@@ -66,3 +73,8 @@ obj-$(CONFIG_ALTIVEC)		+= vecemu.o vecto
 obj-$(CONFIG_KPROBES)		+= kprobes.o
 
 CFLAGS_ioctl32.o += -Ifs/
+
+ifeq ($(CONFIG_PPC_ISERIES),y)
+arch/ppc64/kernel/head.o: arch/ppc64/kernel/lparmap.s
+AFLAGS_head.o += -Iarch/ppc64/kernel
+endif
diff --git a/arch/ppc64/kernel/XmPciLpEvent.c b/arch/ppc64/kernel/XmPciLpEvent.c
deleted file mode 100644
--- a/arch/ppc64/kernel/XmPciLpEvent.c
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * File XmPciLpEvent.h created by Wayne Holm on Mon Jan 15 2001.
- *
- * This module handles PCI interrupt events sent by the iSeries Hypervisor.
-*/
-
-#include <linux/config.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/threads.h>
-#include <linux/smp.h>
-#include <linux/param.h>
-#include <linux/string.h>
-#include <linux/bootmem.h>
-#include <linux/ide.h>
-
-#include <asm/iSeries/HvTypes.h>
-#include <asm/iSeries/HvLpEvent.h>
-#include <asm/iSeries/HvCallPci.h>
-#include <asm/iSeries/XmPciLpEvent.h>
-#include <asm/ppcdebug.h>
-
-static long Pci_Interrupt_Count;
-static long Pci_Event_Count;
-
-enum XmPciLpEvent_Subtype {
-	XmPciLpEvent_BusCreated	   = 0,		// PHB has been created
-	XmPciLpEvent_BusError	   = 1,		// PHB has failed
-	XmPciLpEvent_BusFailed	   = 2,		// Msg to Secondary, Primary failed bus
-	XmPciLpEvent_NodeFailed	   = 4,		// Multi-adapter bridge has failed
-	XmPciLpEvent_NodeRecovered = 5,		// Multi-adapter bridge has recovered
-	XmPciLpEvent_BusRecovered  = 12,	// PHB has been recovered
-	XmPciLpEvent_UnQuiesceBus  = 18,	// Secondary bus unqiescing
-	XmPciLpEvent_BridgeError   = 21,	// Bridge Error
-	XmPciLpEvent_SlotInterrupt = 22		// Slot interrupt
-};
-
-struct XmPciLpEvent_BusInterrupt {
-	HvBusNumber	busNumber;
-	HvSubBusNumber	subBusNumber;
-};
-
-struct XmPciLpEvent_NodeInterrupt {
-	HvBusNumber	busNumber;
-	HvSubBusNumber	subBusNumber;
-	HvAgentId	deviceId;
-};
-
-struct XmPciLpEvent {
-	struct HvLpEvent hvLpEvent;
-
-	union {
-		u64 alignData;			// Align on an 8-byte boundary
-
-		struct {
-			u32		fisr;
-			HvBusNumber	busNumber;
-			HvSubBusNumber	subBusNumber;
-			HvAgentId	deviceId;
-		} slotInterrupt;
-
-		struct XmPciLpEvent_BusInterrupt busFailed;
-		struct XmPciLpEvent_BusInterrupt busRecovered;
-		struct XmPciLpEvent_BusInterrupt busCreated;
-
-		struct XmPciLpEvent_NodeInterrupt nodeFailed;
-		struct XmPciLpEvent_NodeInterrupt nodeRecovered;
-
-	} eventData;
-
-};
-
-static void intReceived(struct XmPciLpEvent *eventParm,
-		struct pt_regs *regsParm);
-
-static void XmPciLpEvent_handler(struct HvLpEvent *eventParm,
-		struct pt_regs *regsParm)
-{
-#ifdef CONFIG_PCI
-#if 0
-	PPCDBG(PPCDBG_BUSWALK, "XmPciLpEvent_handler, type 0x%x\n",
-			eventParm->xType);
-#endif
-	++Pci_Event_Count;
-
-	if (eventParm && (eventParm->xType == HvLpEvent_Type_PciIo)) {
-		switch (eventParm->xFlags.xFunction) {
-		case HvLpEvent_Function_Int:
-			intReceived((struct XmPciLpEvent *)eventParm, regsParm);
-			break;
-		case HvLpEvent_Function_Ack:
-			printk(KERN_ERR
-				"XmPciLpEvent.c: unexpected ack received\n");
-			break;
-		default:
-			printk(KERN_ERR
-				"XmPciLpEvent.c: unexpected event function %d\n",
-				(int)eventParm->xFlags.xFunction);
-			break;
-		}
-	} else if (eventParm)
-		printk(KERN_ERR
-			"XmPciLpEvent.c: Unrecognized PCI event type 0x%x\n",
-			(int)eventParm->xType);
-	else
-		printk(KERN_ERR "XmPciLpEvent.c: NULL event received\n");
-#endif
-}
-
-static void intReceived(struct XmPciLpEvent *eventParm,
-		struct pt_regs *regsParm)
-{
-	int irq;
-
-	++Pci_Interrupt_Count;
-#if 0
-	PPCDBG(PPCDBG_BUSWALK, "PCI: XmPciLpEvent.c: intReceived\n");
-#endif
-
-	switch (eventParm->hvLpEvent.xSubtype) {
-	case XmPciLpEvent_SlotInterrupt:
-		irq = eventParm->hvLpEvent.xCorrelationToken;
-		/* Dispatch the interrupt handlers for this irq */
-		ppc_irq_dispatch_handler(regsParm, irq);
-		HvCallPci_eoi(eventParm->eventData.slotInterrupt.busNumber,
-			eventParm->eventData.slotInterrupt.subBusNumber,
-			eventParm->eventData.slotInterrupt.deviceId);
-		break;
-		/* Ignore error recovery events for now */
-	case XmPciLpEvent_BusCreated:
-		printk(KERN_INFO "XmPciLpEvent.c: system bus %d created\n",
-			eventParm->eventData.busCreated.busNumber);
-		break;
-	case XmPciLpEvent_BusError:
-	case XmPciLpEvent_BusFailed:
-		printk(KERN_INFO "XmPciLpEvent.c: system bus %d failed\n",
-			eventParm->eventData.busFailed.busNumber);
-		break;
-	case XmPciLpEvent_BusRecovered:
-	case XmPciLpEvent_UnQuiesceBus:
-		printk(KERN_INFO "XmPciLpEvent.c: system bus %d recovered\n",
-			eventParm->eventData.busRecovered.busNumber);
-		break;
-	case XmPciLpEvent_NodeFailed:
-	case XmPciLpEvent_BridgeError:
-		printk(KERN_INFO
-			"XmPciLpEvent.c: multi-adapter bridge %d/%d/%d failed\n",
-			eventParm->eventData.nodeFailed.busNumber,
-			eventParm->eventData.nodeFailed.subBusNumber,
-			eventParm->eventData.nodeFailed.deviceId);
-		break;
-	case XmPciLpEvent_NodeRecovered:
-		printk(KERN_INFO
-			"XmPciLpEvent.c: multi-adapter bridge %d/%d/%d recovered\n",
-			eventParm->eventData.nodeRecovered.busNumber,
-			eventParm->eventData.nodeRecovered.subBusNumber,
-			eventParm->eventData.nodeRecovered.deviceId);
-		break;
-	default:
-		printk(KERN_ERR
-			"XmPciLpEvent.c: unrecognized event subtype 0x%x\n",
-			eventParm->hvLpEvent.xSubtype);
-		break;
-	}
-}
-
-
-/* This should be called sometime prior to buswalk (init_IRQ would be good) */
-int XmPciLpEvent_init()
-{
-	int xRc;
-
-	PPCDBG(PPCDBG_BUSWALK,
-			"XmPciLpEvent_init, Register Event type 0x%04X\n",
-			HvLpEvent_Type_PciIo);
-
-	xRc = HvLpEvent_registerHandler(HvLpEvent_Type_PciIo,
-			&XmPciLpEvent_handler);
-	if (xRc == 0) {
-		xRc = HvLpEvent_openPath(HvLpEvent_Type_PciIo, 0);
-		if (xRc != 0)
-			printk(KERN_ERR
-				"XmPciLpEvent.c: open event path failed with rc 0x%x\n",
-				xRc);
-	} else
-		printk(KERN_ERR
-			"XmPciLpEvent.c: register handler failed with rc 0x%x\n",
-			xRc);
-	return xRc;
-}
diff --git a/arch/ppc64/kernel/asm-offsets.c b/arch/ppc64/kernel/asm-offsets.c
--- a/arch/ppc64/kernel/asm-offsets.c
+++ b/arch/ppc64/kernel/asm-offsets.c
@@ -31,7 +31,6 @@
 
 #include <asm/paca.h>
 #include <asm/lppaca.h>
-#include <asm/iSeries/ItLpQueue.h>
 #include <asm/iSeries/HvLpEvent.h>
 #include <asm/rtas.h>
 #include <asm/cputable.h>
diff --git a/arch/ppc64/kernel/bpa_iic.c b/arch/ppc64/kernel/bpa_iic.c
new file mode 100644
--- /dev/null
+++ b/arch/ppc64/kernel/bpa_iic.c
@@ -0,0 +1,270 @@
+/*
+ * BPA Internal Interrupt Controller
+ *
+ * (C) Copyright IBM Deutschland Entwicklung GmbH 2005
+ *
+ * Author: Arnd Bergmann <arndb@de.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, 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 <linux/config.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/percpu.h>
+#include <linux/types.h>
+
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/prom.h>
+#include <asm/ptrace.h>
+
+#include "bpa_iic.h"
+
+struct iic_pending_bits {
+	u32 data;
+	u8 flags;
+	u8 class;
+	u8 source;
+	u8 prio;
+};
+
+enum iic_pending_flags {
+	IIC_VALID = 0x80,
+	IIC_IPI   = 0x40,
+};
+
+struct iic_regs {
+	struct iic_pending_bits pending;
+	struct iic_pending_bits pending_destr;
+	u64 generate;
+	u64 prio;
+};
+
+struct iic {
+	struct iic_regs __iomem *regs;
+};
+
+static DEFINE_PER_CPU(struct iic, iic);
+
+void iic_local_enable(void)
+{
+	out_be64(&__get_cpu_var(iic).regs->prio, 0xff);
+}
+
+void iic_local_disable(void)
+{
+	out_be64(&__get_cpu_var(iic).regs->prio, 0x0);
+}
+
+static unsigned int iic_startup(unsigned int irq)
+{
+	return 0;
+}
+
+static void iic_enable(unsigned int irq)
+{
+	iic_local_enable();
+}
+
+static void iic_disable(unsigned int irq)
+{
+}
+
+static void iic_end(unsigned int irq)
+{
+	iic_local_enable();
+}
+
+static struct hw_interrupt_type iic_pic = {
+	.typename = " BPA-IIC  ",
+	.startup = iic_startup,
+	.enable = iic_enable,
+	.disable = iic_disable,
+	.end = iic_end,
+};
+
+static int iic_external_get_irq(struct iic_pending_bits pending)
+{
+	int irq;
+	unsigned char node, unit;
+
+	node = pending.source >> 4;
+	unit = pending.source & 0xf;
+	irq = -1;
+
+	/*
+	 * This mapping is specific to the Broadband
+	 * Engine. We might need to get the numbers
+	 * from the device tree to support future CPUs.
+	 */
+	switch (unit) {
+	case 0x00:
+	case 0x0b:
+		/*
+		 * One of these units can be connected
+		 * to an external interrupt controller.
+		 */
+		if (pending.prio > 0x3f ||
+		    pending.class != 2)
+			break;
+		irq = IIC_EXT_OFFSET
+			+ spider_get_irq(pending.prio + node * IIC_NODE_STRIDE)
+			+ node * IIC_NODE_STRIDE;
+		break;
+	case 0x01 ... 0x04:
+	case 0x07 ... 0x0a:
+		/*
+		 * These units are connected to the SPEs
+		 */
+		if (pending.class > 2)
+			break;
+		irq = IIC_SPE_OFFSET
+			+ pending.class * IIC_CLASS_STRIDE
+			+ node * IIC_NODE_STRIDE
+			+ unit;
+		break;
+	}
+	if (irq == -1)
+		printk(KERN_WARNING "Unexpected interrupt class %02x, "
+			"source %02x, prio %02x, cpu %02x\n", pending.class,
+			pending.source, pending.prio, smp_processor_id());
+	return irq;
+}
+
+/* Get an IRQ number from the pending state register of the IIC */
+int iic_get_irq(struct pt_regs *regs)
+{
+	struct iic *iic;
+	int irq;
+	struct iic_pending_bits pending;
+
+	iic = &__get_cpu_var(iic);
+	*(unsigned long *) &pending = 
+		in_be64((unsigned long __iomem *) &iic->regs->pending_destr);
+
+	irq = -1;
+	if (pending.flags & IIC_VALID) {
+		if (pending.flags & IIC_IPI) {
+			irq = IIC_IPI_OFFSET + (pending.prio >> 4);
+/*
+			if (irq > 0x80)
+				printk(KERN_WARNING "Unexpected IPI prio %02x"
+					"on CPU %02x\n", pending.prio,
+							smp_processor_id());
+*/
+		} else {
+			irq = iic_external_get_irq(pending);
+		}
+	}
+	return irq;
+}
+
+static struct iic_regs __iomem *find_iic(int cpu)
+{
+	struct device_node *np;
+	int nodeid = cpu / 2;
+	unsigned long regs;
+	struct iic_regs __iomem *iic_regs;
+
+	for (np = of_find_node_by_type(NULL, "cpu");
+	     np;
+	     np = of_find_node_by_type(np, "cpu")) {
+		if (nodeid == *(int *)get_property(np, "node-id", NULL))
+			break;
+	}
+
+	if (!np) {
+		printk(KERN_WARNING "IIC: CPU %d not found\n", cpu);
+		iic_regs = NULL;
+	} else {
+		regs = *(long *)get_property(np, "iic", NULL);
+
+		/* hack until we have decided on the devtree info */
+		regs += 0x400;
+		if (cpu & 1)
+			regs += 0x20;
+
+		printk(KERN_DEBUG "IIC for CPU %d at %lx\n", cpu, regs);
+		iic_regs = __ioremap(regs, sizeof(struct iic_regs),
+						 _PAGE_NO_CACHE);
+	}
+	return iic_regs;
+}
+
+#ifdef CONFIG_SMP
+void iic_setup_cpu(void)
+{
+	out_be64(&__get_cpu_var(iic).regs->prio, 0xff);
+}
+
+void iic_cause_IPI(int cpu, int mesg)
+{
+	out_be64(&per_cpu(iic, cpu).regs->generate, mesg);
+}
+
+static irqreturn_t iic_ipi_action(int irq, void *dev_id, struct pt_regs *regs)
+{
+
+	smp_message_recv(irq - IIC_IPI_OFFSET, regs);
+	return IRQ_HANDLED;
+}
+
+static void iic_request_ipi(int irq, const char *name)
+{
+	/* IPIs are marked SA_INTERRUPT as they must run with irqs
+	 * disabled */
+	get_irq_desc(irq)->handler = &iic_pic;
+	get_irq_desc(irq)->status |= IRQ_PER_CPU;
+	request_irq(irq, iic_ipi_action, SA_INTERRUPT, name, NULL);
+}
+
+void iic_request_IPIs(void)
+{
+	iic_request_ipi(IIC_IPI_OFFSET + PPC_MSG_CALL_FUNCTION, "IPI-call");
+	iic_request_ipi(IIC_IPI_OFFSET + PPC_MSG_RESCHEDULE, "IPI-resched");
+#ifdef CONFIG_DEBUGGER
+	iic_request_ipi(IIC_IPI_OFFSET + PPC_MSG_DEBUGGER_BREAK, "IPI-debug");
+#endif /* CONFIG_DEBUGGER */
+}
+#endif /* CONFIG_SMP */
+
+static void iic_setup_spe_handlers(void)
+{
+	int be, isrc;
+
+	/* Assume two threads per BE are present */
+	for (be=0; be < num_present_cpus() / 2; be++) {
+		for (isrc = 0; isrc < IIC_CLASS_STRIDE * 3; isrc++) {
+			int irq = IIC_NODE_STRIDE * be + IIC_SPE_OFFSET + isrc;
+			get_irq_desc(irq)->handler = &iic_pic;
+		}
+	}
+}
+
+void iic_init_IRQ(void)
+{
+	int cpu, irq_offset;
+	struct iic *iic;
+
+	irq_offset = 0;
+	for_each_cpu(cpu) {
+		iic = &per_cpu(iic, cpu);
+		iic->regs = find_iic(cpu);
+		if (iic->regs)
+			out_be64(&iic->regs->prio, 0xff);
+	}
+	iic_setup_spe_handlers();
+}
diff --git a/arch/ppc64/kernel/bpa_iic.h b/arch/ppc64/kernel/bpa_iic.h
new file mode 100644
--- /dev/null
+++ b/arch/ppc64/kernel/bpa_iic.h
@@ -0,0 +1,62 @@
+#ifndef ASM_BPA_IIC_H
+#define ASM_BPA_IIC_H
+#ifdef __KERNEL__
+/*
+ * Mapping of IIC pending bits into per-node
+ * interrupt numbers.
+ *
+ * IRQ     FF CC SS PP   FF CC SS PP	Description
+ *
+ * 00-3f   80 02 +0 00 - 80 02 +0 3f	South Bridge
+ * 00-3f   80 02 +b 00 - 80 02 +b 3f	South Bridge
+ * 41-4a   80 00 +1 ** - 80 00 +a **	SPU Class 0
+ * 51-5a   80 01 +1 ** - 80 01 +a **	SPU Class 1
+ * 61-6a   80 02 +1 ** - 80 02 +a **	SPU Class 2
+ * 70-7f   C0 ** ** 00 - C0 ** ** 0f	IPI
+ *
+ *    F flags
+ *    C class
+ *    S source
+ *    P Priority
+ *    + node number
+ *    * don't care
+ *
+ * A node consists of a Broadband Engine and an optional
+ * south bridge device providing a maximum of 64 IRQs.
+ * The south bridge may be connected to either IOIF0
+ * or IOIF1.
+ * Each SPE is represented as three IRQ lines, one per
+ * interrupt class.
+ * 16 IRQ numbers are reserved for inter processor
+ * interruptions, although these are only used in the
+ * range of the first node.
+ *
+ * This scheme needs 128 IRQ numbers per BIF node ID,
+ * which means that with the total of 512 lines
+ * available, we can have a maximum of four nodes.
+ */
+
+enum {
+	IIC_EXT_OFFSET   = 0x00, /* Start of south bridge IRQs */
+	IIC_NUM_EXT      = 0x40, /* Number of south bridge IRQs */
+	IIC_SPE_OFFSET   = 0x40, /* Start of SPE interrupts */
+	IIC_CLASS_STRIDE = 0x10, /* SPE IRQs per class    */
+	IIC_IPI_OFFSET   = 0x70, /* Start of IPI IRQs */
+	IIC_NUM_IPIS     = 0x10, /* IRQs reserved for IPI */
+	IIC_NODE_STRIDE  = 0x80, /* Total IRQs per node   */
+};
+
+extern void iic_init_IRQ(void);
+extern int  iic_get_irq(struct pt_regs *regs);
+extern void iic_cause_IPI(int cpu, int mesg);
+extern void iic_request_IPIs(void);
+extern void iic_setup_cpu(void);
+extern void iic_local_enable(void);
+extern void iic_local_disable(void);
+
+
+extern void spider_init_IRQ(void);
+extern int spider_get_irq(unsigned long int_pending);
+
+#endif
+#endif /* ASM_BPA_IIC_H */
diff --git a/arch/ppc64/kernel/bpa_iommu.c b/arch/ppc64/kernel/bpa_iommu.c
new file mode 100644
--- /dev/null
+++ b/arch/ppc64/kernel/bpa_iommu.c
@@ -0,0 +1,377 @@
+/*
+ * IOMMU implementation for Broadband Processor Architecture
+ * We just establish a linear mapping at boot by setting all the
+ * IOPT cache entries in the CPU.
+ * The mapping functions should be identical to pci_direct_iommu, 
+ * except for the handling of the high order bit that is required
+ * by the Spider bridge. These should be split into a separate
+ * file at the point where we get a different bridge chip.
+ *
+ * Copyright (C) 2005 IBM Deutschland Entwicklung GmbH,
+ *			 Arnd Bergmann <arndb@de.ibm.com>
+ *
+ * Based on linear mapping
+ * Copyright (C) 2003 Benjamin Herrenschmidt (benh@kernel.crashing.org)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#undef DEBUG
+
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/bootmem.h>
+#include <linux/mm.h>
+#include <linux/dma-mapping.h>
+
+#include <asm/sections.h>
+#include <asm/iommu.h>
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/pci-bridge.h>
+#include <asm/machdep.h>
+#include <asm/pmac_feature.h>
+#include <asm/abs_addr.h>
+#include <asm/system.h>
+
+#include "pci.h"
+#include "bpa_iommu.h"
+
+static inline unsigned long 
+get_iopt_entry(unsigned long real_address, unsigned long ioid,
+			 unsigned long prot)
+{
+	return (prot & IOPT_PROT_MASK)
+	     | (IOPT_COHERENT)
+	     | (IOPT_ORDER_VC)
+	     | (real_address & IOPT_RPN_MASK)
+	     | (ioid & IOPT_IOID_MASK);
+}
+
+typedef struct {
+	unsigned long val;
+} ioste;
+
+static inline ioste
+mk_ioste(unsigned long val)
+{
+	ioste ioste = { .val = val, };
+	return ioste;
+}
+
+static inline ioste
+get_iost_entry(unsigned long iopt_base, unsigned long io_address, unsigned page_size)
+{
+	unsigned long ps;
+	unsigned long iostep;
+	unsigned long nnpt;
+	unsigned long shift;
+
+	switch (page_size) {
+	case 0x1000000:
+		ps = IOST_PS_16M;
+		nnpt = 0;  /* one page per segment */
+		shift = 5; /* segment has 16 iopt entries */
+		break;
+
+	case 0x100000:
+		ps = IOST_PS_1M;
+		nnpt = 0;  /* one page per segment */
+		shift = 1; /* segment has 256 iopt entries */
+		break;
+
+	case 0x10000:
+		ps = IOST_PS_64K;
+		nnpt = 0x07; /* 8 pages per io page table */
+		shift = 0;   /* all entries are used */
+		break;
+
+	case 0x1000:
+		ps = IOST_PS_4K;
+		nnpt = 0x7f; /* 128 pages per io page table */
+		shift = 0;   /* all entries are used */
+		break;
+
+	default: /* not a known compile time constant */
+		BUILD_BUG_ON(1);
+		break;
+	}
+
+	iostep = iopt_base +
+			 /* need 8 bytes per iopte */
+			(((io_address / page_size * 8)
+			 /* align io page tables on 4k page boundaries */
+				 << shift) 
+			 /* nnpt+1 pages go into each iopt */
+				 & ~(nnpt << 12));
+
+	nnpt++; /* this seems to work, but the documentation is not clear
+		   about wether we put nnpt or nnpt-1 into the ioste bits.
+		   In theory, this can't work for 4k pages. */
+	return mk_ioste(IOST_VALID_MASK
+			| (iostep & IOST_PT_BASE_MASK)
+			| ((nnpt << 5) & IOST_NNPT_MASK)
+			| (ps & IOST_PS_MASK));
+}
+
+/* compute the address of an io pte */
+static inline unsigned long
+get_ioptep(ioste iost_entry, unsigned long io_address)
+{
+	unsigned long iopt_base;
+	unsigned long page_size;
+	unsigned long page_number;
+	unsigned long iopt_offset;
+
+	iopt_base = iost_entry.val & IOST_PT_BASE_MASK;
+	page_size = iost_entry.val & IOST_PS_MASK;
+
+	/* decode page size to compute page number */
+	page_number = (io_address & 0x0fffffff) >> (10 + 2 * page_size);
+	/* page number is an offset into the io page table */
+	iopt_offset = (page_number << 3) & 0x7fff8ul;
+	return iopt_base + iopt_offset;
+}
+
+/* compute the tag field of the iopt cache entry */
+static inline unsigned long
+get_ioc_tag(ioste iost_entry, unsigned long io_address)
+{
+	unsigned long iopte = get_ioptep(iost_entry, io_address);
+
+	return IOPT_VALID_MASK
+	     | ((iopte & 0x00000000000000ff8ul) >> 3)
+	     | ((iopte & 0x0000003fffffc0000ul) >> 9);
+}
+
+/* compute the hashed 6 bit index for the 4-way associative pte cache */
+static inline unsigned long
+get_ioc_hash(ioste iost_entry, unsigned long io_address)
+{
+	unsigned long iopte = get_ioptep(iost_entry, io_address);
+
+	return ((iopte & 0x000000000000001f8ul) >> 3)
+	     ^ ((iopte & 0x00000000000020000ul) >> 17)
+	     ^ ((iopte & 0x00000000000010000ul) >> 15)
+	     ^ ((iopte & 0x00000000000008000ul) >> 13)
+	     ^ ((iopte & 0x00000000000004000ul) >> 11)
+	     ^ ((iopte & 0x00000000000002000ul) >> 9)
+	     ^ ((iopte & 0x00000000000001000ul) >> 7);
+}
+
+/* same as above, but pretend that we have a simpler 1-way associative
+   pte cache with an 8 bit index */
+static inline unsigned long
+get_ioc_hash_1way(ioste iost_entry, unsigned long io_address)
+{
+	unsigned long iopte = get_ioptep(iost_entry, io_address);
+
+	return ((iopte & 0x000000000000001f8ul) >> 3)
+	     ^ ((iopte & 0x00000000000020000ul) >> 17)
+	     ^ ((iopte & 0x00000000000010000ul) >> 15)
+	     ^ ((iopte & 0x00000000000008000ul) >> 13)
+	     ^ ((iopte & 0x00000000000004000ul) >> 11)
+	     ^ ((iopte & 0x00000000000002000ul) >> 9)
+	     ^ ((iopte & 0x00000000000001000ul) >> 7)
+	     ^ ((iopte & 0x0000000000000c000ul) >> 8);
+}
+
+static inline ioste
+get_iost_cache(void __iomem *base, unsigned long index)
+{
+	unsigned long __iomem *p = (base + IOC_ST_CACHE_DIR);
+	return mk_ioste(in_be64(&p[index]));
+}
+
+static inline void
+set_iost_cache(void __iomem *base, unsigned long index, ioste ste)
+{
+	unsigned long __iomem *p = (base + IOC_ST_CACHE_DIR);
+	pr_debug("ioste %02lx was %016lx, store %016lx", index,
+			get_iost_cache(base, index).val, ste.val);
+	out_be64(&p[index], ste.val);
+	pr_debug(" now %016lx\n", get_iost_cache(base, index).val);
+}
+
+static inline unsigned long
+get_iopt_cache(void __iomem *base, unsigned long index, unsigned long *tag)
+{
+	unsigned long __iomem *tags = (void *)(base + IOC_PT_CACHE_DIR);
+	unsigned long __iomem *p = (void *)(base + IOC_PT_CACHE_REG);	
+
+	*tag = tags[index];
+	rmb();
+	return *p;
+}
+
+static inline void
+set_iopt_cache(void __iomem *base, unsigned long index,
+		 unsigned long tag, unsigned long val)
+{
+	unsigned long __iomem *tags = base + IOC_PT_CACHE_DIR;
+	unsigned long __iomem *p = base + IOC_PT_CACHE_REG;
+	pr_debug("iopt %02lx was v%016lx/t%016lx, store v%016lx/t%016lx\n",
+		index, get_iopt_cache(base, index, &oldtag), oldtag, val, tag);
+
+	out_be64(p, val);
+	out_be64(&tags[index], tag);
+}
+
+static inline void
+set_iost_origin(void __iomem *base)
+{
+	unsigned long __iomem *p = base + IOC_ST_ORIGIN;
+	unsigned long origin = IOSTO_ENABLE | IOSTO_SW;
+
+	pr_debug("iost_origin %016lx, now %016lx\n", in_be64(p), origin);
+	out_be64(p, origin);
+}
+
+static inline void
+set_iocmd_config(void __iomem *base)
+{
+	unsigned long __iomem *p = base + 0xc00;
+	unsigned long conf;
+
+	conf = in_be64(p);
+	pr_debug("iost_conf %016lx, now %016lx\n", conf, conf | IOCMD_CONF_TE);
+	out_be64(p, conf | IOCMD_CONF_TE);
+}
+
+/* FIXME: get these from the device tree */
+#define ioc_base	0x20000511000ull
+#define ioc_mmio_base	0x20000510000ull
+#define ioid		0x48a
+#define iopt_phys_offset (- 0x20000000) /* We have a 512MB offset from the SB */
+#define io_page_size	0x1000000
+
+static unsigned long map_iopt_entry(unsigned long address)
+{
+	switch (address >> 20) {
+	case 0x600:
+		address = 0x24020000000ull; /* spider i/o */
+		break;
+	default:
+		address += iopt_phys_offset;
+		break;
+	}
+
+	return get_iopt_entry(address, ioid, IOPT_PROT_RW);
+}
+
+static void iommu_bus_setup_null(struct pci_bus *b) { }
+static void iommu_dev_setup_null(struct pci_dev *d) { }
+
+/* initialize the iommu to support a simple linear mapping
+ * for each DMA window used by any device. For now, we
+ * happen to know that there is only one DMA window in use,
+ * starting at iopt_phys_offset. */
+static void bpa_map_iommu(void)
+{
+	unsigned long address;
+	void __iomem *base;
+	ioste ioste;
+	unsigned long index;
+
+	base = __ioremap(ioc_base, 0x1000, _PAGE_NO_CACHE);
+	pr_debug("%lx mapped to %p\n", ioc_base, base);
+	set_iocmd_config(base);
+	iounmap(base);
+
+	base = __ioremap(ioc_mmio_base, 0x1000, _PAGE_NO_CACHE);
+	pr_debug("%lx mapped to %p\n", ioc_mmio_base, base);
+
+	set_iost_origin(base);
+
+	for (address = 0; address < 0x100000000ul; address += io_page_size) {
+		ioste = get_iost_entry(0x10000000000ul, address, io_page_size);
+		if ((address & 0xfffffff) == 0) /* segment start */
+			set_iost_cache(base, address >> 28, ioste);
+		index = get_ioc_hash_1way(ioste, address);
+		pr_debug("addr %08lx, index %02lx, ioste %016lx\n",
+					 address, index, ioste.val);
+		set_iopt_cache(base,
+			get_ioc_hash_1way(ioste, address),
+			get_ioc_tag(ioste, address),
+			map_iopt_entry(address));
+	}
+	iounmap(base);
+}
+
+
+static void *bpa_alloc_coherent(struct device *hwdev, size_t size,
+			   dma_addr_t *dma_handle, unsigned int __nocast flag)
+{
+	void *ret;
+
+	ret = (void *)__get_free_pages(flag, get_order(size));
+	if (ret != NULL) {
+		memset(ret, 0, size);
+		*dma_handle = virt_to_abs(ret) | BPA_DMA_VALID;
+	}
+	return ret;
+}
+
+static void bpa_free_coherent(struct device *hwdev, size_t size,
+				 void *vaddr, dma_addr_t dma_handle)
+{
+	free_pages((unsigned long)vaddr, get_order(size));
+}
+
+static dma_addr_t bpa_map_single(struct device *hwdev, void *ptr,
+		size_t size, enum dma_data_direction direction)
+{
+	return virt_to_abs(ptr) | BPA_DMA_VALID;
+}
+
+static void bpa_unmap_single(struct device *hwdev, dma_addr_t dma_addr,
+		size_t size, enum dma_data_direction direction)
+{
+}
+
+static int bpa_map_sg(struct device *hwdev, struct scatterlist *sg,
+		int nents, enum dma_data_direction direction)
+{
+	int i;
+
+	for (i = 0; i < nents; i++, sg++) {
+		sg->dma_address = (page_to_phys(sg->page) + sg->offset)
+					| BPA_DMA_VALID;
+		sg->dma_length = sg->length;
+	}
+
+	return nents;
+}
+
+static void bpa_unmap_sg(struct device *hwdev, struct scatterlist *sg,
+		int nents, enum dma_data_direction direction)
+{
+}
+
+static int bpa_dma_supported(struct device *dev, u64 mask)
+{
+	return mask < 0x100000000ull;
+}
+
+void bpa_init_iommu(void)
+{
+	bpa_map_iommu();
+
+	/* Direct I/O, IOMMU off */
+	ppc_md.iommu_dev_setup = iommu_dev_setup_null;
+	ppc_md.iommu_bus_setup = iommu_bus_setup_null;
+
+	pci_dma_ops.alloc_coherent = bpa_alloc_coherent;
+	pci_dma_ops.free_coherent = bpa_free_coherent;
+	pci_dma_ops.map_single = bpa_map_single;
+	pci_dma_ops.unmap_single = bpa_unmap_single;
+	pci_dma_ops.map_sg = bpa_map_sg;
+	pci_dma_ops.unmap_sg = bpa_unmap_sg;
+	pci_dma_ops.dma_supported = bpa_dma_supported;
+}
diff --git a/arch/ppc64/kernel/bpa_iommu.h b/arch/ppc64/kernel/bpa_iommu.h
new file mode 100644
--- /dev/null
+++ b/arch/ppc64/kernel/bpa_iommu.h
@@ -0,0 +1,65 @@
+#ifndef BPA_IOMMU_H
+#define BPA_IOMMU_H
+
+/* some constants */
+enum {
+	/* segment table entries */
+	IOST_VALID_MASK	  = 0x8000000000000000ul,
+	IOST_TAG_MASK     = 0x3000000000000000ul,
+	IOST_PT_BASE_MASK = 0x000003fffffff000ul,
+	IOST_NNPT_MASK	  = 0x0000000000000fe0ul,
+	IOST_PS_MASK	  = 0x000000000000000ful,
+
+	IOST_PS_4K	  = 0x1,
+	IOST_PS_64K	  = 0x3,
+	IOST_PS_1M	  = 0x5,
+	IOST_PS_16M	  = 0x7,
+
+	/* iopt tag register */
+	IOPT_VALID_MASK   = 0x0000000200000000ul,
+	IOPT_TAG_MASK	  = 0x00000001fffffffful,
+
+	/* iopt cache register */
+	IOPT_PROT_MASK	  = 0xc000000000000000ul,
+	IOPT_PROT_NONE	  = 0x0000000000000000ul,
+	IOPT_PROT_READ	  = 0x4000000000000000ul,
+	IOPT_PROT_WRITE	  = 0x8000000000000000ul,
+	IOPT_PROT_RW	  = 0xc000000000000000ul,
+	IOPT_COHERENT	  = 0x2000000000000000ul,
+	
+	IOPT_ORDER_MASK	  = 0x1800000000000000ul,
+	/* order access to same IOID/VC on same address */
+	IOPT_ORDER_ADDR	  = 0x0800000000000000ul,
+	/* similar, but only after a write access */
+	IOPT_ORDER_WRITES = 0x1000000000000000ul,
+	/* Order all accesses to same IOID/VC */
+	IOPT_ORDER_VC	  = 0x1800000000000000ul,
+	
+	IOPT_RPN_MASK	  = 0x000003fffffff000ul,
+	IOPT_HINT_MASK	  = 0x0000000000000800ul,
+	IOPT_IOID_MASK	  = 0x00000000000007fful,
+
+	IOSTO_ENABLE	  = 0x8000000000000000ul,
+	IOSTO_ORIGIN	  = 0x000003fffffff000ul,
+	IOSTO_HW	  = 0x0000000000000800ul,
+	IOSTO_SW	  = 0x0000000000000400ul,
+
+	IOCMD_CONF_TE	  = 0x0000800000000000ul,
+
+	/* memory mapped registers */
+	IOC_PT_CACHE_DIR  = 0x000,
+	IOC_ST_CACHE_DIR  = 0x800,
+	IOC_PT_CACHE_REG  = 0x910,
+	IOC_ST_ORIGIN     = 0x918,
+	IOC_CONF	  = 0x930,
+
+	/* The high bit needs to be set on every DMA address,
+	   only 2GB are addressable */
+	BPA_DMA_VALID	  = 0x80000000,
+	BPA_DMA_MASK	  = 0x7fffffff,
+};
+
+
+void bpa_init_iommu(void);
+
+#endif
diff --git a/arch/ppc64/kernel/bpa_nvram.c b/arch/ppc64/kernel/bpa_nvram.c
new file mode 100644
--- /dev/null
+++ b/arch/ppc64/kernel/bpa_nvram.c
@@ -0,0 +1,118 @@
+/*
+ * NVRAM for CPBW
+ *
+ * (C) Copyright IBM Corp. 2005
+ *
+ * Authors : Utz Bacher <utz.bacher@de.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, 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 <linux/fs.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+
+#include <asm/machdep.h>
+#include <asm/nvram.h>
+#include <asm/prom.h>
+
+static void __iomem *bpa_nvram_start;
+static long bpa_nvram_len;
+static spinlock_t bpa_nvram_lock = SPIN_LOCK_UNLOCKED;
+
+static ssize_t bpa_nvram_read(char *buf, size_t count, loff_t *index)
+{
+	unsigned long flags;
+
+	if (*index >= bpa_nvram_len)
+		return 0;
+	if (*index + count > bpa_nvram_len)
+		count = bpa_nvram_len - *index;
+
+	spin_lock_irqsave(&bpa_nvram_lock, flags);
+
+	memcpy_fromio(buf, bpa_nvram_start + *index, count);
+
+	spin_unlock_irqrestore(&bpa_nvram_lock, flags);
+	
+	*index += count;
+	return count;
+}
+
+static ssize_t bpa_nvram_write(char *buf, size_t count, loff_t *index)
+{
+	unsigned long flags;
+
+	if (*index >= bpa_nvram_len)
+		return 0;
+	if (*index + count > bpa_nvram_len)
+		count = bpa_nvram_len - *index;
+
+	spin_lock_irqsave(&bpa_nvram_lock, flags);
+
+	memcpy_toio(bpa_nvram_start + *index, buf, count);
+
+	spin_unlock_irqrestore(&bpa_nvram_lock, flags);
+	
+	*index += count;
+	return count;
+}
+
+static ssize_t bpa_nvram_get_size(void)
+{
+	return bpa_nvram_len;
+}
+
+int __init bpa_nvram_init(void)
+{
+	struct device_node *nvram_node;
+	unsigned long *buffer;
+	int proplen;
+	unsigned long nvram_addr;
+	int ret;
+
+	ret = -ENODEV;
+	nvram_node = of_find_node_by_type(NULL, "nvram");
+	if (!nvram_node)
+		goto out;
+
+	ret = -EIO;
+	buffer = (unsigned long *)get_property(nvram_node, "reg", &proplen);
+	if (proplen != 2*sizeof(unsigned long))
+		goto out;
+
+	ret = -ENODEV;
+	nvram_addr = buffer[0];
+	bpa_nvram_len = buffer[1];
+	if ( (!bpa_nvram_len) || (!nvram_addr) )
+		goto out;
+
+	bpa_nvram_start = ioremap(nvram_addr, bpa_nvram_len);
+	if (!bpa_nvram_start)
+		goto out;
+
+	printk(KERN_INFO "BPA NVRAM, %luk mapped to %p\n",
+	       bpa_nvram_len >> 10, bpa_nvram_start);
+
+	ppc_md.nvram_read	= bpa_nvram_read;
+	ppc_md.nvram_write	= bpa_nvram_write;
+	ppc_md.nvram_size	= bpa_nvram_get_size;
+
+out:
+	of_node_put(nvram_node);
+	return ret;
+}
diff --git a/arch/ppc64/kernel/bpa_setup.c b/arch/ppc64/kernel/bpa_setup.c
new file mode 100644
--- /dev/null
+++ b/arch/ppc64/kernel/bpa_setup.c
@@ -0,0 +1,140 @@
+/*
+ *  linux/arch/ppc/kernel/bpa_setup.c
+ *
+ *  Copyright (C) 1995  Linus Torvalds
+ *  Adapted from 'alpha' version by Gary Thomas
+ *  Modified by Cort Dougan (cort@cs.nmt.edu)
+ *  Modified by PPC64 Team, IBM Corp
+ *  Modified by BPA Team, IBM Deutschland Entwicklung 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.
+ */
+#undef DEBUG
+
+#include <linux/config.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/stddef.h>
+#include <linux/unistd.h>
+#include <linux/slab.h>
+#include <linux/user.h>
+#include <linux/reboot.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/seq_file.h>
+#include <linux/root_dev.h>
+#include <linux/console.h>
+
+#include <asm/mmu.h>
+#include <asm/processor.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/prom.h>
+#include <asm/rtas.h>
+#include <asm/pci-bridge.h>
+#include <asm/iommu.h>
+#include <asm/dma.h>
+#include <asm/machdep.h>
+#include <asm/time.h>
+#include <asm/nvram.h>
+#include <asm/cputable.h>
+
+#include "pci.h"
+#include "bpa_iic.h"
+#include "bpa_iommu.h"
+
+#ifdef DEBUG
+#define DBG(fmt...) udbg_printf(fmt)
+#else
+#define DBG(fmt...)
+#endif
+
+void bpa_get_cpuinfo(struct seq_file *m)
+{
+	struct device_node *root;
+	const char *model = "";
+
+	root = of_find_node_by_path("/");
+	if (root)
+		model = get_property(root, "model", NULL);
+	seq_printf(m, "machine\t\t: BPA %s\n", model);
+	of_node_put(root);
+}
+
+static void bpa_progress(char *s, unsigned short hex)
+{
+	printk("*** %04x : %s\n", hex, s ? s : "");
+}
+
+static void __init bpa_setup_arch(void)
+{
+	ppc_md.init_IRQ       = iic_init_IRQ;
+	ppc_md.get_irq        = iic_get_irq;
+
+#ifdef CONFIG_SMP
+	smp_init_pSeries();
+#endif
+
+	/* init to some ~sane value until calibrate_delay() runs */
+	loops_per_jiffy = 50000000;
+
+	if (ROOT_DEV == 0) {
+		printk("No ramdisk, default root is /dev/hda2\n");
+		ROOT_DEV = Root_HDA2;
+	}
+
+	/* Find and initialize PCI host bridges */
+	init_pci_config_tokens();
+	find_and_init_phbs();
+	spider_init_IRQ();
+#ifdef CONFIG_DUMMY_CONSOLE
+	conswitchp = &dummy_con;
+#endif
+
+	bpa_nvram_init();
+}
+
+/*
+ * Early initialization.  Relocation is on but do not reference unbolted pages
+ */
+static void __init bpa_init_early(void)
+{
+	DBG(" -> bpa_init_early()\n");
+
+	hpte_init_native();
+
+	bpa_init_iommu();
+
+	ppc64_interrupt_controller = IC_BPA_IIC;
+
+	DBG(" <- bpa_init_early()\n");
+}
+
+
+static int __init bpa_probe(int platform)
+{
+	if (platform != PLATFORM_BPA)
+		return 0;
+
+	return 1;
+}
+
+struct machdep_calls __initdata bpa_md = {
+	.probe			= bpa_probe,
+	.setup_arch		= bpa_setup_arch,
+	.init_early		= bpa_init_early,
+	.get_cpuinfo		= bpa_get_cpuinfo,
+	.restart		= rtas_restart,
+	.power_off		= rtas_power_off,
+	.halt			= rtas_halt,
+	.get_boot_time		= rtas_get_boot_time,
+	.get_rtc_time		= rtas_get_rtc_time,
+	.set_rtc_time		= rtas_set_rtc_time,
+	.calibrate_decr		= generic_calibrate_decr,
+	.progress		= bpa_progress,
+};
diff --git a/arch/ppc64/kernel/cpu_setup_power4.S b/arch/ppc64/kernel/cpu_setup_power4.S
--- a/arch/ppc64/kernel/cpu_setup_power4.S
+++ b/arch/ppc64/kernel/cpu_setup_power4.S
@@ -31,10 +31,13 @@ _GLOBAL(__970_cpu_preinit)
 	 */
 	mfspr	r0,SPRN_PVR
 	srwi	r0,r0,16
-	cmpwi	cr0,r0,0x39
-	cmpwi	cr1,r0,0x3c
-	cror	4*cr0+eq,4*cr0+eq,4*cr1+eq
+	cmpwi	r0,0x39
+	beq	1f
+	cmpwi	r0,0x3c
+	beq	1f
+	cmpwi	r0,0x44
 	bnelr
+1:
 
 	/* Make sure HID4:rm_ci is off before MMU is turned off, that large
 	 * pages are enabled with HID4:61 and clear HID5:DCBZ_size and
@@ -73,7 +76,21 @@ _GLOBAL(__970_cpu_preinit)
 
 _GLOBAL(__setup_cpu_power4)
 	blr
-	
+
+_GLOBAL(__setup_cpu_be)
+        /* Set large page sizes LP=0: 16MB, LP=1: 64KB */
+        addi    r3, 0,  0
+        ori     r3, r3, HID6_LB
+        sldi    r3, r3, 32
+        nor     r3, r3, r3
+        mfspr   r4, SPRN_HID6
+        and     r4, r4, r3
+        addi    r3, 0, 0x02000
+        sldi    r3, r3, 32
+        or      r4, r4, r3
+        mtspr   SPRN_HID6, r4
+	blr
+
 _GLOBAL(__setup_cpu_ppc970)
 	mfspr	r0,SPRN_HID0
 	li	r11,5			/* clear DOZE and SLEEP */
@@ -119,12 +136,14 @@ _GLOBAL(__save_cpu_setup)
 	/* We only deal with 970 for now */
 	mfspr	r0,SPRN_PVR
 	srwi	r0,r0,16
-	cmpwi	cr0,r0,0x39
-	cmpwi	cr1,r0,0x3c
-	cror	4*cr0+eq,4*cr0+eq,4*cr1+eq
-	bne	1f
+	cmpwi	r0,0x39
+	beq	1f
+	cmpwi	r0,0x3c
+	beq	1f
+	cmpwi	r0,0x44
+	bne	2f
 
-	/* Save HID0,1,4 and 5 */
+1:	/* Save HID0,1,4 and 5 */
 	mfspr	r3,SPRN_HID0
 	std	r3,CS_HID0(r5)
 	mfspr	r3,SPRN_HID1
@@ -134,7 +153,7 @@ _GLOBAL(__save_cpu_setup)
 	mfspr	r3,SPRN_HID5
 	std	r3,CS_HID5(r5)
 	
-1:
+2:
 	mtcr	r7
 	blr
 
@@ -151,12 +170,14 @@ _GLOBAL(__restore_cpu_setup)
 	/* We only deal with 970 for now */
 	mfspr	r0,SPRN_PVR
 	srwi	r0,r0,16
-	cmpwi	cr0,r0,0x39
-	cmpwi	cr1,r0,0x3c
-	cror	4*cr0+eq,4*cr0+eq,4*cr1+eq
-	bne	1f
+	cmpwi	r0,0x39
+	beq	1f
+	cmpwi	r0,0x3c
+	beq	1f
+	cmpwi	r0,0x44
+	bnelr
 
-	/* Before accessing memory, we make sure rm_ci is clear */
+1:	/* Before accessing memory, we make sure rm_ci is clear */
 	li	r0,0
 	mfspr	r3,SPRN_HID4
 	rldimi	r3,r0,40,23	/* clear bit 23 (rm_ci) */
@@ -209,6 +230,5 @@ _GLOBAL(__restore_cpu_setup)
 	mtspr	SPRN_HID5,r3
 	sync
 	isync
-1:
 	blr
 
diff --git a/arch/ppc64/kernel/cputable.c b/arch/ppc64/kernel/cputable.c
--- a/arch/ppc64/kernel/cputable.c
+++ b/arch/ppc64/kernel/cputable.c
@@ -34,6 +34,7 @@ EXPORT_SYMBOL(cur_cpu_spec);
 extern void __setup_cpu_power3(unsigned long offset, struct cpu_spec* spec);
 extern void __setup_cpu_power4(unsigned long offset, struct cpu_spec* spec);
 extern void __setup_cpu_ppc970(unsigned long offset, struct cpu_spec* spec);
+extern void __setup_cpu_be(unsigned long offset, struct cpu_spec* spec);
 
 
 /* We only set the altivec features if the kernel was compiled with altivec
@@ -48,150 +49,234 @@ extern void __setup_cpu_ppc970(unsigned 
 #endif
 
 struct cpu_spec	cpu_specs[] = {
-    {	/* Power3 */
-	    0xffff0000, 0x00400000, "POWER3 (630)",
-	    CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
-		    CPU_FTR_IABR | CPU_FTR_PMC8,
-	    COMMON_USER_PPC64,
-	    128, 128,
-	    __setup_cpu_power3,
-	    COMMON_PPC64_FW
-    },
-    {	/* Power3+ */
-	    0xffff0000, 0x00410000, "POWER3 (630+)",
-	    CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
-		    CPU_FTR_IABR | CPU_FTR_PMC8,
-	    COMMON_USER_PPC64,
-	    128, 128,
-	    __setup_cpu_power3,
-	    COMMON_PPC64_FW
-    },
-    {	/* Northstar */
-	    0xffff0000, 0x00330000, "RS64-II (northstar)",
-	    CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
-		    CPU_FTR_IABR | CPU_FTR_PMC8 | CPU_FTR_MMCRA,
-	    COMMON_USER_PPC64,
-	    128, 128,
-	    __setup_cpu_power3,
-	    COMMON_PPC64_FW
-    },
-    {	/* Pulsar */
-	    0xffff0000, 0x00340000, "RS64-III (pulsar)",
-	    CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
-		    CPU_FTR_IABR | CPU_FTR_PMC8 | CPU_FTR_MMCRA,
-	    COMMON_USER_PPC64,
-	    128, 128,
-	    __setup_cpu_power3,
-	    COMMON_PPC64_FW
-    },
-    {	/* I-star */
-	    0xffff0000, 0x00360000, "RS64-III (icestar)",
-	    CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
-		    CPU_FTR_IABR | CPU_FTR_PMC8 | CPU_FTR_MMCRA,
-	    COMMON_USER_PPC64,
-	    128, 128,
-	    __setup_cpu_power3,
-	    COMMON_PPC64_FW
-    },
-    {	/* S-star */
-	    0xffff0000, 0x00370000, "RS64-IV (sstar)",
-	    CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
-		    CPU_FTR_IABR | CPU_FTR_PMC8 | CPU_FTR_MMCRA,
-	    COMMON_USER_PPC64,
-	    128, 128,
-	    __setup_cpu_power3,
-	    COMMON_PPC64_FW
-    },
-    {	/* Power4 */
-	    0xffff0000, 0x00350000, "POWER4 (gp)",
-	    CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
-		    CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_PMC8 | CPU_FTR_MMCRA,
-	    COMMON_USER_PPC64,
-	    128, 128,
-	    __setup_cpu_power4,
-	    COMMON_PPC64_FW
-    },
-    {	/* Power4+ */
-	    0xffff0000, 0x00380000, "POWER4+ (gq)",
-	    CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
-		    CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_PMC8 | CPU_FTR_MMCRA,
-	    COMMON_USER_PPC64,
-	    128, 128,
-	    __setup_cpu_power4,
-	    COMMON_PPC64_FW
-    },
-    {	/* PPC970 */
-	    0xffff0000, 0x00390000, "PPC970",
-	    CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
-		    CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_ALTIVEC_COMP |
-		    CPU_FTR_CAN_NAP | CPU_FTR_PMC8 | CPU_FTR_MMCRA,
-	    COMMON_USER_PPC64 | PPC_FEATURE_HAS_ALTIVEC_COMP,
-	    128, 128,
-	    __setup_cpu_ppc970,
-	    COMMON_PPC64_FW
-    },
-    {	/* PPC970FX */
-	    0xffff0000, 0x003c0000, "PPC970FX",
-	    CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
-		    CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_ALTIVEC_COMP |
-		    CPU_FTR_CAN_NAP | CPU_FTR_PMC8 | CPU_FTR_MMCRA,
-	    COMMON_USER_PPC64 | PPC_FEATURE_HAS_ALTIVEC_COMP,
-	    128, 128,
-	    __setup_cpu_ppc970,
-	    COMMON_PPC64_FW
-    },
-    {	/* Power5 */
-	    0xffff0000, 0x003a0000, "POWER5 (gr)",
-	    CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
-		    CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_MMCRA | CPU_FTR_SMT |
-		    CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE |
-		    CPU_FTR_MMCRA_SIHV,
-	    COMMON_USER_PPC64,
-	    128, 128,
-	    __setup_cpu_power4,
-	    COMMON_PPC64_FW
-    },
-    {	/* Power5 */
-	    0xffff0000, 0x003b0000, "POWER5 (gs)",
-	    CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
-		    CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_MMCRA | CPU_FTR_SMT |
-		    CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE |
-		    CPU_FTR_MMCRA_SIHV,
-	    COMMON_USER_PPC64,
-	    128, 128,
-	    __setup_cpu_power4,
-	    COMMON_PPC64_FW
-    },
-    {	/* default match */
-	    0x00000000, 0x00000000, "POWER4 (compatible)",
-  	    CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
-		    CPU_FTR_PPCAS_ARCH_V2,
-	    COMMON_USER_PPC64,
-	    128, 128,
-	    __setup_cpu_power4,
-	    COMMON_PPC64_FW
-    }
+	{	/* Power3 */
+		.pvr_mask		= 0xffff0000,
+		.pvr_value		= 0x00400000,
+		.cpu_name		= "POWER3 (630)",
+		.cpu_features		= CPU_FTR_SPLIT_ID_CACHE |
+			CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | CPU_FTR_IABR |
+			CPU_FTR_PMC8,
+		.cpu_user_features = COMMON_USER_PPC64,
+		.icache_bsize		= 128,
+		.dcache_bsize		= 128,
+		.cpu_setup		= __setup_cpu_power3,
+		.firmware_features	= COMMON_PPC64_FW,
+	},
+	{	/* Power3+ */
+		.pvr_mask		= 0xffff0000,
+		.pvr_value		= 0x00410000,
+		.cpu_name		= "POWER3 (630+)",
+		.cpu_features		= CPU_FTR_SPLIT_ID_CACHE |
+			CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | CPU_FTR_IABR |
+			CPU_FTR_PMC8,
+		.cpu_user_features	= COMMON_USER_PPC64,
+		.icache_bsize		= 128,
+		.dcache_bsize		= 128,
+		.cpu_setup		= __setup_cpu_power3,
+		.firmware_features	= COMMON_PPC64_FW,
+	},
+	{	/* Northstar */
+		.pvr_mask		= 0xffff0000,
+		.pvr_value		= 0x00330000,
+		.cpu_name		= "RS64-II (northstar)",
+		.cpu_features		= CPU_FTR_SPLIT_ID_CACHE |
+			CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | CPU_FTR_IABR |
+			CPU_FTR_PMC8 | CPU_FTR_MMCRA | CPU_FTR_CTRL,
+		.cpu_user_features	= COMMON_USER_PPC64,
+		.icache_bsize		= 128,
+		.dcache_bsize		= 128,
+		.cpu_setup		= __setup_cpu_power3,
+		.firmware_features	= COMMON_PPC64_FW,
+	},
+	{	/* Pulsar */
+		.pvr_mask		= 0xffff0000,
+		.pvr_value		= 0x00340000,
+		.cpu_name		= "RS64-III (pulsar)",
+		.cpu_features		= CPU_FTR_SPLIT_ID_CACHE |
+			CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | CPU_FTR_IABR |
+			CPU_FTR_PMC8 | CPU_FTR_MMCRA | CPU_FTR_CTRL,
+		.cpu_user_features	= COMMON_USER_PPC64,
+		.icache_bsize		= 128,
+		.dcache_bsize		= 128,
+		.cpu_setup		= __setup_cpu_power3,
+		.firmware_features	= COMMON_PPC64_FW,
+	},
+	{	/* I-star */
+		.pvr_mask		= 0xffff0000,
+		.pvr_value		= 0x00360000,
+		.cpu_name		= "RS64-III (icestar)",
+		.cpu_features		= CPU_FTR_SPLIT_ID_CACHE |
+			CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | CPU_FTR_IABR |
+			CPU_FTR_PMC8 | CPU_FTR_MMCRA | CPU_FTR_CTRL,
+		.cpu_user_features	= COMMON_USER_PPC64,
+		.icache_bsize		= 128,
+		.dcache_bsize		= 128,
+		.cpu_setup		= __setup_cpu_power3,
+		.firmware_features	= COMMON_PPC64_FW,
+	},
+	{	/* S-star */
+		.pvr_mask		= 0xffff0000,
+		.pvr_value		= 0x00370000,
+		.cpu_name		= "RS64-IV (sstar)",
+		.cpu_features		= CPU_FTR_SPLIT_ID_CACHE |
+			CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | CPU_FTR_IABR |
+			CPU_FTR_PMC8 | CPU_FTR_MMCRA | CPU_FTR_CTRL,
+		.cpu_user_features	= COMMON_USER_PPC64,
+		.icache_bsize		= 128,
+		.dcache_bsize		= 128,
+		.cpu_setup		= __setup_cpu_power3,
+		.firmware_features	= COMMON_PPC64_FW,
+	},
+	{	/* Power4 */
+		.pvr_mask		= 0xffff0000,
+		.pvr_value		= 0x00350000,
+		.cpu_name		= "POWER4 (gp)",
+		.cpu_features		= CPU_FTR_SPLIT_ID_CACHE |
+			CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
+			CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_PMC8 | CPU_FTR_MMCRA,
+		.cpu_user_features	= COMMON_USER_PPC64,
+		.icache_bsize		= 128,
+		.dcache_bsize		= 128,
+		.cpu_setup		= __setup_cpu_power4,
+		.firmware_features	= COMMON_PPC64_FW,
+	},
+	{	/* Power4+ */
+		.pvr_mask		= 0xffff0000,
+		.pvr_value		= 0x00380000,
+		.cpu_name		= "POWER4+ (gq)",
+		.cpu_features		= CPU_FTR_SPLIT_ID_CACHE |
+			CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
+			CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_PMC8 | CPU_FTR_MMCRA,
+		.cpu_user_features	= COMMON_USER_PPC64,
+		.icache_bsize		= 128,
+		.dcache_bsize		= 128,
+		.cpu_setup		= __setup_cpu_power4,
+		.firmware_features	= COMMON_PPC64_FW,
+	},
+	{	/* PPC970 */
+		.pvr_mask		= 0xffff0000,
+		.pvr_value		= 0x00390000,
+		.cpu_name		= "PPC970",
+		.cpu_features		= CPU_FTR_SPLIT_ID_CACHE |
+			CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
+			CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_ALTIVEC_COMP |
+			CPU_FTR_CAN_NAP | CPU_FTR_PMC8 | CPU_FTR_MMCRA,
+		.cpu_user_features	= COMMON_USER_PPC64 |
+			PPC_FEATURE_HAS_ALTIVEC_COMP,
+		.icache_bsize		= 128,
+		.dcache_bsize		= 128,
+		.cpu_setup		= __setup_cpu_ppc970,
+		.firmware_features	= COMMON_PPC64_FW,
+	},
+	{	/* PPC970FX */
+		.pvr_mask		= 0xffff0000,
+		.pvr_value		= 0x003c0000,
+		.cpu_name		= "PPC970FX",
+		.cpu_features		= CPU_FTR_SPLIT_ID_CACHE |
+			CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
+			CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_ALTIVEC_COMP |
+			CPU_FTR_CAN_NAP | CPU_FTR_PMC8 | CPU_FTR_MMCRA,
+		.cpu_user_features	= COMMON_USER_PPC64 |
+			PPC_FEATURE_HAS_ALTIVEC_COMP,
+		.icache_bsize		= 128,
+		.dcache_bsize		= 128,
+		.cpu_setup		= __setup_cpu_ppc970,
+		.firmware_features	= COMMON_PPC64_FW,
+	},
+	{	/* PPC970MP */
+		.pvr_mask		= 0xffff0000,
+		.pvr_value		= 0x00440000,
+		.cpu_name		= "PPC970MP",
+		.cpu_features		= CPU_FTR_SPLIT_ID_CACHE |
+			CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
+			CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_ALTIVEC_COMP |
+			CPU_FTR_CAN_NAP | CPU_FTR_PMC8 | CPU_FTR_MMCRA,
+		.cpu_user_features	= COMMON_USER_PPC64 |
+			PPC_FEATURE_HAS_ALTIVEC_COMP,
+		.icache_bsize		= 128,
+		.dcache_bsize		= 128,
+		.cpu_setup		= __setup_cpu_ppc970,
+		.firmware_features	= COMMON_PPC64_FW,
+	},
+	{	/* Power5 */
+		.pvr_mask		= 0xffff0000,
+		.pvr_value		= 0x003a0000,
+		.cpu_name		= "POWER5 (gr)",
+		.cpu_features		= CPU_FTR_SPLIT_ID_CACHE |
+			CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
+			CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_MMCRA | CPU_FTR_SMT |
+			CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE |
+			CPU_FTR_MMCRA_SIHV,
+		.cpu_user_features	= COMMON_USER_PPC64,
+		.icache_bsize		= 128,
+		.dcache_bsize		= 128,
+		.cpu_setup		= __setup_cpu_power4,
+		.firmware_features	= COMMON_PPC64_FW,
+	},
+	{	/* Power5 */
+		.pvr_mask		= 0xffff0000,
+		.pvr_value		= 0x003b0000,
+		.cpu_name		= "POWER5 (gs)",
+		.cpu_features		= CPU_FTR_SPLIT_ID_CACHE |
+			CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
+			CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_MMCRA | CPU_FTR_SMT |
+			CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE |
+			CPU_FTR_MMCRA_SIHV,
+		.cpu_user_features	= COMMON_USER_PPC64,
+		.icache_bsize		= 128,
+		.dcache_bsize		= 128,
+		.cpu_setup		= __setup_cpu_power4,
+		.firmware_features	= COMMON_PPC64_FW,
+	},
+	{	/* BE DD1.x */
+		.pvr_mask		= 0xffff0000,
+		.pvr_value		= 0x00700000,
+		.cpu_name		= "Broadband Engine",
+		.cpu_features		= CPU_FTR_SPLIT_ID_CACHE |
+			CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
+			CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_ALTIVEC_COMP |
+			CPU_FTR_SMT,
+		.cpu_user_features	= COMMON_USER_PPC64 |
+			PPC_FEATURE_HAS_ALTIVEC_COMP,
+		.icache_bsize		= 128,
+		.dcache_bsize		= 128,
+		.cpu_setup		= __setup_cpu_be,
+		.firmware_features	= COMMON_PPC64_FW,
+	},
+	{	/* default match */
+		.pvr_mask		= 0x00000000,
+		.pvr_value		= 0x00000000,
+		.cpu_name		= "POWER4 (compatible)",
+		.cpu_features		= CPU_FTR_SPLIT_ID_CACHE |
+			CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
+			CPU_FTR_PPCAS_ARCH_V2,
+		.cpu_user_features	= COMMON_USER_PPC64,
+		.icache_bsize		= 128,
+		.dcache_bsize		= 128,
+		.cpu_setup		= __setup_cpu_power4,
+		.firmware_features	= COMMON_PPC64_FW,
+	}
 };
 
 firmware_feature_t firmware_features_table[FIRMWARE_MAX_FEATURES] = {
-    {FW_FEATURE_PFT,		"hcall-pft"},
-    {FW_FEATURE_TCE,		"hcall-tce"},
-    {FW_FEATURE_SPRG0,		"hcall-sprg0"},
-    {FW_FEATURE_DABR,		"hcall-dabr"},
-    {FW_FEATURE_COPY,		"hcall-copy"},
-    {FW_FEATURE_ASR,		"hcall-asr"},
-    {FW_FEATURE_DEBUG,		"hcall-debug"},
-    {FW_FEATURE_PERF,		"hcall-perf"},
-    {FW_FEATURE_DUMP,		"hcall-dump"},
-    {FW_FEATURE_INTERRUPT,	"hcall-interrupt"},
-    {FW_FEATURE_MIGRATE,	"hcall-migrate"},
-    {FW_FEATURE_PERFMON,	"hcall-perfmon"},
-    {FW_FEATURE_CRQ,    	"hcall-crq"},
-    {FW_FEATURE_VIO,	        "hcall-vio"},
-    {FW_FEATURE_RDMA,	        "hcall-rdma"},
-    {FW_FEATURE_LLAN,	        "hcall-lLAN"},
-    {FW_FEATURE_BULK,   	"hcall-bulk"},
-    {FW_FEATURE_XDABR,  	"hcall-xdabr"},
-    {FW_FEATURE_MULTITCE,	"hcall-multi-tce"},
-    {FW_FEATURE_SPLPAR,	        "hcall-splpar"},
+	{FW_FEATURE_PFT,		"hcall-pft"},
+	{FW_FEATURE_TCE,		"hcall-tce"},
+	{FW_FEATURE_SPRG0,		"hcall-sprg0"},
+	{FW_FEATURE_DABR,		"hcall-dabr"},
+	{FW_FEATURE_COPY,		"hcall-copy"},
+	{FW_FEATURE_ASR,		"hcall-asr"},
+	{FW_FEATURE_DEBUG,		"hcall-debug"},
+	{FW_FEATURE_PERF,		"hcall-perf"},
+	{FW_FEATURE_DUMP,		"hcall-dump"},
+	{FW_FEATURE_INTERRUPT,		"hcall-interrupt"},
+	{FW_FEATURE_MIGRATE,		"hcall-migrate"},
+	{FW_FEATURE_PERFMON,		"hcall-perfmon"},
+	{FW_FEATURE_CRQ,		"hcall-crq"},
+	{FW_FEATURE_VIO,		"hcall-vio"},
+	{FW_FEATURE_RDMA,		"hcall-rdma"},
+	{FW_FEATURE_LLAN,		"hcall-lLAN"},
+	{FW_FEATURE_BULK,		"hcall-bulk"},
+	{FW_FEATURE_XDABR,		"hcall-xdabr"},
+	{FW_FEATURE_MULTITCE,		"hcall-multi-tce"},
+	{FW_FEATURE_SPLPAR,		"hcall-splpar"},
 };
diff --git a/arch/ppc64/kernel/dma.c b/arch/ppc64/kernel/dma.c
--- a/arch/ppc64/kernel/dma.c
+++ b/arch/ppc64/kernel/dma.c
@@ -15,8 +15,10 @@
 
 static struct dma_mapping_ops *get_dma_ops(struct device *dev)
 {
+#ifdef CONFIG_PCI
 	if (dev->bus == &pci_bus_type)
 		return &pci_dma_ops;
+#endif
 #ifdef CONFIG_IBMVIO
 	if (dev->bus == &vio_bus_type)
 		return &vio_dma_ops;
@@ -37,8 +39,10 @@ EXPORT_SYMBOL(dma_supported);
 
 int dma_set_mask(struct device *dev, u64 dma_mask)
 {
+#ifdef CONFIG_PCI
 	if (dev->bus == &pci_bus_type)
 		return pci_set_dma_mask(to_pci_dev(dev), dma_mask);
+#endif
 #ifdef CONFIG_IBMVIO
 	if (dev->bus == &vio_bus_type)
 		return -EIO;
diff --git a/arch/ppc64/kernel/eeh.c b/arch/ppc64/kernel/eeh.c
--- a/arch/ppc64/kernel/eeh.c
+++ b/arch/ppc64/kernel/eeh.c
@@ -505,7 +505,7 @@ static inline unsigned long eeh_token_to
 	pte_t *ptep;
 	unsigned long pa;
 
-	ptep = find_linux_pte(ioremap_mm.pgd, token);
+	ptep = find_linux_pte(init_mm.pgd, token);
 	if (!ptep)
 		return token;
 	pa = pte_pfn(*ptep) << PAGE_SHIFT;
diff --git a/arch/ppc64/kernel/head.S b/arch/ppc64/kernel/head.S
--- a/arch/ppc64/kernel/head.S
+++ b/arch/ppc64/kernel/head.S
@@ -38,6 +38,7 @@
 #include <asm/cputable.h>
 #include <asm/setup.h>
 #include <asm/hvcall.h>
+#include <asm/iSeries/LparMap.h>
 
 #ifdef CONFIG_PPC_ISERIES
 #define DO_SOFT_DISABLE
@@ -308,6 +309,7 @@ exception_marker:
 label##_pSeries:					\
 	HMT_MEDIUM;					\
 	mtspr	SPRG1,r13;		/* save r13 */	\
+	RUNLATCH_ON(r13);				\
 	EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common)
 
 #define STD_EXCEPTION_ISERIES(n, label, area)		\
@@ -315,6 +317,7 @@ label##_pSeries:					\
 label##_iSeries:					\
 	HMT_MEDIUM;					\
 	mtspr	SPRG1,r13;		/* save r13 */	\
+	RUNLATCH_ON(r13);				\
 	EXCEPTION_PROLOG_ISERIES_1(area);		\
 	EXCEPTION_PROLOG_ISERIES_2;			\
 	b	label##_common
@@ -324,6 +327,7 @@ label##_iSeries:					\
 label##_iSeries:							\
 	HMT_MEDIUM;							\
 	mtspr	SPRG1,r13;		/* save r13 */			\
+	RUNLATCH_ON(r13);						\
 	EXCEPTION_PROLOG_ISERIES_1(PACA_EXGEN);				\
 	lbz	r10,PACAPROCENABLED(r13);				\
 	cmpwi	0,r10,0;						\
@@ -393,6 +397,7 @@ __start_interrupts:
 _machine_check_pSeries:
 	HMT_MEDIUM
 	mtspr	SPRG1,r13		/* save r13 */
+	RUNLATCH_ON(r13)
 	EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common)
 
 	. = 0x300
@@ -419,6 +424,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
 data_access_slb_pSeries:
 	HMT_MEDIUM
 	mtspr	SPRG1,r13
+	RUNLATCH_ON(r13)
 	mfspr	r13,SPRG3		/* get paca address into r13 */
 	std	r9,PACA_EXSLB+EX_R9(r13)	/* save r9 - r12 */
 	std	r10,PACA_EXSLB+EX_R10(r13)
@@ -439,6 +445,7 @@ data_access_slb_pSeries:
 instruction_access_slb_pSeries:
 	HMT_MEDIUM
 	mtspr	SPRG1,r13
+	RUNLATCH_ON(r13)
 	mfspr	r13,SPRG3		/* get paca address into r13 */
 	std	r9,PACA_EXSLB+EX_R9(r13)	/* save r9 - r12 */
 	std	r10,PACA_EXSLB+EX_R10(r13)
@@ -464,6 +471,7 @@ instruction_access_slb_pSeries:
 	.globl	system_call_pSeries
 system_call_pSeries:
 	HMT_MEDIUM
+	RUNLATCH_ON(r9)
 	mr	r9,r13
 	mfmsr	r10
 	mfspr	r13,SPRG3
@@ -515,36 +523,9 @@ __end_interrupts:
 #ifdef CONFIG_PPC_ISERIES
 	.globl naca
 naca:
-	.llong itVpdAreas
-
-	/*
-	 * The iSeries LPAR map is at this fixed address
-	 * so that the HvReleaseData structure can address
-	 * it with a 32-bit offset.
-	 *
-	 * The VSID values below are dependent on the
-	 * VSID generation algorithm.  See include/asm/mmu_context.h.
-	 */
-
-	. = 0x4800
-
-	.llong	2		/* # ESIDs to be mapped by hypervisor	 */
-	.llong	1		/* # memory ranges to be mapped by hypervisor */
-	.llong	STAB0_PAGE	/* Page # of segment table within load area	*/
-	.llong	0		/* Reserved */
-	.llong	0		/* Reserved */
-	.llong	0		/* Reserved */
-	.llong	0		/* Reserved */
-	.llong	0		/* Reserved */
-	.llong	(KERNELBASE>>SID_SHIFT)
-	.llong	0x408f92c94	/* KERNELBASE VSID */
-	/* We have to list the bolted VMALLOC segment here, too, so that it
-	 * will be restored on shared processor switch */
-	.llong	(VMALLOCBASE>>SID_SHIFT)
-	.llong	0xf09b89af5	/* VMALLOCBASE VSID */
-	.llong	8192		/* # pages to map (32 MB) */
-	.llong	0		/* Offset from start of loadarea to start of map */
-	.llong	0x408f92c940000	/* VPN of first page to map */
+	.llong	itVpdAreas
+	.llong	0		/* xRamDisk */
+	.llong	0		/* xRamDiskSize */
 
 	. = 0x6100
 
@@ -699,6 +680,11 @@ hardware_interrupt_iSeries_masked:
 	.globl fwnmi_data_area
 fwnmi_data_area:
 
+#ifdef CONFIG_PPC_ISERIES
+	. = LPARMAP_PHYS
+#include "lparmap.s"
+#endif /* CONFIG_PPC_ISERIES */
+
 /*
  * Vectors for the FWNMI option.  Share common code.
  */
@@ -707,11 +693,13 @@ fwnmi_data_area:
 system_reset_fwnmi:
 	HMT_MEDIUM
 	mtspr	SPRG1,r13		/* save r13 */
+	RUNLATCH_ON(r13)
 	EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common)
 	.globl machine_check_fwnmi
 machine_check_fwnmi:
 	HMT_MEDIUM
 	mtspr	SPRG1,r13		/* save r13 */
+	RUNLATCH_ON(r13)
 	EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common)
 
 	/*
@@ -848,6 +836,7 @@ unrecov_fer:
 	.align	7
 	.globl data_access_common
 data_access_common:
+	RUNLATCH_ON(r10)		/* It wont fit in the 0x300 handler */
 	mfspr	r10,DAR
 	std	r10,PACA_EXGEN+EX_DAR(r13)
 	mfspr	r10,DSISR
@@ -1194,7 +1183,7 @@ _GLOBAL(pSeries_secondary_smp_init)
 	bl	.__restore_cpu_setup
 
 	/* Set up a paca value for this processor. Since we have the
-	 * physical cpu id in r3, we need to search the pacas to find
+	 * physical cpu id in r24, we need to search the pacas to find
 	 * which logical id maps to our physical one.
 	 */
 	LOADADDR(r13, paca) 		/* Get base vaddr of paca array	 */
@@ -1207,8 +1196,8 @@ _GLOBAL(pSeries_secondary_smp_init)
 	cmpwi	r5,NR_CPUS
 	blt	1b
 
-99:	HMT_LOW				/* Couldn't find our CPU id      */
-	b	99b
+	mr	r3,r24			/* not found, copy phys to r3	 */
+	b	.kexec_wait		/* next kernel might do better	 */
 
 2:	mtspr	SPRG3,r13		/* Save vaddr of paca in SPRG3	 */
 	/* From now on, r24 is expected to be logica cpuid */
@@ -2088,7 +2077,7 @@ _GLOBAL(hmt_start_secondary)
 	blr
 #endif
 
-#if defined(CONFIG_SMP) && !defined(CONFIG_PPC_ISERIES)
+#if defined(CONFIG_KEXEC) || (defined(CONFIG_SMP) && !defined(CONFIG_PPC_ISERIES))
 _GLOBAL(smp_release_cpus)
 	/* All secondary cpus are spinning on a common
 	 * spinloop, release them all now so they can start
@@ -2121,17 +2110,6 @@ empty_zero_page:
 swapper_pg_dir:
 	.space	4096
 
-	.globl	ioremap_dir
-ioremap_dir:
-	.space	4096
-
-#ifdef CONFIG_SMP
-/* 1 page segment table per cpu (max 48, cpu0 allocated at STAB0_PHYS_ADDR) */
-	.globl	stab_array
-stab_array:
-	.space	4096 * 48
-#endif
-	
 /*
  * This space gets a copy of optional info passed to us by the bootstrap
  * Used to pass parameters into the kernel like root=/dev/sda1, etc.
diff --git a/arch/ppc64/kernel/hvconsole.c b/arch/ppc64/kernel/hvconsole.c
--- a/arch/ppc64/kernel/hvconsole.c
+++ b/arch/ppc64/kernel/hvconsole.c
@@ -27,7 +27,6 @@
 #include <linux/module.h>
 #include <asm/hvcall.h>
 #include <asm/hvconsole.h>
-#include <asm/prom.h>
 
 /**
  * hvc_get_chars - retrieve characters from firmware for denoted vterm adatper
@@ -42,29 +41,14 @@ int hvc_get_chars(uint32_t vtermno, char
 	unsigned long got;
 
 	if (plpar_hcall(H_GET_TERM_CHAR, vtermno, 0, 0, 0, &got,
-		(unsigned long *)buf, (unsigned long *)buf+1) == H_Success) {
-		/*
-		 * Work around a HV bug where it gives us a null
-		 * after every \r.  -- paulus
-		 */
-		if (got > 0) {
-			int i;
-			for (i = 1; i < got; ++i) {
-				if (buf[i] == 0 && buf[i-1] == '\r') {
-					--got;
-					if (i < got)
-						memmove(&buf[i], &buf[i+1],
-							got - i);
-				}
-			}
-		}
+		(unsigned long *)buf, (unsigned long *)buf+1) == H_Success)
 		return got;
-	}
 	return 0;
 }
 
 EXPORT_SYMBOL(hvc_get_chars);
 
+
 /**
  * hvc_put_chars: send characters to firmware for denoted vterm adapter
  * @vtermno: The vtermno or unit_address of the adapter from which the data
@@ -88,34 +72,3 @@ int hvc_put_chars(uint32_t vtermno, cons
 }
 
 EXPORT_SYMBOL(hvc_put_chars);
-
-/*
- * We hope/assume that the first vty found corresponds to the first console
- * device.
- */
-int hvc_find_vtys(void)
-{
-	struct device_node *vty;
-	int num_found = 0;
-
-	for (vty = of_find_node_by_name(NULL, "vty"); vty != NULL;
-			vty = of_find_node_by_name(vty, "vty")) {
-		uint32_t *vtermno;
-
-		/* We have statically defined space for only a certain number of
-		 * console adapters. */
-		if (num_found >= MAX_NR_HVC_CONSOLES)
-			break;
-
-		vtermno = (uint32_t *)get_property(vty, "reg", NULL);
-		if (!vtermno)
-			continue;
-
-		if (device_is_compatible(vty, "hvterm1")) {
-			hvc_instantiate(*vtermno, num_found);
-			++num_found;
-		}
-	}
-
-	return num_found;
-}
diff --git a/arch/ppc64/kernel/iSeries_VpdInfo.c b/arch/ppc64/kernel/iSeries_VpdInfo.c
--- a/arch/ppc64/kernel/iSeries_VpdInfo.c
+++ b/arch/ppc64/kernel/iSeries_VpdInfo.c
@@ -1,31 +1,31 @@
-/************************************************************************/
-/* File iSeries_vpdInfo.c created by Allan Trautman on Fri Feb  2 2001. */
-/************************************************************************/
-/* This code gets the card location of the hardware                     */
-/* Copyright (C) 20yy  <Allan H Trautman> <IBM Corp>                    */
-/*                                                                      */
-/* This program is free software; you can redistribute it and/or modify */
-/* it under the terms of the GNU General Public License as published by */
-/* the Free Software Foundation; either version 2 of the License, or    */
-/* (at your option) any later version.                                  */
-/*                                                                      */
-/* 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 Activity:                                                     */
-/*   Created, Feb 2, 2001                                               */
-/*   Ported to ppc64, August 20, 2001                                   */
-/* End Change Activity                                                  */
-/************************************************************************/
-#include <linux/config.h>
+/*
+ * File iSeries_vpdInfo.c created by Allan Trautman on Fri Feb  2 2001.
+ *
+ * This code gets the card location of the hardware
+ * Copyright (C) 2001  <Allan H Trautman> <IBM Corp>
+ * Copyright (C) 2005  Stephen Rothwel, IBM Corp
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 Activity:
+ *   Created, Feb 2, 2001
+ *   Ported to ppc64, August 20, 2001
+ * End Change Activity
+ */
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/pci.h>
@@ -34,30 +34,25 @@
 
 #include <asm/iSeries/HvCallPci.h>
 #include <asm/iSeries/HvTypes.h>
-#include <asm/iSeries/mf.h>
-#include <asm/iSeries/LparData.h>
 #include <asm/iSeries/iSeries_pci.h>
-#include "pci.h"
 
 /*
  * Size of Bus VPD data
  */
 #define BUS_VPDSIZE      1024
+
 /*
  * Bus Vpd Tags
  */
-#define  VpdEndOfDataTag   0x78
 #define  VpdEndOfAreaTag   0x79
 #define  VpdIdStringTag    0x82
 #define  VpdVendorAreaTag  0x84
+
 /*
  * Mfg Area Tags
  */
-#define  VpdFruFlag       0x4647     // "FG"
 #define  VpdFruFrameId    0x4649     // "FI"
 #define  VpdSlotMapFormat 0x4D46     // "MF"
-#define  VpdAsmPartNumber 0x504E     // "PN"
-#define  VpdFruSerial     0x534E     // "SN"
 #define  VpdSlotMap       0x534D     // "SM"
 
 /*
@@ -79,74 +74,33 @@ struct SlotMapStruct {
 	char CardLocation[3];
 	char Parms[8];
 	char Reserved[2];
-}; 
+};
 typedef struct SlotMapStruct SlotMap;
 #define SLOT_ENTRY_SIZE   16
 
 /*
- * Formats the device information.
- * - Pass in pci_dev* pointer to the device.
- * - Pass in buffer to place the data.  Danger here is the buffer must
- *   be as big as the client says it is.   Should be at least 128 bytes.
- * Return will the length of the string data put in the buffer.
- * Format:
- * PCI: Bus  0, Device 26, Vendor 0x12AE  Frame  1, Card  C10  Ethernet
- * controller
- */
-int iSeries_Device_Information(struct pci_dev *PciDev, char *buffer,
-		int BufferSize)
-{
-	struct iSeries_Device_Node *DevNode =
-		(struct iSeries_Device_Node *)PciDev->sysdata;
-	int len;
-
-	if (DevNode == NULL)
-		return sprintf(buffer,
-				"PCI: iSeries_Device_Information DevNode is NULL");
-
-	if (BufferSize < 128)
-		return 0;
-
-	len = sprintf(buffer, "PCI: Bus%3d, Device%3d, Vendor %04X ",
-			ISERIES_BUS(DevNode), PCI_SLOT(PciDev->devfn),
-			PciDev->vendor);
-	len += sprintf(buffer + len, "Frame%3d, Card %4s  ",
-			DevNode->FrameId, DevNode->CardLocation);
-#ifdef CONFIG_PCI
-	if (pci_class_name(PciDev->class >> 8) == 0)
-		len += sprintf(buffer + len, "0x%04X  ",
-				(int)(PciDev->class >> 8));
-	else
-		len += sprintf(buffer + len, "%s",
-				pci_class_name(PciDev->class >> 8));
-#endif
-	return len;
-}
-
-/*
  * Parse the Slot Area
  */
-void iSeries_Parse_SlotArea(SlotMap *MapPtr, int MapLen,
-		struct iSeries_Device_Node *DevNode)
+static void __init iSeries_Parse_SlotArea(SlotMap *MapPtr, int MapLen,
+		HvAgentId agent, u8 *PhbId, char card[4])
 {
 	int SlotMapLen = MapLen;
 	SlotMap *SlotMapPtr = MapPtr;
 
 	/*
-	 * Parse Slot label until we find the one requrested
+	 * Parse Slot label until we find the one requested
 	 */
 	while (SlotMapLen > 0) {
-		if (SlotMapPtr->AgentId == DevNode->AgentId ) {
+		if (SlotMapPtr->AgentId == agent) {
 			/*
 			 * If Phb wasn't found, grab the entry first one found.
 			 */
-			if (DevNode->PhbId == 0xff)
-				DevNode->PhbId = SlotMapPtr->PhbId; 
+			if (*PhbId == 0xff)
+				*PhbId = SlotMapPtr->PhbId;
 			/* Found it, extract the data. */
-			if (SlotMapPtr->PhbId == DevNode->PhbId ) {
-	        		memcpy(&DevNode->CardLocation,
-						&SlotMapPtr->CardLocation, 3);
-				DevNode->CardLocation[3]  = 0;
+			if (SlotMapPtr->PhbId == *PhbId) {
+				memcpy(card, &SlotMapPtr->CardLocation, 3);
+				card[3]  = 0;
 				break;
 			}
 		}
@@ -159,8 +113,9 @@ void iSeries_Parse_SlotArea(SlotMap *Map
 /*
  * Parse the Mfg Area
  */
-static void iSeries_Parse_MfgArea(u8 *AreaData, int AreaLen,
-		struct iSeries_Device_Node *DevNode)
+static void __init iSeries_Parse_MfgArea(u8 *AreaData, int AreaLen,
+		HvAgentId agent, u8 *PhbId,
+		u8 *frame, char card[4])
 {
 	MfgArea *MfgAreaPtr = (MfgArea *)AreaData;
 	int MfgAreaLen = AreaLen;
@@ -171,7 +126,7 @@ static void iSeries_Parse_MfgArea(u8 *Ar
 		int MfgTagLen = MfgAreaPtr->TagLength;
 		/* Frame ID         (FI 4649020310 ) */
 		if (MfgAreaPtr->Tag == VpdFruFrameId)		/* FI  */
-			DevNode->FrameId = MfgAreaPtr->AreaData1;
+			*frame = MfgAreaPtr->AreaData1;
 		/* Slot Map Format  (MF 4D46020004 ) */
 		else if (MfgAreaPtr->Tag == VpdSlotMapFormat)	/* MF  */
 			SlotMapFmt = (MfgAreaPtr->AreaData1 * 256)
@@ -183,10 +138,11 @@ static void iSeries_Parse_MfgArea(u8 *Ar
 			if (SlotMapFmt == 0x1004)
 				SlotMapPtr = (SlotMap *)((char *)MfgAreaPtr
 						+ MFG_ENTRY_SIZE + 1);
- 	    		else
+			else
 				SlotMapPtr = (SlotMap *)((char *)MfgAreaPtr
 						+ MFG_ENTRY_SIZE);
-	    		iSeries_Parse_SlotArea(SlotMapPtr, MfgTagLen, DevNode);
+			iSeries_Parse_SlotArea(SlotMapPtr, MfgTagLen,
+					agent, PhbId, card);
 		}
 		/*
 		 * Point to the next Mfg Area
@@ -194,19 +150,19 @@ static void iSeries_Parse_MfgArea(u8 *Ar
 		 */
 		MfgAreaPtr = (MfgArea *)((char *)MfgAreaPtr + MfgTagLen
 				+ MFG_ENTRY_SIZE);
-		MfgAreaLen -= (MfgTagLen + MFG_ENTRY_SIZE); 
-	}	
+		MfgAreaLen -= (MfgTagLen + MFG_ENTRY_SIZE);
+	}
 }
 
 /*
  * Look for "BUS".. Data is not Null terminated.
  * PHBID of 0xFF indicates PHB was not found in VPD Data.
  */
-static int iSeries_Parse_PhbId(u8 *AreaPtr, int AreaLength)
+static int __init iSeries_Parse_PhbId(u8 *AreaPtr, int AreaLength)
 {
 	u8 *PhbPtr = AreaPtr;
 	int DataLen = AreaLength;
-	char PhbId = 0xFF;                   
+	char PhbId = 0xFF;
 
 	while (DataLen > 0) {
 		if ((*PhbPtr == 'B') && (*(PhbPtr + 1) == 'U')
@@ -216,7 +172,7 @@ static int iSeries_Parse_PhbId(u8 *AreaP
 				++PhbPtr;
 			PhbId = (*PhbPtr & 0x0F);
 			break;
-        	}
+		}
 		++PhbPtr;
 		--DataLen;
 	}
@@ -226,52 +182,90 @@ static int iSeries_Parse_PhbId(u8 *AreaP
 /*
  * Parse out the VPD Areas
  */
-static void iSeries_Parse_Vpd(u8 *VpdData, int VpdDataLen,
-		struct iSeries_Device_Node *DevNode)
+static void __init iSeries_Parse_Vpd(u8 *VpdData, int VpdDataLen,
+		HvAgentId agent, u8 *frame, char card[4])
 {
 	u8 *TagPtr = VpdData;
 	int DataLen = VpdDataLen - 3;
+	u8 PhbId;
 
 	while ((*TagPtr != VpdEndOfAreaTag) && (DataLen > 0)) {
-		int AreaLen = *(TagPtr + 1) + (*(TagPtr + 2) * 256);	
+		int AreaLen = *(TagPtr + 1) + (*(TagPtr + 2) * 256);
 		u8 *AreaData  = TagPtr + 3;
 
 		if (*TagPtr == VpdIdStringTag)
-			DevNode->PhbId = iSeries_Parse_PhbId(AreaData, AreaLen);
+			PhbId = iSeries_Parse_PhbId(AreaData, AreaLen);
 		else if (*TagPtr == VpdVendorAreaTag)
-	    		iSeries_Parse_MfgArea(AreaData, AreaLen, DevNode);
+			iSeries_Parse_MfgArea(AreaData, AreaLen,
+					agent, &PhbId, frame, card);
 		/* Point to next Area. */
 		TagPtr  = AreaData + AreaLen;
 		DataLen -= AreaLen;
 	}
-}    
+}
 
-void iSeries_Get_Location_Code(struct iSeries_Device_Node *DevNode)
+static void __init iSeries_Get_Location_Code(u16 bus, HvAgentId agent,
+		u8 *frame, char card[4])
 {
 	int BusVpdLen = 0;
-	u8 *BusVpdPtr = (u8 *)kmalloc(BUS_VPDSIZE, GFP_KERNEL);
+	u8 *BusVpdPtr = kmalloc(BUS_VPDSIZE, GFP_KERNEL);
 
 	if (BusVpdPtr == NULL) {
 		printk("PCI: Bus VPD Buffer allocation failure.\n");
 		return;
 	}
-	BusVpdLen = HvCallPci_getBusVpd(ISERIES_BUS(DevNode),
-					ISERIES_HV_ADDR(BusVpdPtr),
+	BusVpdLen = HvCallPci_getBusVpd(bus, ISERIES_HV_ADDR(BusVpdPtr),
 					BUS_VPDSIZE);
 	if (BusVpdLen == 0) {
-		kfree(BusVpdPtr);
 		printk("PCI: Bus VPD Buffer zero length.\n");
-		return;
+		goto out_free;
 	}
 	/* printk("PCI: BusVpdPtr: %p, %d\n",BusVpdPtr, BusVpdLen); */
 	/* Make sure this is what I think it is */
 	if (*BusVpdPtr != VpdIdStringTag) {	/* 0x82 */
 		printk("PCI: Bus VPD Buffer missing starting tag.\n");
-		kfree(BusVpdPtr);
-		return;
+		goto out_free;
 	}
-	iSeries_Parse_Vpd(BusVpdPtr,BusVpdLen, DevNode);
-	sprintf(DevNode->Location, "Frame%3d, Card %-4s", DevNode->FrameId,
-			DevNode->CardLocation);
+	iSeries_Parse_Vpd(BusVpdPtr, BusVpdLen, agent, frame, card);
+out_free:
 	kfree(BusVpdPtr);
 }
+
+/*
+ * Prints the device information.
+ * - Pass in pci_dev* pointer to the device.
+ * - Pass in the device count
+ *
+ * Format:
+ * PCI: Bus  0, Device 26, Vendor 0x12AE  Frame  1, Card  C10  Ethernet
+ * controller
+ */
+void __init iSeries_Device_Information(struct pci_dev *PciDev, int count)
+{
+	struct iSeries_Device_Node *DevNode = PciDev->sysdata;
+	u16 bus;
+	u8 frame;
+	char card[4];
+	HvSubBusNumber subbus;
+	HvAgentId agent;
+
+	if (DevNode == NULL) {
+		printk("%d. PCI: iSeries_Device_Information DevNode is NULL\n",
+				count);
+		return;
+	}
+
+	bus = ISERIES_BUS(DevNode);
+	subbus = ISERIES_SUBBUS(DevNode);
+	agent = ISERIES_PCI_AGENTID(ISERIES_GET_DEVICE_FROM_SUBBUS(subbus),
+			ISERIES_GET_FUNCTION_FROM_SUBBUS(subbus));
+	iSeries_Get_Location_Code(bus, agent, &frame, card);
+
+	printk("%d. PCI: Bus%3d, Device%3d, Vendor %04X Frame%3d, Card %4s  ",
+			count, bus, PCI_SLOT(PciDev->devfn), PciDev->vendor,
+			frame, card);
+	if (pci_class_name(PciDev->class >> 8) == 0)
+		printk("0x%04X\n", (int)(PciDev->class >> 8));
+	else
+		printk("%s\n", pci_class_name(PciDev->class >> 8));
+}
diff --git a/arch/ppc64/kernel/iSeries_htab.c b/arch/ppc64/kernel/iSeries_htab.c
--- a/arch/ppc64/kernel/iSeries_htab.c
+++ b/arch/ppc64/kernel/iSeries_htab.c
@@ -38,11 +38,12 @@ static inline void iSeries_hunlock(unsig
 }
 
 static long iSeries_hpte_insert(unsigned long hpte_group, unsigned long va,
-			 unsigned long prpn, int secondary,
-			 unsigned long hpteflags, int bolted, int large)
+				unsigned long prpn, unsigned long vflags,
+				unsigned long rflags)
 {
 	long slot;
-	HPTE lhpte;
+	hpte_t lhpte;
+	int secondary = 0;
 
 	/*
 	 * The hypervisor tries both primary and secondary.
@@ -50,13 +51,13 @@ static long iSeries_hpte_insert(unsigned
 	 * it means we have already tried both primary and secondary,
 	 * so we return failure immediately.
 	 */
-	if (secondary)
+	if (vflags & HPTE_V_SECONDARY)
 		return -1;
 
 	iSeries_hlock(hpte_group);
 
 	slot = HvCallHpt_findValid(&lhpte, va >> PAGE_SHIFT);
-	BUG_ON(lhpte.dw0.dw0.v);
+	BUG_ON(lhpte.v & HPTE_V_VALID);
 
 	if (slot == -1)	{ /* No available entry found in either group */
 		iSeries_hunlock(hpte_group);
@@ -64,19 +65,13 @@ static long iSeries_hpte_insert(unsigned
 	}
 
 	if (slot < 0) {		/* MSB set means secondary group */
+		vflags |= HPTE_V_VALID;
 		secondary = 1;
 		slot &= 0x7fffffffffffffff;
 	}
 
-	lhpte.dw1.dword1      = 0;
-	lhpte.dw1.dw1.rpn     = physRpn_to_absRpn(prpn);
-	lhpte.dw1.flags.flags = hpteflags;
-
-	lhpte.dw0.dword0      = 0;
-	lhpte.dw0.dw0.avpn    = va >> 23;
-	lhpte.dw0.dw0.h       = secondary;
-	lhpte.dw0.dw0.bolted  = bolted;
-	lhpte.dw0.dw0.v       = 1;
+	lhpte.v = (va >> 23) << HPTE_V_AVPN_SHIFT | vflags | HPTE_V_VALID;
+	lhpte.r = (physRpn_to_absRpn(prpn) << HPTE_R_RPN_SHIFT) | rflags;
 
 	/* Now fill in the actual HPTE */
 	HvCallHpt_addValidate(slot, secondary, &lhpte);
@@ -88,20 +83,17 @@ static long iSeries_hpte_insert(unsigned
 
 static unsigned long iSeries_hpte_getword0(unsigned long slot)
 {
-	unsigned long dword0;
-	HPTE hpte;
+	hpte_t hpte;
 
 	HvCallHpt_get(&hpte, slot);
-	dword0 = hpte.dw0.dword0;
-
-	return dword0;
+	return hpte.v;
 }
 
 static long iSeries_hpte_remove(unsigned long hpte_group)
 {
 	unsigned long slot_offset;
 	int i;
-	HPTE lhpte;
+	unsigned long hpte_v;
 
 	/* Pick a random slot to start at */
 	slot_offset = mftb() & 0x7;
@@ -109,10 +101,9 @@ static long iSeries_hpte_remove(unsigned
 	iSeries_hlock(hpte_group);
 
 	for (i = 0; i < HPTES_PER_GROUP; i++) {
-		lhpte.dw0.dword0 = 
-			iSeries_hpte_getword0(hpte_group + slot_offset);
+		hpte_v = iSeries_hpte_getword0(hpte_group + slot_offset);
 
-		if (!lhpte.dw0.dw0.bolted) {
+		if (! (hpte_v & HPTE_V_BOLTED)) {
 			HvCallHpt_invalidateSetSwBitsGet(hpte_group + 
 							 slot_offset, 0, 0);
 			iSeries_hunlock(hpte_group);
@@ -137,13 +128,13 @@ static long iSeries_hpte_remove(unsigned
 static long iSeries_hpte_updatepp(unsigned long slot, unsigned long newpp,
 				  unsigned long va, int large, int local)
 {
-	HPTE hpte;
+	hpte_t hpte;
 	unsigned long avpn = va >> 23;
 
 	iSeries_hlock(slot);
 
 	HvCallHpt_get(&hpte, slot);
-	if ((hpte.dw0.dw0.avpn == avpn) && (hpte.dw0.dw0.v)) {
+	if ((HPTE_V_AVPN_VAL(hpte.v) == avpn) && (hpte.v & HPTE_V_VALID)) {
 		/*
 		 * Hypervisor expects bits as NPPP, which is
 		 * different from how they are mapped in our PP.
@@ -167,7 +158,7 @@ static long iSeries_hpte_updatepp(unsign
  */
 static long iSeries_hpte_find(unsigned long vpn)
 {
-	HPTE hpte;
+	hpte_t hpte;
 	long slot;
 
 	/*
@@ -177,7 +168,7 @@ static long iSeries_hpte_find(unsigned l
 	 * 0x80000000xxxxxxxx : Entry found in secondary group, slot x
 	 */
 	slot = HvCallHpt_findValid(&hpte, vpn); 
-	if (hpte.dw0.dw0.v) {
+	if (hpte.v & HPTE_V_VALID) {
 		if (slot < 0) {
 			slot &= 0x7fffffffffffffff;
 			slot = -slot;
@@ -212,7 +203,7 @@ static void iSeries_hpte_updateboltedpp(
 static void iSeries_hpte_invalidate(unsigned long slot, unsigned long va,
 				    int large, int local)
 {
-	HPTE lhpte;
+	unsigned long hpte_v;
 	unsigned long avpn = va >> 23;
 	unsigned long flags;
 
@@ -220,9 +211,9 @@ static void iSeries_hpte_invalidate(unsi
 
 	iSeries_hlock(slot);
 
-	lhpte.dw0.dword0 = iSeries_hpte_getword0(slot);
+	hpte_v = iSeries_hpte_getword0(slot);
 	
-	if ((lhpte.dw0.dw0.avpn == avpn) && lhpte.dw0.dw0.v)
+	if ((HPTE_V_AVPN_VAL(hpte_v) == avpn) && (hpte_v & HPTE_V_VALID))
 		HvCallHpt_invalidateSetSwBitsGet(slot, 0, 0);
 
 	iSeries_hunlock(slot);
diff --git a/arch/ppc64/kernel/iSeries_iommu.c b/arch/ppc64/kernel/iSeries_iommu.c
--- a/arch/ppc64/kernel/iSeries_iommu.c
+++ b/arch/ppc64/kernel/iSeries_iommu.c
@@ -83,7 +83,7 @@ static void tce_free_iSeries(struct iomm
 	}
 }
 
-
+#ifdef CONFIG_PCI
 /*
  * This function compares the known tables to find an iommu_table
  * that has already been built for hardware TCEs.
@@ -159,6 +159,7 @@ void iommu_devnode_init_iSeries(struct i
 	else
 		kfree(tbl);
 }
+#endif
 
 static void iommu_dev_setup_iSeries(struct pci_dev *dev) { }
 static void iommu_bus_setup_iSeries(struct pci_bus *bus) { }
diff --git a/arch/ppc64/kernel/iSeries_irq.c b/arch/ppc64/kernel/iSeries_irq.c
--- a/arch/ppc64/kernel/iSeries_irq.c
+++ b/arch/ppc64/kernel/iSeries_irq.c
@@ -1,27 +1,29 @@
-/************************************************************************/
-/* This module supports the iSeries PCI bus interrupt handling          */
-/* Copyright (C) 20yy  <Robert L Holtorf> <IBM Corp>                    */
-/*                                                                      */
-/* This program is free software; you can redistribute it and/or modify */
-/* it under the terms of the GNU General Public License as published by */
-/* the Free Software Foundation; either version 2 of the License, or    */
-/* (at your option) any later version.                                  */
-/*                                                                      */
-/* 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 Activity:                                                     */
-/*   Created, December 13, 2000 by Wayne Holm                           */ 
-/* End Change Activity                                                  */
-/************************************************************************/
+/*
+ * This module supports the iSeries PCI bus interrupt handling
+ * Copyright (C) 20yy  <Robert L Holtorf> <IBM Corp>
+ * Copyright (C) 2004-2005 IBM Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the:
+ * Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330,
+ * Boston, MA  02111-1307  USA
+ *
+ * Change Activity:
+ *   Created, December 13, 2000 by Wayne Holm
+ * End Change Activity
+ */
+#include <linux/config.h>
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/threads.h>
@@ -30,30 +32,15 @@
 #include <linux/string.h>
 #include <linux/bootmem.h>
 #include <linux/ide.h>
-
 #include <linux/irq.h>
 #include <linux/spinlock.h>
-#include <asm/ppcdebug.h>
 
+#include <asm/ppcdebug.h>
+#include <asm/iSeries/HvTypes.h>
+#include <asm/iSeries/HvLpEvent.h>
 #include <asm/iSeries/HvCallPci.h>
 #include <asm/iSeries/HvCallXm.h>
 #include <asm/iSeries/iSeries_irq.h>
-#include <asm/iSeries/XmPciLpEvent.h>
-
-static unsigned int iSeries_startup_IRQ(unsigned int irq);
-static void iSeries_shutdown_IRQ(unsigned int irq);
-static void iSeries_enable_IRQ(unsigned int irq);
-static void iSeries_disable_IRQ(unsigned int irq);
-static void iSeries_end_IRQ(unsigned int irq);
-
-static hw_irq_controller iSeries_IRQ_handler = {
-	.typename = "iSeries irq controller",
-	.startup = iSeries_startup_IRQ,
-	.shutdown = iSeries_shutdown_IRQ,
-	.enable = iSeries_enable_IRQ,
-	.disable = iSeries_disable_IRQ,
-	.end = iSeries_end_IRQ
-};
 
 /* This maps virtual irq numbers to real irqs */
 unsigned int virt_irq_to_real_map[NR_IRQS];
@@ -62,37 +49,187 @@ unsigned int virt_irq_to_real_map[NR_IRQ
 /* Note: the pcnet32 driver assumes irq numbers < 2 aren't valid. :( */
 static int next_virtual_irq = 2;
 
-/* This is called by init_IRQ.  set in ppc_md.init_IRQ by iSeries_setup.c */
-void __init iSeries_init_IRQ(void)
+static long Pci_Interrupt_Count;
+static long Pci_Event_Count;
+
+enum XmPciLpEvent_Subtype {
+	XmPciLpEvent_BusCreated		= 0,	// PHB has been created
+	XmPciLpEvent_BusError		= 1,	// PHB has failed
+	XmPciLpEvent_BusFailed		= 2,	// Msg to Secondary, Primary failed bus
+	XmPciLpEvent_NodeFailed		= 4,	// Multi-adapter bridge has failed
+	XmPciLpEvent_NodeRecovered	= 5,	// Multi-adapter bridge has recovered
+	XmPciLpEvent_BusRecovered	= 12,	// PHB has been recovered
+	XmPciLpEvent_UnQuiesceBus	= 18,	// Secondary bus unqiescing
+	XmPciLpEvent_BridgeError	= 21,	// Bridge Error
+	XmPciLpEvent_SlotInterrupt	= 22	// Slot interrupt
+};
+
+struct XmPciLpEvent_BusInterrupt {
+	HvBusNumber	busNumber;
+	HvSubBusNumber	subBusNumber;
+};
+
+struct XmPciLpEvent_NodeInterrupt {
+	HvBusNumber	busNumber;
+	HvSubBusNumber	subBusNumber;
+	HvAgentId	deviceId;
+};
+
+struct XmPciLpEvent {
+	struct HvLpEvent hvLpEvent;
+
+	union {
+		u64 alignData;			// Align on an 8-byte boundary
+
+		struct {
+			u32		fisr;
+			HvBusNumber	busNumber;
+			HvSubBusNumber	subBusNumber;
+			HvAgentId	deviceId;
+		} slotInterrupt;
+
+		struct XmPciLpEvent_BusInterrupt busFailed;
+		struct XmPciLpEvent_BusInterrupt busRecovered;
+		struct XmPciLpEvent_BusInterrupt busCreated;
+
+		struct XmPciLpEvent_NodeInterrupt nodeFailed;
+		struct XmPciLpEvent_NodeInterrupt nodeRecovered;
+
+	} eventData;
+
+};
+
+static void intReceived(struct XmPciLpEvent *eventParm,
+		struct pt_regs *regsParm)
 {
-	/* Register PCI event handler and open an event path */
-	XmPciLpEvent_init();
+	int irq;
+
+	++Pci_Interrupt_Count;
+
+	switch (eventParm->hvLpEvent.xSubtype) {
+	case XmPciLpEvent_SlotInterrupt:
+		irq = eventParm->hvLpEvent.xCorrelationToken;
+		/* Dispatch the interrupt handlers for this irq */
+		ppc_irq_dispatch_handler(regsParm, irq);
+		HvCallPci_eoi(eventParm->eventData.slotInterrupt.busNumber,
+			eventParm->eventData.slotInterrupt.subBusNumber,
+			eventParm->eventData.slotInterrupt.deviceId);
+		break;
+		/* Ignore error recovery events for now */
+	case XmPciLpEvent_BusCreated:
+		printk(KERN_INFO "intReceived: system bus %d created\n",
+			eventParm->eventData.busCreated.busNumber);
+		break;
+	case XmPciLpEvent_BusError:
+	case XmPciLpEvent_BusFailed:
+		printk(KERN_INFO "intReceived: system bus %d failed\n",
+			eventParm->eventData.busFailed.busNumber);
+		break;
+	case XmPciLpEvent_BusRecovered:
+	case XmPciLpEvent_UnQuiesceBus:
+		printk(KERN_INFO "intReceived: system bus %d recovered\n",
+			eventParm->eventData.busRecovered.busNumber);
+		break;
+	case XmPciLpEvent_NodeFailed:
+	case XmPciLpEvent_BridgeError:
+		printk(KERN_INFO
+			"intReceived: multi-adapter bridge %d/%d/%d failed\n",
+			eventParm->eventData.nodeFailed.busNumber,
+			eventParm->eventData.nodeFailed.subBusNumber,
+			eventParm->eventData.nodeFailed.deviceId);
+		break;
+	case XmPciLpEvent_NodeRecovered:
+		printk(KERN_INFO
+			"intReceived: multi-adapter bridge %d/%d/%d recovered\n",
+			eventParm->eventData.nodeRecovered.busNumber,
+			eventParm->eventData.nodeRecovered.subBusNumber,
+			eventParm->eventData.nodeRecovered.deviceId);
+		break;
+	default:
+		printk(KERN_ERR
+			"intReceived: unrecognized event subtype 0x%x\n",
+			eventParm->hvLpEvent.xSubtype);
+		break;
+	}
+}
+
+static void XmPciLpEvent_handler(struct HvLpEvent *eventParm,
+		struct pt_regs *regsParm)
+{
+#ifdef CONFIG_PCI
+	++Pci_Event_Count;
+
+	if (eventParm && (eventParm->xType == HvLpEvent_Type_PciIo)) {
+		switch (eventParm->xFlags.xFunction) {
+		case HvLpEvent_Function_Int:
+			intReceived((struct XmPciLpEvent *)eventParm, regsParm);
+			break;
+		case HvLpEvent_Function_Ack:
+			printk(KERN_ERR
+				"XmPciLpEvent_handler: unexpected ack received\n");
+			break;
+		default:
+			printk(KERN_ERR
+				"XmPciLpEvent_handler: unexpected event function %d\n",
+				(int)eventParm->xFlags.xFunction);
+			break;
+		}
+	} else if (eventParm)
+		printk(KERN_ERR
+			"XmPciLpEvent_handler: Unrecognized PCI event type 0x%x\n",
+			(int)eventParm->xType);
+	else
+		printk(KERN_ERR "XmPciLpEvent_handler: NULL event received\n");
+#endif
 }
 
 /*
- * This is called out of iSeries_scan_slot to allocate an IRQ for an EADS slot
- * It calculates the irq value for the slot.
- * Note that subBusNumber is always 0 (at the moment at least).
+ * This is called by init_IRQ.  set in ppc_md.init_IRQ by iSeries_setup.c
+ * It must be called before the bus walk.
  */
-int __init iSeries_allocate_IRQ(HvBusNumber busNumber,
-		HvSubBusNumber subBusNumber, HvAgentId deviceId)
+void __init iSeries_init_IRQ(void)
 {
-	unsigned int realirq, virtirq;
-	u8 idsel = (deviceId >> 4);
-	u8 function = deviceId & 7;
-
-	virtirq = next_virtual_irq++;
-	realirq = ((busNumber - 1) << 6) + ((idsel - 1) << 3) + function;
-	virt_irq_to_real_map[virtirq] = realirq;
+	/* Register PCI event handler and open an event path */
+	int xRc;
 
-	irq_desc[virtirq].handler = &iSeries_IRQ_handler;
-	return virtirq;
+	xRc = HvLpEvent_registerHandler(HvLpEvent_Type_PciIo,
+			&XmPciLpEvent_handler);
+	if (xRc == 0) {
+		xRc = HvLpEvent_openPath(HvLpEvent_Type_PciIo, 0);
+		if (xRc != 0)
+			printk(KERN_ERR "iSeries_init_IRQ: open event path "
+					"failed with rc 0x%x\n", xRc);
+	} else
+		printk(KERN_ERR "iSeries_init_IRQ: register handler "
+				"failed with rc 0x%x\n", xRc);
 }
 
 #define REAL_IRQ_TO_BUS(irq)	((((irq) >> 6) & 0xff) + 1)
 #define REAL_IRQ_TO_IDSEL(irq)	((((irq) >> 3) & 7) + 1)
 #define REAL_IRQ_TO_FUNC(irq)	((irq) & 7)
 
+/*
+ * This will be called by device drivers (via enable_IRQ)
+ * to enable INTA in the bridge interrupt status register.
+ */
+static void iSeries_enable_IRQ(unsigned int irq)
+{
+	u32 bus, deviceId, function, mask;
+	const u32 subBus = 0;
+	unsigned int rirq = virt_irq_to_real_map[irq];
+
+	/* The IRQ has already been locked by the caller */
+	bus = REAL_IRQ_TO_BUS(rirq);
+	function = REAL_IRQ_TO_FUNC(rirq);
+	deviceId = (REAL_IRQ_TO_IDSEL(rirq) << 4) + function;
+
+	/* Unmask secondary INTA */
+	mask = 0x80000000;
+	HvCallPci_unmaskInterrupts(bus, subBus, deviceId, mask);
+	PPCDBG(PPCDBG_BUSWALK, "iSeries_enable_IRQ 0x%02X.%02X.%02X 0x%04X\n",
+			bus, subBus, deviceId, irq);
+}
+
 /* This is called by iSeries_activate_IRQs */
 static unsigned int iSeries_startup_IRQ(unsigned int irq)
 {
@@ -131,7 +268,7 @@ void __init iSeries_activate_IRQs()
 			desc->handler->startup(irq);
 			spin_unlock_irqrestore(&desc->lock, flags);
 		}
-    	}
+	}
 }
 
 /*  this is not called anywhere currently */
@@ -173,29 +310,7 @@ static void iSeries_disable_IRQ(unsigned
 	mask = 0x80000000;
 	HvCallPci_maskInterrupts(bus, subBus, deviceId, mask);
 	PPCDBG(PPCDBG_BUSWALK, "iSeries_disable_IRQ 0x%02X.%02X.%02X 0x%04X\n",
-	       bus, subBus, deviceId, irq);
-}
-
-/*
- * This will be called by device drivers (via enable_IRQ)
- * to enable INTA in the bridge interrupt status register.
- */
-static void iSeries_enable_IRQ(unsigned int irq)
-{
-	u32 bus, deviceId, function, mask;
-	const u32 subBus = 0;
-	unsigned int rirq = virt_irq_to_real_map[irq];
-
-	/* The IRQ has already been locked by the caller */
-	bus = REAL_IRQ_TO_BUS(rirq);
-	function = REAL_IRQ_TO_FUNC(rirq);
-	deviceId = (REAL_IRQ_TO_IDSEL(rirq) << 4) + function;
-
-	/* Unmask secondary INTA */
-	mask = 0x80000000;
-	HvCallPci_unmaskInterrupts(bus, subBus, deviceId, mask);
-	PPCDBG(PPCDBG_BUSWALK, "iSeries_enable_IRQ 0x%02X.%02X.%02X 0x%04X\n",
-	       bus, subBus, deviceId, irq);
+			bus, subBus, deviceId, irq);
 }
 
 /*
@@ -207,3 +322,32 @@ static void iSeries_enable_IRQ(unsigned 
 static void iSeries_end_IRQ(unsigned int irq)
 {
 }
+
+static hw_irq_controller iSeries_IRQ_handler = {
+	.typename = "iSeries irq controller",
+	.startup = iSeries_startup_IRQ,
+	.shutdown = iSeries_shutdown_IRQ,
+	.enable = iSeries_enable_IRQ,
+	.disable = iSeries_disable_IRQ,
+	.end = iSeries_end_IRQ
+};
+
+/*
+ * This is called out of iSeries_scan_slot to allocate an IRQ for an EADS slot
+ * It calculates the irq value for the slot.
+ * Note that subBusNumber is always 0 (at the moment at least).
+ */
+int __init iSeries_allocate_IRQ(HvBusNumber busNumber,
+		HvSubBusNumber subBusNumber, HvAgentId deviceId)
+{
+	unsigned int realirq, virtirq;
+	u8 idsel = (deviceId >> 4);
+	u8 function = deviceId & 7;
+
+	virtirq = next_virtual_irq++;
+	realirq = ((busNumber - 1) << 6) + ((idsel - 1) << 3) + function;
+	virt_irq_to_real_map[virtirq] = realirq;
+
+	irq_desc[virtirq].handler = &iSeries_IRQ_handler;
+	return virtirq;
+}
diff --git a/arch/ppc64/kernel/iSeries_pci.c b/arch/ppc64/kernel/iSeries_pci.c
--- a/arch/ppc64/kernel/iSeries_pci.c
+++ b/arch/ppc64/kernel/iSeries_pci.c
@@ -38,9 +38,7 @@
 #include <asm/iommu.h>
 
 #include <asm/iSeries/HvCallPci.h>
-#include <asm/iSeries/HvCallSm.h>
 #include <asm/iSeries/HvCallXm.h>
-#include <asm/iSeries/LparData.h>
 #include <asm/iSeries/iSeries_irq.h>
 #include <asm/iSeries/iSeries_pci.h>
 #include <asm/iSeries/mf.h>
@@ -225,10 +223,7 @@ static struct iSeries_Device_Node *build
 	node->DsaAddr.Dsa.busNumber = Bus;
 	node->DsaAddr.Dsa.subBusNumber = SubBus;
 	node->DsaAddr.Dsa.deviceId = 0x10;
-	node->AgentId = AgentId;
 	node->DevFn = PCI_DEVFN(ISERIES_ENCODE_DEVICE(AgentId), Function);
-	node->IoRetry = 0;
-	iSeries_Get_Location_Code(node);
 	return node;
 }
 
@@ -302,7 +297,6 @@ void __init iSeries_pci_final_fixup(void
 {
 	struct pci_dev *pdev = NULL;
 	struct iSeries_Device_Node *node;
-	char Buffer[256];
     	int DeviceCount = 0;
 
 	PPCDBG(PPCDBG_BUSWALK, "iSeries_pcibios_fixup Entry.\n"); 
@@ -324,9 +318,7 @@ void __init iSeries_pci_final_fixup(void
 					"pdev 0x%p <==> DevNode 0x%p\n",
 					pdev, node);
 			allocate_device_bars(pdev);
-			iSeries_Device_Information(pdev, Buffer,
-					sizeof(Buffer));
-			printk("%d. %s\n", DeviceCount, Buffer);
+			iSeries_Device_Information(pdev, DeviceCount);
 			iommu_devnode_init_iSeries(node);
 		} else
 			printk("PCI: Device Tree not found for 0x%016lX\n",
@@ -499,7 +491,6 @@ static int scan_bridge_slot(HvBusNumber 
 
 			++DeviceCount;
 			node = build_device_node(Bus, SubBus, EADsIdSel, Function);
-			node->Vendor = VendorId;
 			node->Irq = Irq;
 			node->LogicalSlot = BridgeInfo->logicalSlotNumber;
 
@@ -661,38 +652,34 @@ static struct pci_ops iSeries_pci_ops = 
  * Check Return Code
  * -> On Failure, print and log information.
  *    Increment Retry Count, if exceeds max, panic partition.
- * -> If in retry, print and log success 
  *
  * PCI: Device 23.90 ReadL I/O Error( 0): 0x1234
  * PCI: Device 23.90 ReadL Retry( 1)
  * PCI: Device 23.90 ReadL Retry Successful(1)
  */
 static int CheckReturnCode(char *TextHdr, struct iSeries_Device_Node *DevNode,
-		u64 ret)
+		int *retry, u64 ret)
 {
 	if (ret != 0)  {
 		++Pci_Error_Count;
-		++DevNode->IoRetry;
+		(*retry)++;
 		printk("PCI: %s: Device 0x%04X:%02X  I/O Error(%2d): 0x%04X\n",
 				TextHdr, DevNode->DsaAddr.Dsa.busNumber, DevNode->DevFn,
-				DevNode->IoRetry, (int)ret);
+				*retry, (int)ret);
 		/*
 		 * Bump the retry and check for retry count exceeded.
 		 * If, Exceeded, panic the system.
 		 */
-		if ((DevNode->IoRetry > Pci_Retry_Max) &&
+		if (((*retry) > Pci_Retry_Max) &&
 				(Pci_Error_Flag > 0)) {
 			mf_display_src(0xB6000103);
-			panic_timeout = 0; 
+			panic_timeout = 0;
 			panic("PCI: Hardware I/O Error, SRC B6000103, "
 					"Automatic Reboot Disabled.\n");
 		}
 		return -1;	/* Retry Try */
 	}
-	/* If retry was in progress, log success and rest retry count */
-	if (DevNode->IoRetry > 0)
-		DevNode->IoRetry = 0;
-	return 0; 
+	return 0;
 }
 
 /*
@@ -738,6 +725,7 @@ u8 iSeries_Read_Byte(const volatile void
 {
 	u64 BarOffset;
 	u64 dsa;
+	int retry = 0;
 	struct HvCallPci_LoadReturn ret;
 	struct iSeries_Device_Node *DevNode =
 		xlate_iomm_address(IoAddress, &dsa, &BarOffset);
@@ -757,7 +745,7 @@ u8 iSeries_Read_Byte(const volatile void
 	do {
 		++Pci_Io_Read_Count;
 		HvCall3Ret16(HvCallPciBarLoad8, &ret, dsa, BarOffset, 0);
-	} while (CheckReturnCode("RDB", DevNode, ret.rc) != 0);
+	} while (CheckReturnCode("RDB", DevNode, &retry, ret.rc) != 0);
 
 	return (u8)ret.value;
 }
@@ -767,6 +755,7 @@ u16 iSeries_Read_Word(const volatile voi
 {
 	u64 BarOffset;
 	u64 dsa;
+	int retry = 0;
 	struct HvCallPci_LoadReturn ret;
 	struct iSeries_Device_Node *DevNode =
 		xlate_iomm_address(IoAddress, &dsa, &BarOffset);
@@ -787,7 +776,7 @@ u16 iSeries_Read_Word(const volatile voi
 		++Pci_Io_Read_Count;
 		HvCall3Ret16(HvCallPciBarLoad16, &ret, dsa,
 				BarOffset, 0);
-	} while (CheckReturnCode("RDW", DevNode, ret.rc) != 0);
+	} while (CheckReturnCode("RDW", DevNode, &retry, ret.rc) != 0);
 
 	return swab16((u16)ret.value);
 }
@@ -797,6 +786,7 @@ u32 iSeries_Read_Long(const volatile voi
 {
 	u64 BarOffset;
 	u64 dsa;
+	int retry = 0;
 	struct HvCallPci_LoadReturn ret;
 	struct iSeries_Device_Node *DevNode =
 		xlate_iomm_address(IoAddress, &dsa, &BarOffset);
@@ -817,7 +807,7 @@ u32 iSeries_Read_Long(const volatile voi
 		++Pci_Io_Read_Count;
 		HvCall3Ret16(HvCallPciBarLoad32, &ret, dsa,
 				BarOffset, 0);
-	} while (CheckReturnCode("RDL", DevNode, ret.rc) != 0);
+	} while (CheckReturnCode("RDL", DevNode, &retry, ret.rc) != 0);
 
 	return swab32((u32)ret.value);
 }
@@ -834,6 +824,7 @@ void iSeries_Write_Byte(u8 data, volatil
 {
 	u64 BarOffset;
 	u64 dsa;
+	int retry = 0;
 	u64 rc;
 	struct iSeries_Device_Node *DevNode =
 		xlate_iomm_address(IoAddress, &dsa, &BarOffset);
@@ -853,7 +844,7 @@ void iSeries_Write_Byte(u8 data, volatil
 	do {
 		++Pci_Io_Write_Count;
 		rc = HvCall4(HvCallPciBarStore8, dsa, BarOffset, data, 0);
-	} while (CheckReturnCode("WWB", DevNode, rc) != 0);
+	} while (CheckReturnCode("WWB", DevNode, &retry, rc) != 0);
 }
 EXPORT_SYMBOL(iSeries_Write_Byte);
 
@@ -861,6 +852,7 @@ void iSeries_Write_Word(u16 data, volati
 {
 	u64 BarOffset;
 	u64 dsa;
+	int retry = 0;
 	u64 rc;
 	struct iSeries_Device_Node *DevNode =
 		xlate_iomm_address(IoAddress, &dsa, &BarOffset);
@@ -880,7 +872,7 @@ void iSeries_Write_Word(u16 data, volati
 	do {
 		++Pci_Io_Write_Count;
 		rc = HvCall4(HvCallPciBarStore16, dsa, BarOffset, swab16(data), 0);
-	} while (CheckReturnCode("WWW", DevNode, rc) != 0);
+	} while (CheckReturnCode("WWW", DevNode, &retry, rc) != 0);
 }
 EXPORT_SYMBOL(iSeries_Write_Word);
 
@@ -888,6 +880,7 @@ void iSeries_Write_Long(u32 data, volati
 {
 	u64 BarOffset;
 	u64 dsa;
+	int retry = 0;
 	u64 rc;
 	struct iSeries_Device_Node *DevNode =
 		xlate_iomm_address(IoAddress, &dsa, &BarOffset);
@@ -907,6 +900,6 @@ void iSeries_Write_Long(u32 data, volati
 	do {
 		++Pci_Io_Write_Count;
 		rc = HvCall4(HvCallPciBarStore32, dsa, BarOffset, swab32(data), 0);
-	} while (CheckReturnCode("WWL", DevNode, rc) != 0);
+	} while (CheckReturnCode("WWL", DevNode, &retry, rc) != 0);
 }
 EXPORT_SYMBOL(iSeries_Write_Long);
diff --git a/arch/ppc64/kernel/iSeries_pci_reset.c b/arch/ppc64/kernel/iSeries_pci_reset.c
deleted file mode 100644
--- a/arch/ppc64/kernel/iSeries_pci_reset.c
+++ /dev/null
@@ -1,104 +0,0 @@
-#define PCIFR(...)
-/************************************************************************/
-/* File iSeries_pci_reset.c created by Allan Trautman on Mar 21 2001.   */
-/************************************************************************/
-/* This code supports the pci interface on the IBM iSeries systems.     */
-/* Copyright (C) 20yy  <Allan H Trautman> <IBM Corp>                    */
-/*                                                                      */
-/* This program is free software; you can redistribute it and/or modify */
-/* it under the terms of the GNU General Public License as published by */
-/* the Free Software Foundation; either version 2 of the License, or    */
-/* (at your option) any later version.                                  */
-/*                                                                      */
-/* 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 Activity:                                                     */
-/*   Created, March 20, 2001                                            */
-/*   April 30, 2001, Added return codes on functions.                   */
-/*   September 10, 2001, Ported to ppc64.                               */
-/* End Change Activity                                                  */
-/************************************************************************/
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/irq.h>
-#include <linux/delay.h>
-
-#include <asm/io.h>
-#include <asm/iSeries/HvCallPci.h>
-#include <asm/iSeries/HvTypes.h>
-#include <asm/iSeries/mf.h>
-#include <asm/pci.h>
-
-#include <asm/iSeries/iSeries_pci.h>
-#include "pci.h"
-
-/*
- * Interface to toggle the reset line
- * Time is in .1 seconds, need for seconds.
- */
-int iSeries_Device_ToggleReset(struct pci_dev *PciDev, int AssertTime,
-		int DelayTime)
-{
-	unsigned int AssertDelay, WaitDelay;
-	struct iSeries_Device_Node *DeviceNode =
-		(struct iSeries_Device_Node *)PciDev->sysdata;
-
- 	if (DeviceNode == NULL) { 
-		printk("PCI: Pci Reset Failed, Device Node not found for pci_dev %p\n",
-				PciDev);
-		return -1;
-	}
-	/*
-	 * Set defaults, Assert is .5 second, Wait is 3 seconds.
-	 */
-	if (AssertTime == 0)
-		AssertDelay = 500;
-	else
-		AssertDelay = AssertTime * 100;
-
-	if (DelayTime == 0)
-		WaitDelay = 3000;
-	else
-		WaitDelay = DelayTime * 100;
-
-	/*
-	 * Assert reset
-	 */
-	DeviceNode->ReturnCode = HvCallPci_setSlotReset(ISERIES_BUS(DeviceNode),
-			0x00, DeviceNode->AgentId, 1);
-	if (DeviceNode->ReturnCode == 0) {
-		msleep(AssertDelay);			/* Sleep for the time */
-		DeviceNode->ReturnCode =
-			HvCallPci_setSlotReset(ISERIES_BUS(DeviceNode),
-					0x00, DeviceNode->AgentId, 0);
-
-		/*
-   		 * Wait for device to reset
-		 */
-		msleep(WaitDelay);
-	}
-	if (DeviceNode->ReturnCode == 0)
-		PCIFR("Slot 0x%04X.%02 Reset\n", ISERIES_BUS(DeviceNode),
-				DeviceNode->AgentId);
-	else {
-		printk("PCI: Slot 0x%04X.%02X Reset Failed, RCode: %04X\n",
-				ISERIES_BUS(DeviceNode), DeviceNode->AgentId,
-				DeviceNode->ReturnCode);
-		PCIFR("Slot 0x%04X.%02X Reset Failed, RCode: %04X\n",
-				ISERIES_BUS(DeviceNode), DeviceNode->AgentId,
-				DeviceNode->ReturnCode);
-	}
-	return DeviceNode->ReturnCode;
-}
-EXPORT_SYMBOL(iSeries_Device_ToggleReset);
diff --git a/arch/ppc64/kernel/iSeries_proc.c b/arch/ppc64/kernel/iSeries_proc.c
--- a/arch/ppc64/kernel/iSeries_proc.c
+++ b/arch/ppc64/kernel/iSeries_proc.c
@@ -28,8 +28,7 @@
 #include <asm/iSeries/ItLpQueue.h>
 #include <asm/iSeries/HvCallXm.h>
 #include <asm/iSeries/IoHriMainStore.h>
-#include <asm/iSeries/LparData.h>
-#include <asm/iSeries/iSeries_proc.h>
+#include <asm/iSeries/IoHriProcessorVpd.h>
 
 static int __init iseries_proc_create(void)
 {
@@ -41,50 +40,6 @@ static int __init iseries_proc_create(vo
 }
 core_initcall(iseries_proc_create);
 
-static char *event_types[9] = {
-	"Hypervisor\t\t",
-	"Machine Facilities\t",
-	"Session Manager\t",
-	"SPD I/O\t\t",
-	"Virtual Bus\t\t",
-	"PCI I/O\t\t",
-	"RIO I/O\t\t",
-	"Virtual Lan\t\t",
-	"Virtual I/O\t\t"
-};
-
-static int proc_lpevents_show(struct seq_file *m, void *v)
-{
-	unsigned int i;
-
-	seq_printf(m, "LpEventQueue 0\n");
-	seq_printf(m, "  events processed:\t%lu\n",
-		   (unsigned long)xItLpQueue.xLpIntCount);
-
-	for (i = 0; i < 9; ++i)
-		seq_printf(m, "    %s %10lu\n", event_types[i],
-			   (unsigned long)xItLpQueue.xLpIntCountByType[i]);
-
-	seq_printf(m, "\n  events processed by processor:\n");
-
-	for_each_online_cpu(i)
-		seq_printf(m, "    CPU%02d  %10u\n", i, paca[i].lpevent_count);
-
-	return 0;
-}
-
-static int proc_lpevents_open(struct inode *inode, struct file *file)
-{
-	return single_open(file, proc_lpevents_show, NULL);
-}
-
-static struct file_operations proc_lpevents_operations = {
-	.open		= proc_lpevents_open,
-	.read		= seq_read,
-	.llseek		= seq_lseek,
-	.release	= single_release,
-};
-
 static unsigned long startTitan = 0;
 static unsigned long startTb = 0;
 
@@ -149,10 +104,6 @@ static int __init iseries_proc_init(void
 {
 	struct proc_dir_entry *e;
 
-	e = create_proc_entry("iSeries/lpevents", S_IFREG|S_IRUGO, NULL);
-	if (e)
-		e->proc_fops = &proc_lpevents_operations;
-
 	e = create_proc_entry("iSeries/titanTod", S_IFREG|S_IRUGO, NULL);
 	if (e)
 		e->proc_fops = &proc_titantod_operations;
diff --git a/arch/ppc64/kernel/iSeries_setup.c b/arch/ppc64/kernel/iSeries_setup.c
--- a/arch/ppc64/kernel/iSeries_setup.c
+++ b/arch/ppc64/kernel/iSeries_setup.c
@@ -24,7 +24,6 @@
 #include <linux/smp.h>
 #include <linux/param.h>
 #include <linux/string.h>
-#include <linux/bootmem.h>
 #include <linux/initrd.h>
 #include <linux/seq_file.h>
 #include <linux/kdev_t.h>
@@ -47,7 +46,7 @@
 #include <asm/paca.h>
 #include <asm/cache.h>
 #include <asm/sections.h>
-#include <asm/iSeries/LparData.h>
+#include <asm/abs_addr.h>
 #include <asm/iSeries/HvCallHpt.h>
 #include <asm/iSeries/HvLpConfig.h>
 #include <asm/iSeries/HvCallEvent.h>
@@ -55,10 +54,12 @@
 #include <asm/iSeries/HvCallXm.h>
 #include <asm/iSeries/ItLpQueue.h>
 #include <asm/iSeries/IoHriMainStore.h>
-#include <asm/iSeries/iSeries_proc.h>
 #include <asm/iSeries/mf.h>
 #include <asm/iSeries/HvLpEvent.h>
 #include <asm/iSeries/iSeries_irq.h>
+#include <asm/iSeries/IoHriProcessorVpd.h>
+#include <asm/iSeries/ItVpdAreas.h>
+#include <asm/iSeries/LparMap.h>
 
 extern void hvlog(char *fmt, ...);
 
@@ -74,7 +75,11 @@ extern void ppcdbg_initialize(void);
 static void build_iSeries_Memory_Map(void);
 static void setup_iSeries_cache_sizes(void);
 static void iSeries_bolt_kernel(unsigned long saddr, unsigned long eaddr);
+#ifdef CONFIG_PCI
 extern void iSeries_pci_final_fixup(void);
+#else
+static void iSeries_pci_final_fixup(void) { }
+#endif
 
 /* Global Variables */
 static unsigned long procFreqHz;
@@ -498,7 +503,7 @@ static void __init build_iSeries_Memory_
 
 	/* Fill in the hashed page table hash mask */
 	num_ptegs = hptSizePages *
-		(PAGE_SIZE / (sizeof(HPTE) * HPTES_PER_GROUP));
+		(PAGE_SIZE / (sizeof(hpte_t) * HPTES_PER_GROUP));
 	htab_hash_mask = num_ptegs - 1;
 
 	/*
@@ -613,25 +618,23 @@ static void __init setup_iSeries_cache_s
 static void iSeries_make_pte(unsigned long va, unsigned long pa,
 			     int mode)
 {
-	HPTE local_hpte, rhpte;
+	hpte_t local_hpte, rhpte;
 	unsigned long hash, vpn;
 	long slot;
 
 	vpn = va >> PAGE_SHIFT;
 	hash = hpt_hash(vpn, 0);
 
-	local_hpte.dw1.dword1 = pa | mode;
-	local_hpte.dw0.dword0 = 0;
-	local_hpte.dw0.dw0.avpn = va >> 23;
-	local_hpte.dw0.dw0.bolted = 1;		/* bolted */
-	local_hpte.dw0.dw0.v = 1;
+	local_hpte.r = pa | mode;
+	local_hpte.v = ((va >> 23) << HPTE_V_AVPN_SHIFT)
+		| HPTE_V_BOLTED | HPTE_V_VALID;
 
 	slot = HvCallHpt_findValid(&rhpte, vpn);
 	if (slot < 0) {
 		/* Must find space in primary group */
 		panic("hash_page: hpte already exists\n");
 	}
-	HvCallHpt_addValidate(slot, 0, (HPTE *)&local_hpte );
+	HvCallHpt_addValidate(slot, 0, &local_hpte);
 }
 
 /*
@@ -641,7 +644,7 @@ static void __init iSeries_bolt_kernel(u
 {
 	unsigned long pa;
 	unsigned long mode_rw = _PAGE_ACCESSED | _PAGE_COHERENT | PP_RWXX;
-	HPTE hpte;
+	hpte_t hpte;
 
 	for (pa = saddr; pa < eaddr ;pa += PAGE_SIZE) {
 		unsigned long ea = (unsigned long)__va(pa);
@@ -654,7 +657,7 @@ static void __init iSeries_bolt_kernel(u
 		if (!in_kernel_text(ea))
 			mode_rw |= HW_NO_EXEC;
 
-		if (hpte.dw0.dw0.v) {
+		if (hpte.v & HPTE_V_VALID) {
 			/* HPTE exists, so just bolt it */
 			HvCallHpt_setSwBits(slot, 0x10, 0);
 			/* And make sure the pp bits are correct */
@@ -665,15 +668,11 @@ static void __init iSeries_bolt_kernel(u
 	}
 }
 
-extern unsigned long ppc_proc_freq;
-extern unsigned long ppc_tb_freq;
-
 /*
  * Document me.
  */
 static void __init iSeries_setup_arch(void)
 {
-	void *eventStack;
 	unsigned procIx = get_paca()->lppaca.dyn_hv_phys_proc_index;
 
 	/* Add an eye catcher and the systemcfg layout version number */
@@ -682,24 +681,7 @@ static void __init iSeries_setup_arch(vo
 	systemcfg->version.minor = SYSTEMCFG_MINOR;
 
 	/* Setup the Lp Event Queue */
-
-	/* Allocate a page for the Event Stack
-	 * The hypervisor wants the absolute real address, so
-	 * we subtract out the KERNELBASE and add in the
-	 * absolute real address of the kernel load area
-	 */
-	eventStack = alloc_bootmem_pages(LpEventStackSize);
-	memset(eventStack, 0, LpEventStackSize);
-
-	/* Invoke the hypervisor to initialize the event stack */
-	HvCallEvent_setLpEventStack(0, eventStack, LpEventStackSize);
-
-	/* Initialize fields in our Lp Event Queue */
-	xItLpQueue.xSlicEventStackPtr = (char *)eventStack;
-	xItLpQueue.xSlicCurEventPtr = (char *)eventStack;
-	xItLpQueue.xSlicLastValidEventPtr = (char *)eventStack +
-					(LpEventStackSize - LpEventMaxSize);
-	xItLpQueue.xIndex = 0;
+	setup_hvlpevent_queue();
 
 	/* Compute processor frequency */
 	procFreqHz = ((1UL << 34) * 1000000) /
@@ -766,8 +748,6 @@ static void iSeries_halt(void)
 	mf_power_off();
 }
 
-extern void setup_default_decr(void);
-
 /*
  * void __init iSeries_calibrate_decr()
  *
@@ -852,27 +832,95 @@ static int __init iSeries_src_init(void)
 
 late_initcall(iSeries_src_init);
 
-static int set_spread_lpevents(char *str)
+static inline void process_iSeries_events(void)
 {
-	unsigned long i;
-	unsigned long val = simple_strtoul(str, NULL, 0);
+	asm volatile ("li 0,0x5555; sc" : : : "r0", "r3");
+}
+
+static void yield_shared_processor(void)
+{
+	unsigned long tb;
+
+	HvCall_setEnabledInterrupts(HvCall_MaskIPI |
+				    HvCall_MaskLpEvent |
+				    HvCall_MaskLpProd |
+				    HvCall_MaskTimeout);
+
+	tb = get_tb();
+	/* Compute future tb value when yield should expire */
+	HvCall_yieldProcessor(HvCall_YieldTimed, tb+tb_ticks_per_jiffy);
 
 	/*
-	 * The parameter is the number of processors to share in processing
-	 * lp events.
+	 * The decrementer stops during the yield.  Force a fake decrementer
+	 * here and let the timer_interrupt code sort out the actual time.
 	 */
-	if (( val > 0) && (val <= NR_CPUS)) {
-		for (i = 1; i < val; ++i)
-			paca[i].lpqueue_ptr = paca[0].lpqueue_ptr;
+	get_paca()->lppaca.int_dword.fields.decr_int = 1;
+	process_iSeries_events();
+}
 
-		printk("lpevent processing spread over %ld processors\n", val);
-	} else {
-		printk("invalid spread_lpevents %ld\n", val);
+static int iseries_shared_idle(void)
+{
+	while (1) {
+		while (!need_resched() && !hvlpevent_is_pending()) {
+			local_irq_disable();
+			ppc64_runlatch_off();
+
+			/* Recheck with irqs off */
+			if (!need_resched() && !hvlpevent_is_pending())
+				yield_shared_processor();
+
+			HMT_medium();
+			local_irq_enable();
+		}
+
+		ppc64_runlatch_on();
+
+		if (hvlpevent_is_pending())
+			process_iSeries_events();
+
+		schedule();
 	}
 
-	return 1;
+	return 0;
 }
-__setup("spread_lpevents=", set_spread_lpevents);
+
+static int iseries_dedicated_idle(void)
+{
+	long oldval;
+
+	while (1) {
+		oldval = test_and_clear_thread_flag(TIF_NEED_RESCHED);
+
+		if (!oldval) {
+			set_thread_flag(TIF_POLLING_NRFLAG);
+
+			while (!need_resched()) {
+				ppc64_runlatch_off();
+				HMT_low();
+
+				if (hvlpevent_is_pending()) {
+					HMT_medium();
+					ppc64_runlatch_on();
+					process_iSeries_events();
+				}
+			}
+
+			HMT_medium();
+			clear_thread_flag(TIF_POLLING_NRFLAG);
+		} else {
+			set_need_resched();
+		}
+
+		ppc64_runlatch_on();
+		schedule();
+	}
+
+	return 0;
+}
+
+#ifndef CONFIG_PCI
+void __init iSeries_init_IRQ(void) { }
+#endif
 
 void __init iSeries_early_setup(void)
 {
@@ -895,5 +943,13 @@ void __init iSeries_early_setup(void)
 	ppc_md.get_rtc_time = iSeries_get_rtc_time;
 	ppc_md.calibrate_decr = iSeries_calibrate_decr;
 	ppc_md.progress = iSeries_progress;
+
+	if (get_paca()->lppaca.shared_proc) {
+		ppc_md.idle_loop = iseries_shared_idle;
+		printk(KERN_INFO "Using shared processor idle loop\n");
+	} else {
+		ppc_md.idle_loop = iseries_dedicated_idle;
+		printk(KERN_INFO "Using dedicated idle loop\n");
+	}
 }
 
diff --git a/arch/ppc64/kernel/iSeries_smp.c b/arch/ppc64/kernel/iSeries_smp.c
--- a/arch/ppc64/kernel/iSeries_smp.c
+++ b/arch/ppc64/kernel/iSeries_smp.c
@@ -38,9 +38,7 @@
 #include <asm/io.h>
 #include <asm/smp.h>
 #include <asm/paca.h>
-#include <asm/iSeries/LparData.h>
 #include <asm/iSeries/HvCall.h>
-#include <asm/iSeries/HvCallCfg.h>
 #include <asm/time.h>
 #include <asm/ppcdebug.h>
 #include <asm/machdep.h>
diff --git a/arch/ppc64/kernel/idle.c b/arch/ppc64/kernel/idle.c
--- a/arch/ppc64/kernel/idle.c
+++ b/arch/ppc64/kernel/idle.c
@@ -20,104 +20,18 @@
 #include <linux/kernel.h>
 #include <linux/smp.h>
 #include <linux/cpu.h>
-#include <linux/module.h>
 #include <linux/sysctl.h>
-#include <linux/smp.h>
 
 #include <asm/system.h>
 #include <asm/processor.h>
-#include <asm/mmu.h>
 #include <asm/cputable.h>
 #include <asm/time.h>
-#include <asm/iSeries/HvCall.h>
-#include <asm/iSeries/ItLpQueue.h>
-#include <asm/plpar_wrappers.h>
 #include <asm/systemcfg.h>
+#include <asm/machdep.h>
 
 extern void power4_idle(void);
 
-static int (*idle_loop)(void);
-
-#ifdef CONFIG_PPC_ISERIES
-static unsigned long maxYieldTime = 0;
-static unsigned long minYieldTime = 0xffffffffffffffffUL;
-
-static void yield_shared_processor(void)
-{
-	unsigned long tb;
-	unsigned long yieldTime;
-
-	HvCall_setEnabledInterrupts(HvCall_MaskIPI |
-				    HvCall_MaskLpEvent |
-				    HvCall_MaskLpProd |
-				    HvCall_MaskTimeout);
-
-	tb = get_tb();
-	/* Compute future tb value when yield should expire */
-	HvCall_yieldProcessor(HvCall_YieldTimed, tb+tb_ticks_per_jiffy);
-
-	yieldTime = get_tb() - tb;
-	if (yieldTime > maxYieldTime)
-		maxYieldTime = yieldTime;
-
-	if (yieldTime < minYieldTime)
-		minYieldTime = yieldTime;
-	
-	/*
-	 * The decrementer stops during the yield.  Force a fake decrementer
-	 * here and let the timer_interrupt code sort out the actual time.
-	 */
-	get_paca()->lppaca.int_dword.fields.decr_int = 1;
-	process_iSeries_events();
-}
-
-static int iSeries_idle(void)
-{
-	struct paca_struct *lpaca;
-	long oldval;
-
-	/* ensure iSeries run light will be out when idle */
-	ppc64_runlatch_off();
-
-	lpaca = get_paca();
-
-	while (1) {
-		if (lpaca->lppaca.shared_proc) {
-			if (ItLpQueue_isLpIntPending(lpaca->lpqueue_ptr))
-				process_iSeries_events();
-			if (!need_resched())
-				yield_shared_processor();
-		} else {
-			oldval = test_and_clear_thread_flag(TIF_NEED_RESCHED);
-
-			if (!oldval) {
-				set_thread_flag(TIF_POLLING_NRFLAG);
-
-				while (!need_resched()) {
-					HMT_medium();
-					if (ItLpQueue_isLpIntPending(lpaca->lpqueue_ptr))
-						process_iSeries_events();
-					HMT_low();
-				}
-
-				HMT_medium();
-				clear_thread_flag(TIF_POLLING_NRFLAG);
-			} else {
-				set_need_resched();
-			}
-		}
-
-		ppc64_runlatch_on();
-		schedule();
-		ppc64_runlatch_off();
-	}
-
-	return 0;
-}
-
-#else
-
-static int default_idle(void)
+int default_idle(void)
 {
 	long oldval;
 	unsigned int cpu = smp_processor_id();
@@ -129,7 +43,8 @@ static int default_idle(void)
 			set_thread_flag(TIF_POLLING_NRFLAG);
 
 			while (!need_resched() && !cpu_is_offline(cpu)) {
-				barrier();
+				ppc64_runlatch_off();
+
 				/*
 				 * Go into low thread priority and possibly
 				 * low power mode.
@@ -144,6 +59,7 @@ static int default_idle(void)
 			set_need_resched();
 		}
 
+		ppc64_runlatch_on();
 		schedule();
 		if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING)
 			cpu_die();
@@ -152,127 +68,19 @@ static int default_idle(void)
 	return 0;
 }
 
-#ifdef CONFIG_PPC_PSERIES
-
-DECLARE_PER_CPU(unsigned long, smt_snooze_delay);
-
-int dedicated_idle(void)
+int native_idle(void)
 {
-	long oldval;
-	struct paca_struct *lpaca = get_paca(), *ppaca;
-	unsigned long start_snooze;
-	unsigned long *smt_snooze_delay = &__get_cpu_var(smt_snooze_delay);
-	unsigned int cpu = smp_processor_id();
-
-	ppaca = &paca[cpu ^ 1];
-
 	while (1) {
-		/*
-		 * Indicate to the HV that we are idle. Now would be
-		 * a good time to find other work to dispatch.
-		 */
-		lpaca->lppaca.idle = 1;
-
-		oldval = test_and_clear_thread_flag(TIF_NEED_RESCHED);
-		if (!oldval) {
-			set_thread_flag(TIF_POLLING_NRFLAG);
-			start_snooze = __get_tb() +
-				*smt_snooze_delay * tb_ticks_per_usec;
-			while (!need_resched() && !cpu_is_offline(cpu)) {
-				/*
-				 * Go into low thread priority and possibly
-				 * low power mode.
-				 */
-				HMT_low();
-				HMT_very_low();
-
-				if (*smt_snooze_delay == 0 ||
-				    __get_tb() < start_snooze)
-					continue;
-
-				HMT_medium();
-
-				if (!(ppaca->lppaca.idle)) {
-					local_irq_disable();
-
-					/*
-					 * We are about to sleep the thread
-					 * and so wont be polling any
-					 * more.
-					 */
-					clear_thread_flag(TIF_POLLING_NRFLAG);
-
-					/*
-					 * SMT dynamic mode. Cede will result
-					 * in this thread going dormant, if the
-					 * partner thread is still doing work.
-					 * Thread wakes up if partner goes idle,
-					 * an interrupt is presented, or a prod
-					 * occurs.  Returning from the cede
-					 * enables external interrupts.
-					 */
-					if (!need_resched())
-						cede_processor();
-					else
-						local_irq_enable();
-				} else {
-					/*
-					 * Give the HV an opportunity at the
-					 * processor, since we are not doing
-					 * any work.
-					 */
-					poll_pending();
-				}
-			}
-
-			clear_thread_flag(TIF_POLLING_NRFLAG);
-		} else {
-			set_need_resched();
-		}
-
-		HMT_medium();
-		lpaca->lppaca.idle = 0;
-		schedule();
-		if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING)
-			cpu_die();
-	}
-	return 0;
-}
+		ppc64_runlatch_off();
 
-static int shared_idle(void)
-{
-	struct paca_struct *lpaca = get_paca();
-	unsigned int cpu = smp_processor_id();
+		if (!need_resched())
+			power4_idle();
 
-	while (1) {
-		/*
-		 * Indicate to the HV that we are idle. Now would be
-		 * a good time to find other work to dispatch.
-		 */
-		lpaca->lppaca.idle = 1;
-
-		while (!need_resched() && !cpu_is_offline(cpu)) {
-			local_irq_disable();
-
-			/*
-			 * Yield the processor to the hypervisor.  We return if
-			 * an external interrupt occurs (which are driven prior
-			 * to returning here) or if a prod occurs from another 
-			 * processor. When returning here, external interrupts
-			 * are enabled.
-			 *
-			 * Check need_resched() again with interrupts disabled
-			 * to avoid a race.
-			 */
-			if (!need_resched())
-				cede_processor();
-			else
-				local_irq_enable();
+		if (need_resched()) {
+			ppc64_runlatch_on();
+			schedule();
 		}
 
-		HMT_medium();
-		lpaca->lppaca.idle = 0;
-		schedule();
 		if (cpu_is_offline(smp_processor_id()) &&
 		    system_state == SYSTEM_RUNNING)
 			cpu_die();
@@ -281,29 +89,10 @@ static int shared_idle(void)
 	return 0;
 }
 
-#endif /* CONFIG_PPC_PSERIES */
-
-static int native_idle(void)
-{
-	while(1) {
-		/* check CPU type here */
-		if (!need_resched())
-			power4_idle();
-		if (need_resched())
-			schedule();
-
-		if (cpu_is_offline(_smp_processor_id()) &&
-		    system_state == SYSTEM_RUNNING)
-			cpu_die();
-	}
-	return 0;
-}
-
-#endif /* CONFIG_PPC_ISERIES */
-
 void cpu_idle(void)
 {
-	idle_loop();
+	BUG_ON(NULL == ppc_md.idle_loop);
+	ppc_md.idle_loop();
 }
 
 int powersave_nap;
@@ -337,42 +126,3 @@ register_powersave_nap_sysctl(void)
 }
 __initcall(register_powersave_nap_sysctl);
 #endif
-
-int idle_setup(void)
-{
-	/*
-	 * Move that junk to each platform specific file, eventually define
-	 * a pSeries_idle for shared processor stuff
-	 */
-#ifdef CONFIG_PPC_ISERIES
-	idle_loop = iSeries_idle;
-	return 1;
-#else
-	idle_loop = default_idle;
-#endif
-#ifdef CONFIG_PPC_PSERIES
-	if (systemcfg->platform & PLATFORM_PSERIES) {
-		if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR) {
-			if (get_paca()->lppaca.shared_proc) {
-				printk(KERN_INFO "Using shared processor idle loop\n");
-				idle_loop = shared_idle;
-			} else {
-				printk(KERN_INFO "Using dedicated idle loop\n");
-				idle_loop = dedicated_idle;
-			}
-		} else {
-			printk(KERN_INFO "Using default idle loop\n");
-			idle_loop = default_idle;
-		}
-	}
-#endif /* CONFIG_PPC_PSERIES */
-#ifndef CONFIG_PPC_ISERIES
-	if (systemcfg->platform == PLATFORM_POWERMAC ||
-	    systemcfg->platform == PLATFORM_MAPLE) {
-		printk(KERN_INFO "Using native/NAP idle loop\n");
-		idle_loop = native_idle;
-	}
-#endif /* CONFIG_PPC_ISERIES */
-
-	return 1;
-}
diff --git a/arch/ppc64/kernel/iommu.c b/arch/ppc64/kernel/iommu.c
--- a/arch/ppc64/kernel/iommu.c
+++ b/arch/ppc64/kernel/iommu.c
@@ -242,7 +242,7 @@ int iommu_map_sg(struct device *dev, str
 	dma_addr_t dma_next = 0, dma_addr;
 	unsigned long flags;
 	struct scatterlist *s, *outs, *segstart;
-	int outcount;
+	int outcount, incount;
 	unsigned long handle;
 
 	BUG_ON(direction == DMA_NONE);
@@ -252,6 +252,7 @@ int iommu_map_sg(struct device *dev, str
 
 	outs = s = segstart = &sglist[0];
 	outcount = 1;
+	incount = nelems;
 	handle = 0;
 
 	/* Init first segment length for backout at failure */
@@ -338,10 +339,10 @@ int iommu_map_sg(struct device *dev, str
 
 	DBG("mapped %d elements:\n", outcount);
 
-	/* For the sake of iommu_free_sg, we clear out the length in the
+	/* For the sake of iommu_unmap_sg, we clear out the length in the
 	 * next entry of the sglist if we didn't fill the list completely
 	 */
-	if (outcount < nelems) {
+	if (outcount < incount) {
 		outs++;
 		outs->dma_address = DMA_ERROR_CODE;
 		outs->dma_length = 0;
@@ -423,6 +424,9 @@ struct iommu_table *iommu_init_table(str
 	tbl->it_largehint = tbl->it_halfpoint;
 	spin_lock_init(&tbl->it_lock);
 
+	/* Clear the hardware table in case firmware left allocations in it */
+	ppc_md.tce_free(tbl, tbl->it_offset, tbl->it_size);
+
 	if (!welcomed) {
 		printk(KERN_INFO "IOMMU table initialized, virtual merging %s\n",
 		       novmerge ? "disabled" : "enabled");
diff --git a/arch/ppc64/kernel/irq.c b/arch/ppc64/kernel/irq.c
--- a/arch/ppc64/kernel/irq.c
+++ b/arch/ppc64/kernel/irq.c
@@ -52,7 +52,7 @@
 #include <asm/cache.h>
 #include <asm/prom.h>
 #include <asm/ptrace.h>
-#include <asm/iSeries/LparData.h>
+#include <asm/iSeries/ItLpQueue.h>
 #include <asm/machdep.h>
 #include <asm/paca.h>
 
@@ -66,7 +66,6 @@ EXPORT_SYMBOL(irq_desc);
 int distribute_irqs = 1;
 int __irq_offset_value;
 int ppc_spurious_interrupts;
-unsigned long lpevent_count;
 u64 ppc64_interrupt_controller;
 
 int show_interrupts(struct seq_file *p, void *v)
@@ -245,7 +244,7 @@ void ppc_irq_dispatch_handler(struct pt_
 
 		spin_lock(&desc->lock);
 		if (!noirqdebug)
-			note_interrupt(irq, desc, action_ret);
+			note_interrupt(irq, desc, action_ret, regs);
 		if (likely(!(desc->status & IRQ_PENDING)))
 			break;
 		desc->status &= ~IRQ_PENDING;
@@ -269,7 +268,6 @@ out:
 void do_IRQ(struct pt_regs *regs)
 {
 	struct paca_struct *lpaca;
-	struct ItLpQueue *lpq;
 
 	irq_enter();
 
@@ -295,9 +293,8 @@ void do_IRQ(struct pt_regs *regs)
 		iSeries_smp_message_recv(regs);
 	}
 #endif /* CONFIG_SMP */
-	lpq = lpaca->lpqueue_ptr;
-	if (lpq && ItLpQueue_isLpIntPending(lpq))
-		lpevent_count += ItLpQueue_process(lpq, regs);
+	if (hvlpevent_is_pending())
+		process_hvlpevents(regs);
 
 	irq_exit();
 
@@ -395,6 +392,9 @@ int virt_irq_create_mapping(unsigned int
 	if (ppc64_interrupt_controller == IC_OPEN_PIC)
 		return real_irq;	/* no mapping for openpic (for now) */
 
+	if (ppc64_interrupt_controller == IC_BPA_IIC)
+		return real_irq;	/* no mapping for iic either */
+
 	/* don't map interrupts < MIN_VIRT_IRQ */
 	if (real_irq < MIN_VIRT_IRQ) {
 		virt_irq_to_real_map[real_irq] = real_irq;
diff --git a/arch/ppc64/kernel/kprobes.c b/arch/ppc64/kernel/kprobes.c
--- a/arch/ppc64/kernel/kprobes.c
+++ b/arch/ppc64/kernel/kprobes.c
@@ -32,15 +32,16 @@
 #include <linux/ptrace.h>
 #include <linux/spinlock.h>
 #include <linux/preempt.h>
+#include <asm/cacheflush.h>
 #include <asm/kdebug.h>
 #include <asm/sstep.h>
 
-/* kprobe_status settings */
-#define KPROBE_HIT_ACTIVE	0x00000001
-#define KPROBE_HIT_SS		0x00000002
+static DECLARE_MUTEX(kprobe_mutex);
 
 static struct kprobe *current_kprobe;
 static unsigned long kprobe_status, kprobe_saved_msr;
+static struct kprobe *kprobe_prev;
+static unsigned long kprobe_status_prev, kprobe_saved_msr_prev;
 static struct pt_regs jprobe_saved_regs;
 
 int arch_prepare_kprobe(struct kprobe *p)
@@ -55,32 +56,87 @@ int arch_prepare_kprobe(struct kprobe *p
 		printk("Cannot register a kprobe on rfid or mtmsrd\n");
 		ret = -EINVAL;
 	}
+
+	/* insn must be on a special executable page on ppc64 */
+	if (!ret) {
+		up(&kprobe_mutex);
+		p->ainsn.insn = get_insn_slot();
+		down(&kprobe_mutex);
+		if (!p->ainsn.insn)
+			ret = -ENOMEM;
+	}
 	return ret;
 }
 
 void arch_copy_kprobe(struct kprobe *p)
 {
 	memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
+	p->opcode = *p->addr;
 }
 
-void arch_remove_kprobe(struct kprobe *p)
+void arch_arm_kprobe(struct kprobe *p)
 {
+	*p->addr = BREAKPOINT_INSTRUCTION;
+	flush_icache_range((unsigned long) p->addr,
+			   (unsigned long) p->addr + sizeof(kprobe_opcode_t));
 }
 
-static inline void disarm_kprobe(struct kprobe *p, struct pt_regs *regs)
+void arch_disarm_kprobe(struct kprobe *p)
 {
 	*p->addr = p->opcode;
-	regs->nip = (unsigned long)p->addr;
+	flush_icache_range((unsigned long) p->addr,
+			   (unsigned long) p->addr + sizeof(kprobe_opcode_t));
+}
+
+void arch_remove_kprobe(struct kprobe *p)
+{
+	up(&kprobe_mutex);
+	free_insn_slot(p->ainsn.insn);
+	down(&kprobe_mutex);
 }
 
 static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
 {
+	kprobe_opcode_t insn = *p->ainsn.insn;
+
 	regs->msr |= MSR_SE;
-	/*single step inline if it a breakpoint instruction*/
-	if (p->opcode == BREAKPOINT_INSTRUCTION)
+
+	/* single step inline if it is a trap variant */
+	if (IS_TW(insn) || IS_TD(insn) || IS_TWI(insn) || IS_TDI(insn))
 		regs->nip = (unsigned long)p->addr;
 	else
-		regs->nip = (unsigned long)&p->ainsn.insn;
+		regs->nip = (unsigned long)p->ainsn.insn;
+}
+
+static inline void save_previous_kprobe(void)
+{
+	kprobe_prev = current_kprobe;
+	kprobe_status_prev = kprobe_status;
+	kprobe_saved_msr_prev = kprobe_saved_msr;
+}
+
+static inline void restore_previous_kprobe(void)
+{
+	current_kprobe = kprobe_prev;
+	kprobe_status = kprobe_status_prev;
+	kprobe_saved_msr = kprobe_saved_msr_prev;
+}
+
+void arch_prepare_kretprobe(struct kretprobe *rp, struct pt_regs *regs)
+{
+	struct kretprobe_instance *ri;
+
+	if ((ri = get_free_rp_inst(rp)) != NULL) {
+		ri->rp = rp;
+		ri->task = current;
+		ri->ret_addr = (kprobe_opcode_t *)regs->link;
+
+		/* Replace the return addr with trampoline addr */
+		regs->link = (unsigned long)kretprobe_trampoline;
+		add_rp_inst(ri);
+	} else {
+		rp->nmissed++;
+	}
 }
 
 static inline int kprobe_handler(struct pt_regs *regs)
@@ -101,8 +157,19 @@ static inline int kprobe_handler(struct 
 				unlock_kprobes();
 				goto no_kprobe;
 			}
-			disarm_kprobe(p, regs);
-			ret = 1;
+			/* We have reentered the kprobe_handler(), since
+			 * another probe was hit while within the handler.
+			 * We here save the original kprobes variables and
+			 * just single step on the instruction of the new probe
+			 * without calling any user handlers.
+			 */
+			save_previous_kprobe();
+			current_kprobe = p;
+			kprobe_saved_msr = regs->msr;
+			p->nmissed++;
+			prepare_singlestep(p, regs);
+			kprobe_status = KPROBE_REENTER;
+			return 1;
 		} else {
 			p = current_kprobe;
 			if (p->break_handler && p->break_handler(p, regs)) {
@@ -162,6 +229,78 @@ no_kprobe:
 }
 
 /*
+ * Function return probe trampoline:
+ * 	- init_kprobes() establishes a probepoint here
+ * 	- When the probed function returns, this probe
+ * 		causes the handlers to fire
+ */
+void kretprobe_trampoline_holder(void)
+{
+	asm volatile(".global kretprobe_trampoline\n"
+			"kretprobe_trampoline:\n"
+			"nop\n");
+}
+
+/*
+ * Called when the probe at kretprobe trampoline is hit
+ */
+int trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
+{
+        struct kretprobe_instance *ri = NULL;
+        struct hlist_head *head;
+        struct hlist_node *node, *tmp;
+	unsigned long orig_ret_address = 0;
+	unsigned long trampoline_address =(unsigned long)&kretprobe_trampoline;
+
+        head = kretprobe_inst_table_head(current);
+
+	/*
+	 * It is possible to have multiple instances associated with a given
+	 * task either because an multiple functions in the call path
+	 * have a return probe installed on them, and/or more then one return
+	 * return probe was registered for a target function.
+	 *
+	 * We can handle this because:
+	 *     - instances are always inserted at the head of the list
+	 *     - when multiple return probes are registered for the same
+         *       function, the first instance's ret_addr will point to the
+	 *       real return address, and all the rest will point to
+	 *       kretprobe_trampoline
+	 */
+	hlist_for_each_entry_safe(ri, node, tmp, head, hlist) {
+                if (ri->task != current)
+			/* another task is sharing our hash bucket */
+                        continue;
+
+		if (ri->rp && ri->rp->handler)
+			ri->rp->handler(ri, regs);
+
+		orig_ret_address = (unsigned long)ri->ret_addr;
+		recycle_rp_inst(ri);
+
+		if (orig_ret_address != trampoline_address)
+			/*
+			 * This is the real return address. Any other
+			 * instances associated with this task are for
+			 * other calls deeper on the call stack
+			 */
+			break;
+	}
+
+	BUG_ON(!orig_ret_address || (orig_ret_address == trampoline_address));
+	regs->nip = orig_ret_address;
+
+	unlock_kprobes();
+
+        /*
+         * By returning a non-zero value, we are telling
+         * kprobe_handler() that we have handled unlocking
+         * and re-enabling preemption.
+         */
+        return 1;
+}
+
+/*
  * Called after single-stepping.  p->addr is the address of the
  * instruction whose first byte has been replaced by the "breakpoint"
  * instruction.  To avoid the SMP problems that can occur when we
@@ -172,9 +311,10 @@ no_kprobe:
 static void resume_execution(struct kprobe *p, struct pt_regs *regs)
 {
 	int ret;
+	unsigned int insn = *p->ainsn.insn;
 
 	regs->nip = (unsigned long)p->addr;
-	ret = emulate_step(regs, p->ainsn.insn[0]);
+	ret = emulate_step(regs, insn);
 	if (ret == 0)
 		regs->nip = (unsigned long)p->addr + 4;
 }
@@ -184,13 +324,21 @@ static inline int post_kprobe_handler(st
 	if (!kprobe_running())
 		return 0;
 
-	if (current_kprobe->post_handler)
+	if ((kprobe_status != KPROBE_REENTER) && current_kprobe->post_handler) {
+		kprobe_status = KPROBE_HIT_SSDONE;
 		current_kprobe->post_handler(current_kprobe, regs, 0);
+	}
 
 	resume_execution(current_kprobe, regs);
 	regs->msr |= kprobe_saved_msr;
 
+	/*Restore back the original saved kprobes variables and continue. */
+	if (kprobe_status == KPROBE_REENTER) {
+		restore_previous_kprobe();
+		goto out;
+	}
 	unlock_kprobes();
+out:
 	preempt_enable_no_resched();
 
 	/*
@@ -290,3 +438,13 @@ int longjmp_break_handler(struct kprobe 
 	memcpy(regs, &jprobe_saved_regs, sizeof(struct pt_regs));
 	return 1;
 }
+
+static struct kprobe trampoline_p = {
+	.addr = (kprobe_opcode_t *) &kretprobe_trampoline,
+	.pre_handler = trampoline_probe_handler
+};
+
+int __init arch_init_kprobes(void)
+{
+	return register_kprobe(&trampoline_p);
+}
diff --git a/arch/ppc64/kernel/lparcfg.c b/arch/ppc64/kernel/lparcfg.c
--- a/arch/ppc64/kernel/lparcfg.c
+++ b/arch/ppc64/kernel/lparcfg.c
@@ -28,12 +28,13 @@
 #include <asm/uaccess.h>
 #include <asm/iSeries/HvLpConfig.h>
 #include <asm/lppaca.h>
-#include <asm/iSeries/LparData.h>
 #include <asm/hvcall.h>
 #include <asm/cputable.h>
 #include <asm/rtas.h>
 #include <asm/system.h>
 #include <asm/time.h>
+#include <asm/iSeries/ItExtVpdPanel.h>
+#include <asm/prom.h>
 
 #define MODULE_VERS "1.6"
 #define MODULE_NAME "lparcfg"
diff --git a/arch/ppc64/kernel/lparmap.c b/arch/ppc64/kernel/lparmap.c
new file mode 100644
--- /dev/null
+++ b/arch/ppc64/kernel/lparmap.c
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2005  Stephen Rothwell  IBM Corp.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include <asm/mmu.h>
+#include <asm/page.h>
+#include <asm/iSeries/LparMap.h>
+
+const struct LparMap __attribute__((__section__(".text"))) xLparMap = {
+	.xNumberEsids = HvEsidsToMap,
+	.xNumberRanges = HvRangesToMap,
+	.xSegmentTableOffs = STAB0_PAGE,
+
+	.xEsids = {
+		{ .xKernelEsid = GET_ESID(KERNELBASE),
+		  .xKernelVsid = KERNEL_VSID(KERNELBASE), },
+		{ .xKernelEsid = GET_ESID(VMALLOCBASE),
+		  .xKernelVsid = KERNEL_VSID(VMALLOCBASE), },
+	},
+
+	.xRanges = {
+		{ .xPages = HvPagesToMap,
+		  .xOffset = 0,
+		  .xVPN = KERNEL_VSID(KERNELBASE) << (SID_SHIFT - PAGE_SHIFT),
+		},
+	},
+};
diff --git a/arch/ppc64/kernel/machine_kexec.c b/arch/ppc64/kernel/machine_kexec.c
new file mode 100644
--- /dev/null
+++ b/arch/ppc64/kernel/machine_kexec.c
@@ -0,0 +1,306 @@
+/*
+ * machine_kexec.c - handle transition of Linux booting another kernel
+ *
+ * Copyright (C) 2004-2005, IBM Corp.
+ *
+ * Created by: Milton D Miller II
+ *
+ * This source code is licensed under the GNU General Public License,
+ * Version 2.  See the file COPYING for more details.
+ */
+
+
+#include <linux/cpumask.h>
+#include <linux/kexec.h>
+#include <linux/smp.h>
+#include <linux/thread_info.h>
+#include <linux/errno.h>
+
+#include <asm/page.h>
+#include <asm/current.h>
+#include <asm/machdep.h>
+#include <asm/cacheflush.h>
+#include <asm/paca.h>
+#include <asm/mmu.h>
+#include <asm/sections.h>	/* _end */
+#include <asm/prom.h>
+
+#define HASH_GROUP_SIZE 0x80	/* size of each hash group, asm/mmu.h */
+
+/* Have this around till we move it into crash specific file */
+note_buf_t crash_notes[NR_CPUS];
+
+/* Dummy for now. Not sure if we need to have a crash shutdown in here
+ * and if what it will achieve. Letting it be now to compile the code
+ * in generic kexec environment
+ */
+void machine_crash_shutdown(struct pt_regs *regs)
+{
+	/* do nothing right now */
+	/* smp_relase_cpus() if we want smp on panic kernel */
+	/* cpu_irq_down to isolate us until we are ready */
+}
+
+int machine_kexec_prepare(struct kimage *image)
+{
+	int i;
+	unsigned long begin, end;	/* limits of segment */
+	unsigned long low, high;	/* limits of blocked memory range */
+	struct device_node *node;
+	unsigned long *basep;
+	unsigned int *sizep;
+
+	if (!ppc_md.hpte_clear_all)
+		return -ENOENT;
+
+	/*
+	 * Since we use the kernel fault handlers and paging code to
+	 * handle the virtual mode, we must make sure no destination
+	 * overlaps kernel static data or bss.
+	 */
+	for (i = 0; i < image->nr_segments; i++)
+		if (image->segment[i].mem < __pa(_end))
+			return -ETXTBSY;
+
+	/*
+	 * For non-LPAR, we absolutely can not overwrite the mmu hash
+	 * table, since we are still using the bolted entries in it to
+	 * do the copy.  Check that here.
+	 *
+	 * It is safe if the end is below the start of the blocked
+	 * region (end <= low), or if the beginning is after the
+	 * end of the blocked region (begin >= high).  Use the
+	 * boolean identity !(a || b)  === (!a && !b).
+	 */
+	if (htab_address) {
+		low = __pa(htab_address);
+		high = low + (htab_hash_mask + 1) * HASH_GROUP_SIZE;
+
+		for (i = 0; i < image->nr_segments; i++) {
+			begin = image->segment[i].mem;
+			end = begin + image->segment[i].memsz;
+
+			if ((begin < high) && (end > low))
+				return -ETXTBSY;
+		}
+	}
+
+	/* We also should not overwrite the tce tables */
+	for (node = of_find_node_by_type(NULL, "pci"); node != NULL;
+			node = of_find_node_by_type(node, "pci")) {
+		basep = (unsigned long *)get_property(node, "linux,tce-base",
+							NULL);
+		sizep = (unsigned int *)get_property(node, "linux,tce-size",
+							NULL);
+		if (basep == NULL || sizep == NULL)
+			continue;
+
+		low = *basep;
+		high = low + (*sizep);
+
+		for (i = 0; i < image->nr_segments; i++) {
+			begin = image->segment[i].mem;
+			end = begin + image->segment[i].memsz;
+
+			if ((begin < high) && (end > low))
+				return -ETXTBSY;
+		}
+	}
+
+	return 0;
+}
+
+void machine_kexec_cleanup(struct kimage *image)
+{
+	/* we do nothing in prepare that needs to be undone */
+}
+
+#define IND_FLAGS (IND_DESTINATION | IND_INDIRECTION | IND_DONE | IND_SOURCE)
+
+static void copy_segments(unsigned long ind)
+{
+	unsigned long entry;
+	unsigned long *ptr;
+	void *dest;
+	void *addr;
+
+	/*
+	 * We rely on kexec_load to create a lists that properly
+	 * initializes these pointers before they are used.
+	 * We will still crash if the list is wrong, but at least
+	 * the compiler will be quiet.
+	 */
+	ptr = NULL;
+	dest = NULL;
+
+	for (entry = ind; !(entry & IND_DONE); entry = *ptr++) {
+		addr = __va(entry & PAGE_MASK);
+
+		switch (entry & IND_FLAGS) {
+		case IND_DESTINATION:
+			dest = addr;
+			break;
+		case IND_INDIRECTION:
+			ptr = addr;
+			break;
+		case IND_SOURCE:
+			copy_page(dest, addr);
+			dest += PAGE_SIZE;
+		}
+	}
+}
+
+void kexec_copy_flush(struct kimage *image)
+{
+	long i, nr_segments = image->nr_segments;
+	struct  kexec_segment ranges[KEXEC_SEGMENT_MAX];
+
+	/* save the ranges on the stack to efficiently flush the icache */
+	memcpy(ranges, image->segment, sizeof(ranges));
+
+	/*
+	 * After this call we may not use anything allocated in dynamic
+	 * memory, including *image.
+	 *
+	 * Only globals and the stack are allowed.
+	 */
+	copy_segments(image->head);
+
+	/*
+	 * we need to clear the icache for all dest pages sometime,
+	 * including ones that were in place on the original copy
+	 */
+	for (i = 0; i < nr_segments; i++)
+		flush_icache_range(ranges[i].mem + KERNELBASE,
+				ranges[i].mem + KERNELBASE +
+				ranges[i].memsz);
+}
+
+#ifdef CONFIG_SMP
+
+/* FIXME: we should schedule this function to be called on all cpus based
+ * on calling the interrupts, but we would like to call it off irq level
+ * so that the interrupt controller is clean.
+ */
+void kexec_smp_down(void *arg)
+{
+	if (ppc_md.cpu_irq_down)
+		ppc_md.cpu_irq_down(1);
+
+	local_irq_disable();
+	kexec_smp_wait();
+	/* NOTREACHED */
+}
+
+static void kexec_prepare_cpus(void)
+{
+	int my_cpu, i, notified=-1;
+
+	smp_call_function(kexec_smp_down, NULL, 0, /* wait */0);
+	my_cpu = get_cpu();
+
+	/* check the others cpus are now down (via paca hw cpu id == -1) */
+	for (i=0; i < NR_CPUS; i++) {
+		if (i == my_cpu)
+			continue;
+
+		while (paca[i].hw_cpu_id != -1) {
+			if (!cpu_possible(i)) {
+				printk("kexec: cpu %d hw_cpu_id %d is not"
+						" possible, ignoring\n",
+						i, paca[i].hw_cpu_id);
+				break;
+			}
+			if (!cpu_online(i)) {
+				/* Fixme: this can be spinning in
+				 * pSeries_secondary_wait with a paca
+				 * waiting for it to go online.
+				 */
+				printk("kexec: cpu %d hw_cpu_id %d is not"
+						" online, ignoring\n",
+						i, paca[i].hw_cpu_id);
+				break;
+			}
+			if (i != notified) {
+				printk( "kexec: waiting for cpu %d (physical"
+						" %d) to go down\n",
+						i, paca[i].hw_cpu_id);
+				notified = i;
+			}
+		}
+	}
+
+	/* after we tell the others to go down */
+	if (ppc_md.cpu_irq_down)
+		ppc_md.cpu_irq_down(0);
+
+	put_cpu();
+
+	local_irq_disable();
+}
+
+#else /* ! SMP */
+
+static void kexec_prepare_cpus(void)
+{
+	extern void smp_release_cpus(void);
+	/*
+	 * move the secondarys to us so that we can copy
+	 * the new kernel 0-0x100 safely
+	 *
+	 * do this if kexec in setup.c ?
+	 *
+	 * We need to release the cpus if we are ever going from an
+	 * UP to an SMP kernel.
+	 */
+	smp_release_cpus();
+	if (ppc_md.cpu_irq_down)
+		ppc_md.cpu_irq_down(0);
+	local_irq_disable();
+}
+
+#endif /* SMP */
+
+/*
+ * kexec thread structure and stack.
+ *
+ * We need to make sure that this is 16384-byte aligned due to the
+ * way process stacks are handled.  It also must be statically allocated
+ * or allocated as part of the kimage, because everything else may be
+ * overwritten when we copy the kexec image.  We piggyback on the
+ * "init_task" linker section here to statically allocate a stack.
+ *
+ * We could use a smaller stack if we don't care about anything using
+ * current, but that audit has not been performed.
+ */
+union thread_union kexec_stack
+	__attribute__((__section__(".data.init_task"))) = { };
+
+/* Our assembly helper, in kexec_stub.S */
+extern NORET_TYPE void kexec_sequence(void *newstack, unsigned long start,
+					void *image, void *control,
+					void (*clear_all)(void)) ATTRIB_NORET;
+
+/* too late to fail here */
+void machine_kexec(struct kimage *image)
+{
+
+	/* prepare control code if any */
+
+	/* shutdown other cpus into our wait loop and quiesce interrupts */
+	kexec_prepare_cpus();
+
+	/* switch to a staticly allocated stack.  Based on irq stack code.
+	 * XXX: the task struct will likely be invalid once we do the copy!
+	 */
+	kexec_stack.thread_info.task = current_thread_info()->task;
+	kexec_stack.thread_info.flags = 0;
+
+	/* Some things are best done in assembly.  Finding globals with
+	 * a toc is easier in C, so pass in what we can.
+	 */
+	kexec_sequence(&kexec_stack, image->start, image,
+			page_address(image->control_code_page),
+			ppc_md.hpte_clear_all);
+	/* NOTREACHED */
+}
diff --git a/arch/ppc64/kernel/maple_setup.c b/arch/ppc64/kernel/maple_setup.c
--- a/arch/ppc64/kernel/maple_setup.c
+++ b/arch/ppc64/kernel/maple_setup.c
@@ -78,17 +78,77 @@ extern int maple_pci_get_legacy_ide_irq(
 extern void generic_find_legacy_serial_ports(u64 *physport,
 		unsigned int *default_speed);
 
-
 static void maple_restart(char *cmd)
 {
+	unsigned int maple_nvram_base;
+	unsigned int maple_nvram_offset;
+	unsigned int maple_nvram_command;
+	struct device_node *rtcs;
+
+	/* find NVRAM device */
+	rtcs = find_compatible_devices("nvram", "AMD8111");
+	if (rtcs && rtcs->addrs) {
+		maple_nvram_base = rtcs->addrs[0].address;
+	} else {
+		printk(KERN_EMERG "Maple: Unable to find NVRAM\n");
+		printk(KERN_EMERG "Maple: Manual Restart Required\n");
+		return;
+	}
+
+	/* find service processor device */
+	rtcs = find_devices("service-processor");
+	if (!rtcs) {
+		printk(KERN_EMERG "Maple: Unable to find Service Processor\n");
+		printk(KERN_EMERG "Maple: Manual Restart Required\n");
+		return;
+	}
+	maple_nvram_offset = *(unsigned int*) get_property(rtcs,
+			"restart-addr", NULL);
+	maple_nvram_command = *(unsigned int*) get_property(rtcs,
+			"restart-value", NULL);
+
+	/* send command */
+	outb_p(maple_nvram_command, maple_nvram_base + maple_nvram_offset);
+	for (;;) ;
 }
 
 static void maple_power_off(void)
 {
+	unsigned int maple_nvram_base;
+	unsigned int maple_nvram_offset;
+	unsigned int maple_nvram_command;
+	struct device_node *rtcs;
+
+	/* find NVRAM device */
+	rtcs = find_compatible_devices("nvram", "AMD8111");
+	if (rtcs && rtcs->addrs) {
+		maple_nvram_base = rtcs->addrs[0].address;
+	} else {
+		printk(KERN_EMERG "Maple: Unable to find NVRAM\n");
+		printk(KERN_EMERG "Maple: Manual Power-Down Required\n");
+		return;
+	}
+
+	/* find service processor device */
+	rtcs = find_devices("service-processor");
+	if (!rtcs) {
+		printk(KERN_EMERG "Maple: Unable to find Service Processor\n");
+		printk(KERN_EMERG "Maple: Manual Power-Down Required\n");
+		return;
+	}
+	maple_nvram_offset = *(unsigned int*) get_property(rtcs,
+			"power-off-addr", NULL);
+	maple_nvram_command = *(unsigned int*) get_property(rtcs,
+			"power-off-value", NULL);
+
+	/* send command */
+	outb_p(maple_nvram_command, maple_nvram_base + maple_nvram_offset);
+	for (;;) ;
 }
 
 static void maple_halt(void)
 {
+	maple_power_off();
 }
 
 #ifdef CONFIG_SMP
@@ -117,6 +177,8 @@ void __init maple_setup_arch(void)
 #ifdef CONFIG_DUMMY_CONSOLE
 	conswitchp = &dummy_con;
 #endif
+
+	printk(KERN_INFO "Using native/NAP idle loop\n");
 }
 
 /* 
@@ -235,6 +297,7 @@ struct machdep_calls __initdata maple_md
        	.get_boot_time		= maple_get_boot_time,
        	.set_rtc_time		= maple_set_rtc_time,
        	.get_rtc_time		= maple_get_rtc_time,
-      	.calibrate_decr		= maple_calibrate_decr,
+      	.calibrate_decr		= generic_calibrate_decr,
 	.progress		= maple_progress,
+	.idle_loop		= native_idle,
 };
diff --git a/arch/ppc64/kernel/maple_time.c b/arch/ppc64/kernel/maple_time.c
--- a/arch/ppc64/kernel/maple_time.c
+++ b/arch/ppc64/kernel/maple_time.c
@@ -42,11 +42,8 @@
 #define DBG(x...)
 #endif
 
-extern void setup_default_decr(void);
 extern void GregorianDay(struct rtc_time * tm);
 
-extern unsigned long ppc_tb_freq;
-extern unsigned long ppc_proc_freq;
 static int maple_rtc_addr;
 
 static int maple_clock_read(int addr)
@@ -176,51 +173,3 @@ void __init maple_get_boot_time(struct r
 	maple_get_rtc_time(tm);
 }
 
-/* XXX FIXME: Some sane defaults: 125 MHz timebase, 1GHz processor */
-#define DEFAULT_TB_FREQ		125000000UL
-#define DEFAULT_PROC_FREQ	(DEFAULT_TB_FREQ * 8)
-
-void __init maple_calibrate_decr(void)
-{
-	struct device_node *cpu;
-	struct div_result divres;
-	unsigned int *fp = NULL;
-
-	/*
-	 * The cpu node should have a timebase-frequency property
-	 * to tell us the rate at which the decrementer counts.
-	 */
-	cpu = of_find_node_by_type(NULL, "cpu");
-
-	ppc_tb_freq = DEFAULT_TB_FREQ;
-	if (cpu != 0)
-		fp = (unsigned int *)get_property(cpu, "timebase-frequency", NULL);
-	if (fp != NULL)
-		ppc_tb_freq = *fp;
-	else
-		printk(KERN_ERR "WARNING: Estimating decrementer frequency (not found)\n");
-	fp = NULL;
-	ppc_proc_freq = DEFAULT_PROC_FREQ;
-	if (cpu != 0)
-		fp = (unsigned int *)get_property(cpu, "clock-frequency", NULL);
-	if (fp != NULL)
-		ppc_proc_freq = *fp;
-	else
-		printk(KERN_ERR "WARNING: Estimating processor frequency (not found)\n");
-
-	of_node_put(cpu);
-
-	printk(KERN_INFO "time_init: decrementer frequency = %lu.%.6lu MHz\n",
-	       ppc_tb_freq/1000000, ppc_tb_freq%1000000);
-	printk(KERN_INFO "time_init: processor frequency   = %lu.%.6lu MHz\n",
-	       ppc_proc_freq/1000000, ppc_proc_freq%1000000);
-
-	tb_ticks_per_jiffy = ppc_tb_freq / HZ;
-	tb_ticks_per_sec = tb_ticks_per_jiffy * HZ;
-	tb_ticks_per_usec = ppc_tb_freq / 1000000;
-	tb_to_us = mulhwu_scale_factor(ppc_tb_freq, 1000000);
-	div128_by_32(1024*1024, 0, tb_ticks_per_sec, &divres);
-	tb_to_xs = divres.result_low;
-
-	setup_default_decr();
-}
diff --git a/arch/ppc64/kernel/mf.c b/arch/ppc64/kernel/mf.c
--- a/arch/ppc64/kernel/mf.c
+++ b/arch/ppc64/kernel/mf.c
@@ -40,7 +40,6 @@
 #include <asm/iSeries/vio.h>
 #include <asm/iSeries/mf.h>
 #include <asm/iSeries/HvLpConfig.h>
-#include <asm/iSeries/ItSpCommArea.h>
 #include <asm/iSeries/ItLpQueue.h>
 
 /*
@@ -802,10 +801,8 @@ int mf_get_boot_rtc(struct rtc_time *tm)
 		return rc;
 	/* We need to poll here as we are not yet taking interrupts */
 	while (rtc_data.busy) {
-		extern unsigned long lpevent_count;
-		struct ItLpQueue *lpq = get_paca()->lpqueue_ptr;
-		if (lpq && ItLpQueue_isLpIntPending(lpq))
-			lpevent_count += ItLpQueue_process(lpq, NULL);
+		if (hvlpevent_is_pending())
+			process_hvlpevents(NULL);
 	}
 	return rtc_set_tm(rtc_data.rc, rtc_data.ce_msg.ce_msg, tm);
 }
diff --git a/arch/ppc64/kernel/misc.S b/arch/ppc64/kernel/misc.S
--- a/arch/ppc64/kernel/misc.S
+++ b/arch/ppc64/kernel/misc.S
@@ -680,6 +680,177 @@ _GLOBAL(kernel_thread)
 	ld	r30,-16(r1)
 	blr
 
+/* kexec_wait(phys_cpu)
+ *
+ * wait for the flag to change, indicating this kernel is going away but
+ * the slave code for the next one is at addresses 0 to 100.
+ *
+ * This is used by all slaves.
+ *
+ * Physical (hardware) cpu id should be in r3.
+ */
+_GLOBAL(kexec_wait)
+	bl	1f
+1:	mflr	r5
+	addi	r5,r5,kexec_flag-1b
+
+99:	HMT_LOW
+#ifdef CONFIG_KEXEC		/* use no memory without kexec */
+	lwz	r4,0(r5)
+	cmpwi	0,r4,0
+	bnea	0x60
+#endif
+	b	99b
+
+/* this can be in text because we won't change it until we are
+ * running in real anyways
+ */
+kexec_flag:
+	.long	0
+
+
+#ifdef CONFIG_KEXEC
+
+/* kexec_smp_wait(void)
+ *
+ * call with interrupts off
+ * note: this is a terminal routine, it does not save lr
+ *
+ * get phys id from paca
+ * set paca id to -1 to say we got here
+ * switch to real mode
+ * join other cpus in kexec_wait(phys_id)
+ */
+_GLOBAL(kexec_smp_wait)
+	lhz	r3,PACAHWCPUID(r13)
+	li	r4,-1
+	sth	r4,PACAHWCPUID(r13)	/* let others know we left */
+	bl	real_mode
+	b	.kexec_wait
+
+/*
+ * switch to real mode (turn mmu off)
+ * we use the early kernel trick that the hardware ignores bits
+ * 0 and 1 (big endian) of the effective address in real mode
+ *
+ * don't overwrite r3 here, it is live for kexec_wait above.
+ */
+real_mode:	/* assume normal blr return */
+1:	li	r9,MSR_RI
+	li	r10,MSR_DR|MSR_IR
+	mflr	r11		/* return address to SRR0 */
+	mfmsr	r12
+	andc	r9,r12,r9
+	andc	r10,r12,r10
+
+	mtmsrd	r9,1
+	mtspr	SPRN_SRR1,r10
+	mtspr	SPRN_SRR0,r11
+	rfid
+
+
+/*
+ * kexec_sequence(newstack, start, image, control, clear_all())
+ *
+ * does the grungy work with stack switching and real mode switches
+ * also does simple calls to other code
+ */
+
+_GLOBAL(kexec_sequence)
+	mflr	r0
+	std	r0,16(r1)
+
+	/* switch stacks to newstack -- &kexec_stack.stack */
+	stdu	r1,THREAD_SIZE-112(r3)
+	mr	r1,r3
+
+	li	r0,0
+	std	r0,16(r1)
+
+	/* save regs for local vars on new stack.
+	 * yes, we won't go back, but ...
+	 */
+	std	r31,-8(r1)
+	std	r30,-16(r1)
+	std	r29,-24(r1)
+	std	r28,-32(r1)
+	std	r27,-40(r1)
+	std	r26,-48(r1)
+	std	r25,-56(r1)
+
+	stdu	r1,-112-64(r1)
+
+	/* save args into preserved regs */
+	mr	r31,r3			/* newstack (both) */
+	mr	r30,r4			/* start (real) */
+	mr	r29,r5			/* image (virt) */
+	mr	r28,r6			/* control, unused */
+	mr	r27,r7			/* clear_all() fn desc */
+	mr	r26,r8			/* spare */
+	lhz	r25,PACAHWCPUID(r13)	/* get our phys cpu from paca */
+
+	/* disable interrupts, we are overwriting kernel data next */
+	mfmsr	r3
+	rlwinm	r3,r3,0,17,15
+	mtmsrd	r3,1
+
+	/* copy dest pages, flush whole dest image */
+	mr	r3,r29
+	bl	.kexec_copy_flush	/* (image) */
+
+	/* turn off mmu */
+	bl	real_mode
+
+	/* clear out hardware hash page table and tlb */
+	ld	r5,0(r27)		/* deref function descriptor */
+	mtctr	r5
+	bctrl				/* ppc_md.hash_clear_all(void); */
+
+/*
+ *   kexec image calling is:
+ *      the first 0x100 bytes of the entry point are copied to 0
+ *
+ *      all slaves branch to slave = 0x60 (absolute)
+ *              slave(phys_cpu_id);
+ *
+ *      master goes to start = entry point
+ *              start(phys_cpu_id, start, 0);
+ *
+ *
+ *   a wrapper is needed to call existing kernels, here is an approximate
+ *   description of one method:
+ *
+ * v2: (2.6.10)
+ *   start will be near the boot_block (maybe 0x100 bytes before it?)
+ *   it will have a 0x60, which will b to boot_block, where it will wait
+ *   and 0 will store phys into struct boot-block and load r3 from there,
+ *   copy kernel 0-0x100 and tell slaves to back down to 0x60 again
+ *
+ * v1: (2.6.9)
+ *    boot block will have all cpus scanning device tree to see if they
+ *    are the boot cpu ?????
+ *    other device tree differences (prop sizes, va vs pa, etc)...
+ */
+
+	/* copy  0x100 bytes starting at start to 0 */
+	li	r3,0
+	mr	r4,r30
+	li	r5,0x100
+	li	r6,0
+	bl	.copy_and_flush	/* (dest, src, copy limit, start offset) */
+1:	/* assume normal blr return */
+
+	/* release other cpus to the new kernel secondary start at 0x60 */
+	mflr	r5
+	li	r6,1
+	stw	r6,kexec_flag-1b(5)
+	mr	r3,r25	# my phys cpu
+	mr	r4,r30	# start, aka phys mem offset
+	mtlr	4
+	li	r5,0
+	blr	/* image->start(physid, image->start, 0); */
+#endif /* CONFIG_KEXEC */
+
 /* Why isn't this a) automatic, b) written in 'C'? */	
 	.balign 8
 _GLOBAL(sys_call_table32)
@@ -951,11 +1122,16 @@ _GLOBAL(sys_call_table32)
 	.llong .compat_sys_mq_timedreceive /* 265 */
 	.llong .compat_sys_mq_notify
 	.llong .compat_sys_mq_getsetattr
-	.llong .sys_ni_syscall		/* 268 reserved for sys_kexec_load */
+	.llong .compat_sys_kexec_load
 	.llong .sys32_add_key
-	.llong .sys32_request_key
+	.llong .sys32_request_key	/* 270 */
 	.llong .compat_sys_keyctl
 	.llong .compat_sys_waitid
+	.llong .sys32_ioprio_set
+	.llong .sys32_ioprio_get
+	.llong .sys_inotify_init	/* 275 */
+	.llong .sys_inotify_add_watch
+	.llong .sys_inotify_rm_watch
 
 	.balign 8
 _GLOBAL(sys_call_table)
@@ -1227,8 +1403,13 @@ _GLOBAL(sys_call_table)
 	.llong .sys_mq_timedreceive	/* 265 */
 	.llong .sys_mq_notify
 	.llong .sys_mq_getsetattr
-	.llong .sys_ni_syscall		/* 268 reserved for sys_kexec_load */
+	.llong .sys_kexec_load
 	.llong .sys_add_key
 	.llong .sys_request_key		/* 270 */
 	.llong .sys_keyctl
 	.llong .sys_waitid
+	.llong .sys_ioprio_set
+	.llong .sys_ioprio_get
+	.llong .sys_inotify_init	/* 275 */
+	.llong .sys_inotify_add_watch
+	.llong .sys_inotify_rm_watch
diff --git a/arch/ppc64/kernel/mpic.c b/arch/ppc64/kernel/mpic.c
--- a/arch/ppc64/kernel/mpic.c
+++ b/arch/ppc64/kernel/mpic.c
@@ -792,6 +792,35 @@ void mpic_setup_this_cpu(void)
 #endif /* CONFIG_SMP */
 }
 
+/*
+ * XXX: someone who knows mpic should check this.
+ * do we need to eoi the ipi including for kexec cpu here (see xics comments)?
+ * or can we reset the mpic in the new kernel?
+ */
+void mpic_teardown_this_cpu(int secondary)
+{
+	struct mpic *mpic = mpic_primary;
+	unsigned long flags;
+	u32 msk = 1 << hard_smp_processor_id();
+	unsigned int i;
+
+	BUG_ON(mpic == NULL);
+
+	DBG("%s: teardown_this_cpu(%d)\n", mpic->name, hard_smp_processor_id());
+	spin_lock_irqsave(&mpic_lock, flags);
+
+	/* let the mpic know we don't want intrs.  */
+	for (i = 0; i < mpic->num_sources ; i++)
+		mpic_irq_write(i, MPIC_IRQ_DESTINATION,
+			mpic_irq_read(i, MPIC_IRQ_DESTINATION) & ~msk);
+
+	/* Set current processor priority to max */
+	mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, 0xf);
+
+	spin_unlock_irqrestore(&mpic_lock, flags);
+}
+
+
 void mpic_send_ipi(unsigned int ipi_no, unsigned int cpu_mask)
 {
 	struct mpic *mpic = mpic_primary;
diff --git a/arch/ppc64/kernel/mpic.h b/arch/ppc64/kernel/mpic.h
--- a/arch/ppc64/kernel/mpic.h
+++ b/arch/ppc64/kernel/mpic.h
@@ -255,6 +255,9 @@ extern unsigned int mpic_irq_get_priorit
 /* Setup a non-boot CPU */
 extern void mpic_setup_this_cpu(void);
 
+/* Clean up for kexec (or cpu offline or ...) */
+extern void mpic_teardown_this_cpu(int secondary);
+
 /* Request IPIs on primary mpic */
 extern void mpic_request_ipis(void);
 
@@ -265,3 +268,6 @@ extern void mpic_send_ipi(unsigned int i
 extern int mpic_get_one_irq(struct mpic *mpic, struct pt_regs *regs);
 /* This one gets to the primary mpic */
 extern int mpic_get_irq(struct pt_regs *regs);
+
+/* global mpic for pSeries */
+extern struct mpic *pSeries_mpic;
diff --git a/arch/ppc64/kernel/nvram.c b/arch/ppc64/kernel/nvram.c
--- a/arch/ppc64/kernel/nvram.c
+++ b/arch/ppc64/kernel/nvram.c
@@ -338,9 +338,8 @@ static int nvram_remove_os_partition(voi
  */
 static int nvram_create_os_partition(void)
 {
-	struct list_head * p;
-	struct nvram_partition *part = NULL;
-	struct nvram_partition *new_part = NULL;
+	struct nvram_partition *part;
+	struct nvram_partition *new_part;
 	struct nvram_partition *free_part = NULL;
 	int seq_init[2] = { 0, 0 };
 	loff_t tmp_index;
@@ -349,8 +348,7 @@ static int nvram_create_os_partition(voi
 	
 	/* Find a free partition that will give us the maximum needed size 
 	   If can't find one that will give us the minimum size needed */
-	list_for_each(p, &nvram_part->partition) {
-		part = list_entry(p, struct nvram_partition, partition);
+	list_for_each_entry(part, &nvram_part->partition, partition) {
 		if (part->header.signature != NVRAM_SIG_FREE)
 			continue;
 
diff --git a/arch/ppc64/kernel/of_device.c b/arch/ppc64/kernel/of_device.c
--- a/arch/ppc64/kernel/of_device.c
+++ b/arch/ppc64/kernel/of_device.c
@@ -3,6 +3,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/mod_devicetable.h>
 #include <asm/errno.h>
 #include <asm/of_device.h>
 
@@ -15,20 +16,20 @@
  * Used by a driver to check whether an of_device present in the
  * system is in its list of supported devices.
  */
-const struct of_match * of_match_device(const struct of_match *matches,
+const struct of_device_id *of_match_device(const struct of_device_id *matches,
 					const struct of_device *dev)
 {
 	if (!dev->node)
 		return NULL;
-	while (matches->name || matches->type || matches->compatible) {
+	while (matches->name[0] || matches->type[0] || matches->compatible[0]) {
 		int match = 1;
-		if (matches->name && matches->name != OF_ANY_MATCH)
+		if (matches->name[0])
 			match &= dev->node->name
 				&& !strcmp(matches->name, dev->node->name);
-		if (matches->type && matches->type != OF_ANY_MATCH)
+		if (matches->type[0])
 			match &= dev->node->type
 				&& !strcmp(matches->type, dev->node->type);
-		if (matches->compatible && matches->compatible != OF_ANY_MATCH)
+		if (matches->compatible[0])
 			match &= device_is_compatible(dev->node,
 				matches->compatible);
 		if (match)
@@ -42,7 +43,7 @@ static int of_platform_bus_match(struct 
 {
 	struct of_device * of_dev = to_of_device(dev);
 	struct of_platform_driver * of_drv = to_of_platform_driver(drv);
-	const struct of_match * matches = of_drv->match_table;
+	const struct of_device_id * matches = of_drv->match_table;
 
 	if (!matches)
 		return 0;
@@ -75,7 +76,7 @@ static int of_device_probe(struct device
 	int error = -ENODEV;
 	struct of_platform_driver *drv;
 	struct of_device *of_dev;
-	const struct of_match *match;
+	const struct of_device_id *match;
 
 	drv = to_of_platform_driver(dev->driver);
 	of_dev = to_of_device(dev);
@@ -161,7 +162,7 @@ void of_unregister_driver(struct of_plat
 }
 
 
-static ssize_t dev_show_devspec(struct device *dev, char *buf)
+static ssize_t dev_show_devspec(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct of_device *ofdev;
 
diff --git a/arch/ppc64/kernel/pSeries_lpar.c b/arch/ppc64/kernel/pSeries_lpar.c
--- a/arch/ppc64/kernel/pSeries_lpar.c
+++ b/arch/ppc64/kernel/pSeries_lpar.c
@@ -277,31 +277,20 @@ void vpa_init(int cpu)
 
 long pSeries_lpar_hpte_insert(unsigned long hpte_group,
 			      unsigned long va, unsigned long prpn,
-			      int secondary, unsigned long hpteflags,
-			      int bolted, int large)
+			      unsigned long vflags, unsigned long rflags)
 {
 	unsigned long arpn = physRpn_to_absRpn(prpn);
 	unsigned long lpar_rc;
 	unsigned long flags;
 	unsigned long slot;
-	HPTE lhpte;
+	unsigned long hpte_v, hpte_r;
 	unsigned long dummy0, dummy1;
 
-	/* Fill in the local HPTE with absolute rpn, avpn and flags */
-	lhpte.dw1.dword1      = 0;
-	lhpte.dw1.dw1.rpn     = arpn;
-	lhpte.dw1.flags.flags = hpteflags;
-
-	lhpte.dw0.dword0      = 0;
-	lhpte.dw0.dw0.avpn    = va >> 23;
-	lhpte.dw0.dw0.h       = secondary;
-	lhpte.dw0.dw0.bolted  = bolted;
-	lhpte.dw0.dw0.v       = 1;
-
-	if (large) {
-		lhpte.dw0.dw0.l = 1;
-		lhpte.dw0.dw0.avpn &= ~0x1UL;
-	}
+	hpte_v = ((va >> 23) << HPTE_V_AVPN_SHIFT) | vflags | HPTE_V_VALID;
+	if (vflags & HPTE_V_LARGE)
+		hpte_v &= ~(1UL << HPTE_V_AVPN_SHIFT);
+
+	hpte_r = (arpn << HPTE_R_RPN_SHIFT) | rflags;
 
 	/* Now fill in the actual HPTE */
 	/* Set CEC cookie to 0         */
@@ -312,11 +301,11 @@ long pSeries_lpar_hpte_insert(unsigned l
 	flags = 0;
 
 	/* XXX why is this here? - Anton */
-	if (hpteflags & (_PAGE_GUARDED|_PAGE_NO_CACHE))
-		lhpte.dw1.flags.flags &= ~_PAGE_COHERENT;
+	if (rflags & (_PAGE_GUARDED|_PAGE_NO_CACHE))
+		hpte_r &= ~_PAGE_COHERENT;
 
-	lpar_rc = plpar_hcall(H_ENTER, flags, hpte_group, lhpte.dw0.dword0,
-			      lhpte.dw1.dword1, &slot, &dummy0, &dummy1);
+	lpar_rc = plpar_hcall(H_ENTER, flags, hpte_group, hpte_v,
+			      hpte_r, &slot, &dummy0, &dummy1);
 
 	if (unlikely(lpar_rc == H_PTEG_Full))
 		return -1;
@@ -332,7 +321,7 @@ long pSeries_lpar_hpte_insert(unsigned l
 	/* Because of iSeries, we have to pass down the secondary
 	 * bucket bit here as well
 	 */
-	return (slot & 7) | (secondary << 3);
+	return (slot & 7) | (!!(vflags & HPTE_V_SECONDARY) << 3);
 }
 
 static DEFINE_SPINLOCK(pSeries_lpar_tlbie_lock);
@@ -427,22 +416,18 @@ static long pSeries_lpar_hpte_find(unsig
 	unsigned long hash;
 	unsigned long i, j;
 	long slot;
-	union {
-		unsigned long dword0;
-		Hpte_dword0 dw0;
-	} hpte_dw0;
-	Hpte_dword0 dw0;
+	unsigned long hpte_v;
 
 	hash = hpt_hash(vpn, 0);
 
 	for (j = 0; j < 2; j++) {
 		slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
 		for (i = 0; i < HPTES_PER_GROUP; i++) {
-			hpte_dw0.dword0 = pSeries_lpar_hpte_getword0(slot);
-			dw0 = hpte_dw0.dw0;
+			hpte_v = pSeries_lpar_hpte_getword0(slot);
 
-			if ((dw0.avpn == (vpn >> 11)) && dw0.v &&
-			    (dw0.h == j)) {
+			if ((HPTE_V_AVPN_VAL(hpte_v) == (vpn >> 11))
+			    && (hpte_v & HPTE_V_VALID)
+			    && (!!(hpte_v & HPTE_V_SECONDARY) == j)) {
 				/* HPTE matches */
 				if (j)
 					slot = -slot;
diff --git a/arch/ppc64/kernel/pSeries_pci.c b/arch/ppc64/kernel/pSeries_pci.c
--- a/arch/ppc64/kernel/pSeries_pci.c
+++ b/arch/ppc64/kernel/pSeries_pci.c
@@ -1,13 +1,11 @@
 /*
- * pSeries_pci.c
+ * arch/ppc64/kernel/pSeries_pci.c
  *
  * Copyright (C) 2001 Dave Engebretsen, IBM Corporation
  * Copyright (C) 2003 Anton Blanchard <anton@au.ibm.com>, IBM
  *
  * pSeries specific routines for PCI.
  * 
- * Based on code from pci.c and chrp_pci.c
- *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
@@ -23,430 +21,18 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  */
 
+#include <linux/init.h>
+#include <linux/ioport.h>
 #include <linux/kernel.h>
-#include <linux/threads.h>
 #include <linux/pci.h>
 #include <linux/string.h>
-#include <linux/init.h>
-#include <linux/bootmem.h>
 
-#include <asm/io.h>
-#include <asm/pgtable.h>
-#include <asm/irq.h>
-#include <asm/prom.h>
-#include <asm/machdep.h>
 #include <asm/pci-bridge.h>
-#include <asm/iommu.h>
-#include <asm/rtas.h>
+#include <asm/prom.h>
 
-#include "mpic.h"
 #include "pci.h"
 
-/* RTAS tokens */
-static int read_pci_config;
-static int write_pci_config;
-static int ibm_read_pci_config;
-static int ibm_write_pci_config;
-
-static int s7a_workaround;
-
-extern struct mpic *pSeries_mpic;
-
-static int config_access_valid(struct device_node *dn, int where)
-{
-	if (where < 256)
-		return 1;
-	if (where < 4096 && dn->pci_ext_config_space)
-		return 1;
-
-	return 0;
-}
-
-static int rtas_read_config(struct device_node *dn, int where, int size, u32 *val)
-{
-	int returnval = -1;
-	unsigned long buid, addr;
-	int ret;
-
-	if (!dn)
-		return PCIBIOS_DEVICE_NOT_FOUND;
-	if (!config_access_valid(dn, where))
-		return PCIBIOS_BAD_REGISTER_NUMBER;
-
-	addr = ((where & 0xf00) << 20) | (dn->busno << 16) |
-		(dn->devfn << 8) | (where & 0xff);
-	buid = dn->phb->buid;
-	if (buid) {
-		ret = rtas_call(ibm_read_pci_config, 4, 2, &returnval,
-				addr, buid >> 32, buid & 0xffffffff, size);
-	} else {
-		ret = rtas_call(read_pci_config, 2, 2, &returnval, addr, size);
-	}
-	*val = returnval;
-
-	if (ret)
-		return PCIBIOS_DEVICE_NOT_FOUND;
-
-	if (returnval == EEH_IO_ERROR_VALUE(size)
-	    && eeh_dn_check_failure (dn, NULL))
-		return PCIBIOS_DEVICE_NOT_FOUND;
-
-	return PCIBIOS_SUCCESSFUL;
-}
-
-static int rtas_pci_read_config(struct pci_bus *bus,
-				unsigned int devfn,
-				int where, int size, u32 *val)
-{
-	struct device_node *busdn, *dn;
-
-	if (bus->self)
-		busdn = pci_device_to_OF_node(bus->self);
-	else
-		busdn = bus->sysdata;	/* must be a phb */
-
-	/* Search only direct children of the bus */
-	for (dn = busdn->child; dn; dn = dn->sibling)
-		if (dn->devfn == devfn)
-			return rtas_read_config(dn, where, size, val);
-	return PCIBIOS_DEVICE_NOT_FOUND;
-}
-
-static int rtas_write_config(struct device_node *dn, int where, int size, u32 val)
-{
-	unsigned long buid, addr;
-	int ret;
-
-	if (!dn)
-		return PCIBIOS_DEVICE_NOT_FOUND;
-	if (!config_access_valid(dn, where))
-		return PCIBIOS_BAD_REGISTER_NUMBER;
-
-	addr = ((where & 0xf00) << 20) | (dn->busno << 16) |
-		(dn->devfn << 8) | (where & 0xff);
-	buid = dn->phb->buid;
-	if (buid) {
-		ret = rtas_call(ibm_write_pci_config, 5, 1, NULL, addr, buid >> 32, buid & 0xffffffff, size, (ulong) val);
-	} else {
-		ret = rtas_call(write_pci_config, 3, 1, NULL, addr, size, (ulong)val);
-	}
-
-	if (ret)
-		return PCIBIOS_DEVICE_NOT_FOUND;
-
-	return PCIBIOS_SUCCESSFUL;
-}
-
-static int rtas_pci_write_config(struct pci_bus *bus,
-				 unsigned int devfn,
-				 int where, int size, u32 val)
-{
-	struct device_node *busdn, *dn;
-
-	if (bus->self)
-		busdn = pci_device_to_OF_node(bus->self);
-	else
-		busdn = bus->sysdata;	/* must be a phb */
-
-	/* Search only direct children of the bus */
-	for (dn = busdn->child; dn; dn = dn->sibling)
-		if (dn->devfn == devfn)
-			return rtas_write_config(dn, where, size, val);
-	return PCIBIOS_DEVICE_NOT_FOUND;
-}
-
-struct pci_ops rtas_pci_ops = {
-	rtas_pci_read_config,
-	rtas_pci_write_config
-};
-
-int is_python(struct device_node *dev)
-{
-	char *model = (char *)get_property(dev, "model", NULL);
-
-	if (model && strstr(model, "Python"))
-		return 1;
-
-	return 0;
-}
-
-static int get_phb_reg_prop(struct device_node *dev,
-			    unsigned int addr_size_words,
-			    struct reg_property64 *reg)
-{
-	unsigned int *ui_ptr = NULL, len;
-
-	/* Found a PHB, now figure out where his registers are mapped. */
-	ui_ptr = (unsigned int *)get_property(dev, "reg", &len);
-	if (ui_ptr == NULL)
-		return 1;
-
-	if (addr_size_words == 1) {
-		reg->address = ((struct reg_property32 *)ui_ptr)->address;
-		reg->size    = ((struct reg_property32 *)ui_ptr)->size;
-	} else {
-		*reg = *((struct reg_property64 *)ui_ptr);
-	}
-
-	return 0;
-}
-
-static void python_countermeasures(struct device_node *dev,
-				   unsigned int addr_size_words)
-{
-	struct reg_property64 reg_struct;
-	void __iomem *chip_regs;
-	volatile u32 val;
-
-	if (get_phb_reg_prop(dev, addr_size_words, &reg_struct))
-		return;
-
-	/* Python's register file is 1 MB in size. */
-	chip_regs = ioremap(reg_struct.address & ~(0xfffffUL), 0x100000);
-
-	/* 
-	 * Firmware doesn't always clear this bit which is critical
-	 * for good performance - Anton
-	 */
-
-#define PRG_CL_RESET_VALID 0x00010000
-
-	val = in_be32(chip_regs + 0xf6030);
-	if (val & PRG_CL_RESET_VALID) {
-		printk(KERN_INFO "Python workaround: ");
-		val &= ~PRG_CL_RESET_VALID;
-		out_be32(chip_regs + 0xf6030, val);
-		/*
-		 * We must read it back for changes to
-		 * take effect
-		 */
-		val = in_be32(chip_regs + 0xf6030);
-		printk("reg0: %x\n", val);
-	}
-
-	iounmap(chip_regs);
-}
-
-void __init init_pci_config_tokens (void)
-{
-	read_pci_config = rtas_token("read-pci-config");
-	write_pci_config = rtas_token("write-pci-config");
-	ibm_read_pci_config = rtas_token("ibm,read-pci-config");
-	ibm_write_pci_config = rtas_token("ibm,write-pci-config");
-}
-
-unsigned long __devinit get_phb_buid (struct device_node *phb)
-{
-	int addr_cells;
-	unsigned int *buid_vals;
-	unsigned int len;
-	unsigned long buid;
-
-	if (ibm_read_pci_config == -1) return 0;
-
-	/* PHB's will always be children of the root node,
-	 * or so it is promised by the current firmware. */
-	if (phb->parent == NULL)
-		return 0;
-	if (phb->parent->parent)
-		return 0;
-
-	buid_vals = (unsigned int *) get_property(phb, "reg", &len);
-	if (buid_vals == NULL)
-		return 0;
-
-	addr_cells = prom_n_addr_cells(phb);
-	if (addr_cells == 1) {
-		buid = (unsigned long) buid_vals[0];
-	} else {
-		buid = (((unsigned long)buid_vals[0]) << 32UL) |
-			(((unsigned long)buid_vals[1]) & 0xffffffff);
-	}
-	return buid;
-}
-
-static int phb_set_bus_ranges(struct device_node *dev,
-			      struct pci_controller *phb)
-{
-	int *bus_range;
-	unsigned int len;
-
-	bus_range = (int *) get_property(dev, "bus-range", &len);
-	if (bus_range == NULL || len < 2 * sizeof(int)) {
-		return 1;
- 	}
- 
-	phb->first_busno =  bus_range[0];
-	phb->last_busno  =  bus_range[1];
-
-	return 0;
-}
-
-static int __devinit setup_phb(struct device_node *dev,
-			       struct pci_controller *phb,
-			       unsigned int addr_size_words)
-{
-	pci_setup_pci_controller(phb);
-
-	if (is_python(dev))
-		python_countermeasures(dev, addr_size_words);
-
-	if (phb_set_bus_ranges(dev, phb))
-		return 1;
-
-	phb->arch_data = dev;
-	phb->ops = &rtas_pci_ops;
-	phb->buid = get_phb_buid(dev);
-
-	return 0;
-}
-
-static void __devinit add_linux_pci_domain(struct device_node *dev,
-					   struct pci_controller *phb,
-					   struct property *of_prop)
-{
-	memset(of_prop, 0, sizeof(struct property));
-	of_prop->name = "linux,pci-domain";
-	of_prop->length = sizeof(phb->global_number);
-	of_prop->value = (unsigned char *)&of_prop[1];
-	memcpy(of_prop->value, &phb->global_number, sizeof(phb->global_number));
-	prom_add_property(dev, of_prop);
-}
-
-static struct pci_controller * __init alloc_phb(struct device_node *dev,
-						unsigned int addr_size_words)
-{
-	struct pci_controller *phb;
-	struct property *of_prop;
-
-	phb = alloc_bootmem(sizeof(struct pci_controller));
-	if (phb == NULL)
-		return NULL;
-
-	of_prop = alloc_bootmem(sizeof(struct property) +
-				sizeof(phb->global_number));
-	if (!of_prop)
-		return NULL;
-
-	if (setup_phb(dev, phb, addr_size_words))
-		return NULL;
-
-	add_linux_pci_domain(dev, phb, of_prop);
-
-	return phb;
-}
-
-static struct pci_controller * __devinit alloc_phb_dynamic(struct device_node *dev, unsigned int addr_size_words)
-{
-	struct pci_controller *phb;
-
-	phb = (struct pci_controller *)kmalloc(sizeof(struct pci_controller),
-					       GFP_KERNEL);
-	if (phb == NULL)
-		return NULL;
-
-	if (setup_phb(dev, phb, addr_size_words))
-		return NULL;
-
-	phb->is_dynamic = 1;
-
-	/* TODO: linux,pci-domain? */
-
- 	return phb;
-}
-
-unsigned long __init find_and_init_phbs(void)
-{
-	struct device_node *node;
-	struct pci_controller *phb;
-	unsigned int root_size_cells = 0;
-	unsigned int index;
-	unsigned int *opprop = NULL;
-	struct device_node *root = of_find_node_by_path("/");
-
-	if (ppc64_interrupt_controller == IC_OPEN_PIC) {
-		opprop = (unsigned int *)get_property(root,
-				"platform-open-pic", NULL);
-	}
-
-	root_size_cells = prom_n_size_cells(root);
-
-	index = 0;
-
-	for (node = of_get_next_child(root, NULL);
-	     node != NULL;
-	     node = of_get_next_child(root, node)) {
-		if (node->type == NULL || strcmp(node->type, "pci") != 0)
-			continue;
-
-		phb = alloc_phb(node, root_size_cells);
-		if (!phb)
-			continue;
-
-		pci_process_bridge_OF_ranges(phb, node);
-		pci_setup_phb_io(phb, index == 0);
-
-		if (ppc64_interrupt_controller == IC_OPEN_PIC && pSeries_mpic) {
-			int addr = root_size_cells * (index + 2) - 1;
-			mpic_assign_isu(pSeries_mpic, index, opprop[addr]);
-		}
-
-		index++;
-	}
-
-	of_node_put(root);
-	pci_devs_phb_init();
-
-	/*
-	 * pci_probe_only and pci_assign_all_buses can be set via properties
-	 * in chosen.
-	 */
-	if (of_chosen) {
-		int *prop;
-
-		prop = (int *)get_property(of_chosen, "linux,pci-probe-only",
-					   NULL);
-		if (prop)
-			pci_probe_only = *prop;
-
-		prop = (int *)get_property(of_chosen,
-					   "linux,pci-assign-all-buses", NULL);
-		if (prop)
-			pci_assign_all_buses = *prop;
-	}
-
-	return 0;
-}
-
-struct pci_controller * __devinit init_phb_dynamic(struct device_node *dn)
-{
-	struct device_node *root = of_find_node_by_path("/");
-	unsigned int root_size_cells = 0;
-	struct pci_controller *phb;
-	struct pci_bus *bus;
-	int primary;
-
-	root_size_cells = prom_n_size_cells(root);
-
-	primary = list_empty(&hose_list);
-	phb = alloc_phb_dynamic(dn, root_size_cells);
-	if (!phb)
-		return NULL;
-
-	pci_process_bridge_OF_ranges(phb, dn);
-
-	pci_setup_phb_io_dynamic(phb, primary);
-	of_node_put(root);
-
-	pci_devs_phb_init_dynamic(phb);
-	phb->last_busno = 0xff;
-	bus = pci_scan_bus(phb->first_busno, phb->ops, phb->arch_data);
-	phb->bus = bus;
-	phb->last_busno = bus->subordinate;
-
-	return phb;
-}
-EXPORT_SYMBOL(init_phb_dynamic);
+static int __initdata s7a_workaround = -1;
 
 #if 0
 void pcibios_name_device(struct pci_dev *dev)
@@ -474,11 +60,12 @@ void pcibios_name_device(struct pci_dev 
 DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pcibios_name_device);
 #endif
 
-static void check_s7a(void)
+static void __init check_s7a(void)
 {
 	struct device_node *root;
 	char *model;
 
+	s7a_workaround = 0;
 	root = of_find_node_by_path("/");
 	if (root) {
 		model = get_property(root, "model", NULL);
@@ -488,55 +75,23 @@ static void check_s7a(void)
 	}
 }
 
-/* RPA-specific bits for removing PHBs */
-int pcibios_remove_root_bus(struct pci_controller *phb)
+void __devinit pSeries_irq_bus_setup(struct pci_bus *bus)
 {
-	struct pci_bus *b = phb->bus;
-	struct resource *res;
-	int rc, i;
-
-	res = b->resource[0];
-	if (!res->flags) {
-		printk(KERN_ERR "%s: no IO resource for PHB %s\n", __FUNCTION__,
-				b->name);
-		return 1;
-	}
-
-	rc = unmap_bus_range(b);
-	if (rc) {
-		printk(KERN_ERR "%s: failed to unmap IO on bus %s\n",
-			__FUNCTION__, b->name);
-		return 1;
-	}
-
-	if (release_resource(res)) {
-		printk(KERN_ERR "%s: failed to release IO on bus %s\n",
-				__FUNCTION__, b->name);
-		return 1;
-	}
+	struct pci_dev *dev;
 
-	for (i = 1; i < 3; ++i) {
-		res = b->resource[i];
-		if (!res->flags && i == 0) {
-			printk(KERN_ERR "%s: no MEM resource for PHB %s\n",
-				__FUNCTION__, b->name);
-			return 1;
-		}
-		if (res->flags && release_resource(res)) {
-			printk(KERN_ERR
-			       "%s: failed to release IO %d on bus %s\n",
-				__FUNCTION__, i, b->name);
-			return 1;
+	if (s7a_workaround < 0)
+		check_s7a();
+	list_for_each_entry(dev, &bus->devices, bus_list) {
+		pci_read_irq_line(dev);
+		if (s7a_workaround) {
+			if (dev->irq > 16) {
+				dev->irq -= 3;
+				pci_write_config_byte(dev, PCI_INTERRUPT_LINE,
+					dev->irq);
+			}
 		}
 	}
-
-	list_del(&phb->list_node);
-	if (phb->is_dynamic)
-		kfree(phb);
-
-	return 0;
 }
-EXPORT_SYMBOL(pcibios_remove_root_bus);
 
 static void __init pSeries_request_regions(void)
 {
@@ -553,20 +108,6 @@ static void __init pSeries_request_regio
 
 void __init pSeries_final_fixup(void)
 {
-	struct pci_dev *dev = NULL;
-
-	check_s7a();
-
-	for_each_pci_dev(dev) {
-		pci_read_irq_line(dev);
-		if (s7a_workaround) {
-			if (dev->irq > 16) {
-				dev->irq -= 3;
-				pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
-			}
-		}
-	}
-
 	phbs_remap_io();
 	pSeries_request_regions();
 
diff --git a/arch/ppc64/kernel/pSeries_setup.c b/arch/ppc64/kernel/pSeries_setup.c
--- a/arch/ppc64/kernel/pSeries_setup.c
+++ b/arch/ppc64/kernel/pSeries_setup.c
@@ -19,6 +19,7 @@
 #undef DEBUG
 
 #include <linux/config.h>
+#include <linux/cpu.h>
 #include <linux/errno.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
@@ -71,11 +72,6 @@
 #define DBG(fmt...)
 #endif
 
-extern void pSeries_final_fixup(void);
-
-extern void pSeries_get_boot_time(struct rtc_time *rtc_time);
-extern void pSeries_get_rtc_time(struct rtc_time *rtc_time);
-extern int  pSeries_set_rtc_time(struct rtc_time *rtc_time);
 extern void find_udbg_vterm(void);
 extern void system_reset_fwnmi(void);	/* from head.S */
 extern void machine_check_fwnmi(void);	/* from head.S */
@@ -84,12 +80,12 @@ extern void generic_find_legacy_serial_p
 
 int fwnmi_active;  /* TRUE if an FWNMI handler is present */
 
-extern unsigned long ppc_proc_freq;
-extern unsigned long ppc_tb_freq;
-
 extern void pSeries_system_reset_exception(struct pt_regs *regs);
 extern int pSeries_machine_check_exception(struct pt_regs *regs);
 
+static int pseries_shared_idle(void);
+static int pseries_dedicated_idle(void);
+
 static volatile void __iomem * chrp_int_ack_special;
 struct mpic *pSeries_mpic;
 
@@ -195,14 +191,16 @@ static void __init pSeries_setup_arch(vo
 {
 	/* Fixup ppc_md depending on the type of interrupt controller */
 	if (ppc64_interrupt_controller == IC_OPEN_PIC) {
-		ppc_md.init_IRQ       = pSeries_init_mpic; 
+		ppc_md.init_IRQ       = pSeries_init_mpic;
 		ppc_md.get_irq        = mpic_get_irq;
+	 	ppc_md.cpu_irq_down   = mpic_teardown_this_cpu;
 		/* Allocate the mpic now, so that find_and_init_phbs() can
 		 * fill the ISUs */
 		pSeries_setup_mpic();
 	} else {
 		ppc_md.init_IRQ       = xics_init_IRQ;
 		ppc_md.get_irq        = xics_get_irq;
+		ppc_md.cpu_irq_down   = xics_teardown_cpu;
 	}
 
 #ifdef CONFIG_SMP
@@ -235,6 +233,20 @@ static void __init pSeries_setup_arch(vo
 
 	if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR)
 		vpa_init(boot_cpuid);
+
+	/* Choose an idle loop */
+	if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR) {
+		if (get_paca()->lppaca.shared_proc) {
+			printk(KERN_INFO "Using shared processor idle loop\n");
+			ppc_md.idle_loop = pseries_shared_idle;
+		} else {
+			printk(KERN_INFO "Using dedicated idle loop\n");
+			ppc_md.idle_loop = pseries_dedicated_idle;
+		}
+	} else {
+		printk(KERN_INFO "Using default idle loop\n");
+		ppc_md.idle_loop = default_idle;
+	}
 }
 
 static int __init pSeries_init_panel(void)
@@ -381,171 +393,6 @@ static void __init pSeries_init_early(vo
 }
 
 
-static void pSeries_progress(char *s, unsigned short hex)
-{
-	struct device_node *root;
-	int width, *p;
-	char *os;
-	static int display_character, set_indicator;
-	static int max_width;
-	static DEFINE_SPINLOCK(progress_lock);
-	static int pending_newline = 0;  /* did last write end with unprinted newline? */
-
-	if (!rtas.base)
-		return;
-
-	if (max_width == 0) {
-		if ((root = find_path_device("/rtas")) &&
-		     (p = (unsigned int *)get_property(root,
-						       "ibm,display-line-length",
-						       NULL)))
-			max_width = *p;
-		else
-			max_width = 0x10;
-		display_character = rtas_token("display-character");
-		set_indicator = rtas_token("set-indicator");
-	}
-
-	if (display_character == RTAS_UNKNOWN_SERVICE) {
-		/* use hex display if available */
-		if (set_indicator != RTAS_UNKNOWN_SERVICE)
-			rtas_call(set_indicator, 3, 1, NULL, 6, 0, hex);
-		return;
-	}
-
-	spin_lock(&progress_lock);
-
-	/*
-	 * Last write ended with newline, but we didn't print it since
-	 * it would just clear the bottom line of output. Print it now
-	 * instead.
-	 *
-	 * If no newline is pending, print a CR to start output at the
-	 * beginning of the line.
-	 */
-	if (pending_newline) {
-		rtas_call(display_character, 1, 1, NULL, '\r');
-		rtas_call(display_character, 1, 1, NULL, '\n');
-		pending_newline = 0;
-	} else {
-		rtas_call(display_character, 1, 1, NULL, '\r');
-	}
- 
-	width = max_width;
-	os = s;
-	while (*os) {
-		if (*os == '\n' || *os == '\r') {
-			/* Blank to end of line. */
-			while (width-- > 0)
-				rtas_call(display_character, 1, 1, NULL, ' ');
- 
-			/* If newline is the last character, save it
-			 * until next call to avoid bumping up the
-			 * display output.
-			 */
-			if (*os == '\n' && !os[1]) {
-				pending_newline = 1;
-				spin_unlock(&progress_lock);
-				return;
-			}
- 
-			/* RTAS wants CR-LF, not just LF */
- 
-			if (*os == '\n') {
-				rtas_call(display_character, 1, 1, NULL, '\r');
-				rtas_call(display_character, 1, 1, NULL, '\n');
-			} else {
-				/* CR might be used to re-draw a line, so we'll
-				 * leave it alone and not add LF.
-				 */
-				rtas_call(display_character, 1, 1, NULL, *os);
-			}
- 
-			width = max_width;
-		} else {
-			width--;
-			rtas_call(display_character, 1, 1, NULL, *os);
-		}
- 
-		os++;
- 
-		/* if we overwrite the screen length */
-		if (width <= 0)
-			while ((*os != 0) && (*os != '\n') && (*os != '\r'))
-				os++;
-	}
- 
-	/* Blank to end of line. */
-	while (width-- > 0)
-		rtas_call(display_character, 1, 1, NULL, ' ');
-
-	spin_unlock(&progress_lock);
-}
-
-extern void setup_default_decr(void);
-
-/* Some sane defaults: 125 MHz timebase, 1GHz processor */
-#define DEFAULT_TB_FREQ		125000000UL
-#define DEFAULT_PROC_FREQ	(DEFAULT_TB_FREQ * 8)
-
-static void __init pSeries_calibrate_decr(void)
-{
-	struct device_node *cpu;
-	struct div_result divres;
-	unsigned int *fp;
-	int node_found;
-
-	/*
-	 * The cpu node should have a timebase-frequency property
-	 * to tell us the rate at which the decrementer counts.
-	 */
-	cpu = of_find_node_by_type(NULL, "cpu");
-
-	ppc_tb_freq = DEFAULT_TB_FREQ;		/* hardcoded default */
-	node_found = 0;
-	if (cpu != 0) {
-		fp = (unsigned int *)get_property(cpu, "timebase-frequency",
-						  NULL);
-		if (fp != 0) {
-			node_found = 1;
-			ppc_tb_freq = *fp;
-		}
-	}
-	if (!node_found)
-		printk(KERN_ERR "WARNING: Estimating decrementer frequency "
-				"(not found)\n");
-
-	ppc_proc_freq = DEFAULT_PROC_FREQ;
-	node_found = 0;
-	if (cpu != 0) {
-		fp = (unsigned int *)get_property(cpu, "clock-frequency",
-						  NULL);
-		if (fp != 0) {
-			node_found = 1;
-			ppc_proc_freq = *fp;
-		}
-	}
-	if (!node_found)
-		printk(KERN_ERR "WARNING: Estimating processor frequency "
-				"(not found)\n");
-
-	of_node_put(cpu);
-
-	printk(KERN_INFO "time_init: decrementer frequency = %lu.%.6lu MHz\n",
-	       ppc_tb_freq/1000000, ppc_tb_freq%1000000);
-	printk(KERN_INFO "time_init: processor frequency   = %lu.%.6lu MHz\n",
-	       ppc_proc_freq/1000000, ppc_proc_freq%1000000);
-
-	tb_ticks_per_jiffy = ppc_tb_freq / HZ;
-	tb_ticks_per_sec = tb_ticks_per_jiffy * HZ;
-	tb_ticks_per_usec = ppc_tb_freq / 1000000;
-	tb_to_us = mulhwu_scale_factor(ppc_tb_freq, 1000000);
-	div128_by_32(1024*1024, 0, tb_ticks_per_sec, &divres);
-	tb_to_xs = divres.result_low;
-
-	setup_default_decr();
-}
-
 static int pSeries_check_legacy_ioport(unsigned int baseport)
 {
 	struct device_node *np;
@@ -589,6 +436,144 @@ static int __init pSeries_probe(int plat
 	return 1;
 }
 
+DECLARE_PER_CPU(unsigned long, smt_snooze_delay);
+
+static inline void dedicated_idle_sleep(unsigned int cpu)
+{
+	struct paca_struct *ppaca = &paca[cpu ^ 1];
+
+	/* Only sleep if the other thread is not idle */
+	if (!(ppaca->lppaca.idle)) {
+		local_irq_disable();
+
+		/*
+		 * We are about to sleep the thread and so wont be polling any
+		 * more.
+		 */
+		clear_thread_flag(TIF_POLLING_NRFLAG);
+
+		/*
+		 * SMT dynamic mode. Cede will result in this thread going
+		 * dormant, if the partner thread is still doing work.  Thread
+		 * wakes up if partner goes idle, an interrupt is presented, or
+		 * a prod occurs.  Returning from the cede enables external
+		 * interrupts.
+		 */
+		if (!need_resched())
+			cede_processor();
+		else
+			local_irq_enable();
+	} else {
+		/*
+		 * Give the HV an opportunity at the processor, since we are
+		 * not doing any work.
+		 */
+		poll_pending();
+	}
+}
+
+static int pseries_dedicated_idle(void)
+{
+	long oldval;
+	struct paca_struct *lpaca = get_paca();
+	unsigned int cpu = smp_processor_id();
+	unsigned long start_snooze;
+	unsigned long *smt_snooze_delay = &__get_cpu_var(smt_snooze_delay);
+
+	while (1) {
+		/*
+		 * Indicate to the HV that we are idle. Now would be
+		 * a good time to find other work to dispatch.
+		 */
+		lpaca->lppaca.idle = 1;
+
+		oldval = test_and_clear_thread_flag(TIF_NEED_RESCHED);
+		if (!oldval) {
+			set_thread_flag(TIF_POLLING_NRFLAG);
+
+			start_snooze = __get_tb() +
+				*smt_snooze_delay * tb_ticks_per_usec;
+
+			while (!need_resched() && !cpu_is_offline(cpu)) {
+				ppc64_runlatch_off();
+
+				/*
+				 * Go into low thread priority and possibly
+				 * low power mode.
+				 */
+				HMT_low();
+				HMT_very_low();
+
+				if (*smt_snooze_delay != 0 &&
+				    __get_tb() > start_snooze) {
+					HMT_medium();
+					dedicated_idle_sleep(cpu);
+				}
+
+			}
+
+			HMT_medium();
+			clear_thread_flag(TIF_POLLING_NRFLAG);
+		} else {
+			set_need_resched();
+		}
+
+		lpaca->lppaca.idle = 0;
+		ppc64_runlatch_on();
+
+		schedule();
+
+		if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING)
+			cpu_die();
+	}
+}
+
+static int pseries_shared_idle(void)
+{
+	struct paca_struct *lpaca = get_paca();
+	unsigned int cpu = smp_processor_id();
+
+	while (1) {
+		/*
+		 * Indicate to the HV that we are idle. Now would be
+		 * a good time to find other work to dispatch.
+		 */
+		lpaca->lppaca.idle = 1;
+
+		while (!need_resched() && !cpu_is_offline(cpu)) {
+			local_irq_disable();
+			ppc64_runlatch_off();
+
+			/*
+			 * Yield the processor to the hypervisor.  We return if
+			 * an external interrupt occurs (which are driven prior
+			 * to returning here) or if a prod occurs from another
+			 * processor. When returning here, external interrupts
+			 * are enabled.
+			 *
+			 * Check need_resched() again with interrupts disabled
+			 * to avoid a race.
+			 */
+			if (!need_resched())
+				cede_processor();
+			else
+				local_irq_enable();
+
+			HMT_medium();
+		}
+
+		lpaca->lppaca.idle = 0;
+		ppc64_runlatch_on();
+
+		schedule();
+
+		if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING)
+			cpu_die();
+	}
+
+	return 0;
+}
+
 struct machdep_calls __initdata pSeries_md = {
 	.probe			= pSeries_probe,
 	.setup_arch		= pSeries_setup_arch,
@@ -596,16 +581,17 @@ struct machdep_calls __initdata pSeries_
 	.get_cpuinfo		= pSeries_get_cpuinfo,
 	.log_error		= pSeries_log_error,
 	.pcibios_fixup		= pSeries_final_fixup,
+	.irq_bus_setup		= pSeries_irq_bus_setup,
 	.restart		= rtas_restart,
 	.power_off		= rtas_power_off,
 	.halt			= rtas_halt,
 	.panic			= rtas_os_term,
 	.cpu_die		= pSeries_mach_cpu_die,
-	.get_boot_time		= pSeries_get_boot_time,
-	.get_rtc_time		= pSeries_get_rtc_time,
-	.set_rtc_time		= pSeries_set_rtc_time,
-	.calibrate_decr		= pSeries_calibrate_decr,
-	.progress		= pSeries_progress,
+	.get_boot_time		= rtas_get_boot_time,
+	.get_rtc_time		= rtas_get_rtc_time,
+	.set_rtc_time		= rtas_set_rtc_time,
+	.calibrate_decr		= generic_calibrate_decr,
+	.progress		= rtas_progress,
 	.check_legacy_ioport	= pSeries_check_legacy_ioport,
 	.system_reset_exception = pSeries_system_reset_exception,
 	.machine_check_exception = pSeries_machine_check_exception,
diff --git a/arch/ppc64/kernel/pSeries_smp.c b/arch/ppc64/kernel/pSeries_smp.c
--- a/arch/ppc64/kernel/pSeries_smp.c
+++ b/arch/ppc64/kernel/pSeries_smp.c
@@ -1,5 +1,5 @@
 /*
- * SMP support for pSeries machines.
+ * SMP support for pSeries and BPA machines.
  *
  * Dave Engebretsen, Peter Bergner, and
  * Mike Corrigan {engebret|bergner|mikec}@us.ibm.com
@@ -47,6 +47,7 @@
 #include <asm/pSeries_reconfig.h>
 
 #include "mpic.h"
+#include "bpa_iic.h"
 
 #ifdef DEBUG
 #define DBG(fmt...) udbg_printf(fmt)
@@ -92,10 +93,13 @@ static int query_cpu_stopped(unsigned in
 
 int pSeries_cpu_disable(void)
 {
+	int cpu = smp_processor_id();
+
+	cpu_clear(cpu, cpu_online_map);
 	systemcfg->processorCount--;
 
 	/*fix boot_cpuid here*/
-	if (smp_processor_id() == boot_cpuid)
+	if (cpu == boot_cpuid)
 		boot_cpuid = any_online_cpu(cpu_online_map);
 
 	/* FIXME: abstract this to not be platform specific later on */
@@ -286,6 +290,7 @@ static inline int __devinit smp_startup_
 	return 1;
 }
 
+#ifdef CONFIG_XICS
 static inline void smp_xics_do_message(int cpu, int msg)
 {
 	set_bit(msg, &xics_ipi_message[cpu].value);
@@ -327,6 +332,37 @@ static void __devinit smp_xics_setup_cpu
 	cpu_clear(cpu, of_spin_map);
 
 }
+#endif /* CONFIG_XICS */
+#ifdef CONFIG_BPA_IIC
+static void smp_iic_message_pass(int target, int msg)
+{
+	unsigned int i;
+
+	if (target < NR_CPUS) {
+		iic_cause_IPI(target, msg);
+	} else {
+		for_each_online_cpu(i) {
+			if (target == MSG_ALL_BUT_SELF
+			    && i == smp_processor_id())
+				continue;
+			iic_cause_IPI(i, msg);
+		}
+	}
+}
+
+static int __init smp_iic_probe(void)
+{
+	iic_request_IPIs();
+
+	return cpus_weight(cpu_possible_map);
+}
+
+static void __devinit smp_iic_setup_cpu(int cpu)
+{
+	if (cpu != boot_cpuid)
+		iic_setup_cpu();
+}
+#endif /* CONFIG_BPA_IIC */
 
 static DEFINE_SPINLOCK(timebase_lock);
 static unsigned long timebase = 0;
@@ -375,20 +411,21 @@ static int smp_pSeries_cpu_bootable(unsi
 	 * cpus are assumed to be secondary threads.
 	 */
 	if (system_state < SYSTEM_RUNNING &&
-	    cur_cpu_spec->cpu_features & CPU_FTR_SMT &&
+	    cpu_has_feature(CPU_FTR_SMT) &&
 	    !smt_enabled_at_boot && nr % 2 != 0)
 		return 0;
 
 	return 1;
 }
-
+#ifdef CONFIG_MPIC
 static struct smp_ops_t pSeries_mpic_smp_ops = {
 	.message_pass	= smp_mpic_message_pass,
 	.probe		= smp_mpic_probe,
 	.kick_cpu	= smp_pSeries_kick_cpu,
 	.setup_cpu	= smp_mpic_setup_cpu,
 };
-
+#endif
+#ifdef CONFIG_XICS
 static struct smp_ops_t pSeries_xics_smp_ops = {
 	.message_pass	= smp_xics_message_pass,
 	.probe		= smp_xics_probe,
@@ -396,6 +433,16 @@ static struct smp_ops_t pSeries_xics_smp
 	.setup_cpu	= smp_xics_setup_cpu,
 	.cpu_bootable	= smp_pSeries_cpu_bootable,
 };
+#endif
+#ifdef CONFIG_BPA_IIC
+static struct smp_ops_t bpa_iic_smp_ops = {
+	.message_pass	= smp_iic_message_pass,
+	.probe		= smp_iic_probe,
+	.kick_cpu	= smp_pSeries_kick_cpu,
+	.setup_cpu	= smp_iic_setup_cpu,
+	.cpu_bootable	= smp_pSeries_cpu_bootable,
+};
+#endif
 
 /* This is called very early */
 void __init smp_init_pSeries(void)
@@ -404,10 +451,25 @@ void __init smp_init_pSeries(void)
 
 	DBG(" -> smp_init_pSeries()\n");
 
-	if (ppc64_interrupt_controller == IC_OPEN_PIC)
+	switch (ppc64_interrupt_controller) {
+#ifdef CONFIG_MPIC
+	case IC_OPEN_PIC:
 		smp_ops = &pSeries_mpic_smp_ops;
-	else
+		break;
+#endif
+#ifdef CONFIG_XICS
+	case IC_PPC_XIC:
 		smp_ops = &pSeries_xics_smp_ops;
+		break;
+#endif
+#ifdef CONFIG_BPA_IIC
+	case IC_BPA_IIC:
+		smp_ops = &bpa_iic_smp_ops;
+		break;
+#endif
+	default:
+		panic("Invalid interrupt controller");
+	}
 
 #ifdef CONFIG_HOTPLUG_CPU
 	smp_ops->cpu_disable = pSeries_cpu_disable;
@@ -419,8 +481,8 @@ void __init smp_init_pSeries(void)
 #endif
 
 	/* Mark threads which are still spinning in hold loops. */
-	if (cur_cpu_spec->cpu_features & CPU_FTR_SMT)
-		for_each_present_cpu(i) {
+	if (cpu_has_feature(CPU_FTR_SMT)) {
+		for_each_present_cpu(i) { 
 			if (i % 2 == 0)
 				/*
 				 * Even-numbered logical cpus correspond to
@@ -428,8 +490,9 @@ void __init smp_init_pSeries(void)
 				 */
 				cpu_set(i, of_spin_map);
 		}
-	else
+	} else {
 		of_spin_map = cpu_present_map;
+	}
 
 	cpu_clear(boot_cpuid, of_spin_map);
 
diff --git a/arch/ppc64/kernel/pacaData.c b/arch/ppc64/kernel/pacaData.c
--- a/arch/ppc64/kernel/pacaData.c
+++ b/arch/ppc64/kernel/pacaData.c
@@ -42,21 +42,7 @@ extern unsigned long __toc_start;
  * processors.  The processor VPD array needs one entry per physical
  * processor (not thread).
  */
-#ifdef CONFIG_PPC_ISERIES
-#define EXTRA_INITS(number, lpq)					    \
-	.lppaca_ptr = &paca[number].lppaca,				    \
-	.lpqueue_ptr = (lpq),		/* &xItLpQueue, */		    \
-	.reg_save_ptr = &paca[number].reg_save,				    \
-	.reg_save = {							    \
-		.xDesc = 0xd397d9e2,	/* "LpRS" */			    \
-		.xSize = sizeof(struct ItLpRegSave)			    \
-	},
-#else
-#define EXTRA_INITS(number, lpq)
-#endif
-
-#define PACAINITDATA(number,start,lpq,asrr,asrv)			    \
-{									    \
+#define PACA_INIT_COMMON(number, start, asrr, asrv)			    \
 	.lock_token = 0x8000,						    \
 	.paca_index = (number),		/* Paca Index */		    \
 	.default_decr = 0x00ff0000,	/* Initial Decr */		    \
@@ -74,147 +60,79 @@ extern unsigned long __toc_start;
 		.end_of_quantum = 0xfffffffffffffffful,			    \
 		.slb_count = 64,					    \
 	},								    \
-	EXTRA_INITS((number), (lpq))					    \
-}
 
-struct paca_struct paca[] = {
 #ifdef CONFIG_PPC_ISERIES
-	PACAINITDATA( 0, 1, &xItLpQueue, 0, STAB0_VIRT_ADDR),
+#define PACA_INIT_ISERIES(number)					    \
+	.lppaca_ptr = &paca[number].lppaca,				    \
+	.reg_save_ptr = &paca[number].reg_save,				    \
+	.reg_save = {							    \
+		.xDesc = 0xd397d9e2,	/* "LpRS" */			    \
+		.xSize = sizeof(struct ItLpRegSave)			    \
+	}
+
+#define PACA_INIT(number)						    \
+{									    \
+	PACA_INIT_COMMON(number, 0, 0, 0)				    \
+	PACA_INIT_ISERIES(number)					    \
+}
+
+#define BOOTCPU_PACA_INIT(number)					    \
+{									    \
+	PACA_INIT_COMMON(number, 1, 0, STAB0_VIRT_ADDR)			    \
+	PACA_INIT_ISERIES(number)					    \
+}
+
 #else
-	PACAINITDATA( 0, 1, NULL, STAB0_PHYS_ADDR, STAB0_VIRT_ADDR),
+#define PACA_INIT(number)						    \
+{									    \
+	PACA_INIT_COMMON(number, 0, 0, 0)				    \
+}
+
+#define BOOTCPU_PACA_INIT(number)					    \
+{									    \
+	PACA_INIT_COMMON(number, 1, STAB0_PHYS_ADDR, STAB0_VIRT_ADDR)	    \
+}
 #endif
+
+struct paca_struct paca[] = {
+	BOOTCPU_PACA_INIT(0),
 #if NR_CPUS > 1
-	PACAINITDATA( 1, 0, NULL, 0, 0),
-	PACAINITDATA( 2, 0, NULL, 0, 0),
-	PACAINITDATA( 3, 0, NULL, 0, 0),
+	PACA_INIT(  1), PACA_INIT(  2), PACA_INIT(  3),
 #if NR_CPUS > 4
-	PACAINITDATA( 4, 0, NULL, 0, 0),
-	PACAINITDATA( 5, 0, NULL, 0, 0),
-	PACAINITDATA( 6, 0, NULL, 0, 0),
-	PACAINITDATA( 7, 0, NULL, 0, 0),
+	PACA_INIT(  4), PACA_INIT(  5), PACA_INIT(  6), PACA_INIT(  7),
 #if NR_CPUS > 8
-	PACAINITDATA( 8, 0, NULL, 0, 0),
-	PACAINITDATA( 9, 0, NULL, 0, 0),
-	PACAINITDATA(10, 0, NULL, 0, 0),
-	PACAINITDATA(11, 0, NULL, 0, 0),
-	PACAINITDATA(12, 0, NULL, 0, 0),
-	PACAINITDATA(13, 0, NULL, 0, 0),
-	PACAINITDATA(14, 0, NULL, 0, 0),
-	PACAINITDATA(15, 0, NULL, 0, 0),
-	PACAINITDATA(16, 0, NULL, 0, 0),
-	PACAINITDATA(17, 0, NULL, 0, 0),
-	PACAINITDATA(18, 0, NULL, 0, 0),
-	PACAINITDATA(19, 0, NULL, 0, 0),
-	PACAINITDATA(20, 0, NULL, 0, 0),
-	PACAINITDATA(21, 0, NULL, 0, 0),
-	PACAINITDATA(22, 0, NULL, 0, 0),
-	PACAINITDATA(23, 0, NULL, 0, 0),
-	PACAINITDATA(24, 0, NULL, 0, 0),
-	PACAINITDATA(25, 0, NULL, 0, 0),
-	PACAINITDATA(26, 0, NULL, 0, 0),
-	PACAINITDATA(27, 0, NULL, 0, 0),
-	PACAINITDATA(28, 0, NULL, 0, 0),
-	PACAINITDATA(29, 0, NULL, 0, 0),
-	PACAINITDATA(30, 0, NULL, 0, 0),
-	PACAINITDATA(31, 0, NULL, 0, 0),
+	PACA_INIT(  8), PACA_INIT(  9), PACA_INIT( 10), PACA_INIT( 11),
+	PACA_INIT( 12), PACA_INIT( 13), PACA_INIT( 14), PACA_INIT( 15),
+	PACA_INIT( 16), PACA_INIT( 17), PACA_INIT( 18), PACA_INIT( 19),
+	PACA_INIT( 20), PACA_INIT( 21), PACA_INIT( 22), PACA_INIT( 23),
+	PACA_INIT( 24), PACA_INIT( 25), PACA_INIT( 26), PACA_INIT( 27),
+	PACA_INIT( 28), PACA_INIT( 29), PACA_INIT( 30), PACA_INIT( 31),
 #if NR_CPUS > 32
-	PACAINITDATA(32, 0, NULL, 0, 0),
-	PACAINITDATA(33, 0, NULL, 0, 0),
-	PACAINITDATA(34, 0, NULL, 0, 0),
-	PACAINITDATA(35, 0, NULL, 0, 0),
-	PACAINITDATA(36, 0, NULL, 0, 0),
-	PACAINITDATA(37, 0, NULL, 0, 0),
-	PACAINITDATA(38, 0, NULL, 0, 0),
-	PACAINITDATA(39, 0, NULL, 0, 0),
-	PACAINITDATA(40, 0, NULL, 0, 0),
-	PACAINITDATA(41, 0, NULL, 0, 0),
-	PACAINITDATA(42, 0, NULL, 0, 0),
-	PACAINITDATA(43, 0, NULL, 0, 0),
-	PACAINITDATA(44, 0, NULL, 0, 0),
-	PACAINITDATA(45, 0, NULL, 0, 0),
-	PACAINITDATA(46, 0, NULL, 0, 0),
-	PACAINITDATA(47, 0, NULL, 0, 0),
-	PACAINITDATA(48, 0, NULL, 0, 0),
-	PACAINITDATA(49, 0, NULL, 0, 0),
-	PACAINITDATA(50, 0, NULL, 0, 0),
-	PACAINITDATA(51, 0, NULL, 0, 0),
-	PACAINITDATA(52, 0, NULL, 0, 0),
-	PACAINITDATA(53, 0, NULL, 0, 0),
-	PACAINITDATA(54, 0, NULL, 0, 0),
-	PACAINITDATA(55, 0, NULL, 0, 0),
-	PACAINITDATA(56, 0, NULL, 0, 0),
-	PACAINITDATA(57, 0, NULL, 0, 0),
-	PACAINITDATA(58, 0, NULL, 0, 0),
-	PACAINITDATA(59, 0, NULL, 0, 0),
-	PACAINITDATA(60, 0, NULL, 0, 0),
-	PACAINITDATA(61, 0, NULL, 0, 0),
-	PACAINITDATA(62, 0, NULL, 0, 0),
-	PACAINITDATA(63, 0, NULL, 0, 0),
+	PACA_INIT( 32), PACA_INIT( 33), PACA_INIT( 34), PACA_INIT( 35),
+	PACA_INIT( 36), PACA_INIT( 37), PACA_INIT( 38), PACA_INIT( 39),
+	PACA_INIT( 40), PACA_INIT( 41), PACA_INIT( 42), PACA_INIT( 43),
+	PACA_INIT( 44), PACA_INIT( 45), PACA_INIT( 46), PACA_INIT( 47),
+	PACA_INIT( 48), PACA_INIT( 49), PACA_INIT( 50), PACA_INIT( 51),
+	PACA_INIT( 52), PACA_INIT( 53), PACA_INIT( 54), PACA_INIT( 55),
+	PACA_INIT( 56), PACA_INIT( 57), PACA_INIT( 58), PACA_INIT( 59),
+	PACA_INIT( 60), PACA_INIT( 61), PACA_INIT( 62), PACA_INIT( 63),
 #if NR_CPUS > 64
-	PACAINITDATA(64, 0, NULL, 0, 0),
-	PACAINITDATA(65, 0, NULL, 0, 0),
-	PACAINITDATA(66, 0, NULL, 0, 0),
-	PACAINITDATA(67, 0, NULL, 0, 0),
-	PACAINITDATA(68, 0, NULL, 0, 0),
-	PACAINITDATA(69, 0, NULL, 0, 0),
-	PACAINITDATA(70, 0, NULL, 0, 0),
-	PACAINITDATA(71, 0, NULL, 0, 0),
-	PACAINITDATA(72, 0, NULL, 0, 0),
-	PACAINITDATA(73, 0, NULL, 0, 0),
-	PACAINITDATA(74, 0, NULL, 0, 0),
-	PACAINITDATA(75, 0, NULL, 0, 0),
-	PACAINITDATA(76, 0, NULL, 0, 0),
-	PACAINITDATA(77, 0, NULL, 0, 0),
-	PACAINITDATA(78, 0, NULL, 0, 0),
-	PACAINITDATA(79, 0, NULL, 0, 0),
-	PACAINITDATA(80, 0, NULL, 0, 0),
-	PACAINITDATA(81, 0, NULL, 0, 0),
-	PACAINITDATA(82, 0, NULL, 0, 0),
-	PACAINITDATA(83, 0, NULL, 0, 0),
-	PACAINITDATA(84, 0, NULL, 0, 0),
-	PACAINITDATA(85, 0, NULL, 0, 0),
-	PACAINITDATA(86, 0, NULL, 0, 0),
-	PACAINITDATA(87, 0, NULL, 0, 0),
-	PACAINITDATA(88, 0, NULL, 0, 0),
-	PACAINITDATA(89, 0, NULL, 0, 0),
-	PACAINITDATA(90, 0, NULL, 0, 0),
-	PACAINITDATA(91, 0, NULL, 0, 0),
-	PACAINITDATA(92, 0, NULL, 0, 0),
-	PACAINITDATA(93, 0, NULL, 0, 0),
-	PACAINITDATA(94, 0, NULL, 0, 0),
-	PACAINITDATA(95, 0, NULL, 0, 0),
-	PACAINITDATA(96, 0, NULL, 0, 0),
-	PACAINITDATA(97, 0, NULL, 0, 0),
-	PACAINITDATA(98, 0, NULL, 0, 0),
-	PACAINITDATA(99, 0, NULL, 0, 0),
-	PACAINITDATA(100, 0, NULL, 0, 0),
-	PACAINITDATA(101, 0, NULL, 0, 0),
-	PACAINITDATA(102, 0, NULL, 0, 0),
-	PACAINITDATA(103, 0, NULL, 0, 0),
-	PACAINITDATA(104, 0, NULL, 0, 0),
-	PACAINITDATA(105, 0, NULL, 0, 0),
-	PACAINITDATA(106, 0, NULL, 0, 0),
-	PACAINITDATA(107, 0, NULL, 0, 0),
-	PACAINITDATA(108, 0, NULL, 0, 0),
-	PACAINITDATA(109, 0, NULL, 0, 0),
-	PACAINITDATA(110, 0, NULL, 0, 0),
-	PACAINITDATA(111, 0, NULL, 0, 0),
-	PACAINITDATA(112, 0, NULL, 0, 0),
-	PACAINITDATA(113, 0, NULL, 0, 0),
-	PACAINITDATA(114, 0, NULL, 0, 0),
-	PACAINITDATA(115, 0, NULL, 0, 0),
-	PACAINITDATA(116, 0, NULL, 0, 0),
-	PACAINITDATA(117, 0, NULL, 0, 0),
-	PACAINITDATA(118, 0, NULL, 0, 0),
-	PACAINITDATA(119, 0, NULL, 0, 0),
-	PACAINITDATA(120, 0, NULL, 0, 0),
-	PACAINITDATA(121, 0, NULL, 0, 0),
-	PACAINITDATA(122, 0, NULL, 0, 0),
-	PACAINITDATA(123, 0, NULL, 0, 0),
-	PACAINITDATA(124, 0, NULL, 0, 0),
-	PACAINITDATA(125, 0, NULL, 0, 0),
-	PACAINITDATA(126, 0, NULL, 0, 0),
-	PACAINITDATA(127, 0, NULL, 0, 0),
+	PACA_INIT( 64), PACA_INIT( 65), PACA_INIT( 66), PACA_INIT( 67),
+	PACA_INIT( 68), PACA_INIT( 69), PACA_INIT( 70), PACA_INIT( 71),
+	PACA_INIT( 72), PACA_INIT( 73), PACA_INIT( 74), PACA_INIT( 75),
+	PACA_INIT( 76), PACA_INIT( 77), PACA_INIT( 78), PACA_INIT( 79),
+	PACA_INIT( 80), PACA_INIT( 81), PACA_INIT( 82), PACA_INIT( 83),
+	PACA_INIT( 84), PACA_INIT( 85), PACA_INIT( 86), PACA_INIT( 87),
+	PACA_INIT( 88), PACA_INIT( 89), PACA_INIT( 90), PACA_INIT( 91),
+	PACA_INIT( 92), PACA_INIT( 93), PACA_INIT( 94), PACA_INIT( 95),
+	PACA_INIT( 96), PACA_INIT( 97), PACA_INIT( 98), PACA_INIT( 99),
+	PACA_INIT(100), PACA_INIT(101), PACA_INIT(102), PACA_INIT(103),
+	PACA_INIT(104), PACA_INIT(105), PACA_INIT(106), PACA_INIT(107),
+	PACA_INIT(108), PACA_INIT(109), PACA_INIT(110), PACA_INIT(111),
+	PACA_INIT(112), PACA_INIT(113), PACA_INIT(114), PACA_INIT(115),
+	PACA_INIT(116), PACA_INIT(117), PACA_INIT(118), PACA_INIT(119),
+	PACA_INIT(120), PACA_INIT(121), PACA_INIT(122), PACA_INIT(123),
+	PACA_INIT(124), PACA_INIT(125), PACA_INIT(126), PACA_INIT(127),
 #endif
 #endif
 #endif
diff --git a/arch/ppc64/kernel/pci.c b/arch/ppc64/kernel/pci.c
--- a/arch/ppc64/kernel/pci.c
+++ b/arch/ppc64/kernel/pci.c
@@ -108,8 +108,28 @@ void  pcibios_resource_to_bus(struct pci
 	region->end = res->end - offset;
 }
 
+void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
+			      struct pci_bus_region *region)
+{
+	unsigned long offset = 0;
+	struct pci_controller *hose = pci_bus_to_host(dev->bus);
+
+	if (!hose)
+		return;
+
+	if (res->flags & IORESOURCE_IO)
+	        offset = (unsigned long)hose->io_base_virt - pci_io_base;
+
+	if (res->flags & IORESOURCE_MEM)
+		offset = hose->pci_mem_offset;
+
+	res->start = region->start + offset;
+	res->end = region->end + offset;
+}
+
 #ifdef CONFIG_HOTPLUG
 EXPORT_SYMBOL(pcibios_resource_to_bus);
+EXPORT_SYMBOL(pcibios_bus_to_resource);
 #endif
 
 /*
@@ -351,7 +371,7 @@ static struct resource *__pci_mmap_make_
 		*offset += hose->pci_mem_offset;
 		res_bit = IORESOURCE_MEM;
 	} else {
-		io_offset = (unsigned long)hose->io_base_virt;
+		io_offset = (unsigned long)hose->io_base_virt - pci_io_base;
 		*offset += io_offset;
 		res_bit = IORESOURCE_IO;
 	}
@@ -378,7 +398,7 @@ static struct resource *__pci_mmap_make_
 
 		/* found it! construct the final physical address */
 		if (mmap_state == pci_mmap_io)
-			*offset += hose->io_base_phys - io_offset;
+		       	*offset += hose->io_base_phys - io_offset;
 		return rp;
 	}
 
@@ -507,7 +527,7 @@ int pci_mmap_page_range(struct pci_dev *
 }
 
 #ifdef CONFIG_PPC_MULTIPLATFORM
-static ssize_t pci_show_devspec(struct device *dev, char *buf)
+static ssize_t pci_show_devspec(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct pci_dev *pdev;
 	struct device_node *np;
@@ -902,6 +922,9 @@ void __devinit pcibios_fixup_bus(struct 
 	list_for_each_entry(dev, &bus->devices, bus_list)
 		ppc_md.iommu_dev_setup(dev);
 
+	if (ppc_md.irq_bus_setup)
+		ppc_md.irq_bus_setup(bus);
+
 	if (!pci_probe_only)
 		return;
 
@@ -941,4 +964,22 @@ int pci_read_irq_line(struct pci_dev *pc
 }
 EXPORT_SYMBOL(pci_read_irq_line);
 
+void pci_resource_to_user(const struct pci_dev *dev, int bar,
+			  const struct resource *rsrc,
+			  u64 *start, u64 *end)
+{
+	struct pci_controller *hose = pci_bus_to_host(dev->bus);
+	unsigned long offset = 0;
+
+	if (hose == NULL)
+		return;
+
+	if (rsrc->flags & IORESOURCE_IO)
+		offset = pci_io_base - (unsigned long)hose->io_base_virt +
+			hose->io_base_phys;
+
+	*start = rsrc->start + offset;
+	*end = rsrc->end + offset;
+}
+
 #endif /* CONFIG_PPC_MULTIPLATFORM */
diff --git a/arch/ppc64/kernel/pci.h b/arch/ppc64/kernel/pci.h
--- a/arch/ppc64/kernel/pci.h
+++ b/arch/ppc64/kernel/pci.h
@@ -40,10 +40,14 @@ struct device_node *fetch_dev_dn(struct 
 void pci_addr_cache_insert_device(struct pci_dev *dev);
 void pci_addr_cache_remove_device(struct pci_dev *dev);
 
-/* From pSeries_pci.h */
+/* From rtas_pci.h */
 void init_pci_config_tokens (void);
 unsigned long get_phb_buid (struct device_node *);
 
+/* From pSeries_pci.h */
+extern void pSeries_final_fixup(void);
+extern void pSeries_irq_bus_setup(struct pci_bus *bus);
+
 extern unsigned long pci_probe_only;
 extern unsigned long pci_assign_all_buses;
 extern int pci_read_irq_line(struct pci_dev *pci_dev);
diff --git a/arch/ppc64/kernel/pmac_setup.c b/arch/ppc64/kernel/pmac_setup.c
--- a/arch/ppc64/kernel/pmac_setup.c
+++ b/arch/ppc64/kernel/pmac_setup.c
@@ -97,7 +97,7 @@ EXPORT_SYMBOL(smu_cmdbuf_abs);
 
 extern void udbg_init_scc(struct device_node *np);
 
-void __pmac pmac_show_cpuinfo(struct seq_file *m)
+static void __pmac pmac_show_cpuinfo(struct seq_file *m)
 {
 	struct device_node *np;
 	char *pp;
@@ -144,7 +144,7 @@ void __pmac pmac_show_cpuinfo(struct seq
 }
 
 
-void __init pmac_setup_arch(void)
+static void __init pmac_setup_arch(void)
 {
 	/* init to some ~sane value until calibrate_delay() runs */
 	loops_per_jiffy = 50000000;
@@ -186,6 +186,8 @@ void __init pmac_setup_arch(void)
 #ifdef CONFIG_DUMMY_CONSOLE
 	conswitchp = &dummy_con;
 #endif
+
+	printk(KERN_INFO "Using native/NAP idle loop\n");
 }
 
 #ifdef CONFIG_SCSI
@@ -228,7 +230,7 @@ void __pmac note_bootable_part(dev_t dev
 	}
 }
 
-void __pmac pmac_restart(char *cmd)
+static void __pmac pmac_restart(char *cmd)
 {
 	switch(sys_ctrler) {
 #ifdef CONFIG_ADB_PMU
@@ -247,7 +249,7 @@ void __pmac pmac_restart(char *cmd)
 	}
 }
 
-void __pmac pmac_power_off(void)
+static void __pmac pmac_power_off(void)
 {
 	switch(sys_ctrler) {
 #ifdef CONFIG_ADB_PMU
@@ -265,7 +267,7 @@ void __pmac pmac_power_off(void)
 	}
 }
 
-void __pmac pmac_halt(void)
+static void __pmac pmac_halt(void)
 {
 	pmac_power_off();
 }
@@ -325,7 +327,7 @@ static void __init init_boot_display(voi
 /* 
  * Early initialization.
  */
-void __init pmac_init_early(void)
+static void __init pmac_init_early(void)
 {
 	DBG(" -> pmac_init_early\n");
 
@@ -507,5 +509,6 @@ struct machdep_calls __initdata pmac_md 
       	.calibrate_decr		= pmac_calibrate_decr,
 	.feature_call		= pmac_do_feature_call,
 	.progress		= pmac_progress,
-	.check_legacy_ioport	= pmac_check_legacy_ioport
+	.check_legacy_ioport	= pmac_check_legacy_ioport,
+	.idle_loop		= native_idle,
 };
diff --git a/arch/ppc64/kernel/pmac_time.c b/arch/ppc64/kernel/pmac_time.c
--- a/arch/ppc64/kernel/pmac_time.c
+++ b/arch/ppc64/kernel/pmac_time.c
@@ -40,11 +40,6 @@
 #define DBG(x...)
 #endif
 
-extern void setup_default_decr(void);
-
-extern unsigned long ppc_tb_freq;
-extern unsigned long ppc_proc_freq;
-
 /* Apparently the RTC stores seconds since 1 Jan 1904 */
 #define RTC_OFFSET	2082844800
 
@@ -161,8 +156,7 @@ void __init pmac_get_boot_time(struct rt
 
 /*
  * Query the OF and get the decr frequency.
- * This was taken from the pmac time_init() when merging the prep/pmac
- * time functions.
+ * FIXME: merge this with generic_calibrate_decr
  */
 void __init pmac_calibrate_decr(void)
 {
diff --git a/arch/ppc64/kernel/ppc_ksyms.c b/arch/ppc64/kernel/ppc_ksyms.c
--- a/arch/ppc64/kernel/ppc_ksyms.c
+++ b/arch/ppc64/kernel/ppc_ksyms.c
@@ -75,6 +75,7 @@ EXPORT_SYMBOL(giveup_fpu);
 EXPORT_SYMBOL(giveup_altivec);
 #endif
 EXPORT_SYMBOL(__flush_icache_range);
+EXPORT_SYMBOL(flush_dcache_range);
 
 #ifdef CONFIG_SMP
 #ifdef CONFIG_PPC_ISERIES
diff --git a/arch/ppc64/kernel/proc_ppc64.c b/arch/ppc64/kernel/proc_ppc64.c
--- a/arch/ppc64/kernel/proc_ppc64.c
+++ b/arch/ppc64/kernel/proc_ppc64.c
@@ -53,7 +53,7 @@ static int __init proc_ppc64_create(void
 	if (!root)
 		return 1;
 
-	if (!(systemcfg->platform & PLATFORM_PSERIES))
+	if (!(systemcfg->platform & (PLATFORM_PSERIES | PLATFORM_BPA)))
 		return 0;
 
 	if (!proc_mkdir("rtas", root))
diff --git a/arch/ppc64/kernel/process.c b/arch/ppc64/kernel/process.c
--- a/arch/ppc64/kernel/process.c
+++ b/arch/ppc64/kernel/process.c
@@ -36,6 +36,7 @@
 #include <linux/kallsyms.h>
 #include <linux/interrupt.h>
 #include <linux/utsname.h>
+#include <linux/kprobes.h>
 
 #include <asm/pgtable.h>
 #include <asm/uaccess.h>
@@ -58,14 +59,6 @@ struct task_struct *last_task_used_math 
 struct task_struct *last_task_used_altivec = NULL;
 #endif
 
-struct mm_struct ioremap_mm = {
-	.pgd		= ioremap_dir,
-	.mm_users	= ATOMIC_INIT(2),
-	.mm_count	= ATOMIC_INIT(1),
-	.cpu_vm_mask	= CPU_MASK_ALL,
-	.page_table_lock = SPIN_LOCK_UNLOCKED,
-};
-
 /*
  * Make sure the floating-point register state in the
  * the thread_struct is up to date for task tsk.
@@ -315,6 +308,8 @@ void show_regs(struct pt_regs * regs)
 
 void exit_thread(void)
 {
+	kprobe_flush_task(current);
+
 #ifndef CONFIG_SMP
 	if (last_task_used_math == current)
 		last_task_used_math = NULL;
@@ -329,6 +324,7 @@ void flush_thread(void)
 {
 	struct thread_info *t = current_thread_info();
 
+	kprobe_flush_task(current);
 	if (t->flags & _TIF_ABI_PENDING)
 		t->flags ^= (_TIF_ABI_PENDING | _TIF_32BIT);
 
diff --git a/arch/ppc64/kernel/prom.c b/arch/ppc64/kernel/prom.c
--- a/arch/ppc64/kernel/prom.c
+++ b/arch/ppc64/kernel/prom.c
@@ -884,6 +884,7 @@ static int __init early_init_dt_scan_cpu
 {
 	char *type = get_flat_dt_prop(node, "device_type", NULL);
 	u32 *prop;
+	unsigned long size;
 
 	/* We are scanning "cpu" nodes only */
 	if (type == NULL || strcmp(type, "cpu") != 0)
@@ -915,6 +916,7 @@ static int __init early_init_dt_scan_cpu
 		}
 	}
 
+#ifdef CONFIG_ALTIVEC
 	/* Check if we have a VMX and eventually update CPU features */
 	prop = (u32 *)get_flat_dt_prop(node, "ibm,vmx", NULL);
 	if (prop && (*prop) > 0) {
@@ -928,6 +930,18 @@ static int __init early_init_dt_scan_cpu
 		cur_cpu_spec->cpu_features |= CPU_FTR_ALTIVEC;
 		cur_cpu_spec->cpu_user_features |= PPC_FEATURE_HAS_ALTIVEC;
 	}
+#endif /* CONFIG_ALTIVEC */
+
+	/*
+	 * Check for an SMT capable CPU and set the CPU feature. We do
+	 * this by looking at the size of the ibm,ppc-interrupt-server#s
+	 * property
+	 */
+	prop = (u32 *)get_flat_dt_prop(node, "ibm,ppc-interrupt-server#s",
+				       &size);
+	cur_cpu_spec->cpu_features &= ~CPU_FTR_SMT;
+	if (prop && ((size / sizeof(u32)) > 1))
+		cur_cpu_spec->cpu_features |= CPU_FTR_SMT;
 
 	return 0;
 }
diff --git a/arch/ppc64/kernel/prom_init.c b/arch/ppc64/kernel/prom_init.c
--- a/arch/ppc64/kernel/prom_init.c
+++ b/arch/ppc64/kernel/prom_init.c
@@ -1803,7 +1803,7 @@ static void __init fixup_device_tree(voi
 	if (prom_getprop(u3, "device-rev", &u3_rev, sizeof(u3_rev))
 	    == PROM_ERROR)
 		return;
-	if (u3_rev != 0x35)
+	if (u3_rev != 0x35 && u3_rev != 0x37)
 		return;
 	/* does it need fixup ? */
 	if (prom_getproplen(i2c, "interrupts") > 0)
@@ -1915,9 +1915,9 @@ unsigned long __init prom_init(unsigned 
 		prom_send_capabilities();
 
 	/*
-	 * On pSeries, copy the CPU hold code
+	 * On pSeries and BPA, copy the CPU hold code
 	 */
-       	if (RELOC(of_platform) & PLATFORM_PSERIES)
+       	if (RELOC(of_platform) & (PLATFORM_PSERIES | PLATFORM_BPA))
        		copy_and_flush(0, KERNELBASE - offset, 0x100, 0);
 
 	/*
diff --git a/arch/ppc64/kernel/ptrace.c b/arch/ppc64/kernel/ptrace.c
--- a/arch/ppc64/kernel/ptrace.c
+++ b/arch/ppc64/kernel/ptrace.c
@@ -305,6 +305,8 @@ static void do_syscall_trace(void)
 
 void do_syscall_trace_enter(struct pt_regs *regs)
 {
+	secure_computing(regs->gpr[0]);
+
 	if (test_thread_flag(TIF_SYSCALL_TRACE)
 	    && (current->ptrace & PT_PTRACED))
 		do_syscall_trace();
@@ -320,8 +322,6 @@ void do_syscall_trace_enter(struct pt_re
 
 void do_syscall_trace_leave(struct pt_regs *regs)
 {
-	secure_computing(regs->gpr[0]);
-
 	if (unlikely(current->audit_context))
 		audit_syscall_exit(current, 
 				   (regs->ccr&0x1000)?AUDITSC_FAILURE:AUDITSC_SUCCESS,
diff --git a/arch/ppc64/kernel/ras.c b/arch/ppc64/kernel/ras.c
--- a/arch/ppc64/kernel/ras.c
+++ b/arch/ppc64/kernel/ras.c
@@ -47,7 +47,6 @@
 #include <asm/cache.h>
 #include <asm/prom.h>
 #include <asm/ptrace.h>
-#include <asm/iSeries/LparData.h>
 #include <asm/machdep.h>
 #include <asm/rtas.h>
 #include <asm/ppcdebug.h>
diff --git a/arch/ppc64/kernel/rtas-proc.c b/arch/ppc64/kernel/rtas-proc.c
--- a/arch/ppc64/kernel/rtas-proc.c
+++ b/arch/ppc64/kernel/rtas-proc.c
@@ -371,11 +371,11 @@ static ssize_t ppc_rtas_progress_write(s
 	/* Lets see if the user passed hexdigits */
 	hex = simple_strtoul(progress_led, NULL, 10);
 
-	ppc_md.progress ((char *)progress_led, hex);
+	rtas_progress ((char *)progress_led, hex);
 	return count;
 
 	/* clear the line */
-	/* ppc_md.progress("                   ", 0xffff);*/
+	/* rtas_progress("                   ", 0xffff);*/
 }
 /* ****************************************************************** */
 static int ppc_rtas_progress_show(struct seq_file *m, void *v)
diff --git a/arch/ppc64/kernel/rtas.c b/arch/ppc64/kernel/rtas.c
--- a/arch/ppc64/kernel/rtas.c
+++ b/arch/ppc64/kernel/rtas.c
@@ -91,6 +91,123 @@ call_rtas_display_status_delay(unsigned 
 	}
 }
 
+void
+rtas_progress(char *s, unsigned short hex)
+{
+	struct device_node *root;
+	int width, *p;
+	char *os;
+	static int display_character, set_indicator;
+	static int display_width, display_lines, *row_width, form_feed;
+	static DEFINE_SPINLOCK(progress_lock);
+	static int current_line;
+	static int pending_newline = 0;  /* did last write end with unprinted newline? */
+
+	if (!rtas.base)
+		return;
+
+	if (display_width == 0) {
+		display_width = 0x10;
+		if ((root = find_path_device("/rtas"))) {
+			if ((p = (unsigned int *)get_property(root,
+					"ibm,display-line-length", NULL)))
+				display_width = *p;
+			if ((p = (unsigned int *)get_property(root,
+					"ibm,form-feed", NULL)))
+				form_feed = *p;
+			if ((p = (unsigned int *)get_property(root,
+					"ibm,display-number-of-lines", NULL)))
+				display_lines = *p;
+			row_width = (unsigned int *)get_property(root,
+					"ibm,display-truncation-length", NULL);
+		}
+		display_character = rtas_token("display-character");
+		set_indicator = rtas_token("set-indicator");
+	}
+
+	if (display_character == RTAS_UNKNOWN_SERVICE) {
+		/* use hex display if available */
+		if (set_indicator != RTAS_UNKNOWN_SERVICE)
+			rtas_call(set_indicator, 3, 1, NULL, 6, 0, hex);
+		return;
+	}
+
+	spin_lock(&progress_lock);
+
+	/*
+	 * Last write ended with newline, but we didn't print it since
+	 * it would just clear the bottom line of output. Print it now
+	 * instead.
+	 *
+	 * If no newline is pending and form feed is supported, clear the
+	 * display with a form feed; otherwise, print a CR to start output
+	 * at the beginning of the line.
+	 */
+	if (pending_newline) {
+		rtas_call(display_character, 1, 1, NULL, '\r');
+		rtas_call(display_character, 1, 1, NULL, '\n');
+		pending_newline = 0;
+	} else {
+		current_line = 0;
+		if (form_feed)
+			rtas_call(display_character, 1, 1, NULL,
+				  (char)form_feed);
+		else
+			rtas_call(display_character, 1, 1, NULL, '\r');
+	}
+ 
+	if (row_width)
+		width = row_width[current_line];
+	else
+		width = display_width;
+	os = s;
+	while (*os) {
+		if (*os == '\n' || *os == '\r') {
+			/* If newline is the last character, save it
+			 * until next call to avoid bumping up the
+			 * display output.
+			 */
+			if (*os == '\n' && !os[1]) {
+				pending_newline = 1;
+				current_line++;
+				if (current_line > display_lines-1)
+					current_line = display_lines-1;
+				spin_unlock(&progress_lock);
+				return;
+			}
+ 
+			/* RTAS wants CR-LF, not just LF */
+ 
+			if (*os == '\n') {
+				rtas_call(display_character, 1, 1, NULL, '\r');
+				rtas_call(display_character, 1, 1, NULL, '\n');
+			} else {
+				/* CR might be used to re-draw a line, so we'll
+				 * leave it alone and not add LF.
+				 */
+				rtas_call(display_character, 1, 1, NULL, *os);
+			}
+ 
+			if (row_width)
+				width = row_width[current_line];
+			else
+				width = display_width;
+		} else {
+			width--;
+			rtas_call(display_character, 1, 1, NULL, *os);
+		}
+ 
+		os++;
+ 
+		/* if we overwrite the screen length */
+		if (width <= 0)
+			while ((*os != 0) && (*os != '\n') && (*os != '\r'))
+				os++;
+	}
+ 
+	spin_unlock(&progress_lock);
+}
+
 int
 rtas_token(const char *service)
 {
@@ -425,8 +542,8 @@ rtas_flash_firmware(void)
 
 	printk(KERN_ALERT "FLASH: flash image is %ld bytes\n", image_size);
 	printk(KERN_ALERT "FLASH: performing flash and reboot\n");
-	ppc_md.progress("Flashing        \n", 0x0);
-	ppc_md.progress("Please Wait...  ", 0x0);
+	rtas_progress("Flashing        \n", 0x0);
+	rtas_progress("Please Wait...  ", 0x0);
 	printk(KERN_ALERT "FLASH: this will take several minutes.  Do not power off!\n");
 	status = rtas_call(update_token, 1, 1, NULL, rtas_block_list);
 	switch (status) {	/* should only get "bad" status */
diff --git a/arch/ppc64/kernel/rtas_pci.c b/arch/ppc64/kernel/rtas_pci.c
new file mode 100644
--- /dev/null
+++ b/arch/ppc64/kernel/rtas_pci.c
@@ -0,0 +1,495 @@
+/*
+ * arch/ppc64/kernel/rtas_pci.c
+ *
+ * Copyright (C) 2001 Dave Engebretsen, IBM Corporation
+ * Copyright (C) 2003 Anton Blanchard <anton@au.ibm.com>, IBM
+ *
+ * RTAS specific routines for PCI.
+ * 
+ * Based on code from pci.c, chrp_pci.c and pSeries_pci.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *    
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/threads.h>
+#include <linux/pci.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/bootmem.h>
+
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/irq.h>
+#include <asm/prom.h>
+#include <asm/machdep.h>
+#include <asm/pci-bridge.h>
+#include <asm/iommu.h>
+#include <asm/rtas.h>
+
+#include "mpic.h"
+#include "pci.h"
+
+/* RTAS tokens */
+static int read_pci_config;
+static int write_pci_config;
+static int ibm_read_pci_config;
+static int ibm_write_pci_config;
+
+static int config_access_valid(struct device_node *dn, int where)
+{
+	if (where < 256)
+		return 1;
+	if (where < 4096 && dn->pci_ext_config_space)
+		return 1;
+
+	return 0;
+}
+
+static int rtas_read_config(struct device_node *dn, int where, int size, u32 *val)
+{
+	int returnval = -1;
+	unsigned long buid, addr;
+	int ret;
+
+	if (!dn)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	if (!config_access_valid(dn, where))
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+
+	addr = ((where & 0xf00) << 20) | (dn->busno << 16) |
+		(dn->devfn << 8) | (where & 0xff);
+	buid = dn->phb->buid;
+	if (buid) {
+		ret = rtas_call(ibm_read_pci_config, 4, 2, &returnval,
+				addr, buid >> 32, buid & 0xffffffff, size);
+	} else {
+		ret = rtas_call(read_pci_config, 2, 2, &returnval, addr, size);
+	}
+	*val = returnval;
+
+	if (ret)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	if (returnval == EEH_IO_ERROR_VALUE(size)
+	    && eeh_dn_check_failure (dn, NULL))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int rtas_pci_read_config(struct pci_bus *bus,
+				unsigned int devfn,
+				int where, int size, u32 *val)
+{
+	struct device_node *busdn, *dn;
+
+	if (bus->self)
+		busdn = pci_device_to_OF_node(bus->self);
+	else
+		busdn = bus->sysdata;	/* must be a phb */
+
+	/* Search only direct children of the bus */
+	for (dn = busdn->child; dn; dn = dn->sibling)
+		if (dn->devfn == devfn)
+			return rtas_read_config(dn, where, size, val);
+	return PCIBIOS_DEVICE_NOT_FOUND;
+}
+
+static int rtas_write_config(struct device_node *dn, int where, int size, u32 val)
+{
+	unsigned long buid, addr;
+	int ret;
+
+	if (!dn)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	if (!config_access_valid(dn, where))
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+
+	addr = ((where & 0xf00) << 20) | (dn->busno << 16) |
+		(dn->devfn << 8) | (where & 0xff);
+	buid = dn->phb->buid;
+	if (buid) {
+		ret = rtas_call(ibm_write_pci_config, 5, 1, NULL, addr, buid >> 32, buid & 0xffffffff, size, (ulong) val);
+	} else {
+		ret = rtas_call(write_pci_config, 3, 1, NULL, addr, size, (ulong)val);
+	}
+
+	if (ret)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int rtas_pci_write_config(struct pci_bus *bus,
+				 unsigned int devfn,
+				 int where, int size, u32 val)
+{
+	struct device_node *busdn, *dn;
+
+	if (bus->self)
+		busdn = pci_device_to_OF_node(bus->self);
+	else
+		busdn = bus->sysdata;	/* must be a phb */
+
+	/* Search only direct children of the bus */
+	for (dn = busdn->child; dn; dn = dn->sibling)
+		if (dn->devfn == devfn)
+			return rtas_write_config(dn, where, size, val);
+	return PCIBIOS_DEVICE_NOT_FOUND;
+}
+
+struct pci_ops rtas_pci_ops = {
+	rtas_pci_read_config,
+	rtas_pci_write_config
+};
+
+int is_python(struct device_node *dev)
+{
+	char *model = (char *)get_property(dev, "model", NULL);
+
+	if (model && strstr(model, "Python"))
+		return 1;
+
+	return 0;
+}
+
+static int get_phb_reg_prop(struct device_node *dev,
+			    unsigned int addr_size_words,
+			    struct reg_property64 *reg)
+{
+	unsigned int *ui_ptr = NULL, len;
+
+	/* Found a PHB, now figure out where his registers are mapped. */
+	ui_ptr = (unsigned int *)get_property(dev, "reg", &len);
+	if (ui_ptr == NULL)
+		return 1;
+
+	if (addr_size_words == 1) {
+		reg->address = ((struct reg_property32 *)ui_ptr)->address;
+		reg->size    = ((struct reg_property32 *)ui_ptr)->size;
+	} else {
+		*reg = *((struct reg_property64 *)ui_ptr);
+	}
+
+	return 0;
+}
+
+static void python_countermeasures(struct device_node *dev,
+				   unsigned int addr_size_words)
+{
+	struct reg_property64 reg_struct;
+	void __iomem *chip_regs;
+	volatile u32 val;
+
+	if (get_phb_reg_prop(dev, addr_size_words, &reg_struct))
+		return;
+
+	/* Python's register file is 1 MB in size. */
+	chip_regs = ioremap(reg_struct.address & ~(0xfffffUL), 0x100000);
+
+	/* 
+	 * Firmware doesn't always clear this bit which is critical
+	 * for good performance - Anton
+	 */
+
+#define PRG_CL_RESET_VALID 0x00010000
+
+	val = in_be32(chip_regs + 0xf6030);
+	if (val & PRG_CL_RESET_VALID) {
+		printk(KERN_INFO "Python workaround: ");
+		val &= ~PRG_CL_RESET_VALID;
+		out_be32(chip_regs + 0xf6030, val);
+		/*
+		 * We must read it back for changes to
+		 * take effect
+		 */
+		val = in_be32(chip_regs + 0xf6030);
+		printk("reg0: %x\n", val);
+	}
+
+	iounmap(chip_regs);
+}
+
+void __init init_pci_config_tokens (void)
+{
+	read_pci_config = rtas_token("read-pci-config");
+	write_pci_config = rtas_token("write-pci-config");
+	ibm_read_pci_config = rtas_token("ibm,read-pci-config");
+	ibm_write_pci_config = rtas_token("ibm,write-pci-config");
+}
+
+unsigned long __devinit get_phb_buid (struct device_node *phb)
+{
+	int addr_cells;
+	unsigned int *buid_vals;
+	unsigned int len;
+	unsigned long buid;
+
+	if (ibm_read_pci_config == -1) return 0;
+
+	/* PHB's will always be children of the root node,
+	 * or so it is promised by the current firmware. */
+	if (phb->parent == NULL)
+		return 0;
+	if (phb->parent->parent)
+		return 0;
+
+	buid_vals = (unsigned int *) get_property(phb, "reg", &len);
+	if (buid_vals == NULL)
+		return 0;
+
+	addr_cells = prom_n_addr_cells(phb);
+	if (addr_cells == 1) {
+		buid = (unsigned long) buid_vals[0];
+	} else {
+		buid = (((unsigned long)buid_vals[0]) << 32UL) |
+			(((unsigned long)buid_vals[1]) & 0xffffffff);
+	}
+	return buid;
+}
+
+static int phb_set_bus_ranges(struct device_node *dev,
+			      struct pci_controller *phb)
+{
+	int *bus_range;
+	unsigned int len;
+
+	bus_range = (int *) get_property(dev, "bus-range", &len);
+	if (bus_range == NULL || len < 2 * sizeof(int)) {
+		return 1;
+ 	}
+ 
+	phb->first_busno =  bus_range[0];
+	phb->last_busno  =  bus_range[1];
+
+	return 0;
+}
+
+static int __devinit setup_phb(struct device_node *dev,
+			       struct pci_controller *phb,
+			       unsigned int addr_size_words)
+{
+	pci_setup_pci_controller(phb);
+
+	if (is_python(dev))
+		python_countermeasures(dev, addr_size_words);
+
+	if (phb_set_bus_ranges(dev, phb))
+		return 1;
+
+	phb->arch_data = dev;
+	phb->ops = &rtas_pci_ops;
+	phb->buid = get_phb_buid(dev);
+
+	return 0;
+}
+
+static void __devinit add_linux_pci_domain(struct device_node *dev,
+					   struct pci_controller *phb,
+					   struct property *of_prop)
+{
+	memset(of_prop, 0, sizeof(struct property));
+	of_prop->name = "linux,pci-domain";
+	of_prop->length = sizeof(phb->global_number);
+	of_prop->value = (unsigned char *)&of_prop[1];
+	memcpy(of_prop->value, &phb->global_number, sizeof(phb->global_number));
+	prom_add_property(dev, of_prop);
+}
+
+static struct pci_controller * __init alloc_phb(struct device_node *dev,
+						unsigned int addr_size_words)
+{
+	struct pci_controller *phb;
+	struct property *of_prop;
+
+	phb = alloc_bootmem(sizeof(struct pci_controller));
+	if (phb == NULL)
+		return NULL;
+
+	of_prop = alloc_bootmem(sizeof(struct property) +
+				sizeof(phb->global_number));
+	if (!of_prop)
+		return NULL;
+
+	if (setup_phb(dev, phb, addr_size_words))
+		return NULL;
+
+	add_linux_pci_domain(dev, phb, of_prop);
+
+	return phb;
+}
+
+static struct pci_controller * __devinit alloc_phb_dynamic(struct device_node *dev, unsigned int addr_size_words)
+{
+	struct pci_controller *phb;
+
+	phb = (struct pci_controller *)kmalloc(sizeof(struct pci_controller),
+					       GFP_KERNEL);
+	if (phb == NULL)
+		return NULL;
+
+	if (setup_phb(dev, phb, addr_size_words))
+		return NULL;
+
+	phb->is_dynamic = 1;
+
+	/* TODO: linux,pci-domain? */
+
+ 	return phb;
+}
+
+unsigned long __init find_and_init_phbs(void)
+{
+	struct device_node *node;
+	struct pci_controller *phb;
+	unsigned int root_size_cells = 0;
+	unsigned int index;
+	unsigned int *opprop = NULL;
+	struct device_node *root = of_find_node_by_path("/");
+
+	if (ppc64_interrupt_controller == IC_OPEN_PIC) {
+		opprop = (unsigned int *)get_property(root,
+				"platform-open-pic", NULL);
+	}
+
+	root_size_cells = prom_n_size_cells(root);
+
+	index = 0;
+
+	for (node = of_get_next_child(root, NULL);
+	     node != NULL;
+	     node = of_get_next_child(root, node)) {
+		if (node->type == NULL || strcmp(node->type, "pci") != 0)
+			continue;
+
+		phb = alloc_phb(node, root_size_cells);
+		if (!phb)
+			continue;
+
+		pci_process_bridge_OF_ranges(phb, node);
+		pci_setup_phb_io(phb, index == 0);
+#ifdef CONFIG_PPC_PSERIES
+		if (ppc64_interrupt_controller == IC_OPEN_PIC && pSeries_mpic) {
+			int addr = root_size_cells * (index + 2) - 1;
+			mpic_assign_isu(pSeries_mpic, index, opprop[addr]);
+		}
+#endif
+		index++;
+	}
+
+	of_node_put(root);
+	pci_devs_phb_init();
+
+	/*
+	 * pci_probe_only and pci_assign_all_buses can be set via properties
+	 * in chosen.
+	 */
+	if (of_chosen) {
+		int *prop;
+
+		prop = (int *)get_property(of_chosen, "linux,pci-probe-only",
+					   NULL);
+		if (prop)
+			pci_probe_only = *prop;
+
+		prop = (int *)get_property(of_chosen,
+					   "linux,pci-assign-all-buses", NULL);
+		if (prop)
+			pci_assign_all_buses = *prop;
+	}
+
+	return 0;
+}
+
+struct pci_controller * __devinit init_phb_dynamic(struct device_node *dn)
+{
+	struct device_node *root = of_find_node_by_path("/");
+	unsigned int root_size_cells = 0;
+	struct pci_controller *phb;
+	struct pci_bus *bus;
+	int primary;
+
+	root_size_cells = prom_n_size_cells(root);
+
+	primary = list_empty(&hose_list);
+	phb = alloc_phb_dynamic(dn, root_size_cells);
+	if (!phb)
+		return NULL;
+
+	pci_process_bridge_OF_ranges(phb, dn);
+
+	pci_setup_phb_io_dynamic(phb, primary);
+	of_node_put(root);
+
+	pci_devs_phb_init_dynamic(phb);
+	phb->last_busno = 0xff;
+	bus = pci_scan_bus(phb->first_busno, phb->ops, phb->arch_data);
+	phb->bus = bus;
+	phb->last_busno = bus->subordinate;
+
+	return phb;
+}
+EXPORT_SYMBOL(init_phb_dynamic);
+
+/* RPA-specific bits for removing PHBs */
+int pcibios_remove_root_bus(struct pci_controller *phb)
+{
+	struct pci_bus *b = phb->bus;
+	struct resource *res;
+	int rc, i;
+
+	res = b->resource[0];
+	if (!res->flags) {
+		printk(KERN_ERR "%s: no IO resource for PHB %s\n", __FUNCTION__,
+				b->name);
+		return 1;
+	}
+
+	rc = unmap_bus_range(b);
+	if (rc) {
+		printk(KERN_ERR "%s: failed to unmap IO on bus %s\n",
+			__FUNCTION__, b->name);
+		return 1;
+	}
+
+	if (release_resource(res)) {
+		printk(KERN_ERR "%s: failed to release IO on bus %s\n",
+				__FUNCTION__, b->name);
+		return 1;
+	}
+
+	for (i = 1; i < 3; ++i) {
+		res = b->resource[i];
+		if (!res->flags && i == 0) {
+			printk(KERN_ERR "%s: no MEM resource for PHB %s\n",
+				__FUNCTION__, b->name);
+			return 1;
+		}
+		if (res->flags && release_resource(res)) {
+			printk(KERN_ERR
+			       "%s: failed to release IO %d on bus %s\n",
+				__FUNCTION__, i, b->name);
+			return 1;
+		}
+	}
+
+	list_del(&phb->list_node);
+	if (phb->is_dynamic)
+		kfree(phb);
+
+	return 0;
+}
+EXPORT_SYMBOL(pcibios_remove_root_bus);
diff --git a/arch/ppc64/kernel/rtasd.c b/arch/ppc64/kernel/rtasd.c
--- a/arch/ppc64/kernel/rtasd.c
+++ b/arch/ppc64/kernel/rtasd.c
@@ -440,7 +440,7 @@ static int rtasd(void *unused)
 		goto error;
 	}
 
-	printk(KERN_ERR "RTAS daemon started\n");
+	printk(KERN_INFO "RTAS daemon started\n");
 
 	DEBUG("will sleep for %d jiffies\n", (HZ*60/rtas_event_scan_rate) / 2);
 
@@ -485,7 +485,7 @@ static int __init rtas_init(void)
 	/* No RTAS, only warn if we are on a pSeries box  */
 	if (rtas_token("event-scan") == RTAS_UNKNOWN_SERVICE) {
 		if (systemcfg->platform & PLATFORM_PSERIES)
-			printk(KERN_ERR "rtasd: no event-scan on system\n");
+			printk(KERN_INFO "rtasd: no event-scan on system\n");
 		return 1;
 	}
 
diff --git a/arch/ppc64/kernel/rtc.c b/arch/ppc64/kernel/rtc.c
--- a/arch/ppc64/kernel/rtc.c
+++ b/arch/ppc64/kernel/rtc.c
@@ -42,10 +42,8 @@
 #include <asm/time.h>
 #include <asm/rtas.h>
 
-#include <asm/iSeries/LparData.h>
 #include <asm/iSeries/mf.h>
 #include <asm/machdep.h>
-#include <asm/iSeries/ItSpCommArea.h>
 
 extern int piranha_simulator;
 
@@ -303,7 +301,7 @@ void iSeries_get_boot_time(struct rtc_ti
 #ifdef CONFIG_PPC_RTAS
 #define MAX_RTC_WAIT 5000	/* 5 sec */
 #define RTAS_CLOCK_BUSY (-2)
-void pSeries_get_boot_time(struct rtc_time *rtc_tm)
+void rtas_get_boot_time(struct rtc_time *rtc_tm)
 {
 	int ret[8];
 	int error, wait_time;
@@ -338,7 +336,7 @@ void pSeries_get_boot_time(struct rtc_ti
  * and if a delay is needed to read the clock.  In this case we just
  * silently return without updating rtc_tm.
  */
-void pSeries_get_rtc_time(struct rtc_time *rtc_tm)
+void rtas_get_rtc_time(struct rtc_time *rtc_tm)
 {
         int ret[8];
 	int error, wait_time;
@@ -373,7 +371,7 @@ void pSeries_get_rtc_time(struct rtc_tim
 	rtc_tm->tm_year = ret[0] - 1900;
 }
 
-int pSeries_set_rtc_time(struct rtc_time *tm)
+int rtas_set_rtc_time(struct rtc_time *tm)
 {
 	int error, wait_time;
 	unsigned long max_wait_tb;
diff --git a/arch/ppc64/kernel/setup.c b/arch/ppc64/kernel/setup.c
--- a/arch/ppc64/kernel/setup.c
+++ b/arch/ppc64/kernel/setup.c
@@ -41,7 +41,6 @@
 #include <asm/smp.h>
 #include <asm/elf.h>
 #include <asm/machdep.h>
-#include <asm/iSeries/LparData.h>
 #include <asm/paca.h>
 #include <asm/ppcdebug.h>
 #include <asm/time.h>
@@ -57,6 +56,8 @@
 #include <asm/cache.h>
 #include <asm/page.h>
 #include <asm/mmu.h>
+#include <asm/lmb.h>
+#include <asm/iSeries/ItLpNaca.h>
 
 #ifdef DEBUG
 #define DBG(fmt...) udbg_printf(fmt)
@@ -95,7 +96,6 @@ extern void udbg_init_maple_realmode(voi
 extern unsigned long klimit;
 
 extern void mm_init_ppc64(void);
-extern int  idle_setup(void);
 extern void stab_initialize(unsigned long stab);
 extern void htab_initialize(void);
 extern void early_init_devtree(void *flat_dt);
@@ -343,6 +343,7 @@ static void __init setup_cpu_maps(void)
 extern struct machdep_calls pSeries_md;
 extern struct machdep_calls pmac_md;
 extern struct machdep_calls maple_md;
+extern struct machdep_calls bpa_md;
 
 /* Ultimately, stuff them in an elf section like initcalls... */
 static struct machdep_calls __initdata *machines[] = {
@@ -355,6 +356,9 @@ static struct machdep_calls __initdata *
 #ifdef CONFIG_PPC_MAPLE
 	&maple_md,
 #endif /* CONFIG_PPC_MAPLE */
+#ifdef CONFIG_PPC_BPA
+	&bpa_md,
+#endif
 	NULL
 };
 
@@ -672,37 +676,51 @@ void __init setup_system(void)
 	DBG(" <- setup_system()\n");
 }
 
-
-void machine_restart(char *cmd)
+/* also used by kexec */
+void machine_shutdown(void)
 {
 	if (ppc_md.nvram_sync)
 		ppc_md.nvram_sync();
+}
+
+void machine_restart(char *cmd)
+{
+	machine_shutdown();
 	ppc_md.restart(cmd);
+#ifdef CONFIG_SMP
+	smp_send_stop();
+#endif
+	printk(KERN_EMERG "System Halted, OK to turn off power\n");
+	local_irq_disable();
+	while (1) ;
 }
 
-EXPORT_SYMBOL(machine_restart);
-  
 void machine_power_off(void)
 {
-	if (ppc_md.nvram_sync)
-		ppc_md.nvram_sync();
+	machine_shutdown();
 	ppc_md.power_off();
+#ifdef CONFIG_SMP
+	smp_send_stop();
+#endif
+	printk(KERN_EMERG "System Halted, OK to turn off power\n");
+	local_irq_disable();
+	while (1) ;
 }
+/* Used by the G5 thermal driver */
+EXPORT_SYMBOL_GPL(machine_power_off);
 
-EXPORT_SYMBOL(machine_power_off);
-  
 void machine_halt(void)
 {
-	if (ppc_md.nvram_sync)
-		ppc_md.nvram_sync();
+	machine_shutdown();
 	ppc_md.halt();
+#ifdef CONFIG_SMP
+	smp_send_stop();
+#endif
+	printk(KERN_EMERG "System Halted, OK to turn off power\n");
+	local_irq_disable();
+	while (1) ;
 }
 
-EXPORT_SYMBOL(machine_halt);
-
-unsigned long ppc_proc_freq;
-unsigned long ppc_tb_freq;
-
 static int ppc64_panic_event(struct notifier_block *this,
                              unsigned long event, void *ptr)
 {
@@ -1052,16 +1070,22 @@ void __init setup_arch(char **cmdline_p)
 	irqstack_early_init();
 	emergency_stack_init();
 
+	stabs_alloc();
+
 	/* set up the bootmem stuff with available memory */
 	do_init_bootmem();
+	sparse_init();
 
 	/* initialize the syscall map in systemcfg */
 	setup_syscall_map();
 
 	ppc_md.setup_arch();
 
-	/* Select the correct idle loop for the platform. */
-	idle_setup();
+	/* Use the default idle loop if the platform hasn't provided one. */
+	if (NULL == ppc_md.idle_loop) {
+		ppc_md.idle_loop = default_idle;
+		printk(KERN_INFO "Using default idle loop\n");
+	}
 
 	paging_init();
 	ppc64_boot_msg(0x15, "Setup Done");
@@ -1078,11 +1102,11 @@ void __init setup_arch(char **cmdline_p)
 static void ppc64_do_msg(unsigned int src, const char *msg)
 {
 	if (ppc_md.progress) {
-		char buf[32];
+		char buf[128];
 
-		sprintf(buf, "%08x        \n", src);
+		sprintf(buf, "%08X\n", src);
 		ppc_md.progress(buf, 0);
-		sprintf(buf, "%-16s", msg);
+		snprintf(buf, 128, "%s", msg);
 		ppc_md.progress(buf, 0);
 	}
 }
@@ -1116,7 +1140,7 @@ void ppc64_dump_msg(unsigned int src, co
 }
 
 /* This should only be called on processor 0 during calibrate decr */
-void setup_default_decr(void)
+void __init setup_default_decr(void)
 {
 	struct paca_struct *lpaca = get_paca();
 
diff --git a/arch/ppc64/kernel/smp.c b/arch/ppc64/kernel/smp.c
--- a/arch/ppc64/kernel/smp.c
+++ b/arch/ppc64/kernel/smp.c
@@ -65,13 +65,11 @@ struct smp_ops_t *smp_ops;
 
 static volatile unsigned int cpu_callin_map[NR_CPUS];
 
-extern unsigned char stab_array[];
-
 void smp_call_function_interrupt(void);
 
 int smt_enabled_at_boot = 1;
 
-#ifdef CONFIG_PPC_MULTIPLATFORM
+#ifdef CONFIG_MPIC
 void smp_mpic_message_pass(int target, int msg)
 {
 	/* make sure we're sending something that translates to an IPI */
@@ -128,7 +126,7 @@ void __devinit smp_generic_kick_cpu(int 
 	smp_mb();
 }
 
-#endif /* CONFIG_PPC_MULTIPLATFORM */
+#endif /* CONFIG_MPIC */
 
 static void __init smp_space_timers(unsigned int max_cpus)
 {
@@ -492,19 +490,6 @@ int __devinit __cpu_up(unsigned int cpu)
 
 	paca[cpu].default_decr = tb_ticks_per_jiffy;
 
-	if (!cpu_has_feature(CPU_FTR_SLB)) {
-		void *tmp;
-
-		/* maximum of 48 CPUs on machines with a segment table */
-		if (cpu >= 48)
-			BUG();
-
-		tmp = &stab_array[PAGE_SIZE * cpu];
-		memset(tmp, 0, PAGE_SIZE); 
-		paca[cpu].stab_addr = (unsigned long)tmp;
-		paca[cpu].stab_real = virt_to_abs(tmp);
-	}
-
 	/* Make sure callin-map entry is 0 (can be leftover a CPU
 	 * hotplug
 	 */
diff --git a/arch/ppc64/kernel/spider-pic.c b/arch/ppc64/kernel/spider-pic.c
new file mode 100644
--- /dev/null
+++ b/arch/ppc64/kernel/spider-pic.c
@@ -0,0 +1,191 @@
+/*
+ * External Interrupt Controller on Spider South Bridge
+ *
+ * (C) Copyright IBM Deutschland Entwicklung GmbH 2005
+ *
+ * Author: Arnd Bergmann <arndb@de.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, 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 <linux/interrupt.h>
+#include <linux/irq.h>
+
+#include <asm/pgtable.h>
+#include <asm/prom.h>
+#include <asm/io.h>
+
+#include "bpa_iic.h"
+
+/* register layout taken from Spider spec, table 7.4-4 */
+enum {
+	TIR_DEN		= 0x004, /* Detection Enable Register */
+	TIR_MSK		= 0x084, /* Mask Level Register */
+	TIR_EDC		= 0x0c0, /* Edge Detection Clear Register */
+	TIR_PNDA	= 0x100, /* Pending Register A */
+	TIR_PNDB	= 0x104, /* Pending Register B */
+	TIR_CS		= 0x144, /* Current Status Register */
+	TIR_LCSA	= 0x150, /* Level Current Status Register A */
+	TIR_LCSB	= 0x154, /* Level Current Status Register B */
+	TIR_LCSC	= 0x158, /* Level Current Status Register C */
+	TIR_LCSD	= 0x15c, /* Level Current Status Register D */
+	TIR_CFGA	= 0x200, /* Setting Register A0 */
+	TIR_CFGB	= 0x204, /* Setting Register B0 */
+			/* 0x208 ... 0x3ff Setting Register An/Bn */
+	TIR_PPNDA	= 0x400, /* Packet Pending Register A */
+	TIR_PPNDB	= 0x404, /* Packet Pending Register B */
+	TIR_PIERA	= 0x408, /* Packet Output Error Register A */
+	TIR_PIERB	= 0x40c, /* Packet Output Error Register B */
+	TIR_PIEN	= 0x444, /* Packet Output Enable Register */
+	TIR_PIPND	= 0x454, /* Packet Output Pending Register */
+	TIRDID		= 0x484, /* Spider Device ID Register */
+	REISTIM		= 0x500, /* Reissue Command Timeout Time Setting */
+	REISTIMEN	= 0x504, /* Reissue Command Timeout Setting */
+	REISWAITEN	= 0x508, /* Reissue Wait Control*/
+};
+
+static void __iomem *spider_pics[4];
+
+static void __iomem *spider_get_pic(int irq)
+{
+	int node = irq / IIC_NODE_STRIDE;
+	irq %= IIC_NODE_STRIDE;
+
+	if (irq >= IIC_EXT_OFFSET &&
+	    irq < IIC_EXT_OFFSET + IIC_NUM_EXT &&
+	    spider_pics)
+		return spider_pics[node];
+	return NULL;
+}
+
+static int spider_get_nr(unsigned int irq)
+{
+	return (irq % IIC_NODE_STRIDE) - IIC_EXT_OFFSET;
+}
+
+static void __iomem *spider_get_irq_config(int irq)
+{
+	void __iomem *pic;
+	pic = spider_get_pic(irq);
+	return pic + TIR_CFGA + 8 * spider_get_nr(irq);
+}
+
+static void spider_enable_irq(unsigned int irq)
+{
+	void __iomem *cfg = spider_get_irq_config(irq);
+	irq = spider_get_nr(irq);
+
+	out_be32(cfg, in_be32(cfg) | 0x3107000eu);
+	out_be32(cfg + 4, in_be32(cfg + 4) | 0x00020000u | irq);
+}
+
+static void spider_disable_irq(unsigned int irq)
+{
+	void __iomem *cfg = spider_get_irq_config(irq);
+	irq = spider_get_nr(irq);
+
+	out_be32(cfg, in_be32(cfg) & ~0x30000000u);
+}
+
+static unsigned int spider_startup_irq(unsigned int irq)
+{
+	spider_enable_irq(irq);
+	return 0;
+}
+
+static void spider_shutdown_irq(unsigned int irq)
+{
+	spider_disable_irq(irq);
+}
+
+static void spider_end_irq(unsigned int irq)
+{
+	spider_enable_irq(irq);
+}
+
+static void spider_ack_irq(unsigned int irq)
+{
+	spider_disable_irq(irq);
+	iic_local_enable();
+}
+
+static struct hw_interrupt_type spider_pic = {
+	.typename = " SPIDER   ",
+	.startup = spider_startup_irq,
+	.shutdown = spider_shutdown_irq,
+	.enable = spider_enable_irq,
+	.disable = spider_disable_irq,
+	.ack = spider_ack_irq,
+	.end = spider_end_irq,
+};
+
+
+int spider_get_irq(unsigned long int_pending)
+{
+	void __iomem *regs = spider_get_pic(int_pending);
+	unsigned long cs;
+	int irq;
+
+	cs = in_be32(regs + TIR_CS);
+
+	irq = cs >> 24;
+	if (irq != 63)
+		return irq;
+
+	return -1;
+}
+ 
+void spider_init_IRQ(void)
+{
+	int node;
+	struct device_node *dn;
+	unsigned int *property;
+	long spiderpic;
+	int n;
+
+/* FIXME: detect multiple PICs as soon as the device tree has them */
+	for (node = 0; node < 1; node++) {
+		dn = of_find_node_by_path("/");
+		n = prom_n_addr_cells(dn);
+		property = (unsigned int *) get_property(dn,
+				"platform-spider-pic", NULL);
+
+		if (!property)
+			continue;
+		for (spiderpic = 0; n > 0; --n)
+			spiderpic = (spiderpic << 32) + *property++;
+		printk(KERN_DEBUG "SPIDER addr: %lx\n", spiderpic);
+		spider_pics[node] = __ioremap(spiderpic, 0x800, _PAGE_NO_CACHE);
+		for (n = 0; n < IIC_NUM_EXT; n++) {
+			int irq = n + IIC_EXT_OFFSET + node * IIC_NODE_STRIDE;
+			get_irq_desc(irq)->handler = &spider_pic;
+
+ 		/* do not mask any interrupts because of level */
+ 		out_be32(spider_pics[node] + TIR_MSK, 0x0);
+ 		
+ 		/* disable edge detection clear */
+ 		/* out_be32(spider_pics[node] + TIR_EDC, 0x0); */
+ 		
+ 		/* enable interrupt packets to be output */
+ 		out_be32(spider_pics[node] + TIR_PIEN,
+			in_be32(spider_pics[node] + TIR_PIEN) | 0x1);
+ 		
+ 		/* Enable the interrupt detection enable bit. Do this last! */
+ 		out_be32(spider_pics[node] + TIR_DEN,
+			in_be32(spider_pics[node] +TIR_DEN) | 0x1);
+
+		}
+	}
+}
diff --git a/arch/ppc64/kernel/sys_ppc32.c b/arch/ppc64/kernel/sys_ppc32.c
--- a/arch/ppc64/kernel/sys_ppc32.c
+++ b/arch/ppc64/kernel/sys_ppc32.c
@@ -30,47 +30,26 @@
 #include <linux/sem.h>
 #include <linux/msg.h>
 #include <linux/shm.h>
-#include <linux/slab.h>
-#include <linux/uio.h>
-#include <linux/aio.h>
-#include <linux/nfs_fs.h>
-#include <linux/module.h>
-#include <linux/sunrpc/svc.h>
-#include <linux/nfsd/nfsd.h>
-#include <linux/nfsd/cache.h>
-#include <linux/nfsd/xdr.h>
-#include <linux/nfsd/syscall.h>
 #include <linux/poll.h>
 #include <linux/personality.h>
 #include <linux/stat.h>
-#include <linux/filter.h>
-#include <linux/highmem.h>
-#include <linux/highuid.h>
 #include <linux/mman.h>
-#include <linux/ipv6.h>
 #include <linux/in.h>
-#include <linux/icmpv6.h>
 #include <linux/syscalls.h>
 #include <linux/unistd.h>
 #include <linux/sysctl.h>
 #include <linux/binfmts.h>
-#include <linux/dnotify.h>
 #include <linux/security.h>
 #include <linux/compat.h>
 #include <linux/ptrace.h>
-#include <linux/aio_abi.h>
 #include <linux/elf.h>
 
-#include <net/scm.h>
-#include <net/sock.h>
-
 #include <asm/ptrace.h>
 #include <asm/types.h>
 #include <asm/ipc.h>
 #include <asm/uaccess.h>
 #include <asm/unistd.h>
 #include <asm/semaphore.h>
-#include <asm/ppcdebug.h>
 #include <asm/time.h>
 #include <asm/mmu_context.h>
 #include <asm/systemcfg.h>
@@ -350,8 +329,6 @@ asmlinkage long sys32_adjtimex(struct ti
 	return ret;
 }
 
-
-/* These are here just in case some old sparc32 binary calls it. */
 asmlinkage long sys32_pause(void)
 {
 	current->state = TASK_INTERRUPTIBLE;
@@ -360,8 +337,6 @@ asmlinkage long sys32_pause(void)
 	return -ERESTARTNOHAND;
 }
 
-
-
 static inline long get_ts32(struct timespec *o, struct compat_timeval __user *i)
 {
 	long usec;
@@ -741,6 +716,7 @@ asmlinkage int sys32_pciconfig_write(u32
 
 asmlinkage int sys32_pciconfig_iobase(u32 which, u32 in_bus, u32 in_devfn)
 {
+#ifdef CONFIG_PCI
 	struct pci_controller* hose;
 	struct list_head *ln;
 	struct pci_bus *bus = NULL;
@@ -786,7 +762,7 @@ asmlinkage int sys32_pciconfig_iobase(u3
 	case IOBASE_ISA_MEM:
 		return -EINVAL;
 	}
-
+#endif	/* CONFIG_PCI */
 	return -EOPNOTSUPP;
 }
 
@@ -846,16 +822,6 @@ asmlinkage long sys32_getpgid(u32 pid)
 }
 
 
-/* Note: it is necessary to treat which and who as unsigned ints,
- * with the corresponding cast to a signed int to insure that the 
- * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
- * and the register representation of a signed int (msr in 64-bit mode) is performed.
- */
-asmlinkage long sys32_getpriority(u32 which, u32 who)
-{
-	return sys_getpriority((int)which, (int)who);
-}
-
 
 /* Note: it is necessary to treat pid as an unsigned int,
  * with the corresponding cast to a signed int to insure that the 
@@ -1047,6 +1013,11 @@ asmlinkage long sys32_setpgid(u32 pid, u
 	return sys_setpgid((int)pid, (int)pgid);
 }
 
+long sys32_getpriority(u32 which, u32 who)
+{
+	/* sign extend which and who */
+	return sys_getpriority((int)which, (int)who);
+}
 
 long sys32_setpriority(u32 which, u32 who, u32 niceval)
 {
@@ -1054,6 +1025,18 @@ long sys32_setpriority(u32 which, u32 wh
 	return sys_setpriority((int)which, (int)who, (int)niceval);
 }
 
+long sys32_ioprio_get(u32 which, u32 who)
+{
+	/* sign extend which and who */
+	return sys_ioprio_get((int)which, (int)who);
+}
+
+long sys32_ioprio_set(u32 which, u32 who, u32 ioprio)
+{
+	/* sign extend which, who and ioprio */
+	return sys_ioprio_set((int)which, (int)who, (int)ioprio);
+}
+
 /* Note: it is necessary to treat newmask as an unsigned int,
  * with the corresponding cast to a signed int to insure that the 
  * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
@@ -1272,8 +1255,6 @@ long ppc32_fadvise64_64(int fd, int advi
 			     (u64)len_high << 32 | len_low, advice);
 }
 
-extern asmlinkage long sys_timer_create(clockid_t, sigevent_t __user *, timer_t __user *);
-
 long ppc32_timer_create(clockid_t clock,
 			struct compat_sigevent __user *ev32,
 			timer_t __user *timer_id)
diff --git a/arch/ppc64/kernel/sysfs.c b/arch/ppc64/kernel/sysfs.c
--- a/arch/ppc64/kernel/sysfs.c
+++ b/arch/ppc64/kernel/sysfs.c
@@ -112,7 +112,6 @@ void ppc64_enable_pmcs(void)
 	unsigned long hid0;
 #ifdef CONFIG_PPC_PSERIES
 	unsigned long set, reset;
-	int ret;
 #endif /* CONFIG_PPC_PSERIES */
 
 	/* Only need to enable them once */
@@ -145,11 +144,7 @@ void ppc64_enable_pmcs(void)
 	case PLATFORM_PSERIES_LPAR:
 		set = 1UL << 63;
 		reset = 0;
-		ret = plpar_hcall_norets(H_PERFMON, set, reset);
-		if (ret)
-			printk(KERN_ERR "H_PERFMON call on cpu %u "
-			       "returned %d\n",
-			       smp_processor_id(), ret);
+		plpar_hcall_norets(H_PERFMON, set, reset);
 		break;
 #endif /* CONFIG_PPC_PSERIES */
 
@@ -161,13 +156,6 @@ void ppc64_enable_pmcs(void)
 	/* instruct hypervisor to maintain PMCs */
 	if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR)
 		get_paca()->lppaca.pmcregs_in_use = 1;
-
-	/*
-	 * On SMT machines we have to set the run latch in the ctrl register
-	 * in order to make PMC6 spin.
-	 */
-	if (cpu_has_feature(CPU_FTR_SMT))
-		ppc64_runlatch_on();
 #endif /* CONFIG_PPC_PSERIES */
 }
 
@@ -400,7 +388,12 @@ static int __init topology_init(void)
 		struct cpu *c = &per_cpu(cpu_devices, cpu);
 
 #ifdef CONFIG_NUMA
-		parent = &node_devices[cpu_to_node(cpu)];
+		/* The node to which a cpu belongs can't be known
+		 * until the cpu is made present.
+		 */
+		parent = NULL;
+		if (cpu_present(cpu))
+			parent = &node_devices[cpu_to_node(cpu)];
 #endif
 		/*
 		 * For now, we just see if the system supports making
diff --git a/arch/ppc64/kernel/time.c b/arch/ppc64/kernel/time.c
--- a/arch/ppc64/kernel/time.c
+++ b/arch/ppc64/kernel/time.c
@@ -91,6 +91,7 @@ unsigned long tb_to_xs;
 unsigned      tb_to_us;
 unsigned long processor_freq;
 DEFINE_SPINLOCK(rtc_lock);
+EXPORT_SYMBOL_GPL(rtc_lock);
 
 unsigned long tb_to_ns_scale;
 unsigned long tb_to_ns_shift;
@@ -98,7 +99,6 @@ unsigned long tb_to_ns_shift;
 struct gettimeofday_struct do_gtod;
 
 extern unsigned long wall_jiffies;
-extern unsigned long lpevent_count;
 extern int smp_tb_synchronized;
 
 extern struct timezone sys_tz;
@@ -107,6 +107,9 @@ void ppc_adjtimex(void);
 
 static unsigned adjusting_time = 0;
 
+unsigned long ppc_proc_freq;
+unsigned long ppc_tb_freq;
+
 static __inline__ void timer_check_rtc(void)
 {
         /*
@@ -363,11 +366,8 @@ int timer_interrupt(struct pt_regs * reg
 	set_dec(next_dec);
 
 #ifdef CONFIG_PPC_ISERIES
-	{
-		struct ItLpQueue *lpq = lpaca->lpqueue_ptr;
-		if (lpq && ItLpQueue_isLpIntPending(lpq))
-			lpevent_count += ItLpQueue_process(lpq, regs);
-	}
+	if (hvlpevent_is_pending())
+		process_hvlpevents(regs);
 #endif
 
 /* collect purr register values often, for accurate calculations */
@@ -472,6 +472,66 @@ int do_settimeofday(struct timespec *tv)
 
 EXPORT_SYMBOL(do_settimeofday);
 
+#if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_MAPLE) || defined(CONFIG_PPC_BPA)
+void __init generic_calibrate_decr(void)
+{
+	struct device_node *cpu;
+	struct div_result divres;
+	unsigned int *fp;
+	int node_found;
+
+	/*
+	 * The cpu node should have a timebase-frequency property
+	 * to tell us the rate at which the decrementer counts.
+	 */
+	cpu = of_find_node_by_type(NULL, "cpu");
+
+	ppc_tb_freq = DEFAULT_TB_FREQ;		/* hardcoded default */
+	node_found = 0;
+	if (cpu != 0) {
+		fp = (unsigned int *)get_property(cpu, "timebase-frequency",
+						  NULL);
+		if (fp != 0) {
+			node_found = 1;
+			ppc_tb_freq = *fp;
+		}
+	}
+	if (!node_found)
+		printk(KERN_ERR "WARNING: Estimating decrementer frequency "
+				"(not found)\n");
+
+	ppc_proc_freq = DEFAULT_PROC_FREQ;
+	node_found = 0;
+	if (cpu != 0) {
+		fp = (unsigned int *)get_property(cpu, "clock-frequency",
+						  NULL);
+		if (fp != 0) {
+			node_found = 1;
+			ppc_proc_freq = *fp;
+		}
+	}
+	if (!node_found)
+		printk(KERN_ERR "WARNING: Estimating processor frequency "
+				"(not found)\n");
+
+	of_node_put(cpu);
+
+	printk(KERN_INFO "time_init: decrementer frequency = %lu.%.6lu MHz\n",
+	       ppc_tb_freq/1000000, ppc_tb_freq%1000000);
+	printk(KERN_INFO "time_init: processor frequency   = %lu.%.6lu MHz\n",
+	       ppc_proc_freq/1000000, ppc_proc_freq%1000000);
+
+	tb_ticks_per_jiffy = ppc_tb_freq / HZ;
+	tb_ticks_per_sec = tb_ticks_per_jiffy * HZ;
+	tb_ticks_per_usec = ppc_tb_freq / 1000000;
+	tb_to_us = mulhwu_scale_factor(ppc_tb_freq, 1000000);
+	div128_by_32(1024*1024, 0, tb_ticks_per_sec, &divres);
+	tb_to_xs = divres.result_low;
+
+	setup_default_decr();
+}
+#endif
+
 void __init time_init(void)
 {
 	/* This function is only called on the boot processor */
diff --git a/arch/ppc64/kernel/traps.c b/arch/ppc64/kernel/traps.c
--- a/arch/ppc64/kernel/traps.c
+++ b/arch/ppc64/kernel/traps.c
@@ -126,6 +126,10 @@ int die(const char *str, struct pt_regs 
 			printk("POWERMAC ");
 			nl = 1;
 			break;
+		case PLATFORM_BPA:
+			printk("BPA ");
+			nl = 1;
+			break;
 	}
 	if (nl)
 		printk("\n");
diff --git a/arch/ppc64/kernel/udbg.c b/arch/ppc64/kernel/udbg.c
--- a/arch/ppc64/kernel/udbg.c
+++ b/arch/ppc64/kernel/udbg.c
@@ -141,7 +141,7 @@ void udbg_init_scc(struct device_node *n
 
 #endif /* CONFIG_PPC_PMAC */
 
-#if CONFIG_PPC_PMAC
+#ifdef CONFIG_PPC_PMAC
 static void udbg_real_putc(unsigned char c)
 {
 	while ((real_readb(sccc) & SCC_TXRDY) == 0)
diff --git a/arch/ppc64/kernel/vdso32/vdso32.lds.S b/arch/ppc64/kernel/vdso32/vdso32.lds.S
--- a/arch/ppc64/kernel/vdso32/vdso32.lds.S
+++ b/arch/ppc64/kernel/vdso32/vdso32.lds.S
@@ -40,9 +40,9 @@ SECTIONS
   .gcc_except_table	: { *(.gcc_except_table) }
   .fixup		: { *(.fixup) }
 
-  .got ALIGN(4)		: { *(.got.plt) *(.got) }
-
   .dynamic		: { *(.dynamic) }		:text	:dynamic
+  .got : { *(.got) }
+  .plt : { *(.plt) }
 
   _end = .;
   __end = .;
diff --git a/arch/ppc64/kernel/vio.c b/arch/ppc64/kernel/vio.c
--- a/arch/ppc64/kernel/vio.c
+++ b/arch/ppc64/kernel/vio.c
@@ -41,20 +41,25 @@ static const struct vio_device_id *vio_m
 static struct iommu_table *vio_build_iommu_table(struct vio_dev *);
 static int vio_num_address_cells;
 #endif
-static struct vio_dev *vio_bus_device; /* fake "parent" device */
-
 #ifdef CONFIG_PPC_ISERIES
-static struct vio_dev *__init vio_register_device_iseries(char *type,
-		uint32_t unit_num);
-
 static struct iommu_table veth_iommu_table;
 static struct iommu_table vio_iommu_table;
-
-static struct vio_dev _vio_dev  = {
+#endif
+static struct vio_dev vio_bus_device  = { /* fake "parent" device */
+	.name = vio_bus_device.dev.bus_id,
+	.type = "",
+#ifdef CONFIG_PPC_ISERIES
 	.iommu_table = &vio_iommu_table,
-	.dev.bus = &vio_bus_type
+#endif
+	.dev.bus_id = "vio",
+	.dev.bus = &vio_bus_type,
 };
-struct device *iSeries_vio_dev = &_vio_dev.dev;
+
+#ifdef CONFIG_PPC_ISERIES
+static struct vio_dev *__init vio_register_device_iseries(char *type,
+		uint32_t unit_num);
+
+struct device *iSeries_vio_dev = &vio_bus_device.dev;
 EXPORT_SYMBOL(iSeries_vio_dev);
 
 #define device_is_compatible(a, b)	1
@@ -260,18 +265,10 @@ static int __init vio_bus_init(void)
 	}
 
 	/* the fake parent of all vio devices, just to give us a nice directory */
-	vio_bus_device = kmalloc(sizeof(struct vio_dev), GFP_KERNEL);
-	if (!vio_bus_device) {
-		return 1;
-	}
-	memset(vio_bus_device, 0, sizeof(struct vio_dev));
-	strcpy(vio_bus_device->dev.bus_id, "vio");
-
-	err = device_register(&vio_bus_device->dev);
+	err = device_register(&vio_bus_device.dev);
 	if (err) {
 		printk(KERN_WARNING "%s: device_register returned %i\n", __FUNCTION__,
 			err);
-		kfree(vio_bus_device);
 		return err;
 	}
 
@@ -300,7 +297,7 @@ static void __devinit vio_dev_release(st
 }
 
 #ifdef CONFIG_PPC_PSERIES
-static ssize_t viodev_show_devspec(struct device *dev, char *buf)
+static ssize_t viodev_show_devspec(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct device_node *of_node = dev->platform_data;
 
@@ -309,7 +306,7 @@ static ssize_t viodev_show_devspec(struc
 DEVICE_ATTR(devspec, S_IRUSR | S_IRGRP | S_IROTH, viodev_show_devspec, NULL);
 #endif
 
-static ssize_t viodev_show_name(struct device *dev, char *buf)
+static ssize_t viodev_show_name(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	return sprintf(buf, "%s\n", to_vio_dev(dev)->name);
 }
@@ -326,7 +323,7 @@ static struct vio_dev * __devinit vio_re
 	viodev->unit_address = unit_address;
 	viodev->iommu_table = iommu_table;
 	/* init generic 'struct device' fields: */
-	viodev->dev.parent = &vio_bus_device->dev;
+	viodev->dev.parent = &vio_bus_device.dev;
 	viodev->dev.bus = &vio_bus_type;
 	viodev->dev.release = vio_dev_release;
 
@@ -636,5 +633,3 @@ struct bus_type vio_bus_type = {
 	.name = "vio",
 	.match = vio_bus_match,
 };
-
-EXPORT_SYMBOL(vio_bus_type);
diff --git a/arch/ppc64/kernel/viopath.c b/arch/ppc64/kernel/viopath.c
--- a/arch/ppc64/kernel/viopath.c
+++ b/arch/ppc64/kernel/viopath.c
@@ -43,12 +43,10 @@
 #include <asm/system.h>
 #include <asm/uaccess.h>
 #include <asm/iSeries/HvTypes.h>
-#include <asm/iSeries/LparData.h>
+#include <asm/iSeries/ItExtVpdPanel.h>
 #include <asm/iSeries/HvLpEvent.h>
 #include <asm/iSeries/HvLpConfig.h>
-#include <asm/iSeries/HvCallCfg.h>
 #include <asm/iSeries/mf.h>
-#include <asm/iSeries/iSeries_proc.h>
 #include <asm/iSeries/vio.h>
 
 /* Status of the path to each other partition in the system.
@@ -365,7 +363,7 @@ void vio_set_hostlp(void)
 	 * while we're active
 	 */
 	viopath_ourLp = HvLpConfig_getLpIndex();
-	viopath_hostLp = HvCallCfg_getHostingLpIndex(viopath_ourLp);
+	viopath_hostLp = HvLpConfig_getHostingLpIndex(viopath_ourLp);
 
 	if (viopath_hostLp != HvLpIndexInvalid)
 		vio_setHandler(viomajorsubtype_config, handleConfig);
@@ -487,7 +485,7 @@ int viopath_open(HvLpIndex remoteLp, int
 	unsigned long flags;
 	int tempNumAllocated;
 
-	if ((remoteLp >= HvMaxArchitectedLps) || (remoteLp == HvLpIndexInvalid))
+	if ((remoteLp >= HVMAXARCHITECTEDLPS) || (remoteLp == HvLpIndexInvalid))
 		return -EINVAL;
 
 	subtype = subtype >> VIOMAJOR_SUBTYPE_SHIFT;
@@ -558,7 +556,7 @@ int viopath_close(HvLpIndex remoteLp, in
 	int numOpen;
 	struct alloc_parms parms;
 
-	if ((remoteLp >= HvMaxArchitectedLps) || (remoteLp == HvLpIndexInvalid))
+	if ((remoteLp >= HVMAXARCHITECTEDLPS) || (remoteLp == HvLpIndexInvalid))
 		return -EINVAL;
 
 	subtype = subtype >> VIOMAJOR_SUBTYPE_SHIFT;
diff --git a/arch/ppc64/kernel/xics.c b/arch/ppc64/kernel/xics.c
--- a/arch/ppc64/kernel/xics.c
+++ b/arch/ppc64/kernel/xics.c
@@ -647,6 +647,32 @@ static void xics_set_affinity(unsigned i
 	}
 }
 
+void xics_teardown_cpu(int secondary)
+{
+	int cpu = smp_processor_id();
+
+	ops->cppr_info(cpu, 0x00);
+	iosync();
+
+	/*
+	 * Some machines need to have at least one cpu in the GIQ,
+	 * so leave the master cpu in the group.
+	 */
+	if (secondary) {
+		/*
+		 * we need to EOI the IPI if we got here from kexec down IPI
+		 *
+		 * probably need to check all the other interrupts too
+		 * should we be flagging idle loop instead?
+		 * or creating some task to be scheduled?
+		 */
+		ops->xirr_info_set(cpu, XICS_IPI);
+		rtas_set_indicator(GLOBAL_INTERRUPT_QUEUE,
+			(1UL << interrupt_server_size) - 1 -
+			default_distrib_server, 0);
+	}
+}
+
 #ifdef CONFIG_HOTPLUG_CPU
 
 /* Interrupts are disabled. */
diff --git a/arch/ppc64/lib/Makefile b/arch/ppc64/lib/Makefile
--- a/arch/ppc64/lib/Makefile
+++ b/arch/ppc64/lib/Makefile
@@ -12,7 +12,7 @@ lib-$(CONFIG_SMP) += locks.o
 
 # e2a provides EBCDIC to ASCII conversions.
 ifdef CONFIG_PPC_ISERIES
-obj-$(CONFIG_PCI)	+= e2a.o
+obj-y += e2a.o
 endif
 
 lib-$(CONFIG_DEBUG_KERNEL) += sstep.o
diff --git a/arch/ppc64/mm/Makefile b/arch/ppc64/mm/Makefile
--- a/arch/ppc64/mm/Makefile
+++ b/arch/ppc64/mm/Makefile
@@ -6,6 +6,6 @@ EXTRA_CFLAGS += -mno-minimal-toc
 
 obj-y := fault.o init.o imalloc.o hash_utils.o hash_low.o tlb.o \
 	slb_low.o slb.o stab.o mmap.o
-obj-$(CONFIG_DISCONTIGMEM) += numa.o
+obj-$(CONFIG_NEED_MULTIPLE_NODES) += numa.o
 obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
 obj-$(CONFIG_PPC_MULTIPLATFORM) += hash_native.o
diff --git a/arch/ppc64/mm/hash_low.S b/arch/ppc64/mm/hash_low.S
--- a/arch/ppc64/mm/hash_low.S
+++ b/arch/ppc64/mm/hash_low.S
@@ -170,9 +170,7 @@ htab_insert_pte:
 	/* Call ppc_md.hpte_insert */
 	ld	r7,STK_PARM(r4)(r1)	/* Retreive new pp bits */
 	mr	r4,r29			/* Retreive va */
-	li	r6,0			/* primary slot */
-	li	r8,0			/* not bolted and not large */
-	li	r9,0
+	li	r6,0			/* no vflags */
 _GLOBAL(htab_call_hpte_insert1)
 	bl	.			/* Will be patched by htab_finish_init() */
 	cmpdi	0,r3,0
@@ -192,9 +190,7 @@ _GLOBAL(htab_call_hpte_insert1)
 	/* Call ppc_md.hpte_insert */
 	ld	r7,STK_PARM(r4)(r1)	/* Retreive new pp bits */
 	mr	r4,r29			/* Retreive va */
-	li	r6,1			/* secondary slot */
-	li	r8,0			/* not bolted and not large */
-	li	r9,0
+	li	r6,HPTE_V_SECONDARY@l	/* secondary slot */
 _GLOBAL(htab_call_hpte_insert2)
 	bl	.			/* Will be patched by htab_finish_init() */
 	cmpdi	0,r3,0
diff --git a/arch/ppc64/mm/hash_native.c b/arch/ppc64/mm/hash_native.c
--- a/arch/ppc64/mm/hash_native.c
+++ b/arch/ppc64/mm/hash_native.c
@@ -27,9 +27,9 @@
 
 static DEFINE_SPINLOCK(native_tlbie_lock);
 
-static inline void native_lock_hpte(HPTE *hptep)
+static inline void native_lock_hpte(hpte_t *hptep)
 {
-	unsigned long *word = &hptep->dw0.dword0;
+	unsigned long *word = &hptep->v;
 
 	while (1) {
 		if (!test_and_set_bit(HPTE_LOCK_BIT, word))
@@ -39,32 +39,28 @@ static inline void native_lock_hpte(HPTE
 	}
 }
 
-static inline void native_unlock_hpte(HPTE *hptep)
+static inline void native_unlock_hpte(hpte_t *hptep)
 {
-	unsigned long *word = &hptep->dw0.dword0;
+	unsigned long *word = &hptep->v;
 
 	asm volatile("lwsync":::"memory");
 	clear_bit(HPTE_LOCK_BIT, word);
 }
 
 long native_hpte_insert(unsigned long hpte_group, unsigned long va,
-			unsigned long prpn, int secondary,
-			unsigned long hpteflags, int bolted, int large)
+			unsigned long prpn, unsigned long vflags,
+			unsigned long rflags)
 {
 	unsigned long arpn = physRpn_to_absRpn(prpn);
-	HPTE *hptep = htab_address + hpte_group;
-	Hpte_dword0 dw0;
-	HPTE lhpte;
+	hpte_t *hptep = htab_address + hpte_group;
+	unsigned long hpte_v, hpte_r;
 	int i;
 
 	for (i = 0; i < HPTES_PER_GROUP; i++) {
-		dw0 = hptep->dw0.dw0;
-
-		if (!dw0.v) {
+		if (! (hptep->v & HPTE_V_VALID)) {
 			/* retry with lock held */
 			native_lock_hpte(hptep);
-			dw0 = hptep->dw0.dw0;
-			if (!dw0.v)
+			if (! (hptep->v & HPTE_V_VALID))
 				break;
 			native_unlock_hpte(hptep);
 		}
@@ -75,56 +71,45 @@ long native_hpte_insert(unsigned long hp
 	if (i == HPTES_PER_GROUP)
 		return -1;
 
-	lhpte.dw1.dword1      = 0;
-	lhpte.dw1.dw1.rpn     = arpn;
-	lhpte.dw1.flags.flags = hpteflags;
-
-	lhpte.dw0.dword0      = 0;
-	lhpte.dw0.dw0.avpn    = va >> 23;
-	lhpte.dw0.dw0.h       = secondary;
-	lhpte.dw0.dw0.bolted  = bolted;
-	lhpte.dw0.dw0.v       = 1;
-
-	if (large) {
-		lhpte.dw0.dw0.l = 1;
-		lhpte.dw0.dw0.avpn &= ~0x1UL;
-	}
-
-	hptep->dw1.dword1 = lhpte.dw1.dword1;
+	hpte_v = (va >> 23) << HPTE_V_AVPN_SHIFT | vflags | HPTE_V_VALID;
+	if (vflags & HPTE_V_LARGE)
+		va &= ~(1UL << HPTE_V_AVPN_SHIFT);
+	hpte_r = (arpn << HPTE_R_RPN_SHIFT) | rflags;
 
+	hptep->r = hpte_r;
 	/* Guarantee the second dword is visible before the valid bit */
 	__asm__ __volatile__ ("eieio" : : : "memory");
-
 	/*
 	 * Now set the first dword including the valid bit
 	 * NOTE: this also unlocks the hpte
 	 */
-	hptep->dw0.dword0 = lhpte.dw0.dword0;
+	hptep->v = hpte_v;
 
 	__asm__ __volatile__ ("ptesync" : : : "memory");
 
-	return i | (secondary << 3);
+	return i | (!!(vflags & HPTE_V_SECONDARY) << 3);
 }
 
 static long native_hpte_remove(unsigned long hpte_group)
 {
-	HPTE *hptep;
-	Hpte_dword0 dw0;
+	hpte_t *hptep;
 	int i;
 	int slot_offset;
+	unsigned long hpte_v;
 
 	/* pick a random entry to start at */
 	slot_offset = mftb() & 0x7;
 
 	for (i = 0; i < HPTES_PER_GROUP; i++) {
 		hptep = htab_address + hpte_group + slot_offset;
-		dw0 = hptep->dw0.dw0;
+		hpte_v = hptep->v;
 
-		if (dw0.v && !dw0.bolted) {
+		if ((hpte_v & HPTE_V_VALID) && !(hpte_v & HPTE_V_BOLTED)) {
 			/* retry with lock held */
 			native_lock_hpte(hptep);
-			dw0 = hptep->dw0.dw0;
-			if (dw0.v && !dw0.bolted)
+			hpte_v = hptep->v;
+			if ((hpte_v & HPTE_V_VALID)
+			    && !(hpte_v & HPTE_V_BOLTED))
 				break;
 			native_unlock_hpte(hptep);
 		}
@@ -137,15 +122,15 @@ static long native_hpte_remove(unsigned 
 		return -1;
 
 	/* Invalidate the hpte. NOTE: this also unlocks it */
-	hptep->dw0.dword0 = 0;
+	hptep->v = 0;
 
 	return i;
 }
 
-static inline void set_pp_bit(unsigned long pp, HPTE *addr)
+static inline void set_pp_bit(unsigned long pp, hpte_t *addr)
 {
 	unsigned long old;
-	unsigned long *p = &addr->dw1.dword1;
+	unsigned long *p = &addr->r;
 
 	__asm__ __volatile__(
 	"1:	ldarx	%0,0,%3\n\
@@ -163,11 +148,11 @@ static inline void set_pp_bit(unsigned l
  */
 static long native_hpte_find(unsigned long vpn)
 {
-	HPTE *hptep;
+	hpte_t *hptep;
 	unsigned long hash;
 	unsigned long i, j;
 	long slot;
-	Hpte_dword0 dw0;
+	unsigned long hpte_v;
 
 	hash = hpt_hash(vpn, 0);
 
@@ -175,10 +160,11 @@ static long native_hpte_find(unsigned lo
 		slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
 		for (i = 0; i < HPTES_PER_GROUP; i++) {
 			hptep = htab_address + slot;
-			dw0 = hptep->dw0.dw0;
+			hpte_v = hptep->v;
 
-			if ((dw0.avpn == (vpn >> 11)) && dw0.v &&
-			    (dw0.h == j)) {
+			if ((HPTE_V_AVPN_VAL(hpte_v) == (vpn >> 11))
+			    && (hpte_v & HPTE_V_VALID)
+			    && ( !!(hpte_v & HPTE_V_SECONDARY) == j)) {
 				/* HPTE matches */
 				if (j)
 					slot = -slot;
@@ -195,20 +181,21 @@ static long native_hpte_find(unsigned lo
 static long native_hpte_updatepp(unsigned long slot, unsigned long newpp,
 				 unsigned long va, int large, int local)
 {
-	HPTE *hptep = htab_address + slot;
-	Hpte_dword0 dw0;
+	hpte_t *hptep = htab_address + slot;
+	unsigned long hpte_v;
 	unsigned long avpn = va >> 23;
 	int ret = 0;
 
 	if (large)
-		avpn &= ~0x1UL;
+		avpn &= ~1;
 
 	native_lock_hpte(hptep);
 
-	dw0 = hptep->dw0.dw0;
+	hpte_v = hptep->v;
 
 	/* Even if we miss, we need to invalidate the TLB */
-	if ((dw0.avpn != avpn) || !dw0.v) {
+	if ((HPTE_V_AVPN_VAL(hpte_v) != avpn)
+	    || !(hpte_v & HPTE_V_VALID)) {
 		native_unlock_hpte(hptep);
 		ret = -1;
 	} else {
@@ -244,7 +231,7 @@ static void native_hpte_updateboltedpp(u
 {
 	unsigned long vsid, va, vpn, flags = 0;
 	long slot;
-	HPTE *hptep;
+	hpte_t *hptep;
 	int lock_tlbie = !cpu_has_feature(CPU_FTR_LOCKLESS_TLBIE);
 
 	vsid = get_kernel_vsid(ea);
@@ -269,26 +256,27 @@ static void native_hpte_updateboltedpp(u
 static void native_hpte_invalidate(unsigned long slot, unsigned long va,
 				    int large, int local)
 {
-	HPTE *hptep = htab_address + slot;
-	Hpte_dword0 dw0;
+	hpte_t *hptep = htab_address + slot;
+	unsigned long hpte_v;
 	unsigned long avpn = va >> 23;
 	unsigned long flags;
 	int lock_tlbie = !cpu_has_feature(CPU_FTR_LOCKLESS_TLBIE);
 
 	if (large)
-		avpn &= ~0x1UL;
+		avpn &= ~1;
 
 	local_irq_save(flags);
 	native_lock_hpte(hptep);
 
-	dw0 = hptep->dw0.dw0;
+	hpte_v = hptep->v;
 
 	/* Even if we miss, we need to invalidate the TLB */
-	if ((dw0.avpn != avpn) || !dw0.v) {
+	if ((HPTE_V_AVPN_VAL(hpte_v) != avpn)
+	    || !(hpte_v & HPTE_V_VALID)) {
 		native_unlock_hpte(hptep);
 	} else {
 		/* Invalidate the hpte. NOTE: this also unlocks it */
-		hptep->dw0.dword0 = 0;
+		hptep->v = 0;
 	}
 
 	/* Invalidate the tlb */
@@ -304,13 +292,57 @@ static void native_hpte_invalidate(unsig
 	local_irq_restore(flags);
 }
 
+/*
+ * clear all mappings on kexec.  All cpus are in real mode (or they will
+ * be when they isi), and we are the only one left.  We rely on our kernel
+ * mapping being 0xC0's and the hardware ignoring those two real bits.
+ *
+ * TODO: add batching support when enabled.  remember, no dynamic memory here,
+ * athough there is the control page available...
+ */
+static void native_hpte_clear(void)
+{
+	unsigned long slot, slots, flags;
+	hpte_t *hptep = htab_address;
+	unsigned long hpte_v;
+	unsigned long pteg_count;
+
+	pteg_count = htab_hash_mask + 1;
+
+	local_irq_save(flags);
+
+	/* we take the tlbie lock and hold it.  Some hardware will
+	 * deadlock if we try to tlbie from two processors at once.
+	 */
+	spin_lock(&native_tlbie_lock);
+
+	slots = pteg_count * HPTES_PER_GROUP;
+
+	for (slot = 0; slot < slots; slot++, hptep++) {
+		/*
+		 * we could lock the pte here, but we are the only cpu
+		 * running,  right?  and for crash dump, we probably
+		 * don't want to wait for a maybe bad cpu.
+		 */
+		hpte_v = hptep->v;
+
+		if (hpte_v & HPTE_V_VALID) {
+			hptep->v = 0;
+			tlbie(slot2va(hpte_v, slot), hpte_v & HPTE_V_LARGE);
+		}
+	}
+
+	spin_unlock(&native_tlbie_lock);
+	local_irq_restore(flags);
+}
+
 static void native_flush_hash_range(unsigned long context,
 				    unsigned long number, int local)
 {
 	unsigned long vsid, vpn, va, hash, secondary, slot, flags, avpn;
 	int i, j;
-	HPTE *hptep;
-	Hpte_dword0 dw0;
+	hpte_t *hptep;
+	unsigned long hpte_v;
 	struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch);
 
 	/* XXX fix for large ptes */
@@ -346,14 +378,15 @@ static void native_flush_hash_range(unsi
 
 		native_lock_hpte(hptep);
 
-		dw0 = hptep->dw0.dw0;
+		hpte_v = hptep->v;
 
 		/* Even if we miss, we need to invalidate the TLB */
-		if ((dw0.avpn != avpn) || !dw0.v) {
+		if ((HPTE_V_AVPN_VAL(hpte_v) != avpn)
+		    || !(hpte_v & HPTE_V_VALID)) {
 			native_unlock_hpte(hptep);
 		} else {
 			/* Invalidate the hpte. NOTE: this also unlocks it */
-			hptep->dw0.dword0 = 0;
+			hptep->v = 0;
 		}
 
 		j++;
@@ -415,7 +448,8 @@ void hpte_init_native(void)
 	ppc_md.hpte_updatepp	= native_hpte_updatepp;
 	ppc_md.hpte_updateboltedpp = native_hpte_updateboltedpp;
 	ppc_md.hpte_insert	= native_hpte_insert;
-	ppc_md.hpte_remove     	= native_hpte_remove;
+	ppc_md.hpte_remove	= native_hpte_remove;
+	ppc_md.hpte_clear_all	= native_hpte_clear;
 	if (tlb_batching_enabled())
 		ppc_md.flush_hash_range = native_flush_hash_range;
 	htab_finish_init();
diff --git a/arch/ppc64/mm/hash_utils.c b/arch/ppc64/mm/hash_utils.c
--- a/arch/ppc64/mm/hash_utils.c
+++ b/arch/ppc64/mm/hash_utils.c
@@ -75,8 +75,8 @@
 extern unsigned long dart_tablebase;
 #endif /* CONFIG_U3_DART */
 
-HPTE		*htab_address;
-unsigned long	htab_hash_mask;
+hpte_t *htab_address;
+unsigned long htab_hash_mask;
 
 extern unsigned long _SDR1;
 
@@ -97,11 +97,15 @@ static inline void create_pte_mapping(un
 	unsigned long addr;
 	unsigned int step;
 	unsigned long tmp_mode;
+	unsigned long vflags;
 
-	if (large)
+	if (large) {
 		step = 16*MB;
-	else
+		vflags = HPTE_V_BOLTED | HPTE_V_LARGE;
+	} else {
 		step = 4*KB;
+		vflags = HPTE_V_BOLTED;
+	}
 
 	for (addr = start; addr < end; addr += step) {
 		unsigned long vpn, hash, hpteg;
@@ -129,12 +133,12 @@ static inline void create_pte_mapping(un
 		if (systemcfg->platform & PLATFORM_LPAR)
 			ret = pSeries_lpar_hpte_insert(hpteg, va,
 				virt_to_abs(addr) >> PAGE_SHIFT,
-				0, tmp_mode, 1, large);
+				vflags, tmp_mode);
 		else
 #endif /* CONFIG_PPC_PSERIES */
 			ret = native_hpte_insert(hpteg, va,
 				virt_to_abs(addr) >> PAGE_SHIFT,
-				0, tmp_mode, 1, large);
+				vflags, tmp_mode);
 
 		if (ret == -1) {
 			ppc64_terminate_msg(0x20, "create_pte_mapping");
@@ -195,7 +199,7 @@ void __init htab_initialize(void)
 		memset((void *)table, 0, htab_size_bytes);
 	}
 
-	mode_rw = _PAGE_ACCESSED | _PAGE_COHERENT | PP_RWXX;
+	mode_rw = _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_COHERENT | PP_RWXX;
 
 	/* On U3 based machines, we need to reserve the DART area and
 	 * _NOT_ map it to avoid cache paradoxes as it's remapped non
@@ -310,10 +314,6 @@ int hash_page(unsigned long ea, unsigned
 
 		vsid = get_vsid(mm->context.id, ea);
 		break;
-	case IO_REGION_ID:
-		mm = &ioremap_mm;
-		vsid = get_kernel_vsid(ea);
-		break;
 	case VMALLOC_REGION_ID:
 		mm = &init_mm;
 		vsid = get_kernel_vsid(ea);
diff --git a/arch/ppc64/mm/hugetlbpage.c b/arch/ppc64/mm/hugetlbpage.c
--- a/arch/ppc64/mm/hugetlbpage.c
+++ b/arch/ppc64/mm/hugetlbpage.c
@@ -121,7 +121,7 @@ static pte_t *hugepte_alloc(struct mm_st
 	return hugepte_offset(dir, addr);
 }
 
-static pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr)
+pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr)
 {
 	pud_t *pud;
 
@@ -134,7 +134,7 @@ static pte_t *huge_pte_offset(struct mm_
 	return hugepte_offset(pud, addr);
 }
 
-static pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr)
+pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr)
 {
 	pud_t *pud;
 
@@ -147,25 +147,6 @@ static pte_t *huge_pte_alloc(struct mm_s
 	return hugepte_alloc(mm, pud, addr);
 }
 
-static void set_huge_pte(struct mm_struct *mm, struct vm_area_struct *vma,
-			 unsigned long addr, struct page *page,
-			 pte_t *ptep, int write_access)
-{
-	pte_t entry;
-
-	add_mm_counter(mm, rss, HPAGE_SIZE / PAGE_SIZE);
-	if (write_access) {
-		entry =
-		    pte_mkwrite(pte_mkdirty(mk_pte(page, vma->vm_page_prot)));
-	} else {
-		entry = pte_wrprotect(mk_pte(page, vma->vm_page_prot));
-	}
-	entry = pte_mkyoung(entry);
-	entry = pte_mkhuge(entry);
-
-	set_pte_at(mm, addr, ptep, entry);
-}
-
 /*
  * This function checks for proper alignment of input addr and len parameters.
  */
@@ -259,80 +240,6 @@ int prepare_hugepage_range(unsigned long
 	return -EINVAL;
 }
 
-int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src,
-			struct vm_area_struct *vma)
-{
-	pte_t *src_pte, *dst_pte, entry;
-	struct page *ptepage;
-	unsigned long addr = vma->vm_start;
-	unsigned long end = vma->vm_end;
-	int err = -ENOMEM;
-
-	while (addr < end) {
-		dst_pte = huge_pte_alloc(dst, addr);
-		if (!dst_pte)
-			goto out;
-
-		src_pte = huge_pte_offset(src, addr);
-		entry = *src_pte;
-		
-		ptepage = pte_page(entry);
-		get_page(ptepage);
-		add_mm_counter(dst, rss, HPAGE_SIZE / PAGE_SIZE);
-		set_pte_at(dst, addr, dst_pte, entry);
-
-		addr += HPAGE_SIZE;
-	}
-
-	err = 0;
- out:
-	return err;
-}
-
-int
-follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma,
-		    struct page **pages, struct vm_area_struct **vmas,
-		    unsigned long *position, int *length, int i)
-{
-	unsigned long vpfn, vaddr = *position;
-	int remainder = *length;
-
-	WARN_ON(!is_vm_hugetlb_page(vma));
-
-	vpfn = vaddr/PAGE_SIZE;
-	while (vaddr < vma->vm_end && remainder) {
-		if (pages) {
-			pte_t *pte;
-			struct page *page;
-
-			pte = huge_pte_offset(mm, vaddr);
-
-			/* hugetlb should be locked, and hence, prefaulted */
-			WARN_ON(!pte || pte_none(*pte));
-
-			page = &pte_page(*pte)[vpfn % (HPAGE_SIZE/PAGE_SIZE)];
-
-			WARN_ON(!PageCompound(page));
-
-			get_page(page);
-			pages[i] = page;
-		}
-
-		if (vmas)
-			vmas[i] = vma;
-
-		vaddr += PAGE_SIZE;
-		++vpfn;
-		--remainder;
-		++i;
-	}
-
-	*length = remainder;
-	*position = vaddr;
-
-	return i;
-}
-
 struct page *
 follow_huge_addr(struct mm_struct *mm, unsigned long address, int write)
 {
@@ -363,89 +270,6 @@ follow_huge_pmd(struct mm_struct *mm, un
 	return NULL;
 }
 
-void unmap_hugepage_range(struct vm_area_struct *vma,
-			  unsigned long start, unsigned long end)
-{
-	struct mm_struct *mm = vma->vm_mm;
-	unsigned long addr;
-	pte_t *ptep;
-	struct page *page;
-
-	WARN_ON(!is_vm_hugetlb_page(vma));
-	BUG_ON((start % HPAGE_SIZE) != 0);
-	BUG_ON((end % HPAGE_SIZE) != 0);
-
-	for (addr = start; addr < end; addr += HPAGE_SIZE) {
-		pte_t pte;
-
-		ptep = huge_pte_offset(mm, addr);
-		if (!ptep || pte_none(*ptep))
-			continue;
-
-		pte = *ptep;
-		page = pte_page(pte);
-		pte_clear(mm, addr, ptep);
-
-		put_page(page);
-	}
-	add_mm_counter(mm, rss, -((end - start) >> PAGE_SHIFT));
-	flush_tlb_pending();
-}
-
-int hugetlb_prefault(struct address_space *mapping, struct vm_area_struct *vma)
-{
-	struct mm_struct *mm = current->mm;
-	unsigned long addr;
-	int ret = 0;
-
-	WARN_ON(!is_vm_hugetlb_page(vma));
-	BUG_ON((vma->vm_start % HPAGE_SIZE) != 0);
-	BUG_ON((vma->vm_end % HPAGE_SIZE) != 0);
-
-	spin_lock(&mm->page_table_lock);
-	for (addr = vma->vm_start; addr < vma->vm_end; addr += HPAGE_SIZE) {
-		unsigned long idx;
-		pte_t *pte = huge_pte_alloc(mm, addr);
-		struct page *page;
-
-		if (!pte) {
-			ret = -ENOMEM;
-			goto out;
-		}
-		if (! pte_none(*pte))
-			continue;
-
-		idx = ((addr - vma->vm_start) >> HPAGE_SHIFT)
-			+ (vma->vm_pgoff >> (HPAGE_SHIFT - PAGE_SHIFT));
-		page = find_get_page(mapping, idx);
-		if (!page) {
-			/* charge the fs quota first */
-			if (hugetlb_get_quota(mapping)) {
-				ret = -ENOMEM;
-				goto out;
-			}
-			page = alloc_huge_page();
-			if (!page) {
-				hugetlb_put_quota(mapping);
-				ret = -ENOMEM;
-				goto out;
-			}
-			ret = add_to_page_cache(page, mapping, idx, GFP_ATOMIC);
-			if (! ret) {
-				unlock_page(page);
-			} else {
-				hugetlb_put_quota(mapping);
-				free_huge_page(page);
-				goto out;
-			}
-		}
-		set_huge_pte(mm, vma, addr, page, pte, vma->vm_flags & VM_WRITE);
-	}
-out:
-	spin_unlock(&mm->page_table_lock);
-	return ret;
-}
-
 /* Because we have an exclusive hugepage region which lies within the
  * normal user address space, we have to take special measures to make
  * non-huge mmap()s evade the hugepage reserved regions. */
@@ -468,7 +292,12 @@ unsigned long arch_get_unmapped_area(str
 		    && !is_hugepage_only_range(mm, addr,len))
 			return addr;
 	}
-	start_addr = addr = mm->free_area_cache;
+	if (len > mm->cached_hole_size) {
+	        start_addr = addr = mm->free_area_cache;
+	} else {
+	        start_addr = addr = TASK_UNMAPPED_BASE;
+	        mm->cached_hole_size = 0;
+	}
 
 full_search:
 	vma = find_vma(mm, addr);
@@ -492,6 +321,8 @@ full_search:
 			mm->free_area_cache = addr + len;
 			return addr;
 		}
+		if (addr + mm->cached_hole_size < vma->vm_start)
+		        mm->cached_hole_size = vma->vm_start - addr;
 		addr = vma->vm_end;
 		vma = vma->vm_next;
 	}
@@ -499,6 +330,7 @@ full_search:
 	/* Make sure we didn't miss any holes */
 	if (start_addr != TASK_UNMAPPED_BASE) {
 		start_addr = addr = TASK_UNMAPPED_BASE;
+		mm->cached_hole_size = 0;
 		goto full_search;
 	}
 	return -ENOMEM;
@@ -520,6 +352,7 @@ arch_get_unmapped_area_topdown(struct fi
 	struct vm_area_struct *vma, *prev_vma;
 	struct mm_struct *mm = current->mm;
 	unsigned long base = mm->mmap_base, addr = addr0;
+	unsigned long largest_hole = mm->cached_hole_size;
 	int first_time = 1;
 
 	/* requested length too big for entire address space */
@@ -540,6 +373,10 @@ arch_get_unmapped_area_topdown(struct fi
 			return addr;
 	}
 
+	if (len <= largest_hole) {
+	        largest_hole = 0;
+		mm->free_area_cache = base;
+	}
 try_again:
 	/* make sure it can fit in the remaining address space */
 	if (mm->free_area_cache < len)
@@ -568,13 +405,21 @@ hugepage_recheck:
 		 * vma->vm_start, use it:
 		 */
 		if (addr+len <= vma->vm_start &&
-				(!prev_vma || (addr >= prev_vma->vm_end)))
+		          (!prev_vma || (addr >= prev_vma->vm_end))) {
 			/* remember the address as a hint for next time */
-			return (mm->free_area_cache = addr);
-		else
+		        mm->cached_hole_size = largest_hole;
+		        return (mm->free_area_cache = addr);
+		} else {
 			/* pull free_area_cache down to the first hole */
-			if (mm->free_area_cache == vma->vm_end)
+		        if (mm->free_area_cache == vma->vm_end) {
 				mm->free_area_cache = vma->vm_start;
+				mm->cached_hole_size = largest_hole;
+			}
+		}
+
+		/* remember the largest hole we saw so far */
+		if (addr + largest_hole < vma->vm_start)
+		        largest_hole = vma->vm_start - addr;
 
 		/* try just below the current vma->vm_start */
 		addr = vma->vm_start-len;
@@ -587,6 +432,7 @@ fail:
 	 */
 	if (first_time) {
 		mm->free_area_cache = base;
+		largest_hole = 0;
 		first_time = 0;
 		goto try_again;
 	}
@@ -597,11 +443,13 @@ fail:
 	 * allocations.
 	 */
 	mm->free_area_cache = TASK_UNMAPPED_BASE;
+	mm->cached_hole_size = ~0UL;
 	addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
 	/*
 	 * Restore the topdown base:
 	 */
 	mm->free_area_cache = base;
+	mm->cached_hole_size = ~0UL;
 
 	return addr;
 }
@@ -735,7 +583,7 @@ int hash_huge_page(struct mm_struct *mm,
 	pte_t *ptep;
 	unsigned long va, vpn;
 	pte_t old_pte, new_pte;
-	unsigned long hpteflags, prpn;
+	unsigned long rflags, prpn;
 	long slot;
 	int err = 1;
 
@@ -778,9 +626,9 @@ int hash_huge_page(struct mm_struct *mm,
 	old_pte = *ptep;
 	new_pte = old_pte;
 
-	hpteflags = 0x2 | (! (pte_val(new_pte) & _PAGE_RW));
+	rflags = 0x2 | (! (pte_val(new_pte) & _PAGE_RW));
  	/* _PAGE_EXEC -> HW_NO_EXEC since it's inverted */
-	hpteflags |= ((pte_val(new_pte) & _PAGE_EXEC) ? 0 : HW_NO_EXEC);
+	rflags |= ((pte_val(new_pte) & _PAGE_EXEC) ? 0 : HW_NO_EXEC);
 
 	/* Check if pte already has an hpte (case 2) */
 	if (unlikely(pte_val(old_pte) & _PAGE_HASHPTE)) {
@@ -793,7 +641,7 @@ int hash_huge_page(struct mm_struct *mm,
 		slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
 		slot += (pte_val(old_pte) & _PAGE_GROUP_IX) >> 12;
 
-		if (ppc_md.hpte_updatepp(slot, hpteflags, va, 1, local) == -1)
+		if (ppc_md.hpte_updatepp(slot, rflags, va, 1, local) == -1)
 			pte_val(old_pte) &= ~_PAGE_HPTEFLAGS;
 	}
 
@@ -813,10 +661,10 @@ repeat:
 
 		/* Add in WIMG bits */
 		/* XXX We should store these in the pte */
-		hpteflags |= _PAGE_COHERENT;
+		rflags |= _PAGE_COHERENT;
 
-		slot = ppc_md.hpte_insert(hpte_group, va, prpn, 0,
-					  hpteflags, 0, 1);
+		slot = ppc_md.hpte_insert(hpte_group, va, prpn,
+					  HPTE_V_LARGE, rflags);
 
 		/* Primary is full, try the secondary */
 		if (unlikely(slot == -1)) {
@@ -824,7 +672,7 @@ repeat:
 			hpte_group = ((~hash & htab_hash_mask) *
 				      HPTES_PER_GROUP) & ~0x7UL; 
 			slot = ppc_md.hpte_insert(hpte_group, va, prpn,
-						  1, hpteflags, 0, 1);
+						  HPTE_V_LARGE, rflags);
 			if (slot == -1) {
 				if (mftb() & 0x1)
 					hpte_group = ((hash & htab_hash_mask) * HPTES_PER_GROUP) & ~0x7UL;
diff --git a/arch/ppc64/mm/imalloc.c b/arch/ppc64/mm/imalloc.c
--- a/arch/ppc64/mm/imalloc.c
+++ b/arch/ppc64/mm/imalloc.c
@@ -15,6 +15,7 @@
 #include <asm/pgtable.h>
 #include <asm/semaphore.h>
 #include <asm/imalloc.h>
+#include <asm/cacheflush.h>
 
 static DECLARE_MUTEX(imlist_sem);
 struct vm_struct * imlist = NULL;
@@ -285,29 +286,32 @@ struct vm_struct * im_get_area(unsigned 
 	return area;
 }
 
-unsigned long im_free(void * addr)
+void im_free(void * addr)
 {
 	struct vm_struct **p, *tmp;
-	unsigned long ret_size = 0;
   
 	if (!addr)
-		return ret_size;
-	if ((PAGE_SIZE-1) & (unsigned long) addr) {
+		return;
+	if ((unsigned long) addr & ~PAGE_MASK) {
 		printk(KERN_ERR "Trying to %s bad address (%p)\n", __FUNCTION__,			addr);
-		return ret_size;
+		return;
 	}
 	down(&imlist_sem);
 	for (p = &imlist ; (tmp = *p) ; p = &tmp->next) {
 		if (tmp->addr == addr) {
-			ret_size = tmp->size;
 			*p = tmp->next;
+
+			/* XXX: do we need the lock? */
+			spin_lock(&init_mm.page_table_lock);
+			unmap_vm_area(tmp);
+			spin_unlock(&init_mm.page_table_lock);
+
 			kfree(tmp);
 			up(&imlist_sem);
-			return ret_size;
+			return;
 		}
 	}
 	up(&imlist_sem);
 	printk(KERN_ERR "Trying to %s nonexistent area (%p)\n", __FUNCTION__,
 			addr);
-	return ret_size;
 }
diff --git a/arch/ppc64/mm/init.c b/arch/ppc64/mm/init.c
--- a/arch/ppc64/mm/init.c
+++ b/arch/ppc64/mm/init.c
@@ -73,9 +73,6 @@ static unsigned long phbs_io_bot = PHBS_
 extern pgd_t swapper_pg_dir[];
 extern struct task_struct *current_set[NR_CPUS];
 
-extern pgd_t ioremap_dir[];
-pgd_t * ioremap_pgd = (pgd_t *)&ioremap_dir;
-
 unsigned long klimit = (unsigned long)_end;
 
 unsigned long _SDR1=0;
@@ -101,7 +98,7 @@ void show_mem(void)
 	printk("Free swap:       %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
 	for_each_pgdat(pgdat) {
 		for (i = 0; i < pgdat->node_spanned_pages; i++) {
-			page = pgdat->node_mem_map + i;
+			page = pgdat_page_nr(pgdat, i);
 			total++;
 			if (PageReserved(page))
 				reserved++;
@@ -137,69 +134,6 @@ void iounmap(volatile void __iomem *addr
 
 #else
 
-static void unmap_im_area_pte(pmd_t *pmd, unsigned long addr,
-				  unsigned long end)
-{
-	pte_t *pte;
-
-	pte = pte_offset_kernel(pmd, addr);
-	do {
-		pte_t ptent = ptep_get_and_clear(&ioremap_mm, addr, pte);
-		WARN_ON(!pte_none(ptent) && !pte_present(ptent));
-	} while (pte++, addr += PAGE_SIZE, addr != end);
-}
-
-static inline void unmap_im_area_pmd(pud_t *pud, unsigned long addr,
-				     unsigned long end)
-{
-	pmd_t *pmd;
-	unsigned long next;
-
-	pmd = pmd_offset(pud, addr);
-	do {
-		next = pmd_addr_end(addr, end);
-		if (pmd_none_or_clear_bad(pmd))
-			continue;
-		unmap_im_area_pte(pmd, addr, next);
-	} while (pmd++, addr = next, addr != end);
-}
-
-static inline void unmap_im_area_pud(pgd_t *pgd, unsigned long addr,
-				     unsigned long end)
-{
-	pud_t *pud;
-	unsigned long next;
-
-	pud = pud_offset(pgd, addr);
-	do {
-		next = pud_addr_end(addr, end);
-		if (pud_none_or_clear_bad(pud))
-			continue;
-		unmap_im_area_pmd(pud, addr, next);
-	} while (pud++, addr = next, addr != end);
-}
-
-static void unmap_im_area(unsigned long addr, unsigned long end)
-{
-	struct mm_struct *mm = &ioremap_mm;
-	unsigned long next;
-	pgd_t *pgd;
-
-	spin_lock(&mm->page_table_lock);
-
-	pgd = pgd_offset_i(addr);
-	flush_cache_vunmap(addr, end);
-	do {
-		next = pgd_addr_end(addr, end);
-		if (pgd_none_or_clear_bad(pgd))
-			continue;
-		unmap_im_area_pud(pgd, addr, next);
-	} while (pgd++, addr = next, addr != end);
-	flush_tlb_kernel_range(start, end);
-
-	spin_unlock(&mm->page_table_lock);
-}
-
 /*
  * map_io_page currently only called by __ioremap
  * map_io_page adds an entry to the ioremap page table
@@ -214,21 +148,21 @@ static int map_io_page(unsigned long ea,
 	unsigned long vsid;
 
 	if (mem_init_done) {
-		spin_lock(&ioremap_mm.page_table_lock);
-		pgdp = pgd_offset_i(ea);
-		pudp = pud_alloc(&ioremap_mm, pgdp, ea);
+		spin_lock(&init_mm.page_table_lock);
+		pgdp = pgd_offset_k(ea);
+		pudp = pud_alloc(&init_mm, pgdp, ea);
 		if (!pudp)
 			return -ENOMEM;
-		pmdp = pmd_alloc(&ioremap_mm, pudp, ea);
+		pmdp = pmd_alloc(&init_mm, pudp, ea);
 		if (!pmdp)
 			return -ENOMEM;
-		ptep = pte_alloc_kernel(&ioremap_mm, pmdp, ea);
+		ptep = pte_alloc_kernel(&init_mm, pmdp, ea);
 		if (!ptep)
 			return -ENOMEM;
 		pa = abs_to_phys(pa);
-		set_pte_at(&ioremap_mm, ea, ptep, pfn_pte(pa >> PAGE_SHIFT,
+		set_pte_at(&init_mm, ea, ptep, pfn_pte(pa >> PAGE_SHIFT,
 							  __pgprot(flags)));
-		spin_unlock(&ioremap_mm.page_table_lock);
+		spin_unlock(&init_mm.page_table_lock);
 	} else {
 		unsigned long va, vpn, hash, hpteg;
 
@@ -246,9 +180,10 @@ static int map_io_page(unsigned long ea,
 		hpteg = ((hash & htab_hash_mask) * HPTES_PER_GROUP);
 
 		/* Panic if a pte grpup is full */
-		if (ppc_md.hpte_insert(hpteg, va, pa >> PAGE_SHIFT, 0,
-				       _PAGE_NO_CACHE|_PAGE_GUARDED|PP_RWXX,
-				       1, 0) == -1) {
+		if (ppc_md.hpte_insert(hpteg, va, pa >> PAGE_SHIFT,
+				       HPTE_V_BOLTED,
+				       _PAGE_NO_CACHE|_PAGE_GUARDED|PP_RWXX)
+		    == -1) {
 			panic("map_io_page: could not insert mapping");
 		}
 	}
@@ -267,13 +202,9 @@ static void __iomem * __ioremap_com(unsi
 
 	for (i = 0; i < size; i += PAGE_SIZE)
 		if (map_io_page(ea+i, pa+i, flags))
-			goto failure;
+			return NULL;
 
 	return (void __iomem *) (ea + (addr & ~PAGE_MASK));
- failure:
-	if (mem_init_done)
-		unmap_im_area(ea, ea + size);
-	return NULL;
 }
 
 
@@ -381,19 +312,14 @@ int __ioremap_explicit(unsigned long pa,
  */
 void iounmap(volatile void __iomem *token)
 {
-	unsigned long address, size;
 	void *addr;
 
 	if (!mem_init_done)
 		return;
 	
 	addr = (void *) ((unsigned long __force) token & PAGE_MASK);
-	
-	if ((size = im_free(addr)) == 0)
-		return;
 
-	address = (unsigned long)addr; 
-	unmap_im_area(address, address + size);
+	im_free(addr);
 }
 
 static int iounmap_subset_regions(unsigned long addr, unsigned long size)
@@ -606,7 +532,7 @@ EXPORT_SYMBOL(page_is_ram);
  * Initialize the bootmem system and give it all the memory we
  * have available.
  */
-#ifndef CONFIG_DISCONTIGMEM
+#ifndef CONFIG_NEED_MULTIPLE_NODES
 void __init do_init_bootmem(void)
 {
 	unsigned long i;
@@ -628,12 +554,20 @@ void __init do_init_bootmem(void)
 
 	max_pfn = max_low_pfn;
 
-	/* add all physical memory to the bootmem map. Also find the first */
+	/* Add all physical memory to the bootmem map, mark each area
+	 * present.
+	 */
 	for (i=0; i < lmb.memory.cnt; i++) {
 		unsigned long physbase, size;
+		unsigned long start_pfn, end_pfn;
 
 		physbase = lmb.memory.region[i].physbase;
 		size = lmb.memory.region[i].size;
+
+		start_pfn = physbase >> PAGE_SHIFT;
+		end_pfn = start_pfn + (size >> PAGE_SHIFT);
+		memory_present(0, start_pfn, end_pfn);
+
 		free_bootmem(physbase, size);
 	}
 
@@ -672,7 +606,7 @@ void __init paging_init(void)
 	free_area_init_node(0, NODE_DATA(0), zones_size,
 			    __pa(PAGE_OFFSET) >> PAGE_SHIFT, zholes_size);
 }
-#endif /* CONFIG_DISCONTIGMEM */
+#endif /* ! CONFIG_NEED_MULTIPLE_NODES */
 
 static struct kcore_list kcore_vmem;
 
@@ -703,7 +637,7 @@ module_init(setup_kcore);
 
 void __init mem_init(void)
 {
-#ifdef CONFIG_DISCONTIGMEM
+#ifdef CONFIG_NEED_MULTIPLE_NODES
 	int nid;
 #endif
 	pg_data_t *pgdat;
@@ -714,7 +648,7 @@ void __init mem_init(void)
 	num_physpages = max_low_pfn;	/* RAM is assumed contiguous */
 	high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
 
-#ifdef CONFIG_DISCONTIGMEM
+#ifdef CONFIG_NEED_MULTIPLE_NODES
         for_each_online_node(nid) {
 		if (NODE_DATA(nid)->node_spanned_pages != 0) {
 			printk("freeing bootmem node %x\n", nid);
@@ -729,7 +663,7 @@ void __init mem_init(void)
 
 	for_each_pgdat(pgdat) {
 		for (i = 0; i < pgdat->node_spanned_pages; i++) {
-			page = pgdat->node_mem_map + i;
+			page = pgdat_page_nr(pgdat, i);
 			if (PageReserved(page))
 				reservedpages++;
 		}
diff --git a/arch/ppc64/mm/numa.c b/arch/ppc64/mm/numa.c
--- a/arch/ppc64/mm/numa.c
+++ b/arch/ppc64/mm/numa.c
@@ -440,6 +440,8 @@ new_range:
 		for (i = start ; i < (start+size); i += MEMORY_INCREMENT)
 			numa_memory_lookup_table[i >> MEMORY_INCREMENT_SHIFT] =
 				numa_domain;
+		memory_present(numa_domain, start >> PAGE_SHIFT,
+						(start + size) >> PAGE_SHIFT);
 
 		if (--ranges)
 			goto new_range;
@@ -481,6 +483,7 @@ static void __init setup_nonnuma(void)
 
 	for (i = 0 ; i < top_of_ram; i += MEMORY_INCREMENT)
 		numa_memory_lookup_table[i >> MEMORY_INCREMENT_SHIFT] = 0;
+	memory_present(0, 0, init_node_data[0].node_end_pfn);
 }
 
 static void __init dump_numa_topology(void)
@@ -644,7 +647,12 @@ void __init do_init_bootmem(void)
 new_range:
 			mem_start = read_n_cells(addr_cells, &memcell_buf);
 			mem_size = read_n_cells(size_cells, &memcell_buf);
-			numa_domain = numa_enabled ? of_node_numa_domain(memory) : 0;
+			if (numa_enabled) {
+				numa_domain = of_node_numa_domain(memory);
+				if (numa_domain  >= MAX_NUMNODES)
+					numa_domain = 0;
+			} else
+				numa_domain =  0;
 
 			if (numa_domain != nid)
 				continue;
diff --git a/arch/ppc64/mm/stab.c b/arch/ppc64/mm/stab.c
--- a/arch/ppc64/mm/stab.c
+++ b/arch/ppc64/mm/stab.c
@@ -18,6 +18,8 @@
 #include <asm/mmu_context.h>
 #include <asm/paca.h>
 #include <asm/cputable.h>
+#include <asm/lmb.h>
+#include <asm/abs_addr.h>
 
 struct stab_entry {
 	unsigned long esid_data;
@@ -224,6 +226,39 @@ void switch_stab(struct task_struct *tsk
 extern void slb_initialize(void);
 
 /*
+ * Allocate segment tables for secondary CPUs.  These must all go in
+ * the first (bolted) segment, so that do_stab_bolted won't get a
+ * recursive segment miss on the segment table itself.
+ */
+void stabs_alloc(void)
+{
+	int cpu;
+
+	if (cpu_has_feature(CPU_FTR_SLB))
+		return;
+
+	for_each_cpu(cpu) {
+		unsigned long newstab;
+
+		if (cpu == 0)
+			continue; /* stab for CPU 0 is statically allocated */
+
+		newstab = lmb_alloc_base(PAGE_SIZE, PAGE_SIZE, 1<<SID_SHIFT);
+		if (! newstab)
+			panic("Unable to allocate segment table for CPU %d.\n",
+			      cpu);
+
+		newstab += KERNELBASE;
+
+		memset((void *)newstab, 0, PAGE_SIZE);
+
+		paca[cpu].stab_addr = newstab;
+		paca[cpu].stab_real = virt_to_abs(newstab);
+		printk(KERN_DEBUG "Segment table for CPU %d at 0x%lx virtual, 0x%lx absolute\n", cpu, paca[cpu].stab_addr, paca[cpu].stab_real);
+	}
+}
+
+/*
  * Build an entry for the base kernel segment and put it into
  * the segment table or SLB.  All other segment table or SLB
  * entries are faulted in.
diff --git a/arch/ppc64/xmon/xmon.c b/arch/ppc64/xmon/xmon.c
--- a/arch/ppc64/xmon/xmon.c
+++ b/arch/ppc64/xmon/xmon.c
@@ -329,13 +329,16 @@ int xmon_core(struct pt_regs *regs, int 
 		printf("cpu 0x%x: Exception %lx %s in xmon, "
 		       "returning to main loop\n",
 		       cpu, regs->trap, getvecname(TRAP(regs)));
+		release_output_lock();
 		longjmp(xmon_fault_jmp[cpu], 1);
 	}
 
 	if (setjmp(recurse_jmp) != 0) {
 		if (!in_xmon || !xmon_gate) {
+			get_output_lock();
 			printf("xmon: WARNING: bad recursive fault "
 			       "on cpu 0x%x\n", cpu);
+			release_output_lock();
 			goto waiting;
 		}
 		secondary = !(xmon_taken && cpu == xmon_owner);
@@ -2247,7 +2250,14 @@ scanhex(unsigned long *vp)
 			tmpstr[i] = c;
 		}
 		tmpstr[i++] = 0;
-		*vp = kallsyms_lookup_name(tmpstr);
+		*vp = 0;
+		if (setjmp(bus_error_jmp) == 0) {
+			catch_memory_errors = 1;
+			sync();
+			*vp = kallsyms_lookup_name(tmpstr);
+			sync();
+		}
+		catch_memory_errors = 0;
 		if (!(*vp)) {
 			printf("unknown symbol '%s'\n", tmpstr);
 			return 0;
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -226,6 +226,8 @@ config WARN_STACK_SIZE
 	  This allows you to specify the maximum frame size a function may
 	  have without the compiler complaining about it.
 
+source "mm/Kconfig"
+
 comment "I/O subsystem configuration"
 
 config MACHCHK_WARNING
@@ -453,8 +455,18 @@ config NO_IDLE_HZ_INIT
 	  The HZ timer is switched off in idle by default. That means the
 	  HZ timer is already disabled at boot time.
 
+config KEXEC
+	bool "kexec system call (EXPERIMENTAL)"
+	depends on EXPERIMENTAL
+	help
+	  kexec is a system call that implements the ability to shutdown your
+	  current kernel, and to start another kernel.  It is like a reboot
+	  but is independent of hardware/microcode support.
+
 endmenu
 
+source "net/Kconfig"
+
 config PCMCIA
 	bool
 	default n
@@ -465,7 +477,7 @@ source "drivers/scsi/Kconfig"
 
 source "drivers/s390/Kconfig"
 
-source "net/Kconfig"
+source "drivers/net/Kconfig"
 
 source "fs/Kconfig"
 
diff --git a/arch/s390/appldata/appldata_base.c b/arch/s390/appldata/appldata_base.c
--- a/arch/s390/appldata/appldata_base.c
+++ b/arch/s390/appldata/appldata_base.c
@@ -232,7 +232,11 @@ static int appldata_diag(char record_nr,
 	ry = -1;
 	asm volatile(
 			"diag %1,%0,0xDC\n\t"
-			: "=d" (ry) : "d" (&(appldata_parameter_list)) : "cc");
+			: "=d" (ry)
+			: "d" (&appldata_parameter_list),
+			  "m" (appldata_parameter_list),
+			  "m" (appldata_product_id)
+			: "cc");
 	return (int) ry;
 }
 /************************ timer, work, DIAG <END> ****************************/
diff --git a/arch/s390/boot/install.sh b/arch/s390/boot/install.sh
--- a/arch/s390/boot/install.sh
+++ b/arch/s390/boot/install.sh
@@ -21,8 +21,8 @@
 
 # User may have a custom install script
 
-if [ -x ~/bin/installkernel ]; then exec ~/bin/installkernel "$@"; fi
-if [ -x /sbin/installkernel ]; then exec /sbin/installkernel "$@"; fi
+if [ -x ~/bin/${CROSS_COMPILE}installkernel ]; then exec ~/bin/${CROSS_COMPILE}installkernel "$@"; fi
+if [ -x /sbin/${CROSS_COMPILE}installkernel ]; then exec /sbin/${CROSS_COMPILE}installkernel "$@"; fi
 
 # Default install - same as make zlilo
 
diff --git a/arch/s390/defconfig b/arch/s390/defconfig
--- a/arch/s390/defconfig
+++ b/arch/s390/defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc3
-# Fri Apr 22 15:30:58 2005
+# Linux kernel version: 2.6.13-rc4
+# Fri Jul 29 14:49:30 2005
 #
 CONFIG_MMU=y
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
@@ -23,10 +23,11 @@ CONFIG_INIT_ENV_ARG_LIMIT=32
 CONFIG_LOCALVERSION=""
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
-# CONFIG_POSIX_MQUEUE is not set
+CONFIG_POSIX_MQUEUE=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
+CONFIG_AUDIT=y
+# CONFIG_AUDITSYSCALL is not set
 CONFIG_HOTPLUG=y
 CONFIG_KOBJECT_UEVENT=y
 CONFIG_IKCONFIG=y
@@ -36,6 +37,8 @@ CONFIG_IKCONFIG_PROC=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
@@ -51,9 +54,10 @@ CONFIG_BASE_SMALL=0
 # Loadable module support
 #
 CONFIG_MODULES=y
-# CONFIG_MODULE_UNLOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
 CONFIG_OBSOLETE_MODPARM=y
-# CONFIG_MODVERSIONS is not set
+CONFIG_MODVERSIONS=y
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_KMOD=y
 CONFIG_STOP_MACHINE=y
@@ -81,8 +85,15 @@ CONFIG_MARCH_G5=y
 # CONFIG_MARCH_Z990 is not set
 CONFIG_PACK_STACK=y
 # CONFIG_SMALL_STACK is not set
-# CONFIG_CHECK_STACK is not set
+CONFIG_CHECK_STACK=y
+CONFIG_STACK_GUARD=256
 # CONFIG_WARN_STACK is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
 
 #
 # I/O subsystem configuration
@@ -95,7 +106,7 @@ CONFIG_QDIO=y
 #
 # Misc
 #
-# CONFIG_PREEMPT is not set
+CONFIG_PREEMPT=y
 CONFIG_IPL=y
 # CONFIG_IPL_TAPE is not set
 CONFIG_IPL_VM=y
@@ -105,9 +116,110 @@ CONFIG_BINFMT_MISC=m
 CONFIG_PFAULT=y
 # CONFIG_SHARED_KERNEL is not set
 # CONFIG_CMM is not set
-# CONFIG_VIRT_TIMER is not set
+CONFIG_VIRT_TIMER=y
+CONFIG_VIRT_CPU_ACCOUNTING=y
+# CONFIG_APPLDATA_BASE is not set
 CONFIG_NO_IDLE_HZ=y
 CONFIG_NO_IDLE_HZ_INIT=y
+# CONFIG_KEXEC is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_IP_TCPDIAG=y
+CONFIG_IP_TCPDIAG_IPV6=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+CONFIG_IPV6=y
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_IPV6_TUNNEL is not set
+# CONFIG_NETFILTER is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_CLK_JIFFIES=y
+# CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set
+# CONFIG_NET_SCH_CLK_CPU is not set
+CONFIG_NET_SCH_CBQ=m
+# CONFIG_NET_SCH_HTB is not set
+# CONFIG_NET_SCH_HFSC is not set
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+# CONFIG_NET_SCH_NETEM is not set
+# CONFIG_NET_SCH_INGRESS is not set
+CONFIG_NET_QOS=y
+CONFIG_NET_ESTIMATOR=y
+CONFIG_NET_CLS=y
+# CONFIG_NET_CLS_BASIC is not set
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_ROUTE=y
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+# CONFIG_CLS_U32_PERF is not set
+# CONFIG_NET_CLS_IND is not set
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+# CONFIG_NET_EMATCH is not set
+# CONFIG_NET_CLS_ACT is not set
+CONFIG_NET_CLS_POLICE=y
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
 # CONFIG_PCMCIA is not set
 
 #
@@ -133,6 +245,7 @@ CONFIG_CHR_DEV_ST=y
 CONFIG_BLK_DEV_SR=y
 CONFIG_BLK_DEV_SR_VENDOR=y
 CONFIG_CHR_DEV_SG=y
+# CONFIG_CHR_DEV_SCH is not set
 
 #
 # Some SCSI devices (e.g. CD jukebox) support multiple LUNs
@@ -205,7 +318,13 @@ CONFIG_MD_RAID5=m
 # CONFIG_MD_RAID6 is not set
 CONFIG_MD_MULTIPATH=m
 # CONFIG_MD_FAULTY is not set
-# CONFIG_BLK_DEV_DM is not set
+CONFIG_BLK_DEV_DM=y
+CONFIG_DM_CRYPT=y
+CONFIG_DM_SNAPSHOT=y
+CONFIG_DM_MIRROR=y
+CONFIG_DM_ZERO=y
+CONFIG_DM_MULTIPATH=y
+# CONFIG_DM_MULTIPATH_EMC is not set
 
 #
 # Character device drivers
@@ -231,7 +350,8 @@ CONFIG_CCW_CONSOLE=y
 CONFIG_SCLP=y
 CONFIG_SCLP_TTY=y
 CONFIG_SCLP_CONSOLE=y
-# CONFIG_SCLP_VT220_TTY is not set
+CONFIG_SCLP_VT220_TTY=y
+CONFIG_SCLP_VT220_CONSOLE=y
 CONFIG_SCLP_CPI=m
 CONFIG_S390_TAPE=m
 
@@ -245,6 +365,7 @@ CONFIG_S390_TAPE_BLOCK=y
 #
 CONFIG_S390_TAPE_34XX=m
 # CONFIG_VMLOGRDR is not set
+# CONFIG_VMCP is not set
 # CONFIG_MONREADER is not set
 # CONFIG_DCSS_SHM is not set
 
@@ -254,105 +375,8 @@ CONFIG_S390_TAPE_34XX=m
 CONFIG_Z90CRYPT=m
 
 #
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-CONFIG_UNIX=y
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-# CONFIG_IP_PNP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_TUNNEL is not set
-CONFIG_IP_TCPDIAG=y
-CONFIG_IP_TCPDIAG_IPV6=y
-CONFIG_IPV6=y
-# CONFIG_IPV6_PRIVACY is not set
-# CONFIG_INET6_AH is not set
-# CONFIG_INET6_ESP is not set
-# CONFIG_INET6_IPCOMP is not set
-# CONFIG_INET6_TUNNEL is not set
-# CONFIG_IPV6_TUNNEL is not set
-# CONFIG_NETFILTER is not set
-CONFIG_XFRM=y
-# CONFIG_XFRM_USER is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-CONFIG_NET_SCHED=y
-CONFIG_NET_SCH_CLK_JIFFIES=y
-# CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set
-# CONFIG_NET_SCH_CLK_CPU is not set
-CONFIG_NET_SCH_CBQ=m
-# CONFIG_NET_SCH_HTB is not set
-# CONFIG_NET_SCH_HFSC is not set
-CONFIG_NET_SCH_PRIO=m
-CONFIG_NET_SCH_RED=m
-CONFIG_NET_SCH_SFQ=m
-CONFIG_NET_SCH_TEQL=m
-CONFIG_NET_SCH_TBF=m
-CONFIG_NET_SCH_GRED=m
-CONFIG_NET_SCH_DSMARK=m
-# CONFIG_NET_SCH_NETEM is not set
-# CONFIG_NET_SCH_INGRESS is not set
-CONFIG_NET_QOS=y
-CONFIG_NET_ESTIMATOR=y
-CONFIG_NET_CLS=y
-# CONFIG_NET_CLS_BASIC is not set
-CONFIG_NET_CLS_TCINDEX=m
-CONFIG_NET_CLS_ROUTE4=m
-CONFIG_NET_CLS_ROUTE=y
-CONFIG_NET_CLS_FW=m
-CONFIG_NET_CLS_U32=m
-# CONFIG_CLS_U32_PERF is not set
-# CONFIG_NET_CLS_IND is not set
-CONFIG_NET_CLS_RSVP=m
-CONFIG_NET_CLS_RSVP6=m
-# CONFIG_NET_EMATCH is not set
-# CONFIG_NET_CLS_ACT is not set
-CONFIG_NET_CLS_POLICE=y
-
-#
-# Network testing
+# Network device support
 #
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
 CONFIG_NETDEVICES=y
 CONFIG_DUMMY=m
 CONFIG_BONDING=m
@@ -410,12 +434,15 @@ CONFIG_CCWGROUP=y
 # CONFIG_SLIP is not set
 # CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
 
 #
 # File systems
 #
 CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
 CONFIG_EXT3_FS=y
 CONFIG_EXT3_FS_XATTR=y
 # CONFIG_EXT3_FS_POSIX_ACL is not set
@@ -425,6 +452,7 @@ CONFIG_JBD=y
 CONFIG_FS_MBCACHE=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
 
 #
 # XFS support
@@ -432,6 +460,7 @@ CONFIG_FS_MBCACHE=y
 # CONFIG_XFS_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
 # CONFIG_QUOTA is not set
 CONFIG_DNOTIFY=y
 # CONFIG_AUTOFS_FS is not set
@@ -456,7 +485,6 @@ CONFIG_DNOTIFY=y
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
 CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
 # CONFIG_DEVPTS_FS_XATTR is not set
 CONFIG_TMPFS=y
 # CONFIG_TMPFS_XATTR is not set
@@ -485,15 +513,18 @@ CONFIG_RAMFS=y
 #
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
 # CONFIG_NFS_V4 is not set
 # CONFIG_NFS_DIRECTIO is not set
 CONFIG_NFSD=y
 CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
 # CONFIG_NFSD_V4 is not set
 CONFIG_NFSD_TCP=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_EXPORTFS=y
+CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -543,11 +574,12 @@ CONFIG_MAGIC_SYSRQ=y
 CONFIG_LOG_BUF_SHIFT=17
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_DEBUG_SLAB is not set
+CONFIG_DEBUG_PREEMPT=y
 # CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_KOBJECT is not set
 # CONFIG_DEBUG_INFO is not set
-# CONFIG_DEBUG_FS is not set
+CONFIG_DEBUG_FS=y
 
 #
 # Security options
diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile
--- a/arch/s390/kernel/Makefile
+++ b/arch/s390/kernel/Makefile
@@ -25,6 +25,16 @@ obj-$(CONFIG_ARCH_S390X)	+= entry64.o re
 
 obj-$(CONFIG_VIRT_TIMER)	+= vtime.o
 
+# Kexec part
+S390_KEXEC_OBJS := machine_kexec.o crash.o
+ifeq ($(CONFIG_ARCH_S390X),y)
+S390_KEXEC_OBJS += relocate_kernel64.o
+else
+S390_KEXEC_OBJS += relocate_kernel.o
+endif
+obj-$(CONFIG_KEXEC) += $(S390_KEXEC_OBJS)
+
+
 #
 # This is just to get the dependencies...
 #
diff --git a/arch/s390/kernel/compat_ioctl.c b/arch/s390/kernel/compat_ioctl.c
--- a/arch/s390/kernel/compat_ioctl.c
+++ b/arch/s390/kernel/compat_ioctl.c
@@ -42,7 +42,6 @@ struct ioctl_trans ioctl_start[] = {
 #include "../../../fs/compat_ioctl.c"
 
 /* s390 only ioctls */
-#if defined(CONFIG_DASD) || defined(CONFIG_DASD_MODULE)
 COMPATIBLE_IOCTL(DASDAPIVER)
 COMPATIBLE_IOCTL(BIODASDDISABLE)
 COMPATIBLE_IOCTL(BIODASDENABLE)
@@ -59,16 +58,11 @@ COMPATIBLE_IOCTL(BIODASDPRRD)
 COMPATIBLE_IOCTL(BIODASDPSRD)
 COMPATIBLE_IOCTL(BIODASDGATTR)
 COMPATIBLE_IOCTL(BIODASDSATTR)
-#if defined(CONFIG_DASD_CMB) || defined(CONFIG_DASD_CMB_MODULE)
 COMPATIBLE_IOCTL(BIODASDCMFENABLE)
 COMPATIBLE_IOCTL(BIODASDCMFDISABLE)
 COMPATIBLE_IOCTL(BIODASDREADALLCMB)
-#endif
-#endif
 
-#if defined(CONFIG_S390_TAPE) || defined(CONFIG_S390_TAPE_MODULE)
 COMPATIBLE_IOCTL(TAPE390_DISPLAY)
-#endif
 
 /* s390 doesn't need handlers here */
 COMPATIBLE_IOCTL(TIOCGSERIAL)
diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c
--- a/arch/s390/kernel/compat_linux.c
+++ b/arch/s390/kernel/compat_linux.c
@@ -58,6 +58,7 @@
 #include <linux/compat.h>
 #include <linux/vfs.h>
 #include <linux/ptrace.h>
+#include <linux/fadvise.h>
 
 #include <asm/types.h>
 #include <asm/ipc.h>
@@ -1043,3 +1044,40 @@ sys32_timer_create(clockid_t which_clock
 
 	return ret;
 }
+
+/*
+ * 31 bit emulation wrapper functions for sys_fadvise64/fadvise64_64.
+ * These need to rewrite the advise values for POSIX_FADV_{DONTNEED,NOREUSE}
+ * because the 31 bit values differ from the 64 bit values.
+ */
+
+asmlinkage long
+sys32_fadvise64(int fd, loff_t offset, size_t len, int advise)
+{
+	if (advise == 4)
+		advise = POSIX_FADV_DONTNEED;
+	else if (advise == 5)
+		advise = POSIX_FADV_NOREUSE;
+	return sys_fadvise64(fd, offset, len, advise);
+}
+
+struct fadvise64_64_args {
+	int fd;
+	long long offset;
+	long long len;
+	int advice;
+};
+
+asmlinkage long
+sys32_fadvise64_64(struct fadvise64_64_args __user *args)
+{
+	struct fadvise64_64_args a;
+
+	if ( copy_from_user(&a, args, sizeof(a)) )
+		return -EFAULT;
+	if (a.advice == 4)
+		a.advice = POSIX_FADV_DONTNEED;
+	else if (a.advice == 5)
+		a.advice = POSIX_FADV_NOREUSE;
+	return sys_fadvise64_64(a.fd, a.offset, a.len, a.advice);
+}
diff --git a/arch/s390/kernel/compat_linux.h b/arch/s390/kernel/compat_linux.h
--- a/arch/s390/kernel/compat_linux.h
+++ b/arch/s390/kernel/compat_linux.h
@@ -45,7 +45,7 @@ typedef struct compat_siginfo {
 
 		/* POSIX.1b timers */
 		struct {
-			timer_t _tid;		/* timer id */
+			compat_timer_t _tid;		/* timer id */
 			int _overrun;		/* overrun count */
 			compat_sigval_t _sigval;	/* same as below */
 			int _sys_private;       /* not to be passed to user */
diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S
--- a/arch/s390/kernel/compat_wrapper.S
+++ b/arch/s390/kernel/compat_wrapper.S
@@ -1251,12 +1251,12 @@ sys32_fadvise64_wrapper:
 	or	%r3,%r4			# get low word of 64bit loff_t
 	llgfr	%r4,%r5			# size_t (unsigned long)
 	lgfr	%r5,%r6			# int
-	jg	sys_fadvise64
+	jg	sys32_fadvise64
 
 	.globl	sys32_fadvise64_64_wrapper
 sys32_fadvise64_64_wrapper:
 	llgtr	%r2,%r2			# struct fadvise64_64_args *
-	jg	s390_fadvise64_64
+	jg	sys32_fadvise64_64
 
 	.globl	sys32_clock_settime_wrapper
 sys32_clock_settime_wrapper:
@@ -1441,3 +1441,37 @@ compat_sys_waitid_wrapper:
 	lgfr	%r5,%r5			# int
 	llgtr	%r6,%r6			# struct rusage_emu31 *
 	jg	compat_sys_waitid
+
+	.globl	compat_sys_kexec_load_wrapper
+compat_sys_kexec_load_wrapper:
+	llgfr	%r2,%r2			# unsigned long
+	llgfr	%r3,%r3			# unsigned long
+	llgtr	%r4,%r4			# struct kexec_segment *
+	llgfr	%r5,%r5			# unsigned long
+	jg	compat_sys_kexec_load
+
+	.globl	sys_ioprio_set_wrapper
+sys_ioprio_set_wrapper:
+	lgfr	%r2,%r2			# int
+	lgfr	%r3,%r3			# int
+	lgfr	%r4,%r4			# int
+	jg	sys_ioprio_set
+
+	.globl	sys_ioprio_get_wrapper
+sys_ioprio_get_wrapper:
+	lgfr	%r2,%r2			# int
+	lgfr	%r3,%r3			# int
+	jg	sys_ioprio_get
+
+	.globl	sys_inotify_add_watch_wrapper
+sys_inotify_add_watch_wrapper:
+	lgfr	%r2,%r2			# int
+	llgtr	%r3,%r3			# const char *
+	llgfr	%r4,%r4			# u32
+	jg	sys_inotify_add_watch
+
+	.globl	sys_inotify_rm_watch_wrapper
+sys_inotify_rm_watch_wrapper:
+	lgfr	%r2,%r2			# int
+	llgfr	%r3,%r3			# u32
+	jg	sys_inotify_rm_watch
diff --git a/arch/s390/kernel/cpcmd.c b/arch/s390/kernel/cpcmd.c
--- a/arch/s390/kernel/cpcmd.c
+++ b/arch/s390/kernel/cpcmd.c
@@ -2,7 +2,7 @@
  *  arch/s390/kernel/cpcmd.c
  *
  *  S390 version
- *    Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
+ *    Copyright (C) 1999,2005 IBM Deutschland Entwicklung GmbH, IBM Corporation
  *    Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
  *               Christian Borntraeger (cborntra@de.ibm.com),
  */
@@ -18,93 +18,114 @@
 #include <asm/system.h>
 
 static DEFINE_SPINLOCK(cpcmd_lock);
-static char cpcmd_buf[240];
+static char cpcmd_buf[241];
 
 /*
  * the caller of __cpcmd has to ensure that the response buffer is below 2 GB
  */
-void __cpcmd(char *cmd, char *response, int rlen)
+int  __cpcmd(const char *cmd, char *response, int rlen, int *response_code)
 {
 	const int mask = 0x40000000L;
 	unsigned long flags;
+	int return_code;
+	int return_len;
 	int cmdlen;
 
 	spin_lock_irqsave(&cpcmd_lock, flags);
 	cmdlen = strlen(cmd);
 	BUG_ON(cmdlen > 240);
-	strcpy(cpcmd_buf, cmd);
+	memcpy(cpcmd_buf, cmd, cmdlen);
 	ASCEBC(cpcmd_buf, cmdlen);
 
 	if (response != NULL && rlen > 0) {
 		memset(response, 0, rlen);
 #ifndef CONFIG_ARCH_S390X
-		asm volatile ("LRA   2,0(%0)\n\t"
-                              "LR    4,%1\n\t"
-                              "O     4,%4\n\t"
-                              "LRA   3,0(%2)\n\t"
-                              "LR    5,%3\n\t"
-                              ".long 0x83240008 # Diagnose X'08'\n\t"
-                              : /* no output */
-                              : "a" (cpcmd_buf), "d" (cmdlen),
-                                "a" (response), "d" (rlen), "m" (mask)
-                              : "cc", "2", "3", "4", "5" );
+		asm volatile (	"lra	2,0(%2)\n"
+				"lr	4,%3\n"
+				"o	4,%6\n"
+				"lra	3,0(%4)\n"
+				"lr	5,%5\n"
+				"diag	2,4,0x8\n"
+				"brc	8, 1f\n"
+				"ar	5, %5\n"
+				"1: \n"
+				"lr	%0,4\n"
+				"lr	%1,5\n"
+				: "=d" (return_code), "=d" (return_len)
+				: "a" (cpcmd_buf), "d" (cmdlen),
+				"a" (response), "d" (rlen), "m" (mask)
+				: "cc", "2", "3", "4", "5" );
 #else /* CONFIG_ARCH_S390X */
-                asm volatile ("   lrag  2,0(%0)\n"
-                              "   lgr   4,%1\n"
-                              "   o     4,%4\n"
-                              "   lrag  3,0(%2)\n"
-                              "   lgr   5,%3\n"
-                              "   sam31\n"
-                              "   .long 0x83240008 # Diagnose X'08'\n"
-                              "   sam64"
-                              : /* no output */
-                              : "a" (cpcmd_buf), "d" (cmdlen),
-                                "a" (response), "d" (rlen), "m" (mask)
-                              : "cc", "2", "3", "4", "5" );
+                asm volatile (	"lrag	2,0(%2)\n"
+				"lgr	4,%3\n"
+				"o	4,%6\n"
+				"lrag	3,0(%4)\n"
+				"lgr	5,%5\n"
+				"sam31\n"
+				"diag	2,4,0x8\n"
+				"sam64\n"
+				"brc	8, 1f\n"
+				"agr	5, %5\n"
+				"1: \n"
+				"lgr	%0,4\n"
+				"lgr	%1,5\n"
+				: "=d" (return_code), "=d" (return_len)
+				: "a" (cpcmd_buf), "d" (cmdlen),
+				"a" (response), "d" (rlen), "m" (mask)
+				: "cc", "2", "3", "4", "5" );
 #endif /* CONFIG_ARCH_S390X */
                 EBCASC(response, rlen);
         } else {
+		return_len = 0;
 #ifndef CONFIG_ARCH_S390X
-                asm volatile ("LRA   2,0(%0)\n\t"
-                              "LR    3,%1\n\t"
-                              ".long 0x83230008 # Diagnose X'08'\n\t"
-                              : /* no output */
-                              : "a" (cpcmd_buf), "d" (cmdlen)
-                              : "2", "3"  );
+                asm volatile (	"lra	2,0(%1)\n"
+				"lr	3,%2\n"
+				"diag	2,3,0x8\n"
+				"lr	%0,3\n"
+				: "=d" (return_code)
+				: "a" (cpcmd_buf), "d" (cmdlen)
+				: "2", "3"  );
 #else /* CONFIG_ARCH_S390X */
-                asm volatile ("   lrag  2,0(%0)\n"
-                              "   lgr   3,%1\n"
-                              "   sam31\n"
-                              "   .long 0x83230008 # Diagnose X'08'\n"
-                              "   sam64"
-                              : /* no output */
-                              : "a" (cpcmd_buf), "d" (cmdlen)
-                              : "2", "3"  );
+                asm volatile (	"lrag	2,0(%1)\n"
+				"lgr	3,%2\n"
+				"sam31\n"
+				"diag	2,3,0x8\n"
+				"sam64\n"
+				"lgr	%0,3\n"
+				: "=d" (return_code)
+				: "a" (cpcmd_buf), "d" (cmdlen)
+				: "2", "3" );
 #endif /* CONFIG_ARCH_S390X */
         }
 	spin_unlock_irqrestore(&cpcmd_lock, flags);
+	if (response_code != NULL)
+		*response_code = return_code;
+	return return_len;
 }
 
 EXPORT_SYMBOL(__cpcmd);
 
 #ifdef CONFIG_ARCH_S390X
-void cpcmd(char *cmd, char *response, int rlen)
+int cpcmd(const char *cmd, char *response, int rlen, int *response_code)
 {
 	char *lowbuf;
+	int len;
+
 	if ((rlen == 0) || (response == NULL)
 	    || !((unsigned long)response >> 31))
-		__cpcmd(cmd, response, rlen);
+		len = __cpcmd(cmd, response, rlen, response_code);
 	else {
 		lowbuf = kmalloc(rlen, GFP_KERNEL | GFP_DMA);
 		if (!lowbuf) {
 			printk(KERN_WARNING
 				"cpcmd: could not allocate response buffer\n");
-			return;
+			return -ENOMEM;
 		}
-		__cpcmd(cmd, lowbuf, rlen);
+		len = __cpcmd(cmd, lowbuf, rlen, response_code);
 		memcpy(response, lowbuf, rlen);
 		kfree(lowbuf);
 	}
+	return len;
 }
 
 EXPORT_SYMBOL(cpcmd);
diff --git a/arch/s390/kernel/crash.c b/arch/s390/kernel/crash.c
new file mode 100644
--- /dev/null
+++ b/arch/s390/kernel/crash.c
@@ -0,0 +1,17 @@
+/*
+ * arch/s390/kernel/crash.c
+ *
+ * (C) Copyright IBM Corp. 2005
+ *
+ * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>
+ *
+ */
+
+#include <linux/threads.h>
+#include <linux/kexec.h>
+
+note_buf_t crash_notes[NR_CPUS];
+
+void machine_crash_shutdown(struct pt_regs *regs)
+{
+}
diff --git a/arch/s390/kernel/debug.c b/arch/s390/kernel/debug.c
--- a/arch/s390/kernel/debug.c
+++ b/arch/s390/kernel/debug.c
@@ -19,22 +19,27 @@
 #include <linux/sysctl.h>
 #include <asm/uaccess.h>
 #include <asm/semaphore.h>
-
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/debugfs.h>
 
 #include <asm/debug.h>
 
 #define DEBUG_PROLOG_ENTRY -1
 
+#define ALL_AREAS 0 /* copy all debug areas */
+#define NO_AREAS  1 /* copy no debug areas */
+
 /* typedefs */
 
 typedef struct file_private_info {
 	loff_t offset;			/* offset of last read in file */
 	int    act_area;                /* number of last formated area */
+	int    act_page;                /* act page in given area */
 	int    act_entry;               /* last formated entry (offset */
                                         /* relative to beginning of last */
-                                        /* formated area) */ 
+                                        /* formated page) */
 	size_t act_entry_offset;        /* up to this offset we copied */
 					/* in last read the last formated */
 					/* entry to userland */
@@ -51,8 +56,8 @@ typedef struct
 	 * This assumes that all args are converted into longs 
 	 * on L/390 this is the case for all types of parameter 
 	 * except of floats, and long long (32 bit) 
-         *
-         */
+	 *
+	 */
 	long args[0];
 } debug_sprintf_entry_t;
 
@@ -63,32 +68,38 @@ extern void tod_to_timeval(uint64_t todv
 
 static int debug_init(void);
 static ssize_t debug_output(struct file *file, char __user *user_buf,
-			    size_t user_len, loff_t * offset);
+			size_t user_len, loff_t * offset);
 static ssize_t debug_input(struct file *file, const char __user *user_buf,
-			   size_t user_len, loff_t * offset);
+			size_t user_len, loff_t * offset);
 static int debug_open(struct inode *inode, struct file *file);
 static int debug_close(struct inode *inode, struct file *file);
-static debug_info_t*  debug_info_create(char *name, int page_order, int nr_areas, int buf_size);
+static debug_info_t*  debug_info_create(char *name, int pages_per_area,
+			int nr_areas, int buf_size);
 static void debug_info_get(debug_info_t *);
 static void debug_info_put(debug_info_t *);
 static int debug_prolog_level_fn(debug_info_t * id,
-				 struct debug_view *view, char *out_buf);
+			struct debug_view *view, char *out_buf);
 static int debug_input_level_fn(debug_info_t * id, struct debug_view *view,
-				struct file *file, const char __user *user_buf,
-				size_t user_buf_size, loff_t * offset);
+			struct file *file, const char __user *user_buf,
+			size_t user_buf_size, loff_t * offset);
+static int debug_prolog_pages_fn(debug_info_t * id,
+			struct debug_view *view, char *out_buf);
+static int debug_input_pages_fn(debug_info_t * id, struct debug_view *view,
+			struct file *file, const char __user *user_buf,
+			size_t user_buf_size, loff_t * offset);
 static int debug_input_flush_fn(debug_info_t * id, struct debug_view *view,
-                                struct file *file, const char __user *user_buf,
-                                size_t user_buf_size, loff_t * offset);
+			struct file *file, const char __user *user_buf,
+			size_t user_buf_size, loff_t * offset);
 static int debug_hex_ascii_format_fn(debug_info_t * id, struct debug_view *view,
-                                char *out_buf, const char *in_buf);
+			char *out_buf, const char *in_buf);
 static int debug_raw_format_fn(debug_info_t * id,
-				 struct debug_view *view, char *out_buf,
-				 const char *in_buf);
+			struct debug_view *view, char *out_buf,
+			const char *in_buf);
 static int debug_raw_header_fn(debug_info_t * id, struct debug_view *view,
-                         int area, debug_entry_t * entry, char *out_buf);
+			int area, debug_entry_t * entry, char *out_buf);
 
 static int debug_sprintf_format_fn(debug_info_t * id, struct debug_view *view,
-				   char *out_buf, debug_sprintf_entry_t *curr_event);
+			char *out_buf, debug_sprintf_entry_t *curr_event);
 
 /* globals */
 
@@ -119,6 +130,15 @@ struct debug_view debug_level_view = {
 	NULL
 };
 
+struct debug_view debug_pages_view = {
+	"pages",
+	&debug_prolog_pages_fn,
+	NULL,
+	NULL,
+	&debug_input_pages_fn,
+	NULL
+};
+
 struct debug_view debug_flush_view = {
         "flush",
         NULL,
@@ -149,98 +169,161 @@ DECLARE_MUTEX(debug_lock);
 static int initialized;
 
 static struct file_operations debug_file_ops = {
-	.owner	 = THIS_MODULE,
+	.owner   = THIS_MODULE,
 	.read    = debug_output,
-	.write   = debug_input,	
+	.write   = debug_input,
 	.open    = debug_open,
 	.release = debug_close,
 };
 
-static struct proc_dir_entry *debug_proc_root_entry;
+static struct dentry *debug_debugfs_root_entry;
 
 /* functions */
 
 /*
+ * debug_areas_alloc
+ * - Debug areas are implemented as a threedimensonal array:
+ *   areas[areanumber][pagenumber][pageoffset]
+ */
+
+static debug_entry_t***
+debug_areas_alloc(int pages_per_area, int nr_areas)
+{
+	debug_entry_t*** areas;
+	int i,j;
+
+	areas = (debug_entry_t ***) kmalloc(nr_areas *
+					sizeof(debug_entry_t**),
+					GFP_KERNEL);
+	if (!areas)
+		goto fail_malloc_areas;
+	for (i = 0; i < nr_areas; i++) {
+		areas[i] = (debug_entry_t**) kmalloc(pages_per_area *
+				sizeof(debug_entry_t*),GFP_KERNEL);
+		if (!areas[i]) {
+			goto fail_malloc_areas2;
+		}
+		for(j = 0; j < pages_per_area; j++) {
+			areas[i][j] = (debug_entry_t*)kmalloc(PAGE_SIZE,
+						GFP_KERNEL);
+			if(!areas[i][j]) {
+				for(j--; j >=0 ; j--) {
+					kfree(areas[i][j]);
+				}
+				kfree(areas[i]);
+				goto fail_malloc_areas2;
+			} else {
+				memset(areas[i][j],0,PAGE_SIZE);
+			}
+		}
+	}
+	return areas;
+
+fail_malloc_areas2:
+	for(i--; i >= 0; i--){
+		for(j=0; j < pages_per_area;j++){
+			kfree(areas[i][j]);
+		}
+		kfree(areas[i]);
+	}
+	kfree(areas);
+fail_malloc_areas:
+	return NULL;
+
+}
+
+
+/*
  * debug_info_alloc
  * - alloc new debug-info
  */
 
-static debug_info_t*  debug_info_alloc(char *name, int page_order,
-                                        int nr_areas, int buf_size)
+static debug_info_t*
+debug_info_alloc(char *name, int pages_per_area, int nr_areas, int buf_size,
+		int level, int mode)
 {
 	debug_info_t* rc;
-	int i;
 
 	/* alloc everything */
 
-	rc = (debug_info_t*) kmalloc(sizeof(debug_info_t), GFP_ATOMIC);
+	rc = (debug_info_t*) kmalloc(sizeof(debug_info_t), GFP_KERNEL);
 	if(!rc)
 		goto fail_malloc_rc;
-	rc->active_entry = (int*)kmalloc(nr_areas * sizeof(int), GFP_ATOMIC);
-	if(!rc->active_entry)
-		goto fail_malloc_active_entry;
-	memset(rc->active_entry, 0, nr_areas * sizeof(int));
-	rc->areas = (debug_entry_t **) kmalloc(nr_areas *
-						sizeof(debug_entry_t *),
-						GFP_ATOMIC);
-	if (!rc->areas)
-		goto fail_malloc_areas;
-	for (i = 0; i < nr_areas; i++) {
-		rc->areas[i] = (debug_entry_t *) __get_free_pages(GFP_ATOMIC,
-								page_order);
-		if (!rc->areas[i]) {
-			for (i--; i >= 0; i--) {
-				free_pages((unsigned long) rc->areas[i],
-						page_order);
-			}
-			goto fail_malloc_areas2;
-		} else {
-			memset(rc->areas[i], 0, PAGE_SIZE << page_order);
-		}
+	rc->active_entries = (int*)kmalloc(nr_areas * sizeof(int), GFP_KERNEL);
+	if(!rc->active_entries)
+		goto fail_malloc_active_entries;
+	memset(rc->active_entries, 0, nr_areas * sizeof(int));
+	rc->active_pages = (int*)kmalloc(nr_areas * sizeof(int), GFP_KERNEL);
+	if(!rc->active_pages)
+		goto fail_malloc_active_pages;
+	memset(rc->active_pages, 0, nr_areas * sizeof(int));
+	if((mode == ALL_AREAS) && (pages_per_area != 0)){
+		rc->areas = debug_areas_alloc(pages_per_area, nr_areas);
+		if(!rc->areas)
+			goto fail_malloc_areas;
+	} else {
+		rc->areas = NULL;
 	}
 
 	/* initialize members */
 
 	spin_lock_init(&rc->lock);
-	rc->page_order  = page_order;
-	rc->nr_areas    = nr_areas;
-	rc->active_area = 0;
-	rc->level       = DEBUG_DEFAULT_LEVEL;
-	rc->buf_size    = buf_size;
-	rc->entry_size  = sizeof(debug_entry_t) + buf_size;
-	strlcpy(rc->name, name, sizeof(rc->name));
+	rc->pages_per_area = pages_per_area;
+	rc->nr_areas       = nr_areas;
+	rc->active_area    = 0;
+	rc->level          = level;
+	rc->buf_size       = buf_size;
+	rc->entry_size     = sizeof(debug_entry_t) + buf_size;
+	strlcpy(rc->name, name, sizeof(rc->name)-1);
 	memset(rc->views, 0, DEBUG_MAX_VIEWS * sizeof(struct debug_view *));
-#ifdef CONFIG_PROC_FS
-	memset(rc->proc_entries, 0 ,DEBUG_MAX_VIEWS *
-		sizeof(struct proc_dir_entry*));
-#endif /* CONFIG_PROC_FS */
+	memset(rc->debugfs_entries, 0 ,DEBUG_MAX_VIEWS *
+		sizeof(struct dentry*));
 	atomic_set(&(rc->ref_count), 0);
 
 	return rc;
 
-fail_malloc_areas2:
-	kfree(rc->areas);
 fail_malloc_areas:
-	kfree(rc->active_entry);
-fail_malloc_active_entry:
+	kfree(rc->active_pages);
+fail_malloc_active_pages:
+	kfree(rc->active_entries);
+fail_malloc_active_entries:
 	kfree(rc);
 fail_malloc_rc:
 	return NULL;
 }
 
 /*
- * debug_info_free
- * - free memory debug-info
+ * debug_areas_free
+ * - free all debug areas
  */
 
-static void debug_info_free(debug_info_t* db_info){
-	int i;
+static void
+debug_areas_free(debug_info_t* db_info)
+{
+	int i,j;
+
+	if(!db_info->areas)
+		return;
 	for (i = 0; i < db_info->nr_areas; i++) {
-		free_pages((unsigned long) db_info->areas[i],
-		db_info->page_order);
+		for(j = 0; j < db_info->pages_per_area; j++) {
+			kfree(db_info->areas[i][j]);
+		}
+		kfree(db_info->areas[i]);
 	}
 	kfree(db_info->areas);
-	kfree(db_info->active_entry);
+	db_info->areas = NULL;
+}
+
+/*
+ * debug_info_free
+ * - free memory debug-info
+ */
+
+static void
+debug_info_free(debug_info_t* db_info){
+	debug_areas_free(db_info);
+	kfree(db_info->active_entries);
+	kfree(db_info->active_pages);
 	kfree(db_info);
 }
 
@@ -249,21 +332,22 @@ static void debug_info_free(debug_info_t
  * - create new debug-info
  */
 
-static debug_info_t*  debug_info_create(char *name, int page_order, 
-                                        int nr_areas, int buf_size)
+static debug_info_t*
+debug_info_create(char *name, int pages_per_area, int nr_areas, int buf_size)
 {
 	debug_info_t* rc;
 
-        rc = debug_info_alloc(name, page_order, nr_areas, buf_size);
+        rc = debug_info_alloc(name, pages_per_area, nr_areas, buf_size,
+				DEBUG_DEFAULT_LEVEL, ALL_AREAS);
         if(!rc) 
 		goto out;
 
-
-	/* create proc rood directory */
-        rc->proc_root_entry = proc_mkdir(rc->name, debug_proc_root_entry);
+	/* create root directory */
+        rc->debugfs_root_entry = debugfs_create_dir(rc->name,
+					debug_debugfs_root_entry);
 
 	/* append new element to linked list */
-        if (debug_area_first == NULL) {
+        if (!debug_area_first) {
                 /* first element in list */
                 debug_area_first = rc;
                 rc->prev = NULL;
@@ -285,17 +369,21 @@ out:
  * - copy debug-info
  */
 
-static debug_info_t* debug_info_copy(debug_info_t* in)
+static debug_info_t*
+debug_info_copy(debug_info_t* in, int mode)
 {
-        int i;
+        int i,j;
         debug_info_t* rc;
-        rc = debug_info_alloc(in->name, in->page_order, 
-                                in->nr_areas, in->buf_size);
-        if(!rc)
+
+        rc = debug_info_alloc(in->name, in->pages_per_area, in->nr_areas,
+				in->buf_size, in->level, mode);
+        if(!rc || (mode == NO_AREAS))
                 goto out;
 
         for(i = 0; i < in->nr_areas; i++){
-                memcpy(rc->areas[i],in->areas[i], PAGE_SIZE << in->page_order);
+		for(j = 0; j < in->pages_per_area; j++) {
+			memcpy(rc->areas[i][j], in->areas[i][j],PAGE_SIZE);
+		}
         }
 out:
         return rc;
@@ -306,7 +394,8 @@ out:
  * - increments reference count for debug-info
  */
 
-static void debug_info_get(debug_info_t * db_info)
+static void
+debug_info_get(debug_info_t * db_info)
 {
 	if (db_info)
 		atomic_inc(&db_info->ref_count);
@@ -317,29 +406,20 @@ static void debug_info_get(debug_info_t 
  * - decreases reference count for debug-info and frees it if necessary
  */
 
-static void debug_info_put(debug_info_t *db_info)
+static void
+debug_info_put(debug_info_t *db_info)
 {
 	int i;
 
 	if (!db_info)
 		return;
 	if (atomic_dec_and_test(&db_info->ref_count)) {
-#ifdef DEBUG
-		printk(KERN_INFO "debug: freeing debug area %p (%s)\n",
-		       db_info, db_info->name);
-#endif
 		for (i = 0; i < DEBUG_MAX_VIEWS; i++) {
-			if (db_info->views[i] == NULL)
+			if (!db_info->views[i])
 				continue;
-#ifdef CONFIG_PROC_FS
-			remove_proc_entry(db_info->proc_entries[i]->name,
-					  db_info->proc_root_entry);
-#endif
+			debugfs_remove(db_info->debugfs_entries[i]);
 		}
-#ifdef CONFIG_PROC_FS
-		remove_proc_entry(db_info->proc_root_entry->name,
-				  debug_proc_root_entry);
-#endif
+		debugfs_remove(db_info->debugfs_root_entry);
 		if(db_info == debug_area_first)
 			debug_area_first = db_info->next;
 		if(db_info == debug_area_last)
@@ -355,9 +435,9 @@ static void debug_info_put(debug_info_t 
  * - format one debug entry and return size of formated data
  */
 
-static int debug_format_entry(file_private_info_t *p_info)
+static int
+debug_format_entry(file_private_info_t *p_info)
 {
-	debug_info_t *id_org    = p_info->debug_info_org;
 	debug_info_t *id_snap   = p_info->debug_info_snap;
 	struct debug_view *view = p_info->view;
 	debug_entry_t *act_entry;
@@ -365,22 +445,23 @@ static int debug_format_entry(file_priva
 	if(p_info->act_entry == DEBUG_PROLOG_ENTRY){
 		/* print prolog */
         	if (view->prolog_proc)
-                	len += view->prolog_proc(id_org, view,p_info->temp_buf);
+                	len += view->prolog_proc(id_snap,view,p_info->temp_buf);
 		goto out;
 	}
-
-	act_entry = (debug_entry_t *) ((char*)id_snap->areas[p_info->act_area] +
-					p_info->act_entry);
+	if (!id_snap->areas) /* this is true, if we have a prolog only view */
+		goto out;    /* or if 'pages_per_area' is 0 */
+	act_entry = (debug_entry_t *) ((char*)id_snap->areas[p_info->act_area]
+				[p_info->act_page] + p_info->act_entry);
                         
 	if (act_entry->id.stck == 0LL)
 			goto out;  /* empty entry */
 	if (view->header_proc)
-		len += view->header_proc(id_org, view, p_info->act_area, 
+		len += view->header_proc(id_snap, view, p_info->act_area,
 					act_entry, p_info->temp_buf + len);
 	if (view->format_proc)
-		len += view->format_proc(id_org, view, p_info->temp_buf + len,
+		len += view->format_proc(id_snap, view, p_info->temp_buf + len,
 						DEBUG_DATA(act_entry));
-      out:
+out:
         return len;
 }
 
@@ -389,20 +470,30 @@ static int debug_format_entry(file_priva
  * - goto next entry in p_info
  */
 
-extern inline int debug_next_entry(file_private_info_t *p_info)
+extern inline int
+debug_next_entry(file_private_info_t *p_info)
 {
-	debug_info_t *id = p_info->debug_info_snap;
+	debug_info_t *id;
+
+	id = p_info->debug_info_snap;
 	if(p_info->act_entry == DEBUG_PROLOG_ENTRY){
 		p_info->act_entry = 0;
+		p_info->act_page  = 0;
 		goto out;
 	}
-	if ((p_info->act_entry += id->entry_size)
-		> ((PAGE_SIZE << (id->page_order)) 
-		- id->entry_size)){
-
-		/* next area */
+	if(!id->areas)
+		return 1;
+	p_info->act_entry += id->entry_size;
+	/* switch to next page, if we reached the end of the page  */
+	if (p_info->act_entry > (PAGE_SIZE - id->entry_size)){
+		/* next page */
 		p_info->act_entry = 0;
-        	p_info->act_area++;
+		p_info->act_page += 1;
+		if((p_info->act_page % id->pages_per_area) == 0) {
+			/* next area */
+        		p_info->act_area++;
+			p_info->act_page=0;
+		}
         	if(p_info->act_area >= id->nr_areas)
 			return 1;
 	}
@@ -416,13 +507,14 @@ out:
  * - copies formated debug entries to the user buffer
  */
 
-static ssize_t debug_output(struct file *file,		/* file descriptor */
-			    char __user *user_buf,	/* user buffer */
-			    size_t  len,		/* length of buffer */
-			    loff_t *offset)	      /* offset in the file */
+static ssize_t
+debug_output(struct file *file,		/* file descriptor */
+	    char __user *user_buf,	/* user buffer */
+	    size_t  len,		/* length of buffer */
+	    loff_t *offset)		/* offset in the file */
 {
 	size_t count = 0;
-	size_t entry_offset, size = 0;
+	size_t entry_offset;
 	file_private_info_t *p_info;
 
 	p_info = ((file_private_info_t *) file->private_data);
@@ -430,27 +522,33 @@ static ssize_t debug_output(struct file 
 		return -EPIPE;
 	if(p_info->act_area >= p_info->debug_info_snap->nr_areas)
 		return 0;
-
 	entry_offset = p_info->act_entry_offset;
-
 	while(count < len){
-		size = debug_format_entry(p_info);
-		size = min((len - count), (size - entry_offset));
-
-		if(size){
-			if (copy_to_user(user_buf + count, 
-					p_info->temp_buf + entry_offset, size))
-			return -EFAULT;
+		int formatted_line_size;
+		int formatted_line_residue;
+		int user_buf_residue;
+		size_t copy_size;
+
+		formatted_line_size = debug_format_entry(p_info);
+		formatted_line_residue = formatted_line_size - entry_offset;
+		user_buf_residue = len-count;
+		copy_size = min(user_buf_residue, formatted_line_residue);
+		if(copy_size){
+			if (copy_to_user(user_buf + count, p_info->temp_buf
+					+ entry_offset, copy_size))
+				return -EFAULT;
+			count += copy_size;
+			entry_offset += copy_size;
 		}
-		count += size;
-		entry_offset = 0;
-		if(count != len)
-			if(debug_next_entry(p_info)) 
+		if(copy_size == formatted_line_residue){
+			entry_offset = 0;
+			if(debug_next_entry(p_info))
 				goto out;
+		}
 	}
 out:
 	p_info->offset           = *offset + count;
-	p_info->act_entry_offset = size;	
+	p_info->act_entry_offset = entry_offset;
 	*offset = p_info->offset;
 	return count;
 }
@@ -461,9 +559,9 @@ out:
  * - calls input function of view
  */
 
-static ssize_t debug_input(struct file *file,
-			   const char __user *user_buf, size_t length,
-			   loff_t *offset)
+static ssize_t
+debug_input(struct file *file, const char __user *user_buf, size_t length,
+		loff_t *offset)
 {
 	int rc = 0;
 	file_private_info_t *p_info;
@@ -487,26 +585,23 @@ static ssize_t debug_input(struct file *
  *   handle
  */
 
-static int debug_open(struct inode *inode, struct file *file)
+static int
+debug_open(struct inode *inode, struct file *file)
 {
 	int i = 0, rc = 0;
 	file_private_info_t *p_info;
 	debug_info_t *debug_info, *debug_info_snapshot;
 
-#ifdef DEBUG
-	printk("debug_open\n");
-#endif
 	down(&debug_lock);
 
 	/* find debug log and view */
-
 	debug_info = debug_area_first;
 	while(debug_info != NULL){
 		for (i = 0; i < DEBUG_MAX_VIEWS; i++) {
-			if (debug_info->views[i] == NULL)
+			if (!debug_info->views[i])
 				continue;
-			else if (debug_info->proc_entries[i] ==
-				 PDE(file->f_dentry->d_inode)) {
+			else if (debug_info->debugfs_entries[i] ==
+				 file->f_dentry) {
 				goto found;	/* found view ! */
 			}
 		}
@@ -516,41 +611,42 @@ static int debug_open(struct inode *inod
 	rc = -EINVAL;
 	goto out;
 
-      found:
+found:
 
-	/* make snapshot of current debug areas to get it consistent */
-
-	debug_info_snapshot = debug_info_copy(debug_info);
+	/* Make snapshot of current debug areas to get it consistent.     */
+	/* To copy all the areas is only needed, if we have a view which  */
+	/* formats the debug areas. */
+
+	if(!debug_info->views[i]->format_proc &&
+		!debug_info->views[i]->header_proc){
+		debug_info_snapshot = debug_info_copy(debug_info, NO_AREAS);
+	} else {
+		debug_info_snapshot = debug_info_copy(debug_info, ALL_AREAS);
+	}
 
 	if(!debug_info_snapshot){
-#ifdef DEBUG
-		printk(KERN_ERR "debug_open: debug_info_copy failed (out of mem)\n");
-#endif
 		rc = -ENOMEM;
 		goto out;
 	}
-
-	if ((file->private_data =
-	     kmalloc(sizeof(file_private_info_t), GFP_ATOMIC)) == 0) {
-#ifdef DEBUG
-		printk(KERN_ERR "debug_open: kmalloc failed\n");
-#endif
-		debug_info_free(debug_info_snapshot);	
+	p_info = (file_private_info_t *) kmalloc(sizeof(file_private_info_t),
+						GFP_KERNEL);
+	if(!p_info){
+		if(debug_info_snapshot)
+			debug_info_free(debug_info_snapshot);
 		rc = -ENOMEM;
 		goto out;
 	}
-	p_info = (file_private_info_t *) file->private_data;
 	p_info->offset = 0;
 	p_info->debug_info_snap = debug_info_snapshot;
 	p_info->debug_info_org  = debug_info;
 	p_info->view = debug_info->views[i];
 	p_info->act_area = 0;
+	p_info->act_page = 0;
 	p_info->act_entry = DEBUG_PROLOG_ENTRY;
 	p_info->act_entry_offset = 0;
-
+	file->private_data = p_info;
 	debug_info_get(debug_info);
-
-      out:
+out:
 	up(&debug_lock);
 	return rc;
 }
@@ -561,14 +657,13 @@ static int debug_open(struct inode *inod
  * - deletes  private_data area of the file handle
  */
 
-static int debug_close(struct inode *inode, struct file *file)
+static int
+debug_close(struct inode *inode, struct file *file)
 {
 	file_private_info_t *p_info;
-#ifdef DEBUG
-	printk("debug_close\n");
-#endif
 	p_info = (file_private_info_t *) file->private_data;
-	debug_info_free(p_info->debug_info_snap);
+	if(p_info->debug_info_snap)
+		debug_info_free(p_info->debug_info_snap);
 	debug_info_put(p_info->debug_info_org);
 	kfree(file->private_data);
 	return 0;		/* success */
@@ -580,8 +675,8 @@ static int debug_close(struct inode *ino
  * - returns handle for debug area
  */
 
-debug_info_t *debug_register
-    (char *name, int page_order, int nr_areas, int buf_size) 
+debug_info_t*
+debug_register (char *name, int pages_per_area, int nr_areas, int buf_size)
 {
 	debug_info_t *rc = NULL;
 
@@ -591,18 +686,14 @@ debug_info_t *debug_register
 
         /* create new debug_info */
 
-	rc = debug_info_create(name, page_order, nr_areas, buf_size);
+	rc = debug_info_create(name, pages_per_area, nr_areas, buf_size);
 	if(!rc) 
 		goto out;
 	debug_register_view(rc, &debug_level_view);
         debug_register_view(rc, &debug_flush_view);
-#ifdef DEBUG
-	printk(KERN_INFO
-	       "debug: reserved %d areas of %d pages for debugging %s\n",
-	       nr_areas, 1 << page_order, rc->name);
-#endif
-      out:
-        if (rc == NULL){
+	debug_register_view(rc, &debug_pages_view);
+out:
+        if (!rc){
 		printk(KERN_ERR "debug: debug_register failed for %s\n",name);
         }
 	up(&debug_lock);
@@ -614,27 +705,65 @@ debug_info_t *debug_register
  * - give back debug area
  */
 
-void debug_unregister(debug_info_t * id)
+void
+debug_unregister(debug_info_t * id)
 {
 	if (!id)
 		goto out;
 	down(&debug_lock);
-#ifdef DEBUG
-	printk(KERN_INFO "debug: unregistering %s\n", id->name);
-#endif
 	debug_info_put(id);
 	up(&debug_lock);
 
-      out:
+out:
 	return;
 }
 
 /*
+ * debug_set_size:
+ * - set area size (number of pages) and number of areas
+ */
+static int
+debug_set_size(debug_info_t* id, int nr_areas, int pages_per_area)
+{
+	unsigned long flags;
+	debug_entry_t *** new_areas;
+	int rc=0;
+
+	if(!id || (nr_areas <= 0) || (pages_per_area < 0))
+		return -EINVAL;
+	if(pages_per_area > 0){
+		new_areas = debug_areas_alloc(pages_per_area, nr_areas);
+		if(!new_areas) {
+			printk(KERN_WARNING "debug: could not allocate memory "\
+					 "for pagenumber: %i\n",pages_per_area);
+			rc = -ENOMEM;
+			goto out;
+		}
+	} else {
+		new_areas = NULL;
+	}
+	spin_lock_irqsave(&id->lock,flags);
+	debug_areas_free(id);
+	id->areas = new_areas;
+	id->nr_areas = nr_areas;
+	id->pages_per_area = pages_per_area;
+	id->active_area = 0;
+	memset(id->active_entries,0,sizeof(int)*id->nr_areas);
+	memset(id->active_pages, 0, sizeof(int)*id->nr_areas);
+	spin_unlock_irqrestore(&id->lock,flags);
+	printk(KERN_INFO "debug: %s: set new size (%i pages)\n"\
+			 ,id->name, pages_per_area);
+out:
+	return rc;
+}
+
+/*
  * debug_set_level:
  * - set actual debug level
  */
 
-void debug_set_level(debug_info_t* id, int new_level)
+void
+debug_set_level(debug_info_t* id, int new_level)
 {
 	unsigned long flags;
 	if(!id)
@@ -649,10 +778,6 @@ void debug_set_level(debug_info_t* id, i
                         id->name, new_level, 0, DEBUG_MAX_LEVEL);
         } else {
                 id->level = new_level;
-#ifdef DEBUG
-                printk(KERN_INFO 
-			"debug: %s: new level %i\n",id->name,id->level);
-#endif
         }
 	spin_unlock_irqrestore(&id->lock,flags);
 }
@@ -663,11 +788,16 @@ void debug_set_level(debug_info_t* id, i
  * - set active entry to next in the ring buffer
  */
 
-extern inline void proceed_active_entry(debug_info_t * id)
+extern inline void
+proceed_active_entry(debug_info_t * id)
 {
-	if ((id->active_entry[id->active_area] += id->entry_size)
-	    > ((PAGE_SIZE << (id->page_order)) - id->entry_size))
-		id->active_entry[id->active_area] = 0;
+	if ((id->active_entries[id->active_area] += id->entry_size)
+	    > (PAGE_SIZE - id->entry_size)){
+		id->active_entries[id->active_area] = 0;
+		id->active_pages[id->active_area] =
+			(id->active_pages[id->active_area] + 1) %
+			id->pages_per_area;
+	}
 }
 
 /*
@@ -675,7 +805,8 @@ extern inline void proceed_active_entry(
  * - set active area to next in the ring buffer
  */
 
-extern inline void proceed_active_area(debug_info_t * id)
+extern inline void
+proceed_active_area(debug_info_t * id)
 {
 	id->active_area++;
 	id->active_area = id->active_area % id->nr_areas;
@@ -685,10 +816,12 @@ extern inline void proceed_active_area(d
  * get_active_entry:
  */
 
-extern inline debug_entry_t *get_active_entry(debug_info_t * id)
+extern inline debug_entry_t*
+get_active_entry(debug_info_t * id)
 {
-	return (debug_entry_t *) ((char *) id->areas[id->active_area] +
-				  id->active_entry[id->active_area]);
+	return (debug_entry_t *) (((char *) id->areas[id->active_area]
+					[id->active_pages[id->active_area]]) +
+					id->active_entries[id->active_area]);
 }
 
 /*
@@ -696,8 +829,9 @@ extern inline debug_entry_t *get_active_
  * - set timestamp, caller address, cpu number etc.
  */
 
-extern inline void debug_finish_entry(debug_info_t * id, debug_entry_t* active,
-		int level, int exception)
+extern inline void
+debug_finish_entry(debug_info_t * id, debug_entry_t* active, int level,
+			int exception)
 {
 	STCK(active->id.stck);
 	active->id.fields.cpuid = smp_processor_id();
@@ -721,7 +855,8 @@ static int debug_active=1;
  * always allow read, allow write only if debug_stoppable is set or
  * if debug_active is already off
  */
-static int s390dbf_procactive(ctl_table *table, int write, struct file *filp,
+static int
+s390dbf_procactive(ctl_table *table, int write, struct file *filp,
                      void __user *buffer, size_t *lenp, loff_t *ppos)
 {
 	if (!write || debug_stoppable || !debug_active)
@@ -766,7 +901,8 @@ static struct ctl_table s390dbf_dir_tabl
 
 struct ctl_table_header *s390dbf_sysctl_header;
 
-void debug_stop_all(void)
+void
+debug_stop_all(void)
 {
 	if (debug_stoppable)
 		debug_active = 0;
@@ -778,13 +914,13 @@ void debug_stop_all(void)
  * - write debug entry with given size
  */
 
-debug_entry_t *debug_event_common(debug_info_t * id, int level, const void *buf,
-			          int len)
+debug_entry_t*
+debug_event_common(debug_info_t * id, int level, const void *buf, int len)
 {
 	unsigned long flags;
 	debug_entry_t *active;
 
-	if (!debug_active)
+	if (!debug_active || !id->areas)
 		return NULL;
 	spin_lock_irqsave(&id->lock, flags);
 	active = get_active_entry(id);
@@ -801,13 +937,13 @@ debug_entry_t *debug_event_common(debug_
  * - write debug entry with given size and switch to next debug area
  */
 
-debug_entry_t *debug_exception_common(debug_info_t * id, int level, 
-                                      const void *buf, int len)
+debug_entry_t
+*debug_exception_common(debug_info_t * id, int level, const void *buf, int len)
 {
 	unsigned long flags;
 	debug_entry_t *active;
 
-	if (!debug_active)
+	if (!debug_active || !id->areas)
 		return NULL;
 	spin_lock_irqsave(&id->lock, flags);
 	active = get_active_entry(id);
@@ -823,7 +959,8 @@ debug_entry_t *debug_exception_common(de
  * counts arguments in format string for sprintf view
  */
 
-extern inline int debug_count_numargs(char *string)
+extern inline int
+debug_count_numargs(char *string)
 {
 	int numargs=0;
 
@@ -838,8 +975,8 @@ extern inline int debug_count_numargs(ch
  * debug_sprintf_event:
  */
 
-debug_entry_t *debug_sprintf_event(debug_info_t* id,
-                                   int level,char *string,...)
+debug_entry_t*
+debug_sprintf_event(debug_info_t* id, int level,char *string,...)
 {
 	va_list   ap;
 	int numargs,idx;
@@ -849,7 +986,7 @@ debug_entry_t *debug_sprintf_event(debug
 
 	if((!id) || (level > id->level))
 		return NULL;
-	if (!debug_active)
+	if (!debug_active || !id->areas)
 		return NULL;
 	numargs=debug_count_numargs(string);
 
@@ -871,8 +1008,8 @@ debug_entry_t *debug_sprintf_event(debug
  * debug_sprintf_exception:
  */
 
-debug_entry_t *debug_sprintf_exception(debug_info_t* id,
-                                       int level,char *string,...)
+debug_entry_t*
+debug_sprintf_exception(debug_info_t* id, int level,char *string,...)
 {
 	va_list   ap;
 	int numargs,idx;
@@ -882,7 +1019,7 @@ debug_entry_t *debug_sprintf_exception(d
 
 	if((!id) || (level > id->level))
 		return NULL;
-	if (!debug_active)
+	if (!debug_active || !id->areas)
 		return NULL;
 
 	numargs=debug_count_numargs(string);
@@ -906,15 +1043,14 @@ debug_entry_t *debug_sprintf_exception(d
  * - is called exactly once to initialize the debug feature
  */
 
-static int __init debug_init(void)
+static int
+__init debug_init(void)
 {
 	int rc = 0;
 
 	s390dbf_sysctl_header = register_sysctl_table(s390dbf_dir_table, 1);
 	down(&debug_lock);
-#ifdef CONFIG_PROC_FS
-	debug_proc_root_entry = proc_mkdir(DEBUG_DIR_ROOT, NULL);
-#endif /* CONFIG_PROC_FS */
+	debug_debugfs_root_entry = debugfs_create_dir(DEBUG_DIR_ROOT,NULL);
 	printk(KERN_INFO "debug: Initialization complete\n");
 	initialized = 1;
 	up(&debug_lock);
@@ -926,13 +1062,14 @@ static int __init debug_init(void)
  * debug_register_view:
  */
 
-int debug_register_view(debug_info_t * id, struct debug_view *view)
+int
+debug_register_view(debug_info_t * id, struct debug_view *view)
 {
 	int rc = 0;
 	int i;
 	unsigned long flags;
 	mode_t mode = S_IFREG;
-	struct proc_dir_entry *pde;
+	struct dentry *pde;
 
 	if (!id)
 		goto out;
@@ -940,16 +1077,17 @@ int debug_register_view(debug_info_t * i
 		mode |= S_IRUSR;
 	if (view->input_proc)
 		mode |= S_IWUSR;
-	pde = create_proc_entry(view->name, mode, id->proc_root_entry);
+	pde = debugfs_create_file(view->name, mode, id->debugfs_root_entry,
+				NULL, &debug_file_ops);
 	if (!pde){
-		printk(KERN_WARNING "debug: create_proc_entry() failed! Cannot register view %s/%s\n", id->name,view->name);
+		printk(KERN_WARNING "debug: debugfs_create_file() failed!"\
+			" Cannot register view %s/%s\n", id->name,view->name);
 		rc = -1;
 		goto out;
 	}
-
 	spin_lock_irqsave(&id->lock, flags);
 	for (i = 0; i < DEBUG_MAX_VIEWS; i++) {
-		if (id->views[i] == NULL)
+		if (!id->views[i])
 			break;
 	}
 	if (i == DEBUG_MAX_VIEWS) {
@@ -957,16 +1095,14 @@ int debug_register_view(debug_info_t * i
 			id->name,view->name);
 		printk(KERN_WARNING 
 			"debug: maximum number of views reached (%i)!\n", i);
-		remove_proc_entry(pde->name, id->proc_root_entry);
+		debugfs_remove(pde);
 		rc = -1;
-	}
-	else {
+	} else {
 		id->views[i] = view;
-		pde->proc_fops = &debug_file_ops;
-		id->proc_entries[i] = pde;
+		id->debugfs_entries[i] = pde;
 	}
 	spin_unlock_irqrestore(&id->lock, flags);
-      out:
+out:
 	return rc;
 }
 
@@ -974,7 +1110,8 @@ int debug_register_view(debug_info_t * i
  * debug_unregister_view:
  */
 
-int debug_unregister_view(debug_info_t * id, struct debug_view *view)
+int
+debug_unregister_view(debug_info_t * id, struct debug_view *view)
 {
 	int rc = 0;
 	int i;
@@ -990,15 +1127,46 @@ int debug_unregister_view(debug_info_t *
 	if (i == DEBUG_MAX_VIEWS)
 		rc = -1;
 	else {
-#ifdef CONFIG_PROC_FS
-		remove_proc_entry(id->proc_entries[i]->name,
-				  id->proc_root_entry);
-#endif
+		debugfs_remove(id->debugfs_entries[i]);
 		id->views[i] = NULL;
 		rc = 0;
 	}
 	spin_unlock_irqrestore(&id->lock, flags);
-      out:
+out:
+	return rc;
+}
+
+static inline char *
+debug_get_user_string(const char __user *user_buf, size_t user_len)
+{
+	char* buffer;
+
+	buffer = kmalloc(user_len + 1, GFP_KERNEL);
+	if (!buffer)
+		return ERR_PTR(-ENOMEM);
+	if (copy_from_user(buffer, user_buf, user_len) != 0) {
+		kfree(buffer);
+		return ERR_PTR(-EFAULT);
+	}
+	/* got the string, now strip linefeed. */
+	if (buffer[user_len - 1] == '\n')
+		buffer[user_len - 1] = 0;
+	else
+		buffer[user_len] = 0;
+        return buffer;
+}
+
+static inline int
+debug_get_uint(char *buf)
+{
+	int rc;
+
+	for(; isspace(*buf); buf++);
+	rc = simple_strtoul(buf, &buf, 10);
+	if(*buf){
+		printk("debug: no integer specified!\n");
+		rc = -EINVAL;
+	}
 	return rc;
 }
 
@@ -1011,13 +1179,69 @@ int debug_unregister_view(debug_info_t *
  * prints out actual debug level
  */
 
-static int debug_prolog_level_fn(debug_info_t * id,
+static int
+debug_prolog_pages_fn(debug_info_t * id,
 				 struct debug_view *view, char *out_buf)
 {
+	return sprintf(out_buf, "%i\n", id->pages_per_area);
+}
+
+/*
+ * reads new size (number of pages per debug area)
+ */
+
+static int
+debug_input_pages_fn(debug_info_t * id, struct debug_view *view,
+			struct file *file, const char __user *user_buf,
+			size_t user_len, loff_t * offset)
+{
+	char *str;
+	int rc,new_pages;
+
+	if (user_len > 0x10000)
+                user_len = 0x10000;
+	if (*offset != 0){
+		rc = -EPIPE;
+		goto out;
+	}
+	str = debug_get_user_string(user_buf,user_len);
+	if(IS_ERR(str)){
+		rc = PTR_ERR(str);
+		goto out;
+	}
+	new_pages = debug_get_uint(str);
+	if(new_pages < 0){
+		rc = -EINVAL;
+		goto free_str;
+	}
+	rc = debug_set_size(id,id->nr_areas, new_pages);
+	if(rc != 0){
+		rc = -EINVAL;
+		goto free_str;
+	}
+	rc = user_len;
+free_str:
+	kfree(str);
+out:
+	*offset += user_len;
+	return rc;		/* number of input characters */
+}
+
+/*
+ * prints out actual debug level
+ */
+
+static int
+debug_prolog_level_fn(debug_info_t * id, struct debug_view *view, char *out_buf)
+{
 	int rc = 0;
 
-	if(id->level == -1) rc = sprintf(out_buf,"-\n");
-	else rc = sprintf(out_buf, "%i\n", id->level);
+	if(id->level == DEBUG_OFF_LEVEL) {
+		rc = sprintf(out_buf,"-\n");
+	}
+	else {
+		rc = sprintf(out_buf, "%i\n", id->level);
+	}
 	return rc;
 }
 
@@ -1025,30 +1249,43 @@ static int debug_prolog_level_fn(debug_i
  * reads new debug level
  */
 
-static int debug_input_level_fn(debug_info_t * id, struct debug_view *view,
-				struct file *file, const char __user *user_buf,
-				size_t in_buf_size, loff_t * offset)
-{
-	char input_buf[1];
-	int rc = in_buf_size;
-
-	if (*offset != 0)
+static int
+debug_input_level_fn(debug_info_t * id, struct debug_view *view,
+			struct file *file, const char __user *user_buf,
+			size_t user_len, loff_t * offset)
+{
+	char *str;
+	int rc,new_level;
+
+	if (user_len > 0x10000)
+                user_len = 0x10000;
+	if (*offset != 0){
+		rc = -EPIPE;
 		goto out;
-	if (copy_from_user(input_buf, user_buf, 1)){
-		rc = -EFAULT;
+	}
+	str = debug_get_user_string(user_buf,user_len);
+	if(IS_ERR(str)){
+		rc = PTR_ERR(str);
 		goto out;
 	}
-	if (isdigit(input_buf[0])) {
-		int new_level = ((int) input_buf[0] - (int) '0');
-		debug_set_level(id, new_level);
-	} else if(input_buf[0] == '-') {
+	if(str[0] == '-'){
 		debug_set_level(id, DEBUG_OFF_LEVEL);
+		rc = user_len;
+		goto free_str;
 	} else {
-		printk(KERN_INFO "debug: level `%c` is not valid\n",
-		       input_buf[0]);
+		new_level = debug_get_uint(str);
 	}
-      out:
-	*offset += in_buf_size;
+	if(new_level < 0) {
+		printk(KERN_INFO "debug: level `%s` is not valid\n", str);
+		rc = -EINVAL;
+	} else {
+		debug_set_level(id, new_level);
+		rc = user_len;
+	}
+free_str:
+	kfree(str);
+out:
+	*offset += user_len;
 	return rc;		/* number of input characters */
 }
 
@@ -1057,29 +1294,36 @@ static int debug_input_level_fn(debug_in
  * flushes debug areas
  */
  
-void debug_flush(debug_info_t* id, int area)
+void
+debug_flush(debug_info_t* id, int area)
 {
         unsigned long flags;
-        int i;
+        int i,j;
 
-        if(!id)
+        if(!id || !id->areas)
                 return;
         spin_lock_irqsave(&id->lock,flags);
         if(area == DEBUG_FLUSH_ALL){
                 id->active_area = 0;
-                memset(id->active_entry, 0, id->nr_areas * sizeof(int));
-                for (i = 0; i < id->nr_areas; i++) 
-                        memset(id->areas[i], 0, PAGE_SIZE << id->page_order);
+                memset(id->active_entries, 0, id->nr_areas * sizeof(int));
+                for (i = 0; i < id->nr_areas; i++) {
+			id->active_pages[i] = 0;
+			for(j = 0; j < id->pages_per_area; j++) {
+                        	memset(id->areas[i][j], 0, PAGE_SIZE);
+			}
+		}
                 printk(KERN_INFO "debug: %s: all areas flushed\n",id->name);
         } else if(area >= 0 && area < id->nr_areas) {
-                id->active_entry[area] = 0;
-                memset(id->areas[area], 0, PAGE_SIZE << id->page_order);
-                printk(KERN_INFO
-                        "debug: %s: area %i has been flushed\n",
+                id->active_entries[area] = 0;
+		id->active_pages[area] = 0;
+		for(i = 0; i < id->pages_per_area; i++) {
+                	memset(id->areas[area][i],0,PAGE_SIZE);
+		}
+                printk(KERN_INFO "debug: %s: area %i has been flushed\n",
                         id->name, area);
         } else {
                 printk(KERN_INFO
-                        "debug: %s: area %i cannot be flushed (range: %i - %i)\n",
+                      "debug: %s: area %i cannot be flushed (range: %i - %i)\n",
                         id->name, area, 0, id->nr_areas-1);
         }
         spin_unlock_irqrestore(&id->lock,flags);
@@ -1089,15 +1333,20 @@ void debug_flush(debug_info_t* id, int a
  * view function: flushes debug areas 
  */
 
-static int debug_input_flush_fn(debug_info_t * id, struct debug_view *view,
-                                struct file *file, const char __user *user_buf,
-                                size_t in_buf_size, loff_t * offset)
+static int
+debug_input_flush_fn(debug_info_t * id, struct debug_view *view,
+			struct file *file, const char __user *user_buf,
+			size_t user_len, loff_t * offset)
 {
         char input_buf[1];
-        int rc = in_buf_size;
- 
-        if (*offset != 0)
+        int rc = user_len;
+
+	if (user_len > 0x10000)
+                user_len = 0x10000;
+        if (*offset != 0){
+		rc = -EPIPE;
                 goto out;
+	}
         if (copy_from_user(input_buf, user_buf, 1)){
                 rc = -EFAULT;
                 goto out;
@@ -1114,8 +1363,8 @@ static int debug_input_flush_fn(debug_in
 
         printk(KERN_INFO "debug: area `%c` is not valid\n", input_buf[0]);
 
-      out:
-        *offset += in_buf_size;
+out:
+        *offset += user_len;
         return rc;              /* number of input characters */
 }
 
@@ -1123,8 +1372,9 @@ static int debug_input_flush_fn(debug_in
  * prints debug header in raw format
  */
 
-int debug_raw_header_fn(debug_info_t * id, struct debug_view *view,
-                         int area, debug_entry_t * entry, char *out_buf)
+static int
+debug_raw_header_fn(debug_info_t * id, struct debug_view *view,
+			int area, debug_entry_t * entry, char *out_buf)
 {
         int rc;
 
@@ -1137,7 +1387,8 @@ int debug_raw_header_fn(debug_info_t * i
  * prints debug data in raw format
  */
 
-static int debug_raw_format_fn(debug_info_t * id, struct debug_view *view,
+static int
+debug_raw_format_fn(debug_info_t * id, struct debug_view *view,
 			       char *out_buf, const char *in_buf)
 {
 	int rc;
@@ -1151,8 +1402,9 @@ static int debug_raw_format_fn(debug_inf
  * prints debug data in hex/ascii format
  */
 
-static int debug_hex_ascii_format_fn(debug_info_t * id, struct debug_view *view,
-		    		  char *out_buf, const char *in_buf)
+static int
+debug_hex_ascii_format_fn(debug_info_t * id, struct debug_view *view,
+	    		  char *out_buf, const char *in_buf)
 {
 	int i, rc = 0;
 
@@ -1176,7 +1428,8 @@ static int debug_hex_ascii_format_fn(deb
  * prints header for debug entry
  */
 
-int debug_dflt_header_fn(debug_info_t * id, struct debug_view *view,
+int
+debug_dflt_header_fn(debug_info_t * id, struct debug_view *view,
 			 int area, debug_entry_t * entry, char *out_buf)
 {
 	struct timeval time_val;
@@ -1210,8 +1463,9 @@ int debug_dflt_header_fn(debug_info_t * 
 
 #define DEBUG_SPRINTF_MAX_ARGS 10
 
-int debug_sprintf_format_fn(debug_info_t * id, struct debug_view *view,
-                            char *out_buf, debug_sprintf_entry_t *curr_event)
+static int
+debug_sprintf_format_fn(debug_info_t * id, struct debug_view *view,
+                        char *out_buf, debug_sprintf_entry_t *curr_event)
 {
 	int num_longs, num_used_args = 0,i, rc = 0;
 	int index[DEBUG_SPRINTF_MAX_ARGS];
@@ -1251,14 +1505,10 @@ out:
 /*
  * clean up module
  */
-void __exit debug_exit(void)
+void
+__exit debug_exit(void)
 {
-#ifdef DEBUG
-	printk("debug_cleanup_module: \n");
-#endif
-#ifdef CONFIG_PROC_FS
-	remove_proc_entry(debug_proc_root_entry->name, NULL);
-#endif /* CONFIG_PROC_FS */
+	debugfs_remove(debug_debugfs_root_entry);
 	unregister_sysctl_table(s390dbf_sysctl_header);
 	return;
 }
@@ -1266,7 +1516,7 @@ void __exit debug_exit(void)
 /*
  * module definitions
  */
-core_initcall(debug_init);
+postcore_initcall(debug_init);
 module_exit(debug_exit);
 MODULE_LICENSE("GPL");
 
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
--- a/arch/s390/kernel/entry.S
+++ b/arch/s390/kernel/entry.S
@@ -7,6 +7,7 @@
  *    Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
  *               Hartmut Penner (hp@de.ibm.com),
  *               Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com),
+ *		 Heiko Carstens <heiko.carstens@de.ibm.com>
  */
 
 #include <linux/sys.h>
@@ -49,9 +50,9 @@ SP_ILC       =  STACK_FRAME_OVERHEAD + _
 SP_TRAP      =  STACK_FRAME_OVERHEAD + __PT_TRAP
 SP_SIZE      =  STACK_FRAME_OVERHEAD + __PT_SIZE
 
-_TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | \
+_TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_MCCK_PENDING | \
 		 _TIF_RESTART_SVC | _TIF_SINGLE_STEP )
-_TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NEED_RESCHED)
+_TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_MCCK_PENDING)
 
 STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER
 STACK_SIZE  = 1 << STACK_SHIFT
@@ -121,7 +122,11 @@ STACK_SIZE  = 1 << STACK_SHIFT
 	bz	BASED(stack_overflow)
 3:
 #endif
-2:	s	%r15,BASED(.Lc_spsize)	# make room for registers & psw
+2:
+	.endm
+
+	.macro  CREATE_STACK_FRAME psworg,savearea
+	s	%r15,BASED(.Lc_spsize)	# make room for registers & psw
 	mvc	SP_PSW(8,%r15),0(%r12)	# move user PSW to stack
 	la	%r12,\psworg
 	st	%r2,SP_ORIG_R2(%r15)	# store original content of gpr 2
@@ -161,6 +166,13 @@ __switch_to_base:
         be      __switch_to_noper-__switch_to_base(%r1)	# we got away w/o bashing TLB's
         lctl    %c9,%c11,__THREAD_per(%r3)	# Nope we didn't
 __switch_to_noper:
+	l	%r4,__THREAD_info(%r2)		# get thread_info of prev
+	tm	__TI_flags+3(%r4),_TIF_MCCK_PENDING # machine check pending?
+	bz	__switch_to_no_mcck-__switch_to_base(%r1)
+	ni	__TI_flags+3(%r4),255-_TIF_MCCK_PENDING # clear flag in prev
+	l	%r4,__THREAD_info(%r3)		# get thread_info of next
+	oi	__TI_flags+3(%r4),_TIF_MCCK_PENDING # set it in next
+__switch_to_no_mcck:
         stm     %r6,%r15,__SF_GPRS(%r15)# store __switch_to registers of prev task
 	st	%r15,__THREAD_ksp(%r2)	# store kernel stack to prev->tss.ksp
 	l	%r15,__THREAD_ksp(%r3)	# load kernel stack from next->tss.ksp
@@ -185,6 +197,7 @@ system_call:
 sysc_saveall:
 	SAVE_ALL_BASE __LC_SAVE_AREA
         SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1
+	CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA
 	lh	%r7,0x8a	  # get svc number from lowcore
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
 sysc_vtime:
@@ -234,6 +247,8 @@ sysc_work_loop:
 # One of the work bits is on. Find out which one.
 #
 sysc_work:
+	tm	__TI_flags+3(%r9),_TIF_MCCK_PENDING
+	bo	BASED(sysc_mcck_pending)
 	tm	__TI_flags+3(%r9),_TIF_NEED_RESCHED
 	bo	BASED(sysc_reschedule)
 	tm	__TI_flags+3(%r9),_TIF_SIGPENDING
@@ -253,6 +268,14 @@ sysc_reschedule:        
 	br      %r1		       # call scheduler
 
 #
+# _TIF_MCCK_PENDING is set, call handler
+#
+sysc_mcck_pending:
+	l	%r1,BASED(.Ls390_handle_mcck)
+	la	%r14,BASED(sysc_work_loop)
+	br	%r1			# TIF bit will be cleared by handler
+
+#
 # _TIF_SIGPENDING is set, call do_signal
 #
 sysc_sigpending:     
@@ -430,6 +453,7 @@ pgm_check_handler:
         tm      __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception
         bnz     BASED(pgm_per)           # got per exception -> special case
 	SAVE_ALL __LC_PGM_OLD_PSW,__LC_SAVE_AREA,1
+	CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
 	tm	SP_PSW+1(%r15),0x01	# interrupting from user ?
 	bz	BASED(pgm_no_vtime)
@@ -468,6 +492,7 @@ pgm_per:
 #
 pgm_per_std:
 	SAVE_ALL __LC_PGM_OLD_PSW,__LC_SAVE_AREA,1
+	CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
 	tm	SP_PSW+1(%r15),0x01	# interrupting from user ?
 	bz	BASED(pgm_no_vtime2)
@@ -493,6 +518,7 @@ pgm_no_vtime2:
 #
 pgm_svcper:
 	SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1
+	CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
 	tm	SP_PSW+1(%r15),0x01	# interrupting from user ?
 	bz	BASED(pgm_no_vtime3)
@@ -521,6 +547,7 @@ io_int_handler:
 	stck	__LC_INT_CLOCK
 	SAVE_ALL_BASE __LC_SAVE_AREA+16
         SAVE_ALL __LC_IO_OLD_PSW,__LC_SAVE_AREA+16,0
+	CREATE_STACK_FRAME __LC_IO_OLD_PSW,__LC_SAVE_AREA+16
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
 	tm	SP_PSW+1(%r15),0x01	# interrupting from user ?
 	bz	BASED(io_no_vtime)
@@ -578,9 +605,11 @@ io_work:
 	lr	%r15,%r1
 #
 # One of the work bits is on. Find out which one.
-# Checked are: _TIF_SIGPENDING and _TIF_NEED_RESCHED
+# Checked are: _TIF_SIGPENDING, _TIF_NEED_RESCHED and _TIF_MCCK_PENDING
 #
 io_work_loop:
+	tm	__TI_flags+3(%r9),_TIF_MCCK_PENDING
+	bo      BASED(io_mcck_pending)
 	tm	__TI_flags+3(%r9),_TIF_NEED_RESCHED
 	bo	BASED(io_reschedule)
 	tm	__TI_flags+3(%r9),_TIF_SIGPENDING
@@ -588,6 +617,14 @@ io_work_loop:
 	b	BASED(io_leave)
 
 #
+# _TIF_MCCK_PENDING is set, call handler
+#
+io_mcck_pending:
+	l	%r1,BASED(.Ls390_handle_mcck)
+	l	%r14,BASED(io_work_loop)
+	br	%r1		       # TIF bit will be cleared by handler
+
+#
 # _TIF_NEED_RESCHED is set, call schedule
 #	
 io_reschedule:        
@@ -621,6 +658,7 @@ ext_int_handler:
 	stck	__LC_INT_CLOCK
 	SAVE_ALL_BASE __LC_SAVE_AREA+16
         SAVE_ALL __LC_EXT_OLD_PSW,__LC_SAVE_AREA+16,0
+	CREATE_STACK_FRAME __LC_EXT_OLD_PSW,__LC_SAVE_AREA+16
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
 	tm	SP_PSW+1(%r15),0x01	# interrupting from user ?
 	bz	BASED(ext_no_vtime)
@@ -642,19 +680,62 @@ ext_no_vtime:
 
         .globl mcck_int_handler
 mcck_int_handler:
-	STORE_TIMER __LC_ASYNC_ENTER_TIMER
+	spt	__LC_CPU_TIMER_SAVE_AREA	# revalidate cpu timer
+	lm	%r0,%r15,__LC_GPREGS_SAVE_AREA	# revalidate gprs
 	SAVE_ALL_BASE __LC_SAVE_AREA+32
-        SAVE_ALL __LC_MCK_OLD_PSW,__LC_SAVE_AREA+32,0
+	la	%r12,__LC_MCK_OLD_PSW
+	tm	__LC_MCCK_CODE,0x80     # system damage?
+	bo	BASED(mcck_int_main)	# yes -> rest of mcck code invalid
+	tm	__LC_MCCK_CODE+5,0x02   # stored cpu timer value valid?
+	bo	BASED(0f)
+	spt	__LC_LAST_UPDATE_TIMER	# revalidate cpu timer
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
-	tm	SP_PSW+1(%r15),0x01	# interrupting from user ?
+	mvc	__LC_ASYNC_ENTER_TIMER(8),__LC_LAST_UPDATE_TIMER
+	mvc	__LC_SYNC_ENTER_TIMER(8),__LC_LAST_UPDATE_TIMER
+	mvc	__LC_EXIT_TIMER(8),__LC_LAST_UPDATE_TIMER
+0:	tm	__LC_MCCK_CODE+2,0x08   # mwp of old psw valid?
+	bno	BASED(mcck_no_vtime)	# no -> skip cleanup critical
+	tm	__LC_MCK_OLD_PSW+1,0x01 # interrupting from user ?
 	bz	BASED(mcck_no_vtime)
 	UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER
 	UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
 	mvc	__LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER
 mcck_no_vtime:
 #endif
+0:
+	tm	__LC_MCCK_CODE+2,0x09   # mwp + ia of old psw valid?
+	bno	BASED(mcck_int_main)	# no -> skip cleanup critical
+	tm	__LC_MCK_OLD_PSW+1,0x01	# test problem state bit
+	bnz	BASED(mcck_int_main)	# from user -> load async stack
+	clc	__LC_MCK_OLD_PSW+4(4),BASED(.Lcritical_end)
+	bhe	BASED(mcck_int_main)
+	clc	__LC_MCK_OLD_PSW+4(4),BASED(.Lcritical_start)
+	bl	BASED(mcck_int_main)
+	l	%r14,BASED(.Lcleanup_critical)
+	basr	%r14,%r14
+mcck_int_main:
+	l	%r14,__LC_PANIC_STACK	# are we already on the panic stack?
+	slr	%r14,%r15
+	sra	%r14,PAGE_SHIFT
+	be	BASED(0f)
+	l	%r15,__LC_PANIC_STACK	# load panic stack
+0:	CREATE_STACK_FRAME __LC_MCK_OLD_PSW,__LC_SAVE_AREA+32
+	l	%r9,__LC_THREAD_INFO	# load pointer to thread_info struct
+	la	%r2,SP_PTREGS(%r15)	# load pt_regs
 	l       %r1,BASED(.Ls390_mcck)
-	basr    %r14,%r1	  # call machine check handler
+	basr    %r14,%r1		# call machine check handler
+	tm      SP_PSW+1(%r15),0x01	# returning to user ?
+	bno	BASED(mcck_return)
+	l	%r1,__LC_KERNEL_STACK   # switch to kernel stack
+	s	%r1,BASED(.Lc_spsize)
+	mvc	SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15)
+	xc      __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) # clear back chain
+	lr	%r15,%r1
+	stosm	__SF_EMPTY(%r15),0x04	# turn dat on
+	tm	__TI_flags+3(%r9),_TIF_MCCK_PENDING
+	bno	BASED(mcck_return)
+	l	%r1,BASED(.Ls390_handle_mcck)
+	basr	%r14,%r1		# call machine check handler
 mcck_return:
         RESTORE_ALL 0
 
@@ -742,7 +823,7 @@ cleanup_critical:
 	clc	4(4,%r12),BASED(cleanup_table_sysc_work_loop)
 	bl	BASED(0f)
 	clc	4(4,%r12),BASED(cleanup_table_sysc_work_loop+4)
-	bl	BASED(cleanup_sysc_leave)
+	bl	BASED(cleanup_sysc_return)
 0:
 	br	%r14
 
@@ -760,6 +841,7 @@ cleanup_system_call:
 	mvc	__LC_SAVE_AREA(16),__LC_SAVE_AREA+16
 0:	st	%r13,__LC_SAVE_AREA+20
 	SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1
+	CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA
 	st	%r15,__LC_SAVE_AREA+28
 	lh	%r7,0x8a
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
@@ -834,6 +916,8 @@ cleanup_sysc_leave_insn:
  * Symbol constants
  */
 .Ls390_mcck:   .long  s390_do_machine_check
+.Ls390_handle_mcck:
+	       .long  s390_handle_mcck
 .Ldo_IRQ:      .long  do_IRQ
 .Ldo_extint:   .long  do_extint
 .Ldo_signal:   .long  do_signal
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S
--- a/arch/s390/kernel/entry64.S
+++ b/arch/s390/kernel/entry64.S
@@ -7,6 +7,7 @@
  *    Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
  *               Hartmut Penner (hp@de.ibm.com),
  *               Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com),
+ *		 Heiko Carstens <heiko.carstens@de.ibm.com>
  */
 
 #include <linux/sys.h>
@@ -52,9 +53,9 @@ SP_SIZE      =  STACK_FRAME_OVERHEAD + _
 STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER
 STACK_SIZE  = 1 << STACK_SHIFT
 
-_TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | \
+_TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_MCCK_PENDING | \
 		 _TIF_RESTART_SVC | _TIF_SINGLE_STEP )
-_TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NEED_RESCHED)
+_TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_MCCK_PENDING)
 
 #define BASED(name) name-system_call(%r13)
 
@@ -114,7 +115,11 @@ _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_
 	jz	stack_overflow
 3:
 #endif
-2:	aghi    %r15,-SP_SIZE		# make room for registers & psw
+2:
+	.endm
+
+	.macro	CREATE_STACK_FRAME psworg,savearea
+	aghi    %r15,-SP_SIZE		# make room for registers & psw
 	mvc     SP_PSW(16,%r15),0(%r12)	# move user PSW to stack
 	la	%r12,\psworg
 	stg	%r2,SP_ORIG_R2(%r15)	# store original content of gpr 2
@@ -152,6 +157,13 @@ __switch_to:
         je      __switch_to_noper            # we got away without bashing TLB's
         lctlg   %c9,%c11,__THREAD_per(%r3)	# Nope we didn't
 __switch_to_noper:
+	lg	%r4,__THREAD_info(%r2)              # get thread_info of prev
+	tm	__TI_flags+7(%r4),_TIF_MCCK_PENDING # machine check pending?
+	jz	__switch_to_no_mcck
+	ni	__TI_flags+7(%r4),255-_TIF_MCCK_PENDING # clear flag in prev
+	lg	%r4,__THREAD_info(%r3)		    # get thread_info of next
+	oi	__TI_flags+7(%r4),_TIF_MCCK_PENDING # set it in next
+__switch_to_no_mcck:
         stmg    %r6,%r15,__SF_GPRS(%r15)# store __switch_to registers of prev task
 	stg	%r15,__THREAD_ksp(%r2)	# store kernel stack to prev->tss.ksp
 	lg	%r15,__THREAD_ksp(%r3)	# load kernel stack from next->tss.ksp
@@ -176,6 +188,7 @@ system_call:
 sysc_saveall:
 	SAVE_ALL_BASE __LC_SAVE_AREA
         SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1
+        CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA
 	llgh    %r7,__LC_SVC_INT_CODE # get svc number from lowcore
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
 sysc_vtime:
@@ -232,6 +245,8 @@ sysc_work_loop:
 # One of the work bits is on. Find out which one.
 #
 sysc_work:
+	tm	__TI_flags+7(%r9),_TIF_MCCK_PENDING
+	jo	sysc_mcck_pending
 	tm	__TI_flags+7(%r9),_TIF_NEED_RESCHED
 	jo	sysc_reschedule
 	tm	__TI_flags+7(%r9),_TIF_SIGPENDING
@@ -250,6 +265,13 @@ sysc_reschedule:        
         jg      schedule            # return point is sysc_return
 
 #
+# _TIF_MCCK_PENDING is set, call handler
+#
+sysc_mcck_pending:
+	larl	%r14,sysc_work_loop
+	jg	s390_handle_mcck    # TIF bit will be cleared by handler
+
+#
 # _TIF_SIGPENDING is set, call do_signal
 #
 sysc_sigpending:     
@@ -474,6 +496,7 @@ pgm_check_handler:
         tm      __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception
         jnz     pgm_per                  # got per exception -> special case
 	SAVE_ALL __LC_PGM_OLD_PSW,__LC_SAVE_AREA,1
+	CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
 	tm	SP_PSW+1(%r15),0x01	# interrupting from user ?
 	jz	pgm_no_vtime
@@ -512,6 +535,7 @@ pgm_per:
 #
 pgm_per_std:
 	SAVE_ALL __LC_PGM_OLD_PSW,__LC_SAVE_AREA,1
+	CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
 	tm	SP_PSW+1(%r15),0x01	# interrupting from user ?
 	jz	pgm_no_vtime2
@@ -537,6 +561,7 @@ pgm_no_vtime2:
 #
 pgm_svcper:
 	SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1
+	CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
 	tm	SP_PSW+1(%r15),0x01	# interrupting from user ?
 	jz	pgm_no_vtime3
@@ -564,6 +589,7 @@ io_int_handler:
 	stck	__LC_INT_CLOCK
 	SAVE_ALL_BASE __LC_SAVE_AREA+32
         SAVE_ALL __LC_IO_OLD_PSW,__LC_SAVE_AREA+32,0
+	CREATE_STACK_FRAME __LC_IO_OLD_PSW,__LC_SAVE_AREA+32
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
 	tm	SP_PSW+1(%r15),0x01	# interrupting from user ?
 	jz	io_no_vtime
@@ -621,9 +647,11 @@ io_work:
 	lgr	%r15,%r1
 #
 # One of the work bits is on. Find out which one.
-# Checked are: _TIF_SIGPENDING and _TIF_NEED_RESCHED
+# Checked are: _TIF_SIGPENDING, _TIF_NEED_RESCHED and _TIF_MCCK_PENDING
 #
 io_work_loop:
+	tm	__TI_flags+7(%r9),_TIF_MCCK_PENDING
+	jo	io_mcck_pending
 	tm	__TI_flags+7(%r9),_TIF_NEED_RESCHED
 	jo	io_reschedule
 	tm	__TI_flags+7(%r9),_TIF_SIGPENDING
@@ -631,6 +659,13 @@ io_work_loop:
 	j	io_leave
 
 #
+# _TIF_MCCK_PENDING is set, call handler
+#
+io_mcck_pending:
+	larl	%r14,io_work_loop
+	jg	s390_handle_mcck	# TIF bit will be cleared by handler
+
+#
 # _TIF_NEED_RESCHED is set, call schedule
 #	
 io_reschedule:        
@@ -661,6 +696,7 @@ ext_int_handler:
 	stck	__LC_INT_CLOCK
 	SAVE_ALL_BASE __LC_SAVE_AREA+32
         SAVE_ALL __LC_EXT_OLD_PSW,__LC_SAVE_AREA+32,0
+	CREATE_STACK_FRAME __LC_EXT_OLD_PSW,__LC_SAVE_AREA+32
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
 	tm	SP_PSW+1(%r15),0x01	# interrupting from user ?
 	jz	ext_no_vtime
@@ -680,18 +716,60 @@ ext_no_vtime:
  */
         .globl mcck_int_handler
 mcck_int_handler:
-	STORE_TIMER __LC_ASYNC_ENTER_TIMER
+	la	%r1,4095		# revalidate r1
+	spt	__LC_CPU_TIMER_SAVE_AREA-4095(%r1)	# revalidate cpu timer
+  	lmg     %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1)# revalidate gprs
 	SAVE_ALL_BASE __LC_SAVE_AREA+64
-        SAVE_ALL __LC_MCK_OLD_PSW,__LC_SAVE_AREA+64,0
+	la	%r12,__LC_MCK_OLD_PSW
+	tm	__LC_MCCK_CODE,0x80     # system damage?
+	jo	mcck_int_main		# yes -> rest of mcck code invalid
+	tm	__LC_MCCK_CODE+5,0x02   # stored cpu timer value valid?
+	jo	0f
+	spt	__LC_LAST_UPDATE_TIMER
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
-	tm	SP_PSW+1(%r15),0x01	# interrupting from user ?
+	mvc	__LC_ASYNC_ENTER_TIMER(8),__LC_LAST_UPDATE_TIMER
+	mvc	__LC_SYNC_ENTER_TIMER(8),__LC_LAST_UPDATE_TIMER
+	mvc	__LC_EXIT_TIMER(8),__LC_LAST_UPDATE_TIMER
+0:	tm	__LC_MCCK_CODE+2,0x08	# mwp of old psw valid?
+	jno	mcck_no_vtime		# no -> no timer update
+	tm      __LC_MCK_OLD_PSW+1,0x01 # interrupting from user ?
 	jz	mcck_no_vtime
 	UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER
 	UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
 	mvc	__LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER
 mcck_no_vtime:
 #endif
-	brasl   %r14,s390_do_machine_check
+0:
+	tm	__LC_MCCK_CODE+2,0x09   # mwp + ia of old psw valid?
+	jno	mcck_int_main		# no -> skip cleanup critical
+	tm      __LC_MCK_OLD_PSW+1,0x01 # test problem state bit
+	jnz	mcck_int_main		# from user -> load kernel stack
+	clc	__LC_MCK_OLD_PSW+8(8),BASED(.Lcritical_end)
+	jhe	mcck_int_main
+	clc     __LC_MCK_OLD_PSW+8(8),BASED(.Lcritical_start)
+	jl	mcck_int_main
+	brasl   %r14,cleanup_critical
+mcck_int_main:
+	lg      %r14,__LC_PANIC_STACK   # are we already on the panic stack?
+	slgr	%r14,%r15
+	srag	%r14,%r14,PAGE_SHIFT
+	jz	0f
+	lg      %r15,__LC_PANIC_STACK   # load panic stack
+0:	CREATE_STACK_FRAME __LC_MCK_OLD_PSW,__LC_SAVE_AREA+64
+	lg	%r9,__LC_THREAD_INFO	# load pointer to thread_info struct
+	la	%r2,SP_PTREGS(%r15)	# load pt_regs
+	brasl	%r14,s390_do_machine_check
+	tm	SP_PSW+1(%r15),0x01     # returning to user ?
+	jno	mcck_return
+	lg	%r1,__LC_KERNEL_STACK	# switch to kernel stack
+	aghi	%r1,-SP_SIZE
+	mvc	SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15)
+	xc	__SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1) # clear back chain
+	lgr	%r15,%r1
+	stosm	__SF_EMPTY(%r15),0x04	# turn dat on
+	tm	__TI_flags+7(%r9),_TIF_MCCK_PENDING
+	jno	mcck_return
+	brasl	%r14,s390_handle_mcck
 mcck_return:
         RESTORE_ALL 0
 
@@ -775,7 +853,7 @@ cleanup_critical:
 	clc	8(8,%r12),BASED(cleanup_table_sysc_work_loop)
 	jl	0f
 	clc	8(8,%r12),BASED(cleanup_table_sysc_work_loop+8)
-	jl	cleanup_sysc_leave
+	jl	cleanup_sysc_return
 0:
 	br	%r14
 
@@ -793,6 +871,7 @@ cleanup_system_call:
 	mvc	__LC_SAVE_AREA(32),__LC_SAVE_AREA+32
 0:	stg	%r13,__LC_SAVE_AREA+40
 	SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1
+	CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA
 	stg	%r15,__LC_SAVE_AREA+56
 	llgh	%r7,__LC_SVC_INT_CODE
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
diff --git a/arch/s390/kernel/head.S b/arch/s390/kernel/head.S
--- a/arch/s390/kernel/head.S
+++ b/arch/s390/kernel/head.S
@@ -345,10 +345,32 @@ iplstart:
 	bno   .Lnoreset
         la    %r2,.Lreset              
         lhi   %r3,26
-        .long 0x83230008
+	diag  %r2,%r3,8
+	la    %r5,.Lirb
+	stsch 0(%r5)			       # check if irq is pending
+	tm    30(%r5),0x0f		       # by verifying if any of the
+	bnz   .Lwaitforirq		       # activity or status control
+	tm    31(%r5),0xff		       # bits is set in the schib
+	bz    .Lnoreset
+.Lwaitforirq:
+	mvc   0x78(8),.Lrdrnewpsw              # set up IO interrupt psw
+.Lwaitrdrirq:
+	lpsw  .Lrdrwaitpsw
+.Lrdrint:
+	c     %r1,0xb8                         # compare subchannel number
+	bne   .Lwaitrdrirq
+	la    %r5,.Lirb
+	tsch  0(%r5)
 .Lnoreset:
+        b     .Lnoload
+
+	.align 8
+.Lrdrnewpsw:
+	.long  0x00080000,0x80000000+.Lrdrint
+.Lrdrwaitpsw:
+	.long  0x020a0000,0x80000000+.Lrdrint
 #endif
-	
+
 #
 # everything loaded, go for it
 #
@@ -517,11 +539,16 @@ startup:basr  %r13,0                    
 	l     %r2, .Lrcp2-.LPG1(%r13)	# try with Read SCP
 	b     .Lservicecall-.LPG1(%r13)
 .Lprocsccb:
-	lh    %r1,.Lscpincr1-PARMAREA(%r4) # use this one if != 0
-	chi   %r1,0x00
-	jne   .Lscnd
-	l     %r1,.Lscpincr2-PARMAREA(%r4) # otherwise use this one
+	lhi   %r1,0
+	icm   %r1,3,.Lscpincr1-PARMAREA(%r4) # use this one if != 0
+	jnz   .Lscnd
+	lhi   %r1,0x800			# otherwise report 2GB
 .Lscnd:
+	lhi   %r3,0x800			# limit reported memory size to 2GB
+	cr    %r1,%r3
+	jl    .Lno2gb
+	lr    %r1,%r3
+.Lno2gb:
 	xr    %r3,%r3			# same logic
 	ic    %r3,.Lscpa1-PARMAREA(%r4)
 	chi   %r3,0x00
@@ -750,7 +777,7 @@ _stext:	basr  %r13,0                    
 
 # check control registers
         stctl  %c0,%c15,0(%r15)
-	oi     2(%r15),0x20             # enable sigp external interrupts
+	oi     2(%r15),0x40             # enable sigp emergency signal
 	oi     0(%r15),0x10             # switch on low address protection
         lctl   %c0,%c15,0(%r15)
 
diff --git a/arch/s390/kernel/head64.S b/arch/s390/kernel/head64.S
--- a/arch/s390/kernel/head64.S
+++ b/arch/s390/kernel/head64.S
@@ -344,10 +344,32 @@ iplstart:
 	bno   .Lnoreset
         la    %r2,.Lreset              
         lhi   %r3,26
-        .long 0x83230008
+	diag  %r2,%r3,8
+	la    %r5,.Lirb
+	stsch 0(%r5)			       # check if irq is pending
+	tm    30(%r5),0x0f		       # by verifying if any of the
+	bnz   .Lwaitforirq		       # activity or status control
+	tm    31(%r5),0xff		       # bits is set in the schib
+	bz    .Lnoreset
+.Lwaitforirq:
+	mvc   0x78(8),.Lrdrnewpsw	       # set up IO interrupt psw
+.Lwaitrdrirq:
+	lpsw  .Lrdrwaitpsw
+.Lrdrint:
+	c     %r1,0xb8			       # compare subchannel number
+	bne   .Lwaitrdrirq
+	la    %r5,.Lirb
+	tsch  0(%r5)
 .Lnoreset:
+	b     .Lnoload
+
+	.align 8
+.Lrdrnewpsw:
+	.long  0x00080000,0x80000000+.Lrdrint
+.Lrdrwaitpsw:
+	.long  0x020a0000,0x80000000+.Lrdrint
 #endif
-	
+
 #
 # everything loaded, go for it
 #
@@ -518,9 +540,9 @@ startup:basr  %r13,0                    
 	l     %r2,.Lrcp2-.LPG1(%r13)	# try with Read SCP
 	b     .Lservicecall-.LPG1(%r13)
 .Lprocsccb:
-	lh    %r1,.Lscpincr1-PARMAREA(%r4) # use this one if != 0
-	chi   %r1,0x00
-	jne   .Lscnd
+	lghi  %r1,0
+	icm   %r1,3,.Lscpincr1-PARMAREA(%r4) # use this one if != 0
+	jnz   .Lscnd
 	lg    %r1,.Lscpincr2-PARMAREA(%r4) # otherwise use this one
 .Lscnd:
 	xr    %r3,%r3			# same logic
@@ -643,10 +665,8 @@ startup:basr  %r13,0                    
 #
 	la     %r1,0f-.LPG1(%r13)	# set program check address
 	stg    %r1,__LC_PGM_NEW_PSW+8
-	mvc    __LC_DIAG44_OPCODE(8),.Lnop-.LPG1(%r13)
 	diag   0,0,0x44			# test diag 0x44
 	oi     7(%r12),32		# set diag44 flag
-	mvc    __LC_DIAG44_OPCODE(8),.Ldiag44-.LPG1(%r13)
 0:	
 
 #
@@ -687,7 +707,6 @@ startup:basr  %r13,0                    
 .L4malign:.quad 0xffffffffffc00000
 .Lscan2g:.quad 0x80000000 + 0x20000 - 8 # 2GB + 128K - 8
 .Lnop:	.long  0x07000700
-.Ldiag44:.long 0x83000044
 
 	.org PARMAREA-64
 .Lduct:	.long 0,0,0,0,0,0,0,0
@@ -750,7 +769,7 @@ _stext:	basr  %r13,0                    
 
 # check control registers
         stctg  %c0,%c15,0(%r15)
-	oi     6(%r15),0x20             # enable sigp external interrupts
+	oi     6(%r15),0x40             # enable sigp emergency signal
 	oi     4(%r15),0x10             # switch on low address proctection
         lctlg  %c0,%c15,0(%r15)
 
diff --git a/arch/s390/kernel/machine_kexec.c b/arch/s390/kernel/machine_kexec.c
new file mode 100644
--- /dev/null
+++ b/arch/s390/kernel/machine_kexec.c
@@ -0,0 +1,105 @@
+/*
+ * arch/s390/kernel/machine_kexec.c
+ *
+ * (C) Copyright IBM Corp. 2005
+ *
+ * Author(s): Rolf Adelsberger <adelsberger@de.ibm.com>
+ *
+ */
+
+/*
+ * s390_machine_kexec.c - handle the transition of Linux booting another kernel
+ * on the S390 architecture.
+ */
+
+#include <asm/cio.h>
+#include <asm/setup.h>
+#include <linux/device.h>
+#include <linux/mm.h>
+#include <linux/kexec.h>
+#include <linux/delay.h>
+#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
+#include <asm/system.h>
+
+static void kexec_halt_all_cpus(void *);
+
+typedef void (*relocate_kernel_t) (kimage_entry_t *, unsigned long);
+
+const extern unsigned char relocate_kernel[];
+const extern unsigned long long relocate_kernel_len;
+
+int
+machine_kexec_prepare(struct kimage *image)
+{
+	unsigned long reboot_code_buffer;
+
+	/* We don't support anything but the default image type for now. */
+	if (image->type != KEXEC_TYPE_DEFAULT)
+		return -EINVAL;
+
+	/* Get the destination where the assembler code should be copied to.*/
+	reboot_code_buffer = page_to_pfn(image->control_code_page)<<PAGE_SHIFT;
+
+	/* Then copy it */
+	memcpy((void *) reboot_code_buffer, relocate_kernel,
+	       relocate_kernel_len);
+	return 0;
+}
+
+void
+machine_kexec_cleanup(struct kimage *image)
+{
+}
+
+void
+machine_shutdown(void)
+{
+	printk(KERN_INFO "kexec: machine_shutdown called\n");
+}
+
+NORET_TYPE void
+machine_kexec(struct kimage *image)
+{
+	clear_all_subchannels();
+
+	/* Disable lowcore protection */
+	ctl_clear_bit(0,28);
+
+	on_each_cpu(kexec_halt_all_cpus, image, 0, 0);
+	for (;;);
+}
+
+extern void pfault_fini(void);
+
+static void
+kexec_halt_all_cpus(void *kernel_image)
+{
+	static atomic_t cpuid = ATOMIC_INIT(-1);
+	int cpu;
+	struct kimage *image;
+	relocate_kernel_t data_mover;
+
+#ifdef CONFIG_PFAULT
+	if (MACHINE_IS_VM)
+		pfault_fini();
+#endif
+
+	if (atomic_compare_and_swap(-1, smp_processor_id(), &cpuid))
+		signal_processor(smp_processor_id(), sigp_stop);
+
+	/* Wait for all other cpus to enter stopped state */
+	for_each_online_cpu(cpu) {
+		if (cpu == smp_processor_id())
+			continue;
+		while (!smp_cpu_not_running(cpu))
+			cpu_relax();
+	}
+
+	image = (struct kimage *) kernel_image;
+	data_mover = (relocate_kernel_t)
+		(page_to_pfn(image->control_code_page) << PAGE_SHIFT);
+
+	/* Call the moving routine */
+	(*data_mover) (&image->head, image->start);
+}
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c
--- a/arch/s390/kernel/process.c
+++ b/arch/s390/kernel/process.c
@@ -91,13 +91,12 @@ void do_monitor_call(struct pt_regs *reg
 			    (void *)(long) smp_processor_id());
 }
 
+extern void s390_handle_mcck(void);
 /*
  * The idle loop on a S390...
  */
 void default_idle(void)
 {
-	psw_t wait_psw;
-	unsigned long reg;
 	int cpu, rc;
 
 	local_irq_disable();
@@ -125,38 +124,17 @@ void default_idle(void)
 		cpu_die();
 #endif
 
-	/* 
-	 * Wait for external, I/O or machine check interrupt and
-	 * switch off machine check bit after the wait has ended.
-	 */
-	wait_psw.mask = PSW_KERNEL_BITS | PSW_MASK_MCHECK | PSW_MASK_WAIT |
-		PSW_MASK_IO | PSW_MASK_EXT;
-#ifndef CONFIG_ARCH_S390X
-	asm volatile (
-		"    basr %0,0\n"
-		"0:  la   %0,1f-0b(%0)\n"
-		"    st   %0,4(%1)\n"
-		"    oi   4(%1),0x80\n"
-		"    lpsw 0(%1)\n"
-		"1:  la   %0,2f-1b(%0)\n"
-		"    st   %0,4(%1)\n"
-		"    oi   4(%1),0x80\n"
-		"    ni   1(%1),0xf9\n"
-		"    lpsw 0(%1)\n"
-		"2:"
-		: "=&a" (reg) : "a" (&wait_psw) : "memory", "cc" );
-#else /* CONFIG_ARCH_S390X */
-	asm volatile (
-		"    larl  %0,0f\n"
-		"    stg   %0,8(%1)\n"
-		"    lpswe 0(%1)\n"
-		"0:  larl  %0,1f\n"
-		"    stg   %0,8(%1)\n"
-		"    ni    1(%1),0xf9\n"
-		"    lpswe 0(%1)\n"
-		"1:"
-		: "=&a" (reg) : "a" (&wait_psw) : "memory", "cc" );
-#endif /* CONFIG_ARCH_S390X */
+	local_mcck_disable();
+	if (test_thread_flag(TIF_MCCK_PENDING)) {
+		local_mcck_enable();
+		local_irq_enable();
+		s390_handle_mcck();
+		return;
+	}
+
+	/* Wait for external, I/O or machine check interrupt. */
+	__load_psw_mask(PSW_KERNEL_BITS | PSW_MASK_WAIT |
+			PSW_MASK_IO | PSW_MASK_EXT);
 }
 
 void cpu_idle(void)
diff --git a/arch/s390/kernel/relocate_kernel.S b/arch/s390/kernel/relocate_kernel.S
new file mode 100644
--- /dev/null
+++ b/arch/s390/kernel/relocate_kernel.S
@@ -0,0 +1,120 @@
+/*
+ * arch/s390/kernel/relocate_kernel.S
+ *
+ * (C) Copyright IBM Corp. 2005
+ *
+ * Author(s): Rolf Adelsberger <adelsberger@de.ibm.com>
+ *	      Heiko Carstens <heiko.carstens@de.ibm.com>
+ *
+ */
+
+/*
+ * moves the new kernel to its destination...
+ * %r2 = pointer to first kimage_entry_t
+ * %r3 = start address - where to jump to after the job is done...
+ *
+ * %r5 will be used as temp. storage
+ * %r6 holds the destination address
+ * %r7 = PAGE_SIZE
+ * %r8 holds the source address
+ * %r9 = PAGE_SIZE
+ * %r10 is a page mask
+ */
+
+	.text
+	.globl		relocate_kernel
+	relocate_kernel:
+		basr	%r13,0		#base address
+	.base:
+		stnsm	sys_msk-.base(%r13),0xf8	#disable DAT and IRQ (external)
+		spx	zero64-.base(%r13)	#absolute addressing mode
+		stctl	%c0,%c15,ctlregs-.base(%r13)
+		stm	%r0,%r15,gprregs-.base(%r13)
+		la	%r1,load_psw-.base(%r13)
+		mvc     0(8,%r0),0(%r1)
+		la	%r0,.back-.base(%r13)
+		st	%r0,4(%r0)
+		oi	4(%r0),0x80
+		mvc	0x68(8,%r0),0(%r1)
+		la	%r0,.back_pgm-.base(%r13)
+		st	%r0,0x6c(%r0)
+		oi	0x6c(%r0),0x80
+		lhi	%r0,0
+		diag	%r0,%r0,0x308
+	.back:
+		basr	%r13,0
+	.back_base:
+		oi	have_diag308-.back_base(%r13),0x01
+		lctl	%c0,%c15,ctlregs-.back_base(%r13)
+		lm	%r0,%r15,gprregs-.back_base(%r13)
+		j	.start_reloc
+	.back_pgm:
+		lm	%r0,%r15,gprregs-.base(%r13)
+	.start_reloc:
+		lhi	%r10,-1		#preparing the mask
+		sll	%r10,12		#shift it such that it becomes 0xf000
+	.top:
+		lhi	%r7,4096	#load PAGE_SIZE in r7
+		lhi	%r9,4096	#load PAGE_SIZE in r9
+		l	%r5,0(%r2)	#read another word for indirection page
+		ahi	%r2,4		#increment pointer
+		tml	%r5,0x1		#is it a destination page?
+		je	.indir_check	#NO, goto "indir_check"
+		lr	%r6,%r5		#r6 = r5
+		nr	%r6,%r10	#mask it out and...
+		j	.top		#...next iteration
+	.indir_check:
+		tml	%r5,0x2		#is it a indirection page?
+		je	.done_test	#NO, goto "done_test"
+		nr	%r5,%r10	#YES, mask out,
+		lr	%r2,%r5		#move it into the right register,
+		j	.top		#and read next...
+	.done_test:
+		tml	%r5,0x4		#is it the done indicator?
+		je	.source_test	#NO! Well, then it should be the source indicator...
+		j	.done		#ok, lets finish it here...
+	.source_test:
+		tml	%r5,0x8		#it should be a source indicator...
+		je	.top		#NO, ignore it...
+		lr	%r8,%r5		#r8 = r5
+		nr	%r8,%r10	#masking
+	0:	mvcle	%r6,%r8,0x0	#copy PAGE_SIZE bytes from r8 to r6 - pad with 0
+		jo	0b
+		j	.top
+	.done:
+		sr	%r0,%r0		#clear register r0
+		la	%r4,load_psw-.base(%r13)	#load psw-address into the register
+		o	%r3,4(%r4)	#or load address into psw
+		st	%r3,4(%r4)
+		mvc	0(8,%r0),0(%r4)	#copy psw to absolute address 0
+		tm	have_diag308-.base(%r13),0x01
+		jno	.no_diag308
+		diag	%r0,%r0,0x308
+	.no_diag308:
+		sr	%r1,%r1		#clear %r1
+		sr	%r2,%r2		#clear %r2
+		sigp	%r1,%r2,0x12	#set cpuid to zero
+		lpsw	0		#hopefully start new kernel...
+
+		.align	8
+	zero64:
+		.quad	0
+	load_psw:
+		.long	0x00080000,0x80000000
+	sys_msk:
+		.quad	0
+	ctlregs:
+		.rept	16
+		.long	0
+		.endr
+	gprregs:
+		.rept	16
+		.long	0
+		.endr
+	have_diag308:
+		.byte	0
+		.align	8
+	relocate_kernel_end:
+	.globl	relocate_kernel_len
+	relocate_kernel_len:
+		.quad	relocate_kernel_end - relocate_kernel
diff --git a/arch/s390/kernel/relocate_kernel64.S b/arch/s390/kernel/relocate_kernel64.S
new file mode 100644
--- /dev/null
+++ b/arch/s390/kernel/relocate_kernel64.S
@@ -0,0 +1,123 @@
+/*
+ * arch/s390/kernel/relocate_kernel64.S
+ *
+ * (C) Copyright IBM Corp. 2005
+ *
+ * Author(s): Rolf Adelsberger <adelsberger@de.ibm.com>
+ *	      Heiko Carstens <heiko.carstens@de.ibm.com>
+ *
+ */
+
+/*
+ * moves the new kernel to its destination...
+ * %r2 = pointer to first kimage_entry_t
+ * %r3 = start address - where to jump to after the job is done...
+ *
+ * %r5 will be used as temp. storage
+ * %r6 holds the destination address
+ * %r7 = PAGE_SIZE
+ * %r8 holds the source address
+ * %r9 = PAGE_SIZE
+ *
+ * 0xf000 is a page_mask
+ */
+
+	.text
+	.globl		relocate_kernel
+	relocate_kernel:
+		basr	%r13,0		#base address
+	.base:
+		stnsm	sys_msk-.base(%r13),0xf8	#disable DAT and IRQs
+		spx	zero64-.base(%r13)	#absolute addressing mode
+		stctg	%c0,%c15,ctlregs-.base(%r13)
+		stmg	%r0,%r15,gprregs-.base(%r13)
+		lghi	%r0,3
+		sllg	%r0,%r0,31
+		stg	%r0,0x1d0(%r0)
+		la	%r0,.back_pgm-.base(%r13)
+		stg	%r0,0x1d8(%r0)
+		la	%r1,load_psw-.base(%r13)
+		mvc     0(8,%r0),0(%r1)
+		la	%r0,.back-.base(%r13)
+		st	%r0,4(%r0)
+		oi	4(%r0),0x80
+		lghi	%r0,0
+		diag	%r0,%r0,0x308
+	.back:
+		lhi	%r1,1		#mode 1 = esame
+		sigp	%r1,%r0,0x12	#switch to esame mode
+		sam64			#switch to 64 bit addressing mode
+		basr	%r13,0
+	.back_base:
+		oi	have_diag308-.back_base(%r13),0x01
+		lctlg	%c0,%c15,ctlregs-.back_base(%r13)
+		lmg	%r0,%r15,gprregs-.back_base(%r13)
+		j	.top
+	.back_pgm:
+		lmg	%r0,%r15,gprregs-.base(%r13)
+	.top:
+		lghi	%r7,4096	#load PAGE_SIZE in r7
+		lghi	%r9,4096	#load PAGE_SIZE in r9
+		lg	%r5,0(%r2)	#read another word for indirection page
+		aghi	%r2,8		#increment pointer
+		tml	%r5,0x1		#is it a destination page?
+		je	.indir_check	#NO, goto "indir_check"
+		lgr	%r6,%r5		#r6 = r5
+		nill	%r6,0xf000	#mask it out and...
+		j	.top		#...next iteration
+	.indir_check:
+		tml     %r5,0x2		#is it a indirection page?
+		je      .done_test	#NO, goto "done_test"
+		nill    %r5,0xf000	#YES, mask out,
+		lgr     %r2,%r5		#move it into the right register,
+		j       .top		#and read next...
+	.done_test:
+		tml     %r5,0x4		#is it the done indicator?
+		je      .source_test	#NO! Well, then it should be the source indicator...
+		j       .done		#ok, lets finish it here...
+	.source_test:
+		tml     %r5,0x8		#it should be a source indicator...
+		je      .top		#NO, ignore it...
+		lgr     %r8,%r5		#r8 = r5
+		nill    %r8,0xf000	#masking
+	0:	mvcle   %r6,%r8,0x0	#copy PAGE_SIZE bytes from r8 to r6 - pad with 0
+		jo	0b
+		j       .top
+	.done:
+		sgr     %r0,%r0		#clear register r0
+		la      %r4,load_psw-.base(%r13)	#load psw-address into the register
+		o	%r3,4(%r4)	#or load address into psw
+		st	%r3,4(%r4)
+		mvc     0(8,%r0),0(%r4)	#copy psw to absolute address 0
+		tm	have_diag308-.base(%r13),0x01
+		jno	.no_diag308
+		diag	%r0,%r0,0x308
+	.no_diag308:
+		sam31			#31 bit mode
+		sr      %r1,%r1		#erase register r1
+		sr      %r2,%r2		#erase register r2
+		sigp    %r1,%r2,0x12	#set cpuid to zero
+		lpsw    0		#hopefully start new kernel...
+
+	        .align	8
+	zero64:
+		.quad	0
+	load_psw:
+		.long	0x00080000,0x80000000
+	sys_msk:
+		.quad	0
+	ctlregs:
+		.rept	16
+		.quad	0
+		.endr
+	gprregs:
+		.rept	16
+		.quad	0
+		.endr
+	have_diag308:
+		.byte	0
+		.align	8
+	relocate_kernel_end:
+	.globl	relocate_kernel_len
+	relocate_kernel_len:
+		.quad	relocate_kernel_end - relocate_kernel
diff --git a/arch/s390/kernel/s390_ext.c b/arch/s390/kernel/s390_ext.c
--- a/arch/s390/kernel/s390_ext.c
+++ b/arch/s390/kernel/s390_ext.c
@@ -19,7 +19,6 @@
 #include <asm/irq.h>
 
 /*
- * Simple hash strategy: index = code & 0xff;
  * ext_int_hash[index] is the start of the list for all external interrupts
  * that hash to this index. With the current set of external interrupts 
  * (0x1202 external call, 0x1004 cpu timer, 0x2401 hwc console, 0x4000
@@ -27,6 +26,11 @@
  */
 ext_int_info_t *ext_int_hash[256] = { 0, };
 
+static inline int ext_hash(__u16 code)
+{
+	return (code + (code >> 9)) & 0xff;
+}
+
 int register_external_interrupt(__u16 code, ext_int_handler_t handler)
 {
         ext_int_info_t *p;
@@ -37,7 +41,7 @@ int register_external_interrupt(__u16 co
                 return -ENOMEM;
         p->code = code;
         p->handler = handler;
-        index = code & 0xff;
+	index = ext_hash(code);
         p->next = ext_int_hash[index];
         ext_int_hash[index] = p;
         return 0;
@@ -52,7 +56,7 @@ int register_early_external_interrupt(__
                 return -EINVAL;
         p->code = code;
         p->handler = handler;
-        index = code & 0xff;
+	index = ext_hash(code);
         p->next = ext_int_hash[index];
         ext_int_hash[index] = p;
         return 0;
@@ -63,7 +67,7 @@ int unregister_external_interrupt(__u16 
         ext_int_info_t *p, *q;
         int index;
 
-        index = code & 0xff;
+	index = ext_hash(code);
         q = NULL;
         p = ext_int_hash[index];
         while (p != NULL) {
@@ -90,7 +94,7 @@ int unregister_early_external_interrupt(
 
 	if (p == NULL || p->code != code || p->handler != handler)
 		return -EINVAL;
-	index = code & 0xff;
+	index = ext_hash(code);
 	q = ext_int_hash[index];
 	if (p != q) {
 		while (q != NULL) {
@@ -120,7 +124,7 @@ void do_extint(struct pt_regs *regs, uns
 		 */
 		account_ticks(regs);
 	kstat_cpu(smp_processor_id()).irqs[EXTERNAL_INTERRUPT]++;
-        index = code & 0xff;
+        index = ext_hash(code);
 	for (p = ext_int_hash[index]; p; p = p->next) {
 		if (likely(p->code == code)) {
 			if (likely(p->handler))
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -198,11 +198,11 @@ static void __init conmode_default(void)
 	char *ptr;
 
         if (MACHINE_IS_VM) {
-		__cpcmd("QUERY CONSOLE", query_buffer, 1024);
+		__cpcmd("QUERY CONSOLE", query_buffer, 1024, NULL);
 		console_devno = simple_strtoul(query_buffer + 5, NULL, 16);
 		ptr = strstr(query_buffer, "SUBCHANNEL =");
 		console_irq = simple_strtoul(ptr + 13, NULL, 16);
-		__cpcmd("QUERY TERM", query_buffer, 1024);
+		__cpcmd("QUERY TERM", query_buffer, 1024, NULL);
 		ptr = strstr(query_buffer, "CONMODE");
 		/*
 		 * Set the conmode to 3215 so that the device recognition 
@@ -211,7 +211,7 @@ static void __init conmode_default(void)
 		 * 3215 and the 3270 driver will try to access the console
 		 * device (3215 as console and 3270 as normal tty).
 		 */
-		__cpcmd("TERM CONMODE 3215", NULL, 0);
+		__cpcmd("TERM CONMODE 3215", NULL, 0, NULL);
 		if (ptr == NULL) {
 #if defined(CONFIG_SCLP_CONSOLE)
 			SET_CONSOLE_SCLP;
@@ -299,24 +299,18 @@ void machine_restart(char *command)
 	_machine_restart(command);
 }
 
-EXPORT_SYMBOL(machine_restart);
-
 void machine_halt(void)
 {
 	console_unblank();
 	_machine_halt();
 }
 
-EXPORT_SYMBOL(machine_halt);
-
 void machine_power_off(void)
 {
 	console_unblank();
 	_machine_power_off();
 }
 
-EXPORT_SYMBOL(machine_power_off);
-
 static void __init
 add_memory_hole(unsigned long start, unsigned long end)
 {
@@ -414,7 +408,8 @@ setup_lowcore(void)
 	lc->program_new_psw.mask = PSW_KERNEL_BITS;
 	lc->program_new_psw.addr =
 		PSW_ADDR_AMODE | (unsigned long)pgm_check_handler;
-	lc->mcck_new_psw.mask = PSW_KERNEL_BITS;
+	lc->mcck_new_psw.mask =
+		PSW_KERNEL_BITS & ~PSW_MASK_MCHECK & ~PSW_MASK_DAT;
 	lc->mcck_new_psw.addr =
 		PSW_ADDR_AMODE | (unsigned long) mcck_int_handler;
 	lc->io_new_psw.mask = PSW_KERNEL_BITS;
@@ -424,18 +419,18 @@ setup_lowcore(void)
 	lc->kernel_stack = ((unsigned long) &init_thread_union) + THREAD_SIZE;
 	lc->async_stack = (unsigned long)
 		__alloc_bootmem(ASYNC_SIZE, ASYNC_SIZE, 0) + ASYNC_SIZE;
-#ifdef CONFIG_CHECK_STACK
 	lc->panic_stack = (unsigned long)
 		__alloc_bootmem(PAGE_SIZE, PAGE_SIZE, 0) + PAGE_SIZE;
-#endif
 	lc->current_task = (unsigned long) init_thread_union.thread_info.task;
 	lc->thread_info = (unsigned long) &init_thread_union;
-#ifdef CONFIG_ARCH_S390X
-	if (MACHINE_HAS_DIAG44)
-		lc->diag44_opcode = 0x83000044;
-	else
-		lc->diag44_opcode = 0x07000700;
-#endif /* CONFIG_ARCH_S390X */
+#ifndef CONFIG_ARCH_S390X
+	if (MACHINE_HAS_IEEE) {
+		lc->extended_save_area_addr = (__u32)
+			__alloc_bootmem(PAGE_SIZE, PAGE_SIZE, 0);
+		/* enable extended save area */
+		ctl_set_bit(14, 29);
+	}
+#endif
 	set_prefix((u32)(unsigned long) lc);
 }
 
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -284,7 +284,7 @@ static void do_machine_restart(void * __
 	 * locks are always held disabled).
 	 */
 	if (MACHINE_IS_VM)
-		cpcmd ("IPL", NULL, 0);
+		cpcmd ("IPL", NULL, 0, NULL);
 	else
 		reipl (0x10000 | S390_lowcore.ipl_device);
 }
@@ -313,7 +313,7 @@ static void do_machine_halt(void * __unu
 	if (atomic_compare_and_swap(-1, smp_processor_id(), &cpuid) == 0) {
 		smp_send_stop();
 		if (MACHINE_IS_VM && strlen(vmhalt_cmd) > 0)
-			cpcmd(vmhalt_cmd, NULL, 0);
+			cpcmd(vmhalt_cmd, NULL, 0, NULL);
 		signal_processor(smp_processor_id(),
 				 sigp_stop_and_store_status);
 	}
@@ -332,7 +332,7 @@ static void do_machine_power_off(void * 
 	if (atomic_compare_and_swap(-1, smp_processor_id(), &cpuid) == 0) {
 		smp_send_stop();
 		if (MACHINE_IS_VM && strlen(vmpoff_cmd) > 0)
-			cpcmd(vmpoff_cmd, NULL, 0);
+			cpcmd(vmpoff_cmd, NULL, 0, NULL);
 		signal_processor(smp_processor_id(),
 				 sigp_stop_and_store_status);
 	}
@@ -375,7 +375,7 @@ static void smp_ext_bitcall(int cpu, ec_
          * Set signaling bit in lowcore of target cpu and kick it
          */
 	set_bit(sig, (unsigned long *) &lowcore_ptr[cpu]->ext_call_fast);
-	while(signal_processor(cpu, sigp_external_call) == sigp_busy)
+	while(signal_processor(cpu, sigp_emergency_signal) == sigp_busy)
 		udelay(10);
 }
 
@@ -394,7 +394,7 @@ static void smp_ext_bitcall_others(ec_bi
                  * Set signaling bit in lowcore of target cpu and kick it
                  */
 		set_bit(sig, (unsigned long *) &lowcore_ptr[cpu]->ext_call_fast);
-		while (signal_processor(cpu, sigp_external_call) == sigp_busy)
+		while (signal_processor(cpu, sigp_emergency_signal) == sigp_busy)
 			udelay(10);
         }
 }
@@ -537,7 +537,8 @@ int __devinit start_secondary(void *cpuv
 #endif
 #ifdef CONFIG_PFAULT
 	/* Enable pfault pseudo page faults on this cpu. */
-	pfault_init();
+	if (MACHINE_IS_VM)
+		pfault_init();
 #endif
 	/* Mark this cpu as online */
 	cpu_set(smp_processor_id(), cpu_online_map);
@@ -679,16 +680,19 @@ __cpu_disable(void)
 {
 	unsigned long flags;
 	ec_creg_mask_parms cr_parms;
+	int cpu = smp_processor_id();
 
 	spin_lock_irqsave(&smp_reserve_lock, flags);
-	if (smp_cpu_reserved[smp_processor_id()] != 0) {
+	if (smp_cpu_reserved[cpu] != 0) {
 		spin_unlock_irqrestore(&smp_reserve_lock, flags);
 		return -EBUSY;
 	}
+	cpu_clear(cpu, cpu_online_map);
 
 #ifdef CONFIG_PFAULT
 	/* Disable pfault pseudo page faults on this cpu. */
-	pfault_fini();
+	if (MACHINE_IS_VM)
+		pfault_fini();
 #endif
 
 	/* disable all external interrupts */
@@ -749,9 +753,9 @@ void __init smp_prepare_cpus(unsigned in
 	unsigned int cpu;
         int i;
 
-        /* request the 0x1202 external interrupt */
-        if (register_external_interrupt(0x1202, do_ext_call_interrupt) != 0)
-                panic("Couldn't request external interrupt 0x1202");
+        /* request the 0x1201 emergency signal external interrupt */
+        if (register_external_interrupt(0x1201, do_ext_call_interrupt) != 0)
+                panic("Couldn't request external interrupt 0x1201");
         smp_check_cpus(max_cpus);
         memset(lowcore_ptr,0,sizeof(lowcore_ptr));  
         /*
@@ -771,13 +775,24 @@ void __init smp_prepare_cpus(unsigned in
 
 		*(lowcore_ptr[i]) = S390_lowcore;
 		lowcore_ptr[i]->async_stack = stack + (ASYNC_SIZE);
-#ifdef CONFIG_CHECK_STACK
 		stack = __get_free_pages(GFP_KERNEL,0);
 		if (stack == 0ULL)
 			panic("smp_boot_cpus failed to allocate memory\n");
 		lowcore_ptr[i]->panic_stack = stack + (PAGE_SIZE);
+#ifndef __s390x__
+		if (MACHINE_HAS_IEEE) {
+			lowcore_ptr[i]->extended_save_area_addr =
+				(__u32) __get_free_pages(GFP_KERNEL,0);
+			if (lowcore_ptr[i]->extended_save_area_addr == 0)
+				panic("smp_boot_cpus failed to "
+				      "allocate memory\n");
+		}
 #endif
 	}
+#ifndef __s390x__
+	if (MACHINE_HAS_IEEE)
+		ctl_set_bit(14, 29); /* enable extended save area */
+#endif
 	set_prefix((u32)(unsigned long) lowcore_ptr[smp_processor_id()]);
 
 	for_each_cpu(cpu)
diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S
--- a/arch/s390/kernel/syscalls.S
+++ b/arch/s390/kernel/syscalls.S
@@ -285,8 +285,13 @@ SYSCALL(sys_mq_timedsend,sys_mq_timedsen
 SYSCALL(sys_mq_timedreceive,sys_mq_timedreceive,compat_sys_mq_timedreceive_wrapper)
 SYSCALL(sys_mq_notify,sys_mq_notify,compat_sys_mq_notify_wrapper) /* 275 */
 SYSCALL(sys_mq_getsetattr,sys_mq_getsetattr,compat_sys_mq_getsetattr_wrapper)
-NI_SYSCALL							/* reserved for kexec */
+SYSCALL(sys_kexec_load,sys_kexec_load,compat_sys_kexec_load_wrapper)
 SYSCALL(sys_add_key,sys_add_key,compat_sys_add_key_wrapper)
 SYSCALL(sys_request_key,sys_request_key,compat_sys_request_key_wrapper)
 SYSCALL(sys_keyctl,sys_keyctl,compat_sys_keyctl)		/* 280 */
 SYSCALL(sys_waitid,sys_waitid,compat_sys_waitid_wrapper)
+SYSCALL(sys_ioprio_set,sys_ioprio_set,sys_ioprio_set_wrapper)
+SYSCALL(sys_ioprio_get,sys_ioprio_get,sys_ioprio_get_wrapper)
+SYSCALL(sys_inotify_init,sys_inotify_init,sys_inotify_init)
+SYSCALL(sys_inotify_add_watch,sys_inotify_add_watch,sys_inotify_add_watch_wrapper)
+SYSCALL(sys_inotify_rm_watch,sys_inotify_rm_watch,sys_inotify_rm_watch_wrapper)
diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c
--- a/arch/s390/kernel/traps.c
+++ b/arch/s390/kernel/traps.c
@@ -29,6 +29,7 @@
 #include <linux/delay.h>
 #include <linux/module.h>
 #include <linux/kallsyms.h>
+#include <linux/reboot.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
@@ -668,10 +669,26 @@ asmlinkage void space_switch_exception(s
 
 asmlinkage void kernel_stack_overflow(struct pt_regs * regs)
 {
-	die("Kernel stack overflow", regs, 0);
+	bust_spinlocks(1);
+	printk("Kernel stack overflow.\n");
+	show_regs(regs);
+	bust_spinlocks(0);
 	panic("Corrupt kernel stack, can't continue.");
 }
 
+#ifndef CONFIG_ARCH_S390X
+static int
+pagex_reboot_event(struct notifier_block *this, unsigned long event, void *ptr)
+{
+	if (MACHINE_IS_VM)
+		cpcmd("SET PAGEX OFF", NULL, 0, NULL);
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block pagex_reboot_notifier = {
+	.notifier_call = &pagex_reboot_event,
+};
+#endif
 
 /* init is done in lowcore.S and head.S */
 
@@ -732,7 +749,8 @@ void __init trap_init(void)
 						    &ext_int_pfault);
 #endif
 #ifndef CONFIG_ARCH_S390X
-		cpcmd("SET PAGEX ON", NULL, 0);
+		register_reboot_notifier(&pagex_reboot_notifier);
+		cpcmd("SET PAGEX ON", NULL, 0, NULL);
 #endif
 	}
 }
diff --git a/arch/s390/lib/Makefile b/arch/s390/lib/Makefile
--- a/arch/s390/lib/Makefile
+++ b/arch/s390/lib/Makefile
@@ -5,5 +5,5 @@
 EXTRA_AFLAGS := -traditional
 
 lib-y += delay.o string.o
-lib-$(CONFIG_ARCH_S390_31) += uaccess.o
-lib-$(CONFIG_ARCH_S390X) += uaccess64.o
+lib-$(CONFIG_ARCH_S390_31) += uaccess.o spinlock.o
+lib-$(CONFIG_ARCH_S390X) += uaccess64.o spinlock.o
diff --git a/arch/s390/lib/spinlock.c b/arch/s390/lib/spinlock.c
new file mode 100644
--- /dev/null
+++ b/arch/s390/lib/spinlock.c
@@ -0,0 +1,133 @@
+/*
+ *  arch/s390/lib/spinlock.c
+ *    Out of line spinlock code.
+ *
+ *  S390 version
+ *    Copyright (C) 2004 IBM Deutschland Entwicklung GmbH, IBM Corporation
+ *    Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com)
+ */
+
+#include <linux/types.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/init.h>
+#include <asm/io.h>
+
+atomic_t spin_retry_counter;
+int spin_retry = 1000;
+
+/**
+ * spin_retry= parameter
+ */
+static int __init spin_retry_setup(char *str)
+{
+	spin_retry = simple_strtoul(str, &str, 0);
+	return 1;
+}
+__setup("spin_retry=", spin_retry_setup);
+
+static inline void
+_diag44(void)
+{
+#ifdef __s390x__
+	if (MACHINE_HAS_DIAG44)
+#endif
+		asm volatile("diag 0,0,0x44");
+}
+
+void
+_raw_spin_lock_wait(spinlock_t *lp, unsigned int pc)
+{
+	int count = spin_retry;
+
+	while (1) {
+		if (count-- <= 0) {
+			_diag44();
+			count = spin_retry;
+		}
+		atomic_inc(&spin_retry_counter);
+		if (_raw_compare_and_swap(&lp->lock, 0, pc) == 0)
+			return;
+	}
+}
+EXPORT_SYMBOL(_raw_spin_lock_wait);
+
+int
+_raw_spin_trylock_retry(spinlock_t *lp, unsigned int pc)
+{
+	int count = spin_retry;
+
+	while (count-- > 0) {
+		atomic_inc(&spin_retry_counter);
+		if (_raw_compare_and_swap(&lp->lock, 0, pc) == 0)
+			return 1;
+	}
+	return 0;
+}
+EXPORT_SYMBOL(_raw_spin_trylock_retry);
+
+void
+_raw_read_lock_wait(rwlock_t *rw)
+{
+	unsigned int old;
+	int count = spin_retry;
+
+	while (1) {
+		if (count-- <= 0) {
+			_diag44();
+			count = spin_retry;
+		}
+		atomic_inc(&spin_retry_counter);
+		old = rw->lock & 0x7fffffffU;
+		if (_raw_compare_and_swap(&rw->lock, old, old + 1) == old)
+			return;
+	}
+}
+EXPORT_SYMBOL(_raw_read_lock_wait);
+
+int
+_raw_read_trylock_retry(rwlock_t *rw)
+{
+	unsigned int old;
+	int count = spin_retry;
+
+	while (count-- > 0) {
+		atomic_inc(&spin_retry_counter);
+		old = rw->lock & 0x7fffffffU;
+		if (_raw_compare_and_swap(&rw->lock, old, old + 1) == old)
+			return 1;
+	}
+	return 0;
+}
+EXPORT_SYMBOL(_raw_read_trylock_retry);
+
+void
+_raw_write_lock_wait(rwlock_t *rw)
+{
+	int count = spin_retry;
+
+	while (1) {
+		if (count-- <= 0) {
+			_diag44();
+			count = spin_retry;
+		}
+		atomic_inc(&spin_retry_counter);
+		if (_raw_compare_and_swap(&rw->lock, 0, 0x80000000) == 0)
+			return;
+	}
+}
+EXPORT_SYMBOL(_raw_write_lock_wait);
+
+int
+_raw_write_trylock_retry(rwlock_t *rw)
+{
+	int count = spin_retry;
+
+	while (count-- > 0) {
+		atomic_inc(&spin_retry_counter);
+		if (_raw_compare_and_swap(&rw->lock, 0, 0x80000000) == 0)
+			return 1;
+	}
+	return 0;
+}
+EXPORT_SYMBOL(_raw_write_trylock_retry);
diff --git a/arch/s390/mm/cmm.c b/arch/s390/mm/cmm.c
--- a/arch/s390/mm/cmm.c
+++ b/arch/s390/mm/cmm.c
@@ -21,7 +21,7 @@
 #include <asm/uaccess.h>
 
 static char *sender = "VMRMSVM";
-module_param(sender, charp, 0);
+module_param(sender, charp, 0400);
 MODULE_PARM_DESC(sender,
 		 "Guest name that may send SMSG messages (default VMRMSVM)");
 
diff --git a/arch/s390/mm/extmem.c b/arch/s390/mm/extmem.c
--- a/arch/s390/mm/extmem.c
+++ b/arch/s390/mm/extmem.c
@@ -576,8 +576,8 @@ segment_save(char *name)
 			segtype_string[seg->range[i].start & 0xff]);
 	}
 	sprintf(cmd2, "SAVESEG %s", name);
-	cpcmd(cmd1, NULL, 0);
-	cpcmd(cmd2, NULL, 0);
+	cpcmd(cmd1, NULL, 0, NULL);
+	cpcmd(cmd2, NULL, 0, NULL);
 	spin_unlock(&dcss_lock);
 }
 
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -486,7 +486,7 @@ config CPU_SUBTYPE_ST40
        depends on CPU_SUBTYPE_ST40STB1 || CPU_SUBTYPE_ST40GX1
        default y
 
-config DISCONTIGMEM
+config ARCH_DISCONTIGMEM_ENABLE
 	bool
 	depends on SH_HP690
 	default y
@@ -496,6 +496,8 @@ config DISCONTIGMEM
 	  or have huge holes in the physical address space for other reasons.
 	  See <file:Documentation/vm/numa> for more.
 
+source "mm/Kconfig"
+
 config ZERO_PAGE_OFFSET
 	hex "Zero page offset"
 	default "0x00001000" if !(SH_MPC1211 || SH_SH03)
@@ -782,6 +784,8 @@ config EMBEDDED_RAMDISK_IMAGE
 
 endmenu
 
+source "net/Kconfig"
+
 source "drivers/Kconfig"
 
 source "fs/Kconfig"
diff --git a/arch/sh/kernel/entry.S b/arch/sh/kernel/entry.S
--- a/arch/sh/kernel/entry.S
+++ b/arch/sh/kernel/entry.S
@@ -1145,5 +1145,10 @@ ENTRY(sys_call_table)
 	.long sys_add_key		/* 285 */
 	.long sys_request_key
 	.long sys_keyctl
+	.long sys_ioprio_set
+	.long sys_ioprio_get
+	.long sys_inotify_init		/* 290 */
+	.long sys_inotify_add_watch
+	.long sys_inotify_rm_watch
 
 /* End of entry.S */
diff --git a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c
--- a/arch/sh/kernel/process.c
+++ b/arch/sh/kernel/process.c
@@ -80,8 +80,6 @@ void machine_restart(char * __unused)
 		     "mov.l @%1, %0" : : "r" (0x10000000), "r" (0x80000001));
 }
 
-EXPORT_SYMBOL(machine_restart);
-
 void machine_halt(void)
 {
 #if defined(CONFIG_SH_HS7751RVOIP)
@@ -96,8 +94,6 @@ void machine_halt(void)
 		cpu_sleep();
 }
 
-EXPORT_SYMBOL(machine_halt);
-
 void machine_power_off(void)
 {
 #if defined(CONFIG_SH_HS7751RVOIP)
@@ -110,8 +106,6 @@ void machine_power_off(void)
 #endif
 }
 
-EXPORT_SYMBOL(machine_power_off);
-
 void show_regs(struct pt_regs * regs)
 {
 	printk("\n");
diff --git a/arch/sh/kernel/signal.c b/arch/sh/kernel/signal.c
--- a/arch/sh/kernel/signal.c
+++ b/arch/sh/kernel/signal.c
@@ -579,7 +579,7 @@ int do_signal(struct pt_regs *regs, sigs
 	if (!user_mode(regs))
 		return 1;
 
-	if (try_to_freeze(0))
+	if (try_to_freeze())
 		goto no_signal;
 
 	if (!oldset)
diff --git a/arch/sh/kernel/sys_sh.c b/arch/sh/kernel/sys_sh.c
--- a/arch/sh/kernel/sys_sh.c
+++ b/arch/sh/kernel/sys_sh.c
@@ -79,6 +79,10 @@ unsigned long arch_get_unmapped_area(str
 		    (!vma || addr + len <= vma->vm_start))
 			return addr;
 	}
+	if (len <= mm->cached_hole_size) {
+	        mm->cached_hole_size = 0;
+		mm->free_area_cache = TASK_UNMAPPED_BASE;
+	}
 	if (flags & MAP_PRIVATE)
 		addr = PAGE_ALIGN(mm->free_area_cache);
 	else
@@ -95,6 +99,7 @@ full_search:
 			 */
 			if (start_addr != TASK_UNMAPPED_BASE) {
 				start_addr = addr = TASK_UNMAPPED_BASE;
+				mm->cached_hole_size = 0;
 				goto full_search;
 			}
 			return -ENOMEM;
@@ -106,6 +111,9 @@ full_search:
 			mm->free_area_cache = addr + len;
 			return addr;
 		}
+		if (addr + mm->cached_hole_size < vma->vm_start)
+		        mm->cached_hole_size = vma->vm_start - addr;
+
 		addr = vma->vm_end;
 		if (!(flags & MAP_PRIVATE))
 			addr = COLOUR_ALIGN(addr);
diff --git a/arch/sh/lib/delay.c b/arch/sh/lib/delay.c
--- a/arch/sh/lib/delay.c
+++ b/arch/sh/lib/delay.c
@@ -24,7 +24,7 @@ inline void __const_udelay(unsigned long
 	__asm__("dmulu.l	%0, %2\n\t"
 		"sts	mach, %0"
 		: "=r" (xloops)
-		: "0" (xloops), "r" (cpu_data[_smp_processor_id()].loops_per_jiffy)
+		: "0" (xloops), "r" (cpu_data[raw_smp_processor_id()].loops_per_jiffy)
 		: "macl", "mach");
 	__delay(xloops * HZ);
 }
diff --git a/arch/sh/mm/hugetlbpage.c b/arch/sh/mm/hugetlbpage.c
--- a/arch/sh/mm/hugetlbpage.c
+++ b/arch/sh/mm/hugetlbpage.c
@@ -24,7 +24,7 @@
 #include <asm/tlbflush.h>
 #include <asm/cacheflush.h>
 
-static pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr)
+pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr)
 {
 	pgd_t *pgd;
 	pmd_t *pmd;
@@ -39,7 +39,7 @@ static pte_t *huge_pte_alloc(struct mm_s
 	return pte;
 }
 
-static pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr)
+pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr)
 {
 	pgd_t *pgd;
 	pmd_t *pmd;
@@ -56,28 +56,34 @@ static pte_t *huge_pte_offset(struct mm_
 
 #define mk_pte_huge(entry) do { pte_val(entry) |= _PAGE_SZHUGE; } while (0)
 
-static void set_huge_pte(struct mm_struct *mm, struct vm_area_struct *vma,
-			 struct page *page, pte_t * page_table, int write_access)
+void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
+		     pte_t *ptep, pte_t entry)
 {
-	unsigned long i;
-	pte_t entry;
+	int i;
+
+	for (i = 0; i < (1 << HUGETLB_PAGE_ORDER); i++) {
+		set_pte_at(mm, addr, ptep, entry);
+		ptep++;
+		addr += PAGE_SIZE;
+		pte_val(entry) += PAGE_SIZE;
+	}
+}
 
-	add_mm_counter(mm, rss, HPAGE_SIZE / PAGE_SIZE);
+pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
+			      pte_t *ptep)
+{
+	pte_t entry;
+	int i;
 
-	if (write_access)
-		entry = pte_mkwrite(pte_mkdirty(mk_pte(page,
-						       vma->vm_page_prot)));
-	else
-		entry = pte_wrprotect(mk_pte(page, vma->vm_page_prot));
-	entry = pte_mkyoung(entry);
-	mk_pte_huge(entry);
+	entry = *ptep;
 
 	for (i = 0; i < (1 << HUGETLB_PAGE_ORDER); i++) {
-		set_pte(page_table, entry);
-		page_table++;
-
-		pte_val(entry) += PAGE_SIZE;
+		pte_clear(mm, addr, ptep);
+		addr += PAGE_SIZE;
+		ptep++;
 	}
+
+	return entry;
 }
 
 /*
@@ -92,79 +98,6 @@ int is_aligned_hugepage_range(unsigned l
 	return 0;
 }
 
-int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src,
-			    struct vm_area_struct *vma)
-{
-	pte_t *src_pte, *dst_pte, entry;
-	struct page *ptepage;
-	unsigned long addr = vma->vm_start;
-	unsigned long end = vma->vm_end;
-	int i;
-
-	while (addr < end) {
-		dst_pte = huge_pte_alloc(dst, addr);
-		if (!dst_pte)
-			goto nomem;
-		src_pte = huge_pte_offset(src, addr);
-		BUG_ON(!src_pte || pte_none(*src_pte));
-		entry = *src_pte;
-		ptepage = pte_page(entry);
-		get_page(ptepage);
-		for (i = 0; i < (1 << HUGETLB_PAGE_ORDER); i++) {
-			set_pte(dst_pte, entry);
-			pte_val(entry) += PAGE_SIZE;
-			dst_pte++;
-		}
-		add_mm_counter(dst, rss, HPAGE_SIZE / PAGE_SIZE);
-		addr += HPAGE_SIZE;
-	}
-	return 0;
-
-nomem:
-	return -ENOMEM;
-}
-
-int follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma,
-			struct page **pages, struct vm_area_struct **vmas,
-			unsigned long *position, int *length, int i)
-{
-	unsigned long vaddr = *position;
-	int remainder = *length;
-
-	WARN_ON(!is_vm_hugetlb_page(vma));
-
-	while (vaddr < vma->vm_end && remainder) {
-		if (pages) {
-			pte_t *pte;
-			struct page *page;
-
-			pte = huge_pte_offset(mm, vaddr);
-
-			/* hugetlb should be locked, and hence, prefaulted */
-			BUG_ON(!pte || pte_none(*pte));
-
-			page = pte_page(*pte);
-
-			WARN_ON(!PageCompound(page));
-
-			get_page(page);
-			pages[i] = page;
-		}
-
-		if (vmas)
-			vmas[i] = vma;
-
-		vaddr += PAGE_SIZE;
-		--remainder;
-		++i;
-	}
-
-	*length = remainder;
-	*position = vaddr;
-
-	return i;
-}
-
 struct page *follow_huge_addr(struct mm_struct *mm,
 			      unsigned long address, int write)
 {
@@ -181,84 +114,3 @@ struct page *follow_huge_pmd(struct mm_s
 {
 	return NULL;
 }
-
-void unmap_hugepage_range(struct vm_area_struct *vma,
-			  unsigned long start, unsigned long end)
-{
-	struct mm_struct *mm = vma->vm_mm;
-	unsigned long address;
-	pte_t *pte;
-	struct page *page;
-	int i;
-
-	BUG_ON(start & (HPAGE_SIZE - 1));
-	BUG_ON(end & (HPAGE_SIZE - 1));
-
-	for (address = start; address < end; address += HPAGE_SIZE) {
-		pte = huge_pte_offset(mm, address);
-		BUG_ON(!pte);
-		if (pte_none(*pte))
-			continue;
-		page = pte_page(*pte);
-		put_page(page);
-		for (i = 0; i < (1 << HUGETLB_PAGE_ORDER); i++) {
-			pte_clear(mm, address+(i*PAGE_SIZE), pte);
-			pte++;
-		}
-	}
-	add_mm_counter(mm, rss, -((end - start) >> PAGE_SHIFT));
-	flush_tlb_range(vma, start, end);
-}
-
-int hugetlb_prefault(struct address_space *mapping, struct vm_area_struct *vma)
-{
-	struct mm_struct *mm = current->mm;
-	unsigned long addr;
-	int ret = 0;
-
-	BUG_ON(vma->vm_start & ~HPAGE_MASK);
-	BUG_ON(vma->vm_end & ~HPAGE_MASK);
-
-	spin_lock(&mm->page_table_lock);
-	for (addr = vma->vm_start; addr < vma->vm_end; addr += HPAGE_SIZE) {
-		unsigned long idx;
-		pte_t *pte = huge_pte_alloc(mm, addr);
-		struct page *page;
-
-		if (!pte) {
-			ret = -ENOMEM;
-			goto out;
-		}
-		if (!pte_none(*pte))
-			continue;
-
-		idx = ((addr - vma->vm_start) >> HPAGE_SHIFT)
-			+ (vma->vm_pgoff >> (HPAGE_SHIFT - PAGE_SHIFT));
-		page = find_get_page(mapping, idx);
-		if (!page) {
-			/* charge the fs quota first */
-			if (hugetlb_get_quota(mapping)) {
-				ret = -ENOMEM;
-				goto out;
-			}
-			page = alloc_huge_page();
-			if (!page) {
-				hugetlb_put_quota(mapping);
-				ret = -ENOMEM;
-				goto out;
-			}
-			ret = add_to_page_cache(page, mapping, idx, GFP_ATOMIC);
-			if (! ret) {
-				unlock_page(page);
-			} else {
-				hugetlb_put_quota(mapping);
-				free_huge_page(page);
-				goto out;
-			}
-		}
-		set_huge_pte(mm, vma, page, pte, vma->vm_flags & VM_WRITE);
-	}
-out:
-	spin_unlock(&mm->page_table_lock);
-	return ret;
-}
diff --git a/arch/sh64/Kconfig b/arch/sh64/Kconfig
--- a/arch/sh64/Kconfig
+++ b/arch/sh64/Kconfig
@@ -217,6 +217,8 @@ config PREEMPT
 	bool "Preemptible Kernel (EXPERIMENTAL)"
 	depends on EXPERIMENTAL
 
+source "mm/Kconfig"
+
 endmenu
 
 menu "Bus options (PCI, PCMCIA, EISA, MCA, ISA)"
@@ -266,6 +268,8 @@ source "fs/Kconfig.binfmt"
 
 endmenu
 
+source "net/Kconfig"
+
 source "drivers/Kconfig"
 
 source "fs/Kconfig"
diff --git a/arch/sh64/kernel/signal.c b/arch/sh64/kernel/signal.c
--- a/arch/sh64/kernel/signal.c
+++ b/arch/sh64/kernel/signal.c
@@ -697,7 +697,7 @@ int do_signal(struct pt_regs *regs, sigs
 	if (!user_mode(regs))
 		return 1;
 
-	if (try_to_freeze(0))
+	if (try_to_freeze())
 		goto no_signal;
 
 	if (!oldset)
diff --git a/arch/sh64/kernel/syscalls.S b/arch/sh64/kernel/syscalls.S
--- a/arch/sh64/kernel/syscalls.S
+++ b/arch/sh64/kernel/syscalls.S
@@ -342,4 +342,9 @@ sys_call_table:
 	.long sys_add_key
 	.long sys_request_key
 	.long sys_keyctl		/* 315 */
+	.long sys_ioprio_set
+	.long sys_ioprio_get
+	.long sys_inotify_init
+	.long sys_inotify_add_watch
+	.long sys_inotify_rm_watch	/* 320 */
 
diff --git a/arch/sh64/mm/fault.c b/arch/sh64/mm/fault.c
--- a/arch/sh64/mm/fault.c
+++ b/arch/sh64/mm/fault.c
@@ -223,13 +223,13 @@ good_area:
 	 */
 survive:
 	switch (handle_mm_fault(mm, vma, address, writeaccess)) {
-	case 1:
+	case VM_FAULT_MINOR:
 		tsk->min_flt++;
 		break;
-	case 2:
+	case VM_FAULT_MAJOR:
 		tsk->maj_flt++;
 		break;
-	case 0:
+	case VM_FAULT_SIGBUS:
 		goto do_sigbus;
 	default:
 		goto out_of_memory;
diff --git a/arch/sh64/mm/hugetlbpage.c b/arch/sh64/mm/hugetlbpage.c
--- a/arch/sh64/mm/hugetlbpage.c
+++ b/arch/sh64/mm/hugetlbpage.c
@@ -24,7 +24,7 @@
 #include <asm/tlbflush.h>
 #include <asm/cacheflush.h>
 
-static pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr)
+pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr)
 {
 	pgd_t *pgd;
 	pmd_t *pmd;
@@ -39,7 +39,7 @@ static pte_t *huge_pte_alloc(struct mm_s
 	return pte;
 }
 
-static pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr)
+pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr)
 {
 	pgd_t *pgd;
 	pmd_t *pmd;
@@ -80,6 +80,20 @@ static void set_huge_pte(struct mm_struc
 	}
 }
 
+pte_t huge_ptep_get_and_clear(pte_t *ptep)
+{
+	pte_t entry;
+
+	entry = *ptep;
+
+	for (i = 0; i < (1 << HUGETLB_PAGE_ORDER); i++) {
+		pte_clear(pte);
+		pte++;
+	}
+
+	return entry;
+}
+
 /*
  * This function checks for proper alignment of input addr and len parameters.
  */
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -264,66 +264,18 @@ config SUNOS_EMUL
 	  want to run SunOS binaries on an Ultra you must also say Y to
 	  "Kernel support for 32-bit a.out binaries" above.
 
-source "drivers/parport/Kconfig"
-
-config PRINTER
-	tristate "Parallel printer support"
-	depends on PARPORT
-	---help---
-	  If you intend to attach a printer to the parallel port of your Linux
-	  box (as opposed to using a serial printer; if the connector at the
-	  printer has 9 or 25 holes ["female"], then it's serial), say Y.
-	  Also read the Printing-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  It is possible to share one parallel port among several devices
-	  (e.g. printer and ZIP drive) and it is safe to compile the
-	  corresponding drivers into the kernel.  If you want to compile this
-	  driver as a module however, choose M here and read
-	  <file:Documentation/parport.txt>.  The module will be called lp.
-
-	  If you have several parallel ports, you can specify which ports to
-	  use with the "lp" kernel command line option.  (Try "man bootparam"
-	  or see the documentation of your boot loader (silo) about how to pass
-	  options to the kernel at boot time.)  The syntax of the "lp" command
-	  line option can be found in <file:drivers/char/lp.c>.
-
-	  If you have more than 8 printers, you need to increase the LP_NO
-	  macro in lp.c and the PARPORT_MAX macro in parport.h.
+source "mm/Kconfig"
 
 endmenu
 
-source "drivers/base/Kconfig"
-
-source "drivers/video/Kconfig"
-
-source "drivers/mtd/Kconfig"
+source "net/Kconfig"
 
-source "drivers/serial/Kconfig"
+source "drivers/Kconfig"
 
 if !SUN4
 source "drivers/sbus/char/Kconfig"
 endif
 
-source "drivers/block/Kconfig"
-
-# Don't frighten a common SBus user
-if PCI
-
-source "drivers/ide/Kconfig"
-
-endif
-
-source "drivers/isdn/Kconfig"
-
-source "drivers/scsi/Kconfig"
-
-source "drivers/fc4/Kconfig"
-
-source "drivers/md/Kconfig"
-
-source "net/Kconfig"
-
 # This one must be before the filesystem configs. -DaveM
 
 menu "Unix98 PTY support"
@@ -372,18 +324,8 @@ config UNIX98_PTY_COUNT
 
 endmenu
 
-source "drivers/input/Kconfig"
-
 source "fs/Kconfig"
 
-source "sound/Kconfig"
-
-source "drivers/usb/Kconfig"
-
-source "drivers/infiniband/Kconfig"
-
-source "drivers/char/watchdog/Kconfig"
-
 source "arch/sparc/Kconfig.debug"
 
 source "security/Kconfig"
diff --git a/arch/sparc/kernel/process.c b/arch/sparc/kernel/process.c
--- a/arch/sparc/kernel/process.c
+++ b/arch/sparc/kernel/process.c
@@ -158,8 +158,6 @@ void machine_halt(void)
 	panic("Halt failed!");
 }
 
-EXPORT_SYMBOL(machine_halt);
-
 void machine_restart(char * cmd)
 {
 	char *p;
@@ -180,8 +178,6 @@ void machine_restart(char * cmd)
 	panic("Reboot failed!");
 }
 
-EXPORT_SYMBOL(machine_restart);
-
 void machine_power_off(void)
 {
 #ifdef CONFIG_SUN_AUXIO
@@ -191,8 +187,6 @@ void machine_power_off(void)
 	machine_halt();
 }
 
-EXPORT_SYMBOL(machine_power_off);
-
 static DEFINE_SPINLOCK(sparc_backtrace_lock);
 
 void __show_backtrace(unsigned long fp)
diff --git a/arch/sparc/kernel/sparc_ksyms.c b/arch/sparc/kernel/sparc_ksyms.c
--- a/arch/sparc/kernel/sparc_ksyms.c
+++ b/arch/sparc/kernel/sparc_ksyms.c
@@ -98,8 +98,9 @@ extern void ___rw_write_enter(void);
  * The module references will be fixed up by module_frob_arch_sections.
  */
 #define DOT_ALIAS2(__ret, __x, __arg1, __arg2) \
-	extern __ret __x(__arg1, __arg2) \
-	             __attribute__((weak, alias("." # __x)));
+	extern __ret __x(__arg1, __arg2); \
+	asm(".weak " #__x);\
+	asm(#__x "=." #__x);
 
 DOT_ALIAS2(int, div, int, int)
 DOT_ALIAS2(int, mul, int, int)
diff --git a/arch/sparc/kernel/systbls.S b/arch/sparc/kernel/systbls.S
--- a/arch/sparc/kernel/systbls.S
+++ b/arch/sparc/kernel/systbls.S
@@ -48,8 +48,8 @@ sys_call_table:
 /*135*/	.long sys_nis_syscall, sys_mkdir, sys_rmdir, sys_utimes, sys_stat64
 /*140*/	.long sys_sendfile64, sys_nis_syscall, sys_futex, sys_gettid, sys_getrlimit
 /*145*/	.long sys_setrlimit, sys_pivot_root, sys_prctl, sys_pciconfig_read, sys_pciconfig_write
-/*150*/	.long sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_poll, sys_getdents64
-/*155*/	.long sys_fcntl64, sys_ni_syscall, sys_statfs, sys_fstatfs, sys_oldumount
+/*150*/	.long sys_nis_syscall, sys_inotify_init, sys_inotify_add_watch, sys_poll, sys_getdents64
+/*155*/	.long sys_fcntl64, sys_inotify_rm_watch, sys_statfs, sys_fstatfs, sys_oldumount
 /*160*/	.long sys_sched_setaffinity, sys_sched_getaffinity, sys_getdomainname, sys_setdomainname, sys_nis_syscall
 /*165*/	.long sys_quotactl, sys_set_tid_address, sys_mount, sys_ustat, sys_setxattr
 /*170*/	.long sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr, sys_getdents
@@ -57,11 +57,11 @@ sys_call_table:
 /*180*/	.long sys_flistxattr, sys_removexattr, sys_lremovexattr, sys_sigpending, sys_ni_syscall
 /*185*/	.long sys_setpgid, sys_fremovexattr, sys_tkill, sys_exit_group, sys_newuname
 /*190*/	.long sys_init_module, sys_personality, sparc_remap_file_pages, sys_epoll_create, sys_epoll_ctl
-/*195*/	.long sys_epoll_wait, sys_nis_syscall, sys_getppid, sparc_sigaction, sys_sgetmask
+/*195*/	.long sys_epoll_wait, sys_ioprio_set, sys_getppid, sparc_sigaction, sys_sgetmask
 /*200*/	.long sys_ssetmask, sys_sigsuspend, sys_newlstat, sys_uselib, old_readdir
 /*205*/	.long sys_readahead, sys_socketcall, sys_syslog, sys_lookup_dcookie, sys_fadvise64
 /*210*/	.long sys_fadvise64_64, sys_tgkill, sys_waitpid, sys_swapoff, sys_sysinfo
-/*215*/	.long sys_ipc, sys_sigreturn, sys_clone, sys_nis_syscall, sys_adjtimex
+/*215*/	.long sys_ipc, sys_sigreturn, sys_clone, sys_ioprio_get, sys_adjtimex
 /*220*/	.long sys_sigprocmask, sys_ni_syscall, sys_delete_module, sys_ni_syscall, sys_getpgid
 /*225*/	.long sys_bdflush, sys_sysfs, sys_nis_syscall, sys_setfsuid16, sys_setfsgid16
 /*230*/	.long sys_select, sys_time, sys_nis_syscall, sys_stime, sys_statfs64
diff --git a/arch/sparc/mm/init.c b/arch/sparc/mm/init.c
--- a/arch/sparc/mm/init.c
+++ b/arch/sparc/mm/init.c
@@ -384,7 +384,6 @@ void map_high_region(unsigned long start
 		struct page *page = pfn_to_page(tmp);
 
 		ClearPageReserved(page);
-		set_bit(PG_highmem, &page->flags);
 		set_page_count(page, 1);
 		__free_page(page);
 		totalhigh_pages++;
diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig
--- a/arch/sparc64/Kconfig
+++ b/arch/sparc64/Kconfig
@@ -43,6 +43,25 @@ config SPARC64_PAGE_SIZE_4MB
 
 endchoice
 
+config SECCOMP
+	bool "Enable seccomp to safely compute untrusted bytecode"
+	depends on PROC_FS
+	default y
+	help
+	  This kernel feature is useful for number crunching applications
+	  that may need to compute untrusted bytecode during their
+	  execution. By using pipes or other transports made available to
+	  the process as file descriptors supporting the read/write
+	  syscalls, it's possible to isolate those applications in
+	  their own address space using seccomp. Once seccomp is
+	  enabled via /proc/<pid>/seccomp, it cannot be disabled
+	  and the task is only allowed to execute a few safe syscalls
+	  defined by each seccomp mode.
+
+	  If unsure, say Y. Only embedded should say N here.
+
+source kernel/Kconfig.hz
+
 source "init/Kconfig"
 
 config SYSVIPC_COMPAT
@@ -444,6 +463,24 @@ config PRINTER
 	  If you have more than 8 printers, you need to increase the LP_NO
 	  macro in lp.c and the PARPORT_MAX macro in parport.h.
 
+config PPDEV
+	tristate "Support for user-space parallel port device drivers"
+	depends on PARPORT
+	---help---
+	  Saying Y to this adds support for /dev/parport device nodes.  This
+	  is needed for programs that want portable access to the parallel
+	  port, for instance deviceid (which displays Plug-and-Play device
+	  IDs).
+
+	  This is the parallel port equivalent of SCSI generic support (sg).
+	  It is safe to say N to this -- it is not needed for normal printing
+	  or parallel port CD-ROM/disk support.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called ppdev.
+
+	  If unsure, say N.
+
 config ENVCTRL
 	tristate "SUNW, envctrl support"
 	depends on PCI
@@ -484,8 +521,12 @@ config CMDLINE
 
 	  NOTE: This option WILL override the PROM bootargs setting!
 
+source "mm/Kconfig"
+
 endmenu
 
+source "net/Kconfig"
+
 source "drivers/base/Kconfig"
 
 source "drivers/video/Kconfig"
@@ -512,7 +553,7 @@ endif
 
 source "drivers/ieee1394/Kconfig"
 
-source "net/Kconfig"
+source "drivers/net/Kconfig"
 
 source "drivers/isdn/Kconfig"
 
@@ -608,6 +649,8 @@ source "drivers/input/Kconfig"
 
 source "drivers/i2c/Kconfig"
 
+source "drivers/hwmon/Kconfig"
+
 source "fs/Kconfig"
 
 source "drivers/media/Kconfig"
diff --git a/arch/sparc64/kernel/Makefile b/arch/sparc64/kernel/Makefile
--- a/arch/sparc64/kernel/Makefile
+++ b/arch/sparc64/kernel/Makefile
@@ -8,7 +8,7 @@ EXTRA_CFLAGS := -Werror
 extra-y		:= head.o init_task.o vmlinux.lds
 
 obj-y		:= process.o setup.o cpu.o idprom.o \
-		   traps.o devices.o auxio.o \
+		   traps.o devices.o auxio.o una_asm.o \
 		   irq.o ptrace.o time.o sys_sparc.o signal.o \
 		   unaligned.o central.o pci.o starfire.o semaphore.o \
 		   power.o sbus.o iommu_common.o sparc64_ksyms.o chmc.o
diff --git a/arch/sparc64/kernel/auxio.c b/arch/sparc64/kernel/auxio.c
--- a/arch/sparc64/kernel/auxio.c
+++ b/arch/sparc64/kernel/auxio.c
@@ -16,7 +16,7 @@
 #include <asm/ebus.h>
 #include <asm/auxio.h>
 
-/* This cannot be static, as it is referenced in entry.S */
+/* This cannot be static, as it is referenced in irq.c */
 void __iomem *auxio_register = NULL;
 
 enum auxio_type {
diff --git a/arch/sparc64/kernel/dtlb_backend.S b/arch/sparc64/kernel/dtlb_backend.S
--- a/arch/sparc64/kernel/dtlb_backend.S
+++ b/arch/sparc64/kernel/dtlb_backend.S
@@ -16,7 +16,7 @@
 #elif PAGE_SHIFT == 19
 #define SZ_BITS		_PAGE_SZ512K
 #elif PAGE_SHIFT == 22
-#define SZ_BITS		_PAGE_SZ4M
+#define SZ_BITS		_PAGE_SZ4MB
 #endif
 
 #define VALID_SZ_BITS	(_PAGE_VALID | SZ_BITS)
diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S
--- a/arch/sparc64/kernel/entry.S
+++ b/arch/sparc64/kernel/entry.S
@@ -22,8 +22,6 @@
 #include <asm/estate.h>
 #include <asm/auxio.h>
 
-/* #define SYSCALL_TRACING	1 */
-
 #define curptr      g6
 
 #define NR_SYSCALLS 284      /* Each OS is different... */
@@ -271,8 +269,9 @@ cplus_fptrap_insn_1:
 	fmuld		%f0, %f2, %f26
 	faddd		%f0, %f2, %f28
 	fmuld		%f0, %f2, %f30
+	membar		#Sync
 	b,pt		%xcc, fpdis_exit
-	 membar		#Sync
+	 nop
 2:	andcc		%g5, FPRS_DU, %g0
 	bne,pt		%icc, 3f
 	 fzero		%f32
@@ -301,8 +300,9 @@ cplus_fptrap_insn_2:
 	fmuld		%f32, %f34, %f58
 	faddd		%f32, %f34, %f60
 	fmuld		%f32, %f34, %f62
+	membar		#Sync
 	ba,pt		%xcc, fpdis_exit
-	 membar		#Sync
+	 nop
 3:	mov		SECONDARY_CONTEXT, %g3
 	add		%g6, TI_FPREGS, %g1
 	ldxa		[%g3] ASI_DMMU, %g5
@@ -551,13 +551,11 @@ do_ivec:
 	sllx		%g3, 5, %g3
 	or		%g2, %lo(ivector_table), %g2
 	add		%g2, %g3, %g3
-	ldx		[%g3 + 0x08], %g2	/* irq_info */
 	ldub		[%g3 + 0x04], %g4	/* pil */
-	brz,pn		%g2, do_ivec_spurious
-	 mov		1, %g2
-
+	mov		1, %g2
 	sllx		%g2, %g4, %g2
 	sllx		%g4, 2, %g4
+
 	lduw		[%g6 + %g4], %g5	/* g5 = irq_work(cpu, pil) */
 	stw		%g5, [%g3 + 0x00]	/* bucket->irq_chain = g5 */
 	stw		%g3, [%g6 + %g4]	/* irq_work(cpu, pil) = bucket */
@@ -565,9 +563,9 @@ do_ivec:
 	retry
 do_ivec_xcall:
 	mov		0x50, %g1
-
 	ldxa		[%g1 + %g0] ASI_INTR_R, %g1
 	srl		%g3, 0, %g3
+
 	mov		0x60, %g7
 	ldxa		[%g7 + %g0] ASI_INTR_R, %g7
 	stxa		%g0, [%g0] ASI_INTR_RECEIVE
@@ -579,19 +577,6 @@ do_ivec_xcall:
 1:	jmpl		%g3, %g0
 	 nop
 
-do_ivec_spurious:
-	stw		%g3, [%g6 + 0x00]	/* irq_work(cpu, 0) = bucket */
-	rdpr		%pstate, %g5
-
-	wrpr		%g5, PSTATE_IG | PSTATE_AG, %pstate
-	sethi		%hi(109f), %g7
-	ba,pt		%xcc, etrap
-109:	 or		%g7, %lo(109b), %g7
-	call		catch_disabled_ivec
-	 add		%sp, PTREGS_OFF, %o0
-	ba,pt		%xcc, rtrap
-	 clr		%l6
-
 	.globl		save_alternate_globals
 save_alternate_globals: /* %o0 = save_area */
 	rdpr		%pstate, %o5
@@ -699,116 +684,6 @@ utrap_ill:
 	ba,pt		%xcc, rtrap
 	 clr		%l6
 
-#ifdef CONFIG_BLK_DEV_FD
-	.globl		floppy_hardint
-floppy_hardint:
-	wr		%g0, (1 << 11), %clear_softint
-	sethi		%hi(doing_pdma), %g1
-	ld		[%g1 + %lo(doing_pdma)], %g2
-	brz,pn		%g2, floppy_dosoftint
-	 sethi		%hi(fdc_status), %g3
-	ldx		[%g3 + %lo(fdc_status)], %g3
-	sethi		%hi(pdma_vaddr), %g5
-	ldx		[%g5 + %lo(pdma_vaddr)], %g4
-	sethi		%hi(pdma_size), %g5
-	ldx		[%g5 + %lo(pdma_size)], %g5
-
-next_byte:
-	lduba		[%g3] ASI_PHYS_BYPASS_EC_E, %g7
-	andcc		%g7, 0x80, %g0
-	be,pn		%icc, floppy_fifo_emptied
-	 andcc		%g7, 0x20, %g0
-	be,pn		%icc, floppy_overrun
-	 andcc		%g7, 0x40, %g0
-	be,pn		%icc, floppy_write
-	 sub		%g5, 1, %g5
-
-	inc		%g3
-	lduba		[%g3] ASI_PHYS_BYPASS_EC_E, %g7
-	dec		%g3
-	orcc		%g0, %g5, %g0
-	stb		%g7, [%g4]
-	bne,pn		%xcc, next_byte
-	 add		%g4, 1, %g4
-
-	b,pt		%xcc, floppy_tdone
-	 nop
-
-floppy_write:
-	ldub		[%g4], %g7
-	orcc		%g0, %g5, %g0
-	inc		%g3
-	stba		%g7, [%g3] ASI_PHYS_BYPASS_EC_E
-	dec		%g3
-	bne,pn		%xcc, next_byte
-	 add		%g4, 1, %g4
-
-floppy_tdone:
-	sethi		%hi(pdma_vaddr), %g1
-	stx		%g4, [%g1 + %lo(pdma_vaddr)]
-	sethi		%hi(pdma_size), %g1
-	stx		%g5, [%g1 + %lo(pdma_size)]
-	sethi		%hi(auxio_register), %g1
-	ldx		[%g1 + %lo(auxio_register)], %g7
-	lduba		[%g7] ASI_PHYS_BYPASS_EC_E, %g5
-	or		%g5, AUXIO_AUX1_FTCNT, %g5
-/*	andn		%g5, AUXIO_AUX1_MASK, %g5 */
-	stba		%g5, [%g7] ASI_PHYS_BYPASS_EC_E
-	andn		%g5, AUXIO_AUX1_FTCNT, %g5
-/*	andn		%g5, AUXIO_AUX1_MASK, %g5 */
-
-	nop; nop;  nop; nop;  nop; nop;
-	nop; nop;  nop; nop;  nop; nop;
-
-	stba		%g5, [%g7] ASI_PHYS_BYPASS_EC_E
-	sethi		%hi(doing_pdma), %g1
-	b,pt		%xcc, floppy_dosoftint
-	 st		%g0, [%g1 + %lo(doing_pdma)]
-
-floppy_fifo_emptied:
-	sethi		%hi(pdma_vaddr), %g1
-	stx		%g4, [%g1 + %lo(pdma_vaddr)]
-	sethi		%hi(pdma_size), %g1
-	stx		%g5, [%g1 + %lo(pdma_size)]
-	sethi		%hi(irq_action), %g1
-	or		%g1, %lo(irq_action), %g1
-	ldx		[%g1 + (11 << 3)], %g3		! irqaction[floppy_irq]
-	ldx		[%g3 + 0x08], %g4		! action->flags>>48==ino
-	sethi		%hi(ivector_table), %g3
-	srlx		%g4, 48, %g4
-	or		%g3, %lo(ivector_table), %g3
-	sllx		%g4, 5, %g4
-	ldx		[%g3 + %g4], %g4		! &ivector_table[ino]
-	ldx		[%g4 + 0x10], %g4		! bucket->iclr
-	stwa		%g0, [%g4] ASI_PHYS_BYPASS_EC_E	! ICLR_IDLE
-	membar		#Sync				! probably not needed...
-	retry
-
-floppy_overrun:
-	sethi		%hi(pdma_vaddr), %g1
-	stx		%g4, [%g1 + %lo(pdma_vaddr)]
-	sethi		%hi(pdma_size), %g1
-	stx		%g5, [%g1 + %lo(pdma_size)]
-	sethi		%hi(doing_pdma), %g1
-	st		%g0, [%g1 + %lo(doing_pdma)]
-
-floppy_dosoftint:
-	rdpr		%pil, %g2
-	wrpr		%g0, 15, %pil
-	sethi		%hi(109f), %g7
-	b,pt		%xcc, etrap_irq
-109:	 or		%g7, %lo(109b), %g7
-
-	mov		11, %o0
-	mov		0, %o1
-	call		sparc_floppy_irq
-	 add		%sp, PTREGS_OFF, %o2
-
-	b,pt		%xcc, rtrap_irq
-	 nop
-
-#endif /* CONFIG_BLK_DEV_FD */
-
 	/* XXX Here is stuff we still need to write... -DaveM XXX */
 	.globl		netbsd_syscall
 netbsd_syscall:
@@ -1677,11 +1552,12 @@ sys_ptrace:	add		%sp, PTREGS_OFF, %o0
 		nop
 		.align		32
 1:		ldx		[%curptr + TI_FLAGS], %l5
-		andcc		%l5, _TIF_SYSCALL_TRACE, %g0
+		andcc		%l5, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT), %g0
 		be,pt		%icc, rtrap
 		 clr		%l6
+		add		%sp, PTREGS_OFF, %o0
 		call		syscall_trace
-		 nop
+		 mov		1, %o1
 
 		ba,pt		%xcc, rtrap
 		 clr		%l6
@@ -1724,11 +1600,11 @@ sys_clone:	flushw
 		ba,pt		%xcc, sparc_do_fork
 		 add		%sp, PTREGS_OFF, %o2
 ret_from_syscall:
-		/* Clear SPARC_FLAG_NEWCHILD, switch_to leaves thread.flags in
-		 * %o7 for us.  Check performance counter stuff too.
+		/* Clear current_thread_info()->new_child, and
+		 * check performance counter stuff too.
 		 */
-		andn		%o7, _TIF_NEWCHILD, %l0
-		stx		%l0, [%g6 + TI_FLAGS]
+		stb		%g0, [%g6 + TI_NEW_CHILD]
+		ldx		[%g6 + TI_FLAGS], %l0
 		call		schedule_tail
 		 mov		%g7, %o0
 		andcc		%l0, _TIF_PERFCTR, %g0
@@ -1765,18 +1641,20 @@ linux_sparc_ni_syscall:
 	 or		%l7, %lo(sys_ni_syscall), %l7
 
 linux_syscall_trace32:
+	add		%sp, PTREGS_OFF, %o0
 	call		syscall_trace
-	 nop
+	 clr		%o1
 	srl		%i0, 0, %o0
-	mov		%i4, %o4
+	srl		%i4, 0, %o4
 	srl		%i1, 0, %o1
 	srl		%i2, 0, %o2
 	b,pt		%xcc, 2f
 	 srl		%i3, 0, %o3
 
 linux_syscall_trace:
+	add		%sp, PTREGS_OFF, %o0
 	call		syscall_trace
-	 nop
+	 clr		%o1
 	mov		%i0, %o0
 	mov		%i1, %o1
 	mov		%i2, %o2
@@ -1794,11 +1672,6 @@ linux_sparc_syscall32:
 	bgeu,pn		%xcc, linux_sparc_ni_syscall		! CTI
 	 srl		%i0, 0, %o0				! IEU0
 	sll		%g1, 2, %l4				! IEU0	Group
-#ifdef SYSCALL_TRACING
-	call		syscall_trace_entry
-	 add		%sp, PTREGS_OFF, %o0
-	srl		%i0, 0, %o0
-#endif
 	srl		%i4, 0, %o4				! IEU1
 	lduw		[%l7 + %l4], %l7			! Load
 	srl		%i1, 0, %o1				! IEU0	Group
@@ -1806,7 +1679,7 @@ linux_sparc_syscall32:
 
 	srl		%i5, 0, %o5				! IEU1
 	srl		%i2, 0, %o2				! IEU0	Group
-	andcc		%l0, _TIF_SYSCALL_TRACE, %g0		! IEU0	Group
+	andcc		%l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT), %g0
 	bne,pn		%icc, linux_syscall_trace32		! CTI
 	 mov		%i0, %l5				! IEU1
 	call		%l7					! CTI	Group brk forced
@@ -1822,11 +1695,6 @@ linux_sparc_syscall:
 	bgeu,pn		%xcc, linux_sparc_ni_syscall		! CTI
 	 mov		%i0, %o0				! IEU0
 	sll		%g1, 2, %l4				! IEU0	Group
-#ifdef SYSCALL_TRACING
-	call		syscall_trace_entry
-	 add		%sp, PTREGS_OFF, %o0
-	mov		%i0, %o0
-#endif
 	mov		%i1, %o1				! IEU1
 	lduw		[%l7 + %l4], %l7			! Load
 4:	mov		%i2, %o2				! IEU0	Group
@@ -1834,7 +1702,7 @@ linux_sparc_syscall:
 
 	mov		%i3, %o3				! IEU1
 	mov		%i4, %o4				! IEU0	Group
-	andcc		%l0, _TIF_SYSCALL_TRACE, %g0		! IEU1	Group+1 bubble
+	andcc		%l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT), %g0
 	bne,pn		%icc, linux_syscall_trace		! CTI	Group
 	 mov		%i0, %l5				! IEU0
 2:	call		%l7					! CTI	Group brk forced
@@ -1843,12 +1711,6 @@ linux_sparc_syscall:
 
 3:	stx		%o0, [%sp + PTREGS_OFF + PT_V9_I0]
 ret_sys_call:
-#ifdef SYSCALL_TRACING
-	mov		%o0, %o1
-	call		syscall_trace_exit
-	 add		%sp, PTREGS_OFF, %o0
-	mov		%o1, %o0
-#endif
 	ldx		[%sp + PTREGS_OFF + PT_V9_TSTATE], %g3
 	ldx		[%sp + PTREGS_OFF + PT_V9_TNPC], %l1 ! pc = npc
 	sra		%o0, 0, %o0
@@ -1858,17 +1720,16 @@ ret_sys_call:
 	/* Check if force_successful_syscall_return()
 	 * was invoked.
 	 */
-	ldx		[%curptr + TI_FLAGS], %l0
-	andcc		%l0, _TIF_SYSCALL_SUCCESS, %g0
-	be,pt		%icc, 1f
-	 andn		%l0, _TIF_SYSCALL_SUCCESS, %l0
+	ldub		[%curptr + TI_SYS_NOERROR], %l0
+	brz,pt		%l0, 1f
+	 nop
 	ba,pt		%xcc, 80f
-	 stx		%l0, [%curptr + TI_FLAGS]
+	 stb		%g0, [%curptr + TI_SYS_NOERROR]
 
 1:
 	cmp		%o0, -ERESTART_RESTARTBLOCK
 	bgeu,pn		%xcc, 1f
-	 andcc		%l0, _TIF_SYSCALL_TRACE, %l6	
+	 andcc		%l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT), %l6
 80:
 	/* System call success, clear Carry condition code. */
 	andn		%g3, %g2, %g3
@@ -1883,7 +1744,7 @@ ret_sys_call:
 	/* System call failure, set Carry condition code.
 	 * Also, get abs(errno) to return to the process.
 	 */
-	andcc		%l0, _TIF_SYSCALL_TRACE, %l6	
+	andcc		%l0, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT), %l6	
 	sub		%g0, %o0, %o0
 	or		%g3, %g2, %g3
 	stx		%o0, [%sp + PTREGS_OFF + PT_V9_I0]
@@ -1896,8 +1757,9 @@ ret_sys_call:
 	b,pt		%xcc, rtrap
 	 stx		%l2, [%sp + PTREGS_OFF + PT_V9_TNPC]
 linux_syscall_trace2:
+	add		%sp, PTREGS_OFF, %o0
 	call		syscall_trace
-	 nop
+	 mov		1, %o1
 	stx		%l1, [%sp + PTREGS_OFF + PT_V9_TPC]
 	ba,pt		%xcc, rtrap
 	 stx		%l2, [%sp + PTREGS_OFF + PT_V9_TNPC]
diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c
--- a/arch/sparc64/kernel/irq.c
+++ b/arch/sparc64/kernel/irq.c
@@ -37,6 +37,7 @@
 #include <asm/uaccess.h>
 #include <asm/cache.h>
 #include <asm/cpudata.h>
+#include <asm/auxio.h>
 
 #ifdef CONFIG_SMP
 static void distribute_irqs(void);
@@ -70,31 +71,7 @@ struct irq_work_struct {
 struct irq_work_struct __irq_work[NR_CPUS];
 #define irq_work(__cpu, __pil)	&(__irq_work[(__cpu)].irq_worklists[(__pil)])
 
-#ifdef CONFIG_PCI
-/* This is a table of physical addresses used to deal with IBF_DMA_SYNC.
- * It is used for PCI only to synchronize DMA transfers with IRQ delivery
- * for devices behind busses other than APB on Sabre systems.
- *
- * Currently these physical addresses are just config space accesses
- * to the command register for that device.
- */
-unsigned long pci_dma_wsync;
-unsigned long dma_sync_reg_table[256];
-unsigned char dma_sync_reg_table_entry = 0;
-#endif
-
-/* This is based upon code in the 32-bit Sparc kernel written mostly by
- * David Redman (djhr@tadpole.co.uk).
- */
-#define MAX_STATIC_ALLOC	4
-static struct irqaction static_irqaction[MAX_STATIC_ALLOC];
-static int static_irq_count;
-
-/* This is exported so that fast IRQ handlers can get at it... -DaveM */
-struct irqaction *irq_action[NR_IRQS+1] = {
-	  NULL, NULL, NULL, NULL, NULL, NULL , NULL, NULL,
-	  NULL, NULL, NULL, NULL, NULL, NULL , NULL, NULL
-};
+static struct irqaction *irq_action[NR_IRQS+1];
 
 /* This only synchronizes entities which modify IRQ handler
  * state and some selected user-level spots that want to
@@ -240,17 +217,22 @@ void disable_irq(unsigned int irq)
  * the CPU %tick register and not by some normal vectored interrupt
  * source.  To handle this special case, we use this dummy INO bucket.
  */
+static struct irq_desc pil0_dummy_desc;
 static struct ino_bucket pil0_dummy_bucket = {
-	0,	/* irq_chain */
-	0,	/* pil */
-	0,	/* pending */
-	0,	/* flags */
-	0,	/* __unused */
-	NULL,	/* irq_info */
-	0UL,	/* iclr */
-	0UL,	/* imap */
+	.irq_info	=	&pil0_dummy_desc,
 };
 
+static void build_irq_error(const char *msg, unsigned int ino, int pil, int inofixup,
+			    unsigned long iclr, unsigned long imap,
+			    struct ino_bucket *bucket)
+{
+	prom_printf("IRQ: INO %04x (%d:%016lx:%016lx) --> "
+		    "(%d:%d:%016lx:%016lx), halting...\n",
+		    ino, bucket->pil, bucket->iclr, bucket->imap,
+		    pil, inofixup, iclr, imap);
+	prom_halt();
+}
+
 unsigned int build_irq(int pil, int inofixup, unsigned long iclr, unsigned long imap)
 {
 	struct ino_bucket *bucket;
@@ -279,28 +261,35 @@ unsigned int build_irq(int pil, int inof
 		prom_halt();
 	}
 
-	/* Ok, looks good, set it up.  Don't touch the irq_chain or
-	 * the pending flag.
-	 */
 	bucket = &ivector_table[ino];
-	if ((bucket->flags & IBF_ACTIVE) ||
-	    (bucket->irq_info != NULL)) {
-		/* This is a gross fatal error if it happens here. */
-		prom_printf("IRQ: Trying to reinit INO bucket, fatal error.\n");
-		prom_printf("IRQ: Request INO %04x (%d:%d:%016lx:%016lx)\n",
-			    ino, pil, inofixup, iclr, imap);
-		prom_printf("IRQ: Existing (%d:%016lx:%016lx)\n",
-			    bucket->pil, bucket->iclr, bucket->imap);
-		prom_printf("IRQ: Cannot continue, halting...\n");
+	if (bucket->flags & IBF_ACTIVE)
+		build_irq_error("IRQ: Trying to build active INO bucket.\n",
+				ino, pil, inofixup, iclr, imap, bucket);
+
+	if (bucket->irq_info) {
+		if (bucket->imap != imap || bucket->iclr != iclr)
+			build_irq_error("IRQ: Trying to reinit INO bucket.\n",
+					ino, pil, inofixup, iclr, imap, bucket);
+
+		goto out;
+	}
+
+	bucket->irq_info = kmalloc(sizeof(struct irq_desc), GFP_ATOMIC);
+	if (!bucket->irq_info) {
+		prom_printf("IRQ: Error, kmalloc(irq_desc) failed.\n");
 		prom_halt();
 	}
+	memset(bucket->irq_info, 0, sizeof(struct irq_desc));
+
+	/* Ok, looks good, set it up.  Don't touch the irq_chain or
+	 * the pending flag.
+	 */
 	bucket->imap  = imap;
 	bucket->iclr  = iclr;
 	bucket->pil   = pil;
 	bucket->flags = 0;
 
-	bucket->irq_info = NULL;
-
+out:
 	return __irq(bucket);
 }
 
@@ -318,26 +307,65 @@ static void atomic_bucket_insert(struct 
 	__asm__ __volatile__("wrpr %0, 0x0, %%pstate" : : "r" (pstate));
 }
 
+static int check_irq_sharing(int pil, unsigned long irqflags)
+{
+	struct irqaction *action, *tmp;
+
+	action = *(irq_action + pil);
+	if (action) {
+		if ((action->flags & SA_SHIRQ) && (irqflags & SA_SHIRQ)) {
+			for (tmp = action; tmp->next; tmp = tmp->next)
+				;
+		} else {
+			return -EBUSY;
+		}
+	}
+	return 0;
+}
+
+static void append_irq_action(int pil, struct irqaction *action)
+{
+	struct irqaction **pp = irq_action + pil;
+
+	while (*pp)
+		pp = &((*pp)->next);
+	*pp = action;
+}
+
+static struct irqaction *get_action_slot(struct ino_bucket *bucket)
+{
+	struct irq_desc *desc = bucket->irq_info;
+	int max_irq, i;
+
+	max_irq = 1;
+	if (bucket->flags & IBF_PCI)
+		max_irq = MAX_IRQ_DESC_ACTION;
+	for (i = 0; i < max_irq; i++) {
+		struct irqaction *p = &desc->action[i];
+		u32 mask = (1 << i);
+
+		if (desc->action_active_mask & mask)
+			continue;
+
+		desc->action_active_mask |= mask;
+		return p;
+	}
+	return NULL;
+}
+
 int request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *),
 		unsigned long irqflags, const char *name, void *dev_id)
 {
-	struct irqaction *action, *tmp = NULL;
+	struct irqaction *action;
 	struct ino_bucket *bucket = __bucket(irq);
 	unsigned long flags;
 	int pending = 0;
 
-	if ((bucket != &pil0_dummy_bucket) &&
-	    (bucket < &ivector_table[0] ||
-	     bucket >= &ivector_table[NUM_IVECS])) {
-		unsigned int *caller;
-
-		__asm__ __volatile__("mov %%i7, %0" : "=r" (caller));
-		printk(KERN_CRIT "request_irq: Old style IRQ registry attempt "
-		       "from %p, irq %08x.\n", caller, irq);
+	if (unlikely(!handler))
 		return -EINVAL;
-	}	
-	if (!handler)
-	    return -EINVAL;
+
+	if (unlikely(!bucket->irq_info))
+		return -ENODEV;
 
 	if ((bucket != &pil0_dummy_bucket) && (irqflags & SA_SAMPLE_RANDOM)) {
 		/*
@@ -355,93 +383,20 @@ int request_irq(unsigned int irq, irqret
 
 	spin_lock_irqsave(&irq_action_lock, flags);
 
-	action = *(bucket->pil + irq_action);
-	if (action) {
-		if ((action->flags & SA_SHIRQ) && (irqflags & SA_SHIRQ))
-			for (tmp = action; tmp->next; tmp = tmp->next)
-				;
-		else {
-			spin_unlock_irqrestore(&irq_action_lock, flags);
-			return -EBUSY;
-		}
-		action = NULL;		/* Or else! */
+	if (check_irq_sharing(bucket->pil, irqflags)) {
+		spin_unlock_irqrestore(&irq_action_lock, flags);
+		return -EBUSY;
 	}
 
-	/* If this is flagged as statically allocated then we use our
-	 * private struct which is never freed.
-	 */
-	if (irqflags & SA_STATIC_ALLOC) {
-	    if (static_irq_count < MAX_STATIC_ALLOC)
-		action = &static_irqaction[static_irq_count++];
-	    else
-		printk("Request for IRQ%d (%s) SA_STATIC_ALLOC failed "
-		       "using kmalloc\n", irq, name);
-	}	
-	if (action == NULL)
-	    action = (struct irqaction *)kmalloc(sizeof(struct irqaction),
-						 GFP_ATOMIC);
-	
+	action = get_action_slot(bucket);
 	if (!action) { 
 		spin_unlock_irqrestore(&irq_action_lock, flags);
 		return -ENOMEM;
 	}
 
-	if (bucket == &pil0_dummy_bucket) {
-		bucket->irq_info = action;
-		bucket->flags |= IBF_ACTIVE;
-	} else {
-		if ((bucket->flags & IBF_ACTIVE) != 0) {
-			void *orig = bucket->irq_info;
-			void **vector = NULL;
-
-			if ((bucket->flags & IBF_PCI) == 0) {
-				printk("IRQ: Trying to share non-PCI bucket.\n");
-				goto free_and_ebusy;
-			}
-			if ((bucket->flags & IBF_MULTI) == 0) {
-				vector = kmalloc(sizeof(void *) * 4, GFP_ATOMIC);
-				if (vector == NULL)
-					goto free_and_enomem;
-
-				/* We might have slept. */
-				if ((bucket->flags & IBF_MULTI) != 0) {
-					int ent;
-
-					kfree(vector);
-					vector = (void **)bucket->irq_info;
-					for(ent = 0; ent < 4; ent++) {
-						if (vector[ent] == NULL) {
-							vector[ent] = action;
-							break;
-						}
-					}
-					if (ent == 4)
-						goto free_and_ebusy;
-				} else {
-					vector[0] = orig;
-					vector[1] = action;
-					vector[2] = NULL;
-					vector[3] = NULL;
-					bucket->irq_info = vector;
-					bucket->flags |= IBF_MULTI;
-				}
-			} else {
-				int ent;
-
-				vector = (void **)orig;
-				for (ent = 0; ent < 4; ent++) {
-					if (vector[ent] == NULL) {
-						vector[ent] = action;
-						break;
-					}
-				}
-				if (ent == 4)
-					goto free_and_ebusy;
-			}
-		} else {
-			bucket->irq_info = action;
-			bucket->flags |= IBF_ACTIVE;
-		}
+	bucket->flags |= IBF_ACTIVE;
+	pending = 0;
+	if (bucket != &pil0_dummy_bucket) {
 		pending = bucket->pending;
 		if (pending)
 			bucket->pending = 0;
@@ -455,10 +410,7 @@ int request_irq(unsigned int irq, irqret
 	put_ino_in_irqaction(action, irq);
 	put_smpaff_in_irqaction(action, CPU_MASK_NONE);
 
-	if (tmp)
-		tmp->next = action;
-	else
-		*(bucket->pil + irq_action) = action;
+	append_irq_action(bucket->pil, action);
 
 	enable_irq(irq);
 
@@ -467,147 +419,103 @@ int request_irq(unsigned int irq, irqret
 		atomic_bucket_insert(bucket);
 		set_softint(1 << bucket->pil);
 	}
+
 	spin_unlock_irqrestore(&irq_action_lock, flags);
-	if ((bucket != &pil0_dummy_bucket) && (!(irqflags & SA_STATIC_ALLOC)))
+
+	if (bucket != &pil0_dummy_bucket)
 		register_irq_proc(__irq_ino(irq));
 
 #ifdef CONFIG_SMP
 	distribute_irqs();
 #endif
 	return 0;
-
-free_and_ebusy:
-	kfree(action);
-	spin_unlock_irqrestore(&irq_action_lock, flags);
-	return -EBUSY;
-
-free_and_enomem:
-	kfree(action);
-	spin_unlock_irqrestore(&irq_action_lock, flags);
-	return -ENOMEM;
 }
 
 EXPORT_SYMBOL(request_irq);
 
-void free_irq(unsigned int irq, void *dev_id)
+static struct irqaction *unlink_irq_action(unsigned int irq, void *dev_id)
 {
-	struct irqaction *action;
-	struct irqaction *tmp = NULL;
-	unsigned long flags;
-	struct ino_bucket *bucket = __bucket(irq), *bp;
+	struct ino_bucket *bucket = __bucket(irq);
+	struct irqaction *action, **pp;
 
-	if ((bucket != &pil0_dummy_bucket) &&
-	    (bucket < &ivector_table[0] ||
-	     bucket >= &ivector_table[NUM_IVECS])) {
-		unsigned int *caller;
-
-		__asm__ __volatile__("mov %%i7, %0" : "=r" (caller));
-		printk(KERN_CRIT "free_irq: Old style IRQ removal attempt "
-		       "from %p, irq %08x.\n", caller, irq);
-		return;
-	}
-	
-	spin_lock_irqsave(&irq_action_lock, flags);
+	pp = irq_action + bucket->pil;
+	action = *pp;
+	if (unlikely(!action))
+		return NULL;
 
-	action = *(bucket->pil + irq_action);
-	if (!action->handler) {
+	if (unlikely(!action->handler)) {
 		printk("Freeing free IRQ %d\n", bucket->pil);
-		return;
-	}
-	if (dev_id) {
-		for ( ; action; action = action->next) {
-			if (action->dev_id == dev_id)
-				break;
-			tmp = action;
-		}
-		if (!action) {
-			printk("Trying to free free shared IRQ %d\n", bucket->pil);
-			spin_unlock_irqrestore(&irq_action_lock, flags);
-			return;
-		}
-	} else if (action->flags & SA_SHIRQ) {
-		printk("Trying to free shared IRQ %d with NULL device ID\n", bucket->pil);
-		spin_unlock_irqrestore(&irq_action_lock, flags);
-		return;
+		return NULL;
 	}
 
-	if (action->flags & SA_STATIC_ALLOC) {
-		printk("Attempt to free statically allocated IRQ %d (%s)\n",
-		       bucket->pil, action->name);
-		spin_unlock_irqrestore(&irq_action_lock, flags);
-		return;
+	while (action && action->dev_id != dev_id) {
+		pp = &action->next;
+		action = *pp;
 	}
 
-	if (action && tmp)
-		tmp->next = action->next;
-	else
-		*(bucket->pil + irq_action) = action->next;
+	if (likely(action))
+		*pp = action->next;
+
+	return action;
+}
+
+void free_irq(unsigned int irq, void *dev_id)
+{
+	struct irqaction *action;
+	struct ino_bucket *bucket;
+	unsigned long flags;
+
+	spin_lock_irqsave(&irq_action_lock, flags);
+
+	action = unlink_irq_action(irq, dev_id);
 
 	spin_unlock_irqrestore(&irq_action_lock, flags);
 
+	if (unlikely(!action))
+		return;
+
 	synchronize_irq(irq);
 
 	spin_lock_irqsave(&irq_action_lock, flags);
 
+	bucket = __bucket(irq);
 	if (bucket != &pil0_dummy_bucket) {
+		struct irq_desc *desc = bucket->irq_info;
 		unsigned long imap = bucket->imap;
-		void **vector, *orig;
-		int ent;
+		int ent, i;
 
-		orig = bucket->irq_info;
-		vector = (void **)orig;
+		for (i = 0; i < MAX_IRQ_DESC_ACTION; i++) {
+			struct irqaction *p = &desc->action[i];
 
-		if ((bucket->flags & IBF_MULTI) != 0) {
-			int other = 0;
-			void *orphan = NULL;
-			for (ent = 0; ent < 4; ent++) {
-				if (vector[ent] == action)
-					vector[ent] = NULL;
-				else if (vector[ent] != NULL) {
-					orphan = vector[ent];
-					other++;
-				}
+			if (p == action) {
+				desc->action_active_mask &= ~(1 << i);
+				break;
 			}
+		}
 
-			/* Only free when no other shared irq
-			 * uses this bucket.
+		if (!desc->action_active_mask) {
+			/* This unique interrupt source is now inactive. */
+			bucket->flags &= ~IBF_ACTIVE;
+
+			/* See if any other buckets share this bucket's IMAP
+			 * and are still active.
 			 */
-			if (other) {
-				if (other == 1) {
-					/* Convert back to non-shared bucket. */
-					bucket->irq_info = orphan;
-					bucket->flags &= ~(IBF_MULTI);
-					kfree(vector);
-				}
-				goto out;
+			for (ent = 0; ent < NUM_IVECS; ent++) {
+				struct ino_bucket *bp = &ivector_table[ent];
+				if (bp != bucket	&&
+				    bp->imap == imap	&&
+				    (bp->flags & IBF_ACTIVE) != 0)
+					break;
 			}
-		} else {
-			bucket->irq_info = NULL;
-		}
 
-		/* This unique interrupt source is now inactive. */
-		bucket->flags &= ~IBF_ACTIVE;
-
-		/* See if any other buckets share this bucket's IMAP
-		 * and are still active.
-		 */
-		for (ent = 0; ent < NUM_IVECS; ent++) {
-			bp = &ivector_table[ent];
-			if (bp != bucket	&&
-			    bp->imap == imap	&&
-			    (bp->flags & IBF_ACTIVE) != 0)
-				break;
+			/* Only disable when no other sub-irq levels of
+			 * the same IMAP are active.
+			 */
+			if (ent == NUM_IVECS)
+				disable_irq(irq);
 		}
-
-		/* Only disable when no other sub-irq levels of
-		 * the same IMAP are active.
-		 */
-		if (ent == NUM_IVECS)
-			disable_irq(irq);
 	}
 
-out:
-	kfree(action);
 	spin_unlock_irqrestore(&irq_action_lock, flags);
 }
 
@@ -646,99 +554,55 @@ void synchronize_irq(unsigned int irq)
 }
 #endif /* CONFIG_SMP */
 
-void catch_disabled_ivec(struct pt_regs *regs)
+static void process_bucket(int irq, struct ino_bucket *bp, struct pt_regs *regs)
 {
-	int cpu = smp_processor_id();
-	struct ino_bucket *bucket = __bucket(*irq_work(cpu, 0));
-
-	/* We can actually see this on Ultra/PCI PCI cards, which are bridges
-	 * to other devices.  Here a single IMAP enabled potentially multiple
-	 * unique interrupt sources (which each do have a unique ICLR register.
-	 *
-	 * So what we do is just register that the IVEC arrived, when registered
-	 * for real the request_irq() code will check the bit and signal
-	 * a local CPU interrupt for it.
-	 */
-#if 0
-	printk("IVEC: Spurious interrupt vector (%x) received at (%016lx)\n",
-	       bucket - &ivector_table[0], regs->tpc);
-#endif
-	*irq_work(cpu, 0) = 0;
-	bucket->pending = 1;
-}
-
-/* Tune this... */
-#define FORWARD_VOLUME		12
-
-#ifdef CONFIG_SMP
+	struct irq_desc *desc = bp->irq_info;
+	unsigned char flags = bp->flags;
+	u32 action_mask, i;
+	int random;
 
-static inline void redirect_intr(int cpu, struct ino_bucket *bp)
-{
-	/* Ok, here is what is going on:
-	 * 1) Retargeting IRQs on Starfire is very
-	 *    expensive so just forget about it on them.
-	 * 2) Moving around very high priority interrupts
-	 *    is a losing game.
-	 * 3) If the current cpu is idle, interrupts are
-	 *    useful work, so keep them here.  But do not
-	 *    pass to our neighbour if he is not very idle.
-	 * 4) If sysadmin explicitly asks for directed intrs,
-	 *    Just Do It.
-	 */
-	struct irqaction *ap = bp->irq_info;
-	cpumask_t cpu_mask;
-	unsigned int buddy, ticks;
-
-	cpu_mask = get_smpaff_in_irqaction(ap);
-	cpus_and(cpu_mask, cpu_mask, cpu_online_map);
-	if (cpus_empty(cpu_mask))
-		cpu_mask = cpu_online_map;
+	bp->flags |= IBF_INPROGRESS;
 
-	if (this_is_starfire != 0 ||
-	    bp->pil >= 10 || current->pid == 0)
+	if (unlikely(!(flags & IBF_ACTIVE))) {
+		bp->pending = 1;
 		goto out;
-
-	/* 'cpu' is the MID (ie. UPAID), calculate the MID
-	 * of our buddy.
-	 */
-	buddy = cpu + 1;
-	if (buddy >= NR_CPUS)
-		buddy = 0;
-
-	ticks = 0;
-	while (!cpu_isset(buddy, cpu_mask)) {
-		if (++buddy >= NR_CPUS)
-			buddy = 0;
-		if (++ticks > NR_CPUS) {
-			put_smpaff_in_irqaction(ap, CPU_MASK_NONE);
-			goto out;
-		}
 	}
 
-	if (buddy == cpu)
-		goto out;
+	if (desc->pre_handler)
+		desc->pre_handler(bp,
+				  desc->pre_handler_arg1,
+				  desc->pre_handler_arg2);
+
+	action_mask = desc->action_active_mask;
+	random = 0;
+	for (i = 0; i < MAX_IRQ_DESC_ACTION; i++) {
+		struct irqaction *p = &desc->action[i];
+		u32 mask = (1 << i);
 
-	/* Voo-doo programming. */
-	if (cpu_data(buddy).idle_volume < FORWARD_VOLUME)
-		goto out;
+		if (!(action_mask & mask))
+			continue;
 
-	/* This just so happens to be correct on Cheetah
-	 * at the moment.
-	 */
-	buddy <<= 26;
+		action_mask &= ~mask;
 
-	/* Push it to our buddy. */
-	upa_writel(buddy | IMAP_VALID, bp->imap);
+		if (p->handler(__irq(bp), p->dev_id, regs) == IRQ_HANDLED)
+			random |= p->flags;
 
+		if (!action_mask)
+			break;
+	}
+	if (bp->pil != 0) {
+		upa_writel(ICLR_IDLE, bp->iclr);
+		/* Test and add entropy */
+		if (random & SA_SAMPLE_RANDOM)
+			add_interrupt_randomness(irq);
+	}
 out:
-	return;
+	bp->flags &= ~IBF_INPROGRESS;
 }
 
-#endif
-
 void handler_irq(int irq, struct pt_regs *regs)
 {
-	struct ino_bucket *bp, *nbp;
+	struct ino_bucket *bp;
 	int cpu = smp_processor_id();
 
 #ifndef CONFIG_SMP
@@ -756,8 +620,6 @@ void handler_irq(int irq, struct pt_regs
 		clear_softint(clr_mask);
 	}
 #else
-	int should_forward = 0;
-
 	clear_softint(1 << irq);
 #endif
 
@@ -772,199 +634,76 @@ void handler_irq(int irq, struct pt_regs
 #else
 	bp = __bucket(xchg32(irq_work(cpu, irq), 0));
 #endif
-	for ( ; bp != NULL; bp = nbp) {
-		unsigned char flags = bp->flags;
-		unsigned char random = 0;
+	while (bp) {
+		struct ino_bucket *nbp = __bucket(bp->irq_chain);
 
-		nbp = __bucket(bp->irq_chain);
 		bp->irq_chain = 0;
-
-		bp->flags |= IBF_INPROGRESS;
-
-		if ((flags & IBF_ACTIVE) != 0) {
-#ifdef CONFIG_PCI
-			if ((flags & IBF_DMA_SYNC) != 0) {
-				upa_readl(dma_sync_reg_table[bp->synctab_ent]);
-				upa_readq(pci_dma_wsync);
-			}
-#endif
-			if ((flags & IBF_MULTI) == 0) {
-				struct irqaction *ap = bp->irq_info;
-				int ret;
-
-				ret = ap->handler(__irq(bp), ap->dev_id, regs);
-				if (ret == IRQ_HANDLED)
-					random |= ap->flags;
-			} else {
-				void **vector = (void **)bp->irq_info;
-				int ent;
-				for (ent = 0; ent < 4; ent++) {
-					struct irqaction *ap = vector[ent];
-					if (ap != NULL) {
-						int ret;
-
-						ret = ap->handler(__irq(bp),
-								  ap->dev_id,
-								  regs);
-						if (ret == IRQ_HANDLED)
-							random |= ap->flags;
-					}
-				}
-			}
-			/* Only the dummy bucket lacks IMAP/ICLR. */
-			if (bp->pil != 0) {
-#ifdef CONFIG_SMP
-				if (should_forward) {
-					redirect_intr(cpu, bp);
-					should_forward = 0;
-				}
-#endif
-				upa_writel(ICLR_IDLE, bp->iclr);
-
-				/* Test and add entropy */
-				if (random & SA_SAMPLE_RANDOM)
-					add_interrupt_randomness(irq);
-			}
-		} else
-			bp->pending = 1;
-
-		bp->flags &= ~IBF_INPROGRESS;
+		process_bucket(irq, bp, regs);
+		bp = nbp;
 	}
 	irq_exit();
 }
 
 #ifdef CONFIG_BLK_DEV_FD
-extern void floppy_interrupt(int irq, void *dev_cookie, struct pt_regs *regs);
-
-void sparc_floppy_irq(int irq, void *dev_cookie, struct pt_regs *regs)
-{
-	struct irqaction *action = *(irq + irq_action);
-	struct ino_bucket *bucket;
-	int cpu = smp_processor_id();
-
-	irq_enter();
-	kstat_this_cpu.irqs[irq]++;
-
-	*(irq_work(cpu, irq)) = 0;
-	bucket = get_ino_in_irqaction(action) + ivector_table;
-
-	bucket->flags |= IBF_INPROGRESS;
-
-	floppy_interrupt(irq, dev_cookie, regs);
-	upa_writel(ICLR_IDLE, bucket->iclr);
-
-	bucket->flags &= ~IBF_INPROGRESS;
-
-	irq_exit();
-}
-#endif
-
-/* The following assumes that the branch lies before the place we
- * are branching to.  This is the case for a trap vector...
- * You have been warned.
- */
-#define SPARC_BRANCH(dest_addr, inst_addr) \
-          (0x10800000 | ((((dest_addr)-(inst_addr))>>2)&0x3fffff))
-
-#define SPARC_NOP (0x01000000)
-
-static void install_fast_irq(unsigned int cpu_irq,
-			     irqreturn_t (*handler)(int, void *, struct pt_regs *))
-{
-	extern unsigned long sparc64_ttable_tl0;
-	unsigned long ttent = (unsigned long) &sparc64_ttable_tl0;
-	unsigned int *insns;
-
-	ttent += 0x820;
-	ttent += (cpu_irq - 1) << 5;
-	insns = (unsigned int *) ttent;
-	insns[0] = SPARC_BRANCH(((unsigned long) handler),
-				((unsigned long)&insns[0]));
-	insns[1] = SPARC_NOP;
-	__asm__ __volatile__("membar #StoreStore; flush %0" : : "r" (ttent));
-}
-
-int request_fast_irq(unsigned int irq,
-		     irqreturn_t (*handler)(int, void *, struct pt_regs *),
-		     unsigned long irqflags, const char *name, void *dev_id)
-{
-	struct irqaction *action;
-	struct ino_bucket *bucket = __bucket(irq);
-	unsigned long flags;
+extern irqreturn_t floppy_interrupt(int, void *, struct pt_regs *);;
 
-	/* No pil0 dummy buckets allowed here. */
-	if (bucket < &ivector_table[0] ||
-	    bucket >= &ivector_table[NUM_IVECS]) {
-		unsigned int *caller;
-
-		__asm__ __volatile__("mov %%i7, %0" : "=r" (caller));
-		printk(KERN_CRIT "request_fast_irq: Old style IRQ registry attempt "
-		       "from %p, irq %08x.\n", caller, irq);
-		return -EINVAL;
-	}	
-	
-	if (!handler)
-		return -EINVAL;
+/* XXX No easy way to include asm/floppy.h XXX */
+extern unsigned char *pdma_vaddr;
+extern unsigned long pdma_size;
+extern volatile int doing_pdma;
+extern unsigned long fdc_status;
+
+irqreturn_t sparc_floppy_irq(int irq, void *dev_cookie, struct pt_regs *regs)
+{
+	if (likely(doing_pdma)) {
+		void __iomem *stat = (void __iomem *) fdc_status;
+		unsigned char *vaddr = pdma_vaddr;
+		unsigned long size = pdma_size;
+		u8 val;
+
+		while (size) {
+			val = readb(stat);
+			if (unlikely(!(val & 0x80))) {
+				pdma_vaddr = vaddr;
+				pdma_size = size;
+				return IRQ_HANDLED;
+			}
+			if (unlikely(!(val & 0x20))) {
+				pdma_vaddr = vaddr;
+				pdma_size = size;
+				doing_pdma = 0;
+				goto main_interrupt;
+			}
+			if (val & 0x40) {
+				/* read */
+				*vaddr++ = readb(stat + 1);
+			} else {
+				unsigned char data = *vaddr++;
 
-	if ((bucket->pil == 0) || (bucket->pil == 14)) {
-		printk("request_fast_irq: Trying to register shared IRQ 0 or 14.\n");
-		return -EBUSY;
-	}
+				/* write */
+				writeb(data, stat + 1);
+			}
+			size--;
+		}
 
-	spin_lock_irqsave(&irq_action_lock, flags);
+		pdma_vaddr = vaddr;
+		pdma_size = size;
 
-	action = *(bucket->pil + irq_action);
-	if (action) {
-		if (action->flags & SA_SHIRQ)
-			panic("Trying to register fast irq when already shared.\n");
-		if (irqflags & SA_SHIRQ)
-			panic("Trying to register fast irq as shared.\n");
-		printk("request_fast_irq: Trying to register yet already owned.\n");
-		spin_unlock_irqrestore(&irq_action_lock, flags);
-		return -EBUSY;
-	}
+		/* Send Terminal Count pulse to floppy controller. */
+		val = readb(auxio_register);
+		val |= AUXIO_AUX1_FTCNT;
+		writeb(val, auxio_register);
+		val &= AUXIO_AUX1_FTCNT;
+		writeb(val, auxio_register);
 
-	/*
-	 * We do not check for SA_SAMPLE_RANDOM in this path. Neither do we
-	 * support smp intr affinity in this path.
-	 */
-	if (irqflags & SA_STATIC_ALLOC) {
-		if (static_irq_count < MAX_STATIC_ALLOC)
-			action = &static_irqaction[static_irq_count++];
-		else
-			printk("Request for IRQ%d (%s) SA_STATIC_ALLOC failed "
-			       "using kmalloc\n", bucket->pil, name);
-	}
-	if (action == NULL)
-		action = (struct irqaction *)kmalloc(sizeof(struct irqaction),
-						     GFP_ATOMIC);
-	if (!action) {
-		spin_unlock_irqrestore(&irq_action_lock, flags);
-		return -ENOMEM;
+		doing_pdma = 0;
 	}
-	install_fast_irq(bucket->pil, handler);
 
-	bucket->irq_info = action;
-	bucket->flags |= IBF_ACTIVE;
-
-	action->handler = handler;
-	action->flags = irqflags;
-	action->dev_id = NULL;
-	action->name = name;
-	action->next = NULL;
-	put_ino_in_irqaction(action, irq);
-	put_smpaff_in_irqaction(action, CPU_MASK_NONE);
-
-	*(bucket->pil + irq_action) = action;
-	enable_irq(irq);
-
-	spin_unlock_irqrestore(&irq_action_lock, flags);
-
-#ifdef CONFIG_SMP
-	distribute_irqs();
-#endif
-	return 0;
+main_interrupt:
+	return floppy_interrupt(irq, dev_cookie, regs);
 }
+EXPORT_SYMBOL(sparc_floppy_irq);
+#endif
 
 /* We really don't need these at all on the Sparc.  We only have
  * stubs here because they are exported to modules.
@@ -1030,7 +769,10 @@ static void distribute_irqs(void)
 	 */
 	for (level = 1; level < NR_IRQS; level++) {
 		struct irqaction *p = irq_action[level];
-		if (level == 12) continue;
+
+		if (level == 12)
+			continue;
+
 		while(p) {
 			cpu = retarget_one_irq(p, cpu);
 			p = p->next;
@@ -1040,8 +782,14 @@ static void distribute_irqs(void)
 }
 #endif
 
+struct sun5_timer {
+	u64	count0;
+	u64	limit0;
+	u64	count1;
+	u64	limit1;
+};
 
-struct sun5_timer *prom_timers;
+static struct sun5_timer *prom_timers;
 static u64 prom_limit0, prom_limit1;
 
 static void map_prom_timers(void)
@@ -1097,18 +845,6 @@ static void kill_prom_timer(void)
 	: "g1", "g2");
 }
 
-void enable_prom_timer(void)
-{
-	if (!prom_timers)
-		return;
-
-	/* Set it to whatever was there before. */
-	prom_timers->limit1 = prom_limit1;
-	prom_timers->count1 = 0;
-	prom_timers->limit0 = prom_limit0;
-	prom_timers->count0 = 0;
-}
-
 void init_irqwork_curcpu(void)
 {
 	register struct irq_work_struct *workp asm("o2");
@@ -1175,7 +911,8 @@ static int irq_affinity_read_proc (char 
 			int count, int *eof, void *data)
 {
 	struct ino_bucket *bp = ivector_table + (long)data;
-	struct irqaction *ap = bp->irq_info;
+	struct irq_desc *desc = bp->irq_info;
+	struct irqaction *ap = desc->action;
 	cpumask_t mask;
 	int len;
 
@@ -1193,11 +930,13 @@ static int irq_affinity_read_proc (char 
 static inline void set_intr_affinity(int irq, cpumask_t hw_aff)
 {
 	struct ino_bucket *bp = ivector_table + irq;
+	struct irq_desc *desc = bp->irq_info;
+	struct irqaction *ap = desc->action;
 
 	/* Users specify affinity in terms of hw cpu ids.
 	 * As soon as we do this, handler_irq() might see and take action.
 	 */
-	put_smpaff_in_irqaction((struct irqaction *)bp->irq_info, hw_aff);
+	put_smpaff_in_irqaction(ap, hw_aff);
 
 	/* Migration is simply done by the next cpu to service this
 	 * interrupt.
diff --git a/arch/sparc64/kernel/kprobes.c b/arch/sparc64/kernel/kprobes.c
--- a/arch/sparc64/kernel/kprobes.c
+++ b/arch/sparc64/kernel/kprobes.c
@@ -6,7 +6,6 @@
 #include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/kprobes.h>
-
 #include <asm/kdebug.h>
 #include <asm/signal.h>
 
@@ -47,25 +46,59 @@ void arch_copy_kprobe(struct kprobe *p)
 {
 	p->ainsn.insn[0] = *p->addr;
 	p->ainsn.insn[1] = BREAKPOINT_INSTRUCTION_2;
+	p->opcode = *p->addr;
 }
 
-void arch_remove_kprobe(struct kprobe *p)
+void arch_arm_kprobe(struct kprobe *p)
+{
+	*p->addr = BREAKPOINT_INSTRUCTION;
+	flushi(p->addr);
+}
+
+void arch_disarm_kprobe(struct kprobe *p)
 {
+	*p->addr = p->opcode;
+	flushi(p->addr);
 }
 
-/* kprobe_status settings */
-#define KPROBE_HIT_ACTIVE	0x00000001
-#define KPROBE_HIT_SS		0x00000002
+void arch_remove_kprobe(struct kprobe *p)
+{
+}
 
 static struct kprobe *current_kprobe;
 static unsigned long current_kprobe_orig_tnpc;
 static unsigned long current_kprobe_orig_tstate_pil;
 static unsigned int kprobe_status;
+static struct kprobe *kprobe_prev;
+static unsigned long kprobe_orig_tnpc_prev;
+static unsigned long kprobe_orig_tstate_pil_prev;
+static unsigned int kprobe_status_prev;
 
-static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
+static inline void save_previous_kprobe(void)
+{
+	kprobe_status_prev = kprobe_status;
+	kprobe_orig_tnpc_prev = current_kprobe_orig_tnpc;
+	kprobe_orig_tstate_pil_prev = current_kprobe_orig_tstate_pil;
+	kprobe_prev = current_kprobe;
+}
+
+static inline void restore_previous_kprobe(void)
+{
+	kprobe_status = kprobe_status_prev;
+	current_kprobe_orig_tnpc = kprobe_orig_tnpc_prev;
+	current_kprobe_orig_tstate_pil = kprobe_orig_tstate_pil_prev;
+	current_kprobe = kprobe_prev;
+}
+
+static inline void set_current_kprobe(struct kprobe *p, struct pt_regs *regs)
 {
 	current_kprobe_orig_tnpc = regs->tnpc;
 	current_kprobe_orig_tstate_pil = (regs->tstate & TSTATE_PIL);
+	current_kprobe = p;
+}
+
+static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
+{
 	regs->tstate |= TSTATE_PIL;
 
 	/*single step inline, if it a breakpoint instruction*/
@@ -78,17 +111,6 @@ static inline void prepare_singlestep(st
 	}
 }
 
-static inline void disarm_kprobe(struct kprobe *p, struct pt_regs *regs)
-{
-	*p->addr = p->opcode;
-	flushi(p->addr);
-
-	regs->tpc = (unsigned long) p->addr;
-	regs->tnpc = current_kprobe_orig_tnpc;
-	regs->tstate = ((regs->tstate & ~TSTATE_PIL) |
-			current_kprobe_orig_tstate_pil);
-}
-
 static int kprobe_handler(struct pt_regs *regs)
 {
 	struct kprobe *p;
@@ -109,8 +131,18 @@ static int kprobe_handler(struct pt_regs
 				unlock_kprobes();
 				goto no_kprobe;
 			}
-			disarm_kprobe(p, regs);
-			ret = 1;
+			/* We have reentered the kprobe_handler(), since
+			 * another probe was hit while within the handler.
+			 * We here save the original kprobes variables and
+			 * just single step on the instruction of the new probe
+			 * without calling any user handlers.
+			 */
+			save_previous_kprobe();
+			set_current_kprobe(p, regs);
+			p->nmissed++;
+			kprobe_status = KPROBE_REENTER;
+			prepare_singlestep(p, regs);
+			return 1;
 		} else {
 			p = current_kprobe;
 			if (p->break_handler && p->break_handler(p, regs))
@@ -138,8 +170,8 @@ static int kprobe_handler(struct pt_regs
 		goto no_kprobe;
 	}
 
+	set_current_kprobe(p, regs);
 	kprobe_status = KPROBE_HIT_ACTIVE;
-	current_kprobe = p;
 	if (p->pre_handler && p->pre_handler(p, regs))
 		return 1;
 
@@ -245,12 +277,20 @@ static inline int post_kprobe_handler(st
 	if (!kprobe_running())
 		return 0;
 
-	if (current_kprobe->post_handler)
+	if ((kprobe_status != KPROBE_REENTER) && current_kprobe->post_handler) {
+		kprobe_status = KPROBE_HIT_SSDONE;
 		current_kprobe->post_handler(current_kprobe, regs, 0);
+	}
 
 	resume_execution(current_kprobe, regs);
 
+	/*Restore back the original saved kprobes variables and continue. */
+	if (kprobe_status == KPROBE_REENTER) {
+		restore_previous_kprobe();
+		goto out;
+	}
 	unlock_kprobes();
+out:
 	preempt_enable_no_resched();
 
 	return 1;
@@ -392,3 +432,9 @@ int longjmp_break_handler(struct kprobe 
 	}
 	return 0;
 }
+
+/* architecture specific initialization */
+int arch_init_kprobes(void)
+{
+	return 0;
+}
diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c
--- a/arch/sparc64/kernel/pci.c
+++ b/arch/sparc64/kernel/pci.c
@@ -540,6 +540,7 @@ void pcibios_bus_to_resource(struct pci_
 
 	pbm->parent->resource_adjust(pdev, res, root);
 }
+EXPORT_SYMBOL(pcibios_bus_to_resource);
 
 char * __init pcibios_setup(char *str)
 {
diff --git a/arch/sparc64/kernel/pci_psycho.c b/arch/sparc64/kernel/pci_psycho.c
--- a/arch/sparc64/kernel/pci_psycho.c
+++ b/arch/sparc64/kernel/pci_psycho.c
@@ -1303,8 +1303,7 @@ static void psycho_controller_hwinit(str
 {
 	u64 tmp;
 
-	/* PROM sets the IRQ retry value too low, increase it. */
-	psycho_write(p->pbm_A.controller_regs + PSYCHO_IRQ_RETRY, 0xff);
+	psycho_write(p->pbm_A.controller_regs + PSYCHO_IRQ_RETRY, 5);
 
 	/* Enable arbiter for all PCI slots. */
 	tmp = psycho_read(p->pbm_A.controller_regs + PSYCHO_PCIA_CTRL);
diff --git a/arch/sparc64/kernel/pci_sabre.c b/arch/sparc64/kernel/pci_sabre.c
--- a/arch/sparc64/kernel/pci_sabre.c
+++ b/arch/sparc64/kernel/pci_sabre.c
@@ -595,6 +595,23 @@ static int __init sabre_ino_to_pil(struc
 	return ret;
 }
 
+/* When a device lives behind a bridge deeper in the PCI bus topology
+ * than APB, a special sequence must run to make sure all pending DMA
+ * transfers at the time of IRQ delivery are visible in the coherency
+ * domain by the cpu.  This sequence is to perform a read on the far
+ * side of the non-APB bridge, then perform a read of Sabre's DMA
+ * write-sync register.
+ */
+static void sabre_wsync_handler(struct ino_bucket *bucket, void *_arg1, void *_arg2)
+{
+	struct pci_dev *pdev = _arg1;
+	unsigned long sync_reg = (unsigned long) _arg2;
+	u16 _unused;
+
+	pci_read_config_word(pdev, PCI_VENDOR_ID, &_unused);
+	sabre_read(sync_reg);
+}
+
 static unsigned int __init sabre_irq_build(struct pci_pbm_info *pbm,
 					   struct pci_dev *pdev,
 					   unsigned int ino)
@@ -639,24 +656,14 @@ static unsigned int __init sabre_irq_bui
 	if (pdev) {
 		struct pcidev_cookie *pcp = pdev->sysdata;
 
-		/* When a device lives behind a bridge deeper in the
-		 * PCI bus topology than APB, a special sequence must
-		 * run to make sure all pending DMA transfers at the
-		 * time of IRQ delivery are visible in the coherency
-		 * domain by the cpu.  This sequence is to perform
-		 * a read on the far side of the non-APB bridge, then
-		 * perform a read of Sabre's DMA write-sync register.
-		 *
-		 * Currently, the PCI_CONFIG register for the device
-		 * is used for this read from the far side of the bridge.
-		 */
 		if (pdev->bus->number != pcp->pbm->pci_first_busno) {
-			bucket->flags |= IBF_DMA_SYNC;
-			bucket->synctab_ent = dma_sync_reg_table_entry++;
-			dma_sync_reg_table[bucket->synctab_ent] =
-				(unsigned long) sabre_pci_config_mkaddr(
-					pcp->pbm,
-					pdev->bus->number, pdev->devfn, PCI_COMMAND);
+			struct pci_controller_info *p = pcp->pbm->parent;
+			struct irq_desc *d = bucket->irq_info;
+
+			d->pre_handler = sabre_wsync_handler;
+			d->pre_handler_arg1 = pdev;
+			d->pre_handler_arg2 = (void *)
+				p->pbm_A.controller_regs + SABRE_WRSYNC;
 		}
 	}
 	return __irq(bucket);
@@ -1626,10 +1633,9 @@ void __init sabre_init(int pnode, char *
 	 */
 	p->pbm_A.controller_regs = pr_regs[0].phys_addr;
 	p->pbm_B.controller_regs = pr_regs[0].phys_addr;
-	pci_dma_wsync = p->pbm_A.controller_regs + SABRE_WRSYNC;
 
-	printk("PCI: Found SABRE, main regs at %016lx, wsync at %016lx\n",
-	       p->pbm_A.controller_regs, pci_dma_wsync);
+	printk("PCI: Found SABRE, main regs at %016lx\n",
+	       p->pbm_A.controller_regs);
 
 	/* Clear interrupts */
 
diff --git a/arch/sparc64/kernel/pci_schizo.c b/arch/sparc64/kernel/pci_schizo.c
--- a/arch/sparc64/kernel/pci_schizo.c
+++ b/arch/sparc64/kernel/pci_schizo.c
@@ -15,6 +15,7 @@
 #include <asm/iommu.h>
 #include <asm/irq.h>
 #include <asm/upa.h>
+#include <asm/pstate.h>
 
 #include "pci_impl.h"
 #include "iommu_common.h"
@@ -326,6 +327,44 @@ static int __init schizo_ino_to_pil(stru
 	return ret;
 }
 
+static void tomatillo_wsync_handler(struct ino_bucket *bucket, void *_arg1, void *_arg2)
+{
+	unsigned long sync_reg = (unsigned long) _arg2;
+	u64 mask = 1 << (__irq_ino(__irq(bucket)) & IMAP_INO);
+	u64 val;
+	int limit;
+
+	schizo_write(sync_reg, mask);
+
+	limit = 100000;
+	val = 0;
+	while (--limit) {
+		val = schizo_read(sync_reg);
+		if (!(val & mask))
+			break;
+	}
+	if (limit <= 0) {
+		printk("tomatillo_wsync_handler: DMA won't sync [%lx:%lx]\n",
+		       val, mask);
+	}
+
+	if (_arg1) {
+		static unsigned char cacheline[64]
+			__attribute__ ((aligned (64)));
+
+		__asm__ __volatile__("rd %%fprs, %0\n\t"
+				     "or %0, %4, %1\n\t"
+				     "wr %1, 0x0, %%fprs\n\t"
+				     "stda %%f0, [%5] %6\n\t"
+				     "wr %0, 0x0, %%fprs\n\t"
+				     "membar #Sync"
+				     : "=&r" (mask), "=&r" (val)
+				     : "0" (mask), "1" (val),
+				     "i" (FPRS_FEF), "r" (&cacheline[0]),
+				     "i" (ASI_BLK_COMMIT_P));
+	}
+}
+
 static unsigned int schizo_irq_build(struct pci_pbm_info *pbm,
 				     struct pci_dev *pdev,
 				     unsigned int ino)
@@ -369,6 +408,15 @@ static unsigned int schizo_irq_build(str
 	bucket = __bucket(build_irq(pil, ign_fixup, iclr, imap));
 	bucket->flags |= IBF_PCI;
 
+	if (pdev && pbm->chip_type == PBM_CHIP_TYPE_TOMATILLO) {
+		struct irq_desc *p = bucket->irq_info;
+
+		p->pre_handler = tomatillo_wsync_handler;
+		p->pre_handler_arg1 = ((pbm->chip_version <= 4) ?
+				       (void *) 1 : (void *) 0);
+		p->pre_handler_arg2 = (void *) pbm->sync_reg;
+	}
+
 	return __irq(bucket);
 }
 
@@ -885,6 +933,7 @@ static irqreturn_t schizo_ce_intr(int ir
 
 #define SCHIZO_PCI_CTRL		(0x2000UL)
 #define SCHIZO_PCICTRL_BUS_UNUS	(1UL << 63UL) /* Safari */
+#define SCHIZO_PCICTRL_DTO_INT	(1UL << 61UL) /* Tomatillo */
 #define SCHIZO_PCICTRL_ARB_PRIO (0x1ff << 52UL) /* Tomatillo */
 #define SCHIZO_PCICTRL_ESLCK	(1UL << 51UL) /* Safari */
 #define SCHIZO_PCICTRL_ERRSLOT	(7UL << 48UL) /* Safari */
@@ -1887,37 +1936,27 @@ static void __init schizo_pbm_hw_init(st
 {
 	u64 tmp;
 
-	/* Set IRQ retry to infinity. */
-	schizo_write(pbm->pbm_regs + SCHIZO_PCI_IRQ_RETRY,
-		     SCHIZO_IRQ_RETRY_INF);
-
-	/* Enable arbiter for all PCI slots.  Also, disable PCI interval
-	 * timer so that DTO (Discard TimeOuts) are not reported because
-	 * some Schizo revisions report them erroneously.
-	 */
+	schizo_write(pbm->pbm_regs + SCHIZO_PCI_IRQ_RETRY, 5);
+
 	tmp = schizo_read(pbm->pbm_regs + SCHIZO_PCI_CTRL);
-	if (pbm->chip_type == PBM_CHIP_TYPE_SCHIZO_PLUS &&
-	    pbm->chip_version == 0x5 &&
-	    pbm->chip_revision == 0x1)
-		tmp |= 0x0f;
-	else
-		tmp |= 0xff;
 
-	tmp &= ~SCHIZO_PCICTRL_PTO;
+	/* Enable arbiter for all PCI slots.  */
+	tmp |= 0xff;
+
 	if (pbm->chip_type == PBM_CHIP_TYPE_TOMATILLO &&
 	    pbm->chip_version >= 0x2)
 		tmp |= 0x3UL << SCHIZO_PCICTRL_PTO_SHIFT;
-	else
-		tmp |= 0x1UL << SCHIZO_PCICTRL_PTO_SHIFT;
 
 	if (!prom_getbool(pbm->prom_node, "no-bus-parking"))
 		tmp |= SCHIZO_PCICTRL_PARK;
+	else
+		tmp &= ~SCHIZO_PCICTRL_PARK;
 
 	if (pbm->chip_type == PBM_CHIP_TYPE_TOMATILLO &&
 	    pbm->chip_version <= 0x1)
-		tmp |= (1UL << 61);
+		tmp |= SCHIZO_PCICTRL_DTO_INT;
 	else
-		tmp &= ~(1UL << 61);
+		tmp &= ~SCHIZO_PCICTRL_DTO_INT;
 
 	if (pbm->chip_type == PBM_CHIP_TYPE_TOMATILLO)
 		tmp |= (SCHIZO_PCICTRL_MRM_PREF |
@@ -2015,6 +2054,9 @@ static void __init schizo_pbm_init(struc
 	pbm->pbm_regs = pr_regs[0].phys_addr;
 	pbm->controller_regs = pr_regs[1].phys_addr - 0x10000UL;
 
+	if (chip_type == PBM_CHIP_TYPE_TOMATILLO)
+		pbm->sync_reg = pr_regs[3].phys_addr + 0x1a18UL;
+
 	sprintf(pbm->name,
 		(chip_type == PBM_CHIP_TYPE_TOMATILLO ?
 		 "TOMATILLO%d PBM%c" :
diff --git a/arch/sparc64/kernel/power.c b/arch/sparc64/kernel/power.c
--- a/arch/sparc64/kernel/power.c
+++ b/arch/sparc64/kernel/power.c
@@ -4,6 +4,8 @@
  * Copyright (C) 1999 David S. Miller (davem@redhat.com)
  */
 
+#define __KERNEL_SYSCALLS__
+
 #include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
@@ -17,7 +19,6 @@
 #include <asm/ebus.h>
 #include <asm/auxio.h>
 
-#define __KERNEL_SYSCALLS__
 #include <linux/unistd.h>
 
 /*
@@ -68,8 +69,6 @@ void machine_power_off(void)
 	machine_halt();
 }
 
-EXPORT_SYMBOL(machine_power_off);
-
 #ifdef CONFIG_PCI
 static int powerd(void *__unused)
 {
diff --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c
--- a/arch/sparc64/kernel/process.c
+++ b/arch/sparc64/kernel/process.c
@@ -124,8 +124,6 @@ void machine_halt(void)
 	panic("Halt failed!");
 }
 
-EXPORT_SYMBOL(machine_halt);
-
 void machine_alt_power_off(void)
 {
 	if (!serial_console && prom_palette)
@@ -154,8 +152,6 @@ void machine_restart(char * cmd)
 	panic("Reboot failed!");
 }
 
-EXPORT_SYMBOL(machine_restart);
-
 static void show_regwindow32(struct pt_regs *regs)
 {
 	struct reg_window32 __user *rw;
@@ -621,8 +617,8 @@ int copy_thread(int nr, unsigned long cl
 	memcpy(child_trap_frame, (((struct sparc_stackf *)regs)-1), (TRACEREG_SZ+STACKFRAME_SZ));
 
 	t->flags = (t->flags & ~((0xffUL << TI_FLAG_CWP_SHIFT) | (0xffUL << TI_FLAG_CURRENT_DS_SHIFT))) |
-		_TIF_NEWCHILD |
 		(((regs->tstate + 1) & TSTATE_CWP) << TI_FLAG_CWP_SHIFT);
+	t->new_child = 1;
 	t->ksp = ((unsigned long) child_trap_frame) - STACK_BIAS;
 	t->kregs = (struct pt_regs *)(child_trap_frame+sizeof(struct sparc_stackf));
 	t->fpsaved[0] = 0;
diff --git a/arch/sparc64/kernel/ptrace.c b/arch/sparc64/kernel/ptrace.c
--- a/arch/sparc64/kernel/ptrace.c
+++ b/arch/sparc64/kernel/ptrace.c
@@ -19,6 +19,8 @@
 #include <linux/smp.h>
 #include <linux/smp_lock.h>
 #include <linux/security.h>
+#include <linux/seccomp.h>
+#include <linux/audit.h>
 #include <linux/signal.h>
 
 #include <asm/asi.h>
@@ -628,15 +630,27 @@ out:
 	unlock_kernel();
 }
 
-asmlinkage void syscall_trace(void)
+asmlinkage void syscall_trace(struct pt_regs *regs, int syscall_exit_p)
 {
-#ifdef DEBUG_PTRACE
-	printk("%s [%d]: syscall_trace\n", current->comm, current->pid);
-#endif
-	if (!test_thread_flag(TIF_SYSCALL_TRACE))
-		return;
+	/* do the secure computing check first */
+	secure_computing(regs->u_regs[UREG_G1]);
+
+	if (unlikely(current->audit_context) && syscall_exit_p) {
+		unsigned long tstate = regs->tstate;
+		int result = AUDITSC_SUCCESS;
+
+		if (unlikely(tstate & (TSTATE_XCARRY | TSTATE_ICARRY)))
+			result = AUDITSC_FAILURE;
+
+		audit_syscall_exit(current, result, regs->u_regs[UREG_I0]);
+	}
+
 	if (!(current->ptrace & PT_PTRACED))
-		return;
+		goto out;
+
+	if (!test_thread_flag(TIF_SYSCALL_TRACE))
+		goto out;
+
 	ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
 				 ? 0x80 : 0));
 
@@ -645,12 +659,20 @@ asmlinkage void syscall_trace(void)
 	 * for normal use.  strace only continues with a signal if the
 	 * stopping signal is not SIGTRAP.  -brl
 	 */
-#ifdef DEBUG_PTRACE
-	printk("%s [%d]: syscall_trace exit= %x\n", current->comm,
-		current->pid, current->exit_code);
-#endif
 	if (current->exit_code) {
-		send_sig (current->exit_code, current, 1);
+		send_sig(current->exit_code, current, 1);
 		current->exit_code = 0;
 	}
+
+out:
+	if (unlikely(current->audit_context) && !syscall_exit_p)
+		audit_syscall_entry(current,
+				    (test_thread_flag(TIF_32BIT) ?
+				     AUDIT_ARCH_SPARC :
+				     AUDIT_ARCH_SPARC64),
+				    regs->u_regs[UREG_G1],
+				    regs->u_regs[UREG_I0],
+				    regs->u_regs[UREG_I1],
+				    regs->u_regs[UREG_I2],
+				    regs->u_regs[UREG_I3]);
 }
diff --git a/arch/sparc64/kernel/semaphore.c b/arch/sparc64/kernel/semaphore.c
--- a/arch/sparc64/kernel/semaphore.c
+++ b/arch/sparc64/kernel/semaphore.c
@@ -32,8 +32,9 @@ static __inline__ int __sem_update_count
 "	add	%1, %4, %1\n"
 "	cas	[%3], %0, %1\n"
 "	cmp	%0, %1\n"
+"	membar	#StoreLoad | #StoreStore\n"
 "	bne,pn	%%icc, 1b\n"
-"	 membar #StoreLoad | #StoreStore\n"
+"	 nop\n"
 	: "=&r" (old_count), "=&r" (tmp), "=m" (sem->count)
 	: "r" (&sem->count), "r" (incr), "m" (sem->count)
 	: "cc");
@@ -71,8 +72,9 @@ void up(struct semaphore *sem)
 "	cmp	%%g1, %%g7\n"
 "	bne,pn	%%icc, 1b\n"
 "	 addcc	%%g7, 1, %%g0\n"
+"	membar	#StoreLoad | #StoreStore\n"
 "	ble,pn	%%icc, 3f\n"
-"	 membar	#StoreLoad | #StoreStore\n"
+"	 nop\n"
 "2:\n"
 "	.subsection 2\n"
 "3:	mov	%0, %%g1\n"
@@ -128,8 +130,9 @@ void __sched down(struct semaphore *sem)
 "	cmp	%%g1, %%g7\n"
 "	bne,pn	%%icc, 1b\n"
 "	 cmp	%%g7, 1\n"
+"	membar	#StoreLoad | #StoreStore\n"
 "	bl,pn	%%icc, 3f\n"
-"	 membar	#StoreLoad | #StoreStore\n"
+"	 nop\n"
 "2:\n"
 "	.subsection 2\n"
 "3:	mov	%0, %%g1\n"
@@ -233,8 +236,9 @@ int __sched down_interruptible(struct se
 "	cmp	%%g1, %%g7\n"
 "	bne,pn	%%icc, 1b\n"
 "	 cmp	%%g7, 1\n"
+"	membar	#StoreLoad | #StoreStore\n"
 "	bl,pn	%%icc, 3f\n"
-"	 membar	#StoreLoad | #StoreStore\n"
+"	 nop\n"
 "2:\n"
 "	.subsection 2\n"
 "3:	mov	%2, %%g1\n"
diff --git a/arch/sparc64/kernel/signal32.c b/arch/sparc64/kernel/signal32.c
--- a/arch/sparc64/kernel/signal32.c
+++ b/arch/sparc64/kernel/signal32.c
@@ -102,7 +102,7 @@ typedef struct compat_siginfo{
 
 		/* POSIX.1b timers */
 		struct {
-			timer_t _tid;			/* timer id */
+			compat_timer_t _tid;			/* timer id */
 			int _overrun;			/* overrun count */
 			compat_sigval_t _sigval;		/* same as below */
 			int _sys_private;		/* not to be passed to user */
diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c
--- a/arch/sparc64/kernel/smp.c
+++ b/arch/sparc64/kernel/smp.c
@@ -45,8 +45,8 @@ extern void calibrate_delay(void);
 /* Please don't make this stuff initdata!!!  --DaveM */
 static unsigned char boot_cpu_id;
 
-cpumask_t cpu_online_map = CPU_MASK_NONE;
-cpumask_t phys_cpu_present_map = CPU_MASK_NONE;
+cpumask_t cpu_online_map __read_mostly = CPU_MASK_NONE;
+cpumask_t phys_cpu_present_map __read_mostly = CPU_MASK_NONE;
 static cpumask_t smp_commenced_mask;
 static cpumask_t cpu_callout_map;
 
@@ -137,7 +137,7 @@ void __init smp_callin(void)
 	/* Clear this or we will die instantly when we
 	 * schedule back to this idler...
 	 */
-	clear_thread_flag(TIF_NEWCHILD);
+	current_thread_info()->new_child = 0;
 
 	/* Attach to the address space of init_task. */
 	atomic_inc(&init_mm.mm_count);
@@ -155,7 +155,7 @@ void cpu_panic(void)
 	panic("SMP bolixed\n");
 }
 
-static unsigned long current_tick_offset;
+static unsigned long current_tick_offset __read_mostly;
 
 /* This tick register synchronization scheme is taken entirely from
  * the ia64 port, see arch/ia64/kernel/smpboot.c for details and credit.
@@ -1193,8 +1193,8 @@ void smp_send_stop(void)
 {
 }
 
-unsigned long __per_cpu_base;
-unsigned long __per_cpu_shift;
+unsigned long __per_cpu_base __read_mostly;
+unsigned long __per_cpu_shift __read_mostly;
 
 EXPORT_SYMBOL(__per_cpu_base);
 EXPORT_SYMBOL(__per_cpu_shift);
diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c
--- a/arch/sparc64/kernel/sparc64_ksyms.c
+++ b/arch/sparc64/kernel/sparc64_ksyms.c
@@ -79,7 +79,7 @@ extern void linux_sparc_syscall(void);
 extern void rtrap(void);
 extern void show_regs(struct pt_regs *);
 extern void solaris_syscall(void);
-extern void syscall_trace(void);
+extern void syscall_trace(struct pt_regs *, int);
 extern u32 sunos_sys_table[], sys_call_table32[];
 extern void tl0_solaris(void);
 extern void sys_sigsuspend(void);
@@ -227,7 +227,6 @@ EXPORT_SYMBOL(__flush_dcache_range);
 
 EXPORT_SYMBOL(mostek_lock);
 EXPORT_SYMBOL(mstk48t02_regs);
-EXPORT_SYMBOL(request_fast_irq);
 #ifdef CONFIG_SUN_AUXIO
 EXPORT_SYMBOL(auxio_set_led);
 EXPORT_SYMBOL(auxio_set_lte);
diff --git a/arch/sparc64/kernel/sys32.S b/arch/sparc64/kernel/sys32.S
--- a/arch/sparc64/kernel/sys32.S
+++ b/arch/sparc64/kernel/sys32.S
@@ -135,6 +135,8 @@ SIGN2(sys32_shutdown, sys_shutdown, %o0,
 SIGN3(sys32_socketpair, sys_socketpair, %o0, %o1, %o2)
 SIGN1(sys32_getpeername, sys_getpeername, %o0)
 SIGN1(sys32_getsockname, sys_getsockname, %o0)
+SIGN2(sys32_ioprio_get, sys_ioprio_get, %o0, %o1)
+SIGN3(sys32_ioprio_set, sys_ioprio_set, %o0, %o1, %o2)
 
 	.globl		sys32_mmap2
 sys32_mmap2:
diff --git a/arch/sparc64/kernel/sys_sparc.c b/arch/sparc64/kernel/sys_sparc.c
--- a/arch/sparc64/kernel/sys_sparc.c
+++ b/arch/sparc64/kernel/sys_sparc.c
@@ -84,6 +84,10 @@ unsigned long arch_get_unmapped_area(str
 			return addr;
 	}
 
+	if (len <= mm->cached_hole_size) {
+	        mm->cached_hole_size = 0;
+		mm->free_area_cache = TASK_UNMAPPED_BASE;
+	}
 	start_addr = addr = mm->free_area_cache;
 
 	task_size -= len;
@@ -103,6 +107,7 @@ full_search:
 		if (task_size < addr) {
 			if (start_addr != TASK_UNMAPPED_BASE) {
 				start_addr = addr = TASK_UNMAPPED_BASE;
+				mm->cached_hole_size = 0;
 				goto full_search;
 			}
 			return -ENOMEM;
@@ -114,6 +119,9 @@ full_search:
 			mm->free_area_cache = addr + len;
 			return addr;
 		}
+		if (addr + mm->cached_hole_size < vma->vm_start)
+		        mm->cached_hole_size = vma->vm_start - addr;
+
 		addr = vma->vm_end;
 		if (do_color_align)
 			addr = COLOUR_ALIGN(addr, pgoff);
diff --git a/arch/sparc64/kernel/systbls.S b/arch/sparc64/kernel/systbls.S
--- a/arch/sparc64/kernel/systbls.S
+++ b/arch/sparc64/kernel/systbls.S
@@ -50,8 +50,8 @@ sys_call_table32:
 	.word sys_nis_syscall, sys32_mkdir, sys_rmdir, sys32_utimes, compat_sys_stat64
 /*140*/	.word sys32_sendfile64, sys_nis_syscall, sys32_futex, sys_gettid, compat_sys_getrlimit
 	.word compat_sys_setrlimit, sys_pivot_root, sys32_prctl, sys_pciconfig_read, sys_pciconfig_write
-/*150*/	.word sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_poll, sys_getdents64
-	.word compat_sys_fcntl64, sys_ni_syscall, compat_sys_statfs, compat_sys_fstatfs, sys_oldumount
+/*150*/	.word sys_nis_syscall, sys_inotify_init, sys_inotify_add_watch, sys_poll, sys_getdents64
+	.word compat_sys_fcntl64, sys_inotify_rm_watch, compat_sys_statfs, compat_sys_fstatfs, sys_oldumount
 /*160*/	.word compat_sys_sched_setaffinity, compat_sys_sched_getaffinity, sys32_getdomainname, sys32_setdomainname, sys_nis_syscall
 	.word sys_quotactl, sys_set_tid_address, compat_sys_mount, sys_ustat, sys32_setxattr
 /*170*/	.word sys32_lsetxattr, sys32_fsetxattr, sys_getxattr, sys_lgetxattr, compat_sys_getdents
@@ -59,11 +59,11 @@ sys_call_table32:
 /*180*/	.word sys32_flistxattr, sys_removexattr, sys_lremovexattr, compat_sys_sigpending, sys_ni_syscall
 	.word sys32_setpgid, sys32_fremovexattr, sys32_tkill, sys32_exit_group, sparc64_newuname
 /*190*/	.word sys32_init_module, sparc64_personality, sys_remap_file_pages, sys32_epoll_create, sys32_epoll_ctl
-	.word sys32_epoll_wait, sys_nis_syscall, sys_getppid, sys32_sigaction, sys_sgetmask
+	.word sys32_epoll_wait, sys32_ioprio_set, sys_getppid, sys32_sigaction, sys_sgetmask
 /*200*/	.word sys32_ssetmask, sys_sigsuspend, compat_sys_newlstat, sys_uselib, compat_sys_old_readdir
 	.word sys32_readahead, sys32_socketcall, sys32_syslog, sys32_lookup_dcookie, sys32_fadvise64
 /*210*/	.word sys32_fadvise64_64, sys32_tgkill, sys32_waitpid, sys_swapoff, sys32_sysinfo
-	.word sys32_ipc, sys32_sigreturn, sys_clone, sys_nis_syscall, sys32_adjtimex
+	.word sys32_ipc, sys32_sigreturn, sys_clone, sys32_ioprio_get, sys32_adjtimex
 /*220*/	.word sys32_sigprocmask, sys_ni_syscall, sys32_delete_module, sys_ni_syscall, sys32_getpgid
 	.word sys32_bdflush, sys32_sysfs, sys_nis_syscall, sys32_setfsuid16, sys32_setfsgid16
 /*230*/	.word sys32_select, compat_sys_time, sys_nis_syscall, compat_sys_stime, compat_sys_statfs64
@@ -116,8 +116,8 @@ sys_call_table:
 	.word sys_socketpair, sys_mkdir, sys_rmdir, sys_utimes, sys_stat64
 /*140*/	.word sys_sendfile64, sys_getpeername, sys_futex, sys_gettid, sys_getrlimit
 	.word sys_setrlimit, sys_pivot_root, sys_prctl, sys_pciconfig_read, sys_pciconfig_write
-/*150*/	.word sys_getsockname, sys_nis_syscall, sys_nis_syscall, sys_poll, sys_getdents64
-	.word sys_nis_syscall, sys_ni_syscall, sys_statfs, sys_fstatfs, sys_oldumount
+/*150*/	.word sys_getsockname, sys_inotify_init, sys_inotify_add_watch, sys_poll, sys_getdents64
+	.word sys_nis_syscall, sys_inotify_rm_watch, sys_statfs, sys_fstatfs, sys_oldumount
 /*160*/	.word sys_sched_setaffinity, sys_sched_getaffinity, sys_getdomainname, sys_setdomainname, sys_utrap_install
 	.word sys_quotactl, sys_set_tid_address, sys_mount, sys_ustat, sys_setxattr
 /*170*/	.word sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr, sys_getdents
@@ -125,11 +125,11 @@ sys_call_table:
 /*180*/	.word sys_flistxattr, sys_removexattr, sys_lremovexattr, sys_nis_syscall, sys_ni_syscall
 	.word sys_setpgid, sys_fremovexattr, sys_tkill, sys_exit_group, sparc64_newuname
 /*190*/	.word sys_init_module, sparc64_personality, sys_remap_file_pages, sys_epoll_create, sys_epoll_ctl
-	.word sys_epoll_wait, sys_nis_syscall, sys_getppid, sys_nis_syscall, sys_sgetmask
+	.word sys_epoll_wait, sys_ioprio_set, sys_getppid, sys_nis_syscall, sys_sgetmask
 /*200*/	.word sys_ssetmask, sys_nis_syscall, sys_newlstat, sys_uselib, sys_nis_syscall
 	.word sys_readahead, sys_socketcall, sys_syslog, sys_lookup_dcookie, sys_fadvise64
 /*210*/	.word sys_fadvise64_64, sys_tgkill, sys_waitpid, sys_swapoff, sys_sysinfo
-	.word sys_ipc, sys_nis_syscall, sys_clone, sys_nis_syscall, sys_adjtimex
+	.word sys_ipc, sys_nis_syscall, sys_clone, sys_ioprio_get, sys_adjtimex
 /*220*/	.word sys_nis_syscall, sys_ni_syscall, sys_delete_module, sys_ni_syscall, sys_getpgid
 	.word sys_bdflush, sys_sysfs, sys_nis_syscall, sys_setfsuid, sys_setfsgid
 /*230*/	.word sys_select, sys_nis_syscall, sys_nis_syscall, sys_stime, sys_statfs64
diff --git a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c
--- a/arch/sparc64/kernel/time.c
+++ b/arch/sparc64/kernel/time.c
@@ -73,7 +73,7 @@ static __initdata struct sparc64_tick_op
 	.get_tick	= dummy_get_tick,
 };
 
-struct sparc64_tick_ops *tick_ops = &dummy_tick_ops;
+struct sparc64_tick_ops *tick_ops __read_mostly = &dummy_tick_ops;
 
 #define TICK_PRIV_BIT	(1UL << 63)
 
@@ -195,7 +195,7 @@ static unsigned long tick_add_tick(unsig
 	return new_tick;
 }
 
-static struct sparc64_tick_ops tick_operations = {
+static struct sparc64_tick_ops tick_operations __read_mostly = {
 	.init_tick	=	tick_init_tick,
 	.get_tick	=	tick_get_tick,
 	.get_compare	=	tick_get_compare,
@@ -276,7 +276,7 @@ static unsigned long stick_add_compare(u
 	return new_compare;
 }
 
-static struct sparc64_tick_ops stick_operations = {
+static struct sparc64_tick_ops stick_operations __read_mostly = {
 	.init_tick	=	stick_init_tick,
 	.get_tick	=	stick_get_tick,
 	.get_compare	=	stick_get_compare,
@@ -422,7 +422,7 @@ static unsigned long hbtick_add_compare(
 	return val;
 }
 
-static struct sparc64_tick_ops hbtick_operations = {
+static struct sparc64_tick_ops hbtick_operations __read_mostly = {
 	.init_tick	=	hbtick_init_tick,
 	.get_tick	=	hbtick_get_tick,
 	.get_compare	=	hbtick_get_compare,
@@ -437,10 +437,9 @@ static struct sparc64_tick_ops hbtick_op
  * NOTE: On SUN5 systems the ticker interrupt comes in using 2
  *       interrupts, one at level14 and one with softint bit 0.
  */
-unsigned long timer_tick_offset;
-unsigned long timer_tick_compare;
+unsigned long timer_tick_offset __read_mostly;
 
-static unsigned long timer_ticks_per_nsec_quotient;
+static unsigned long timer_ticks_per_nsec_quotient __read_mostly;
 
 #define TICK_SIZE (tick_nsec / 1000)
 
@@ -464,7 +463,7 @@ static inline void timer_check_rtc(void)
 
 static irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs * regs)
 {
-	unsigned long ticks, pstate;
+	unsigned long ticks, compare, pstate;
 
 	write_seqlock(&xtime_lock);
 
@@ -483,14 +482,14 @@ static irqreturn_t timer_interrupt(int i
 				     : "=r" (pstate)
 				     : "i" (PSTATE_IE));
 
-		timer_tick_compare = tick_ops->add_compare(timer_tick_offset);
+		compare = tick_ops->add_compare(timer_tick_offset);
 		ticks = tick_ops->get_tick();
 
 		/* Restore PSTATE_IE. */
 		__asm__ __volatile__("wrpr	%0, 0x0, %%pstate"
 				     : /* no outputs */
 				     : "r" (pstate));
-	} while (time_after_eq(ticks, timer_tick_compare));
+	} while (time_after_eq(ticks, compare));
 
 	timer_check_rtc();
 
@@ -506,11 +505,6 @@ void timer_tick_interrupt(struct pt_regs
 
 	do_timer(regs);
 
-	/*
-	 * Only keep timer_tick_offset uptodate, but don't set TICK_CMPR.
-	 */
-	timer_tick_compare = tick_ops->get_compare() + timer_tick_offset;
-
 	timer_check_rtc();
 
 	write_sequnlock(&xtime_lock);
@@ -973,7 +967,7 @@ static void sparc64_start_timers(irqretu
 	int err;
 
 	/* Register IRQ handler. */
-	err = request_irq(build_irq(0, 0, 0UL, 0UL), cfunc, SA_STATIC_ALLOC,
+	err = request_irq(build_irq(0, 0, 0UL, 0UL), cfunc, 0,
 			  "timer", NULL);
 
 	if (err) {
diff --git a/arch/sparc64/kernel/trampoline.S b/arch/sparc64/kernel/trampoline.S
--- a/arch/sparc64/kernel/trampoline.S
+++ b/arch/sparc64/kernel/trampoline.S
@@ -98,8 +98,9 @@ startup_continue:
 
 	sethi		%hi(prom_entry_lock), %g2
 1:	ldstub		[%g2 + %lo(prom_entry_lock)], %g1
+	membar		#StoreLoad | #StoreStore
 	brnz,pn		%g1, 1b
-	 membar		#StoreLoad | #StoreStore
+	 nop
 
 	sethi		%hi(p1275buf), %g2
 	or		%g2, %lo(p1275buf), %g2
diff --git a/arch/sparc64/kernel/traps.c b/arch/sparc64/kernel/traps.c
--- a/arch/sparc64/kernel/traps.c
+++ b/arch/sparc64/kernel/traps.c
@@ -2125,6 +2125,11 @@ void __init trap_init(void)
 	    TI_PCR != offsetof(struct thread_info, pcr_reg) ||
 	    TI_CEE_STUFF != offsetof(struct thread_info, cee_stuff) ||
 	    TI_PRE_COUNT != offsetof(struct thread_info, preempt_count) ||
+	    TI_NEW_CHILD != offsetof(struct thread_info, new_child) ||
+	    TI_SYS_NOERROR != offsetof(struct thread_info, syscall_noerror) ||
+	    TI_RESTART_BLOCK != offsetof(struct thread_info, restart_block) ||
+	    TI_KUNA_REGS != offsetof(struct thread_info, kern_una_regs) ||
+	    TI_KUNA_INSN != offsetof(struct thread_info, kern_una_insn) ||
 	    TI_FPREGS != offsetof(struct thread_info, fpregs) ||
 	    (TI_FPREGS & (64 - 1)))
 		thread_info_offsets_are_bolixed_dave();
diff --git a/arch/sparc64/kernel/una_asm.S b/arch/sparc64/kernel/una_asm.S
new file mode 100644
--- /dev/null
+++ b/arch/sparc64/kernel/una_asm.S
@@ -0,0 +1,153 @@
+/* una_asm.S: Kernel unaligned trap assembler helpers.
+ *
+ * Copyright (C) 1996,2005 David S. Miller (davem@davemloft.net)
+ * Copyright (C) 1996,1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
+ */
+
+	.text
+
+kernel_unaligned_trap_fault:
+	call	kernel_mna_trap_fault
+	 nop
+	retl
+	 nop
+	.size	kern_unaligned_trap_fault, .-kern_unaligned_trap_fault
+
+	.globl	__do_int_store
+__do_int_store:
+	rd	%asi, %o4
+	wr	%o3, 0, %asi
+	ldx	[%o2], %g3
+	cmp	%o1, 2
+	be,pn	%icc, 2f
+	 cmp	%o1, 4
+	be,pt	%icc, 1f
+	 srlx	%g3, 24, %g2
+	srlx	%g3, 56, %g1
+	srlx	%g3, 48, %g7
+4:	stba	%g1, [%o0] %asi
+	srlx	%g3, 40, %g1
+5:	stba	%g7, [%o0 + 1] %asi
+	srlx	%g3, 32, %g7
+6:	stba	%g1, [%o0 + 2] %asi
+7:	stba	%g7, [%o0 + 3] %asi
+	srlx	%g3, 16, %g1
+8:	stba	%g2, [%o0 + 4] %asi
+	srlx	%g3, 8, %g7
+9:	stba	%g1, [%o0 + 5] %asi
+10:	stba	%g7, [%o0 + 6] %asi
+	ba,pt	%xcc, 0f
+11:	 stba	%g3, [%o0 + 7] %asi
+1:	srl	%g3, 16, %g7
+12:	stba	%g2, [%o0] %asi
+	srl	%g3, 8, %g2
+13:	stba	%g7, [%o0 + 1] %asi
+14:	stba	%g2, [%o0 + 2] %asi
+	ba,pt	%xcc, 0f
+15:	 stba	%g3, [%o0 + 3] %asi
+2:	srl	%g3, 8, %g2
+16:	stba	%g2, [%o0] %asi
+17:	stba	%g3, [%o0 + 1] %asi
+0:
+	wr	%o4, 0x0, %asi
+	retl
+	 nop
+	.size	__do_int_store, .-__do_int_store
+
+	.section	__ex_table
+	.word		4b, kernel_unaligned_trap_fault
+	.word		5b, kernel_unaligned_trap_fault
+	.word		6b, kernel_unaligned_trap_fault
+	.word		7b, kernel_unaligned_trap_fault
+	.word		8b, kernel_unaligned_trap_fault
+	.word		9b, kernel_unaligned_trap_fault
+	.word		10b, kernel_unaligned_trap_fault
+	.word		11b, kernel_unaligned_trap_fault
+	.word		12b, kernel_unaligned_trap_fault
+	.word		13b, kernel_unaligned_trap_fault
+	.word		14b, kernel_unaligned_trap_fault
+	.word		15b, kernel_unaligned_trap_fault
+	.word		16b, kernel_unaligned_trap_fault
+	.word		17b, kernel_unaligned_trap_fault
+	.previous
+
+	.globl	do_int_load
+do_int_load:
+	rd	%asi, %o5
+	wr	%o4, 0, %asi
+	cmp	%o1, 8
+	bge,pn	%icc, 9f
+	 cmp	%o1, 4
+	be,pt	%icc, 6f
+4:	 lduba	[%o2] %asi, %g2
+5:	lduba	[%o2 + 1] %asi, %g3
+	sll	%g2, 8, %g2
+	brz,pt	%o3, 3f
+	 add	%g2, %g3, %g2
+	sllx	%g2, 48, %g2
+	srax	%g2, 48, %g2
+3:	ba,pt	%xcc, 0f
+	 stx	%g2, [%o0]
+6:	lduba	[%o2 + 1] %asi, %g3
+	sll	%g2, 24, %g2
+7:	lduba	[%o2 + 2] %asi, %g7
+	sll	%g3, 16, %g3
+8:	lduba	[%o2 + 3] %asi, %g1
+	sll	%g7, 8, %g7
+	or	%g2, %g3, %g2
+	or	%g7, %g1, %g7
+	or	%g2, %g7, %g2
+	brnz,a,pt %o3, 3f
+	 sra	%g2, 0, %g2
+3:	ba,pt	%xcc, 0f
+	 stx	%g2, [%o0]
+9:	lduba	[%o2] %asi, %g2
+10:	lduba	[%o2 + 1] %asi, %g3
+	sllx	%g2, 56, %g2
+11:	lduba	[%o2 + 2] %asi, %g7
+	sllx	%g3, 48, %g3
+12:	lduba	[%o2 + 3] %asi, %g1
+	sllx	%g7, 40, %g7
+	sllx	%g1, 32, %g1
+	or	%g2, %g3, %g2
+	or	%g7, %g1, %g7
+13:	lduba	[%o2 + 4] %asi, %g3
+	or	%g2, %g7, %g7
+14:	lduba	[%o2 + 5] %asi, %g1
+	sllx	%g3, 24, %g3
+15:	lduba	[%o2 + 6] %asi, %g2
+	sllx	%g1, 16, %g1
+	or	%g7, %g3, %g7
+16:	lduba	[%o2 + 7] %asi, %g3
+	sllx	%g2, 8, %g2
+	or	%g7, %g1, %g7
+	or	%g2, %g3, %g2
+	or	%g7, %g2, %g7
+	cmp	%o1, 8
+	be,a,pt %icc, 0f
+	 stx	%g7, [%o0]
+	srlx	%g7, 32, %g2
+	sra	%g7, 0, %g7
+	stx	%g2, [%o0]
+	stx	%g7, [%o0 + 8]
+0:
+	wr	%o5, 0x0, %asi
+	retl
+	 nop
+	.size	__do_int_load, .-__do_int_load
+
+	.section	__ex_table
+	.word		4b, kernel_unaligned_trap_fault
+	.word		5b, kernel_unaligned_trap_fault
+	.word		6b, kernel_unaligned_trap_fault
+	.word		7b, kernel_unaligned_trap_fault
+	.word		8b, kernel_unaligned_trap_fault
+	.word		9b, kernel_unaligned_trap_fault
+	.word		10b, kernel_unaligned_trap_fault
+	.word		11b, kernel_unaligned_trap_fault
+	.word		12b, kernel_unaligned_trap_fault
+	.word		13b, kernel_unaligned_trap_fault
+	.word		14b, kernel_unaligned_trap_fault
+	.word		15b, kernel_unaligned_trap_fault
+	.word		16b, kernel_unaligned_trap_fault
+	.previous
diff --git a/arch/sparc64/kernel/unaligned.c b/arch/sparc64/kernel/unaligned.c
--- a/arch/sparc64/kernel/unaligned.c
+++ b/arch/sparc64/kernel/unaligned.c
@@ -180,169 +180,28 @@ static void __attribute_used__ unaligned
 	die_if_kernel(str, regs);
 }
 
-#define do_integer_load(dest_reg, size, saddr, is_signed, asi, errh) ({		\
-__asm__ __volatile__ (								\
-	"wr	%4, 0, %%asi\n\t"						\
-	"cmp	%1, 8\n\t"							\
-	"bge,pn	%%icc, 9f\n\t"							\
-	" cmp	%1, 4\n\t"							\
-	"be,pt	%%icc, 6f\n"							\
-"4:\t"	" lduba	[%2] %%asi, %%l1\n"						\
-"5:\t"	"lduba	[%2 + 1] %%asi, %%l2\n\t"					\
-	"sll	%%l1, 8, %%l1\n\t"						\
-	"brz,pt	%3, 3f\n\t"							\
-	" add	%%l1, %%l2, %%l1\n\t"						\
-	"sllx	%%l1, 48, %%l1\n\t"						\
-	"srax	%%l1, 48, %%l1\n"						\
-"3:\t"	"ba,pt	%%xcc, 0f\n\t"							\
-	" stx	%%l1, [%0]\n"							\
-"6:\t"	"lduba	[%2 + 1] %%asi, %%l2\n\t"					\
-	"sll	%%l1, 24, %%l1\n"						\
-"7:\t"	"lduba	[%2 + 2] %%asi, %%g7\n\t"					\
-	"sll	%%l2, 16, %%l2\n"						\
-"8:\t"	"lduba	[%2 + 3] %%asi, %%g1\n\t"					\
-	"sll	%%g7, 8, %%g7\n\t"						\
-	"or	%%l1, %%l2, %%l1\n\t"						\
-	"or	%%g7, %%g1, %%g7\n\t"						\
-	"or	%%l1, %%g7, %%l1\n\t"						\
-	"brnz,a,pt %3, 3f\n\t"							\
-	" sra	%%l1, 0, %%l1\n"						\
-"3:\t"	"ba,pt	%%xcc, 0f\n\t"							\
-	" stx	%%l1, [%0]\n"							\
-"9:\t"	"lduba	[%2] %%asi, %%l1\n"						\
-"10:\t"	"lduba	[%2 + 1] %%asi, %%l2\n\t"					\
-	"sllx	%%l1, 56, %%l1\n"						\
-"11:\t"	"lduba	[%2 + 2] %%asi, %%g7\n\t"					\
-	"sllx	%%l2, 48, %%l2\n"						\
-"12:\t"	"lduba	[%2 + 3] %%asi, %%g1\n\t"					\
-	"sllx	%%g7, 40, %%g7\n\t"						\
-	"sllx	%%g1, 32, %%g1\n\t"						\
-	"or	%%l1, %%l2, %%l1\n\t"						\
-	"or	%%g7, %%g1, %%g7\n"						\
-"13:\t"	"lduba	[%2 + 4] %%asi, %%l2\n\t"					\
-	"or	%%l1, %%g7, %%g7\n"						\
-"14:\t"	"lduba	[%2 + 5] %%asi, %%g1\n\t"					\
-	"sllx	%%l2, 24, %%l2\n"						\
-"15:\t"	"lduba	[%2 + 6] %%asi, %%l1\n\t"					\
-	"sllx	%%g1, 16, %%g1\n\t"						\
-	"or	%%g7, %%l2, %%g7\n"						\
-"16:\t"	"lduba	[%2 + 7] %%asi, %%l2\n\t"					\
-	"sllx	%%l1, 8, %%l1\n\t"						\
-	"or	%%g7, %%g1, %%g7\n\t"						\
-	"or	%%l1, %%l2, %%l1\n\t"						\
-	"or	%%g7, %%l1, %%g7\n\t"						\
-	"cmp	%1, 8\n\t"							\
-	"be,a,pt %%icc, 0f\n\t"							\
-	" stx	%%g7, [%0]\n\t"							\
-	"srlx	%%g7, 32, %%l1\n\t"						\
-	"sra	%%g7, 0, %%g7\n\t"						\
-	"stx	%%l1, [%0]\n\t"							\
-	"stx	%%g7, [%0 + 8]\n"						\
-"0:\n\t"									\
-	"wr	%%g0, %5, %%asi\n\n\t"						\
-	".section __ex_table\n\t"						\
-	".word	4b, " #errh "\n\t"						\
-	".word	5b, " #errh "\n\t"						\
-	".word	6b, " #errh "\n\t"						\
-	".word	7b, " #errh "\n\t"						\
-	".word	8b, " #errh "\n\t"						\
-	".word	9b, " #errh "\n\t"						\
-	".word	10b, " #errh "\n\t"						\
-	".word	11b, " #errh "\n\t"						\
-	".word	12b, " #errh "\n\t"						\
-	".word	13b, " #errh "\n\t"						\
-	".word	14b, " #errh "\n\t"						\
-	".word	15b, " #errh "\n\t"						\
-	".word	16b, " #errh "\n\n\t"						\
-	".previous\n\t"								\
-	: : "r" (dest_reg), "r" (size), "r" (saddr), "r" (is_signed),		\
-	  "r" (asi), "i" (ASI_AIUS)						\
-	: "l1", "l2", "g7", "g1", "cc");					\
-})
+extern void do_int_load(unsigned long *dest_reg, int size,
+			unsigned long *saddr, int is_signed, int asi);
 	
-#define store_common(dst_addr, size, src_val, asi, errh) ({			\
-__asm__ __volatile__ (								\
-	"wr	%3, 0, %%asi\n\t"						\
-	"ldx	[%2], %%l1\n"							\
-	"cmp	%1, 2\n\t"							\
-	"be,pn	%%icc, 2f\n\t"							\
-	" cmp	%1, 4\n\t"							\
-	"be,pt	%%icc, 1f\n\t"							\
-	" srlx	%%l1, 24, %%l2\n\t"						\
-	"srlx	%%l1, 56, %%g1\n\t"						\
-	"srlx	%%l1, 48, %%g7\n"						\
-"4:\t"	"stba	%%g1, [%0] %%asi\n\t"						\
-	"srlx	%%l1, 40, %%g1\n"						\
-"5:\t"	"stba	%%g7, [%0 + 1] %%asi\n\t"					\
-	"srlx	%%l1, 32, %%g7\n"						\
-"6:\t"	"stba	%%g1, [%0 + 2] %%asi\n"						\
-"7:\t"	"stba	%%g7, [%0 + 3] %%asi\n\t"					\
-	"srlx	%%l1, 16, %%g1\n"						\
-"8:\t"	"stba	%%l2, [%0 + 4] %%asi\n\t"					\
-	"srlx	%%l1, 8, %%g7\n"						\
-"9:\t"	"stba	%%g1, [%0 + 5] %%asi\n"						\
-"10:\t"	"stba	%%g7, [%0 + 6] %%asi\n\t"					\
-	"ba,pt	%%xcc, 0f\n"							\
-"11:\t"	" stba	%%l1, [%0 + 7] %%asi\n"						\
-"1:\t"	"srl	%%l1, 16, %%g7\n"						\
-"12:\t"	"stba	%%l2, [%0] %%asi\n\t"						\
-	"srl	%%l1, 8, %%l2\n"						\
-"13:\t"	"stba	%%g7, [%0 + 1] %%asi\n"						\
-"14:\t"	"stba	%%l2, [%0 + 2] %%asi\n\t"					\
-	"ba,pt	%%xcc, 0f\n"							\
-"15:\t"	" stba	%%l1, [%0 + 3] %%asi\n"						\
-"2:\t"	"srl	%%l1, 8, %%l2\n"						\
-"16:\t"	"stba	%%l2, [%0] %%asi\n"						\
-"17:\t"	"stba	%%l1, [%0 + 1] %%asi\n"						\
-"0:\n\t"									\
-	"wr	%%g0, %4, %%asi\n\n\t"						\
-	".section __ex_table\n\t"						\
-	".word	4b, " #errh "\n\t"						\
-	".word	5b, " #errh "\n\t"						\
-	".word	6b, " #errh "\n\t"						\
-	".word	7b, " #errh "\n\t"						\
-	".word	8b, " #errh "\n\t"						\
-	".word	9b, " #errh "\n\t"						\
-	".word	10b, " #errh "\n\t"						\
-	".word	11b, " #errh "\n\t"						\
-	".word	12b, " #errh "\n\t"						\
-	".word	13b, " #errh "\n\t"						\
-	".word	14b, " #errh "\n\t"						\
-	".word	15b, " #errh "\n\t"						\
-	".word	16b, " #errh "\n\t"						\
-	".word	17b, " #errh "\n\n\t"						\
-	".previous\n\t"								\
-	: : "r" (dst_addr), "r" (size), "r" (src_val), "r" (asi), "i" (ASI_AIUS)\
-	: "l1", "l2", "g7", "g1", "cc");					\
-})
-
-#define do_integer_store(reg_num, size, dst_addr, regs, asi, errh) ({		\
-	unsigned long zero = 0;							\
-	unsigned long *src_val = &zero;						\
-										\
-	if (size == 16) {							\
-		size = 8;							\
-		zero = (((long)(reg_num ? 					\
-		        (unsigned)fetch_reg(reg_num, regs) : 0)) << 32) |	\
-			(unsigned)fetch_reg(reg_num + 1, regs);			\
-	} else if (reg_num) src_val = fetch_reg_addr(reg_num, regs);		\
-	store_common(dst_addr, size, src_val, asi, errh);			\
-})
-
-extern void smp_capture(void);
-extern void smp_release(void);
-
-#define do_atomic(srcdest_reg, mem, errh) ({					\
-	unsigned long flags, tmp;						\
-										\
-	smp_capture();								\
-	local_irq_save(flags);							\
-	tmp = *srcdest_reg;							\
-	do_integer_load(srcdest_reg, 4, mem, 0, errh);				\
-	store_common(mem, 4, &tmp, errh);					\
-	local_irq_restore(flags);						\
-	smp_release();								\
-})
+extern void __do_int_store(unsigned long *dst_addr, int size,
+			   unsigned long *src_val, int asi);
+
+static inline void do_int_store(int reg_num, int size, unsigned long *dst_addr,
+				struct pt_regs *regs, int asi)
+{
+	unsigned long zero = 0;
+	unsigned long *src_val = &zero;
+
+	if (size == 16) {
+		size = 8;
+		zero = (((long)(reg_num ?
+		        (unsigned)fetch_reg(reg_num, regs) : 0)) << 32) |
+			(unsigned)fetch_reg(reg_num + 1, regs);
+	} else if (reg_num) {
+		src_val = fetch_reg_addr(reg_num, regs);
+	}
+	__do_int_store(dst_addr, size, src_val, asi);
+}
 
 static inline void advance(struct pt_regs *regs)
 {
@@ -364,24 +223,29 @@ static inline int ok_for_kernel(unsigned
 	return !floating_point_load_or_store_p(insn);
 }
 
-void kernel_mna_trap_fault(struct pt_regs *regs, unsigned int insn) __asm__ ("kernel_mna_trap_fault");
-
-void kernel_mna_trap_fault(struct pt_regs *regs, unsigned int insn)
+void kernel_mna_trap_fault(void)
 {
-	unsigned long g2 = regs->u_regs [UREG_G2];
+	struct pt_regs *regs = current_thread_info()->kern_una_regs;
+	unsigned int insn = current_thread_info()->kern_una_insn;
+	unsigned long g2 = regs->u_regs[UREG_G2];
 	unsigned long fixup = search_extables_range(regs->tpc, &g2);
 
 	if (!fixup) {
-		unsigned long address = compute_effective_address(regs, insn, ((insn >> 25) & 0x1f));
+		unsigned long address;
+
+		address = compute_effective_address(regs, insn,
+						    ((insn >> 25) & 0x1f));
         	if (address < PAGE_SIZE) {
-                	printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference in mna handler");
+                	printk(KERN_ALERT "Unable to handle kernel NULL "
+			       "pointer dereference in mna handler");
         	} else
-                	printk(KERN_ALERT "Unable to handle kernel paging request in mna handler");
+                	printk(KERN_ALERT "Unable to handle kernel paging "
+			       "request in mna handler");
 	        printk(KERN_ALERT " at virtual address %016lx\n",address);
-		printk(KERN_ALERT "current->{mm,active_mm}->context = %016lx\n",
+		printk(KERN_ALERT "current->{active_,}mm->context = %016lx\n",
 			(current->mm ? CTX_HWBITS(current->mm->context) :
 			CTX_HWBITS(current->active_mm->context)));
-		printk(KERN_ALERT "current->{mm,active_mm}->pgd = %016lx\n",
+		printk(KERN_ALERT "current->{active_,}mm->pgd = %016lx\n",
 			(current->mm ? (unsigned long) current->mm->pgd :
 			(unsigned long) current->active_mm->pgd));
 	        die_if_kernel("Oops", regs);
@@ -400,48 +264,41 @@ asmlinkage void kernel_unaligned_trap(st
 	enum direction dir = decode_direction(insn);
 	int size = decode_access_size(insn);
 
+	current_thread_info()->kern_una_regs = regs;
+	current_thread_info()->kern_una_insn = insn;
+
 	if (!ok_for_kernel(insn) || dir == both) {
-		printk("Unsupported unaligned load/store trap for kernel at <%016lx>.\n",
-		       regs->tpc);
-		unaligned_panic("Kernel does fpu/atomic unaligned load/store.", regs);
-
-		__asm__ __volatile__ ("\n"
-"kernel_unaligned_trap_fault:\n\t"
-		"mov	%0, %%o0\n\t"
-		"call	kernel_mna_trap_fault\n\t"
-		" mov	%1, %%o1\n\t"
-		:
-		: "r" (regs), "r" (insn)
-		: "o0", "o1", "o2", "o3", "o4", "o5", "o7",
-		  "g1", "g2", "g3", "g4", "g7", "cc");
+		printk("Unsupported unaligned load/store trap for kernel "
+		       "at <%016lx>.\n", regs->tpc);
+		unaligned_panic("Kernel does fpu/atomic "
+				"unaligned load/store.", regs);
+
+		kernel_mna_trap_fault();
 	} else {
-		unsigned long addr = compute_effective_address(regs, insn, ((insn >> 25) & 0x1f));
+		unsigned long addr;
 
+		addr = compute_effective_address(regs, insn,
+						 ((insn >> 25) & 0x1f));
 #ifdef DEBUG_MNA
-		printk("KMNA: pc=%016lx [dir=%s addr=%016lx size=%d] retpc[%016lx]\n",
-		       regs->tpc, dirstrings[dir], addr, size, regs->u_regs[UREG_RETPC]);
+		printk("KMNA: pc=%016lx [dir=%s addr=%016lx size=%d] "
+		       "retpc[%016lx]\n",
+		       regs->tpc, dirstrings[dir], addr, size,
+		       regs->u_regs[UREG_RETPC]);
 #endif
 		switch (dir) {
 		case load:
-			do_integer_load(fetch_reg_addr(((insn>>25)&0x1f), regs),
-					size, (unsigned long *) addr,
-					decode_signedness(insn), decode_asi(insn, regs),
-					kernel_unaligned_trap_fault);
+			do_int_load(fetch_reg_addr(((insn>>25)&0x1f), regs),
+				    size, (unsigned long *) addr,
+				    decode_signedness(insn),
+				    decode_asi(insn, regs));
 			break;
 
 		case store:
-			do_integer_store(((insn>>25)&0x1f), size,
-					 (unsigned long *) addr, regs,
-					 decode_asi(insn, regs),
-					 kernel_unaligned_trap_fault);
+			do_int_store(((insn>>25)&0x1f), size,
+				     (unsigned long *) addr, regs,
+				     decode_asi(insn, regs));
 			break;
-#if 0 /* unsupported */
-		case both:
-			do_atomic(fetch_reg_addr(((insn>>25)&0x1f), regs),
-				  (unsigned long *) addr,
-				  kernel_unaligned_trap_fault);
-			break;
-#endif
+
 		default:
 			panic("Impossible kernel unaligned trap.");
 			/* Not reached... */
diff --git a/arch/sparc64/kernel/us2e_cpufreq.c b/arch/sparc64/kernel/us2e_cpufreq.c
--- a/arch/sparc64/kernel/us2e_cpufreq.c
+++ b/arch/sparc64/kernel/us2e_cpufreq.c
@@ -88,7 +88,6 @@ static void frob_mem_refresh(int cpu_slo
 {
 	unsigned long old_refr_count, refr_count, mctrl;
 
-
 	refr_count  = (clock_tick * MCTRL0_REFR_INTERVAL);
 	refr_count /= (MCTRL0_REFR_CLKS_P_CNT * divisor * 1000000000UL);
 
@@ -230,6 +229,25 @@ static unsigned long estar_to_divisor(un
 	return ret;
 }
 
+static unsigned int us2e_freq_get(unsigned int cpu)
+{
+	cpumask_t cpus_allowed;
+	unsigned long clock_tick, estar;
+
+	if (!cpu_online(cpu))
+		return 0;
+
+	cpus_allowed = current->cpus_allowed;
+	set_cpus_allowed(current, cpumask_of_cpu(cpu));
+
+	clock_tick = sparc64_get_clock_tick(cpu) / 1000;
+	estar = read_hbreg(HBIRD_ESTAR_MODE_ADDR);
+
+	set_cpus_allowed(current, cpus_allowed);
+
+	return clock_tick / estar_to_divisor(estar);
+}
+
 static void us2e_set_cpu_divider_index(unsigned int cpu, unsigned int index)
 {
 	unsigned long new_bits, new_freq;
@@ -243,7 +261,7 @@ static void us2e_set_cpu_divider_index(u
 	cpus_allowed = current->cpus_allowed;
 	set_cpus_allowed(current, cpumask_of_cpu(cpu));
 
-	new_freq = clock_tick = sparc64_get_clock_tick(cpu);
+	new_freq = clock_tick = sparc64_get_clock_tick(cpu) / 1000;
 	new_bits = index_to_estar_mode(index);
 	divisor = index_to_divisor(index);
 	new_freq /= divisor;
@@ -258,7 +276,8 @@ static void us2e_set_cpu_divider_index(u
 	cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
 
 	if (old_divisor != divisor)
-		us2e_transition(estar, new_bits, clock_tick, old_divisor, divisor);
+		us2e_transition(estar, new_bits, clock_tick * 1000,
+				old_divisor, divisor);
 
 	cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
 
@@ -272,10 +291,8 @@ static int us2e_freq_target(struct cpufr
 	unsigned int new_index = 0;
 
 	if (cpufreq_frequency_table_target(policy,
-					      &us2e_freq_table[policy->cpu].table[0],
-					      target_freq,
-					      relation,
-					      &new_index))
+					   &us2e_freq_table[policy->cpu].table[0],
+					   target_freq, relation, &new_index))
 		return -EINVAL;
 
 	us2e_set_cpu_divider_index(policy->cpu, new_index);
@@ -292,7 +309,7 @@ static int us2e_freq_verify(struct cpufr
 static int __init us2e_freq_cpu_init(struct cpufreq_policy *policy)
 {
 	unsigned int cpu = policy->cpu;
-	unsigned long clock_tick = sparc64_get_clock_tick(cpu);
+	unsigned long clock_tick = sparc64_get_clock_tick(cpu) / 1000;
 	struct cpufreq_frequency_table *table =
 		&us2e_freq_table[cpu].table[0];
 
@@ -351,9 +368,10 @@ static int __init us2e_freq_init(void)
 		memset(us2e_freq_table, 0,
 		       (NR_CPUS * sizeof(struct us2e_freq_percpu_info)));
 
+		driver->init = us2e_freq_cpu_init;
 		driver->verify = us2e_freq_verify;
 		driver->target = us2e_freq_target;
-		driver->init = us2e_freq_cpu_init;
+		driver->get = us2e_freq_get;
 		driver->exit = us2e_freq_cpu_exit;
 		driver->owner = THIS_MODULE,
 		strcpy(driver->name, "UltraSPARC-IIe");
diff --git a/arch/sparc64/kernel/us3_cpufreq.c b/arch/sparc64/kernel/us3_cpufreq.c
--- a/arch/sparc64/kernel/us3_cpufreq.c
+++ b/arch/sparc64/kernel/us3_cpufreq.c
@@ -56,7 +56,7 @@ static void write_safari_cfg(unsigned lo
 
 static unsigned long get_current_freq(unsigned int cpu, unsigned long safari_cfg)
 {
-	unsigned long clock_tick = sparc64_get_clock_tick(cpu);
+	unsigned long clock_tick = sparc64_get_clock_tick(cpu) / 1000;
 	unsigned long ret;
 
 	switch (safari_cfg & SAFARI_CFG_DIV_MASK) {
@@ -76,6 +76,26 @@ static unsigned long get_current_freq(un
 	return ret;
 }
 
+static unsigned int us3_freq_get(unsigned int cpu)
+{
+	cpumask_t cpus_allowed;
+	unsigned long reg;
+	unsigned int ret;
+
+	if (!cpu_online(cpu))
+		return 0;
+
+	cpus_allowed = current->cpus_allowed;
+	set_cpus_allowed(current, cpumask_of_cpu(cpu));
+
+	reg = read_safari_cfg();
+	ret = get_current_freq(cpu, reg);
+
+	set_cpus_allowed(current, cpus_allowed);
+
+	return ret;
+}
+
 static void us3_set_cpu_divider_index(unsigned int cpu, unsigned int index)
 {
 	unsigned long new_bits, new_freq, reg;
@@ -88,7 +108,7 @@ static void us3_set_cpu_divider_index(un
 	cpus_allowed = current->cpus_allowed;
 	set_cpus_allowed(current, cpumask_of_cpu(cpu));
 
-	new_freq = sparc64_get_clock_tick(cpu);
+	new_freq = sparc64_get_clock_tick(cpu) / 1000;
 	switch (index) {
 	case 0:
 		new_bits = SAFARI_CFG_DIV_1;
@@ -150,7 +170,7 @@ static int us3_freq_verify(struct cpufre
 static int __init us3_freq_cpu_init(struct cpufreq_policy *policy)
 {
 	unsigned int cpu = policy->cpu;
-	unsigned long clock_tick = sparc64_get_clock_tick(cpu);
+	unsigned long clock_tick = sparc64_get_clock_tick(cpu) / 1000;
 	struct cpufreq_frequency_table *table =
 		&us3_freq_table[cpu].table[0];
 
@@ -206,9 +226,10 @@ static int __init us3_freq_init(void)
 		memset(us3_freq_table, 0,
 		       (NR_CPUS * sizeof(struct us3_freq_percpu_info)));
 
+		driver->init = us3_freq_cpu_init;
 		driver->verify = us3_freq_verify;
 		driver->target = us3_freq_target;
-		driver->init = us3_freq_cpu_init;
+		driver->get = us3_freq_get;
 		driver->exit = us3_freq_cpu_exit;
 		driver->owner = THIS_MODULE,
 		strcpy(driver->name, "UltraSPARC-III");
diff --git a/arch/sparc64/kernel/vmlinux.lds.S b/arch/sparc64/kernel/vmlinux.lds.S
--- a/arch/sparc64/kernel/vmlinux.lds.S
+++ b/arch/sparc64/kernel/vmlinux.lds.S
@@ -32,6 +32,8 @@ SECTIONS
   .data1   : { *(.data1) }
   . = ALIGN(64);
   .data.cacheline_aligned : { *(.data.cacheline_aligned) }
+  . = ALIGN(64);
+  .data.read_mostly : { *(.data.read_mostly) }
   _edata  =  .;
   PROVIDE (edata = .);
   .fixup   : { *(.fixup) }
diff --git a/arch/sparc64/lib/U1memcpy.S b/arch/sparc64/lib/U1memcpy.S
--- a/arch/sparc64/lib/U1memcpy.S
+++ b/arch/sparc64/lib/U1memcpy.S
@@ -87,14 +87,17 @@
 #define LOOP_CHUNK3(src, dest, len, branch_dest)		\
 	MAIN_LOOP_CHUNK(src, dest, f32, f48, len, branch_dest)
 
+#define DO_SYNC			membar	#Sync;
 #define STORE_SYNC(dest, fsrc)				\
 	EX_ST(STORE_BLK(%fsrc, %dest));			\
-	add			%dest, 0x40, %dest;
+	add			%dest, 0x40, %dest;	\
+	DO_SYNC
 
 #define STORE_JUMP(dest, fsrc, target)			\
 	EX_ST(STORE_BLK(%fsrc, %dest));			\
 	add			%dest, 0x40, %dest;	\
-	ba,pt			%xcc, target;
+	ba,pt			%xcc, target;		\
+	 nop;
 
 #define FINISH_VISCHUNK(dest, f0, f1, left)	\
 	subcc			%left, 8, %left;\
@@ -239,17 +242,17 @@ FUNC_NAME:		/* %o0=dst, %o1=src, %o2=len
 	ba,pt		%xcc, 1b+4
 	 faligndata	%f0, %f2, %f48
 1:	FREG_FROB(f16,f18,f20,f22,f24,f26,f28,f30,f32)
-	STORE_SYNC(o0, f48) membar #Sync
+	STORE_SYNC(o0, f48)
 	FREG_FROB(f32,f34,f36,f38,f40,f42,f44,f46,f0)
-	STORE_JUMP(o0, f48, 40f) membar #Sync
+	STORE_JUMP(o0, f48, 40f)
 2:	FREG_FROB(f32,f34,f36,f38,f40,f42,f44,f46,f0)
-	STORE_SYNC(o0, f48) membar #Sync
+	STORE_SYNC(o0, f48)
 	FREG_FROB(f0, f2, f4, f6, f8, f10,f12,f14,f16)
-	STORE_JUMP(o0, f48, 48f) membar #Sync
+	STORE_JUMP(o0, f48, 48f)
 3:	FREG_FROB(f0, f2, f4, f6, f8, f10,f12,f14,f16)
-	STORE_SYNC(o0, f48) membar #Sync
+	STORE_SYNC(o0, f48)
 	FREG_FROB(f16,f18,f20,f22,f24,f26,f28,f30,f32)
-	STORE_JUMP(o0, f48, 56f) membar #Sync
+	STORE_JUMP(o0, f48, 56f)
 
 1:	FREG_FROB(f2, f4, f6, f8, f10,f12,f14,f16,f18)
 	LOOP_CHUNK1(o1, o0, GLOBAL_SPARE, 1f)
@@ -260,17 +263,17 @@ FUNC_NAME:		/* %o0=dst, %o1=src, %o2=len
 	ba,pt		%xcc, 1b+4
 	 faligndata	%f2, %f4, %f48
 1:	FREG_FROB(f18,f20,f22,f24,f26,f28,f30,f32,f34)
-	STORE_SYNC(o0, f48) membar #Sync
+	STORE_SYNC(o0, f48)
 	FREG_FROB(f34,f36,f38,f40,f42,f44,f46,f0, f2)
-	STORE_JUMP(o0, f48, 41f) membar #Sync
+	STORE_JUMP(o0, f48, 41f)
 2:	FREG_FROB(f34,f36,f38,f40,f42,f44,f46,f0, f2)
-	STORE_SYNC(o0, f48) membar #Sync
+	STORE_SYNC(o0, f48)
 	FREG_FROB(f2, f4, f6, f8, f10,f12,f14,f16,f18)
-	STORE_JUMP(o0, f48, 49f) membar #Sync
+	STORE_JUMP(o0, f48, 49f)
 3:	FREG_FROB(f2, f4, f6, f8, f10,f12,f14,f16,f18)
-	STORE_SYNC(o0, f48) membar #Sync
+	STORE_SYNC(o0, f48)
 	FREG_FROB(f18,f20,f22,f24,f26,f28,f30,f32,f34)
-	STORE_JUMP(o0, f48, 57f) membar #Sync
+	STORE_JUMP(o0, f48, 57f)
 
 1:	FREG_FROB(f4, f6, f8, f10,f12,f14,f16,f18,f20)
 	LOOP_CHUNK1(o1, o0, GLOBAL_SPARE, 1f)
@@ -281,17 +284,17 @@ FUNC_NAME:		/* %o0=dst, %o1=src, %o2=len
 	ba,pt		%xcc, 1b+4
 	 faligndata	%f4, %f6, %f48
 1:	FREG_FROB(f20,f22,f24,f26,f28,f30,f32,f34,f36)
-	STORE_SYNC(o0, f48) membar #Sync
+	STORE_SYNC(o0, f48)
 	FREG_FROB(f36,f38,f40,f42,f44,f46,f0, f2, f4)
-	STORE_JUMP(o0, f48, 42f) membar #Sync
+	STORE_JUMP(o0, f48, 42f)
 2:	FREG_FROB(f36,f38,f40,f42,f44,f46,f0, f2, f4)
-	STORE_SYNC(o0, f48) membar #Sync
+	STORE_SYNC(o0, f48)
 	FREG_FROB(f4, f6, f8, f10,f12,f14,f16,f18,f20)
-	STORE_JUMP(o0, f48, 50f) membar #Sync
+	STORE_JUMP(o0, f48, 50f)
 3:	FREG_FROB(f4, f6, f8, f10,f12,f14,f16,f18,f20)
-	STORE_SYNC(o0, f48) membar #Sync
+	STORE_SYNC(o0, f48)
 	FREG_FROB(f20,f22,f24,f26,f28,f30,f32,f34,f36)
-	STORE_JUMP(o0, f48, 58f) membar #Sync
+	STORE_JUMP(o0, f48, 58f)
 
 1:	FREG_FROB(f6, f8, f10,f12,f14,f16,f18,f20,f22)
 	LOOP_CHUNK1(o1, o0, GLOBAL_SPARE, 1f)
@@ -302,17 +305,17 @@ FUNC_NAME:		/* %o0=dst, %o1=src, %o2=len
 	ba,pt		%xcc, 1b+4
 	 faligndata	%f6, %f8, %f48
 1:	FREG_FROB(f22,f24,f26,f28,f30,f32,f34,f36,f38)
-	STORE_SYNC(o0, f48) membar #Sync
+	STORE_SYNC(o0, f48)
 	FREG_FROB(f38,f40,f42,f44,f46,f0, f2, f4, f6)
-	STORE_JUMP(o0, f48, 43f) membar #Sync
+	STORE_JUMP(o0, f48, 43f)
 2:	FREG_FROB(f38,f40,f42,f44,f46,f0, f2, f4, f6)
-	STORE_SYNC(o0, f48) membar #Sync
+	STORE_SYNC(o0, f48)
 	FREG_FROB(f6, f8, f10,f12,f14,f16,f18,f20,f22)
-	STORE_JUMP(o0, f48, 51f) membar #Sync
+	STORE_JUMP(o0, f48, 51f)
 3:	FREG_FROB(f6, f8, f10,f12,f14,f16,f18,f20,f22)
-	STORE_SYNC(o0, f48) membar #Sync
+	STORE_SYNC(o0, f48)
 	FREG_FROB(f22,f24,f26,f28,f30,f32,f34,f36,f38)
-	STORE_JUMP(o0, f48, 59f) membar #Sync
+	STORE_JUMP(o0, f48, 59f)
 
 1:	FREG_FROB(f8, f10,f12,f14,f16,f18,f20,f22,f24)
 	LOOP_CHUNK1(o1, o0, GLOBAL_SPARE, 1f)
@@ -323,17 +326,17 @@ FUNC_NAME:		/* %o0=dst, %o1=src, %o2=len
 	ba,pt		%xcc, 1b+4
 	 faligndata	%f8, %f10, %f48
 1:	FREG_FROB(f24,f26,f28,f30,f32,f34,f36,f38,f40)
-	STORE_SYNC(o0, f48) membar #Sync
+	STORE_SYNC(o0, f48)
 	FREG_FROB(f40,f42,f44,f46,f0, f2, f4, f6, f8)
-	STORE_JUMP(o0, f48, 44f) membar #Sync
+	STORE_JUMP(o0, f48, 44f)
 2:	FREG_FROB(f40,f42,f44,f46,f0, f2, f4, f6, f8)
-	STORE_SYNC(o0, f48) membar #Sync
+	STORE_SYNC(o0, f48)
 	FREG_FROB(f8, f10,f12,f14,f16,f18,f20,f22,f24)
-	STORE_JUMP(o0, f48, 52f) membar #Sync
+	STORE_JUMP(o0, f48, 52f)
 3:	FREG_FROB(f8, f10,f12,f14,f16,f18,f20,f22,f24)
-	STORE_SYNC(o0, f48) membar #Sync
+	STORE_SYNC(o0, f48)
 	FREG_FROB(f24,f26,f28,f30,f32,f34,f36,f38,f40)
-	STORE_JUMP(o0, f48, 60f) membar #Sync
+	STORE_JUMP(o0, f48, 60f)
 
 1:	FREG_FROB(f10,f12,f14,f16,f18,f20,f22,f24,f26)
 	LOOP_CHUNK1(o1, o0, GLOBAL_SPARE, 1f)
@@ -344,17 +347,17 @@ FUNC_NAME:		/* %o0=dst, %o1=src, %o2=len
 	ba,pt		%xcc, 1b+4
 	 faligndata	%f10, %f12, %f48
 1:	FREG_FROB(f26,f28,f30,f32,f34,f36,f38,f40,f42)
-	STORE_SYNC(o0, f48) membar #Sync
+	STORE_SYNC(o0, f48)
 	FREG_FROB(f42,f44,f46,f0, f2, f4, f6, f8, f10)
-	STORE_JUMP(o0, f48, 45f) membar #Sync
+	STORE_JUMP(o0, f48, 45f)
 2:	FREG_FROB(f42,f44,f46,f0, f2, f4, f6, f8, f10)
-	STORE_SYNC(o0, f48) membar #Sync
+	STORE_SYNC(o0, f48)
 	FREG_FROB(f10,f12,f14,f16,f18,f20,f22,f24,f26)
-	STORE_JUMP(o0, f48, 53f) membar #Sync
+	STORE_JUMP(o0, f48, 53f)
 3:	FREG_FROB(f10,f12,f14,f16,f18,f20,f22,f24,f26)
-	STORE_SYNC(o0, f48) membar #Sync
+	STORE_SYNC(o0, f48)
 	FREG_FROB(f26,f28,f30,f32,f34,f36,f38,f40,f42)
-	STORE_JUMP(o0, f48, 61f) membar #Sync
+	STORE_JUMP(o0, f48, 61f)
 
 1:	FREG_FROB(f12,f14,f16,f18,f20,f22,f24,f26,f28)
 	LOOP_CHUNK1(o1, o0, GLOBAL_SPARE, 1f)
@@ -365,17 +368,17 @@ FUNC_NAME:		/* %o0=dst, %o1=src, %o2=len
 	ba,pt		%xcc, 1b+4
 	 faligndata	%f12, %f14, %f48
 1:	FREG_FROB(f28,f30,f32,f34,f36,f38,f40,f42,f44)
-	STORE_SYNC(o0, f48) membar #Sync
+	STORE_SYNC(o0, f48)
 	FREG_FROB(f44,f46,f0, f2, f4, f6, f8, f10,f12)
-	STORE_JUMP(o0, f48, 46f) membar #Sync
+	STORE_JUMP(o0, f48, 46f)
 2:	FREG_FROB(f44,f46,f0, f2, f4, f6, f8, f10,f12)
-	STORE_SYNC(o0, f48) membar #Sync
+	STORE_SYNC(o0, f48)
 	FREG_FROB(f12,f14,f16,f18,f20,f22,f24,f26,f28)
-	STORE_JUMP(o0, f48, 54f) membar #Sync
+	STORE_JUMP(o0, f48, 54f)
 3:	FREG_FROB(f12,f14,f16,f18,f20,f22,f24,f26,f28)
-	STORE_SYNC(o0, f48) membar #Sync
+	STORE_SYNC(o0, f48)
 	FREG_FROB(f28,f30,f32,f34,f36,f38,f40,f42,f44)
-	STORE_JUMP(o0, f48, 62f) membar #Sync
+	STORE_JUMP(o0, f48, 62f)
 
 1:	FREG_FROB(f14,f16,f18,f20,f22,f24,f26,f28,f30)
 	LOOP_CHUNK1(o1, o0, GLOBAL_SPARE, 1f)
@@ -386,17 +389,17 @@ FUNC_NAME:		/* %o0=dst, %o1=src, %o2=len
 	ba,pt		%xcc, 1b+4
 	 faligndata	%f14, %f16, %f48
 1:	FREG_FROB(f30,f32,f34,f36,f38,f40,f42,f44,f46)
-	STORE_SYNC(o0, f48) membar #Sync
+	STORE_SYNC(o0, f48)
 	FREG_FROB(f46,f0, f2, f4, f6, f8, f10,f12,f14)
-	STORE_JUMP(o0, f48, 47f) membar #Sync
+	STORE_JUMP(o0, f48, 47f)
 2:	FREG_FROB(f46,f0, f2, f4, f6, f8, f10,f12,f14)
-	STORE_SYNC(o0, f48) membar #Sync
+	STORE_SYNC(o0, f48)
 	FREG_FROB(f14,f16,f18,f20,f22,f24,f26,f28,f30)
-	STORE_JUMP(o0, f48, 55f) membar #Sync
+	STORE_JUMP(o0, f48, 55f)
 3:	FREG_FROB(f14,f16,f18,f20,f22,f24,f26,f28,f30)
-	STORE_SYNC(o0, f48) membar #Sync
+	STORE_SYNC(o0, f48)
 	FREG_FROB(f30,f32,f34,f36,f38,f40,f42,f44,f46)
-	STORE_JUMP(o0, f48, 63f) membar #Sync
+	STORE_JUMP(o0, f48, 63f)
 
 40:	FINISH_VISCHUNK(o0, f0,  f2,  g3)
 41:	FINISH_VISCHUNK(o0, f2,  f4,  g3)
diff --git a/arch/sparc64/lib/VISsave.S b/arch/sparc64/lib/VISsave.S
--- a/arch/sparc64/lib/VISsave.S
+++ b/arch/sparc64/lib/VISsave.S
@@ -72,7 +72,11 @@ vis1:	ldub		[%g6 + TI_FPSAVED], %g3
 
 	stda		%f48, [%g3 + %g1] ASI_BLK_P
 5:	membar		#Sync
-	jmpl		%g7 + %g0, %g0
+	ba,pt		%xcc, 80f
+	 nop
+
+	.align		32
+80:	jmpl		%g7 + %g0, %g0
 	 nop
 
 6:	ldub		[%g3 + TI_FPSAVED], %o5
@@ -87,8 +91,11 @@ vis1:	ldub		[%g6 + TI_FPSAVED], %g3
 	stda		%f32, [%g2 + %g1] ASI_BLK_P
 	stda		%f48, [%g3 + %g1] ASI_BLK_P
 	membar		#Sync
-	jmpl		%g7 + %g0, %g0
+	ba,pt		%xcc, 80f
+	 nop
 
+	.align		32
+80:	jmpl		%g7 + %g0, %g0
 	 nop
 
 	.align		32
@@ -126,6 +133,10 @@ VISenterhalf:
 	stda		%f0, [%g2 + %g1] ASI_BLK_P
 	stda		%f16, [%g3 + %g1] ASI_BLK_P
 	membar		#Sync
+	ba,pt		%xcc, 4f
+	 nop
+
+	.align		32
 4:	and		%o5, FPRS_DU, %o5
 	jmpl		%g7 + %g0, %g0
 	 wr		%o5, FPRS_FEF, %fprs
diff --git a/arch/sparc64/lib/atomic.S b/arch/sparc64/lib/atomic.S
--- a/arch/sparc64/lib/atomic.S
+++ b/arch/sparc64/lib/atomic.S
@@ -7,18 +7,6 @@
 #include <linux/config.h>
 #include <asm/asi.h>
 
-	/* On SMP we need to use memory barriers to ensure
-	 * correct memory operation ordering, nop these out
-	 * for uniprocessor.
-	 */
-#ifdef CONFIG_SMP
-#define ATOMIC_PRE_BARRIER	membar #StoreLoad | #LoadLoad
-#define ATOMIC_POST_BARRIER	membar #StoreLoad | #StoreStore
-#else
-#define ATOMIC_PRE_BARRIER	nop
-#define ATOMIC_POST_BARRIER	nop
-#endif
-
 	.text
 
 	/* Two versions of the atomic routines, one that
@@ -52,6 +40,24 @@ atomic_sub: /* %o0 = decrement, %o1 = at
 	 nop
 	.size	atomic_sub, .-atomic_sub
 
+	/* On SMP we need to use memory barriers to ensure
+	 * correct memory operation ordering, nop these out
+	 * for uniprocessor.
+	 */
+#ifdef CONFIG_SMP
+
+#define ATOMIC_PRE_BARRIER	membar #StoreLoad | #LoadLoad;
+#define ATOMIC_POST_BARRIER	\
+	ba,pt %xcc, 80b;	\
+	membar #StoreLoad | #StoreStore
+
+80:	retl
+	 nop
+#else
+#define ATOMIC_PRE_BARRIER
+#define ATOMIC_POST_BARRIER
+#endif
+
 	.globl	atomic_add_ret
 	.type	atomic_add_ret,#function
 atomic_add_ret: /* %o0 = increment, %o1 = atomic_ptr */
@@ -62,9 +68,10 @@ atomic_add_ret: /* %o0 = increment, %o1 
 	cmp	%g1, %g7
 	bne,pn	%icc, 1b
 	 add	%g7, %o0, %g7
+	sra	%g7, 0, %o0
 	ATOMIC_POST_BARRIER
 	retl
-	 sra	%g7, 0, %o0
+	 nop
 	.size	atomic_add_ret, .-atomic_add_ret
 
 	.globl	atomic_sub_ret
@@ -77,9 +84,10 @@ atomic_sub_ret: /* %o0 = decrement, %o1 
 	cmp	%g1, %g7
 	bne,pn	%icc, 1b
 	 sub	%g7, %o0, %g7
+	sra	%g7, 0, %o0
 	ATOMIC_POST_BARRIER
 	retl
-	 sra	%g7, 0, %o0
+	 nop
 	.size	atomic_sub_ret, .-atomic_sub_ret
 
 	.globl	atomic64_add
@@ -118,9 +126,10 @@ atomic64_add_ret: /* %o0 = increment, %o
 	cmp	%g1, %g7
 	bne,pn	%xcc, 1b
 	 add	%g7, %o0, %g7
+	mov	%g7, %o0
 	ATOMIC_POST_BARRIER
 	retl
-	 mov	%g7, %o0
+	 nop
 	.size	atomic64_add_ret, .-atomic64_add_ret
 
 	.globl	atomic64_sub_ret
@@ -133,7 +142,8 @@ atomic64_sub_ret: /* %o0 = decrement, %o
 	cmp	%g1, %g7
 	bne,pn	%xcc, 1b
 	 sub	%g7, %o0, %g7
+	mov	%g7, %o0
 	ATOMIC_POST_BARRIER
 	retl
-	 mov	%g7, %o0
+	 nop
 	.size	atomic64_sub_ret, .-atomic64_sub_ret
diff --git a/arch/sparc64/lib/bitops.S b/arch/sparc64/lib/bitops.S
--- a/arch/sparc64/lib/bitops.S
+++ b/arch/sparc64/lib/bitops.S
@@ -7,20 +7,26 @@
 #include <linux/config.h>
 #include <asm/asi.h>
 
+	.text
+
 	/* On SMP we need to use memory barriers to ensure
 	 * correct memory operation ordering, nop these out
 	 * for uniprocessor.
 	 */
+
 #ifdef CONFIG_SMP
 #define BITOP_PRE_BARRIER	membar #StoreLoad | #LoadLoad
-#define BITOP_POST_BARRIER	membar #StoreLoad | #StoreStore
+#define BITOP_POST_BARRIER	\
+	ba,pt	%xcc, 80b;	\
+	membar #StoreLoad | #StoreStore
+
+80:	retl
+	 nop
 #else
-#define BITOP_PRE_BARRIER	nop
-#define BITOP_POST_BARRIER	nop
+#define BITOP_PRE_BARRIER
+#define BITOP_POST_BARRIER
 #endif
 
-	.text
-
 	.globl	test_and_set_bit
 	.type	test_and_set_bit,#function
 test_and_set_bit:	/* %o0=nr, %o1=addr */
@@ -37,10 +43,11 @@ test_and_set_bit:	/* %o0=nr, %o1=addr */
 	cmp	%g7, %g1
 	bne,pn	%xcc, 1b
 	 and	%g7, %o2, %g2
-	BITOP_POST_BARRIER
 	clr	%o0
+	movrne	%g2, 1, %o0
+	BITOP_POST_BARRIER
 	retl
-	 movrne	%g2, 1, %o0
+	 nop
 	.size	test_and_set_bit, .-test_and_set_bit
 
 	.globl	test_and_clear_bit
@@ -59,10 +66,11 @@ test_and_clear_bit:	/* %o0=nr, %o1=addr 
 	cmp	%g7, %g1
 	bne,pn	%xcc, 1b
 	 and	%g7, %o2, %g2
-	BITOP_POST_BARRIER
 	clr	%o0
+	movrne	%g2, 1, %o0
+	BITOP_POST_BARRIER
 	retl
-	 movrne	%g2, 1, %o0
+	 nop
 	.size	test_and_clear_bit, .-test_and_clear_bit
 
 	.globl	test_and_change_bit
@@ -81,10 +89,11 @@ test_and_change_bit:	/* %o0=nr, %o1=addr
 	cmp	%g7, %g1
 	bne,pn	%xcc, 1b
 	 and	%g7, %o2, %g2
-	BITOP_POST_BARRIER
 	clr	%o0
+	movrne	%g2, 1, %o0
+	BITOP_POST_BARRIER
 	retl
-	 movrne	%g2, 1, %o0
+	 nop
 	.size	test_and_change_bit, .-test_and_change_bit
 
 	.globl	set_bit
diff --git a/arch/sparc64/lib/debuglocks.c b/arch/sparc64/lib/debuglocks.c
--- a/arch/sparc64/lib/debuglocks.c
+++ b/arch/sparc64/lib/debuglocks.c
@@ -252,8 +252,9 @@ wlock_again:
 "		andn	%%g1, %%g3, %%g7\n"
 "		casx	[%0], %%g1, %%g7\n"
 "		cmp	%%g1, %%g7\n"
+"		membar	#StoreLoad | #StoreStore\n"
 "		bne,pn	%%xcc, 1b\n"
-"		 membar	#StoreLoad | #StoreStore"
+"		 nop"
 		: /* no outputs */
 		: "r" (&(rw->lock))
 		: "g3", "g1", "g7", "cc", "memory");
@@ -351,8 +352,9 @@ int _do_write_trylock (rwlock_t *rw, cha
 "		andn	%%g1, %%g3, %%g7\n"
 "		casx	[%0], %%g1, %%g7\n"
 "		cmp	%%g1, %%g7\n"
+"		membar	#StoreLoad | #StoreStore\n"
 "		bne,pn	%%xcc, 1b\n"
-"		 membar	#StoreLoad | #StoreStore"
+"		 nop"
 		: /* no outputs */
 		: "r" (&(rw->lock))
 		: "g3", "g1", "g7", "cc", "memory");
diff --git a/arch/sparc64/lib/dec_and_lock.S b/arch/sparc64/lib/dec_and_lock.S
--- a/arch/sparc64/lib/dec_and_lock.S
+++ b/arch/sparc64/lib/dec_and_lock.S
@@ -48,8 +48,9 @@ start_to_zero:
 #endif
 to_zero:
 	ldstub	[%o1], %g3
+	membar	#StoreLoad | #StoreStore
 	brnz,pn	%g3, spin_on_lock
-	 membar	#StoreLoad | #StoreStore
+	 nop
 loop2:	cas	[%o0], %g2, %g7		/* ASSERT(g7 == 0) */
 	cmp	%g2, %g7
 
@@ -71,8 +72,9 @@ loop2:	cas	[%o0], %g2, %g7		/* ASSERT(g7
 	 nop
 spin_on_lock:
 	ldub	[%o1], %g3
+	membar	#LoadLoad
 	brnz,pt	%g3, spin_on_lock
-	 membar	#LoadLoad
+	 nop
 	ba,pt	%xcc, to_zero
 	 nop
 	nop
diff --git a/arch/sparc64/lib/delay.c b/arch/sparc64/lib/delay.c
--- a/arch/sparc64/lib/delay.c
+++ b/arch/sparc64/lib/delay.c
@@ -31,7 +31,7 @@ void __const_udelay(unsigned long n)
 {
 	n *= 4;
 
-	n *= (cpu_data(_smp_processor_id()).udelay_val * (HZ/4));
+	n *= (cpu_data(raw_smp_processor_id()).udelay_val * (HZ/4));
 	n >>= 32;
 
 	__delay(n + 1);
diff --git a/arch/sparc64/lib/rwsem.S b/arch/sparc64/lib/rwsem.S
--- a/arch/sparc64/lib/rwsem.S
+++ b/arch/sparc64/lib/rwsem.S
@@ -17,8 +17,9 @@ __down_read:
 	bne,pn		%icc, 1b
 	 add		%g7, 1, %g7
 	cmp		%g7, 0
+	membar		#StoreLoad | #StoreStore
 	bl,pn		%icc, 3f
-	 membar		#StoreLoad | #StoreStore
+	 nop
 2:
 	retl
 	 nop
@@ -57,8 +58,9 @@ __down_write:
 	cmp		%g3, %g7
 	bne,pn		%icc, 1b
 	 cmp		%g7, 0
+	membar		#StoreLoad | #StoreStore
 	bne,pn		%icc, 3f
-	 membar		#StoreLoad | #StoreStore
+	 nop
 2:	retl
 	 nop
 3:
@@ -97,8 +99,9 @@ __up_read:
 	cmp		%g1, %g7
 	bne,pn		%icc, 1b
 	 cmp		%g7, 0
+	membar		#StoreLoad | #StoreStore
 	bl,pn		%icc, 3f
-	 membar		#StoreLoad | #StoreStore
+	 nop
 2:	retl
 	 nop
 3:	sethi		%hi(RWSEM_ACTIVE_MASK), %g1
@@ -126,8 +129,9 @@ __up_write:
 	bne,pn		%icc, 1b
 	 sub		%g7, %g1, %g7
 	cmp		%g7, 0
+	membar		#StoreLoad | #StoreStore
 	bl,pn		%icc, 3f
-	 membar		#StoreLoad | #StoreStore
+	 nop
 2:
 	retl
 	 nop
@@ -151,8 +155,9 @@ __downgrade_write:
 	bne,pn		%icc, 1b
 	 sub		%g7, %g1, %g7
 	cmp		%g7, 0
+	membar		#StoreLoad | #StoreStore
 	bl,pn		%icc, 3f
-	 membar		#StoreLoad | #StoreStore
+	 nop
 2:
 	retl
 	 nop
diff --git a/arch/sparc64/mm/fault.c b/arch/sparc64/mm/fault.c
--- a/arch/sparc64/mm/fault.c
+++ b/arch/sparc64/mm/fault.c
@@ -34,22 +34,6 @@
 extern struct sparc_phys_banks sp_banks[SPARC_PHYS_BANKS];
 
 /*
- * To debug kernel during syscall entry.
- */
-void syscall_trace_entry(struct pt_regs *regs)
-{
-	printk("scall entry: %s[%d]/cpu%d: %d\n", current->comm, current->pid, smp_processor_id(), (int) regs->u_regs[UREG_G1]);
-}
-
-/*
- * To debug kernel during syscall exit.
- */
-void syscall_trace_exit(struct pt_regs *regs)
-{
-	printk("scall exit: %s[%d]/cpu%d: %d\n", current->comm, current->pid, smp_processor_id(), (int) regs->u_regs[UREG_G1]);
-}
-
-/*
  * To debug kernel to catch accesses to certain virtual/physical addresses.
  * Mode = 0 selects physical watchpoints, mode = 1 selects virtual watchpoints.
  * flags = VM_READ watches memread accesses, flags = VM_WRITE watches memwrite accesses.
diff --git a/arch/sparc64/mm/hugetlbpage.c b/arch/sparc64/mm/hugetlbpage.c
--- a/arch/sparc64/mm/hugetlbpage.c
+++ b/arch/sparc64/mm/hugetlbpage.c
@@ -22,7 +22,7 @@
 #include <asm/cacheflush.h>
 #include <asm/mmu_context.h>
 
-static pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr)
+pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr)
 {
 	pgd_t *pgd;
 	pud_t *pud;
@@ -41,7 +41,7 @@ static pte_t *huge_pte_alloc(struct mm_s
 	return pte;
 }
 
-static pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr)
+pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr)
 {
 	pgd_t *pgd;
 	pud_t *pud;
@@ -62,30 +62,34 @@ static pte_t *huge_pte_offset(struct mm_
 
 #define mk_pte_huge(entry) do { pte_val(entry) |= _PAGE_SZHUGE; } while (0)
 
-static void set_huge_pte(struct mm_struct *mm, struct vm_area_struct *vma,
-			 unsigned long addr,
-			 struct page *page, pte_t * page_table, int write_access)
+void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
+		     pte_t *ptep, pte_t entry)
 {
-	unsigned long i;
-	pte_t entry;
+	int i;
+
+	for (i = 0; i < (1 << HUGETLB_PAGE_ORDER); i++) {
+		set_pte_at(mm, addr, ptep, entry);
+		ptep++;
+		addr += PAGE_SIZE;
+		pte_val(entry) += PAGE_SIZE;
+	}
+}
 
-	add_mm_counter(mm, rss, HPAGE_SIZE / PAGE_SIZE);
+pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
+			      pte_t *ptep)
+{
+	pte_t entry;
+	int i;
 
-	if (write_access)
-		entry = pte_mkwrite(pte_mkdirty(mk_pte(page,
-						       vma->vm_page_prot)));
-	else
-		entry = pte_wrprotect(mk_pte(page, vma->vm_page_prot));
-	entry = pte_mkyoung(entry);
-	mk_pte_huge(entry);
+	entry = *ptep;
 
 	for (i = 0; i < (1 << HUGETLB_PAGE_ORDER); i++) {
-		set_pte_at(mm, addr, page_table, entry);
-		page_table++;
+		pte_clear(mm, addr, ptep);
 		addr += PAGE_SIZE;
-
-		pte_val(entry) += PAGE_SIZE;
+		ptep++;
 	}
+
+	return entry;
 }
 
 /*
@@ -100,79 +104,6 @@ int is_aligned_hugepage_range(unsigned l
 	return 0;
 }
 
-int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src,
-			    struct vm_area_struct *vma)
-{
-	pte_t *src_pte, *dst_pte, entry;
-	struct page *ptepage;
-	unsigned long addr = vma->vm_start;
-	unsigned long end = vma->vm_end;
-	int i;
-
-	while (addr < end) {
-		dst_pte = huge_pte_alloc(dst, addr);
-		if (!dst_pte)
-			goto nomem;
-		src_pte = huge_pte_offset(src, addr);
-		BUG_ON(!src_pte || pte_none(*src_pte));
-		entry = *src_pte;
-		ptepage = pte_page(entry);
-		get_page(ptepage);
-		for (i = 0; i < (1 << HUGETLB_PAGE_ORDER); i++) {
-			set_pte_at(dst, addr, dst_pte, entry);
-			pte_val(entry) += PAGE_SIZE;
-			dst_pte++;
-			addr += PAGE_SIZE;
-		}
-		add_mm_counter(dst, rss, HPAGE_SIZE / PAGE_SIZE);
-	}
-	return 0;
-
-nomem:
-	return -ENOMEM;
-}
-
-int follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma,
-			struct page **pages, struct vm_area_struct **vmas,
-			unsigned long *position, int *length, int i)
-{
-	unsigned long vaddr = *position;
-	int remainder = *length;
-
-	WARN_ON(!is_vm_hugetlb_page(vma));
-
-	while (vaddr < vma->vm_end && remainder) {
-		if (pages) {
-			pte_t *pte;
-			struct page *page;
-
-			pte = huge_pte_offset(mm, vaddr);
-
-			/* hugetlb should be locked, and hence, prefaulted */
-			BUG_ON(!pte || pte_none(*pte));
-
-			page = pte_page(*pte);
-
-			WARN_ON(!PageCompound(page));
-
-			get_page(page);
-			pages[i] = page;
-		}
-
-		if (vmas)
-			vmas[i] = vma;
-
-		vaddr += PAGE_SIZE;
-		--remainder;
-		++i;
-	}
-
-	*length = remainder;
-	*position = vaddr;
-
-	return i;
-}
-
 struct page *follow_huge_addr(struct mm_struct *mm,
 			      unsigned long address, int write)
 {
@@ -190,34 +121,6 @@ struct page *follow_huge_pmd(struct mm_s
 	return NULL;
 }
 
-void unmap_hugepage_range(struct vm_area_struct *vma,
-			  unsigned long start, unsigned long end)
-{
-	struct mm_struct *mm = vma->vm_mm;
-	unsigned long address;
-	pte_t *pte;
-	struct page *page;
-	int i;
-
-	BUG_ON(start & (HPAGE_SIZE - 1));
-	BUG_ON(end & (HPAGE_SIZE - 1));
-
-	for (address = start; address < end; address += HPAGE_SIZE) {
-		pte = huge_pte_offset(mm, address);
-		BUG_ON(!pte);
-		if (pte_none(*pte))
-			continue;
-		page = pte_page(*pte);
-		put_page(page);
-		for (i = 0; i < (1 << HUGETLB_PAGE_ORDER); i++) {
-			pte_clear(mm, address+(i*PAGE_SIZE), pte);
-			pte++;
-		}
-	}
-	add_mm_counter(mm, rss, -((end - start) >> PAGE_SHIFT));
-	flush_tlb_range(vma, start, end);
-}
-
 static void context_reload(void *__data)
 {
 	struct mm_struct *mm = __data;
@@ -226,12 +129,8 @@ static void context_reload(void *__data)
 		load_secondary_context(mm);
 }
 
-int hugetlb_prefault(struct address_space *mapping, struct vm_area_struct *vma)
+void hugetlb_prefault_arch_hook(struct mm_struct *mm)
 {
-	struct mm_struct *mm = current->mm;
-	unsigned long addr;
-	int ret = 0;
-
 	/* On UltraSPARC-III+ and later, configure the second half of
 	 * the Data-TLB for huge pages.
 	 */
@@ -261,50 +160,4 @@ int hugetlb_prefault(struct address_spac
 		}
 		spin_unlock(&ctx_alloc_lock);
 	}
-
-	BUG_ON(vma->vm_start & ~HPAGE_MASK);
-	BUG_ON(vma->vm_end & ~HPAGE_MASK);
-
-	spin_lock(&mm->page_table_lock);
-	for (addr = vma->vm_start; addr < vma->vm_end; addr += HPAGE_SIZE) {
-		unsigned long idx;
-		pte_t *pte = huge_pte_alloc(mm, addr);
-		struct page *page;
-
-		if (!pte) {
-			ret = -ENOMEM;
-			goto out;
-		}
-		if (!pte_none(*pte))
-			continue;
-
-		idx = ((addr - vma->vm_start) >> HPAGE_SHIFT)
-			+ (vma->vm_pgoff >> (HPAGE_SHIFT - PAGE_SHIFT));
-		page = find_get_page(mapping, idx);
-		if (!page) {
-			/* charge the fs quota first */
-			if (hugetlb_get_quota(mapping)) {
-				ret = -ENOMEM;
-				goto out;
-			}
-			page = alloc_huge_page();
-			if (!page) {
-				hugetlb_put_quota(mapping);
-				ret = -ENOMEM;
-				goto out;
-			}
-			ret = add_to_page_cache(page, mapping, idx, GFP_ATOMIC);
-			if (! ret) {
-				unlock_page(page);
-			} else {
-				hugetlb_put_quota(mapping);
-				free_huge_page(page);
-				goto out;
-			}
-		}
-		set_huge_pte(mm, vma, addr, page, pte, vma->vm_flags & VM_WRITE);
-	}
-out:
-	spin_unlock(&mm->page_table_lock);
-	return ret;
 }
diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c
--- a/arch/sparc64/mm/init.c
+++ b/arch/sparc64/mm/init.c
@@ -121,23 +121,33 @@ __inline__ void flush_dcache_page_impl(s
 }
 
 #define PG_dcache_dirty		PG_arch_1
+#define PG_dcache_cpu_shift	24
+#define PG_dcache_cpu_mask	(256 - 1)
+
+#if NR_CPUS > 256
+#error D-cache dirty tracking and thread_info->cpu need fixing for > 256 cpus
+#endif
 
 #define dcache_dirty_cpu(page) \
-	(((page)->flags >> 24) & (NR_CPUS - 1UL))
+	(((page)->flags >> PG_dcache_cpu_shift) & PG_dcache_cpu_mask)
 
 static __inline__ void set_dcache_dirty(struct page *page, int this_cpu)
 {
 	unsigned long mask = this_cpu;
-	unsigned long non_cpu_bits = ~((NR_CPUS - 1UL) << 24UL);
-	mask = (mask << 24) | (1UL << PG_dcache_dirty);
+	unsigned long non_cpu_bits;
+
+	non_cpu_bits = ~(PG_dcache_cpu_mask << PG_dcache_cpu_shift);
+	mask = (mask << PG_dcache_cpu_shift) | (1UL << PG_dcache_dirty);
+
 	__asm__ __volatile__("1:\n\t"
 			     "ldx	[%2], %%g7\n\t"
 			     "and	%%g7, %1, %%g1\n\t"
 			     "or	%%g1, %0, %%g1\n\t"
 			     "casx	[%2], %%g7, %%g1\n\t"
 			     "cmp	%%g7, %%g1\n\t"
+			     "membar	#StoreLoad | #StoreStore\n\t"
 			     "bne,pn	%%xcc, 1b\n\t"
-			     " membar	#StoreLoad | #StoreStore"
+			     " nop"
 			     : /* no outputs */
 			     : "r" (mask), "r" (non_cpu_bits), "r" (&page->flags)
 			     : "g1", "g7");
@@ -150,19 +160,21 @@ static __inline__ void clear_dcache_dirt
 	__asm__ __volatile__("! test_and_clear_dcache_dirty\n"
 			     "1:\n\t"
 			     "ldx	[%2], %%g7\n\t"
-			     "srlx	%%g7, 24, %%g1\n\t"
+			     "srlx	%%g7, %4, %%g1\n\t"
 			     "and	%%g1, %3, %%g1\n\t"
 			     "cmp	%%g1, %0\n\t"
 			     "bne,pn	%%icc, 2f\n\t"
 			     " andn	%%g7, %1, %%g1\n\t"
 			     "casx	[%2], %%g7, %%g1\n\t"
 			     "cmp	%%g7, %%g1\n\t"
+			     "membar	#StoreLoad | #StoreStore\n\t"
 			     "bne,pn	%%xcc, 1b\n\t"
-			     " membar	#StoreLoad | #StoreStore\n"
+			     " nop\n"
 			     "2:"
 			     : /* no outputs */
 			     : "r" (cpu), "r" (mask), "r" (&page->flags),
-			       "i" (NR_CPUS - 1UL)
+			       "i" (PG_dcache_cpu_mask),
+			       "i" (PG_dcache_cpu_shift)
 			     : "g1", "g7");
 }
 
@@ -178,7 +190,8 @@ void update_mmu_cache(struct vm_area_str
 	if (pfn_valid(pfn) &&
 	    (page = pfn_to_page(pfn), page_mapping(page)) &&
 	    ((pg_flags = page->flags) & (1UL << PG_dcache_dirty))) {
-		int cpu = ((pg_flags >> 24) & (NR_CPUS - 1UL));
+		int cpu = ((pg_flags >> PG_dcache_cpu_shift) &
+			   PG_dcache_cpu_mask);
 		int this_cpu = get_cpu();
 
 		/* This is just to optimize away some function calls
diff --git a/arch/sparc64/mm/ultra.S b/arch/sparc64/mm/ultra.S
--- a/arch/sparc64/mm/ultra.S
+++ b/arch/sparc64/mm/ultra.S
@@ -72,6 +72,7 @@ __flush_tlb_pending:
 	flush		%g6
 	retl
 	 wrpr		%g7, 0x0, %pstate
+	nop
 
 	.align		32
 	.globl		__flush_tlb_kernel_range
@@ -249,7 +250,7 @@ __cheetah_flush_tlb_mm: /* 15 insns */
 	retl
 	 wrpr		%g7, 0x0, %pstate
 
-__cheetah_flush_tlb_pending:	/* 22 insns */
+__cheetah_flush_tlb_pending:	/* 23 insns */
 	/* %o0 = context, %o1 = nr, %o2 = vaddrs[] */
 	rdpr		%pstate, %g7
 	sllx		%o1, 3, %o1
@@ -266,8 +267,9 @@ __cheetah_flush_tlb_pending:	/* 22 insns
 	 andn		%o3, 1, %o3
 	stxa		%g0, [%o3] ASI_IMMU_DEMAP
 2:	stxa		%g0, [%o3] ASI_DMMU_DEMAP	
+	membar		#Sync
 	brnz,pt		%o1, 1b
-	 membar		#Sync
+	 nop
 	stxa		%g2, [%o4] ASI_DMMU
 	flush		%g6
 	wrpr		%g0, 0, %tl
@@ -316,7 +318,7 @@ cheetah_patch_cachetlbops:
 	sethi		%hi(__cheetah_flush_tlb_pending), %o1
 	or		%o1, %lo(__cheetah_flush_tlb_pending), %o1
 	call		cheetah_patch_one
-	 mov		22, %o2
+	 mov		23, %o2
 
 #ifdef DCACHE_ALIASING_POSSIBLE
 	sethi		%hi(__flush_dcache_page), %o0
diff --git a/arch/sparc64/solaris/entry64.S b/arch/sparc64/solaris/entry64.S
--- a/arch/sparc64/solaris/entry64.S
+++ b/arch/sparc64/solaris/entry64.S
@@ -24,8 +24,9 @@
 
 	.text
 solaris_syscall_trace:
+	add		%sp, PTREGS_OFF, %o0
 	call		syscall_trace
-	 nop
+	 mov		0, %o1
 	srl		%i0, 0, %o0
 	mov		%i4, %o4
 	srl		%i1, 0, %o1
@@ -159,8 +160,10 @@ ret_from_solaris:
 	 stx		%l2, [%sp + PTREGS_OFF + PT_V9_TNPC] !npc = npc+4 
 
 solaris_syscall_trace2:
+	add		%sp, PTREGS_OFF, %o0
 	call		syscall_trace
-	 add		%l1, 0x4, %l2			/* npc = npc+4 */
+	 mov		1, %o1
+	add		%l1, 0x4, %l2			/* npc = npc+4 */
 	andcc		%l1, 1, %g0
 	bne,pn		%icc, 2b
 	 nop
diff --git a/arch/sparc64/solaris/socket.c b/arch/sparc64/solaris/socket.c
--- a/arch/sparc64/solaris/socket.c
+++ b/arch/sparc64/solaris/socket.c
@@ -16,6 +16,7 @@
 #include <linux/net.h>
 #include <linux/compat.h>
 #include <net/compat.h>
+#include <net/sock.h>
 
 #include <asm/uaccess.h>
 #include <asm/string.h>
@@ -297,119 +298,165 @@ asmlinkage int solaris_sendmsg(int fd, s
 {
 	struct socket *sock;
 	char address[MAX_SOCK_ADDR];
-	struct iovec iov[UIO_FASTIOV];
+	struct iovec iovstack[UIO_FASTIOV], *iov = iovstack;
 	unsigned char ctl[sizeof(struct cmsghdr) + 20];
 	unsigned char *ctl_buf = ctl;
-	struct msghdr kern_msg;
-	int err, total_len;
+	struct msghdr msg_sys;
+	int err, ctl_len, iov_size, total_len;
 
-	if(msghdr_from_user32_to_kern(&kern_msg, user_msg))
-		return -EFAULT;
-	if(kern_msg.msg_iovlen > UIO_MAXIOV)
-		return -EINVAL;
-	err = verify_compat_iovec(&kern_msg, iov, address, VERIFY_READ);
-	if (err < 0)
+	err = -EFAULT;
+	if (msghdr_from_user32_to_kern(&msg_sys, user_msg))
+		goto out;
+
+	sock = sockfd_lookup(fd, &err);
+	if (!sock)
 		goto out;
+
+	/* do not move before msg_sys is valid */
+	err = -EMSGSIZE;
+	if (msg_sys.msg_iovlen > UIO_MAXIOV)
+		goto out_put;
+
+	/* Check whether to allocate the iovec area*/
+	err = -ENOMEM;
+	iov_size = msg_sys.msg_iovlen * sizeof(struct iovec);
+	if (msg_sys.msg_iovlen > UIO_FASTIOV) {
+		iov = sock_kmalloc(sock->sk, iov_size, GFP_KERNEL);
+		if (!iov)
+			goto out_put;
+	}
+
+	err = verify_compat_iovec(&msg_sys, iov, address, VERIFY_READ);
+	if (err < 0)
+		goto out_freeiov;
 	total_len = err;
 
-	if(kern_msg.msg_controllen) {
-		struct sol_cmsghdr __user *ucmsg = kern_msg.msg_control;
+	err = -ENOBUFS;
+	if (msg_sys.msg_controllen > INT_MAX)
+		goto out_freeiov;
+
+	ctl_len = msg_sys.msg_controllen;
+	if (ctl_len) {
+		struct sol_cmsghdr __user *ucmsg = msg_sys.msg_control;
 		unsigned long *kcmsg;
 		compat_size_t cmlen;
 
-		if(kern_msg.msg_controllen > sizeof(ctl) &&
-		   kern_msg.msg_controllen <= 256) {
+		err = -EINVAL;
+		if (ctl_len <= sizeof(compat_size_t))
+			goto out_freeiov;
+
+		if (ctl_len > sizeof(ctl)) {
 			err = -ENOBUFS;
-			ctl_buf = kmalloc(kern_msg.msg_controllen, GFP_KERNEL);
-			if(!ctl_buf)
+			ctl_buf = kmalloc(ctl_len, GFP_KERNEL);
+			if (!ctl_buf)
 				goto out_freeiov;
 		}
 		__get_user(cmlen, &ucmsg->cmsg_len);
 		kcmsg = (unsigned long *) ctl_buf;
 		*kcmsg++ = (unsigned long)cmlen;
 		err = -EFAULT;
-		if(copy_from_user(kcmsg, &ucmsg->cmsg_level,
-				  kern_msg.msg_controllen - sizeof(compat_size_t)))
+		if (copy_from_user(kcmsg, &ucmsg->cmsg_level,
+				   ctl_len - sizeof(compat_size_t)))
 			goto out_freectl;
-		kern_msg.msg_control = ctl_buf;
+		msg_sys.msg_control = ctl_buf;
 	}
-	kern_msg.msg_flags = solaris_to_linux_msgflags(user_flags);
+	msg_sys.msg_flags = solaris_to_linux_msgflags(user_flags);
 
-	lock_kernel();
-	sock = sockfd_lookup(fd, &err);
-	if (sock != NULL) {
-		if (sock->file->f_flags & O_NONBLOCK)
-			kern_msg.msg_flags |= MSG_DONTWAIT;
-		err = sock_sendmsg(sock, &kern_msg, total_len);
-		sockfd_put(sock);
-	}
-	unlock_kernel();
+	if (sock->file->f_flags & O_NONBLOCK)
+		msg_sys.msg_flags |= MSG_DONTWAIT;
+	err = sock_sendmsg(sock, &msg_sys, total_len);
 
 out_freectl:
-	/* N.B. Use kfree here, as kern_msg.msg_controllen might change? */
-	if(ctl_buf != ctl)
-		kfree(ctl_buf);
+	if (ctl_buf != ctl)    
+		sock_kfree_s(sock->sk, ctl_buf, ctl_len);
 out_freeiov:
-	if(kern_msg.msg_iov != iov)
-		kfree(kern_msg.msg_iov);
-out:
+	if (iov != iovstack)
+		sock_kfree_s(sock->sk, iov, iov_size);
+out_put:
+	sockfd_put(sock);
+out:       
 	return err;
 }
 
 asmlinkage int solaris_recvmsg(int fd, struct sol_nmsghdr __user *user_msg, unsigned int user_flags)
 {
-	struct iovec iovstack[UIO_FASTIOV];
-	struct msghdr kern_msg;
-	char addr[MAX_SOCK_ADDR];
 	struct socket *sock;
+	struct iovec iovstack[UIO_FASTIOV];
 	struct iovec *iov = iovstack;
+	struct msghdr msg_sys;
+	unsigned long cmsg_ptr;
+	int err, iov_size, total_len, len;
+
+	/* kernel mode address */
+	char addr[MAX_SOCK_ADDR];
+
+	/* user mode address pointers */
 	struct sockaddr __user *uaddr;
 	int __user *uaddr_len;
-	unsigned long cmsg_ptr;
-	int err, total_len, len = 0;
 
-	if(msghdr_from_user32_to_kern(&kern_msg, user_msg))
+	if (msghdr_from_user32_to_kern(&msg_sys, user_msg))
 		return -EFAULT;
-	if(kern_msg.msg_iovlen > UIO_MAXIOV)
-		return -EINVAL;
 
-	uaddr = kern_msg.msg_name;
+	sock = sockfd_lookup(fd, &err);
+	if (!sock)
+		goto out;
+
+	err = -EMSGSIZE;
+	if (msg_sys.msg_iovlen > UIO_MAXIOV)
+		goto out_put;
+
+	/* Check whether to allocate the iovec area*/
+	err = -ENOMEM;
+	iov_size = msg_sys.msg_iovlen * sizeof(struct iovec);
+	if (msg_sys.msg_iovlen > UIO_FASTIOV) {
+		iov = sock_kmalloc(sock->sk, iov_size, GFP_KERNEL);
+		if (!iov)
+			goto out_put;
+	}
+
+	/*
+	 *	Save the user-mode address (verify_iovec will change the
+	 *	kernel msghdr to use the kernel address space)
+	 */
+	 
+	uaddr = (void __user *) msg_sys.msg_name;
 	uaddr_len = &user_msg->msg_namelen;
-	err = verify_compat_iovec(&kern_msg, iov, addr, VERIFY_WRITE);
+	err = verify_compat_iovec(&msg_sys, iov, addr, VERIFY_WRITE);
 	if (err < 0)
-		goto out;
+		goto out_freeiov;
 	total_len = err;
 
-	cmsg_ptr = (unsigned long) kern_msg.msg_control;
-	kern_msg.msg_flags = 0;
+	cmsg_ptr = (unsigned long) msg_sys.msg_control;
+	msg_sys.msg_flags = MSG_CMSG_COMPAT;
 
-	lock_kernel();
-	sock = sockfd_lookup(fd, &err);
-	if (sock != NULL) {
-		if (sock->file->f_flags & O_NONBLOCK)
-			user_flags |= MSG_DONTWAIT;
-		err = sock_recvmsg(sock, &kern_msg, total_len, user_flags);
-		if(err >= 0)
-			len = err;
-		sockfd_put(sock);
-	}
-	unlock_kernel();
+	if (sock->file->f_flags & O_NONBLOCK)
+		user_flags |= MSG_DONTWAIT;
 
-	if(uaddr != NULL && err >= 0)
-		err = move_addr_to_user(addr, kern_msg.msg_namelen, uaddr, uaddr_len);
-	if(err >= 0) {
-		err = __put_user(linux_to_solaris_msgflags(kern_msg.msg_flags), &user_msg->msg_flags);
-		if(!err) {
-			/* XXX Convert cmsg back into userspace 32-bit format... */
-			err = __put_user((unsigned long)kern_msg.msg_control - cmsg_ptr,
-					 &user_msg->msg_controllen);
-		}
+	err = sock_recvmsg(sock, &msg_sys, total_len, user_flags);
+	if(err < 0)
+		goto out_freeiov;
+
+	len = err;
+
+	if (uaddr != NULL) {
+		err = move_addr_to_user(addr, msg_sys.msg_namelen, uaddr, uaddr_len);
+		if (err < 0)
+			goto out_freeiov;
 	}
+	err = __put_user(linux_to_solaris_msgflags(msg_sys.msg_flags), &user_msg->msg_flags);
+	if (err)
+		goto out_freeiov;
+	err = __put_user((unsigned long)msg_sys.msg_control - cmsg_ptr,
+			 &user_msg->msg_controllen);
+	if (err)
+		goto out_freeiov;
+	err = len;
 
-	if(kern_msg.msg_iov != iov)
-		kfree(kern_msg.msg_iov);
+out_freeiov:
+	if (iov != iovstack)
+		sock_kfree_s(sock->sk, iov, iov_size);
+out_put:
+	sockfd_put(sock);
 out:
-	if(err < 0)
-		return err;
-	return len;
+	return err;
 }
diff --git a/arch/um/Kconfig b/arch/um/Kconfig
--- a/arch/um/Kconfig
+++ b/arch/um/Kconfig
@@ -35,6 +35,11 @@ config GENERIC_CALIBRATE_DELAY
 	bool
 	default y
 
+# Used in kernel/irq/manage.c and include/linux/irq.h
+config IRQ_RELEASE_METHOD
+	bool
+	default y
+
 menu "UML-specific options"
 
 config MODE_TT
@@ -69,6 +74,7 @@ config MODE_SKAS
 	option will shrink the UML binary slightly.
 
 source "arch/um/Kconfig_arch"
+source "mm/Kconfig"
 
 config LD_SCRIPT_STATIC
 	bool
@@ -122,7 +128,6 @@ config HOSTFS
 
 config HPPFS
 	tristate "HoneyPot ProcFS (EXPERIMENTAL)"
-	depends on BROKEN
 	help
 	hppfs (HoneyPot ProcFS) is a filesystem which allows UML /proc
 	entries to be overridden, removed, or fabricated from the host.
@@ -135,8 +140,9 @@ config HPPFS
 	You only need this if you are setting up a UML honeypot.  Otherwise,
 	it is safe to say 'N' here.
 
-	If you are actively using it, please ask for it to be fixed. In this
-	moment, it does not work on 2.6 (it works somehow on 2.4).
+	If you are actively using it, please report any problems, since it's
+	getting fixed. In this moment, it is experimental on 2.6 (it works on
+	2.4).
 
 config MCONSOLE
 	bool "Management console"
@@ -269,6 +275,8 @@ endmenu
 
 source "init/Kconfig"
 
+source "net/Kconfig"
+
 source "drivers/base/Kconfig"
 
 source "arch/um/Kconfig_char"
@@ -281,7 +289,7 @@ config NETDEVICES
 
 source "arch/um/Kconfig_net"
 
-source "net/Kconfig"
+source "drivers/net/Kconfig"
 
 source "fs/Kconfig"
 
diff --git a/arch/um/Kconfig_i386 b/arch/um/Kconfig_i386
--- a/arch/um/Kconfig_i386
+++ b/arch/um/Kconfig_i386
@@ -19,6 +19,18 @@ config 3_LEVEL_PGTABLES
 	memory.  All the memory that can't be mapped directly will be treated
 	as high memory.
 
+config STUB_CODE
+	hex
+	default 0xbfffe000
+
+config STUB_DATA
+	hex
+	default 0xbffff000
+
+config STUB_START
+	hex
+	default STUB_CODE
+
 config ARCH_HAS_SC_SIGNALS
 	bool
 	default y
diff --git a/arch/um/Kconfig_net b/arch/um/Kconfig_net
--- a/arch/um/Kconfig_net
+++ b/arch/um/Kconfig_net
@@ -135,7 +135,7 @@ config UML_NET_MCAST
 
 config UML_NET_PCAP
 	bool "pcap transport"
-	depends on UML_NET && BROKEN
+	depends on UML_NET && EXPERIMENTAL
 	help
 	The pcap transport makes a pcap packet stream on the host look
 	like an ethernet device inside UML.  This is useful for making 
diff --git a/arch/um/Kconfig_x86_64 b/arch/um/Kconfig_x86_64
--- a/arch/um/Kconfig_x86_64
+++ b/arch/um/Kconfig_x86_64
@@ -14,6 +14,18 @@ config 3_LEVEL_PGTABLES
        bool
        default y
 
+config STUB_CODE
+	hex
+	default 0x7fbfffe000
+
+config STUB_DATA
+	hex
+	default 0x7fbffff000
+
+config STUB_START
+	hex
+	default STUB_CODE
+
 config ARCH_HAS_SC_SIGNALS
 	bool
 	default n
diff --git a/arch/um/Makefile b/arch/um/Makefile
--- a/arch/um/Makefile
+++ b/arch/um/Makefile
@@ -51,25 +51,26 @@ MRPROPER_DIRS	+= $(ARCH_DIR)/include2
 endif
 SYS_DIR		:= $(ARCH_DIR)/include/sysdep-$(SUBARCH)
 
-include $(srctree)/$(ARCH_DIR)/Makefile-$(SUBARCH)
+# -Dvmap=kernel_vmap affects everything, and prevents anything from
+# referencing the libpcap.o symbol so named.
+
+CFLAGS += $(CFLAGS-y) -D__arch_um__ -DSUBARCH=\"$(SUBARCH)\" \
+	$(ARCH_INCLUDE) $(MODE_INCLUDE) -Dvmap=kernel_vmap
 
-core-y += $(SUBARCH_CORE)
-libs-y += $(SUBARCH_LIBS)
+USER_CFLAGS := $(patsubst -I%,,$(CFLAGS))
+USER_CFLAGS := $(patsubst -D__KERNEL__,,$(USER_CFLAGS)) $(ARCH_INCLUDE) \
+	$(MODE_INCLUDE)
 
 # -Derrno=kernel_errno - This turns all kernel references to errno into
 # kernel_errno to separate them from the libc errno.  This allows -fno-common
 # in CFLAGS.  Otherwise, it would cause ld to complain about the two different
 # errnos.
 
-CFLAGS += $(CFLAGS-y) -D__arch_um__ -DSUBARCH=\"$(SUBARCH)\" \
-	$(ARCH_INCLUDE) $(MODE_INCLUDE)
-
-USER_CFLAGS := $(patsubst -I%,,$(CFLAGS))
-USER_CFLAGS := $(patsubst -D__KERNEL__,,$(USER_CFLAGS)) $(ARCH_INCLUDE) \
-	$(MODE_INCLUDE) $(ARCH_USER_CFLAGS)
 CFLAGS += -Derrno=kernel_errno -Dsigprocmask=kernel_sigprocmask
 CFLAGS += $(call cc-option,-fno-unit-at-a-time,)
 
+include $(srctree)/$(ARCH_DIR)/Makefile-$(SUBARCH)
+
 #This will adjust *FLAGS accordingly to the platform.
 include $(srctree)/$(ARCH_DIR)/Makefile-os-$(OS)
 
@@ -116,18 +117,19 @@ CONFIG_KERNEL_STACK_ORDER ?= 2
 STACK_SIZE := $(shell echo $$[ 4096 * (1 << $(CONFIG_KERNEL_STACK_ORDER)) ] )
 
 ifndef START
-  START = $$(($(TOP_ADDR) - $(SIZE)))
+  START = $(shell echo $$[ $(TOP_ADDR) - $(SIZE) ] )
 endif
 
-CPPFLAGS_vmlinux.lds = $(shell echo -U$(SUBARCH) \
+CPPFLAGS_vmlinux.lds = -U$(SUBARCH) \
 	-DSTART=$(START) -DELF_ARCH=$(ELF_ARCH) \
-	-DELF_FORMAT=\"$(ELF_FORMAT)\" $(CPP_MODE-y) \
-	-DKERNEL_STACK_SIZE=$(STACK_SIZE))
+	-DELF_FORMAT="$(ELF_FORMAT)" $(CPP_MODE-y) \
+	-DKERNEL_STACK_SIZE=$(STACK_SIZE) \
+	-DUNMAP_PATH=arch/um/sys-$(SUBARCH)/unmap_fin.o
 
 #The wrappers will select whether using "malloc" or the kernel allocator.
 LINK_WRAPS = -Wl,--wrap,malloc -Wl,--wrap,free -Wl,--wrap,calloc
 
-CFLAGS_vmlinux = $(LINK-y) $(LINK_WRAPS)
+CFLAGS_vmlinux := $(LINK-y) $(LINK_WRAPS)
 define cmd_vmlinux__
 	$(CC) $(CFLAGS_vmlinux) -o $@ \
 	-Wl,-T,$(vmlinux-lds) $(vmlinux-init) \
@@ -140,7 +142,8 @@ endef
 #When cleaning we don't include .config, so we don't include
 #TT or skas makefiles and don't clean skas_ptregs.h.
 CLEAN_FILES += linux x.i gmon.out $(ARCH_DIR)/include/uml-config.h \
-	$(GEN_HEADERS) $(ARCH_DIR)/include/skas_ptregs.h
+	$(GEN_HEADERS) $(ARCH_DIR)/include/skas_ptregs.h \
+	$(ARCH_DIR)/include/user_constants.h
 
 MRPROPER_FILES += $(SYMLINK_HEADERS) $(ARCH_SYMLINKS) \
 	$(addprefix $(ARCH_DIR)/kernel/,$(KERN_SYMLINKS)) $(ARCH_DIR)/os \
@@ -242,7 +245,7 @@ $(ARCH_DIR)/util: scripts_basic $(SYS_DI
 $(ARCH_DIR)/kernel/skas/util: scripts_basic $(ARCH_DIR)/user-offsets.h FORCE
 	$(Q)$(MAKE) $(build)=$@
 
-$(ARCH_DIR)/os-$(OS)/util: scripts_basic FORCE
+$(ARCH_DIR)/os-$(OS)/util: scripts_basic $(ARCH_DIR)/user-offsets.h FORCE
 	$(Q)$(MAKE) $(build)=$@
 
 export SUBARCH USER_CFLAGS OS
diff --git a/arch/um/Makefile-i386 b/arch/um/Makefile-i386
--- a/arch/um/Makefile-i386
+++ b/arch/um/Makefile-i386
@@ -1,4 +1,4 @@
-SUBARCH_CORE := arch/um/sys-i386/ arch/i386/crypto/
+core-y += arch/um/sys-i386/ arch/i386/crypto/
 
 TOP_ADDR := $(CONFIG_TOP_ADDR)
 
@@ -8,21 +8,33 @@ ifeq ($(CONFIG_MODE_SKAS),y)
   endif
 endif
 
-CFLAGS += -U__$(SUBARCH)__ -U$(SUBARCH)
-ARCH_USER_CFLAGS :=
+LDFLAGS			+= -m elf_i386
+ELF_ARCH		:= $(SUBARCH)
+ELF_FORMAT 		:= elf32-$(SUBARCH)
+OBJCOPYFLAGS  		:= -O binary -R .note -R .comment -S
+
+ifeq ("$(origin SUBARCH)", "command line")
+ifneq ("$(shell uname -m | sed -e s/i.86/i386/)", "$(SUBARCH)")
+CFLAGS			+= $(call cc-option,-m32)
+USER_CFLAGS		+= $(call cc-option,-m32)
+HOSTCFLAGS		+= $(call cc-option,-m32)
+HOSTLDFLAGS		+= $(call cc-option,-m32)
+AFLAGS			+= $(call cc-option,-m32)
+LINK-y			+= $(call cc-option,-m32)
+UML_OBJCOPYFLAGS	+= -F $(ELF_FORMAT)
 
-ifneq ($(CONFIG_GPROF),y)
-ARCH_CFLAGS += -DUM_FASTCALL
+export LDFLAGS HOSTCFLAGS HOSTLDFLAGS UML_OBJCOPYFLAGS
+endif
 endif
 
-ELF_ARCH := $(SUBARCH)
-ELF_FORMAT := elf32-$(SUBARCH)
+CFLAGS += -U__$(SUBARCH)__ -U$(SUBARCH) $(STUB_CFLAGS)
 
-OBJCOPYFLAGS  := -O binary -R .note -R .comment -S
+ifneq ($(CONFIG_GPROF),y)
+ARCH_CFLAGS += -DUM_FASTCALL
+endif
 
 SYS_UTIL_DIR	:= $(ARCH_DIR)/sys-i386/util
-
-SYS_HEADERS := $(SYS_DIR)/sc.h $(SYS_DIR)/thread.h
+SYS_HEADERS	:= $(SYS_DIR)/sc.h $(SYS_DIR)/thread.h
 
 prepare: $(SYS_HEADERS)
 
diff --git a/arch/um/Makefile-x86_64 b/arch/um/Makefile-x86_64
--- a/arch/um/Makefile-x86_64
+++ b/arch/um/Makefile-x86_64
@@ -1,11 +1,13 @@
 # Copyright 2003 - 2004 Pathscale, Inc
 # Released under the GPL
 
-SUBARCH_LIBS := arch/um/sys-x86_64/
+libs-y += arch/um/sys-x86_64/
 START := 0x60000000
 
-CFLAGS += -U__$(SUBARCH)__ -fno-builtin
-ARCH_USER_CFLAGS := -D__x86_64__
+#We #undef __x86_64__ for kernelspace, not for userspace where
+#it's needed for headers to work!
+CFLAGS += -U__$(SUBARCH)__ -fno-builtin $(STUB_CFLAGS)
+USER_CFLAGS += -fno-builtin
 
 ELF_ARCH := i386:x86-64
 ELF_FORMAT := elf64-x86-64
diff --git a/arch/um/defconfig b/arch/um/defconfig
--- a/arch/um/defconfig
+++ b/arch/um/defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc3-skas3-v9-pre2
-# Sun Apr 24 19:46:10 2005
+# Linux kernel version: 2.6.12-rc6-mm1
+# Tue Jun 14 18:22:21 2005
 #
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_UML=y
@@ -13,23 +13,32 @@ CONFIG_GENERIC_CALIBRATE_DELAY=y
 #
 # UML-specific options
 #
-CONFIG_MODE_TT=y
+# CONFIG_MODE_TT is not set
+# CONFIG_STATIC_LINK is not set
 CONFIG_MODE_SKAS=y
 CONFIG_UML_X86=y
 # CONFIG_64BIT is not set
 CONFIG_TOP_ADDR=0xc0000000
 # CONFIG_3_LEVEL_PGTABLES is not set
+CONFIG_STUB_CODE=0xbfffe000
+CONFIG_STUB_DATA=0xbffff000
+CONFIG_STUB_START=0xbfffe000
 CONFIG_ARCH_HAS_SC_SIGNALS=y
 CONFIG_ARCH_REUSE_HOST_VSYSCALL_AREA=y
-CONFIG_LD_SCRIPT_STATIC=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_LD_SCRIPT_DYN=y
 CONFIG_NET=y
 CONFIG_BINFMT_ELF=y
 CONFIG_BINFMT_MISC=m
-CONFIG_HOSTFS=y
+# CONFIG_HOSTFS is not set
 CONFIG_MCONSOLE=y
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_HOST_2G_2G is not set
-# CONFIG_SMP is not set
 CONFIG_NEST_LEVEL=0
 CONFIG_KERNEL_HALF_GIGS=1
 # CONFIG_HIGHMEM is not set
@@ -63,6 +72,8 @@ CONFIG_IKCONFIG_PROC=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 CONFIG_KALLSYMS_EXTRA_PASS=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
@@ -81,6 +92,7 @@ CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_FORCE_UNLOAD is not set
 CONFIG_OBSOLETE_MODPARM=y
+# CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_KMOD=y
 
@@ -115,6 +127,7 @@ CONFIG_UML_SOUND=m
 CONFIG_SOUND=m
 CONFIG_HOSTAUDIO=m
 CONFIG_UML_RANDOM=y
+# CONFIG_MMAPPER is not set
 
 #
 # Block devices
@@ -176,6 +189,17 @@ CONFIG_INET=y
 # CONFIG_INET_TUNNEL is not set
 CONFIG_IP_TCPDIAG=y
 # CONFIG_IP_TCPDIAG_IPV6 is not set
+
+#
+# TCP congestion control
+#
+CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_WESTWOOD=y
+CONFIG_TCP_CONG_HTCP=y
+# CONFIG_TCP_CONG_HSTCP is not set
+# CONFIG_TCP_CONG_HYBLA is not set
+# CONFIG_TCP_CONG_VEGAS is not set
+# CONFIG_TCP_CONG_SCALABLE is not set
 # CONFIG_IPV6 is not set
 # CONFIG_NETFILTER is not set
 
@@ -206,11 +230,15 @@ CONFIG_IP_TCPDIAG=y
 # Network testing
 #
 # CONFIG_NET_PKTGEN is not set
+# CONFIG_KGDBOE is not set
 # CONFIG_NETPOLL is not set
+# CONFIG_NETPOLL_RX is not set
+# CONFIG_NETPOLL_TRAP is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
 # CONFIG_HAMRADIO is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
 CONFIG_DUMMY=m
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
@@ -227,6 +255,7 @@ CONFIG_PPP=m
 # CONFIG_PPP_SYNC_TTY is not set
 # CONFIG_PPP_DEFLATE is not set
 # CONFIG_PPP_BSDCOMP is not set
+# CONFIG_PPP_MPPE is not set
 # CONFIG_PPPOE is not set
 CONFIG_SLIP=m
 # CONFIG_SLIP_COMPRESSED is not set
@@ -240,10 +269,12 @@ CONFIG_SLIP=m
 #
 CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
 CONFIG_EXT3_FS=y
 # CONFIG_EXT3_FS_XATTR is not set
 CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
+# CONFIG_REISER4_FS is not set
 CONFIG_REISERFS_FS=y
 # CONFIG_REISERFS_CHECK is not set
 # CONFIG_REISERFS_PROC_INFO is not set
@@ -256,6 +287,7 @@ CONFIG_REISERFS_FS=y
 # CONFIG_XFS_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
 CONFIG_QUOTA=y
 # CONFIG_QFMT_V1 is not set
 # CONFIG_QFMT_V2 is not set
@@ -265,6 +297,12 @@ CONFIG_AUTOFS_FS=m
 CONFIG_AUTOFS4_FS=m
 
 #
+# Caches
+#
+# CONFIG_FSCACHE is not set
+# CONFIG_FUSE_FS is not set
+
+#
 # CD-ROM/DVD Filesystems
 #
 CONFIG_ISO9660_FS=m
@@ -291,6 +329,8 @@ CONFIG_TMPFS=y
 # CONFIG_TMPFS_XATTR is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
+# CONFIG_RELAYFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -319,6 +359,7 @@ CONFIG_RAMFS=y
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
 
 #
 # Partition Types
@@ -404,14 +445,15 @@ CONFIG_CRC32=m
 # CONFIG_PRINTK_TIME is not set
 CONFIG_DEBUG_KERNEL=y
 CONFIG_LOG_BUF_SHIFT=14
+CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_SCHEDSTATS is not set
-# CONFIG_DEBUG_SLAB is not set
+CONFIG_DEBUG_SLAB=y
 # CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_KOBJECT is not set
 CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_FS is not set
 CONFIG_FRAME_POINTER=y
-CONFIG_PT_PROXY=y
+# CONFIG_GPROF is not set
 # CONFIG_GCOV is not set
 # CONFIG_SYSCALL_DEBUG is not set
diff --git a/arch/um/drivers/Makefile b/arch/um/drivers/Makefile
--- a/arch/um/drivers/Makefile
+++ b/arch/um/drivers/Makefile
@@ -10,7 +10,6 @@ slip-objs := slip_kern.o slip_user.o
 slirp-objs := slirp_kern.o slirp_user.o
 daemon-objs := daemon_kern.o daemon_user.o
 mcast-objs := mcast_kern.o mcast_user.o
-#pcap-objs := pcap_kern.o pcap_user.o $(PCAP)
 net-objs := net_kern.o net_user.o
 mconsole-objs := mconsole_kern.o mconsole_user.o
 hostaudio-objs := hostaudio_kern.o
@@ -18,6 +17,19 @@ ubd-objs := ubd_kern.o ubd_user.o
 port-objs := port_kern.o port_user.o
 harddog-objs := harddog_kern.o harddog_user.o
 
+LDFLAGS_pcap.o := -r $(shell $(CC) $(CFLAGS) -print-file-name=libpcap.a)
+
+targets := pcap_kern.o pcap_user.o
+
+$(obj)/pcap.o: $(obj)/pcap_kern.o $(obj)/pcap_user.o
+	$(LD) -r -dp -o $@ $^ $(LDFLAGS) $(LDFLAGS_pcap.o)
+#XXX: The call below does not work because the flags are added before the
+# object name, so nothing from the library gets linked.
+#$(call if_changed,ld)
+
+# When the above is fixed, don't forget to add this too!
+#targets += $(obj)/pcap.o
+
 obj-y := stdio_console.o fd.o chan_kern.o chan_user.o line.o
 obj-$(CONFIG_SSL) += ssl.o
 obj-$(CONFIG_STDERR_CONSOLE) += stderr_console.o
@@ -26,7 +38,7 @@ obj-$(CONFIG_UML_NET_SLIP) += slip.o sli
 obj-$(CONFIG_UML_NET_SLIRP) += slirp.o slip_common.o
 obj-$(CONFIG_UML_NET_DAEMON) += daemon.o 
 obj-$(CONFIG_UML_NET_MCAST) += mcast.o 
-#obj-$(CONFIG_UML_NET_PCAP) += pcap.o $(PCAP)
+obj-$(CONFIG_UML_NET_PCAP) += pcap.o
 obj-$(CONFIG_UML_NET) += net.o 
 obj-$(CONFIG_MCONSOLE) += mconsole.o
 obj-$(CONFIG_MMAPPER) += mmapper_kern.o 
@@ -41,6 +53,7 @@ obj-$(CONFIG_UML_WATCHDOG) += harddog.o
 obj-$(CONFIG_BLK_DEV_COW_COMMON) += cow_user.o
 obj-$(CONFIG_UML_RANDOM) += random.o
 
-USER_OBJS := fd.o null.o pty.o tty.o xterm.o slip_common.o
+# pcap_user.o must be added explicitly.
+USER_OBJS := fd.o null.o pty.o tty.o xterm.o slip_common.o pcap_user.o
 
 include arch/um/scripts/Makefile.rules
diff --git a/arch/um/drivers/cow.h b/arch/um/drivers/cow.h
--- a/arch/um/drivers/cow.h
+++ b/arch/um/drivers/cow.h
@@ -3,10 +3,10 @@
 
 #include <asm/types.h>
 
-#if __BYTE_ORDER == __BIG_ENDIAN
+#if defined(__BIG_ENDIAN)
 # define ntohll(x) (x)
 # define htonll(x) (x)
-#elif __BYTE_ORDER == __LITTLE_ENDIAN
+#elif defined(__LITTLE_ENDIAN)
 # define ntohll(x)  bswap_64(x)
 # define htonll(x)  bswap_64(x)
 #else
diff --git a/arch/um/drivers/daemon_user.c b/arch/um/drivers/daemon_user.c
--- a/arch/um/drivers/daemon_user.c
+++ b/arch/um/drivers/daemon_user.c
@@ -157,9 +157,9 @@ static void daemon_remove(void *data)
 
 	os_close_file(pri->fd);
 	os_close_file(pri->control);
-	if(pri->data_addr != NULL) kfree(pri->data_addr);
-	if(pri->ctl_addr != NULL) kfree(pri->ctl_addr);
-	if(pri->local_addr != NULL) kfree(pri->local_addr);
+	kfree(pri->data_addr);
+	kfree(pri->ctl_addr);
+	kfree(pri->local_addr);
 }
 
 int daemon_user_write(int fd, void *buf, int len, struct daemon_data *pri)
diff --git a/arch/um/drivers/hostaudio_kern.c b/arch/um/drivers/hostaudio_kern.c
--- a/arch/um/drivers/hostaudio_kern.c
+++ b/arch/um/drivers/hostaudio_kern.c
@@ -57,10 +57,10 @@ __uml_setup("mixer=", set_mixer, "mixer=
 
 #else /*MODULE*/
 
-MODULE_PARM(dsp, "s");
+module_param(dsp, charp, 0644);
 MODULE_PARM_DESC(dsp, DSP_HELP);
 
-MODULE_PARM(mixer, "s");
+module_param(mixer, charp, 0644);
 MODULE_PARM_DESC(mixer, MIXER_HELP);
 
 #endif
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c
--- a/arch/um/drivers/line.c
+++ b/arch/um/drivers/line.c
@@ -406,14 +406,12 @@ void line_disable(struct tty_struct *tty
 	if(line->driver->read_irq == current_irq)
 		free_irq_later(line->driver->read_irq, tty);
 	else {
-		free_irq_by_irq_and_dev(line->driver->read_irq, tty);
 		free_irq(line->driver->read_irq, tty);
 	}
 
 	if(line->driver->write_irq == current_irq)
 		free_irq_later(line->driver->write_irq, tty);
 	else {
-		free_irq_by_irq_and_dev(line->driver->write_irq, tty);
 		free_irq(line->driver->write_irq, tty);
 	}
 
@@ -604,11 +602,26 @@ int line_get_config(char *name, struct l
 	return n;
 }
 
-int line_remove(struct line *lines, unsigned int num, char *str)
+int line_id(char **str, int *start_out, int *end_out)
+{
+	char *end;
+        int n;
+
+	n = simple_strtoul(*str, &end, 0);
+	if((*end != '\0') || (end == *str))
+                return -1;
+
+        *str = end;
+        *start_out = n;
+        *end_out = n;
+        return n;
+}
+
+int line_remove(struct line *lines, unsigned int num, int n)
 {
 	char config[sizeof("conxxxx=none\0")];
 
-	sprintf(config, "%s=none", str);
+	sprintf(config, "%d=none", n);
 	return !line_setup(lines, num, config, 0);
 }
 
@@ -650,11 +663,15 @@ struct tty_driver *line_register_devfs(s
 	return driver;
 }
 
+static spinlock_t winch_handler_lock;
+LIST_HEAD(winch_handlers);
+
 void lines_init(struct line *lines, int nlines)
 {
 	struct line *line;
 	int i;
 
+	spin_lock_init(&winch_handler_lock);
 	for(i = 0; i < nlines; i++){
 		line = &lines[i];
 		INIT_LIST_HEAD(&line->chan_list);
@@ -711,31 +728,30 @@ irqreturn_t winch_interrupt(int irq, voi
 	return IRQ_HANDLED;
 }
 
-DECLARE_MUTEX(winch_handler_sem);
-LIST_HEAD(winch_handlers);
-
 void register_winch_irq(int fd, int tty_fd, int pid, struct tty_struct *tty)
 {
 	struct winch *winch;
 
-	down(&winch_handler_sem);
 	winch = kmalloc(sizeof(*winch), GFP_KERNEL);
 	if (winch == NULL) {
 		printk("register_winch_irq - kmalloc failed\n");
-		goto out;
+		return;
 	}
+
 	*winch = ((struct winch) { .list  	= LIST_HEAD_INIT(winch->list),
 				   .fd  	= fd,
 				   .tty_fd 	= tty_fd,
 				   .pid  	= pid,
 				   .tty 	= tty });
+
+	spin_lock(&winch_handler_lock);
 	list_add(&winch->list, &winch_handlers);
+	spin_unlock(&winch_handler_lock);
+
 	if(um_request_irq(WINCH_IRQ, fd, IRQ_READ, winch_interrupt,
 			  SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM, 
 			  "winch", winch) < 0)
 		printk("register_winch_irq - failed to register IRQ\n");
- out:
-	up(&winch_handler_sem);
 }
 
 static void unregister_winch(struct tty_struct *tty)
@@ -743,7 +759,7 @@ static void unregister_winch(struct tty_
 	struct list_head *ele;
 	struct winch *winch, *found = NULL;
 
-	down(&winch_handler_sem);
+	spin_lock(&winch_handler_lock);
 	list_for_each(ele, &winch_handlers){
 		winch = list_entry(ele, struct winch, list);
                 if(winch->tty == tty){
@@ -751,21 +767,25 @@ static void unregister_winch(struct tty_
                         break;
                 }
         }
-
         if(found == NULL)
-                goto out;
+		goto err;
+
+	list_del(&winch->list);
+	spin_unlock(&winch_handler_lock);
 
         if(winch->pid != -1)
                 os_kill_process(winch->pid, 1);
 
-        free_irq_by_irq_and_dev(WINCH_IRQ, winch);
         free_irq(WINCH_IRQ, winch);
-        list_del(&winch->list);
         kfree(winch);
- out:
-	up(&winch_handler_sem);
+
+	return;
+err:
+	spin_unlock(&winch_handler_lock);
 }
 
+/* XXX: No lock as it's an exitcall... is this valid? Depending on cleanup
+ * order... are we sure that nothing else is done on the list? */
 static void winch_cleanup(void)
 {
 	struct list_head *ele;
@@ -774,6 +794,9 @@ static void winch_cleanup(void)
 	list_for_each(ele, &winch_handlers){
 		winch = list_entry(ele, struct winch, list);
 		if(winch->fd != -1){
+			/* Why is this different from the above free_irq(),
+			 * which deactivates SIGIO? This searches the FD
+			 * somewhere else and removes it from the list... */
 			deactivate_fd(winch->fd, WINCH_IRQ);
 			os_close_file(winch->fd);
 		}
diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c
--- a/arch/um/drivers/mconsole_kern.c
+++ b/arch/um/drivers/mconsole_kern.c
@@ -419,8 +419,9 @@ void mconsole_config(struct mc_request *
 void mconsole_remove(struct mc_request *req)
 {
 	struct mc_device *dev;	
-	char *ptr = req->request.data;
-	int err;
+	char *ptr = req->request.data, *err_msg = "";
+        char error[256];
+	int err, start, end, n;
 
 	ptr += strlen("remove");
 	while(isspace(*ptr)) ptr++;
@@ -429,8 +430,35 @@ void mconsole_remove(struct mc_request *
 		mconsole_reply(req, "Bad remove option", 1, 0);
 		return;
 	}
-	err = (*dev->remove)(&ptr[strlen(dev->name)]);
-	mconsole_reply(req, "", err, 0);
+
+        ptr = &ptr[strlen(dev->name)];
+
+        err = 1;
+        n = (*dev->id)(&ptr, &start, &end);
+        if(n < 0){
+                err_msg = "Couldn't parse device number";
+                goto out;
+        }
+        else if((n < start) || (n > end)){
+                sprintf(error, "Invalid device number - must be between "
+                        "%d and %d", start, end);
+                err_msg = error;
+                goto out;
+        }
+
+	err = (*dev->remove)(n);
+        switch(err){
+        case -ENODEV:
+                err_msg = "Device doesn't exist";
+                break;
+        case -EBUSY:
+                err_msg = "Device is currently open";
+                break;
+        default:
+                break;
+        }
+ out:
+	mconsole_reply(req, err_msg, err, 0);
 }
 
 #ifdef CONFIG_MAGIC_SYSRQ
@@ -529,7 +557,7 @@ static int create_proc_mconsole(void)
 
 	ent = create_proc_entry("mconsole", S_IFREG | 0200, NULL);
 	if(ent == NULL){
-		printk("create_proc_mconsole : create_proc_entry failed\n");
+		printk(KERN_INFO "create_proc_mconsole : create_proc_entry failed\n");
 		return(0);
 	}
 
diff --git a/arch/um/drivers/mmapper_kern.c b/arch/um/drivers/mmapper_kern.c
--- a/arch/um/drivers/mmapper_kern.c
+++ b/arch/um/drivers/mmapper_kern.c
@@ -9,19 +9,11 @@
  *
  */
 
-#include <linux/types.h>
-#include <linux/kdev_t.h>
-#include <linux/time.h>
-#include <linux/devfs_fs_kernel.h>
+#include <linux/init.h> 
 #include <linux/module.h>
 #include <linux/mm.h> 
-#include <linux/slab.h>
-#include <linux/init.h> 
-#include <linux/smp_lock.h>
 #include <linux/miscdevice.h>
 #include <asm/uaccess.h>
-#include <asm/irq.h>
-#include <asm/pgtable.h>
 #include "mem_user.h"
 #include "user_util.h"
  
@@ -31,35 +23,22 @@ static unsigned long p_buf = 0;
 static char *v_buf = NULL;
 
 static ssize_t
-mmapper_read(struct file *file, char *buf, size_t count, loff_t *ppos)
+mmapper_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
 {
-	if(*ppos > mmapper_size)
-		return -EINVAL;
-
-	if(count + *ppos > mmapper_size)
-		count = count + *ppos - mmapper_size;
-
-	if(count < 0)
-		return -EINVAL;
- 
-	copy_to_user(buf,&v_buf[*ppos],count);
-	
-	return count;
+	return simple_read_from_buffer(buf, count, ppos, v_buf, mmapper_size);
 }
 
 static ssize_t
-mmapper_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
+mmapper_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
 {
-	if(*ppos > mmapper_size)
+	if (*ppos > mmapper_size)
 		return -EINVAL;
 
-	if(count + *ppos > mmapper_size)
-		count = count + *ppos - mmapper_size;
-
-	if(count < 0)
-		return -EINVAL;
+	if (count > mmapper_size - *ppos)
+		count = mmapper_size - *ppos;
 
-	copy_from_user(&v_buf[*ppos],buf,count);
+	if (copy_from_user(&v_buf[*ppos], buf, count))
+		return -EFAULT;
 	
 	return count;
 }
@@ -77,7 +56,6 @@ mmapper_mmap(struct file *file, struct v
 	int ret = -EINVAL;
 	int size;
 
-	lock_kernel();
 	if (vma->vm_pgoff != 0)
 		goto out;
 	
@@ -92,7 +70,6 @@ mmapper_mmap(struct file *file, struct v
 		goto out;
 	ret = 0;
 out:
-	unlock_kernel();
 	return ret;
 }
 
diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c
--- a/arch/um/drivers/net_kern.c
+++ b/arch/um/drivers/net_kern.c
@@ -146,7 +146,6 @@ static int uml_net_close(struct net_devi
 	netif_stop_queue(dev);
 	spin_lock(&lp->lock);
 
-	free_irq_by_irq_and_dev(dev->irq, dev);
 	free_irq(dev->irq, dev);
 	if(lp->close != NULL)
 		(*lp->close)(lp->fd, &lp->user);
@@ -613,25 +612,35 @@ static int net_config(char *str)
 	return(err);
 }
 
-static int net_remove(char *str)
+static int net_id(char **str, int *start_out, int *end_out)
+{
+        char *end;
+        int n;
+
+	n = simple_strtoul(*str, &end, 0);
+	if((*end != '\0') || (end == *str))
+		return -1;
+
+        *start_out = n;
+        *end_out = n;
+        *str = end;
+        return n;
+}
+
+static int net_remove(int n)
 {
 	struct uml_net *device;
 	struct net_device *dev;
 	struct uml_net_private *lp;
-	char *end;
-	int n;
-
-	n = simple_strtoul(str, &end, 0);
-	if((*end != '\0') || (end == str))
-		return(-1);
 
 	device = find_device(n);
 	if(device == NULL)
-		return(0);
+		return -ENODEV;
 
 	dev = device->dev;
 	lp = dev->priv;
-	if(lp->fd > 0) return(-1);
+	if(lp->fd > 0)
+                return -EBUSY;
 	if(lp->remove != NULL) (*lp->remove)(&lp->user);
 	unregister_netdev(dev);
 	platform_device_unregister(&device->pdev);
@@ -639,13 +648,14 @@ static int net_remove(char *str)
 	list_del(&device->list);
 	kfree(device);
 	free_netdev(dev);
-	return(0);
+	return 0;
 }
 
 static struct mc_device net_mc = {
 	.name		= "eth",
 	.config		= net_config,
 	.get_config	= NULL,
+        .id		= net_id,
 	.remove		= net_remove,
 };
 
diff --git a/arch/um/drivers/port_kern.c b/arch/um/drivers/port_kern.c
--- a/arch/um/drivers/port_kern.c
+++ b/arch/um/drivers/port_kern.c
@@ -257,7 +257,6 @@ int port_wait(void *data)
 		 * connection.  Then we loop here throwing out failed 
 		 * connections until a good one is found.
 		 */
-		free_irq_by_irq_and_dev(TELNETD_IRQ, conn);
 		free_irq(TELNETD_IRQ, conn);
 
 		if(conn->fd >= 0) break;
diff --git a/arch/um/drivers/ssl.c b/arch/um/drivers/ssl.c
--- a/arch/um/drivers/ssl.c
+++ b/arch/um/drivers/ssl.c
@@ -49,7 +49,7 @@ static struct chan_opts opts = {
 
 static int ssl_config(char *str);
 static int ssl_get_config(char *dev, char *str, int size, char **error_out);
-static int ssl_remove(char *str);
+static int ssl_remove(int n);
 
 static struct line_driver driver = {
 	.name 			= "UML serial line",
@@ -69,6 +69,7 @@ static struct line_driver driver = {
 		.name  		= "ssl",
 		.config 	= ssl_config,
 		.get_config 	= ssl_get_config,
+                .id		= line_id,
 		.remove 	= ssl_remove,
 	},
 };
@@ -94,10 +95,10 @@ static int ssl_get_config(char *dev, cha
 			       str, size, error_out));
 }
 
-static int ssl_remove(char *str)
+static int ssl_remove(int n)
 {
-	return(line_remove(serial_lines, 
-			   sizeof(serial_lines)/sizeof(serial_lines[0]), str));
+        return line_remove(serial_lines,
+                           sizeof(serial_lines)/sizeof(serial_lines[0]), n);
 }
 
 int ssl_open(struct tty_struct *tty, struct file *filp)
diff --git a/arch/um/drivers/stdio_console.c b/arch/um/drivers/stdio_console.c
--- a/arch/um/drivers/stdio_console.c
+++ b/arch/um/drivers/stdio_console.c
@@ -55,7 +55,7 @@ static struct chan_opts opts = {
 
 static int con_config(char *str);
 static int con_get_config(char *dev, char *str, int size, char **error_out);
-static int con_remove(char *str);
+static int con_remove(int n);
 
 static struct line_driver driver = {
 	.name 			= "UML console",
@@ -75,6 +75,7 @@ static struct line_driver driver = {
 		.name  		= "con",
 		.config 	= con_config,
 		.get_config 	= con_get_config,
+                .id		= line_id,
 		.remove 	= con_remove,
 	},
 };
@@ -99,9 +100,9 @@ static int con_get_config(char *dev, cha
 			       size, error_out));
 }
 
-static int con_remove(char *str)
+static int con_remove(int n)
 {
-	return(line_remove(vts, sizeof(vts)/sizeof(vts[0]), str));
+        return line_remove(vts, sizeof(vts)/sizeof(vts[0]), n);
 }
 
 static int con_open(struct tty_struct *tty, struct file *filp)
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -754,24 +754,34 @@ static int ubd_get_config(char *name, ch
 	return(len);
 }
 
-static int ubd_remove(char *str)
+static int ubd_id(char **str, int *start_out, int *end_out)
+{
+        int n;
+
+	n = parse_unit(str);
+        *start_out = 0;
+        *end_out = MAX_DEV - 1;
+        return n;
+}
+
+static int ubd_remove(int n)
 {
 	struct ubd *dev;
-	int n, err = -ENODEV;
+	int err = -ENODEV;
 
-	n = parse_unit(&str);
+	spin_lock(&ubd_lock);
 
-	if((n < 0) || (n >= MAX_DEV))
-		return(err);
+	if(ubd_gendisk[n] == NULL)
+		goto out;
 
 	dev = &ubd_dev[n];
-	if(dev->count > 0)
-		return(-EBUSY);	/* you cannot remove a open disk */
 
-	err = 0;
- 	spin_lock(&ubd_lock);
+	if(dev->file == NULL)
+		goto out;
 
-	if(ubd_gendisk[n] == NULL)
+	/* you cannot remove a open disk */
+	err = -EBUSY;
+	if(dev->count > 0)
 		goto out;
 
 	del_gendisk(ubd_gendisk[n]);
@@ -787,15 +797,16 @@ static int ubd_remove(char *str)
 	platform_device_unregister(&dev->pdev);
 	*dev = ((struct ubd) DEFAULT_UBD);
 	err = 0;
- out:
- 	spin_unlock(&ubd_lock);
-	return(err);
+out:
+	spin_unlock(&ubd_lock);
+	return err;
 }
 
 static struct mc_device ubd_mc = {
 	.name		= "ubd",
 	.config		= ubd_config,
  	.get_config	= ubd_get_config,
+	.id		= ubd_id,
 	.remove		= ubd_remove,
 };
 
diff --git a/arch/um/drivers/xterm_kern.c b/arch/um/drivers/xterm_kern.c
--- a/arch/um/drivers/xterm_kern.c
+++ b/arch/um/drivers/xterm_kern.c
@@ -69,7 +69,6 @@ int xterm_fd(int socket, int *pid_out)
 	 * isn't set) this will hang... */
 	wait_for_completion(&data->ready);
 
-	free_irq_by_irq_and_dev(XTERM_IRQ, data);
 	free_irq(XTERM_IRQ, data);
 
 	ret = data->new_fd;
diff --git a/arch/um/include/line.h b/arch/um/include/line.h
--- a/arch/um/include/line.h
+++ b/arch/um/include/line.h
@@ -101,7 +101,8 @@ extern void lines_init(struct line *line
 extern void close_lines(struct line *lines, int nlines);
 
 extern int line_config(struct line *lines, unsigned int sizeof_lines, char *str);
-extern int line_remove(struct line *lines, unsigned int sizeof_lines, char *str);
+extern int line_id(char **str, int *start_out, int *end_out);
+extern int line_remove(struct line *lines, unsigned int sizeof_lines, int n);
 extern int line_get_config(char *dev, struct line *lines, unsigned int sizeof_lines, char *str,
 			   int size, char **error_out);
 
diff --git a/arch/um/include/mconsole_kern.h b/arch/um/include/mconsole_kern.h
--- a/arch/um/include/mconsole_kern.h
+++ b/arch/um/include/mconsole_kern.h
@@ -20,7 +20,8 @@ struct mc_device {
 	char *name;
 	int (*config)(char *);
 	int (*get_config)(char *, char *, int, char **);
-	int (*remove)(char *);
+        int (*id)(char **, int *, int *);
+	int (*remove)(int);
 };
 
 #define CONFIG_CHUNK(str, size, current, chunk, end) \
diff --git a/arch/um/include/mem.h b/arch/um/include/mem.h
--- a/arch/um/include/mem.h
+++ b/arch/um/include/mem.h
@@ -13,6 +13,7 @@ extern int physmem_subst_mapping(void *v
 extern int is_remapped(void *virt);
 extern int physmem_remove_mapping(void *virt);
 extern void physmem_forget_descriptor(int fd);
+extern unsigned long to_phys(void *virt);
 
 #endif
 
diff --git a/arch/um/include/registers.h b/arch/um/include/registers.h
--- a/arch/um/include/registers.h
+++ b/arch/um/include/registers.h
@@ -14,6 +14,7 @@ extern int restore_fp_registers(int pid,
 extern void save_registers(int pid, union uml_pt_regs *regs);
 extern void restore_registers(int pid, union uml_pt_regs *regs);
 extern void init_registers(int pid);
+extern void get_safe_registers(unsigned long * regs);
 
 #endif
 
diff --git a/arch/um/include/sysdep-i386/ptrace_user.h b/arch/um/include/sysdep-i386/ptrace_user.h
--- a/arch/um/include/sysdep-i386/ptrace_user.h
+++ b/arch/um/include/sysdep-i386/ptrace_user.h
@@ -20,11 +20,24 @@
 #define PT_SYSCALL_ARG3_OFFSET PT_OFFSET(EDX)
 #define PT_SYSCALL_ARG4_OFFSET PT_OFFSET(ESI)
 #define PT_SYSCALL_ARG5_OFFSET PT_OFFSET(EDI)
+#define PT_SYSCALL_ARG6_OFFSET PT_OFFSET(EBP)
 
 #define PT_SYSCALL_RET_OFFSET PT_OFFSET(EAX)
 
+#define REGS_SYSCALL_NR EAX /* This is used before a system call */
+#define REGS_SYSCALL_ARG1 EBX
+#define REGS_SYSCALL_ARG2 ECX
+#define REGS_SYSCALL_ARG3 EDX
+#define REGS_SYSCALL_ARG4 ESI
+#define REGS_SYSCALL_ARG5 EDI
+#define REGS_SYSCALL_ARG6 EBP
+
+#define REGS_IP_INDEX EIP
+#define REGS_SP_INDEX UESP
+
 #define PT_IP_OFFSET PT_OFFSET(EIP)
 #define PT_IP(regs) ((regs)[EIP])
+#define PT_SP_OFFSET PT_OFFSET(UESP)
 #define PT_SP(regs) ((regs)[UESP])
 
 #ifndef FRAME_SIZE
diff --git a/arch/um/include/sysdep-i386/stub.h b/arch/um/include/sysdep-i386/stub.h
new file mode 100644
--- /dev/null
+++ b/arch/um/include/sysdep-i386/stub.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com)
+ * Licensed under the GPL
+ */
+
+#ifndef __SYSDEP_STUB_H
+#define __SYSDEP_STUB_H
+
+#include <asm/ptrace.h>
+#include <asm/unistd.h>
+
+extern void stub_segv_handler(int sig);
+extern void stub_clone_handler(void);
+
+#define STUB_SYSCALL_RET EAX
+#define STUB_MMAP_NR __NR_mmap2
+#define MMAP_OFFSET(o) ((o) >> PAGE_SHIFT)
+
+static inline long stub_syscall2(long syscall, long arg1, long arg2)
+{
+	long ret;
+
+	__asm__("movl %0, %%ecx; " : : "g" (arg2) : "%ecx");
+	__asm__("movl %0, %%ebx; " : : "g" (arg1) : "%ebx");
+	__asm__("movl %0, %%eax; " : : "g" (syscall) : "%eax");
+	__asm__("int $0x80;" : : : "%eax");
+	__asm__ __volatile__("movl %%eax, %0; " : "=g" (ret) :);
+	return(ret);
+}
+
+static inline long stub_syscall3(long syscall, long arg1, long arg2, long arg3)
+{
+	__asm__("movl %0, %%edx; " : : "g" (arg3) : "%edx");
+	return(stub_syscall2(syscall, arg1, arg2));
+}
+
+static inline long stub_syscall4(long syscall, long arg1, long arg2, long arg3,
+				 long arg4)
+{
+	__asm__("movl %0, %%esi; " : : "g" (arg4) : "%esi");
+	return(stub_syscall3(syscall, arg1, arg2, arg3));
+}
+
+static inline long stub_syscall6(long syscall, long arg1, long arg2, long arg3,
+				 long arg4, long arg5, long arg6)
+{
+	long ret;
+	__asm__("movl %0, %%eax; " : : "g" (syscall) : "%eax");
+	__asm__("movl %0, %%ebx; " : : "g" (arg1) : "%ebx");
+	__asm__("movl %0, %%ecx; " : : "g" (arg2) : "%ecx");
+	__asm__("movl %0, %%edx; " : : "g" (arg3) : "%edx");
+	__asm__("movl %0, %%esi; " : : "g" (arg4) : "%esi");
+	__asm__("movl %0, %%edi; " : : "g" (arg5) : "%edi");
+	__asm__ __volatile__("pushl %%ebp ; movl %1, %%ebp; "
+		"int $0x80; popl %%ebp ; "
+		"movl %%eax, %0; " : "=g" (ret) : "g" (arg6) : "%eax");
+	return(ret);
+}
+
+static inline void trap_myself(void)
+{
+	__asm("int3");
+}
+
+#endif
diff --git a/arch/um/include/sysdep-x86_64/ptrace_user.h b/arch/um/include/sysdep-x86_64/ptrace_user.h
--- a/arch/um/include/sysdep-x86_64/ptrace_user.h
+++ b/arch/um/include/sysdep-x86_64/ptrace_user.h
@@ -55,6 +55,20 @@
 #define PTRACE_OLDSETOPTIONS 21
 #endif
 
+/* These are before the system call, so the the system call number is RAX
+ * rather than ORIG_RAX, and arg4 is R10 rather than RCX
+ */
+#define REGS_SYSCALL_NR PT_INDEX(RAX)
+#define REGS_SYSCALL_ARG1 PT_INDEX(RDI)
+#define REGS_SYSCALL_ARG2 PT_INDEX(RSI)
+#define REGS_SYSCALL_ARG3 PT_INDEX(RDX)
+#define REGS_SYSCALL_ARG4 PT_INDEX(R10)
+#define REGS_SYSCALL_ARG5 PT_INDEX(R8)
+#define REGS_SYSCALL_ARG6 PT_INDEX(R9)
+
+#define REGS_IP_INDEX PT_INDEX(RIP)
+#define REGS_SP_INDEX PT_INDEX(RSP)
+
 #endif
 
 /*
diff --git a/arch/um/include/sysdep-x86_64/stub.h b/arch/um/include/sysdep-x86_64/stub.h
new file mode 100644
--- /dev/null
+++ b/arch/um/include/sysdep-x86_64/stub.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com)
+ * Licensed under the GPL
+ */
+
+#ifndef __SYSDEP_STUB_H
+#define __SYSDEP_STUB_H
+
+#include <asm/ptrace.h>
+#include <asm/unistd.h>
+#include <sysdep/ptrace_user.h>
+
+extern void stub_segv_handler(int sig);
+extern void stub_clone_handler(void);
+
+#define STUB_SYSCALL_RET PT_INDEX(RAX)
+#define STUB_MMAP_NR __NR_mmap
+#define MMAP_OFFSET(o) (o)
+
+static inline long stub_syscall2(long syscall, long arg1, long arg2)
+{
+	long ret;
+
+	__asm__("movq %0, %%rsi; " : : "g" (arg2) : "%rsi");
+	__asm__("movq %0, %%rdi; " : : "g" (arg1) : "%rdi");
+	__asm__("movq %0, %%rax; " : : "g" (syscall) : "%rax");
+	__asm__("syscall;" : : : "%rax", "%r11", "%rcx");
+	__asm__ __volatile__("movq %%rax, %0; " : "=g" (ret) :);
+	return(ret);
+}
+
+static inline long stub_syscall3(long syscall, long arg1, long arg2, long arg3)
+{
+	__asm__("movq %0, %%rdx; " : : "g" (arg3) : "%rdx");
+	return(stub_syscall2(syscall, arg1, arg2));
+}
+
+static inline long stub_syscall4(long syscall, long arg1, long arg2, long arg3,
+				 long arg4)
+{
+	__asm__("movq %0, %%r10; " : : "g" (arg4) : "%r10");
+	return(stub_syscall3(syscall, arg1, arg2, arg3));
+}
+
+static inline long stub_syscall6(long syscall, long arg1, long arg2, long arg3,
+				 long arg4, long arg5, long arg6)
+{
+	__asm__("movq %0, %%r9; " : : "g" (arg6) : "%r9");
+	__asm__("movq %0, %%r8; " : : "g" (arg5) : "%r8");
+	return(stub_syscall4(syscall, arg1, arg2, arg3, arg4));
+}
+
+static inline void trap_myself(void)
+{
+	__asm("int3");
+}
+
+#endif
diff --git a/arch/um/include/time_user.h b/arch/um/include/time_user.h
--- a/arch/um/include/time_user.h
+++ b/arch/um/include/time_user.h
@@ -8,11 +8,12 @@
 
 extern void timer(void);
 extern void switch_timers(int to_real);
-extern void set_interval(int timer_type);
 extern void idle_sleep(int secs);
 extern void enable_timer(void);
+extern void prepare_timer(void * ptr);
 extern void disable_timer(void);
 extern unsigned long time_lock(void);
 extern void time_unlock(unsigned long);
+extern void user_time_init(void);
 
 #endif
diff --git a/arch/um/include/tlb.h b/arch/um/include/tlb.h
--- a/arch/um/include/tlb.h
+++ b/arch/um/include/tlb.h
@@ -37,31 +37,25 @@ struct host_vm_op {
 extern void mprotect_kernel_vm(int w);
 extern void force_flush_all(void);
 extern void fix_range_common(struct mm_struct *mm, unsigned long start_addr,
-			     unsigned long end_addr, int force, int data,
-			     void (*do_ops)(int, struct host_vm_op *, int));
+                             unsigned long end_addr, int force,
+                             void (*do_ops)(union mm_context *,
+                                            struct host_vm_op *, int));
 extern int flush_tlb_kernel_range_common(unsigned long start,
 					 unsigned long end);
 
 extern int add_mmap(unsigned long virt, unsigned long phys, unsigned long len,
 		    int r, int w, int x, struct host_vm_op *ops, int index,
-		    int last_filled, int data,
-		    void (*do_ops)(int, struct host_vm_op *, int));
+                    int last_filled, union mm_context *mmu,
+                    void (*do_ops)(union mm_context *, struct host_vm_op *,
+                                   int));
 extern int add_munmap(unsigned long addr, unsigned long len,
 		      struct host_vm_op *ops, int index, int last_filled,
-		      int data, void (*do_ops)(int, struct host_vm_op *, int));
+                      union mm_context *mmu,
+                      void (*do_ops)(union mm_context *, struct host_vm_op *,
+                                     int));
 extern int add_mprotect(unsigned long addr, unsigned long len, int r, int w,
 			int x, struct host_vm_op *ops, int index,
-			int last_filled, int data,
-			void (*do_ops)(int, struct host_vm_op *, int));
+                        int last_filled, union mm_context *mmu,
+                        void (*do_ops)(union mm_context *, struct host_vm_op *,
+                                       int));
 #endif
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/kernel/dyn.lds.S b/arch/um/kernel/dyn.lds.S
--- a/arch/um/kernel/dyn.lds.S
+++ b/arch/um/kernel/dyn.lds.S
@@ -67,6 +67,12 @@ SECTIONS
     *(.stub .text.* .gnu.linkonce.t.*)
     /* .gnu.warning sections are handled specially by elf32.em.  */
     *(.gnu.warning)
+
+    . = ALIGN(4096);
+    __syscall_stub_start = .;
+    *(.__syscall_stub*)
+    __syscall_stub_end = .;
+    . = ALIGN(4096);
   } =0x90909090
   .fini           : {
     KEEP (*(.fini))
diff --git a/arch/um/kernel/exitcode.c b/arch/um/kernel/exitcode.c
--- a/arch/um/kernel/exitcode.c
+++ b/arch/um/kernel/exitcode.c
@@ -48,7 +48,7 @@ static int make_proc_exitcode(void)
 
 	ent = create_proc_entry("exitcode", 0600, &proc_root);
 	if(ent == NULL){
-		printk("make_proc_exitcode : Failed to register "
+		printk(KERN_WARNING "make_proc_exitcode : Failed to register "
 		       "/proc/exitcode\n");
 		return(0);
 	}
diff --git a/arch/um/kernel/helper.c b/arch/um/kernel/helper.c
--- a/arch/um/kernel/helper.c
+++ b/arch/um/kernel/helper.c
@@ -13,6 +13,7 @@
 #include "user.h"
 #include "kern_util.h"
 #include "user_util.h"
+#include "helper.h"
 #include "os.h"
 
 struct helper_data {
@@ -149,7 +150,7 @@ int run_helper_thread(int (*proc)(void *
 	return(pid);
 }
 
-int helper_wait(int pid, int block)
+int helper_wait(int pid)
 {
 	int ret;
 
@@ -160,14 +161,3 @@ int helper_wait(int pid, int block)
 	}
 	return(ret);
 }
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c
--- a/arch/um/kernel/irq.c
+++ b/arch/um/kernel/irq.c
@@ -124,14 +124,16 @@ void irq_unlock(unsigned long flags)
 	spin_unlock_irqrestore(&irq_spinlock, flags);
 }
 
-/*  presently hw_interrupt_type must define (startup || enable) &&
- *  disable && end */
+/* hw_interrupt_type must define (startup || enable) &&
+ * (shutdown || disable) && end */
 static void dummy(unsigned int irq)
 {
 }
 
-static struct hw_interrupt_type SIGIO_irq_type = {
+/* This is used for everything else than the timer. */
+static struct hw_interrupt_type normal_irq_type = {
 	.typename = "SIGIO",
+	.release = free_irq_by_irq_and_dev,
 	.disable = dummy,
 	.enable = dummy,
 	.ack = dummy,
@@ -140,6 +142,7 @@ static struct hw_interrupt_type SIGIO_ir
 
 static struct hw_interrupt_type SIGVTALRM_irq_type = {
 	.typename = "SIGVTALRM",
+	.release = free_irq_by_irq_and_dev,
 	.shutdown = dummy, /* never called */
 	.disable = dummy,
 	.enable = dummy,
@@ -160,7 +163,7 @@ void __init init_IRQ(void)
 		irq_desc[i].status = IRQ_DISABLED;
 		irq_desc[i].action = NULL;
 		irq_desc[i].depth = 1;
-		irq_desc[i].handler = &SIGIO_irq_type;
+		irq_desc[i].handler = &normal_irq_type;
 		enable_irq(i);
 	}
 }
diff --git a/arch/um/kernel/irq_user.c b/arch/um/kernel/irq_user.c
--- a/arch/um/kernel/irq_user.c
+++ b/arch/um/kernel/irq_user.c
@@ -85,8 +85,6 @@ void sigio_handler(int sig, union uml_pt
 				next = irq_fd->next;
 				if(irq_fd->freed){
 					free_irq(irq_fd->irq, irq_fd->id);
-					free_irq_by_irq_and_dev(irq_fd->irq,
-								irq_fd->id);
 				}
 			}
 		}
diff --git a/arch/um/kernel/main.c b/arch/um/kernel/main.c
--- a/arch/um/kernel/main.c
+++ b/arch/um/kernel/main.c
@@ -69,7 +69,6 @@ static __init void do_uml_initcalls(void
 
 static void last_ditch_exit(int sig)
 {
-        kmalloc_ok = 0;
 	signal(SIGINT, SIG_DFL);
 	signal(SIGTERM, SIG_DFL);
 	signal(SIGHUP, SIG_DFL);
diff --git a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c
--- a/arch/um/kernel/mem.c
+++ b/arch/um/kernel/mem.c
@@ -53,7 +53,6 @@ static void setup_highmem(unsigned long 
 	for(i = 0; i < highmem_len >> PAGE_SHIFT; i++){
 		page = &mem_map[highmem_pfn + i];
 		ClearPageReserved(page);
-		set_bit(PG_highmem, &page->flags);
 		set_page_count(page, 1);
 		__free_page(page);
 	}
diff --git a/arch/um/kernel/physmem.c b/arch/um/kernel/physmem.c
--- a/arch/um/kernel/physmem.c
+++ b/arch/um/kernel/physmem.c
@@ -353,6 +353,8 @@ void map_memory(unsigned long virt, unsi
 
 #define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
 
+extern int __syscall_stub_start, __binary_start;
+
 void setup_physmem(unsigned long start, unsigned long reserve_end,
 		   unsigned long len, unsigned long highmem)
 {
@@ -371,6 +373,12 @@ void setup_physmem(unsigned long start, 
 		exit(1);
 	}
 
+	/* Special kludge - This page will be mapped in to userspace processes
+	 * from physmem_fd, so it needs to be written out there.
+	 */
+	os_seek_file(physmem_fd, __pa(&__syscall_stub_start));
+	os_write_file(physmem_fd, &__syscall_stub_start, PAGE_SIZE);
+
 	bootmap_size = init_bootmem(pfn, pfn + delta);
 	free_bootmem(__pa(reserve_end) + bootmap_size,
 		     len - bootmap_size - reserve);
diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c
--- a/arch/um/kernel/process.c
+++ b/arch/um/kernel/process.c
@@ -32,6 +32,7 @@
 #include "uml-config.h"
 #include "choose-mode.h"
 #include "mode.h"
+#include "tempfile.h"
 #ifdef UML_CONFIG_MODE_SKAS
 #include "skas.h"
 #include "skas_ptrace.h"
@@ -130,7 +131,7 @@ int start_fork_tramp(void *thread_arg, u
 	return(arg.pid);
 }
 
-static int ptrace_child(void)
+static int ptrace_child(void *arg)
 {
 	int ret;
 	int pid = os_getpid(), ppid = getppid();
@@ -159,16 +160,20 @@ static int ptrace_child(void)
 	_exit(ret);
 }
 
-static int start_ptraced_child(void)
+static int start_ptraced_child(void **stack_out)
 {
+	void *stack;
+	unsigned long sp;
 	int pid, n, status;
 	
-	pid = fork();
-	if(pid == 0)
-		ptrace_child();
-
+	stack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
+		     MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+	if(stack == MAP_FAILED)
+		panic("check_ptrace : mmap failed, errno = %d", errno);
+	sp = (unsigned long) stack + PAGE_SIZE - sizeof(void *);
+	pid = clone(ptrace_child, (void *) sp, SIGCHLD, NULL);
 	if(pid < 0)
-		panic("check_ptrace : fork failed, errno = %d", errno);
+		panic("check_ptrace : clone failed, errno = %d", errno);
 	CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
 	if(n < 0)
 		panic("check_ptrace : wait failed, errno = %d", errno);
@@ -176,6 +181,7 @@ static int start_ptraced_child(void)
 		panic("check_ptrace : expected SIGSTOP, got status = %d",
 		      status);
 
+	*stack_out = stack;
 	return(pid);
 }
 
@@ -183,12 +189,12 @@ static int start_ptraced_child(void)
  * just avoid using sysemu, not panic, but only if SYSEMU features are broken.
  * So only for SYSEMU features we test mustpanic, while normal host features
  * must work anyway!*/
-static int stop_ptraced_child(int pid, int exitcode, int mustexit)
+static int stop_ptraced_child(int pid, void *stack, int exitcode, int mustpanic)
 {
 	int status, n, ret = 0;
 
 	if(ptrace(PTRACE_CONT, pid, 0, 0) < 0)
-		panic("stop_ptraced_child : ptrace failed, errno = %d", errno);
+		panic("check_ptrace : ptrace failed, errno = %d", errno);
 	CATCH_EINTR(n = waitpid(pid, &status, 0));
 	if(!WIFEXITED(status) || (WEXITSTATUS(status) != exitcode)) {
 		int exit_with = WEXITSTATUS(status);
@@ -199,24 +205,40 @@ static int stop_ptraced_child(int pid, i
 		printk("check_ptrace : child exited with exitcode %d, while "
 		      "expecting %d; status 0x%x", exit_with,
 		      exitcode, status);
-		if (mustexit)
+		if (mustpanic)
 			panic("\n");
 		else
 			printk("\n");
 		ret = -1;
 	}
 
+	if(munmap(stack, PAGE_SIZE) < 0)
+		panic("check_ptrace : munmap failed, errno = %d", errno);
 	return ret;
 }
 
 static int force_sysemu_disabled = 0;
 
+int ptrace_faultinfo = 1;
+int proc_mm = 1;
+
+static int __init skas0_cmd_param(char *str, int* add)
+{
+	ptrace_faultinfo = proc_mm = 0;
+	return 0;
+}
+
 static int __init nosysemu_cmd_param(char *str, int* add)
 {
 	force_sysemu_disabled = 1;
 	return 0;
 }
 
+__uml_setup("skas0", skas0_cmd_param,
+		"skas0\n"
+		"    Disables SKAS3 usage, so that SKAS0 is used, unless you \n"
+		"    specify mode=tt.\n\n");
+
 __uml_setup("nosysemu", nosysemu_cmd_param,
 		"nosysemu\n"
 		"    Turns off syscall emulation patch for ptrace (SYSEMU) on.\n"
@@ -227,11 +249,12 @@ __uml_setup("nosysemu", nosysemu_cmd_par
 
 static void __init check_sysemu(void)
 {
+	void *stack;
 	int pid, syscall, n, status, count=0;
 
 	printk("Checking syscall emulation patch for ptrace...");
 	sysemu_supported = 0;
-	pid = start_ptraced_child();
+	pid = start_ptraced_child(&stack);
 
 	if(ptrace(PTRACE_SYSEMU, pid, 0, 0) < 0)
 		goto fail;
@@ -249,7 +272,7 @@ static void __init check_sysemu(void)
 		panic("check_sysemu : failed to modify system "
 		      "call return, errno = %d", errno);
 
-	if (stop_ptraced_child(pid, 0, 0) < 0)
+	if (stop_ptraced_child(pid, stack, 0, 0) < 0)
 		goto fail_stopped;
 
 	sysemu_supported = 1;
@@ -257,7 +280,7 @@ static void __init check_sysemu(void)
 	set_using_sysemu(!force_sysemu_disabled);
 
 	printk("Checking advanced syscall emulation patch for ptrace...");
-	pid = start_ptraced_child();
+	pid = start_ptraced_child(&stack);
 	while(1){
 		count++;
 		if(ptrace(PTRACE_SYSEMU_SINGLESTEP, pid, 0, 0) < 0)
@@ -282,7 +305,7 @@ static void __init check_sysemu(void)
 			break;
 		}
 	}
-	if (stop_ptraced_child(pid, 0, 0) < 0)
+	if (stop_ptraced_child(pid, stack, 0, 0) < 0)
 		goto fail_stopped;
 
 	sysemu_supported = 2;
@@ -293,17 +316,18 @@ static void __init check_sysemu(void)
 	return;
 
 fail:
-	stop_ptraced_child(pid, 1, 0);
+	stop_ptraced_child(pid, stack, 1, 0);
 fail_stopped:
 	printk("missing\n");
 }
 
 void __init check_ptrace(void)
 {
+	void *stack;
 	int pid, syscall, n, status;
 
 	printk("Checking that ptrace can change system call numbers...");
-	pid = start_ptraced_child();
+	pid = start_ptraced_child(&stack);
 
 	if (ptrace(PTRACE_OLDSETOPTIONS, pid, 0, (void *)PTRACE_O_TRACESYSGOOD) < 0)
 		panic("check_ptrace: PTRACE_SETOPTIONS failed, errno = %d", errno);
@@ -330,7 +354,7 @@ void __init check_ptrace(void)
 			break;
 		}
 	}
-	stop_ptraced_child(pid, 0, 1);
+	stop_ptraced_child(pid, stack, 0, 1);
 	printk("OK\n");
 	check_sysemu();
 }
@@ -358,49 +382,54 @@ void forward_pending_sigio(int target)
 		kill(target, SIGIO);
 }
 
+extern void *__syscall_stub_start, __syscall_stub_end;
+
 #ifdef UML_CONFIG_MODE_SKAS
-static inline int check_skas3_ptrace_support(void)
+
+static inline void check_skas3_ptrace_support(void)
 {
 	struct ptrace_faultinfo fi;
-	int pid, n, ret = 1;
+	void *stack;
+	int pid, n;
 
 	printf("Checking for the skas3 patch in the host...");
-	pid = start_ptraced_child();
+	pid = start_ptraced_child(&stack);
 
 	n = ptrace(PTRACE_FAULTINFO, pid, 0, &fi);
 	if (n < 0) {
+		ptrace_faultinfo = 0;
 		if(errno == EIO)
 			printf("not found\n");
 		else {
 			perror("not found");
 		}
-		ret = 0;
-	} else {
-		printf("found\n");
+	}
+	else {
+		if (!ptrace_faultinfo)
+			printf("found but disabled on command line\n");
+		else
+			printf("found\n");
 	}
 
 	init_registers(pid);
-	stop_ptraced_child(pid, 1, 1);
-
-	return(ret);
+	stop_ptraced_child(pid, stack, 1, 1);
 }
 
 int can_do_skas(void)
 {
-	int ret = 1;
-
 	printf("Checking for /proc/mm...");
 	if (os_access("/proc/mm", OS_ACC_W_OK) < 0) {
+		proc_mm = 0;
 		printf("not found\n");
-		ret = 0;
-		goto out;
 	} else {
-		printf("found\n");
+		if (!proc_mm)
+			printf("found but disabled on command line\n");
+		else
+			printf("found\n");
 	}
 
-	ret = check_skas3_ptrace_support();
-out:
-	return ret;
+	check_skas3_ptrace_support();
+	return 1;
 }
 #else
 int can_do_skas(void)
diff --git a/arch/um/kernel/process_kern.c b/arch/um/kernel/process_kern.c
--- a/arch/um/kernel/process_kern.c
+++ b/arch/um/kernel/process_kern.c
@@ -8,6 +8,7 @@
 #include "linux/kernel.h"
 #include "linux/sched.h"
 #include "linux/interrupt.h"
+#include "linux/string.h"
 #include "linux/mm.h"
 #include "linux/slab.h"
 #include "linux/utsname.h"
@@ -95,8 +96,8 @@ int kernel_thread(int (*fn)(void *), voi
 
 	current->thread.request.u.thread.proc = fn;
 	current->thread.request.u.thread.arg = arg;
-	pid = do_fork(CLONE_VM | CLONE_UNTRACED | flags, 0, NULL, 0, NULL,
-		      NULL);
+	pid = do_fork(CLONE_VM | CLONE_UNTRACED | flags, 0,
+		      &current->thread.regs, 0, NULL, NULL);
 	if(pid < 0)
 		panic("do_fork failed in kernel_thread, errno = %d", pid);
 	return(pid);
@@ -168,7 +169,7 @@ int current_pid(void)
 
 void default_idle(void)
 {
-	uml_idle_timer();
+	CHOOSE_MODE(uml_idle_timer(), (void) 0);
 
 	atomic_inc(&init_mm.mm_count);
 	current->mm = &init_mm;
@@ -322,12 +323,7 @@ void do_uml_exitcalls(void)
 
 char *uml_strdup(char *string)
 {
-	char *new;
-
-	new = kmalloc(strlen(string) + 1, GFP_KERNEL);
-	if(new == NULL) return(NULL);
-	strcpy(new, string);
-	return(new);
+	return kstrdup(string, GFP_KERNEL);
 }
 
 int copy_to_user_proc(void __user *to, void *from, int size)
@@ -416,7 +412,7 @@ int __init make_proc_sysemu(void)
 
 	if (ent == NULL)
 	{
-		printk("Failed to register /proc/sysemu\n");
+		printk(KERN_WARNING "Failed to register /proc/sysemu\n");
 		return(0);
 	}
 
diff --git a/arch/um/kernel/reboot.c b/arch/um/kernel/reboot.c
--- a/arch/um/kernel/reboot.c
+++ b/arch/um/kernel/reboot.c
@@ -38,35 +38,28 @@ static void kill_off_processes(void)
 
 void uml_cleanup(void)
 {
-	kill_off_processes();
+        kmalloc_ok = 0;
 	do_uml_exitcalls();
+	kill_off_processes();
 }
 
 void machine_restart(char * __unused)
 {
-	do_uml_exitcalls();
-	kill_off_processes();
+        uml_cleanup();
 	CHOOSE_MODE(reboot_tt(), reboot_skas());
 }
 
-EXPORT_SYMBOL(machine_restart);
-
 void machine_power_off(void)
 {
-	do_uml_exitcalls();
-	kill_off_processes();
+        uml_cleanup();
 	CHOOSE_MODE(halt_tt(), halt_skas());
 }
 
-EXPORT_SYMBOL(machine_power_off);
-
 void machine_halt(void)
 {
 	machine_power_off();
 }
 
-EXPORT_SYMBOL(machine_halt);
-
 /*
  * Overrides for Emacs so that we follow Linus's tabbing style.
  * Emacs will notice this stuff at the end of the file and automatically
diff --git a/arch/um/kernel/skas/Makefile b/arch/um/kernel/skas/Makefile
--- a/arch/um/kernel/skas/Makefile
+++ b/arch/um/kernel/skas/Makefile
@@ -3,11 +3,14 @@
 # Licensed under the GPL
 #
 
-obj-y := exec_kern.o mem.o mem_user.o mmu.o process.o process_kern.o \
-	syscall_kern.o syscall_user.o time.o tlb.o trap_user.o uaccess.o \
+obj-y := clone.o exec_kern.o mem.o mem_user.o mmu.o process.o process_kern.o \
+	syscall_kern.o syscall_user.o tlb.o trap_user.o uaccess.o \
 
 subdir- := util
 
-USER_OBJS := process.o time.o
+USER_OBJS := process.o clone.o
 
 include arch/um/scripts/Makefile.rules
+
+# clone.o is in the stub, so it can't be built with profiling
+$(obj)/clone.o : c_flags = -Wp,-MD,$(depfile) $(call unprofile,$(USER_CFLAGS))
diff --git a/arch/um/kernel/skas/clone.c b/arch/um/kernel/skas/clone.c
new file mode 100644
--- /dev/null
+++ b/arch/um/kernel/skas/clone.c
@@ -0,0 +1,44 @@
+#include <sched.h>
+#include <signal.h>
+#include <sys/mman.h>
+#include <sys/time.h>
+#include <asm/unistd.h>
+#include <asm/page.h>
+#include "ptrace_user.h"
+#include "skas.h"
+#include "stub-data.h"
+#include "uml-config.h"
+#include "sysdep/stub.h"
+
+/* This is in a separate file because it needs to be compiled with any
+ * extraneous gcc flags (-pg, -fprofile-arcs, -ftest-coverage) disabled
+ */
+void __attribute__ ((__section__ (".__syscall_stub")))
+stub_clone_handler(void)
+{
+	long err;
+	struct stub_data *from = (struct stub_data *) UML_CONFIG_STUB_DATA;
+
+	err = stub_syscall2(__NR_clone, CLONE_PARENT | CLONE_FILES | SIGCHLD,
+			    UML_CONFIG_STUB_DATA + PAGE_SIZE / 2 -
+			    sizeof(void *));
+	if(err != 0)
+		goto out;
+
+	err = stub_syscall4(__NR_ptrace, PTRACE_TRACEME, 0, 0, 0);
+	if(err)
+		goto out;
+
+	err = stub_syscall3(__NR_setitimer, ITIMER_VIRTUAL,
+			    (long) &from->timer, 0);
+	if(err)
+		goto out;
+
+	err = stub_syscall6(STUB_MMAP_NR, UML_CONFIG_STUB_DATA, PAGE_SIZE,
+			    PROT_READ | PROT_WRITE, MAP_FIXED | MAP_SHARED,
+			    from->fd, from->offset);
+ out:
+	/* save current result. Parent: pid; child: retcode of mmap */
+	from->err = err;
+	trap_myself();
+}
diff --git a/arch/um/kernel/skas/exec_kern.c b/arch/um/kernel/skas/exec_kern.c
--- a/arch/um/kernel/skas/exec_kern.c
+++ b/arch/um/kernel/skas/exec_kern.c
@@ -18,7 +18,7 @@
 void flush_thread_skas(void)
 {
 	force_flush_all();
-	switch_mm_skas(current->mm->context.skas.mm_fd);
+        switch_mm_skas(&current->mm->context.skas.id);
 }
 
 void start_thread_skas(struct pt_regs *regs, unsigned long eip, 
diff --git a/arch/um/kernel/skas/include/mm_id.h b/arch/um/kernel/skas/include/mm_id.h
new file mode 100644
--- /dev/null
+++ b/arch/um/kernel/skas/include/mm_id.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2005 Jeff Dike (jdike@karaya.com)
+ * Licensed under the GPL
+ */
+
+#ifndef __MM_ID_H
+#define __MM_ID_H
+
+struct mm_id {
+	union {
+		int mm_fd;
+		int pid;
+	} u;
+	unsigned long stack;
+};
+
+#endif
diff --git a/arch/um/kernel/skas/include/mmu-skas.h b/arch/um/kernel/skas/include/mmu-skas.h
--- a/arch/um/kernel/skas/include/mmu-skas.h
+++ b/arch/um/kernel/skas/include/mmu-skas.h
@@ -6,10 +6,15 @@
 #ifndef __SKAS_MMU_H
 #define __SKAS_MMU_H
 
+#include "mm_id.h"
+
 struct mmu_context_skas {
-	int mm_fd;
+	struct mm_id id;
+        unsigned long last_page_table;
 };
 
+extern void switch_mm_skas(struct mm_id * mm_idp);
+
 #endif
 
 /*
diff --git a/arch/um/kernel/skas/include/mode-skas.h b/arch/um/kernel/skas/include/mode-skas.h
--- a/arch/um/kernel/skas/include/mode-skas.h
+++ b/arch/um/kernel/skas/include/mode-skas.h
@@ -13,7 +13,6 @@ extern unsigned long exec_fp_regs[];
 extern unsigned long exec_fpx_regs[];
 extern int have_fpx_regs;
 
-extern void user_time_init_skas(void);
 extern void sig_handler_common_skas(int sig, void *sc_ptr);
 extern void halt_skas(void);
 extern void reboot_skas(void);
diff --git a/arch/um/kernel/skas/include/skas.h b/arch/um/kernel/skas/include/skas.h
--- a/arch/um/kernel/skas/include/skas.h
+++ b/arch/um/kernel/skas/include/skas.h
@@ -6,9 +6,11 @@
 #ifndef __SKAS_H
 #define __SKAS_H
 
+#include "mm_id.h"
 #include "sysdep/ptrace.h"
 
 extern int userspace_pid[];
+extern int proc_mm, ptrace_faultinfo;
 
 extern void switch_threads(void *me, void *next);
 extern void thread_wait(void *sw, void *fb);
@@ -22,16 +24,18 @@ extern void new_thread_proc(void *stack,
 extern void remove_sigstack(void);
 extern void new_thread_handler(int sig);
 extern void handle_syscall(union uml_pt_regs *regs);
-extern void map(int fd, unsigned long virt, unsigned long len, int r, int w,
-		int x, int phys_fd, unsigned long long offset);
-extern int unmap(int fd, void *addr, unsigned long len);
-extern int protect(int fd, unsigned long addr, unsigned long len, 
-		   int r, int w, int x);
+extern int map(struct mm_id * mm_idp, unsigned long virt, unsigned long len,
+               int r, int w, int x, int phys_fd, unsigned long long offset);
+extern int unmap(struct mm_id * mm_idp, void *addr, unsigned long len);
+extern int protect(struct mm_id * mm_idp, unsigned long addr,
+		   unsigned long len, int r, int w, int x);
 extern void user_signal(int sig, union uml_pt_regs *regs, int pid);
 extern int new_mm(int from);
-extern void start_userspace(int cpu);
+extern int start_userspace(unsigned long stub_stack);
+extern int copy_context_skas0(unsigned long stack, int pid);
 extern void get_skas_faultinfo(int pid, struct faultinfo * fi);
 extern long execute_syscall_skas(void *r);
+extern unsigned long current_stub_stack(void);
 
 #endif
 
diff --git a/arch/um/kernel/skas/include/stub-data.h b/arch/um/kernel/skas/include/stub-data.h
new file mode 100644
--- /dev/null
+++ b/arch/um/kernel/skas/include/stub-data.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2005 Jeff Dike (jdike@karaya.com)
+ * Licensed under the GPL
+ */
+
+#ifndef __STUB_DATA_H
+#define __STUB_DATA_H
+
+#include <sys/time.h>
+
+struct stub_data {
+	long offset;
+	int fd;
+	struct itimerval timer;
+	long err;
+};
+
+#endif
diff --git a/arch/um/kernel/skas/mem.c b/arch/um/kernel/skas/mem.c
--- a/arch/um/kernel/skas/mem.c
+++ b/arch/um/kernel/skas/mem.c
@@ -5,7 +5,9 @@
 
 #include "linux/config.h"
 #include "linux/mm.h"
+#include "asm/pgtable.h"
 #include "mem_user.h"
+#include "skas.h"
 
 unsigned long set_task_sizes_skas(int arg, unsigned long *host_size_out, 
 				  unsigned long *task_size_out)
@@ -18,7 +20,9 @@ unsigned long set_task_sizes_skas(int ar
 	*task_size_out = CONFIG_HOST_TASK_SIZE;
 #else
 	*host_size_out = top;
-	*task_size_out = top;
+	if (proc_mm && ptrace_faultinfo)
+		*task_size_out = top;
+	else *task_size_out = CONFIG_STUB_START & PGDIR_MASK;
 #endif
 	return(((unsigned long) set_task_sizes_skas) & ~0xffffff);
 }
diff --git a/arch/um/kernel/skas/mem_user.c b/arch/um/kernel/skas/mem_user.c
--- a/arch/um/kernel/skas/mem_user.c
+++ b/arch/um/kernel/skas/mem_user.c
@@ -3,100 +3,171 @@
  * Licensed under the GPL
  */
 
+#include <signal.h>
 #include <errno.h>
 #include <sys/mman.h>
+#include <sys/wait.h>
+#include <asm/page.h>
+#include <asm/unistd.h>
 #include "mem_user.h"
 #include "mem.h"
+#include "mm_id.h"
 #include "user.h"
 #include "os.h"
 #include "proc_mm.h"
+#include "ptrace_user.h"
+#include "user_util.h"
+#include "kern_util.h"
+#include "task.h"
+#include "registers.h"
+#include "uml-config.h"
+#include "sysdep/ptrace.h"
+#include "sysdep/stub.h"
+#include "skas.h"
 
-void map(int fd, unsigned long virt, unsigned long len, int r, int w,
-	 int x, int phys_fd, unsigned long long offset)
+extern unsigned long syscall_stub, __syscall_stub_start;
+
+extern void wait_stub_done(int pid, int sig, char * fname);
+
+static long run_syscall_stub(struct mm_id * mm_idp, int syscall,
+                             unsigned long *args)
 {
-	struct proc_mm_op map;
-	int prot, n;
+        int n, pid = mm_idp->u.pid;
+        unsigned long regs[MAX_REG_NR];
+
+        get_safe_registers(regs);
+        regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE +
+                ((unsigned long) &syscall_stub -
+                 (unsigned long) &__syscall_stub_start);
+        /* XXX Don't have a define for starting a syscall */
+        regs[REGS_SYSCALL_NR] = syscall;
+        regs[REGS_SYSCALL_ARG1] = args[0];
+        regs[REGS_SYSCALL_ARG2] = args[1];
+        regs[REGS_SYSCALL_ARG3] = args[2];
+        regs[REGS_SYSCALL_ARG4] = args[3];
+        regs[REGS_SYSCALL_ARG5] = args[4];
+        regs[REGS_SYSCALL_ARG6] = args[5];
+        n = ptrace_setregs(pid, regs);
+        if(n < 0){
+                printk("run_syscall_stub : PTRACE_SETREGS failed, "
+                       "errno = %d\n", n);
+                return(n);
+        }
 
-	prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) | 
-		(x ? PROT_EXEC : 0);
+        wait_stub_done(pid, 0, "run_syscall_stub");
 
-	map = ((struct proc_mm_op) { .op 	= MM_MMAP,
-				     .u 	= 
-				     { .mmap	= 
-				       { .addr 		= virt,
-					 .len		= len,
-					 .prot		= prot,
-					 .flags		= MAP_SHARED | 
-					                  MAP_FIXED,
-					 .fd		= phys_fd,
-					 .offset	= offset
-				       } } } );
-	n = os_write_file(fd, &map, sizeof(map));
-	if(n != sizeof(map)) 
-		printk("map : /proc/mm map failed, err = %d\n", -n);
+        return(*((unsigned long *) mm_idp->stack));
 }
 
-int unmap(int fd, void *addr, unsigned long len)
+int map(struct mm_id *mm_idp, unsigned long virt, unsigned long len,
+        int r, int w, int x, int phys_fd, unsigned long long offset)
 {
-	struct proc_mm_op unmap;
-	int n;
+        int prot, n;
 
-	unmap = ((struct proc_mm_op) { .op 	= MM_MUNMAP,
-				       .u 	= 
-				       { .munmap	= 
-					 { .addr 	= (unsigned long) addr,
-					   .len		= len } } } );
-	n = os_write_file(fd, &unmap, sizeof(unmap));
-	if(n != sizeof(unmap)) {
-		if(n < 0)
-			return(n);
-		else if(n > 0)
-			return(-EIO);
-	}
+        prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) |
+                (x ? PROT_EXEC : 0);
 
-	return(0);
+        if(proc_mm){
+                struct proc_mm_op map;
+                int fd = mm_idp->u.mm_fd;
+                map = ((struct proc_mm_op) { .op	= MM_MMAP,
+                                             .u		=
+                                             { .mmap	=
+                                               { .addr	= virt,
+                                                 .len	= len,
+                                                 .prot	= prot,
+                                                 .flags	= MAP_SHARED |
+                                                 MAP_FIXED,
+                                                 .fd	= phys_fd,
+                                                 .offset= offset
+                                               } } } );
+                n = os_write_file(fd, &map, sizeof(map));
+                if(n != sizeof(map))
+                        printk("map : /proc/mm map failed, err = %d\n", -n);
+        }
+        else {
+                long res;
+                unsigned long args[] = { virt, len, prot,
+                                         MAP_SHARED | MAP_FIXED, phys_fd,
+                                         MMAP_OFFSET(offset) };
+
+                res = run_syscall_stub(mm_idp, STUB_MMAP_NR, args);
+                if((void *) res == MAP_FAILED)
+                        printk("mmap stub failed, errno = %d\n", res);
+        }
+
+        return 0;
 }
 
-int protect(int fd, unsigned long addr, unsigned long len, int r, int w, 
-	    int x, int must_succeed)
+int unmap(struct mm_id *mm_idp, void *addr, unsigned long len)
 {
-	struct proc_mm_op protect;
-	int prot, n;
+        int n;
 
-	prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) | 
-		(x ? PROT_EXEC : 0);
+        if(proc_mm){
+                struct proc_mm_op unmap;
+                int fd = mm_idp->u.mm_fd;
+                unmap = ((struct proc_mm_op) { .op	= MM_MUNMAP,
+                                               .u	=
+                                               { .munmap	=
+                                                 { .addr	=
+                                                   (unsigned long) addr,
+                                                   .len		= len } } } );
+                n = os_write_file(fd, &unmap, sizeof(unmap));
+                if(n != sizeof(unmap)) {
+                        if(n < 0)
+                                return(n);
+                        else if(n > 0)
+                                return(-EIO);
+                }
+        }
+        else {
+                int res;
+                unsigned long args[] = { (unsigned long) addr, len, 0, 0, 0,
+                                         0 };
+
+                res = run_syscall_stub(mm_idp, __NR_munmap, args);
+                if(res < 0)
+                        printk("munmap stub failed, errno = %d\n", res);
+        }
 
-	protect = ((struct proc_mm_op) { .op 	= MM_MPROTECT,
-				       .u 	= 
-				       { .mprotect	= 
-					 { .addr 	= (unsigned long) addr,
-					   .len		= len,
-					   .prot	= prot } } } );
-
-	n = os_write_file(fd, &protect, sizeof(protect));
-	if(n != sizeof(protect)) {
-		if(n == 0) return(0);
+        return(0);
+}
 
-		if(must_succeed)
-			panic("protect failed, err = %d", -n);
+int protect(struct mm_id *mm_idp, unsigned long addr, unsigned long len,
+	    int r, int w, int x)
+{
+        struct proc_mm_op protect;
+        int prot, n;
+
+        prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) |
+                (x ? PROT_EXEC : 0);
 
-		return(-EIO);
-	}
+        if(proc_mm){
+                int fd = mm_idp->u.mm_fd;
+                protect = ((struct proc_mm_op) { .op	= MM_MPROTECT,
+                                                 .u	=
+                                                 { .mprotect	=
+                                                   { .addr	=
+                                                     (unsigned long) addr,
+                                                     .len	= len,
+                                                     .prot	= prot } } } );
+
+                n = os_write_file(fd, &protect, sizeof(protect));
+                if(n != sizeof(protect))
+                        panic("protect failed, err = %d", -n);
+        }
+        else {
+                int res;
+                unsigned long args[] = { addr, len, prot, 0, 0, 0 };
+
+                res = run_syscall_stub(mm_idp, __NR_mprotect, args);
+                if(res < 0)
+                        panic("mprotect stub failed, errno = %d\n", res);
+        }
 
-	return(0);
+        return(0);
 }
 
 void before_mem_skas(unsigned long unused)
 {
 }
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/kernel/skas/mmu.c b/arch/um/kernel/skas/mmu.c
--- a/arch/um/kernel/skas/mmu.c
+++ b/arch/um/kernel/skas/mmu.c
@@ -3,46 +3,143 @@
  * Licensed under the GPL
  */
 
+#include "linux/config.h"
 #include "linux/sched.h"
 #include "linux/list.h"
 #include "linux/spinlock.h"
 #include "linux/slab.h"
+#include "linux/errno.h"
+#include "linux/mm.h"
 #include "asm/current.h"
 #include "asm/segment.h"
 #include "asm/mmu.h"
+#include "asm/pgalloc.h"
+#include "asm/pgtable.h"
 #include "os.h"
 #include "skas.h"
 
-int init_new_context_skas(struct task_struct *task, struct mm_struct *mm)
+extern int __syscall_stub_start;
+
+static int init_stub_pte(struct mm_struct *mm, unsigned long proc,
+			 unsigned long kernel)
 {
-	int from;
+	pgd_t *pgd;
+	pud_t *pud;
+	pmd_t *pmd;
+	pte_t *pte;
+
+	spin_lock(&mm->page_table_lock);
+	pgd = pgd_offset(mm, proc);
+	pud = pud_alloc(mm, pgd, proc);
+	if (!pud)
+		goto out;
+
+	pmd = pmd_alloc(mm, pud, proc);
+	if (!pmd)
+		goto out_pmd;
+
+	pte = pte_alloc_map(mm, pmd, proc);
+	if (!pte)
+		goto out_pte;
+
+	/* There's an interaction between the skas0 stub pages, stack
+	 * randomization, and the BUG at the end of exit_mmap.  exit_mmap
+         * checks that the number of page tables freed is the same as had
+         * been allocated.  If the stack is on the last page table page,
+	 * then the stack pte page will be freed, and if not, it won't.  To
+	 * avoid having to know where the stack is, or if the process mapped
+	 * something at the top of its address space for some other reason,
+	 * we set TASK_SIZE to end at the start of the last page table.
+	 * This keeps exit_mmap off the last page, but introduces a leak
+	 * of that page.  So, we hang onto it here and free it in
+	 * destroy_context_skas.
+	 */
+
+        mm->context.skas.last_page_table = pmd_page_kernel(*pmd);
+
+	*pte = mk_pte(virt_to_page(kernel), __pgprot(_PAGE_PRESENT));
+	*pte = pte_mkexec(*pte);
+	*pte = pte_wrprotect(*pte);
+	spin_unlock(&mm->page_table_lock);
+	return(0);
 
-	if((current->mm != NULL) && (current->mm != &init_mm))
-		from = current->mm->context.skas.mm_fd;
-	else from = -1;
-
-	mm->context.skas.mm_fd = new_mm(from);
-	if(mm->context.skas.mm_fd < 0){
-		printk("init_new_context_skas - new_mm failed, errno = %d\n",
-		       mm->context.skas.mm_fd);
-		return(mm->context.skas.mm_fd);
+ out_pmd:
+	pud_free(pud);
+ out_pte:
+	pmd_free(pmd);
+ out:
+	spin_unlock(&mm->page_table_lock);
+	return(-ENOMEM);
+}
+
+int init_new_context_skas(struct task_struct *task, struct mm_struct *mm)
+{
+	struct mm_struct *cur_mm = current->mm;
+	struct mm_id *cur_mm_id = &cur_mm->context.skas.id;
+	struct mm_id *mm_id = &mm->context.skas.id;
+	unsigned long stack;
+	int from, ret;
+
+	if(proc_mm){
+		if((cur_mm != NULL) && (cur_mm != &init_mm))
+			from = cur_mm->context.skas.id.u.mm_fd;
+		else from = -1;
+
+		ret = new_mm(from);
+		if(ret < 0){
+			printk("init_new_context_skas - new_mm failed, "
+			       "errno = %d\n", ret);
+			return ret;
+		}
+		mm_id->u.mm_fd = ret;
+	}
+	else {
+		/* This zeros the entry that pgd_alloc didn't, needed since
+		 * we are about to reinitialize it, and want mm.nr_ptes to
+		 * be accurate.
+		 */
+		mm->pgd[USER_PTRS_PER_PGD] = __pgd(0);
+
+		ret = init_stub_pte(mm, CONFIG_STUB_CODE,
+				    (unsigned long) &__syscall_stub_start);
+		if(ret)
+			goto out;
+
+		ret = -ENOMEM;
+		stack = get_zeroed_page(GFP_KERNEL);
+		if(stack == 0)
+			goto out;
+		mm_id->stack = stack;
+
+		ret = init_stub_pte(mm, CONFIG_STUB_DATA, stack);
+		if(ret)
+			goto out_free;
+
+		mm->nr_ptes--;
+
+		if((cur_mm != NULL) && (cur_mm != &init_mm))
+			mm_id->u.pid = copy_context_skas0(stack,
+							  cur_mm_id->u.pid);
+		else mm_id->u.pid = start_userspace(stack);
 	}
 
-	return(0);
+	return 0;
+
+ out_free:
+	free_page(mm_id->stack);
+ out:
+	return ret;
 }
 
 void destroy_context_skas(struct mm_struct *mm)
 {
-	os_close_file(mm->context.skas.mm_fd);
-}
+	struct mmu_context_skas *mmu = &mm->context.skas;
 
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
+	if(proc_mm)
+		os_close_file(mmu->id.u.mm_fd);
+	else {
+		os_kill_ptraced_process(mmu->id.u.pid, 1);
+		free_page(mmu->id.stack);
+		free_page(mmu->last_page_table);
+	}
+}
diff --git a/arch/um/kernel/skas/process.c b/arch/um/kernel/skas/process.c
--- a/arch/um/kernel/skas/process.c
+++ b/arch/um/kernel/skas/process.c
@@ -1,5 +1,5 @@
 /* 
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
+ * Copyright (C) 2002- 2004 Jeff Dike (jdike@addtoit.com)
  * Licensed under the GPL
  */
 
@@ -13,7 +13,9 @@
 #include <sys/wait.h>
 #include <sys/mman.h>
 #include <sys/user.h>
+#include <sys/time.h>
 #include <asm/unistd.h>
+#include <asm/types.h>
 #include "user.h"
 #include "ptrace_user.h"
 #include "time_user.h"
@@ -21,13 +23,18 @@
 #include "user_util.h"
 #include "kern_util.h"
 #include "skas.h"
+#include "stub-data.h"
+#include "mm_id.h"
 #include "sysdep/sigcontext.h"
+#include "sysdep/stub.h"
 #include "os.h"
 #include "proc_mm.h"
 #include "skas_ptrace.h"
 #include "chan_user.h"
 #include "signal_user.h"
 #include "registers.h"
+#include "mem.h"
+#include "uml-config.h"
 #include "process.h"
 
 int is_skas_winch(int pid, int fd, void *data)
@@ -39,20 +46,59 @@ int is_skas_winch(int pid, int fd, void 
 	return(1);
 }
 
+void wait_stub_done(int pid, int sig, char * fname)
+{
+        int n, status, err;
+
+        do {
+                if ( sig != -1 ) {
+                        err = ptrace(PTRACE_CONT, pid, 0, sig);
+                        if(err)
+                                panic("%s : continue failed, errno = %d\n",
+                                      fname, errno);
+                }
+                sig = 0;
+
+                CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
+        } while((n >= 0) && WIFSTOPPED(status) &&
+                ((WSTOPSIG(status) == SIGVTALRM) ||
+		 /* running UML inside a detached screen can cause
+		  * SIGWINCHes
+		  */
+		 (WSTOPSIG(status) == SIGWINCH)));
+
+        if((n < 0) || !WIFSTOPPED(status) ||
+           (WSTOPSIG(status) != SIGUSR1 && WSTOPSIG(status) != SIGTRAP)){
+                panic("%s : failed to wait for SIGUSR1/SIGTRAP, "
+                      "pid = %d, n = %d, errno = %d, status = 0x%x\n",
+                      fname, pid, n, errno, status);
+        }
+}
+
 void get_skas_faultinfo(int pid, struct faultinfo * fi)
 {
-	int err;
+        int err;
 
-        err = ptrace(PTRACE_FAULTINFO, pid, 0, fi);
-	if(err)
-                panic("get_skas_faultinfo - PTRACE_FAULTINFO failed, "
-                      "errno = %d\n", errno);
-
-        /* Special handling for i386, which has different structs */
-        if (sizeof(struct ptrace_faultinfo) < sizeof(struct faultinfo))
-                memset((char *)fi + sizeof(struct ptrace_faultinfo), 0,
-                       sizeof(struct faultinfo) -
-                       sizeof(struct ptrace_faultinfo));
+        if(ptrace_faultinfo){
+                err = ptrace(PTRACE_FAULTINFO, pid, 0, fi);
+                if(err)
+                        panic("get_skas_faultinfo - PTRACE_FAULTINFO failed, "
+                              "errno = %d\n", errno);
+
+                /* Special handling for i386, which has different structs */
+                if (sizeof(struct ptrace_faultinfo) < sizeof(struct faultinfo))
+                        memset((char *)fi + sizeof(struct ptrace_faultinfo), 0,
+                               sizeof(struct faultinfo) -
+                               sizeof(struct ptrace_faultinfo));
+        }
+        else {
+                wait_stub_done(pid, SIGSEGV, "get_skas_faultinfo");
+
+                /* faultinfo is prepared by the stub-segv-handler at start of
+                 * the stub stack page. We just have to copy it.
+                 */
+                memcpy(fi, (void *)current_stub_stack(), sizeof(*fi));
+        }
 }
 
 static void handle_segv(int pid, union uml_pt_regs * regs)
@@ -91,11 +137,56 @@ static void handle_trap(int pid, union u
 	handle_syscall(regs);
 }
 
-static int userspace_tramp(void *arg)
+extern int __syscall_stub_start;
+
+static int userspace_tramp(void *stack)
 {
-	init_new_thread_signals(0);
-	enable_timer();
+	void *addr;
+
 	ptrace(PTRACE_TRACEME, 0, 0, 0);
+
+	init_new_thread_signals(1);
+	enable_timer();
+
+	if(!proc_mm){
+		/* This has a pte, but it can't be mapped in with the usual
+		 * tlb_flush mechanism because this is part of that mechanism
+		 */
+		int fd;
+		__u64 offset;
+
+		fd = phys_mapping(to_phys(&__syscall_stub_start), &offset);
+		addr = mmap64((void *) UML_CONFIG_STUB_CODE, page_size(),
+			      PROT_EXEC, MAP_FIXED | MAP_PRIVATE, fd, offset);
+		if(addr == MAP_FAILED){
+			printk("mapping mmap stub failed, errno = %d\n",
+			       errno);
+			exit(1);
+		}
+
+		if(stack != NULL){
+			fd = phys_mapping(to_phys(stack), &offset);
+			addr = mmap((void *) UML_CONFIG_STUB_DATA, page_size(),
+				    PROT_READ | PROT_WRITE,
+				    MAP_FIXED | MAP_SHARED, fd, offset);
+			if(addr == MAP_FAILED){
+				printk("mapping segfault stack failed, "
+				       "errno = %d\n", errno);
+				exit(1);
+			}
+		}
+	}
+	if(!ptrace_faultinfo && (stack != NULL)){
+		unsigned long v = UML_CONFIG_STUB_CODE +
+				  (unsigned long) stub_segv_handler -
+				  (unsigned long) &__syscall_stub_start;
+
+		set_sigstack((void *) UML_CONFIG_STUB_DATA, page_size());
+		set_handler(SIGSEGV, (void *) v, SA_ONSTACK,
+			    SIGIO, SIGWINCH, SIGALRM, SIGVTALRM,
+			    SIGUSR1, -1);
+	}
+
 	os_stop_process(os_getpid());
 	return(0);
 }
@@ -105,11 +196,11 @@ static int userspace_tramp(void *arg)
 #define NR_CPUS 1
 int userspace_pid[NR_CPUS];
 
-void start_userspace(int cpu)
+int start_userspace(unsigned long stub_stack)
 {
 	void *stack;
 	unsigned long sp;
-	int pid, status, n;
+	int pid, status, n, flags;
 
 	stack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
 		     MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
@@ -117,8 +208,9 @@ void start_userspace(int cpu)
 		panic("start_userspace : mmap failed, errno = %d", errno);
 	sp = (unsigned long) stack + PAGE_SIZE - sizeof(void *);
 
-	pid = clone(userspace_tramp, (void *) sp, 
-		    CLONE_FILES | CLONE_VM | SIGCHLD, NULL);
+	flags = CLONE_FILES | SIGCHLD;
+	if(proc_mm) flags |= CLONE_VM;
+	pid = clone(userspace_tramp, (void *) sp, flags, (void *) stub_stack);
 	if(pid < 0)
 		panic("start_userspace : clone failed, errno = %d", errno);
 
@@ -140,7 +232,7 @@ void start_userspace(int cpu)
 	if(munmap(stack, PAGE_SIZE) < 0)
 		panic("start_userspace : munmap failed, errno = %d\n", errno);
 
-	userspace_pid[cpu] = pid;
+	return(pid);
 }
 
 void userspace(union uml_pt_regs *regs)
@@ -174,7 +266,9 @@ void userspace(union uml_pt_regs *regs)
 		if(WIFSTOPPED(status)){
 		  	switch(WSTOPSIG(status)){
 			case SIGSEGV:
-                                handle_segv(pid, regs);
+                                if(PTRACE_FULL_FAULTINFO || !ptrace_faultinfo)
+                                        user_signal(SIGSEGV, regs, pid);
+                                else handle_segv(pid, regs);
 				break;
 			case SIGTRAP + 0x80:
 			        handle_trap(pid, regs, local_using_sysemu);
@@ -194,6 +288,7 @@ void userspace(union uml_pt_regs *regs)
 			        printk("userspace - child stopped with signal "
 				       "%d\n", WSTOPSIG(status));
 			}
+			pid = userspace_pid[0];
 			interrupt_end();
 
 			/* Avoid -ERESTARTSYS handling in host */
@@ -207,6 +302,67 @@ void userspace(union uml_pt_regs *regs)
 #define INIT_JMP_HALT 3
 #define INIT_JMP_REBOOT 4
 
+
+int copy_context_skas0(unsigned long new_stack, int pid)
+{
+	int err;
+	unsigned long regs[MAX_REG_NR];
+	unsigned long current_stack = current_stub_stack();
+	struct stub_data *data = (struct stub_data *) current_stack;
+	struct stub_data *child_data = (struct stub_data *) new_stack;
+	__u64 new_offset;
+	int new_fd = phys_mapping(to_phys((void *)new_stack), &new_offset);
+
+	/* prepare offset and fd of child's stack as argument for parent's
+	 * and child's mmap2 calls
+	 */
+	*data = ((struct stub_data) { .offset	= MMAP_OFFSET(new_offset),
+				      .fd	= new_fd,
+				      .timer	= ((struct itimerval)
+					           { { 0, 1000000 / hz() },
+						     { 0, 1000000 / hz() }})});
+	get_safe_registers(regs);
+
+	/* Set parent's instruction pointer to start of clone-stub */
+	regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE +
+				(unsigned long) stub_clone_handler -
+				(unsigned long) &__syscall_stub_start;
+	regs[REGS_SP_INDEX] = UML_CONFIG_STUB_DATA + PAGE_SIZE -
+		sizeof(void *);
+	err = ptrace_setregs(pid, regs);
+	if(err < 0)
+		panic("copy_context_skas0 : PTRACE_SETREGS failed, "
+		      "pid = %d, errno = %d\n", pid, errno);
+
+	/* set a well known return code for detection of child write failure */
+	child_data->err = 12345678;
+
+	/* Wait, until parent has finished its work: read child's pid from
+	 * parent's stack, and check, if bad result.
+	 */
+	wait_stub_done(pid, 0, "copy_context_skas0");
+
+	pid = data->err;
+	if(pid < 0)
+		panic("copy_context_skas0 - stub-parent reports error %d\n",
+		      pid);
+
+	/* Wait, until child has finished too: read child's result from
+	 * child's stack and check it.
+	 */
+	wait_stub_done(pid, -1, "copy_context_skas0");
+	if (child_data->err != UML_CONFIG_STUB_DATA)
+		panic("copy_context_skas0 - stub-child reports error %d\n",
+		      child_data->err);
+
+	if (ptrace(PTRACE_OLDSETOPTIONS, pid, NULL,
+		   (void *)PTRACE_O_TRACESYSGOOD) < 0)
+		panic("copy_context_skas0 : PTRACE_SETOPTIONS failed, "
+		      "errno = %d\n", errno);
+
+	return pid;
+}
+
 void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr,
 		void (*handler)(int))
 {
@@ -334,21 +490,19 @@ void reboot_skas(void)
 	siglongjmp(initial_jmpbuf, INIT_JMP_REBOOT);
 }
 
-void switch_mm_skas(int mm_fd)
+void switch_mm_skas(struct mm_id *mm_idp)
 {
 	int err;
 
 #warning need cpu pid in switch_mm_skas
-	err = ptrace(PTRACE_SWITCH_MM, userspace_pid[0], 0, mm_fd);
-	if(err)
-		panic("switch_mm_skas - PTRACE_SWITCH_MM failed, errno = %d\n",
-		      errno);
-}
-
-void kill_off_processes_skas(void)
-{
-#warning need to loop over userspace_pids in kill_off_processes_skas
-	os_kill_ptraced_process(userspace_pid[0], 1);
+	if(proc_mm){
+		err = ptrace(PTRACE_SWITCH_MM, userspace_pid[0], 0,
+			     mm_idp->u.mm_fd);
+		if(err)
+			panic("switch_mm_skas - PTRACE_SWITCH_MM failed, "
+			      "errno = %d\n", errno);
+	}
+	else userspace_pid[0] = mm_idp->u.pid;
 }
 
 /*
diff --git a/arch/um/kernel/skas/process_kern.c b/arch/um/kernel/skas/process_kern.c
--- a/arch/um/kernel/skas/process_kern.c
+++ b/arch/um/kernel/skas/process_kern.c
@@ -111,8 +111,7 @@ int copy_thread_skas(int nr, unsigned lo
   	void (*handler)(int);
 
 	if(current->thread.forking){
-	  	memcpy(&p->thread.regs.regs.skas, 
-		       &current->thread.regs.regs.skas, 
+	  	memcpy(&p->thread.regs.regs.skas, &regs->regs.skas,
 		       sizeof(p->thread.regs.regs.skas));
 		REGS_SET_SYSCALL_RETURN(p->thread.regs.regs.skas.regs, 0);
 		if(sp != 0) REGS_SP(p->thread.regs.regs.skas.regs) = sp;
@@ -176,12 +175,14 @@ static int start_kernel_proc(void *unuse
 	return(0);
 }
 
+extern int userspace_pid[];
+
 int start_uml_skas(void)
 {
-	start_userspace(0);
+	if(proc_mm)
+		userspace_pid[0] = start_userspace(0);
 
 	init_new_thread_signals(1);
-	uml_idle_timer();
 
 	init_task.thread.request.u.thread.proc = start_kernel_proc;
 	init_task.thread.request.u.thread.arg = NULL;
@@ -202,13 +203,30 @@ int thread_pid_skas(struct task_struct *
 	return(userspace_pid[0]);
 }
 
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
+void kill_off_processes_skas(void)
+{
+	if(proc_mm)
+#warning need to loop over userspace_pids in kill_off_processes_skas
+		os_kill_ptraced_process(userspace_pid[0], 1);
+	else {
+		struct task_struct *p;
+		int pid, me;
+
+		me = os_getpid();
+		for_each_process(p){
+			if(p->mm == NULL)
+				continue;
+
+			pid = p->mm->context.skas.id.u.pid;
+			os_kill_ptraced_process(pid, 1);
+		}
+	}
+}
+
+unsigned long current_stub_stack(void)
+{
+	if(current->mm == NULL)
+		return(0);
+
+	return(current->mm->context.skas.id.stack);
+}
diff --git a/arch/um/kernel/skas/syscall_user.c b/arch/um/kernel/skas/syscall_user.c
--- a/arch/um/kernel/skas/syscall_user.c
+++ b/arch/um/kernel/skas/syscall_user.c
@@ -15,7 +15,7 @@
 void handle_syscall(union uml_pt_regs *regs)
 {
 	long result;
-#if UML_CONFIG_SYSCALL_DEBUG
+#ifdef UML_CONFIG_SYSCALL_DEBUG
   	int index;
 
   	index = record_syscall_start(UPT_SYSCALL_NR(regs));
@@ -27,7 +27,7 @@ void handle_syscall(union uml_pt_regs *r
 	REGS_SET_SYSCALL_RETURN(regs->skas.regs, result);
 
 	syscall_trace(regs, 1);
-#if UML_CONFIG_SYSCALL_DEBUG
+#ifdef UML_CONFIG_SYSCALL_DEBUG
   	record_syscall_end(index, result);
 #endif
 }
diff --git a/arch/um/kernel/skas/time.c b/arch/um/kernel/skas/time.c
deleted file mode 100644
--- a/arch/um/kernel/skas/time.c
+++ /dev/null
@@ -1,30 +0,0 @@
-/* 
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#include <sys/signal.h>
-#include <sys/time.h>
-#include "time_user.h"
-#include "process.h"
-#include "user.h"
-
-void user_time_init_skas(void)
-{
-        if(signal(SIGALRM, (__sighandler_t) alarm_handler) == SIG_ERR)
-                panic("Couldn't set SIGALRM handler");
- 	if(signal(SIGVTALRM, (__sighandler_t) alarm_handler) == SIG_ERR)
- 		panic("Couldn't set SIGVTALRM handler");
-	set_interval(ITIMER_VIRTUAL);
-}
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/kernel/skas/tlb.c b/arch/um/kernel/skas/tlb.c
--- a/arch/um/kernel/skas/tlb.c
+++ b/arch/um/kernel/skas/tlb.c
@@ -6,6 +6,7 @@
 
 #include "linux/stddef.h"
 #include "linux/sched.h"
+#include "linux/config.h"
 #include "linux/mm.h"
 #include "asm/page.h"
 #include "asm/pgtable.h"
@@ -17,7 +18,7 @@
 #include "os.h"
 #include "tlb.h"
 
-static void do_ops(int fd, struct host_vm_op *ops, int last)
+static void do_ops(union mm_context *mmu, struct host_vm_op *ops, int last)
 {
 	struct host_vm_op *op;
 	int i;
@@ -26,18 +27,18 @@ static void do_ops(int fd, struct host_v
 		op = &ops[i];
 		switch(op->type){
 		case MMAP:
-			map(fd, op->u.mmap.addr, op->u.mmap.len,
+                        map(&mmu->skas.id, op->u.mmap.addr, op->u.mmap.len,
 			    op->u.mmap.r, op->u.mmap.w, op->u.mmap.x,
 			    op->u.mmap.fd, op->u.mmap.offset);
 			break;
 		case MUNMAP:
-			unmap(fd, (void *) op->u.munmap.addr,
+                        unmap(&mmu->skas.id, (void *) op->u.munmap.addr,
 			      op->u.munmap.len);
 			break;
 		case MPROTECT:
-			protect(fd, op->u.mprotect.addr, op->u.mprotect.len,
-				op->u.mprotect.r, op->u.mprotect.w,
-				op->u.mprotect.x);
+                        protect(&mmu->skas.id, op->u.mprotect.addr,
+                                op->u.mprotect.len, op->u.mprotect.r,
+                                op->u.mprotect.w, op->u.mprotect.x);
 			break;
 		default:
 			printk("Unknown op type %d in do_ops\n", op->type);
@@ -46,12 +47,15 @@ static void do_ops(int fd, struct host_v
 	}
 }
 
+extern int proc_mm;
+
 static void fix_range(struct mm_struct *mm, unsigned long start_addr,
 		      unsigned long end_addr, int force)
 {
-        int fd = mm->context.skas.mm_fd;
+        if(!proc_mm && (end_addr > CONFIG_STUB_START))
+                end_addr = CONFIG_STUB_START;
 
-        fix_range_common(mm, start_addr, end_addr, force, fd, do_ops);
+        fix_range_common(mm, start_addr, end_addr, force, do_ops);
 }
 
 void __flush_tlb_one_skas(unsigned long addr)
@@ -69,17 +73,20 @@ void flush_tlb_range_skas(struct vm_area
 
 void flush_tlb_mm_skas(struct mm_struct *mm)
 {
+	unsigned long end;
+
 	/* Don't bother flushing if this address space is about to be
          * destroyed.
          */
         if(atomic_read(&mm->mm_users) == 0)
                 return;
 
-        fix_range(mm, 0, host_task_size, 0);
-        flush_tlb_kernel_range_common(start_vm, end_vm);
+	end = proc_mm ? task_size : CONFIG_STUB_START;
+        fix_range(mm, 0, end, 0);
 }
 
 void force_flush_all_skas(void)
 {
-        fix_range(current->mm, 0, host_task_size, 1);
+	unsigned long end = proc_mm ? task_size : CONFIG_STUB_START;
+        fix_range(current->mm, 0, end, 1);
 }
diff --git a/arch/um/kernel/skas/trap_user.c b/arch/um/kernel/skas/trap_user.c
--- a/arch/um/kernel/skas/trap_user.c
+++ b/arch/um/kernel/skas/trap_user.c
@@ -58,7 +58,6 @@ void user_signal(int sig, union uml_pt_r
         int segv = ((sig == SIGFPE) || (sig == SIGSEGV) || (sig == SIGBUS) ||
                     (sig == SIGILL) || (sig == SIGTRAP));
 
-	regs->skas.is_user = 1;
 	if (segv)
 		get_skas_faultinfo(pid, &regs->skas.faultinfo);
 	info = &sig_info[sig];
diff --git a/arch/um/kernel/syscall_kern.c b/arch/um/kernel/syscall_kern.c
--- a/arch/um/kernel/syscall_kern.c
+++ b/arch/um/kernel/syscall_kern.c
@@ -31,7 +31,8 @@ long sys_fork(void)
 	long ret;
 
 	current->thread.forking = 1;
-        ret = do_fork(SIGCHLD, 0, NULL, 0, NULL, NULL);
+	ret = do_fork(SIGCHLD, UPT_SP(&current->thread.regs.regs),
+		      &current->thread.regs, 0, NULL, NULL);
 	current->thread.forking = 0;
 	return(ret);
 }
@@ -41,8 +42,9 @@ long sys_vfork(void)
 	long ret;
 
 	current->thread.forking = 1;
-	ret = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, 0, NULL, 0, NULL,
-		      NULL);
+	ret = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD,
+		      UPT_SP(&current->thread.regs.regs),
+		      &current->thread.regs, 0, NULL, NULL);
 	current->thread.forking = 0;
 	return(ret);
 }
@@ -162,14 +164,3 @@ int next_syscall_index(int limit)
 	spin_unlock(&syscall_lock);
 	return(ret);
 }
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/kernel/time.c b/arch/um/kernel/time.c
--- a/arch/um/kernel/time.c
+++ b/arch/um/kernel/time.c
@@ -33,7 +33,7 @@ void timer(void)
 	timeradd(&xtime, &local_offset, &xtime);
 }
 
-void set_interval(int timer_type)
+static void set_interval(int timer_type)
 {
 	int usec = 1000000/hz();
 	struct itimerval interval = ((struct itimerval) { { 0, usec },
@@ -45,12 +45,14 @@ void set_interval(int timer_type)
 
 void enable_timer(void)
 {
+	set_interval(ITIMER_VIRTUAL);
+}
+
+void prepare_timer(void * ptr)
+{
 	int usec = 1000000/hz();
-	struct itimerval enable = ((struct itimerval) { { 0, usec },
-							{ 0, usec }});
-	if(setitimer(ITIMER_VIRTUAL, &enable, NULL))
-		printk("enable_timer - setitimer failed, errno = %d\n",
-		       errno);
+	*(struct itimerval *)ptr = ((struct itimerval) { { 0, usec },
+							 { 0, usec }});
 }
 
 void disable_timer(void)
@@ -155,13 +157,15 @@ void idle_sleep(int secs)
 	nanosleep(&ts, NULL);
 }
 
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
+/* XXX This partly duplicates init_irq_signals */
+
+void user_time_init(void)
+{
+	set_handler(SIGVTALRM, (__sighandler_t) alarm_handler,
+		    SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGWINCH,
+		    SIGALRM, SIGUSR2, -1);
+	set_handler(SIGALRM, (__sighandler_t) alarm_handler,
+		    SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGWINCH,
+		    SIGVTALRM, SIGUSR2, -1);
+	set_interval(ITIMER_VIRTUAL);
+}
diff --git a/arch/um/kernel/time_kern.c b/arch/um/kernel/time_kern.c
--- a/arch/um/kernel/time_kern.c
+++ b/arch/um/kernel/time_kern.c
@@ -137,7 +137,10 @@ long um_stime(int __user *tptr)
 void timer_handler(int sig, union uml_pt_regs *regs)
 {
 	local_irq_disable();
-	update_process_times(CHOOSE_MODE(user_context(UPT_SP(regs)), (regs)->skas.is_user));
+	irq_enter();
+	update_process_times(CHOOSE_MODE(user_context(UPT_SP(regs)),
+					 (regs)->skas.is_user));
+	irq_exit();
 	local_irq_enable();
 	if(current_thread->cpu == 0)
 		timer_irq(regs);
@@ -162,7 +165,7 @@ int __init timer_init(void)
 {
 	int err;
 
-	CHOOSE_MODE(user_time_init_tt(), user_time_init_skas());
+	user_time_init();
 	err = request_irq(TIMER_IRQ, um_timer, SA_INTERRUPT, "timer", NULL);
 	if(err != 0)
 		printk(KERN_ERR "timer_init : request_irq failed - "
diff --git a/arch/um/kernel/tlb.c b/arch/um/kernel/tlb.c
--- a/arch/um/kernel/tlb.c
+++ b/arch/um/kernel/tlb.c
@@ -18,13 +18,15 @@
 #define ADD_ROUND(n, inc) (((n) + (inc)) & ~((inc) - 1))
 
 void fix_range_common(struct mm_struct *mm, unsigned long start_addr,
-                      unsigned long end_addr, int force, int data,
-                      void (*do_ops)(int, struct host_vm_op *, int))
+                      unsigned long end_addr, int force,
+                      void (*do_ops)(union mm_context *, struct host_vm_op *,
+                                     int))
 {
         pgd_t *npgd;
         pud_t *npud;
         pmd_t *npmd;
         pte_t *npte;
+        union mm_context *mmu = &mm->context;
         unsigned long addr, end;
         int r, w, x;
         struct host_vm_op ops[16];
@@ -40,7 +42,7 @@ void fix_range_common(struct mm_struct *
                                 end = end_addr;
                         if(force || pgd_newpage(*npgd)){
                                 op_index = add_munmap(addr, end - addr, ops,
-                                                      op_index, last_op, data,
+                                                      op_index, last_op, mmu,
                                                       do_ops);
                                 pgd_mkuptodate(*npgd);
                         }
@@ -55,7 +57,7 @@ void fix_range_common(struct mm_struct *
                                 end = end_addr;
                         if(force || pud_newpage(*npud)){
                                 op_index = add_munmap(addr, end - addr, ops,
-                                                      op_index, last_op, data,
+                                                      op_index, last_op, mmu,
                                                       do_ops);
                                 pud_mkuptodate(*npud);
                         }
@@ -70,7 +72,7 @@ void fix_range_common(struct mm_struct *
                                 end = end_addr;
                         if(force || pmd_newpage(*npmd)){
                                 op_index = add_munmap(addr, end - addr, ops,
-                                                      op_index, last_op, data,
+                                                      op_index, last_op, mmu,
                                                       do_ops);
                                 pmd_mkuptodate(*npmd);
                         }
@@ -93,21 +95,21 @@ void fix_range_common(struct mm_struct *
                                 op_index = add_mmap(addr,
                                                     pte_val(*npte) & PAGE_MASK,
                                                     PAGE_SIZE, r, w, x, ops,
-                                                    op_index, last_op, data,
+                                                    op_index, last_op, mmu,
                                                     do_ops);
                         else op_index = add_munmap(addr, PAGE_SIZE, ops,
-                                                   op_index, last_op, data,
+                                                   op_index, last_op, mmu,
                                                    do_ops);
                 }
                 else if(pte_newprot(*npte))
                         op_index = add_mprotect(addr, PAGE_SIZE, r, w, x, ops,
-                                                op_index, last_op, data,
+                                                op_index, last_op, mmu,
                                                 do_ops);
 
                 *npte = pte_mkuptodate(*npte);
                 addr += PAGE_SIZE;
         }
-        (*do_ops)(data, ops, op_index);
+        (*do_ops)(mmu, ops, op_index);
 }
 
 int flush_tlb_kernel_range_common(unsigned long start, unsigned long end)
@@ -195,51 +197,6 @@ int flush_tlb_kernel_range_common(unsign
         return(updated);
 }
 
-void flush_tlb_page(struct vm_area_struct *vma, unsigned long address)
-{
-        address &= PAGE_MASK;
-        flush_tlb_range(vma, address, address + PAGE_SIZE);
-}
-
-void flush_tlb_all(void)
-{
-        flush_tlb_mm(current->mm);
-}
-  
-void flush_tlb_kernel_range(unsigned long start, unsigned long end)
-{
-        CHOOSE_MODE_PROC(flush_tlb_kernel_range_tt,
-                         flush_tlb_kernel_range_common, start, end);
-}
-
-void flush_tlb_kernel_vm(void)
-{
-        CHOOSE_MODE(flush_tlb_kernel_vm_tt(),
-                    flush_tlb_kernel_range_common(start_vm, end_vm));
-}
-
-void __flush_tlb_one(unsigned long addr)
-{
-        CHOOSE_MODE_PROC(__flush_tlb_one_tt, __flush_tlb_one_skas, addr);
-}
-
-void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, 
-     unsigned long end)
-{
-        CHOOSE_MODE_PROC(flush_tlb_range_tt, flush_tlb_range_skas, vma, start,
-                         end);
-}
-
-void flush_tlb_mm(struct mm_struct *mm)
-{
-        CHOOSE_MODE_PROC(flush_tlb_mm_tt, flush_tlb_mm_skas, mm);
-}
-
-void force_flush_all(void)
-{
-        CHOOSE_MODE(force_flush_all_tt(), force_flush_all_skas());
-}
-
 pgd_t *pgd_offset_proc(struct mm_struct *mm, unsigned long address)
 {
         return(pgd_offset(mm, address));
@@ -270,9 +227,9 @@ pte_t *addr_pte(struct task_struct *task
 }
 
 int add_mmap(unsigned long virt, unsigned long phys, unsigned long len,
-     int r, int w, int x, struct host_vm_op *ops, int index,
-     int last_filled, int data,
-     void (*do_ops)(int, struct host_vm_op *, int))
+             int r, int w, int x, struct host_vm_op *ops, int index,
+             int last_filled, union mm_context *mmu,
+             void (*do_ops)(union mm_context *, struct host_vm_op *, int))
 {
         __u64 offset;
 	struct host_vm_op *last;
@@ -292,7 +249,7 @@ int add_mmap(unsigned long virt, unsigne
 	}
 
 	if(index == last_filled){
-		(*do_ops)(data, ops, last_filled);
+		(*do_ops)(mmu, ops, last_filled);
 		index = -1;
 	}
 
@@ -310,8 +267,8 @@ int add_mmap(unsigned long virt, unsigne
 }
 
 int add_munmap(unsigned long addr, unsigned long len, struct host_vm_op *ops,
-	       int index, int last_filled, int data,
-	       void (*do_ops)(int, struct host_vm_op *, int))
+	       int index, int last_filled, union mm_context *mmu,
+	       void (*do_ops)(union mm_context *, struct host_vm_op *, int))
 {
 	struct host_vm_op *last;
 
@@ -325,7 +282,7 @@ int add_munmap(unsigned long addr, unsig
 	}
 
 	if(index == last_filled){
-		(*do_ops)(data, ops, last_filled);
+		(*do_ops)(mmu, ops, last_filled);
 		index = -1;
 	}
 
@@ -337,8 +294,9 @@ int add_munmap(unsigned long addr, unsig
 }
 
 int add_mprotect(unsigned long addr, unsigned long len, int r, int w, int x,
-		 struct host_vm_op *ops, int index, int last_filled, int data,
-		 void (*do_ops)(int, struct host_vm_op *, int))
+                 struct host_vm_op *ops, int index, int last_filled,
+                 union mm_context *mmu,
+                 void (*do_ops)(union mm_context *, struct host_vm_op *, int))
 {
 	struct host_vm_op *last;
 
@@ -354,7 +312,7 @@ int add_mprotect(unsigned long addr, uns
 	}
 
 	if(index == last_filled){
-		(*do_ops)(data, ops, last_filled);
+		(*do_ops)(mmu, ops, last_filled);
 		index = -1;
 	}
 
@@ -367,3 +325,49 @@ int add_mprotect(unsigned long addr, uns
 						      .x	= x } } });
 	return(index);
 }
+
+void flush_tlb_page(struct vm_area_struct *vma, unsigned long address)
+{
+        address &= PAGE_MASK;
+        flush_tlb_range(vma, address, address + PAGE_SIZE);
+}
+
+void flush_tlb_all(void)
+{
+        flush_tlb_mm(current->mm);
+}
+
+void flush_tlb_kernel_range(unsigned long start, unsigned long end)
+{
+        CHOOSE_MODE_PROC(flush_tlb_kernel_range_tt,
+                         flush_tlb_kernel_range_common, start, end);
+}
+
+void flush_tlb_kernel_vm(void)
+{
+        CHOOSE_MODE(flush_tlb_kernel_vm_tt(),
+                    flush_tlb_kernel_range_common(start_vm, end_vm));
+}
+
+void __flush_tlb_one(unsigned long addr)
+{
+        CHOOSE_MODE_PROC(__flush_tlb_one_tt, __flush_tlb_one_skas, addr);
+}
+
+void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
+		     unsigned long end)
+{
+        CHOOSE_MODE_PROC(flush_tlb_range_tt, flush_tlb_range_skas, vma, start,
+                         end);
+}
+
+void flush_tlb_mm(struct mm_struct *mm)
+{
+        CHOOSE_MODE_PROC(flush_tlb_mm_tt, flush_tlb_mm_skas, mm);
+}
+
+void force_flush_all(void)
+{
+        CHOOSE_MODE(force_flush_all_tt(), force_flush_all_skas());
+}
+
diff --git a/arch/um/kernel/tt/Makefile b/arch/um/kernel/tt/Makefile
--- a/arch/um/kernel/tt/Makefile
+++ b/arch/um/kernel/tt/Makefile
@@ -3,27 +3,12 @@
 # Licensed under the GPL
 #
 
-extra-y := unmap_fin.o
-targets := unmap.o
-clean-files := unmap_tmp.o
-
 obj-y = exec_kern.o exec_user.o gdb.o ksyms.o mem.o mem_user.o process_kern.o \
-	syscall_kern.o syscall_user.o time.o tlb.o tracer.o trap_user.o \
+	syscall_kern.o syscall_user.o tlb.o tracer.o trap_user.o \
 	uaccess.o uaccess_user.o
 
 obj-$(CONFIG_PT_PROXY) += gdb_kern.o ptproxy/
 
-USER_OBJS := gdb.o time.o tracer.o
+USER_OBJS := gdb.o tracer.o
 
 include arch/um/scripts/Makefile.rules
-
-UNMAP_CFLAGS := $(patsubst -pg -DPROFILING,,$(USER_CFLAGS))
-UNMAP_CFLAGS := $(patsubst -fprofile-arcs -ftest-coverage,,$(UNMAP_CFLAGS))
-
-#XXX: partially copied from arch/um/scripts/Makefile.rules
-$(obj)/unmap.o: c_flags = -Wp,-MD,$(depfile) $(UNMAP_CFLAGS)
-
-$(obj)/unmap_fin.o : $(obj)/unmap.o
-	$(LD) -r -o $(obj)/unmap_tmp.o $< $(shell $(CC) -print-file-name=libc.a)
-	$(OBJCOPY) $(obj)/unmap_tmp.o $@ -G switcheroo
-
diff --git a/arch/um/kernel/tt/gdb.c b/arch/um/kernel/tt/gdb.c
--- a/arch/um/kernel/tt/gdb.c
+++ b/arch/um/kernel/tt/gdb.c
@@ -153,10 +153,10 @@ void remove_gdb_cb(void *unused)
 	exit_debugger_cb(NULL);
 }
 
-int gdb_remove(char *unused)
+int gdb_remove(int unused)
 {
 	initial_thread_cb(remove_gdb_cb, NULL);
-	return(0);
+        return 0;
 }
 
 void signal_usr1(int sig)
diff --git a/arch/um/kernel/tt/gdb_kern.c b/arch/um/kernel/tt/gdb_kern.c
--- a/arch/um/kernel/tt/gdb_kern.c
+++ b/arch/um/kernel/tt/gdb_kern.c
@@ -10,7 +10,7 @@
 #ifdef CONFIG_MCONSOLE
 
 extern int gdb_config(char *str);
-extern int gdb_remove(char *unused);
+extern int gdb_remove(int n);
 
 static struct mc_device gdb_mc = {
 	.name		= "gdb",
diff --git a/arch/um/kernel/tt/include/debug.h b/arch/um/kernel/tt/include/debug.h
--- a/arch/um/kernel/tt/include/debug.h
+++ b/arch/um/kernel/tt/include/debug.h
@@ -4,8 +4,8 @@
  * Licensed under the GPL
  */
 
-#ifndef __DEBUG_H
-#define __DEBUG_H
+#ifndef __UML_TT_DEBUG_H
+#define __UML_TT_DEBUG_H
 
 extern int debugger_proxy(int status, pid_t pid);
 extern void child_proxy(pid_t pid, int status);
@@ -13,17 +13,6 @@ extern void init_proxy (pid_t pid, int w
 extern int start_debugger(char *prog, int startup, int stop, int *debugger_fd);
 extern void fake_child_exit(void);
 extern int gdb_config(char *str);
-extern int gdb_remove(char *unused);
+extern int gdb_remove(int unused);
 
 #endif
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/kernel/tt/include/mode-tt.h b/arch/um/kernel/tt/include/mode-tt.h
--- a/arch/um/kernel/tt/include/mode-tt.h
+++ b/arch/um/kernel/tt/include/mode-tt.h
@@ -13,7 +13,6 @@ enum { OP_NONE, OP_EXEC, OP_FORK, OP_TRA
 extern int tracing_pid;
 
 extern int tracer(int (*init_proc)(void *), void *sp);
-extern void user_time_init_tt(void);
 extern void sig_handler_common_tt(int sig, void *sc);
 extern void syscall_handler_tt(int sig, union uml_pt_regs *regs);
 extern void reboot_tt(void);
diff --git a/arch/um/kernel/tt/process_kern.c b/arch/um/kernel/tt/process_kern.c
--- a/arch/um/kernel/tt/process_kern.c
+++ b/arch/um/kernel/tt/process_kern.c
@@ -266,10 +266,10 @@ int copy_thread_tt(int nr, unsigned long
 	}
 
 	if(current->thread.forking){
-		sc_to_sc(UPT_SC(&p->thread.regs.regs), 
-			 UPT_SC(&current->thread.regs.regs));
+		sc_to_sc(UPT_SC(&p->thread.regs.regs), UPT_SC(&regs->regs));
 		SC_SET_SYSCALL_RETURN(UPT_SC(&p->thread.regs.regs), 0);
-		if(sp != 0) SC_SP(UPT_SC(&p->thread.regs.regs)) = sp;
+		if(sp != 0)
+			SC_SP(UPT_SC(&p->thread.regs.regs)) = sp;
 	}
 	p->thread.mode.tt.extern_pid = new_pid;
 
@@ -459,14 +459,3 @@ int is_valid_pid(int pid)
 	read_unlock(&tasklist_lock);
 	return(0);
 }
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/kernel/tt/time.c b/arch/um/kernel/tt/time.c
deleted file mode 100644
--- a/arch/um/kernel/tt/time.c
+++ /dev/null
@@ -1,28 +0,0 @@
-/* 
- * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#include <signal.h>
-#include <sys/time.h>
-#include <time_user.h>
-#include "process.h"
-#include "user.h"
-
-void user_time_init_tt(void)
-{
-	if(signal(SIGVTALRM, (__sighandler_t) alarm_handler) == SIG_ERR)
-		panic("Couldn't set SIGVTALRM handler");
-	set_interval(ITIMER_VIRTUAL);
-}
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/kernel/tt/tlb.c b/arch/um/kernel/tt/tlb.c
--- a/arch/um/kernel/tt/tlb.c
+++ b/arch/um/kernel/tt/tlb.c
@@ -17,7 +17,7 @@
 #include "os.h"
 #include "tlb.h"
 
-static void do_ops(int unused, struct host_vm_op *ops, int last)
+static void do_ops(union mm_context *mmu, struct host_vm_op *ops, int last)
 {
 	struct host_vm_op *op;
 	int i;
@@ -55,7 +55,7 @@ static void fix_range(struct mm_struct *
                 panic("fix_range fixing wrong address space, current = 0x%p",
                       current);
 
-        fix_range_common(mm, start_addr, end_addr, force, 0, do_ops);
+        fix_range_common(mm, start_addr, end_addr, force, do_ops);
 }
 
 atomic_t vmchange_seq = ATOMIC_INIT(1);
diff --git a/arch/um/kernel/tt/unmap.c b/arch/um/kernel/tt/unmap.c
deleted file mode 100644
--- a/arch/um/kernel/tt/unmap.c
+++ /dev/null
@@ -1,31 +0,0 @@
-/* 
- * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#include <sys/mman.h>
-
-int switcheroo(int fd, int prot, void *from, void *to, int size)
-{
-	if(munmap(to, size) < 0){
-		return(-1);
-	}
-	if(mmap(to, size, prot,	MAP_SHARED | MAP_FIXED, fd, 0) != to){
-		return(-1);
-	}
-	if(munmap(from, size) < 0){
-		return(-1);
-	}
-	return(0);
-}
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c
--- a/arch/um/kernel/um_arch.c
+++ b/arch/um/kernel/um_arch.c
@@ -38,6 +38,9 @@
 #include "choose-mode.h"
 #include "mode_kern.h"
 #include "mode.h"
+#ifdef UML_CONFIG_MODE_SKAS
+#include "skas.h"
+#endif
 
 #define DEFAULT_COMMAND_LINE "root=98:0"
 
@@ -318,6 +321,7 @@ int linux_main(int argc, char **argv)
 	unsigned long avail, diff;
 	unsigned long virtmem_size, max_physmem;
 	unsigned int i, add;
+	char * mode;
 
 	for (i = 1; i < argc; i++){
 		if((i == 1) && (argv[i][0] == ' ')) continue;
@@ -338,6 +342,21 @@ int linux_main(int argc, char **argv)
 		exit(1);
 	}
 #endif
+
+#ifndef CONFIG_MODE_SKAS
+	mode = "TT";
+#else
+	/* Show to the user the result of selection */
+	if (mode_tt)
+		mode = "TT";
+	else if (proc_mm && ptrace_faultinfo)
+		mode = "SKAS3";
+	else
+		mode = "SKAS0";
+#endif
+
+	printf("UML running in %s mode\n", mode);
+
 	uml_start = CHOOSE_MODE_PROC(set_task_sizes_tt, set_task_sizes_skas, 0,
 				     &host_task_size, &task_size);
 
diff --git a/arch/um/kernel/uml.lds.S b/arch/um/kernel/uml.lds.S
--- a/arch/um/kernel/uml.lds.S
+++ b/arch/um/kernel/uml.lds.S
@@ -14,19 +14,10 @@ SECTIONS
   /* Used in arch/um/kernel/mem.c. Any memory between START and __binary_start
    * is remapped.*/
   __binary_start = .;
-#ifdef MODE_TT
-  .thread_private : {
-    __start_thread_private = .;
-    errno = .;
-    . += 4;
-    arch/um/kernel/tt/unmap_fin.o (.data)
-    __end_thread_private = .;
-  }
-  . = ALIGN(4096);
-  .remap : { arch/um/kernel/tt/unmap_fin.o (.text) }
 
-  /* We want it only if we are in MODE_TT. In both cases, however, when MODE_TT
-   * is off the resulting binary segfaults.*/
+#ifdef MODE_TT
+  .remap_data : { UNMAP_PATH (.data .bss) }
+  .remap : { UNMAP_PATH (.text) }
 
   . = ALIGN(4096);		/* Init code and data */
 #endif
@@ -39,6 +30,7 @@ SECTIONS
 	_einittext = .;
   }
   . = ALIGN(4096);
+
   .text      :
   {
     *(.text)
@@ -48,6 +40,12 @@ SECTIONS
     /* .gnu.warning sections are handled specially by elf32.em.  */
     *(.gnu.warning)
     *(.gnu.linkonce.t*)
+
+    . = ALIGN(4096);
+    __syscall_stub_start = .;
+    *(.__syscall_stub*)
+    __syscall_stub_end = .;
+    . = ALIGN(4096);
   }
 
   #include "asm/common.lds.S"
diff --git a/arch/um/os-Linux/elf_aux.c b/arch/um/os-Linux/elf_aux.c
--- a/arch/um/os-Linux/elf_aux.c
+++ b/arch/um/os-Linux/elf_aux.c
@@ -11,6 +11,7 @@
 #include <stddef.h>
 #include "init.h"
 #include "elf_user.h"
+#include "mem_user.h"
 
 #if ELF_CLASS == ELFCLASS32
 typedef Elf32_auxv_t elf_auxv_t;
@@ -40,6 +41,9 @@ __init void scan_elf_aux( char **envp)
 				break;
 			case AT_SYSINFO_EHDR:
 				vsyscall_ehdr = auxv->a_un.a_val;
+				/* See if the page is under TASK_SIZE */
+				if (vsyscall_ehdr < (unsigned long) envp)
+					vsyscall_ehdr = 0;
 				break;
 			case AT_HWCAP:
 				elf_aux_hwcap = auxv->a_un.a_val;
diff --git a/arch/um/os-Linux/sys-i386/registers.c b/arch/um/os-Linux/sys-i386/registers.c
--- a/arch/um/os-Linux/sys-i386/registers.c
+++ b/arch/um/os-Linux/sys-i386/registers.c
@@ -121,6 +121,11 @@ void init_registers(int pid)
 		      err);
 }
 
+void get_safe_registers(unsigned long *regs)
+{
+	memcpy(regs, exec_regs, HOST_FRAME_SIZE * sizeof(unsigned long));
+}
+
 /*
  * Overrides for Emacs so that we follow Linus's tabbing style.
  * Emacs will notice this stuff at the end of the file and automatically
diff --git a/arch/um/os-Linux/sys-x86_64/registers.c b/arch/um/os-Linux/sys-x86_64/registers.c
--- a/arch/um/os-Linux/sys-x86_64/registers.c
+++ b/arch/um/os-Linux/sys-x86_64/registers.c
@@ -69,6 +69,11 @@ void init_registers(int pid)
 		      err);
 }
 
+void get_safe_registers(unsigned long *regs)
+{
+	memcpy(regs, exec_regs, HOST_FRAME_SIZE * sizeof(unsigned long));
+}
+
 /*
  * Overrides for Emacs so that we follow Linus's tabbing style.
  * Emacs will notice this stuff at the end of the file and automatically
diff --git a/arch/um/os-Linux/user_syms.c b/arch/um/os-Linux/user_syms.c
--- a/arch/um/os-Linux/user_syms.c
+++ b/arch/um/os-Linux/user_syms.c
@@ -83,6 +83,9 @@ EXPORT_SYMBOL_PROTO(statfs64);
 
 EXPORT_SYMBOL_PROTO(getuid);
 
+EXPORT_SYMBOL_PROTO(fsync);
+EXPORT_SYMBOL_PROTO(fdatasync);
+
 /*
  * Overrides for Emacs so that we follow Linus's tabbing style.
  * Emacs will notice this stuff at the end of the file and automatically
diff --git a/arch/um/scripts/Makefile.rules b/arch/um/scripts/Makefile.rules
--- a/arch/um/scripts/Makefile.rules
+++ b/arch/um/scripts/Makefile.rules
@@ -10,6 +10,17 @@ USER_OBJS := $(foreach file,$(USER_OBJS)
 $(USER_OBJS) : c_flags = -Wp,-MD,$(depfile) $(USER_CFLAGS) \
 	$(CFLAGS_$(notdir $@))
 
+# The stubs and unmap.o can't try to call mcount or update basic block data
+define unprofile
+	$(patsubst -pg,,$(patsubst -fprofile-arcs -ftest-coverage,,$(1)))
+endef
+
+
+# The stubs and unmap.o can't try to call mcount or update basic block data
+define unprofile
+	$(patsubst -pg,,$(patsubst -fprofile-arcs -ftest-coverage,,$(1)))
+endef
+
 quiet_cmd_make_link = SYMLINK $@
 cmd_make_link       = ln -sf $(srctree)/arch/$(SUBARCH)/$($(notdir $@)-dir)/$(notdir $@) $@
 
diff --git a/arch/um/scripts/Makefile.unmap b/arch/um/scripts/Makefile.unmap
new file mode 100644
--- /dev/null
+++ b/arch/um/scripts/Makefile.unmap
@@ -0,0 +1,22 @@
+clean-files += unmap_tmp.o unmap_fin.o unmap.o
+
+ifdef CONFIG_MODE_TT
+
+#Always build unmap_fin.o
+extra-y += unmap_fin.o
+#Do dependency tracking for unmap.o (it will be always built, but won't get the tracking unless we use this).
+targets += unmap.o
+
+#XXX: partially copied from arch/um/scripts/Makefile.rules
+$(obj)/unmap.o: _c_flags = $(call unprofile,$(CFLAGS))
+
+quiet_cmd_wrapld = LD      $@
+define cmd_wrapld
+	$(LD) $(LDFLAGS) -r -o $(obj)/unmap_tmp.o $< $(shell $(CC) $(CFLAGS) -print-file-name=libc.a); \
+	$(OBJCOPY) $(UML_OBJCOPYFLAGS) $(obj)/unmap_tmp.o $@ -G switcheroo
+endef
+
+$(obj)/unmap_fin.o : $(obj)/unmap.o FORCE
+	$(call if_changed,wrapld)
+
+endif
diff --git a/arch/um/sys-i386/Makefile b/arch/um/sys-i386/Makefile
--- a/arch/um/sys-i386/Makefile
+++ b/arch/um/sys-i386/Makefile
@@ -1,6 +1,6 @@
 obj-y = bitops.o bugs.o checksum.o delay.o fault.o ksyms.o ldt.o ptrace.o \
-	ptrace_user.o semaphore.o signal.o sigcontext.o syscalls.o sysrq.o \
-	sys_call_table.o
+	ptrace_user.o semaphore.o signal.o sigcontext.o stub.o stub_segv.o \
+	syscalls.o sysrq.o sys_call_table.o
 
 obj-$(CONFIG_HIGHMEM) += highmem.o
 obj-$(CONFIG_MODULES) += module.o
@@ -16,4 +16,14 @@ semaphore.c-dir = kernel
 highmem.c-dir = mm
 module.c-dir = kernel
 
+STUB_CFLAGS = -Wp,-MD,$(depfile) $(call unprofile,$(USER_CFLAGS))
+
+# _cflags works with kernel files, not with userspace ones, but c_flags does,
+# why ask why?
+$(obj)/stub_segv.o : c_flags = $(STUB_CFLAGS)
+
+$(obj)/stub.o : a_flags = $(STUB_CFLAGS)
+
 subdir- := util
+
+include arch/um/scripts/Makefile.unmap
diff --git a/arch/um/sys-i386/ldt.c b/arch/um/sys-i386/ldt.c
--- a/arch/um/sys-i386/ldt.c
+++ b/arch/um/sys-i386/ldt.c
@@ -4,96 +4,106 @@
  */
 
 #include "linux/config.h"
+#include "linux/sched.h"
 #include "linux/slab.h"
+#include "linux/types.h"
 #include "asm/uaccess.h"
 #include "asm/ptrace.h"
+#include "asm/smp.h"
+#include "asm/ldt.h"
 #include "choose-mode.h"
 #include "kern.h"
+#include "mode_kern.h"
 
 #ifdef CONFIG_MODE_TT
-extern int modify_ldt(int func, void *ptr, unsigned long bytecount);
 
-/* XXX this needs copy_to_user and copy_from_user */
+extern int modify_ldt(int func, void *ptr, unsigned long bytecount);
 
-int sys_modify_ldt_tt(int func, void __user *ptr, unsigned long bytecount)
+static int do_modify_ldt_tt(int func, void *ptr, unsigned long bytecount)
 {
-	if (!access_ok(VERIFY_READ, ptr, bytecount))
-		return -EFAULT;
-
 	return modify_ldt(func, ptr, bytecount);
 }
+
 #endif
 
 #ifdef CONFIG_MODE_SKAS
-extern int userspace_pid[];
 
+#include "skas.h"
 #include "skas_ptrace.h"
 
-int sys_modify_ldt_skas(int func, void __user *ptr, unsigned long bytecount)
+static int do_modify_ldt_skas(int func, void *ptr, unsigned long bytecount)
 {
 	struct ptrace_ldt ldt;
-	void *buf;
-	int res, n;
+	u32 cpu;
+	int res;
+
+	ldt = ((struct ptrace_ldt) { .func	= func,
+				     .ptr	= ptr,
+				     .bytecount = bytecount });
 
-	buf = kmalloc(bytecount, GFP_KERNEL);
-	if(buf == NULL)
-		return(-ENOMEM);
+	cpu = get_cpu();
+	res = ptrace(PTRACE_LDT, userspace_pid[cpu], 0, (unsigned long) &ldt);
+	put_cpu();
 
-	res = 0;
+	return res;
+}
+#endif
+
+int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
+{
+	struct user_desc info;
+	int res = 0;
+	void *buf = NULL;
+	void *p = NULL; /* What we pass to host. */
 
 	switch(func){
 	case 1:
-	case 0x11:
-		res = copy_from_user(buf, ptr, bytecount);
+	case 0x11: /* write_ldt */
+		/* Do this check now to avoid overflows. */
+		if (bytecount != sizeof(struct user_desc)) {
+			res = -EINVAL;
+			goto out;
+		}
+
+		if(copy_from_user(&info, ptr, sizeof(info))) {
+			res = -EFAULT;
+			goto out;
+		}
+
+		p = &info;
 		break;
-	}
+	case 0:
+	case 2: /* read_ldt */
 
-	if(res != 0){
-		res = -EFAULT;
+		/* The use of info avoids kmalloc on the write case, not on the
+		 * read one. */
+		buf = kmalloc(bytecount, GFP_KERNEL);
+		if (!buf) {
+			res = -ENOMEM;
+			goto out;
+		}
+		p = buf;
+	default:
+		res = -ENOSYS;
 		goto out;
 	}
 
-	ldt = ((struct ptrace_ldt) { .func	= func,
-				     .ptr	= buf,
-				     .bytecount = bytecount });
-#warning Need to look up userspace_pid by cpu
-	res = ptrace(PTRACE_LDT, userspace_pid[0], 0, (unsigned long) &ldt);
+	res = CHOOSE_MODE_PROC(do_modify_ldt_tt, do_modify_ldt_skas, func,
+				p, bytecount);
 	if(res < 0)
 		goto out;
 
 	switch(func){
 	case 0:
 	case 2:
-		n = res;
-		res = copy_to_user(ptr, buf, n);
-		if(res != 0)
+		/* Modify_ldt was for reading and returned the number of read
+		 * bytes.*/
+		if(copy_to_user(ptr, p, res))
 			res = -EFAULT;
-		else 
-			res = n;
 		break;
 	}
 
- out:
+out:
 	kfree(buf);
-	return(res);
-}
-#endif
-
-int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
-{
-	return(CHOOSE_MODE_PROC(sys_modify_ldt_tt, sys_modify_ldt_skas, func, 
-				ptr, bytecount));
+	return res;
 }
-
-
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/sys-i386/signal.c b/arch/um/sys-i386/signal.c
--- a/arch/um/sys-i386/signal.c
+++ b/arch/um/sys-i386/signal.c
@@ -312,7 +312,7 @@ long sys_sigreturn(struct pt_regs regs)
 	unsigned long __user *extramask = frame->extramask;
 	int sig_size = (_NSIG_WORDS - 1) * sizeof(unsigned long);
 
-	if(copy_from_user(&set.sig[0], oldmask, sizeof(&set.sig[0])) ||
+	if(copy_from_user(&set.sig[0], oldmask, sizeof(set.sig[0])) ||
 	   copy_from_user(&set.sig[1], extramask, sig_size))
 		goto segfault;
 
diff --git a/arch/um/sys-i386/stub.S b/arch/um/sys-i386/stub.S
new file mode 100644
--- /dev/null
+++ b/arch/um/sys-i386/stub.S
@@ -0,0 +1,8 @@
+#include "uml-config.h"
+
+	.globl syscall_stub
+.section .__syscall_stub, "x"
+syscall_stub:
+	int 	$0x80
+	mov	%eax, UML_CONFIG_STUB_DATA
+	int3
diff --git a/arch/um/sys-i386/stub_segv.c b/arch/um/sys-i386/stub_segv.c
new file mode 100644
--- /dev/null
+++ b/arch/um/sys-i386/stub_segv.c
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com)
+ * Licensed under the GPL
+ */
+
+#include <signal.h>
+#include <asm/sigcontext.h>
+#include <asm/unistd.h>
+#include "uml-config.h"
+#include "sysdep/sigcontext.h"
+#include "sysdep/faultinfo.h"
+
+void __attribute__ ((__section__ (".__syscall_stub")))
+stub_segv_handler(int sig)
+{
+	struct sigcontext *sc = (struct sigcontext *) (&sig + 1);
+
+	GET_FAULTINFO_FROM_SC(*((struct faultinfo *) UML_CONFIG_STUB_DATA),
+			      sc);
+
+	__asm__("movl %0, %%eax ; int $0x80": : "g" (__NR_getpid));
+	__asm__("movl %%eax, %%ebx ; movl %0, %%eax ; movl %1, %%ecx ;"
+		"int $0x80": : "g" (__NR_kill), "g" (SIGUSR1));
+	/* Load pointer to sigcontext into esp, since we need to leave
+	 * the stack in its original form when we do the sigreturn here, by
+	 * hand.
+	 */
+	__asm__("mov %0,%%esp ; movl %1, %%eax ; "
+		"int $0x80" : : "a" (sc), "g" (__NR_sigreturn));
+}
diff --git a/arch/um/sys-i386/syscalls.c b/arch/um/sys-i386/syscalls.c
--- a/arch/um/sys-i386/syscalls.c
+++ b/arch/um/sys-i386/syscalls.c
@@ -69,15 +69,11 @@ long sys_clone(unsigned long clone_flags
 {
 	long ret;
 
-	/* XXX: normal arch do here this pass, and also pass the regs to
-	 * do_fork, instead of NULL. Currently the arch-independent code
-	 * ignores these values, while the UML code (actually it's
-	 * copy_thread) does the right thing. But this should change,
-	 probably. */
-	/*if (!newsp)
-		newsp = UPT_SP(current->thread.regs);*/
+	if (!newsp)
+		newsp = UPT_SP(&current->thread.regs.regs);
 	current->thread.forking = 1;
-	ret = do_fork(clone_flags, newsp, NULL, 0, parent_tid, child_tid);
+	ret = do_fork(clone_flags, newsp, &current->thread.regs, 0, parent_tid,
+		      child_tid);
 	current->thread.forking = 0;
 	return(ret);
 }
@@ -197,14 +193,3 @@ long sys_sigaction(int sig, const struct
 
 	return ret;
 }
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/sys-i386/unmap.c b/arch/um/sys-i386/unmap.c
new file mode 100644
--- /dev/null
+++ b/arch/um/sys-i386/unmap.c
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
+ * Licensed under the GPL
+ */
+
+#include <linux/mman.h>
+#include <asm/unistd.h>
+
+static int errno;
+
+static inline _syscall2(int,munmap,void *,start,size_t,len)
+static inline _syscall6(void *,mmap2,void *,addr,size_t,len,int,prot,int,flags,int,fd,off_t,offset)
+int switcheroo(int fd, int prot, void *from, void *to, int size)
+{
+	if(munmap(to, size) < 0){
+		return(-1);
+	}
+	if(mmap2(to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) == (void*) -1 ){
+		return(-1);
+	}
+	if(munmap(from, size) < 0){
+		return(-1);
+	}
+	return(0);
+}
diff --git a/arch/um/sys-x86_64/Makefile b/arch/um/sys-x86_64/Makefile
--- a/arch/um/sys-x86_64/Makefile
+++ b/arch/um/sys-x86_64/Makefile
@@ -6,8 +6,8 @@
 
 #XXX: why into lib-y?
 lib-y = bitops.o bugs.o csum-partial.o delay.o fault.o mem.o memcpy.o \
-	ptrace.o ptrace_user.o semaphore.o sigcontext.o signal.o \
-	syscalls.o sysrq.o thunk.o syscall_table.o
+	ptrace.o ptrace_user.o semaphore.o sigcontext.o signal.o stub.o \
+	stub_segv.o syscalls.o syscall_table.o sysrq.o thunk.o
 
 obj-y := ksyms.o
 obj-$(CONFIG_MODULES) += module.o um_module.o
@@ -28,4 +28,14 @@ semaphore.c-dir = kernel
 thunk.S-dir = lib
 module.c-dir = kernel
 
+STUB_CFLAGS = -Wp,-MD,$(depfile) $(call unprofile,$(USER_CFLAGS))
+
+# _cflags works with kernel files, not with userspace ones, but c_flags does,
+# why ask why?
+$(obj)/stub_segv.o : c_flags = $(STUB_CFLAGS)
+
+$(obj)/stub.o : a_flags = $(STUB_CFLAGS)
+
 subdir- := util
+
+include arch/um/scripts/Makefile.unmap
diff --git a/arch/um/sys-x86_64/signal.c b/arch/um/sys-x86_64/signal.c
--- a/arch/um/sys-x86_64/signal.c
+++ b/arch/um/sys-x86_64/signal.c
@@ -168,7 +168,7 @@ int setup_signal_stack_si(unsigned long 
 
 	frame = (struct rt_sigframe __user *)
 		round_down(stack_top - sizeof(struct rt_sigframe), 16) - 8;
-	((unsigned char *) frame) -= 128;
+        frame = (struct rt_sigframe *) ((unsigned long) frame - 128);
 
 	if (!access_ok(VERIFY_WRITE, fp, sizeof(struct _fpstate)))
 		goto out;
diff --git a/arch/um/sys-x86_64/stub.S b/arch/um/sys-x86_64/stub.S
new file mode 100644
--- /dev/null
+++ b/arch/um/sys-x86_64/stub.S
@@ -0,0 +1,15 @@
+#include "uml-config.h"
+
+	.globl syscall_stub
+.section .__syscall_stub, "x"
+syscall_stub:
+	syscall
+	/* We don't have 64-bit constants, so this constructs the address
+	 * we need.
+	 */
+	movq	$(UML_CONFIG_STUB_DATA >> 32), %rbx
+	salq	$32, %rbx
+	movq	$(UML_CONFIG_STUB_DATA & 0xffffffff), %rcx
+	or	%rcx, %rbx
+	movq	%rax, (%rbx)
+	int3
diff --git a/arch/um/sys-x86_64/stub_segv.c b/arch/um/sys-x86_64/stub_segv.c
new file mode 100644
--- /dev/null
+++ b/arch/um/sys-x86_64/stub_segv.c
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com)
+ * Licensed under the GPL
+ */
+
+#include <signal.h>
+#include <linux/compiler.h>
+#include <asm/unistd.h>
+#include "uml-config.h"
+#include "sysdep/sigcontext.h"
+#include "sysdep/faultinfo.h"
+
+void __attribute__ ((__section__ (".__syscall_stub")))
+stub_segv_handler(int sig)
+{
+	struct ucontext *uc;
+
+	__asm__("movq %%rdx, %0" : "=g" (uc) :);
+        GET_FAULTINFO_FROM_SC(*((struct faultinfo *) UML_CONFIG_STUB_DATA),
+                              &uc->uc_mcontext);
+
+	__asm__("movq %0, %%rax ; syscall": : "g" (__NR_getpid));
+	__asm__("movq %%rax, %%rdi ; movq %0, %%rax ; movq %1, %%rsi ;"
+		"syscall": : "g" (__NR_kill), "g" (SIGUSR1));
+	/* Two popqs to restore the stack to the state just before entering
+	 * the handler, one pops the return address, the other pops the frame
+	 * pointer.
+	 */
+	__asm__("popq %%rax ; popq %%rax ; movq %0, %%rax ; syscall" : : "g"
+		(__NR_rt_sigreturn));
+}
diff --git a/arch/um/sys-x86_64/syscalls.c b/arch/um/sys-x86_64/syscalls.c
--- a/arch/um/sys-x86_64/syscalls.c
+++ b/arch/um/sys-x86_64/syscalls.c
@@ -174,26 +174,11 @@ long sys_clone(unsigned long clone_flags
 {
 	long ret;
 
-	/* XXX: normal arch do here this pass, and also pass the regs to
-	 * do_fork, instead of NULL. Currently the arch-independent code
-	 * ignores these values, while the UML code (actually it's
-	 * copy_thread) does the right thing. But this should change,
-	 probably. */
-	/*if (!newsp)
-		newsp = UPT_SP(current->thread.regs);*/
+	if (!newsp)
+		newsp = UPT_SP(&current->thread.regs.regs);
 	current->thread.forking = 1;
-	ret = do_fork(clone_flags, newsp, NULL, 0, parent_tid, child_tid);
+	ret = do_fork(clone_flags, newsp, &current->thread.regs, 0, parent_tid,
+		      child_tid);
 	current->thread.forking = 0;
 	return(ret);
 }
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/sys-x86_64/unmap.c b/arch/um/sys-x86_64/unmap.c
new file mode 100644
--- /dev/null
+++ b/arch/um/sys-x86_64/unmap.c
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
+ * Licensed under the GPL
+ */
+
+#include <linux/mman.h>
+#include <asm/unistd.h>
+
+static int errno;
+
+static inline _syscall2(int,munmap,void *,start,size_t,len)
+static inline _syscall6(void *,mmap,void *,addr,size_t,len,int,prot,int,flags,int,fd,off_t,offset)
+int switcheroo(int fd, int prot, void *from, void *to, int size)
+{
+	if(munmap(to, size) < 0){
+		return(-1);
+	}
+	if(mmap(to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) == (void*) -1){
+		return(-1);
+	}
+	if(munmap(from, size) < 0){
+		return(-1);
+	}
+	return(0);
+}
diff --git a/arch/v850/Kconfig b/arch/v850/Kconfig
--- a/arch/v850/Kconfig
+++ b/arch/v850/Kconfig
@@ -218,6 +218,8 @@ menu "Processor type and features"
 	     a lot of RAM, and you need to able to allocate very large
 	     contiguous chunks. If unsure, say N.
 
+source "mm/Kconfig"
+
 endmenu
 
 
@@ -248,6 +250,8 @@ source "fs/Kconfig.binfmt"
 
 endmenu
 
+source "net/Kconfig"
+
 #############################################################################
 
 source "drivers/base/Kconfig"
@@ -281,7 +285,7 @@ source "drivers/ieee1394/Kconfig"
 
 source "drivers/message/i2o/Kconfig"
 
-source "net/Kconfig"
+source "drivers/net/Kconfig"
 
 source "drivers/isdn/Kconfig"
 
diff --git a/arch/v850/Makefile b/arch/v850/Makefile
--- a/arch/v850/Makefile
+++ b/arch/v850/Makefile
@@ -1,8 +1,8 @@
 #
 # arch/v850/Makefile
 #
-#  Copyright (C) 2001,02,03  NEC Corporation
-#  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
+#  Copyright (C) 2001,02,03,05  NEC Corporation
+#  Copyright (C) 2001,02,03,05  Miles Bader <miles@gnu.org>
 #
 # This file is included by the global makefile so that you can add your own
 # architecture-specific flags and dependencies. Remember to do have actions
@@ -22,6 +22,9 @@ CFLAGS += -ffixed-r16 -mno-prolog-functi
 CFLAGS += -fno-builtin
 CFLAGS += -D__linux__ -DUTS_SYSNAME=\"uClinux\"
 
+# By default, build a kernel that runs on the gdb v850 simulator.
+KBUILD_DEFCONFIG := sim_defconfig
+
 # This prevents the linker from consolidating the .gnu.linkonce.this_module
 # section into .text (which the v850 default linker script for -r does for
 # some reason)
diff --git a/arch/v850/README b/arch/v850/README
--- a/arch/v850/README
+++ b/arch/v850/README
@@ -1,31 +1,43 @@
 This port to the NEC V850E processor supports the following platforms:
 
-   + The gdb v850e simulator (CONFIG_V850E_SIM).
+   "sim"
+	The gdb v850e simulator (CONFIG_V850E_SIM).
 
-   + The Midas labs RTE-V850E/MA1-CB and RTE-V850E/NB85E-CB evaluation boards
-     (CONFIG_RTE_CB_MA1 and CONFIG_RTE_CB_NB85E).  This support has only been
-     tested when running with the Multi-debugger monitor ROM (for the Green
-     Hills Multi debugger).  The optional NEC Solution Gear RTE-MOTHER-A
-     motherboard is also supported, which allows PCI boards to be used
-     (CONFIG_RTE_MB_A_PCI).
-
-   + The Midas labs RTE-V850E/ME2-CB evaluation board (CONFIG_RTE_CB_ME2).
-     This has only been tested using a kernel downloaded via an ICE connection
-     using the Multi debugger.  Support for the RTE-MOTHER-A is present, but
-     hasn't been tested (unlike the other Midas labs cpu boards, the
-     RTE-V850E/ME2-CB includes an ethernet adaptor).
-
-   + The NEC AS85EP1 V850E evaluation chip/board (CONFIG_V850E_AS85EP1).
-
-   + The NEC `Anna' (board/chip) implementation of the V850E2 processor
-     (CONFIG_V850E2_ANNA).
-
-   + The sim85e2c and sim85e2s simulators, which are verilog simulations of
-     the V850E2 NA85E2C/NA85E2S cpu cores (CONFIG_V850E2_SIM85E2C and
-     CONFIG_V850E2_SIM85E2S).
-
-   + A FPGA implementation of the V850E2 NA85E2C cpu core
-     (CONFIG_V850E2_FPGA85E2C).
+   "rte-ma1-cb"
+	The Midas labs RTE-V850E/MA1-CB and RTE-V850E/NB85E-CB evaluation
+	boards (CONFIG_RTE_CB_MA1 and CONFIG_RTE_CB_NB85E).  This support
+	has only been tested when running with the Multi-debugger monitor
+	ROM (for the Green Hills Multi debugger).  The optional NEC
+	Solution Gear RTE-MOTHER-A motherboard is also supported, which
+	allows PCI boards to be used (CONFIG_RTE_MB_A_PCI).
+
+   "rte-me2-cb"
+	The Midas labs RTE-V850E/ME2-CB evaluation board (CONFIG_RTE_CB_ME2).
+     	This has only been tested using a kernel downloaded via an ICE
+     	connection using the Multi debugger.  Support for the RTE-MOTHER-A is
+     	present, but hasn't been tested (unlike the other Midas labs cpu
+     	boards, the RTE-V850E/ME2-CB includes an ethernet adaptor).
+
+   "as85ep1"
+	The NEC AS85EP1 V850E evaluation chip/board (CONFIG_V850E_AS85EP1).
+
+   "anna"
+	The NEC `Anna' (board/chip) implementation of the V850E2 processor
+	(CONFIG_V850E2_ANNA).
+
+   "sim85e2c", "sim85e2s"
+   	The sim85e2c and sim85e2s simulators, which are verilog simulations
+	of the V850E2 NA85E2C/NA85E2S cpu cores (CONFIG_V850E2_SIM85E2C and
+	CONFIG_V850E2_SIM85E2S).
+
+   "fpga85e2c"
+	A FPGA implementation of the V850E2 NA85E2C cpu core
+	(CONFIG_V850E2_FPGA85E2C).
+
+To get a default kernel configuration for a particular platform, you can
+use a <platform>_defconfig make target (e.g., "make rte-me2-cb_defconfig");
+to see which default configurations are possible, look in the directory
+"arch/v850/configs".
 
 Porting to anything with a V850E/MA1 or MA2 processor should be simple.
 See the file <asm-v850/machdep.h> and the files it includes for an example of
diff --git a/arch/v850/configs/rte-ma1-cb_defconfig b/arch/v850/configs/rte-ma1-cb_defconfig
new file mode 100644
--- /dev/null
+++ b/arch/v850/configs/rte-ma1-cb_defconfig
@@ -0,0 +1,605 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.12-uc0
+# Thu Jul 21 11:08:27 2005
+#
+# CONFIG_MMU is not set
+# CONFIG_UID16 is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+# CONFIG_ISA is not set
+# CONFIG_ISAPNP is not set
+# CONFIG_EISA is not set
+# CONFIG_MCA is not set
+CONFIG_V850=y
+
+#
+# Processor type and features
+#
+# CONFIG_V850E_SIM is not set
+CONFIG_RTE_CB_MA1=y
+# CONFIG_RTE_CB_NB85E is not set
+# CONFIG_RTE_CB_ME2 is not set
+# CONFIG_V850E_AS85EP1 is not set
+# CONFIG_V850E2_SIM85E2C is not set
+# CONFIG_V850E2_SIM85E2S is not set
+# CONFIG_V850E2_FPGA85E2C is not set
+# CONFIG_V850E2_ANNA is not set
+CONFIG_V850E=y
+CONFIG_V850E_MA1=y
+CONFIG_RTE_CB=y
+CONFIG_RTE_CB_MULTI=y
+CONFIG_RTE_CB_MULTI_DBTRAP=y
+# CONFIG_RTE_CB_MA1_KSRAM is not set
+CONFIG_RTE_MB_A_PCI=y
+CONFIG_RTE_GBUS_INT=y
+CONFIG_PCI=y
+CONFIG_V850E_INTC=y
+CONFIG_V850E_TIMER_D=y
+# CONFIG_V850E_CACHE is not set
+# CONFIG_V850E2_CACHE is not set
+CONFIG_NO_CACHE=y
+CONFIG_ZERO_BSS=y
+# CONFIG_V850E_HIGHRES_TIMER is not set
+# CONFIG_RESET_GUARD is not set
+CONFIG_LARGE_ALLOCS=y
+
+#
+# Code maturity level options
+#
+# CONFIG_EXPERIMENTAL is not set
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_SYSCTL is not set
+# CONFIG_AUDIT is not set
+# CONFIG_HOTPLUG is not set
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_EMBEDDED=y
+# CONFIG_KALLSYMS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+# CONFIG_BASE_FULL is not set
+# CONFIG_FUTEX is not set
+# CONFIG_EPOLL is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_BASE_SMALL=1
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_OBSOLETE_MODPARM=y
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+
+#
+# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
+#
+# CONFIG_PCI_LEGACY_PROC is not set
+# CONFIG_PCI_NAMES is not set
+# CONFIG_PCI_DEBUG is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PCI Hotplug Support
+#
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_FLAT=y
+# CONFIG_BINFMT_ZFLAT is not set
+# CONFIG_BINFMT_SHARED_FLAT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+# CONFIG_MTD_PARTITIONS is not set
+
+#
+# User Modules And Translation Layers
+#
+# CONFIG_MTD_CHAR is not set
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+CONFIG_MTD_SLRAM=y
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_RAM is not set
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CDROM_PKTCDVD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_AS is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# Disk device support
+#
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_SCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Networking support
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_PACKET is not set
+# CONFIG_UNIX is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_TUNNEL is not set
+# CONFIG_IP_TCPDIAG is not set
+# CONFIG_IP_TCPDIAG_IPV6 is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_NET_VENDOR_SMC is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+# CONFIG_NE2000 is not set
+CONFIG_NET_PCI=y
+# CONFIG_PCNET32 is not set
+# CONFIG_AMD8111_ETH is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_DGRS is not set
+CONFIG_EEPRO100=y
+# CONFIG_E100 is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_8139TOO 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
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_R8169 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_VIA_VELOCITY is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_V850E_UART=y
+CONFIG_V850E_UART_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+# CONFIG_UNIX98_PTYS is not set
+# CONFIG_LEGACY_PTYS is not set
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# File systems
+#
+# CONFIG_EXT2_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+
+#
+# XFS support
+#
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+CONFIG_ROMFS_FS=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_SYSFS=y
+# CONFIG_TMPFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_SUNRPC=y
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+# CONFIG_USB is not set
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_MAGIC_SYSRQ is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_FS is not set
+# CONFIG_NO_KERNEL_MSG is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC32 is not set
+# CONFIG_LIBCRC32C is not set
diff --git a/arch/v850/configs/rte-me2-cb_defconfig b/arch/v850/configs/rte-me2-cb_defconfig
new file mode 100644
--- /dev/null
+++ b/arch/v850/configs/rte-me2-cb_defconfig
@@ -0,0 +1,453 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.12-uc0
+# Thu Jul 21 11:30:08 2005
+#
+# CONFIG_MMU is not set
+# CONFIG_UID16 is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+# CONFIG_ISA is not set
+# CONFIG_ISAPNP is not set
+# CONFIG_EISA is not set
+# CONFIG_MCA is not set
+CONFIG_V850=y
+
+#
+# Processor type and features
+#
+# CONFIG_V850E_SIM is not set
+# CONFIG_RTE_CB_MA1 is not set
+# CONFIG_RTE_CB_NB85E is not set
+CONFIG_RTE_CB_ME2=y
+# CONFIG_V850E_AS85EP1 is not set
+# CONFIG_V850E2_SIM85E2C is not set
+# CONFIG_V850E2_SIM85E2S is not set
+# CONFIG_V850E2_FPGA85E2C is not set
+# CONFIG_V850E2_ANNA is not set
+CONFIG_V850E=y
+CONFIG_V850E_ME2=y
+CONFIG_RTE_CB=y
+# CONFIG_RTE_MB_A_PCI is not set
+# CONFIG_PCI is not set
+CONFIG_V850E_INTC=y
+CONFIG_V850E_TIMER_D=y
+CONFIG_V850E_CACHE=y
+# CONFIG_V850E2_CACHE is not set
+# CONFIG_NO_CACHE is not set
+# CONFIG_ROM_KERNEL is not set
+CONFIG_ZERO_BSS=y
+# CONFIG_V850E_HIGHRES_TIMER is not set
+# CONFIG_RESET_GUARD is not set
+CONFIG_LARGE_ALLOCS=y
+
+#
+# Code maturity level options
+#
+# CONFIG_EXPERIMENTAL is not set
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_SYSCTL is not set
+# CONFIG_AUDIT is not set
+# CONFIG_HOTPLUG is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_EMBEDDED=y
+# CONFIG_KALLSYMS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+# CONFIG_BASE_FULL is not set
+# CONFIG_FUTEX is not set
+# CONFIG_EPOLL is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_BASE_SMALL=1
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_OBSOLETE_MODPARM=y
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+
+#
+# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
+#
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PCI Hotplug Support
+#
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_FLAT=y
+# CONFIG_BINFMT_ZFLAT is not set
+# CONFIG_BINFMT_SHARED_FLAT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+# CONFIG_MTD_PARTITIONS is not set
+
+#
+# User Modules And Translation Layers
+#
+# CONFIG_MTD_CHAR is not set
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+
+#
+# Self-contained MTD device drivers
+#
+CONFIG_MTD_SLRAM=y
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_RAM is not set
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CDROM_PKTCDVD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_AS is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+
+#
+# Disk device support
+#
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_SCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# I2O device support
+#
+
+#
+# Networking support
+#
+# CONFIG_NET is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# ISDN subsystem
+#
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+# CONFIG_SERIO_SERPORT is not set
+# CONFIG_SERIO_LIBPS2 is not set
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=1
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_V850E_UART is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_UNIX98_PTYS is not set
+# CONFIG_LEGACY_PTYS is not set
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+
+#
+# File systems
+#
+# CONFIG_EXT2_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+
+#
+# XFS support
+#
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+CONFIG_ROMFS_FS=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_SYSFS=y
+# CONFIG_TMPFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB_ARCH_HAS_HCD is not set
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_MAGIC_SYSRQ is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_FS is not set
+# CONFIG_NO_KERNEL_MSG is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC32 is not set
+# CONFIG_LIBCRC32C is not set
diff --git a/arch/v850/configs/sim_defconfig b/arch/v850/configs/sim_defconfig
new file mode 100644
--- /dev/null
+++ b/arch/v850/configs/sim_defconfig
@@ -0,0 +1,442 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.12-uc0
+# Thu Jul 21 11:29:27 2005
+#
+# CONFIG_MMU is not set
+# CONFIG_UID16 is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+# CONFIG_ISA is not set
+# CONFIG_ISAPNP is not set
+# CONFIG_EISA is not set
+# CONFIG_MCA is not set
+CONFIG_V850=y
+
+#
+# Processor type and features
+#
+CONFIG_V850E_SIM=y
+# CONFIG_RTE_CB_MA1 is not set
+# CONFIG_RTE_CB_NB85E is not set
+# CONFIG_RTE_CB_ME2 is not set
+# CONFIG_V850E_AS85EP1 is not set
+# CONFIG_V850E2_SIM85E2C is not set
+# CONFIG_V850E2_SIM85E2S is not set
+# CONFIG_V850E2_FPGA85E2C is not set
+# CONFIG_V850E2_ANNA is not set
+CONFIG_V850E=y
+# CONFIG_PCI is not set
+# CONFIG_V850E_INTC is not set
+# CONFIG_V850E_TIMER_D is not set
+# CONFIG_V850E_CACHE is not set
+# CONFIG_V850E2_CACHE is not set
+CONFIG_NO_CACHE=y
+CONFIG_ZERO_BSS=y
+# CONFIG_RESET_GUARD is not set
+CONFIG_LARGE_ALLOCS=y
+
+#
+# Code maturity level options
+#
+# CONFIG_EXPERIMENTAL is not set
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_SYSCTL is not set
+# CONFIG_AUDIT is not set
+# CONFIG_HOTPLUG is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_EMBEDDED=y
+# CONFIG_KALLSYMS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+# CONFIG_BASE_FULL is not set
+# CONFIG_FUTEX is not set
+# CONFIG_EPOLL is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_BASE_SMALL=1
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_OBSOLETE_MODPARM=y
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+
+#
+# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
+#
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PCI Hotplug Support
+#
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_FLAT=y
+# CONFIG_BINFMT_ZFLAT is not set
+# CONFIG_BINFMT_SHARED_FLAT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+# CONFIG_MTD_PARTITIONS is not set
+
+#
+# User Modules And Translation Layers
+#
+# CONFIG_MTD_CHAR is not set
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+
+#
+# Self-contained MTD device drivers
+#
+CONFIG_MTD_SLRAM=y
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_RAM is not set
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CDROM_PKTCDVD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_AS is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+
+#
+# Disk device support
+#
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_SCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# I2O device support
+#
+
+#
+# Networking support
+#
+# CONFIG_NET is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# ISDN subsystem
+#
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+# CONFIG_SERIO_SERPORT is not set
+# CONFIG_SERIO_LIBPS2 is not set
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_UNIX98_PTYS is not set
+# CONFIG_LEGACY_PTYS is not set
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+
+#
+# File systems
+#
+# CONFIG_EXT2_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+
+#
+# XFS support
+#
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+CONFIG_ROMFS_FS=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_SYSFS=y
+# CONFIG_TMPFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB_ARCH_HAS_HCD is not set
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_MAGIC_SYSRQ is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_FS is not set
+# CONFIG_NO_KERNEL_MSG is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC32 is not set
+# CONFIG_LIBCRC32C is not set
diff --git a/arch/v850/kernel/anna.c b/arch/v850/kernel/anna.c
--- a/arch/v850/kernel/anna.c
+++ b/arch/v850/kernel/anna.c
@@ -132,8 +132,6 @@ void machine_restart (char *__unused)
 	asm ("jmp r0"); /* Jump to the reset vector.  */
 }
 
-EXPORT_SYMBOL(machine_restart);
-
 void machine_halt (void)
 {
 #ifdef CONFIG_RESET_GUARD
@@ -145,15 +143,11 @@ void machine_halt (void)
 		asm ("halt; nop; nop; nop; nop; nop");
 }
 
-EXPORT_SYMBOL(machine_halt);
-
 void machine_power_off (void)
 {
 	machine_halt ();
 }
 
-EXPORT_SYMBOL(machine_power_off);
-
 /* Called before configuring an on-chip UART.  */
 void anna_uart_pre_configure (unsigned chan, unsigned cflags, unsigned baud)
 {
diff --git a/arch/v850/kernel/as85ep1.c b/arch/v850/kernel/as85ep1.c
--- a/arch/v850/kernel/as85ep1.c
+++ b/arch/v850/kernel/as85ep1.c
@@ -160,8 +160,6 @@ void machine_restart (char *__unused)
 	asm ("jmp r0"); /* Jump to the reset vector.  */
 }
 
-EXPORT_SYMBOL(machine_restart);
-
 void machine_halt (void)
 {
 #ifdef CONFIG_RESET_GUARD
@@ -173,15 +171,11 @@ void machine_halt (void)
 		asm ("halt; nop; nop; nop; nop; nop");
 }
 
-EXPORT_SYMBOL(machine_halt);
-
 void machine_power_off (void)
 {
 	machine_halt ();
 }
 
-EXPORT_SYMBOL(machine_power_off);
-
 /* Called before configuring an on-chip UART.  */
 void as85ep1_uart_pre_configure (unsigned chan, unsigned cflags, unsigned baud)
 {
diff --git a/arch/v850/kernel/fpga85e2c.c b/arch/v850/kernel/fpga85e2c.c
--- a/arch/v850/kernel/fpga85e2c.c
+++ b/arch/v850/kernel/fpga85e2c.c
@@ -121,22 +121,16 @@ void machine_halt (void)
 	}
 }
 
-EXPORT_SYMBOL(machine_halt);
-
 void machine_restart (char *__unused)
 {
 	machine_halt ();
 }
 
-EXPORT_SYMBOL(machine_restart);
-
 void machine_power_off (void)
 {
 	machine_halt ();
 }
 
-EXPORT_SYMBOL(machine_power_off);
-
 
 /* Interrupts */
 
diff --git a/arch/v850/kernel/rte_cb.c b/arch/v850/kernel/rte_cb.c
--- a/arch/v850/kernel/rte_cb.c
+++ b/arch/v850/kernel/rte_cb.c
@@ -67,8 +67,6 @@ void machine_restart (char *__unused)
 	asm ("jmp r0"); /* Jump to the reset vector.  */
 }
 
-EXPORT_SYMBOL(machine_restart);
-
 /* This says `HALt.' in LEDese.  */
 static unsigned char halt_leds_msg[] = { 0x76, 0x77, 0x38, 0xF8 };
 
@@ -89,15 +87,11 @@ void machine_halt (void)
 		asm ("halt; nop; nop; nop; nop; nop");
 }
 
-EXPORT_SYMBOL(machine_halt);
-
 void machine_power_off (void)
 {
 	machine_halt ();
 }
 
-EXPORT_SYMBOL(machine_power_off);
-
 
 /* Animated LED display for timer tick.  */
 
diff --git a/arch/v850/kernel/rte_mb_a_pci.c b/arch/v850/kernel/rte_mb_a_pci.c
--- a/arch/v850/kernel/rte_mb_a_pci.c
+++ b/arch/v850/kernel/rte_mb_a_pci.c
@@ -1,8 +1,8 @@
 /*
  * arch/v850/kernel/mb_a_pci.c -- PCI support for Midas lab RTE-MOTHER-A board
  *
- *  Copyright (C) 2001,02,03  NEC Electronics Corporation
- *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
+ *  Copyright (C) 2001,02,03,05  NEC Electronics Corporation
+ *  Copyright (C) 2001,02,03,05  Miles Bader <miles@gnu.org>
  *
  * This file is subject to the terms and conditions of the GNU General
  * Public License.  See the file COPYING in the main directory of this
@@ -743,15 +743,17 @@ pci_unmap_sg (struct pci_dev *pdev, stru
    for a scatter-gather list, same rules and usage.  */
 
 void
-pci_dma_sync_sg_for_cpu (struct pci_dev *dev, struct scatterlist *sg, int sg_len,
-		 int dir)
+pci_dma_sync_sg_for_cpu (struct pci_dev *dev,
+			 struct scatterlist *sg, int sg_len,
+			 int dir)
 {
 	BUG ();
 }
 
 void
-pci_dma_sync_sg_for_device (struct pci_dev *dev, struct scatterlist *sg, int sg_len,
-		 int dir)
+pci_dma_sync_sg_for_device (struct pci_dev *dev,
+			    struct scatterlist *sg, int sg_len,
+			    int dir)
 {
 	BUG ();
 }
@@ -786,6 +788,27 @@ pci_free_consistent (struct pci_dev *pde
 }
 
 
+/* iomap/iomap */
+
+void __iomem *pci_iomap (struct pci_dev *dev, int bar, unsigned long max)
+{
+	unsigned long start = pci_resource_start (dev, bar);
+	unsigned long len = pci_resource_len (dev, bar);
+
+	if (!start || len == 0)
+		return 0;
+
+	/* None of the ioremap functions actually do anything, other than
+	   re-casting their argument, so don't bother differentiating them.  */
+	return ioremap (start, len);
+}
+
+void pci_iounmap (struct pci_dev *dev, void __iomem *addr)
+{
+	/* nothing */
+}
+
+
 /* symbol exports (for modules) */
 
 EXPORT_SYMBOL (pci_map_single);
@@ -794,3 +817,5 @@ EXPORT_SYMBOL (pci_alloc_consistent);
 EXPORT_SYMBOL (pci_free_consistent);
 EXPORT_SYMBOL (pci_dma_sync_single_for_cpu);
 EXPORT_SYMBOL (pci_dma_sync_single_for_device);
+EXPORT_SYMBOL (pci_iomap);
+EXPORT_SYMBOL (pci_iounmap);
diff --git a/arch/v850/kernel/sim.c b/arch/v850/kernel/sim.c
--- a/arch/v850/kernel/sim.c
+++ b/arch/v850/kernel/sim.c
@@ -104,24 +104,18 @@ void machine_restart (char *__unused)
 	V850_SIM_SYSCALL (exit, 0);
 }
 
-EXPORT_SYMBOL(machine_restart);
-
 void machine_halt (void)
 {
 	V850_SIM_SYSCALL (write, 1, "HALT\n", 5);
 	V850_SIM_SYSCALL (exit, 0);
 }
 
-EXPORT_SYMBOL(machine_halt);
-
 void machine_power_off (void)
 {
 	V850_SIM_SYSCALL (write, 1, "POWER OFF\n", 10);
 	V850_SIM_SYSCALL (exit, 0);
 }
 
-EXPORT_SYMBOL(machine_power_off);
-
 
 /* Load data from a file called NAME into ram.  The address and length
    of the data image are returned in ADDR and LEN.  */
diff --git a/arch/v850/kernel/sim85e2.c b/arch/v850/kernel/sim85e2.c
--- a/arch/v850/kernel/sim85e2.c
+++ b/arch/v850/kernel/sim85e2.c
@@ -184,18 +184,13 @@ void machine_halt (void)
 	for (;;) {}
 }
 
-EXPORT_SYMBOL(machine_halt);
-
 void machine_restart (char *__unused)
 {
 	machine_halt ();
 }
 
-EXPORT_SYMBOL(machine_restart);
-
 void machine_power_off (void)
 {
 	machine_halt ();
 }
 
-EXPORT_SYMBOL(machine_power_off);
diff --git a/arch/v850/kernel/vmlinux.lds.S b/arch/v850/kernel/vmlinux.lds.S
--- a/arch/v850/kernel/vmlinux.lds.S
+++ b/arch/v850/kernel/vmlinux.lds.S
@@ -1,8 +1,8 @@
 /*
  * arch/v850/vmlinux.lds.S -- kernel linker script for v850 platforms
  *
- *  Copyright (C) 2002,03,04  NEC Electronics Corporation
- *  Copyright (C) 2002,03,04  Miles Bader <miles@gnu.org>
+ *  Copyright (C) 2002,03,04,05  NEC Electronics Corporation
+ *  Copyright (C) 2002,03,04,05  Miles Bader <miles@gnu.org>
  *
  * This file is subject to the terms and conditions of the GNU General
  * Public License.  See the file COPYING in the main directory of this
@@ -12,6 +12,7 @@
  */
 
 #include <linux/config.h>
+
 #define VMLINUX_SYMBOL(_sym_) _##_sym_
 #include <asm-generic/vmlinux.lds.h>
 
@@ -42,6 +43,19 @@
 			*(.rodata) *(.rodata.*)				      \
 			*(__vermagic)		/* Kernel version magic */    \
 			*(.rodata1)					      \
+		/* PCI quirks */					      \
+		___start_pci_fixups_early = . ;				      \
+			*(.pci_fixup_early)				      \
+		___end_pci_fixups_early = . ;				      \
+		___start_pci_fixups_header = . ;			      \
+			*(.pci_fixup_header)				      \
+		___end_pci_fixups_header = . ;				      \
+		___start_pci_fixups_final = . ;				      \
+			*(.pci_fixup_final)				      \
+		___end_pci_fixups_final = . ;				      \
+		___start_pci_fixups_enable = . ;			      \
+			*(.pci_fixup_enable)				      \
+		___end_pci_fixups_enable = . ;				      \
 		/* Kernel symbol table: Normal symbols */		      \
 		___start___ksymtab = .;					      \
 			*(__ksymtab)					      \
@@ -61,6 +75,7 @@
 			*(__kcrctab_gpl)				      \
 		___stop___kcrctab_gpl = .;				      \
 		/* Built-in module parameters */			      \
+		. = ALIGN (4) ;						      \
 		___start___param = .;					      \
 		*(__param)						      \
 		___stop___param = .;
diff --git a/arch/v850/lib/checksum.c b/arch/v850/lib/checksum.c
--- a/arch/v850/lib/checksum.c
+++ b/arch/v850/lib/checksum.c
@@ -138,7 +138,8 @@ unsigned int csum_partial_copy(const uns
  * Copy from userspace and compute checksum.  If we catch an exception
  * then zero the rest of the buffer.
  */
-unsigned int csum_partial_copy_from_user (const unsigned char *src, unsigned char *dst,
+unsigned int csum_partial_copy_from_user (const unsigned char *src,
+					  unsigned char *dst,
                                           int len, unsigned int sum,
                                           int *err_ptr)
 {
diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig
--- a/arch/x86_64/Kconfig
+++ b/arch/x86_64/Kconfig
@@ -207,33 +207,6 @@ config SMP
 
 	  If you don't know what to do here, say N.
 
-config PREEMPT
-	bool "Preemptible Kernel"
-	---help---
-	  This option reduces the latency of the kernel when reacting to
-	  real-time or interactive events by allowing a low priority process to
-	  be preempted even if it is in kernel mode executing a system call.
-	  This allows applications to run more reliably even when the system is
-	  under load. On contrary it may also break your drivers and add
-	  priority inheritance problems to your system. Don't select it if
-	  you rely on a stable system or have slightly obscure hardware.
-	  It's also not very well tested on x86-64 currently.
-	  You have been warned.
-
-	  Say Y here if you are feeling brave and building a kernel for a
-	  desktop, embedded or real-time system.  Say N if you are unsure.
-
-config PREEMPT_BKL
-	bool "Preempt The Big Kernel Lock"
-	depends on PREEMPT
-	default y
-	help
-	  This option reduces the latency of the kernel by making the
-	  big kernel lock preemptible.
-
-	  Say Y here if you are building a kernel for a desktop system.
-	  Say N if you are unsure.
-
 config SCHED_SMT
 	bool "SMT (Hyperthreading) scheduler support"
 	depends on SMP
@@ -244,6 +217,8 @@ config SCHED_SMT
 	  cost of slightly increased overhead in some places. If unsure say
 	  N here.
 
+source "kernel/Kconfig.preempt"
+
 config K8_NUMA
        bool "K8 NUMA support"
        select NUMA
@@ -265,7 +240,7 @@ config NUMA_EMU
 	  into virtual nodes when booted with "numa=fake=N", where N is the
 	  number of nodes. This is only useful for debugging.
 
-config DISCONTIGMEM
+config ARCH_DISCONTIGMEM_ENABLE
        bool
        depends on NUMA
        default y
@@ -274,6 +249,27 @@ config NUMA
        bool
        default n
 
+config ARCH_DISCONTIGMEM_ENABLE
+	def_bool y
+	depends on NUMA
+
+config ARCH_DISCONTIGMEM_DEFAULT
+	def_bool y
+	depends on NUMA
+
+config ARCH_SPARSEMEM_ENABLE
+	def_bool y
+	depends on NUMA
+
+config ARCH_FLATMEM_ENABLE
+	def_bool y
+	depends on !NUMA
+
+source "mm/Kconfig"
+
+config HAVE_ARCH_EARLY_PFN_TO_NID
+	def_bool y
+
 config HAVE_DEC_LOCK
 	bool
 	depends on SMP
@@ -292,6 +288,15 @@ config NR_CPUS
 	  This is purely to save memory - each supported CPU requires
 	  memory in the static kernel configuration.
 
+config HOTPLUG_CPU
+	bool "Support for hot-pluggable CPUs (EXPERIMENTAL)"
+	depends on SMP && HOTPLUG && EXPERIMENTAL
+	help
+		Say Y here to experiment with turning CPUs off and on.  CPUs
+		can be controlled through /sys/devices/system/cpu/cpu#.
+		Say N if you want to disable CPU hotplug.
+
+
 config HPET_TIMER
 	bool
 	default y
@@ -324,12 +329,15 @@ config HPET_EMULATE_RTC
 
 config GART_IOMMU
 	bool "IOMMU support"
+	default y
 	depends on PCI
 	help
-	  Support the K8 IOMMU. Needed to run systems with more than 4GB of memory
+	  Support the IOMMU. Needed to run systems with more than 3GB of memory
 	  properly with 32-bit PCI devices that do not support DAC (Double Address
 	  Cycle). The IOMMU can be turned off at runtime with the iommu=off parameter.
 	  Normally the kernel will take the right choice by itself.
+	  This option includes a driver for the AMD Opteron/Athlon64 IOMMU
+	  and a software emulation used on some other systems.
 	  If unsure, say Y.
 
 # need this always enabled with GART_IOMMU for the VIA workaround
@@ -364,6 +372,34 @@ config X86_MCE_INTEL
 	   Additional support for intel specific MCE features such as
 	   the thermal monitor.
 
+config PHYSICAL_START
+	hex "Physical address where the kernel is loaded" if EMBEDDED
+	default "0x100000"
+	help
+	  This gives the physical address where the kernel is loaded.
+	  Primarily used in the case of kexec on panic where the
+	  fail safe kernel needs to run at a different address than
+	  the panic-ed kernel.
+
+	  Don't change this unless you know what you are doing.
+
+config KEXEC
+	bool "kexec system call (EXPERIMENTAL)"
+	depends on EXPERIMENTAL
+	help
+	  kexec is a system call that implements the ability to shutdown your
+	  current kernel, and to start another kernel.  It is like a reboot
+	  but it is indepedent of the system firmware.   And like a reboot
+	  you can start any kernel with it, not just Linux.
+
+	  The name comes from the similiarity to the exec system call.
+
+	  It is an ongoing process to be certain the hardware in a machine
+	  is properly shutdown, so do not be surprised if this code does not
+	  initially work for you.  It may help to enable device hotplugging
+	  support.  As of this writing the exact hardware interface is
+	  strongly in flux, so no good recommendation can be made.
+
 config SECCOMP
 	bool "Enable seccomp to safely compute untrusted bytecode"
 	depends on PROC_FS
@@ -381,6 +417,8 @@ config SECCOMP
 
 	  If unsure, say Y. Only embedded should say N here.
 
+source kernel/Kconfig.hz
+
 endmenu
 
 #
@@ -480,6 +518,8 @@ config UID16
 
 endmenu
 
+source "net/Kconfig"
+
 source drivers/Kconfig
 
 source "drivers/firmware/Kconfig"
diff --git a/arch/x86_64/Makefile b/arch/x86_64/Makefile
--- a/arch/x86_64/Makefile
+++ b/arch/x86_64/Makefile
@@ -21,21 +21,9 @@
 #
 # $Id: Makefile,v 1.31 2002/03/22 15:56:07 ak Exp $
 
-#
-# early bootup linking needs 32bit. You can either use real 32bit tools
-# here or 64bit tools in 32bit mode.
-#
-IA32_CC := $(CC) $(CPPFLAGS) -m32 -O2 -fomit-frame-pointer
-IA32_LD := $(LD) -m elf_i386
-IA32_AS := $(CC) $(AFLAGS) -m32 -Wa,--32 -traditional -c
-IA32_OBJCOPY := $(CROSS_COMPILE)objcopy
-IA32_CPP := $(CROSS_COMPILE)gcc -m32 -E
-export IA32_CC IA32_LD IA32_AS IA32_OBJCOPY IA32_CPP
-
-
 LDFLAGS		:= -m elf_x86_64
 OBJCOPYFLAGS	:= -O binary -R .note -R .comment -S
-LDFLAGS_vmlinux := -e stext
+LDFLAGS_vmlinux :=
 
 CHECKFLAGS      += -D__x86_64__ -m64
 
@@ -65,7 +53,9 @@ CFLAGS += $(call cc-option,-mno-sse -mno
 head-y := arch/x86_64/kernel/head.o arch/x86_64/kernel/head64.o arch/x86_64/kernel/init_task.o
 
 libs-y 					+= arch/x86_64/lib/
-core-y					+= arch/x86_64/kernel/ arch/x86_64/mm/
+core-y					+= arch/x86_64/kernel/ \
+					   arch/x86_64/mm/ \
+					   arch/x86_64/crypto/
 core-$(CONFIG_IA32_EMULATION)		+= arch/x86_64/ia32/
 drivers-$(CONFIG_PCI)			+= arch/x86_64/pci/
 drivers-$(CONFIG_OPROFILE)		+= arch/x86_64/oprofile/
diff --git a/arch/x86_64/boot/compressed/head.S b/arch/x86_64/boot/compressed/head.S
--- a/arch/x86_64/boot/compressed/head.S
+++ b/arch/x86_64/boot/compressed/head.S
@@ -2,8 +2,6 @@
  *  linux/boot/head.S
  *
  *  Copyright (C) 1991, 1992, 1993  Linus Torvalds
- *
- *  $Id: head.S,v 1.3 2001/04/20 00:59:28 ak Exp $	 		
  */
 
 /*
@@ -21,13 +19,14 @@
  */
 
 /*
- * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996	
+ * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
  */
 .code32
 .text
 
 #include <linux/linkage.h>
 #include <asm/segment.h>
+#include <asm/page.h>
 
 	.code32
 	.globl startup_32
@@ -77,7 +76,7 @@ startup_32:
 	jnz  3f
 	addl $8,%esp
 	xorl %ebx,%ebx
-	ljmp $(__KERNEL_CS), $0x100000
+	ljmp $(__KERNEL_CS), $__PHYSICAL_START
 
 /*
  * We come here, if we were loaded high.
@@ -103,7 +102,7 @@ startup_32:
 	popl %ecx	# lcount
 	popl %edx	# high_buffer_start
 	popl %eax	# hcount
-	movl $0x100000,%edi
+	movl $__PHYSICAL_START,%edi
 	cli		# make sure we don't get interrupted
 	ljmp $(__KERNEL_CS), $0x1000 # and jump to the move routine
 
@@ -128,7 +127,7 @@ move_routine_start:
 	movsl
 	movl %ebx,%esi	# Restore setup pointer
 	xorl %ebx,%ebx
-	ljmp $(__KERNEL_CS), $0x100000
+	ljmp $(__KERNEL_CS), $__PHYSICAL_START
 move_routine_end:
 
 
diff --git a/arch/x86_64/boot/compressed/misc.c b/arch/x86_64/boot/compressed/misc.c
--- a/arch/x86_64/boot/compressed/misc.c
+++ b/arch/x86_64/boot/compressed/misc.c
@@ -11,6 +11,7 @@
 
 #include "miscsetup.h"
 #include <asm/io.h>
+#include <asm/page.h>
 
 /*
  * gzip declarations
@@ -92,8 +93,11 @@ static unsigned long output_ptr = 0;
 static void *malloc(int size);
 static void free(void *where);
  
+void* memset(void* s, int c, unsigned n);
+void* memcpy(void* dest, const void* src, unsigned n);
+
 static void putstr(const char *);
-  
+
 extern int end;
 static long free_mem_ptr = (long)&end;
 static long free_mem_end_ptr;
@@ -284,7 +288,7 @@ void setup_normal_output_buffer(void)
 #else
 	if ((ALT_MEM_K > EXT_MEM_K ? ALT_MEM_K : EXT_MEM_K) < 1024) error("Less than 2MB of memory");
 #endif
-	output_data = (char *)0x100000; /* Points to 1M */
+	output_data = (char *)__PHYSICAL_START; /* Normally Points to 1M */
 	free_mem_end_ptr = (long)real_mode;
 }
 
@@ -307,8 +311,8 @@ void setup_output_buffer_if_we_run_high(
 	low_buffer_size = low_buffer_end - LOW_BUFFER_START;
 	high_loaded = 1;
 	free_mem_end_ptr = (long)high_buffer_start;
-	if ( (0x100000 + low_buffer_size) > ((ulg)high_buffer_start)) {
-		high_buffer_start = (uch *)(0x100000 + low_buffer_size);
+	if ( (__PHYSICAL_START + low_buffer_size) > ((ulg)high_buffer_start)) {
+		high_buffer_start = (uch *)(__PHYSICAL_START + low_buffer_size);
 		mv->hcount = 0; /* say: we need not to move high_buffer */
 	}
 	else mv->hcount = -1;
diff --git a/arch/x86_64/boot/install.sh b/arch/x86_64/boot/install.sh
--- a/arch/x86_64/boot/install.sh
+++ b/arch/x86_64/boot/install.sh
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# arch/i386/boot/install.sh
+# arch/x86_64/boot/install.sh
 #
 # This file is subject to the terms and conditions of the GNU General Public
 # License.  See the file "COPYING" in the main directory of this archive
@@ -21,8 +21,8 @@
 
 # User may have a custom install script
 
-if [ -x ~/bin/installkernel ]; then exec ~/bin/installkernel "$@"; fi
-if [ -x /sbin/installkernel ]; then exec /sbin/installkernel "$@"; fi
+if [ -x ~/bin/${CROSS_COMPILE}installkernel ]; then exec ~/bin/${CROSS_COMPILE}installkernel "$@"; fi
+if [ -x /sbin/${CROSS_COMPILE}installkernel ]; then exec /sbin/${CROSS_COMPILE}installkernel "$@"; fi
 
 # Default install - same as make zlilo
 
diff --git a/arch/x86_64/boot/setup.S b/arch/x86_64/boot/setup.S
--- a/arch/x86_64/boot/setup.S
+++ b/arch/x86_64/boot/setup.S
@@ -33,7 +33,7 @@
  * Transcribed from Intel (as86) -> AT&T (gas) by Chris Noe, May 1999.
  * <stiker@northlink.com>
  *
- * Fix to work around buggy BIOSes which dont use carry bit correctly
+ * Fix to work around buggy BIOSes which don't use carry bit correctly
  * and/or report extended memory in CX/DX for e801h memory size detection 
  * call.  As a result the kernel got wrong figures.  The int15/e801h docs
  * from Ralf Brown interrupt list seem to indicate AX/BX should be used
@@ -383,7 +383,7 @@ sse_ok:
 # a whole bunch of different types, and allows memory holes and
 # everything.  We scan through this memory map and build a list
 # of the first 32 memory areas, which we return at [E820MAP].
-# This is documented at http://www.teleport.com/~acpi/acpihtml/topic245.htm
+# This is documented at http://www.acpi.info/, in the ACPI 2.0 specification.
 
 #define SMAP  0x534d4150
 
@@ -436,7 +436,7 @@ bail820:
 
 meme801:
 	stc					# fix to work around buggy
-	xorw	%cx,%cx				# BIOSes which dont clear/set
+	xorw	%cx,%cx				# BIOSes which don't clear/set
 	xorw	%dx,%dx				# carry on pass/error of
 						# e801h memory size call
 						# or merely pass cx,dx though
@@ -733,7 +733,7 @@ flush_instr:
 #
 #	but we yet haven't reloaded the CS register, so the default size 
 #	of the target offset still is 16 bit.
-#       However, using an operant prefix (0x66), the CPU will properly
+#	However, using an operand prefix (0x66), the CPU will properly
 #	take our 48 bit far pointer. (INTeL 80386 Programmer's Reference
 #	Manual, Mixing 16-bit and 32-bit code, page 16-6)
 
diff --git a/arch/x86_64/boot/tools/build.c b/arch/x86_64/boot/tools/build.c
--- a/arch/x86_64/boot/tools/build.c
+++ b/arch/x86_64/boot/tools/build.c
@@ -1,6 +1,4 @@
 /*
- *  $Id: build.c,v 1.3 2001/06/26 15:14:50 pavel Exp $
- *
  *  Copyright (C) 1991, 1992  Linus Torvalds
  *  Copyright (C) 1997 Martin Mares
  */
@@ -8,7 +6,8 @@
 /*
  * This file builds a disk-image from three different files:
  *
- * - bootsect: exactly 512 bytes of 8086 machine code, loads the rest
+ * - bootsect: compatibility mbr which prints an error message if
+ *             someone tries to boot the kernel directly.
  * - setup: 8086 machine code, sets up system parm
  * - system: 80386 code for actual system
  *
diff --git a/arch/x86_64/crypto/Makefile b/arch/x86_64/crypto/Makefile
new file mode 100644
--- /dev/null
+++ b/arch/x86_64/crypto/Makefile
@@ -0,0 +1,9 @@
+# 
+# x86_64/crypto/Makefile 
+# 
+# Arch-specific CryptoAPI modules.
+# 
+
+obj-$(CONFIG_CRYPTO_AES_X86_64) += aes-x86_64.o
+
+aes-x86_64-y := aes-x86_64-asm.o aes.o
diff --git a/arch/x86_64/crypto/aes-x86_64-asm.S b/arch/x86_64/crypto/aes-x86_64-asm.S
new file mode 100644
--- /dev/null
+++ b/arch/x86_64/crypto/aes-x86_64-asm.S
@@ -0,0 +1,186 @@
+/* AES (Rijndael) implementation (FIPS PUB 197) for x86_64
+ *
+ * Copyright (C) 2005 Andreas Steinmetz, <ast@domdv.de>
+ *
+ * License:
+ * This code can be distributed under the terms of the GNU General Public
+ * License (GPL) Version 2 provided that the above header down to and
+ * including this sentence is retained in full.
+ */
+
+.extern aes_ft_tab
+.extern aes_it_tab
+.extern aes_fl_tab
+.extern aes_il_tab
+
+.text
+
+#define R1	%rax
+#define R1E	%eax
+#define R1X	%ax
+#define R1H	%ah
+#define R1L	%al
+#define R2	%rbx
+#define R2E	%ebx
+#define R2X	%bx
+#define R2H	%bh
+#define R2L	%bl
+#define R3	%rcx
+#define R3E	%ecx
+#define R3X	%cx
+#define R3H	%ch
+#define R3L	%cl
+#define R4	%rdx
+#define R4E	%edx
+#define R4X	%dx
+#define R4H	%dh
+#define R4L	%dl
+#define R5	%rsi
+#define R5E	%esi
+#define R6	%rdi
+#define R6E	%edi
+#define R7	%rbp
+#define R7E	%ebp
+#define R8	%r8
+#define R9	%r9
+#define R10	%r10
+#define R11	%r11
+
+#define prologue(FUNC,BASE,B128,B192,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11) \
+	.global	FUNC;			\
+	.type	FUNC,@function;		\
+	.align	8;			\
+FUNC:	movq	r1,r2;			\
+	movq	r3,r4;			\
+	leaq	BASE+52(r8),r9;		\
+	movq	r10,r11;		\
+	movl	(r7),r5 ## E;		\
+	movl	4(r7),r1 ## E;		\
+	movl	8(r7),r6 ## E;		\
+	movl	12(r7),r7 ## E;		\
+	movl	(r8),r10 ## E;		\
+	xorl	-48(r9),r5 ## E;	\
+	xorl	-44(r9),r1 ## E;	\
+	xorl	-40(r9),r6 ## E;	\
+	xorl	-36(r9),r7 ## E;	\
+	cmpl	$24,r10 ## E;		\
+	jb	B128;			\
+	leaq	32(r9),r9;		\
+	je	B192;			\
+	leaq	32(r9),r9;
+
+#define epilogue(r1,r2,r3,r4,r5,r6,r7,r8,r9) \
+	movq	r1,r2;			\
+	movq	r3,r4;			\
+	movl	r5 ## E,(r9);		\
+	movl	r6 ## E,4(r9);		\
+	movl	r7 ## E,8(r9);		\
+	movl	r8 ## E,12(r9);		\
+	ret;
+
+#define round(TAB,OFFSET,r1,r2,r3,r4,r5,r6,r7,r8,ra,rb,rc,rd) \
+	movzbl	r2 ## H,r5 ## E;	\
+	movzbl	r2 ## L,r6 ## E;	\
+	movl	TAB+1024(,r5,4),r5 ## E;\
+	movw	r4 ## X,r2 ## X;	\
+	movl	TAB(,r6,4),r6 ## E;	\
+	roll	$16,r2 ## E;		\
+	shrl	$16,r4 ## E;		\
+	movzbl	r4 ## H,r7 ## E;	\
+	movzbl	r4 ## L,r4 ## E;	\
+	xorl	OFFSET(r8),ra ## E;	\
+	xorl	OFFSET+4(r8),rb ## E;	\
+	xorl	TAB+3072(,r7,4),r5 ## E;\
+	xorl	TAB+2048(,r4,4),r6 ## E;\
+	movzbl	r1 ## L,r7 ## E;	\
+	movzbl	r1 ## H,r4 ## E;	\
+	movl	TAB+1024(,r4,4),r4 ## E;\
+	movw	r3 ## X,r1 ## X;	\
+	roll	$16,r1 ## E;		\
+	shrl	$16,r3 ## E;		\
+	xorl	TAB(,r7,4),r5 ## E;	\
+	movzbl	r3 ## H,r7 ## E;	\
+	movzbl	r3 ## L,r3 ## E;	\
+	xorl	TAB+3072(,r7,4),r4 ## E;\
+	xorl	TAB+2048(,r3,4),r5 ## E;\
+	movzbl	r1 ## H,r7 ## E;	\
+	movzbl	r1 ## L,r3 ## E;	\
+	shrl	$16,r1 ## E;		\
+	xorl	TAB+3072(,r7,4),r6 ## E;\
+	movl	TAB+2048(,r3,4),r3 ## E;\
+	movzbl	r1 ## H,r7 ## E;	\
+	movzbl	r1 ## L,r1 ## E;	\
+	xorl	TAB+1024(,r7,4),r6 ## E;\
+	xorl	TAB(,r1,4),r3 ## E;	\
+	movzbl	r2 ## H,r1 ## E;	\
+	movzbl	r2 ## L,r7 ## E;	\
+	shrl	$16,r2 ## E;		\
+	xorl	TAB+3072(,r1,4),r3 ## E;\
+	xorl	TAB+2048(,r7,4),r4 ## E;\
+	movzbl	r2 ## H,r1 ## E;	\
+	movzbl	r2 ## L,r2 ## E;	\
+	xorl	OFFSET+8(r8),rc ## E;	\
+	xorl	OFFSET+12(r8),rd ## E;	\
+	xorl	TAB+1024(,r1,4),r3 ## E;\
+	xorl	TAB(,r2,4),r4 ## E;
+
+#define move_regs(r1,r2,r3,r4) \
+	movl	r3 ## E,r1 ## E;	\
+	movl	r4 ## E,r2 ## E;
+
+#define entry(FUNC,BASE,B128,B192) \
+	prologue(FUNC,BASE,B128,B192,R2,R8,R7,R9,R1,R3,R4,R6,R10,R5,R11)
+
+#define return epilogue(R8,R2,R9,R7,R5,R6,R3,R4,R11)
+
+#define encrypt_round(TAB,OFFSET) \
+	round(TAB,OFFSET,R1,R2,R3,R4,R5,R6,R7,R10,R5,R6,R3,R4) \
+	move_regs(R1,R2,R5,R6)
+
+#define encrypt_final(TAB,OFFSET) \
+	round(TAB,OFFSET,R1,R2,R3,R4,R5,R6,R7,R10,R5,R6,R3,R4)
+
+#define decrypt_round(TAB,OFFSET) \
+	round(TAB,OFFSET,R2,R1,R4,R3,R6,R5,R7,R10,R5,R6,R3,R4) \
+	move_regs(R1,R2,R5,R6)
+
+#define decrypt_final(TAB,OFFSET) \
+	round(TAB,OFFSET,R2,R1,R4,R3,R6,R5,R7,R10,R5,R6,R3,R4)
+
+/* void aes_encrypt(void *ctx, u8 *out, const u8 *in) */
+
+	entry(aes_encrypt,0,enc128,enc192)
+	encrypt_round(aes_ft_tab,-96)
+	encrypt_round(aes_ft_tab,-80)
+enc192:	encrypt_round(aes_ft_tab,-64)
+	encrypt_round(aes_ft_tab,-48)
+enc128:	encrypt_round(aes_ft_tab,-32)
+	encrypt_round(aes_ft_tab,-16)
+	encrypt_round(aes_ft_tab,  0)
+	encrypt_round(aes_ft_tab, 16)
+	encrypt_round(aes_ft_tab, 32)
+	encrypt_round(aes_ft_tab, 48)
+	encrypt_round(aes_ft_tab, 64)
+	encrypt_round(aes_ft_tab, 80)
+	encrypt_round(aes_ft_tab, 96)
+	encrypt_final(aes_fl_tab,112)
+	return
+
+/* void aes_decrypt(void *ctx, u8 *out, const u8 *in) */
+
+	entry(aes_decrypt,240,dec128,dec192)
+	decrypt_round(aes_it_tab,-96)
+	decrypt_round(aes_it_tab,-80)
+dec192:	decrypt_round(aes_it_tab,-64)
+	decrypt_round(aes_it_tab,-48)
+dec128:	decrypt_round(aes_it_tab,-32)
+	decrypt_round(aes_it_tab,-16)
+	decrypt_round(aes_it_tab,  0)
+	decrypt_round(aes_it_tab, 16)
+	decrypt_round(aes_it_tab, 32)
+	decrypt_round(aes_it_tab, 48)
+	decrypt_round(aes_it_tab, 64)
+	decrypt_round(aes_it_tab, 80)
+	decrypt_round(aes_it_tab, 96)
+	decrypt_final(aes_il_tab,112)
+	return
diff --git a/arch/x86_64/crypto/aes.c b/arch/x86_64/crypto/aes.c
new file mode 100644
--- /dev/null
+++ b/arch/x86_64/crypto/aes.c
@@ -0,0 +1,325 @@
+/*
+ * Cryptographic API.
+ *
+ * AES Cipher Algorithm.
+ *
+ * Based on Brian Gladman's code.
+ *
+ * Linux developers:
+ *  Alexander Kjeldaas <astor@fast.no>
+ *  Herbert Valerio Riedel <hvr@hvrlab.org>
+ *  Kyle McMartin <kyle@debian.org>
+ *  Adam J. Richter <adam@yggdrasil.com> (conversion to 2.5 API).
+ *  Andreas Steinmetz <ast@domdv.de> (adapted to x86_64 assembler)
+ *
+ * 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.
+ *
+ * ---------------------------------------------------------------------------
+ * Copyright (c) 2002, Dr Brian Gladman <brg@gladman.me.uk>, Worcester, UK.
+ * All rights reserved.
+ *
+ * LICENSE TERMS
+ *
+ * The free distribution and use of this software in both source and binary
+ * form is allowed (with or without changes) provided that:
+ *
+ *   1. distributions of this source code include the above copyright
+ *      notice, this list of conditions and the following disclaimer;
+ *
+ *   2. distributions in binary form include the above copyright
+ *      notice, this list of conditions and the following disclaimer
+ *      in the documentation and/or other associated materials;
+ *
+ *   3. the copyright holder's name is not used to endorse products
+ *      built using this software without specific written permission.
+ *
+ * ALTERNATIVELY, provided that this notice is retained in full, this product
+ * may be distributed under the terms of the GNU General Public License (GPL),
+ * in which case the provisions of the GPL apply INSTEAD OF those given above.
+ *
+ * DISCLAIMER
+ *
+ * This software is provided 'as is' with no explicit or implied warranties
+ * in respect of its properties, including, but not limited to, correctness
+ * and/or fitness for purpose.
+ * ---------------------------------------------------------------------------
+ */
+
+/* Some changes from the Gladman version:
+    s/RIJNDAEL(e_key)/E_KEY/g
+    s/RIJNDAEL(d_key)/D_KEY/g
+*/
+
+#include <asm/byteorder.h>
+#include <linux/bitops.h>
+#include <linux/crypto.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/types.h>
+
+#define AES_MIN_KEY_SIZE	16
+#define AES_MAX_KEY_SIZE	32
+
+#define AES_BLOCK_SIZE		16
+
+/*
+ * #define byte(x, nr) ((unsigned char)((x) >> (nr*8)))
+ */
+static inline u8 byte(const u32 x, const unsigned n)
+{
+	return x >> (n << 3);
+}
+
+#define u32_in(x) le32_to_cpu(*(const __le32 *)(x))
+
+struct aes_ctx
+{
+	u32 key_length;
+	u32 E[60];
+	u32 D[60];
+};
+
+#define E_KEY ctx->E
+#define D_KEY ctx->D
+
+static u8 pow_tab[256] __initdata;
+static u8 log_tab[256] __initdata;
+static u8 sbx_tab[256] __initdata;
+static u8 isb_tab[256] __initdata;
+static u32 rco_tab[10];
+u32 aes_ft_tab[4][256];
+u32 aes_it_tab[4][256];
+
+u32 aes_fl_tab[4][256];
+u32 aes_il_tab[4][256];
+
+static inline u8 f_mult(u8 a, u8 b)
+{
+	u8 aa = log_tab[a], cc = aa + log_tab[b];
+
+	return pow_tab[cc + (cc < aa ? 1 : 0)];
+}
+
+#define ff_mult(a, b) (a && b ? f_mult(a, b) : 0)
+
+#define ls_box(x)				\
+	(aes_fl_tab[0][byte(x, 0)] ^		\
+	 aes_fl_tab[1][byte(x, 1)] ^		\
+	 aes_fl_tab[2][byte(x, 2)] ^		\
+	 aes_fl_tab[3][byte(x, 3)])
+
+static void __init gen_tabs(void)
+{
+	u32 i, t;
+	u8 p, q;
+
+	/* log and power tables for GF(2**8) finite field with
+	   0x011b as modular polynomial - the simplest primitive
+	   root is 0x03, used here to generate the tables */
+
+	for (i = 0, p = 1; i < 256; ++i) {
+		pow_tab[i] = (u8)p;
+		log_tab[p] = (u8)i;
+
+		p ^= (p << 1) ^ (p & 0x80 ? 0x01b : 0);
+	}
+
+	log_tab[1] = 0;
+
+	for (i = 0, p = 1; i < 10; ++i) {
+		rco_tab[i] = p;
+
+		p = (p << 1) ^ (p & 0x80 ? 0x01b : 0);
+	}
+
+	for (i = 0; i < 256; ++i) {
+		p = (i ? pow_tab[255 - log_tab[i]] : 0);
+		q = ((p >> 7) | (p << 1)) ^ ((p >> 6) | (p << 2));
+		p ^= 0x63 ^ q ^ ((q >> 6) | (q << 2));
+		sbx_tab[i] = p;
+		isb_tab[p] = (u8)i;
+	}
+
+	for (i = 0; i < 256; ++i) {
+		p = sbx_tab[i];
+
+		t = p;
+		aes_fl_tab[0][i] = t;
+		aes_fl_tab[1][i] = rol32(t, 8);
+		aes_fl_tab[2][i] = rol32(t, 16);
+		aes_fl_tab[3][i] = rol32(t, 24);
+
+		t = ((u32)ff_mult(2, p)) |
+		    ((u32)p << 8) |
+		    ((u32)p << 16) | ((u32)ff_mult(3, p) << 24);
+
+		aes_ft_tab[0][i] = t;
+		aes_ft_tab[1][i] = rol32(t, 8);
+		aes_ft_tab[2][i] = rol32(t, 16);
+		aes_ft_tab[3][i] = rol32(t, 24);
+
+		p = isb_tab[i];
+
+		t = p;
+		aes_il_tab[0][i] = t;
+		aes_il_tab[1][i] = rol32(t, 8);
+		aes_il_tab[2][i] = rol32(t, 16);
+		aes_il_tab[3][i] = rol32(t, 24);
+
+		t = ((u32)ff_mult(14, p)) |
+		    ((u32)ff_mult(9, p) << 8) |
+		    ((u32)ff_mult(13, p) << 16) |
+		    ((u32)ff_mult(11, p) << 24);
+
+		aes_it_tab[0][i] = t;
+		aes_it_tab[1][i] = rol32(t, 8);
+		aes_it_tab[2][i] = rol32(t, 16);
+		aes_it_tab[3][i] = rol32(t, 24);
+	}
+}
+
+#define star_x(x) (((x) & 0x7f7f7f7f) << 1) ^ ((((x) & 0x80808080) >> 7) * 0x1b)
+
+#define imix_col(y, x)			\
+	u    = star_x(x);		\
+	v    = star_x(u);		\
+	w    = star_x(v);		\
+	t    = w ^ (x);			\
+	(y)  = u ^ v ^ w;		\
+	(y) ^= ror32(u ^ t,  8) ^	\
+	       ror32(v ^ t, 16) ^	\
+	       ror32(t, 24)
+
+/* initialise the key schedule from the user supplied key */
+
+#define loop4(i)					\
+{							\
+	t = ror32(t,  8); t = ls_box(t) ^ rco_tab[i];	\
+	t ^= E_KEY[4 * i];     E_KEY[4 * i + 4] = t;	\
+	t ^= E_KEY[4 * i + 1]; E_KEY[4 * i + 5] = t;	\
+	t ^= E_KEY[4 * i + 2]; E_KEY[4 * i + 6] = t;	\
+	t ^= E_KEY[4 * i + 3]; E_KEY[4 * i + 7] = t;	\
+}
+
+#define loop6(i)					\
+{							\
+	t = ror32(t,  8); t = ls_box(t) ^ rco_tab[i];	\
+	t ^= E_KEY[6 * i];     E_KEY[6 * i + 6] = t;	\
+	t ^= E_KEY[6 * i + 1]; E_KEY[6 * i + 7] = t;	\
+	t ^= E_KEY[6 * i + 2]; E_KEY[6 * i + 8] = t;	\
+	t ^= E_KEY[6 * i + 3]; E_KEY[6 * i + 9] = t;	\
+	t ^= E_KEY[6 * i + 4]; E_KEY[6 * i + 10] = t;	\
+	t ^= E_KEY[6 * i + 5]; E_KEY[6 * i + 11] = t;	\
+}
+
+#define loop8(i)					\
+{							\
+	t = ror32(t,  8); ; t = ls_box(t) ^ rco_tab[i];	\
+	t ^= E_KEY[8 * i];     E_KEY[8 * i + 8] = t;	\
+	t ^= E_KEY[8 * i + 1]; E_KEY[8 * i + 9] = t;	\
+	t ^= E_KEY[8 * i + 2]; E_KEY[8 * i + 10] = t;	\
+	t ^= E_KEY[8 * i + 3]; E_KEY[8 * i + 11] = t;	\
+	t  = E_KEY[8 * i + 4] ^ ls_box(t);		\
+	E_KEY[8 * i + 12] = t;				\
+	t ^= E_KEY[8 * i + 5]; E_KEY[8 * i + 13] = t;	\
+	t ^= E_KEY[8 * i + 6]; E_KEY[8 * i + 14] = t;	\
+	t ^= E_KEY[8 * i + 7]; E_KEY[8 * i + 15] = t;	\
+}
+
+static int aes_set_key(void *ctx_arg, const u8 *in_key, unsigned int key_len,
+		       u32 *flags)
+{
+	struct aes_ctx *ctx = ctx_arg;
+	u32 i, j, t, u, v, w;
+
+	if (key_len != 16 && key_len != 24 && key_len != 32) {
+		*flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
+		return -EINVAL;
+	}
+
+	ctx->key_length = key_len;
+
+	D_KEY[key_len + 24] = E_KEY[0] = u32_in(in_key);
+	D_KEY[key_len + 25] = E_KEY[1] = u32_in(in_key + 4);
+	D_KEY[key_len + 26] = E_KEY[2] = u32_in(in_key + 8);
+	D_KEY[key_len + 27] = E_KEY[3] = u32_in(in_key + 12);
+
+	switch (key_len) {
+	case 16:
+		t = E_KEY[3];
+		for (i = 0; i < 10; ++i)
+			loop4(i);
+		break;
+
+	case 24:
+		E_KEY[4] = u32_in(in_key + 16);
+		t = E_KEY[5] = u32_in(in_key + 20);
+		for (i = 0; i < 8; ++i)
+			loop6 (i);
+		break;
+
+	case 32:
+		E_KEY[4] = u32_in(in_key + 16);
+		E_KEY[5] = u32_in(in_key + 20);
+		E_KEY[6] = u32_in(in_key + 24);
+		t = E_KEY[7] = u32_in(in_key + 28);
+		for (i = 0; i < 7; ++i)
+			loop8(i);
+		break;
+	}
+
+	D_KEY[0] = E_KEY[key_len + 24];
+	D_KEY[1] = E_KEY[key_len + 25];
+	D_KEY[2] = E_KEY[key_len + 26];
+	D_KEY[3] = E_KEY[key_len + 27];
+
+	for (i = 4; i < key_len + 24; ++i) {
+		j = key_len + 24 - (i & ~3) + (i & 3);
+		imix_col(D_KEY[j], E_KEY[i]);
+	}
+
+	return 0;
+}
+
+extern void aes_encrypt(void *ctx_arg, u8 *out, const u8 *in);
+extern void aes_decrypt(void *ctx_arg, u8 *out, const u8 *in);
+
+static struct crypto_alg aes_alg = {
+	.cra_name		=	"aes",
+	.cra_flags		=	CRYPTO_ALG_TYPE_CIPHER,
+	.cra_blocksize		=	AES_BLOCK_SIZE,
+	.cra_ctxsize		=	sizeof(struct aes_ctx),
+	.cra_module		=	THIS_MODULE,
+	.cra_list		=	LIST_HEAD_INIT(aes_alg.cra_list),
+	.cra_u			=	{
+		.cipher = {
+			.cia_min_keysize	=	AES_MIN_KEY_SIZE,
+			.cia_max_keysize	=	AES_MAX_KEY_SIZE,
+			.cia_setkey	   	= 	aes_set_key,
+			.cia_encrypt	 	=	aes_encrypt,
+			.cia_decrypt	  	=	aes_decrypt
+		}
+	}
+};
+
+static int __init aes_init(void)
+{
+	gen_tabs();
+	return crypto_register_alg(&aes_alg);
+}
+
+static void __exit aes_fini(void)
+{
+	crypto_unregister_alg(&aes_alg);
+}
+
+module_init(aes_init);
+module_exit(aes_fini);
+
+MODULE_DESCRIPTION("Rijndael (AES) Cipher Algorithm");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("aes");
diff --git a/arch/x86_64/defconfig b/arch/x86_64/defconfig
--- a/arch/x86_64/defconfig
+++ b/arch/x86_64/defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc4
-# Fri May 13 06:39:11 2005
+# Linux kernel version: 2.6.13-rc6-git3
+# Fri Aug 12 16:40:34 2005
 #
 CONFIG_X86_64=y
 CONFIG_64BIT=y
@@ -84,14 +84,27 @@ CONFIG_X86_IO_APIC=y
 CONFIG_X86_LOCAL_APIC=y
 CONFIG_MTRR=y
 CONFIG_SMP=y
-# CONFIG_PREEMPT is not set
 CONFIG_SCHED_SMT=y
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_PREEMPT_BKL=y
 CONFIG_K8_NUMA=y
 # CONFIG_NUMA_EMU is not set
-CONFIG_DISCONTIGMEM=y
+CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
 CONFIG_NUMA=y
+CONFIG_ARCH_DISCONTIGMEM_DEFAULT=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_SELECT_MEMORY_MODEL=y
+# CONFIG_FLATMEM_MANUAL is not set
+CONFIG_DISCONTIGMEM_MANUAL=y
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_DISCONTIGMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_NEED_MULTIPLE_NODES=y
+CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y
 CONFIG_HAVE_DEC_LOCK=y
-CONFIG_NR_CPUS=8
+CONFIG_NR_CPUS=32
 CONFIG_HPET_TIMER=y
 CONFIG_X86_PM_TIMER=y
 CONFIG_HPET_EMULATE_RTC=y
@@ -99,7 +112,13 @@ CONFIG_GART_IOMMU=y
 CONFIG_SWIOTLB=y
 CONFIG_X86_MCE=y
 CONFIG_X86_MCE_INTEL=y
+CONFIG_PHYSICAL_START=0x100000
+# CONFIG_KEXEC is not set
 CONFIG_SECCOMP=y
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_ISA_DMA_API=y
@@ -118,12 +137,11 @@ CONFIG_PM_STD_PARTITION=""
 CONFIG_ACPI=y
 CONFIG_ACPI_BOOT=y
 CONFIG_ACPI_INTERPRETER=y
-CONFIG_ACPI_SLEEP=y
-CONFIG_ACPI_SLEEP_PROC_FS=y
 CONFIG_ACPI_AC=y
 CONFIG_ACPI_BATTERY=y
 CONFIG_ACPI_BUTTON=y
 # CONFIG_ACPI_VIDEO is not set
+CONFIG_ACPI_HOTKEY=m
 CONFIG_ACPI_FAN=y
 CONFIG_ACPI_PROCESSOR=y
 CONFIG_ACPI_THERMAL=y
@@ -154,6 +172,7 @@ CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
 # CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
 CONFIG_CPU_FREQ_GOV_USERSPACE=y
 CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
 
 #
 # CPUFreq processor drivers
@@ -204,6 +223,72 @@ CONFIG_SYSVIPC_COMPAT=y
 CONFIG_UID16=y
 
 #
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_IP_TCPDIAG=y
+CONFIG_IP_TCPDIAG_IPV6=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+CONFIG_IPV6=y
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_IPV6_TUNNEL is not set
+# CONFIG_NETFILTER is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+
+#
 # Device Drivers
 #
 
@@ -308,6 +393,7 @@ CONFIG_BLK_DEV_AMD74XX=y
 # CONFIG_BLK_DEV_HPT366 is not set
 # CONFIG_BLK_DEV_SC1200 is not set
 CONFIG_BLK_DEV_PIIX=y
+# CONFIG_BLK_DEV_IT821X is not set
 # CONFIG_BLK_DEV_NS87415 is not set
 # CONFIG_BLK_DEV_PDC202XX_OLD is not set
 CONFIG_BLK_DEV_PDC202XX_NEW=y
@@ -338,6 +424,7 @@ CONFIG_BLK_DEV_SD=y
 # CONFIG_CHR_DEV_OSST is not set
 # CONFIG_BLK_DEV_SR is not set
 # CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
 
 #
 # Some SCSI devices (e.g. CD jukebox) support multiple LUNs
@@ -402,6 +489,7 @@ CONFIG_SCSI_QLA2XXX=y
 # CONFIG_SCSI_QLA2300 is not set
 # CONFIG_SCSI_QLA2322 is not set
 # CONFIG_SCSI_QLA6312 is not set
+# CONFIG_SCSI_QLA24XX is not set
 # CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
@@ -410,13 +498,22 @@ CONFIG_SCSI_QLA2XXX=y
 #
 # Multi-device support (RAID and LVM)
 #
-# CONFIG_MD is not set
+CONFIG_MD=y
+# CONFIG_BLK_DEV_MD is not set
+CONFIG_BLK_DEV_DM=y
+# CONFIG_DM_CRYPT is not set
+# CONFIG_DM_SNAPSHOT is not set
+# CONFIG_DM_MIRROR is not set
+# CONFIG_DM_ZERO is not set
+# CONFIG_DM_MULTIPATH is not set
 
 #
 # Fusion MPT device support
 #
 CONFIG_FUSION=y
-CONFIG_FUSION_MAX_SGE=40
+CONFIG_FUSION_SPI=y
+# CONFIG_FUSION_FC is not set
+CONFIG_FUSION_MAX_SGE=128
 # CONFIG_FUSION_CTL is not set
 
 #
@@ -430,75 +527,8 @@ CONFIG_FUSION_MAX_SGE=40
 # CONFIG_I2O is not set
 
 #
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-CONFIG_UNIX=y
-# CONFIG_NET_KEY is not set
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-# CONFIG_IP_PNP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_TUNNEL is not set
-CONFIG_IP_TCPDIAG=y
-CONFIG_IP_TCPDIAG_IPV6=y
-CONFIG_IPV6=y
-# CONFIG_IPV6_PRIVACY is not set
-# CONFIG_INET6_AH is not set
-# CONFIG_INET6_ESP is not set
-# CONFIG_INET6_IPCOMP is not set
-# CONFIG_INET6_TUNNEL is not set
-# CONFIG_IPV6_TUNNEL is not set
-# CONFIG_NETFILTER is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
+# Network device support
 #
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-CONFIG_NETPOLL=y
-# CONFIG_NETPOLL_RX is not set
-# CONFIG_NETPOLL_TRAP is not set
-CONFIG_NET_POLL_CONTROLLER=y
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
 CONFIG_NETDEVICES=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
@@ -517,7 +547,9 @@ CONFIG_NET_ETHERNET=y
 CONFIG_MII=y
 # CONFIG_HAPPYMEAL is not set
 # CONFIG_SUNGEM is not set
-# CONFIG_NET_VENDOR_3COM is not set
+CONFIG_NET_VENDOR_3COM=y
+CONFIG_VORTEX=y
+# CONFIG_TYPHOON is not set
 
 #
 # Tulip family network device support
@@ -532,7 +564,7 @@ CONFIG_NET_PCI=y
 CONFIG_FORCEDETH=y
 # CONFIG_DGRS is not set
 # CONFIG_EEPRO100 is not set
-# CONFIG_E100 is not set
+CONFIG_E100=y
 # CONFIG_FEALNX is not set
 # CONFIG_NATSEMI is not set
 # CONFIG_NE2K_PCI is not set
@@ -558,9 +590,11 @@ CONFIG_E1000=y
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
 # CONFIG_R8169 is not set
+# CONFIG_SKGE is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_VIA_VELOCITY is not set
 CONFIG_TIGON3=y
+# CONFIG_BNX2 is not set
 
 #
 # Ethernet (10000 Mbit)
@@ -591,6 +625,10 @@ CONFIG_S2IO=m
 # CONFIG_NET_FC is not set
 # CONFIG_SHAPER is not set
 CONFIG_NETCONSOLE=y
+CONFIG_NETPOLL=y
+# CONFIG_NETPOLL_RX is not set
+# CONFIG_NETPOLL_TRAP is not set
+CONFIG_NET_POLL_CONTROLLER=y
 
 #
 # ISDN subsystem
@@ -647,7 +685,6 @@ CONFIG_SERIO_I8042=y
 CONFIG_SERIO_LIBPS2=y
 # CONFIG_SERIO_RAW is not set
 # CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
 
 #
 # Character devices
@@ -716,6 +753,7 @@ CONFIG_MAX_RAW_DEVS=256
 # I2C support
 #
 # CONFIG_I2C is not set
+# CONFIG_I2C_SENSOR is not set
 
 #
 # Dallas's 1-wire bus
@@ -723,6 +761,12 @@ CONFIG_MAX_RAW_DEVS=256
 # CONFIG_W1 is not set
 
 #
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
 # Misc devices
 #
 # CONFIG_IBM_ASM is not set
@@ -808,6 +852,7 @@ CONFIG_USB_DEVICEFS=y
 CONFIG_USB_EHCI_HCD=y
 # CONFIG_USB_EHCI_SPLIT_ISO is not set
 # CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+# CONFIG_USB_ISP116X_HCD is not set
 CONFIG_USB_OHCI_HCD=y
 # CONFIG_USB_OHCI_BIG_ENDIAN is not set
 CONFIG_USB_OHCI_LITTLE_ENDIAN=y
@@ -846,12 +891,15 @@ CONFIG_USB_HIDINPUT=y
 # CONFIG_USB_HIDDEV is not set
 # CONFIG_USB_AIPTEK is not set
 # CONFIG_USB_WACOM is not set
+# CONFIG_USB_ACECAD is not set
 # CONFIG_USB_KBTAB is not set
 # CONFIG_USB_POWERMATE is not set
 # CONFIG_USB_MTOUCH is not set
+# CONFIG_USB_ITMTOUCH is not set
 # CONFIG_USB_EGALAX is not set
 # CONFIG_USB_XPAD is not set
 # CONFIG_USB_ATI_REMOTE is not set
+# CONFIG_USB_KEYSPAN_REMOTE is not set
 
 #
 # USB Imaging devices
@@ -902,10 +950,11 @@ CONFIG_USB_MON=y
 # CONFIG_USB_PHIDGETSERVO is not set
 # CONFIG_USB_IDMOUSE is not set
 # CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
 # CONFIG_USB_TEST is not set
 
 #
-# USB ATM/DSL drivers
+# USB DSL modem support
 #
 
 #
@@ -924,6 +973,10 @@ CONFIG_USB_MON=y
 # CONFIG_INFINIBAND is not set
 
 #
+# SN Devices
+#
+
+#
 # Firmware Drivers
 #
 # CONFIG_EDD is not set
@@ -935,6 +988,7 @@ CONFIG_EXT2_FS=y
 CONFIG_EXT2_FS_XATTR=y
 CONFIG_EXT2_FS_POSIX_ACL=y
 # CONFIG_EXT2_FS_SECURITY is not set
+# CONFIG_EXT2_FS_XIP is not set
 CONFIG_EXT3_FS=y
 CONFIG_EXT3_FS_XATTR=y
 CONFIG_EXT3_FS_POSIX_ACL=y
@@ -957,6 +1011,7 @@ CONFIG_FS_POSIX_ACL=y
 # CONFIG_XFS_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
 # CONFIG_QUOTA is not set
 CONFIG_DNOTIFY=y
 CONFIG_AUTOFS_FS=y
@@ -986,7 +1041,6 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
 CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
 # CONFIG_DEVPTS_FS_XATTR is not set
 CONFIG_TMPFS=y
 # CONFIG_TMPFS_XATTR is not set
@@ -1016,15 +1070,18 @@ CONFIG_RAMFS=y
 #
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
 # CONFIG_NFS_V4 is not set
 # CONFIG_NFS_DIRECTIO is not set
 CONFIG_NFSD=y
 CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
 # CONFIG_NFSD_V4 is not set
 CONFIG_NFSD_TCP=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_EXPORTFS=y
+CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
diff --git a/arch/x86_64/ia32/Makefile b/arch/x86_64/ia32/Makefile
--- a/arch/x86_64/ia32/Makefile
+++ b/arch/x86_64/ia32/Makefile
@@ -4,14 +4,14 @@
 
 obj-$(CONFIG_IA32_EMULATION) := ia32entry.o sys_ia32.o ia32_ioctl.o \
 	ia32_signal.o tls32.o \
-	ia32_binfmt.o fpu32.o ptrace32.o syscall32.o
+	ia32_binfmt.o fpu32.o ptrace32.o syscall32.o syscall32_syscall.o
 
 sysv-$(CONFIG_SYSVIPC) := ipc32.o
 obj-$(CONFIG_IA32_EMULATION) += $(sysv-y)
 
 obj-$(CONFIG_IA32_AOUT) += ia32_aout.o
 
-$(obj)/syscall32.o: $(src)/syscall32.c \
+$(obj)/syscall32_syscall.o: \
 	$(foreach F,sysenter syscall,$(obj)/vsyscall-$F.so)
 
 # Teach kbuild about targets
diff --git a/arch/x86_64/ia32/ia32_aout.c b/arch/x86_64/ia32/ia32_aout.c
--- a/arch/x86_64/ia32/ia32_aout.c
+++ b/arch/x86_64/ia32/ia32_aout.c
@@ -42,7 +42,7 @@ extern int ia32_setup_arg_pages(struct l
 static int load_aout_binary(struct linux_binprm *, struct pt_regs * regs);
 static int load_aout_library(struct file*);
 
-#if CORE_DUMP
+#ifdef CORE_DUMP
 static int aout_core_dump(long signr, struct pt_regs * regs, struct file *file);
 
 /*
@@ -103,7 +103,7 @@ static struct linux_binfmt aout_format =
 	.module		= THIS_MODULE,
 	.load_binary	= load_aout_binary,
 	.load_shlib	= load_aout_library,
-#if CORE_DUMP
+#ifdef CORE_DUMP
 	.core_dump	= aout_core_dump,
 #endif
 	.min_coredump	= PAGE_SIZE
@@ -120,7 +120,7 @@ static void set_brk(unsigned long start,
 	up_write(&current->mm->mmap_sem);
 }
 
-#if CORE_DUMP
+#ifdef CORE_DUMP
 /*
  * These are the only things you should do on a core-file: use only these
  * macros to write out all the necessary info.
@@ -312,6 +312,7 @@ static int load_aout_binary(struct linux
 	current->mm->brk = ex.a_bss +
 		(current->mm->start_brk = N_BSSADDR(ex));
 	current->mm->free_area_cache = TASK_UNMAPPED_BASE;
+	current->mm->cached_hole_size = 0;
 
 	set_mm_counter(current->mm, rss, 0);
 	current->mm->mmap = NULL;
diff --git a/arch/x86_64/ia32/ia32_binfmt.c b/arch/x86_64/ia32/ia32_binfmt.c
--- a/arch/x86_64/ia32/ia32_binfmt.c
+++ b/arch/x86_64/ia32/ia32_binfmt.c
@@ -46,7 +46,7 @@ struct elf_phdr; 
 
 #define IA32_EMULATOR 1
 
-#define ELF_ET_DYN_BASE		(TASK_UNMAPPED_32 + 0x1000000)
+#define ELF_ET_DYN_BASE		(TASK_UNMAPPED_BASE + 0x1000000)
 
 #undef ELF_ARCH
 #define ELF_ARCH EM_386
@@ -307,9 +307,6 @@ MODULE_AUTHOR("Eric Youngdale, Andi Klee
 
 #define elf_addr_t __u32
 
-#undef TASK_SIZE
-#define TASK_SIZE 0xffffffff
-
 static void elf32_init(struct pt_regs *);
 
 #define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1
diff --git a/arch/x86_64/ia32/ia32_signal.c b/arch/x86_64/ia32/ia32_signal.c
--- a/arch/x86_64/ia32/ia32_signal.c
+++ b/arch/x86_64/ia32/ia32_signal.c
@@ -428,8 +428,8 @@ get_sigframe(struct k_sigaction *ka, str
 	return (void __user *)((rsp - frame_size) & -8UL);
 }
 
-void ia32_setup_frame(int sig, struct k_sigaction *ka,
-			compat_sigset_t *set, struct pt_regs * regs)
+int ia32_setup_frame(int sig, struct k_sigaction *ka,
+		     compat_sigset_t *set, struct pt_regs * regs)
 {
 	struct sigframe __user *frame;
 	int err = 0;
@@ -514,14 +514,15 @@ void ia32_setup_frame(int sig, struct k_
 		current->comm, current->pid, frame, regs->rip, frame->pretcode);
 #endif
 
-	return;
+	return 1;
 
 give_sigsegv:
 	force_sigsegv(sig, current);
+	return 0;
 }
 
-void ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
-			   compat_sigset_t *set, struct pt_regs * regs)
+int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
+			compat_sigset_t *set, struct pt_regs * regs)
 {
 	struct rt_sigframe __user *frame;
 	int err = 0;
@@ -613,9 +614,9 @@ void ia32_setup_rt_frame(int sig, struct
 		current->comm, current->pid, frame, regs->rip, frame->pretcode);
 #endif
 
-	return;
+	return 1;
 
 give_sigsegv:
 	force_sigsegv(sig, current);
+	return 0;
 }
-
diff --git a/arch/x86_64/ia32/ia32entry.S b/arch/x86_64/ia32/ia32entry.S
--- a/arch/x86_64/ia32/ia32entry.S
+++ b/arch/x86_64/ia32/ia32entry.S
@@ -589,13 +589,17 @@ ia32_sys_call_table:
 	.quad compat_sys_mq_timedreceive	/* 280 */
 	.quad compat_sys_mq_notify
 	.quad compat_sys_mq_getsetattr
-	.quad quiet_ni_syscall		/* reserved for kexec */
+	.quad compat_sys_kexec_load	/* reserved for kexec */
 	.quad compat_sys_waitid
-	.quad quiet_ni_syscall		/* sys_altroot */
+	.quad quiet_ni_syscall		/* 285: sys_altroot */
 	.quad sys_add_key
 	.quad sys_request_key
 	.quad sys_keyctl
-	/* don't forget to change IA32_NR_syscalls */
+	.quad sys_ioprio_set
+	.quad sys_ioprio_get		/* 290 */
+	.quad sys_inotify_init
+	.quad sys_inotify_add_watch
+	.quad sys_inotify_rm_watch
 ia32_syscall_end:		
 	.rept IA32_NR_syscalls-(ia32_syscall_end-ia32_sys_call_table)/8
 		.quad ni_syscall
diff --git a/arch/x86_64/ia32/ptrace32.c b/arch/x86_64/ia32/ptrace32.c
--- a/arch/x86_64/ia32/ptrace32.c
+++ b/arch/x86_64/ia32/ptrace32.c
@@ -43,11 +43,11 @@ static int putreg32(struct task_struct *
 	switch (regno) {
 	case offsetof(struct user32, regs.fs):
 		if (val && (val & 3) != 3) return -EIO; 
-		child->thread.fs = val & 0xffff; 
+		child->thread.fsindex = val & 0xffff;
 		break;
 	case offsetof(struct user32, regs.gs):
 		if (val && (val & 3) != 3) return -EIO; 
-		child->thread.gs = val & 0xffff;
+		child->thread.gsindex = val & 0xffff;
 		break;
 	case offsetof(struct user32, regs.ds):
 		if (val && (val & 3) != 3) return -EIO; 
@@ -138,10 +138,10 @@ static int getreg32(struct task_struct *
 
 	switch (regno) {
 	case offsetof(struct user32, regs.fs):
-	        *val = child->thread.fs; 
+	        *val = child->thread.fsindex;
 		break;
 	case offsetof(struct user32, regs.gs):
-		*val = child->thread.gs;
+		*val = child->thread.gsindex;
 		break;
 	case offsetof(struct user32, regs.ds):
 		*val = child->thread.ds;
diff --git a/arch/x86_64/ia32/sys_ia32.c b/arch/x86_64/ia32/sys_ia32.c
--- a/arch/x86_64/ia32/sys_ia32.c
+++ b/arch/x86_64/ia32/sys_ia32.c
@@ -61,6 +61,7 @@
 #include <linux/ptrace.h>
 #include <linux/highuid.h>
 #include <linux/vmalloc.h>
+#include <linux/fsnotify.h>
 #include <asm/mman.h>
 #include <asm/types.h>
 #include <asm/uaccess.h>
@@ -984,8 +985,10 @@ asmlinkage long sys32_open(const char __
 			if (IS_ERR(f)) {
 				put_unused_fd(fd); 
 				fd = error;
-			} else
+			} else {
+				fsnotify_open(f->f_dentry);
 				fd_install(fd, f);
+			}
 		}
 		putname(tmp);
 	}
diff --git a/arch/x86_64/ia32/syscall32.c b/arch/x86_64/ia32/syscall32.c
--- a/arch/x86_64/ia32/syscall32.c
+++ b/arch/x86_64/ia32/syscall32.c
@@ -14,16 +14,6 @@
 #include <asm/tlbflush.h>
 #include <asm/ia32_unistd.h>
 
-/* 32bit VDSOs mapped into user space. */ 
-asm(".section \".init.data\",\"aw\"\n"
-    "syscall32_syscall:\n"
-    ".incbin \"arch/x86_64/ia32/vsyscall-syscall.so\"\n"
-    "syscall32_syscall_end:\n"
-    "syscall32_sysenter:\n"
-    ".incbin \"arch/x86_64/ia32/vsyscall-sysenter.so\"\n"
-    "syscall32_sysenter_end:\n"
-    ".previous");
-
 extern unsigned char syscall32_syscall[], syscall32_syscall_end[];
 extern unsigned char syscall32_sysenter[], syscall32_sysenter_end[];
 extern int sysctl_vsyscall32;
@@ -57,6 +47,7 @@ int syscall32_setup_pages(struct linux_b
 	int npages = (VSYSCALL32_END - VSYSCALL32_BASE) >> PAGE_SHIFT;
 	struct vm_area_struct *vma;
 	struct mm_struct *mm = current->mm;
+	int ret;
 
 	vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
 	if (!vma)
@@ -78,7 +69,11 @@ int syscall32_setup_pages(struct linux_b
 	vma->vm_mm = mm;
 
 	down_write(&mm->mmap_sem);
-	insert_vm_struct(mm, vma);
+	if ((ret = insert_vm_struct(mm, vma))) {
+		up_write(&mm->mmap_sem);
+		kmem_cache_free(vm_area_cachep, vma);
+		return ret;
+	}
 	mm->total_vm += npages;
 	up_write(&mm->mmap_sem);
 	return 0;
diff --git a/arch/x86_64/ia32/syscall32_syscall.S b/arch/x86_64/ia32/syscall32_syscall.S
new file mode 100644
--- /dev/null
+++ b/arch/x86_64/ia32/syscall32_syscall.S
@@ -0,0 +1,17 @@
+/* 32bit VDSOs mapped into user space. */
+
+	.section ".init.data","aw"
+
+	.globl syscall32_syscall
+	.globl syscall32_syscall_end
+
+syscall32_syscall:
+	.incbin "arch/x86_64/ia32/vsyscall-syscall.so"
+syscall32_syscall_end:
+
+	.globl syscall32_sysenter
+	.globl syscall32_sysenter_end
+
+syscall32_sysenter:
+	.incbin "arch/x86_64/ia32/vsyscall-sysenter.so"
+syscall32_sysenter_end:
diff --git a/arch/x86_64/kernel/Makefile b/arch/x86_64/kernel/Makefile
--- a/arch/x86_64/kernel/Makefile
+++ b/arch/x86_64/kernel/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_SMP)		+= smp.o smpboot.o tr
 obj-$(CONFIG_X86_LOCAL_APIC)	+= apic.o  nmi.o
 obj-$(CONFIG_X86_IO_APIC)	+= io_apic.o mpparse.o \
 		genapic.o genapic_cluster.o genapic_flat.o
+obj-$(CONFIG_KEXEC)		+= machine_kexec.o relocate_kernel.o crash.o
 obj-$(CONFIG_PM)		+= suspend.o
 obj-$(CONFIG_SOFTWARE_SUSPEND)	+= suspend_asm.o
 obj-$(CONFIG_CPU_FREQ)		+= cpufreq/
diff --git a/arch/x86_64/kernel/acpi/wakeup.S b/arch/x86_64/kernel/acpi/wakeup.S
--- a/arch/x86_64/kernel/acpi/wakeup.S
+++ b/arch/x86_64/kernel/acpi/wakeup.S
@@ -67,7 +67,7 @@ wakeup_code:
 	shll	$4, %eax
 	addl	$(gdta - wakeup_code), %eax
 	movl	%eax, gdt_48a +2 - wakeup_code
-	lgdt	%ds:gdt_48a - wakeup_code		# load gdt with whatever is
+	lgdtl	%ds:gdt_48a - wakeup_code	# load gdt with whatever is
 						# appropriate
 
 	movl	$1, %eax			# protected mode (PE) bit
diff --git a/arch/x86_64/kernel/aperture.c b/arch/x86_64/kernel/aperture.c
--- a/arch/x86_64/kernel/aperture.c
+++ b/arch/x86_64/kernel/aperture.c
@@ -40,11 +40,7 @@ int fix_aperture __initdata = 1;
 
 static u32 __init allocate_aperture(void) 
 {
-#ifdef CONFIG_DISCONTIGMEM
 	pg_data_t *nd0 = NODE_DATA(0);
-#else
-	pg_data_t *nd0 = &contig_page_data;
-#endif	
 	u32 aper_size;
 	void *p; 
 
diff --git a/arch/x86_64/kernel/apic.c b/arch/x86_64/kernel/apic.c
--- a/arch/x86_64/kernel/apic.c
+++ b/arch/x86_64/kernel/apic.c
@@ -133,7 +133,7 @@ void __init connect_bsp_APIC(void)
 	}
 }
 
-void disconnect_bsp_APIC(void)
+void disconnect_bsp_APIC(int virt_wire_setup)
 {
 	if (pic_mode) {
 		/*
@@ -146,6 +146,42 @@ void disconnect_bsp_APIC(void)
 		outb(0x70, 0x22);
 		outb(0x00, 0x23);
 	}
+	else {
+		/* Go back to Virtual Wire compatibility mode */
+		unsigned long value;
+
+		/* For the spurious interrupt use vector F, and enable it */
+		value = apic_read(APIC_SPIV);
+		value &= ~APIC_VECTOR_MASK;
+		value |= APIC_SPIV_APIC_ENABLED;
+		value |= 0xf;
+		apic_write_around(APIC_SPIV, value);
+
+		if (!virt_wire_setup) {
+			/* For LVT0 make it edge triggered, active high, external and enabled */
+			value = apic_read(APIC_LVT0);
+			value &= ~(APIC_MODE_MASK | APIC_SEND_PENDING |
+				APIC_INPUT_POLARITY | APIC_LVT_REMOTE_IRR |
+				APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED );
+			value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING;
+			value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_EXTINT);
+			apic_write_around(APIC_LVT0, value);
+		}
+		else {
+			/* Disable LVT0 */
+			apic_write_around(APIC_LVT0, APIC_LVT_MASKED);
+		}
+
+		/* For LVT1 make it edge triggered, active high, nmi and enabled */
+		value = apic_read(APIC_LVT1);
+		value &= ~(
+			APIC_MODE_MASK | APIC_SEND_PENDING |
+			APIC_INPUT_POLARITY | APIC_LVT_REMOTE_IRR |
+			APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED);
+		value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING;
+		value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_NMI);
+		apic_write_around(APIC_LVT1, value);
+	}
 }
 
 void disable_local_APIC(void)
@@ -285,7 +321,7 @@ void __init init_bsp_APIC(void)
 	apic_write_around(APIC_LVT1, value);
 }
 
-void __init setup_local_APIC (void)
+void __cpuinit setup_local_APIC (void)
 {
 	unsigned int value, ver, maxlvt;
 
@@ -534,7 +570,7 @@ static struct sys_device device_lapic = 
 	.cls		= &lapic_sysclass,
 };
 
-static void __init apic_pm_activate(void)
+static void __cpuinit apic_pm_activate(void)
 {
 	apic_pm_state.active = 1;
 }
@@ -774,14 +810,14 @@ void __init setup_boot_APIC_clock (void)
 	local_irq_enable();
 }
 
-void __init setup_secondary_APIC_clock(void)
+void __cpuinit setup_secondary_APIC_clock(void)
 {
 	local_irq_disable(); /* FIXME: Do we need this? --RR */
 	setup_APIC_timer(calibration_result);
 	local_irq_enable();
 }
 
-void __init disable_APIC_timer(void)
+void __cpuinit disable_APIC_timer(void)
 {
 	if (using_apic_timer) {
 		unsigned long v;
diff --git a/arch/x86_64/kernel/crash.c b/arch/x86_64/kernel/crash.c
new file mode 100644
--- /dev/null
+++ b/arch/x86_64/kernel/crash.c
@@ -0,0 +1,35 @@
+/*
+ * Architecture specific (x86_64) functions for kexec based crash dumps.
+ *
+ * Created by: Hariprasad Nellitheertha (hari@in.ibm.com)
+ *
+ * Copyright (C) IBM Corporation, 2004. All rights reserved.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/smp.h>
+#include <linux/irq.h>
+#include <linux/reboot.h>
+#include <linux/kexec.h>
+
+#include <asm/processor.h>
+#include <asm/hardirq.h>
+#include <asm/nmi.h>
+#include <asm/hw_irq.h>
+
+note_buf_t crash_notes[NR_CPUS];
+
+void machine_crash_shutdown(struct pt_regs *regs)
+{
+	/* This function is only called after the system
+	 * has paniced or is otherwise in a critical state.
+	 * The minimum amount of code to allow a kexec'd kernel
+	 * to run successfully needs to happen here.
+	 *
+	 * In practice this means shooting down the other cpus in
+	 * an SMP system.
+	 */
+}
diff --git a/arch/x86_64/kernel/e820.c b/arch/x86_64/kernel/e820.c
--- a/arch/x86_64/kernel/e820.c
+++ b/arch/x86_64/kernel/e820.c
@@ -16,6 +16,7 @@
 #include <linux/bootmem.h>
 #include <linux/ioport.h>
 #include <linux/string.h>
+#include <linux/kexec.h>
 #include <asm/page.h>
 #include <asm/e820.h>
 #include <asm/proto.h>
@@ -184,6 +185,40 @@ unsigned long __init e820_end_of_ram(voi
 }
 
 /* 
+ * Compute how much memory is missing in a range.
+ * Unlike the other functions in this file the arguments are in page numbers.
+ */
+unsigned long __init
+e820_hole_size(unsigned long start_pfn, unsigned long end_pfn)
+{
+	unsigned long ram = 0;
+	unsigned long start = start_pfn << PAGE_SHIFT;
+	unsigned long end = end_pfn << PAGE_SHIFT;
+	int i;
+	for (i = 0; i < e820.nr_map; i++) {
+		struct e820entry *ei = &e820.map[i];
+		unsigned long last, addr;
+
+		if (ei->type != E820_RAM ||
+		    ei->addr+ei->size <= start ||
+		    ei->addr >= end)
+			continue;
+
+		addr = round_up(ei->addr, PAGE_SIZE);
+		if (addr < start)
+			addr = start;
+
+		last = round_down(ei->addr + ei->size, PAGE_SIZE);
+		if (last >= end)
+			last = end;
+
+		if (last > addr)
+			ram += last - addr;
+	}
+	return ((end - start) - ram) >> PAGE_SHIFT;
+}
+
+/*
  * Mark e820 reserved areas as busy for the resource manager.
  */
 void __init e820_reserve_resources(void)
@@ -191,8 +226,6 @@ void __init e820_reserve_resources(void)
 	int i;
 	for (i = 0; i < e820.nr_map; i++) {
 		struct resource *res;
-		if (e820.map[i].addr + e820.map[i].size > 0x100000000ULL)
-			continue;
 		res = alloc_bootmem_low(sizeof(struct resource));
 		switch (e820.map[i].type) {
 		case E820_RAM:	res->name = "System RAM"; break;
@@ -212,6 +245,9 @@ void __init e820_reserve_resources(void)
 			 */
 			request_resource(res, &code_resource);
 			request_resource(res, &data_resource);
+#ifdef CONFIG_KEXEC
+			request_resource(res, &crashk_res);
+#endif
 		}
 	}
 }
diff --git a/arch/x86_64/kernel/early_printk.c b/arch/x86_64/kernel/early_printk.c
--- a/arch/x86_64/kernel/early_printk.c
+++ b/arch/x86_64/kernel/early_printk.c
@@ -2,20 +2,24 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/string.h>
+#include <linux/tty.h>
 #include <asm/io.h>
 #include <asm/processor.h>
 
 /* Simple VGA output */
 
 #ifdef __i386__
+#include <asm/setup.h>
 #define VGABASE		(__ISA_IO_base + 0xb8000)
 #else
+#include <asm/bootsetup.h>
 #define VGABASE		((void __iomem *)0xffffffff800b8000UL)
 #endif
 
-#define MAX_YPOS	25
-#define MAX_XPOS	80
+#define MAX_YPOS	max_ypos
+#define MAX_XPOS	max_xpos
 
+static int max_ypos = 25, max_xpos = 80;
 static int current_ypos = 1, current_xpos = 0; 
 
 static void early_vga_write(struct console *con, const char *str, unsigned n)
@@ -196,7 +200,10 @@ int __init setup_early_printk(char *opt)
 	} else if (!strncmp(buf, "ttyS", 4)) { 
 		early_serial_init(buf);
 		early_console = &early_serial_console;		
-	} else if (!strncmp(buf, "vga", 3)) {
+	} else if (!strncmp(buf, "vga", 3)
+	           && SCREEN_INFO.orig_video_isVGA == 1) {
+		max_xpos = SCREEN_INFO.orig_video_cols;
+		max_ypos = SCREEN_INFO.orig_video_lines;
 		early_console = &early_vga_console; 
 	}
 	early_console_initialized = 1;
diff --git a/arch/x86_64/kernel/entry.S b/arch/x86_64/kernel/entry.S
--- a/arch/x86_64/kernel/entry.S
+++ b/arch/x86_64/kernel/entry.S
@@ -76,7 +76,7 @@
 
 	.macro FAKE_STACK_FRAME child_rip
 	/* push in order ss, rsp, eflags, cs, rip */
-	xorq %rax, %rax
+	xorl %eax, %eax
 	pushq %rax /* ss */
 	CFI_ADJUST_CFA_OFFSET	8
 	pushq %rax /* rsp */
@@ -423,7 +423,7 @@ ENTRY(stub_rt_sigreturn)
 	testl $3,CS(%rdi)
 	je 1f
 	swapgs	
-1:	addl $1,%gs:pda_irqcount	# RED-PEN should check preempt count
+1:	incl	%gs:pda_irqcount	# RED-PEN should check preempt count
 	movq %gs:pda_irqstackptr,%rax
 	cmoveq %rax,%rsp							
 	pushq %rdi			# save old stack	
@@ -436,7 +436,7 @@ ENTRY(common_interrupt)
 ret_from_intr:		
 	popq  %rdi
 	cli	
-	subl $1,%gs:pda_irqcount
+	decl %gs:pda_irqcount
 #ifdef CONFIG_DEBUG_INFO
 	movq RBP(%rdi),%rbp
 #endif
@@ -494,7 +494,7 @@ retint_signal:
 	sti
 	SAVE_REST
 	movq $-1,ORIG_RAX(%rsp) 			
-	xorq %rsi,%rsi		# oldset
+	xorl %esi,%esi		# oldset
 	movq %rsp,%rdi		# &pt_regs
 	call do_notify_resume
 	RESTORE_REST
@@ -752,7 +752,7 @@ child_rip:
 	movq %rsi, %rdi
 	call *%rax
 	# exit
-	xorq %rdi, %rdi
+	xorl %edi, %edi
 	call do_exit
 
 /*
@@ -918,3 +918,15 @@ ENTRY(machine_check)
 ENTRY(call_debug)
        zeroentry do_call_debug
 
+ENTRY(call_softirq)
+	movq %gs:pda_irqstackptr,%rax
+	pushq %r15
+	movq %rsp,%r15
+	incl %gs:pda_irqcount
+	cmove %rax,%rsp
+	call __do_softirq
+	movq %r15,%rsp
+	decl %gs:pda_irqcount
+	popq %r15
+	ret
+
diff --git a/arch/x86_64/kernel/genapic.c b/arch/x86_64/kernel/genapic.c
--- a/arch/x86_64/kernel/genapic.c
+++ b/arch/x86_64/kernel/genapic.c
@@ -31,6 +31,7 @@ u8 x86_cpu_to_log_apicid[NR_CPUS] = { [0
 
 extern struct genapic apic_cluster;
 extern struct genapic apic_flat;
+extern struct genapic apic_physflat;
 
 struct genapic *genapic = &apic_flat;
 
@@ -44,12 +45,7 @@ void __init clustered_apic_check(void)
 	u8 clusters, max_cluster;
 	u8 id;
 	u8 cluster_cnt[NUM_APIC_CLUSTERS];
-
-	if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) {
-		/* AMD always uses flat mode right now */
-		genapic = &apic_flat;
-		goto print;
-	}
+	int num_cpus = 0;
 
 #if defined(CONFIG_ACPI_BUS)
 	/*
@@ -64,15 +60,34 @@ void __init clustered_apic_check(void)
 #endif
 
 	memset(cluster_cnt, 0, sizeof(cluster_cnt));
-
 	for (i = 0; i < NR_CPUS; i++) {
 		id = bios_cpu_apicid[i];
-		if (id != BAD_APICID)
-			cluster_cnt[APIC_CLUSTERID(id)]++;
+		if (id == BAD_APICID)
+			continue;
+		num_cpus++;
+		cluster_cnt[APIC_CLUSTERID(id)]++;
 	}
 
+	/* Don't use clustered mode on AMD platforms. */
+ 	if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) {
+		genapic = &apic_physflat;
+#ifndef CONFIG_CPU_HOTPLUG
+		/* In the CPU hotplug case we cannot use broadcast mode
+		   because that opens a race when a CPU is removed.
+		   Stay at physflat mode in this case.
+		   It is bad to do this unconditionally though. Once
+		   we have ACPI platform support for CPU hotplug
+		   we should detect hotplug capablity from ACPI tables and
+		   only do this when really needed. -AK */
+		if (num_cpus <= 8)
+			genapic = &apic_flat;
+#endif
+ 		goto print;
+ 	}
+
 	clusters = 0;
 	max_cluster = 0;
+
 	for (i = 0; i < NUM_APIC_CLUSTERS; i++) {
 		if (cluster_cnt[i] > 0) {
 			++clusters;
diff --git a/arch/x86_64/kernel/genapic_flat.c b/arch/x86_64/kernel/genapic_flat.c
--- a/arch/x86_64/kernel/genapic_flat.c
+++ b/arch/x86_64/kernel/genapic_flat.c
@@ -2,7 +2,7 @@
  * Copyright 2004 James Cleverdon, IBM.
  * Subject to the GNU Public License, v.2
  *
- * Flat APIC subarch code.  Maximum 8 CPUs, logical delivery.
+ * Flat APIC subarch code.
  *
  * Hacked for x86-64 by James Cleverdon from i386 architecture code by
  * Martin Bligh, Andi Kleen, James Bottomley, John Stultz, and
@@ -18,7 +18,6 @@
 #include <asm/smp.h>
 #include <asm/ipi.h>
 
-
 static cpumask_t flat_target_cpus(void)
 {
 	return cpu_online_map;
@@ -45,22 +44,6 @@ static void flat_init_apic_ldr(void)
 	apic_write_around(APIC_LDR, val);
 }
 
-static void flat_send_IPI_allbutself(int vector)
-{
-	/*
-	 * if there are no other CPUs in the system then
-	 * we get an APIC send error if we try to broadcast.
-	 * thus we have to avoid sending IPIs in this case.
-	 */
-	if (num_online_cpus() > 1)
-		__send_IPI_shortcut(APIC_DEST_ALLBUT, vector, APIC_DEST_LOGICAL);
-}
-
-static void flat_send_IPI_all(int vector)
-{
-	__send_IPI_shortcut(APIC_DEST_ALLINC, vector, APIC_DEST_LOGICAL);
-}
-
 static void flat_send_IPI_mask(cpumask_t cpumask, int vector)
 {
 	unsigned long mask = cpus_addr(cpumask)[0];
@@ -93,6 +76,17 @@ static void flat_send_IPI_mask(cpumask_t
 	local_irq_restore(flags);
 }
 
+static void flat_send_IPI_allbutself(int vector)
+{
+	if (((num_online_cpus()) - 1) >= 1)
+		__send_IPI_shortcut(APIC_DEST_ALLBUT, vector,APIC_DEST_LOGICAL);
+}
+
+static void flat_send_IPI_all(int vector)
+{
+	__send_IPI_shortcut(APIC_DEST_ALLINC, vector, APIC_DEST_LOGICAL);
+}
+
 static int flat_apic_id_registered(void)
 {
 	return physid_isset(GET_APIC_ID(apic_read(APIC_ID)), phys_cpu_present_map);
@@ -125,3 +119,63 @@ struct genapic apic_flat =  {
 	.cpu_mask_to_apicid = flat_cpu_mask_to_apicid,
 	.phys_pkg_id = phys_pkg_id,
 };
+
+/*
+ * Physflat mode is used when there are more than 8 CPUs on a AMD system.
+ * We cannot use logical delivery in this case because the mask
+ * overflows, so use physical mode.
+ */
+
+static cpumask_t physflat_target_cpus(void)
+{
+	return cpumask_of_cpu(0);
+}
+
+static void physflat_send_IPI_mask(cpumask_t cpumask, int vector)
+{
+	send_IPI_mask_sequence(cpumask, vector);
+}
+
+static void physflat_send_IPI_allbutself(int vector)
+{
+	cpumask_t allbutme = cpu_online_map;
+	int me = get_cpu();
+	cpu_clear(me, allbutme);
+	physflat_send_IPI_mask(allbutme, vector);
+	put_cpu();
+}
+
+static void physflat_send_IPI_all(int vector)
+{
+	physflat_send_IPI_mask(cpu_online_map, vector);
+}
+
+static unsigned int physflat_cpu_mask_to_apicid(cpumask_t cpumask)
+{
+	int cpu;
+
+	/*
+	 * We're using fixed IRQ delivery, can only return one phys APIC ID.
+	 * May as well be the first.
+	 */
+	cpu = first_cpu(cpumask);
+	if ((unsigned)cpu < NR_CPUS)
+		return x86_cpu_to_apicid[cpu];
+	else
+		return BAD_APICID;
+}
+
+struct genapic apic_physflat =  {
+	.name = "physical flat",
+	.int_delivery_mode = dest_LowestPrio,
+	.int_dest_mode = (APIC_DEST_PHYSICAL != 0),
+	.int_delivery_dest = APIC_DEST_PHYSICAL | APIC_DM_LOWEST,
+	.target_cpus = physflat_target_cpus,
+	.apic_id_registered = flat_apic_id_registered,
+	.init_apic_ldr = flat_init_apic_ldr,/*not needed, but shouldn't hurt*/
+	.send_IPI_all = physflat_send_IPI_all,
+	.send_IPI_allbutself = physflat_send_IPI_allbutself,
+	.send_IPI_mask = physflat_send_IPI_mask,
+	.cpu_mask_to_apicid = physflat_cpu_mask_to_apicid,
+	.phys_pkg_id = phys_pkg_id,
+};
diff --git a/arch/x86_64/kernel/head.S b/arch/x86_64/kernel/head.S
--- a/arch/x86_64/kernel/head.S
+++ b/arch/x86_64/kernel/head.S
@@ -137,14 +137,14 @@ startup_64:
 	wrmsr
 
 	/* Setup cr0 */
-	xorq	%rax, %rax
-	btsq	$31, %rax			/* Enable paging */
-	btsq	$0, %rax			/* Enable protected mode */
-	btsq	$1, %rax			/* Enable MP */
-	btsq	$4, %rax			/* Enable ET */
-	btsq	$5, %rax			/* Enable NE */
-	btsq	$16, %rax			/* Enable WP */
-	btsq	$18, %rax			/* Enable AM */
+#define CR0_PM				1		/* protected mode */
+#define CR0_MP				(1<<1)
+#define CR0_ET				(1<<4)
+#define CR0_NE				(1<<5)
+#define CR0_WP				(1<<16)
+#define CR0_AM				(1<<18)
+#define CR0_PAGING 			(1<<31)
+	movl $CR0_PM|CR0_MP|CR0_ET|CR0_NE|CR0_WP|CR0_AM|CR0_PAGING,%eax
 	/* Make changes effective */
 	movq	%rax, %cr0
 
@@ -248,23 +248,23 @@ ENTRY(_stext)
 	 */
 .org 0x1000
 ENTRY(init_level4_pgt)
-	.quad	0x0000000000102007		/* -> level3_ident_pgt */
+	.quad	0x0000000000002007 + __PHYSICAL_START	/* -> level3_ident_pgt */
 	.fill	255,8,0
-	.quad	0x000000000010a007
+	.quad	0x000000000000a007 + __PHYSICAL_START
 	.fill	254,8,0
 	/* (2^48-(2*1024*1024*1024))/(2^39) = 511 */
-	.quad	0x0000000000103007		/* -> level3_kernel_pgt */
+	.quad	0x0000000000003007 + __PHYSICAL_START	/* -> level3_kernel_pgt */
 
 .org 0x2000
 ENTRY(level3_ident_pgt)
-	.quad	0x0000000000104007
+	.quad	0x0000000000004007 + __PHYSICAL_START
 	.fill	511,8,0
 
 .org 0x3000
 ENTRY(level3_kernel_pgt)
 	.fill	510,8,0
 	/* (2^48-(2*1024*1024*1024)-((2^39)*511))/(2^30) = 510 */
-	.quad	0x0000000000105007		/* -> level2_kernel_pgt */
+	.quad	0x0000000000005007 + __PHYSICAL_START	/* -> level2_kernel_pgt */
 	.fill	1,8,0
 
 .org 0x4000
@@ -337,17 +337,17 @@ ENTRY(empty_bad_pmd_table)
 
 .org 0xa000
 ENTRY(level3_physmem_pgt)
-	.quad	0x0000000000105007		/* -> level2_kernel_pgt (so that __va works even before pagetable_init) */
+	.quad	0x0000000000005007 + __PHYSICAL_START	/* -> level2_kernel_pgt (so that __va works even before pagetable_init) */
 
 	.org 0xb000
 #ifdef CONFIG_ACPI_SLEEP
 ENTRY(wakeup_level4_pgt)
-	.quad	0x0000000000102007		/* -> level3_ident_pgt */
+	.quad	0x0000000000002007 + __PHYSICAL_START	/* -> level3_ident_pgt */
 	.fill	255,8,0
-	.quad	0x000000000010a007
+	.quad	0x000000000000a007 + __PHYSICAL_START
 	.fill	254,8,0
 	/* (2^48-(2*1024*1024*1024))/(2^39) = 511 */
-	.quad	0x0000000000103007		/* -> level3_kernel_pgt */
+	.quad	0x0000000000003007 + __PHYSICAL_START	/* -> level3_kernel_pgt */
 #endif
 
 	.data
diff --git a/arch/x86_64/kernel/head64.c b/arch/x86_64/kernel/head64.c
--- a/arch/x86_64/kernel/head64.c
+++ b/arch/x86_64/kernel/head64.c
@@ -94,7 +94,7 @@ void __init x86_64_start_kernel(char * r
 	s = strstr(saved_command_line, "earlyprintk=");
 	if (s != NULL)
 		setup_early_printk(s);
-#ifdef CONFIG_DISCONTIGMEM
+#ifdef CONFIG_NUMA
 	s = strstr(saved_command_line, "numa=");
 	if (s != NULL)
 		numa_setup(s+5);
diff --git a/arch/x86_64/kernel/i387.c b/arch/x86_64/kernel/i387.c
--- a/arch/x86_64/kernel/i387.c
+++ b/arch/x86_64/kernel/i387.c
@@ -42,7 +42,7 @@ void mxcsr_feature_mask_init(void)
  * Called at bootup to set up the initial FPU state that is later cloned
  * into all processes.
  */
-void __init fpu_init(void)
+void __cpuinit fpu_init(void)
 {
 	unsigned long oldcr0 = read_cr0();
 	extern void __bad_fxsave_alignment(void);
diff --git a/arch/x86_64/kernel/i8259.c b/arch/x86_64/kernel/i8259.c
--- a/arch/x86_64/kernel/i8259.c
+++ b/arch/x86_64/kernel/i8259.c
@@ -157,14 +157,13 @@ static unsigned int startup_8259A_irq(un
 }
 
 static struct hw_interrupt_type i8259A_irq_type = {
-	"XT-PIC",
-	startup_8259A_irq,
-	shutdown_8259A_irq,
-	enable_8259A_irq,
-	disable_8259A_irq,
-	mask_and_ack_8259A,
-	end_8259A_irq,
-	NULL
+	.typename = "XT-PIC",
+	.startup = startup_8259A_irq,
+	.shutdown = shutdown_8259A_irq,
+	.enable = enable_8259A_irq,
+	.disable = disable_8259A_irq,
+	.ack = mask_and_ack_8259A,
+	.end = end_8259A_irq,
 };
 
 /*
@@ -415,10 +414,22 @@ static int i8259A_suspend(struct sys_dev
 	return 0;
 }
 
+static int i8259A_shutdown(struct sys_device *dev)
+{
+	/* Put the i8259A into a quiescent state that
+	 * the kernel initialization code can get it
+	 * out of.
+	 */
+	outb(0xff, 0x21);	/* mask all of 8259A-1 */
+	outb(0xff, 0xA1);	/* mask all of 8259A-1 */
+	return 0;
+}
+
 static struct sysdev_class i8259_sysdev_class = {
 	set_kset_name("i8259"),
 	.suspend = i8259A_suspend,
 	.resume = i8259A_resume,
+	.shutdown = i8259A_shutdown,
 };
 
 static struct sys_device device_i8259A = {
diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c
--- a/arch/x86_64/kernel/io_apic.c
+++ b/arch/x86_64/kernel/io_apic.c
@@ -330,7 +330,7 @@ static int find_irq_entry(int apic, int 
 /*
  * Find the pin to which IRQ[irq] (ISA) is connected
  */
-static int __init find_isa_irq_pin(int irq, int type)
+static int find_isa_irq_pin(int irq, int type)
 {
 	int i;
 
@@ -1064,7 +1064,6 @@ void print_all_local_APICs (void)
 
 void __apicdebuginit print_PIC(void)
 {
-	extern spinlock_t i8259A_lock;
 	unsigned int v;
 	unsigned long flags;
 
@@ -1132,12 +1131,44 @@ static void __init enable_IO_APIC(void)
  */
 void disable_IO_APIC(void)
 {
+	int pin;
 	/*
 	 * Clear the IO-APIC before rebooting:
 	 */
 	clear_IO_APIC();
 
-	disconnect_bsp_APIC();
+	/*
+	 * If the i82559 is routed through an IOAPIC
+	 * Put that IOAPIC in virtual wire mode
+	 * so legacy interrups can be delivered.
+	 */
+	pin = find_isa_irq_pin(0, mp_ExtINT);
+	if (pin != -1) {
+		struct IO_APIC_route_entry entry;
+		unsigned long flags;
+
+		memset(&entry, 0, sizeof(entry));
+		entry.mask            = 0; /* Enabled */
+		entry.trigger         = 0; /* Edge */
+		entry.irr             = 0;
+		entry.polarity        = 0; /* High */
+		entry.delivery_status = 0;
+		entry.dest_mode       = 0; /* Physical */
+		entry.delivery_mode   = 7; /* ExtInt */
+		entry.vector          = 0;
+		entry.dest.physical.physical_dest = 0;
+
+
+		/*
+		 * Add it to the IO-APIC irq-routing table:
+		 */
+		spin_lock_irqsave(&ioapic_lock, flags);
+		io_apic_write(0, 0x11+2*pin, *(((int *)&entry)+1));
+		io_apic_write(0, 0x10+2*pin, *(((int *)&entry)+0));
+		spin_unlock_irqrestore(&ioapic_lock, flags);
+	}
+
+	disconnect_bsp_APIC(pin != -1);
 }
 
 /*
diff --git a/arch/x86_64/kernel/irq.c b/arch/x86_64/kernel/irq.c
--- a/arch/x86_64/kernel/irq.c
+++ b/arch/x86_64/kernel/irq.c
@@ -14,6 +14,7 @@
 #include <linux/interrupt.h>
 #include <linux/seq_file.h>
 #include <linux/module.h>
+#include <linux/delay.h>
 #include <asm/uaccess.h>
 #include <asm/io_apic.h>
 
@@ -106,3 +107,50 @@ asmlinkage unsigned int do_IRQ(struct pt
 	return 1;
 }
 
+#ifdef CONFIG_HOTPLUG_CPU
+void fixup_irqs(cpumask_t map)
+{
+	unsigned int irq;
+	static int warned;
+
+	for (irq = 0; irq < NR_IRQS; irq++) {
+		cpumask_t mask;
+		if (irq == 2)
+			continue;
+
+		cpus_and(mask, irq_affinity[irq], map);
+		if (any_online_cpu(mask) == NR_CPUS) {
+			printk("Breaking affinity for irq %i\n", irq);
+			mask = map;
+		}
+		if (irq_desc[irq].handler->set_affinity)
+			irq_desc[irq].handler->set_affinity(irq, mask);
+		else if (irq_desc[irq].action && !(warned++))
+			printk("Cannot set affinity for irq %i\n", irq);
+	}
+
+	/* That doesn't seem sufficient.  Give it 1ms. */
+	local_irq_enable();
+	mdelay(1);
+	local_irq_disable();
+}
+#endif
+
+extern void call_softirq(void);
+
+asmlinkage void do_softirq(void)
+{
+ 	__u32 pending;
+ 	unsigned long flags;
+
+ 	if (in_interrupt())
+ 		return;
+
+ 	local_irq_save(flags);
+ 	pending = local_softirq_pending();
+ 	/* Switch to interrupt stack */
+ 	if (pending)
+		call_softirq();
+ 	local_irq_restore(flags);
+}
+EXPORT_SYMBOL(do_softirq);
diff --git a/arch/x86_64/kernel/kprobes.c b/arch/x86_64/kernel/kprobes.c
--- a/arch/x86_64/kernel/kprobes.c
+++ b/arch/x86_64/kernel/kprobes.c
@@ -27,6 +27,8 @@
  *		<prasanna@in.ibm.com> adapted for x86_64
  * 2005-Mar	Roland McGrath <roland@redhat.com>
  *		Fixed to handle %rip-relative addressing mode correctly.
+ * 2005-May     Rusty Lynch <rusty.lynch@intel.com>
+ *              Added function return probes functionality
  */
 
 #include <linux/config.h>
@@ -36,23 +38,19 @@
 #include <linux/string.h>
 #include <linux/slab.h>
 #include <linux/preempt.h>
-#include <linux/moduleloader.h>
 
+#include <asm/cacheflush.h>
 #include <asm/pgtable.h>
 #include <asm/kdebug.h>
 
 static DECLARE_MUTEX(kprobe_mutex);
 
-/* kprobe_status settings */
-#define KPROBE_HIT_ACTIVE	0x00000001
-#define KPROBE_HIT_SS		0x00000002
-
 static struct kprobe *current_kprobe;
 static unsigned long kprobe_status, kprobe_old_rflags, kprobe_saved_rflags;
+static struct kprobe *kprobe_prev;
+static unsigned long kprobe_status_prev, kprobe_old_rflags_prev, kprobe_saved_rflags_prev;
 static struct pt_regs jprobe_saved_regs;
 static long *jprobe_saved_rsp;
-static kprobe_opcode_t *get_insn_slot(void);
-static void free_insn_slot(kprobe_opcode_t *slot);
 void jprobe_return_end(void);
 
 /* copy of the kernel stack at the probe fire time */
@@ -214,6 +212,21 @@ void arch_copy_kprobe(struct kprobe *p)
 		BUG_ON((s64) (s32) disp != disp); /* Sanity check.  */
 		*ripdisp = disp;
 	}
+	p->opcode = *p->addr;
+}
+
+void arch_arm_kprobe(struct kprobe *p)
+{
+	*p->addr = BREAKPOINT_INSTRUCTION;
+	flush_icache_range((unsigned long) p->addr,
+			   (unsigned long) p->addr + sizeof(kprobe_opcode_t));
+}
+
+void arch_disarm_kprobe(struct kprobe *p)
+{
+	*p->addr = p->opcode;
+	flush_icache_range((unsigned long) p->addr,
+			   (unsigned long) p->addr + sizeof(kprobe_opcode_t));
 }
 
 void arch_remove_kprobe(struct kprobe *p)
@@ -223,10 +236,29 @@ void arch_remove_kprobe(struct kprobe *p
 	down(&kprobe_mutex);
 }
 
-static inline void disarm_kprobe(struct kprobe *p, struct pt_regs *regs)
+static inline void save_previous_kprobe(void)
 {
-	*p->addr = p->opcode;
-	regs->rip = (unsigned long)p->addr;
+	kprobe_prev = current_kprobe;
+	kprobe_status_prev = kprobe_status;
+	kprobe_old_rflags_prev = kprobe_old_rflags;
+	kprobe_saved_rflags_prev = kprobe_saved_rflags;
+}
+
+static inline void restore_previous_kprobe(void)
+{
+	current_kprobe = kprobe_prev;
+	kprobe_status = kprobe_status_prev;
+	kprobe_old_rflags = kprobe_old_rflags_prev;
+	kprobe_saved_rflags = kprobe_saved_rflags_prev;
+}
+
+static inline void set_current_kprobe(struct kprobe *p, struct pt_regs *regs)
+{
+	current_kprobe = p;
+	kprobe_saved_rflags = kprobe_old_rflags
+		= (regs->eflags & (TF_MASK | IF_MASK));
+	if (is_IF_modifier(p->ainsn.insn))
+		kprobe_saved_rflags &= ~IF_MASK;
 }
 
 static void prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
@@ -240,6 +272,25 @@ static void prepare_singlestep(struct kp
 		regs->rip = (unsigned long)p->ainsn.insn;
 }
 
+void arch_prepare_kretprobe(struct kretprobe *rp, struct pt_regs *regs)
+{
+	unsigned long *sara = (unsigned long *)regs->rsp;
+        struct kretprobe_instance *ri;
+
+        if ((ri = get_free_rp_inst(rp)) != NULL) {
+                ri->rp = rp;
+                ri->task = current;
+		ri->ret_addr = (kprobe_opcode_t *) *sara;
+
+		/* Replace the return addr with trampoline addr */
+		*sara = (unsigned long) &kretprobe_trampoline;
+
+                add_rp_inst(ri);
+        } else {
+                rp->nmissed++;
+        }
+}
+
 /*
  * Interrupts are disabled on entry as trap3 is an interrupt gate and they
  * remain disabled thorough out this function.
@@ -264,9 +315,30 @@ int kprobe_handler(struct pt_regs *regs)
 				regs->eflags |= kprobe_saved_rflags;
 				unlock_kprobes();
 				goto no_kprobe;
+			} else if (kprobe_status == KPROBE_HIT_SSDONE) {
+				/* TODO: Provide re-entrancy from
+				 * post_kprobes_handler() and avoid exception
+				 * stack corruption while single-stepping on
+				 * the instruction of the new probe.
+				 */
+				arch_disarm_kprobe(p);
+				regs->rip = (unsigned long)p->addr;
+				ret = 1;
+			} else {
+				/* We have reentered the kprobe_handler(), since
+				 * another probe was hit while within the
+				 * handler. We here save the original kprobe
+				 * variables and just single step on instruction
+				 * of the new probe without calling any user
+				 * handlers.
+				 */
+				save_previous_kprobe();
+				set_current_kprobe(p, regs);
+				p->nmissed++;
+				prepare_singlestep(p, regs);
+				kprobe_status = KPROBE_REENTER;
+				return 1;
 			}
-			disarm_kprobe(p, regs);
-			ret = 1;
 		} else {
 			p = current_kprobe;
 			if (p->break_handler && p->break_handler(p, regs)) {
@@ -296,11 +368,7 @@ int kprobe_handler(struct pt_regs *regs)
 	}
 
 	kprobe_status = KPROBE_HIT_ACTIVE;
-	current_kprobe = p;
-	kprobe_saved_rflags = kprobe_old_rflags
-	    = (regs->eflags & (TF_MASK | IF_MASK));
-	if (is_IF_modifier(p->ainsn.insn))
-		kprobe_saved_rflags &= ~IF_MASK;
+	set_current_kprobe(p, regs);
 
 	if (p->pre_handler && p->pre_handler(p, regs))
 		/* handler has already set things up, so skip ss setup */
@@ -317,6 +385,78 @@ no_kprobe:
 }
 
 /*
+ * For function-return probes, init_kprobes() establishes a probepoint
+ * here. When a retprobed function returns, this probe is hit and
+ * trampoline_probe_handler() runs, calling the kretprobe's handler.
+ */
+ void kretprobe_trampoline_holder(void)
+ {
+ 	asm volatile (  ".global kretprobe_trampoline\n"
+ 			"kretprobe_trampoline: \n"
+ 			"nop\n");
+ }
+
+/*
+ * Called when we hit the probe point at kretprobe_trampoline
+ */
+int trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
+{
+        struct kretprobe_instance *ri = NULL;
+        struct hlist_head *head;
+        struct hlist_node *node, *tmp;
+	unsigned long orig_ret_address = 0;
+	unsigned long trampoline_address =(unsigned long)&kretprobe_trampoline;
+
+        head = kretprobe_inst_table_head(current);
+
+	/*
+	 * It is possible to have multiple instances associated with a given
+	 * task either because an multiple functions in the call path
+	 * have a return probe installed on them, and/or more then one return
+	 * return probe was registered for a target function.
+	 *
+	 * We can handle this because:
+	 *     - instances are always inserted at the head of the list
+	 *     - when multiple return probes are registered for the same
+         *       function, the first instance's ret_addr will point to the
+	 *       real return address, and all the rest will point to
+	 *       kretprobe_trampoline
+	 */
+	hlist_for_each_entry_safe(ri, node, tmp, head, hlist) {
+                if (ri->task != current)
+			/* another task is sharing our hash bucket */
+                        continue;
+
+		if (ri->rp && ri->rp->handler)
+			ri->rp->handler(ri, regs);
+
+		orig_ret_address = (unsigned long)ri->ret_addr;
+		recycle_rp_inst(ri);
+
+		if (orig_ret_address != trampoline_address)
+			/*
+			 * This is the real return address. Any other
+			 * instances associated with this task are for
+			 * other calls deeper on the call stack
+			 */
+			break;
+	}
+
+	BUG_ON(!orig_ret_address || (orig_ret_address == trampoline_address));
+	regs->rip = orig_ret_address;
+
+	unlock_kprobes();
+	preempt_enable_no_resched();
+
+        /*
+         * By returning a non-zero value, we are telling
+         * kprobe_handler() that we have handled unlocking
+         * and re-enabling preemption.
+         */
+        return 1;
+}
+
+/*
  * Called after single-stepping.  p->addr is the address of the
  * instruction whose first byte has been replaced by the "int 3"
  * instruction.  To avoid the SMP problems that can occur when we
@@ -401,13 +541,22 @@ int post_kprobe_handler(struct pt_regs *
 	if (!kprobe_running())
 		return 0;
 
-	if (current_kprobe->post_handler)
+	if ((kprobe_status != KPROBE_REENTER) && current_kprobe->post_handler) {
+		kprobe_status = KPROBE_HIT_SSDONE;
 		current_kprobe->post_handler(current_kprobe, regs, 0);
+	}
 
 	resume_execution(current_kprobe, regs);
 	regs->eflags |= kprobe_saved_rflags;
 
-	unlock_kprobes();
+	/* Restore the original saved kprobes variables and continue. */
+	if (kprobe_status == KPROBE_REENTER) {
+		restore_previous_kprobe();
+		goto out;
+	} else {
+		unlock_kprobes();
+	}
+out:
 	preempt_enable_no_resched();
 
 	/*
@@ -528,111 +677,12 @@ int longjmp_break_handler(struct kprobe 
 	return 0;
 }
 
-/*
- * kprobe->ainsn.insn points to the copy of the instruction to be single-stepped.
- * By default on x86_64, pages we get from kmalloc or vmalloc are not
- * executable.  Single-stepping an instruction on such a page yields an
- * oops.  So instead of storing the instruction copies in their respective
- * kprobe objects, we allocate a page, map it executable, and store all the
- * instruction copies there.  (We can allocate additional pages if somebody
- * inserts a huge number of probes.)  Each page can hold up to INSNS_PER_PAGE
- * instruction slots, each of which is MAX_INSN_SIZE*sizeof(kprobe_opcode_t)
- * bytes.
- */
-#define INSNS_PER_PAGE (PAGE_SIZE/(MAX_INSN_SIZE*sizeof(kprobe_opcode_t)))
-struct kprobe_insn_page {
-	struct hlist_node hlist;
-	kprobe_opcode_t *insns;		/* page of instruction slots */
-	char slot_used[INSNS_PER_PAGE];
-	int nused;
+static struct kprobe trampoline_p = {
+	.addr = (kprobe_opcode_t *) &kretprobe_trampoline,
+	.pre_handler = trampoline_probe_handler
 };
 
-static struct hlist_head kprobe_insn_pages;
-
-/**
- * get_insn_slot() - Find a slot on an executable page for an instruction.
- * We allocate an executable page if there's no room on existing ones.
- */
-static kprobe_opcode_t *get_insn_slot(void)
-{
-	struct kprobe_insn_page *kip;
-	struct hlist_node *pos;
-
-	hlist_for_each(pos, &kprobe_insn_pages) {
-		kip = hlist_entry(pos, struct kprobe_insn_page, hlist);
-		if (kip->nused < INSNS_PER_PAGE) {
-			int i;
-			for (i = 0; i < INSNS_PER_PAGE; i++) {
-				if (!kip->slot_used[i]) {
-					kip->slot_used[i] = 1;
-					kip->nused++;
-					return kip->insns + (i*MAX_INSN_SIZE);
-				}
-			}
-			/* Surprise!  No unused slots.  Fix kip->nused. */
-			kip->nused = INSNS_PER_PAGE;
-		}
-	}
-
-	/* All out of space.  Need to allocate a new page. Use slot 0.*/
-	kip = kmalloc(sizeof(struct kprobe_insn_page), GFP_KERNEL);
-	if (!kip) {
-		return NULL;
-	}
-
-	/*
-	 * For the %rip-relative displacement fixups to be doable, we
-	 * need our instruction copy to be within +/- 2GB of any data it
-	 * might access via %rip.  That is, within 2GB of where the
-	 * kernel image and loaded module images reside.  So we allocate
-	 * a page in the module loading area.
-	 */
-	kip->insns = module_alloc(PAGE_SIZE);
-	if (!kip->insns) {
-		kfree(kip);
-		return NULL;
-	}
-	INIT_HLIST_NODE(&kip->hlist);
-	hlist_add_head(&kip->hlist, &kprobe_insn_pages);
-	memset(kip->slot_used, 0, INSNS_PER_PAGE);
-	kip->slot_used[0] = 1;
-	kip->nused = 1;
-	return kip->insns;
-}
-
-/**
- * free_insn_slot() - Free instruction slot obtained from get_insn_slot().
- */
-static void free_insn_slot(kprobe_opcode_t *slot)
+int __init arch_init_kprobes(void)
 {
-	struct kprobe_insn_page *kip;
-	struct hlist_node *pos;
-
-	hlist_for_each(pos, &kprobe_insn_pages) {
-		kip = hlist_entry(pos, struct kprobe_insn_page, hlist);
-		if (kip->insns <= slot
-		    && slot < kip->insns+(INSNS_PER_PAGE*MAX_INSN_SIZE)) {
-			int i = (slot - kip->insns) / MAX_INSN_SIZE;
-			kip->slot_used[i] = 0;
-			kip->nused--;
-			if (kip->nused == 0) {
-				/*
-				 * Page is no longer in use.  Free it unless
-				 * it's the last one.  We keep the last one
-				 * so as not to have to set it up again the
-				 * next time somebody inserts a probe.
-				 */
-				hlist_del(&kip->hlist);
-				if (hlist_empty(&kprobe_insn_pages)) {
-					INIT_HLIST_NODE(&kip->hlist);
-					hlist_add_head(&kip->hlist,
-						&kprobe_insn_pages);
-				} else {
-					module_free(NULL, kip->insns);
-					kfree(kip);
-				}
-			}
-			return;
-		}
-	}
+	return register_kprobe(&trampoline_p);
 }
diff --git a/arch/x86_64/kernel/machine_kexec.c b/arch/x86_64/kernel/machine_kexec.c
new file mode 100644
--- /dev/null
+++ b/arch/x86_64/kernel/machine_kexec.c
@@ -0,0 +1,231 @@
+/*
+ * machine_kexec.c - handle transition of Linux booting another kernel
+ * Copyright (C) 2002-2005 Eric Biederman  <ebiederm@xmission.com>
+ *
+ * This source code is licensed under the GNU General Public License,
+ * Version 2.  See the file COPYING for more details.
+ */
+
+#include <linux/mm.h>
+#include <linux/kexec.h>
+#include <linux/string.h>
+#include <linux/reboot.h>
+#include <asm/pgtable.h>
+#include <asm/tlbflush.h>
+#include <asm/mmu_context.h>
+#include <asm/io.h>
+
+static void init_level2_page(pmd_t *level2p, unsigned long addr)
+{
+	unsigned long end_addr;
+
+	addr &= PAGE_MASK;
+	end_addr = addr + PUD_SIZE;
+	while (addr < end_addr) {
+		set_pmd(level2p++, __pmd(addr | __PAGE_KERNEL_LARGE_EXEC));
+		addr += PMD_SIZE;
+	}
+}
+
+static int init_level3_page(struct kimage *image, pud_t *level3p,
+				unsigned long addr, unsigned long last_addr)
+{
+	unsigned long end_addr;
+	int result;
+
+	result = 0;
+	addr &= PAGE_MASK;
+	end_addr = addr + PGDIR_SIZE;
+	while ((addr < last_addr) && (addr < end_addr)) {
+		struct page *page;
+		pmd_t *level2p;
+
+		page = kimage_alloc_control_pages(image, 0);
+		if (!page) {
+			result = -ENOMEM;
+			goto out;
+		}
+		level2p = (pmd_t *)page_address(page);
+		init_level2_page(level2p, addr);
+		set_pud(level3p++, __pud(__pa(level2p) | _KERNPG_TABLE));
+		addr += PUD_SIZE;
+	}
+	/* clear the unused entries */
+	while (addr < end_addr) {
+		pud_clear(level3p++);
+		addr += PUD_SIZE;
+	}
+out:
+	return result;
+}
+
+
+static int init_level4_page(struct kimage *image, pgd_t *level4p,
+				unsigned long addr, unsigned long last_addr)
+{
+	unsigned long end_addr;
+	int result;
+
+	result = 0;
+	addr &= PAGE_MASK;
+	end_addr = addr + (PTRS_PER_PGD * PGDIR_SIZE);
+	while ((addr < last_addr) && (addr < end_addr)) {
+		struct page *page;
+		pud_t *level3p;
+
+		page = kimage_alloc_control_pages(image, 0);
+		if (!page) {
+			result = -ENOMEM;
+			goto out;
+		}
+		level3p = (pud_t *)page_address(page);
+		result = init_level3_page(image, level3p, addr, last_addr);
+		if (result) {
+			goto out;
+		}
+		set_pgd(level4p++, __pgd(__pa(level3p) | _KERNPG_TABLE));
+		addr += PGDIR_SIZE;
+	}
+	/* clear the unused entries */
+	while (addr < end_addr) {
+		pgd_clear(level4p++);
+		addr += PGDIR_SIZE;
+	}
+out:
+	return result;
+}
+
+
+static int init_pgtable(struct kimage *image, unsigned long start_pgtable)
+{
+	pgd_t *level4p;
+	level4p = (pgd_t *)__va(start_pgtable);
+ 	return init_level4_page(image, level4p, 0, end_pfn << PAGE_SHIFT);
+}
+
+static void set_idt(void *newidt, u16 limit)
+{
+	struct desc_ptr curidt;
+
+	/* x86-64 supports unaliged loads & stores */
+	curidt.size    = limit;
+	curidt.address = (unsigned long)newidt;
+
+	__asm__ __volatile__ (
+		"lidtq %0\n"
+		: : "m" (curidt)
+		);
+};
+
+
+static void set_gdt(void *newgdt, u16 limit)
+{
+	struct desc_ptr curgdt;
+
+	/* x86-64 supports unaligned loads & stores */
+	curgdt.size    = limit;
+	curgdt.address = (unsigned long)newgdt;
+
+	__asm__ __volatile__ (
+		"lgdtq %0\n"
+		: : "m" (curgdt)
+		);
+};
+
+static void load_segments(void)
+{
+	__asm__ __volatile__ (
+		"\tmovl %0,%%ds\n"
+		"\tmovl %0,%%es\n"
+		"\tmovl %0,%%ss\n"
+		"\tmovl %0,%%fs\n"
+		"\tmovl %0,%%gs\n"
+		: : "a" (__KERNEL_DS)
+		);
+}
+
+typedef NORET_TYPE void (*relocate_new_kernel_t)(unsigned long indirection_page,
+					unsigned long control_code_buffer,
+					unsigned long start_address,
+					unsigned long pgtable) ATTRIB_NORET;
+
+const extern unsigned char relocate_new_kernel[];
+const extern unsigned long relocate_new_kernel_size;
+
+int machine_kexec_prepare(struct kimage *image)
+{
+	unsigned long start_pgtable, control_code_buffer;
+	int result;
+
+	/* Calculate the offsets */
+	start_pgtable = page_to_pfn(image->control_code_page) << PAGE_SHIFT;
+	control_code_buffer = start_pgtable + PAGE_SIZE;
+
+	/* Setup the identity mapped 64bit page table */
+	result = init_pgtable(image, start_pgtable);
+	if (result)
+		return result;
+
+	/* Place the code in the reboot code buffer */
+	memcpy(__va(control_code_buffer), relocate_new_kernel,
+						relocate_new_kernel_size);
+
+	return 0;
+}
+
+void machine_kexec_cleanup(struct kimage *image)
+{
+	return;
+}
+
+/*
+ * Do not allocate memory (or fail in any way) in machine_kexec().
+ * We are past the point of no return, committed to rebooting now.
+ */
+NORET_TYPE void machine_kexec(struct kimage *image)
+{
+	unsigned long page_list;
+	unsigned long control_code_buffer;
+	unsigned long start_pgtable;
+	relocate_new_kernel_t rnk;
+
+	/* Interrupts aren't acceptable while we reboot */
+	local_irq_disable();
+
+	/* Calculate the offsets */
+	page_list = image->head;
+	start_pgtable = page_to_pfn(image->control_code_page) << PAGE_SHIFT;
+	control_code_buffer = start_pgtable + PAGE_SIZE;
+
+	/* Set the low half of the page table to my identity mapped
+	 * page table for kexec.  Leave the high half pointing at the
+	 * kernel pages.   Don't bother to flush the global pages
+	 * as that will happen when I fully switch to my identity mapped
+	 * page table anyway.
+	 */
+	memcpy(__va(read_cr3()), __va(start_pgtable), PAGE_SIZE/2);
+	__flush_tlb();
+
+
+	/* The segment registers are funny things, they are
+	 * automatically loaded from a table, in memory wherever you
+	 * set them to a specific selector, but this table is never
+	 * accessed again unless you set the segment to a different selector.
+	 *
+	 * The more common model are caches where the behide
+	 * the scenes work is done, but is also dropped at arbitrary
+	 * times.
+	 *
+	 * I take advantage of this here by force loading the
+	 * segments, before I zap the gdt with an invalid value.
+	 */
+	load_segments();
+	/* The gdt & idt are now invalid.
+	 * If you want to load them you must set up your own idt & gdt.
+	 */
+	set_gdt(phys_to_virt(0),0);
+	set_idt(phys_to_virt(0),0);
+	/* now call it */
+	rnk = (relocate_new_kernel_t) control_code_buffer;
+	(*rnk)(page_list, control_code_buffer, image->start, start_pgtable);
+}
diff --git a/arch/x86_64/kernel/mce.c b/arch/x86_64/kernel/mce.c
--- a/arch/x86_64/kernel/mce.c
+++ b/arch/x86_64/kernel/mce.c
@@ -15,6 +15,8 @@
 #include <linux/sysdev.h>
 #include <linux/miscdevice.h>
 #include <linux/fs.h>
+#include <linux/cpu.h>
+#include <linux/percpu.h>
 #include <asm/processor.h> 
 #include <asm/msr.h>
 #include <asm/mce.h>
@@ -34,6 +36,7 @@ static unsigned long bank[NR_BANKS] = { 
 static unsigned long console_logged;
 static int notify_user;
 static int rip_msr;
+static int mce_bootlog;
 
 /*
  * Lockless MCE logging infrastructure.
@@ -195,10 +198,11 @@ void do_machine_check(struct pt_regs * r
 			rdmsrl(MSR_IA32_MC0_ADDR + i*4, m.addr);
 
 		mce_get_rip(&m, regs);
-		if (error_code != -1)
+		if (error_code >= 0)
 			rdtscll(m.tsc);
 		wrmsrl(MSR_IA32_MC0_STATUS + i*4, 0);
-		mce_log(&m);
+		if (error_code != -2)
+			mce_log(&m);
 
 		/* Did this bank cause the exception? */
 		/* Assume that the bank with uncorrectable errors did it,
@@ -313,7 +317,7 @@ static void mce_init(void *dummy)
 
 	/* Log the machine checks left over from the previous reset.
 	   This also clears all registers */
-	do_machine_check(NULL, -1);
+	do_machine_check(NULL, mce_bootlog ? -1 : -2);
 
 	set_in_cr4(X86_CR4_MCE);
 
@@ -327,7 +331,7 @@ static void mce_init(void *dummy)
 }
 
 /* Add per CPU specific workarounds here */
-static void __init mce_cpu_quirks(struct cpuinfo_x86 *c) 
+static void __cpuinit mce_cpu_quirks(struct cpuinfo_x86 *c)
 { 
 	/* This should be disabled by the BIOS, but isn't always */
 	if (c->x86_vendor == X86_VENDOR_AMD && c->x86 == 15) {
@@ -337,7 +341,7 @@ static void __init mce_cpu_quirks(struct
 	}
 }			
 
-static void __init mce_cpu_features(struct cpuinfo_x86 *c)
+static void __cpuinit mce_cpu_features(struct cpuinfo_x86 *c)
 {
 	switch (c->x86_vendor) {
 	case X86_VENDOR_INTEL:
@@ -352,7 +356,7 @@ static void __init mce_cpu_features(stru
  * Called for each booted CPU to set up machine checks.
  * Must be called with preempt off. 
  */
-void __init mcheck_init(struct cpuinfo_x86 *c)
+void __cpuinit mcheck_init(struct cpuinfo_x86 *c)
 {
 	static cpumask_t mce_cpus __initdata = CPU_MASK_NONE;
 
@@ -411,7 +415,7 @@ static ssize_t mce_read(struct file *fil
 	memset(mcelog.entry, 0, next * sizeof(struct mce));
 	mcelog.next = 0;
 
-	synchronize_kernel();	
+	synchronize_sched();
 
 	/* Collect entries that were still getting written before the synchronize. */
 
@@ -474,11 +478,17 @@ static int __init mcheck_disable(char *s
 }
 
 /* mce=off disables machine check. Note you can reenable it later
-   using sysfs */
+   using sysfs.
+   mce=bootlog Log MCEs from before booting. Disabled by default to work
+   around buggy BIOS that leave bogus MCEs.  */
 static int __init mcheck_enable(char *str)
 {
+	if (*str == '=')
+		str++;
 	if (!strcmp(str, "off"))
 		mce_dont_init = 1;
+	else if (!strcmp(str, "bootlog"))
+		mce_bootlog = 1;
 	else
 		printk("mce= argument %s ignored. Please use /sys", str); 
 	return 0;
@@ -514,10 +524,7 @@ static struct sysdev_class mce_sysclass 
 	set_kset_name("machinecheck"),
 };
 
-static struct sys_device device_mce = {
-	.id	= 0,
-	.cls	= &mce_sysclass,
-};
+static DEFINE_PER_CPU(struct sys_device, device_mce);
 
 /* Why are there no generic functions for this? */
 #define ACCESSOR(name, var, start) \
@@ -542,27 +549,83 @@ ACCESSOR(bank4ctl,bank[4],mce_restart())
 ACCESSOR(tolerant,tolerant,)
 ACCESSOR(check_interval,check_interval,mce_restart())
 
+/* Per cpu sysdev init.  All of the cpus still share the same ctl bank */
+static __cpuinit int mce_create_device(unsigned int cpu)
+{
+	int err;
+	if (!mce_available(&cpu_data[cpu]))
+		return -EIO;
+
+	per_cpu(device_mce,cpu).id = cpu;
+	per_cpu(device_mce,cpu).cls = &mce_sysclass;
+
+	err = sysdev_register(&per_cpu(device_mce,cpu));
+
+	if (!err) {
+		sysdev_create_file(&per_cpu(device_mce,cpu), &attr_bank0ctl);
+		sysdev_create_file(&per_cpu(device_mce,cpu), &attr_bank1ctl);
+		sysdev_create_file(&per_cpu(device_mce,cpu), &attr_bank2ctl);
+		sysdev_create_file(&per_cpu(device_mce,cpu), &attr_bank3ctl);
+		sysdev_create_file(&per_cpu(device_mce,cpu), &attr_bank4ctl);
+		sysdev_create_file(&per_cpu(device_mce,cpu), &attr_tolerant);
+		sysdev_create_file(&per_cpu(device_mce,cpu), &attr_check_interval);
+	}
+	return err;
+}
+
+#ifdef CONFIG_HOTPLUG_CPU
+static __cpuinit void mce_remove_device(unsigned int cpu)
+{
+	sysdev_remove_file(&per_cpu(device_mce,cpu), &attr_bank0ctl);
+	sysdev_remove_file(&per_cpu(device_mce,cpu), &attr_bank1ctl);
+	sysdev_remove_file(&per_cpu(device_mce,cpu), &attr_bank2ctl);
+	sysdev_remove_file(&per_cpu(device_mce,cpu), &attr_bank3ctl);
+	sysdev_remove_file(&per_cpu(device_mce,cpu), &attr_bank4ctl);
+	sysdev_remove_file(&per_cpu(device_mce,cpu), &attr_tolerant);
+	sysdev_remove_file(&per_cpu(device_mce,cpu), &attr_check_interval);
+	sysdev_unregister(&per_cpu(device_mce,cpu));
+}
+#endif
+
+/* Get notified when a cpu comes on/off. Be hotplug friendly. */
+static __cpuinit int
+mce_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu)
+{
+	unsigned int cpu = (unsigned long)hcpu;
+
+	switch (action) {
+	case CPU_ONLINE:
+		mce_create_device(cpu);
+		break;
+#ifdef CONFIG_HOTPLUG_CPU
+	case CPU_DEAD:
+		mce_remove_device(cpu);
+		break;
+#endif
+	}
+	return NOTIFY_OK;
+}
+
+static struct notifier_block mce_cpu_notifier = {
+	.notifier_call = mce_cpu_callback,
+};
+
 static __init int mce_init_device(void)
 {
 	int err;
+	int i = 0;
+
 	if (!mce_available(&boot_cpu_data))
 		return -EIO;
 	err = sysdev_class_register(&mce_sysclass);
-	if (!err)
-		err = sysdev_register(&device_mce);
-	if (!err) { 
-		/* could create per CPU objects, but it is not worth it. */
-		sysdev_create_file(&device_mce, &attr_bank0ctl); 
-		sysdev_create_file(&device_mce, &attr_bank1ctl); 
-		sysdev_create_file(&device_mce, &attr_bank2ctl); 
-		sysdev_create_file(&device_mce, &attr_bank3ctl); 
-		sysdev_create_file(&device_mce, &attr_bank4ctl); 
-		sysdev_create_file(&device_mce, &attr_tolerant); 
-		sysdev_create_file(&device_mce, &attr_check_interval);
-	} 
-	
+
+	for_each_online_cpu(i) {
+		mce_create_device(i);
+	}
+
+	register_cpu_notifier(&mce_cpu_notifier);
 	misc_register(&mce_log_device);
 	return err;
-
 }
+
 device_initcall(mce_init_device);
diff --git a/arch/x86_64/kernel/mce_intel.c b/arch/x86_64/kernel/mce_intel.c
--- a/arch/x86_64/kernel/mce_intel.c
+++ b/arch/x86_64/kernel/mce_intel.c
@@ -42,7 +42,7 @@ done:
 	irq_exit();
 }
 
-static void __init intel_init_thermal(struct cpuinfo_x86 *c)
+static void __cpuinit intel_init_thermal(struct cpuinfo_x86 *c)
 {
 	u32 l, h;
 	int tm2 = 0;
@@ -93,7 +93,7 @@ static void __init intel_init_thermal(st
 	return;
 }
 
-void __init mce_intel_feature_init(struct cpuinfo_x86 *c)
+void __cpuinit mce_intel_feature_init(struct cpuinfo_x86 *c)
 {
 	intel_init_thermal(c);
 }
diff --git a/arch/x86_64/kernel/mpparse.c b/arch/x86_64/kernel/mpparse.c
--- a/arch/x86_64/kernel/mpparse.c
+++ b/arch/x86_64/kernel/mpparse.c
@@ -23,6 +23,7 @@
 #include <linux/kernel_stat.h>
 #include <linux/mc146818rtc.h>
 #include <linux/acpi.h>
+#include <linux/module.h>
 
 #include <asm/smp.h>
 #include <asm/mtrr.h>
@@ -45,7 +46,8 @@ int acpi_found_madt;
 int apic_version [MAX_APICS];
 unsigned char mp_bus_id_to_type [MAX_MP_BUSSES] = { [0 ... MAX_MP_BUSSES-1] = -1 };
 int mp_bus_id_to_pci_bus [MAX_MP_BUSSES] = { [0 ... MAX_MP_BUSSES-1] = -1 };
-cpumask_t pci_bus_to_cpumask [256] = { [0 ... 255] = CPU_MASK_ALL };
+unsigned char pci_bus_to_node [256];
+EXPORT_SYMBOL(pci_bus_to_node);
 
 static int mp_current_pci_id = 0;
 /* I/O APIC entries */
@@ -107,7 +109,7 @@ static int __init mpf_checksum(unsigned 
 
 static void __init MP_processor_info (struct mpc_config_processor *m)
 {
-	int ver;
+	int ver, cpu;
 	static int found_bsp=0;
 
 	if (!(m->mpc_cpuflag & CPU_ENABLED))
@@ -129,7 +131,7 @@ static void __init MP_processor_info (st
 		return;
 	}
 
-	num_processors++;
+	cpu = num_processors++;
 
 	if (m->mpc_apicid > MAX_APICS) {
 		printk(KERN_ERR "Processor #%d INVALID. (Max ID: %d).\n",
@@ -153,13 +155,18 @@ static void __init MP_processor_info (st
  		 * in same order as logical cpu numbers. Hence the first
  		 * entry is BSP, and so on.
  		 */
+		cpu = 0;
+
  		bios_cpu_apicid[0] = m->mpc_apicid;
  		x86_cpu_to_apicid[0] = m->mpc_apicid;
  		found_bsp = 1;
- 	} else {
- 		bios_cpu_apicid[num_processors - found_bsp] = m->mpc_apicid;
- 		x86_cpu_to_apicid[num_processors - found_bsp] = m->mpc_apicid;
- 	}
+ 	} else
+		cpu = num_processors - found_bsp;
+	bios_cpu_apicid[cpu] = m->mpc_apicid;
+	x86_cpu_to_apicid[cpu] = m->mpc_apicid;
+
+	cpu_set(cpu, cpu_possible_map);
+	cpu_set(cpu, cpu_present_map);
 }
 
 static void __init MP_bus_info (struct mpc_config_bus *m)
@@ -904,11 +911,20 @@ void __init mp_config_acpi_legacy_irqs (
 	return;
 }
 
+#define MAX_GSI_NUM	4096
+
 int mp_register_gsi(u32 gsi, int edge_level, int active_high_low)
 {
 	int			ioapic = -1;
 	int			ioapic_pin = 0;
 	int			idx, bit = 0;
+	static int		pci_irq = 16;
+	/*
+	 * Mapping between Global System Interrupts, which
+	 * represent all possible interrupts, to the IRQs
+	 * assigned to actual devices.
+	 */
+	static int		gsi_to_irq[MAX_GSI_NUM];
 
 	if (acpi_irq_model != ACPI_IRQ_MODEL_IOAPIC)
 		return gsi;
@@ -943,11 +959,34 @@ int mp_register_gsi(u32 gsi, int edge_le
 	if ((1<<bit) & mp_ioapic_routing[ioapic].pin_programmed[idx]) {
 		Dprintk(KERN_DEBUG "Pin %d-%d already programmed\n",
 			mp_ioapic_routing[ioapic].apic_id, ioapic_pin);
-		return gsi;
+		return gsi_to_irq[gsi];
 	}
 
 	mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<<bit);
 
+	if (edge_level) {
+		/*
+		 * For PCI devices assign IRQs in order, avoiding gaps
+		 * due to unused I/O APIC pins.
+		 */
+		int irq = gsi;
+		if (gsi < MAX_GSI_NUM) {
+			if (gsi > 15)
+				gsi = pci_irq++;
+#ifdef CONFIG_ACPI_BUS
+			/*
+			 * Don't assign IRQ used by ACPI SCI
+			 */
+			if (gsi == acpi_fadt.sci_int)
+				gsi = pci_irq++;
+#endif
+			gsi_to_irq[irq] = gsi;
+		} else {
+			printk(KERN_ERR "GSI %u is too high\n", gsi);
+			return gsi;
+		}
+	}
+
 	io_apic_set_pci_routing(ioapic, ioapic_pin, gsi,
 		edge_level == ACPI_EDGE_SENSITIVE ? 0 : 1,
 		active_high_low == ACPI_ACTIVE_HIGH ? 0 : 1);
diff --git a/arch/x86_64/kernel/nmi.c b/arch/x86_64/kernel/nmi.c
--- a/arch/x86_64/kernel/nmi.c
+++ b/arch/x86_64/kernel/nmi.c
@@ -98,7 +98,7 @@ static unsigned int nmi_p4_cccr_val;
 	(P4_CCCR_OVF_PMI0|P4_CCCR_THRESHOLD(15)|P4_CCCR_COMPLEMENT|	\
 	 P4_CCCR_COMPARE|P4_CCCR_REQUIRED|P4_CCCR_ESCR_SELECT(4)|P4_CCCR_ENABLE)
 
-static __init inline int nmi_known_cpu(void)
+static __cpuinit inline int nmi_known_cpu(void)
 {
 	switch (boot_cpu_data.x86_vendor) {
 	case X86_VENDOR_AMD:
@@ -110,7 +110,7 @@ static __init inline int nmi_known_cpu(v
 }
 
 /* Run after command line and cpu_init init, but before all other checks */
-void __init nmi_watchdog_default(void)
+void __cpuinit nmi_watchdog_default(void)
 {
 	if (nmi_watchdog != NMI_DEFAULT)
 		return;
diff --git a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c
--- a/arch/x86_64/kernel/process.c
+++ b/arch/x86_64/kernel/process.c
@@ -8,7 +8,8 @@
  * 
  *  X86-64 port
  *	Andi Kleen.
- * 
+ *
+ *	CPU hotplug support - ashok.raj@intel.com
  *  $Id: process.c,v 1.38 2002/01/15 10:08:03 ak Exp $
  */
 
@@ -18,6 +19,7 @@
 
 #include <stdarg.h>
 
+#include <linux/cpu.h>
 #include <linux/errno.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
@@ -34,6 +36,7 @@
 #include <linux/ptrace.h>
 #include <linux/utsname.h>
 #include <linux/random.h>
+#include <linux/kprobes.h>
 
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
@@ -153,6 +156,29 @@ void cpu_idle_wait(void)
 }
 EXPORT_SYMBOL_GPL(cpu_idle_wait);
 
+#ifdef CONFIG_HOTPLUG_CPU
+DECLARE_PER_CPU(int, cpu_state);
+
+#include <asm/nmi.h>
+/* We don't actually take CPU down, just spin without interrupts. */
+static inline void play_dead(void)
+{
+	idle_task_exit();
+	wbinvd();
+	mb();
+	/* Ack it */
+	__get_cpu_var(cpu_state) = CPU_DEAD;
+
+	while (1)
+		safe_halt();
+}
+#else
+static inline void play_dead(void)
+{
+	BUG();
+}
+#endif /* CONFIG_HOTPLUG_CPU */
+
 /*
  * The idle thread. There's no useful work to be
  * done, so just try to conserve power and have a
@@ -173,6 +199,8 @@ void cpu_idle (void)
 			idle = pm_idle;
 			if (!idle)
 				idle = default_idle;
+			if (cpu_is_offline(smp_processor_id()))
+				play_dead();
 			idle();
 		}
 
@@ -203,7 +231,7 @@ static void mwait_idle(void)
 	}
 }
 
-void __init select_idle_routine(const struct cpuinfo_x86 *c)
+void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c)
 {
 	static int printed;
 	if (cpu_has(c, X86_FEATURE_MWAIT)) {
@@ -293,6 +321,14 @@ void exit_thread(void)
 {
 	struct task_struct *me = current;
 	struct thread_struct *t = &me->thread;
+
+	/*
+	 * Remove function-return probe instances associated with this task
+	 * and put them back on the free list. Do not insert an exit probe for
+	 * this function, it will be disabled by kprobe_flush_task if you do.
+	 */
+	kprobe_flush_task(me);
+
 	if (me->thread.io_bitmap_ptr) { 
 		struct tss_struct *tss = &per_cpu(init_tss, get_cpu());
 
@@ -312,6 +348,13 @@ void flush_thread(void)
 	struct task_struct *tsk = current;
 	struct thread_info *t = current_thread_info();
 
+	/*
+	 * Remove function-return probe instances associated with this task
+	 * and put them back on the free list. Do not insert an exit probe for
+	 * this function, it will be disabled by kprobe_flush_task if you do.
+	 */
+	kprobe_flush_task(tsk);
+
 	if (t->flags & _TIF_ABI_PENDING)
 		t->flags ^= (_TIF_ABI_PENDING | _TIF_IA32);
 
@@ -439,6 +482,33 @@ out:
 }
 
 /*
+ * This function selects if the context switch from prev to next
+ * has to tweak the TSC disable bit in the cr4.
+ */
+static inline void disable_tsc(struct task_struct *prev_p,
+			       struct task_struct *next_p)
+{
+	struct thread_info *prev, *next;
+
+	/*
+	 * gcc should eliminate the ->thread_info dereference if
+	 * has_secure_computing returns 0 at compile time (SECCOMP=n).
+	 */
+	prev = prev_p->thread_info;
+	next = next_p->thread_info;
+
+	if (has_secure_computing(prev) || has_secure_computing(next)) {
+		/* slow path here */
+		if (has_secure_computing(prev) &&
+		    !has_secure_computing(next)) {
+			write_cr4(read_cr4() & ~X86_CR4_TSD);
+		} else if (!has_secure_computing(prev) &&
+			   has_secure_computing(next))
+			write_cr4(read_cr4() | X86_CR4_TSD);
+	}
+}
+
+/*
  * This special macro can be used to load a debugging register
  */
 #define loaddebug(thread,r) set_debug(thread->debugreg ## r, r)
@@ -556,6 +626,8 @@ struct task_struct *__switch_to(struct t
 		}
 	}
 
+	disable_tsc(prev_p, next_p);
+
 	return prev_p;
 }
 
@@ -656,7 +728,7 @@ long do_arch_prctl(struct task_struct *t
 
 	switch (code) { 
 	case ARCH_SET_GS:
-		if (addr >= TASK_SIZE) 
+		if (addr >= TASK_SIZE_OF(task))
 			return -EPERM; 
 		cpu = get_cpu();
 		/* handle small bases via the GDT because that's faster to 
@@ -682,7 +754,7 @@ long do_arch_prctl(struct task_struct *t
 	case ARCH_SET_FS:
 		/* Not strictly needed for fs, but do it for symmetry
 		   with gs */
-		if (addr >= TASK_SIZE)
+		if (addr >= TASK_SIZE_OF(task))
 			return -EPERM; 
 		cpu = get_cpu();
 		/* handle small bases via the GDT because that's faster to 
diff --git a/arch/x86_64/kernel/ptrace.c b/arch/x86_64/kernel/ptrace.c
--- a/arch/x86_64/kernel/ptrace.c
+++ b/arch/x86_64/kernel/ptrace.c
@@ -257,12 +257,12 @@ static int putreg(struct task_struct *ch
 			value &= 0xffff;
 			return 0;
 		case offsetof(struct user_regs_struct,fs_base):
-			if (value >= TASK_SIZE)
+			if (value >= TASK_SIZE_OF(child))
 				return -EIO;
 			child->thread.fs = value;
 			return 0;
 		case offsetof(struct user_regs_struct,gs_base):
-			if (value >= TASK_SIZE)
+			if (value >= TASK_SIZE_OF(child))
 				return -EIO;
 			child->thread.gs = value;
 			return 0;
@@ -279,7 +279,7 @@ static int putreg(struct task_struct *ch
 			break;
 		case offsetof(struct user_regs_struct, rip):
 			/* Check if the new RIP address is canonical */
-			if (value >= TASK_SIZE)
+			if (value >= TASK_SIZE_OF(child))
 				return -EIO;
 			break;
 	}
@@ -419,6 +419,8 @@ asmlinkage long sys_ptrace(long request,
 		break;
 
 	case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
+	{
+		int dsize = test_tsk_thread_flag(child, TIF_IA32) ? 3 : 7;
 		ret = -EIO;
 		if ((addr & 7) ||
 		    addr > sizeof(struct user) - 7)
@@ -430,22 +432,22 @@ asmlinkage long sys_ptrace(long request,
 			break;
 		/* Disallows to set a breakpoint into the vsyscall */
 		case offsetof(struct user, u_debugreg[0]):
-			if (data >= TASK_SIZE-7) break;
+			if (data >= TASK_SIZE_OF(child) - dsize) break;
 			child->thread.debugreg0 = data;
 			ret = 0;
 			break;
 		case offsetof(struct user, u_debugreg[1]):
-			if (data >= TASK_SIZE-7) break;
+			if (data >= TASK_SIZE_OF(child) - dsize) break;
 			child->thread.debugreg1 = data;
 			ret = 0;
 			break;
 		case offsetof(struct user, u_debugreg[2]):
-			if (data >= TASK_SIZE-7) break;
+			if (data >= TASK_SIZE_OF(child) - dsize) break;
 			child->thread.debugreg2 = data;
 			ret = 0;
 			break;
 		case offsetof(struct user, u_debugreg[3]):
-			if (data >= TASK_SIZE-7) break;
+			if (data >= TASK_SIZE_OF(child) - dsize) break;
 			child->thread.debugreg3 = data;
 			ret = 0;
 			break;
@@ -469,6 +471,7 @@ asmlinkage long sys_ptrace(long request,
 		  break;
 		}
 		break;
+	}
 	case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
 	case PTRACE_CONT:    /* restart after signal. */
 
diff --git a/arch/x86_64/kernel/reboot.c b/arch/x86_64/kernel/reboot.c
--- a/arch/x86_64/kernel/reboot.c
+++ b/arch/x86_64/kernel/reboot.c
@@ -66,34 +66,6 @@ static int __init reboot_setup(char *str
 
 __setup("reboot=", reboot_setup);
 
-#ifdef CONFIG_SMP
-static void smp_halt(void)
-{
-	int cpuid = safe_smp_processor_id(); 
-	static int first_entry = 1;
-
-	if (reboot_force)
-		return;
-
-	if (first_entry) {
-		first_entry = 0;
-		smp_call_function((void *)machine_restart, NULL, 1, 0);
-	}
-			
-	smp_stop_cpu(); 
-
-	/* AP calling this. Just halt */
-	if (cpuid != boot_cpu_id) { 
-		for (;;) 
-			asm("hlt");
-	}
-
-	/* Wait for all other CPUs to have run smp_stop_cpu */
-	while (!cpus_empty(cpu_online_map))
-		rep_nop(); 
-}
-#endif
-
 static inline void kb_wait(void)
 {
 	int i;
@@ -103,25 +75,44 @@ static inline void kb_wait(void)
 			break;
 }
 
-void machine_restart(char * __unused)
+void machine_shutdown(void)
 {
-	int i;
+	/* Stop the cpus and apics */
+#ifdef CONFIG_SMP
+	int reboot_cpu_id;
 
-	printk("machine restart\n");
+	/* The boot cpu is always logical cpu 0 */
+	reboot_cpu_id = 0;
 
-#ifdef CONFIG_SMP
-	smp_halt(); 
+	/* Make certain the cpu I'm about to reboot on is online */
+	if (!cpu_isset(reboot_cpu_id, cpu_online_map)) {
+		reboot_cpu_id = smp_processor_id();
+	}
+
+	/* Make certain I only run on the appropriate processor */
+	set_cpus_allowed(current, cpumask_of_cpu(reboot_cpu_id));
+
+	/* O.K Now that I'm on the appropriate processor,
+	 * stop all of the others.
+	 */
+	smp_send_stop();
 #endif
 
-	if (!reboot_force) {
-		local_irq_disable();
+	local_irq_disable();
+
 #ifndef CONFIG_SMP
-		disable_local_APIC();
+	disable_local_APIC();
 #endif
-		disable_IO_APIC();
-		local_irq_enable();
-	}
-	
+
+	disable_IO_APIC();
+
+	local_irq_enable();
+}
+
+void machine_emergency_restart(void)
+{
+	int i;
+
 	/* Tell the BIOS if we want cold or warm reboot */
 	*((unsigned short *)__va(0x472)) = reboot_mode;
        
@@ -146,18 +137,26 @@ void machine_restart(char * __unused)
 	}      
 }
 
-EXPORT_SYMBOL(machine_restart);
+void machine_restart(char * __unused)
+{
+	printk("machine restart\n");
+
+	if (!reboot_force) {
+		machine_shutdown();
+	}
+	machine_emergency_restart();
+}
 
 void machine_halt(void)
 {
 }
 
-EXPORT_SYMBOL(machine_halt);
-
 void machine_power_off(void)
 {
+	if (!reboot_force) {
+		machine_shutdown();
+	}
 	if (pm_power_off)
 		pm_power_off();
 }
 
-EXPORT_SYMBOL(machine_power_off);
diff --git a/arch/x86_64/kernel/relocate_kernel.S b/arch/x86_64/kernel/relocate_kernel.S
new file mode 100644
--- /dev/null
+++ b/arch/x86_64/kernel/relocate_kernel.S
@@ -0,0 +1,143 @@
+/*
+ * relocate_kernel.S - put the kernel image in place to boot
+ * Copyright (C) 2002-2005 Eric Biederman  <ebiederm@xmission.com>
+ *
+ * This source code is licensed under the GNU General Public License,
+ * Version 2.  See the file COPYING for more details.
+ */
+
+#include <linux/linkage.h>
+
+	/*
+	 * Must be relocatable PIC code callable as a C function, that once
+	 * it starts can not use the previous processes stack.
+	 */
+	.globl relocate_new_kernel
+	.code64
+relocate_new_kernel:
+	/* %rdi page_list
+	 * %rsi reboot_code_buffer
+	 * %rdx start address
+	 * %rcx page_table
+	 * %r8  arg5
+	 * %r9  arg6
+	 */
+
+	/* zero out flags, and disable interrupts */
+	pushq $0
+	popfq
+
+	/* set a new stack at the bottom of our page... */
+	lea   4096(%rsi), %rsp
+
+	/* store the parameters back on the stack */
+	pushq	%rdx /* store the start address */
+
+	/* Set cr0 to a known state:
+	 * 31 1 == Paging enabled
+	 * 18 0 == Alignment check disabled
+	 * 16 0 == Write protect disabled
+	 * 3  0 == No task switch
+	 * 2  0 == Don't do FP software emulation.
+	 * 0  1 == Proctected mode enabled
+	 */
+	movq	%cr0, %rax
+	andq	$~((1<<18)|(1<<16)|(1<<3)|(1<<2)), %rax
+	orl	$((1<<31)|(1<<0)), %eax
+	movq	%rax, %cr0
+
+	/* Set cr4 to a known state:
+	 * 10 0 == xmm exceptions disabled
+	 * 9  0 == xmm registers instructions disabled
+	 * 8  0 == performance monitoring counter disabled
+	 * 7  0 == page global disabled
+	 * 6  0 == machine check exceptions disabled
+	 * 5  1 == physical address extension enabled
+	 * 4  0 == page size extensions	disabled
+	 * 3  0 == Debug extensions disabled
+	 * 2  0 == Time stamp disable (disabled)
+	 * 1  0 == Protected mode virtual interrupts disabled
+	 * 0  0 == VME disabled
+	 */
+
+	movq	$((1<<5)), %rax
+	movq	%rax, %cr4
+
+	jmp 1f
+1:
+
+	/* Switch to the identity mapped page tables,
+	 * and flush the TLB.
+	*/
+	movq	%rcx, %cr3
+
+	/* Do the copies */
+	movq	%rdi, %rcx 	/* Put the page_list in %rcx */
+	xorq	%rdi, %rdi
+	xorq	%rsi, %rsi
+	jmp	1f
+
+0:	/* top, read another word for the indirection page */
+
+	movq	(%rbx), %rcx
+	addq	$8,	%rbx
+1:
+	testq	$0x1,	%rcx  /* is it a destination page? */
+	jz	2f
+	movq	%rcx,	%rdi
+	andq	$0xfffffffffffff000, %rdi
+	jmp	0b
+2:
+	testq	$0x2,	%rcx  /* is it an indirection page? */
+	jz	2f
+	movq	%rcx,   %rbx
+	andq	$0xfffffffffffff000, %rbx
+	jmp	0b
+2:
+	testq	$0x4,	%rcx  /* is it the done indicator? */
+	jz	2f
+	jmp	3f
+2:
+	testq	$0x8,	%rcx  /* is it the source indicator? */
+	jz	0b	      /* Ignore it otherwise */
+	movq	%rcx,   %rsi  /* For ever source page do a copy */
+	andq	$0xfffffffffffff000, %rsi
+
+	movq	$512,   %rcx
+	rep ; movsq
+	jmp	0b
+3:
+
+	/* To be certain of avoiding problems with self-modifying code
+	 * I need to execute a serializing instruction here.
+	 * So I flush the TLB by reloading %cr3 here, it's handy,
+	 * and not processor dependent.
+	 */
+	movq	%cr3, %rax
+	movq	%rax, %cr3
+
+	/* set all of the registers to known values */
+	/* leave %rsp alone */
+
+	xorq	%rax, %rax
+	xorq	%rbx, %rbx
+	xorq    %rcx, %rcx
+	xorq    %rdx, %rdx
+	xorq    %rsi, %rsi
+	xorq    %rdi, %rdi
+	xorq    %rbp, %rbp
+	xorq	%r8,  %r8
+	xorq	%r9,  %r9
+	xorq	%r10, %r9
+	xorq	%r11, %r11
+	xorq	%r12, %r12
+	xorq	%r13, %r13
+	xorq	%r14, %r14
+	xorq	%r15, %r15
+
+	ret
+relocate_new_kernel_end:
+
+	.globl relocate_new_kernel_size
+relocate_new_kernel_size:
+	.quad relocate_new_kernel_end - relocate_new_kernel
diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c
--- a/arch/x86_64/kernel/setup.c
+++ b/arch/x86_64/kernel/setup.c
@@ -40,6 +40,9 @@
 #include <linux/acpi.h>
 #include <linux/kallsyms.h>
 #include <linux/edd.h>
+#include <linux/mmzone.h>
+#include <linux/kexec.h>
+
 #include <asm/mtrr.h>
 #include <asm/uaccess.h>
 #include <asm/system.h>
@@ -348,7 +351,7 @@ static __init void parse_cmdline_early (
 		if (!memcmp(from, "mem=", 4))
 			parse_memopt(from+4, &from); 
 
-#ifdef CONFIG_DISCONTIGMEM
+#ifdef CONFIG_NUMA
 		if (!memcmp(from, "numa=", 5))
 			numa_setup(from+5); 
 #endif
@@ -365,6 +368,27 @@ static __init void parse_cmdline_early (
 		if (!memcmp(from, "noexec=", 7))
 			nonx_setup(from + 7);
 
+#ifdef CONFIG_KEXEC
+		/* crashkernel=size@addr specifies the location to reserve for
+		 * a crash kernel.  By reserving this memory we guarantee
+		 * that linux never set's it up as a DMA target.
+		 * Useful for holding code to do something appropriate
+		 * after a kernel panic.
+		 */
+		else if (!memcmp(from, "crashkernel=", 12)) {
+			unsigned long size, base;
+			size = memparse(from+12, &from);
+			if (*from == '@') {
+				base = memparse(from+1, &from);
+				/* FIXME: Do I want a sanity check
+				 * to validate the memory range?
+				 */
+				crashk_res.start = base;
+				crashk_res.end   = base + size - 1;
+			}
+		}
+#endif
+
 	next_char:
 		c = *(from++);
 		if (!c)
@@ -377,17 +401,20 @@ static __init void parse_cmdline_early (
 	*cmdline_p = command_line;
 }
 
-#ifndef CONFIG_DISCONTIGMEM
-static void __init contig_initmem_init(void)
-{
-        unsigned long bootmap_size, bootmap; 
-        bootmap_size = bootmem_bootmap_pages(end_pfn)<<PAGE_SHIFT;
-        bootmap = find_e820_area(0, end_pfn<<PAGE_SHIFT, bootmap_size);
-        if (bootmap == -1L) 
-                panic("Cannot find bootmem map of size %ld\n",bootmap_size);
-        bootmap_size = init_bootmem(bootmap >> PAGE_SHIFT, end_pfn);
-        e820_bootmem_free(&contig_page_data, 0, end_pfn << PAGE_SHIFT); 
-        reserve_bootmem(bootmap, bootmap_size);
+#ifndef CONFIG_NUMA
+static void __init
+contig_initmem_init(unsigned long start_pfn, unsigned long end_pfn)
+{
+	unsigned long bootmap_size, bootmap;
+
+	memory_present(0, start_pfn, end_pfn);
+	bootmap_size = bootmem_bootmap_pages(end_pfn)<<PAGE_SHIFT;
+	bootmap = find_e820_area(0, end_pfn<<PAGE_SHIFT, bootmap_size);
+	if (bootmap == -1L)
+		panic("Cannot find bootmem map of size %ld\n",bootmap_size);
+	bootmap_size = init_bootmem(bootmap >> PAGE_SHIFT, end_pfn);
+	e820_bootmem_free(NODE_DATA(0), 0, end_pfn << PAGE_SHIFT);
+	reserve_bootmem(bootmap, bootmap_size);
 } 
 #endif
 
@@ -554,10 +581,10 @@ void __init setup_arch(char **cmdline_p)
 	acpi_numa_init();
 #endif
 
-#ifdef CONFIG_DISCONTIGMEM
+#ifdef CONFIG_NUMA
 	numa_initmem_init(0, end_pfn); 
 #else
-	contig_initmem_init(); 
+	contig_initmem_init(0, end_pfn);
 #endif
 
 	/* Reserve direct mapping */
@@ -618,6 +645,15 @@ void __init setup_arch(char **cmdline_p)
 		}
 	}
 #endif
+#ifdef CONFIG_KEXEC
+	if (crashk_res.start != crashk_res.end) {
+		reserve_bootmem(crashk_res.start,
+			crashk_res.end - crashk_res.start + 1);
+	}
+#endif
+
+	sparse_init();
+
 	paging_init();
 
 	check_ioapic();
@@ -669,7 +705,7 @@ void __init setup_arch(char **cmdline_p)
 #endif
 }
 
-static int __init get_model_name(struct cpuinfo_x86 *c)
+static int __cpuinit get_model_name(struct cpuinfo_x86 *c)
 {
 	unsigned int *v;
 
@@ -685,7 +721,7 @@ static int __init get_model_name(struct 
 }
 
 
-static void __init display_cacheinfo(struct cpuinfo_x86 *c)
+static void __cpuinit display_cacheinfo(struct cpuinfo_x86 *c)
 {
 	unsigned int n, dummy, eax, ebx, ecx, edx;
 
@@ -729,8 +765,6 @@ static void __init amd_detect_cmp(struct
 	int cpu = smp_processor_id();
 	int node = 0;
 	unsigned bits;
-	if (c->x86_num_cores == 1)
-		return;
 
 	bits = 0;
 	while ((1 << bits) < c->x86_num_cores)
@@ -796,7 +830,7 @@ static int __init init_amd(struct cpuinf
 	return r;
 }
 
-static void __init detect_ht(struct cpuinfo_x86 *c)
+static void __cpuinit detect_ht(struct cpuinfo_x86 *c)
 {
 #ifdef CONFIG_SMP
 	u32 	eax, ebx, ecx, edx;
@@ -857,7 +891,7 @@ static void __init detect_ht(struct cpui
 /*
  * find out the number of processor cores on the die
  */
-static int __init intel_num_cpu_cores(struct cpuinfo_x86 *c)
+static int __cpuinit intel_num_cpu_cores(struct cpuinfo_x86 *c)
 {
 	unsigned int eax;
 
@@ -875,7 +909,7 @@ static int __init intel_num_cpu_cores(st
 		return 1;
 }
 
-static void __init init_intel(struct cpuinfo_x86 *c)
+static void __cpuinit init_intel(struct cpuinfo_x86 *c)
 {
 	/* Cache sizes */
 	unsigned n;
@@ -895,7 +929,7 @@ static void __init init_intel(struct cpu
  	c->x86_num_cores = intel_num_cpu_cores(c);
 }
 
-void __init get_cpu_vendor(struct cpuinfo_x86 *c)
+void __cpuinit get_cpu_vendor(struct cpuinfo_x86 *c)
 {
 	char *v = c->x86_vendor_id;
 
@@ -916,7 +950,7 @@ struct cpu_model_info {
 /* Do some early cpuid on the boot CPU to get some parameter that are
    needed before check_bugs. Everything advanced is in identify_cpu
    below. */
-void __init early_identify_cpu(struct cpuinfo_x86 *c)
+void __cpuinit early_identify_cpu(struct cpuinfo_x86 *c)
 {
 	u32 tfms;
 
@@ -970,7 +1004,7 @@ void __init early_identify_cpu(struct cp
 /*
  * This does the hard work of actually picking apart the CPU stuff...
  */
-void __init identify_cpu(struct cpuinfo_x86 *c)
+void __cpuinit identify_cpu(struct cpuinfo_x86 *c)
 {
 	int i;
 	u32 xlvl;
@@ -1040,14 +1074,17 @@ void __init identify_cpu(struct cpuinfo_
 #ifdef CONFIG_X86_MCE
 	mcheck_init(c);
 #endif
+	if (c == &boot_cpu_data)
+		mtrr_bp_init();
+	else
+		mtrr_ap_init();
 #ifdef CONFIG_NUMA
-	if (c != &boot_cpu_data)
-		numa_add_cpu(c - cpu_data);
+	numa_add_cpu(smp_processor_id());
 #endif
 }
  
 
-void __init print_cpu_info(struct cpuinfo_x86 *c)
+void __cpuinit print_cpu_info(struct cpuinfo_x86 *c)
 {
 	if (c->x86_model_id[0])
 		printk("%s", c->x86_model_id);
diff --git a/arch/x86_64/kernel/setup64.c b/arch/x86_64/kernel/setup64.c
--- a/arch/x86_64/kernel/setup64.c
+++ b/arch/x86_64/kernel/setup64.c
@@ -12,6 +12,7 @@
 #include <linux/string.h>
 #include <linux/bootmem.h>
 #include <linux/bitops.h>
+#include <linux/module.h>
 #include <asm/bootsetup.h>
 #include <asm/pda.h>
 #include <asm/pgtable.h>
@@ -22,22 +23,15 @@
 #include <asm/smp.h>
 #include <asm/i387.h>
 #include <asm/percpu.h>
-#include <asm/mtrr.h>
 #include <asm/proto.h>
-#include <asm/mman.h>
-#include <asm/numa.h>
+#include <asm/sections.h>
 
 char x86_boot_params[BOOT_PARAM_SIZE] __initdata = {0,};
 
-cpumask_t cpu_initialized __initdata = CPU_MASK_NONE;
+cpumask_t cpu_initialized __cpuinitdata = CPU_MASK_NONE;
 
 struct x8664_pda cpu_pda[NR_CPUS] __cacheline_aligned; 
 
-extern struct task_struct init_task;
-
-extern unsigned char __per_cpu_start[], __per_cpu_end[]; 
-
-extern struct desc_ptr cpu_gdt_descr[];
 struct desc_ptr idt_descr = { 256 * 16, (unsigned long) idt_table }; 
 
 char boot_cpu_stack[IRQSTACKSIZE] __attribute__((section(".bss.page_aligned")));
@@ -101,7 +95,7 @@ void __init setup_per_cpu_areas(void)
 #endif
 
 	for (i = 0; i < NR_CPUS; i++) { 
-		unsigned char *ptr;
+		char *ptr;
 
 		if (!NODE_DATA(cpu_to_node(i))) {
 			printk("cpu with no node %d, num_online_nodes %d\n",
@@ -171,7 +165,7 @@ void syscall_init(void)
 	wrmsrl(MSR_SYSCALL_MASK, EF_TF|EF_DF|EF_IE|0x3000); 
 }
 
-void __init check_efer(void)
+void __cpuinit check_efer(void)
 {
 	unsigned long efer;
 
@@ -188,13 +182,9 @@ void __init check_efer(void)
  * 'CPU state barrier', nothing should get across.
  * A lot of state is already set up in PDA init.
  */
-void __init cpu_init (void)
+void __cpuinit cpu_init (void)
 {
-#ifdef CONFIG_SMP
 	int cpu = stack_smp_processor_id();
-#else
-	int cpu = smp_processor_id();
-#endif
 	struct tss_struct *t = &per_cpu(init_tss, cpu);
 	unsigned long v; 
 	char *estacks = NULL; 
@@ -214,7 +204,7 @@ void __init cpu_init (void)
 
 	printk("Initializing CPU#%d\n", cpu);
 
-		clear_in_cr4(X86_CR4_VME|X86_CR4_PVI|X86_CR4_TSD|X86_CR4_DE);
+	clear_in_cr4(X86_CR4_VME|X86_CR4_PVI|X86_CR4_TSD|X86_CR4_DE);
 
 	/*
 	 * Initialize the per-CPU GDT with the boot GDT,
diff --git a/arch/x86_64/kernel/signal.c b/arch/x86_64/kernel/signal.c
--- a/arch/x86_64/kernel/signal.c
+++ b/arch/x86_64/kernel/signal.c
@@ -34,9 +34,9 @@
 
 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
 
-void ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
+int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
                sigset_t *set, struct pt_regs * regs); 
-void ia32_setup_frame(int sig, struct k_sigaction *ka,
+int ia32_setup_frame(int sig, struct k_sigaction *ka,
             sigset_t *set, struct pt_regs * regs); 
 
 asmlinkage long
@@ -238,7 +238,7 @@ get_stack(struct k_sigaction *ka, struct
 	return (void __user *)round_down(rsp - size, 16); 
 }
 
-static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
+static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
 			   sigset_t *set, struct pt_regs * regs)
 {
 	struct rt_sigframe __user *frame;
@@ -327,20 +327,23 @@ static void setup_rt_frame(int sig, stru
 		current->comm, current->pid, frame, regs->rip, frame->pretcode);
 #endif
 
-	return;
+	return 1;
 
 give_sigsegv:
 	force_sigsegv(sig, current);
+	return 0;
 }
 
 /*
  * OK, we're invoking a handler
  */	
 
-static void
+static int
 handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
 		sigset_t *oldset, struct pt_regs *regs)
 {
+	int ret;
+
 #ifdef DEBUG_SIG
 	printk("handle_signal pid:%d sig:%lu rip:%lx rsp:%lx regs=%p\n",
 		current->pid, sig,
@@ -384,20 +387,22 @@ handle_signal(unsigned long sig, siginfo
 #ifdef CONFIG_IA32_EMULATION
 	if (test_thread_flag(TIF_IA32)) {
 		if (ka->sa.sa_flags & SA_SIGINFO)
-			ia32_setup_rt_frame(sig, ka, info, oldset, regs);
+			ret = ia32_setup_rt_frame(sig, ka, info, oldset, regs);
 		else
-			ia32_setup_frame(sig, ka, oldset, regs);
+			ret = ia32_setup_frame(sig, ka, oldset, regs);
 	} else 
 #endif
-	setup_rt_frame(sig, ka, info, oldset, regs);
+	ret = setup_rt_frame(sig, ka, info, oldset, regs);
 
-	if (!(ka->sa.sa_flags & SA_NODEFER)) {
+	if (ret && !(ka->sa.sa_flags & SA_NODEFER)) {
 		spin_lock_irq(&current->sighand->siglock);
 		sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
 		sigaddset(&current->blocked,sig);
 		recalc_sigpending();
 		spin_unlock_irq(&current->sighand->siglock);
 	}
+
+	return ret;
 }
 
 /*
@@ -417,10 +422,10 @@ int do_signal(struct pt_regs *regs, sigs
 	 * kernel mode. Just return without doing anything
 	 * if so.
 	 */
-	if ((regs->cs & 3) != 3)
+	if (!user_mode(regs))
 		return 1;
 
-	if (try_to_freeze(0))
+	if (try_to_freeze())
 		goto no_signal;
 
 	if (!oldset)
@@ -434,11 +439,10 @@ int do_signal(struct pt_regs *regs, sigs
 		 * inside the kernel.
 		 */
 		if (current->thread.debugreg7)
-			asm volatile("movq %0,%%db7"	: : "r" (current->thread.debugreg7));
+			set_debugreg(current->thread.debugreg7, 7);
 
 		/* Whee!  Actually deliver the signal.  */
-		handle_signal(signr, &info, &ka, oldset, regs);
-		return 1;
+		return handle_signal(signr, &info, &ka, oldset, regs);
 	}
 
  no_signal:
diff --git a/arch/x86_64/kernel/smp.c b/arch/x86_64/kernel/smp.c
--- a/arch/x86_64/kernel/smp.c
+++ b/arch/x86_64/kernel/smp.c
@@ -129,10 +129,9 @@ asmlinkage void smp_invalidate_interrupt
 		} else
 			leave_mm(cpu);
 	}
+out:
 	ack_APIC_irq();
 	cpu_clear(cpu, flush_cpumask);
-
-out:
 	put_cpu_no_resched();
 }
 
@@ -283,6 +282,79 @@ struct call_data_struct {
 
 static struct call_data_struct * call_data;
 
+void lock_ipi_call_lock(void)
+{
+	spin_lock_irq(&call_lock);
+}
+
+void unlock_ipi_call_lock(void)
+{
+	spin_unlock_irq(&call_lock);
+}
+
+/*
+ * this function sends a 'generic call function' IPI to one other CPU
+ * in the system.
+ */
+static void __smp_call_function_single (int cpu, void (*func) (void *info), void *info,
+				int nonatomic, int wait)
+{
+	struct call_data_struct data;
+	int cpus = 1;
+
+	data.func = func;
+	data.info = info;
+	atomic_set(&data.started, 0);
+	data.wait = wait;
+	if (wait)
+		atomic_set(&data.finished, 0);
+
+	call_data = &data;
+	wmb();
+	/* Send a message to all other CPUs and wait for them to respond */
+	send_IPI_mask(cpumask_of_cpu(cpu), CALL_FUNCTION_VECTOR);
+
+	/* Wait for response */
+	while (atomic_read(&data.started) != cpus)
+		cpu_relax();
+
+	if (!wait)
+		return;
+
+	while (atomic_read(&data.finished) != cpus)
+		cpu_relax();
+}
+
+/*
+ * smp_call_function_single - Run a function on another CPU
+ * @func: The function to run. This must be fast and non-blocking.
+ * @info: An arbitrary pointer to pass to the function.
+ * @nonatomic: Currently unused.
+ * @wait: If true, wait until function has completed on other CPUs.
+ *
+ * Retrurns 0 on success, else a negative status code.
+ *
+ * Does not return until the remote CPU is nearly ready to execute <func>
+ * or is or has executed.
+ */
+
+int smp_call_function_single (int cpu, void (*func) (void *info), void *info,
+	int nonatomic, int wait)
+{
+	/* prevent preemption and reschedule on another processor */
+	int me = get_cpu();
+	if (cpu == me) {
+		WARN_ON(1);
+		put_cpu();
+		return -EBUSY;
+	}
+	spin_lock_bh(&call_lock);
+	__smp_call_function_single(cpu, func, info, nonatomic, wait);
+	spin_unlock_bh(&call_lock);
+	put_cpu();
+	return 0;
+}
+
 /*
  * this function sends a 'generic call function' IPI to all other CPUs
  * in the system.
diff --git a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c
--- a/arch/x86_64/kernel/smpboot.c
+++ b/arch/x86_64/kernel/smpboot.c
@@ -34,6 +34,7 @@
  *      Andi Kleen              :       Converted to new state machine.
  *					Various cleanups.
  *					Probably mostly hotplug CPU ready now.
+ *	Ashok Raj			: CPU hotplug support
  */
 
 
@@ -58,11 +59,6 @@
 #include <asm/proto.h>
 #include <asm/nmi.h>
 
-/* Change for real CPU hotplug. Note other files need to be fixed
-   first too. */
-#define __cpuinit __init
-#define __cpuinitdata __initdata
-
 /* Number of siblings per CPU package */
 int smp_num_siblings = 1;
 /* Package ID of each logical CPU */
@@ -103,6 +99,19 @@ EXPORT_SYMBOL(cpu_core_map);
 extern unsigned char trampoline_data[];
 extern unsigned char trampoline_end[];
 
+/* State of each CPU */
+DEFINE_PER_CPU(int, cpu_state) = { 0 };
+
+/*
+ * Store all idle threads, this can be reused instead of creating
+ * a new thread. Also avoids complicated thread destroy functionality
+ * for idle threads.
+ */
+struct task_struct *idle_thread_array[NR_CPUS] __cpuinitdata ;
+
+#define get_idle_for_cpu(x)     (idle_thread_array[(x)])
+#define set_idle_for_cpu(x,p)   (idle_thread_array[(x)] = (p))
+
 /*
  * Currently trivial. Write the real->protected mode
  * bootstrap into the page concerned. The caller
@@ -202,9 +211,6 @@ static __cpuinit void sync_master(void *
 {
 	unsigned long flags, i;
 
-	if (smp_processor_id() != boot_cpu_id)
-		return;
-
 	go[MASTER] = 0;
 
 	local_irq_save(flags);
@@ -253,12 +259,12 @@ get_delta(long *rt, long *master)
 	return tcenter - best_tm;
 }
 
-static __cpuinit void sync_tsc(void)
+static __cpuinit void sync_tsc(unsigned int master)
 {
 	int i, done = 0;
 	long delta, adj, adjust_latency = 0;
 	unsigned long flags, rt, master_time_stamp, bound;
-#if DEBUG_TSC_SYNC
+#ifdef DEBUG_TSC_SYNC
 	static struct syncdebug {
 		long rt;	/* roundtrip time */
 		long master;	/* master's timestamp */
@@ -267,9 +273,17 @@ static __cpuinit void sync_tsc(void)
 	} t[NUM_ROUNDS] __cpuinitdata;
 #endif
 
+	printk(KERN_INFO "CPU %d: Syncing TSC to CPU %u.\n",
+		smp_processor_id(), master);
+
 	go[MASTER] = 1;
 
-	smp_call_function(sync_master, NULL, 1, 0);
+	/* It is dangerous to broadcast IPI as cpus are coming up,
+	 * as they may not be ready to accept them.  So since
+	 * we only need to send the ipi to the boot cpu direct
+	 * the message, and avoid the race.
+	 */
+	smp_call_function_single(master, sync_master, NULL, 1, 0);
 
 	while (go[MASTER])	/* wait for master to be ready */
 		no_cpu_relax();
@@ -294,7 +308,7 @@ static __cpuinit void sync_tsc(void)
 				rdtscll(t);
 				wrmsrl(MSR_IA32_TSC, t + adj);
 			}
-#if DEBUG_TSC_SYNC
+#ifdef DEBUG_TSC_SYNC
 			t[i].rt = rt;
 			t[i].master = master_time_stamp;
 			t[i].diff = delta;
@@ -304,7 +318,7 @@ static __cpuinit void sync_tsc(void)
 	}
 	spin_unlock_irqrestore(&tsc_sync_lock, flags);
 
-#if DEBUG_TSC_SYNC
+#ifdef DEBUG_TSC_SYNC
 	for (i = 0; i < NUM_ROUNDS; ++i)
 		printk("rt=%5ld master=%5ld diff=%5ld adjlat=%5ld\n",
 		       t[i].rt, t[i].master, t[i].diff, t[i].lat);
@@ -313,16 +327,14 @@ static __cpuinit void sync_tsc(void)
 	printk(KERN_INFO
 	       "CPU %d: synchronized TSC with CPU %u (last diff %ld cycles, "
 	       "maxerr %lu cycles)\n",
-	       smp_processor_id(), boot_cpu_id, delta, rt);
+	       smp_processor_id(), master, delta, rt);
 }
 
 static void __cpuinit tsc_sync_wait(void)
 {
 	if (notscsync || !cpu_has_tsc)
 		return;
-	printk(KERN_INFO "CPU %d: Syncing TSC to CPU %u.\n", smp_processor_id(),
-			boot_cpu_id);
-	sync_tsc();
+	sync_tsc(0);
 }
 
 static __init int notscsync_setup(char *s)
@@ -418,6 +430,33 @@ void __cpuinit smp_callin(void)
 	cpu_set(cpuid, cpu_callin_map);
 }
 
+static inline void set_cpu_sibling_map(int cpu)
+{
+	int i;
+
+	if (smp_num_siblings > 1) {
+		for_each_cpu(i) {
+			if (cpu_core_id[cpu] == cpu_core_id[i]) {
+				cpu_set(i, cpu_sibling_map[cpu]);
+				cpu_set(cpu, cpu_sibling_map[i]);
+			}
+		}
+	} else {
+		cpu_set(cpu, cpu_sibling_map[cpu]);
+	}
+
+	if (current_cpu_data.x86_num_cores > 1) {
+		for_each_cpu(i) {
+			if (phys_proc_id[cpu] == phys_proc_id[i]) {
+				cpu_set(i, cpu_core_map[cpu]);
+				cpu_set(cpu, cpu_core_map[i]);
+			}
+		}
+	} else {
+		cpu_core_map[cpu] = cpu_sibling_map[cpu];
+	}
+}
+
 /*
  * Setup code on secondary processor (after comming out of the trampoline)
  */
@@ -448,23 +487,43 @@ void __cpuinit start_secondary(void)
 	enable_APIC_timer();
 
 	/*
-	 * Allow the master to continue.
+	 * The sibling maps must be set before turing the online map on for
+	 * this cpu
 	 */
-	cpu_set(smp_processor_id(), cpu_online_map);
-	mb();
+	set_cpu_sibling_map(smp_processor_id());
 
-	/* Wait for TSC sync to not schedule things before.
-	   We still process interrupts, which could see an inconsistent
-	   time in that window unfortunately. */
+	/* 
+  	 * Wait for TSC sync to not schedule things before.
+	 * We still process interrupts, which could see an inconsistent
+	 * time in that window unfortunately. 
+	 * Do this here because TSC sync has global unprotected state.
+ 	 */
 	tsc_sync_wait();
 
+	/*
+	 * We need to hold call_lock, so there is no inconsistency
+	 * between the time smp_call_function() determines number of
+	 * IPI receipients, and the time when the determination is made
+	 * for which cpus receive the IPI in genapic_flat.c. Holding this
+	 * lock helps us to not include this cpu in a currently in progress
+	 * smp_call_function().
+	 */
+	lock_ipi_call_lock();
+
+	/*
+	 * Allow the master to continue.
+	 */
+	cpu_set(smp_processor_id(), cpu_online_map);
+	per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE;
+	unlock_ipi_call_lock();
+
 	cpu_idle();
 }
 
 extern volatile unsigned long init_rsp;
 extern void (*initial_code)(void);
 
-#if APIC_DEBUG
+#ifdef APIC_DEBUG
 static void inquire_remote_apic(int apicid)
 {
 	unsigned i, regs[] = { APIC_ID >> 4, APIC_LVR >> 4, APIC_SPIV >> 4 };
@@ -628,36 +687,81 @@ static int __cpuinit wakeup_secondary_vi
 	return (send_status | accept_status);
 }
 
+struct create_idle {
+	struct task_struct *idle;
+	struct completion done;
+	int cpu;
+};
+
+void do_fork_idle(void *_c_idle)
+{
+	struct create_idle *c_idle = _c_idle;
+
+	c_idle->idle = fork_idle(c_idle->cpu);
+	complete(&c_idle->done);
+}
+
 /*
  * Boot one CPU.
  */
 static int __cpuinit do_boot_cpu(int cpu, int apicid)
 {
-	struct task_struct *idle;
 	unsigned long boot_error;
 	int timeout;
 	unsigned long start_rip;
+	struct create_idle c_idle = {
+		.cpu = cpu,
+		.done = COMPLETION_INITIALIZER(c_idle.done),
+	};
+	DECLARE_WORK(work, do_fork_idle, &c_idle);
+
+	c_idle.idle = get_idle_for_cpu(cpu);
+
+	if (c_idle.idle) {
+		c_idle.idle->thread.rsp = (unsigned long) (((struct pt_regs *)
+			(THREAD_SIZE + (unsigned long) c_idle.idle->thread_info)) - 1);
+		init_idle(c_idle.idle, cpu);
+		goto do_rest;
+	}
+
 	/*
-	 * We can't use kernel_thread since we must avoid to
-	 * reschedule the child.
-	 */
-	idle = fork_idle(cpu);
-	if (IS_ERR(idle)) {
+	 * During cold boot process, keventd thread is not spun up yet.
+	 * When we do cpu hot-add, we create idle threads on the fly, we should
+	 * not acquire any attributes from the calling context. Hence the clean
+	 * way to create kernel_threads() is to do that from keventd().
+	 * We do the current_is_keventd() due to the fact that ACPI notifier
+	 * was also queuing to keventd() and when the caller is already running
+	 * in context of keventd(), we would end up with locking up the keventd
+	 * thread.
+	 */
+	if (!keventd_up() || current_is_keventd())
+		work.func(work.data);
+	else {
+		schedule_work(&work);
+		wait_for_completion(&c_idle.done);
+	}
+
+	if (IS_ERR(c_idle.idle)) {
 		printk("failed fork for CPU %d\n", cpu);
-		return PTR_ERR(idle);
+		return PTR_ERR(c_idle.idle);
 	}
 
-	cpu_pda[cpu].pcurrent = idle;
+	set_idle_for_cpu(cpu, c_idle.idle);
+
+do_rest:
+
+	cpu_pda[cpu].pcurrent = c_idle.idle;
 
 	start_rip = setup_trampoline();
 
-	init_rsp = idle->thread.rsp;
+	init_rsp = c_idle.idle->thread.rsp;
 	per_cpu(init_tss,cpu).rsp0 = init_rsp;
 	initial_code = start_secondary;
-	clear_ti_thread_flag(idle->thread_info, TIF_FORK);
+	clear_ti_thread_flag(c_idle.idle->thread_info, TIF_FORK);
 
-	printk(KERN_INFO "Booting processor %d/%d rip %lx rsp %lx\n", cpu, apicid,
-	       start_rip, init_rsp);
+	printk(KERN_INFO "Booting processor %d/%d APIC 0x%x\n", cpu,
+		cpus_weight(cpu_present_map),
+		apicid);
 
 	/*
 	 * This grunge runs the startup process for
@@ -724,7 +828,7 @@ static int __cpuinit do_boot_cpu(int cpu
 			else
 				/* trampoline code not run */
 				printk("Not responding.\n");
-#if APIC_DEBUG
+#ifdef APIC_DEBUG
 			inquire_remote_apic(apicid);
 #endif
 		}
@@ -746,51 +850,6 @@ cycles_t cacheflush_time;
 unsigned long cache_decay_ticks;
 
 /*
- * Construct cpu_sibling_map[], so that we can tell the sibling CPU
- * on SMT systems efficiently.
- */
-static __cpuinit void detect_siblings(void)
-{
-	int cpu;
-
-	for (cpu = 0; cpu < NR_CPUS; cpu++) {
-		cpus_clear(cpu_sibling_map[cpu]);
-		cpus_clear(cpu_core_map[cpu]);
-	}
-
-	for_each_online_cpu (cpu) {
-		struct cpuinfo_x86 *c = cpu_data + cpu;
-		int siblings = 0;
-		int i;
-		if (smp_num_siblings > 1) {
-			for_each_online_cpu (i) {
-				if (cpu_core_id[cpu] == cpu_core_id[i]) {
-					siblings++;
-					cpu_set(i, cpu_sibling_map[cpu]);
-				}
-			}
-		} else {
-			siblings++;
-			cpu_set(cpu, cpu_sibling_map[cpu]);
-		}
-
-		if (siblings != smp_num_siblings) {
-			printk(KERN_WARNING
-	       "WARNING: %d siblings found for CPU%d, should be %d\n",
-			       siblings, cpu, smp_num_siblings);
-			smp_num_siblings = siblings;
-		}
-		if (c->x86_num_cores > 1) {
-			for_each_online_cpu(i) {
-				if (phys_proc_id[cpu] == phys_proc_id[i])
-					cpu_set(i, cpu_core_map[cpu]);
-			}
-		} else
-			cpu_core_map[cpu] = cpu_sibling_map[cpu];
-	}
-}
-
-/*
  * Cleanup possible dangling ends...
  */
 static __cpuinit void smp_cleanup_boot(void)
@@ -823,7 +882,7 @@ static __cpuinit void smp_cleanup_boot(v
  *
  * RED-PEN audit/test this more. I bet there is more state messed up here.
  */
-static __cpuinit void disable_smp(void)
+static __init void disable_smp(void)
 {
 	cpu_present_map = cpumask_of_cpu(0);
 	cpu_possible_map = cpumask_of_cpu(0);
@@ -838,7 +897,7 @@ static __cpuinit void disable_smp(void)
 /*
  * Handle user cpus=... parameter.
  */
-static __cpuinit void enforce_max_cpus(unsigned max_cpus)
+static __init void enforce_max_cpus(unsigned max_cpus)
 {
 	int i, k;
 	k = 0;
@@ -852,10 +911,31 @@ static __cpuinit void enforce_max_cpus(u
 	}
 }
 
+#ifdef CONFIG_HOTPLUG_CPU
+/*
+ * cpu_possible_map should be static, it cannot change as cpu's
+ * are onlined, or offlined. The reason is per-cpu data-structures
+ * are allocated by some modules at init time, and dont expect to
+ * do this dynamically on cpu arrival/departure.
+ * cpu_present_map on the other hand can change dynamically.
+ * In case when cpu_hotplug is not compiled, then we resort to current
+ * behaviour, which is cpu_possible == cpu_present.
+ * If cpu-hotplug is supported, then we need to preallocate for all
+ * those NR_CPUS, hence cpu_possible_map represents entire NR_CPUS range.
+ * - Ashok Raj
+ */
+static void prefill_possible_map(void)
+{
+	int i;
+	for (i = 0; i < NR_CPUS; i++)
+		cpu_set(i, cpu_possible_map);
+}
+#endif
+
 /*
  * Various sanity checks.
  */
-static int __cpuinit smp_sanity_check(unsigned max_cpus)
+static int __init smp_sanity_check(unsigned max_cpus)
 {
 	if (!physid_isset(hard_smp_processor_id(), phys_cpu_present_map)) {
 		printk("weird, boot CPU (#%d) not listed by the BIOS.\n",
@@ -913,28 +993,17 @@ static int __cpuinit smp_sanity_check(un
  * Prepare for SMP bootup.  The MP table or ACPI has been read
  * earlier.  Just do some sanity checking here and enable APIC mode.
  */
-void __cpuinit smp_prepare_cpus(unsigned int max_cpus)
+void __init smp_prepare_cpus(unsigned int max_cpus)
 {
-	int i;
-
 	nmi_watchdog_default();
 	current_cpu_data = boot_cpu_data;
 	current_thread_info()->cpu = 0;  /* needed? */
 
 	enforce_max_cpus(max_cpus);
 
-	/*
-	 * Fill in cpu_present_mask
-	 */
-	for (i = 0; i < NR_CPUS; i++) {
-		int apicid = cpu_present_to_apicid(i);
-		if (physid_isset(apicid, phys_cpu_present_map)) {
-			cpu_set(i, cpu_present_map);
-			/* possible map would be different if we supported real
-			   CPU hotplug. */
-			cpu_set(i, cpu_possible_map);
-		}
-	}
+#ifdef CONFIG_HOTPLUG_CPU
+	prefill_possible_map();
+#endif
 
 	if (smp_sanity_check(max_cpus) < 0) {
 		printk(KERN_INFO "SMP disabled\n");
@@ -978,13 +1047,13 @@ void __init smp_prepare_boot_cpu(void)
 	int me = smp_processor_id();
 	cpu_set(me, cpu_online_map);
 	cpu_set(me, cpu_callout_map);
+	cpu_set(0, cpu_sibling_map[0]);
+	cpu_set(0, cpu_core_map[0]);
+	per_cpu(cpu_state, me) = CPU_ONLINE;
 }
 
 /*
  * Entry point to boot a CPU.
- *
- * This is all __cpuinit, not __devinit for now because we don't support
- * CPU hotplug (yet).
  */
 int __cpuinit __cpu_up(unsigned int cpu)
 {
@@ -1001,6 +1070,15 @@ int __cpuinit __cpu_up(unsigned int cpu)
 		return -EINVAL;
 	}
 
+	/*
+	 * Already booted CPU?
+	 */
+ 	if (cpu_isset(cpu, cpu_callin_map)) {
+		Dprintk("do_boot_cpu %d Already started\n", cpu);
+ 		return -ENOSYS;
+	}
+
+	per_cpu(cpu_state, cpu) = CPU_UP_PREPARE;
 	/* Boot it! */
 	err = do_boot_cpu(cpu, apicid);
 	if (err < 0) {
@@ -1013,23 +1091,117 @@ int __cpuinit __cpu_up(unsigned int cpu)
 
 	while (!cpu_isset(cpu, cpu_online_map))
 		cpu_relax();
-	return 0;
+	err = 0;
+
+	return err;
 }
 
 /*
  * Finish the SMP boot.
  */
-void __cpuinit smp_cpus_done(unsigned int max_cpus)
+void __init smp_cpus_done(unsigned int max_cpus)
 {
+#ifndef CONFIG_HOTPLUG_CPU
 	zap_low_mappings();
+#endif
 	smp_cleanup_boot();
 
 #ifdef CONFIG_X86_IO_APIC
 	setup_ioapic_dest();
 #endif
 
-	detect_siblings();
 	time_init_gtod();
 
 	check_nmi_watchdog();
 }
+
+#ifdef CONFIG_HOTPLUG_CPU
+
+static void remove_siblinginfo(int cpu)
+{
+	int sibling;
+
+	for_each_cpu_mask(sibling, cpu_sibling_map[cpu])
+		cpu_clear(cpu, cpu_sibling_map[sibling]);
+	for_each_cpu_mask(sibling, cpu_core_map[cpu])
+		cpu_clear(cpu, cpu_core_map[sibling]);
+	cpus_clear(cpu_sibling_map[cpu]);
+	cpus_clear(cpu_core_map[cpu]);
+	phys_proc_id[cpu] = BAD_APICID;
+	cpu_core_id[cpu] = BAD_APICID;
+}
+
+void remove_cpu_from_maps(void)
+{
+	int cpu = smp_processor_id();
+
+	cpu_clear(cpu, cpu_callout_map);
+	cpu_clear(cpu, cpu_callin_map);
+	clear_bit(cpu, &cpu_initialized); /* was set by cpu_init() */
+}
+
+int __cpu_disable(void)
+{
+	int cpu = smp_processor_id();
+
+	/*
+	 * Perhaps use cpufreq to drop frequency, but that could go
+	 * into generic code.
+ 	 *
+	 * We won't take down the boot processor on i386 due to some
+	 * interrupts only being able to be serviced by the BSP.
+	 * Especially so if we're not using an IOAPIC	-zwane
+	 */
+	if (cpu == 0)
+		return -EBUSY;
+
+	disable_APIC_timer();
+
+	/*
+	 * HACK:
+	 * Allow any queued timer interrupts to get serviced
+	 * This is only a temporary solution until we cleanup
+	 * fixup_irqs as we do for IA64.
+	 */
+	local_irq_enable();
+	mdelay(1);
+
+	local_irq_disable();
+	remove_siblinginfo(cpu);
+
+	/* It's now safe to remove this processor from the online map */
+	cpu_clear(cpu, cpu_online_map);
+	remove_cpu_from_maps();
+	fixup_irqs(cpu_online_map);
+	return 0;
+}
+
+void __cpu_die(unsigned int cpu)
+{
+	/* We don't do anything here: idle task is faking death itself. */
+	unsigned int i;
+
+	for (i = 0; i < 10; i++) {
+		/* They ack this in play_dead by setting CPU_DEAD */
+		if (per_cpu(cpu_state, cpu) == CPU_DEAD) {
+			printk ("CPU %d is now offline\n", cpu);
+			return;
+		}
+		msleep(100);
+	}
+ 	printk(KERN_ERR "CPU %u didn't die...\n", cpu);
+}
+
+#else /* ... !CONFIG_HOTPLUG_CPU */
+
+int __cpu_disable(void)
+{
+	return -ENOSYS;
+}
+
+void __cpu_die(unsigned int cpu)
+{
+	/* We said "no" in __cpu_disable */
+	BUG();
+}
+#endif /* CONFIG_HOTPLUG_CPU */
diff --git a/arch/x86_64/kernel/suspend.c b/arch/x86_64/kernel/suspend.c
--- a/arch/x86_64/kernel/suspend.c
+++ b/arch/x86_64/kernel/suspend.c
@@ -44,7 +44,6 @@ void __save_processor_state(struct saved
 	 */
 	asm volatile ("sgdt %0" : "=m" (ctxt->gdt_limit));
 	asm volatile ("sidt %0" : "=m" (ctxt->idt_limit));
-	asm volatile ("sldt %0" : "=m" (ctxt->ldt));
 	asm volatile ("str %0"  : "=m" (ctxt->tr));
 
 	/* XMM0..XMM15 should be handled by kernel_fpu_begin(). */
@@ -69,6 +68,7 @@ void __save_processor_state(struct saved
 	asm volatile ("movq %%cr2, %0" : "=r" (ctxt->cr2));
 	asm volatile ("movq %%cr3, %0" : "=r" (ctxt->cr3));
 	asm volatile ("movq %%cr4, %0" : "=r" (ctxt->cr4));
+	asm volatile ("movq %%cr8, %0" : "=r" (ctxt->cr8));
 }
 
 void save_processor_state(void)
@@ -90,12 +90,20 @@ void __restore_processor_state(struct sa
 	/*
 	 * control registers
 	 */
+	asm volatile ("movq %0, %%cr8" :: "r" (ctxt->cr8));
 	asm volatile ("movq %0, %%cr4" :: "r" (ctxt->cr4));
 	asm volatile ("movq %0, %%cr3" :: "r" (ctxt->cr3));
 	asm volatile ("movq %0, %%cr2" :: "r" (ctxt->cr2));
 	asm volatile ("movq %0, %%cr0" :: "r" (ctxt->cr0));
 
 	/*
+	 * now restore the descriptor tables to their proper values
+	 * ltr is done i fix_processor_context().
+	 */
+	asm volatile ("lgdt %0" :: "m" (ctxt->gdt_limit));
+	asm volatile ("lidt %0" :: "m" (ctxt->idt_limit));
+
+	/*
 	 * segment registers
 	 */
 	asm volatile ("movw %0, %%ds" :: "r" (ctxt->ds));
@@ -108,17 +116,10 @@ void __restore_processor_state(struct sa
 	wrmsrl(MSR_GS_BASE, ctxt->gs_base);
 	wrmsrl(MSR_KERNEL_GS_BASE, ctxt->gs_kernel_base);
 
-	/*
-	 * now restore the descriptor tables to their proper values
-	 * ltr is done i fix_processor_context().
-	 */
-	asm volatile ("lgdt %0" :: "m" (ctxt->gdt_limit));
-	asm volatile ("lidt %0" :: "m" (ctxt->idt_limit));
-	asm volatile ("lldt %0" :: "m" (ctxt->ldt));
-
 	fix_processor_context();
 
 	do_fpu_end();
+	mtrr_ap_init();
 }
 
 void restore_processor_state(void)
diff --git a/arch/x86_64/kernel/sys_x86_64.c b/arch/x86_64/kernel/sys_x86_64.c
--- a/arch/x86_64/kernel/sys_x86_64.c
+++ b/arch/x86_64/kernel/sys_x86_64.c
@@ -68,13 +68,7 @@ out:
 static void find_start_end(unsigned long flags, unsigned long *begin,
 			   unsigned long *end)
 {
-#ifdef CONFIG_IA32_EMULATION
-	if (test_thread_flag(TIF_IA32)) { 
-		*begin = TASK_UNMAPPED_32;
-		*end = IA32_PAGE_OFFSET; 
-	} else 
-#endif
-	if (flags & MAP_32BIT) { 
+	if (!test_thread_flag(TIF_IA32) && (flags & MAP_32BIT)) {
 		/* This is usually used needed to map code in small
 		   model, so it needs to be in the first 31bit. Limit
 		   it to that.  This means we need to move the
@@ -84,10 +78,10 @@ static void find_start_end(unsigned long
 		   of playground for now. -AK */ 
 		*begin = 0x40000000; 
 		*end = 0x80000000;		
-	} else { 
-		*begin = TASK_UNMAPPED_64; 
+	} else {
+		*begin = TASK_UNMAPPED_BASE;
 		*end = TASK_SIZE; 
-		}
+	}
 } 
 
 unsigned long
@@ -111,6 +105,11 @@ arch_get_unmapped_area(struct file *filp
 		    (!vma || addr + len <= vma->vm_start))
 			return addr;
 	}
+	if (((flags & MAP_32BIT) || test_thread_flag(TIF_IA32))
+	    && len <= mm->cached_hole_size) {
+	        mm->cached_hole_size = 0;
+		mm->free_area_cache = begin;
+	}
 	addr = mm->free_area_cache;
 	if (addr < begin) 
 		addr = begin; 
@@ -126,6 +125,7 @@ full_search:
 			 */
 			if (start_addr != begin) {
 				start_addr = addr = begin;
+				mm->cached_hole_size = 0;
 				goto full_search;
 			}
 			return -ENOMEM;
@@ -137,6 +137,9 @@ full_search:
 			mm->free_area_cache = addr + len;
 			return addr;
 		}
+		if (addr + mm->cached_hole_size < vma->vm_start)
+		        mm->cached_hole_size = vma->vm_start - addr;
+
 		addr = vma->vm_end;
 	}
 }
diff --git a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c
--- a/arch/x86_64/kernel/time.c
+++ b/arch/x86_64/kernel/time.c
@@ -64,6 +64,7 @@ static int notsc __initdata = 0;
 unsigned int cpu_khz;					/* TSC clocks / usec, not used here */
 static unsigned long hpet_period;			/* fsecs / HPET clock */
 unsigned long hpet_tick;				/* HPET clocks / interrupt */
+static int hpet_use_timer;
 unsigned long vxtime_hz = PIT_TICK_RATE;
 int report_lost_ticks;				/* command line option */
 unsigned long long monotonic_base;
@@ -105,7 +106,9 @@ static inline unsigned int do_gettimeoff
 
 static inline unsigned int do_gettimeoffset_hpet(void)
 {
-	return ((hpet_readl(HPET_COUNTER) - vxtime.last) * vxtime.quot) >> 32;
+	/* cap counter read to one tick to avoid inconsistencies */
+	unsigned long counter = hpet_readl(HPET_COUNTER) - vxtime.last;
+	return (min(counter,hpet_tick) * vxtime.quot) >> 32;
 }
 
 unsigned int (*do_gettimeoffset)(void) = do_gettimeoffset_tsc;
@@ -301,7 +304,7 @@ unsigned long long monotonic_clock(void)
 
 			last_offset = vxtime.last;
 			base = monotonic_base;
-			this_offset = hpet_readl(HPET_T0_CMP) - hpet_tick;
+			this_offset = hpet_readl(HPET_COUNTER);
 
 		} while (read_seqretry(&xtime_lock, seq));
 		offset = (this_offset - last_offset);
@@ -377,7 +380,14 @@ static irqreturn_t timer_interrupt(int i
 
 	write_seqlock(&xtime_lock);
 
-	if (vxtime.hpet_address) {
+	if (vxtime.hpet_address)
+		offset = hpet_readl(HPET_COUNTER);
+
+	if (hpet_use_timer) {
+		/* if we're using the hpet timer functionality,
+		 * we can more accurately know the counter value
+		 * when the timer interrupt occured.
+		 */
 		offset = hpet_readl(HPET_T0_CMP) - hpet_tick;
 		delay = hpet_readl(HPET_COUNTER) - offset;
 	} else {
@@ -803,17 +813,18 @@ static int hpet_timer_stop_set_go(unsign
  * Set up timer 0, as periodic with first interrupt to happen at hpet_tick,
  * and period also hpet_tick.
  */
-
-	hpet_writel(HPET_TN_ENABLE | HPET_TN_PERIODIC | HPET_TN_SETVAL |
+	if (hpet_use_timer) {
+		hpet_writel(HPET_TN_ENABLE | HPET_TN_PERIODIC | HPET_TN_SETVAL |
 		    HPET_TN_32BIT, HPET_T0_CFG);
-	hpet_writel(hpet_tick, HPET_T0_CMP);
-	hpet_writel(hpet_tick, HPET_T0_CMP); /* AK: why twice? */
-
+		hpet_writel(hpet_tick, HPET_T0_CMP);
+		hpet_writel(hpet_tick, HPET_T0_CMP); /* AK: why twice? */
+		cfg |= HPET_CFG_LEGACY;
+	}
 /*
  * Go!
  */
 
-	cfg |= HPET_CFG_ENABLE | HPET_CFG_LEGACY;
+	cfg |= HPET_CFG_ENABLE;
 	hpet_writel(cfg, HPET_CFG);
 
 	return 0;
@@ -834,8 +845,7 @@ static int hpet_init(void)
 
 	id = hpet_readl(HPET_ID);
 
-	if (!(id & HPET_ID_VENDOR) || !(id & HPET_ID_NUMBER) ||
-	    !(id & HPET_ID_LEGSUP))
+	if (!(id & HPET_ID_VENDOR) || !(id & HPET_ID_NUMBER))
 		return -1;
 
 	hpet_period = hpet_readl(HPET_PERIOD);
@@ -845,6 +855,8 @@ static int hpet_init(void)
 	hpet_tick = (1000000000L * (USEC_PER_SEC / HZ) + hpet_period / 2) /
 		hpet_period;
 
+	hpet_use_timer = (id & HPET_ID_LEGSUP);
+
 	return hpet_timer_stop_set_go(hpet_tick);
 }
 
@@ -901,9 +913,11 @@ void __init time_init(void)
 	set_normalized_timespec(&wall_to_monotonic,
 	                        -xtime.tv_sec, -xtime.tv_nsec);
 
-	if (!hpet_init()) {
+	if (!hpet_init())
                 vxtime_hz = (1000000000000000L + hpet_period / 2) /
 			hpet_period;
+
+	if (hpet_use_timer) {
 		cpu_khz = hpet_calibrate_tsc();
 		timename = "HPET";
 #ifdef CONFIG_X86_PM_TIMER
@@ -968,7 +982,7 @@ void __init time_init_gtod(void)
 	if (unsynchronized_tsc())
 		notsc = 1;
 	if (vxtime.hpet_address && notsc) {
-		timetype = "HPET";
+		timetype = hpet_use_timer ? "HPET" : "PIT/HPET";
 		vxtime.last = hpet_readl(HPET_T0_CMP) - hpet_tick;
 		vxtime.mode = VXTIME_HPET;
 		do_gettimeoffset = do_gettimeoffset_hpet;
@@ -983,7 +997,7 @@ void __init time_init_gtod(void)
 		printk(KERN_INFO "Disabling vsyscall due to use of PM timer\n");
 #endif
 	} else {
-		timetype = vxtime.hpet_address ? "HPET/TSC" : "PIT/TSC";
+		timetype = hpet_use_timer ? "HPET/TSC" : "PIT/TSC";
 		vxtime.mode = VXTIME_TSC;
 	}
 
diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c
--- a/arch/x86_64/kernel/traps.c
+++ b/arch/x86_64/kernel/traps.c
@@ -274,7 +274,7 @@ EXPORT_SYMBOL(dump_stack);
 void show_registers(struct pt_regs *regs)
 {
 	int i;
-	int in_kernel = (regs->cs & 3) == 0;
+	int in_kernel = !user_mode(regs);
 	unsigned long rsp;
 	const int cpu = safe_smp_processor_id(); 
 	struct task_struct *cur = cpu_pda[cpu].pcurrent; 
@@ -318,7 +318,7 @@ void handle_BUG(struct pt_regs *regs)
 	struct bug_frame f;
 	char tmp;
 
-	if (regs->cs & 3)
+	if (user_mode(regs))
 		return; 
 	if (__copy_from_user(&f, (struct bug_frame *) regs->rip, 
 			     sizeof(struct bug_frame)))
@@ -437,7 +437,7 @@ static void do_trap(int trapnr, int sign
        }
 #endif
 
-	if ((regs->cs & 3)  != 0) { 
+	if (user_mode(regs)) {
 		struct task_struct *tsk = current;
 
 		if (exception_trace && unhandled_signal(tsk, signr))
@@ -522,7 +522,7 @@ asmlinkage void do_general_protection(st
        }
 #endif
 
-	if ((regs->cs & 3)!=0) { 
+	if (user_mode(regs)) {
 		struct task_struct *tsk = current;
 
 		if (exception_trace && unhandled_signal(tsk, SIGSEGV))
@@ -586,9 +586,12 @@ static void unknown_nmi_error(unsigned c
 asmlinkage void default_do_nmi(struct pt_regs *regs)
 {
 	unsigned char reason = 0;
+	int cpu;
+
+	cpu = smp_processor_id();
 
 	/* Only the BSP gets external NMIs from the system.  */
-	if (!smp_processor_id())
+	if (!cpu)
 		reason = get_nmi_reason();
 
 	if (!(reason & 0xc0)) {
@@ -638,7 +641,7 @@ asmlinkage struct pt_regs *sync_regs(str
 	if (eregs == (struct pt_regs *)eregs->rsp)
 		;
 	/* Exception from user space */
-	else if (eregs->cs & 3)
+	else if (user_mode(eregs))
 		regs = ((struct pt_regs *)current->thread.rsp0) - 1;
 	/* Exception from kernel and interrupts are enabled. Move to
  	   kernel process stack. */
@@ -669,7 +672,7 @@ asmlinkage void do_debug(struct pt_regs 
        }
 #endif
 
-	asm("movq %%db6,%0" : "=r" (condition));
+	get_debugreg(condition, 6);
 
 	if (notify_die(DIE_DEBUG, "debug", regs, condition, error_code,
 						SIGTRAP) == NOTIFY_STOP)
@@ -697,7 +700,7 @@ asmlinkage void do_debug(struct pt_regs 
 		 * allowing programs to debug themselves without the ptrace()
 		 * interface.
 		 */
-                if ((regs->cs & 3) == 0)
+                if (!user_mode(regs))
                        goto clear_TF_reenable;
 		/*
 		 * Was the TF flag set by a debugger? If so, clear it now,
@@ -715,13 +718,13 @@ asmlinkage void do_debug(struct pt_regs 
 	info.si_signo = SIGTRAP;
 	info.si_errno = 0;
 	info.si_code = TRAP_BRKPT;
-	if ((regs->cs & 3) == 0) 
+	if (!user_mode(regs))
 		goto clear_dr7; 
 
 	info.si_addr = (void __user *)regs->rip;
 	force_sig_info(SIGTRAP, &info, tsk);	
 clear_dr7:
-	asm volatile("movq %0,%%db7"::"r"(0UL));
+	set_debugreg(0UL, 7);
 	return;
 
 clear_TF_reenable:
@@ -756,7 +759,7 @@ asmlinkage void do_coprocessor_error(str
 	unsigned short cwd, swd;
 
 	conditional_sti(regs);
-	if ((regs->cs & 3) == 0 &&
+	if (!user_mode(regs) &&
 	    kernel_math_error(regs, "kernel x87 math error"))
 		return;
 
@@ -822,7 +825,7 @@ asmlinkage void do_simd_coprocessor_erro
 	unsigned short mxcsr;
 
 	conditional_sti(regs);
-	if ((regs->cs & 3) == 0 &&
+	if (!user_mode(regs) &&
         	kernel_math_error(regs, "kernel simd math error"))
 		return;
 
diff --git a/arch/x86_64/kernel/vmlinux.lds.S b/arch/x86_64/kernel/vmlinux.lds.S
--- a/arch/x86_64/kernel/vmlinux.lds.S
+++ b/arch/x86_64/kernel/vmlinux.lds.S
@@ -2,7 +2,10 @@
  * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>;
  */
 
+#define LOAD_OFFSET __START_KERNEL_map
+
 #include <asm-generic/vmlinux.lds.h>
+#include <asm/page.h>
 #include <linux/config.h>
 
 OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64")
@@ -11,28 +14,30 @@ ENTRY(phys_startup_64)
 jiffies_64 = jiffies;
 SECTIONS
 {
-  . = 0xffffffff80100000;
+  . = __START_KERNEL;
   phys_startup_64 = startup_64 - LOAD_OFFSET;
   _text = .;			/* Text and read-only data */
-  .text : {
+  .text :  AT(ADDR(.text) - LOAD_OFFSET) {
 	*(.text)
 	SCHED_TEXT
 	LOCK_TEXT
 	*(.fixup)
 	*(.gnu.warning)
 	} = 0x9090
-  .text.lock : { *(.text.lock) }	/* out-of-line lock text */
+  				/* out-of-line lock text */
+  .text.lock : AT(ADDR(.text.lock) - LOAD_OFFSET) { *(.text.lock) }
 
   _etext = .;			/* End of text section */
 
   . = ALIGN(16);		/* Exception table */
   __start___ex_table = .;
-  __ex_table : { *(__ex_table) }
+  __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { *(__ex_table) }
   __stop___ex_table = .;
 
   RODATA
 
-  .data : {			/* Data */
+				/* Data */
+  .data : AT(ADDR(.data) - LOAD_OFFSET) {
 	*(.data)
 	CONSTRUCTORS
 	}
@@ -40,62 +45,99 @@ SECTIONS
   _edata = .;			/* End of data section */
 
   __bss_start = .;		/* BSS */
-  .bss : {
+  .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
 	*(.bss.page_aligned)	
 	*(.bss)
 	}
   __bss_end = .;
 
+  . = ALIGN(PAGE_SIZE);
+  . = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
+  .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
+	*(.data.cacheline_aligned)
+  }
   . = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
-  .data.cacheline_aligned : { *(.data.cacheline_aligned) }
+  .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) {
+  	*(.data.read_mostly)
+  }
 
-#define AFTER(x)      BINALIGN(LOADADDR(x) + SIZEOF(x), 16)
-#define BINALIGN(x,y) (((x) + (y) - 1)  & ~((y) - 1))
-#define CACHE_ALIGN(x) BINALIGN(x, CONFIG_X86_L1_CACHE_BYTES)
+#define VSYSCALL_ADDR (-10*1024*1024)
+#define VSYSCALL_PHYS_ADDR ((LOADADDR(.data.read_mostly) + SIZEOF(.data.read_mostly) + 4095) & ~(4095))
+#define VSYSCALL_VIRT_ADDR ((ADDR(.data.read_mostly) + SIZEOF(.data.read_mostly) + 4095) & ~(4095))
+
+#define VLOAD_OFFSET (VSYSCALL_ADDR - VSYSCALL_PHYS_ADDR)
+#define VLOAD(x) (ADDR(x) - VLOAD_OFFSET)
+
+#define VVIRT_OFFSET (VSYSCALL_ADDR - VSYSCALL_VIRT_ADDR)
+#define VVIRT(x) (ADDR(x) - VVIRT_OFFSET)
+
+  . = VSYSCALL_ADDR;
+  .vsyscall_0 :	 AT(VSYSCALL_PHYS_ADDR) { *(.vsyscall_0) }
+  __vsyscall_0 = VSYSCALL_VIRT_ADDR;
 
-  .vsyscall_0 -10*1024*1024: AT ((LOADADDR(.data.cacheline_aligned) + SIZEOF(.data.cacheline_aligned) + 4095) & ~(4095)) { *(.vsyscall_0) }
-  __vsyscall_0 = LOADADDR(.vsyscall_0);
   . = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
-  .xtime_lock : AT CACHE_ALIGN(AFTER(.vsyscall_0)) { *(.xtime_lock) }
-  xtime_lock = LOADADDR(.xtime_lock);
-  .vxtime : AT AFTER(.xtime_lock) { *(.vxtime) }
-  vxtime = LOADADDR(.vxtime);
-  .wall_jiffies : AT AFTER(.vxtime) { *(.wall_jiffies) }
-  wall_jiffies = LOADADDR(.wall_jiffies);
-  .sys_tz : AT AFTER(.wall_jiffies) { *(.sys_tz) }
-  sys_tz = LOADADDR(.sys_tz);
-  .sysctl_vsyscall : AT AFTER(.sys_tz) { *(.sysctl_vsyscall) }
-  sysctl_vsyscall = LOADADDR(.sysctl_vsyscall); 
-  .xtime : AT AFTER(.sysctl_vsyscall) { *(.xtime) }
-  xtime = LOADADDR(.xtime);
+  .xtime_lock : AT(VLOAD(.xtime_lock)) { *(.xtime_lock) }
+  xtime_lock = VVIRT(.xtime_lock);
+
+  .vxtime : AT(VLOAD(.vxtime)) { *(.vxtime) }
+  vxtime = VVIRT(.vxtime);
+
+  .wall_jiffies : AT(VLOAD(.wall_jiffies)) { *(.wall_jiffies) }
+  wall_jiffies = VVIRT(.wall_jiffies);
+
+  .sys_tz : AT(VLOAD(.sys_tz)) { *(.sys_tz) }
+  sys_tz = VVIRT(.sys_tz);
+
+  .sysctl_vsyscall : AT(VLOAD(.sysctl_vsyscall)) { *(.sysctl_vsyscall) }
+  sysctl_vsyscall = VVIRT(.sysctl_vsyscall);
+
+  .xtime : AT(VLOAD(.xtime)) { *(.xtime) }
+  xtime = VVIRT(.xtime);
+
   . = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
-  .jiffies : AT CACHE_ALIGN(AFTER(.xtime)) { *(.jiffies) }
-  jiffies = LOADADDR(.jiffies);
-  .vsyscall_1 ADDR(.vsyscall_0) + 1024: AT (LOADADDR(.vsyscall_0) + 1024) { *(.vsyscall_1) }
-  . = LOADADDR(.vsyscall_0) + 4096;
+  .jiffies : AT(VLOAD(.jiffies)) { *(.jiffies) }
+  jiffies = VVIRT(.jiffies);
+
+  .vsyscall_1 ADDR(.vsyscall_0) + 1024: AT(VLOAD(.vsyscall_1)) { *(.vsyscall_1) }
+  .vsyscall_2 ADDR(.vsyscall_0) + 2048: AT(VLOAD(.vsyscall_2)) { *(.vsyscall_2) }
+  .vsyscall_3 ADDR(.vsyscall_0) + 3072: AT(VLOAD(.vsyscall_3)) { *(.vsyscall_3) }
+
+  . = VSYSCALL_VIRT_ADDR + 4096;
+
+#undef VSYSCALL_ADDR
+#undef VSYSCALL_PHYS_ADDR
+#undef VSYSCALL_VIRT_ADDR
+#undef VLOAD_OFFSET
+#undef VLOAD
+#undef VVIRT_OFFSET
+#undef VVIRT
 
   . = ALIGN(8192);		/* init_task */
-  .data.init_task : { *(.data.init_task) }
+  .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
+	*(.data.init_task)
+  }
 
   . = ALIGN(4096);
-  .data.page_aligned : { *(.data.page_aligned) }
+  .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
+	*(.data.page_aligned)
+  }
 
   . = ALIGN(4096);		/* Init code and data */
   __init_begin = .;
-  .init.text : { 
+  .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {
 	_sinittext = .;
 	*(.init.text)
 	_einittext = .;
   }
   __initdata_begin = .;
-  .init.data : { *(.init.data) }
+  .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) { *(.init.data) }
   __initdata_end = .;
   . = ALIGN(16);
   __setup_start = .;
-  .init.setup : { *(.init.setup) }
+  .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) { *(.init.setup) }
   __setup_end = .;
   __initcall_start = .;
-  .initcall.init : {
+  .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) {
 	*(.initcall1.init) 
 	*(.initcall2.init) 
 	*(.initcall3.init) 
@@ -106,32 +148,38 @@ SECTIONS
   }
   __initcall_end = .;
   __con_initcall_start = .;
-  .con_initcall.init : { *(.con_initcall.init) }
+  .con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET) {
+	*(.con_initcall.init)
+  }
   __con_initcall_end = .;
   SECURITY_INIT
   . = ALIGN(8);
   __alt_instructions = .;
-  .altinstructions : { *(.altinstructions) } 
+  .altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) {
+	*(.altinstructions)
+  }
   __alt_instructions_end = .; 
- .altinstr_replacement : { *(.altinstr_replacement) }
+  .altinstr_replacement : AT(ADDR(.altinstr_replacement) - LOAD_OFFSET) {
+	*(.altinstr_replacement)
+  }
   /* .exit.text is discard at runtime, not link time, to deal with references
      from .altinstructions and .eh_frame */
-  .exit.text : { *(.exit.text) }
-  .exit.data : { *(.exit.data) }	
+  .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) { *(.exit.text) }
+  .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) { *(.exit.data) }
   . = ALIGN(4096);
   __initramfs_start = .;
-  .init.ramfs : { *(.init.ramfs) }
+  .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) { *(.init.ramfs) }
   __initramfs_end = .;	
   . = ALIGN(32);
   __per_cpu_start = .;
-  .data.percpu  : { *(.data.percpu) }
+  .data.percpu  : AT(ADDR(.data.percpu) - LOAD_OFFSET) { *(.data.percpu) }
   __per_cpu_end = .;
   . = ALIGN(4096);
   __init_end = .;
 
   . = ALIGN(4096);
   __nosave_begin = .;
-  .data_nosave : { *(.data.nosave) }
+  .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { *(.data.nosave) }
   . = ALIGN(4096);
   __nosave_end = .;
 
diff --git a/arch/x86_64/lib/csum-copy.S b/arch/x86_64/lib/csum-copy.S
--- a/arch/x86_64/lib/csum-copy.S
+++ b/arch/x86_64/lib/csum-copy.S
@@ -188,8 +188,8 @@ csum_partial_copy_generic:
 	source
 	movw (%rdi),%bx
 	adcl %ebx,%eax
-	dest
 	decl %ecx
+	dest
 	movw %bx,(%rsi)
 	leaq 2(%rdi),%rdi
 	leaq 2(%rsi),%rsi
diff --git a/arch/x86_64/lib/delay.c b/arch/x86_64/lib/delay.c
--- a/arch/x86_64/lib/delay.c
+++ b/arch/x86_64/lib/delay.c
@@ -12,12 +12,17 @@
 #include <linux/sched.h>
 #include <linux/delay.h>
 #include <asm/delay.h>
+#include <asm/msr.h>
 
 #ifdef CONFIG_SMP
 #include <asm/smp.h>
 #endif
 
-int x86_udelay_tsc = 0;		/* Delay via TSC */
+int read_current_timer(unsigned long *timer_value)
+{
+	rdtscll(*timer_value);
+	return 0;
+}
 
 void __delay(unsigned long loops)
 {
@@ -34,7 +39,7 @@ void __delay(unsigned long loops)
 
 inline void __const_udelay(unsigned long xloops)
 {
-	__delay(((xloops * cpu_data[_smp_processor_id()].loops_per_jiffy) >> 32) * HZ);
+	__delay(((xloops * cpu_data[raw_smp_processor_id()].loops_per_jiffy) >> 32) * HZ);
 }
 
 void __udelay(unsigned long usecs)
diff --git a/arch/x86_64/mm/Makefile b/arch/x86_64/mm/Makefile
--- a/arch/x86_64/mm/Makefile
+++ b/arch/x86_64/mm/Makefile
@@ -4,7 +4,7 @@
 
 obj-y	 := init.o fault.o ioremap.o extable.o pageattr.o
 obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
-obj-$(CONFIG_DISCONTIGMEM) += numa.o
+obj-$(CONFIG_NUMA) += numa.o
 obj-$(CONFIG_K8_NUMA) += k8topology.o
 obj-$(CONFIG_ACPI_NUMA) += srat.o
 
diff --git a/arch/x86_64/mm/fault.c b/arch/x86_64/mm/fault.c
--- a/arch/x86_64/mm/fault.c
+++ b/arch/x86_64/mm/fault.c
@@ -23,7 +23,6 @@
 #include <linux/vt_kern.h>		/* For unblank_screen() */
 #include <linux/compiler.h>
 #include <linux/module.h>
-#include <linux/kprobes.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
@@ -74,7 +73,7 @@ static noinline int is_prefetch(struct p
 	instr = (unsigned char *)convert_rip_to_linear(current, regs);
 	max_instr = instr + 15;
 
-	if ((regs->cs & 3) != 0 && instr >= (unsigned char *)TASK_SIZE)
+	if (user_mode(regs) && instr >= (unsigned char *)TASK_SIZE)
 		return 0;
 
 	while (scan_more && instr < max_instr) { 
@@ -106,7 +105,7 @@ static noinline int is_prefetch(struct p
 			/* Could check the LDT for lm, but for now it's good
 			   enough to assume that long mode only uses well known
 			   segments or kernel. */
-			scan_more = ((regs->cs & 3) == 0) || (regs->cs == __USER_CS);
+			scan_more = (!user_mode(regs)) || (regs->cs == __USER_CS);
 			break;
 			
 		case 0x60:
@@ -212,9 +211,7 @@ int unhandled_signal(struct task_struct 
 {
 	if (tsk->pid == 1)
 		return 1;
-	/* Warn for strace, but not for gdb */
-	if (!test_ti_thread_flag(tsk->thread_info, TIF_SYSCALL_TRACE) &&
-	    (tsk->ptrace & PT_PTRACED))
+	if (tsk->ptrace & PT_PTRACED)
 		return 0;
 	return (tsk->sighand->action[sig-1].sa.sa_handler == SIG_IGN) ||
 		(tsk->sighand->action[sig-1].sa.sa_handler == SIG_DFL);
@@ -350,7 +347,7 @@ asmlinkage void do_page_fault(struct pt_
 	 * (error_code & 4) == 0, and that the fault was not a
 	 * protection error (error_code & 1) == 0.
 	 */
-	if (unlikely(address >= TASK_SIZE)) {
+	if (unlikely(address >= TASK_SIZE64)) {
 		if (!(error_code & 5) &&
 		      ((address >= VMALLOC_START && address < VMALLOC_END) ||
 		       (address >= MODULES_VADDR && address < MODULES_END))) {
@@ -440,13 +437,13 @@ good_area:
 	 * the fault.
 	 */
 	switch (handle_mm_fault(mm, vma, address, write)) {
-	case 1:
+	case VM_FAULT_MINOR:
 		tsk->min_flt++;
 		break;
-	case 2:
+	case VM_FAULT_MAJOR:
 		tsk->maj_flt++;
 		break;
-	case 0:
+	case VM_FAULT_SIGBUS:
 		goto do_sigbus;
 	default:
 		goto out_of_memory;
diff --git a/arch/x86_64/mm/init.c b/arch/x86_64/mm/init.c
--- a/arch/x86_64/mm/init.c
+++ b/arch/x86_64/mm/init.c
@@ -318,22 +318,30 @@ void zap_low_mappings(void)
 	flush_tlb_all();
 }
 
-#ifndef CONFIG_DISCONTIGMEM
+#ifndef CONFIG_NUMA
 void __init paging_init(void)
 {
 	{
-		unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0};
+		unsigned long zones_size[MAX_NR_ZONES];
+		unsigned long holes[MAX_NR_ZONES];
 		unsigned int max_dma;
 
+		memset(zones_size, 0, sizeof(zones_size));
+		memset(holes, 0, sizeof(holes));
+
 		max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
 
-		if (end_pfn < max_dma)
+		if (end_pfn < max_dma) {
 			zones_size[ZONE_DMA] = end_pfn;
-		else {
+			holes[ZONE_DMA] = e820_hole_size(0, end_pfn);
+		} else {
 			zones_size[ZONE_DMA] = max_dma;
+			holes[ZONE_DMA] = e820_hole_size(0, max_dma);
 			zones_size[ZONE_NORMAL] = end_pfn - max_dma;
+			holes[ZONE_NORMAL] = e820_hole_size(max_dma, end_pfn);
 		}
-		free_area_init(zones_size);
+		free_area_init_node(0, NODE_DATA(0), zones_size,
+                        __pa(PAGE_OFFSET) >> PAGE_SHIFT, holes);
 	}
 	return;
 }
@@ -427,13 +435,16 @@ void __init mem_init(void)
 	reservedpages = 0;
 
 	/* this will put all low memory onto the freelists */
-#ifdef CONFIG_DISCONTIGMEM
+#ifdef CONFIG_NUMA
 	totalram_pages += numa_free_all_bootmem();
 	tmp = 0;
 	/* should count reserved pages here for all nodes */ 
 #else
+
+#ifdef CONFIG_FLATMEM
 	max_mapnr = end_pfn;
 	if (!mem_map) BUG();
+#endif
 
 	totalram_pages += free_all_bootmem();
 
@@ -515,7 +526,7 @@ void free_initrd_mem(unsigned long start
 void __init reserve_bootmem_generic(unsigned long phys, unsigned len) 
 { 
 	/* Should check here against the e820 map to avoid double free */ 
-#ifdef CONFIG_DISCONTIGMEM
+#ifdef CONFIG_NUMA
 	int nid = phys_to_nid(phys);
   	reserve_bootmem_node(NODE_DATA(nid), phys, len);
 #else       		
diff --git a/arch/x86_64/mm/ioremap.c b/arch/x86_64/mm/ioremap.c
--- a/arch/x86_64/mm/ioremap.c
+++ b/arch/x86_64/mm/ioremap.c
@@ -178,7 +178,7 @@ void __iomem * __ioremap(unsigned long p
 	if (phys_addr >= ISA_START_ADDRESS && last_addr < ISA_END_ADDRESS)
 		return (__force void __iomem *)phys_to_virt(phys_addr);
 
-#ifndef CONFIG_DISCONTIGMEM
+#ifdef CONFIG_FLATMEM
 	/*
 	 * Don't allow anybody to remap normal RAM that we're using..
 	 */
diff --git a/arch/x86_64/mm/numa.c b/arch/x86_64/mm/numa.c
--- a/arch/x86_64/mm/numa.c
+++ b/arch/x86_64/mm/numa.c
@@ -36,35 +36,44 @@ int numa_off __initdata;
 int __init compute_hash_shift(struct node *nodes, int numnodes)
 {
 	int i; 
-	int shift = 24;
-	u64 addr;
+	int shift = 20;
+	unsigned long addr,maxend=0;
 	
-	/* When in doubt use brute force. */
-	while (shift < 48) { 
-		memset(memnodemap,0xff,sizeof(*memnodemap) * NODEMAPSIZE); 
-		for (i = 0; i < numnodes; i++) {
-			if (nodes[i].start == nodes[i].end) 
-				continue;
-			for (addr = nodes[i].start; 
-			     addr < nodes[i].end; 
-			     addr += (1UL << shift)) {
-				if (memnodemap[addr >> shift] != 0xff && 
-				    memnodemap[addr >> shift] != i) { 
-					printk(KERN_INFO 
-					    "node %d shift %d addr %Lx conflict %d\n", 
-					       i, shift, addr, memnodemap[addr>>shift]);
-					goto next; 
-				} 
-				memnodemap[addr >> shift] = i; 
+	for (i = 0; i < numnodes; i++)
+		if ((nodes[i].start != nodes[i].end) && (nodes[i].end > maxend))
+				maxend = nodes[i].end;
+
+	while ((1UL << shift) <  (maxend / NODEMAPSIZE))
+		shift++;
+
+	printk (KERN_DEBUG"Using %d for the hash shift. Max adder is %lx \n",
+			shift,maxend);
+	memset(memnodemap,0xff,sizeof(*memnodemap) * NODEMAPSIZE);
+	for (i = 0; i < numnodes; i++) {
+		if (nodes[i].start == nodes[i].end)
+			continue;
+		for (addr = nodes[i].start;
+		     addr < nodes[i].end;
+		     addr += (1UL << shift)) {
+			if (memnodemap[addr >> shift] != 0xff) {
+				printk(KERN_INFO
+	"Your memory is not aligned you need to rebuild your kernel "
+	"with a bigger NODEMAPSIZE shift=%d adder=%lu\n",
+					shift,addr);
+				return -1;
 			} 
+			memnodemap[addr >> shift] = i;
 		} 
-		return shift; 
-	next:
-		shift++; 
 	} 
-	memset(memnodemap,0,sizeof(*memnodemap) * NODEMAPSIZE); 
-	return -1; 
+	return shift;
+}
+
+#ifdef CONFIG_SPARSEMEM
+int early_pfn_to_nid(unsigned long pfn)
+{
+	return phys_to_nid(pfn << PAGE_SHIFT);
 }
+#endif
 
 /* Initialize bootmem allocator for a node */
 void __init setup_node_bootmem(int nodeid, unsigned long start, unsigned long end)
@@ -80,6 +89,7 @@ void __init setup_node_bootmem(int nodei
 	start_pfn = start >> PAGE_SHIFT;
 	end_pfn = end >> PAGE_SHIFT;
 
+	memory_present(nodeid, start_pfn, end_pfn);
 	nodedata_phys = find_e820_area(start, end, pgdat_size); 
 	if (nodedata_phys == -1L) 
 		panic("Cannot find memory pgdat in node %d\n", nodeid);
@@ -116,9 +126,11 @@ void __init setup_node_zones(int nodeid)
 { 
 	unsigned long start_pfn, end_pfn; 
 	unsigned long zones[MAX_NR_ZONES];
+	unsigned long holes[MAX_NR_ZONES];
 	unsigned long dma_end_pfn;
 
 	memset(zones, 0, sizeof(unsigned long) * MAX_NR_ZONES); 
+	memset(holes, 0, sizeof(unsigned long) * MAX_NR_ZONES);
 
 	start_pfn = node_start_pfn(nodeid);
 	end_pfn = node_end_pfn(nodeid);
@@ -129,13 +141,17 @@ void __init setup_node_zones(int nodeid)
 	dma_end_pfn = __pa(MAX_DMA_ADDRESS) >> PAGE_SHIFT; 
 	if (start_pfn < dma_end_pfn) { 
 		zones[ZONE_DMA] = dma_end_pfn - start_pfn;
+		holes[ZONE_DMA] = e820_hole_size(start_pfn, dma_end_pfn);
 		zones[ZONE_NORMAL] = end_pfn - dma_end_pfn; 
+		holes[ZONE_NORMAL] = e820_hole_size(dma_end_pfn, end_pfn);
+
 	} else { 
 		zones[ZONE_NORMAL] = end_pfn - start_pfn; 
+		holes[ZONE_NORMAL] = e820_hole_size(start_pfn, end_pfn);
 	} 
     
 	free_area_init_node(nodeid, NODE_DATA(nodeid), zones,
-			    start_pfn, NULL); 
+			    start_pfn, holes);
 } 
 
 void __init numa_init_array(void)
@@ -243,7 +259,7 @@ void __init numa_initmem_init(unsigned l
 	setup_node_bootmem(0, start_pfn << PAGE_SHIFT, end_pfn << PAGE_SHIFT);
 }
 
-__init void numa_add_cpu(int cpu)
+__cpuinit void numa_add_cpu(int cpu)
 {
 	/* BP is initialized elsewhere */
 	if (cpu) 
diff --git a/arch/x86_64/mm/srat.c b/arch/x86_64/mm/srat.c
--- a/arch/x86_64/mm/srat.c
+++ b/arch/x86_64/mm/srat.c
@@ -20,6 +20,9 @@
 
 static struct acpi_table_slit *acpi_slit;
 
+/* Internal processor count */
+static unsigned int __initdata num_processors = 0;
+
 static nodemask_t nodes_parsed __initdata;
 static nodemask_t nodes_found __initdata;
 static struct node nodes[MAX_NUMNODES] __initdata;
@@ -101,16 +104,18 @@ acpi_numa_processor_affinity_init(struct
 		bad_srat();
 		return;
 	}
-	if (pa->apic_id >= NR_CPUS) {
-		printk(KERN_ERR "SRAT: lapic %u too large.\n",
-		       pa->apic_id);
+	if (num_processors >= NR_CPUS) {
+		printk(KERN_ERR "SRAT: Processor #%d (lapic %u) INVALID. (Max ID: %d).\n",
+			num_processors, pa->apic_id, NR_CPUS);
 		bad_srat();
 		return;
 	}
-	cpu_to_node[pa->apic_id] = node;
+	cpu_to_node[num_processors] = node;
 	acpi_numa = 1;
-	printk(KERN_INFO "SRAT: PXM %u -> APIC %u -> Node %u\n",
-	       pxm, pa->apic_id, node);
+	printk(KERN_INFO "SRAT: PXM %u -> APIC %u -> CPU %u -> Node %u\n",
+	       pxm, pa->apic_id, num_processors, node);
+
+	num_processors++;
 }
 
 /* Callback for parsing of the Proximity Domain <-> Memory Area mappings */
@@ -124,7 +129,6 @@ acpi_numa_memory_affinity_init(struct ac
 
 	if (srat_disabled() || ma->flags.enabled == 0)
 		return;
-	/* hotplug bit is ignored for now */
 	pxm = ma->proximity_domain;
 	node = setup_node(pxm);
 	if (node < 0) {
@@ -134,6 +138,10 @@ acpi_numa_memory_affinity_init(struct ac
 	}
 	start = ma->base_addr_lo | ((u64)ma->base_addr_hi << 32);
 	end = start + (ma->length_lo | ((u64)ma->length_hi << 32));
+	/* It is fine to add this area to the nodes data it will be used later*/
+	if (ma->flags.hot_pluggable == 1)
+		printk(KERN_INFO "SRAT: hot plug zone found %lx - %lx \n",
+				start, end);
 	i = conflicting_nodes(start, end);
 	if (i >= 0) {
 		printk(KERN_ERR
diff --git a/arch/x86_64/pci/k8-bus.c b/arch/x86_64/pci/k8-bus.c
--- a/arch/x86_64/pci/k8-bus.c
+++ b/arch/x86_64/pci/k8-bus.c
@@ -29,7 +29,7 @@ __init static int
 fill_mp_bus_to_cpumask(void)
 {
 	struct pci_dev *nb_dev = NULL;
-	int i, j, printed;
+	int i, j;
 	u32 ldtbus, nid;
 	static int lbnr[3] = {
 		LDT_BUS_NUMBER_REGISTER_0,
@@ -47,31 +47,26 @@ fill_mp_bus_to_cpumask(void)
 			 * if there are no busses hanging off of the current
 			 * ldt link then both the secondary and subordinate
 			 * bus number fields are set to 0.
+			 * 
+			 * RED-PEN
+			 * This is slightly broken because it assumes
+ 			 * HT node IDs == Linux node ids, which is not always
+			 * true. However it is probably mostly true.
 			 */
 			if (!(SECONDARY_LDT_BUS_NUMBER(ldtbus) == 0
 				&& SUBORDINATE_LDT_BUS_NUMBER(ldtbus) == 0)) {
 				for (j = SECONDARY_LDT_BUS_NUMBER(ldtbus);
 				     j <= SUBORDINATE_LDT_BUS_NUMBER(ldtbus);
-				     j++)
-					pci_bus_to_cpumask[j] =
-						node_to_cpumask(NODE_ID(nid));
+				     j++) { 
+					int node = NODE_ID(nid);
+					if (!node_online(node))
+						node = 0;
+					pci_bus_to_node[j] = node;
+				}		
 			}
 		}
 	}
 
-	/* quick sanity check */
-	printed = 0;
-	for (i = 0; i < 256; i++) {
-		if (cpus_empty(pci_bus_to_cpumask[i])) {
-			pci_bus_to_cpumask[i] = CPU_MASK_ALL;
-			if (printed)
-				continue;
-			printk(KERN_ERR
-			       "k8-bus.c: some busses have empty cpu mask\n");
-			printed = 1;
-		}
-	}
-
 	return 0;
 }
 
diff --git a/arch/x86_64/pci/mmconfig.c b/arch/x86_64/pci/mmconfig.c
--- a/arch/x86_64/pci/mmconfig.c
+++ b/arch/x86_64/pci/mmconfig.c
@@ -7,25 +7,50 @@
 
 #include <linux/pci.h>
 #include <linux/init.h>
+#include <linux/acpi.h>
 #include "pci.h"
 
 #define MMCONFIG_APER_SIZE (256*1024*1024)
 
-/* The physical address of the MMCONFIG aperture.  Set from ACPI tables. */
-u32 pci_mmcfg_base_addr;
-
 /* Static virtual mapping of the MMCONFIG aperture */
-char *pci_mmcfg_virt;
+struct mmcfg_virt {
+	struct acpi_table_mcfg_config *cfg;
+	char *virt;
+};
+static struct mmcfg_virt *pci_mmcfg_virt;
+
+static char *get_virt(unsigned int seg, int bus)
+{
+	int cfg_num = -1;
+	struct acpi_table_mcfg_config *cfg;
+
+	while (1) {
+		++cfg_num;
+		if (cfg_num >= pci_mmcfg_config_num) {
+			/* something bad is going on, no cfg table is found. */
+			/* so we fall back to the old way we used to do this */
+			/* and just rely on the first entry to be correct. */
+			return pci_mmcfg_virt[0].virt;
+		}
+		cfg = pci_mmcfg_virt[cfg_num].cfg;
+		if (cfg->pci_segment_group_number != seg)
+			continue;
+		if ((cfg->start_bus_number <= bus) &&
+		    (cfg->end_bus_number >= bus))
+			return pci_mmcfg_virt[cfg_num].virt;
+	}
+}
 
-static inline char *pci_dev_base(unsigned int bus, unsigned int devfn)
+static inline char *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn)
 {
-	return pci_mmcfg_virt + ((bus << 20) | (devfn << 12));
+
+	return get_virt(seg, bus) + ((bus << 20) | (devfn << 12));
 }
 
 static int pci_mmcfg_read(unsigned int seg, unsigned int bus,
 			  unsigned int devfn, int reg, int len, u32 *value)
 {
-	char *addr = pci_dev_base(bus, devfn); 
+	char *addr = pci_dev_base(seg, bus, devfn);
 
 	if (unlikely(!value || (bus > 255) || (devfn > 255) || (reg > 4095)))
 		return -EINVAL;
@@ -48,7 +73,7 @@ static int pci_mmcfg_read(unsigned int s
 static int pci_mmcfg_write(unsigned int seg, unsigned int bus,
 			   unsigned int devfn, int reg, int len, u32 value)
 {
-	char *addr = pci_dev_base(bus,devfn);
+	char *addr = pci_dev_base(seg, bus, devfn);
 
 	if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095)))
 		return -EINVAL;
@@ -75,9 +100,15 @@ static struct pci_raw_ops pci_mmcfg = {
 
 static int __init pci_mmcfg_init(void)
 {
+	int i;
+
 	if ((pci_probe & PCI_PROBE_MMCONF) == 0)
 		return 0;
-	if (!pci_mmcfg_base_addr)
+
+	acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg);
+	if ((pci_mmcfg_config_num == 0) ||
+	    (pci_mmcfg_config == NULL) ||
+	    (pci_mmcfg_config[0].base_address == 0))
 		return 0;
 
 	/* Kludge for now. Don't use mmconfig on AMD systems because
@@ -88,13 +119,22 @@ static int __init pci_mmcfg_init(void)
 		return 0; 
 
 	/* RED-PEN i386 doesn't do _nocache right now */
-	pci_mmcfg_virt = ioremap_nocache(pci_mmcfg_base_addr, MMCONFIG_APER_SIZE);
-	if (!pci_mmcfg_virt) { 
-		printk("PCI: Cannot map mmconfig aperture\n");
+	pci_mmcfg_virt = kmalloc(sizeof(*pci_mmcfg_virt) * pci_mmcfg_config_num, GFP_KERNEL);
+	if (pci_mmcfg_virt == NULL) {
+		printk("PCI: Can not allocate memory for mmconfig structures\n");
 		return 0;
-	}	
+	}
+	for (i = 0; i < pci_mmcfg_config_num; ++i) {
+		pci_mmcfg_virt[i].cfg = &pci_mmcfg_config[i];
+		pci_mmcfg_virt[i].virt = ioremap_nocache(pci_mmcfg_config[i].base_address, MMCONFIG_APER_SIZE);
+		if (!pci_mmcfg_virt[i].virt) {
+			printk("PCI: Cannot map mmconfig aperture for segment %d\n",
+			       pci_mmcfg_config[i].pci_segment_group_number);
+			return 0;
+		}
+		printk(KERN_INFO "PCI: Using MMCONFIG at %x\n", pci_mmcfg_config[i].base_address);
+	}
 
-	printk(KERN_INFO "PCI: Using MMCONFIG at %x\n", pci_mmcfg_base_addr);
 	raw_pci_ops = &pci_mmcfg;
 	pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF;
 
diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig
new file mode 100644
--- /dev/null
+++ b/arch/xtensa/Kconfig
@@ -0,0 +1,262 @@
+# For a description of the syntax of this configuration file,
+# see Documentation/kbuild/config-language.txt.
+
+mainmenu "Linux/Xtensa Kernel Configuration"
+
+config FRAME_POINTER
+	bool
+	default n
+
+config XTENSA
+	bool
+	default y
+	help
+	  Xtensa processors are 32-bit RISC machines designed by Tensilica
+	  primarily for embedded systems.  These processors are both
+	  configurable and extensible.  The Linux port to the Xtensa
+	  architecture supports all processor configurations and extensions,
+	  with reasonable minimum requirements.  The Xtensa Linux project has
+	  a home page at <http://xtensa.sourceforge.net/>.
+
+config UID16
+	bool
+	default n
+
+config RWSEM_XCHGADD_ALGORITHM
+	bool
+	default y
+
+config HAVE_DEC_LOCK
+	bool
+	default y
+
+config GENERIC_HARDIRQS
+	bool
+	default y
+
+source "init/Kconfig"
+
+menu "Processor type and features"
+
+choice
+	prompt "Xtensa Processor Configuration"
+	default XTENSA_CPU_LINUX_BE
+
+config XTENSA_CPU_LINUX_BE
+	bool "linux_be"
+	---help---
+	  The linux_be processor configuration is the baseline Xtensa
+	  configurations included in this kernel and also used by
+	  binutils, gcc, and gdb. It contains no TIE, no coprocessors,
+	  and the following configuration options:
+
+	  Code Density Option                2 Misc Special Registers
+	  NSA/NSAU Instructions              128-bit Data Bus Width
+	  Processor ID                       8K, 2-way I and D Caches
+	  Zero-Overhead Loops                2 Inst Address Break Registers
+	  Big Endian                         2 Data Address Break Registers
+	  64 General-Purpose Registers       JTAG Interface and Trace Port
+	  17 Interrupts                      MMU w/ TLBs and Autorefill
+	  3 Interrupt Levels                 8 Autorefill Ways (I/D TLBs)
+	  3 Timers                           Unaligned Exceptions
+endchoice
+
+config MMU
+	bool
+	default y
+
+config XTENSA_UNALIGNED_USER
+	bool "Unaligned memory access in use space"
+	---help---
+	   The Xtensa architecture currently does not handle unaligned
+	   memory accesses in hardware but through an exception handler.
+	   Per default, unaligned memory accesses are disabled in user space.
+
+	   Say Y here to enable unaligned memory access in user space.
+
+config PREEMPT
+	bool "Preemptible Kernel"
+	---help---
+           This option reduces the latency of the kernel when reacting to
+           real-time or interactive events by allowing a low priority process to
+           be preempted even if it is in kernel mode executing a system call.
+           Unfortunately the kernel code has some race conditions if both
+           CONFIG_SMP and CONFIG_PREEMPT are enabled, so this option is
+           currently disabled if you are building an SMP kernel.
+
+           Say Y here if you are building a kernel for a desktop, embedded
+           or real-time system.  Say N if you are unsure.
+
+config MATH_EMULATION
+	bool "Math emulation"
+	help
+	Can we use information of configuration file?
+
+config HIGHMEM
+	bool "High memory support"
+
+endmenu
+
+menu "Platform options"
+
+choice
+	prompt "Xtensa System Type"
+	default XTENSA_PLATFORM_ISS
+
+config XTENSA_PLATFORM_ISS
+	bool "ISS"
+	help
+	  ISS is an acronym for Tensilica's Instruction Set Simulator.
+
+config XTENSA_PLATFORM_XT2000
+	bool "XT2000"
+	help
+	  XT2000 is the name of Tensilica's feature-rich emulation platform.
+	  This hardware is capable of running a full Linux distribution.
+
+endchoice
+
+
+config XTENSA_CALIBRATE_CCOUNT
+	bool "Auto calibration of the CPU clock rate"
+	---help---
+	  On some platforms (XT2000, for example), the CPU clock rate can
+	  vary.  The frequency can be determined, however, by measuring
+	  against a well known, fixed frequency, such as an UART oscillator.
+
+config XTENSA_CPU_CLOCK
+	int "CPU clock rate [MHz]"
+	depends on !XTENSA_CALIBRATE_CCOUNT
+	default "16"
+
+config GENERIC_CALIBRATE_DELAY
+	bool "Auto calibration of the BogoMIPS value"
+	---help---
+	  The BogoMIPS value can easily be derived from the CPU frequency.
+
+config CMDLINE_BOOL
+	bool "Default bootloader kernel arguments"
+
+config CMDLINE
+	string "Initial kernel command string"
+	depends on CMDLINE_BOOL
+	default "console=ttyS0,38400 root=/dev/ram"
+	help
+	  On some architectures (EBSA110 and CATS), there is currently no way
+	  for the boot loader to pass arguments to the kernel. For these
+	  architectures, you should supply some command-line options at build
+	  time by entering them here. As a minimum, you should specify the
+	  memory size and the root device (e.g., mem=64M root=/dev/nfs).
+
+config SERIAL_CONSOLE
+	bool
+	depends on XTENSA_PLATFORM_ISS
+	default y
+
+config XTENSA_ISS_NETWORK
+	bool
+	depends on XTENSA_PLATFORM_ISS
+	default y
+
+source "mm/Kconfig"
+
+endmenu
+
+menu "Bus options"
+
+config PCI
+	bool "PCI support" if !XTENSA_PLATFORM_ISS
+	depends on !XTENSA_PLATFORM_ISS
+	default y
+	help
+	  Find out whether you have a PCI motherboard. PCI is the name of a
+	  bus system, i.e. the way the CPU talks to the other stuff inside
+	  your box. Other bus systems are ISA, EISA, MicroChannel (MCA) or
+	  VESA. If you have PCI, say Y, otherwise N.
+
+	  The PCI-HOWTO, available from
+	  <http://www.linuxdoc.org/docs.html#howto>, contains valuable
+	  information about which PCI hardware does work under Linux and which
+	  doesn't
+
+source "drivers/pci/Kconfig"
+
+config HOTPLUG
+
+	bool "Support for hot-pluggable devices"
+	---help---
+	Say Y here if you want to plug devices into your computer while
+	the system is running, and be able to use them quickly.  In many
+	cases, the devices can likewise be unplugged at any time too.
+
+	One well known example of this is PCMCIA- or PC-cards, credit-card
+	size devices such as network cards, modems or hard drives which are
+	plugged into slots found on all modern laptop computers.  Another
+	example, used on modern desktops as well as laptops, is USB.
+
+	Enable HOTPLUG and KMOD, and build a modular kernel.  Get agent
+	software (at <http://linux-hotplug.sourceforge.net/>) and install it.
+	Then your kernel will automatically call out to a user mode "policy
+	agent" (/sbin/hotplug) to load modules and set up software needed
+	to use devices as you hotplug them.
+
+source "drivers/pcmcia/Kconfig"
+
+source "drivers/pci/hotplug/Kconfig"
+
+endmenu
+
+menu "Exectuable file formats"
+
+# only elf supported
+config KCORE_ELF
+        bool
+        depends on PROC_FS
+        default y
+        help
+          If you enabled support for /proc file system then the file
+          /proc/kcore will contain the kernel core image in ELF format. This
+          can be used in gdb:
+
+          $ cd /usr/src/linux ; gdb vmlinux /proc/kcore
+
+          This is especially useful if you have compiled the kernel with the
+          "-g" option to preserve debugging information. It is mainly used
+	  for examining kernel data structures on the live kernel.
+
+source "fs/Kconfig.binfmt"
+
+endmenu
+
+source "net/Kconfig"
+
+source "drivers/Kconfig"
+
+source "fs/Kconfig"
+
+menu "Xtensa initrd options"
+	depends on BLK_DEV_INITRD
+
+	config EMBEDDED_RAMDISK
+	bool "Embed root filesystem ramdisk into the kernel"
+
+config EMBEDDED_RAMDISK_IMAGE
+	string "Filename of gziped ramdisk image"
+	depends on EMBEDDED_RAMDISK
+	default "ramdisk.gz"
+	help
+	  This is the filename of the ramdisk image to be built into the
+	  kernel.  Relative pathnames are relative to arch/xtensa/boot/ramdisk/.
+	  The ramdisk image is not part of the kernel distribution; you must
+	  provide one yourself.
+endmenu
+
+source "arch/xtensa/Kconfig.debug"
+
+source "security/Kconfig"
+
+source "crypto/Kconfig"
+
+source "lib/Kconfig"
+
+
diff --git a/arch/xtensa/Kconfig.debug b/arch/xtensa/Kconfig.debug
new file mode 100644
--- /dev/null
+++ b/arch/xtensa/Kconfig.debug
@@ -0,0 +1,7 @@
+menu "Kernel hacking"
+
+source "lib/Kconfig.debug"
+
+endmenu
+
+
diff --git a/arch/xtensa/Makefile b/arch/xtensa/Makefile
new file mode 100644
--- /dev/null
+++ b/arch/xtensa/Makefile
@@ -0,0 +1,104 @@
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 2001 - 2005  Tensilica Inc.
+#
+# This file is included by the global makefile so that you can add your own
+# architecture-specific flags and dependencies. Remember to do have actions
+# for "archclean" and "archdep" for cleaning up and making dependencies for
+# this architecture
+
+# Core configuration.
+# (Use CPU=<xtensa_config> to use another default compiler.)
+
+cpu-$(CONFIG_XTENSA_CPU_LINUX_BE)	:= linux_be
+cpu-$(CONFIG_XTENSA_CPU_LINUX_CUSTOM)	:= linux_custom
+
+CPU = $(cpu-y)
+export CPU
+
+# Platform configuration
+
+platform-$(CONFIG_XTENSA_PLATFORM_XT2000)	:= xt2000
+platform-$(CONFIG_XTENSA_PLATFORM_ISS)		:= iss
+
+PLATFORM = $(platform-y)
+export PLATFORM
+
+CPPFLAGS	+= $(if $(KBUILD_SRC),-I$(srctree)/include/asm-xtensa/)
+CPPFLAGS	+= -Iinclude/asm
+CFLAGS		+= -pipe -mlongcalls
+
+KBUILD_DEFCONFIG := iss_defconfig
+
+# ramdisk/initrd support
+# You need a compressed ramdisk image, named ramdisk.gz in
+# arch/xtensa/boot/ramdisk
+
+core-$(CONFIG_EMBEDDED_RAMDISK)	+= arch/xtensa/boot/ramdisk/
+
+# Test for cross compiling
+
+ifneq ($(CPU),)
+  COMPILE_ARCH = $(shell uname -m)
+
+  ifneq ($(COMPILE_ARCH), xtensa)
+    ifndef CROSS_COMPILE
+      CROSS_COMPILE = xtensa_$(CPU)-
+    endif
+  endif
+endif
+
+#
+
+LIBGCC := $(shell $(CC) $(CFLAGS) -print-libgcc-file-name)
+
+head-y		:= arch/xtensa/kernel/head.o
+core-y		+= arch/xtensa/kernel/ arch/xtensa/mm/
+ifneq ($(PLATFORM),)
+core-y		+= arch/xtensa/platform-$(PLATFORM)/
+endif
+libs-y		+= arch/xtensa/lib/ $(LIBGCC)
+
+boot		:= arch/xtensa/boot
+
+archinc		:= include/asm-xtensa
+
+arch/xtensa/kernel/asm-offsets.s: \
+	arch/xtensa/kernel/asm-offsets.c $(archinc)/.platform
+
+include/asm-xtensa/offsets.h: arch/xtensa/kernel/asm-offsets.s
+	$(call filechk,gen-asm-offsets)
+
+prepare: $(archinc)/.platform $(archinc)/offsets.h
+
+# Update machine cpu and platform symlinks if something which affects
+# them changed.
+
+$(archinc)/.platform: $(wildcard include/config/arch/*.h) include/config/MARKER
+	@echo '  SYMLINK $(archinc)/xtensa/config -> $(archinc)/xtensa/config-$(CPU)'
+	$(Q)mkdir -p $(archinc)
+	$(Q)mkdir -p $(archinc)/xtensa
+	$(Q)ln -fsn $(srctree)/$(archinc)/xtensa/config-$(CPU) $(archinc)/xtensa/config
+	@echo '  SYMLINK $(archinc)/platform -> $(archinc)/platform-$(PLATFORM)'
+	$(Q)ln -fsn $(srctree)/$(archinc)/platform-$(PLATFORM) $(archinc)/platform
+	@touch $@
+
+
+all: zImage
+
+bzImage : zImage
+
+zImage zImage.initrd: vmlinux
+	$(Q)$(MAKE) $(build)=$(boot) $@
+
+CLEAN_FILES	+= arch/xtensa/vmlinux.lds $(archinc)/offset.h \
+		   $(archinc)/platform $(archinc)/xtensa/config \
+		   $(archinc)/.platform
+
+define archhelp
+  @echo '* zImage      - Compressed kernel image (arch/xtensa/boot/images/zImage.*)'
+endef
+
diff --git a/arch/xtensa/boot/Makefile b/arch/xtensa/boot/Makefile
new file mode 100644
--- /dev/null
+++ b/arch/xtensa/boot/Makefile
@@ -0,0 +1,33 @@
+#
+# arch/xtensa/boot/Makefile
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+#
+
+
+CFLAGS 		+= -fno-builtin -Iarch/$(ARCH)/boot/include
+HOSTFLAGS	+= -Iarch/$(ARCH)/boot/include
+
+BIG_ENDIAN	:= $(shell echo -e __XTENSA_EB__ | $(CC) -E - | grep -v "\#")
+
+export CFLAGS
+export AFLAGS
+export BIG_ENDIAN
+
+subdir-y	:= lib
+
+# Subdirs for the boot loader(s)
+
+bootdir-$(CONFIG_XTENSA_PLATFORM_ISS)	 += boot-elf
+bootdir-$(CONFIG_XTENSA_PLATFORM_XT2000) += boot-redboot boot-elf
+
+
+zImage zImage.initrd Image Image.initrd: $(bootdir-y)
+
+$(bootdir-y): $(addprefix $(obj)/,$(subdir-y)) \
+	      $(addprefix $(obj)/,$(host-progs))
+	$(Q)$(MAKE) $(build)=$(obj)/$@ $(MAKECMDGOALS)
+
diff --git a/arch/xtensa/boot/boot-elf/Makefile b/arch/xtensa/boot/boot-elf/Makefile
new file mode 100644
--- /dev/null
+++ b/arch/xtensa/boot/boot-elf/Makefile
@@ -0,0 +1,52 @@
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+
+GZIP = gzip
+GZIP_FLAGS = -v9fc
+
+ifeq ($(BIG_ENDIAN),1)
+OBJCOPY_ARGS    := -O elf32-xtensa-be
+else
+OBJCOPY_ARGS    := -O elf32-xtensa-le
+endif
+
+export OBJCOPY_ARGS
+
+boot-y		:= bootstrap.o
+
+OBJS		:= $(addprefix $(obj)/,$(boot-y))
+
+Image:	vmlinux $(OBJS)
+	$(OBJCOPY) --strip-all -R .comment -R .xt.insn -O binary \
+		vmlinux vmlinux.tmp
+	$(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \
+		--add-section image=vmlinux.tmp \
+		--set-section-flags image=contents,alloc,load,load,data \
+		$(OBJS) $@.tmp
+	$(LD) $(LDFLAGS) $(LDFLAGS_vmlinux) \
+		-T $(srctree)/arch/$(ARCH)/boot/boot-elf/boot.ld \
+		-o arch/$(ARCH)/boot/$@.elf $@.tmp
+	rm -f $@.tmp vmlinux.tmp
+
+Image.initrd:	vmlinux $(OBJS)
+	$(OBJCOPY) --strip-all -R .comment -R .xt.insn -O binary \
+		--add-section .initrd=arch/$(ARCH)/boot/ramdisk \
+		--set-section-flags .initrd=contents,alloc,load,load,data \
+		vmlinux vmlinux.tmp
+	$(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \
+		--add-section image=vmlinux.tmp \
+		--set-section-flags image=contents,alloc,load,load,data \
+		$(OBJS) $@.tmp
+	$(LD) $(LDFLAGS) $(LDFLAGS_vmlinux) \
+		-T $(srctree)/arch/$(ARCH)/boot/boot-elf/boot.ld \
+		-o arch/$(ARCH)/boot/$@.elf $@.tmp
+	rm -f $@.tmp vmlinux.tmp
+
+
+zImage:	Image
+
+zImage.initrd:	Image.initrd
+
diff --git a/arch/xtensa/boot/boot-elf/boot.ld b/arch/xtensa/boot/boot-elf/boot.ld
new file mode 100644
--- /dev/null
+++ b/arch/xtensa/boot/boot-elf/boot.ld
@@ -0,0 +1,71 @@
+OUTPUT_ARCH(xtensa)
+
+SECTIONS
+{
+	.start 0xD0000000 : { *(.start) }
+
+	.text 0xD0000000:
+	{
+		__reloc_start = . ;
+		_text_start = . ;
+		*(.literal .text.literal .text)
+		_text_end = . ;
+	}
+
+	.rodata ALIGN(0x04):
+	{
+		*(.rodata)
+		*(.rodata1)
+	}
+
+	.data ALIGN(0x04):
+	{
+		*(.data)
+		*(.data1)
+		*(.sdata)
+		*(.sdata2)
+		*(.got.plt)
+		*(.got)
+		*(.dynamic)
+	}
+
+	__reloc_end = . ;
+
+	.initrd ALIGN(0x10) :
+	{
+		boot_initrd_start = . ;
+		*(.initrd)
+		boot_initrd_end = .;
+	}
+
+	. = ALIGN(0x10);
+	__image_load = . ;
+	.image 0xd0001000:
+	{
+		_image_start = .;
+		*(image)
+		. = (. + 3) & ~ 3;
+		_image_end = .	;
+	}
+
+
+	.bss ((LOADADDR(.image) + SIZEOF(.image) + 3) & ~ 3):
+	{
+		__bss_start = .;
+		*(.sbss)
+		*(.scommon)
+		*(.dynbss)
+		*(.bss)
+		__bss_end = .;
+	}
+	_end = .;
+	_param_start = .;
+
+	.ResetVector.text 0xfe000020 :
+	{
+		*(.ResetVector.text)
+	}
+
+
+	PROVIDE (end = .);
+}
diff --git a/arch/xtensa/boot/boot-elf/bootstrap.S b/arch/xtensa/boot/boot-elf/bootstrap.S
new file mode 100644
--- /dev/null
+++ b/arch/xtensa/boot/boot-elf/bootstrap.S
@@ -0,0 +1,37 @@
+
+#include <xtensa/config/specreg.h>
+#include <xtensa/config/core.h>
+
+#include <linux/config.h>
+#include <asm/bootparam.h>
+
+
+/* ResetVector
+ */
+	.section        .ResetVector.text, "ax"
+	.global         _ResetVector
+_ResetVector:
+	_j reset
+	.align 4
+RomInitAddr:
+	.word 0xd0001000
+RomBootParam:
+	.word _bootparam
+reset:
+	l32r    a0, RomInitAddr
+	l32r	a2, RomBootParam
+	movi	a3, 0
+	movi	a4, 0
+	jx      a0
+
+	.align 4
+	.section .bootstrap.data, "aw"
+
+	.globl _bootparam
+_bootparam:
+	.short	BP_TAG_FIRST
+	.short	4
+	.long	BP_VERSION
+	.short	BP_TAG_LAST
+	.short	0
+	.long	0
diff --git a/arch/xtensa/boot/boot-redboot/Makefile b/arch/xtensa/boot/boot-redboot/Makefile
new file mode 100644
--- /dev/null
+++ b/arch/xtensa/boot/boot-redboot/Makefile
@@ -0,0 +1,35 @@
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+
+GZIP = gzip
+GZIP_FLAGS = -v9fc
+ifeq ($(BIG_ENDIAN),1)
+OBJCOPY_ARGS 	:= -O elf32-xtensa-be
+else
+OBJCOPY_ARGS 	:= -O elf32-xtensa-le
+endif
+
+LD_ARGS	= -T $(srctree)/$(obj)/boot.ld
+
+boot-y	:= bootstrap.o
+
+OBJS	:= $(addprefix $(obj)/,$(boot-y))
+LIBS	:= arch/xtensa/boot/lib/lib.a arch/xtensa/lib/lib.a
+
+LIBGCC := $(shell $(CC) $(CFLAGS) -print-libgcc-file-name)
+
+zImage: vmlinux $(OBJS) $(LIBS)
+	$(OBJCOPY) --strip-all -R .comment -R .xt.insn -O binary \
+		vmlinux vmlinux.tmp
+	gzip -vf9 vmlinux.tmp
+	$(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \
+		--add-section image=vmlinux.tmp.gz \
+		--set-section-flags image=contents,alloc,load,load,data \
+		$(OBJS) $@.tmp
+	$(LD) $(LD_ARGS) -o $@.elf $@.tmp $(LIBS) -L/xtensa-elf/lib $(LIBGCC)
+	$(OBJCOPY) -S -O binary $@.elf arch/$(ARCH)/boot/$@.redboot
+	rm -f $@.tmp $@.elf vmlinux.tmp.gz
+
diff --git a/arch/xtensa/boot/boot-redboot/boot.ld b/arch/xtensa/boot/boot-redboot/boot.ld
new file mode 100644
--- /dev/null
+++ b/arch/xtensa/boot/boot-redboot/boot.ld
@@ -0,0 +1,66 @@
+OUTPUT_ARCH(xtensa)
+
+SECTIONS
+{
+	.start 0xD0200000 : { *(.start) }
+
+	.text :
+	{
+		__reloc_start = . ;
+		_text_start = . ;
+		*(.literal .text.literal .text)
+		_text_end = . ;
+	}
+
+	.rodata ALIGN(0x04):
+	{
+		*(.rodata)
+		*(.rodata1)
+	}
+
+	.data ALIGN(0x04):
+	{
+		*(.data)
+		*(.data1)
+		*(.sdata)
+		*(.sdata2)
+		*(.got.plt)
+		*(.got)
+		*(.dynamic)
+	}
+
+	__reloc_end = . ;
+
+	.initrd ALIGN(0x10) :
+	{
+		boot_initrd_start = . ;
+		*(.initrd)
+		boot_initrd_end = .;
+	}
+
+	. = ALIGN(0x10);
+	__image_load = . ;
+	.image 0xd0001000: AT(__image_load)
+	{
+		_image_start = .;
+		*(image)
+		. = (. + 3) & ~ 3;
+		_image_end = .	;
+	}
+
+
+	.bss ((LOADADDR(.image) + SIZEOF(.image) + 3) & ~ 3):
+	{
+		__bss_start = .;
+		*(.sbss)
+		*(.scommon)
+		*(.dynbss)
+		*(.bss)
+		__bss_end = .;
+	}
+	_end = .;
+	_param_start = .;
+
+
+	PROVIDE (end = .);
+}
diff --git a/arch/xtensa/boot/boot-redboot/bootstrap.S b/arch/xtensa/boot/boot-redboot/bootstrap.S
new file mode 100644
--- /dev/null
+++ b/arch/xtensa/boot/boot-redboot/bootstrap.S
@@ -0,0 +1,246 @@
+
+#define _ASMLANGUAGE
+#include <xtensa/config/specreg.h>
+#include <xtensa/config/core.h>
+#include <xtensa/cacheasm.h>
+
+	/*
+	 * RB-Data: RedBoot data/bss
+	 * P:	    Boot-Parameters
+	 * L:	    Kernel-Loader
+	 *
+	 * The Linux-Kernel image including the loader must be loaded
+	 * to a position so that the kernel and the boot parameters
+	 * can fit in the space before the load address.
+	 *  ______________________________________________________
+	 * |_RB-Data_|_P_|__________|_L_|___Linux-Kernel___|______|
+	 *                          ^
+	 *                          ^ Load address
+	 *  ______________________________________________________
+	 * |___Linux-Kernel___|_P_|_L_|___________________________|
+	 *
+	 * The loader copies the parameter to the position that will
+	 * be the end of the kernel and itself to the end of the
+	 * parameter list.
+	 */
+
+/* Make sure we have enough space for the 'uncompressor' */
+
+#define STACK_SIZE 32768
+#define HEAP_SIZE (131072*4)
+
+	# a2: Parameter list
+	# a3: Size of parameter list
+
+	.section .start, "ax"
+
+	.globl __start
+	/* this must be the first byte of the loader! */
+__start:
+	entry	sp, 32		# we do not intend to return
+	_call0	_start
+__start_a0:
+	.align 4
+
+	.section .text, "ax"
+	.begin literal_prefix .text
+
+	/* put literals in here! */
+
+	.globl _start
+_start:
+
+	/* 'reset' window registers */
+
+	movi	a4, 1
+	wsr	a4, PS
+	rsync
+
+	rsr	a5, WINDOWBASE
+	ssl	a5
+	sll	a4, a4
+	wsr	a4, WINDOWSTART
+	rsync
+
+	movi	a4, 0x00040000
+	wsr	a4, PS
+	rsync
+
+	/* copy the loader to its address
+	 * Note: The loader itself is a very small piece, so we assume we
+	 *       don't partially overlap. We also assume (even more important)
+	 *	 that the kernel image is out of the way. Usually, when the
+	 *	 load address of this image is not at an arbitrary address,
+	 *	 but aligned to some 10K's we shouldn't overlap.
+	 */
+
+	/* Note: The assembler cannot relax "addi a0, a0, ..." to an
+	   l32r, so we load to a4 first. */
+
+	addi	a4, a0, __start - __start_a0
+	mov	a0, a4
+	movi	a4, __start
+	movi	a5, __reloc_end
+
+	# a0: address where this code has been loaded
+	# a4: compiled address of __start
+	# a5: compiled end address
+
+	mov.n	a7, a0
+	mov.n	a8, a4
+
+1:
+	l32i	a10, a7, 0
+	l32i	a11, a7, 4
+	s32i	a10, a8, 0
+	s32i	a11, a8, 4
+	l32i	a10, a7, 8
+	l32i	a11, a7, 12
+	s32i	a10, a8, 8
+	s32i	a11, a8, 12
+	addi	a8, a8, 16
+	addi	a7, a7, 16
+	blt	a8, a5, 1b
+
+
+	/* We have to flush and invalidate the caches here before we jump. */
+
+#if XCHAL_DCACHE_IS_WRITEBACK
+	dcache_writeback_all  a5, a6
+#endif
+	icache_invalidate_all a5, a6
+
+	movi	a11, _reloc
+	jx	a11
+
+	.globl _reloc
+_reloc:
+
+	/* RedBoot is now at the end of the memory, so we don't have
+	 * to copy the parameter list. Keep the code around; in case
+	 * we need it again. */
+#if 0
+	# a0: load address
+	# a2: start address of parameter list
+	# a3: length of parameter list
+	# a4: __start
+
+	/* copy the parameter list out of the way */
+
+	movi	a6, _param_start
+	add	a3, a2, a3
+2:
+	l32i	a8, a2, 0
+	s32i	a8, a6, 0
+	addi	a2, a2, 4
+	addi	a6, a6, 4
+	blt	a2, a3, 2b
+#endif
+
+	/* clear BSS section */
+	movi	a6, __bss_start
+	movi	a7, __bss_end
+	movi.n	a5, 0
+3:
+	s32i	a5, a6, 0
+	addi	a6, a6, 4
+	blt	a6, a7, 3b
+
+	movi	a5, -16
+	movi	a1, _stack + STACK_SIZE
+	and	a1, a1, a5
+
+	/* Uncompress the kernel */
+
+	# a0: load address
+	# a2: boot parameter
+	# a4: __start
+
+	movi	a3, __image_load
+	sub	a4, a3, a4
+	add	a8, a0, a4
+
+	# a1  Stack
+	# a8(a4)  Load address of the image
+
+	movi	a6, _image_start
+	movi	a10, _image_end
+	movi	a7, 0x1000000
+	sub	a11, a10, a6
+	movi	a9, complen
+	s32i	a11, a9, 0
+
+	movi	a0, 0
+
+	# a6 destination
+	# a7 maximum size of destination
+	# a8 source
+	# a9 ptr to length
+
+	.extern gunzip
+	movi	a4, gunzip
+	beqz	a4, 1f
+
+	callx4	a4
+
+	j	2f
+
+
+	# a6 destination start
+	# a7 maximum size of destination
+	# a8 source start
+	# a9 ptr to length
+	# a10 destination end
+
+1:
+        l32i    a9, a8, 0
+        l32i    a11, a8, 4
+        s32i    a9, a6, 0
+        s32i    a11, a6, 4
+        l32i    a9, a8, 8
+        l32i    a11, a8, 12
+        s32i    a9, a6, 8
+        s32i    a11, a6, 12
+        addi    a6, a6, 16
+        addi    a8, a8, 16
+        blt     a6, a10, 1b
+
+
+	/* jump to the kernel */
+2:
+#if XCHAL_DCACHE_IS_WRITEBACK
+	dcache_writeback_all a5, a6
+#endif
+	icache_invalidate_all a5, a6
+
+	movi	a5, __start
+	movi	a3, boot_initrd_start
+	movi	a4, boot_initrd_end
+	sub	a3, a3, a5
+	sub	a4, a4, a5
+	add	a3, a0, a3
+	add	a4, a0, a4
+
+	# a2  Boot parameter list
+	# a3  initrd_start (virtual load address)
+	# a4  initrd_end   (virtual load address)
+
+	movi	a0, _image_start
+	jx	a0
+
+	.align 16
+	.data
+	.globl avail_ram
+avail_ram:
+	.long	_heap
+	.globl end_avail
+end_avail:
+	.long	_heap + HEAP_SIZE
+
+	.comm _stack, STACK_SIZE
+	.comm _heap, HEAP_SIZE
+
+	.globl end_avail
+	.comm complen, 4
+
+	.end	literal_prefix
diff --git a/arch/xtensa/boot/lib/Makefile b/arch/xtensa/boot/lib/Makefile
new file mode 100644
--- /dev/null
+++ b/arch/xtensa/boot/lib/Makefile
@@ -0,0 +1,17 @@
+#
+# Makefile for some libs needed by zImage.
+#
+
+zlib	:= infblock.c infcodes.c inffast.c inflate.c inftrees.c infutil.c
+
+lib-y	+= $(zlib:.c=.o) zmem.o
+
+EXTRA_CFLAGS	+= -Ilib/zlib_inflate
+
+quiet_cmd_copy_zlib = COPY    $@
+      cmd_copy_zlib = cat $< > $@
+
+$(addprefix $(obj)/,$(zlib)): $(obj)/%: $(srctree)/lib/zlib_inflate/%
+	$(call cmd,copy_zlib)
+
+clean-files	:= $(zlib)
diff --git a/arch/xtensa/boot/lib/zmem.c b/arch/xtensa/boot/lib/zmem.c
new file mode 100644
--- /dev/null
+++ b/arch/xtensa/boot/lib/zmem.c
@@ -0,0 +1,79 @@
+#include <linux/zlib.h>
+
+/* bits taken from ppc */
+
+extern void *avail_ram, *end_avail;
+
+void exit (void)
+{
+  for (;;);
+}
+
+void *zalloc(unsigned size)
+{
+        void *p = avail_ram;
+
+        size = (size + 7) & -8;
+        avail_ram += size;
+        if (avail_ram > end_avail) {
+                //puts("oops... out of memory\n");
+                //pause();
+                exit ();
+        }
+        return p;
+}
+
+#define HEAD_CRC        2
+#define EXTRA_FIELD     4
+#define ORIG_NAME       8
+#define COMMENT         0x10
+#define RESERVED        0xe0
+
+#define DEFLATED        8
+
+void gunzip (void *dst, int dstlen, unsigned char *src, int *lenp)
+{
+	z_stream s;
+	int r, i, flags;
+
+        /* skip header */
+        i = 10;
+        flags = src[3];
+        if (src[2] != DEFLATED || (flags & RESERVED) != 0) {
+                //puts("bad gzipped data\n");
+                exit();
+        }
+        if ((flags & EXTRA_FIELD) != 0)
+                i = 12 + src[10] + (src[11] << 8);
+        if ((flags & ORIG_NAME) != 0)
+                while (src[i++] != 0)
+                        ;
+        if ((flags & COMMENT) != 0)
+                while (src[i++] != 0)
+                        ;
+        if ((flags & HEAD_CRC) != 0)
+                i += 2;
+        if (i >= *lenp) {
+                //puts("gunzip: ran out of data in header\n");
+                exit();
+        }
+
+	s.workspace = zalloc(zlib_inflate_workspacesize());
+        r = zlib_inflateInit2(&s, -MAX_WBITS);
+        if (r != Z_OK) {
+                //puts("inflateInit2 returned "); puthex(r); puts("\n");
+                exit();
+        }
+        s.next_in = src + i;
+        s.avail_in = *lenp - i;
+        s.next_out = dst;
+        s.avail_out = dstlen;
+        r = zlib_inflate(&s, Z_FINISH);
+        if (r != Z_OK && r != Z_STREAM_END) {
+                //puts("inflate returned "); puthex(r); puts("\n");
+                exit();
+        }
+        *lenp = s.next_out - (unsigned char *) dst;
+        zlib_inflateEnd(&s);
+}
+
diff --git a/arch/xtensa/boot/ramdisk/Makefile b/arch/xtensa/boot/ramdisk/Makefile
new file mode 100644
--- /dev/null
+++ b/arch/xtensa/boot/ramdisk/Makefile
@@ -0,0 +1,23 @@
+#
+# Makefile for a ramdisk image
+#
+
+BIG_ENDIAN	:= $(shell echo -e "\#ifdef __XTENSA_EL__\nint little;\n\#else\nint big;\n\#endif" | $(CC) -E -|grep -c big)
+
+ifeq ($(BIG_ENDIAN),1)
+OBJCOPY_ARGS    := -O elf32-xtensa-be
+else
+OBJCOPY_ARGS    := -O elf32-xtensa-le
+endif
+
+obj-y = ramdisk.o
+
+RAMDISK_IMAGE = arch/$(ARCH)/boot/ramdisk/$(CONFIG_EMBEDDED_RAMDISK_IMAGE)
+
+arch/$(ARCH)/boot/ramdisk/ramdisk.o:
+	$(Q)echo -e "dummy:" | $(AS) -o $@;
+	$(Q)$(OBJCOPY) $(OBJCOPY_ARGS)					    \
+		--add-section .initrd=$(RAMDISK_IMAGE)			    \
+		--set-section-flags .initrd=contents,alloc,load,load,data   \
+		arch/$(ARCH)/boot/ramdisk/ramdisk.o $@
+
diff --git a/arch/xtensa/configs/common_defconfig b/arch/xtensa/configs/common_defconfig
new file mode 100644
--- /dev/null
+++ b/arch/xtensa/configs/common_defconfig
@@ -0,0 +1,662 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.11-rc2
+# Tue Mar  1 16:36:53 2005
+#
+# CONFIG_FRAME_POINTER is not set
+CONFIG_XTENSA=y
+# CONFIG_UID16 is not set
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_HAVE_DEC_LOCK=y
+CONFIG_GENERIC_HARDIRQS=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_HOTPLUG is not set
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+# CONFIG_EMBEDDED is not set
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODULE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+
+#
+# Processor type and features
+#
+CONFIG_XTENSA_ARCH_LINUX_BE=y
+# CONFIG_XTENSA_ARCH_LINUX_LE is not set
+# CONFIG_XTENSA_ARCH_LINUX_TEST is not set
+# CONFIG_XTENSA_ARCH_S5 is not set
+# CONFIG_XTENSA_CUSTOM is not set
+CONFIG_MMU=y
+# CONFIG_XTENSA_UNALIGNED_USER is not set
+# CONFIG_PREEMPT is not set
+# CONFIG_MATH_EMULATION is not set
+# CONFIG_HIGHMEM is not set
+
+#
+# Platform options
+#
+# CONFIG_XTENSA_PLATFORM_ISS is not set
+CONFIG_XTENSA_PLATFORM_XT2000=y
+CONFIG_XTENSA_CALIBRATE_CCOUNT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=ttyS0,38400 ip=bootp root=nfs nfsroot=/opt/montavista/pro/devkit/xtensa/linux_be/target"
+
+#
+# Bus options
+#
+CONFIG_PCI=y
+# CONFIG_PCI_LEGACY_PROC is not set
+# CONFIG_PCI_NAMES is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
+#
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Exectuable file formats
+#
+CONFIG_KCORE_ELF=y
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_MISC=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_RAM is not set
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CDROM_PKTCDVD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_SCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Networking support
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_PACKET is not set
+# CONFIG_NETLINK_DEV is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_TUNNEL is not set
+# CONFIG_IP_TCPDIAG is not set
+# CONFIG_IP_TCPDIAG_IPV6 is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_CLK_JIFFIES=y
+# CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set
+# CONFIG_NET_SCH_CLK_CPU is not set
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+# CONFIG_NET_SCH_HFSC is not set
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+# CONFIG_NET_SCH_NETEM is not set
+CONFIG_NET_SCH_INGRESS=m
+CONFIG_NET_QOS=y
+CONFIG_NET_ESTIMATOR=y
+CONFIG_NET_CLS=y
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_ROUTE=y
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+# CONFIG_CLS_U32_PERF is not set
+# CONFIG_NET_CLS_IND is not set
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+# CONFIG_NET_CLS_ACT is not set
+CONFIG_NET_CLS_POLICE=y
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=y
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_MII is not set
+CONFIG_XT2000_SONIC=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_PCI is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+CONFIG_NET_RADIO=y
+
+#
+# Obsolete Wireless cards support (pre-802.11)
+#
+CONFIG_STRIP=m
+
+#
+# Wireless 802.11b ISA/PCI cards support
+#
+CONFIG_HERMES=m
+# CONFIG_PLX_HERMES is not set
+# CONFIG_TMD_HERMES is not set
+# CONFIG_PCI_HERMES is not set
+# CONFIG_ATMEL is not set
+
+#
+# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
+#
+# CONFIG_PRISM54 is not set
+CONFIG_NET_WIRELESS=y
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input I/O drivers
+#
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+# CONFIG_SERIO_SERPORT is not set
+# CONFIG_SERIO_CT82C710 is not set
+# CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_RAW is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# File systems
+#
+# CONFIG_EXT2_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+# CONFIG_PROC_KCORE is not set
+CONFIG_SYSFS=y
+CONFIG_DEVFS_FS=y
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+# CONFIG_DEVPTS_FS_XATTR is not set
+# CONFIG_TMPFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+# CONFIG_EXPORTFS is not set
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+
+#
+# Kernel hacking
+#
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_STACKOVERFLOW is not set
+# CONFIG_DEBUG_SLAB is not set
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_PAGEALLOC is not set
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_KGDB is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC32 is not set
+# CONFIG_LIBCRC32C is not set
diff --git a/arch/xtensa/configs/iss_defconfig b/arch/xtensa/configs/iss_defconfig
new file mode 100644
--- /dev/null
+++ b/arch/xtensa/configs/iss_defconfig
@@ -0,0 +1,531 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.11-rc2
+# Fri Feb 25 19:21:24 2005
+#
+CONFIG_FRAME_POINTER=y
+CONFIG_XTENSA=y
+# CONFIG_UID16 is not set
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_HAVE_DEC_LOCK=y
+CONFIG_GENERIC_HARDIRQS=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_HOTPLUG is not set
+# CONFIG_KOBJECT_UEVENT is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# Processor type and features
+#
+CONFIG_XTENSA_ARCH_LINUX_BE=y
+# CONFIG_XTENSA_ARCH_LINUX_LE is not set
+# CONFIG_XTENSA_ARCH_LINUX_TEST is not set
+# CONFIG_XTENSA_ARCH_S5 is not set
+# CONFIG_XTENSA_CUSTOM is not set
+CONFIG_MMU=y
+# CONFIG_XTENSA_UNALIGNED_USER is not set
+# CONFIG_PREEMPT is not set
+# CONFIG_MATH_EMULATION is not set
+# CONFIG_HIGHMEM is not set
+
+#
+# Platform options
+#
+CONFIG_XTENSA_PLATFORM_ISS=y
+# CONFIG_XTENSA_PLATFORM_XT2000 is not set
+# CONFIG_XTENSA_PLATFORM_ARUBA is not set
+# CONFIG_XTENSA_CALIBRATE_CCOUNT is not set
+CONFIG_XTENSA_CPU_CLOCK=10
+# CONFIG_GENERIC_CALIBRATE_DELAY is not set
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=ttyS0,38400 eth0=tuntap,,tap0 ip=192.168.168.5:192.168.168.1 root=nfs nfsroot=192.168.168.1:/opt/montavista/pro/devkit/xtensa/linux_be/target"
+CONFIG_SERIAL_CONSOLE=y
+CONFIG_XTENSA_ISS_NETWORK=y
+
+#
+# Bus options
+#
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PC-card bridges
+#
+
+#
+# PCI Hotplug Support
+#
+
+#
+# Exectuable file formats
+#
+CONFIG_KCORE_ELF=y
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+# CONFIG_STANDALONE is not set
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_RAM is not set
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CDROM_PKTCDVD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_AS is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_SCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# I2O device support
+#
+
+#
+# Networking support
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+# CONFIG_NETLINK_DEV is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_TUNNEL is not set
+# CONFIG_IP_TCPDIAG is not set
+# CONFIG_IP_TCPDIAG_IPV6 is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_SCTP_HMAC_NONE is not set
+# CONFIG_SCTP_HMAC_SHA1 is not set
+# CONFIG_SCTP_HMAC_MD5 is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_SCH_CLK_JIFFIES is not set
+# CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set
+# CONFIG_NET_SCH_CLK_CPU is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_NETDEVICES is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input I/O drivers
+#
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+# CONFIG_SERIO is not set
+# CONFIG_SERIO_I8042 is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+
+#
+# Watchdog Device Drivers
+#
+CONFIG_SOFT_WATCHDOG=y
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB_ARCH_HAS_HCD is not set
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# File systems
+#
+# CONFIG_EXT2_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_QUOTA is not set
+# CONFIG_DNOTIFY is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+CONFIG_DEVFS_FS=y
+CONFIG_DEVFS_MOUNT=y
+# CONFIG_DEVFS_DEBUG is not set
+# CONFIG_DEVPTS_FS_XATTR is not set
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_XATTR is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V4 is not set
+CONFIG_NFS_DIRECTIO=y
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+# CONFIG_EXPORTFS is not set
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+
+#
+# Kernel hacking
+#
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_STACKOVERFLOW is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_PAGEALLOC is not set
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_KGDB is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC32 is not set
+# CONFIG_LIBCRC32C is not set
diff --git a/arch/xtensa/kernel/Makefile b/arch/xtensa/kernel/Makefile
new file mode 100644
--- /dev/null
+++ b/arch/xtensa/kernel/Makefile
@@ -0,0 +1,18 @@
+#
+# Makefile for the Linux/Xtensa kernel.
+#
+
+extra-y := head.o vmlinux.lds
+
+
+obj-y := align.o entry.o irq.o coprocessor.o process.o ptrace.o semaphore.o  \
+	 setup.o signal.o syscalls.o time.o traps.o vectors.o platform.o  \
+	 pci-dma.o
+
+## windowspill.o
+
+obj-$(CONFIG_KGDB) += xtensa-stub.o
+obj-$(CONFIG_PCI) += pci.o
+obj-$(CONFIG_MODULES) += xtensa_ksyms.o module.o
+
+
diff --git a/arch/xtensa/kernel/align.S b/arch/xtensa/kernel/align.S
new file mode 100644
--- /dev/null
+++ b/arch/xtensa/kernel/align.S
@@ -0,0 +1,459 @@
+/*
+ * arch/xtensa/kernel/align.S
+ *
+ * Handle unalignment exceptions in kernel space.
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file "COPYING" in the main directory of
+ * this archive for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica, Inc.
+ *
+ * Rewritten by Chris Zankel <chris@zankel.net>
+ *
+ * Based on work from Joe Taylor <joe@tensilica.com, joetylr@yahoo.com>
+ * and Marc Gauthier <marc@tensilica.com, marc@alimni.uwaterloo.ca>
+ */
+
+#include <linux/linkage.h>
+#include <asm/ptrace.h>
+#include <asm/ptrace.h>
+#include <asm/current.h>
+#include <asm/offsets.h>
+#include <asm/pgtable.h>
+#include <asm/processor.h>
+#include <asm/page.h>
+#include <asm/thread_info.h>
+
+#if XCHAL_UNALIGNED_LOAD_EXCEPTION || XCHAL_UNALIGNED_STORE_EXCEPTION
+
+/*  First-level exception handler for unaligned exceptions.
+ *
+ *  Note: This handler works only for kernel exceptions.  Unaligned user
+ *        access should get a seg fault.
+ */
+
+/* Big and little endian 16-bit values are located in
+ * different halves of a register.  HWORD_START helps to
+ * abstract the notion of extracting a 16-bit value from a
+ * register.
+ * We also have to define new shifting instructions because
+ * lsb and msb are on 'opposite' ends in a register for
+ * different endian machines.
+ *
+ * Assume a memory region in ascending address:
+ *   	0 1 2 3|4 5 6 7
+ *
+ * When loading one word into a register, the content of that register is:
+ *  LE	3 2 1 0, 7 6 5 4
+ *  BE  0 1 2 3, 4 5 6 7
+ *
+ * Masking the bits of the higher/lower address means:
+ *  LE  X X 0 0, 0 0 X X
+ *  BE	0 0 X X, X X 0 0
+ *
+ * Shifting to higher/lower addresses, means:
+ *  LE  shift left / shift right
+ *  BE  shift right / shift left
+ *
+ * Extracting 16 bits from a 32 bit reg. value to higher/lower address means:
+ *  LE  mask 0 0 X X / shift left
+ *  BE  shift left / mask 0 0 X X
+ */
+
+#define UNALIGNED_USER_EXCEPTION
+
+#if XCHAL_HAVE_BE
+
+#define HWORD_START	16
+#define	INSN_OP0	28
+#define	INSN_T		24
+#define	INSN_OP1	16
+
+.macro __src_b	r, w0, w1;	src	\r, \w0, \w1;	.endm
+.macro __ssa8	r;		ssa8b	\r;		.endm
+.macro __ssa8r	r;		ssa8l	\r;		.endm
+.macro __sh	r, s;		srl	\r, \s;		.endm
+.macro __sl	r, s;		sll	\r, \s;		.endm
+.macro __exth	r, s;		extui	\r, \s, 0, 16;	.endm
+.macro __extl	r, s;		slli	\r, \s, 16;	.endm
+
+#else
+
+#define HWORD_START	0
+#define	INSN_OP0	0
+#define	INSN_T		4
+#define	INSN_OP1	12
+
+.macro __src_b	r, w0, w1;	src	\r, \w1, \w0;	.endm
+.macro __ssa8	r;		ssa8l	\r;		.endm
+.macro __ssa8r	r;		ssa8b	\r;		.endm
+.macro __sh	r, s;		sll	\r, \s;		.endm
+.macro __sl	r, s;		srl	\r, \s;		.endm
+.macro __exth	r, s;		slli	\r, \s, 16;	.endm
+.macro __extl	r, s;		extui	\r, \s, 0, 16;	.endm
+
+#endif
+
+/*
+ *	xxxx xxxx = imm8 field
+ *	     yyyy = imm4 field
+ *	     ssss = s field
+ *	     tttt = t field
+ *
+ *	       		 16		    0
+ *		          -------------------
+ *	L32I.N		  yyyy ssss tttt 1000
+ *	S32I.N	          yyyy ssss tttt 1001
+ *
+ *	       23			    0
+ *		-----------------------------
+ *	res	          0000           0010
+ *	L16UI	xxxx xxxx 0001 ssss tttt 0010
+ *	L32I	xxxx xxxx 0010 ssss tttt 0010
+ *	XXX	          0011 ssss tttt 0010
+ *	XXX	          0100 ssss tttt 0010
+ *	S16I	xxxx xxxx 0101 ssss tttt 0010
+ *	S32I	xxxx xxxx 0110 ssss tttt 0010
+ *	XXX	          0111 ssss tttt 0010
+ *	XXX	          1000 ssss tttt 0010
+ *	L16SI	xxxx xxxx 1001 ssss tttt 0010
+ *	XXX	          1010           0010
+ *      **L32AI	xxxx xxxx 1011 ssss tttt 0010 unsupported
+ *	XXX	          1100           0010
+ *	XXX	          1101           0010
+ *	XXX	          1110           0010
+ *	**S32RI	xxxx xxxx 1111 ssss tttt 0010 unsupported
+ *		-----------------------------
+ *                           ^         ^    ^
+ *    sub-opcode (NIBBLE_R) -+         |    |
+ *       t field (NIBBLE_T) -----------+    |
+ *  major opcode (NIBBLE_OP0) --------------+
+ */
+
+#define OP0_L32I_N	0x8		/* load immediate narrow */
+#define OP0_S32I_N	0x9		/* store immediate narrow */
+#define OP1_SI_MASK	0x4		/* OP1 bit set for stores */
+#define OP1_SI_BIT	2		/* OP1 bit number for stores */
+
+#define OP1_L32I	0x2
+#define OP1_L16UI	0x1
+#define OP1_L16SI	0x9
+#define OP1_L32AI	0xb
+
+#define OP1_S32I	0x6
+#define OP1_S16I	0x5
+#define OP1_S32RI	0xf
+
+/*
+ * Entry condition:
+ *
+ *   a0:	trashed, original value saved on stack (PT_AREG0)
+ *   a1:	a1
+ *   a2:	new stack pointer, original in DEPC
+ *   a3:	dispatch table
+ *   depc:	a2, original value saved on stack (PT_DEPC)
+ *   excsave_1:	a3
+ *
+ *   PT_DEPC >= VALID_DOUBLE_EXCEPTION_ADDRESS: double exception, DEPC
+ *	     <  VALID_DOUBLE_EXCEPTION_ADDRESS: regular exception
+ */
+
+
+ENTRY(fast_unaligned)
+
+	/* Note: We don't expect the address to be aligned on a word
+	 *       boundary. After all, the processor generated that exception
+	 *       and it would be a hardware fault.
+	 */
+
+	/* Save some working register */
+
+	s32i	a4, a2, PT_AREG4
+	s32i	a5, a2, PT_AREG5
+	s32i	a6, a2, PT_AREG6
+	s32i	a7, a2, PT_AREG7
+	s32i	a8, a2, PT_AREG8
+
+	rsr	a0, DEPC
+	xsr	a3, EXCSAVE_1
+	s32i	a0, a2, PT_AREG2
+	s32i	a3, a2, PT_AREG3
+
+	/* Keep value of SAR in a0 */
+
+	rsr	a0, SAR
+	rsr	a8, EXCVADDR		# load unaligned memory address
+
+	/* Now, identify one of the following load/store instructions.
+	 *
+	 * The only possible danger of a double exception on the
+	 * following l32i instructions is kernel code in vmalloc
+	 * memory. The processor was just executing at the EPC_1
+	 * address, and indeed, already fetched the instruction.  That
+	 * guarantees a TLB mapping, which hasn't been replaced by
+	 * this unaligned exception handler that uses only static TLB
+	 * mappings. However, high-level interrupt handlers might
+	 * modify TLB entries, so for the generic case, we register a
+	 * TABLE_FIXUP handler here, too.
+	 */
+
+	/* a3...a6 saved on stack, a2 = SP */
+
+	/* Extract the instruction that caused the unaligned access. */
+
+	rsr	a7, EPC_1	# load exception address
+	movi	a3, ~3
+	and	a3, a3, a7	# mask lower bits
+
+	l32i	a4, a3, 0	# load 2 words
+	l32i	a5, a3, 4
+
+	__ssa8	a7
+	__src_b	a4, a4, a5	# a4 has the instruction
+
+	/* Analyze the instruction (load or store?). */
+
+	extui	a5, a4, INSN_OP0, 4	# get insn.op0 nibble
+
+#if XCHAL_HAVE_NARROW
+	_beqi	a5, OP0_L32I_N, .Lload	# L32I.N, jump
+	addi	a6, a5, -OP0_S32I_N
+	_beqz	a6, .Lstore		# S32I.N, do a store
+#endif
+	/* 'store indicator bit' not set, jump */
+	_bbci.l	a4, OP1_SI_BIT + INSN_OP1, .Lload
+
+	/* Store: Jump to table entry to get the value in the source register.*/
+
+.Lstore:movi	a5, .Lstore_table	# table
+	extui	a6, a4, INSN_T, 4	# get source register
+	addx8	a5, a6, a5
+	jx	a5			# jump into table
+
+	/* Invalid instruction, CRITICAL! */
+.Linvalid_instruction_load:
+	j	.Linvalid_instruction
+
+	/* Load: Load memory address. */
+
+.Lload: movi	a3, ~3
+	and	a3, a3, a8		# align memory address
+
+	__ssa8	a8
+#ifdef UNALIGNED_USER_EXCEPTION
+	addi	a3, a3, 8
+	l32e	a5, a3, -8
+	l32e	a6, a3, -4
+#else
+	l32i	a5, a3, 0
+	l32i	a6, a3, 4
+#endif
+	__src_b	a3, a5, a6		# a3 has the data word
+
+#if XCHAL_HAVE_NARROW
+	addi	a7, a7, 2		# increment PC (assume 16-bit insn)
+
+	extui	a5, a4, INSN_OP0, 4
+	_beqi	a5, OP0_L32I_N, 1f	# l32i.n: jump
+
+	addi	a7, a7, 1
+#else
+	addi	a7, a7, 3
+#endif
+
+	extui	a5, a4, INSN_OP1, 4
+	_beqi	a5, OP1_L32I, 1f	# l32i: jump
+
+	extui	a3, a3, 0, 16		# extract lower 16 bits
+	_beqi	a5, OP1_L16UI, 1f
+	addi	a5, a5, -OP1_L16SI
+	_bnez	a5, .Linvalid_instruction_load
+
+	/* sign extend value */
+
+	slli	a3, a3, 16
+	srai	a3, a3, 16
+
+	/* Set target register. */
+
+1:
+
+#if XCHAL_HAVE_LOOP
+	rsr	a3, LEND		# check if we reached LEND
+	bne	a7, a3, 1f
+	rsr	a3, LCOUNT		# and LCOUNT != 0
+	beqz	a3, 1f
+	addi	a3, a3, -1		# decrement LCOUNT and set
+	rsr	a7, LBEG		# set PC to LBEGIN
+	wsr	a3, LCOUNT
+#endif
+
+1:	wsr	a7, EPC_1		# skip load instruction
+	extui	a4, a4, INSN_T, 4	# extract target register
+	movi	a5, .Lload_table
+	addx8	a4, a4, a5
+	jx	a4			# jump to entry for target register
+
+	.align	8
+.Lload_table:
+	s32i	a3, a2, PT_AREG0;	_j .Lexit;	.align 8
+	mov	a1, a3;			_j .Lexit;	.align 8 # fishy??
+	s32i	a3, a2, PT_AREG2;	_j .Lexit;	.align 8
+	s32i	a3, a2, PT_AREG3;	_j .Lexit;	.align 8
+	s32i	a3, a2, PT_AREG4;	_j .Lexit;	.align 8
+	s32i	a3, a2, PT_AREG5;	_j .Lexit;	.align 8
+	s32i	a3, a2, PT_AREG6;	_j .Lexit;	.align 8
+	s32i	a3, a2, PT_AREG7;	_j .Lexit;	.align 8
+	s32i	a3, a2, PT_AREG8;	_j .Lexit;	.align 8
+	mov	a9, a3		;	_j .Lexit;	.align 8
+	mov	a10, a3		;	_j .Lexit;	.align 8
+	mov	a11, a3		;	_j .Lexit;	.align 8
+	mov	a12, a3		;	_j .Lexit;	.align 8
+	mov	a13, a3		;	_j .Lexit;	.align 8
+	mov	a14, a3		;	_j .Lexit;	.align 8
+	mov	a15, a3		;	_j .Lexit;	.align 8
+
+.Lstore_table:
+	l32i	a3, a2, PT_AREG0;	_j 1f;	.align 8
+	mov	a3, a1;			_j 1f;	.align 8	# fishy??
+	l32i	a3, a2, PT_AREG2;	_j 1f;	.align 8
+	l32i	a3, a2, PT_AREG3;	_j 1f;	.align 8
+	l32i	a3, a2, PT_AREG4;	_j 1f;	.align 8
+	l32i	a3, a2, PT_AREG5;	_j 1f;	.align 8
+	l32i	a3, a2, PT_AREG6;	_j 1f;	.align 8
+	l32i	a3, a2, PT_AREG7;	_j 1f;	.align 8
+	l32i	a3, a2, PT_AREG8;	_j 1f;	.align 8
+	mov	a3, a9		;	_j 1f;	.align 8
+	mov	a3, a10		;	_j 1f;	.align 8
+	mov	a3, a11		;	_j 1f;	.align 8
+	mov	a3, a12		;	_j 1f;	.align 8
+	mov	a3, a13		;	_j 1f;	.align 8
+	mov	a3, a14		;	_j 1f;	.align 8
+	mov	a3, a15		;	_j 1f;	.align 8
+
+1: 	# a7: instruction pointer, a4: instruction, a3: value
+
+	movi	a6, 0			# mask: ffffffff:00000000
+
+#if XCHAL_HAVE_NARROW
+	addi	a7, a7, 2		# incr. PC,assume 16-bit instruction
+
+	extui	a5, a4, INSN_OP0, 4	# extract OP0
+	addi	a5, a5, -OP0_S32I_N
+	_beqz	a5, 1f			# s32i.n: jump
+
+	addi	a7, a7, 1		# increment PC, 32-bit instruction
+#else
+	addi	a7, a7, 3		# increment PC, 32-bit instruction
+#endif
+
+	extui	a5, a4, INSN_OP1, 4	# extract OP1
+	_beqi	a5, OP1_S32I, 1f	# jump if 32 bit store
+	_bnei	a5, OP1_S16I, .Linvalid_instruction_store
+
+	movi	a5, -1
+	__extl	a3, a3			# get 16-bit value
+	__exth	a6, a5			# get 16-bit mask ffffffff:ffff0000
+
+	/* Get memory address */
+
+1:
+#if XCHAL_HAVE_LOOP
+	rsr	a3, LEND		# check if we reached LEND
+	bne	a7, a3, 1f
+	rsr	a3, LCOUNT		# and LCOUNT != 0
+	beqz	a3, 1f
+	addi	a3, a3, -1		# decrement LCOUNT and set
+	rsr	a7, LBEG		# set PC to LBEGIN
+	wsr	a3, LCOUNT
+#endif
+
+1:	wsr	a7, EPC_1		# skip store instruction
+	movi	a4, ~3
+	and	a4, a4, a8		# align memory address
+
+	/* Insert value into memory */
+
+	movi	a5, -1			# mask: ffffffff:XXXX0000
+#ifdef UNALIGNED_USER_EXCEPTION
+	addi	a4, a4, 8
+#endif
+
+	__ssa8r a8
+	__src_b	a7, a5, a6		# lo-mask  F..F0..0 (BE) 0..0F..F (LE)
+	__src_b	a6, a6, a5		# hi-mask  0..0F..F (BE) F..F0..0 (LE)
+#ifdef UNALIGNED_USER_EXCEPTION
+	l32e	a5, a4, -8
+#else
+	l32i	a5, a4, 0		# load lower address word
+#endif
+	and	a5, a5, a7		# mask
+	__sh	a7, a3 			# shift value
+	or	a5, a5, a7		# or with original value
+#ifdef UNALIGNED_USER_EXCEPTION
+	s32e	a5, a4, -8
+	l32e	a7, a4, -4
+#else
+	s32i	a5, a4, 0		# store
+	l32i	a7, a4, 4		# same for upper address word
+#endif
+	__sl	a5, a3
+	and	a6, a7, a6
+	or	a6, a6, a5
+#ifdef UNALIGNED_USER_EXCEPTION
+	s32e	a6, a4, -4
+#else
+	s32i	a6, a4, 4
+#endif
+
+	/* Done. restore stack and return */
+
+.Lexit:
+	movi	a4, 0
+	rsr	a3, EXCSAVE_1
+	s32i	a4, a3, EXC_TABLE_FIXUP
+
+	/* Restore working register */
+
+	l32i	a7, a2, PT_AREG7
+	l32i	a6, a2, PT_AREG6
+	l32i	a5, a2, PT_AREG5
+	l32i	a4, a2, PT_AREG4
+	l32i	a3, a2, PT_AREG3
+
+	/* restore SAR and return */
+
+	wsr	a0, SAR
+	l32i	a0, a2, PT_AREG0
+	l32i	a2, a2, PT_AREG2
+	rfe
+
+	/* We cannot handle this exception. */
+
+	.extern _kernel_exception
+.Linvalid_instruction_store:
+.Linvalid_instruction:
+
+	/* Restore a4...a8 and SAR, set SP, and jump to default exception. */
+
+	l32i	a8, a2, PT_AREG8
+	l32i	a7, a2, PT_AREG7
+	l32i	a6, a2, PT_AREG6
+	l32i	a5, a2, PT_AREG5
+	l32i	a4, a2, PT_AREG4
+	wsr	a0, SAR
+	mov	a1, a2
+
+	rsr	a0, PS
+        bbsi.l  a2, PS_UM_SHIFT, 1f     # jump if user mode
+
+	movi	a0, _kernel_exception
+	jx	a0
+
+1:	movi	a0, _user_exception
+	jx	a0
+
+
+#endif /* XCHAL_UNALIGNED_LOAD_EXCEPTION || XCHAL_UNALIGNED_STORE_EXCEPTION */
+
diff --git a/arch/xtensa/kernel/asm-offsets.c b/arch/xtensa/kernel/asm-offsets.c
new file mode 100644
--- /dev/null
+++ b/arch/xtensa/kernel/asm-offsets.c
@@ -0,0 +1,93 @@
+/*
+ * arch/xtensa/kernel/asm-offsets.c
+ *
+ * Generates definitions from c-type structures used by assembly sources.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2005 Tensilica Inc.
+ *
+ * Chris Zankel <chris@zankel.net>
+ */
+
+#include <asm/processor.h>
+
+#include <linux/types.h>
+#include <linux/stddef.h>
+#include <linux/thread_info.h>
+#include <linux/ptrace.h>
+#include <asm/ptrace.h>
+#include <asm/processor.h>
+#include <asm/uaccess.h>
+
+#define DEFINE(sym, val) asm volatile("\n->" #sym " %0 " #val : : "i" (val))
+#define BLANK() asm volatile("\n->" : : )
+
+int main(void)
+{
+	/* struct pt_regs */
+	DEFINE(PT_PC, offsetof (struct pt_regs, pc));
+	DEFINE(PT_PS, offsetof (struct pt_regs, ps));
+	DEFINE(PT_DEPC, offsetof (struct pt_regs, depc));
+	DEFINE(PT_EXCCAUSE, offsetof (struct pt_regs, exccause));
+	DEFINE(PT_EXCVADDR, offsetof (struct pt_regs, excvaddr));
+	DEFINE(PT_DEBUGCAUSE, offsetof (struct pt_regs, debugcause));
+	DEFINE(PT_WMASK, offsetof (struct pt_regs, wmask));
+	DEFINE(PT_LBEG, offsetof (struct pt_regs, lbeg));
+	DEFINE(PT_LEND, offsetof (struct pt_regs, lend));
+	DEFINE(PT_LCOUNT, offsetof (struct pt_regs, lcount));
+	DEFINE(PT_SAR, offsetof (struct pt_regs, sar));
+	DEFINE(PT_SYSCALL, offsetof (struct pt_regs, syscall));
+	DEFINE(PT_AREG, offsetof (struct pt_regs, areg[0]));
+	DEFINE(PT_AREG0, offsetof (struct pt_regs, areg[0]));
+	DEFINE(PT_AREG1, offsetof (struct pt_regs, areg[1]));
+	DEFINE(PT_AREG2, offsetof (struct pt_regs, areg[2]));
+	DEFINE(PT_AREG3, offsetof (struct pt_regs, areg[3]));
+	DEFINE(PT_AREG4, offsetof (struct pt_regs, areg[4]));
+	DEFINE(PT_AREG5, offsetof (struct pt_regs, areg[5]));
+	DEFINE(PT_AREG6, offsetof (struct pt_regs, areg[6]));
+	DEFINE(PT_AREG7, offsetof (struct pt_regs, areg[7]));
+	DEFINE(PT_AREG8, offsetof (struct pt_regs, areg[8]));
+	DEFINE(PT_AREG9, offsetof (struct pt_regs, areg[9]));
+	DEFINE(PT_AREG10, offsetof (struct pt_regs, areg[10]));
+	DEFINE(PT_AREG11, offsetof (struct pt_regs, areg[11]));
+	DEFINE(PT_AREG12, offsetof (struct pt_regs, areg[12]));
+	DEFINE(PT_AREG13, offsetof (struct pt_regs, areg[13]));
+	DEFINE(PT_AREG14, offsetof (struct pt_regs, areg[14]));
+	DEFINE(PT_AREG15, offsetof (struct pt_regs, areg[15]));
+	DEFINE(PT_WINDOWBASE, offsetof (struct pt_regs, windowbase));
+	DEFINE(PT_WINDOWSTART, offsetof(struct pt_regs, windowstart));
+	DEFINE(PT_SIZE, sizeof(struct pt_regs));
+	DEFINE(PT_AREG_END, offsetof (struct pt_regs, areg[XCHAL_NUM_AREGS]));
+	DEFINE(PT_USER_SIZE, offsetof(struct pt_regs, areg[XCHAL_NUM_AREGS]));
+	BLANK();
+
+	/* struct task_struct */
+	DEFINE(TASK_PTRACE, offsetof (struct task_struct, ptrace));
+	DEFINE(TASK_MM, offsetof (struct task_struct, mm));
+	DEFINE(TASK_ACTIVE_MM, offsetof (struct task_struct, active_mm));
+	DEFINE(TASK_PID, offsetof (struct task_struct, pid));
+	DEFINE(TASK_THREAD, offsetof (struct task_struct, thread));
+	DEFINE(TASK_THREAD_INFO, offsetof (struct task_struct, thread_info));
+	DEFINE(TASK_STRUCT_SIZE, sizeof (struct task_struct));
+	BLANK();
+
+	/* struct thread_info (offset from start_struct) */
+	DEFINE(THREAD_RA, offsetof (struct task_struct, thread.ra));
+	DEFINE(THREAD_SP, offsetof (struct task_struct, thread.sp));
+	DEFINE(THREAD_CP_SAVE, offsetof (struct task_struct, thread.cp_save));
+	DEFINE(THREAD_CURRENT_DS, offsetof (struct task_struct, thread.current_ds));
+	BLANK();
+
+	/* struct mm_struct */
+	DEFINE(MM_USERS, offsetof(struct mm_struct, mm_users));
+	DEFINE(MM_PGD, offsetof (struct mm_struct, pgd));
+	DEFINE(MM_CONTEXT, offsetof (struct mm_struct, context));
+	BLANK();
+	DEFINE(PT_SINGLESTEP_BIT, PT_SINGLESTEP_BIT);
+	return 0;
+}
+
+
diff --git a/arch/xtensa/kernel/coprocessor.S b/arch/xtensa/kernel/coprocessor.S
new file mode 100644
--- /dev/null
+++ b/arch/xtensa/kernel/coprocessor.S
@@ -0,0 +1,201 @@
+/*
+ * arch/xtensa/kernel/coprocessor.S
+ *
+ * Xtensa processor configuration-specific table of coprocessor and
+ * other custom register layout information.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2003 - 2005 Tensilica Inc.
+ *
+ * Marc Gauthier <marc@tensilica.com> <marc@alumni.uwaterloo.ca>
+ */
+
+/*
+ * This module contains a table that describes the layout of the various
+ * custom registers and states associated with each coprocessor, as well
+ * as those not associated with any coprocessor ("extra state").
+ * This table is included with core dumps and is available via the ptrace
+ * interface, allowing the layout of such register/state information to
+ * be modified in the kernel without affecting the debugger.  Each
+ * register or state is identified using a 32-bit "libdb target number"
+ * assigned when the Xtensa processor is generated.
+ */
+
+#include <linux/config.h>
+#include <linux/linkage.h>
+#include <asm/processor.h>
+
+#if XCHAL_HAVE_CP
+
+#define CP_LAST ((XCHAL_CP_MAX - 1) * COPROCESSOR_INFO_SIZE)
+
+ENTRY(release_coprocessors)
+
+	entry	a1, 16
+						# a2: task
+	movi	a3, 1 << XCHAL_CP_MAX 		# a3: coprocessor-bit
+	movi	a4, coprocessor_info+CP_LAST	# a4: owner-table
+						# a5: tmp
+	movi	a6, 0				# a6: 0
+	rsil	a7, LOCKLEVEL			# a7: PS
+
+1:	/* Check if task is coprocessor owner of coprocessor[i]. */
+
+	l32i	a5, a4, COPROCESSOR_INFO_OWNER
+	srli	a3, a3, 1
+	beqz	a3, 1f
+	addi	a4, a4, -8
+	beq	a2, a5, 1b
+
+	/* Found an entry: Clear entry CPENABLE bit to disable CP. */
+
+	rsr	a5, CPENABLE
+	s32i	a6, a4, COPROCESSOR_INFO_OWNER
+	xor	a5, a3, a5
+	wsr	a5, CPENABLE
+
+	bnez	a3, 1b
+
+1:	wsr	a7, PS
+	rsync
+	retw
+
+
+ENTRY(disable_coprocessor)
+	entry	sp, 16
+	rsil	a7, LOCKLEVEL
+	rsr	a3, CPENABLE
+	movi	a4, 1
+	ssl	a2
+	sll	a4, a4
+	and	a4, a3, a4
+	xor	a3, a3, a4
+	wsr	a3, CPENABLE
+	wsr	a7, PS
+	rsync
+	retw
+
+ENTRY(enable_coprocessor)
+	entry	sp, 16
+	rsil	a7, LOCKLEVEL
+	rsr	a3, CPENABLE
+	movi	a4, 1
+	ssl	a2
+	sll	a4, a4
+	or	a3, a3, a4
+	wsr	a3, CPENABLE
+	wsr	a7, PS
+	rsync
+	retw
+
+#endif
+
+ENTRY(save_coprocessor_extra)
+	entry	sp, 16
+	xchal_extra_store_funcbody
+	retw
+
+ENTRY(restore_coprocessor_extra)
+	entry	sp, 16
+	xchal_extra_load_funcbody
+	retw
+
+ENTRY(save_coprocessor_registers)
+	entry	sp, 16
+	xchal_cpi_store_funcbody
+	retw
+
+ENTRY(restore_coprocessor_registers)
+	entry	sp, 16
+	xchal_cpi_load_funcbody
+	retw
+
+
+/*
+ *  The Xtensa compile-time HAL (core.h) XCHAL_*_SA_CONTENTS_LIBDB macros
+ *  describe the contents of coprocessor & extra save areas in terms of
+ *  undefined CONTENTS_LIBDB_{SREG,UREG,REGF} macros.  We define these
+ *  latter macros here; they expand into a table of the format we want.
+ *  The general format is:
+ *
+ *	CONTENTS_LIBDB_SREG(libdbnum, offset, size, align, rsv1, name, sregnum,
+ *			    bitmask, rsv2, rsv3)
+ *	CONTENTS_LIBDB_UREG(libdbnum, offset, size, align, rsv1, name, uregnum,
+ *			    bitmask, rsv2, rsv3)
+ *	CONTENTS_LIBDB_REGF(libdbnum, offset, size, align, rsv1, name, index,
+ *			    numentries, contentsize, regname_base,
+ *			    regfile_name, rsv2, rsv3)
+ *
+ *  For this table, we only care about the <libdbnum>, <offset> and <size>
+ *  fields.
+ */
+
+/*  Map all XCHAL CONTENTS macros to the reg_entry asm macro defined below:  */
+
+#define CONTENTS_LIBDB_SREG(libdbnum,offset,size,align,rsv1,name,sregnum,     \
+			    bitmask, rsv2, rsv3)			      \
+		reg_entry libdbnum, offset, size ;
+#define CONTENTS_LIBDB_UREG(libdbnum,offset,size,align,rsv1,name,uregnum,     \
+			    bitmask, rsv2, rsv3)			      \
+		reg_entry libdbnum, offset, size ;
+#define CONTENTS_LIBDB_REGF(libdbnum, offset, size, align, rsv1, name, index, \
+			    numentries, contentsize, regname_base,	      \
+			    regfile_name, rsv2, rsv3)			      \
+		reg_entry libdbnum, offset, size ;
+
+/* A single table entry: */
+	.macro	reg_entry	libdbnum, offset, size
+	 .ifne	(__last_offset-(__last_group_offset+\offset))
+	  /* padding entry */
+	  .word	(0xFC000000+__last_offset-(__last_group_offset+\offset))
+	 .endif
+	 .word	\libdbnum				/* actual entry */
+	 .set	__last_offset, __last_group_offset+\offset+\size
+	.endm	/* reg_entry */
+
+
+/* Table entry that marks the beginning of a group (coprocessor or "extra"): */
+	.macro	reg_group	cpnum, num_entries, align
+	 .set	__last_group_offset, (__last_offset + \align- 1) & -\align
+	 .ifne	\num_entries
+	  .word	0xFD000000+(\cpnum<<16)+\num_entries
+	 .endif
+	.endm	/* reg_group */
+
+/*
+ * Register info tables.
+ */
+
+	.section .rodata, "a"
+	.globl	_xtensa_reginfo_tables
+	.globl	_xtensa_reginfo_table_size
+	.align	4
+_xtensa_reginfo_table_size:
+	.word	_xtensa_reginfo_table_end - _xtensa_reginfo_tables
+
+_xtensa_reginfo_tables:
+	.set	__last_offset, 0
+	reg_group 0xFF, XCHAL_EXTRA_SA_CONTENTS_LIBDB_NUM, XCHAL_EXTRA_SA_ALIGN
+	XCHAL_EXTRA_SA_CONTENTS_LIBDB
+	reg_group 0, XCHAL_CP0_SA_CONTENTS_LIBDB_NUM, XCHAL_CP0_SA_ALIGN
+	XCHAL_CP0_SA_CONTENTS_LIBDB
+	reg_group 1, XCHAL_CP1_SA_CONTENTS_LIBDB_NUM, XCHAL_CP1_SA_ALIGN
+	XCHAL_CP1_SA_CONTENTS_LIBDB
+	reg_group 2, XCHAL_CP2_SA_CONTENTS_LIBDB_NUM, XCHAL_CP2_SA_ALIGN
+	XCHAL_CP2_SA_CONTENTS_LIBDB
+	reg_group 3, XCHAL_CP3_SA_CONTENTS_LIBDB_NUM, XCHAL_CP3_SA_ALIGN
+	XCHAL_CP3_SA_CONTENTS_LIBDB
+	reg_group 4, XCHAL_CP4_SA_CONTENTS_LIBDB_NUM, XCHAL_CP4_SA_ALIGN
+	XCHAL_CP4_SA_CONTENTS_LIBDB
+	reg_group 5, XCHAL_CP5_SA_CONTENTS_LIBDB_NUM, XCHAL_CP5_SA_ALIGN
+	XCHAL_CP5_SA_CONTENTS_LIBDB
+	reg_group 6, XCHAL_CP6_SA_CONTENTS_LIBDB_NUM, XCHAL_CP6_SA_ALIGN
+	XCHAL_CP6_SA_CONTENTS_LIBDB
+	reg_group 7, XCHAL_CP7_SA_CONTENTS_LIBDB_NUM, XCHAL_CP7_SA_ALIGN
+	XCHAL_CP7_SA_CONTENTS_LIBDB
+	.word	0xFC000000	/* invalid register number,marks end of table*/
+_xtensa_reginfo_table_end:
+
diff --git a/arch/xtensa/kernel/entry.S b/arch/xtensa/kernel/entry.S
new file mode 100644
--- /dev/null
+++ b/arch/xtensa/kernel/entry.S
@@ -0,0 +1,1996 @@
+/*
+ * arch/xtensa/kernel/entry.S
+ *
+ * Low-level exception handling
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2004-2005 by Tensilica Inc.
+ *
+ * Chris Zankel <chris@zankel.net>
+ *
+ */
+
+#include <linux/linkage.h>
+#include <asm/offsets.h>
+#include <asm/processor.h>
+#include <asm/thread_info.h>
+#include <asm/uaccess.h>
+#include <asm/unistd.h>
+#include <asm/ptrace.h>
+#include <asm/current.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/signal.h>
+#include <xtensa/coreasm.h>
+
+/* Unimplemented features. */
+
+#undef SIGNAL_HANDLING_IN_DOUBLE_EXCEPTION
+#undef KERNEL_STACK_OVERFLOW_CHECK
+#undef PREEMPTIBLE_KERNEL
+#undef ALLOCA_EXCEPTION_IN_IRAM
+
+/* Not well tested.
+ *
+ * - fast_coprocessor
+ */
+
+/*
+ * Macro to find first bit set in WINDOWBASE from the left + 1
+ *
+ * 100....0 -> 1
+ * 010....0 -> 2
+ * 000....1 -> WSBITS
+ */
+
+	.macro ffs_ws bit mask
+
+#if XCHAL_HAVE_NSA
+	nsau    \bit, \mask			# 32-WSBITS ... 31 (32 iff 0)
+	addi    \bit, \bit, WSBITS - 32 + 1   	# uppest bit set -> return 1
+#else
+	movi    \bit, WSBITS
+#if WSBITS > 16
+	_bltui  \mask, 0x10000, 99f
+	addi    \bit, \bit, -16
+	extui   \mask, \mask, 16, 16
+#endif
+#if WSBITS > 8
+99:	_bltui  \mask, 0x100, 99f
+	addi    \bit, \bit, -8
+	srli    \mask, \mask, 8
+#endif
+99:	_bltui  \mask, 0x10, 99f
+	addi    \bit, \bit, -4
+	srli    \mask, \mask, 4
+99:	_bltui  \mask, 0x4, 99f
+	addi    \bit, \bit, -2
+	srli    \mask, \mask, 2
+99:	_bltui  \mask, 0x2, 99f
+	addi    \bit, \bit, -1
+99:
+
+#endif
+	.endm
+
+/* ----------------- DEFAULT FIRST LEVEL EXCEPTION HANDLERS ----------------- */
+
+/*
+ * First-level exception handler for user exceptions.
+ * Save some special registers, extra states and all registers in the AR
+ * register file that were in use in the user task, and jump to the common
+ * exception code.
+ * We save SAR (used to calculate WMASK), and WB and WS (we don't have to
+ * save them for kernel exceptions).
+ *
+ * Entry condition for user_exception:
+ *
+ *   a0:	trashed, original value saved on stack (PT_AREG0)
+ *   a1:	a1
+ *   a2:	new stack pointer, original value in depc
+ *   a3:	dispatch table
+ *   depc:	a2, original value saved on stack (PT_DEPC)
+ *   excsave1:	a3
+ *
+ *   PT_DEPC >= VALID_DOUBLE_EXCEPTION_ADDRESS: double exception, DEPC
+ *	     <  VALID_DOUBLE_EXCEPTION_ADDRESS: regular exception
+ *
+ * Entry condition for _user_exception:
+ *
+ *   a0-a3 and depc have been saved to PT_AREG0...PT_AREG3 and PT_DEPC
+ *   excsave has been restored, and
+ *   stack pointer (a1) has been set.
+ *
+ * Note: _user_exception might be at an odd adress. Don't use call0..call12
+ */
+
+ENTRY(user_exception)
+
+	/* Save a2, a3, and depc, restore excsave_1 and set SP. */
+
+	xsr	a3, EXCSAVE_1
+	rsr	a0, DEPC
+	s32i	a1, a2, PT_AREG1
+	s32i	a0, a2, PT_AREG2
+	s32i	a3, a2, PT_AREG3
+	mov	a1, a2
+
+	.globl _user_exception
+_user_exception:
+
+	/* Save SAR and turn off single stepping */
+
+	movi	a2, 0
+	rsr	a3, SAR
+	wsr	a2, ICOUNTLEVEL
+	s32i	a3, a1, PT_SAR
+
+	/* Rotate ws so that the current windowbase is at bit0. */
+	/* Assume ws = xxwww1yyyy. Rotate ws right, so that a2 = yyyyxxwww1 */
+
+	rsr	a2, WINDOWBASE
+	rsr	a3, WINDOWSTART
+	ssr	a2
+	s32i	a2, a1, PT_WINDOWBASE
+	s32i	a3, a1, PT_WINDOWSTART
+	slli	a2, a3, 32-WSBITS
+	src	a2, a3, a2
+	srli	a2, a2, 32-WSBITS
+	s32i	a2, a1, PT_WMASK	# needed for restoring registers
+
+	/* Save only live registers. */
+
+	_bbsi.l	a2, 1, 1f
+	s32i	a4, a1, PT_AREG4
+	s32i	a5, a1, PT_AREG5
+	s32i	a6, a1, PT_AREG6
+	s32i	a7, a1, PT_AREG7
+	_bbsi.l	a2, 2, 1f
+	s32i	a8, a1, PT_AREG8
+	s32i	a9, a1, PT_AREG9
+	s32i	a10, a1, PT_AREG10
+	s32i	a11, a1, PT_AREG11
+	_bbsi.l	a2, 3, 1f
+	s32i	a12, a1, PT_AREG12
+	s32i	a13, a1, PT_AREG13
+	s32i	a14, a1, PT_AREG14
+	s32i	a15, a1, PT_AREG15
+	_bnei	a2, 1, 1f		# only one valid frame?
+
+	/* Only one valid frame, skip saving regs. */
+
+	j	2f
+
+	/* Save the remaining registers.
+	 * We have to save all registers up to the first '1' from
+	 * the right, except the current frame (bit 0).
+	 * Assume a2 is:  001001000110001
+	 * All regiser frames starting from the top fiel to the marked '1'
+	 * must be saved.
+	 */
+
+1:	addi	a3, a2, -1		# eliminate '1' in bit 0: yyyyxxww0
+	neg	a3, a3			# yyyyxxww0 -> YYYYXXWW1+1
+	and	a3, a3, a2		# max. only one bit is set
+
+	/* Find number of frames to save */
+
+	ffs_ws	a0, a3			# number of frames to the '1' from left
+
+	/* Store information into WMASK:
+	 * bits 0..3: xxx1 masked lower 4 bits of the rotated windowstart,
+	 * bits 4...: number of valid 4-register frames
+	 */
+
+	slli	a3, a0, 4		# number of frames to save in bits 8..4
+	extui	a2, a2, 0, 4		# mask for the first 16 registers
+	or	a2, a3, a2
+	s32i	a2, a1, PT_WMASK	# needed when we restore the reg-file
+
+	/* Save 4 registers at a time */
+
+1:	rotw	-1
+	s32i	a0, a5, PT_AREG_END - 16
+	s32i	a1, a5, PT_AREG_END - 12
+	s32i	a2, a5, PT_AREG_END - 8
+	s32i	a3, a5, PT_AREG_END - 4
+	addi	a0, a4, -1
+	addi	a1, a5, -16
+	_bnez	a0, 1b
+
+	/* WINDOWBASE still in SAR! */
+
+	rsr	a2, SAR			# original WINDOWBASE
+	movi	a3, 1
+	ssl	a2
+	sll	a3, a3
+	wsr	a3, WINDOWSTART		# set corresponding WINDOWSTART bit
+	wsr	a2, WINDOWBASE		# and WINDOWSTART
+	rsync
+
+	/* We are back to the original stack pointer (a1) */
+
+2:
+#if XCHAL_EXTRA_SA_SIZE
+
+	/* For user exceptions, save the extra state into the user's TCB.
+	 * Note: We must assume that xchal_extra_store_funcbody destroys a2..a15
+	 */
+
+	GET_CURRENT(a2,a1)
+	addi	a2, a2, THREAD_CP_SAVE
+	xchal_extra_store_funcbody
+#endif
+
+	/* Now, jump to the common exception handler. */
+
+	j	common_exception
+
+
+/*
+ * First-level exit handler for kernel exceptions
+ * Save special registers and the live window frame.
+ * Note: Even though we changes the stack pointer, we don't have to do a
+ *	 MOVSP here, as we do that when we return from the exception.
+ *	 (See comment in the kernel exception exit code)
+ *
+ * Entry condition for kernel_exception:
+ *
+ *   a0:	trashed, original value saved on stack (PT_AREG0)
+ *   a1:	a1
+ *   a2:	new stack pointer, original in DEPC
+ *   a3:	dispatch table
+ *   depc:	a2, original value saved on stack (PT_DEPC)
+ *   excsave_1:	a3
+ *
+ *   PT_DEPC >= VALID_DOUBLE_EXCEPTION_ADDRESS: double exception, DEPC
+ *	     <  VALID_DOUBLE_EXCEPTION_ADDRESS: regular exception
+ *
+ * Entry condition for _kernel_exception:
+ *
+ *   a0-a3 and depc have been saved to PT_AREG0...PT_AREG3 and PT_DEPC
+ *   excsave has been restored, and
+ *   stack pointer (a1) has been set.
+ *
+ * Note: _kernel_exception might be at an odd adress. Don't use call0..call12
+ */
+
+ENTRY(kernel_exception)
+
+	/* Save a0, a2, a3, DEPC and set SP. */
+
+	xsr	a3, EXCSAVE_1		# restore a3, excsave_1
+	rsr	a0, DEPC		# get a2
+	s32i	a1, a2, PT_AREG1
+	s32i	a0, a2, PT_AREG2
+	s32i	a3, a2, PT_AREG3
+	mov	a1, a2
+
+	.globl _kernel_exception
+_kernel_exception:
+
+	/* Save SAR and turn off single stepping */
+
+	movi	a2, 0
+	rsr	a3, SAR
+	wsr	a2, ICOUNTLEVEL
+	s32i	a3, a1, PT_SAR
+
+	/* Rotate ws so that the current windowbase is at bit0. */
+	/* Assume ws = xxwww1yyyy. Rotate ws right, so that a2 = yyyyxxwww1 */
+
+	rsr	a2, WINDOWBASE		# don't need to save these, we only
+	rsr	a3, WINDOWSTART		# need shifted windowstart: windowmask
+	ssr	a2
+	slli	a2, a3, 32-WSBITS
+	src	a2, a3, a2
+	srli	a2, a2, 32-WSBITS
+	s32i	a2, a1, PT_WMASK	# needed for kernel_exception_exit
+
+	/* Save only the live window-frame */
+
+	_bbsi.l	a2, 1, 1f
+	s32i	a4, a1, PT_AREG4
+	s32i	a5, a1, PT_AREG5
+	s32i	a6, a1, PT_AREG6
+	s32i	a7, a1, PT_AREG7
+	_bbsi.l	a2, 2, 1f
+	s32i	a8, a1, PT_AREG8
+	s32i	a9, a1, PT_AREG9
+	s32i	a10, a1, PT_AREG10
+	s32i	a11, a1, PT_AREG11
+	_bbsi.l	a2, 3, 1f
+	s32i	a12, a1, PT_AREG12
+	s32i	a13, a1, PT_AREG13
+	s32i	a14, a1, PT_AREG14
+	s32i	a15, a1, PT_AREG15
+
+1:
+
+#ifdef KERNEL_STACK_OVERFLOW_CHECK
+
+	/*  Stack overflow check, for debugging  */
+	extui	a2, a1, TASK_SIZE_BITS,XX
+	movi	a3, SIZE??
+	_bge	a2, a3, out_of_stack_panic
+
+#endif
+
+/*
+ * This is the common exception handler.
+ * We get here from the user exception handler or simply by falling through
+ * from the kernel exception handler.
+ * Save the remaining special registers, switch to kernel mode, and jump
+ * to the second-level exception handler.
+ *
+ */
+
+common_exception:
+
+	/* Save EXCVADDR, DEBUGCAUSE, and PC, and clear LCOUNT */
+
+	rsr	a2, DEBUGCAUSE
+	rsr	a3, EPC_1
+	s32i	a2, a1, PT_DEBUGCAUSE
+	s32i	a3, a1, PT_PC
+
+	rsr	a3, EXCVADDR
+	movi	a2, 0
+	s32i	a3, a1, PT_EXCVADDR
+	xsr	a2, LCOUNT
+	s32i	a2, a1, PT_LCOUNT
+
+	/* It is now save to restore the EXC_TABLE_FIXUP variable. */
+
+	rsr	a0, EXCCAUSE
+	movi	a3, 0
+	rsr	a2, EXCSAVE_1
+	s32i	a0, a1, PT_EXCCAUSE
+	s32i	a3, a2, EXC_TABLE_FIXUP
+
+	/* All unrecoverable states are saved on stack, now, and a1 is valid,
+	 * so we can allow exceptions and interrupts (*) again.
+	 * Set PS(EXCM = 0, UM = 0, RING = 0, OWB = 0, WOE = 1, INTLEVEL = X)
+	 *
+	 * (*) We only allow interrupts if PS.INTLEVEL was not set to 1 before
+	 *     (interrupts disabled) and if this exception is not an interrupt.
+	 */
+
+	rsr	a3, PS
+	addi	a0, a0, -4
+	movi	a2, 1
+	extui	a3, a3, 0, 1		# a3 = PS.INTLEVEL[0]
+	moveqz	a3, a2, a0		# a3 = 1 iff interrupt exception
+	movi	a2, PS_WOE_MASK
+	or	a3, a3, a2
+	rsr	a0, EXCCAUSE
+	xsr	a3, PS
+
+	s32i	a3, a1, PT_PS		# save ps
+
+	/* Save LBEG, LEND */
+
+	rsr	a2, LBEG
+	rsr	a3, LEND
+	s32i	a2, a1, PT_LBEG
+	s32i	a3, a1, PT_LEND
+
+	/* Go to second-level dispatcher. Set up parameters to pass to the
+	 * exception handler and call the exception handler.
+	 */
+
+	movi	a4, exc_table
+	mov	a6, a1			# pass stack frame
+	mov	a7, a0			# pass EXCCAUSE
+	addx4	a4, a0, a4
+	l32i	a4, a4, EXC_TABLE_DEFAULT		# load handler
+
+	/* Call the second-level handler */
+
+	callx4	a4
+
+	/* Jump here for exception exit */
+
+common_exception_return:
+
+	/* Jump if we are returning from kernel exceptions. */
+
+1:	l32i	a3, a1, PT_PS
+	_bbsi.l	a3, PS_UM_SHIFT, 2f
+	j	kernel_exception_exit
+
+	/* Specific to a user exception exit:
+	 * We need to check some flags for signal handling and rescheduling,
+	 * and have to restore WB and WS, extra states, and all registers
+	 * in the register file that were in use in the user task.
+	 */
+
+2:	wsr	a3, PS		/* disable interrupts */
+
+	/* Check for signals (keep interrupts disabled while we read TI_FLAGS)
+	 * Note: PS.INTLEVEL = 0, PS.EXCM = 1
+	 */
+
+	GET_THREAD_INFO(a2,a1)
+	l32i	a4, a2, TI_FLAGS
+
+	/* Enable interrupts again.
+	 * Note: When we get here, we certainly have handled any interrupts.
+	 *       (Hint: There is only one user exception frame on stack)
+	 */
+
+	movi	a3, PS_WOE_MASK
+
+	_bbsi.l	a4, TIF_NEED_RESCHED, 3f
+	_bbci.l	a4, TIF_SIGPENDING, 4f
+
+#ifndef SIGNAL_HANDLING_IN_DOUBLE_EXCEPTION
+	l32i	a4, a1, PT_DEPC
+	bgeui	a4, VALID_DOUBLE_EXCEPTION_ADDRESS, 4f
+#endif
+
+	/* Reenable interrupts and call do_signal() */
+
+	wsr	a3, PS
+	movi	a4, do_signal	# int do_signal(struct pt_regs*, sigset_t*)
+	mov	a6, a1
+	movi	a7, 0
+	callx4	a4
+	j	1b
+
+3:	/* Reenable interrupts and reschedule */
+
+	wsr	a3, PS
+	movi	a4, schedule	# void schedule (void)
+	callx4	a4
+	j	1b
+
+	/* Restore the state of the task and return from the exception. */
+
+
+	/* If we are returning from a user exception, and the process
+	 * to run next has PT_SINGLESTEP set, we want to setup
+	 * ICOUNT and ICOUNTLEVEL to step one instruction.
+	 * PT_SINGLESTEP is set by sys_ptrace (ptrace.c)
+	 */
+
+4:	/* a2 holds GET_CURRENT(a2,a1)  */
+
+	l32i	a3, a2, TI_TASK
+	l32i	a3, a3, TASK_PTRACE
+	bbci.l	a3, PT_SINGLESTEP_BIT, 1f # jump if single-step flag is not set
+
+	movi	a3, -2			# PT_SINGLESTEP flag is set,
+	movi	a4, 1			# icountlevel of 1 means it won't
+	wsr	a3, ICOUNT		# start counting until after rfe
+	wsr	a4, ICOUNTLEVEL		# so setup icount & icountlevel.
+	isync
+
+1:
+
+#if XCHAL_EXTRA_SA_SIZE
+
+	/* For user exceptions, restore the extra state from the user's TCB. */
+
+	/* Note: a2 still contains GET_CURRENT(a2,a1) */
+	addi	a2, a2, THREAD_CP_SAVE
+	xchal_extra_load_funcbody
+
+	/* We must assume that xchal_extra_store_funcbody destroys
+	 * registers a2..a15.  FIXME, this list can eventually be
+	 * reduced once real register requirements of the macro are
+	 * finalized. */
+
+#endif /* XCHAL_EXTRA_SA_SIZE */
+
+
+	/* Switch to the user thread WINDOWBASE. Save SP temporarily in DEPC */
+
+	l32i	a2, a1, PT_WINDOWBASE
+	l32i	a3, a1, PT_WINDOWSTART
+	wsr	a1, DEPC		# use DEPC as temp storage
+	wsr	a3, WINDOWSTART		# restore WINDOWSTART
+	ssr	a2			# preserve user's WB in the SAR
+	wsr	a2, WINDOWBASE		# switch to user's saved WB
+	rsync
+	rsr	a1, DEPC		# restore stack pointer
+	l32i	a2, a1, PT_WMASK	# register frames saved (in bits 4...9)
+	rotw	-1			# we restore a4..a7
+	_bltui	a6, 16, 1f		# only have to restore current window?
+
+	/* The working registers are a0 and a3.  We are restoring to
+	 * a4..a7.  Be careful not to destroy what we have just restored.
+	 * Note: wmask has the format YYYYM:
+	 *       Y: number of registers saved in groups of 4
+	 *       M: 4 bit mask of first 16 registers
+	 */
+
+	mov	a2, a6
+	mov	a3, a5
+
+2:	rotw	-1			# a0..a3 become a4..a7
+	addi	a3, a7, -4*4		# next iteration
+	addi	a2, a6, -16		# decrementing Y in WMASK
+	l32i	a4, a3, PT_AREG_END + 0
+	l32i	a5, a3, PT_AREG_END + 4
+	l32i	a6, a3, PT_AREG_END + 8
+	l32i	a7, a3, PT_AREG_END + 12
+	_bgeui	a2, 16, 2b
+
+	/* Clear unrestored registers (don't leak anything to user-land */
+
+1:	rsr	a0, WINDOWBASE
+	rsr	a3, SAR
+	sub	a3, a0, a3
+	beqz	a3, 2f
+	extui	a3, a3, 0, WBBITS
+
+1:	rotw	-1
+	addi	a3, a7, -1
+	movi	a4, 0
+	movi	a5, 0
+	movi	a6, 0
+	movi	a7, 0
+	bgei	a3, 1, 1b
+
+	/* We are back were we were when we started.
+	 * Note: a2 still contains WMASK (if we've returned to the original
+	 *	 frame where we had loaded a2), or at least the lower 4 bits
+	 *	 (if we have restored WSBITS-1 frames).
+	 */
+
+2:	j	common_exception_exit
+
+	/* This is the kernel exception exit.
+	 * We avoided to do a MOVSP when we entered the exception, but we
+	 * have to do it here.
+	 */
+
+kernel_exception_exit:
+
+	/* Disable interrupts (a3 holds PT_PS) */
+
+	wsr	a3, PS
+
+#ifdef PREEMPTIBLE_KERNEL
+
+#ifdef CONFIG_PREEMPT
+
+	/*
+	 * Note: We've just returned from a call4, so we have
+	 * at least 4 addt'l regs.
+	 */
+
+	/* Check current_thread_info->preempt_count */
+
+	GET_THREAD_INFO(a2)
+	l32i	a3, a2, TI_PREEMPT
+	bnez	a3, 1f
+
+	l32i	a2, a2, TI_FLAGS
+
+1:
+
+#endif
+
+#endif
+
+	/* Check if we have to do a movsp.
+	 *
+	 * We only have to do a movsp if the previous window-frame has
+	 * been spilled to the *temporary* exception stack instead of the
+	 * task's stack. This is the case if the corresponding bit in
+	 * WINDOWSTART for the previous window-frame was set before
+	 * (not spilled) but is zero now (spilled).
+	 * If this bit is zero, all other bits except the one for the
+	 * current window frame are also zero. So, we can use a simple test:
+	 * 'and' WINDOWSTART and WINDOWSTART-1:
+	 *
+	 *  (XXXXXX1[0]* - 1) AND XXXXXX1[0]* = XXXXXX0[0]*
+	 *
+	 * The result is zero only if one bit was set.
+	 *
+	 * (Note: We might have gone through several task switches before
+	 *        we come back to the current task, so WINDOWBASE might be
+	 *        different from the time the exception occurred.)
+	 */
+
+	/* Test WINDOWSTART before and after the exception.
+	 * We actually have WMASK, so we only have to test if it is 1 or not.
+	 */
+
+	l32i	a2, a1, PT_WMASK
+	_beqi	a2, 1, common_exception_exit	# Spilled before exception,jump
+
+	/* Test WINDOWSTART now. If spilled, do the movsp */
+
+	rsr     a3, WINDOWSTART
+	addi	a0, a3, -1
+	and     a3, a3, a0
+	_bnez	a3, common_exception_exit
+
+	/* Do a movsp (we returned from a call4, so we have at least a0..a7) */
+
+	addi    a0, a1, -16
+	l32i    a3, a0, 0
+	l32i    a4, a0, 4
+	s32i    a3, a1, PT_SIZE+0
+	s32i    a4, a1, PT_SIZE+4
+	l32i    a3, a0, 8
+	l32i    a4, a0, 12
+	s32i    a3, a1, PT_SIZE+8
+	s32i    a4, a1, PT_SIZE+12
+
+	/* Common exception exit.
+	 * We restore the special register and the current window frame, and
+	 * return from the exception.
+	 *
+	 * Note: We expect a2 to hold PT_WMASK
+	 */
+
+common_exception_exit:
+
+	_bbsi.l	a2, 1, 1f
+	l32i	a4,  a1, PT_AREG4
+	l32i	a5,  a1, PT_AREG5
+	l32i	a6,  a1, PT_AREG6
+	l32i	a7,  a1, PT_AREG7
+	_bbsi.l	a2, 2, 1f
+	l32i	a8,  a1, PT_AREG8
+	l32i	a9,  a1, PT_AREG9
+	l32i	a10, a1, PT_AREG10
+	l32i	a11, a1, PT_AREG11
+	_bbsi.l	a2, 3, 1f
+	l32i	a12, a1, PT_AREG12
+	l32i	a13, a1, PT_AREG13
+	l32i	a14, a1, PT_AREG14
+	l32i	a15, a1, PT_AREG15
+
+	/* Restore PC, SAR */
+
+1:	l32i	a2, a1, PT_PC
+	l32i	a3, a1, PT_SAR
+	wsr	a2, EPC_1
+	wsr	a3, SAR
+
+	/* Restore LBEG, LEND, LCOUNT */
+
+	l32i	a2, a1, PT_LBEG
+	l32i	a3, a1, PT_LEND
+	wsr	a2, LBEG
+	l32i	a2, a1, PT_LCOUNT
+	wsr	a3, LEND
+	wsr	a2, LCOUNT
+
+	/* Check if it was double exception. */
+
+	l32i	a0, a1, PT_DEPC
+	l32i	a3, a1, PT_AREG3
+	l32i	a2, a1, PT_AREG2
+	_bgeui	a0, VALID_DOUBLE_EXCEPTION_ADDRESS, 1f
+
+	/* Restore a0...a3 and return */
+
+	l32i	a0, a1, PT_AREG0
+	l32i	a1, a1, PT_AREG1
+	rfe
+
+1:	wsr	a0, DEPC
+	l32i	a0, a1, PT_AREG0
+	l32i	a1, a1, PT_AREG1
+	rfde
+
+/*
+ * Debug exception handler.
+ *
+ * Currently, we don't support KGDB, so only user application can be debugged.
+ *
+ * When we get here,  a0 is trashed and saved to excsave[debuglevel]
+ */
+
+ENTRY(debug_exception)
+
+	rsr	a0, EPS + XCHAL_DEBUGLEVEL
+	bbsi.l	a0, PS_EXCM_SHIFT, 1f	# exception mode
+
+	/* Set EPC_1 and EXCCAUSE */
+
+	wsr	a2, DEPC		# save a2 temporarily
+	rsr	a2, EPC + XCHAL_DEBUGLEVEL
+	wsr	a2, EPC_1
+
+	movi	a2, EXCCAUSE_MAPPED_DEBUG
+	wsr	a2, EXCCAUSE
+
+	/* Restore PS to the value before the debug exc but with PS.EXCM set.*/
+
+	movi	a2, 1 << PS_EXCM_SHIFT
+	or	a2, a0, a2
+	movi	a0, debug_exception	# restore a3, debug jump vector
+	wsr	a2, PS
+	xsr	a0, EXCSAVE + XCHAL_DEBUGLEVEL
+
+	/* Switch to kernel/user stack, restore jump vector, and save a0 */
+
+	bbsi.l	a2, PS_UM_SHIFT, 2f	# jump if user mode
+
+	addi	a2, a1, -16-PT_SIZE	# assume kernel stack
+	s32i	a0, a2, PT_AREG0
+	movi	a0, 0
+	s32i	a1, a2, PT_AREG1
+	s32i	a0, a2, PT_DEPC		# mark it as a regular exception
+	xsr	a0, DEPC
+	s32i	a3, a2, PT_AREG3
+	s32i	a0, a2, PT_AREG2
+	mov	a1, a2
+	j	_kernel_exception
+
+2:	rsr	a2, EXCSAVE_1
+	l32i	a2, a2, EXC_TABLE_KSTK	# load kernel stack pointer
+	s32i	a0, a2, PT_AREG0
+	movi	a0, 0
+	s32i	a1, a2, PT_AREG1
+	s32i	a0, a2, PT_DEPC
+	xsr	a0, DEPC
+	s32i	a3, a2, PT_AREG3
+	s32i	a0, a2, PT_AREG2
+	mov	a1, a2
+	j	_user_exception
+
+	/* Debug exception while in exception mode. */
+1:	j	1b	// FIXME!!
+
+
+/*
+ * We get here in case of an unrecoverable exception.
+ * The only thing we can do is to be nice and print a panic message.
+ * We only produce a single stack frame for panic, so ???
+ *
+ *
+ * Entry conditions:
+ *
+ *   - a0 contains the caller address; original value saved in excsave1.
+ *   - the original a0 contains a valid return address (backtrace) or 0.
+ *   - a2 contains a valid stackpointer
+ *
+ * Notes:
+ *
+ *   - If the stack pointer could be invalid, the caller has to setup a
+ *     dummy stack pointer (e.g. the stack of the init_task)
+ *
+ *   - If the return address could be invalid, the caller has to set it
+ *     to 0, so the backtrace would stop.
+ *
+ */
+	.align 4
+unrecoverable_text:
+	.ascii "Unrecoverable error in exception handler\0"
+
+ENTRY(unrecoverable_exception)
+
+	movi	a0, 1
+	movi	a1, 0
+
+	wsr	a0, WINDOWSTART
+	wsr	a1, WINDOWBASE
+	rsync
+
+	movi	a1, PS_WOE_MASK | 1
+	wsr	a1, PS
+	rsync
+
+	movi	a1, init_task
+	movi	a0, 0
+	addi	a1, a1, PT_REGS_OFFSET
+
+	movi	a4, panic
+	movi	a6, unrecoverable_text
+
+	callx4	a4
+
+1:	j	1b
+
+
+/* -------------------------- FAST EXCEPTION HANDLERS ----------------------- */
+
+/*
+ * Fast-handler for alloca exceptions
+ *
+ *  The ALLOCA handler is entered when user code executes the MOVSP
+ *  instruction and the caller's frame is not in the register file.
+ *  In this case, the caller frame's a0..a3 are on the stack just
+ *  below sp (a1), and this handler moves them.
+ *
+ *  For "MOVSP <ar>,<as>" without destination register a1, this routine
+ *  simply moves the value from <as> to <ar> without moving the save area.
+ *
+ * Entry condition:
+ *
+ *   a0:	trashed, original value saved on stack (PT_AREG0)
+ *   a1:	a1
+ *   a2:	new stack pointer, original in DEPC
+ *   a3:	dispatch table
+ *   depc:	a2, original value saved on stack (PT_DEPC)
+ *   excsave_1:	a3
+ *
+ *   PT_DEPC >= VALID_DOUBLE_EXCEPTION_ADDRESS: double exception, DEPC
+ *	     <  VALID_DOUBLE_EXCEPTION_ADDRESS: regular exception
+ */
+
+#if XCHAL_HAVE_BE
+#define _EXTUI_MOVSP_SRC(ar)	extui ar, ar, 4, 4
+#define _EXTUI_MOVSP_DST(ar)	extui ar, ar, 0, 4
+#else
+#define _EXTUI_MOVSP_SRC(ar)	extui ar, ar, 0, 4
+#define _EXTUI_MOVSP_DST(ar)	extui ar, ar, 4, 4
+#endif
+
+ENTRY(fast_alloca)
+
+	/* We shouldn't be in a double exception. */
+
+	l32i	a0, a2, PT_DEPC
+	_bgeui	a0, VALID_DOUBLE_EXCEPTION_ADDRESS, .Lunhandled_double
+
+	rsr	a0, DEPC		# get a2
+	s32i	a4, a2, PT_AREG4	# save a4 and
+	s32i	a0, a2, PT_AREG2	# a2 to stack
+
+	/* Exit critical section. */
+
+	movi	a0, 0
+	s32i	a0, a3, EXC_TABLE_FIXUP
+
+	/* Restore a3, excsave_1 */
+
+	xsr	a3, EXCSAVE_1		# make sure excsave_1 is valid for dbl.
+	rsr	a4, EPC_1		# get exception address
+	s32i	a3, a2, PT_AREG3	# save a3 to stack
+
+#ifdef ALLOCA_EXCEPTION_IN_IRAM
+#error	iram not supported
+#else
+	/* Note: l8ui not allowed in IRAM/IROM!! */
+	l8ui	a0, a4, 1		# read as(src) from MOVSP instruction
+#endif
+	movi	a3, .Lmovsp_src
+	_EXTUI_MOVSP_SRC(a0)		# extract source register number
+	addx8	a3, a0, a3
+	jx	a3
+
+.Lunhandled_double:
+	wsr	a0, EXCSAVE_1
+	movi	a0, unrecoverable_exception
+	callx0	a0
+
+	.align 8
+.Lmovsp_src:
+	l32i	a3, a2, PT_AREG0;	_j 1f;	.align 8
+	mov	a3, a1;			_j 1f;	.align 8
+	l32i	a3, a2, PT_AREG2;	_j 1f;	.align 8
+	l32i	a3, a2, PT_AREG3;	_j 1f;	.align 8
+	l32i	a3, a2, PT_AREG4;	_j 1f;	.align 8
+	mov	a3, a5;			_j 1f;	.align 8
+	mov	a3, a6;			_j 1f;	.align 8
+	mov	a3, a7;			_j 1f;	.align 8
+	mov	a3, a8;			_j 1f;	.align 8
+	mov	a3, a9;			_j 1f;	.align 8
+	mov	a3, a10;		_j 1f;	.align 8
+	mov	a3, a11;		_j 1f;	.align 8
+	mov	a3, a12;		_j 1f;	.align 8
+	mov	a3, a13;		_j 1f;	.align 8
+	mov	a3, a14;		_j 1f;	.align 8
+	mov	a3, a15;		_j 1f;	.align 8
+
+1:
+
+#ifdef ALLOCA_EXCEPTION_IN_IRAM
+#error	iram not supported
+#else
+	l8ui	a0, a4, 0		# read ar(dst) from MOVSP instruction
+#endif
+	addi	a4, a4, 3		# step over movsp
+	_EXTUI_MOVSP_DST(a0)		# extract destination register
+	wsr	a4, EPC_1		# save new epc_1
+
+	_bnei	a0, 1, 1f		# no 'movsp a1, ax': jump
+
+        /* Move the save area. This implies the use of the L32E
+	 * and S32E instructions, because this move must be done with
+	 * the user's PS.RING privilege levels, not with ring 0
+	 * (kernel's) privileges currently active with PS.EXCM
+	 * set. Note that we have stil registered a fixup routine with the
+	 * double exception vector in case a double exception occurs.
+	 */
+
+	/* a0,a4:avail a1:old user stack a2:exc. stack a3:new user stack. */
+
+	l32e	a0, a1, -16
+	l32e	a4, a1, -12
+	s32e	a0, a3, -16
+	s32e	a4, a3, -12
+	l32e	a0, a1, -8
+	l32e	a4, a1, -4
+	s32e	a0, a3, -8
+	s32e	a4, a3, -4
+
+	/* Restore stack-pointer and all the other saved registers. */
+
+	mov	a1, a3
+
+	l32i	a4, a2, PT_AREG4
+	l32i	a3, a2, PT_AREG3
+	l32i	a0, a2, PT_AREG0
+	l32i	a2, a2, PT_AREG2
+	rfe
+
+	/*  MOVSP <at>,<as>  was invoked with <at> != a1.
+	 *  Because the stack pointer is not being modified,
+	 *  we should be able to just modify the pointer
+	 *  without moving any save area.
+	 *  The processor only traps these occurrences if the
+	 *  caller window isn't live, so unfortunately we can't
+	 *  use this as an alternate trap mechanism.
+	 *  So we just do the move.  This requires that we
+	 *  resolve the destination register, not just the source,
+	 *  so there's some extra work.
+	 *  (PERHAPS NOT REALLY NEEDED, BUT CLEANER...)
+	 */
+
+	/* a0 dst-reg, a1 user-stack, a2 stack, a3 value of src reg. */
+
+1:	movi	a4, .Lmovsp_dst
+	addx8	a4, a0, a4
+	jx	a4
+
+	.align 8
+.Lmovsp_dst:
+	s32i	a3, a2, PT_AREG0;	_j 1f;	.align 8
+	mov	a1, a3;			_j 1f;	.align 8
+	s32i	a3, a2, PT_AREG2;	_j 1f;	.align 8
+	s32i	a3, a2, PT_AREG3;	_j 1f;	.align 8
+	s32i	a3, a2, PT_AREG4;	_j 1f;	.align 8
+	mov	a5, a3;			_j 1f;	.align 8
+	mov	a6, a3;			_j 1f;	.align 8
+	mov	a7, a3;			_j 1f;	.align 8
+	mov	a8, a3;			_j 1f;	.align 8
+	mov	a9, a3;			_j 1f;	.align 8
+	mov	a10, a3;		_j 1f;	.align 8
+	mov	a11, a3;		_j 1f;	.align 8
+	mov	a12, a3;		_j 1f;	.align 8
+	mov	a13, a3;		_j 1f;	.align 8
+	mov	a14, a3;		_j 1f;	.align 8
+	mov	a15, a3;		_j 1f;	.align 8
+
+1:	l32i	a4, a2, PT_AREG4
+	l32i	a3, a2, PT_AREG3
+	l32i	a0, a2, PT_AREG0
+	l32i	a2, a2, PT_AREG2
+	rfe
+
+
+/*
+ * fast system calls.
+ *
+ * WARNING:  The kernel doesn't save the entire user context before
+ * handling a fast system call.  These functions are small and short,
+ * usually offering some functionality not available to user tasks.
+ *
+ * BE CAREFUL TO PRESERVE THE USER'S CONTEXT.
+ *
+ * Entry condition:
+ *
+ *   a0:	trashed, original value saved on stack (PT_AREG0)
+ *   a1:	a1
+ *   a2:	new stack pointer, original in DEPC
+ *   a3:	dispatch table
+ *   depc:	a2, original value saved on stack (PT_DEPC)
+ *   excsave_1:	a3
+ */
+
+ENTRY(fast_syscall_kernel)
+
+	/* Skip syscall. */
+
+	rsr	a0, EPC_1
+	addi	a0, a0, 3
+	wsr	a0, EPC_1
+
+	l32i	a0, a2, PT_DEPC
+	bgeui	a0, VALID_DOUBLE_EXCEPTION_ADDRESS, fast_syscall_unrecoverable
+
+	rsr	a0, DEPC			# get syscall-nr
+	_beqz	a0, fast_syscall_spill_registers
+
+	addi	a0, a0, -__NR_sysxtensa
+	_beqz	a0, fast_syscall_sysxtensa
+
+	j	kernel_exception
+
+
+ENTRY(fast_syscall_user)
+
+	/* Skip syscall. */
+
+	rsr	a0, EPC_1
+	addi	a0, a0, 3
+	wsr	a0, EPC_1
+
+	l32i	a0, a2, PT_DEPC
+	bgeui	a0, VALID_DOUBLE_EXCEPTION_ADDRESS, fast_syscall_unrecoverable
+
+	rsr	a0, DEPC			# get syscall-nr
+	_beqz	a0, fast_syscall_spill_registers
+
+	addi	a0, a0, -__NR_sysxtensa
+	_beqz	a0, fast_syscall_sysxtensa
+
+	j	user_exception
+
+ENTRY(fast_syscall_unrecoverable)
+
+        /* Restore all states. */
+
+        l32i    a0, a2, PT_AREG0        # restore a0
+        xsr     a2, DEPC                # restore a2, depc
+        rsr     a3, EXCSAVE_1
+
+        wsr     a0, EXCSAVE_1
+        movi    a0, unrecoverable_exception
+        callx0  a0
+
+
+
+/*
+ * sysxtensa syscall handler
+ *
+ * int sysxtensa (XTENSA_ATOMIC_SET, ptr, val, unused);
+ * int sysxtensa (XTENSA_ATOMIC_ADD, ptr, val, unused);
+ * int sysxtensa (XTENSA_ATOMIC_EXG_ADD, ptr, val, unused);
+ * int sysxtensa (XTENSA_ATOMIC_CMP_SWP, ptr, oldval, newval);
+ * a2                    a6              a3    a4      a5
+ *
+ * Entry condition:
+ *
+ *   a0:	trashed, original value saved on stack (PT_AREG0)
+ *   a1:	a1
+ *   a2:	new stack pointer, original in DEPC
+ *   a3:	dispatch table
+ *   depc:	a2, original value saved on stack (PT_DEPC)
+ *   excsave_1:	a3
+ *
+ *   PT_DEPC >= VALID_DOUBLE_EXCEPTION_ADDRESS: double exception, DEPC
+ *	     <  VALID_DOUBLE_EXCEPTION_ADDRESS: regular exception
+ *
+ * Note: we don't have to save a2; a2 holds the return value
+ *
+ * We use the two macros TRY and CATCH:
+ *
+ * TRY	 adds an entry to the __ex_table fixup table for the immediately
+ *	 following instruction.
+ *
+ * CATCH catches any exception that occurred at one of the preceeding TRY
+ *       statements and continues from there
+ *
+ * Usage TRY	l32i	a0, a1, 0
+ *		<other code>
+ *	 done:	rfe
+ *	 CATCH	<set return code>
+ *		j done
+ */
+
+#define TRY								\
+	.section __ex_table, "a";					\
+	.word	66f, 67f;						\
+	.text;								\
+66:
+
+#define CATCH								\
+67:
+
+ENTRY(fast_syscall_sysxtensa)
+
+	_beqz	a6, 1f
+	_blti	a6, SYSXTENSA_COUNT, 2f
+
+1:	j	user_exception
+
+2:	xsr	a3, EXCSAVE_1		# restore a3, excsave1
+	s32i	a7, a2, PT_AREG7
+
+	movi	a7, 4			# sizeof(unsigned int)
+	verify_area a3, a7, a0, a2, .Leac
+
+	_beqi	a6, SYSXTENSA_ATOMIC_SET, .Lset
+	_beqi	a6, SYSXTENSA_ATOMIC_EXG_ADD, .Lexg
+	_beqi	a6, SYSXTENSA_ATOMIC_ADD, .Ladd
+
+	/* Fall through for SYSXTENSA_ATOMIC_CMP_SWP */
+
+.Lswp:	/* Atomic compare and swap */
+
+TRY	l32i	a7, a3, 0		# read old value
+	bne	a7, a4, 1f		# same as old value? jump
+	s32i	a5, a3, 0		# different, modify value
+	movi	a7, 1			# and return 1
+	j	.Lret
+
+1:	movi	a7, 0			# same values: return 0
+	j	.Lret
+
+.Ladd:	/* Atomic add */
+.Lexg:	/* Atomic (exchange) add */
+
+TRY	l32i	a7, a3, 0
+	add	a4, a4, a7
+	s32i	a4, a3, 0
+	j	.Lret
+
+.Lset:	/* Atomic set */
+
+TRY	l32i	a7, a3, 0		# read old value as return value
+	s32i	a4, a3, 0		# write new value
+
+.Lret:	mov	a0, a2
+	mov	a2, a7
+	l32i	a7, a0, PT_AREG7
+	l32i	a3, a0, PT_AREG3
+	l32i	a0, a0, PT_AREG0
+	rfe
+
+CATCH
+.Leac:	movi	a7, -EFAULT
+	j	.Lret
+
+
+
+/* fast_syscall_spill_registers.
+ *
+ * Entry condition:
+ *
+ *   a0:	trashed, original value saved on stack (PT_AREG0)
+ *   a1:	a1
+ *   a2:	new stack pointer, original in DEPC
+ *   a3:	dispatch table
+ *   depc:	a2, original value saved on stack (PT_DEPC)
+ *   excsave_1:	a3
+ *
+ * Note: We assume the stack pointer is EXC_TABLE_KSTK in the fixup handler.
+ * Note: We don't need to save a2 in depc (return value)
+ */
+
+ENTRY(fast_syscall_spill_registers)
+
+	/* Register a FIXUP handler (pass current wb as a parameter) */
+
+	movi	a0, fast_syscall_spill_registers_fixup
+	s32i	a0, a3, EXC_TABLE_FIXUP
+	rsr	a0, WINDOWBASE
+	s32i	a0, a3, EXC_TABLE_PARAM
+
+	/* Save a3 and SAR on stack. */
+
+	rsr	a0, SAR
+	xsr	a3, EXCSAVE_1		# restore a3 and excsave_1
+	s32i	a0, a2, PT_AREG4	# store SAR to PT_AREG4
+	s32i	a3, a2, PT_AREG3
+
+	/* The spill routine might clobber a7, a11, and a15. */
+
+	s32i	a7, a2, PT_AREG5
+	s32i	a11, a2, PT_AREG6
+	s32i	a15, a2, PT_AREG7
+
+	call0	_spill_registers	# destroys a3, DEPC, and SAR
+
+	/* Advance PC, restore registers and SAR, and return from exception. */
+
+	l32i	a3, a2, PT_AREG4
+	l32i	a0, a2, PT_AREG0
+	wsr	a3, SAR
+	l32i	a3, a2, PT_AREG3
+
+	/* Restore clobbered registers. */
+
+	l32i	a7, a2, PT_AREG5
+	l32i	a11, a2, PT_AREG6
+	l32i	a15, a2, PT_AREG7
+
+	movi	a2, 0
+	rfe
+
+/* Fixup handler.
+ *
+ * We get here if the spill routine causes an exception, e.g. tlb miss.
+ * We basically restore WINDOWBASE and WINDOWSTART to the condition when
+ * we entered the spill routine and jump to the user exception handler.
+ *
+ * a0: value of depc, original value in depc
+ * a2: trashed, original value in EXC_TABLE_DOUBLE_SAVE
+ * a3: exctable, original value in excsave1
+ */
+
+fast_syscall_spill_registers_fixup:
+
+	rsr	a2, WINDOWBASE	# get current windowbase (a2 is saved)
+	xsr	a0, DEPC	# restore depc and a0
+	ssl	a2		# set shift (32 - WB)
+
+	/* We need to make sure the current registers (a0-a3) are preserved.
+	 * To do this, we simply set the bit for the current window frame
+	 * in WS, so that the exception handlers save them to the task stack.
+	 */
+
+	rsr	a3, EXCSAVE_1	# get spill-mask
+	slli	a2, a3, 1	# shift left by one
+
+	slli	a3, a2, 32-WSBITS
+	src	a2, a2, a3	# a1 = xxwww1yyxxxwww1yy......
+	wsr	a2, WINDOWSTART	# set corrected windowstart
+
+	movi	a3, exc_table
+	l32i	a2, a3, EXC_TABLE_DOUBLE_SAVE	# restore a2
+	l32i	a3, a3, EXC_TABLE_PARAM	# original WB (in user task)
+
+	/* Return to the original (user task) WINDOWBASE.
+	 * We leave the following frame behind:
+	 * a0, a1, a2	same
+	 * a3:		trashed (saved in excsave_1)
+	 * depc:	depc (we have to return to that address)
+	 * excsave_1:	a3
+	 */
+
+	wsr	a3, WINDOWBASE
+	rsync
+
+	/* We are now in the original frame when we entered _spill_registers:
+	 *  a0: return address
+	 *  a1: used, stack pointer
+	 *  a2: kernel stack pointer
+	 *  a3: available, saved in EXCSAVE_1
+	 *  depc: exception address
+	 *  excsave: a3
+	 * Note: This frame might be the same as above.
+	 */
+
+#ifdef SIGNAL_HANDLING_IN_DOUBLE_EXCEPTION
+	/* Restore registers we precautiously saved.
+	 * We have the value of the 'right' a3
+	 */
+
+	l32i	a7, a2, PT_AREG5
+	l32i	a11, a2, PT_AREG6
+	l32i	a15, a2, PT_AREG7
+#endif
+
+	/* Setup stack pointer. */
+
+	addi	a2, a2, -PT_USER_SIZE
+	s32i	a0, a2, PT_AREG0
+
+	/* Make sure we return to this fixup handler. */
+
+	movi	a3, fast_syscall_spill_registers_fixup_return
+	s32i	a3, a2, PT_DEPC		# setup depc
+
+	/* Jump to the exception handler. */
+
+	movi	a3, exc_table
+	rsr	a0, EXCCAUSE
+        addx4   a0, a0, a3              	# find entry in table
+        l32i    a0, a0, EXC_TABLE_FAST_USER     # load handler
+        jx      a0
+
+fast_syscall_spill_registers_fixup_return:
+
+	/* When we return here, all registers have been restored (a2: DEPC) */
+
+	wsr	a2, DEPC		# exception address
+
+	/* Restore fixup handler. */
+
+	xsr	a3, EXCSAVE_1
+	movi	a2, fast_syscall_spill_registers_fixup
+	s32i	a2, a3, EXC_TABLE_FIXUP
+	rsr	a2, WINDOWBASE
+	s32i	a2, a3, EXC_TABLE_PARAM
+	l32i	a2, a3, EXC_TABLE_KSTK
+
+#ifdef SIGNAL_HANDLING_IN_DOUBLE_EXCEPTION
+	/* Save registers again that might be clobbered. */
+
+	s32i	a7, a2, PT_AREG5
+	s32i	a11, a2, PT_AREG6
+	s32i	a15, a2, PT_AREG7
+#endif
+
+	/* Load WB at the time the exception occurred. */
+
+	rsr	a3, SAR			# WB is still in SAR
+	neg	a3, a3
+	wsr	a3, WINDOWBASE
+	rsync
+
+	/* Restore a3 and return. */
+
+	movi	a3, exc_table
+	xsr	a3, EXCSAVE_1
+
+	rfde
+
+
+/*
+ * spill all registers.
+ *
+ * This is not a real function. The following conditions must be met:
+ *
+ *  - must be called with call0.
+ *  - uses DEPC, a3 and SAR.
+ *  - the last 'valid' register of each frame are clobbered.
+ *  - the caller must have registered a fixup handler
+ *    (or be inside a critical section)
+ *  - PS_EXCM must be set (PS_WOE cleared?)
+ */
+
+ENTRY(_spill_registers)
+
+	/*
+	 * Rotate ws so that the current windowbase is at bit 0.
+	 * Assume ws = xxxwww1yy (www1 current window frame).
+	 * Rotate ws right so that a2 = yyxxxwww1.
+	 */
+
+	wsr	a2, DEPC		# preserve a2
+	rsr	a2, WINDOWBASE
+	rsr	a3, WINDOWSTART
+	ssr	a2			# holds WB
+	slli	a2, a3, WSBITS
+	or	a3, a3, a2		# a2 = xxxwww1yyxxxwww1yy
+	srl	a3, a3
+
+	/* We are done if there are no more than the current register frame. */
+
+	extui	a3, a3, 1, WSBITS-2	# a3 = 0yyxxxwww
+	movi	a2, (1 << (WSBITS-1))
+	_beqz	a3, .Lnospill		# only one active frame? jump
+
+	/* We want 1 at the top, so that we return to the current windowbase */
+
+	or	a3, a3, a2		# 1yyxxxwww
+
+	/* Skip empty frames - get 'oldest' WINDOWSTART-bit. */
+
+	wsr	a3, WINDOWSTART		# save shifted windowstart
+	neg	a2, a3
+	and	a3, a2, a3		# first bit set from right: 000010000
+
+	ffs_ws	a2, a3			# a2: shifts to skip empty frames
+	movi	a3, WSBITS
+	sub	a2, a3, a2		# WSBITS-a2:number of 0-bits from right
+	ssr	a2			# save in SAR for later.
+
+	rsr	a3, WINDOWBASE
+	add	a3, a3, a2
+	rsr	a2, DEPC		# restore a2
+	wsr	a3, WINDOWBASE
+	rsync
+
+	rsr	a3, WINDOWSTART
+	srl	a3, a3			# shift windowstart
+
+	/* WB is now just one frame below the oldest frame in the register
+	   window. WS is shifted so the oldest frame is in bit 0, thus, WB
+	   and WS differ by one 4-register frame. */
+
+	/* Save frames. Depending what call was used (call4, call8, call12),
+	 * we have to save 4,8. or 12 registers.
+	 */
+
+	_bbsi.l	a3, 1, .Lc4
+	_bbsi.l	a3, 2, .Lc8
+
+	/* Special case: we have a call12-frame starting at a4. */
+
+	_bbci.l	a3, 3, .Lc12	# bit 3 shouldn't be zero! (Jump to Lc12 first)
+
+	s32e	a4, a1, -16	# a1 is valid with an empty spill area
+	l32e	a4, a5, -12
+	s32e	a8, a4, -48
+	mov	a8, a4
+	l32e	a4, a1, -16
+	j	.Lc12c
+
+.Lloop: _bbsi.l	a3, 1, .Lc4
+	_bbci.l	a3, 2, .Lc12
+
+.Lc8:	s32e	a4, a13, -16
+	l32e	a4, a5, -12
+	s32e	a8, a4, -32
+	s32e	a5, a13, -12
+	s32e	a6, a13, -8
+	s32e	a7, a13, -4
+	s32e	a9, a4, -28
+	s32e	a10, a4, -24
+	s32e	a11, a4, -20
+
+	srli	a11, a3, 2		# shift windowbase by 2
+	rotw	2
+	_bnei	a3, 1, .Lloop
+
+.Lexit: /* Done. Do the final rotation, set WS, and return. */
+
+	rotw	1
+	rsr	a3, WINDOWBASE
+	ssl	a3
+	movi	a3, 1
+	sll	a3, a3
+	wsr	a3, WINDOWSTART
+
+.Lnospill:
+	jx	a0
+
+.Lc4:	s32e	a4, a9, -16
+	s32e	a5, a9, -12
+	s32e	a6, a9, -8
+	s32e	a7, a9, -4
+
+	srli	a7, a3, 1
+	rotw	1
+	_bnei	a3, 1, .Lloop
+	j	.Lexit
+
+.Lc12:	_bbci.l	a3, 3, .Linvalid_mask	# bit 2 shouldn't be zero!
+
+	/* 12-register frame (call12) */
+
+	l32e	a2, a5, -12
+	s32e	a8, a2, -48
+	mov	a8, a2
+
+.Lc12c: s32e	a9, a8, -44
+	s32e	a10, a8, -40
+	s32e	a11, a8, -36
+	s32e	a12, a8, -32
+	s32e	a13, a8, -28
+	s32e	a14, a8, -24
+	s32e	a15, a8, -20
+	srli	a15, a3, 3
+
+	/* The stack pointer for a4..a7 is out of reach, so we rotate the
+	 * window, grab the stackpointer, and rotate back.
+	 * Alternatively, we could also use the following approach, but that
+	 * makes the fixup routine much more complicated:
+	 * rotw	1
+	 * s32e	a0, a13, -16
+	 * ...
+	 * rotw 2
+	 */
+
+	rotw	1
+	mov	a5, a13
+	rotw	-1
+
+	s32e	a4, a9, -16
+	s32e	a5, a9, -12
+	s32e	a6, a9, -8
+	s32e	a7, a9, -4
+
+	rotw	3
+
+	_beqi	a3, 1, .Lexit
+	j	.Lloop
+
+.Linvalid_mask:
+
+	/* We get here because of an unrecoverable error in the window
+	 * registers. If we are in user space, we kill the application,
+	 * however, this condition is unrecoverable in kernel space.
+	 */
+
+	rsr	a0, PS
+	_bbci.l	a0, PS_UM_SHIFT, 1f
+
+ 	/* User space: Setup a dummy frame and kill application.
+	 * Note: We assume EXC_TABLE_KSTK contains a valid stack pointer.
+	 */
+
+	movi	a0, 1
+	movi	a1, 0
+
+	wsr	a0, WINDOWSTART
+	wsr	a1, WINDOWBASE
+	rsync
+
+	movi	a0, 0
+
+	movi	a3, exc_table
+	l32i	a1, a3, EXC_TABLE_KSTK
+	wsr	a3, EXCSAVE_1
+
+	movi	a4, PS_WOE_MASK | 1
+	wsr	a4, PS
+	rsync
+
+	movi	a6, SIGSEGV
+	movi	a4, do_exit
+	callx4	a4
+
+1:	/* Kernel space: PANIC! */
+
+	wsr	a0, EXCSAVE_1
+	movi	a0, unrecoverable_exception
+	callx0	a0		# should not return
+1:	j	1b
+
+/*
+ * We should never get here. Bail out!
+ */
+
+ENTRY(fast_second_level_miss_double_kernel)
+
+1:	movi	a0, unrecoverable_exception
+	callx0	a0		# should not return
+1:	j	1b
+
+/* First-level entry handler for user, kernel, and double 2nd-level
+ * TLB miss exceptions.  Note that for now, user and kernel miss
+ * exceptions share the same entry point and are handled identically.
+ *
+ * An old, less-efficient C version of this function used to exist.
+ * We include it below, interleaved as comments, for reference.
+ *
+ * Entry condition:
+ *
+ *   a0:	trashed, original value saved on stack (PT_AREG0)
+ *   a1:	a1
+ *   a2:	new stack pointer, original in DEPC
+ *   a3:	dispatch table
+ *   depc:	a2, original value saved on stack (PT_DEPC)
+ *   excsave_1:	a3
+ *
+ *   PT_DEPC >= VALID_DOUBLE_EXCEPTION_ADDRESS: double exception, DEPC
+ *	     <  VALID_DOUBLE_EXCEPTION_ADDRESS: regular exception
+ */
+
+ENTRY(fast_second_level_miss)
+
+	/* Save a1. Note: we don't expect a double exception. */
+
+	s32i	a1, a2, PT_AREG1
+
+	/* We need to map the page of PTEs for the user task.  Find
+	 * the pointer to that page.  Also, it's possible for tsk->mm
+	 * to be NULL while tsk->active_mm is nonzero if we faulted on
+	 * a vmalloc address.  In that rare case, we must use
+	 * active_mm instead to avoid a fault in this handler.  See
+	 *
+	 * http://mail.nl.linux.org/linux-mm/2002-08/msg00258.html
+	 *   (or search Internet on "mm vs. active_mm")
+	 *
+	 *	if (!mm)
+	 *		mm = tsk->active_mm;
+	 *	pgd = pgd_offset (mm, regs->excvaddr);
+	 *	pmd = pmd_offset (pgd, regs->excvaddr);
+	 *	pmdval = *pmd;
+	 */
+
+	GET_CURRENT(a1,a2)
+	l32i	a0, a1, TASK_MM		# tsk->mm
+	beqz	a0, 9f
+
+8:	rsr	a1, EXCVADDR		# fault address
+	_PGD_OFFSET(a0, a1, a1)
+	l32i	a0, a0, 0		# read pmdval
+	//beqi	a0, _PAGE_USER, 2f
+	beqz	a0, 2f
+
+	/* Read ptevaddr and convert to top of page-table page.
+	 *
+	 * 	vpnval = read_ptevaddr_register() & PAGE_MASK;
+	 * 	vpnval += DTLB_WAY_PGTABLE;
+	 *	pteval = mk_pte (virt_to_page(pmd_val(pmdval)), PAGE_KERNEL);
+	 *	write_dtlb_entry (pteval, vpnval);
+	 *
+	 * The messy computation for 'pteval' above really simplifies
+	 * into the following:
+	 *
+	 * pteval = ((pmdval - PAGE_OFFSET) & PAGE_MASK) | PAGE_KERNEL
+	 */
+
+	movi	a1, -PAGE_OFFSET
+	add	a0, a0, a1		# pmdval - PAGE_OFFSET
+	extui	a1, a0, 0, PAGE_SHIFT	# ... & PAGE_MASK
+	xor	a0, a0, a1
+
+
+	movi	a1, PAGE_DIRECTORY
+	or	a0, a0, a1		# ... | PAGE_DIRECTORY
+
+	rsr	a1, PTEVADDR
+	srli	a1, a1, PAGE_SHIFT
+	slli	a1, a1, PAGE_SHIFT	# ptevaddr & PAGE_MASK
+	addi	a1, a1, DTLB_WAY_PGTABLE	# ... + way_number
+
+	wdtlb	a0, a1
+	dsync
+
+	/* Exit critical section. */
+
+	movi	a0, 0
+	s32i	a0, a3, EXC_TABLE_FIXUP
+
+	/* Restore the working registers, and return. */
+
+	l32i	a0, a2, PT_AREG0
+	l32i	a1, a2, PT_AREG1
+	l32i	a2, a2, PT_DEPC
+	xsr	a3, EXCSAVE_1
+
+	bgeui	a2, VALID_DOUBLE_EXCEPTION_ADDRESS, 1f
+
+	/* Restore excsave1 and return. */
+
+	rsr	a2, DEPC
+	rfe
+
+	/* Return from double exception. */
+
+1:	xsr	a2, DEPC
+	esync
+	rfde
+
+9:	l32i	a0, a1, TASK_ACTIVE_MM	# unlikely case mm == 0
+	j	8b
+
+2:	/* Invalid PGD, default exception handling */
+
+	rsr	a1, DEPC
+	xsr	a3, EXCSAVE_1
+	s32i	a1, a2, PT_AREG2
+	s32i	a3, a2, PT_AREG3
+	mov	a1, a2
+
+	rsr	a2, PS
+	bbsi.l	a2, PS_UM_SHIFT, 1f
+	j	_kernel_exception
+1:	j	_user_exception
+
+
+/*
+ * StoreProhibitedException
+ *
+ * Update the pte and invalidate the itlb mapping for this pte.
+ *
+ * Entry condition:
+ *
+ *   a0:	trashed, original value saved on stack (PT_AREG0)
+ *   a1:	a1
+ *   a2:	new stack pointer, original in DEPC
+ *   a3:	dispatch table
+ *   depc:	a2, original value saved on stack (PT_DEPC)
+ *   excsave_1:	a3
+ *
+ *   PT_DEPC >= VALID_DOUBLE_EXCEPTION_ADDRESS: double exception, DEPC
+ *	     <  VALID_DOUBLE_EXCEPTION_ADDRESS: regular exception
+ */
+
+ENTRY(fast_store_prohibited)
+
+	/* Save a1 and a4. */
+
+	s32i	a1, a2, PT_AREG1
+	s32i	a4, a2, PT_AREG4
+
+	GET_CURRENT(a1,a2)
+	l32i	a0, a1, TASK_MM		# tsk->mm
+	beqz	a0, 9f
+
+8:	rsr	a1, EXCVADDR		# fault address
+	_PGD_OFFSET(a0, a1, a4)
+	l32i	a0, a0, 0
+	//beqi	a0, _PAGE_USER, 2f	# FIXME use _PAGE_INVALID
+	beqz	a0, 2f
+
+	_PTE_OFFSET(a0, a1, a4)
+	l32i	a4, a0, 0		# read pteval
+	movi	a1, _PAGE_VALID | _PAGE_RW
+	bnall	a4, a1, 2f
+
+	movi	a1, _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_WRENABLE
+	or	a4, a4, a1
+	rsr	a1, EXCVADDR
+	s32i	a4, a0, 0
+
+	/* We need to flush the cache if we have page coloring. */
+#if (DCACHE_WAY_SIZE > PAGE_SIZE) && XCHAL_DCACHE_IS_WRITEBACK
+	dhwb	a0, 0
+#endif
+	pdtlb	a0, a1
+	beqz	a0, 1f
+	idtlb	a0		// FIXME do we need this?
+	wdtlb	a4, a0
+1:
+
+	/* Exit critical section. */
+
+	movi	a0, 0
+	s32i	a0, a3, EXC_TABLE_FIXUP
+
+	/* Restore the working registers, and return. */
+
+	l32i	a4, a2, PT_AREG4
+	l32i	a1, a2, PT_AREG1
+	l32i	a0, a2, PT_AREG0
+	l32i	a2, a2, PT_DEPC
+
+	/* Restore excsave1 and a3. */
+
+	xsr	a3, EXCSAVE_1
+	bgeui	a2, VALID_DOUBLE_EXCEPTION_ADDRESS, 1f
+
+	rsr	a2, DEPC
+	rfe
+
+	/* Double exception. Restore FIXUP handler and return. */
+
+1:	xsr	a2, DEPC
+	esync
+	rfde
+
+9:	l32i	a0, a1, TASK_ACTIVE_MM	# unlikely case mm == 0
+	j	8b
+
+2:	/* If there was a problem, handle fault in C */
+
+	rsr	a4, DEPC	# still holds a2
+	xsr	a3, EXCSAVE_1
+	s32i	a4, a2, PT_AREG2
+	s32i	a3, a2, PT_AREG3
+	l32i	a4, a2, PT_AREG4
+	mov	a1, a2
+
+	rsr	a2, PS
+	bbsi.l	a2, PS_UM_SHIFT, 1f
+	j	_kernel_exception
+1:	j	_user_exception
+
+
+#if XCHAL_EXTRA_SA_SIZE
+
+#warning fast_coprocessor untested
+
+/*
+ * Entry condition:
+ *
+ *   a0:	trashed, original value saved on stack (PT_AREG0)
+ *   a1:	a1
+ *   a2:	new stack pointer, original in DEPC
+ *   a3:	dispatch table
+ *   depc:	a2, original value saved on stack (PT_DEPC)
+ *   excsave_1:	a3
+ *
+ *   PT_DEPC >= VALID_DOUBLE_EXCEPTION_ADDRESS: double exception, DEPC
+ *	     <  VALID_DOUBLE_EXCEPTION_ADDRESS: regular exception
+ */
+
+ENTRY(fast_coprocessor_double)
+	wsr	a0, EXCSAVE_1
+	movi	a0, unrecoverable_exception
+	callx0	a0
+
+ENTRY(fast_coprocessor)
+
+	/* Fatal if we are in a double exception. */
+
+	l32i	a0, a2, PT_DEPC
+	_bgeui	a0, VALID_DOUBLE_EXCEPTION_ADDRESS, fast_coprocessor_double
+
+	/* Save some registers a1, a3, a4, SAR */
+
+	xsr	a3, EXCSAVE_1
+	s32i	a3, a2, PT_AREG3
+	rsr	a3, SAR
+	s32i	a4, a2, PT_AREG4
+	s32i	a1, a2, PT_AREG1
+	s32i	a5, a1, PT_AREG5
+	s32i	a3, a2, PT_SAR
+	mov	a1, a2
+
+	/* Currently, the HAL macros only guarantee saving a0 and a1.
+	 * These can and will be refined in the future, but for now,
+	 * just save the remaining registers of a2...a15.
+	 */
+	s32i	a6, a1, PT_AREG6
+	s32i	a7, a1, PT_AREG7
+	s32i	a8, a1, PT_AREG8
+	s32i	a9, a1, PT_AREG9
+	s32i	a10, a1, PT_AREG10
+	s32i	a11, a1, PT_AREG11
+	s32i	a12, a1, PT_AREG12
+	s32i	a13, a1, PT_AREG13
+	s32i	a14, a1, PT_AREG14
+	s32i	a15, a1, PT_AREG15
+
+	/* Find coprocessor number. Subtract first CP EXCCAUSE from EXCCAUSE */
+
+	rsr	a0, EXCCAUSE
+	addi	a3, a0, -XCHAL_EXCCAUSE_COPROCESSOR0_DISABLED
+
+	/* Set corresponding CPENABLE bit */
+
+	movi	a4, 1
+	ssl	a3			# SAR: 32 - coprocessor_number
+	rsr	a5, CPENABLE
+	sll	a4, a4
+	or	a4, a5, a4
+	wsr	a4, CPENABLE
+	rsync
+	movi	a5, coprocessor_info	# list of owner and offset into cp_save
+	addx8	a0, a4, a5		# entry for CP
+
+	bne	a4, a5, .Lload		# bit wasn't set before, cp not in use
+
+	/* Now compare the current task with the owner of the coprocessor.
+	 * If they are the same, there is no reason to save or restore any
+	 * coprocessor state. Having already enabled the coprocessor,
+	 * branch ahead to return.
+	 */
+	GET_CURRENT(a5,a1)
+	l32i	a4, a0, COPROCESSOR_INFO_OWNER	# a4: current owner for this CP
+	beq	a4, a5, .Ldone
+
+	/* Find location to dump current coprocessor state:
+	 *  task_struct->task_cp_save_offset + coprocessor_offset[coprocessor]
+	 *
+	 * Note: a0 pointer to the entry in the coprocessor owner table,
+	 *	 a3 coprocessor number,
+         *	 a4 current owner of coprocessor.
+	 */
+	l32i	a5, a0, COPROCESSOR_INFO_OFFSET
+	addi	a2, a4, THREAD_CP_SAVE
+	add	a2, a2, a5
+
+	/* Store current coprocessor states. (a5 still has CP number) */
+
+	xchal_cpi_store_funcbody
+
+	/* The macro might have destroyed a3 (coprocessor number), but
+	 * SAR still has 32 - coprocessor_number!
+	 */
+	movi	a3, 32
+	rsr	a4, SAR
+	sub	a3, a3, a4
+
+.Lload:	/* A new task now owns the corpocessors. Save its TCB pointer into
+	 * the coprocessor owner table.
+	 *
+	 * Note: a0 pointer to the entry in the coprocessor owner table,
+	 *	 a3 coprocessor number.
+	 */
+	GET_CURRENT(a4,a1)
+	s32i	a4, a0, 0
+
+	/* Find location from where to restore the current coprocessor state.*/
+
+	l32i	a5, a0, COPROCESSOR_INFO_OFFSET
+	addi	a2, a4, THREAD_CP_SAVE
+	add	a2, a2, a4
+
+	xchal_cpi_load_funcbody
+
+	/* We must assume that the xchal_cpi_store_funcbody macro destroyed
+	 * registers a2..a15.
+	 */
+
+.Ldone:	l32i	a15, a1, PT_AREG15
+	l32i	a14, a1, PT_AREG14
+	l32i	a13, a1, PT_AREG13
+	l32i	a12, a1, PT_AREG12
+	l32i	a11, a1, PT_AREG11
+	l32i	a10, a1, PT_AREG10
+	l32i	a9, a1, PT_AREG9
+	l32i	a8, a1, PT_AREG8
+	l32i	a7, a1, PT_AREG7
+	l32i	a6, a1, PT_AREG6
+	l32i	a5, a1, PT_AREG5
+	l32i	a4, a1, PT_AREG4
+	l32i	a3, a1, PT_AREG3
+	l32i	a2, a1, PT_AREG2
+	l32i	a0, a1, PT_AREG0
+	l32i	a1, a1, PT_AREG1
+
+	rfe
+
+#endif /* XCHAL_EXTRA_SA_SIZE */
+
+/*
+ * Task switch.
+ *
+ * struct task*  _switch_to (struct task* prev, struct task* next)
+ *         a2                              a2                 a3
+ */
+
+ENTRY(_switch_to)
+
+	entry	a1, 16
+
+	mov	a4, a3			# preserve a3
+
+	s32i	a0, a2, THREAD_RA	# save return address
+	s32i	a1, a2, THREAD_SP	# save stack pointer
+
+	/* Disable ints while we manipulate the stack pointer; spill regs. */
+
+	movi	a5, PS_EXCM_MASK | LOCKLEVEL
+	xsr	a5, PS
+	rsr	a3, EXCSAVE_1
+	rsync
+	s32i	a3, a3, EXC_TABLE_FIXUP	/* enter critical section */
+
+	call0	_spill_registers
+
+	/* Set kernel stack (and leave critical section)
+	 * Note: It's save to set it here. The stack will not be overwritten
+	 *       because the kernel stack will only be loaded again after
+	 *       we return from kernel space.
+	 */
+
+	l32i	a0, a4, TASK_THREAD_INFO
+	rsr	a3, EXCSAVE_1		# exc_table
+	movi	a1, 0
+	addi	a0, a0, PT_REGS_OFFSET
+	s32i	a1, a3, EXC_TABLE_FIXUP
+	s32i	a0, a3, EXC_TABLE_KSTK
+
+	/* restore context of the task that 'next' addresses */
+
+	l32i	a0, a4, THREAD_RA	/* restore return address */
+	l32i	a1, a4, THREAD_SP	/* restore stack pointer */
+
+	wsr	a5, PS
+	rsync
+
+	retw
+
+
+ENTRY(ret_from_fork)
+
+	/* void schedule_tail (struct task_struct *prev)
+	 * Note: prev is still in a6 (return value from fake call4 frame)
+	 */
+	movi	a4, schedule_tail
+	callx4	a4
+
+	movi	a4, do_syscall_trace
+	callx4	a4
+
+	j	common_exception_return
+
+
+
+/*
+ * Table of syscalls
+ */
+
+.data
+.align  4
+.global sys_call_table
+sys_call_table:
+
+#define SYSCALL(call, narg) .word call
+#include "syscalls.h"
+
+/*
+ * Number of arguments of each syscall
+ */
+
+.global sys_narg_table
+sys_narg_table:
+
+#undef SYSCALL
+#define SYSCALL(call, narg) .byte narg
+#include "syscalls.h"
+
diff --git a/arch/xtensa/kernel/head.S b/arch/xtensa/kernel/head.S
new file mode 100644
--- /dev/null
+++ b/arch/xtensa/kernel/head.S
@@ -0,0 +1,237 @@
+/*
+ * arch/xtensa/kernel/head.S
+ *
+ * Xtensa Processor startup code.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ *
+ * Chris Zankel <chris@zankel.net>
+ * Marc Gauthier <marc@tensilica.com, marc@alumni.uwaterloo.ca>
+ * Joe Taylor <joe@tensilica.com, joetylr@yahoo.com>
+ * Kevin Chea
+ */
+
+#include <xtensa/cacheasm.h>
+#include <linux/config.h>
+#include <asm/processor.h>
+#include <asm/page.h>
+
+/*
+ * This module contains the entry code for kernel images. It performs the
+ * minimal setup needed to call the generic C routines.
+ *
+ * Prerequisites:
+ *
+ * - The kernel image has been loaded to the actual address where it was
+ *   compiled to.
+ * - a2 contains either 0 or a pointer to a list of boot parameters.
+ *   (see setup.c for more details)
+ *
+ */
+
+	.macro	iterate	from, to , cmd
+		.ifeq	((\to - \from) & ~0xfff)
+			\cmd	\from
+			iterate "(\from+1)", \to, \cmd
+		.endif
+	.endm
+
+/*
+ *  _start
+ *
+ *  The bootloader passes a pointer to a list of boot parameters in a2.
+ */
+
+	/* The first bytes of the kernel image must be an instruction, so we
+	 * manually allocate and define the literal constant we need for a jx
+	 * instruction.
+	 */
+
+	.section .head.text, "ax"
+	.globl _start
+_start:	_j	2f
+	.align	4
+1:	.word	_startup
+2:	l32r	a0, 1b
+	jx	a0
+
+	.text
+	.align 4
+_startup:
+
+	/* Disable interrupts and exceptions. */
+
+	movi	a0, XCHAL_PS_EXCM_MASK
+	wsr	a0, PS
+
+	/* Preserve the pointer to the boot parameter list in EXCSAVE_1 */
+
+	wsr	a2, EXCSAVE_1
+
+	/* Start with a fresh windowbase and windowstart.  */
+
+	movi	a1, 1
+	movi	a0, 0
+	wsr	a1, WINDOWSTART
+	wsr	a0, WINDOWBASE
+	rsync
+
+	/* Set a0 to 0 for the remaining initialization. */
+
+	movi	a0, 0
+
+	/* Clear debugging registers. */
+
+#if XCHAL_HAVE_DEBUG
+	wsr	a0, IBREAKENABLE
+	wsr	a0, ICOUNT
+	movi	a1, 15
+	wsr	a0, ICOUNTLEVEL
+
+	.macro reset_dbreak num
+	wsr	a0, DBREAKC + \num
+	.endm
+
+        iterate 0, XCHAL_NUM_IBREAK-1, reset_dbreak
+#endif
+
+	/* Clear CCOUNT (not really necessary, but nice) */
+
+	wsr	a0, CCOUNT	# not really necessary, but nice
+
+	/* Disable zero-loops. */
+
+#if XCHAL_HAVE_LOOPS
+	wsr	a0, LCOUNT
+#endif
+
+	/* Disable all timers. */
+
+	.macro	reset_timer	num
+	wsr	a0, CCOMPARE_0 + \num
+	.endm
+	iterate	0, XCHAL_NUM_TIMERS-1, reset_timer
+
+	/* Interrupt initialization. */
+
+	movi	a2, XCHAL_INTTYPE_MASK_SOFTWARE | XCHAL_INTTYPE_MASK_EXTERN_EDGE
+	wsr	a0, INTENABLE
+	wsr	a2, INTCLEAR
+
+	/* Disable coprocessors. */
+
+#if XCHAL_CP_NUM > 0
+	wsr	a0, CPENABLE
+#endif
+
+	/* Set PS.INTLEVEL=1, PS.WOE=0, kernel stack, PS.EXCM=0
+	 *
+	 * Note: PS.EXCM must be cleared before using any loop
+	 *	 instructions; otherwise, they are silently disabled, and
+	 * 	 at most one iteration of the loop is executed.
+	 */
+
+	movi	a1, 1
+	wsr	a1, PS
+	rsync
+
+	/*  Initialize the caches.
+	 *  Does not include flushing writeback d-cache.
+	 *  a6, a7 are just working registers (clobbered).
+	 */
+
+	icache_reset  a2, a3
+	dcache_reset  a2, a3
+
+	/* Unpack data sections
+	 *
+	 * The linker script used to build the Linux kernel image
+	 * creates a table located at __boot_reloc_table_start
+	 * that contans the information what data needs to be unpacked.
+	 *
+	 * Uses a2-a7.
+	 */
+
+	movi	a2, __boot_reloc_table_start
+	movi	a3, __boot_reloc_table_end
+
+1:	beq	a2, a3, 3f	# no more entries?
+	l32i	a4, a2, 0	# start destination (in RAM)
+	l32i	a5, a2, 4	# end desination (in RAM)
+	l32i	a6, a2, 8	# start source (in ROM)
+	addi	a2, a2, 12	# next entry
+	beq	a4, a5, 1b	# skip, empty entry
+	beq	a4, a6, 1b	# skip, source and dest. are the same
+
+2:	l32i	a7, a6, 0	# load word
+	addi	a6, a6, 4
+	s32i	a7, a4, 0	# store word
+	addi	a4, a4, 4
+	bltu	a4, a5, 2b
+	j	1b
+
+3:
+	/* All code and initialized data segments have been copied.
+	 * Now clear the BSS segment.
+	 */
+
+	movi	a2, _bss_start	# start of BSS
+	movi	a3, _bss_end	# end of BSS
+
+1:	addi	a2, a2, 4
+	s32i	a0, a2, 0
+	blt	a2, a3, 1b
+
+#if XCHAL_DCACHE_IS_WRITEBACK
+
+	/* After unpacking, flush the writeback cache to memory so the
+	 * instructions/data are available.
+	 */
+
+	dcache_writeback_all	a2, a3
+#endif
+
+	/* Setup stack and enable window exceptions (keep irqs disabled) */
+
+	movi	a1, init_thread_union
+	addi	a1, a1, KERNEL_STACK_SIZE
+
+	movi	a2, 0x00040001		# WOE=1, INTLEVEL=1, UM=0
+	wsr	a2, PS			# (enable reg-windows; progmode stack)
+	rsync
+
+	/* Set up EXCSAVE[DEBUGLEVEL] to point to the Debug Exception Handler.*/
+
+	movi	a2, debug_exception
+	wsr	a2, EXCSAVE + XCHAL_DEBUGLEVEL
+
+	/* Set up EXCSAVE[1] to point to the exc_table. */
+
+	movi	a6, exc_table
+	xsr	a6, EXCSAVE_1
+
+	/* init_arch kick-starts the linux kernel */
+
+	movi	a4, init_arch
+	callx4	a4
+
+	movi	a4, start_kernel
+	callx4	a4
+
+should_never_return:
+	j	should_never_return
+
+	/* Define some common data structures here.  We define them
+	 * here in this assembly file due to their unusual alignment
+	 * requirements.
+	 */
+
+	.comm   swapper_pg_dir,PAGE_SIZE,PAGE_SIZE
+	.comm	empty_bad_page_table,PAGE_SIZE,PAGE_SIZE
+	.comm	empty_bad_page,PAGE_SIZE,PAGE_SIZE
+	.comm	empty_zero_page,PAGE_SIZE,PAGE_SIZE
+
diff --git a/arch/xtensa/kernel/irq.c b/arch/xtensa/kernel/irq.c
new file mode 100644
--- /dev/null
+++ b/arch/xtensa/kernel/irq.c
@@ -0,0 +1,192 @@
+/*
+ * linux/arch/xtensa/kernel/irq.c
+ *
+ * Xtensa built-in interrupt controller and some generic functions copied
+ * from i386.
+ *
+ * Copyright (C) 2002 - 2005 Tensilica, Inc.
+ * Copyright (C) 1992, 1998 Linus Torvalds, Ingo Molnar
+ *
+ *
+ * Chris Zankel <chris@zankel.net>
+ * Kevin Chea
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/seq_file.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/kernel_stat.h>
+
+#include <asm/uaccess.h>
+#include <asm/platform.h>
+
+static void enable_xtensa_irq(unsigned int irq);
+static void disable_xtensa_irq(unsigned int irq);
+static void mask_and_ack_xtensa(unsigned int irq);
+static void end_xtensa_irq(unsigned int irq);
+
+static unsigned int cached_irq_mask;
+
+atomic_t irq_err_count;
+
+/*
+ * 'what should we do if we get a hw irq event on an illegal vector'.
+ * each architecture has to answer this themselves.
+ */
+void ack_bad_irq(unsigned int irq)
+{
+          printk("unexpected IRQ trap at vector %02x\n", irq);
+}
+
+/*
+ * do_IRQ handles all normal device IRQ's (the special
+ * SMP cross-CPU interrupts have their own specific
+ * handlers).
+ */
+
+unsigned int  do_IRQ(int irq, struct pt_regs *regs)
+{
+	irq_enter();
+
+#ifdef CONFIG_DEBUG_STACKOVERFLOW
+	/* Debugging check for stack overflow: is there less than 1KB free? */
+	{
+		unsigned long sp;
+
+		__asm__ __volatile__ ("mov %0, a1\n" : "=a" (sp));
+		sp &= THREAD_SIZE - 1;
+
+		if (unlikely(sp < (sizeof(thread_info) + 1024)))
+			printk("Stack overflow in do_IRQ: %ld\n",
+			       sp - sizeof(struct thread_info));
+	}
+#endif
+
+	__do_IRQ(irq, regs);
+
+	irq_exit();
+
+	return 1;
+}
+
+/*
+ * Generic, controller-independent functions:
+ */
+
+int show_interrupts(struct seq_file *p, void *v)
+{
+	int i = *(loff_t *) v, j;
+	struct irqaction * action;
+	unsigned long flags;
+
+	if (i == 0) {
+		seq_printf(p, "           ");
+		for (j=0; j<NR_CPUS; j++)
+			if (cpu_online(j))
+				seq_printf(p, "CPU%d       ",j);
+		seq_putc(p, '\n');
+	}
+
+	if (i < NR_IRQS) {
+		spin_lock_irqsave(&irq_desc[i].lock, flags);
+		action = irq_desc[i].action;
+		if (!action)
+			goto skip;
+		seq_printf(p, "%3d: ",i);
+#ifndef CONFIG_SMP
+		seq_printf(p, "%10u ", kstat_irqs(i));
+#else
+		for (j = 0; j < NR_CPUS; j++)
+			if (cpu_online(j))
+				seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
+#endif
+		seq_printf(p, " %14s", irq_desc[i].handler->typename);
+		seq_printf(p, "  %s", action->name);
+
+		for (action=action->next; action; action = action->next)
+			seq_printf(p, ", %s", action->name);
+
+		seq_putc(p, '\n');
+skip:
+		spin_unlock_irqrestore(&irq_desc[i].lock, flags);
+	} else if (i == NR_IRQS) {
+		seq_printf(p, "NMI: ");
+		for (j = 0; j < NR_CPUS; j++)
+			if (cpu_online(j))
+				seq_printf(p, "%10u ", nmi_count(j));
+		seq_putc(p, '\n');
+		seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count));
+	}
+	return 0;
+}
+/* shutdown is same as "disable" */
+#define shutdown_xtensa_irq disable_xtensa_irq
+
+static unsigned int startup_xtensa_irq(unsigned int irq)
+{
+	enable_xtensa_irq(irq);
+	return 0;               /* never anything pending */
+}
+
+static struct hw_interrupt_type xtensa_irq_type = {
+	"Xtensa-IRQ",
+	startup_xtensa_irq,
+	shutdown_xtensa_irq,
+	enable_xtensa_irq,
+	disable_xtensa_irq,
+	mask_and_ack_xtensa,
+	end_xtensa_irq
+};
+
+static inline void mask_irq(unsigned int irq)
+{
+	cached_irq_mask &= ~(1 << irq);
+	set_sr (cached_irq_mask, INTENABLE);
+}
+
+static inline void unmask_irq(unsigned int irq)
+{
+	cached_irq_mask |= 1 << irq;
+	set_sr (cached_irq_mask, INTENABLE);
+}
+
+static void disable_xtensa_irq(unsigned int irq)
+{
+	unsigned long flags;
+	local_save_flags(flags);
+	mask_irq(irq);
+	local_irq_restore(flags);
+}
+
+static void enable_xtensa_irq(unsigned int irq)
+{
+	unsigned long flags;
+	local_save_flags(flags);
+	unmask_irq(irq);
+	local_irq_restore(flags);
+}
+
+static void mask_and_ack_xtensa(unsigned int irq)
+{
+        disable_xtensa_irq(irq);
+}
+
+static void end_xtensa_irq(unsigned int irq)
+{
+        enable_xtensa_irq(irq);
+}
+
+
+void __init init_IRQ(void)
+{
+	int i;
+
+	for (i=0; i < XTENSA_NR_IRQS; i++)
+		irq_desc[i].handler = &xtensa_irq_type;
+
+	cached_irq_mask = 0;
+
+	platform_init_irq();
+}
diff --git a/arch/xtensa/kernel/module.c b/arch/xtensa/kernel/module.c
new file mode 100644
--- /dev/null
+++ b/arch/xtensa/kernel/module.c
@@ -0,0 +1,78 @@
+/*
+ * arch/xtensa/kernel/platform.c
+ *
+ * Module support.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ *
+ * Chris Zankel <chris@zankel.net>
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/moduleloader.h>
+#include <linux/elf.h>
+#include <linux/vmalloc.h>
+#include <linux/fs.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/cache.h>
+
+LIST_HEAD(module_buf_list);
+
+void *module_alloc(unsigned long size)
+{
+  panic("module_alloc not implemented");
+}
+
+void module_free(struct module *mod, void *module_region)
+{
+  panic("module_free not implemented");
+}
+
+int module_frob_arch_sections(Elf32_Ehdr *hdr,
+    			      Elf32_Shdr *sechdrs,
+			      char *secstrings,
+			      struct module *me)
+{
+  panic("module_frob_arch_sections not implemented");
+}
+
+int apply_relocate(Elf32_Shdr *sechdrs,
+    		   const char *strtab,
+		   unsigned int symindex,
+		   unsigned int relsec,
+		   struct module *module)
+{
+  panic ("apply_relocate not implemented");
+}
+
+int apply_relocate_add(Elf32_Shdr *sechdrs,
+		       const char *strtab,
+		       unsigned int symindex,
+		       unsigned int relsec,
+		       struct module *module)
+{
+  panic("apply_relocate_add not implemented");
+}
+
+int module_finalize(const Elf_Ehdr *hdr,
+    		    const Elf_Shdr *sechdrs,
+		    struct module *me)
+{
+  panic ("module_finalize not implemented");
+}
+
+void module_arch_cleanup(struct module *mod)
+{
+  panic("module_arch_cleanup not implemented");
+}
+
+struct bug_entry *module_find_bug(unsigned long bugaddr)
+{
+  panic("module_find_bug not implemented");
+}
diff --git a/arch/xtensa/kernel/pci-dma.c b/arch/xtensa/kernel/pci-dma.c
new file mode 100644
--- /dev/null
+++ b/arch/xtensa/kernel/pci-dma.c
@@ -0,0 +1,73 @@
+/*
+ * arch/xtensa/pci-dma.c
+ *
+ * DMA coherent memory allocation.
+ *
+ * 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.
+ *
+ * Copyright (C) 2002 - 2005 Tensilica Inc.
+ *
+ * Based on version for i386.
+ *
+ * Chris Zankel <chris@zankel.net>
+ * Joe Taylor <joe@tensilica.com, joetylr@yahoo.com>
+ */
+
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/pci.h>
+#include <asm/io.h>
+#include <asm/cacheflush.h>
+
+/*
+ * Note: We assume that the full memory space is always mapped to 'kseg'
+ *	 Otherwise we have to use page attributes (not implemented).
+ */
+
+void *
+dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, int gfp)
+{
+	void *ret;
+
+	/* ignore region speicifiers */
+	gfp &= ~(__GFP_DMA | __GFP_HIGHMEM);
+
+	if (dev == NULL || (*dev->dma_mask < 0xffffffff))
+		gfp |= GFP_DMA;
+	ret = (void *)__get_free_pages(gfp, get_order(size));
+
+	if (ret != NULL) {
+		memset(ret, 0, size);
+		*handle = virt_to_bus(ret);
+	}
+	return (void*) BYPASS_ADDR((unsigned long)ret);
+}
+
+void dma_free_coherent(struct device *hwdev, size_t size,
+			 void *vaddr, dma_addr_t dma_handle)
+{
+	free_pages(CACHED_ADDR((unsigned long)vaddr), get_order(size));
+}
+
+
+void consistent_sync(void *vaddr, size_t size, int direction)
+{
+	switch (direction) {
+	case PCI_DMA_NONE:
+		BUG();
+	case PCI_DMA_FROMDEVICE:        /* invalidate only */
+		__invalidate_dcache_range((unsigned long)vaddr,
+				          (unsigned long)size);
+		break;
+
+	case PCI_DMA_TODEVICE:          /* writeback only */
+	case PCI_DMA_BIDIRECTIONAL:     /* writeback and invalidate */
+		__flush_invalidate_dcache_range((unsigned long)vaddr,
+				    		(unsigned long)size);
+		break;
+	}
+}
diff --git a/arch/xtensa/kernel/pci.c b/arch/xtensa/kernel/pci.c
new file mode 100644
--- /dev/null
+++ b/arch/xtensa/kernel/pci.c
@@ -0,0 +1,478 @@
+/*
+ * arch/xtensa/pcibios.c
+ *
+ * PCI bios-type initialisation for PCI machines
+ *
+ * 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.
+ *
+ * Copyright (C) 2001-2005 Tensilica Inc.
+ *
+ * Based largely on work from Cort (ppc/kernel/pci.c)
+ * IO functions copied from sparc.
+ *
+ * Chris Zankel <chris@zankel.net>
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/bootmem.h>
+
+#include <asm/pci-bridge.h>
+#include <asm/platform.h>
+
+#undef DEBUG
+
+#ifdef DEBUG
+#define DBG(x...) printk(x)
+#else
+#define DBG(x...)
+#endif
+
+/* PCI Controller */
+
+
+/*
+ * pcibios_alloc_controller
+ * pcibios_enable_device
+ * pcibios_fixups
+ * pcibios_align_resource
+ * pcibios_fixup_bus
+ * pcibios_setup
+ * pci_bus_add_device
+ * pci_mmap_page_range
+ */
+
+struct pci_controller* pci_ctrl_head;
+struct pci_controller** pci_ctrl_tail = &pci_ctrl_head;
+
+static int pci_bus_count;
+
+/*
+ * We need to avoid collisions with `mirrored' VGA ports
+ * and other strange ISA hardware, so we always want the
+ * addresses to be allocated in the 0x000-0x0ff region
+ * modulo 0x400.
+ *
+ * Why? Because some silly external IO cards only decode
+ * the low 10 bits of the IO address. The 0x00-0xff region
+ * is reserved for motherboard devices that decode all 16
+ * bits, so it's ok to allocate at, say, 0x2800-0x28ff,
+ * but we want to try to avoid allocating at 0x2900-0x2bff
+ * which might have be mirrored at 0x0100-0x03ff..
+ */
+void
+pcibios_align_resource(void *data, struct resource *res, unsigned long size,
+    		       unsigned long align)
+{
+	struct pci_dev *dev = data;
+
+	if (res->flags & IORESOURCE_IO) {
+		unsigned long start = res->start;
+
+		if (size > 0x100) {
+			printk(KERN_ERR "PCI: I/O Region %s/%d too large"
+			       " (%ld bytes)\n", pci_name(dev),
+			       dev->resource - res, size);
+		}
+
+		if (start & 0x300) {
+			start = (start + 0x3ff) & ~0x3ff;
+			res->start = start;
+		}
+	}
+}
+
+int
+pcibios_enable_resources(struct pci_dev *dev, int mask)
+{
+	u16 cmd, old_cmd;
+	int idx;
+	struct resource *r;
+
+	pci_read_config_word(dev, PCI_COMMAND, &cmd);
+	old_cmd = cmd;
+	for(idx=0; idx<6; idx++) {
+		r = &dev->resource[idx];
+		if (!r->start && r->end) {
+			printk (KERN_ERR "PCI: Device %s not available because "
+				"of resource collisions\n", pci_name(dev));
+			return -EINVAL;
+		}
+		if (r->flags & IORESOURCE_IO)
+			cmd |= PCI_COMMAND_IO;
+		if (r->flags & IORESOURCE_MEM)
+			cmd |= PCI_COMMAND_MEMORY;
+	}
+	if (dev->resource[PCI_ROM_RESOURCE].start)
+		cmd |= PCI_COMMAND_MEMORY;
+	if (cmd != old_cmd) {
+		printk("PCI: Enabling device %s (%04x -> %04x)\n",
+			pci_name(dev), old_cmd, cmd);
+		pci_write_config_word(dev, PCI_COMMAND, cmd);
+	}
+	return 0;
+}
+
+struct pci_controller * __init pcibios_alloc_controller(void)
+{
+	struct pci_controller *pci_ctrl;
+
+	pci_ctrl = (struct pci_controller *)alloc_bootmem(sizeof(*pci_ctrl));
+	memset(pci_ctrl, 0, sizeof(struct pci_controller));
+
+	*pci_ctrl_tail = pci_ctrl;
+	pci_ctrl_tail = &pci_ctrl->next;
+
+	return pci_ctrl;
+}
+
+static int __init pcibios_init(void)
+{
+	struct pci_controller *pci_ctrl;
+	struct pci_bus *bus;
+	int next_busno = 0, i;
+
+	printk("PCI: Probing PCI hardware\n");
+
+	/* Scan all of the recorded PCI controllers.  */
+	for (pci_ctrl = pci_ctrl_head; pci_ctrl; pci_ctrl = pci_ctrl->next) {
+		pci_ctrl->last_busno = 0xff;
+		bus = pci_scan_bus(pci_ctrl->first_busno, pci_ctrl->ops,
+				   pci_ctrl);
+		if (pci_ctrl->io_resource.flags) {
+			unsigned long offs;
+
+			offs = (unsigned long)pci_ctrl->io_space.base;
+			pci_ctrl->io_resource.start += offs;
+			pci_ctrl->io_resource.end += offs;
+			bus->resource[0] = &pci_ctrl->io_resource;
+		}
+		for (i = 0; i < 3; ++i)
+			if (pci_ctrl->mem_resources[i].flags)
+				bus->resource[i+1] =&pci_ctrl->mem_resources[i];
+		pci_ctrl->bus = bus;
+		pci_ctrl->last_busno = bus->subordinate;
+		if (next_busno <= pci_ctrl->last_busno)
+			next_busno = pci_ctrl->last_busno+1;
+	}
+	pci_bus_count = next_busno;
+
+	return platform_pcibios_fixup();
+}
+
+subsys_initcall(pcibios_init);
+
+void __init pcibios_fixup_bus(struct pci_bus *bus)
+{
+	struct pci_controller *pci_ctrl = bus->sysdata;
+	struct resource *res;
+	unsigned long io_offset;
+	int i;
+
+	io_offset = (unsigned long)pci_ctrl->io_space.base;
+	if (bus->parent == NULL) {
+		/* this is a host bridge - fill in its resources */
+		pci_ctrl->bus = bus;
+
+		bus->resource[0] = res = &pci_ctrl->io_resource;
+		if (!res->flags) {
+			if (io_offset)
+				printk (KERN_ERR "I/O resource not set for host"
+					" bridge %d\n", pci_ctrl->index);
+			res->start = 0;
+			res->end = IO_SPACE_LIMIT;
+			res->flags = IORESOURCE_IO;
+		}
+		res->start += io_offset;
+		res->end += io_offset;
+
+		for (i = 0; i < 3; i++) {
+			res = &pci_ctrl->mem_resources[i];
+			if (!res->flags) {
+				if (i > 0)
+					continue;
+				printk(KERN_ERR "Memory resource not set for "
+				       "host bridge %d\n", pci_ctrl->index);
+				res->start = 0;
+				res->end = ~0U;
+				res->flags = IORESOURCE_MEM;
+			}
+			bus->resource[i+1] = res;
+		}
+	} else {
+		/* This is a subordinate bridge */
+		pci_read_bridge_bases(bus);
+
+		for (i = 0; i < 4; i++) {
+			if ((res = bus->resource[i]) == NULL || !res->flags)
+				continue;
+			if (io_offset && (res->flags & IORESOURCE_IO)) {
+				res->start += io_offset;
+				res->end += io_offset;
+			}
+		}
+	}
+}
+
+char __init *pcibios_setup(char *str)
+{
+	return str;
+}
+
+/* the next one is stolen from the alpha port... */
+
+void __init
+pcibios_update_irq(struct pci_dev *dev, int irq)
+{
+	pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
+}
+
+int pcibios_enable_device(struct pci_dev *dev, int mask)
+{
+	u16 cmd, old_cmd;
+	int idx;
+	struct resource *r;
+
+	pci_read_config_word(dev, PCI_COMMAND, &cmd);
+	old_cmd = cmd;
+	for (idx=0; idx<6; idx++) {
+		r = &dev->resource[idx];
+		if (!r->start && r->end) {
+			printk(KERN_ERR "PCI: Device %s not available because "
+			       "of resource collisions\n", pci_name(dev));
+			return -EINVAL;
+		}
+		if (r->flags & IORESOURCE_IO)
+			cmd |= PCI_COMMAND_IO;
+		if (r->flags & IORESOURCE_MEM)
+			cmd |= PCI_COMMAND_MEMORY;
+	}
+	if (cmd != old_cmd) {
+		printk("PCI: Enabling device %s (%04x -> %04x)\n",
+		       pci_name(dev), old_cmd, cmd);
+		pci_write_config_word(dev, PCI_COMMAND, cmd);
+	}
+
+	return 0;
+}
+
+#ifdef CONFIG_PROC_FS
+
+/*
+ * Return the index of the PCI controller for device pdev.
+ */
+
+int
+pci_controller_num(struct pci_dev *dev)
+{
+	struct pci_controller *pci_ctrl = (struct pci_controller*) dev->sysdata;
+	return pci_ctrl->index;
+}
+
+#endif /* CONFIG_PROC_FS */
+
+/*
+ * Platform support for /proc/bus/pci/X/Y mmap()s,
+ * modelled on the sparc64 implementation by Dave Miller.
+ *  -- paulus.
+ */
+
+/*
+ * Adjust vm_pgoff of VMA such that it is the physical page offset
+ * corresponding to the 32-bit pci bus offset for DEV requested by the user.
+ *
+ * Basically, the user finds the base address for his device which he wishes
+ * to mmap.  They read the 32-bit value from the config space base register,
+ * add whatever PAGE_SIZE multiple offset they wish, and feed this into the
+ * offset parameter of mmap on /proc/bus/pci/XXX for that device.
+ *
+ * Returns negative error code on failure, zero on success.
+ */
+static __inline__ int
+__pci_mmap_make_offset(struct pci_dev *dev, struct vm_area_struct *vma,
+		       enum pci_mmap_state mmap_state)
+{
+	struct pci_controller *pci_ctrl = (struct pci_controller*) dev->sysdata;
+	unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
+	unsigned long io_offset = 0;
+	int i, res_bit;
+
+	if (pci_ctrl == 0)
+		return -EINVAL;		/* should never happen */
+
+	/* If memory, add on the PCI bridge address offset */
+	if (mmap_state == pci_mmap_mem) {
+		res_bit = IORESOURCE_MEM;
+	} else {
+		io_offset = (unsigned long)pci_ctrl->io_space.base;
+		offset += io_offset;
+		res_bit = IORESOURCE_IO;
+	}
+
+	/*
+	 * Check that the offset requested corresponds to one of the
+	 * resources of the device.
+	 */
+	for (i = 0; i <= PCI_ROM_RESOURCE; i++) {
+		struct resource *rp = &dev->resource[i];
+		int flags = rp->flags;
+
+		/* treat ROM as memory (should be already) */
+		if (i == PCI_ROM_RESOURCE)
+			flags |= IORESOURCE_MEM;
+
+		/* Active and same type? */
+		if ((flags & res_bit) == 0)
+			continue;
+
+		/* In the range of this resource? */
+		if (offset < (rp->start & PAGE_MASK) || offset > rp->end)
+			continue;
+
+		/* found it! construct the final physical address */
+		if (mmap_state == pci_mmap_io)
+			offset += pci_ctrl->io_space.start - io_offset;
+		vma->vm_pgoff = offset >> PAGE_SHIFT;
+		return 0;
+	}
+
+	return -EINVAL;
+}
+
+/*
+ * Set vm_flags of VMA, as appropriate for this architecture, for a pci device
+ * mapping.
+ */
+static __inline__ void
+__pci_mmap_set_flags(struct pci_dev *dev, struct vm_area_struct *vma,
+		     enum pci_mmap_state mmap_state)
+{
+	vma->vm_flags |= VM_SHM | VM_LOCKED | VM_IO;
+}
+
+/*
+ * Set vm_page_prot of VMA, as appropriate for this architecture, for a pci
+ * device mapping.
+ */
+static __inline__ void
+__pci_mmap_set_pgprot(struct pci_dev *dev, struct vm_area_struct *vma,
+		      enum pci_mmap_state mmap_state, int write_combine)
+{
+	int prot = pgprot_val(vma->vm_page_prot);
+
+	/* Set to write-through */
+	prot &= ~_PAGE_NO_CACHE;
+#if 0
+	if (!write_combine)
+		prot |= _PAGE_WRITETHRU;
+#endif
+	vma->vm_page_prot = __pgprot(prot);
+}
+
+/*
+ * Perform the actual remap of the pages for a PCI device mapping, as
+ * appropriate for this architecture.  The region in the process to map
+ * is described by vm_start and vm_end members of VMA, the base physical
+ * address is found in vm_pgoff.
+ * The pci device structure is provided so that architectures may make mapping
+ * decisions on a per-device or per-bus basis.
+ *
+ * Returns a negative error code on failure, zero on success.
+ */
+int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
+			enum pci_mmap_state mmap_state,
+			int write_combine)
+{
+	int ret;
+
+	ret = __pci_mmap_make_offset(dev, vma, mmap_state);
+	if (ret < 0)
+		return ret;
+
+	__pci_mmap_set_flags(dev, vma, mmap_state);
+	__pci_mmap_set_pgprot(dev, vma, mmap_state, write_combine);
+
+	ret = io_remap_page_range(vma, vma->vm_start, vma->vm_pgoff<<PAGE_SHIFT,
+			       vma->vm_end - vma->vm_start, vma->vm_page_prot);
+
+	return ret;
+}
+
+/*
+ * This probably belongs here rather than ioport.c because
+ * we do not want this crud linked into SBus kernels.
+ * Also, think for a moment about likes of floppy.c that
+ * include architecture specific parts. They may want to redefine ins/outs.
+ *
+ * We do not use horroble macroses here because we want to
+ * advance pointer by sizeof(size).
+ */
+void outsb(unsigned long addr, const void *src, unsigned long count) {
+        while (count) {
+                count -= 1;
+                writeb(*(const char *)src, addr);
+                src += 1;
+                addr += 1;
+        }
+}
+
+void outsw(unsigned long addr, const void *src, unsigned long count) {
+        while (count) {
+                count -= 2;
+                writew(*(const short *)src, addr);
+                src += 2;
+                addr += 2;
+        }
+}
+
+void outsl(unsigned long addr, const void *src, unsigned long count) {
+        while (count) {
+                count -= 4;
+                writel(*(const long *)src, addr);
+                src += 4;
+                addr += 4;
+        }
+}
+
+void insb(unsigned long addr, void *dst, unsigned long count) {
+        while (count) {
+                count -= 1;
+                *(unsigned char *)dst = readb(addr);
+                dst += 1;
+                addr += 1;
+        }
+}
+
+void insw(unsigned long addr, void *dst, unsigned long count) {
+        while (count) {
+                count -= 2;
+                *(unsigned short *)dst = readw(addr);
+                dst += 2;
+                addr += 2;
+        }
+}
+
+void insl(unsigned long addr, void *dst, unsigned long count) {
+        while (count) {
+                count -= 4;
+                /*
+                 * XXX I am sure we are in for an unaligned trap here.
+                 */
+                *(unsigned long *)dst = readl(addr);
+                dst += 4;
+                addr += 4;
+        }
+}
+
+
+
diff --git a/arch/xtensa/kernel/platform.c b/arch/xtensa/kernel/platform.c
new file mode 100644
--- /dev/null
+++ b/arch/xtensa/kernel/platform.c
@@ -0,0 +1,49 @@
+/*
+ * arch/xtensa/kernel/platform.c
+ *
+ * Default platform functions.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2005 Tensilica Inc.
+ *
+ * Chris Zankel <chris@zankel.net>
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/time.h>
+#include <asm/platform.h>
+#include <asm/timex.h>
+
+#define _F(r,f,a,b)							\
+	r __platform_##f a b;                                   	\
+	r platform_##f a __attribute__((weak, alias("__platform_"#f)))
+
+/*
+ * Default functions that are used if no platform specific function is defined.
+ * (Please, refer to include/asm-xtensa/platform.h for more information)
+ */
+
+_F(void, setup, (char** cmd), { });
+_F(void, init_irq, (void), { });
+_F(void, restart, (void), { while(1); });
+_F(void, halt, (void), { while(1); });
+_F(void, power_off, (void), { while(1); });
+_F(void, idle, (void), { __asm__ __volatile__ ("waiti 0" ::: "memory"); });
+_F(void, heartbeat, (void), { });
+_F(int,  pcibios_fixup, (void), { return 0; });
+_F(int, get_rtc_time, (time_t* t), { return 0; });
+_F(int, set_rtc_time, (time_t t), { return 0; });
+
+#if CONFIG_XTENSA_CALIBRATE_CCOUNT
+_F(void, calibrate_ccount, (void),
+{
+  printk ("ERROR: Cannot calibrate cpu frequency! Assuming 100MHz.\n");
+  ccount_per_jiffy = 100 * (1000000UL/HZ);
+});
+#endif
+
diff --git a/arch/xtensa/kernel/process.c b/arch/xtensa/kernel/process.c
new file mode 100644
--- /dev/null
+++ b/arch/xtensa/kernel/process.c
@@ -0,0 +1,482 @@
+// TODO	verify coprocessor handling
+/*
+ * arch/xtensa/kernel/process.c
+ *
+ * Xtensa Processor version.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ *
+ * Joe Taylor <joe@tensilica.com, joetylr@yahoo.com>
+ * Chris Zankel <chris@zankel.net>
+ * Marc Gauthier <marc@tensilica.com, marc@alumni.uwaterloo.ca>
+ * Kevin Chea
+ */
+
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/stddef.h>
+#include <linux/unistd.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+#include <linux/elf.h>
+#include <linux/init.h>
+#include <linux/prctl.h>
+#include <linux/init_task.h>
+#include <linux/module.h>
+#include <linux/mqueue.h>
+
+#include <asm/pgtable.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/processor.h>
+#include <asm/platform.h>
+#include <asm/mmu.h>
+#include <asm/irq.h>
+#include <asm/atomic.h>
+#include <asm/offsets.h>
+#include <asm/coprocessor.h>
+
+extern void ret_from_fork(void);
+
+static struct fs_struct init_fs = INIT_FS;
+static struct files_struct init_files = INIT_FILES;
+static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
+static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
+struct mm_struct init_mm = INIT_MM(init_mm);
+EXPORT_SYMBOL(init_mm);
+
+union thread_union init_thread_union
+	__attribute__((__section__(".data.init_task"))) =
+{ INIT_THREAD_INFO(init_task) };
+
+struct task_struct init_task = INIT_TASK(init_task);
+EXPORT_SYMBOL(init_task);
+
+struct task_struct *current_set[NR_CPUS] = {&init_task, };
+
+
+#if XCHAL_CP_NUM > 0
+
+/*
+ * Coprocessor ownership.
+ */
+
+coprocessor_info_t coprocessor_info[] = {
+	{ 0, XTENSA_CPE_CP0_OFFSET },
+	{ 0, XTENSA_CPE_CP1_OFFSET },
+	{ 0, XTENSA_CPE_CP2_OFFSET },
+	{ 0, XTENSA_CPE_CP3_OFFSET },
+	{ 0, XTENSA_CPE_CP4_OFFSET },
+	{ 0, XTENSA_CPE_CP5_OFFSET },
+	{ 0, XTENSA_CPE_CP6_OFFSET },
+	{ 0, XTENSA_CPE_CP7_OFFSET },
+};
+
+#endif
+
+/*
+ * Powermanagement idle function, if any is provided by the platform.
+ */
+
+void cpu_idle(void)
+{
+  	local_irq_enable();
+
+	/* endless idle loop with no priority at all */
+	while (1) {
+		while (!need_resched())
+			platform_idle();
+		preempt_enable();
+		schedule();
+	}
+}
+
+/*
+ * Free current thread data structures etc..
+ */
+
+void exit_thread(void)
+{
+	release_coprocessors(current);	/* Empty macro if no CPs are defined */
+}
+
+void flush_thread(void)
+{
+	release_coprocessors(current);	/* Empty macro if no CPs are defined */
+}
+
+/*
+ * Copy thread.
+ *
+ * The stack layout for the new thread looks like this:
+ *
+ *	+------------------------+ <- sp in childregs (= tos)
+ *	|       childregs        |
+ *	+------------------------+ <- thread.sp = sp in dummy-frame
+ *	|      dummy-frame       |    (saved in dummy-frame spill-area)
+ *	+------------------------+
+ *
+ * We create a dummy frame to return to ret_from_fork:
+ *   a0 points to ret_from_fork (simulating a call4)
+ *   sp points to itself (thread.sp)
+ *   a2, a3 are unused.
+ *
+ * Note: This is a pristine frame, so we don't need any spill region on top of
+ *       childregs.
+ */
+
+int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
+		unsigned long unused,
+                struct task_struct * p, struct pt_regs * regs)
+{
+	struct pt_regs *childregs;
+	unsigned long tos;
+	int user_mode = user_mode(regs);
+
+	/* Set up new TSS. */
+	tos = (unsigned long)p->thread_info + THREAD_SIZE;
+	if (user_mode)
+		childregs = (struct pt_regs*)(tos - PT_USER_SIZE);
+	else
+		childregs = (struct pt_regs*)tos - 1;
+
+	*childregs = *regs;
+
+	/* Create a call4 dummy-frame: a0 = 0, a1 = childregs. */
+	*((int*)childregs - 3) = (unsigned long)childregs;
+	*((int*)childregs - 4) = 0;
+
+	childregs->areg[1] = tos;
+	childregs->areg[2] = 0;
+	p->set_child_tid = p->clear_child_tid = NULL;
+	p->thread.ra = MAKE_RA_FOR_CALL((unsigned long)ret_from_fork, 0x1);
+	p->thread.sp = (unsigned long)childregs;
+	if (user_mode(regs)) {
+
+		int len = childregs->wmask & ~0xf;
+		childregs->areg[1] = usp;
+		memcpy(&childregs->areg[XCHAL_NUM_AREGS - len/4],
+		       &regs->areg[XCHAL_NUM_AREGS - len/4], len);
+
+		if (clone_flags & CLONE_SETTLS)
+			childregs->areg[2] = childregs->areg[6];
+
+	} else {
+		/* In kernel space, we start a new thread with a new stack. */
+		childregs->wmask = 1;
+	}
+	return 0;
+}
+
+
+/*
+ * Create a kernel thread
+ */
+
+int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
+{
+	long retval;
+	__asm__ __volatile__
+		("mov           a5, %4\n\t" /* preserve fn in a5 */
+		 "mov           a6, %3\n\t" /* preserve and setup arg in a6 */
+		 "movi		a2, %1\n\t" /* load __NR_clone for syscall*/
+		 "mov		a3, sp\n\t" /* sp check and sys_clone */
+		 "mov		a4, %5\n\t" /* load flags for syscall */
+		 "syscall\n\t"
+		 "beq		a3, sp, 1f\n\t" /* branch if parent */
+		 "callx4	a5\n\t"     /* call fn */
+		 "movi		a2, %2\n\t" /* load __NR_exit for syscall */
+		 "mov		a3, a6\n\t" /* load fn return value */
+		 "syscall\n"
+		 "1:\n\t"
+		 "mov		%0, a2\n\t" /* parent returns zero */
+		 :"=r" (retval)
+		 :"i" (__NR_clone), "i" (__NR_exit),
+		 "r" (arg), "r" (fn),
+		 "r" (flags | CLONE_VM)
+		 : "a2", "a3", "a4", "a5", "a6" );
+	return retval;
+}
+
+
+/*
+ * These bracket the sleeping functions..
+ */
+
+unsigned long get_wchan(struct task_struct *p)
+{
+	unsigned long sp, pc;
+	unsigned long stack_page = (unsigned long) p->thread_info;
+	int count = 0;
+
+	if (!p || p == current || p->state == TASK_RUNNING)
+		return 0;
+
+	sp = p->thread.sp;
+	pc = MAKE_PC_FROM_RA(p->thread.ra, p->thread.sp);
+
+	do {
+		if (sp < stack_page + sizeof(struct task_struct) ||
+		    sp >= (stack_page + THREAD_SIZE) ||
+		    pc == 0)
+			return 0;
+		if (!in_sched_functions(pc))
+			return pc;
+
+		/* Stack layout: sp-4: ra, sp-3: sp' */
+
+		pc = MAKE_PC_FROM_RA(*(unsigned long*)sp - 4, sp);
+		sp = *(unsigned long *)sp - 3;
+	} while (count++ < 16);
+	return 0;
+}
+
+/*
+ * do_copy_regs() gathers information from 'struct pt_regs' and
+ * 'current->thread.areg[]' to fill in the xtensa_gregset_t
+ * structure.
+ *
+ * xtensa_gregset_t and 'struct pt_regs' are vastly different formats
+ * of processor registers.  Besides different ordering,
+ * xtensa_gregset_t contains non-live register information that
+ * 'struct pt_regs' does not.  Exception handling (primarily) uses
+ * 'struct pt_regs'.  Core files and ptrace use xtensa_gregset_t.
+ *
+ */
+
+void do_copy_regs (xtensa_gregset_t *elfregs, struct pt_regs *regs,
+		   struct task_struct *tsk)
+{
+	int i, n, wb_offset;
+
+	elfregs->xchal_config_id0 = XCHAL_HW_CONFIGID0;
+	elfregs->xchal_config_id1 = XCHAL_HW_CONFIGID1;
+
+	__asm__ __volatile__ ("rsr  %0, 176\n" : "=a" (i));
+ 	elfregs->cpux = i;
+	__asm__ __volatile__ ("rsr  %0, 208\n" : "=a" (i));
+ 	elfregs->cpuy = i;
+
+	/* Note:  PS.EXCM is not set while user task is running; its
+	 * being set in regs->ps is for exception handling convenience.
+	 */
+
+	elfregs->pc		= regs->pc;
+	elfregs->ps		= (regs->ps & ~XCHAL_PS_EXCM_MASK);
+	elfregs->exccause	= regs->exccause;
+	elfregs->excvaddr	= regs->excvaddr;
+	elfregs->windowbase	= regs->windowbase;
+	elfregs->windowstart	= regs->windowstart;
+	elfregs->lbeg		= regs->lbeg;
+	elfregs->lend		= regs->lend;
+	elfregs->lcount		= regs->lcount;
+	elfregs->sar		= regs->sar;
+	elfregs->syscall	= regs->syscall;
+
+	/* Copy register file.
+	 * The layout looks like this:
+	 *
+	 * |  a0 ... a15  | Z ... Z |  arX ... arY  |
+	 *  current window  unused    saved frames
+	 */
+
+	memset (elfregs->ar, 0, sizeof(elfregs->ar));
+
+	wb_offset = regs->windowbase * 4;
+	n = (regs->wmask&1)? 4 : (regs->wmask&2)? 8 : (regs->wmask&4)? 12 : 16;
+
+	for (i = 0; i < n; i++)
+		elfregs->ar[(wb_offset + i) % XCHAL_NUM_AREGS] = regs->areg[i];
+
+	n = (regs->wmask >> 4) * 4;
+
+	for (i = XCHAL_NUM_AREGS - n; n > 0; i++, n--)
+		elfregs->ar[(wb_offset + i) % XCHAL_NUM_AREGS] = regs->areg[i];
+}
+
+void xtensa_elf_core_copy_regs (xtensa_gregset_t *elfregs, struct pt_regs *regs)
+{
+	do_copy_regs ((xtensa_gregset_t *)elfregs, regs, current);
+}
+
+
+/* The inverse of do_copy_regs().  No error or sanity checking. */
+
+void do_restore_regs (xtensa_gregset_t *elfregs, struct pt_regs *regs,
+		      struct task_struct *tsk)
+{
+	int i, n, wb_offset;
+
+	/* Note:  PS.EXCM is not set while user task is running; it
+	 * needs to be set in regs->ps is for exception handling convenience.
+	 */
+
+	regs->pc		= elfregs->pc;
+	regs->ps		= (elfregs->ps | XCHAL_PS_EXCM_MASK);
+	regs->exccause		= elfregs->exccause;
+	regs->excvaddr		= elfregs->excvaddr;
+	regs->windowbase	= elfregs->windowbase;
+	regs->windowstart	= elfregs->windowstart;
+	regs->lbeg		= elfregs->lbeg;
+	regs->lend		= elfregs->lend;
+	regs->lcount		= elfregs->lcount;
+	regs->sar		= elfregs->sar;
+	regs->syscall	= elfregs->syscall;
+
+	/* Clear everything. */
+
+	memset (regs->areg, 0, sizeof(regs->areg));
+
+	/* Copy regs from live window frame. */
+
+	wb_offset = regs->windowbase * 4;
+	n = (regs->wmask&1)? 4 : (regs->wmask&2)? 8 : (regs->wmask&4)? 12 : 16;
+
+	for (i = 0; i < n; i++)
+		regs->areg[(wb_offset+i) % XCHAL_NUM_AREGS] = elfregs->ar[i];
+
+	n = (regs->wmask >> 4) * 4;
+
+	for (i = XCHAL_NUM_AREGS - n; n > 0; i++, n--)
+		regs->areg[(wb_offset+i) % XCHAL_NUM_AREGS] = elfregs->ar[i];
+}
+
+/*
+ * do_save_fpregs() gathers information from 'struct pt_regs' and
+ * 'current->thread' to fill in the elf_fpregset_t structure.
+ *
+ * Core files and ptrace use elf_fpregset_t.
+ */
+
+void do_save_fpregs (elf_fpregset_t *fpregs, struct pt_regs *regs,
+		     struct task_struct *tsk)
+{
+#if XCHAL_HAVE_CP
+
+	extern unsigned char	_xtensa_reginfo_tables[];
+	extern unsigned		_xtensa_reginfo_table_size;
+	int i;
+	unsigned long flags;
+
+	/* Before dumping coprocessor state from memory,
+	 * ensure any live coprocessor contents for this
+	 * task are first saved to memory:
+	 */
+	local_irq_save(flags);
+
+	for (i = 0; i < XCHAL_CP_MAX; i++) {
+		if (tsk == coprocessor_info[i].owner) {
+			enable_coprocessor(i);
+			save_coprocessor_registers(
+			    tsk->thread.cp_save+coprocessor_info[i].offset,i);
+			disable_coprocessor(i);
+		}
+	}
+
+	local_irq_restore(flags);
+
+	/* Now dump coprocessor & extra state: */
+	memcpy((unsigned char*)fpregs,
+		_xtensa_reginfo_tables, _xtensa_reginfo_table_size);
+	memcpy((unsigned char*)fpregs + _xtensa_reginfo_table_size,
+		tsk->thread.cp_save, XTENSA_CP_EXTRA_SIZE);
+#endif
+}
+
+/*
+ * The inverse of do_save_fpregs().
+ * Copies coprocessor and extra state from fpregs into regs and tsk->thread.
+ * Returns 0 on success, non-zero if layout doesn't match.
+ */
+
+int  do_restore_fpregs (elf_fpregset_t *fpregs, struct pt_regs *regs,
+		        struct task_struct *tsk)
+{
+#if XCHAL_HAVE_CP
+
+	extern unsigned char	_xtensa_reginfo_tables[];
+	extern unsigned		_xtensa_reginfo_table_size;
+	int i;
+	unsigned long flags;
+
+	/* Make sure save area layouts match.
+	 * FIXME:  in the future we could allow restoring from
+	 * a different layout of the same registers, by comparing
+	 * fpregs' table with _xtensa_reginfo_tables and matching
+	 * entries and copying registers one at a time.
+	 * Not too sure yet whether that's very useful.
+	 */
+
+	if( memcmp((unsigned char*)fpregs,
+		_xtensa_reginfo_tables, _xtensa_reginfo_table_size) ) {
+	    return -1;
+	}
+
+	/* Before restoring coprocessor state from memory,
+	 * ensure any live coprocessor contents for this
+	 * task are first invalidated.
+	 */
+
+	local_irq_save(flags);
+
+	for (i = 0; i < XCHAL_CP_MAX; i++) {
+		if (tsk == coprocessor_info[i].owner) {
+			enable_coprocessor(i);
+			save_coprocessor_registers(
+			    tsk->thread.cp_save+coprocessor_info[i].offset,i);
+			coprocessor_info[i].owner = 0;
+			disable_coprocessor(i);
+		}
+	}
+
+	local_irq_restore(flags);
+
+	/*  Now restore coprocessor & extra state:  */
+
+	memcpy(tsk->thread.cp_save,
+		(unsigned char*)fpregs + _xtensa_reginfo_table_size,
+		XTENSA_CP_EXTRA_SIZE);
+#endif
+	return 0;
+}
+/*
+ * Fill in the CP structure for a core dump for a particular task.
+ */
+
+int
+dump_task_fpu(struct pt_regs *regs, struct task_struct *task, elf_fpregset_t *r)
+{
+/* see asm/coprocessor.h for this magic number 16 */
+#if TOTAL_CPEXTRA_SIZE > 16
+	do_save_fpregs (r, regs, task);
+
+	/*  For now, bit 16 means some extra state may be present:  */
+// FIXME!! need to track to return more accurate mask
+	return 0x10000 | XCHAL_CP_MASK;
+#else
+	return 0;	/* no coprocessors active on this processor */
+#endif
+}
+
+/*
+ * Fill in the CP structure for a core dump.
+ * This includes any FPU coprocessor.
+ * Here, we dump all coprocessors, and other ("extra") custom state.
+ *
+ * This function is called by elf_core_dump() in fs/binfmt_elf.c
+ * (in which case 'regs' comes from calls to do_coredump, see signals.c).
+ */
+int  dump_fpu(struct pt_regs *regs, elf_fpregset_t *r)
+{
+	return dump_task_fpu(regs, current, r);
+}
diff --git a/arch/xtensa/kernel/ptrace.c b/arch/xtensa/kernel/ptrace.c
new file mode 100644
--- /dev/null
+++ b/arch/xtensa/kernel/ptrace.c
@@ -0,0 +1,408 @@
+// TODO some minor issues
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005  Tensilica Inc.
+ *
+ * Joe Taylor	<joe@tensilica.com, joetylr@yahoo.com>
+ * Chris Zankel <chris@zankel.net>
+ * Scott Foehner<sfoehner@yahoo.com>,
+ * Kevin Chea
+ * Marc Gauthier<marc@tensilica.com> <marc@alumni.uwaterloo.ca>
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/errno.h>
+#include <linux/ptrace.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/security.h>
+#include <linux/signal.h>
+
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
+#include <asm/ptrace.h>
+#include <asm/elf.h>
+
+#define TEST_KERNEL	// verify kernel operations FIXME: remove
+
+
+/*
+ * Called by kernel/ptrace.c when detaching..
+ *
+ * Make sure single step bits etc are not set.
+ */
+
+void ptrace_disable(struct task_struct *child)
+{
+	/* Nothing to do.. */
+}
+
+int sys_ptrace(long request, long pid, long addr, long data)
+{
+	struct task_struct *child;
+	int ret = -EPERM;
+
+	lock_kernel();
+
+#if 0
+	if ((int)request != 1)
+	printk("ptrace(r=%d,pid=%d,addr=%08lx,data=%08lx)\n",
+	       (int) request, (int) pid, (unsigned long) addr,
+	       (unsigned long) data);
+#endif
+
+	if (request == PTRACE_TRACEME) {
+
+		/* Are we already being traced? */
+
+		if (current->ptrace & PT_PTRACED)
+			goto out;
+
+		if ((ret = security_ptrace(current->parent, current)))
+			goto out;
+
+		/* Set the ptrace bit in the process flags. */
+
+		current->ptrace |= PT_PTRACED;
+		ret = 0;
+		goto out;
+	}
+
+	ret = -ESRCH;
+	read_lock(&tasklist_lock);
+	child = find_task_by_pid(pid);
+	if (child)
+		get_task_struct(child);
+	read_unlock(&tasklist_lock);
+	if (!child)
+		goto out;
+
+	ret = -EPERM;
+	if (pid == 1)		/* you may not mess with init */
+		goto out;
+
+	if (request == PTRACE_ATTACH) {
+		ret = ptrace_attach(child);
+		goto out_tsk;
+	}
+
+	if ((ret = ptrace_check_attach(child, request == PTRACE_KILL)) < 0)
+		goto out_tsk;
+
+	switch (request) {
+	case PTRACE_PEEKTEXT: /* read word at location addr. */
+	case PTRACE_PEEKDATA:
+	{
+		unsigned long tmp;
+		int copied;
+
+		copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
+		ret = -EIO;
+		if (copied != sizeof(tmp))
+			break;
+		ret = put_user(tmp,(unsigned long *) data);
+
+		goto out;
+	}
+
+	/* Read the word at location addr in the USER area.  */
+
+	case PTRACE_PEEKUSR:
+		{
+		struct pt_regs *regs;
+		unsigned long tmp;
+
+		regs = xtensa_pt_regs(child);
+		tmp = 0;  /* Default return value. */
+
+		switch(addr) {
+
+		case REG_AR_BASE ... REG_AR_BASE + XCHAL_NUM_AREGS - 1:
+			{
+			int ar = addr - REG_AR_BASE - regs->windowbase * 4;
+			ar &= (XCHAL_NUM_AREGS - 1);
+			if (ar < 16 && ar + (regs->wmask >> 4) * 4 >= 0)
+				tmp = regs->areg[ar];
+			else
+				ret = -EIO;
+			break;
+			}
+		case REG_A_BASE ... REG_A_BASE + 15:
+			tmp = regs->areg[addr - REG_A_BASE];
+			break;
+		case REG_PC:
+			tmp = regs->pc;
+			break;
+		case REG_PS:
+			/* Note:  PS.EXCM is not set while user task is running;
+			 * its being set in regs is for exception handling
+			 * convenience.  */
+			tmp = (regs->ps & ~XCHAL_PS_EXCM_MASK);
+			break;
+		case REG_WB:
+			tmp = regs->windowbase;
+			break;
+		case REG_WS:
+			tmp = regs->windowstart;
+			break;
+		case REG_LBEG:
+			tmp = regs->lbeg;
+			break;
+		case REG_LEND:
+			tmp = regs->lend;
+			break;
+		case REG_LCOUNT:
+			tmp = regs->lcount;
+			break;
+		case REG_SAR:
+			tmp = regs->sar;
+			break;
+		case REG_DEPC:
+			tmp = regs->depc;
+			break;
+		case REG_EXCCAUSE:
+			tmp = regs->exccause;
+			break;
+		case REG_EXCVADDR:
+			tmp = regs->excvaddr;
+			break;
+		case SYSCALL_NR:
+			tmp = regs->syscall;
+			break;
+		default:
+			tmp = 0;
+			ret = -EIO;
+			goto out;
+		}
+		ret = put_user(tmp, (unsigned long *) data);
+		goto out;
+		}
+
+	case PTRACE_POKETEXT: /* write the word at location addr. */
+	case PTRACE_POKEDATA:
+		if (access_process_vm(child, addr, &data, sizeof(data), 1)
+		    == sizeof(data))
+			break;
+		ret = -EIO;
+		goto out;
+
+	case PTRACE_POKEUSR:
+		{
+		struct pt_regs *regs;
+		regs = xtensa_pt_regs(child);
+
+		switch (addr) {
+		case REG_AR_BASE ... REG_AR_BASE + XCHAL_NUM_AREGS - 1:
+			{
+			int ar = addr - REG_AR_BASE - regs->windowbase * 4;
+			if (ar < 16 && ar + (regs->wmask >> 4) * 4 >= 0)
+				regs->areg[ar & (XCHAL_NUM_AREGS - 1)] = data;
+			else
+				ret = -EIO;
+			break;
+			}
+		case REG_A_BASE ... REG_A_BASE + 15:
+			regs->areg[addr - REG_A_BASE] = data;
+			break;
+		case REG_PC:
+			regs->pc = data;
+			break;
+		case SYSCALL_NR:
+			regs->syscall = data;
+			break;
+#ifdef TEST_KERNEL
+		case REG_WB:
+			regs->windowbase = data;
+			break;
+		case REG_WS:
+			regs->windowstart = data;
+			break;
+#endif
+
+		default:
+			/* The rest are not allowed. */
+			ret = -EIO;
+			break;
+		}
+		break;
+		}
+
+	/* continue and stop at next (return from) syscall */
+	case PTRACE_SYSCALL:
+	case PTRACE_CONT: /* restart after signal. */
+	{
+		ret = -EIO;
+		if (!valid_signal(data))
+			break;
+		if (request == PTRACE_SYSCALL)
+			set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
+		else
+			clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
+		child->exit_code = data;
+		/* Make sure the single step bit is not set. */
+		child->ptrace &= ~PT_SINGLESTEP;
+		wake_up_process(child);
+		ret = 0;
+		break;
+	}
+
+	/*
+	 * make the child exit.  Best I can do is send it a sigkill.
+	 * perhaps it should be put in the status that it wants to
+	 * exit.
+	 */
+	case PTRACE_KILL:
+		ret = 0;
+		if (child->state == EXIT_ZOMBIE)	/* already dead */
+			break;
+		child->exit_code = SIGKILL;
+		child->ptrace &= ~PT_SINGLESTEP;
+		wake_up_process(child);
+		break;
+
+	case PTRACE_SINGLESTEP:
+		ret = -EIO;
+		if (!valid_signal(data))
+			break;
+		clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
+		child->ptrace |= PT_SINGLESTEP;
+		child->exit_code = data;
+		wake_up_process(child);
+		ret = 0;
+		break;
+
+	case PTRACE_GETREGS:
+	{
+		/* 'data' points to user memory in which to write.
+		 * Mainly due to the non-live register values, we
+		 * reformat the register values into something more
+		 * standard.  For convenience, we use the handy
+		 * elf_gregset_t format. */
+
+		xtensa_gregset_t format;
+		struct pt_regs *regs = xtensa_pt_regs(child);
+
+		do_copy_regs (&format, regs, child);
+
+		/* Now, copy to user space nice and easy... */
+		ret = 0;
+		if (copy_to_user((void *)data, &format, sizeof(elf_gregset_t)))
+			ret = -EFAULT;
+		break;
+	}
+
+	case PTRACE_SETREGS:
+	{
+		/* 'data' points to user memory that contains the new
+		 * values in the elf_gregset_t format. */
+
+		xtensa_gregset_t format;
+		struct pt_regs *regs = xtensa_pt_regs(child);
+
+		if (copy_from_user(&format,(void *)data,sizeof(elf_gregset_t))){
+			ret = -EFAULT;
+			break;
+		}
+
+		/* FIXME: Perhaps we want some sanity checks on
+		 * these user-space values?  See ARM version.  Are
+		 * debuggers a security concern? */
+
+		do_restore_regs (&format, regs, child);
+
+		ret = 0;
+		break;
+	}
+
+	case PTRACE_GETFPREGS:
+	{
+		/* 'data' points to user memory in which to write.
+		 * For convenience, we use the handy
+		 * elf_fpregset_t format. */
+
+		elf_fpregset_t fpregs;
+		struct pt_regs *regs = xtensa_pt_regs(child);
+
+		do_save_fpregs (&fpregs, regs, child);
+
+		/* Now, copy to user space nice and easy... */
+		ret = 0;
+		if (copy_to_user((void *)data, &fpregs, sizeof(elf_fpregset_t)))
+			ret = -EFAULT;
+
+		break;
+	}
+
+	case PTRACE_SETFPREGS:
+	{
+		/* 'data' points to user memory that contains the new
+		 * values in the elf_fpregset_t format.
+		 */
+		elf_fpregset_t fpregs;
+		struct pt_regs *regs = xtensa_pt_regs(child);
+
+		ret = 0;
+		if (copy_from_user(&fpregs, (void *)data, sizeof(elf_fpregset_t))) {
+			ret = -EFAULT;
+			break;
+		}
+
+		if (do_restore_fpregs (&fpregs, regs, child))
+			ret = -EIO;
+		break;
+	}
+
+	case PTRACE_GETFPREGSIZE:
+		/* 'data' points to 'unsigned long' set to the size
+		 * of elf_fpregset_t
+		 */
+		ret = put_user(sizeof(elf_fpregset_t), (unsigned long *) data);
+		break;
+
+	case PTRACE_DETACH: /* detach a process that was attached. */
+		ret = ptrace_detach(child, data);
+		break;
+
+	default:
+		ret = ptrace_request(child, request, addr, data);
+		goto out;
+	}
+out_tsk:
+	put_task_struct(child);
+out:
+	unlock_kernel();
+	return ret;
+}
+
+void do_syscall_trace(void)
+{
+	if (!test_thread_flag(TIF_SYSCALL_TRACE))
+		return;
+
+	if (!(current->ptrace & PT_PTRACED))
+		return;
+
+	/*
+	 * The 0x80 provides a way for the tracing parent to distinguish
+	 * between a syscall stop and SIGTRAP delivery
+	 */
+	ptrace_notify(SIGTRAP|((current->ptrace & PT_TRACESYSGOOD) ? 0x80 : 0));
+
+	/*
+	 * this isn't the same as continuing with a signal, but it will do
+	 * for normal use.  strace only continues with a signal if the
+	 * stopping signal is not SIGTRAP.  -brl
+	 */
+	if (current->exit_code) {
+		send_sig(current->exit_code, current, 1);
+		current->exit_code = 0;
+	}
+}
diff --git a/arch/xtensa/kernel/semaphore.c b/arch/xtensa/kernel/semaphore.c
new file mode 100644
--- /dev/null
+++ b/arch/xtensa/kernel/semaphore.c
@@ -0,0 +1,226 @@
+/*
+ * arch/xtensa/kernel/semaphore.c
+ *
+ * Generic semaphore code. Buyer beware. Do your own specific changes
+ * in <asm/semaphore-helper.h>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ *
+ * Joe Taylor	<joe@tensilica.com, joetylr@yahoo.com>
+ * Chris Zankel	<chris@zankel.net>
+ * Marc Gauthier<marc@tensilica.com, marc@alumni.uwaterloo.ca>
+ * Kevin Chea
+ */
+
+#include <linux/sched.h>
+#include <linux/wait.h>
+#include <linux/init.h>
+#include <asm/semaphore.h>
+#include <asm/errno.h>
+
+/*
+ * These two _must_ execute atomically wrt each other.
+ */
+
+static __inline__ void wake_one_more(struct semaphore * sem)
+{
+	atomic_inc((atomic_t *)&sem->sleepers);
+}
+
+static __inline__ int waking_non_zero(struct semaphore *sem)
+{
+	unsigned long flags;
+	int ret = 0;
+
+	spin_lock_irqsave(&semaphore_wake_lock, flags);
+	if (sem->sleepers > 0) {
+		sem->sleepers--;
+		ret = 1;
+	}
+	spin_unlock_irqrestore(&semaphore_wake_lock, flags);
+	return ret;
+}
+
+/*
+ * waking_non_zero_interruptible:
+ *	1	got the lock
+ *	0	go to sleep
+ *	-EINTR	interrupted
+ *
+ * We must undo the sem->count down_interruptible() increment while we are
+ * protected by the spinlock in order to make atomic this atomic_inc() with the
+ * atomic_read() in wake_one_more(), otherwise we can race. -arca
+ */
+
+static __inline__ int waking_non_zero_interruptible(struct semaphore *sem,
+						struct task_struct *tsk)
+{
+	unsigned long flags;
+	int ret = 0;
+
+	spin_lock_irqsave(&semaphore_wake_lock, flags);
+	if (sem->sleepers > 0) {
+		sem->sleepers--;
+		ret = 1;
+	} else if (signal_pending(tsk)) {
+		atomic_inc(&sem->count);
+		ret = -EINTR;
+	}
+	spin_unlock_irqrestore(&semaphore_wake_lock, flags);
+	return ret;
+}
+
+/*
+ * waking_non_zero_trylock:
+ *	1	failed to lock
+ *	0	got the lock
+ *
+ * We must undo the sem->count down_trylock() increment while we are
+ * protected by the spinlock in order to make atomic this atomic_inc() with the
+ * atomic_read() in wake_one_more(), otherwise we can race. -arca
+ */
+
+static __inline__ int waking_non_zero_trylock(struct semaphore *sem)
+{
+	unsigned long flags;
+	int ret = 1;
+
+	spin_lock_irqsave(&semaphore_wake_lock, flags);
+	if (sem->sleepers <= 0)
+		atomic_inc(&sem->count);
+	else {
+		sem->sleepers--;
+		ret = 0;
+	}
+	spin_unlock_irqrestore(&semaphore_wake_lock, flags);
+	return ret;
+}
+
+spinlock_t semaphore_wake_lock;
+
+/*
+ * Semaphores are implemented using a two-way counter:
+ * The "count" variable is decremented for each process
+ * that tries to sleep, while the "waking" variable is
+ * incremented when the "up()" code goes to wake up waiting
+ * processes.
+ *
+ * Notably, the inline "up()" and "down()" functions can
+ * efficiently test if they need to do any extra work (up
+ * needs to do something only if count was negative before
+ * the increment operation.
+ *
+ * waking_non_zero() (from asm/semaphore.h) must execute
+ * atomically.
+ *
+ * When __up() is called, the count was negative before
+ * incrementing it, and we need to wake up somebody.
+ *
+ * This routine adds one to the count of processes that need to
+ * wake up and exit.  ALL waiting processes actually wake up but
+ * only the one that gets to the "waking" field first will gate
+ * through and acquire the semaphore.  The others will go back
+ * to sleep.
+ *
+ * Note that these functions are only called when there is
+ * contention on the lock, and as such all this is the
+ * "non-critical" part of the whole semaphore business. The
+ * critical part is the inline stuff in <asm/semaphore.h>
+ * where we want to avoid any extra jumps and calls.
+ */
+
+void __up(struct semaphore *sem)
+{
+	wake_one_more(sem);
+	wake_up(&sem->wait);
+}
+
+/*
+ * Perform the "down" function.  Return zero for semaphore acquired,
+ * return negative for signalled out of the function.
+ *
+ * If called from __down, the return is ignored and the wait loop is
+ * not interruptible.  This means that a task waiting on a semaphore
+ * using "down()" cannot be killed until someone does an "up()" on
+ * the semaphore.
+ *
+ * If called from __down_interruptible, the return value gets checked
+ * upon return.  If the return value is negative then the task continues
+ * with the negative value in the return register (it can be tested by
+ * the caller).
+ *
+ * Either form may be used in conjunction with "up()".
+ *
+ */
+
+#define DOWN_VAR				\
+	struct task_struct *tsk = current;	\
+	wait_queue_t wait;			\
+	init_waitqueue_entry(&wait, tsk);
+
+#define DOWN_HEAD(task_state)						\
+									\
+									\
+	tsk->state = (task_state);					\
+	add_wait_queue(&sem->wait, &wait);				\
+									\
+	/*								\
+	 * Ok, we're set up.  sem->count is known to be less than zero	\
+	 * so we must wait.						\
+	 *								\
+	 * We can let go the lock for purposes of waiting.		\
+	 * We re-acquire it after awaking so as to protect		\
+	 * all semaphore operations.					\
+	 *								\
+	 * If "up()" is called before we call waking_non_zero() then	\
+	 * we will catch it right away.  If it is called later then	\
+	 * we will have to go through a wakeup cycle to catch it.	\
+	 *								\
+	 * Multiple waiters contend for the semaphore lock to see	\
+	 * who gets to gate through and who has to wait some more.	\
+	 */								\
+	for (;;) {
+
+#define DOWN_TAIL(task_state)			\
+		tsk->state = (task_state);	\
+	}					\
+	tsk->state = TASK_RUNNING;		\
+	remove_wait_queue(&sem->wait, &wait);
+
+void __sched __down(struct semaphore * sem)
+{
+	DOWN_VAR
+	DOWN_HEAD(TASK_UNINTERRUPTIBLE)
+	if (waking_non_zero(sem))
+		break;
+	schedule();
+	DOWN_TAIL(TASK_UNINTERRUPTIBLE)
+}
+
+int __sched __down_interruptible(struct semaphore * sem)
+{
+	int ret = 0;
+	DOWN_VAR
+	DOWN_HEAD(TASK_INTERRUPTIBLE)
+
+	ret = waking_non_zero_interruptible(sem, tsk);
+	if (ret)
+	{
+		if (ret == 1)
+			/* ret != 0 only if we get interrupted -arca */
+			ret = 0;
+		break;
+	}
+	schedule();
+	DOWN_TAIL(TASK_INTERRUPTIBLE)
+	return ret;
+}
+
+int __down_trylock(struct semaphore * sem)
+{
+	return waking_non_zero_trylock(sem);
+}
diff --git a/arch/xtensa/kernel/setup.c b/arch/xtensa/kernel/setup.c
new file mode 100644
--- /dev/null
+++ b/arch/xtensa/kernel/setup.c
@@ -0,0 +1,520 @@
+/*
+ * arch/xtensa/setup.c
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995  Linus Torvalds
+ * Copyright (C) 2001 - 2005  Tensilica Inc.
+ *
+ * Chris Zankel	<chris@zankel.net>
+ * Joe Taylor	<joe@tensilica.com, joetylr@yahoo.com>
+ * Kevin Chea
+ * Marc Gauthier<marc@tensilica.com> <marc@alumni.uwaterloo.ca>
+ */
+
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/proc_fs.h>
+#include <linux/tty.h>
+#include <linux/bootmem.h>
+#include <linux/kernel.h>
+
+#if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE)
+# include <linux/console.h>
+#endif
+
+#ifdef CONFIG_RTC
+# include <linux/timex.h>
+#endif
+
+#ifdef CONFIG_PROC_FS
+# include <linux/seq_file.h>
+#endif
+
+#include <asm/system.h>
+#include <asm/bootparam.h>
+#include <asm/pgtable.h>
+#include <asm/processor.h>
+#include <asm/timex.h>
+#include <asm/platform.h>
+#include <asm/page.h>
+#include <asm/setup.h>
+
+#include <xtensa/config/system.h>
+
+#if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE)
+struct screen_info screen_info = { 0, 24, 0, 0, 0, 80, 0, 0, 0, 24, 1, 16};
+#endif
+
+#ifdef CONFIG_BLK_DEV_FD
+extern struct fd_ops no_fd_ops;
+struct fd_ops *fd_ops;
+#endif
+
+#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
+extern struct ide_ops no_ide_ops;
+struct ide_ops *ide_ops;
+#endif
+
+extern struct rtc_ops no_rtc_ops;
+struct rtc_ops *rtc_ops;
+
+#ifdef CONFIG_PC_KEYB
+extern struct kbd_ops no_kbd_ops;
+struct kbd_ops *kbd_ops;
+#endif
+
+#ifdef CONFIG_BLK_DEV_INITRD
+extern void *initrd_start;
+extern void *initrd_end;
+extern void *__initrd_start;
+extern void *__initrd_end;
+int initrd_is_mapped = 0;
+extern int initrd_below_start_ok;
+#endif
+
+unsigned char aux_device_present;
+extern unsigned long loops_per_jiffy;
+
+/* Command line specified as configuration option. */
+
+static char command_line[COMMAND_LINE_SIZE];
+
+#ifdef CONFIG_CMDLINE_BOOL
+static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE;
+#endif
+
+sysmem_info_t __initdata sysmem;
+
+#ifdef CONFIG_BLK_DEV_INITRD
+int initrd_is_mapped;
+#endif
+
+extern void init_mmu(void);
+
+/*
+ * Boot parameter parsing.
+ *
+ * The Xtensa port uses a list of variable-sized tags to pass data to
+ * the kernel. The first tag must be a BP_TAG_FIRST tag for the list
+ * to be recognised. The list is terminated with a zero-sized
+ * BP_TAG_LAST tag.
+ */
+
+typedef struct tagtable {
+	u32 tag;
+	int (*parse)(const bp_tag_t*);
+} tagtable_t;
+
+#define __tagtable(tag, fn) static tagtable_t __tagtable_##fn 		\
+	__attribute__((unused, __section__(".taglist"))) = { tag, fn }
+
+/* parse current tag */
+
+static int __init parse_tag_mem(const bp_tag_t *tag)
+{
+	meminfo_t *mi = (meminfo_t*)(tag->data);
+
+	if (mi->type != MEMORY_TYPE_CONVENTIONAL)
+		return -1;
+
+	if (sysmem.nr_banks >= SYSMEM_BANKS_MAX) {
+		printk(KERN_WARNING
+		       "Ignoring memory bank 0x%08lx size %ldKB\n",
+		       (unsigned long)mi->start,
+		       (unsigned long)mi->end - (unsigned long)mi->start);
+		return -EINVAL;
+	}
+	sysmem.bank[sysmem.nr_banks].type  = mi->type;
+	sysmem.bank[sysmem.nr_banks].start = PAGE_ALIGN(mi->start);
+	sysmem.bank[sysmem.nr_banks].end   = mi->end & PAGE_SIZE;
+	sysmem.nr_banks++;
+
+	return 0;
+}
+
+__tagtable(BP_TAG_MEMORY, parse_tag_mem);
+
+#ifdef CONFIG_BLK_DEV_INITRD
+
+static int __init parse_tag_initrd(const bp_tag_t* tag)
+{
+	meminfo_t* mi;
+	mi = (meminfo_t*)(tag->data);
+	initrd_start = (void*)(mi->start);
+	initrd_end = (void*)(mi->end);
+
+	return 0;
+}
+
+__tagtable(BP_TAG_INITRD, parse_tag_initrd);
+
+#endif /* CONFIG_BLK_DEV_INITRD */
+
+static int __init parse_tag_cmdline(const bp_tag_t* tag)
+{
+	strncpy(command_line, (char*)(tag->data), COMMAND_LINE_SIZE);
+	command_line[COMMAND_LINE_SIZE - 1] = '\0';
+	return 0;
+}
+
+__tagtable(BP_TAG_COMMAND_LINE, parse_tag_cmdline);
+
+static int __init parse_bootparam(const bp_tag_t* tag)
+{
+	extern tagtable_t __tagtable_begin, __tagtable_end;
+	tagtable_t *t;
+
+	/* Boot parameters must start with a BP_TAG_FIRST tag. */
+
+	if (tag->id != BP_TAG_FIRST) {
+		printk(KERN_WARNING "Invalid boot parameters!\n");
+		return 0;
+	}
+
+	tag = (bp_tag_t*)((unsigned long)tag + sizeof(bp_tag_t) + tag->size);
+
+	/* Parse all tags. */
+
+	while (tag != NULL && tag->id != BP_TAG_LAST) {
+	 	for (t = &__tagtable_begin; t < &__tagtable_end; t++) {
+			if (tag->id == t->tag) {
+				t->parse(tag);
+				break;
+			}
+		}
+		if (t == &__tagtable_end)
+			printk(KERN_WARNING "Ignoring tag "
+			       "0x%08x\n", tag->id);
+		tag = (bp_tag_t*)((unsigned long)(tag + 1) + tag->size);
+	}
+
+	return 0;
+}
+
+/*
+ * Initialize architecture. (Early stage)
+ */
+
+void __init init_arch(bp_tag_t *bp_start)
+{
+
+#ifdef CONFIG_BLK_DEV_INITRD
+	initrd_start = &__initrd_start;
+	initrd_end = &__initrd_end;
+#endif
+
+	sysmem.nr_banks = 0;
+
+#ifdef CONFIG_CMDLINE_BOOL
+	strcpy(command_line, default_command_line);
+#endif
+
+	/* Parse boot parameters */
+
+        if (bp_start)
+	  parse_bootparam(bp_start);
+
+	if (sysmem.nr_banks == 0) {
+		sysmem.nr_banks = 1;
+		sysmem.bank[0].start = PLATFORM_DEFAULT_MEM_START;
+		sysmem.bank[0].end = PLATFORM_DEFAULT_MEM_START
+				     + PLATFORM_DEFAULT_MEM_SIZE;
+	}
+
+	/* Early hook for platforms */
+
+	platform_init(bp_start);
+
+	/* Initialize MMU. */
+
+	init_mmu();
+}
+
+/*
+ * Initialize system. Setup memory and reserve regions.
+ */
+
+extern char _end;
+extern char _stext;
+extern char _WindowVectors_text_start;
+extern char _WindowVectors_text_end;
+extern char _DebugInterruptVector_literal_start;
+extern char _DebugInterruptVector_text_end;
+extern char _KernelExceptionVector_literal_start;
+extern char _KernelExceptionVector_text_end;
+extern char _UserExceptionVector_literal_start;
+extern char _UserExceptionVector_text_end;
+extern char _DoubleExceptionVector_literal_start;
+extern char _DoubleExceptionVector_text_end;
+
+void __init setup_arch(char **cmdline_p)
+{
+	extern int mem_reserve(unsigned long, unsigned long, int);
+	extern void bootmem_init(void);
+
+	memcpy(saved_command_line, command_line, COMMAND_LINE_SIZE);
+	saved_command_line[COMMAND_LINE_SIZE-1] = '\0';
+	*cmdline_p = command_line;
+
+	/* Reserve some memory regions */
+
+#ifdef CONFIG_BLK_DEV_INITRD
+	if (initrd_start < initrd_end) {
+		initrd_is_mapped = mem_reserve(__pa(initrd_start),
+					       __pa(initrd_end), 0);
+		initrd_below_start_ok = 1;
+ 	} else {
+		initrd_start = 0;
+	}
+#endif
+
+	mem_reserve(__pa(&_stext),__pa(&_end), 1);
+
+	mem_reserve(__pa(&_WindowVectors_text_start),
+		    __pa(&_WindowVectors_text_end), 0);
+
+	mem_reserve(__pa(&_DebugInterruptVector_literal_start),
+		    __pa(&_DebugInterruptVector_text_end), 0);
+
+	mem_reserve(__pa(&_KernelExceptionVector_literal_start),
+		    __pa(&_KernelExceptionVector_text_end), 0);
+
+	mem_reserve(__pa(&_UserExceptionVector_literal_start),
+		    __pa(&_UserExceptionVector_text_end), 0);
+
+	mem_reserve(__pa(&_DoubleExceptionVector_literal_start),
+		    __pa(&_DoubleExceptionVector_text_end), 0);
+
+	bootmem_init();
+
+	platform_setup(cmdline_p);
+
+
+	paging_init();
+
+#ifdef CONFIG_VT
+# if defined(CONFIG_VGA_CONSOLE)
+	conswitchp = &vga_con;
+# elif defined(CONFIG_DUMMY_CONSOLE)
+	conswitchp = &dummy_con;
+# endif
+#endif
+
+#if CONFIG_PCI
+	platform_pcibios_init();
+#endif
+}
+
+void machine_restart(char * cmd)
+{
+	platform_restart();
+}
+
+void machine_halt(void)
+{
+	platform_halt();
+	while (1);
+}
+
+void machine_power_off(void)
+{
+	platform_power_off();
+	while (1);
+}
+#ifdef CONFIG_PROC_FS
+
+/*
+ * Display some core information through /proc/cpuinfo.
+ */
+
+static int
+c_show(struct seq_file *f, void *slot)
+{
+	/* high-level stuff */
+	seq_printf(f,"processor\t: 0\n"
+		     "vendor_id\t: Tensilica\n"
+		     "model\t\t: Xtensa " XCHAL_HW_RELEASE_NAME "\n"
+		     "core ID\t\t: " XCHAL_CORE_ID "\n"
+		     "build ID\t: 0x%x\n"
+		     "byte order\t: %s\n"
+ 		     "cpu MHz\t\t: %lu.%02lu\n"
+		     "bogomips\t: %lu.%02lu\n",
+		     XCHAL_BUILD_UNIQUE_ID,
+		     XCHAL_HAVE_BE ?  "big" : "little",
+		     CCOUNT_PER_JIFFY/(1000000/HZ),
+		     (CCOUNT_PER_JIFFY/(10000/HZ)) % 100,
+		     loops_per_jiffy/(500000/HZ),
+		     (loops_per_jiffy/(5000/HZ)) % 100);
+
+	seq_printf(f,"flags\t\t: "
+#if XCHAL_HAVE_NMI
+		     "nmi "
+#endif
+#if XCHAL_HAVE_DEBUG
+		     "debug "
+# if XCHAL_HAVE_OCD
+		     "ocd "
+# endif
+#endif
+#if XCHAL_HAVE_DENSITY
+	    	     "density "
+#endif
+#if XCHAL_HAVE_BOOLEANS
+		     "boolean "
+#endif
+#if XCHAL_HAVE_LOOPS
+		     "loop "
+#endif
+#if XCHAL_HAVE_NSA
+		     "nsa "
+#endif
+#if XCHAL_HAVE_MINMAX
+		     "minmax "
+#endif
+#if XCHAL_HAVE_SEXT
+		     "sext "
+#endif
+#if XCHAL_HAVE_CLAMPS
+		     "clamps "
+#endif
+#if XCHAL_HAVE_MAC16
+		     "mac16 "
+#endif
+#if XCHAL_HAVE_MUL16
+		     "mul16 "
+#endif
+#if XCHAL_HAVE_MUL32
+		     "mul32 "
+#endif
+#if XCHAL_HAVE_MUL32_HIGH
+		     "mul32h "
+#endif
+#if XCHAL_HAVE_FP
+		     "fpu "
+#endif
+		     "\n");
+
+	/* Registers. */
+	seq_printf(f,"physical aregs\t: %d\n"
+		     "misc regs\t: %d\n"
+		     "ibreak\t\t: %d\n"
+		     "dbreak\t\t: %d\n",
+		     XCHAL_NUM_AREGS,
+		     XCHAL_NUM_MISC_REGS,
+		     XCHAL_NUM_IBREAK,
+		     XCHAL_NUM_DBREAK);
+
+
+	/* Interrupt. */
+	seq_printf(f,"num ints\t: %d\n"
+		     "ext ints\t: %d\n"
+		     "int levels\t: %d\n"
+		     "timers\t\t: %d\n"
+		     "debug level\t: %d\n",
+		     XCHAL_NUM_INTERRUPTS,
+		     XCHAL_NUM_EXTINTERRUPTS,
+		     XCHAL_NUM_INTLEVELS,
+		     XCHAL_NUM_TIMERS,
+		     XCHAL_DEBUGLEVEL);
+
+	/* Coprocessors */
+#if XCHAL_HAVE_CP
+	seq_printf(f, "coprocessors\t: %d\n", XCHAL_CP_NUM);
+#else
+	seq_printf(f, "coprocessors\t: none\n");
+#endif
+
+	/* {I,D}{RAM,ROM} and XLMI */
+	seq_printf(f,"inst ROMs\t: %d\n"
+		     "inst RAMs\t: %d\n"
+		     "data ROMs\t: %d\n"
+		     "data RAMs\t: %d\n"
+		     "XLMI ports\t: %d\n",
+		     XCHAL_NUM_IROM,
+		     XCHAL_NUM_IRAM,
+		     XCHAL_NUM_DROM,
+		     XCHAL_NUM_DRAM,
+		     XCHAL_NUM_XLMI);
+
+	/* Cache */
+	seq_printf(f,"icache line size: %d\n"
+		     "icache ways\t: %d\n"
+		     "icache size\t: %d\n"
+		     "icache flags\t: "
+#if XCHAL_ICACHE_LINE_LOCKABLE
+		     "lock"
+#endif
+		     "\n"
+		     "dcache line size: %d\n"
+		     "dcache ways\t: %d\n"
+		     "dcache size\t: %d\n"
+		     "dcache flags\t: "
+#if XCHAL_DCACHE_IS_WRITEBACK
+		     "writeback"
+#endif
+#if XCHAL_DCACHE_LINE_LOCKABLE
+		     "lock"
+#endif
+		     "\n",
+		     XCHAL_ICACHE_LINESIZE,
+		     XCHAL_ICACHE_WAYS,
+		     XCHAL_ICACHE_SIZE,
+		     XCHAL_DCACHE_LINESIZE,
+		     XCHAL_DCACHE_WAYS,
+		     XCHAL_DCACHE_SIZE);
+
+	/* MMU */
+	seq_printf(f,"ASID bits\t: %d\n"
+		     "ASID invalid\t: %d\n"
+		     "ASID kernel\t: %d\n"
+		     "rings\t\t: %d\n"
+		     "itlb ways\t: %d\n"
+		     "itlb AR ways\t: %d\n"
+		     "dtlb ways\t: %d\n"
+		     "dtlb AR ways\t: %d\n",
+		     XCHAL_MMU_ASID_BITS,
+		     XCHAL_MMU_ASID_INVALID,
+		     XCHAL_MMU_ASID_KERNEL,
+		     XCHAL_MMU_RINGS,
+		     XCHAL_ITLB_WAYS,
+		     XCHAL_ITLB_ARF_WAYS,
+		     XCHAL_DTLB_WAYS,
+		     XCHAL_DTLB_ARF_WAYS);
+
+	return 0;
+}
+
+/*
+ * We show only CPU #0 info.
+ */
+static void *
+c_start(struct seq_file *f, loff_t *pos)
+{
+	return (void *) ((*pos == 0) ? (void *)1 : NULL);
+}
+
+static void *
+c_next(struct seq_file *f, void *v, loff_t *pos)
+{
+	return NULL;
+}
+
+static void
+c_stop(struct seq_file *f, void *v)
+{
+}
+
+struct seq_operations cpuinfo_op =
+{
+	start:  c_start,
+	next:   c_next,
+	stop:   c_stop,
+	show:   c_show
+};
+
+#endif /* CONFIG_PROC_FS */
+
diff --git a/arch/xtensa/kernel/signal.c b/arch/xtensa/kernel/signal.c
new file mode 100644
--- /dev/null
+++ b/arch/xtensa/kernel/signal.c
@@ -0,0 +1,713 @@
+// TODO coprocessor stuff
+/*
+ *  linux/arch/xtensa/kernel/signal.c
+ *
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ *  1997-11-28  Modified for POSIX.1b signals by Richard Henderson
+ *
+ *  Joe Taylor <joe@tensilica.com>
+ *  Chris Zankel <chris@zankel.net>
+ *
+ *
+ *
+ */
+
+#include <xtensa/config/core.h>
+#include <xtensa/hal.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/kernel.h>
+#include <linux/signal.h>
+#include <linux/errno.h>
+#include <linux/wait.h>
+#include <linux/ptrace.h>
+#include <linux/unistd.h>
+#include <linux/stddef.h>
+#include <linux/personality.h>
+#include <asm/ucontext.h>
+#include <asm/uaccess.h>
+#include <asm/pgtable.h>
+#include <asm/cacheflush.h>
+
+#define DEBUG_SIG  0
+
+#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
+
+asmlinkage long sys_wait4(pid_t pid,unsigned int * stat_addr, int options,
+			  struct rusage * ru);
+asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset);
+
+extern struct task_struct *coproc_owners[];
+
+
+/*
+ * Atomically swap in the new signal mask, and wait for a signal.
+ */
+
+int sys_sigsuspend(struct pt_regs *regs)
+{
+	old_sigset_t mask = (old_sigset_t) regs->areg[3];
+	sigset_t saveset;
+
+	mask &= _BLOCKABLE;
+	spin_lock_irq(&current->sighand->siglock);
+	saveset = current->blocked;
+	siginitset(&current->blocked, mask);
+	recalc_sigpending();
+	spin_unlock_irq(&current->sighand->siglock);
+
+	regs->areg[2] = -EINTR;
+	while (1) {
+		current->state = TASK_INTERRUPTIBLE;
+		schedule();
+		if (do_signal(regs, &saveset))
+			return -EINTR;
+	}
+}
+
+asmlinkage int
+sys_rt_sigsuspend(struct pt_regs *regs)
+{
+	sigset_t *unewset = (sigset_t *) regs->areg[4];
+	size_t sigsetsize = (size_t) regs->areg[3];
+	sigset_t saveset, newset;
+	/* XXX: Don't preclude handling different sized sigset_t's.  */
+	if (sigsetsize != sizeof(sigset_t))
+		return -EINVAL;
+
+	if (copy_from_user(&newset, unewset, sizeof(newset)))
+		return -EFAULT;
+	sigdelsetmask(&newset, ~_BLOCKABLE);
+	spin_lock_irq(&current->sighand->siglock);
+	saveset = current->blocked;
+	current->blocked = newset;
+	recalc_sigpending();
+	spin_unlock_irq(&current->sighand->siglock);
+
+	regs->areg[2] = -EINTR;
+	while (1) {
+		current->state = TASK_INTERRUPTIBLE;
+		schedule();
+		if (do_signal(regs, &saveset))
+			return -EINTR;
+	}
+}
+
+asmlinkage int
+sys_sigaction(int sig, const struct old_sigaction *act,
+	      struct old_sigaction *oact)
+{
+	struct k_sigaction new_ka, old_ka;
+	int ret;
+
+	if (act) {
+		old_sigset_t mask;
+		if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
+		    __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
+		    __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
+			return -EFAULT;
+		__get_user(new_ka.sa.sa_flags, &act->sa_flags);
+		__get_user(mask, &act->sa_mask);
+		siginitset(&new_ka.sa.sa_mask, mask);
+	}
+
+	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
+
+	if (!ret && oact) {
+		if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
+		    __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
+		    __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
+			return -EFAULT;
+		__put_user(old_ka.sa.sa_flags, &oact->sa_flags);
+		__put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
+	}
+
+	return ret;
+}
+
+asmlinkage int
+sys_sigaltstack(struct pt_regs *regs)
+{
+	const stack_t *uss = (stack_t *) regs->areg[4];
+	stack_t *uoss = (stack_t *) regs->areg[3];
+
+	if (regs->depc > 64)
+		panic ("Double exception sys_sigreturn\n");
+
+
+	return do_sigaltstack(uss, uoss, regs->areg[1]);
+}
+
+
+/*
+ * Do a signal return; undo the signal stack.
+ */
+
+struct sigframe
+{
+	struct sigcontext sc;
+	struct _cpstate cpstate;
+	unsigned long extramask[_NSIG_WORDS-1];
+	unsigned char retcode[6];
+	unsigned int reserved[4]; /* Reserved area for chaining */
+	unsigned int window[4]; /* Window of 4 registers for initial context */
+};
+
+struct rt_sigframe
+{
+	struct siginfo info;
+	struct ucontext uc;
+	struct _cpstate cpstate;
+	unsigned char retcode[6];
+	unsigned int reserved[4]; /* Reserved area for chaining */
+	unsigned int window[4]; /* Window of 4 registers for initial context */
+};
+
+extern void release_all_cp (struct task_struct *);
+
+
+// FIXME restore_cpextra
+static inline int
+restore_cpextra (struct _cpstate *buf)
+{
+#if 0
+	/* The signal handler may have used coprocessors in which
+	 * case they are still enabled.  We disable them to force a
+	 * reloading of the original task's CP state by the lazy
+	 * context-switching mechanisms of CP exception handling.
+	 * Also, we essentially discard any coprocessor state that the
+	 * signal handler created. */
+
+	struct task_struct *tsk = current;
+	release_all_cp(tsk);
+	return __copy_from_user(tsk->thread.cpextra, buf, TOTAL_CPEXTRA_SIZE);
+#endif
+	return 0;
+}
+
+/* Note: We don't copy double exception 'tregs', we have to finish double exc. first before we return to signal handler! This dbl.exc.handler might cause another double exception, but I think we are fine as the situation is the same as if we had returned to the signal handerl and got an interrupt immediately...
+ */
+
+
+static int
+restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
+{
+	struct thread_struct *thread;
+	unsigned int err = 0;
+	unsigned long ps;
+	struct _cpstate *buf;
+
+#define COPY(x)	err |= __get_user(regs->x, &sc->sc_##x)
+	COPY(pc);
+	COPY(depc);
+	COPY(wmask);
+	COPY(lbeg);
+	COPY(lend);
+	COPY(lcount);
+	COPY(sar);
+	COPY(windowbase);
+	COPY(windowstart);
+#undef COPY
+
+	/* For PS, restore only PS.CALLINC.
+	 * Assume that all other bits are either the same as for the signal
+	 * handler, or the user mode value doesn't matter (e.g. PS.OWB).
+	 */
+	err |= __get_user(ps, &sc->sc_ps);
+	regs->ps = (regs->ps & ~XCHAL_PS_CALLINC_MASK)
+		| (ps & XCHAL_PS_CALLINC_MASK);
+
+	/* Additional corruption checks */
+
+	if ((regs->windowbase >= (XCHAL_NUM_AREGS/4))
+	|| ((regs->windowstart & ~((1<<(XCHAL_NUM_AREGS/4)) - 1)) != 0) )
+		err = 1;
+	if ((regs->lcount > 0)
+	&& ((regs->lbeg > TASK_SIZE) || (regs->lend > TASK_SIZE)) )
+		err = 1;
+
+	/* Restore extended register state.
+	 * See struct thread_struct in processor.h.
+	 */
+	thread = &current->thread;
+
+	err |= __copy_from_user (regs->areg, sc->sc_areg, XCHAL_NUM_AREGS*4);
+	err |= __get_user(buf, &sc->sc_cpstate);
+	if (buf) {
+		if (verify_area(VERIFY_READ, buf, sizeof(*buf)))
+			goto badframe;
+		err |= restore_cpextra(buf);
+	}
+
+	regs->syscall = -1;		/* disable syscall checks */
+	return err;
+
+badframe:
+	return 1;
+}
+
+static inline void
+flush_my_cpstate(struct task_struct *tsk)
+{
+	unsigned long flags;
+	local_irq_save(flags);
+
+#if 0	// FIXME
+	for (i = 0; i < XCHAL_CP_NUM; i++) {
+		if (tsk == coproc_owners[i]) {
+			xthal_validate_cp(i);
+			xthal_save_cpregs(tsk->thread.cpregs_ptr[i], i);
+
+			/* Invalidate and "disown" the cp to allow
+			 * callers the chance to reset cp state in the
+			 * task_struct. */
+
+			xthal_invalidate_cp(i);
+			coproc_owners[i] = 0;
+		}
+	}
+#endif
+	local_irq_restore(flags);
+}
+
+/* Return codes:
+	0:  nothing saved
+	1:  stuff to save, successful
+       -1:  stuff to save, error happened
+*/
+static int
+save_cpextra (struct _cpstate *buf)
+{
+#if (XCHAL_EXTRA_SA_SIZE == 0) && (XCHAL_CP_NUM == 0)
+	return 0;
+#else
+
+	/* FIXME: If a task has never used a coprocessor, there is
+	 * no need to save and restore anything.  Tracking this
+	 * information would allow us to optimize this section.
+	 * Perhaps we can use current->used_math or (current->flags &
+	 * PF_USEDFPU) or define a new field in the thread
+	 * structure. */
+
+	/* We flush any live, task-owned cp state to the task_struct,
+	 * then copy it all to the sigframe.  Then we clear all
+	 * cp/extra state in the task_struct, effectively
+	 * clearing/resetting all cp/extra state for the signal
+	 * handler (cp-exception handling will load these new values
+	 * into the cp/extra registers.)  This step is important for
+	 * things like a floating-point cp, where the OS must reset
+	 * the FCR to the default rounding mode. */
+
+	int err = 0;
+	struct task_struct *tsk = current;
+
+	flush_my_cpstate(tsk);
+	/* Note that we just copy everything: 'extra' and 'cp' state together.*/
+	err |= __copy_to_user(buf, tsk->thread.cp_save, XTENSA_CP_EXTRA_SIZE);
+	memset(tsk->thread.cp_save, 0, XTENSA_CP_EXTRA_SIZE);
+
+#if (XTENSA_CP_EXTRA_SIZE == 0)
+#error Sanity check on memset above, cpextra_size should not be zero.
+#endif
+
+	return err ? -1 : 1;
+#endif
+}
+
+static int
+setup_sigcontext(struct sigcontext *sc, struct _cpstate *cpstate,
+		 struct pt_regs *regs, unsigned long mask)
+{
+	struct thread_struct *thread;
+	int err = 0;
+
+//printk("setup_sigcontext\n");
+#define COPY(x)	err |= __put_user(regs->x, &sc->sc_##x)
+	COPY(pc);
+	COPY(ps);
+	COPY(depc);
+	COPY(wmask);
+	COPY(lbeg);
+	COPY(lend);
+	COPY(lcount);
+	COPY(sar);
+	COPY(windowbase);
+	COPY(windowstart);
+#undef COPY
+
+	/* Save extended register state.
+	 * See struct thread_struct in processor.h.
+	 */
+	thread = &current->thread;
+	err |= __copy_to_user (sc->sc_areg, regs->areg, XCHAL_NUM_AREGS * 4);
+	err |= save_cpextra(cpstate);
+	err |= __put_user(err ? NULL : cpstate, &sc->sc_cpstate);
+	/* non-iBCS2 extensions.. */
+	err |= __put_user(mask, &sc->oldmask);
+
+	return err;
+}
+
+asmlinkage int sys_sigreturn(struct pt_regs *regs)
+{
+	struct sigframe *frame = (struct sigframe *)regs->areg[1];
+	sigset_t set;
+	if (regs->depc > 64)
+		panic ("Double exception sys_sigreturn\n");
+
+	if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
+		goto badframe;
+
+	if (__get_user(set.sig[0], &frame->sc.oldmask)
+	    || (_NSIG_WORDS > 1
+		&& __copy_from_user(&set.sig[1], &frame->extramask,
+				    sizeof(frame->extramask))))
+		goto badframe;
+
+	sigdelsetmask(&set, ~_BLOCKABLE);
+
+	spin_lock_irq(&current->sighand->siglock);
+	current->blocked = set;
+	recalc_sigpending();
+	spin_unlock_irq(&current->sighand->siglock);
+
+	if (restore_sigcontext(regs, &frame->sc))
+		goto badframe;
+	return regs->areg[2];
+
+badframe:
+	force_sig(SIGSEGV, current);
+	return 0;
+}
+
+asmlinkage int sys_rt_sigreturn(struct pt_regs *regs)
+{
+	struct rt_sigframe *frame = (struct rt_sigframe *)regs->areg[1];
+	sigset_t set;
+	stack_t st;
+	int ret;
+	if (regs->depc > 64)
+	{
+		printk("!!!!!!! DEPC !!!!!!!\n");
+		return 0;
+	}
+
+	if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
+		goto badframe;
+
+	if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
+		goto badframe;
+
+	sigdelsetmask(&set, ~_BLOCKABLE);
+	spin_lock_irq(&current->sighand->siglock);
+	current->blocked = set;
+	recalc_sigpending();
+	spin_unlock_irq(&current->sighand->siglock);
+
+	if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
+		goto badframe;
+	ret = regs->areg[2];
+
+	if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st)))
+		goto badframe;
+	/* It is more difficult to avoid calling this function than to
+	   call it and ignore errors.  */
+	do_sigaltstack(&st, NULL, regs->areg[1]);
+
+	return ret;
+
+badframe:
+	force_sig(SIGSEGV, current);
+	return 0;
+}
+
+/*
+ * Set up a signal frame.
+ */
+
+/*
+ * Determine which stack to use..
+ */
+static inline void *
+get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size)
+{
+	if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && ! on_sig_stack(sp))
+		sp = current->sas_ss_sp + current->sas_ss_size;
+
+	return (void *)((sp - frame_size) & -16ul);
+}
+
+#define USE_SIGRETURN		0
+#define USE_RT_SIGRETURN	1
+
+static int
+gen_return_code(unsigned char *codemem, unsigned int use_rt_sigreturn)
+{
+	unsigned int retcall;
+	int err = 0;
+
+#if 0
+	/* Ignoring SA_RESTORER for now; it's supposed to be obsolete,
+	 * and the xtensa glibc doesn't use it.
+	 */
+	if (ka->sa.sa_flags & SA_RESTORER) {
+		regs->pr = (unsigned long) ka->sa.sa_restorer;
+	} else
+#endif /* 0 */
+	{
+
+#if (__NR_sigreturn > 255) || (__NR_rt_sigreturn > 255)
+
+/* The 12-bit immediate is really split up within the 24-bit MOVI
+ * instruction.  As long as the above system call numbers fit within
+ * 8-bits, the following code works fine. See the Xtensa ISA for
+ * details.
+ */
+
+#error Generating the MOVI instruction below breaks!
+#endif
+
+		retcall = use_rt_sigreturn ? __NR_rt_sigreturn : __NR_sigreturn;
+
+#ifdef __XTENSA_EB__   /* Big Endian version */
+		/* Generate instruction:  MOVI a2, retcall */
+		err |= __put_user(0x22, &codemem[0]);
+		err |= __put_user(0x0a, &codemem[1]);
+		err |= __put_user(retcall, &codemem[2]);
+		/* Generate instruction:  SYSCALL */
+		err |= __put_user(0x00, &codemem[3]);
+		err |= __put_user(0x05, &codemem[4]);
+		err |= __put_user(0x00, &codemem[5]);
+
+#elif defined __XTENSA_EL__   /* Little Endian version */
+		/* Generate instruction:  MOVI a2, retcall */
+		err |= __put_user(0x22, &codemem[0]);
+		err |= __put_user(0xa0, &codemem[1]);
+		err |= __put_user(retcall, &codemem[2]);
+		/* Generate instruction:  SYSCALL */
+		err |= __put_user(0x00, &codemem[3]);
+		err |= __put_user(0x50, &codemem[4]);
+		err |= __put_user(0x00, &codemem[5]);
+#else
+#error Must use compiler for Xtensa processors.
+#endif
+	}
+
+	/* Flush generated code out of the data cache */
+
+	if (err == 0)
+		__flush_invalidate_cache_range((unsigned long)codemem, 6UL);
+
+	return err;
+}
+
+static void
+set_thread_state(struct pt_regs *regs, void *stack, unsigned char *retaddr,
+	void *handler, unsigned long arg1, void *arg2, void *arg3)
+{
+	/* Set up registers for signal handler */
+	start_thread(regs, (unsigned long) handler, (unsigned long) stack);
+
+	/* Set up a stack frame for a call4
+	 * Note: PS.CALLINC is set to one by start_thread
+	 */
+	regs->areg[4] = (((unsigned long) retaddr) & 0x3fffffff) | 0x40000000;
+	regs->areg[6] = arg1;
+	regs->areg[7] = (unsigned long) arg2;
+	regs->areg[8] = (unsigned long) arg3;
+}
+
+static void setup_frame(int sig, struct k_sigaction *ka,
+			sigset_t *set, struct pt_regs *regs)
+{
+	struct sigframe *frame;
+	int err = 0;
+	int signal;
+
+	frame = get_sigframe(ka, regs->areg[1], sizeof(*frame));
+	if (regs->depc > 64)
+	{
+		printk("!!!!!!! DEPC !!!!!!!\n");
+		return;
+	}
+
+
+	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
+		goto give_sigsegv;
+
+	signal = current_thread_info()->exec_domain
+		&& current_thread_info()->exec_domain->signal_invmap
+		&& sig < 32
+		? current_thread_info()->exec_domain->signal_invmap[sig]
+		: sig;
+
+	err |= setup_sigcontext(&frame->sc, &frame->cpstate, regs, set->sig[0]);
+
+	if (_NSIG_WORDS > 1) {
+		err |= __copy_to_user(frame->extramask, &set->sig[1],
+				      sizeof(frame->extramask));
+	}
+
+	/* Create sys_sigreturn syscall in stack frame */
+	err |= gen_return_code(frame->retcode, USE_SIGRETURN);
+
+	if (err)
+		goto give_sigsegv;
+
+	/* Create signal handler execution context.
+	 * Return context not modified until this point.
+	 */
+	set_thread_state(regs, frame, frame->retcode,
+		ka->sa.sa_handler, signal, &frame->sc, NULL);
+
+	/* Set access mode to USER_DS.  Nomenclature is outdated, but
+	 * functionality is used in uaccess.h
+	 */
+	set_fs(USER_DS);
+
+
+#if DEBUG_SIG
+	printk("SIG deliver (%s:%d): signal=%d sp=%p pc=%08x\n",
+		current->comm, current->pid, signal, frame, regs->pc);
+#endif
+
+	return;
+
+give_sigsegv:
+	if (sig == SIGSEGV)
+		ka->sa.sa_handler = SIG_DFL;
+	force_sig(SIGSEGV, current);
+}
+
+static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
+			   sigset_t *set, struct pt_regs *regs)
+{
+	struct rt_sigframe *frame;
+	int err = 0;
+	int signal;
+
+	frame = get_sigframe(ka, regs->areg[1], sizeof(*frame));
+	if (regs->depc > 64)
+		panic ("Double exception sys_sigreturn\n");
+
+	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
+		goto give_sigsegv;
+
+	signal = current_thread_info()->exec_domain
+		&& current_thread_info()->exec_domain->signal_invmap
+		&& sig < 32
+		? current_thread_info()->exec_domain->signal_invmap[sig]
+		: sig;
+
+	err |= copy_siginfo_to_user(&frame->info, info);
+
+	/* Create the ucontext.  */
+	err |= __put_user(0, &frame->uc.uc_flags);
+	err |= __put_user(0, &frame->uc.uc_link);
+	err |= __put_user((void *)current->sas_ss_sp,
+			  &frame->uc.uc_stack.ss_sp);
+	err |= __put_user(sas_ss_flags(regs->areg[1]),
+			  &frame->uc.uc_stack.ss_flags);
+	err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
+	err |= setup_sigcontext(&frame->uc.uc_mcontext, &frame->cpstate,
+			        regs, set->sig[0]);
+	err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
+
+	/* Create sys_rt_sigreturn syscall in stack frame */
+	err |= gen_return_code(frame->retcode, USE_RT_SIGRETURN);
+
+	if (err)
+		goto give_sigsegv;
+
+	/* Create signal handler execution context.
+	 * Return context not modified until this point.
+	 */
+	set_thread_state(regs, frame, frame->retcode,
+		ka->sa.sa_handler, signal, &frame->info, &frame->uc);
+
+	/* Set access mode to USER_DS.  Nomenclature is outdated, but
+	 * functionality is used in uaccess.h
+	 */
+	set_fs(USER_DS);
+
+#if DEBUG_SIG
+	printk("SIG rt deliver (%s:%d): signal=%d sp=%p pc=%08x\n",
+		current->comm, current->pid, signal, frame, regs->pc);
+#endif
+
+	return;
+
+give_sigsegv:
+	if (sig == SIGSEGV)
+		ka->sa.sa_handler = SIG_DFL;
+	force_sig(SIGSEGV, current);
+}
+
+
+
+/*
+ * Note that 'init' is a special process: it doesn't get signals it doesn't
+ * want to handle. Thus you cannot kill init even with a SIGKILL even by
+ * mistake.
+ *
+ * Note that we go through the signals twice: once to check the signals that
+ * the kernel can handle, and then we build all the user-level signal handling
+ * stack-frames in one go after that.
+ */
+int do_signal(struct pt_regs *regs, sigset_t *oldset)
+{
+	siginfo_t info;
+	int signr;
+	struct k_sigaction ka;
+
+	if (!oldset)
+		oldset = &current->blocked;
+
+	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
+
+	/* Are we from a system call? */
+	if (regs->syscall >= 0) {
+		/* If so, check system call restarting.. */
+		switch (regs->areg[2]) {
+			case ERESTARTNOHAND:
+			case ERESTART_RESTARTBLOCK:
+				regs->areg[2] = -EINTR;
+				break;
+
+			case ERESTARTSYS:
+				if (!(ka.sa.sa_flags & SA_RESTART)) {
+					regs->areg[2] = -EINTR;
+					break;
+				}
+			/* fallthrough */
+			case ERESTARTNOINTR:
+				regs->areg[2] = regs->syscall;
+				regs->pc -= 3;
+		}
+	}
+
+	if (signr == 0)
+		return 0;		/* no signals delivered */
+
+	/* Whee!  Actually deliver the signal.  */
+
+	/* Set up the stack frame */
+	if (ka.sa.sa_flags & SA_SIGINFO)
+		setup_rt_frame(signr, &ka, &info, oldset, regs);
+	else
+		setup_frame(signr, &ka, oldset, regs);
+
+	if (ka.sa.sa_flags & SA_ONESHOT)
+		ka.sa.sa_handler = SIG_DFL;
+
+	if (!(ka.sa.sa_flags & SA_NODEFER)) {
+		spin_lock_irq(&current->sighand->siglock);
+		sigorsets(&current->blocked, &current->blocked, &ka.sa.sa_mask);
+		sigaddset(&current->blocked, signr);
+		recalc_sigpending();
+		spin_unlock_irq(&current->sighand->siglock);
+	}
+	return 1;
+}
diff --git a/arch/xtensa/kernel/syscalls.c b/arch/xtensa/kernel/syscalls.c
new file mode 100644
--- /dev/null
+++ b/arch/xtensa/kernel/syscalls.c
@@ -0,0 +1,269 @@
+/*
+ * arch/xtensa/kernel/syscall.c
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ * Copyright (C) 2000 Silicon Graphics, Inc.
+ * Copyright (C) 1995 - 2000 by Ralf Baechle
+ *
+ * Joe Taylor <joe@tensilica.com, joetylr@yahoo.com>
+ * Marc Gauthier <marc@tensilica.com, marc@alumni.uwaterloo.ca>
+ * Chris Zankel <chris@zankel.net>
+ * Kevin Chea
+ *
+ */
+
+#define DEBUG	0
+
+#include <linux/config.h>
+#include <linux/linkage.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/mman.h>
+#include <linux/sched.h>
+#include <linux/file.h>
+#include <linux/slab.h>
+#include <linux/utsname.h>
+#include <linux/unistd.h>
+#include <linux/stringify.h>
+#include <linux/syscalls.h>
+#include <linux/sem.h>
+#include <linux/msg.h>
+#include <linux/shm.h>
+#include <linux/errno.h>
+#include <asm/ptrace.h>
+#include <asm/signal.h>
+#include <asm/uaccess.h>
+#include <asm/hardirq.h>
+#include <asm/mman.h>
+#include <asm/shmparam.h>
+#include <asm/page.h>
+
+extern void do_syscall_trace(void);
+typedef int (*syscall_t)(void *a0,...);
+extern syscall_t sys_call_table[];
+extern unsigned char sys_narg_table[];
+
+/*
+ * sys_pipe() is the normal C calling standard for creating a pipe. It's not
+ * the way unix traditional does this, though.
+ */
+
+int sys_pipe(int __user *userfds)
+{
+	int fd[2];
+	int error;
+
+	error = do_pipe(fd);
+	if (!error) {
+		if (copy_to_user(userfds, fd, 2 * sizeof(int)))
+			error = -EFAULT;
+	}
+	return error;
+}
+
+/*
+ * Common code for old and new mmaps.
+ */
+long sys_mmap(unsigned long addr, unsigned long len, unsigned long prot,
+	      unsigned long flags, unsigned long fd, unsigned long pgoff)
+{
+	int error = -EBADF;
+	struct file * file = NULL;
+
+	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+	if (!(flags & MAP_ANONYMOUS)) {
+		file = fget(fd);
+		if (!file)
+			goto out;
+	}
+
+	down_write(&current->mm->mmap_sem);
+	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
+	up_write(&current->mm->mmap_sem);
+
+	if (file)
+		fput(file);
+out:
+	return error;
+}
+
+int sys_clone(struct pt_regs *regs)
+{
+	unsigned long clone_flags;
+	unsigned long newsp;
+	int __user *parent_tidptr, *child_tidptr;
+	clone_flags = regs->areg[4];
+	newsp = regs->areg[3];
+	parent_tidptr = (int __user *)regs->areg[5];
+	child_tidptr = (int __user *)regs->areg[6];
+	if (!newsp)
+		newsp = regs->areg[1];
+	return do_fork(clone_flags,newsp,regs,0,parent_tidptr,child_tidptr);
+}
+
+/*
+ * sys_execve() executes a new program.
+ */
+
+int sys_execve(struct pt_regs *regs)
+{
+	int error;
+	char * filename;
+
+	filename = getname((char *) (long)regs->areg[5]);
+	error = PTR_ERR(filename);
+	if (IS_ERR(filename))
+		goto out;
+	error = do_execve(filename, (char **) (long)regs->areg[3],
+	                  (char **) (long)regs->areg[4], regs);
+	putname(filename);
+
+out:
+	return error;
+}
+
+int sys_uname(struct old_utsname * name)
+{
+	if (name && !copy_to_user(name, &system_utsname, sizeof (*name)))
+		return 0;
+	return -EFAULT;
+}
+
+/*
+ * Build the string table for the builtin "poor man's strace".
+ */
+
+#if DEBUG
+#define SYSCALL(fun, narg) #fun,
+static char *sfnames[] = {
+#include "syscalls.h"
+};
+#undef SYS
+#endif
+
+void system_call (struct pt_regs *regs)
+{
+	syscall_t syscall;
+	unsigned long parm0, parm1, parm2, parm3, parm4, parm5;
+	int nargs, res;
+	unsigned int syscallnr;
+	int ps;
+
+#if DEBUG
+	int i;
+	unsigned long parms[6];
+	char *sysname;
+#endif
+
+	regs->syscall = regs->areg[2];
+
+	do_syscall_trace();
+
+	/* Have to load after syscall_trace because strace
+	 * sometimes changes regs->syscall.
+	 */
+	syscallnr = regs->syscall;
+
+	parm0 = parm1 = parm2 = parm3 = parm4 = parm5 = 0;
+
+	/* Restore interrupt level to syscall invoker's.
+	 * If this were in assembly, we wouldn't disable
+	 * interrupts in the first place:
+	 */
+	local_save_flags (ps);
+	local_irq_restore((ps & ~XCHAL_PS_INTLEVEL_MASK) |
+			  (regs->ps & XCHAL_PS_INTLEVEL_MASK) );
+
+	if (syscallnr > __NR_Linux_syscalls) {
+		regs->areg[2] = -ENOSYS;
+		return;
+	}
+
+	syscall = sys_call_table[syscallnr];
+	nargs = sys_narg_table[syscallnr];
+
+	if (syscall == NULL) {
+		regs->areg[2] = -ENOSYS;
+		return;
+	}
+
+	/* There shouldn't be more than six arguments in the table! */
+
+	if (nargs > 6)
+		panic("Internal error - too many syscall arguments (%d)!\n",
+		      nargs);
+
+	/* Linux takes system-call arguments in registers.  The ABI
+         * and Xtensa software conventions require the system-call
+         * number in a2.  If an argument exists in a2, we move it to
+         * the next available register.  Note that for improved
+         * efficiency, we do NOT shift all parameters down one
+         * register to maintain the original order.
+	 *
+         * At best case (zero arguments), we just write the syscall
+         * number to a2.  At worst case (1 to 6 arguments), we move
+         * the argument in a2 to the next available register, then
+         * write the syscall number to a2.
+	 *
+         * For clarity, the following truth table enumerates all
+         * possibilities.
+	 *
+         * arguments	syscall number	arg0, arg1, arg2, arg3, arg4, arg5
+         * ---------	--------------	----------------------------------
+	 *	0	      a2
+	 *	1	      a2	a3
+	 *	2	      a2	a4,   a3
+	 *	3	      a2	a5,   a3,   a4
+	 *	4	      a2	a6,   a3,   a4,   a5
+	 *	5	      a2	a7,   a3,   a4,   a5,   a6
+	 *	6	      a2	a8,   a3,   a4,   a5,   a6,   a7
+	 */
+	if (nargs) {
+		parm0 = regs->areg[nargs+2];
+		parm1 = regs->areg[3];
+		parm2 = regs->areg[4];
+		parm3 = regs->areg[5];
+		parm4 = regs->areg[6];
+		parm5 = regs->areg[7];
+	} else /* nargs == 0 */
+		parm0 = (unsigned long) regs;
+
+#if DEBUG
+	parms[0] = parm0;
+	parms[1] = parm1;
+	parms[2] = parm2;
+	parms[3] = parm3;
+	parms[4] = parm4;
+	parms[5] = parm5;
+
+	sysname = sfnames[syscallnr];
+	if (strncmp(sysname, "sys_", 4) == 0)
+		sysname = sysname + 4;
+
+	printk("\017SYSCALL:I:%x:%d:%s  %s(", regs->pc, current->pid,
+	       current->comm, sysname);
+	for (i = 0; i < nargs; i++)
+		printk((i>0) ? ", %#lx" : "%#lx", parms[i]);
+	printk(")\n");
+#endif
+
+	res = syscall((void *)parm0, parm1, parm2, parm3, parm4, parm5);
+
+#if DEBUG
+	printk("\017SYSCALL:O:%d:%s  %s(",current->pid, current->comm, sysname);
+	for (i = 0; i < nargs; i++)
+		printk((i>0) ? ", %#lx" : "%#lx", parms[i]);
+	if (res < 4096)
+		printk(") = %d\n", res);
+	else
+		printk(") = %#x\n", res);
+#endif /* DEBUG */
+
+	regs->areg[2] = res;
+	do_syscall_trace();
+}
diff --git a/arch/xtensa/kernel/syscalls.h b/arch/xtensa/kernel/syscalls.h
new file mode 100644
--- /dev/null
+++ b/arch/xtensa/kernel/syscalls.h
@@ -0,0 +1,247 @@
+/*
+ * arch/xtensa/kernel/syscalls.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995, 1996, 1997, 1998 by Ralf Baechle
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ *
+ * Changes by Joe Taylor <joe@tensilica.com>
+ */
+
+/*
+ * This file is being included twice - once to build a list of all
+ * syscalls and once to build a table of how many arguments each syscall
+ * accepts.  Syscalls that receive a pointer to the saved registers are
+ * marked as having zero arguments.
+ *
+ * The binary compatibility calls are in a separate list.
+ *
+ * Entry '0' used to be system_call.  It's removed to disable indirect
+ * system calls for now so user tasks can't recurse.  See mips'
+ * sys_syscall for a comparable example.
+ */
+
+SYSCALL(0, 0)		                /* 00 */
+SYSCALL(sys_exit, 1)
+SYSCALL(sys_ni_syscall, 0)
+SYSCALL(sys_read, 3)
+SYSCALL(sys_write, 3)
+SYSCALL(sys_open, 3)			/* 05 */
+SYSCALL(sys_close, 1)
+SYSCALL(sys_ni_syscall, 3)
+SYSCALL(sys_creat, 2)
+SYSCALL(sys_link, 2)
+SYSCALL(sys_unlink, 1)			/* 10 */
+SYSCALL(sys_execve, 0)
+SYSCALL(sys_chdir, 1)
+SYSCALL(sys_ni_syscall, 1)
+SYSCALL(sys_mknod, 3)
+SYSCALL(sys_chmod, 2)			/* 15 */
+SYSCALL(sys_lchown, 3)
+SYSCALL(sys_ni_syscall, 0)
+SYSCALL(sys_newstat, 2)
+SYSCALL(sys_lseek, 3)
+SYSCALL(sys_getpid, 0)			/* 20 */
+SYSCALL(sys_mount, 5)
+SYSCALL(sys_ni_syscall, 1)
+SYSCALL(sys_setuid, 1)
+SYSCALL(sys_getuid, 0)
+SYSCALL(sys_ni_syscall, 1)		/* 25 */
+SYSCALL(sys_ptrace, 4)
+SYSCALL(sys_ni_syscall, 1)
+SYSCALL(sys_newfstat, 2)
+SYSCALL(sys_ni_syscall, 0)
+SYSCALL(sys_utime, 2)			/* 30 */
+SYSCALL(sys_ni_syscall, 0)
+SYSCALL(sys_ni_syscall, 0)
+SYSCALL(sys_access, 2)
+SYSCALL(sys_ni_syscall, 1)
+SYSCALL(sys_ni_syscall, 0)		/* 35 */
+SYSCALL(sys_sync, 0)
+SYSCALL(sys_kill, 2)
+SYSCALL(sys_rename, 2)
+SYSCALL(sys_mkdir, 2)
+SYSCALL(sys_rmdir, 1)			/* 40 */
+SYSCALL(sys_dup, 1)
+SYSCALL(sys_pipe, 1)
+SYSCALL(sys_times, 1)
+SYSCALL(sys_ni_syscall, 0)
+SYSCALL(sys_brk, 1)			/* 45 */
+SYSCALL(sys_setgid, 1)
+SYSCALL(sys_getgid, 0)
+SYSCALL(sys_ni_syscall, 0)
+SYSCALL(sys_geteuid, 0)
+SYSCALL(sys_getegid, 0)			/* 50 */
+SYSCALL(sys_acct, 1)
+SYSCALL(sys_umount, 2)
+SYSCALL(sys_ni_syscall, 0)
+SYSCALL(sys_ioctl, 3)
+SYSCALL(sys_fcntl, 3)			/* 55 */
+SYSCALL(sys_ni_syscall, 2)
+SYSCALL(sys_setpgid, 2)
+SYSCALL(sys_ni_syscall, 0)
+SYSCALL(sys_ni_syscall, 0)
+SYSCALL(sys_umask, 1)			/* 60 */
+SYSCALL(sys_chroot, 1)
+SYSCALL(sys_ustat, 2)
+SYSCALL(sys_dup2, 2)
+SYSCALL(sys_getppid, 0)
+SYSCALL(sys_ni_syscall, 0)		/* 65 */
+SYSCALL(sys_setsid, 0)
+SYSCALL(sys_sigaction, 3)
+SYSCALL(sys_ni_syscall, 0)
+SYSCALL(sys_ni_syscall, 1)
+SYSCALL(sys_setreuid, 2)		/* 70 */
+SYSCALL(sys_setregid, 2)
+SYSCALL(sys_sigsuspend, 0)
+SYSCALL(sys_ni_syscall, 1)
+SYSCALL(sys_sethostname, 2)
+SYSCALL(sys_setrlimit, 2)		/* 75 */
+SYSCALL(sys_getrlimit, 2)
+SYSCALL(sys_getrusage, 2)
+SYSCALL(sys_gettimeofday, 2)
+SYSCALL(sys_settimeofday, 2)
+SYSCALL(sys_getgroups, 2)		/* 80 */
+SYSCALL(sys_setgroups, 2)
+SYSCALL(sys_ni_syscall, 0)
+SYSCALL(sys_symlink, 2)
+SYSCALL(sys_newlstat, 2)
+SYSCALL(sys_readlink, 3)		/* 85 */
+SYSCALL(sys_uselib, 1)
+SYSCALL(sys_swapon, 2)
+SYSCALL(sys_reboot, 3)
+SYSCALL(sys_ni_syscall, 3)
+SYSCALL(sys_ni_syscall, 6)		/* 90 */
+SYSCALL(sys_munmap, 2)
+SYSCALL(sys_truncate, 2)
+SYSCALL(sys_ftruncate, 2)
+SYSCALL(sys_fchmod, 2)
+SYSCALL(sys_fchown, 3)			/* 95 */
+SYSCALL(sys_getpriority, 2)
+SYSCALL(sys_setpriority, 3)
+SYSCALL(sys_ni_syscall, 0)
+SYSCALL(sys_statfs, 2)
+SYSCALL(sys_fstatfs, 2)			/* 100 */
+SYSCALL(sys_ni_syscall, 3)
+SYSCALL(sys_ni_syscall, 2)
+SYSCALL(sys_syslog, 3)
+SYSCALL(sys_setitimer, 3)
+SYSCALL(sys_getitimer, 2)		/* 105 */
+SYSCALL(sys_newstat, 2)
+SYSCALL(sys_newlstat, 2)
+SYSCALL(sys_newfstat, 2)
+SYSCALL(sys_uname, 1)
+SYSCALL(sys_ni_syscall, 0)		/* 110 */
+SYSCALL(sys_vhangup, 0)
+SYSCALL(sys_ni_syscall, 0)
+SYSCALL(sys_ni_syscall, 0)
+SYSCALL(sys_wait4, 4)
+SYSCALL(sys_swapoff, 1)			/* 115 */
+SYSCALL(sys_sysinfo, 1)
+SYSCALL(sys_ni_syscall, 0)
+SYSCALL(sys_fsync, 1)
+SYSCALL(sys_sigreturn, 0)
+SYSCALL(sys_clone, 0)			/* 120 */
+SYSCALL(sys_setdomainname, 2)
+SYSCALL(sys_newuname, 1)
+SYSCALL(sys_ni_syscall, 0)
+SYSCALL(sys_adjtimex, 1)
+SYSCALL(sys_mprotect, 3)		/* 125 */
+SYSCALL(sys_ni_syscall, 3)
+SYSCALL(sys_ni_syscall, 2)
+SYSCALL(sys_init_module, 2)
+SYSCALL(sys_delete_module, 1)
+SYSCALL(sys_ni_syscall, 1)		/* 130 */
+SYSCALL(sys_quotactl, 0)
+SYSCALL(sys_getpgid, 1)
+SYSCALL(sys_fchdir, 1)
+SYSCALL(sys_bdflush, 2)
+SYSCALL(sys_sysfs, 3)			/* 135 */
+SYSCALL(sys_personality, 1)
+SYSCALL(sys_ni_syscall, 0)
+SYSCALL(sys_setfsuid, 1)
+SYSCALL(sys_setfsgid, 1)
+SYSCALL(sys_llseek, 5)			/* 140 */
+SYSCALL(sys_getdents, 3)
+SYSCALL(sys_select, 5)
+SYSCALL(sys_flock, 2)
+SYSCALL(sys_msync, 3)
+SYSCALL(sys_readv, 3)			/* 145 */
+SYSCALL(sys_writev, 3)
+SYSCALL(sys_ni_syscall, 3)
+SYSCALL(sys_ni_syscall, 3)
+SYSCALL(sys_ni_syscall, 4)		/* handled in fast syscall handler. */
+SYSCALL(sys_ni_syscall, 0)		/* 150 */
+SYSCALL(sys_getsid, 1)
+SYSCALL(sys_fdatasync, 1)
+SYSCALL(sys_sysctl, 1)
+SYSCALL(sys_mlock, 2)
+SYSCALL(sys_munlock, 2)			/* 155 */
+SYSCALL(sys_mlockall, 1)
+SYSCALL(sys_munlockall, 0)
+SYSCALL(sys_sched_setparam,2)
+SYSCALL(sys_sched_getparam,2)
+SYSCALL(sys_sched_setscheduler,3)	/* 160 */
+SYSCALL(sys_sched_getscheduler,1)
+SYSCALL(sys_sched_yield,0)
+SYSCALL(sys_sched_get_priority_max,1)
+SYSCALL(sys_sched_get_priority_min,1)
+SYSCALL(sys_sched_rr_get_interval,2)	/* 165 */
+SYSCALL(sys_nanosleep,2)
+SYSCALL(sys_mremap,4)
+SYSCALL(sys_accept, 3)
+SYSCALL(sys_bind, 3)
+SYSCALL(sys_connect, 3)			/* 170 */
+SYSCALL(sys_getpeername, 3)
+SYSCALL(sys_getsockname, 3)
+SYSCALL(sys_getsockopt, 5)
+SYSCALL(sys_listen, 2)
+SYSCALL(sys_recv, 4)			/* 175 */
+SYSCALL(sys_recvfrom, 6)
+SYSCALL(sys_recvmsg, 3)
+SYSCALL(sys_send, 4)
+SYSCALL(sys_sendmsg, 3)
+SYSCALL(sys_sendto, 6)			/* 180 */
+SYSCALL(sys_setsockopt, 5)
+SYSCALL(sys_shutdown, 2)
+SYSCALL(sys_socket, 3)
+SYSCALL(sys_socketpair, 4)
+SYSCALL(sys_setresuid, 3)		/* 185 */
+SYSCALL(sys_getresuid, 3)
+SYSCALL(sys_ni_syscall, 5)
+SYSCALL(sys_poll, 3)
+SYSCALL(sys_nfsservctl, 3)
+SYSCALL(sys_setresgid, 3)		/* 190 */
+SYSCALL(sys_getresgid, 3)
+SYSCALL(sys_prctl, 5)
+SYSCALL(sys_rt_sigreturn, 0)
+SYSCALL(sys_rt_sigaction, 4)
+SYSCALL(sys_rt_sigprocmask, 4)		/* 195 */
+SYSCALL(sys_rt_sigpending, 2)
+SYSCALL(sys_rt_sigtimedwait, 4)
+SYSCALL(sys_rt_sigqueueinfo, 3)
+SYSCALL(sys_rt_sigsuspend, 0)
+SYSCALL(sys_pread64, 5)			/* 200 */
+SYSCALL(sys_pwrite64, 5)
+SYSCALL(sys_chown, 3)
+SYSCALL(sys_getcwd, 2)
+SYSCALL(sys_capget, 2)
+SYSCALL(sys_capset, 2)			/* 205 */
+SYSCALL(sys_sigaltstack, 0)
+SYSCALL(sys_sendfile, 4)
+SYSCALL(sys_ni_syscall, 0)
+SYSCALL(sys_ni_syscall, 0)
+SYSCALL(sys_mmap, 6)			/* 210 */
+SYSCALL(sys_truncate64, 2)
+SYSCALL(sys_ftruncate64, 2)
+SYSCALL(sys_stat64, 2)
+SYSCALL(sys_lstat64, 2)
+SYSCALL(sys_fstat64, 2)			/* 215 */
+SYSCALL(sys_pivot_root, 2)
+SYSCALL(sys_mincore, 3)
+SYSCALL(sys_madvise, 3)
+SYSCALL(sys_getdents64, 3)
+SYSCALL(sys_ni_syscall, 0)		/* 220 */
diff --git a/arch/xtensa/kernel/time.c b/arch/xtensa/kernel/time.c
new file mode 100644
--- /dev/null
+++ b/arch/xtensa/kernel/time.c
@@ -0,0 +1,227 @@
+/*
+ * arch/xtensa/kernel/time.c
+ *
+ * Timer and clock support.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2005 Tensilica Inc.
+ *
+ * Chris Zankel <chris@zankel.net>
+ */
+
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/time.h>
+#include <linux/timex.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/profile.h>
+#include <linux/delay.h>
+
+#include <asm/timex.h>
+#include <asm/platform.h>
+
+
+extern volatile unsigned long wall_jiffies;
+
+u64 jiffies_64 = INITIAL_JIFFIES;
+EXPORT_SYMBOL(jiffies_64);
+
+spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED;
+EXPORT_SYMBOL(rtc_lock);
+
+
+#ifdef CONFIG_XTENSA_CALIBRATE_CCOUNT
+unsigned long ccount_per_jiffy;		/* per 1/HZ */
+unsigned long ccount_nsec;		/* nsec per ccount increment */
+#endif
+
+unsigned int last_ccount_stamp;
+static long last_rtc_update = 0;
+
+/*
+ * Scheduler clock - returns current tim in nanosec units.
+ */
+
+unsigned long long sched_clock(void)
+{
+	return (unsigned long long)jiffies * (1000000000 / HZ);
+}
+
+static irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static struct irqaction timer_irqaction = {
+	.handler =	timer_interrupt,
+	.flags =	SA_INTERRUPT,
+	.name =		"timer",
+};
+
+void __init time_init(void)
+{
+	time_t sec_o, sec_n = 0;
+
+	/* The platform must provide a function to calibrate the processor
+	 * speed for the CALIBRATE.
+	 */
+
+#if CONFIG_XTENSA_CALIBRATE_CCOUNT
+	printk("Calibrating CPU frequency ");
+	platform_calibrate_ccount();
+	printk("%d.%02d MHz\n", (int)ccount_per_jiffy/(1000000/HZ),
+			(int)(ccount_per_jiffy/(10000/HZ))%100);
+#endif
+
+	/* Set time from RTC (if provided) */
+
+	if (platform_get_rtc_time(&sec_o) == 0)
+		while (platform_get_rtc_time(&sec_n))
+			if (sec_o != sec_n)
+				break;
+
+	xtime.tv_nsec = 0;
+	last_rtc_update = xtime.tv_sec = sec_n;
+	last_ccount_stamp = get_ccount();
+
+	set_normalized_timespec(&wall_to_monotonic,
+		-xtime.tv_sec, -xtime.tv_nsec);
+
+	/* Initialize the linux timer interrupt. */
+
+	setup_irq(LINUX_TIMER_INT, &timer_irqaction);
+	set_linux_timer(get_ccount() + CCOUNT_PER_JIFFY);
+}
+
+
+int do_settimeofday(struct timespec *tv)
+{
+	time_t wtm_sec, sec = tv->tv_sec;
+	long wtm_nsec, nsec = tv->tv_nsec;
+	unsigned long ccount;
+
+	if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
+		return -EINVAL;
+
+	write_seqlock_irq(&xtime_lock);
+
+	/* This is revolting. We need to set "xtime" correctly. However, the
+	 * value in this location is the value at the most recent update of
+	 * wall time.  Discover what correction gettimeofday() would have
+	 * made, and then undo it!
+	 */
+	ccount = get_ccount();
+	nsec -= (ccount - last_ccount_stamp) * CCOUNT_NSEC;
+	nsec -= (jiffies - wall_jiffies) * CCOUNT_PER_JIFFY * CCOUNT_NSEC;
+
+	wtm_sec  = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
+	wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
+
+	set_normalized_timespec(&xtime, sec, nsec);
+	set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
+
+	time_adjust = 0;                /* stop active adjtime() */
+	time_status |= STA_UNSYNC;
+	time_maxerror = NTP_PHASE_LIMIT;
+	time_esterror = NTP_PHASE_LIMIT;
+	write_sequnlock_irq(&xtime_lock);
+	return 0;
+}
+
+EXPORT_SYMBOL(do_settimeofday);
+
+
+void do_gettimeofday(struct timeval *tv)
+{
+	unsigned long flags;
+	unsigned long sec, usec, delta, lost, seq;
+
+	do {
+		seq = read_seqbegin_irqsave(&xtime_lock, flags);
+
+		delta = get_ccount() - last_ccount_stamp;
+		sec = xtime.tv_sec;
+		usec = (xtime.tv_nsec / NSEC_PER_USEC);
+
+		lost = jiffies - wall_jiffies;
+
+	} while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
+
+	usec += lost * (1000000UL/HZ) + (delta * CCOUNT_NSEC) / NSEC_PER_USEC;
+	for (; usec >= 1000000; sec++, usec -= 1000000)
+		;
+
+	tv->tv_sec = sec;
+	tv->tv_usec = usec;
+}
+
+EXPORT_SYMBOL(do_gettimeofday);
+
+/*
+ * The timer interrupt is called HZ times per second.
+ */
+
+irqreturn_t timer_interrupt (int irq, void *dev_id, struct pt_regs *regs)
+{
+
+	unsigned long next;
+
+	next = get_linux_timer();
+
+again:
+	while ((signed long)(get_ccount() - next) > 0) {
+
+		profile_tick(CPU_PROFILING, regs);
+#ifndef CONFIG_SMP
+		update_process_times(user_mode(regs));
+#endif
+
+		write_seqlock(&xtime_lock);
+
+		last_ccount_stamp = next;
+		next += CCOUNT_PER_JIFFY;
+		do_timer (regs); /* Linux handler in kernel/timer.c */
+
+		if ((time_status & STA_UNSYNC) == 0 &&
+		    xtime.tv_sec - last_rtc_update >= 659 &&
+		    abs((xtime.tv_nsec/1000)-(1000000-1000000/HZ))<5000000/HZ &&
+		    jiffies - wall_jiffies == 1) {
+
+			if (platform_set_rtc_time(xtime.tv_sec+1) == 0)
+				last_rtc_update = xtime.tv_sec+1;
+			else
+				/* Do it again in 60 s */
+				last_rtc_update += 60;
+		}
+		write_sequnlock(&xtime_lock);
+	}
+
+	/* NOTE: writing CCOMPAREn clears the interrupt.  */
+
+	set_linux_timer (next);
+
+	/* Make sure we didn't miss any tick... */
+
+	if ((signed long)(get_ccount() - next) > 0)
+		goto again;
+
+	/* Allow platform to do something usefull (Wdog). */
+
+	platform_heartbeat();
+
+	return IRQ_HANDLED;
+}
+
+#ifndef CONFIG_GENERIC_CALIBRATE_DELAY
+void __devinit calibrate_delay(void)
+{
+	loops_per_jiffy = CCOUNT_PER_JIFFY;
+	printk("Calibrating delay loop (skipped)... "
+	       "%lu.%02lu BogoMIPS preset\n",
+	       loops_per_jiffy/(1000000/HZ),
+	       (loops_per_jiffy/(10000/HZ)) % 100);
+}
+#endif
+
diff --git a/arch/xtensa/kernel/traps.c b/arch/xtensa/kernel/traps.c
new file mode 100644
--- /dev/null
+++ b/arch/xtensa/kernel/traps.c
@@ -0,0 +1,498 @@
+/*
+ * arch/xtensa/kernel/traps.c
+ *
+ * Exception handling.
+ *
+ * Derived from code with the following copyrights:
+ * Copyright (C) 1994 - 1999 by Ralf Baechle
+ * Modified for R3000 by Paul M. Antoine, 1995, 1996
+ * Complete output from die() by Ulf Carlsson, 1998
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ *
+ * Essentially rewritten for the Xtensa architecture port.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ *
+ * Joe Taylor	<joe@tensilica.com, joetylr@yahoo.com>
+ * Chris Zankel	<chris@zankel.net>
+ * Marc Gauthier<marc@tensilica.com, marc@alumni.uwaterloo.ca>
+ * Kevin Chea
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/stringify.h>
+#include <linux/kallsyms.h>
+#include <linux/delay.h>
+
+#include <asm/ptrace.h>
+#include <asm/timex.h>
+#include <asm/uaccess.h>
+#include <asm/pgtable.h>
+#include <asm/processor.h>
+
+#ifdef CONFIG_KGDB
+extern int gdb_enter;
+extern int return_from_debug_flag;
+#endif
+
+/*
+ * Machine specific interrupt handlers
+ */
+
+extern void kernel_exception(void);
+extern void user_exception(void);
+
+extern void fast_syscall_kernel(void);
+extern void fast_syscall_user(void);
+extern void fast_alloca(void);
+extern void fast_unaligned(void);
+extern void fast_second_level_miss(void);
+extern void fast_store_prohibited(void);
+extern void fast_coprocessor(void);
+
+extern void do_illegal_instruction (struct pt_regs*);
+extern void do_interrupt (struct pt_regs*);
+extern void do_unaligned_user (struct pt_regs*);
+extern void do_multihit (struct pt_regs*, unsigned long);
+extern void do_page_fault (struct pt_regs*, unsigned long);
+extern void do_debug (struct pt_regs*);
+extern void system_call (struct pt_regs*);
+
+/*
+ * The vector table must be preceded by a save area (which
+ * implies it must be in RAM, unless one places RAM immediately
+ * before a ROM and puts the vector at the start of the ROM (!))
+ */
+
+#define KRNL		0x01
+#define USER		0x02
+
+#define COPROCESSOR(x)							\
+{ XCHAL_EXCCAUSE_COPROCESSOR ## x ## _DISABLED, USER, fast_coprocessor }
+
+typedef struct {
+	int cause;
+	int fast;
+	void* handler;
+} dispatch_init_table_t;
+
+dispatch_init_table_t __init dispatch_init_table[] = {
+
+{ XCHAL_EXCCAUSE_ILLEGAL_INSTRUCTION,	0,	   do_illegal_instruction},
+{ XCHAL_EXCCAUSE_SYSTEM_CALL,		KRNL,	   fast_syscall_kernel },
+{ XCHAL_EXCCAUSE_SYSTEM_CALL,		USER,	   fast_syscall_user },
+{ XCHAL_EXCCAUSE_SYSTEM_CALL,		0,	   system_call },
+/* XCHAL_EXCCAUSE_INSTRUCTION_FETCH unhandled */
+/* XCHAL_EXCCAUSE_LOAD_STORE_ERROR unhandled*/
+{ XCHAL_EXCCAUSE_LEVEL1_INTERRUPT,	0,	   do_interrupt },
+{ XCHAL_EXCCAUSE_ALLOCA,		USER|KRNL, fast_alloca },
+/* XCHAL_EXCCAUSE_INTEGER_DIVIDE_BY_ZERO unhandled */
+/* XCHAL_EXCCAUSE_PRIVILEGED unhandled */
+#if XCHAL_UNALIGNED_LOAD_EXCEPTION || XCHAL_UNALIGNED_STORE_EXCEPTION
+#ifdef CONFIG_UNALIGNED_USER
+{ XCHAL_EXCCAUSE_UNALIGNED,		USER,	   fast_unaligned },
+#else
+{ XCHAL_EXCCAUSE_UNALIGNED,		0,	   do_unaligned_user },
+#endif
+{ XCHAL_EXCCAUSE_UNALIGNED,		KRNL,	   fast_unaligned },
+#endif
+{ XCHAL_EXCCAUSE_ITLB_MISS,		0,	   do_page_fault },
+{ XCHAL_EXCCAUSE_ITLB_MISS,		USER|KRNL, fast_second_level_miss},
+{ XCHAL_EXCCAUSE_ITLB_MULTIHIT,		0,	   do_multihit },
+{ XCHAL_EXCCAUSE_ITLB_PRIVILEGE,	0,	   do_page_fault },
+/* XCHAL_EXCCAUSE_SIZE_RESTRICTION unhandled */
+{ XCHAL_EXCCAUSE_FETCH_CACHE_ATTRIBUTE,	0,	   do_page_fault },
+{ XCHAL_EXCCAUSE_DTLB_MISS,		USER|KRNL, fast_second_level_miss},
+{ XCHAL_EXCCAUSE_DTLB_MISS,		0,	   do_page_fault },
+{ XCHAL_EXCCAUSE_DTLB_MULTIHIT,		0,	   do_multihit },
+{ XCHAL_EXCCAUSE_DTLB_PRIVILEGE,	0,	   do_page_fault },
+/* XCHAL_EXCCAUSE_DTLB_SIZE_RESTRICTION unhandled */
+{ XCHAL_EXCCAUSE_STORE_CACHE_ATTRIBUTE,	USER|KRNL, fast_store_prohibited },
+{ XCHAL_EXCCAUSE_STORE_CACHE_ATTRIBUTE,	0,	   do_page_fault },
+{ XCHAL_EXCCAUSE_LOAD_CACHE_ATTRIBUTE,	0,	   do_page_fault },
+/* XCCHAL_EXCCAUSE_FLOATING_POINT unhandled */
+#if (XCHAL_CP_MASK & 1)
+COPROCESSOR(0),
+#endif
+#if (XCHAL_CP_MASK & 2)
+COPROCESSOR(1),
+#endif
+#if (XCHAL_CP_MASK & 4)
+COPROCESSOR(2),
+#endif
+#if (XCHAL_CP_MASK & 8)
+COPROCESSOR(3),
+#endif
+#if (XCHAL_CP_MASK & 16)
+COPROCESSOR(4),
+#endif
+#if (XCHAL_CP_MASK & 32)
+COPROCESSOR(5),
+#endif
+#if (XCHAL_CP_MASK & 64)
+COPROCESSOR(6),
+#endif
+#if (XCHAL_CP_MASK & 128)
+COPROCESSOR(7),
+#endif
+{ EXCCAUSE_MAPPED_DEBUG,		0,		do_debug },
+{ -1, -1, 0 }
+
+};
+
+/* The exception table <exc_table> serves two functions:
+ * 1. it contains three dispatch tables (fast_user, fast_kernel, default-c)
+ * 2. it is a temporary memory buffer for the exception handlers.
+ */
+
+unsigned long exc_table[EXC_TABLE_SIZE/4];
+
+void die(const char*, struct pt_regs*, long);
+
+static inline void
+__die_if_kernel(const char *str, struct pt_regs *regs, long err)
+{
+	if (!user_mode(regs))
+		die(str, regs, err);
+}
+
+/*
+ * Unhandled Exceptions. Kill user task or panic if in kernel space.
+ */
+
+void do_unhandled(struct pt_regs *regs, unsigned long exccause)
+{
+	__die_if_kernel("Caught unhandled exception - should not happen",
+	    		regs, SIGKILL);
+
+	/* If in user mode, send SIGILL signal to current process */
+	printk("Caught unhandled exception in '%s' "
+	       "(pid = %d, pc = %#010lx) - should not happen\n"
+	       "\tEXCCAUSE is %ld\n",
+	       current->comm, current->pid, regs->pc, exccause);
+	force_sig(SIGILL, current);
+}
+
+/*
+ * Multi-hit exception. This if fatal!
+ */
+
+void do_multihit(struct pt_regs *regs, unsigned long exccause)
+{
+	die("Caught multihit exception", regs, SIGKILL);
+}
+
+/*
+ * Level-1 interrupt.
+ * We currently have no priority encoding.
+ */
+
+unsigned long ignored_level1_interrupts;
+extern void do_IRQ(int, struct pt_regs *);
+
+void do_interrupt (struct pt_regs *regs)
+{
+	unsigned long intread = get_sr (INTREAD);
+	unsigned long intenable = get_sr (INTENABLE);
+	int i, mask;
+
+	/* Handle all interrupts (no priorities).
+	 * (Clear the interrupt before processing, in case it's
+	 *  edge-triggered or software-generated)
+	 */
+
+	for (i=0, mask = 1; i < XCHAL_NUM_INTERRUPTS; i++, mask <<= 1) {
+		if (mask & (intread & intenable)) {
+			set_sr (mask, INTCLEAR);
+			do_IRQ (i,regs);
+		}
+	}
+}
+
+/*
+ * Illegal instruction. Fatal if in kernel space.
+ */
+
+void
+do_illegal_instruction(struct pt_regs *regs)
+{
+	__die_if_kernel("Illegal instruction in kernel", regs, SIGKILL);
+
+	/* If in user mode, send SIGILL signal to current process. */
+
+	printk("Illegal Instruction in '%s' (pid = %d, pc = %#010lx)\n",
+	    current->comm, current->pid, regs->pc);
+	force_sig(SIGILL, current);
+}
+
+
+/*
+ * Handle unaligned memory accesses from user space. Kill task.
+ *
+ * If CONFIG_UNALIGNED_USER is not set, we don't allow unaligned memory
+ * accesses causes from user space.
+ */
+
+#if XCHAL_UNALIGNED_LOAD_EXCEPTION || XCHAL_UNALIGNED_STORE_EXCEPTION
+#ifndef CONFIG_UNALIGNED_USER
+void
+do_unaligned_user (struct pt_regs *regs)
+{
+	siginfo_t info;
+
+	__die_if_kernel("Unhandled unaligned exception in kernel",
+	    		regs, SIGKILL);
+
+	current->thread.bad_vaddr = regs->excvaddr;
+	current->thread.error_code = -3;
+	printk("Unaligned memory access to %08lx in '%s' "
+	       "(pid = %d, pc = %#010lx)\n",
+	       regs->excvaddr, current->comm, current->pid, regs->pc);
+	info.si_signo = SIGBUS;
+	info.si_errno = 0;
+	info.si_code = BUS_ADRALN;
+	info.si_addr = (void *) regs->excvaddr;
+	force_sig_info(SIGSEGV, &info, current);
+
+}
+#endif
+#endif
+
+void
+do_debug(struct pt_regs *regs)
+{
+#ifdef CONFIG_KGDB
+	/* If remote debugging is configured AND enabled, we give control to
+	 * kgdb.  Otherwise, we fall through, perhaps giving control to the
+	 * native debugger.
+	 */
+
+	if (gdb_enter) {
+		extern void gdb_handle_exception(struct pt_regs *);
+		gdb_handle_exception(regs);
+		return_from_debug_flag = 1;
+		return;
+	}
+#endif
+
+	__die_if_kernel("Breakpoint in kernel", regs, SIGKILL);
+
+	/* If in user mode, send SIGTRAP signal to current process */
+
+	force_sig(SIGTRAP, current);
+}
+
+
+/*
+ * Initialize dispatch tables.
+ *
+ * The exception vectors are stored compressed the __init section in the
+ * dispatch_init_table. This function initializes the following three tables
+ * from that compressed table:
+ * - fast user		first dispatch table for user exceptions
+ * - fast kernel	first dispatch table for kernel exceptions
+ * - default C-handler	C-handler called by the default fast handler.
+ *
+ * See vectors.S for more details.
+ */
+
+#define set_handler(idx,handler) (exc_table[idx] = (unsigned long) (handler))
+
+void trap_init(void)
+{
+	int i;
+
+	/* Setup default vectors. */
+
+	for(i = 0; i < 64; i++) {
+		set_handler(EXC_TABLE_FAST_USER/4   + i, user_exception);
+		set_handler(EXC_TABLE_FAST_KERNEL/4 + i, kernel_exception);
+		set_handler(EXC_TABLE_DEFAULT/4 + i, do_unhandled);
+	}
+
+	/* Setup specific handlers. */
+
+	for(i = 0; dispatch_init_table[i].cause >= 0; i++) {
+
+		int fast = dispatch_init_table[i].fast;
+		int cause = dispatch_init_table[i].cause;
+		void *handler = dispatch_init_table[i].handler;
+
+		if (fast == 0)
+			set_handler (EXC_TABLE_DEFAULT/4 + cause, handler);
+		if (fast && fast & USER)
+			set_handler (EXC_TABLE_FAST_USER/4 + cause, handler);
+		if (fast && fast & KRNL)
+			set_handler (EXC_TABLE_FAST_KERNEL/4 + cause, handler);
+	}
+
+	/* Initialize EXCSAVE_1 to hold the address of the exception table. */
+
+	i = (unsigned long)exc_table;
+	__asm__ __volatile__("wsr  %0, "__stringify(EXCSAVE_1)"\n" : : "a" (i));
+}
+
+/*
+ * This function dumps the current valid window frame and other base registers.
+ */
+
+void show_regs(struct pt_regs * regs)
+{
+	int i, wmask;
+
+	wmask = regs->wmask & ~1;
+
+	for (i = 0; i < 32; i++) {
+		if (wmask & (1 << (i / 4)))
+			break;
+		if ((i % 8) == 0)
+			printk ("\n" KERN_INFO "a%02d: ", i);
+		printk("%08lx ", regs->areg[i]);
+	}
+	printk("\n");
+
+	printk("pc: %08lx, ps: %08lx, depc: %08lx, excvaddr: %08lx\n",
+	       regs->pc, regs->ps, regs->depc, regs->excvaddr);
+	printk("lbeg: %08lx, lend: %08lx lcount: %08lx, sar: %08lx\n",
+	       regs->lbeg, regs->lend, regs->lcount, regs->sar);
+	if (user_mode(regs))
+		printk("wb: %08lx, ws: %08lx, wmask: %08lx, syscall: %ld\n",
+		       regs->windowbase, regs->windowstart, regs->wmask,
+		       regs->syscall);
+}
+
+void show_trace(struct task_struct *task, unsigned long *sp)
+{
+	unsigned long a0, a1, pc;
+	unsigned long sp_start, sp_end;
+
+	a1 = (unsigned long)sp;
+
+	if (a1 == 0)
+		__asm__ __volatile__ ("mov %0, a1\n" : "=a"(a1));
+
+
+	sp_start = a1 & ~(THREAD_SIZE-1);
+	sp_end = sp_start + THREAD_SIZE;
+
+	printk("Call Trace:");
+#ifdef CONFIG_KALLSYMS
+	printk("\n");
+#endif
+	spill_registers();
+
+	while (a1 > sp_start && a1 < sp_end) {
+		sp = (unsigned long*)a1;
+
+		a0 = *(sp - 4);
+		a1 = *(sp - 3);
+
+		if (a1 <= (unsigned long) sp)
+			break;
+
+		pc = MAKE_PC_FROM_RA(a0, a1);
+
+		if (kernel_text_address(pc)) {
+			printk(" [<%08lx>] ", pc);
+			print_symbol("%s\n", pc);
+		}
+	}
+	printk("\n");
+}
+
+/*
+ * This routine abuses get_user()/put_user() to reference pointers
+ * with at least a bit of error checking ...
+ */
+
+static int kstack_depth_to_print = 24;
+
+void show_stack(struct task_struct *task, unsigned long *sp)
+{
+	int i = 0;
+	unsigned long *stack;
+
+	if (sp == 0)
+		__asm__ __volatile__ ("mov %0, a1\n" : "=a"(sp));
+
+ 	stack = sp;
+
+	printk("\nStack: ");
+
+	for (i = 0; i < kstack_depth_to_print; i++) {
+		if (kstack_end(sp))
+			break;
+		if (i && ((i % 8) == 0))
+			printk("\n       ");
+		printk("%08lx ", *sp++);
+	}
+	printk("\n");
+	show_trace(task, stack);
+}
+
+void dump_stack(void)
+{
+	show_stack(current, NULL);
+}
+
+EXPORT_SYMBOL(dump_stack);
+
+
+void show_code(unsigned int *pc)
+{
+	long i;
+
+	printk("\nCode:");
+
+	for(i = -3 ; i < 6 ; i++) {
+		unsigned long insn;
+		if (__get_user(insn, pc + i)) {
+			printk(" (Bad address in pc)\n");
+			break;
+		}
+		printk("%c%08lx%c",(i?' ':'<'),insn,(i?' ':'>'));
+	}
+}
+
+spinlock_t die_lock = SPIN_LOCK_UNLOCKED;
+
+void die(const char * str, struct pt_regs * regs, long err)
+{
+	static int die_counter;
+	int nl = 0;
+
+	console_verbose();
+	spin_lock_irq(&die_lock);
+
+	printk("%s: sig: %ld [#%d]\n", str, err, ++die_counter);
+#ifdef CONFIG_PREEMPT
+	printk("PREEMPT ");
+	nl = 1;
+#endif
+	if (nl)
+		printk("\n");
+	show_regs(regs);
+	if (!user_mode(regs))
+		show_stack(NULL, (unsigned long*)regs->areg[1]);
+
+	spin_unlock_irq(&die_lock);
+
+	if (in_interrupt())
+		panic("Fatal exception in interrupt");
+
+	if (panic_on_oops) {
+		printk(KERN_EMERG "Fatal exception: panic in 5 seconds\n");
+		ssleep(5);
+		panic("Fatal exception");
+	}
+	do_exit(err);
+}
+
+
diff --git a/arch/xtensa/kernel/vectors.S b/arch/xtensa/kernel/vectors.S
new file mode 100644
--- /dev/null
+++ b/arch/xtensa/kernel/vectors.S
@@ -0,0 +1,464 @@
+/*
+ * arch/xtensa/kernel/vectors.S
+ *
+ * This file contains all exception vectors (user, kernel, and double),
+ * as well as the window vectors (overflow and underflow), and the debug
+ * vector. These are the primary vectors executed by the processor if an
+ * exception occurs.
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file "COPYING" in the main directory of
+ * this archive for more details.
+ *
+ * Copyright (C) 2005 Tensilica, Inc.
+ *
+ * Chris Zankel <chris@zankel.net>
+ *
+ */
+
+/*
+ * We use a two-level table approach. The user and kernel exception vectors
+ * use a first-level dispatch table to dispatch the exception to a registered
+ * fast handler or the default handler, if no fast handler was registered.
+ * The default handler sets up a C-stack and dispatches the exception to a
+ * registerd C handler in the second-level dispatch table.
+ *
+ * Fast handler entry condition:
+ *
+ *   a0:	trashed, original value saved on stack (PT_AREG0)
+ *   a1:	a1
+ *   a2:	new stack pointer, original value in depc
+ *   a3:	dispatch table
+ *   depc:	a2, original value saved on stack (PT_DEPC)
+ *   excsave_1:	a3
+ *
+ * The value for PT_DEPC saved to stack also functions as a boolean to
+ * indicate that the exception is either a double or a regular exception:
+ *
+ *   PT_DEPC	>= VALID_DOUBLE_EXCEPTION_ADDRESS: double exception
+ *		<  VALID_DOUBLE_EXCEPTION_ADDRESS: regular exception
+ *
+ * Note:  Neither the kernel nor the user exception handler generate literals.
+ *
+ */
+
+#include <linux/linkage.h>
+#include <asm/ptrace.h>
+#include <asm/ptrace.h>
+#include <asm/current.h>
+#include <asm/offsets.h>
+#include <asm/pgtable.h>
+#include <asm/processor.h>
+#include <asm/page.h>
+#include <asm/thread_info.h>
+#include <asm/processor.h>
+
+
+/*
+ * User exception vector. (Exceptions with PS.UM == 1, PS.EXCM == 0)
+ *
+ * We get here when an exception occurred while we were in userland.
+ * We switch to the kernel stack and jump to the first level handler
+ * associated to the exception cause.
+ *
+ * Note: the saved kernel stack pointer (EXC_TABLE_KSTK) is already
+ *       decremented by PT_USER_SIZE.
+ */
+
+	.section .UserExceptionVector.text, "ax"
+
+ENTRY(_UserExceptionVector)
+
+	xsr	a3, EXCSAVE_1		# save a3 and get dispatch table
+	wsr	a2, DEPC		# save a2
+	l32i	a2, a3, EXC_TABLE_KSTK	# load kernel stack to a2
+	s32i	a0, a2, PT_AREG0	# save a0 to ESF
+	rsr	a0, EXCCAUSE		# retrieve exception cause
+	s32i	a0, a2, PT_DEPC		# mark it as a regular exception
+	addx4	a0, a0, a3		# find entry in table
+	l32i	a0, a0, EXC_TABLE_FAST_USER	# load handler
+	jx	a0
+
+/*
+ * Kernel exception vector. (Exceptions with PS.UM == 0, PS.EXCM == 0)
+ *
+ * We get this exception when we were already in kernel space.
+ * We decrement the current stack pointer (kernel) by PT_SIZE and
+ * jump to the first-level handler associated with the exception cause.
+ *
+ * Note: we need to preserve space for the spill region.
+ */
+
+	.section .KernelExceptionVector.text, "ax"
+
+ENTRY(_KernelExceptionVector)
+
+	xsr	a3, EXCSAVE_1		# save a3, and get dispatch table
+	wsr	a2, DEPC		# save a2
+	addi	a2, a1, -16-PT_SIZE	# adjust stack pointer
+	s32i	a0, a2, PT_AREG0	# save a0 to ESF
+	rsr	a0, EXCCAUSE		# retrieve exception cause
+	s32i	a0, a2, PT_DEPC		# mark it as a regular exception
+	addx4	a0, a0, a3		# find entry in table
+	l32i	a0, a0, EXC_TABLE_FAST_KERNEL	# load handler address
+	jx	a0
+
+
+/*
+ * Double exception vector (Exceptions with PS.EXCM == 1)
+ * We get this exception when another exception occurs while were are
+ * already in an exception, such as window overflow/underflow exception,
+ * or 'expected' exceptions, for example memory exception when we were trying
+ * to read data from an invalid address in user space.
+ *
+ * Note that this vector is never invoked for level-1 interrupts, because such
+ * interrupts are disabled (masked) when PS.EXCM is set.
+ *
+ * We decode the exception and take the appropriate action.  However, the
+ * double exception vector is much more careful, because a lot more error
+ * cases go through the double exception vector than through the user and
+ * kernel exception vectors.
+ *
+ * Occasionally, the kernel expects a double exception to occur.  This usually
+ * happens when accessing user-space memory with the user's permissions
+ * (l32e/s32e instructions).  The kernel state, though, is not always suitable
+ * for immediate transfer of control to handle_double, where "normal" exception
+ * processing occurs. Also in kernel mode, TLB misses can occur if accessing
+ * vmalloc memory, possibly requiring repair in a double exception handler.
+ *
+ * The variable at TABLE_FIXUP offset from the pointer in EXCSAVE_1 doubles as
+ * a boolean variable and a pointer to a fixup routine. If the variable
+ * EXC_TABLE_FIXUP is non-zero, this handler jumps to that address. A value of
+ * zero indicates to use the default kernel/user exception handler.
+ * There is only one exception, when the value is identical to the exc_table
+ * label, the kernel is in trouble. This mechanism is used to protect critical
+ * sections, mainly when the handler writes to the stack to assert the stack
+ * pointer is valid. Once the fixup/default handler leaves that area, the
+ * EXC_TABLE_FIXUP variable is reset to the fixup handler or zero.
+ *
+ * Procedures wishing to use this mechanism should set EXC_TABLE_FIXUP to the
+ * nonzero address of a fixup routine before it could cause a double exception
+ * and reset it before it returns.
+ *
+ * Some other things to take care of when a fast exception handler doesn't
+ * specify a particular fixup handler but wants to use the default handlers:
+ *
+ *  - The original stack pointer (in a1) must not be modified. The fast
+ *    exception handler should only use a2 as the stack pointer.
+ *
+ *  - If the fast handler manipulates the stack pointer (in a2), it has to
+ *    register a valid fixup handler and cannot use the default handlers.
+ *
+ *  - The handler can use any other generic register from a3 to a15, but it
+ *    must save the content of these registers to stack (PT_AREG3...PT_AREGx)
+ *
+ *  - These registers must be saved before a double exception can occur.
+ *
+ *  - If we ever implement handling signals while in double exceptions, the
+ *    number of registers a fast handler has saved (excluding a0 and a1) must
+ *    be written to  PT_AREG1. (1 if only a3 is used, 2 for a3 and a4, etc. )
+ *
+ * The fixup handlers are special handlers:
+ *
+ *  - Fixup entry conditions differ from regular exceptions:
+ *
+ *	a0:	   DEPC
+ *	a1: 	   a1
+ *	a2:	   trashed, original value in EXC_TABLE_DOUBLE_A2
+ *	a3:	   exctable
+ *	depc:	   a0
+ *	excsave_1: a3
+ *
+ *  - When the kernel enters the fixup handler, it still assumes it is in a
+ *    critical section, so EXC_TABLE_FIXUP variable is set to exc_table.
+ *    The fixup handler, therefore, has to re-register itself as the fixup
+ *    handler before it returns from the double exception.
+ *
+ *  - Fixup handler can share the same exception frame with the fast handler.
+ *    The kernel stack pointer is not changed when entering the fixup handler.
+ *
+ *  - Fixup handlers can jump to the default kernel and user exception
+ *    handlers. Before it jumps, though, it has to setup a exception frame
+ *    on stack. Because the default handler resets the register fixup handler
+ *    the fixup handler must make sure that the default handler returns to
+ *    it instead of the exception address, so it can re-register itself as
+ *    the fixup handler.
+ *
+ * In case of a critical condition where the kernel cannot recover, we jump
+ * to unrecoverable_exception with the following entry conditions.
+ * All registers a0...a15 are unchanged from the last exception, except:
+ *
+ *	a0:	   last address before we jumped to the unrecoverable_exception.
+ *	excsave_1: a0
+ *
+ *
+ * See the handle_alloca_user and spill_registers routines for example clients.
+ *
+ * FIXME: Note: we currently don't allow signal handling coming from a double
+ *        exception, so the item markt with (*) is not required.
+ */
+
+	.section .DoubleExceptionVector.text, "ax"
+	.begin literal_prefix .DoubleExceptionVector
+
+ENTRY(_DoubleExceptionVector)
+
+	/* Deliberately destroy excsave (don't assume it's value was valid). */
+
+	wsr	a3, EXCSAVE_1		# save a3
+
+	/* Check for kernel double exception (usually fatal). */
+
+	rsr	a3, PS
+	_bbci.l	a3, PS_UM_SHIFT, .Lksp
+
+	/* Check if we are currently handling a window exception. */
+	/* Note: We don't need to indicate that we enter a critical section. */
+
+	xsr	a0, DEPC		# get DEPC, save a0
+
+	movi	a3, XCHAL_WINDOW_VECTORS_VADDR
+	_bltu	a0, a3, .Lfixup
+	addi	a3, a3, XSHAL_WINDOW_VECTORS_SIZE
+	_bgeu	a0, a3, .Lfixup
+
+	/* Window overflow/underflow exception. Get stack pointer. */
+
+	mov	a3, a2
+	movi	a2, exc_table
+	l32i	a2, a2, EXC_TABLE_KSTK
+
+	/* Check for overflow/underflow exception, jump if overflow. */
+
+	_bbci.l	a0, 6, .Lovfl
+
+	/* a0: depc, a1: a1, a2: kstk, a3: a2, depc: a0, excsave: a3  */
+
+	/* Restart window underflow exception.
+	 * We return to the instruction in user space that caused the window
+	 * underflow exception. Therefore, we change window base to the value
+	 * before we entered the window underflow exception and prepare the
+	 * registers to return as if we were coming from a regular exception
+	 * by changing depc (in a0).
+	 * Note: We can trash the current window frame (a0...a3) and depc!
+	 */
+
+	wsr	a2, DEPC		# save stack pointer temporarily
+	rsr	a0, PS
+	extui	a0, a0, XCHAL_PS_OWB_SHIFT, XCHAL_PS_OWB_BITS
+	wsr	a0, WINDOWBASE
+	rsync
+
+	/* We are now in the previous window frame. Save registers again. */
+
+	xsr	a2, DEPC		# save a2 and get stack pointer
+	s32i	a0, a2, PT_AREG0
+
+	wsr	a3, EXCSAVE_1		# save a3
+	movi	a3, exc_table
+
+	rsr	a0, EXCCAUSE
+	s32i	a0, a2, PT_DEPC		# mark it as a regular exception
+	addx4	a0, a0, a3
+	l32i	a0, a0, EXC_TABLE_FAST_USER
+	jx	a0
+
+.Lfixup:/* Check for a fixup handler or if we were in a critical section. */
+
+	/* a0: depc, a1: a1, a2: a2, a3: trashed, depc: a0, excsave1: a3 */
+
+	movi	a3, exc_table
+	s32i	a2, a3, EXC_TABLE_DOUBLE_SAVE	# temporary variable
+
+	/* Enter critical section. */
+
+	l32i	a2, a3, EXC_TABLE_FIXUP
+	s32i	a3, a3, EXC_TABLE_FIXUP
+	beq	a2, a3, .Lunrecoverable_fixup	# critical!
+	beqz	a2, .Ldflt			# no handler was registered
+
+	/* a0: depc, a1: a1, a2: trash, a3: exctable, depc: a0, excsave: a3 */
+
+	jx	a2
+
+.Ldflt:	/* Get stack pointer. */
+
+	l32i	a3, a3, EXC_TABLE_DOUBLE_SAVE
+	addi	a2, a3, -PT_USER_SIZE
+
+.Lovfl:	/* Jump to default handlers. */
+
+	/* a0: depc, a1: a1, a2: kstk, a3: a2, depc: a0, excsave: a3 */
+
+	xsr	a3, DEPC
+	s32i	a0, a2, PT_DEPC
+	s32i	a3, a2, PT_AREG0
+
+	/* a0: avail, a1: a1, a2: kstk, a3: avail, depc: a2, excsave: a3 */
+
+	movi	a3, exc_table
+	rsr	a0, EXCCAUSE
+	addx4	a0, a0, a3
+	l32i	a0, a0, EXC_TABLE_FAST_USER
+	jx	a0
+
+	/*
+	 * We only allow the ITLB miss exception if we are in kernel space.
+	 * All other exceptions are unexpected and thus unrecoverable!
+	 */
+
+	.extern fast_second_level_miss_double_kernel
+
+.Lksp:	/* a0: a0, a1: a1, a2: a2, a3: trashed, depc: depc, excsave: a3 */
+
+	rsr	a3, EXCCAUSE
+	beqi	a3, XCHAL_EXCCAUSE_ITLB_MISS, 1f
+	addi	a3, a3, -XCHAL_EXCCAUSE_DTLB_MISS
+	bnez	a3, .Lunrecoverable
+1:	movi	a3, fast_second_level_miss_double_kernel
+	jx	a3
+
+	/* Critical! We can't handle this situation. PANIC! */
+
+	.extern unrecoverable_exception
+
+.Lunrecoverable_fixup:
+	l32i	a2, a3, EXC_TABLE_DOUBLE_SAVE
+	xsr	a0, DEPC
+
+.Lunrecoverable:
+	rsr	a3, EXCSAVE_1
+	wsr	a0, EXCSAVE_1
+	movi	a0, unrecoverable_exception
+	callx0	a0
+
+	.end literal_prefix
+
+
+/*
+ * Debug interrupt vector
+ *
+ * There is not much space here, so simply jump to another handler.
+ * EXCSAVE[DEBUGLEVEL] has been set to that handler.
+ */
+
+	.section .DebugInterruptVector.text, "ax"
+
+ENTRY(_DebugInterruptVector)
+	xsr	a0, EXCSAVE + XCHAL_DEBUGLEVEL
+	jx	a0
+
+
+
+/* Window overflow and underflow handlers.
+ * The handlers must be 64 bytes apart, first starting with the underflow
+ * handlers underflow-4 to underflow-12, then the overflow handlers
+ * overflow-4 to overflow-12.
+ *
+ * Note: We rerun the underflow handlers if we hit an exception, so
+ *	 we try to access any page that would cause a page fault early.
+ */
+
+	.section		.WindowVectors.text, "ax"
+
+
+/* 4-Register Window Overflow Vector (Handler) */
+
+	.align 64
+.global _WindowOverflow4
+_WindowOverflow4:
+	s32e	a0, a5, -16
+	s32e	a1, a5, -12
+	s32e	a2, a5,  -8
+	s32e	a3, a5,  -4
+	rfwo
+
+
+/* 4-Register Window Underflow Vector (Handler) */
+
+	.align 64
+.global _WindowUnderflow4
+_WindowUnderflow4:
+	l32e	a0, a5, -16
+	l32e	a1, a5, -12
+	l32e	a2, a5,  -8
+	l32e	a3, a5,  -4
+	rfwu
+
+
+/* 8-Register Window Overflow Vector (Handler) */
+
+	.align 64
+.global _WindowOverflow8
+_WindowOverflow8:
+	s32e	a0, a9, -16
+	l32e	a0, a1, -12
+	s32e	a2, a9,  -8
+	s32e	a1, a9, -12
+	s32e	a3, a9,  -4
+	s32e	a4, a0, -32
+	s32e	a5, a0, -28
+	s32e	a6, a0, -24
+	s32e	a7, a0, -20
+	rfwo
+
+/* 8-Register Window Underflow Vector (Handler) */
+
+	.align 64
+.global _WindowUnderflow8
+_WindowUnderflow8:
+	l32e	a1, a9, -12
+	l32e	a0, a9, -16
+	l32e	a7, a1, -12
+	l32e	a2, a9,  -8
+	l32e	a4, a7, -32
+	l32e	a3, a9,  -4
+	l32e	a5, a7, -28
+	l32e	a6, a7, -24
+	l32e	a7, a7, -20
+	rfwu
+
+
+/* 12-Register Window Overflow Vector (Handler) */
+
+	.align 64
+.global _WindowOverflow12
+_WindowOverflow12:
+	s32e	a0,  a13, -16
+	l32e	a0,  a1,  -12
+	s32e	a1,  a13, -12
+	s32e	a2,  a13,  -8
+	s32e	a3,  a13,  -4
+	s32e	a4,  a0,  -48
+	s32e	a5,  a0,  -44
+	s32e	a6,  a0,  -40
+	s32e	a7,  a0,  -36
+	s32e	a8,  a0,  -32
+	s32e	a9,  a0,  -28
+	s32e	a10, a0,  -24
+	s32e	a11, a0,  -20
+	rfwo
+
+/* 12-Register Window Underflow Vector (Handler) */
+
+	.align 64
+.global _WindowUnderflow12
+_WindowUnderflow12:
+	l32e	a1,  a13, -12
+	l32e	a0,  a13, -16
+	l32e	a11, a1,  -12
+	l32e	a2,  a13,  -8
+	l32e	a4,  a11, -48
+	l32e	a8,  a11, -32
+	l32e	a3,  a13,  -4
+	l32e	a5,  a11, -44
+	l32e	a6,  a11, -40
+	l32e	a7,  a11, -36
+	l32e	a9,  a11, -28
+	l32e	a10, a11, -24
+	l32e	a11, a11, -20
+	rfwu
+
+	.text
+
+
diff --git a/arch/xtensa/kernel/vmlinux.lds.S b/arch/xtensa/kernel/vmlinux.lds.S
new file mode 100644
--- /dev/null
+++ b/arch/xtensa/kernel/vmlinux.lds.S
@@ -0,0 +1,341 @@
+/*
+ * arch/xtensa/kernel/vmlinux.lds.S
+ *
+ * Xtensa linker script
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ *
+ * Chris Zankel <chris@zankel.net>
+ * Marc Gauthier <marc@tensilica.com, marc@alumni.uwaterloo.ca>
+ * Joe Taylor <joe@tensilica.com, joetylr@yahoo.com>
+ */
+
+#include <asm-generic/vmlinux.lds.h>
+
+#include <linux/config.h>
+#define _NOCLANGUAGE
+#include <xtensa/config/core.h>
+#include <xtensa/config/system.h>
+OUTPUT_ARCH(xtensa)
+ENTRY(_start)
+
+#if XCHAL_MEMORY_ORDER == XTHAL_BIGENDIAN
+jiffies = jiffies_64 + 4;
+#else
+jiffies = jiffies_64;
+#endif
+
+#define KERNELOFFSET 0x1000
+
+/* Note: In the following macros, it would be nice to specify only the
+   vector name and section kind and construct "sym" and "section" using
+   CPP concatenation, but that does not work reliably.  Concatenating a
+   string with "." produces an invalid token.  CPP will not print a
+   warning because it thinks this is an assembly file, but it leaves
+   them as multiple tokens and there may or may not be whitespace
+   between them.  */
+
+/* Macro for a relocation entry */
+
+#define RELOCATE_ENTRY(sym, section)		\
+	LONG(sym ## _start);			\
+	LONG(sym ## _end);			\
+	LONG(LOADADDR(section))
+
+/* Macro to define a section for a vector.
+ *
+ * Use of the MIN function catches the types of errors illustrated in
+ * the following example:
+ *
+ * Assume the section .DoubleExceptionVector.literal is completely
+ * full.  Then a programmer adds code to .DoubleExceptionVector.text
+ * that produces another literal.  The final literal position will
+ * overlay onto the first word of the adjacent code section
+ * .DoubleExceptionVector.text.  (In practice, the literals will
+ * overwrite the code, and the first few instructions will be
+ * garbage.)
+ */
+
+#define SECTION_VECTOR(sym, section, addr, max_prevsec_size, prevsec)       \
+  section addr : AT((MIN(LOADADDR(prevsec) + max_prevsec_size,		    \
+		         LOADADDR(prevsec) + SIZEOF(prevsec)) + 3) & ~ 3)   \
+  {									    \
+    . = ALIGN(4);							    \
+    sym ## _start = ABSOLUTE(.);		 			    \
+    *(section)								    \
+    sym ## _end = ABSOLUTE(.);						    \
+  }
+
+/*
+ *  Mapping of input sections to output sections when linking.
+ */
+
+SECTIONS
+{
+  . = XCHAL_KSEG_CACHED_VADDR + KERNELOFFSET;
+  /* .text section */
+
+  _text = .;
+  _stext = .;
+  _ftext = .;
+
+  .text :
+  {
+    /* The .head.text section must be the first section! */
+    *(.head.text)
+    *(.literal .text)
+    *(.srom.text)
+    VMLINUX_SYMBOL(__sched_text_start) = .;
+    *(.sched.literal .sched.text)
+    VMLINUX_SYMBOL(__sched_text_end) = .;
+    VMLINUX_SYMBOL(__lock_text_start) = .;
+    *(.spinlock.literal .spinlock.text)
+    VMLINUX_SYMBOL(__lock_text_end) = .;
+
+  }
+  _etext = .;
+
+  . = ALIGN(16);
+
+  RODATA
+
+  /*  Relocation table */
+
+  . = ALIGN(16);
+  __boot_reloc_table_start = ABSOLUTE(.);
+
+  __relocate : {
+
+    RELOCATE_ENTRY(_WindowVectors_text,
+		   .WindowVectors.text);
+#if 0
+    RELOCATE_ENTRY(_KernelExceptionVector_literal,
+		   .KernelExceptionVector.literal);
+#endif
+    RELOCATE_ENTRY(_KernelExceptionVector_text,
+		   .KernelExceptionVector.text);
+#if 0
+    RELOCATE_ENTRY(_UserExceptionVector_literal,
+		   .UserExceptionVector.literal);
+#endif
+    RELOCATE_ENTRY(_UserExceptionVector_text,
+		   .UserExceptionVector.text);
+    RELOCATE_ENTRY(_DoubleExceptionVector_literal,
+		   .DoubleExceptionVector.literal);
+    RELOCATE_ENTRY(_DoubleExceptionVector_text,
+		   .DoubleExceptionVector.text);
+  }
+  __boot_reloc_table_end = ABSOLUTE(.) ;
+
+  .fixup   : { *(.fixup) }
+
+  . = ALIGN(16);
+
+  __ex_table : {
+    __start___ex_table = .;
+    *(__ex_table)
+    __stop___ex_table = .;
+  }
+
+  /* Data section */
+
+  . = ALIGN(XCHAL_ICACHE_LINESIZE);
+  _fdata = .;
+  .data :
+  {
+    *(.data) CONSTRUCTORS
+    . = ALIGN(XCHAL_ICACHE_LINESIZE);
+    *(.data.cacheline_aligned)
+  }
+
+  _edata = .;
+
+  /* The initial task */
+  . = ALIGN(8192);
+  .data.init_task : { *(.data.init_task) }
+
+  /* Initialization code and data: */
+
+  . = ALIGN(1<<XCHAL_MMU_MIN_PTE_PAGE_SIZE);
+  __init_begin = .;
+  .init.text : {
+  	_sinittext = .;
+	*(.init.literal) *(.init.text)
+	_einittext = .;
+  }
+
+  .init.data :
+  {
+    *(.init.data)
+    . = ALIGN(0x4);
+    __tagtable_begin = .;
+    *(.taglist)
+    __tagtable_end = .;
+  }
+
+  . = ALIGN(XCHAL_ICACHE_LINESIZE);
+
+  __setup_start = .;
+  .init.setup : { *(.init.setup) }
+  __setup_end = .;
+
+  __initcall_start = .;
+  .initcall.init : {
+  	*(.initcall1.init)
+  	*(.initcall2.init)
+  	*(.initcall3.init)
+  	*(.initcall4.init)
+  	*(.initcall5.init)
+  	*(.initcall6.init)
+  	*(.initcall7.init)
+  }
+  __initcall_end = .;
+
+  __con_initcall_start = .;
+  .con_initcall.init : { *(.con_initcall.init) }
+  __con_initcall_end = .;
+
+  SECURITY_INIT
+
+  . = ALIGN(4);
+
+  __start___ftr_fixup = .;
+  __ftr_fixup : { *(__ftr_fixup) }
+  __stop___ftr_fixup = .;
+
+  . = ALIGN(32);
+  __per_cpu_start = .;
+  .data.percpu  : { *(.data.percpu) }
+  __per_cpu_end = .;
+
+  . = ALIGN(4096);
+  __initramfs_start =.;
+  .init.ramfs : { *(.init.ramfs) }
+  __initramfs_end = .;
+
+  /* We need this dummy segment here */
+
+  . = ALIGN(4);
+  .dummy : { LONG(0) }
+
+  /* The vectors are relocated to the real position at startup time */
+
+  SECTION_VECTOR (_WindowVectors_text,
+		  .WindowVectors.text,
+		  XCHAL_WINDOW_VECTORS_VADDR, 4,
+		  .dummy)
+  SECTION_VECTOR (_DebugInterruptVector_literal,
+		  .DebugInterruptVector.literal,
+		  XCHAL_INTLEVEL_VECTOR_VADDR(XCHAL_DEBUGLEVEL) - 4,
+		  SIZEOF(.WindowVectors.text),
+		  .WindowVectors.text)
+  SECTION_VECTOR (_DebugInterruptVector_text,
+		  .DebugInterruptVector.text,
+		  XCHAL_INTLEVEL_VECTOR_VADDR(XCHAL_DEBUGLEVEL),
+		  4,
+		  .DebugInterruptVector.literal)
+  SECTION_VECTOR (_KernelExceptionVector_literal,
+		  .KernelExceptionVector.literal,
+		  XCHAL_KERNELEXC_VECTOR_VADDR - 4,
+		  SIZEOF(.DebugInterruptVector.text),
+		  .DebugInterruptVector.text)
+  SECTION_VECTOR (_KernelExceptionVector_text,
+		  .KernelExceptionVector.text,
+		  XCHAL_KERNELEXC_VECTOR_VADDR,
+		  4,
+		  .KernelExceptionVector.literal)
+  SECTION_VECTOR (_UserExceptionVector_literal,
+		  .UserExceptionVector.literal,
+		  XCHAL_USEREXC_VECTOR_VADDR - 4,
+		  SIZEOF(.KernelExceptionVector.text),
+		  .KernelExceptionVector.text)
+  SECTION_VECTOR (_UserExceptionVector_text,
+		  .UserExceptionVector.text,
+		  XCHAL_USEREXC_VECTOR_VADDR,
+		  4,
+		  .UserExceptionVector.literal)
+  SECTION_VECTOR (_DoubleExceptionVector_literal,
+		  .DoubleExceptionVector.literal,
+		  XCHAL_DOUBLEEXC_VECTOR_VADDR - 16,
+		  SIZEOF(.UserExceptionVector.text),
+		  .UserExceptionVector.text)
+  SECTION_VECTOR (_DoubleExceptionVector_text,
+		  .DoubleExceptionVector.text,
+		  XCHAL_DOUBLEEXC_VECTOR_VADDR,
+		  32,
+		  .DoubleExceptionVector.literal)
+
+  . = (LOADADDR( .DoubleExceptionVector.text ) + SIZEOF( .DoubleExceptionVector.text ) + 3) & ~ 3;
+  . = ALIGN(1<<XCHAL_MMU_MIN_PTE_PAGE_SIZE);
+
+  __init_end = .;
+
+  . = ALIGN(8192);
+
+  /* BSS section */
+  _bss_start = .;
+  .sbss : { *(.sbss) *(.scommon) }
+  .bss : { *(COMMON) *(.bss) }
+  _bss_end = .;
+  _end = .;
+
+  /* only used by the boot loader  */
+
+  . = ALIGN(0x10);
+  .bootstrap : { *(.bootstrap.literal .bootstrap.text .bootstrap.data) }
+
+  . = ALIGN(0x1000);
+  __initrd_start = .;
+  .initrd : { *(.initrd) }
+  __initrd_end = .;
+
+  .ResetVector.text XCHAL_RESET_VECTOR_VADDR :
+  {
+    *(.ResetVector.text)
+  }
+
+
+  /* Sections to be discarded */
+  /DISCARD/ :
+  {
+        *(.text.exit)
+	*(.text.exit.literal)
+        *(.data.exit)
+        *(.exitcall.exit)
+  }
+
+
+  .debug  0 :  { *(.debug) }
+  .line  0 :  { *(.line) }
+  .debug_srcinfo  0 :  { *(.debug_srcinfo) }
+  .debug_sfnames  0 :  { *(.debug_sfnames) }
+  .debug_aranges  0 :  { *(.debug_aranges) }
+  .debug_pubnames  0 :  { *(.debug_pubnames) }
+  .debug_info  0 :  { *(.debug_info) }
+  .debug_abbrev  0 :  { *(.debug_abbrev) }
+  .debug_line  0 :  { *(.debug_line) }
+  .debug_frame  0 :  { *(.debug_frame) }
+  .debug_str  0 :  { *(.debug_str) }
+  .debug_loc  0 :  { *(.debug_loc) }
+  .debug_macinfo  0 :  { *(.debug_macinfo) }
+  .debug_weaknames  0 :  { *(.debug_weaknames) }
+  .debug_funcnames  0 :  { *(.debug_funcnames) }
+  .debug_typenames  0 :  { *(.debug_typenames) }
+  .debug_varnames  0 :  { *(.debug_varnames) }
+
+  .xt.insn 0 :
+  {
+    *(.xt.insn)
+    *(.gnu.linkonce.x*)
+  }
+
+  .xt.lit 0 :
+  {
+    *(.xt.lit)
+    *(.gnu.linkonce.p*)
+  }
+}
diff --git a/arch/xtensa/kernel/xtensa_ksyms.c b/arch/xtensa/kernel/xtensa_ksyms.c
new file mode 100644
--- /dev/null
+++ b/arch/xtensa/kernel/xtensa_ksyms.c
@@ -0,0 +1,123 @@
+/*
+ * arch/xtensa/kernel/xtensa_ksyms.c
+ *
+ * Export Xtensa-specific functions for loadable modules.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005  Tensilica Inc.
+ *
+ * Joe Taylor <joe@tensilica.com>
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <asm/irq.h>
+#include <linux/in6.h>
+#include <linux/pci.h>
+#include <linux/ide.h>
+
+#include <asm/uaccess.h>
+#include <asm/checksum.h>
+#include <asm/dma.h>
+#include <asm/io.h>
+#include <asm/page.h>
+#include <asm/pgalloc.h>
+#include <asm/semaphore.h>
+#ifdef CONFIG_BLK_DEV_FD
+#include <asm/floppy.h>
+#endif
+#ifdef CONFIG_NET
+#include <net/checksum.h>
+#endif /* CONFIG_NET */
+
+
+/*
+ * String functions
+ */
+EXPORT_SYMBOL(memcmp);
+EXPORT_SYMBOL(memset);
+EXPORT_SYMBOL(memcpy);
+EXPORT_SYMBOL(memmove);
+EXPORT_SYMBOL(memchr);
+EXPORT_SYMBOL(strcat);
+EXPORT_SYMBOL(strchr);
+EXPORT_SYMBOL(strlen);
+EXPORT_SYMBOL(strpbrk);
+EXPORT_SYMBOL(strncat);
+EXPORT_SYMBOL(strnlen);
+EXPORT_SYMBOL(strrchr);
+EXPORT_SYMBOL(strstr);
+
+EXPORT_SYMBOL(enable_irq);
+EXPORT_SYMBOL(disable_irq);
+EXPORT_SYMBOL(kernel_thread);
+
+/*
+ * gcc internal math functions
+ */
+extern long long __ashrdi3(long long, int);
+extern long long __ashldi3(long long, int);
+extern long long __lshrdi3(long long, int);
+extern int __divsi3(int, int);
+extern int __modsi3(int, int);
+extern long long __muldi3(long long, long long);
+extern int __mulsi3(int, int);
+extern unsigned int __udivsi3(unsigned int, unsigned int);
+extern unsigned int __umodsi3(unsigned int, unsigned int);
+extern unsigned long long __umoddi3(unsigned long long, unsigned long long);
+extern unsigned long long __udivdi3(unsigned long long, unsigned long long);
+
+EXPORT_SYMBOL(__ashldi3);
+EXPORT_SYMBOL(__ashrdi3);
+EXPORT_SYMBOL(__lshrdi3);
+EXPORT_SYMBOL(__divsi3);
+EXPORT_SYMBOL(__modsi3);
+EXPORT_SYMBOL(__muldi3);
+EXPORT_SYMBOL(__mulsi3);
+EXPORT_SYMBOL(__udivsi3);
+EXPORT_SYMBOL(__umodsi3);
+EXPORT_SYMBOL(__udivdi3);
+EXPORT_SYMBOL(__umoddi3);
+
+/*
+ * Semaphore operations
+ */
+EXPORT_SYMBOL(__down);
+EXPORT_SYMBOL(__down_interruptible);
+EXPORT_SYMBOL(__down_trylock);
+EXPORT_SYMBOL(__up);
+
+#ifdef CONFIG_NET
+/*
+ * Networking support
+ */
+EXPORT_SYMBOL(csum_partial_copy_generic);
+#endif /* CONFIG_NET */
+
+/*
+ * Architecture-specific symbols
+ */
+EXPORT_SYMBOL(__xtensa_copy_user);
+
+/*
+ * Kernel hacking ...
+ */
+
+#if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE)
+// FIXME EXPORT_SYMBOL(screen_info);
+#endif
+
+EXPORT_SYMBOL(get_wchan);
+
+EXPORT_SYMBOL(outsb);
+EXPORT_SYMBOL(outsw);
+EXPORT_SYMBOL(outsl);
+EXPORT_SYMBOL(insb);
+EXPORT_SYMBOL(insw);
+EXPORT_SYMBOL(insl);
diff --git a/arch/xtensa/lib/Makefile b/arch/xtensa/lib/Makefile
new file mode 100644
--- /dev/null
+++ b/arch/xtensa/lib/Makefile
@@ -0,0 +1,7 @@
+#
+# Makefile for Xtensa-specific library files.
+#
+
+lib-y	+= memcopy.o memset.o checksum.o strcasecmp.o \
+	   usercopy.o strncpy_user.o strnlen_user.o
+lib-$(CONFIG_PCI) += pci-auto.o
diff --git a/arch/xtensa/lib/checksum.S b/arch/xtensa/lib/checksum.S
new file mode 100644
--- /dev/null
+++ b/arch/xtensa/lib/checksum.S
@@ -0,0 +1,410 @@
+/*
+ * INET		An implementation of the TCP/IP protocol suite for the LINUX
+ *		operating system.  INET is implemented using the  BSD Socket
+ *		interface as the means of communication with the user level.
+ *
+ *		IP/TCP/UDP checksumming routines
+ *
+ * Xtensa version:  Copyright (C) 2001 Tensilica, Inc. by Kevin Chea
+ *                  Optimized by Joe Taylor
+ *
+ *		This program is free software; you can redistribute it and/or
+ *		modify it under the terms of the GNU General Public License
+ *		as published by the Free Software Foundation; either version
+ *		2 of the License, or (at your option) any later version.
+ */
+
+#include <asm/errno.h>
+#include <linux/linkage.h>
+#define _ASMLANGUAGE
+#include <xtensa/config/core.h>
+
+/*
+ * computes a partial checksum, e.g. for TCP/UDP fragments
+ */
+
+/*
+ * unsigned int csum_partial(const unsigned char *buf, int len,
+ *                           unsigned int sum);
+ *    a2 = buf
+ *    a3 = len
+ *    a4 = sum
+ *
+ * This function assumes 2- or 4-byte alignment.  Other alignments will fail!
+ */
+
+/* ONES_ADD converts twos-complement math to ones-complement. */
+#define ONES_ADD(sum, val)	  \
+	add	sum, sum, val	; \
+	bgeu	sum, val, 99f	; \
+	addi	sum, sum, 1	; \
+99:				;
+
+.text
+ENTRY(csum_partial)
+	  /*
+	   * Experiments with Ethernet and SLIP connections show that buf
+	   * is aligned on either a 2-byte or 4-byte boundary.
+	   */
+	entry	sp, 32
+	extui	a5, a2, 0, 2
+	bnez	a5, 8f		/* branch if 2-byte aligned */
+	/* Fall-through on common case, 4-byte alignment */
+1:
+	srli	a5, a3, 5	/* 32-byte chunks */
+#if XCHAL_HAVE_LOOPS
+	loopgtz	a5, 2f
+#else
+	beqz	a5, 2f
+	slli	a5, a5, 5
+	add	a5, a5, a2	/* a5 = end of last 32-byte chunk */
+.Loop1:
+#endif
+	l32i	a6, a2, 0
+	l32i	a7, a2, 4
+	ONES_ADD(a4, a6)
+	ONES_ADD(a4, a7)
+	l32i	a6, a2, 8
+	l32i	a7, a2, 12
+	ONES_ADD(a4, a6)
+	ONES_ADD(a4, a7)
+	l32i	a6, a2, 16
+	l32i	a7, a2, 20
+	ONES_ADD(a4, a6)
+	ONES_ADD(a4, a7)
+	l32i	a6, a2, 24
+	l32i	a7, a2, 28
+	ONES_ADD(a4, a6)
+	ONES_ADD(a4, a7)
+	addi	a2, a2, 4*8
+#if !XCHAL_HAVE_LOOPS
+	blt	a2, a5, .Loop1
+#endif
+2:
+	extui	a5, a3, 2, 3	/* remaining 4-byte chunks */
+#if XCHAL_HAVE_LOOPS
+	loopgtz	a5, 3f
+#else
+	beqz	a5, 3f
+	slli	a5, a5, 2
+	add	a5, a5, a2	/* a5 = end of last 4-byte chunk */
+.Loop2:
+#endif
+	l32i	a6, a2, 0
+	ONES_ADD(a4, a6)
+	addi	a2, a2, 4
+#if !XCHAL_HAVE_LOOPS
+	blt	a2, a5, .Loop2
+#endif
+3:
+	_bbci.l	a3, 1, 5f	/* remaining 2-byte chunk */
+	l16ui	a6, a2, 0
+	ONES_ADD(a4, a6)
+	addi	a2, a2, 2
+5:
+	_bbci.l	a3, 0, 7f	/* remaining 1-byte chunk */
+6:	l8ui	a6, a2, 0
+#ifdef __XTENSA_EB__
+	slli	a6, a6, 8	/* load byte into bits 8..15 */
+#endif
+	ONES_ADD(a4, a6)
+7:
+	mov	a2, a4
+	retw
+
+	/* uncommon case, buf is 2-byte aligned */
+8:
+	beqz	a3, 7b		/* branch if len == 0 */
+	beqi	a3, 1, 6b	/* branch if len == 1 */
+
+	extui	a5, a2, 0, 1
+	bnez	a5, 8f		/* branch if 1-byte aligned */
+
+	l16ui	a6, a2, 0	/* common case, len >= 2 */
+	ONES_ADD(a4, a6)
+	addi	a2, a2, 2	/* adjust buf */
+	addi	a3, a3, -2	/* adjust len */
+	j	1b		/* now buf is 4-byte aligned */
+
+	/* case: odd-byte aligned, len > 1
+	 * This case is dog slow, so don't give us an odd address.
+	 * (I don't think this ever happens, but just in case.)
+	 */
+8:
+	srli	a5, a3, 2	/* 4-byte chunks */
+#if XCHAL_HAVE_LOOPS
+	loopgtz	a5, 2f
+#else
+	beqz	a5, 2f
+	slli	a5, a5, 2
+	add	a5, a5, a2	/* a5 = end of last 4-byte chunk */
+.Loop3:
+#endif
+	l8ui	a6, a2, 0	/* bits 24..31 */
+	l16ui	a7, a2, 1	/* bits  8..23 */
+	l8ui	a8, a2, 3	/* bits  0.. 8 */
+#ifdef	__XTENSA_EB__
+	slli	a6, a6, 24
+#else
+	slli	a8, a8, 24
+#endif
+	slli	a7, a7, 8
+	or	a7, a7, a6
+	or	a7, a7, a8
+	ONES_ADD(a4, a7)
+	addi	a2, a2, 4
+#if !XCHAL_HAVE_LOOPS
+	blt	a2, a5, .Loop3
+#endif
+2:
+	_bbci.l	a3, 1, 3f	/* remaining 2-byte chunk, still odd addr */
+	l8ui	a6, a2, 0
+	l8ui	a7, a2, 1
+#ifdef	__XTENSA_EB__
+	slli	a6, a6, 8
+#else
+	slli	a7, a7, 8
+#endif
+	or	a7, a7, a6
+	ONES_ADD(a4, a7)
+	addi	a2, a2, 2
+3:
+	j	5b		/* branch to handle the remaining byte */
+
+
+
+/*
+ * Copy from ds while checksumming, otherwise like csum_partial
+ *
+ * The macros SRC and DST specify the type of access for the instruction.
+ * thus we can call a custom exception handler for each access type.
+ */
+
+#define SRC(y...)			\
+	9999: y;			\
+	.section __ex_table, "a";	\
+	.long 9999b, 6001f	;	\
+	.previous
+
+#define DST(y...)			\
+	9999: y;			\
+	.section __ex_table, "a";	\
+	.long 9999b, 6002f	;	\
+	.previous
+
+/*
+unsigned int csum_partial_copy_generic (const char *src, char *dst, int len,
+					int sum, int *src_err_ptr, int *dst_err_ptr)
+	a2  = src
+	a3  = dst
+	a4  = len
+	a5  = sum
+	a6  = src_err_ptr
+	a7  = dst_err_ptr
+	a8  = temp
+	a9  = temp
+	a10 = temp
+	a11 = original len for exception handling
+	a12 = original dst for exception handling
+
+    This function is optimized for 4-byte aligned addresses.  Other
+    alignments work, but not nearly as efficiently.
+ */
+
+ENTRY(csum_partial_copy_generic)
+	entry	sp, 32
+	mov	a12, a3
+	mov	a11, a4
+	or	a10, a2, a3
+
+	/* We optimize the following alignment tests for the 4-byte
+	aligned case.  Two bbsi.l instructions might seem more optimal
+	(commented out below).  However, both labels 5: and 3: are out
+	of the imm8 range, so the assembler relaxes them into
+	equivalent bbci.l, j combinations, which is actually
+	slower. */
+
+	extui	a9, a10, 0, 2
+	beqz	a9, 1f		/* branch if both are 4-byte aligned */
+	bbsi.l	a10, 0, 5f	/* branch if one address is odd */
+	j	3f		/* one address is 2-byte aligned */
+
+/*	_bbsi.l	a10, 0, 5f */	/* branch if odd address */
+/*	_bbsi.l	a10, 1, 3f */	/* branch if 2-byte-aligned address */
+
+1:
+	/* src and dst are both 4-byte aligned */
+	srli	a10, a4, 5	/* 32-byte chunks */
+#if XCHAL_HAVE_LOOPS
+	loopgtz	a10, 2f
+#else
+	beqz	a10, 2f
+	slli	a10, a10, 5
+	add	a10, a10, a2	/* a10 = end of last 32-byte src chunk */
+.Loop5:
+#endif
+SRC(	l32i	a9, a2, 0	)
+SRC(	l32i	a8, a2, 4	)
+DST(	s32i	a9, a3, 0	)
+DST(	s32i	a8, a3, 4	)
+	ONES_ADD(a5, a9)
+	ONES_ADD(a5, a8)
+SRC(	l32i	a9, a2, 8	)
+SRC(	l32i	a8, a2, 12	)
+DST(	s32i	a9, a3, 8	)
+DST(	s32i	a8, a3, 12	)
+	ONES_ADD(a5, a9)
+	ONES_ADD(a5, a8)
+SRC(	l32i	a9, a2, 16	)
+SRC(	l32i	a8, a2, 20	)
+DST(	s32i	a9, a3, 16	)
+DST(	s32i	a8, a3, 20	)
+	ONES_ADD(a5, a9)
+	ONES_ADD(a5, a8)
+SRC(	l32i	a9, a2, 24	)
+SRC(	l32i	a8, a2, 28	)
+DST(	s32i	a9, a3, 24	)
+DST(	s32i	a8, a3, 28	)
+	ONES_ADD(a5, a9)
+	ONES_ADD(a5, a8)
+	addi	a2, a2, 32
+	addi	a3, a3, 32
+#if !XCHAL_HAVE_LOOPS
+	blt	a2, a10, .Loop5
+#endif
+2:
+	extui	a10, a4, 2, 3	/* remaining 4-byte chunks */
+	extui	a4, a4, 0, 2	/* reset len for general-case, 2-byte chunks */
+#if XCHAL_HAVE_LOOPS
+	loopgtz	a10, 3f
+#else
+	beqz	a10, 3f
+	slli	a10, a10, 2
+	add	a10, a10, a2	/* a10 = end of last 4-byte src chunk */
+.Loop6:
+#endif
+SRC(	l32i	a9, a2, 0	)
+DST(	s32i	a9, a3, 0	)
+	ONES_ADD(a5, a9)
+	addi	a2, a2, 4
+	addi	a3, a3, 4
+#if !XCHAL_HAVE_LOOPS
+	blt	a2, a10, .Loop6
+#endif
+3:
+	/*
+	Control comes to here in two cases: (1) It may fall through
+	to here from the 4-byte alignment case to process, at most,
+	one 2-byte chunk.  (2) It branches to here from above if
+	either src or dst is 2-byte aligned, and we process all bytes
+	here, except for perhaps a trailing odd byte.  It's
+	inefficient, so align your addresses to 4-byte boundaries.
+
+	a2 = src
+	a3 = dst
+	a4 = len
+	a5 = sum
+	*/
+	srli	a10, a4, 1	/* 2-byte chunks */
+#if XCHAL_HAVE_LOOPS
+	loopgtz	a10, 4f
+#else
+	beqz	a10, 4f
+	slli	a10, a10, 1
+	add	a10, a10, a2	/* a10 = end of last 2-byte src chunk */
+.Loop7:
+#endif
+SRC(	l16ui	a9, a2, 0	)
+DST(	s16i	a9, a3, 0	)
+	ONES_ADD(a5, a9)
+	addi	a2, a2, 2
+	addi	a3, a3, 2
+#if !XCHAL_HAVE_LOOPS
+	blt	a2, a10, .Loop7
+#endif
+4:
+	/* This section processes a possible trailing odd byte. */
+	_bbci.l	a4, 0, 8f	/* 1-byte chunk */
+SRC(	l8ui	a9, a2, 0	)
+DST(	s8i	a9, a3, 0	)
+#ifdef __XTENSA_EB__
+	slli	a9, a9, 8	/* shift byte to bits 8..15 */
+#endif
+	ONES_ADD(a5, a9)
+8:
+	mov	a2, a5
+	retw
+
+5:
+	/* Control branch to here when either src or dst is odd.  We
+	process all bytes using 8-bit accesses.  Grossly inefficient,
+	so don't feed us an odd address. */
+
+	srli	a10, a4, 1	/* handle in pairs for 16-bit csum */
+#if XCHAL_HAVE_LOOPS
+	loopgtz	a10, 6f
+#else
+	beqz	a10, 6f
+	slli	a10, a10, 1
+	add	a10, a10, a2	/* a10 = end of last odd-aligned, 2-byte src chunk */
+.Loop8:
+#endif
+SRC(	l8ui	a9, a2, 0	)
+SRC(	l8ui	a8, a2, 1	)
+DST(	s8i	a9, a3, 0	)
+DST(	s8i	a8, a3, 1	)
+#ifdef __XTENSA_EB__
+	slli	a9, a9, 8	/* combine into a single 16-bit value */
+#else				/* for checksum computation */
+	slli	a8, a8, 8
+#endif
+	or	a9, a9, a8
+	ONES_ADD(a5, a9)
+	addi	a2, a2, 2
+	addi	a3, a3, 2
+#if !XCHAL_HAVE_LOOPS
+	blt	a2, a10, .Loop8
+#endif
+6:
+	j	4b		/* process the possible trailing odd byte */
+
+
+# Exception handler:
+.section .fixup, "ax"
+/*
+	a6  = src_err_ptr
+	a7  = dst_err_ptr
+	a11 = original len for exception handling
+	a12 = original dst for exception handling
+*/
+
+6001:
+	_movi	a2, -EFAULT
+	s32i	a2, a6, 0	/* src_err_ptr */
+
+	# clear the complete destination - computing the rest
+	# is too much work
+	movi	a2, 0
+#if XCHAL_HAVE_LOOPS
+	loopgtz	a11, 2f
+#else
+	beqz	a11, 2f
+	add	a11, a11, a12	/* a11 = ending address */
+.Leloop:
+#endif
+	s8i	a2, a12, 0
+	addi	a12, a12, 1
+#if !XCHAL_HAVE_LOOPS
+	blt	a12, a11, .Leloop
+#endif
+2:
+	retw
+
+6002:
+	movi	a2, -EFAULT
+	s32i	a2, a7, 0	/* dst_err_ptr */
+	movi	a2, 0
+	retw
+
+.previous
+
diff --git a/arch/xtensa/lib/memcopy.S b/arch/xtensa/lib/memcopy.S
new file mode 100644
--- /dev/null
+++ b/arch/xtensa/lib/memcopy.S
@@ -0,0 +1,315 @@
+/*
+ * arch/xtensa/lib/hal/memcopy.S -- Core HAL library functions
+ * xthal_memcpy and xthal_bcopy
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2002 - 2005 Tensilica Inc.
+ */
+
+#include <xtensa/coreasm.h>
+
+	.macro	src_b	r, w0, w1
+#ifdef __XTENSA_EB__
+	src	\r, \w0, \w1
+#else
+	src	\r, \w1, \w0
+#endif
+	.endm
+
+	.macro	ssa8	r
+#ifdef __XTENSA_EB__
+	ssa8b	\r
+#else
+	ssa8l	\r
+#endif
+	.endm
+
+
+/*
+ * void *memcpy(void *dst, const void *src, size_t len);
+ * void *memmove(void *dst, const void *src, size_t len);
+ * void *bcopy(const void *src, void *dst, size_t len);
+ *
+ * This function is intended to do the same thing as the standard
+ * library function memcpy() (or bcopy()) for most cases.
+ * However, where the source and/or destination references
+ * an instruction RAM or ROM or a data RAM or ROM, that
+ * source and/or destination will always be accessed with
+ * 32-bit load and store instructions (as required for these
+ * types of devices).
+ *
+ * !!!!!!!  XTFIXME:
+ * !!!!!!!  Handling of IRAM/IROM has not yet
+ * !!!!!!!  been implemented.
+ *
+ * The bcopy version is provided here to avoid the overhead
+ * of an extra call, for callers that require this convention.
+ *
+ * The (general case) algorithm is as follows:
+ *   If destination is unaligned, align it by conditionally
+ *     copying 1 and 2 bytes.
+ *   If source is aligned,
+ *     do 16 bytes with a loop, and then finish up with
+ *     8, 4, 2, and 1 byte copies conditional on the length;
+ *   else (if source is unaligned),
+ *     do the same, but use SRC to align the source data.
+ *   This code tries to use fall-through branches for the common
+ *     case of aligned source and destination and multiple
+ *     of 4 (or 8) length.
+ *
+ * Register use:
+ *	a0/ return address
+ *	a1/ stack pointer
+ *	a2/ return value
+ *	a3/ src
+ *	a4/ length
+ *	a5/ dst
+ *	a6/ tmp
+ *	a7/ tmp
+ *	a8/ tmp
+ *	a9/ tmp
+ *	a10/ tmp
+ *	a11/ tmp
+ */
+
+	.text
+	.align	4
+	.global	bcopy
+	.type   bcopy,@function
+bcopy:
+	entry	sp, 16		# minimal stack frame
+	# a2=src, a3=dst, a4=len
+	mov	a5, a3		# copy dst so that a2 is return value
+	mov	a3, a2
+	mov	a2, a5
+	j	.Lcommon	# go to common code for memcpy+bcopy
+
+
+/*
+ * Byte by byte copy
+ */
+	.align	4
+	.byte	0		# 1 mod 4 alignment for LOOPNEZ
+				# (0 mod 4 alignment for LBEG)
+.Lbytecopy:
+#if XCHAL_HAVE_LOOPS
+	loopnez	a4, .Lbytecopydone
+#else /* !XCHAL_HAVE_LOOPS */
+	beqz	a4, .Lbytecopydone
+	add	a7, a3, a4	# a7 = end address for source
+#endif /* !XCHAL_HAVE_LOOPS */
+.Lnextbyte:
+	l8ui	a6, a3, 0
+	addi	a3, a3, 1
+	s8i	a6, a5, 0
+	addi	a5, a5, 1
+#if !XCHAL_HAVE_LOOPS
+	blt	a3, a7, .Lnextbyte
+#endif /* !XCHAL_HAVE_LOOPS */
+.Lbytecopydone:
+	retw
+
+/*
+ * Destination is unaligned
+ */
+
+	.align	4
+.Ldst1mod2:	# dst is only byte aligned
+	_bltui	a4, 7, .Lbytecopy	# do short copies byte by byte
+
+	# copy 1 byte
+	l8ui	a6, a3,  0
+	addi	a3, a3,  1
+	addi	a4, a4, -1
+	s8i	a6, a5,  0
+	addi	a5, a5,  1
+	_bbci.l	a5, 1, .Ldstaligned	# if dst is now aligned, then
+					# return to main algorithm
+.Ldst2mod4:	# dst 16-bit aligned
+	# copy 2 bytes
+	_bltui	a4, 6, .Lbytecopy	# do short copies byte by byte
+	l8ui	a6, a3,  0
+	l8ui	a7, a3,  1
+	addi	a3, a3,  2
+	addi	a4, a4, -2
+	s8i	a6, a5,  0
+	s8i	a7, a5,  1
+	addi	a5, a5,  2
+	j	.Ldstaligned	# dst is now aligned, return to main algorithm
+
+	.align	4
+	.global	memcpy
+	.type   memcpy,@function
+memcpy:
+	.global	memmove
+	.type   memmove,@function
+memmove:
+
+	entry	sp, 16		# minimal stack frame
+	# a2/ dst, a3/ src, a4/ len
+	mov	a5, a2		# copy dst so that a2 is return value
+.Lcommon:
+	_bbsi.l	a2, 0, .Ldst1mod2	# if dst is 1 mod 2
+	_bbsi.l	a2, 1, .Ldst2mod4	# if dst is 2 mod 4
+.Ldstaligned:	# return here from .Ldst?mod? once dst is aligned
+	srli	a7, a4, 4	# number of loop iterations with 16B
+				# per iteration
+	movi	a8, 3		# if source is not aligned,
+	_bany	a3, a8, .Lsrcunaligned	# then use shifting copy
+	/*
+	 * Destination and source are word-aligned, use word copy.
+	 */
+	# copy 16 bytes per iteration for word-aligned dst and word-aligned src
+#if XCHAL_HAVE_LOOPS
+	loopnez	a7, .Loop1done
+#else /* !XCHAL_HAVE_LOOPS */
+	beqz	a7, .Loop1done
+	slli	a8, a7, 4
+	add	a8, a8, a3	# a8 = end of last 16B source chunk
+#endif /* !XCHAL_HAVE_LOOPS */
+.Loop1:
+	l32i	a6, a3,  0
+	l32i	a7, a3,  4
+	s32i	a6, a5,  0
+	l32i	a6, a3,  8
+	s32i	a7, a5,  4
+	l32i	a7, a3, 12
+	s32i	a6, a5,  8
+	addi	a3, a3, 16
+	s32i	a7, a5, 12
+	addi	a5, a5, 16
+#if !XCHAL_HAVE_LOOPS
+	blt	a3, a8, .Loop1
+#endif /* !XCHAL_HAVE_LOOPS */
+.Loop1done:
+	bbci.l	a4, 3, .L2
+	# copy 8 bytes
+	l32i	a6, a3,  0
+	l32i	a7, a3,  4
+	addi	a3, a3,  8
+	s32i	a6, a5,  0
+	s32i	a7, a5,  4
+	addi	a5, a5,  8
+.L2:
+	bbsi.l	a4, 2, .L3
+	bbsi.l	a4, 1, .L4
+	bbsi.l	a4, 0, .L5
+	retw
+.L3:
+	# copy 4 bytes
+	l32i	a6, a3,  0
+	addi	a3, a3,  4
+	s32i	a6, a5,  0
+	addi	a5, a5,  4
+	bbsi.l	a4, 1, .L4
+	bbsi.l	a4, 0, .L5
+	retw
+.L4:
+	# copy 2 bytes
+	l16ui	a6, a3,  0
+	addi	a3, a3,  2
+	s16i	a6, a5,  0
+	addi	a5, a5,  2
+	bbsi.l	a4, 0, .L5
+	retw
+.L5:
+	# copy 1 byte
+	l8ui	a6, a3,  0
+	s8i	a6, a5,  0
+	retw
+
+/*
+ * Destination is aligned, Source is unaligned
+ */
+
+	.align	4
+.Lsrcunaligned:
+	_beqz	a4, .Ldone	# avoid loading anything for zero-length copies
+	# copy 16 bytes per iteration for word-aligned dst and unaligned src
+	ssa8	a3		# set shift amount from byte offset
+#define SIM_CHECKS_ALIGNMENT	1	/* set to 1 when running on ISS (simulator) with the
+					   lint or ferret client, or 0 to save a few cycles */
+#if XCHAL_UNALIGNED_LOAD_EXCEPTION || SIM_CHECKS_ALIGNMENT
+	and	a11, a3, a8	# save unalignment offset for below
+	sub	a3, a3, a11	# align a3
+#endif
+	l32i	a6, a3, 0	# load first word
+#if XCHAL_HAVE_LOOPS
+	loopnez	a7, .Loop2done
+#else /* !XCHAL_HAVE_LOOPS */
+	beqz	a7, .Loop2done
+	slli	a10, a7, 4
+	add	a10, a10, a3	# a10 = end of last 16B source chunk
+#endif /* !XCHAL_HAVE_LOOPS */
+.Loop2:
+	l32i	a7, a3,  4
+	l32i	a8, a3,  8
+	src_b	a6, a6, a7
+	s32i	a6, a5,  0
+	l32i	a9, a3, 12
+	src_b	a7, a7, a8
+	s32i	a7, a5,  4
+	l32i	a6, a3, 16
+	src_b	a8, a8, a9
+	s32i	a8, a5,  8
+	addi	a3, a3, 16
+	src_b	a9, a9, a6
+	s32i	a9, a5, 12
+	addi	a5, a5, 16
+#if !XCHAL_HAVE_LOOPS
+	blt	a3, a10, .Loop2
+#endif /* !XCHAL_HAVE_LOOPS */
+.Loop2done:
+	bbci.l	a4, 3, .L12
+	# copy 8 bytes
+	l32i	a7, a3,  4
+	l32i	a8, a3,  8
+	src_b	a6, a6, a7
+	s32i	a6, a5,  0
+	addi	a3, a3,  8
+	src_b	a7, a7, a8
+	s32i	a7, a5,  4
+	addi	a5, a5,  8
+	mov	a6, a8
+.L12:
+	bbci.l	a4, 2, .L13
+	# copy 4 bytes
+	l32i	a7, a3,  4
+	addi	a3, a3,  4
+	src_b	a6, a6, a7
+	s32i	a6, a5,  0
+	addi	a5, a5,  4
+	mov	a6, a7
+.L13:
+#if XCHAL_UNALIGNED_LOAD_EXCEPTION || SIM_CHECKS_ALIGNMENT
+	add	a3, a3, a11	# readjust a3 with correct misalignment
+#endif
+	bbsi.l	a4, 1, .L14
+	bbsi.l	a4, 0, .L15
+.Ldone:	retw
+.L14:
+	# copy 2 bytes
+	l8ui	a6, a3,  0
+	l8ui	a7, a3,  1
+	addi	a3, a3,  2
+	s8i	a6, a5,  0
+	s8i	a7, a5,  1
+	addi	a5, a5,  2
+	bbsi.l	a4, 0, .L15
+	retw
+.L15:
+	# copy 1 byte
+	l8ui	a6, a3,  0
+	s8i	a6, a5,  0
+	retw
+
+/*
+ * Local Variables:
+ * mode:fundamental
+ * comment-start: "# "
+ * comment-start-skip: "# *"
+ * End:
+ */
diff --git a/arch/xtensa/lib/memset.S b/arch/xtensa/lib/memset.S
new file mode 100644
--- /dev/null
+++ b/arch/xtensa/lib/memset.S
@@ -0,0 +1,160 @@
+/*
+ *  arch/xtensa/lib/memset.S
+ *
+ *  ANSI C standard library function memset
+ *  (Well, almost.  .fixup code might return zero.)
+ *
+ *  This file is subject to the terms and conditions of the GNU General
+ *  Public License.  See the file "COPYING" in the main directory of
+ *  this archive for more details.
+ *
+ *  Copyright (C) 2002 Tensilica Inc.
+ */
+
+#include <xtensa/coreasm.h>
+
+/*
+ * void *memset(void *dst, int c, size_t length)
+ *
+ * The algorithm is as follows:
+ *   Create a word with c in all byte positions
+ *   If the destination is aligned,
+ *     do 16B chucks with a loop, and then finish up with
+ *     8B, 4B, 2B, and 1B stores conditional on the length.
+ *   If destination is unaligned, align it by conditionally
+ *     setting 1B and 2B and then go to aligned case.
+ *   This code tries to use fall-through branches for the common
+ *     case of an aligned destination (except for the branches to
+ *     the alignment labels).
+ */
+
+/* Load or store instructions that may cause exceptions use the EX macro. */
+
+#define EX(insn,reg1,reg2,offset,handler)	\
+9:	insn	reg1, reg2, offset;		\
+	.section __ex_table, "a";		\
+	.word	9b, handler;			\
+	.previous
+
+
+.text
+.align	4
+.global	memset
+.type	memset,@function
+memset:
+	entry	sp, 16		# minimal stack frame
+	# a2/ dst, a3/ c, a4/ length
+	extui	a3, a3, 0, 8	# mask to just 8 bits
+	slli	a7, a3, 8	# duplicate character in all bytes of word
+	or	a3, a3, a7	# ...
+	slli	a7, a3, 16	# ...
+	or	a3, a3, a7	# ...
+	mov	a5, a2		# copy dst so that a2 is return value
+	movi	a6, 3		# for alignment tests
+	bany	a2, a6, .Ldstunaligned # if dst is unaligned
+.L0:	# return here from .Ldstunaligned when dst is aligned
+	srli	a7, a4, 4	# number of loop iterations with 16B
+				# per iteration
+	bnez	a4, .Laligned
+	retw
+
+/*
+ * Destination is word-aligned.
+ */
+	# set 16 bytes per iteration for word-aligned dst
+	.align	4		# 1 mod 4 alignment for LOOPNEZ
+	.byte	0		# (0 mod 4 alignment for LBEG)
+.Laligned:
+#if XCHAL_HAVE_LOOPS
+	loopnez	a7, .Loop1done
+#else /* !XCHAL_HAVE_LOOPS */
+	beqz	a7, .Loop1done
+	slli	a6, a7, 4
+	add	a6, a6, a5	# a6 = end of last 16B chunk
+#endif /* !XCHAL_HAVE_LOOPS */
+.Loop1:
+	EX(s32i, a3, a5,  0, memset_fixup)
+	EX(s32i, a3, a5,  4, memset_fixup)
+	EX(s32i, a3, a5,  8, memset_fixup)
+	EX(s32i, a3, a5, 12, memset_fixup)
+	addi	a5, a5, 16
+#if !XCHAL_HAVE_LOOPS
+	blt	a5, a6, .Loop1
+#endif /* !XCHAL_HAVE_LOOPS */
+.Loop1done:
+	bbci.l	a4, 3, .L2
+	# set 8 bytes
+	EX(s32i, a3, a5,  0, memset_fixup)
+	EX(s32i, a3, a5,  4, memset_fixup)
+	addi	a5, a5,  8
+.L2:
+	bbci.l	a4, 2, .L3
+	# set 4 bytes
+	EX(s32i, a3, a5,  0, memset_fixup)
+	addi	a5, a5,  4
+.L3:
+	bbci.l	a4, 1, .L4
+	# set 2 bytes
+	EX(s16i, a3, a5,  0, memset_fixup)
+	addi	a5, a5,  2
+.L4:
+	bbci.l	a4, 0, .L5
+	# set 1 byte
+	EX(s8i, a3, a5,  0, memset_fixup)
+.L5:
+.Lret1:
+	retw
+
+/*
+ * Destination is unaligned
+ */
+
+.Ldstunaligned:
+	bltui	a4, 8, .Lbyteset	# do short copies byte by byte
+	bbci.l	a5, 0, .L20		# branch if dst alignment half-aligned
+	# dst is only byte aligned
+	# set 1 byte
+	EX(s8i, a3, a5,  0, memset_fixup)
+	addi	a5, a5,  1
+	addi	a4, a4, -1
+	# now retest if dst aligned
+	bbci.l	a5, 1, .L0	# if now aligned, return to main algorithm
+.L20:
+	# dst half-aligned
+	# set 2 bytes
+	EX(s16i, a3, a5,  0, memset_fixup)
+	addi	a5, a5,  2
+	addi	a4, a4, -2
+	j	.L0		# dst is now aligned, return to main algorithm
+
+/*
+ * Byte by byte set
+ */
+	.align	4
+	.byte	0		# 1 mod 4 alignment for LOOPNEZ
+				# (0 mod 4 alignment for LBEG)
+.Lbyteset:
+#if XCHAL_HAVE_LOOPS
+	loopnez	a4, .Lbytesetdone
+#else /* !XCHAL_HAVE_LOOPS */
+	beqz	a4, .Lbytesetdone
+	add	a6, a5, a4	# a6 = ending address
+#endif /* !XCHAL_HAVE_LOOPS */
+.Lbyteloop:
+	EX(s8i, a3, a5, 0, memset_fixup)
+	addi	a5, a5, 1
+#if !XCHAL_HAVE_LOOPS
+	blt	a5, a6, .Lbyteloop
+#endif /* !XCHAL_HAVE_LOOPS */
+.Lbytesetdone:
+	retw
+
+
+	.section .fixup, "ax"
+	.align	4
+
+/* We return zero if a failure occurred. */
+
+memset_fixup:
+	movi	a2, 0
+	retw
diff --git a/arch/xtensa/lib/pci-auto.c b/arch/xtensa/lib/pci-auto.c
new file mode 100644
--- /dev/null
+++ b/arch/xtensa/lib/pci-auto.c
@@ -0,0 +1,352 @@
+/*
+ * arch/xtensa/kernel/pci-auto.c
+ *
+ * PCI autoconfiguration library
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ *
+ * Chris Zankel <zankel@tensilica.com, cez@zankel.net>
+ *
+ * Based on work from Matt Porter <mporter@mvista.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+
+#include <asm/pci-bridge.h>
+
+
+/*
+ *
+ * Setting up a PCI
+ *
+ * pci_ctrl->first_busno = <first bus number (0)>
+ * pci_ctrl->last_busno = <last bus number (0xff)>
+ * pci_ctrl->ops = <PCI config operations>
+ * pci_ctrl->map_irq = <function to return the interrupt number for a device>
+ *
+ * pci_ctrl->io_space.start = <IO space start address (PCI view)>
+ * pci_ctrl->io_space.end = <IO space end address (PCI view)>
+ * pci_ctrl->io_space.base = <IO space offset: address 0 from CPU space>
+ * pci_ctrl->mem_space.start = <MEM space start address (PCI view)>
+ * pci_ctrl->mem_space.end = <MEM space end address (PCI view)>
+ * pci_ctrl->mem_space.base = <MEM space offset: address 0 from CPU space>
+ *
+ * pcibios_init_resource(&pci_ctrl->io_resource, <IO space start>,
+ * 			 <IO space end>, IORESOURCE_IO, "PCI host bridge");
+ * pcibios_init_resource(&pci_ctrl->mem_resources[0], <MEM space start>,
+ * 			 <MEM space end>, IORESOURCE_MEM, "PCI host bridge");
+ *
+ * pci_ctrl->last_busno = pciauto_bus_scan(pci_ctrl,pci_ctrl->first_busno);
+ *
+ * int __init pciauto_bus_scan(struct pci_controller *pci_ctrl, int current_bus)
+ *
+ */
+
+
+/* define DEBUG to print some debugging messages. */
+
+#undef DEBUG
+
+#ifdef DEBUG
+# define DBG(x...) printk(x)
+#else
+# define DBG(x...)
+#endif
+
+static int pciauto_upper_iospc;
+static int pciauto_upper_memspc;
+
+static struct pci_dev pciauto_dev;
+static struct pci_bus pciauto_bus;
+
+/*
+ * Helper functions
+ */
+
+/* Initialize the bars of a PCI device.  */
+
+static void __init
+pciauto_setup_bars(struct pci_dev *dev, int bar_limit)
+{
+	int bar_size;
+	int bar, bar_nr;
+	int *upper_limit;
+	int found_mem64 = 0;
+
+	for (bar = PCI_BASE_ADDRESS_0, bar_nr = 0;
+	     bar <= bar_limit;
+	     bar+=4, bar_nr++)
+	{
+		/* Tickle the BAR and get the size */
+		pci_write_config_dword(dev, bar, 0xffffffff);
+		pci_read_config_dword(dev, bar, &bar_size);
+
+		/* If BAR is not implemented go to the next BAR */
+		if (!bar_size)
+			continue;
+
+		/* Check the BAR type and set our address mask */
+		if (bar_size & PCI_BASE_ADDRESS_SPACE_IO)
+		{
+			bar_size &= PCI_BASE_ADDRESS_IO_MASK;
+			upper_limit = &pciauto_upper_iospc;
+			DBG("PCI Autoconfig: BAR %d, I/O, ", bar_nr);
+		}
+		else
+		{
+			if ((bar_size & PCI_BASE_ADDRESS_MEM_TYPE_MASK) ==
+			    PCI_BASE_ADDRESS_MEM_TYPE_64)
+				found_mem64 = 1;
+
+			bar_size &= PCI_BASE_ADDRESS_MEM_MASK;
+			upper_limit = &pciauto_upper_memspc;
+			DBG("PCI Autoconfig: BAR %d, Mem, ", bar_nr);
+		}
+
+		/* Allocate a base address (bar_size is negative!) */
+		*upper_limit = (*upper_limit + bar_size) & bar_size;
+
+		/* Write it out and update our limit */
+		pci_write_config_dword(dev, bar, *upper_limit);
+
+		/*
+		 * If we are a 64-bit decoder then increment to the
+		 * upper 32 bits of the bar and force it to locate
+		 * in the lower 4GB of memory.
+		 */
+
+		if (found_mem64)
+			pci_write_config_dword(dev, (bar+=4), 0x00000000);
+
+		DBG("size=0x%x, address=0x%x\n", ~bar_size + 1, *upper_limit);
+	}
+}
+
+/* Initialize the interrupt number. */
+
+static void __init
+pciauto_setup_irq(struct pci_controller* pci_ctrl,struct pci_dev *dev,int devfn)
+{
+	u8 pin;
+	int irq = 0;
+
+	pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
+
+	/* Fix illegal pin numbers. */
+
+	if (pin == 0 || pin > 4)
+		pin = 1;
+
+	if (pci_ctrl->map_irq)
+		irq = pci_ctrl->map_irq(dev, PCI_SLOT(devfn), pin);
+
+	if (irq == -1)
+		irq = 0;
+
+	DBG("PCI Autoconfig: Interrupt %d, pin %d\n", irq, pin);
+
+	pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
+}
+
+
+static void __init
+pciauto_prescan_setup_bridge(struct pci_dev *dev, int current_bus,
+			     int sub_bus, int *iosave, int *memsave)
+{
+	/* Configure bus number registers */
+	pci_write_config_byte(dev, PCI_PRIMARY_BUS, current_bus);
+	pci_write_config_byte(dev, PCI_SECONDARY_BUS, sub_bus + 1);
+	pci_write_config_byte(dev, PCI_SUBORDINATE_BUS,	0xff);
+
+	/* Round memory allocator to 1MB boundary */
+	pciauto_upper_memspc &= ~(0x100000 - 1);
+	*memsave = pciauto_upper_memspc;
+
+	/* Round I/O allocator to 4KB boundary */
+	pciauto_upper_iospc &= ~(0x1000 - 1);
+	*iosave = pciauto_upper_iospc;
+
+	/* Set up memory and I/O filter limits, assume 32-bit I/O space */
+	pci_write_config_word(dev, PCI_MEMORY_LIMIT,
+			      ((pciauto_upper_memspc - 1) & 0xfff00000) >> 16);
+	pci_write_config_byte(dev, PCI_IO_LIMIT,
+			      ((pciauto_upper_iospc - 1) & 0x0000f000) >> 8);
+	pci_write_config_word(dev, PCI_IO_LIMIT_UPPER16,
+			      ((pciauto_upper_iospc - 1) & 0xffff0000) >> 16);
+}
+
+static void __init
+pciauto_postscan_setup_bridge(struct pci_dev *dev, int current_bus, int sub_bus,
+			      int *iosave, int *memsave)
+{
+	int cmdstat;
+
+	/* Configure bus number registers */
+	pci_write_config_byte(dev, PCI_SUBORDINATE_BUS,	sub_bus);
+
+	/*
+	 * Round memory allocator to 1MB boundary.
+	 * If no space used, allocate minimum.
+	 */
+	pciauto_upper_memspc &= ~(0x100000 - 1);
+	if (*memsave == pciauto_upper_memspc)
+		pciauto_upper_memspc -= 0x00100000;
+
+	pci_write_config_word(dev, PCI_MEMORY_BASE, pciauto_upper_memspc >> 16);
+
+	/* Allocate 1MB for pre-fretch */
+	pci_write_config_word(dev, PCI_PREF_MEMORY_LIMIT,
+			      ((pciauto_upper_memspc - 1) & 0xfff00000) >> 16);
+
+	pciauto_upper_memspc -= 0x100000;
+
+	pci_write_config_word(dev, PCI_PREF_MEMORY_BASE,
+			      pciauto_upper_memspc >> 16);
+
+	/* Round I/O allocator to 4KB boundary */
+	pciauto_upper_iospc &= ~(0x1000 - 1);
+	if (*iosave == pciauto_upper_iospc)
+		pciauto_upper_iospc -= 0x1000;
+
+	pci_write_config_byte(dev, PCI_IO_BASE,
+			      (pciauto_upper_iospc & 0x0000f000) >> 8);
+	pci_write_config_word(dev, PCI_IO_BASE_UPPER16,
+			      pciauto_upper_iospc >> 16);
+
+	/* Enable memory and I/O accesses, enable bus master */
+	pci_read_config_dword(dev, PCI_COMMAND, &cmdstat);
+	pci_write_config_dword(dev, PCI_COMMAND,
+			       cmdstat |
+			       PCI_COMMAND_IO |
+			       PCI_COMMAND_MEMORY |
+			       PCI_COMMAND_MASTER);
+}
+
+/*
+ * Scan the current PCI bus.
+ */
+
+
+int __init pciauto_bus_scan(struct pci_controller *pci_ctrl, int current_bus)
+{
+	int sub_bus, pci_devfn, pci_class, cmdstat, found_multi=0;
+	unsigned short vid;
+	unsigned char header_type;
+	struct pci_dev *dev = &pciauto_dev;
+
+        pciauto_dev.bus = &pciauto_bus;
+        pciauto_dev.sysdata = pci_ctrl;
+	pciauto_bus.ops = pci_ctrl->ops;
+
+	/*
+	 * Fetch our I/O and memory space upper boundaries used
+	 * to allocated base addresses on this pci_controller.
+	 */
+
+	if (current_bus == pci_ctrl->first_busno)
+	{
+		pciauto_upper_iospc = pci_ctrl->io_resource.end + 1;
+		pciauto_upper_memspc = pci_ctrl->mem_resources[0].end + 1;
+	}
+
+	sub_bus = current_bus;
+
+	for (pci_devfn = 0; pci_devfn < 0xff; pci_devfn++)
+	{
+		/* Skip our host bridge */
+		if ((current_bus == pci_ctrl->first_busno) && (pci_devfn == 0))
+			continue;
+
+		if (PCI_FUNC(pci_devfn) && !found_multi)
+			continue;
+
+		pciauto_bus.number = current_bus;
+		pciauto_dev.devfn = pci_devfn;
+
+		/* If config space read fails from this device, move on */
+		if (pci_read_config_byte(dev, PCI_HEADER_TYPE, &header_type))
+			continue;
+
+		if (!PCI_FUNC(pci_devfn))
+			found_multi = header_type & 0x80;
+		pci_read_config_word(dev, PCI_VENDOR_ID, &vid);
+
+		if (vid == 0xffff || vid == 0x0000) {
+			found_multi = 0;
+			continue;
+		}
+
+		pci_read_config_dword(dev, PCI_CLASS_REVISION, &pci_class);
+
+		if ((pci_class >> 16) == PCI_CLASS_BRIDGE_PCI) {
+
+			int iosave, memsave;
+
+			DBG("PCI Autoconfig: Found P2P bridge, device %d\n",
+			    PCI_SLOT(pci_devfn));
+
+			/* Allocate PCI I/O and/or memory space */
+			pciauto_setup_bars(dev, PCI_BASE_ADDRESS_1);
+
+			pciauto_prescan_setup_bridge(dev, current_bus, sub_bus,
+					&iosave, &memsave);
+			sub_bus = pciauto_bus_scan(pci_ctrl, sub_bus+1);
+			pciauto_postscan_setup_bridge(dev, current_bus, sub_bus,
+					&iosave, &memsave);
+			pciauto_bus.number = current_bus;
+
+			continue;
+
+		}
+
+
+#if 0
+		/* Skip legacy mode IDE controller */
+
+		if ((pci_class >> 16) == PCI_CLASS_STORAGE_IDE) {
+
+			unsigned char prg_iface;
+			pci_read_config_byte(dev, PCI_CLASS_PROG, &prg_iface);
+
+			if (!(prg_iface & PCIAUTO_IDE_MODE_MASK)) {
+				DBG("PCI Autoconfig: Skipping legacy mode "
+				    "IDE controller\n");
+				continue;
+			}
+		}
+#endif
+
+		/*
+		 * Found a peripheral, enable some standard
+		 * settings
+		 */
+
+		pci_read_config_dword(dev, PCI_COMMAND,	&cmdstat);
+		pci_write_config_dword(dev, PCI_COMMAND,
+				cmdstat |
+					PCI_COMMAND_IO |
+					PCI_COMMAND_MEMORY |
+					PCI_COMMAND_MASTER);
+		pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x80);
+
+		/* Allocate PCI I/O and/or memory space */
+		DBG("PCI Autoconfig: Found Bus %d, Device %d, Function %d\n",
+		    current_bus, PCI_SLOT(pci_devfn), PCI_FUNC(pci_devfn) );
+
+		pciauto_setup_bars(dev, PCI_BASE_ADDRESS_5);
+		pciauto_setup_irq(pci_ctrl, dev, pci_devfn);
+	}
+	return sub_bus;
+}
+
+
+
+
+
diff --git a/arch/xtensa/lib/strcasecmp.c b/arch/xtensa/lib/strcasecmp.c
new file mode 100644
--- /dev/null
+++ b/arch/xtensa/lib/strcasecmp.c
@@ -0,0 +1,32 @@
+/*
+ *  linux/arch/xtensa/lib/strcasecmp.c
+ *
+ *  This file is subject to the terms and conditions of the GNU General
+ *  Public License.  See the file "COPYING" in the main directory of
+ *  this archive for more details.
+ *
+ *  Copyright (C) 2002 Tensilica Inc.
+ */
+
+#include <linux/string.h>
+
+
+/* We handle nothing here except the C locale.  Since this is used in
+   only one place, on strings known to contain only 7 bit ASCII, this
+   is ok.  */
+
+int strcasecmp(const char *a, const char *b)
+{
+	int ca, cb;
+
+	do {
+		ca = *a++ & 0xff;
+		cb = *b++ & 0xff;
+		if (ca >= 'A' && ca <= 'Z')
+			ca += 'a' - 'A';
+		if (cb >= 'A' && cb <= 'Z')
+			cb += 'a' - 'A';
+	} while (ca == cb && ca != '\0');
+
+	return ca - cb;
+}
diff --git a/arch/xtensa/lib/strncpy_user.S b/arch/xtensa/lib/strncpy_user.S
new file mode 100644
--- /dev/null
+++ b/arch/xtensa/lib/strncpy_user.S
@@ -0,0 +1,224 @@
+/*
+ *  arch/xtensa/lib/strncpy_user.S
+ *
+ *  This file is subject to the terms and conditions of the GNU General
+ *  Public License.  See the file "COPYING" in the main directory of
+ *  this archive for more details.
+ *
+ *  Returns: -EFAULT if exception before terminator, N if the entire
+ *  buffer filled, else strlen.
+ *
+ *  Copyright (C) 2002 Tensilica Inc.
+ */
+
+#include <xtensa/coreasm.h>
+#include <linux/errno.h>
+
+/* Load or store instructions that may cause exceptions use the EX macro. */
+
+#define EX(insn,reg1,reg2,offset,handler)	\
+9:	insn	reg1, reg2, offset;		\
+	.section __ex_table, "a";		\
+	.word	9b, handler;			\
+	.previous
+
+/*
+ * char *__strncpy_user(char *dst, const char *src, size_t len)
+ */
+.text
+.begin literal
+.align	4
+.Lmask0:
+	.byte	0xff, 0x00, 0x00, 0x00
+.Lmask1:
+	.byte	0x00, 0xff, 0x00, 0x00
+.Lmask2:
+	.byte	0x00, 0x00, 0xff, 0x00
+.Lmask3:
+	.byte	0x00, 0x00, 0x00, 0xff
+.end literal
+
+# Register use
+#   a0/ return address
+#   a1/ stack pointer
+#   a2/ return value
+#   a3/ src
+#   a4/ len
+#   a5/ mask0
+#   a6/ mask1
+#   a7/ mask2
+#   a8/ mask3
+#   a9/ tmp
+#   a10/ tmp
+#   a11/ dst
+#   a12/ tmp
+
+.align	4
+.global	__strncpy_user
+.type	__strncpy_user,@function
+__strncpy_user:
+	entry	sp, 16		# minimal stack frame
+	# a2/ dst, a3/ src, a4/ len
+	mov	a11, a2		# leave dst in return value register
+	beqz	a4, .Lret	# if len is zero
+	l32r	a5, .Lmask0	# mask for byte 0
+	l32r	a6, .Lmask1	# mask for byte 1
+	l32r	a7, .Lmask2	# mask for byte 2
+	l32r	a8, .Lmask3	# mask for byte 3
+	bbsi.l	a3, 0, .Lsrc1mod2 # if only  8-bit aligned
+	bbsi.l	a3, 1, .Lsrc2mod4 # if only 16-bit aligned
+.Lsrcaligned:	# return here when src is word-aligned
+	srli	a12, a4, 2	# number of loop iterations with 4B per loop
+	movi	a9, 3
+	bnone	a11, a9, .Laligned
+	j	.Ldstunaligned
+
+.Lsrc1mod2:	# src address is odd
+	EX(l8ui, a9, a3, 0, fixup_l)	# get byte 0
+	addi	a3, a3, 1		# advance src pointer
+	EX(s8i, a9, a11, 0, fixup_s)	# store byte 0
+	beqz	a9, .Lret		# if byte 0 is zero
+	addi	a11, a11, 1		# advance dst pointer
+	addi	a4, a4, -1		# decrement len
+	beqz	a4, .Lret		# if len is zero
+	bbci.l	a3, 1, .Lsrcaligned	# if src is now word-aligned
+
+.Lsrc2mod4:	# src address is 2 mod 4
+	EX(l8ui, a9, a3, 0, fixup_l)	# get byte 0
+	/* 1-cycle interlock */
+	EX(s8i, a9, a11, 0, fixup_s)	# store byte 0
+	beqz	a9, .Lret		# if byte 0 is zero
+	addi	a11, a11, 1		# advance dst pointer
+	addi	a4, a4, -1		# decrement len
+	beqz	a4, .Lret		# if len is zero
+	EX(l8ui, a9, a3, 1, fixup_l)	# get byte 0
+	addi	a3, a3, 2		# advance src pointer
+	EX(s8i, a9, a11, 0, fixup_s)	# store byte 0
+	beqz	a9, .Lret		# if byte 0 is zero
+	addi	a11, a11, 1		# advance dst pointer
+	addi	a4, a4, -1		# decrement len
+	bnez	a4, .Lsrcaligned	# if len is nonzero
+.Lret:
+	sub	a2, a11, a2		# compute strlen
+	retw
+
+/*
+ * dst is word-aligned, src is word-aligned
+ */
+	.align	4		# 1 mod 4 alignment for LOOPNEZ
+	.byte	0		# (0 mod 4 alignment for LBEG)
+.Laligned:
+#if XCHAL_HAVE_LOOPS
+	loopnez	a12, .Loop1done
+#else
+	beqz	a12, .Loop1done
+	slli	a12, a12, 2
+	add	a12, a12, a11	# a12 = end of last 4B chunck
+#endif
+.Loop1:
+	EX(l32i, a9, a3, 0, fixup_l)	# get word from src
+	addi	a3, a3, 4		# advance src pointer
+	bnone	a9, a5, .Lz0		# if byte 0 is zero
+	bnone	a9, a6, .Lz1		# if byte 1 is zero
+	bnone	a9, a7, .Lz2		# if byte 2 is zero
+	EX(s32i, a9, a11, 0, fixup_s)	# store word to dst
+	bnone	a9, a8, .Lz3		# if byte 3 is zero
+	addi	a11, a11, 4		# advance dst pointer
+#if !XCHAL_HAVE_LOOPS
+	blt	a11, a12, .Loop1
+#endif
+
+.Loop1done:
+	bbci.l	a4, 1, .L100
+	# copy 2 bytes
+	EX(l16ui, a9, a3, 0, fixup_l)
+	addi	a3, a3, 2		# advance src pointer
+#ifdef __XTENSA_EB__
+	bnone	a9, a7, .Lz0		# if byte 2 is zero
+	bnone	a9, a8, .Lz1		# if byte 3 is zero
+#else
+	bnone	a9, a5, .Lz0		# if byte 0 is zero
+	bnone	a9, a6, .Lz1		# if byte 1 is zero
+#endif
+	EX(s16i, a9, a11, 0, fixup_s)
+	addi	a11, a11, 2		# advance dst pointer
+.L100:
+	bbci.l	a4, 0, .Lret
+	EX(l8ui, a9, a3, 0, fixup_l)
+	/* slot */
+	EX(s8i, a9, a11, 0, fixup_s)
+	beqz	a9, .Lret		# if byte is zero
+	addi	a11, a11, 1-3		# advance dst ptr 1, but also cancel
+					# the effect of adding 3 in .Lz3 code
+	/* fall thru to .Lz3 and "retw" */
+
+.Lz3:	# byte 3 is zero
+	addi	a11, a11, 3		# advance dst pointer
+	sub	a2, a11, a2		# compute strlen
+	retw
+.Lz0:	# byte 0 is zero
+#ifdef __XTENSA_EB__
+	movi	a9, 0
+#endif /* __XTENSA_EB__ */
+	EX(s8i, a9, a11, 0, fixup_s)
+	sub	a2, a11, a2		# compute strlen
+	retw
+.Lz1:	# byte 1 is zero
+#ifdef __XTENSA_EB__
+        extui   a9, a9, 16, 16
+#endif /* __XTENSA_EB__ */
+	EX(s16i, a9, a11, 0, fixup_s)
+	addi	a11, a11, 1		# advance dst pointer
+	sub	a2, a11, a2		# compute strlen
+	retw
+.Lz2:	# byte 2 is zero
+#ifdef __XTENSA_EB__
+        extui   a9, a9, 16, 16
+#endif /* __XTENSA_EB__ */
+	EX(s16i, a9, a11, 0, fixup_s)
+	movi	a9, 0
+	EX(s8i, a9, a11, 2, fixup_s)
+	addi	a11, a11, 2		# advance dst pointer
+	sub	a2, a11, a2		# compute strlen
+	retw
+
+	.align	4		# 1 mod 4 alignment for LOOPNEZ
+	.byte	0		# (0 mod 4 alignment for LBEG)
+.Ldstunaligned:
+/*
+ * for now just use byte copy loop
+ */
+#if XCHAL_HAVE_LOOPS
+	loopnez	a4, .Lunalignedend
+#else
+	beqz	a4, .Lunalignedend
+	add	a12, a11, a4		# a12 = ending address
+#endif /* XCHAL_HAVE_LOOPS */
+.Lnextbyte:
+	EX(l8ui, a9, a3, 0, fixup_l)
+	addi	a3, a3, 1
+	EX(s8i, a9, a11, 0, fixup_s)
+	beqz	a9, .Lunalignedend
+	addi	a11, a11, 1
+#if !XCHAL_HAVE_LOOPS
+	blt	a11, a12, .Lnextbyte
+#endif
+
+.Lunalignedend:
+	sub	a2, a11, a2		# compute strlen
+	retw
+
+
+	.section .fixup, "ax"
+	.align	4
+
+	/* For now, just return -EFAULT.  Future implementations might
+	 * like to clear remaining kernel space, like the fixup
+	 * implementation in memset().  Thus, we differentiate between
+	 * load/store fixups. */
+
+fixup_s:
+fixup_l:
+	movi	a2, -EFAULT
+	retw
+
diff --git a/arch/xtensa/lib/strnlen_user.S b/arch/xtensa/lib/strnlen_user.S
new file mode 100644
--- /dev/null
+++ b/arch/xtensa/lib/strnlen_user.S
@@ -0,0 +1,147 @@
+/*
+ *  arch/xtensa/lib/strnlen_user.S
+ *
+ *  This file is subject to the terms and conditions of the GNU General
+ *  Public License.  See the file "COPYING" in the main directory of
+ *  this archive for more details.
+ *
+ *  Returns strnlen, including trailing zero terminator.
+ *  Zero indicates error.
+ *
+ *  Copyright (C) 2002 Tensilica Inc.
+ */
+
+#include <xtensa/coreasm.h>
+
+/* Load or store instructions that may cause exceptions use the EX macro. */
+
+#define EX(insn,reg1,reg2,offset,handler)	\
+9:	insn	reg1, reg2, offset;		\
+	.section __ex_table, "a";		\
+	.word	9b, handler;			\
+	.previous
+
+/*
+ * size_t __strnlen_user(const char *s, size_t len)
+ */
+.text
+.begin literal
+.align	4
+.Lmask0:
+	.byte	0xff, 0x00, 0x00, 0x00
+.Lmask1:
+	.byte	0x00, 0xff, 0x00, 0x00
+.Lmask2:
+	.byte	0x00, 0x00, 0xff, 0x00
+.Lmask3:
+	.byte	0x00, 0x00, 0x00, 0xff
+.end literal
+
+# Register use:
+#   a2/ src
+#   a3/ len
+#   a4/ tmp
+#   a5/ mask0
+#   a6/ mask1
+#   a7/ mask2
+#   a8/ mask3
+#   a9/ tmp
+#   a10/ tmp
+
+.align	4
+.global	__strnlen_user
+.type	__strnlen_user,@function
+__strnlen_user:
+	entry	sp, 16		# minimal stack frame
+	# a2/ s, a3/ len
+	addi	a4, a2, -4	# because we overincrement at the end;
+				# we compensate with load offsets of 4
+	l32r	a5, .Lmask0	# mask for byte 0
+	l32r	a6, .Lmask1	# mask for byte 1
+	l32r	a7, .Lmask2	# mask for byte 2
+	l32r	a8, .Lmask3	# mask for byte 3
+	bbsi.l	a2, 0, .L1mod2	# if only  8-bit aligned
+	bbsi.l	a2, 1, .L2mod4	# if only 16-bit aligned
+
+/*
+ * String is word-aligned.
+ */
+.Laligned:
+	srli	a10, a3, 2	# number of loop iterations with 4B per loop
+#if XCHAL_HAVE_LOOPS
+	loopnez	a10, .Ldone
+#else
+	beqz	a10, .Ldone
+	slli	a10, a10, 2
+	add	a10, a10, a4	# a10 = end of last 4B chunk
+#endif /* XCHAL_HAVE_LOOPS */
+.Loop:
+	EX(l32i, a9, a4, 4, lenfixup)	# get next word of string
+	addi	a4, a4, 4		# advance string pointer
+	bnone	a9, a5, .Lz0		# if byte 0 is zero
+	bnone	a9, a6, .Lz1		# if byte 1 is zero
+	bnone	a9, a7, .Lz2		# if byte 2 is zero
+	bnone	a9, a8, .Lz3		# if byte 3 is zero
+#if !XCHAL_HAVE_LOOPS
+	blt	a4, a10, .Loop
+#endif
+
+.Ldone:
+	EX(l32i, a9, a4, 4, lenfixup)	# load 4 bytes for remaining checks
+
+	bbci.l	a3, 1, .L100
+	# check two more bytes (bytes 0, 1 of word)
+	addi	a4, a4, 2	# advance string pointer
+	bnone	a9, a5, .Lz0	# if byte 0 is zero
+	bnone	a9, a6, .Lz1	# if byte 1 is zero
+.L100:
+	bbci.l	a3, 0, .L101
+	# check one more byte (byte 2 of word)
+	# Actually, we don't need to check.  Zero or nonzero, we'll add one.
+	# Do not add an extra one for the NULL terminator since we have
+	#  exhausted the original len parameter.
+	addi	a4, a4, 1	# advance string pointer
+.L101:
+	sub	a2, a4, a2	# compute length
+	retw
+
+# NOTE that in several places below, we point to the byte just after
+# the zero byte in order to include the NULL terminator in the count.
+
+.Lz3:	# byte 3 is zero
+	addi	a4, a4, 3	# point to zero byte
+.Lz0:	# byte 0 is zero
+	addi	a4, a4, 1	# point just beyond zero byte
+	sub	a2, a4, a2	# subtract to get length
+	retw
+.Lz1:	# byte 1 is zero
+	addi	a4, a4, 1+1	# point just beyond zero byte
+	sub	a2, a4, a2	# subtract to get length
+	retw
+.Lz2:	# byte 2 is zero
+	addi	a4, a4, 2+1	# point just beyond zero byte
+	sub	a2, a4, a2	# subtract to get length
+	retw
+
+.L1mod2:	# address is odd
+	EX(l8ui, a9, a4, 4, lenfixup)	# get byte 0
+	addi	a4, a4, 1		# advance string pointer
+	beqz	a9, .Lz3		# if byte 0 is zero
+	bbci.l	a4, 1, .Laligned	# if string pointer is now word-aligned
+
+.L2mod4:	# address is 2 mod 4
+	addi	a4, a4, 2	# advance ptr for aligned access
+	EX(l32i, a9, a4, 0, lenfixup)	# get word with first two bytes of string
+	bnone	a9, a7, .Lz2	# if byte 2 (of word, not string) is zero
+	bany	a9, a8, .Laligned # if byte 3 (of word, not string) is nonzero
+	# byte 3 is zero
+	addi	a4, a4, 3+1	# point just beyond zero byte
+	sub	a2, a4, a2	# subtract to get length
+	retw
+
+	.section .fixup, "ax"
+	.align	4
+lenfixup:
+	movi	a2, 0
+	retw
+
diff --git a/arch/xtensa/lib/usercopy.S b/arch/xtensa/lib/usercopy.S
new file mode 100644
--- /dev/null
+++ b/arch/xtensa/lib/usercopy.S
@@ -0,0 +1,321 @@
+/*
+ *  arch/xtensa/lib/usercopy.S
+ *
+ *  Copy to/from user space (derived from arch/xtensa/lib/hal/memcopy.S)
+ *
+ *  DO NOT COMBINE this function with <arch/xtensa/lib/hal/memcopy.S>.
+ *  It needs to remain separate and distinct.  The hal files are part
+ *  of the the Xtensa link-time HAL, and those files may differ per
+ *  processor configuration.  Patching the kernel for another
+ *  processor configuration includes replacing the hal files, and we
+ *  could loose the special functionality for accessing user-space
+ *  memory during such a patch.  We sacrifice a little code space here
+ *  in favor to simplify code maintenance.
+ *
+ *  This file is subject to the terms and conditions of the GNU General
+ *  Public License.  See the file "COPYING" in the main directory of
+ *  this archive for more details.
+ *
+ *  Copyright (C) 2002 Tensilica Inc.
+ */
+
+
+/*
+ * size_t __xtensa_copy_user (void *dst, const void *src, size_t len);
+ *
+ * The returned value is the number of bytes not copied.  Implies zero
+ * is success.
+ *
+ * The general case algorithm is as follows:
+ *   If the destination and source are both aligned,
+ *     do 16B chunks with a loop, and then finish up with
+ *     8B, 4B, 2B, and 1B copies conditional on the length.
+ *   If destination is aligned and source unaligned,
+ *     do the same, but use SRC to align the source data.
+ *   If destination is unaligned, align it by conditionally
+ *     copying 1B and 2B and then retest.
+ *   This code tries to use fall-through braches for the common
+ *     case of aligned destinations (except for the branches to
+ *     the alignment label).
+ *
+ * Register use:
+ *	a0/ return address
+ *	a1/ stack pointer
+ *	a2/ return value
+ *	a3/ src
+ *	a4/ length
+ *	a5/ dst
+ *	a6/ tmp
+ *	a7/ tmp
+ *	a8/ tmp
+ *	a9/ tmp
+ *	a10/ tmp
+ *	a11/ original length
+ */
+
+#include <xtensa/coreasm.h>
+
+#ifdef __XTENSA_EB__
+#define ALIGN(R, W0, W1) src	R, W0, W1
+#define SSA8(R)	ssa8b R
+#else
+#define ALIGN(R, W0, W1) src	R, W1, W0
+#define SSA8(R)	ssa8l R
+#endif
+
+/* Load or store instructions that may cause exceptions use the EX macro. */
+
+#define EX(insn,reg1,reg2,offset,handler)	\
+9:	insn	reg1, reg2, offset;		\
+	.section __ex_table, "a";		\
+	.word	9b, handler;			\
+	.previous
+
+
+	.text
+	.align	4
+	.global	__xtensa_copy_user
+	.type	__xtensa_copy_user,@function
+__xtensa_copy_user:
+	entry	sp, 16		# minimal stack frame
+	# a2/ dst, a3/ src, a4/ len
+	mov	a5, a2		# copy dst so that a2 is return value
+	mov	a11, a4		# preserve original len for error case
+.Lcommon:
+	bbsi.l	a2, 0, .Ldst1mod2 # if dst is 1 mod 2
+	bbsi.l	a2, 1, .Ldst2mod4 # if dst is 2 mod 4
+.Ldstaligned:	# return here from .Ldstunaligned when dst is aligned
+	srli	a7, a4, 4	# number of loop iterations with 16B
+				# per iteration
+	movi	a8, 3		  # if source is also aligned,
+	bnone	a3, a8, .Laligned # then use word copy
+	SSA8(	a3)		# set shift amount from byte offset
+	bnez	a4, .Lsrcunaligned
+	movi	a2, 0		# return success for len==0
+	retw
+
+/*
+ * Destination is unaligned
+ */
+
+.Ldst1mod2:	# dst is only byte aligned
+	bltui	a4, 7, .Lbytecopy	# do short copies byte by byte
+
+	# copy 1 byte
+	EX(l8ui, a6, a3, 0, l_fixup)
+	addi	a3, a3,  1
+	EX(s8i, a6, a5,  0, s_fixup)
+	addi	a5, a5,  1
+	addi	a4, a4, -1
+	bbci.l	a5, 1, .Ldstaligned	# if dst is now aligned, then
+					# return to main algorithm
+.Ldst2mod4:	# dst 16-bit aligned
+	# copy 2 bytes
+	bltui	a4, 6, .Lbytecopy	# do short copies byte by byte
+	EX(l8ui, a6, a3, 0, l_fixup)
+	EX(l8ui, a7, a3, 1, l_fixup)
+	addi	a3, a3,  2
+	EX(s8i, a6, a5,  0, s_fixup)
+	EX(s8i, a7, a5,  1, s_fixup)
+	addi	a5, a5,  2
+	addi	a4, a4, -2
+	j	.Ldstaligned	# dst is now aligned, return to main algorithm
+
+/*
+ * Byte by byte copy
+ */
+	.align	4
+	.byte	0		# 1 mod 4 alignment for LOOPNEZ
+				# (0 mod 4 alignment for LBEG)
+.Lbytecopy:
+#if XCHAL_HAVE_LOOPS
+	loopnez	a4, .Lbytecopydone
+#else /* !XCHAL_HAVE_LOOPS */
+	beqz	a4, .Lbytecopydone
+	add	a7, a3, a4	# a7 = end address for source
+#endif /* !XCHAL_HAVE_LOOPS */
+.Lnextbyte:
+	EX(l8ui, a6, a3, 0, l_fixup)
+	addi	a3, a3, 1
+	EX(s8i, a6, a5, 0, s_fixup)
+	addi	a5, a5, 1
+#if !XCHAL_HAVE_LOOPS
+	blt	a3, a7, .Lnextbyte
+#endif /* !XCHAL_HAVE_LOOPS */
+.Lbytecopydone:
+	movi	a2, 0		# return success for len bytes copied
+	retw
+
+/*
+ * Destination and source are word-aligned.
+ */
+	# copy 16 bytes per iteration for word-aligned dst and word-aligned src
+	.align	4		# 1 mod 4 alignment for LOOPNEZ
+	.byte	0		# (0 mod 4 alignment for LBEG)
+.Laligned:
+#if XCHAL_HAVE_LOOPS
+	loopnez	a7, .Loop1done
+#else /* !XCHAL_HAVE_LOOPS */
+	beqz	a7, .Loop1done
+	slli	a8, a7, 4
+	add	a8, a8, a3	# a8 = end of last 16B source chunk
+#endif /* !XCHAL_HAVE_LOOPS */
+.Loop1:
+	EX(l32i, a6, a3,  0, l_fixup)
+	EX(l32i, a7, a3,  4, l_fixup)
+	EX(s32i, a6, a5,  0, s_fixup)
+	EX(l32i, a6, a3,  8, l_fixup)
+	EX(s32i, a7, a5,  4, s_fixup)
+	EX(l32i, a7, a3, 12, l_fixup)
+	EX(s32i, a6, a5,  8, s_fixup)
+	addi	a3, a3, 16
+	EX(s32i, a7, a5, 12, s_fixup)
+	addi	a5, a5, 16
+#if !XCHAL_HAVE_LOOPS
+	blt	a3, a8, .Loop1
+#endif /* !XCHAL_HAVE_LOOPS */
+.Loop1done:
+	bbci.l	a4, 3, .L2
+	# copy 8 bytes
+	EX(l32i, a6, a3,  0, l_fixup)
+	EX(l32i, a7, a3,  4, l_fixup)
+	addi	a3, a3,  8
+	EX(s32i, a6, a5,  0, s_fixup)
+	EX(s32i, a7, a5,  4, s_fixup)
+	addi	a5, a5,  8
+.L2:
+	bbci.l	a4, 2, .L3
+	# copy 4 bytes
+	EX(l32i, a6, a3,  0, l_fixup)
+	addi	a3, a3,  4
+	EX(s32i, a6, a5,  0, s_fixup)
+	addi	a5, a5,  4
+.L3:
+	bbci.l	a4, 1, .L4
+	# copy 2 bytes
+	EX(l16ui, a6, a3,  0, l_fixup)
+	addi	a3, a3,  2
+	EX(s16i,  a6, a5,  0, s_fixup)
+	addi	a5, a5,  2
+.L4:
+	bbci.l	a4, 0, .L5
+	# copy 1 byte
+	EX(l8ui, a6, a3,  0, l_fixup)
+	EX(s8i,  a6, a5,  0, s_fixup)
+.L5:
+	movi	a2, 0		# return success for len bytes copied
+	retw
+
+/*
+ * Destination is aligned, Source is unaligned
+ */
+
+	.align	4
+	.byte	0		# 1 mod 4 alignement for LOOPNEZ
+				# (0 mod 4 alignment for LBEG)
+.Lsrcunaligned:
+	# copy 16 bytes per iteration for word-aligned dst and unaligned src
+	and	a10, a3, a8	# save unalignment offset for below
+	sub	a3, a3, a10	# align a3 (to avoid sim warnings only; not needed for hardware)
+	EX(l32i, a6, a3, 0, l_fixup)	# load first word
+#if XCHAL_HAVE_LOOPS
+	loopnez	a7, .Loop2done
+#else /* !XCHAL_HAVE_LOOPS */
+	beqz	a7, .Loop2done
+	slli	a10, a7, 4
+	add	a10, a10, a3	# a10 = end of last 16B source chunk
+#endif /* !XCHAL_HAVE_LOOPS */
+.Loop2:
+	EX(l32i, a7, a3,  4, l_fixup)
+	EX(l32i, a8, a3,  8, l_fixup)
+	ALIGN(	a6, a6, a7)
+	EX(s32i, a6, a5,  0, s_fixup)
+	EX(l32i, a9, a3, 12, l_fixup)
+	ALIGN(	a7, a7, a8)
+	EX(s32i, a7, a5,  4, s_fixup)
+	EX(l32i, a6, a3, 16, l_fixup)
+	ALIGN(	a8, a8, a9)
+	EX(s32i, a8, a5,  8, s_fixup)
+	addi	a3, a3, 16
+	ALIGN(	a9, a9, a6)
+	EX(s32i, a9, a5, 12, s_fixup)
+	addi	a5, a5, 16
+#if !XCHAL_HAVE_LOOPS
+	blt	a3, a10, .Loop2
+#endif /* !XCHAL_HAVE_LOOPS */
+.Loop2done:
+	bbci.l	a4, 3, .L12
+	# copy 8 bytes
+	EX(l32i, a7, a3,  4, l_fixup)
+	EX(l32i, a8, a3,  8, l_fixup)
+	ALIGN(	a6, a6, a7)
+	EX(s32i, a6, a5,  0, s_fixup)
+	addi	a3, a3,  8
+	ALIGN(	a7, a7, a8)
+	EX(s32i, a7, a5,  4, s_fixup)
+	addi	a5, a5,  8
+	mov	a6, a8
+.L12:
+	bbci.l	a4, 2, .L13
+	# copy 4 bytes
+	EX(l32i, a7, a3,  4, l_fixup)
+	addi	a3, a3,  4
+	ALIGN(	a6, a6, a7)
+	EX(s32i, a6, a5,  0, s_fixup)
+	addi	a5, a5,  4
+	mov	a6, a7
+.L13:
+	add	a3, a3, a10	# readjust a3 with correct misalignment
+	bbci.l	a4, 1, .L14
+	# copy 2 bytes
+	EX(l8ui, a6, a3,  0, l_fixup)
+	EX(l8ui, a7, a3,  1, l_fixup)
+	addi	a3, a3,  2
+	EX(s8i, a6, a5,  0, s_fixup)
+	EX(s8i, a7, a5,  1, s_fixup)
+	addi	a5, a5,  2
+.L14:
+	bbci.l	a4, 0, .L15
+	# copy 1 byte
+	EX(l8ui, a6, a3,  0, l_fixup)
+	EX(s8i,  a6, a5,  0, s_fixup)
+.L15:
+	movi	a2, 0		# return success for len bytes copied
+	retw
+
+
+	.section .fixup, "ax"
+	.align	4
+
+/* a2 = original dst; a5 = current dst; a11= original len
+ * bytes_copied = a5 - a2
+ * retval = bytes_not_copied = original len - bytes_copied
+ * retval = a11 - (a5 - a2)
+ *
+ * Clearing the remaining pieces of kernel memory plugs security
+ * holes.  This functionality is the equivalent of the *_zeroing
+ * functions that some architectures provide.
+ */
+
+.Lmemset:
+	.word	memset
+
+s_fixup:
+	sub	a2, a5, a2	/* a2 <-- bytes copied */
+	sub	a2, a11, a2	/* a2 <-- bytes not copied */
+	retw
+
+l_fixup:
+	sub	a2, a5, a2	/* a2 <-- bytes copied */
+	sub	a2, a11, a2	/* a2 <-- bytes not copied == return value */
+
+	/* void *memset(void *s, int c, size_t n); */
+	mov	a6, a5		/* s */
+	movi	a7, 0		/* c */
+	mov	a8, a2		/* n */
+	l32r	a4, .Lmemset
+	callx4	a4
+	/* Ignore memset return value in a6. */
+	/* a2 still contains bytes not copied. */
+	retw
+
diff --git a/arch/xtensa/mm/Makefile b/arch/xtensa/mm/Makefile
new file mode 100644
--- /dev/null
+++ b/arch/xtensa/mm/Makefile
@@ -0,0 +1,13 @@
+#
+# Makefile for the Linux/Xtensa-specific parts of the memory manager.
+#
+# 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 definition is now in the main makefile...
+
+obj-y	 := init.o fault.o tlb.o misc.o
+obj-m	 :=
+obj-n	 :=
+obj-	 :=
diff --git a/arch/xtensa/mm/fault.c b/arch/xtensa/mm/fault.c
new file mode 100644
--- /dev/null
+++ b/arch/xtensa/mm/fault.c
@@ -0,0 +1,241 @@
+// TODO VM_EXEC flag work-around, cache aliasing
+/*
+ * arch/xtensa/mm/fault.c
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ *
+ * Chris Zankel <chris@zankel.net>
+ * Joe Taylor	<joe@tensilica.com, joetylr@yahoo.com>
+ */
+
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <asm/mmu_context.h>
+#include <asm/cacheflush.h>
+#include <asm/hardirq.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/pgalloc.h>
+
+unsigned long asid_cache = ASID_FIRST_VERSION;
+void bad_page_fault(struct pt_regs*, unsigned long, int);
+
+/*
+ * This routine handles page faults.  It determines the address,
+ * and the problem, and then passes it off to one of the appropriate
+ * routines.
+ *
+ * Note: does not handle Miss and MultiHit.
+ */
+
+void do_page_fault(struct pt_regs *regs)
+{
+	struct vm_area_struct * vma;
+	struct mm_struct *mm = current->mm;
+	unsigned int exccause = regs->exccause;
+	unsigned int address = regs->excvaddr;
+	siginfo_t info;
+
+	int is_write, is_exec;
+
+	info.si_code = SEGV_MAPERR;
+
+	/* We fault-in kernel-space virtual memory on-demand. The
+	 * 'reference' page table is init_mm.pgd.
+	 */
+	if (address >= TASK_SIZE && !user_mode(regs))
+		goto vmalloc_fault;
+
+	/* If we're in an interrupt or have no user
+	 * context, we must not take the fault..
+	 */
+	if (in_atomic() || !mm) {
+		bad_page_fault(regs, address, SIGSEGV);
+		return;
+	}
+
+	is_write = (exccause == XCHAL_EXCCAUSE_STORE_CACHE_ATTRIBUTE) ? 1 : 0;
+	is_exec =  (exccause == XCHAL_EXCCAUSE_ITLB_PRIVILEGE ||
+		    exccause == XCHAL_EXCCAUSE_ITLB_MISS ||
+		    exccause == XCHAL_EXCCAUSE_FETCH_CACHE_ATTRIBUTE) ? 1 : 0;
+
+#if 0
+	printk("[%s:%d:%08x:%d:%08x:%s%s]\n", current->comm, current->pid,
+	       address, exccause, regs->pc, is_write? "w":"", is_exec? "x":"");
+#endif
+
+	down_read(&mm->mmap_sem);
+	vma = find_vma(mm, address);
+
+	if (!vma)
+		goto bad_area;
+	if (vma->vm_start <= address)
+		goto good_area;
+	if (!(vma->vm_flags & VM_GROWSDOWN))
+		goto bad_area;
+	if (expand_stack(vma, address))
+		goto bad_area;
+
+	/* Ok, we have a good vm_area for this memory access, so
+	 * we can handle it..
+	 */
+
+good_area:
+	info.si_code = SEGV_ACCERR;
+
+	if (is_write) {
+		if (!(vma->vm_flags & VM_WRITE))
+			goto bad_area;
+	} else if (is_exec) {
+		if (!(vma->vm_flags & VM_EXEC))
+			goto bad_area;
+	} else	/* Allow read even from write-only pages. */
+		if (!(vma->vm_flags & (VM_READ | VM_WRITE)))
+			goto bad_area;
+
+	/* If for any reason at all we couldn't handle the fault,
+	 * make sure we exit gracefully rather than endlessly redo
+	 * the fault.
+	 */
+survive:
+	switch (handle_mm_fault(mm, vma, address, is_write)) {
+	case VM_FAULT_MINOR:
+		current->min_flt++;
+		break;
+	case VM_FAULT_MAJOR:
+		current->maj_flt++;
+		break;
+	case VM_FAULT_SIGBUS:
+		goto do_sigbus;
+	case VM_FAULT_OOM:
+		goto out_of_memory;
+	default:
+		BUG();
+	}
+
+	up_read(&mm->mmap_sem);
+	return;
+
+	/* Something tried to access memory that isn't in our memory map..
+	 * Fix it, but check if it's kernel or user first..
+	 */
+bad_area:
+	up_read(&mm->mmap_sem);
+	if (user_mode(regs)) {
+		current->thread.bad_vaddr = address;
+		current->thread.error_code = is_write;
+		info.si_signo = SIGSEGV;
+		info.si_errno = 0;
+		/* info.si_code has been set above */
+		info.si_addr = (void *) address;
+		force_sig_info(SIGSEGV, &info, current);
+		return;
+	}
+	bad_page_fault(regs, address, SIGSEGV);
+	return;
+
+
+	/* We ran out of memory, or some other thing happened to us that made
+	 * us unable to handle the page fault gracefully.
+	 */
+out_of_memory:
+	up_read(&mm->mmap_sem);
+	if (current->pid == 1) {
+		yield();
+		down_read(&mm->mmap_sem);
+		goto survive;
+	}
+	printk("VM: killing process %s\n", current->comm);
+	if (user_mode(regs))
+		do_exit(SIGKILL);
+	bad_page_fault(regs, address, SIGKILL);
+	return;
+
+do_sigbus:
+	up_read(&mm->mmap_sem);
+
+	/* Send a sigbus, regardless of whether we were in kernel
+	 * or user mode.
+	 */
+	current->thread.bad_vaddr = address;
+	info.si_code = SIGBUS;
+	info.si_errno = 0;
+	info.si_code = BUS_ADRERR;
+	info.si_addr = (void *) address;
+	force_sig_info(SIGBUS, &info, current);
+
+	/* Kernel mode? Handle exceptions or die */
+	if (!user_mode(regs))
+		bad_page_fault(regs, address, SIGBUS);
+
+vmalloc_fault:
+	{
+		/* Synchronize this task's top level page-table
+		 * with the 'reference' page table.
+		 */
+		struct mm_struct *act_mm = current->active_mm;
+		int index = pgd_index(address);
+		pgd_t *pgd, *pgd_k;
+		pmd_t *pmd, *pmd_k;
+		pte_t *pte_k;
+
+		if (act_mm == NULL)
+			goto bad_page_fault;
+
+		pgd = act_mm->pgd + index;
+		pgd_k = init_mm.pgd + index;
+
+		if (!pgd_present(*pgd_k))
+			goto bad_page_fault;
+
+		pgd_val(*pgd) = pgd_val(*pgd_k);
+
+		pmd = pmd_offset(pgd, address);
+		pmd_k = pmd_offset(pgd_k, address);
+		if (!pmd_present(*pmd) || !pmd_present(*pmd_k))
+			goto bad_page_fault;
+
+		pmd_val(*pmd) = pmd_val(*pmd_k);
+		pte_k = pte_offset_kernel(pmd_k, address);
+
+		if (!pte_present(*pte_k))
+			goto bad_page_fault;
+		return;
+	}
+bad_page_fault:
+	bad_page_fault(regs, address, SIGKILL);
+	return;
+}
+
+
+void
+bad_page_fault(struct pt_regs *regs, unsigned long address, int sig)
+{
+	extern void die(const char*, struct pt_regs*, long);
+	const struct exception_table_entry *entry;
+
+	/* Are we prepared to handle this kernel fault?  */
+	if ((entry = search_exception_tables(regs->pc)) != NULL) {
+#if 1
+		printk(KERN_DEBUG "%s: Exception at pc=%#010lx (%lx)\n",
+				current->comm, regs->pc, entry->fixup);
+#endif
+		current->thread.bad_uaddr = address;
+		regs->pc = entry->fixup;
+		return;
+	}
+
+	/* Oops. The kernel tried to access some bad page. We'll have to
+	 * terminate things with extreme prejudice.
+	 */
+	printk(KERN_ALERT "Unable to handle kernel paging request at virtual "
+	       "address %08lx\n pc = %08lx, ra = %08lx\n",
+	       address, regs->pc, regs->areg[0]);
+	die("Oops", regs, sig);
+	do_exit(sig);
+}
+
diff --git a/arch/xtensa/mm/init.c b/arch/xtensa/mm/init.c
new file mode 100644
--- /dev/null
+++ b/arch/xtensa/mm/init.c
@@ -0,0 +1,551 @@
+/*
+ * arch/xtensa/mm/init.c
+ *
+ * Derived from MIPS, PPC.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ *
+ * Chris Zankel	<chris@zankel.net>
+ * Joe Taylor	<joe@tensilica.com, joetylr@yahoo.com>
+ * Marc Gauthier
+ * Kevin Chea
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/ptrace.h>
+#include <linux/bootmem.h>
+#include <linux/swap.h>
+
+#include <asm/pgtable.h>
+#include <asm/bootparam.h>
+#include <asm/mmu_context.h>
+#include <asm/tlb.h>
+#include <asm/tlbflush.h>
+#include <asm/page.h>
+#include <asm/pgalloc.h>
+#include <asm/pgtable.h>
+
+
+#define DEBUG 0
+
+DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
+//static DEFINE_SPINLOCK(tlb_lock);
+
+/*
+ * This flag is used to indicate that the page was mapped and modified in
+ * kernel space, so the cache is probably dirty at that address.
+ * If cache aliasing is enabled and the page color mismatches, update_mmu_cache
+ * synchronizes the caches if this bit is set.
+ */
+
+#define PG_cache_clean PG_arch_1
+
+/* References to section boundaries */
+
+extern char _ftext, _etext, _fdata, _edata, _rodata_end;
+extern char __init_begin, __init_end;
+
+/*
+ * mem_reserve(start, end, must_exist)
+ *
+ * Reserve some memory from the memory pool.
+ *
+ * Parameters:
+ *  start	Start of region,
+ *  end		End of region,
+ *  must_exist	Must exist in memory pool.
+ *
+ * Returns:
+ *  0 (memory area couldn't be mapped)
+ * -1 (success)
+ */
+
+int __init mem_reserve(unsigned long start, unsigned long end, int must_exist)
+{
+	int i;
+
+	if (start == end)
+		return 0;
+
+	start = start & PAGE_MASK;
+	end = PAGE_ALIGN(end);
+
+	for (i = 0; i < sysmem.nr_banks; i++)
+		if (start < sysmem.bank[i].end
+		    && end >= sysmem.bank[i].start)
+			break;
+
+	if (i == sysmem.nr_banks) {
+		if (must_exist)
+			printk (KERN_WARNING "mem_reserve: [0x%0lx, 0x%0lx) "
+				"not in any region!\n", start, end);
+		return 0;
+	}
+
+	if (start > sysmem.bank[i].start) {
+		if (end < sysmem.bank[i].end) {
+			/* split entry */
+			if (sysmem.nr_banks >= SYSMEM_BANKS_MAX)
+				panic("meminfo overflow\n");
+			sysmem.bank[sysmem.nr_banks].start = end;
+			sysmem.bank[sysmem.nr_banks].end = sysmem.bank[i].end;
+			sysmem.nr_banks++;
+		}
+		sysmem.bank[i].end = start;
+	} else {
+		if (end < sysmem.bank[i].end)
+			sysmem.bank[i].start = end;
+		else {
+			/* remove entry */
+			sysmem.nr_banks--;
+			sysmem.bank[i].start = sysmem.bank[sysmem.nr_banks].start;
+			sysmem.bank[i].end   = sysmem.bank[sysmem.nr_banks].end;
+		}
+	}
+	return -1;
+}
+
+
+/*
+ * Initialize the bootmem system and give it all the memory we have available.
+ */
+
+void __init bootmem_init(void)
+{
+	unsigned long pfn;
+	unsigned long bootmap_start, bootmap_size;
+	int i;
+
+	max_low_pfn = max_pfn = 0;
+	min_low_pfn = ~0;
+
+	for (i=0; i < sysmem.nr_banks; i++) {
+		pfn = PAGE_ALIGN(sysmem.bank[i].start) >> PAGE_SHIFT;
+		if (pfn < min_low_pfn)
+			min_low_pfn = pfn;
+		pfn = PAGE_ALIGN(sysmem.bank[i].end - 1) >> PAGE_SHIFT;
+		if (pfn > max_pfn)
+			max_pfn = pfn;
+	}
+
+	if (min_low_pfn > max_pfn)
+		panic("No memory found!\n");
+
+	max_low_pfn = max_pfn < MAX_LOW_MEMORY >> PAGE_SHIFT ?
+		max_pfn : MAX_LOW_MEMORY >> PAGE_SHIFT;
+
+	/* Find an area to use for the bootmem bitmap. */
+
+	bootmap_size = bootmem_bootmap_pages(max_low_pfn) << PAGE_SHIFT;
+	bootmap_start = ~0;
+
+	for (i=0; i<sysmem.nr_banks; i++)
+		if (sysmem.bank[i].end - sysmem.bank[i].start >= bootmap_size) {
+			bootmap_start = sysmem.bank[i].start;
+			break;
+		}
+
+	if (bootmap_start == ~0UL)
+		panic("Cannot find %ld bytes for bootmap\n", bootmap_size);
+
+	/* Reserve the bootmem bitmap area */
+
+	mem_reserve(bootmap_start, bootmap_start + bootmap_size, 1);
+	bootmap_size = init_bootmem_node(NODE_DATA(0), min_low_pfn,
+					 bootmap_start >> PAGE_SHIFT,
+					 max_low_pfn);
+
+	/* Add all remaining memory pieces into the bootmem map */
+
+	for (i=0; i<sysmem.nr_banks; i++)
+		free_bootmem(sysmem.bank[i].start,
+			     sysmem.bank[i].end - sysmem.bank[i].start);
+
+}
+
+
+void __init paging_init(void)
+{
+	unsigned long zones_size[MAX_NR_ZONES];
+	int i;
+
+	/* All pages are DMA-able, so we put them all in the DMA zone. */
+
+	zones_size[ZONE_DMA] = max_low_pfn;
+	for (i = 1; i < MAX_NR_ZONES; i++)
+		zones_size[i] = 0;
+
+#ifdef CONFIG_HIGHMEM
+	zones_size[ZONE_HIGHMEM] = max_pfn - max_low_pfn;
+#endif
+
+	/* Initialize the kernel's page tables. */
+
+	memset(swapper_pg_dir, 0, PAGE_SIZE);
+
+	free_area_init(zones_size);
+}
+
+/*
+ * Flush the mmu and reset associated register to default values.
+ */
+
+void __init init_mmu (void)
+{
+	/* Writing zeros to the <t>TLBCFG special registers ensure
+	 * that valid values exist in the register.  For existing
+	 * PGSZID<w> fields, zero selects the first element of the
+	 * page-size array.  For nonexistant PGSZID<w> fields, zero is
+	 * the best value to write.  Also, when changing PGSZID<w>
+	 * fields, the corresponding TLB must be flushed.
+	 */
+	set_itlbcfg_register (0);
+	set_dtlbcfg_register (0);
+	flush_tlb_all ();
+
+	/* Set rasid register to a known value. */
+
+	set_rasid_register (ASID_ALL_RESERVED);
+
+	/* Set PTEVADDR special register to the start of the page
+	 * table, which is in kernel mappable space (ie. not
+	 * statically mapped).  This register's value is undefined on
+	 * reset.
+	 */
+	set_ptevaddr_register (PGTABLE_START);
+}
+
+/*
+ * Initialize memory pages.
+ */
+
+void __init mem_init(void)
+{
+	unsigned long codesize, reservedpages, datasize, initsize;
+	unsigned long highmemsize, tmp, ram;
+
+	max_mapnr = num_physpages = max_low_pfn;
+	high_memory = (void *) __va(max_mapnr << PAGE_SHIFT);
+	highmemsize = 0;
+
+#if CONFIG_HIGHMEM
+#error HIGHGMEM not implemented in init.c
+#endif
+
+	totalram_pages += free_all_bootmem();
+
+	reservedpages = ram = 0;
+	for (tmp = 0; tmp < max_low_pfn; tmp++) {
+		ram++;
+		if (PageReserved(mem_map+tmp))
+			reservedpages++;
+	}
+
+	codesize =  (unsigned long) &_etext - (unsigned long) &_ftext;
+	datasize =  (unsigned long) &_edata - (unsigned long) &_fdata;
+	initsize =  (unsigned long) &__init_end - (unsigned long) &__init_begin;
+
+	printk("Memory: %luk/%luk available (%ldk kernel code, %ldk reserved, "
+	       "%ldk data, %ldk init %ldk highmem)\n",
+	       (unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
+	       ram << (PAGE_SHIFT-10),
+	       codesize >> 10,
+	       reservedpages << (PAGE_SHIFT-10),
+	       datasize >> 10,
+	       initsize >> 10,
+	       highmemsize >> 10);
+}
+
+void
+free_reserved_mem(void *start, void *end)
+{
+	for (; start < end; start += PAGE_SIZE) {
+		ClearPageReserved(virt_to_page(start));
+		set_page_count(virt_to_page(start), 1);
+		free_page((unsigned long)start);
+		totalram_pages++;
+	}
+}
+
+#ifdef CONFIG_BLK_DEV_INITRD
+extern int initrd_is_mapped;
+
+void free_initrd_mem(unsigned long start, unsigned long end)
+{
+	if (initrd_is_mapped) {
+		free_reserved_mem((void*)start, (void*)end);
+		printk ("Freeing initrd memory: %ldk freed\n",(end-start)>>10);
+	}
+}
+#endif
+
+void free_initmem(void)
+{
+	free_reserved_mem(&__init_begin, &__init_end);
+	printk("Freeing unused kernel memory: %dk freed\n",
+	       (&__init_end - &__init_begin) >> 10);
+}
+
+void show_mem(void)
+{
+	int i, free = 0, total = 0, reserved = 0;
+	int shared = 0, cached = 0;
+
+	printk("Mem-info:\n");
+	show_free_areas();
+	printk("Free swap:       %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
+	i = max_mapnr;
+	while (i-- > 0) {
+		total++;
+		if (PageReserved(mem_map+i))
+			reserved++;
+		else if (PageSwapCache(mem_map+i))
+			cached++;
+		else if (!page_count(mem_map + i))
+			free++;
+		else
+			shared += page_count(mem_map + i) - 1;
+	}
+	printk("%d pages of RAM\n", total);
+	printk("%d reserved pages\n", reserved);
+	printk("%d pages shared\n", shared);
+	printk("%d pages swap cached\n",cached);
+	printk("%d free pages\n", free);
+}
+
+/* ------------------------------------------------------------------------- */
+
+#if (DCACHE_WAY_SIZE > PAGE_SIZE)
+
+/*
+ * With cache aliasing, the page color of the page in kernel space and user
+ * space might mismatch. We temporarily map the page to a different virtual
+ * address with the same color and clear the page there.
+ */
+
+void clear_user_page(void *kaddr, unsigned long vaddr, struct page* page)
+{
+
+  	/*  There shouldn't be any entries for this page. */
+
+	__flush_invalidate_dcache_page_phys(__pa(page_address(page)));
+
+	if (!PAGE_COLOR_EQ(vaddr, kaddr)) {
+		unsigned long v, p;
+
+		/* Temporarily map page to DTLB_WAY_DCACHE_ALIAS0. */
+
+		spin_lock(&tlb_lock);
+
+		p = (unsigned long)pte_val((mk_pte(page,PAGE_KERNEL)));
+		kaddr = (void*)PAGE_COLOR_MAP0(vaddr);
+		v = (unsigned long)kaddr | DTLB_WAY_DCACHE_ALIAS0;
+		__asm__ __volatile__("wdtlb %0,%1; dsync" : :"a" (p), "a" (v));
+
+		clear_page(kaddr);
+
+		spin_unlock(&tlb_lock);
+	} else {
+		clear_page(kaddr);
+	}
+
+	/* We need to make sure that i$ and d$ are coherent. */
+
+	clear_bit(PG_cache_clean, &page->flags);
+}
+
+/*
+ * With cache aliasing, we have to make sure that the page color of the page
+ * in kernel space matches that of the virtual user address before we read
+ * the page. If the page color differ, we create a temporary DTLB entry with
+ * the corrent page color and use this 'temporary' address as the source.
+ * We then use the same approach as in clear_user_page and copy the data
+ * to the kernel space and clear the PG_cache_clean bit to synchronize caches
+ * later.
+ *
+ * Note:
+ * Instead of using another 'way' for the temporary DTLB entry, we could
+ * probably use the same entry that points to the kernel address (after
+ * saving the original value and restoring it when we are done).
+ */
+
+void copy_user_page(void* to, void* from, unsigned long vaddr,
+    		    struct page* to_page)
+{
+	/* There shouldn't be any entries for the new page. */
+
+	__flush_invalidate_dcache_page_phys(__pa(page_address(to_page)));
+
+	spin_lock(&tlb_lock);
+
+	if (!PAGE_COLOR_EQ(vaddr, from)) {
+		unsigned long v, p, t;
+
+		__asm__ __volatile__ ("pdtlb %1,%2; rdtlb1 %0,%1"
+				      : "=a"(p), "=a"(t) : "a"(from));
+		from = (void*)PAGE_COLOR_MAP0(vaddr);
+		v = (unsigned long)from | DTLB_WAY_DCACHE_ALIAS0;
+		__asm__ __volatile__ ("wdtlb %0,%1; dsync" ::"a" (p), "a" (v));
+	}
+
+	if (!PAGE_COLOR_EQ(vaddr, to)) {
+		unsigned long v, p;
+
+		p = (unsigned long)pte_val((mk_pte(to_page,PAGE_KERNEL)));
+		to = (void*)PAGE_COLOR_MAP1(vaddr);
+		v = (unsigned long)to | DTLB_WAY_DCACHE_ALIAS1;
+		__asm__ __volatile__ ("wdtlb %0,%1; dsync" ::"a" (p), "a" (v));
+	}
+	copy_page(to, from);
+
+	spin_unlock(&tlb_lock);
+
+	/* We need to make sure that i$ and d$ are coherent. */
+
+	clear_bit(PG_cache_clean, &to_page->flags);
+}
+
+
+
+/*
+ * Any time the kernel writes to a user page cache page, or it is about to
+ * read from a page cache page this routine is called.
+ *
+ * Note:
+ * The kernel currently only provides one architecture bit in the page
+ * flags that we use for I$/D$ coherency. Maybe, in future, we can
+ * use a sepearte bit for deferred dcache aliasing:
+ * If the page is not mapped yet, we only need to set a flag,
+ * if mapped, we need to invalidate the page.
+ */
+// FIXME: we probably need this for WB caches not only for Page Coloring..
+
+void flush_dcache_page(struct page *page)
+{
+	unsigned long addr = __pa(page_address(page));
+	struct address_space *mapping = page_mapping(page);
+
+	__flush_invalidate_dcache_page_phys(addr);
+
+	if (!test_bit(PG_cache_clean, &page->flags))
+		return;
+
+	/* If this page hasn't been mapped, yet, handle I$/D$ coherency later.*/
+#if 0
+	if (mapping && !mapping_mapped(mapping))
+		clear_bit(PG_cache_clean, &page->flags);
+	else
+#endif
+		__invalidate_icache_page_phys(addr);
+}
+
+void flush_cache_range(struct vm_area_struct* vma, unsigned long s,
+		       unsigned long e)
+{
+	__flush_invalidate_cache_all();
+}
+
+void flush_cache_page(struct vm_area_struct* vma, unsigned long address,
+    		      unsigned long pfn)
+{
+	struct page *page = pfn_to_page(pfn);
+
+	/* Remove any entry for the old mapping. */
+
+	if (current->active_mm == vma->vm_mm) {
+		unsigned long addr = __pa(page_address(page));
+		__flush_invalidate_dcache_page_phys(addr);
+		if ((vma->vm_flags & VM_EXEC) != 0)
+			__invalidate_icache_page_phys(addr);
+	} else {
+		BUG();
+	}
+}
+
+#endif	/* (DCACHE_WAY_SIZE > PAGE_SIZE) */
+
+
+pte_t* pte_alloc_one_kernel (struct mm_struct* mm, unsigned long addr)
+{
+	pte_t* pte = (pte_t*)__get_free_pages(GFP_KERNEL|__GFP_REPEAT, 0);
+	if (likely(pte)) {
+	       	pte_t* ptep = (pte_t*)(pte_val(*pte) + PAGE_OFFSET);
+		int i;
+		for (i = 0; i < 1024; i++, ptep++)
+			pte_clear(mm, addr, ptep);
+	}
+	return pte;
+}
+
+struct page* pte_alloc_one(struct mm_struct *mm, unsigned long addr)
+{
+	struct page *page;
+
+	page = alloc_pages(GFP_KERNEL | __GFP_REPEAT, 0);
+
+	if (likely(page)) {
+		pte_t* ptep = kmap_atomic(page, KM_USER0);
+		int i;
+
+		for (i = 0; i < 1024; i++, ptep++)
+			pte_clear(mm, addr, ptep);
+
+		kunmap_atomic(ptep, KM_USER0);
+	}
+	return page;
+}
+
+
+/*
+ * Handle D$/I$ coherency.
+ *
+ * Note:
+ * We only have one architecture bit for the page flags, so we cannot handle
+ * cache aliasing, yet.
+ */
+
+void
+update_mmu_cache(struct vm_area_struct * vma, unsigned long addr, pte_t pte)
+{
+	unsigned long pfn = pte_pfn(pte);
+	struct page *page;
+	unsigned long vaddr = addr & PAGE_MASK;
+
+	if (!pfn_valid(pfn))
+		return;
+
+	page = pfn_to_page(pfn);
+
+	invalidate_itlb_mapping(addr);
+	invalidate_dtlb_mapping(addr);
+
+	/* We have a new mapping. Use it. */
+
+	write_dtlb_entry(pte, dtlb_probe(addr));
+
+	/* If the processor can execute from this page, synchronize D$/I$. */
+
+	if ((vma->vm_flags & VM_EXEC) != 0) {
+
+		write_itlb_entry(pte, itlb_probe(addr));
+
+		/* Synchronize caches, if not clean. */
+
+		if (!test_and_set_bit(PG_cache_clean, &page->flags)) {
+			__flush_dcache_page(vaddr);
+			__invalidate_icache_page(vaddr);
+		}
+	}
+}
+
diff --git a/arch/xtensa/mm/misc.S b/arch/xtensa/mm/misc.S
new file mode 100644
--- /dev/null
+++ b/arch/xtensa/mm/misc.S
@@ -0,0 +1,374 @@
+/*
+ * arch/xtensa/mm/misc.S
+ *
+ * Miscellaneous assembly functions.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ *
+ * Chris Zankel	<chris@zankel.net>
+ */
+
+/* Note: we might want to implement some of the loops as zero-overhead-loops,
+ *	 where applicable and if supported by the processor.
+ */
+
+#include <linux/linkage.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+
+#include <xtensa/cacheasm.h>
+#include <xtensa/cacheattrasm.h>
+
+/* clear_page (page) */
+
+ENTRY(clear_page)
+	entry	a1, 16
+	addi	a4, a2, PAGE_SIZE
+	movi	a3, 0
+
+1:	s32i	a3, a2, 0
+	s32i	a3, a2, 4
+	s32i	a3, a2, 8
+	s32i	a3, a2, 12
+	s32i	a3, a2, 16
+	s32i	a3, a2, 20
+	s32i	a3, a2, 24
+	s32i	a3, a2, 28
+	addi	a2, a2, 32
+	blt	a2, a4, 1b
+
+	retw
+
+/*
+ * copy_page (void *to, void *from)
+ *                  a2        a3
+ */
+
+ENTRY(copy_page)
+	entry	a1, 16
+	addi	a4, a2, PAGE_SIZE
+
+1:	l32i	a5, a3, 0
+	l32i	a6, a3, 4
+	l32i	a7, a3, 8
+	s32i	a5, a2, 0
+	s32i	a6, a2, 4
+	s32i	a7, a2, 8
+	l32i	a5, a3, 12
+	l32i	a6, a3, 16
+	l32i	a7, a3, 20
+	s32i	a5, a2, 12
+	s32i	a6, a2, 16
+	s32i	a7, a2, 20
+	l32i	a5, a3, 24
+	l32i	a6, a3, 28
+	s32i	a5, a2, 24
+	s32i	a6, a2, 28
+	addi	a2, a2, 32
+	addi	a3, a3, 32
+	blt	a2, a4, 1b
+
+	retw
+
+
+/*
+ * void __flush_invalidate_cache_all(void)
+ */
+
+ENTRY(__flush_invalidate_cache_all)
+	entry	sp, 16
+	dcache_writeback_inv_all a2, a3
+	icache_invalidate_all a2, a3
+	retw
+
+/*
+ * void __invalidate_icache_all(void)
+ */
+
+ENTRY(__invalidate_icache_all)
+	entry	sp, 16
+	icache_invalidate_all a2, a3
+	retw
+
+/*
+ * void __flush_invalidate_dcache_all(void)
+ */
+
+ENTRY(__flush_invalidate_dcache_all)
+	entry	sp, 16
+	dcache_writeback_inv_all a2, a3
+	retw
+
+
+/*
+ * void __flush_invalidate_cache_range(ulong start, ulong size)
+ */
+
+ENTRY(__flush_invalidate_cache_range)
+	entry	sp, 16
+	mov	a4, a2
+	mov	a5, a3
+	dcache_writeback_inv_region a4, a5, a6
+	icache_invalidate_region a2, a3, a4
+	retw
+
+/*
+ * void __invalidate_icache_page(ulong start)
+ */
+
+ENTRY(__invalidate_icache_page)
+	entry	sp, 16
+	movi	a3, PAGE_SIZE
+	icache_invalidate_region a2, a3, a4
+	retw
+
+/*
+ * void __invalidate_dcache_page(ulong start)
+ */
+
+ENTRY(__invalidate_dcache_page)
+	entry	sp, 16
+	movi	a3, PAGE_SIZE
+	dcache_invalidate_region a2, a3, a4
+	retw
+
+/*
+ * void __invalidate_icache_range(ulong start, ulong size)
+ */
+
+ENTRY(__invalidate_icache_range)
+	entry	sp, 16
+	icache_invalidate_region a2, a3, a4
+	retw
+
+/*
+ * void __invalidate_dcache_range(ulong start, ulong size)
+ */
+
+ENTRY(__invalidate_dcache_range)
+	entry	sp, 16
+	dcache_invalidate_region a2, a3, a4
+	retw
+
+/*
+ * void __flush_dcache_page(ulong start)
+ */
+
+ENTRY(__flush_dcache_page)
+	entry	sp, 16
+	movi	a3, PAGE_SIZE
+	dcache_writeback_region a2, a3, a4
+	retw
+
+/*
+ * void __flush_invalidate_dcache_page(ulong start)
+ */
+
+ENTRY(__flush_invalidate_dcache_page)
+	entry	sp, 16
+	movi	a3, PAGE_SIZE
+	dcache_writeback_inv_region a2, a3, a4
+	retw
+
+/*
+ * void __flush_invalidate_dcache_range(ulong start, ulong size)
+ */
+
+ENTRY(__flush_invalidate_dcache_range)
+	entry	sp, 16
+	dcache_writeback_inv_region a2, a3, a4
+	retw
+
+/*
+ * void __invalidate_dcache_all(void)
+ */
+
+ENTRY(__invalidate_dcache_all)
+	entry	sp, 16
+	dcache_invalidate_all a2, a3
+	retw
+
+/*
+ * void __flush_invalidate_dcache_page_phys(ulong start)
+ */
+
+ENTRY(__flush_invalidate_dcache_page_phys)
+	entry	sp, 16
+
+	movi	a3, XCHAL_DCACHE_SIZE
+	movi	a4, PAGE_MASK | 1
+	addi	a2, a2, 1
+
+1:	addi	a3, a3, -XCHAL_DCACHE_LINESIZE
+
+	ldct	a6, a3
+	dsync
+	and	a6, a6, a4
+	beq	a6, a2, 2f
+	bgeui	a3, 2, 1b
+	retw
+
+2:	diwbi	a3, 0
+	bgeui	a3, 2, 1b
+	retw
+
+ENTRY(check_dcache_low0)
+	entry	sp, 16
+
+	movi	a3, XCHAL_DCACHE_SIZE / 4
+	movi	a4, PAGE_MASK | 1
+	addi	a2, a2, 1
+
+1:	addi	a3, a3, -XCHAL_DCACHE_LINESIZE
+
+	ldct	a6, a3
+	dsync
+	and	a6, a6, a4
+	beq	a6, a2, 2f
+	bgeui	a3, 2, 1b
+	retw
+
+2:	j 2b
+
+ENTRY(check_dcache_high0)
+	entry	sp, 16
+
+	movi	a5, XCHAL_DCACHE_SIZE / 4
+	movi	a3, XCHAL_DCACHE_SIZE / 2
+	movi	a4, PAGE_MASK | 1
+	addi	a2, a2, 1
+
+1:	addi	a3, a3, -XCHAL_DCACHE_LINESIZE
+	addi	a5, a5, -XCHAL_DCACHE_LINESIZE
+
+	ldct	a6, a3
+	dsync
+	and	a6, a6, a4
+	beq	a6, a2, 2f
+	bgeui	a5, 2, 1b
+	retw
+
+2:	j 2b
+
+ENTRY(check_dcache_low1)
+	entry	sp, 16
+
+	movi	a5, XCHAL_DCACHE_SIZE / 4
+	movi	a3, XCHAL_DCACHE_SIZE * 3 / 4
+	movi	a4, PAGE_MASK | 1
+	addi	a2, a2, 1
+
+1:	addi	a3, a3, -XCHAL_DCACHE_LINESIZE
+	addi	a5, a5, -XCHAL_DCACHE_LINESIZE
+
+	ldct	a6, a3
+	dsync
+	and	a6, a6, a4
+	beq	a6, a2, 2f
+	bgeui	a5, 2, 1b
+	retw
+
+2:	j 2b
+
+ENTRY(check_dcache_high1)
+	entry	sp, 16
+
+	movi	a5, XCHAL_DCACHE_SIZE / 4
+	movi	a3, XCHAL_DCACHE_SIZE
+	movi	a4, PAGE_MASK | 1
+	addi	a2, a2, 1
+
+1:	addi	a3, a3, -XCHAL_DCACHE_LINESIZE
+	addi	a5, a5, -XCHAL_DCACHE_LINESIZE
+
+	ldct	a6, a3
+	dsync
+	and	a6, a6, a4
+	beq	a6, a2, 2f
+	bgeui	a5, 2, 1b
+	retw
+
+2:	j 2b
+
+
+/*
+ * void __invalidate_icache_page_phys(ulong start)
+ */
+
+ENTRY(__invalidate_icache_page_phys)
+	entry	sp, 16
+
+	movi	a3, XCHAL_ICACHE_SIZE
+	movi	a4, PAGE_MASK | 1
+	addi	a2, a2, 1
+
+1:	addi	a3, a3, -XCHAL_ICACHE_LINESIZE
+
+	lict	a6, a3
+	isync
+	and	a6, a6, a4
+	beq	a6, a2, 2f
+	bgeui	a3, 2, 1b
+	retw
+
+2:	iii	a3, 0
+	bgeui	a3, 2, 1b
+	retw
+
+
+#if 0
+
+	movi	a3, XCHAL_DCACHE_WAYS - 1
+	movi	a4, PAGE_SIZE
+
+1:	mov	a5, a2
+	add	a6, a2, a4
+
+2:	diwbi	a5, 0
+	diwbi	a5, XCHAL_DCACHE_LINESIZE
+	diwbi	a5, XCHAL_DCACHE_LINESIZE * 2
+	diwbi	a5, XCHAL_DCACHE_LINESIZE * 3
+
+	addi	a5, a5, XCHAL_DCACHE_LINESIZE * 4
+	blt	a5, a6, 2b
+
+	addi	a3, a3, -1
+	addi	a2, a2, XCHAL_DCACHE_SIZE / XCHAL_DCACHE_WAYS
+	bgez	a3, 1b
+
+	retw
+
+ENTRY(__invalidate_icache_page_index)
+	entry	sp, 16
+
+	movi	a3, XCHAL_ICACHE_WAYS - 1
+	movi	a4, PAGE_SIZE
+
+1:	mov	a5, a2
+	add	a6, a2, a4
+
+2:	iii	a5, 0
+	iii	a5, XCHAL_ICACHE_LINESIZE
+	iii	a5, XCHAL_ICACHE_LINESIZE * 2
+	iii	a5, XCHAL_ICACHE_LINESIZE * 3
+
+	addi	a5, a5, XCHAL_ICACHE_LINESIZE * 4
+	blt	a5, a6, 2b
+
+	addi	a3, a3, -1
+	addi	a2, a2, XCHAL_ICACHE_SIZE / XCHAL_ICACHE_WAYS
+	bgez	a3, 2b
+
+	retw
+
+#endif
+
+
+
+
+
+
diff --git a/arch/xtensa/mm/pgtable.c b/arch/xtensa/mm/pgtable.c
new file mode 100644
--- /dev/null
+++ b/arch/xtensa/mm/pgtable.c
@@ -0,0 +1,76 @@
+/*
+ * arch/xtensa/mm/fault.c
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ *
+ * Chris Zankel <chris@zankel.net>
+ */
+
+#if (DCACHE_SIZE > PAGE_SIZE)
+
+pte_t* pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
+{
+	pte_t *pte, p;
+	int color = ADDR_COLOR(address);
+	int i;
+
+	p = (pte_t*) __get_free_pages(GFP_KERNEL|__GFP_REPEAT, COLOR_ORDER);
+
+	if (likely(p)) {
+		struct page *page;
+
+		for (i = 0; i < COLOR_SIZE; i++, p++) {
+			page = virt_to_page(pte);
+
+			set_page_count(page, 1);
+			ClearPageCompound(page);
+
+			if (ADDR_COLOR(p) == color)
+				pte = p;
+			else
+				free_page(p);
+		}
+		clear_page(pte);
+	}
+	return pte;
+}
+
+#ifdef PROFILING
+
+int mask;
+int hit;
+int flush;
+
+#endif
+
+struct page* pte_alloc_one(struct mm_struct *mm, unsigned long address)
+{
+	struct page *page, p;
+	int color = ADDR_COLOR(address);
+
+	p = alloc_pages(GFP_KERNEL | __GFP_REPEAT, PTE_ORDER);
+
+	if (likely(p)) {
+		for (i = 0; i < PAGE_ORDER; i++) {
+			set_page_count(p, 1);
+			ClearPageCompound(p);
+
+			if (PADDR_COLOR(page_address(pg)) == color)
+				page = p;
+			else
+				free_page(p);
+		}
+		clear_highpage(page);
+	}
+
+	return page;
+}
+
+#endif
+
+
+
diff --git a/arch/xtensa/mm/tlb.c b/arch/xtensa/mm/tlb.c
new file mode 100644
--- /dev/null
+++ b/arch/xtensa/mm/tlb.c
@@ -0,0 +1,545 @@
+/*
+ * arch/xtensa/mm/mmu.c
+ *
+ * Logic that manipulates the Xtensa MMU.  Derived from MIPS.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2003 Tensilica Inc.
+ *
+ * Joe Taylor
+ * Chris Zankel	<chris@zankel.net>
+ * Marc Gauthier
+ */
+
+#include <linux/mm.h>
+#include <asm/processor.h>
+#include <asm/mmu_context.h>
+#include <asm/tlbflush.h>
+#include <asm/system.h>
+#include <asm/cacheflush.h>
+
+
+static inline void __flush_itlb_all (void)
+{
+	int way, index;
+
+	for (way = 0; way < XCHAL_ITLB_ARF_WAYS; way++) {
+		for (index = 0; index < ITLB_ENTRIES_PER_ARF_WAY; index++) {
+			int entry = way + (index << PAGE_SHIFT);
+			invalidate_itlb_entry_no_isync (entry);
+		}
+	}
+	asm volatile ("isync\n");
+}
+
+static inline void __flush_dtlb_all (void)
+{
+	int way, index;
+
+	for (way = 0; way < XCHAL_DTLB_ARF_WAYS; way++) {
+		for (index = 0; index < DTLB_ENTRIES_PER_ARF_WAY; index++) {
+			int entry = way + (index << PAGE_SHIFT);
+			invalidate_dtlb_entry_no_isync (entry);
+		}
+	}
+	asm volatile ("isync\n");
+}
+
+
+void flush_tlb_all (void)
+{
+	__flush_itlb_all();
+	__flush_dtlb_all();
+}
+
+/* If mm is current, we simply assign the current task a new ASID, thus,
+ * invalidating all previous tlb entries. If mm is someone else's user mapping,
+ * wie invalidate the context, thus, when that user mapping is swapped in,
+ * a new context will be assigned to it.
+ */
+
+void flush_tlb_mm(struct mm_struct *mm)
+{
+#if 0
+	printk("[tlbmm<%lx>]\n", (unsigned long)mm->context);
+#endif
+
+	if (mm == current->active_mm) {
+		int flags;
+		local_save_flags(flags);
+		get_new_mmu_context(mm, asid_cache);
+		set_rasid_register(ASID_INSERT(mm->context));
+		local_irq_restore(flags);
+	}
+	else
+		mm->context = 0;
+}
+
+void flush_tlb_range (struct vm_area_struct *vma,
+    		      unsigned long start, unsigned long end)
+{
+	struct mm_struct *mm = vma->vm_mm;
+	unsigned long flags;
+
+	if (mm->context == NO_CONTEXT)
+		return;
+
+#if 0
+	printk("[tlbrange<%02lx,%08lx,%08lx>]\n",
+			(unsigned long)mm->context, start, end);
+#endif
+	local_save_flags(flags);
+
+	if (end-start + (PAGE_SIZE-1) <= SMALLEST_NTLB_ENTRIES << PAGE_SHIFT) {
+		int oldpid = get_rasid_register();
+		set_rasid_register (ASID_INSERT(mm->context));
+		start &= PAGE_MASK;
+ 		if (vma->vm_flags & VM_EXEC)
+			while(start < end) {
+				invalidate_itlb_mapping(start);
+				invalidate_dtlb_mapping(start);
+				start += PAGE_SIZE;
+			}
+		else
+			while(start < end) {
+				invalidate_dtlb_mapping(start);
+				start += PAGE_SIZE;
+			}
+
+		set_rasid_register(oldpid);
+	} else {
+		get_new_mmu_context(mm, asid_cache);
+		if (mm == current->active_mm)
+			set_rasid_register(ASID_INSERT(mm->context));
+	}
+	local_irq_restore(flags);
+}
+
+void flush_tlb_page (struct vm_area_struct *vma, unsigned long page)
+{
+	struct mm_struct* mm = vma->vm_mm;
+	unsigned long flags;
+	int oldpid;
+#if 0
+	printk("[tlbpage<%02lx,%08lx>]\n",
+			(unsigned long)mm->context, page);
+#endif
+
+	if(mm->context == NO_CONTEXT)
+		return;
+
+	local_save_flags(flags);
+
+       	oldpid = get_rasid_register();
+
+	if (vma->vm_flags & VM_EXEC)
+		invalidate_itlb_mapping(page);
+	invalidate_dtlb_mapping(page);
+
+	set_rasid_register(oldpid);
+
+	local_irq_restore(flags);
+
+#if 0
+	flush_tlb_all();
+	return;
+#endif
+}
+
+
+#ifdef DEBUG_TLB
+
+#define USE_ITLB  0
+#define USE_DTLB  1
+
+struct way_config_t {
+	int indicies;
+	int indicies_log2;
+	int pgsz_log2;
+	int arf;
+};
+
+static struct way_config_t itlb[XCHAL_ITLB_WAYS] =
+{
+	{ XCHAL_ITLB_SET(XCHAL_ITLB_WAY0_SET, ENTRIES),
+	  XCHAL_ITLB_SET(XCHAL_ITLB_WAY0_SET, ENTRIES_LOG2),
+	  XCHAL_ITLB_SET(XCHAL_ITLB_WAY0_SET, PAGESZ_LOG2_MIN),
+	  XCHAL_ITLB_SET(XCHAL_ITLB_WAY0_SET, ARF)
+	},
+	{ XCHAL_ITLB_SET(XCHAL_ITLB_WAY1_SET, ENTRIES),
+	  XCHAL_ITLB_SET(XCHAL_ITLB_WAY1_SET, ENTRIES_LOG2),
+	  XCHAL_ITLB_SET(XCHAL_ITLB_WAY1_SET, PAGESZ_LOG2_MIN),
+	  XCHAL_ITLB_SET(XCHAL_ITLB_WAY1_SET, ARF)
+	},
+	{ XCHAL_ITLB_SET(XCHAL_ITLB_WAY2_SET, ENTRIES),
+	  XCHAL_ITLB_SET(XCHAL_ITLB_WAY2_SET, ENTRIES_LOG2),
+	  XCHAL_ITLB_SET(XCHAL_ITLB_WAY2_SET, PAGESZ_LOG2_MIN),
+	  XCHAL_ITLB_SET(XCHAL_ITLB_WAY2_SET, ARF)
+	},
+	{ XCHAL_ITLB_SET(XCHAL_ITLB_WAY3_SET, ENTRIES),
+	  XCHAL_ITLB_SET(XCHAL_ITLB_WAY3_SET, ENTRIES_LOG2),
+	  XCHAL_ITLB_SET(XCHAL_ITLB_WAY3_SET, PAGESZ_LOG2_MIN),
+	  XCHAL_ITLB_SET(XCHAL_ITLB_WAY3_SET, ARF)
+	},
+	{ XCHAL_ITLB_SET(XCHAL_ITLB_WAY4_SET, ENTRIES),
+	  XCHAL_ITLB_SET(XCHAL_ITLB_WAY4_SET, ENTRIES_LOG2),
+	  XCHAL_ITLB_SET(XCHAL_ITLB_WAY4_SET, PAGESZ_LOG2_MIN),
+	  XCHAL_ITLB_SET(XCHAL_ITLB_WAY4_SET, ARF)
+	},
+	{ XCHAL_ITLB_SET(XCHAL_ITLB_WAY5_SET, ENTRIES),
+	  XCHAL_ITLB_SET(XCHAL_ITLB_WAY5_SET, ENTRIES_LOG2),
+	  XCHAL_ITLB_SET(XCHAL_ITLB_WAY5_SET, PAGESZ_LOG2_MIN),
+	  XCHAL_ITLB_SET(XCHAL_ITLB_WAY5_SET, ARF)
+	},
+	{ XCHAL_ITLB_SET(XCHAL_ITLB_WAY6_SET, ENTRIES),
+	  XCHAL_ITLB_SET(XCHAL_ITLB_WAY6_SET, ENTRIES_LOG2),
+	  XCHAL_ITLB_SET(XCHAL_ITLB_WAY6_SET, PAGESZ_LOG2_MIN),
+	  XCHAL_ITLB_SET(XCHAL_ITLB_WAY6_SET, ARF)
+	}
+};
+
+static struct way_config_t dtlb[XCHAL_DTLB_WAYS] =
+{
+	{ XCHAL_DTLB_SET(XCHAL_DTLB_WAY0_SET, ENTRIES),
+	  XCHAL_DTLB_SET(XCHAL_DTLB_WAY0_SET, ENTRIES_LOG2),
+	  XCHAL_DTLB_SET(XCHAL_DTLB_WAY0_SET, PAGESZ_LOG2_MIN),
+	  XCHAL_DTLB_SET(XCHAL_DTLB_WAY0_SET, ARF)
+	},
+	{ XCHAL_DTLB_SET(XCHAL_DTLB_WAY1_SET, ENTRIES),
+	  XCHAL_DTLB_SET(XCHAL_DTLB_WAY1_SET, ENTRIES_LOG2),
+	  XCHAL_DTLB_SET(XCHAL_DTLB_WAY1_SET, PAGESZ_LOG2_MIN),
+	  XCHAL_DTLB_SET(XCHAL_DTLB_WAY1_SET, ARF)
+	},
+	{ XCHAL_DTLB_SET(XCHAL_DTLB_WAY2_SET, ENTRIES),
+	  XCHAL_DTLB_SET(XCHAL_DTLB_WAY2_SET, ENTRIES_LOG2),
+	  XCHAL_DTLB_SET(XCHAL_DTLB_WAY2_SET, PAGESZ_LOG2_MIN),
+	  XCHAL_DTLB_SET(XCHAL_DTLB_WAY2_SET, ARF)
+	},
+	{ XCHAL_DTLB_SET(XCHAL_DTLB_WAY3_SET, ENTRIES),
+	  XCHAL_DTLB_SET(XCHAL_DTLB_WAY3_SET, ENTRIES_LOG2),
+	  XCHAL_DTLB_SET(XCHAL_DTLB_WAY3_SET, PAGESZ_LOG2_MIN),
+	  XCHAL_DTLB_SET(XCHAL_DTLB_WAY3_SET, ARF)
+	},
+	{ XCHAL_DTLB_SET(XCHAL_DTLB_WAY4_SET, ENTRIES),
+	  XCHAL_DTLB_SET(XCHAL_DTLB_WAY4_SET, ENTRIES_LOG2),
+	  XCHAL_DTLB_SET(XCHAL_DTLB_WAY4_SET, PAGESZ_LOG2_MIN),
+	  XCHAL_DTLB_SET(XCHAL_DTLB_WAY4_SET, ARF)
+	},
+	{ XCHAL_DTLB_SET(XCHAL_DTLB_WAY5_SET, ENTRIES),
+	  XCHAL_DTLB_SET(XCHAL_DTLB_WAY5_SET, ENTRIES_LOG2),
+	  XCHAL_DTLB_SET(XCHAL_DTLB_WAY5_SET, PAGESZ_LOG2_MIN),
+	  XCHAL_DTLB_SET(XCHAL_DTLB_WAY5_SET, ARF)
+	},
+	{ XCHAL_DTLB_SET(XCHAL_DTLB_WAY6_SET, ENTRIES),
+	  XCHAL_DTLB_SET(XCHAL_DTLB_WAY6_SET, ENTRIES_LOG2),
+	  XCHAL_DTLB_SET(XCHAL_DTLB_WAY6_SET, PAGESZ_LOG2_MIN),
+	  XCHAL_DTLB_SET(XCHAL_DTLB_WAY6_SET, ARF)
+	},
+	{ XCHAL_DTLB_SET(XCHAL_DTLB_WAY7_SET, ENTRIES),
+	  XCHAL_DTLB_SET(XCHAL_DTLB_WAY7_SET, ENTRIES_LOG2),
+	  XCHAL_DTLB_SET(XCHAL_DTLB_WAY7_SET, PAGESZ_LOG2_MIN),
+	  XCHAL_DTLB_SET(XCHAL_DTLB_WAY7_SET, ARF)
+	},
+	{ XCHAL_DTLB_SET(XCHAL_DTLB_WAY8_SET, ENTRIES),
+	  XCHAL_DTLB_SET(XCHAL_DTLB_WAY8_SET, ENTRIES_LOG2),
+	  XCHAL_DTLB_SET(XCHAL_DTLB_WAY8_SET, PAGESZ_LOG2_MIN),
+	  XCHAL_DTLB_SET(XCHAL_DTLB_WAY8_SET, ARF)
+	},
+	{ XCHAL_DTLB_SET(XCHAL_DTLB_WAY9_SET, ENTRIES),
+	  XCHAL_DTLB_SET(XCHAL_DTLB_WAY9_SET, ENTRIES_LOG2),
+	  XCHAL_DTLB_SET(XCHAL_DTLB_WAY9_SET, PAGESZ_LOG2_MIN),
+	  XCHAL_DTLB_SET(XCHAL_DTLB_WAY9_SET, ARF)
+	}
+};
+
+/*  Total number of entries:  */
+#define ITLB_TOTAL_ENTRIES	\
+		XCHAL_ITLB_SET(XCHAL_ITLB_WAY0_SET, ENTRIES) + \
+		XCHAL_ITLB_SET(XCHAL_ITLB_WAY1_SET, ENTRIES) + \
+		XCHAL_ITLB_SET(XCHAL_ITLB_WAY2_SET, ENTRIES) + \
+		XCHAL_ITLB_SET(XCHAL_ITLB_WAY3_SET, ENTRIES) + \
+		XCHAL_ITLB_SET(XCHAL_ITLB_WAY4_SET, ENTRIES) + \
+		XCHAL_ITLB_SET(XCHAL_ITLB_WAY5_SET, ENTRIES) + \
+		XCHAL_ITLB_SET(XCHAL_ITLB_WAY6_SET, ENTRIES)
+#define DTLB_TOTAL_ENTRIES	\
+		XCHAL_DTLB_SET(XCHAL_DTLB_WAY0_SET, ENTRIES) + \
+		XCHAL_DTLB_SET(XCHAL_DTLB_WAY1_SET, ENTRIES) + \
+		XCHAL_DTLB_SET(XCHAL_DTLB_WAY2_SET, ENTRIES) + \
+		XCHAL_DTLB_SET(XCHAL_DTLB_WAY3_SET, ENTRIES) + \
+		XCHAL_DTLB_SET(XCHAL_DTLB_WAY4_SET, ENTRIES) + \
+		XCHAL_DTLB_SET(XCHAL_DTLB_WAY5_SET, ENTRIES) + \
+		XCHAL_DTLB_SET(XCHAL_DTLB_WAY6_SET, ENTRIES) + \
+		XCHAL_DTLB_SET(XCHAL_DTLB_WAY7_SET, ENTRIES) + \
+		XCHAL_DTLB_SET(XCHAL_DTLB_WAY8_SET, ENTRIES) + \
+		XCHAL_DTLB_SET(XCHAL_DTLB_WAY9_SET, ENTRIES)
+
+
+typedef struct {
+    unsigned		va;
+    unsigned		pa;
+    unsigned char	asid;
+    unsigned char	ca;
+    unsigned char	way;
+    unsigned char	index;
+    unsigned char	pgsz_log2;	/* 0 .. 32 */
+    unsigned char	type;		/* 0=ITLB 1=DTLB */
+} tlb_dump_entry_t;
+
+/*  Return -1 if a precedes b, +1 if a follows b, 0 if same:  */
+int cmp_tlb_dump_info( tlb_dump_entry_t *a, tlb_dump_entry_t *b )
+{
+    if (a->asid < b->asid) return -1;
+    if (a->asid > b->asid) return  1;
+    if (a->va < b->va) return -1;
+    if (a->va > b->va) return  1;
+    if (a->pa < b->pa) return -1;
+    if (a->pa > b->pa) return  1;
+    if (a->ca < b->ca) return -1;
+    if (a->ca > b->ca) return  1;
+    if (a->way < b->way) return -1;
+    if (a->way > b->way) return  1;
+    if (a->index < b->index) return -1;
+    if (a->index > b->index) return  1;
+    return 0;
+}
+
+void sort_tlb_dump_info( tlb_dump_entry_t *t, int n )
+{
+    int i, j;
+    /*  Simple O(n*n) sort:  */
+    for (i = 0; i < n-1; i++)
+	for (j = i+1; j < n; j++)
+	    if (cmp_tlb_dump_info(t+i, t+j) > 0) {
+		tlb_dump_entry_t tmp = t[i];
+		t[i] = t[j];
+		t[j] = tmp;
+	    }
+}
+
+
+static tlb_dump_entry_t itlb_dump_info[ITLB_TOTAL_ENTRIES];
+static tlb_dump_entry_t dtlb_dump_info[DTLB_TOTAL_ENTRIES];
+
+
+static inline char *way_type (int type)
+{
+	return type ? "autorefill" : "non-autorefill";
+}
+
+void print_entry (struct way_config_t *way_info,
+		  unsigned int way,
+		  unsigned int index,
+		  unsigned int virtual,
+		  unsigned int translation)
+{
+	char valid_chr;
+	unsigned int va, pa, asid, ca;
+
+	va = virtual &
+	  	~((1 << (way_info->pgsz_log2 + way_info->indicies_log2)) - 1);
+	asid = virtual & ((1 << XCHAL_MMU_ASID_BITS) - 1);
+	pa = translation & ~((1 << way_info->pgsz_log2) - 1);
+	ca = translation & ((1 << XCHAL_MMU_CA_BITS) - 1);
+	valid_chr = asid ? 'V' : 'I';
+
+	/* Compute and incorporate the effect of the index bits on the
+	 * va.  It's more useful for kernel debugging, since we always
+	 * want to know the effective va anyway. */
+
+	va += index << way_info->pgsz_log2;
+
+	printk ("\t[%d,%d] (%c) vpn 0x%.8x  ppn 0x%.8x  asid 0x%.2x  am 0x%x\n",
+		way, index, valid_chr, va, pa, asid, ca);
+}
+
+void print_itlb_entry (struct way_config_t *way_info, int way, int index)
+{
+	print_entry (way_info, way, index,
+		     read_itlb_virtual (way + (index << way_info->pgsz_log2)),
+		     read_itlb_translation (way + (index << way_info->pgsz_log2)));
+}
+
+void print_dtlb_entry (struct way_config_t *way_info, int way, int index)
+{
+	print_entry (way_info, way, index,
+		     read_dtlb_virtual (way + (index << way_info->pgsz_log2)),
+		     read_dtlb_translation (way + (index << way_info->pgsz_log2)));
+}
+
+void dump_itlb (void)
+{
+	int way, index;
+
+	printk ("\nITLB: ways = %d\n", XCHAL_ITLB_WAYS);
+
+	for (way = 0; way < XCHAL_ITLB_WAYS; way++) {
+		printk ("\nWay: %d, Entries: %d, MinPageSize: %d, Type: %s\n",
+			way, itlb[way].indicies,
+			itlb[way].pgsz_log2, way_type(itlb[way].arf));
+		for (index = 0; index < itlb[way].indicies; index++) {
+			print_itlb_entry(&itlb[way], way, index);
+		}
+	}
+}
+
+void dump_dtlb (void)
+{
+	int way, index;
+
+	printk ("\nDTLB: ways = %d\n", XCHAL_DTLB_WAYS);
+
+	for (way = 0; way < XCHAL_DTLB_WAYS; way++) {
+		printk ("\nWay: %d, Entries: %d, MinPageSize: %d, Type: %s\n",
+			way, dtlb[way].indicies,
+			dtlb[way].pgsz_log2, way_type(dtlb[way].arf));
+		for (index = 0; index < dtlb[way].indicies; index++) {
+			print_dtlb_entry(&dtlb[way], way, index);
+		}
+	}
+}
+
+void dump_tlb (tlb_dump_entry_t *tinfo, struct way_config_t *config,
+		int entries, int ways, int type, int show_invalid)
+{
+    tlb_dump_entry_t *e = tinfo;
+    int way, i;
+
+    /*  Gather all info:  */
+    for (way = 0; way < ways; way++) {
+	struct way_config_t *cfg = config + way;
+	for (i = 0; i < cfg->indicies; i++) {
+	    unsigned wayindex = way + (i << cfg->pgsz_log2);
+	    unsigned vv = (type ? read_dtlb_virtual (wayindex)
+		    		: read_itlb_virtual (wayindex));
+	    unsigned pp = (type ? read_dtlb_translation (wayindex)
+		    		: read_itlb_translation (wayindex));
+
+	    /* Compute and incorporate the effect of the index bits on the
+	     * va.  It's more useful for kernel debugging, since we always
+	     * want to know the effective va anyway. */
+
+	    e->va = (vv & ~((1 << (cfg->pgsz_log2 + cfg->indicies_log2)) - 1));
+	    e->va += (i << cfg->pgsz_log2);
+	    e->pa = (pp & ~((1 << cfg->pgsz_log2) - 1));
+	    e->asid = (vv & ((1 << XCHAL_MMU_ASID_BITS) - 1));
+	    e->ca = (pp & ((1 << XCHAL_MMU_CA_BITS) - 1));
+	    e->way = way;
+	    e->index = i;
+	    e->pgsz_log2 = cfg->pgsz_log2;
+	    e->type = type;
+	    e++;
+	}
+    }
+#if 1
+    /*  Sort by ASID and VADDR:  */
+    sort_tlb_dump_info (tinfo, entries);
+#endif
+
+    /*  Display all sorted info:  */
+    printk ("\n%cTLB dump:\n", (type ? 'D' : 'I'));
+    for (e = tinfo, i = 0; i < entries; i++, e++) {
+#if 0
+	if (e->asid == 0 && !show_invalid)
+	    continue;
+#endif
+	printk ("%c way=%d i=%d  ASID=%02X V=%08X -> P=%08X CA=%X (%d %cB)\n",
+		(e->type ? 'D' : 'I'), e->way, e->index,
+		e->asid, e->va, e->pa, e->ca,
+		(1 << (e->pgsz_log2 % 10)),
+		" kMG"[e->pgsz_log2 / 10]
+		);
+    }
+}
+
+void dump_tlbs2 (int showinv)
+{
+    dump_tlb (itlb_dump_info, itlb, ITLB_TOTAL_ENTRIES, XCHAL_ITLB_WAYS, 0, showinv);
+    dump_tlb (dtlb_dump_info, dtlb, DTLB_TOTAL_ENTRIES, XCHAL_DTLB_WAYS, 1, showinv);
+}
+
+void dump_all_tlbs (void)
+{
+    dump_tlbs2 (1);
+}
+
+void dump_valid_tlbs (void)
+{
+    dump_tlbs2 (0);
+}
+
+
+void dump_tlbs (void)
+{
+	dump_itlb();
+	dump_dtlb();
+}
+
+void dump_cache_tag(int dcache, int idx)
+{
+	int w, i, s, e;
+	unsigned long tag, index;
+	unsigned long num_lines, num_ways, cache_size, line_size;
+
+	num_ways = dcache ? XCHAL_DCACHE_WAYS : XCHAL_ICACHE_WAYS;
+	cache_size = dcache ? XCHAL_DCACHE_SIZE : XCHAL_ICACHE_SIZE;
+	line_size = dcache ? XCHAL_DCACHE_LINESIZE : XCHAL_ICACHE_LINESIZE;
+
+	num_lines = cache_size / num_ways;
+
+	s = 0; e = num_lines;
+
+	if (idx >= 0)
+		e = (s = idx * line_size) + 1;
+
+	for (i = s; i < e; i+= line_size) {
+		printk("\nline %#08x:", i);
+		for (w = 0; w < num_ways; w++) {
+			index = w * num_lines + i;
+			if (dcache)
+				__asm__ __volatile__("ldct %0, %1\n\t"
+						: "=a"(tag) : "a"(index));
+			else
+				__asm__ __volatile__("lict %0, %1\n\t"
+						: "=a"(tag) : "a"(index));
+
+			printk(" %#010lx", tag);
+		}
+	}
+	printk ("\n");
+}
+
+void dump_icache(int index)
+{
+	unsigned long data, addr;
+	int w, i;
+
+	const unsigned long num_ways = XCHAL_ICACHE_WAYS;
+	const unsigned long cache_size = XCHAL_ICACHE_SIZE;
+	const unsigned long line_size = XCHAL_ICACHE_LINESIZE;
+	const unsigned long num_lines = cache_size / num_ways / line_size;
+
+	for (w = 0; w < num_ways; w++) {
+		printk ("\nWay %d", w);
+
+		for (i = 0; i < line_size; i+= 4) {
+			addr = w * num_lines + index * line_size + i;
+			__asm__ __volatile__("licw %0, %1\n\t"
+					: "=a"(data) : "a"(addr));
+			printk(" %#010lx", data);
+		}
+	}
+	printk ("\n");
+}
+
+void dump_cache_tags(void)
+{
+	printk("Instruction cache\n");
+	dump_cache_tag(0, -1);
+	printk("Data cache\n");
+	dump_cache_tag(1, -1);
+}
+
+#endif
diff --git a/arch/xtensa/platform-iss/Makefile b/arch/xtensa/platform-iss/Makefile
new file mode 100644
--- /dev/null
+++ b/arch/xtensa/platform-iss/Makefile
@@ -0,0 +1,13 @@
+# $Id: Makefile,v 1.1.1.1 2002/08/28 16:10:14 aroll Exp $
+#
+# Makefile for the Xtensa Instruction Set Simulator (ISS)
+# "prom monitor" library routines under Linux.
+#
+# 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 in the main makefile...
+
+obj-y			= io.o console.o setup.o network.o
+
diff --git a/arch/xtensa/platform-iss/console.c b/arch/xtensa/platform-iss/console.c
new file mode 100644
--- /dev/null
+++ b/arch/xtensa/platform-iss/console.c
@@ -0,0 +1,300 @@
+/*
+ * arch/xtensa/platform-iss/console.c
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001-2005 Tensilica Inc.
+ *   Authors	Christian Zankel, Joe Taylor
+ */
+
+#include <linux/module.h>
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/console.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/mm.h>
+#include <linux/major.h>
+#include <linux/param.h>
+#include <linux/serial.h>
+#include <linux/serialP.h>
+#include <linux/console.h>
+
+#include <asm/uaccess.h>
+#include <asm/irq.h>
+
+#include <xtensa/simcall.h>
+
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+
+#ifdef SERIAL_INLINE
+#define _INLINE_ inline
+#endif
+
+#define SERIAL_MAX_NUM_LINES 1
+#define SERIAL_TIMER_VALUE (20 * HZ)
+
+static struct tty_driver *serial_driver;
+static struct timer_list serial_timer;
+
+static DEFINE_SPINLOCK(timer_lock);
+
+int errno;
+
+static int __simc (int a, int b, int c, int d, int e, int f)
+{
+	int ret;
+	__asm__ __volatile__ ("simcall\n"
+			"mov %0, a2\n"
+			"mov %1, a3\n" : "=a" (ret), "=a" (errno)
+			: : "a2", "a3");
+	return ret;
+}
+
+static char *serial_version = "0.1";
+static char *serial_name = "ISS serial driver";
+
+/*
+ * 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 void rs_poll(unsigned long);
+
+static int rs_open(struct tty_struct *tty, struct file * filp)
+{
+	int line = tty->index;
+
+	if ((line < 0) || (line >= SERIAL_MAX_NUM_LINES))
+		return -ENODEV;
+
+	spin_lock(&timer_lock);
+
+	if (tty->count == 1) {
+		init_timer(&serial_timer);
+		serial_timer.data = (unsigned long) tty;
+		serial_timer.function = rs_poll;
+		mod_timer(&serial_timer, jiffies + SERIAL_TIMER_VALUE);
+	}
+	spin_unlock(&timer_lock);
+
+	return 0;
+}
+
+
+/*
+ * ------------------------------------------------------------
+ * iss_serial_close()
+ *
+ * This routine is called when the serial port gets closed.  First, we
+ * wait for the last remaining data to be sent.  Then, we unlink its
+ * async structure from the interrupt chain if necessary, and we free
+ * that IRQ if nothing is left in the chain.
+ * ------------------------------------------------------------
+ */
+static void rs_close(struct tty_struct *tty, struct file * filp)
+{
+	spin_lock(&timer_lock);
+	if (tty->count == 1)
+		del_timer_sync(&serial_timer);
+	spin_unlock(&timer_lock);
+}
+
+
+static int rs_write(struct tty_struct * tty,
+		    const unsigned char *buf, int count)
+{
+	/* see drivers/char/serialX.c to reference original version */
+
+	__simc (SYS_write, 1, (unsigned long)buf, count, 0, 0);
+	return count;
+}
+
+static void rs_poll(unsigned long priv)
+{
+	struct tty_struct* tty = (struct tty_struct*) priv;
+
+	struct timeval tv = { .tv_sec = 0, .tv_usec = 0 };
+	int i = 0;
+	unsigned char c;
+
+	spin_lock(&timer_lock);
+
+	while (__simc(SYS_select_one, 0, XTISS_SELECT_ONE_READ, (int)&tv,0,0)){
+		__simc (SYS_read, 0, (unsigned long)&c, 1, 0, 0);
+		tty->flip.count++;
+		*tty->flip.char_buf_ptr++ = c;
+		*tty->flip.flag_buf_ptr++ = TTY_NORMAL;
+		i++;
+	}
+
+	if (i)
+		tty_flip_buffer_push(tty);
+
+
+	mod_timer(&serial_timer, jiffies + SERIAL_TIMER_VALUE);
+	spin_unlock(&timer_lock);
+}
+
+
+static void rs_put_char(struct tty_struct *tty, unsigned char ch)
+{
+	char buf[2];
+
+	if (!tty)
+		return;
+
+	buf[0] = ch;
+	buf[1] = '\0';		/* Is this NULL necessary? */
+	__simc (SYS_write, 1, (unsigned long) buf, 1, 0, 0);
+}
+
+static void rs_flush_chars(struct tty_struct *tty)
+{
+}
+
+static int rs_write_room(struct tty_struct *tty)
+{
+	/* Let's say iss can always accept 2K characters.. */
+	return 2 * 1024;
+}
+
+static int rs_chars_in_buffer(struct tty_struct *tty)
+{
+	/* the iss doesn't buffer characters */
+	return 0;
+}
+
+static void rs_hangup(struct tty_struct *tty)
+{
+	/* Stub, once again.. */
+}
+
+static void rs_wait_until_sent(struct tty_struct *tty, int timeout)
+{
+	/* Stub, once again.. */
+}
+
+static int rs_read_proc(char *page, char **start, off_t off, int count,
+			int *eof, void *data)
+{
+	int len = 0;
+	off_t begin = 0;
+
+	len += sprintf(page, "serinfo:1.0 driver:%s\n", serial_version);
+	*eof = 1;
+
+	if (off >= len + begin)
+		return 0;
+
+	*start = page + (off - begin);
+	return ((count < begin + len - off) ? count : begin + len - off);
+}
+
+
+static struct tty_operations serial_ops = {
+	.open = rs_open,
+	.close = rs_close,
+	.write = rs_write,
+	.put_char = rs_put_char,
+	.flush_chars = rs_flush_chars,
+	.write_room = rs_write_room,
+	.chars_in_buffer = rs_chars_in_buffer,
+	.hangup = rs_hangup,
+	.wait_until_sent = rs_wait_until_sent,
+	.read_proc = rs_read_proc
+};
+
+int __init rs_init(void)
+{
+	serial_driver = alloc_tty_driver(1);
+
+	printk ("%s %s\n", serial_name, serial_version);
+
+	/* Initialize the tty_driver structure */
+
+	serial_driver->owner = THIS_MODULE;
+	serial_driver->driver_name = "iss_serial";
+	serial_driver->name = "ttyS";
+	serial_driver->major = TTY_MAJOR;
+	serial_driver->minor_start = 64;
+	serial_driver->type = TTY_DRIVER_TYPE_SERIAL;
+	serial_driver->subtype = SERIAL_TYPE_NORMAL;
+	serial_driver->init_termios = tty_std_termios;
+	serial_driver->init_termios.c_cflag =
+		B9600 | CS8 | CREAD | HUPCL | CLOCAL;
+	serial_driver->flags = TTY_DRIVER_REAL_RAW;
+
+	tty_set_operations(serial_driver, &serial_ops);
+
+	if (tty_register_driver(serial_driver))
+		panic("Couldn't register serial driver\n");
+	return 0;
+}
+
+
+static __exit void rs_exit(void)
+{
+	int error;
+
+	if ((error = tty_unregister_driver(serial_driver)))
+		printk("ISS_SERIAL: failed to unregister serial driver (%d)\n",
+		       error);
+	put_tty_driver(serial_driver);
+}
+
+
+/* We use `late_initcall' instead of just `__initcall' as a workaround for
+ * the fact that (1) simcons_tty_init can't be called before tty_init,
+ * (2) tty_init is called via `module_init', (3) if statically linked,
+ * module_init == device_init, and (4) there's no ordering of init lists.
+ * We can do this easily because simcons is always statically linked, but
+ * other tty drivers that depend on tty_init and which must use
+ * `module_init' to declare their init routines are likely to be broken.
+ */
+
+late_initcall(rs_init);
+
+
+#ifdef CONFIG_SERIAL_CONSOLE
+
+static void iss_console_write(struct console *co, const char *s, unsigned count)
+{
+	int len = strlen(s);
+
+	if (s != 0 && *s != 0)
+		__simc (SYS_write, 1, (unsigned long)s,
+			count < len ? count : len,0,0);
+}
+
+static struct tty_driver* iss_console_device(struct console *c, int *index)
+{
+	*index = c->index;
+	return serial_driver;
+}
+
+
+static struct console sercons = {
+	.name = "ttyS",
+	.write = iss_console_write,
+	.device = iss_console_device,
+	.flags = CON_PRINTBUFFER,
+	.index = -1
+};
+
+static int __init iss_console_init(void)
+{
+	register_console(&sercons);
+	return 0;
+}
+
+console_initcall(iss_console_init);
+
+#endif /* CONFIG_SERIAL_CONSOLE */
+
diff --git a/arch/xtensa/platform-iss/io.c b/arch/xtensa/platform-iss/io.c
new file mode 100644
--- /dev/null
+++ b/arch/xtensa/platform-iss/io.c
@@ -0,0 +1,32 @@
+/* This file isn't really needed right now. */
+
+#if 0
+
+#include <asm/io.h>
+#include <xtensa/simcall.h>
+
+extern int __simc ();
+
+
+char iss_serial_getc()
+{
+  char c;
+  __simc( SYS_read, 0, &c, 1 );
+  return c;
+}
+
+void iss_serial_putc( char c )
+{
+  __simc( SYS_write, 1, &c, 1 );
+}
+
+void iss_serial_puts( char *s )
+{
+  if( s != 0 && *s != 0 )
+    __simc( SYS_write, 1, s, strlen(s) );
+}
+
+/*#error Need I/O ports to specific hardware!*/
+
+#endif
+
diff --git a/arch/xtensa/platform-iss/network.c b/arch/xtensa/platform-iss/network.c
new file mode 100644
--- /dev/null
+++ b/arch/xtensa/platform-iss/network.c
@@ -0,0 +1,855 @@
+/*
+ *
+ * arch/xtensa/platform-iss/network.c
+ *
+ * Platform specific initialization.
+ *
+ * Authors: Chris Zankel <chris@zankel.net>
+ * Based on work form the UML team.
+ *
+ * Copyright 2005 Tensilica 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/config.h>
+#include <linux/list.h>
+#include <linux/irq.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+#include <linux/timer.h>
+#include <linux/if_ether.h>
+#include <linux/inetdevice.h>
+#include <linux/init.h>
+#include <linux/if_tun.h>
+#include <linux/etherdevice.h>
+#include <linux/interrupt.h>
+#include <linux/ioctl.h>
+#include <linux/bootmem.h>
+#include <linux/ethtool.h>
+#include <linux/rtnetlink.h>
+#include <linux/timer.h>
+
+#include <xtensa/simcall.h>
+
+#define DRIVER_NAME "iss-netdev"
+#define ETH_MAX_PACKET 1500
+#define ETH_HEADER_OTHER 14
+#define ISS_NET_TIMER_VALUE (2 * HZ)
+
+
+static DEFINE_SPINLOCK(opened_lock);
+static LIST_HEAD(opened);
+
+static DEFINE_SPINLOCK(devices_lock);
+static LIST_HEAD(devices);
+
+/* ------------------------------------------------------------------------- */
+
+/* We currently only support the TUNTAP transport protocol. */
+
+#define TRANSPORT_TUNTAP_NAME "tuntap"
+#define TRANSPORT_TUNTAP_MTU ETH_MAX_PACKET
+
+struct tuntap_info {
+	char dev_name[IFNAMSIZ];
+	int fixed_config;
+	unsigned char gw[ETH_ALEN];
+	int fd;
+};
+
+/* ------------------------------------------------------------------------- */
+
+
+/* This structure contains out private information for the driver. */
+
+struct iss_net_private {
+
+	struct list_head device_list;
+	struct list_head opened_list;
+
+	spinlock_t lock;
+	struct net_device *dev;
+	struct platform_device pdev;
+	struct timer_list tl;
+	struct net_device_stats stats;
+
+	struct timer_list timer;
+	unsigned int timer_val;
+
+	int index;
+	int mtu;
+
+	unsigned char mac[ETH_ALEN];
+	int have_mac;
+
+	struct {
+		union {
+			struct tuntap_info tuntap;
+		} info;
+
+		int (*open)(struct iss_net_private *lp);
+		void (*close)(struct iss_net_private *lp);
+		int (*read)(struct iss_net_private *lp, struct sk_buff **skb);
+		int (*write)(struct iss_net_private *lp, struct sk_buff **skb);
+		unsigned short (*protocol)(struct sk_buff *skb);
+		int (*poll)(struct iss_net_private *lp);
+	} tp;
+
+};
+
+/* ======================= ISS SIMCALL INTERFACE =========================== */
+
+/* Note: __simc must _not_ be declared inline! */
+
+static int errno;
+
+static int __simc (int a, int b, int c, int d, int e, int f)
+{
+	int ret;
+	__asm__ __volatile__ ("simcall\n"
+	    		      "mov %0, a2\n"
+			      "mov %1, a3\n" : "=a" (ret), "=a" (errno)
+			      : : "a2", "a3");
+	return ret;
+}
+
+static int inline simc_open(char *file, int flags, int mode)
+{
+	return __simc(SYS_open, (int) file, flags, mode, 0, 0);
+}
+
+static int inline simc_close(int fd)
+{
+	return __simc(SYS_close, fd, 0, 0, 0, 0);
+}
+
+static int inline simc_ioctl(int fd, int request, void *arg)
+{
+	return __simc(SYS_ioctl, fd, request, (int) arg, 0, 0);
+}
+
+static int inline simc_read(int fd, void *buf, size_t count)
+{
+	return __simc(SYS_read, fd, (int) buf, count, 0, 0);
+}
+
+static int inline simc_write(int fd, void *buf, size_t count)
+{
+	return __simc(SYS_write, fd, (int) buf, count, 0, 0);
+}
+
+static int inline simc_poll(int fd)
+{
+	struct timeval tv = { .tv_sec = 0, .tv_usec = 0 };
+
+	return __simc(SYS_select_one, fd, XTISS_SELECT_ONE_READ, (int)&tv,0,0);
+}
+
+/* ================================ HELPERS ================================ */
+
+
+static char *split_if_spec(char *str, ...)
+{
+	char **arg, *end;
+	va_list ap;
+
+	va_start(ap, str);
+	while ((arg = va_arg(ap, char**)) != NULL) {
+		if (*str == '\0')
+			return NULL;
+		end = strchr(str, ',');
+		if (end != str)
+			*arg = str;
+		if (end == NULL)
+			return NULL;
+		*end ++ = '\0';
+		str = end;
+	}
+	va_end(ap);
+	return str;
+}
+
+
+#if 0
+/* Adjust SKB. */
+
+struct sk_buff *ether_adjust_skb(struct sk_buff *skb, int extra)
+{
+	if ((skb != NULL) && (skb_tailroom(skb) < extra)) {
+		struct sk_buff *skb2;
+
+		skb2 = skb_copy_expand(skb, 0, extra, GFP_ATOMIC);
+		dev_kfree_skb(skb);
+		skb = skb2;
+	}
+	if (skb != NULL)
+		skb_put(skb, extra);
+
+	return skb;
+}
+#endif
+
+/* Return the IP address as a string for a given device. */
+
+static void dev_ip_addr(void *d, char *buf, char *bin_buf)
+{
+	struct net_device *dev = d;
+	struct in_device *ip = dev->ip_ptr;
+	struct in_ifaddr *in;
+	u32 addr;
+
+	if ((ip == NULL) || ((in = ip->ifa_list) == NULL)) {
+		printk(KERN_WARNING "Device not assigned an IP address!\n");
+		return;
+	}
+
+	addr = in->ifa_address;
+	sprintf(buf, "%d.%d.%d.%d", addr & 0xff, (addr >> 8) & 0xff,
+		(addr >> 16) & 0xff, addr >> 24);
+
+	if (bin_buf) {
+		bin_buf[0] = addr & 0xff;
+		bin_buf[1] = (addr >> 8) & 0xff;
+		bin_buf[2] = (addr >> 16) & 0xff;
+		bin_buf[3] = addr >> 24;
+	}
+}
+
+/* Set Ethernet address of the specified device. */
+
+static void inline set_ether_mac(void *d, unsigned char *addr)
+{
+	struct net_device *dev = d;
+	memcpy(dev->dev_addr, addr, ETH_ALEN);
+}
+
+
+/* ======================= TUNTAP TRANSPORT INTERFACE ====================== */
+
+static int tuntap_open(struct iss_net_private *lp)
+{
+	struct ifreq ifr;
+	char *dev_name = lp->tp.info.tuntap.dev_name;
+	int err = -EINVAL;
+	int fd;
+
+	/* We currently only support a fixed configuration. */
+
+	if (!lp->tp.info.tuntap.fixed_config)
+		return -EINVAL;
+
+	if ((fd = simc_open("/dev/net/tun", 02, 0)) < 0) {	/* O_RDWR */
+		printk("Failed to open /dev/net/tun, returned %d "
+		       "(errno = %d)\n", fd, errno);
+		return fd;
+	}
+
+	memset(&ifr, 0, sizeof ifr);
+	ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
+	strlcpy(ifr.ifr_name, dev_name, sizeof ifr.ifr_name - 1);
+
+	if ((err = simc_ioctl(fd, TUNSETIFF, (void*) &ifr)) < 0) {
+		printk("Failed to set interface, returned %d "
+		       "(errno = %d)\n", err, errno);
+		simc_close(fd);
+		return err;
+	}
+
+	lp->tp.info.tuntap.fd = fd;
+	return err;
+}
+
+static void tuntap_close(struct iss_net_private *lp)
+{
+#if 0
+	if (lp->tp.info.tuntap.fixed_config)
+		iter_addresses(lp->tp.info.tuntap.dev, close_addr, lp->host.dev_name);
+#endif
+	simc_close(lp->tp.info.tuntap.fd);
+	lp->tp.info.tuntap.fd = -1;
+}
+
+static int tuntap_read (struct iss_net_private *lp, struct sk_buff **skb)
+{
+#if 0
+	*skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER);
+	if (*skb == NULL)
+		return -ENOMEM;
+#endif
+
+	return simc_read(lp->tp.info.tuntap.fd,
+			(*skb)->data, (*skb)->dev->mtu + ETH_HEADER_OTHER);
+}
+
+static int tuntap_write (struct iss_net_private *lp, struct sk_buff **skb)
+{
+	return simc_write(lp->tp.info.tuntap.fd, (*skb)->data, (*skb)->len);
+}
+
+unsigned short tuntap_protocol(struct sk_buff *skb)
+{
+	return eth_type_trans(skb, skb->dev);
+}
+
+static int tuntap_poll(struct iss_net_private *lp)
+{
+	return simc_poll(lp->tp.info.tuntap.fd);
+}
+
+/*
+ * Currently only a device name is supported.
+ * ethX=tuntap[,[mac address][,[device name]]]
+ */
+
+static int tuntap_probe(struct iss_net_private *lp, int index, char *init)
+{
+	const int len = strlen(TRANSPORT_TUNTAP_NAME);
+	char *dev_name = NULL, *mac_str = NULL, *rem = NULL;
+
+	/* Transport should be 'tuntap': ethX=tuntap,mac,dev_name */
+
+	if (strncmp(init, TRANSPORT_TUNTAP_NAME, len))
+		return 0;
+
+	if (*(init += strlen(TRANSPORT_TUNTAP_NAME)) == ',') {
+		if ((rem=split_if_spec(init+1, &mac_str, &dev_name)) != NULL) {
+			printk("Extra garbage on specification : '%s'\n", rem);
+			return 0;
+		}
+	} else if (*init != '\0') {
+		printk("Invalid argument: %s. Skipping device!\n", init);
+		return 0;
+	}
+
+	if (dev_name) {
+		strncpy(lp->tp.info.tuntap.dev_name, dev_name,
+			 sizeof lp->tp.info.tuntap.dev_name);
+		lp->tp.info.tuntap.fixed_config = 1;
+	} else
+		strcpy(lp->tp.info.tuntap.dev_name, TRANSPORT_TUNTAP_NAME);
+
+
+#if 0
+	if (setup_etheraddr(mac_str, lp->mac))
+		lp->have_mac = 1;
+#endif
+	lp->mtu = TRANSPORT_TUNTAP_MTU;
+
+	//lp->info.tuntap.gate_addr = gate_addr;
+
+	lp->tp.info.tuntap.fd = -1;
+
+	lp->tp.open = tuntap_open;
+	lp->tp.close = tuntap_close;
+	lp->tp.read = tuntap_read;
+	lp->tp.write = tuntap_write;
+	lp->tp.protocol = tuntap_protocol;
+	lp->tp.poll = tuntap_poll;
+
+	printk("TUN/TAP backend - ");
+#if 0
+	if (lp->host.gate_addr != NULL)
+		printk("IP = %s", lp->host.gate_addr);
+#endif
+	printk("\n");
+
+	return 1;
+}
+
+/* ================================ ISS NET ================================ */
+
+static int iss_net_rx(struct net_device *dev)
+{
+	struct iss_net_private *lp = dev->priv;
+	int pkt_len;
+	struct sk_buff *skb;
+
+	/* Check if there is any new data. */
+
+	if (lp->tp.poll(lp) == 0)
+		return 0;
+
+	/* Try to allocate memory, if it fails, try again next round. */
+
+	if ((skb = dev_alloc_skb(dev->mtu + 2 + ETH_HEADER_OTHER)) == NULL) {
+		lp->stats.rx_dropped++;
+		return 0;
+	}
+
+	skb_reserve(skb, 2);
+
+	/* Setup skb */
+
+	skb->dev = dev;
+	skb->mac.raw = skb->data;
+	pkt_len = lp->tp.read(lp, &skb);
+	skb_put(skb, pkt_len);
+
+	if (pkt_len > 0) {
+		skb_trim(skb, pkt_len);
+		skb->protocol = lp->tp.protocol(skb);
+	//	netif_rx(skb);
+		netif_rx_ni(skb);
+
+		lp->stats.rx_bytes += skb->len;
+		lp->stats.rx_packets++;
+		return pkt_len;
+	}
+	kfree_skb(skb);
+	return pkt_len;
+}
+
+static int iss_net_poll(void)
+{
+	struct list_head *ele;
+	int err, ret = 0;
+
+	spin_lock(&opened_lock);
+
+	list_for_each(ele, &opened) {
+		struct iss_net_private *lp;
+
+		lp = list_entry(ele, struct iss_net_private, opened_list);
+
+		if (!netif_running(lp->dev))
+			break;
+
+		spin_lock(&lp->lock);
+
+		while ((err = iss_net_rx(lp->dev)) > 0)
+			ret++;
+
+		spin_unlock(&lp->lock);
+
+		if (err < 0) {
+			printk(KERN_ERR "Device '%s' read returned %d, "
+			       "shutting it down\n", lp->dev->name, err);
+			dev_close(lp->dev);
+		} else {
+			// FIXME reactivate_fd(lp->fd, ISS_ETH_IRQ);
+		}
+	}
+
+	spin_unlock(&opened_lock);
+	return ret;
+}
+
+
+static void iss_net_timer(unsigned long priv)
+{
+	struct iss_net_private* lp = (struct iss_net_private*) priv;
+
+	spin_lock(&lp->lock);
+
+	iss_net_poll();
+
+	mod_timer(&lp->timer, jiffies + lp->timer_val);
+
+	spin_unlock(&lp->lock);
+}
+
+
+static int iss_net_open(struct net_device *dev)
+{
+	struct iss_net_private *lp = dev->priv;
+	char addr[sizeof "255.255.255.255\0"];
+	int err;
+
+	spin_lock(&lp->lock);
+
+	if ((err = lp->tp.open(lp)) < 0)
+		goto out;
+
+	if (!lp->have_mac) {
+		dev_ip_addr(dev, addr, &lp->mac[2]);
+		set_ether_mac(dev, lp->mac);
+	}
+
+	netif_start_queue(dev);
+
+	/* clear buffer - it can happen that the host side of the interface
+	 * is full when we gethere. In this case, new data is never queued,
+	 * SIGIOs never arrive, and the net never works.
+	 */
+	while ((err = iss_net_rx(dev)) > 0)
+		;
+
+	spin_lock(&opened_lock);
+	list_add(&lp->opened_list, &opened);
+	spin_unlock(&opened_lock);
+
+	init_timer(&lp->timer);
+	lp->timer_val = ISS_NET_TIMER_VALUE;
+	lp->timer.data = (unsigned long) lp;
+	lp->timer.function = iss_net_timer;
+	mod_timer(&lp->timer, jiffies + lp->timer_val);
+
+out:
+	spin_unlock(&lp->lock);
+	return err;
+}
+
+static int iss_net_close(struct net_device *dev)
+{
+	struct iss_net_private *lp = dev->priv;
+printk("iss_net_close!\n");
+	netif_stop_queue(dev);
+	spin_lock(&lp->lock);
+
+	spin_lock(&opened_lock);
+	list_del(&opened);
+	spin_unlock(&opened_lock);
+
+	del_timer_sync(&lp->timer);
+
+	lp->tp.close(lp);
+
+	spin_unlock(&lp->lock);
+	return 0;
+}
+
+static int iss_net_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	struct iss_net_private *lp = dev->priv;
+	unsigned long flags;
+	int len;
+
+	netif_stop_queue(dev);
+	spin_lock_irqsave(&lp->lock, flags);
+
+	len = lp->tp.write(lp, &skb);
+
+	if (len == skb->len) {
+		lp->stats.tx_packets++;
+		lp->stats.tx_bytes += skb->len;
+		dev->trans_start = jiffies;
+		netif_start_queue(dev);
+
+		/* this is normally done in the interrupt when tx finishes */
+		netif_wake_queue(dev);
+
+	} else if (len == 0) {
+		netif_start_queue(dev);
+		lp->stats.tx_dropped++;
+
+	} else {
+		netif_start_queue(dev);
+		printk(KERN_ERR "iss_net_start_xmit: failed(%d)\n", len);
+	}
+
+	spin_unlock_irqrestore(&lp->lock, flags);
+
+	dev_kfree_skb(skb);
+	return 0;
+}
+
+
+static struct net_device_stats *iss_net_get_stats(struct net_device *dev)
+{
+	struct iss_net_private *lp = dev->priv;
+	return &lp->stats;
+}
+
+static void iss_net_set_multicast_list(struct net_device *dev)
+{
+#if 0
+	if (dev->flags & IFF_PROMISC)
+		return;
+	else if (dev->mc_count)
+		dev->flags |= IFF_ALLMULTI;
+	else
+		dev->flags &= ~IFF_ALLMULTI;
+#endif
+}
+
+static void iss_net_tx_timeout(struct net_device *dev)
+{
+#if 0
+	dev->trans_start = jiffies;
+	netif_wake_queue(dev);
+#endif
+}
+
+static int iss_net_set_mac(struct net_device *dev, void *addr)
+{
+#if 0
+	struct iss_net_private *lp = dev->priv;
+	struct sockaddr *hwaddr = addr;
+
+	spin_lock(&lp->lock);
+	memcpy(dev->dev_addr, hwaddr->sa_data, ETH_ALEN);
+	spin_unlock(&lp->lock);
+#endif
+
+	return 0;
+}
+
+static int iss_net_change_mtu(struct net_device *dev, int new_mtu)
+{
+#if 0
+	struct iss_net_private *lp = dev->priv;
+	int err = 0;
+
+	spin_lock(&lp->lock);
+
+	// FIXME not needed new_mtu = transport_set_mtu(new_mtu, &lp->user);
+
+	if (new_mtu < 0)
+		err = new_mtu;
+	else
+		dev->mtu = new_mtu;
+
+	spin_unlock(&lp->lock);
+	return err;
+#endif
+	return -EINVAL;
+}
+
+static int iss_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+{
+#if 0
+	static const struct ethtool_drvinfo info = {
+		.cmd     = ETHTOOL_GDRVINFO,
+		.driver  = DRIVER_NAME,
+		.version = "42",
+	};
+	void *useraddr;
+	u32 ethcmd;
+
+	switch (cmd) {
+	case SIOCETHTOOL:
+		useraddr = ifr->ifr_data;
+		if (copy_from_user(&ethcmd, useraddr, sizeof(ethcmd)))
+			return -EFAULT;
+
+		switch (ethcmd) {
+			case ETHTOOL_GDRVINFO:
+				if (copy_to_user(useraddr, &info, sizeof(info)))
+					return -EFAULT;
+				return 0;
+			default:
+				return -EOPNOTSUPP;
+		}
+	default:
+		return -EINVAL;
+	}
+#endif
+	return -EINVAL;
+}
+
+void iss_net_user_timer_expire(unsigned long _conn)
+{
+}
+
+
+static struct device_driver iss_net_driver = {
+	.name  = DRIVER_NAME,
+	.bus   = &platform_bus_type,
+};
+
+static int driver_registered;
+
+static int iss_net_configure(int index, char *init)
+{
+	struct net_device *dev;
+	struct iss_net_private *lp;
+	int err;
+
+	if ((dev = alloc_etherdev(sizeof *lp)) == NULL) {
+		printk(KERN_ERR "eth_configure: failed to allocate device\n");
+		return 1;
+	}
+
+	/* Initialize private element. */
+
+	lp = dev->priv;
+	*lp = ((struct iss_net_private) {
+		.device_list		= LIST_HEAD_INIT(lp->device_list),
+		.opened_list		= LIST_HEAD_INIT(lp->opened_list),
+		.lock			= SPIN_LOCK_UNLOCKED,
+		.dev			= dev,
+		.index			= index,
+		//.fd                   = -1,
+		.mac			= { 0xfe, 0xfd, 0x0, 0x0, 0x0, 0x0 },
+		.have_mac		= 0,
+		});
+
+	/*
+	 * Try all transport protocols.
+	 * Note: more protocols can be added by adding '&& !X_init(lp, eth)'.
+	 */
+
+	if (!tuntap_probe(lp, index, init)) {
+		printk("Invalid arguments. Skipping device!\n");
+		goto errout;
+	}
+
+	printk(KERN_INFO "Netdevice %d ", index);
+	if (lp->have_mac)
+		printk("(%02x:%02x:%02x:%02x:%02x:%02x) ",
+				lp->mac[0], lp->mac[1],
+				lp->mac[2], lp->mac[3],
+				lp->mac[4], lp->mac[5]);
+	printk(": ");
+
+	/* sysfs register */
+
+	if (!driver_registered) {
+		driver_register(&iss_net_driver);
+		driver_registered = 1;
+	}
+
+	spin_lock(&devices_lock);
+	list_add(&lp->device_list, &devices);
+	spin_unlock(&devices_lock);
+
+	lp->pdev.id = index;
+	lp->pdev.name = DRIVER_NAME;
+	platform_device_register(&lp->pdev);
+	SET_NETDEV_DEV(dev,&lp->pdev.dev);
+
+	/*
+	 * If this name ends up conflicting with an existing registered
+	 * netdevice, that is OK, register_netdev{,ice}() will notice this
+	 * and fail.
+	 */
+	snprintf(dev->name, sizeof dev->name, "eth%d", index);
+
+	dev->mtu = lp->mtu;
+	dev->open = iss_net_open;
+	dev->hard_start_xmit = iss_net_start_xmit;
+	dev->stop = iss_net_close;
+	dev->get_stats = iss_net_get_stats;
+	dev->set_multicast_list = iss_net_set_multicast_list;
+	dev->tx_timeout = iss_net_tx_timeout;
+	dev->set_mac_address = iss_net_set_mac;
+	dev->change_mtu = iss_net_change_mtu;
+	dev->do_ioctl = iss_net_ioctl;
+	dev->watchdog_timeo = (HZ >> 1);
+	dev->irq = -1;
+
+	rtnl_lock();
+	err = register_netdevice(dev);
+	rtnl_unlock();
+
+	if (err) {
+		printk("Error registering net device!\n");
+		/* XXX: should we call ->remove() here? */
+		free_netdev(dev);
+		return 1;
+	}
+
+	init_timer(&lp->tl);
+	lp->tl.function = iss_net_user_timer_expire;
+
+#if 0
+	if (lp->have_mac)
+		set_ether_mac(dev, lp->mac);
+#endif
+	return 0;
+
+errout:
+	// FIXME: unregister; free, etc..
+	return -EIO;
+
+}
+
+/* ------------------------------------------------------------------------- */
+
+/* Filled in during early boot */
+
+struct list_head eth_cmd_line = LIST_HEAD_INIT(eth_cmd_line);
+
+struct iss_net_init {
+	struct list_head list;
+	char *init;		/* init string */
+	int index;
+};
+
+/*
+ * Parse the command line and look for 'ethX=...' fields, and register all
+ * those fields. They will be later initialized in iss_net_init.
+ */
+
+#define ERR KERN_ERR "iss_net_setup: "
+
+static int iss_net_setup(char *str)
+{
+	struct iss_net_private *device = NULL;
+	struct iss_net_init *new;
+	struct list_head *ele;
+	char *end;
+	int n;
+
+	n = simple_strtoul(str, &end, 0);
+	if (end == str) {
+		printk(ERR "Failed to parse '%s'\n", str);
+		return 1;
+	}
+	if (n < 0) {
+		printk(ERR "Device %d is negative\n", n);
+		return 1;
+	}
+	if (*(str = end) != '=') {
+		printk(ERR "Expected '=' after device number\n");
+		return 1;
+	}
+
+	spin_lock(&devices_lock);
+
+	list_for_each(ele, &devices) {
+		device = list_entry(ele, struct iss_net_private, device_list);
+		if (device->index == n)
+			break;
+	}
+
+	spin_unlock(&devices_lock);
+
+	if (device && device->index == n) {
+		printk(ERR "Device %d already configured\n", n);
+		return 1;
+	}
+
+	if ((new = alloc_bootmem(sizeof new)) == NULL) {
+		printk("Alloc_bootmem failed\n");
+		return 1;
+	}
+
+	INIT_LIST_HEAD(&new->list);
+	new->index = n;
+	new->init = str + 1;
+
+	list_add_tail(&new->list, &eth_cmd_line);
+	return 1;
+}
+
+#undef ERR
+
+__setup("eth", iss_net_setup);
+
+/*
+ * Initialize all ISS Ethernet devices previously registered in iss_net_setup.
+ */
+
+static int iss_net_init(void)
+{
+	struct list_head *ele, *next;
+
+	/* Walk through all Ethernet devices specified in the command line. */
+
+	list_for_each_safe(ele, next, &eth_cmd_line) {
+		struct iss_net_init *eth;
+		eth = list_entry(ele, struct iss_net_init, list);
+		iss_net_configure(eth->index, eth->init);
+	}
+
+	return 1;
+}
+
+module_init(iss_net_init);
+
diff --git a/arch/xtensa/platform-iss/setup.c b/arch/xtensa/platform-iss/setup.c
new file mode 100644
--- /dev/null
+++ b/arch/xtensa/platform-iss/setup.c
@@ -0,0 +1,112 @@
+/*
+ *
+ * arch/xtensa/platform-iss/setup.c
+ *
+ * Platform specific initialization.
+ *
+ * Authors: Chris Zankel <chris@zankel.net>
+ *          Joe Taylor <joe@tensilica.com>
+ *
+ * Copyright 2001 - 2005 Tensilica 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/config.h>
+#include <linux/stddef.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/reboot.h>
+#include <linux/pci.h>
+#include <linux/kdev_t.h>
+#include <linux/types.h>
+#include <linux/major.h>
+#include <linux/blkdev.h>
+#include <linux/console.h>
+#include <linux/delay.h>
+#include <linux/stringify.h>
+#include <linux/notifier.h>
+
+#include <asm/platform.h>
+#include <asm/bootparam.h>
+
+
+void __init platform_init(bp_tag_t* bootparam)
+{
+
+}
+
+void platform_halt(void)
+{
+	printk (" ** Called platform_halt(), looping forever! **\n");
+	while (1);
+}
+
+void platform_power_off(void)
+{
+	printk (" ** Called platform_power_off(), looping forever! **\n");
+	while (1);
+}
+void platform_restart(void)
+{
+	/* Flush and reset the mmu, simulate a processor reset, and
+	 * jump to the reset vector. */
+
+	__asm__ __volatile__("movi	a2, 15\n\t"
+			     "wsr	a2, " __stringify(ICOUNTLEVEL) "\n\t"
+			     "movi	a2, 0\n\t"
+			     "wsr	a2, " __stringify(ICOUNT) "\n\t"
+			     "wsr	a2, " __stringify(IBREAKENABLE) "\n\t"
+			     "wsr	a2, " __stringify(LCOUNT) "\n\t"
+			     "movi	a2, 0x1f\n\t"
+			     "wsr	a2, " __stringify(PS) "\n\t"
+			     "isync\n\t"
+			     "jx	%0\n\t"
+			     :
+			     : "a" (XCHAL_RESET_VECTOR_VADDR)
+			     : "a2");
+
+	/* control never gets here */
+}
+
+extern void iss_net_poll(void);
+
+const char twirl[]="|/-\\|/-\\";
+
+void platform_heartbeat(void)
+{
+#if 0
+	static int i = 0, j = 0;
+
+	if (--i < 0) {
+		i = 99;
+		printk("\r%c\r", twirl[j++]);
+		if (j == 8)
+			j = 0;
+	}
+#endif
+}
+
+
+
+static int
+iss_panic_event(struct notifier_block *this, unsigned long event, void *ptr)
+{
+	__asm__ __volatile__("movi a2, -1; simcall\n");
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block iss_panic_block = {
+	iss_panic_event,
+	NULL,
+	0
+};
+
+void __init platform_setup(char **p_cmdline)
+{
+	notifier_chain_register(&panic_notifier_list, &iss_panic_block);
+}
diff --git a/crypto/Kconfig b/crypto/Kconfig
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -146,7 +146,7 @@ config CRYPTO_SERPENT
 
 config CRYPTO_AES
 	tristate "AES cipher algorithms"
-	depends on CRYPTO && !((X86 || UML_X86) && !64BIT)
+	depends on CRYPTO && !(X86 || UML_X86)
 	help
 	  AES cipher algorithms (FIPS-197). AES uses the Rijndael 
 	  algorithm.
@@ -184,6 +184,26 @@ config CRYPTO_AES_586
 
 	  See <http://csrc.nist.gov/encryption/aes/> for more information.
 
+config CRYPTO_AES_X86_64
+	tristate "AES cipher algorithms (x86_64)"
+	depends on CRYPTO && ((X86 || UML_X86) && 64BIT)
+	help
+	  AES cipher algorithms (FIPS-197). AES uses the Rijndael 
+	  algorithm.
+
+	  Rijndael appears to be consistently a very good performer in
+	  both hardware and software across a wide range of computing 
+	  environments regardless of its use in feedback or non-feedback 
+	  modes. Its key setup time is excellent, and its key agility is 
+	  good. Rijndael's very low memory requirements make it very well 
+	  suited for restricted-space environments, in which it also 
+	  demonstrates excellent performance. Rijndael's operations are 
+	  among the easiest to defend against power and timing attacks.	
+
+	  The AES specifies three key sizes: 128, 192 and 256 bits	  
+
+	  See <http://csrc.nist.gov/encryption/aes/> for more information.
+
 config CRYPTO_CAST5
 	tristate "CAST5 (CAST-128) cipher algorithm"
 	depends on CRYPTO
diff --git a/crypto/aes.c b/crypto/aes.c
--- a/crypto/aes.c
+++ b/crypto/aes.c
@@ -67,7 +67,7 @@
 /*
  * #define byte(x, nr) ((unsigned char)((x) >> (nr*8))) 
  */
-inline static u8
+static inline u8
 byte(const u32 x, const unsigned n)
 {
 	return x >> (n << 3);
diff --git a/crypto/api.c b/crypto/api.c
--- a/crypto/api.c
+++ b/crypto/api.c
@@ -13,9 +13,12 @@
  * any later version.
  *
  */
+
+#include <linux/compiler.h>
 #include <linux/init.h>
 #include <linux/crypto.h>
 #include <linux/errno.h>
+#include <linux/kmod.h>
 #include <linux/rwsem.h>
 #include <linux/slab.h>
 #include "internal.h"
@@ -33,7 +36,7 @@ static inline void crypto_alg_put(struct
 	module_put(alg->cra_module);
 }
 
-struct crypto_alg *crypto_alg_lookup(const char *name)
+static struct crypto_alg *crypto_alg_lookup(const char *name)
 {
 	struct crypto_alg *q, *alg = NULL;
 
@@ -54,6 +57,13 @@ struct crypto_alg *crypto_alg_lookup(con
 	return alg;
 }
 
+/* A far more intelligent version of this is planned.  For now, just
+ * try an exact match on the name of the algorithm. */
+static inline struct crypto_alg *crypto_alg_mod_lookup(const char *name)
+{
+	return try_then_request_module(crypto_alg_lookup(name), name);
+}
+
 static int crypto_init_flags(struct crypto_tfm *tfm, u32 flags)
 {
 	tfm->crt_flags = 0;
@@ -117,20 +127,46 @@ static void crypto_exit_ops(struct crypt
 	}
 }
 
+static unsigned int crypto_ctxsize(struct crypto_alg *alg, int flags)
+{
+	unsigned int len;
+
+	switch (alg->cra_flags & CRYPTO_ALG_TYPE_MASK) {
+	default:
+		BUG();
+
+	case CRYPTO_ALG_TYPE_CIPHER:
+		len = crypto_cipher_ctxsize(alg, flags);
+		break;
+		
+	case CRYPTO_ALG_TYPE_DIGEST:
+		len = crypto_digest_ctxsize(alg, flags);
+		break;
+		
+	case CRYPTO_ALG_TYPE_COMPRESS:
+		len = crypto_compress_ctxsize(alg, flags);
+		break;
+	}
+
+	return len + alg->cra_alignmask;
+}
+
 struct crypto_tfm *crypto_alloc_tfm(const char *name, u32 flags)
 {
 	struct crypto_tfm *tfm = NULL;
 	struct crypto_alg *alg;
+	unsigned int tfm_size;
 
 	alg = crypto_alg_mod_lookup(name);
 	if (alg == NULL)
 		goto out;
-	
-	tfm = kmalloc(sizeof(*tfm) + alg->cra_ctxsize, GFP_KERNEL);
+
+	tfm_size = sizeof(*tfm) + crypto_ctxsize(alg, flags);
+	tfm = kmalloc(tfm_size, GFP_KERNEL);
 	if (tfm == NULL)
 		goto out_put;
 
-	memset(tfm, 0, sizeof(*tfm) + alg->cra_ctxsize);
+	memset(tfm, 0, tfm_size);
 	
 	tfm->__crt_alg = alg;
 	
@@ -155,8 +191,14 @@ out:
 
 void crypto_free_tfm(struct crypto_tfm *tfm)
 {
-	struct crypto_alg *alg = tfm->__crt_alg;
-	int size = sizeof(*tfm) + alg->cra_ctxsize;
+	struct crypto_alg *alg;
+	int size;
+
+	if (unlikely(!tfm))
+		return;
+
+	alg = tfm->__crt_alg;
+	size = sizeof(*tfm) + alg->cra_ctxsize;
 
 	crypto_exit_ops(tfm);
 	crypto_alg_put(alg);
@@ -168,6 +210,12 @@ int crypto_register_alg(struct crypto_al
 {
 	int ret = 0;
 	struct crypto_alg *q;
+
+	if (alg->cra_alignmask & (alg->cra_alignmask + 1))
+		return -EINVAL;
+
+	if (alg->cra_alignmask > PAGE_SIZE)
+		return -EINVAL;
 	
 	down_write(&crypto_alg_sem);
 	
diff --git a/crypto/cipher.c b/crypto/cipher.c
--- a/crypto/cipher.c
+++ b/crypto/cipher.c
@@ -4,6 +4,7 @@
  * Cipher operations.
  *
  * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
+ * Copyright (c) 2005 Herbert Xu <herbert@gondor.apana.org.au>
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -22,10 +23,6 @@
 #include "internal.h"
 #include "scatterwalk.h"
 
-typedef void (cryptfn_t)(void *, u8 *, const u8 *);
-typedef void (procfn_t)(struct crypto_tfm *, u8 *,
-                        u8*, cryptfn_t, void *);
-
 static inline void xor_64(u8 *a, const u8 *b)
 {
 	((u32 *)a)[0] ^= ((u32 *)b)[0];
@@ -39,63 +36,70 @@ static inline void xor_128(u8 *a, const 
 	((u32 *)a)[2] ^= ((u32 *)b)[2];
 	((u32 *)a)[3] ^= ((u32 *)b)[3];
 }
- 
-static inline void *prepare_src(struct scatter_walk *walk, int bsize,
-				void *tmp, int in_place)
+
+static unsigned int crypt_slow(const struct cipher_desc *desc,
+			       struct scatter_walk *in,
+			       struct scatter_walk *out, unsigned int bsize)
 {
-	void *src = walk->data;
-	int n = bsize;
+	unsigned long alignmask = crypto_tfm_alg_alignmask(desc->tfm);
+	u8 buffer[bsize * 2 + alignmask];
+	u8 *src = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1);
+	u8 *dst = src + bsize;
+	unsigned int n;
 
-	if (unlikely(scatterwalk_across_pages(walk, bsize))) {
-		src = tmp;
-		n = scatterwalk_copychunks(src, walk, bsize, 0);
-	}
-	scatterwalk_advance(walk, n);
-	return src;
+	n = scatterwalk_copychunks(src, in, bsize, 0);
+	scatterwalk_advance(in, n);
+
+	desc->prfn(desc, dst, src, bsize);
+
+	n = scatterwalk_copychunks(dst, out, bsize, 1);
+	scatterwalk_advance(out, n);
+
+	return bsize;
 }
 
-static inline void *prepare_dst(struct scatter_walk *walk, int bsize,
-				void *tmp, int in_place)
+static inline unsigned int crypt_fast(const struct cipher_desc *desc,
+				      struct scatter_walk *in,
+				      struct scatter_walk *out,
+				      unsigned int nbytes, u8 *tmp)
 {
-	void *dst = walk->data;
+	u8 *src, *dst;
+
+	src = in->data;
+	dst = scatterwalk_samebuf(in, out) ? src : out->data;
 
-	if (unlikely(scatterwalk_across_pages(walk, bsize)) || in_place)
+	if (tmp) {
+		memcpy(tmp, in->data, nbytes);
+		src = tmp;
 		dst = tmp;
-	return dst;
-}
+	}
 
-static inline void complete_src(struct scatter_walk *walk, int bsize,
-				void *src, int in_place)
-{
-}
+	nbytes = desc->prfn(desc, dst, src, nbytes);
 
-static inline void complete_dst(struct scatter_walk *walk, int bsize,
-				void *dst, int in_place)
-{
-	int n = bsize;
+	if (tmp)
+		memcpy(out->data, tmp, nbytes);
+
+	scatterwalk_advance(in, nbytes);
+	scatterwalk_advance(out, nbytes);
 
-	if (unlikely(scatterwalk_across_pages(walk, bsize)))
-		n = scatterwalk_copychunks(dst, walk, bsize, 1);
-	else if (in_place)
-		memcpy(walk->data, dst, bsize);
-	scatterwalk_advance(walk, n);
+	return nbytes;
 }
 
 /* 
  * Generic encrypt/decrypt wrapper for ciphers, handles operations across
  * multiple page boundaries by using temporary blocks.  In user context,
- * the kernel is given a chance to schedule us once per block.
+ * the kernel is given a chance to schedule us once per page.
  */
-static int crypt(struct crypto_tfm *tfm,
+static int crypt(const struct cipher_desc *desc,
 		 struct scatterlist *dst,
 		 struct scatterlist *src,
-                 unsigned int nbytes, cryptfn_t crfn,
-                 procfn_t prfn, void *info)
+		 unsigned int nbytes)
 {
 	struct scatter_walk walk_in, walk_out;
+	struct crypto_tfm *tfm = desc->tfm;
 	const unsigned int bsize = crypto_tfm_alg_blocksize(tfm);
-	u8 tmp_src[bsize];
-	u8 tmp_dst[bsize];
+	unsigned int alignmask = crypto_tfm_alg_alignmask(tfm);
+	unsigned long buffer = 0;
 
 	if (!nbytes)
 		return 0;
@@ -109,64 +113,144 @@ static int crypt(struct crypto_tfm *tfm,
 	scatterwalk_start(&walk_out, dst);
 
 	for(;;) {
-		u8 *src_p, *dst_p;
-		int in_place;
+		unsigned int n = nbytes;
+		u8 *tmp = NULL;
+
+		if (!scatterwalk_aligned(&walk_in, alignmask) ||
+		    !scatterwalk_aligned(&walk_out, alignmask)) {
+			if (!buffer) {
+				buffer = __get_free_page(GFP_ATOMIC);
+				if (!buffer)
+					n = 0;
+			}
+			tmp = (u8 *)buffer;
+		}
 
 		scatterwalk_map(&walk_in, 0);
 		scatterwalk_map(&walk_out, 1);
 
-		in_place = scatterwalk_samebuf(&walk_in, &walk_out);
+		n = scatterwalk_clamp(&walk_in, n);
+		n = scatterwalk_clamp(&walk_out, n);
+
+		if (likely(n >= bsize))
+			n = crypt_fast(desc, &walk_in, &walk_out, n, tmp);
+		else
+			n = crypt_slow(desc, &walk_in, &walk_out, bsize);
 
-		do {
-			src_p = prepare_src(&walk_in, bsize, tmp_src,
-					    in_place);
-			dst_p = prepare_dst(&walk_out, bsize, tmp_dst,
-					    in_place);
-
-			prfn(tfm, dst_p, src_p, crfn, info);
-
-			complete_src(&walk_in, bsize, src_p, in_place);
-			complete_dst(&walk_out, bsize, dst_p, in_place);
-
-			nbytes -= bsize;
-		} while (nbytes &&
-			 !scatterwalk_across_pages(&walk_in, bsize) &&
-			 !scatterwalk_across_pages(&walk_out, bsize));
+		nbytes -= n;
 
 		scatterwalk_done(&walk_in, 0, nbytes);
 		scatterwalk_done(&walk_out, 1, nbytes);
 
 		if (!nbytes)
-			return 0;
+			break;
 
 		crypto_yield(tfm);
 	}
+
+	if (buffer)
+		free_page(buffer);
+
+	return 0;
+}
+
+static int crypt_iv_unaligned(struct cipher_desc *desc,
+			      struct scatterlist *dst,
+			      struct scatterlist *src,
+			      unsigned int nbytes)
+{
+	struct crypto_tfm *tfm = desc->tfm;
+	unsigned long alignmask = crypto_tfm_alg_alignmask(tfm);
+	u8 *iv = desc->info;
+
+	if (unlikely(((unsigned long)iv & alignmask))) {
+		unsigned int ivsize = tfm->crt_cipher.cit_ivsize;
+		u8 buffer[ivsize + alignmask];
+		u8 *tmp = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1);
+		int err;
+
+		desc->info = memcpy(tmp, iv, ivsize);
+		err = crypt(desc, dst, src, nbytes);
+		memcpy(iv, tmp, ivsize);
+
+		return err;
+	}
+
+	return crypt(desc, dst, src, nbytes);
 }
 
-static void cbc_process_encrypt(struct crypto_tfm *tfm, u8 *dst, u8 *src,
-				cryptfn_t fn, void *info)
+static unsigned int cbc_process_encrypt(const struct cipher_desc *desc,
+					u8 *dst, const u8 *src,
+					unsigned int nbytes)
 {
-	u8 *iv = info;
+	struct crypto_tfm *tfm = desc->tfm;
+	void (*xor)(u8 *, const u8 *) = tfm->crt_u.cipher.cit_xor_block;
+	int bsize = crypto_tfm_alg_blocksize(tfm);
+
+	void (*fn)(void *, u8 *, const u8 *) = desc->crfn;
+	u8 *iv = desc->info;
+	unsigned int done = 0;
+
+	do {
+		xor(iv, src);
+		fn(crypto_tfm_ctx(tfm), dst, iv);
+		memcpy(iv, dst, bsize);
 
-	tfm->crt_u.cipher.cit_xor_block(iv, src);
-	fn(crypto_tfm_ctx(tfm), dst, iv);
-	memcpy(iv, dst, crypto_tfm_alg_blocksize(tfm));
+		src += bsize;
+		dst += bsize;
+	} while ((done += bsize) < nbytes);
+
+	return done;
 }
 
-static void cbc_process_decrypt(struct crypto_tfm *tfm, u8 *dst, u8 *src,
-				cryptfn_t fn, void *info)
+static unsigned int cbc_process_decrypt(const struct cipher_desc *desc,
+					u8 *dst, const u8 *src,
+					unsigned int nbytes)
 {
-	u8 *iv = info;
+	struct crypto_tfm *tfm = desc->tfm;
+	void (*xor)(u8 *, const u8 *) = tfm->crt_u.cipher.cit_xor_block;
+	int bsize = crypto_tfm_alg_blocksize(tfm);
+
+	u8 stack[src == dst ? bsize : 0];
+	u8 *buf = stack;
+	u8 **dst_p = src == dst ? &buf : &dst;
+
+	void (*fn)(void *, u8 *, const u8 *) = desc->crfn;
+	u8 *iv = desc->info;
+	unsigned int done = 0;
 
-	fn(crypto_tfm_ctx(tfm), dst, src);
-	tfm->crt_u.cipher.cit_xor_block(dst, iv);
-	memcpy(iv, src, crypto_tfm_alg_blocksize(tfm));
+	do {
+		u8 *tmp_dst = *dst_p;
+
+		fn(crypto_tfm_ctx(tfm), tmp_dst, src);
+		xor(tmp_dst, iv);
+		memcpy(iv, src, bsize);
+		if (tmp_dst != dst)
+			memcpy(dst, tmp_dst, bsize);
+
+		src += bsize;
+		dst += bsize;
+	} while ((done += bsize) < nbytes);
+
+	return done;
 }
 
-static void ecb_process(struct crypto_tfm *tfm, u8 *dst, u8 *src,
-			cryptfn_t fn, void *info)
+static unsigned int ecb_process(const struct cipher_desc *desc, u8 *dst,
+				const u8 *src, unsigned int nbytes)
 {
-	fn(crypto_tfm_ctx(tfm), dst, src);
+	struct crypto_tfm *tfm = desc->tfm;
+	int bsize = crypto_tfm_alg_blocksize(tfm);
+	void (*fn)(void *, u8 *, const u8 *) = desc->crfn;
+	unsigned int done = 0;
+
+	do {
+		fn(crypto_tfm_ctx(tfm), dst, src);
+
+		src += bsize;
+		dst += bsize;
+	} while ((done += bsize) < nbytes);
+
+	return done;
 }
 
 static int setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen)
@@ -185,9 +269,14 @@ static int ecb_encrypt(struct crypto_tfm
 		       struct scatterlist *dst,
                        struct scatterlist *src, unsigned int nbytes)
 {
-	return crypt(tfm, dst, src, nbytes,
-	             tfm->__crt_alg->cra_cipher.cia_encrypt,
-	             ecb_process, NULL);
+	struct cipher_desc desc;
+	struct cipher_alg *cipher = &tfm->__crt_alg->cra_cipher;
+
+	desc.tfm = tfm;
+	desc.crfn = cipher->cia_encrypt;
+	desc.prfn = cipher->cia_encrypt_ecb ?: ecb_process;
+
+	return crypt(&desc, dst, src, nbytes);
 }
 
 static int ecb_decrypt(struct crypto_tfm *tfm,
@@ -195,9 +284,14 @@ static int ecb_decrypt(struct crypto_tfm
                        struct scatterlist *src,
 		       unsigned int nbytes)
 {
-	return crypt(tfm, dst, src, nbytes,
-	             tfm->__crt_alg->cra_cipher.cia_decrypt,
-	             ecb_process, NULL);
+	struct cipher_desc desc;
+	struct cipher_alg *cipher = &tfm->__crt_alg->cra_cipher;
+
+	desc.tfm = tfm;
+	desc.crfn = cipher->cia_decrypt;
+	desc.prfn = cipher->cia_decrypt_ecb ?: ecb_process;
+
+	return crypt(&desc, dst, src, nbytes);
 }
 
 static int cbc_encrypt(struct crypto_tfm *tfm,
@@ -205,9 +299,15 @@ static int cbc_encrypt(struct crypto_tfm
                        struct scatterlist *src,
 		       unsigned int nbytes)
 {
-	return crypt(tfm, dst, src, nbytes,
-	             tfm->__crt_alg->cra_cipher.cia_encrypt,
-	             cbc_process_encrypt, tfm->crt_cipher.cit_iv);
+	struct cipher_desc desc;
+	struct cipher_alg *cipher = &tfm->__crt_alg->cra_cipher;
+
+	desc.tfm = tfm;
+	desc.crfn = cipher->cia_encrypt;
+	desc.prfn = cipher->cia_encrypt_cbc ?: cbc_process_encrypt;
+	desc.info = tfm->crt_cipher.cit_iv;
+
+	return crypt(&desc, dst, src, nbytes);
 }
 
 static int cbc_encrypt_iv(struct crypto_tfm *tfm,
@@ -215,9 +315,15 @@ static int cbc_encrypt_iv(struct crypto_
                           struct scatterlist *src,
                           unsigned int nbytes, u8 *iv)
 {
-	return crypt(tfm, dst, src, nbytes,
-	             tfm->__crt_alg->cra_cipher.cia_encrypt,
-	             cbc_process_encrypt, iv);
+	struct cipher_desc desc;
+	struct cipher_alg *cipher = &tfm->__crt_alg->cra_cipher;
+
+	desc.tfm = tfm;
+	desc.crfn = cipher->cia_encrypt;
+	desc.prfn = cipher->cia_encrypt_cbc ?: cbc_process_encrypt;
+	desc.info = iv;
+
+	return crypt_iv_unaligned(&desc, dst, src, nbytes);
 }
 
 static int cbc_decrypt(struct crypto_tfm *tfm,
@@ -225,9 +331,15 @@ static int cbc_decrypt(struct crypto_tfm
                        struct scatterlist *src,
 		       unsigned int nbytes)
 {
-	return crypt(tfm, dst, src, nbytes,
-	             tfm->__crt_alg->cra_cipher.cia_decrypt,
-	             cbc_process_decrypt, tfm->crt_cipher.cit_iv);
+	struct cipher_desc desc;
+	struct cipher_alg *cipher = &tfm->__crt_alg->cra_cipher;
+
+	desc.tfm = tfm;
+	desc.crfn = cipher->cia_decrypt;
+	desc.prfn = cipher->cia_decrypt_cbc ?: cbc_process_decrypt;
+	desc.info = tfm->crt_cipher.cit_iv;
+
+	return crypt(&desc, dst, src, nbytes);
 }
 
 static int cbc_decrypt_iv(struct crypto_tfm *tfm,
@@ -235,9 +347,15 @@ static int cbc_decrypt_iv(struct crypto_
                           struct scatterlist *src,
                           unsigned int nbytes, u8 *iv)
 {
-	return crypt(tfm, dst, src, nbytes,
-	             tfm->__crt_alg->cra_cipher.cia_decrypt,
-	             cbc_process_decrypt, iv);
+	struct cipher_desc desc;
+	struct cipher_alg *cipher = &tfm->__crt_alg->cra_cipher;
+
+	desc.tfm = tfm;
+	desc.crfn = cipher->cia_decrypt;
+	desc.prfn = cipher->cia_decrypt_cbc ?: cbc_process_decrypt;
+	desc.info = iv;
+
+	return crypt_iv_unaligned(&desc, dst, src, nbytes);
 }
 
 static int nocrypt(struct crypto_tfm *tfm,
@@ -306,6 +424,8 @@ int crypto_init_cipher_ops(struct crypto
 	}
 	
 	if (ops->cit_mode == CRYPTO_TFM_MODE_CBC) {
+		unsigned long align;
+		unsigned long addr;
 	    	
 	    	switch (crypto_tfm_alg_blocksize(tfm)) {
 	    	case 8:
@@ -325,9 +445,11 @@ int crypto_init_cipher_ops(struct crypto
 	    	}
 	    	
 		ops->cit_ivsize = crypto_tfm_alg_blocksize(tfm);
-	    	ops->cit_iv = kmalloc(ops->cit_ivsize, GFP_KERNEL);
-		if (ops->cit_iv == NULL)
-			ret = -ENOMEM;
+		align = crypto_tfm_alg_alignmask(tfm) + 1;
+		addr = (unsigned long)crypto_tfm_ctx(tfm);
+		addr = ALIGN(addr, align);
+		addr += ALIGN(tfm->__crt_alg->cra_ctxsize, align);
+		ops->cit_iv = (void *)addr;
 	}
 
 out:	
@@ -336,6 +458,4 @@ out:	
 
 void crypto_exit_cipher_ops(struct crypto_tfm *tfm)
 {
-	if (tfm->crt_cipher.cit_iv)
-		kfree(tfm->crt_cipher.cit_iv);
 }
diff --git a/crypto/des.c b/crypto/des.c
--- a/crypto/des.c
+++ b/crypto/des.c
@@ -1,18 +1,9 @@
-/* 
+/*
  * Cryptographic API.
  *
  * DES & Triple DES EDE Cipher Algorithms.
  *
- * Originally released as descore by Dana L. How <how@isl.stanford.edu>.
- * Modified by Raimar Falke <rf13@inf.tu-dresden.de> for the Linux-Kernel.
- * Derived from Cryptoapi and Nettle implementations, adapted for in-place
- * scatterlist interface.  Changed LGPL to GPL per section 3 of the LGPL.
- *
- * Copyright (c) 1992 Dana L. How.
- * Copyright (c) Raimar Falke <rf13@inf.tu-dresden.de> 
- * Copyright (c) Gisle Sælensminde <gisle@ii.uib.no>
- * Copyright (C) 2001 Niels Möller.
- * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
+ * Copyright (c) 2005 Dag Arne Osvik <da@osvik.no>
  *
  * 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
@@ -20,11 +11,11 @@
  * (at your option) any later version.
  *
  */
+
+#include <linux/bitops.h>
 #include <linux/init.h>
 #include <linux/module.h>
-#include <linux/mm.h>
 #include <linux/errno.h>
-#include <asm/scatterlist.h>
 #include <linux/crypto.h>
 
 #define DES_KEY_SIZE		8
@@ -35,1157 +26,826 @@
 #define DES3_EDE_EXPKEY_WORDS	(3 * DES_EXPKEY_WORDS)
 #define DES3_EDE_BLOCK_SIZE	DES_BLOCK_SIZE
 
-#define ROR(d,c,o)	((d) = (d) >> (c) | (d) << (o))
+#define ROL(x, r) ((x) = rol32((x), (r)))
+#define ROR(x, r) ((x) = ror32((x), (r)))
 
 struct des_ctx {
-	u8 iv[DES_BLOCK_SIZE];
 	u32 expkey[DES_EXPKEY_WORDS];
 };
 
 struct des3_ede_ctx {
-	u8 iv[DES_BLOCK_SIZE];
 	u32 expkey[DES3_EDE_EXPKEY_WORDS];
 };
 
-static const u32 des_keymap[] = {
-	0x02080008, 0x02082000, 0x00002008, 0x00000000,
-	0x02002000, 0x00080008, 0x02080000, 0x02082008,
-	0x00000008, 0x02000000, 0x00082000, 0x00002008,
-	0x00082008, 0x02002008, 0x02000008, 0x02080000,
-	0x00002000, 0x00082008, 0x00080008, 0x02002000,
-	0x02082008, 0x02000008, 0x00000000, 0x00082000,
-	0x02000000, 0x00080000, 0x02002008, 0x02080008,
-	0x00080000, 0x00002000, 0x02082000, 0x00000008,
-	0x00080000, 0x00002000, 0x02000008, 0x02082008,
-	0x00002008, 0x02000000, 0x00000000, 0x00082000,
-	0x02080008, 0x02002008, 0x02002000, 0x00080008,
-	0x02082000, 0x00000008, 0x00080008, 0x02002000,
-	0x02082008, 0x00080000, 0x02080000, 0x02000008,
-	0x00082000, 0x00002008, 0x02002008, 0x02080000,
-	0x00000008, 0x02082000, 0x00082008, 0x00000000,
-	0x02000000, 0x02080008, 0x00002000, 0x00082008,
-
-	0x08000004, 0x00020004, 0x00000000, 0x08020200,
-	0x00020004, 0x00000200, 0x08000204, 0x00020000,
-	0x00000204, 0x08020204, 0x00020200, 0x08000000,
-	0x08000200, 0x08000004, 0x08020000, 0x00020204,
-	0x00020000, 0x08000204, 0x08020004, 0x00000000,
-	0x00000200, 0x00000004, 0x08020200, 0x08020004,
-	0x08020204, 0x08020000, 0x08000000, 0x00000204,
-	0x00000004, 0x00020200, 0x00020204, 0x08000200,
-	0x00000204, 0x08000000, 0x08000200, 0x00020204,
-	0x08020200, 0x00020004, 0x00000000, 0x08000200,
-	0x08000000, 0x00000200, 0x08020004, 0x00020000,
-	0x00020004, 0x08020204, 0x00020200, 0x00000004,
-	0x08020204, 0x00020200, 0x00020000, 0x08000204,
-	0x08000004, 0x08020000, 0x00020204, 0x00000000,
-	0x00000200, 0x08000004, 0x08000204, 0x08020200,
-	0x08020000, 0x00000204, 0x00000004, 0x08020004,
-
-	0x80040100, 0x01000100, 0x80000000, 0x81040100,
-	0x00000000, 0x01040000, 0x81000100, 0x80040000,
-	0x01040100, 0x81000000, 0x01000000, 0x80000100,
-	0x81000000, 0x80040100, 0x00040000, 0x01000000,
-	0x81040000, 0x00040100, 0x00000100, 0x80000000,
-	0x00040100, 0x81000100, 0x01040000, 0x00000100,
-	0x80000100, 0x00000000, 0x80040000, 0x01040100,
-	0x01000100, 0x81040000, 0x81040100, 0x00040000,
-	0x81040000, 0x80000100, 0x00040000, 0x81000000,
-	0x00040100, 0x01000100, 0x80000000, 0x01040000,
-	0x81000100, 0x00000000, 0x00000100, 0x80040000,
-	0x00000000, 0x81040000, 0x01040100, 0x00000100,
-	0x01000000, 0x81040100, 0x80040100, 0x00040000,
-	0x81040100, 0x80000000, 0x01000100, 0x80040100,
-	0x80040000, 0x00040100, 0x01040000, 0x81000100,
-	0x80000100, 0x01000000, 0x81000000, 0x01040100,
-
-	0x04010801, 0x00000000, 0x00010800, 0x04010000,
-	0x04000001, 0x00000801, 0x04000800, 0x00010800,
-	0x00000800, 0x04010001, 0x00000001, 0x04000800,
-	0x00010001, 0x04010800, 0x04010000, 0x00000001,
-	0x00010000, 0x04000801, 0x04010001, 0x00000800,
-	0x00010801, 0x04000000, 0x00000000, 0x00010001,
-	0x04000801, 0x00010801, 0x04010800, 0x04000001,
-	0x04000000, 0x00010000, 0x00000801, 0x04010801,
-	0x00010001, 0x04010800, 0x04000800, 0x00010801,
-	0x04010801, 0x00010001, 0x04000001, 0x00000000,
-	0x04000000, 0x00000801, 0x00010000, 0x04010001,
-	0x00000800, 0x04000000, 0x00010801, 0x04000801,
-	0x04010800, 0x00000800, 0x00000000, 0x04000001,
-	0x00000001, 0x04010801, 0x00010800, 0x04010000,
-	0x04010001, 0x00010000, 0x00000801, 0x04000800,
-	0x04000801, 0x00000001, 0x04010000, 0x00010800,
-
-	0x00000400, 0x00000020, 0x00100020, 0x40100000,
-	0x40100420, 0x40000400, 0x00000420, 0x00000000,
-	0x00100000, 0x40100020, 0x40000020, 0x00100400,
-	0x40000000, 0x00100420, 0x00100400, 0x40000020,
-	0x40100020, 0x00000400, 0x40000400, 0x40100420,
-	0x00000000, 0x00100020, 0x40100000, 0x00000420,
-	0x40100400, 0x40000420, 0x00100420, 0x40000000,
-	0x40000420, 0x40100400, 0x00000020, 0x00100000,
-	0x40000420, 0x00100400, 0x40100400, 0x40000020,
-	0x00000400, 0x00000020, 0x00100000, 0x40100400,
-	0x40100020, 0x40000420, 0x00000420, 0x00000000,
-	0x00000020, 0x40100000, 0x40000000, 0x00100020,
-	0x00000000, 0x40100020, 0x00100020, 0x00000420,
-	0x40000020, 0x00000400, 0x40100420, 0x00100000,
-	0x00100420, 0x40000000, 0x40000400, 0x40100420,
-	0x40100000, 0x00100420, 0x00100400, 0x40000400,
-
-	0x00800000, 0x00001000, 0x00000040, 0x00801042,
-	0x00801002, 0x00800040, 0x00001042, 0x00801000,
-	0x00001000, 0x00000002, 0x00800002, 0x00001040,
-	0x00800042, 0x00801002, 0x00801040, 0x00000000,
-	0x00001040, 0x00800000, 0x00001002, 0x00000042,
-	0x00800040, 0x00001042, 0x00000000, 0x00800002,
-	0x00000002, 0x00800042, 0x00801042, 0x00001002,
-	0x00801000, 0x00000040, 0x00000042, 0x00801040,
-	0x00801040, 0x00800042, 0x00001002, 0x00801000,
-	0x00001000, 0x00000002, 0x00800002, 0x00800040,
-	0x00800000, 0x00001040, 0x00801042, 0x00000000,
-	0x00001042, 0x00800000, 0x00000040, 0x00001002,
-	0x00800042, 0x00000040, 0x00000000, 0x00801042,
-	0x00801002, 0x00801040, 0x00000042, 0x00001000,
-	0x00001040, 0x00801002, 0x00800040, 0x00000042,
-	0x00000002, 0x00001042, 0x00801000, 0x00800002,
-
-	0x10400000, 0x00404010, 0x00000010, 0x10400010,
-	0x10004000, 0x00400000, 0x10400010, 0x00004010,
-	0x00400010, 0x00004000, 0x00404000, 0x10000000,
-	0x10404010, 0x10000010, 0x10000000, 0x10404000,
-	0x00000000, 0x10004000, 0x00404010, 0x00000010,
-	0x10000010, 0x10404010, 0x00004000, 0x10400000,
-	0x10404000, 0x00400010, 0x10004010, 0x00404000,
-	0x00004010, 0x00000000, 0x00400000, 0x10004010,
-	0x00404010, 0x00000010, 0x10000000, 0x00004000,
-	0x10000010, 0x10004000, 0x00404000, 0x10400010,
-	0x00000000, 0x00404010, 0x00004010, 0x10404000,
-	0x10004000, 0x00400000, 0x10404010, 0x10000000,
-	0x10004010, 0x10400000, 0x00400000, 0x10404010,
-	0x00004000, 0x00400010, 0x10400010, 0x00004010,
-	0x00400010, 0x00000000, 0x10404000, 0x10000010,
-	0x10400000, 0x10004010, 0x00000010, 0x00404000,
-
-	0x00208080, 0x00008000, 0x20200000, 0x20208080,
-	0x00200000, 0x20008080, 0x20008000, 0x20200000,
-	0x20008080, 0x00208080, 0x00208000, 0x20000080,
-	0x20200080, 0x00200000, 0x00000000, 0x20008000,
-	0x00008000, 0x20000000, 0x00200080, 0x00008080,
-	0x20208080, 0x00208000, 0x20000080, 0x00200080,
-	0x20000000, 0x00000080, 0x00008080, 0x20208000,
-	0x00000080, 0x20200080, 0x20208000, 0x00000000,
-	0x00000000, 0x20208080, 0x00200080, 0x20008000,
-	0x00208080, 0x00008000, 0x20000080, 0x00200080,
-	0x20208000, 0x00000080, 0x00008080, 0x20200000,
-	0x20008080, 0x20000000, 0x20200000, 0x00208000,
-	0x20208080, 0x00008080, 0x00208000, 0x20200080,
-	0x00200000, 0x20000080, 0x20008000, 0x00000000,
-	0x00008000, 0x00200000, 0x20200080, 0x00208080,
-	0x20000000, 0x20208000, 0x00000080, 0x20008080,
+/* Lookup tables for key expansion */
+
+static const u8 pc1[256] = {
+	0x00, 0x00, 0x40, 0x04, 0x10, 0x10, 0x50, 0x14,
+	0x04, 0x40, 0x44, 0x44, 0x14, 0x50, 0x54, 0x54,
+	0x02, 0x02, 0x42, 0x06, 0x12, 0x12, 0x52, 0x16,
+	0x06, 0x42, 0x46, 0x46, 0x16, 0x52, 0x56, 0x56,
+	0x80, 0x08, 0xc0, 0x0c, 0x90, 0x18, 0xd0, 0x1c,
+	0x84, 0x48, 0xc4, 0x4c, 0x94, 0x58, 0xd4, 0x5c,
+	0x82, 0x0a, 0xc2, 0x0e, 0x92, 0x1a, 0xd2, 0x1e,
+	0x86, 0x4a, 0xc6, 0x4e, 0x96, 0x5a, 0xd6, 0x5e,
+	0x20, 0x20, 0x60, 0x24, 0x30, 0x30, 0x70, 0x34,
+	0x24, 0x60, 0x64, 0x64, 0x34, 0x70, 0x74, 0x74,
+	0x22, 0x22, 0x62, 0x26, 0x32, 0x32, 0x72, 0x36,
+	0x26, 0x62, 0x66, 0x66, 0x36, 0x72, 0x76, 0x76,
+	0xa0, 0x28, 0xe0, 0x2c, 0xb0, 0x38, 0xf0, 0x3c,
+	0xa4, 0x68, 0xe4, 0x6c, 0xb4, 0x78, 0xf4, 0x7c,
+	0xa2, 0x2a, 0xe2, 0x2e, 0xb2, 0x3a, 0xf2, 0x3e,
+	0xa6, 0x6a, 0xe6, 0x6e, 0xb6, 0x7a, 0xf6, 0x7e,
+	0x08, 0x80, 0x48, 0x84, 0x18, 0x90, 0x58, 0x94,
+	0x0c, 0xc0, 0x4c, 0xc4, 0x1c, 0xd0, 0x5c, 0xd4,
+	0x0a, 0x82, 0x4a, 0x86, 0x1a, 0x92, 0x5a, 0x96,
+	0x0e, 0xc2, 0x4e, 0xc6, 0x1e, 0xd2, 0x5e, 0xd6,
+	0x88, 0x88, 0xc8, 0x8c, 0x98, 0x98, 0xd8, 0x9c,
+	0x8c, 0xc8, 0xcc, 0xcc, 0x9c, 0xd8, 0xdc, 0xdc,
+	0x8a, 0x8a, 0xca, 0x8e, 0x9a, 0x9a, 0xda, 0x9e,
+	0x8e, 0xca, 0xce, 0xce, 0x9e, 0xda, 0xde, 0xde,
+	0x28, 0xa0, 0x68, 0xa4, 0x38, 0xb0, 0x78, 0xb4,
+	0x2c, 0xe0, 0x6c, 0xe4, 0x3c, 0xf0, 0x7c, 0xf4,
+	0x2a, 0xa2, 0x6a, 0xa6, 0x3a, 0xb2, 0x7a, 0xb6,
+	0x2e, 0xe2, 0x6e, 0xe6, 0x3e, 0xf2, 0x7e, 0xf6,
+	0xa8, 0xa8, 0xe8, 0xac, 0xb8, 0xb8, 0xf8, 0xbc,
+	0xac, 0xe8, 0xec, 0xec, 0xbc, 0xf8, 0xfc, 0xfc,
+	0xaa, 0xaa, 0xea, 0xae, 0xba, 0xba, 0xfa, 0xbe,
+	0xae, 0xea, 0xee, 0xee, 0xbe, 0xfa, 0xfe, 0xfe
 };
 
-static const u8 rotors[] = {
-	34, 13,  5, 46, 47, 18, 32, 41, 11, 53, 33, 20,
-	14, 36, 30, 24, 49,  2, 15, 37, 42, 50,  0, 21,
-	38, 48,  6, 26, 39,  4, 52, 25, 12, 27, 31, 40,
-	1, 17, 28, 29, 23, 51, 35,  7,  3, 22,  9, 43,
-
-	41, 20, 12, 53, 54, 25, 39, 48, 18, 31, 40, 27,
-	21, 43, 37,  0,  1,  9, 22, 44, 49,  2,  7, 28,
-	45, 55, 13, 33, 46, 11,  6, 32, 19, 34, 38, 47,
-	8, 24, 35, 36, 30,  3, 42, 14, 10, 29, 16, 50,
-
-	55, 34, 26, 38, 11, 39, 53,  5, 32, 45, 54, 41,
-	35,  2, 51, 14, 15, 23, 36,  3,  8, 16, 21, 42,
-	6, 12, 27, 47, 31, 25, 20, 46, 33, 48, 52,  4,
-	22,  7, 49, 50, 44, 17,  1, 28, 24, 43, 30,  9,
-
-	12, 48, 40, 52, 25, 53, 38, 19, 46,  6, 11, 55,
-	49, 16, 10, 28, 29, 37, 50, 17, 22, 30, 35,  1,
-	20, 26, 41,  4, 45, 39, 34, 31, 47,  5, 13, 18,
-	36, 21,  8,  9,  3,  0, 15, 42,  7,  2, 44, 23,
-
-	26,  5, 54, 13, 39, 38, 52, 33, 31, 20, 25, 12,
-	8, 30, 24, 42, 43, 51,  9,  0, 36, 44, 49, 15,
-	34, 40, 55, 18,  6, 53, 48, 45,  4, 19, 27, 32,
-	50, 35, 22, 23, 17, 14, 29,  1, 21, 16,  3, 37,
-
-	40, 19, 11, 27, 53, 52, 13, 47, 45, 34, 39, 26,
-	22, 44,  7,  1,  2, 10, 23, 14, 50,  3,  8, 29,
-	48, 54, 12, 32, 20, 38,  5,  6, 18, 33, 41, 46,
-	9, 49, 36, 37,  0, 28, 43, 15, 35, 30, 17, 51,
-
-	54, 33, 25, 41, 38, 13, 27,  4,  6, 48, 53, 40,
-	36,  3, 21, 15, 16, 24, 37, 28,  9, 17, 22, 43,
-	5, 11, 26, 46, 34, 52, 19, 20, 32, 47, 55, 31,
-	23,  8, 50, 51, 14, 42,  2, 29, 49, 44,  0, 10,
-
-	11, 47, 39, 55, 52, 27, 41, 18, 20,  5, 38, 54,
-	50, 17, 35, 29, 30,  7, 51, 42, 23,  0, 36,  2,
-	19, 25, 40, 31, 48, 13, 33, 34, 46,  4, 12, 45,
-	37, 22,  9, 10, 28,  1, 16, 43,  8,  3, 14, 24,
-
-	18, 54, 46,  5,  6, 34, 48, 25, 27, 12, 45,  4,
-	2, 24, 42, 36, 37, 14,  3, 49, 30,  7, 43,  9,
-	26, 32, 47, 38, 55, 20, 40, 41, 53, 11, 19, 52,
-	44, 29, 16, 17, 35,  8, 23, 50, 15, 10, 21,  0,
-
-	32, 11, 31, 19, 20, 48,  5, 39, 41, 26,  6, 18,
-	16,  7,  1, 50, 51, 28, 17,  8, 44, 21,  2, 23,
-	40, 46,  4, 52, 12, 34, 54, 55, 38, 25, 33, 13,
-	3, 43, 30,  0, 49, 22, 37,  9, 29, 24, 35, 14,
-
-	46, 25, 45, 33, 34,  5, 19, 53, 55, 40, 20, 32,
-	30, 21, 15,  9, 10, 42,  0, 22,  3, 35, 16, 37,
-	54, 31, 18, 13, 26, 48, 11, 12, 52, 39, 47, 27,
-	17,  2, 44, 14,  8, 36, 51, 23, 43,  7, 49, 28,
-
-	31, 39,  6, 47, 48, 19, 33, 38, 12, 54, 34, 46,
-	44, 35, 29, 23, 24,  1, 14, 36, 17, 49, 30, 51,
-	11, 45, 32, 27, 40,  5, 25, 26, 13, 53,  4, 41,
-	0, 16,  3, 28, 22, 50, 10, 37,  2, 21,  8, 42,
-
-	45, 53, 20,  4,  5, 33, 47, 52, 26, 11, 48, 31,
-	3, 49, 43, 37,  7, 15, 28, 50,  0,  8, 44, 10,
-	25,  6, 46, 41, 54, 19, 39, 40, 27, 38, 18, 55,
-	14, 30, 17, 42, 36,  9, 24, 51, 16, 35, 22,  1,
-
-	6, 38, 34, 18, 19, 47,  4, 13, 40, 25,  5, 45,
-	17,  8,  2, 51, 21, 29, 42,  9, 14, 22,  3, 24,
-	39, 20, 31, 55, 11, 33, 53, 54, 41, 52, 32, 12,
-	28, 44,  0,  1, 50, 23,  7, 10, 30, 49, 36, 15,
-
-	20, 52, 48, 32, 33,  4, 18, 27, 54, 39, 19,  6,
-	0, 22, 16, 10, 35, 43,  1, 23, 28, 36, 17,  7,
-	53, 34, 45, 12, 25, 47, 38, 11, 55, 13, 46, 26,
-	42,  3, 14, 15,  9, 37, 21, 24, 44,  8, 50, 29,
-
-	27,  6, 55, 39, 40, 11, 25, 34,  4, 46, 26, 13,
-	7, 29, 23, 17, 42, 50,  8, 30, 35, 43, 24, 14,
-	31, 41, 52, 19, 32, 54, 45, 18,  5, 20, 53, 33,
-	49, 10, 21, 22, 16, 44, 28,  0, 51, 15,  2, 36,
+static const u8 rs[256] = {
+	0x00, 0x00, 0x80, 0x80, 0x02, 0x02, 0x82, 0x82,
+	0x04, 0x04, 0x84, 0x84, 0x06, 0x06, 0x86, 0x86,
+	0x08, 0x08, 0x88, 0x88, 0x0a, 0x0a, 0x8a, 0x8a,
+	0x0c, 0x0c, 0x8c, 0x8c, 0x0e, 0x0e, 0x8e, 0x8e,
+	0x10, 0x10, 0x90, 0x90, 0x12, 0x12, 0x92, 0x92,
+	0x14, 0x14, 0x94, 0x94, 0x16, 0x16, 0x96, 0x96,
+	0x18, 0x18, 0x98, 0x98, 0x1a, 0x1a, 0x9a, 0x9a,
+	0x1c, 0x1c, 0x9c, 0x9c, 0x1e, 0x1e, 0x9e, 0x9e,
+	0x20, 0x20, 0xa0, 0xa0, 0x22, 0x22, 0xa2, 0xa2,
+	0x24, 0x24, 0xa4, 0xa4, 0x26, 0x26, 0xa6, 0xa6,
+	0x28, 0x28, 0xa8, 0xa8, 0x2a, 0x2a, 0xaa, 0xaa,
+	0x2c, 0x2c, 0xac, 0xac, 0x2e, 0x2e, 0xae, 0xae,
+	0x30, 0x30, 0xb0, 0xb0, 0x32, 0x32, 0xb2, 0xb2,
+	0x34, 0x34, 0xb4, 0xb4, 0x36, 0x36, 0xb6, 0xb6,
+	0x38, 0x38, 0xb8, 0xb8, 0x3a, 0x3a, 0xba, 0xba,
+	0x3c, 0x3c, 0xbc, 0xbc, 0x3e, 0x3e, 0xbe, 0xbe,
+	0x40, 0x40, 0xc0, 0xc0, 0x42, 0x42, 0xc2, 0xc2,
+	0x44, 0x44, 0xc4, 0xc4, 0x46, 0x46, 0xc6, 0xc6,
+	0x48, 0x48, 0xc8, 0xc8, 0x4a, 0x4a, 0xca, 0xca,
+	0x4c, 0x4c, 0xcc, 0xcc, 0x4e, 0x4e, 0xce, 0xce,
+	0x50, 0x50, 0xd0, 0xd0, 0x52, 0x52, 0xd2, 0xd2,
+	0x54, 0x54, 0xd4, 0xd4, 0x56, 0x56, 0xd6, 0xd6,
+	0x58, 0x58, 0xd8, 0xd8, 0x5a, 0x5a, 0xda, 0xda,
+	0x5c, 0x5c, 0xdc, 0xdc, 0x5e, 0x5e, 0xde, 0xde,
+	0x60, 0x60, 0xe0, 0xe0, 0x62, 0x62, 0xe2, 0xe2,
+	0x64, 0x64, 0xe4, 0xe4, 0x66, 0x66, 0xe6, 0xe6,
+	0x68, 0x68, 0xe8, 0xe8, 0x6a, 0x6a, 0xea, 0xea,
+	0x6c, 0x6c, 0xec, 0xec, 0x6e, 0x6e, 0xee, 0xee,
+	0x70, 0x70, 0xf0, 0xf0, 0x72, 0x72, 0xf2, 0xf2,
+	0x74, 0x74, 0xf4, 0xf4, 0x76, 0x76, 0xf6, 0xf6,
+	0x78, 0x78, 0xf8, 0xf8, 0x7a, 0x7a, 0xfa, 0xfa,
+	0x7c, 0x7c, 0xfc, 0xfc, 0x7e, 0x7e, 0xfe, 0xfe
 };
 
-static const u8 parity[] = {
-	8,1,0,8,0,8,8,0,0,8,8,0,8,0,2,8,0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,3,
-	0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,
-	0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,
-	8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,
-	0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,
-	8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,
-	8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,
-	4,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,8,5,0,8,0,8,8,0,0,8,8,0,8,0,6,8,
+static const u32 pc2[1024] = {
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00040000, 0x00000000, 0x04000000, 0x00100000,
+	0x00400000, 0x00000008, 0x00000800, 0x40000000,
+	0x00440000, 0x00000008, 0x04000800, 0x40100000,
+	0x00000400, 0x00000020, 0x08000000, 0x00000100,
+	0x00040400, 0x00000020, 0x0c000000, 0x00100100,
+	0x00400400, 0x00000028, 0x08000800, 0x40000100,
+	0x00440400, 0x00000028, 0x0c000800, 0x40100100,
+	0x80000000, 0x00000010, 0x00000000, 0x00800000,
+	0x80040000, 0x00000010, 0x04000000, 0x00900000,
+	0x80400000, 0x00000018, 0x00000800, 0x40800000,
+	0x80440000, 0x00000018, 0x04000800, 0x40900000,
+	0x80000400, 0x00000030, 0x08000000, 0x00800100,
+	0x80040400, 0x00000030, 0x0c000000, 0x00900100,
+	0x80400400, 0x00000038, 0x08000800, 0x40800100,
+	0x80440400, 0x00000038, 0x0c000800, 0x40900100,
+	0x10000000, 0x00000000, 0x00200000, 0x00001000,
+	0x10040000, 0x00000000, 0x04200000, 0x00101000,
+	0x10400000, 0x00000008, 0x00200800, 0x40001000,
+	0x10440000, 0x00000008, 0x04200800, 0x40101000,
+	0x10000400, 0x00000020, 0x08200000, 0x00001100,
+	0x10040400, 0x00000020, 0x0c200000, 0x00101100,
+	0x10400400, 0x00000028, 0x08200800, 0x40001100,
+	0x10440400, 0x00000028, 0x0c200800, 0x40101100,
+	0x90000000, 0x00000010, 0x00200000, 0x00801000,
+	0x90040000, 0x00000010, 0x04200000, 0x00901000,
+	0x90400000, 0x00000018, 0x00200800, 0x40801000,
+	0x90440000, 0x00000018, 0x04200800, 0x40901000,
+	0x90000400, 0x00000030, 0x08200000, 0x00801100,
+	0x90040400, 0x00000030, 0x0c200000, 0x00901100,
+	0x90400400, 0x00000038, 0x08200800, 0x40801100,
+	0x90440400, 0x00000038, 0x0c200800, 0x40901100,
+	0x00000200, 0x00080000, 0x00000000, 0x00000004,
+	0x00040200, 0x00080000, 0x04000000, 0x00100004,
+	0x00400200, 0x00080008, 0x00000800, 0x40000004,
+	0x00440200, 0x00080008, 0x04000800, 0x40100004,
+	0x00000600, 0x00080020, 0x08000000, 0x00000104,
+	0x00040600, 0x00080020, 0x0c000000, 0x00100104,
+	0x00400600, 0x00080028, 0x08000800, 0x40000104,
+	0x00440600, 0x00080028, 0x0c000800, 0x40100104,
+	0x80000200, 0x00080010, 0x00000000, 0x00800004,
+	0x80040200, 0x00080010, 0x04000000, 0x00900004,
+	0x80400200, 0x00080018, 0x00000800, 0x40800004,
+	0x80440200, 0x00080018, 0x04000800, 0x40900004,
+	0x80000600, 0x00080030, 0x08000000, 0x00800104,
+	0x80040600, 0x00080030, 0x0c000000, 0x00900104,
+	0x80400600, 0x00080038, 0x08000800, 0x40800104,
+	0x80440600, 0x00080038, 0x0c000800, 0x40900104,
+	0x10000200, 0x00080000, 0x00200000, 0x00001004,
+	0x10040200, 0x00080000, 0x04200000, 0x00101004,
+	0x10400200, 0x00080008, 0x00200800, 0x40001004,
+	0x10440200, 0x00080008, 0x04200800, 0x40101004,
+	0x10000600, 0x00080020, 0x08200000, 0x00001104,
+	0x10040600, 0x00080020, 0x0c200000, 0x00101104,
+	0x10400600, 0x00080028, 0x08200800, 0x40001104,
+	0x10440600, 0x00080028, 0x0c200800, 0x40101104,
+	0x90000200, 0x00080010, 0x00200000, 0x00801004,
+	0x90040200, 0x00080010, 0x04200000, 0x00901004,
+	0x90400200, 0x00080018, 0x00200800, 0x40801004,
+	0x90440200, 0x00080018, 0x04200800, 0x40901004,
+	0x90000600, 0x00080030, 0x08200000, 0x00801104,
+	0x90040600, 0x00080030, 0x0c200000, 0x00901104,
+	0x90400600, 0x00080038, 0x08200800, 0x40801104,
+	0x90440600, 0x00080038, 0x0c200800, 0x40901104,
+	0x00000002, 0x00002000, 0x20000000, 0x00000001,
+	0x00040002, 0x00002000, 0x24000000, 0x00100001,
+	0x00400002, 0x00002008, 0x20000800, 0x40000001,
+	0x00440002, 0x00002008, 0x24000800, 0x40100001,
+	0x00000402, 0x00002020, 0x28000000, 0x00000101,
+	0x00040402, 0x00002020, 0x2c000000, 0x00100101,
+	0x00400402, 0x00002028, 0x28000800, 0x40000101,
+	0x00440402, 0x00002028, 0x2c000800, 0x40100101,
+	0x80000002, 0x00002010, 0x20000000, 0x00800001,
+	0x80040002, 0x00002010, 0x24000000, 0x00900001,
+	0x80400002, 0x00002018, 0x20000800, 0x40800001,
+	0x80440002, 0x00002018, 0x24000800, 0x40900001,
+	0x80000402, 0x00002030, 0x28000000, 0x00800101,
+	0x80040402, 0x00002030, 0x2c000000, 0x00900101,
+	0x80400402, 0x00002038, 0x28000800, 0x40800101,
+	0x80440402, 0x00002038, 0x2c000800, 0x40900101,
+	0x10000002, 0x00002000, 0x20200000, 0x00001001,
+	0x10040002, 0x00002000, 0x24200000, 0x00101001,
+	0x10400002, 0x00002008, 0x20200800, 0x40001001,
+	0x10440002, 0x00002008, 0x24200800, 0x40101001,
+	0x10000402, 0x00002020, 0x28200000, 0x00001101,
+	0x10040402, 0x00002020, 0x2c200000, 0x00101101,
+	0x10400402, 0x00002028, 0x28200800, 0x40001101,
+	0x10440402, 0x00002028, 0x2c200800, 0x40101101,
+	0x90000002, 0x00002010, 0x20200000, 0x00801001,
+	0x90040002, 0x00002010, 0x24200000, 0x00901001,
+	0x90400002, 0x00002018, 0x20200800, 0x40801001,
+	0x90440002, 0x00002018, 0x24200800, 0x40901001,
+	0x90000402, 0x00002030, 0x28200000, 0x00801101,
+	0x90040402, 0x00002030, 0x2c200000, 0x00901101,
+	0x90400402, 0x00002038, 0x28200800, 0x40801101,
+	0x90440402, 0x00002038, 0x2c200800, 0x40901101,
+	0x00000202, 0x00082000, 0x20000000, 0x00000005,
+	0x00040202, 0x00082000, 0x24000000, 0x00100005,
+	0x00400202, 0x00082008, 0x20000800, 0x40000005,
+	0x00440202, 0x00082008, 0x24000800, 0x40100005,
+	0x00000602, 0x00082020, 0x28000000, 0x00000105,
+	0x00040602, 0x00082020, 0x2c000000, 0x00100105,
+	0x00400602, 0x00082028, 0x28000800, 0x40000105,
+	0x00440602, 0x00082028, 0x2c000800, 0x40100105,
+	0x80000202, 0x00082010, 0x20000000, 0x00800005,
+	0x80040202, 0x00082010, 0x24000000, 0x00900005,
+	0x80400202, 0x00082018, 0x20000800, 0x40800005,
+	0x80440202, 0x00082018, 0x24000800, 0x40900005,
+	0x80000602, 0x00082030, 0x28000000, 0x00800105,
+	0x80040602, 0x00082030, 0x2c000000, 0x00900105,
+	0x80400602, 0x00082038, 0x28000800, 0x40800105,
+	0x80440602, 0x00082038, 0x2c000800, 0x40900105,
+	0x10000202, 0x00082000, 0x20200000, 0x00001005,
+	0x10040202, 0x00082000, 0x24200000, 0x00101005,
+	0x10400202, 0x00082008, 0x20200800, 0x40001005,
+	0x10440202, 0x00082008, 0x24200800, 0x40101005,
+	0x10000602, 0x00082020, 0x28200000, 0x00001105,
+	0x10040602, 0x00082020, 0x2c200000, 0x00101105,
+	0x10400602, 0x00082028, 0x28200800, 0x40001105,
+	0x10440602, 0x00082028, 0x2c200800, 0x40101105,
+	0x90000202, 0x00082010, 0x20200000, 0x00801005,
+	0x90040202, 0x00082010, 0x24200000, 0x00901005,
+	0x90400202, 0x00082018, 0x20200800, 0x40801005,
+	0x90440202, 0x00082018, 0x24200800, 0x40901005,
+	0x90000602, 0x00082030, 0x28200000, 0x00801105,
+	0x90040602, 0x00082030, 0x2c200000, 0x00901105,
+	0x90400602, 0x00082038, 0x28200800, 0x40801105,
+	0x90440602, 0x00082038, 0x2c200800, 0x40901105,
+
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000008, 0x00080000, 0x10000000,
+	0x02000000, 0x00000000, 0x00000080, 0x00001000,
+	0x02000000, 0x00000008, 0x00080080, 0x10001000,
+	0x00004000, 0x00000000, 0x00000040, 0x00040000,
+	0x00004000, 0x00000008, 0x00080040, 0x10040000,
+	0x02004000, 0x00000000, 0x000000c0, 0x00041000,
+	0x02004000, 0x00000008, 0x000800c0, 0x10041000,
+	0x00020000, 0x00008000, 0x08000000, 0x00200000,
+	0x00020000, 0x00008008, 0x08080000, 0x10200000,
+	0x02020000, 0x00008000, 0x08000080, 0x00201000,
+	0x02020000, 0x00008008, 0x08080080, 0x10201000,
+	0x00024000, 0x00008000, 0x08000040, 0x00240000,
+	0x00024000, 0x00008008, 0x08080040, 0x10240000,
+	0x02024000, 0x00008000, 0x080000c0, 0x00241000,
+	0x02024000, 0x00008008, 0x080800c0, 0x10241000,
+	0x00000000, 0x01000000, 0x00002000, 0x00000020,
+	0x00000000, 0x01000008, 0x00082000, 0x10000020,
+	0x02000000, 0x01000000, 0x00002080, 0x00001020,
+	0x02000000, 0x01000008, 0x00082080, 0x10001020,
+	0x00004000, 0x01000000, 0x00002040, 0x00040020,
+	0x00004000, 0x01000008, 0x00082040, 0x10040020,
+	0x02004000, 0x01000000, 0x000020c0, 0x00041020,
+	0x02004000, 0x01000008, 0x000820c0, 0x10041020,
+	0x00020000, 0x01008000, 0x08002000, 0x00200020,
+	0x00020000, 0x01008008, 0x08082000, 0x10200020,
+	0x02020000, 0x01008000, 0x08002080, 0x00201020,
+	0x02020000, 0x01008008, 0x08082080, 0x10201020,
+	0x00024000, 0x01008000, 0x08002040, 0x00240020,
+	0x00024000, 0x01008008, 0x08082040, 0x10240020,
+	0x02024000, 0x01008000, 0x080020c0, 0x00241020,
+	0x02024000, 0x01008008, 0x080820c0, 0x10241020,
+	0x00000400, 0x04000000, 0x00100000, 0x00000004,
+	0x00000400, 0x04000008, 0x00180000, 0x10000004,
+	0x02000400, 0x04000000, 0x00100080, 0x00001004,
+	0x02000400, 0x04000008, 0x00180080, 0x10001004,
+	0x00004400, 0x04000000, 0x00100040, 0x00040004,
+	0x00004400, 0x04000008, 0x00180040, 0x10040004,
+	0x02004400, 0x04000000, 0x001000c0, 0x00041004,
+	0x02004400, 0x04000008, 0x001800c0, 0x10041004,
+	0x00020400, 0x04008000, 0x08100000, 0x00200004,
+	0x00020400, 0x04008008, 0x08180000, 0x10200004,
+	0x02020400, 0x04008000, 0x08100080, 0x00201004,
+	0x02020400, 0x04008008, 0x08180080, 0x10201004,
+	0x00024400, 0x04008000, 0x08100040, 0x00240004,
+	0x00024400, 0x04008008, 0x08180040, 0x10240004,
+	0x02024400, 0x04008000, 0x081000c0, 0x00241004,
+	0x02024400, 0x04008008, 0x081800c0, 0x10241004,
+	0x00000400, 0x05000000, 0x00102000, 0x00000024,
+	0x00000400, 0x05000008, 0x00182000, 0x10000024,
+	0x02000400, 0x05000000, 0x00102080, 0x00001024,
+	0x02000400, 0x05000008, 0x00182080, 0x10001024,
+	0x00004400, 0x05000000, 0x00102040, 0x00040024,
+	0x00004400, 0x05000008, 0x00182040, 0x10040024,
+	0x02004400, 0x05000000, 0x001020c0, 0x00041024,
+	0x02004400, 0x05000008, 0x001820c0, 0x10041024,
+	0x00020400, 0x05008000, 0x08102000, 0x00200024,
+	0x00020400, 0x05008008, 0x08182000, 0x10200024,
+	0x02020400, 0x05008000, 0x08102080, 0x00201024,
+	0x02020400, 0x05008008, 0x08182080, 0x10201024,
+	0x00024400, 0x05008000, 0x08102040, 0x00240024,
+	0x00024400, 0x05008008, 0x08182040, 0x10240024,
+	0x02024400, 0x05008000, 0x081020c0, 0x00241024,
+	0x02024400, 0x05008008, 0x081820c0, 0x10241024,
+	0x00000800, 0x00010000, 0x20000000, 0x00000010,
+	0x00000800, 0x00010008, 0x20080000, 0x10000010,
+	0x02000800, 0x00010000, 0x20000080, 0x00001010,
+	0x02000800, 0x00010008, 0x20080080, 0x10001010,
+	0x00004800, 0x00010000, 0x20000040, 0x00040010,
+	0x00004800, 0x00010008, 0x20080040, 0x10040010,
+	0x02004800, 0x00010000, 0x200000c0, 0x00041010,
+	0x02004800, 0x00010008, 0x200800c0, 0x10041010,
+	0x00020800, 0x00018000, 0x28000000, 0x00200010,
+	0x00020800, 0x00018008, 0x28080000, 0x10200010,
+	0x02020800, 0x00018000, 0x28000080, 0x00201010,
+	0x02020800, 0x00018008, 0x28080080, 0x10201010,
+	0x00024800, 0x00018000, 0x28000040, 0x00240010,
+	0x00024800, 0x00018008, 0x28080040, 0x10240010,
+	0x02024800, 0x00018000, 0x280000c0, 0x00241010,
+	0x02024800, 0x00018008, 0x280800c0, 0x10241010,
+	0x00000800, 0x01010000, 0x20002000, 0x00000030,
+	0x00000800, 0x01010008, 0x20082000, 0x10000030,
+	0x02000800, 0x01010000, 0x20002080, 0x00001030,
+	0x02000800, 0x01010008, 0x20082080, 0x10001030,
+	0x00004800, 0x01010000, 0x20002040, 0x00040030,
+	0x00004800, 0x01010008, 0x20082040, 0x10040030,
+	0x02004800, 0x01010000, 0x200020c0, 0x00041030,
+	0x02004800, 0x01010008, 0x200820c0, 0x10041030,
+	0x00020800, 0x01018000, 0x28002000, 0x00200030,
+	0x00020800, 0x01018008, 0x28082000, 0x10200030,
+	0x02020800, 0x01018000, 0x28002080, 0x00201030,
+	0x02020800, 0x01018008, 0x28082080, 0x10201030,
+	0x00024800, 0x01018000, 0x28002040, 0x00240030,
+	0x00024800, 0x01018008, 0x28082040, 0x10240030,
+	0x02024800, 0x01018000, 0x280020c0, 0x00241030,
+	0x02024800, 0x01018008, 0x280820c0, 0x10241030,
+	0x00000c00, 0x04010000, 0x20100000, 0x00000014,
+	0x00000c00, 0x04010008, 0x20180000, 0x10000014,
+	0x02000c00, 0x04010000, 0x20100080, 0x00001014,
+	0x02000c00, 0x04010008, 0x20180080, 0x10001014,
+	0x00004c00, 0x04010000, 0x20100040, 0x00040014,
+	0x00004c00, 0x04010008, 0x20180040, 0x10040014,
+	0x02004c00, 0x04010000, 0x201000c0, 0x00041014,
+	0x02004c00, 0x04010008, 0x201800c0, 0x10041014,
+	0x00020c00, 0x04018000, 0x28100000, 0x00200014,
+	0x00020c00, 0x04018008, 0x28180000, 0x10200014,
+	0x02020c00, 0x04018000, 0x28100080, 0x00201014,
+	0x02020c00, 0x04018008, 0x28180080, 0x10201014,
+	0x00024c00, 0x04018000, 0x28100040, 0x00240014,
+	0x00024c00, 0x04018008, 0x28180040, 0x10240014,
+	0x02024c00, 0x04018000, 0x281000c0, 0x00241014,
+	0x02024c00, 0x04018008, 0x281800c0, 0x10241014,
+	0x00000c00, 0x05010000, 0x20102000, 0x00000034,
+	0x00000c00, 0x05010008, 0x20182000, 0x10000034,
+	0x02000c00, 0x05010000, 0x20102080, 0x00001034,
+	0x02000c00, 0x05010008, 0x20182080, 0x10001034,
+	0x00004c00, 0x05010000, 0x20102040, 0x00040034,
+	0x00004c00, 0x05010008, 0x20182040, 0x10040034,
+	0x02004c00, 0x05010000, 0x201020c0, 0x00041034,
+	0x02004c00, 0x05010008, 0x201820c0, 0x10041034,
+	0x00020c00, 0x05018000, 0x28102000, 0x00200034,
+	0x00020c00, 0x05018008, 0x28182000, 0x10200034,
+	0x02020c00, 0x05018000, 0x28102080, 0x00201034,
+	0x02020c00, 0x05018008, 0x28182080, 0x10201034,
+	0x00024c00, 0x05018000, 0x28102040, 0x00240034,
+	0x00024c00, 0x05018008, 0x28182040, 0x10240034,
+	0x02024c00, 0x05018000, 0x281020c0, 0x00241034,
+	0x02024c00, 0x05018008, 0x281820c0, 0x10241034
 };
 
+/* S-box lookup tables */
 
-static void des_small_fips_encrypt(u32 *expkey, u8 *dst, const u8 *src)
-{
-	u32 x, y, z;
-	
-	x  = src[7];
-	x <<= 8;
-	x |= src[6];
-	x <<= 8;
-	x |= src[5];
-	x <<= 8;
-	x |= src[4];
-	y  = src[3];
-	y <<= 8;
-	y |= src[2];
-	y <<= 8;
-	y |= src[1];
-	y <<= 8;
-	y |= src[0];
-	z  = ((x >> 004) ^ y) & 0x0F0F0F0FL;
-	x ^= z << 004;
-	y ^= z;
-	z  = ((y >> 020) ^ x) & 0x0000FFFFL;
-	y ^= z << 020;
-	x ^= z;
-	z  = ((x >> 002) ^ y) & 0x33333333L;
-	x ^= z << 002;
-	y ^= z;
-	z  = ((y >> 010) ^ x) & 0x00FF00FFL;
-	y ^= z << 010;
-	x ^= z;
-	x  = x >> 1 | x << 31;
-	z  = (x ^ y) & 0x55555555L;
-	y ^= z;
-	x ^= z;
-	y  = y >> 1 | y << 31;
-	z  = expkey[0];
-	z ^= y;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
-	z  = expkey[1];
-	z ^= y;
-	z  = z << 4 | z >> 28;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
-	z  = expkey[2];
-	z ^= x;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
-	z  = expkey[3];
-	z ^= x;
-	z  = z << 4 | z >> 28;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
-	z  = expkey[4];
-	z ^= y;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
-	z  = expkey[5];
-	z ^= y;
-	z  = z << 4 | z >> 28;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
-	z  = expkey[6];
-	z ^= x;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
-	z  = expkey[7];
-	z ^= x;
-	z  = z << 4 | z >> 28;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
-	z  = expkey[8];
-	z ^= y;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
-	z  = expkey[9];
-	z ^= y;
-	z  = z << 4 | z >> 28;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
-	z  = expkey[10];
-	z ^= x;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
-	z  = expkey[11];
-	z ^= x;
-	z  = z << 4 | z >> 28;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
-	z  = expkey[12];
-	z ^= y;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
-	z  = expkey[13];
-	z ^= y;
-	z  = z << 4 | z >> 28;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
-	z  = expkey[14];
-	z ^= x;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
-	z  = expkey[15];
-	z ^= x;
-	z  = z << 4 | z >> 28;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
-	z  = expkey[16];
-	z ^= y;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
-	z  = expkey[17];
-	z ^= y;
-	z  = z << 4 | z >> 28;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
-	z  = expkey[18];
-	z ^= x;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
-	z  = expkey[19];
-	z ^= x;
-	z  = z << 4 | z >> 28;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
-	z  = expkey[20];
-	z ^= y;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
-	z  = expkey[21];
-	z ^= y;
-	z  = z << 4 | z >> 28;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
-	z  = expkey[22];
-	z ^= x;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
-	z  = expkey[23];
-	z ^= x;
-	z  = z << 4 | z >> 28;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
-	z  = expkey[24];
-	z ^= y;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
-	z  = expkey[25];
-	z ^= y;
-	z  = z << 4 | z >> 28;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
-	z  = expkey[26];
-	z ^= x;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
-	z  = expkey[27];
-	z ^= x;
-	z  = z << 4 | z >> 28;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
-	z  = expkey[28];
-	z ^= y;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
-	z  = expkey[29];
-	z ^= y;
-	z  = z << 4 | z >> 28;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
-	z  = expkey[30];
-	z ^= x;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
-	z  = expkey[31];
-	z ^= x;
-	z  = z << 4 | z >> 28;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
-	x  = x << 1 | x >> 31;
-	z  = (x ^ y) & 0x55555555L;
-	y ^= z;
-	x ^= z;
-	y  = y << 1 | y >> 31;
-	z  = ((x >> 010) ^ y) & 0x00FF00FFL;
-	x ^= z << 010;
-	y ^= z;
-	z  = ((y >> 002) ^ x) & 0x33333333L;
-	y ^= z << 002;
-	x ^= z;
-	z  = ((x >> 020) ^ y) & 0x0000FFFFL;
-	x ^= z << 020;
-	y ^= z;
-	z  = ((y >> 004) ^ x) & 0x0F0F0F0FL;
-	y ^= z << 004;
-	x ^= z;
-	dst[0] = x;
-	x >>= 8;
-	dst[1] = x;
-	x >>= 8;
-	dst[2] = x;
-	x >>= 8;
-	dst[3] = x;
-	dst[4] = y;
-	y >>= 8;
-	dst[5] = y;
-	y >>= 8;
-	dst[6] = y;
-	y >>= 8;
-	dst[7] = y;
-}
+static const u32 S1[64] = {
+	0x01010400, 0x00000000, 0x00010000, 0x01010404,
+	0x01010004, 0x00010404, 0x00000004, 0x00010000,
+	0x00000400, 0x01010400, 0x01010404, 0x00000400,
+	0x01000404, 0x01010004, 0x01000000, 0x00000004,
+	0x00000404, 0x01000400, 0x01000400, 0x00010400,
+	0x00010400, 0x01010000, 0x01010000, 0x01000404,
+	0x00010004, 0x01000004, 0x01000004, 0x00010004,
+	0x00000000, 0x00000404, 0x00010404, 0x01000000,
+	0x00010000, 0x01010404, 0x00000004, 0x01010000,
+	0x01010400, 0x01000000, 0x01000000, 0x00000400,
+	0x01010004, 0x00010000, 0x00010400, 0x01000004,
+	0x00000400, 0x00000004, 0x01000404, 0x00010404,
+	0x01010404, 0x00010004, 0x01010000, 0x01000404,
+	0x01000004, 0x00000404, 0x00010404, 0x01010400,
+	0x00000404, 0x01000400, 0x01000400, 0x00000000,
+	0x00010004, 0x00010400, 0x00000000, 0x01010004
+};
 
-static void des_small_fips_decrypt(u32 *expkey, u8 *dst, const u8 *src)
-{
-	u32 x, y, z;
-	
-	x  = src[7];
-	x <<= 8;
-	x |= src[6];
-	x <<= 8;
-	x |= src[5];
-	x <<= 8;
-	x |= src[4];
-	y  = src[3];
-	y <<= 8;
-	y |= src[2];
-	y <<= 8;
-	y |= src[1];
-	y <<= 8;
-	y |= src[0];
-	z  = ((x >> 004) ^ y) & 0x0F0F0F0FL;
-	x ^= z << 004;
-	y ^= z;
-	z  = ((y >> 020) ^ x) & 0x0000FFFFL;
-	y ^= z << 020;
-	x ^= z;
-	z  = ((x >> 002) ^ y) & 0x33333333L;
-	x ^= z << 002;
-	y ^= z;
-	z  = ((y >> 010) ^ x) & 0x00FF00FFL;
-	y ^= z << 010;
-	x ^= z;
-	x  = x >> 1 | x << 31;
-	z  = (x ^ y) & 0x55555555L;
-	y ^= z;
-	x ^= z;
-	y  = y >> 1 | y << 31;
-	z  = expkey[31];
-	z ^= y;
-	z  = z << 4 | z >> 28;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
-	z  = expkey[30];
-	z ^= y;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
-	z  = expkey[29];
-	z ^= x;
-	z  = z << 4 | z >> 28;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
-	z  = expkey[28];
-	z ^= x;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
-	z  = expkey[27];
-	z ^= y;
-	z  = z << 4 | z >> 28;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
-	z  = expkey[26];
-	z ^= y;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
-	z  = expkey[25];
-	z ^= x;
-	z  = z << 4 | z >> 28;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
-	z  = expkey[24];
-	z ^= x;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
-	z  = expkey[23];
-	z ^= y;
-	z  = z << 4 | z >> 28;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
-	z  = expkey[22];
-	z ^= y;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
-	z  = expkey[21];
-	z ^= x;
-	z  = z << 4 | z >> 28;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
-	z  = expkey[20];
-	z ^= x;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
-	z  = expkey[19];
-	z ^= y;
-	z  = z << 4 | z >> 28;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
-	z  = expkey[18];
-	z ^= y;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
-	z  = expkey[17];
-	z ^= x;
-	z  = z << 4 | z >> 28;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
-	z  = expkey[16];
-	z ^= x;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
-	z  = expkey[15];
-	z ^= y;
-	z  = z << 4 | z >> 28;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
-	z  = expkey[14];
-	z ^= y;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
-	z  = expkey[13];
-	z ^= x;
-	z  = z << 4 | z >> 28;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
-	z  = expkey[12];
-	z ^= x;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
-	z  = expkey[11];
-	z ^= y;
-	z  = z << 4 | z >> 28;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
-	z  = expkey[10];
-	z ^= y;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
-	z  = expkey[9];
-	z ^= x;
-	z  = z << 4 | z >> 28;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
-	z  = expkey[8];
-	z ^= x;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
-	z  = expkey[7];
-	z ^= y;
-	z  = z << 4 | z >> 28;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
-	z  = expkey[6];
-	z ^= y;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
-	z  = expkey[5];
-	z ^= x;
-	z  = z << 4 | z >> 28;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
-	z  = expkey[4];
-	z ^= x;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
-	z  = expkey[3];
-	z ^= y;
-	z  = z << 4 | z >> 28;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
-	z  = expkey[2];
-	z ^= y;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
-	z >>= 8;
-	x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
-	z  = expkey[1];
-	z ^= x;
-	z  = z << 4 | z >> 28;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z));
-	z  = expkey[0];
-	z ^= x;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z));
-	z >>= 8;
-	y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z));
-	x  = x << 1 | x >> 31;
-	z  = (x ^ y) & 0x55555555L;
-	y ^= z;
-	x ^= z;
-	y  = y << 1 | y >> 31;
-	z  = ((x >> 010) ^ y) & 0x00FF00FFL;
-	x ^= z << 010;
-	y ^= z;
-	z  = ((y >> 002) ^ x) & 0x33333333L;
-	y ^= z << 002;
-	x ^= z;
-	z  = ((x >> 020) ^ y) & 0x0000FFFFL;
-	x ^= z << 020;
-	y ^= z;
-	z  = ((y >> 004) ^ x) & 0x0F0F0F0FL;
-	y ^= z << 004;
-	x ^= z;
-	dst[0] = x;
-	x >>= 8;
-	dst[1] = x;
-	x >>= 8;
-	dst[2] = x;
-	x >>= 8;
-	dst[3] = x;
-	dst[4] = y;
-	y >>= 8;
-	dst[5] = y;
-	y >>= 8;
-	dst[6] = y;
-	y >>= 8;
-	dst[7] = y;
-}
+static const u32 S2[64] = {
+	0x80108020, 0x80008000, 0x00008000, 0x00108020,
+	0x00100000, 0x00000020, 0x80100020, 0x80008020,
+	0x80000020, 0x80108020, 0x80108000, 0x80000000,
+	0x80008000, 0x00100000, 0x00000020, 0x80100020,
+	0x00108000, 0x00100020, 0x80008020, 0x00000000,
+	0x80000000, 0x00008000, 0x00108020, 0x80100000,
+	0x00100020, 0x80000020, 0x00000000, 0x00108000,
+	0x00008020, 0x80108000, 0x80100000, 0x00008020,
+	0x00000000, 0x00108020, 0x80100020, 0x00100000,
+	0x80008020, 0x80100000, 0x80108000, 0x00008000,
+	0x80100000, 0x80008000, 0x00000020, 0x80108020,
+	0x00108020, 0x00000020, 0x00008000, 0x80000000,
+	0x00008020, 0x80108000, 0x00100000, 0x80000020,
+	0x00100020, 0x80008020, 0x80000020, 0x00100020,
+	0x00108000, 0x00000000, 0x80008000, 0x00008020,
+	0x80000000, 0x80100020, 0x80108020, 0x00108000
+};
+
+static const u32 S3[64] = {
+	0x00000208, 0x08020200, 0x00000000, 0x08020008,
+	0x08000200, 0x00000000, 0x00020208, 0x08000200,
+	0x00020008, 0x08000008, 0x08000008, 0x00020000,
+	0x08020208, 0x00020008, 0x08020000, 0x00000208,
+	0x08000000, 0x00000008, 0x08020200, 0x00000200,
+	0x00020200, 0x08020000, 0x08020008, 0x00020208,
+	0x08000208, 0x00020200, 0x00020000, 0x08000208,
+	0x00000008, 0x08020208, 0x00000200, 0x08000000,
+	0x08020200, 0x08000000, 0x00020008, 0x00000208,
+	0x00020000, 0x08020200, 0x08000200, 0x00000000,
+	0x00000200, 0x00020008, 0x08020208, 0x08000200,
+	0x08000008, 0x00000200, 0x00000000, 0x08020008,
+	0x08000208, 0x00020000, 0x08000000, 0x08020208,
+	0x00000008, 0x00020208, 0x00020200, 0x08000008,
+	0x08020000, 0x08000208, 0x00000208, 0x08020000,
+	0x00020208, 0x00000008, 0x08020008, 0x00020200
+};
+
+static const u32 S4[64] = {
+	0x00802001, 0x00002081, 0x00002081, 0x00000080,
+	0x00802080, 0x00800081, 0x00800001, 0x00002001,
+	0x00000000, 0x00802000, 0x00802000, 0x00802081,
+	0x00000081, 0x00000000, 0x00800080, 0x00800001,
+	0x00000001, 0x00002000, 0x00800000, 0x00802001,
+	0x00000080, 0x00800000, 0x00002001, 0x00002080,
+	0x00800081, 0x00000001, 0x00002080, 0x00800080,
+	0x00002000, 0x00802080, 0x00802081, 0x00000081,
+	0x00800080, 0x00800001, 0x00802000, 0x00802081,
+	0x00000081, 0x00000000, 0x00000000, 0x00802000,
+	0x00002080, 0x00800080, 0x00800081, 0x00000001,
+	0x00802001, 0x00002081, 0x00002081, 0x00000080,
+	0x00802081, 0x00000081, 0x00000001, 0x00002000,
+	0x00800001, 0x00002001, 0x00802080, 0x00800081,
+	0x00002001, 0x00002080, 0x00800000, 0x00802001,
+	0x00000080, 0x00800000, 0x00002000, 0x00802080
+};
+
+static const u32 S5[64] = {
+	0x00000100, 0x02080100, 0x02080000, 0x42000100,
+	0x00080000, 0x00000100, 0x40000000, 0x02080000,
+	0x40080100, 0x00080000, 0x02000100, 0x40080100,
+	0x42000100, 0x42080000, 0x00080100, 0x40000000,
+	0x02000000, 0x40080000, 0x40080000, 0x00000000,
+	0x40000100, 0x42080100, 0x42080100, 0x02000100,
+	0x42080000, 0x40000100, 0x00000000, 0x42000000,
+	0x02080100, 0x02000000, 0x42000000, 0x00080100,
+	0x00080000, 0x42000100, 0x00000100, 0x02000000,
+	0x40000000, 0x02080000, 0x42000100, 0x40080100,
+	0x02000100, 0x40000000, 0x42080000, 0x02080100,
+	0x40080100, 0x00000100, 0x02000000, 0x42080000,
+	0x42080100, 0x00080100, 0x42000000, 0x42080100,
+	0x02080000, 0x00000000, 0x40080000, 0x42000000,
+	0x00080100, 0x02000100, 0x40000100, 0x00080000,
+	0x00000000, 0x40080000, 0x02080100, 0x40000100
+};
+
+static const u32 S6[64] = {
+	0x20000010, 0x20400000, 0x00004000, 0x20404010,
+	0x20400000, 0x00000010, 0x20404010, 0x00400000,
+	0x20004000, 0x00404010, 0x00400000, 0x20000010,
+	0x00400010, 0x20004000, 0x20000000, 0x00004010,
+	0x00000000, 0x00400010, 0x20004010, 0x00004000,
+	0x00404000, 0x20004010, 0x00000010, 0x20400010,
+	0x20400010, 0x00000000, 0x00404010, 0x20404000,
+	0x00004010, 0x00404000, 0x20404000, 0x20000000,
+	0x20004000, 0x00000010, 0x20400010, 0x00404000,
+	0x20404010, 0x00400000, 0x00004010, 0x20000010,
+	0x00400000, 0x20004000, 0x20000000, 0x00004010,
+	0x20000010, 0x20404010, 0x00404000, 0x20400000,
+	0x00404010, 0x20404000, 0x00000000, 0x20400010,
+	0x00000010, 0x00004000, 0x20400000, 0x00404010,
+	0x00004000, 0x00400010, 0x20004010, 0x00000000,
+	0x20404000, 0x20000000, 0x00400010, 0x20004010
+};
+
+static const u32 S7[64] = {
+	0x00200000, 0x04200002, 0x04000802, 0x00000000,
+	0x00000800, 0x04000802, 0x00200802, 0x04200800,
+	0x04200802, 0x00200000, 0x00000000, 0x04000002,
+	0x00000002, 0x04000000, 0x04200002, 0x00000802,
+	0x04000800, 0x00200802, 0x00200002, 0x04000800,
+	0x04000002, 0x04200000, 0x04200800, 0x00200002,
+	0x04200000, 0x00000800, 0x00000802, 0x04200802,
+	0x00200800, 0x00000002, 0x04000000, 0x00200800,
+	0x04000000, 0x00200800, 0x00200000, 0x04000802,
+	0x04000802, 0x04200002, 0x04200002, 0x00000002,
+	0x00200002, 0x04000000, 0x04000800, 0x00200000,
+	0x04200800, 0x00000802, 0x00200802, 0x04200800,
+	0x00000802, 0x04000002, 0x04200802, 0x04200000,
+	0x00200800, 0x00000000, 0x00000002, 0x04200802,
+	0x00000000, 0x00200802, 0x04200000, 0x00000800,
+	0x04000002, 0x04000800, 0x00000800, 0x00200002
+};
+
+static const u32 S8[64] = {
+	0x10001040, 0x00001000, 0x00040000, 0x10041040,
+	0x10000000, 0x10001040, 0x00000040, 0x10000000,
+	0x00040040, 0x10040000, 0x10041040, 0x00041000,
+	0x10041000, 0x00041040, 0x00001000, 0x00000040,
+	0x10040000, 0x10000040, 0x10001000, 0x00001040,
+	0x00041000, 0x00040040, 0x10040040, 0x10041000,
+	0x00001040, 0x00000000, 0x00000000, 0x10040040,
+	0x10000040, 0x10001000, 0x00041040, 0x00040000,
+	0x00041040, 0x00040000, 0x10041000, 0x00001000,
+	0x00000040, 0x10040040, 0x00001000, 0x00041040,
+	0x10001000, 0x00000040, 0x10000040, 0x10040000,
+	0x10040040, 0x10000000, 0x00040000, 0x10001040,
+	0x00000000, 0x10041040, 0x00040040, 0x10000040,
+	0x10040000, 0x10001000, 0x10001040, 0x00000000,
+	0x10041040, 0x00041000, 0x00041000, 0x00001040,
+	0x00001040, 0x00040040, 0x10000000, 0x10041000
+};
+
+/* Encryption components: IP, FP, and round function */
+
+#define IP(L, R, T)		\
+	ROL(R, 4);		\
+	T  = L;			\
+	L ^= R;			\
+	L &= 0xf0f0f0f0;	\
+	R ^= L;			\
+	L ^= T;			\
+	ROL(R, 12);		\
+	T  = L;			\
+	L ^= R;			\
+	L &= 0xffff0000;	\
+	R ^= L;			\
+	L ^= T;			\
+	ROR(R, 14);		\
+	T  = L;			\
+	L ^= R;			\
+	L &= 0xcccccccc;	\
+	R ^= L;			\
+	L ^= T;			\
+	ROL(R, 6);		\
+	T  = L;			\
+	L ^= R;			\
+	L &= 0xff00ff00;	\
+	R ^= L;			\
+	L ^= T;			\
+	ROR(R, 7);		\
+	T  = L;			\
+	L ^= R;			\
+	L &= 0xaaaaaaaa;	\
+	R ^= L;			\
+	L ^= T;			\
+	ROL(L, 1);
+
+#define FP(L, R, T)		\
+	ROR(L, 1);		\
+	T  = L;			\
+	L ^= R;			\
+	L &= 0xaaaaaaaa;	\
+	R ^= L;			\
+	L ^= T;			\
+	ROL(R, 7);		\
+	T  = L;			\
+	L ^= R;			\
+	L &= 0xff00ff00;	\
+	R ^= L;			\
+	L ^= T;			\
+	ROR(R, 6);		\
+	T  = L;			\
+	L ^= R;			\
+	L &= 0xcccccccc;	\
+	R ^= L;			\
+	L ^= T;			\
+	ROL(R, 14);		\
+	T  = L;			\
+	L ^= R;			\
+	L &= 0xffff0000;	\
+	R ^= L;			\
+	L ^= T;			\
+	ROR(R, 12);		\
+	T  = L;			\
+	L ^= R;			\
+	L &= 0xf0f0f0f0;	\
+	R ^= L;			\
+	L ^= T;			\
+	ROR(R, 4);
+
+#define ROUND(L, R, A, B, K, d)					\
+	B = K[0];			A = K[1];	K += d;	\
+	B ^= R;				A ^= R;			\
+	B &= 0x3f3f3f3f;		ROR(A, 4);		\
+	L ^= S8[0xff & B];		A &= 0x3f3f3f3f;	\
+	L ^= S6[0xff & (B >> 8)];	B >>= 16;		\
+	L ^= S7[0xff & A];					\
+	L ^= S5[0xff & (A >> 8)];	A >>= 16;		\
+	L ^= S4[0xff & B];					\
+	L ^= S2[0xff & (B >> 8)];				\
+	L ^= S3[0xff & A];					\
+	L ^= S1[0xff & (A >> 8)];
 
 /*
+ * PC2 lookup tables are organized as 2 consecutive sets of 4 interleaved
+ * tables of 128 elements.  One set is for C_i and the other for D_i, while
+ * the 4 interleaved tables correspond to four 7-bit subsets of C_i or D_i.
+ *
+ * After PC1 each of the variables a,b,c,d contains a 7 bit subset of C_i
+ * or D_i in bits 7-1 (bit 0 being the least significant).
+ */
+
+#define T1(x) pt[2 * (x) + 0]
+#define T2(x) pt[2 * (x) + 1]
+#define T3(x) pt[2 * (x) + 2]
+#define T4(x) pt[2 * (x) + 3]
+
+#define PC2(a, b, c, d) (T4(d) | T3(c) | T2(b) | T1(a))
+
+/*
+ * Encryption key expansion
+ *
  * RFC2451: Weak key checks SHOULD be performed.
+ *
+ * FIPS 74:
+ *
+ *   Keys having duals are keys which produce all zeros, all ones, or
+ *   alternating zero-one patterns in the C and D registers after Permuted
+ *   Choice 1 has operated on the key.
+ *
  */
-static int setkey(u32 *expkey, const u8 *key, unsigned int keylen, u32 *flags)
+static unsigned long ekey(u32 *pe, const u8 *k)
 {
-	const u8 *k;
-	u8 *b0, *b1;
-	u32 n, w;
-	u8 bits0[56], bits1[56];
-
-	n  = parity[key[0]]; n <<= 4;
-	n |= parity[key[1]]; n <<= 4;
-	n |= parity[key[2]]; n <<= 4;
-	n |= parity[key[3]]; n <<= 4;
-	n |= parity[key[4]]; n <<= 4;
-	n |= parity[key[5]]; n <<= 4;
-	n |= parity[key[6]]; n <<= 4;
-	n |= parity[key[7]];
-	w = 0x88888888L;
-	
-	if ((*flags & CRYPTO_TFM_REQ_WEAK_KEY)
-	    && !((n - (w >> 3)) & w)) {  /* 1 in 10^10 keys passes this test */
-		if (n < 0x41415151) {
-			if (n < 0x31312121) {
-				if (n < 0x14141515) {
-					/* 01 01 01 01 01 01 01 01 */
-					if (n == 0x11111111) goto weak;
-					/* 01 1F 01 1F 01 0E 01 0E */
-					if (n == 0x13131212) goto weak;
-				} else {
-					/* 01 E0 01 E0 01 F1 01 F1 */
-					if (n == 0x14141515) goto weak;
-					/* 01 FE 01 FE 01 FE 01 FE */
-					if (n == 0x16161616) goto weak;
-				}
-			} else {
-				if (n < 0x34342525) {
-					/* 1F 01 1F 01 0E 01 0E 01 */
-					if (n == 0x31312121) goto weak;
-					/* 1F 1F 1F 1F 0E 0E 0E 0E (?) */
-					if (n == 0x33332222) goto weak;
-				} else {
-					/* 1F E0 1F E0 0E F1 0E F1 */
-					if (n == 0x34342525) goto weak;
-					/* 1F FE 1F FE 0E FE 0E FE */
-					if (n == 0x36362626) goto weak;
-				}
-			}
-		} else {
-			if (n < 0x61616161) {
-				if (n < 0x44445555) {
-					/* E0 01 E0 01 F1 01 F1 01 */
-					if (n == 0x41415151) goto weak;
-					/* E0 1F E0 1F F1 0E F1 0E */
-					if (n == 0x43435252) goto weak;
-				} else {
-					/* E0 E0 E0 E0 F1 F1 F1 F1 (?) */
-					if (n == 0x44445555) goto weak;
-					/* E0 FE E0 FE F1 FE F1 FE */
-					if (n == 0x46465656) goto weak;
-				}
-			} else {
-				if (n < 0x64646565) {
-					/* FE 01 FE 01 FE 01 FE 01 */
-					if (n == 0x61616161) goto weak;
-					/* FE 1F FE 1F FE 0E FE 0E */
-					if (n == 0x63636262) goto weak;
-				} else {
-					/* FE E0 FE E0 FE F1 FE F1 */
-					if (n == 0x64646565) goto weak;
-					/* FE FE FE FE FE FE FE FE */
-					if (n == 0x66666666) goto weak;
-				}
-			}
-		}
-	
-		goto not_weak;
-weak:
-		*flags |= CRYPTO_TFM_RES_WEAK_KEY;
-		return -EINVAL;
+	/* K&R: long is at least 32 bits */
+	unsigned long a, b, c, d, w;
+	const u32 *pt = pc2;
+
+	d = k[4]; d &= 0x0e; d <<= 4; d |= k[0] & 0x1e; d = pc1[d];
+	c = k[5]; c &= 0x0e; c <<= 4; c |= k[1] & 0x1e; c = pc1[c];
+	b = k[6]; b &= 0x0e; b <<= 4; b |= k[2] & 0x1e; b = pc1[b];
+	a = k[7]; a &= 0x0e; a <<= 4; a |= k[3] & 0x1e; a = pc1[a];
+
+	pe[15 * 2 + 0] = PC2(a, b, c, d); d = rs[d];
+	pe[14 * 2 + 0] = PC2(d, a, b, c); c = rs[c]; b = rs[b];
+	pe[13 * 2 + 0] = PC2(b, c, d, a); a = rs[a]; d = rs[d];
+	pe[12 * 2 + 0] = PC2(d, a, b, c); c = rs[c]; b = rs[b];
+	pe[11 * 2 + 0] = PC2(b, c, d, a); a = rs[a]; d = rs[d];
+	pe[10 * 2 + 0] = PC2(d, a, b, c); c = rs[c]; b = rs[b];
+	pe[ 9 * 2 + 0] = PC2(b, c, d, a); a = rs[a]; d = rs[d];
+	pe[ 8 * 2 + 0] = PC2(d, a, b, c); c = rs[c];
+	pe[ 7 * 2 + 0] = PC2(c, d, a, b); b = rs[b]; a = rs[a];
+	pe[ 6 * 2 + 0] = PC2(a, b, c, d); d = rs[d]; c = rs[c];
+	pe[ 5 * 2 + 0] = PC2(c, d, a, b); b = rs[b]; a = rs[a];
+	pe[ 4 * 2 + 0] = PC2(a, b, c, d); d = rs[d]; c = rs[c];
+	pe[ 3 * 2 + 0] = PC2(c, d, a, b); b = rs[b]; a = rs[a];
+	pe[ 2 * 2 + 0] = PC2(a, b, c, d); d = rs[d]; c = rs[c];
+	pe[ 1 * 2 + 0] = PC2(c, d, a, b); b = rs[b];
+	pe[ 0 * 2 + 0] = PC2(b, c, d, a);
+
+	/* Check if first half is weak */
+	w  = (a ^ c) | (b ^ d) | (rs[a] ^ c) | (b ^ rs[d]);
+
+	/* Skip to next table set */
+	pt += 512;
+
+	d = k[0]; d &= 0xe0; d >>= 4; d |= k[4] & 0xf0; d = pc1[d + 1];
+	c = k[1]; c &= 0xe0; c >>= 4; c |= k[5] & 0xf0; c = pc1[c + 1];
+	b = k[2]; b &= 0xe0; b >>= 4; b |= k[6] & 0xf0; b = pc1[b + 1];
+	a = k[3]; a &= 0xe0; a >>= 4; a |= k[7] & 0xf0; a = pc1[a + 1];
+
+	/* Check if second half is weak */
+	w |= (a ^ c) | (b ^ d) | (rs[a] ^ c) | (b ^ rs[d]);
+
+	pe[15 * 2 + 1] = PC2(a, b, c, d); d = rs[d];
+	pe[14 * 2 + 1] = PC2(d, a, b, c); c = rs[c]; b = rs[b];
+	pe[13 * 2 + 1] = PC2(b, c, d, a); a = rs[a]; d = rs[d];
+	pe[12 * 2 + 1] = PC2(d, a, b, c); c = rs[c]; b = rs[b];
+	pe[11 * 2 + 1] = PC2(b, c, d, a); a = rs[a]; d = rs[d];
+	pe[10 * 2 + 1] = PC2(d, a, b, c); c = rs[c]; b = rs[b];
+	pe[ 9 * 2 + 1] = PC2(b, c, d, a); a = rs[a]; d = rs[d];
+	pe[ 8 * 2 + 1] = PC2(d, a, b, c); c = rs[c];
+	pe[ 7 * 2 + 1] = PC2(c, d, a, b); b = rs[b]; a = rs[a];
+	pe[ 6 * 2 + 1] = PC2(a, b, c, d); d = rs[d]; c = rs[c];
+	pe[ 5 * 2 + 1] = PC2(c, d, a, b); b = rs[b]; a = rs[a];
+	pe[ 4 * 2 + 1] = PC2(a, b, c, d); d = rs[d]; c = rs[c];
+	pe[ 3 * 2 + 1] = PC2(c, d, a, b); b = rs[b]; a = rs[a];
+	pe[ 2 * 2 + 1] = PC2(a, b, c, d); d = rs[d]; c = rs[c];
+	pe[ 1 * 2 + 1] = PC2(c, d, a, b); b = rs[b];
+	pe[ 0 * 2 + 1] = PC2(b, c, d, a);
+
+	/* Fixup: 2413 5768 -> 1357 2468 */
+	for (d = 0; d < 16; ++d) {
+		a = pe[2 * d];
+		b = pe[2 * d + 1];
+		c = a ^ b;
+		c &= 0xffff0000;
+		a ^= c;
+		b ^= c;
+		ROL(b, 18);
+		pe[2 * d] = a;
+		pe[2 * d + 1] = b;
 	}
 
-not_weak:
-
-	/* explode the bits */
-	n = 56;
-	b0 = bits0;
-	b1 = bits1;
-	
-	do {
-		w = (256 | *key++) << 2;
-		do {
-			--n;
-			b1[n] = 8 & w;
-			w >>= 1;
-			b0[n] = 4 & w;
-		} while ( w >= 16 );
-	} while ( n );
-	
-	/* put the bits in the correct places */
-	n = 16;
-	k = rotors;
-	
-	do {
-		w   = (b1[k[ 0   ]] | b0[k[ 1   ]]) << 4;
-		w  |= (b1[k[ 2   ]] | b0[k[ 3   ]]) << 2;
-		w  |=  b1[k[ 4   ]] | b0[k[ 5   ]];
-		w <<= 8;
-		w  |= (b1[k[ 6   ]] | b0[k[ 7   ]]) << 4;
-		w  |= (b1[k[ 8   ]] | b0[k[ 9   ]]) << 2;
-		w  |=  b1[k[10   ]] | b0[k[11   ]];
-		w <<= 8;
-		w  |= (b1[k[12   ]] | b0[k[13   ]]) << 4;
-		w  |= (b1[k[14   ]] | b0[k[15   ]]) << 2;
-		w  |=  b1[k[16   ]] | b0[k[17   ]];
-		w <<= 8;
-		w  |= (b1[k[18   ]] | b0[k[19   ]]) << 4;
-		w  |= (b1[k[20   ]] | b0[k[21   ]]) << 2;
-		w  |=  b1[k[22   ]] | b0[k[23   ]];
-		expkey[0] = w;
-		
-		w   = (b1[k[ 0+24]] | b0[k[ 1+24]]) << 4;
-		w  |= (b1[k[ 2+24]] | b0[k[ 3+24]]) << 2;
-		w  |=  b1[k[ 4+24]] | b0[k[ 5+24]];
-		w <<= 8;
-		w  |= (b1[k[ 6+24]] | b0[k[ 7+24]]) << 4;
-		w  |= (b1[k[ 8+24]] | b0[k[ 9+24]]) << 2;
-		w  |=  b1[k[10+24]] | b0[k[11+24]];
-		w <<= 8;
-		w  |= (b1[k[12+24]] | b0[k[13+24]]) << 4;
-		w  |= (b1[k[14+24]] | b0[k[15+24]]) << 2;
-		w  |=  b1[k[16+24]] | b0[k[17+24]];
-		w <<= 8;
-		w  |= (b1[k[18+24]] | b0[k[19+24]]) << 4;
-		w  |= (b1[k[20+24]] | b0[k[21+24]]) << 2;
-		w  |=  b1[k[22+24]] | b0[k[23+24]];
-		
-		ROR(w, 4, 28);      /* could be eliminated */
-		expkey[1] = w;
-
-		k += 48;
-		expkey += 2;
-	} while (--n);
+	/* Zero if weak key */
+	return w;
+}
 
-	return 0;
+/*
+ * Decryption key expansion
+ *
+ * No weak key checking is performed, as this is only used by triple DES
+ *
+ */
+static void dkey(u32 *pe, const u8 *k)
+{
+	/* K&R: long is at least 32 bits */
+	unsigned long a, b, c, d;
+	const u32 *pt = pc2;
+
+	d = k[4]; d &= 0x0e; d <<= 4; d |= k[0] & 0x1e; d = pc1[d];
+	c = k[5]; c &= 0x0e; c <<= 4; c |= k[1] & 0x1e; c = pc1[c];
+	b = k[6]; b &= 0x0e; b <<= 4; b |= k[2] & 0x1e; b = pc1[b];
+	a = k[7]; a &= 0x0e; a <<= 4; a |= k[3] & 0x1e; a = pc1[a];
+
+	pe[ 0 * 2] = PC2(a, b, c, d); d = rs[d];
+	pe[ 1 * 2] = PC2(d, a, b, c); c = rs[c]; b = rs[b];
+	pe[ 2 * 2] = PC2(b, c, d, a); a = rs[a]; d = rs[d];
+	pe[ 3 * 2] = PC2(d, a, b, c); c = rs[c]; b = rs[b];
+	pe[ 4 * 2] = PC2(b, c, d, a); a = rs[a]; d = rs[d];
+	pe[ 5 * 2] = PC2(d, a, b, c); c = rs[c]; b = rs[b];
+	pe[ 6 * 2] = PC2(b, c, d, a); a = rs[a]; d = rs[d];
+	pe[ 7 * 2] = PC2(d, a, b, c); c = rs[c];
+	pe[ 8 * 2] = PC2(c, d, a, b); b = rs[b]; a = rs[a];
+	pe[ 9 * 2] = PC2(a, b, c, d); d = rs[d]; c = rs[c];
+	pe[10 * 2] = PC2(c, d, a, b); b = rs[b]; a = rs[a];
+	pe[11 * 2] = PC2(a, b, c, d); d = rs[d]; c = rs[c];
+	pe[12 * 2] = PC2(c, d, a, b); b = rs[b]; a = rs[a];
+	pe[13 * 2] = PC2(a, b, c, d); d = rs[d]; c = rs[c];
+	pe[14 * 2] = PC2(c, d, a, b); b = rs[b];
+	pe[15 * 2] = PC2(b, c, d, a);
+
+	/* Skip to next table set */
+	pt += 512;
+
+	d = k[0]; d &= 0xe0; d >>= 4; d |= k[4] & 0xf0; d = pc1[d + 1];
+	c = k[1]; c &= 0xe0; c >>= 4; c |= k[5] & 0xf0; c = pc1[c + 1];
+	b = k[2]; b &= 0xe0; b >>= 4; b |= k[6] & 0xf0; b = pc1[b + 1];
+	a = k[3]; a &= 0xe0; a >>= 4; a |= k[7] & 0xf0; a = pc1[a + 1];
+
+	pe[ 0 * 2 + 1] = PC2(a, b, c, d); d = rs[d];
+	pe[ 1 * 2 + 1] = PC2(d, a, b, c); c = rs[c]; b = rs[b];
+	pe[ 2 * 2 + 1] = PC2(b, c, d, a); a = rs[a]; d = rs[d];
+	pe[ 3 * 2 + 1] = PC2(d, a, b, c); c = rs[c]; b = rs[b];
+	pe[ 4 * 2 + 1] = PC2(b, c, d, a); a = rs[a]; d = rs[d];
+	pe[ 5 * 2 + 1] = PC2(d, a, b, c); c = rs[c]; b = rs[b];
+	pe[ 6 * 2 + 1] = PC2(b, c, d, a); a = rs[a]; d = rs[d];
+	pe[ 7 * 2 + 1] = PC2(d, a, b, c); c = rs[c];
+	pe[ 8 * 2 + 1] = PC2(c, d, a, b); b = rs[b]; a = rs[a];
+	pe[ 9 * 2 + 1] = PC2(a, b, c, d); d = rs[d]; c = rs[c];
+	pe[10 * 2 + 1] = PC2(c, d, a, b); b = rs[b]; a = rs[a];
+	pe[11 * 2 + 1] = PC2(a, b, c, d); d = rs[d]; c = rs[c];
+	pe[12 * 2 + 1] = PC2(c, d, a, b); b = rs[b]; a = rs[a];
+	pe[13 * 2 + 1] = PC2(a, b, c, d); d = rs[d]; c = rs[c];
+	pe[14 * 2 + 1] = PC2(c, d, a, b); b = rs[b];
+	pe[15 * 2 + 1] = PC2(b, c, d, a);
+
+	/* Fixup: 2413 5768 -> 1357 2468 */
+	for (d = 0; d < 16; ++d) {
+		a = pe[2 * d];
+		b = pe[2 * d + 1];
+		c = a ^ b;
+		c &= 0xffff0000;
+		a ^= c;
+		b ^= c;
+		ROL(b, 18);
+		pe[2 * d] = a;
+		pe[2 * d + 1] = b;
+	}
 }
 
 static int des_setkey(void *ctx, const u8 *key, unsigned int keylen, u32 *flags)
 {
-	return setkey(((struct des_ctx *)ctx)->expkey, key, keylen, flags);
+	struct des_ctx *dctx = ctx;
+	u32 tmp[DES_EXPKEY_WORDS];
+	int ret;
+
+	/* Expand to tmp */
+	ret = ekey(tmp, key);
+
+	if (unlikely(ret == 0) && (*flags & CRYPTO_TFM_REQ_WEAK_KEY)) {
+		*flags |= CRYPTO_TFM_RES_WEAK_KEY;
+		return -EINVAL;
+	}
+
+	/* Copy to output */
+	memcpy(dctx->expkey, tmp, sizeof(dctx->expkey));
+
+	return 0;
 }
 
 static void des_encrypt(void *ctx, u8 *dst, const u8 *src)
 {
-	des_small_fips_encrypt(((struct des_ctx *)ctx)->expkey, dst, src);
+	const u32 *K = ((struct des_ctx *)ctx)->expkey;
+	const __le32 *s = (const __le32 *)src;
+	__le32 *d = (__le32 *)dst;
+	u32 L, R, A, B;
+	int i;
+
+	L = le32_to_cpu(s[0]);
+	R = le32_to_cpu(s[1]);
+
+	IP(L, R, A);
+	for (i = 0; i < 8; i++) {
+		ROUND(L, R, A, B, K, 2);
+		ROUND(R, L, A, B, K, 2);
+	}
+	FP(R, L, A);
+
+	d[0] = cpu_to_le32(R);
+	d[1] = cpu_to_le32(L);
 }
 
 static void des_decrypt(void *ctx, u8 *dst, const u8 *src)
 {
-	des_small_fips_decrypt(((struct des_ctx *)ctx)->expkey, dst, src);
+	const u32 *K = ((struct des_ctx *)ctx)->expkey + DES_EXPKEY_WORDS - 2;
+	const __le32 *s = (const __le32 *)src;
+	__le32 *d = (__le32 *)dst;
+	u32 L, R, A, B;
+	int i;
+
+	L = le32_to_cpu(s[0]);
+	R = le32_to_cpu(s[1]);
+
+	IP(L, R, A);
+	for (i = 0; i < 8; i++) {
+		ROUND(L, R, A, B, K, -2);
+		ROUND(R, L, A, B, K, -2);
+	}
+	FP(R, L, A);
+
+	d[0] = cpu_to_le32(R);
+	d[1] = cpu_to_le32(L);
 }
 
-/* 
+/*
  * RFC2451:
  *
  *   For DES-EDE3, there is no known need to reject weak or
@@ -1199,44 +859,86 @@ static void des_decrypt(void *ctx, u8 *d
  *
  */
 static int des3_ede_setkey(void *ctx, const u8 *key,
-                           unsigned int keylen, u32 *flags)
+			   unsigned int keylen, u32 *flags)
 {
-	unsigned int i, off;
+	const u32 *K = (const u32 *)key;
 	struct des3_ede_ctx *dctx = ctx;
+	u32 *expkey = dctx->expkey;
 
-	if (!(memcmp(key, &key[DES_KEY_SIZE], DES_KEY_SIZE) && 
-	    memcmp(&key[DES_KEY_SIZE], &key[DES_KEY_SIZE * 2],
-	    					DES_KEY_SIZE))) {
-
+	if (unlikely(!((K[0] ^ K[2]) | (K[1] ^ K[3])) ||
+		     !((K[2] ^ K[4]) | (K[3] ^ K[5]))))
+	{
 		*flags |= CRYPTO_TFM_RES_BAD_KEY_SCHED;
 		return -EINVAL;
 	}
-	
-	for (i = 0, off = 0; i < 3; i++, off += DES_EXPKEY_WORDS,
-							key += DES_KEY_SIZE) {
-		int ret = setkey(&dctx->expkey[off], key, DES_KEY_SIZE, flags);
-		if (ret < 0)
-			return ret;
-	}	
+
+	ekey(expkey, key); expkey += DES_EXPKEY_WORDS; key += DES_KEY_SIZE;
+	dkey(expkey, key); expkey += DES_EXPKEY_WORDS; key += DES_KEY_SIZE;
+	ekey(expkey, key);
+
 	return 0;
 }
 
 static void des3_ede_encrypt(void *ctx, u8 *dst, const u8 *src)
 {
 	struct des3_ede_ctx *dctx = ctx;
-	
-	des_small_fips_encrypt(dctx->expkey, dst, src);
-	des_small_fips_decrypt(&dctx->expkey[DES_EXPKEY_WORDS], dst, dst);
-	des_small_fips_encrypt(&dctx->expkey[DES_EXPKEY_WORDS * 2], dst, dst);
+	const u32 *K = dctx->expkey;
+	const __le32 *s = (const __le32 *)src;
+	__le32 *d = (__le32 *)dst;
+	u32 L, R, A, B;
+	int i;
+
+	L = le32_to_cpu(s[0]);
+	R = le32_to_cpu(s[1]);
+
+	IP(L, R, A);
+	for (i = 0; i < 8; i++) {
+		ROUND(L, R, A, B, K, 2);
+		ROUND(R, L, A, B, K, 2);
+	}
+	for (i = 0; i < 8; i++) {
+		ROUND(R, L, A, B, K, 2);
+		ROUND(L, R, A, B, K, 2);
+	}
+	for (i = 0; i < 8; i++) {
+		ROUND(L, R, A, B, K, 2);
+		ROUND(R, L, A, B, K, 2);
+	}
+	FP(R, L, A);
+
+	d[0] = cpu_to_le32(R);
+	d[1] = cpu_to_le32(L);
 }
 
 static void des3_ede_decrypt(void *ctx, u8 *dst, const u8 *src)
 {
 	struct des3_ede_ctx *dctx = ctx;
+	const u32 *K = dctx->expkey + DES3_EDE_EXPKEY_WORDS - 2;
+	const __le32 *s = (const __le32 *)src;
+	__le32 *d = (__le32 *)dst;
+	u32 L, R, A, B;
+	int i;
+
+	L = le32_to_cpu(s[0]);
+	R = le32_to_cpu(s[1]);
+
+	IP(L, R, A);
+	for (i = 0; i < 8; i++) {
+		ROUND(L, R, A, B, K, -2);
+		ROUND(R, L, A, B, K, -2);
+	}
+	for (i = 0; i < 8; i++) {
+		ROUND(R, L, A, B, K, -2);
+		ROUND(L, R, A, B, K, -2);
+	}
+	for (i = 0; i < 8; i++) {
+		ROUND(L, R, A, B, K, -2);
+		ROUND(R, L, A, B, K, -2);
+	}
+	FP(R, L, A);
 
-	des_small_fips_decrypt(&dctx->expkey[DES_EXPKEY_WORDS * 2], dst, src);
-	des_small_fips_encrypt(&dctx->expkey[DES_EXPKEY_WORDS], dst, dst);
-	des_small_fips_decrypt(dctx->expkey, dst, dst);
+	d[0] = cpu_to_le32(R);
+	d[1] = cpu_to_le32(L);
 }
 
 static struct crypto_alg des_alg = {
@@ -1249,7 +951,7 @@ static struct crypto_alg des_alg = {
 	.cra_u			=	{ .cipher = {
 	.cia_min_keysize	=	DES_KEY_SIZE,
 	.cia_max_keysize	=	DES_KEY_SIZE,
-	.cia_setkey		= 	des_setkey,
+	.cia_setkey		=	des_setkey,
 	.cia_encrypt		=	des_encrypt,
 	.cia_decrypt		=	des_decrypt } }
 };
@@ -1264,9 +966,9 @@ static struct crypto_alg des3_ede_alg = 
 	.cra_u			=	{ .cipher = {
 	.cia_min_keysize	=	DES3_EDE_KEY_SIZE,
 	.cia_max_keysize	=	DES3_EDE_KEY_SIZE,
-	.cia_setkey	   	= 	des3_ede_setkey,
-	.cia_encrypt	 	=	des3_ede_encrypt,
-	.cia_decrypt	  	=	des3_ede_decrypt } }
+	.cia_setkey		=	des3_ede_setkey,
+	.cia_encrypt		=	des3_ede_encrypt,
+	.cia_decrypt		=	des3_ede_decrypt } }
 };
 
 MODULE_ALIAS("des3_ede");
@@ -1274,7 +976,7 @@ MODULE_ALIAS("des3_ede");
 static int __init init(void)
 {
 	int ret = 0;
-	
+
 	ret = crypto_register_alg(&des_alg);
 	if (ret < 0)
 		goto out;
@@ -1282,7 +984,7 @@ static int __init init(void)
 	ret = crypto_register_alg(&des3_ede_alg);
 	if (ret < 0)
 		crypto_unregister_alg(&des_alg);
-out:	
+out:
 	return ret;
 }
 
@@ -1297,3 +999,4 @@ module_exit(fini);
 
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("DES & Triple DES EDE Cipher Algorithms");
+MODULE_AUTHOR("Dag Arne Osvik <da@osvik.no>");
diff --git a/crypto/hmac.c b/crypto/hmac.c
--- a/crypto/hmac.c
+++ b/crypto/hmac.c
@@ -49,8 +49,7 @@ int crypto_alloc_hmac_block(struct crypt
 
 void crypto_free_hmac_block(struct crypto_tfm *tfm)
 {
-	if (tfm->crt_digest.dit_hmac_block)
-		kfree(tfm->crt_digest.dit_hmac_block);
+	kfree(tfm->crt_digest.dit_hmac_block);
 }
 
 void crypto_hmac_init(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen)
diff --git a/crypto/internal.h b/crypto/internal.h
--- a/crypto/internal.h
+++ b/crypto/internal.h
@@ -16,7 +16,7 @@
 #include <linux/highmem.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
-#include <linux/kmod.h>
+#include <linux/kernel.h>
 #include <asm/kmap_types.h>
 
 extern enum km_type crypto_km_types[];
@@ -42,20 +42,6 @@ static inline void crypto_yield(struct c
 		cond_resched();
 }
 
-static inline void *crypto_tfm_ctx(struct crypto_tfm *tfm)
-{
-	return (void *)&tfm[1];
-}
-
-struct crypto_alg *crypto_alg_lookup(const char *name);
-
-/* A far more intelligent version of this is planned.  For now, just
- * try an exact match on the name of the algorithm. */
-static inline struct crypto_alg *crypto_alg_mod_lookup(const char *name)
-{
-	return try_then_request_module(crypto_alg_lookup(name), name);
-}
-
 #ifdef CONFIG_CRYPTO_HMAC
 int crypto_alloc_hmac_block(struct crypto_tfm *tfm);
 void crypto_free_hmac_block(struct crypto_tfm *tfm);
@@ -76,6 +62,33 @@ static inline void crypto_init_proc(void
 { }
 #endif
 
+static inline unsigned int crypto_digest_ctxsize(struct crypto_alg *alg,
+						 int flags)
+{
+	return alg->cra_ctxsize;
+}
+
+static inline unsigned int crypto_cipher_ctxsize(struct crypto_alg *alg,
+						 int flags)
+{
+	unsigned int len = alg->cra_ctxsize;
+	
+	switch (flags & CRYPTO_TFM_MODE_MASK) {
+	case CRYPTO_TFM_MODE_CBC:
+		len = ALIGN(len, (unsigned long)alg->cra_alignmask + 1);
+		len += alg->cra_blocksize;
+		break;
+	}
+
+	return len;
+}
+
+static inline unsigned int crypto_compress_ctxsize(struct crypto_alg *alg,
+						   int flags)
+{
+	return alg->cra_ctxsize;
+}
+
 int crypto_init_digest_flags(struct crypto_tfm *tfm, u32 flags);
 int crypto_init_cipher_flags(struct crypto_tfm *tfm, u32 flags);
 int crypto_init_compress_flags(struct crypto_tfm *tfm, u32 flags);
diff --git a/crypto/scatterwalk.c b/crypto/scatterwalk.c
--- a/crypto/scatterwalk.c
+++ b/crypto/scatterwalk.c
@@ -100,7 +100,7 @@ void scatterwalk_done(struct scatter_wal
 int scatterwalk_copychunks(void *buf, struct scatter_walk *walk,
 			   size_t nbytes, int out)
 {
-	do {
+	while (nbytes > walk->len_this_page) {
 		memcpy_dir(buf, walk->data, walk->len_this_page, out);
 		buf += walk->len_this_page;
 		nbytes -= walk->len_this_page;
@@ -108,7 +108,7 @@ int scatterwalk_copychunks(void *buf, st
 		scatterwalk_unmap(walk, out);
 		scatterwalk_pagedone(walk, out, 1);
 		scatterwalk_map(walk, out);
-	} while (nbytes > walk->len_this_page);
+	}
 
 	memcpy_dir(buf, walk->data, nbytes, out);
 	return nbytes;
diff --git a/crypto/scatterwalk.h b/crypto/scatterwalk.h
--- a/crypto/scatterwalk.h
+++ b/crypto/scatterwalk.h
@@ -40,10 +40,10 @@ static inline int scatterwalk_samebuf(st
 	       walk_in->offset == walk_out->offset;
 }
 
-static inline int scatterwalk_across_pages(struct scatter_walk *walk,
-					   unsigned int nbytes)
+static inline unsigned int scatterwalk_clamp(struct scatter_walk *walk,
+					     unsigned int nbytes)
 {
-	return nbytes > walk->len_this_page;
+	return nbytes > walk->len_this_page ? walk->len_this_page : nbytes;
 }
 
 static inline void scatterwalk_advance(struct scatter_walk *walk,
@@ -55,6 +55,12 @@ static inline void scatterwalk_advance(s
 	walk->len_this_segment -= nbytes;
 }
 
+static inline unsigned int scatterwalk_aligned(struct scatter_walk *walk,
+					       unsigned int alignmask)
+{
+	return !(walk->offset & alignmask);
+}
+
 void scatterwalk_start(struct scatter_walk *walk, struct scatterlist *sg);
 int scatterwalk_copychunks(void *buf, struct scatter_walk *walk, size_t nbytes, int out);
 void scatterwalk_map(struct scatter_walk *walk, int out);
diff --git a/crypto/serpent.c b/crypto/serpent.c
--- a/crypto/serpent.c
+++ b/crypto/serpent.c
@@ -210,7 +210,6 @@
 	x4 ^= x2;
 
 struct serpent_ctx {
-	u8 iv[SERPENT_BLOCK_SIZE];
 	u32 expkey[SERPENT_EXPKEY_WORDS];
 };
 
diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c
--- a/crypto/tcrypt.c
+++ b/crypto/tcrypt.c
@@ -1,4 +1,4 @@
-/* 
+/*
  * Quick & dirty crypto testing module.
  *
  * This will only exist until we have a better testing mechanism
@@ -9,11 +9,12 @@
  *
  * 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) 
+ * Software Foundation; either version 2 of the License, or (at your option)
  * any later version.
  *
- * 14 - 09 - 2003 
- *	Rewritten by Kartikey Mahendra Bhatt
+ * 2004-08-09 Added cipher speed tests (Reyk Floeter <reyk@vantronix.net>)
+ * 2003-09-14 Rewritten by Kartikey Mahendra Bhatt
+ *
  */
 
 #include <linux/init.h>
@@ -25,12 +26,15 @@
 #include <linux/crypto.h>
 #include <linux/highmem.h>
 #include <linux/moduleparam.h>
+#include <linux/jiffies.h>
+#include <linux/timex.h>
+#include <linux/interrupt.h>
 #include "tcrypt.h"
 
 /*
  * Need to kmalloc() memory for testing kmap().
  */
-#define TVMEMSIZE	4096
+#define TVMEMSIZE	16384
 #define XBUFSIZE	32768
 
 /*
@@ -55,19 +59,23 @@
 
 static unsigned int IDX[8] = { IDX1, IDX2, IDX3, IDX4, IDX5, IDX6, IDX7, IDX8 };
 
+/*
+ * Used by test_cipher_speed()
+ */
+static unsigned int sec;
+
 static int mode;
 static char *xbuf;
 static char *tvmem;
 
 static char *check[] = {
 	"des", "md5", "des3_ede", "rot13", "sha1", "sha256", "blowfish",
-	"twofish", "serpent", "sha384", "sha512", "md4", "aes", "cast6", 
-	"arc4", "michael_mic", "deflate", "crc32c", "tea", "xtea", 
+	"twofish", "serpent", "sha384", "sha512", "md4", "aes", "cast6",
+	"arc4", "michael_mic", "deflate", "crc32c", "tea", "xtea",
 	"khazad", "wp512", "wp384", "wp256", "tnepres", NULL
 };
 
-static void
-hexdump(unsigned char *buf, unsigned int len)
+static void hexdump(unsigned char *buf, unsigned int len)
 {
 	while (len--)
 		printk("%02x", *buf++);
@@ -75,29 +83,29 @@ hexdump(unsigned char *buf, unsigned int
 	printk("\n");
 }
 
-static void 
-test_hash (char * algo, struct hash_testvec * template, unsigned int tcount)
+static void test_hash(char *algo, struct hash_testvec *template,
+		      unsigned int tcount)
 {
-	char *p; 
-        unsigned int i, j, k, temp;
-        struct scatterlist sg[8];
-        char result[64];
-        struct crypto_tfm *tfm;
-        struct hash_testvec *hash_tv;
-        unsigned int tsize;
-	 
-        printk("\ntesting %s\n", algo);
+	char *p;
+	unsigned int i, j, k, temp;
+	struct scatterlist sg[8];
+	char result[64];
+	struct crypto_tfm *tfm;
+	struct hash_testvec *hash_tv;
+	unsigned int tsize;
+
+	printk("\ntesting %s\n", algo);
 
-	tsize = sizeof (struct hash_testvec);
+	tsize = sizeof(struct hash_testvec);
 	tsize *= tcount;
-	
+
 	if (tsize > TVMEMSIZE) {
 		printk("template (%u) too big for tvmem (%u)\n", tsize, TVMEMSIZE);
 		return;
 	}
 
 	memcpy(tvmem, template, tsize);
-	hash_tv = (void *) tvmem;
+	hash_tv = (void *)tvmem;
 	tfm = crypto_alloc_tfm(algo, 0);
 	if (tfm == NULL) {
 		printk("failed to load transform for %s\n", algo);
@@ -105,70 +113,71 @@ test_hash (char * algo, struct hash_test
 	}
 
 	for (i = 0; i < tcount; i++) {
-		printk ("test %u:\n", i + 1);
-		memset (result, 0, 64);
+		printk("test %u:\n", i + 1);
+		memset(result, 0, 64);
 
 		p = hash_tv[i].plaintext;
-		sg[0].page = virt_to_page (p);
-		sg[0].offset = offset_in_page (p);
+		sg[0].page = virt_to_page(p);
+		sg[0].offset = offset_in_page(p);
 		sg[0].length = hash_tv[i].psize;
 
-		crypto_digest_init (tfm);
+		crypto_digest_init(tfm);
 		if (tfm->crt_u.digest.dit_setkey) {
-			crypto_digest_setkey (tfm, hash_tv[i].key,
-					      hash_tv[i].ksize);
+			crypto_digest_setkey(tfm, hash_tv[i].key,
+					     hash_tv[i].ksize);
 		}
-		crypto_digest_update (tfm, sg, 1);
-		crypto_digest_final (tfm, result);
+		crypto_digest_update(tfm, sg, 1);
+		crypto_digest_final(tfm, result);
 
-		hexdump (result, crypto_tfm_alg_digestsize (tfm));
+		hexdump(result, crypto_tfm_alg_digestsize(tfm));
 		printk("%s\n",
-			memcmp(result, hash_tv[i].digest,
-				crypto_tfm_alg_digestsize(tfm)) ? "fail" :
-			"pass");
+		       memcmp(result, hash_tv[i].digest,
+			      crypto_tfm_alg_digestsize(tfm)) ?
+		       "fail" : "pass");
 	}
 
-	printk ("testing %s across pages\n", algo);
+	printk("testing %s across pages\n", algo);
 
 	/* setup the dummy buffer first */
-        memset(xbuf, 0, XBUFSIZE);
+	memset(xbuf, 0, XBUFSIZE);
 
 	j = 0;
 	for (i = 0; i < tcount; i++) {
 		if (hash_tv[i].np) {
 			j++;
-			printk ("test %u:\n", j);
-			memset (result, 0, 64);
+			printk("test %u:\n", j);
+			memset(result, 0, 64);
 
 			temp = 0;
 			for (k = 0; k < hash_tv[i].np; k++) {
-				memcpy (&xbuf[IDX[k]], hash_tv[i].plaintext + temp, 
-						hash_tv[i].tap[k]);	
+				memcpy(&xbuf[IDX[k]],
+				       hash_tv[i].plaintext + temp,
+				       hash_tv[i].tap[k]);
 				temp += hash_tv[i].tap[k];
 				p = &xbuf[IDX[k]];
-				sg[k].page = virt_to_page (p);
-				sg[k].offset = offset_in_page (p);
+				sg[k].page = virt_to_page(p);
+				sg[k].offset = offset_in_page(p);
 				sg[k].length = hash_tv[i].tap[k];
 			}
 
-			crypto_digest_digest (tfm, sg, hash_tv[i].np, result);
-			
-			hexdump (result, crypto_tfm_alg_digestsize (tfm));
+			crypto_digest_digest(tfm, sg, hash_tv[i].np, result);
+
+			hexdump(result, crypto_tfm_alg_digestsize(tfm));
 			printk("%s\n",
-				memcmp(result, hash_tv[i].digest,
-					crypto_tfm_alg_digestsize(tfm)) ? "fail" :
-				"pass");
+			       memcmp(result, hash_tv[i].digest,
+				      crypto_tfm_alg_digestsize(tfm)) ?
+			       "fail" : "pass");
 		}
 	}
-	
-	crypto_free_tfm (tfm);
+
+	crypto_free_tfm(tfm);
 }
 
 
 #ifdef CONFIG_CRYPTO_HMAC
 
-static void
-test_hmac(char *algo, struct hmac_testvec * template, unsigned int tcount)
+static void test_hmac(char *algo, struct hmac_testvec *template,
+		      unsigned int tcount)
 {
 	char *p;
 	unsigned int i, j, k, temp;
@@ -185,8 +194,8 @@ test_hmac(char *algo, struct hmac_testve
 	}
 
 	printk("\ntesting hmac_%s\n", algo);
-	
-	tsize = sizeof (struct hmac_testvec);
+
+	tsize = sizeof(struct hmac_testvec);
 	tsize *= tcount;
 	if (tsize > TVMEMSIZE) {
 		printk("template (%u) too big for tvmem (%u)\n", tsize,
@@ -195,7 +204,7 @@ test_hmac(char *algo, struct hmac_testve
 	}
 
 	memcpy(tvmem, template, tsize);
-	hmac_tv = (void *) tvmem;
+	hmac_tv = (void *)tvmem;
 
 	for (i = 0; i < tcount; i++) {
 		printk("test %u:\n", i + 1);
@@ -219,34 +228,35 @@ test_hmac(char *algo, struct hmac_testve
 	printk("\ntesting hmac_%s across pages\n", algo);
 
 	memset(xbuf, 0, XBUFSIZE);
-	
+
 	j = 0;
 	for (i = 0; i < tcount; i++) {
 		if (hmac_tv[i].np) {
 			j++;
-			printk ("test %u:\n",j);
-			memset (result, 0, 64);
+			printk("test %u:\n",j);
+			memset(result, 0, 64);
 
 			temp = 0;
 			klen = hmac_tv[i].ksize;
 			for (k = 0; k < hmac_tv[i].np; k++) {
-				memcpy (&xbuf[IDX[k]], hmac_tv[i].plaintext + temp, 
-						hmac_tv[i].tap[k]);	
+				memcpy(&xbuf[IDX[k]],
+				       hmac_tv[i].plaintext + temp,
+				       hmac_tv[i].tap[k]);
 				temp += hmac_tv[i].tap[k];
 				p = &xbuf[IDX[k]];
-				sg[k].page = virt_to_page (p);
-				sg[k].offset = offset_in_page (p);
+				sg[k].page = virt_to_page(p);
+				sg[k].offset = offset_in_page(p);
 				sg[k].length = hmac_tv[i].tap[k];
 			}
 
-			crypto_hmac(tfm, hmac_tv[i].key, &klen, sg, hmac_tv[i].np, 
-					result);
+			crypto_hmac(tfm, hmac_tv[i].key, &klen, sg,
+				    hmac_tv[i].np, result);
 			hexdump(result, crypto_tfm_alg_digestsize(tfm));
-			
+
 			printk("%s\n",
-				memcmp(result, hmac_tv[i].digest,
-					crypto_tfm_alg_digestsize(tfm)) ? "fail" : 
-				"pass");
+			       memcmp(result, hmac_tv[i].digest,
+				      crypto_tfm_alg_digestsize(tfm)) ?
+			       "fail" : "pass");
 		}
 	}
 out:
@@ -255,8 +265,8 @@ out:
 
 #endif	/* CONFIG_CRYPTO_HMAC */
 
-static void
-test_cipher(char * algo, int mode, int enc, struct cipher_testvec * template, unsigned int tcount)
+static void test_cipher(char *algo, int mode, int enc,
+			struct cipher_testvec *template, unsigned int tcount)
 {
 	unsigned int ret, i, j, k, temp;
 	unsigned int tsize;
@@ -265,22 +275,22 @@ test_cipher(char * algo, int mode, int e
 	char *key;
 	struct cipher_testvec *cipher_tv;
 	struct scatterlist sg[8];
-	char e[11], m[4];
+	const char *e, *m;
 
 	if (enc == ENCRYPT)
-	        strncpy(e, "encryption", 11);
+	        e = "encryption";
 	else
-        	strncpy(e, "decryption", 11);
+		e = "decryption";
 	if (mode == MODE_ECB)
-        	strncpy(m, "ECB", 4);
+		m = "ECB";
 	else
-        	strncpy(m, "CBC", 4);
+		m = "CBC";
 
-	printk("\ntesting %s %s %s \n", algo, m, e);
+	printk("\ntesting %s %s %s\n", algo, m, e);
 
-	tsize = sizeof (struct cipher_testvec);	
+	tsize = sizeof (struct cipher_testvec);
 	tsize *= tcount;
-	
+
 	if (tsize > TVMEMSIZE) {
 		printk("template (%u) too big for tvmem (%u)\n", tsize,
 		       TVMEMSIZE);
@@ -288,112 +298,113 @@ test_cipher(char * algo, int mode, int e
 	}
 
 	memcpy(tvmem, template, tsize);
-	cipher_tv = (void *) tvmem;
+	cipher_tv = (void *)tvmem;
+
+	if (mode)
+		tfm = crypto_alloc_tfm(algo, 0);
+	else
+		tfm = crypto_alloc_tfm(algo, CRYPTO_TFM_MODE_CBC);
 
-	if (mode) 
-		tfm = crypto_alloc_tfm (algo, 0);
-	else 
-		tfm = crypto_alloc_tfm (algo, CRYPTO_TFM_MODE_CBC);
-	
 	if (tfm == NULL) {
 		printk("failed to load transform for %s %s\n", algo, m);
 		return;
 	}
-	
+
 	j = 0;
 	for (i = 0; i < tcount; i++) {
 		if (!(cipher_tv[i].np)) {
-			j++;	
+			j++;
 			printk("test %u (%d bit key):\n",
 			j, cipher_tv[i].klen * 8);
 
 			tfm->crt_flags = 0;
-			if (cipher_tv[i].wk) 
+			if (cipher_tv[i].wk)
 				tfm->crt_flags |= CRYPTO_TFM_REQ_WEAK_KEY;
 			key = cipher_tv[i].key;
-	
+
 			ret = crypto_cipher_setkey(tfm, key, cipher_tv[i].klen);
 			if (ret) {
 				printk("setkey() failed flags=%x\n", tfm->crt_flags);
-	
+
 				if (!cipher_tv[i].fail)
 					goto out;
-			}	
+			}
 
 			p = cipher_tv[i].input;
 			sg[0].page = virt_to_page(p);
 			sg[0].offset = offset_in_page(p);
 			sg[0].length = cipher_tv[i].ilen;
-	
+
 			if (!mode) {
 				crypto_cipher_set_iv(tfm, cipher_tv[i].iv,
-					crypto_tfm_alg_ivsize (tfm));
+					crypto_tfm_alg_ivsize(tfm));
 			}
-		
+
 			if (enc)
 				ret = crypto_cipher_encrypt(tfm, sg, sg, cipher_tv[i].ilen);
 			else
 				ret = crypto_cipher_decrypt(tfm, sg, sg, cipher_tv[i].ilen);
-			
-				
+
+
 			if (ret) {
 				printk("%s () failed flags=%x\n", e, tfm->crt_flags);
 				goto out;
-			}	
-	
+			}
+
 			q = kmap(sg[0].page) + sg[0].offset;
 			hexdump(q, cipher_tv[i].rlen);
-	
-			printk("%s\n", 
-				memcmp(q, cipher_tv[i].result, cipher_tv[i].rlen) ? "fail" : 
-			"pass");
+
+			printk("%s\n",
+			       memcmp(q, cipher_tv[i].result,
+				      cipher_tv[i].rlen) ? "fail" : "pass");
 		}
 	}
-	
-	printk("\ntesting %s %s %s across pages (chunking) \n", algo, m, e);
+
+	printk("\ntesting %s %s %s across pages (chunking)\n", algo, m, e);
 	memset(xbuf, 0, XBUFSIZE);
-	
+
 	j = 0;
 	for (i = 0; i < tcount; i++) {
 		if (cipher_tv[i].np) {
-			j++;				
+			j++;
 			printk("test %u (%d bit key):\n",
 			j, cipher_tv[i].klen * 8);
 
-			tfm->crt_flags = 0;			
-			if (cipher_tv[i].wk) 
+			tfm->crt_flags = 0;
+			if (cipher_tv[i].wk)
 				tfm->crt_flags |= CRYPTO_TFM_REQ_WEAK_KEY;
 			key = cipher_tv[i].key;
-			
-			ret = crypto_cipher_setkey(tfm, key, cipher_tv[i].klen);		
+
+			ret = crypto_cipher_setkey(tfm, key, cipher_tv[i].klen);
 			if (ret) {
 				printk("setkey() failed flags=%x\n", tfm->crt_flags);
-				
+
 				if (!cipher_tv[i].fail)
 					goto out;
 			}
 
 			temp = 0;
 			for (k = 0; k < cipher_tv[i].np; k++) {
-				memcpy (&xbuf[IDX[k]], cipher_tv[i].input + temp, 
-						cipher_tv[i].tap[k]);	
+				memcpy(&xbuf[IDX[k]],
+				       cipher_tv[i].input + temp,
+				       cipher_tv[i].tap[k]);
 				temp += cipher_tv[i].tap[k];
 				p = &xbuf[IDX[k]];
-				sg[k].page = virt_to_page (p);
-				sg[k].offset = offset_in_page (p);
+				sg[k].page = virt_to_page(p);
+				sg[k].offset = offset_in_page(p);
 				sg[k].length = cipher_tv[i].tap[k];
 			}
-			
+
 			if (!mode) {
 				crypto_cipher_set_iv(tfm, cipher_tv[i].iv,
-						crypto_tfm_alg_ivsize (tfm));
+						crypto_tfm_alg_ivsize(tfm));
 			}
-			
+
 			if (enc)
 				ret = crypto_cipher_encrypt(tfm, sg, sg, cipher_tv[i].ilen);
 			else
 				ret = crypto_cipher_decrypt(tfm, sg, sg, cipher_tv[i].ilen);
-			
+
 			if (ret) {
 				printk("%s () failed flags=%x\n", e, tfm->crt_flags);
 				goto out;
@@ -404,9 +415,9 @@ test_cipher(char * algo, int mode, int e
 				printk("page %u\n", k);
 				q = kmap(sg[k].page) + sg[k].offset;
 				hexdump(q, cipher_tv[i].tap[k]);
-				printk("%s\n", 
-					memcmp(q, cipher_tv[i].result + temp, 
-						cipher_tv[i].tap[k]) ? "fail" : 
+				printk("%s\n",
+					memcmp(q, cipher_tv[i].result + temp,
+						cipher_tv[i].tap[k]) ? "fail" :
 					"pass");
 				temp += cipher_tv[i].tap[k];
 			}
@@ -417,8 +428,169 @@ out:
 	crypto_free_tfm(tfm);
 }
 
-static void
-test_deflate(void)
+static int test_cipher_jiffies(struct crypto_tfm *tfm, int enc, char *p,
+			       int blen, int sec)
+{
+	struct scatterlist sg[8];
+	unsigned long start, end;
+	int bcount;
+	int ret;
+
+	sg[0].page = virt_to_page(p);
+	sg[0].offset = offset_in_page(p);
+	sg[0].length = blen;
+
+	for (start = jiffies, end = start + sec * HZ, bcount = 0;
+	     time_before(jiffies, end); bcount++) {
+		if (enc)
+			ret = crypto_cipher_encrypt(tfm, sg, sg, blen);
+		else
+			ret = crypto_cipher_decrypt(tfm, sg, sg, blen);
+
+		if (ret)
+			return ret;
+	}
+
+	printk("%d operations in %d seconds (%ld bytes)\n",
+	       bcount, sec, (long)bcount * blen);
+	return 0;
+}
+
+static int test_cipher_cycles(struct crypto_tfm *tfm, int enc, char *p,
+			      int blen)
+{
+	struct scatterlist sg[8];
+	unsigned long cycles = 0;
+	int ret = 0;
+	int i;
+
+	sg[0].page = virt_to_page(p);
+	sg[0].offset = offset_in_page(p);
+	sg[0].length = blen;
+
+	local_bh_disable();
+	local_irq_disable();
+
+	/* Warm-up run. */
+	for (i = 0; i < 4; i++) {
+		if (enc)
+			ret = crypto_cipher_encrypt(tfm, sg, sg, blen);
+		else
+			ret = crypto_cipher_decrypt(tfm, sg, sg, blen);
+
+		if (ret)
+			goto out;
+	}
+
+	/* The real thing. */
+	for (i = 0; i < 8; i++) {
+		cycles_t start, end;
+
+		start = get_cycles();
+		if (enc)
+			ret = crypto_cipher_encrypt(tfm, sg, sg, blen);
+		else
+			ret = crypto_cipher_decrypt(tfm, sg, sg, blen);
+		end = get_cycles();
+
+		if (ret)
+			goto out;
+
+		cycles += end - start;
+	}
+
+out:
+	local_irq_enable();
+	local_bh_enable();
+
+	if (ret == 0)
+		printk("1 operation in %lu cycles (%d bytes)\n",
+		       (cycles + 4) / 8, blen);
+
+	return ret;
+}
+
+static void test_cipher_speed(char *algo, int mode, int enc, unsigned int sec,
+			      struct cipher_testvec *template,
+			      unsigned int tcount, struct cipher_speed *speed)
+{
+	unsigned int ret, i, j, iv_len;
+	unsigned char *key, *p, iv[128];
+	struct crypto_tfm *tfm;
+	const char *e, *m;
+
+	if (enc == ENCRYPT)
+	        e = "encryption";
+	else
+		e = "decryption";
+	if (mode == MODE_ECB)
+		m = "ECB";
+	else
+		m = "CBC";
+
+	printk("\ntesting speed of %s %s %s\n", algo, m, e);
+
+	if (mode)
+		tfm = crypto_alloc_tfm(algo, 0);
+	else
+		tfm = crypto_alloc_tfm(algo, CRYPTO_TFM_MODE_CBC);
+
+	if (tfm == NULL) {
+		printk("failed to load transform for %s %s\n", algo, m);
+		return;
+	}
+
+	for (i = 0; speed[i].klen != 0; i++) {
+		if ((speed[i].blen + speed[i].klen) > TVMEMSIZE) {
+			printk("template (%u) too big for tvmem (%u)\n",
+			       speed[i].blen + speed[i].klen, TVMEMSIZE);
+			goto out;
+		}
+
+		printk("test %u (%d bit key, %d byte blocks): ", i,
+		       speed[i].klen * 8, speed[i].blen);
+
+		memset(tvmem, 0xff, speed[i].klen + speed[i].blen);
+
+		/* set key, plain text and IV */
+		key = (unsigned char *)tvmem;
+		for (j = 0; j < tcount; j++) {
+			if (template[j].klen == speed[i].klen) {
+				key = template[j].key;
+				break;
+			}
+		}
+		p = (unsigned char *)tvmem + speed[i].klen;
+
+		ret = crypto_cipher_setkey(tfm, key, speed[i].klen);
+		if (ret) {
+			printk("setkey() failed flags=%x\n", tfm->crt_flags);
+			goto out;
+		}
+
+		if (!mode) {
+			iv_len = crypto_tfm_alg_ivsize(tfm);
+			memset(&iv, 0xff, iv_len);
+			crypto_cipher_set_iv(tfm, iv, iv_len);
+		}
+
+		if (sec)
+			ret = test_cipher_jiffies(tfm, enc, p, speed[i].blen,
+						  sec);
+		else
+			ret = test_cipher_cycles(tfm, enc, p, speed[i].blen);
+
+		if (ret) {
+			printk("%s() failed flags=%x\n", e, tfm->crt_flags);
+			break;
+		}
+	}
+
+out:
+	crypto_free_tfm(tfm);
+}
+
+static void test_deflate(void)
 {
 	unsigned int i;
 	char result[COMP_BUF_SIZE];
@@ -436,7 +608,7 @@ test_deflate(void)
 	}
 
 	memcpy(tvmem, deflate_comp_tv_template, tsize);
-	tv = (void *) tvmem;
+	tv = (void *)tvmem;
 
 	tfm = crypto_alloc_tfm("deflate", 0);
 	if (tfm == NULL) {
@@ -446,7 +618,7 @@ test_deflate(void)
 
 	for (i = 0; i < DEFLATE_COMP_TEST_VECTORS; i++) {
 		int ilen, ret, dlen = COMP_BUF_SIZE;
-		
+
 		printk("test %u:\n", i + 1);
 		memset(result, 0, sizeof (result));
 
@@ -473,11 +645,11 @@ test_deflate(void)
 	}
 
 	memcpy(tvmem, deflate_decomp_tv_template, tsize);
-	tv = (void *) tvmem;
+	tv = (void *)tvmem;
 
 	for (i = 0; i < DEFLATE_DECOMP_TEST_VECTORS; i++) {
 		int ilen, ret, dlen = COMP_BUF_SIZE;
-		
+
 		printk("test %u:\n", i + 1);
 		memset(result, 0, sizeof (result));
 
@@ -497,8 +669,7 @@ out:
 	crypto_free_tfm(tfm);
 }
 
-static void
-test_crc32c(void)
+static void test_crc32c(void)
 {
 #define NUMVEC 6
 #define VECSIZE 40
@@ -511,7 +682,7 @@ test_crc32c(void)
 		0xd579c862, 0xba979ad0, 0x2b29d913
 	};
 	static u32 tot_vec_results = 0x24c5d375;
-	
+
 	struct scatterlist sg[NUMVEC];
 	struct crypto_tfm *tfm;
 	char *fmtdata = "testing crc32c initialized to %08x: %s\n";
@@ -525,18 +696,18 @@ test_crc32c(void)
 		printk("failed to load transform for crc32c\n");
 		return;
 	}
-	
+
 	crypto_digest_init(tfm);
 	crypto_digest_final(tfm, (u8*)&crc);
 	printk(fmtdata, crc, (crc == 0) ? "pass" : "ERROR");
-	
+
 	/*
 	 * stuff test_vec with known values, simple incrementing
 	 * byte values.
 	 */
 	b = 0;
 	for (i = 0; i < NUMVEC; i++) {
-		for (j = 0; j < VECSIZE; j++) 
+		for (j = 0; j < VECSIZE; j++)
 			test_vec[i][j] = ++b;
 		sg[i].page = virt_to_page(test_vec[i]);
 		sg[i].offset = offset_in_page(test_vec[i]);
@@ -548,11 +719,11 @@ test_crc32c(void)
 	crypto_digest_final(tfm, (u8*)&crc);
 	printk("testing crc32c setkey returns %08x : %s\n", crc, (crc == (SEEDTESTVAL ^ ~(u32)0)) ?
 	       "pass" : "ERROR");
-	
+
 	printk("testing crc32c using update/final:\n");
 
 	pass = 1;		    /* assume all is well */
-	
+
 	for (i = 0; i < NUMVEC; i++) {
 		seed = ~(u32)0;
 		(void)crypto_digest_setkey(tfm, (const u8*)&seed, sizeof(u32));
@@ -591,66 +762,64 @@ test_crc32c(void)
 		printk(" %08x:BAD, wanted %08x\n", crc, tot_vec_results);
 		pass = 0;
 	}
-	
+
 	printk("\n%s\n", pass ? "pass" : "ERROR");
 
 	crypto_free_tfm(tfm);
 	printk("crc32c test complete\n");
 }
 
-static void
-test_available(void)
+static void test_available(void)
 {
 	char **name = check;
-	
+
 	while (*name) {
 		printk("alg %s ", *name);
 		printk((crypto_alg_available(*name, 0)) ?
 			"found\n" : "not found\n");
 		name++;
-	}	
+	}
 }
 
-static void
-do_test(void)
+static void do_test(void)
 {
 	switch (mode) {
 
 	case 0:
 		test_hash("md5", md5_tv_template, MD5_TEST_VECTORS);
-		
+
 		test_hash("sha1", sha1_tv_template, SHA1_TEST_VECTORS);
-		
+
 		//DES
 		test_cipher ("des", MODE_ECB, ENCRYPT, des_enc_tv_template, DES_ENC_TEST_VECTORS);
-                test_cipher ("des", MODE_ECB, DECRYPT, des_dec_tv_template, DES_DEC_TEST_VECTORS);
-                test_cipher ("des", MODE_CBC, ENCRYPT, des_cbc_enc_tv_template, DES_CBC_ENC_TEST_VECTORS);
-                test_cipher ("des", MODE_CBC, DECRYPT, des_cbc_dec_tv_template, DES_CBC_DEC_TEST_VECTORS);
-	
+		test_cipher ("des", MODE_ECB, DECRYPT, des_dec_tv_template, DES_DEC_TEST_VECTORS);
+		test_cipher ("des", MODE_CBC, ENCRYPT, des_cbc_enc_tv_template, DES_CBC_ENC_TEST_VECTORS);
+		test_cipher ("des", MODE_CBC, DECRYPT, des_cbc_dec_tv_template, DES_CBC_DEC_TEST_VECTORS);
+
 		//DES3_EDE
 		test_cipher ("des3_ede", MODE_ECB, ENCRYPT, des3_ede_enc_tv_template, DES3_EDE_ENC_TEST_VECTORS);
-                test_cipher ("des3_ede", MODE_ECB, DECRYPT, des3_ede_dec_tv_template, DES3_EDE_DEC_TEST_VECTORS);
-		
+		test_cipher ("des3_ede", MODE_ECB, DECRYPT, des3_ede_dec_tv_template, DES3_EDE_DEC_TEST_VECTORS);
+
 		test_hash("md4", md4_tv_template, MD4_TEST_VECTORS);
-		
+
 		test_hash("sha256", sha256_tv_template, SHA256_TEST_VECTORS);
-		
+
 		//BLOWFISH
 		test_cipher ("blowfish", MODE_ECB, ENCRYPT, bf_enc_tv_template, BF_ENC_TEST_VECTORS);
 		test_cipher ("blowfish", MODE_ECB, DECRYPT, bf_dec_tv_template, BF_DEC_TEST_VECTORS);
 		test_cipher ("blowfish", MODE_CBC, ENCRYPT, bf_cbc_enc_tv_template, BF_CBC_ENC_TEST_VECTORS);
 		test_cipher ("blowfish", MODE_CBC, DECRYPT, bf_cbc_dec_tv_template, BF_CBC_DEC_TEST_VECTORS);
-		
+
 		//TWOFISH
 		test_cipher ("twofish", MODE_ECB, ENCRYPT, tf_enc_tv_template, TF_ENC_TEST_VECTORS);
 		test_cipher ("twofish", MODE_ECB, DECRYPT, tf_dec_tv_template, TF_DEC_TEST_VECTORS);
 		test_cipher ("twofish", MODE_CBC, ENCRYPT, tf_cbc_enc_tv_template, TF_CBC_ENC_TEST_VECTORS);
 		test_cipher ("twofish", MODE_CBC, DECRYPT, tf_cbc_dec_tv_template, TF_CBC_DEC_TEST_VECTORS);
-		
+
 		//SERPENT
 		test_cipher ("serpent", MODE_ECB, ENCRYPT, serpent_enc_tv_template, SERPENT_ENC_TEST_VECTORS);
 		test_cipher ("serpent", MODE_ECB, DECRYPT, serpent_dec_tv_template, SERPENT_DEC_TEST_VECTORS);
-		
+
 		//TNEPRES
 		test_cipher ("tnepres", MODE_ECB, ENCRYPT, tnepres_enc_tv_template, TNEPRES_ENC_TEST_VECTORS);
 		test_cipher ("tnepres", MODE_ECB, DECRYPT, tnepres_dec_tv_template, TNEPRES_DEC_TEST_VECTORS);
@@ -662,7 +831,7 @@ do_test(void)
 		//CAST5
 		test_cipher ("cast5", MODE_ECB, ENCRYPT, cast5_enc_tv_template, CAST5_ENC_TEST_VECTORS);
 		test_cipher ("cast5", MODE_ECB, DECRYPT, cast5_dec_tv_template, CAST5_DEC_TEST_VECTORS);
-		
+
 		//CAST6
 		test_cipher ("cast6", MODE_ECB, ENCRYPT, cast6_enc_tv_template, CAST6_ENC_TEST_VECTORS);
 		test_cipher ("cast6", MODE_ECB, DECRYPT, cast6_dec_tv_template, CAST6_DEC_TEST_VECTORS);
@@ -702,9 +871,9 @@ do_test(void)
 		test_crc32c();
 #ifdef CONFIG_CRYPTO_HMAC
 		test_hmac("md5", hmac_md5_tv_template, HMAC_MD5_TEST_VECTORS);
-		test_hmac("sha1", hmac_sha1_tv_template, HMAC_SHA1_TEST_VECTORS);		
+		test_hmac("sha1", hmac_sha1_tv_template, HMAC_SHA1_TEST_VECTORS);
 		test_hmac("sha256", hmac_sha256_tv_template, HMAC_SHA256_TEST_VECTORS);
-#endif		
+#endif
 
 		test_hash("michael_mic", michael_mic_tv_template, MICHAEL_MIC_TEST_VECTORS);
 		break;
@@ -726,17 +895,17 @@ do_test(void)
 
 	case 4:
 		test_cipher ("des3_ede", MODE_ECB, ENCRYPT, des3_ede_enc_tv_template, DES3_EDE_ENC_TEST_VECTORS);
-                test_cipher ("des3_ede", MODE_ECB, DECRYPT, des3_ede_dec_tv_template, DES3_EDE_DEC_TEST_VECTORS);
+		test_cipher ("des3_ede", MODE_ECB, DECRYPT, des3_ede_dec_tv_template, DES3_EDE_DEC_TEST_VECTORS);
 		break;
 
 	case 5:
 		test_hash("md4", md4_tv_template, MD4_TEST_VECTORS);
 		break;
-		
+
 	case 6:
 		test_hash("sha256", sha256_tv_template, SHA256_TEST_VECTORS);
 		break;
-	
+
 	case 7:
 		test_cipher ("blowfish", MODE_ECB, ENCRYPT, bf_enc_tv_template, BF_ENC_TEST_VECTORS);
 		test_cipher ("blowfish", MODE_ECB, DECRYPT, bf_dec_tv_template, BF_DEC_TEST_VECTORS);
@@ -750,7 +919,7 @@ do_test(void)
 		test_cipher ("twofish", MODE_CBC, ENCRYPT, tf_cbc_enc_tv_template, TF_CBC_ENC_TEST_VECTORS);
 		test_cipher ("twofish", MODE_CBC, DECRYPT, tf_cbc_dec_tv_template, TF_CBC_DEC_TEST_VECTORS);
 		break;
-		
+
 	case 9:
 		test_cipher ("serpent", MODE_ECB, ENCRYPT, serpent_enc_tv_template, SERPENT_ENC_TEST_VECTORS);
 		test_cipher ("serpent", MODE_ECB, DECRYPT, serpent_dec_tv_template, SERPENT_DEC_TEST_VECTORS);
@@ -758,13 +927,13 @@ do_test(void)
 
 	case 10:
 		test_cipher ("aes", MODE_ECB, ENCRYPT, aes_enc_tv_template, AES_ENC_TEST_VECTORS);
-		test_cipher ("aes", MODE_ECB, DECRYPT, aes_dec_tv_template, AES_DEC_TEST_VECTORS);	
+		test_cipher ("aes", MODE_ECB, DECRYPT, aes_dec_tv_template, AES_DEC_TEST_VECTORS);
 		break;
 
 	case 11:
 		test_hash("sha384", sha384_tv_template, SHA384_TEST_VECTORS);
 		break;
-		
+
 	case 12:
 		test_hash("sha512", sha512_tv_template, SHA512_TEST_VECTORS);
 		break;
@@ -852,21 +1021,84 @@ do_test(void)
 	case 100:
 		test_hmac("md5", hmac_md5_tv_template, HMAC_MD5_TEST_VECTORS);
 		break;
-		
+
 	case 101:
-		test_hmac("sha1", hmac_sha1_tv_template, HMAC_SHA1_TEST_VECTORS);		
+		test_hmac("sha1", hmac_sha1_tv_template, HMAC_SHA1_TEST_VECTORS);
 		break;
-	
+
 	case 102:
 		test_hmac("sha256", hmac_sha256_tv_template, HMAC_SHA256_TEST_VECTORS);
 		break;
 
 #endif
 
+	case 200:
+		test_cipher_speed("aes", MODE_ECB, ENCRYPT, sec, NULL, 0,
+				  aes_speed_template);
+		test_cipher_speed("aes", MODE_ECB, DECRYPT, sec, NULL, 0,
+				  aes_speed_template);
+		test_cipher_speed("aes", MODE_CBC, ENCRYPT, sec, NULL, 0,
+				  aes_speed_template);
+		test_cipher_speed("aes", MODE_CBC, DECRYPT, sec, NULL, 0,
+				  aes_speed_template);
+		break;
+
+	case 201:
+		test_cipher_speed("des3_ede", MODE_ECB, ENCRYPT, sec,
+				  des3_ede_enc_tv_template,
+				  DES3_EDE_ENC_TEST_VECTORS,
+				  des3_ede_speed_template);
+		test_cipher_speed("des3_ede", MODE_ECB, DECRYPT, sec,
+				  des3_ede_dec_tv_template,
+				  DES3_EDE_DEC_TEST_VECTORS,
+				  des3_ede_speed_template);
+		test_cipher_speed("des3_ede", MODE_CBC, ENCRYPT, sec,
+				  des3_ede_enc_tv_template,
+				  DES3_EDE_ENC_TEST_VECTORS,
+				  des3_ede_speed_template);
+		test_cipher_speed("des3_ede", MODE_CBC, DECRYPT, sec,
+				  des3_ede_dec_tv_template,
+				  DES3_EDE_DEC_TEST_VECTORS,
+				  des3_ede_speed_template);
+		break;
+
+	case 202:
+		test_cipher_speed("twofish", MODE_ECB, ENCRYPT, sec, NULL, 0,
+				  twofish_speed_template);
+		test_cipher_speed("twofish", MODE_ECB, DECRYPT, sec, NULL, 0,
+				  twofish_speed_template);
+		test_cipher_speed("twofish", MODE_CBC, ENCRYPT, sec, NULL, 0,
+				  twofish_speed_template);
+		test_cipher_speed("twofish", MODE_CBC, DECRYPT, sec, NULL, 0,
+				  twofish_speed_template);
+		break;
+
+	case 203:
+		test_cipher_speed("blowfish", MODE_ECB, ENCRYPT, sec, NULL, 0,
+				  blowfish_speed_template);
+		test_cipher_speed("blowfish", MODE_ECB, DECRYPT, sec, NULL, 0,
+				  blowfish_speed_template);
+		test_cipher_speed("blowfish", MODE_CBC, ENCRYPT, sec, NULL, 0,
+				  blowfish_speed_template);
+		test_cipher_speed("blowfish", MODE_CBC, DECRYPT, sec, NULL, 0,
+				  blowfish_speed_template);
+		break;
+
+	case 204:
+		test_cipher_speed("des", MODE_ECB, ENCRYPT, sec, NULL, 0,
+				  des_speed_template);
+		test_cipher_speed("des", MODE_ECB, DECRYPT, sec, NULL, 0,
+				  des_speed_template);
+		test_cipher_speed("des", MODE_CBC, ENCRYPT, sec, NULL, 0,
+				  des_speed_template);
+		test_cipher_speed("des", MODE_CBC, DECRYPT, sec, NULL, 0,
+				  des_speed_template);
+		break;
+
 	case 1000:
 		test_available();
 		break;
-		
+
 	default:
 		/* useful for debugging */
 		printk("not testing anything\n");
@@ -874,8 +1106,7 @@ do_test(void)
 	}
 }
 
-static int __init
-init(void)
+static int __init init(void)
 {
 	tvmem = kmalloc(TVMEMSIZE, GFP_KERNEL);
 	if (tvmem == NULL)
@@ -904,6 +1135,9 @@ module_init(init);
 module_exit(fini);
 
 module_param(mode, int, 0);
+module_param(sec, uint, 0);
+MODULE_PARM_DESC(sec, "Length in seconds of speed tests "
+		      "(defaults to zero which uses CPU cycles instead)");
 
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("Quick & dirty crypto testing module");
diff --git a/crypto/tcrypt.h b/crypto/tcrypt.h
--- a/crypto/tcrypt.h
+++ b/crypto/tcrypt.h
@@ -9,10 +9,11 @@
  *
  * 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) 
+ * Software Foundation; either version 2 of the License, or (at your option)
  * any later version.
  *
- * 14 - 09 - 2003 Changes by Kartikey Mahendra Bhatt
+ * 2004-08-09 Cipher speed tests by Reyk Floeter <reyk@vantronix.net>
+ * 2003-09-14 Changes by Kartikey Mahendra Bhatt
  *
  */
 #ifndef _CRYPTO_TCRYPT_H
@@ -29,19 +30,19 @@ struct hash_testvec {
 	unsigned char psize;
 	char digest[MAX_DIGEST_SIZE];
 	unsigned char np;
-	unsigned char tap[MAX_TAP];		
+	unsigned char tap[MAX_TAP];
 	char key[128]; /* only used with keyed hash algorithms */
 	unsigned char ksize;
 };
 
-struct hmac_testvec {	
+struct hmac_testvec {
 	char key[128];
 	unsigned char ksize;
 	char plaintext[128];
 	unsigned char psize;
 	char digest[MAX_DIGEST_SIZE];
 	unsigned char np;
-	unsigned char tap[MAX_TAP];		
+	unsigned char tap[MAX_TAP];
 };
 
 struct cipher_testvec {
@@ -55,7 +56,12 @@ struct cipher_testvec {
 	char result[48];
 	unsigned char rlen;
 	int np;
-	unsigned char tap[MAX_TAP];	
+	unsigned char tap[MAX_TAP];
+};
+
+struct cipher_speed {
+	unsigned char klen;
+	unsigned int blen;
 };
 
 /*
@@ -155,7 +161,7 @@ static struct hash_testvec md5_tv_templa
 #define SHA1_TEST_VECTORS	2
 
 static struct hash_testvec sha1_tv_template[] = {
-	{ 
+	{
 		.plaintext = "abc",
 		.psize	= 3,
 		.digest	= { 0xa9, 0x99, 0x3e, 0x36, 0x47, 0x06, 0x81, 0x6a, 0xba, 0x3e,
@@ -175,8 +181,8 @@ static struct hash_testvec sha1_tv_templ
  */
 #define SHA256_TEST_VECTORS	2
 
-static struct hash_testvec sha256_tv_template[] = {	
-	{ 
+static struct hash_testvec sha256_tv_template[] = {
+	{
 		.plaintext = "abc",
 		.psize	= 3,
 		.digest	= { 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
@@ -201,7 +207,7 @@ static struct hash_testvec sha256_tv_tem
 #define SHA384_TEST_VECTORS	4
 
 static struct hash_testvec sha384_tv_template[] = {
-	{ 
+	{
 		.plaintext= "abc",
 		.psize	= 3,
 		.digest	= { 0xcb, 0x00, 0x75, 0x3f, 0x45, 0xa3, 0x5e, 0x8b,
@@ -221,7 +227,7 @@ static struct hash_testvec sha384_tv_tem
 			    0x5f, 0xe9, 0x5b, 0x1f, 0xe3, 0xc8, 0x45, 0x2b},
 	}, {
 		.plaintext = "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
- 			     "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
+			     "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
 		.psize	= 112,
 		.digest	= { 0x09, 0x33, 0x0c, 0x33, 0xf7, 0x11, 0x47, 0xe8,
 			    0x3d, 0x19, 0x2f, 0xc7, 0x82, 0xcd, 0x1b, 0x47,
@@ -250,7 +256,7 @@ static struct hash_testvec sha384_tv_tem
 #define SHA512_TEST_VECTORS	4
 
 static struct hash_testvec sha512_tv_template[] = {
-	{ 
+	{
 		.plaintext = "abc",
 		.psize	= 3,
 		.digest	= { 0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba,
@@ -303,14 +309,14 @@ static struct hash_testvec sha512_tv_tem
 
 
 /*
- * WHIRLPOOL test vectors from Whirlpool package 
+ * WHIRLPOOL test vectors from Whirlpool package
  * by Vincent Rijmen and Paulo S. L. M. Barreto as part of the NESSIE
  * submission
  */
 #define WP512_TEST_VECTORS	8
 
 static struct hash_testvec wp512_tv_template[] = {
-	{ 
+	{
 		.plaintext = "",
 		.psize	= 0,
 		.digest	= { 0x19, 0xFA, 0x61, 0xD7, 0x55, 0x22, 0xA4, 0x66,
@@ -348,13 +354,13 @@ static struct hash_testvec wp512_tv_temp
 	}, {
 		.plaintext = "message digest",
 		.psize	= 14,
-		.digest	= { 0x37, 0x8C, 0x84, 0xA4, 0x12, 0x6E, 0x2D, 0xC6, 
-			    0xE5, 0x6D, 0xCC, 0x74, 0x58, 0x37, 0x7A, 0xAC, 
-			    0x83, 0x8D, 0x00, 0x03, 0x22, 0x30, 0xF5, 0x3C, 
-			    0xE1, 0xF5, 0x70, 0x0C, 0x0F, 0xFB, 0x4D, 0x3B, 
-			    0x84, 0x21, 0x55, 0x76, 0x59, 0xEF, 0x55, 0xC1, 
-			    0x06, 0xB4, 0xB5, 0x2A, 0xC5, 0xA4, 0xAA, 0xA6, 
-			    0x92, 0xED, 0x92, 0x00, 0x52, 0x83, 0x8F, 0x33, 
+		.digest	= { 0x37, 0x8C, 0x84, 0xA4, 0x12, 0x6E, 0x2D, 0xC6,
+			    0xE5, 0x6D, 0xCC, 0x74, 0x58, 0x37, 0x7A, 0xAC,
+			    0x83, 0x8D, 0x00, 0x03, 0x22, 0x30, 0xF5, 0x3C,
+			    0xE1, 0xF5, 0x70, 0x0C, 0x0F, 0xFB, 0x4D, 0x3B,
+			    0x84, 0x21, 0x55, 0x76, 0x59, 0xEF, 0x55, 0xC1,
+			    0x06, 0xB4, 0xB5, 0x2A, 0xC5, 0xA4, 0xAA, 0xA6,
+			    0x92, 0xED, 0x92, 0x00, 0x52, 0x83, 0x8F, 0x33,
 			    0x62, 0xE8, 0x6D, 0xBD, 0x37, 0xA8, 0x90, 0x3E },
 	}, {
 		.plaintext = "abcdefghijklmnopqrstuvwxyz",
@@ -394,7 +400,7 @@ static struct hash_testvec wp512_tv_temp
 	}, {
 		.plaintext = "abcdbcdecdefdefgefghfghighijhijk",
 		.psize	= 32,
-		.digest	= { 0x2A, 0x98, 0x7E, 0xA4, 0x0F, 0x91, 0x70, 0x61, 
+		.digest	= { 0x2A, 0x98, 0x7E, 0xA4, 0x0F, 0x91, 0x70, 0x61,
 			    0xF5, 0xD6, 0xF0, 0xA0, 0xE4, 0x64, 0x4F, 0x48,
 			    0x8A, 0x7A, 0x5A, 0x52, 0xDE, 0xEE, 0x65, 0x62,
 			    0x07, 0xC5, 0x62, 0xF9, 0x88, 0xE9, 0x5C, 0x69,
@@ -408,7 +414,7 @@ static struct hash_testvec wp512_tv_temp
 #define WP384_TEST_VECTORS	8
 
 static struct hash_testvec wp384_tv_template[] = {
-	{ 
+	{
 		.plaintext = "",
 		.psize	= 0,
 		.digest	= { 0x19, 0xFA, 0x61, 0xD7, 0x55, 0x22, 0xA4, 0x66,
@@ -440,11 +446,11 @@ static struct hash_testvec wp384_tv_temp
 	}, {
 		.plaintext = "message digest",
 		.psize	= 14,
-		.digest	= { 0x37, 0x8C, 0x84, 0xA4, 0x12, 0x6E, 0x2D, 0xC6, 
-			    0xE5, 0x6D, 0xCC, 0x74, 0x58, 0x37, 0x7A, 0xAC, 
-			    0x83, 0x8D, 0x00, 0x03, 0x22, 0x30, 0xF5, 0x3C, 
-			    0xE1, 0xF5, 0x70, 0x0C, 0x0F, 0xFB, 0x4D, 0x3B, 
-			    0x84, 0x21, 0x55, 0x76, 0x59, 0xEF, 0x55, 0xC1, 
+		.digest	= { 0x37, 0x8C, 0x84, 0xA4, 0x12, 0x6E, 0x2D, 0xC6,
+			    0xE5, 0x6D, 0xCC, 0x74, 0x58, 0x37, 0x7A, 0xAC,
+			    0x83, 0x8D, 0x00, 0x03, 0x22, 0x30, 0xF5, 0x3C,
+			    0xE1, 0xF5, 0x70, 0x0C, 0x0F, 0xFB, 0x4D, 0x3B,
+			    0x84, 0x21, 0x55, 0x76, 0x59, 0xEF, 0x55, 0xC1,
 			    0x06, 0xB4, 0xB5, 0x2A, 0xC5, 0xA4, 0xAA, 0xA6 },
 	}, {
 		.plaintext = "abcdefghijklmnopqrstuvwxyz",
@@ -478,7 +484,7 @@ static struct hash_testvec wp384_tv_temp
 	}, {
 		.plaintext = "abcdbcdecdefdefgefghfghighijhijk",
 		.psize	= 32,
-		.digest	= { 0x2A, 0x98, 0x7E, 0xA4, 0x0F, 0x91, 0x70, 0x61, 
+		.digest	= { 0x2A, 0x98, 0x7E, 0xA4, 0x0F, 0x91, 0x70, 0x61,
 			    0xF5, 0xD6, 0xF0, 0xA0, 0xE4, 0x64, 0x4F, 0x48,
 			    0x8A, 0x7A, 0x5A, 0x52, 0xDE, 0xEE, 0x65, 0x62,
 			    0x07, 0xC5, 0x62, 0xF9, 0x88, 0xE9, 0x5C, 0x69,
@@ -490,7 +496,7 @@ static struct hash_testvec wp384_tv_temp
 #define WP256_TEST_VECTORS	8
 
 static struct hash_testvec wp256_tv_template[] = {
-	{ 
+	{
 		.plaintext = "",
 		.psize	= 0,
 		.digest	= { 0x19, 0xFA, 0x61, 0xD7, 0x55, 0x22, 0xA4, 0x66,
@@ -516,9 +522,9 @@ static struct hash_testvec wp256_tv_temp
 	}, {
 		.plaintext = "message digest",
 		.psize	= 14,
-		.digest	= { 0x37, 0x8C, 0x84, 0xA4, 0x12, 0x6E, 0x2D, 0xC6, 
-			    0xE5, 0x6D, 0xCC, 0x74, 0x58, 0x37, 0x7A, 0xAC, 
-			    0x83, 0x8D, 0x00, 0x03, 0x22, 0x30, 0xF5, 0x3C, 
+		.digest	= { 0x37, 0x8C, 0x84, 0xA4, 0x12, 0x6E, 0x2D, 0xC6,
+			    0xE5, 0x6D, 0xCC, 0x74, 0x58, 0x37, 0x7A, 0xAC,
+			    0x83, 0x8D, 0x00, 0x03, 0x22, 0x30, 0xF5, 0x3C,
 			    0xE1, 0xF5, 0x70, 0x0C, 0x0F, 0xFB, 0x4D, 0x3B },
 	}, {
 		.plaintext = "abcdefghijklmnopqrstuvwxyz",
@@ -546,7 +552,7 @@ static struct hash_testvec wp256_tv_temp
 	}, {
 		.plaintext = "abcdbcdecdefdefgefghfghighijhijk",
 		.psize	= 32,
-		.digest	= { 0x2A, 0x98, 0x7E, 0xA4, 0x0F, 0x91, 0x70, 0x61, 
+		.digest	= { 0x2A, 0x98, 0x7E, 0xA4, 0x0F, 0x91, 0x70, 0x61,
 			    0xF5, 0xD6, 0xF0, 0xA0, 0xE4, 0x64, 0x4F, 0x48,
 			    0x8A, 0x7A, 0x5A, 0x52, 0xDE, 0xEE, 0x65, 0x62,
 			    0x07, 0xC5, 0x62, 0xF9, 0x88, 0xE9, 0x5C, 0x69 },
@@ -554,7 +560,7 @@ static struct hash_testvec wp256_tv_temp
 };
 
 /*
- * TIGER test vectors from Tiger website 
+ * TIGER test vectors from Tiger website
  */
 #define TGR192_TEST_VECTORS	6
 
@@ -693,7 +699,7 @@ static struct hash_testvec tgr128_tv_tem
 #define HMAC_MD5_TEST_VECTORS	7
 
 static struct hmac_testvec hmac_md5_tv_template[] =
-{	
+{
 	{
 		.key	= { [0 ... 15] =  0x0b },
 		.ksize	= 16,
@@ -756,7 +762,7 @@ static struct hmac_testvec hmac_md5_tv_t
  */
 #define HMAC_SHA1_TEST_VECTORS	7
 
-static struct hmac_testvec hmac_sha1_tv_template[] = {	
+static struct hmac_testvec hmac_sha1_tv_template[] = {
 	{
 		.key	= { [0 ... 19] = 0x0b },
 		.ksize	= 20,
@@ -766,11 +772,11 @@ static struct hmac_testvec hmac_sha1_tv_
 			    0xe2, 0x8b, 0xc0, 0xb6, 0xfb, 0x37, 0x8c, 0x8e, 0xf1,
 			    0x46, 0xbe },
 	}, {
-		.key	= { 'J', 'e', 'f', 'e' },		
+		.key	= { 'J', 'e', 'f', 'e' },
 		.ksize	= 4,
 		.plaintext = "what do ya want for nothing?",
 		.psize	= 28,
-		.digest	= { 0xef, 0xfc, 0xdf, 0x6a, 0xe5, 0xeb, 0x2f, 0xa2, 0xd2, 0x74, 
+		.digest	= { 0xef, 0xfc, 0xdf, 0x6a, 0xe5, 0xeb, 0x2f, 0xa2, 0xd2, 0x74,
 			    0x16, 0xd5, 0xf1, 0x84, 0xdf, 0x9c, 0x25, 0x9a, 0x7c, 0x79 },
 		.np	= 2,
 		.tap	= { 14, 14 }
@@ -779,30 +785,30 @@ static struct hmac_testvec hmac_sha1_tv_
 		.ksize	= 20,
 		.plaintext = { [0 ... 49] = 0xdd },
 		.psize	= 50,
-		.digest	= { 0x12, 0x5d, 0x73, 0x42, 0xb9, 0xac, 0x11, 0xcd, 0x91, 0xa3, 
+		.digest	= { 0x12, 0x5d, 0x73, 0x42, 0xb9, 0xac, 0x11, 0xcd, 0x91, 0xa3,
 			    0x9a, 0xf4, 0x8a, 0xa1, 0x7b, 0x4f, 0x63, 0xf1, 0x75, 0xd3 },
 	}, {
 		.key	= { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
-			    0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 
+			    0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
 			    0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19 },
 		.ksize	= 25,
 		.plaintext = { [0 ... 49] = 0xcd },
 		.psize	= 50,
-		.digest	= { 0x4c, 0x90, 0x07, 0xf4, 0x02, 0x62, 0x50, 0xc6, 0xbc, 0x84, 
+		.digest	= { 0x4c, 0x90, 0x07, 0xf4, 0x02, 0x62, 0x50, 0xc6, 0xbc, 0x84,
 			    0x14, 0xf9, 0xbf, 0x50, 0xc8, 0x6c, 0x2d, 0x72, 0x35, 0xda },
 	}, {
 		.key	= { [0 ... 19] = 0x0c },
 		.ksize	= 20,
 		.plaintext = "Test With Truncation",
 		.psize	= 20,
-		.digest	= { 0x4c, 0x1a, 0x03, 0x42, 0x4b, 0x55, 0xe0, 0x7f, 0xe7, 0xf2, 
+		.digest	= { 0x4c, 0x1a, 0x03, 0x42, 0x4b, 0x55, 0xe0, 0x7f, 0xe7, 0xf2,
 			    0x7b, 0xe1, 0xd5, 0x8b, 0xb9, 0x32, 0x4a, 0x9a, 0x5a, 0x04 },
 	}, {
 		.key	= { [0 ... 79] = 0xaa },
 		.ksize	= 80,
 		.plaintext = "Test Using Larger Than Block-Size Key - Hash Key First",
 		.psize	= 54,
-		.digest	= { 0xaa, 0x4a, 0xe5, 0xe1, 0x52, 0x72, 0xd0, 0x0e, 0x95, 0x70, 
+		.digest	= { 0xaa, 0x4a, 0xe5, 0xe1, 0x52, 0x72, 0xd0, 0x0e, 0x95, 0x70,
 			    0x56, 0x37, 0xce, 0x8a, 0x3b, 0x55, 0xed, 0x40, 0x21, 0x12 },
 	}, {
 		.key	= { [0 ... 79] = 0xaa },
@@ -810,7 +816,7 @@ static struct hmac_testvec hmac_sha1_tv_
 		.plaintext = "Test Using Larger Than Block-Size Key and Larger Than One "
 			     "Block-Size Data",
 		.psize	= 73,
-		.digest	= { 0xe8, 0xe9, 0x9d, 0x0f, 0x45, 0x23, 0x7d, 0x78, 0x6d, 0x6b, 
+		.digest	= { 0xe8, 0xe9, 0x9d, 0x0f, 0x45, 0x23, 0x7d, 0x78, 0x6d, 0x6b,
 			    0xba, 0xa7, 0x96, 0x5c, 0x78, 0x08, 0xbb, 0xff, 0x1a, 0x91 },
 	},
 };
@@ -1011,7 +1017,7 @@ static struct cipher_testvec des_enc_tv_
 			    0xf7, 0x9c, 0x89, 0x2a, 0x33, 0x8f, 0x4a, 0x8b },
 		.rlen	= 32,
 		.np	= 3,
-		.tap	= { 14, 10, 8 } 
+		.tap	= { 14, 10, 8 }
 	}, {
 		.key	= { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
 		.klen	= 8,
@@ -1024,7 +1030,7 @@ static struct cipher_testvec des_enc_tv_
 			    0xb4, 0x99, 0x26, 0xf7, 0x1f, 0xe1, 0xd4, 0x90 },
 		.rlen	= 24,
 		.np	= 4,
-		.tap	= { 2, 1, 3, 18 } 
+		.tap	= { 2, 1, 3, 18 }
 	}, {
 		.key	= { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
 		.klen	= 8,
@@ -1035,7 +1041,7 @@ static struct cipher_testvec des_enc_tv_
 			    0xf7, 0x9c, 0x89, 0x2a, 0x33, 0x8f, 0x4a, 0x8b },
 		.rlen	= 16,
 		.np	= 5,
-		.tap	= { 2, 2, 2, 2, 8 } 
+		.tap	= { 2, 2, 2, 2, 8 }
 	}, {
 		.key	= { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
 		.klen	= 8,
@@ -1044,7 +1050,7 @@ static struct cipher_testvec des_enc_tv_
 		.result	= { 0xc9, 0x57, 0x44, 0x25, 0x6a, 0x5e, 0xd3, 0x1d },
 		.rlen	= 8,
 		.np	= 8,
-		.tap	= { 1, 1, 1, 1, 1, 1, 1, 1 } 
+		.tap	= { 1, 1, 1, 1, 1, 1, 1, 1 }
 	},
 };
 
@@ -1057,7 +1063,7 @@ static struct cipher_testvec des_dec_tv_
 		.result	= { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xe7 },
 		.rlen	= 8,
 	}, { /* Sbox test from NBS */
-		.key	= { 0x7c, 0xa1, 0x10, 0x45, 0x4a, 0x1a, 0x6e, 0x57 },		
+		.key	= { 0x7c, 0xa1, 0x10, 0x45, 0x4a, 0x1a, 0x6e, 0x57 },
 		.klen	= 8,
 		.input	= { 0x69, 0x0f, 0x5b, 0x0d, 0x9a, 0x26, 0x93, 0x9b },
 		.ilen	= 8,
@@ -1092,19 +1098,19 @@ static struct cipher_testvec des_cbc_enc
 	{ /* From OpenSSL */
 		.key	= { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef},
 		.klen	= 8,
-		.iv	= { 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10},		
-		.input	= { 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x20, 
-			    0x4e, 0x6f, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74, 
-			    0x68, 0x65, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20 }, 
+		.iv	= { 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10},
+		.input	= { 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x20,
+			    0x4e, 0x6f, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74,
+			    0x68, 0x65, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20 },
 		.ilen	= 24,
-		.result	= { 0xcc, 0xd1, 0x73, 0xff, 0xab, 0x20, 0x39, 0xf4, 
-			    0xac, 0xd8, 0xae, 0xfd, 0xdf, 0xd8, 0xa1, 0xeb, 
-			    0x46, 0x8e, 0x91, 0x15, 0x78, 0x88, 0xba, 0x68 }, 
+		.result	= { 0xcc, 0xd1, 0x73, 0xff, 0xab, 0x20, 0x39, 0xf4,
+			    0xac, 0xd8, 0xae, 0xfd, 0xdf, 0xd8, 0xa1, 0xeb,
+			    0x46, 0x8e, 0x91, 0x15, 0x78, 0x88, 0xba, 0x68 },
 		.rlen	= 24,
 	}, { /* FIPS Pub 81 */
 		.key	= { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
 		.klen	= 8,
-		.iv	= { 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef },		
+		.iv	= { 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef },
 		.input	= { 0x4e, 0x6f, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74 },
 		.ilen	= 8,
 		.result	= { 0xe5, 0xc7, 0xcd, 0xde, 0x87, 0x2b, 0xf2, 0x7c },
@@ -1117,7 +1123,7 @@ static struct cipher_testvec des_cbc_enc
 		.ilen	= 8,
 		.result	= { 0x43, 0xe9, 0x34, 0x00, 0x8c, 0x38, 0x9c, 0x0f },
 		.rlen	= 8,
-	}, {	
+	}, {
 		.key	= { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
 		.klen	= 8,
 		.iv	= { 0x43, 0xe9, 0x34, 0x00, 0x8c, 0x38, 0x9c, 0x0f },
@@ -1125,18 +1131,18 @@ static struct cipher_testvec des_cbc_enc
 		.ilen	= 8,
 		.result	= { 0x68, 0x37, 0x88, 0x49, 0x9a, 0x7c, 0x05, 0xf6 },
 		.rlen	= 8,
-	}, { /* Copy of openssl vector for chunk testing */	
+	}, { /* Copy of openssl vector for chunk testing */
 	     /* From OpenSSL */
 		.key	= { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef},
 		.klen	= 8,
-		.iv	= { 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10},		
-		.input	= { 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x20, 
-			    0x4e, 0x6f, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74, 
-			    0x68, 0x65, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20 }, 
+		.iv	= { 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10},
+		.input	= { 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x20,
+			    0x4e, 0x6f, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74,
+			    0x68, 0x65, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20 },
 		.ilen	= 24,
-		.result	= { 0xcc, 0xd1, 0x73, 0xff, 0xab, 0x20, 0x39, 0xf4, 
-			    0xac, 0xd8, 0xae, 0xfd, 0xdf, 0xd8, 0xa1, 0xeb, 
-			    0x46, 0x8e, 0x91, 0x15, 0x78, 0x88, 0xba, 0x68 }, 
+		.result	= { 0xcc, 0xd1, 0x73, 0xff, 0xab, 0x20, 0x39, 0xf4,
+			    0xac, 0xd8, 0xae, 0xfd, 0xdf, 0xd8, 0xa1, 0xeb,
+			    0x46, 0x8e, 0x91, 0x15, 0x78, 0x88, 0xba, 0x68 },
 		.rlen	= 24,
 		.np	= 2,
 		.tap	= { 13, 11 }
@@ -1155,24 +1161,24 @@ static struct cipher_testvec des_cbc_dec
 	}, {
 		.key	= { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
 		.klen	= 8,
-		.iv	= { 0xe5, 0xc7, 0xcd, 0xde, 0x87, 0x2b, 0xf2, 0x7c },		
+		.iv	= { 0xe5, 0xc7, 0xcd, 0xde, 0x87, 0x2b, 0xf2, 0x7c },
 		.input	= { 0x43, 0xe9, 0x34, 0x00, 0x8c, 0x38, 0x9c, 0x0f },
 		.ilen	= 8,
-		.result	= { 0x68, 0x65, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20 }, 
+		.result	= { 0x68, 0x65, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20 },
 		.rlen	= 8,
 	}, {
 		.key	= { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
 		.klen	= 8,
 		.iv	= { 0x43, 0xe9, 0x34, 0x00, 0x8c, 0x38, 0x9c, 0x0f },
-		.input	= { 0x68, 0x37, 0x88, 0x49, 0x9a, 0x7c, 0x05, 0xf6 }, 
+		.input	= { 0x68, 0x37, 0x88, 0x49, 0x9a, 0x7c, 0x05, 0xf6 },
 		.ilen	= 8,
 		.result	= { 0x66, 0x6f, 0x72, 0x20, 0x61, 0x6c, 0x6c, 0x20 },
 		.rlen	= 8,
-	}, { /* Copy of above, for chunk testing */	
+	}, { /* Copy of above, for chunk testing */
 		.key	= { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
 		.klen	= 8,
 		.iv	= { 0x43, 0xe9, 0x34, 0x00, 0x8c, 0x38, 0x9c, 0x0f },
-		.input	= { 0x68, 0x37, 0x88, 0x49, 0x9a, 0x7c, 0x05, 0xf6 }, 
+		.input	= { 0x68, 0x37, 0x88, 0x49, 0x9a, 0x7c, 0x05, 0xf6 },
 		.ilen	= 8,
 		.result	= { 0x66, 0x6f, 0x72, 0x20, 0x61, 0x6c, 0x6c, 0x20 },
 		.rlen	= 8,
@@ -1276,7 +1282,7 @@ static struct cipher_testvec bf_enc_tv_t
 		.ilen	= 8,
 		.result	= { 0xe8, 0x7a, 0x24, 0x4e, 0x2c, 0xc8, 0x5e, 0x82 },
 		.rlen	= 8,
-	}, { /* Vary the keylength... */	
+	}, { /* Vary the keylength... */
 		.key	= { 0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87,
 			    0x78, 0x69, 0x5a, 0x4b, 0x3c, 0x2d, 0x1e, 0x0f },
 		.klen	= 16,
@@ -1297,9 +1303,9 @@ static struct cipher_testvec bf_enc_tv_t
 		.key	= { 0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87,
 			    0x78, 0x69, 0x5a, 0x4b, 0x3c, 0x2d, 0x1e, 0x0f,
 			    0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
-			    0x04, 0x68, 0x91, 0x04, 0xc2, 0xfd, 0x3b, 0x2f, 
-			    0x58, 0x40, 0x23, 0x64, 0x1a, 0xba, 0x61, 0x76, 
-			    0x1f, 0x1f, 0x1f, 0x1f, 0x0e, 0x0e, 0x0e, 0x0e, 
+			    0x04, 0x68, 0x91, 0x04, 0xc2, 0xfd, 0x3b, 0x2f,
+			    0x58, 0x40, 0x23, 0x64, 0x1a, 0xba, 0x61, 0x76,
+			    0x1f, 0x1f, 0x1f, 0x1f, 0x0e, 0x0e, 0x0e, 0x0e,
 			    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
 		.klen	= 56,
 		.input	= { 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 },
@@ -1331,7 +1337,7 @@ static struct cipher_testvec bf_dec_tv_t
 		.ilen	= 8,
 		.result	= { 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 },
 		.rlen	= 8,
-	}, { /* Vary the keylength... */	
+	}, { /* Vary the keylength... */
 		.key	= { 0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87,
 			    0x78, 0x69, 0x5a, 0x4b, 0x3c, 0x2d, 0x1e, 0x0f },
 		.klen	= 16,
@@ -1352,9 +1358,9 @@ static struct cipher_testvec bf_dec_tv_t
 		.key	= { 0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87,
 			    0x78, 0x69, 0x5a, 0x4b, 0x3c, 0x2d, 0x1e, 0x0f,
 			    0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
-			    0x04, 0x68, 0x91, 0x04, 0xc2, 0xfd, 0x3b, 0x2f, 
-			    0x58, 0x40, 0x23, 0x64, 0x1a, 0xba, 0x61, 0x76, 
-			    0x1f, 0x1f, 0x1f, 0x1f, 0x0e, 0x0e, 0x0e, 0x0e, 
+			    0x04, 0x68, 0x91, 0x04, 0xc2, 0xfd, 0x3b, 0x2f,
+			    0x58, 0x40, 0x23, 0x64, 0x1a, 0xba, 0x61, 0x76,
+			    0x1f, 0x1f, 0x1f, 0x1f, 0x0e, 0x0e, 0x0e, 0x0e,
 			    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
 		.klen	= 56,
 		.input	= { 0xc0, 0x45, 0x04, 0x01, 0x2e, 0x4e, 0x1f, 0x53 },
@@ -1369,7 +1375,7 @@ static struct cipher_testvec bf_cbc_enc_
 		.key	= { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
 			    0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87 },
 		.klen	= 16,
-		.iv	= { 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 },		
+		.iv	= { 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 },
 		.input	= { 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x20,
 			    0x4e, 0x6f, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74,
 			    0x68, 0x65, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20,
@@ -1388,7 +1394,7 @@ static struct cipher_testvec bf_cbc_dec_
 		.key	= { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
 			    0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87 },
 		.klen	= 16,
-		.iv	= { 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 },		
+		.iv	= { 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 },
 		.input	= { 0x6b, 0x77, 0xb4, 0xd6, 0x30, 0x06, 0xde, 0xe6,
 			    0x05, 0xb1, 0x56, 0xe2, 0x74, 0x03, 0x97, 0x93,
 			    0x58, 0xde, 0xb9, 0xe7, 0x15, 0x46, 0x16, 0xd9,
@@ -1490,7 +1496,7 @@ static struct cipher_testvec tf_cbc_enc_
 		.key	= { [0 ... 15] = 0x00 },
 		.klen	= 16,
 		.iv	= { 0x9f, 0x58, 0x9f, 0x5c, 0xf6, 0x12, 0x2c, 0x32,
-			    0xb6, 0xbf, 0xec, 0x2f, 0x2a, 0xe8, 0xc3, 0x5a },		
+			    0xb6, 0xbf, 0xec, 0x2f, 0x2a, 0xe8, 0xc3, 0x5a },
 		.input	= { [0 ... 15] = 0x00 },
 		.ilen	= 16,
 		.result	= { 0xd4, 0x91, 0xdb, 0x16, 0xe7, 0xb1, 0xc3, 0x9e,
@@ -1528,7 +1534,7 @@ static struct cipher_testvec tf_cbc_dec_
 		.klen	= 16,
 		.iv	= { [0 ... 15] = 0x00 },
 		.input	= { 0x9f, 0x58, 0x9f, 0x5c, 0xf6, 0x12, 0x2c, 0x32,
-			    0xb6, 0xbf, 0xec, 0x2f, 0x2a, 0xe8, 0xc3, 0x5a },		  
+			    0xb6, 0xbf, 0xec, 0x2f, 0x2a, 0xe8, 0xc3, 0x5a },
 		.ilen	= 16,
 		.result	= { [0 ... 15] = 0x00 },
 		.rlen	= 16,
@@ -1578,8 +1584,7 @@ static struct cipher_testvec tf_cbc_dec_
 #define TNEPRES_ENC_TEST_VECTORS	4
 #define TNEPRES_DEC_TEST_VECTORS	4
 
-static struct cipher_testvec serpent_enc_tv_template[] = 
-{
+static struct cipher_testvec serpent_enc_tv_template[] = {
 	{
 		.input	= { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
 			    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
@@ -1620,8 +1625,7 @@ static struct cipher_testvec serpent_enc
 	},
 };
 
-static struct cipher_testvec tnepres_enc_tv_template[] = 
-{
+static struct cipher_testvec tnepres_enc_tv_template[] = {
 	{ /* KeySize=128, PT=0, I=1 */
 		.input	= { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 			    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
@@ -1629,7 +1633,7 @@ static struct cipher_testvec tnepres_enc
 			    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
 		.klen   = 16,
 		.ilen	= 16,
-		.result	= { 0x49, 0xaf, 0xbf, 0xad, 0x9d, 0x5a, 0x34, 0x05, 
+		.result	= { 0x49, 0xaf, 0xbf, 0xad, 0x9d, 0x5a, 0x34, 0x05,
 			    0x2c, 0xd8, 0xff, 0xa5, 0x98, 0x6b, 0xd2, 0xdd },
 		.rlen	= 16,
 	}, { /* KeySize=192, PT=0, I=1 */
@@ -1640,7 +1644,7 @@ static struct cipher_testvec tnepres_enc
 		.input	= { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 			    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
 		.ilen	= 16,
-		.result	= { 0xe7, 0x8e, 0x54, 0x02, 0xc7, 0x19, 0x55, 0x68, 
+		.result	= { 0xe7, 0x8e, 0x54, 0x02, 0xc7, 0x19, 0x55, 0x68,
 			    0xac, 0x36, 0x78, 0xf7, 0xa3, 0xf6, 0x0c, 0x66 },
 		.rlen	= 16,
 	}, { /* KeySize=256, PT=0, I=1 */
@@ -1652,7 +1656,7 @@ static struct cipher_testvec tnepres_enc
 		.input	= { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 			    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
 		.ilen	= 16,
-		.result	= { 0xab, 0xed, 0x96, 0xe7, 0x66, 0xbf, 0x28, 0xcb, 
+		.result	= { 0xab, 0xed, 0x96, 0xe7, 0x66, 0xbf, 0x28, 0xcb,
 			    0xc0, 0xeb, 0xd2, 0x1a, 0x82, 0xef, 0x08, 0x19 },
 		.rlen	= 16,
 	}, { /* KeySize=256, I=257 */
@@ -1664,15 +1668,14 @@ static struct cipher_testvec tnepres_enc
 		.input	= { 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08,
 			    0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00 },
 		.ilen	= 16,
-		.result	= { 0x5c, 0xe7, 0x1c, 0x70, 0xd2, 0x88, 0x2e, 0x5b, 
+		.result	= { 0x5c, 0xe7, 0x1c, 0x70, 0xd2, 0x88, 0x2e, 0x5b,
 			    0xb8, 0x32, 0xe4, 0x33, 0xf8, 0x9f, 0x26, 0xde },
 		.rlen	= 16,
 	},
 };
 
 
-static struct cipher_testvec serpent_dec_tv_template[] = 
-{
+static struct cipher_testvec serpent_dec_tv_template[] = {
 	{
 		.input	= { 0x12, 0x07, 0xfc, 0xce, 0x9b, 0xd0, 0xd6, 0x47,
 			    0x6a, 0xe9, 0x8f, 0xbe, 0xd1, 0x43, 0xa0, 0xe2 },
@@ -1713,8 +1716,7 @@ static struct cipher_testvec serpent_dec
 	},
 };
 
-static struct cipher_testvec tnepres_dec_tv_template[] =
-{
+static struct cipher_testvec tnepres_dec_tv_template[] = {
 	{
 		.input	= { 0x41, 0xcc, 0x6b, 0x31, 0x59, 0x31, 0x45, 0x97,
 			    0x6d, 0x6f, 0xbb, 0x38, 0x4b, 0x37, 0x21, 0x28 },
@@ -1726,7 +1728,7 @@ static struct cipher_testvec tnepres_dec
 		.key	= { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
 			    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
 		.klen	= 16,
-		.input	= { 0xea, 0xf4, 0xd7, 0xfc, 0xd8, 0x01, 0x34, 0x47, 
+		.input	= { 0xea, 0xf4, 0xd7, 0xfc, 0xd8, 0x01, 0x34, 0x47,
 			    0x81, 0x45, 0x0b, 0xfa, 0x0c, 0xd6, 0xad, 0x6e },
 		.ilen	= 16,
 		.result	= { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
@@ -1738,7 +1740,7 @@ static struct cipher_testvec tnepres_dec
 			    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
 			    0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f },
 		.klen	= 32,
-		.input	= { 0x64, 0xa9, 0x1a, 0x37, 0xed, 0x9f, 0xe7, 0x49, 
+		.input	= { 0x64, 0xa9, 0x1a, 0x37, 0xed, 0x9f, 0xe7, 0x49,
 			    0xa8, 0x4e, 0x76, 0xd6, 0xf5, 0x0d, 0x78, 0xee },
 		.ilen	= 16,
 		.result	= { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
@@ -1747,7 +1749,7 @@ static struct cipher_testvec tnepres_dec
 	}, { /* KeySize=128, I=121 */
 		.key	= { [15] = 0x80 },
 		.klen	= 16,
-		.input	= { 0x3d, 0xda, 0xbf, 0xc0, 0x06, 0xda, 0xab, 0x06, 
+		.input	= { 0x3d, 0xda, 0xbf, 0xc0, 0x06, 0xda, 0xab, 0x06,
 			    0x46, 0x2a, 0xf4, 0xef, 0x81, 0x54, 0x4e, 0x26 },
 		.ilen	= 16,
 		.result	= { [0 ... 15] = 0x00 },
@@ -1760,58 +1762,56 @@ static struct cipher_testvec tnepres_dec
 #define CAST6_ENC_TEST_VECTORS	3
 #define CAST6_DEC_TEST_VECTORS  3
 
-static struct cipher_testvec cast6_enc_tv_template[] = 
-{
+static struct cipher_testvec cast6_enc_tv_template[] = {
 	{
-		.key	= { 0x23, 0x42, 0xbb, 0x9e, 0xfa, 0x38, 0x54, 0x2c, 
+		.key	= { 0x23, 0x42, 0xbb, 0x9e, 0xfa, 0x38, 0x54, 0x2c,
 			    0x0a, 0xf7, 0x56, 0x47, 0xf2, 0x9f, 0x61, 0x5d },
 		.klen	= 16,
 		.input	= { [0 ... 15] = 0x00 },
 		.ilen	= 16,
-		.result	= { 0xc8, 0x42, 0xa0, 0x89, 0x72, 0xb4, 0x3d, 0x20, 
+		.result	= { 0xc8, 0x42, 0xa0, 0x89, 0x72, 0xb4, 0x3d, 0x20,
 			    0x83, 0x6c, 0x91, 0xd1, 0xb7, 0x53, 0x0f, 0x6b },
 		.rlen	= 16,
 	}, {
-		.key	= { 0x23, 0x42, 0xbb, 0x9e, 0xfa, 0x38, 0x54, 0x2c, 
-			    0xbe, 0xd0, 0xac, 0x83, 0x94, 0x0a, 0xc2, 0x98, 
+		.key	= { 0x23, 0x42, 0xbb, 0x9e, 0xfa, 0x38, 0x54, 0x2c,
+			    0xbe, 0xd0, 0xac, 0x83, 0x94, 0x0a, 0xc2, 0x98,
 			    0xba, 0xc7, 0x7a, 0x77, 0x17, 0x94, 0x28, 0x63 },
 		.klen	= 24,
 		.input	= { [0 ... 15] = 0x00 },
 		.ilen	= 16,
-		.result	= { 0x1b, 0x38, 0x6c, 0x02, 0x10, 0xdc, 0xad, 0xcb, 
+		.result	= { 0x1b, 0x38, 0x6c, 0x02, 0x10, 0xdc, 0xad, 0xcb,
 			    0xdd, 0x0e, 0x41, 0xaa, 0x08, 0xa7, 0xa7, 0xe8 },
 		.rlen	= 16,
 	}, {
 		.key	= { 0x23, 0x42, 0xbb, 0x9e, 0xfa, 0x38, 0x54, 0x2c,
 			    0xbe, 0xd0, 0xac, 0x83, 0x94, 0x0a, 0xc2, 0x98,
 			    0x8d, 0x7c, 0x47, 0xce, 0x26, 0x49, 0x08, 0x46,
-			    0x1c, 0xc1, 0xb5, 0x13, 0x7a, 0xe6, 0xb6, 0x04 },				  
+			    0x1c, 0xc1, 0xb5, 0x13, 0x7a, 0xe6, 0xb6, 0x04 },
 		.klen	= 32,
 		.input	= { [0 ... 15] = 0x00 },
 		.ilen	= 16,
-		.result	= { 0x4f, 0x6a, 0x20, 0x38, 0x28, 0x68, 0x97, 0xb9, 
+		.result	= { 0x4f, 0x6a, 0x20, 0x38, 0x28, 0x68, 0x97, 0xb9,
 			    0xc9, 0x87, 0x01, 0x36, 0x55, 0x33, 0x17, 0xfa },
 		.rlen	= 16,
 	},
 };
 
-static struct cipher_testvec cast6_dec_tv_template[] = 
-{
+static struct cipher_testvec cast6_dec_tv_template[] = {
 	{
-		.key	= { 0x23, 0x42, 0xbb, 0x9e, 0xfa, 0x38, 0x54, 0x2c, 
+		.key	= { 0x23, 0x42, 0xbb, 0x9e, 0xfa, 0x38, 0x54, 0x2c,
 			    0x0a, 0xf7, 0x56, 0x47, 0xf2, 0x9f, 0x61, 0x5d },
 		.klen	= 16,
-		.input	= { 0xc8, 0x42, 0xa0, 0x89, 0x72, 0xb4, 0x3d, 0x20, 
+		.input	= { 0xc8, 0x42, 0xa0, 0x89, 0x72, 0xb4, 0x3d, 0x20,
 			    0x83, 0x6c, 0x91, 0xd1, 0xb7, 0x53, 0x0f, 0x6b },
 		.ilen	= 16,
 		.result	= { [0 ... 15] = 0x00 },
 		.rlen	= 16,
 	}, {
-		.key	= { 0x23, 0x42, 0xbb, 0x9e, 0xfa, 0x38, 0x54, 0x2c, 
-			    0xbe, 0xd0, 0xac, 0x83, 0x94, 0x0a, 0xc2, 0x98, 
+		.key	= { 0x23, 0x42, 0xbb, 0x9e, 0xfa, 0x38, 0x54, 0x2c,
+			    0xbe, 0xd0, 0xac, 0x83, 0x94, 0x0a, 0xc2, 0x98,
 			    0xba, 0xc7, 0x7a, 0x77, 0x17, 0x94, 0x28, 0x63 },
 		.klen	= 24,
-		.input	= { 0x1b, 0x38, 0x6c, 0x02, 0x10, 0xdc, 0xad, 0xcb, 
+		.input	= { 0x1b, 0x38, 0x6c, 0x02, 0x10, 0xdc, 0xad, 0xcb,
 			    0xdd, 0x0e, 0x41, 0xaa, 0x08, 0xa7, 0xa7, 0xe8 },
 		.ilen	= 16,
 		.result	= { [0 ... 15] = 0x00 },
@@ -1820,9 +1820,9 @@ static struct cipher_testvec cast6_dec_t
 		.key	= { 0x23, 0x42, 0xbb, 0x9e, 0xfa, 0x38, 0x54, 0x2c,
 			    0xbe, 0xd0, 0xac, 0x83, 0x94, 0x0a, 0xc2, 0x98,
 			    0x8d, 0x7c, 0x47, 0xce, 0x26, 0x49, 0x08, 0x46,
-			    0x1c, 0xc1, 0xb5, 0x13, 0x7a, 0xe6, 0xb6, 0x04 },				  
+			    0x1c, 0xc1, 0xb5, 0x13, 0x7a, 0xe6, 0xb6, 0x04 },
 		.klen	= 32,
-		.input	= { 0x4f, 0x6a, 0x20, 0x38, 0x28, 0x68, 0x97, 0xb9, 
+		.input	= { 0x4f, 0x6a, 0x20, 0x38, 0x28, 0x68, 0x97, 0xb9,
 			    0xc9, 0x87, 0x01, 0x36, 0x55, 0x33, 0x17, 0xfa },
 		.ilen	= 16,
 		.result	= { [0 ... 15] = 0x00 },
@@ -1837,9 +1837,9 @@ static struct cipher_testvec cast6_dec_t
 #define AES_ENC_TEST_VECTORS 3
 #define AES_DEC_TEST_VECTORS 3
 
-static struct cipher_testvec aes_enc_tv_template[] = { 
+static struct cipher_testvec aes_enc_tv_template[] = {
 	{ /* From FIPS-197 */
-		.key	= { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 
+		.key	= { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
 			    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
 		.klen	= 16,
 		.input	= { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
@@ -1853,7 +1853,7 @@ static struct cipher_testvec aes_enc_tv_
 			    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
 			    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17 },
 		.klen	= 24,
-		.input	= { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 
+		.input	= { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
 			    0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
 		.ilen	= 16,
 		.result	= { 0xdd, 0xa9, 0x7c, 0xa4, 0x86, 0x4c, 0xdf, 0xe0,
@@ -1865,7 +1865,7 @@ static struct cipher_testvec aes_enc_tv_
 			    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
 			    0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f },
 		.klen	= 32,
-		.input	= { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 
+		.input	= { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
 			    0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
 		.ilen	= 16,
 		.result	= { 0x8e, 0xa2, 0xb7, 0xca, 0x51, 0x67, 0x45, 0xbf,
@@ -1874,9 +1874,9 @@ static struct cipher_testvec aes_enc_tv_
 	},
 };
 
-static struct cipher_testvec aes_dec_tv_template[] = { 
+static struct cipher_testvec aes_dec_tv_template[] = {
 	{ /* From FIPS-197 */
-		.key	= { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 
+		.key	= { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
 			    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
 		.klen	= 16,
 		.input	= { 0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x04, 0x30,
@@ -1893,8 +1893,8 @@ static struct cipher_testvec aes_dec_tv_
 		.input	= { 0xdd, 0xa9, 0x7c, 0xa4, 0x86, 0x4c, 0xdf, 0xe0,
 			    0x6e, 0xaf, 0x70, 0xa0, 0xec, 0x0d, 0x71, 0x91 },
 		.ilen	= 16,
-		.result	= { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 
-			    0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },  
+		.result	= { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+			    0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
 		.rlen	= 16,
 	}, {
 		.key	= { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
@@ -1905,7 +1905,7 @@ static struct cipher_testvec aes_dec_tv_
 		.input	= { 0x8e, 0xa2, 0xb7, 0xca, 0x51, 0x67, 0x45, 0xbf,
 			    0xea, 0xfc, 0x49, 0x90, 0x4b, 0x49, 0x60, 0x89 },
 		.ilen	= 16,
-		.result	= { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 
+		.result	= { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
 			    0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
 		.rlen	= 16,
 	},
@@ -1915,8 +1915,7 @@ static struct cipher_testvec aes_dec_tv_
 #define CAST5_ENC_TEST_VECTORS	3
 #define CAST5_DEC_TEST_VECTORS	3
 
-static struct cipher_testvec cast5_enc_tv_template[] =
-{
+static struct cipher_testvec cast5_enc_tv_template[] = {
 	{
 		.key	= { 0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78,
 			    0x23, 0x45, 0x67, 0x89, 0x34, 0x56, 0x78, 0x9a },
@@ -1943,8 +1942,7 @@ static struct cipher_testvec cast5_enc_t
 	},
 };
 
-static struct cipher_testvec cast5_dec_tv_template[] =
-{
+static struct cipher_testvec cast5_dec_tv_template[] = {
 	{
 		.key	= { 0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78,
 			    0x23, 0x45, 0x67, 0x89, 0x34, 0x56, 0x78, 0x9a },
@@ -1971,14 +1969,13 @@ static struct cipher_testvec cast5_dec_t
 	},
 };
 
-/* 
- * ARC4 test vectors from OpenSSL 
+/*
+ * ARC4 test vectors from OpenSSL
  */
 #define ARC4_ENC_TEST_VECTORS	7
 #define ARC4_DEC_TEST_VECTORS	7
 
-static struct cipher_testvec arc4_enc_tv_template[] =
-{
+static struct cipher_testvec arc4_enc_tv_template[] = {
 	{
 		.key	= { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
 		.klen	= 8,
@@ -2044,8 +2041,7 @@ static struct cipher_testvec arc4_enc_tv
 	},
 };
 
-static struct cipher_testvec arc4_dec_tv_template[] =
-{
+static struct cipher_testvec arc4_dec_tv_template[] = {
 	{
 		.key	= { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef },
 		.klen	= 8,
@@ -2111,14 +2107,13 @@ static struct cipher_testvec arc4_dec_tv
 	},
 };
 
-/* 
+/*
  * TEA test vectors
  */
 #define TEA_ENC_TEST_VECTORS	4
 #define TEA_DEC_TEST_VECTORS	4
 
-static struct cipher_testvec tea_enc_tv_template[] =
-{
+static struct cipher_testvec tea_enc_tv_template[] = {
 	{
 		.key    = { [0 ... 15] = 0x00 },
 		.klen	= 16,
@@ -2138,31 +2133,30 @@ static struct cipher_testvec tea_enc_tv_
 		.key	= { 0x09, 0x65, 0x43, 0x11, 0x66, 0x44, 0x39, 0x25,
 			    0x51, 0x3a, 0x16, 0x10, 0x0a, 0x08, 0x12, 0x6e },
 		.klen	= 16,
-		.input	= { 0x6c, 0x6f, 0x6e, 0x67, 0x65, 0x72, 0x5f, 0x74, 
+		.input	= { 0x6c, 0x6f, 0x6e, 0x67, 0x65, 0x72, 0x5f, 0x74,
 			    0x65, 0x73, 0x74, 0x5f, 0x76, 0x65, 0x63, 0x74 },
 		.ilen	= 16,
-		.result	= { 0xbe, 0x7a, 0xbb, 0x81, 0x95, 0x2d, 0x1f, 0x1e, 
+		.result	= { 0xbe, 0x7a, 0xbb, 0x81, 0x95, 0x2d, 0x1f, 0x1e,
 			    0xdd, 0x89, 0xa1, 0x25, 0x04, 0x21, 0xdf, 0x95 },
 		.rlen	= 16,
 	}, {
 		.key	= { 0x4d, 0x76, 0x32, 0x17, 0x05, 0x3f, 0x75, 0x2c,
 			    0x5d, 0x04, 0x16, 0x36, 0x15, 0x72, 0x63, 0x2f },
 		.klen	= 16,
-		.input	= { 0x54, 0x65, 0x61, 0x20, 0x69, 0x73, 0x20, 0x67, 
-			    0x6f, 0x6f, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x20, 
-			    0x79, 0x6f, 0x75, 0x21, 0x21, 0x21, 0x20, 0x72, 
+		.input	= { 0x54, 0x65, 0x61, 0x20, 0x69, 0x73, 0x20, 0x67,
+			    0x6f, 0x6f, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x20,
+			    0x79, 0x6f, 0x75, 0x21, 0x21, 0x21, 0x20, 0x72,
 			    0x65, 0x61, 0x6c, 0x6c, 0x79, 0x21, 0x21, 0x21 },
 		.ilen	= 32,
-		.result	= { 0xe0, 0x4d, 0x5d, 0x3c, 0xb7, 0x8c, 0x36, 0x47, 
-			    0x94, 0x18, 0x95, 0x91, 0xa9, 0xfc, 0x49, 0xf8, 
-			    0x44, 0xd1, 0x2d, 0xc2, 0x99, 0xb8, 0x08, 0x2a, 
+		.result	= { 0xe0, 0x4d, 0x5d, 0x3c, 0xb7, 0x8c, 0x36, 0x47,
+			    0x94, 0x18, 0x95, 0x91, 0xa9, 0xfc, 0x49, 0xf8,
+			    0x44, 0xd1, 0x2d, 0xc2, 0x99, 0xb8, 0x08, 0x2a,
 			    0x07, 0x89, 0x73, 0xc2, 0x45, 0x92, 0xc6, 0x90 },
 		.rlen	= 32,
 	}
 };
 
-static struct cipher_testvec tea_dec_tv_template[] =
-{
+static struct cipher_testvec tea_dec_tv_template[] = {
 	{
 		.key    = { [0 ... 15] = 0x00 },
 		.klen	= 16,
@@ -2183,9 +2177,9 @@ static struct cipher_testvec tea_dec_tv_
 			    0x51, 0x3a, 0x16, 0x10, 0x0a, 0x08, 0x12, 0x6e },
 		.klen	= 16,
 		.input	= { 0xbe, 0x7a, 0xbb, 0x81, 0x95, 0x2d, 0x1f, 0x1e,
-                            0xdd, 0x89, 0xa1, 0x25, 0x04, 0x21, 0xdf, 0x95 },
-                .ilen   = 16,
-		.result	= { 0x6c, 0x6f, 0x6e, 0x67, 0x65, 0x72, 0x5f, 0x74, 
+			    0xdd, 0x89, 0xa1, 0x25, 0x04, 0x21, 0xdf, 0x95 },
+		.ilen   = 16,
+		.result	= { 0x6c, 0x6f, 0x6e, 0x67, 0x65, 0x72, 0x5f, 0x74,
 			    0x65, 0x73, 0x74, 0x5f, 0x76, 0x65, 0x63, 0x74 },
 		.rlen	= 16,
 	}, {
@@ -2193,26 +2187,25 @@ static struct cipher_testvec tea_dec_tv_
 			    0x5d, 0x04, 0x16, 0x36, 0x15, 0x72, 0x63, 0x2f },
 		.klen	= 16,
 		.input	= { 0xe0, 0x4d, 0x5d, 0x3c, 0xb7, 0x8c, 0x36, 0x47,
-                            0x94, 0x18, 0x95, 0x91, 0xa9, 0xfc, 0x49, 0xf8,
-                            0x44, 0xd1, 0x2d, 0xc2, 0x99, 0xb8, 0x08, 0x2a,
-                            0x07, 0x89, 0x73, 0xc2, 0x45, 0x92, 0xc6, 0x90 },
+			    0x94, 0x18, 0x95, 0x91, 0xa9, 0xfc, 0x49, 0xf8,
+			    0x44, 0xd1, 0x2d, 0xc2, 0x99, 0xb8, 0x08, 0x2a,
+			    0x07, 0x89, 0x73, 0xc2, 0x45, 0x92, 0xc6, 0x90 },
 		.ilen	= 32,
-		.result	= { 0x54, 0x65, 0x61, 0x20, 0x69, 0x73, 0x20, 0x67, 
-			    0x6f, 0x6f, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x20, 
-			    0x79, 0x6f, 0x75, 0x21, 0x21, 0x21, 0x20, 0x72, 
+		.result	= { 0x54, 0x65, 0x61, 0x20, 0x69, 0x73, 0x20, 0x67,
+			    0x6f, 0x6f, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x20,
+			    0x79, 0x6f, 0x75, 0x21, 0x21, 0x21, 0x20, 0x72,
 			    0x65, 0x61, 0x6c, 0x6c, 0x79, 0x21, 0x21, 0x21 },
 		.rlen	= 32,
 	}
 };
 
-/* 
- * XTEA test vectors 
+/*
+ * XTEA test vectors
  */
 #define XTEA_ENC_TEST_VECTORS	4
 #define XTEA_DEC_TEST_VECTORS	4
 
-static struct cipher_testvec xtea_enc_tv_template[] =
-{
+static struct cipher_testvec xtea_enc_tv_template[] = {
 	{
 		.key    = { [0 ... 15] = 0x00 },
 		.klen	= 16,
@@ -2232,31 +2225,30 @@ static struct cipher_testvec xtea_enc_tv
 		.key	= { 0x09, 0x65, 0x43, 0x11, 0x66, 0x44, 0x39, 0x25,
 			    0x51, 0x3a, 0x16, 0x10, 0x0a, 0x08, 0x12, 0x6e },
 		.klen	= 16,
-		.input	= { 0x6c, 0x6f, 0x6e, 0x67, 0x65, 0x72, 0x5f, 0x74, 
+		.input	= { 0x6c, 0x6f, 0x6e, 0x67, 0x65, 0x72, 0x5f, 0x74,
 			    0x65, 0x73, 0x74, 0x5f, 0x76, 0x65, 0x63, 0x74 },
 		.ilen	= 16,
-		.result	= { 0xe2, 0x04, 0xdb, 0xf2, 0x89, 0x85, 0x9e, 0xea, 
+		.result	= { 0xe2, 0x04, 0xdb, 0xf2, 0x89, 0x85, 0x9e, 0xea,
 			    0x61, 0x35, 0xaa, 0xed, 0xb5, 0xcb, 0x71, 0x2c },
 		.rlen	= 16,
 	}, {
 		.key	= { 0x4d, 0x76, 0x32, 0x17, 0x05, 0x3f, 0x75, 0x2c,
 			    0x5d, 0x04, 0x16, 0x36, 0x15, 0x72, 0x63, 0x2f },
 		.klen	= 16,
-		.input	= { 0x54, 0x65, 0x61, 0x20, 0x69, 0x73, 0x20, 0x67, 
-			    0x6f, 0x6f, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x20, 
-			    0x79, 0x6f, 0x75, 0x21, 0x21, 0x21, 0x20, 0x72, 
+		.input	= { 0x54, 0x65, 0x61, 0x20, 0x69, 0x73, 0x20, 0x67,
+			    0x6f, 0x6f, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x20,
+			    0x79, 0x6f, 0x75, 0x21, 0x21, 0x21, 0x20, 0x72,
 			    0x65, 0x61, 0x6c, 0x6c, 0x79, 0x21, 0x21, 0x21 },
 		.ilen	= 32,
-		.result	= { 0x0b, 0x03, 0xcd, 0x8a, 0xbe, 0x95, 0xfd, 0xb1, 
-			    0xc1, 0x44, 0x91, 0x0b, 0xa5, 0xc9, 0x1b, 0xb4, 
-			    0xa9, 0xda, 0x1e, 0x9e, 0xb1, 0x3e, 0x2a, 0x8f, 
+		.result	= { 0x0b, 0x03, 0xcd, 0x8a, 0xbe, 0x95, 0xfd, 0xb1,
+			    0xc1, 0x44, 0x91, 0x0b, 0xa5, 0xc9, 0x1b, 0xb4,
+			    0xa9, 0xda, 0x1e, 0x9e, 0xb1, 0x3e, 0x2a, 0x8f,
 			    0xea, 0xa5, 0x6a, 0x85, 0xd1, 0xf4, 0xa8, 0xa5 },
 		.rlen	= 32,
 	}
 };
 
-static struct cipher_testvec xtea_dec_tv_template[] =
-{
+static struct cipher_testvec xtea_dec_tv_template[] = {
 	{
 		.key    = { [0 ... 15] = 0x00 },
 		.klen	= 16,
@@ -2276,24 +2268,24 @@ static struct cipher_testvec xtea_dec_tv
 		.key	= { 0x09, 0x65, 0x43, 0x11, 0x66, 0x44, 0x39, 0x25,
 			    0x51, 0x3a, 0x16, 0x10, 0x0a, 0x08, 0x12, 0x6e },
 		.klen	= 16,
-		.input	= { 0xe2, 0x04, 0xdb, 0xf2, 0x89, 0x85, 0x9e, 0xea, 
+		.input	= { 0xe2, 0x04, 0xdb, 0xf2, 0x89, 0x85, 0x9e, 0xea,
 			    0x61, 0x35, 0xaa, 0xed, 0xb5, 0xcb, 0x71, 0x2c },
 		.ilen	= 16,
-		.result	= { 0x6c, 0x6f, 0x6e, 0x67, 0x65, 0x72, 0x5f, 0x74, 
+		.result	= { 0x6c, 0x6f, 0x6e, 0x67, 0x65, 0x72, 0x5f, 0x74,
 			    0x65, 0x73, 0x74, 0x5f, 0x76, 0x65, 0x63, 0x74 },
 		.rlen	= 16,
 	}, {
 		.key	= { 0x4d, 0x76, 0x32, 0x17, 0x05, 0x3f, 0x75, 0x2c,
 			    0x5d, 0x04, 0x16, 0x36, 0x15, 0x72, 0x63, 0x2f },
 		.klen	= 16,
-		.input	= { 0x0b, 0x03, 0xcd, 0x8a, 0xbe, 0x95, 0xfd, 0xb1, 
-			    0xc1, 0x44, 0x91, 0x0b, 0xa5, 0xc9, 0x1b, 0xb4, 
-			    0xa9, 0xda, 0x1e, 0x9e, 0xb1, 0x3e, 0x2a, 0x8f, 
+		.input	= { 0x0b, 0x03, 0xcd, 0x8a, 0xbe, 0x95, 0xfd, 0xb1,
+			    0xc1, 0x44, 0x91, 0x0b, 0xa5, 0xc9, 0x1b, 0xb4,
+			    0xa9, 0xda, 0x1e, 0x9e, 0xb1, 0x3e, 0x2a, 0x8f,
 			    0xea, 0xa5, 0x6a, 0x85, 0xd1, 0xf4, 0xa8, 0xa5 },
 		.ilen	= 32,
-		.result	= { 0x54, 0x65, 0x61, 0x20, 0x69, 0x73, 0x20, 0x67, 
-			    0x6f, 0x6f, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x20, 
-			    0x79, 0x6f, 0x75, 0x21, 0x21, 0x21, 0x20, 0x72, 
+		.result	= { 0x54, 0x65, 0x61, 0x20, 0x69, 0x73, 0x20, 0x67,
+			    0x6f, 0x6f, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x20,
+			    0x79, 0x6f, 0x75, 0x21, 0x21, 0x21, 0x20, 0x72,
 			    0x65, 0x61, 0x6c, 0x6c, 0x79, 0x21, 0x21, 0x21 },
 		.rlen	= 32,
 	}
@@ -2305,9 +2297,9 @@ static struct cipher_testvec xtea_dec_tv
 #define KHAZAD_ENC_TEST_VECTORS 5
 #define KHAZAD_DEC_TEST_VECTORS 5
 
-static struct cipher_testvec khazad_enc_tv_template[] = { 
-	{ 
-		.key	= { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+static struct cipher_testvec khazad_enc_tv_template[] = {
+	{
+		.key	= { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 			    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
 		.klen	= 16,
 		.input	= { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
@@ -2351,9 +2343,9 @@ static struct cipher_testvec khazad_enc_
 	},
 };
 
-static struct cipher_testvec khazad_dec_tv_template[] = { 
+static struct cipher_testvec khazad_dec_tv_template[] = {
 	{
-		.key	= { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+		.key	= { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 			    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
 		.klen	= 16,
 		.input	= { 0X49, 0Xa4, 0Xce, 0X32, 0Xac, 0X19, 0X0e, 0X3f },
@@ -2697,8 +2689,7 @@ static struct comp_testvec deflate_decom
  */
 #define MICHAEL_MIC_TEST_VECTORS 6
 
-static struct hash_testvec michael_mic_tv_template[] =
-{
+static struct hash_testvec michael_mic_tv_template[] = {
 	{
 		.key = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
 		.ksize = 8,
@@ -2743,4 +2734,88 @@ static struct hash_testvec michael_mic_t
 	}
 };
 
+/*
+ * Cipher speed tests
+ */
+static struct cipher_speed aes_speed_template[] = {
+	{ .klen = 16, .blen = 16, },
+	{ .klen = 16, .blen = 64, },
+	{ .klen = 16, .blen = 256, },
+	{ .klen = 16, .blen = 1024, },
+	{ .klen = 16, .blen = 8192, },
+	{ .klen = 24, .blen = 16, },
+	{ .klen = 24, .blen = 64, },
+	{ .klen = 24, .blen = 256, },
+	{ .klen = 24, .blen = 1024, },
+	{ .klen = 24, .blen = 8192, },
+	{ .klen = 32, .blen = 16, },
+	{ .klen = 32, .blen = 64, },
+	{ .klen = 32, .blen = 256, },
+	{ .klen = 32, .blen = 1024, },
+	{ .klen = 32, .blen = 8192, },
+
+	/* End marker */
+	{  .klen = 0, .blen = 0, }
+};
+
+static struct cipher_speed des3_ede_speed_template[] = {
+	{ .klen = 24, .blen = 16, },
+	{ .klen = 24, .blen = 64, },
+	{ .klen = 24, .blen = 256, },
+	{ .klen = 24, .blen = 1024, },
+	{ .klen = 24, .blen = 8192, },
+
+	/* End marker */
+	{  .klen = 0, .blen = 0, }
+};
+
+static struct cipher_speed twofish_speed_template[] = {
+	{ .klen = 16, .blen = 16, },
+	{ .klen = 16, .blen = 64, },
+	{ .klen = 16, .blen = 256, },
+	{ .klen = 16, .blen = 1024, },
+	{ .klen = 16, .blen = 8192, },
+	{ .klen = 24, .blen = 16, },
+	{ .klen = 24, .blen = 64, },
+	{ .klen = 24, .blen = 256, },
+	{ .klen = 24, .blen = 1024, },
+	{ .klen = 24, .blen = 8192, },
+	{ .klen = 32, .blen = 16, },
+	{ .klen = 32, .blen = 64, },
+	{ .klen = 32, .blen = 256, },
+	{ .klen = 32, .blen = 1024, },
+	{ .klen = 32, .blen = 8192, },
+
+	/* End marker */
+	{  .klen = 0, .blen = 0, }
+};
+
+static struct cipher_speed blowfish_speed_template[] = {
+	/* Don't support blowfish keys > 256 bit in this test */
+	{ .klen = 8, .blen = 16, },
+	{ .klen = 8, .blen = 64, },
+	{ .klen = 8, .blen = 256, },
+	{ .klen = 8, .blen = 1024, },
+	{ .klen = 8, .blen = 8192, },
+	{ .klen = 32, .blen = 16, },
+	{ .klen = 32, .blen = 64, },
+	{ .klen = 32, .blen = 256, },
+	{ .klen = 32, .blen = 1024, },
+	{ .klen = 32, .blen = 8192, },
+
+	/* End marker */
+	{  .klen = 0, .blen = 0, }
+};
+
+static struct cipher_speed des_speed_template[] = {
+	{ .klen = 8, .blen = 16, },
+	{ .klen = 8, .blen = 64, },
+	{ .klen = 8, .blen = 256, },
+	{ .klen = 8, .blen = 1024, },
+	{ .klen = 8, .blen = 8192, },
+
+	/* End marker */
+	{  .klen = 0, .blen = 0, }
+};
+
 #endif	/* _CRYPTO_TCRYPT_H */
diff --git a/drivers/Kconfig b/drivers/Kconfig
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -28,7 +28,7 @@ source "drivers/message/i2o/Kconfig"
 
 source "drivers/macintosh/Kconfig"
 
-source "net/Kconfig"
+source "drivers/net/Kconfig"
 
 source "drivers/isdn/Kconfig"
 
@@ -44,6 +44,8 @@ source "drivers/i2c/Kconfig"
 
 source "drivers/w1/Kconfig"
 
+source "drivers/hwmon/Kconfig"
+
 source "drivers/misc/Kconfig"
 
 source "drivers/media/Kconfig"
@@ -58,4 +60,6 @@ source "drivers/mmc/Kconfig"
 
 source "drivers/infiniband/Kconfig"
 
+source "drivers/sn/Kconfig"
+
 endmenu
diff --git a/drivers/Makefile b/drivers/Makefile
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -52,6 +52,7 @@ obj-$(CONFIG_INPUT)		+= input/
 obj-$(CONFIG_I2O)		+= message/
 obj-$(CONFIG_I2C)		+= i2c/
 obj-$(CONFIG_W1)		+= w1/
+obj-$(CONFIG_HWMON)		+= hwmon/
 obj-$(CONFIG_PHONE)		+= telephony/
 obj-$(CONFIG_MD)		+= md/
 obj-$(CONFIG_BT)		+= bluetooth/
@@ -61,6 +62,6 @@ obj-$(CONFIG_EISA)		+= eisa/
 obj-$(CONFIG_CPU_FREQ)		+= cpufreq/
 obj-$(CONFIG_MMC)		+= mmc/
 obj-$(CONFIG_INFINIBAND)	+= infiniband/
-obj-$(CONFIG_BLK_DEV_SGIIOC4)	+= sn/
+obj-$(CONFIG_SGI_IOC4)		+= sn/
 obj-y				+= firmware/
 obj-$(CONFIG_CRYPTO)		+= crypto/
diff --git a/drivers/acorn/block/fd1772.c b/drivers/acorn/block/fd1772.c
--- a/drivers/acorn/block/fd1772.c
+++ b/drivers/acorn/block/fd1772.c
@@ -1283,8 +1283,7 @@ static void do_fd_request(request_queue_
 	if (fdc_busy) return;
 	save_flags(flags);
 	cli();
-	while (fdc_busy)
-		sleep_on(&fdc_wait);
+	wait_event(fdc_wait, !fdc_busy);
 	fdc_busy = 1;
 	ENABLE_IRQ();
 	restore_flags(flags);
diff --git a/drivers/acorn/char/pcf8583.c b/drivers/acorn/char/pcf8583.c
--- a/drivers/acorn/char/pcf8583.c
+++ b/drivers/acorn/char/pcf8583.c
@@ -26,11 +26,8 @@ static unsigned short normal_addr[] = { 
 
 static struct i2c_client_address_data addr_data = {
 	.normal_i2c		= normal_addr,
-	.normal_i2c_range	= ignore,
 	.probe			= ignore,
-	.probe_range		= ignore,
 	.ignore			= ignore,
-	.ignore_range		= ignore,
 	.force			= ignore,
 };
 
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -3,6 +3,7 @@
 #
 
 menu "ACPI (Advanced Configuration and Power Interface) Support"
+	depends on PM
 	depends on !X86_VISWS
 	depends on !IA64_HP_SIM
 	depends on IA64 || X86
@@ -48,14 +49,13 @@ config ACPI_BOOT
 
 config ACPI_INTERPRETER
 	bool
-	depends on !IA64_SGI_SN
 	default y
 
 if ACPI_INTERPRETER
 
 config ACPI_SLEEP
 	bool "Sleep States (EXPERIMENTAL)"
-	depends on X86
+	depends on X86 && (!SMP || SUSPEND_SMP)
 	depends on EXPERIMENTAL && PM
 	default y
 	---help---
@@ -79,6 +79,14 @@ config ACPI_SLEEP_PROC_FS
 	depends on ACPI_SLEEP && PROC_FS
 	default y
 
+config ACPI_SLEEP_PROC_SLEEP
+	bool "/proc/acpi/sleep (deprecated)"
+	depends on ACPI_SLEEP_PROC_FS
+	default n
+	---help---
+	  Create /proc/acpi/sleep
+	  Deprecated by /sys/power/state
+
 config ACPI_AC
 	tristate "AC Adapter"
 	depends on X86
@@ -99,7 +107,6 @@ config ACPI_BATTERY
 
 config ACPI_BUTTON
 	tristate "Button"
-	depends on !IA64_SGI_SN
 	default m
 	help
 	  This driver registers for events based on buttons, such as the
@@ -111,7 +118,6 @@ config ACPI_BUTTON
 config ACPI_VIDEO
 	tristate "Video"
 	depends on EXPERIMENTAL
-	depends on !IA64_SGI_SN
 	default m
 	help
 	  This driver implement the ACPI Extensions For Display Adapters
@@ -122,9 +128,18 @@ config ACPI_VIDEO
 	  Note that this is an ref. implementation only.  It may or may not work
 	  for your integrated video device.
 
+config ACPI_HOTKEY
+	tristate "Generic Hotkey"
+	depends on ACPI_INTERPRETER
+	depends on EXPERIMENTAL
+	depends on !IA64_SGI_SN
+	default n
+	help
+	  Experimental consolidated hotkey driver.
+	  If you are unsure, say N.
+
 config ACPI_FAN
 	tristate "Fan"
-	depends on !IA64_SGI_SN
 	default m
 	help
 	  This driver adds support for ACPI fan devices, allowing user-mode 
@@ -132,7 +147,6 @@ config ACPI_FAN
 
 config ACPI_PROCESSOR
 	tristate "Processor"
-	depends on !IA64_SGI_SN
 	default m
 	help
 	  This driver installs ACPI as the idle handler for Linux, and uses
@@ -142,7 +156,6 @@ config ACPI_PROCESSOR
 config ACPI_HOTPLUG_CPU
 	bool "Processor Hotplug (EXPERIMENTAL)"
 	depends on ACPI_PROCESSOR && HOTPLUG_CPU && EXPERIMENTAL
-	depends on !IA64_SGI_SN
 	select ACPI_CONTAINER
 	default n
 	 ---help---
@@ -262,7 +275,6 @@ config ACPI_BLACKLIST_YEAR
 
 config ACPI_DEBUG
 	bool "Debug Statements"
-	depends on !IA64_SGI_SN
 	default n
 	help
 	  The ACPI driver can optionally report errors with a great deal
@@ -271,7 +283,6 @@ config ACPI_DEBUG
 
 config ACPI_BUS
 	bool
-	depends on !IA64_SGI_SN
 	default y
 
 config ACPI_EC
@@ -285,17 +296,14 @@ config ACPI_EC
 
 config ACPI_POWER
 	bool
-	depends on !IA64_SGI_SN
 	default y
 
 config ACPI_PCI
 	bool
-	depends on !IA64_SGI_SN
 	default PCI
 
 config ACPI_SYSTEM
 	bool
-	depends on !IA64_SGI_SN
 	default y
 	help
 	  This driver will enable your system to shut down using ACPI, and
@@ -327,8 +335,13 @@ config ACPI_CONTAINER
 	depends on EXPERIMENTAL
 	default (ACPI_HOTPLUG_MEMORY || ACPI_HOTPLUG_CPU || ACPI_HOTPLUG_IO)
 	 ---help---
-	 	This is the ACPI generic container driver which supports
-		ACPI0004, PNP0A05 and PNP0A06 devices
+	  This allows _physical_ insertion and removal of CPUs and memory.
+	  This can be useful, for example, on NUMA machines that support
+	  ACPI based physical hotplug of nodes, or non-NUMA machines that
+	  support physical cpu/memory hot-plug.
+
+	  If one selects "m", this driver can be loaded with
+	  "modprobe acpi_container".
 
 config ACPI_HOTPLUG_MEMORY
 	tristate "Memory Hotplug"
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -36,13 +36,14 @@ processor-objs	+= processor_perflib.o			
 endif
 
 obj-$(CONFIG_ACPI_BUS)		+= sleep/
-obj-$(CONFIG_ACPI_BUS)		+= bus.o
+obj-$(CONFIG_ACPI_BUS)		+= bus.o glue.o
 obj-$(CONFIG_ACPI_AC) 		+= ac.o
 obj-$(CONFIG_ACPI_BATTERY)	+= battery.o
 obj-$(CONFIG_ACPI_BUTTON)	+= button.o
 obj-$(CONFIG_ACPI_EC)		+= ec.o
 obj-$(CONFIG_ACPI_FAN)		+= fan.o
-obj-$(CONFIG_ACPI_VIDEO)	+= video.o
+obj-$(CONFIG_ACPI_VIDEO)	+= video.o 
+obj-$(CONFIG_ACPI_HOTKEY)	+= hotkey.o
 obj-$(CONFIG_ACPI_PCI)		+= pci_root.o pci_link.o pci_irq.o pci_bind.o
 obj-$(CONFIG_ACPI_POWER)	+= power.o
 obj-$(CONFIG_ACPI_PROCESSOR)	+= processor.o
diff --git a/drivers/acpi/asus_acpi.c b/drivers/acpi/asus_acpi.c
--- a/drivers/acpi/asus_acpi.c
+++ b/drivers/acpi/asus_acpi.c
@@ -1204,6 +1204,10 @@ static int __init asus_acpi_init(void)
 	if (acpi_disabled)
 		return -ENODEV;
 
+	if (!acpi_specific_hotkey_enabled){
+		printk(KERN_ERR "Using generic hotkey driver\n");
+		return -ENODEV;	
+	}
 	asus_proc_dir = proc_mkdir(PROC_ASUS, acpi_root_dir);
 	if (!asus_proc_dir) {
 		printk(KERN_ERR "Asus ACPI: Unable to create /proc entry\n");
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -212,6 +212,12 @@ acpi_bus_set_power (
 		ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Device is not power manageable\n"));
 		return_VALUE(-ENODEV);
 	}
+	/*
+	 * Get device's current power state if it's unknown
+	 * This means device power state isn't initialized or previous setting failed
+	 */
+	if (device->power.state == ACPI_STATE_UNKNOWN)
+		acpi_bus_get_power(device->handle, &device->power.state);
 	if (state == device->power.state) {
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device is already at D%d\n", state));
 		return_VALUE(0);
@@ -231,7 +237,7 @@ acpi_bus_set_power (
 	 * On transitions to a high-powered state we first apply power (via
 	 * power resources) then evalute _PSx.  Conversly for transitions to
 	 * a lower-powered state.
-	 */ 
+	 */
 	if (state < device->power.state) {
 		if (device->power.flags.power_resources) {
 			result = acpi_power_transition(device, state);
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
--- a/drivers/acpi/button.c
+++ b/drivers/acpi/button.c
@@ -156,6 +156,10 @@ static int acpi_button_state_open_fs(str
 	return single_open(file, acpi_button_state_seq_show, PDE(inode)->data);
 }
 
+static struct proc_dir_entry *acpi_power_dir;
+static struct proc_dir_entry *acpi_sleep_dir;
+static struct proc_dir_entry *acpi_lid_dir;
+
 static int
 acpi_button_add_fs (
 	struct acpi_device	*device)
@@ -173,17 +177,23 @@ acpi_button_add_fs (
 	switch (button->type) {
 	case ACPI_BUTTON_TYPE_POWER:
 	case ACPI_BUTTON_TYPE_POWERF:
-			entry = proc_mkdir(ACPI_BUTTON_SUBCLASS_POWER, 
+		if (!acpi_power_dir)
+			acpi_power_dir = proc_mkdir(ACPI_BUTTON_SUBCLASS_POWER, 
 				acpi_button_dir);
+		entry = acpi_power_dir;
 		break;
 	case ACPI_BUTTON_TYPE_SLEEP:
 	case ACPI_BUTTON_TYPE_SLEEPF:
-			entry = proc_mkdir(ACPI_BUTTON_SUBCLASS_SLEEP, 
+		if (!acpi_sleep_dir)
+			acpi_sleep_dir = proc_mkdir(ACPI_BUTTON_SUBCLASS_SLEEP, 
 				acpi_button_dir);
+		entry = acpi_sleep_dir;
 		break;
 	case ACPI_BUTTON_TYPE_LID:
-			entry = proc_mkdir(ACPI_BUTTON_SUBCLASS_LID, 
+		if (!acpi_lid_dir)
+			acpi_lid_dir = proc_mkdir(ACPI_BUTTON_SUBCLASS_LID, 
 				acpi_button_dir);
+		entry = acpi_lid_dir;
 		break;
 	}
 
@@ -246,24 +256,6 @@ acpi_button_remove_fs (
 
 		remove_proc_entry(acpi_device_bid(device),
 				     acpi_device_dir(device)->parent);
-
-
-		switch (button->type) {
-			case ACPI_BUTTON_TYPE_POWER:
-			case ACPI_BUTTON_TYPE_POWERF:
-				remove_proc_entry(ACPI_BUTTON_SUBCLASS_POWER, 
-					acpi_button_dir);
-				break;
-			case ACPI_BUTTON_TYPE_SLEEP:
-			case ACPI_BUTTON_TYPE_SLEEPF:
-				remove_proc_entry(ACPI_BUTTON_SUBCLASS_SLEEP, 
-					acpi_button_dir);
-				break;
-			case ACPI_BUTTON_TYPE_LID:
-				remove_proc_entry(ACPI_BUTTON_SUBCLASS_LID, 
-					acpi_button_dir);
-				break;
-		}
 		acpi_device_dir(device) = NULL;
 	}
 
@@ -327,10 +319,6 @@ acpi_button_add (
 	acpi_status		status = AE_OK;
 	struct acpi_button	*button = NULL;
 
-	static struct acpi_device *power_button;
-	static struct acpi_device *sleep_button;
-	static struct acpi_device *lid_button;
-
 	ACPI_FUNCTION_TRACE("acpi_button_add");
 
 	if (!device)
@@ -391,38 +379,6 @@ acpi_button_add (
 		goto end;
 	}
 
-	/*
-	 * Ensure only one button of each type is used.
-	 */
-	switch (button->type) {
-	case ACPI_BUTTON_TYPE_POWER:
-	case ACPI_BUTTON_TYPE_POWERF:
-		if (!power_button)
-			power_button = device;
-		else {
-			kfree(button);
-			return_VALUE(-ENODEV);
-		}
-		break;
-	case ACPI_BUTTON_TYPE_SLEEP:
-	case ACPI_BUTTON_TYPE_SLEEPF:
-		if (!sleep_button)
-			sleep_button = device;
-		else {
-			kfree(button);
-			return_VALUE(-ENODEV);
-		}
-		break;
-	case ACPI_BUTTON_TYPE_LID:
-		if (!lid_button)
-			lid_button = device;
-		else {
-			kfree(button);
-			return_VALUE(-ENODEV);
-		}
-		break;
-	}
-
 	result = acpi_button_add_fs(device);
 	if (result)
 		goto end;
@@ -530,7 +486,6 @@ acpi_button_init (void)
 	if (!acpi_button_dir)
 		return_VALUE(-ENODEV);
 	acpi_button_dir->owner = THIS_MODULE;
-
 	result = acpi_bus_register_driver(&acpi_button_driver);
 	if (result < 0) {
 		remove_proc_entry(ACPI_BUTTON_CLASS, acpi_root_dir);
@@ -548,6 +503,12 @@ acpi_button_exit (void)
 
 	acpi_bus_unregister_driver(&acpi_button_driver);
 
+	if (acpi_power_dir) 
+		remove_proc_entry(ACPI_BUTTON_SUBCLASS_POWER, acpi_button_dir);
+	if (acpi_sleep_dir)
+		remove_proc_entry(ACPI_BUTTON_SUBCLASS_SLEEP, acpi_button_dir);
+	if (acpi_lid_dir)
+		remove_proc_entry(ACPI_BUTTON_SUBCLASS_LID, acpi_button_dir);
 	remove_proc_entry(ACPI_BUTTON_CLASS, acpi_root_dir);
 
 	return_VOID;
diff --git a/drivers/acpi/container.c b/drivers/acpi/container.c
--- a/drivers/acpi/container.c
+++ b/drivers/acpi/container.c
@@ -153,7 +153,7 @@ container_device_add(struct acpi_device 
 		return_VALUE(-ENODEV);
 	}
 
-	result = acpi_bus_scan(*device);
+	result = acpi_bus_start(*device);
 
 	return_VALUE(result);
 }
diff --git a/drivers/acpi/dispatcher/dsfield.c b/drivers/acpi/dispatcher/dsfield.c
--- a/drivers/acpi/dispatcher/dsfield.c
+++ b/drivers/acpi/dispatcher/dsfield.c
@@ -53,13 +53,20 @@
 #define _COMPONENT          ACPI_DISPATCHER
 	 ACPI_MODULE_NAME    ("dsfield")
 
+/* Local prototypes */
+
+static acpi_status
+acpi_ds_get_field_names (
+	struct acpi_create_field_info   *info,
+	struct acpi_walk_state          *walk_state,
+	union acpi_parse_object         *arg);
+
 
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ds_create_buffer_field
  *
- * PARAMETERS:  Opcode              - The opcode to be executed
- *              Operands            - List of operands for the opcode
+ * PARAMETERS:  Op                  - Current parse op (create_xXField)
  *              walk_state          - Current state
  *
  * RETURN:      Status
@@ -70,7 +77,7 @@
  *              create_word_field_op,
  *              create_dword_field_op,
  *              create_qword_field_op,
- *              create_field_op     (all of which define fields in buffers)
+ *              create_field_op     (all of which define a field in a buffer)
  *
  ******************************************************************************/
 
@@ -119,7 +126,8 @@ acpi_ds_create_buffer_field (
 			flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE;
 		}
 		else {
-			flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE | ACPI_NS_ERROR_IF_FOUND;
+			flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE |
+					ACPI_NS_ERROR_IF_FOUND;
 		}
 
 		/*
@@ -134,16 +142,16 @@ acpi_ds_create_buffer_field (
 		}
 	}
 
-	/* We could put the returned object (Node) on the object stack for later, but
-	 * for now, we will put it in the "op" object that the parser uses, so we
-	 * can get it again at the end of this scope
+	/* We could put the returned object (Node) on the object stack for later,
+	 * but for now, we will put it in the "op" object that the parser uses,
+	 * so we can get it again at the end of this scope
 	 */
 	op->common.node = node;
 
 	/*
-	 * If there is no object attached to the node, this node was just created and
-	 * we need to create the field object.  Otherwise, this was a lookup of an
-	 * existing node and we don't want to create the field object again.
+	 * If there is no object attached to the node, this node was just created
+	 * and we need to create the field object.  Otherwise, this was a lookup
+	 * of an existing node and we don't want to create the field object again.
 	 */
 	obj_desc = acpi_ns_get_attached_object (node);
 	if (obj_desc) {
@@ -205,7 +213,7 @@ cleanup:
  *
  ******************************************************************************/
 
-acpi_status
+static acpi_status
 acpi_ds_get_field_names (
 	struct acpi_create_field_info   *info,
 	struct acpi_walk_state          *walk_state,
@@ -238,7 +246,8 @@ acpi_ds_get_field_names (
 					 + (acpi_integer) arg->common.value.size;
 
 			if (position > ACPI_UINT32_MAX) {
-				ACPI_REPORT_ERROR (("Bit offset within field too large (> 0xFFFFFFFF)\n"));
+				ACPI_REPORT_ERROR ((
+					"Bit offset within field too large (> 0xFFFFFFFF)\n"));
 				return_ACPI_STATUS (AE_SUPPORT);
 			}
 
@@ -250,12 +259,15 @@ acpi_ds_get_field_names (
 
 			/*
 			 * Get a new access_type and access_attribute -- to be used for all
-			 * field units that follow, until field end or another access_as keyword.
+			 * field units that follow, until field end or another access_as
+			 * keyword.
 			 *
-			 * In field_flags, preserve the flag bits other than the ACCESS_TYPE bits
+			 * In field_flags, preserve the flag bits other than the
+			 * ACCESS_TYPE bits
 			 */
-			info->field_flags = (u8) ((info->field_flags & ~(AML_FIELD_ACCESS_TYPE_MASK)) |
-					  ((u8) ((u32) arg->common.value.integer >> 8)));
+			info->field_flags = (u8)
+				((info->field_flags & ~(AML_FIELD_ACCESS_TYPE_MASK)) |
+				((u8) ((u32) arg->common.value.integer >> 8)));
 
 			info->attribute = (u8) (arg->common.value.integer);
 			break;
@@ -267,7 +279,8 @@ acpi_ds_get_field_names (
 
 			status = acpi_ns_lookup (walk_state->scope_info,
 					  (char *) &arg->named.name,
-					  info->field_type, ACPI_IMODE_EXECUTE, ACPI_NS_DONT_OPEN_SCOPE,
+					  info->field_type, ACPI_IMODE_EXECUTE,
+					  ACPI_NS_DONT_OPEN_SCOPE,
 					  walk_state, &info->field_node);
 			if (ACPI_FAILURE (status)) {
 				ACPI_REPORT_NSERROR ((char *) &arg->named.name, status);
@@ -295,8 +308,9 @@ acpi_ds_get_field_names (
 					 + (acpi_integer) arg->common.value.size;
 
 			if (position > ACPI_UINT32_MAX) {
-				ACPI_REPORT_ERROR (("Field [%4.4s] bit offset too large (> 0xFFFFFFFF)\n",
-						(char *) &info->field_node->name));
+				ACPI_REPORT_ERROR ((
+					"Field [%4.4s] bit offset too large (> 0xFFFFFFFF)\n",
+					(char *) &info->field_node->name));
 				return_ACPI_STATUS (AE_SUPPORT);
 			}
 
@@ -306,7 +320,8 @@ acpi_ds_get_field_names (
 
 		default:
 
-			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid opcode in field list: %X\n",
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+				"Invalid opcode in field list: %X\n",
 				arg->common.aml_opcode));
 			return_ACPI_STATUS (AE_AML_BAD_OPCODE);
 		}
@@ -435,7 +450,8 @@ acpi_ds_init_field_objects (
 			status = acpi_ns_lookup (walk_state->scope_info,
 					  (char *) &arg->named.name,
 					  type, ACPI_IMODE_LOAD_PASS1,
-					  ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE | ACPI_NS_ERROR_IF_FOUND,
+					  ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE |
+					  ACPI_NS_ERROR_IF_FOUND,
 					  walk_state, &node);
 			if (ACPI_FAILURE (status)) {
 				ACPI_REPORT_NSERROR ((char *) &arg->named.name, status);
diff --git a/drivers/acpi/dispatcher/dsinit.c b/drivers/acpi/dispatcher/dsinit.c
--- a/drivers/acpi/dispatcher/dsinit.c
+++ b/drivers/acpi/dispatcher/dsinit.c
@@ -49,12 +49,21 @@
 #define _COMPONENT          ACPI_DISPATCHER
 	 ACPI_MODULE_NAME    ("dsinit")
 
+/* Local prototypes */
+
+static acpi_status
+acpi_ds_init_one_object (
+	acpi_handle                     obj_handle,
+	u32                             level,
+	void                            *context,
+	void                            **return_value);
+
 
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ds_init_one_object
  *
- * PARAMETERS:  obj_handle      - Node
+ * PARAMETERS:  obj_handle      - Node for the object
  *              Level           - Current nesting level
  *              Context         - Points to a init info struct
  *              return_value    - Not used
@@ -70,7 +79,7 @@
  *
  ******************************************************************************/
 
-acpi_status
+static acpi_status
 acpi_ds_init_one_object (
 	acpi_handle                     obj_handle,
 	u32                             level,
@@ -105,7 +114,8 @@ acpi_ds_init_one_object (
 
 		status = acpi_ds_initialize_region (obj_handle);
 		if (ACPI_FAILURE (status)) {
-			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Region %p [%4.4s] - Init failure, %s\n",
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+				"Region %p [%4.4s] - Init failure, %s\n",
 				obj_handle, acpi_ut_get_node_name (obj_handle),
 				acpi_format_exception (status)));
 		}
@@ -118,8 +128,10 @@ acpi_ds_init_one_object (
 
 		info->method_count++;
 
-		/* Print a dot for each method unless we are going to print the entire pathname */
-
+		/*
+		 * Print a dot for each method unless we are going to print
+		 * the entire pathname
+		 */
 		if (!(acpi_dbg_level & ACPI_LV_INIT_NAMES)) {
 			ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, "."));
 		}
@@ -140,7 +152,8 @@ acpi_ds_init_one_object (
 		 */
 		status = acpi_ds_parse_method (obj_handle);
 		if (ACPI_FAILURE (status)) {
-			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Method %p [%4.4s] - parse failure, %s\n",
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+				"Method %p [%4.4s] - parse failure, %s\n",
 				obj_handle, acpi_ut_get_node_name (obj_handle),
 				acpi_format_exception (status)));
 
@@ -154,7 +167,8 @@ acpi_ds_init_one_object (
 		 * for every execution since there isn't much overhead
 		 */
 		acpi_ns_delete_namespace_subtree (obj_handle);
-		acpi_ns_delete_namespace_by_owner (((struct acpi_namespace_node *) obj_handle)->object->method.owning_id);
+		acpi_ns_delete_namespace_by_owner (
+			((struct acpi_namespace_node *) obj_handle)->object->method.owning_id);
 		break;
 
 
diff --git a/drivers/acpi/dispatcher/dsmethod.c b/drivers/acpi/dispatcher/dsmethod.c
--- a/drivers/acpi/dispatcher/dsmethod.c
+++ b/drivers/acpi/dispatcher/dsmethod.c
@@ -153,12 +153,11 @@ acpi_ds_parse_method (
 	/*
 	 * Parse the method, first pass
 	 *
-	 * The first pass load is where newly declared named objects are
-	 * added into the namespace.  Actual evaluation of
-	 * the named objects (what would be called a "second
-	 * pass") happens during the actual execution of the
-	 * method so that operands to the named objects can
-	 * take on dynamic run-time values.
+	 * The first pass load is where newly declared named objects are added into
+	 * the namespace.  Actual evaluation of the named objects (what would be
+	 * called a "second pass") happens during the actual execution of the
+	 * method so that operands to the named objects can take on dynamic
+	 * run-time values.
 	 */
 	status = acpi_ps_parse_aml (walk_state);
 	if (ACPI_FAILURE (status)) {
diff --git a/drivers/acpi/dispatcher/dsmthdat.c b/drivers/acpi/dispatcher/dsmthdat.c
--- a/drivers/acpi/dispatcher/dsmthdat.c
+++ b/drivers/acpi/dispatcher/dsmthdat.c
@@ -52,6 +52,29 @@
 #define _COMPONENT          ACPI_DISPATCHER
 	 ACPI_MODULE_NAME    ("dsmthdat")
 
+/* Local prototypes */
+
+static void
+acpi_ds_method_data_delete_value (
+	u16                             opcode,
+	u32                             index,
+	struct acpi_walk_state          *walk_state);
+
+static acpi_status
+acpi_ds_method_data_set_value (
+	u16                             opcode,
+	u32                             index,
+	union acpi_operand_object       *object,
+	struct acpi_walk_state          *walk_state);
+
+#ifdef ACPI_OBSOLETE_FUNCTIONS
+acpi_object_type
+acpi_ds_method_data_get_type (
+	u16                             opcode,
+	u32                             index,
+	struct acpi_walk_state          *walk_state);
+#endif
+
 
 /*******************************************************************************
  *
@@ -62,8 +85,8 @@
  * RETURN:      Status
  *
  * DESCRIPTION: Initialize the data structures that hold the method's arguments
- *              and locals.  The data struct is an array of NTEs for each.
- *              This allows ref_of and de_ref_of to work properly for these
+ *              and locals.  The data struct is an array of namespace nodes for
+ *              each - this allows ref_of and de_ref_of to work properly for these
  *              special data types.
  *
  * NOTES:       walk_state fields are initialized to zero by the
@@ -92,7 +115,8 @@ acpi_ds_method_data_init (
 		walk_state->arguments[i].name.integer |= (i << 24);
 		walk_state->arguments[i].descriptor   = ACPI_DESC_TYPE_NAMED;
 		walk_state->arguments[i].type         = ACPI_TYPE_ANY;
-		walk_state->arguments[i].flags        = ANOBJ_END_OF_PEER_LIST | ANOBJ_METHOD_ARG;
+		walk_state->arguments[i].flags        = ANOBJ_END_OF_PEER_LIST |
+				  ANOBJ_METHOD_ARG;
 	}
 
 	/* Init the method locals */
@@ -104,7 +128,8 @@ acpi_ds_method_data_init (
 		walk_state->local_variables[i].name.integer |= (i << 24);
 		walk_state->local_variables[i].descriptor  = ACPI_DESC_TYPE_NAMED;
 		walk_state->local_variables[i].type        = ACPI_TYPE_ANY;
-		walk_state->local_variables[i].flags       = ANOBJ_END_OF_PEER_LIST | ANOBJ_METHOD_LOCAL;
+		walk_state->local_variables[i].flags       = ANOBJ_END_OF_PEER_LIST |
+				 ANOBJ_METHOD_LOCAL;
 	}
 
 	return_VOID;
@@ -198,15 +223,18 @@ acpi_ds_method_data_init_args (
 		return_ACPI_STATUS (AE_OK);
 	}
 
-	/* Copy passed parameters into the new method stack frame  */
+	/* Copy passed parameters into the new method stack frame */
 
-	while ((index < ACPI_METHOD_NUM_ARGS) && (index < max_param_count) && params[index]) {
+	while ((index < ACPI_METHOD_NUM_ARGS) &&
+		   (index < max_param_count)      &&
+			params[index]) {
 		/*
 		 * A valid parameter.
 		 * Store the argument in the method/walk descriptor.
 		 * Do not copy the arg in order to implement call by reference
 		 */
-		status = acpi_ds_method_data_set_value (AML_ARG_OP, index, params[index], walk_state);
+		status = acpi_ds_method_data_set_value (AML_ARG_OP, index,
+				 params[index], walk_state);
 		if (ACPI_FAILURE (status)) {
 			return_ACPI_STATUS (status);
 		}
@@ -224,11 +252,13 @@ acpi_ds_method_data_init_args (
  * FUNCTION:    acpi_ds_method_data_get_node
  *
  * PARAMETERS:  Opcode              - Either AML_LOCAL_OP or AML_ARG_OP
- *              Index               - which local_var or argument whose type
- *                                      to get
+ *              Index               - Which Local or Arg whose type to get
  *              walk_state          - Current walk state object
+ *              Node                - Where the node is returned.
  *
- * RETURN:      Get the Node associated with a local or arg.
+ * RETURN:      Status and node
+ *
+ * DESCRIPTION: Get the Node associated with a local or arg.
  *
  ******************************************************************************/
 
@@ -249,7 +279,8 @@ acpi_ds_method_data_get_node (
 	case AML_LOCAL_OP:
 
 		if (index > ACPI_METHOD_MAX_LOCAL) {
-			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Local index %d is invalid (max %d)\n",
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+				"Local index %d is invalid (max %d)\n",
 				index, ACPI_METHOD_MAX_LOCAL));
 			return_ACPI_STATUS (AE_AML_INVALID_INDEX);
 		}
@@ -262,7 +293,8 @@ acpi_ds_method_data_get_node (
 	case AML_ARG_OP:
 
 		if (index > ACPI_METHOD_MAX_ARG) {
-			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Arg index %d is invalid (max %d)\n",
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+				"Arg index %d is invalid (max %d)\n",
 				index, ACPI_METHOD_MAX_ARG));
 			return_ACPI_STATUS (AE_AML_INVALID_INDEX);
 		}
@@ -286,7 +318,7 @@ acpi_ds_method_data_get_node (
  * FUNCTION:    acpi_ds_method_data_set_value
  *
  * PARAMETERS:  Opcode              - Either AML_LOCAL_OP or AML_ARG_OP
- *              Index               - which local_var or argument to get
+ *              Index               - Which Local or Arg to get
  *              Object              - Object to be inserted into the stack entry
  *              walk_state          - Current walk state object
  *
@@ -297,7 +329,7 @@ acpi_ds_method_data_get_node (
  *
  ******************************************************************************/
 
-acpi_status
+static acpi_status
 acpi_ds_method_data_set_value (
 	u16                             opcode,
 	u32                             index,
@@ -340,68 +372,16 @@ acpi_ds_method_data_set_value (
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_ds_method_data_get_type
- *
- * PARAMETERS:  Opcode              - Either AML_LOCAL_OP or AML_ARG_OP
- *              Index               - which local_var or argument whose type
- *                                      to get
- *              walk_state          - Current walk state object
- *
- * RETURN:      Data type of current value of the selected Arg or Local
- *
- ******************************************************************************/
-#ifdef ACPI_FUTURE_USAGE
-acpi_object_type
-acpi_ds_method_data_get_type (
-	u16                             opcode,
-	u32                             index,
-	struct acpi_walk_state          *walk_state)
-{
-	acpi_status                     status;
-	struct acpi_namespace_node      *node;
-	union acpi_operand_object       *object;
-
-
-	ACPI_FUNCTION_TRACE ("ds_method_data_get_type");
-
-
-	/* Get the namespace node for the arg/local */
-
-	status = acpi_ds_method_data_get_node (opcode, index, walk_state, &node);
-	if (ACPI_FAILURE (status)) {
-		return_VALUE ((ACPI_TYPE_NOT_FOUND));
-	}
-
-	/* Get the object */
-
-	object = acpi_ns_get_attached_object (node);
-	if (!object) {
-		/* Uninitialized local/arg, return TYPE_ANY */
-
-		return_VALUE (ACPI_TYPE_ANY);
-	}
-
-	/* Get the object type */
-
-	return_VALUE (ACPI_GET_OBJECT_TYPE (object));
-}
-#endif  /*  ACPI_FUTURE_USAGE  */
-
-
-/*******************************************************************************
- *
  * FUNCTION:    acpi_ds_method_data_get_value
  *
  * PARAMETERS:  Opcode              - Either AML_LOCAL_OP or AML_ARG_OP
  *              Index               - which local_var or argument to get
  *              walk_state          - Current walk state object
- *              *dest_desc          - Ptr to Descriptor into which selected Arg
- *                                    or Local value should be copied
+ *              dest_desc           - Where Arg or Local value is returned
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Retrieve value of selected Arg or Local from the method frame
- *              at the current top of the method stack.
+ * DESCRIPTION: Retrieve value of selected Arg or Local for this method
  *              Used only in acpi_ex_resolve_to_value().
  *
  ******************************************************************************/
@@ -467,14 +447,16 @@ acpi_ds_method_data_get_value (
 		else switch (opcode) {
 		case AML_ARG_OP:
 
-			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Uninitialized Arg[%d] at node %p\n",
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+				"Uninitialized Arg[%d] at node %p\n",
 				index, node));
 
 			return_ACPI_STATUS (AE_AML_UNINITIALIZED_ARG);
 
 		case AML_LOCAL_OP:
 
-			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Uninitialized Local[%d] at node %p\n",
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+				"Uninitialized Local[%d] at node %p\n",
 				index, node));
 
 			return_ACPI_STATUS (AE_AML_UNINITIALIZED_LOCAL);
@@ -506,12 +488,12 @@ acpi_ds_method_data_get_value (
  *
  * RETURN:      None
  *
- * DESCRIPTION: Delete the entry at Opcode:Index on the method stack.  Inserts
+ * DESCRIPTION: Delete the entry at Opcode:Index.  Inserts
  *              a null into the stack slot after the object is deleted.
  *
  ******************************************************************************/
 
-void
+static void
 acpi_ds_method_data_delete_value (
 	u16                             opcode,
 	u32                             index,
@@ -562,7 +544,7 @@ acpi_ds_method_data_delete_value (
  * FUNCTION:    acpi_ds_store_object_to_local
  *
  * PARAMETERS:  Opcode              - Either AML_LOCAL_OP or AML_ARG_OP
- *              Index               - which local_var or argument to set
+ *              Index               - Which Local or Arg to set
  *              obj_desc            - Value to be stored
  *              walk_state          - Current walk state
  *
@@ -651,19 +633,20 @@ acpi_ds_store_object_to_local (
 		 */
 		if (opcode == AML_ARG_OP) {
 			/*
-			 * Make sure that the object is the correct type.  This may be overkill, but
-			 * it is here because references were NS nodes in the past.  Now they are
-			 * operand objects of type Reference.
+			 * Make sure that the object is the correct type.  This may be
+			 * overkill, butit is here because references were NS nodes in
+			 *  the past.  Now they are operand objects of type Reference.
 			 */
 			if (ACPI_GET_DESCRIPTOR_TYPE (current_obj_desc) != ACPI_DESC_TYPE_OPERAND) {
-				ACPI_REPORT_ERROR (("Invalid descriptor type while storing to method arg: [%s]\n",
-						acpi_ut_get_descriptor_name (current_obj_desc)));
+				ACPI_REPORT_ERROR ((
+					"Invalid descriptor type while storing to method arg: [%s]\n",
+					acpi_ut_get_descriptor_name (current_obj_desc)));
 				return_ACPI_STATUS (AE_AML_INTERNAL);
 			}
 
 			/*
-			 * If we have a valid reference object that came from ref_of(), do the
-			 * indirect store
+			 * If we have a valid reference object that came from ref_of(),
+			 * do the indirect store
 			 */
 			if ((current_obj_desc->common.type == ACPI_TYPE_LOCAL_REFERENCE) &&
 				(current_obj_desc->reference.opcode == AML_REF_OF_OP)) {
@@ -713,3 +696,55 @@ acpi_ds_store_object_to_local (
 }
 
 
+#ifdef ACPI_OBSOLETE_FUNCTIONS
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ds_method_data_get_type
+ *
+ * PARAMETERS:  Opcode              - Either AML_LOCAL_OP or AML_ARG_OP
+ *              Index               - Which Local or Arg whose type to get
+ *              walk_state          - Current walk state object
+ *
+ * RETURN:      Data type of current value of the selected Arg or Local
+ *
+ * DESCRIPTION: Get the type of the object stored in the Local or Arg
+ *
+ ******************************************************************************/
+
+acpi_object_type
+acpi_ds_method_data_get_type (
+	u16                             opcode,
+	u32                             index,
+	struct acpi_walk_state          *walk_state)
+{
+	acpi_status                     status;
+	struct acpi_namespace_node      *node;
+	union acpi_operand_object       *object;
+
+
+	ACPI_FUNCTION_TRACE ("ds_method_data_get_type");
+
+
+	/* Get the namespace node for the arg/local */
+
+	status = acpi_ds_method_data_get_node (opcode, index, walk_state, &node);
+	if (ACPI_FAILURE (status)) {
+		return_VALUE ((ACPI_TYPE_NOT_FOUND));
+	}
+
+	/* Get the object */
+
+	object = acpi_ns_get_attached_object (node);
+	if (!object) {
+		/* Uninitialized local/arg, return TYPE_ANY */
+
+		return_VALUE (ACPI_TYPE_ANY);
+	}
+
+	/* Get the object type */
+
+	return_VALUE (ACPI_GET_OBJECT_TYPE (object));
+}
+#endif
+
+
diff --git a/drivers/acpi/dispatcher/dsobject.c b/drivers/acpi/dispatcher/dsobject.c
--- a/drivers/acpi/dispatcher/dsobject.c
+++ b/drivers/acpi/dispatcher/dsobject.c
@@ -52,9 +52,15 @@
 #define _COMPONENT          ACPI_DISPATCHER
 	 ACPI_MODULE_NAME    ("dsobject")
 
+static acpi_status
+acpi_ds_build_internal_object (
+	struct acpi_walk_state          *walk_state,
+	union acpi_parse_object         *op,
+	union acpi_operand_object       **obj_desc_ptr);
+
 
 #ifndef ACPI_NO_METHOD_EXECUTION
-/*****************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    acpi_ds_build_internal_object
  *
@@ -67,9 +73,9 @@
  * DESCRIPTION: Translate a parser Op object to the equivalent namespace object
  *              Simple objects are any objects other than a package object!
  *
- ****************************************************************************/
+ ******************************************************************************/
 
-acpi_status
+static acpi_status
 acpi_ds_build_internal_object (
 	struct acpi_walk_state          *walk_state,
 	union acpi_parse_object         *op,
@@ -90,9 +96,11 @@ acpi_ds_build_internal_object (
 		 * Otherwise, go ahead and look it up now
 		 */
 		if (!op->common.node) {
-			status = acpi_ns_lookup (walk_state->scope_info, op->common.value.string,
+			status = acpi_ns_lookup (walk_state->scope_info,
+					  op->common.value.string,
 					  ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
-					  ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, NULL,
+					  ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
+					  NULL,
 					  (struct acpi_namespace_node **) &(op->common.node));
 
 			if (ACPI_FAILURE (status)) {
@@ -104,12 +112,14 @@ acpi_ds_build_internal_object (
 
 	/* Create and init the internal ACPI object */
 
-	obj_desc = acpi_ut_create_internal_object ((acpi_ps_get_opcode_info (op->common.aml_opcode))->object_type);
+	obj_desc = acpi_ut_create_internal_object (
+			 (acpi_ps_get_opcode_info (op->common.aml_opcode))->object_type);
 	if (!obj_desc) {
 		return_ACPI_STATUS (AE_NO_MEMORY);
 	}
 
-	status = acpi_ds_init_object_from_op (walk_state, op, op->common.aml_opcode, &obj_desc);
+	status = acpi_ds_init_object_from_op (walk_state, op, op->common.aml_opcode,
+			 &obj_desc);
 	if (ACPI_FAILURE (status)) {
 		acpi_ut_remove_reference (obj_desc);
 		return_ACPI_STATUS (status);
@@ -120,7 +130,7 @@ acpi_ds_build_internal_object (
 }
 
 
-/*****************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    acpi_ds_build_internal_buffer_obj
  *
@@ -134,7 +144,7 @@ acpi_ds_build_internal_object (
  * DESCRIPTION: Translate a parser Op package object to the equivalent
  *              namespace object
  *
- ****************************************************************************/
+ ******************************************************************************/
 
 acpi_status
 acpi_ds_build_internal_buffer_obj (
@@ -229,7 +239,7 @@ acpi_ds_build_internal_buffer_obj (
 }
 
 
-/*****************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    acpi_ds_build_internal_package_obj
  *
@@ -243,7 +253,7 @@ acpi_ds_build_internal_buffer_obj (
  * DESCRIPTION: Translate a parser Op package object to the equivalent
  *              namespace object
  *
- ****************************************************************************/
+ ******************************************************************************/
 
 acpi_status
 acpi_ds_build_internal_package_obj (
@@ -331,11 +341,12 @@ acpi_ds_build_internal_package_obj (
 		if (arg->common.aml_opcode == AML_INT_RETURN_VALUE_OP) {
 			/* Object (package or buffer) is already built */
 
-			obj_desc->package.elements[i] = ACPI_CAST_PTR (union acpi_operand_object, arg->common.node);
+			obj_desc->package.elements[i] =
+				ACPI_CAST_PTR (union acpi_operand_object, arg->common.node);
 		}
 		else {
 			status = acpi_ds_build_internal_object (walk_state, arg,
-					  &obj_desc->package.elements[i]);
+					 &obj_desc->package.elements[i]);
 		}
 
 		i++;
@@ -348,7 +359,7 @@ acpi_ds_build_internal_package_obj (
 }
 
 
-/*****************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    acpi_ds_create_node
  *
@@ -360,7 +371,7 @@ acpi_ds_build_internal_package_obj (
  *
  * DESCRIPTION: Create the object to be associated with a namespace node
  *
- ****************************************************************************/
+ ******************************************************************************/
 
 acpi_status
 acpi_ds_create_node (
@@ -392,7 +403,8 @@ acpi_ds_create_node (
 
 	/* Build an internal object for the argument(s) */
 
-	status = acpi_ds_build_internal_object (walk_state, op->common.value.arg, &obj_desc);
+	status = acpi_ds_build_internal_object (walk_state, op->common.value.arg,
+			 &obj_desc);
 	if (ACPI_FAILURE (status)) {
 		return_ACPI_STATUS (status);
 	}
@@ -414,7 +426,7 @@ acpi_ds_create_node (
 #endif /* ACPI_NO_METHOD_EXECUTION */
 
 
-/*****************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    acpi_ds_init_object_from_op
  *
@@ -429,7 +441,7 @@ acpi_ds_create_node (
  *              associated arguments.  The namespace object is a more compact
  *              representation of the Op and its arguments.
  *
- ****************************************************************************/
+ ******************************************************************************/
 
 acpi_status
 acpi_ds_init_object_from_op (
@@ -462,7 +474,8 @@ acpi_ds_init_object_from_op (
 		/*
 		 * Defer evaluation of Buffer term_arg operand
 		 */
-		obj_desc->buffer.node     = (struct acpi_namespace_node *) walk_state->operands[0];
+		obj_desc->buffer.node     = (struct acpi_namespace_node *)
+				   walk_state->operands[0];
 		obj_desc->buffer.aml_start = op->named.data;
 		obj_desc->buffer.aml_length = op->named.length;
 		break;
@@ -473,7 +486,8 @@ acpi_ds_init_object_from_op (
 		/*
 		 * Defer evaluation of Package term_arg operand
 		 */
-		obj_desc->package.node     = (struct acpi_namespace_node *) walk_state->operands[0];
+		obj_desc->package.node     = (struct acpi_namespace_node *)
+				   walk_state->operands[0];
 		obj_desc->package.aml_start = op->named.data;
 		obj_desc->package.aml_length = op->named.length;
 		break;
@@ -486,9 +500,10 @@ acpi_ds_init_object_from_op (
 			/*
 			 * Resolve AML Constants here - AND ONLY HERE!
 			 * All constants are integers.
-			 * We mark the integer with a flag that indicates that it started life
-			 * as a constant -- so that stores to constants will perform as expected (noop).
-			 * (zero_op is used as a placeholder for optional target operands.)
+			 * We mark the integer with a flag that indicates that it started
+			 * life as a constant -- so that stores to constants will perform
+			 * as expected (noop). zero_op is used as a placeholder for optional
+			 * target operands.
 			 */
 			obj_desc->common.flags = AOPOBJ_AML_CONSTANT;
 
@@ -521,7 +536,8 @@ acpi_ds_init_object_from_op (
 
 			default:
 
-				ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown constant opcode %X\n", opcode));
+				ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+					"Unknown constant opcode %X\n", opcode));
 				status = AE_AML_OPERAND_TYPE;
 				break;
 			}
@@ -535,7 +551,8 @@ acpi_ds_init_object_from_op (
 
 
 		default:
-			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown Integer type %X\n", op_info->type));
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown Integer type %X\n",
+				op_info->type));
 			status = AE_AML_OPERAND_TYPE;
 			break;
 		}
@@ -570,8 +587,10 @@ acpi_ds_init_object_from_op (
 			obj_desc->reference.offset = opcode - AML_LOCAL_OP;
 
 #ifndef ACPI_NO_METHOD_EXECUTION
-			status = acpi_ds_method_data_get_node (AML_LOCAL_OP, obj_desc->reference.offset,
-					 walk_state, (struct acpi_namespace_node **) &obj_desc->reference.object);
+			status = acpi_ds_method_data_get_node (AML_LOCAL_OP,
+					 obj_desc->reference.offset,
+					 walk_state,
+					 (struct acpi_namespace_node **) &obj_desc->reference.object);
 #endif
 			break;
 
@@ -584,8 +603,10 @@ acpi_ds_init_object_from_op (
 			obj_desc->reference.offset = opcode - AML_ARG_OP;
 
 #ifndef ACPI_NO_METHOD_EXECUTION
-			status = acpi_ds_method_data_get_node (AML_ARG_OP, obj_desc->reference.offset,
-					 walk_state, (struct acpi_namespace_node **) &obj_desc->reference.object);
+			status = acpi_ds_method_data_get_node (AML_ARG_OP,
+					 obj_desc->reference.offset,
+					 walk_state,
+					 (struct acpi_namespace_node **) &obj_desc->reference.object);
 #endif
 			break;
 
diff --git a/drivers/acpi/dispatcher/dsopcode.c b/drivers/acpi/dispatcher/dsopcode.c
--- a/drivers/acpi/dispatcher/dsopcode.c
+++ b/drivers/acpi/dispatcher/dsopcode.c
@@ -54,12 +54,31 @@
 #define _COMPONENT          ACPI_DISPATCHER
 	 ACPI_MODULE_NAME    ("dsopcode")
 
+/* Local prototypes */
 
-/*****************************************************************************
+static acpi_status
+acpi_ds_execute_arguments (
+	struct acpi_namespace_node      *node,
+	struct acpi_namespace_node      *scope_node,
+	u32                             aml_length,
+	u8                              *aml_start);
+
+static acpi_status
+acpi_ds_init_buffer_field (
+	u16                             aml_opcode,
+	union acpi_operand_object       *obj_desc,
+	union acpi_operand_object       *buffer_desc,
+	union acpi_operand_object       *offset_desc,
+	union acpi_operand_object       *length_desc,
+	union acpi_operand_object       *result_desc);
+
+
+/*******************************************************************************
  *
  * FUNCTION:    acpi_ds_execute_arguments
  *
- * PARAMETERS:  Node                - Parent NS node
+ * PARAMETERS:  Node                - Object NS node
+ *              scope_node          - Parent NS node
  *              aml_length          - Length of executable AML
  *              aml_start           - Pointer to the AML
  *
@@ -67,9 +86,9 @@
  *
  * DESCRIPTION: Late (deferred) execution of region or field arguments
  *
- ****************************************************************************/
+ ******************************************************************************/
 
-acpi_status
+static acpi_status
 acpi_ds_execute_arguments (
 	struct acpi_namespace_node      *node,
 	struct acpi_namespace_node      *scope_node,
@@ -162,7 +181,7 @@ acpi_ds_execute_arguments (
 }
 
 
-/*****************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    acpi_ds_get_buffer_field_arguments
  *
@@ -173,7 +192,7 @@ acpi_ds_execute_arguments (
  * DESCRIPTION: Get buffer_field Buffer and Index. This implements the late
  *              evaluation of these field attributes.
  *
- ****************************************************************************/
+ ******************************************************************************/
 
 acpi_status
 acpi_ds_get_buffer_field_arguments (
@@ -208,7 +227,7 @@ acpi_ds_get_buffer_field_arguments (
 }
 
 
-/*****************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    acpi_ds_get_buffer_arguments
  *
@@ -219,7 +238,7 @@ acpi_ds_get_buffer_field_arguments (
  * DESCRIPTION: Get Buffer length and initializer byte list.  This implements
  *              the late evaluation of these attributes.
  *
- ****************************************************************************/
+ ******************************************************************************/
 
 acpi_status
 acpi_ds_get_buffer_arguments (
@@ -255,7 +274,7 @@ acpi_ds_get_buffer_arguments (
 }
 
 
-/*****************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    acpi_ds_get_package_arguments
  *
@@ -266,7 +285,7 @@ acpi_ds_get_buffer_arguments (
  * DESCRIPTION: Get Package length and initializer byte list.  This implements
  *              the late evaluation of these attributes.
  *
- ****************************************************************************/
+ ******************************************************************************/
 
 acpi_status
 acpi_ds_get_package_arguments (
@@ -353,17 +372,17 @@ acpi_ds_get_region_arguments (
 }
 
 
-/*****************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    acpi_ds_initialize_region
  *
- * PARAMETERS:  Op              - A valid region Op object
+ * PARAMETERS:  obj_handle      - Region namespace node
  *
  * RETURN:      Status
  *
  * DESCRIPTION: Front end to ev_initialize_region
  *
- ****************************************************************************/
+ ******************************************************************************/
 
 acpi_status
 acpi_ds_initialize_region (
@@ -382,7 +401,7 @@ acpi_ds_initialize_region (
 }
 
 
-/*****************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    acpi_ds_init_buffer_field
  *
@@ -390,16 +409,16 @@ acpi_ds_initialize_region (
  *              obj_desc        - buffer_field object
  *              buffer_desc     - Host Buffer
  *              offset_desc     - Offset into buffer
- *              Length          - Length of field (CREATE_FIELD_OP only)
- *              Result          - Where to store the result
+ *              length_desc     - Length of field (CREATE_FIELD_OP only)
+ *              result_desc     - Where to store the result
  *
  * RETURN:      Status
  *
  * DESCRIPTION: Perform actual initialization of a buffer field
  *
- ****************************************************************************/
+ ******************************************************************************/
 
-acpi_status
+static acpi_status
 acpi_ds_init_buffer_field (
 	u16                             aml_opcode,
 	union acpi_operand_object       *obj_desc,
@@ -435,8 +454,10 @@ acpi_ds_init_buffer_field (
 	 * after resolution in acpi_ex_resolve_operands().
 	 */
 	if (ACPI_GET_DESCRIPTOR_TYPE (result_desc) != ACPI_DESC_TYPE_NAMED) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "(%s) destination not a NS Node [%s]\n",
-				acpi_ps_get_opcode_name (aml_opcode), acpi_ut_get_descriptor_name (result_desc)));
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+				"(%s) destination not a NS Node [%s]\n",
+				acpi_ps_get_opcode_name (aml_opcode),
+				acpi_ut_get_descriptor_name (result_desc)));
 
 		status = AE_AML_OPERAND_TYPE;
 		goto cleanup;
@@ -452,9 +473,18 @@ acpi_ds_init_buffer_field (
 
 		/* Offset is in bits, count is in bits */
 
+		field_flags = AML_FIELD_ACCESS_BYTE;
 		bit_offset = offset;
 		bit_count  = (u32) length_desc->integer.value;
-		field_flags = AML_FIELD_ACCESS_BYTE;
+
+		/* Must have a valid (>0) bit count */
+
+		if (bit_count == 0) {
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+				"Attempt to create_field of length 0\n"));
+			status = AE_AML_OPERAND_VALUE;
+			goto cleanup;
+		}
 		break;
 
 	case AML_CREATE_BIT_FIELD_OP:
@@ -527,7 +557,8 @@ acpi_ds_init_buffer_field (
 
 	/*
 	 * Initialize areas of the field object that are common to all fields
-	 * For field_flags, use LOCK_RULE = 0 (NO_LOCK), UPDATE_RULE = 0 (UPDATE_PRESERVE)
+	 * For field_flags, use LOCK_RULE = 0 (NO_LOCK),
+	 * UPDATE_RULE = 0 (UPDATE_PRESERVE)
 	 */
 	status = acpi_ex_prep_common_field_object (obj_desc, field_flags, 0,
 			  bit_offset, bit_count);
@@ -539,8 +570,8 @@ acpi_ds_init_buffer_field (
 
 	/* Reference count for buffer_desc inherits obj_desc count */
 
-	buffer_desc->common.reference_count = (u16) (buffer_desc->common.reference_count +
-			  obj_desc->common.reference_count);
+	buffer_desc->common.reference_count = (u16)
+		(buffer_desc->common.reference_count + obj_desc->common.reference_count);
 
 
 cleanup:
@@ -569,7 +600,7 @@ cleanup:
 }
 
 
-/*****************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    acpi_ds_eval_buffer_field_operands
  *
@@ -581,7 +612,7 @@ cleanup:
  * DESCRIPTION: Get buffer_field Buffer and Index
  *              Called from acpi_ds_exec_end_op during buffer_field parse tree walk
  *
- ****************************************************************************/
+ ******************************************************************************/
 
 acpi_status
 acpi_ds_eval_buffer_field_operands (
@@ -656,7 +687,7 @@ acpi_ds_eval_buffer_field_operands (
 }
 
 
-/*****************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    acpi_ds_eval_region_operands
  *
@@ -668,7 +699,7 @@ acpi_ds_eval_buffer_field_operands (
  * DESCRIPTION: Get region address and length
  *              Called from acpi_ds_exec_end_op during op_region parse tree walk
  *
- ****************************************************************************/
+ ******************************************************************************/
 
 acpi_status
 acpi_ds_eval_region_operands (
@@ -686,7 +717,8 @@ acpi_ds_eval_region_operands (
 
 
 	/*
-	 * This is where we evaluate the address and length fields of the op_region declaration
+	 * This is where we evaluate the address and length fields of the
+	 * op_region declaration
 	 */
 	node =  op->common.node;
 
@@ -707,7 +739,8 @@ acpi_ds_eval_region_operands (
 
 	/* Resolve the length and address operands to numbers */
 
-	status = acpi_ex_resolve_operands (op->common.aml_opcode, ACPI_WALK_OPERANDS, walk_state);
+	status = acpi_ex_resolve_operands (op->common.aml_opcode,
+			 ACPI_WALK_OPERANDS, walk_state);
 	if (ACPI_FAILURE (status)) {
 		return_ACPI_STATUS (status);
 	}
@@ -736,7 +769,8 @@ acpi_ds_eval_region_operands (
 	 */
 	operand_desc = walk_state->operands[walk_state->num_operands - 2];
 
-	obj_desc->region.address = (acpi_physical_address) operand_desc->integer.value;
+	obj_desc->region.address = (acpi_physical_address)
+			  operand_desc->integer.value;
 	acpi_ut_remove_reference (operand_desc);
 
 	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "rgn_obj %p Addr %8.8X%8.8X Len %X\n",
@@ -752,7 +786,7 @@ acpi_ds_eval_region_operands (
 }
 
 
-/*****************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    acpi_ds_eval_data_object_operands
  *
@@ -765,7 +799,7 @@ acpi_ds_eval_region_operands (
  * DESCRIPTION: Get the operands and complete the following data object types:
  *              Buffer, Package.
  *
- ****************************************************************************/
+ ******************************************************************************/
 
 acpi_status
 acpi_ds_eval_data_object_operands (
@@ -830,7 +864,7 @@ acpi_ds_eval_data_object_operands (
 
 	if (ACPI_SUCCESS (status)) {
 		/*
-		 * Return the object in the walk_state, unless the parent is a package --
+		 * Return the object in the walk_state, unless the parent is a package -
 		 * in this case, the return object will be stored in the parse tree
 		 * for the package.
 		 */
@@ -988,7 +1022,8 @@ acpi_ds_exec_end_control_op (
 			status = AE_CTRL_PENDING;
 		}
 
-		ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[WHILE_OP] termination! Op=%p\n", op));
+		ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+			"[WHILE_OP] termination! Op=%p\n",op));
 
 		/* Pop this control state and free it */
 
diff --git a/drivers/acpi/dispatcher/dsutils.c b/drivers/acpi/dispatcher/dsutils.c
--- a/drivers/acpi/dispatcher/dsutils.c
+++ b/drivers/acpi/dispatcher/dsutils.c
@@ -100,7 +100,6 @@ acpi_ds_clear_implicit_return (
 
 
 #ifndef ACPI_NO_METHOD_EXECUTION
-
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ds_do_implicit_return
@@ -205,7 +204,7 @@ acpi_ds_is_result_used (
 	 * NOTE: this is optional because the ASL language does not actually
 	 * support this behavior.
 	 */
-	acpi_ds_do_implicit_return (walk_state->result_obj, walk_state, TRUE);
+	(void) acpi_ds_do_implicit_return (walk_state->result_obj, walk_state, TRUE);
 
 	/*
 	 * Now determine if the parent will use the result
@@ -219,8 +218,9 @@ acpi_ds_is_result_used (
 		(op->common.parent->common.aml_opcode == AML_SCOPE_OP)) {
 		/* No parent, the return value cannot possibly be used */
 
-		ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "At Method level, result of [%s] not used\n",
-				acpi_ps_get_opcode_name (op->common.aml_opcode)));
+		ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+			"At Method level, result of [%s] not used\n",
+			acpi_ps_get_opcode_name (op->common.aml_opcode)));
 		return_VALUE (FALSE);
 	}
 
@@ -228,7 +228,8 @@ acpi_ds_is_result_used (
 
 	parent_info = acpi_ps_get_opcode_info (op->common.parent->common.aml_opcode);
 	if (parent_info->class == AML_CLASS_UNKNOWN) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown parent opcode. Op=%p\n", op));
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"Unknown parent opcode. Op=%p\n", op));
 		return_VALUE (FALSE);
 	}
 
@@ -309,17 +310,19 @@ acpi_ds_is_result_used (
 
 
 result_used:
-	ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Result of [%s] used by Parent [%s] Op=%p\n",
-			acpi_ps_get_opcode_name (op->common.aml_opcode),
-			acpi_ps_get_opcode_name (op->common.parent->common.aml_opcode), op));
+	ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+		"Result of [%s] used by Parent [%s] Op=%p\n",
+		acpi_ps_get_opcode_name (op->common.aml_opcode),
+		acpi_ps_get_opcode_name (op->common.parent->common.aml_opcode), op));
 
 	return_VALUE (TRUE);
 
 
 result_not_used:
-	ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Result of [%s] not used by Parent [%s] Op=%p\n",
-			acpi_ps_get_opcode_name (op->common.aml_opcode),
-			acpi_ps_get_opcode_name (op->common.parent->common.aml_opcode), op));
+	ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+		"Result of [%s] not used by Parent [%s] Op=%p\n",
+		acpi_ps_get_opcode_name (op->common.aml_opcode),
+		acpi_ps_get_opcode_name (op->common.parent->common.aml_opcode), op));
 
 	return_VALUE (FALSE);
 }
@@ -522,7 +525,8 @@ acpi_ds_create_operand (
 		if ((walk_state->deferred_node) &&
 			(walk_state->deferred_node->type == ACPI_TYPE_BUFFER_FIELD) &&
 			(arg_index != 0)) {
-			obj_desc = ACPI_CAST_PTR (union acpi_operand_object, walk_state->deferred_node);
+			obj_desc = ACPI_CAST_PTR (
+					 union acpi_operand_object, walk_state->deferred_node);
 			status = AE_OK;
 		}
 		else    /* All other opcodes */ {
@@ -565,7 +569,8 @@ acpi_ds_create_operand (
 					 * indicate this to the interpreter, set the
 					 * object to the root
 					 */
-					obj_desc = ACPI_CAST_PTR (union acpi_operand_object, acpi_gbl_root_node);
+					obj_desc = ACPI_CAST_PTR (
+							 union acpi_operand_object, acpi_gbl_root_node);
 					status = AE_OK;
 				}
 				else {
@@ -612,7 +617,8 @@ acpi_ds_create_operand (
 			 */
 			opcode = AML_ZERO_OP;       /* Has no arguments! */
 
-			ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Null namepath: Arg=%p\n", arg));
+			ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+				"Null namepath: Arg=%p\n", arg));
 		}
 		else {
 			opcode = arg->common.aml_opcode;
@@ -642,7 +648,8 @@ acpi_ds_create_operand (
 				 * Only error is underflow, and this indicates
 				 * a missing or null operand!
 				 */
-				ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Missing or null operand, %s\n",
+				ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+					"Missing or null operand, %s\n",
 					acpi_format_exception (status)));
 				return_ACPI_STATUS (status);
 			}
@@ -657,8 +664,8 @@ acpi_ds_create_operand (
 
 			/* Initialize the new object */
 
-			status = acpi_ds_init_object_from_op (walk_state, arg,
-					 opcode, &obj_desc);
+			status = acpi_ds_init_object_from_op (
+					 walk_state, arg, opcode, &obj_desc);
 			if (ACPI_FAILURE (status)) {
 				acpi_ut_delete_object_desc (obj_desc);
 				return_ACPI_STATUS (status);
diff --git a/drivers/acpi/dispatcher/dswexec.c b/drivers/acpi/dispatcher/dswexec.c
--- a/drivers/acpi/dispatcher/dswexec.c
+++ b/drivers/acpi/dispatcher/dswexec.c
@@ -73,11 +73,13 @@ static ACPI_EXECUTE_OP      acpi_gbl_op_
 			  acpi_ex_opcode_3A_1T_1R,
 			  acpi_ex_opcode_6A_0T_1R};
 
+
 /*****************************************************************************
  *
  * FUNCTION:    acpi_ds_get_predicate_value
  *
  * PARAMETERS:  walk_state      - Current state of the parse tree walk
+ *              result_obj      - if non-zero, pop result from result stack
  *
  * RETURN:      Status
  *
@@ -124,7 +126,8 @@ acpi_ds_get_predicate_value (
 	}
 
 	if (!obj_desc) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No predicate obj_desc=%p State=%p\n",
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"No predicate obj_desc=%p State=%p\n",
 			obj_desc, walk_state));
 
 		return_ACPI_STATUS (AE_AML_NO_OPERAND);
@@ -197,7 +200,7 @@ cleanup:
  * FUNCTION:    acpi_ds_exec_begin_op
  *
  * PARAMETERS:  walk_state      - Current state of the parse tree walk
- *              out_op          - Return op if a new one is created
+ *              out_op          - Where to return op if a new one is created
  *
  * RETURN:      Status
  *
@@ -233,7 +236,8 @@ acpi_ds_exec_begin_op (
 		walk_state->op_info = acpi_ps_get_opcode_info (op->common.aml_opcode);
 
 		if (acpi_ns_opens_scope (walk_state->op_info->object_type)) {
-			ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "(%s) Popping scope for Op %p\n",
+			ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+				"(%s) Popping scope for Op %p\n",
 				acpi_ut_get_type_name (walk_state->op_info->object_type), op));
 
 			status = acpi_ds_scope_stack_pop (walk_state);
@@ -297,11 +301,10 @@ acpi_ds_exec_begin_op (
 
 		if (walk_state->walk_type == ACPI_WALK_METHOD) {
 			/*
-			 * Found a named object declaration during method
-			 * execution;  we must enter this object into the
-			 * namespace.  The created object is temporary and
-			 * will be deleted upon completion of the execution
-			 * of this method.
+			 * Found a named object declaration during method execution;
+			 * we must enter this object into the namespace.  The created
+			 * object is temporary and will be deleted upon completion of
+			 * the execution of this method.
 			 */
 			status = acpi_ds_load2_begin_op (walk_state, NULL);
 		}
@@ -338,8 +341,6 @@ acpi_ds_exec_begin_op (
  * FUNCTION:    acpi_ds_exec_end_op
  *
  * PARAMETERS:  walk_state      - Current state of the parse tree walk
- *              Op              - Op that has been just been completed in the
- *                                walk;  Arguments have now been evaluated.
  *
  * RETURN:      Status
  *
@@ -389,7 +390,7 @@ acpi_ds_exec_end_op (
 	/* Decode the Opcode Class */
 
 	switch (op_class) {
-	case AML_CLASS_ARGUMENT:    /* constants, literals, etc. -- do nothing */
+	case AML_CLASS_ARGUMENT:    /* constants, literals, etc. - do nothing */
 		break;
 
 
@@ -417,12 +418,12 @@ acpi_ds_exec_end_op (
 			/* Resolve all operands */
 
 			status = acpi_ex_resolve_operands (walk_state->opcode,
-					  &(walk_state->operands [walk_state->num_operands -1]),
-					  walk_state);
+					 &(walk_state->operands [walk_state->num_operands -1]),
+					 walk_state);
 			if (ACPI_SUCCESS (status)) {
 				ACPI_DUMP_OPERANDS (ACPI_WALK_OPERANDS, ACPI_IMODE_EXECUTE,
-						  acpi_ps_get_opcode_name (walk_state->opcode),
-						  walk_state->num_operands, "after ex_resolve_operands");
+					acpi_ps_get_opcode_name (walk_state->opcode),
+					walk_state->num_operands, "after ex_resolve_operands");
 			}
 		}
 
@@ -506,7 +507,8 @@ acpi_ds_exec_end_op (
 			if ((op->asl.parent) &&
 			   ((op->asl.parent->asl.aml_opcode == AML_PACKAGE_OP) ||
 				(op->asl.parent->asl.aml_opcode == AML_VAR_PACKAGE_OP))) {
-				ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Method Reference in a Package, Op=%p\n", op));
+				ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+					"Method Reference in a Package, Op=%p\n", op));
 				op->common.node = (struct acpi_namespace_node *) op->asl.value.arg->asl.node->object;
 				acpi_ut_add_reference (op->asl.value.arg->asl.node->object);
 				return_ACPI_STATUS (AE_OK);
@@ -583,13 +585,15 @@ acpi_ds_exec_end_op (
 			case AML_NAME_OP:
 
 				/*
-				 * Put the Node on the object stack (Contains the ACPI Name of
-				 * this object)
+				 * Put the Node on the object stack (Contains the ACPI Name
+				 * of this object)
 				 */
 				walk_state->operands[0] = (void *) op->common.parent->common.node;
 				walk_state->num_operands = 1;
 
-				status = acpi_ds_create_node (walk_state, op->common.parent->common.node, op->common.parent);
+				status = acpi_ds_create_node (walk_state,
+						 op->common.parent->common.node,
+						 op->common.parent);
 				if (ACPI_FAILURE (status)) {
 					break;
 				}
@@ -600,7 +604,7 @@ acpi_ds_exec_end_op (
 			case AML_INT_EVAL_SUBTREE_OP:
 
 				status = acpi_ds_eval_data_object_operands (walk_state, op,
-						  acpi_ns_get_attached_object (op->common.parent->common.node));
+						 acpi_ns_get_attached_object (op->common.parent->common.node));
 				break;
 
 			default:
@@ -609,7 +613,7 @@ acpi_ds_exec_end_op (
 				break;
 			}
 
-			/* Done with this result state (Now that operand stack is built) */
+			/* Done with result state (Now that operand stack is built) */
 
 			status = acpi_ds_result_stack_pop (walk_state);
 			if (ACPI_FAILURE (status)) {
@@ -620,8 +624,7 @@ acpi_ds_exec_end_op (
 			 * If a result object was returned from above, push it on the
 			 * current result stack
 			 */
-			if (ACPI_SUCCESS (status) &&
-				walk_state->result_obj) {
+			if (walk_state->result_obj) {
 				status = acpi_ds_result_push (walk_state->result_obj, walk_state);
 			}
 			break;
@@ -654,7 +657,8 @@ acpi_ds_exec_end_op (
 
 		case AML_TYPE_UNDEFINED:
 
-			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Undefined opcode type Op=%p\n", op));
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+				"Undefined opcode type Op=%p\n", op));
 			return_ACPI_STATUS (AE_NOT_IMPLEMENTED);
 
 
@@ -709,13 +713,14 @@ cleanup:
 		status = acpi_gbl_exception_handler (status,
 				 walk_state->method_node->name.integer, walk_state->opcode,
 				 walk_state->aml_offset, NULL);
-		acpi_ex_enter_interpreter ();
+		(void) acpi_ex_enter_interpreter ();
 	}
 
 	if (walk_state->result_obj) {
 		/* Break to debugger to display result */
 
-		ACPI_DEBUGGER_EXEC (acpi_db_display_result_object (walk_state->result_obj, walk_state));
+		ACPI_DEBUGGER_EXEC (acpi_db_display_result_object (walk_state->result_obj,
+				 walk_state));
 
 		/*
 		 * Delete the result op if and only if:
diff --git a/drivers/acpi/dispatcher/dswload.c b/drivers/acpi/dispatcher/dswload.c
--- a/drivers/acpi/dispatcher/dswload.c
+++ b/drivers/acpi/dispatcher/dswload.c
@@ -79,20 +79,23 @@ acpi_ds_init_callbacks (
 
 	switch (pass_number) {
 	case 1:
-		walk_state->parse_flags       = ACPI_PARSE_LOAD_PASS1 | ACPI_PARSE_DELETE_TREE;
+		walk_state->parse_flags       = ACPI_PARSE_LOAD_PASS1 |
+				   ACPI_PARSE_DELETE_TREE;
 		walk_state->descending_callback = acpi_ds_load1_begin_op;
 		walk_state->ascending_callback = acpi_ds_load1_end_op;
 		break;
 
 	case 2:
-		walk_state->parse_flags       = ACPI_PARSE_LOAD_PASS1 | ACPI_PARSE_DELETE_TREE;
+		walk_state->parse_flags       = ACPI_PARSE_LOAD_PASS1 |
+				   ACPI_PARSE_DELETE_TREE;
 		walk_state->descending_callback = acpi_ds_load2_begin_op;
 		walk_state->ascending_callback = acpi_ds_load2_end_op;
 		break;
 
 	case 3:
 #ifndef ACPI_NO_METHOD_EXECUTION
-		walk_state->parse_flags      |= ACPI_PARSE_EXECUTE  | ACPI_PARSE_DELETE_TREE;
+		walk_state->parse_flags      |= ACPI_PARSE_EXECUTE  |
+				   ACPI_PARSE_DELETE_TREE;
 		walk_state->descending_callback = acpi_ds_exec_begin_op;
 		walk_state->ascending_callback = acpi_ds_exec_end_op;
 #endif
@@ -111,8 +114,7 @@ acpi_ds_init_callbacks (
  * FUNCTION:    acpi_ds_load1_begin_op
  *
  * PARAMETERS:  walk_state      - Current state of the parse tree walk
- *              Op              - Op that has been just been reached in the
- *                                walk;  Arguments have not been evaluated yet.
+ *              out_op          - Where to return op if a new one is created
  *
  * RETURN:      Status
  *
@@ -146,7 +148,8 @@ acpi_ds_load1_begin_op (
 #if 0
 			if ((walk_state->op_info->class == AML_CLASS_EXECUTE) ||
 				(walk_state->op_info->class == AML_CLASS_CONTROL)) {
-				acpi_os_printf ("\n\n***EXECUTABLE OPCODE %s***\n\n", walk_state->op_info->name);
+				acpi_os_printf ("\n\n***EXECUTABLE OPCODE %s***\n\n",
+					walk_state->op_info->name);
 				*out_op = op;
 				return (AE_CTRL_SKIP);
 			}
@@ -191,7 +194,8 @@ acpi_ds_load1_begin_op (
 			 */
 			acpi_dm_add_to_external_list (path);
 			status = acpi_ns_lookup (walk_state->scope_info, path, object_type,
-					   ACPI_IMODE_LOAD_PASS1, ACPI_NS_SEARCH_PARENT, walk_state, &(node));
+					   ACPI_IMODE_LOAD_PASS1, ACPI_NS_SEARCH_PARENT,
+					   walk_state, &(node));
 		}
 #endif
 		if (ACPI_FAILURE (status)) {
@@ -224,10 +228,12 @@ acpi_ds_load1_begin_op (
 			 *  Name (DEB, 0)
 			 *  Scope (DEB) { ... }
 			 *
-			 * Note: silently change the type here.  On the second pass, we will report a warning
+			 * Note: silently change the type here.  On the second pass, we will report
+			 * a warning
 			 */
 
-			ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Type override - [%4.4s] had invalid type (%s) for Scope operator, changed to (Scope)\n",
+			ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+				"Type override - [%4.4s] had invalid type (%s) for Scope operator, changed to (Scope)\n",
 				path, acpi_ut_get_type_name (node->type)));
 
 			node->type = ACPI_TYPE_ANY;
@@ -238,7 +244,8 @@ acpi_ds_load1_begin_op (
 
 			/* All other types are an error */
 
-			ACPI_REPORT_ERROR (("Invalid type (%s) for target of Scope operator [%4.4s] (Cannot override)\n",
+			ACPI_REPORT_ERROR ((
+				"Invalid type (%s) for target of Scope operator [%4.4s] (Cannot override)\n",
 				acpi_ut_get_type_name (node->type), path));
 
 			return (AE_AML_OPERAND_TYPE);
@@ -249,7 +256,8 @@ acpi_ds_load1_begin_op (
 	default:
 
 		/*
-		 * For all other named opcodes, we will enter the name into the namespace.
+		 * For all other named opcodes, we will enter the name into
+		 * the namespace.
 		 *
 		 * Setup the search flags.
 		 * Since we are entering a name into the namespace, we do not want to
@@ -279,14 +287,16 @@ acpi_ds_load1_begin_op (
 					acpi_ut_get_type_name (object_type)));
 		}
 		else {
-			ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[%s] Both Find or Create allowed\n",
+			ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+				"[%s] Both Find or Create allowed\n",
 					acpi_ut_get_type_name (object_type)));
 		}
 
 		/*
 		 * Enter the named type into the internal namespace.  We enter the name
-		 * as we go downward in the parse tree.  Any necessary subobjects that involve
-		 * arguments to the opcode must be created as we go back up the parse tree later.
+		 * as we go downward in the parse tree.  Any necessary subobjects that
+		 * involve arguments to the opcode must be created as we go back up the
+		 * parse tree later.
 		 */
 		status = acpi_ns_lookup (walk_state->scope_info, path, object_type,
 				  ACPI_IMODE_LOAD_PASS1, flags, walk_state, &(node));
@@ -335,8 +345,6 @@ acpi_ds_load1_begin_op (
  * FUNCTION:    acpi_ds_load1_end_op
  *
  * PARAMETERS:  walk_state      - Current state of the parse tree walk
- *              Op              - Op that has been just been completed in the
- *                                walk;  Arguments have now been evaluated.
  *
  * RETURN:      Status
  *
@@ -383,7 +391,9 @@ acpi_ds_load1_end_op (
 
 	if (op->common.aml_opcode == AML_REGION_OP) {
 		status = acpi_ex_create_region (op->named.data, op->named.length,
-				   (acpi_adr_space_type) ((op->common.value.arg)->common.value.integer), walk_state);
+				   (acpi_adr_space_type)
+						 ((op->common.value.arg)->common.value.integer),
+						 walk_state);
 		if (ACPI_FAILURE (status)) {
 			return (status);
 		}
@@ -394,7 +404,8 @@ acpi_ds_load1_end_op (
 		/* For Name opcode, get the object type from the argument */
 
 		if (op->common.value.arg) {
-			object_type = (acpi_ps_get_opcode_info ((op->common.value.arg)->common.aml_opcode))->object_type;
+			object_type = (acpi_ps_get_opcode_info (
+				(op->common.value.arg)->common.aml_opcode))->object_type;
 			op->common.node->type = (u8) object_type;
 		}
 	}
@@ -448,8 +459,7 @@ acpi_ds_load1_end_op (
  * FUNCTION:    acpi_ds_load2_begin_op
  *
  * PARAMETERS:  walk_state      - Current state of the parse tree walk
- *              Op              - Op that has been just been reached in the
- *                                walk;  Arguments have not been evaluated yet.
+ *              out_op          - Wher to return op if a new one is created
  *
  * RETURN:      Status
  *
@@ -478,14 +488,14 @@ acpi_ds_load2_begin_op (
 	if (op) {
 		/* We only care about Namespace opcodes here */
 
-		if ((!(walk_state->op_info->flags & AML_NSOPCODE) && (walk_state->opcode != AML_INT_NAMEPATH_OP)) ||
+		if ((!(walk_state->op_info->flags & AML_NSOPCODE) &&
+			  (walk_state->opcode != AML_INT_NAMEPATH_OP)) ||
 			(!(walk_state->op_info->flags & AML_NAMED))) {
 			return_ACPI_STATUS (AE_OK);
 		}
 
-		/*
-		 * Get the name we are going to enter or lookup in the namespace
-		 */
+		/* Get the name we are going to enter or lookup in the namespace */
+
 		if (walk_state->opcode == AML_INT_NAMEPATH_OP) {
 			/* For Namepath op, get the path string */
 
@@ -528,21 +538,25 @@ acpi_ds_load2_begin_op (
 	case AML_INT_NAMEPATH_OP:
 
 		/*
-		 * The name_path is an object reference to an existing object. Don't enter the
-		 * name into the namespace, but look it up for use later
+		 * The name_path is an object reference to an existing object.
+		 * Don't enter the name into the namespace, but look it up
+		 * for use later.
 		 */
 		status = acpi_ns_lookup (walk_state->scope_info, buffer_ptr, object_type,
-				  ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT, walk_state, &(node));
+				  ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT,
+				  walk_state, &(node));
 		break;
 
 	case AML_SCOPE_OP:
 
 		/*
-		 * The Path is an object reference to an existing object.  Don't enter the
-		 * name into the namespace, but look it up for use later
+		 * The Path is an object reference to an existing object.
+		 * Don't enter the name into the namespace, but look it up
+		 * for use later.
 		 */
 		status = acpi_ns_lookup (walk_state->scope_info, buffer_ptr, object_type,
-				  ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT, walk_state, &(node));
+				  ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT,
+				  walk_state, &(node));
 		if (ACPI_FAILURE (status)) {
 #ifdef _ACPI_ASL_COMPILER
 			if (status == AE_NOT_FOUND) {
@@ -582,7 +596,8 @@ acpi_ds_load2_begin_op (
 			 *  Scope (DEB) { ... }
 			 */
 
-			ACPI_REPORT_WARNING (("Type override - [%4.4s] had invalid type (%s) for Scope operator, changed to (Scope)\n",
+			ACPI_REPORT_WARNING ((
+				"Type override - [%4.4s] had invalid type (%s) for Scope operator, changed to (Scope)\n",
 				buffer_ptr, acpi_ut_get_type_name (node->type)));
 
 			node->type = ACPI_TYPE_ANY;
@@ -593,7 +608,8 @@ acpi_ds_load2_begin_op (
 
 			/* All other types are an error */
 
-			ACPI_REPORT_ERROR (("Invalid type (%s) for target of Scope operator [%4.4s]\n",
+			ACPI_REPORT_ERROR ((
+				"Invalid type (%s) for target of Scope operator [%4.4s]\n",
 				acpi_ut_get_type_name (node->type), buffer_ptr));
 
 			return (AE_AML_OPERAND_TYPE);
@@ -621,8 +637,9 @@ acpi_ds_load2_begin_op (
 
 		/*
 		 * Enter the named type into the internal namespace.  We enter the name
-		 * as we go downward in the parse tree.  Any necessary subobjects that involve
-		 * arguments to the opcode must be created as we go back up the parse tree later.
+		 * as we go downward in the parse tree.  Any necessary subobjects that
+		 * involve arguments to the opcode must be created as we go back up the
+		 * parse tree later.
 		 *
 		 * Note: Name may already exist if we are executing a deferred opcode.
 		 */
@@ -635,7 +652,8 @@ acpi_ds_load2_begin_op (
 		}
 
 		status = acpi_ns_lookup (walk_state->scope_info, buffer_ptr, object_type,
-				  ACPI_IMODE_EXECUTE, ACPI_NS_NO_UPSEARCH, walk_state, &(node));
+				  ACPI_IMODE_EXECUTE, ACPI_NS_NO_UPSEARCH,
+				  walk_state, &(node));
 		break;
 	}
 
@@ -678,8 +696,6 @@ acpi_ds_load2_begin_op (
  * FUNCTION:    acpi_ds_load2_end_op
  *
  * PARAMETERS:  walk_state      - Current state of the parse tree walk
- *              Op              - Op that has been just been completed in the
- *                                walk;  Arguments have now been evaluated.
  *
  * RETURN:      Status
  *
@@ -738,7 +754,8 @@ acpi_ds_load2_end_op (
 
 	/* Pop the scope stack */
 
-	if (acpi_ns_opens_scope (object_type) && (op->common.aml_opcode != AML_INT_METHODCALL_OP)) {
+	if (acpi_ns_opens_scope (object_type) &&
+	   (op->common.aml_opcode != AML_INT_METHODCALL_OP)) {
 		ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "(%s) Popping scope for Op %p\n",
 			acpi_ut_get_type_name (object_type), op));
 
@@ -803,7 +820,7 @@ acpi_ds_load2_end_op (
 		case AML_INDEX_FIELD_OP:
 
 			status = acpi_ds_create_index_field (op, (acpi_handle) arg->common.node,
-					   walk_state);
+					 walk_state);
 			break;
 
 		case AML_BANK_FIELD_OP:
@@ -884,14 +901,16 @@ acpi_ds_load2_end_op (
 #ifndef ACPI_NO_METHOD_EXECUTION
 		case AML_REGION_OP:
 			/*
-			 * The op_region is not fully parsed at this time. Only valid argument is the space_id.
-			 * (We must save the address of the AML of the address and length operands)
+			 * The op_region is not fully parsed at this time. Only valid
+			 * argument is the space_id. (We must save the address of the
+			 * AML of the address and length operands)
 			 */
 			/*
 			 * If we have a valid region, initialize it
 			 * Namespace is NOT locked at this point.
 			 */
-			status = acpi_ev_initialize_region (acpi_ns_get_attached_object (node), FALSE);
+			status = acpi_ev_initialize_region (acpi_ns_get_attached_object (node),
+					 FALSE);
 			if (ACPI_FAILURE (status)) {
 				/*
 				 *  If AE_NOT_EXIST is returned, it is not fatal
@@ -942,15 +961,16 @@ acpi_ds_load2_end_op (
 		if (ACPI_SUCCESS (status)) {
 			/*
 			 * Make sure that what we found is indeed a method
-			 * We didn't search for a method on purpose, to see if the name would resolve
+			 * We didn't search for a method on purpose, to see if the name
+			 * would resolve
 			 */
 			if (new_node->type != ACPI_TYPE_METHOD) {
 				status = AE_AML_OPERAND_TYPE;
 			}
 
-			/* We could put the returned object (Node) on the object stack for later, but
-			 * for now, we will put it in the "op" object that the parser uses, so we
-			 * can get it again at the end of this scope
+			/* We could put the returned object (Node) on the object stack for
+			 * later, but for now, we will put it in the "op" object that the
+			 * parser uses, so we can get it again at the end of this scope
 			 */
 			op->common.node = new_node;
 		}
diff --git a/drivers/acpi/dispatcher/dswscope.c b/drivers/acpi/dispatcher/dswscope.c
--- a/drivers/acpi/dispatcher/dswscope.c
+++ b/drivers/acpi/dispatcher/dswscope.c
@@ -50,14 +50,13 @@
 	 ACPI_MODULE_NAME    ("dswscope")
 
 
-#define STACK_POP(head) head
-
-
 /****************************************************************************
  *
  * FUNCTION:    acpi_ds_scope_stack_clear
  *
- * PARAMETERS:  None
+ * PARAMETERS:  walk_state      - Current state
+ *
+ * RETURN:      None
  *
  * DESCRIPTION: Pop (and free) everything on the scope stack except the
  *              root scope object (which remains at the stack top.)
@@ -80,7 +79,8 @@ acpi_ds_scope_stack_clear (
 		walk_state->scope_info = scope_info->scope.next;
 
 		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
-			"Popped object type (%s)\n", acpi_ut_get_type_name (scope_info->common.value)));
+			"Popped object type (%s)\n",
+			acpi_ut_get_type_name (scope_info->common.value)));
 		acpi_ut_delete_generic_state (scope_info);
 	}
 }
@@ -90,8 +90,11 @@ acpi_ds_scope_stack_clear (
  *
  * FUNCTION:    acpi_ds_scope_stack_push
  *
- * PARAMETERS:  *Node,              - Name to be made current
- *              Type,               - Type of frame being pushed
+ * PARAMETERS:  Node            - Name to be made current
+ *              Type            - Type of frame being pushed
+ *              walk_state      - Current state
+ *
+ * RETURN:      Status
  *
  * DESCRIPTION: Push the current scope on the scope stack, and make the
  *              passed Node current.
@@ -121,7 +124,8 @@ acpi_ds_scope_stack_push (
 	/* Make sure object type is valid */
 
 	if (!acpi_ut_valid_object_type (type)) {
-		ACPI_REPORT_WARNING (("ds_scope_stack_push: Invalid object type: 0x%X\n", type));
+		ACPI_REPORT_WARNING ((
+			"ds_scope_stack_push: Invalid object type: 0x%X\n", type));
 	}
 
 	/* Allocate a new scope object */
@@ -170,16 +174,11 @@ acpi_ds_scope_stack_push (
  *
  * FUNCTION:    acpi_ds_scope_stack_pop
  *
- * PARAMETERS:  Type                - The type of frame to be found
+ * PARAMETERS:  walk_state      - Current state
  *
- * DESCRIPTION: Pop the scope stack until a frame of the requested type
- *              is found.
+ * RETURN:      Status
  *
- * RETURN:      Count of frames popped.  If no frame of the requested type
- *              was found, the count is returned as a negative number and
- *              the scope stack is emptied (which sets the current scope
- *              to the root).  If the scope stack was empty at entry, the
- *              function is a no-op and returns 0.
+ * DESCRIPTION: Pop the scope stack once.
  *
  ***************************************************************************/
 
diff --git a/drivers/acpi/dispatcher/dswstate.c b/drivers/acpi/dispatcher/dswstate.c
--- a/drivers/acpi/dispatcher/dswstate.c
+++ b/drivers/acpi/dispatcher/dswstate.c
@@ -50,67 +50,31 @@
 #define _COMPONENT          ACPI_DISPATCHER
 	 ACPI_MODULE_NAME    ("dswstate")
 
+/* Local prototypes */
 
-#ifdef ACPI_FUTURE_USAGE
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_ds_result_insert
- *
- * PARAMETERS:  Object              - Object to push
- *              Index               - Where to insert the object
- *              walk_state          - Current Walk state
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Insert an object onto this walk's result stack
- *
- ******************************************************************************/
-
+#ifdef ACPI_OBSOLETE_FUNCTIONS
 acpi_status
 acpi_ds_result_insert (
 	void                            *object,
 	u32                             index,
-	struct acpi_walk_state          *walk_state)
-{
-	union acpi_generic_state        *state;
-
+	struct acpi_walk_state          *walk_state);
 
-	ACPI_FUNCTION_NAME ("ds_result_insert");
-
-
-	state = walk_state->results;
-	if (!state) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No result object pushed! State=%p\n",
-			walk_state));
-		return (AE_NOT_EXIST);
-	}
-
-	if (index >= ACPI_OBJ_NUM_OPERANDS) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
-			"Index out of range: %X Obj=%p State=%p Num=%X\n",
-			index, object, walk_state, state->results.num_results));
-		return (AE_BAD_PARAMETER);
-	}
-
-	if (!object) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
-			"Null Object! Index=%X Obj=%p State=%p Num=%X\n",
-			index, object, walk_state, state->results.num_results));
-		return (AE_BAD_PARAMETER);
-	}
-
-	state->results.obj_desc [index] = object;
-	state->results.num_results++;
+acpi_status
+acpi_ds_obj_stack_delete_all (
+	struct acpi_walk_state          *walk_state);
 
-	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
-		"Obj=%p [%s] State=%p Num=%X Cur=%X\n",
-		object, object ? acpi_ut_get_object_type_name ((union acpi_operand_object *) object) : "NULL",
-		walk_state, state->results.num_results, walk_state->current_result));
+acpi_status
+acpi_ds_obj_stack_pop_object (
+	union acpi_operand_object       **object,
+	struct acpi_walk_state          *walk_state);
 
-	return (AE_OK);
-}
+void *
+acpi_ds_obj_stack_get_value (
+	u32                             index,
+	struct acpi_walk_state          *walk_state);
+#endif
 
+#ifdef ACPI_FUTURE_USAGE
 
 /*******************************************************************************
  *
@@ -178,7 +142,6 @@ acpi_ds_result_remove (
 
 #endif  /*  ACPI_FUTURE_USAGE  */
 
-
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ds_result_pop
@@ -227,15 +190,18 @@ acpi_ds_result_pop (
 			*object = state->results.obj_desc [index -1];
 			state->results.obj_desc [index -1] = NULL;
 
-			ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p [%s] Index=%X State=%p Num=%X\n",
-				*object, (*object) ? acpi_ut_get_object_type_name (*object) : "NULL",
+			ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+				"Obj=%p [%s] Index=%X State=%p Num=%X\n",
+				*object,
+				(*object) ? acpi_ut_get_object_type_name (*object) : "NULL",
 				(u32) index -1, walk_state, state->results.num_results));
 
 			return (AE_OK);
 		}
 	}
 
-	ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No result objects! State=%p\n", walk_state));
+	ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+		"No result objects! State=%p\n", walk_state));
 	return (AE_AML_NO_RETURN_VALUE);
 }
 
@@ -274,7 +240,8 @@ acpi_ds_result_pop_from_bottom (
 	}
 
 	if (!state->results.num_results) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No result objects! State=%p\n", walk_state));
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No result objects! State=%p\n",
+			walk_state));
 		return (AE_AML_NO_RETURN_VALUE);
 	}
 
@@ -293,7 +260,8 @@ acpi_ds_result_pop_from_bottom (
 	/* Check for a valid result object */
 
 	if (!*object) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Null operand! State=%p #Ops=%X, Index=%X\n",
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"Null operand! State=%p #Ops=%X, Index=%X\n",
 			walk_state, state->results.num_results, (u32) index));
 		return (AE_AML_NO_RETURN_VALUE);
 	}
@@ -344,7 +312,8 @@ acpi_ds_result_push (
 	}
 
 	if (!object) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Null Object! Obj=%p State=%p Num=%X\n",
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"Null Object! Obj=%p State=%p Num=%X\n",
 			object, walk_state, state->results.num_results));
 		return (AE_BAD_PARAMETER);
 	}
@@ -439,43 +408,6 @@ acpi_ds_result_stack_pop (
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_ds_obj_stack_delete_all
- *
- * PARAMETERS:  walk_state          - Current Walk state
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Clear the object stack by deleting all objects that are on it.
- *              Should be used with great care, if at all!
- *
- ******************************************************************************/
-#ifdef ACPI_FUTURE_USAGE
-acpi_status
-acpi_ds_obj_stack_delete_all (
-	struct acpi_walk_state          *walk_state)
-{
-	u32                             i;
-
-
-	ACPI_FUNCTION_TRACE_PTR ("ds_obj_stack_delete_all", walk_state);
-
-
-	/* The stack size is configurable, but fixed */
-
-	for (i = 0; i < ACPI_OBJ_NUM_OPERANDS; i++) {
-		if (walk_state->operands[i]) {
-			acpi_ut_remove_reference (walk_state->operands[i]);
-			walk_state->operands[i] = NULL;
-		}
-	}
-
-	return_ACPI_STATUS (AE_OK);
-}
-#endif  /*  ACPI_FUTURE_USAGE  */
-
-
-/*******************************************************************************
- *
  * FUNCTION:    acpi_ds_obj_stack_push
  *
  * PARAMETERS:  Object              - Object to push
@@ -517,67 +449,6 @@ acpi_ds_obj_stack_push (
 }
 
 
-#if 0
-/*******************************************************************************
- *
- * FUNCTION:    acpi_ds_obj_stack_pop_object
- *
- * PARAMETERS:  pop_count           - Number of objects/entries to pop
- *              walk_state          - Current Walk state
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Pop this walk's object stack.  Objects on the stack are NOT
- *              deleted by this routine.
- *
- ******************************************************************************/
-
-acpi_status
-acpi_ds_obj_stack_pop_object (
-	union acpi_operand_object       **object,
-	struct acpi_walk_state          *walk_state)
-{
-	ACPI_FUNCTION_NAME ("ds_obj_stack_pop_object");
-
-
-	/* Check for stack underflow */
-
-	if (walk_state->num_operands == 0) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
-			"Missing operand/stack empty! State=%p #Ops=%X\n",
-			walk_state, walk_state->num_operands));
-		*object = NULL;
-		return (AE_AML_NO_OPERAND);
-	}
-
-	/* Pop the stack */
-
-	walk_state->num_operands--;
-
-	/* Check for a valid operand */
-
-	if (!walk_state->operands [walk_state->num_operands]) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
-			"Null operand! State=%p #Ops=%X\n",
-			walk_state, walk_state->num_operands));
-		*object = NULL;
-		return (AE_AML_NO_OPERAND);
-	}
-
-	/* Get operand and set stack entry to null */
-
-	*object = walk_state->operands [walk_state->num_operands];
-	walk_state->operands [walk_state->num_operands] = NULL;
-
-	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p [%s] State=%p #Ops=%X\n",
-			  *object, acpi_ut_get_object_type_name (*object),
-			  walk_state, walk_state->num_operands));
-
-	return (AE_OK);
-}
-#endif
-
-
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ds_obj_stack_pop
@@ -680,48 +551,6 @@ acpi_ds_obj_stack_pop_and_delete (
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_ds_obj_stack_get_value
- *
- * PARAMETERS:  Index               - Stack index whose value is desired.  Based
- *                                    on the top of the stack (index=0 == top)
- *              walk_state          - Current Walk state
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Retrieve an object from this walk's object stack.  Index must
- *              be within the range of the current stack pointer.
- *
- ******************************************************************************/
-#ifdef ACPI_FUTURE_USAGE
-void *
-acpi_ds_obj_stack_get_value (
-	u32                             index,
-	struct acpi_walk_state          *walk_state)
-{
-
-	ACPI_FUNCTION_TRACE_PTR ("ds_obj_stack_get_value", walk_state);
-
-
-	/* Can't do it if the stack is empty */
-
-	if (walk_state->num_operands == 0) {
-		return_PTR (NULL);
-	}
-
-	/* or if the index is past the top of the stack */
-
-	if (index > (walk_state->num_operands - (u32) 1)) {
-		return_PTR (NULL);
-	}
-
-	return_PTR (walk_state->operands[(acpi_native_uint)(walk_state->num_operands - 1) -
-			  index]);
-}
-#endif  /*  ACPI_FUTURE_USAGE  */
-
-
-/*******************************************************************************
- *
  * FUNCTION:    acpi_ds_get_current_walk_state
  *
  * PARAMETERS:  Thread          - Get current active state for this Thread
@@ -757,11 +586,11 @@ acpi_ds_get_current_walk_state (
  * FUNCTION:    acpi_ds_push_walk_state
  *
  * PARAMETERS:  walk_state      - State to push
- *              walk_list       - The list that owns the walk stack
+ *              Thread          - Thread state object
  *
  * RETURN:      None
  *
- * DESCRIPTION: Place the walk_state at the head of the state list.
+ * DESCRIPTION: Place the Thread state at the head of the state list.
  *
  ******************************************************************************/
 
@@ -784,9 +613,9 @@ acpi_ds_push_walk_state (
  *
  * FUNCTION:    acpi_ds_pop_walk_state
  *
- * PARAMETERS:  walk_list       - The list that owns the walk stack
+ * PARAMETERS:  Thread      - Current thread state
  *
- * RETURN:      A walk_state object popped from the stack
+ * RETURN:      A walk_state object popped from the thread's stack
  *
  * DESCRIPTION: Remove and return the walkstate object that is at the head of
  *              the walk stack for the given walk list.  NULL indicates that
@@ -814,7 +643,7 @@ acpi_ds_pop_walk_state (
 		/*
 		 * Don't clear the NEXT field, this serves as an indicator
 		 * that there is a parent WALK STATE
-		 *     NO: walk_state->Next = NULL;
+		 * Do Not: walk_state->Next = NULL;
 		 */
 	}
 
@@ -826,7 +655,9 @@ acpi_ds_pop_walk_state (
  *
  * FUNCTION:    acpi_ds_create_walk_state
  *
- * PARAMETERS:  Origin          - Starting point for this walk
+ * PARAMETERS:  owner_id        - ID for object creation
+ *              Origin          - Starting point for this walk
+ *              mth_desc        - Method object
  *              Thread          - Current thread state
  *
  * RETURN:      Pointer to the new walk state.
@@ -896,8 +727,7 @@ acpi_ds_create_walk_state (
  *              method_node     - Control method NS node, if any
  *              aml_start       - Start of AML
  *              aml_length      - Length of AML
- *              Params          - Method args, if any
- *              return_obj_desc - Where to store a return object, if any
+ *              Info            - Method info block (params, etc.)
  *              pass_number     - 1, 2, or 3
  *
  * RETURN:      Status
@@ -931,7 +761,7 @@ acpi_ds_init_aml_walk (
 
 	/* The next_op of the next_walk will be the beginning of the method */
 
-	walk_state->next_op             = NULL;
+	walk_state->next_op = NULL;
 
 	if (info) {
 		if (info->parameter_type == ACPI_PARAM_GPE) {
@@ -939,8 +769,8 @@ acpi_ds_init_aml_walk (
 					   info->parameters);
 		}
 		else {
-			walk_state->params              = info->parameters;
-			walk_state->caller_return_desc  = &info->return_object;
+			walk_state->params          = info->parameters;
+			walk_state->caller_return_desc = &info->return_object;
 		}
 	}
 
@@ -964,7 +794,8 @@ acpi_ds_init_aml_walk (
 
 		/* Init the method arguments */
 
-		status = acpi_ds_method_data_init_args (walk_state->params, ACPI_METHOD_NUM_ARGS, walk_state);
+		status = acpi_ds_method_data_init_args (walk_state->params,
+				 ACPI_METHOD_NUM_ARGS, walk_state);
 		if (ACPI_FAILURE (status)) {
 			return_ACPI_STATUS (status);
 		}
@@ -1031,12 +862,14 @@ acpi_ds_delete_walk_state (
 	}
 
 	if (walk_state->data_type != ACPI_DESC_TYPE_WALK) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%p is not a valid walk state\n", walk_state));
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%p is not a valid walk state\n",
+			walk_state));
 		return;
 	}
 
 	if (walk_state->parser_state.scope) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%p walk still has a scope list\n", walk_state));
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%p walk still has a scope list\n",
+			walk_state));
 	}
 
 	/* Always must free any linked control states */
@@ -1078,7 +911,7 @@ acpi_ds_delete_walk_state (
  *
  * PARAMETERS:  None
  *
- * RETURN:      Status
+ * RETURN:      None
  *
  * DESCRIPTION: Purge the global state object cache.  Used during subsystem
  *              termination.
@@ -1098,3 +931,200 @@ acpi_ds_delete_walk_state_cache (
 #endif
 
 
+#ifdef ACPI_OBSOLETE_FUNCTIONS
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ds_result_insert
+ *
+ * PARAMETERS:  Object              - Object to push
+ *              Index               - Where to insert the object
+ *              walk_state          - Current Walk state
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Insert an object onto this walk's result stack
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ds_result_insert (
+	void                            *object,
+	u32                             index,
+	struct acpi_walk_state          *walk_state)
+{
+	union acpi_generic_state        *state;
+
+
+	ACPI_FUNCTION_NAME ("ds_result_insert");
+
+
+	state = walk_state->results;
+	if (!state) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No result object pushed! State=%p\n",
+			walk_state));
+		return (AE_NOT_EXIST);
+	}
+
+	if (index >= ACPI_OBJ_NUM_OPERANDS) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"Index out of range: %X Obj=%p State=%p Num=%X\n",
+			index, object, walk_state, state->results.num_results));
+		return (AE_BAD_PARAMETER);
+	}
+
+	if (!object) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"Null Object! Index=%X Obj=%p State=%p Num=%X\n",
+			index, object, walk_state, state->results.num_results));
+		return (AE_BAD_PARAMETER);
+	}
+
+	state->results.obj_desc [index] = object;
+	state->results.num_results++;
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+		"Obj=%p [%s] State=%p Num=%X Cur=%X\n",
+		object, object ? acpi_ut_get_object_type_name ((union acpi_operand_object *) object) : "NULL",
+		walk_state, state->results.num_results, walk_state->current_result));
+
+	return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ds_obj_stack_delete_all
+ *
+ * PARAMETERS:  walk_state          - Current Walk state
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Clear the object stack by deleting all objects that are on it.
+ *              Should be used with great care, if at all!
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ds_obj_stack_delete_all (
+	struct acpi_walk_state          *walk_state)
+{
+	u32                             i;
+
+
+	ACPI_FUNCTION_TRACE_PTR ("ds_obj_stack_delete_all", walk_state);
+
+
+	/* The stack size is configurable, but fixed */
+
+	for (i = 0; i < ACPI_OBJ_NUM_OPERANDS; i++) {
+		if (walk_state->operands[i]) {
+			acpi_ut_remove_reference (walk_state->operands[i]);
+			walk_state->operands[i] = NULL;
+		}
+	}
+
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ds_obj_stack_pop_object
+ *
+ * PARAMETERS:  Object              - Where to return the popped object
+ *              walk_state          - Current Walk state
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Pop this walk's object stack.  Objects on the stack are NOT
+ *              deleted by this routine.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ds_obj_stack_pop_object (
+	union acpi_operand_object       **object,
+	struct acpi_walk_state          *walk_state)
+{
+	ACPI_FUNCTION_NAME ("ds_obj_stack_pop_object");
+
+
+	/* Check for stack underflow */
+
+	if (walk_state->num_operands == 0) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"Missing operand/stack empty! State=%p #Ops=%X\n",
+			walk_state, walk_state->num_operands));
+		*object = NULL;
+		return (AE_AML_NO_OPERAND);
+	}
+
+	/* Pop the stack */
+
+	walk_state->num_operands--;
+
+	/* Check for a valid operand */
+
+	if (!walk_state->operands [walk_state->num_operands]) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"Null operand! State=%p #Ops=%X\n",
+			walk_state, walk_state->num_operands));
+		*object = NULL;
+		return (AE_AML_NO_OPERAND);
+	}
+
+	/* Get operand and set stack entry to null */
+
+	*object = walk_state->operands [walk_state->num_operands];
+	walk_state->operands [walk_state->num_operands] = NULL;
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p [%s] State=%p #Ops=%X\n",
+			  *object, acpi_ut_get_object_type_name (*object),
+			  walk_state, walk_state->num_operands));
+
+	return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ds_obj_stack_get_value
+ *
+ * PARAMETERS:  Index               - Stack index whose value is desired.  Based
+ *                                    on the top of the stack (index=0 == top)
+ *              walk_state          - Current Walk state
+ *
+ * RETURN:      Pointer to the requested operand
+ *
+ * DESCRIPTION: Retrieve an object from this walk's operand stack.  Index must
+ *              be within the range of the current stack pointer.
+ *
+ ******************************************************************************/
+
+void *
+acpi_ds_obj_stack_get_value (
+	u32                             index,
+	struct acpi_walk_state          *walk_state)
+{
+
+	ACPI_FUNCTION_TRACE_PTR ("ds_obj_stack_get_value", walk_state);
+
+
+	/* Can't do it if the stack is empty */
+
+	if (walk_state->num_operands == 0) {
+		return_PTR (NULL);
+	}
+
+	/* or if the index is past the top of the stack */
+
+	if (index > (walk_state->num_operands - (u32) 1)) {
+		return_PTR (NULL);
+	}
+
+	return_PTR (walk_state->operands[(acpi_native_uint)(walk_state->num_operands - 1) -
+			  index]);
+}
+#endif
+
+
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -31,6 +31,7 @@
 #include <linux/delay.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
+#include <linux/interrupt.h>
 #include <asm/io.h>
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>
@@ -49,60 +50,149 @@ ACPI_MODULE_NAME		("acpi_ec")
 
 #define ACPI_EC_FLAG_OBF	0x01	/* Output buffer full */
 #define ACPI_EC_FLAG_IBF	0x02	/* Input buffer full */
+#define ACPI_EC_FLAG_BURST	0x10	/* burst mode */
 #define ACPI_EC_FLAG_SCI	0x20	/* EC-SCI occurred */
 
 #define ACPI_EC_EVENT_OBF	0x01	/* Output buffer full */
 #define ACPI_EC_EVENT_IBE	0x02	/* Input buffer empty */
 
-#define ACPI_EC_UDELAY		100	/* Poll @ 100us increments */
-#define ACPI_EC_UDELAY_COUNT	1000	/* Wait 10ms max. during EC ops */
+#define ACPI_EC_DELAY		50	/* Wait 50ms max. during EC ops */
 #define ACPI_EC_UDELAY_GLK	1000	/* Wait 1ms max. to get global lock */
 
+#define ACPI_EC_UDELAY         100     /* Poll @ 100us increments */
+#define ACPI_EC_UDELAY_COUNT   1000    /* Wait 10ms max. during EC ops */
+
 #define ACPI_EC_COMMAND_READ	0x80
 #define ACPI_EC_COMMAND_WRITE	0x81
+#define ACPI_EC_BURST_ENABLE	0x82
+#define ACPI_EC_BURST_DISABLE	0x83
 #define ACPI_EC_COMMAND_QUERY	0x84
 
-static int acpi_ec_add (struct acpi_device *device);
+#define EC_POLLING		0xFF
+#define EC_BURST		0x00
+
+
 static int acpi_ec_remove (struct acpi_device *device, int type);
 static int acpi_ec_start (struct acpi_device *device);
 static int acpi_ec_stop (struct acpi_device *device, int type);
+static int acpi_ec_burst_add ( struct acpi_device *device);
+static int acpi_ec_polling_add ( struct acpi_device	*device);
 
 static struct acpi_driver acpi_ec_driver = {
 	.name =		ACPI_EC_DRIVER_NAME,
 	.class =	ACPI_EC_CLASS,
 	.ids =		ACPI_EC_HID,
 	.ops =		{
-				.add =		acpi_ec_add,
+				.add =		acpi_ec_polling_add,
 				.remove =	acpi_ec_remove,
 				.start =	acpi_ec_start,
 				.stop =		acpi_ec_stop,
 			},
 };
-
-struct acpi_ec {
-	acpi_handle			handle;
-	unsigned long			uid;
-	unsigned long			gpe_bit;
-	struct acpi_generic_address	status_addr;
-	struct acpi_generic_address	command_addr;
-	struct acpi_generic_address	data_addr;
-	unsigned long			global_lock;
-	spinlock_t			lock;
+union acpi_ec {
+	struct {
+		u32				mode;
+		acpi_handle			handle;
+		unsigned long			uid;
+		unsigned long			gpe_bit;
+		struct acpi_generic_address	status_addr;
+		struct acpi_generic_address	command_addr;
+		struct acpi_generic_address	data_addr;
+		unsigned long			global_lock;
+	} common;
+
+	struct {
+		u32				mode;
+		acpi_handle			handle;
+		unsigned long			uid;
+		unsigned long			gpe_bit;
+		struct acpi_generic_address	status_addr;
+		struct acpi_generic_address	command_addr;
+		struct acpi_generic_address	data_addr;
+		unsigned long			global_lock;
+		unsigned int			expect_event;
+		atomic_t			leaving_burst; /* 0 : No, 1 : Yes, 2: abort*/
+		atomic_t			pending_gpe;
+		struct semaphore		sem;
+		wait_queue_head_t		wait;
+	}burst;
+
+	struct {
+		u32				mode;
+		acpi_handle			handle;
+		unsigned long			uid;
+		unsigned long			gpe_bit;
+		struct acpi_generic_address	status_addr;
+		struct acpi_generic_address	command_addr;
+		struct acpi_generic_address	data_addr;
+		unsigned long			global_lock;
+       		spinlock_t                      lock;
+	}polling;
 };
 
+static int acpi_ec_polling_wait ( union acpi_ec *ec, u8 event); 
+static int acpi_ec_burst_wait(union acpi_ec *ec, unsigned int event);
+static int acpi_ec_polling_read ( union acpi_ec *ec, u8 address, u32 *data);
+static int acpi_ec_burst_read( union acpi_ec *ec, u8 address, u32 *data);
+static int acpi_ec_polling_write ( union acpi_ec *ec, u8 address, u8 data);
+static int acpi_ec_burst_write ( union acpi_ec *ec, u8 address, u8 data);
+static int acpi_ec_polling_query ( union acpi_ec *ec, u32 *data);
+static int acpi_ec_burst_query ( union acpi_ec *ec, u32 *data);
+static void acpi_ec_gpe_polling_query ( void *ec_cxt);
+static void acpi_ec_gpe_burst_query ( void *ec_cxt);
+static u32 acpi_ec_gpe_polling_handler ( void *data);
+static u32 acpi_ec_gpe_burst_handler ( void *data);
+static acpi_status __init
+acpi_fake_ecdt_polling_callback (
+	acpi_handle	handle,
+	u32		Level,
+	void		*context,
+	void		**retval);
+
+static acpi_status __init
+acpi_fake_ecdt_burst_callback (
+	acpi_handle	handle,
+	u32		Level,
+	void		*context,
+	void		**retval);
+
+static int __init
+acpi_ec_polling_get_real_ecdt(void);
+static int __init
+acpi_ec_burst_get_real_ecdt(void);
 /* If we find an EC via the ECDT, we need to keep a ptr to its context */
-static struct acpi_ec	*ec_ecdt;
+static union acpi_ec	*ec_ecdt;
 
 /* External interfaces use first EC only, so remember */
 static struct acpi_device *first_ec;
+static int acpi_ec_polling_mode = EC_POLLING;
 
 /* --------------------------------------------------------------------------
                              Transaction Management
    -------------------------------------------------------------------------- */
 
+static inline u32 acpi_ec_read_status(union acpi_ec *ec)
+{
+	u32	status = 0;
+
+	acpi_hw_low_level_read(8, &status, &ec->common.status_addr);
+	return status;
+}
+
 static int
 acpi_ec_wait (
-	struct acpi_ec		*ec,
+	union acpi_ec		*ec,
+	u8			event)
+{
+	if (acpi_ec_polling_mode) 
+		return acpi_ec_polling_wait (ec, event);
+	else
+		return acpi_ec_burst_wait (ec, event);
+}
+
+static int
+acpi_ec_polling_wait (
+	union acpi_ec		*ec,
 	u8			event)
 {
 	u32			acpi_ec_status = 0;
@@ -115,7 +205,7 @@ acpi_ec_wait (
 	switch (event) {
 	case ACPI_EC_EVENT_OBF:
 		do {
-			acpi_hw_low_level_read(8, &acpi_ec_status, &ec->status_addr);
+			acpi_hw_low_level_read(8, &acpi_ec_status, &ec->common.status_addr);
 			if (acpi_ec_status & ACPI_EC_FLAG_OBF)
 				return 0;
 			udelay(ACPI_EC_UDELAY);
@@ -123,7 +213,7 @@ acpi_ec_wait (
 		break;
 	case ACPI_EC_EVENT_IBE:
 		do {
-			acpi_hw_low_level_read(8, &acpi_ec_status, &ec->status_addr);
+			acpi_hw_low_level_read(8, &acpi_ec_status, &ec->common.status_addr);
 			if (!(acpi_ec_status & ACPI_EC_FLAG_IBF))
 				return 0;
 			udelay(ACPI_EC_UDELAY);
@@ -135,11 +225,129 @@ acpi_ec_wait (
 
 	return -ETIME;
 }
+static int acpi_ec_burst_wait(union acpi_ec *ec, unsigned int event)
+{
+	int	result = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_ec_wait");
+
+	ec->burst.expect_event = event;
+	smp_mb();
+
+	result = wait_event_interruptible_timeout(ec->burst.wait,
+					!ec->burst.expect_event,
+					msecs_to_jiffies(ACPI_EC_DELAY));
+	
+	ec->burst.expect_event = 0;
+	smp_mb();
+
+	if (result < 0){
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR," result  = %d ", result));
+		return_VALUE(result);
+	}
+
+	/*
+	 * Verify that the event in question has actually happened by
+	 * querying EC status. Do the check even if operation timed-out
+	 * to make sure that we did not miss interrupt.
+	 */
+	switch (event) {
+	case ACPI_EC_EVENT_OBF:
+		if (acpi_ec_read_status(ec) & ACPI_EC_FLAG_OBF)
+			return_VALUE(0);
+		break;
+
+	case ACPI_EC_EVENT_IBE:
+		if (~acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF)
+			return_VALUE(0);
+		break;
+	}
+
+	return_VALUE(-ETIME);
+}
+
 
 
 static int
+acpi_ec_enter_burst_mode (
+	union acpi_ec		*ec)
+{
+	u32			tmp = 0;
+	int			status = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_ec_enter_burst_mode");
+
+	status = acpi_ec_read_status(ec);
+	if (status != -EINVAL &&
+		!(status & ACPI_EC_FLAG_BURST)){
+		acpi_hw_low_level_write(8, ACPI_EC_BURST_ENABLE, &ec->common.command_addr);
+		status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
+		if (status){
+			acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
+			return_VALUE(-EINVAL);
+		}
+		acpi_hw_low_level_read(8, &tmp, &ec->common.data_addr);
+		acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
+		if(tmp != 0x90 ) {/* Burst ACK byte*/
+			return_VALUE(-EINVAL);
+		}
+	}
+
+	atomic_set(&ec->burst.leaving_burst , 0);
+	return_VALUE(0);
+}
+
+static int
+acpi_ec_leave_burst_mode (
+	union acpi_ec		*ec)
+{
+	int			status =0;
+
+	ACPI_FUNCTION_TRACE("acpi_ec_leave_burst_mode");
+
+	atomic_set(&ec->burst.leaving_burst , 1);
+	status = acpi_ec_read_status(ec);
+	if (status != -EINVAL &&
+		(status & ACPI_EC_FLAG_BURST)){
+		acpi_hw_low_level_write(8, ACPI_EC_BURST_DISABLE, &ec->common.command_addr);
+		status = acpi_ec_wait(ec, ACPI_EC_FLAG_IBF);
+		if (status){
+			acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
+			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,"------->wait fail\n"));
+			return_VALUE(-EINVAL);
+		}
+		acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
+		status = acpi_ec_read_status(ec);
+	}
+
+	return_VALUE(0);
+}
+
+static int
 acpi_ec_read (
-	struct acpi_ec		*ec,
+	union acpi_ec		*ec,
+	u8			address,
+	u32			*data)
+{
+	if (acpi_ec_polling_mode) 
+		return acpi_ec_polling_read(ec, address, data);
+	else
+		return acpi_ec_burst_read(ec, address, data);
+}
+static int
+acpi_ec_write (
+	union acpi_ec		*ec,
+	u8			address,
+	u8			data)
+{
+	if (acpi_ec_polling_mode) 
+		return acpi_ec_polling_write(ec, address, data);
+	else
+		return acpi_ec_burst_write(ec, address, data);
+}
+static int
+acpi_ec_polling_read (
+	union acpi_ec		*ec,
 	u8			address,
 	u32			*data)
 {
@@ -155,34 +363,33 @@ acpi_ec_read (
 
 	*data = 0;
 
-	if (ec->global_lock) {
+	if (ec->common.global_lock) {
 		status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
 		if (ACPI_FAILURE(status))
 			return_VALUE(-ENODEV);
 	}
-	
-	spin_lock_irqsave(&ec->lock, flags);
 
-	acpi_hw_low_level_write(8, ACPI_EC_COMMAND_READ, &ec->command_addr);
+	spin_lock_irqsave(&ec->polling.lock, flags);
+
+	acpi_hw_low_level_write(8, ACPI_EC_COMMAND_READ, &ec->common.command_addr);
 	result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
 	if (result)
 		goto end;
 
-	acpi_hw_low_level_write(8, address, &ec->data_addr);
+	acpi_hw_low_level_write(8, address, &ec->common.data_addr);
 	result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
 	if (result)
 		goto end;
 
-
-	acpi_hw_low_level_read(8, data, &ec->data_addr);
+	acpi_hw_low_level_read(8, data, &ec->common.data_addr);
 
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Read [%02x] from address [%02x]\n",
 		*data, address));
-
+	
 end:
-	spin_unlock_irqrestore(&ec->lock, flags);
+	spin_unlock_irqrestore(&ec->polling.lock, flags);
 
-	if (ec->global_lock)
+	if (ec->common.global_lock)
 		acpi_release_global_lock(glk);
 
 	return_VALUE(result);
@@ -190,8 +397,8 @@ end:
 
 
 static int
-acpi_ec_write (
-	struct acpi_ec		*ec,
+acpi_ec_polling_write (
+	union acpi_ec		*ec,
 	u8			address,
 	u8			data)
 {
@@ -205,25 +412,25 @@ acpi_ec_write (
 	if (!ec)
 		return_VALUE(-EINVAL);
 
-	if (ec->global_lock) {
+	if (ec->common.global_lock) {
 		status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
 		if (ACPI_FAILURE(status))
 			return_VALUE(-ENODEV);
 	}
 
-	spin_lock_irqsave(&ec->lock, flags);
+	spin_lock_irqsave(&ec->polling.lock, flags);
 
-	acpi_hw_low_level_write(8, ACPI_EC_COMMAND_WRITE, &ec->command_addr);
+	acpi_hw_low_level_write(8, ACPI_EC_COMMAND_WRITE, &ec->common.command_addr);
 	result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
 	if (result)
 		goto end;
 
-	acpi_hw_low_level_write(8, address, &ec->data_addr);
+	acpi_hw_low_level_write(8, address, &ec->common.data_addr);
 	result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
 	if (result)
 		goto end;
 
-	acpi_hw_low_level_write(8, data, &ec->data_addr);
+	acpi_hw_low_level_write(8, data, &ec->common.data_addr);
 	result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
 	if (result)
 		goto end;
@@ -232,21 +439,172 @@ acpi_ec_write (
 		data, address));
 
 end:
-	spin_unlock_irqrestore(&ec->lock, flags);
+	spin_unlock_irqrestore(&ec->polling.lock, flags);
 
-	if (ec->global_lock)
+	if (ec->common.global_lock)
 		acpi_release_global_lock(glk);
 
 	return_VALUE(result);
 }
 
+static int
+acpi_ec_burst_read (
+	union acpi_ec		*ec,
+	u8			address,
+	u32			*data)
+{
+	int			status = 0;
+	u32			glk;
+
+	ACPI_FUNCTION_TRACE("acpi_ec_read");
+
+	if (!ec || !data)
+		return_VALUE(-EINVAL);
+
+retry:
+	*data = 0;
+
+	if (ec->common.global_lock) {
+		status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
+		if (ACPI_FAILURE(status))
+			return_VALUE(-ENODEV);
+	}
+
+	WARN_ON(in_interrupt());
+	down(&ec->burst.sem);
+
+	if(acpi_ec_enter_burst_mode(ec))
+		goto end;
+
+	acpi_hw_low_level_write(8, ACPI_EC_COMMAND_READ, &ec->common.command_addr);
+	status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
+	acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
+	if (status) {
+		goto end;
+	}
+
+	acpi_hw_low_level_write(8, address, &ec->common.data_addr);
+	status= acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
+	if (status){
+		acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
+		goto end;
+	}
+
+	acpi_hw_low_level_read(8, data, &ec->common.data_addr);
+	acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
+
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Read [%02x] from address [%02x]\n",
+		*data, address));
+	
+end:
+	acpi_ec_leave_burst_mode(ec);
+	up(&ec->burst.sem);
+
+	if (ec->common.global_lock)
+		acpi_release_global_lock(glk);
+
+	if(atomic_read(&ec->burst.leaving_burst) == 2){
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO,"aborted, retry ...\n"));
+		while(atomic_read(&ec->burst.pending_gpe)){
+			msleep(1);	
+		}
+		acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
+		goto retry;
+	}
+
+	return_VALUE(status);
+}
+
+
+static int
+acpi_ec_burst_write (
+	union acpi_ec		*ec,
+	u8			address,
+	u8			data)
+{
+	int			status = 0;
+	u32			glk;
+	u32			tmp;
+
+	ACPI_FUNCTION_TRACE("acpi_ec_write");
+
+	if (!ec)
+		return_VALUE(-EINVAL);
+retry:
+	if (ec->common.global_lock) {
+		status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
+		if (ACPI_FAILURE(status))
+			return_VALUE(-ENODEV);
+	}
+
+	WARN_ON(in_interrupt());
+	down(&ec->burst.sem);
+
+	if(acpi_ec_enter_burst_mode(ec))
+		goto end;
+
+	status = acpi_ec_read_status(ec);
+	if (status != -EINVAL &&
+		!(status & ACPI_EC_FLAG_BURST)){
+		acpi_hw_low_level_write(8, ACPI_EC_BURST_ENABLE, &ec->common.command_addr);
+		status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
+		if (status)
+			goto end;
+		acpi_hw_low_level_read(8, &tmp, &ec->common.data_addr);
+		if(tmp != 0x90 ) /* Burst ACK byte*/
+			goto end;
+	}
+	/*Now we are in burst mode*/
+
+	acpi_hw_low_level_write(8, ACPI_EC_COMMAND_WRITE, &ec->common.command_addr);
+	status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
+	acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
+	if (status){
+		goto end;
+	}
+
+	acpi_hw_low_level_write(8, address, &ec->common.data_addr);
+	status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
+	if (status){
+		acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
+		goto end;
+	}
+
+	acpi_hw_low_level_write(8, data, &ec->common.data_addr);
+	status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
+	acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
+	if (status)
+		goto end;
+
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Wrote [%02x] to address [%02x]\n",
+		data, address));
+
+end:
+	acpi_ec_leave_burst_mode(ec);
+	up(&ec->burst.sem);
+
+	if (ec->common.global_lock)
+		acpi_release_global_lock(glk);
+
+	if(atomic_read(&ec->burst.leaving_burst) == 2){
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO,"aborted, retry ...\n"));
+		while(atomic_read(&ec->burst.pending_gpe)){
+			msleep(1);	
+		}
+		acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
+		goto retry;
+	}
+
+	return_VALUE(status);
+}
+
 /*
  * Externally callable EC access functions. For now, assume 1 EC only
  */
 int
 ec_read(u8 addr, u8 *val)
 {
-	struct acpi_ec *ec;
+	union acpi_ec *ec;
 	int err;
 	u32 temp_data;
 
@@ -269,7 +627,7 @@ EXPORT_SYMBOL(ec_read);
 int
 ec_write(u8 addr, u8 val)
 {
-	struct acpi_ec *ec;
+	union acpi_ec *ec;
 	int err;
 
 	if (!first_ec)
@@ -283,10 +641,19 @@ ec_write(u8 addr, u8 val)
 }
 EXPORT_SYMBOL(ec_write);
 
-
 static int
 acpi_ec_query (
-	struct acpi_ec		*ec,
+	union acpi_ec		*ec,
+	u32			*data)
+{
+	if (acpi_ec_polling_mode) 
+		return acpi_ec_polling_query(ec, data);
+	else
+		return acpi_ec_burst_query(ec, data);
+}
+static int
+acpi_ec_polling_query (
+	union acpi_ec		*ec,
 	u32			*data)
 {
 	int			result = 0;
@@ -301,7 +668,7 @@ acpi_ec_query (
 
 	*data = 0;
 
-	if (ec->global_lock) {
+	if (ec->common.global_lock) {
 		status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
 		if (ACPI_FAILURE(status))
 			return_VALUE(-ENODEV);
@@ -312,32 +679,86 @@ acpi_ec_query (
 	 * Note that successful completion of the query causes the ACPI_EC_SCI
 	 * bit to be cleared (and thus clearing the interrupt source).
 	 */
-	spin_lock_irqsave(&ec->lock, flags);
+	spin_lock_irqsave(&ec->polling.lock, flags);
 
-	acpi_hw_low_level_write(8, ACPI_EC_COMMAND_QUERY, &ec->command_addr);
+	acpi_hw_low_level_write(8, ACPI_EC_COMMAND_QUERY, &ec->common.command_addr);
 	result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
 	if (result)
 		goto end;
-	
-	acpi_hw_low_level_read(8, data, &ec->data_addr);
+
+	acpi_hw_low_level_read(8, data, &ec->common.data_addr);
 	if (!*data)
 		result = -ENODATA;
 
 end:
-	spin_unlock_irqrestore(&ec->lock, flags);
+	spin_unlock_irqrestore(&ec->polling.lock, flags);
 
-	if (ec->global_lock)
+	if (ec->common.global_lock)
 		acpi_release_global_lock(glk);
 
 	return_VALUE(result);
 }
+static int
+acpi_ec_burst_query (
+	union acpi_ec		*ec,
+	u32			*data)
+{
+	int			status = 0;
+	u32			glk;
+
+	ACPI_FUNCTION_TRACE("acpi_ec_query");
+
+	if (!ec || !data)
+		return_VALUE(-EINVAL);
+	*data = 0;
+
+	if (ec->common.global_lock) {
+		status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
+		if (ACPI_FAILURE(status))
+			return_VALUE(-ENODEV);
+	}
+
+	down(&ec->burst.sem);
+	if(acpi_ec_enter_burst_mode(ec))
+		goto end;
+	/*
+	 * Query the EC to find out which _Qxx method we need to evaluate.
+	 * Note that successful completion of the query causes the ACPI_EC_SCI
+	 * bit to be cleared (and thus clearing the interrupt source).
+	 */
+	acpi_hw_low_level_write(8, ACPI_EC_COMMAND_QUERY, &ec->common.command_addr);
+	status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
+	if (status){
+		acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
+		goto end;
+	}
+
+	acpi_hw_low_level_read(8, data, &ec->common.data_addr);
+	acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
+	if (!*data)
+		status = -ENODATA;
+
+end:
+	acpi_ec_leave_burst_mode(ec);
+	up(&ec->burst.sem);
+
+	if (ec->common.global_lock)
+		acpi_release_global_lock(glk);
+
+	if(atomic_read(&ec->burst.leaving_burst) == 2){
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO,"aborted, retry ...\n"));
+		acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
+		status = -ENODATA;
+	}
+	return_VALUE(status);
+}
 
 
 /* --------------------------------------------------------------------------
                                 Event Management
    -------------------------------------------------------------------------- */
 
-struct acpi_ec_query_data {
+union acpi_ec_query_data {
 	acpi_handle		handle;
 	u8			data;
 };
@@ -346,7 +767,17 @@ static void
 acpi_ec_gpe_query (
 	void			*ec_cxt)
 {
-	struct acpi_ec		*ec = (struct acpi_ec *) ec_cxt;
+	if (acpi_ec_polling_mode) 
+		acpi_ec_gpe_polling_query(ec_cxt);
+	else
+		acpi_ec_gpe_burst_query(ec_cxt);
+}
+
+static void
+acpi_ec_gpe_polling_query (
+	void			*ec_cxt)
+{
+	union acpi_ec		*ec = (union acpi_ec *) ec_cxt;
 	u32			value = 0;
 	unsigned long		flags = 0;
 	static char		object_name[5] = {'_','Q','0','0','\0'};
@@ -356,11 +787,11 @@ acpi_ec_gpe_query (
 	ACPI_FUNCTION_TRACE("acpi_ec_gpe_query");
 
 	if (!ec_cxt)
-		goto end;	
+		goto end;
 
-	spin_lock_irqsave(&ec->lock, flags);
-	acpi_hw_low_level_read(8, &value, &ec->command_addr);
-	spin_unlock_irqrestore(&ec->lock, flags);
+	spin_lock_irqsave(&ec->polling.lock, flags);
+	acpi_hw_low_level_read(8, &value, &ec->common.command_addr);
+	spin_unlock_irqrestore(&ec->polling.lock, flags);
 
 	/* TBD: Implement asynch events!
 	 * NOTE: All we care about are EC-SCI's.  Other EC events are
@@ -373,29 +804,67 @@ acpi_ec_gpe_query (
 
 	if (acpi_ec_query(ec, &value))
 		goto end;
-	
+
 	object_name[2] = hex[((value >> 4) & 0x0F)];
 	object_name[3] = hex[(value & 0x0F)];
 
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluating %s\n", object_name));
 
-	acpi_evaluate_object(ec->handle, object_name, NULL, NULL);
+	acpi_evaluate_object(ec->common.handle, object_name, NULL, NULL);
 
-end:
-	acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
+end:	
+	acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
+}
+static void
+acpi_ec_gpe_burst_query (
+	void			*ec_cxt)
+{
+	union acpi_ec		*ec = (union acpi_ec *) ec_cxt;
+	u32			value;
+	int			result = -ENODATA;
+	static char		object_name[5] = {'_','Q','0','0','\0'};
+	const char		hex[] = {'0','1','2','3','4','5','6','7',
+				         '8','9','A','B','C','D','E','F'};
+
+	ACPI_FUNCTION_TRACE("acpi_ec_gpe_query");
+
+	if (acpi_ec_read_status(ec) & ACPI_EC_FLAG_SCI)
+		result = acpi_ec_query(ec, &value);
+
+	if (result)
+		goto end;
+
+	object_name[2] = hex[((value >> 4) & 0x0F)];
+	object_name[3] = hex[(value & 0x0F)];
+
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluating %s\n", object_name));
+
+	acpi_evaluate_object(ec->common.handle, object_name, NULL, NULL);
+end:	
+	atomic_dec(&ec->burst.pending_gpe);
+	return;
 }
 
 static u32
 acpi_ec_gpe_handler (
 	void			*data)
 {
+	if (acpi_ec_polling_mode) 
+		return acpi_ec_gpe_polling_handler(data);
+	else
+		return acpi_ec_gpe_burst_handler(data);	
+}
+static u32
+acpi_ec_gpe_polling_handler (
+	void			*data)
+{
 	acpi_status		status = AE_OK;
-	struct acpi_ec		*ec = (struct acpi_ec *) data;
+	union acpi_ec		*ec = (union acpi_ec *) data;
 
 	if (!ec)
 		return ACPI_INTERRUPT_NOT_HANDLED;
 
-	acpi_disable_gpe(NULL, ec->gpe_bit, ACPI_ISR);
+	acpi_disable_gpe(NULL, ec->common.gpe_bit, ACPI_ISR);
 
 	status = acpi_os_queue_for_execution(OSD_PRIORITY_GPE,
 		acpi_ec_gpe_query, ec);
@@ -405,6 +874,55 @@ acpi_ec_gpe_handler (
 	else
 		return ACPI_INTERRUPT_NOT_HANDLED;
 }
+static u32
+acpi_ec_gpe_burst_handler (
+	void			*data)
+{
+	acpi_status		status = AE_OK;
+	u32			value;
+	union acpi_ec		*ec = (union acpi_ec *) data;
+
+	if (!ec)
+		return ACPI_INTERRUPT_NOT_HANDLED;
+
+	acpi_disable_gpe(NULL, ec->common.gpe_bit, ACPI_ISR);
+
+	value = acpi_ec_read_status(ec);
+
+	if((value & ACPI_EC_FLAG_IBF) &&
+		!(value & ACPI_EC_FLAG_BURST) &&
+			(atomic_read(&ec->burst.leaving_burst) == 0)) { 
+	/*
+	 * the embedded controller disables 
+	 * burst mode for any reason other 
+	 * than the burst disable command
+	 * to process critical event.
+	 */
+		atomic_set(&ec->burst.leaving_burst , 2); /* block current pending transaction
+					and retry */
+		wake_up(&ec->burst.wait);
+	}else {
+		if ((ec->burst.expect_event == ACPI_EC_EVENT_OBF &&
+				(value & ACPI_EC_FLAG_OBF)) ||
+	    			(ec->burst.expect_event == ACPI_EC_EVENT_IBE &&
+				!(value & ACPI_EC_FLAG_IBF))) {
+			ec->burst.expect_event = 0;
+			wake_up(&ec->burst.wait);
+			return ACPI_INTERRUPT_HANDLED;
+		}
+	}
+
+	if (value & ACPI_EC_FLAG_SCI){
+		atomic_add(1, &ec->burst.pending_gpe) ;
+		status = acpi_os_queue_for_execution(OSD_PRIORITY_GPE,
+						acpi_ec_gpe_query, ec);
+		return status == AE_OK ?
+		ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED;
+	} 
+	acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_ISR);
+	return status == AE_OK ?
+		ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED;
+}
 
 /* --------------------------------------------------------------------------
                              Address Space Management
@@ -421,10 +939,8 @@ acpi_ec_space_setup (
 	 * The EC object is in the handler context and is needed
 	 * when calling the acpi_ec_space_handler.
 	 */
-	if(function == ACPI_REGION_DEACTIVATE) 
-		*return_context = NULL;
-	else 
-		*return_context = handler_context;
+	*return_context  = (function != ACPI_REGION_DEACTIVATE) ?
+						handler_context : NULL;
 
 	return AE_OK;
 }
@@ -440,8 +956,8 @@ acpi_ec_space_handler (
 	void			*region_context)
 {
 	int			result = 0;
-	struct acpi_ec		*ec = NULL;
-	u32			temp = 0;
+	union acpi_ec		*ec = NULL;
+	u64			temp = *value;
 	acpi_integer		f_v = 0;
 	int 			i = 0;
 
@@ -450,22 +966,21 @@ acpi_ec_space_handler (
 	if ((address > 0xFF) || !value || !handler_context)
 		return_VALUE(AE_BAD_PARAMETER);
 
-	if(bit_width != 8) {
+	if (bit_width != 8 && acpi_strict) {
 		printk(KERN_WARNING PREFIX "acpi_ec_space_handler: bit_width should be 8\n");
-		if (acpi_strict)
-			return_VALUE(AE_BAD_PARAMETER);
+		return_VALUE(AE_BAD_PARAMETER);
 	}
 
-	ec = (struct acpi_ec *) handler_context;
+	ec = (union acpi_ec *) handler_context;
 
 next_byte:
 	switch (function) {
 	case ACPI_READ:
-		result = acpi_ec_read(ec, (u8) address, &temp);
-		*value = (acpi_integer) temp;
+		temp = 0;
+		result = acpi_ec_read(ec, (u8) address, (u32 *)&temp);
 		break;
 	case ACPI_WRITE:
-		result = acpi_ec_write(ec, (u8) address, (u8) *value);
+		result = acpi_ec_write(ec, (u8) address, (u8) temp);
 		break;
 	default:
 		result = -EINVAL;
@@ -474,19 +989,18 @@ next_byte:
 	}
 
 	bit_width -= 8;
-	if(bit_width){
-
-		if(function == ACPI_READ)
-			f_v |= (acpi_integer) (*value) << 8*i;
-		if(function == ACPI_WRITE)
-			(*value) >>=8; 
+	if (bit_width) {
+		if (function == ACPI_READ)
+			f_v |= temp << 8 * i;
+		if (function == ACPI_WRITE)
+			temp >>= 8;
 		i++;
+		address++;
 		goto next_byte;
 	}
 
-
-	if(function == ACPI_READ){
-		f_v |= (acpi_integer) (*value) << 8*i;
+	if (function == ACPI_READ) {
+		f_v |= temp << 8 * i;
 		*value = f_v;
 	}
 
@@ -505,8 +1019,6 @@ out:
 	default:
 		return_VALUE(AE_OK);
 	}
-	
-
 }
 
 
@@ -520,7 +1032,7 @@ static struct proc_dir_entry	*acpi_ec_di
 static int
 acpi_ec_read_info (struct seq_file *seq, void *offset)
 {
-	struct acpi_ec		*ec = (struct acpi_ec *) seq->private;
+	union acpi_ec		*ec = (union acpi_ec *) seq->private;
 
 	ACPI_FUNCTION_TRACE("acpi_ec_read_info");
 
@@ -528,11 +1040,12 @@ acpi_ec_read_info (struct seq_file *seq,
 		goto end;
 
 	seq_printf(seq, "gpe bit:                 0x%02x\n",
-		(u32) ec->gpe_bit);
+		(u32) ec->common.gpe_bit);
 	seq_printf(seq, "ports:                   0x%02x, 0x%02x\n",
-		(u32) ec->status_addr.address, (u32) ec->data_addr.address);
+		(u32) ec->common.status_addr.address, (u32) ec->common.data_addr.address);
 	seq_printf(seq, "use global lock:         %s\n",
-		ec->global_lock?"yes":"no");
+		ec->common.global_lock?"yes":"no");
+	acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
 
 end:
 	return_VALUE(0);
@@ -602,13 +1115,14 @@ acpi_ec_remove_fs (
                                Driver Interface
    -------------------------------------------------------------------------- */
 
+
 static int
-acpi_ec_add (
+acpi_ec_polling_add (
 	struct acpi_device	*device)
 {
 	int			result = 0;
 	acpi_status		status = AE_OK;
-	struct acpi_ec		*ec = NULL;
+	union acpi_ec		*ec = NULL;
 	unsigned long		uid;
 
 	ACPI_FUNCTION_TRACE("acpi_ec_add");
@@ -616,36 +1130,36 @@ acpi_ec_add (
 	if (!device)
 		return_VALUE(-EINVAL);
 
-	ec = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL);
+	ec = kmalloc(sizeof(union acpi_ec), GFP_KERNEL);
 	if (!ec)
 		return_VALUE(-ENOMEM);
-	memset(ec, 0, sizeof(struct acpi_ec));
+	memset(ec, 0, sizeof(union acpi_ec));
 
-	ec->handle = device->handle;
-	ec->uid = -1;
-	spin_lock_init(&ec->lock);
+	ec->common.handle = device->handle;
+	ec->common.uid = -1;
+	spin_lock_init(&ec->polling.lock);
 	strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME);
 	strcpy(acpi_device_class(device), ACPI_EC_CLASS);
 	acpi_driver_data(device) = ec;
 
 	/* Use the global lock for all EC transactions? */
-	acpi_evaluate_integer(ec->handle, "_GLK", NULL, &ec->global_lock);
+	acpi_evaluate_integer(ec->common.handle, "_GLK", NULL, &ec->common.global_lock);
 
 	/* If our UID matches the UID for the ECDT-enumerated EC,
 	   we now have the *real* EC info, so kill the makeshift one.*/
-	acpi_evaluate_integer(ec->handle, "_UID", NULL, &uid);
-	if (ec_ecdt && ec_ecdt->uid == uid) {
+	acpi_evaluate_integer(ec->common.handle, "_UID", NULL, &uid);
+	if (ec_ecdt && ec_ecdt->common.uid == uid) {
 		acpi_remove_address_space_handler(ACPI_ROOT_OBJECT,
 			ACPI_ADR_SPACE_EC, &acpi_ec_space_handler);
 	
-		acpi_remove_gpe_handler(NULL, ec_ecdt->gpe_bit, &acpi_ec_gpe_handler);
+		acpi_remove_gpe_handler(NULL, ec_ecdt->common.gpe_bit, &acpi_ec_gpe_handler);
 
 		kfree(ec_ecdt);
 	}
 
 	/* Get GPE bit assignment (EC events). */
 	/* TODO: Add support for _GPE returning a package */
-	status = acpi_evaluate_integer(ec->handle, "_GPE", NULL, &ec->gpe_bit);
+	status = acpi_evaluate_integer(ec->common.handle, "_GPE", NULL, &ec->common.gpe_bit);
 	if (ACPI_FAILURE(status)) {
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
 			"Error obtaining GPE bit assignment\n"));
@@ -659,7 +1173,78 @@ acpi_ec_add (
 
 	printk(KERN_INFO PREFIX "%s [%s] (gpe %d)\n",
 		acpi_device_name(device), acpi_device_bid(device),
-		(u32) ec->gpe_bit);
+		(u32) ec->common.gpe_bit);
+
+	if (!first_ec)
+		first_ec = device;
+
+end:
+	if (result)
+		kfree(ec);
+
+	return_VALUE(result);
+}
+static int
+acpi_ec_burst_add (
+	struct acpi_device	*device)
+{
+	int			result = 0;
+	acpi_status		status = AE_OK;
+	union acpi_ec		*ec = NULL;
+	unsigned long		uid;
+
+	ACPI_FUNCTION_TRACE("acpi_ec_add");
+
+	if (!device)
+		return_VALUE(-EINVAL);
+
+	ec = kmalloc(sizeof(union acpi_ec), GFP_KERNEL);
+	if (!ec)
+		return_VALUE(-ENOMEM);
+	memset(ec, 0, sizeof(union acpi_ec));
+
+	ec->common.handle = device->handle;
+	ec->common.uid = -1;
+ 	atomic_set(&ec->burst.pending_gpe, 0);
+ 	atomic_set(&ec->burst.leaving_burst , 1);
+ 	init_MUTEX(&ec->burst.sem);
+ 	init_waitqueue_head(&ec->burst.wait);
+	strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME);
+	strcpy(acpi_device_class(device), ACPI_EC_CLASS);
+	acpi_driver_data(device) = ec;
+
+	/* Use the global lock for all EC transactions? */
+	acpi_evaluate_integer(ec->common.handle, "_GLK", NULL, &ec->common.global_lock);
+
+	/* If our UID matches the UID for the ECDT-enumerated EC,
+	   we now have the *real* EC info, so kill the makeshift one.*/
+	acpi_evaluate_integer(ec->common.handle, "_UID", NULL, &uid);
+	if (ec_ecdt && ec_ecdt->common.uid == uid) {
+		acpi_remove_address_space_handler(ACPI_ROOT_OBJECT,
+			ACPI_ADR_SPACE_EC, &acpi_ec_space_handler);
+
+		acpi_remove_gpe_handler(NULL, ec_ecdt->common.gpe_bit, &acpi_ec_gpe_handler);
+
+		kfree(ec_ecdt);
+	}
+
+	/* Get GPE bit assignment (EC events). */
+	/* TODO: Add support for _GPE returning a package */
+	status = acpi_evaluate_integer(ec->common.handle, "_GPE", NULL, &ec->common.gpe_bit);
+	if (ACPI_FAILURE(status)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"Error obtaining GPE bit assignment\n"));
+		result = -ENODEV;
+		goto end;
+	}
+
+	result = acpi_ec_add_fs(device);
+	if (result)
+		goto end;
+
+	printk(KERN_INFO PREFIX "%s [%s] (gpe %d)\n",
+		acpi_device_name(device), acpi_device_bid(device),
+		(u32) ec->common.gpe_bit);
 
 	if (!first_ec)
 		first_ec = device;
@@ -677,7 +1262,7 @@ acpi_ec_remove (
 	struct acpi_device	*device,
 	int			type)
 {
-	struct acpi_ec		*ec = NULL;
+	union acpi_ec		*ec = NULL;
 
 	ACPI_FUNCTION_TRACE("acpi_ec_remove");
 
@@ -699,7 +1284,7 @@ acpi_ec_io_ports (
 	struct acpi_resource	*resource,
 	void			*context)
 {
-	struct acpi_ec		*ec = (struct acpi_ec *) context;
+	union acpi_ec		*ec = (union acpi_ec *) context;
 	struct acpi_generic_address *addr;
 
 	if (resource->id != ACPI_RSTYPE_IO) {
@@ -711,10 +1296,10 @@ acpi_ec_io_ports (
 	 * the second address region returned is the status/command
 	 * port.
 	 */
-	if (ec->data_addr.register_bit_width == 0) {
-		addr = &ec->data_addr;
-	} else if (ec->command_addr.register_bit_width == 0) {
-		addr = &ec->command_addr;
+	if (ec->common.data_addr.register_bit_width == 0) {
+		addr = &ec->common.data_addr;
+	} else if (ec->common.command_addr.register_bit_width == 0) {
+		addr = &ec->common.command_addr;
 	} else {
 		return AE_CTRL_TERMINATE;
 	}
@@ -733,7 +1318,7 @@ acpi_ec_start (
 	struct acpi_device	*device)
 {
 	acpi_status		status = AE_OK;
-	struct acpi_ec		*ec = NULL;
+	union acpi_ec		*ec = NULL;
 
 	ACPI_FUNCTION_TRACE("acpi_ec_start");
 
@@ -748,35 +1333,36 @@ acpi_ec_start (
 	/*
 	 * Get I/O port addresses. Convert to GAS format.
 	 */
-	status = acpi_walk_resources(ec->handle, METHOD_NAME__CRS,
+	status = acpi_walk_resources(ec->common.handle, METHOD_NAME__CRS,
 		acpi_ec_io_ports, ec);
-	if (ACPI_FAILURE(status) || ec->command_addr.register_bit_width == 0) {
+	if (ACPI_FAILURE(status) || ec->common.command_addr.register_bit_width == 0) {
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error getting I/O port addresses"));
 		return_VALUE(-ENODEV);
 	}
 
-	ec->status_addr = ec->command_addr;
+	ec->common.status_addr = ec->common.command_addr;
 
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "gpe=0x%02x, ports=0x%2x,0x%2x\n",
-		(u32) ec->gpe_bit, (u32) ec->command_addr.address,
-		(u32) ec->data_addr.address));
+		(u32) ec->common.gpe_bit, (u32) ec->common.command_addr.address,
+		(u32) ec->common.data_addr.address));
+
 
 	/*
 	 * Install GPE handler
 	 */
-	status = acpi_install_gpe_handler(NULL, ec->gpe_bit,
+	status = acpi_install_gpe_handler(NULL, ec->common.gpe_bit,
 		ACPI_GPE_EDGE_TRIGGERED, &acpi_ec_gpe_handler, ec);
 	if (ACPI_FAILURE(status)) {
 		return_VALUE(-ENODEV);
 	}
-	acpi_set_gpe_type (NULL, ec->gpe_bit, ACPI_GPE_TYPE_RUNTIME);
-	acpi_enable_gpe (NULL, ec->gpe_bit, ACPI_NOT_ISR);
+	acpi_set_gpe_type (NULL, ec->common.gpe_bit, ACPI_GPE_TYPE_RUNTIME);
+	acpi_enable_gpe (NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
 
-	status = acpi_install_address_space_handler (ec->handle,
+	status = acpi_install_address_space_handler (ec->common.handle,
 			ACPI_ADR_SPACE_EC, &acpi_ec_space_handler,
 			&acpi_ec_space_setup, ec);
 	if (ACPI_FAILURE(status)) {
-		acpi_remove_gpe_handler(NULL, ec->gpe_bit, &acpi_ec_gpe_handler);
+		acpi_remove_gpe_handler(NULL, ec->common.gpe_bit, &acpi_ec_gpe_handler);
 		return_VALUE(-ENODEV);
 	}
 
@@ -790,7 +1376,7 @@ acpi_ec_stop (
 	int			type)
 {
 	acpi_status		status = AE_OK;
-	struct acpi_ec		*ec = NULL;
+	union acpi_ec		*ec = NULL;
 
 	ACPI_FUNCTION_TRACE("acpi_ec_stop");
 
@@ -799,12 +1385,12 @@ acpi_ec_stop (
 
 	ec = acpi_driver_data(device);
 
-	status = acpi_remove_address_space_handler(ec->handle,
+	status = acpi_remove_address_space_handler(ec->common.handle,
 		ACPI_ADR_SPACE_EC, &acpi_ec_space_handler);
 	if (ACPI_FAILURE(status))
 		return_VALUE(-ENODEV);
 
-	status = acpi_remove_gpe_handler(NULL, ec->gpe_bit, &acpi_ec_gpe_handler);
+	status = acpi_remove_gpe_handler(NULL, ec->common.gpe_bit, &acpi_ec_gpe_handler);
 	if (ACPI_FAILURE(status))
 		return_VALUE(-ENODEV);
 
@@ -818,27 +1404,76 @@ acpi_fake_ecdt_callback (
 	void		*context,
 	void		**retval)
 {
+
+	if (acpi_ec_polling_mode)
+		return acpi_fake_ecdt_polling_callback(handle,
+			Level, context, retval);
+	else
+		return acpi_fake_ecdt_burst_callback(handle,
+			Level, context, retval);
+}
+
+static acpi_status __init
+acpi_fake_ecdt_polling_callback (
+	acpi_handle	handle,
+	u32		Level,
+	void		*context,
+	void		**retval)
+{
+	acpi_status	status;
+
+	status = acpi_walk_resources(handle, METHOD_NAME__CRS,
+		acpi_ec_io_ports, ec_ecdt);
+	if (ACPI_FAILURE(status))
+		return status;
+	ec_ecdt->common.status_addr = ec_ecdt->common.command_addr;
+
+	ec_ecdt->common.uid = -1;
+	acpi_evaluate_integer(handle, "_UID", NULL, &ec_ecdt->common.uid);
+
+	status = acpi_evaluate_integer(handle, "_GPE", NULL, &ec_ecdt->common.gpe_bit);
+	if (ACPI_FAILURE(status))
+		return status;
+	spin_lock_init(&ec_ecdt->polling.lock);
+	ec_ecdt->common.global_lock = TRUE;
+	ec_ecdt->common.handle = handle;
+
+	printk(KERN_INFO PREFIX  "GPE=0x%02x, ports=0x%2x, 0x%2x\n",
+		(u32) ec_ecdt->common.gpe_bit, (u32) ec_ecdt->common.command_addr.address,
+		(u32) ec_ecdt->common.data_addr.address);
+
+	return AE_CTRL_TERMINATE;
+}
+
+static acpi_status __init
+acpi_fake_ecdt_burst_callback (
+	acpi_handle	handle,
+	u32		Level,
+	void		*context,
+	void		**retval)
+{
 	acpi_status	status;
 
+	init_MUTEX(&ec_ecdt->burst.sem);
+	init_waitqueue_head(&ec_ecdt->burst.wait);
 	status = acpi_walk_resources(handle, METHOD_NAME__CRS,
 		acpi_ec_io_ports, ec_ecdt);
 	if (ACPI_FAILURE(status))
 		return status;
-	ec_ecdt->status_addr = ec_ecdt->command_addr;
+	ec_ecdt->common.status_addr = ec_ecdt->common.command_addr;
 
-	ec_ecdt->uid = -1;
-	acpi_evaluate_integer(handle, "_UID", NULL, &ec_ecdt->uid);
+	ec_ecdt->common.uid = -1;
+	acpi_evaluate_integer(handle, "_UID", NULL, &ec_ecdt->common.uid);
 
-	status = acpi_evaluate_integer(handle, "_GPE", NULL, &ec_ecdt->gpe_bit);
+	status = acpi_evaluate_integer(handle, "_GPE", NULL, &ec_ecdt->common.gpe_bit);
 	if (ACPI_FAILURE(status))
 		return status;
-	spin_lock_init(&ec_ecdt->lock);
-	ec_ecdt->global_lock = TRUE;
-	ec_ecdt->handle = handle;
+	ec_ecdt->common.global_lock = TRUE;
+	ec_ecdt->common.handle = handle;
 
 	printk(KERN_INFO PREFIX  "GPE=0x%02x, ports=0x%2x, 0x%2x\n",
-		(u32) ec_ecdt->gpe_bit, (u32) ec_ecdt->command_addr.address,
-		(u32) ec_ecdt->data_addr.address);
+		(u32) ec_ecdt->common.gpe_bit, (u32) ec_ecdt->common.command_addr.address,
+		(u32) ec_ecdt->common.data_addr.address);
 
 	return AE_CTRL_TERMINATE;
 }
@@ -861,12 +1496,12 @@ acpi_ec_fake_ecdt(void)
 
 	printk(KERN_INFO PREFIX "Try to make an fake ECDT\n");
 
-	ec_ecdt = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL);
+	ec_ecdt = kmalloc(sizeof(union acpi_ec), GFP_KERNEL);
 	if (!ec_ecdt) {
 		ret = -ENOMEM;
 		goto error;
 	}
-	memset(ec_ecdt, 0, sizeof(struct acpi_ec));
+	memset(ec_ecdt, 0, sizeof(union acpi_ec));
 
 	status = acpi_get_devices (ACPI_EC_HID,
 				acpi_fake_ecdt_callback,
@@ -887,6 +1522,15 @@ error:
 static int __init
 acpi_ec_get_real_ecdt(void)
 {
+	if (acpi_ec_polling_mode)
+		return acpi_ec_polling_get_real_ecdt();
+	else
+		return acpi_ec_burst_get_real_ecdt();
+}
+
+static int __init
+acpi_ec_polling_get_real_ecdt(void)
+{
 	acpi_status		status;
 	struct acpi_table_ecdt 	*ecdt_ptr;
 
@@ -900,21 +1544,67 @@ acpi_ec_get_real_ecdt(void)
 	/*
 	 * Generate a temporary ec context to use until the namespace is scanned
 	 */
-	ec_ecdt = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL);
+	ec_ecdt = kmalloc(sizeof(union acpi_ec), GFP_KERNEL);
+	if (!ec_ecdt)
+		return -ENOMEM;
+	memset(ec_ecdt, 0, sizeof(union acpi_ec));
+
+	ec_ecdt->common.command_addr = ecdt_ptr->ec_control;
+	ec_ecdt->common.status_addr = ecdt_ptr->ec_control;
+	ec_ecdt->common.data_addr = ecdt_ptr->ec_data;
+	ec_ecdt->common.gpe_bit = ecdt_ptr->gpe_bit;
+	spin_lock_init(&ec_ecdt->polling.lock);
+	/* use the GL just to be safe */
+	ec_ecdt->common.global_lock = TRUE;
+	ec_ecdt->common.uid = ecdt_ptr->uid;
+
+	status = acpi_get_handle(NULL, ecdt_ptr->ec_id, &ec_ecdt->common.handle);
+	if (ACPI_FAILURE(status)) {
+		goto error;
+	}
+
+	return 0;
+error:
+	printk(KERN_ERR PREFIX "Could not use ECDT\n");
+	kfree(ec_ecdt);
+	ec_ecdt = NULL;
+
+	return -ENODEV;
+}
+
+
+static int __init
+acpi_ec_burst_get_real_ecdt(void)
+{
+	acpi_status		status;
+	struct acpi_table_ecdt 	*ecdt_ptr;
+
+	status = acpi_get_firmware_table("ECDT", 1, ACPI_LOGICAL_ADDRESSING,
+		(struct acpi_table_header **) &ecdt_ptr);
+	if (ACPI_FAILURE(status))
+		return -ENODEV;
+
+	printk(KERN_INFO PREFIX "Found ECDT\n");
+
+	/*
+	 * Generate a temporary ec context to use until the namespace is scanned
+	 */
+	ec_ecdt = kmalloc(sizeof(union acpi_ec), GFP_KERNEL);
 	if (!ec_ecdt)
 		return -ENOMEM;
-	memset(ec_ecdt, 0, sizeof(struct acpi_ec));
+	memset(ec_ecdt, 0, sizeof(union acpi_ec));
 
-	ec_ecdt->command_addr = ecdt_ptr->ec_control;
-	ec_ecdt->status_addr = ecdt_ptr->ec_control;
-	ec_ecdt->data_addr = ecdt_ptr->ec_data;
-	ec_ecdt->gpe_bit = ecdt_ptr->gpe_bit;
-	spin_lock_init(&ec_ecdt->lock);
+ 	init_MUTEX(&ec_ecdt->burst.sem);
+ 	init_waitqueue_head(&ec_ecdt->burst.wait);
+	ec_ecdt->common.command_addr = ecdt_ptr->ec_control;
+	ec_ecdt->common.status_addr = ecdt_ptr->ec_control;
+	ec_ecdt->common.data_addr = ecdt_ptr->ec_data;
+	ec_ecdt->common.gpe_bit = ecdt_ptr->gpe_bit;
 	/* use the GL just to be safe */
-	ec_ecdt->global_lock = TRUE;
-	ec_ecdt->uid = ecdt_ptr->uid;
+	ec_ecdt->common.global_lock = TRUE;
+	ec_ecdt->common.uid = ecdt_ptr->uid;
 
-	status = acpi_get_handle(NULL, ecdt_ptr->ec_id, &ec_ecdt->handle);
+	status = acpi_get_handle(NULL, ecdt_ptr->ec_id, &ec_ecdt->common.handle);
 	if (ACPI_FAILURE(status)) {
 		goto error;
 	}
@@ -947,20 +1637,20 @@ acpi_ec_ecdt_probe (void)
 	/*
 	 * Install GPE handler
 	 */
-	status = acpi_install_gpe_handler(NULL, ec_ecdt->gpe_bit,
+	status = acpi_install_gpe_handler(NULL, ec_ecdt->common.gpe_bit,
 		ACPI_GPE_EDGE_TRIGGERED, &acpi_ec_gpe_handler,
 		ec_ecdt);
 	if (ACPI_FAILURE(status)) {
 		goto error;
 	}
-	acpi_set_gpe_type (NULL, ec_ecdt->gpe_bit, ACPI_GPE_TYPE_RUNTIME);
-	acpi_enable_gpe (NULL, ec_ecdt->gpe_bit, ACPI_NOT_ISR);
+	acpi_set_gpe_type (NULL, ec_ecdt->common.gpe_bit, ACPI_GPE_TYPE_RUNTIME);
+	acpi_enable_gpe (NULL, ec_ecdt->common.gpe_bit, ACPI_NOT_ISR);
 
 	status = acpi_install_address_space_handler (ACPI_ROOT_OBJECT,
 			ACPI_ADR_SPACE_EC, &acpi_ec_space_handler,
 			&acpi_ec_space_setup, ec_ecdt);
 	if (ACPI_FAILURE(status)) {
-		acpi_remove_gpe_handler(NULL, ec_ecdt->gpe_bit,
+		acpi_remove_gpe_handler(NULL, ec_ecdt->common.gpe_bit,
 			&acpi_ec_gpe_handler);
 		goto error;
 	}
@@ -1021,4 +1711,24 @@ static int __init acpi_fake_ecdt_setup(c
 	acpi_fake_ecdt_enabled = 1;
 	return 0;
 }
+
 __setup("acpi_fake_ecdt", acpi_fake_ecdt_setup);
+static int __init acpi_ec_set_polling_mode(char *str)
+{
+	int burst;
+
+	if (!get_option(&str, &burst))
+		return 0;
+
+	if (burst) {
+		acpi_ec_polling_mode = EC_BURST;
+		acpi_ec_driver.ops.add = acpi_ec_burst_add;
+	} else {
+		acpi_ec_polling_mode = EC_POLLING;
+		acpi_ec_driver.ops.add = acpi_ec_polling_add;
+	}
+	printk(KERN_INFO PREFIX "EC %s mode.\n",
+		burst ? "burst": "polling");
+	return 0;
+}
+__setup("ec_burst=", acpi_ec_set_polling_mode);
diff --git a/drivers/acpi/events/evevent.c b/drivers/acpi/events/evevent.c
--- a/drivers/acpi/events/evevent.c
+++ b/drivers/acpi/events/evevent.c
@@ -47,6 +47,16 @@
 #define _COMPONENT          ACPI_EVENTS
 	 ACPI_MODULE_NAME    ("evevent")
 
+/* Local prototypes */
+
+static acpi_status
+acpi_ev_fixed_event_initialize (
+	void);
+
+static u32
+acpi_ev_fixed_event_dispatch (
+	u32                             event);
+
 
 /*******************************************************************************
  *
@@ -56,7 +66,7 @@
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Initialize global data structures for events.
+ * DESCRIPTION: Initialize global data structures for ACPI events (Fixed, GPE)
  *
  ******************************************************************************/
 
@@ -78,9 +88,9 @@ acpi_ev_initialize_events (
 	}
 
 	/*
-	 * Initialize the Fixed and General Purpose Events. This is
-	 * done prior to enabling SCIs to prevent interrupts from
-	 * occurring before handers are installed.
+	 * Initialize the Fixed and General Purpose Events. This is done prior to
+	 * enabling SCIs to prevent interrupts from occurring before the handlers are
+	 * installed.
 	 */
 	status = acpi_ev_fixed_event_initialize ();
 	if (ACPI_FAILURE (status)) {
@@ -161,7 +171,7 @@ acpi_ev_install_xrupt_handlers (
  *
  ******************************************************************************/
 
-acpi_status
+static acpi_status
 acpi_ev_fixed_event_initialize (
 	void)
 {
@@ -180,7 +190,8 @@ acpi_ev_fixed_event_initialize (
 		/* Enable the fixed event */
 
 		if (acpi_gbl_fixed_event_info[i].enable_register_id != 0xFF) {
-			status = acpi_set_register (acpi_gbl_fixed_event_info[i].enable_register_id,
+			status = acpi_set_register (
+					 acpi_gbl_fixed_event_info[i].enable_register_id,
 					 0, ACPI_MTX_LOCK);
 			if (ACPI_FAILURE (status)) {
 				return (status);
@@ -200,7 +211,7 @@ acpi_ev_fixed_event_initialize (
  *
  * RETURN:      INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED
  *
- * DESCRIPTION: Checks the PM status register for fixed events
+ * DESCRIPTION: Checks the PM status register for active fixed events
  *
  ******************************************************************************/
 
@@ -221,8 +232,10 @@ acpi_ev_fixed_event_detect (
 	 * Read the fixed feature status and enable registers, as all the cases
 	 * depend on their values.  Ignore errors here.
 	 */
-	(void) acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1_STATUS, &fixed_status);
-	(void) acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1_ENABLE, &fixed_enable);
+	(void) acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1_STATUS,
+			 &fixed_status);
+	(void) acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1_ENABLE,
+			 &fixed_enable);
 
 	ACPI_DEBUG_PRINT ((ACPI_DB_INTERRUPTS,
 		"Fixed Event Block: Enable %08X Status %08X\n",
@@ -259,7 +272,7 @@ acpi_ev_fixed_event_detect (
  *
  ******************************************************************************/
 
-u32
+static u32
 acpi_ev_fixed_event_dispatch (
 	u32                             event)
 {
diff --git a/drivers/acpi/events/evgpe.c b/drivers/acpi/events/evgpe.c
--- a/drivers/acpi/events/evgpe.c
+++ b/drivers/acpi/events/evgpe.c
@@ -48,6 +48,12 @@
 #define _COMPONENT          ACPI_EVENTS
 	 ACPI_MODULE_NAME    ("evgpe")
 
+/* Local prototypes */
+
+static void ACPI_SYSTEM_XFACE
+acpi_ev_asynch_execute_gpe_method (
+	void                            *context);
+
 
 /*******************************************************************************
  *
@@ -335,8 +341,10 @@ acpi_ev_get_gpe_event_info (
 			gpe_block = acpi_gbl_gpe_fadt_blocks[i];
 			if (gpe_block) {
 				if ((gpe_number >= gpe_block->block_base_number) &&
-					(gpe_number < gpe_block->block_base_number + (gpe_block->register_count * 8))) {
-					return (&gpe_block->event_info[gpe_number - gpe_block->block_base_number]);
+					(gpe_number < gpe_block->block_base_number +
+						(gpe_block->register_count * 8))) {
+					return (&gpe_block->event_info[gpe_number -
+						gpe_block->block_base_number]);
 				}
 			}
 		}
@@ -437,7 +445,7 @@ acpi_ev_gpe_detect (
 				"Read GPE Register at GPE%X: Status=%02X, Enable=%02X\n",
 				gpe_register_info->base_gpe_number, status_reg, enable_reg));
 
-			/* First check if there is anything active at all in this register */
+			/* Check if there is anything active at all in this register */
 
 			enabled_status_byte = (u8) (status_reg & enable_reg);
 			if (!enabled_status_byte) {
@@ -457,8 +465,8 @@ acpi_ev_gpe_detect (
 					 * or method.
 					 */
 					int_status |= acpi_ev_gpe_dispatch (
-							  &gpe_block->event_info[(i * ACPI_GPE_REGISTER_WIDTH) + j],
-							  (u32) j + gpe_register_info->base_gpe_number);
+						&gpe_block->event_info[(i * ACPI_GPE_REGISTER_WIDTH) + j],
+						(u32) j + gpe_register_info->base_gpe_number);
 				}
 			}
 		}
@@ -523,7 +531,8 @@ acpi_ev_asynch_execute_gpe_method (
 	 * Take a snapshot of the GPE info for this level - we copy the
 	 * info to prevent a race condition with remove_handler/remove_block.
 	 */
-	ACPI_MEMCPY (&local_gpe_event_info, gpe_event_info, sizeof (struct acpi_gpe_event_info));
+	ACPI_MEMCPY (&local_gpe_event_info, gpe_event_info,
+		sizeof (struct acpi_gpe_event_info));
 
 	status = acpi_ut_release_mutex (ACPI_MTX_EVENTS);
 	if (ACPI_FAILURE (status)) {
@@ -534,7 +543,8 @@ acpi_ev_asynch_execute_gpe_method (
 	 * Must check for control method type dispatch one more
 	 * time to avoid race with ev_gpe_install_handler
 	 */
-	if ((local_gpe_event_info.flags & ACPI_GPE_DISPATCH_MASK) == ACPI_GPE_DISPATCH_METHOD) {
+	if ((local_gpe_event_info.flags & ACPI_GPE_DISPATCH_MASK) ==
+			ACPI_GPE_DISPATCH_METHOD) {
 		/*
 		 * Invoke the GPE Method (_Lxx, _Exx) i.e., evaluate the _Lxx/_Exx
 		 * control method that corresponds to this GPE
@@ -553,7 +563,8 @@ acpi_ev_asynch_execute_gpe_method (
 		}
 	}
 
-	if ((local_gpe_event_info.flags & ACPI_GPE_XRUPT_TYPE_MASK) == ACPI_GPE_LEVEL_TRIGGERED) {
+	if ((local_gpe_event_info.flags & ACPI_GPE_XRUPT_TYPE_MASK) ==
+			ACPI_GPE_LEVEL_TRIGGERED) {
 		/*
 		 * GPE is level-triggered, we clear the GPE status bit after
 		 * handling the event.
@@ -575,7 +586,7 @@ acpi_ev_asynch_execute_gpe_method (
  *
  * FUNCTION:    acpi_ev_gpe_dispatch
  *
- * PARAMETERS:  gpe_event_info  - info for this GPE
+ * PARAMETERS:  gpe_event_info  - Info for this GPE
  *              gpe_number      - Number relative to the parent GPE block
  *
  * RETURN:      INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED
@@ -602,10 +613,12 @@ acpi_ev_gpe_dispatch (
 	 * If edge-triggered, clear the GPE status bit now.  Note that
 	 * level-triggered events are cleared after the GPE is serviced.
 	 */
-	if ((gpe_event_info->flags & ACPI_GPE_XRUPT_TYPE_MASK) == ACPI_GPE_EDGE_TRIGGERED) {
+	if ((gpe_event_info->flags & ACPI_GPE_XRUPT_TYPE_MASK) ==
+			ACPI_GPE_EDGE_TRIGGERED) {
 		status = acpi_hw_clear_gpe (gpe_event_info);
 		if (ACPI_FAILURE (status)) {
-			ACPI_REPORT_ERROR (("acpi_ev_gpe_dispatch: %s, Unable to clear GPE[%2X]\n",
+			ACPI_REPORT_ERROR ((
+				"acpi_ev_gpe_dispatch: %s, Unable to clear GPE[%2X]\n",
 				acpi_format_exception (status), gpe_number));
 			return_VALUE (ACPI_INTERRUPT_NOT_HANDLED);
 		}
@@ -639,7 +652,8 @@ acpi_ev_gpe_dispatch (
 
 		/* It is now safe to clear level-triggered events. */
 
-		if ((gpe_event_info->flags & ACPI_GPE_XRUPT_TYPE_MASK) == ACPI_GPE_LEVEL_TRIGGERED) {
+		if ((gpe_event_info->flags & ACPI_GPE_XRUPT_TYPE_MASK) ==
+				ACPI_GPE_LEVEL_TRIGGERED) {
 			status = acpi_hw_clear_gpe (gpe_event_info);
 			if (ACPI_FAILURE (status)) {
 				ACPI_REPORT_ERROR ((
@@ -704,7 +718,6 @@ acpi_ev_gpe_dispatch (
 
 
 #ifdef ACPI_GPE_NOTIFY_CHECK
-
 /*******************************************************************************
  * TBD: NOT USED, PROTOTYPE ONLY AND WILL PROBABLY BE REMOVED
  *
diff --git a/drivers/acpi/events/evgpeblk.c b/drivers/acpi/events/evgpeblk.c
--- a/drivers/acpi/events/evgpeblk.c
+++ b/drivers/acpi/events/evgpeblk.c
@@ -48,6 +48,39 @@
 #define _COMPONENT          ACPI_EVENTS
 	 ACPI_MODULE_NAME    ("evgpeblk")
 
+/* Local prototypes */
+
+static acpi_status
+acpi_ev_save_method_info (
+	acpi_handle                     obj_handle,
+	u32                             level,
+	void                            *obj_desc,
+	void                            **return_value);
+
+static acpi_status
+acpi_ev_match_prw_and_gpe (
+	acpi_handle                     obj_handle,
+	u32                             level,
+	void                            *info,
+	void                            **return_value);
+
+static struct acpi_gpe_xrupt_info *
+acpi_ev_get_gpe_xrupt_block (
+	u32                             interrupt_level);
+
+static acpi_status
+acpi_ev_delete_gpe_xrupt (
+	struct acpi_gpe_xrupt_info      *gpe_xrupt);
+
+static acpi_status
+acpi_ev_install_gpe_block (
+	struct acpi_gpe_block_info      *gpe_block,
+	u32                             interrupt_level);
+
+static acpi_status
+acpi_ev_create_gpe_info_blocks (
+	struct acpi_gpe_block_info      *gpe_block);
+
 
 /*******************************************************************************
  *
@@ -155,7 +188,7 @@ unlock_and_exit:
 }
 
 
-/******************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    acpi_ev_delete_gpe_handlers
  *
@@ -190,7 +223,8 @@ acpi_ev_delete_gpe_handlers (
 		for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) {
 			gpe_event_info = &gpe_block->event_info[(i * ACPI_GPE_REGISTER_WIDTH) + j];
 
-			if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) == ACPI_GPE_DISPATCH_HANDLER) {
+			if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) ==
+					ACPI_GPE_DISPATCH_HANDLER) {
 				ACPI_MEM_FREE (gpe_event_info->dispatch.handler);
 				gpe_event_info->dispatch.handler = NULL;
 				gpe_event_info->flags &= ~ACPI_GPE_DISPATCH_MASK;
@@ -471,7 +505,7 @@ acpi_ev_get_gpe_xrupt_block (
 	ACPI_FUNCTION_TRACE ("ev_get_gpe_xrupt_block");
 
 
-	/* No need for spin lock since we are not changing any list elements here */
+	/* No need for lock since we are not changing any list elements here */
 
 	next_gpe_xrupt = acpi_gbl_gpe_xrupt_list_head;
 	while (next_gpe_xrupt) {
@@ -619,7 +653,7 @@ acpi_ev_install_gpe_block (
 		goto unlock_and_exit;
 	}
 
-	/* Install the new block at the end of the list for this interrupt with lock */
+	/* Install the new block at the end of the list with lock */
 
 	acpi_os_acquire_lock (acpi_gbl_gpe_lock, ACPI_NOT_ISR);
 	if (gpe_xrupt_block->gpe_block_list_head) {
@@ -756,10 +790,12 @@ acpi_ev_create_gpe_info_blocks (
 	 * per register.  Initialization to zeros is sufficient.
 	 */
 	gpe_event_info = ACPI_MEM_CALLOCATE (
-			   ((acpi_size) gpe_block->register_count * ACPI_GPE_REGISTER_WIDTH) *
+			   ((acpi_size) gpe_block->register_count *
+			   ACPI_GPE_REGISTER_WIDTH) *
 			   sizeof (struct acpi_gpe_event_info));
 	if (!gpe_event_info) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not allocate the gpe_event_info table\n"));
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"Could not allocate the gpe_event_info table\n"));
 		status = AE_NO_MEMORY;
 		goto error_exit;
 	}
@@ -899,7 +935,8 @@ acpi_ev_create_gpe_block (
 	gpe_block->block_base_number = gpe_block_base_number;
 	gpe_block->node           = gpe_device;
 
-	ACPI_MEMCPY (&gpe_block->block_address, gpe_block_address, sizeof (struct acpi_generic_address));
+	ACPI_MEMCPY (&gpe_block->block_address, gpe_block_address,
+		sizeof (struct acpi_generic_address));
 
 	/* Create the register_info and event_info sub-structures */
 
@@ -1061,8 +1098,9 @@ acpi_ev_gpe_initialize (
 
 		/* Install GPE Block 0 */
 
-		status = acpi_ev_create_gpe_block (acpi_gbl_fadt_gpe_device, &acpi_gbl_FADT->xgpe0_blk,
-				 register_count0, 0, acpi_gbl_FADT->sci_int, &acpi_gbl_gpe_fadt_blocks[0]);
+		status = acpi_ev_create_gpe_block (acpi_gbl_fadt_gpe_device,
+				 &acpi_gbl_FADT->xgpe0_blk, register_count0, 0,
+				 acpi_gbl_FADT->sci_int, &acpi_gbl_gpe_fadt_blocks[0]);
 
 		if (ACPI_FAILURE (status)) {
 			ACPI_REPORT_ERROR ((
@@ -1094,8 +1132,9 @@ acpi_ev_gpe_initialize (
 		else {
 			/* Install GPE Block 1 */
 
-			status = acpi_ev_create_gpe_block (acpi_gbl_fadt_gpe_device, &acpi_gbl_FADT->xgpe1_blk,
-					 register_count1, acpi_gbl_FADT->gpe1_base,
+			status = acpi_ev_create_gpe_block (acpi_gbl_fadt_gpe_device,
+					 &acpi_gbl_FADT->xgpe1_blk, register_count1,
+					 acpi_gbl_FADT->gpe1_base,
 					 acpi_gbl_FADT->sci_int, &acpi_gbl_gpe_fadt_blocks[1]);
 
 			if (ACPI_FAILURE (status)) {
@@ -1109,7 +1148,7 @@ acpi_ev_gpe_initialize (
 			 * space. However, GPE0 always starts at GPE number zero.
 			 */
 			gpe_number_max = acpi_gbl_FADT->gpe1_base +
-					   ((register_count1 * ACPI_GPE_REGISTER_WIDTH) - 1);
+					  ((register_count1 * ACPI_GPE_REGISTER_WIDTH) - 1);
 		}
 	}
 
diff --git a/drivers/acpi/events/evmisc.c b/drivers/acpi/events/evmisc.c
--- a/drivers/acpi/events/evmisc.c
+++ b/drivers/acpi/events/evmisc.c
@@ -50,6 +50,35 @@
 	 ACPI_MODULE_NAME    ("evmisc")
 
 
+#ifdef ACPI_DEBUG_OUTPUT
+static const char                *acpi_notify_value_names[] =
+{
+	"Bus Check",
+	"Device Check",
+	"Device Wake",
+	"Eject request",
+	"Device Check Light",
+	"Frequency Mismatch",
+	"Bus Mode Mismatch",
+	"Power Fault"
+};
+#endif
+
+/* Local prototypes */
+
+static void ACPI_SYSTEM_XFACE
+acpi_ev_notify_dispatch (
+	void                            *context);
+
+static void ACPI_SYSTEM_XFACE
+acpi_ev_global_lock_thread (
+	void                            *context);
+
+static u32
+acpi_ev_global_lock_handler (
+	void                            *context);
+
+
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ev_is_notify_object
@@ -98,20 +127,6 @@ acpi_ev_is_notify_object (
  *
  ******************************************************************************/
 
-#ifdef ACPI_DEBUG_OUTPUT
-static const char                *acpi_notify_value_names[] =
-{
-	"Bus Check",
-	"Device Check",
-	"Device Wake",
-	"Eject request",
-	"Device Check Light",
-	"Frequency Mismatch",
-	"Bus Mode Mismatch",
-	"Power Fault"
-};
-#endif
-
 acpi_status
 acpi_ev_queue_notify_request (
 	struct acpi_namespace_node      *node,
@@ -128,9 +143,10 @@ acpi_ev_queue_notify_request (
 
 	/*
 	 * For value 3 (Ejection Request), some device method may need to be run.
-	 * For value 2 (Device Wake) if _PRW exists, the _PS0 method may need to be run.
+	 * For value 2 (Device Wake) if _PRW exists, the _PS0 method may need
+	 *   to be run.
 	 * For value 0x80 (Status Change) on the power button or sleep button,
-	 * initiate soft-off or sleep operation?
+	 *   initiate soft-off or sleep operation?
 	 */
 	ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
 		"Dispatching Notify(%X) on node %p\n", notify_value, node));
@@ -140,8 +156,9 @@ acpi_ev_queue_notify_request (
 				acpi_notify_value_names[notify_value]));
 	}
 	else {
-		ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Notify value: 0x%2.2X **Device Specific**\n",
-				notify_value));
+		ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+			"Notify value: 0x%2.2X **Device Specific**\n",
+			notify_value));
 	}
 
 	/* Get the notify object attached to the NS Node */
@@ -210,7 +227,7 @@ acpi_ev_queue_notify_request (
  *
  * FUNCTION:    acpi_ev_notify_dispatch
  *
- * PARAMETERS:  Context         - To be passsed to the notify handler
+ * PARAMETERS:  Context         - To be passed to the notify handler
  *
  * RETURN:      None.
  *
@@ -219,7 +236,7 @@ acpi_ev_queue_notify_request (
  *
  ******************************************************************************/
 
-void ACPI_SYSTEM_XFACE
+static void ACPI_SYSTEM_XFACE
 acpi_ev_notify_dispatch (
 	void                            *context)
 {
@@ -234,7 +251,8 @@ acpi_ev_notify_dispatch (
 
 	/*
 	 * We will invoke a global notify handler if installed.
-	 * This is done _before_ we invoke the per-device handler attached to the device.
+	 * This is done _before_ we invoke the per-device handler attached
+	 * to the device.
 	 */
 	if (notify_info->notify.value <= ACPI_MAX_SYS_NOTIFY) {
 		/* Global system notification handler */
@@ -256,15 +274,17 @@ acpi_ev_notify_dispatch (
 	/* Invoke the system handler first, if present */
 
 	if (global_handler) {
-		global_handler (notify_info->notify.node, notify_info->notify.value, global_context);
+		global_handler (notify_info->notify.node, notify_info->notify.value,
+			global_context);
 	}
 
 	/* Now invoke the per-device handler, if present */
 
 	handler_obj = notify_info->notify.handler_obj;
 	if (handler_obj) {
-		handler_obj->notify.handler (notify_info->notify.node, notify_info->notify.value,
-				  handler_obj->notify.context);
+		handler_obj->notify.handler (notify_info->notify.node,
+			notify_info->notify.value,
+			handler_obj->notify.context);
 	}
 
 	/* All done with the info object */
@@ -370,7 +390,8 @@ acpi_ev_global_lock_handler (
  ******************************************************************************/
 
 acpi_status
-acpi_ev_init_global_lock_handler (void)
+acpi_ev_init_global_lock_handler (
+	void)
 {
 	acpi_status                     status;
 
@@ -380,7 +401,7 @@ acpi_ev_init_global_lock_handler (void)
 
 	acpi_gbl_global_lock_present = TRUE;
 	status = acpi_install_fixed_event_handler (ACPI_EVENT_GLOBAL,
-			  acpi_ev_global_lock_handler, NULL);
+			 acpi_ev_global_lock_handler, NULL);
 
 	/*
 	 * If the global lock does not exist on this platform, the attempt
@@ -433,8 +454,10 @@ acpi_ev_acquire_global_lock (
 
 	acpi_gbl_global_lock_thread_count++;
 
-	/* If we (OS side vs. BIOS side) have the hardware lock already, we are done */
-
+	/*
+	 * If we (OS side vs. BIOS side) have the hardware lock already,
+	 * we are done
+	 */
 	if (acpi_gbl_global_lock_acquired) {
 		return_ACPI_STATUS (AE_OK);
 	}
@@ -480,7 +503,8 @@ acpi_ev_acquire_global_lock (
  ******************************************************************************/
 
 acpi_status
-acpi_ev_release_global_lock (void)
+acpi_ev_release_global_lock (
+	void)
 {
 	u8                              pending = FALSE;
 	acpi_status                     status = AE_OK;
@@ -490,7 +514,8 @@ acpi_ev_release_global_lock (void)
 
 
 	if (!acpi_gbl_global_lock_thread_count) {
-		ACPI_REPORT_WARNING(("Cannot release HW Global Lock, it has not been acquired\n"));
+		ACPI_REPORT_WARNING((
+			"Cannot release HW Global Lock, it has not been acquired\n"));
 		return_ACPI_STATUS (AE_NOT_ACQUIRED);
 	}
 
@@ -515,7 +540,8 @@ acpi_ev_release_global_lock (void)
 	 * register
 	 */
 	if (pending) {
-		status = acpi_set_register (ACPI_BITREG_GLOBAL_LOCK_RELEASE, 1, ACPI_MTX_LOCK);
+		status = acpi_set_register (ACPI_BITREG_GLOBAL_LOCK_RELEASE,
+				 1, ACPI_MTX_LOCK);
 	}
 
 	return_ACPI_STATUS (status);
@@ -535,7 +561,8 @@ acpi_ev_release_global_lock (void)
  ******************************************************************************/
 
 void
-acpi_ev_terminate (void)
+acpi_ev_terminate (
+	void)
 {
 	acpi_native_uint                i;
 	acpi_status                     status;
@@ -555,7 +582,8 @@ acpi_ev_terminate (void)
 		for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) {
 			status = acpi_disable_event ((u32) i, 0);
 			if (ACPI_FAILURE (status)) {
-				ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not disable fixed event %d\n", (u32) i));
+				ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+					"Could not disable fixed event %d\n", (u32) i));
 			}
 		}
 
@@ -567,7 +595,8 @@ acpi_ev_terminate (void)
 
 		status = acpi_ev_remove_sci_handler ();
 		if (ACPI_FAILURE(status)) {
-			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not remove SCI handler\n"));
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+				"Could not remove SCI handler\n"));
 		}
 	}
 
diff --git a/drivers/acpi/events/evregion.c b/drivers/acpi/events/evregion.c
--- a/drivers/acpi/events/evregion.c
+++ b/drivers/acpi/events/evregion.c
@@ -58,6 +58,22 @@ static u8                   acpi_gbl_def
 			 ACPI_ADR_SPACE_PCI_CONFIG,
 			 ACPI_ADR_SPACE_DATA_TABLE};
 
+/* Local prototypes */
+
+static acpi_status
+acpi_ev_reg_run (
+	acpi_handle                     obj_handle,
+	u32                             level,
+	void                            *context,
+	void                            **return_value);
+
+static acpi_status
+acpi_ev_install_handler (
+	acpi_handle                     obj_handle,
+	u32                             level,
+	void                            *context,
+	void                            **return_value);
+
 
 /*******************************************************************************
  *
@@ -179,8 +195,8 @@ acpi_ev_initialize_op_regions (
  *
  * FUNCTION:    acpi_ev_execute_reg_method
  *
- * PARAMETERS:  region_obj          - Object structure
- *              Function            - Passed to _REG:  On (1) or Off (0)
+ * PARAMETERS:  region_obj          - Region object
+ *              Function            - Passed to _REG: On (1) or Off (0)
  *
  * RETURN:      Status
  *
@@ -323,14 +339,16 @@ acpi_ev_address_space_dispatch (
 		if (!region_setup) {
 			/* No initialization routine, exit with error */
 
-			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No init routine for region(%p) [%s]\n",
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+				"No init routine for region(%p) [%s]\n",
 				region_obj, acpi_ut_get_region_name (region_obj->region.space_id)));
 			return_ACPI_STATUS (AE_NOT_EXIST);
 		}
 
 		/*
-		 * We must exit the interpreter because the region setup will potentially
-		 * execute control methods (e.g., _REG method for this region)
+		 * We must exit the interpreter because the region
+		 * setup will potentially execute control methods
+		 * (e.g., _REG method for this region)
 		 */
 		acpi_ex_exit_interpreter ();
 
@@ -621,7 +639,7 @@ acpi_ev_attach_region (
  *
  ******************************************************************************/
 
-acpi_status
+static acpi_status
 acpi_ev_install_handler (
 	acpi_handle                     obj_handle,
 	u32                             level,
@@ -848,7 +866,8 @@ acpi_ev_install_space_handler (
 				if (handler_obj->address_space.handler == handler) {
 					/*
 					 * It is (relatively) OK to attempt to install the SAME
-					 * handler twice. This can easily happen with PCI_Config space.
+					 * handler twice. This can easily happen
+					 * with PCI_Config space.
 					 */
 					status = AE_SAME_HANDLER;
 					goto unlock_and_exit;
@@ -1011,7 +1030,7 @@ acpi_ev_execute_reg_methods (
  *
  ******************************************************************************/
 
-acpi_status
+static acpi_status
 acpi_ev_reg_run (
 	acpi_handle                     obj_handle,
 	u32                             level,
diff --git a/drivers/acpi/events/evrgnini.c b/drivers/acpi/events/evrgnini.c
--- a/drivers/acpi/events/evrgnini.c
+++ b/drivers/acpi/events/evrgnini.c
@@ -61,7 +61,7 @@
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Do any prep work for region handling, a nop for now
+ * DESCRIPTION: Setup a system_memory operation region
  *
  ******************************************************************************/
 
@@ -115,7 +115,7 @@ acpi_ev_system_memory_region_setup (
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Do any prep work for region handling
+ * DESCRIPTION: Setup a IO operation region
  *
  ******************************************************************************/
 
@@ -144,14 +144,14 @@ acpi_ev_io_space_region_setup (
  *
  * FUNCTION:    acpi_ev_pci_config_region_setup
  *
- * PARAMETERS:  Handle             - Region we are interested in
+ * PARAMETERS:  Handle              - Region we are interested in
  *              Function            - Start or stop
  *              handler_context     - Address space handler context
  *              region_context      - Region specific context
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Do any prep work for region handling
+ * DESCRIPTION: Setup a PCI_Config operation region
  *
  * MUTEX:       Assumes namespace is not locked
  *
@@ -324,7 +324,7 @@ acpi_ev_pci_config_region_setup (
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Do any prep work for region handling
+ * DESCRIPTION: Setup a pci_bAR operation region
  *
  * MUTEX:       Assumes namespace is not locked
  *
@@ -355,7 +355,7 @@ acpi_ev_pci_bar_region_setup (
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Do any prep work for region handling
+ * DESCRIPTION: Setup a CMOS operation region
  *
  * MUTEX:       Assumes namespace is not locked
  *
@@ -386,7 +386,7 @@ acpi_ev_cmos_region_setup (
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Do any prep work for region handling
+ * DESCRIPTION: Default region initialization
  *
  ******************************************************************************/
 
diff --git a/drivers/acpi/events/evsci.c b/drivers/acpi/events/evsci.c
--- a/drivers/acpi/events/evsci.c
+++ b/drivers/acpi/events/evsci.c
@@ -49,6 +49,12 @@
 #define _COMPONENT          ACPI_EVENTS
 	 ACPI_MODULE_NAME    ("evsci")
 
+/* Local prototypes */
+
+static u32 ACPI_SYSTEM_XFACE
+acpi_ev_sci_xrupt_handler (
+	void                            *context);
+
 
 /*******************************************************************************
  *
@@ -146,7 +152,8 @@ acpi_ev_gpe_xrupt_handler (
  ******************************************************************************/
 
 u32
-acpi_ev_install_sci_handler (void)
+acpi_ev_install_sci_handler (
+	void)
 {
 	u32                             status = AE_OK;
 
@@ -180,7 +187,8 @@ acpi_ev_install_sci_handler (void)
  ******************************************************************************/
 
 acpi_status
-acpi_ev_remove_sci_handler (void)
+acpi_ev_remove_sci_handler (
+	void)
 {
 	acpi_status                     status;
 
diff --git a/drivers/acpi/events/evxface.c b/drivers/acpi/events/evxface.c
--- a/drivers/acpi/events/evxface.c
+++ b/drivers/acpi/events/evxface.c
@@ -64,6 +64,7 @@
  * DESCRIPTION: Saves the pointer to the handler function
  *
  ******************************************************************************/
+
 #ifdef ACPI_FUTURE_USAGE
 acpi_status
 acpi_install_exception_handler (
@@ -457,7 +458,8 @@ acpi_remove_notify_handler (
 	/* Root Object */
 
 	if (device == ACPI_ROOT_OBJECT) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Removing notify handler for ROOT object.\n"));
+		ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+			"Removing notify handler for ROOT object.\n"));
 
 		if (((handler_type & ACPI_SYSTEM_NOTIFY) &&
 			  !acpi_gbl_system_notify.handler)      ||
@@ -564,8 +566,9 @@ EXPORT_SYMBOL(acpi_remove_notify_handler
  *
  * FUNCTION:    acpi_install_gpe_handler
  *
- * PARAMETERS:  gpe_number      - The GPE number within the GPE block
- *              gpe_block       - GPE block (NULL == FADT GPEs)
+ * PARAMETERS:  gpe_device      - Namespace node for the GPE (NULL for FADT
+ *                                defined GPEs)
+ *              gpe_number      - The GPE number within the GPE block
  *              Type            - Whether this GPE should be treated as an
  *                                edge- or level-triggered interrupt.
  *              Address         - Address of the handler
@@ -662,8 +665,9 @@ EXPORT_SYMBOL(acpi_install_gpe_handler);
  *
  * FUNCTION:    acpi_remove_gpe_handler
  *
- * PARAMETERS:  gpe_number      - The event to remove a handler
- *              gpe_block       - GPE block (NULL == FADT GPEs)
+ * PARAMETERS:  gpe_device      - Namespace node for the GPE (NULL for FADT
+ *                                defined GPEs)
+ *              gpe_number      - The event to remove a handler
  *              Address         - Address of the handler
  *
  * RETURN:      Status
@@ -766,7 +770,8 @@ EXPORT_SYMBOL(acpi_remove_gpe_handler);
  * FUNCTION:    acpi_acquire_global_lock
  *
  * PARAMETERS:  Timeout         - How long the caller is willing to wait
- *              out_handle      - A handle to the lock if acquired
+ *              Handle          - Where the handle to the lock is returned
+ *                                (if acquired)
  *
  * RETURN:      Status
  *
@@ -812,7 +817,7 @@ EXPORT_SYMBOL(acpi_acquire_global_lock);
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Release the ACPI Global Lock
+ * DESCRIPTION: Release the ACPI Global Lock. The handle must be valid.
  *
  ******************************************************************************/
 
diff --git a/drivers/acpi/events/evxfevnt.c b/drivers/acpi/events/evxfevnt.c
--- a/drivers/acpi/events/evxfevnt.c
+++ b/drivers/acpi/events/evxfevnt.c
@@ -64,7 +64,8 @@
  ******************************************************************************/
 
 acpi_status
-acpi_enable (void)
+acpi_enable (
+	void)
 {
 	acpi_status                     status = AE_OK;
 
@@ -91,7 +92,8 @@ acpi_enable (void)
 			return_ACPI_STATUS (status);
 		}
 
-		ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "Transition to ACPI mode successful\n"));
+		ACPI_DEBUG_PRINT ((ACPI_DB_INIT,
+			"Transition to ACPI mode successful\n"));
 	}
 
 	return_ACPI_STATUS (status);
@@ -106,12 +108,13 @@ acpi_enable (void)
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Transfers the system into LEGACY mode.
+ * DESCRIPTION: Transfers the system into LEGACY (non-ACPI) mode.
  *
  ******************************************************************************/
 
 acpi_status
-acpi_disable (void)
+acpi_disable (
+	void)
 {
 	acpi_status                     status = AE_OK;
 
@@ -125,7 +128,8 @@ acpi_disable (void)
 	}
 
 	if (acpi_hw_get_mode() == ACPI_SYS_MODE_LEGACY) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "System is already in legacy (non-ACPI) mode\n"));
+		ACPI_DEBUG_PRINT ((ACPI_DB_INIT,
+			"System is already in legacy (non-ACPI) mode\n"));
 	}
 	else {
 		/* Transition to LEGACY mode */
@@ -133,7 +137,8 @@ acpi_disable (void)
 		status = acpi_hw_set_mode (ACPI_SYS_MODE_LEGACY);
 
 		if (ACPI_FAILURE (status)) {
-			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not exit ACPI mode to legacy mode"));
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+				"Could not exit ACPI mode to legacy mode"));
 			return_ACPI_STATUS (status);
 		}
 
@@ -214,7 +219,7 @@ EXPORT_SYMBOL(acpi_enable_event);
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Enable an ACPI event (general purpose)
+ * DESCRIPTION: Set the type of an individual GPE
  *
  ******************************************************************************/
 
@@ -519,13 +524,12 @@ unlock_and_exit:
 
 
 #ifdef ACPI_FUTURE_USAGE
-
 /*******************************************************************************
  *
  * FUNCTION:    acpi_get_event_status
  *
  * PARAMETERS:  Event           - The fixed event
- *              Event Status    - Where the current status of the event will
+ *              event_status    - Where the current status of the event will
  *                                be returned
  *
  * RETURN:      Status
@@ -571,7 +575,7 @@ acpi_get_event_status (
  * PARAMETERS:  gpe_device      - Parent GPE Device
  *              gpe_number      - GPE level within the GPE block
  *              Flags           - Called from an ISR or not
- *              Event Status    - Where the current status of the event will
+ *              event_status    - Where the current status of the event will
  *                                be returned
  *
  * RETURN:      Status
@@ -775,4 +779,5 @@ unlock_and_exit:
 	(void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
 	return_ACPI_STATUS (status);
 }
+
 EXPORT_SYMBOL(acpi_remove_gpe_block);
diff --git a/drivers/acpi/executer/exconfig.c b/drivers/acpi/executer/exconfig.c
--- a/drivers/acpi/executer/exconfig.c
+++ b/drivers/acpi/executer/exconfig.c
@@ -54,6 +54,14 @@
 #define _COMPONENT          ACPI_EXECUTER
 	 ACPI_MODULE_NAME    ("exconfig")
 
+/* Local prototypes */
+
+static acpi_status
+acpi_ex_add_table (
+	struct acpi_table_header        *table,
+	struct acpi_namespace_node      *parent_node,
+	union acpi_operand_object       **ddb_handle);
+
 
 /*******************************************************************************
  *
@@ -70,7 +78,7 @@
  *
  ******************************************************************************/
 
-acpi_status
+static acpi_status
 acpi_ex_add_table (
 	struct acpi_table_header        *table,
 	struct acpi_namespace_node      *parent_node,
@@ -95,10 +103,10 @@ acpi_ex_add_table (
 
 	ACPI_MEMSET (&table_info, 0, sizeof (struct acpi_table_desc));
 
-	table_info.type        = ACPI_TABLE_SSDT;
-	table_info.pointer     = table;
-	table_info.length      = (acpi_size) table->length;
-	table_info.allocation  = ACPI_MEM_ALLOCATED;
+	table_info.type      = ACPI_TABLE_SSDT;
+	table_info.pointer   = table;
+	table_info.length    = (acpi_size) table->length;
+	table_info.allocation = ACPI_MEM_ALLOCATED;
 
 	status = acpi_tb_install_table (&table_info);
 	if (ACPI_FAILURE (status)) {
@@ -226,11 +234,10 @@ acpi_ex_load_table_op (
 			start_node = parent_node;
 		}
 
-		/*
-		 * Find the node referenced by the parameter_path_string
-		 */
+		/* Find the node referenced by the parameter_path_string */
+
 		status = acpi_ns_get_node_by_path (operand[4]->string.pointer, start_node,
-				   ACPI_NS_SEARCH_PARENT, &parameter_node);
+				 ACPI_NS_SEARCH_PARENT, &parameter_node);
 		if (ACPI_FAILURE (status)) {
 			return_ACPI_STATUS (status);
 		}
@@ -248,7 +255,8 @@ acpi_ex_load_table_op (
 	if (parameter_node) {
 		/* Store the parameter data into the optional parameter object */
 
-		status = acpi_ex_store (operand[5], ACPI_CAST_PTR (union acpi_operand_object, parameter_node),
+		status = acpi_ex_store (operand[5],
+				 ACPI_CAST_PTR (union acpi_operand_object, parameter_node),
 				 walk_state);
 		if (ACPI_FAILURE (status)) {
 			(void) acpi_ex_unload_table (ddb_handle);
@@ -371,7 +379,8 @@ acpi_ex_load_op (
 			goto cleanup;
 		}
 
-		table_ptr = ACPI_CAST_PTR (struct acpi_table_header, buffer_desc->buffer.pointer);
+		table_ptr = ACPI_CAST_PTR (struct acpi_table_header,
+				  buffer_desc->buffer.pointer);
 
 		 /* Sanity check the table length */
 
diff --git a/drivers/acpi/executer/exconvrt.c b/drivers/acpi/executer/exconvrt.c
--- a/drivers/acpi/executer/exconvrt.c
+++ b/drivers/acpi/executer/exconvrt.c
@@ -50,6 +50,15 @@
 #define _COMPONENT          ACPI_EXECUTER
 	 ACPI_MODULE_NAME    ("exconvrt")
 
+/* Local prototypes */
+
+static u32
+acpi_ex_convert_to_ascii (
+	acpi_integer                    integer,
+	u16                             base,
+	u8                              *string,
+	u8                              max_length);
+
 
 /*******************************************************************************
  *
@@ -115,9 +124,8 @@ acpi_ex_convert_to_integer (
 	 */
 	result = 0;
 
-	/*
-	 * String conversion is different than Buffer conversion
-	 */
+	/* String conversion is different than Buffer conversion */
+
 	switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
 	case ACPI_TYPE_STRING:
 
@@ -168,9 +176,8 @@ acpi_ex_convert_to_integer (
 		break;
 	}
 
-	/*
-	 * Create a new integer
-	 */
+	/* Create a new integer */
+
 	return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
 	if (!return_desc) {
 		return_ACPI_STATUS (AE_NO_MEMORY);
@@ -251,7 +258,8 @@ acpi_ex_convert_to_buffer (
 		 * ASL/AML code that depends on the null being transferred to the new
 		 * buffer.
 		 */
-		return_desc = acpi_ut_create_buffer_object ((acpi_size) obj_desc->string.length + 1);
+		return_desc = acpi_ut_create_buffer_object (
+				  (acpi_size) obj_desc->string.length + 1);
 		if (!return_desc) {
 			return_ACPI_STATUS (AE_NO_MEMORY);
 		}
@@ -291,7 +299,7 @@ acpi_ex_convert_to_buffer (
  *
  ******************************************************************************/
 
-u32
+static u32
 acpi_ex_convert_to_ascii (
 	acpi_integer                    integer,
 	u16                             base,
@@ -357,8 +365,9 @@ acpi_ex_convert_to_ascii (
 
 	case 16:
 
-		hex_length = ACPI_MUL_2 (data_width); /* 2 ascii hex chars per data byte */
+		/* hex_length: 2 ascii hex chars per data byte */
 
+		hex_length = ACPI_MUL_2 (data_width);
 		for (i = 0, j = (hex_length-1); i < hex_length; i++, j--) {
 			/* Get one hex digit, most significant digits first */
 
@@ -475,7 +484,7 @@ acpi_ex_convert_to_string (
 		/* Setup string length, base, and separator */
 
 		switch (type) {
-		case ACPI_EXPLICIT_CONVERT_DECIMAL: /* Used by to_decimal_string operator */
+		case ACPI_EXPLICIT_CONVERT_DECIMAL: /* Used by to_decimal_string */
 			/*
 			 * From ACPI: "If Data is a buffer, it is converted to a string of
 			 * decimal values separated by commas."
@@ -509,7 +518,7 @@ acpi_ex_convert_to_string (
 			string_length = (obj_desc->buffer.length * 3);
 			break;
 
-		case ACPI_EXPLICIT_CONVERT_HEX:     /* Used by to_hex_string operator */
+		case ACPI_EXPLICIT_CONVERT_HEX:     /* Used by to_hex_string */
 			/*
 			 * From ACPI: "If Data is a buffer, it is converted to a string of
 			 * hexadecimal values separated by commas."
@@ -530,9 +539,8 @@ acpi_ex_convert_to_string (
 			return_ACPI_STATUS (AE_AML_STRING_LIMIT);
 		}
 
-		/*
-		 * Create a new string object and string buffer
-		 */
+		/* Create a new string object and string buffer */
+
 		return_desc = acpi_ut_create_string_object ((acpi_size) string_length);
 		if (!return_desc) {
 			return_ACPI_STATUS (AE_NO_MEMORY);
@@ -551,8 +559,10 @@ acpi_ex_convert_to_string (
 			*new_buf++ = separator; /* each separated by a comma or space */
 		}
 
-		/* Null terminate the string (overwrites final comma/space from above) */
-
+		/*
+		 * Null terminate the string
+		 * (overwrites final comma/space from above)
+		 */
 		new_buf--;
 		*new_buf = 0;
 		break;
@@ -645,7 +655,6 @@ acpi_ex_convert_to_target_type (
 
 
 		case ACPI_TYPE_STRING:
-
 			/*
 			 * The operand must be a String.  We can convert an
 			 * Integer or Buffer if necessary
@@ -656,7 +665,6 @@ acpi_ex_convert_to_target_type (
 
 
 		case ACPI_TYPE_BUFFER:
-
 			/*
 			 * The operand must be a Buffer.  We can convert an
 			 * Integer or String if necessary
diff --git a/drivers/acpi/executer/excreate.c b/drivers/acpi/executer/excreate.c
--- a/drivers/acpi/executer/excreate.c
+++ b/drivers/acpi/executer/excreate.c
@@ -55,7 +55,7 @@
 
 
 #ifndef ACPI_NO_METHOD_EXECUTION
-/*****************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    acpi_ex_create_alias
  *
@@ -65,7 +65,7 @@
  *
  * DESCRIPTION: Create a new named alias
  *
- ****************************************************************************/
+ ******************************************************************************/
 
 acpi_status
 acpi_ex_create_alias (
@@ -140,8 +140,7 @@ acpi_ex_create_alias (
 		 * target node or the alias Node
 		 */
 		status = acpi_ns_attach_object (alias_node,
-				 acpi_ns_get_attached_object (target_node),
-				 target_node->type);
+				 acpi_ns_get_attached_object (target_node), target_node->type);
 		break;
 	}
 
@@ -151,7 +150,7 @@ acpi_ex_create_alias (
 }
 
 
-/*****************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    acpi_ex_create_event
  *
@@ -161,7 +160,7 @@ acpi_ex_create_alias (
  *
  * DESCRIPTION: Create a new event object
  *
- ****************************************************************************/
+ ******************************************************************************/
 
 acpi_status
 acpi_ex_create_event (
@@ -185,7 +184,7 @@ acpi_ex_create_event (
 	 * that the event is created in an unsignalled state
 	 */
 	status = acpi_os_create_semaphore (ACPI_NO_UNIT_LIMIT, 0,
-			   &obj_desc->event.semaphore);
+			 &obj_desc->event.semaphore);
 	if (ACPI_FAILURE (status)) {
 		goto cleanup;
 	}
@@ -193,7 +192,7 @@ acpi_ex_create_event (
 	/* Attach object to the Node */
 
 	status = acpi_ns_attach_object ((struct acpi_namespace_node *) walk_state->operands[0],
-			   obj_desc, ACPI_TYPE_EVENT);
+			 obj_desc, ACPI_TYPE_EVENT);
 
 cleanup:
 	/*
@@ -205,7 +204,7 @@ cleanup:
 }
 
 
-/*****************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    acpi_ex_create_mutex
  *
@@ -217,7 +216,7 @@ cleanup:
  *
  *              Mutex (Name[0], sync_level[1])
  *
- ****************************************************************************/
+ ******************************************************************************/
 
 acpi_status
 acpi_ex_create_mutex (
@@ -267,20 +266,20 @@ cleanup:
 }
 
 
-/*****************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    acpi_ex_create_region
  *
  * PARAMETERS:  aml_start           - Pointer to the region declaration AML
  *              aml_length          - Max length of the declaration AML
- *              Operands            - List of operands for the opcode
+ *              region_space        - space_iD for the region
  *              walk_state          - Current state
  *
  * RETURN:      Status
  *
  * DESCRIPTION: Create a new operation region object
  *
- ****************************************************************************/
+ ******************************************************************************/
 
 acpi_status
 acpi_ex_create_region (
@@ -321,7 +320,7 @@ acpi_ex_create_region (
 	}
 
 	ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "Region Type - %s (%X)\n",
-			  acpi_ut_get_region_name (region_space), region_space));
+		acpi_ut_get_region_name (region_space), region_space));
 
 	/* Create the region descriptor */
 
@@ -360,7 +359,7 @@ cleanup:
 }
 
 
-/*****************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    acpi_ex_create_table_region
  *
@@ -370,7 +369,7 @@ cleanup:
  *
  * DESCRIPTION: Create a new data_table_region object
  *
- ****************************************************************************/
+ ******************************************************************************/
 
 acpi_status
 acpi_ex_create_table_region (
@@ -455,7 +454,7 @@ cleanup:
 }
 
 
-/*****************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    acpi_ex_create_processor
  *
@@ -467,7 +466,7 @@ cleanup:
  *
  *              Processor (Name[0], cpu_iD[1], pblock_addr[2], pblock_length[3])
  *
- ****************************************************************************/
+ ******************************************************************************/
 
 acpi_status
 acpi_ex_create_processor (
@@ -488,9 +487,8 @@ acpi_ex_create_processor (
 		return_ACPI_STATUS (AE_NO_MEMORY);
 	}
 
-	/*
-	 * Initialize the processor object from the operands
-	 */
+	/* Initialize the processor object from the operands */
+
 	obj_desc->processor.proc_id = (u8)          operand[1]->integer.value;
 	obj_desc->processor.address = (acpi_io_address) operand[2]->integer.value;
 	obj_desc->processor.length = (u8)           operand[3]->integer.value;
@@ -507,7 +505,7 @@ acpi_ex_create_processor (
 }
 
 
-/*****************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    acpi_ex_create_power_resource
  *
@@ -519,7 +517,7 @@ acpi_ex_create_processor (
  *
  *              power_resource (Name[0], system_level[1], resource_order[2])
  *
- ****************************************************************************/
+ ******************************************************************************/
 
 acpi_status
 acpi_ex_create_power_resource (
@@ -555,10 +553,10 @@ acpi_ex_create_power_resource (
 	acpi_ut_remove_reference (obj_desc);
 	return_ACPI_STATUS (status);
 }
-
 #endif
 
-/*****************************************************************************
+
+/*******************************************************************************
  *
  * FUNCTION:    acpi_ex_create_method
  *
@@ -570,7 +568,7 @@ acpi_ex_create_power_resource (
  *
  * DESCRIPTION: Create a new method object
  *
- ****************************************************************************/
+ ******************************************************************************/
 
 acpi_status
 acpi_ex_create_method (
diff --git a/drivers/acpi/executer/exdump.c b/drivers/acpi/executer/exdump.c
--- a/drivers/acpi/executer/exdump.c
+++ b/drivers/acpi/executer/exdump.c
@@ -51,23 +51,48 @@
 #define _COMPONENT          ACPI_EXECUTER
 	 ACPI_MODULE_NAME    ("exdump")
 
+/* Local prototypes */
+
+#ifdef ACPI_FUTURE_USAGE
+static void
+acpi_ex_out_string (
+	char                            *title,
+	char                            *value);
+
+static void
+acpi_ex_out_pointer (
+	char                            *title,
+	void                            *value);
+
+static void
+acpi_ex_out_integer (
+	char                            *title,
+	u32                             value);
+
+static void
+acpi_ex_out_address (
+	char                            *title,
+	acpi_physical_address           value);
+#endif	/* ACPI_FUTURE_USAGE */
+
 
 /*
  * The following routines are used for debug output only
  */
 #if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
 
-/*****************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    acpi_ex_dump_operand
  *
- * PARAMETERS:  *obj_desc         - Pointer to entry to be dumped
+ * PARAMETERS:  *obj_desc       - Pointer to entry to be dumped
+ *              Depth           - Current nesting depth
  *
  * RETURN:      None
  *
  * DESCRIPTION: Dump an operand object
  *
- ****************************************************************************/
+ ******************************************************************************/
 
 void
 acpi_ex_dump_operand (
@@ -86,9 +111,8 @@ acpi_ex_dump_operand (
 	}
 
 	if (!obj_desc) {
-		/*
-		 * This could be a null element of a package
-		 */
+		/* This could be a null element of a package */
+
 		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Null Object Descriptor\n"));
 		return;
 	}
@@ -117,6 +141,8 @@ acpi_ex_dump_operand (
 		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%p ", obj_desc));
 	}
 
+	/* Decode object type */
+
 	switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
 	case ACPI_TYPE_LOCAL_REFERENCE:
 
@@ -274,7 +300,9 @@ acpi_ex_dump_operand (
 	case ACPI_TYPE_STRING:
 
 		acpi_os_printf ("String length %X @ %p ",
-			obj_desc->string.length, obj_desc->string.pointer);
+			obj_desc->string.length,
+			obj_desc->string.pointer);
+
 		acpi_ut_print_string (obj_desc->string.pointer, ACPI_UINT8_MAX);
 		acpi_os_printf ("\n");
 		break;
@@ -290,10 +318,13 @@ acpi_ex_dump_operand (
 
 		acpi_os_printf (
 			"region_field: Bits=%X acc_width=%X Lock=%X Update=%X at byte=%X bit=%X of below:\n",
-			obj_desc->field.bit_length, obj_desc->field.access_byte_width,
+			obj_desc->field.bit_length,
+			obj_desc->field.access_byte_width,
 			obj_desc->field.field_flags & AML_FIELD_LOCK_RULE_MASK,
 			obj_desc->field.field_flags & AML_FIELD_UPDATE_RULE_MASK,
-			obj_desc->field.base_byte_offset, obj_desc->field.start_field_bit_offset);
+			obj_desc->field.base_byte_offset,
+			obj_desc->field.start_field_bit_offset);
+
 		acpi_ex_dump_operand (obj_desc->field.region_obj, depth+1);
 		break;
 
@@ -308,13 +339,15 @@ acpi_ex_dump_operand (
 
 		acpi_os_printf (
 			"buffer_field: %X bits at byte %X bit %X of \n",
-			obj_desc->buffer_field.bit_length, obj_desc->buffer_field.base_byte_offset,
+			obj_desc->buffer_field.bit_length,
+			obj_desc->buffer_field.base_byte_offset,
 			obj_desc->buffer_field.start_field_bit_offset);
 
 		if (!obj_desc->buffer_field.buffer_obj) {
 			ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "*NULL* \n"));
 		}
-		else if (ACPI_GET_OBJECT_TYPE (obj_desc->buffer_field.buffer_obj) != ACPI_TYPE_BUFFER) {
+		else if (ACPI_GET_OBJECT_TYPE (obj_desc->buffer_field.buffer_obj) !=
+				 ACPI_TYPE_BUFFER) {
 			acpi_os_printf ("*not a Buffer* \n");
 		}
 		else {
@@ -331,10 +364,10 @@ acpi_ex_dump_operand (
 
 	case ACPI_TYPE_METHOD:
 
-		acpi_os_printf (
-			"Method(%X) @ %p:%X\n",
+		acpi_os_printf ("Method(%X) @ %p:%X\n",
 			obj_desc->method.param_count,
-			obj_desc->method.aml_start, obj_desc->method.aml_length);
+			obj_desc->method.aml_start,
+			obj_desc->method.aml_length);
 		break;
 
 
@@ -379,7 +412,7 @@ acpi_ex_dump_operand (
 }
 
 
-/*****************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    acpi_ex_dump_operands
  *
@@ -393,7 +426,7 @@ acpi_ex_dump_operand (
  *
  * DESCRIPTION: Dump the object stack
  *
- ****************************************************************************/
+ ******************************************************************************/
 
 void
 acpi_ex_dump_operands (
@@ -441,10 +474,9 @@ acpi_ex_dump_operands (
 
 
 #ifdef ACPI_FUTURE_USAGE
-
-/*****************************************************************************
+/*******************************************************************************
  *
- * FUNCTION:    acpi_ex_out*
+ * FUNCTION:    acpi_ex_out* functions
  *
  * PARAMETERS:  Title               - Descriptive text
  *              Value               - Value to be displayed
@@ -453,9 +485,9 @@ acpi_ex_dump_operands (
  *              reduce the number of format strings required and keeps them
  *              all in one place for easy modification.
  *
- ****************************************************************************/
+ ******************************************************************************/
 
-void
+static void
 acpi_ex_out_string (
 	char                            *title,
 	char                            *value)
@@ -463,7 +495,7 @@ acpi_ex_out_string (
 	acpi_os_printf ("%20s : %s\n", title, value);
 }
 
-void
+static void
 acpi_ex_out_pointer (
 	char                            *title,
 	void                            *value)
@@ -471,7 +503,7 @@ acpi_ex_out_pointer (
 	acpi_os_printf ("%20s : %p\n", title, value);
 }
 
-void
+static void
 acpi_ex_out_integer (
 	char                            *title,
 	u32                             value)
@@ -479,7 +511,7 @@ acpi_ex_out_integer (
 	acpi_os_printf ("%20s : %X\n", title, value);
 }
 
-void
+static void
 acpi_ex_out_address (
 	char                            *title,
 	acpi_physical_address           value)
@@ -493,16 +525,16 @@ acpi_ex_out_address (
 }
 
 
-/*****************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    acpi_ex_dump_node
  *
  * PARAMETERS:  *Node               - Descriptor to dump
- *              Flags               - Force display
+ *              Flags               - Force display if TRUE
  *
  * DESCRIPTION: Dumps the members of the given.Node
  *
- ****************************************************************************/
+ ******************************************************************************/
 
 void
 acpi_ex_dump_node (
@@ -531,16 +563,16 @@ acpi_ex_dump_node (
 }
 
 
-/*****************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    acpi_ex_dump_object_descriptor
  *
  * PARAMETERS:  *Object             - Descriptor to dump
- *              Flags               - Force display
+ *              Flags               - Force display if TRUE
  *
  * DESCRIPTION: Dumps the members of the object descriptor given.
  *
- ****************************************************************************/
+ ******************************************************************************/
 
 void
 acpi_ex_dump_object_descriptor (
@@ -553,6 +585,10 @@ acpi_ex_dump_object_descriptor (
 	ACPI_FUNCTION_TRACE ("ex_dump_object_descriptor");
 
 
+	if (!obj_desc) {
+		return_VOID;
+	}
+
 	if (!flags) {
 		if (!((ACPI_LV_OBJECTS & acpi_dbg_level) && (_COMPONENT & acpi_dbg_layer))) {
 			return_VOID;
@@ -747,11 +783,17 @@ acpi_ex_dump_object_descriptor (
 	case ACPI_TYPE_LOCAL_REFERENCE:
 
 		acpi_ex_out_integer ("target_type", obj_desc->reference.target_type);
-		acpi_ex_out_string ("Opcode",       (acpi_ps_get_opcode_info (obj_desc->reference.opcode))->name);
+		acpi_ex_out_string ("Opcode",       (acpi_ps_get_opcode_info (
+				  obj_desc->reference.opcode))->name);
 		acpi_ex_out_integer ("Offset",      obj_desc->reference.offset);
 		acpi_ex_out_pointer ("obj_desc",    obj_desc->reference.object);
 		acpi_ex_out_pointer ("Node",        obj_desc->reference.node);
 		acpi_ex_out_pointer ("Where",       obj_desc->reference.where);
+
+		if (obj_desc->reference.object) {
+			acpi_os_printf ("\nReferenced Object:\n");
+			acpi_ex_dump_object_descriptor (obj_desc->reference.object, flags);
+		}
 		break;
 
 
@@ -788,6 +830,5 @@ acpi_ex_dump_object_descriptor (
 }
 
 #endif  /*  ACPI_FUTURE_USAGE  */
-
 #endif
 
diff --git a/drivers/acpi/executer/exfield.c b/drivers/acpi/executer/exfield.c
--- a/drivers/acpi/executer/exfield.c
+++ b/drivers/acpi/executer/exfield.c
@@ -120,8 +120,8 @@ acpi_ex_read_data_from_field (
 		 * Note: Smbus protocol value is passed in upper 16-bits of Function
 		 */
 		status = acpi_ex_access_region (obj_desc, 0,
-				  ACPI_CAST_PTR (acpi_integer, buffer_desc->buffer.pointer),
-				  ACPI_READ | (obj_desc->field.attribute << 16));
+				 ACPI_CAST_PTR (acpi_integer, buffer_desc->buffer.pointer),
+				 ACPI_READ | (obj_desc->field.attribute << 16));
 		acpi_ex_release_global_lock (locked);
 		goto exit;
 	}
@@ -196,6 +196,7 @@ exit:
  *
  * PARAMETERS:  source_desc         - Contains data to write
  *              obj_desc            - The named field
+ *              result_desc         - Where the return value is returned, if any
  *
  * RETURN:      Status
  *
@@ -250,12 +251,15 @@ acpi_ex_write_data_to_field (
 		if (ACPI_GET_OBJECT_TYPE (source_desc) != ACPI_TYPE_BUFFER) {
 			ACPI_REPORT_ERROR (("SMBus write requires Buffer, found type %s\n",
 				acpi_ut_get_object_type_name (source_desc)));
+
 			return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
 		}
 
 		if (source_desc->buffer.length < ACPI_SMBUS_BUFFER_SIZE) {
-			ACPI_REPORT_ERROR (("SMBus write requires Buffer of length %X, found length %X\n",
+			ACPI_REPORT_ERROR ((
+				"SMBus write requires Buffer of length %X, found length %X\n",
 				ACPI_SMBUS_BUFFER_SIZE, source_desc->buffer.length));
+
 			return_ACPI_STATUS (AE_AML_BUFFER_LIMIT);
 		}
 
@@ -265,14 +269,16 @@ acpi_ex_write_data_to_field (
 		}
 
 		buffer = buffer_desc->buffer.pointer;
-		ACPI_MEMCPY (buffer, source_desc->buffer.pointer, ACPI_SMBUS_BUFFER_SIZE);
+		ACPI_MEMCPY (buffer, source_desc->buffer.pointer,
+			ACPI_SMBUS_BUFFER_SIZE);
 
 		/* Lock entire transaction if requested */
 
 		locked = acpi_ex_acquire_global_lock (obj_desc->common_field.field_flags);
 
 		/*
-		 * Perform the write (returns status and perhaps data in the same buffer)
+		 * Perform the write (returns status and perhaps data in the
+		 * same buffer)
 		 * Note: SMBus protocol type is passed in upper 16-bits of Function.
 		 */
 		status = acpi_ex_access_region (obj_desc, 0,
@@ -284,9 +290,8 @@ acpi_ex_write_data_to_field (
 		return_ACPI_STATUS (status);
 	}
 
-	/*
-	 * Get a pointer to the data to be written
-	 */
+	/* Get a pointer to the data to be written */
+
 	switch (ACPI_GET_OBJECT_TYPE (source_desc)) {
 	case ACPI_TYPE_INTEGER:
 		buffer = &source_desc->integer.value;
@@ -314,7 +319,8 @@ acpi_ex_write_data_to_field (
 	 * the ACPI specification.
 	 */
 	new_buffer = NULL;
-	required_length = ACPI_ROUND_BITS_UP_TO_BYTES (obj_desc->common_field.bit_length);
+	required_length = ACPI_ROUND_BITS_UP_TO_BYTES (
+			   obj_desc->common_field.bit_length);
 
 	if (length < required_length) {
 		/* We need to create a new buffer */
@@ -338,6 +344,7 @@ acpi_ex_write_data_to_field (
 		"field_write [FROM]: Obj %p (%s:%X), Buf %p, byte_len %X\n",
 		source_desc, acpi_ut_get_type_name (ACPI_GET_OBJECT_TYPE (source_desc)),
 		ACPI_GET_OBJECT_TYPE (source_desc), buffer, length));
+
 	ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
 		"field_write [TO]:  Obj %p (%s:%X), bit_len %X, bit_off %X, byte_off %X\n",
 		obj_desc, acpi_ut_get_type_name (ACPI_GET_OBJECT_TYPE (obj_desc)),
diff --git a/drivers/acpi/executer/exfldio.c b/drivers/acpi/executer/exfldio.c
--- a/drivers/acpi/executer/exfldio.c
+++ b/drivers/acpi/executer/exfldio.c
@@ -52,12 +52,31 @@
 #define _COMPONENT          ACPI_EXECUTER
 	 ACPI_MODULE_NAME    ("exfldio")
 
+/* Local prototypes */
+
+static acpi_status
+acpi_ex_field_datum_io (
+	union acpi_operand_object       *obj_desc,
+	u32                             field_datum_byte_offset,
+	acpi_integer                    *value,
+	u32                             read_write);
+
+static u8
+acpi_ex_register_overflow (
+	union acpi_operand_object       *obj_desc,
+	acpi_integer                    value);
+
+static acpi_status
+acpi_ex_setup_region (
+	union acpi_operand_object       *obj_desc,
+	u32                             field_datum_byte_offset);
+
 
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ex_setup_region
  *
- * PARAMETERS:  *obj_desc               - Field to be read or written
+ * PARAMETERS:  obj_desc                - Field to be read or written
  *              field_datum_byte_offset - Byte offset of this datum within the
  *                                        parent field
  *
@@ -69,7 +88,7 @@
  *
  ******************************************************************************/
 
-acpi_status
+static acpi_status
 acpi_ex_setup_region (
 	union acpi_operand_object       *obj_desc,
 	u32                             field_datum_byte_offset)
@@ -127,9 +146,9 @@ acpi_ex_setup_region (
 	 * length of one field datum (access width) must fit within the region.
 	 * (Region length is specified in bytes)
 	 */
-	if (rgn_desc->region.length < (obj_desc->common_field.base_byte_offset
-			   + field_datum_byte_offset
-			   + obj_desc->common_field.access_byte_width)) {
+	if (rgn_desc->region.length < (obj_desc->common_field.base_byte_offset +
+			   field_datum_byte_offset +
+			   obj_desc->common_field.access_byte_width)) {
 		if (acpi_gbl_enable_interpreter_slack) {
 			/*
 			 * Slack mode only:  We will go ahead and allow access to this
@@ -155,7 +174,8 @@ acpi_ex_setup_region (
 				"Field [%4.4s] access width (%d bytes) too large for region [%4.4s] (length %X)\n",
 				acpi_ut_get_node_name (obj_desc->common_field.node),
 				obj_desc->common_field.access_byte_width,
-				acpi_ut_get_node_name (rgn_desc->region.node), rgn_desc->region.length));
+				acpi_ut_get_node_name (rgn_desc->region.node),
+				rgn_desc->region.length));
 		}
 
 		/*
@@ -167,7 +187,8 @@ acpi_ex_setup_region (
 			acpi_ut_get_node_name (obj_desc->common_field.node),
 			obj_desc->common_field.base_byte_offset,
 			field_datum_byte_offset, obj_desc->common_field.access_byte_width,
-			acpi_ut_get_node_name (rgn_desc->region.node), rgn_desc->region.length));
+			acpi_ut_get_node_name (rgn_desc->region.node),
+			rgn_desc->region.length));
 
 		return_ACPI_STATUS (AE_AML_REGION_LIMIT);
 	}
@@ -180,10 +201,10 @@ acpi_ex_setup_region (
  *
  * FUNCTION:    acpi_ex_access_region
  *
- * PARAMETERS:  *obj_desc               - Field to be read
+ * PARAMETERS:  obj_desc                - Field to be read
  *              field_datum_byte_offset - Byte offset of this datum within the
  *                                        parent field
- *              *Value                  - Where to store value (must at least
+ *              Value                   - Where to store value (must at least
  *                                        the size of acpi_integer)
  *              Function                - Read or Write flag plus other region-
  *                                        dependent flags
@@ -226,9 +247,9 @@ acpi_ex_access_region (
 	 * 3) The current offset into the field
 	 */
 	rgn_desc = obj_desc->common_field.region_obj;
-	address = rgn_desc->region.address
-			 + obj_desc->common_field.base_byte_offset
-			 + field_datum_byte_offset;
+	address = rgn_desc->region.address +
+			 obj_desc->common_field.base_byte_offset +
+			 field_datum_byte_offset;
 
 	if ((function & ACPI_IO_MASK) == ACPI_READ) {
 		ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "[READ]"));
@@ -249,7 +270,8 @@ acpi_ex_access_region (
 	/* Invoke the appropriate address_space/op_region handler */
 
 	status = acpi_ev_address_space_dispatch (rgn_desc, function,
-			  address, ACPI_MUL_8 (obj_desc->common_field.access_byte_width), value);
+			 address,
+			 ACPI_MUL_8 (obj_desc->common_field.access_byte_width), value);
 
 	if (ACPI_FAILURE (status)) {
 		if (status == AE_NOT_IMPLEMENTED) {
@@ -274,7 +296,7 @@ acpi_ex_access_region (
  *
  * FUNCTION:    acpi_ex_register_overflow
  *
- * PARAMETERS:  *obj_desc               - Register(Field) to be written
+ * PARAMETERS:  obj_desc                - Register(Field) to be written
  *              Value                   - Value to be stored
  *
  * RETURN:      TRUE if value overflows the field, FALSE otherwise
@@ -287,7 +309,7 @@ acpi_ex_access_region (
  *
  ******************************************************************************/
 
-u8
+static u8
 acpi_ex_register_overflow (
 	union acpi_operand_object       *obj_desc,
 	acpi_integer                    value)
@@ -319,10 +341,10 @@ acpi_ex_register_overflow (
  *
  * FUNCTION:    acpi_ex_field_datum_io
  *
- * PARAMETERS:  *obj_desc               - Field to be read
+ * PARAMETERS:  obj_desc                - Field to be read
  *              field_datum_byte_offset - Byte offset of this datum within the
  *                                        parent field
- *              *Value                  - Where to store value (must be 64 bits)
+ *              Value                   - Where to store value (must be 64 bits)
  *              read_write              - Read or Write flag
  *
  * RETURN:      Status
@@ -333,7 +355,7 @@ acpi_ex_register_overflow (
  *
  ******************************************************************************/
 
-acpi_status
+static acpi_status
 acpi_ex_field_datum_io (
 	union acpi_operand_object       *obj_desc,
 	u32                             field_datum_byte_offset,
@@ -350,7 +372,9 @@ acpi_ex_field_datum_io (
 	if (read_write == ACPI_READ) {
 		if (!value) {
 			local_value = 0;
-			value = &local_value; /* To support reads without saving return value */
+
+			/* To support reads without saving return value */
+			value = &local_value;
 		}
 
 		/* Clear the entire return buffer first, [Very Important!] */
@@ -363,8 +387,10 @@ acpi_ex_field_datum_io (
 	 *
 	 * buffer_field - Read/write from/to a Buffer
 	 * region_field - Read/write from/to a Operation Region.
-	 * bank_field  - Write to a Bank Register, then read/write from/to an op_region
-	 * index_field - Write to an Index Register, then read/write from/to a Data Register
+	 * bank_field  - Write to a Bank Register, then read/write from/to an
+	 *               operation_region
+	 * index_field - Write to an Index Register, then read/write from/to a
+	 *               Data Register
 	 */
 	switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
 	case ACPI_TYPE_BUFFER_FIELD:
@@ -384,19 +410,20 @@ acpi_ex_field_datum_io (
 			 * Copy the data from the source buffer.
 			 * Length is the field width in bytes.
 			 */
-			ACPI_MEMCPY (value, (obj_desc->buffer_field.buffer_obj)->buffer.pointer
-					  + obj_desc->buffer_field.base_byte_offset
-					  + field_datum_byte_offset,
-					  obj_desc->common_field.access_byte_width);
+			ACPI_MEMCPY (value,
+				(obj_desc->buffer_field.buffer_obj)->buffer.pointer +
+					obj_desc->buffer_field.base_byte_offset +
+					field_datum_byte_offset,
+				obj_desc->common_field.access_byte_width);
 		}
 		else {
 			/*
 			 * Copy the data to the target buffer.
 			 * Length is the field width in bytes.
 			 */
-			ACPI_MEMCPY ((obj_desc->buffer_field.buffer_obj)->buffer.pointer
-					+ obj_desc->buffer_field.base_byte_offset
-					+ field_datum_byte_offset,
+			ACPI_MEMCPY ((obj_desc->buffer_field.buffer_obj)->buffer.pointer +
+					obj_desc->buffer_field.base_byte_offset +
+					field_datum_byte_offset,
 					value, obj_desc->common_field.access_byte_width);
 		}
 
@@ -406,8 +433,10 @@ acpi_ex_field_datum_io (
 
 	case ACPI_TYPE_LOCAL_BANK_FIELD:
 
-		/* Ensure that the bank_value is not beyond the capacity of the register */
-
+		/*
+		 * Ensure that the bank_value is not beyond the capacity of
+		 * the register
+		 */
 		if (acpi_ex_register_overflow (obj_desc->bank_field.bank_obj,
 				  (acpi_integer) obj_desc->bank_field.value)) {
 			return_ACPI_STATUS (AE_AML_REGISTER_LIMIT);
@@ -445,8 +474,10 @@ acpi_ex_field_datum_io (
 	case ACPI_TYPE_LOCAL_INDEX_FIELD:
 
 
-		/* Ensure that the index_value is not beyond the capacity of the register */
-
+		/*
+		 * Ensure that the index_value is not beyond the capacity of
+		 * the register
+		 */
 		if (acpi_ex_register_overflow (obj_desc->index_field.index_obj,
 				  (acpi_integer) obj_desc->index_field.value)) {
 			return_ACPI_STATUS (AE_AML_REGISTER_LIMIT);
@@ -496,14 +527,16 @@ acpi_ex_field_datum_io (
 
 	if (ACPI_SUCCESS (status)) {
 		if (read_write == ACPI_READ) {
-			ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "Value Read %8.8X%8.8X, Width %d\n",
-					   ACPI_FORMAT_UINT64 (*value),
-					   obj_desc->common_field.access_byte_width));
+			ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
+				"Value Read %8.8X%8.8X, Width %d\n",
+				ACPI_FORMAT_UINT64 (*value),
+				obj_desc->common_field.access_byte_width));
 		}
 		else {
-			ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "Value Written %8.8X%8.8X, Width %d\n",
-					   ACPI_FORMAT_UINT64 (*value),
-					   obj_desc->common_field.access_byte_width));
+			ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
+				"Value Written %8.8X%8.8X, Width %d\n",
+				ACPI_FORMAT_UINT64 (*value),
+				obj_desc->common_field.access_byte_width));
 		}
 	}
 
@@ -515,8 +548,10 @@ acpi_ex_field_datum_io (
  *
  * FUNCTION:    acpi_ex_write_with_update_rule
  *
- * PARAMETERS:  *obj_desc           - Field to be set
- *              Value               - Value to store
+ * PARAMETERS:  obj_desc                - Field to be written
+ *              Mask                    - bitmask within field datum
+ *              field_value             - Value to write
+ *              field_datum_byte_offset - Offset of datum within field
  *
  * RETURN:      Status
  *
@@ -689,7 +724,8 @@ acpi_ex_extract_from_field (
 		/* Merge with previous datum if necessary */
 
 		merged_datum |= raw_datum <<
-			(obj_desc->common_field.access_bit_width - obj_desc->common_field.start_field_bit_offset);
+			(obj_desc->common_field.access_bit_width -
+				obj_desc->common_field.start_field_bit_offset);
 
 		if (i == datum_count) {
 			break;
@@ -707,7 +743,8 @@ acpi_ex_extract_from_field (
 
 	/* Mask off any extra bits in the last datum */
 
-	buffer_tail_bits = obj_desc->common_field.bit_length % obj_desc->common_field.access_bit_width;
+	buffer_tail_bits = obj_desc->common_field.bit_length %
+			   obj_desc->common_field.access_bit_width;
 	if (buffer_tail_bits) {
 		merged_datum &= ACPI_MASK_BITS_ABOVE (buffer_tail_bits);
 	}
@@ -791,7 +828,8 @@ acpi_ex_insert_into_field (
 		/* Write merged datum to the target field */
 
 		merged_datum &= mask;
-		status = acpi_ex_write_with_update_rule (obj_desc, mask, merged_datum, field_offset);
+		status = acpi_ex_write_with_update_rule (obj_desc, mask,
+				 merged_datum, field_offset);
 		if (ACPI_FAILURE (status)) {
 			return_ACPI_STATUS (status);
 		}
@@ -800,7 +838,8 @@ acpi_ex_insert_into_field (
 
 		field_offset += obj_desc->common_field.access_byte_width;
 		merged_datum = raw_datum >>
-			(obj_desc->common_field.access_bit_width - obj_desc->common_field.start_field_bit_offset);
+			(obj_desc->common_field.access_bit_width -
+				obj_desc->common_field.start_field_bit_offset);
 		mask = ACPI_INTEGER_MAX;
 
 		if (i == datum_count) {
@@ -819,7 +858,8 @@ acpi_ex_insert_into_field (
 	/* Mask off any extra bits in the last datum */
 
 	buffer_tail_bits = (obj_desc->common_field.bit_length +
-			obj_desc->common_field.start_field_bit_offset) % obj_desc->common_field.access_bit_width;
+			obj_desc->common_field.start_field_bit_offset) %
+				obj_desc->common_field.access_bit_width;
 	if (buffer_tail_bits) {
 		mask &= ACPI_MASK_BITS_ABOVE (buffer_tail_bits);
 	}
@@ -827,7 +867,8 @@ acpi_ex_insert_into_field (
 	/* Write the last datum to the field */
 
 	merged_datum &= mask;
-	status = acpi_ex_write_with_update_rule (obj_desc, mask, merged_datum, field_offset);
+	status = acpi_ex_write_with_update_rule (obj_desc,
+			 mask, merged_datum, field_offset);
 
 	return_ACPI_STATUS (status);
 }
diff --git a/drivers/acpi/executer/exmisc.c b/drivers/acpi/executer/exmisc.c
--- a/drivers/acpi/executer/exmisc.c
+++ b/drivers/acpi/executer/exmisc.c
@@ -139,8 +139,9 @@ acpi_ex_get_object_reference (
 	reference_obj->reference.object = referenced_obj;
 	*return_desc = reference_obj;
 
-	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Object %p Type [%s], returning Reference %p\n",
-			obj_desc, acpi_ut_get_object_type_name (obj_desc), *return_desc));
+	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+		"Object %p Type [%s], returning Reference %p\n",
+		obj_desc, acpi_ut_get_object_type_name (obj_desc), *return_desc));
 
 	return_ACPI_STATUS (AE_OK);
 }
@@ -456,7 +457,7 @@ acpi_ex_do_math_op (
 		return (integer0 * integer1);
 
 
-	case AML_SHIFT_LEFT_OP:         /* shift_left (Operand, shift_count, Result) */
+	case AML_SHIFT_LEFT_OP:         /* shift_left (Operand, shift_count, Result)*/
 
 		return (integer0 << integer1);
 
diff --git a/drivers/acpi/executer/exmutex.c b/drivers/acpi/executer/exmutex.c
--- a/drivers/acpi/executer/exmutex.c
+++ b/drivers/acpi/executer/exmutex.c
@@ -49,6 +49,13 @@
 #define _COMPONENT          ACPI_EXECUTER
 	 ACPI_MODULE_NAME    ("exmutex")
 
+/* Local prototypes */
+
+static void
+acpi_ex_link_mutex (
+	union acpi_operand_object       *obj_desc,
+	struct acpi_thread_state        *thread);
+
 
 /*******************************************************************************
  *
@@ -56,7 +63,7 @@
  *
  * PARAMETERS:  obj_desc            - The mutex to be unlinked
  *
- * RETURN:      Status
+ * RETURN:      None
  *
  * DESCRIPTION: Remove a mutex from the "acquired_mutex" list
  *
@@ -92,16 +99,16 @@ acpi_ex_unlink_mutex (
  *
  * FUNCTION:    acpi_ex_link_mutex
  *
- * PARAMETERS:  obj_desc            - The mutex to be linked
- *              list_head           - head of the "acquired_mutex" list
+ * PARAMETERS:  obj_desc        - The mutex to be linked
+ *              Thread          - Current executing thread object
  *
- * RETURN:      Status
+ * RETURN:      None
  *
  * DESCRIPTION: Add a mutex to the "acquired_mutex" list for this walk
  *
  ******************************************************************************/
 
-void
+static void
 acpi_ex_link_mutex (
 	union acpi_operand_object       *obj_desc,
 	struct acpi_thread_state        *thread)
@@ -132,8 +139,9 @@ acpi_ex_link_mutex (
  *
  * FUNCTION:    acpi_ex_acquire_mutex
  *
- * PARAMETERS:  time_desc           - The 'time to delay' object descriptor
- *              obj_desc            - The object descriptor for this op
+ * PARAMETERS:  time_desc           - Timeout integer
+ *              obj_desc            - Mutex object
+ *              walk_state          - Current method execution state
  *
  * RETURN:      Status
  *
@@ -161,7 +169,7 @@ acpi_ex_acquire_mutex (
 
 	if (!walk_state->thread) {
 		ACPI_REPORT_ERROR (("Cannot acquire Mutex [%4.4s], null thread info\n",
-				acpi_ut_get_node_name (obj_desc->mutex.node)));
+			acpi_ut_get_node_name (obj_desc->mutex.node)));
 		return_ACPI_STATUS (AE_AML_INTERNAL);
 	}
 
@@ -170,8 +178,9 @@ acpi_ex_acquire_mutex (
 	 * mutex.  This mechanism provides some deadlock prevention
 	 */
 	if (walk_state->thread->current_sync_level > obj_desc->mutex.sync_level) {
-		ACPI_REPORT_ERROR (("Cannot acquire Mutex [%4.4s], incorrect sync_level\n",
-				acpi_ut_get_node_name (obj_desc->mutex.node)));
+		ACPI_REPORT_ERROR ((
+			"Cannot acquire Mutex [%4.4s], incorrect sync_level\n",
+			acpi_ut_get_node_name (obj_desc->mutex.node)));
 		return_ACPI_STATUS (AE_AML_MUTEX_ORDER);
 	}
 
@@ -180,8 +189,10 @@ acpi_ex_acquire_mutex (
 	if (obj_desc->mutex.owner_thread) {
 		/* Special case for Global Lock, allow all threads */
 
-		if ((obj_desc->mutex.owner_thread->thread_id == walk_state->thread->thread_id) ||
-			(obj_desc->mutex.semaphore == acpi_gbl_global_lock_semaphore)) {
+		if ((obj_desc->mutex.owner_thread->thread_id ==
+				walk_state->thread->thread_id)      ||
+			(obj_desc->mutex.semaphore ==
+				acpi_gbl_global_lock_semaphore)) {
 			/*
 			 * The mutex is already owned by this thread,
 			 * just increment the acquisition depth
@@ -221,6 +232,7 @@ acpi_ex_acquire_mutex (
  * FUNCTION:    acpi_ex_release_mutex
  *
  * PARAMETERS:  obj_desc            - The object descriptor for this op
+ *              walk_state          - Current method execution state
  *
  * RETURN:      Status
  *
@@ -278,8 +290,9 @@ acpi_ex_release_mutex (
 	 * equal to the current sync level
 	 */
 	if (obj_desc->mutex.sync_level > walk_state->thread->current_sync_level) {
-		ACPI_REPORT_ERROR (("Cannot release Mutex [%4.4s], incorrect sync_level\n",
-				acpi_ut_get_node_name (obj_desc->mutex.node)));
+		ACPI_REPORT_ERROR ((
+			"Cannot release Mutex [%4.4s], incorrect sync_level\n",
+			acpi_ut_get_node_name (obj_desc->mutex.node)));
 		return_ACPI_STATUS (AE_AML_MUTEX_ORDER);
 	}
 
@@ -313,11 +326,11 @@ acpi_ex_release_mutex (
  *
  * FUNCTION:    acpi_ex_release_all_mutexes
  *
- * PARAMETERS:  mutex_list            - Head of the mutex list
+ * PARAMETERS:  Thread          - Current executing thread object
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Release all mutexes in the list
+ * DESCRIPTION: Release all mutexes held by this thread
  *
  ******************************************************************************/
 
diff --git a/drivers/acpi/executer/exnames.c b/drivers/acpi/executer/exnames.c
--- a/drivers/acpi/executer/exnames.c
+++ b/drivers/acpi/executer/exnames.c
@@ -50,13 +50,17 @@
 #define _COMPONENT          ACPI_EXECUTER
 	 ACPI_MODULE_NAME    ("exnames")
 
+/* Local prototypes */
 
-/* AML Package Length encodings */
+static char *
+acpi_ex_allocate_name_string (
+	u32                             prefix_count,
+	u32                             num_name_segs);
 
-#define ACPI_AML_PACKAGE_TYPE1   0x40
-#define ACPI_AML_PACKAGE_TYPE2   0x4000
-#define ACPI_AML_PACKAGE_TYPE3   0x400000
-#define ACPI_AML_PACKAGE_TYPE4   0x40000000
+static acpi_status
+acpi_ex_name_segment (
+	u8                              **in_aml_address,
+	char                            *name_string);
 
 
 /*******************************************************************************
@@ -64,7 +68,7 @@
  * FUNCTION:    acpi_ex_allocate_name_string
  *
  * PARAMETERS:  prefix_count        - Count of parent levels. Special cases:
- *                                    (-1) = root,  0 = none
+ *                                    (-1)==root,  0==none
  *              num_name_segs       - count of 4-character name segments
  *
  * RETURN:      A pointer to the allocated string segment.  This segment must
@@ -75,7 +79,7 @@
  *
  ******************************************************************************/
 
-char *
+static char *
 acpi_ex_allocate_name_string (
 	u32                             prefix_count,
 	u32                             num_name_segs)
@@ -88,7 +92,7 @@ acpi_ex_allocate_name_string (
 
 
 	/*
-	 * Allow room for all \ and ^ prefixes, all segments, and a multi_name_prefix.
+	 * Allow room for all \ and ^ prefixes, all segments and a multi_name_prefix.
 	 * Also, one byte for the null terminator.
 	 * This may actually be somewhat longer than needed.
 	 */
@@ -107,7 +111,8 @@ acpi_ex_allocate_name_string (
 	 */
 	name_string = ACPI_MEM_ALLOCATE (size_needed);
 	if (!name_string) {
-		ACPI_REPORT_ERROR (("ex_allocate_name_string: Could not allocate size %d\n", size_needed));
+		ACPI_REPORT_ERROR ((
+			"ex_allocate_name_string: Could not allocate size %d\n", size_needed));
 		return_PTR (NULL);
 	}
 
@@ -152,15 +157,17 @@ acpi_ex_allocate_name_string (
  *
  * FUNCTION:    acpi_ex_name_segment
  *
- * PARAMETERS:  interpreter_mode    - Current running mode (load1/Load2/Exec)
+ * PARAMETERS:  in_aml_address  - Pointer to the name in the AML code
+ *              name_string     - Where to return the name. The name is appended
+ *                                to any existing string to form a namepath
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Execute a name segment (4 bytes)
+ * DESCRIPTION: Extract an ACPI name (4 bytes) from the AML byte stream
  *
  ******************************************************************************/
 
-acpi_status
+static acpi_status
 acpi_ex_name_segment (
 	u8                              **in_aml_address,
 	char                            *name_string)
@@ -223,10 +230,13 @@ acpi_ex_name_segment (
 		status = AE_CTRL_PENDING;
 	}
 	else {
-		/* Segment started with one or more valid characters, but fewer than 4 */
-
+		/*
+		 * Segment started with one or more valid characters, but fewer than
+		 * the required 4
+		 */
 		status = AE_AML_BAD_NAME;
-		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Bad character %02x in name, at %p\n",
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"Bad character %02x in name, at %p\n",
 			*aml_address, aml_address));
 	}
 
@@ -239,11 +249,16 @@ acpi_ex_name_segment (
  *
  * FUNCTION:    acpi_ex_get_name_string
  *
- * PARAMETERS:  data_type           - Data type to be associated with this name
+ * PARAMETERS:  data_type           - Object type to be associated with this
+ *                                    name
+ *              in_aml_address      - Pointer to the namestring in the AML code
+ *              out_name_string     - Where the namestring is returned
+ *              out_name_length     - Length of the returned string
  *
- * RETURN:      Status
+ * RETURN:      Status, namestring and length
  *
- * DESCRIPTION: Get a name, including any prefixes.
+ * DESCRIPTION: Extract a full namepath from the AML byte stream,
+ *              including any prefixes.
  *
  ******************************************************************************/
 
@@ -286,7 +301,8 @@ acpi_ex_get_name_string (
 		switch (*aml_address) {
 		case AML_ROOT_PREFIX:
 
-			ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "root_prefix(\\) at %p\n", aml_address));
+			ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "root_prefix(\\) at %p\n",
+				aml_address));
 
 			/*
 			 * Remember that we have a root_prefix --
@@ -303,7 +319,8 @@ acpi_ex_get_name_string (
 			/* Increment past possibly multiple parent prefixes */
 
 			do {
-				ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "parent_prefix (^) at %p\n", aml_address));
+				ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "parent_prefix (^) at %p\n",
+					aml_address));
 
 				aml_address++;
 				prefix_count++;
@@ -321,13 +338,13 @@ acpi_ex_get_name_string (
 			break;
 		}
 
-
 		/* Examine first character of name for name segment prefix operator */
 
 		switch (*aml_address) {
 		case AML_DUAL_NAME_PREFIX:
 
-			ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "dual_name_prefix at %p\n", aml_address));
+			ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "dual_name_prefix at %p\n",
+				aml_address));
 
 			aml_address++;
 			name_string = acpi_ex_allocate_name_string (prefix_count, 2);
@@ -349,7 +366,8 @@ acpi_ex_get_name_string (
 
 		case AML_MULTI_NAME_PREFIX_OP:
 
-			ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "multi_name_prefix at %p\n", aml_address));
+			ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "multi_name_prefix at %p\n",
+				aml_address));
 
 			/* Fetch count of segments remaining in name path */
 
@@ -368,7 +386,8 @@ acpi_ex_get_name_string (
 			has_prefix = TRUE;
 
 			while (num_segments &&
-					(status = acpi_ex_name_segment (&aml_address, name_string)) == AE_OK) {
+					(status = acpi_ex_name_segment (&aml_address, name_string)) ==
+						AE_OK) {
 				num_segments--;
 			}
 
@@ -380,7 +399,8 @@ acpi_ex_get_name_string (
 			/* null_name valid as of 8-12-98 ASL/AML Grammar Update */
 
 			if (prefix_count == ACPI_UINT32_MAX) {
-				ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "name_seg is \"\\\" followed by NULL\n"));
+				ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+					"name_seg is \"\\\" followed by NULL\n"));
 			}
 
 			/* Consume the NULL byte */
diff --git a/drivers/acpi/executer/exoparg1.c b/drivers/acpi/executer/exoparg1.c
--- a/drivers/acpi/executer/exoparg1.c
+++ b/drivers/acpi/executer/exoparg1.c
@@ -97,7 +97,8 @@ acpi_ex_opcode_0A_0T_1R (
 	union acpi_operand_object       *return_desc = NULL;
 
 
-	ACPI_FUNCTION_TRACE_STR ("ex_opcode_0A_0T_1R", acpi_ps_get_opcode_name (walk_state->opcode));
+	ACPI_FUNCTION_TRACE_STR ("ex_opcode_0A_0T_1R",
+		acpi_ps_get_opcode_name (walk_state->opcode));
 
 
 	/* Examine the AML opcode */
@@ -161,7 +162,8 @@ acpi_ex_opcode_1A_0T_0R (
 	acpi_status                     status = AE_OK;
 
 
-	ACPI_FUNCTION_TRACE_STR ("ex_opcode_1A_0T_0R", acpi_ps_get_opcode_name (walk_state->opcode));
+	ACPI_FUNCTION_TRACE_STR ("ex_opcode_1A_0T_0R",
+		acpi_ps_get_opcode_name (walk_state->opcode));
 
 
 	/* Examine the AML opcode */
@@ -236,7 +238,8 @@ acpi_ex_opcode_1A_1T_0R (
 	union acpi_operand_object       **operand = &walk_state->operands[0];
 
 
-	ACPI_FUNCTION_TRACE_STR ("ex_opcode_1A_1T_0R", acpi_ps_get_opcode_name (walk_state->opcode));
+	ACPI_FUNCTION_TRACE_STR ("ex_opcode_1A_1T_0R",
+		acpi_ps_get_opcode_name (walk_state->opcode));
 
 
 	/* Examine the AML opcode */
@@ -289,7 +292,8 @@ acpi_ex_opcode_1A_1T_1R (
 	acpi_integer                    digit;
 
 
-	ACPI_FUNCTION_TRACE_STR ("ex_opcode_1A_1T_1R", acpi_ps_get_opcode_name (walk_state->opcode));
+	ACPI_FUNCTION_TRACE_STR ("ex_opcode_1A_1T_1R",
+		acpi_ps_get_opcode_name (walk_state->opcode));
 
 
 	/* Examine the AML opcode */
@@ -409,8 +413,10 @@ acpi_ex_opcode_1A_1T_1R (
 			for (i = 0; (i < acpi_gbl_integer_nybble_width) && (digit > 0); i++) {
 				(void) acpi_ut_short_divide (digit, 10, &digit, &temp32);
 
-				/* Insert the BCD digit that resides in the remainder from above */
-
+				/*
+				 * Insert the BCD digit that resides in the
+				 * remainder from above
+				 */
 				return_desc->integer.value |= (((acpi_integer) temp32) <<
 						   ACPI_MUL_4 (i));
 			}
@@ -445,7 +451,8 @@ acpi_ex_opcode_1A_1T_1R (
 
 			/* Get the object reference, store it, and remove our reference */
 
-			status = acpi_ex_get_object_reference (operand[0], &return_desc2, walk_state);
+			status = acpi_ex_get_object_reference (operand[0],
+					 &return_desc2, walk_state);
 			if (ACPI_FAILURE (status)) {
 				goto cleanup;
 			}
@@ -482,10 +489,10 @@ acpi_ex_opcode_1A_1T_1R (
 
 		if (!walk_state->result_obj) {
 			/*
-			 * Normally, we would remove a reference on the Operand[0] parameter;
-			 * But since it is being used as the internal return object
-			 * (meaning we would normally increment it), the two cancel out,
-			 * and we simply don't do anything.
+			 * Normally, we would remove a reference on the Operand[0]
+			 * parameter; But since it is being used as the internal return
+			 * object (meaning we would normally increment it), the two
+			 * cancel out, and we simply don't do anything.
 			 */
 			walk_state->result_obj = operand[0];
 			walk_state->operands[0] = NULL; /* Prevent deletion */
@@ -549,9 +556,8 @@ acpi_ex_opcode_1A_1T_1R (
 	case AML_SHIFT_LEFT_BIT_OP:     /* shift_left_bit (Source, bit_num) */
 	case AML_SHIFT_RIGHT_BIT_OP:    /* shift_right_bit (Source, bit_num) */
 
-		/*
-		 * These are two obsolete opcodes
-		 */
+		/* These are two obsolete opcodes */
+
 		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
 			"%s is obsolete and not implemented\n",
 			acpi_ps_get_opcode_name (walk_state->opcode)));
@@ -568,9 +574,8 @@ acpi_ex_opcode_1A_1T_1R (
 	}
 
 	if (ACPI_SUCCESS (status)) {
-		/*
-		 * Store the return value computed above into the target object
-		 */
+		/* Store the return value computed above into the target object */
+
 		status = acpi_ex_store (return_desc, operand[1], walk_state);
 	}
 
@@ -615,7 +620,8 @@ acpi_ex_opcode_1A_0T_1R (
 	acpi_integer                    value;
 
 
-	ACPI_FUNCTION_TRACE_STR ("ex_opcode_1A_0T_1R", acpi_ps_get_opcode_name (walk_state->opcode));
+	ACPI_FUNCTION_TRACE_STR ("ex_opcode_1A_0T_1R",
+		acpi_ps_get_opcode_name (walk_state->opcode));
 
 
 	/* Examine the AML opcode */
@@ -706,9 +712,9 @@ acpi_ex_opcode_1A_0T_1R (
 
 		/*
 		 * Note: The operand is not resolved at this point because we want to
-		 * get the associated object, not its value.  For example, we don't want
-		 * to resolve a field_unit to its value, we want the actual field_unit
-		 * object.
+		 * get the associated object, not its value.  For example, we don't
+		 * want to resolve a field_unit to its value, we want the actual
+		 * field_unit object.
 		 */
 
 		/* Get the type of the base object */
@@ -738,7 +744,8 @@ acpi_ex_opcode_1A_0T_1R (
 
 		/* Get the base object */
 
-		status = acpi_ex_resolve_multiple (walk_state, operand[0], &type, &temp_desc);
+		status = acpi_ex_resolve_multiple (walk_state,
+				 operand[0], &type, &temp_desc);
 		if (ACPI_FAILURE (status)) {
 			goto cleanup;
 		}
@@ -818,8 +825,10 @@ acpi_ex_opcode_1A_0T_1R (
 
 					/* Set Operand[0] to the value of the local/arg */
 
-					status = acpi_ds_method_data_get_value (operand[0]->reference.opcode,
-							 operand[0]->reference.offset, walk_state, &temp_desc);
+					status = acpi_ds_method_data_get_value (
+							 operand[0]->reference.opcode,
+							 operand[0]->reference.offset,
+							 walk_state, &temp_desc);
 					if (ACPI_FAILURE (status)) {
 						goto cleanup;
 					}
@@ -852,21 +861,26 @@ acpi_ex_opcode_1A_0T_1R (
 			case ACPI_TYPE_STRING:
 
 				/*
-				 * This is a deref_of (String). The string is a reference to a named ACPI object.
+				 * This is a deref_of (String). The string is a reference
+				 * to a named ACPI object.
 				 *
 				 * 1) Find the owning Node
-				 * 2) Dereference the node to an actual object.  Could be a Field, so we nee
-				 *    to resolve the node to a value.
+				 * 2) Dereference the node to an actual object.  Could be a
+				 *    Field, so we need to resolve the node to a value.
 				 */
 				status = acpi_ns_get_node_by_path (operand[0]->string.pointer,
-						  walk_state->scope_info->scope.node, ACPI_NS_SEARCH_PARENT,
-						  ACPI_CAST_INDIRECT_PTR (struct acpi_namespace_node, &return_desc));
+						 walk_state->scope_info->scope.node,
+						 ACPI_NS_SEARCH_PARENT,
+						 ACPI_CAST_INDIRECT_PTR (
+								struct acpi_namespace_node, &return_desc));
 				if (ACPI_FAILURE (status)) {
 					goto cleanup;
 				}
 
 				status = acpi_ex_resolve_node_to_value (
-						  ACPI_CAST_INDIRECT_PTR (struct acpi_namespace_node, &return_desc), walk_state);
+						  ACPI_CAST_INDIRECT_PTR (
+								 struct acpi_namespace_node, &return_desc),
+								walk_state);
 				goto cleanup;
 
 
@@ -883,14 +897,16 @@ acpi_ex_opcode_1A_0T_1R (
 			/*
 			 * This is a deref_of (object_reference)
 			 * Get the actual object from the Node (This is the dereference).
-			 * -- This case may only happen when a local_x or arg_x is dereferenced above.
+			 * This case may only happen when a local_x or arg_x is
+			 * dereferenced above.
 			 */
-			return_desc = acpi_ns_get_attached_object ((struct acpi_namespace_node *) operand[0]);
+			return_desc = acpi_ns_get_attached_object (
+					  (struct acpi_namespace_node *) operand[0]);
 		}
 		else {
 			/*
-			 * This must be a reference object produced by either the Index() or
-			 * ref_of() operator
+			 * This must be a reference object produced by either the
+			 * Index() or ref_of() operator
 			 */
 			switch (operand[0]->reference.opcode) {
 			case AML_INDEX_OP:
@@ -931,8 +947,8 @@ acpi_ex_opcode_1A_0T_1R (
 				case ACPI_TYPE_PACKAGE:
 
 					/*
-					 * Return the referenced element of the package.  We must add
-					 * another reference to the referenced object, however.
+					 * Return the referenced element of the package.  We must
+					 * add another reference to the referenced object, however.
 					 */
 					return_desc = *(operand[0]->reference.where);
 					if (!return_desc) {
@@ -967,9 +983,11 @@ acpi_ex_opcode_1A_0T_1R (
 
 				return_desc = operand[0]->reference.object;
 
-				if (ACPI_GET_DESCRIPTOR_TYPE (return_desc) == ACPI_DESC_TYPE_NAMED) {
+				if (ACPI_GET_DESCRIPTOR_TYPE (return_desc) ==
+						ACPI_DESC_TYPE_NAMED) {
 
-					return_desc = acpi_ns_get_attached_object ((struct acpi_namespace_node *) return_desc);
+					return_desc = acpi_ns_get_attached_object (
+							  (struct acpi_namespace_node *) return_desc);
 				}
 
 				/* Add another reference to the object! */
diff --git a/drivers/acpi/executer/exoparg2.c b/drivers/acpi/executer/exoparg2.c
--- a/drivers/acpi/executer/exoparg2.c
+++ b/drivers/acpi/executer/exoparg2.c
@@ -118,7 +118,7 @@ acpi_ex_opcode_2A_0T_0R (
 
 		value = (u32) operand[1]->integer.value;
 
-		/* Notifies allowed on this object? */
+		/* Are notifies allowed on this object? */
 
 		if (!acpi_ev_is_notify_object (node)) {
 			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
@@ -203,11 +203,12 @@ acpi_ex_opcode_2A_2T_1R (
 		acpi_ps_get_opcode_name (walk_state->opcode));
 
 
-	/*
-	 * Execute the opcode
-	 */
+	/* Execute the opcode */
+
 	switch (walk_state->opcode) {
-	case AML_DIVIDE_OP:             /* Divide (Dividend, Divisor, remainder_result quotient_result) */
+	case AML_DIVIDE_OP:
+
+		/* Divide (Dividend, Divisor, remainder_result quotient_result) */
 
 		return_desc1 = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
 		if (!return_desc1) {
@@ -241,7 +242,6 @@ acpi_ex_opcode_2A_2T_1R (
 		goto cleanup;
 	}
 
-
 	/* Store the results to the target reference operands */
 
 	status = acpi_ex_store (return_desc2, operand[2], walk_state);
@@ -295,7 +295,7 @@ acpi_ex_opcode_2A_1T_1R (
 {
 	union acpi_operand_object       **operand = &walk_state->operands[0];
 	union acpi_operand_object       *return_desc = NULL;
-	u32                             index;
+	acpi_integer                    index;
 	acpi_status                     status = AE_OK;
 	acpi_size                       length;
 
@@ -304,9 +304,8 @@ acpi_ex_opcode_2A_1T_1R (
 		acpi_ps_get_opcode_name (walk_state->opcode));
 
 
-	/*
-	 * Execute the opcode
-	 */
+	/* Execute the opcode */
+
 	if (walk_state->op_info->flags & AML_MATH) {
 		/* All simple math opcodes (add, etc.) */
 
@@ -322,9 +321,8 @@ acpi_ex_opcode_2A_1T_1R (
 		goto store_result_to_target;
 	}
 
-
 	switch (walk_state->opcode) {
-	case AML_MOD_OP:                /* Mod (Dividend, Divisor, remainder_result (ACPI 2.0) */
+	case AML_MOD_OP: /* Mod (Dividend, Divisor, remainder_result (ACPI 2.0) */
 
 		return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
 		if (!return_desc) {
@@ -341,18 +339,19 @@ acpi_ex_opcode_2A_1T_1R (
 		break;
 
 
-	case AML_CONCAT_OP:             /* Concatenate (Data1, Data2, Result) */
+	case AML_CONCAT_OP: /* Concatenate (Data1, Data2, Result) */
 
 		status = acpi_ex_do_concatenate (operand[0], operand[1],
 				 &return_desc, walk_state);
 		break;
 
 
-	case AML_TO_STRING_OP:          /* to_string (Buffer, Length, Result) (ACPI 2.0) */
+	case AML_TO_STRING_OP: /* to_string (Buffer, Length, Result) (ACPI 2.0) */
 
 		/*
 		 * Input object is guaranteed to be a buffer at this point (it may have
-		 * been converted.)  Copy the raw buffer data to a new object of type String.
+		 * been converted.)  Copy the raw buffer data to a new object of
+		 * type String.
 		 */
 
 		/*
@@ -383,14 +382,16 @@ acpi_ex_opcode_2A_1T_1R (
 			goto cleanup;
 		}
 
-		/* Copy the raw buffer data with no transform. NULL terminated already. */
+		/* Copy the raw buffer data with no transform. NULL terminated already*/
 
 		ACPI_MEMCPY (return_desc->string.pointer,
 			operand[0]->buffer.pointer, length);
 		break;
 
 
-	case AML_CONCAT_RES_OP:         /* concatenate_res_template (Buffer, Buffer, Result) (ACPI 2.0) */
+	case AML_CONCAT_RES_OP:
+
+		/* concatenate_res_template (Buffer, Buffer, Result) (ACPI 2.0) */
 
 		status = acpi_ex_concat_template (operand[0], operand[1],
 				 &return_desc, walk_state);
@@ -407,33 +408,33 @@ acpi_ex_opcode_2A_1T_1R (
 			goto cleanup;
 		}
 
-		index = (u32) operand[1]->integer.value;
+		index = operand[1]->integer.value;
+
+		/* At this point, the Source operand is a Package, Buffer, or String */
 
-		/*
-		 * At this point, the Source operand is a Package, Buffer, or String
-		 */
 		if (ACPI_GET_OBJECT_TYPE (operand[0]) == ACPI_TYPE_PACKAGE) {
 			/* Object to be indexed is a Package */
 
 			if (index >= operand[0]->package.count) {
 				ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
-					"Index value (%X) beyond package end (%X)\n",
-					index, operand[0]->package.count));
+					"Index value (%X%8.8X) beyond package end (%X)\n",
+					ACPI_FORMAT_UINT64 (index), operand[0]->package.count));
 				status = AE_AML_PACKAGE_LIMIT;
 				goto cleanup;
 			}
 
 			return_desc->reference.target_type = ACPI_TYPE_PACKAGE;
 			return_desc->reference.object    = operand[0];
-			return_desc->reference.where     = &operand[0]->package.elements [index];
+			return_desc->reference.where     = &operand[0]->package.elements [
+					  index];
 		}
 		else {
 			/* Object to be indexed is a Buffer/String */
 
 			if (index >= operand[0]->buffer.length) {
 				ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
-					"Index value (%X) beyond end of buffer (%X)\n",
-					index, operand[0]->buffer.length));
+					"Index value (%X%8.8X) beyond end of buffer (%X)\n",
+					ACPI_FORMAT_UINT64 (index), operand[0]->buffer.length));
 				status = AE_AML_BUFFER_LIMIT;
 				goto cleanup;
 			}
@@ -451,7 +452,7 @@ acpi_ex_opcode_2A_1T_1R (
 		/* Complete the Index reference object */
 
 		return_desc->reference.opcode    = AML_INDEX_OP;
-		return_desc->reference.offset    = index;
+		return_desc->reference.offset    = (u32) index;
 
 		/* Store the reference to the Target */
 
@@ -536,22 +537,24 @@ acpi_ex_opcode_2A_0T_1R (
 		goto cleanup;
 	}
 
-	/*
-	 * Execute the Opcode
-	 */
-	if (walk_state->op_info->flags & AML_LOGICAL_NUMERIC) /* logical_op (Operand0, Operand1) */ {
+	/* Execute the Opcode */
+
+	if (walk_state->op_info->flags & AML_LOGICAL_NUMERIC) {
+		/* logical_op (Operand0, Operand1) */
+
 		status = acpi_ex_do_logical_numeric_op (walk_state->opcode,
 				  operand[0]->integer.value, operand[1]->integer.value,
 				  &logical_result);
 		goto store_logical_result;
 	}
-	else if (walk_state->op_info->flags & AML_LOGICAL)  /* logical_op (Operand0, Operand1) */ {
+	else if (walk_state->op_info->flags & AML_LOGICAL) {
+		/* logical_op (Operand0, Operand1) */
+
 		status = acpi_ex_do_logical_op (walk_state->opcode, operand[0],
 				 operand[1], &logical_result);
 		goto store_logical_result;
 	}
 
-
 	switch (walk_state->opcode) {
 	case AML_ACQUIRE_OP:            /* Acquire (mutex_object, Timeout) */
 
diff --git a/drivers/acpi/executer/exoparg3.c b/drivers/acpi/executer/exoparg3.c
--- a/drivers/acpi/executer/exoparg3.c
+++ b/drivers/acpi/executer/exoparg3.c
@@ -97,11 +97,12 @@ acpi_ex_opcode_3A_0T_0R (
 	acpi_status                     status = AE_OK;
 
 
-	ACPI_FUNCTION_TRACE_STR ("ex_opcode_3A_0T_0R", acpi_ps_get_opcode_name (walk_state->opcode));
+	ACPI_FUNCTION_TRACE_STR ("ex_opcode_3A_0T_0R",
+		acpi_ps_get_opcode_name (walk_state->opcode));
 
 
 	switch (walk_state->opcode) {
-	case AML_FATAL_OP:          /* Fatal (fatal_type fatal_code fatal_arg)   */
+	case AML_FATAL_OP:          /* Fatal (fatal_type fatal_code fatal_arg) */
 
 		ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
 			"fatal_op: Type %X Code %X Arg %X <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n",
@@ -116,9 +117,8 @@ acpi_ex_opcode_3A_0T_0R (
 			fatal->argument = (u32) operand[2]->integer.value;
 		}
 
-		/*
-		 * Always signal the OS!
-		 */
+		/* Always signal the OS! */
+
 		status = acpi_os_signal (ACPI_SIGNAL_FATAL, fatal);
 
 		/* Might return while OS is shutting down, just continue */
@@ -162,21 +162,23 @@ acpi_ex_opcode_3A_1T_1R (
 	union acpi_operand_object       *return_desc = NULL;
 	char                            *buffer;
 	acpi_status                     status = AE_OK;
-	acpi_native_uint                index;
+	acpi_integer                    index;
 	acpi_size                       length;
 
 
-	ACPI_FUNCTION_TRACE_STR ("ex_opcode_3A_1T_1R", acpi_ps_get_opcode_name (walk_state->opcode));
+	ACPI_FUNCTION_TRACE_STR ("ex_opcode_3A_1T_1R",
+		acpi_ps_get_opcode_name (walk_state->opcode));
 
 
 	switch (walk_state->opcode) {
-	case AML_MID_OP:        /* Mid  (Source[0], Index[1], Length[2], Result[3]) */
+	case AML_MID_OP:    /* Mid (Source[0], Index[1], Length[2], Result[3]) */
 
 		/*
 		 * Create the return object.  The Source operand is guaranteed to be
 		 * either a String or a Buffer, so just use its type.
 		 */
-		return_desc = acpi_ut_create_internal_object (ACPI_GET_OBJECT_TYPE (operand[0]));
+		return_desc = acpi_ut_create_internal_object (
+				  ACPI_GET_OBJECT_TYPE (operand[0]));
 		if (!return_desc) {
 			status = AE_NO_MEMORY;
 			goto cleanup;
@@ -184,7 +186,7 @@ acpi_ex_opcode_3A_1T_1R (
 
 		/* Get the Integer values from the objects */
 
-		index = (acpi_native_uint) operand[1]->integer.value;
+		index = operand[1]->integer.value;
 		length = (acpi_size) operand[2]->integer.value;
 
 		/*
@@ -197,7 +199,8 @@ acpi_ex_opcode_3A_1T_1R (
 
 			if ((index + length) >
 				operand[0]->string.length) {
-				length = (acpi_size) operand[0]->string.length - index;
+				length = (acpi_size) operand[0]->string.length -
+						 (acpi_size) index;
 			}
 
 			/* Allocate a new buffer for the String/Buffer */
diff --git a/drivers/acpi/executer/exoparg6.c b/drivers/acpi/executer/exoparg6.c
--- a/drivers/acpi/executer/exoparg6.c
+++ b/drivers/acpi/executer/exoparg6.c
@@ -75,6 +75,14 @@
  * fully resolved operands.
 !*/
 
+/* Local prototypes */
+
+static u8
+acpi_ex_do_match (
+	u32                             match_op,
+	union acpi_operand_object       *package_obj,
+	union acpi_operand_object       *match_obj);
+
 
 /*******************************************************************************
  *
@@ -92,7 +100,7 @@
  *
  ******************************************************************************/
 
-u8
+static u8
 acpi_ex_do_match (
 	u32                             match_op,
 	union acpi_operand_object       *package_obj,
@@ -216,11 +224,12 @@ acpi_ex_opcode_6A_0T_1R (
 	union acpi_operand_object       **operand = &walk_state->operands[0];
 	union acpi_operand_object       *return_desc = NULL;
 	acpi_status                     status = AE_OK;
-	u32                             index;
+	acpi_integer                    index;
 	union acpi_operand_object       *this_element;
 
 
-	ACPI_FUNCTION_TRACE_STR ("ex_opcode_6A_0T_1R", acpi_ps_get_opcode_name (walk_state->opcode));
+	ACPI_FUNCTION_TRACE_STR ("ex_opcode_6A_0T_1R",
+		acpi_ps_get_opcode_name (walk_state->opcode));
 
 
 	switch (walk_state->opcode) {
@@ -241,9 +250,11 @@ acpi_ex_opcode_6A_0T_1R (
 
 		/* Get the package start_index, validate against the package length */
 
-		index = (u32) operand[5]->integer.value;
-		if (index >= (u32) operand[0]->package.count) {
-			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Index beyond package end\n"));
+		index = operand[5]->integer.value;
+		if (index >= operand[0]->package.count) {
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+				"Index (%X%8.8X) beyond package end (%X)\n",
+				ACPI_FORMAT_UINT64 (index), operand[0]->package.count));
 			status = AE_AML_PACKAGE_LIMIT;
 			goto cleanup;
 		}
@@ -314,13 +325,12 @@ acpi_ex_opcode_6A_0T_1R (
 
 	default:
 
-		ACPI_REPORT_ERROR (("acpi_ex_opcode_3A_0T_0R: Unknown opcode %X\n",
+		ACPI_REPORT_ERROR (("acpi_ex_opcode_6A_0T_1R: Unknown opcode %X\n",
 				walk_state->opcode));
 		status = AE_AML_BAD_OPCODE;
 		goto cleanup;
 	}
 
-
 	walk_state->result_obj = return_desc;
 
 
diff --git a/drivers/acpi/executer/exprep.c b/drivers/acpi/executer/exprep.c
--- a/drivers/acpi/executer/exprep.c
+++ b/drivers/acpi/executer/exprep.c
@@ -52,8 +52,23 @@
 #define _COMPONENT          ACPI_EXECUTER
 	 ACPI_MODULE_NAME    ("exprep")
 
+/* Local prototypes */
+
+static u32
+acpi_ex_decode_field_access (
+	union acpi_operand_object       *obj_desc,
+	u8                              field_flags,
+	u32                             *return_byte_alignment);
+
 
 #ifdef ACPI_UNDER_DEVELOPMENT
+
+static u32
+acpi_ex_generate_access (
+	u32                             field_bit_offset,
+	u32                             field_bit_length,
+	u32                             region_length);
+
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ex_generate_access
@@ -99,12 +114,14 @@ acpi_ex_generate_access (
 	/* Round Field start offset and length to "minimal" byte boundaries */
 
 	field_byte_offset  = ACPI_DIV_8 (ACPI_ROUND_DOWN (field_bit_offset, 8));
-	field_byte_end_offset = ACPI_DIV_8 (ACPI_ROUND_UP (field_bit_length + field_bit_offset, 8));
+	field_byte_end_offset = ACPI_DIV_8 (ACPI_ROUND_UP (field_bit_length +
+			   field_bit_offset, 8));
 	field_byte_length  = field_byte_end_offset - field_byte_offset;
 
 	ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
 			"Bit length %d, Bit offset %d\n",
 			field_bit_length, field_bit_offset));
+
 	ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
 			"Byte Length %d, Byte Offset %d, End Offset %d\n",
 			field_byte_length, field_byte_offset, field_byte_end_offset));
@@ -117,20 +134,26 @@ acpi_ex_generate_access (
 	 */
 	for (access_byte_width = 1; access_byte_width <= 8; access_byte_width <<= 1) {
 		/*
-		 * 1) Round end offset up to next access boundary and make sure that this
-		 *    does not go beyond the end of the parent region.
-		 * 2) When the Access width is greater than the field_byte_length, we are done.
-		 *    (This does not optimize for the perfectly aligned case yet).
+		 * 1) Round end offset up to next access boundary and make sure that
+		 *    this does not go beyond the end of the parent region.
+		 * 2) When the Access width is greater than the field_byte_length, we
+		 *    are done. (This does not optimize for the perfectly aligned
+		 *    case yet).
 		 */
 		if (ACPI_ROUND_UP (field_byte_end_offset, access_byte_width) <= region_length) {
-			field_start_offset = ACPI_ROUND_DOWN (field_byte_offset, access_byte_width) /
-					  access_byte_width;
-			field_end_offset = ACPI_ROUND_UP   ((field_byte_length + field_byte_offset),
-					  access_byte_width) / access_byte_width;
-			accesses         = field_end_offset - field_start_offset;
+			field_start_offset =
+				ACPI_ROUND_DOWN (field_byte_offset, access_byte_width) /
+				access_byte_width;
+
+			field_end_offset =
+				ACPI_ROUND_UP ((field_byte_length + field_byte_offset),
+					access_byte_width) / access_byte_width;
+
+			accesses = field_end_offset - field_start_offset;
 
 			ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
 					"access_width %d end is within region\n", access_byte_width));
+
 			ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
 					"Field Start %d, Field End %d -- requires %d accesses\n",
 					field_start_offset, field_end_offset, accesses));
@@ -139,8 +162,8 @@ acpi_ex_generate_access (
 
 			if (accesses <= 1) {
 				ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
-						"Entire field can be accessed with one operation of size %d\n",
-						access_byte_width));
+					"Entire field can be accessed with one operation of size %d\n",
+					access_byte_width));
 				return_VALUE (access_byte_width);
 			}
 
@@ -155,15 +178,20 @@ acpi_ex_generate_access (
 		}
 		else {
 			ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
-					"access_width %d end is NOT within region\n", access_byte_width));
+				"access_width %d end is NOT within region\n", access_byte_width));
 			if (access_byte_width == 1) {
 				ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
 						"Field goes beyond end-of-region!\n"));
-				return_VALUE (0);     /* Field does not fit in the region at all */
-			}
 
-			/* This width goes beyond the end-of-region, back off to previous access */
+				/* Field does not fit in the region at all */
 
+				return_VALUE (0);
+			}
+
+			/*
+			 * This width goes beyond the end-of-region, back off to
+			 * previous access
+			 */
 			ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
 					"Backing off to previous optimal access width of %d\n",
 					minimum_access_width));
@@ -171,8 +199,10 @@ acpi_ex_generate_access (
 		}
 	}
 
-	/* Could not read/write field with one operation, just use max access width */
-
+	/*
+	 * Could not read/write field with one operation,
+	 * just use max access width
+	 */
 	ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
 			"Cannot access field in one operation, using width 8\n"));
 	return_VALUE (8);
@@ -184,8 +214,9 @@ acpi_ex_generate_access (
  *
  * FUNCTION:    acpi_ex_decode_field_access
  *
- * PARAMETERS:  Access          - Encoded field access bits
- *              Length          - Field length.
+ * PARAMETERS:  obj_desc            - Field object
+ *              field_flags         - Encoded fieldflags (contains access bits)
+ *              return_byte_alignment - Where the byte alignment is returned
  *
  * RETURN:      Field granularity (8, 16, 32 or 64) and
  *              byte_alignment (1, 2, 3, or 4)
@@ -214,9 +245,10 @@ acpi_ex_decode_field_access (
 	case AML_FIELD_ACCESS_ANY:
 
 #ifdef ACPI_UNDER_DEVELOPMENT
-		byte_alignment = acpi_ex_generate_access (obj_desc->common_field.start_field_bit_offset,
-				 obj_desc->common_field.bit_length,
-				 0xFFFFFFFF /* Temp until we pass region_length as param */);
+		byte_alignment =
+			acpi_ex_generate_access (obj_desc->common_field.start_field_bit_offset,
+				obj_desc->common_field.bit_length,
+				0xFFFFFFFF /* Temp until we pass region_length as parameter */);
 		bit_length = byte_alignment * 8;
 #endif
 
@@ -276,6 +308,7 @@ acpi_ex_decode_field_access (
  *              field_flags         - Access, lock_rule, and update_rule.
  *                                    The format of a field_flag is described
  *                                    in the ACPI specification
+ *              field_attribute     - Special attributes (not used)
  *              field_bit_position  - Field start position
  *              field_bit_length    - Field length in number of bits
  *
@@ -337,7 +370,7 @@ acpi_ex_prep_common_field_object (
 	/* Setup width (access granularity) fields */
 
 	obj_desc->common_field.access_byte_width = (u8)
-			ACPI_DIV_8 (access_bit_width); /* 1, 2, 4,  8 */
+			ACPI_DIV_8 (access_bit_width);          /* 1,  2,  4,  8 */
 
 	obj_desc->common_field.access_bit_width = (u8) access_bit_width;
 
@@ -380,11 +413,7 @@ acpi_ex_prep_common_field_object (
  *
  * FUNCTION:    acpi_ex_prep_field_value
  *
- * PARAMETERS:  Node                - Owning Node
- *              region_node         - Region in which field is being defined
- *              field_flags         - Access, lock_rule, and update_rule.
- *              field_bit_position  - Field start position
- *              field_bit_length    - Field length in number of bits
+ * PARAMETERS:  Info    - Contains all field creation info
  *
  * RETURN:      Status
  *
@@ -445,7 +474,7 @@ acpi_ex_prep_field_value (
 	switch (info->field_type) {
 	case ACPI_TYPE_LOCAL_REGION_FIELD:
 
-		obj_desc->field.region_obj   = acpi_ns_get_attached_object (info->region_node);
+		obj_desc->field.region_obj = acpi_ns_get_attached_object (info->region_node);
 
 		/* An additional reference for the container */
 
@@ -461,8 +490,10 @@ acpi_ex_prep_field_value (
 	case ACPI_TYPE_LOCAL_BANK_FIELD:
 
 		obj_desc->bank_field.value   = info->bank_value;
-		obj_desc->bank_field.region_obj = acpi_ns_get_attached_object (info->region_node);
-		obj_desc->bank_field.bank_obj = acpi_ns_get_attached_object (info->register_node);
+		obj_desc->bank_field.region_obj = acpi_ns_get_attached_object (
+				 info->region_node);
+		obj_desc->bank_field.bank_obj = acpi_ns_get_attached_object (
+				 info->register_node);
 
 		/* An additional reference for the attached objects */
 
@@ -481,10 +512,13 @@ acpi_ex_prep_field_value (
 
 	case ACPI_TYPE_LOCAL_INDEX_FIELD:
 
-		obj_desc->index_field.index_obj = acpi_ns_get_attached_object (info->register_node);
-		obj_desc->index_field.data_obj = acpi_ns_get_attached_object (info->data_register_node);
+		obj_desc->index_field.index_obj = acpi_ns_get_attached_object (
+				 info->register_node);
+		obj_desc->index_field.data_obj = acpi_ns_get_attached_object (
+				 info->data_register_node);
 		obj_desc->index_field.value  = (u32)
-			(info->field_bit_position / ACPI_MUL_8 (obj_desc->field.access_byte_width));
+			(info->field_bit_position / ACPI_MUL_8 (
+					  obj_desc->field.access_byte_width));
 
 		if (!obj_desc->index_field.data_obj || !obj_desc->index_field.index_obj) {
 			ACPI_REPORT_ERROR (("Null Index Object during field prep\n"));
diff --git a/drivers/acpi/executer/exregion.c b/drivers/acpi/executer/exregion.c
--- a/drivers/acpi/executer/exregion.c
+++ b/drivers/acpi/executer/exregion.c
@@ -115,7 +115,6 @@ acpi_ex_system_memory_space_handler (
 		return_ACPI_STATUS (AE_AML_OPERAND_VALUE);
 	}
 
-
 #ifndef ACPI_MISALIGNED_TRANSFERS
 	/*
 	 * Hardware does not support non-aligned data transfers, we must verify
@@ -134,7 +133,8 @@ acpi_ex_system_memory_space_handler (
 	 */
 	if ((address < mem_info->mapped_physical_address) ||
 		(((acpi_integer) address + length) >
-			((acpi_integer) mem_info->mapped_physical_address + mem_info->mapped_length))) {
+			((acpi_integer)
+			mem_info->mapped_physical_address + mem_info->mapped_length))) {
 		/*
 		 * The request cannot be resolved by the current memory mapping;
 		 * Delete the existing mapping and create a new one.
@@ -150,7 +150,9 @@ acpi_ex_system_memory_space_handler (
 		 * Don't attempt to map memory beyond the end of the region, and
 		 * constrain the maximum mapping size to something reasonable.
 		 */
-		window_size = (acpi_size) ((mem_info->address + mem_info->length) - address);
+		window_size = (acpi_size)
+			((mem_info->address + mem_info->length) - address);
+
 		if (window_size > ACPI_SYSMEM_REGION_WINDOW_SIZE) {
 			window_size = ACPI_SYSMEM_REGION_WINDOW_SIZE;
 		}
@@ -160,8 +162,9 @@ acpi_ex_system_memory_space_handler (
 		status = acpi_os_map_memory (address, window_size,
 				  (void **) &mem_info->mapped_logical_address);
 		if (ACPI_FAILURE (status)) {
-			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not map memory at %8.8X%8.8X, size %X\n",
-					ACPI_FORMAT_UINT64 (address), (u32) window_size));
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+				"Could not map memory at %8.8X%8.8X, size %X\n",
+				ACPI_FORMAT_UINT64 (address), (u32) window_size));
 			mem_info->mapped_length = 0;
 			return_ACPI_STATUS (status);
 		}
@@ -177,10 +180,12 @@ acpi_ex_system_memory_space_handler (
 	 * access
 	 */
 	logical_addr_ptr = mem_info->mapped_logical_address +
-			  ((acpi_integer) address - (acpi_integer) mem_info->mapped_physical_address);
+			   ((acpi_integer) address -
+					  (acpi_integer) mem_info->mapped_physical_address);
 
 	ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
-			"system_memory %d (%d width) Address=%8.8X%8.8X\n", function, bit_width,
+			"system_memory %d (%d width) Address=%8.8X%8.8X\n",
+			function, bit_width,
 			ACPI_FORMAT_UINT64 (address)));
 
    /*
@@ -298,13 +303,15 @@ acpi_ex_system_io_space_handler (
 	switch (function) {
 	case ACPI_READ:
 
-		status = acpi_os_read_port ((acpi_io_address) address, &value32, bit_width);
+		status = acpi_os_read_port ((acpi_io_address) address,
+				 &value32, bit_width);
 		*value = value32;
 		break;
 
 	case ACPI_WRITE:
 
-		status = acpi_os_write_port ((acpi_io_address) address, (u32) *value, bit_width);
+		status = acpi_os_write_port ((acpi_io_address) address,
+				 (u32) *value, bit_width);
 		break;
 
 	default:
@@ -375,12 +382,14 @@ acpi_ex_pci_config_space_handler (
 	case ACPI_READ:
 
 		*value = 0;
-		status = acpi_os_read_pci_configuration (pci_id, pci_register, value, bit_width);
+		status = acpi_os_read_pci_configuration (pci_id, pci_register,
+				 value, bit_width);
 		break;
 
 	case ACPI_WRITE:
 
-		status = acpi_os_write_pci_configuration (pci_id, pci_register, *value, bit_width);
+		status = acpi_os_write_pci_configuration (pci_id, pci_register,
+				 *value, bit_width);
 		break;
 
 	default:
@@ -505,8 +514,7 @@ acpi_ex_data_table_space_handler (
 
 	logical_addr_ptr = ACPI_PHYSADDR_TO_PTR (address);
 
-
-   /* Perform the memory read or write */
+	/* Perform the memory read or write */
 
 	switch (function) {
 	case ACPI_READ:
diff --git a/drivers/acpi/executer/exresnte.c b/drivers/acpi/executer/exresnte.c
--- a/drivers/acpi/executer/exresnte.c
+++ b/drivers/acpi/executer/exresnte.c
@@ -210,15 +210,15 @@ acpi_ex_resolve_node_to_value (
 	case ACPI_TYPE_LOCAL_BANK_FIELD:
 	case ACPI_TYPE_LOCAL_INDEX_FIELD:
 
-		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "field_read Node=%p source_desc=%p Type=%X\n",
+		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+			"field_read Node=%p source_desc=%p Type=%X\n",
 			node, source_desc, entry_type));
 
 		status = acpi_ex_read_data_from_field (walk_state, source_desc, &obj_desc);
 		break;
 
-	/*
-	 * For these objects, just return the object attached to the Node
-	 */
+	/* For these objects, just return the object attached to the Node */
+
 	case ACPI_TYPE_MUTEX:
 	case ACPI_TYPE_METHOD:
 	case ACPI_TYPE_POWER:
@@ -233,12 +233,12 @@ acpi_ex_resolve_node_to_value (
 		acpi_ut_add_reference (obj_desc);
 		break;
 
-
 	/* TYPE_ANY is untyped, and thus there is no object associated with it */
 
 	case ACPI_TYPE_ANY:
 
-		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Untyped entry %p, no attached object!\n",
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"Untyped entry %p, no attached object!\n",
 			node));
 
 		return_ACPI_STATUS (AE_AML_OPERAND_TYPE);  /* Cannot be AE_TYPE */
@@ -259,7 +259,8 @@ acpi_ex_resolve_node_to_value (
 		default:
 			/* No named references are allowed here */
 
-			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unsupported Reference opcode %X (%s)\n",
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+				"Unsupported Reference opcode %X (%s)\n",
 				source_desc->reference.opcode,
 				acpi_ps_get_opcode_name (source_desc->reference.opcode)));
 
@@ -268,11 +269,12 @@ acpi_ex_resolve_node_to_value (
 		break;
 
 
-	/* Default case is for unknown types */
-
 	default:
 
-		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Node %p - Unknown object type %X\n",
+		/* Default case is for unknown types */
+
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"Node %p - Unknown object type %X\n",
 			node, entry_type));
 
 		return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
@@ -280,7 +282,7 @@ acpi_ex_resolve_node_to_value (
 	} /* switch (entry_type) */
 
 
-	/* Put the object descriptor on the stack */
+	/* Return the object descriptor */
 
 	*object_ptr = (void *) obj_desc;
 	return_ACPI_STATUS (status);
diff --git a/drivers/acpi/executer/exresolv.c b/drivers/acpi/executer/exresolv.c
--- a/drivers/acpi/executer/exresolv.c
+++ b/drivers/acpi/executer/exresolv.c
@@ -54,6 +54,13 @@
 #define _COMPONENT          ACPI_EXECUTER
 	 ACPI_MODULE_NAME    ("exresolv")
 
+/* Local prototypes */
+
+static acpi_status
+acpi_ex_resolve_object_to_value (
+	union acpi_operand_object       **stack_ptr,
+	struct acpi_walk_state          *walk_state);
+
 
 /*******************************************************************************
  *
@@ -96,6 +103,11 @@ acpi_ex_resolve_to_value (
 		if (ACPI_FAILURE (status)) {
 			return_ACPI_STATUS (status);
 		}
+
+		if (!*stack_ptr) {
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Internal - null pointer\n"));
+			return_ACPI_STATUS (AE_AML_NO_OPERAND);
+		}
 	}
 
 	/*
@@ -120,18 +132,17 @@ acpi_ex_resolve_to_value (
  *
  * FUNCTION:    acpi_ex_resolve_object_to_value
  *
- * PARAMETERS:  stack_ptr       - Pointer to a stack location that contains a
- *                                ptr to an internal object.
+ * PARAMETERS:  stack_ptr       - Pointer to an internal object
  *              walk_state      - Current method state
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Retrieve the value from an internal object.  The Reference type
+ * DESCRIPTION: Retrieve the value from an internal object. The Reference type
  *              uses the associated AML opcode to determine the value.
  *
  ******************************************************************************/
 
-acpi_status
+static acpi_status
 acpi_ex_resolve_object_to_value (
 	union acpi_operand_object       **stack_ptr,
 	struct acpi_walk_state          *walk_state)
@@ -159,7 +170,7 @@ acpi_ex_resolve_object_to_value (
 		case AML_NAME_OP:
 
 			/*
-			 * Convert indirect name ptr to a direct name ptr.
+			 * Convert name reference to a namespace node
 			 * Then, acpi_ex_resolve_node_to_value can be used to get the value
 			 */
 			temp_node = stack_desc->reference.object;
@@ -168,7 +179,7 @@ acpi_ex_resolve_object_to_value (
 
 			acpi_ut_remove_reference (stack_desc);
 
-			/* Put direct name pointer onto stack and exit */
+			/* Return the namespace node */
 
 			(*stack_ptr) = temp_node;
 			break;
@@ -255,10 +266,19 @@ acpi_ex_resolve_object_to_value (
 
 			break;
 
+		case AML_INT_NAMEPATH_OP:   /* Reference to a named object */
+
+			/* Get the object pointed to by the namespace node */
+
+			*stack_ptr = (stack_desc->reference.node)->object;
+			acpi_ut_add_reference (*stack_ptr);
+			acpi_ut_remove_reference (stack_desc);
+			break;
 
 		default:
 
-			ACPI_REPORT_ERROR (("During resolve, Unknown Reference opcode %X (%s) in %p\n",
+			ACPI_REPORT_ERROR ((
+				"During resolve, Unknown Reference opcode %X (%s) in %p\n",
 				opcode, acpi_ps_get_opcode_name (opcode), stack_desc));
 			status = AE_AML_INTERNAL;
 			break;
@@ -278,9 +298,8 @@ acpi_ex_resolve_object_to_value (
 		break;
 
 
-	/*
-	 * These cases may never happen here, but just in case..
-	 */
+	/* These cases may never happen here, but just in case.. */
+
 	case ACPI_TYPE_BUFFER_FIELD:
 	case ACPI_TYPE_LOCAL_REGION_FIELD:
 	case ACPI_TYPE_LOCAL_BANK_FIELD:
@@ -333,9 +352,8 @@ acpi_ex_resolve_multiple (
 	ACPI_FUNCTION_TRACE ("acpi_ex_resolve_multiple");
 
 
-	/*
-	 * Operand can be either a namespace node or an operand descriptor
-	 */
+	/* Operand can be either a namespace node or an operand descriptor */
+
 	switch (ACPI_GET_DESCRIPTOR_TYPE (obj_desc)) {
 	case ACPI_DESC_TYPE_OPERAND:
 		type = obj_desc->common.type;
@@ -357,10 +375,8 @@ acpi_ex_resolve_multiple (
 		return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
 	}
 
+	/* If type is anything other than a reference, we are done */
 
-	/*
-	 * If type is anything other than a reference, we are done
-	 */
 	if (type != ACPI_TYPE_LOCAL_REFERENCE) {
 		goto exit;
 	}
@@ -382,8 +398,9 @@ acpi_ex_resolve_multiple (
 			/* All "References" point to a NS node */
 
 			if (ACPI_GET_DESCRIPTOR_TYPE (node) != ACPI_DESC_TYPE_NAMED) {
-				ACPI_REPORT_ERROR (("acpi_ex_resolve_multiple: Not a NS node %p [%s]\n",
-						node, acpi_ut_get_descriptor_name (node)));
+				ACPI_REPORT_ERROR ((
+					"acpi_ex_resolve_multiple: Not a NS node %p [%s]\n",
+					node, acpi_ut_get_descriptor_name (node)));
 				return_ACPI_STATUS (AE_AML_INTERNAL);
 			}
 
@@ -440,8 +457,9 @@ acpi_ex_resolve_multiple (
 			/* All "References" point to a NS node */
 
 			if (ACPI_GET_DESCRIPTOR_TYPE (node) != ACPI_DESC_TYPE_NAMED) {
-				ACPI_REPORT_ERROR (("acpi_ex_resolve_multiple: Not a NS node %p [%s]\n",
-						node, acpi_ut_get_descriptor_name (node)));
+				ACPI_REPORT_ERROR ((
+					"acpi_ex_resolve_multiple: Not a NS node %p [%s]\n",
+					node, acpi_ut_get_descriptor_name (node)));
 			   return_ACPI_STATUS (AE_AML_INTERNAL);
 			}
 
@@ -468,7 +486,7 @@ acpi_ex_resolve_multiple (
 
 			if (return_desc) {
 				status = acpi_ds_method_data_get_value (obj_desc->reference.opcode,
-						  obj_desc->reference.offset, walk_state, &obj_desc);
+						 obj_desc->reference.offset, walk_state, &obj_desc);
 				if (ACPI_FAILURE (status)) {
 					return_ACPI_STATUS (status);
 				}
@@ -500,7 +518,8 @@ acpi_ex_resolve_multiple (
 
 		default:
 
-			ACPI_REPORT_ERROR (("acpi_ex_resolve_multiple: Unknown Reference subtype %X\n",
+			ACPI_REPORT_ERROR ((
+				"acpi_ex_resolve_multiple: Unknown Reference subtype %X\n",
 				obj_desc->reference.opcode));
 			return_ACPI_STATUS (AE_AML_INTERNAL);
 		}
diff --git a/drivers/acpi/executer/exresop.c b/drivers/acpi/executer/exresop.c
--- a/drivers/acpi/executer/exresop.c
+++ b/drivers/acpi/executer/exresop.c
@@ -52,6 +52,14 @@
 #define _COMPONENT          ACPI_EXECUTER
 	 ACPI_MODULE_NAME    ("exresop")
 
+/* Local prototypes */
+
+static acpi_status
+acpi_ex_check_object_type (
+	acpi_object_type                type_needed,
+	acpi_object_type                this_type,
+	void                            *object);
+
 
 /*******************************************************************************
  *
@@ -67,7 +75,7 @@
  *
  ******************************************************************************/
 
-acpi_status
+static acpi_status
 acpi_ex_check_object_type (
 	acpi_object_type                type_needed,
 	acpi_object_type                this_type,
@@ -142,6 +150,7 @@ acpi_ex_resolve_operands (
 	const struct acpi_opcode_info   *op_info;
 	u32                             this_arg_type;
 	acpi_object_type                type_needed;
+	u16                             target_op = 0;
 
 
 	ACPI_FUNCTION_TRACE_U32 ("ex_resolve_operands", opcode);
@@ -160,7 +169,8 @@ acpi_ex_resolve_operands (
 		return_ACPI_STATUS (AE_AML_INTERNAL);
 	}
 
-	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Opcode %X [%s] required_operand_types=%8.8X \n",
+	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+		"Opcode %X [%s] required_operand_types=%8.8X \n",
 		opcode, op_info->name, arg_types));
 
 	/*
@@ -187,7 +197,7 @@ acpi_ex_resolve_operands (
 		switch (ACPI_GET_DESCRIPTOR_TYPE (obj_desc)) {
 		case ACPI_DESC_TYPE_NAMED:
 
-			/* Node */
+			/* Namespace Node */
 
 			object_type = ((struct acpi_namespace_node *) obj_desc)->type;
 			break;
@@ -202,16 +212,16 @@ acpi_ex_resolve_operands (
 			/* Check for bad acpi_object_type */
 
 			if (!acpi_ut_valid_object_type (object_type)) {
-				ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Bad operand object type [%X]\n",
+				ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+					"Bad operand object type [%X]\n",
 					object_type));
 
 				return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
 			}
 
 			if (object_type == (u8) ACPI_TYPE_LOCAL_REFERENCE) {
-				/*
-				 * Decode the Reference
-				 */
+				/* Decode the Reference */
+
 				op_info = acpi_ps_get_opcode_info (opcode);
 				if (op_info->class == AML_CLASS_UNKNOWN) {
 					return_ACPI_STATUS (AE_AML_BAD_OPCODE);
@@ -219,12 +229,17 @@ acpi_ex_resolve_operands (
 
 				switch (obj_desc->reference.opcode) {
 				case AML_DEBUG_OP:
+					target_op = AML_DEBUG_OP;
+
+					/*lint -fallthrough */
+
 				case AML_NAME_OP:
 				case AML_INDEX_OP:
 				case AML_REF_OF_OP:
 				case AML_ARG_OP:
 				case AML_LOCAL_OP:
-				case AML_LOAD_OP:   /* ddb_handle from LOAD_OP or LOAD_TABLE_OP */
+				case AML_LOAD_OP: /* ddb_handle from LOAD_OP or LOAD_TABLE_OP */
+				case AML_INT_NAMEPATH_OP: /* Reference to a named object */
 
 					ACPI_DEBUG_ONLY_MEMBERS (ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
 						"Operand is a Reference, ref_opcode [%s]\n",
@@ -254,10 +269,8 @@ acpi_ex_resolve_operands (
 			return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
 		}
 
+		/* Get one argument type, point to the next */
 
-		/*
-		 * Get one argument type, point to the next
-		 */
 		this_arg_type = GET_CURRENT_ARG_TYPE (arg_types);
 		INCREMENT_ARG_LIST (arg_types);
 
@@ -271,26 +284,31 @@ acpi_ex_resolve_operands (
 			if ((ACPI_GET_DESCRIPTOR_TYPE (obj_desc) == ACPI_DESC_TYPE_OPERAND) &&
 				(ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_STRING)) {
 				/*
-				 * String found - the string references a named object and must be
-				 * resolved to a node
+				 * String found - the string references a named object and
+				 * must be resolved to a node
 				 */
 				goto next_operand;
 			}
 
-			/* Else not a string - fall through to the normal Reference case below */
+			/*
+			 * Else not a string - fall through to the normal Reference
+			 * case below
+			 */
 			/*lint -fallthrough */
 
 		case ARGI_REFERENCE:            /* References: */
 		case ARGI_INTEGER_REF:
 		case ARGI_OBJECT_REF:
 		case ARGI_DEVICE_REF:
-		case ARGI_TARGETREF:            /* Allows implicit conversion rules before store */
-		case ARGI_FIXED_TARGET:         /* No implicit conversion before store to target */
-		case ARGI_SIMPLE_TARGET:        /* Name, Local, or Arg - no implicit conversion  */
-
-			/* Need an operand of type ACPI_TYPE_LOCAL_REFERENCE */
+		case ARGI_TARGETREF:     /* Allows implicit conversion rules before store */
+		case ARGI_FIXED_TARGET:  /* No implicit conversion before store to target */
+		case ARGI_SIMPLE_TARGET: /* Name, Local, or Arg - no implicit conversion  */
 
-			if (ACPI_GET_DESCRIPTOR_TYPE (obj_desc) == ACPI_DESC_TYPE_NAMED) /* Node (name) ptr OK as-is */ {
+			/*
+			 * Need an operand of type ACPI_TYPE_LOCAL_REFERENCE
+			 * A Namespace Node is OK as-is
+			 */
+			if (ACPI_GET_DESCRIPTOR_TYPE (obj_desc) == ACPI_DESC_TYPE_NAMED) {
 				goto next_operand;
 			}
 
@@ -300,11 +318,9 @@ acpi_ex_resolve_operands (
 				return_ACPI_STATUS (status);
 			}
 
-			if (AML_NAME_OP == obj_desc->reference.opcode) {
-				/*
-				 * Convert an indirect name ptr to direct name ptr and put
-				 * it on the stack
-				 */
+			if (obj_desc->reference.opcode == AML_NAME_OP) {
+				/* Convert a named reference to the actual named object */
+
 				temp_node = obj_desc->reference.object;
 				acpi_ut_remove_reference (obj_desc);
 				(*stack_ptr) = temp_node;
@@ -332,7 +348,6 @@ acpi_ex_resolve_operands (
 			break;
 		}
 
-
 		/*
 		 * Resolve this object to a value
 		 */
@@ -392,7 +407,7 @@ acpi_ex_resolve_operands (
 		/*
 		 * The more complex cases allow multiple resolved object types
 		 */
-		case ARGI_INTEGER:   /* Number */
+		case ARGI_INTEGER:
 
 			/*
 			 * Need an operand of type ACPI_TYPE_INTEGER,
@@ -563,7 +578,7 @@ acpi_ex_resolve_operands (
 
 		case ARGI_REGION_OR_FIELD:
 
-			/* Need an operand of type ACPI_TYPE_REGION or a FIELD in a region */
+			/* Need an operand of type REGION or a FIELD in a region */
 
 			switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
 			case ACPI_TYPE_REGION:
@@ -614,6 +629,12 @@ acpi_ex_resolve_operands (
 					break;
 				}
 
+				if (target_op == AML_DEBUG_OP) {
+					/* Allow store of any object to the Debug object */
+
+					break;
+				}
+
 				ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
 					"Needed Integer/Buffer/String/Package/Ref/Ddb], found [%s] %p\n",
 					acpi_ut_get_object_type_name (obj_desc), obj_desc));
@@ -652,8 +673,7 @@ next_operand:
 		if (GET_CURRENT_ARG_TYPE (arg_types)) {
 			stack_ptr--;
 		}
-
-	}   /* while (*Types) */
+	}
 
 	return_ACPI_STATUS (status);
 }
diff --git a/drivers/acpi/executer/exstore.c b/drivers/acpi/executer/exstore.c
--- a/drivers/acpi/executer/exstore.c
+++ b/drivers/acpi/executer/exstore.c
@@ -48,11 +48,171 @@
 #include <acpi/acinterp.h>
 #include <acpi/amlcode.h>
 #include <acpi/acnamesp.h>
+#include <acpi/acparser.h>
 
 
 #define _COMPONENT          ACPI_EXECUTER
 	 ACPI_MODULE_NAME    ("exstore")
 
+/* Local prototypes */
+
+static void
+acpi_ex_do_debug_object (
+	union acpi_operand_object       *source_desc,
+	u32                             level,
+	u32                             index);
+
+static acpi_status
+acpi_ex_store_object_to_index (
+	union acpi_operand_object       *val_desc,
+	union acpi_operand_object       *dest_desc,
+	struct acpi_walk_state          *walk_state);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_do_debug_object
+ *
+ * PARAMETERS:  source_desc         - Value to be stored
+ *              Level               - Indentation level (used for packages)
+ *              Index               - Current package element, zero if not pkg
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Handles stores to the Debug Object.
+ *
+ ******************************************************************************/
+
+static void
+acpi_ex_do_debug_object (
+	union acpi_operand_object       *source_desc,
+	u32                             level,
+	u32                             index)
+{
+	u32                             i;
+
+
+	ACPI_FUNCTION_TRACE_PTR ("ex_do_debug_object", source_desc);
+
+
+	ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "[ACPI Debug] %*s",
+		level, " "));
+
+	/* Display index for package output only */
+
+	if (index > 0) {
+	   ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT,
+		   "(%.2u) ", index -1));
+	}
+
+	if (!source_desc) {
+		ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "<Null Object>\n"));
+		return_VOID;
+	}
+
+	if (ACPI_GET_DESCRIPTOR_TYPE (source_desc) == ACPI_DESC_TYPE_OPERAND) {
+		ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "%s: ",
+			acpi_ut_get_object_type_name (source_desc)));
+
+		if (!acpi_ut_valid_internal_object (source_desc)) {
+		   ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT,
+			   "%p, Invalid Internal Object!\n", source_desc));
+		   return_VOID;
+		}
+	}
+	else if (ACPI_GET_DESCRIPTOR_TYPE (source_desc) == ACPI_DESC_TYPE_NAMED) {
+		ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "%s: %p\n",
+			acpi_ut_get_type_name (((struct acpi_namespace_node *) source_desc)->type),
+			source_desc));
+		return_VOID;
+	}
+	else {
+		return_VOID;
+	}
+
+	switch (ACPI_GET_OBJECT_TYPE (source_desc)) {
+	case ACPI_TYPE_INTEGER:
+
+		/* Output correct integer width */
+
+		if (acpi_gbl_integer_byte_width == 4) {
+			ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "0x%8.8X\n",
+				(u32) source_desc->integer.value));
+		}
+		else {
+			ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "0x%8.8X%8.8X\n",
+				ACPI_FORMAT_UINT64 (source_desc->integer.value)));
+		}
+		break;
+
+	case ACPI_TYPE_BUFFER:
+
+		ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "[0x%.2X]",
+			(u32) source_desc->buffer.length));
+		ACPI_DUMP_BUFFER (source_desc->buffer.pointer,
+			(source_desc->buffer.length < 32) ? source_desc->buffer.length : 32);
+		break;
+
+	case ACPI_TYPE_STRING:
+
+		ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "[0x%.2X] \"%s\"\n",
+			source_desc->string.length, source_desc->string.pointer));
+		break;
+
+	case ACPI_TYPE_PACKAGE:
+
+		ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "[0x%.2X Elements]\n",
+			source_desc->package.count));
+
+		/* Output the entire contents of the package */
+
+		for (i = 0; i < source_desc->package.count; i++) {
+			acpi_ex_do_debug_object (source_desc->package.elements[i],
+				level+4, i+1);
+		}
+		break;
+
+	case ACPI_TYPE_LOCAL_REFERENCE:
+
+		if (source_desc->reference.opcode == AML_INDEX_OP) {
+			ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "[%s, 0x%X]\n",
+				acpi_ps_get_opcode_name (source_desc->reference.opcode),
+				source_desc->reference.offset));
+		}
+		else {
+			ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "[%s]\n",
+				acpi_ps_get_opcode_name (source_desc->reference.opcode)));
+		}
+
+
+		if (source_desc->reference.object) {
+			if (ACPI_GET_DESCRIPTOR_TYPE (source_desc->reference.object) ==
+					ACPI_DESC_TYPE_NAMED) {
+				acpi_ex_do_debug_object (((struct acpi_namespace_node *)
+					source_desc->reference.object)->object,
+					level+4, 0);
+			}
+			else {
+				acpi_ex_do_debug_object (source_desc->reference.object, level+4, 0);
+			}
+		}
+		else if (source_desc->reference.node) {
+			acpi_ex_do_debug_object ((source_desc->reference.node)->object,
+				level+4, 0);
+		}
+		break;
+
+	default:
+
+		ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "%p %s\n",
+			source_desc, acpi_ut_get_object_type_name (source_desc)));
+		break;
+	}
+
+	ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC, "\n"));
+	return_VOID;
+}
+
 
 /*******************************************************************************
  *
@@ -154,8 +314,9 @@ acpi_ex_store (
 
 		/* Storing an object into a Name "container" */
 
-		status = acpi_ex_store_object_to_node (source_desc, ref_desc->reference.object,
-				  walk_state, ACPI_IMPLICIT_CONVERSION);
+		status = acpi_ex_store_object_to_node (source_desc,
+				 ref_desc->reference.object,
+				 walk_state, ACPI_IMPLICIT_CONVERSION);
 		break;
 
 
@@ -173,7 +334,7 @@ acpi_ex_store (
 		/* Store to a method local/arg  */
 
 		status = acpi_ds_store_object_to_local (ref_desc->reference.opcode,
-				  ref_desc->reference.offset, source_desc, walk_state);
+				 ref_desc->reference.offset, source_desc, walk_state);
 		break;
 
 
@@ -187,60 +348,7 @@ acpi_ex_store (
 			"**** Write to Debug Object: Object %p %s ****:\n\n",
 			source_desc, acpi_ut_get_object_type_name (source_desc)));
 
-		ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "[ACPI Debug] %s: ",
-			acpi_ut_get_object_type_name (source_desc)));
-
-		if (!acpi_ut_valid_internal_object (source_desc)) {
-		   ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT,
-			   "%p, Invalid Internal Object!\n", source_desc));
-		   break;
-		}
-
-		switch (ACPI_GET_OBJECT_TYPE (source_desc)) {
-		case ACPI_TYPE_INTEGER:
-
-			if (acpi_gbl_integer_byte_width == 4) {
-				ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "0x%8.8X\n",
-					(u32) source_desc->integer.value));
-			}
-			else {
-				ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "0x%8.8X%8.8X\n",
-					ACPI_FORMAT_UINT64 (source_desc->integer.value)));
-			}
-			break;
-
-
-		case ACPI_TYPE_BUFFER:
-
-			ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "[0x%.2X]",
-				(u32) source_desc->buffer.length));
-			ACPI_DUMP_BUFFER (source_desc->buffer.pointer,
-				(source_desc->buffer.length < 32) ? source_desc->buffer.length : 32);
-			break;
-
-
-		case ACPI_TYPE_STRING:
-
-			ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "[0x%.2X] \"%s\"\n",
-				source_desc->string.length, source_desc->string.pointer));
-			break;
-
-
-		case ACPI_TYPE_PACKAGE:
-
-			ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "[0x%.2X] Elements Ptr - %p\n",
-				source_desc->package.count, source_desc->package.elements));
-			break;
-
-
-		default:
-
-			ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DEBUG_OBJECT, "%p\n",
-				source_desc));
-			break;
-		}
-
-		ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC, "\n"));
+		acpi_ex_do_debug_object (source_desc, 0, 0);
 		break;
 
 
@@ -272,7 +380,7 @@ acpi_ex_store (
  *
  ******************************************************************************/
 
-acpi_status
+static acpi_status
 acpi_ex_store_object_to_index (
 	union acpi_operand_object       *source_desc,
 	union acpi_operand_object       *index_desc,
@@ -313,16 +421,22 @@ acpi_ex_store_object_to_index (
 		if (obj_desc) {
 			/* Decrement reference count by the ref count of the parent package */
 
-			for (i = 0; i < ((union acpi_operand_object *) index_desc->reference.object)->common.reference_count; i++) {
+			for (i = 0;
+				 i < ((union acpi_operand_object *)
+						index_desc->reference.object)->common.reference_count;
+				 i++) {
 				acpi_ut_remove_reference (obj_desc);
 			}
 		}
 
 		*(index_desc->reference.where) = new_desc;
 
-		/* Increment reference count by the ref count of the parent package -1 */
+		/* Increment ref count by the ref count of the parent package-1 */
 
-		for (i = 1; i < ((union acpi_operand_object *) index_desc->reference.object)->common.reference_count; i++) {
+		for (i = 1;
+			 i < ((union acpi_operand_object *)
+					index_desc->reference.object)->common.reference_count;
+			 i++) {
 			acpi_ut_add_reference (new_desc);
 		}
 
@@ -440,9 +554,8 @@ acpi_ex_store_object_to_node (
 	ACPI_FUNCTION_TRACE_PTR ("ex_store_object_to_node", source_desc);
 
 
-	/*
-	 * Get current type of the node, and object attached to Node
-	 */
+	/* Get current type of the node, and object attached to Node */
+
 	target_type = acpi_ns_get_type (node);
 	target_desc = acpi_ns_get_attached_object (node);
 
@@ -467,19 +580,18 @@ acpi_ex_store_object_to_node (
 		target_type = ACPI_TYPE_ANY;
 	}
 
-	/*
-	 * Do the actual store operation
-	 */
+	/* Do the actual store operation */
+
 	switch (target_type) {
 	case ACPI_TYPE_BUFFER_FIELD:
 	case ACPI_TYPE_LOCAL_REGION_FIELD:
 	case ACPI_TYPE_LOCAL_BANK_FIELD:
 	case ACPI_TYPE_LOCAL_INDEX_FIELD:
 
-		/*
-		 * For fields, copy the source data to the target field.
-		 */
-		status = acpi_ex_write_data_to_field (source_desc, target_desc, &walk_state->result_obj);
+		/* For fields, copy the source data to the target field. */
+
+		status = acpi_ex_write_data_to_field (source_desc, target_desc,
+				 &walk_state->result_obj);
 		break;
 
 
@@ -493,7 +605,8 @@ acpi_ex_store_object_to_node (
 		 *
 		 * Copy and/or convert the source object to a new target object
 		 */
-		status = acpi_ex_store_object_to_object (source_desc, target_desc, &new_desc, walk_state);
+		status = acpi_ex_store_object_to_object (source_desc, target_desc,
+				 &new_desc, walk_state);
 		if (ACPI_FAILURE (status)) {
 			return_ACPI_STATUS (status);
 		}
@@ -526,7 +639,8 @@ acpi_ex_store_object_to_node (
 
 		/* No conversions for all other types.  Just attach the source object */
 
-		status = acpi_ns_attach_object (node, source_desc, ACPI_GET_OBJECT_TYPE (source_desc));
+		status = acpi_ns_attach_object (node, source_desc,
+				 ACPI_GET_OBJECT_TYPE (source_desc));
 		break;
 	}
 
diff --git a/drivers/acpi/executer/exstoren.c b/drivers/acpi/executer/exstoren.c
--- a/drivers/acpi/executer/exstoren.c
+++ b/drivers/acpi/executer/exstoren.c
@@ -81,9 +81,8 @@ acpi_ex_resolve_object (
 	ACPI_FUNCTION_TRACE ("ex_resolve_object");
 
 
-	/*
-	 * Ensure we have a Target that can be stored to
-	 */
+	/* Ensure we have a Target that can be stored to */
+
 	switch (target_type) {
 	case ACPI_TYPE_BUFFER_FIELD:
 	case ACPI_TYPE_LOCAL_REGION_FIELD:
@@ -118,16 +117,14 @@ acpi_ex_resolve_object (
 			break;
 		}
 
-		/*
-		 * Must have a Integer, Buffer, or String
-		 */
+		/* Must have a Integer, Buffer, or String */
+
 		if ((ACPI_GET_OBJECT_TYPE (source_desc) != ACPI_TYPE_INTEGER)   &&
 			(ACPI_GET_OBJECT_TYPE (source_desc) != ACPI_TYPE_BUFFER)    &&
 			(ACPI_GET_OBJECT_TYPE (source_desc) != ACPI_TYPE_STRING)    &&
 			!((ACPI_GET_OBJECT_TYPE (source_desc) == ACPI_TYPE_LOCAL_REFERENCE) && (source_desc->reference.opcode == AML_LOAD_OP))) {
-			/*
-			 * Conversion successful but still not a valid type
-			 */
+			/* Conversion successful but still not a valid type */
+
 			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
 				"Cannot assign type %s to %s (must be type Int/Str/Buf)\n",
 				acpi_ut_get_object_type_name (source_desc),
@@ -140,9 +137,8 @@ acpi_ex_resolve_object (
 	case ACPI_TYPE_LOCAL_ALIAS:
 	case ACPI_TYPE_LOCAL_METHOD_ALIAS:
 
-		/*
-		 * Aliases are resolved by acpi_ex_prep_operands
-		 */
+		/* Aliases are resolved by acpi_ex_prep_operands */
+
 		ACPI_REPORT_ERROR (("Store into Alias - should never happen\n"));
 		status = AE_AML_INTERNAL;
 		break;
diff --git a/drivers/acpi/executer/exstorob.c b/drivers/acpi/executer/exstorob.c
--- a/drivers/acpi/executer/exstorob.c
+++ b/drivers/acpi/executer/exstorob.c
@@ -128,7 +128,8 @@ acpi_ex_store_buffer_to_buffer (
 	else {
 		/* Truncate the source, copy only what will fit */
 
-		ACPI_MEMCPY (target_desc->buffer.pointer, buffer, target_desc->buffer.length);
+		ACPI_MEMCPY (target_desc->buffer.pointer, buffer,
+			target_desc->buffer.length);
 
 		ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
 			"Truncating source buffer from %X to %X\n",
@@ -183,7 +184,8 @@ acpi_ex_store_string_to_string (
 		 * String will fit in existing non-static buffer.
 		 * Clear old string and copy in the new one
 		 */
-		ACPI_MEMSET (target_desc->string.pointer, 0, (acpi_size) target_desc->string.length + 1);
+		ACPI_MEMSET (target_desc->string.pointer, 0,
+			(acpi_size) target_desc->string.length + 1);
 		ACPI_MEMCPY (target_desc->string.pointer, buffer, length);
 	}
 	else {
@@ -198,7 +200,8 @@ acpi_ex_store_string_to_string (
 			ACPI_MEM_FREE (target_desc->string.pointer);
 		}
 
-		target_desc->string.pointer = ACPI_MEM_CALLOCATE ((acpi_size) length + 1);
+		target_desc->string.pointer = ACPI_MEM_CALLOCATE (
+				   (acpi_size) length + 1);
 		if (!target_desc->string.pointer) {
 			return_ACPI_STATUS (AE_NO_MEMORY);
 		}
diff --git a/drivers/acpi/executer/exsystem.c b/drivers/acpi/executer/exsystem.c
--- a/drivers/acpi/executer/exsystem.c
+++ b/drivers/acpi/executer/exsystem.c
@@ -55,8 +55,8 @@
  *
  * FUNCTION:    acpi_ex_system_wait_semaphore
  *
- * PARAMETERS:  Semaphore           - OSD semaphore to wait on
- *              Timeout             - Max time to wait
+ * PARAMETERS:  Semaphore       - Semaphore to wait on
+ *              Timeout         - Max time to wait
  *
  * RETURN:      Status
  *
@@ -90,7 +90,8 @@ acpi_ex_system_wait_semaphore (
 
 		status = acpi_os_wait_semaphore (semaphore, 1, timeout);
 
-		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "*** Thread awake after blocking, %s\n",
+		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+			"*** Thread awake after blocking, %s\n",
 			acpi_format_exception (status)));
 
 		/* Reacquire the interpreter */
@@ -111,8 +112,8 @@ acpi_ex_system_wait_semaphore (
  *
  * FUNCTION:    acpi_ex_system_do_stall
  *
- * PARAMETERS:  how_long            - The amount of time to stall,
- *                                    in microseconds
+ * PARAMETERS:  how_long        - The amount of time to stall,
+ *                                in microseconds
  *
  * RETURN:      Status
  *
@@ -141,7 +142,8 @@ acpi_ex_system_do_stall (
 		 * (ACPI specifies 100 usec as max, but this gives some slack in
 		 * order to support existing BIOSs)
 		 */
-		ACPI_REPORT_ERROR (("Stall: Time parameter is too large (%d)\n", how_long));
+		ACPI_REPORT_ERROR (("Stall: Time parameter is too large (%d)\n",
+			how_long));
 		status = AE_AML_OPERAND_VALUE;
 	}
 	else {
@@ -156,8 +158,8 @@ acpi_ex_system_do_stall (
  *
  * FUNCTION:    acpi_ex_system_do_suspend
  *
- * PARAMETERS:  how_long            - The amount of time to suspend,
- *                                    in milliseconds
+ * PARAMETERS:  how_long        - The amount of time to suspend,
+ *                                in milliseconds
  *
  * RETURN:      None
  *
@@ -192,8 +194,8 @@ acpi_ex_system_do_suspend (
  *
  * FUNCTION:    acpi_ex_system_acquire_mutex
  *
- * PARAMETERS:  *time_desc          - The 'time to delay' object descriptor
- *              *obj_desc           - The object descriptor for this op
+ * PARAMETERS:  time_desc       - The 'time to delay' object descriptor
+ *              obj_desc        - The object descriptor for this op
  *
  * RETURN:      Status
  *
@@ -218,16 +220,15 @@ acpi_ex_system_acquire_mutex (
 		return_ACPI_STATUS (AE_BAD_PARAMETER);
 	}
 
-	/*
-	 * Support for the _GL_ Mutex object -- go get the global lock
-	 */
+	/* Support for the _GL_ Mutex object -- go get the global lock */
+
 	if (obj_desc->mutex.semaphore == acpi_gbl_global_lock_semaphore) {
 		status = acpi_ev_acquire_global_lock ((u16) time_desc->integer.value);
 		return_ACPI_STATUS (status);
 	}
 
 	status = acpi_ex_system_wait_semaphore (obj_desc->mutex.semaphore,
-			  (u16) time_desc->integer.value);
+			 (u16) time_desc->integer.value);
 	return_ACPI_STATUS (status);
 }
 
@@ -236,7 +237,7 @@ acpi_ex_system_acquire_mutex (
  *
  * FUNCTION:    acpi_ex_system_release_mutex
  *
- * PARAMETERS:  *obj_desc           - The object descriptor for this op
+ * PARAMETERS:  obj_desc        - The object descriptor for this op
  *
  * RETURN:      Status
  *
@@ -261,9 +262,8 @@ acpi_ex_system_release_mutex (
 		return_ACPI_STATUS (AE_BAD_PARAMETER);
 	}
 
-	/*
-	 * Support for the _GL_ Mutex object -- release the global lock
-	 */
+	/* Support for the _GL_ Mutex object -- release the global lock */
+
 	if (obj_desc->mutex.semaphore == acpi_gbl_global_lock_semaphore) {
 		status = acpi_ev_release_global_lock ();
 		return_ACPI_STATUS (status);
@@ -278,9 +278,9 @@ acpi_ex_system_release_mutex (
  *
  * FUNCTION:    acpi_ex_system_signal_event
  *
- * PARAMETERS:  *obj_desc           - The object descriptor for this op
+ * PARAMETERS:  obj_desc        - The object descriptor for this op
  *
- * RETURN:      AE_OK
+ * RETURN:      Status
  *
  * DESCRIPTION: Provides an access point to perform synchronization operations
  *              within the AML.
@@ -309,8 +309,8 @@ acpi_ex_system_signal_event (
  *
  * FUNCTION:    acpi_ex_system_wait_event
  *
- * PARAMETERS:  *time_desc          - The 'time to delay' object descriptor
- *              *obj_desc           - The object descriptor for this op
+ * PARAMETERS:  time_desc       - The 'time to delay' object descriptor
+ *              obj_desc        - The object descriptor for this op
  *
  * RETURN:      Status
  *
@@ -333,7 +333,7 @@ acpi_ex_system_wait_event (
 
 	if (obj_desc) {
 		status = acpi_ex_system_wait_semaphore (obj_desc->event.semaphore,
-				  (u16) time_desc->integer.value);
+				 (u16) time_desc->integer.value);
 	}
 
 	return_ACPI_STATUS (status);
@@ -344,7 +344,7 @@ acpi_ex_system_wait_event (
  *
  * FUNCTION:    acpi_ex_system_reset_event
  *
- * PARAMETERS:  *obj_desc           - The object descriptor for this op
+ * PARAMETERS:  obj_desc        - The object descriptor for this op
  *
  * RETURN:      Status
  *
diff --git a/drivers/acpi/executer/exutils.c b/drivers/acpi/executer/exutils.c
--- a/drivers/acpi/executer/exutils.c
+++ b/drivers/acpi/executer/exutils.c
@@ -67,22 +67,31 @@
 #define _COMPONENT          ACPI_EXECUTER
 	 ACPI_MODULE_NAME    ("exutils")
 
+/* Local prototypes */
 
-#ifndef ACPI_NO_METHOD_EXECUTION
+static u32
+acpi_ex_digits_needed (
+	acpi_integer                    value,
+	u32                             base);
 
+
+#ifndef ACPI_NO_METHOD_EXECUTION
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ex_enter_interpreter
  *
  * PARAMETERS:  None
  *
+ * RETURN:      Status
+ *
  * DESCRIPTION: Enter the interpreter execution region.  Failure to enter
  *              the interpreter region is a fatal system error
  *
  ******************************************************************************/
 
 acpi_status
-acpi_ex_enter_interpreter (void)
+acpi_ex_enter_interpreter (
+	void)
 {
 	acpi_status                     status;
 
@@ -104,6 +113,8 @@ acpi_ex_enter_interpreter (void)
  *
  * PARAMETERS:  None
  *
+ * RETURN:      None
+ *
  * DESCRIPTION: Exit the interpreter execution region
  *
  * Cases where the interpreter is unlocked:
@@ -119,7 +130,8 @@ acpi_ex_enter_interpreter (void)
  ******************************************************************************/
 
 void
-acpi_ex_exit_interpreter (void)
+acpi_ex_exit_interpreter (
+	void)
 {
 	acpi_status                     status;
 
@@ -212,7 +224,8 @@ acpi_ex_acquire_global_lock (
 			locked = TRUE;
 		}
 		else {
-			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not acquire Global Lock, %s\n",
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+				"Could not acquire Global Lock, %s\n",
 				acpi_format_exception (status)));
 		}
 	}
@@ -228,7 +241,7 @@ acpi_ex_acquire_global_lock (
  * PARAMETERS:  locked_by_me    - Return value from corresponding call to
  *                                acquire_global_lock.
  *
- * RETURN:      Status
+ * RETURN:      None
  *
  * DESCRIPTION: Release the global lock if it is locked.
  *
@@ -269,11 +282,14 @@ acpi_ex_release_global_lock (
  * PARAMETERS:  Value           - Value to be represented
  *              Base            - Base of representation
  *
- * RETURN:      the number of digits needed to represent Value in Base
+ * RETURN:      The number of digits.
+ *
+ * DESCRIPTION: Calculate the number of digits needed to represent the Value
+ *              in the given Base (Radix)
  *
  ******************************************************************************/
 
-u32
+static u32
 acpi_ex_digits_needed (
 	acpi_integer                    value,
 	u32                             base)
@@ -312,6 +328,8 @@ acpi_ex_digits_needed (
  * PARAMETERS:  numeric_id      - EISA ID to be converted
  *              out_string      - Where to put the converted string (8 bytes)
  *
+ * RETURN:      None
+ *
  * DESCRIPTION: Convert a numeric EISA ID to string representation
  *
  ******************************************************************************/
@@ -349,7 +367,10 @@ acpi_ex_eisa_id_to_string (
  * PARAMETERS:  Value           - Value to be converted
  *              out_string      - Where to put the converted string (8 bytes)
  *
- * RETURN:      Convert a number to string representation
+ * RETURN:      None, string
+ *
+ * DESCRIPTOIN: Convert a number to string representation. Assumes string
+ *              buffer is large enough to hold the string.
  *
  ******************************************************************************/
 
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
new file mode 100644
--- /dev/null
+++ b/drivers/acpi/glue.c
@@ -0,0 +1,360 @@
+/*
+ * Link physical devices with ACPI devices support
+ *
+ * Copyright (c) 2005 David Shaohua Li <shaohua.li@intel.com>
+ * Copyright (c) 2005 Intel Corp.
+ *
+ * This file is released under the GPLv2.
+ */
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/device.h>
+#include <linux/rwsem.h>
+#include <linux/acpi.h>
+
+#define ACPI_GLUE_DEBUG	0
+#if ACPI_GLUE_DEBUG
+#define DBG(x...) printk(PREFIX x)
+#else
+#define DBG(x...)
+#endif
+static LIST_HEAD(bus_type_list);
+static DECLARE_RWSEM(bus_type_sem);
+
+int register_acpi_bus_type(struct acpi_bus_type *type)
+{
+	if (acpi_disabled)
+		return -ENODEV;
+	if (type && type->bus && type->find_device) {
+		down_write(&bus_type_sem);
+		list_add_tail(&type->list, &bus_type_list);
+		up_write(&bus_type_sem);
+		printk(KERN_INFO PREFIX "bus type %s registered\n", type->bus->name);
+		return 0;
+	}
+	return -ENODEV;
+}
+
+EXPORT_SYMBOL(register_acpi_bus_type);
+
+int unregister_acpi_bus_type(struct acpi_bus_type *type)
+{
+	if (acpi_disabled)
+		return 0;
+	if (type) {
+		down_write(&bus_type_sem);
+		list_del_init(&type->list);
+		up_write(&bus_type_sem);
+		printk(KERN_INFO PREFIX "ACPI bus type %s unregistered\n", type->bus->name);
+		return 0;
+	}
+	return -ENODEV;
+}
+
+EXPORT_SYMBOL(unregister_acpi_bus_type);
+
+static struct acpi_bus_type *acpi_get_bus_type(struct bus_type *type)
+{
+	struct acpi_bus_type *tmp, *ret = NULL;
+
+	down_read(&bus_type_sem);
+	list_for_each_entry(tmp, &bus_type_list, list) {
+		if (tmp->bus == type) {
+			ret = tmp;
+			break;
+		}
+	}
+	up_read(&bus_type_sem);
+	return ret;
+}
+
+static int acpi_find_bridge_device(struct device *dev, acpi_handle * handle)
+{
+	struct acpi_bus_type *tmp;
+	int ret = -ENODEV;
+
+	down_read(&bus_type_sem);
+	list_for_each_entry(tmp, &bus_type_list, list) {
+		if (tmp->find_bridge && !tmp->find_bridge(dev, handle)) {
+			ret = 0;
+			break;
+		}
+	}
+	up_read(&bus_type_sem);
+	return ret;
+}
+
+/* Get PCI root bridge's handle from its segment and bus number */
+struct acpi_find_pci_root {
+	unsigned int seg;
+	unsigned int bus;
+	acpi_handle handle;
+};
+
+static acpi_status
+do_root_bridge_busnr_callback(struct acpi_resource *resource, void *data)
+{
+	int *busnr = (int *)data;
+	struct acpi_resource_address64 address;
+
+	if (resource->id != ACPI_RSTYPE_ADDRESS16 &&
+	    resource->id != ACPI_RSTYPE_ADDRESS32 &&
+	    resource->id != ACPI_RSTYPE_ADDRESS64)
+		return AE_OK;
+
+	acpi_resource_to_address64(resource, &address);
+	if ((address.address_length > 0) &&
+	    (address.resource_type == ACPI_BUS_NUMBER_RANGE))
+		*busnr = address.min_address_range;
+
+	return AE_OK;
+}
+
+static int get_root_bridge_busnr(acpi_handle handle)
+{
+	acpi_status status;
+	int bus, bbn;
+	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+
+	acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
+
+	status = acpi_evaluate_integer(handle, METHOD_NAME__BBN, NULL,
+				       (unsigned long *)&bbn);
+	if (status == AE_NOT_FOUND) {
+		/* Assume bus = 0 */
+		printk(KERN_INFO PREFIX
+		       "Assume root bridge [%s] bus is 0\n",
+		       (char *)buffer.pointer);
+		status = AE_OK;
+		bbn = 0;
+	}
+	if (ACPI_FAILURE(status)) {
+		bbn = -ENODEV;
+		goto exit;
+	}
+	if (bbn > 0)
+		goto exit;
+
+	/* _BBN in some systems return 0 for all root bridges */
+	bus = -1;
+	status = acpi_walk_resources(handle, METHOD_NAME__CRS,
+				     do_root_bridge_busnr_callback, &bus);
+	/* If _CRS failed, we just use _BBN */
+	if (ACPI_FAILURE(status) || (bus == -1))
+		goto exit;
+	/* We select _CRS */
+	if (bbn != bus) {
+		printk(KERN_INFO PREFIX
+		       "_BBN and _CRS returns different value for %s. Select _CRS\n",
+		       (char *)buffer.pointer);
+		bbn = bus;
+	}
+      exit:
+	acpi_os_free(buffer.pointer);
+	return bbn;
+}
+
+static acpi_status
+find_pci_rootbridge(acpi_handle handle, u32 lvl, void *context, void **rv)
+{
+	struct acpi_find_pci_root *find = (struct acpi_find_pci_root *)context;
+	unsigned long seg, bus;
+	acpi_status status;
+	int tmp;
+	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+
+	acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
+
+	status = acpi_evaluate_integer(handle, METHOD_NAME__SEG, NULL, &seg);
+	if (status == AE_NOT_FOUND) {
+		/* Assume seg = 0 */
+		printk(KERN_INFO PREFIX
+		       "Assume root bridge [%s] segment is 0\n",
+		       (char *)buffer.pointer);
+		status = AE_OK;
+		seg = 0;
+	}
+	if (ACPI_FAILURE(status)) {
+		status = AE_CTRL_DEPTH;
+		goto exit;
+	}
+
+	tmp = get_root_bridge_busnr(handle);
+	if (tmp < 0) {
+		printk(KERN_ERR PREFIX
+		       "Find root bridge failed for %s\n",
+		       (char *)buffer.pointer);
+		status = AE_CTRL_DEPTH;
+		goto exit;
+	}
+	bus = tmp;
+
+	if (seg == find->seg && bus == find->bus)
+		find->handle = handle;
+	status = AE_OK;
+      exit:
+	acpi_os_free(buffer.pointer);
+	return status;
+}
+
+acpi_handle acpi_get_pci_rootbridge_handle(unsigned int seg, unsigned int bus)
+{
+	struct acpi_find_pci_root find = { seg, bus, NULL };
+
+	acpi_get_devices(PCI_ROOT_HID_STRING, find_pci_rootbridge, &find, NULL);
+	return find.handle;
+}
+
+/* Get device's handler per its address under its parent */
+struct acpi_find_child {
+	acpi_handle handle;
+	acpi_integer address;
+};
+
+static acpi_status
+do_acpi_find_child(acpi_handle handle, u32 lvl, void *context, void **rv)
+{
+	acpi_status status;
+	struct acpi_device_info *info;
+	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+	struct acpi_find_child *find = (struct acpi_find_child *)context;
+
+	status = acpi_get_object_info(handle, &buffer);
+	if (ACPI_SUCCESS(status)) {
+		info = buffer.pointer;
+		if (info->address == find->address)
+			find->handle = handle;
+		acpi_os_free(buffer.pointer);
+	}
+	return AE_OK;
+}
+
+acpi_handle acpi_get_child(acpi_handle parent, acpi_integer address)
+{
+	struct acpi_find_child find = { NULL, address };
+
+	if (!parent)
+		return NULL;
+	acpi_walk_namespace(ACPI_TYPE_DEVICE, parent,
+			    1, do_acpi_find_child, &find, NULL);
+	return find.handle;
+}
+
+EXPORT_SYMBOL(acpi_get_child);
+
+/* Link ACPI devices with physical devices */
+static void acpi_glue_data_handler(acpi_handle handle,
+				   u32 function, void *context)
+{
+	/* we provide an empty handler */
+}
+
+/* Note: a success call will increase reference count by one */
+struct device *acpi_get_physical_device(acpi_handle handle)
+{
+	acpi_status status;
+	struct device *dev;
+
+	status = acpi_get_data(handle, acpi_glue_data_handler, (void **)&dev);
+	if (ACPI_SUCCESS(status))
+		return get_device(dev);
+	return NULL;
+}
+
+EXPORT_SYMBOL(acpi_get_physical_device);
+
+static int acpi_bind_one(struct device *dev, acpi_handle handle)
+{
+	acpi_status status;
+
+	if (dev->firmware_data) {
+		printk(KERN_WARNING PREFIX
+		       "Drivers changed 'firmware_data' for %s\n", dev->bus_id);
+		return -EINVAL;
+	}
+	get_device(dev);
+	status = acpi_attach_data(handle, acpi_glue_data_handler, dev);
+	if (ACPI_FAILURE(status)) {
+		put_device(dev);
+		return -EINVAL;
+	}
+	dev->firmware_data = handle;
+
+	return 0;
+}
+
+static int acpi_unbind_one(struct device *dev)
+{
+	if (!dev->firmware_data)
+		return 0;
+	if (dev == acpi_get_physical_device(dev->firmware_data)) {
+		/* acpi_get_physical_device increase refcnt by one */
+		put_device(dev);
+		acpi_detach_data(dev->firmware_data, acpi_glue_data_handler);
+		dev->firmware_data = NULL;
+		/* acpi_bind_one increase refcnt by one */
+		put_device(dev);
+	} else {
+		printk(KERN_ERR PREFIX
+		       "Oops, 'firmware_data' corrupt for %s\n", dev->bus_id);
+	}
+	return 0;
+}
+
+static int acpi_platform_notify(struct device *dev)
+{
+	struct acpi_bus_type *type;
+	acpi_handle handle;
+	int ret = -EINVAL;
+
+	if (!dev->bus || !dev->parent) {
+		/* bridge devices genernally haven't bus or parent */
+		ret = acpi_find_bridge_device(dev, &handle);
+		goto end;
+	}
+	type = acpi_get_bus_type(dev->bus);
+	if (!type) {
+		DBG("No ACPI bus support for %s\n", dev->bus_id);
+		ret = -EINVAL;
+		goto end;
+	}
+	if ((ret = type->find_device(dev, &handle)) != 0)
+		DBG("Can't get handler for %s\n", dev->bus_id);
+      end:
+	if (!ret)
+		acpi_bind_one(dev, handle);
+
+#if ACPI_GLUE_DEBUG
+	if (!ret) {
+		struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+
+		acpi_get_name(dev->firmware_data, ACPI_FULL_PATHNAME, &buffer);
+		DBG("Device %s -> %s\n", dev->bus_id, (char *)buffer.pointer);
+		acpi_os_free(buffer.pointer);
+	} else
+		DBG("Device %s -> No ACPI support\n", dev->bus_id);
+#endif
+
+	return ret;
+}
+
+static int acpi_platform_notify_remove(struct device *dev)
+{
+	acpi_unbind_one(dev);
+	return 0;
+}
+
+static int __init init_acpi_device_notify(void)
+{
+	if (acpi_disabled)
+		return 0;
+	if (platform_notify || platform_notify_remove) {
+		printk(KERN_ERR PREFIX "Can't use platform_notify\n");
+		return 0;
+	}
+	platform_notify = acpi_platform_notify;
+	platform_notify_remove = acpi_platform_notify_remove;
+	return 0;
+}
+
+arch_initcall(init_acpi_device_notify);
diff --git a/drivers/acpi/hardware/hwacpi.c b/drivers/acpi/hardware/hwacpi.c
--- a/drivers/acpi/hardware/hwacpi.c
+++ b/drivers/acpi/hardware/hwacpi.c
@@ -58,7 +58,8 @@
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Initialize and validate various ACPI registers
+ * DESCRIPTION: Initialize and validate the various ACPI registers defined in
+ *              the FADT.
  *
  ******************************************************************************/
 
@@ -75,7 +76,7 @@ acpi_hw_initialize (
 	/* We must have the ACPI tables by the time we get here */
 
 	if (!acpi_gbl_FADT) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "A FADT is not loaded\n"));
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No FADT is present\n"));
 
 		return_ACPI_STATUS (AE_NO_ACPI_TABLES);
 	}
@@ -131,7 +132,8 @@ acpi_hw_set_mode (
 	 * transitions are not supported.
 	 */
 	if (!acpi_gbl_FADT->acpi_enable && !acpi_gbl_FADT->acpi_disable) {
-		ACPI_REPORT_ERROR (("No ACPI mode transition supported in this system (enable/disable both zero)\n"));
+		ACPI_REPORT_ERROR ((
+			"No ACPI mode transition supported in this system (enable/disable both zero)\n"));
 		return_ACPI_STATUS (AE_OK);
 	}
 
@@ -162,7 +164,8 @@ acpi_hw_set_mode (
 	}
 
 	if (ACPI_FAILURE (status)) {
-		ACPI_REPORT_ERROR (("Could not write mode change, %s\n", acpi_format_exception (status)));
+		ACPI_REPORT_ERROR (("Could not write mode change, %s\n",
+			acpi_format_exception (status)));
 		return_ACPI_STATUS (status);
 	}
 
@@ -173,7 +176,8 @@ acpi_hw_set_mode (
 	retry = 3000;
 	while (retry) {
 		if (acpi_hw_get_mode() == mode) {
-			ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Mode %X successfully enabled\n", mode));
+			ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Mode %X successfully enabled\n",
+				mode));
 			return_ACPI_STATUS (AE_OK);
 		}
 		acpi_os_stall(1000);
@@ -185,7 +189,7 @@ acpi_hw_set_mode (
 }
 
 
-/******************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    acpi_hw_get_mode
  *
@@ -199,7 +203,8 @@ acpi_hw_set_mode (
  ******************************************************************************/
 
 u32
-acpi_hw_get_mode (void)
+acpi_hw_get_mode (
+	void)
 {
 	acpi_status                     status;
 	u32                             value;
diff --git a/drivers/acpi/hardware/hwgpe.c b/drivers/acpi/hardware/hwgpe.c
--- a/drivers/acpi/hardware/hwgpe.c
+++ b/drivers/acpi/hardware/hwgpe.c
@@ -48,6 +48,13 @@
 #define _COMPONENT          ACPI_HARDWARE
 	 ACPI_MODULE_NAME    ("hwgpe")
 
+/* Local prototypes */
+
+static acpi_status
+acpi_hw_enable_wakeup_gpe_block (
+	struct acpi_gpe_xrupt_info      *gpe_xrupt_info,
+	struct acpi_gpe_block_info      *gpe_block);
+
 
 /******************************************************************************
  *
@@ -135,6 +142,7 @@ acpi_hw_clear_gpe (
  * DESCRIPTION: Return the status of a single GPE.
  *
  ******************************************************************************/
+
 #ifdef ACPI_FUTURE_USAGE
 acpi_status
 acpi_hw_get_gpe_status (
@@ -206,7 +214,7 @@ unlock_and_exit:
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Disable all GPEs within a GPE block
+ * DESCRIPTION: Disable all GPEs within a single GPE block
  *
  ******************************************************************************/
 
@@ -244,7 +252,7 @@ acpi_hw_disable_gpe_block (
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Clear status bits for all GPEs within a GPE block
+ * DESCRIPTION: Clear status bits for all GPEs within a single GPE block
  *
  ******************************************************************************/
 
@@ -282,8 +290,8 @@ acpi_hw_clear_gpe_block (
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Enable all "runtime" GPEs within a GPE block. (Includes
- *              combination wake/run GPEs.)
+ * DESCRIPTION: Enable all "runtime" GPEs within a single GPE block. Includes
+ *              combination wake/run GPEs.
  *
  ******************************************************************************/
 
@@ -327,12 +335,12 @@ acpi_hw_enable_runtime_gpe_block (
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Enable all "wake" GPEs within a GPE block.  (Includes
- *              combination wake/run GPEs.)
+ * DESCRIPTION: Enable all "wake" GPEs within a single GPE block. Includes
+ *              combination wake/run GPEs.
  *
  ******************************************************************************/
 
-acpi_status
+static acpi_status
 acpi_hw_enable_wakeup_gpe_block (
 	struct acpi_gpe_xrupt_info      *gpe_xrupt_info,
 	struct acpi_gpe_block_info      *gpe_block)
@@ -350,7 +358,8 @@ acpi_hw_enable_wakeup_gpe_block (
 
 		/* Enable all "wake" GPEs in this register */
 
-		status = acpi_hw_low_level_write (8, gpe_block->register_info[i].enable_for_wake,
+		status = acpi_hw_low_level_write (8,
+				 gpe_block->register_info[i].enable_for_wake,
 				 &gpe_block->register_info[i].enable_address);
 		if (ACPI_FAILURE (status)) {
 			return (status);
@@ -369,7 +378,7 @@ acpi_hw_enable_wakeup_gpe_block (
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Disable and clear all GPEs
+ * DESCRIPTION: Disable and clear all GPEs in all GPE blocks
  *
  ******************************************************************************/
 
@@ -397,7 +406,7 @@ acpi_hw_disable_all_gpes (
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Enable all GPEs of the given type
+ * DESCRIPTION: Enable all "runtime" GPEs, in all GPE blocks
  *
  ******************************************************************************/
 
@@ -424,7 +433,7 @@ acpi_hw_enable_all_runtime_gpes (
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Enable all GPEs of the given type
+ * DESCRIPTION: Enable all "wakeup" GPEs, in all GPE blocks
  *
  ******************************************************************************/
 
diff --git a/drivers/acpi/hardware/hwregs.c b/drivers/acpi/hardware/hwregs.c
--- a/drivers/acpi/hardware/hwregs.c
+++ b/drivers/acpi/hardware/hwregs.c
@@ -87,8 +87,9 @@ acpi_hw_clear_acpi_status (
 		}
 	}
 
-	status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1_STATUS,
-			  ACPI_BITMASK_ALL_FIXED_STATUS);
+	status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK,
+			 ACPI_REGISTER_PM1_STATUS,
+			 ACPI_BITMASK_ALL_FIXED_STATUS);
 	if (ACPI_FAILURE (status)) {
 		goto unlock_and_exit;
 	}
@@ -138,28 +139,30 @@ acpi_get_sleep_type_data (
 {
 	acpi_status                     status = AE_OK;
 	struct acpi_parameter_info      info;
+	char                            *sleep_state_name;
 
 
 	ACPI_FUNCTION_TRACE ("acpi_get_sleep_type_data");
 
 
-	/*
-	 * Validate parameters
-	 */
+	/* Validate parameters */
+
 	if ((sleep_state > ACPI_S_STATES_MAX) ||
 		!sleep_type_a || !sleep_type_b) {
 		return_ACPI_STATUS (AE_BAD_PARAMETER);
 	}
 
-	/*
-	 * Evaluate the namespace object containing the values for this state
-	 */
+	/* Evaluate the namespace object containing the values for this state */
+
 	info.parameters = NULL;
-	status = acpi_ns_evaluate_by_name ((char *) acpi_gbl_sleep_state_names[sleep_state],
-			  &info);
+	info.return_object = NULL;
+	sleep_state_name = (char *) acpi_gbl_sleep_state_names[sleep_state];
+
+	status = acpi_ns_evaluate_by_name (sleep_state_name, &info);
 	if (ACPI_FAILURE (status)) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%s while evaluating sleep_state [%s]\n",
-			acpi_format_exception (status), acpi_gbl_sleep_state_names[sleep_state]));
+		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+			"%s while evaluating sleep_state [%s]\n",
+			acpi_format_exception (status), sleep_state_name));
 
 		return_ACPI_STATUS (status);
 	}
@@ -167,45 +170,57 @@ acpi_get_sleep_type_data (
 	/* Must have a return object */
 
 	if (!info.return_object) {
-		ACPI_REPORT_ERROR (("Missing Sleep State object\n"));
+		ACPI_REPORT_ERROR (("No Sleep State object returned from [%s]\n",
+			sleep_state_name));
 		status = AE_NOT_EXIST;
 	}
 
 	/* It must be of type Package */
 
 	else if (ACPI_GET_OBJECT_TYPE (info.return_object) != ACPI_TYPE_PACKAGE) {
-		ACPI_REPORT_ERROR (("Sleep State object not a Package\n"));
+		ACPI_REPORT_ERROR (("Sleep State return object is not a Package\n"));
 		status = AE_AML_OPERAND_TYPE;
 	}
 
-	/* The package must have at least two elements */
-
+	/*
+	 * The package must have at least two elements.  NOTE (March 2005): This
+	 * goes against the current ACPI spec which defines this object as a
+	 * package with one encoded DWORD element.  However, existing practice
+	 * by BIOS vendors seems to be to have 2 or more elements, at least
+	 * one per sleep type (A/B).
+	 */
 	else if (info.return_object->package.count < 2) {
-		ACPI_REPORT_ERROR (("Sleep State package does not have at least two elements\n"));
+		ACPI_REPORT_ERROR ((
+			"Sleep State return package does not have at least two elements\n"));
 		status = AE_AML_NO_OPERAND;
 	}
 
 	/* The first two elements must both be of type Integer */
 
-	else if ((ACPI_GET_OBJECT_TYPE (info.return_object->package.elements[0]) != ACPI_TYPE_INTEGER) ||
-			 (ACPI_GET_OBJECT_TYPE (info.return_object->package.elements[1]) != ACPI_TYPE_INTEGER)) {
-		ACPI_REPORT_ERROR (("Sleep State package elements are not both Integers (%s, %s)\n",
+	else if ((ACPI_GET_OBJECT_TYPE (info.return_object->package.elements[0])
+			 != ACPI_TYPE_INTEGER) ||
+			 (ACPI_GET_OBJECT_TYPE (info.return_object->package.elements[1])
+				!= ACPI_TYPE_INTEGER)) {
+		ACPI_REPORT_ERROR ((
+			"Sleep State return package elements are not both Integers (%s, %s)\n",
 			acpi_ut_get_object_type_name (info.return_object->package.elements[0]),
 			acpi_ut_get_object_type_name (info.return_object->package.elements[1])));
 		status = AE_AML_OPERAND_TYPE;
 	}
 	else {
-		/*
-		 * Valid _Sx_ package size, type, and value
-		 */
-		*sleep_type_a = (u8) (info.return_object->package.elements[0])->integer.value;
-		*sleep_type_b = (u8) (info.return_object->package.elements[1])->integer.value;
+		/* Valid _Sx_ package size, type, and value */
+
+		*sleep_type_a = (u8)
+			(info.return_object->package.elements[0])->integer.value;
+		*sleep_type_b = (u8)
+			(info.return_object->package.elements[1])->integer.value;
 	}
 
 	if (ACPI_FAILURE (status)) {
 		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
-			"While evaluating sleep_state [%s], bad Sleep object %p type %s\n",
-			acpi_gbl_sleep_state_names[sleep_state], info.return_object,
+			"%s While evaluating sleep_state [%s], bad Sleep object %p type %s\n",
+			acpi_format_exception (status),
+			sleep_state_name, info.return_object,
 			acpi_ut_get_object_type_name (info.return_object)));
 	}
 
@@ -221,9 +236,9 @@ EXPORT_SYMBOL(acpi_get_sleep_type_data);
  *
  * PARAMETERS:  register_id         - Index of ACPI Register to access
  *
- * RETURN:      The bit mask to be used when accessing the register
+ * RETURN:      The bitmask to be used when accessing the register
  *
- * DESCRIPTION: Map register_id into a register bit mask.
+ * DESCRIPTION: Map register_id into a register bitmask.
  *
  ******************************************************************************/
 
@@ -359,7 +374,7 @@ acpi_set_register (
 	/* Always do a register read first so we can insert the new bits  */
 
 	status = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK,
-			  bit_reg_info->parent_register, &register_value);
+			 bit_reg_info->parent_register, &register_value);
 	if (ACPI_FAILURE (status)) {
 		goto unlock_and_exit;
 	}
@@ -396,7 +411,7 @@ acpi_set_register (
 				bit_reg_info->access_bit_mask, value);
 
 		status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK,
-				  ACPI_REGISTER_PM1_ENABLE, (u16) register_value);
+				 ACPI_REGISTER_PM1_ENABLE, (u16) register_value);
 		break;
 
 
@@ -413,7 +428,7 @@ acpi_set_register (
 				bit_reg_info->access_bit_mask, value);
 
 		status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK,
-				  ACPI_REGISTER_PM1_CONTROL, (u16) register_value);
+				 ACPI_REGISTER_PM1_CONTROL, (u16) register_value);
 		break;
 
 
@@ -427,17 +442,19 @@ acpi_set_register (
 
 		ACPI_DEBUG_PRINT ((ACPI_DB_IO, "PM2 control: Read %X from %8.8X%8.8X\n",
 			register_value,
-			ACPI_FORMAT_UINT64 (acpi_gbl_FADT->xpm2_cnt_blk.address)));
+			ACPI_FORMAT_UINT64 (
+				acpi_gbl_FADT->xpm2_cnt_blk.address)));
 
 		ACPI_REGISTER_INSERT_VALUE (register_value, bit_reg_info->bit_position,
 				bit_reg_info->access_bit_mask, value);
 
 		ACPI_DEBUG_PRINT ((ACPI_DB_IO, "About to write %4.4X to %8.8X%8.8X\n",
 			register_value,
-			ACPI_FORMAT_UINT64 (acpi_gbl_FADT->xpm2_cnt_blk.address)));
+			ACPI_FORMAT_UINT64 (
+				acpi_gbl_FADT->xpm2_cnt_blk.address)));
 
 		status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK,
-				   ACPI_REGISTER_PM2_CONTROL, (u8) (register_value));
+				 ACPI_REGISTER_PM2_CONTROL, (u8) (register_value));
 		break;
 
 
@@ -454,7 +471,9 @@ unlock_and_exit:
 
 	/* Normalize the value that was read */
 
-	ACPI_DEBUG_EXEC (register_value = ((register_value & bit_reg_info->access_bit_mask) >> bit_reg_info->bit_position));
+	ACPI_DEBUG_EXEC (register_value =
+		((register_value & bit_reg_info->access_bit_mask) >>
+			bit_reg_info->bit_position));
 
 	ACPI_DEBUG_PRINT ((ACPI_DB_IO, "Set bits: %8.8X actual %8.8X register %X\n",
 			value, register_value, bit_reg_info->parent_register));
@@ -469,7 +488,7 @@ EXPORT_SYMBOL(acpi_set_register);
  *
  * PARAMETERS:  use_lock            - Mutex hw access
  *              register_id         - register_iD + Offset
- *              return_value        - Value that was read from the register
+ *              return_value        - Where the register value is returned
  *
  * RETURN:      Status and the value read.
  *
@@ -557,7 +576,8 @@ acpi_hw_register_read (
 		break;
 
 	default:
-		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown Register ID: %X\n", register_id));
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown Register ID: %X\n",
+			register_id));
 		status = AE_BAD_PARAMETER;
 		break;
 	}
@@ -763,10 +783,11 @@ acpi_hw_low_level_read (
 		return (AE_BAD_PARAMETER);
 	}
 
-	ACPI_DEBUG_PRINT ((ACPI_DB_IO, "Read:  %8.8X width %2d from %8.8X%8.8X (%s)\n",
-			*value, width,
-			ACPI_FORMAT_UINT64 (address),
-			acpi_ut_get_region_name (reg->address_space_id)));
+	ACPI_DEBUG_PRINT ((ACPI_DB_IO,
+		"Read:  %8.8X width %2d from %8.8X%8.8X (%s)\n",
+		*value, width,
+		ACPI_FORMAT_UINT64 (address),
+		acpi_ut_get_region_name (reg->address_space_id)));
 
 	return (status);
 }
@@ -841,10 +862,11 @@ acpi_hw_low_level_write (
 		return (AE_BAD_PARAMETER);
 	}
 
-	ACPI_DEBUG_PRINT ((ACPI_DB_IO, "Wrote: %8.8X width %2d   to %8.8X%8.8X (%s)\n",
-			value, width,
-			ACPI_FORMAT_UINT64 (address),
-			acpi_ut_get_region_name (reg->address_space_id)));
+	ACPI_DEBUG_PRINT ((ACPI_DB_IO,
+		"Wrote: %8.8X width %2d   to %8.8X%8.8X (%s)\n",
+		value, width,
+		ACPI_FORMAT_UINT64 (address),
+		acpi_ut_get_region_name (reg->address_space_id)));
 
 	return (status);
 }
diff --git a/drivers/acpi/hardware/hwsleep.c b/drivers/acpi/hardware/hwsleep.c
--- a/drivers/acpi/hardware/hwsleep.c
+++ b/drivers/acpi/hardware/hwsleep.c
@@ -43,27 +43,13 @@
  */
 
 #include <linux/module.h>
-
 #include <acpi/acpi.h>
 
 #define _COMPONENT          ACPI_HARDWARE
 	 ACPI_MODULE_NAME    ("hwsleep")
 
 
-#define METHOD_NAME__BFS        "\\_BFS"
-#define METHOD_NAME__GTS        "\\_GTS"
-#define METHOD_NAME__PTS        "\\_PTS"
-#define METHOD_NAME__SST        "\\_SI._SST"
-#define METHOD_NAME__WAK        "\\_WAK"
-
-#define ACPI_SST_INDICATOR_OFF  0
-#define ACPI_SST_WORKING        1
-#define ACPI_SST_WAKING         2
-#define ACPI_SST_SLEEPING       3
-#define ACPI_SST_SLEEP_CONTEXT  4
-
-
-/******************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    acpi_set_firmware_waking_vector
  *
@@ -72,7 +58,7 @@
  *
  * RETURN:      Status
  *
- * DESCRIPTION: access function for d_firmware_waking_vector field in FACS
+ * DESCRIPTION: Access function for the firmware_waking_vector field in FACS
  *
  ******************************************************************************/
 
@@ -99,19 +85,20 @@ acpi_set_firmware_waking_vector (
 }
 
 
-/******************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    acpi_get_firmware_waking_vector
  *
- * PARAMETERS:  *physical_address   - Output buffer where contents of
+ * PARAMETERS:  *physical_address   - Where the contents of
  *                                    the firmware_waking_vector field of
- *                                    the FACS will be stored.
+ *                                    the FACS will be returned.
  *
- * RETURN:      Status
+ * RETURN:      Status, vector
  *
- * DESCRIPTION: Access function for firmware_waking_vector field in FACS
+ * DESCRIPTION: Access function for the firmware_waking_vector field in FACS
  *
  ******************************************************************************/
+
 #ifdef ACPI_FUTURE_USAGE
 acpi_status
 acpi_get_firmware_waking_vector (
@@ -141,7 +128,7 @@ acpi_get_firmware_waking_vector (
 #endif
 
 
-/******************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    acpi_enter_sleep_state_prep
  *
@@ -215,7 +202,7 @@ acpi_enter_sleep_state_prep (
 		break;
 
 	default:
-		arg.integer.value = ACPI_SST_INDICATOR_OFF; /* Default is indicator off */
+		arg.integer.value = ACPI_SST_INDICATOR_OFF; /* Default is off */
 		break;
 	}
 
@@ -223,14 +210,15 @@ acpi_enter_sleep_state_prep (
 
 	status = acpi_evaluate_object (NULL, METHOD_NAME__SST, &arg_list, NULL);
 	if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) {
-		 ACPI_REPORT_ERROR (("Method _SST failed, %s\n", acpi_format_exception (status)));
+		 ACPI_REPORT_ERROR (("Method _SST failed, %s\n",
+			acpi_format_exception (status)));
 	}
 
 	return_ACPI_STATUS (AE_OK);
 }
 
 
-/******************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    acpi_enter_sleep_state
  *
@@ -299,15 +287,18 @@ acpi_enter_sleep_state (
 
 	/* Get current value of PM1A control */
 
-	status = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1_CONTROL, &PM1Acontrol);
+	status = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK,
+			 ACPI_REGISTER_PM1_CONTROL, &PM1Acontrol);
 	if (ACPI_FAILURE (status)) {
 		return_ACPI_STATUS (status);
 	}
-	ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "Entering sleep state [S%d]\n", sleep_state));
+	ACPI_DEBUG_PRINT ((ACPI_DB_INIT,
+		"Entering sleep state [S%d]\n", sleep_state));
 
 	/* Clear SLP_EN and SLP_TYP fields */
 
-	PM1Acontrol &= ~(sleep_type_reg_info->access_bit_mask | sleep_enable_reg_info->access_bit_mask);
+	PM1Acontrol &= ~(sleep_type_reg_info->access_bit_mask |
+			   sleep_enable_reg_info->access_bit_mask);
 	PM1Bcontrol = PM1Acontrol;
 
 	/* Insert SLP_TYP bits */
@@ -322,12 +313,14 @@ acpi_enter_sleep_state (
 
 	/* Write #1: fill in SLP_TYP data */
 
-	status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1A_CONTROL, PM1Acontrol);
+	status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK,
+			 ACPI_REGISTER_PM1A_CONTROL, PM1Acontrol);
 	if (ACPI_FAILURE (status)) {
 		return_ACPI_STATUS (status);
 	}
 
-	status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1B_CONTROL, PM1Bcontrol);
+	status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK,
+			 ACPI_REGISTER_PM1B_CONTROL, PM1Bcontrol);
 	if (ACPI_FAILURE (status)) {
 		return_ACPI_STATUS (status);
 	}
@@ -341,22 +334,25 @@ acpi_enter_sleep_state (
 
 	ACPI_FLUSH_CPU_CACHE ();
 
-	status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1A_CONTROL, PM1Acontrol);
+	status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK,
+			 ACPI_REGISTER_PM1A_CONTROL, PM1Acontrol);
 	if (ACPI_FAILURE (status)) {
 		return_ACPI_STATUS (status);
 	}
 
-	status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1B_CONTROL, PM1Bcontrol);
+	status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK,
+			 ACPI_REGISTER_PM1B_CONTROL, PM1Bcontrol);
 	if (ACPI_FAILURE (status)) {
 		return_ACPI_STATUS (status);
 	}
 
 	if (sleep_state > ACPI_STATE_S3) {
 		/*
-		 * We wanted to sleep > S3, but it didn't happen (by virtue of the fact that
-		 * we are still executing!)
+		 * We wanted to sleep > S3, but it didn't happen (by virtue of the
+		 * fact that we are still executing!)
 		 *
-		 * Wait ten seconds, then try again. This is to get S4/S5 to work on all machines.
+		 * Wait ten seconds, then try again. This is to get S4/S5 to work on
+		 * all machines.
 		 *
 		 * We wait so long to allow chipsets that poll this reg very slowly to
 		 * still read the right value. Ideally, this block would go
@@ -364,7 +360,8 @@ acpi_enter_sleep_state (
 		 */
 		acpi_os_stall (10000000);
 
-		status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1_CONTROL,
+		status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK,
+				 ACPI_REGISTER_PM1_CONTROL,
 				 sleep_enable_reg_info->access_bit_mask);
 		if (ACPI_FAILURE (status)) {
 			return_ACPI_STATUS (status);
@@ -374,7 +371,8 @@ acpi_enter_sleep_state (
 	/* Wait until we enter sleep state */
 
 	do {
-		status = acpi_get_register (ACPI_BITREG_WAKE_STATUS, &in_value, ACPI_MTX_DO_NOT_LOCK);
+		status = acpi_get_register (ACPI_BITREG_WAKE_STATUS, &in_value,
+			ACPI_MTX_DO_NOT_LOCK);
 		if (ACPI_FAILURE (status)) {
 			return_ACPI_STATUS (status);
 		}
@@ -388,7 +386,7 @@ acpi_enter_sleep_state (
 EXPORT_SYMBOL(acpi_enter_sleep_state);
 
 
-/******************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    acpi_enter_sleep_state_s4bios
  *
@@ -439,11 +437,13 @@ acpi_enter_sleep_state_s4bios (
 
 	ACPI_FLUSH_CPU_CACHE ();
 
-	status = acpi_os_write_port (acpi_gbl_FADT->smi_cmd, (u32) acpi_gbl_FADT->S4bios_req, 8);
+	status = acpi_os_write_port (acpi_gbl_FADT->smi_cmd,
+			 (u32) acpi_gbl_FADT->S4bios_req, 8);
 
 	do {
 		acpi_os_stall(1000);
-		status = acpi_get_register (ACPI_BITREG_WAKE_STATUS, &in_value, ACPI_MTX_DO_NOT_LOCK);
+		status = acpi_get_register (ACPI_BITREG_WAKE_STATUS, &in_value,
+			ACPI_MTX_DO_NOT_LOCK);
 		if (ACPI_FAILURE (status)) {
 			return_ACPI_STATUS (status);
 		}
@@ -454,7 +454,7 @@ acpi_enter_sleep_state_s4bios (
 EXPORT_SYMBOL(acpi_enter_sleep_state_s4bios);
 
 
-/******************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    acpi_leave_sleep_state
  *
@@ -534,18 +534,21 @@ acpi_leave_sleep_state (
 	arg.integer.value = ACPI_SST_WAKING;
 	status = acpi_evaluate_object (NULL, METHOD_NAME__SST, &arg_list, NULL);
 	if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) {
-		ACPI_REPORT_ERROR (("Method _SST failed, %s\n", acpi_format_exception (status)));
+		ACPI_REPORT_ERROR (("Method _SST failed, %s\n",
+			acpi_format_exception (status)));
 	}
 
 	arg.integer.value = sleep_state;
 	status = acpi_evaluate_object (NULL, METHOD_NAME__BFS, &arg_list, NULL);
 	if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) {
-		ACPI_REPORT_ERROR (("Method _BFS failed, %s\n", acpi_format_exception (status)));
+		ACPI_REPORT_ERROR (("Method _BFS failed, %s\n",
+			acpi_format_exception (status)));
 	}
 
 	status = acpi_evaluate_object (NULL, METHOD_NAME__WAK, &arg_list, NULL);
 	if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) {
-		ACPI_REPORT_ERROR (("Method _WAK failed, %s\n", acpi_format_exception (status)));
+		ACPI_REPORT_ERROR (("Method _WAK failed, %s\n",
+			acpi_format_exception (status)));
 	}
 	/* TBD: _WAK "sometimes" returns stuff - do we want to look at it? */
 
@@ -567,15 +570,19 @@ acpi_leave_sleep_state (
 
 	/* Enable power button */
 
-	(void) acpi_set_register(acpi_gbl_fixed_event_info[ACPI_EVENT_POWER_BUTTON].enable_register_id,
+	(void) acpi_set_register(
+			acpi_gbl_fixed_event_info[ACPI_EVENT_POWER_BUTTON].enable_register_id,
 			1, ACPI_MTX_DO_NOT_LOCK);
-	(void) acpi_set_register(acpi_gbl_fixed_event_info[ACPI_EVENT_POWER_BUTTON].status_register_id,
+
+	(void) acpi_set_register(
+			acpi_gbl_fixed_event_info[ACPI_EVENT_POWER_BUTTON].status_register_id,
 			1, ACPI_MTX_DO_NOT_LOCK);
 
 	arg.integer.value = ACPI_SST_WORKING;
 	status = acpi_evaluate_object (NULL, METHOD_NAME__SST, &arg_list, NULL);
 	if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) {
-		ACPI_REPORT_ERROR (("Method _SST failed, %s\n", acpi_format_exception (status)));
+		ACPI_REPORT_ERROR (("Method _SST failed, %s\n",
+			acpi_format_exception (status)));
 	}
 
 	return_ACPI_STATUS (status);
diff --git a/drivers/acpi/hardware/hwtimer.c b/drivers/acpi/hardware/hwtimer.c
--- a/drivers/acpi/hardware/hwtimer.c
+++ b/drivers/acpi/hardware/hwtimer.c
@@ -43,7 +43,6 @@
  */
 
 #include <linux/module.h>
-
 #include <acpi/acpi.h>
 
 #define _COMPONENT          ACPI_HARDWARE
@@ -90,7 +89,7 @@ acpi_get_timer_resolution (
  *
  * PARAMETERS:  Ticks               - Where the timer value is returned
  *
- * RETURN:      Status and current ticks
+ * RETURN:      Status and current timer value (ticks)
  *
  * DESCRIPTION: Obtains current value of ACPI PM Timer (in ticks).
  *
@@ -199,5 +198,6 @@ acpi_get_timer_duration (
 	*time_elapsed = (u32) quotient;
 	return_ACPI_STATUS (status);
 }
+
 EXPORT_SYMBOL(acpi_get_timer_duration);
 
diff --git a/drivers/acpi/hotkey.c b/drivers/acpi/hotkey.c
new file mode 100644
--- /dev/null
+++ b/drivers/acpi/hotkey.c
@@ -0,0 +1,1115 @@
+/*
+ *  hotkey.c - ACPI Hotkey Driver ($Revision: 0.2 $)
+ *
+ *  Copyright (C) 2004 Luming Yu <luming.yu@intel.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/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/proc_fs.h>
+#include <linux/sched.h>
+#include <linux/kmod.h>
+#include <linux/seq_file.h>
+#include <acpi/acpi_drivers.h>
+#include <acpi/acpi_bus.h>
+#include <asm/uaccess.h>
+
+#define HOTKEY_ACPI_VERSION "0.1"
+
+#define HOTKEY_PROC "hotkey"
+#define HOTKEY_EV_CONFIG    "event_config"
+#define HOTKEY_PL_CONFIG    "poll_config"
+#define HOTKEY_ACTION   "action"
+#define HOTKEY_INFO "info"
+
+#define ACPI_HOTK_NAME          "Generic Hotkey Driver"
+#define ACPI_HOTK_CLASS         "Hotkey"
+#define ACPI_HOTK_DEVICE_NAME   "Hotkey"
+#define ACPI_HOTK_HID           "Unknown?"
+#define ACPI_HOTKEY_COMPONENT   0x20000000
+
+#define ACPI_HOTKEY_EVENT   0x1
+#define ACPI_HOTKEY_POLLING 0x2
+#define ACPI_UNDEFINED_EVENT    0xf
+
+#define RESULT_STR_LEN	    80
+
+#define ACTION_METHOD	0
+#define POLL_METHOD	1
+
+#define IS_EVENT(e)       	((e) <= 10000 && (e) >0)
+#define IS_POLL(e)      	((e) > 10000)
+#define IS_OTHERS(e)		((e)<=0 || (e)>=20000)
+#define _COMPONENT              ACPI_HOTKEY_COMPONENT
+ACPI_MODULE_NAME("acpi_hotkey")
+
+MODULE_AUTHOR("luming.yu@intel.com");
+MODULE_DESCRIPTION(ACPI_HOTK_NAME);
+MODULE_LICENSE("GPL");
+
+/*  standardized internal hotkey number/event  */
+enum {
+	/* Video Extension event */
+	HK_EVENT_CYCLE_OUTPUT_DEVICE = 0x80,
+	HK_EVENT_OUTPUT_DEVICE_STATUS_CHANGE,
+	HK_EVENT_CYCLE_DISPLAY_OUTPUT,
+	HK_EVENT_NEXT_DISPLAY_OUTPUT,
+	HK_EVENT_PREVIOUS_DISPLAY_OUTPUT,
+	HK_EVENT_CYCLE_BRIGHTNESS,
+	HK_EVENT_INCREASE_BRIGHTNESS,
+	HK_EVENT_DECREASE_BRIGHTNESS,
+	HK_EVENT_ZERO_BRIGHTNESS,
+	HK_EVENT_DISPLAY_DEVICE_OFF,
+
+	/* Snd Card event */
+	HK_EVENT_VOLUME_MUTE,
+	HK_EVENT_VOLUME_INCLREASE,
+	HK_EVENT_VOLUME_DECREASE,
+
+	/* running state control */
+	HK_EVENT_ENTERRING_S3,
+	HK_EVENT_ENTERRING_S4,
+	HK_EVENT_ENTERRING_S5,
+};
+
+/*  procdir we use */
+static struct proc_dir_entry *hotkey_proc_dir;
+static struct proc_dir_entry *hotkey_config;
+static struct proc_dir_entry *hotkey_poll_config;
+static struct proc_dir_entry *hotkey_action;
+static struct proc_dir_entry *hotkey_info;
+
+/* linkage for all type of hotkey */
+struct acpi_hotkey_link {
+	struct list_head entries;
+	int hotkey_type;	/* event or polling based hotkey  */
+	int hotkey_standard_num;	/* standardized hotkey(event) number */
+};
+
+/* event based hotkey */
+struct acpi_event_hotkey {
+	struct acpi_hotkey_link hotkey_link;
+	int flag;
+	acpi_handle bus_handle;	/* bus to install notify handler */
+	int external_hotkey_num;	/* external hotkey/event number */
+	acpi_handle action_handle;	/* acpi handle attached aml action method */
+	char *action_method;	/* action method */
+};
+
+/*
+ * There are two ways to poll status
+ * 1. directy call read_xxx method, without any arguments passed in
+ * 2. call write_xxx method, with arguments passed in, you need
+ * the result is saved in acpi_polling_hotkey.poll_result.
+ * anthoer read command through polling interface.
+ *
+ */
+
+/* polling based hotkey */
+struct acpi_polling_hotkey {
+	struct acpi_hotkey_link hotkey_link;
+	int flag;
+	acpi_handle poll_handle;	/* acpi handle attached polling method */
+	char *poll_method;	/* poll method */
+	acpi_handle action_handle;	/* acpi handle attached action method */
+	char *action_method;	/* action method */
+	union acpi_object *poll_result;	/* polling_result */
+	struct proc_dir_entry *proc;
+};
+
+/* hotkey object union */
+union acpi_hotkey {
+	struct list_head entries;
+	struct acpi_hotkey_link link;
+	struct acpi_event_hotkey event_hotkey;
+	struct acpi_polling_hotkey poll_hotkey;
+};
+
+/* hotkey object list */
+struct acpi_hotkey_list {
+	struct list_head *entries;
+	int count;
+};
+
+static int auto_hotkey_add(struct acpi_device *device);
+static int auto_hotkey_remove(struct acpi_device *device, int type);
+
+static struct acpi_driver hotkey_driver = {
+	.name = ACPI_HOTK_NAME,
+	.class = ACPI_HOTK_CLASS,
+	.ids = ACPI_HOTK_HID,
+	.ops = {
+		.add = auto_hotkey_add,
+		.remove = auto_hotkey_remove,
+		},
+};
+
+static void free_hotkey_device(union acpi_hotkey *key);
+static void free_hotkey_buffer(union acpi_hotkey *key);
+static void free_poll_hotkey_buffer(union acpi_hotkey *key);
+static int hotkey_open_config(struct inode *inode, struct file *file);
+static int hotkey_poll_open_config(struct inode *inode, struct file *file);
+static ssize_t hotkey_write_config(struct file *file,
+				   const char __user * buffer,
+				   size_t count, loff_t * data);
+static int hotkey_info_open_fs(struct inode *inode, struct file *file);
+static int hotkey_action_open_fs(struct inode *inode, struct file *file);
+static ssize_t hotkey_execute_aml_method(struct file *file,
+					 const char __user * buffer,
+					 size_t count, loff_t * data);
+static int hotkey_config_seq_show(struct seq_file *seq, void *offset);
+static int hotkey_poll_config_seq_show(struct seq_file *seq, void *offset);
+static int hotkey_polling_open_fs(struct inode *inode, struct file *file);
+static union acpi_hotkey *get_hotkey_by_event(struct
+			      acpi_hotkey_list
+			      *hotkey_list, int event);
+
+/* event based config */
+static struct file_operations hotkey_config_fops = {
+	.open = hotkey_open_config,
+	.read = seq_read,
+	.write = hotkey_write_config,
+	.llseek = seq_lseek,
+	.release = single_release,
+};
+
+/* polling based config */
+static struct file_operations hotkey_poll_config_fops = {
+	.open = hotkey_poll_open_config,
+	.read = seq_read,
+	.write = hotkey_write_config,
+	.llseek = seq_lseek,
+	.release = single_release,
+};
+
+/* hotkey driver info */
+static struct file_operations hotkey_info_fops = {
+	.open = hotkey_info_open_fs,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = single_release,
+};
+
+/* action */
+static struct file_operations hotkey_action_fops = {
+	.open = hotkey_action_open_fs,
+	.read = seq_read,
+	.write = hotkey_execute_aml_method,
+	.llseek = seq_lseek,
+	.release = single_release,
+};
+
+/* polling results */
+static struct file_operations hotkey_polling_fops = {
+	.open = hotkey_polling_open_fs,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = single_release,
+};
+
+struct acpi_hotkey_list global_hotkey_list;	/* link all ev or pl hotkey  */
+struct list_head hotkey_entries;	/* head of the list of hotkey_list */
+
+static int hotkey_info_seq_show(struct seq_file *seq, void *offset)
+{
+	ACPI_FUNCTION_TRACE("hotkey_info_seq_show");
+
+	seq_printf(seq, "Hotkey generic driver ver: %s\n", HOTKEY_ACPI_VERSION);
+
+	return_VALUE(0);
+}
+
+static int hotkey_info_open_fs(struct inode *inode, struct file *file)
+{
+	return single_open(file, hotkey_info_seq_show, PDE(inode)->data);
+}
+
+static char *format_result(union acpi_object *object)
+{
+	char *buf = NULL;
+	
+	buf = (char *)kmalloc(RESULT_STR_LEN, GFP_KERNEL);
+	if (buf)
+		memset(buf, 0, RESULT_STR_LEN);
+	else
+		goto do_fail;
+
+	/* Now, just support integer type */
+	if (object->type == ACPI_TYPE_INTEGER)
+		sprintf(buf, "%d\n", (u32) object->integer.value);
+do_fail:
+	return (buf);
+}
+
+static int hotkey_polling_seq_show(struct seq_file *seq, void *offset)
+{
+	struct acpi_polling_hotkey *poll_hotkey =
+	    (struct acpi_polling_hotkey *)seq->private;
+	char *buf;
+
+	ACPI_FUNCTION_TRACE("hotkey_polling_seq_show");
+
+	if (poll_hotkey->poll_result){
+		buf = format_result(poll_hotkey->poll_result);
+		if(buf)
+			seq_printf(seq, "%s", buf);
+		kfree(buf);
+	}
+	return_VALUE(0);
+}
+
+static int hotkey_polling_open_fs(struct inode *inode, struct file *file)
+{
+	return single_open(file, hotkey_polling_seq_show, PDE(inode)->data);
+}
+
+static int hotkey_action_open_fs(struct inode *inode, struct file *file)
+{
+	return single_open(file, hotkey_info_seq_show, PDE(inode)->data);
+}
+
+/* Mapping external hotkey number to standardized hotkey event num */
+static int hotkey_get_internal_event(int event, struct acpi_hotkey_list *list)
+{
+	struct list_head *entries;
+	int val = -1;
+
+	ACPI_FUNCTION_TRACE("hotkey_get_internal_event");
+
+	list_for_each(entries, list->entries) {
+		union acpi_hotkey *key =
+		    container_of(entries, union acpi_hotkey, entries);
+		if (key->link.hotkey_type == ACPI_HOTKEY_EVENT
+		    && key->event_hotkey.external_hotkey_num == event){
+			val = key->link.hotkey_standard_num;
+			break;
+		}
+	}
+
+	return_VALUE(val);
+}
+
+static void
+acpi_hotkey_notify_handler(acpi_handle handle, u32 event, void *data)
+{
+	struct acpi_device *device = NULL;
+	u32 internal_event;
+
+	ACPI_FUNCTION_TRACE("acpi_hotkey_notify_handler");
+
+	if (acpi_bus_get_device(handle, &device))
+		return_VOID;
+
+	internal_event = hotkey_get_internal_event(event, &global_hotkey_list);
+	acpi_bus_generate_event(device, internal_event, 0);
+
+	return_VOID;
+}
+
+/* Need to invent automatically hotkey add method */
+static int auto_hotkey_add(struct acpi_device *device)
+{
+	/* Implement me */
+	return 0;
+}
+
+/* Need to invent automatically hotkey remove method */
+static int auto_hotkey_remove(struct acpi_device *device, int type)
+{
+	/* Implement me */
+	return 0;
+}
+
+/* Create a proc file for each polling method */
+static int create_polling_proc(union acpi_hotkey *device)
+{
+	struct proc_dir_entry *proc;
+	char  proc_name[80];
+	mode_t mode;
+
+	ACPI_FUNCTION_TRACE("create_polling_proc");
+	mode = S_IFREG | S_IRUGO | S_IWUGO;
+
+	sprintf(proc_name, "%d", device->link.hotkey_standard_num);
+	/*
+	strcat(proc_name, device->poll_hotkey.poll_method);
+	*/
+	proc = create_proc_entry(proc_name, mode, hotkey_proc_dir);
+
+	if (!proc) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				  "Hotkey: Unable to create %s entry\n",
+				  device->poll_hotkey.poll_method));
+		return_VALUE(-ENODEV);
+	} else {
+		proc->proc_fops = &hotkey_polling_fops;
+		proc->owner = THIS_MODULE;
+		proc->data = device;
+		proc->uid = 0;
+		proc->gid = 0;
+		device->poll_hotkey.proc = proc;
+	}
+	return_VALUE(0);
+}
+
+static int hotkey_add(union acpi_hotkey *device)
+{
+	int status = 0;
+	struct acpi_device *dev = NULL;
+
+	ACPI_FUNCTION_TRACE("hotkey_add");
+
+	if (device->link.hotkey_type == ACPI_HOTKEY_EVENT) {
+		acpi_bus_get_device(device->event_hotkey.bus_handle, &dev);
+		status = acpi_install_notify_handler(dev->handle,
+						     ACPI_DEVICE_NOTIFY,
+						     acpi_hotkey_notify_handler,
+						     dev);
+	} else			/* Add polling hotkey */
+		create_polling_proc(device);
+
+	global_hotkey_list.count++;
+
+	list_add_tail(&device->link.entries, global_hotkey_list.entries);
+
+	return_VALUE(status);
+}
+
+static int hotkey_remove(union acpi_hotkey *device)
+{
+	struct list_head *entries, *next;
+
+	ACPI_FUNCTION_TRACE("hotkey_remove");
+
+	list_for_each_safe(entries, next, global_hotkey_list.entries) {
+		union acpi_hotkey *key =
+		    container_of(entries, union acpi_hotkey, entries);
+		if (key->link.hotkey_standard_num ==
+		    device->link.hotkey_standard_num) {
+			list_del(&key->link.entries);
+			free_hotkey_device(key);
+			global_hotkey_list.count--;
+			break;
+		}
+	}
+	kfree(device);
+	return_VALUE(0);
+}
+
+static int  hotkey_update(union acpi_hotkey *key)
+{
+	struct list_head *entries;
+
+	ACPI_FUNCTION_TRACE("hotkey_update");
+
+	list_for_each(entries, global_hotkey_list.entries) {
+		union acpi_hotkey *tmp=
+		    container_of(entries, union acpi_hotkey, entries);
+		if (tmp->link.hotkey_standard_num ==
+		    key->link.hotkey_standard_num) {
+			if (key->link.hotkey_type == ACPI_HOTKEY_EVENT) {
+				free_hotkey_buffer(tmp);
+				tmp->event_hotkey.bus_handle =
+			    		key->event_hotkey.bus_handle;
+				tmp->event_hotkey.external_hotkey_num =
+			    		key->event_hotkey.external_hotkey_num;
+				tmp->event_hotkey.action_handle =
+			    		key->event_hotkey.action_handle;
+				tmp->event_hotkey.action_method =
+			    		key->event_hotkey.action_method;
+				kfree(key);
+			} else {
+				/*
+				char  proc_name[80];
+
+				sprintf(proc_name, "%d", tmp->link.hotkey_standard_num);
+				strcat(proc_name, tmp->poll_hotkey.poll_method);
+				remove_proc_entry(proc_name,hotkey_proc_dir);
+				*/
+				free_poll_hotkey_buffer(tmp);
+				tmp->poll_hotkey.poll_handle =
+					key->poll_hotkey.poll_handle;
+				tmp->poll_hotkey.poll_method =
+					key->poll_hotkey.poll_method;
+				tmp->poll_hotkey.action_handle =
+					key->poll_hotkey.action_handle;
+				tmp->poll_hotkey.action_method =
+					key->poll_hotkey.action_method;
+				tmp->poll_hotkey.poll_result =
+					key->poll_hotkey.poll_result;
+				/*
+				create_polling_proc(tmp);
+				*/
+				kfree(key);
+			}
+			return_VALUE(0);
+			break;
+		}
+	}
+
+	return_VALUE(-ENODEV);
+}
+
+static void free_hotkey_device(union acpi_hotkey *key)
+{
+	struct acpi_device *dev;
+
+	ACPI_FUNCTION_TRACE("free_hotkey_device");
+
+	if (key->link.hotkey_type == ACPI_HOTKEY_EVENT) {
+		acpi_bus_get_device(key->event_hotkey.bus_handle, &dev);
+		if (dev->handle)
+			acpi_remove_notify_handler(dev->handle,
+						   ACPI_DEVICE_NOTIFY,
+						   acpi_hotkey_notify_handler);
+		free_hotkey_buffer(key);
+	} else {
+		char  proc_name[80];
+
+		sprintf(proc_name, "%d", key->link.hotkey_standard_num);
+		/*
+		strcat(proc_name, key->poll_hotkey.poll_method);
+		*/
+		remove_proc_entry(proc_name,hotkey_proc_dir);
+		free_poll_hotkey_buffer(key);
+	}
+	kfree(key);
+	return_VOID;
+}
+
+static void
+free_hotkey_buffer(union acpi_hotkey *key)
+{
+	kfree(key->event_hotkey.action_method);
+}
+
+static void
+free_poll_hotkey_buffer(union acpi_hotkey *key)
+{
+	kfree(key->poll_hotkey.action_method);
+	kfree(key->poll_hotkey.poll_method);
+	kfree(key->poll_hotkey.poll_result);
+}
+static int
+init_hotkey_device(union acpi_hotkey *key, char *bus_str, char *action_str,
+		   char *method, int std_num, int external_num)
+{
+	acpi_handle	tmp_handle;
+	acpi_status status = AE_OK;
+
+	ACPI_FUNCTION_TRACE("init_hotkey_device");
+
+	if(std_num < 0 || IS_POLL(std_num) || !key )
+		goto do_fail;
+
+	if(!bus_str || !action_str || !method)
+		goto do_fail;
+
+	key->link.hotkey_type = ACPI_HOTKEY_EVENT;
+	key->link.hotkey_standard_num = std_num;
+	key->event_hotkey.flag = 0;
+	key->event_hotkey.action_method = method;
+
+	status = acpi_get_handle(NULL,bus_str, &(key->event_hotkey.bus_handle));
+	if(ACPI_FAILURE(status))
+		goto do_fail;
+	key->event_hotkey.external_hotkey_num = external_num;
+	status = acpi_get_handle(NULL,action_str, &(key->event_hotkey.action_handle));
+	if(ACPI_FAILURE(status))
+		goto do_fail;
+	status = acpi_get_handle(key->event_hotkey.action_handle,
+				method, &tmp_handle);
+	if (ACPI_FAILURE(status))
+		goto do_fail;
+	return_VALUE(AE_OK);
+do_fail:
+	return_VALUE(-ENODEV);
+}
+
+static int
+init_poll_hotkey_device(union acpi_hotkey *key,
+			char *poll_str,
+			char *poll_method,
+			char *action_str, char *action_method, int std_num)
+{
+	acpi_status status = AE_OK;
+	acpi_handle	tmp_handle;
+
+	ACPI_FUNCTION_TRACE("init_poll_hotkey_device");
+
+	if(std_num < 0 || IS_EVENT(std_num) || !key)
+		goto do_fail;
+
+	if(!poll_str || !poll_method || !action_str || !action_method)
+		goto do_fail;
+
+	key->link.hotkey_type = ACPI_HOTKEY_POLLING;
+	key->link.hotkey_standard_num = std_num;
+	key->poll_hotkey.flag = 0;
+	key->poll_hotkey.poll_method = poll_method;
+	key->poll_hotkey.action_method = action_method;
+
+	status = acpi_get_handle(NULL,poll_str, &(key->poll_hotkey.poll_handle));
+	if(ACPI_FAILURE(status))
+		goto do_fail;
+	status = acpi_get_handle(key->poll_hotkey.poll_handle,
+				poll_method, &tmp_handle);
+        if (ACPI_FAILURE(status))
+       		goto do_fail;
+	status = acpi_get_handle(NULL,action_str, &(key->poll_hotkey.action_handle));
+	if (ACPI_FAILURE(status))
+		goto do_fail;
+	status = acpi_get_handle(key->poll_hotkey.action_handle,
+				action_method, &tmp_handle);
+	if (ACPI_FAILURE(status))
+		goto do_fail;
+	key->poll_hotkey.poll_result =
+	    (union acpi_object *)kmalloc(sizeof(union acpi_object), GFP_KERNEL);
+	if(!key->poll_hotkey.poll_result)
+		goto do_fail;
+	return_VALUE(AE_OK);
+do_fail:
+	return_VALUE(-ENODEV);
+}
+
+
+static int hotkey_open_config(struct inode *inode, struct file *file)
+{
+	ACPI_FUNCTION_TRACE("hotkey_open_config");
+	return_VALUE(single_open
+		     (file, hotkey_config_seq_show, PDE(inode)->data));
+}
+
+static int hotkey_poll_open_config(struct inode *inode, struct file *file)
+{
+	ACPI_FUNCTION_TRACE("hotkey_poll_open_config");
+	return_VALUE(single_open
+		     (file, hotkey_poll_config_seq_show, PDE(inode)->data));
+}
+
+static int hotkey_config_seq_show(struct seq_file *seq, void *offset)
+{
+	struct acpi_hotkey_list *hotkey_list = &global_hotkey_list;
+	struct list_head *entries;
+	char bus_name[ACPI_PATHNAME_MAX] = { 0 };
+	char action_name[ACPI_PATHNAME_MAX] = { 0 };
+	struct acpi_buffer bus = { ACPI_PATHNAME_MAX, bus_name };
+	struct acpi_buffer act = { ACPI_PATHNAME_MAX, action_name };
+
+	ACPI_FUNCTION_TRACE(("hotkey_config_seq_show"));
+
+	list_for_each(entries, hotkey_list->entries) {
+		union acpi_hotkey *key =
+		    container_of(entries, union acpi_hotkey, entries);
+		if (key->link.hotkey_type == ACPI_HOTKEY_EVENT) {
+			acpi_get_name(key->event_hotkey.bus_handle,
+				      ACPI_NAME_TYPE_MAX, &bus);
+			acpi_get_name(key->event_hotkey.action_handle,
+				      ACPI_NAME_TYPE_MAX, &act);
+			seq_printf(seq, "%s:%s:%s:%d:%d\n", bus_name,
+				   action_name,
+				   key->event_hotkey.action_method,
+				   key->link.hotkey_standard_num,
+				   key->event_hotkey.external_hotkey_num);
+		}
+	}
+	seq_puts(seq, "\n");
+	return_VALUE(0);
+}
+
+static int hotkey_poll_config_seq_show(struct seq_file *seq, void *offset)
+{
+	struct acpi_hotkey_list *hotkey_list = &global_hotkey_list;
+	struct list_head *entries;
+	char bus_name[ACPI_PATHNAME_MAX] = { 0 };
+	char action_name[ACPI_PATHNAME_MAX] = { 0 };
+	struct acpi_buffer bus = { ACPI_PATHNAME_MAX, bus_name };
+	struct acpi_buffer act = { ACPI_PATHNAME_MAX, action_name };
+
+	ACPI_FUNCTION_TRACE(("hotkey_config_seq_show"));
+
+	list_for_each(entries, hotkey_list->entries) {
+		union acpi_hotkey *key =
+		    container_of(entries, union acpi_hotkey, entries);
+		if (key->link.hotkey_type == ACPI_HOTKEY_POLLING) {
+			acpi_get_name(key->poll_hotkey.poll_handle,
+				      ACPI_NAME_TYPE_MAX, &bus);
+			acpi_get_name(key->poll_hotkey.action_handle,
+				      ACPI_NAME_TYPE_MAX, &act);
+			seq_printf(seq, "%s:%s:%s:%s:%d\n", bus_name,
+				   key->poll_hotkey.poll_method,
+				   action_name,
+				   key->poll_hotkey.action_method,
+				   key->link.hotkey_standard_num);
+		}
+	}
+	seq_puts(seq, "\n");
+	return_VALUE(0);
+}
+
+static int
+get_parms(char *config_record,
+	  int *cmd,
+	  char **bus_handle,
+	  char **bus_method,
+	  char **action_handle,
+	  char **method, int *internal_event_num, int *external_event_num)
+{
+	char *tmp, *tmp1, count;
+	ACPI_FUNCTION_TRACE(("get_parms"));
+
+	sscanf(config_record, "%d", cmd);
+
+	if(*cmd == 1){
+		if(sscanf(config_record, "%d:%d", cmd, internal_event_num)!=2)
+			goto do_fail;
+		else
+			return (6);
+	}
+	tmp = strchr(config_record, ':');
+	if (!tmp)
+		goto do_fail;
+	tmp++;
+	tmp1 = strchr(tmp, ':');
+	if (!tmp1)
+		goto do_fail;
+
+	count = tmp1 - tmp;
+	*bus_handle = (char *) kmalloc(count+1, GFP_KERNEL);
+	if(!*bus_handle)
+		goto do_fail;
+	strncpy(*bus_handle, tmp, count);
+	*(*bus_handle + count) = 0;
+
+	tmp = tmp1;
+	tmp++;
+	tmp1 = strchr(tmp, ':');
+	if (!tmp1)
+		goto do_fail;
+	count = tmp1 - tmp;
+	*bus_method = (char *) kmalloc(count+1, GFP_KERNEL);
+	if(!*bus_method)
+		goto do_fail;
+	strncpy(*bus_method, tmp, count);
+	*(*bus_method + count) = 0;
+
+	tmp = tmp1;
+	tmp++;
+	tmp1 = strchr(tmp, ':');
+	if (!tmp1)
+		goto do_fail;
+	count = tmp1 - tmp;
+	*action_handle = (char *) kmalloc(count+1, GFP_KERNEL);
+	strncpy(*action_handle, tmp, count);
+	*(*action_handle + count) = 0;
+
+	tmp = tmp1;
+	tmp++;
+	tmp1 = strchr(tmp, ':');
+	if (!tmp1)
+		goto do_fail;
+	count = tmp1 - tmp;
+	*method = (char *) kmalloc(count+1, GFP_KERNEL);
+	if(!*method)
+		goto do_fail;
+	strncpy(*method, tmp, count);
+	*(*method + count) = 0;
+
+	if(sscanf(tmp1 + 1, "%d:%d", internal_event_num, external_event_num)<=0)
+		goto do_fail;
+
+	return_VALUE(6);
+do_fail:
+	return_VALUE(-1);
+}
+
+/*  count is length for one input record */
+static ssize_t hotkey_write_config(struct file *file,
+				   const char __user * buffer,
+				   size_t count, loff_t * data)
+{
+	char *config_record = NULL;
+	char *bus_handle = NULL;
+	char *bus_method = NULL;
+	char *action_handle = NULL;
+	char *method = NULL;
+	int cmd, internal_event_num, external_event_num;
+	int ret = 0;
+	union acpi_hotkey *key = NULL;
+
+	ACPI_FUNCTION_TRACE(("hotkey_write_config"));
+
+	config_record = (char *) kmalloc(count+1, GFP_KERNEL);
+	if(!config_record)
+		return_VALUE(-ENOMEM);
+
+	if (copy_from_user(config_record, buffer, count)) {
+		kfree(config_record);
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid data \n"));
+		return_VALUE(-EINVAL);
+	}
+	config_record[count] = 0;
+
+	ret = get_parms(config_record,
+			&cmd,
+			&bus_handle,
+			&bus_method,
+			&action_handle,
+			&method, &internal_event_num, &external_event_num);
+
+	kfree(config_record);
+	if(IS_OTHERS(internal_event_num))
+		goto do_fail;
+	if (ret != 6) {
+do_fail:	
+		kfree(bus_handle);
+		kfree(bus_method);
+		kfree(action_handle);
+		kfree(method);
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				  "Invalid data format ret=%d\n", ret));
+		return_VALUE(-EINVAL);
+	}
+
+	key = kmalloc(sizeof(union acpi_hotkey), GFP_KERNEL);
+	if(!key)
+		goto do_fail;
+	memset(key, 0, sizeof(union acpi_hotkey));
+	if(cmd == 1) {
+		union acpi_hotkey *tmp = NULL;
+		tmp = get_hotkey_by_event(&global_hotkey_list,
+				internal_event_num);
+		if(!tmp)
+			ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid key"));
+		else
+			memcpy(key, tmp, sizeof(union acpi_hotkey));
+		goto cont_cmd;
+	}
+	if (IS_EVENT(internal_event_num)) {
+		kfree(bus_method);
+		ret = init_hotkey_device(key, bus_handle, action_handle, method,
+				 internal_event_num, external_event_num);
+	} else
+		ret = init_poll_hotkey_device(key, bus_handle, bus_method,
+				      action_handle, method,
+				      internal_event_num);
+	if (ret) {
+		kfree(bus_handle);
+		kfree(action_handle);
+		if(IS_EVENT(internal_event_num))
+			free_hotkey_buffer(key);
+		else
+			free_poll_hotkey_buffer(key);
+		kfree(key);
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid hotkey \n"));
+		return_VALUE(-EINVAL);
+	}
+
+cont_cmd:
+	kfree(bus_handle);
+	kfree(action_handle);
+
+	switch (cmd) {
+	case 0:
+		if(get_hotkey_by_event(&global_hotkey_list,key->link.hotkey_standard_num))
+			goto fail_out;
+		else
+			hotkey_add(key);
+		break;
+	case 1:
+		hotkey_remove(key);
+		break;
+	case 2:
+		if(hotkey_update(key))
+			goto fail_out;
+		break;
+	default:
+		goto fail_out;
+		break;
+	}
+	return_VALUE(count);
+fail_out:
+	if(IS_EVENT(internal_event_num))
+		free_hotkey_buffer(key);
+	else
+		free_poll_hotkey_buffer(key);
+	kfree(key);
+	ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "invalid key\n"));
+	return_VALUE(-EINVAL);
+}
+
+/*
+ * This function evaluates an ACPI method, given an int as parameter, the
+ * method is searched within the scope of the handle, can be NULL. The output
+ * of the method is written is output, which can also be NULL
+ *
+ * returns 1 if write is successful, 0 else.
+ */
+static int write_acpi_int(acpi_handle handle, const char *method, int val,
+			  struct acpi_buffer *output)
+{
+	struct acpi_object_list params;	/* list of input parameters (an int here) */
+	union acpi_object in_obj;	/* the only param we use */
+	acpi_status status;
+
+	ACPI_FUNCTION_TRACE("write_acpi_int");
+	params.count = 1;
+	params.pointer = &in_obj;
+	in_obj.type = ACPI_TYPE_INTEGER;
+	in_obj.integer.value = val;
+
+	status = acpi_evaluate_object(handle, (char *)method, &params, output);
+
+	return_VALUE(status == AE_OK);
+}
+
+static int read_acpi_int(acpi_handle handle, const char *method, union acpi_object *val)
+{
+	struct acpi_buffer output;
+	union acpi_object out_obj;
+	acpi_status status;
+
+	ACPI_FUNCTION_TRACE("read_acpi_int");
+	output.length = sizeof(out_obj);
+	output.pointer = &out_obj;
+
+	status = acpi_evaluate_object(handle, (char *)method, NULL, &output);
+	if(val){
+		val->integer.value = out_obj.integer.value;
+		val->type = out_obj.type;
+	} else
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "null val pointer"));
+	return_VALUE((status == AE_OK)
+		     && (out_obj.type == ACPI_TYPE_INTEGER));
+}
+
+static union acpi_hotkey *get_hotkey_by_event(struct
+			      acpi_hotkey_list
+			      *hotkey_list, int event)
+{
+	struct list_head *entries;
+
+	list_for_each(entries, hotkey_list->entries) {
+		union acpi_hotkey *key =
+		    container_of(entries, union acpi_hotkey, entries);
+		if (key->link.hotkey_standard_num == event) {
+			return(key);
+		}
+	}
+	return(NULL);
+}
+
+/*
+ * user call AML method interface:
+ * Call convention:
+ * echo "event_num: arg type : value"
+ * example: echo "1:1:30" > /proc/acpi/action
+ * Just support 1 integer arg passing to AML method
+ */
+
+static ssize_t hotkey_execute_aml_method(struct file *file,
+					 const char __user * buffer,
+					 size_t count, loff_t * data)
+{
+	struct acpi_hotkey_list *hotkey_list = &global_hotkey_list;
+	char *arg;
+	int event,method_type,type, value;
+	union acpi_hotkey *key;
+
+	ACPI_FUNCTION_TRACE("hotkey_execte_aml_method");
+
+	arg = (char *) kmalloc(count+1, GFP_KERNEL);
+	if(!arg)
+		return_VALUE(-ENOMEM);
+	arg[count]=0;
+
+	if (copy_from_user(arg, buffer, count)) {
+		kfree(arg);
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid argument 2"));
+		return_VALUE(-EINVAL);
+	}
+
+	if (sscanf(arg, "%d:%d:%d:%d", &event, &method_type, &type, &value) != 4) {
+		kfree(arg);
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid argument 3"));
+		return_VALUE(-EINVAL);
+	}
+	kfree(arg);
+	if (type == ACPI_TYPE_INTEGER) {
+		key = get_hotkey_by_event(hotkey_list, event);
+		if(!key)
+			goto do_fail;
+		if (IS_EVENT(event))
+			write_acpi_int(key->event_hotkey.action_handle,
+					key->event_hotkey.action_method, value, NULL);
+		else if (IS_POLL(event)) {
+			if ( method_type == POLL_METHOD )
+				read_acpi_int(key->poll_hotkey.poll_handle,
+					key->poll_hotkey.poll_method,
+					key->poll_hotkey.poll_result);
+			else if ( method_type == ACTION_METHOD )
+				write_acpi_int(key->poll_hotkey.action_handle,
+					key->poll_hotkey.action_method, value, NULL);
+			else
+				goto do_fail;
+
+		}
+	} else {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Not supported"));
+		return_VALUE(-EINVAL);
+	}
+	return_VALUE(count);
+do_fail:
+	return_VALUE(-EINVAL);
+
+}
+
+static int __init hotkey_init(void)
+{
+	int result;
+	mode_t mode = S_IFREG | S_IRUGO | S_IWUGO;
+
+	ACPI_FUNCTION_TRACE("hotkey_init");
+
+	if (acpi_disabled)
+		return -ENODEV;
+
+	if (acpi_specific_hotkey_enabled) {
+		printk("Using specific hotkey driver\n");
+		return -ENODEV;
+	}
+
+	hotkey_proc_dir = proc_mkdir(HOTKEY_PROC, acpi_root_dir);
+	if (!hotkey_proc_dir) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				  "Hotkey: Unable to create %s entry\n",
+				  HOTKEY_PROC));
+		return (-ENODEV);
+	}
+	hotkey_proc_dir->owner = THIS_MODULE;
+
+	hotkey_config =
+	    create_proc_entry(HOTKEY_EV_CONFIG, mode, hotkey_proc_dir);
+	if (!hotkey_config) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				  "Hotkey: Unable to create %s entry\n",
+				  HOTKEY_EV_CONFIG));
+		goto do_fail1;
+	} else {
+		hotkey_config->proc_fops = &hotkey_config_fops;
+		hotkey_config->data = &global_hotkey_list;
+		hotkey_config->owner = THIS_MODULE;
+		hotkey_config->uid = 0;
+		hotkey_config->gid = 0;
+	}
+
+	hotkey_poll_config =
+	    create_proc_entry(HOTKEY_PL_CONFIG, mode, hotkey_proc_dir);
+	if (!hotkey_poll_config) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				  "Hotkey: Unable to create %s entry\n",
+				  HOTKEY_EV_CONFIG));
+
+		goto do_fail2;
+	} else {
+		hotkey_poll_config->proc_fops = &hotkey_poll_config_fops;
+		hotkey_poll_config->data = &global_hotkey_list;
+		hotkey_poll_config->owner = THIS_MODULE;
+		hotkey_poll_config->uid = 0;
+		hotkey_poll_config->gid = 0;
+	}
+
+	hotkey_action = create_proc_entry(HOTKEY_ACTION, mode, hotkey_proc_dir);
+	if (!hotkey_action) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				  "Hotkey: Unable to create %s entry\n",
+				  HOTKEY_ACTION));
+		goto do_fail3;
+	} else {
+		hotkey_action->proc_fops = &hotkey_action_fops;
+		hotkey_action->owner = THIS_MODULE;
+		hotkey_action->uid = 0;
+		hotkey_action->gid = 0;
+	}
+
+	hotkey_info = create_proc_entry(HOTKEY_INFO, mode, hotkey_proc_dir);
+	if (!hotkey_info) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				  "Hotkey: Unable to create %s entry\n",
+				  HOTKEY_INFO));
+		goto do_fail4;
+	} else {
+		hotkey_info->proc_fops = &hotkey_info_fops;
+		hotkey_info->owner = THIS_MODULE;
+		hotkey_info->uid = 0;
+		hotkey_info->gid = 0;
+	}
+
+	result = acpi_bus_register_driver(&hotkey_driver);
+	if (result < 0)
+		goto do_fail5;
+	global_hotkey_list.count = 0;
+	global_hotkey_list.entries = &hotkey_entries;
+
+	INIT_LIST_HEAD(&hotkey_entries);
+
+	return (0);
+
+do_fail5:
+	remove_proc_entry(HOTKEY_INFO, hotkey_proc_dir);
+do_fail4:
+	remove_proc_entry(HOTKEY_ACTION, hotkey_proc_dir);
+do_fail3:
+	remove_proc_entry(HOTKEY_PL_CONFIG, hotkey_proc_dir);
+do_fail2:
+	remove_proc_entry(HOTKEY_EV_CONFIG, hotkey_proc_dir);
+do_fail1:
+	remove_proc_entry(HOTKEY_PROC, acpi_root_dir);
+	return (-ENODEV);
+}
+
+static void __exit hotkey_exit(void)
+{
+	struct list_head *entries, *next;
+
+	ACPI_FUNCTION_TRACE("hotkey_exit");
+
+	list_for_each_safe(entries, next, global_hotkey_list.entries) {
+		union acpi_hotkey *key =
+		    container_of(entries, union acpi_hotkey, entries);
+
+		acpi_os_wait_events_complete(NULL);
+		list_del(&key->link.entries);
+		global_hotkey_list.count--;
+		free_hotkey_device(key);
+	}
+	acpi_bus_unregister_driver(&hotkey_driver);
+	remove_proc_entry(HOTKEY_EV_CONFIG, hotkey_proc_dir);
+	remove_proc_entry(HOTKEY_PL_CONFIG, hotkey_proc_dir);
+	remove_proc_entry(HOTKEY_ACTION, hotkey_proc_dir);
+	remove_proc_entry(HOTKEY_INFO, hotkey_proc_dir);
+	remove_proc_entry(HOTKEY_PROC, acpi_root_dir);
+	return;
+}
+
+module_init(hotkey_init);
+module_exit(hotkey_exit);
diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c
--- a/drivers/acpi/ibm_acpi.c
+++ b/drivers/acpi/ibm_acpi.c
@@ -1025,7 +1025,7 @@ static int setup_notify(struct ibm_struc
 	return 0;
 }
 
-static int device_add(struct acpi_device *device)
+static int ibmacpi_device_add(struct acpi_device *device)
 {
 	return 0;
 }
@@ -1043,7 +1043,7 @@ static int register_driver(struct ibm_st
 	memset(ibm->driver, 0, sizeof(struct acpi_driver));
 	sprintf(ibm->driver->name, "%s/%s", IBM_NAME, ibm->name);
 	ibm->driver->ids = ibm->hid;
-	ibm->driver->ops.add = &device_add;
+	ibm->driver->ops.add = &ibmacpi_device_add;
 
 	ret = acpi_bus_register_driver(ibm->driver);
 	if (ret < 0) {
@@ -1185,6 +1185,10 @@ static int __init acpi_ibm_init(void)
 	if (acpi_disabled)
 		return -ENODEV;
 
+	if (!acpi_specific_hotkey_enabled){
+		printk(IBM_ERR "Using generic hotkey driver\n");
+		return -ENODEV;	
+	}
 	/* these handles are required */
 	if (IBM_HANDLE_INIT(ec,	  1) < 0 ||
 	    IBM_HANDLE_INIT(hkey, 1) < 0 ||
diff --git a/drivers/acpi/namespace/nsaccess.c b/drivers/acpi/namespace/nsaccess.c
--- a/drivers/acpi/namespace/nsaccess.c
+++ b/drivers/acpi/namespace/nsaccess.c
@@ -67,7 +67,8 @@
  ******************************************************************************/
 
 acpi_status
-acpi_ns_root_initialize (void)
+acpi_ns_root_initialize (
+	void)
 {
 	acpi_status                         status;
 	const struct acpi_predefined_names *init_val = NULL;
@@ -265,7 +266,7 @@ unlock_and_exit:
  *
  * FUNCTION:    acpi_ns_lookup
  *
- * PARAMETERS:  prefix_node     - Search scope if name is not fully qualified
+ * PARAMETERS:  scope_info      - Current scope info block
  *              Pathname        - Search pathname, in internal format
  *                                (as represented in the AML stream)
  *              Type            - Type associated with name
diff --git a/drivers/acpi/namespace/nsalloc.c b/drivers/acpi/namespace/nsalloc.c
--- a/drivers/acpi/namespace/nsalloc.c
+++ b/drivers/acpi/namespace/nsalloc.c
@@ -49,14 +49,20 @@
 #define _COMPONENT          ACPI_NAMESPACE
 	 ACPI_MODULE_NAME    ("nsalloc")
 
+/* Local prototypes */
+
+static void
+acpi_ns_remove_reference (
+	struct acpi_namespace_node      *node);
+
 
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ns_create_node
  *
- * PARAMETERS:  acpi_name       - Name of the new node
+ * PARAMETERS:  Name            - Name of the new node (4 char ACPI name)
  *
- * RETURN:      None
+ * RETURN:      New namespace node (Null on failure)
  *
  * DESCRIPTION: Create a namespace node
  *
@@ -145,7 +151,6 @@ acpi_ns_delete_node (
 		}
 	}
 
-
 	ACPI_MEM_TRACKING (acpi_gbl_memory_lists[ACPI_MEM_LIST_NSNODE].total_freed++);
 
 	/*
@@ -157,57 +162,6 @@ acpi_ns_delete_node (
 }
 
 
-#ifdef ACPI_ALPHABETIC_NAMESPACE
-/*******************************************************************************
- *
- * FUNCTION:    acpi_ns_compare_names
- *
- * PARAMETERS:  Name1           - First name to compare
- *              Name2           - Second name to compare
- *
- * RETURN:      value from strncmp
- *
- * DESCRIPTION: Compare two ACPI names.  Names that are prefixed with an
- *              underscore are forced to be alphabetically first.
- *
- ******************************************************************************/
-
-int
-acpi_ns_compare_names (
-	char                            *name1,
-	char                            *name2)
-{
-	char                            reversed_name1[ACPI_NAME_SIZE];
-	char                            reversed_name2[ACPI_NAME_SIZE];
-	u32                             i;
-	u32                             j;
-
-
-	/*
-	 * Replace all instances of "underscore" with a value that is smaller so
-	 * that all names that are prefixed with underscore(s) are alphabetically
-	 * first.
-	 *
-	 * Reverse the name bytewise so we can just do a 32-bit compare instead
-	 * of a strncmp.
-	 */
-	for (i = 0, j= (ACPI_NAME_SIZE - 1); i < ACPI_NAME_SIZE; i++, j--) {
-		reversed_name1[j] = name1[i];
-		if (name1[i] == '_') {
-			reversed_name1[j] = '*';
-		}
-
-		reversed_name2[j] = name2[i];
-		if (name2[i] == '_') {
-			reversed_name2[j] = '*';
-		}
-	}
-
-	return (*(int *) reversed_name1 - *(int *) reversed_name2);
-}
-#endif
-
-
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ns_install_node
@@ -271,7 +225,8 @@ acpi_ns_install_node (
 		 * alphabetic placement.
 		 */
 		previous_child_node = NULL;
-		while (acpi_ns_compare_names (acpi_ut_get_node_name (child_node), acpi_ut_get_node_name (node)) < 0) {
+		while (acpi_ns_compare_names (acpi_ut_get_node_name (child_node),
+				 acpi_ut_get_node_name (node)) < 0) {
 			if (child_node->flags & ANOBJ_END_OF_PEER_LIST) {
 				/* Last peer;  Clear end-of-list flag */
 
@@ -429,7 +384,8 @@ acpi_ns_delete_children (
 		/* There should be only one reference remaining on this node */
 
 		if (child_node->reference_count != 1) {
-			ACPI_REPORT_WARNING (("Existing references (%d) on node being deleted (%p)\n",
+			ACPI_REPORT_WARNING ((
+				"Existing references (%d) on node being deleted (%p)\n",
 				child_node->reference_count, child_node));
 		}
 
@@ -548,7 +504,7 @@ acpi_ns_delete_namespace_subtree (
  *
  ******************************************************************************/
 
-void
+static void
 acpi_ns_remove_reference (
 	struct acpi_namespace_node      *node)
 {
@@ -683,3 +639,54 @@ acpi_ns_delete_namespace_by_owner (
 }
 
 
+#ifdef ACPI_ALPHABETIC_NAMESPACE
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_compare_names
+ *
+ * PARAMETERS:  Name1           - First name to compare
+ *              Name2           - Second name to compare
+ *
+ * RETURN:      value from strncmp
+ *
+ * DESCRIPTION: Compare two ACPI names.  Names that are prefixed with an
+ *              underscore are forced to be alphabetically first.
+ *
+ ******************************************************************************/
+
+int
+acpi_ns_compare_names (
+	char                            *name1,
+	char                            *name2)
+{
+	char                            reversed_name1[ACPI_NAME_SIZE];
+	char                            reversed_name2[ACPI_NAME_SIZE];
+	u32                             i;
+	u32                             j;
+
+
+	/*
+	 * Replace all instances of "underscore" with a value that is smaller so
+	 * that all names that are prefixed with underscore(s) are alphabetically
+	 * first.
+	 *
+	 * Reverse the name bytewise so we can just do a 32-bit compare instead
+	 * of a strncmp.
+	 */
+	for (i = 0, j= (ACPI_NAME_SIZE - 1); i < ACPI_NAME_SIZE; i++, j--) {
+		reversed_name1[j] = name1[i];
+		if (name1[i] == '_') {
+			reversed_name1[j] = '*';
+		}
+
+		reversed_name2[j] = name2[i];
+		if (name2[i] == '_') {
+			reversed_name2[j] = '*';
+		}
+	}
+
+	return (*(int *) reversed_name1 - *(int *) reversed_name2);
+}
+#endif
+
+
diff --git a/drivers/acpi/namespace/nsdump.c b/drivers/acpi/namespace/nsdump.c
--- a/drivers/acpi/namespace/nsdump.c
+++ b/drivers/acpi/namespace/nsdump.c
@@ -50,16 +50,32 @@
 #define _COMPONENT          ACPI_NAMESPACE
 	 ACPI_MODULE_NAME    ("nsdump")
 
+/* Local prototypes */
 
-#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
+#ifdef ACPI_OBSOLETE_FUNCTIONS
+void
+acpi_ns_dump_root_devices (
+	void);
 
+static acpi_status
+acpi_ns_dump_one_device (
+	acpi_handle                     obj_handle,
+	u32                             level,
+	void                            *context,
+	void                            **return_value);
+#endif
+
+
+#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ns_print_pathname
  *
- * PARAMETERS:  num_segment         - Number of ACPI name segments
+ * PARAMETERS:  num_segments        - Number of ACPI name segments
  *              Pathname            - The compressed (internal) path
  *
+ * RETURN:      None
+ *
  * DESCRIPTION: Print an object's full namespace pathname
  *
  ******************************************************************************/
@@ -103,6 +119,8 @@ acpi_ns_print_pathname (
  *              Level               - Desired debug level
  *              Component           - Caller's component ID
  *
+ * RETURN:      None
+ *
  * DESCRIPTION: Print an object's full namespace pathname
  *              Manages allocation/freeing of a pathname buffer
  *
@@ -137,9 +155,12 @@ acpi_ns_dump_pathname (
  *
  * FUNCTION:    acpi_ns_dump_one_object
  *
- * PARAMETERS:  Handle              - Node to be dumped
+ * PARAMETERS:  obj_handle          - Node to be dumped
  *              Level               - Nesting level of the handle
  *              Context             - Passed into walk_namespace
+ *              return_value        - Not used
+ *
+ * RETURN:      Status
  *
  * DESCRIPTION: Dump a single Node
  *              This procedure is a user_function called by acpi_ns_walk_namespace.
@@ -394,8 +415,7 @@ acpi_ns_dump_one_object (
 			return (AE_OK);
 		}
 
-		acpi_os_printf ("(R%d)",
-				obj_desc->common.reference_count);
+		acpi_os_printf ("(R%d)", obj_desc->common.reference_count);
 
 		switch (type) {
 		case ACPI_TYPE_METHOD:
@@ -551,18 +571,20 @@ cleanup:
 
 
 #ifdef ACPI_FUTURE_USAGE
-
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ns_dump_objects
  *
  * PARAMETERS:  Type                - Object type to be dumped
+ *              display_type        - 0 or ACPI_DISPLAY_SUMMARY
  *              max_depth           - Maximum depth of dump. Use ACPI_UINT32_MAX
  *                                    for an effectively unlimited depth.
  *              owner_id            - Dump only objects owned by this ID.  Use
  *                                    ACPI_UINT32_MAX to match all owners.
  *              start_handle        - Where in namespace to start/end search
  *
+ * RETURN:      None
+ *
  * DESCRIPTION: Dump typed objects within the loaded namespace.
  *              Uses acpi_ns_walk_namespace in conjunction with acpi_ns_dump_one_object.
  *
@@ -590,10 +612,44 @@ acpi_ns_dump_objects (
 			 ACPI_NS_WALK_NO_UNLOCK, acpi_ns_dump_one_object,
 			 (void *) &info, NULL);
 }
+#endif	/* ACPI_FUTURE_USAGE */
 
 
 /*******************************************************************************
  *
+ * FUNCTION:    acpi_ns_dump_entry
+ *
+ * PARAMETERS:  Handle              - Node to be dumped
+ *              debug_level         - Output level
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Dump a single Node
+ *
+ ******************************************************************************/
+
+void
+acpi_ns_dump_entry (
+	acpi_handle                     handle,
+	u32                             debug_level)
+{
+	struct acpi_walk_info           info;
+
+
+	ACPI_FUNCTION_ENTRY ();
+
+
+	info.debug_level = debug_level;
+	info.owner_id = ACPI_UINT32_MAX;
+	info.display_type = ACPI_DISPLAY_SUMMARY;
+
+	(void) acpi_ns_dump_one_object (handle, 1, &info, NULL);
+}
+
+
+#ifdef _ACPI_ASL_COMPILER
+/*******************************************************************************
+ *
  * FUNCTION:    acpi_ns_dump_tables
  *
  * PARAMETERS:  search_base         - Root of subtree to be dumped, or
@@ -601,6 +657,8 @@ acpi_ns_dump_objects (
  *              max_depth           - Maximum depth of dump.  Use INT_MAX
  *                                    for an effectively unlimited depth.
  *
+ * RETURN:      None
+ *
  * DESCRIPTION: Dump the name space, or a portion of it.
  *
  ******************************************************************************/
@@ -626,7 +684,7 @@ acpi_ns_dump_tables (
 	}
 
 	if (ACPI_NS_ALL == search_base) {
-		/*  entire namespace    */
+		/* Entire namespace */
 
 		search_handle = acpi_gbl_root_node;
 		ACPI_DEBUG_PRINT ((ACPI_DB_TABLES, "\\\n"));
@@ -636,38 +694,5 @@ acpi_ns_dump_tables (
 			ACPI_UINT32_MAX, search_handle);
 	return_VOID;
 }
-
-#endif  /*  ACPI_FUTURE_USAGE  */
-
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_ns_dump_entry
- *
- * PARAMETERS:  Handle              - Node to be dumped
- *              debug_level         - Output level
- *
- * DESCRIPTION: Dump a single Node
- *
- ******************************************************************************/
-
-void
-acpi_ns_dump_entry (
-	acpi_handle                     handle,
-	u32                             debug_level)
-{
-	struct acpi_walk_info           info;
-
-
-	ACPI_FUNCTION_ENTRY ();
-
-
-	info.debug_level = debug_level;
-	info.owner_id = ACPI_UINT32_MAX;
-	info.display_type = ACPI_DISPLAY_SUMMARY;
-
-	(void) acpi_ns_dump_one_object (handle, 1, &info, NULL);
-}
-
-#endif
-
+#endif	/* _ACPI_ASL_COMPILER */
+#endif	/* defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER) */
diff --git a/drivers/acpi/namespace/nsdumpdv.c b/drivers/acpi/namespace/nsdumpdv.c
--- a/drivers/acpi/namespace/nsdumpdv.c
+++ b/drivers/acpi/namespace/nsdumpdv.c
@@ -43,15 +43,18 @@
 
 
 #include <acpi/acpi.h>
-#include <acpi/acnamesp.h>
 
 
+/* TBD: This entire module is apparently obsolete and should be removed */
+
 #define _COMPONENT          ACPI_NAMESPACE
 	 ACPI_MODULE_NAME    ("nsdumpdv")
 
-
+#ifdef ACPI_OBSOLETE_FUNCTIONS
 #if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
 
+#include <acpi/acnamesp.h>
+
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ns_dump_one_device
@@ -59,13 +62,16 @@
  * PARAMETERS:  Handle              - Node to be dumped
  *              Level               - Nesting level of the handle
  *              Context             - Passed into walk_namespace
+ *              return_value        - Not used
+ *
+ * RETURN:      Status
  *
  * DESCRIPTION: Dump a single Node that represents a device
  *              This procedure is a user_function called by acpi_ns_walk_namespace.
  *
  ******************************************************************************/
 
-acpi_status
+static acpi_status
 acpi_ns_dump_one_device (
 	acpi_handle                     obj_handle,
 	u32                             level,
@@ -108,12 +114,15 @@ acpi_ns_dump_one_device (
  *
  * PARAMETERS:  None
  *
+ * RETURN:      None
+ *
  * DESCRIPTION: Dump all objects of type "device"
  *
  ******************************************************************************/
 
 void
-acpi_ns_dump_root_devices (void)
+acpi_ns_dump_root_devices (
+	void)
 {
 	acpi_handle                     sys_bus_handle;
 	acpi_status                     status;
@@ -142,5 +151,6 @@ acpi_ns_dump_root_devices (void)
 }
 
 #endif
+#endif
 
 
diff --git a/drivers/acpi/namespace/nseval.c b/drivers/acpi/namespace/nseval.c
--- a/drivers/acpi/namespace/nseval.c
+++ b/drivers/acpi/namespace/nseval.c
@@ -52,19 +52,33 @@
 #define _COMPONENT          ACPI_NAMESPACE
 	 ACPI_MODULE_NAME    ("nseval")
 
+/* Local prototypes */
+
+static acpi_status
+acpi_ns_execute_control_method (
+	struct acpi_parameter_info      *info);
+
+static acpi_status
+acpi_ns_get_object_value (
+	struct acpi_parameter_info      *info);
+
 
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ns_evaluate_relative
  *
- * PARAMETERS:  Pathname            - Name of method to execute, If NULL, the
- *                                    handle is the object to execute
- *              Info                - Method info block
+ * PARAMETERS:  Pathname        - Name of method to execute, If NULL, the
+ *                                handle is the object to execute
+ *              Info            - Method info block, contains:
+ *                  return_object   - Where to put method's return value (if
+ *                                    any).  If NULL, no value is returned.
+ *                  Params          - List of parameters to pass to the method,
+ *                                    terminated by NULL.  Params itself may be
+ *                                    NULL if no parameters are being passed.
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Find and execute the requested method using the handle as a
- *              scope
+ * DESCRIPTION: Evaluate the object or find and execute the requested method
  *
  * MUTEX:       Locks Namespace
  *
@@ -157,8 +171,8 @@ cleanup1:
  *
  * FUNCTION:    acpi_ns_evaluate_by_name
  *
- * PARAMETERS:  Pathname            - Fully qualified pathname to the object
- *              Info                - Contains:
+ * PARAMETERS:  Pathname        - Fully qualified pathname to the object
+ *              Info                - Method info block, contains:
  *                  return_object   - Where to put method's return value (if
  *                                    any).  If NULL, no value is returned.
  *                  Params          - List of parameters to pass to the method,
@@ -167,8 +181,8 @@ cleanup1:
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Find and execute the requested method passing the given
- *              parameters
+ * DESCRIPTION: Evaluate the object or rind and execute the requested method
+ *              passing the given parameters
  *
  * MUTEX:       Locks Namespace
  *
@@ -241,17 +255,21 @@ cleanup:
  *
  * FUNCTION:    acpi_ns_evaluate_by_handle
  *
- * PARAMETERS:  Handle              - Method Node to execute
- *              Params              - List of parameters to pass to the method,
- *                                    terminated by NULL.  Params itself may be
+ * PARAMETERS:  Info            - Method info block, contains:
+ *                  Node            - Method/Object Node to execute
+ *                  Parameters      - List of parameters to pass to the method,
+ *                                    terminated by NULL. Params itself may be
  *                                    NULL if no parameters are being passed.
- *              param_type          - Type of Parameter list
- *              return_object       - Where to put method's return value (if
- *                                    any).  If NULL, no value is returned.
+ *                  return_object   - Where to put method's return value (if
+ *                                    any). If NULL, no value is returned.
+ *                  parameter_type  - Type of Parameter list
+ *                  return_object   - Where to put method's return value (if
+ *                                    any). If NULL, no value is returned.
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Execute the requested method passing the given parameters
+ * DESCRIPTION: Evaluate object or execute the requested method passing the
+ *              given parameters
  *
  * MUTEX:       Locks Namespace
  *
@@ -345,7 +363,16 @@ acpi_ns_evaluate_by_handle (
  *
  * FUNCTION:    acpi_ns_execute_control_method
  *
- * PARAMETERS:  Info            - Method info block (w/params)
+ * PARAMETERS:  Info            - Method info block, contains:
+ *                  Node            - Method Node to execute
+ *                  Parameters      - List of parameters to pass to the method,
+ *                                    terminated by NULL. Params itself may be
+ *                                    NULL if no parameters are being passed.
+ *                  return_object   - Where to put method's return value (if
+ *                                    any). If NULL, no value is returned.
+ *                  parameter_type  - Type of Parameter list
+ *                  return_object   - Where to put method's return value (if
+ *                                    any). If NULL, no value is returned.
  *
  * RETURN:      Status
  *
@@ -355,7 +382,7 @@ acpi_ns_evaluate_by_handle (
  *
  ******************************************************************************/
 
-acpi_status
+static acpi_status
 acpi_ns_execute_control_method (
 	struct acpi_parameter_info      *info)
 {
@@ -414,7 +441,10 @@ acpi_ns_execute_control_method (
  *
  * FUNCTION:    acpi_ns_get_object_value
  *
- * PARAMETERS:  Info            - Method info block (w/params)
+ * PARAMETERS:  Info            - Method info block, contains:
+ *                  Node            - Object's NS node
+ *                  return_object   - Where to put object value (if
+ *                                    any). If NULL, no value is returned.
  *
  * RETURN:      Status
  *
@@ -424,7 +454,7 @@ acpi_ns_execute_control_method (
  *
  ******************************************************************************/
 
-acpi_status
+static acpi_status
 acpi_ns_get_object_value (
 	struct acpi_parameter_info      *info)
 {
diff --git a/drivers/acpi/namespace/nsinit.c b/drivers/acpi/namespace/nsinit.c
--- a/drivers/acpi/namespace/nsinit.c
+++ b/drivers/acpi/namespace/nsinit.c
@@ -50,6 +50,22 @@
 #define _COMPONENT          ACPI_NAMESPACE
 	 ACPI_MODULE_NAME    ("nsinit")
 
+/* Local prototypes */
+
+static acpi_status
+acpi_ns_init_one_object (
+	acpi_handle                     obj_handle,
+	u32                             level,
+	void                            *context,
+	void                            **return_value);
+
+static acpi_status
+acpi_ns_init_one_device (
+	acpi_handle                     obj_handle,
+	u32                             nesting_level,
+	void                            *context,
+	void                            **return_value);
+
 
 /*******************************************************************************
  *
@@ -191,7 +207,7 @@ acpi_ns_initialize_devices (
  *
  ******************************************************************************/
 
-acpi_status
+static acpi_status
 acpi_ns_init_one_object (
 	acpi_handle                     obj_handle,
 	u32                             level,
@@ -331,7 +347,7 @@ acpi_ns_init_one_object (
  *
  ******************************************************************************/
 
-acpi_status
+static acpi_status
 acpi_ns_init_one_device (
 	acpi_handle                     obj_handle,
 	u32                             nesting_level,
@@ -374,7 +390,8 @@ acpi_ns_init_one_device (
 	/*
 	 * Run _STA to determine if we can run _INI on the device.
 	 */
-	ACPI_DEBUG_EXEC (acpi_ut_display_init_pathname (ACPI_TYPE_METHOD, pinfo.node, "_STA"));
+	ACPI_DEBUG_EXEC (acpi_ut_display_init_pathname (ACPI_TYPE_METHOD,
+			   pinfo.node, METHOD_NAME__STA));
 	status = acpi_ut_execute_STA (pinfo.node, &flags);
 
 	if (ACPI_FAILURE (status)) {
@@ -399,8 +416,9 @@ acpi_ns_init_one_device (
 	/*
 	 * The device is present. Run _INI.
 	 */
-	ACPI_DEBUG_EXEC (acpi_ut_display_init_pathname (ACPI_TYPE_METHOD, pinfo.node, "_INI"));
-	status = acpi_ns_evaluate_relative ("_INI", &pinfo);
+	ACPI_DEBUG_EXEC (acpi_ut_display_init_pathname (ACPI_TYPE_METHOD,
+			   pinfo.node, METHOD_NAME__INI));
+	status = acpi_ns_evaluate_relative (METHOD_NAME__INI, &pinfo);
 	if (ACPI_FAILURE (status)) {
 		/* No _INI (AE_NOT_FOUND) means device requires no initialization */
 
diff --git a/drivers/acpi/namespace/nsload.c b/drivers/acpi/namespace/nsload.c
--- a/drivers/acpi/namespace/nsload.c
+++ b/drivers/acpi/namespace/nsload.c
@@ -50,9 +50,24 @@
 #define _COMPONENT          ACPI_NAMESPACE
 	 ACPI_MODULE_NAME    ("nsload")
 
+/* Local prototypes */
 
-#ifndef ACPI_NO_METHOD_EXECUTION
+static acpi_status
+acpi_ns_load_table_by_type (
+	acpi_table_type                 table_type);
+
+#ifdef ACPI_FUTURE_IMPLEMENTATION
+acpi_status
+acpi_ns_unload_namespace (
+	acpi_handle                     handle);
+
+static acpi_status
+acpi_ns_delete_subtree (
+	acpi_handle                     start_handle);
+#endif
 
+
+#ifndef ACPI_NO_METHOD_EXECUTION
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ns_load_table
@@ -159,7 +174,7 @@ acpi_ns_load_table (
  *
  ******************************************************************************/
 
-acpi_status
+static acpi_status
 acpi_ns_load_table_by_type (
 	acpi_table_type                 table_type)
 {
@@ -321,8 +336,7 @@ acpi_ns_load_namespace (
 }
 
 
-#ifdef ACPI_FUTURE_USAGE
-
+#ifdef ACPI_FUTURE_IMPLEMENTATION
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ns_delete_subtree
@@ -339,7 +353,7 @@ acpi_ns_load_namespace (
  *
  ******************************************************************************/
 
-acpi_status
+static acpi_status
 acpi_ns_delete_subtree (
 	acpi_handle                     start_handle)
 {
@@ -453,8 +467,6 @@ acpi_ns_unload_namespace (
 
 	return_ACPI_STATUS (status);
 }
-
-#endif  /*  ACPI_FUTURE_USAGE  */
-
+#endif
 #endif
 
diff --git a/drivers/acpi/namespace/nsnames.c b/drivers/acpi/namespace/nsnames.c
--- a/drivers/acpi/namespace/nsnames.c
+++ b/drivers/acpi/namespace/nsnames.c
@@ -50,6 +50,14 @@
 #define _COMPONENT          ACPI_NAMESPACE
 	 ACPI_MODULE_NAME    ("nsnames")
 
+/* Local prototypes */
+
+static void
+acpi_ns_build_external_path (
+	struct acpi_namespace_node      *node,
+	acpi_size                       size,
+	char                            *name_buffer);
+
 
 /*******************************************************************************
  *
@@ -66,7 +74,7 @@
  *
  ******************************************************************************/
 
-void
+static void
 acpi_ns_build_external_path (
 	struct acpi_namespace_node      *node,
 	acpi_size                       size,
@@ -126,7 +134,7 @@ acpi_ns_build_external_path (
  *
  * FUNCTION:    acpi_ns_get_external_pathname
  *
- * PARAMETERS:  Node            - NS node whose pathname is needed
+ * PARAMETERS:  Node            - Namespace node whose pathname is needed
  *
  * RETURN:      Pointer to storage containing the fully qualified name of
  *              the node, In external format (name segments separated by path
diff --git a/drivers/acpi/namespace/nsobject.c b/drivers/acpi/namespace/nsobject.c
--- a/drivers/acpi/namespace/nsobject.c
+++ b/drivers/acpi/namespace/nsobject.c
@@ -60,6 +60,8 @@
  *              Type                - Type of object, or ACPI_TYPE_ANY if not
  *                                    known
  *
+ * RETURN:      Status
+ *
  * DESCRIPTION: Record the given object as the value associated with the
  *              name whose acpi_handle is passed.  If Object is NULL
  *              and Type is ACPI_TYPE_ANY, set the name as having no value.
@@ -97,7 +99,8 @@ acpi_ns_attach_object (
 	if (!object && (ACPI_TYPE_ANY != type)) {
 		/* Null object */
 
-		ACPI_REPORT_ERROR (("ns_attach_object: Null object, but type not ACPI_TYPE_ANY\n"));
+		ACPI_REPORT_ERROR ((
+			"ns_attach_object: Null object, but type not ACPI_TYPE_ANY\n"));
 		return_ACPI_STATUS (AE_BAD_PARAMETER);
 	}
 
@@ -112,7 +115,8 @@ acpi_ns_attach_object (
 	/* Check if this object is already attached */
 
 	if (node->object == object) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj %p already installed in name_obj %p\n",
+		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+			"Obj %p already installed in name_obj %p\n",
 			object, node));
 
 		return_ACPI_STATUS (AE_OK);
@@ -192,7 +196,7 @@ acpi_ns_attach_object (
  *
  * FUNCTION:    acpi_ns_detach_object
  *
- * PARAMETERS:  Node           - An node whose object will be detached
+ * PARAMETERS:  Node           - A Namespace node whose object will be detached
  *
  * RETURN:      None.
  *
@@ -248,7 +252,7 @@ acpi_ns_detach_object (
  *
  * FUNCTION:    acpi_ns_get_attached_object
  *
- * PARAMETERS:  Node             - Parent Node to be examined
+ * PARAMETERS:  Node             - Namespace node
  *
  * RETURN:      Current value of the object field from the Node whose
  *              handle is passed
@@ -284,7 +288,7 @@ acpi_ns_get_attached_object (
  *
  * FUNCTION:    acpi_ns_get_secondary_object
  *
- * PARAMETERS:  Node             - Parent Node to be examined
+ * PARAMETERS:  Node             - Namespace node
  *
  * RETURN:      Current value of the object field from the Node whose
  *              handle is passed.
diff --git a/drivers/acpi/namespace/nssearch.c b/drivers/acpi/namespace/nssearch.c
--- a/drivers/acpi/namespace/nssearch.c
+++ b/drivers/acpi/namespace/nssearch.c
@@ -49,15 +49,24 @@
 #define _COMPONENT          ACPI_NAMESPACE
 	 ACPI_MODULE_NAME    ("nssearch")
 
+/* Local prototypes */
+
+static acpi_status
+acpi_ns_search_parent_tree (
+	u32                             target_name,
+	struct acpi_namespace_node      *node,
+	acpi_object_type                type,
+	struct acpi_namespace_node      **return_node);
+
 
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ns_search_node
  *
- * PARAMETERS:  *target_name        - Ascii ACPI name to search for
- *              *Node               - Starting node where search will begin
- *              Type                - Object type to match
- *              **return_node       - Where the matched Named obj is returned
+ * PARAMETERS:  target_name     - Ascii ACPI name to search for
+ *              Node            - Starting node where search will begin
+ *              Type            - Object type to match
+ *              return_node     - Where the matched Named obj is returned
  *
  * RETURN:      Status
  *
@@ -163,10 +172,10 @@ acpi_ns_search_node (
  *
  * FUNCTION:    acpi_ns_search_parent_tree
  *
- * PARAMETERS:  *target_name        - Ascii ACPI name to search for
- *              *Node               - Starting node where search will begin
- *              Type                - Object type to match
- *              **return_node       - Where the matched Node is returned
+ * PARAMETERS:  target_name     - Ascii ACPI name to search for
+ *              Node            - Starting node where search will begin
+ *              Type            - Object type to match
+ *              return_node     - Where the matched Node is returned
  *
  * RETURN:      Status
  *
@@ -257,12 +266,12 @@ acpi_ns_search_parent_tree (
  *
  * PARAMETERS:  target_name         - Ascii ACPI name to search for (4 chars)
  *              walk_state          - Current state of the walk
- *              *Node               - Starting node where search will begin
+ *              Node                - Starting node where search will begin
  *              interpreter_mode    - Add names only in ACPI_MODE_LOAD_PASS_x.
  *                                    Otherwise,search only.
  *              Type                - Object type to match
  *              Flags               - Flags describing the search restrictions
- *              **return_node       - Where the Node is returned
+ *              return_node         - Where the Node is returned
  *
  * RETURN:      Status
  *
diff --git a/drivers/acpi/namespace/nsutils.c b/drivers/acpi/namespace/nsutils.c
--- a/drivers/acpi/namespace/nsutils.c
+++ b/drivers/acpi/namespace/nsutils.c
@@ -51,6 +51,18 @@
 #define _COMPONENT          ACPI_NAMESPACE
 	 ACPI_MODULE_NAME    ("nsutils")
 
+/* Local prototypes */
+
+static u8
+acpi_ns_valid_path_separator (
+	char                            sep);
+
+#ifdef ACPI_OBSOLETE_FUNCTIONS
+acpi_name
+acpi_ns_find_parent_name (
+	struct acpi_namespace_node      *node_to_search);
+#endif
+
 
 /*******************************************************************************
  *
@@ -59,7 +71,8 @@
  * PARAMETERS:  module_name         - Caller's module name (for error output)
  *              line_number         - Caller's line number (for error output)
  *              component_id        - Caller's component ID (for error output)
- *              Message             - Error message to use on failure
+ *              internal_name       - Name or path of the namespace node
+ *              lookup_status       - Exception code from NS lookup
  *
  * RETURN:      None
  *
@@ -121,6 +134,9 @@ acpi_ns_report_error (
  *              line_number         - Caller's line number (for error output)
  *              component_id        - Caller's component ID (for error output)
  *              Message             - Error message to use on failure
+ *              prefix_node         - Prefix relative to the path
+ *              Path                - Path to the node
+ *              method_status       - Execution status
  *
  * RETURN:      None
  *
@@ -161,8 +177,8 @@ acpi_ns_report_method_error (
  *
  * FUNCTION:    acpi_ns_print_node_pathname
  *
- * PARAMETERS:  Node                - Object
- *              Msg                 - Prefix message
+ * PARAMETERS:  Node            - Object
+ *              Message         - Prefix message
  *
  * DESCRIPTION: Print an object's full namespace pathname
  *              Manages allocation/freeing of a pathname buffer
@@ -172,7 +188,7 @@ acpi_ns_report_method_error (
 void
 acpi_ns_print_node_pathname (
 	struct acpi_namespace_node      *node,
-	char                            *msg)
+	char                            *message)
 {
 	struct acpi_buffer              buffer;
 	acpi_status                     status;
@@ -189,8 +205,8 @@ acpi_ns_print_node_pathname (
 
 	status = acpi_ns_handle_to_pathname (node, &buffer);
 	if (ACPI_SUCCESS (status)) {
-		if (msg) {
-			acpi_os_printf ("%s ", msg);
+		if (message) {
+			acpi_os_printf ("%s ", message);
 		}
 
 		acpi_os_printf ("[%s] (Node %p)", (char *) buffer.pointer, node);
@@ -224,7 +240,7 @@ acpi_ns_valid_root_prefix (
  *
  * FUNCTION:    acpi_ns_valid_path_separator
  *
- * PARAMETERS:  Sep              - Character to be checked
+ * PARAMETERS:  Sep         - Character to be checked
  *
  * RETURN:      TRUE if a valid path separator
  *
@@ -232,7 +248,7 @@ acpi_ns_valid_root_prefix (
  *
  ******************************************************************************/
 
-u8
+static u8
 acpi_ns_valid_path_separator (
 	char                            sep)
 {
@@ -245,10 +261,12 @@ acpi_ns_valid_path_separator (
  *
  * FUNCTION:    acpi_ns_get_type
  *
- * PARAMETERS:  Handle              - Parent Node to be examined
+ * PARAMETERS:  Node        - Parent Node to be examined
  *
  * RETURN:      Type field from Node whose handle is passed
  *
+ * DESCRIPTION: Return the type of a Namespace node
+ *
  ******************************************************************************/
 
 acpi_object_type
@@ -271,11 +289,13 @@ acpi_ns_get_type (
  *
  * FUNCTION:    acpi_ns_local
  *
- * PARAMETERS:  Type            - A namespace object type
+ * PARAMETERS:  Type        - A namespace object type
  *
  * RETURN:      LOCAL if names must be found locally in objects of the
  *              passed type, 0 if enclosing scopes should be searched
  *
+ * DESCRIPTION: Returns scope rule for the given object type.
+ *
  ******************************************************************************/
 
 u32
@@ -303,7 +323,7 @@ acpi_ns_local (
  * PARAMETERS:  Info            - Info struct initialized with the
  *                                external name pointer.
  *
- * RETURN:      Status
+ * RETURN:      None
  *
  * DESCRIPTION: Calculate the length of the internal (AML) namestring
  *              corresponding to the external (ASL) namestring.
@@ -551,14 +571,16 @@ acpi_ns_internalize_name (
  *
  * FUNCTION:    acpi_ns_externalize_name
  *
- * PARAMETERS:  *internal_name         - Internal representation of name
- *              **converted_name       - Where to return the resulting
- *                                       external representation of name
+ * PARAMETERS:  internal_name_length - Lenth of the internal name below
+ *              internal_name       - Internal representation of name
+ *              converted_name_length - Where the length is returned
+ *              converted_name      - Where the resulting external name
+ *                                    is returned
  *
  * RETURN:      Status
  *
  * DESCRIPTION: Convert internal name (e.g. 5c 2f 02 5f 50 52 5f 43 50 55 30)
- *              to its external form (e.g. "\_PR_.CPU0")
+ *              to its external (printable) form (e.g. "\_PR_.CPU0")
  *
  ******************************************************************************/
 
@@ -717,8 +739,9 @@ acpi_ns_externalize_name (
  *
  * DESCRIPTION: Convert a namespace handle to a real Node
  *
- * Note: Real integer handles allow for more verification
- *       and keep all pointers within this subsystem.
+ * Note: Real integer handles would allow for more verification
+ *       and keep all pointers within this subsystem - however this introduces
+ *       more (and perhaps unnecessary) overhead.
  *
  ******************************************************************************/
 
@@ -775,7 +798,7 @@ acpi_ns_convert_entry_to_handle (
 	return ((acpi_handle) node);
 
 
-/* ---------------------------------------------------
+/* Example future implementation ---------------------
 
 	if (!Node)
 	{
@@ -801,12 +824,13 @@ acpi_ns_convert_entry_to_handle (
  *
  * RETURN:      none
  *
- * DESCRIPTION: free memory allocated for table storage.
+ * DESCRIPTION: free memory allocated for namespace and ACPI table storage.
  *
  ******************************************************************************/
 
 void
-acpi_ns_terminate (void)
+acpi_ns_terminate (
+	void)
 {
 	union acpi_operand_object       *obj_desc;
 
@@ -940,7 +964,6 @@ acpi_ns_get_node_by_path (
 	(void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
 
 cleanup:
-	/* Cleanup */
 	if (internal_path) {
 		ACPI_MEM_FREE (internal_path);
 	}
@@ -950,55 +973,6 @@ cleanup:
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_ns_find_parent_name
- *
- * PARAMETERS:  *child_node            - Named Obj whose name is to be found
- *
- * RETURN:      The ACPI name
- *
- * DESCRIPTION: Search for the given obj in its parent scope and return the
- *              name segment, or "????" if the parent name can't be found
- *              (which "should not happen").
- *
- ******************************************************************************/
-#ifdef ACPI_FUTURE_USAGE
-acpi_name
-acpi_ns_find_parent_name (
-	struct acpi_namespace_node      *child_node)
-{
-	struct acpi_namespace_node      *parent_node;
-
-
-	ACPI_FUNCTION_TRACE ("ns_find_parent_name");
-
-
-	if (child_node) {
-		/* Valid entry.  Get the parent Node */
-
-		parent_node = acpi_ns_get_parent_node (child_node);
-		if (parent_node) {
-			ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
-				"Parent of %p [%4.4s] is %p [%4.4s]\n",
-				child_node, acpi_ut_get_node_name (child_node),
-				parent_node, acpi_ut_get_node_name (parent_node)));
-
-			if (parent_node->name.integer) {
-				return_VALUE ((acpi_name) parent_node->name.integer);
-			}
-		}
-
-		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
-			"Unable to find parent of %p (%4.4s)\n",
-			child_node, acpi_ut_get_node_name (child_node)));
-	}
-
-	return_VALUE (ACPI_UNKNOWN_NAME);
-}
-#endif
-
-
-/*******************************************************************************
- *
  * FUNCTION:    acpi_ns_get_parent_node
  *
  * PARAMETERS:  Node       - Current table entry
@@ -1009,7 +983,6 @@ acpi_ns_find_parent_name (
  *
  ******************************************************************************/
 
-
 struct acpi_namespace_node *
 acpi_ns_get_parent_node (
 	struct acpi_namespace_node      *node)
@@ -1030,7 +1003,6 @@ acpi_ns_get_parent_node (
 		node = node->peer;
 	}
 
-
 	return (node->peer);
 }
 
@@ -1049,7 +1021,6 @@ acpi_ns_get_parent_node (
  *
  ******************************************************************************/
 
-
 struct acpi_namespace_node *
 acpi_ns_get_next_valid_node (
 	struct acpi_namespace_node      *node)
@@ -1067,3 +1038,53 @@ acpi_ns_get_next_valid_node (
 }
 
 
+#ifdef ACPI_OBSOLETE_FUNCTIONS
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_find_parent_name
+ *
+ * PARAMETERS:  *child_node            - Named Obj whose name is to be found
+ *
+ * RETURN:      The ACPI name
+ *
+ * DESCRIPTION: Search for the given obj in its parent scope and return the
+ *              name segment, or "????" if the parent name can't be found
+ *              (which "should not happen").
+ *
+ ******************************************************************************/
+
+acpi_name
+acpi_ns_find_parent_name (
+	struct acpi_namespace_node      *child_node)
+{
+	struct acpi_namespace_node      *parent_node;
+
+
+	ACPI_FUNCTION_TRACE ("ns_find_parent_name");
+
+
+	if (child_node) {
+		/* Valid entry.  Get the parent Node */
+
+		parent_node = acpi_ns_get_parent_node (child_node);
+		if (parent_node) {
+			ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+				"Parent of %p [%4.4s] is %p [%4.4s]\n",
+				child_node, acpi_ut_get_node_name (child_node),
+				parent_node, acpi_ut_get_node_name (parent_node)));
+
+			if (parent_node->name.integer) {
+				return_VALUE ((acpi_name) parent_node->name.integer);
+			}
+		}
+
+		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+			"Unable to find parent of %p (%4.4s)\n",
+			child_node, acpi_ut_get_node_name (child_node)));
+	}
+
+	return_VALUE (ACPI_UNKNOWN_NAME);
+}
+#endif
+
+
diff --git a/drivers/acpi/namespace/nswalk.c b/drivers/acpi/namespace/nswalk.c
--- a/drivers/acpi/namespace/nswalk.c
+++ b/drivers/acpi/namespace/nswalk.c
@@ -56,7 +56,7 @@
  *
  * PARAMETERS:  Type                - Type of node to be searched for
  *              parent_node         - Parent node whose children we are
- *                                     getting
+ *                                    getting
  *              child_node          - Previous child that was found.
  *                                    The NEXT child will be returned
  *
diff --git a/drivers/acpi/namespace/nsxfeval.c b/drivers/acpi/namespace/nsxfeval.c
--- a/drivers/acpi/namespace/nsxfeval.c
+++ b/drivers/acpi/namespace/nsxfeval.c
@@ -58,11 +58,11 @@
  * FUNCTION:    acpi_evaluate_object_typed
  *
  * PARAMETERS:  Handle              - Object handle (optional)
- *              *Pathname           - Object pathname (optional)
- *              **external_params   - List of parameters to pass to method,
+ *              Pathname            - Object pathname (optional)
+ *              external_params     - List of parameters to pass to method,
  *                                    terminated by NULL.  May be NULL
  *                                    if no parameters are being passed.
- *              *return_buffer      - Where to put method's return value (if
+ *              return_buffer       - Where to put method's return value (if
  *                                    any).  If NULL, no value is returned.
  *              return_type         - Expected type of return object
  *
@@ -73,6 +73,7 @@
  *              be valid (non-null)
  *
  ******************************************************************************/
+
 #ifdef ACPI_FUTURE_USAGE
 acpi_status
 acpi_evaluate_object_typed (
@@ -307,7 +308,8 @@ acpi_evaluate_object (
 				if (ACPI_SUCCESS (status)) {
 					/* Validate/Allocate/Clear caller buffer */
 
-					status = acpi_ut_initialize_buffer (return_buffer, buffer_space_needed);
+					status = acpi_ut_initialize_buffer (return_buffer,
+							  buffer_space_needed);
 					if (ACPI_FAILURE (status)) {
 						/*
 						 * Caller's buffer is too small or a new one can't be allocated
@@ -423,7 +425,8 @@ acpi_walk_namespace (
 		return_ACPI_STATUS (status);
 	}
 
-	status = acpi_ns_walk_namespace (type, start_object, max_depth, ACPI_NS_WALK_UNLOCK,
+	status = acpi_ns_walk_namespace (type, start_object, max_depth,
+			  ACPI_NS_WALK_UNLOCK,
 			  user_function, context, return_value);
 
 	(void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
@@ -525,7 +528,8 @@ acpi_ns_get_device_callback (
 		}
 	}
 
-	status = info->user_function (obj_handle, nesting_level, info->context, return_value);
+	status = info->user_function (obj_handle, nesting_level, info->context,
+			 return_value);
 	return (status);
 }
 
diff --git a/drivers/acpi/namespace/nsxfname.c b/drivers/acpi/namespace/nsxfname.c
--- a/drivers/acpi/namespace/nsxfname.c
+++ b/drivers/acpi/namespace/nsxfname.c
@@ -57,9 +57,9 @@
  * FUNCTION:    acpi_get_handle
  *
  * PARAMETERS:  Parent          - Object to search under (search scope).
- *              path_name       - Pointer to an asciiz string containing the
- *                                  name
- *              ret_handle      - Where the return handle is placed
+ *              Pathname        - Pointer to an asciiz string containing the
+ *                                name
+ *              ret_handle      - Where the return handle is returned
  *
  * RETURN:      Status
  *
@@ -220,7 +220,7 @@ EXPORT_SYMBOL(acpi_get_name);
  * FUNCTION:    acpi_get_object_info
  *
  * PARAMETERS:  Handle          - Object Handle
- *              Info            - Where the info is returned
+ *              Buffer          - Where the info is returned
  *
  * RETURN:      Status
  *
diff --git a/drivers/acpi/namespace/nsxfobj.c b/drivers/acpi/namespace/nsxfobj.c
--- a/drivers/acpi/namespace/nsxfobj.c
+++ b/drivers/acpi/namespace/nsxfobj.c
@@ -56,7 +56,7 @@
  * FUNCTION:    acpi_get_type
  *
  * PARAMETERS:  Handle          - Handle of object whose type is desired
- *              *ret_type       - Where the type will be placed
+ *              ret_type        - Where the type will be placed
  *
  * RETURN:      Status
  *
@@ -258,5 +258,5 @@ unlock_and_exit:
 	(void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
 	return (status);
 }
-EXPORT_SYMBOL(acpi_get_next_object);
 
+EXPORT_SYMBOL(acpi_get_next_object);
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -71,6 +71,9 @@ EXPORT_SYMBOL(acpi_in_debugger);
 extern char line_buf[80];
 #endif /*ENABLE_DEBUGGER*/
 
+int acpi_specific_hotkey_enabled = TRUE;
+EXPORT_SYMBOL(acpi_specific_hotkey_enabled);
+
 static unsigned int acpi_irq_irq;
 static acpi_osd_handler acpi_irq_handler;
 static void *acpi_irq_context;
@@ -142,10 +145,14 @@ acpi_os_vprintf(const char *fmt, va_list
 #endif
 }
 
+extern int acpi_in_resume;
 void *
 acpi_os_allocate(acpi_size size)
 {
-	return kmalloc(size, GFP_KERNEL);
+	if (acpi_in_resume)
+		return kmalloc(size, GFP_ATOMIC);
+	else
+		return kmalloc(size, GFP_KERNEL);
 }
 
 void
@@ -1152,6 +1159,15 @@ acpi_wake_gpes_always_on_setup(char *str
 
 __setup("acpi_wake_gpes_always_on", acpi_wake_gpes_always_on_setup);
 
+int __init
+acpi_hotkey_setup(char *str)
+{
+	acpi_specific_hotkey_enabled = FALSE;
+	return 1;
+}
+
+__setup("acpi_generic_hotkey", acpi_hotkey_setup);
+
 /*
  * max_cstate is defined in the base kernel so modules can
  * change it w/o depending on the state of the processor module.
diff --git a/drivers/acpi/parser/psargs.c b/drivers/acpi/parser/psargs.c
--- a/drivers/acpi/parser/psargs.c
+++ b/drivers/acpi/parser/psargs.c
@@ -50,6 +50,16 @@
 #define _COMPONENT          ACPI_PARSER
 	 ACPI_MODULE_NAME    ("psargs")
 
+/* Local prototypes */
+
+static u32
+acpi_ps_get_next_package_length (
+	struct acpi_parse_state         *parser_state);
+
+static union acpi_parse_object *
+acpi_ps_get_next_field (
+	struct acpi_parse_state         *parser_state);
+
 
 /*******************************************************************************
  *
@@ -64,7 +74,7 @@
  *
  ******************************************************************************/
 
-u32
+static u32
 acpi_ps_get_next_package_length (
 	struct acpi_parse_state         *parser_state)
 {
@@ -78,7 +88,6 @@ acpi_ps_get_next_package_length (
 	encoded_length = (u32) ACPI_GET8 (parser_state->aml);
 	parser_state->aml++;
 
-
 	switch (encoded_length >> 6) /* bits 6-7 contain encoding scheme */ {
 	case 0: /* 1-byte encoding (bits 0-5) */
 
@@ -287,13 +296,14 @@ acpi_ps_get_next_namepath (
 		 * parent tree, but don't open a new scope -- we just want to lookup the
 		 * object  (MUST BE mode EXECUTE to perform upsearch)
 		 */
-		status = acpi_ns_lookup (&scope_info, path, ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
-				 ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, NULL, &node);
+		status = acpi_ns_lookup (&scope_info, path, ACPI_TYPE_ANY,
+				 ACPI_IMODE_EXECUTE,
+				 ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
+				 NULL, &node);
 		if (ACPI_SUCCESS (status) && method_call) {
 			if (node->type == ACPI_TYPE_METHOD) {
-				/*
-				 * This name is actually a control method invocation
-				 */
+				/* This name is actually a control method invocation */
+
 				method_desc = acpi_ns_get_attached_object (node);
 				ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
 					"Control Method - %p Desc %p Path=%p\n",
@@ -360,7 +370,7 @@ acpi_ps_get_next_namepath (
 				/*
 				 * We got a NOT_FOUND during table load or we encountered
 				 * a cond_ref_of(x) where the target does not exist.
-				 * -- either case is ok
+				 * Either case is ok
 				 */
 				status = AE_OK;
 			}
@@ -486,12 +496,13 @@ acpi_ps_get_next_simple_arg (
  *
  ******************************************************************************/
 
-union acpi_parse_object *
+static union acpi_parse_object *
 acpi_ps_get_next_field (
 	struct acpi_parse_state         *parser_state)
 {
-	u32                             aml_offset = (u32) ACPI_PTR_DIFF (parser_state->aml,
-			 parser_state->aml_start);
+	u32                             aml_offset = (u32)
+			  ACPI_PTR_DIFF (parser_state->aml,
+					   parser_state->aml_start);
 	union acpi_parse_object         *field;
 	u16                             opcode;
 	u32                             name;
@@ -500,7 +511,7 @@ acpi_ps_get_next_field (
 	ACPI_FUNCTION_TRACE ("ps_get_next_field");
 
 
-	/* determine field type */
+	/* Determine field type */
 
 	switch (ACPI_GET8 (parser_state->aml)) {
 	default:
@@ -521,7 +532,6 @@ acpi_ps_get_next_field (
 		break;
 	}
 
-
 	/* Allocate a new field op */
 
 	field = acpi_ps_alloc_op (opcode);
@@ -582,10 +592,10 @@ acpi_ps_get_next_field (
  *
  * FUNCTION:    acpi_ps_get_next_arg
  *
- * PARAMETERS:  parser_state        - Current parser state object
+ * PARAMETERS:  walk_state          - Current state
+ *              parser_state        - Current parser state object
  *              arg_type            - The argument type (AML_*_ARG)
- *              arg_count           - If the argument points to a control method
- *                                    the method's argument is returned here.
+ *              return_arg          - Where the next arg is returned
  *
  * RETURN:      Status, and an op object containing the next argument.
  *
@@ -619,7 +629,7 @@ acpi_ps_get_next_arg (
 	case ARGP_NAME:
 	case ARGP_NAMESTRING:
 
-		/* constants, strings, and namestrings are all the same size */
+		/* Constants, strings, and namestrings are all the same size */
 
 		arg = acpi_ps_alloc_op (AML_BYTE_OP);
 		if (!arg) {
@@ -654,7 +664,6 @@ acpi_ps_get_next_arg (
 				else {
 					arg = field;
 				}
-
 				prev = field;
 			}
 
@@ -677,8 +686,8 @@ acpi_ps_get_next_arg (
 
 			/* Fill in bytelist data */
 
-			arg->common.value.size = (u32) ACPI_PTR_DIFF (parser_state->pkg_end,
-					  parser_state->aml);
+			arg->common.value.size = (u32)
+				ACPI_PTR_DIFF (parser_state->pkg_end, parser_state->aml);
 			arg->named.data = parser_state->aml;
 
 			/* Skip to End of byte data */
@@ -706,7 +715,7 @@ acpi_ps_get_next_arg (
 			status = acpi_ps_get_next_namepath (walk_state, parser_state, arg, 0);
 		}
 		else {
-			/* single complex argument, nothing returned */
+			/* Single complex argument, nothing returned */
 
 			walk_state->arg_count = 1;
 		}
@@ -716,7 +725,7 @@ acpi_ps_get_next_arg (
 	case ARGP_DATAOBJ:
 	case ARGP_TERMARG:
 
-		/* single complex argument, nothing returned */
+		/* Single complex argument, nothing returned */
 
 		walk_state->arg_count = 1;
 		break;
@@ -727,7 +736,7 @@ acpi_ps_get_next_arg (
 	case ARGP_OBJLIST:
 
 		if (parser_state->aml < parser_state->pkg_end) {
-			/* non-empty list of variable arguments, nothing returned */
+			/* Non-empty list of variable arguments, nothing returned */
 
 			walk_state->arg_count = ACPI_VAR_ARGS;
 		}
diff --git a/drivers/acpi/parser/psopcode.c b/drivers/acpi/parser/psopcode.c
--- a/drivers/acpi/parser/psopcode.c
+++ b/drivers/acpi/parser/psopcode.c
@@ -44,6 +44,7 @@
 
 #include <acpi/acpi.h>
 #include <acpi/acparser.h>
+#include <acpi/acopcode.h>
 #include <acpi/amlcode.h>
 
 
@@ -51,23 +52,6 @@
 	 ACPI_MODULE_NAME    ("psopcode")
 
 
-#define _UNK                        0x6B
-/*
- * Reserved ASCII characters.  Do not use any of these for
- * internal opcodes, since they are used to differentiate
- * name strings from AML opcodes
- */
-#define _ASC                        0x6C
-#define _NAM                        0x6C
-#define _PFX                        0x6D
-#define _UNKNOWN_OPCODE             0x02    /* An example unknown opcode */
-
-#define MAX_EXTENDED_OPCODE         0x88
-#define NUM_EXTENDED_OPCODE         (MAX_EXTENDED_OPCODE + 1)
-#define MAX_INTERNAL_OPCODE
-#define NUM_INTERNAL_OPCODE         (MAX_INTERNAL_OPCODE + 1)
-
-
 /*******************************************************************************
  *
  * NAME:        acpi_gbl_aml_op_info
@@ -79,274 +63,9 @@
  *
  ******************************************************************************/
 
-
-/*
- * All AML opcodes and the parse-time arguments for each.  Used by the AML parser  Each list is compressed
- * into a 32-bit number and stored in the master opcode table at the end of this file.
- */
-
-
-#define ARGP_ACCESSFIELD_OP             ARGP_LIST1 (ARGP_NAMESTRING)
-#define ARGP_ACQUIRE_OP                 ARGP_LIST2 (ARGP_SUPERNAME,  ARGP_WORDDATA)
-#define ARGP_ADD_OP                     ARGP_LIST3 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_TARGET)
-#define ARGP_ALIAS_OP                   ARGP_LIST2 (ARGP_NAMESTRING, ARGP_NAME)
-#define ARGP_ARG0                       ARG_NONE
-#define ARGP_ARG1                       ARG_NONE
-#define ARGP_ARG2                       ARG_NONE
-#define ARGP_ARG3                       ARG_NONE
-#define ARGP_ARG4                       ARG_NONE
-#define ARGP_ARG5                       ARG_NONE
-#define ARGP_ARG6                       ARG_NONE
-#define ARGP_BANK_FIELD_OP              ARGP_LIST6 (ARGP_PKGLENGTH,  ARGP_NAMESTRING,    ARGP_NAMESTRING,ARGP_TERMARG,   ARGP_BYTEDATA,  ARGP_FIELDLIST)
-#define ARGP_BIT_AND_OP                 ARGP_LIST3 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_TARGET)
-#define ARGP_BIT_NAND_OP                ARGP_LIST3 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_TARGET)
-#define ARGP_BIT_NOR_OP                 ARGP_LIST3 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_TARGET)
-#define ARGP_BIT_NOT_OP                 ARGP_LIST2 (ARGP_TERMARG,    ARGP_TARGET)
-#define ARGP_BIT_OR_OP                  ARGP_LIST3 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_TARGET)
-#define ARGP_BIT_XOR_OP                 ARGP_LIST3 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_TARGET)
-#define ARGP_BREAK_OP                   ARG_NONE
-#define ARGP_BREAK_POINT_OP             ARG_NONE
-#define ARGP_BUFFER_OP                  ARGP_LIST3 (ARGP_PKGLENGTH,  ARGP_TERMARG,       ARGP_BYTELIST)
-#define ARGP_BYTE_OP                    ARGP_LIST1 (ARGP_BYTEDATA)
-#define ARGP_BYTELIST_OP                ARGP_LIST1 (ARGP_NAMESTRING)
-#define ARGP_CONCAT_OP                  ARGP_LIST3 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_TARGET)
-#define ARGP_CONCAT_RES_OP              ARGP_LIST3 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_TARGET)
-#define ARGP_COND_REF_OF_OP             ARGP_LIST2 (ARGP_SUPERNAME,  ARGP_SUPERNAME)
-#define ARGP_CONTINUE_OP                ARG_NONE
-#define ARGP_COPY_OP                    ARGP_LIST2 (ARGP_SUPERNAME,  ARGP_SIMPLENAME)
-#define ARGP_CREATE_BIT_FIELD_OP        ARGP_LIST3 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_NAME)
-#define ARGP_CREATE_BYTE_FIELD_OP       ARGP_LIST3 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_NAME)
-#define ARGP_CREATE_DWORD_FIELD_OP      ARGP_LIST3 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_NAME)
-#define ARGP_CREATE_FIELD_OP            ARGP_LIST4 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_TERMARG,   ARGP_NAME)
-#define ARGP_CREATE_QWORD_FIELD_OP      ARGP_LIST3 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_NAME)
-#define ARGP_CREATE_WORD_FIELD_OP       ARGP_LIST3 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_NAME)
-#define ARGP_DATA_REGION_OP             ARGP_LIST4 (ARGP_NAME,       ARGP_TERMARG,       ARGP_TERMARG,   ARGP_TERMARG)
-#define ARGP_DEBUG_OP                   ARG_NONE
-#define ARGP_DECREMENT_OP               ARGP_LIST1 (ARGP_SUPERNAME)
-#define ARGP_DEREF_OF_OP                ARGP_LIST1 (ARGP_TERMARG)
-#define ARGP_DEVICE_OP                  ARGP_LIST3 (ARGP_PKGLENGTH,  ARGP_NAME,          ARGP_OBJLIST)
-#define ARGP_DIVIDE_OP                  ARGP_LIST4 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_TARGET,    ARGP_TARGET)
-#define ARGP_DWORD_OP                   ARGP_LIST1 (ARGP_DWORDDATA)
-#define ARGP_ELSE_OP                    ARGP_LIST2 (ARGP_PKGLENGTH,  ARGP_TERMLIST)
-#define ARGP_EVENT_OP                   ARGP_LIST1 (ARGP_NAME)
-#define ARGP_FATAL_OP                   ARGP_LIST3 (ARGP_BYTEDATA,   ARGP_DWORDDATA,     ARGP_TERMARG)
-#define ARGP_FIELD_OP                   ARGP_LIST4 (ARGP_PKGLENGTH,  ARGP_NAMESTRING,    ARGP_BYTEDATA,  ARGP_FIELDLIST)
-#define ARGP_FIND_SET_LEFT_BIT_OP       ARGP_LIST2 (ARGP_TERMARG,    ARGP_TARGET)
-#define ARGP_FIND_SET_RIGHT_BIT_OP      ARGP_LIST2 (ARGP_TERMARG,    ARGP_TARGET)
-#define ARGP_FROM_BCD_OP                ARGP_LIST2 (ARGP_TERMARG,    ARGP_TARGET)
-#define ARGP_IF_OP                      ARGP_LIST3 (ARGP_PKGLENGTH,  ARGP_TERMARG,       ARGP_TERMLIST)
-#define ARGP_INCREMENT_OP               ARGP_LIST1 (ARGP_SUPERNAME)
-#define ARGP_INDEX_FIELD_OP             ARGP_LIST5 (ARGP_PKGLENGTH,  ARGP_NAMESTRING,    ARGP_NAMESTRING,ARGP_BYTEDATA,  ARGP_FIELDLIST)
-#define ARGP_INDEX_OP                   ARGP_LIST3 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_TARGET)
-#define ARGP_LAND_OP                    ARGP_LIST2 (ARGP_TERMARG,    ARGP_TERMARG)
-#define ARGP_LEQUAL_OP                  ARGP_LIST2 (ARGP_TERMARG,    ARGP_TERMARG)
-#define ARGP_LGREATER_OP                ARGP_LIST2 (ARGP_TERMARG,    ARGP_TERMARG)
-#define ARGP_LGREATEREQUAL_OP           ARGP_LIST2 (ARGP_TERMARG,    ARGP_TERMARG)
-#define ARGP_LLESS_OP                   ARGP_LIST2 (ARGP_TERMARG,    ARGP_TERMARG)
-#define ARGP_LLESSEQUAL_OP              ARGP_LIST2 (ARGP_TERMARG,    ARGP_TERMARG)
-#define ARGP_LNOT_OP                    ARGP_LIST1 (ARGP_TERMARG)
-#define ARGP_LNOTEQUAL_OP               ARGP_LIST2 (ARGP_TERMARG,    ARGP_TERMARG)
-#define ARGP_LOAD_OP                    ARGP_LIST2 (ARGP_NAMESTRING, ARGP_SUPERNAME)
-#define ARGP_LOAD_TABLE_OP              ARGP_LIST6 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_TERMARG,   ARGP_TERMARG,  ARGP_TERMARG,   ARGP_TERMARG)
-#define ARGP_LOCAL0                     ARG_NONE
-#define ARGP_LOCAL1                     ARG_NONE
-#define ARGP_LOCAL2                     ARG_NONE
-#define ARGP_LOCAL3                     ARG_NONE
-#define ARGP_LOCAL4                     ARG_NONE
-#define ARGP_LOCAL5                     ARG_NONE
-#define ARGP_LOCAL6                     ARG_NONE
-#define ARGP_LOCAL7                     ARG_NONE
-#define ARGP_LOR_OP                     ARGP_LIST2 (ARGP_TERMARG,    ARGP_TERMARG)
-#define ARGP_MATCH_OP                   ARGP_LIST6 (ARGP_TERMARG,    ARGP_BYTEDATA,      ARGP_TERMARG,   ARGP_BYTEDATA,  ARGP_TERMARG,   ARGP_TERMARG)
-#define ARGP_METHOD_OP                  ARGP_LIST4 (ARGP_PKGLENGTH,  ARGP_NAME,          ARGP_BYTEDATA,  ARGP_TERMLIST)
-#define ARGP_METHODCALL_OP              ARGP_LIST1 (ARGP_NAMESTRING)
-#define ARGP_MID_OP                     ARGP_LIST4 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_TERMARG,   ARGP_TARGET)
-#define ARGP_MOD_OP                     ARGP_LIST3 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_TARGET)
-#define ARGP_MULTIPLY_OP                ARGP_LIST3 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_TARGET)
-#define ARGP_MUTEX_OP                   ARGP_LIST2 (ARGP_NAME,       ARGP_BYTEDATA)
-#define ARGP_NAME_OP                    ARGP_LIST2 (ARGP_NAME,       ARGP_DATAOBJ)
-#define ARGP_NAMEDFIELD_OP              ARGP_LIST1 (ARGP_NAMESTRING)
-#define ARGP_NAMEPATH_OP                ARGP_LIST1 (ARGP_NAMESTRING)
-#define ARGP_NOOP_OP                    ARG_NONE
-#define ARGP_NOTIFY_OP                  ARGP_LIST2 (ARGP_SUPERNAME,  ARGP_TERMARG)
-#define ARGP_ONE_OP                     ARG_NONE
-#define ARGP_ONES_OP                    ARG_NONE
-#define ARGP_PACKAGE_OP                 ARGP_LIST3 (ARGP_PKGLENGTH,  ARGP_BYTEDATA,      ARGP_DATAOBJLIST)
-#define ARGP_POWER_RES_OP               ARGP_LIST5 (ARGP_PKGLENGTH,  ARGP_NAME,          ARGP_BYTEDATA,  ARGP_WORDDATA,  ARGP_OBJLIST)
-#define ARGP_PROCESSOR_OP               ARGP_LIST6 (ARGP_PKGLENGTH,  ARGP_NAME,          ARGP_BYTEDATA,  ARGP_DWORDDATA, ARGP_BYTEDATA,  ARGP_OBJLIST)
-#define ARGP_QWORD_OP                   ARGP_LIST1 (ARGP_QWORDDATA)
-#define ARGP_REF_OF_OP                  ARGP_LIST1 (ARGP_SUPERNAME)
-#define ARGP_REGION_OP                  ARGP_LIST4 (ARGP_NAME,       ARGP_BYTEDATA,      ARGP_TERMARG,   ARGP_TERMARG)
-#define ARGP_RELEASE_OP                 ARGP_LIST1 (ARGP_SUPERNAME)
-#define ARGP_RESERVEDFIELD_OP           ARGP_LIST1 (ARGP_NAMESTRING)
-#define ARGP_RESET_OP                   ARGP_LIST1 (ARGP_SUPERNAME)
-#define ARGP_RETURN_OP                  ARGP_LIST1 (ARGP_TERMARG)
-#define ARGP_REVISION_OP                ARG_NONE
-#define ARGP_SCOPE_OP                   ARGP_LIST3 (ARGP_PKGLENGTH,  ARGP_NAME,          ARGP_TERMLIST)
-#define ARGP_SHIFT_LEFT_OP              ARGP_LIST3 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_TARGET)
-#define ARGP_SHIFT_RIGHT_OP             ARGP_LIST3 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_TARGET)
-#define ARGP_SIGNAL_OP                  ARGP_LIST1 (ARGP_SUPERNAME)
-#define ARGP_SIZE_OF_OP                 ARGP_LIST1 (ARGP_SUPERNAME)
-#define ARGP_SLEEP_OP                   ARGP_LIST1 (ARGP_TERMARG)
-#define ARGP_STALL_OP                   ARGP_LIST1 (ARGP_TERMARG)
-#define ARGP_STATICSTRING_OP            ARGP_LIST1 (ARGP_NAMESTRING)
-#define ARGP_STORE_OP                   ARGP_LIST2 (ARGP_TERMARG,    ARGP_SUPERNAME)
-#define ARGP_STRING_OP                  ARGP_LIST1 (ARGP_CHARLIST)
-#define ARGP_SUBTRACT_OP                ARGP_LIST3 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_TARGET)
-#define ARGP_THERMAL_ZONE_OP            ARGP_LIST3 (ARGP_PKGLENGTH,  ARGP_NAME,          ARGP_OBJLIST)
-#define ARGP_TIMER_OP                   ARG_NONE
-#define ARGP_TO_BCD_OP                  ARGP_LIST2 (ARGP_TERMARG,    ARGP_TARGET)
-#define ARGP_TO_BUFFER_OP               ARGP_LIST2 (ARGP_TERMARG,    ARGP_TARGET)
-#define ARGP_TO_DEC_STR_OP              ARGP_LIST2 (ARGP_TERMARG,    ARGP_TARGET)
-#define ARGP_TO_HEX_STR_OP              ARGP_LIST2 (ARGP_TERMARG,    ARGP_TARGET)
-#define ARGP_TO_INTEGER_OP              ARGP_LIST2 (ARGP_TERMARG,    ARGP_TARGET)
-#define ARGP_TO_STRING_OP               ARGP_LIST3 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_TARGET)
-#define ARGP_TYPE_OP                    ARGP_LIST1 (ARGP_SUPERNAME)
-#define ARGP_UNLOAD_OP                  ARGP_LIST1 (ARGP_SUPERNAME)
-#define ARGP_VAR_PACKAGE_OP             ARGP_LIST3 (ARGP_PKGLENGTH,  ARGP_TERMARG,       ARGP_DATAOBJLIST)
-#define ARGP_WAIT_OP                    ARGP_LIST2 (ARGP_SUPERNAME,  ARGP_TERMARG)
-#define ARGP_WHILE_OP                   ARGP_LIST3 (ARGP_PKGLENGTH,  ARGP_TERMARG,       ARGP_TERMLIST)
-#define ARGP_WORD_OP                    ARGP_LIST1 (ARGP_WORDDATA)
-#define ARGP_ZERO_OP                    ARG_NONE
-
-
-/*
- * All AML opcodes and the runtime arguments for each.  Used by the AML interpreter  Each list is compressed
- * into a 32-bit number and stored in the master opcode table at the end of this file.
- *
- * (Used by prep_operands procedure and the ASL Compiler)
- */
-
-
-#define ARGI_ACCESSFIELD_OP             ARGI_INVALID_OPCODE
-#define ARGI_ACQUIRE_OP                 ARGI_LIST2 (ARGI_MUTEX,      ARGI_INTEGER)
-#define ARGI_ADD_OP                     ARGI_LIST3 (ARGI_INTEGER,    ARGI_INTEGER,       ARGI_TARGETREF)
-#define ARGI_ALIAS_OP                   ARGI_INVALID_OPCODE
-#define ARGI_ARG0                       ARG_NONE
-#define ARGI_ARG1                       ARG_NONE
-#define ARGI_ARG2                       ARG_NONE
-#define ARGI_ARG3                       ARG_NONE
-#define ARGI_ARG4                       ARG_NONE
-#define ARGI_ARG5                       ARG_NONE
-#define ARGI_ARG6                       ARG_NONE
-#define ARGI_BANK_FIELD_OP              ARGI_INVALID_OPCODE
-#define ARGI_BIT_AND_OP                 ARGI_LIST3 (ARGI_INTEGER,    ARGI_INTEGER,       ARGI_TARGETREF)
-#define ARGI_BIT_NAND_OP                ARGI_LIST3 (ARGI_INTEGER,    ARGI_INTEGER,       ARGI_TARGETREF)
-#define ARGI_BIT_NOR_OP                 ARGI_LIST3 (ARGI_INTEGER,    ARGI_INTEGER,       ARGI_TARGETREF)
-#define ARGI_BIT_NOT_OP                 ARGI_LIST2 (ARGI_INTEGER,    ARGI_TARGETREF)
-#define ARGI_BIT_OR_OP                  ARGI_LIST3 (ARGI_INTEGER,    ARGI_INTEGER,       ARGI_TARGETREF)
-#define ARGI_BIT_XOR_OP                 ARGI_LIST3 (ARGI_INTEGER,    ARGI_INTEGER,       ARGI_TARGETREF)
-#define ARGI_BREAK_OP                   ARG_NONE
-#define ARGI_BREAK_POINT_OP             ARG_NONE
-#define ARGI_BUFFER_OP                  ARGI_LIST1 (ARGI_INTEGER)
-#define ARGI_BYTE_OP                    ARGI_INVALID_OPCODE
-#define ARGI_BYTELIST_OP                ARGI_INVALID_OPCODE
-#define ARGI_CONCAT_OP                  ARGI_LIST3 (ARGI_COMPUTEDATA,ARGI_COMPUTEDATA,   ARGI_TARGETREF)
-#define ARGI_CONCAT_RES_OP              ARGI_LIST3 (ARGI_BUFFER,     ARGI_BUFFER,        ARGI_TARGETREF)
-#define ARGI_COND_REF_OF_OP             ARGI_LIST2 (ARGI_OBJECT_REF, ARGI_TARGETREF)
-#define ARGI_CONTINUE_OP                ARGI_INVALID_OPCODE
-#define ARGI_COPY_OP                    ARGI_LIST2 (ARGI_ANYTYPE,    ARGI_SIMPLE_TARGET)
-#define ARGI_CREATE_BIT_FIELD_OP        ARGI_LIST3 (ARGI_BUFFER,     ARGI_INTEGER,       ARGI_REFERENCE)
-#define ARGI_CREATE_BYTE_FIELD_OP       ARGI_LIST3 (ARGI_BUFFER,     ARGI_INTEGER,       ARGI_REFERENCE)
-#define ARGI_CREATE_DWORD_FIELD_OP      ARGI_LIST3 (ARGI_BUFFER,     ARGI_INTEGER,       ARGI_REFERENCE)
-#define ARGI_CREATE_FIELD_OP            ARGI_LIST4 (ARGI_BUFFER,     ARGI_INTEGER,       ARGI_INTEGER,      ARGI_REFERENCE)
-#define ARGI_CREATE_QWORD_FIELD_OP      ARGI_LIST3 (ARGI_BUFFER,     ARGI_INTEGER,       ARGI_REFERENCE)
-#define ARGI_CREATE_WORD_FIELD_OP       ARGI_LIST3 (ARGI_BUFFER,     ARGI_INTEGER,       ARGI_REFERENCE)
-#define ARGI_DATA_REGION_OP             ARGI_LIST3 (ARGI_STRING,     ARGI_STRING,        ARGI_STRING)
-#define ARGI_DEBUG_OP                   ARG_NONE
-#define ARGI_DECREMENT_OP               ARGI_LIST1 (ARGI_INTEGER_REF)
-#define ARGI_DEREF_OF_OP                ARGI_LIST1 (ARGI_REF_OR_STRING)
-#define ARGI_DEVICE_OP                  ARGI_INVALID_OPCODE
-#define ARGI_DIVIDE_OP                  ARGI_LIST4 (ARGI_INTEGER,    ARGI_INTEGER,       ARGI_TARGETREF,    ARGI_TARGETREF)
-#define ARGI_DWORD_OP                   ARGI_INVALID_OPCODE
-#define ARGI_ELSE_OP                    ARGI_INVALID_OPCODE
-#define ARGI_EVENT_OP                   ARGI_INVALID_OPCODE
-#define ARGI_FATAL_OP                   ARGI_LIST3 (ARGI_INTEGER,    ARGI_INTEGER,       ARGI_INTEGER)
-#define ARGI_FIELD_OP                   ARGI_INVALID_OPCODE
-#define ARGI_FIND_SET_LEFT_BIT_OP       ARGI_LIST2 (ARGI_INTEGER,    ARGI_TARGETREF)
-#define ARGI_FIND_SET_RIGHT_BIT_OP      ARGI_LIST2 (ARGI_INTEGER,    ARGI_TARGETREF)
-#define ARGI_FROM_BCD_OP                ARGI_LIST2 (ARGI_INTEGER,    ARGI_TARGETREF)
-#define ARGI_IF_OP                      ARGI_INVALID_OPCODE
-#define ARGI_INCREMENT_OP               ARGI_LIST1 (ARGI_INTEGER_REF)
-#define ARGI_INDEX_FIELD_OP             ARGI_INVALID_OPCODE
-#define ARGI_INDEX_OP                   ARGI_LIST3 (ARGI_COMPLEXOBJ, ARGI_INTEGER,       ARGI_TARGETREF)
-#define ARGI_LAND_OP                    ARGI_LIST2 (ARGI_INTEGER,    ARGI_INTEGER)
-#define ARGI_LEQUAL_OP                  ARGI_LIST2 (ARGI_COMPUTEDATA,ARGI_COMPUTEDATA)
-#define ARGI_LGREATER_OP                ARGI_LIST2 (ARGI_COMPUTEDATA,ARGI_COMPUTEDATA)
-#define ARGI_LGREATEREQUAL_OP           ARGI_INVALID_OPCODE
-#define ARGI_LLESS_OP                   ARGI_LIST2 (ARGI_COMPUTEDATA,ARGI_COMPUTEDATA)
-#define ARGI_LLESSEQUAL_OP              ARGI_INVALID_OPCODE
-#define ARGI_LNOT_OP                    ARGI_LIST1 (ARGI_INTEGER)
-#define ARGI_LNOTEQUAL_OP               ARGI_INVALID_OPCODE
-#define ARGI_LOAD_OP                    ARGI_LIST2 (ARGI_REGION_OR_FIELD,ARGI_TARGETREF)
-#define ARGI_LOAD_TABLE_OP              ARGI_LIST6 (ARGI_STRING,     ARGI_STRING,        ARGI_STRING,       ARGI_STRING,    ARGI_STRING, ARGI_ANYTYPE)
-#define ARGI_LOCAL0                     ARG_NONE
-#define ARGI_LOCAL1                     ARG_NONE
-#define ARGI_LOCAL2                     ARG_NONE
-#define ARGI_LOCAL3                     ARG_NONE
-#define ARGI_LOCAL4                     ARG_NONE
-#define ARGI_LOCAL5                     ARG_NONE
-#define ARGI_LOCAL6                     ARG_NONE
-#define ARGI_LOCAL7                     ARG_NONE
-#define ARGI_LOR_OP                     ARGI_LIST2 (ARGI_INTEGER,    ARGI_INTEGER)
-#define ARGI_MATCH_OP                   ARGI_LIST6 (ARGI_PACKAGE,    ARGI_INTEGER,   ARGI_COMPUTEDATA,      ARGI_INTEGER,ARGI_COMPUTEDATA,ARGI_INTEGER)
-#define ARGI_METHOD_OP                  ARGI_INVALID_OPCODE
-#define ARGI_METHODCALL_OP              ARGI_INVALID_OPCODE
-#define ARGI_MID_OP                     ARGI_LIST4 (ARGI_BUFFER_OR_STRING,ARGI_INTEGER,  ARGI_INTEGER,      ARGI_TARGETREF)
-#define ARGI_MOD_OP                     ARGI_LIST3 (ARGI_INTEGER,    ARGI_INTEGER,       ARGI_TARGETREF)
-#define ARGI_MULTIPLY_OP                ARGI_LIST3 (ARGI_INTEGER,    ARGI_INTEGER,       ARGI_TARGETREF)
-#define ARGI_MUTEX_OP                   ARGI_INVALID_OPCODE
-#define ARGI_NAME_OP                    ARGI_INVALID_OPCODE
-#define ARGI_NAMEDFIELD_OP              ARGI_INVALID_OPCODE
-#define ARGI_NAMEPATH_OP                ARGI_INVALID_OPCODE
-#define ARGI_NOOP_OP                    ARG_NONE
-#define ARGI_NOTIFY_OP                  ARGI_LIST2 (ARGI_DEVICE_REF, ARGI_INTEGER)
-#define ARGI_ONE_OP                     ARG_NONE
-#define ARGI_ONES_OP                    ARG_NONE
-#define ARGI_PACKAGE_OP                 ARGI_LIST1 (ARGI_INTEGER)
-#define ARGI_POWER_RES_OP               ARGI_INVALID_OPCODE
-#define ARGI_PROCESSOR_OP               ARGI_INVALID_OPCODE
-#define ARGI_QWORD_OP                   ARGI_INVALID_OPCODE
-#define ARGI_REF_OF_OP                  ARGI_LIST1 (ARGI_OBJECT_REF)
-#define ARGI_REGION_OP                  ARGI_LIST2 (ARGI_INTEGER,    ARGI_INTEGER)
-#define ARGI_RELEASE_OP                 ARGI_LIST1 (ARGI_MUTEX)
-#define ARGI_RESERVEDFIELD_OP           ARGI_INVALID_OPCODE
-#define ARGI_RESET_OP                   ARGI_LIST1 (ARGI_EVENT)
-#define ARGI_RETURN_OP                  ARGI_INVALID_OPCODE
-#define ARGI_REVISION_OP                ARG_NONE
-#define ARGI_SCOPE_OP                   ARGI_INVALID_OPCODE
-#define ARGI_SHIFT_LEFT_OP              ARGI_LIST3 (ARGI_INTEGER,    ARGI_INTEGER,       ARGI_TARGETREF)
-#define ARGI_SHIFT_RIGHT_OP             ARGI_LIST3 (ARGI_INTEGER,    ARGI_INTEGER,       ARGI_TARGETREF)
-#define ARGI_SIGNAL_OP                  ARGI_LIST1 (ARGI_EVENT)
-#define ARGI_SIZE_OF_OP                 ARGI_LIST1 (ARGI_DATAOBJECT)
-#define ARGI_SLEEP_OP                   ARGI_LIST1 (ARGI_INTEGER)
-#define ARGI_STALL_OP                   ARGI_LIST1 (ARGI_INTEGER)
-#define ARGI_STATICSTRING_OP            ARGI_INVALID_OPCODE
-#define ARGI_STORE_OP                   ARGI_LIST2 (ARGI_DATAREFOBJ, ARGI_TARGETREF)
-#define ARGI_STRING_OP                  ARGI_INVALID_OPCODE
-#define ARGI_SUBTRACT_OP                ARGI_LIST3 (ARGI_INTEGER,    ARGI_INTEGER,       ARGI_TARGETREF)
-#define ARGI_THERMAL_ZONE_OP            ARGI_INVALID_OPCODE
-#define ARGI_TIMER_OP                   ARG_NONE
-#define ARGI_TO_BCD_OP                  ARGI_LIST2 (ARGI_INTEGER,    ARGI_FIXED_TARGET)
-#define ARGI_TO_BUFFER_OP               ARGI_LIST2 (ARGI_COMPUTEDATA,ARGI_FIXED_TARGET)
-#define ARGI_TO_DEC_STR_OP              ARGI_LIST2 (ARGI_COMPUTEDATA,ARGI_FIXED_TARGET)
-#define ARGI_TO_HEX_STR_OP              ARGI_LIST2 (ARGI_COMPUTEDATA,ARGI_FIXED_TARGET)
-#define ARGI_TO_INTEGER_OP              ARGI_LIST2 (ARGI_COMPUTEDATA,ARGI_FIXED_TARGET)
-#define ARGI_TO_STRING_OP               ARGI_LIST3 (ARGI_BUFFER,     ARGI_INTEGER,       ARGI_FIXED_TARGET)
-#define ARGI_TYPE_OP                    ARGI_LIST1 (ARGI_ANYTYPE)
-#define ARGI_UNLOAD_OP                  ARGI_LIST1 (ARGI_DDBHANDLE)
-#define ARGI_VAR_PACKAGE_OP             ARGI_LIST1 (ARGI_INTEGER)
-#define ARGI_WAIT_OP                    ARGI_LIST2 (ARGI_EVENT,      ARGI_INTEGER)
-#define ARGI_WHILE_OP                   ARGI_INVALID_OPCODE
-#define ARGI_WORD_OP                    ARGI_INVALID_OPCODE
-#define ARGI_ZERO_OP                    ARG_NONE
-
-
 /*
  * Summary of opcode types/flags
- */
-
-/******************************************************************************
+ *
 
  Opcodes that have associated namespace objects (AML_NSOBJECT flag)
 
@@ -460,14 +179,13 @@
 	AML_CREATE_DWORD_FIELD_OP
 	AML_CREATE_QWORD_FIELD_OP
 
-******************************************************************************/
+ ******************************************************************************/
 
 
 /*
- * Master Opcode information table.  A summary of everything we know about each opcode, all in one place.
+ * Master Opcode information table.  A summary of everything we know about each
+ * opcode, all in one place.
  */
-
-
 const struct acpi_opcode_info     acpi_gbl_aml_op_info[AML_NUM_OPCODES] =
 {
 /*! [Begin] no source code translation */
@@ -693,8 +411,7 @@ static const u8 acpi_gbl_long_op_index[N
  *
  * PARAMETERS:  Opcode              - The AML opcode
  *
- * RETURN:      A pointer to the info about the opcode.  NULL if the opcode was
- *              not found in the table.
+ * RETURN:      A pointer to the info about the opcode.
  *
  * DESCRIPTION: Find AML opcode description based on the opcode.
  *              NOTE: This procedure must ALWAYS return a valid pointer!
@@ -731,7 +448,8 @@ acpi_ps_get_opcode_info (
 
 	default:
 
-		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown AML opcode [%4.4X]\n", opcode));
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"Unknown AML opcode [%4.4X]\n", opcode));
 		break;
 	}
 
diff --git a/drivers/acpi/parser/psparse.c b/drivers/acpi/parser/psparse.c
--- a/drivers/acpi/parser/psparse.c
+++ b/drivers/acpi/parser/psparse.c
@@ -64,6 +64,23 @@
 
 static u32                          acpi_gbl_depth = 0;
 
+/* Local prototypes */
+
+static void
+acpi_ps_complete_this_op (
+	struct acpi_walk_state          *walk_state,
+	union acpi_parse_object         *op);
+
+static acpi_status
+acpi_ps_next_parse_state (
+	struct acpi_walk_state          *walk_state,
+	union acpi_parse_object         *op,
+	acpi_status                     callback_status);
+
+static acpi_status
+acpi_ps_parse_loop (
+	struct acpi_walk_state          *walk_state);
+
 
 /*******************************************************************************
  *
@@ -100,7 +117,7 @@ acpi_ps_get_opcode_size (
  *
  * PARAMETERS:  parser_state        - A parser state object
  *
- * RETURN:      Status
+ * RETURN:      Next AML opcode
  *
  * DESCRIPTION: Get next AML opcode (without incrementing AML pointer)
  *
@@ -117,7 +134,6 @@ acpi_ps_peek_opcode (
 	aml = parser_state->aml;
 	opcode = (u16) ACPI_GET8 (aml);
 
-
 	if (opcode == AML_EXTOP) {
 		/* Extended opcode */
 
@@ -142,7 +158,7 @@ acpi_ps_peek_opcode (
  *
  ******************************************************************************/
 
-void
+static void
 acpi_ps_complete_this_op (
 	struct acpi_walk_state          *walk_state,
 	union acpi_parse_object         *op)
@@ -272,7 +288,6 @@ acpi_ps_complete_this_op (
 					next = NULL;
 				}
 			}
-
 			prev = next;
 		}
 	}
@@ -280,7 +295,7 @@ acpi_ps_complete_this_op (
 
 cleanup:
 
-	/* Now we can actually delete the subtree rooted at op */
+	/* Now we can actually delete the subtree rooted at Op */
 
 	acpi_ps_delete_parse_tree (op);
 	return_VOID;
@@ -291,7 +306,9 @@ cleanup:
  *
  * FUNCTION:    acpi_ps_next_parse_state
  *
- * PARAMETERS:  parser_state        - Current parser state object
+ * PARAMETERS:  walk_state          - Current state
+ *              Op                  - Current parse op
+ *              callback_status     - Status from previous operation
  *
  * RETURN:      Status
  *
@@ -300,7 +317,7 @@ cleanup:
  *
  ******************************************************************************/
 
-acpi_status
+static acpi_status
 acpi_ps_next_parse_state (
 	struct acpi_walk_state          *walk_state,
 	union acpi_parse_object         *op,
@@ -382,9 +399,8 @@ acpi_ps_next_parse_state (
 
 	case AE_CTRL_TRANSFER:
 
-		/*
-		 * A method call (invocation) -- transfer control
-		 */
+		/* A method call (invocation) -- transfer control */
+
 		status = AE_CTRL_TRANSFER;
 		walk_state->prev_op = op;
 		walk_state->method_call_op = op;
@@ -397,6 +413,7 @@ acpi_ps_next_parse_state (
 
 
 	default:
+
 		status = callback_status;
 		if ((callback_status & AE_CODE_MASK) == AE_CODE_CONTROL) {
 			status = AE_OK;
@@ -412,7 +429,7 @@ acpi_ps_next_parse_state (
  *
  * FUNCTION:    acpi_ps_parse_loop
  *
- * PARAMETERS:  parser_state        - Current parser state object
+ * PARAMETERS:  walk_state          - Current state
  *
  * RETURN:      Status
  *
@@ -421,7 +438,7 @@ acpi_ps_next_parse_state (
  *
  ******************************************************************************/
 
-acpi_status
+static acpi_status
 acpi_ps_parse_loop (
 	struct acpi_walk_state          *walk_state)
 {
@@ -443,6 +460,7 @@ acpi_ps_parse_loop (
 	walk_state->arg_types = 0;
 
 #if (!defined (ACPI_NO_METHOD_EXECUTION) && !defined (ACPI_CONSTANT_EVAL_ONLY))
+
 	if (walk_state->walk_type & ACPI_WALK_METHOD_RESTART) {
 		/* We are restarting a preempted control method */
 
@@ -471,7 +489,8 @@ acpi_ps_parse_loop (
 							acpi_format_exception (status)));
 
 					}
-					ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "get_predicate Failed, %s\n",
+					ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+						"get_predicate Failed, %s\n",
 						acpi_format_exception (status)));
 					return_ACPI_STATUS (status);
 				}
@@ -492,16 +511,15 @@ acpi_ps_parse_loop (
 	}
 #endif
 
-	/*
-	 * Iterative parsing loop, while there is more aml to process:
-	 */
+	/* Iterative parsing loop, while there is more AML to process: */
+
 	while ((parser_state->aml < parser_state->aml_end) || (op)) {
 		aml_op_start = parser_state->aml;
 		if (!op) {
 			/* Get the next opcode from the AML stream */
 
 			walk_state->aml_offset = (u32) ACPI_PTR_DIFF (parser_state->aml,
-					   parser_state->aml_start);
+					  parser_state->aml_start);
 			walk_state->opcode   = acpi_ps_peek_opcode (parser_state);
 
 			/*
@@ -578,8 +596,10 @@ acpi_ps_parse_loop (
 					INCREMENT_ARG_LIST (walk_state->arg_types);
 				}
 
-				/* Make sure that we found a NAME and didn't run out of arguments */
-
+				/*
+				 * Make sure that we found a NAME and didn't run out of
+				 * arguments
+				 */
 				if (!GET_CURRENT_ARG_TYPE (walk_state->arg_types)) {
 					status = AE_AML_NO_OPERAND;
 					goto close_this_op;
@@ -597,12 +617,13 @@ acpi_ps_parse_loop (
 
 				status = walk_state->descending_callback (walk_state, &op);
 				if (ACPI_FAILURE (status)) {
-					ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "During name lookup/catalog, %s\n",
-							acpi_format_exception (status)));
+					ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+						"During name lookup/catalog, %s\n",
+						acpi_format_exception (status)));
 					goto close_this_op;
 				}
 
-				if (op == NULL) {
+				if (!op) {
 					continue;
 				}
 
@@ -659,7 +680,7 @@ acpi_ps_parse_loop (
 
 				if ((walk_state->descending_callback != NULL)) {
 					/*
-					 * Find the object.  This will either insert the object into
+					 * Find the object. This will either insert the object into
 					 * the namespace or simply look it up
 					 */
 					walk_state->op = op;
@@ -688,11 +709,15 @@ acpi_ps_parse_loop (
 		}
 
 
-		/* Start arg_count at zero because we don't know if there are any args yet */
-
+		/*
+		 * Start arg_count at zero because we don't know if there are
+		 * any args yet
+		 */
 		walk_state->arg_count = 0;
 
-		if (walk_state->arg_types) /* Are there any arguments that must be processed? */ {
+		/* Are there any arguments that must be processed? */
+
+		if (walk_state->arg_types) {
 			/* Get arguments */
 
 			switch (op->common.aml_opcode) {
@@ -720,14 +745,18 @@ acpi_ps_parse_loop (
 
 			default:
 
-				/* Op is not a constant or string, append each argument to the Op */
-
+				/*
+				 * Op is not a constant or string, append each argument
+				 * to the Op
+				 */
 				while (GET_CURRENT_ARG_TYPE (walk_state->arg_types) &&
 						!walk_state->arg_count) {
-					walk_state->aml_offset = (u32) ACPI_PTR_DIFF (parser_state->aml,
-							   parser_state->aml_start);
+					walk_state->aml_offset = (u32)
+						ACPI_PTR_DIFF (parser_state->aml, parser_state->aml_start);
+
 					status = acpi_ps_get_next_arg (walk_state, parser_state,
-							 GET_CURRENT_ARG_TYPE (walk_state->arg_types), &arg);
+							 GET_CURRENT_ARG_TYPE (walk_state->arg_types),
+							 &arg);
 					if (ACPI_FAILURE (status)) {
 						goto close_this_op;
 					}
@@ -752,7 +781,8 @@ acpi_ps_parse_loop (
 					 * Save the length and address of the body
 					 */
 					op->named.data   = parser_state->aml;
-					op->named.length = (u32) (parser_state->pkg_end - parser_state->aml);
+					op->named.length = (u32) (parser_state->pkg_end -
+							   parser_state->aml);
 
 					/* Skip body of method */
 
@@ -773,7 +803,8 @@ acpi_ps_parse_loop (
 						 * to parse them correctly.
 						 */
 						op->named.data   = aml_op_start;
-						op->named.length = (u32) (parser_state->pkg_end - aml_op_start);
+						op->named.length = (u32) (parser_state->pkg_end -
+								   aml_op_start);
 
 						/* Skip body */
 
@@ -785,7 +816,8 @@ acpi_ps_parse_loop (
 				case AML_WHILE_OP:
 
 					if (walk_state->control_state) {
-						walk_state->control_state->control.package_end = parser_state->pkg_end;
+						walk_state->control_state->control.package_end =
+							parser_state->pkg_end;
 					}
 					break;
 
@@ -801,8 +833,10 @@ acpi_ps_parse_loop (
 		/* Check for arguments that need to be processed */
 
 		if (walk_state->arg_count) {
-			/* There are arguments (complex ones), push Op and prepare for argument */
-
+			/*
+			 * There are arguments (complex ones), push Op and
+			 * prepare for argument
+			 */
 			status = acpi_ps_push_scope (parser_state, op,
 					 walk_state->arg_types, walk_state->arg_count);
 			if (ACPI_FAILURE (status)) {
@@ -812,8 +846,10 @@ acpi_ps_parse_loop (
 			continue;
 		}
 
-		/* All arguments have been processed -- Op is complete, prepare for next */
-
+		/*
+		 * All arguments have been processed -- Op is complete,
+		 * prepare for next
+		 */
 		walk_state->op_info = acpi_ps_get_opcode_info (op->common.aml_opcode);
 		if (walk_state->op_info->flags & AML_NAMED) {
 			if (acpi_gbl_depth) {
@@ -880,9 +916,8 @@ close_this_op:
 
 		case AE_CTRL_TRANSFER:
 
-			/*
-			 * We are about to transfer to a called method.
-			 */
+			/* We are about to transfer to a called method. */
+
 			walk_state->prev_op = op;
 			walk_state->prev_arg_types = walk_state->arg_types;
 			return_ACPI_STATUS (status);
@@ -1051,10 +1086,7 @@ close_this_op:
  *
  * FUNCTION:    acpi_ps_parse_aml
  *
- * PARAMETERS:  start_scope     - The starting point of the parse.  Becomes the
- *                                root of the parsed op tree.
- *              Aml             - Pointer to the raw AML code to parse
- *              aml_size        - Length of the AML to parse
+ * PARAMETERS:  walk_state      - Current state
  *
  *
  * RETURN:      Status
@@ -1076,8 +1108,10 @@ acpi_ps_parse_aml (
 
 	ACPI_FUNCTION_TRACE ("ps_parse_aml");
 
-	ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Entered with walk_state=%p Aml=%p size=%X\n",
-		walk_state, walk_state->parser_state.aml, walk_state->parser_state.aml_size));
+	ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
+		"Entered with walk_state=%p Aml=%p size=%X\n",
+		walk_state, walk_state->parser_state.aml,
+		walk_state->parser_state.aml_size));
 
 
 	/* Create and initialize a new thread state */
@@ -1142,9 +1176,10 @@ acpi_ps_parse_aml (
 			if ((status == AE_ALREADY_EXISTS) &&
 				(!walk_state->method_desc->method.semaphore)) {
 				/*
-				 * This method is marked not_serialized, but it tried to create a named
-				 * object, causing the second thread entrance to fail.  We will workaround
-				 * this by marking the method permanently as Serialized.
+				 * This method is marked not_serialized, but it tried to create
+				 * a named object, causing the second thread entrance to fail.
+				 * We will workaround this by marking the method permanently
+				 * as Serialized.
 				 */
 				walk_state->method_desc->method.method_flags |= AML_METHOD_SERIALIZED;
 				walk_state->method_desc->method.concurrency = 1;
@@ -1187,7 +1222,8 @@ acpi_ps_parse_aml (
 
 		previous_walk_state = walk_state;
 
-		ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "return_value=%p, implicit_value=%p State=%p\n",
+		ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
+			"return_value=%p, implicit_value=%p State=%p\n",
 			walk_state->return_desc, walk_state->implicit_return_obj, walk_state));
 
 		/* Check if we have restarted a preempted walk */
@@ -1231,12 +1267,14 @@ acpi_ps_parse_aml (
 		 */
 		else if (previous_walk_state->caller_return_desc) {
 			if (previous_walk_state->implicit_return_obj) {
-				*(previous_walk_state->caller_return_desc) = previous_walk_state->implicit_return_obj;
+				*(previous_walk_state->caller_return_desc) =
+					previous_walk_state->implicit_return_obj;
 			}
 			else {
 				 /* NULL if no return value */
 
-				*(previous_walk_state->caller_return_desc) = previous_walk_state->return_desc;
+				*(previous_walk_state->caller_return_desc) =
+					previous_walk_state->return_desc;
 			}
 		}
 		else {
diff --git a/drivers/acpi/parser/psscope.c b/drivers/acpi/parser/psscope.c
--- a/drivers/acpi/parser/psscope.c
+++ b/drivers/acpi/parser/psscope.c
@@ -65,6 +65,7 @@ union acpi_parse_object *
 acpi_ps_get_parent_scope (
 	struct acpi_parse_state         *parser_state)
 {
+
 	return (parser_state->scope->parse_scope.op);
 }
 
@@ -87,8 +88,10 @@ u8
 acpi_ps_has_completed_scope (
 	struct acpi_parse_state         *parser_state)
 {
-	return ((u8) ((parser_state->aml >= parser_state->scope->parse_scope.arg_end ||
-			   !parser_state->scope->parse_scope.arg_count)));
+
+	return ((u8)
+			((parser_state->aml >= parser_state->scope->parse_scope.arg_end ||
+			 !parser_state->scope->parse_scope.arg_count)));
 }
 
 
@@ -167,23 +170,23 @@ acpi_ps_push_scope (
 		return_ACPI_STATUS (AE_NO_MEMORY);
 	}
 
-	scope->common.data_type        = ACPI_DESC_TYPE_STATE_PSCOPE;
-	scope->parse_scope.op          = op;
-	scope->parse_scope.arg_list    = remaining_args;
-	scope->parse_scope.arg_count   = arg_count;
-	scope->parse_scope.pkg_end     = parser_state->pkg_end;
+	scope->common.data_type    = ACPI_DESC_TYPE_STATE_PSCOPE;
+	scope->parse_scope.op      = op;
+	scope->parse_scope.arg_list = remaining_args;
+	scope->parse_scope.arg_count = arg_count;
+	scope->parse_scope.pkg_end = parser_state->pkg_end;
 
 	/* Push onto scope stack */
 
 	acpi_ut_push_generic_state (&parser_state->scope, scope);
 
 	if (arg_count == ACPI_VAR_ARGS) {
-		/* multiple arguments */
+		/* Multiple arguments */
 
 		scope->parse_scope.arg_end = parser_state->pkg_end;
 	}
 	else {
-		/* single argument */
+		/* Single argument */
 
 		scope->parse_scope.arg_end = ACPI_TO_POINTER (ACPI_MAX_PTR);
 	}
@@ -221,18 +224,17 @@ acpi_ps_pop_scope (
 	ACPI_FUNCTION_TRACE ("ps_pop_scope");
 
 
-	/*
-	 * Only pop the scope if there is in fact a next scope
-	 */
+	/* Only pop the scope if there is in fact a next scope */
+
 	if (scope->common.next) {
 		scope = acpi_ut_pop_generic_state (&parser_state->scope);
 
 		/* return to parsing previous op */
 
-		*op                     = scope->parse_scope.op;
-		*arg_list               = scope->parse_scope.arg_list;
-		*arg_count              = scope->parse_scope.arg_count;
-		parser_state->pkg_end   = scope->parse_scope.pkg_end;
+		*op                 = scope->parse_scope.op;
+		*arg_list           = scope->parse_scope.arg_list;
+		*arg_count          = scope->parse_scope.arg_count;
+		parser_state->pkg_end = scope->parse_scope.pkg_end;
 
 		/* All done with this scope state structure */
 
@@ -241,12 +243,13 @@ acpi_ps_pop_scope (
 	else {
 		/* empty parse stack, prepare to fetch next opcode */
 
-		*op                     = NULL;
-		*arg_list               = 0;
-		*arg_count              = 0;
+		*op       = NULL;
+		*arg_list = 0;
+		*arg_count = 0;
 	}
 
-	ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Popped Op %p Args %X\n", *op, *arg_count));
+	ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
+		"Popped Op %p Args %X\n", *op, *arg_count));
 	return_VOID;
 }
 
@@ -257,7 +260,7 @@ acpi_ps_pop_scope (
  *
  * PARAMETERS:  parser_state        - Current parser state object
  *
- * RETURN:      Status
+ * RETURN:      None
  *
  * DESCRIPTION: Destroy available list, remaining stack levels, and return
  *              root scope
diff --git a/drivers/acpi/parser/pstree.c b/drivers/acpi/parser/pstree.c
--- a/drivers/acpi/parser/pstree.c
+++ b/drivers/acpi/parser/pstree.c
@@ -49,6 +49,14 @@
 #define _COMPONENT          ACPI_PARSER
 	 ACPI_MODULE_NAME    ("pstree")
 
+/* Local prototypes */
+
+#ifdef ACPI_OBSOLETE_FUNCTIONS
+union acpi_parse_object *
+acpi_ps_get_child (
+	union acpi_parse_object         *op);
+#endif
+
 
 /*******************************************************************************
  *
@@ -57,7 +65,7 @@
  * PARAMETERS:  Op              - Get an argument for this op
  *              Argn            - Nth argument to get
  *
- * RETURN:      The argument (as an Op object).  NULL if argument does not exist
+ * RETURN:      The argument (as an Op object). NULL if argument does not exist
  *
  * DESCRIPTION: Get the specified op's argument.
  *
@@ -152,7 +160,6 @@ acpi_ps_append_arg (
 		return;
 	}
 
-
 	/* Append the argument to the linked argument list */
 
 	if (op->common.value.arg) {
@@ -164,14 +171,12 @@ acpi_ps_append_arg (
 		}
 		prev_arg->common.next = arg;
 	}
-
 	else {
 		/* No argument list, this will be the first argument */
 
 		op->common.value.arg = arg;
 	}
 
-
 	/* Set the parent in this arg and any args linked after it */
 
 	while (arg) {
@@ -182,73 +187,6 @@ acpi_ps_append_arg (
 
 
 #ifdef ACPI_FUTURE_USAGE
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_ps_get_child
- *
- * PARAMETERS:  Op              - Get the child of this Op
- *
- * RETURN:      Child Op, Null if none is found.
- *
- * DESCRIPTION: Get op's children or NULL if none
- *
- ******************************************************************************/
-union acpi_parse_object *
-acpi_ps_get_child (
-	union acpi_parse_object         *op)
-{
-	union acpi_parse_object         *child = NULL;
-
-
-	ACPI_FUNCTION_ENTRY ();
-
-
-	switch (op->common.aml_opcode) {
-	case AML_SCOPE_OP:
-	case AML_ELSE_OP:
-	case AML_DEVICE_OP:
-	case AML_THERMAL_ZONE_OP:
-	case AML_INT_METHODCALL_OP:
-
-		child = acpi_ps_get_arg (op, 0);
-		break;
-
-
-	case AML_BUFFER_OP:
-	case AML_PACKAGE_OP:
-	case AML_METHOD_OP:
-	case AML_IF_OP:
-	case AML_WHILE_OP:
-	case AML_FIELD_OP:
-
-		child = acpi_ps_get_arg (op, 1);
-		break;
-
-
-	case AML_POWER_RES_OP:
-	case AML_INDEX_FIELD_OP:
-
-		child = acpi_ps_get_arg (op, 2);
-		break;
-
-
-	case AML_PROCESSOR_OP:
-	case AML_BANK_FIELD_OP:
-
-		child = acpi_ps_get_arg (op, 3);
-		break;
-
-
-	default:
-		/* All others have no children */
-		break;
-	}
-
-	return (child);
-}
-
-
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ps_get_depth_next
@@ -280,21 +218,21 @@ acpi_ps_get_depth_next (
 		return (NULL);
 	}
 
-	/* look for an argument or child */
+	/* Look for an argument or child */
 
 	next = acpi_ps_get_arg (op, 0);
 	if (next) {
 		return (next);
 	}
 
-	/* look for a sibling */
+	/* Look for a sibling */
 
 	next = op->common.next;
 	if (next) {
 		return (next);
 	}
 
-	/* look for a sibling of parent */
+	/* Look for a sibling of parent */
 
 	parent = op->common.parent;
 
@@ -305,13 +243,13 @@ acpi_ps_get_depth_next (
 		}
 
 		if (arg == origin) {
-			/* reached parent of origin, end search */
+			/* Reached parent of origin, end search */
 
 			return (NULL);
 		}
 
 		if (parent->common.next) {
-			/* found sibling of parent */
+			/* Found sibling of parent */
 
 			return (parent->common.next);
 		}
@@ -323,5 +261,74 @@ acpi_ps_get_depth_next (
 	return (next);
 }
 
+
+#ifdef ACPI_OBSOLETE_FUNCTIONS
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ps_get_child
+ *
+ * PARAMETERS:  Op              - Get the child of this Op
+ *
+ * RETURN:      Child Op, Null if none is found.
+ *
+ * DESCRIPTION: Get op's children or NULL if none
+ *
+ ******************************************************************************/
+
+union acpi_parse_object *
+acpi_ps_get_child (
+	union acpi_parse_object         *op)
+{
+	union acpi_parse_object         *child = NULL;
+
+
+	ACPI_FUNCTION_ENTRY ();
+
+
+	switch (op->common.aml_opcode) {
+	case AML_SCOPE_OP:
+	case AML_ELSE_OP:
+	case AML_DEVICE_OP:
+	case AML_THERMAL_ZONE_OP:
+	case AML_INT_METHODCALL_OP:
+
+		child = acpi_ps_get_arg (op, 0);
+		break;
+
+
+	case AML_BUFFER_OP:
+	case AML_PACKAGE_OP:
+	case AML_METHOD_OP:
+	case AML_IF_OP:
+	case AML_WHILE_OP:
+	case AML_FIELD_OP:
+
+		child = acpi_ps_get_arg (op, 1);
+		break;
+
+
+	case AML_POWER_RES_OP:
+	case AML_INDEX_FIELD_OP:
+
+		child = acpi_ps_get_arg (op, 2);
+		break;
+
+
+	case AML_PROCESSOR_OP:
+	case AML_BANK_FIELD_OP:
+
+		child = acpi_ps_get_arg (op, 3);
+		break;
+
+
+	default:
+		/* All others have no children */
+		break;
+	}
+
+	return (child);
+}
+#endif
+
 #endif  /*  ACPI_FUTURE_USAGE  */
 
diff --git a/drivers/acpi/parser/psutils.c b/drivers/acpi/parser/psutils.c
--- a/drivers/acpi/parser/psutils.c
+++ b/drivers/acpi/parser/psutils.c
@@ -45,7 +45,6 @@
 #include <acpi/acpi.h>
 #include <acpi/acparser.h>
 #include <acpi/amlcode.h>
-#include <acpi/acnamesp.h>
 
 #define _COMPONENT          ACPI_PARSER
 	 ACPI_MODULE_NAME    ("psutils")
@@ -57,7 +56,7 @@
  *
  * PARAMETERS:  None
  *
- * RETURN:      scope_op
+ * RETURN:      A new Scope object, null on failure
  *
  * DESCRIPTION: Create a Scope and associated namepath op with the root name
  *
@@ -75,7 +74,6 @@ acpi_ps_create_scope_op (
 		return (NULL);
 	}
 
-
 	scope_op->named.name = ACPI_ROOT_NAME;
 	return (scope_op);
 }
@@ -88,10 +86,9 @@ acpi_ps_create_scope_op (
  * PARAMETERS:  Op              - A newly allocated Op object
  *              Opcode          - Opcode to store in the Op
  *
- * RETURN:      Status
+ * RETURN:      None
  *
- * DESCRIPTION: Allocate an acpi_op, choose op type (and thus size) based on
- *              opcode
+ * DESCRIPTION: Initialize a parse (Op) object
  *
  ******************************************************************************/
 
@@ -107,7 +104,8 @@ acpi_ps_init_op (
 	op->common.aml_opcode = opcode;
 
 	ACPI_DISASM_ONLY_MEMBERS (ACPI_STRNCPY (op->common.aml_op_name,
-			(acpi_ps_get_opcode_info (opcode))->name, sizeof (op->common.aml_op_name)));
+			(acpi_ps_get_opcode_info (opcode))->name,
+				sizeof (op->common.aml_op_name)));
 }
 
 
@@ -117,7 +115,7 @@ acpi_ps_init_op (
  *
  * PARAMETERS:  Opcode          - Opcode that will be stored in the new Op
  *
- * RETURN:      Pointer to the new Op.
+ * RETURN:      Pointer to the new Op, null on failure
  *
  * DESCRIPTION: Allocate an acpi_op, choose op type (and thus size) based on
  *              opcode.  A cache of opcodes is available for the pure
@@ -275,7 +273,6 @@ acpi_ps_get_name (
 	union acpi_parse_object         *op)
 {
 
-
 	/* The "generic" object has no name associated with it */
 
 	if (op->common.flags & ACPI_PARSEOP_GENERIC) {
diff --git a/drivers/acpi/parser/pswalk.c b/drivers/acpi/parser/pswalk.c
--- a/drivers/acpi/parser/pswalk.c
+++ b/drivers/acpi/parser/pswalk.c
@@ -90,17 +90,15 @@ acpi_ps_delete_parse_tree (
 			}
 		}
 
-		/*
-		 * No more children, this Op is complete.
-		 */
+		/* No more children, this Op is complete. */
+
 		next = op->common.next;
 		parent = op->common.parent;
 
 		acpi_ps_free_op (op);
 
-		/*
-		 * If we are back to the starting point, the walk is complete.
-		 */
+		/* If we are back to the starting point, the walk is complete. */
+
 		if (op == subtree_root) {
 			return_VOID;
 		}
@@ -111,5 +109,6 @@ acpi_ps_delete_parse_tree (
 			op = parent;
 		}
 	}
+
 	return_VOID;
 }
diff --git a/drivers/acpi/parser/psxface.c b/drivers/acpi/parser/psxface.c
--- a/drivers/acpi/parser/psxface.c
+++ b/drivers/acpi/parser/psxface.c
@@ -57,13 +57,16 @@
  *
  * FUNCTION:    acpi_psx_execute
  *
- * PARAMETERS:  Info->Node          - A method object containing both the AML
- *                                    address and length.
- *              **Params            - List of parameters to pass to method,
+ * PARAMETERS:  Info            - Method info block, contains:
+ *                  Node            - Method Node to execute
+ *                  Parameters      - List of parameters to pass to the method,
  *                                    terminated by NULL. Params itself may be
  *                                    NULL if no parameters are being passed.
- *              **return_obj_desc   - Return object from execution of the
- *                                    method.
+ *                  return_object   - Where to put method's return value (if
+ *                                    any). If NULL, no value is returned.
+ *                  parameter_type  - Type of Parameter list
+ *                  return_object   - Where to put method's return value (if
+ *                                    any). If NULL, no value is returned.
  *
  * RETURN:      Status
  *
@@ -196,9 +199,8 @@ acpi_psx_execute (
 		goto cleanup3;
 	}
 
-	/*
-	 * The walk of the parse tree is where we actually execute the method
-	 */
+	/* The walk of the parse tree is where we actually execute the method */
+
 	status = acpi_ps_parse_aml (walk_state);
 	goto cleanup2; /* Walk state already deleted */
 
@@ -217,7 +219,8 @@ cleanup1:
 		for (i = 0; info->parameters[i]; i++) {
 			/* Ignore errors, just do them all */
 
-			(void) acpi_ut_update_object_reference (info->parameters[i], REF_DECREMENT);
+			(void) acpi_ut_update_object_reference (
+					 info->parameters[i], REF_DECREMENT);
 		}
 	}
 
diff --git a/drivers/acpi/pci_bind.c b/drivers/acpi/pci_bind.c
--- a/drivers/acpi/pci_bind.c
+++ b/drivers/acpi/pci_bind.c
@@ -61,15 +61,14 @@ acpi_pci_data_handler (
 
 
 /**
- * acpi_os_get_pci_id
+ * acpi_get_pci_id
  * ------------------
  * This function is used by the ACPI Interpreter (a.k.a. Core Subsystem)
  * to resolve PCI information for ACPI-PCI devices defined in the namespace.
  * This typically occurs when resolving PCI operation region information.
  */
-#ifdef ACPI_FUTURE_USAGE
 acpi_status
-acpi_os_get_pci_id (
+acpi_get_pci_id (
 	acpi_handle		handle,
 	struct acpi_pci_id	*id)
 {
@@ -78,7 +77,7 @@ acpi_os_get_pci_id (
 	struct acpi_device	*device = NULL;
 	struct acpi_pci_data	*data = NULL;
 
-	ACPI_FUNCTION_TRACE("acpi_os_get_pci_id");
+	ACPI_FUNCTION_TRACE("acpi_get_pci_id");
 
 	if (!id)
 		return_ACPI_STATUS(AE_BAD_PARAMETER);
@@ -92,7 +91,7 @@ acpi_os_get_pci_id (
 	}
 
 	status = acpi_get_data(handle, acpi_pci_data_handler, (void**) &data);
-	if (ACPI_FAILURE(status) || !data || !data->dev) {
+	if (ACPI_FAILURE(status) || !data) {
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 
 			"Invalid ACPI-PCI context for device %s\n",
 			acpi_device_bid(device)));
@@ -115,7 +114,7 @@ acpi_os_get_pci_id (
 
 	return_ACPI_STATUS(AE_OK);
 }
-#endif  /*  ACPI_FUTURE_USAGE  */
+EXPORT_SYMBOL(acpi_get_pci_id);
 
 	
 int
@@ -129,6 +128,8 @@ acpi_pci_bind (
 	char			*pathname = NULL;
 	struct acpi_buffer	buffer = {0, NULL};
 	acpi_handle		handle = NULL;
+	struct pci_dev		*dev;
+	struct pci_bus 		*bus;
 
 	ACPI_FUNCTION_TRACE("acpi_pci_bind");
 
@@ -193,8 +194,20 @@ acpi_pci_bind (
 	 * Locate matching device in PCI namespace.  If it doesn't exist
 	 * this typically means that the device isn't currently inserted
 	 * (e.g. docking station, port replicator, etc.).
+	 * We cannot simply search the global pci device list, since
+	 * PCI devices are added to the global pci list when the root
+	 * bridge start ops are run, which may not have happened yet.
 	 */
-	data->dev = pci_find_slot(data->id.bus, PCI_DEVFN(data->id.device, data->id.function));
+	bus = pci_find_bus(data->id.segment, data->id.bus);
+	if (bus) {
+		list_for_each_entry(dev, &bus->devices, bus_list) {
+			if (dev->devfn == PCI_DEVFN(data->id.device,
+						data->id.function)) {
+				data->dev = dev;
+				break;
+			}
+		}
+	}
 	if (!data->dev) {
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
 			"Device %02x:%02x:%02x.%02x not present in PCI namespace\n",
diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c
--- a/drivers/acpi/pci_irq.c
+++ b/drivers/acpi/pci_irq.c
@@ -269,7 +269,51 @@ acpi_pci_irq_del_prt (int segment, int b
 /* --------------------------------------------------------------------------
                           PCI Interrupt Routing Support
    -------------------------------------------------------------------------- */
+typedef int (*irq_lookup_func)(struct acpi_prt_entry *, int *, int *, char **);
 
+static int
+acpi_pci_allocate_irq(struct acpi_prt_entry *entry,
+	int	*edge_level,
+	int	*active_high_low,
+	char	**link)
+{
+	int	irq;
+
+	ACPI_FUNCTION_TRACE("acpi_pci_allocate_irq");
+
+	if (entry->link.handle) {
+		irq = acpi_pci_link_allocate_irq(entry->link.handle,
+			entry->link.index, edge_level, active_high_low, link);
+		if (irq < 0) {
+			ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid IRQ link routing entry\n"));
+			return_VALUE(-1);
+		}
+	} else {
+		irq = entry->link.index;
+		*edge_level = ACPI_LEVEL_SENSITIVE;
+		*active_high_low = ACPI_ACTIVE_LOW;
+	}
+
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found IRQ %d\n", irq));
+	return_VALUE(irq);
+}
+
+static int
+acpi_pci_free_irq(struct acpi_prt_entry *entry,
+	int	*edge_level,
+	int	*active_high_low,
+	char	**link)
+{
+	int	irq;
+
+	ACPI_FUNCTION_TRACE("acpi_pci_free_irq");
+	if (entry->link.handle) {
+		irq = acpi_pci_link_free_irq(entry->link.handle);
+	} else {
+		irq = entry->link.index;
+	}
+	return_VALUE(irq);
+}
 /*
  * acpi_pci_irq_lookup
  * success: return IRQ >= 0
@@ -282,12 +326,13 @@ acpi_pci_irq_lookup (
 	int			pin,
 	int			*edge_level,
 	int			*active_high_low,
-	char			**link)
+	char			**link,
+	irq_lookup_func		func)
 {
 	struct acpi_prt_entry	*entry = NULL;
 	int segment = pci_domain_nr(bus);
 	int bus_nr = bus->number;
-	int irq;
+	int ret;
 
 	ACPI_FUNCTION_TRACE("acpi_pci_irq_lookup");
 
@@ -301,22 +346,8 @@ acpi_pci_irq_lookup (
 		return_VALUE(-1);
 	}
 	
-	if (entry->link.handle) {
-		irq = acpi_pci_link_get_irq(entry->link.handle,
-			entry->link.index, edge_level, active_high_low, link);
-		if (irq < 0) {
-			ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid IRQ link routing entry\n"));
-			return_VALUE(-1);
-		}
-	} else {
-		irq = entry->link.index;
-		*edge_level = ACPI_LEVEL_SENSITIVE;
-		*active_high_low = ACPI_ACTIVE_LOW;
-	}
-
-	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found IRQ %d\n", irq));
-
-	return_VALUE(irq);
+	ret = func(entry, edge_level, active_high_low, link);
+	return_VALUE(ret);
 }
 
 /*
@@ -330,7 +361,8 @@ acpi_pci_irq_derive (
 	int			pin,
 	int			*edge_level,
 	int			*active_high_low,
-	char			**link)
+	char			**link,
+	irq_lookup_func		func)
 {
 	struct pci_dev		*bridge = dev;
 	int			irq = -1;
@@ -363,7 +395,7 @@ acpi_pci_irq_derive (
 		}
 
 		irq = acpi_pci_irq_lookup(bridge->bus, PCI_SLOT(bridge->devfn),
-			pin, edge_level, active_high_low, link);
+			pin, edge_level, active_high_low, link, func);
 	}
 
 	if (irq < 0) {
@@ -415,7 +447,7 @@ acpi_pci_irq_enable (
 	 * values override any BIOS-assigned IRQs set during boot.
 	 */
  	irq = acpi_pci_irq_lookup(dev->bus, PCI_SLOT(dev->devfn), pin,
-		&edge_level, &active_high_low, &link);
+		&edge_level, &active_high_low, &link, acpi_pci_allocate_irq);
 
 	/*
 	 * If no PRT entry was found, we'll try to derive an IRQ from the
@@ -423,7 +455,7 @@ acpi_pci_irq_enable (
 	 */
 	if (irq < 0)
  		irq = acpi_pci_irq_derive(dev, pin, &edge_level,
-			&active_high_low, &link);
+			&active_high_low, &link, acpi_pci_allocate_irq);
  
 	/*
 	 * No IRQ known to the ACPI subsystem - maybe the BIOS / 
@@ -433,8 +465,9 @@ acpi_pci_irq_enable (
 		printk(KERN_WARNING PREFIX "PCI Interrupt %s[%c]: no GSI",
 			pci_name(dev), ('A' + pin));
 		/* Interrupt Line values above 0xF are forbidden */
-		if (dev->irq >= 0 && (dev->irq <= 0xF)) {
+		if (dev->irq > 0 && (dev->irq <= 0xF)) {
 			printk(" - using IRQ %d\n", dev->irq);
+			acpi_register_gsi(dev->irq, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW);
 			return_VALUE(0);
 		}
 		else {
@@ -461,7 +494,9 @@ acpi_pci_irq_enable (
 EXPORT_SYMBOL(acpi_pci_irq_enable);
 
 
-#ifdef CONFIG_ACPI_DEALLOCATE_IRQ
+/* FIXME: implement x86/x86_64 version */
+void __attribute__((weak)) acpi_unregister_gsi(u32 i) {}
+
 void
 acpi_pci_irq_disable (
 	struct pci_dev		*dev)
@@ -488,14 +523,14 @@ acpi_pci_irq_disable (
 	 * First we check the PCI IRQ routing table (PRT) for an IRQ.
 	 */
  	gsi = acpi_pci_irq_lookup(dev->bus, PCI_SLOT(dev->devfn), pin,
-				  &edge_level, &active_high_low, NULL);
+			&edge_level, &active_high_low, NULL, acpi_pci_free_irq);
 	/*
 	 * If no PRT entry was found, we'll try to derive an IRQ from the
 	 * device's parent bridge.
 	 */
 	if (gsi < 0)
  		gsi = acpi_pci_irq_derive(dev, pin,
-					  &edge_level, &active_high_low, NULL);
+			&edge_level, &active_high_low, NULL, acpi_pci_free_irq);
 	if (gsi < 0)
 		return_VOID;
 
@@ -511,4 +546,3 @@ acpi_pci_irq_disable (
 
 	return_VOID;
 }
-#endif /* CONFIG_ACPI_DEALLOCATE_IRQ */
diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c
--- a/drivers/acpi/pci_link.c
+++ b/drivers/acpi/pci_link.c
@@ -68,14 +68,19 @@ static struct acpi_driver acpi_pci_link_
 			},
 };
 
+/*
+ * If a link is initialized, we never change its active and initialized
+ * later even the link is disable. Instead, we just repick the active irq
+ */
 struct acpi_pci_link_irq {
 	u8			active;			/* Current IRQ */
 	u8			edge_level;		/* All IRQs */
 	u8			active_high_low;	/* All IRQs */
-	u8			initialized;
 	u8			resource_type;
 	u8			possible_count;
 	u8			possible[ACPI_PCI_LINK_MAX_POSSIBLE];
+	u8			initialized:1;
+	u8			reserved:7;
 };
 
 struct acpi_pci_link {
@@ -83,12 +88,14 @@ struct acpi_pci_link {
 	struct acpi_device	*device;
 	acpi_handle		handle;
 	struct acpi_pci_link_irq irq;
+	int			refcnt;
 };
 
 static struct {
 	int			count;
 	struct list_head	entries;
 }				acpi_link;
+DECLARE_MUTEX(acpi_link_lock);
 
 
 /* --------------------------------------------------------------------------
@@ -530,8 +537,12 @@ static int acpi_pci_link_allocate(
 
 	ACPI_FUNCTION_TRACE("acpi_pci_link_allocate");
 
-	if (link->irq.initialized)
+	if (link->irq.initialized) {
+		if (link->refcnt == 0)
+			/* This means the link is disabled but initialized */
+			acpi_pci_link_set(link, link->irq.active);
 		return_VALUE(0);
+	}
 
 	/*
 	 * search for active IRQ in list of possible IRQs.
@@ -590,13 +601,13 @@ static int acpi_pci_link_allocate(
 }
 
 /*
- * acpi_pci_link_get_irq
+ * acpi_pci_link_allocate_irq
  * success: return IRQ >= 0
  * failure: return -1
  */
 
 int
-acpi_pci_link_get_irq (
+acpi_pci_link_allocate_irq (
 	acpi_handle		handle,
 	int			index,
 	int			*edge_level,
@@ -607,7 +618,7 @@ acpi_pci_link_get_irq (
 	struct acpi_device	*device = NULL;
 	struct acpi_pci_link	*link = NULL;
 
-	ACPI_FUNCTION_TRACE("acpi_pci_link_get_irq");
+	ACPI_FUNCTION_TRACE("acpi_pci_link_allocate_irq");
 
 	result = acpi_bus_get_device(handle, &device);
 	if (result) {
@@ -627,21 +638,81 @@ acpi_pci_link_get_irq (
 		return_VALUE(-1);
 	}
 
-	if (acpi_pci_link_allocate(link))
+	down(&acpi_link_lock);
+	if (acpi_pci_link_allocate(link)) {
+		up(&acpi_link_lock);
 		return_VALUE(-1);
+	}
 	   
 	if (!link->irq.active) {
+		up(&acpi_link_lock);
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Link active IRQ is 0!\n"));
 		return_VALUE(-1);
 	}
+	link->refcnt ++;
+	up(&acpi_link_lock);
 
 	if (edge_level) *edge_level = link->irq.edge_level;
 	if (active_high_low) *active_high_low = link->irq.active_high_low;
 	if (name) *name = acpi_device_bid(link->device);
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+		"Link %s is referenced\n", acpi_device_bid(link->device)));
 	return_VALUE(link->irq.active);
 }
 
+/*
+ * We don't change link's irq information here.  After it is reenabled, we
+ * continue use the info
+ */
+int
+acpi_pci_link_free_irq(acpi_handle handle)
+{
+	struct acpi_device	*device = NULL;
+	struct acpi_pci_link	*link = NULL;
+	acpi_status		result;
+
+	ACPI_FUNCTION_TRACE("acpi_pci_link_free_irq");
+
+	result = acpi_bus_get_device(handle, &device);
+	if (result) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid link device\n"));
+		return_VALUE(-1);
+	}
+
+	link = (struct acpi_pci_link *) acpi_driver_data(device);
+	if (!link) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid link context\n"));
+		return_VALUE(-1);
+	}
+
+	down(&acpi_link_lock);
+	if (!link->irq.initialized) {
+		up(&acpi_link_lock);
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Link isn't initialized\n"));
+		return_VALUE(-1);
+	}
 
+#ifdef	FUTURE_USE
+	/*
+	 * The Link reference count allows us to _DISable an unused link
+	 * and suspend time, and set it again  on resume.
+	 * However, 2.6.12 still has irq_router.resume
+	 * which blindly restores the link state.
+	 * So we disable the reference count method
+	 * to prevent duplicate acpi_pci_link_set()
+	 * which would harm some systems
+	 */
+	link->refcnt --;
+#endif
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+		"Link %s is dereferenced\n", acpi_device_bid(link->device)));
+
+	if (link->refcnt == 0) {
+		acpi_ut_evaluate_object(link->handle, "_DIS", 0, NULL);
+	}
+	up(&acpi_link_lock);
+	return_VALUE(link->irq.active);
+}
 /* --------------------------------------------------------------------------
                                  Driver Interface
    -------------------------------------------------------------------------- */
@@ -671,6 +742,7 @@ acpi_pci_link_add (
 	strcpy(acpi_device_class(device), ACPI_PCI_LINK_CLASS);
 	acpi_driver_data(device) = link;
 
+	down(&acpi_link_lock);
 	result = acpi_pci_link_get_possible(link);
 	if (result)
 		goto end;
@@ -706,6 +778,7 @@ acpi_pci_link_add (
 end:
 	/* disable all links -- to be activated on use */
 	acpi_ut_evaluate_object(link->handle, "_DIS", 0, NULL);
+	up(&acpi_link_lock);
 
 	if (result)
 		kfree(link);
@@ -713,20 +786,23 @@ end:
 	return_VALUE(result);
 }
 
-
 static int
-acpi_pci_link_resume (
-	struct acpi_pci_link	*link)
+acpi_pci_link_resume(
+	struct acpi_pci_link *link)
 {
 	ACPI_FUNCTION_TRACE("acpi_pci_link_resume");
-	
-	if (link->irq.active && link->irq.initialized)
+
+	if (link->refcnt && link->irq.active && link->irq.initialized)
 		return_VALUE(acpi_pci_link_set(link, link->irq.active));
 	else
 		return_VALUE(0);
 }
 
-
+/*
+ * FIXME: this is a workaround to avoid nasty warning.  It will be removed
+ * after every device calls pci_disable_device in .resume.
+ */
+int acpi_in_resume;
 static int
 irqrouter_resume(
 	struct sys_device *dev)
@@ -736,16 +812,17 @@ irqrouter_resume(
 
 	ACPI_FUNCTION_TRACE("irqrouter_resume");
 
+	acpi_in_resume = 1;
 	list_for_each(node, &acpi_link.entries) {
-
 		link = list_entry(node, struct acpi_pci_link, node);
 		if (!link) {
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid link context\n"));
+			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				"Invalid link context\n"));
 			continue;
 		}
-
 		acpi_pci_link_resume(link);
 	}
+	acpi_in_resume = 0;
 	return_VALUE(0);
 }
 
@@ -764,8 +841,9 @@ acpi_pci_link_remove (
 
 	link = (struct acpi_pci_link *) acpi_driver_data(device);
 
-	/* TBD: Acquire/release lock */
+	down(&acpi_link_lock);
 	list_del(&link->node);
+	up(&acpi_link_lock);
 
 	kfree(link);
 
@@ -812,9 +890,12 @@ static int __init acpi_irq_penalty_updat
  * There is no ISA_POSSIBLE weight, so we simply use
  * the (small) PCI_USING penalty.
  */
-void acpi_penalize_isa_irq(int irq)
+void acpi_penalize_isa_irq(int irq, int active)
 {
-	acpi_irq_penalty[irq] += PIRQ_PENALTY_PCI_USING;
+	if (active)
+		acpi_irq_penalty[irq] += PIRQ_PENALTY_ISA_USED;
+	else
+		acpi_irq_penalty[irq] += PIRQ_PENALTY_PCI_USING;
 }
 
 /*
@@ -854,6 +935,7 @@ int __init acpi_irq_balance_set(char *st
 __setup("acpi_irq_balance", acpi_irq_balance_set);
 
 
+/* FIXME: we will remove this interface after all drivers call pci_disable_device */
 static struct sysdev_class irqrouter_sysdev_class = {
         set_kset_name("irqrouter"),
         .resume = irqrouter_resume,
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -46,6 +46,7 @@ ACPI_MODULE_NAME		("pci_root")
 
 static int acpi_pci_root_add (struct acpi_device *device);
 static int acpi_pci_root_remove (struct acpi_device *device, int type);
+static int acpi_pci_root_start (struct acpi_device *device);
 
 static struct acpi_driver acpi_pci_root_driver = {
 	.name =		ACPI_PCI_ROOT_DRIVER_NAME,
@@ -54,6 +55,7 @@ static struct acpi_driver acpi_pci_root_
 	.ops =		{
 				.add =    acpi_pci_root_add,
 				.remove = acpi_pci_root_remove,
+				.start =  acpi_pci_root_start,
 			},
 };
 
@@ -169,6 +171,7 @@ acpi_pci_root_add (
 	if (!root)
 		return_VALUE(-ENOMEM);
 	memset(root, 0, sizeof(struct acpi_pci_root));
+	INIT_LIST_HEAD(&root->node);
 
 	root->handle = device->handle;
 	strcpy(acpi_device_name(device), ACPI_PCI_ROOT_DEVICE_NAME);
@@ -298,12 +301,31 @@ acpi_pci_root_add (
 			root->id.bus);
 
 end:
-	if (result)
+	if (result) {
+		if (!list_empty(&root->node))
+			list_del(&root->node);
 		kfree(root);
+	}
 
 	return_VALUE(result);
 }
 
+static int
+acpi_pci_root_start (
+	struct acpi_device	*device)
+{
+	struct acpi_pci_root	*root;
+
+	ACPI_FUNCTION_TRACE("acpi_pci_root_start");
+
+	list_for_each_entry(root, &acpi_pci_roots, node) {
+		if (root->handle == device->handle) {
+			pci_bus_add_devices(root->bus);
+			return_VALUE(0);
+		}
+	}
+	return_VALUE(-ENODEV);
+}
 
 static int
 acpi_pci_root_remove (
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
--- a/drivers/acpi/processor_core.c
+++ b/drivers/acpi/processor_core.c
@@ -256,6 +256,43 @@ acpi_processor_errata (
 
 
 /* --------------------------------------------------------------------------
+                              Common ACPI processor fucntions
+   -------------------------------------------------------------------------- */
+
+/*
+ * _PDC is required for a BIOS-OS handshake for most of the newer
+ * ACPI processor features.
+ */
+
+int acpi_processor_set_pdc(struct acpi_processor *pr,
+				struct acpi_object_list *pdc_in)
+{
+	acpi_status		status = AE_OK;
+	u32			arg0_buf[3];
+	union acpi_object	arg0 = {ACPI_TYPE_BUFFER};
+	struct acpi_object_list	no_object = {1, &arg0};
+	struct acpi_object_list	*pdc;
+
+	ACPI_FUNCTION_TRACE("acpi_processor_set_pdc");
+
+	arg0.buffer.length = 12;
+	arg0.buffer.pointer = (u8 *) arg0_buf;
+	arg0_buf[0] = ACPI_PDC_REVISION_ID;
+	arg0_buf[1] = 0;
+	arg0_buf[2] = 0;
+
+	pdc = (pdc_in) ? pdc_in : &no_object;
+
+	status = acpi_evaluate_object(pr->handle, "_PDC", pdc, NULL);
+
+	if ((ACPI_FAILURE(status)) && (pdc_in))
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Error evaluating _PDC, using legacy perf. control...\n"));
+
+	return_VALUE(status);
+}
+
+
+/* --------------------------------------------------------------------------
                               FS Interface (/proc)
    -------------------------------------------------------------------------- */
 
@@ -723,7 +760,7 @@ int acpi_processor_device_add(
 		return_VALUE(-ENODEV);
 	}
 
-	acpi_bus_scan(*device);
+	acpi_bus_start(*device);
 
 	pr = acpi_driver_data(*device);
 	if (!pr)
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -6,6 +6,8 @@
  *  Copyright (C) 2004       Dominik Brodowski <linux@brodo.de>
  *  Copyright (C) 2004  Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
  *  			- Added processor hotplug support
+ *  Copyright (C) 2005  Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
+ *  			- Added support for C3 on SMP
  *
  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  *
@@ -79,30 +81,32 @@ module_param(bm_history, uint, 0644);
  *
  * To skip this limit, boot/load with a large max_cstate limit.
  */
-static int no_c2c3(struct dmi_system_id *id)
+static int set_max_cstate(struct dmi_system_id *id)
 {
 	if (max_cstate > ACPI_PROCESSOR_MAX_POWER)
 		return 0;
 
-	printk(KERN_NOTICE PREFIX "%s detected - C2,C3 disabled."
+	printk(KERN_NOTICE PREFIX "%s detected - limiting to C%ld max_cstate."
 		" Override with \"processor.max_cstate=%d\"\n", id->ident,
-	       ACPI_PROCESSOR_MAX_POWER + 1);
+		(long)id->driver_data, ACPI_PROCESSOR_MAX_POWER + 1);
 
-	max_cstate = 1;
+	max_cstate = (long)id->driver_data;
 
 	return 0;
 }
 
 
-
-
 static struct dmi_system_id __initdata processor_power_dmi_table[] = {
-	{ no_c2c3, "IBM ThinkPad R40e", {
+	{ set_max_cstate, "IBM ThinkPad R40e", {
 	  DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
-	  DMI_MATCH(DMI_BIOS_VERSION,"1SET60WW") }},
-	{ no_c2c3, "Medion 41700", {
+	  DMI_MATCH(DMI_BIOS_VERSION,"1SET60WW") }, (void*)1},
+	{ set_max_cstate, "Medion 41700", {
 	  DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
-	  DMI_MATCH(DMI_BIOS_VERSION,"R01-A1J") }},
+	  DMI_MATCH(DMI_BIOS_VERSION,"R01-A1J") }, (void*)1},
+	{ set_max_cstate, "Clevo 5600D", {
+	  DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
+	  DMI_MATCH(DMI_BIOS_VERSION,"SHE845M0.86C.0013.D.0302131307") },
+	  (void*)2},
 	{},
 };
 
@@ -142,7 +146,7 @@ acpi_processor_power_activate (
 		switch (old->type) {
 		case ACPI_STATE_C3:
 			/* Disable bus master reload */
-			if (new->type != ACPI_STATE_C3)
+			if (new->type != ACPI_STATE_C3 && pr->flags.bm_check)
 				acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0, ACPI_MTX_DO_NOT_LOCK);
 			break;
 		}
@@ -152,7 +156,7 @@ acpi_processor_power_activate (
 	switch (new->type) {
 	case ACPI_STATE_C3:
 		/* Enable bus master reload */
-		if (old->type != ACPI_STATE_C3)
+		if (old->type != ACPI_STATE_C3 && pr->flags.bm_check)
 			acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 1, ACPI_MTX_DO_NOT_LOCK);
 		break;
 	}
@@ -163,6 +167,9 @@ acpi_processor_power_activate (
 }
 
 
+static atomic_t 	c3_cpu_count;
+
+
 static void acpi_processor_idle (void)
 {
 	struct acpi_processor	*pr = NULL;
@@ -171,7 +178,7 @@ static void acpi_processor_idle (void)
 	int			sleep_ticks = 0;
 	u32			t1, t2 = 0;
 
-	pr = processors[_smp_processor_id()];
+	pr = processors[raw_smp_processor_id()];
 	if (!pr)
 		return;
 
@@ -297,8 +304,22 @@ static void acpi_processor_idle (void)
 		break;
 
 	case ACPI_STATE_C3:
-		/* Disable bus master arbitration */
-		acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1, ACPI_MTX_DO_NOT_LOCK);
+		
+		if (pr->flags.bm_check) {
+			if (atomic_inc_return(&c3_cpu_count) ==
+					num_online_cpus()) {
+				/*
+				 * All CPUs are trying to go to C3
+				 * Disable bus master arbitration
+				 */
+				acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1,
+					ACPI_MTX_DO_NOT_LOCK);
+			}
+		} else {
+			/* SMP with no shared cache... Invalidate cache  */
+			ACPI_FLUSH_CPU_CACHE();
+		}
+		
 		/* Get start time (ticks) */
 		t1 = inl(acpi_fadt.xpm_tmr_blk.address);
 		/* Invoke C3 */
@@ -307,8 +328,12 @@ static void acpi_processor_idle (void)
 		t2 = inl(acpi_fadt.xpm_tmr_blk.address);
 		/* Get end time (ticks) */
 		t2 = inl(acpi_fadt.xpm_tmr_blk.address);
-		/* Enable bus master arbitration */
-		acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0, ACPI_MTX_DO_NOT_LOCK);
+		if (pr->flags.bm_check) {
+			/* Enable bus master arbitration */
+			atomic_dec(&c3_cpu_count);
+			acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0, ACPI_MTX_DO_NOT_LOCK);
+		}
+
 		/* Re-enable interrupts */
 		local_irq_enable();
 		/* Compute time (ticks) that we were actually asleep */
@@ -519,6 +544,30 @@ static int acpi_processor_get_power_info
 }
 
 
+static int acpi_processor_get_power_info_default_c1 (struct acpi_processor *pr)
+{
+	int i;
+
+	ACPI_FUNCTION_TRACE("acpi_processor_get_power_info_default_c1");
+
+	for (i = 0; i < ACPI_PROCESSOR_MAX_POWER; i++)
+		memset(&(pr->power.states[i]), 0, 
+		       sizeof(struct acpi_processor_cx));
+
+	/* if info is obtained from pblk/fadt, type equals state */
+	pr->power.states[ACPI_STATE_C1].type = ACPI_STATE_C1;
+	pr->power.states[ACPI_STATE_C2].type = ACPI_STATE_C2;
+	pr->power.states[ACPI_STATE_C3].type = ACPI_STATE_C3;
+
+	/* the C0 state only exists as a filler in our array,
+	 * and all processors need to support C1 */
+	pr->power.states[ACPI_STATE_C0].valid = 1;
+	pr->power.states[ACPI_STATE_C1].valid = 1;
+
+	return_VALUE(0);
+}
+
+
 static int acpi_processor_get_power_info_cst (struct acpi_processor *pr)
 {
 	acpi_status		status = 0;
@@ -529,15 +578,13 @@ static int acpi_processor_get_power_info
 
 	ACPI_FUNCTION_TRACE("acpi_processor_get_power_info_cst");
 
-	if (errata.smp)
-		return_VALUE(-ENODEV);
-
 	if (nocst)
 		return_VALUE(-ENODEV);
 
 	pr->power.count = 0;
 	for (i = 0; i < ACPI_PROCESSOR_MAX_POWER; i++)
-		memset(pr->power.states, 0, sizeof(struct acpi_processor_cx));
+		memset(&(pr->power.states[i]), 0, 
+		       sizeof(struct acpi_processor_cx));
 
 	status = acpi_evaluate_object(pr->handle, "_CST", NULL, &buffer);
 	if (ACPI_FAILURE(status)) {
@@ -664,13 +711,6 @@ static void acpi_processor_power_verify_
 		return_VOID;
 	}
 
-	/* We're (currently) only supporting C2 on UP */
-	else if (errata.smp) {
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-				  "C2 not supported in SMP mode\n"));
-		return_VOID;
-	}
-
 	/*
 	 * Otherwise we've met all of our C2 requirements.
 	 * Normalize the C2 latency to expidite policy
@@ -686,6 +726,8 @@ static void acpi_processor_power_verify_
 	struct acpi_processor *pr,
 	struct acpi_processor_cx *cx)
 {
+	static int bm_check_flag;
+
 	ACPI_FUNCTION_TRACE("acpi_processor_get_power_verify_c3");
 
 	if (!cx->address)
@@ -702,20 +744,6 @@ static void acpi_processor_power_verify_
 		return_VOID;
 	}
 
-	/* bus mastering control is necessary */
-	else if (!pr->flags.bm_control) {
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-				  "C3 support requires bus mastering control\n"));
-		return_VOID;
-	}
-
-	/* We're (currently) only supporting C2 on UP */
-	else if (errata.smp) {
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-				  "C3 not supported in SMP mode\n"));
-		return_VOID;
-	}
-
 	/*
 	 * PIIX4 Erratum #18: We don't support C3 when Type-F (fast)
 	 * DMA transfers are used by any ISA device to avoid livelock.
@@ -729,6 +757,37 @@ static void acpi_processor_power_verify_
 		return_VOID;
 	}
 
+	/* All the logic here assumes flags.bm_check is same across all CPUs */
+	if (!bm_check_flag) {
+		/* Determine whether bm_check is needed based on CPU  */
+		acpi_processor_power_init_bm_check(&(pr->flags), pr->id);
+		bm_check_flag = pr->flags.bm_check;
+	} else {
+		pr->flags.bm_check = bm_check_flag;
+	}
+
+	if (pr->flags.bm_check) {
+		/* bus mastering control is necessary */
+		if (!pr->flags.bm_control) {
+			ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+			  "C3 support requires bus mastering control\n"));
+			return_VOID;
+		}
+	} else {
+		/*
+		 * WBINVD should be set in fadt, for C3 state to be
+		 * supported on when bm_check is not required.
+		 */
+		if (acpi_fadt.wb_invd != 1) {
+			ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+			  "Cache invalidation should work properly"
+			  " for C3 to be enabled on SMP systems\n"));
+			return_VOID;
+		}
+		acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD,
+				0, ACPI_MTX_DO_NOT_LOCK);
+	}
+
 	/*
 	 * Otherwise we've met all of our C3 requirements.
 	 * Normalize the C3 latency to expidite policy.  Enable
@@ -737,7 +796,6 @@ static void acpi_processor_power_verify_
 	 */
 	cx->valid = 1;
 	cx->latency_ticks = US_TO_PM_TIMER_TICKS(cx->latency);
-	pr->flags.bm_check = 1;
 
 	return_VOID;
 }
@@ -786,11 +844,8 @@ static int acpi_processor_get_power_info
 	result = acpi_processor_get_power_info_cst(pr);
 	if ((result) || (acpi_processor_power_verify(pr) < 2)) {
 		result = acpi_processor_get_power_info_fadt(pr);
-		if (result)
-			return_VALUE(result);
-
-		if (acpi_processor_power_verify(pr) < 2)
-			return_VALUE(-ENODEV);
+		if ((result) || (acpi_processor_power_verify(pr) < 2))
+			result = acpi_processor_get_power_info_default_c1(pr);
 	}
 
 	/*
@@ -810,11 +865,10 @@ static int acpi_processor_get_power_info
 	 * CPU as being "idle manageable"
 	 */
 	for (i = 1; i < ACPI_PROCESSOR_MAX_POWER; i++) {
-		if (pr->power.states[i].valid)
+		if (pr->power.states[i].valid) {
 			pr->power.count = i;
-		if ((pr->power.states[i].valid) &&
-		    (pr->power.states[i].type >= ACPI_STATE_C2))
 			pr->flags.power = 1;
+		}
 	}
 
 	return_VALUE(0);
@@ -829,7 +883,7 @@ int acpi_processor_cst_has_changed (stru
 	if (!pr)
  		return_VALUE(-EINVAL);
 
-	if (errata.smp || nocst) {
+	if ( nocst) {
 		return_VALUE(-ENODEV);
 	}
 
@@ -929,7 +983,6 @@ static struct file_operations acpi_proce
 	.release	= single_release,
 };
 
-
 int acpi_processor_power_init(struct acpi_processor *pr, struct acpi_device *device)
 {
 	acpi_status		status = 0;
@@ -946,7 +999,10 @@ int acpi_processor_power_init(struct acp
 		first_run++;
 	}
 
-	if (!errata.smp && (pr->id == 0) && acpi_fadt.cst_cnt && !nocst) {
+	if (!pr)
+		return_VALUE(-EINVAL);
+
+	if (acpi_fadt.cst_cnt && !nocst) {
 		status = acpi_os_write_port(acpi_fadt.smi_cmd, acpi_fadt.cst_cnt, 8);
 		if (ACPI_FAILURE(status)) {
 			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
@@ -954,6 +1010,8 @@ int acpi_processor_power_init(struct acp
 		}
 	}
 
+	acpi_processor_power_init_pdc(&(pr->power), pr->id);
+	acpi_processor_set_pdc(pr, pr->power.pdc);
 	acpi_processor_get_power_info(pr);
 
 	/*
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c
--- a/drivers/acpi/processor_perflib.c
+++ b/drivers/acpi/processor_perflib.c
@@ -165,37 +165,6 @@ void acpi_processor_ppc_exit(void) {
 	acpi_processor_ppc_status &= ~PPC_REGISTERED;
 }
 
-/*
- * when registering a cpufreq driver with this ACPI processor driver, the
- * _PCT and _PSS structures are read out and written into struct
- * acpi_processor_performance.
- */
-static int acpi_processor_set_pdc (struct acpi_processor *pr)
-{
-	acpi_status             status = AE_OK;
-	u32			arg0_buf[3];
-	union acpi_object	arg0 = {ACPI_TYPE_BUFFER};
-	struct acpi_object_list no_object = {1, &arg0};
-	struct acpi_object_list *pdc;
-
-	ACPI_FUNCTION_TRACE("acpi_processor_set_pdc");
-
-	arg0.buffer.length = 12;
-	arg0.buffer.pointer = (u8 *) arg0_buf;
-	arg0_buf[0] = ACPI_PDC_REVISION_ID;
-	arg0_buf[1] = 0;
-	arg0_buf[2] = 0;
-
-	pdc = (pr->performance->pdc) ? pr->performance->pdc : &no_object;
-
-	status = acpi_evaluate_object(pr->handle, "_PDC", pdc, NULL);
-
-	if ((ACPI_FAILURE(status)) && (pr->performance->pdc))
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Error evaluating _PDC, using legacy perf. control...\n"));
-
-	return_VALUE(status);
-}
-
 
 static int
 acpi_processor_get_performance_control (
@@ -357,7 +326,7 @@ acpi_processor_get_performance_info (
 	if (!pr || !pr->performance || !pr->handle)
 		return_VALUE(-EINVAL);
 
-	acpi_processor_set_pdc(pr);
+	acpi_processor_set_pdc(pr, pr->performance->pdc);
 
 	status = acpi_get_handle(pr->handle, "_PCT", &handle);
 	if (ACPI_FAILURE(status)) {
diff --git a/drivers/acpi/resources/rsaddr.c b/drivers/acpi/resources/rsaddr.c
--- a/drivers/acpi/resources/rsaddr.c
+++ b/drivers/acpi/resources/rsaddr.c
@@ -77,21 +77,21 @@ acpi_rs_address16_resource (
 	u8                              **output_buffer,
 	acpi_size                       *structure_size)
 {
-	u8                              *buffer = byte_stream_buffer;
-	struct acpi_resource            *output_struct = (void *) *output_buffer;
-	u8                              *temp_ptr;
-	acpi_size                       struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_address16);
 	u32                             index;
 	u16                             temp16;
 	u8                              temp8;
+	u8                              *temp_ptr;
+	u8                              *buffer = byte_stream_buffer;
+	struct acpi_resource            *output_struct = (void *) *output_buffer;
+	acpi_size                       struct_size = ACPI_SIZEOF_RESOURCE (
+			  struct acpi_resource_address16);
 
 
 	ACPI_FUNCTION_TRACE ("rs_address16_resource");
 
 
-	/*
-	 * Point past the Descriptor to get the number of bytes consumed
-	 */
+	/* Point past the Descriptor to get the number of bytes consumed */
+
 	buffer += 1;
 	ACPI_MOVE_16_TO_16 (&temp16, buffer);
 
@@ -104,9 +104,8 @@ acpi_rs_address16_resource (
 	*bytes_consumed = temp16 + 3;
 	output_struct->id = ACPI_RSTYPE_ADDRESS16;
 
-	/*
-	 * Get the Resource Type (Byte3)
-	 */
+	/* Get the Resource Type (Byte3) */
+
 	buffer += 2;
 	temp8 = *buffer;
 
@@ -118,9 +117,8 @@ acpi_rs_address16_resource (
 
 	output_struct->data.address16.resource_type = temp8;
 
-	/*
-	 * Get the General Flags (Byte4)
-	 */
+	/* Get the General Flags (Byte4) */
+
 	buffer += 1;
 	temp8 = *buffer;
 
@@ -140,9 +138,8 @@ acpi_rs_address16_resource (
 
 	output_struct->data.address16.max_address_fixed = (temp8 >> 3) & 0x01;
 
-	/*
-	 * Get the Type Specific Flags (Byte5)
-	 */
+	/* Get the Type Specific Flags (Byte5) */
+
 	buffer += 1;
 	temp8 = *buffer;
 
@@ -165,39 +162,34 @@ acpi_rs_address16_resource (
 		}
 	}
 
-	/*
-	 * Get Granularity (Bytes 6-7)
-	 */
+	/* Get Granularity (Bytes 6-7) */
+
 	buffer += 1;
 	ACPI_MOVE_16_TO_32 (&output_struct->data.address16.granularity, buffer);
 
-	/*
-	 * Get min_address_range (Bytes 8-9)
-	 */
+	/* Get min_address_range (Bytes 8-9) */
+
 	buffer += 2;
 	ACPI_MOVE_16_TO_32 (&output_struct->data.address16.min_address_range, buffer);
 
-	/*
-	 * Get max_address_range (Bytes 10-11)
-	 */
+	/* Get max_address_range (Bytes 10-11) */
+
 	buffer += 2;
 	ACPI_MOVE_16_TO_32 (&output_struct->data.address16.max_address_range, buffer);
 
-	/*
-	 * Get address_translation_offset (Bytes 12-13)
-	 */
+	/* Get address_translation_offset (Bytes 12-13) */
+
 	buffer += 2;
-	ACPI_MOVE_16_TO_32 (&output_struct->data.address16.address_translation_offset, buffer);
+	ACPI_MOVE_16_TO_32 (&output_struct->data.address16.address_translation_offset,
+		buffer);
+
+	/* Get address_length (Bytes 14-15) */
 
-	/*
-	 * Get address_length (Bytes 14-15)
-	 */
 	buffer += 2;
 	ACPI_MOVE_16_TO_32 (&output_struct->data.address16.address_length, buffer);
 
-	/*
-	 * Resource Source Index (if present)
-	 */
+	/* Resource Source Index (if present) */
+
 	buffer += 2;
 
 	/*
@@ -225,7 +217,8 @@ acpi_rs_address16_resource (
 		output_struct->data.address16.resource_source.string_ptr =
 				(char *)((u8 * )output_struct + struct_size);
 
-		temp_ptr = (u8 *) output_struct->data.address16.resource_source.string_ptr;
+		temp_ptr = (u8 *)
+			output_struct->data.address16.resource_source.string_ptr;
 
 		/* Copy the string into the buffer */
 
@@ -239,9 +232,8 @@ acpi_rs_address16_resource (
 			index += 1;
 		}
 
-		/*
-		 * Add the terminating null
-		 */
+		/* Add the terminating null */
+
 		*temp_ptr = 0x00;
 
 		output_struct->data.address16.resource_source.string_length = index + 1;
@@ -260,14 +252,12 @@ acpi_rs_address16_resource (
 		output_struct->data.address16.resource_source.string_ptr = NULL;
 	}
 
-	/*
-	 * Set the Length parameter
-	 */
+	/* Set the Length parameter */
+
 	output_struct->length = (u32) struct_size;
 
-	/*
-	 * Return the final size of the structure
-	 */
+	/* Return the final size of the structure */
+
 	*structure_size = struct_size;
 	return_ACPI_STATUS (AE_OK);
 }
@@ -305,28 +295,24 @@ acpi_rs_address16_stream (
 	ACPI_FUNCTION_TRACE ("rs_address16_stream");
 
 
-	/*
-	 * The descriptor field is static
-	 */
+	/* The descriptor field is static */
+
 	*buffer = 0x88;
 	buffer += 1;
 
-	/*
-	 * Save a pointer to the Length field - to be filled in later
-	 */
+	/* Save a pointer to the Length field - to be filled in later */
+
 	length_field = buffer;
 	buffer += 2;
 
-	/*
-	 * Set the Resource Type (Memory, Io, bus_number)
-	 */
+	/* Set the Resource Type (Memory, Io, bus_number) */
+
 	temp8 = (u8) (linked_list->data.address16.resource_type & 0x03);
 	*buffer = temp8;
 	buffer += 1;
 
-	/*
-	 * Set the general flags
-	 */
+	/* Set the general flags */
+
 	temp8 = (u8) (linked_list->data.address16.producer_consumer & 0x01);
 
 	temp8 |= (linked_list->data.address16.decode & 0x01) << 1;
@@ -336,9 +322,8 @@ acpi_rs_address16_stream (
 	*buffer = temp8;
 	buffer += 1;
 
-	/*
-	 * Set the type specific flags
-	 */
+	/* Set the type specific flags */
+
 	temp8 = 0;
 
 	if (ACPI_MEMORY_RANGE == linked_list->data.address16.resource_type) {
@@ -362,39 +347,34 @@ acpi_rs_address16_stream (
 	*buffer = temp8;
 	buffer += 1;
 
-	/*
-	 * Set the address space granularity
-	 */
+	/* Set the address space granularity */
+
 	ACPI_MOVE_32_TO_16 (buffer, &linked_list->data.address16.granularity);
 	buffer += 2;
 
-	/*
-	 * Set the address range minimum
-	 */
+	/* Set the address range minimum */
+
 	ACPI_MOVE_32_TO_16 (buffer, &linked_list->data.address16.min_address_range);
 	buffer += 2;
 
-	/*
-	 * Set the address range maximum
-	 */
+	/* Set the address range maximum */
+
 	ACPI_MOVE_32_TO_16 (buffer, &linked_list->data.address16.max_address_range);
 	buffer += 2;
 
-	/*
-	 * Set the address translation offset
-	 */
-	ACPI_MOVE_32_TO_16 (buffer, &linked_list->data.address16.address_translation_offset);
+	/* Set the address translation offset */
+
+	ACPI_MOVE_32_TO_16 (buffer,
+		&linked_list->data.address16.address_translation_offset);
 	buffer += 2;
 
-	/*
-	 * Set the address length
-	 */
+	/* Set the address length */
+
 	ACPI_MOVE_32_TO_16 (buffer, &linked_list->data.address16.address_length);
 	buffer += 2;
 
-	/*
-	 * Resource Source Index and Resource Source are optional
-	 */
+	/* Resource Source Index and Resource Source are optional */
+
 	if (0 != linked_list->data.address16.resource_source.string_length) {
 		temp8 = (u8) linked_list->data.address16.resource_source.index;
 
@@ -403,9 +383,8 @@ acpi_rs_address16_stream (
 
 		temp_pointer = (char *) buffer;
 
-		/*
-		 * Copy the string
-		 */
+		/* Copy the string */
+
 		ACPI_STRCPY (temp_pointer,
 				linked_list->data.address16.resource_source.string_ptr);
 
@@ -413,12 +392,12 @@ acpi_rs_address16_stream (
 		 * Buffer needs to be set to the length of the sting + one for the
 		 * terminating null
 		 */
-		buffer += (acpi_size)(ACPI_STRLEN (linked_list->data.address16.resource_source.string_ptr) + 1);
+		buffer += (acpi_size)(ACPI_STRLEN (
+				 linked_list->data.address16.resource_source.string_ptr) + 1);
 	}
 
-	/*
-	 * Return the number of bytes consumed in this operation
-	 */
+	/* Return the number of bytes consumed in this operation */
+
 	actual_bytes = ACPI_PTR_DIFF (buffer, *output_buffer);
 	*bytes_consumed = actual_bytes;
 
@@ -475,9 +454,8 @@ acpi_rs_address32_resource (
 	buffer = byte_stream_buffer;
 	struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_address32);
 
-	/*
-	 * Point past the Descriptor to get the number of bytes consumed
-	 */
+	/* Point past the Descriptor to get the number of bytes consumed */
+
 	buffer += 1;
 	ACPI_MOVE_16_TO_16 (&temp16, buffer);
 
@@ -490,9 +468,8 @@ acpi_rs_address32_resource (
 	*bytes_consumed = temp16 + 3;
 	output_struct->id = ACPI_RSTYPE_ADDRESS32;
 
-	/*
-	 * Get the Resource Type (Byte3)
-	 */
+	/* Get the Resource Type (Byte3) */
+
 	buffer += 2;
 	temp8 = *buffer;
 
@@ -504,35 +481,29 @@ acpi_rs_address32_resource (
 
 	output_struct->data.address32.resource_type = temp8;
 
-	/*
-	 * Get the General Flags (Byte4)
-	 */
+	/* Get the General Flags (Byte4) */
+
 	buffer += 1;
 	temp8 = *buffer;
 
-	/*
-	 * Producer / Consumer
-	 */
+	/* Producer / Consumer */
+
 	output_struct->data.address32.producer_consumer = temp8 & 0x01;
 
-	/*
-	 * Decode
-	 */
+	/* Decode */
+
 	output_struct->data.address32.decode = (temp8 >> 1) & 0x01;
 
-	/*
-	 * Min Address Fixed
-	 */
+	/* Min Address Fixed */
+
 	output_struct->data.address32.min_address_fixed = (temp8 >> 2) & 0x01;
 
-	/*
-	 * Max Address Fixed
-	 */
+	/* Max Address Fixed */
+
 	output_struct->data.address32.max_address_fixed = (temp8 >> 3) & 0x01;
 
-	/*
-	 * Get the Type Specific Flags (Byte5)
-	 */
+	/* Get the Type Specific Flags (Byte5) */
+
 	buffer += 1;
 	temp8 = *buffer;
 
@@ -556,39 +527,34 @@ acpi_rs_address32_resource (
 		}
 	}
 
-	/*
-	 * Get Granularity (Bytes 6-9)
-	 */
+	/* Get Granularity (Bytes 6-9) */
+
 	buffer += 1;
 	ACPI_MOVE_32_TO_32 (&output_struct->data.address32.granularity, buffer);
 
-	/*
-	 * Get min_address_range (Bytes 10-13)
-	 */
+	/* Get min_address_range (Bytes 10-13) */
+
 	buffer += 4;
 	ACPI_MOVE_32_TO_32 (&output_struct->data.address32.min_address_range, buffer);
 
-	/*
-	 * Get max_address_range (Bytes 14-17)
-	 */
+	/* Get max_address_range (Bytes 14-17) */
+
 	buffer += 4;
 	ACPI_MOVE_32_TO_32 (&output_struct->data.address32.max_address_range, buffer);
 
-	/*
-	 * Get address_translation_offset (Bytes 18-21)
-	 */
+	/* Get address_translation_offset (Bytes 18-21) */
+
 	buffer += 4;
-	ACPI_MOVE_32_TO_32 (&output_struct->data.address32.address_translation_offset, buffer);
+	ACPI_MOVE_32_TO_32 (&output_struct->data.address32.address_translation_offset,
+		buffer);
+
+	/* Get address_length (Bytes 22-25) */
 
-	/*
-	 * Get address_length (Bytes 22-25)
-	 */
 	buffer += 4;
 	ACPI_MOVE_32_TO_32 (&output_struct->data.address32.address_length, buffer);
 
-	/*
-	 * Resource Source Index (if present)
-	 */
+	/* Resource Source Index (if present) */
+
 	buffer += 4;
 
 	/*
@@ -615,7 +581,8 @@ acpi_rs_address32_resource (
 		output_struct->data.address32.resource_source.string_ptr =
 				(char *)((u8 *)output_struct + struct_size);
 
-		temp_ptr = (u8 *) output_struct->data.address32.resource_source.string_ptr;
+		temp_ptr = (u8 *)
+			output_struct->data.address32.resource_source.string_ptr;
 
 		/* Copy the string into the buffer */
 
@@ -628,9 +595,8 @@ acpi_rs_address32_resource (
 			index += 1;
 		}
 
-		/*
-		 * Add the terminating null
-		 */
+		/* Add the terminating null */
+
 		*temp_ptr = 0x00;
 		output_struct->data.address32.resource_source.string_length = index + 1;
 
@@ -648,14 +614,12 @@ acpi_rs_address32_resource (
 		output_struct->data.address32.resource_source.string_ptr = NULL;
 	}
 
-	/*
-	 * Set the Length parameter
-	 */
+	/* Set the Length parameter */
+
 	output_struct->length = (u32) struct_size;
 
-	/*
-	 * Return the final size of the structure
-	 */
+	/* Return the final size of the structure */
+
 	*structure_size = struct_size;
 	return_ACPI_STATUS (AE_OK);
 }
@@ -694,29 +658,25 @@ acpi_rs_address32_stream (
 
 	buffer = *output_buffer;
 
-	/*
-	 * The descriptor field is static
-	 */
+	/* The descriptor field is static */
+
 	*buffer = 0x87;
 	buffer += 1;
 
-	/*
-	 * Set a pointer to the Length field - to be filled in later
-	 */
+	/* Set a pointer to the Length field - to be filled in later */
+
 	length_field = ACPI_CAST_PTR (u16, buffer);
 	buffer += 2;
 
-	/*
-	 * Set the Resource Type (Memory, Io, bus_number)
-	 */
+	/* Set the Resource Type (Memory, Io, bus_number) */
+
 	temp8 = (u8) (linked_list->data.address32.resource_type & 0x03);
 
 	*buffer = temp8;
 	buffer += 1;
 
-	/*
-	 * Set the general flags
-	 */
+	/* Set the general flags */
+
 	temp8 = (u8) (linked_list->data.address32.producer_consumer & 0x01);
 	temp8 |= (linked_list->data.address32.decode & 0x01) << 1;
 	temp8 |= (linked_list->data.address32.min_address_fixed & 0x01) << 2;
@@ -725,9 +685,8 @@ acpi_rs_address32_stream (
 	*buffer = temp8;
 	buffer += 1;
 
-	/*
-	 * Set the type specific flags
-	 */
+	/* Set the type specific flags */
+
 	temp8 = 0;
 
 	if (ACPI_MEMORY_RANGE == linked_list->data.address32.resource_type) {
@@ -751,39 +710,34 @@ acpi_rs_address32_stream (
 	*buffer = temp8;
 	buffer += 1;
 
-	/*
-	 * Set the address space granularity
-	 */
+	/* Set the address space granularity */
+
 	ACPI_MOVE_32_TO_32 (buffer, &linked_list->data.address32.granularity);
 	buffer += 4;
 
-	/*
-	 * Set the address range minimum
-	 */
+	/* Set the address range minimum */
+
 	ACPI_MOVE_32_TO_32 (buffer, &linked_list->data.address32.min_address_range);
 	buffer += 4;
 
-	/*
-	 * Set the address range maximum
-	 */
+	/* Set the address range maximum */
+
 	ACPI_MOVE_32_TO_32 (buffer, &linked_list->data.address32.max_address_range);
 	buffer += 4;
 
-	/*
-	 * Set the address translation offset
-	 */
-	ACPI_MOVE_32_TO_32 (buffer, &linked_list->data.address32.address_translation_offset);
+	/* Set the address translation offset */
+
+	ACPI_MOVE_32_TO_32 (buffer,
+		&linked_list->data.address32.address_translation_offset);
 	buffer += 4;
 
-	/*
-	 * Set the address length
-	 */
+	/* Set the address length */
+
 	ACPI_MOVE_32_TO_32 (buffer, &linked_list->data.address32.address_length);
 	buffer += 4;
 
-	/*
-	 * Resource Source Index and Resource Source are optional
-	 */
+	/* Resource Source Index and Resource Source are optional */
+
 	if (0 != linked_list->data.address32.resource_source.string_length) {
 		temp8 = (u8) linked_list->data.address32.resource_source.index;
 
@@ -792,9 +746,8 @@ acpi_rs_address32_stream (
 
 		temp_pointer = (char *) buffer;
 
-		/*
-		 * Copy the string
-		 */
+		/* Copy the string */
+
 		ACPI_STRCPY (temp_pointer,
 			linked_list->data.address32.resource_source.string_ptr);
 
@@ -802,12 +755,12 @@ acpi_rs_address32_stream (
 		 * Buffer needs to be set to the length of the sting + one for the
 		 *  terminating null
 		 */
-		buffer += (acpi_size)(ACPI_STRLEN (linked_list->data.address32.resource_source.string_ptr) + 1);
+		buffer += (acpi_size)(ACPI_STRLEN (
+				 linked_list->data.address32.resource_source.string_ptr) + 1);
 	}
 
-	/*
-	 * Return the number of bytes consumed in this operation
-	 */
+	/* Return the number of bytes consumed in this operation */
+
 	*bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer);
 
 	/*
@@ -864,9 +817,8 @@ acpi_rs_address64_resource (
 	struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_address64);
 	resource_type = *buffer;
 
-	/*
-	 * Point past the Descriptor to get the number of bytes consumed
-	 */
+	/* Point past the Descriptor to get the number of bytes consumed */
+
 	buffer += 1;
 	ACPI_MOVE_16_TO_16 (&temp16, buffer);
 
@@ -879,9 +831,8 @@ acpi_rs_address64_resource (
 	*bytes_consumed = temp16 + 3;
 	output_struct->id = ACPI_RSTYPE_ADDRESS64;
 
-	/*
-	 * Get the Resource Type (Byte3)
-	 */
+	/* Get the Resource Type (Byte3) */
+
 	buffer += 2;
 	temp8 = *buffer;
 
@@ -893,35 +844,29 @@ acpi_rs_address64_resource (
 
 	output_struct->data.address64.resource_type = temp8;
 
-	/*
-	 * Get the General Flags (Byte4)
-	 */
+	/* Get the General Flags (Byte4) */
+
 	buffer += 1;
 	temp8 = *buffer;
 
-	/*
-	 * Producer / Consumer
-	 */
+	/* Producer / Consumer */
+
 	output_struct->data.address64.producer_consumer = temp8 & 0x01;
 
-	/*
-	 * Decode
-	 */
+	/* Decode */
+
 	output_struct->data.address64.decode = (temp8 >> 1) & 0x01;
 
-	/*
-	 * Min Address Fixed
-	 */
+	/* Min Address Fixed */
+
 	output_struct->data.address64.min_address_fixed = (temp8 >> 2) & 0x01;
 
-	/*
-	 * Max Address Fixed
-	 */
+	/* Max Address Fixed */
+
 	output_struct->data.address64.max_address_fixed = (temp8 >> 3) & 0x01;
 
-	/*
-	 * Get the Type Specific Flags (Byte5)
-	 */
+	/* Get the Type Specific Flags (Byte5) */
+
 	buffer += 1;
 	temp8 = *buffer;
 
@@ -951,33 +896,29 @@ acpi_rs_address64_resource (
 		buffer += 2;
 	}
 
-	/*
-	 * Get Granularity (Bytes 6-13) or (Bytes 8-15)
-	 */
+	/* Get Granularity (Bytes 6-13) or (Bytes 8-15) */
+
 	buffer += 1;
 	ACPI_MOVE_64_TO_64 (&output_struct->data.address64.granularity, buffer);
 
-	/*
-	 * Get min_address_range (Bytes 14-21) or (Bytes 16-23)
-	 */
+	/* Get min_address_range (Bytes 14-21) or (Bytes 16-23) */
+
 	buffer += 8;
 	ACPI_MOVE_64_TO_64 (&output_struct->data.address64.min_address_range, buffer);
 
-	/*
-	 * Get max_address_range (Bytes 22-29) or (Bytes 24-31)
-	 */
+	/* Get max_address_range (Bytes 22-29) or (Bytes 24-31) */
+
 	buffer += 8;
 	ACPI_MOVE_64_TO_64 (&output_struct->data.address64.max_address_range, buffer);
 
-	/*
-	 * Get address_translation_offset (Bytes 30-37) or (Bytes 32-39)
-	 */
+	/* Get address_translation_offset (Bytes 30-37) or (Bytes 32-39) */
+
 	buffer += 8;
-	ACPI_MOVE_64_TO_64 (&output_struct->data.address64.address_translation_offset, buffer);
+	ACPI_MOVE_64_TO_64 (&output_struct->data.address64.address_translation_offset,
+		buffer);
+
+	/* Get address_length (Bytes 38-45) or (Bytes 40-47) */
 
-	/*
-	 * Get address_length (Bytes 38-45) or (Bytes 40-47)
-	 */
 	buffer += 8;
 	ACPI_MOVE_64_TO_64 (&output_struct->data.address64.address_length, buffer);
 
@@ -989,14 +930,15 @@ acpi_rs_address64_resource (
 		/* Get type_specific_attribute (Bytes 48-55) */
 
 		buffer += 8;
-		ACPI_MOVE_64_TO_64 (&output_struct->data.address64.type_specific_attributes, buffer);
+		ACPI_MOVE_64_TO_64 (
+			&output_struct->data.address64.type_specific_attributes,
+			buffer);
 	}
 	else {
 		output_struct->data.address64.type_specific_attributes = 0;
 
-		/*
-		 * Resource Source Index (if present)
-		 */
+		/* Resource Source Index (if present) */
+
 		buffer += 8;
 
 		/*
@@ -1025,7 +967,8 @@ acpi_rs_address64_resource (
 			output_struct->data.address64.resource_source.string_ptr =
 					(char *)((u8 *)output_struct + struct_size);
 
-			temp_ptr = (u8 *) output_struct->data.address64.resource_source.string_ptr;
+			temp_ptr = (u8 *)
+				output_struct->data.address64.resource_source.string_ptr;
 
 			/* Copy the string into the buffer */
 
@@ -1042,7 +985,8 @@ acpi_rs_address64_resource (
 			 * Add the terminating null
 			 */
 			*temp_ptr = 0x00;
-			output_struct->data.address64.resource_source.string_length = index + 1;
+			output_struct->data.address64.resource_source.string_length =
+				index + 1;
 
 			/*
 			 * In order for the struct_size to fall on a 32-bit boundary,
@@ -1054,14 +998,12 @@ acpi_rs_address64_resource (
 		}
 	}
 
-	/*
-	 * Set the Length parameter
-	 */
+	/* Set the Length parameter */
+
 	output_struct->length = (u32) struct_size;
 
-	/*
-	 * Return the final size of the structure
-	 */
+	/* Return the final size of the structure */
+
 	*structure_size = struct_size;
 	return_ACPI_STATUS (AE_OK);
 }
@@ -1100,29 +1042,25 @@ acpi_rs_address64_stream (
 
 	buffer = *output_buffer;
 
-	/*
-	 * The descriptor field is static
-	 */
+	/* The descriptor field is static */
+
 	*buffer = 0x8A;
 	buffer += 1;
 
-	/*
-	 * Set a pointer to the Length field - to be filled in later
-	 */
+	/* Set a pointer to the Length field - to be filled in later */
+
 	length_field = ACPI_CAST_PTR (u16, buffer);
 	buffer += 2;
 
-	/*
-	 * Set the Resource Type (Memory, Io, bus_number)
-	 */
+	/* Set the Resource Type (Memory, Io, bus_number) */
+
 	temp8 = (u8) (linked_list->data.address64.resource_type & 0x03);
 
 	*buffer = temp8;
 	buffer += 1;
 
-	/*
-	 * Set the general flags
-	 */
+	/* Set the general flags */
+
 	temp8 = (u8) (linked_list->data.address64.producer_consumer & 0x01);
 	temp8 |= (linked_list->data.address64.decode & 0x01) << 1;
 	temp8 |= (linked_list->data.address64.min_address_fixed & 0x01) << 2;
@@ -1131,9 +1069,8 @@ acpi_rs_address64_stream (
 	*buffer = temp8;
 	buffer += 1;
 
-	/*
-	 * Set the type specific flags
-	 */
+	/* Set the type specific flags */
+
 	temp8 = 0;
 
 	if (ACPI_MEMORY_RANGE == linked_list->data.address64.resource_type) {
@@ -1157,39 +1094,34 @@ acpi_rs_address64_stream (
 	*buffer = temp8;
 	buffer += 1;
 
-	/*
-	 * Set the address space granularity
-	 */
+	/* Set the address space granularity */
+
 	ACPI_MOVE_64_TO_64 (buffer, &linked_list->data.address64.granularity);
 	buffer += 8;
 
-	/*
-	 * Set the address range minimum
-	 */
+	/* Set the address range minimum */
+
 	ACPI_MOVE_64_TO_64 (buffer, &linked_list->data.address64.min_address_range);
 	buffer += 8;
 
-	/*
-	 * Set the address range maximum
-	 */
+	/* Set the address range maximum */
+
 	ACPI_MOVE_64_TO_64 (buffer, &linked_list->data.address64.max_address_range);
 	buffer += 8;
 
-	/*
-	 * Set the address translation offset
-	 */
-	ACPI_MOVE_64_TO_64 (buffer, &linked_list->data.address64.address_translation_offset);
+	/* Set the address translation offset */
+
+	ACPI_MOVE_64_TO_64 (buffer,
+		&linked_list->data.address64.address_translation_offset);
 	buffer += 8;
 
-	/*
-	 * Set the address length
-	 */
+	/* Set the address length */
+
 	ACPI_MOVE_64_TO_64 (buffer, &linked_list->data.address64.address_length);
 	buffer += 8;
 
-	/*
-	 * Resource Source Index and Resource Source are optional
-	 */
+	/* Resource Source Index and Resource Source are optional */
+
 	if (0 != linked_list->data.address64.resource_source.string_length) {
 		temp8 = (u8) linked_list->data.address64.resource_source.index;
 
@@ -1198,21 +1130,21 @@ acpi_rs_address64_stream (
 
 		temp_pointer = (char *) buffer;
 
-		/*
-		 * Copy the string
-		 */
-		ACPI_STRCPY (temp_pointer, linked_list->data.address64.resource_source.string_ptr);
+		/* Copy the string */
+
+		ACPI_STRCPY (temp_pointer,
+			linked_list->data.address64.resource_source.string_ptr);
 
 		/*
 		 * Buffer needs to be set to the length of the sting + one for the
 		 * terminating null
 		 */
-		buffer += (acpi_size)(ACPI_STRLEN (linked_list->data.address64.resource_source.string_ptr) + 1);
+		buffer += (acpi_size)(ACPI_STRLEN (
+				 linked_list->data.address64.resource_source.string_ptr) + 1);
 	}
 
-	/*
-	 * Return the number of bytes consumed in this operation
-	 */
+	/* Return the number of bytes consumed in this operation */
+
 	*bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer);
 
 	/*
diff --git a/drivers/acpi/resources/rscalc.c b/drivers/acpi/resources/rscalc.c
--- a/drivers/acpi/resources/rscalc.c
+++ b/drivers/acpi/resources/rscalc.c
@@ -81,9 +81,8 @@ acpi_rs_get_byte_stream_length (
 
 
 	while (!done) {
-		/*
-		 * Init the variable that will hold the size to add to the total.
-		 */
+		/* Init the variable that will hold the size to add to the total. */
+
 		segment_size = 0;
 
 		switch (linked_list->id) {
@@ -196,7 +195,8 @@ acpi_rs_get_byte_stream_length (
 			segment_size = 16;
 
 			if (linked_list->data.address16.resource_source.string_ptr) {
-				segment_size += linked_list->data.address16.resource_source.string_length;
+				segment_size +=
+					linked_list->data.address16.resource_source.string_length;
 				segment_size++;
 			}
 			break;
@@ -212,7 +212,8 @@ acpi_rs_get_byte_stream_length (
 			segment_size = 26;
 
 			if (linked_list->data.address32.resource_source.string_ptr) {
-				segment_size += linked_list->data.address32.resource_source.string_length;
+				segment_size +=
+					linked_list->data.address32.resource_source.string_length;
 				segment_size++;
 			}
 			break;
@@ -227,7 +228,8 @@ acpi_rs_get_byte_stream_length (
 			segment_size = 46;
 
 			if (linked_list->data.address64.resource_source.string_ptr) {
-				segment_size += linked_list->data.address64.resource_source.string_length;
+				segment_size +=
+					linked_list->data.address64.resource_source.string_length;
 				segment_size++;
 			}
 			break;
@@ -241,38 +243,36 @@ acpi_rs_get_byte_stream_length (
 			 * Index + the length of the null terminated string
 			 * Resource Source + 1 for the null.
 			 */
-			segment_size = 9 +
-				(((acpi_size) linked_list->data.extended_irq.number_of_interrupts - 1) * 4);
+			segment_size = 9 + (((acpi_size)
+				linked_list->data.extended_irq.number_of_interrupts - 1) * 4);
 
 			if (linked_list->data.extended_irq.resource_source.string_ptr) {
-				segment_size += linked_list->data.extended_irq.resource_source.string_length;
+				segment_size +=
+					linked_list->data.extended_irq.resource_source.string_length;
 				segment_size++;
 			}
 			break;
 
 		default:
-			/*
-			 * If we get here, everything is out of sync, exit with error
-			 */
+
+			/* If we get here, everything is out of sync, exit with error */
+
 			return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE);
 
 		} /* switch (linked_list->Id) */
 
-		/*
-		 * Update the total
-		 */
+		/* Update the total */
+
 		byte_stream_size_needed += segment_size;
 
-		/*
-		 * Point to the next object
-		 */
+		/* Point to the next object */
+
 		linked_list = ACPI_PTR_ADD (struct acpi_resource,
 				  linked_list, linked_list->length);
 	}
 
-	/*
-	 * This is the data the caller needs
-	 */
+	/* This is the data the caller needs */
+
 	*size_needed = byte_stream_size_needed;
 	return_ACPI_STATUS (AE_OK);
 }
@@ -320,9 +320,8 @@ acpi_rs_get_list_length (
 
 
 	while (bytes_parsed < byte_stream_buffer_length) {
-		/*
-		 * The next byte in the stream is the resource type
-		 */
+		/* The next byte in the stream is the resource type */
+
 		resource_type = acpi_rs_get_resource_type (*byte_stream_buffer);
 
 		switch (resource_type) {
@@ -346,9 +345,8 @@ acpi_rs_get_list_length (
 			ACPI_MOVE_16_TO_16 (&temp16, buffer);
 			bytes_consumed = temp16 + 3;
 
-			/*
-			 * Ensure a 32-bit boundary for the structure
-			 */
+			/* Ensure a 32-bit boundary for the structure */
+
 			temp16 = (u16) ACPI_ROUND_UP_to_32_bITS (temp16);
 
 			structure_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_vendor) +
@@ -416,9 +414,8 @@ acpi_rs_get_list_length (
 				temp8 = 0;
 			}
 
-			/*
-			 * Ensure a 64-bit boundary for the structure
-			 */
+			/* Ensure a 64-bit boundary for the structure */
+
 			temp8 = (u8) ACPI_ROUND_UP_to_64_bITS (temp8);
 
 			structure_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_address64) +
@@ -452,9 +449,8 @@ acpi_rs_get_list_length (
 				temp8 = 0;
 			}
 
-			/*
-			 * Ensure a 32-bit boundary for the structure
-			 */
+			/* Ensure a 32-bit boundary for the structure */
+
 			temp8 = (u8) ACPI_ROUND_UP_to_32_bITS (temp8);
 
 			structure_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_address32) +
@@ -488,9 +484,8 @@ acpi_rs_get_list_length (
 				temp8 = 0;
 			}
 
-			/*
-			 * Ensure a 32-bit boundary for the structure
-			 */
+			/* Ensure a 32-bit boundary for the structure */
+
 			temp8 = (u8) ACPI_ROUND_UP_to_32_bITS (temp8);
 
 			structure_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_address16) +
@@ -537,9 +532,8 @@ acpi_rs_get_list_length (
 				temp8 = 0;
 			}
 
-			/*
-			 * Ensure a 32-bit boundary for the structure
-			 */
+			/* Ensure a 32-bit boundary for the structure */
+
 			temp8 = (u8) ACPI_ROUND_UP_to_32_bITS (temp8);
 
 			structure_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_ext_irq) +
@@ -567,9 +561,8 @@ acpi_rs_get_list_length (
 
 			++buffer;
 
-			/*
-			 * Look at the number of bits set
-			 */
+			/* Look at the number of bits set */
+
 			ACPI_MOVE_16_TO_16 (&temp16, buffer);
 
 			for (index = 0; index < 16; index++) {
@@ -596,9 +589,8 @@ acpi_rs_get_list_length (
 
 			++buffer;
 
-			/*
-			 * Look at the number of bits set
-			 */
+			/* Look at the number of bits set */
+
 			temp8 = *buffer;
 
 			for(index = 0; index < 8; index++) {
@@ -670,9 +662,8 @@ acpi_rs_get_list_length (
 			temp8 = (u8) (temp8 & 0x7);
 			bytes_consumed = temp8 + 1;
 
-			/*
-			 * Ensure a 32-bit boundary for the structure
-			 */
+			/* Ensure a 32-bit boundary for the structure */
+
 			temp8 = (u8) ACPI_ROUND_UP_to_32_bITS (temp8);
 			structure_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_vendor) +
 					   (temp8 * sizeof (u8));
@@ -697,21 +688,18 @@ acpi_rs_get_list_length (
 			return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE);
 		}
 
-		/*
-		 * Update the return value and counter
-		 */
+		/* Update the return value and counter */
+
 		buffer_size += (u32) ACPI_ALIGN_RESOURCE_SIZE (structure_size);
 		bytes_parsed += bytes_consumed;
 
-		/*
-		 * Set the byte stream to point to the next resource
-		 */
+		/* Set the byte stream to point to the next resource */
+
 		byte_stream_buffer += bytes_consumed;
 	}
 
-	/*
-	 * This is the data the caller needs
-	 */
+	/* This is the data the caller needs */
+
 	*size_needed = buffer_size;
 	return_ACPI_STATUS (AE_OK);
 }
@@ -767,9 +755,8 @@ acpi_rs_get_pci_routing_table_length (
 	top_object_list = package_object->package.elements;
 
 	for (index = 0; index < number_of_elements; index++) {
-		/*
-		 * Dereference the sub-package
-		 */
+		/* Dereference the sub-package */
+
 		package_element = *top_object_list;
 
 		/*
@@ -778,37 +765,40 @@ acpi_rs_get_pci_routing_table_length (
 		 */
 		sub_object_list = package_element->package.elements;
 
-		/*
-		 * Scan the irq_table_elements for the Source Name String
-		 */
+		/* Scan the irq_table_elements for the Source Name String */
+
 		name_found = FALSE;
 
 		for (table_index = 0; table_index < 4 && !name_found; table_index++) {
-			if ((ACPI_TYPE_STRING == ACPI_GET_OBJECT_TYPE (*sub_object_list)) ||
-				((ACPI_TYPE_LOCAL_REFERENCE == ACPI_GET_OBJECT_TYPE (*sub_object_list)) &&
-					((*sub_object_list)->reference.opcode == AML_INT_NAMEPATH_OP))) {
+			if ((ACPI_TYPE_STRING ==
+					ACPI_GET_OBJECT_TYPE (*sub_object_list)) ||
+
+				((ACPI_TYPE_LOCAL_REFERENCE ==
+					ACPI_GET_OBJECT_TYPE (*sub_object_list)) &&
+
+					((*sub_object_list)->reference.opcode ==
+						AML_INT_NAMEPATH_OP))) {
 				name_found = TRUE;
 			}
 			else {
-				/*
-				 * Look at the next element
-				 */
+				/* Look at the next element */
+
 				sub_object_list++;
 			}
 		}
 
 		temp_size_needed += (sizeof (struct acpi_pci_routing_table) - 4);
 
-		/*
-		 * Was a String type found?
-		 */
+		/* Was a String type found? */
+
 		if (name_found) {
 			if (ACPI_GET_OBJECT_TYPE (*sub_object_list) == ACPI_TYPE_STRING) {
 				/*
 				 * The length String.Length field does not include the
 				 * terminating NULL, add 1
 				 */
-				temp_size_needed += ((acpi_size) (*sub_object_list)->string.length + 1);
+				temp_size_needed += ((acpi_size)
+					(*sub_object_list)->string.length + 1);
 			}
 			else {
 				temp_size_needed += acpi_ns_get_pathname_length (
@@ -827,14 +817,14 @@ acpi_rs_get_pci_routing_table_length (
 
 		temp_size_needed = ACPI_ROUND_UP_to_64_bITS (temp_size_needed);
 
-		/*
-		 * Point to the next union acpi_operand_object
-		 */
+		/* Point to the next union acpi_operand_object */
+
 		top_object_list++;
 	}
 
 	/*
-	 * Adding an extra element to the end of the list, essentially a NULL terminator
+	 * Adding an extra element to the end of the list, essentially a
+	 * NULL terminator
 	 */
 	*buffer_size_needed = temp_size_needed + sizeof (struct acpi_pci_routing_table);
 	return_ACPI_STATUS (AE_OK);
diff --git a/drivers/acpi/resources/rscreate.c b/drivers/acpi/resources/rscreate.c
--- a/drivers/acpi/resources/rscreate.c
+++ b/drivers/acpi/resources/rscreate.c
@@ -87,9 +87,8 @@ acpi_rs_create_resource_list (
 	ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "byte_stream_buffer = %p\n",
 		byte_stream_buffer));
 
-	/*
-	 * Params already validated, so we don't re-validate here
-	 */
+	/* Params already validated, so we don't re-validate here */
+
 	byte_stream_buffer_length = byte_stream_buffer->buffer.length;
 	byte_stream_start = byte_stream_buffer->buffer.pointer;
 
@@ -171,9 +170,8 @@ acpi_rs_create_pci_routing_table (
 
 	/* Params already validated, so we don't re-validate here */
 
-	/*
-	 * Get the required buffer length
-	 */
+	/* Get the required buffer length */
+
 	status = acpi_rs_get_pci_routing_table_length (package_object,
 			 &buffer_size_needed);
 	if (ACPI_FAILURE (status)) {
@@ -217,9 +215,8 @@ acpi_rs_create_pci_routing_table (
 		 */
 		user_prt->length = (sizeof (struct acpi_pci_routing_table) - 4);
 
-		/*
-		 * Each element of the top-level package must also be a package
-		 */
+		/* Each element of the top-level package must also be a package */
+
 		if (ACPI_GET_OBJECT_TYPE (*top_object_list) != ACPI_TYPE_PACKAGE) {
 			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
 				"(PRT[%X]) Need sub-package, found %s\n",
@@ -243,9 +240,8 @@ acpi_rs_create_pci_routing_table (
 		 */
 		sub_object_list = (*top_object_list)->package.elements;
 
-		/*
-		 * 1) First subobject: Dereference the PRT.Address
-		 */
+		/* 1) First subobject: Dereference the PRT.Address */
+
 		obj_desc = sub_object_list[0];
 		if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_INTEGER) {
 			user_prt->address = obj_desc->integer.value;
@@ -257,9 +253,8 @@ acpi_rs_create_pci_routing_table (
 			return_ACPI_STATUS (AE_BAD_DATA);
 		}
 
-		/*
-		 * 2) Second subobject: Dereference the PRT.Pin
-		 */
+		/* 2) Second subobject: Dereference the PRT.Pin */
+
 		obj_desc = sub_object_list[1];
 		if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_INTEGER) {
 			user_prt->pin = (u32) obj_desc->integer.value;
@@ -271,9 +266,8 @@ acpi_rs_create_pci_routing_table (
 			return_ACPI_STATUS (AE_BAD_DATA);
 		}
 
-		/*
-		 * 3) Third subobject: Dereference the PRT.source_name
-		 */
+		/* 3) Third subobject: Dereference the PRT.source_name */
+
 		obj_desc = sub_object_list[2];
 		switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
 		case ACPI_TYPE_LOCAL_REFERENCE:
@@ -296,7 +290,9 @@ acpi_rs_create_pci_routing_table (
 
 			status = acpi_ns_handle_to_pathname ((acpi_handle) node, &path_buffer);
 
-			user_prt->length += (u32) ACPI_STRLEN (user_prt->source) + 1; /* include null terminator */
+			/* +1 to include null terminator */
+
+			user_prt->length += (u32) ACPI_STRLEN (user_prt->source) + 1;
 			break;
 
 
@@ -304,8 +300,10 @@ acpi_rs_create_pci_routing_table (
 
 			ACPI_STRCPY (user_prt->source, obj_desc->string.pointer);
 
-			/* Add to the Length field the length of the string (add 1 for terminator) */
-
+			/*
+			 * Add to the Length field the length of the string
+			 * (add 1 for terminator)
+			 */
 			user_prt->length += obj_desc->string.length + 1;
 			break;
 
@@ -333,9 +331,8 @@ acpi_rs_create_pci_routing_table (
 
 		user_prt->length = (u32) ACPI_ROUND_UP_to_64_bITS (user_prt->length);
 
-		/*
-		 * 4) Fourth subobject: Dereference the PRT.source_index
-		 */
+		/* 4) Fourth subobject: Dereference the PRT.source_index */
+
 		obj_desc = sub_object_list[3];
 		if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_INTEGER) {
 			user_prt->source_index = (u32) obj_desc->integer.value;
diff --git a/drivers/acpi/resources/rsdump.c b/drivers/acpi/resources/rsdump.c
--- a/drivers/acpi/resources/rsdump.c
+++ b/drivers/acpi/resources/rsdump.c
@@ -48,9 +48,62 @@
 #define _COMPONENT          ACPI_RESOURCES
 	 ACPI_MODULE_NAME    ("rsdump")
 
+/* Local prototypes */
 
-#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
+static void
+acpi_rs_dump_irq (
+	union acpi_resource_data        *data);
+
+static void
+acpi_rs_dump_address16 (
+	union acpi_resource_data        *data);
+
+static void
+acpi_rs_dump_address32 (
+	union acpi_resource_data        *data);
+
+static void
+acpi_rs_dump_address64 (
+	union acpi_resource_data        *data);
+
+static void
+acpi_rs_dump_dma (
+	union acpi_resource_data        *data);
+
+static void
+acpi_rs_dump_io (
+	union acpi_resource_data        *data);
+
+static void
+acpi_rs_dump_extended_irq (
+	union acpi_resource_data        *data);
 
+static void
+acpi_rs_dump_fixed_io (
+	union acpi_resource_data        *data);
+
+static void
+acpi_rs_dump_fixed_memory32 (
+	union acpi_resource_data        *data);
+
+static void
+acpi_rs_dump_memory24 (
+	union acpi_resource_data        *data);
+
+static void
+acpi_rs_dump_memory32 (
+	union acpi_resource_data        *data);
+
+static void
+acpi_rs_dump_start_depend_fns (
+	union acpi_resource_data        *data);
+
+static void
+acpi_rs_dump_vendor_specific (
+	union acpi_resource_data        *data);
+
+
+#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
 /*******************************************************************************
  *
  * FUNCTION:    acpi_rs_dump_irq
@@ -63,7 +116,7 @@
  *
  ******************************************************************************/
 
-void
+static void
 acpi_rs_dump_irq (
 	union acpi_resource_data        *data)
 {
@@ -77,13 +130,13 @@ acpi_rs_dump_irq (
 	acpi_os_printf ("IRQ Resource\n");
 
 	acpi_os_printf ("  %s Triggered\n",
-			 ACPI_LEVEL_SENSITIVE == irq_data->edge_level ? "Level" : "Edge");
+		ACPI_LEVEL_SENSITIVE == irq_data->edge_level ? "Level" : "Edge");
 
 	acpi_os_printf ("  Active %s\n",
-			 ACPI_ACTIVE_LOW == irq_data->active_high_low ? "Low" : "High");
+		ACPI_ACTIVE_LOW == irq_data->active_high_low ? "Low" : "High");
 
 	acpi_os_printf ("  %s\n",
-			 ACPI_SHARED == irq_data->shared_exclusive ? "Shared" : "Exclusive");
+		ACPI_SHARED == irq_data->shared_exclusive ? "Shared" : "Exclusive");
 
 	acpi_os_printf ("  %X Interrupts ( ", irq_data->number_of_interrupts);
 
@@ -108,7 +161,7 @@ acpi_rs_dump_irq (
  *
  ******************************************************************************/
 
-void
+static void
 acpi_rs_dump_dma (
 	union acpi_resource_data        *data)
 {
@@ -144,7 +197,7 @@ acpi_rs_dump_dma (
 	}
 
 	acpi_os_printf ("  %sBus Master\n",
-			 ACPI_BUS_MASTER == dma_data->bus_master ? "" : "Not a ");
+		ACPI_BUS_MASTER == dma_data->bus_master ? "" : "Not a ");
 
 
 	switch (dma_data->transfer) {
@@ -165,7 +218,8 @@ acpi_rs_dump_dma (
 		break;
 	}
 
-	acpi_os_printf ("  Number of Channels: %X ( ", dma_data->number_of_channels);
+	acpi_os_printf ("  Number of Channels: %X ( ",
+		dma_data->number_of_channels);
 
 	for (index = 0; index < dma_data->number_of_channels; index++) {
 		acpi_os_printf ("%X ", dma_data->channels[index]);
@@ -188,7 +242,7 @@ acpi_rs_dump_dma (
  *
  ******************************************************************************/
 
-void
+static void
 acpi_rs_dump_start_depend_fns (
 	union acpi_resource_data        *data)
 {
@@ -232,8 +286,7 @@ acpi_rs_dump_start_depend_fns (
 		break;
 
 	default:
-		acpi_os_printf ("  Invalid performance "
-				  "robustness preference\n");
+		acpi_os_printf ("  Invalid performance robustness preference\n");
 		break;
 	}
 
@@ -253,7 +306,7 @@ acpi_rs_dump_start_depend_fns (
  *
  ******************************************************************************/
 
-void
+static void
 acpi_rs_dump_io (
 	union acpi_resource_data        *data)
 {
@@ -266,19 +319,15 @@ acpi_rs_dump_io (
 	acpi_os_printf ("Io Resource\n");
 
 	acpi_os_printf ("  %d bit decode\n",
-			 ACPI_DECODE_16 == io_data->io_decode ? 16 : 10);
+		ACPI_DECODE_16 == io_data->io_decode ? 16 : 10);
 
-	acpi_os_printf ("  Range minimum base: %08X\n",
-			 io_data->min_base_address);
+	acpi_os_printf ("  Range minimum base: %08X\n", io_data->min_base_address);
 
-	acpi_os_printf ("  Range maximum base: %08X\n",
-			 io_data->max_base_address);
+	acpi_os_printf ("  Range maximum base: %08X\n", io_data->max_base_address);
 
-	acpi_os_printf ("  Alignment: %08X\n",
-			 io_data->alignment);
+	acpi_os_printf ("  Alignment: %08X\n", io_data->alignment);
 
-	acpi_os_printf ("  Range Length: %08X\n",
-			 io_data->range_length);
+	acpi_os_printf ("  Range Length: %08X\n", io_data->range_length);
 
 	return;
 }
@@ -296,7 +345,7 @@ acpi_rs_dump_io (
  *
  ******************************************************************************/
 
-void
+static void
 acpi_rs_dump_fixed_io (
 	union acpi_resource_data        *data)
 {
@@ -307,11 +356,9 @@ acpi_rs_dump_fixed_io (
 
 
 	acpi_os_printf ("Fixed Io Resource\n");
-	acpi_os_printf ("  Range base address: %08X",
-			 fixed_io_data->base_address);
+	acpi_os_printf ("  Range base address: %08X", fixed_io_data->base_address);
 
-	acpi_os_printf ("  Range length: %08X",
-			 fixed_io_data->range_length);
+	acpi_os_printf ("  Range length: %08X", fixed_io_data->range_length);
 
 	return;
 }
@@ -329,7 +376,7 @@ acpi_rs_dump_fixed_io (
  *
  ******************************************************************************/
 
-void
+static void
 acpi_rs_dump_vendor_specific (
 	union acpi_resource_data        *data)
 {
@@ -346,7 +393,7 @@ acpi_rs_dump_vendor_specific (
 
 	for (index = 0; index < vendor_data->length; index++) {
 		acpi_os_printf ("  Byte %X: %08X\n",
-				 index, vendor_data->reserved[index]);
+			index, vendor_data->reserved[index]);
 	}
 
 	return;
@@ -365,7 +412,7 @@ acpi_rs_dump_vendor_specific (
  *
  ******************************************************************************/
 
-void
+static void
 acpi_rs_dump_memory24 (
 	union acpi_resource_data        *data)
 {
@@ -378,21 +425,19 @@ acpi_rs_dump_memory24 (
 	acpi_os_printf ("24-Bit Memory Range Resource\n");
 
 	acpi_os_printf ("  Read%s\n",
-			 ACPI_READ_WRITE_MEMORY ==
-			 memory24_data->read_write_attribute ?
-			 "/Write" : " only");
+		ACPI_READ_WRITE_MEMORY ==
+			memory24_data->read_write_attribute ?
+			"/Write" : " only");
 
 	acpi_os_printf ("  Range minimum base: %08X\n",
-			 memory24_data->min_base_address);
+		memory24_data->min_base_address);
 
 	acpi_os_printf ("  Range maximum base: %08X\n",
-			 memory24_data->max_base_address);
+		memory24_data->max_base_address);
 
-	acpi_os_printf ("  Alignment: %08X\n",
-			 memory24_data->alignment);
+	acpi_os_printf ("  Alignment: %08X\n", memory24_data->alignment);
 
-	acpi_os_printf ("  Range length: %08X\n",
-			 memory24_data->range_length);
+	acpi_os_printf ("  Range length: %08X\n", memory24_data->range_length);
 
 	return;
 }
@@ -410,7 +455,7 @@ acpi_rs_dump_memory24 (
  *
  ******************************************************************************/
 
-void
+static void
 acpi_rs_dump_memory32 (
 	union acpi_resource_data        *data)
 {
@@ -423,21 +468,19 @@ acpi_rs_dump_memory32 (
 	acpi_os_printf ("32-Bit Memory Range Resource\n");
 
 	acpi_os_printf ("  Read%s\n",
-			 ACPI_READ_WRITE_MEMORY ==
-			 memory32_data->read_write_attribute ?
-			 "/Write" : " only");
+		ACPI_READ_WRITE_MEMORY ==
+			memory32_data->read_write_attribute ?
+			"/Write" : " only");
 
 	acpi_os_printf ("  Range minimum base: %08X\n",
-			 memory32_data->min_base_address);
+		memory32_data->min_base_address);
 
 	acpi_os_printf ("  Range maximum base: %08X\n",
-			 memory32_data->max_base_address);
+		memory32_data->max_base_address);
 
-	acpi_os_printf ("  Alignment: %08X\n",
-			 memory32_data->alignment);
+	acpi_os_printf ("  Alignment: %08X\n", memory32_data->alignment);
 
-	acpi_os_printf ("  Range length: %08X\n",
-			 memory32_data->range_length);
+	acpi_os_printf ("  Range length: %08X\n", memory32_data->range_length);
 
 	return;
 }
@@ -455,11 +498,12 @@ acpi_rs_dump_memory32 (
  *
  ******************************************************************************/
 
-void
+static void
 acpi_rs_dump_fixed_memory32 (
 	union acpi_resource_data            *data)
 {
-	struct acpi_resource_fixed_mem32    *fixed_memory32_data = (struct acpi_resource_fixed_mem32 *) data;
+	struct acpi_resource_fixed_mem32    *fixed_memory32_data =
+			   (struct acpi_resource_fixed_mem32 *) data;
 
 
 	ACPI_FUNCTION_ENTRY ();
@@ -468,15 +512,14 @@ acpi_rs_dump_fixed_memory32 (
 	acpi_os_printf ("32-Bit Fixed Location Memory Range Resource\n");
 
 	acpi_os_printf ("  Read%s\n",
-			 ACPI_READ_WRITE_MEMORY ==
-			 fixed_memory32_data->read_write_attribute ?
-			 "/Write" : " Only");
+		ACPI_READ_WRITE_MEMORY ==
+			fixed_memory32_data->read_write_attribute ? "/Write" : " Only");
 
 	acpi_os_printf ("  Range base address: %08X\n",
-			 fixed_memory32_data->range_base_address);
+		fixed_memory32_data->range_base_address);
 
 	acpi_os_printf ("  Range length: %08X\n",
-			 fixed_memory32_data->range_length);
+		fixed_memory32_data->range_length);
 
 	return;
 }
@@ -494,7 +537,7 @@ acpi_rs_dump_fixed_memory32 (
  *
  ******************************************************************************/
 
-void
+static void
 acpi_rs_dump_address16 (
 	union acpi_resource_data        *data)
 {
@@ -514,35 +557,30 @@ acpi_rs_dump_address16 (
 
 		switch (address16_data->attribute.memory.cache_attribute) {
 		case ACPI_NON_CACHEABLE_MEMORY:
-			acpi_os_printf ("  Type Specific: "
-					  "Noncacheable memory\n");
+			acpi_os_printf ("  Type Specific: Noncacheable memory\n");
 			break;
 
 		case ACPI_CACHABLE_MEMORY:
-			acpi_os_printf ("  Type Specific: "
-					  "Cacheable memory\n");
+			acpi_os_printf ("  Type Specific: Cacheable memory\n");
 			break;
 
 		case ACPI_WRITE_COMBINING_MEMORY:
-			acpi_os_printf ("  Type Specific: "
-					  "Write-combining memory\n");
+			acpi_os_printf ("  Type Specific: Write-combining memory\n");
 			break;
 
 		case ACPI_PREFETCHABLE_MEMORY:
-			acpi_os_printf ("  Type Specific: "
-					  "Prefetchable memory\n");
+			acpi_os_printf ("  Type Specific: Prefetchable memory\n");
 			break;
 
 		default:
-			acpi_os_printf ("  Type Specific: "
-					  "Invalid cache attribute\n");
+			acpi_os_printf ("  Type Specific: Invalid cache attribute\n");
 			break;
 		}
 
 		acpi_os_printf ("  Type Specific: Read%s\n",
 			ACPI_READ_WRITE_MEMORY ==
-			address16_data->attribute.memory.read_write_attribute ?
-			"/Write" : " Only");
+				address16_data->attribute.memory.read_write_attribute ?
+				"/Write" : " Only");
 		break;
 
 	case ACPI_IO_RANGE:
@@ -551,30 +589,26 @@ acpi_rs_dump_address16 (
 
 		switch (address16_data->attribute.io.range_attribute) {
 		case ACPI_NON_ISA_ONLY_RANGES:
-			acpi_os_printf ("  Type Specific: "
-					  "Non-ISA Io Addresses\n");
+			acpi_os_printf ("  Type Specific: Non-ISA Io Addresses\n");
 			break;
 
 		case ACPI_ISA_ONLY_RANGES:
-			acpi_os_printf ("  Type Specific: "
-					  "ISA Io Addresses\n");
+			acpi_os_printf ("  Type Specific: ISA Io Addresses\n");
 			break;
 
 		case ACPI_ENTIRE_RANGE:
-			acpi_os_printf ("  Type Specific: "
-					  "ISA and non-ISA Io Addresses\n");
+			acpi_os_printf ("  Type Specific: ISA and non-ISA Io Addresses\n");
 			break;
 
 		default:
-			acpi_os_printf ("  Type Specific: "
-					  "Invalid range attribute\n");
+			acpi_os_printf ("  Type Specific: Invalid range attribute\n");
 			break;
 		}
 
 		acpi_os_printf ("  Type Specific: %s Translation\n",
 			ACPI_SPARSE_TRANSLATION ==
-			address16_data->attribute.io.translation_attribute ?
-			"Sparse" : "Dense");
+				address16_data->attribute.io.translation_attribute ?
+				"Sparse" : "Dense");
 		break;
 
 	case ACPI_BUS_NUMBER_RANGE:
@@ -589,41 +623,42 @@ acpi_rs_dump_address16 (
 	}
 
 	acpi_os_printf ("  Resource %s\n",
-			ACPI_CONSUMER == address16_data->producer_consumer ?
+		ACPI_CONSUMER == address16_data->producer_consumer ?
 			"Consumer" : "Producer");
 
 	acpi_os_printf ("  %s decode\n",
-			 ACPI_SUB_DECODE == address16_data->decode ?
-			 "Subtractive" : "Positive");
+		ACPI_SUB_DECODE == address16_data->decode ?
+			"Subtractive" : "Positive");
 
 	acpi_os_printf ("  Min address is %s fixed\n",
-			 ACPI_ADDRESS_FIXED == address16_data->min_address_fixed ?
-			 "" : "not");
+		ACPI_ADDRESS_FIXED == address16_data->min_address_fixed ?
+			"" : "not");
 
 	acpi_os_printf ("  Max address is %s fixed\n",
-			 ACPI_ADDRESS_FIXED == address16_data->max_address_fixed ?
-			 "" : "not");
+		ACPI_ADDRESS_FIXED == address16_data->max_address_fixed ?
+			"" : "not");
 
 	acpi_os_printf ("  Granularity: %08X\n",
-			 address16_data->granularity);
+		address16_data->granularity);
 
 	acpi_os_printf ("  Address range min: %08X\n",
-			 address16_data->min_address_range);
+		address16_data->min_address_range);
 
 	acpi_os_printf ("  Address range max: %08X\n",
-			 address16_data->max_address_range);
+		address16_data->max_address_range);
 
 	acpi_os_printf ("  Address translation offset: %08X\n",
-			 address16_data->address_translation_offset);
+		address16_data->address_translation_offset);
 
 	acpi_os_printf ("  Address Length: %08X\n",
-			 address16_data->address_length);
+		address16_data->address_length);
 
 	if (0xFF != address16_data->resource_source.index) {
 		acpi_os_printf ("  Resource Source Index: %X\n",
-				 address16_data->resource_source.index);
+			address16_data->resource_source.index);
+
 		acpi_os_printf ("  Resource Source: %s\n",
-				 address16_data->resource_source.string_ptr);
+			address16_data->resource_source.string_ptr);
 	}
 
 	return;
@@ -642,7 +677,7 @@ acpi_rs_dump_address16 (
  *
  ******************************************************************************/
 
-void
+static void
 acpi_rs_dump_address32 (
 	union acpi_resource_data        *data)
 {
@@ -661,35 +696,30 @@ acpi_rs_dump_address32 (
 
 		switch (address32_data->attribute.memory.cache_attribute) {
 		case ACPI_NON_CACHEABLE_MEMORY:
-			acpi_os_printf ("  Type Specific: "
-					  "Noncacheable memory\n");
+			acpi_os_printf ("  Type Specific: Noncacheable memory\n");
 			break;
 
 		case ACPI_CACHABLE_MEMORY:
-			acpi_os_printf ("  Type Specific: "
-					  "Cacheable memory\n");
+			acpi_os_printf ("  Type Specific: Cacheable memory\n");
 			break;
 
 		case ACPI_WRITE_COMBINING_MEMORY:
-			acpi_os_printf ("  Type Specific: "
-					  "Write-combining memory\n");
+			acpi_os_printf ("  Type Specific: Write-combining memory\n");
 			break;
 
 		case ACPI_PREFETCHABLE_MEMORY:
-			acpi_os_printf ("  Type Specific: "
-					  "Prefetchable memory\n");
+			acpi_os_printf ("  Type Specific: Prefetchable memory\n");
 			break;
 
 		default:
-			acpi_os_printf ("  Type Specific: "
-					  "Invalid cache attribute\n");
+			acpi_os_printf ("  Type Specific: Invalid cache attribute\n");
 			break;
 		}
 
 		acpi_os_printf ("  Type Specific: Read%s\n",
 			ACPI_READ_WRITE_MEMORY ==
-			address32_data->attribute.memory.read_write_attribute ?
-			"/Write" : " Only");
+				address32_data->attribute.memory.read_write_attribute ?
+				"/Write" : " Only");
 		break;
 
 	case ACPI_IO_RANGE:
@@ -698,30 +728,26 @@ acpi_rs_dump_address32 (
 
 		switch (address32_data->attribute.io.range_attribute) {
 		case ACPI_NON_ISA_ONLY_RANGES:
-			acpi_os_printf ("  Type Specific: "
-					  "Non-ISA Io Addresses\n");
+			acpi_os_printf ("  Type Specific: Non-ISA Io Addresses\n");
 			break;
 
 		case ACPI_ISA_ONLY_RANGES:
-			acpi_os_printf ("  Type Specific: "
-					  "ISA Io Addresses\n");
+			acpi_os_printf ("  Type Specific: ISA Io Addresses\n");
 			break;
 
 		case ACPI_ENTIRE_RANGE:
-			acpi_os_printf ("  Type Specific: "
-					  "ISA and non-ISA Io Addresses\n");
+			acpi_os_printf ("  Type Specific: ISA and non-ISA Io Addresses\n");
 			break;
 
 		default:
-			acpi_os_printf ("  Type Specific: "
-					  "Invalid Range attribute");
+			acpi_os_printf ("  Type Specific: Invalid Range attribute");
 			break;
 		}
 
 		acpi_os_printf ("  Type Specific: %s Translation\n",
 			ACPI_SPARSE_TRANSLATION ==
-			address32_data->attribute.io.translation_attribute ?
-			"Sparse" : "Dense");
+				address32_data->attribute.io.translation_attribute ?
+				"Sparse" : "Dense");
 		break;
 
 	case ACPI_BUS_NUMBER_RANGE:
@@ -731,46 +757,48 @@ acpi_rs_dump_address32 (
 
 	default:
 
-		acpi_os_printf ("  Resource Type: 0x%2.2X\n", address32_data->resource_type);
+		acpi_os_printf ("  Resource Type: 0x%2.2X\n",
+			address32_data->resource_type);
 		break;
 	}
 
 	acpi_os_printf ("  Resource %s\n",
-			 ACPI_CONSUMER == address32_data->producer_consumer ?
-			 "Consumer" : "Producer");
+		ACPI_CONSUMER == address32_data->producer_consumer ?
+			"Consumer" : "Producer");
 
 	acpi_os_printf ("  %s decode\n",
-			 ACPI_SUB_DECODE == address32_data->decode ?
-			 "Subtractive" : "Positive");
+		ACPI_SUB_DECODE == address32_data->decode ?
+			"Subtractive" : "Positive");
 
 	acpi_os_printf ("  Min address is %s fixed\n",
-			 ACPI_ADDRESS_FIXED == address32_data->min_address_fixed ?
-			 "" : "not ");
+		ACPI_ADDRESS_FIXED == address32_data->min_address_fixed ?
+			"" : "not ");
 
 	acpi_os_printf ("  Max address is %s fixed\n",
-			 ACPI_ADDRESS_FIXED == address32_data->max_address_fixed ?
-			 "" : "not ");
+		ACPI_ADDRESS_FIXED == address32_data->max_address_fixed ?
+			"" : "not ");
 
 	acpi_os_printf ("  Granularity: %08X\n",
-			 address32_data->granularity);
+		address32_data->granularity);
 
 	acpi_os_printf ("  Address range min: %08X\n",
-			 address32_data->min_address_range);
+		address32_data->min_address_range);
 
 	acpi_os_printf ("  Address range max: %08X\n",
-			 address32_data->max_address_range);
+		address32_data->max_address_range);
 
 	acpi_os_printf ("  Address translation offset: %08X\n",
-			 address32_data->address_translation_offset);
+		address32_data->address_translation_offset);
 
 	acpi_os_printf ("  Address Length: %08X\n",
-			 address32_data->address_length);
+		address32_data->address_length);
 
 	if(0xFF != address32_data->resource_source.index) {
 		acpi_os_printf ("  Resource Source Index: %X\n",
-				 address32_data->resource_source.index);
+			address32_data->resource_source.index);
+
 		acpi_os_printf ("  Resource Source: %s\n",
-				 address32_data->resource_source.string_ptr);
+			address32_data->resource_source.string_ptr);
 	}
 
 	return;
@@ -789,7 +817,7 @@ acpi_rs_dump_address32 (
  *
  ******************************************************************************/
 
-void
+static void
 acpi_rs_dump_address64 (
 	union acpi_resource_data        *data)
 {
@@ -808,35 +836,30 @@ acpi_rs_dump_address64 (
 
 		switch (address64_data->attribute.memory.cache_attribute) {
 		case ACPI_NON_CACHEABLE_MEMORY:
-			acpi_os_printf ("  Type Specific: "
-					  "Noncacheable memory\n");
+			acpi_os_printf ("  Type Specific: Noncacheable memory\n");
 			break;
 
 		case ACPI_CACHABLE_MEMORY:
-			acpi_os_printf ("  Type Specific: "
-					  "Cacheable memory\n");
+			acpi_os_printf ("  Type Specific: Cacheable memory\n");
 			break;
 
 		case ACPI_WRITE_COMBINING_MEMORY:
-			acpi_os_printf ("  Type Specific: "
-					  "Write-combining memory\n");
+			acpi_os_printf ("  Type Specific: Write-combining memory\n");
 			break;
 
 		case ACPI_PREFETCHABLE_MEMORY:
-			acpi_os_printf ("  Type Specific: "
-					  "Prefetchable memory\n");
+			acpi_os_printf ("  Type Specific: Prefetchable memory\n");
 			break;
 
 		default:
-			acpi_os_printf ("  Type Specific: "
-					  "Invalid cache attribute\n");
+			acpi_os_printf ("  Type Specific: Invalid cache attribute\n");
 			break;
 		}
 
 		acpi_os_printf ("  Type Specific: Read%s\n",
 			ACPI_READ_WRITE_MEMORY ==
-			address64_data->attribute.memory.read_write_attribute ?
-			"/Write" : " Only");
+				address64_data->attribute.memory.read_write_attribute ?
+				"/Write" : " Only");
 		break;
 
 	case ACPI_IO_RANGE:
@@ -845,30 +868,26 @@ acpi_rs_dump_address64 (
 
 		switch (address64_data->attribute.io.range_attribute) {
 		case ACPI_NON_ISA_ONLY_RANGES:
-			acpi_os_printf ("  Type Specific: "
-					  "Non-ISA Io Addresses\n");
+			acpi_os_printf ("  Type Specific: Non-ISA Io Addresses\n");
 			break;
 
 		case ACPI_ISA_ONLY_RANGES:
-			acpi_os_printf ("  Type Specific: "
-					  "ISA Io Addresses\n");
+			acpi_os_printf ("  Type Specific: ISA Io Addresses\n");
 			break;
 
 		case ACPI_ENTIRE_RANGE:
-			acpi_os_printf ("  Type Specific: "
-					  "ISA and non-ISA Io Addresses\n");
+			acpi_os_printf ("  Type Specific: ISA and non-ISA Io Addresses\n");
 			break;
 
 		default:
-			acpi_os_printf ("  Type Specific: "
-					  "Invalid Range attribute");
+			acpi_os_printf ("  Type Specific: Invalid Range attribute");
 			break;
 		}
 
 		acpi_os_printf ("  Type Specific: %s Translation\n",
 			ACPI_SPARSE_TRANSLATION ==
-			address64_data->attribute.io.translation_attribute ?
-			"Sparse" : "Dense");
+				address64_data->attribute.io.translation_attribute ?
+				"Sparse" : "Dense");
 		break;
 
 	case ACPI_BUS_NUMBER_RANGE:
@@ -878,49 +897,51 @@ acpi_rs_dump_address64 (
 
 	default:
 
-		acpi_os_printf ("  Resource Type: 0x%2.2X\n", address64_data->resource_type);
+		acpi_os_printf ("  Resource Type: 0x%2.2X\n",
+			address64_data->resource_type);
 		break;
 	}
 
 	acpi_os_printf ("  Resource %s\n",
-			 ACPI_CONSUMER == address64_data->producer_consumer ?
-			 "Consumer" : "Producer");
+		ACPI_CONSUMER == address64_data->producer_consumer ?
+			"Consumer" : "Producer");
 
 	acpi_os_printf ("  %s decode\n",
-			 ACPI_SUB_DECODE == address64_data->decode ?
-			 "Subtractive" : "Positive");
+		ACPI_SUB_DECODE == address64_data->decode ?
+			"Subtractive" : "Positive");
 
 	acpi_os_printf ("  Min address is %s fixed\n",
-			 ACPI_ADDRESS_FIXED == address64_data->min_address_fixed ?
-			 "" : "not ");
+		ACPI_ADDRESS_FIXED == address64_data->min_address_fixed ?
+			"" : "not ");
 
 	acpi_os_printf ("  Max address is %s fixed\n",
-			 ACPI_ADDRESS_FIXED == address64_data->max_address_fixed ?
-			 "" : "not ");
+		ACPI_ADDRESS_FIXED == address64_data->max_address_fixed ?
+			"" : "not ");
 
 	acpi_os_printf ("  Granularity: %8.8X%8.8X\n",
-			 ACPI_FORMAT_UINT64 (address64_data->granularity));
+		ACPI_FORMAT_UINT64 (address64_data->granularity));
 
 	acpi_os_printf ("  Address range min: %8.8X%8.8X\n",
-			 ACPI_FORMAT_UINT64 (address64_data->min_address_range));
+		ACPI_FORMAT_UINT64 (address64_data->min_address_range));
 
 	acpi_os_printf ("  Address range max: %8.8X%8.8X\n",
-			 ACPI_FORMAT_UINT64 (address64_data->max_address_range));
+		ACPI_FORMAT_UINT64 (address64_data->max_address_range));
 
 	acpi_os_printf ("  Address translation offset: %8.8X%8.8X\n",
-			 ACPI_FORMAT_UINT64 (address64_data->address_translation_offset));
+		ACPI_FORMAT_UINT64 (address64_data->address_translation_offset));
 
 	acpi_os_printf ("  Address Length: %8.8X%8.8X\n",
-			 ACPI_FORMAT_UINT64 (address64_data->address_length));
+		ACPI_FORMAT_UINT64 (address64_data->address_length));
 
 	acpi_os_printf ("  Type Specific Attributes: %8.8X%8.8X\n",
-			 ACPI_FORMAT_UINT64 (address64_data->type_specific_attributes));
+		ACPI_FORMAT_UINT64 (address64_data->type_specific_attributes));
 
 	if (0xFF != address64_data->resource_source.index) {
 		acpi_os_printf ("  Resource Source Index: %X\n",
-				 address64_data->resource_source.index);
+			address64_data->resource_source.index);
+
 		acpi_os_printf ("  Resource Source: %s\n",
-				 address64_data->resource_source.string_ptr);
+			address64_data->resource_source.string_ptr);
 	}
 
 	return;
@@ -939,7 +960,7 @@ acpi_rs_dump_address64 (
  *
  ******************************************************************************/
 
-void
+static void
 acpi_rs_dump_extended_irq (
 	union acpi_resource_data        *data)
 {
@@ -953,23 +974,22 @@ acpi_rs_dump_extended_irq (
 	acpi_os_printf ("Extended IRQ Resource\n");
 
 	acpi_os_printf ("  Resource %s\n",
-			 ACPI_CONSUMER == ext_irq_data->producer_consumer ?
-			 "Consumer" : "Producer");
+		ACPI_CONSUMER == ext_irq_data->producer_consumer ?
+			"Consumer" : "Producer");
 
 	acpi_os_printf ("  %s\n",
-			 ACPI_LEVEL_SENSITIVE == ext_irq_data->edge_level ?
-			 "Level" : "Edge");
+		ACPI_LEVEL_SENSITIVE == ext_irq_data->edge_level ?
+			"Level" : "Edge");
 
 	acpi_os_printf ("  Active %s\n",
-			 ACPI_ACTIVE_LOW == ext_irq_data->active_high_low ?
-			 "low" : "high");
+		ACPI_ACTIVE_LOW == ext_irq_data->active_high_low ?
+			"low" : "high");
 
 	acpi_os_printf ("  %s\n",
-			 ACPI_SHARED == ext_irq_data->shared_exclusive ?
-			 "Shared" : "Exclusive");
+		ACPI_SHARED == ext_irq_data->shared_exclusive ?
+			"Shared" : "Exclusive");
 
-	acpi_os_printf ("  Interrupts : %X ( ",
-			 ext_irq_data->number_of_interrupts);
+	acpi_os_printf ("  Interrupts : %X ( ", ext_irq_data->number_of_interrupts);
 
 	for (index = 0; index < ext_irq_data->number_of_interrupts; index++) {
 		acpi_os_printf ("%X ", ext_irq_data->interrupts[index]);
@@ -979,9 +999,10 @@ acpi_rs_dump_extended_irq (
 
 	if(0xFF != ext_irq_data->resource_source.index) {
 		acpi_os_printf ("  Resource Source Index: %X",
-				 ext_irq_data->resource_source.index);
+			ext_irq_data->resource_source.index);
+
 		acpi_os_printf ("  Resource Source: %s",
-				 ext_irq_data->resource_source.string_ptr);
+			ext_irq_data->resource_source.string_ptr);
 	}
 
 	return;
@@ -992,7 +1013,7 @@ acpi_rs_dump_extended_irq (
  *
  * FUNCTION:    acpi_rs_dump_resource_list
  *
- * PARAMETERS:  Data            - pointer to the resource structure to dump.
+ * PARAMETERS:  Resource        - pointer to the resource structure to dump.
  *
  * RETURN:      None
  *
@@ -1096,7 +1117,7 @@ acpi_rs_dump_resource_list (
  *
  * FUNCTION:    acpi_rs_dump_irq_list
  *
- * PARAMETERS:  Data            - pointer to the routing table to dump.
+ * PARAMETERS:  route_table     - pointer to the routing table to dump.
  *
  * RETURN:      None
  *
@@ -1124,20 +1145,17 @@ acpi_rs_dump_irq_list (
 			acpi_os_printf ("PCI IRQ Routing Table structure %X.\n", count++);
 
 			acpi_os_printf ("  Address: %8.8X%8.8X\n",
-					 ACPI_FORMAT_UINT64 (prt_element->address));
+				ACPI_FORMAT_UINT64 (prt_element->address));
 
 			acpi_os_printf ("  Pin: %X\n", prt_element->pin);
 
 			acpi_os_printf ("  Source: %s\n", prt_element->source);
 
-			acpi_os_printf ("  source_index: %X\n",
-					 prt_element->source_index);
+			acpi_os_printf ("  source_index: %X\n", prt_element->source_index);
 
 			buffer += prt_element->length;
-
 			prt_element = ACPI_CAST_PTR (struct acpi_pci_routing_table, buffer);
-
-			if(0 == prt_element->length) {
+			if (0 == prt_element->length) {
 				done = TRUE;
 			}
 		}
diff --git a/drivers/acpi/resources/rsio.c b/drivers/acpi/resources/rsio.c
--- a/drivers/acpi/resources/rsio.c
+++ b/drivers/acpi/resources/rsio.c
@@ -81,67 +81,60 @@ acpi_rs_io_resource (
 	struct acpi_resource            *output_struct = (void *) *output_buffer;
 	u16                             temp16 = 0;
 	u8                              temp8 = 0;
-	acpi_size                       struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_io);
+	acpi_size                       struct_size = ACPI_SIZEOF_RESOURCE (
+			  struct acpi_resource_io);
 
 
 	ACPI_FUNCTION_TRACE ("rs_io_resource");
 
 
-	/*
-	 * The number of bytes consumed are Constant
-	 */
+	/* The number of bytes consumed are Constant */
+
 	*bytes_consumed = 8;
 
 	output_struct->id = ACPI_RSTYPE_IO;
 
-	/*
-	 * Check Decode
-	 */
+	/* Check Decode */
+
 	buffer += 1;
 	temp8 = *buffer;
 
 	output_struct->data.io.io_decode = temp8 & 0x01;
 
-	/*
-	 * Check min_base Address
-	 */
+	/* Check min_base Address */
+
 	buffer += 1;
 	ACPI_MOVE_16_TO_16 (&temp16, buffer);
 
 	output_struct->data.io.min_base_address = temp16;
 
-	/*
-	 * Check max_base Address
-	 */
+	/* Check max_base Address */
+
 	buffer += 2;
 	ACPI_MOVE_16_TO_16 (&temp16, buffer);
 
 	output_struct->data.io.max_base_address = temp16;
 
-	/*
-	 * Check Base alignment
-	 */
+	/* Check Base alignment */
+
 	buffer += 2;
 	temp8 = *buffer;
 
 	output_struct->data.io.alignment = temp8;
 
-	/*
-	 * Check range_length
-	 */
+	/* Check range_length */
+
 	buffer += 1;
 	temp8 = *buffer;
 
 	output_struct->data.io.range_length = temp8;
 
-	/*
-	 * Set the Length parameter
-	 */
+	/* Set the Length parameter */
+
 	output_struct->length = (u32) struct_size;
 
-	/*
-	 * Return the final size of the structure
-	 */
+	/* Return the final size of the structure */
+
 	*structure_size = struct_size;
 	return_ACPI_STATUS (AE_OK);
 }
@@ -179,43 +172,39 @@ acpi_rs_fixed_io_resource (
 	struct acpi_resource            *output_struct = (void *) *output_buffer;
 	u16                             temp16 = 0;
 	u8                              temp8 = 0;
-	acpi_size                       struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_fixed_io);
+	acpi_size                       struct_size = ACPI_SIZEOF_RESOURCE (
+			  struct acpi_resource_fixed_io);
 
 
 	ACPI_FUNCTION_TRACE ("rs_fixed_io_resource");
 
 
-	/*
-	 * The number of bytes consumed are Constant
-	 */
+	/* The number of bytes consumed are Constant */
+
 	*bytes_consumed = 4;
 
 	output_struct->id = ACPI_RSTYPE_FIXED_IO;
 
-	/*
-	 * Check Range Base Address
-	 */
+	/* Check Range Base Address */
+
 	buffer += 1;
 	ACPI_MOVE_16_TO_16 (&temp16, buffer);
 
 	output_struct->data.fixed_io.base_address = temp16;
 
-	/*
-	 * Check range_length
-	 */
+	/* Check range_length */
+
 	buffer += 2;
 	temp8 = *buffer;
 
 	output_struct->data.fixed_io.range_length = temp8;
 
-	/*
-	 * Set the Length parameter
-	 */
+	/* Set the Length parameter */
+
 	output_struct->length = (u32) struct_size;
 
-	/*
-	 * Return the final size of the structure
-	 */
+	/* Return the final size of the structure */
+
 	*structure_size = struct_size;
 	return_ACPI_STATUS (AE_OK);
 }
@@ -251,55 +240,48 @@ acpi_rs_io_stream (
 	ACPI_FUNCTION_TRACE ("rs_io_stream");
 
 
-	/*
-	 * The descriptor field is static
-	 */
+	/* The descriptor field is static */
+
 	*buffer = 0x47;
 	buffer += 1;
 
-	/*
-	 * Io Information Byte
-	 */
+	/* Io Information Byte */
+
 	temp8 = (u8) (linked_list->data.io.io_decode & 0x01);
 
 	*buffer = temp8;
 	buffer += 1;
 
-	/*
-	 * Set the Range minimum base address
-	 */
+	/* Set the Range minimum base address */
+
 	temp16 = (u16) linked_list->data.io.min_base_address;
 
 	ACPI_MOVE_16_TO_16 (buffer, &temp16);
 	buffer += 2;
 
-	/*
-	 * Set the Range maximum base address
-	 */
+	/* Set the Range maximum base address */
+
 	temp16 = (u16) linked_list->data.io.max_base_address;
 
 	ACPI_MOVE_16_TO_16 (buffer, &temp16);
 	buffer += 2;
 
-	/*
-	 * Set the base alignment
-	 */
+	/* Set the base alignment */
+
 	temp8 = (u8) linked_list->data.io.alignment;
 
 	*buffer = temp8;
 	buffer += 1;
 
-	/*
-	 * Set the range length
-	 */
+	/* Set the range length */
+
 	temp8 = (u8) linked_list->data.io.range_length;
 
 	*buffer = temp8;
 	buffer += 1;
 
-	/*
-	 * Return the number of bytes consumed in this operation
-	 */
+	/* Return the number of bytes consumed in this operation */
+
 	*bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer);
 	return_ACPI_STATUS (AE_OK);
 }
@@ -335,32 +317,28 @@ acpi_rs_fixed_io_stream (
 	ACPI_FUNCTION_TRACE ("rs_fixed_io_stream");
 
 
-	/*
-	 * The descriptor field is static
-	 */
+	/* The descriptor field is static */
+
 	*buffer = 0x4B;
 
 	buffer += 1;
 
-	/*
-	 * Set the Range base address
-	 */
+	/* Set the Range base address */
+
 	temp16 = (u16) linked_list->data.fixed_io.base_address;
 
 	ACPI_MOVE_16_TO_16 (buffer, &temp16);
 	buffer += 2;
 
-	/*
-	 * Set the range length
-	 */
+	/* Set the range length */
+
 	temp8 = (u8) linked_list->data.fixed_io.range_length;
 
 	*buffer = temp8;
 	buffer += 1;
 
-	/*
-	 * Return the number of bytes consumed in this operation
-	 */
+	/* Return the number of bytes consumed in this operation */
+
 	*bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer);
 	return_ACPI_STATUS (AE_OK);
 }
@@ -399,21 +377,20 @@ acpi_rs_dma_resource (
 	u8                              temp8 = 0;
 	u8                              index;
 	u8                              i;
-	acpi_size                       struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_dma);
+	acpi_size                       struct_size = ACPI_SIZEOF_RESOURCE (
+			  struct acpi_resource_dma);
 
 
 	ACPI_FUNCTION_TRACE ("rs_dma_resource");
 
 
-	/*
-	 * The number of bytes consumed are Constant
-	 */
+	/* The number of bytes consumed are Constant */
+
 	*bytes_consumed = 3;
 	output_struct->id = ACPI_RSTYPE_DMA;
 
-	/*
-	 * Point to the 8-bits of Byte 1
-	 */
+	/* Point to the 8-bits of Byte 1 */
+
 	buffer += 1;
 	temp8 = *buffer;
 
@@ -430,46 +407,40 @@ acpi_rs_dma_resource (
 
 	output_struct->data.dma.number_of_channels = i;
 	if (i > 0) {
-		/*
-		 * Calculate the structure size based upon the number of interrupts
-		 */
+		/* Calculate the structure size based upon the number of interrupts */
+
 		struct_size += ((acpi_size) i - 1) * 4;
 	}
 
-	/*
-	 * Point to Byte 2
-	 */
+	/* Point to Byte 2 */
+
 	buffer += 1;
 	temp8 = *buffer;
 
-	/*
-	 * Check for transfer preference (Bits[1:0])
-	 */
+	/* Check for transfer preference (Bits[1:0]) */
+
 	output_struct->data.dma.transfer = temp8 & 0x03;
 
 	if (0x03 == output_struct->data.dma.transfer) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid DMA.Transfer preference (3)\n"));
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"Invalid DMA.Transfer preference (3)\n"));
 		return_ACPI_STATUS (AE_BAD_DATA);
 	}
 
-	/*
-	 * Get bus master preference (Bit[2])
-	 */
+	/* Get bus master preference (Bit[2]) */
+
 	output_struct->data.dma.bus_master = (temp8 >> 2) & 0x01;
 
-	/*
-	 * Get channel speed support (Bits[6:5])
-	 */
+	/* Get channel speed support (Bits[6:5]) */
+
 	output_struct->data.dma.type = (temp8 >> 5) & 0x03;
 
-	/*
-	 * Set the Length parameter
-	 */
+	/* Set the Length parameter */
+
 	output_struct->length = (u32) struct_size;
 
-	/*
-	 * Return the final size of the structure
-	 */
+	/* Return the final size of the structure */
+
 	*structure_size = struct_size;
 	return_ACPI_STATUS (AE_OK);
 }
@@ -506,16 +477,14 @@ acpi_rs_dma_stream (
 	ACPI_FUNCTION_TRACE ("rs_dma_stream");
 
 
-	/*
-	 * The descriptor field is static
-	 */
+	/* The descriptor field is static */
+
 	*buffer = 0x2A;
 	buffer += 1;
 	temp8 = 0;
 
-	/*
-	 * Loop through all of the Channels and set the mask bits
-	 */
+	/* Loop through all of the Channels and set the mask bits */
+
 	for (index = 0;
 		 index < linked_list->data.dma.number_of_channels;
 		 index++) {
@@ -526,9 +495,8 @@ acpi_rs_dma_stream (
 	*buffer = temp8;
 	buffer += 1;
 
-	/*
-	 * Set the DMA Info
-	 */
+	/* Set the DMA Info */
+
 	temp8 = (u8) ((linked_list->data.dma.type & 0x03) << 5);
 	temp8 |= ((linked_list->data.dma.bus_master & 0x01) << 2);
 	temp8 |= (linked_list->data.dma.transfer & 0x03);
@@ -536,9 +504,8 @@ acpi_rs_dma_stream (
 	*buffer = temp8;
 	buffer += 1;
 
-	/*
-	 * Return the number of bytes consumed in this operation
-	 */
+	/* Return the number of bytes consumed in this operation */
+
 	*bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer);
 	return_ACPI_STATUS (AE_OK);
 }
diff --git a/drivers/acpi/resources/rsirq.c b/drivers/acpi/resources/rsirq.c
--- a/drivers/acpi/resources/rsirq.c
+++ b/drivers/acpi/resources/rsirq.c
@@ -83,7 +83,8 @@ acpi_rs_irq_resource (
 	u8                              temp8 = 0;
 	u8                              index;
 	u8                              i;
-	acpi_size                       struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_irq);
+	acpi_size                       struct_size = ACPI_SIZEOF_RESOURCE (
+			  struct acpi_resource_irq);
 
 
 	ACPI_FUNCTION_TRACE ("rs_irq_resource");
@@ -91,15 +92,14 @@ acpi_rs_irq_resource (
 
 	/*
 	 * The number of bytes consumed are contained in the descriptor
-	 *  (Bits:0-1)
+	 * (Bits:0-1)
 	 */
 	temp8 = *buffer;
 	*bytes_consumed = (temp8 & 0x03) + 1;
 	output_struct->id = ACPI_RSTYPE_IRQ;
 
-	/*
-	 * Point to the 16-bits of Bytes 1 and 2
-	 */
+	/* Point to the 16-bits of Bytes 1 and 2 */
+
 	buffer += 1;
 	ACPI_MOVE_16_TO_16 (&temp16, buffer);
 
@@ -118,22 +118,19 @@ acpi_rs_irq_resource (
 
 	output_struct->data.irq.number_of_interrupts = i;
 	if (i > 0) {
-		/*
-		 * Calculate the structure size based upon the number of interrupts
-		 */
+		/* Calculate the structure size based upon the number of interrupts */
+
 		struct_size += ((acpi_size) i - 1) * 4;
 	}
 
-	/*
-	 * Point to Byte 3 if it is used
-	 */
+	/* Point to Byte 3 if it is used */
+
 	if (4 == *bytes_consumed) {
 		buffer += 2;
 		temp8 = *buffer;
 
-		/*
-		 * Check for HE, LL interrupts
-		 */
+		/* Check for HE, LL interrupts */
+
 		switch (temp8 & 0x09) {
 		case 0x01: /* HE */
 			output_struct->data.irq.edge_level = ACPI_EDGE_SENSITIVE;
@@ -152,13 +149,13 @@ acpi_rs_irq_resource (
 			 * so 0x00 and 0x09 are illegal.
 			 */
 			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
-				"Invalid interrupt polarity/trigger in resource list, %X\n", temp8));
+				"Invalid interrupt polarity/trigger in resource list, %X\n",
+				temp8));
 			return_ACPI_STATUS (AE_BAD_DATA);
 		}
 
-		/*
-		 * Check for sharable
-		 */
+		/* Check for sharable */
+
 		output_struct->data.irq.shared_exclusive = (temp8 >> 3) & 0x01;
 	}
 	else {
@@ -171,14 +168,12 @@ acpi_rs_irq_resource (
 		output_struct->data.irq.shared_exclusive = ACPI_EXCLUSIVE;
 	}
 
-	/*
-	 * Set the Length parameter
-	 */
+	/* Set the Length parameter */
+
 	output_struct->length = (u32) struct_size;
 
-	/*
-	 * Return the final size of the structure
-	 */
+	/* Return the final size of the structure */
+
 	*structure_size = struct_size;
 	return_ACPI_STATUS (AE_OK);
 }
@@ -234,9 +229,8 @@ acpi_rs_irq_stream (
 	buffer += 1;
 	temp16 = 0;
 
-	/*
-	 * Loop through all of the interrupts and set the mask bits
-	 */
+	/* Loop through all of the interrupts and set the mask bits */
+
 	for(index = 0;
 		index < linked_list->data.irq.number_of_interrupts;
 		index++) {
@@ -247,9 +241,8 @@ acpi_rs_irq_stream (
 	ACPI_MOVE_16_TO_16 (buffer, &temp16);
 	buffer += 2;
 
-	/*
-	 * Set the IRQ Info byte if needed.
-	 */
+	/* Set the IRQ Info byte if needed. */
+
 	if (IRqinfo_byte_needed) {
 		temp8 = 0;
 		temp8 = (u8) ((linked_list->data.irq.shared_exclusive &
@@ -267,9 +260,8 @@ acpi_rs_irq_stream (
 		buffer += 1;
 	}
 
-	/*
-	 * Return the number of bytes consumed in this operation
-	 */
+	/* Return the number of bytes consumed in this operation */
+
 	*bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer);
 	return_ACPI_STATUS (AE_OK);
 }
@@ -309,15 +301,15 @@ acpi_rs_extended_irq_resource (
 	u8                              temp8 = 0;
 	u8                              *temp_ptr;
 	u8                              index;
-	acpi_size                       struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_ext_irq);
+	acpi_size                       struct_size = ACPI_SIZEOF_RESOURCE (
+			  struct acpi_resource_ext_irq);
 
 
 	ACPI_FUNCTION_TRACE ("rs_extended_irq_resource");
 
 
-	/*
-	 * Point past the Descriptor to get the number of bytes consumed
-	 */
+	/* Point past the Descriptor to get the number of bytes consumed */
+
 	buffer += 1;
 	ACPI_MOVE_16_TO_16 (&temp16, buffer);
 
@@ -330,9 +322,8 @@ acpi_rs_extended_irq_resource (
 	*bytes_consumed = temp16 + 3;
 	output_struct->id = ACPI_RSTYPE_EXT_IRQ;
 
-	/*
-	 * Point to the Byte3
-	 */
+	/* Point to the Byte3 */
+
 	buffer += 2;
 	temp8 = *buffer;
 
@@ -347,21 +338,18 @@ acpi_rs_extended_irq_resource (
 	 * - Edge/Level are defined opposite in the table vs the headers
 	 */
 	output_struct->data.extended_irq.edge_level =
-			   (temp8 & 0x2) ? ACPI_EDGE_SENSITIVE : ACPI_LEVEL_SENSITIVE;
+		(temp8 & 0x2) ? ACPI_EDGE_SENSITIVE : ACPI_LEVEL_SENSITIVE;
+
+	/* Check Interrupt Polarity */
 
-	/*
-	 * Check Interrupt Polarity
-	 */
 	output_struct->data.extended_irq.active_high_low = (temp8 >> 2) & 0x1;
 
-	/*
-	 * Check for sharable
-	 */
+	/* Check for sharable */
+
 	output_struct->data.extended_irq.shared_exclusive = (temp8 >> 3) & 0x01;
 
-	/*
-	 * Point to Byte4 (IRQ Table length)
-	 */
+	/* Point to Byte4 (IRQ Table length) */
+
 	buffer += 1;
 	temp8 = *buffer;
 
@@ -379,14 +367,12 @@ acpi_rs_extended_irq_resource (
 	 */
 	struct_size += (temp8 - 1) * 4;
 
-	/*
-	 * Point to Byte5 (First IRQ Number)
-	 */
+	/* Point to Byte5 (First IRQ Number) */
+
 	buffer += 1;
 
-	/*
-	 * Cycle through every IRQ in the table
-	 */
+	/* Cycle through every IRQ in the table */
+
 	for (index = 0; index < temp8; index++) {
 		ACPI_MOVE_32_TO_32 (
 			&output_struct->data.extended_irq.interrupts[index], buffer);
@@ -407,7 +393,8 @@ acpi_rs_extended_irq_resource (
 	 * we add 1 to the length.
 	 */
 	if (*bytes_consumed >
-		((acpi_size) output_struct->data.extended_irq.number_of_interrupts * 4) + (5 + 1)) {
+		((acpi_size) output_struct->data.extended_irq.number_of_interrupts * 4) +
+		(5 + 1)) {
 		/* Dereference the Index */
 
 		temp8 = *buffer;
@@ -417,13 +404,13 @@ acpi_rs_extended_irq_resource (
 
 		buffer += 1;
 
-		/*
-		 * Point the String pointer to the end of this structure.
-		 */
+		/* Point the String pointer to the end of this structure. */
+
 		output_struct->data.extended_irq.resource_source.string_ptr =
 				(char *)((char *) output_struct + struct_size);
 
-		temp_ptr = (u8 *) output_struct->data.extended_irq.resource_source.string_ptr;
+		temp_ptr = (u8 *)
+			output_struct->data.extended_irq.resource_source.string_ptr;
 
 		/* Copy the string into the buffer */
 
@@ -436,9 +423,8 @@ acpi_rs_extended_irq_resource (
 			index += 1;
 		}
 
-		/*
-		 * Add the terminating null
-		 */
+		/* Add the terminating null */
+
 		*temp_ptr = 0x00;
 		output_struct->data.extended_irq.resource_source.string_length = index + 1;
 
@@ -456,14 +442,12 @@ acpi_rs_extended_irq_resource (
 		output_struct->data.extended_irq.resource_source.string_ptr = NULL;
 	}
 
-	/*
-	 * Set the Length parameter
-	 */
+	/* Set the Length parameter */
+
 	output_struct->length = (u32) struct_size;
 
-	/*
-	 * Return the final size of the structure
-	 */
+	/* Return the final size of the structure */
+
 	*structure_size = struct_size;
 	return_ACPI_STATUS (AE_OK);
 }
@@ -501,21 +485,18 @@ acpi_rs_extended_irq_stream (
 	ACPI_FUNCTION_TRACE ("rs_extended_irq_stream");
 
 
-	/*
-	 * The descriptor field is static
-	 */
+	/* The descriptor field is static */
+
 	*buffer = 0x89;
 	buffer += 1;
 
-	/*
-	 * Set a pointer to the Length field - to be filled in later
-	 */
+	/* Set a pointer to the Length field - to be filled in later */
+
 	length_field = ACPI_CAST_PTR (u16, buffer);
 	buffer += 2;
 
-	/*
-	 * Set the Interrupt vector flags
-	 */
+	/* Set the Interrupt vector flags */
+
 	temp8 = (u8)(linked_list->data.extended_irq.producer_consumer & 0x01);
 	temp8 |= ((linked_list->data.extended_irq.shared_exclusive & 0x01) << 3);
 
@@ -532,17 +513,15 @@ acpi_rs_extended_irq_stream (
 		temp8 |= 0x2;
 	}
 
-	/*
-	 * Set the Interrupt Polarity
-	 */
+	/* Set the Interrupt Polarity */
+
 	temp8 |= ((linked_list->data.extended_irq.active_high_low & 0x1) << 2);
 
 	*buffer = temp8;
 	buffer += 1;
 
-	/*
-	 * Set the Interrupt table length
-	 */
+	/* Set the Interrupt table length */
+
 	temp8 = (u8) linked_list->data.extended_irq.number_of_interrupts;
 
 	*buffer = temp8;
@@ -555,18 +534,16 @@ acpi_rs_extended_irq_stream (
 		buffer += 4;
 	}
 
-	/*
-	 * Resource Source Index and Resource Source are optional
-	 */
+	/* Resource Source Index and Resource Source are optional */
+
 	if (0 != linked_list->data.extended_irq.resource_source.string_length) {
 		*buffer = (u8) linked_list->data.extended_irq.resource_source.index;
 		buffer += 1;
 
 		temp_pointer = (char *) buffer;
 
-		/*
-		 * Copy the string
-		 */
+		/* Copy the string */
+
 		ACPI_STRCPY (temp_pointer,
 			linked_list->data.extended_irq.resource_source.string_ptr);
 
@@ -574,12 +551,12 @@ acpi_rs_extended_irq_stream (
 		 * Buffer needs to be set to the length of the sting + one for the
 		 * terminating null
 		 */
-		buffer += (acpi_size)(ACPI_STRLEN (linked_list->data.extended_irq.resource_source.string_ptr) + 1);
+		buffer += (acpi_size) (ACPI_STRLEN (
+			linked_list->data.extended_irq.resource_source.string_ptr) + 1);
 	}
 
-	/*
-	 * Return the number of bytes consumed in this operation
-	 */
+	/* Return the number of bytes consumed in this operation */
+
 	*bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer);
 
 	/*
diff --git a/drivers/acpi/resources/rslist.c b/drivers/acpi/resources/rslist.c
--- a/drivers/acpi/resources/rslist.c
+++ b/drivers/acpi/resources/rslist.c
@@ -55,7 +55,7 @@
  *
  * PARAMETERS:  resource_start_byte     - Byte 0 of a resource descriptor
  *
- * RETURN:      The Resource Type (Name) with no extraneous bits
+ * RETURN:      The Resource Type with no extraneous bits
  *
  * DESCRIPTION: Extract the Resource Type/Name from the first byte of
  *              a resource descriptor.
@@ -70,28 +70,25 @@ acpi_rs_get_resource_type (
 	ACPI_FUNCTION_ENTRY ();
 
 
-	/*
-	 * Determine if this is a small or large resource
-	 */
+	/* Determine if this is a small or large resource */
+
 	switch (resource_start_byte & ACPI_RDESC_TYPE_MASK) {
 	case ACPI_RDESC_TYPE_SMALL:
 
-		/*
-		 * Small Resource Type -- Only bits 6:3 are valid
-		 */
+		/* Small Resource Type -- Only bits 6:3 are valid */
+
 		return ((u8) (resource_start_byte & ACPI_RDESC_SMALL_MASK));
 
 
 	case ACPI_RDESC_TYPE_LARGE:
 
-		/*
-		 * Large Resource Type -- All bits are valid
-		 */
+		/* Large Resource Type -- All bits are valid */
+
 		return (resource_start_byte);
 
 
 	default:
-		/* No other types of resource descriptor */
+		/* Invalid type */
 		break;
 	}
 
@@ -135,9 +132,8 @@ acpi_rs_byte_stream_to_list (
 
 	while (bytes_parsed < byte_stream_buffer_length &&
 			!end_tag_processed) {
-		/*
-		 * The next byte in the stream is the resource type
-		 */
+		/* The next byte in the stream is the resource type */
+
 		resource_type = acpi_rs_get_resource_type (*byte_stream_buffer);
 
 		switch (resource_type) {
@@ -299,28 +295,23 @@ acpi_rs_byte_stream_to_list (
 			return_ACPI_STATUS (status);
 		}
 
-		/*
-		 * Update the return value and counter
-		 */
+		/* Update the return value and counter */
+
 		bytes_parsed += bytes_consumed;
 
-		/*
-		 * Set the byte stream to point to the next resource
-		 */
+		/* Set the byte stream to point to the next resource */
+
 		byte_stream_buffer += bytes_consumed;
 
-		/*
-		 * Set the Buffer to the next structure
-		 */
+		/* Set the Buffer to the next structure */
+
 		resource = ACPI_CAST_PTR (struct acpi_resource, buffer);
 		resource->length = (u32) ACPI_ALIGN_RESOURCE_SIZE (resource->length);
 		buffer += ACPI_ALIGN_RESOURCE_SIZE (structure_size);
+	}
 
-	} /*  end while */
+	/* Check the reason for exiting the while loop */
 
-	/*
-	 * Check the reason for exiting the while loop
-	 */
 	if (!end_tag_processed) {
 		return_ACPI_STATUS (AE_AML_NO_RESOURCE_END_TAG);
 	}
@@ -424,9 +415,8 @@ acpi_rs_list_to_byte_stream (
 			 */
 			status = acpi_rs_end_tag_stream (linked_list, &buffer, &bytes_consumed);
 
-			/*
-			 * An End Tag indicates the end of the Resource Template
-			 */
+			/* An End Tag indicates the end of the Resource Template */
+
 			done = TRUE;
 			break;
 
@@ -488,27 +478,25 @@ acpi_rs_list_to_byte_stream (
 		default:
 			/*
 			 * If we get here, everything is out of sync,
-			 *  so exit with an error
+			 * so exit with an error
 			 */
-			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid descriptor type (%X) in resource list\n",
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+				"Invalid descriptor type (%X) in resource list\n",
 				linked_list->id));
 			status = AE_BAD_DATA;
 			break;
-
-		} /* switch (linked_list->Id) */
+		}
 
 		if (ACPI_FAILURE (status)) {
 			return_ACPI_STATUS (status);
 		}
 
-		/*
-		 * Set the Buffer to point to the open byte
-		 */
+		/* Set the Buffer to point to the open byte */
+
 		buffer += bytes_consumed;
 
-		/*
-		 * Point to the next object
-		 */
+		/* Point to the next object */
+
 		linked_list = ACPI_PTR_ADD (struct acpi_resource,
 				  linked_list, linked_list->length);
 	}
diff --git a/drivers/acpi/resources/rsmemory.c b/drivers/acpi/resources/rsmemory.c
--- a/drivers/acpi/resources/rsmemory.c
+++ b/drivers/acpi/resources/rsmemory.c
@@ -81,15 +81,15 @@ acpi_rs_memory24_resource (
 	struct acpi_resource            *output_struct = (void *) *output_buffer;
 	u16                             temp16 = 0;
 	u8                              temp8 = 0;
-	acpi_size                       struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_mem24);
+	acpi_size                       struct_size = ACPI_SIZEOF_RESOURCE (
+			  struct acpi_resource_mem24);
 
 
 	ACPI_FUNCTION_TRACE ("rs_memory24_resource");
 
 
-	/*
-	 * Point past the Descriptor to get the number of bytes consumed
-	 */
+	/* Point past the Descriptor to get the number of bytes consumed */
+
 	buffer += 1;
 
 	ACPI_MOVE_16_TO_16 (&temp16, buffer);
@@ -97,48 +97,41 @@ acpi_rs_memory24_resource (
 	*bytes_consumed = (acpi_size) temp16 + 3;
 	output_struct->id = ACPI_RSTYPE_MEM24;
 
-	/*
-	 * Check Byte 3 the Read/Write bit
-	 */
+	/* Check Byte 3 the Read/Write bit */
+
 	temp8 = *buffer;
 	buffer += 1;
 	output_struct->data.memory24.read_write_attribute = temp8 & 0x01;
 
-	/*
-	 * Get min_base_address (Bytes 4-5)
-	 */
+	/* Get min_base_address (Bytes 4-5) */
+
 	ACPI_MOVE_16_TO_16 (&temp16, buffer);
 	buffer += 2;
 	output_struct->data.memory24.min_base_address = temp16;
 
-	/*
-	 * Get max_base_address (Bytes 6-7)
-	 */
+	/* Get max_base_address (Bytes 6-7) */
+
 	ACPI_MOVE_16_TO_16 (&temp16, buffer);
 	buffer += 2;
 	output_struct->data.memory24.max_base_address = temp16;
 
-	/*
-	 * Get Alignment (Bytes 8-9)
-	 */
+	/* Get Alignment (Bytes 8-9) */
+
 	ACPI_MOVE_16_TO_16 (&temp16, buffer);
 	buffer += 2;
 	output_struct->data.memory24.alignment = temp16;
 
-	/*
-	 * Get range_length (Bytes 10-11)
-	 */
+	/* Get range_length (Bytes 10-11) */
+
 	ACPI_MOVE_16_TO_16 (&temp16, buffer);
 	output_struct->data.memory24.range_length = temp16;
 
-	/*
-	 * Set the Length parameter
-	 */
+	/* Set the Length parameter */
+
 	output_struct->length = (u32) struct_size;
 
-	/*
-	 * Return the final size of the structure
-	 */
+	/* Return the final size of the structure */
+
 	*structure_size = struct_size;
 	return_ACPI_STATUS (AE_OK);
 }
@@ -174,53 +167,45 @@ acpi_rs_memory24_stream (
 	ACPI_FUNCTION_TRACE ("rs_memory24_stream");
 
 
-	/*
-	 * The descriptor field is static
-	 */
+	/* The descriptor field is static */
+
 	*buffer = 0x81;
 	buffer += 1;
 
-	/*
-	 * The length field is static
-	 */
+	/* The length field is static */
+
 	temp16 = 0x09;
 	ACPI_MOVE_16_TO_16 (buffer, &temp16);
 	buffer += 2;
 
-	/*
-	 * Set the Information Byte
-	 */
+	/* Set the Information Byte */
+
 	temp8 = (u8) (linked_list->data.memory24.read_write_attribute & 0x01);
 	*buffer = temp8;
 	buffer += 1;
 
-	/*
-	 * Set the Range minimum base address
-	 */
+	/* Set the Range minimum base address */
+
 	ACPI_MOVE_32_TO_16 (buffer, &linked_list->data.memory24.min_base_address);
 	buffer += 2;
 
-	/*
-	 * Set the Range maximum base address
-	 */
+	/* Set the Range maximum base address */
+
 	ACPI_MOVE_32_TO_16 (buffer, &linked_list->data.memory24.max_base_address);
 	buffer += 2;
 
-	/*
-	 * Set the base alignment
-	 */
+	/* Set the base alignment */
+
 	ACPI_MOVE_32_TO_16 (buffer, &linked_list->data.memory24.alignment);
 	buffer += 2;
 
-	/*
-	 * Set the range length
-	 */
+	/* Set the range length */
+
 	ACPI_MOVE_32_TO_16 (buffer, &linked_list->data.memory24.range_length);
 	buffer += 2;
 
-	/*
-	 * Return the number of bytes consumed in this operation
-	 */
+	/* Return the number of bytes consumed in this operation */
+
 	*bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer);
 	return_ACPI_STATUS (AE_OK);
 }
@@ -258,15 +243,15 @@ acpi_rs_memory32_range_resource (
 	struct acpi_resource            *output_struct = (void *) *output_buffer;
 	u16                             temp16 = 0;
 	u8                              temp8 = 0;
-	acpi_size                       struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_mem32);
+	acpi_size                       struct_size = ACPI_SIZEOF_RESOURCE (
+			  struct acpi_resource_mem32);
 
 
 	ACPI_FUNCTION_TRACE ("rs_memory32_range_resource");
 
 
-	/*
-	 * Point past the Descriptor to get the number of bytes consumed
-	 */
+	/* Point past the Descriptor to get the number of bytes consumed */
+
 	buffer += 1;
 
 	ACPI_MOVE_16_TO_16 (&temp16, buffer);
@@ -285,45 +270,38 @@ acpi_rs_memory32_range_resource (
 	 *  4 * sizeof(RESOURCE_DATA) instead of 4 * sizeof(u8)
 	 */
 
-	/*
-	 * Check Byte 3 the Read/Write bit
-	 */
+	/* Check Byte 3 the Read/Write bit */
+
 	temp8 = *buffer;
 	buffer += 1;
 
 	output_struct->data.memory32.read_write_attribute = temp8 & 0x01;
 
-	/*
-	 * Get min_base_address (Bytes 4-7)
-	 */
+	/* Get min_base_address (Bytes 4-7) */
+
 	ACPI_MOVE_32_TO_32 (&output_struct->data.memory32.min_base_address, buffer);
 	buffer += 4;
 
-	/*
-	 * Get max_base_address (Bytes 8-11)
-	 */
+	/* Get max_base_address (Bytes 8-11) */
+
 	ACPI_MOVE_32_TO_32 (&output_struct->data.memory32.max_base_address, buffer);
 	buffer += 4;
 
-	/*
-	 * Get Alignment (Bytes 12-15)
-	 */
+	/* Get Alignment (Bytes 12-15) */
+
 	ACPI_MOVE_32_TO_32 (&output_struct->data.memory32.alignment, buffer);
 	buffer += 4;
 
-	/*
-	 * Get range_length (Bytes 16-19)
-	 */
+	/* Get range_length (Bytes 16-19) */
+
 	ACPI_MOVE_32_TO_32 (&output_struct->data.memory32.range_length, buffer);
 
-	/*
-	 * Set the Length parameter
-	 */
+	/* Set the Length parameter */
+
 	output_struct->length = (u32) struct_size;
 
-	/*
-	 * Return the final size of the structure
-	 */
+	/* Return the final size of the structure */
+
 	*structure_size = struct_size;
 	return_ACPI_STATUS (AE_OK);
 }
@@ -361,15 +339,15 @@ acpi_rs_fixed_memory32_resource (
 	struct acpi_resource            *output_struct = (void *) *output_buffer;
 	u16                             temp16 = 0;
 	u8                              temp8 = 0;
-	acpi_size                       struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_fixed_mem32);
+	acpi_size                       struct_size = ACPI_SIZEOF_RESOURCE (
+			  struct acpi_resource_fixed_mem32);
 
 
 	ACPI_FUNCTION_TRACE ("rs_fixed_memory32_resource");
 
 
-	/*
-	 * Point past the Descriptor to get the number of bytes consumed
-	 */
+	/* Point past the Descriptor to get the number of bytes consumed */
+
 	buffer += 1;
 	ACPI_MOVE_16_TO_16 (&temp16, buffer);
 
@@ -378,32 +356,28 @@ acpi_rs_fixed_memory32_resource (
 
 	output_struct->id = ACPI_RSTYPE_FIXED_MEM32;
 
-	/*
-	 * Check Byte 3 the Read/Write bit
-	 */
+	/* Check Byte 3 the Read/Write bit */
+
 	temp8 = *buffer;
 	buffer += 1;
 	output_struct->data.fixed_memory32.read_write_attribute = temp8 & 0x01;
 
-	/*
-	 * Get range_base_address (Bytes 4-7)
-	 */
-	ACPI_MOVE_32_TO_32 (&output_struct->data.fixed_memory32.range_base_address, buffer);
+	/* Get range_base_address (Bytes 4-7) */
+
+	ACPI_MOVE_32_TO_32 (&output_struct->data.fixed_memory32.range_base_address,
+		buffer);
 	buffer += 4;
 
-	/*
-	 * Get range_length (Bytes 8-11)
-	 */
+	/* Get range_length (Bytes 8-11) */
+
 	ACPI_MOVE_32_TO_32 (&output_struct->data.fixed_memory32.range_length, buffer);
 
-	/*
-	 * Set the Length parameter
-	 */
+	/* Set the Length parameter */
+
 	output_struct->length = (u32) struct_size;
 
-	/*
-	 * Return the final size of the structure
-	 */
+	/* Return the final size of the structure */
+
 	*structure_size = struct_size;
 	return_ACPI_STATUS (AE_OK);
 }
@@ -439,54 +413,46 @@ acpi_rs_memory32_range_stream (
 	ACPI_FUNCTION_TRACE ("rs_memory32_range_stream");
 
 
-	/*
-	 * The descriptor field is static
-	 */
+	/* The descriptor field is static */
+
 	*buffer = 0x85;
 	buffer += 1;
 
-	/*
-	 * The length field is static
-	 */
+	/* The length field is static */
+
 	temp16 = 0x11;
 
 	ACPI_MOVE_16_TO_16 (buffer, &temp16);
 	buffer += 2;
 
-	/*
-	 * Set the Information Byte
-	 */
+	/* Set the Information Byte */
+
 	temp8 = (u8) (linked_list->data.memory32.read_write_attribute & 0x01);
 	*buffer = temp8;
 	buffer += 1;
 
-	/*
-	 * Set the Range minimum base address
-	 */
+	/* Set the Range minimum base address */
+
 	ACPI_MOVE_32_TO_32 (buffer, &linked_list->data.memory32.min_base_address);
 	buffer += 4;
 
-	/*
-	 * Set the Range maximum base address
-	 */
+	/* Set the Range maximum base address */
+
 	ACPI_MOVE_32_TO_32 (buffer, &linked_list->data.memory32.max_base_address);
 	buffer += 4;
 
-	/*
-	 * Set the base alignment
-	 */
+	/* Set the base alignment */
+
 	ACPI_MOVE_32_TO_32 (buffer, &linked_list->data.memory32.alignment);
 	buffer += 4;
 
-	/*
-	 * Set the range length
-	 */
+	/* Set the range length */
+
 	ACPI_MOVE_32_TO_32 (buffer, &linked_list->data.memory32.range_length);
 	buffer += 4;
 
-	/*
-	 * Return the number of bytes consumed in this operation
-	 */
+	/* Return the number of bytes consumed in this operation */
+
 	*bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer);
 	return_ACPI_STATUS (AE_OK);
 }
@@ -522,44 +488,38 @@ acpi_rs_fixed_memory32_stream (
 	ACPI_FUNCTION_TRACE ("rs_fixed_memory32_stream");
 
 
-	/*
-	 * The descriptor field is static
-	 */
+	/* The descriptor field is static */
+
 	*buffer = 0x86;
 	buffer += 1;
 
-	/*
-	 * The length field is static
-	 */
+	/* The length field is static */
+
 	temp16 = 0x09;
 
 	ACPI_MOVE_16_TO_16 (buffer, &temp16);
 	buffer += 2;
 
-	/*
-	 * Set the Information Byte
-	 */
+	/* Set the Information Byte */
+
 	temp8 = (u8) (linked_list->data.fixed_memory32.read_write_attribute & 0x01);
 	*buffer = temp8;
 	buffer += 1;
 
-	/*
-	 * Set the Range base address
-	 */
+	/* Set the Range base address */
+
 	ACPI_MOVE_32_TO_32 (buffer,
-			 &linked_list->data.fixed_memory32.range_base_address);
+		&linked_list->data.fixed_memory32.range_base_address);
 	buffer += 4;
 
-	/*
-	 * Set the range length
-	 */
+	/* Set the range length */
+
 	ACPI_MOVE_32_TO_32 (buffer,
-			 &linked_list->data.fixed_memory32.range_length);
+		&linked_list->data.fixed_memory32.range_length);
 	buffer += 4;
 
-	/*
-	 * Return the number of bytes consumed in this operation
-	 */
+	/* Return the number of bytes consumed in this operation */
+
 	*bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer);
 	return_ACPI_STATUS (AE_OK);
 }
diff --git a/drivers/acpi/resources/rsmisc.c b/drivers/acpi/resources/rsmisc.c
--- a/drivers/acpi/resources/rsmisc.c
+++ b/drivers/acpi/resources/rsmisc.c
@@ -84,24 +84,20 @@ acpi_rs_end_tag_resource (
 	ACPI_FUNCTION_TRACE ("rs_end_tag_resource");
 
 
-	/*
-	 * The number of bytes consumed is static
-	 */
+	/* The number of bytes consumed is static */
+
 	*bytes_consumed = 2;
 
-	/*
-	 *  Fill out the structure
-	 */
+	/*  Fill out the structure */
+
 	output_struct->id = ACPI_RSTYPE_END_TAG;
 
-	/*
-	 * Set the Length parameter
-	 */
+	/* Set the Length parameter */
+
 	output_struct->length = 0;
 
-	/*
-	 * Return the final size of the structure
-	 */
+	/* Return the final size of the structure */
+
 	*structure_size = struct_size;
 	return_ACPI_STATUS (AE_OK);
 }
@@ -136,9 +132,8 @@ acpi_rs_end_tag_stream (
 	ACPI_FUNCTION_TRACE ("rs_end_tag_stream");
 
 
-	/*
-	 * The descriptor field is static
-	 */
+	/* The descriptor field is static */
+
 	*buffer = 0x79;
 	buffer += 1;
 
@@ -151,9 +146,8 @@ acpi_rs_end_tag_stream (
 	*buffer = temp8;
 	buffer += 1;
 
-	/*
-	 * Return the number of bytes consumed in this operation
-	 */
+	/* Return the number of bytes consumed in this operation */
+
 	*bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer);
 	return_ACPI_STATUS (AE_OK);
 }
@@ -192,21 +186,20 @@ acpi_rs_vendor_resource (
 	u16                             temp16 = 0;
 	u8                              temp8 = 0;
 	u8                              index;
-	acpi_size                       struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_vendor);
+	acpi_size                       struct_size = ACPI_SIZEOF_RESOURCE (
+			  struct acpi_resource_vendor);
 
 
 	ACPI_FUNCTION_TRACE ("rs_vendor_resource");
 
 
-	/*
-	 * Dereference the Descriptor to find if this is a large or small item.
-	 */
+	/* Dereference the Descriptor to find if this is a large or small item. */
+
 	temp8 = *buffer;
 
 	if (temp8 & 0x80) {
-		/*
-		 * Large Item, point to the length field
-		 */
+		/* Large Item, point to the length field */
+
 		buffer += 1;
 
 		/* Dereference */
@@ -222,9 +215,8 @@ acpi_rs_vendor_resource (
 		buffer += 2;
 	}
 	else {
-		/*
-		 * Small Item, dereference the size
-		 */
+		/* Small Item, dereference the size */
+
 		temp16 = (u8)(*buffer & 0x07);
 
 		/* Calculate bytes consumed */
@@ -251,14 +243,12 @@ acpi_rs_vendor_resource (
 	 */
 	struct_size += ACPI_ROUND_UP_to_32_bITS (temp16);
 
-	/*
-	 * Set the Length parameter
-	 */
+	/* Set the Length parameter */
+
 	output_struct->length = (u32) struct_size;
 
-	/*
-	 * Return the final size of the structure
-	 */
+	/* Return the final size of the structure */
+
 	*structure_size = struct_size;
 	return_ACPI_STATUS (AE_OK);
 }
@@ -295,13 +285,11 @@ acpi_rs_vendor_stream (
 	ACPI_FUNCTION_TRACE ("rs_vendor_stream");
 
 
-	/*
-	 * Dereference the length to find if this is a large or small item.
-	 */
+	/* Dereference the length to find if this is a large or small item. */
+
 	if(linked_list->data.vendor_specific.length > 7) {
-		/*
-		 * Large Item, Set the descriptor field and length bytes
-		 */
+		/* Large Item, Set the descriptor field and length bytes */
+
 		*buffer = 0x84;
 		buffer += 1;
 
@@ -311,9 +299,8 @@ acpi_rs_vendor_stream (
 		buffer += 2;
 	}
 	else {
-		/*
-		 * Small Item, Set the descriptor field
-		 */
+		/* Small Item, Set the descriptor field */
+
 		temp8 = 0x70;
 		temp8 |= (u8) linked_list->data.vendor_specific.length;
 
@@ -321,9 +308,8 @@ acpi_rs_vendor_stream (
 		buffer += 1;
 	}
 
-	/*
-	 * Loop through all of the Vendor Specific fields
-	 */
+	/* Loop through all of the Vendor Specific fields */
+
 	for (index = 0; index < linked_list->data.vendor_specific.length; index++) {
 		temp8 = linked_list->data.vendor_specific.reserved[index];
 
@@ -331,9 +317,8 @@ acpi_rs_vendor_stream (
 		buffer += 1;
 	}
 
-	/*
-	 * Return the number of bytes consumed in this operation
-	 */
+	/* Return the number of bytes consumed in this operation */
+
 	*bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer);
 	return_ACPI_STATUS (AE_OK);
 }
@@ -370,40 +355,37 @@ acpi_rs_start_depend_fns_resource (
 	u8                              *buffer = byte_stream_buffer;
 	struct acpi_resource            *output_struct = (void *) *output_buffer;
 	u8                              temp8 = 0;
-	acpi_size                       struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_start_dpf);
+	acpi_size                       struct_size = ACPI_SIZEOF_RESOURCE (
+			  struct acpi_resource_start_dpf);
 
 
 	ACPI_FUNCTION_TRACE ("rs_start_depend_fns_resource");
 
 
-	/*
-	 * The number of bytes consumed are contained in the descriptor (Bits:0-1)
-	 */
+	/* The number of bytes consumed are found in the descriptor (Bits:0-1) */
+
 	temp8 = *buffer;
 
 	*bytes_consumed = (temp8 & 0x01) + 1;
 
 	output_struct->id = ACPI_RSTYPE_START_DPF;
 
-	/*
-	 * Point to Byte 1 if it is used
-	 */
+	/* Point to Byte 1 if it is used */
+
 	if (2 == *bytes_consumed) {
 		buffer += 1;
 		temp8 = *buffer;
 
-		/*
-		 * Check Compatibility priority
-		 */
+		/* Check Compatibility priority */
+
 		output_struct->data.start_dpf.compatibility_priority = temp8 & 0x03;
 
 		if (3 == output_struct->data.start_dpf.compatibility_priority) {
 			return_ACPI_STATUS (AE_AML_BAD_RESOURCE_VALUE);
 		}
 
-		/*
-		 * Check Performance/Robustness preference
-		 */
+		/* Check Performance/Robustness preference */
+
 		output_struct->data.start_dpf.performance_robustness = (temp8 >> 2) & 0x03;
 
 		if (3 == output_struct->data.start_dpf.performance_robustness) {
@@ -412,20 +394,18 @@ acpi_rs_start_depend_fns_resource (
 	}
 	else {
 		output_struct->data.start_dpf.compatibility_priority =
-				ACPI_ACCEPTABLE_CONFIGURATION;
+			ACPI_ACCEPTABLE_CONFIGURATION;
 
 		output_struct->data.start_dpf.performance_robustness =
-				ACPI_ACCEPTABLE_CONFIGURATION;
+			ACPI_ACCEPTABLE_CONFIGURATION;
 	}
 
-	/*
-	 * Set the Length parameter
-	 */
+	/* Set the Length parameter */
+
 	output_struct->length = (u32) struct_size;
 
-	/*
-	 * Return the final size of the structure
-	 */
+	/* Return the final size of the structure */
+
 	*structure_size = struct_size;
 	return_ACPI_STATUS (AE_OK);
 }
@@ -466,24 +446,20 @@ acpi_rs_end_depend_fns_resource (
 	ACPI_FUNCTION_TRACE ("rs_end_depend_fns_resource");
 
 
-	/*
-	 * The number of bytes consumed is static
-	 */
+	/* The number of bytes consumed is static */
+
 	*bytes_consumed = 1;
 
-	/*
-	 *  Fill out the structure
-	 */
+	/*  Fill out the structure */
+
 	output_struct->id = ACPI_RSTYPE_END_DPF;
 
-	/*
-	 * Set the Length parameter
-	 */
+	/* Set the Length parameter */
+
 	output_struct->length = (u32) struct_size;
 
-	/*
-	 * Return the final size of the structure
-	 */
+	/* Return the final size of the structure */
+
 	*structure_size = struct_size;
 	return_ACPI_STATUS (AE_OK);
 }
@@ -533,9 +509,8 @@ acpi_rs_start_depend_fns_stream (
 		*buffer = 0x31;
 		buffer += 1;
 
-		/*
-		 * Set the Priority Byte Definition
-		 */
+		/* Set the Priority Byte Definition */
+
 		temp8 = 0;
 		temp8 = (u8) ((linked_list->data.start_dpf.performance_robustness &
 				   0x03) << 2);
@@ -546,9 +521,8 @@ acpi_rs_start_depend_fns_stream (
 
 	buffer += 1;
 
-	/*
-	 * Return the number of bytes consumed in this operation
-	 */
+	/* Return the number of bytes consumed in this operation */
+
 	*bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer);
 	return_ACPI_STATUS (AE_OK);
 }
@@ -582,15 +556,13 @@ acpi_rs_end_depend_fns_stream (
 	ACPI_FUNCTION_TRACE ("rs_end_depend_fns_stream");
 
 
-	/*
-	 * The descriptor field is static
-	 */
+	/* The descriptor field is static */
+
 	*buffer = 0x38;
 	buffer += 1;
 
-	/*
-	 * Return the number of bytes consumed in this operation
-	 */
+	/* Return the number of bytes consumed in this operation */
+
 	*bytes_consumed = ACPI_PTR_DIFF (buffer, *output_buffer);
 	return_ACPI_STATUS (AE_OK);
 }
diff --git a/drivers/acpi/resources/rsutils.c b/drivers/acpi/resources/rsutils.c
--- a/drivers/acpi/resources/rsutils.c
+++ b/drivers/acpi/resources/rsutils.c
@@ -83,10 +83,10 @@ acpi_rs_get_prt_method_data (
 
 	/* Parameters guaranteed valid by caller */
 
-	/*
-	 * Execute the method, no parameters
-	 */
-	status = acpi_ut_evaluate_object (handle, "_PRT", ACPI_BTYPE_PACKAGE, &obj_desc);
+	/* Execute the method, no parameters */
+
+	status = acpi_ut_evaluate_object (handle, METHOD_NAME__PRT,
+			 ACPI_BTYPE_PACKAGE, &obj_desc);
 	if (ACPI_FAILURE (status)) {
 		return_ACPI_STATUS (status);
 	}
@@ -136,10 +136,10 @@ acpi_rs_get_crs_method_data (
 
 	/* Parameters guaranteed valid by caller */
 
-	/*
-	 * Execute the method, no parameters
-	 */
-	status = acpi_ut_evaluate_object (handle, "_CRS", ACPI_BTYPE_BUFFER, &obj_desc);
+	/* Execute the method, no parameters */
+
+	status = acpi_ut_evaluate_object (handle, METHOD_NAME__CRS,
+			 ACPI_BTYPE_BUFFER, &obj_desc);
 	if (ACPI_FAILURE (status)) {
 		return_ACPI_STATUS (status);
 	}
@@ -175,6 +175,7 @@ acpi_rs_get_crs_method_data (
  *              and the contents of the callers buffer is undefined.
  *
  ******************************************************************************/
+
 #ifdef ACPI_FUTURE_USAGE
 acpi_status
 acpi_rs_get_prs_method_data (
@@ -190,10 +191,10 @@ acpi_rs_get_prs_method_data (
 
 	/* Parameters guaranteed valid by caller */
 
-	/*
-	 * Execute the method, no parameters
-	 */
-	status = acpi_ut_evaluate_object (handle, "_PRS", ACPI_BTYPE_BUFFER, &obj_desc);
+	/* Execute the method, no parameters */
+
+	status = acpi_ut_evaluate_object (handle, METHOD_NAME__PRS,
+			 ACPI_BTYPE_BUFFER, &obj_desc);
 	if (ACPI_FAILURE (status)) {
 		return_ACPI_STATUS (status);
 	}
@@ -218,6 +219,7 @@ acpi_rs_get_prs_method_data (
  * FUNCTION:    acpi_rs_get_method_data
  *
  * PARAMETERS:  Handle          - a handle to the containing object
+ *              Path            - Path to method, relative to Handle
  *              ret_buffer      - a pointer to a buffer structure for the
  *                                  results
  *
@@ -246,9 +248,8 @@ acpi_rs_get_method_data (
 
 	/* Parameters guaranteed valid by caller */
 
-	/*
-	 * Execute the method, no parameters
-	 */
+	/* Execute the method, no parameters */
+
 	status = acpi_ut_evaluate_object (handle, path, ACPI_BTYPE_BUFFER, &obj_desc);
 	if (ACPI_FAILURE (status)) {
 		return_ACPI_STATUS (status);
@@ -314,18 +315,16 @@ acpi_rs_set_srs_method_data (
 		return_ACPI_STATUS (status);
 	}
 
-	/*
-	 * Init the param object
-	 */
+	/* Init the param object */
+
 	params[0] = acpi_ut_create_internal_object (ACPI_TYPE_BUFFER);
 	if (!params[0]) {
 		acpi_os_free (buffer.pointer);
 		return_ACPI_STATUS (AE_NO_MEMORY);
 	}
 
-	/*
-	 * Set up the parameter object
-	 */
+	/* Set up the parameter object */
+
 	params[0]->buffer.length  = (u32) buffer.length;
 	params[0]->buffer.pointer = buffer.pointer;
 	params[0]->common.flags   = AOPOBJ_DATA_VALID;
@@ -335,10 +334,9 @@ acpi_rs_set_srs_method_data (
 	info.parameters = params;
 	info.parameter_type = ACPI_PARAM_ARGS;
 
-	/*
-	 * Execute the method, no return value
-	 */
-	status = acpi_ns_evaluate_relative ("_SRS", &info);
+	/* Execute the method, no return value */
+
+	status = acpi_ns_evaluate_relative (METHOD_NAME__SRS, &info);
 	if (ACPI_SUCCESS (status)) {
 		/* Delete any return object (especially if implicit_return is enabled) */
 
@@ -347,9 +345,8 @@ acpi_rs_set_srs_method_data (
 		}
 	}
 
-	/*
-	 * Clean up and return the status from acpi_ns_evaluate_relative
-	 */
+	/* Clean up and return the status from acpi_ns_evaluate_relative */
+
 	acpi_ut_remove_reference (params[0]);
 	return_ACPI_STATUS (status);
 }
diff --git a/drivers/acpi/resources/rsxface.c b/drivers/acpi/resources/rsxface.c
--- a/drivers/acpi/resources/rsxface.c
+++ b/drivers/acpi/resources/rsxface.c
@@ -49,6 +49,23 @@
 #define _COMPONENT          ACPI_RESOURCES
 	 ACPI_MODULE_NAME    ("rsxface")
 
+/* Local macros for 16,32-bit to 64-bit conversion */
+
+#define ACPI_COPY_FIELD(out, in, field)  ((out)->field = (in)->field)
+#define ACPI_COPY_ADDRESS(out, in)                      \
+	ACPI_COPY_FIELD(out, in, resource_type);             \
+	ACPI_COPY_FIELD(out, in, producer_consumer);         \
+	ACPI_COPY_FIELD(out, in, decode);                    \
+	ACPI_COPY_FIELD(out, in, min_address_fixed);         \
+	ACPI_COPY_FIELD(out, in, max_address_fixed);         \
+	ACPI_COPY_FIELD(out, in, attribute);                 \
+	ACPI_COPY_FIELD(out, in, granularity);               \
+	ACPI_COPY_FIELD(out, in, min_address_range);         \
+	ACPI_COPY_FIELD(out, in, max_address_range);         \
+	ACPI_COPY_FIELD(out, in, address_translation_offset); \
+	ACPI_COPY_FIELD(out, in, address_length);            \
+	ACPI_COPY_FIELD(out, in, resource_source);
+
 
 /*******************************************************************************
  *
@@ -180,6 +197,7 @@ EXPORT_SYMBOL(acpi_get_current_resources
  *              and the value of ret_buffer is undefined.
  *
  ******************************************************************************/
+
 #ifdef ACPI_FUTURE_USAGE
 acpi_status
 acpi_get_possible_resources (
@@ -346,9 +364,8 @@ acpi_set_current_resources (
 	ACPI_FUNCTION_TRACE ("acpi_set_current_resources");
 
 
-	/*
-	 * Must have a valid handle and buffer
-	 */
+	/* Must have a valid handle and buffer */
+
 	if ((!device_handle)      ||
 		(!in_buffer)          ||
 		(!in_buffer->pointer) ||
@@ -362,21 +379,6 @@ acpi_set_current_resources (
 EXPORT_SYMBOL(acpi_set_current_resources);
 
 
-#define ACPI_COPY_FIELD(out, in, field)  ((out)->field = (in)->field)
-#define ACPI_COPY_ADDRESS(out, in)                      \
-	ACPI_COPY_FIELD(out, in, resource_type);             \
-	ACPI_COPY_FIELD(out, in, producer_consumer);         \
-	ACPI_COPY_FIELD(out, in, decode);                    \
-	ACPI_COPY_FIELD(out, in, min_address_fixed);         \
-	ACPI_COPY_FIELD(out, in, max_address_fixed);         \
-	ACPI_COPY_FIELD(out, in, attribute);                 \
-	ACPI_COPY_FIELD(out, in, granularity);               \
-	ACPI_COPY_FIELD(out, in, min_address_range);         \
-	ACPI_COPY_FIELD(out, in, max_address_range);         \
-	ACPI_COPY_FIELD(out, in, address_translation_offset); \
-	ACPI_COPY_FIELD(out, in, address_length);            \
-	ACPI_COPY_FIELD(out, in, resource_source);
-
 /******************************************************************************
  *
  * FUNCTION:    acpi_resource_to_address64
@@ -408,14 +410,14 @@ acpi_resource_to_address64 (
 	case ACPI_RSTYPE_ADDRESS16:
 
 		address16 = (struct acpi_resource_address16 *) &resource->data;
-		ACPI_COPY_ADDRESS(out, address16);
+		ACPI_COPY_ADDRESS (out, address16);
 		break;
 
 
 	case ACPI_RSTYPE_ADDRESS32:
 
 		address32 = (struct acpi_resource_address32 *) &resource->data;
-		ACPI_COPY_ADDRESS(out, address32);
+		ACPI_COPY_ADDRESS (out, address32);
 		break;
 
 
@@ -434,4 +436,3 @@ acpi_resource_to_address64 (
 	return (AE_OK);
 }
 EXPORT_SYMBOL(acpi_resource_to_address64);
-
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -65,14 +65,14 @@ static ssize_t acpi_device_attr_show(str
 {
 	struct acpi_device *device = to_acpi_device(kobj);
 	struct acpi_device_attribute *attribute = to_handle_attr(attr);
-	return attribute->show ? attribute->show(device, buf) : 0;
+	return attribute->show ? attribute->show(device, buf) : -EIO;
 }
 static ssize_t acpi_device_attr_store(struct kobject *kobj,
 		struct attribute *attr, const char *buf, size_t len)
 {
 	struct acpi_device *device = to_acpi_device(kobj);
 	struct acpi_device_attribute *attribute = to_handle_attr(attr);
-	return attribute->store ? attribute->store(device, buf, len) : len;
+	return attribute->store ? attribute->store(device, buf, len) : -EIO;
 }
 
 static struct sysfs_ops acpi_device_sysfs_ops = {
@@ -553,20 +553,29 @@ acpi_bus_driver_init (
 	 * upon possible configuration and currently allocated resources.
 	 */
 
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Driver successfully bound to device\n"));
+	return_VALUE(0);
+}
+
+int
+acpi_start_single_object (
+		struct acpi_device *device)
+{
+	int result = 0;
+	struct acpi_driver *driver;
+
+	ACPI_FUNCTION_TRACE("acpi_start_single_object");
+
+	if (!(driver = device->driver))
+		return_VALUE(0);
+
 	if (driver->ops.start) {
 		result = driver->ops.start(device);
 		if (result && driver->ops.remove)
 			driver->ops.remove(device, ACPI_BUS_REMOVAL_NORMAL);
-		return_VALUE(result);
 	}
 
-	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Driver successfully bound to device\n"));
-
-	if (driver->ops.scan) {
-		driver->ops.scan(device);
-	}
-
-	return_VALUE(0);
+	return_VALUE(result);
 }
 
 static int acpi_driver_attach(struct acpi_driver * drv)
@@ -586,6 +595,7 @@ static int acpi_driver_attach(struct acp
 
 		if (!acpi_bus_match(dev, drv)) {
 			if (!acpi_bus_driver_init(dev, drv)) {
+				acpi_start_single_object(dev);
 				atomic_inc(&drv->references);
 				count++;
 				ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found driver [%s] for device [%s]\n",
@@ -1009,8 +1019,8 @@ acpi_bus_remove (
 }
 
 
-int
-acpi_bus_add (
+static int
+acpi_add_single_object (
 	struct acpi_device	**child,
 	struct acpi_device	*parent,
 	acpi_handle		handle,
@@ -1019,7 +1029,7 @@ acpi_bus_add (
 	int			result = 0;
 	struct acpi_device	*device = NULL;
 
-	ACPI_FUNCTION_TRACE("acpi_bus_add");
+	ACPI_FUNCTION_TRACE("acpi_add_single_object");
 
 	if (!child)
 		return_VALUE(-EINVAL);
@@ -1051,13 +1061,15 @@ acpi_bus_add (
 	/*
 	 * Status
 	 * ------
-	 * See if the device is present.  We always assume that non-Device()
-	 * objects (e.g. thermal zones, power resources, processors, etc.) are
-	 * present, functioning, etc. (at least when parent object is present).
-	 * Note that _STA has a different meaning for some objects (e.g.
-	 * power resources) so we need to be careful how we use it.
+	 * See if the device is present.  We always assume that non-Device
+	 * and non-Processor objects (e.g. thermal zones, power resources,
+	 * etc.) are present, functioning, etc. (at least when parent object
+	 * is present).  Note that _STA has a different meaning for some
+	 * objects (e.g. power resources) so we need to be careful how we use
+	 * it.
 	 */
 	switch (type) {
+	case ACPI_BUS_TYPE_PROCESSOR:
 	case ACPI_BUS_TYPE_DEVICE:
 		result = acpi_bus_get_status(device);
 		if (ACPI_FAILURE(result) || !device->status.present) {
@@ -1140,7 +1152,7 @@ acpi_bus_add (
 	 *
 	 * TBD: Assumes LDM provides driver hot-plug capability.
 	 */
-	acpi_bus_find_driver(device);
+	result = acpi_bus_find_driver(device);
 
 end:
 	if (!result)
@@ -1153,10 +1165,10 @@ end:
 
 	return_VALUE(result);
 }
-EXPORT_SYMBOL(acpi_bus_add);
 
 
-int acpi_bus_scan (struct acpi_device	*start)
+static int acpi_bus_scan (struct acpi_device	*start,
+		struct acpi_bus_ops *ops)
 {
 	acpi_status		status = AE_OK;
 	struct acpi_device	*parent = NULL;
@@ -1229,9 +1241,20 @@ int acpi_bus_scan (struct acpi_device	*s
 			continue;
 		}
 
-		status = acpi_bus_add(&child, parent, chandle, type);
-		if (ACPI_FAILURE(status))
-			continue;
+		if (ops->acpi_op_add)
+			status = acpi_add_single_object(&child, parent,
+					chandle, type);
+		 else
+			status = acpi_bus_get_device(chandle, &child);
+
+		 if (ACPI_FAILURE(status))
+			 continue;
+
+		if (ops->acpi_op_start) {
+			status = acpi_start_single_object(child);
+			if (ACPI_FAILURE(status))
+				continue;
+		}
 
 		/*
 		 * If the device is present, enabled, and functioning then
@@ -1257,8 +1280,50 @@ int acpi_bus_scan (struct acpi_device	*s
 
 	return_VALUE(0);
 }
-EXPORT_SYMBOL(acpi_bus_scan);
 
+int
+acpi_bus_add (
+	struct acpi_device	**child,
+	struct acpi_device	*parent,
+	acpi_handle		handle,
+	int			type)
+{
+	int result;
+	struct acpi_bus_ops ops;
+
+	ACPI_FUNCTION_TRACE("acpi_bus_add");
+
+	result = acpi_add_single_object(child, parent, handle, type);
+	if (!result) {
+		memset(&ops, 0, sizeof(ops));
+		ops.acpi_op_add = 1;
+		result = acpi_bus_scan(*child, &ops);
+	}
+	return_VALUE(result);
+}
+EXPORT_SYMBOL(acpi_bus_add);
+
+int
+acpi_bus_start (
+	struct acpi_device *device)
+{
+	int result;
+	struct acpi_bus_ops ops;
+
+	ACPI_FUNCTION_TRACE("acpi_bus_start");
+
+	if (!device)
+		return_VALUE(-EINVAL);
+
+	result = acpi_start_single_object(device);
+	if (!result) {
+		memset(&ops, 0, sizeof(ops));
+		ops.acpi_op_start = 1;
+		result = acpi_bus_scan(device, &ops);
+	}
+	return_VALUE(result);
+}
+EXPORT_SYMBOL(acpi_bus_start);
 
 static int
 acpi_bus_trim(struct acpi_device	*start,
@@ -1331,13 +1396,19 @@ acpi_bus_scan_fixed (
 	/*
 	 * Enumerate all fixed-feature devices.
 	 */
-	if (acpi_fadt.pwr_button == 0)
-		result = acpi_bus_add(&device, acpi_root, 
+	if (acpi_fadt.pwr_button == 0) {
+		result = acpi_add_single_object(&device, acpi_root,
 			NULL, ACPI_BUS_TYPE_POWER_BUTTON);
+		if (!result)
+			result = acpi_start_single_object(device);
+	}
 
-	if (acpi_fadt.sleep_button == 0)
-		result = acpi_bus_add(&device, acpi_root, 
+	if (acpi_fadt.sleep_button == 0) {
+		result = acpi_add_single_object(&device, acpi_root,
 			NULL, ACPI_BUS_TYPE_SLEEP_BUTTON);
+		if (!result)
+			result = acpi_start_single_object(device);
+	}
 
 	return_VALUE(result);
 }
@@ -1346,6 +1417,7 @@ acpi_bus_scan_fixed (
 static int __init acpi_scan_init(void)
 {
 	int result;
+	struct acpi_bus_ops ops;
 
 	ACPI_FUNCTION_TRACE("acpi_scan_init");
 
@@ -1357,17 +1429,23 @@ static int __init acpi_scan_init(void)
 	/*
 	 * Create the root device in the bus's device tree
 	 */
-	result = acpi_bus_add(&acpi_root, NULL, ACPI_ROOT_OBJECT, 
+	result = acpi_add_single_object(&acpi_root, NULL, ACPI_ROOT_OBJECT,
 		ACPI_BUS_TYPE_SYSTEM);
 	if (result)
 		goto Done;
 
+	result = acpi_start_single_object(acpi_root);
+
 	/*
 	 * Enumerate devices in the ACPI namespace.
 	 */
 	result = acpi_bus_scan_fixed(acpi_root);
-	if (!result) 
-		result = acpi_bus_scan(acpi_root);
+	if (!result) {
+		memset(&ops, 0, sizeof(ops));
+		ops.acpi_op_add = 1;
+		ops.acpi_op_start = 1;
+		result = acpi_bus_scan(acpi_root, &ops);
+	}
 
 	if (result)
 		acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL);
diff --git a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c
--- a/drivers/acpi/sleep/main.c
+++ b/drivers/acpi/sleep/main.c
@@ -1,6 +1,7 @@
 /*
  * sleep.c - ACPI sleep support.
  *
+ * Copyright (c) 2005 Alexey Starikovskiy <alexey.y.starikovskiy@intel.com>
  * Copyright (c) 2004 David Shaohua Li <shaohua.li@intel.com>
  * Copyright (c) 2000-2003 Patrick Mochel
  * Copyright (c) 2003 Open Source Development Lab
@@ -14,7 +15,6 @@
 #include <linux/dmi.h>
 #include <linux/device.h>
 #include <linux/suspend.h>
-#include <asm/io.h>
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>
 #include "sleep.h"
@@ -27,10 +27,11 @@ extern void do_suspend_lowlevel_s4bios(v
 extern void do_suspend_lowlevel(void);
 
 static u32 acpi_suspend_states[] = {
-	[PM_SUSPEND_ON]		= ACPI_STATE_S0,
-	[PM_SUSPEND_STANDBY]	= ACPI_STATE_S1,
-	[PM_SUSPEND_MEM]	= ACPI_STATE_S3,
-	[PM_SUSPEND_DISK]	= ACPI_STATE_S4,
+	[PM_SUSPEND_ON] = ACPI_STATE_S0,
+	[PM_SUSPEND_STANDBY] = ACPI_STATE_S1,
+	[PM_SUSPEND_MEM] = ACPI_STATE_S3,
+	[PM_SUSPEND_DISK] = ACPI_STATE_S4,
+	[PM_SUSPEND_MAX] = ACPI_STATE_S5
 };
 
 static int init_8259A_after_S1;
@@ -44,30 +45,20 @@ static int init_8259A_after_S1;
  *	wakeup code to the waking vector. 
  */
 
+extern int acpi_sleep_prepare(u32 acpi_state);
+extern void acpi_power_off(void);
+
 static int acpi_pm_prepare(suspend_state_t pm_state)
 {
 	u32 acpi_state = acpi_suspend_states[pm_state];
 
-	if (!sleep_states[acpi_state])
+	if (!sleep_states[acpi_state]) {
+		printk("acpi_pm_prepare does not support %d \n", pm_state);
 		return -EPERM;
-
-	/* do we have a wakeup address for S2 and S3? */
-	/* Here, we support only S4BIOS, those we set the wakeup address */
-	/* S4OS is only supported for now via swsusp.. */
-	if (pm_state == PM_SUSPEND_MEM || pm_state == PM_SUSPEND_DISK) {
-		if (!acpi_wakeup_address)
-			return -EFAULT;
-		acpi_set_firmware_waking_vector(
-			(acpi_physical_address) virt_to_phys(
-				(void *)acpi_wakeup_address));
 	}
-	ACPI_FLUSH_CPU_CACHE();
-	acpi_enable_wakeup_device_prep(acpi_state);
-	acpi_enter_sleep_state_prep(acpi_state);
-	return 0;
+	return acpi_sleep_prepare(acpi_state);
 }
 
-
 /**
  *	acpi_pm_enter - Actually enter a sleep state.
  *	@pm_state:		State we're entering.
@@ -92,11 +83,9 @@ static int acpi_pm_enter(suspend_state_t
 			return error;
 	}
 
-
 	local_irq_save(flags);
 	acpi_enable_wakeup_device(acpi_state);
-	switch (pm_state)
-	{
+	switch (pm_state) {
 	case PM_SUSPEND_STANDBY:
 		barrier();
 		status = acpi_enter_sleep_state(acpi_state);
@@ -112,6 +101,10 @@ static int acpi_pm_enter(suspend_state_t
 		else
 			do_suspend_lowlevel_s4bios();
 		break;
+	case PM_SUSPEND_MAX:
+		acpi_power_off();
+		break;
+
 	default:
 		return -EINVAL;
 	}
@@ -126,11 +119,9 @@ static int acpi_pm_enter(suspend_state_t
 	if (pm_state > PM_SUSPEND_STANDBY)
 		acpi_restore_state_mem();
 
-
 	return ACPI_SUCCESS(status) ? 0 : -EFAULT;
 }
 
-
 /**
  *	acpi_pm_finish - Finish up suspend sequence.
  *	@pm_state:		State we're coming out of.
@@ -156,27 +147,26 @@ static int acpi_pm_finish(suspend_state_
 	return 0;
 }
 
-
 int acpi_suspend(u32 acpi_state)
 {
 	suspend_state_t states[] = {
-		[1]	= PM_SUSPEND_STANDBY,
-		[3]	= PM_SUSPEND_MEM,
-		[4]	= PM_SUSPEND_DISK,
+		[1] = PM_SUSPEND_STANDBY,
+		[3] = PM_SUSPEND_MEM,
+		[4] = PM_SUSPEND_DISK,
+		[5] = PM_SUSPEND_MAX
 	};
 
-	if (acpi_state <= 4 && states[acpi_state])
+	if (acpi_state < 6 && states[acpi_state])
 		return pm_suspend(states[acpi_state]);
 	return -EINVAL;
 }
 
 static struct pm_ops acpi_pm_ops = {
-	.prepare	= acpi_pm_prepare,
-	.enter		= acpi_pm_enter,
-	.finish		= acpi_pm_finish,
+	.prepare = acpi_pm_prepare,
+	.enter = acpi_pm_enter,
+	.finish = acpi_pm_finish,
 };
 
-
 /*
  * Toshiba fails to preserve interrupts over S1, reinitialization
  * of 8259 is needed after S1 resume.
@@ -190,16 +180,16 @@ static int __init init_ints_after_s1(str
 
 static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
 	{
-		.callback = init_ints_after_s1,
-		.ident = "Toshiba Satellite 4030cdt",
-		.matches = { DMI_MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"), },
-	},
-	{ },
+	 .callback = init_ints_after_s1,
+	 .ident = "Toshiba Satellite 4030cdt",
+	 .matches = {DMI_MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"),},
+	 },
+	{},
 };
 
 static int __init acpi_sleep_init(void)
 {
-	int			i = 0;
+	int i = 0;
 
 	dmi_check_system(acpisleep_dmi_table);
 
@@ -207,7 +197,7 @@ static int __init acpi_sleep_init(void)
 		return 0;
 
 	printk(KERN_INFO PREFIX "(supports");
-	for (i=0; i < ACPI_S_STATE_COUNT; i++) {
+	for (i = 0; i < ACPI_S_STATE_COUNT; i++) {
 		acpi_status status;
 		u8 type_a, type_b;
 		status = acpi_get_sleep_type_data(i, &type_a, &type_b);
diff --git a/drivers/acpi/sleep/poweroff.c b/drivers/acpi/sleep/poweroff.c
--- a/drivers/acpi/sleep/poweroff.c
+++ b/drivers/acpi/sleep/poweroff.c
@@ -3,37 +3,96 @@
  *
  * AKA S5, but it is independent of whether or not the kernel supports
  * any other sleep support in the system.
+ *
+ * Copyright (c) 2005 Alexey Starikovskiy <alexey.y.starikovskiy@intel.com>
+ *
+ * This file is released under the GPLv2.
  */
 
 #include <linux/pm.h>
 #include <linux/init.h>
 #include <acpi/acpi_bus.h>
 #include <linux/sched.h>
+#include <linux/sysdev.h>
+#include <asm/io.h>
 #include "sleep.h"
 
-static void
-acpi_power_off (void)
+int acpi_sleep_prepare(u32 acpi_state)
+{
+#ifdef CONFIG_ACPI_SLEEP
+	/* do we have a wakeup address for S2 and S3? */
+	/* Here, we support only S4BIOS, those we set the wakeup address */
+	/* S4OS is only supported for now via swsusp.. */
+	if (acpi_state == ACPI_STATE_S3 || acpi_state == ACPI_STATE_S4) {
+		if (!acpi_wakeup_address) {
+			return -EFAULT;
+		}
+		acpi_set_firmware_waking_vector((acpi_physical_address)
+						virt_to_phys((void *)
+							     acpi_wakeup_address));
+
+	}
+	ACPI_FLUSH_CPU_CACHE();
+	acpi_enable_wakeup_device_prep(acpi_state);
+#endif
+	if (acpi_state == ACPI_STATE_S5) {
+		acpi_wakeup_gpe_poweroff_prepare();
+	}
+	acpi_enter_sleep_state_prep(acpi_state);
+	return 0;
+}
+
+#ifdef CONFIG_PM
+
+void acpi_power_off(void)
 {
-	printk("%s called\n",__FUNCTION__);
+	/* acpi_sleep_prepare(ACPI_STATE_S5) should have already been called */
+	printk("%s called\n", __FUNCTION__);
+	local_irq_disable();
 	/* Some SMP machines only can poweroff in boot CPU */
-	set_cpus_allowed(current, cpumask_of_cpu(0));
-	acpi_wakeup_gpe_poweroff_prepare();
-	acpi_enter_sleep_state_prep(ACPI_STATE_S5);
-	ACPI_DISABLE_IRQS();
 	acpi_enter_sleep_state(ACPI_STATE_S5);
 }
 
+static int acpi_shutdown(struct sys_device *x)
+{
+	if (system_state == SYSTEM_POWER_OFF) {
+		/* Prepare if we are going to power off the system */
+		return acpi_sleep_prepare(ACPI_STATE_S5);
+	}
+	return 0;
+}
+
+static struct sysdev_class acpi_sysclass = {
+	set_kset_name("acpi"),
+	.shutdown = acpi_shutdown
+};
+
+static struct sys_device device_acpi = {
+	.id = 0,
+	.cls = &acpi_sysclass,
+};
+
 static int acpi_poweroff_init(void)
 {
 	if (!acpi_disabled) {
 		u8 type_a, type_b;
 		acpi_status status;
 
-		status = acpi_get_sleep_type_data(ACPI_STATE_S5, &type_a, &type_b);
-		if (ACPI_SUCCESS(status))
-			pm_power_off = acpi_power_off;
+		status =
+		    acpi_get_sleep_type_data(ACPI_STATE_S5, &type_a, &type_b);
+		if (ACPI_SUCCESS(status)) {
+			int error;
+			error = sysdev_class_register(&acpi_sysclass);
+			if (!error)
+				error = sysdev_register(&device_acpi);
+			if (!error)
+				pm_power_off = acpi_power_off;
+			return error;
+		}
 	}
 	return 0;
 }
 
 late_initcall(acpi_poweroff_init);
+
+#endif /* CONFIG_PM */
diff --git a/drivers/acpi/sleep/proc.c b/drivers/acpi/sleep/proc.c
--- a/drivers/acpi/sleep/proc.c
+++ b/drivers/acpi/sleep/proc.c
@@ -13,13 +13,17 @@
 
 #include "sleep.h"
 
+#ifdef	CONFIG_ACPI_SLEEP_PROC_SLEEP
 #define ACPI_SYSTEM_FILE_SLEEP		"sleep"
+#endif
+
 #define ACPI_SYSTEM_FILE_ALARM		"alarm"
 #define ACPI_SYSTEM_FILE_WAKEUP_DEVICE   "wakeup"
 
 #define _COMPONENT		ACPI_SYSTEM_COMPONENT
 ACPI_MODULE_NAME		("sleep")
 
+#ifdef	CONFIG_ACPI_SLEEP_PROC_SLEEP
 
 static int acpi_system_sleep_seq_show(struct seq_file *seq, void *offset)
 {
@@ -78,6 +82,7 @@ acpi_system_write_sleep (
  Done:
 	return error ? error : count;
 }
+#endif	/* CONFIG_ACPI_SLEEP_PROC_SLEEP */
 
 static int acpi_system_alarm_seq_show(struct seq_file *seq, void *offset)
 {
@@ -452,6 +457,7 @@ static struct file_operations acpi_syste
 	.release	= single_release,
 };
 
+#ifdef	CONFIG_ACPI_SLEEP_PROC_SLEEP
 static struct file_operations acpi_system_sleep_fops = {
 	.open		= acpi_system_sleep_open_fs,
 	.read		= seq_read,
@@ -459,6 +465,7 @@ static struct file_operations acpi_syste
 	.llseek		= seq_lseek,
 	.release	= single_release,
 };
+#endif	/* CONFIG_ACPI_SLEEP_PROC_SLEEP */
 
 static struct file_operations acpi_system_alarm_fops = {
 	.open		= acpi_system_alarm_open_fs,
@@ -484,11 +491,13 @@ static int acpi_sleep_proc_init(void)
 	if (acpi_disabled)
 		return 0;
  
+#ifdef	CONFIG_ACPI_SLEEP_PROC_SLEEP
 	/* 'sleep' [R/W]*/
 	entry = create_proc_entry(ACPI_SYSTEM_FILE_SLEEP,
 				  S_IFREG|S_IRUGO|S_IWUSR, acpi_root_dir);
 	if (entry)
 		entry->proc_fops = &acpi_system_sleep_fops;
+#endif
 
 	/* 'alarm' [R/W] */
 	entry = create_proc_entry(ACPI_SYSTEM_FILE_ALARM,
diff --git a/drivers/acpi/tables/tbconvrt.c b/drivers/acpi/tables/tbconvrt.c
--- a/drivers/acpi/tables/tbconvrt.c
+++ b/drivers/acpi/tables/tbconvrt.c
@@ -50,6 +50,24 @@
 #define _COMPONENT          ACPI_TABLES
 	 ACPI_MODULE_NAME    ("tbconvrt")
 
+/* Local prototypes */
+
+static void
+acpi_tb_init_generic_address (
+	struct acpi_generic_address     *new_gas_struct,
+	u8                              register_bit_width,
+	acpi_physical_address           address);
+
+static void
+acpi_tb_convert_fadt1 (
+	struct fadt_descriptor_rev2    *local_fadt,
+	struct fadt_descriptor_rev1    *original_fadt);
+
+static void
+acpi_tb_convert_fadt2 (
+	struct fadt_descriptor_rev2    *local_fadt,
+	struct fadt_descriptor_rev2    *original_fadt);
+
 
 u8 acpi_fadt_is_v1;
 EXPORT_SYMBOL(acpi_fadt_is_v1);
@@ -142,11 +160,13 @@ acpi_tb_convert_to_xsdt (
 	for (i = 0; i < acpi_gbl_rsdt_table_count; i++) {
 		if (acpi_gbl_RSDP->revision < 2) {
 			ACPI_STORE_ADDRESS (new_table->table_offset_entry[i],
-				(ACPI_CAST_PTR (struct rsdt_descriptor_rev1, table_info->pointer))->table_offset_entry[i]);
+				(ACPI_CAST_PTR (struct rsdt_descriptor_rev1,
+					table_info->pointer))->table_offset_entry[i]);
 		}
 		else {
 			new_table->table_offset_entry[i] =
-				(ACPI_CAST_PTR (XSDT_DESCRIPTOR, table_info->pointer))->table_offset_entry[i];
+				(ACPI_CAST_PTR (XSDT_DESCRIPTOR,
+					table_info->pointer))->table_offset_entry[i];
 		}
 	}
 
@@ -164,7 +184,7 @@ acpi_tb_convert_to_xsdt (
 }
 
 
-/******************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    acpi_tb_init_generic_address
  *
@@ -201,7 +221,7 @@ acpi_tb_init_generic_address (
  * PARAMETERS:  local_fadt      - Pointer to new FADT
  *              original_fadt   - Pointer to old FADT
  *
- * RETURN:      Populates local_fadt
+ * RETURN:      None, populates local_fadt
  *
  * DESCRIPTION: Convert an ACPI 1.0 FADT to common internal format
  *
@@ -213,7 +233,6 @@ acpi_tb_convert_fadt1 (
 	struct fadt_descriptor_rev1    *original_fadt)
 {
 
-
 	/* ACPI 1.0 FACS */
 	/* The BIOS stored FADT should agree with Revision 1.0 */
 	acpi_fadt_is_v1 = 1;
@@ -232,7 +251,8 @@ acpi_tb_convert_fadt1 (
 	ACPI_STORE_ADDRESS (local_fadt->Xdsdt, local_fadt->V1_dsdt);
 
 	/*
-	 * System Interrupt Model isn't used in ACPI 2.0 (local_fadt->Reserved1 = 0;)
+	 * System Interrupt Model isn't used in ACPI 2.0
+	 * (local_fadt->Reserved1 = 0;)
 	 */
 
 	/*
@@ -269,7 +289,8 @@ acpi_tb_convert_fadt1 (
 		 * that immediately follows.
 		 */
 		ACPI_MEMCPY (&local_fadt->reset_register,
-			&(ACPI_CAST_PTR (struct fadt_descriptor_rev2_minus, original_fadt))->reset_register,
+			&(ACPI_CAST_PTR (struct fadt_descriptor_rev2_minus,
+				original_fadt))->reset_register,
   			sizeof (struct acpi_generic_address) + 1);
 	}
 	else {
@@ -304,7 +325,8 @@ acpi_tb_convert_fadt1 (
 
 	acpi_tb_init_generic_address (&acpi_gbl_xpm1a_enable,
 		 (u8) ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len),
-		 (acpi_physical_address) (local_fadt->xpm1a_evt_blk.address +
+		 (acpi_physical_address)
+			(local_fadt->xpm1a_evt_blk.address +
 			ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len)));
 
 	/* PM1B is optional; leave null if not present */
@@ -312,7 +334,8 @@ acpi_tb_convert_fadt1 (
 	if (local_fadt->xpm1b_evt_blk.address) {
 		acpi_tb_init_generic_address (&acpi_gbl_xpm1b_enable,
 			 (u8) ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len),
-			 (acpi_physical_address) (local_fadt->xpm1b_evt_blk.address +
+			 (acpi_physical_address)
+				(local_fadt->xpm1b_evt_blk.address +
 				ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len)));
 	}
 }
@@ -325,7 +348,7 @@ acpi_tb_convert_fadt1 (
  * PARAMETERS:  local_fadt      - Pointer to new FADT
  *              original_fadt   - Pointer to old FADT
  *
- * RETURN:      Populates local_fadt
+ * RETURN:      None, populates local_fadt
  *
  * DESCRIPTION: Convert an ACPI 2.0 FADT to common internal format.
  *              Handles optional "X" fields.
@@ -348,7 +371,8 @@ acpi_tb_convert_fadt2 (
 	 * is zero.
 	 */
 	if (!(local_fadt->xfirmware_ctrl)) {
-		ACPI_STORE_ADDRESS (local_fadt->xfirmware_ctrl, local_fadt->V1_firmware_ctrl);
+		ACPI_STORE_ADDRESS (local_fadt->xfirmware_ctrl,
+			local_fadt->V1_firmware_ctrl);
 	}
 
 	if (!(local_fadt->Xdsdt)) {
@@ -357,32 +381,38 @@ acpi_tb_convert_fadt2 (
 
 	if (!(local_fadt->xpm1a_evt_blk.address)) {
 		acpi_tb_init_generic_address (&local_fadt->xpm1a_evt_blk,
-			local_fadt->pm1_evt_len, (acpi_physical_address) local_fadt->V1_pm1a_evt_blk);
+			local_fadt->pm1_evt_len,
+			(acpi_physical_address) local_fadt->V1_pm1a_evt_blk);
 	}
 
 	if (!(local_fadt->xpm1b_evt_blk.address)) {
 		acpi_tb_init_generic_address (&local_fadt->xpm1b_evt_blk,
-			local_fadt->pm1_evt_len, (acpi_physical_address) local_fadt->V1_pm1b_evt_blk);
+			local_fadt->pm1_evt_len,
+			(acpi_physical_address) local_fadt->V1_pm1b_evt_blk);
 	}
 
 	if (!(local_fadt->xpm1a_cnt_blk.address)) {
 		acpi_tb_init_generic_address (&local_fadt->xpm1a_cnt_blk,
-			local_fadt->pm1_cnt_len, (acpi_physical_address) local_fadt->V1_pm1a_cnt_blk);
+			local_fadt->pm1_cnt_len,
+			(acpi_physical_address) local_fadt->V1_pm1a_cnt_blk);
 	}
 
 	if (!(local_fadt->xpm1b_cnt_blk.address)) {
 		acpi_tb_init_generic_address (&local_fadt->xpm1b_cnt_blk,
-			local_fadt->pm1_cnt_len, (acpi_physical_address) local_fadt->V1_pm1b_cnt_blk);
+			local_fadt->pm1_cnt_len,
+			(acpi_physical_address) local_fadt->V1_pm1b_cnt_blk);
 	}
 
 	if (!(local_fadt->xpm2_cnt_blk.address)) {
 		acpi_tb_init_generic_address (&local_fadt->xpm2_cnt_blk,
-			local_fadt->pm2_cnt_len, (acpi_physical_address) local_fadt->V1_pm2_cnt_blk);
+			local_fadt->pm2_cnt_len,
+			(acpi_physical_address) local_fadt->V1_pm2_cnt_blk);
 	}
 
 	if (!(local_fadt->xpm_tmr_blk.address)) {
 		acpi_tb_init_generic_address (&local_fadt->xpm_tmr_blk,
-			local_fadt->pm_tm_len, (acpi_physical_address) local_fadt->V1_pm_tmr_blk);
+			local_fadt->pm_tm_len,
+			(acpi_physical_address) local_fadt->V1_pm_tmr_blk);
 	}
 
 	if (!(local_fadt->xgpe0_blk.address)) {
@@ -399,18 +429,24 @@ acpi_tb_convert_fadt2 (
 
 	acpi_tb_init_generic_address (&acpi_gbl_xpm1a_enable,
 		(u8) ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len),
-		(acpi_physical_address) (local_fadt->xpm1a_evt_blk.address +
+		(acpi_physical_address)
+			(local_fadt->xpm1a_evt_blk.address +
 			ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len)));
-	acpi_gbl_xpm1a_enable.address_space_id = local_fadt->xpm1a_evt_blk.address_space_id;
+
+	acpi_gbl_xpm1a_enable.address_space_id =
+		local_fadt->xpm1a_evt_blk.address_space_id;
 
 	/* PM1B is optional; leave null if not present */
 
 	if (local_fadt->xpm1b_evt_blk.address) {
 		acpi_tb_init_generic_address (&acpi_gbl_xpm1b_enable,
 			(u8) ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len),
-			(acpi_physical_address) (local_fadt->xpm1b_evt_blk.address +
+			(acpi_physical_address)
+				(local_fadt->xpm1b_evt_blk.address +
 				ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len)));
-		acpi_gbl_xpm1b_enable.address_space_id = local_fadt->xpm1b_evt_blk.address_space_id;
+
+		acpi_gbl_xpm1b_enable.address_space_id =
+			local_fadt->xpm1b_evt_blk.address_space_id;
 	}
 }
 
@@ -432,7 +468,8 @@ acpi_tb_convert_fadt2 (
  ******************************************************************************/
 
 acpi_status
-acpi_tb_convert_table_fadt (void)
+acpi_tb_convert_table_fadt (
+	void)
 {
 	struct fadt_descriptor_rev2    *local_fadt;
 	struct acpi_table_desc         *table_desc;
@@ -446,7 +483,8 @@ acpi_tb_convert_table_fadt (void)
 	 * at least as long as the version 1.0 FADT
 	 */
 	if (acpi_gbl_FADT->length < sizeof (struct fadt_descriptor_rev1)) {
-		ACPI_REPORT_ERROR (("FADT is invalid, too short: 0x%X\n", acpi_gbl_FADT->length));
+		ACPI_REPORT_ERROR (("FADT is invalid, too short: 0x%X\n",
+			acpi_gbl_FADT->length));
 		return_ACPI_STATUS (AE_INVALID_TABLE_LENGTH);
 	}
 
@@ -461,8 +499,9 @@ acpi_tb_convert_table_fadt (void)
 		if (acpi_gbl_FADT->length < sizeof (struct fadt_descriptor_rev2)) {
 			/* Length is too short to be a V2.0 table */
 
-			ACPI_REPORT_WARNING (("Inconsistent FADT length (0x%X) and revision (0x%X), using FADT V1.0 portion of table\n",
-					 acpi_gbl_FADT->length, acpi_gbl_FADT->revision));
+			ACPI_REPORT_WARNING ((
+				"Inconsistent FADT length (0x%X) and revision (0x%X), using FADT V1.0 portion of table\n",
+				acpi_gbl_FADT->length, acpi_gbl_FADT->revision));
 
 			acpi_tb_convert_fadt1 (local_fadt, (void *) acpi_gbl_FADT);
 		}
@@ -478,9 +517,8 @@ acpi_tb_convert_table_fadt (void)
 		acpi_tb_convert_fadt1 (local_fadt, (void *) acpi_gbl_FADT);
 	}
 
-	/*
-	 * Global FADT pointer will point to the new common V2.0 FADT
-	 */
+	/* Global FADT pointer will point to the new common V2.0 FADT */
+
 	acpi_gbl_FADT = local_fadt;
 	acpi_gbl_FADT->length = sizeof (FADT_DESCRIPTOR);
 
@@ -508,7 +546,7 @@ acpi_tb_convert_table_fadt (void)
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_tb_convert_table_facs
+ * FUNCTION:    acpi_tb_build_common_facs
  *
  * PARAMETERS:  table_info      - Info for currently installed FACS
  *
@@ -530,12 +568,14 @@ acpi_tb_build_common_facs (
 	/* Absolute minimum length is 24, but the ACPI spec says 64 */
 
 	if (acpi_gbl_FACS->length < 24) {
-		ACPI_REPORT_ERROR (("Invalid FACS table length: 0x%X\n", acpi_gbl_FACS->length));
+		ACPI_REPORT_ERROR (("Invalid FACS table length: 0x%X\n",
+			acpi_gbl_FACS->length));
 		return_ACPI_STATUS (AE_INVALID_TABLE_LENGTH);
 	}
 
 	if (acpi_gbl_FACS->length < 64) {
-		ACPI_REPORT_WARNING (("FACS is shorter than the ACPI specification allows: 0x%X, using anyway\n",
+		ACPI_REPORT_WARNING ((
+			"FACS is shorter than the ACPI specification allows: 0x%X, using anyway\n",
 			acpi_gbl_FACS->length));
 	}
 
@@ -548,7 +588,8 @@ acpi_tb_build_common_facs (
 		(!(acpi_gbl_FACS->xfirmware_waking_vector))) {
 		/* ACPI 1.0 FACS or short table or optional X_ field is zero */
 
-		acpi_gbl_common_fACS.firmware_waking_vector = ACPI_CAST_PTR (u64, &(acpi_gbl_FACS->firmware_waking_vector));
+		acpi_gbl_common_fACS.firmware_waking_vector = ACPI_CAST_PTR (u64,
+				&(acpi_gbl_FACS->firmware_waking_vector));
 		acpi_gbl_common_fACS.vector_width = 32;
 	}
 	else {
diff --git a/drivers/acpi/tables/tbget.c b/drivers/acpi/tables/tbget.c
--- a/drivers/acpi/tables/tbget.c
+++ b/drivers/acpi/tables/tbget.c
@@ -49,6 +49,19 @@
 #define _COMPONENT          ACPI_TABLES
 	 ACPI_MODULE_NAME    ("tbget")
 
+/* Local prototypes */
+
+static acpi_status
+acpi_tb_get_this_table (
+	struct acpi_pointer             *address,
+	struct acpi_table_header        *header,
+	struct acpi_table_desc          *table_info);
+
+static acpi_status
+acpi_tb_table_override (
+	struct acpi_table_header        *header,
+	struct acpi_table_desc          *table_info);
+
 
 /*******************************************************************************
  *
@@ -76,9 +89,8 @@ acpi_tb_get_table (
 	ACPI_FUNCTION_TRACE ("tb_get_table");
 
 
-	/*
-	 * Get the header in order to get signature and table size
-	 */
+	/* Get the header in order to get signature and table size */
+
 	status = acpi_tb_get_table_header (address, &header);
 	if (ACPI_FAILURE (status)) {
 		return_ACPI_STATUS (status);
@@ -127,8 +139,8 @@ acpi_tb_get_table_header (
 
 
 	/*
-	 * Flags contains the current processor mode (Virtual or Physical addressing)
-	 * The pointer_type is either Logical or Physical
+	 * Flags contains the current processor mode (Virtual or Physical
+	 * addressing) The pointer_type is either Logical or Physical
 	 */
 	switch (address->pointer_type) {
 	case ACPI_PHYSMODE_PHYSPTR:
@@ -136,7 +148,8 @@ acpi_tb_get_table_header (
 
 		/* Pointer matches processor mode, copy the header */
 
-		ACPI_MEMCPY (return_header, address->pointer.logical, sizeof (struct acpi_table_header));
+		ACPI_MEMCPY (return_header, address->pointer.logical,
+			sizeof (struct acpi_table_header));
 		break;
 
 
@@ -144,10 +157,11 @@ acpi_tb_get_table_header (
 
 		/* Create a logical address for the physical pointer*/
 
-		status = acpi_os_map_memory (address->pointer.physical, sizeof (struct acpi_table_header),
-				  (void *) &header);
+		status = acpi_os_map_memory (address->pointer.physical,
+				 sizeof (struct acpi_table_header), (void *) &header);
 		if (ACPI_FAILURE (status)) {
-			ACPI_REPORT_ERROR (("Could not map memory at %8.8X%8.8X for length %X\n",
+			ACPI_REPORT_ERROR ((
+				"Could not map memory at %8.8X%8.8X for length %X\n",
 				ACPI_FORMAT_UINT64 (address->pointer.physical),
 				sizeof (struct acpi_table_header)));
 			return_ACPI_STATUS (status);
@@ -210,9 +224,8 @@ acpi_tb_get_table_body (
 		return_ACPI_STATUS (AE_BAD_PARAMETER);
 	}
 
-	/*
-	 * Attempt table override.
-	 */
+	/* Attempt table override. */
+
 	status = acpi_tb_table_override (header, table_info);
 	if (ACPI_SUCCESS (status)) {
 		/* Table was overridden by the host OS */
@@ -241,7 +254,7 @@ acpi_tb_get_table_body (
  *
  ******************************************************************************/
 
-acpi_status
+static acpi_status
 acpi_tb_table_override (
 	struct acpi_table_header        *header,
 	struct acpi_table_desc          *table_info)
@@ -315,7 +328,7 @@ acpi_tb_table_override (
  *
  ******************************************************************************/
 
-acpi_status
+static acpi_status
 acpi_tb_get_this_table (
 	struct acpi_pointer             *address,
 	struct acpi_table_header        *header,
@@ -330,8 +343,8 @@ acpi_tb_get_this_table (
 
 
 	/*
-	 * Flags contains the current processor mode (Virtual or Physical addressing)
-	 * The pointer_type is either Logical or Physical
+	 * Flags contains the current processor mode (Virtual or Physical
+	 * addressing) The pointer_type is either Logical or Physical
 	 */
 	switch (address->pointer_type) {
 	case ACPI_PHYSMODE_PHYSPTR:
@@ -341,7 +354,8 @@ acpi_tb_get_this_table (
 
 		full_table = ACPI_MEM_ALLOCATE (header->length);
 		if (!full_table) {
-			ACPI_REPORT_ERROR (("Could not allocate table memory for [%4.4s] length %X\n",
+			ACPI_REPORT_ERROR ((
+				"Could not allocate table memory for [%4.4s] length %X\n",
 				header->signature, header->length));
 			return_ACPI_STATUS (AE_NO_MEMORY);
 		}
@@ -362,12 +376,14 @@ acpi_tb_get_this_table (
 		 * Just map the table's physical memory
 		 * into our address space.
 		 */
-		status = acpi_os_map_memory (address->pointer.physical, (acpi_size) header->length,
-				  (void *) &full_table);
+		status = acpi_os_map_memory (address->pointer.physical,
+				 (acpi_size) header->length, (void *) &full_table);
 		if (ACPI_FAILURE (status)) {
-			ACPI_REPORT_ERROR (("Could not map memory for table [%4.4s] at %8.8X%8.8X for length %X\n",
+			ACPI_REPORT_ERROR ((
+				"Could not map memory for table [%4.4s] at %8.8X%8.8X for length %X\n",
 				header->signature,
-				ACPI_FORMAT_UINT64 (address->pointer.physical), header->length));
+				ACPI_FORMAT_UINT64 (address->pointer.physical),
+				header->length));
 			return (status);
 		}
 
@@ -465,9 +481,8 @@ acpi_tb_get_table_ptr (
 		return_ACPI_STATUS (AE_OK);
 	}
 
-	/*
-	 * Check for instance out of range
-	 */
+	/* Check for instance out of range */
+
 	if (instance > acpi_gbl_table_lists[table_type].count) {
 		return_ACPI_STATUS (AE_NOT_EXIST);
 	}
diff --git a/drivers/acpi/tables/tbgetall.c b/drivers/acpi/tables/tbgetall.c
--- a/drivers/acpi/tables/tbgetall.c
+++ b/drivers/acpi/tables/tbgetall.c
@@ -49,6 +49,19 @@
 #define _COMPONENT          ACPI_TABLES
 	 ACPI_MODULE_NAME    ("tbgetall")
 
+/* Local prototypes */
+
+static acpi_status
+acpi_tb_get_primary_table (
+	struct acpi_pointer             *address,
+	struct acpi_table_desc          *table_info);
+
+static acpi_status
+acpi_tb_get_secondary_table (
+	struct acpi_pointer             *address,
+	acpi_string                     signature,
+	struct acpi_table_desc          *table_info);
+
 
 /*******************************************************************************
  *
@@ -63,7 +76,7 @@
  *
  ******************************************************************************/
 
-acpi_status
+static acpi_status
 acpi_tb_get_primary_table (
 	struct acpi_pointer             *address,
 	struct acpi_table_desc          *table_info)
@@ -81,9 +94,8 @@ acpi_tb_get_primary_table (
 		return_ACPI_STATUS (AE_OK);
 	}
 
-	/*
-	 * Get the header in order to get signature and table size
-	 */
+	/* Get the header in order to get signature and table size */
+
 	status = acpi_tb_get_table_header (address, &header);
 	if (ACPI_FAILURE (status)) {
 		return_ACPI_STATUS (status);
@@ -130,7 +142,7 @@ acpi_tb_get_primary_table (
  *
  ******************************************************************************/
 
-acpi_status
+static acpi_status
 acpi_tb_get_secondary_table (
 	struct acpi_pointer             *address,
 	acpi_string                     signature,
@@ -153,7 +165,8 @@ acpi_tb_get_secondary_table (
 	/* Signature must match request */
 
 	if (ACPI_STRNCMP (header.signature, signature, ACPI_NAME_SIZE)) {
-		ACPI_REPORT_ERROR (("Incorrect table signature - wanted [%s] found [%4.4s]\n",
+		ACPI_REPORT_ERROR ((
+			"Incorrect table signature - wanted [%s] found [%4.4s]\n",
 			signature, header.signature));
 		return_ACPI_STATUS (AE_BAD_SIGNATURE);
 	}
@@ -230,7 +243,8 @@ acpi_tb_get_required_tables (
 	for (i = 0; i < acpi_gbl_rsdt_table_count; i++) {
 		/* Get the table address from the common internal XSDT */
 
-		address.pointer.value = acpi_gbl_XSDT->table_offset_entry[i];
+		address.pointer.value =
+				  acpi_gbl_XSDT->table_offset_entry[i];
 
 		/*
 		 * Get the tables needed by this subsystem (FADT and any SSDTs).
@@ -252,18 +266,18 @@ acpi_tb_get_required_tables (
 	}
 
 	/*
-	 * Convert the FADT to a common format.  This allows earlier revisions of the
-	 * table to coexist with newer versions, using common access code.
+	 * Convert the FADT to a common format.  This allows earlier revisions of
+	 * the table to coexist with newer versions, using common access code.
 	 */
 	status = acpi_tb_convert_table_fadt ();
 	if (ACPI_FAILURE (status)) {
-		ACPI_REPORT_ERROR (("Could not convert FADT to internal common format\n"));
+		ACPI_REPORT_ERROR ((
+			"Could not convert FADT to internal common format\n"));
 		return_ACPI_STATUS (status);
 	}
 
-	/*
-	 * Get the FACS (Pointed to by the FADT)
-	 */
+	/* Get the FACS (Pointed to by the FADT) */
+
 	address.pointer.value = acpi_gbl_FADT->xfirmware_ctrl;
 
 	status = acpi_tb_get_secondary_table (&address, FACS_SIG, &table_info);
@@ -282,9 +296,8 @@ acpi_tb_get_required_tables (
 		return_ACPI_STATUS (status);
 	}
 
-	/*
-	 * Get/install the DSDT (Pointed to by the FADT)
-	 */
+	/* Get/install the DSDT (Pointed to by the FADT) */
+
 	address.pointer.value = acpi_gbl_FADT->Xdsdt;
 
 	status = acpi_tb_get_secondary_table (&address, DSDT_SIG, &table_info);
diff --git a/drivers/acpi/tables/tbinstal.c b/drivers/acpi/tables/tbinstal.c
--- a/drivers/acpi/tables/tbinstal.c
+++ b/drivers/acpi/tables/tbinstal.c
@@ -49,6 +49,14 @@
 #define _COMPONENT          ACPI_TABLES
 	 ACPI_MODULE_NAME    ("tbinstal")
 
+/* Local prototypes */
+
+static acpi_status
+acpi_tb_match_signature (
+	char                            *signature,
+	struct acpi_table_desc          *table_info,
+	u8                              search_type);
+
 
 /*******************************************************************************
  *
@@ -56,6 +64,7 @@
  *
  * PARAMETERS:  Signature           - Table signature to match
  *              table_info          - Return data
+ *              search_type         - Table type to match (primary/secondary)
  *
  * RETURN:      Status
  *
@@ -64,7 +73,7 @@
  *
  ******************************************************************************/
 
-acpi_status
+static acpi_status
 acpi_tb_match_signature (
 	char                            *signature,
 	struct acpi_table_desc          *table_info,
@@ -76,9 +85,8 @@ acpi_tb_match_signature (
 	ACPI_FUNCTION_TRACE ("tb_match_signature");
 
 
-	/*
-	 * Search for a signature match among the known table types
-	 */
+	/* Search for a signature match among the known table types */
+
 	for (i = 0; i < NUM_ACPI_TABLE_TYPES; i++) {
 		if (!(acpi_gbl_table_data[i].flags & search_type)) {
 			continue;
@@ -161,6 +169,7 @@ acpi_tb_install_table (
  * FUNCTION:    acpi_tb_recognize_table
  *
  * PARAMETERS:  table_info          - Return value from acpi_tb_get_table_body
+ *              search_type         - Table type to match (primary/secondary)
  *
  * RETURN:      Status
  *
@@ -203,7 +212,8 @@ acpi_tb_recognize_table (
 	 * This can be any one of many valid ACPI tables, it just isn't one of
 	 * the tables that is consumed by the core subsystem
 	 */
-	status = acpi_tb_match_signature (table_header->signature, table_info, search_type);
+	status = acpi_tb_match_signature (table_header->signature,
+			 table_info, search_type);
 	if (ACPI_FAILURE (status)) {
 		return_ACPI_STATUS (status);
 	}
@@ -253,9 +263,8 @@ acpi_tb_init_table_descriptor (
 		return_ACPI_STATUS (AE_NO_MEMORY);
 	}
 
-	/*
-	 * Install the table into the global data structure
-	 */
+	/* Install the table into the global data structure */
+
 	list_head = &acpi_gbl_table_lists[table_type];
 
 	/*
@@ -316,7 +325,8 @@ acpi_tb_init_table_descriptor (
 	table_desc->aml_start           = (u8 *) (table_desc->pointer + 1),
 	table_desc->aml_length          = (u32) (table_desc->length -
 			 (u32) sizeof (struct acpi_table_header));
-	table_desc->table_id            = acpi_ut_allocate_owner_id (ACPI_OWNER_TYPE_TABLE);
+	table_desc->table_id            = acpi_ut_allocate_owner_id (
+			 ACPI_OWNER_TYPE_TABLE);
 	table_desc->loaded_into_namespace = FALSE;
 
 	/*
@@ -349,7 +359,8 @@ acpi_tb_init_table_descriptor (
  ******************************************************************************/
 
 void
-acpi_tb_delete_all_tables (void)
+acpi_tb_delete_all_tables (
+	void)
 {
 	acpi_table_type                 type;
 
diff --git a/drivers/acpi/tables/tbrsdt.c b/drivers/acpi/tables/tbrsdt.c
--- a/drivers/acpi/tables/tbrsdt.c
+++ b/drivers/acpi/tables/tbrsdt.c
@@ -84,8 +84,9 @@ acpi_tb_verify_rsdp (
 		/*
 		 * Obtain access to the RSDP structure
 		 */
-		status = acpi_os_map_memory (address->pointer.physical, sizeof (struct rsdp_descriptor),
-				  (void *) &rsdp);
+		status = acpi_os_map_memory (address->pointer.physical,
+				 sizeof (struct rsdp_descriptor),
+						   (void *) &rsdp);
 		if (ACPI_FAILURE (status)) {
 			return_ACPI_STATUS (status);
 		}
@@ -154,9 +155,9 @@ cleanup:
  *
  * FUNCTION:    acpi_tb_get_rsdt_address
  *
- * PARAMETERS:  None
+ * PARAMETERS:  out_address         - Where the address is returned
  *
- * RETURN:      RSDT physical address
+ * RETURN:      None, Address
  *
  * DESCRIPTION: Extract the address of the RSDT or XSDT, depending on the
  *              version of the RSDP
@@ -181,7 +182,8 @@ acpi_tb_get_rsdt_address (
 		out_address->pointer.value = acpi_gbl_RSDP->rsdt_physical_address;
 	}
 	else {
-		out_address->pointer.value = acpi_gbl_RSDP->xsdt_physical_address;
+		out_address->pointer.value =
+			acpi_gbl_RSDP->xsdt_physical_address;
 	}
 }
 
@@ -224,7 +226,8 @@ acpi_tb_validate_rsdt (
 	if (no_match) {
 		/* Invalid RSDT or XSDT signature */
 
-		ACPI_REPORT_ERROR (("Invalid signature where RSDP indicates RSDT/XSDT should be located\n"));
+		ACPI_REPORT_ERROR ((
+			"Invalid signature where RSDP indicates RSDT/XSDT should be located\n"));
 
 		ACPI_DUMP_BUFFER (acpi_gbl_RSDP, 20);
 
@@ -282,6 +285,7 @@ acpi_tb_get_table_rsdt (
 	if (ACPI_FAILURE (status)) {
 		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not get the RSDT/XSDT, %s\n",
 			acpi_format_exception (status)));
+
 		return_ACPI_STATUS (status);
 	}
 
@@ -299,7 +303,8 @@ acpi_tb_get_table_rsdt (
 
 	/* Get the number of tables defined in the RSDT or XSDT */
 
-	acpi_gbl_rsdt_table_count = acpi_tb_get_table_count (acpi_gbl_RSDP, table_info.pointer);
+	acpi_gbl_rsdt_table_count = acpi_tb_get_table_count (acpi_gbl_RSDP,
+			  table_info.pointer);
 
 	/* Convert and/or copy to an XSDT structure */
 
diff --git a/drivers/acpi/tables/tbutils.c b/drivers/acpi/tables/tbutils.c
--- a/drivers/acpi/tables/tbutils.c
+++ b/drivers/acpi/tables/tbutils.c
@@ -49,48 +49,14 @@
 #define _COMPONENT          ACPI_TABLES
 	 ACPI_MODULE_NAME    ("tbutils")
 
+/* Local prototypes */
 
-/*******************************************************************************
- *
- * FUNCTION:    acpi_tb_handle_to_object
- *
- * PARAMETERS:  table_id            - Id for which the function is searching
- *              table_desc          - Pointer to return the matching table
- *                                      descriptor.
- *
- * RETURN:      Search the tables to find one with a matching table_id and
- *              return a pointer to that table descriptor.
- *
- ******************************************************************************/
-#ifdef ACPI_FUTURE_USAGE
+#ifdef ACPI_OBSOLETE_FUNCTIONS
 acpi_status
 acpi_tb_handle_to_object (
 	u16                             table_id,
-	struct acpi_table_desc          **return_table_desc)
-{
-	u32                             i;
-	struct acpi_table_desc          *table_desc;
-
-
-	ACPI_FUNCTION_NAME ("tb_handle_to_object");
-
-
-	for (i = 0; i < ACPI_TABLE_MAX; i++) {
-		table_desc = acpi_gbl_table_lists[i].next;
-		while (table_desc) {
-			if (table_desc->table_id == table_id) {
-				*return_table_desc = table_desc;
-				return (AE_OK);
-			}
-
-			table_desc = table_desc->next;
-		}
-	}
-
-	ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "table_id=%X does not exist\n", table_id));
-	return (AE_BAD_PARAMETER);
-}
-#endif  /*  ACPI_FUTURE_USAGE  */
+	struct acpi_table_desc          **table_desc);
+#endif
 
 
 /*******************************************************************************
@@ -128,6 +94,7 @@ acpi_tb_validate_table_header (
 	if (!acpi_os_readable (table_header, sizeof (struct acpi_table_header))) {
 		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
 			"Cannot read table header at %p\n", table_header));
+
 		return (AE_BAD_ADDRESS);
 	}
 
@@ -141,6 +108,7 @@ acpi_tb_validate_table_header (
 
 		ACPI_REPORT_WARNING (("Invalid table signature found: [%4.4s]\n",
 			(char *) &signature));
+
 		ACPI_DUMP_BUFFER (table_header, sizeof (struct acpi_table_header));
 		return (AE_BAD_SIGNATURE);
 	}
@@ -154,6 +122,7 @@ acpi_tb_validate_table_header (
 
 		ACPI_REPORT_WARNING (("Invalid table header length (0x%X) found\n",
 			(u32) table_header->length));
+
 		ACPI_DUMP_BUFFER (table_header, sizeof (struct acpi_table_header));
 		return (AE_BAD_HEADER);
 	}
@@ -193,8 +162,10 @@ acpi_tb_verify_table_checksum (
 	/* Return the appropriate exception */
 
 	if (checksum) {
-		ACPI_REPORT_WARNING (("Invalid checksum in table [%4.4s] (%02X, sum %02X is not zero)\n",
-			table_header->signature, (u32) table_header->checksum, (u32) checksum));
+		ACPI_REPORT_WARNING ((
+			"Invalid checksum in table [%4.4s] (%02X, sum %02X is not zero)\n",
+			table_header->signature, (u32) table_header->checksum,
+			(u32) checksum));
 
 		status = AE_BAD_CHECKSUM;
 	}
@@ -209,7 +180,7 @@ acpi_tb_verify_table_checksum (
  * PARAMETERS:  Buffer              - Buffer to checksum
  *              Length              - Size of the buffer
  *
- * RETURNS      8 bit checksum of buffer
+ * RETURN:      8 bit checksum of buffer
  *
  * DESCRIPTION: Computes an 8 bit checksum of the buffer(length) and returns it.
  *
@@ -238,3 +209,47 @@ acpi_tb_checksum (
 }
 
 
+#ifdef ACPI_OBSOLETE_FUNCTIONS
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_handle_to_object
+ *
+ * PARAMETERS:  table_id            - Id for which the function is searching
+ *              table_desc          - Pointer to return the matching table
+ *                                      descriptor.
+ *
+ * RETURN:      Search the tables to find one with a matching table_id and
+ *              return a pointer to that table descriptor.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_tb_handle_to_object (
+	u16                             table_id,
+	struct acpi_table_desc          **return_table_desc)
+{
+	u32                             i;
+	struct acpi_table_desc          *table_desc;
+
+
+	ACPI_FUNCTION_NAME ("tb_handle_to_object");
+
+
+	for (i = 0; i < ACPI_TABLE_MAX; i++) {
+		table_desc = acpi_gbl_table_lists[i].next;
+		while (table_desc) {
+			if (table_desc->table_id == table_id) {
+				*return_table_desc = table_desc;
+				return (AE_OK);
+			}
+
+			table_desc = table_desc->next;
+		}
+	}
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "table_id=%X does not exist\n", table_id));
+	return (AE_BAD_PARAMETER);
+}
+#endif
+
+
diff --git a/drivers/acpi/tables/tbxface.c b/drivers/acpi/tables/tbxface.c
--- a/drivers/acpi/tables/tbxface.c
+++ b/drivers/acpi/tables/tbxface.c
@@ -67,7 +67,8 @@
  ******************************************************************************/
 
 acpi_status
-acpi_load_tables (void)
+acpi_load_tables (
+	void)
 {
 	struct acpi_pointer             rsdp_address;
 	acpi_status                     status;
@@ -82,7 +83,7 @@ acpi_load_tables (void)
 			  &rsdp_address);
 	if (ACPI_FAILURE (status)) {
 		ACPI_REPORT_ERROR (("acpi_load_tables: Could not get RSDP, %s\n",
-				  acpi_format_exception (status)));
+			acpi_format_exception (status)));
 		goto error_exit;
 	}
 
@@ -93,7 +94,7 @@ acpi_load_tables (void)
 	status = acpi_tb_verify_rsdp (&rsdp_address);
 	if (ACPI_FAILURE (status)) {
 		ACPI_REPORT_ERROR (("acpi_load_tables: RSDP Failed validation: %s\n",
-				  acpi_format_exception (status)));
+			acpi_format_exception (status)));
 		goto error_exit;
 	}
 
@@ -102,7 +103,7 @@ acpi_load_tables (void)
 	status = acpi_tb_get_table_rsdt ();
 	if (ACPI_FAILURE (status)) {
 		ACPI_REPORT_ERROR (("acpi_load_tables: Could not load RSDT: %s\n",
-				  acpi_format_exception (status)));
+			acpi_format_exception (status)));
 		goto error_exit;
 	}
 
@@ -110,20 +111,20 @@ acpi_load_tables (void)
 
 	status = acpi_tb_get_required_tables ();
 	if (ACPI_FAILURE (status)) {
-		ACPI_REPORT_ERROR (("acpi_load_tables: Error getting required tables (DSDT/FADT/FACS): %s\n",
-				  acpi_format_exception (status)));
+		ACPI_REPORT_ERROR ((
+			"acpi_load_tables: Error getting required tables (DSDT/FADT/FACS): %s\n",
+			acpi_format_exception (status)));
 		goto error_exit;
 	}
 
 	ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "ACPI Tables successfully acquired\n"));
 
-
 	/* Load the namespace from the tables */
 
 	status = acpi_ns_load_namespace ();
 	if (ACPI_FAILURE (status)) {
 		ACPI_REPORT_ERROR (("acpi_load_tables: Could not load namespace: %s\n",
-				  acpi_format_exception (status)));
+			acpi_format_exception (status)));
 		goto error_exit;
 	}
 
@@ -139,7 +140,6 @@ error_exit:
 
 
 #ifdef ACPI_FUTURE_USAGE
-
 /*******************************************************************************
  *
  * FUNCTION:    acpi_load_table
@@ -250,7 +250,6 @@ acpi_unload_table (
 		return_ACPI_STATUS (AE_BAD_PARAMETER);
 	}
 
-
 	/* Find all tables of the requested type */
 
 	table_desc = acpi_gbl_table_lists[table_type].next;
@@ -321,7 +320,6 @@ acpi_get_table_header (
 		return_ACPI_STATUS (AE_BAD_PARAMETER);
 	}
 
-
 	/* Get a pointer to the entire table */
 
 	status = acpi_tb_get_table_ptr (table_type, instance, &tbl_ptr);
@@ -329,23 +327,20 @@ acpi_get_table_header (
 		return_ACPI_STATUS (status);
 	}
 
-	/*
-	 * The function will return a NULL pointer if the table is not loaded
-	 */
+	/* The function will return a NULL pointer if the table is not loaded */
+
 	if (tbl_ptr == NULL) {
 		return_ACPI_STATUS (AE_NOT_EXIST);
 	}
 
-	/*
-	 * Copy the header to the caller's buffer
-	 */
+	/* Copy the header to the caller's buffer */
+
 	ACPI_MEMCPY ((void *) out_table_header, (void *) tbl_ptr,
-			 sizeof (struct acpi_table_header));
+		sizeof (struct acpi_table_header));
 
 	return_ACPI_STATUS (status);
 }
 
-
 #endif  /*  ACPI_FUTURE_USAGE  */
 
 /*******************************************************************************
@@ -404,7 +399,6 @@ acpi_get_table (
 		return_ACPI_STATUS (AE_BAD_PARAMETER);
 	}
 
-
 	/* Get a pointer to the entire table */
 
 	status = acpi_tb_get_table_ptr (table_type, instance, &tbl_ptr);
@@ -423,9 +417,8 @@ acpi_get_table (
 	/* Get the table length */
 
 	if (table_type == ACPI_TABLE_RSDP) {
-		/*
-		 *  RSD PTR is the only "table" without a header
-		 */
+		/* RSD PTR is the only "table" without a header */
+
 		table_length = sizeof (struct rsdp_descriptor);
 	}
 	else {
diff --git a/drivers/acpi/tables/tbxfroot.c b/drivers/acpi/tables/tbxfroot.c
--- a/drivers/acpi/tables/tbxfroot.c
+++ b/drivers/acpi/tables/tbxfroot.c
@@ -50,6 +50,18 @@
 #define _COMPONENT          ACPI_TABLES
 	 ACPI_MODULE_NAME    ("tbxfroot")
 
+/* Local prototypes */
+
+static acpi_status
+acpi_tb_find_rsdp (
+	struct acpi_table_desc          *table_info,
+	u32                             flags);
+
+static u8 *
+acpi_tb_scan_memory_for_rsdp (
+	u8                              *start_address,
+	u32                             length);
+
 
 /*******************************************************************************
  *
@@ -57,7 +69,8 @@
  *
  * PARAMETERS:  Signature           - String with ACPI table signature
  *              oem_id              - String with the table OEM ID
- *              oem_table_id        - String with the OEM Table ID.
+ *              oem_table_id        - String with the OEM Table ID
+ *              table_ptr           - Where the table pointer is returned
  *
  * RETURN:      Status
  *
@@ -99,14 +112,13 @@ acpi_tb_find_table (
 		if (!acpi_gbl_DSDT) {
 			return_ACPI_STATUS (AE_NO_ACPI_TABLES);
 		}
-
 		table = acpi_gbl_DSDT;
 	}
 	else {
 		/* Find the table */
 
 		status = acpi_get_firmware_table (signature, 1,
-				   ACPI_LOGICAL_ADDRESSING, &table);
+				 ACPI_LOGICAL_ADDRESSING, &table);
 		if (ACPI_FAILURE (status)) {
 			return_ACPI_STATUS (status);
 		}
@@ -114,14 +126,19 @@ acpi_tb_find_table (
 
 	/* Check oem_id and oem_table_id */
 
-	if ((oem_id[0]     && ACPI_STRNCMP (
-			 oem_id, table->oem_id, sizeof (table->oem_id))) ||
+	if ((oem_id[0] && ACPI_STRNCMP (
+			   oem_id, table->oem_id,
+			   sizeof (table->oem_id))) ||
+
 		(oem_table_id[0] && ACPI_STRNCMP (
-				   oem_table_id, table->oem_table_id, sizeof (table->oem_table_id)))) {
+				   oem_table_id, table->oem_table_id,
+				   sizeof (table->oem_table_id)))) {
 		return_ACPI_STATUS (AE_AML_NAME_NOT_FOUND);
 	}
 
-	ACPI_DEBUG_PRINT ((ACPI_DB_TABLES, "Found table [%4.4s]\n", table->signature));
+	ACPI_DEBUG_PRINT ((ACPI_DB_TABLES, "Found table [%4.4s]\n",
+		table->signature));
+
 	*table_ptr = table;
 	return_ACPI_STATUS (AE_OK);
 }
@@ -191,8 +208,8 @@ acpi_get_firmware_table (
 		/* Map and validate the RSDP */
 
 		if ((flags & ACPI_MEMORY_MODE) == ACPI_LOGICAL_ADDRESSING) {
-			status = acpi_os_map_memory (address.pointer.physical, sizeof (struct rsdp_descriptor),
-					  (void *) &acpi_gbl_RSDP);
+			status = acpi_os_map_memory (address.pointer.physical,
+					 sizeof (struct rsdp_descriptor), (void *) &acpi_gbl_RSDP);
 			if (ACPI_FAILURE (status)) {
 				return_ACPI_STATUS (status);
 			}
@@ -203,7 +220,8 @@ acpi_get_firmware_table (
 
 		/* The signature and checksum must both be correct */
 
-		if (ACPI_STRNCMP ((char *) acpi_gbl_RSDP, RSDP_SIG, sizeof (RSDP_SIG)-1) != 0) {
+		if (ACPI_STRNCMP ((char *) acpi_gbl_RSDP, RSDP_SIG,
+				sizeof (RSDP_SIG)-1) != 0) {
 			/* Nope, BAD Signature */
 
 			return_ACPI_STATUS (AE_BAD_SIGNATURE);
@@ -313,7 +331,8 @@ acpi_get_firmware_table (
 
 
 cleanup:
-	acpi_os_unmap_memory (rsdt_info->pointer, (acpi_size) rsdt_info->pointer->length);
+	acpi_os_unmap_memory (rsdt_info->pointer,
+		(acpi_size) rsdt_info->pointer->length);
 	ACPI_MEM_FREE (rsdt_info);
 
 	if (header) {
@@ -335,8 +354,8 @@ EXPORT_SYMBOL(acpi_get_firmware_table);
  *
  * FUNCTION:    acpi_find_root_pointer
  *
- * PARAMETERS:  **rsdp_address          - Where to place the RSDP address
- *              Flags                   - Logical/Physical addressing
+ * PARAMETERS:  Flags                   - Logical/Physical addressing
+ *              rsdp_address            - Where to place the RSDP address
  *
  * RETURN:      Status, Physical address of the RSDP
  *
@@ -363,6 +382,7 @@ acpi_find_root_pointer (
 		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
 			"RSDP structure not found, %s Flags=%X\n",
 			acpi_format_exception (status), flags));
+
 		return_ACPI_STATUS (AE_NO_ACPI_TABLES);
 	}
 
@@ -385,7 +405,7 @@ acpi_find_root_pointer (
  *
  ******************************************************************************/
 
-u8 *
+static u8 *
 acpi_tb_scan_memory_for_rsdp (
 	u8                              *start_address,
 	u32                             length)
@@ -406,7 +426,8 @@ acpi_tb_scan_memory_for_rsdp (
 		 mem_rover += ACPI_RSDP_SCAN_STEP) {
 		/* The signature and checksum must both be correct */
 
-		if (ACPI_STRNCMP ((char *) mem_rover, RSDP_SIG, sizeof (RSDP_SIG)-1) != 0) {
+		if (ACPI_STRNCMP ((char *) mem_rover,
+				RSDP_SIG, sizeof (RSDP_SIG) - 1) != 0) {
 			/* No signature match, keep looking */
 
 			continue;
@@ -450,7 +471,7 @@ acpi_tb_scan_memory_for_rsdp (
  *
  * FUNCTION:    acpi_tb_find_rsdp
  *
- * PARAMETERS:  *table_info             - Where the table info is returned
+ * PARAMETERS:  table_info              - Where the table info is returned
  *              Flags                   - Current memory mode (logical vs.
  *                                        physical addressing)
  *
@@ -468,7 +489,7 @@ acpi_tb_scan_memory_for_rsdp (
  *
  ******************************************************************************/
 
-acpi_status
+static acpi_status
 acpi_tb_find_rsdp (
 	struct acpi_table_desc          *table_info,
 	u32                             flags)
@@ -483,43 +504,49 @@ acpi_tb_find_rsdp (
 
 
 	/*
-	 * Scan supports either 1) Logical addressing or 2) Physical addressing
+	 * Scan supports either logical addressing or physical addressing
 	 */
 	if ((flags & ACPI_MEMORY_MODE) == ACPI_LOGICAL_ADDRESSING) {
-		/*
-		 * 1a) Get the location of the EBDA
-		 */
-		status = acpi_os_map_memory ((acpi_physical_address) ACPI_EBDA_PTR_LOCATION,
-				  ACPI_EBDA_PTR_LENGTH,
-				  (void *) &table_ptr);
+		/* 1a) Get the location of the Extended BIOS Data Area (EBDA) */
+
+		status = acpi_os_map_memory (
+				 (acpi_physical_address) ACPI_EBDA_PTR_LOCATION,
+				 ACPI_EBDA_PTR_LENGTH, (void *) &table_ptr);
 		if (ACPI_FAILURE (status)) {
 			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
 				"Could not map memory at %8.8X for length %X\n",
 				ACPI_EBDA_PTR_LOCATION, ACPI_EBDA_PTR_LENGTH));
+
 			return_ACPI_STATUS (status);
 		}
 
 		ACPI_MOVE_16_TO_32 (&physical_address, table_ptr);
-		physical_address <<= 4;                 /* Convert segment to physical address */
+
+		/* Convert segment part to physical address */
+
+		physical_address <<= 4;
 		acpi_os_unmap_memory (table_ptr, ACPI_EBDA_PTR_LENGTH);
 
 		/* EBDA present? */
 
 		if (physical_address > 0x400) {
 			/*
-			 * 1b) Search EBDA paragraphs (EBDa is required to be a minimum of 1_k length)
+			 * 1b) Search EBDA paragraphs (EBDa is required to be a
+			 *     minimum of 1_k length)
 			 */
-			status = acpi_os_map_memory ((acpi_physical_address) physical_address,
-					  ACPI_EBDA_WINDOW_SIZE,
-					  (void *) &table_ptr);
+			status = acpi_os_map_memory (
+					 (acpi_physical_address) physical_address,
+					 ACPI_EBDA_WINDOW_SIZE, (void *) &table_ptr);
 			if (ACPI_FAILURE (status)) {
 				ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
 					"Could not map memory at %8.8X for length %X\n",
 					physical_address, ACPI_EBDA_WINDOW_SIZE));
+
 				return_ACPI_STATUS (status);
 			}
 
-			mem_rover = acpi_tb_scan_memory_for_rsdp (table_ptr, ACPI_EBDA_WINDOW_SIZE);
+			mem_rover = acpi_tb_scan_memory_for_rsdp (table_ptr,
+					  ACPI_EBDA_WINDOW_SIZE);
 			acpi_os_unmap_memory (table_ptr, ACPI_EBDA_WINDOW_SIZE);
 
 			if (mem_rover) {
@@ -527,7 +554,8 @@ acpi_tb_find_rsdp (
 
 				physical_address += ACPI_PTR_DIFF (mem_rover, table_ptr);
 
-				table_info->physical_address = (acpi_physical_address) physical_address;
+				table_info->physical_address =
+					(acpi_physical_address) physical_address;
 				return_ACPI_STATUS (AE_OK);
 			}
 		}
@@ -535,13 +563,15 @@ acpi_tb_find_rsdp (
 		/*
 		 * 2) Search upper memory: 16-byte boundaries in E0000h-FFFFFh
 		 */
-		status = acpi_os_map_memory ((acpi_physical_address) ACPI_HI_RSDP_WINDOW_BASE,
-				  ACPI_HI_RSDP_WINDOW_SIZE,
-				  (void *) &table_ptr);
+		status = acpi_os_map_memory (
+				 (acpi_physical_address) ACPI_HI_RSDP_WINDOW_BASE,
+				 ACPI_HI_RSDP_WINDOW_SIZE, (void *) &table_ptr);
+
 		if (ACPI_FAILURE (status)) {
 			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
 				"Could not map memory at %8.8X for length %X\n",
 				ACPI_HI_RSDP_WINDOW_BASE, ACPI_HI_RSDP_WINDOW_SIZE));
+
 			return_ACPI_STATUS (status);
 		}
 
@@ -551,9 +581,11 @@ acpi_tb_find_rsdp (
 		if (mem_rover) {
 			/* Found it, return the physical address */
 
-			physical_address = ACPI_HI_RSDP_WINDOW_BASE + ACPI_PTR_DIFF (mem_rover, table_ptr);
+			physical_address =
+				ACPI_HI_RSDP_WINDOW_BASE + ACPI_PTR_DIFF (mem_rover, table_ptr);
 
-			table_info->physical_address = (acpi_physical_address) physical_address;
+			table_info->physical_address =
+				(acpi_physical_address) physical_address;
 			return_ACPI_STATUS (AE_OK);
 		}
 	}
@@ -562,9 +594,8 @@ acpi_tb_find_rsdp (
 	 * Physical addressing
 	 */
 	else {
-		/*
-		 * 1a) Get the location of the EBDA
-		 */
+		/* 1a) Get the location of the EBDA */
+
 		ACPI_MOVE_16_TO_32 (&physical_address, ACPI_EBDA_PTR_LOCATION);
 		physical_address <<= 4;     /* Convert segment to physical address */
 
@@ -572,9 +603,11 @@ acpi_tb_find_rsdp (
 
 		if (physical_address > 0x400) {
 			/*
-			 * 1b) Search EBDA paragraphs (EBDa is required to be a minimum of 1_k length)
+			 * 1b) Search EBDA paragraphs (EBDa is required to be a minimum of
+			 *     1_k length)
 			 */
-			mem_rover = acpi_tb_scan_memory_for_rsdp (ACPI_PHYSADDR_TO_PTR (physical_address),
+			mem_rover = acpi_tb_scan_memory_for_rsdp (
+					  ACPI_PHYSADDR_TO_PTR (physical_address),
 					  ACPI_EBDA_WINDOW_SIZE);
 			if (mem_rover) {
 				/* Found it, return the physical address */
@@ -584,10 +617,10 @@ acpi_tb_find_rsdp (
 			}
 		}
 
-		/*
-		 * 2) Search upper memory: 16-byte boundaries in E0000h-FFFFFh
-		 */
-		mem_rover = acpi_tb_scan_memory_for_rsdp (ACPI_PHYSADDR_TO_PTR (ACPI_HI_RSDP_WINDOW_BASE),
+		/* 2) Search upper memory: 16-byte boundaries in E0000h-FFFFFh */
+
+		mem_rover = acpi_tb_scan_memory_for_rsdp (
+				  ACPI_PHYSADDR_TO_PTR (ACPI_HI_RSDP_WINDOW_BASE),
 				  ACPI_HI_RSDP_WINDOW_SIZE);
 		if (mem_rover) {
 			/* Found it, return the physical address */
diff --git a/drivers/acpi/toshiba_acpi.c b/drivers/acpi/toshiba_acpi.c
--- a/drivers/acpi/toshiba_acpi.c
+++ b/drivers/acpi/toshiba_acpi.c
@@ -263,6 +263,9 @@ dispatch_write(struct file* file, const 
 	 * destination so that sscanf can be used on it safely.
 	 */
 	tmp_buffer = kmalloc(count + 1, GFP_KERNEL);
+	if(!tmp_buffer)
+		return -ENOMEM;
+
 	if (copy_from_user(tmp_buffer, buffer, count)) {
 		result = -EFAULT;
 	}
@@ -529,6 +532,11 @@ toshiba_acpi_init(void)
 
 	if (acpi_disabled)
 		return -ENODEV;
+
+	if (!acpi_specific_hotkey_enabled){
+		printk(MY_INFO "Using generic hotkey driver\n");
+		return -ENODEV;	
+	}
 	/* simple device detection: look for HCI method */
 	if (is_valid_acpi_path(METHOD_HCI_1))
 		method_hci = METHOD_HCI_1;
diff --git a/drivers/acpi/utilities/utalloc.c b/drivers/acpi/utilities/utalloc.c
--- a/drivers/acpi/utilities/utalloc.c
+++ b/drivers/acpi/utilities/utalloc.c
@@ -47,8 +47,35 @@
 #define _COMPONENT          ACPI_UTILITIES
 	 ACPI_MODULE_NAME    ("utalloc")
 
+/* Local prototypes */
 
-/******************************************************************************
+#ifdef	ACPI_DBG_TRACK_ALLOCATIONS
+static struct acpi_debug_mem_block *
+acpi_ut_find_allocation (
+	u32                             list_id,
+	void                            *allocation);
+
+static acpi_status
+acpi_ut_track_allocation (
+	u32                             list_id,
+	struct acpi_debug_mem_block     *address,
+	acpi_size                       size,
+	u8                              alloc_type,
+	u32                             component,
+	char                            *module,
+	u32                             line);
+
+static acpi_status
+acpi_ut_remove_allocation (
+	u32                             list_id,
+	struct acpi_debug_mem_block     *address,
+	u32                             component,
+	char                            *module,
+	u32                             line);
+#endif	/* ACPI_DBG_TRACK_ALLOCATIONS */
+
+
+/*******************************************************************************
  *
  * FUNCTION:    acpi_ut_release_to_cache
  *
@@ -98,7 +125,8 @@ acpi_ut_release_to_cache (
 
 		/* Put the object at the head of the cache list */
 
-		* (ACPI_CAST_INDIRECT_PTR (char, &(((char *) object)[cache_info->link_offset]))) = cache_info->list_head;
+		* (ACPI_CAST_INDIRECT_PTR (char,
+			&(((char *) object)[cache_info->link_offset]))) = cache_info->list_head;
 		cache_info->list_head = object;
 		cache_info->cache_depth++;
 
@@ -115,7 +143,7 @@ acpi_ut_release_to_cache (
 }
 
 
-/******************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    acpi_ut_acquire_from_cache
  *
@@ -156,7 +184,8 @@ acpi_ut_acquire_from_cache (
 		/* There is an object available, use it */
 
 		object = cache_info->list_head;
-		cache_info->list_head = *(ACPI_CAST_INDIRECT_PTR (char, &(((char *) object)[cache_info->link_offset])));
+		cache_info->list_head = *(ACPI_CAST_INDIRECT_PTR (char,
+				 &(((char *) object)[cache_info->link_offset])));
 
 		ACPI_MEM_TRACKING (cache_info->cache_hits++);
 		cache_info->cache_depth--;
@@ -201,7 +230,7 @@ acpi_ut_acquire_from_cache (
 
 
 #ifdef ACPI_ENABLE_OBJECT_CACHE
-/******************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    acpi_ut_delete_generic_cache
  *
@@ -228,7 +257,8 @@ acpi_ut_delete_generic_cache (
 	while (cache_info->list_head) {
 		/* Delete one cached state object */
 
-		next = *(ACPI_CAST_INDIRECT_PTR (char, &(((char *) cache_info->list_head)[cache_info->link_offset])));
+		next = *(ACPI_CAST_INDIRECT_PTR (char,
+				 &(((char *) cache_info->list_head)[cache_info->link_offset])));
 		ACPI_MEM_FREE (cache_info->list_head);
 
 		cache_info->list_head = next;
@@ -497,8 +527,8 @@ acpi_ut_allocate_and_track (
 	acpi_status                     status;
 
 
-	allocation = acpi_ut_allocate (size + sizeof (struct acpi_debug_mem_header), component,
-			  module, line);
+	allocation = acpi_ut_allocate (size + sizeof (struct acpi_debug_mem_header),
+			  component, module, line);
 	if (!allocation) {
 		return (NULL);
 	}
@@ -543,8 +573,8 @@ acpi_ut_callocate_and_track (
 	acpi_status                     status;
 
 
-	allocation = acpi_ut_callocate (size + sizeof (struct acpi_debug_mem_header), component,
-			  module, line);
+	allocation = acpi_ut_callocate (size + sizeof (struct acpi_debug_mem_header),
+			  component, module, line);
 	if (!allocation) {
 		/* Report allocation error */
 
@@ -637,7 +667,7 @@ acpi_ut_free_and_track (
  *
  ******************************************************************************/
 
-struct acpi_debug_mem_block *
+static struct acpi_debug_mem_block *
 acpi_ut_find_allocation (
 	u32                             list_id,
 	void                            *allocation)
@@ -686,7 +716,7 @@ acpi_ut_find_allocation (
  *
  ******************************************************************************/
 
-acpi_status
+static acpi_status
 acpi_ut_track_allocation (
 	u32                             list_id,
 	struct acpi_debug_mem_block     *allocation,
@@ -721,10 +751,12 @@ acpi_ut_track_allocation (
 
 	element = acpi_ut_find_allocation (list_id, allocation);
 	if (element) {
-		ACPI_REPORT_ERROR (("ut_track_allocation: Allocation already present in list! (%p)\n",
+		ACPI_REPORT_ERROR ((
+			"ut_track_allocation: Allocation already present in list! (%p)\n",
 			allocation));
 
-		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Element %p Address %p\n", element, allocation));
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Element %p Address %p\n",
+			element, allocation));
 
 		goto unlock_and_exit;
 	}
@@ -773,7 +805,7 @@ unlock_and_exit:
  *
  ******************************************************************************/
 
-acpi_status
+static acpi_status
 acpi_ut_remove_allocation (
 	u32                             list_id,
 	struct acpi_debug_mem_block     *allocation,
@@ -797,7 +829,7 @@ acpi_ut_remove_allocation (
 		/* No allocations! */
 
 		_ACPI_REPORT_ERROR (module, line, component,
-				("ut_remove_allocation: Empty allocation list, nothing to free!\n"));
+			("ut_remove_allocation: Empty allocation list, nothing to free!\n"));
 
 		return_ACPI_STATUS (AE_OK);
 	}
@@ -824,7 +856,8 @@ acpi_ut_remove_allocation (
 
 	ACPI_MEMSET (&allocation->user_space, 0xEA, allocation->size);
 
-	ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Freeing size 0%X\n", allocation->size));
+	ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Freeing size 0%X\n",
+		allocation->size));
 
 	status = acpi_ut_release_mutex (ACPI_MTX_MEMORY);
 	return_ACPI_STATUS (status);
@@ -842,6 +875,7 @@ acpi_ut_remove_allocation (
  * DESCRIPTION: Print some info about the outstanding allocations.
  *
  ******************************************************************************/
+
 #ifdef ACPI_FUTURE_USAGE
 void
 acpi_ut_dump_allocation_info (
@@ -884,7 +918,8 @@ acpi_ut_dump_allocation_info (
 	ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
 			  ("%30s: %4d (%3d Kb)\n", "Max Nodes",
 			  acpi_gbl_max_concurrent_node_count,
-			  ROUND_UP_TO_1K ((acpi_gbl_max_concurrent_node_count * sizeof (struct acpi_namespace_node)))));
+			  ROUND_UP_TO_1K ((acpi_gbl_max_concurrent_node_count *
+					 sizeof (struct acpi_namespace_node)))));
 */
 	return_VOID;
 }
@@ -933,26 +968,26 @@ acpi_ut_dump_allocations (
 			descriptor = ACPI_CAST_PTR (union acpi_descriptor, &element->user_space);
 			if (descriptor->descriptor_id != ACPI_DESC_TYPE_CACHED) {
 				acpi_os_printf ("%p Len %04X %9.9s-%d [%s] ",
-						 descriptor, element->size, element->module,
-						 element->line, acpi_ut_get_descriptor_name (descriptor));
+					descriptor, element->size, element->module,
+					element->line, acpi_ut_get_descriptor_name (descriptor));
 
 				/* Most of the elements will be Operand objects. */
 
 				switch (ACPI_GET_DESCRIPTOR_TYPE (descriptor)) {
 				case ACPI_DESC_TYPE_OPERAND:
 					acpi_os_printf ("%12.12s R%hd",
-							acpi_ut_get_type_name (descriptor->object.common.type),
-							descriptor->object.common.reference_count);
+						acpi_ut_get_type_name (descriptor->object.common.type),
+						descriptor->object.common.reference_count);
 					break;
 
 				case ACPI_DESC_TYPE_PARSER:
 					acpi_os_printf ("aml_opcode %04hX",
-							descriptor->op.asl.aml_opcode);
+						descriptor->op.asl.aml_opcode);
 					break;
 
 				case ACPI_DESC_TYPE_NAMED:
 					acpi_os_printf ("%4.4s",
-							acpi_ut_get_node_name (&descriptor->node));
+						acpi_ut_get_node_name (&descriptor->node));
 					break;
 
 				default:
@@ -983,6 +1018,5 @@ acpi_ut_dump_allocations (
 	return_VOID;
 }
 
-
 #endif  /* #ifdef ACPI_DBG_TRACK_ALLOCATIONS */
 
diff --git a/drivers/acpi/utilities/utcopy.c b/drivers/acpi/utilities/utcopy.c
--- a/drivers/acpi/utilities/utcopy.c
+++ b/drivers/acpi/utilities/utcopy.c
@@ -49,21 +49,69 @@
 #define _COMPONENT          ACPI_UTILITIES
 	 ACPI_MODULE_NAME    ("utcopy")
 
+/* Local prototypes */
+
+static acpi_status
+acpi_ut_copy_isimple_to_esimple (
+	union acpi_operand_object       *internal_object,
+	union acpi_object               *external_object,
+	u8                              *data_space,
+	acpi_size                       *buffer_space_used);
+
+static acpi_status
+acpi_ut_copy_ielement_to_ielement (
+	u8                              object_type,
+	union acpi_operand_object       *source_object,
+	union acpi_generic_state        *state,
+	void                            *context);
+
+static acpi_status
+acpi_ut_copy_ipackage_to_epackage (
+	union acpi_operand_object       *internal_object,
+	u8                              *buffer,
+	acpi_size                       *space_used);
+
+static acpi_status
+acpi_ut_copy_esimple_to_isimple(
+	union acpi_object               *user_obj,
+	union acpi_operand_object       **return_obj);
+
+static acpi_status
+acpi_ut_copy_simple_object (
+	union acpi_operand_object       *source_desc,
+	union acpi_operand_object       *dest_desc);
+
+static acpi_status
+acpi_ut_copy_ielement_to_eelement (
+	u8                              object_type,
+	union acpi_operand_object       *source_object,
+	union acpi_generic_state        *state,
+	void                            *context);
+
+static acpi_status
+acpi_ut_copy_ipackage_to_ipackage (
+	union acpi_operand_object       *source_obj,
+	union acpi_operand_object       *dest_obj,
+	struct acpi_walk_state          *walk_state);
+
 
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ut_copy_isimple_to_esimple
  *
- * PARAMETERS:  *internal_object    - Pointer to the object we are examining
- *              *Buffer             - Where the object is returned
- *              *space_used         - Where the data length is returned
+ * PARAMETERS:  internal_object     - Source object to be copied
+ *              external_object     - Where to return the copied object
+ *              data_space          - Where object data is returned (such as
+ *                                    buffer and string data)
+ *              buffer_space_used   - Length of data_space that was used
  *
  * RETURN:      Status
  *
- * DESCRIPTION: This function is called to place a simple object in a user
- *              buffer.
+ * DESCRIPTION: This function is called to copy a simple internal object to
+ *              an external object.
  *
- *              The buffer is assumed to have sufficient space for the object.
+ *              The data_space buffer is assumed to have sufficient space for
+ *              the object.
  *
  ******************************************************************************/
 
@@ -107,10 +155,12 @@ acpi_ut_copy_isimple_to_esimple (
 
 		external_object->string.pointer = (char *) data_space;
 		external_object->string.length = internal_object->string.length;
-		*buffer_space_used = ACPI_ROUND_UP_TO_NATIVE_WORD ((acpi_size) internal_object->string.length + 1);
+		*buffer_space_used = ACPI_ROUND_UP_TO_NATIVE_WORD (
+				   (acpi_size) internal_object->string.length + 1);
 
-		ACPI_MEMCPY ((void *) data_space, (void *) internal_object->string.pointer,
-				 (acpi_size) internal_object->string.length + 1);
+		ACPI_MEMCPY ((void *) data_space,
+			(void *) internal_object->string.pointer,
+			(acpi_size) internal_object->string.length + 1);
 		break;
 
 
@@ -118,10 +168,12 @@ acpi_ut_copy_isimple_to_esimple (
 
 		external_object->buffer.pointer = data_space;
 		external_object->buffer.length = internal_object->buffer.length;
-		*buffer_space_used = ACPI_ROUND_UP_TO_NATIVE_WORD (internal_object->string.length);
+		*buffer_space_used = ACPI_ROUND_UP_TO_NATIVE_WORD (
+				   internal_object->string.length);
 
-		ACPI_MEMCPY ((void *) data_space, (void *) internal_object->buffer.pointer,
-				 internal_object->buffer.length);
+		ACPI_MEMCPY ((void *) data_space,
+			(void *) internal_object->buffer.pointer,
+			internal_object->buffer.length);
 		break;
 
 
@@ -194,7 +246,7 @@ acpi_ut_copy_isimple_to_esimple (
  *
  ******************************************************************************/
 
-acpi_status
+static acpi_status
 acpi_ut_copy_ielement_to_eelement (
 	u8                              object_type,
 	union acpi_operand_object       *source_object,
@@ -213,7 +265,7 @@ acpi_ut_copy_ielement_to_eelement (
 
 	this_index   = state->pkg.index;
 	target_object = (union acpi_object *)
-			  &((union acpi_object *)(state->pkg.dest_object))->package.elements[this_index];
+		&((union acpi_object *)(state->pkg.dest_object))->package.elements[this_index];
 
 	switch (object_type) {
 	case ACPI_COPY_TYPE_SIMPLE:
@@ -236,7 +288,8 @@ acpi_ut_copy_ielement_to_eelement (
 		 */
 		target_object->type             = ACPI_TYPE_PACKAGE;
 		target_object->package.count    = source_object->package.count;
-		target_object->package.elements = ACPI_CAST_PTR (union acpi_object, info->free_space);
+		target_object->package.elements =
+			ACPI_CAST_PTR (union acpi_object, info->free_space);
 
 		/*
 		 * Pass the new package object back to the package walk routine
@@ -248,7 +301,8 @@ acpi_ut_copy_ielement_to_eelement (
 		 * update the buffer length counter
 		 */
 		object_space = ACPI_ROUND_UP_TO_NATIVE_WORD (
-				   (acpi_size) target_object->package.count * sizeof (union acpi_object));
+				   (acpi_size) target_object->package.count *
+				   sizeof (union acpi_object));
 		break;
 
 
@@ -266,9 +320,9 @@ acpi_ut_copy_ielement_to_eelement (
  *
  * FUNCTION:    acpi_ut_copy_ipackage_to_epackage
  *
- * PARAMETERS:  *internal_object    - Pointer to the object we are returning
- *              *Buffer             - Where the object is returned
- *              *space_used         - Where the object length is returned
+ * PARAMETERS:  internal_object     - Pointer to the object we are returning
+ *              Buffer              - Where the object is returned
+ *              space_used          - Where the object length is returned
  *
  * RETURN:      Status
  *
@@ -304,13 +358,15 @@ acpi_ut_copy_ipackage_to_epackage (
 	 * Free space begins right after the first package
 	 */
 	info.length      = ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (union acpi_object));
-	info.free_space  = buffer + ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (union acpi_object));
+	info.free_space  = buffer + ACPI_ROUND_UP_TO_NATIVE_WORD (
+			   sizeof (union acpi_object));
 	info.object_space = 0;
 	info.num_packages = 1;
 
 	external_object->type            = ACPI_GET_OBJECT_TYPE (internal_object);
 	external_object->package.count   = internal_object->package.count;
-	external_object->package.elements = ACPI_CAST_PTR (union acpi_object, info.free_space);
+	external_object->package.elements = ACPI_CAST_PTR (union acpi_object,
+			  info.free_space);
 
 	/*
 	 * Leave room for an array of ACPI_OBJECTS in the buffer
@@ -333,8 +389,8 @@ acpi_ut_copy_ipackage_to_epackage (
  *
  * FUNCTION:    acpi_ut_copy_iobject_to_eobject
  *
- * PARAMETERS:  *internal_object    - The internal object to be converted
- *              *buffer_ptr         - Where the object is returned
+ * PARAMETERS:  internal_object     - The internal object to be converted
+ *              buffer_ptr          - Where the object is returned
  *
  * RETURN:      Status
  *
@@ -367,10 +423,10 @@ acpi_ut_copy_iobject_to_eobject (
 		 * Build a simple object (no nested objects)
 		 */
 		status = acpi_ut_copy_isimple_to_esimple (internal_object,
-				  (union acpi_object *) ret_buffer->pointer,
-				  ((u8 *) ret_buffer->pointer +
-				  ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (union acpi_object))),
-				  &ret_buffer->length);
+				 (union acpi_object *) ret_buffer->pointer,
+				 ((u8 *) ret_buffer->pointer +
+				 ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (union acpi_object))),
+				 &ret_buffer->length);
 		/*
 		 * build simple does not include the object size in the length
 		 * so we add it in here
@@ -386,8 +442,8 @@ acpi_ut_copy_iobject_to_eobject (
  *
  * FUNCTION:    acpi_ut_copy_esimple_to_isimple
  *
- * PARAMETERS:  *external_object   - The external object to be converted
- *              *internal_object   - Where the internal object is returned
+ * PARAMETERS:  external_object     - The external object to be converted
+ *              ret_internal_object - Where the internal object is returned
  *
  * RETURN:      Status
  *
@@ -398,7 +454,7 @@ acpi_ut_copy_iobject_to_eobject (
  *
  ******************************************************************************/
 
-acpi_status
+static acpi_status
 acpi_ut_copy_esimple_to_isimple (
 	union acpi_object               *external_object,
 	union acpi_operand_object       **ret_internal_object)
@@ -417,7 +473,8 @@ acpi_ut_copy_esimple_to_isimple (
 	case ACPI_TYPE_BUFFER:
 	case ACPI_TYPE_INTEGER:
 
-		internal_object = acpi_ut_create_internal_object ((u8) external_object->type);
+		internal_object = acpi_ut_create_internal_object (
+				   (u8) external_object->type);
 		if (!internal_object) {
 			return_ACPI_STATUS (AE_NO_MEMORY);
 		}
@@ -486,7 +543,6 @@ error_exit:
 
 
 #ifdef ACPI_FUTURE_IMPLEMENTATION
-
 /* Code to convert packages that are parameters to control methods */
 
 /*******************************************************************************
@@ -614,7 +670,7 @@ acpi_ut_copy_eobject_to_iobject (
  *
  ******************************************************************************/
 
-acpi_status
+static acpi_status
 acpi_ut_copy_simple_object (
 	union acpi_operand_object       *source_desc,
 	union acpi_operand_object       *dest_desc)
@@ -724,7 +780,7 @@ acpi_ut_copy_simple_object (
  *
  ******************************************************************************/
 
-acpi_status
+static acpi_status
 acpi_ut_copy_ielement_to_ielement (
 	u8                              object_type,
 	union acpi_operand_object       *source_object,
@@ -837,7 +893,7 @@ error_exit:
  *
  ******************************************************************************/
 
-acpi_status
+static acpi_status
 acpi_ut_copy_ipackage_to_ipackage (
 	union acpi_operand_object       *source_obj,
 	union acpi_operand_object       *dest_obj,
diff --git a/drivers/acpi/utilities/utdebug.c b/drivers/acpi/utilities/utdebug.c
--- a/drivers/acpi/utilities/utdebug.c
+++ b/drivers/acpi/utilities/utdebug.c
@@ -56,7 +56,7 @@ static char     *acpi_gbl_fn_entry_str =
 static char     *acpi_gbl_fn_exit_str = "----Exit-";
 
 
-/*****************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    acpi_ut_init_stack_ptr_trace
  *
@@ -64,9 +64,9 @@ static char     *acpi_gbl_fn_exit_str = 
  *
  * RETURN:      None
  *
- * DESCRIPTION: Save the current stack pointer
+ * DESCRIPTION: Save the current CPU stack pointer at subsystem startup
  *
- ****************************************************************************/
+ ******************************************************************************/
 
 void
 acpi_ut_init_stack_ptr_trace (
@@ -79,7 +79,7 @@ acpi_ut_init_stack_ptr_trace (
 }
 
 
-/*****************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    acpi_ut_track_stack_ptr
  *
@@ -87,9 +87,9 @@ acpi_ut_init_stack_ptr_trace (
  *
  * RETURN:      None
  *
- * DESCRIPTION: Save the current stack pointer
+ * DESCRIPTION: Save the current CPU stack pointer
  *
- ****************************************************************************/
+ ******************************************************************************/
 
 void
 acpi_ut_track_stack_ptr (
@@ -110,16 +110,16 @@ acpi_ut_track_stack_ptr (
 }
 
 
-/*****************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    acpi_ut_debug_print
  *
- * PARAMETERS:  debug_level         - Requested debug print level
- *              proc_name           - Caller's procedure name
- *              module_name         - Caller's module name (for error output)
+ * PARAMETERS:  requested_debug_level - Requested debug print level
  *              line_number         - Caller's line number (for error output)
- *              component_id        - Caller's component ID (for error output)
- *
+ *              dbg_info            - Contains:
+ *                  proc_name           - Caller's procedure name
+ *                  module_name         - Caller's module name
+ *                  component_id        - Caller's component ID
  *              Format              - Printf format field
  *              ...                 - Optional printf arguments
  *
@@ -128,7 +128,7 @@ acpi_ut_track_stack_ptr (
  * DESCRIPTION: Print error message with prefix consisting of the module name,
  *              line number, and component ID.
  *
- ****************************************************************************/
+ ******************************************************************************/
 
 void  ACPI_INTERNAL_VAR_XFACE
 acpi_ut_debug_print (
@@ -157,7 +157,8 @@ acpi_ut_debug_print (
 
 	if (thread_id != acpi_gbl_prev_thread_id) {
 		if (ACPI_LV_THREADS & acpi_dbg_level) {
-			acpi_os_printf ("\n**** Context Switch from TID %X to TID %X ****\n\n",
+			acpi_os_printf (
+				"\n**** Context Switch from TID %X to TID %X ****\n\n",
 				acpi_gbl_prev_thread_id, thread_id);
 		}
 
@@ -174,15 +175,16 @@ acpi_ut_debug_print (
 		acpi_os_printf ("[%04lX] ", thread_id);
 	}
 
-	acpi_os_printf ("[%02ld] %-22.22s: ", acpi_gbl_nesting_level, dbg_info->proc_name);
+	acpi_os_printf ("[%02ld] %-22.22s: ",
+		acpi_gbl_nesting_level, dbg_info->proc_name);
 
 	va_start (args, format);
 	acpi_os_vprintf (format, args);
 }
-EXPORT_SYMBOL(acpi_ut_debug_print);
 
+EXPORT_SYMBOL(acpi_ut_debug_print);
 
-/*****************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    acpi_ut_debug_print_raw
  *
@@ -200,7 +202,7 @@ EXPORT_SYMBOL(acpi_ut_debug_print);
  * DESCRIPTION: Print message with no headers.  Has same interface as
  *              debug_print so that the same macros can be used.
  *
- ****************************************************************************/
+ ******************************************************************************/
 
 void  ACPI_INTERNAL_VAR_XFACE
 acpi_ut_debug_print_raw (
@@ -224,7 +226,7 @@ acpi_ut_debug_print_raw (
 EXPORT_SYMBOL(acpi_ut_debug_print_raw);
 
 
-/*****************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    acpi_ut_trace
  *
@@ -239,7 +241,7 @@ EXPORT_SYMBOL(acpi_ut_debug_print_raw);
  * DESCRIPTION: Function entry trace.  Prints only if TRACE_FUNCTIONS bit is
  *              set in debug_level
  *
- ****************************************************************************/
+ ******************************************************************************/
 
 void
 acpi_ut_trace (
@@ -256,7 +258,7 @@ acpi_ut_trace (
 EXPORT_SYMBOL(acpi_ut_trace);
 
 
-/*****************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    acpi_ut_trace_ptr
  *
@@ -272,7 +274,7 @@ EXPORT_SYMBOL(acpi_ut_trace);
  * DESCRIPTION: Function entry trace.  Prints only if TRACE_FUNCTIONS bit is
  *              set in debug_level
  *
- ****************************************************************************/
+ ******************************************************************************/
 
 void
 acpi_ut_trace_ptr (
@@ -288,7 +290,7 @@ acpi_ut_trace_ptr (
 }
 
 
-/*****************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    acpi_ut_trace_str
  *
@@ -304,7 +306,7 @@ acpi_ut_trace_ptr (
  * DESCRIPTION: Function entry trace.  Prints only if TRACE_FUNCTIONS bit is
  *              set in debug_level
  *
- ****************************************************************************/
+ ******************************************************************************/
 
 void
 acpi_ut_trace_str (
@@ -321,7 +323,7 @@ acpi_ut_trace_str (
 }
 
 
-/*****************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    acpi_ut_trace_u32
  *
@@ -337,7 +339,7 @@ acpi_ut_trace_str (
  * DESCRIPTION: Function entry trace.  Prints only if TRACE_FUNCTIONS bit is
  *              set in debug_level
  *
- ****************************************************************************/
+ ******************************************************************************/
 
 void
 acpi_ut_trace_u32 (
@@ -354,7 +356,7 @@ acpi_ut_trace_u32 (
 }
 
 
-/*****************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    acpi_ut_exit
  *
@@ -369,7 +371,7 @@ acpi_ut_trace_u32 (
  * DESCRIPTION: Function exit trace.  Prints only if TRACE_FUNCTIONS bit is
  *              set in debug_level
  *
- ****************************************************************************/
+ ******************************************************************************/
 
 void
 acpi_ut_exit (
@@ -385,7 +387,7 @@ acpi_ut_exit (
 EXPORT_SYMBOL(acpi_ut_exit);
 
 
-/*****************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    acpi_ut_status_exit
  *
@@ -401,7 +403,7 @@ EXPORT_SYMBOL(acpi_ut_exit);
  * DESCRIPTION: Function exit trace.  Prints only if TRACE_FUNCTIONS bit is
  *              set in debug_level. Prints exit status also.
  *
- ****************************************************************************/
+ ******************************************************************************/
 
 void
 acpi_ut_status_exit (
@@ -426,7 +428,7 @@ acpi_ut_status_exit (
 EXPORT_SYMBOL(acpi_ut_status_exit);
 
 
-/*****************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    acpi_ut_value_exit
  *
@@ -442,7 +444,7 @@ EXPORT_SYMBOL(acpi_ut_status_exit);
  * DESCRIPTION: Function exit trace.  Prints only if TRACE_FUNCTIONS bit is
  *              set in debug_level. Prints exit value also.
  *
- ****************************************************************************/
+ ******************************************************************************/
 
 void
 acpi_ut_value_exit (
@@ -460,7 +462,7 @@ acpi_ut_value_exit (
 EXPORT_SYMBOL(acpi_ut_value_exit);
 
 
-/*****************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    acpi_ut_ptr_exit
  *
@@ -469,14 +471,14 @@ EXPORT_SYMBOL(acpi_ut_value_exit);
  *                  proc_name           - Caller's procedure name
  *                  module_name         - Caller's module name
  *                  component_id        - Caller's component ID
- *              Value               - Value to be printed with exit msg
+ *              Ptr                 - Pointer to display
  *
  * RETURN:      None
  *
  * DESCRIPTION: Function exit trace.  Prints only if TRACE_FUNCTIONS bit is
  *              set in debug_level. Prints exit value also.
  *
- ****************************************************************************/
+ ******************************************************************************/
 
 void
 acpi_ut_ptr_exit (
@@ -494,7 +496,7 @@ acpi_ut_ptr_exit (
 #endif
 
 
-/*****************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    acpi_ut_dump_buffer
  *
@@ -507,7 +509,7 @@ acpi_ut_ptr_exit (
  *
  * DESCRIPTION: Generic dump buffer in both hex and ascii.
  *
- ****************************************************************************/
+ ******************************************************************************/
 
 void
 acpi_ut_dump_buffer (
@@ -533,34 +535,28 @@ acpi_ut_dump_buffer (
 		display = DB_BYTE_DISPLAY;
 	}
 
-	acpi_os_printf ("\nOffset Value\n");
+	/* Nasty little dump buffer routine! */
 
-	/*
-	 * Nasty little dump buffer routine!
-	 */
 	while (i < count) {
 		/* Print current offset */
 
-		acpi_os_printf ("%05X  ", (u32) i);
+		acpi_os_printf ("%6.4X: ", (u32) i);
 
 		/* Print 16 hex chars */
 
 		for (j = 0; j < 16;) {
 			if (i + j >= count) {
-				acpi_os_printf ("\n");
-				return;
-			}
+				/* Dump fill spaces */
 
-			/* Make sure that the s8 doesn't get sign-extended! */
+				acpi_os_printf ("%*s", ((display * 2) + 1), " ");
+				j += display;
+				continue;
+			}
 
 			switch (display) {
-			/* Default is BYTE display */
+			default:    /* Default is BYTE display */
 
-			default:
-
-				acpi_os_printf ("%02X ",
-						*((u8 *) &buffer[i + j]));
-				j += 1;
+				acpi_os_printf ("%02X ", buffer[i + j]);
 				break;
 
 
@@ -568,7 +564,6 @@ acpi_ut_dump_buffer (
 
 				ACPI_MOVE_16_TO_32 (&temp32, &buffer[i + j]);
 				acpi_os_printf ("%04X ", temp32);
-				j += 2;
 				break;
 
 
@@ -576,7 +571,6 @@ acpi_ut_dump_buffer (
 
 				ACPI_MOVE_32_TO_32 (&temp32, &buffer[i + j]);
 				acpi_os_printf ("%08X ", temp32);
-				j += 4;
 				break;
 
 
@@ -587,15 +581,17 @@ acpi_ut_dump_buffer (
 
 				ACPI_MOVE_32_TO_32 (&temp32, &buffer[i + j + 4]);
 				acpi_os_printf ("%08X ", temp32);
-				j += 8;
 				break;
 			}
+
+			j += display;
 		}
 
 		/*
 		 * Print the ASCII equivalent characters
 		 * But watch out for the bad unprintable ones...
 		 */
+		acpi_os_printf (" ");
 		for (j = 0; j < 16; j++) {
 			if (i + j >= count) {
 				acpi_os_printf ("\n");
diff --git a/drivers/acpi/utilities/utdelete.c b/drivers/acpi/utilities/utdelete.c
--- a/drivers/acpi/utilities/utdelete.c
+++ b/drivers/acpi/utilities/utdelete.c
@@ -51,12 +51,23 @@
 #define _COMPONENT          ACPI_UTILITIES
 	 ACPI_MODULE_NAME    ("utdelete")
 
+/* Local prototypes */
+
+static void
+acpi_ut_delete_internal_obj (
+	union acpi_operand_object       *object);
+
+static void
+acpi_ut_update_ref_count (
+	union acpi_operand_object       *object,
+	u32                             action);
+
 
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ut_delete_internal_obj
  *
- * PARAMETERS:  *Object        - Pointer to the list to be deleted
+ * PARAMETERS:  Object         - Object to be deleted
  *
  * RETURN:      None
  *
@@ -65,7 +76,7 @@
  *
  ******************************************************************************/
 
-void
+static void
 acpi_ut_delete_internal_obj (
 	union acpi_operand_object       *object)
 {
@@ -152,7 +163,8 @@ acpi_ut_delete_internal_obj (
 
 	case ACPI_TYPE_MUTEX:
 
-		ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "***** Mutex %p, Semaphore %p\n",
+		ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
+			"***** Mutex %p, Semaphore %p\n",
 			object, object->mutex.semaphore));
 
 		acpi_ex_unlink_mutex (object);
@@ -162,7 +174,8 @@ acpi_ut_delete_internal_obj (
 
 	case ACPI_TYPE_EVENT:
 
-		ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "***** Event %p, Semaphore %p\n",
+		ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
+			"***** Event %p, Semaphore %p\n",
 			object, object->event.semaphore));
 
 		(void) acpi_os_delete_semaphore (object->event.semaphore);
@@ -172,7 +185,8 @@ acpi_ut_delete_internal_obj (
 
 	case ACPI_TYPE_METHOD:
 
-		ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "***** Method %p\n", object));
+		ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
+			"***** Method %p\n", object));
 
 		/* Delete the method semaphore if it exists */
 
@@ -185,7 +199,8 @@ acpi_ut_delete_internal_obj (
 
 	case ACPI_TYPE_REGION:
 
-		ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "***** Region %p\n", object));
+		ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
+			"***** Region %p\n", object));
 
 		second_desc = acpi_ns_get_secondary_object (object);
 		if (second_desc) {
@@ -212,7 +227,8 @@ acpi_ut_delete_internal_obj (
 
 	case ACPI_TYPE_BUFFER_FIELD:
 
-		ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "***** Buffer Field %p\n", object));
+		ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
+			"***** Buffer Field %p\n", object));
 
 		second_desc = acpi_ns_get_secondary_object (object);
 		if (second_desc) {
@@ -247,7 +263,7 @@ acpi_ut_delete_internal_obj (
  *
  * FUNCTION:    acpi_ut_delete_internal_object_list
  *
- * PARAMETERS:  *obj_list       - Pointer to the list to be deleted
+ * PARAMETERS:  obj_list        - Pointer to the list to be deleted
  *
  * RETURN:      None
  *
@@ -283,7 +299,7 @@ acpi_ut_delete_internal_object_list (
  *
  * FUNCTION:    acpi_ut_update_ref_count
  *
- * PARAMETERS:  *Object         - Object whose ref count is to be updated
+ * PARAMETERS:  Object          - Object whose ref count is to be updated
  *              Action          - What to do
  *
  * RETURN:      New ref count
@@ -312,7 +328,8 @@ acpi_ut_update_ref_count (
 	new_count = count;
 
 	/*
-	 * Perform the reference count action (increment, decrement, or force delete)
+	 * Perform the reference count action
+	 * (increment, decrement, or force delete)
 	 */
 	switch (action) {
 
@@ -321,7 +338,8 @@ acpi_ut_update_ref_count (
 		new_count++;
 		object->common.reference_count = new_count;
 
-		ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Obj %p Refs=%X, [Incremented]\n",
+		ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
+			"Obj %p Refs=%X, [Incremented]\n",
 			object, new_count));
 		break;
 
@@ -329,7 +347,8 @@ acpi_ut_update_ref_count (
 	case REF_DECREMENT:
 
 		if (count < 1) {
-			ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Obj %p Refs=%X, can't decrement! (Set to 0)\n",
+			ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
+				"Obj %p Refs=%X, can't decrement! (Set to 0)\n",
 				object, new_count));
 
 			new_count = 0;
@@ -337,12 +356,14 @@ acpi_ut_update_ref_count (
 		else {
 			new_count--;
 
-			ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Obj %p Refs=%X, [Decremented]\n",
+			ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
+				"Obj %p Refs=%X, [Decremented]\n",
 				object, new_count));
 		}
 
 		if (ACPI_GET_OBJECT_TYPE (object) == ACPI_TYPE_METHOD) {
-			ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Method Obj %p Refs=%X, [Decremented]\n",
+			ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
+				"Method Obj %p Refs=%X, [Decremented]\n",
 				object, new_count));
 		}
 
@@ -356,7 +377,8 @@ acpi_ut_update_ref_count (
 
 	case REF_FORCE_DELETE:
 
-		ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Obj %p Refs=%X, Force delete! (Set to 0)\n",
+		ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
+			"Obj %p Refs=%X, Force delete! (Set to 0)\n",
 			object, count));
 
 		new_count = 0;
@@ -390,7 +412,7 @@ acpi_ut_update_ref_count (
  *
  * FUNCTION:    acpi_ut_update_object_reference
  *
- * PARAMETERS:  *Object             - Increment ref count for this object
+ * PARAMETERS:  Object              - Increment ref count for this object
  *                                    and all sub-objects
  *              Action              - Either REF_INCREMENT or REF_DECREMENT or
  *                                    REF_FORCE_DELETE
@@ -431,7 +453,8 @@ acpi_ut_update_object_reference (
 	/* Make sure that this isn't a namespace handle */
 
 	if (ACPI_GET_DESCRIPTOR_TYPE (object) == ACPI_DESC_TYPE_NAMED) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Object %p is NS handle\n", object));
+		ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
+			"Object %p is NS handle\n", object));
 		return_ACPI_STATUS (AE_OK);
 	}
 
@@ -614,8 +637,8 @@ error_exit:
  *
  * FUNCTION:    acpi_ut_add_reference
  *
- * PARAMETERS:  *Object        - Object whose reference count is to be
- *                                  incremented
+ * PARAMETERS:  Object          - Object whose reference count is to be
+ *                                incremented
  *
  * RETURN:      None
  *
@@ -652,7 +675,7 @@ acpi_ut_add_reference (
  *
  * FUNCTION:    acpi_ut_remove_reference
  *
- * PARAMETERS:  *Object        - Object whose ref count will be decremented
+ * PARAMETERS:  Object         - Object whose ref count will be decremented
  *
  * RETURN:      None
  *
diff --git a/drivers/acpi/utilities/uteval.c b/drivers/acpi/utilities/uteval.c
--- a/drivers/acpi/utilities/uteval.c
+++ b/drivers/acpi/utilities/uteval.c
@@ -50,6 +50,19 @@
 #define _COMPONENT          ACPI_UTILITIES
 	 ACPI_MODULE_NAME    ("uteval")
 
+/* Local prototypes */
+
+static void
+acpi_ut_copy_id_string (
+	char                            *destination,
+	char                            *source,
+	acpi_size                       max_length);
+
+static acpi_status
+acpi_ut_translate_one_cid (
+	union acpi_operand_object       *obj_desc,
+	struct acpi_compatible_id       *one_cid);
+
 
 /*******************************************************************************
  *
@@ -237,9 +250,9 @@ acpi_ut_evaluate_object (
  *
  * FUNCTION:    acpi_ut_evaluate_numeric_object
  *
- * PARAMETERS:  *object_name        - Object name to be evaluated
+ * PARAMETERS:  object_name         - Object name to be evaluated
  *              device_node         - Node for the device
- *              *Address            - Where the value is returned
+ *              Address             - Where the value is returned
  *
  * RETURN:      Status
  *
@@ -303,7 +316,6 @@ acpi_ut_copy_id_string (
 	acpi_size                       max_length)
 {
 
-
 	/*
 	 * Workaround for ID strings that have a leading asterisk. This construct
 	 * is not allowed by the ACPI specification  (ID strings must be
@@ -325,7 +337,7 @@ acpi_ut_copy_id_string (
  * FUNCTION:    acpi_ut_execute_HID
  *
  * PARAMETERS:  device_node         - Node for the device
- *              *Hid                - Where the HID is returned
+ *              Hid                 - Where the HID is returned
  *
  * RETURN:      Status
  *
@@ -429,7 +441,7 @@ acpi_ut_translate_one_cid (
  * FUNCTION:    acpi_ut_execute_CID
  *
  * PARAMETERS:  device_node         - Node for the device
- *              *Cid                - Where the CID is returned
+ *              return_cid_list     - Where the CID list is returned
  *
  * RETURN:      Status
  *
@@ -488,10 +500,10 @@ acpi_ut_execute_CID (
 	cid_list->size = size;
 
 	/*
-	 *  A _CID can return either a single compatible ID or a package of compatible
-	 *  IDs.  Each compatible ID can be one of the following:
-	 *  -- Number (32 bit compressed EISA ID) or
-	 *  -- String (PCI ID format, e.g. "PCI\VEN_vvvv&DEV_dddd&SUBSYS_ssssssss").
+	 *  A _CID can return either a single compatible ID or a package of
+	 *  compatible IDs.  Each compatible ID can be one of the following:
+	 *  1) Integer (32 bit compressed EISA ID) or
+	 *  2) String (PCI ID format, e.g. "PCI\VEN_vvvv&DEV_dddd&SUBSYS_ssssssss")
 	 */
 
 	/* The _CID object can be either a single CID or a package (list) of CIDs */
@@ -534,7 +546,7 @@ acpi_ut_execute_CID (
  * FUNCTION:    acpi_ut_execute_UID
  *
  * PARAMETERS:  device_node         - Node for the device
- *              *Uid                - Where the UID is returned
+ *              Uid                 - Where the UID is returned
  *
  * RETURN:      Status
  *
@@ -587,7 +599,7 @@ acpi_ut_execute_UID (
  * FUNCTION:    acpi_ut_execute_STA
  *
  * PARAMETERS:  device_node         - Node for the device
- *              *Flags              - Where the status flags are returned
+ *              Flags               - Where the status flags are returned
  *
  * RETURN:      Status
  *
@@ -641,7 +653,7 @@ acpi_ut_execute_STA (
  * FUNCTION:    acpi_ut_execute_Sxds
  *
  * PARAMETERS:  device_node         - Node for the device
- *              *Flags              - Where the status flags are returned
+ *              Flags               - Where the status flags are returned
  *
  * RETURN:      Status
  *
diff --git a/drivers/acpi/utilities/utglobal.c b/drivers/acpi/utilities/utglobal.c
--- a/drivers/acpi/utilities/utglobal.c
+++ b/drivers/acpi/utilities/utglobal.c
@@ -44,7 +44,6 @@
 #define DEFINE_ACPI_GLOBALS
 
 #include <linux/module.h>
-
 #include <acpi/acpi.h>
 #include <acpi/acnamesp.h>
 
@@ -52,13 +51,14 @@
 	 ACPI_MODULE_NAME    ("utglobal")
 
 
-/******************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    acpi_format_exception
  *
  * PARAMETERS:  Status       - The acpi_status code to be formatted
  *
- * RETURN:      A string containing the exception  text
+ * RETURN:      A string containing the exception text. A valid pointer is
+ *              always returned.
  *
  * DESCRIPTION: This function translates an ACPI exception into an ASCII string.
  *
@@ -68,8 +68,8 @@ const char *
 acpi_format_exception (
 	acpi_status                     status)
 {
-	const char                      *exception = "UNKNOWN_STATUS_CODE";
 	acpi_status                     sub_status;
+	const char                      *exception = NULL;
 
 
 	ACPI_FUNCTION_NAME ("format_exception");
@@ -82,57 +82,55 @@ acpi_format_exception (
 
 		if (sub_status <= AE_CODE_ENV_MAX) {
 			exception = acpi_gbl_exception_names_env [sub_status];
-			break;
 		}
-		goto unknown;
+		break;
 
 	case AE_CODE_PROGRAMMER:
 
 		if (sub_status <= AE_CODE_PGM_MAX) {
 			exception = acpi_gbl_exception_names_pgm [sub_status -1];
-			break;
 		}
-		goto unknown;
+		break;
 
 	case AE_CODE_ACPI_TABLES:
 
 		if (sub_status <= AE_CODE_TBL_MAX) {
 			exception = acpi_gbl_exception_names_tbl [sub_status -1];
-			break;
 		}
-		goto unknown;
+		break;
 
 	case AE_CODE_AML:
 
 		if (sub_status <= AE_CODE_AML_MAX) {
 			exception = acpi_gbl_exception_names_aml [sub_status -1];
-			break;
 		}
-		goto unknown;
+		break;
 
 	case AE_CODE_CONTROL:
 
 		if (sub_status <= AE_CODE_CTRL_MAX) {
 			exception = acpi_gbl_exception_names_ctrl [sub_status -1];
-			break;
 		}
-		goto unknown;
+		break;
 
 	default:
-		goto unknown;
+		break;
 	}
 
+	if (!exception) {
+		/* Exception code was not recognized */
 
-	return ((const char *) exception);
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"Unknown exception code: 0x%8.8X\n", status));
 
-unknown:
+		return ((const char *) "UNKNOWN_STATUS_CODE");
+	}
 
-	ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown exception code: 0x%8.8X\n", status));
 	return ((const char *) exception);
 }
 
 
-/******************************************************************************
+/*******************************************************************************
  *
  * Static global variable initialization.
  *
@@ -212,13 +210,12 @@ const char                          *acp
 };
 
 
-/******************************************************************************
+/*******************************************************************************
  *
  * Namespace globals
  *
  ******************************************************************************/
 
-
 /*
  * Predefined ACPI Names (Built-in to the Interpreter)
  *
@@ -241,9 +238,11 @@ const struct acpi_predefined_names      
 #if !defined (ACPI_NO_METHOD_EXECUTION) || defined (ACPI_CONSTANT_EVAL_ONLY)
 	{"_OSI",    ACPI_TYPE_METHOD,           (char *) 1},
 #endif
-	{NULL,      ACPI_TYPE_ANY,              NULL}              /* Table terminator */
-};
 
+	/* Table terminator */
+
+	{NULL,      ACPI_TYPE_ANY,              NULL}
+};
 
 /*
  * Properties of the ACPI Object Types, both internal and external.
@@ -288,22 +287,25 @@ const u8                                
 /* Hex to ASCII conversion table */
 
 static const char                   acpi_gbl_hex_to_ascii[] =
-			  {'0','1','2','3','4','5','6','7',
-					 '8','9','A','B','C','D','E','F'};
+{
+	'0','1','2','3','4','5','6','7',
+	'8','9','A','B','C','D','E','F'
+};
+
 
-/*****************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    acpi_ut_hex_to_ascii_char
  *
  * PARAMETERS:  Integer             - Contains the hex digit
  *              Position            - bit position of the digit within the
- *                                    integer
+ *                                    integer (multiple of 4)
  *
- * RETURN:      Ascii character
+ * RETURN:      The converted Ascii character
  *
- * DESCRIPTION: Convert a hex digit to an ascii character
+ * DESCRIPTION: Convert a hex digit to an Ascii character
  *
- ****************************************************************************/
+ ******************************************************************************/
 
 char
 acpi_ut_hex_to_ascii_char (
@@ -315,7 +317,7 @@ acpi_ut_hex_to_ascii_char (
 }
 
 
-/******************************************************************************
+/*******************************************************************************
  *
  * Table name globals
  *
@@ -324,7 +326,7 @@ acpi_ut_hex_to_ascii_char (
  * that are not used by the subsystem are simply ignored.
  *
  * Do NOT add any table to this list that is not consumed directly by this
- * subsystem.
+ * subsystem (No MADT, ECDT, SBST, etc.)
  *
  ******************************************************************************/
 
@@ -391,7 +393,7 @@ struct acpi_fixed_event_info        acpi
 	/* ACPI_EVENT_RTC           */  {ACPI_BITREG_RT_CLOCK_STATUS,       ACPI_BITREG_RT_CLOCK_ENABLE,     ACPI_BITMASK_RT_CLOCK_STATUS,       ACPI_BITMASK_RT_CLOCK_ENABLE},
 };
 
-/*****************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    acpi_ut_get_region_name
  *
@@ -401,7 +403,7 @@ struct acpi_fixed_event_info        acpi
  *
  * DESCRIPTION: Translate a Space ID into a name string (Debug only)
  *
- ****************************************************************************/
+ ******************************************************************************/
 
 /* Region type decoding */
 
@@ -429,7 +431,6 @@ acpi_ut_get_region_name (
 	{
 		return ("user_defined_region");
 	}
-
 	else if (space_id >= ACPI_NUM_PREDEFINED_REGIONS)
 	{
 		return ("invalid_space_id");
@@ -439,7 +440,7 @@ acpi_ut_get_region_name (
 }
 
 
-/*****************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    acpi_ut_get_event_name
  *
@@ -449,7 +450,7 @@ acpi_ut_get_region_name (
  *
  * DESCRIPTION: Translate a Event ID into a name string (Debug only)
  *
- ****************************************************************************/
+ ******************************************************************************/
 
 /* Event type decoding */
 
@@ -477,7 +478,7 @@ acpi_ut_get_event_name (
 }
 
 
-/*****************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    acpi_ut_get_type_name
  *
@@ -487,20 +488,21 @@ acpi_ut_get_event_name (
  *
  * DESCRIPTION: Translate a Type ID into a name string (Debug only)
  *
- ****************************************************************************/
+ ******************************************************************************/
 
 /*
  * Elements of acpi_gbl_ns_type_names below must match
  * one-to-one with values of acpi_object_type
  *
- * The type ACPI_TYPE_ANY (Untyped) is used as a "don't care" when searching; when
- * stored in a table it really means that we have thus far seen no evidence to
- * indicate what type is actually going to be stored for this entry.
+ * The type ACPI_TYPE_ANY (Untyped) is used as a "don't care" when searching;
+ * when stored in a table it really means that we have thus far seen no
+ * evidence to indicate what type is actually going to be stored for this entry.
  */
 static const char                   acpi_gbl_bad_type[] = "UNDEFINED";
-#define TYPE_NAME_LENGTH    12                           /* Maximum length of each string */
 
-static const char                   *acpi_gbl_ns_type_names[] = /* printable names of ACPI types */
+/* Printable names of the ACPI object types */
+
+static const char                   *acpi_gbl_ns_type_names[] =
 {
 	/* 00 */ "Untyped",
 	/* 01 */ "Integer",
@@ -564,7 +566,7 @@ acpi_ut_get_object_type_name (
 }
 
 
-/*****************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    acpi_ut_get_node_name
  *
@@ -574,7 +576,7 @@ acpi_ut_get_object_type_name (
  *
  * DESCRIPTION: Validate the node and return the node's ACPI name.
  *
- ****************************************************************************/
+ ******************************************************************************/
 
 char *
 acpi_ut_get_node_name (
@@ -618,7 +620,7 @@ acpi_ut_get_node_name (
 }
 
 
-/*****************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    acpi_ut_get_descriptor_name
  *
@@ -628,9 +630,11 @@ acpi_ut_get_node_name (
  *
  * DESCRIPTION: Validate object and return the descriptor type
  *
- ****************************************************************************/
+ ******************************************************************************/
+
+/* Printable names of object descriptor types */
 
-static const char                   *acpi_gbl_desc_type_names[] = /* printable names of descriptor types */
+static const char                   *acpi_gbl_desc_type_names[] =
 {
 	/* 00 */ "Invalid",
 	/* 01 */ "Cached",
@@ -676,17 +680,18 @@ acpi_ut_get_descriptor_name (
  * Strings and procedures used for debug only
  */
 
-/*****************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    acpi_ut_get_mutex_name
  *
- * PARAMETERS:  None.
+ * PARAMETERS:  mutex_id        - The predefined ID for this mutex.
  *
- * RETURN:      Status
+ * RETURN:      String containing the name of the mutex. Always returns a valid
+ *              pointer.
  *
  * DESCRIPTION: Translate a mutex ID into a name string (Debug only)
  *
- ****************************************************************************/
+ ******************************************************************************/
 
 char *
 acpi_ut_get_mutex_name (
@@ -700,21 +705,20 @@ acpi_ut_get_mutex_name (
 
 	return (acpi_gbl_mutex_names[mutex_id]);
 }
-
 #endif
 
 
-/*****************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    acpi_ut_valid_object_type
  *
  * PARAMETERS:  Type            - Object type to be validated
  *
- * RETURN:      TRUE if valid object type
+ * RETURN:      TRUE if valid object type, FALSE otherwise
  *
  * DESCRIPTION: Validate an object type
  *
- ****************************************************************************/
+ ******************************************************************************/
 
 u8
 acpi_ut_valid_object_type (
@@ -732,7 +736,7 @@ acpi_ut_valid_object_type (
 }
 
 
-/****************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    acpi_ut_allocate_owner_id
  *
@@ -740,7 +744,10 @@ acpi_ut_valid_object_type (
  *
  * DESCRIPTION: Allocate a table or method owner id
  *
- ***************************************************************************/
+ * NOTE: this algorithm has a wraparound problem at 64_k method invocations, and
+ *       should be revisited (TBD)
+ *
+ ******************************************************************************/
 
 acpi_owner_id
 acpi_ut_allocate_owner_id (
@@ -796,16 +803,18 @@ acpi_ut_allocate_owner_id (
 }
 
 
-/****************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    acpi_ut_init_globals
  *
- * PARAMETERS:  none
+ * PARAMETERS:  None
+ *
+ * RETURN:      None
  *
  * DESCRIPTION: Init library globals.  All globals that require specific
  *              initialization should be initialized here!
  *
- ***************************************************************************/
+ ******************************************************************************/
 
 void
 acpi_ut_init_globals (
diff --git a/drivers/acpi/utilities/utinit.c b/drivers/acpi/utilities/utinit.c
--- a/drivers/acpi/utilities/utinit.c
+++ b/drivers/acpi/utilities/utinit.c
@@ -49,19 +49,29 @@
 #define _COMPONENT          ACPI_UTILITIES
 	 ACPI_MODULE_NAME    ("utinit")
 
+/* Local prototypes */
+
+static void
+acpi_ut_fadt_register_error (
+	char                            *register_name,
+	u32                             value,
+	acpi_size                       offset);
+
+static void acpi_ut_terminate (
+	void);
+
 
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ut_fadt_register_error
  *
- * PARAMETERS:  *register_name          - Pointer to string identifying register
+ * PARAMETERS:  register_name           - Pointer to string identifying register
  *              Value                   - Actual register contents value
- *              acpi_test_spec_section  - TDS section containing assertion
- *              acpi_assertion          - Assertion number being tested
+ *              Offset                  - Byte offset in the FADT
  *
  * RETURN:      AE_BAD_VALUE
  *
- * DESCRIPTION: Display failure message and link failure to TDS assertion
+ * DESCRIPTION: Display failure message
  *
  ******************************************************************************/
 
@@ -166,12 +176,13 @@ acpi_ut_validate_fadt (
  *
  * RETURN:      none
  *
- * DESCRIPTION: free global memory
+ * DESCRIPTION: Free global memory
  *
  ******************************************************************************/
 
-void
-acpi_ut_terminate (void)
+static void
+acpi_ut_terminate (
+	void)
 {
 	struct acpi_gpe_block_info      *gpe_block;
 	struct acpi_gpe_block_info      *next_gpe_block;
@@ -183,8 +194,6 @@ acpi_ut_terminate (void)
 
 
 	/* Free global tables, etc. */
-
-
 	/* Free global GPE blocks and related info structures */
 
 	gpe_xrupt_info = acpi_gbl_gpe_xrupt_list_head;
@@ -221,7 +230,8 @@ acpi_ut_terminate (void)
  ******************************************************************************/
 
 void
-acpi_ut_subsystem_shutdown (void)
+acpi_ut_subsystem_shutdown (
+	void)
 {
 
 	ACPI_FUNCTION_TRACE ("ut_subsystem_shutdown");
@@ -229,14 +239,16 @@ acpi_ut_subsystem_shutdown (void)
 	/* Just exit if subsystem is already shutdown */
 
 	if (acpi_gbl_shutdown) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "ACPI Subsystem is already terminated\n"));
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"ACPI Subsystem is already terminated\n"));
 		return_VOID;
 	}
 
 	/* Subsystem appears active, go ahead and shut it down */
 
 	acpi_gbl_shutdown = TRUE;
-	ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Shutting down ACPI Subsystem...\n"));
+	ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+		"Shutting down ACPI Subsystem...\n"));
 
 	/* Close the acpi_event Handling */
 
diff --git a/drivers/acpi/utilities/utmath.c b/drivers/acpi/utilities/utmath.c
--- a/drivers/acpi/utilities/utmath.c
+++ b/drivers/acpi/utilities/utmath.c
@@ -259,6 +259,8 @@ acpi_ut_divide (
  *
  * FUNCTION:    acpi_ut_short_divide, acpi_ut_divide
  *
+ * PARAMETERS:  See function headers above
+ *
  * DESCRIPTION: Native versions of the ut_divide functions. Use these if either
  *              1) The target is a 64-bit platform and therefore 64-bit
  *                 integer math is supported directly by the machine.
diff --git a/drivers/acpi/utilities/utmisc.c b/drivers/acpi/utilities/utmisc.c
--- a/drivers/acpi/utilities/utmisc.c
+++ b/drivers/acpi/utilities/utmisc.c
@@ -49,12 +49,57 @@
 #define _COMPONENT          ACPI_UTILITIES
 	 ACPI_MODULE_NAME    ("utmisc")
 
+/* Local prototypes */
+
+static acpi_status
+acpi_ut_create_mutex (
+	acpi_mutex_handle               mutex_id);
+
+static acpi_status
+acpi_ut_delete_mutex (
+	acpi_mutex_handle               mutex_id);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_strupr (strupr)
+ *
+ * PARAMETERS:  src_string      - The source string to convert
+ *
+ * RETURN:      Converted src_string (same as input pointer)
+ *
+ * DESCRIPTION: Convert string to uppercase
+ *
+ * NOTE: This is not a POSIX function, so it appears here, not in utclib.c
+ *
+ ******************************************************************************/
+
+char *
+acpi_ut_strupr (
+	char                            *src_string)
+{
+	char                            *string;
+
+
+	ACPI_FUNCTION_ENTRY ();
+
+
+	/* Walk entire string, uppercasing the letters */
+
+	for (string = src_string; *string; string++) {
+		*string = (char) ACPI_TOUPPER (*string);
+	}
+
+	return (src_string);
+}
+
 
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ut_print_string
  *
  * PARAMETERS:  String          - Null terminated ASCII string
+ *              max_length      - Maximum output length
  *
  * RETURN:      None
  *
@@ -148,6 +193,8 @@ acpi_ut_print_string (
  *
  * PARAMETERS:  Value           - Value to be converted
  *
+ * RETURN:      u32 integer with bytes swapped
+ *
  * DESCRIPTION: Convert a 32-bit value to big-endian (swap the bytes)
  *
  ******************************************************************************/
@@ -160,7 +207,6 @@ acpi_ut_dword_byte_swap (
 		u32                         value;
 		u8                          bytes[4];
 	} out;
-
 	union {
 		u32                         value;
 		u8                          bytes[4];
@@ -219,7 +265,8 @@ acpi_ut_set_integer_width (
  *
  * FUNCTION:    acpi_ut_display_init_pathname
  *
- * PARAMETERS:  obj_handle          - Handle whose pathname will be displayed
+ * PARAMETERS:  Type                - Object type of the node
+ *              obj_handle          - Handle whose pathname will be displayed
  *              Path                - Additional path string to be appended.
  *                                      (NULL if no extra path)
  *
@@ -270,7 +317,8 @@ acpi_ut_display_init_pathname (
 
 	/* Print the object type and pathname */
 
-	acpi_os_printf ("%-12s %s", acpi_ut_get_type_name (type), (char *) buffer.pointer);
+	acpi_os_printf ("%-12s %s",
+		acpi_ut_get_type_name (type), (char *) buffer.pointer);
 
 	/* Extra path is used to append names like _STA, _INI, etc. */
 
@@ -288,9 +336,9 @@ acpi_ut_display_init_pathname (
  *
  * FUNCTION:    acpi_ut_valid_acpi_name
  *
- * PARAMETERS:  Character           - The character to be examined
+ * PARAMETERS:  Name            - The name to be examined
  *
- * RETURN:      1 if Character may appear in a name, else 0
+ * RETURN:      TRUE if the name is valid, FALSE otherwise
  *
  * DESCRIPTION: Check for a valid ACPI name.  Each character must be one of:
  *              1) Upper case alpha
@@ -495,40 +543,6 @@ error_exit:
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_ut_strupr
- *
- * PARAMETERS:  src_string      - The source string to convert to
- *
- * RETURN:      src_string
- *
- * DESCRIPTION: Convert string to uppercase
- *
- ******************************************************************************/
-#ifdef ACPI_FUTURE_USAGE
-char *
-acpi_ut_strupr (
-	char                            *src_string)
-{
-	char                            *string;
-
-
-	ACPI_FUNCTION_ENTRY ();
-
-
-	/* Walk entire string, uppercasing the letters */
-
-	for (string = src_string; *string; ) {
-		*string = (char) ACPI_TOUPPER (*string);
-		string++;
-	}
-
-	return (src_string);
-}
-#endif  /*  ACPI_FUTURE_USAGE  */
-
-
-/*******************************************************************************
- *
  * FUNCTION:    acpi_ut_mutex_initialize
  *
  * PARAMETERS:  None.
@@ -611,7 +625,7 @@ acpi_ut_mutex_terminate (
  *
  ******************************************************************************/
 
-acpi_status
+static acpi_status
 acpi_ut_create_mutex (
 	acpi_mutex_handle               mutex_id)
 {
@@ -648,7 +662,7 @@ acpi_ut_create_mutex (
  *
  ******************************************************************************/
 
-acpi_status
+static acpi_status
 acpi_ut_delete_mutex (
 	acpi_mutex_handle               mutex_id)
 {
@@ -715,16 +729,16 @@ acpi_ut_acquire_mutex (
 			if (acpi_gbl_mutex_info[i].owner_id == this_thread_id) {
 				if (i == mutex_id) {
 					ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
-							"Mutex [%s] already acquired by this thread [%X]\n",
-							acpi_ut_get_mutex_name (mutex_id), this_thread_id));
+						"Mutex [%s] already acquired by this thread [%X]\n",
+						acpi_ut_get_mutex_name (mutex_id), this_thread_id));
 
 					return (AE_ALREADY_ACQUIRED);
 				}
 
 				ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
-						"Invalid acquire order: Thread %X owns [%s], wants [%s]\n",
-						this_thread_id, acpi_ut_get_mutex_name (i),
-						acpi_ut_get_mutex_name (mutex_id)));
+					"Invalid acquire order: Thread %X owns [%s], wants [%s]\n",
+					this_thread_id, acpi_ut_get_mutex_name (i),
+					acpi_ut_get_mutex_name (mutex_id)));
 
 				return (AE_ACQUIRE_DEADLOCK);
 			}
@@ -733,22 +747,23 @@ acpi_ut_acquire_mutex (
 #endif
 
 	ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX,
-			 "Thread %X attempting to acquire Mutex [%s]\n",
-			 this_thread_id, acpi_ut_get_mutex_name (mutex_id)));
+		"Thread %X attempting to acquire Mutex [%s]\n",
+		this_thread_id, acpi_ut_get_mutex_name (mutex_id)));
 
 	status = acpi_os_wait_semaphore (acpi_gbl_mutex_info[mutex_id].mutex,
 			   1, ACPI_WAIT_FOREVER);
 	if (ACPI_SUCCESS (status)) {
 		ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Thread %X acquired Mutex [%s]\n",
-				 this_thread_id, acpi_ut_get_mutex_name (mutex_id)));
+			this_thread_id, acpi_ut_get_mutex_name (mutex_id)));
 
 		acpi_gbl_mutex_info[mutex_id].use_count++;
 		acpi_gbl_mutex_info[mutex_id].owner_id = this_thread_id;
 	}
 	else {
-		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Thread %X could not acquire Mutex [%s] %s\n",
-				 this_thread_id, acpi_ut_get_mutex_name (mutex_id),
-				 acpi_format_exception (status)));
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"Thread %X could not acquire Mutex [%s] %s\n",
+				this_thread_id, acpi_ut_get_mutex_name (mutex_id),
+				acpi_format_exception (status)));
 	}
 
 	return (status);
@@ -793,8 +808,8 @@ acpi_ut_release_mutex (
 	 */
 	if (acpi_gbl_mutex_info[mutex_id].owner_id == ACPI_MUTEX_NOT_ACQUIRED) {
 		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
-				"Mutex [%s] is not acquired, cannot release\n",
-				acpi_ut_get_mutex_name (mutex_id)));
+			"Mutex [%s] is not acquired, cannot release\n",
+			acpi_ut_get_mutex_name (mutex_id)));
 
 		return (AE_NOT_ACQUIRED);
 	}
@@ -812,8 +827,8 @@ acpi_ut_release_mutex (
 			}
 
 			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
-					"Invalid release order: owns [%s], releasing [%s]\n",
-					acpi_ut_get_mutex_name (i), acpi_ut_get_mutex_name (mutex_id)));
+				"Invalid release order: owns [%s], releasing [%s]\n",
+				acpi_ut_get_mutex_name (i), acpi_ut_get_mutex_name (mutex_id)));
 
 			return (AE_RELEASE_DEADLOCK);
 		}
@@ -826,13 +841,14 @@ acpi_ut_release_mutex (
 	status = acpi_os_signal_semaphore (acpi_gbl_mutex_info[mutex_id].mutex, 1);
 
 	if (ACPI_FAILURE (status)) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Thread %X could not release Mutex [%s] %s\n",
-				 this_thread_id, acpi_ut_get_mutex_name (mutex_id),
-				 acpi_format_exception (status)));
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"Thread %X could not release Mutex [%s] %s\n",
+			this_thread_id, acpi_ut_get_mutex_name (mutex_id),
+			acpi_format_exception (status)));
 	}
 	else {
 		ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Thread %X released Mutex [%s]\n",
-				 this_thread_id, acpi_ut_get_mutex_name (mutex_id)));
+			this_thread_id, acpi_ut_get_mutex_name (mutex_id)));
 	}
 
 	return (status);
@@ -843,11 +859,11 @@ acpi_ut_release_mutex (
  *
  * FUNCTION:    acpi_ut_create_update_state_and_push
  *
- * PARAMETERS:  *Object         - Object to be added to the new state
+ * PARAMETERS:  Object          - Object to be added to the new state
  *              Action          - Increment/Decrement
  *              state_list      - List the state will be added to
  *
- * RETURN:      None
+ * RETURN:      Status
  *
  * DESCRIPTION: Create a new state and push it
  *
@@ -885,15 +901,16 @@ acpi_ut_create_update_state_and_push (
  *
  * FUNCTION:    acpi_ut_create_pkg_state_and_push
  *
- * PARAMETERS:  *Object         - Object to be added to the new state
+ * PARAMETERS:  Object          - Object to be added to the new state
  *              Action          - Increment/Decrement
  *              state_list      - List the state will be added to
  *
- * RETURN:      None
+ * RETURN:      Status
  *
  * DESCRIPTION: Create a new state and push it
  *
  ******************************************************************************/
+
 #ifdef ACPI_FUTURE_USAGE
 acpi_status
 acpi_ut_create_pkg_state_and_push (
@@ -925,7 +942,7 @@ acpi_ut_create_pkg_state_and_push (
  * PARAMETERS:  list_head           - Head of the state stack
  *              State               - State object to push
  *
- * RETURN:      Status
+ * RETURN:      None
  *
  * DESCRIPTION: Push a state object onto a state stack
  *
@@ -954,7 +971,7 @@ acpi_ut_push_generic_state (
  *
  * PARAMETERS:  list_head           - Head of the state stack
  *
- * RETURN:      Status
+ * RETURN:      The popped state object
  *
  * DESCRIPTION: Pop a state object from a state stack
  *
@@ -989,7 +1006,7 @@ acpi_ut_pop_generic_state (
  *
  * PARAMETERS:  None
  *
- * RETURN:      Status
+ * RETURN:      The new state object. NULL on failure.
  *
  * DESCRIPTION: Create a generic state object.  Attempt to obtain one from
  *              the global state cache;  If none available, create a new one.
@@ -997,7 +1014,8 @@ acpi_ut_pop_generic_state (
  ******************************************************************************/
 
 union acpi_generic_state *
-acpi_ut_create_generic_state (void)
+acpi_ut_create_generic_state (
+	void)
 {
 	union acpi_generic_state        *state;
 
@@ -1023,7 +1041,7 @@ acpi_ut_create_generic_state (void)
  *
  * PARAMETERS:  None
  *
- * RETURN:      Thread State
+ * RETURN:      New Thread State. NULL on failure
  *
  * DESCRIPTION: Create a "Thread State" - a flavor of the generic state used
  *              to track per-thread info during method execution
@@ -1060,11 +1078,10 @@ acpi_ut_create_thread_state (
  *
  * FUNCTION:    acpi_ut_create_update_state
  *
- * PARAMETERS:  Object              - Initial Object to be installed in the
- *                                    state
- *              Action              - Update action to be performed
+ * PARAMETERS:  Object          - Initial Object to be installed in the state
+ *              Action          - Update action to be performed
  *
- * RETURN:      Status
+ * RETURN:      New state object, null on failure
  *
  * DESCRIPTION: Create an "Update State" - a flavor of the generic state used
  *              to update reference counts and delete complex objects such
@@ -1104,11 +1121,10 @@ acpi_ut_create_update_state (
  *
  * FUNCTION:    acpi_ut_create_pkg_state
  *
- * PARAMETERS:  Object              - Initial Object to be installed in the
- *                                    state
- *              Action              - Update action to be performed
+ * PARAMETERS:  Object          - Initial Object to be installed in the state
+ *              Action          - Update action to be performed
  *
- * RETURN:      Status
+ * RETURN:      New state object, null on failure
  *
  * DESCRIPTION: Create a "Package State"
  *
@@ -1151,7 +1167,7 @@ acpi_ut_create_pkg_state (
  *
  * PARAMETERS:  None
  *
- * RETURN:      Status
+ * RETURN:      New state object, null on failure
  *
  * DESCRIPTION: Create a "Control State" - a flavor of the generic state used
  *              to support nested IF/WHILE constructs in the AML.
@@ -1190,7 +1206,7 @@ acpi_ut_create_control_state (
  *
  * PARAMETERS:  State               - The state object to be deleted
  *
- * RETURN:      Status
+ * RETURN:      None
  *
  * DESCRIPTION: Put a state object back into the global state cache.  The object
  *              is not actually freed at this time.
@@ -1216,7 +1232,7 @@ acpi_ut_delete_generic_state (
  *
  * PARAMETERS:  None
  *
- * RETURN:      Status
+ * RETURN:      None
  *
  * DESCRIPTION: Purge the global state object cache.  Used during subsystem
  *              termination.
@@ -1240,7 +1256,10 @@ acpi_ut_delete_generic_state_cache (
  *
  * FUNCTION:    acpi_ut_walk_package_tree
  *
- * PARAMETERS:  obj_desc        - The Package object on which to resolve refs
+ * PARAMETERS:  source_object       - The package to walk
+ *              target_object       - Target object (if package is being copied)
+ *              walk_callback       - Called once for each package element
+ *              Context             - Passed to the callback function
  *
  * RETURN:      Status
  *
@@ -1359,7 +1378,7 @@ acpi_ut_walk_package_tree (
  * PARAMETERS:  Buffer          - Buffer to be scanned
  *              Length          - number of bytes to examine
  *
- * RETURN:      checksum
+ * RETURN:      The generated checksum
  *
  * DESCRIPTION: Generate a checksum on a raw buffer
  *
@@ -1442,7 +1461,6 @@ acpi_ut_get_resource_end_tag (
  * PARAMETERS:  module_name         - Caller's module name (for error output)
  *              line_number         - Caller's line number (for error output)
  *              component_id        - Caller's component ID (for error output)
- *              Message             - Error message to use on failure
  *
  * RETURN:      None
  *
@@ -1457,7 +1475,6 @@ acpi_ut_report_error (
 	u32                             component_id)
 {
 
-
 	acpi_os_printf ("%8s-%04d: *** Error: ", module_name, line_number);
 }
 
@@ -1469,7 +1486,6 @@ acpi_ut_report_error (
  * PARAMETERS:  module_name         - Caller's module name (for error output)
  *              line_number         - Caller's line number (for error output)
  *              component_id        - Caller's component ID (for error output)
- *              Message             - Error message to use on failure
  *
  * RETURN:      None
  *
@@ -1495,7 +1511,6 @@ acpi_ut_report_warning (
  * PARAMETERS:  module_name         - Caller's module name (for error output)
  *              line_number         - Caller's line number (for error output)
  *              component_id        - Caller's component ID (for error output)
- *              Message             - Error message to use on failure
  *
  * RETURN:      None
  *
diff --git a/drivers/acpi/utilities/utobject.c b/drivers/acpi/utilities/utobject.c
--- a/drivers/acpi/utilities/utobject.c
+++ b/drivers/acpi/utilities/utobject.c
@@ -50,6 +50,25 @@
 #define _COMPONENT          ACPI_UTILITIES
 	 ACPI_MODULE_NAME    ("utobject")
 
+/* Local prototypes */
+
+static acpi_status
+acpi_ut_get_simple_object_size (
+	union acpi_operand_object       *obj,
+	acpi_size                       *obj_length);
+
+static acpi_status
+acpi_ut_get_package_object_size (
+	union acpi_operand_object       *obj,
+	acpi_size                       *obj_length);
+
+static acpi_status
+acpi_ut_get_element_length (
+	u8                              object_type,
+	union acpi_operand_object       *source_object,
+	union acpi_generic_state        *state,
+	void                            *context);
+
 
 /*******************************************************************************
  *
@@ -60,7 +79,7 @@
  *              component_id        - Component type of caller
  *              Type                - ACPI Type of the new object
  *
- * RETURN:      Object              - The new object.  Null on failure
+ * RETURN:      A new internal object, null on failure
  *
  * DESCRIPTION: Create and initialize a new internal object.
  *
@@ -83,7 +102,8 @@ acpi_ut_create_internal_object_dbg (
 	union acpi_operand_object       *second_object;
 
 
-	ACPI_FUNCTION_TRACE_STR ("ut_create_internal_object_dbg", acpi_ut_get_type_name (type));
+	ACPI_FUNCTION_TRACE_STR ("ut_create_internal_object_dbg",
+		acpi_ut_get_type_name (type));
 
 
 	/* Allocate the raw object descriptor */
@@ -99,7 +119,8 @@ acpi_ut_create_internal_object_dbg (
 
 		/* These types require a secondary object */
 
-		second_object = acpi_ut_allocate_object_desc_dbg (module_name, line_number, component_id);
+		second_object = acpi_ut_allocate_object_desc_dbg (module_name,
+				   line_number, component_id);
 		if (!second_object) {
 			acpi_ut_delete_object_desc (object);
 			return_PTR (NULL);
@@ -138,7 +159,7 @@ acpi_ut_create_internal_object_dbg (
  *
  * PARAMETERS:  buffer_size            - Size of buffer to be created
  *
- * RETURN:      Pointer to a new Buffer object
+ * RETURN:      Pointer to a new Buffer object, null on failure
  *
  * DESCRIPTION: Create a fully initialized buffer object
  *
@@ -192,9 +213,9 @@ acpi_ut_create_buffer_object (
  *
  * FUNCTION:    acpi_ut_create_string_object
  *
- * PARAMETERS:  string_size            - Size of string to be created.  Does not
- *                                       include NULL terminator, this is added
- *                                       automatically.
+ * PARAMETERS:  string_size         - Size of string to be created. Does not
+ *                                    include NULL terminator, this is added
+ *                                    automatically.
  *
  * RETURN:      Pointer to a new String object
  *
@@ -249,7 +270,9 @@ acpi_ut_create_string_object (
  *
  * PARAMETERS:  Object              - Object to be validated
  *
- * RETURN:      Validate a pointer to be an union acpi_operand_object
+ * RETURN:      TRUE if object is valid, FALSE otherwise
+ *
+ * DESCRIPTION: Validate a pointer to be an union acpi_operand_object
  *
  ******************************************************************************/
 
@@ -399,8 +422,8 @@ acpi_ut_delete_object_cache (
  *
  * FUNCTION:    acpi_ut_get_simple_object_size
  *
- * PARAMETERS:  *internal_object    - Pointer to the object we are examining
- *              *obj_length         - Where the length is returned
+ * PARAMETERS:  internal_object    - An ACPI operand object
+ *              obj_length         - Where the length is returned
  *
  * RETURN:      Status
  *
@@ -412,7 +435,7 @@ acpi_ut_delete_object_cache (
  *
  ******************************************************************************/
 
-acpi_status
+static acpi_status
 acpi_ut_get_simple_object_size (
 	union acpi_operand_object       *internal_object,
 	acpi_size                       *obj_length)
@@ -424,8 +447,10 @@ acpi_ut_get_simple_object_size (
 	ACPI_FUNCTION_TRACE_PTR ("ut_get_simple_object_size", internal_object);
 
 
-	/* Handle a null object (Could be a uninitialized package element -- which is legal) */
-
+	/*
+	 * Handle a null object (Could be a uninitialized package
+	 * element -- which is legal)
+	 */
 	if (!internal_object) {
 		*obj_length = 0;
 		return_ACPI_STATUS (AE_OK);
@@ -480,7 +505,8 @@ acpi_ut_get_simple_object_size (
 			 * Get the actual length of the full pathname to this object.
 			 * The reference will be converted to the pathname to the object
 			 */
-			length += ACPI_ROUND_UP_TO_NATIVE_WORD (acpi_ns_get_pathname_length (internal_object->reference.node));
+			length += ACPI_ROUND_UP_TO_NATIVE_WORD (
+					 acpi_ns_get_pathname_length (internal_object->reference.node));
 			break;
 
 		default:
@@ -530,7 +556,7 @@ acpi_ut_get_simple_object_size (
  *
  ******************************************************************************/
 
-acpi_status
+static acpi_status
 acpi_ut_get_element_length (
 	u8                              object_type,
 	union acpi_operand_object       *source_object,
@@ -582,8 +608,8 @@ acpi_ut_get_element_length (
  *
  * FUNCTION:    acpi_ut_get_package_object_size
  *
- * PARAMETERS:  *internal_object    - Pointer to the object we are examining
- *              *obj_length         - Where the length is returned
+ * PARAMETERS:  internal_object     - An ACPI internal object
+ *              obj_length          - Where the length is returned
  *
  * RETURN:      Status
  *
@@ -595,7 +621,7 @@ acpi_ut_get_element_length (
  *
  ******************************************************************************/
 
-acpi_status
+static acpi_status
 acpi_ut_get_package_object_size (
 	union acpi_operand_object       *internal_object,
 	acpi_size                       *obj_length)
@@ -636,8 +662,8 @@ acpi_ut_get_package_object_size (
  *
  * FUNCTION:    acpi_ut_get_object_size
  *
- * PARAMETERS:  *internal_object    - Pointer to the object we are examining
- *              *obj_length         - Where the length will be returned
+ * PARAMETERS:  internal_object     - An ACPI internal object
+ *              obj_length          - Where the length will be returned
  *
  * RETURN:      Status
  *
@@ -647,7 +673,7 @@ acpi_ut_get_package_object_size (
  ******************************************************************************/
 
 acpi_status
-acpi_ut_get_object_size(
+acpi_ut_get_object_size (
 	union acpi_operand_object       *internal_object,
 	acpi_size                       *obj_length)
 {
diff --git a/drivers/acpi/utilities/utxface.c b/drivers/acpi/utilities/utxface.c
--- a/drivers/acpi/utilities/utxface.c
+++ b/drivers/acpi/utilities/utxface.c
@@ -73,6 +73,7 @@ acpi_initialize_subsystem (
 {
 	acpi_status                     status;
 
+
 	ACPI_FUNCTION_TRACE ("acpi_initialize_subsystem");
 
 
@@ -105,7 +106,6 @@ acpi_initialize_subsystem (
 	 * Initialize the namespace manager and
 	 * the root of the namespace tree
 	 */
-
 	status = acpi_ns_root_initialize ();
 	if (ACPI_FAILURE (status)) {
 		ACPI_REPORT_ERROR (("Namespace initialization failure, %s\n",
@@ -113,7 +113,6 @@ acpi_initialize_subsystem (
 		return_ACPI_STATUS (status);
 	}
 
-
 	/* If configured, initialize the AML debugger */
 
 	ACPI_DEBUGGER_EXEC (status = acpi_db_initialize ());
@@ -150,7 +149,8 @@ acpi_enable_subsystem (
 	 * The values from the FADT are validated here.
 	 */
 	if (!(flags & ACPI_NO_HARDWARE_INIT)) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Initializing ACPI hardware\n"));
+		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+			"[Init] Initializing ACPI hardware\n"));
 
 		status = acpi_hw_initialize ();
 		if (ACPI_FAILURE (status)) {
@@ -178,7 +178,8 @@ acpi_enable_subsystem (
 	 * install_address_space_handler interface.
 	 */
 	if (!(flags & ACPI_NO_ADDRESS_SPACE_INIT)) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Installing default address space handlers\n"));
+		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+			"[Init] Installing default address space handlers\n"));
 
 		status = acpi_ev_install_region_handlers ();
 		if (ACPI_FAILURE (status)) {
@@ -189,12 +190,14 @@ acpi_enable_subsystem (
 	/*
 	 * Initialize ACPI Event handling (Fixed and General Purpose)
 	 *
-	 * NOTE: We must have the hardware AND events initialized before we can execute
-	 * ANY control methods SAFELY.  Any control method can require ACPI hardware
-	 * support, so the hardware MUST be initialized before execution!
+	 * NOTE: We must have the hardware AND events initialized before we can
+	 * execute ANY control methods SAFELY.  Any control method can require
+	 * ACPI hardware support, so the hardware MUST be initialized before
+	 * execution!
 	 */
 	if (!(flags & ACPI_NO_EVENT_INIT)) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Initializing ACPI events\n"));
+		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+			"[Init] Initializing ACPI events\n"));
 
 		status = acpi_ev_initialize_events ();
 		if (ACPI_FAILURE (status)) {
@@ -205,7 +208,8 @@ acpi_enable_subsystem (
 	/* Install the SCI handler and Global Lock handler */
 
 	if (!(flags & ACPI_NO_HANDLER_INIT)) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Installing SCI/GL handlers\n"));
+		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+			"[Init] Installing SCI/GL handlers\n"));
 
 		status = acpi_ev_install_xrupt_handlers ();
 		if (ACPI_FAILURE (status)) {
@@ -247,7 +251,8 @@ acpi_initialize_objects (
 	 * contain executable AML (see call to acpi_ns_initialize_objects below).
 	 */
 	if (!(flags & ACPI_NO_ADDRESS_SPACE_INIT)) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Executing _REG op_region methods\n"));
+		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+			"[Init] Executing _REG op_region methods\n"));
 
 		status = acpi_ev_initialize_op_regions ();
 		if (ACPI_FAILURE (status)) {
@@ -261,7 +266,8 @@ acpi_initialize_objects (
 	 * objects: operation_regions, buffer_fields, Buffers, and Packages.
 	 */
 	if (!(flags & ACPI_NO_OBJECT_INIT)) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Completing Initialization of ACPI Objects\n"));
+		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+			"[Init] Completing Initialization of ACPI Objects\n"));
 
 		status = acpi_ns_initialize_objects ();
 		if (ACPI_FAILURE (status)) {
@@ -274,7 +280,8 @@ acpi_initialize_objects (
 	 * This runs the _STA and _INI methods.
 	 */
 	if (!(flags & ACPI_NO_DEVICE_INIT)) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Initializing ACPI Devices\n"));
+		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
+			"[Init] Initializing ACPI Devices\n"));
 
 		status = acpi_ns_initialize_devices ();
 		if (ACPI_FAILURE (status)) {
@@ -307,7 +314,8 @@ acpi_initialize_objects (
  ******************************************************************************/
 
 acpi_status
-acpi_terminate (void)
+acpi_terminate (
+	void)
 {
 	acpi_status                 status;
 
@@ -344,8 +352,7 @@ acpi_terminate (void)
 
 
 #ifdef ACPI_FUTURE_USAGE
-
-/*****************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    acpi_subsystem_status
  *
@@ -354,14 +361,16 @@ acpi_terminate (void)
  * RETURN:      Status of the ACPI subsystem
  *
  * DESCRIPTION: Other drivers that use the ACPI subsystem should call this
- *              before making any other calls, to ensure the subsystem initial-
- *              ized successfully.
+ *              before making any other calls, to ensure the subsystem
+ *              initialized successfully.
  *
- ****************************************************************************/
+ ******************************************************************************/
 
 acpi_status
-acpi_subsystem_status (void)
+acpi_subsystem_status (
+	void)
 {
+
 	if (acpi_gbl_startup_flags & ACPI_INITIALIZED_OK) {
 		return (AE_OK);
 	}
@@ -371,13 +380,12 @@ acpi_subsystem_status (void)
 }
 
 
-/******************************************************************************
+/*******************************************************************************
  *
  * FUNCTION:    acpi_get_system_info
  *
- * PARAMETERS:  out_buffer      - a pointer to a buffer to receive the
- *                                resources for the device
- *              buffer_length   - the number of bytes available in the buffer
+ * PARAMETERS:  out_buffer      - A buffer to receive the resources for the
+ *                                device
  *
  * RETURN:      Status          - the status of the call
  *
@@ -395,8 +403,8 @@ acpi_get_system_info (
 	struct acpi_buffer              *out_buffer)
 {
 	struct acpi_system_info         *info_ptr;
-	u32                             i;
 	acpi_status                     status;
+	u32                             i;
 
 
 	ACPI_FUNCTION_TRACE ("acpi_get_system_info");
@@ -466,6 +474,7 @@ EXPORT_SYMBOL(acpi_get_system_info);
  * FUNCTION:    acpi_install_initialization_handler
  *
  * PARAMETERS:  Handler             - Callback procedure
+ *              Function            - Not (currently) used, see below
  *
  * RETURN:      Status
  *
@@ -495,7 +504,6 @@ acpi_install_initialization_handler (
 
 #endif  /*  ACPI_FUTURE_USAGE  */
 
-
 /*****************************************************************************
  *
  * FUNCTION:    acpi_purge_cached_objects
@@ -509,7 +517,8 @@ acpi_install_initialization_handler (
  ****************************************************************************/
 
 acpi_status
-acpi_purge_cached_objects (void)
+acpi_purge_cached_objects (
+	void)
 {
 	ACPI_FUNCTION_TRACE ("acpi_purge_cached_objects");
 
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -564,12 +564,13 @@ acpi_video_device_find_cap (struct acpi_
 		int count = 0;
 		union acpi_object *o;
 		
-		br = kmalloc(sizeof &br, GFP_KERNEL);
+		br = kmalloc(sizeof(*br), GFP_KERNEL);
 		if (!br) {
 			printk(KERN_ERR "can't allocate memory\n");
 		} else {
-			memset(br, 0, sizeof &br);
-			br->levels = kmalloc(obj->package.count * sizeof &br->levels, GFP_KERNEL);
+			memset(br, 0, sizeof(*br));
+			br->levels = kmalloc(obj->package.count *
+					sizeof *(br->levels), GFP_KERNEL);
 			if (!br->levels)
 				goto out;
 
@@ -584,8 +585,7 @@ acpi_video_device_find_cap (struct acpi_
 			}
 out:
 			if (count < 2) {
-				if (br->levels)
-					kfree(br->levels);
+				kfree(br->levels);
 				kfree(br);
 			} else {
 				br->count = count;
@@ -595,8 +595,7 @@ out:
 		}
 	}
 
-	if (obj)
-		kfree(obj);
+	kfree(obj);
 
 	return_VOID;
 }
@@ -1585,7 +1584,7 @@ acpi_video_switch_output(
 	ACPI_FUNCTION_TRACE("acpi_video_switch_output");
 
 	list_for_each_safe(node, next, &video->video_device_list) {
-		struct acpi_video_device * dev = container_of(node, struct acpi_video_device, entry);
+		dev = container_of(node, struct acpi_video_device, entry);
 		status = acpi_video_device_get_state(dev, &state);
 		if (state & 0x2){
 			dev_next = container_of(node->next, struct acpi_video_device, entry);
diff --git a/drivers/atm/ambassador.c b/drivers/atm/ambassador.c
--- a/drivers/atm/ambassador.c
+++ b/drivers/atm/ambassador.c
@@ -794,7 +794,9 @@ static void drain_rx_pools (amb_dev * de
     drain_rx_pool (dev, pool);
 }
 
-static inline void fill_rx_pool (amb_dev * dev, unsigned char pool, int priority) {
+static inline void fill_rx_pool (amb_dev * dev, unsigned char pool,
+                                 unsigned int __nocast priority)
+{
   rx_in rx;
   amb_rxq * rxq;
   
diff --git a/drivers/atm/firestream.c b/drivers/atm/firestream.c
--- a/drivers/atm/firestream.c
+++ b/drivers/atm/firestream.c
@@ -1374,7 +1374,8 @@ static void reset_chip (struct fs_dev *d
 	}
 }
 
-static void __devinit *aligned_kmalloc (int size, int flags, int alignment)
+static void __devinit *aligned_kmalloc (int size, unsigned int __nocast flags,
+					int alignment)
 {
 	void  *t;
 
@@ -1464,7 +1465,8 @@ static inline int nr_buffers_in_freepool
    does. I've seen "receive abort: no buffers" and things started
    working again after that...  -- REW */
 
-static void top_off_fp (struct fs_dev *dev, struct freepool *fp, int gfp_flags)
+static void top_off_fp (struct fs_dev *dev, struct freepool *fp,
+			unsigned int __nocast gfp_flags)
 {
 	struct FS_BPENTRY *qe, *ne;
 	struct sk_buff *skb;
diff --git a/drivers/atm/he.c b/drivers/atm/he.c
--- a/drivers/atm/he.c
+++ b/drivers/atm/he.c
@@ -57,7 +57,6 @@
 
 #include <linux/config.h>
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/kernel.h>
 #include <linux/skbuff.h>
 #include <linux/pci.h>
diff --git a/drivers/atm/idt77252.c b/drivers/atm/idt77252.c
--- a/drivers/atm/idt77252.c
+++ b/drivers/atm/idt77252.c
@@ -46,6 +46,7 @@ static char const rcsid[] =
 #include <linux/init.h>
 #include <linux/bitops.h>
 #include <linux/wait.h>
+#include <linux/jiffies.h>
 #include <asm/semaphore.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
@@ -780,7 +781,7 @@ push_on_scq(struct idt77252_dev *card, s
 	return 0;
 
 out:
-	if (jiffies - scq->trans_start > HZ) {
+	if (time_after(jiffies, scq->trans_start + HZ)) {
 		printk("%s: Error pushing TBD for %d.%d\n",
 		       card->name, vc->tx_vcc->vpi, vc->tx_vcc->vci);
 #ifdef CONFIG_ATM_IDT77252_DEBUG
diff --git a/drivers/atm/zatm.c b/drivers/atm/zatm.c
--- a/drivers/atm/zatm.c
+++ b/drivers/atm/zatm.c
@@ -16,9 +16,9 @@
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
 #include <linux/delay.h>
-#include <linux/ioport.h> /* for request_region */
 #include <linux/uio.h>
 #include <linux/init.h>
+#include <linux/dma-mapping.h>
 #include <linux/atm_zatm.h>
 #include <linux/capability.h>
 #include <linux/bitops.h>
@@ -1257,22 +1257,22 @@ static int __init zatm_init(struct atm_d
 
 static int __init zatm_start(struct atm_dev *dev)
 {
-	struct zatm_dev *zatm_dev;
+	struct zatm_dev *zatm_dev = ZATM_DEV(dev);
+	struct pci_dev *pdev = zatm_dev->pci_dev;
 	unsigned long curr;
 	int pools,vccs,rx;
-	int error,i,ld;
+	int error, i, ld;
 
 	DPRINTK("zatm_start\n");
-	zatm_dev = ZATM_DEV(dev);
 	zatm_dev->rx_map = zatm_dev->tx_map = NULL;
-	for (i = 0; i < NR_MBX; i++)
-		zatm_dev->mbx_start[i] = 0;
-	if (request_irq(zatm_dev->irq,&zatm_int,SA_SHIRQ,DEV_LABEL,dev)) {
-		printk(KERN_ERR DEV_LABEL "(itf %d): IRQ%d is already in use\n",
-		    dev->number,zatm_dev->irq);
-		return -EAGAIN;
+ 	for (i = 0; i < NR_MBX; i++)
+ 		zatm_dev->mbx_start[i] = 0;
+ 	error = request_irq(zatm_dev->irq, zatm_int, SA_SHIRQ, DEV_LABEL, dev);
+	if (error < 0) {
+ 		printk(KERN_ERR DEV_LABEL "(itf %d): IRQ%d is already in use\n",
+ 		    dev->number,zatm_dev->irq);
+		goto done;
 	}
-	request_region(zatm_dev->base,uPD98401_PORTS,DEV_LABEL);
 	/* define memory regions */
 	pools = NR_POOLS;
 	if (NR_SHAPERS*SHAPER_SIZE > pools*POOL_SIZE)
@@ -1299,51 +1299,66 @@ static int __init zatm_start(struct atm_
 	    "%ld VCs\n",dev->number,NR_SHAPERS,pools,rx,
 	    (zatm_dev->mem-curr*4)/VC_SIZE);
 	/* create mailboxes */
-	for (i = 0; i < NR_MBX; i++)
-		if (mbx_entries[i]) {
-			unsigned long here;
-
-			here = (unsigned long) kmalloc(2*MBX_SIZE(i),
-			    GFP_KERNEL);
-			if (!here) {
-				error = -ENOMEM;
-				goto out;
-			}
-			if ((here^(here+MBX_SIZE(i))) & ~0xffffUL)/* paranoia */
-				here = (here & ~0xffffUL)+0x10000;
-			zatm_dev->mbx_start[i] = here;
-			if ((here^virt_to_bus((void *) here)) & 0xffff) {
-				printk(KERN_ERR DEV_LABEL "(itf %d): system "
-				    "bus incompatible with driver\n",
-				    dev->number);
-				error = -ENODEV;
-				goto out;
-			}
-			DPRINTK("mbx@0x%08lx-0x%08lx\n",here,here+MBX_SIZE(i));
-			zatm_dev->mbx_end[i] = (here+MBX_SIZE(i)) & 0xffff;
-			zout(virt_to_bus((void *) here) >> 16,MSH(i));
-			zout(virt_to_bus((void *) here),MSL(i));
-			zout((here+MBX_SIZE(i)) & 0xffff,MBA(i));
-			zout(here & 0xffff,MTA(i));
-			zout(here & 0xffff,MWA(i));
-		}
+	for (i = 0; i < NR_MBX; i++) {
+		void *mbx;
+		dma_addr_t mbx_dma;
+
+		if (!mbx_entries[i])
+			continue;
+		mbx = pci_alloc_consistent(pdev, 2*MBX_SIZE(i), &mbx_dma);
+		if (!mbx) {
+			error = -ENOMEM;
+			goto out;
+		}
+		/*
+		 * Alignment provided by pci_alloc_consistent() isn't enough
+		 * for this device.
+		 */
+		if (((unsigned long)mbx ^ mbx_dma) & 0xffff) {
+			printk(KERN_ERR DEV_LABEL "(itf %d): system "
+			       "bus incompatible with driver\n", dev->number);
+			pci_free_consistent(pdev, 2*MBX_SIZE(i), mbx, mbx_dma);
+			error = -ENODEV;
+			goto out;
+		}
+		DPRINTK("mbx@0x%08lx-0x%08lx\n", mbx, mbx + MBX_SIZE(i));
+		zatm_dev->mbx_start[i] = (unsigned long)mbx;
+		zatm_dev->mbx_dma[i] = mbx_dma;
+		zatm_dev->mbx_end[i] = (zatm_dev->mbx_start[i] + MBX_SIZE(i)) &
+					0xffff;
+		zout(mbx_dma >> 16, MSH(i));
+		zout(mbx_dma, MSL(i));
+		zout(zatm_dev->mbx_end[i], MBA(i));
+		zout((unsigned long)mbx & 0xffff, MTA(i));
+		zout((unsigned long)mbx & 0xffff, MWA(i));
+	}
 	error = start_tx(dev);
-	if (error) goto out;
+	if (error)
+		goto out;
 	error = start_rx(dev);
-	if (error) goto out;
+	if (error)
+		goto out_tx;
 	error = dev->phy->start(dev);
-	if (error) goto out;
+	if (error)
+		goto out_rx;
 	zout(0xffffffff,IMR); /* enable interrupts */
 	/* enable TX & RX */
 	zout(zin(GMR) | uPD98401_GMR_SE | uPD98401_GMR_RE,GMR);
-	return 0;
-    out:
-	for (i = 0; i < NR_MBX; i++)
-		kfree(zatm_dev->mbx_start[i]);
+done:
+	return error;
+
+out_rx:
 	kfree(zatm_dev->rx_map);
+out_tx:
 	kfree(zatm_dev->tx_map);
+out:
+	while (i-- > 0) {
+		pci_free_consistent(pdev, 2*MBX_SIZE(i), 
+				    (void *)zatm_dev->mbx_start[i],
+				    zatm_dev->mbx_dma[i]);
+	}
 	free_irq(zatm_dev->irq, dev);
-	return error;
+	goto done;
 }
 
 
diff --git a/drivers/atm/zatm.h b/drivers/atm/zatm.h
--- a/drivers/atm/zatm.h
+++ b/drivers/atm/zatm.h
@@ -73,6 +73,7 @@ struct zatm_dev {
 	int chans;			/* map size, must be 2^n */
 	/*-------------------------------- mailboxes */
 	unsigned long mbx_start[NR_MBX];/* start addresses */
+	dma_addr_t mbx_dma[NR_MBX];
 	u16 mbx_end[NR_MBX];		/* end offset (in bytes) */
 	/*-------------------------------- other pointers */
 	u32 pool_base;			/* Free buffer pool dsc (word addr) */
diff --git a/drivers/base/Makefile b/drivers/base/Makefile
--- a/drivers/base/Makefile
+++ b/drivers/base/Makefile
@@ -1,7 +1,7 @@
 # Makefile for the Linux device tree
 
-obj-y			:= core.o sys.o bus.o \
-			   driver.o class.o class_simple.o platform.o \
+obj-y			:= core.o sys.o bus.o dd.o \
+			   driver.o class.o platform.o \
 			   cpu.o firmware.o init.o map.o dmapool.o \
 			   attribute_container.o transport_class.o
 obj-y			+= power/
diff --git a/drivers/base/base.h b/drivers/base/base.h
--- a/drivers/base/base.h
+++ b/drivers/base/base.h
@@ -4,6 +4,9 @@ extern void bus_remove_device(struct dev
 extern int bus_add_driver(struct device_driver *);
 extern void bus_remove_driver(struct device_driver *);
 
+extern void driver_detach(struct device_driver * drv);
+extern int driver_probe_device(struct device_driver *, struct device *);
+
 static inline struct class_device *to_class_dev(struct kobject *obj)
 {
 	return container_of(obj, struct class_device, kobj);
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -17,9 +17,6 @@
 #include "base.h"
 #include "power/power.h"
 
-#define to_dev(node) container_of(node, struct device, bus_list)
-#define to_drv(node) container_of(node, struct device_driver, kobj.entry)
-
 #define to_bus_attr(_attr) container_of(_attr, struct bus_attribute, attr)
 #define to_bus(obj) container_of(obj, struct bus_type, subsys.kset.kobj)
 
@@ -36,7 +33,7 @@ drv_attr_show(struct kobject * kobj, str
 {
 	struct driver_attribute * drv_attr = to_drv_attr(attr);
 	struct device_driver * drv = to_driver(kobj);
-	ssize_t ret = 0;
+	ssize_t ret = -EIO;
 
 	if (drv_attr->show)
 		ret = drv_attr->show(drv, buf);
@@ -49,7 +46,7 @@ drv_attr_store(struct kobject * kobj, st
 {
 	struct driver_attribute * drv_attr = to_drv_attr(attr);
 	struct device_driver * drv = to_driver(kobj);
-	ssize_t ret = 0;
+	ssize_t ret = -EIO;
 
 	if (drv_attr->store)
 		ret = drv_attr->store(drv, buf, count);
@@ -135,50 +132,65 @@ static struct kobj_type ktype_bus = {
 
 decl_subsys(bus, &ktype_bus, NULL);
 
-static int __bus_for_each_dev(struct bus_type *bus, struct device *start,
-			      void *data, int (*fn)(struct device *, void *))
+
+/* Manually detach a device from it's associated driver. */
+static int driver_helper(struct device *dev, void *data)
 {
-	struct list_head *head;
-	struct device *dev;
-	int error = 0;
+	const char *name = data;
 
-	if (!(bus = get_bus(bus)))
-		return -EINVAL;
+	if (strcmp(name, dev->bus_id) == 0)
+		return 1;
+	return 0;
+}
 
-	head = &bus->devices.list;
-	dev = list_prepare_entry(start, head, bus_list);
-	list_for_each_entry_continue(dev, head, bus_list) {
-		get_device(dev);
-		error = fn(dev, data);
-		put_device(dev);
-		if (error)
-			break;
+static ssize_t driver_unbind(struct device_driver *drv,
+			     const char *buf, size_t count)
+{
+	struct bus_type *bus = get_bus(drv->bus);
+	struct device *dev;
+	int err = -ENODEV;
+
+	dev = bus_find_device(bus, NULL, (void *)buf, driver_helper);
+	if ((dev) &&
+	    (dev->driver == drv)) {
+		device_release_driver(dev);
+		err = count;
 	}
-	put_bus(bus);
-	return error;
+	return err;
 }
+static DRIVER_ATTR(unbind, S_IWUSR, NULL, driver_unbind);
 
-static int __bus_for_each_drv(struct bus_type *bus, struct device_driver *start,
-			      void * data, int (*fn)(struct device_driver *, void *))
+/*
+ * Manually attach a device to a driver.
+ * Note: the driver must want to bind to the device,
+ * it is not possible to override the driver's id table.
+ */
+static ssize_t driver_bind(struct device_driver *drv,
+			   const char *buf, size_t count)
 {
-	struct list_head *head;
-	struct device_driver *drv;
-	int error = 0;
-
-	if (!(bus = get_bus(bus)))
-		return -EINVAL;
+	struct bus_type *bus = get_bus(drv->bus);
+	struct device *dev;
+	int err = -ENODEV;
 
-	head = &bus->drivers.list;
-	drv = list_prepare_entry(start, head, kobj.entry);
-	list_for_each_entry_continue(drv, head, kobj.entry) {
-		get_driver(drv);
-		error = fn(drv, data);
-		put_driver(drv);
-		if (error)
-			break;
+	dev = bus_find_device(bus, NULL, (void *)buf, driver_helper);
+	if ((dev) &&
+	    (dev->driver == NULL)) {
+		down(&dev->sem);
+		err = driver_probe_device(drv, dev);
+		up(&dev->sem);
+		put_device(dev);
 	}
-	put_bus(bus);
-	return error;
+	if (err)
+		return err;
+	return count;
+}
+static DRIVER_ATTR(bind, S_IWUSR, NULL, driver_bind);
+
+
+static struct device * next_device(struct klist_iter * i)
+{
+	struct klist_node * n = klist_next(i);
+	return n ? container_of(n, struct device, knode_bus) : NULL;
 }
 
 /**
@@ -204,12 +216,60 @@ static int __bus_for_each_drv(struct bus
 int bus_for_each_dev(struct bus_type * bus, struct device * start,
 		     void * data, int (*fn)(struct device *, void *))
 {
-	int ret;
+	struct klist_iter i;
+	struct device * dev;
+	int error = 0;
 
-	down_read(&bus->subsys.rwsem);
-	ret = __bus_for_each_dev(bus, start, data, fn);
-	up_read(&bus->subsys.rwsem);
-	return ret;
+	if (!bus)
+		return -EINVAL;
+
+	klist_iter_init_node(&bus->klist_devices, &i,
+			     (start ? &start->knode_bus : NULL));
+	while ((dev = next_device(&i)) && !error)
+		error = fn(dev, data);
+	klist_iter_exit(&i);
+	return error;
+}
+
+/**
+ * bus_find_device - device iterator for locating a particular device.
+ * @bus: bus type
+ * @start: Device to begin with
+ * @data: Data to pass to match function
+ * @match: Callback function to check device
+ *
+ * This is similar to the bus_for_each_dev() function above, but it
+ * returns a reference to a device that is 'found' for later use, as
+ * determined by the @match callback.
+ *
+ * The callback should return 0 if the device doesn't match and non-zero
+ * if it does.  If the callback returns non-zero, this function will
+ * return to the caller and not iterate over any more devices.
+ */
+struct device * bus_find_device(struct bus_type *bus,
+				struct device *start, void *data,
+				int (*match)(struct device *, void *))
+{
+	struct klist_iter i;
+	struct device *dev;
+
+	if (!bus)
+		return NULL;
+
+	klist_iter_init_node(&bus->klist_devices, &i,
+			     (start ? &start->knode_bus : NULL));
+	while ((dev = next_device(&i)))
+		if (match(dev, data) && get_device(dev))
+			break;
+	klist_iter_exit(&i);
+	return dev;
+}
+
+
+static struct device_driver * next_driver(struct klist_iter * i)
+{
+	struct klist_node * n = klist_next(i);
+	return n ? container_of(n, struct device_driver, knode_bus) : NULL;
 }
 
 /**
@@ -235,179 +295,19 @@ int bus_for_each_dev(struct bus_type * b
 int bus_for_each_drv(struct bus_type * bus, struct device_driver * start,
 		     void * data, int (*fn)(struct device_driver *, void *))
 {
-	int ret;
-
-	down_read(&bus->subsys.rwsem);
-	ret = __bus_for_each_drv(bus, start, data, fn);
-	up_read(&bus->subsys.rwsem);
-	return ret;
-}
-
-/**
- *	device_bind_driver - bind a driver to one device.
- *	@dev:	device.
- *
- *	Allow manual attachment of a driver to a device.
- *	Caller must have already set @dev->driver.
- *
- *	Note that this does not modify the bus reference count
- *	nor take the bus's rwsem. Please verify those are accounted
- *	for before calling this. (It is ok to call with no other effort
- *	from a driver's probe() method.)
- */
-
-void device_bind_driver(struct device * dev)
-{
-	pr_debug("bound device '%s' to driver '%s'\n",
-		 dev->bus_id, dev->driver->name);
-	list_add_tail(&dev->driver_list, &dev->driver->devices);
-	sysfs_create_link(&dev->driver->kobj, &dev->kobj,
-			  kobject_name(&dev->kobj));
-	sysfs_create_link(&dev->kobj, &dev->driver->kobj, "driver");
-}
-
-
-/**
- *	driver_probe_device - attempt to bind device & driver.
- *	@drv:	driver.
- *	@dev:	device.
- *
- *	First, we call the bus's match function, if one present, which
- *	should compare the device IDs the driver supports with the
- *	device IDs of the device. Note we don't do this ourselves
- *	because we don't know the format of the ID structures, nor what
- *	is to be considered a match and what is not.
- *
- *	If we find a match, we call @drv->probe(@dev) if it exists, and
- *	call device_bind_driver() above.
- */
-int driver_probe_device(struct device_driver * drv, struct device * dev)
-{
-	if (drv->bus->match && !drv->bus->match(dev, drv))
-		return -ENODEV;
-
-	dev->driver = drv;
-	if (drv->probe) {
-		int error = drv->probe(dev);
-		if (error) {
-			dev->driver = NULL;
-			return error;
-		}
-	}
-
-	device_bind_driver(dev);
-	return 0;
-}
-
-
-/**
- *	device_attach - try to attach device to a driver.
- *	@dev:	device.
- *
- *	Walk the list of drivers that the bus has and call
- *	driver_probe_device() for each pair. If a compatible
- *	pair is found, break out and return.
- */
-int device_attach(struct device * dev)
-{
- 	struct bus_type * bus = dev->bus;
-	struct list_head * entry;
-	int error;
-
-	if (dev->driver) {
-		device_bind_driver(dev);
-		return 1;
-	}
-
-	if (bus->match) {
-		list_for_each(entry, &bus->drivers.list) {
-			struct device_driver * drv = to_drv(entry);
-			error = driver_probe_device(drv, dev);
-			if (!error)
-				/* success, driver matched */
-				return 1;
-			if (error != -ENODEV && error != -ENXIO)
-				/* driver matched but the probe failed */
-				printk(KERN_WARNING
-				    "%s: probe of %s failed with error %d\n",
-				    drv->name, dev->bus_id, error);
-		}
-	}
-
-	return 0;
-}
-
-
-/**
- *	driver_attach - try to bind driver to devices.
- *	@drv:	driver.
- *
- *	Walk the list of devices that the bus has on it and try to
- *	match the driver with each one.  If driver_probe_device()
- *	returns 0 and the @dev->driver is set, we've found a
- *	compatible pair.
- *
- *	Note that we ignore the -ENODEV error from driver_probe_device(),
- *	since it's perfectly valid for a driver not to bind to any devices.
- */
-void driver_attach(struct device_driver * drv)
-{
-	struct bus_type * bus = drv->bus;
-	struct list_head * entry;
-	int error;
-
-	if (!bus->match)
-		return;
-
-	list_for_each(entry, &bus->devices.list) {
-		struct device * dev = container_of(entry, struct device, bus_list);
-		if (!dev->driver) {
-			error = driver_probe_device(drv, dev);
-			if (error && (error != -ENODEV))
-				/* driver matched but the probe failed */
-				printk(KERN_WARNING
-				    "%s: probe of %s failed with error %d\n",
-				    drv->name, dev->bus_id, error);
-		}
-	}
-}
-
-
-/**
- *	device_release_driver - manually detach device from driver.
- *	@dev:	device.
- *
- *	Manually detach device from driver.
- *	Note that this is called without incrementing the bus
- *	reference count nor taking the bus's rwsem. Be sure that
- *	those are accounted for before calling this function.
- */
-
-void device_release_driver(struct device * dev)
-{
-	struct device_driver * drv = dev->driver;
-	if (drv) {
-		sysfs_remove_link(&drv->kobj, kobject_name(&dev->kobj));
-		sysfs_remove_link(&dev->kobj, "driver");
-		list_del_init(&dev->driver_list);
-		if (drv->remove)
-			drv->remove(dev);
-		dev->driver = NULL;
-	}
-}
-
+	struct klist_iter i;
+	struct device_driver * drv;
+	int error = 0;
 
-/**
- *	driver_detach - detach driver from all devices it controls.
- *	@drv:	driver.
- */
+	if (!bus)
+		return -EINVAL;
 
-static void driver_detach(struct device_driver * drv)
-{
-	while (!list_empty(&drv->devices)) {
-		struct device * dev = container_of(drv->devices.next, struct device, driver_list);
-		device_release_driver(dev);
-	}
+	klist_iter_init_node(&bus->klist_drivers, &i,
+			     start ? &start->knode_bus : NULL);
+	while ((drv = next_driver(&i)) && !error)
+		error = fn(drv, data);
+	klist_iter_exit(&i);
+	return error;
 }
 
 static int device_add_attrs(struct bus_type * bus, struct device * dev)
@@ -456,14 +356,14 @@ int bus_add_device(struct device * dev)
 	int error = 0;
 
 	if (bus) {
-		down_write(&dev->bus->subsys.rwsem);
 		pr_debug("bus %s: add device %s\n", bus->name, dev->bus_id);
-		list_add_tail(&dev->bus_list, &dev->bus->devices.list);
 		device_attach(dev);
-		up_write(&dev->bus->subsys.rwsem);
-		device_add_attrs(bus, dev);
-		sysfs_create_link(&bus->devices.kobj, &dev->kobj, dev->bus_id);
-		sysfs_create_link(&dev->kobj, &dev->bus->subsys.kset.kobj, "bus");
+		klist_add_tail(&bus->klist_devices, &dev->knode_bus);
+		error = device_add_attrs(bus, dev);
+		if (!error) {
+			sysfs_create_link(&bus->devices.kobj, &dev->kobj, dev->bus_id);
+			sysfs_create_link(&dev->kobj, &dev->bus->subsys.kset.kobj, "bus");
+		}
 	}
 	return error;
 }
@@ -483,11 +383,9 @@ void bus_remove_device(struct device * d
 		sysfs_remove_link(&dev->kobj, "bus");
 		sysfs_remove_link(&dev->bus->devices.kobj, dev->bus_id);
 		device_remove_attrs(dev->bus, dev);
-		down_write(&dev->bus->subsys.rwsem);
+		klist_remove(&dev->knode_bus);
 		pr_debug("bus %s: remove device %s\n", dev->bus->name, dev->bus_id);
 		device_release_driver(dev);
-		list_del_init(&dev->bus_list);
-		up_write(&dev->bus->subsys.rwsem);
 		put_bus(dev->bus);
 	}
 }
@@ -547,12 +445,13 @@ int bus_add_driver(struct device_driver 
 			return error;
 		}
 
-		down_write(&bus->subsys.rwsem);
 		driver_attach(drv);
-		up_write(&bus->subsys.rwsem);
+		klist_add_tail(&bus->klist_drivers, &drv->knode_bus);
 		module_add_driver(drv->owner, drv);
 
 		driver_add_attrs(bus, drv);
+		driver_create_file(drv, &driver_attr_unbind);
+		driver_create_file(drv, &driver_attr_bind);
 	}
 	return error;
 }
@@ -570,11 +469,12 @@ int bus_add_driver(struct device_driver 
 void bus_remove_driver(struct device_driver * drv)
 {
 	if (drv->bus) {
+		driver_remove_file(drv, &driver_attr_bind);
+		driver_remove_file(drv, &driver_attr_unbind);
 		driver_remove_attrs(drv->bus, drv);
-		down_write(&drv->bus->subsys.rwsem);
+		klist_remove(&drv->knode_bus);
 		pr_debug("bus %s: remove driver %s\n", drv->bus->name, drv->name);
 		driver_detach(drv);
-		up_write(&drv->bus->subsys.rwsem);
 		module_remove_driver(drv);
 		kobject_unregister(&drv->kobj);
 		put_bus(drv->bus);
@@ -585,33 +485,22 @@ void bus_remove_driver(struct device_dri
 /* Helper for bus_rescan_devices's iter */
 static int bus_rescan_devices_helper(struct device *dev, void *data)
 {
-	int *count = data;
-
-	if (!dev->driver && device_attach(dev))
-		(*count)++;
-
+	if (!dev->driver)
+		device_attach(dev);
 	return 0;
 }
 
-
 /**
- *	bus_rescan_devices - rescan devices on the bus for possible drivers
- *	@bus:	the bus to scan.
+ * bus_rescan_devices - rescan devices on the bus for possible drivers
+ * @bus: the bus to scan.
  *
- *	This function will look for devices on the bus with no driver
- *	attached and rescan it against existing drivers to see if it
- *	matches any. Calls device_attach(). Returns the number of devices
- *	that were sucessfully bound to a driver.
+ * This function will look for devices on the bus with no driver
+ * attached and rescan it against existing drivers to see if it matches
+ * any by calling device_attach() for the unbound devices.
  */
-int bus_rescan_devices(struct bus_type * bus)
+void bus_rescan_devices(struct bus_type * bus)
 {
-	int count = 0;
-
-	down_write(&bus->subsys.rwsem);
-	__bus_for_each_dev(bus, NULL, &count, bus_rescan_devices_helper);
-	up_write(&bus->subsys.rwsem);
-
-	return count;
+	bus_for_each_dev(bus, NULL, NULL, bus_rescan_devices_helper);
 }
 
 
@@ -710,6 +599,9 @@ int bus_register(struct bus_type * bus)
 	retval = kset_register(&bus->drivers);
 	if (retval)
 		goto bus_drivers_fail;
+
+	klist_init(&bus->klist_devices);
+	klist_init(&bus->klist_drivers);
 	bus_add_attrs(bus);
 
 	pr_debug("bus type '%s' registered\n", bus->name);
@@ -747,14 +639,9 @@ int __init buses_init(void)
 
 
 EXPORT_SYMBOL_GPL(bus_for_each_dev);
+EXPORT_SYMBOL_GPL(bus_find_device);
 EXPORT_SYMBOL_GPL(bus_for_each_drv);
 
-EXPORT_SYMBOL_GPL(driver_probe_device);
-EXPORT_SYMBOL_GPL(device_bind_driver);
-EXPORT_SYMBOL_GPL(device_release_driver);
-EXPORT_SYMBOL_GPL(device_attach);
-EXPORT_SYMBOL_GPL(driver_attach);
-
 EXPORT_SYMBOL_GPL(bus_add_device);
 EXPORT_SYMBOL_GPL(bus_remove_device);
 EXPORT_SYMBOL_GPL(bus_register);
diff --git a/drivers/base/class.c b/drivers/base/class.c
--- a/drivers/base/class.c
+++ b/drivers/base/class.c
@@ -16,6 +16,7 @@
 #include <linux/init.h>
 #include <linux/string.h>
 #include <linux/kdev_t.h>
+#include <linux/err.h>
 #include "base.h"
 
 #define to_class_attr(_attr) container_of(_attr, struct class_attribute, attr)
@@ -26,7 +27,7 @@ class_attr_show(struct kobject * kobj, s
 {
 	struct class_attribute * class_attr = to_class_attr(attr);
 	struct class * dc = to_class(kobj);
-	ssize_t ret = 0;
+	ssize_t ret = -EIO;
 
 	if (class_attr->show)
 		ret = class_attr->show(dc, buf);
@@ -39,7 +40,7 @@ class_attr_store(struct kobject * kobj, 
 {
 	struct class_attribute * class_attr = to_class_attr(attr);
 	struct class * dc = to_class(kobj);
-	ssize_t ret = 0;
+	ssize_t ret = -EIO;
 
 	if (class_attr->store)
 		ret = class_attr->store(dc, buf, count);
@@ -162,6 +163,69 @@ void class_unregister(struct class * cls
 	subsystem_unregister(&cls->subsys);
 }
 
+static void class_create_release(struct class *cls)
+{
+	kfree(cls);
+}
+
+static void class_device_create_release(struct class_device *class_dev)
+{
+	kfree(class_dev);
+}
+
+/**
+ * class_create - create a struct class structure
+ * @owner: pointer to the module that is to "own" this struct class
+ * @name: pointer to a string for the name of this class.
+ *
+ * This is used to create a struct class pointer that can then be used
+ * in calls to class_device_create().
+ *
+ * Note, the pointer created here is to be destroyed when finished by
+ * making a call to class_destroy().
+ */
+struct class *class_create(struct module *owner, char *name)
+{
+	struct class *cls;
+	int retval;
+
+	cls = kmalloc(sizeof(struct class), GFP_KERNEL);
+	if (!cls) {
+		retval = -ENOMEM;
+		goto error;
+	}
+	memset(cls, 0x00, sizeof(struct class));
+
+	cls->name = name;
+	cls->owner = owner;
+	cls->class_release = class_create_release;
+	cls->release = class_device_create_release;
+
+	retval = class_register(cls);
+	if (retval)
+		goto error;
+
+	return cls;
+
+error:
+	kfree(cls);
+	return ERR_PTR(retval);
+}
+
+/**
+ * class_destroy - destroys a struct class structure
+ * @cs: pointer to the struct class that is to be destroyed
+ *
+ * Note, the pointer to be destroyed must have been created with a call
+ * to class_create().
+ */
+void class_destroy(struct class *cls)
+{
+	if ((cls == NULL) || (IS_ERR(cls)))
+		return;
+
+	class_unregister(cls);
+}
 
 /* Class Device Stuff */
 
@@ -235,6 +299,11 @@ static void class_dev_release(struct kob
 
 	pr_debug("device class '%s': release.\n", cd->class_id);
 
+	if (cd->devt_attr) {
+		kfree(cd->devt_attr);
+		cd->devt_attr = NULL;
+	}
+
 	if (cls->release)
 		cls->release(cd);
 	else {
@@ -262,7 +331,7 @@ static int class_hotplug_filter(struct k
 	return 0;
 }
 
-static char *class_hotplug_name(struct kset *kset, struct kobject *kobj)
+static const char *class_hotplug_name(struct kset *kset, struct kobject *kobj)
 {
 	struct class_device *class_dev = to_class_dev(kobj);
 
@@ -375,7 +444,6 @@ static ssize_t show_dev(struct class_dev
 {
 	return print_dev_t(buf, class_dev->devt);
 }
-static CLASS_DEVICE_ATTR(dev, S_IRUGO, show_dev, NULL);
 
 void class_device_initialize(struct class_device *class_dev)
 {
@@ -412,7 +480,31 @@ int class_device_add(struct class_device
 	if ((error = kobject_add(&class_dev->kobj)))
 		goto register_done;
 
-	/* now take care of our own registration */
+	/* add the needed attributes to this device */
+	if (MAJOR(class_dev->devt)) {
+		struct class_device_attribute *attr;
+		attr = kmalloc(sizeof(*attr), GFP_KERNEL);
+		if (!attr) {
+			error = -ENOMEM;
+			kobject_del(&class_dev->kobj);
+			goto register_done;
+		}
+		memset(attr, sizeof(*attr), 0x00);
+		attr->attr.name = "dev";
+		attr->attr.mode = S_IRUGO;
+		attr->attr.owner = parent->owner;
+		attr->show = show_dev;
+		attr->store = NULL;
+		class_device_create_file(class_dev, attr);
+		class_dev->devt_attr = attr;
+	}
+
+	class_device_add_attrs(class_dev);
+	if (class_dev->dev)
+		sysfs_create_link(&class_dev->kobj,
+				  &class_dev->dev->kobj, "device");
+
+	/* notify any interfaces this device is now here */
 	if (parent) {
 		down(&parent->sem);
 		list_add_tail(&class_dev->node, &parent->children);
@@ -421,16 +513,8 @@ int class_device_add(struct class_device
 				class_intf->add(class_dev);
 		up(&parent->sem);
 	}
-
-	if (MAJOR(class_dev->devt))
-		class_device_create_file(class_dev, &class_device_attr_dev);
-
-	class_device_add_attrs(class_dev);
-	if (class_dev->dev)
-		sysfs_create_link(&class_dev->kobj,
-				  &class_dev->dev->kobj, "device");
-
 	kobject_hotplug(&class_dev->kobj, KOBJ_ADD);
+
  register_done:
 	if (error && parent)
 		class_put(parent);
@@ -444,6 +528,58 @@ int class_device_register(struct class_d
 	return class_device_add(class_dev);
 }
 
+/**
+ * class_device_create - creates a class device and registers it with sysfs
+ * @cs: pointer to the struct class that this device should be registered to.
+ * @dev: the dev_t for the char device to be added.
+ * @device: a pointer to a struct device that is assiociated with this class device.
+ * @fmt: string for the class device's name
+ *
+ * This function can be used by char device classes.  A struct
+ * class_device will be created in sysfs, registered to the specified
+ * class.  A "dev" file will be created, showing the dev_t for the
+ * device.  The pointer to the struct class_device will be returned from
+ * the call.  Any further sysfs files that might be required can be
+ * created using this pointer.
+ *
+ * Note: the struct class passed to this function must have previously
+ * been created with a call to class_create().
+ */
+struct class_device *class_device_create(struct class *cls, dev_t devt,
+					 struct device *device, char *fmt, ...)
+{
+	va_list args;
+	struct class_device *class_dev = NULL;
+	int retval = -ENODEV;
+
+	if (cls == NULL || IS_ERR(cls))
+		goto error;
+
+	class_dev = kmalloc(sizeof(struct class_device), GFP_KERNEL);
+	if (!class_dev) {
+		retval = -ENOMEM;
+		goto error;
+	}
+	memset(class_dev, 0x00, sizeof(struct class_device));
+
+	class_dev->devt = devt;
+	class_dev->dev = device;
+	class_dev->class = cls;
+
+	va_start(args, fmt);
+	vsnprintf(class_dev->class_id, BUS_ID_SIZE, fmt, args);
+	va_end(args);
+	retval = class_device_register(class_dev);
+	if (retval)
+		goto error;
+
+	return class_dev;
+
+error:
+	kfree(class_dev);
+	return ERR_PTR(retval);
+}
+
 void class_device_del(struct class_device *class_dev)
 {
 	struct class * parent = class_dev->class;
@@ -460,6 +596,8 @@ void class_device_del(struct class_devic
 
 	if (class_dev->dev)
 		sysfs_remove_link(&class_dev->kobj, "device");
+	if (class_dev->devt_attr)
+		class_device_remove_file(class_dev, class_dev->devt_attr);
 	class_device_remove_attrs(class_dev);
 
 	kobject_hotplug(&class_dev->kobj, KOBJ_REMOVE);
@@ -477,6 +615,32 @@ void class_device_unregister(struct clas
 	class_device_put(class_dev);
 }
 
+/**
+ * class_device_destroy - removes a class device that was created with class_device_create()
+ * @cls: the pointer to the struct class that this device was registered * with.
+ * @dev: the dev_t of the device that was previously registered.
+ *
+ * This call unregisters and cleans up a class device that was created with a
+ * call to class_device_create()
+ */
+void class_device_destroy(struct class *cls, dev_t devt)
+{
+	struct class_device *class_dev = NULL;
+	struct class_device *class_dev_tmp;
+
+	down(&cls->sem);
+	list_for_each_entry(class_dev_tmp, &cls->children, node) {
+		if (class_dev_tmp->devt == devt) {
+			class_dev = class_dev_tmp;
+			break;
+		}
+	}
+	up(&cls->sem);
+
+	if (class_dev)
+		class_device_unregister(class_dev);
+}
+
 int class_device_rename(struct class_device *class_dev, char *new_name)
 {
 	int error = 0;
@@ -576,6 +740,8 @@ EXPORT_SYMBOL_GPL(class_register);
 EXPORT_SYMBOL_GPL(class_unregister);
 EXPORT_SYMBOL_GPL(class_get);
 EXPORT_SYMBOL_GPL(class_put);
+EXPORT_SYMBOL_GPL(class_create);
+EXPORT_SYMBOL_GPL(class_destroy);
 
 EXPORT_SYMBOL_GPL(class_device_register);
 EXPORT_SYMBOL_GPL(class_device_unregister);
@@ -584,6 +750,8 @@ EXPORT_SYMBOL_GPL(class_device_add);
 EXPORT_SYMBOL_GPL(class_device_del);
 EXPORT_SYMBOL_GPL(class_device_get);
 EXPORT_SYMBOL_GPL(class_device_put);
+EXPORT_SYMBOL_GPL(class_device_create);
+EXPORT_SYMBOL_GPL(class_device_destroy);
 EXPORT_SYMBOL_GPL(class_device_create_file);
 EXPORT_SYMBOL_GPL(class_device_remove_file);
 EXPORT_SYMBOL_GPL(class_device_create_bin_file);
diff --git a/drivers/base/class_simple.c b/drivers/base/class_simple.c
deleted file mode 100644
--- a/drivers/base/class_simple.c
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * class_simple.c - a "simple" interface for classes for simple char devices.
- *
- * Copyright (c) 2003-2004 Greg Kroah-Hartman <greg@kroah.com>
- * Copyright (c) 2003-2004 IBM Corp.
- *
- * This file is released under the GPLv2
- *
- */
-
-#include <linux/config.h>
-#include <linux/device.h>
-#include <linux/err.h>
-
-struct class_simple {
-	struct class class;
-};
-#define to_class_simple(d) container_of(d, struct class_simple, class)
-
-struct simple_dev {
-	struct list_head node;
-	struct class_device class_dev;
-};
-#define to_simple_dev(d) container_of(d, struct simple_dev, class_dev)
-
-static LIST_HEAD(simple_dev_list);
-static DEFINE_SPINLOCK(simple_dev_list_lock);
-
-static void release_simple_dev(struct class_device *class_dev)
-{
-	struct simple_dev *s_dev = to_simple_dev(class_dev);
-	kfree(s_dev);
-}
-
-static void class_simple_release(struct class *class)
-{
-	struct class_simple *cs = to_class_simple(class);
-	kfree(cs);
-}
-
-/**
- * class_simple_create - create a struct class_simple structure
- * @owner: pointer to the module that is to "own" this struct class_simple
- * @name: pointer to a string for the name of this class.
- *
- * This is used to create a struct class_simple pointer that can then be used
- * in calls to class_simple_device_add().  This is used when you do not wish to
- * create a full blown class support for a type of char devices.
- *
- * Note, the pointer created here is to be destroyed when finished by making a
- * call to class_simple_destroy().
- */
-struct class_simple *class_simple_create(struct module *owner, char *name)
-{
-	struct class_simple *cs;
-	int retval;
-
-	cs = kmalloc(sizeof(*cs), GFP_KERNEL);
-	if (!cs) {
-		retval = -ENOMEM;
-		goto error;
-	}
-	memset(cs, 0x00, sizeof(*cs));
-
-	cs->class.name = name;
-	cs->class.class_release = class_simple_release;
-	cs->class.release = release_simple_dev;
-
-	retval = class_register(&cs->class);
-	if (retval)
-		goto error;
-
-	return cs;
-
-error:
-	kfree(cs);
-	return ERR_PTR(retval);
-}
-EXPORT_SYMBOL(class_simple_create);
-
-/**
- * class_simple_destroy - destroys a struct class_simple structure
- * @cs: pointer to the struct class_simple that is to be destroyed
- *
- * Note, the pointer to be destroyed must have been created with a call to
- * class_simple_create().
- */
-void class_simple_destroy(struct class_simple *cs)
-{
-	if ((cs == NULL) || (IS_ERR(cs)))
-		return;
-
-	class_unregister(&cs->class);
-}
-EXPORT_SYMBOL(class_simple_destroy);
-
-/**
- * class_simple_device_add - adds a class device to sysfs for a character driver
- * @cs: pointer to the struct class_simple that this device should be registered to.
- * @dev: the dev_t for the device to be added.
- * @device: a pointer to a struct device that is assiociated with this class device.
- * @fmt: string for the class device's name
- *
- * This function can be used by simple char device classes that do not
- * implement their own class device registration.  A struct class_device will
- * be created in sysfs, registered to the specified class.  A "dev" file will
- * be created, showing the dev_t for the device.  The pointer to the struct
- * class_device will be returned from the call.  Any further sysfs files that
- * might be required can be created using this pointer.
- * Note: the struct class_simple passed to this function must have previously been
- * created with a call to class_simple_create().
- */
-struct class_device *class_simple_device_add(struct class_simple *cs, dev_t dev, struct device *device, const char *fmt, ...)
-{
-	va_list args;
-	struct simple_dev *s_dev = NULL;
-	int retval;
-
-	if ((cs == NULL) || (IS_ERR(cs))) {
-		retval = -ENODEV;
-		goto error;
-	}
-
-	s_dev = kmalloc(sizeof(*s_dev), GFP_KERNEL);
-	if (!s_dev) {
-		retval = -ENOMEM;
-		goto error;
-	}
-	memset(s_dev, 0x00, sizeof(*s_dev));
-
-	s_dev->class_dev.devt = dev;
-	s_dev->class_dev.dev = device;
-	s_dev->class_dev.class = &cs->class;
-
-	va_start(args, fmt);
-	vsnprintf(s_dev->class_dev.class_id, BUS_ID_SIZE, fmt, args);
-	va_end(args);
-	retval = class_device_register(&s_dev->class_dev);
-	if (retval)
-		goto error;
-
-	spin_lock(&simple_dev_list_lock);
-	list_add(&s_dev->node, &simple_dev_list);
-	spin_unlock(&simple_dev_list_lock);
-
-	return &s_dev->class_dev;
-
-error:
-	kfree(s_dev);
-	return ERR_PTR(retval);
-}
-EXPORT_SYMBOL(class_simple_device_add);
-
-/**
- * class_simple_set_hotplug - set the hotplug callback in the embedded struct class
- * @cs: pointer to the struct class_simple to hold the pointer
- * @hotplug: function pointer to the hotplug function
- *
- * Implement and set a hotplug function to add environment variables specific to this
- * class on the hotplug event.
- */
-int class_simple_set_hotplug(struct class_simple *cs,
-	int (*hotplug)(struct class_device *dev, char **envp, int num_envp, char *buffer, int buffer_size))
-{
-	if ((cs == NULL) || (IS_ERR(cs)))
-		return -ENODEV;
-	cs->class.hotplug = hotplug;
-	return 0;
-}
-EXPORT_SYMBOL(class_simple_set_hotplug);
-
-/**
- * class_simple_device_remove - removes a class device that was created with class_simple_device_add()
- * @dev: the dev_t of the device that was previously registered.
- *
- * This call unregisters and cleans up a class device that was created with a
- * call to class_device_simple_add()
- */
-void class_simple_device_remove(dev_t dev)
-{
-	struct simple_dev *s_dev = NULL;
-	int found = 0;
-
-	spin_lock(&simple_dev_list_lock);
-	list_for_each_entry(s_dev, &simple_dev_list, node) {
-		if (s_dev->class_dev.devt == dev) {
-			found = 1;
-			break;
-		}
-	}
-	if (found) {
-		list_del(&s_dev->node);
-		spin_unlock(&simple_dev_list_lock);
-		class_device_unregister(&s_dev->class_dev);
-	} else {
-		spin_unlock(&simple_dev_list_lock);
-	}
-}
-EXPORT_SYMBOL(class_simple_device_remove);
diff --git a/drivers/base/core.c b/drivers/base/core.c
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -36,10 +36,10 @@ dev_attr_show(struct kobject * kobj, str
 {
 	struct device_attribute * dev_attr = to_dev_attr(attr);
 	struct device * dev = to_dev(kobj);
-	ssize_t ret = 0;
+	ssize_t ret = -EIO;
 
 	if (dev_attr->show)
-		ret = dev_attr->show(dev, buf);
+		ret = dev_attr->show(dev, dev_attr, buf);
 	return ret;
 }
 
@@ -49,10 +49,10 @@ dev_attr_store(struct kobject * kobj, st
 {
 	struct device_attribute * dev_attr = to_dev_attr(attr);
 	struct device * dev = to_dev(kobj);
-	ssize_t ret = 0;
+	ssize_t ret = -EIO;
 
 	if (dev_attr->store)
-		ret = dev_attr->store(dev, buf, count);
+		ret = dev_attr->store(dev, dev_attr, buf, count);
 	return ret;
 }
 
@@ -102,7 +102,7 @@ static int dev_hotplug_filter(struct kse
 	return 0;
 }
 
-static char *dev_hotplug_name(struct kset *kset, struct kobject *kobj)
+static const char *dev_hotplug_name(struct kset *kset, struct kobject *kobj)
 {
 	struct device *dev = to_dev(kobj);
 
@@ -207,11 +207,9 @@ void device_initialize(struct device *de
 {
 	kobj_set_kset_s(dev, devices_subsys);
 	kobject_init(&dev->kobj);
-	INIT_LIST_HEAD(&dev->node);
-	INIT_LIST_HEAD(&dev->children);
-	INIT_LIST_HEAD(&dev->driver_list);
-	INIT_LIST_HEAD(&dev->bus_list);
+	klist_init(&dev->klist_children);
 	INIT_LIST_HEAD(&dev->dma_pools);
+	init_MUTEX(&dev->sem);
 }
 
 /**
@@ -250,10 +248,8 @@ int device_add(struct device *dev)
 		goto PMError;
 	if ((error = bus_add_device(dev)))
 		goto BusError;
-	down_write(&devices_subsys.rwsem);
 	if (parent)
-		list_add_tail(&dev->node, &parent->children);
-	up_write(&devices_subsys.rwsem);
+		klist_add_tail(&parent->klist_children, &dev->knode_parent);
 
 	/* notify platform of device entry */
 	if (platform_notify)
@@ -336,10 +332,8 @@ void device_del(struct device * dev)
 {
 	struct device * parent = dev->parent;
 
-	down_write(&devices_subsys.rwsem);
 	if (parent)
-		list_del_init(&dev->node);
-	up_write(&devices_subsys.rwsem);
+		klist_del(&dev->knode_parent);
 
 	/* Notify the platform of the removal, in case they
 	 * need to do anything...
@@ -373,6 +367,12 @@ void device_unregister(struct device * d
 }
 
 
+static struct device * next_device(struct klist_iter * i)
+{
+	struct klist_node * n = klist_next(i);
+	return n ? container_of(n, struct device, knode_parent) : NULL;
+}
+
 /**
  *	device_for_each_child - device child iterator.
  *	@dev:	parent struct device.
@@ -385,39 +385,20 @@ void device_unregister(struct device * d
  *	We check the return of @fn each time. If it returns anything
  *	other than 0, we break out and return that value.
  */
-int device_for_each_child(struct device * dev, void * data,
+int device_for_each_child(struct device * parent, void * data,
 		     int (*fn)(struct device *, void *))
 {
+	struct klist_iter i;
 	struct device * child;
 	int error = 0;
 
-	down_read(&devices_subsys.rwsem);
-	list_for_each_entry(child, &dev->children, node) {
-		if((error = fn(child, data)))
-			break;
-	}
-	up_read(&devices_subsys.rwsem);
+	klist_iter_init(&parent->klist_children, &i);
+	while ((child = next_device(&i)) && !error)
+		error = fn(child, data);
+	klist_iter_exit(&i);
 	return error;
 }
 
-/**
- *	device_find - locate device on a bus by name.
- *	@name:	name of the device.
- *	@bus:	bus to scan for the device.
- *
- *	Call kset_find_obj() to iterate over list of devices on
- *	a bus to find device by name. Return device if found.
- *
- *	Note that kset_find_obj increments device's reference count.
- */
-struct device *device_find(const char *name, struct bus_type *bus)
-{
-	struct kobject *k = kset_find_obj(&bus->devices, name);
-	if (k)
-		return to_dev(k);
-	return NULL;
-}
-
 int __init devices_init(void)
 {
 	return subsystem_register(&devices_subsys);
@@ -433,7 +414,6 @@ EXPORT_SYMBOL_GPL(device_del);
 EXPORT_SYMBOL_GPL(device_unregister);
 EXPORT_SYMBOL_GPL(get_device);
 EXPORT_SYMBOL_GPL(put_device);
-EXPORT_SYMBOL_GPL(device_find);
 
 EXPORT_SYMBOL_GPL(device_create_file);
 EXPORT_SYMBOL_GPL(device_remove_file);
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c
--- a/drivers/base/cpu.c
+++ b/drivers/base/cpu.c
@@ -16,6 +16,11 @@ struct sysdev_class cpu_sysdev_class = {
 EXPORT_SYMBOL(cpu_sysdev_class);
 
 #ifdef CONFIG_HOTPLUG_CPU
+int __attribute__((weak)) smp_prepare_cpu (int cpu)
+{
+	return 0;
+}
+
 static ssize_t show_online(struct sys_device *dev, char *buf)
 {
 	struct cpu *cpu = container_of(dev, struct cpu, sysdev);
@@ -36,7 +41,11 @@ static ssize_t store_online(struct sys_d
 			kobject_hotplug(&dev->kobj, KOBJ_OFFLINE);
 		break;
 	case '1':
-		ret = cpu_up(cpu->sysdev.id);
+		ret = smp_prepare_cpu(cpu->sysdev.id);
+		if (!ret)
+			ret = cpu_up(cpu->sysdev.id);
+		if (!ret)
+			kobject_hotplug(&dev->kobj, KOBJ_ONLINE);
 		break;
 	default:
 		ret = -EINVAL;
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
new file mode 100644
--- /dev/null
+++ b/drivers/base/dd.c
@@ -0,0 +1,248 @@
+/*
+ *	drivers/base/dd.c - The core device/driver interactions.
+ *
+ * 	This file contains the (sometimes tricky) code that controls the
+ *	interactions between devices and drivers, which primarily includes
+ *	driver binding and unbinding.
+ *
+ *	All of this code used to exist in drivers/base/bus.c, but was
+ *	relocated to here in the name of compartmentalization (since it wasn't
+ *	strictly code just for the 'struct bus_type'.
+ *
+ *	Copyright (c) 2002-5 Patrick Mochel
+ *	Copyright (c) 2002-3 Open Source Development Labs
+ *
+ *	This file is released under the GPLv2
+ */
+
+#include <linux/device.h>
+#include <linux/module.h>
+
+#include "base.h"
+#include "power/power.h"
+
+#define to_drv(node) container_of(node, struct device_driver, kobj.entry)
+
+
+/**
+ *	device_bind_driver - bind a driver to one device.
+ *	@dev:	device.
+ *
+ *	Allow manual attachment of a driver to a device.
+ *	Caller must have already set @dev->driver.
+ *
+ *	Note that this does not modify the bus reference count
+ *	nor take the bus's rwsem. Please verify those are accounted
+ *	for before calling this. (It is ok to call with no other effort
+ *	from a driver's probe() method.)
+ *
+ *	This function must be called with @dev->sem held.
+ */
+void device_bind_driver(struct device * dev)
+{
+	pr_debug("bound device '%s' to driver '%s'\n",
+		 dev->bus_id, dev->driver->name);
+	klist_add_tail(&dev->driver->klist_devices, &dev->knode_driver);
+	sysfs_create_link(&dev->driver->kobj, &dev->kobj,
+			  kobject_name(&dev->kobj));
+	sysfs_create_link(&dev->kobj, &dev->driver->kobj, "driver");
+}
+
+/**
+ *	driver_probe_device - attempt to bind device & driver.
+ *	@drv:	driver.
+ *	@dev:	device.
+ *
+ *	First, we call the bus's match function, if one present, which
+ *	should compare the device IDs the driver supports with the
+ *	device IDs of the device. Note we don't do this ourselves
+ *	because we don't know the format of the ID structures, nor what
+ *	is to be considered a match and what is not.
+ *
+ *
+ *	This function returns 1 if a match is found, an error if one
+ *	occurs (that is not -ENODEV or -ENXIO), and 0 otherwise.
+ *
+ *	This function must be called with @dev->sem held.
+ */
+int driver_probe_device(struct device_driver * drv, struct device * dev)
+{
+	int ret = 0;
+
+	if (drv->bus->match && !drv->bus->match(dev, drv))
+		goto Done;
+
+	pr_debug("%s: Matched Device %s with Driver %s\n",
+		 drv->bus->name, dev->bus_id, drv->name);
+	dev->driver = drv;
+	if (drv->probe) {
+		ret = drv->probe(dev);
+		if (ret) {
+			dev->driver = NULL;
+			goto ProbeFailed;
+		}
+	}
+	device_bind_driver(dev);
+	ret = 1;
+	pr_debug("%s: Bound Device %s to Driver %s\n",
+		 drv->bus->name, dev->bus_id, drv->name);
+	goto Done;
+
+ ProbeFailed:
+	if (ret == -ENODEV || ret == -ENXIO) {
+		/* Driver matched, but didn't support device
+		 * or device not found.
+		 * Not an error; keep going.
+		 */
+		ret = 0;
+	} else {
+		/* driver matched but the probe failed */
+		printk(KERN_WARNING
+		       "%s: probe of %s failed with error %d\n",
+		       drv->name, dev->bus_id, ret);
+	}
+ Done:
+	return ret;
+}
+
+static int __device_attach(struct device_driver * drv, void * data)
+{
+	struct device * dev = data;
+	return driver_probe_device(drv, dev);
+}
+
+/**
+ *	device_attach - try to attach device to a driver.
+ *	@dev:	device.
+ *
+ *	Walk the list of drivers that the bus has and call
+ *	driver_probe_device() for each pair. If a compatible
+ *	pair is found, break out and return.
+ *
+ *	Returns 1 if the device was bound to a driver;
+ *	0 if no matching device was found; error code otherwise.
+ */
+int device_attach(struct device * dev)
+{
+	int ret = 0;
+
+	down(&dev->sem);
+	if (dev->driver) {
+		device_bind_driver(dev);
+		ret = 1;
+	} else
+		ret = bus_for_each_drv(dev->bus, NULL, dev, __device_attach);
+	up(&dev->sem);
+	return ret;
+}
+
+static int __driver_attach(struct device * dev, void * data)
+{
+	struct device_driver * drv = data;
+
+	/*
+	 * Lock device and try to bind to it. We drop the error
+	 * here and always return 0, because we need to keep trying
+	 * to bind to devices and some drivers will return an error
+	 * simply if it didn't support the device.
+	 *
+	 * driver_probe_device() will spit a warning if there
+	 * is an error.
+	 */
+
+	down(&dev->sem);
+	if (!dev->driver)
+		driver_probe_device(drv, dev);
+	up(&dev->sem);
+
+
+	return 0;
+}
+
+/**
+ *	driver_attach - try to bind driver to devices.
+ *	@drv:	driver.
+ *
+ *	Walk the list of devices that the bus has on it and try to
+ *	match the driver with each one.  If driver_probe_device()
+ *	returns 0 and the @dev->driver is set, we've found a
+ *	compatible pair.
+ */
+void driver_attach(struct device_driver * drv)
+{
+	bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);
+}
+
+/**
+ *	device_release_driver - manually detach device from driver.
+ *	@dev:	device.
+ *
+ *	Manually detach device from driver.
+ *
+ *	__device_release_driver() must be called with @dev->sem held.
+ */
+
+static void __device_release_driver(struct device * dev)
+{
+	struct device_driver * drv;
+
+	drv = dev->driver;
+	if (drv) {
+		get_driver(drv);
+		sysfs_remove_link(&drv->kobj, kobject_name(&dev->kobj));
+		sysfs_remove_link(&dev->kobj, "driver");
+		klist_remove(&dev->knode_driver);
+
+		if (drv->remove)
+			drv->remove(dev);
+		dev->driver = NULL;
+		put_driver(drv);
+	}
+}
+
+void device_release_driver(struct device * dev)
+{
+	/*
+	 * If anyone calls device_release_driver() recursively from
+	 * within their ->remove callback for the same device, they
+	 * will deadlock right here.
+	 */
+	down(&dev->sem);
+	__device_release_driver(dev);
+	up(&dev->sem);
+}
+
+
+/**
+ * driver_detach - detach driver from all devices it controls.
+ * @drv: driver.
+ */
+void driver_detach(struct device_driver * drv)
+{
+	struct device * dev;
+
+	for (;;) {
+		spin_lock_irq(&drv->klist_devices.k_lock);
+		if (list_empty(&drv->klist_devices.k_list)) {
+			spin_unlock_irq(&drv->klist_devices.k_lock);
+			break;
+		}
+		dev = list_entry(drv->klist_devices.k_list.prev,
+				struct device, knode_driver.n_node);
+		get_device(dev);
+		spin_unlock_irq(&drv->klist_devices.k_lock);
+
+		down(&dev->sem);
+		if (dev->driver == drv)
+			__device_release_driver(dev);
+		up(&dev->sem);
+		put_device(dev);
+	}
+}
+
+
+EXPORT_SYMBOL_GPL(device_bind_driver);
+EXPORT_SYMBOL_GPL(device_release_driver);
+EXPORT_SYMBOL_GPL(device_attach);
+EXPORT_SYMBOL_GPL(driver_attach);
+
diff --git a/drivers/base/dmapool.c b/drivers/base/dmapool.c
--- a/drivers/base/dmapool.c
+++ b/drivers/base/dmapool.c
@@ -41,7 +41,7 @@ struct dma_page {	/* cacheable header fo
 static DECLARE_MUTEX (pools_lock);
 
 static ssize_t
-show_pools (struct device *dev, char *buf)
+show_pools (struct device *dev, struct device_attribute *attr, char *buf)
 {
 	unsigned temp;
 	unsigned size;
diff --git a/drivers/base/driver.c b/drivers/base/driver.c
--- a/drivers/base/driver.c
+++ b/drivers/base/driver.c
@@ -18,6 +18,78 @@
 #define to_dev(node) container_of(node, struct device, driver_list)
 #define to_drv(obj) container_of(obj, struct device_driver, kobj)
 
+
+static struct device * next_device(struct klist_iter * i)
+{
+	struct klist_node * n = klist_next(i);
+	return n ? container_of(n, struct device, knode_driver) : NULL;
+}
+
+/**
+ *	driver_for_each_device - Iterator for devices bound to a driver.
+ *	@drv:	Driver we're iterating.
+ *	@data:	Data to pass to the callback.
+ *	@fn:	Function to call for each device.
+ *
+ *	Iterate over the @drv's list of devices calling @fn for each one.
+ */
+
+int driver_for_each_device(struct device_driver * drv, struct device * start, 
+			   void * data, int (*fn)(struct device *, void *))
+{
+	struct klist_iter i;
+	struct device * dev;
+	int error = 0;
+
+	if (!drv)
+		return -EINVAL;
+
+	klist_iter_init_node(&drv->klist_devices, &i,
+			     start ? &start->knode_driver : NULL);
+	while ((dev = next_device(&i)) && !error)
+		error = fn(dev, data);
+	klist_iter_exit(&i);
+	return error;
+}
+
+EXPORT_SYMBOL_GPL(driver_for_each_device);
+
+
+/**
+ * driver_find_device - device iterator for locating a particular device.
+ * @driver: The device's driver
+ * @start: Device to begin with
+ * @data: Data to pass to match function
+ * @match: Callback function to check device
+ *
+ * This is similar to the driver_for_each_device() function above, but
+ * it returns a reference to a device that is 'found' for later use, as
+ * determined by the @match callback.
+ *
+ * The callback should return 0 if the device doesn't match and non-zero
+ * if it does.  If the callback returns non-zero, this function will
+ * return to the caller and not iterate over any more devices.
+ */
+struct device * driver_find_device(struct device_driver *drv,
+				   struct device * start, void * data,
+				   int (*match)(struct device *, void *))
+{
+	struct klist_iter i;
+	struct device *dev;
+
+	if (!drv)
+		return NULL;
+
+	klist_iter_init_node(&drv->klist_devices, &i,
+			     (start ? &start->knode_driver : NULL));
+	while ((dev = next_device(&i)))
+		if (match(dev, data) && get_device(dev))
+			break;
+	klist_iter_exit(&i);
+	return dev;
+}
+EXPORT_SYMBOL_GPL(driver_find_device);
+
 /**
  *	driver_create_file - create sysfs file for driver.
  *	@drv:	driver.
@@ -85,7 +157,7 @@ void put_driver(struct device_driver * d
  */
 int driver_register(struct device_driver * drv)
 {
-	INIT_LIST_HEAD(&drv->devices);
+	klist_init(&drv->klist_devices);
 	init_completion(&drv->unloaded);
 	return bus_add_driver(drv);
 }
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -74,6 +74,8 @@ static ssize_t
 firmware_timeout_store(struct class *class, const char *buf, size_t count)
 {
 	loading_timeout = simple_strtol(buf, NULL, 10);
+	if (loading_timeout < 0)
+		loading_timeout = 0;
 	return count;
 }
 
@@ -138,6 +140,10 @@ firmware_loading_store(struct class_devi
 	switch (loading) {
 	case 1:
 		down(&fw_lock);
+		if (!fw_priv->fw) {
+			up(&fw_lock);
+			break;
+		}
 		vfree(fw_priv->fw->data);
 		fw_priv->fw->data = NULL;
 		fw_priv->fw->size = 0;
@@ -178,7 +184,7 @@ firmware_data_read(struct kobject *kobj,
 
 	down(&fw_lock);
 	fw = fw_priv->fw;
-	if (test_bit(FW_STATUS_DONE, &fw_priv->status)) {
+	if (!fw || test_bit(FW_STATUS_DONE, &fw_priv->status)) {
 		ret_count = -ENODEV;
 		goto out;
 	}
@@ -238,9 +244,10 @@ firmware_data_write(struct kobject *kobj
 
 	if (!capable(CAP_SYS_RAWIO))
 		return -EPERM;
+
 	down(&fw_lock);
 	fw = fw_priv->fw;
-	if (test_bit(FW_STATUS_DONE, &fw_priv->status)) {
+	if (!fw || test_bit(FW_STATUS_DONE, &fw_priv->status)) {
 		retval = -ENODEV;
 		goto out;
 	}
@@ -418,7 +425,7 @@ request_firmware(const struct firmware *
 
 	fw_priv = class_get_devdata(class_dev);
 
-	if (loading_timeout) {
+	if (loading_timeout > 0) {
 		fw_priv->timeout.expires = jiffies + loading_timeout * HZ;
 		add_timer(&fw_priv->timeout);
 	}
diff --git a/drivers/base/node.c b/drivers/base/node.c
--- a/drivers/base/node.c
+++ b/drivers/base/node.c
@@ -87,7 +87,7 @@ static ssize_t node_read_numastat(struct
 	for (i = 0; i < MAX_NR_ZONES; i++) {
 		struct zone *z = &pg->node_zones[i];
 		for (cpu = 0; cpu < NR_CPUS; cpu++) {
-			struct per_cpu_pageset *ps = &z->pageset[cpu];
+			struct per_cpu_pageset *ps = zone_pcp(z,cpu);
 			numa_hit += ps->numa_hit;
 			numa_miss += ps->numa_miss;
 			numa_foreign += ps->numa_foreign;
@@ -136,7 +136,7 @@ static SYSDEV_ATTR(distance, S_IRUGO, no
  *
  * Initialize and register the node device.
  */
-int __init register_node(struct node *node, int num, struct node *parent)
+int register_node(struct node *node, int num, struct node *parent)
 {
 	int error;
 
@@ -153,8 +153,24 @@ int __init register_node(struct node *no
 	return error;
 }
 
+/**
+ * unregister_node - unregister a node device
+ * @node: node going away
+ *
+ * Unregisters a node device @node.  All the devices on the node must be
+ * unregistered before calling this function.
+ */
+void unregister_node(struct node *node)
+{
+	sysdev_remove_file(&node->sysdev, &attr_cpumap);
+	sysdev_remove_file(&node->sysdev, &attr_meminfo);
+	sysdev_remove_file(&node->sysdev, &attr_numastat);
+	sysdev_remove_file(&node->sysdev, &attr_distance);
+
+	sysdev_unregister(&node->sysdev);
+}
 
-int __init register_node_type(void)
+static int __init register_node_type(void)
 {
 	return sysdev_class_register(&node_class);
 }
diff --git a/drivers/base/power/resume.c b/drivers/base/power/resume.c
--- a/drivers/base/power/resume.c
+++ b/drivers/base/power/resume.c
@@ -22,6 +22,9 @@ extern int sysdev_resume(void);
 
 int resume_device(struct device * dev)
 {
+	int error = 0;
+
+	down(&dev->sem);
 	if (dev->power.pm_parent
 			&& dev->power.pm_parent->power.power_state) {
 		dev_err(dev, "PM: resume from %d, parent %s still %d\n",
@@ -31,9 +34,10 @@ int resume_device(struct device * dev)
 	}
 	if (dev->bus && dev->bus->resume) {
 		dev_dbg(dev,"resuming\n");
-		return dev->bus->resume(dev);
+		error = dev->bus->resume(dev);
 	}
-	return 0;
+	up(&dev->sem);
+	return error;
 }
 
 
diff --git a/drivers/base/power/suspend.c b/drivers/base/power/suspend.c
--- a/drivers/base/power/suspend.c
+++ b/drivers/base/power/suspend.c
@@ -39,6 +39,7 @@ int suspend_device(struct device * dev, 
 {
 	int error = 0;
 
+	down(&dev->sem);
 	if (dev->power.power_state) {
 		dev_dbg(dev, "PM: suspend %d-->%d\n",
 			dev->power.power_state, state);
@@ -58,7 +59,7 @@ int suspend_device(struct device * dev, 
 		dev_dbg(dev, "suspending\n");
 		error = dev->bus->suspend(dev, state);
 	}
-
+	up(&dev->sem);
 	return error;
 }
 
@@ -113,8 +114,19 @@ int device_suspend(pm_message_t state)
 		put_device(dev);
 	}
 	up(&dpm_list_sem);
-	if (error)
+	if (error) {
+		/* we failed... before resuming, bring back devices from
+		 * dpm_off_irq list back to main dpm_off list, we do want
+		 * to call resume() on them, in case they partially suspended
+		 * despite returning -EAGAIN
+		 */
+		while (!list_empty(&dpm_off_irq)) {
+			struct list_head * entry = dpm_off_irq.next;
+			list_del(entry);
+			list_add(entry, &dpm_off);
+		}
 		dpm_resume();
+	}
 	up(&dpm_sem);
 	return error;
 }
diff --git a/drivers/base/power/sysfs.c b/drivers/base/power/sysfs.c
--- a/drivers/base/power/sysfs.c
+++ b/drivers/base/power/sysfs.c
@@ -24,12 +24,12 @@
  *	low-power state.
  */
 
-static ssize_t state_show(struct device * dev, char * buf)
+static ssize_t state_show(struct device * dev, struct device_attribute *attr, char * buf)
 {
 	return sprintf(buf, "%u\n", dev->power.power_state);
 }
 
-static ssize_t state_store(struct device * dev, const char * buf, size_t n)
+static ssize_t state_store(struct device * dev, struct device_attribute *attr, const char * buf, size_t n)
 {
 	u32 state;
 	char * rest;
diff --git a/drivers/base/sys.c b/drivers/base/sys.c
--- a/drivers/base/sys.c
+++ b/drivers/base/sys.c
@@ -22,7 +22,6 @@
 #include <linux/string.h>
 #include <linux/pm.h>
 
-
 extern struct subsystem devices_subsys;
 
 #define to_sysdev(k) container_of(k, struct sys_device, kobj)
@@ -37,7 +36,7 @@ sysdev_show(struct kobject * kobj, struc
 
 	if (sysdev_attr->show)
 		return sysdev_attr->show(sysdev, buffer);
-	return 0;
+	return -EIO;
 }
 
 
@@ -50,7 +49,7 @@ sysdev_store(struct kobject * kobj, stru
 
 	if (sysdev_attr->store)
 		return sysdev_attr->store(sysdev, buffer, count);
-	return 0;
+	return -EIO;
 }
 
 static struct sysfs_ops sysfs_ops = {
diff --git a/drivers/block/aoe/aoechr.c b/drivers/block/aoe/aoechr.c
--- a/drivers/block/aoe/aoechr.c
+++ b/drivers/block/aoe/aoechr.c
@@ -36,7 +36,7 @@ static int emsgs_head_idx, emsgs_tail_id
 static struct semaphore emsgs_sema;
 static spinlock_t emsgs_lock;
 static int nblocked_emsgs_readers;
-static struct class_simple *aoe_class;
+static struct class *aoe_class;
 static struct aoe_chardev chardevs[] = {
 	{ MINOR_ERR, "err" },
 	{ MINOR_DISCOVER, "discover" },
@@ -218,13 +218,13 @@ aoechr_init(void)
 	}
 	sema_init(&emsgs_sema, 0);
 	spin_lock_init(&emsgs_lock);
-	aoe_class = class_simple_create(THIS_MODULE, "aoe");
+	aoe_class = class_create(THIS_MODULE, "aoe");
 	if (IS_ERR(aoe_class)) {
 		unregister_chrdev(AOE_MAJOR, "aoechr");
 		return PTR_ERR(aoe_class);
 	}
 	for (i = 0; i < ARRAY_SIZE(chardevs); ++i)
-		class_simple_device_add(aoe_class,
+		class_device_create(aoe_class,
 					MKDEV(AOE_MAJOR, chardevs[i].minor),
 					NULL, chardevs[i].name);
 
@@ -237,8 +237,8 @@ aoechr_exit(void)
 	int i;
 
 	for (i = 0; i < ARRAY_SIZE(chardevs); ++i)
-		class_simple_device_remove(MKDEV(AOE_MAJOR, chardevs[i].minor));
-	class_simple_destroy(aoe_class);
+		class_device_destroy(aoe_class, MKDEV(AOE_MAJOR, chardevs[i].minor));
+	class_destroy(aoe_class);
 	unregister_chrdev(AOE_MAJOR, "aoechr");
 }
 
diff --git a/drivers/block/as-iosched.c b/drivers/block/as-iosched.c
--- a/drivers/block/as-iosched.c
+++ b/drivers/block/as-iosched.c
@@ -1806,7 +1806,8 @@ static void as_put_request(request_queue
 	rq->elevator_private = NULL;
 }
 
-static int as_set_request(request_queue_t *q, struct request *rq, int gfp_mask)
+static int as_set_request(request_queue_t *q, struct request *rq,
+			  struct bio *bio, int gfp_mask)
 {
 	struct as_data *ad = q->elevator->elevator_data;
 	struct as_rq *arq = mempool_alloc(ad->arq_pool, gfp_mask);
@@ -1827,7 +1828,7 @@ static int as_set_request(request_queue_
 	return 1;
 }
 
-static int as_may_queue(request_queue_t *q, int rw)
+static int as_may_queue(request_queue_t *q, int rw, struct bio *bio)
 {
 	int ret = ELV_MQUEUE_MAY;
 	struct as_data *ad = q->elevator->elevator_data;
@@ -1871,20 +1872,22 @@ static int as_init_queue(request_queue_t
 	if (!arq_pool)
 		return -ENOMEM;
 
-	ad = kmalloc(sizeof(*ad), GFP_KERNEL);
+	ad = kmalloc_node(sizeof(*ad), GFP_KERNEL, q->node);
 	if (!ad)
 		return -ENOMEM;
 	memset(ad, 0, sizeof(*ad));
 
 	ad->q = q; /* Identify what queue the data belongs to */
 
-	ad->hash = kmalloc(sizeof(struct list_head)*AS_HASH_ENTRIES,GFP_KERNEL);
+	ad->hash = kmalloc_node(sizeof(struct list_head)*AS_HASH_ENTRIES,
+				GFP_KERNEL, q->node);
 	if (!ad->hash) {
 		kfree(ad);
 		return -ENOMEM;
 	}
 
-	ad->arq_pool = mempool_create(BLKDEV_MIN_RQ, mempool_alloc_slab, mempool_free_slab, arq_pool);
+	ad->arq_pool = mempool_create_node(BLKDEV_MIN_RQ, mempool_alloc_slab,
+				mempool_free_slab, arq_pool, q->node);
 	if (!ad->arq_pool) {
 		kfree(ad->hash);
 		kfree(ad);
@@ -1932,23 +1935,15 @@ struct as_fs_entry {
 static ssize_t
 as_var_show(unsigned int var, char *page)
 {
-	var = (var * 1000) / HZ;
 	return sprintf(page, "%d\n", var);
 }
 
 static ssize_t
 as_var_store(unsigned long *var, const char *page, size_t count)
 {
-	unsigned long tmp;
 	char *p = (char *) page;
 
-	tmp = simple_strtoul(p, &p, 10);
-	if (tmp != 0) {
-		tmp = (tmp * HZ) / 1000;
-		if (tmp == 0)
-			tmp = 1;
-	}
-	*var = tmp;
+	*var = simple_strtoul(p, &p, 10);
 	return count;
 }
 
@@ -2044,7 +2039,7 @@ as_attr_show(struct kobject *kobj, struc
 	struct as_fs_entry *entry = to_as(attr);
 
 	if (!entry->show)
-		return 0;
+		return -EIO;
 
 	return entry->show(e->elevator_data, page);
 }
@@ -2057,7 +2052,7 @@ as_attr_store(struct kobject *kobj, stru
 	struct as_fs_entry *entry = to_as(attr);
 
 	if (!entry->store)
-		return -EINVAL;
+		return -EIO;
 
 	return entry->store(e->elevator_data, page, length);
 }
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -1,6 +1,6 @@
 /*
  *    Disk Array driver for HP SA 5xxx and 6xxx Controllers
- *    Copyright 2000, 2002 Hewlett-Packard Development Company, L.P.
+ *    Copyright 2000, 2005 Hewlett-Packard Development Company, L.P.
  *
  *    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
@@ -41,6 +41,7 @@
 #include <asm/uaccess.h>
 #include <asm/io.h>
 
+#include <linux/dma-mapping.h>
 #include <linux/blkdev.h>
 #include <linux/genhd.h>
 #include <linux/completion.h>
@@ -53,7 +54,7 @@
 MODULE_AUTHOR("Hewlett-Packard Company");
 MODULE_DESCRIPTION("Driver for HP Controller SA5xxx SA6xxx version 2.6.6");
 MODULE_SUPPORTED_DEVICE("HP SA5i SA5i+ SA532 SA5300 SA5312 SA641 SA642 SA6400"
-			" SA6i P600 P800 E400");
+			" SA6i P600 P800 E400 E300");
 MODULE_LICENSE("GPL");
 
 #include "cciss_cmd.h"
@@ -84,8 +85,10 @@ static const struct pci_device_id cciss_
 		0x103C, 0x3225, 0, 0, 0},
 	{ PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSB,
 		0x103c, 0x3223, 0, 0, 0},
-	{ PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSB,
+	{ PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSC,
 		0x103c, 0x3231, 0, 0, 0},
+	{ PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSC,
+		0x103c, 0x3233, 0, 0, 0},
 	{0,}
 };
 MODULE_DEVICE_TABLE(pci, cciss_pci_device_id);
@@ -109,6 +112,7 @@ static struct board_type products[] = {
 	{ 0x3225103C, "Smart Array P600", &SA5_access},
 	{ 0x3223103C, "Smart Array P800", &SA5_access},
 	{ 0x3231103C, "Smart Array E400", &SA5_access},
+	{ 0x3233103C, "Smart Array E300", &SA5_access},
 };
 
 /* How long to wait (in millesconds) for board to go into simple mode */
@@ -126,8 +130,6 @@ static struct board_type products[] = {
 #define MAX_CTLR_ORIG 	8
 
 
-#define CCISS_DMA_MASK	0xFFFFFFFF	/* 32 bit DMA */
-
 static ctlr_info_t *hba[MAX_CTLR];
 
 static void do_cciss_request(request_queue_t *q);
@@ -636,6 +638,7 @@ static int cciss_ioctl(struct inode *ino
 		cciss_pci_info_struct pciinfo;
 
 		if (!arg) return -EINVAL;
+		pciinfo.domain = pci_domain_nr(host->pdev->bus);
 		pciinfo.bus = host->pdev->bus->number;
 		pciinfo.dev_fn = host->pdev->devfn;
 		pciinfo.board_id = host->board_id;
@@ -783,18 +786,10 @@ static int cciss_ioctl(struct inode *ino
 
  	case CCISS_GETLUNINFO: {
  		LogvolInfo_struct luninfo;
- 		int i;
  		
  		luninfo.LunID = drv->LunID;
  		luninfo.num_opens = drv->usage_count;
  		luninfo.num_parts = 0;
- 		/* count partitions 1 to 15 with sizes > 0 */
- 		for (i = 0; i < MAX_PART - 1; i++) {
-			if (!disk->part[i])
-				continue;
-			if (disk->part[i]->nr_sects != 0)
-				luninfo.num_parts++;
-		}
  		if (copy_to_user(argp, &luninfo,
  				sizeof(LogvolInfo_struct)))
  			return -EFAULT;
@@ -1140,7 +1135,7 @@ static int revalidate_allvol(ctlr_info_t
 		/* this is for the online array utilities */
 		if (!drv->heads && i)
 			continue;
-		blk_queue_hardsect_size(host->queue, drv->block_size);
+		blk_queue_hardsect_size(drv->queue, drv->block_size);
 		set_capacity(disk, drv->nr_blocks);
 		add_disk(disk);
 	}
@@ -1696,7 +1691,7 @@ static int cciss_revalidate(struct gendi
 	cciss_read_capacity(h->ctlr, logvol, size_buff, 1, &total_size, &block_size);
 	cciss_geometry_inquiry(h->ctlr, logvol, 1, total_size, block_size, inq_buff, drv);
 
-	blk_queue_hardsect_size(h->queue, drv->block_size);
+	blk_queue_hardsect_size(drv->queue, drv->block_size);
 	set_capacity(disk, drv->nr_blocks);
 
 	kfree(size_buff);
@@ -2253,12 +2248,12 @@ static irqreturn_t do_cciss_intr(int irq
  	 * them up.  We will also keep track of the next queue to run so
  	 * that every queue gets a chance to be started first.
  	*/
- 	for (j=0; j < NWD; j++){
- 		int curr_queue = (start_queue + j) % NWD;
+	for (j=0; j < h->highest_lun + 1; j++){
+		int curr_queue = (start_queue + j) % (h->highest_lun + 1);
  		/* make sure the disk has been added and the drive is real
  		 * because this can be called from the middle of init_one.
  		*/
- 		if(!(h->gendisk[curr_queue]->queue) ||
+		if(!(h->drv[curr_queue].queue) ||
 		 		   !(h->drv[curr_queue].heads))
  			continue;
  		blk_start_queue(h->gendisk[curr_queue]->queue);
@@ -2269,14 +2264,14 @@ static irqreturn_t do_cciss_intr(int irq
  		if ((find_first_zero_bit(h->cmd_pool_bits, NR_CMDS)) == NR_CMDS)
  		{
  			if (curr_queue == start_queue){
- 				h->next_to_run = (start_queue + 1) % NWD;
+				h->next_to_run = (start_queue + 1) % (h->highest_lun + 1);
  				goto cleanup;
  			} else {
  				h->next_to_run = curr_queue;
  				goto cleanup;
  	}
  		} else {
- 			curr_queue = (curr_queue + 1) % NWD;
+			curr_queue = (curr_queue + 1) % (h->highest_lun + 1);
  		}
  	}
 
@@ -2284,7 +2279,6 @@ cleanup:
 	spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
 	return IRQ_HANDLED;
 }
-
 /* 
  *  We cannot read the structure directly, for portablity we must use 
  *   the io functions.
@@ -2393,11 +2387,6 @@ static int cciss_pci_init(ctlr_info_t *c
 		printk(KERN_ERR "cciss: Unable to Enable PCI device\n");
 		return( -1);
 	}
-	if (pci_set_dma_mask(pdev, CCISS_DMA_MASK ) != 0)
-	{
-		printk(KERN_ERR "cciss:  Unable to set DMA mask\n");
-		return(-1);
-	}
 
 	subsystem_vendor_id = pdev->subsystem_vendor;
 	subsystem_device_id = pdev->subsystem_device;
@@ -2747,9 +2736,9 @@ static int __devinit cciss_init_one(stru
 	hba[i]->pdev = pdev;
 
 	/* configure PCI DMA stuff */
-	if (!pci_set_dma_mask(pdev, 0xffffffffffffffffULL))
+	if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK))
 		printk("cciss: using DAC cycles\n");
-	else if (!pci_set_dma_mask(pdev, 0xffffffff))
+	else if (!pci_set_dma_mask(pdev, DMA_32BIT_MASK))
 		printk("cciss: not using DAC cycles\n");
 	else {
 		printk("cciss: no suitable DMA available\n");
@@ -2799,13 +2788,6 @@ static int __devinit cciss_init_one(stru
 	}
 
 	spin_lock_init(&hba[i]->lock);
-	q = blk_init_queue(do_cciss_request, &hba[i]->lock);
-	if (!q)
-		goto clean4;
-
-	q->backing_dev_info.ra_pages = READ_AHEAD;
-	hba[i]->queue = q;
-	q->queuedata = hba[i];
 
 	/* Initialize the pdev driver private data. 
 		have it point to hba[i].  */
@@ -2827,6 +2809,20 @@ static int __devinit cciss_init_one(stru
 
 	cciss_procinit(i);
 
+	for(j=0; j < NWD; j++) { /* mfm */
+		drive_info_struct *drv = &(hba[i]->drv[j]);
+		struct gendisk *disk = hba[i]->gendisk[j];
+
+		q = blk_init_queue(do_cciss_request, &hba[i]->lock);
+		if (!q) {
+			printk(KERN_ERR
+			   "cciss:  unable to allocate queue for disk %d\n",
+			   j);
+			break;
+		}
+		drv->queue = q;
+
+		q->backing_dev_info.ra_pages = READ_AHEAD;
 	blk_queue_bounce_limit(q, hba[i]->pdev->dma_mask);
 
 	/* This is a hardware imposed limit. */
@@ -2837,26 +2833,23 @@ static int __devinit cciss_init_one(stru
 
 	blk_queue_max_sectors(q, 512);
 
-
-	for(j=0; j<NWD; j++) {
-		drive_info_struct *drv = &(hba[i]->drv[j]);
-		struct gendisk *disk = hba[i]->gendisk[j];
-
+		q->queuedata = hba[i];
 		sprintf(disk->disk_name, "cciss/c%dd%d", i, j);
 		sprintf(disk->devfs_name, "cciss/host%d/target%d", i, j);
 		disk->major = hba[i]->major;
 		disk->first_minor = j << NWD_SHIFT;
 		disk->fops = &cciss_fops;
-		disk->queue = hba[i]->queue;
+		disk->queue = q;
 		disk->private_data = drv;
 		/* we must register the controller even if no disks exist */
 		/* this is for the online array utilities */
 		if(!drv->heads && j)
 			continue;
-		blk_queue_hardsect_size(hba[i]->queue, drv->block_size);
+		blk_queue_hardsect_size(q, drv->block_size);
 		set_capacity(disk, drv->nr_blocks);
 		add_disk(disk);
 	}
+
 	return(1);
 
 clean4:
@@ -2922,10 +2915,10 @@ static void __devexit cciss_remove_one (
 	for (j = 0; j < NWD; j++) {
 		struct gendisk *disk = hba[i]->gendisk[j];
 		if (disk->flags & GENHD_FL_UP)
+			blk_cleanup_queue(disk->queue);
 			del_gendisk(disk);
 	}
 
-	blk_cleanup_queue(hba[i]->queue);
 	pci_free_consistent(hba[i]->pdev, NR_CMDS * sizeof(CommandList_struct),
 			    hba[i]->cmd_pool, hba[i]->cmd_pool_dhandle);
 	pci_free_consistent(hba[i]->pdev, NR_CMDS * sizeof( ErrorInfo_struct),
diff --git a/drivers/block/cciss.h b/drivers/block/cciss.h
--- a/drivers/block/cciss.h
+++ b/drivers/block/cciss.h
@@ -29,6 +29,7 @@ typedef struct _drive_info_struct
 {
  	__u32   LunID;	
 	int 	usage_count;
+	struct request_queue *queue;
 	sector_t nr_blocks;
 	int	block_size;
 	int 	heads;
@@ -72,7 +73,6 @@ struct ctlr_info 
 	unsigned int maxQsinceinit;
 	unsigned int maxSG;
 	spinlock_t lock;
-	struct request_queue *queue;
 
 	//* pointers to command and error info pool */ 
 	CommandList_struct 	*cmd_pool;
@@ -260,7 +260,7 @@ struct board_type {
 	struct access_method *access;
 };
 
-#define CCISS_LOCK(i)	(hba[i]->queue->queue_lock)
+#define CCISS_LOCK(i)	(&hba[i]->lock)
 
 #endif /* CCISS_H */
 
diff --git a/drivers/block/cfq-iosched.c b/drivers/block/cfq-iosched.c
--- a/drivers/block/cfq-iosched.c
+++ b/drivers/block/cfq-iosched.c
@@ -21,22 +21,34 @@
 #include <linux/hash.h>
 #include <linux/rbtree.h>
 #include <linux/mempool.h>
-
-static unsigned long max_elapsed_crq;
-static unsigned long max_elapsed_dispatch;
+#include <linux/ioprio.h>
+#include <linux/writeback.h>
 
 /*
  * tunables
  */
 static int cfq_quantum = 4;		/* max queue in one round of service */
 static int cfq_queued = 8;		/* minimum rq allocate limit per-queue*/
-static int cfq_service = HZ;		/* period over which service is avg */
-static int cfq_fifo_expire_r = HZ / 2;	/* fifo timeout for sync requests */
-static int cfq_fifo_expire_w = 5 * HZ;	/* fifo timeout for async requests */
-static int cfq_fifo_rate = HZ / 8;	/* fifo expiry rate */
+static int cfq_fifo_expire[2] = { HZ / 4, HZ / 8 };
 static int cfq_back_max = 16 * 1024;	/* maximum backwards seek, in KiB */
 static int cfq_back_penalty = 2;	/* penalty of a backwards seek */
 
+static int cfq_slice_sync = HZ / 10;
+static int cfq_slice_async = HZ / 25;
+static int cfq_slice_async_rq = 2;
+static int cfq_slice_idle = HZ / 100;
+
+#define CFQ_IDLE_GRACE		(HZ / 10)
+#define CFQ_SLICE_SCALE		(5)
+
+#define CFQ_KEY_ASYNC		(0)
+#define CFQ_KEY_ANY		(0xffff)
+
+/*
+ * disable queueing at the driver/hardware level
+ */
+static int cfq_max_depth = 2;
+
 /*
  * for the hash of cfqq inside the cfqd
  */
@@ -55,6 +67,7 @@ static int cfq_back_penalty = 2;	/* pena
 #define list_entry_hash(ptr)	hlist_entry((ptr), struct cfq_rq, hash)
 
 #define list_entry_cfqq(ptr)	list_entry((ptr), struct cfq_queue, cfq_list)
+#define list_entry_fifo(ptr)	list_entry((ptr), struct request, queuelist)
 
 #define RQ_DATA(rq)		(rq)->elevator_private
 
@@ -75,78 +88,110 @@ static int cfq_back_penalty = 2;	/* pena
 #define rb_entry_crq(node)	rb_entry((node), struct cfq_rq, rb_node)
 #define rq_rb_key(rq)		(rq)->sector
 
-/*
- * threshold for switching off non-tag accounting
- */
-#define CFQ_MAX_TAG		(4)
-
-/*
- * sort key types and names
- */
-enum {
-	CFQ_KEY_PGID,
-	CFQ_KEY_TGID,
-	CFQ_KEY_UID,
-	CFQ_KEY_GID,
-	CFQ_KEY_LAST,
-};
-
-static char *cfq_key_types[] = { "pgid", "tgid", "uid", "gid", NULL };
-
 static kmem_cache_t *crq_pool;
 static kmem_cache_t *cfq_pool;
 static kmem_cache_t *cfq_ioc_pool;
 
+#define CFQ_PRIO_LISTS		IOPRIO_BE_NR
+#define cfq_class_idle(cfqq)	((cfqq)->ioprio_class == IOPRIO_CLASS_IDLE)
+#define cfq_class_be(cfqq)	((cfqq)->ioprio_class == IOPRIO_CLASS_BE)
+#define cfq_class_rt(cfqq)	((cfqq)->ioprio_class == IOPRIO_CLASS_RT)
+
+#define ASYNC			(0)
+#define SYNC			(1)
+
+#define cfq_cfqq_dispatched(cfqq)	\
+	((cfqq)->on_dispatch[ASYNC] + (cfqq)->on_dispatch[SYNC])
+
+#define cfq_cfqq_class_sync(cfqq)	((cfqq)->key != CFQ_KEY_ASYNC)
+
+#define cfq_cfqq_sync(cfqq)		\
+	(cfq_cfqq_class_sync(cfqq) || (cfqq)->on_dispatch[SYNC])
+
+/*
+ * Per block device queue structure
+ */
 struct cfq_data {
-	struct list_head rr_list;
+	atomic_t ref;
+	request_queue_t *queue;
+
+	/*
+	 * rr list of queues with requests and the count of them
+	 */
+	struct list_head rr_list[CFQ_PRIO_LISTS];
+	struct list_head busy_rr;
+	struct list_head cur_rr;
+	struct list_head idle_rr;
+	unsigned int busy_queues;
+
+	/*
+	 * non-ordered list of empty cfqq's
+	 */
 	struct list_head empty_list;
 
+	/*
+	 * cfqq lookup hash
+	 */
 	struct hlist_head *cfq_hash;
-	struct hlist_head *crq_hash;
 
-	/* queues on rr_list (ie they have pending requests */
-	unsigned int busy_queues;
+	/*
+	 * global crq hash for all queues
+	 */
+	struct hlist_head *crq_hash;
 
 	unsigned int max_queued;
 
-	atomic_t ref;
+	mempool_t *crq_pool;
 
-	int key_type;
+	int rq_in_driver;
 
-	mempool_t *crq_pool;
+	/*
+	 * schedule slice state info
+	 */
+	/*
+	 * idle window management
+	 */
+	struct timer_list idle_slice_timer;
+	struct work_struct unplug_work;
 
-	request_queue_t *queue;
+	struct cfq_queue *active_queue;
+	struct cfq_io_context *active_cic;
+	int cur_prio, cur_end_prio;
+	unsigned int dispatch_slice;
+
+	struct timer_list idle_class_timer;
 
 	sector_t last_sector;
+	unsigned long last_end_request;
 
-	int rq_in_driver;
+	unsigned int rq_starved;
 
 	/*
 	 * tunables, see top of file
 	 */
 	unsigned int cfq_quantum;
 	unsigned int cfq_queued;
-	unsigned int cfq_fifo_expire_r;
-	unsigned int cfq_fifo_expire_w;
-	unsigned int cfq_fifo_batch_expire;
+	unsigned int cfq_fifo_expire[2];
 	unsigned int cfq_back_penalty;
 	unsigned int cfq_back_max;
-	unsigned int find_best_crq;
-
-	unsigned int cfq_tagged;
+	unsigned int cfq_slice[2];
+	unsigned int cfq_slice_async_rq;
+	unsigned int cfq_slice_idle;
+	unsigned int cfq_max_depth;
 };
 
+/*
+ * Per process-grouping structure
+ */
 struct cfq_queue {
 	/* reference count */
 	atomic_t ref;
 	/* parent cfq_data */
 	struct cfq_data *cfqd;
-	/* hash of mergeable requests */
+	/* cfqq lookup hash */
 	struct hlist_node cfq_hash;
 	/* hash key */
-	unsigned long key;
-	/* whether queue is on rr (or empty) list */
-	int on_rr;
+	unsigned int key;
 	/* on either rr or empty list of cfqd */
 	struct list_head cfq_list;
 	/* sorted list of pending requests */
@@ -158,21 +203,22 @@ struct cfq_queue {
 	/* currently allocated requests */
 	int allocated[2];
 	/* fifo list of requests in sort_list */
-	struct list_head fifo[2];
-	/* last time fifo expired */
-	unsigned long last_fifo_expire;
+	struct list_head fifo;
 
-	int key_type;
+	unsigned long slice_start;
+	unsigned long slice_end;
+	unsigned long slice_left;
+	unsigned long service_last;
+
+	/* number of requests that are on the dispatch list */
+	int on_dispatch[2];
+
+	/* io prio of this group */
+	unsigned short ioprio, org_ioprio;
+	unsigned short ioprio_class, org_ioprio_class;
 
-	unsigned long service_start;
-	unsigned long service_used;
-
-	unsigned int max_rate;
-
-	/* number of requests that have been handed to the driver */
-	int in_flight;
-	/* number of currently allocated requests */
-	int alloc_limit[2];
+	/* various state flags, see below */
+	unsigned int flags;
 };
 
 struct cfq_rq {
@@ -184,42 +230,78 @@ struct cfq_rq {
 	struct cfq_queue *cfq_queue;
 	struct cfq_io_context *io_context;
 
-	unsigned long service_start;
-	unsigned long queue_start;
+	unsigned int crq_flags;
+};
+
+enum cfqq_state_flags {
+	CFQ_CFQQ_FLAG_on_rr = 0,
+	CFQ_CFQQ_FLAG_wait_request,
+	CFQ_CFQQ_FLAG_must_alloc,
+	CFQ_CFQQ_FLAG_must_alloc_slice,
+	CFQ_CFQQ_FLAG_must_dispatch,
+	CFQ_CFQQ_FLAG_fifo_expire,
+	CFQ_CFQQ_FLAG_idle_window,
+	CFQ_CFQQ_FLAG_prio_changed,
+	CFQ_CFQQ_FLAG_expired,
+};
+
+#define CFQ_CFQQ_FNS(name)						\
+static inline void cfq_mark_cfqq_##name(struct cfq_queue *cfqq)		\
+{									\
+	cfqq->flags |= (1 << CFQ_CFQQ_FLAG_##name);			\
+}									\
+static inline void cfq_clear_cfqq_##name(struct cfq_queue *cfqq)	\
+{									\
+	cfqq->flags &= ~(1 << CFQ_CFQQ_FLAG_##name);			\
+}									\
+static inline int cfq_cfqq_##name(const struct cfq_queue *cfqq)		\
+{									\
+	return (cfqq->flags & (1 << CFQ_CFQQ_FLAG_##name)) != 0;	\
+}
 
-	unsigned int in_flight : 1;
-	unsigned int accounted : 1;
-	unsigned int is_sync   : 1;
-	unsigned int is_write  : 1;
+CFQ_CFQQ_FNS(on_rr);
+CFQ_CFQQ_FNS(wait_request);
+CFQ_CFQQ_FNS(must_alloc);
+CFQ_CFQQ_FNS(must_alloc_slice);
+CFQ_CFQQ_FNS(must_dispatch);
+CFQ_CFQQ_FNS(fifo_expire);
+CFQ_CFQQ_FNS(idle_window);
+CFQ_CFQQ_FNS(prio_changed);
+CFQ_CFQQ_FNS(expired);
+#undef CFQ_CFQQ_FNS
+
+enum cfq_rq_state_flags {
+	CFQ_CRQ_FLAG_in_flight = 0,
+	CFQ_CRQ_FLAG_in_driver,
+	CFQ_CRQ_FLAG_is_sync,
+	CFQ_CRQ_FLAG_requeued,
 };
 
-static struct cfq_queue *cfq_find_cfq_hash(struct cfq_data *, unsigned long);
+#define CFQ_CRQ_FNS(name)						\
+static inline void cfq_mark_crq_##name(struct cfq_rq *crq)		\
+{									\
+	crq->crq_flags |= (1 << CFQ_CRQ_FLAG_##name);			\
+}									\
+static inline void cfq_clear_crq_##name(struct cfq_rq *crq)		\
+{									\
+	crq->crq_flags &= ~(1 << CFQ_CRQ_FLAG_##name);			\
+}									\
+static inline int cfq_crq_##name(const struct cfq_rq *crq)		\
+{									\
+	return (crq->crq_flags & (1 << CFQ_CRQ_FLAG_##name)) != 0;	\
+}
+
+CFQ_CRQ_FNS(in_flight);
+CFQ_CRQ_FNS(in_driver);
+CFQ_CRQ_FNS(is_sync);
+CFQ_CRQ_FNS(requeued);
+#undef CFQ_CRQ_FNS
+
+static struct cfq_queue *cfq_find_cfq_hash(struct cfq_data *, unsigned int, unsigned short);
 static void cfq_dispatch_sort(request_queue_t *, struct cfq_rq *);
-static void cfq_update_next_crq(struct cfq_rq *);
 static void cfq_put_cfqd(struct cfq_data *cfqd);
 
-/*
- * what the fairness is based on (ie how processes are grouped and
- * differentiated)
- */
-static inline unsigned long
-cfq_hash_key(struct cfq_data *cfqd, struct task_struct *tsk)
-{
-	/*
-	 * optimize this so that ->key_type is the offset into the struct
-	 */
-	switch (cfqd->key_type) {
-		case CFQ_KEY_PGID:
-			return process_group(tsk);
-		default:
-		case CFQ_KEY_TGID:
-			return tsk->tgid;
-		case CFQ_KEY_UID:
-			return tsk->uid;
-		case CFQ_KEY_GID:
-			return tsk->gid;
-	}
-}
+#define process_sync(tsk)	((tsk)->flags & PF_SYNCWRITE)
 
 /*
  * lots of deadline iosched dupes, can be abstracted later...
@@ -235,16 +317,12 @@ static void cfq_remove_merge_hints(reque
 
 	if (q->last_merge == crq->request)
 		q->last_merge = NULL;
-
-	cfq_update_next_crq(crq);
 }
 
 static inline void cfq_add_crq_hash(struct cfq_data *cfqd, struct cfq_rq *crq)
 {
 	const int hash_idx = CFQ_MHASH_FN(rq_hash_key(crq->request));
 
-	BUG_ON(!hlist_unhashed(&crq->hash));
-
 	hlist_add_head(&crq->hash, &cfqd->crq_hash[hash_idx]);
 }
 
@@ -257,8 +335,6 @@ static struct request *cfq_find_rq_hash(
 		struct cfq_rq *crq = list_entry_hash(entry);
 		struct request *__rq = crq->request;
 
-		BUG_ON(hlist_unhashed(&crq->hash));
-
 		if (!rq_mergeable(__rq)) {
 			cfq_del_crq_hash(crq);
 			continue;
@@ -271,6 +347,28 @@ static struct request *cfq_find_rq_hash(
 	return NULL;
 }
 
+static inline int cfq_pending_requests(struct cfq_data *cfqd)
+{
+	return !list_empty(&cfqd->queue->queue_head) || cfqd->busy_queues;
+}
+
+/*
+ * scheduler run of queue, if there are requests pending and no one in the
+ * driver that will restart queueing
+ */
+static inline void cfq_schedule_dispatch(struct cfq_data *cfqd)
+{
+	if (!cfqd->rq_in_driver && cfq_pending_requests(cfqd))
+		kblockd_schedule_work(&cfqd->unplug_work);
+}
+
+static int cfq_queue_empty(request_queue_t *q)
+{
+	struct cfq_data *cfqd = q->elevator->elevator_data;
+
+	return !cfq_pending_requests(cfqd);
+}
+
 /*
  * Lifted from AS - choose which of crq1 and crq2 that is best served now.
  * We choose the request that is closest to the head right now. Distance
@@ -288,35 +386,21 @@ cfq_choose_req(struct cfq_data *cfqd, st
 	if (crq2 == NULL)
 		return crq1;
 
+	if (cfq_crq_requeued(crq1) && !cfq_crq_requeued(crq2))
+		return crq1;
+	else if (cfq_crq_requeued(crq2) && !cfq_crq_requeued(crq1))
+		return crq2;
+
+	if (cfq_crq_is_sync(crq1) && !cfq_crq_is_sync(crq2))
+		return crq1;
+	else if (cfq_crq_is_sync(crq2) && !cfq_crq_is_sync(crq1))
+		return crq2;
+
 	s1 = crq1->request->sector;
 	s2 = crq2->request->sector;
 
 	last = cfqd->last_sector;
 
-#if 0
-	if (!list_empty(&cfqd->queue->queue_head)) {
-		struct list_head *entry = &cfqd->queue->queue_head;
-		unsigned long distance = ~0UL;
-		struct request *rq;
-
-		while ((entry = entry->prev) != &cfqd->queue->queue_head) {
-			rq = list_entry_rq(entry);
-
-			if (blk_barrier_rq(rq))
-				break;
-
-			if (distance < abs(s1 - rq->sector + rq->nr_sectors)) {
-				distance = abs(s1 - rq->sector +rq->nr_sectors);
-				last = rq->sector + rq->nr_sectors;
-			}
-			if (distance < abs(s2 - rq->sector + rq->nr_sectors)) {
-				distance = abs(s2 - rq->sector +rq->nr_sectors);
-				last = rq->sector + rq->nr_sectors;
-			}
-		}
-	}
-#endif
-
 	/*
 	 * by definition, 1KiB is 2 sectors
 	 */
@@ -377,11 +461,14 @@ cfq_find_next_crq(struct cfq_data *cfqd,
 	struct cfq_rq *crq_next = NULL, *crq_prev = NULL;
 	struct rb_node *rbnext, *rbprev;
 
-	if (!ON_RB(&last->rb_node))
-		return NULL;
-
-	if ((rbnext = rb_next(&last->rb_node)) == NULL)
+	rbnext = NULL;
+	if (ON_RB(&last->rb_node))
+		rbnext = rb_next(&last->rb_node);
+	if (!rbnext) {
 		rbnext = rb_first(&cfqq->sort_list);
+		if (rbnext == &last->rb_node)
+			rbnext = NULL;
+	}
 
 	rbprev = rb_prev(&last->rb_node);
 
@@ -401,67 +488,53 @@ static void cfq_update_next_crq(struct c
 		cfqq->next_crq = cfq_find_next_crq(cfqq->cfqd, cfqq, crq);
 }
 
-static int cfq_check_sort_rr_list(struct cfq_queue *cfqq)
+static void cfq_resort_rr_list(struct cfq_queue *cfqq, int preempted)
 {
-	struct list_head *head = &cfqq->cfqd->rr_list;
-	struct list_head *next, *prev;
-
-	/*
-	 * list might still be ordered
-	 */
-	next = cfqq->cfq_list.next;
-	if (next != head) {
-		struct cfq_queue *cnext = list_entry_cfqq(next);
+	struct cfq_data *cfqd = cfqq->cfqd;
+	struct list_head *list, *entry;
 
-		if (cfqq->service_used > cnext->service_used)
-			return 1;
-	}
+	BUG_ON(!cfq_cfqq_on_rr(cfqq));
 
-	prev = cfqq->cfq_list.prev;
-	if (prev != head) {
-		struct cfq_queue *cprev = list_entry_cfqq(prev);
+	list_del(&cfqq->cfq_list);
 
-		if (cfqq->service_used < cprev->service_used)
-			return 1;
+	if (cfq_class_rt(cfqq))
+		list = &cfqd->cur_rr;
+	else if (cfq_class_idle(cfqq))
+		list = &cfqd->idle_rr;
+	else {
+		/*
+		 * if cfqq has requests in flight, don't allow it to be
+		 * found in cfq_set_active_queue before it has finished them.
+		 * this is done to increase fairness between a process that
+		 * has lots of io pending vs one that only generates one
+		 * sporadically or synchronously
+		 */
+		if (cfq_cfqq_dispatched(cfqq))
+			list = &cfqd->busy_rr;
+		else
+			list = &cfqd->rr_list[cfqq->ioprio];
 	}
 
-	return 0;
-}
-
-static void cfq_sort_rr_list(struct cfq_queue *cfqq, int new_queue)
-{
-	struct list_head *entry = &cfqq->cfqd->rr_list;
-
-	if (!cfqq->on_rr)
-		return;
-	if (!new_queue && !cfq_check_sort_rr_list(cfqq))
+	/*
+	 * if queue was preempted, just add to front to be fair. busy_rr
+	 * isn't sorted.
+	 */
+	if (preempted || list == &cfqd->busy_rr) {
+		list_add(&cfqq->cfq_list, list);
 		return;
-
-	list_del(&cfqq->cfq_list);
+	}
 
 	/*
-	 * sort by our mean service_used, sub-sort by in-flight requests
+	 * sort by when queue was last serviced
 	 */
-	while ((entry = entry->prev) != &cfqq->cfqd->rr_list) {
+	entry = list;
+	while ((entry = entry->prev) != list) {
 		struct cfq_queue *__cfqq = list_entry_cfqq(entry);
 
-		if (cfqq->service_used > __cfqq->service_used)
+		if (!__cfqq->service_last)
+			break;
+		if (time_before(__cfqq->service_last, cfqq->service_last))
 			break;
-		else if (cfqq->service_used == __cfqq->service_used) {
-			struct list_head *prv;
-
-			while ((prv = entry->prev) != &cfqq->cfqd->rr_list) {
-				__cfqq = list_entry_cfqq(prv);
-
-				WARN_ON(__cfqq->service_used > cfqq->service_used);
-				if (cfqq->service_used != __cfqq->service_used)
-					break;
-				if (cfqq->in_flight > __cfqq->in_flight)
-					break;
-
-				entry = prv;
-			}
-		}
 	}
 
 	list_add(&cfqq->cfq_list, entry);
@@ -469,28 +542,24 @@ static void cfq_sort_rr_list(struct cfq_
 
 /*
  * add to busy list of queues for service, trying to be fair in ordering
- * the pending list according to requests serviced
+ * the pending list according to last request service
  */
 static inline void
-cfq_add_cfqq_rr(struct cfq_data *cfqd, struct cfq_queue *cfqq)
+cfq_add_cfqq_rr(struct cfq_data *cfqd, struct cfq_queue *cfqq, int requeue)
 {
-	/*
-	 * it's currently on the empty list
-	 */
-	cfqq->on_rr = 1;
+	BUG_ON(cfq_cfqq_on_rr(cfqq));
+	cfq_mark_cfqq_on_rr(cfqq);
 	cfqd->busy_queues++;
 
-	if (time_after(jiffies, cfqq->service_start + cfq_service))
-		cfqq->service_used >>= 3;
-
-	cfq_sort_rr_list(cfqq, 1);
+	cfq_resort_rr_list(cfqq, requeue);
 }
 
 static inline void
 cfq_del_cfqq_rr(struct cfq_data *cfqd, struct cfq_queue *cfqq)
 {
+	BUG_ON(!cfq_cfqq_on_rr(cfqq));
+	cfq_clear_cfqq_on_rr(cfqq);
 	list_move(&cfqq->cfq_list, &cfqd->empty_list);
-	cfqq->on_rr = 0;
 
 	BUG_ON(!cfqd->busy_queues);
 	cfqd->busy_queues--;
@@ -505,16 +574,17 @@ static inline void cfq_del_crq_rb(struct
 
 	if (ON_RB(&crq->rb_node)) {
 		struct cfq_data *cfqd = cfqq->cfqd;
+		const int sync = cfq_crq_is_sync(crq);
 
-		BUG_ON(!cfqq->queued[crq->is_sync]);
+		BUG_ON(!cfqq->queued[sync]);
+		cfqq->queued[sync]--;
 
 		cfq_update_next_crq(crq);
 
-		cfqq->queued[crq->is_sync]--;
 		rb_erase(&crq->rb_node, &cfqq->sort_list);
 		RB_CLEAR_COLOR(&crq->rb_node);
 
-		if (RB_EMPTY(&cfqq->sort_list) && cfqq->on_rr)
+		if (cfq_cfqq_on_rr(cfqq) && RB_EMPTY(&cfqq->sort_list))
 			cfq_del_cfqq_rr(cfqd, cfqq);
 	}
 }
@@ -550,7 +620,7 @@ static void cfq_add_crq_rb(struct cfq_rq
 	struct cfq_rq *__alias;
 
 	crq->rb_key = rq_rb_key(rq);
-	cfqq->queued[crq->is_sync]++;
+	cfqq->queued[cfq_crq_is_sync(crq)]++;
 
 	/*
 	 * looks a little odd, but the first insert might return an alias.
@@ -561,8 +631,8 @@ static void cfq_add_crq_rb(struct cfq_rq
 
 	rb_insert_color(&crq->rb_node, &cfqq->sort_list);
 
-	if (!cfqq->on_rr)
-		cfq_add_cfqq_rr(cfqd, cfqq);
+	if (!cfq_cfqq_on_rr(cfqq))
+		cfq_add_cfqq_rr(cfqd, cfqq, cfq_crq_requeued(crq));
 
 	/*
 	 * check if this request is a better next-serve candidate
@@ -575,17 +645,16 @@ cfq_reposition_crq_rb(struct cfq_queue *
 {
 	if (ON_RB(&crq->rb_node)) {
 		rb_erase(&crq->rb_node, &cfqq->sort_list);
-		cfqq->queued[crq->is_sync]--;
+		cfqq->queued[cfq_crq_is_sync(crq)]--;
 	}
 
 	cfq_add_crq_rb(crq);
 }
 
-static struct request *
-cfq_find_rq_rb(struct cfq_data *cfqd, sector_t sector)
+static struct request *cfq_find_rq_rb(struct cfq_data *cfqd, sector_t sector)
+
 {
-	const unsigned long key = cfq_hash_key(cfqd, current);
-	struct cfq_queue *cfqq = cfq_find_cfq_hash(cfqd, key);
+	struct cfq_queue *cfqq = cfq_find_cfq_hash(cfqd, current->pid, CFQ_KEY_ANY);
 	struct rb_node *n;
 
 	if (!cfqq)
@@ -609,20 +678,25 @@ out:
 
 static void cfq_deactivate_request(request_queue_t *q, struct request *rq)
 {
+	struct cfq_data *cfqd = q->elevator->elevator_data;
 	struct cfq_rq *crq = RQ_DATA(rq);
 
 	if (crq) {
 		struct cfq_queue *cfqq = crq->cfq_queue;
 
-		if (cfqq->cfqd->cfq_tagged) {
-			cfqq->service_used--;
-			cfq_sort_rr_list(cfqq, 0);
+		if (cfq_crq_in_driver(crq)) {
+			cfq_clear_crq_in_driver(crq);
+			WARN_ON(!cfqd->rq_in_driver);
+			cfqd->rq_in_driver--;
 		}
+		if (cfq_crq_in_flight(crq)) {
+			const int sync = cfq_crq_is_sync(crq);
 
-		if (crq->accounted) {
-			crq->accounted = 0;
-			cfqq->cfqd->rq_in_driver--;
+			cfq_clear_crq_in_flight(crq);
+			WARN_ON(!cfqq->on_dispatch[sync]);
+			cfqq->on_dispatch[sync]--;
 		}
+		cfq_mark_crq_requeued(crq);
 	}
 }
 
@@ -640,11 +714,10 @@ static void cfq_remove_request(request_q
 	struct cfq_rq *crq = RQ_DATA(rq);
 
 	if (crq) {
-		cfq_remove_merge_hints(q, crq);
 		list_del_init(&rq->queuelist);
+		cfq_del_crq_rb(crq);
+		cfq_remove_merge_hints(q, crq);
 
-		if (crq->cfq_queue)
-			cfq_del_crq_rb(crq);
 	}
 }
 
@@ -662,21 +735,15 @@ cfq_merge(request_queue_t *q, struct req
 	}
 
 	__rq = cfq_find_rq_hash(cfqd, bio->bi_sector);
-	if (__rq) {
-		BUG_ON(__rq->sector + __rq->nr_sectors != bio->bi_sector);
-
-		if (elv_rq_merge_ok(__rq, bio)) {
-			ret = ELEVATOR_BACK_MERGE;
-			goto out;
-		}
+	if (__rq && elv_rq_merge_ok(__rq, bio)) {
+		ret = ELEVATOR_BACK_MERGE;
+		goto out;
 	}
 
 	__rq = cfq_find_rq_rb(cfqd, bio->bi_sector + bio_sectors(bio));
-	if (__rq) {
-		if (elv_rq_merge_ok(__rq, bio)) {
-			ret = ELEVATOR_FRONT_MERGE;
-			goto out;
-		}
+	if (__rq && elv_rq_merge_ok(__rq, bio)) {
+		ret = ELEVATOR_FRONT_MERGE;
+		goto out;
 	}
 
 	return ELEVATOR_NO_MERGE;
@@ -709,235 +776,496 @@ static void
 cfq_merged_requests(request_queue_t *q, struct request *rq,
 		    struct request *next)
 {
-	struct cfq_rq *crq = RQ_DATA(rq);
-	struct cfq_rq *cnext = RQ_DATA(next);
-
 	cfq_merged_request(q, rq);
 
-	if (!list_empty(&rq->queuelist) && !list_empty(&next->queuelist)) {
-		if (time_before(cnext->queue_start, crq->queue_start)) {
-			list_move(&rq->queuelist, &next->queuelist);
-			crq->queue_start = cnext->queue_start;
-		}
-	}
+	/*
+	 * reposition in fifo if next is older than rq
+	 */
+	if (!list_empty(&rq->queuelist) && !list_empty(&next->queuelist) &&
+	    time_before(next->start_time, rq->start_time))
+		list_move(&rq->queuelist, &next->queuelist);
 
-	cfq_update_next_crq(cnext);
 	cfq_remove_request(q, next);
 }
 
+static inline void
+__cfq_set_active_queue(struct cfq_data *cfqd, struct cfq_queue *cfqq)
+{
+	if (cfqq) {
+		/*
+		 * stop potential idle class queues waiting service
+		 */
+		del_timer(&cfqd->idle_class_timer);
+
+		cfqq->slice_start = jiffies;
+		cfqq->slice_end = 0;
+		cfqq->slice_left = 0;
+		cfq_clear_cfqq_must_alloc_slice(cfqq);
+		cfq_clear_cfqq_fifo_expire(cfqq);
+		cfq_clear_cfqq_expired(cfqq);
+	}
+
+	cfqd->active_queue = cfqq;
+}
+
 /*
- * we dispatch cfqd->cfq_quantum requests in total from the rr_list queues,
- * this function sector sorts the selected request to minimize seeks. we start
- * at cfqd->last_sector, not 0.
+ * 0
+ * 0,1
+ * 0,1,2
+ * 0,1,2,3
+ * 0,1,2,3,4
+ * 0,1,2,3,4,5
+ * 0,1,2,3,4,5,6
+ * 0,1,2,3,4,5,6,7
  */
-static void cfq_dispatch_sort(request_queue_t *q, struct cfq_rq *crq)
+static int cfq_get_next_prio_level(struct cfq_data *cfqd)
 {
-	struct cfq_data *cfqd = q->elevator->elevator_data;
-	struct cfq_queue *cfqq = crq->cfq_queue;
-	struct list_head *head = &q->queue_head, *entry = head;
-	struct request *__rq;
-	sector_t last;
-
-	cfq_del_crq_rb(crq);
-	cfq_remove_merge_hints(q, crq);
-	list_del(&crq->request->queuelist);
+	int prio, wrap;
 
-	last = cfqd->last_sector;
-	while ((entry = entry->prev) != head) {
-		__rq = list_entry_rq(entry);
+	prio = -1;
+	wrap = 0;
+	do {
+		int p;
 
-		if (blk_barrier_rq(crq->request))
-			break;
-		if (!blk_fs_request(crq->request))
-			break;
+		for (p = cfqd->cur_prio; p <= cfqd->cur_end_prio; p++) {
+			if (!list_empty(&cfqd->rr_list[p])) {
+				prio = p;
+				break;
+			}
+		}
 
-		if (crq->request->sector > __rq->sector)
-			break;
-		if (__rq->sector > last && crq->request->sector < last) {
-			last = crq->request->sector;
+		if (prio != -1)
 			break;
+		cfqd->cur_prio = 0;
+		if (++cfqd->cur_end_prio == CFQ_PRIO_LISTS) {
+			cfqd->cur_end_prio = 0;
+			if (wrap)
+				break;
+			wrap = 1;
 		}
-	}
+	} while (1);
 
-	cfqd->last_sector = last;
-	crq->in_flight = 1;
-	cfqq->in_flight++;
-	list_add(&crq->request->queuelist, entry);
-}
+	if (unlikely(prio == -1))
+		return -1;
 
-/*
- * return expired entry, or NULL to just start from scratch in rbtree
- */
-static inline struct cfq_rq *cfq_check_fifo(struct cfq_queue *cfqq)
-{
-	struct cfq_data *cfqd = cfqq->cfqd;
-	const int reads = !list_empty(&cfqq->fifo[0]);
-	const int writes = !list_empty(&cfqq->fifo[1]);
-	unsigned long now = jiffies;
-	struct cfq_rq *crq;
+	BUG_ON(prio >= CFQ_PRIO_LISTS);
 
-	if (time_before(now, cfqq->last_fifo_expire + cfqd->cfq_fifo_batch_expire))
-		return NULL;
+	list_splice_init(&cfqd->rr_list[prio], &cfqd->cur_rr);
 
-	crq = RQ_DATA(list_entry(cfqq->fifo[0].next, struct request, queuelist));
-	if (reads && time_after(now, crq->queue_start + cfqd->cfq_fifo_expire_r)) {
-		cfqq->last_fifo_expire = now;
-		return crq;
+	cfqd->cur_prio = prio + 1;
+	if (cfqd->cur_prio > cfqd->cur_end_prio) {
+		cfqd->cur_end_prio = cfqd->cur_prio;
+		cfqd->cur_prio = 0;
 	}
-
-	crq = RQ_DATA(list_entry(cfqq->fifo[1].next, struct request, queuelist));
-	if (writes && time_after(now, crq->queue_start + cfqd->cfq_fifo_expire_w)) {
-		cfqq->last_fifo_expire = now;
-		return crq;
+	if (cfqd->cur_end_prio == CFQ_PRIO_LISTS) {
+		cfqd->cur_prio = 0;
+		cfqd->cur_end_prio = 0;
 	}
 
-	return NULL;
+	return prio;
 }
 
-/*
- * dispatch a single request from given queue
- */
-static inline void
-cfq_dispatch_request(request_queue_t *q, struct cfq_data *cfqd,
-		     struct cfq_queue *cfqq)
+static struct cfq_queue *cfq_set_active_queue(struct cfq_data *cfqd)
 {
-	struct cfq_rq *crq;
+	struct cfq_queue *cfqq;
 
 	/*
-	 * follow expired path, else get first next available
+	 * if current queue is expired but not done with its requests yet,
+	 * wait for that to happen
 	 */
-	if ((crq = cfq_check_fifo(cfqq)) == NULL) {
-		if (cfqd->find_best_crq)
-			crq = cfqq->next_crq;
-		else
-			crq = rb_entry_crq(rb_first(&cfqq->sort_list));
+	if ((cfqq = cfqd->active_queue) != NULL) {
+		if (cfq_cfqq_expired(cfqq) && cfq_cfqq_dispatched(cfqq))
+			return NULL;
 	}
 
-	cfqd->last_sector = crq->request->sector + crq->request->nr_sectors;
+	/*
+	 * if current list is non-empty, grab first entry. if it is empty,
+	 * get next prio level and grab first entry then if any are spliced
+	 */
+	if (!list_empty(&cfqd->cur_rr) || cfq_get_next_prio_level(cfqd) != -1)
+		cfqq = list_entry_cfqq(cfqd->cur_rr.next);
 
 	/*
-	 * finally, insert request into driver list
+	 * if we have idle queues and no rt or be queues had pending
+	 * requests, either allow immediate service if the grace period
+	 * has passed or arm the idle grace timer
 	 */
-	cfq_dispatch_sort(q, crq);
+	if (!cfqq && !list_empty(&cfqd->idle_rr)) {
+		unsigned long end = cfqd->last_end_request + CFQ_IDLE_GRACE;
+
+		if (time_after_eq(jiffies, end))
+			cfqq = list_entry_cfqq(cfqd->idle_rr.next);
+		else
+			mod_timer(&cfqd->idle_class_timer, end);
+	}
+
+	__cfq_set_active_queue(cfqd, cfqq);
+	return cfqq;
 }
 
-static int cfq_dispatch_requests(request_queue_t *q, int max_dispatch)
+/*
+ * current cfqq expired its slice (or was too idle), select new one
+ */
+static void
+__cfq_slice_expired(struct cfq_data *cfqd, struct cfq_queue *cfqq,
+		    int preempted)
 {
-	struct cfq_data *cfqd = q->elevator->elevator_data;
-	struct cfq_queue *cfqq;
-	struct list_head *entry, *tmp;
-	int queued, busy_queues, first_round;
-
-	if (list_empty(&cfqd->rr_list))
-		return 0;
+	unsigned long now = jiffies;
 
-	queued = 0;
-	first_round = 1;
-restart:
-	busy_queues = 0;
-	list_for_each_safe(entry, tmp, &cfqd->rr_list) {
-		cfqq = list_entry_cfqq(entry);
+	if (cfq_cfqq_wait_request(cfqq))
+		del_timer(&cfqd->idle_slice_timer);
 
-		BUG_ON(RB_EMPTY(&cfqq->sort_list));
+	if (!preempted && !cfq_cfqq_dispatched(cfqq))
+		cfqq->service_last = now;
 
-		/*
-		 * first round of queueing, only select from queues that
-		 * don't already have io in-flight
-		 */
-		if (first_round && cfqq->in_flight)
-			continue;
+	cfq_clear_cfqq_must_dispatch(cfqq);
+	cfq_clear_cfqq_wait_request(cfqq);
 
-		cfq_dispatch_request(q, cfqd, cfqq);
+	/*
+	 * store what was left of this slice, if the queue idled out
+	 * or was preempted
+	 */
+	if (time_after(now, cfqq->slice_end))
+		cfqq->slice_left = now - cfqq->slice_end;
+	else
+		cfqq->slice_left = 0;
 
-		if (!RB_EMPTY(&cfqq->sort_list))
-			busy_queues++;
+	if (cfq_cfqq_on_rr(cfqq))
+		cfq_resort_rr_list(cfqq, preempted);
 
-		queued++;
-	}
+	if (cfqq == cfqd->active_queue)
+		cfqd->active_queue = NULL;
 
-	if ((queued < max_dispatch) && (busy_queues || first_round)) {
-		first_round = 0;
-		goto restart;
+	if (cfqd->active_cic) {
+		put_io_context(cfqd->active_cic->ioc);
+		cfqd->active_cic = NULL;
 	}
 
-	return queued;
+	cfqd->dispatch_slice = 0;
 }
 
-static inline void cfq_account_dispatch(struct cfq_rq *crq)
+static inline void cfq_slice_expired(struct cfq_data *cfqd, int preempted)
 {
-	struct cfq_queue *cfqq = crq->cfq_queue;
-	struct cfq_data *cfqd = cfqq->cfqd;
-	unsigned long now, elapsed;
+	struct cfq_queue *cfqq = cfqd->active_queue;
 
-	if (!blk_fs_request(crq->request))
-		return;
+	if (cfqq) {
+		/*
+		 * use deferred expiry, if there are requests in progress as
+		 * not to disturb the slice of the next queue
+		 */
+		if (cfq_cfqq_dispatched(cfqq))
+			cfq_mark_cfqq_expired(cfqq);
+		else
+			__cfq_slice_expired(cfqd, cfqq, preempted);
+	}
+}
 
-	/*
-	 * accounted bit is necessary since some drivers will call
-	 * elv_next_request() many times for the same request (eg ide)
-	 */
-	if (crq->accounted)
-		return;
+static int cfq_arm_slice_timer(struct cfq_data *cfqd, struct cfq_queue *cfqq)
 
-	now = jiffies;
-	if (cfqq->service_start == ~0UL)
-		cfqq->service_start = now;
+{
+	WARN_ON(!RB_EMPTY(&cfqq->sort_list));
+	WARN_ON(cfqq != cfqd->active_queue);
 
 	/*
-	 * on drives with tagged command queueing, command turn-around time
-	 * doesn't necessarily reflect the time spent processing this very
-	 * command inside the drive. so do the accounting differently there,
-	 * by just sorting on the number of requests
-	 */
-	if (cfqd->cfq_tagged) {
-		if (time_after(now, cfqq->service_start + cfq_service)) {
-			cfqq->service_start = now;
-			cfqq->service_used /= 10;
-		}
-
-		cfqq->service_used++;
-		cfq_sort_rr_list(cfqq, 0);
-	}
+	 * idle is disabled, either manually or by past process history
+	 */
+	if (!cfqd->cfq_slice_idle)
+		return 0;
+	if (!cfq_cfqq_idle_window(cfqq))
+		return 0;
+	/*
+	 * task has exited, don't wait
+	 */
+	if (cfqd->active_cic && !cfqd->active_cic->ioc->task)
+		return 0;
+
+	cfq_mark_cfqq_must_dispatch(cfqq);
+	cfq_mark_cfqq_wait_request(cfqq);
+
+	if (!timer_pending(&cfqd->idle_slice_timer)) {
+		unsigned long slice_left = min(cfqq->slice_end - 1, (unsigned long) cfqd->cfq_slice_idle);
+
+		cfqd->idle_slice_timer.expires = jiffies + slice_left;
+		add_timer(&cfqd->idle_slice_timer);
+	}
+
+	return 1;
+}
+
+/*
+ * we dispatch cfqd->cfq_quantum requests in total from the rr_list queues,
+ * this function sector sorts the selected request to minimize seeks. we start
+ * at cfqd->last_sector, not 0.
+ */
+static void cfq_dispatch_sort(request_queue_t *q, struct cfq_rq *crq)
+{
+	struct cfq_data *cfqd = q->elevator->elevator_data;
+	struct cfq_queue *cfqq = crq->cfq_queue;
+	struct list_head *head = &q->queue_head, *entry = head;
+	struct request *__rq;
+	sector_t last;
+
+	list_del(&crq->request->queuelist);
+
+	last = cfqd->last_sector;
+	list_for_each_entry_reverse(__rq, head, queuelist) {
+		struct cfq_rq *__crq = RQ_DATA(__rq);
+
+		if (blk_barrier_rq(__rq))
+			break;
+		if (!blk_fs_request(__rq))
+			break;
+		if (cfq_crq_requeued(__crq))
+			break;
+
+		if (__rq->sector <= crq->request->sector)
+			break;
+		if (__rq->sector > last && crq->request->sector < last) {
+			last = crq->request->sector + crq->request->nr_sectors;
+			break;
+		}
+		entry = &__rq->queuelist;
+	}
+
+	cfqd->last_sector = last;
+
+	cfqq->next_crq = cfq_find_next_crq(cfqd, cfqq, crq);
 
-	elapsed = now - crq->queue_start;
-	if (elapsed > max_elapsed_dispatch)
-		max_elapsed_dispatch = elapsed;
+	cfq_del_crq_rb(crq);
+	cfq_remove_merge_hints(q, crq);
+
+	cfq_mark_crq_in_flight(crq);
+	cfq_clear_crq_requeued(crq);
+
+	cfqq->on_dispatch[cfq_crq_is_sync(crq)]++;
+	list_add_tail(&crq->request->queuelist, entry);
+}
+
+/*
+ * return expired entry, or NULL to just start from scratch in rbtree
+ */
+static inline struct cfq_rq *cfq_check_fifo(struct cfq_queue *cfqq)
+{
+	struct cfq_data *cfqd = cfqq->cfqd;
+	struct request *rq;
+	struct cfq_rq *crq;
 
-	crq->accounted = 1;
-	crq->service_start = now;
+	if (cfq_cfqq_fifo_expire(cfqq))
+		return NULL;
+
+	if (!list_empty(&cfqq->fifo)) {
+		int fifo = cfq_cfqq_class_sync(cfqq);
 
-	if (++cfqd->rq_in_driver >= CFQ_MAX_TAG && !cfqd->cfq_tagged) {
-		cfqq->cfqd->cfq_tagged = 1;
-		printk("cfq: depth %d reached, tagging now on\n", CFQ_MAX_TAG);
+		crq = RQ_DATA(list_entry_fifo(cfqq->fifo.next));
+		rq = crq->request;
+		if (time_after(jiffies, rq->start_time + cfqd->cfq_fifo_expire[fifo])) {
+			cfq_mark_cfqq_fifo_expire(cfqq);
+			return crq;
+		}
 	}
+
+	return NULL;
+}
+
+/*
+ * Scale schedule slice based on io priority. Use the sync time slice only
+ * if a queue is marked sync and has sync io queued. A sync queue with async
+ * io only, should not get full sync slice length.
+ */
+static inline int
+cfq_prio_to_slice(struct cfq_data *cfqd, struct cfq_queue *cfqq)
+{
+	const int base_slice = cfqd->cfq_slice[cfq_cfqq_sync(cfqq)];
+
+	WARN_ON(cfqq->ioprio >= IOPRIO_BE_NR);
+
+	return base_slice + (base_slice/CFQ_SLICE_SCALE * (4 - cfqq->ioprio));
+}
+
+static inline void
+cfq_set_prio_slice(struct cfq_data *cfqd, struct cfq_queue *cfqq)
+{
+	cfqq->slice_end = cfq_prio_to_slice(cfqd, cfqq) + jiffies;
+}
+
+static inline int
+cfq_prio_to_maxrq(struct cfq_data *cfqd, struct cfq_queue *cfqq)
+{
+	const int base_rq = cfqd->cfq_slice_async_rq;
+
+	WARN_ON(cfqq->ioprio >= IOPRIO_BE_NR);
+
+	return 2 * (base_rq + base_rq * (CFQ_PRIO_LISTS - 1 - cfqq->ioprio));
+}
+
+/*
+ * get next queue for service
+ */
+static struct cfq_queue *cfq_select_queue(struct cfq_data *cfqd, int force)
+{
+	unsigned long now = jiffies;
+	struct cfq_queue *cfqq;
+
+	cfqq = cfqd->active_queue;
+	if (!cfqq)
+		goto new_queue;
+
+	if (cfq_cfqq_expired(cfqq))
+		goto new_queue;
+
+	/*
+	 * slice has expired
+	 */
+	if (!cfq_cfqq_must_dispatch(cfqq) && time_after(now, cfqq->slice_end))
+		goto expire;
+
+	/*
+	 * if queue has requests, dispatch one. if not, check if
+	 * enough slice is left to wait for one
+	 */
+	if (!RB_EMPTY(&cfqq->sort_list))
+		goto keep_queue;
+	else if (!force && cfq_cfqq_class_sync(cfqq) &&
+		 time_before(now, cfqq->slice_end)) {
+		if (cfq_arm_slice_timer(cfqd, cfqq))
+			return NULL;
+	}
+
+expire:
+	cfq_slice_expired(cfqd, 0);
+new_queue:
+	cfqq = cfq_set_active_queue(cfqd);
+keep_queue:
+	return cfqq;
+}
+
+static int
+__cfq_dispatch_requests(struct cfq_data *cfqd, struct cfq_queue *cfqq,
+			int max_dispatch)
+{
+	int dispatched = 0;
+
+	BUG_ON(RB_EMPTY(&cfqq->sort_list));
+
+	do {
+		struct cfq_rq *crq;
+
+		/*
+		 * follow expired path, else get first next available
+		 */
+		if ((crq = cfq_check_fifo(cfqq)) == NULL)
+			crq = cfqq->next_crq;
+
+		/*
+		 * finally, insert request into driver dispatch list
+		 */
+		cfq_dispatch_sort(cfqd->queue, crq);
+
+		cfqd->dispatch_slice++;
+		dispatched++;
+
+		if (!cfqd->active_cic) {
+			atomic_inc(&crq->io_context->ioc->refcount);
+			cfqd->active_cic = crq->io_context;
+		}
+
+		if (RB_EMPTY(&cfqq->sort_list))
+			break;
+
+	} while (dispatched < max_dispatch);
+
+	/*
+	 * if slice end isn't set yet, set it. if at least one request was
+	 * sync, use the sync time slice value
+	 */
+	if (!cfqq->slice_end)
+		cfq_set_prio_slice(cfqd, cfqq);
+
+	/*
+	 * expire an async queue immediately if it has used up its slice. idle
+	 * queue always expire after 1 dispatch round.
+	 */
+	if ((!cfq_cfqq_sync(cfqq) &&
+	    cfqd->dispatch_slice >= cfq_prio_to_maxrq(cfqd, cfqq)) ||
+	    cfq_class_idle(cfqq))
+		cfq_slice_expired(cfqd, 0);
+
+	return dispatched;
+}
+
+static int
+cfq_dispatch_requests(request_queue_t *q, int max_dispatch, int force)
+{
+	struct cfq_data *cfqd = q->elevator->elevator_data;
+	struct cfq_queue *cfqq;
+
+	if (!cfqd->busy_queues)
+		return 0;
+
+	cfqq = cfq_select_queue(cfqd, force);
+	if (cfqq) {
+		cfq_clear_cfqq_must_dispatch(cfqq);
+		cfq_clear_cfqq_wait_request(cfqq);
+		del_timer(&cfqd->idle_slice_timer);
+
+		if (cfq_class_idle(cfqq))
+			max_dispatch = 1;
+
+		return __cfq_dispatch_requests(cfqd, cfqq, max_dispatch);
+	}
+
+	return 0;
+}
+
+static inline void cfq_account_dispatch(struct cfq_rq *crq)
+{
+	struct cfq_queue *cfqq = crq->cfq_queue;
+	struct cfq_data *cfqd = cfqq->cfqd;
+
+	if (unlikely(!blk_fs_request(crq->request)))
+		return;
+
+	/*
+	 * accounted bit is necessary since some drivers will call
+	 * elv_next_request() many times for the same request (eg ide)
+	 */
+	if (cfq_crq_in_driver(crq))
+		return;
+
+	cfq_mark_crq_in_driver(crq);
+	cfqd->rq_in_driver++;
 }
 
 static inline void
 cfq_account_completion(struct cfq_queue *cfqq, struct cfq_rq *crq)
 {
 	struct cfq_data *cfqd = cfqq->cfqd;
+	unsigned long now;
 
-	if (!crq->accounted)
+	if (!cfq_crq_in_driver(crq))
 		return;
 
+	now = jiffies;
+
 	WARN_ON(!cfqd->rq_in_driver);
 	cfqd->rq_in_driver--;
 
-	if (!cfqd->cfq_tagged) {
-		unsigned long now = jiffies;
-		unsigned long duration = now - crq->service_start;
+	if (!cfq_class_idle(cfqq))
+		cfqd->last_end_request = now;
 
-		if (time_after(now, cfqq->service_start + cfq_service)) {
-			cfqq->service_start = now;
-			cfqq->service_used >>= 3;
+	if (!cfq_cfqq_dispatched(cfqq)) {
+		if (cfq_cfqq_on_rr(cfqq)) {
+			cfqq->service_last = now;
+			cfq_resort_rr_list(cfqq, 0);
+		}
+		if (cfq_cfqq_expired(cfqq)) {
+			__cfq_slice_expired(cfqd, cfqq, 0);
+			cfq_schedule_dispatch(cfqd);
 		}
-
-		cfqq->service_used += duration;
-		cfq_sort_rr_list(cfqq, 0);
-
-		if (duration > max_elapsed_crq)
-			max_elapsed_crq = duration;
 	}
+
+	if (cfq_crq_is_sync(crq))
+		crq->io_context->last_end_request = now;
 }
 
 static struct request *cfq_next_request(request_queue_t *q)
@@ -950,7 +1278,19 @@ static struct request *cfq_next_request(
 dispatch:
 		rq = list_entry_rq(q->queue_head.next);
 
-		if ((crq = RQ_DATA(rq)) != NULL) {
+		crq = RQ_DATA(rq);
+		if (crq) {
+			struct cfq_queue *cfqq = crq->cfq_queue;
+
+			/*
+			 * if idle window is disabled, allow queue buildup
+			 */
+			if (!cfq_crq_in_driver(crq) &&
+			    !cfq_cfqq_idle_window(cfqq) &&
+			    !blk_barrier_rq(rq) &&
+			    cfqd->rq_in_driver >= cfqd->cfq_max_depth)
+				return NULL;
+
 			cfq_remove_merge_hints(q, crq);
 			cfq_account_dispatch(crq);
 		}
@@ -958,7 +1298,7 @@ dispatch:
 		return rq;
 	}
 
-	if (cfq_dispatch_requests(q, cfqd->cfq_quantum))
+	if (cfq_dispatch_requests(q, cfqd->cfq_quantum, 0))
 		goto dispatch;
 
 	return NULL;
@@ -972,13 +1312,21 @@ dispatch:
  */
 static void cfq_put_queue(struct cfq_queue *cfqq)
 {
-	BUG_ON(!atomic_read(&cfqq->ref));
+	struct cfq_data *cfqd = cfqq->cfqd;
+
+	BUG_ON(atomic_read(&cfqq->ref) <= 0);
 
 	if (!atomic_dec_and_test(&cfqq->ref))
 		return;
 
 	BUG_ON(rb_first(&cfqq->sort_list));
-	BUG_ON(cfqq->on_rr);
+	BUG_ON(cfqq->allocated[READ] + cfqq->allocated[WRITE]);
+	BUG_ON(cfq_cfqq_on_rr(cfqq));
+
+	if (unlikely(cfqd->active_queue == cfqq)) {
+		__cfq_slice_expired(cfqd, cfqq, 0);
+		cfq_schedule_dispatch(cfqd);
+	}
 
 	cfq_put_cfqd(cfqq->cfqd);
 
@@ -991,15 +1339,17 @@ static void cfq_put_queue(struct cfq_que
 }
 
 static inline struct cfq_queue *
-__cfq_find_cfq_hash(struct cfq_data *cfqd, unsigned long key, const int hashval)
+__cfq_find_cfq_hash(struct cfq_data *cfqd, unsigned int key, unsigned int prio,
+		    const int hashval)
 {
 	struct hlist_head *hash_list = &cfqd->cfq_hash[hashval];
 	struct hlist_node *entry, *next;
 
 	hlist_for_each_safe(entry, next, hash_list) {
 		struct cfq_queue *__cfqq = list_entry_qhash(entry);
+		const unsigned short __p = IOPRIO_PRIO_VALUE(__cfqq->ioprio_class, __cfqq->ioprio);
 
-		if (__cfqq->key == key)
+		if (__cfqq->key == key && (__p == prio || prio == CFQ_KEY_ANY))
 			return __cfqq;
 	}
 
@@ -1007,94 +1357,220 @@ __cfq_find_cfq_hash(struct cfq_data *cfq
 }
 
 static struct cfq_queue *
-cfq_find_cfq_hash(struct cfq_data *cfqd, unsigned long key)
+cfq_find_cfq_hash(struct cfq_data *cfqd, unsigned int key, unsigned short prio)
 {
-	return __cfq_find_cfq_hash(cfqd, key, hash_long(key, CFQ_QHASH_SHIFT));
+	return __cfq_find_cfq_hash(cfqd, key, prio, hash_long(key, CFQ_QHASH_SHIFT));
 }
 
-static inline void
-cfq_rehash_cfqq(struct cfq_data *cfqd, struct cfq_queue **cfqq,
-		struct cfq_io_context *cic)
+static void cfq_free_io_context(struct cfq_io_context *cic)
 {
-	unsigned long hashkey = cfq_hash_key(cfqd, current);
-	unsigned long hashval = hash_long(hashkey, CFQ_QHASH_SHIFT);
-	struct cfq_queue *__cfqq;
-	unsigned long flags;
-
-	spin_lock_irqsave(cfqd->queue->queue_lock, flags);
+	struct cfq_io_context *__cic;
+	struct list_head *entry, *next;
 
-	hlist_del(&(*cfqq)->cfq_hash);
-
-	__cfqq = __cfq_find_cfq_hash(cfqd, hashkey, hashval);
-	if (!__cfqq || __cfqq == *cfqq) {
-		__cfqq = *cfqq;
-		hlist_add_head(&__cfqq->cfq_hash, &cfqd->cfq_hash[hashval]);
-		__cfqq->key_type = cfqd->key_type;
-	} else {
-		atomic_inc(&__cfqq->ref);
-		cic->cfqq = __cfqq;
-		cfq_put_queue(*cfqq);
-		*cfqq = __cfqq;
+	list_for_each_safe(entry, next, &cic->list) {
+		__cic = list_entry(entry, struct cfq_io_context, list);
+		kmem_cache_free(cfq_ioc_pool, __cic);
 	}
 
-	cic->cfqq = __cfqq;
-	spin_unlock_irqrestore(cfqd->queue->queue_lock, flags);
+	kmem_cache_free(cfq_ioc_pool, cic);
 }
 
-static void cfq_free_io_context(struct cfq_io_context *cic)
+/*
+ * Called with interrupts disabled
+ */
+static void cfq_exit_single_io_context(struct cfq_io_context *cic)
 {
-	kmem_cache_free(cfq_ioc_pool, cic);
+	struct cfq_data *cfqd = cic->cfqq->cfqd;
+	request_queue_t *q = cfqd->queue;
+
+	WARN_ON(!irqs_disabled());
+
+	spin_lock(q->queue_lock);
+
+	if (unlikely(cic->cfqq == cfqd->active_queue)) {
+		__cfq_slice_expired(cfqd, cic->cfqq, 0);
+		cfq_schedule_dispatch(cfqd);
+	}
+
+	cfq_put_queue(cic->cfqq);
+	cic->cfqq = NULL;
+	spin_unlock(q->queue_lock);
 }
 
 /*
- * locking hierarchy is: io_context lock -> queue locks
+ * Another task may update the task cic list, if it is doing a queue lookup
+ * on its behalf. cfq_cic_lock excludes such concurrent updates
  */
 static void cfq_exit_io_context(struct cfq_io_context *cic)
 {
-	struct cfq_queue *cfqq = cic->cfqq;
-	struct list_head *entry = &cic->list;
-	request_queue_t *q;
+	struct cfq_io_context *__cic;
+	struct list_head *entry;
 	unsigned long flags;
 
+	local_irq_save(flags);
+
 	/*
 	 * put the reference this task is holding to the various queues
 	 */
-	spin_lock_irqsave(&cic->ioc->lock, flags);
-	while ((entry = cic->list.next) != &cic->list) {
-		struct cfq_io_context *__cic;
-
+	list_for_each(entry, &cic->list) {
 		__cic = list_entry(entry, struct cfq_io_context, list);
-		list_del(entry);
-
-		q = __cic->cfqq->cfqd->queue;
-		spin_lock(q->queue_lock);
-		cfq_put_queue(__cic->cfqq);
-		spin_unlock(q->queue_lock);
+		cfq_exit_single_io_context(__cic);
 	}
 
-	q = cfqq->cfqd->queue;
-	spin_lock(q->queue_lock);
-	cfq_put_queue(cfqq);
-	spin_unlock(q->queue_lock);
-
-	cic->cfqq = NULL;
-	spin_unlock_irqrestore(&cic->ioc->lock, flags);
+	cfq_exit_single_io_context(cic);
+	local_irq_restore(flags);
 }
 
-static struct cfq_io_context *cfq_alloc_io_context(int gfp_flags)
+static struct cfq_io_context *
+cfq_alloc_io_context(struct cfq_data *cfqd, int gfp_mask)
 {
-	struct cfq_io_context *cic = kmem_cache_alloc(cfq_ioc_pool, gfp_flags);
+	struct cfq_io_context *cic = kmem_cache_alloc(cfq_ioc_pool, gfp_mask);
 
 	if (cic) {
-		cic->dtor = cfq_free_io_context;
-		cic->exit = cfq_exit_io_context;
 		INIT_LIST_HEAD(&cic->list);
 		cic->cfqq = NULL;
+		cic->key = NULL;
+		cic->last_end_request = jiffies;
+		cic->ttime_total = 0;
+		cic->ttime_samples = 0;
+		cic->ttime_mean = 0;
+		cic->dtor = cfq_free_io_context;
+		cic->exit = cfq_exit_io_context;
 	}
 
 	return cic;
 }
 
+static void cfq_init_prio_data(struct cfq_queue *cfqq)
+{
+	struct task_struct *tsk = current;
+	int ioprio_class;
+
+	if (!cfq_cfqq_prio_changed(cfqq))
+		return;
+
+	ioprio_class = IOPRIO_PRIO_CLASS(tsk->ioprio);
+	switch (ioprio_class) {
+		default:
+			printk(KERN_ERR "cfq: bad prio %x\n", ioprio_class);
+		case IOPRIO_CLASS_NONE:
+			/*
+			 * no prio set, place us in the middle of the BE classes
+			 */
+			cfqq->ioprio = task_nice_ioprio(tsk);
+			cfqq->ioprio_class = IOPRIO_CLASS_BE;
+			break;
+		case IOPRIO_CLASS_RT:
+			cfqq->ioprio = task_ioprio(tsk);
+			cfqq->ioprio_class = IOPRIO_CLASS_RT;
+			break;
+		case IOPRIO_CLASS_BE:
+			cfqq->ioprio = task_ioprio(tsk);
+			cfqq->ioprio_class = IOPRIO_CLASS_BE;
+			break;
+		case IOPRIO_CLASS_IDLE:
+			cfqq->ioprio_class = IOPRIO_CLASS_IDLE;
+			cfqq->ioprio = 7;
+			cfq_clear_cfqq_idle_window(cfqq);
+			break;
+	}
+
+	/*
+	 * keep track of original prio settings in case we have to temporarily
+	 * elevate the priority of this queue
+	 */
+	cfqq->org_ioprio = cfqq->ioprio;
+	cfqq->org_ioprio_class = cfqq->ioprio_class;
+
+	if (cfq_cfqq_on_rr(cfqq))
+		cfq_resort_rr_list(cfqq, 0);
+
+	cfq_clear_cfqq_prio_changed(cfqq);
+}
+
+static inline void changed_ioprio(struct cfq_queue *cfqq)
+{
+	if (cfqq) {
+		struct cfq_data *cfqd = cfqq->cfqd;
+
+		spin_lock(cfqd->queue->queue_lock);
+		cfq_mark_cfqq_prio_changed(cfqq);
+		cfq_init_prio_data(cfqq);
+		spin_unlock(cfqd->queue->queue_lock);
+	}
+}
+
+/*
+ * callback from sys_ioprio_set, irqs are disabled
+ */
+static int cfq_ioc_set_ioprio(struct io_context *ioc, unsigned int ioprio)
+{
+	struct cfq_io_context *cic = ioc->cic;
+
+	changed_ioprio(cic->cfqq);
+
+	list_for_each_entry(cic, &cic->list, list)
+		changed_ioprio(cic->cfqq);
+
+	return 0;
+}
+
+static struct cfq_queue *
+cfq_get_queue(struct cfq_data *cfqd, unsigned int key, unsigned short ioprio,
+	      int gfp_mask)
+{
+	const int hashval = hash_long(key, CFQ_QHASH_SHIFT);
+	struct cfq_queue *cfqq, *new_cfqq = NULL;
+
+retry:
+	cfqq = __cfq_find_cfq_hash(cfqd, key, ioprio, hashval);
+
+	if (!cfqq) {
+		if (new_cfqq) {
+			cfqq = new_cfqq;
+			new_cfqq = NULL;
+		} else if (gfp_mask & __GFP_WAIT) {
+			spin_unlock_irq(cfqd->queue->queue_lock);
+			new_cfqq = kmem_cache_alloc(cfq_pool, gfp_mask);
+			spin_lock_irq(cfqd->queue->queue_lock);
+			goto retry;
+		} else {
+			cfqq = kmem_cache_alloc(cfq_pool, gfp_mask);
+			if (!cfqq)
+				goto out;
+		}
+
+		memset(cfqq, 0, sizeof(*cfqq));
+
+		INIT_HLIST_NODE(&cfqq->cfq_hash);
+		INIT_LIST_HEAD(&cfqq->cfq_list);
+		RB_CLEAR_ROOT(&cfqq->sort_list);
+		INIT_LIST_HEAD(&cfqq->fifo);
+
+		cfqq->key = key;
+		hlist_add_head(&cfqq->cfq_hash, &cfqd->cfq_hash[hashval]);
+		atomic_set(&cfqq->ref, 0);
+		cfqq->cfqd = cfqd;
+		atomic_inc(&cfqd->ref);
+		cfqq->service_last = 0;
+		/*
+		 * set ->slice_left to allow preemption for a new process
+		 */
+		cfqq->slice_left = 2 * cfqd->cfq_slice_idle;
+		cfq_mark_cfqq_idle_window(cfqq);
+		cfq_mark_cfqq_prio_changed(cfqq);
+		cfq_init_prio_data(cfqq);
+	}
+
+	if (new_cfqq)
+		kmem_cache_free(cfq_pool, new_cfqq);
+
+	atomic_inc(&cfqq->ref);
+out:
+	WARN_ON((gfp_mask & __GFP_WAIT) && !cfqq);
+	return cfqq;
+}
+
 /*
  * Setup general io context and cfq io context. There can be several cfq
  * io contexts per general io context, if this process is doing io to more
@@ -1102,39 +1578,39 @@ static struct cfq_io_context *cfq_alloc_
  * cfqq, so we don't need to worry about it disappearing
  */
 static struct cfq_io_context *
-cfq_get_io_context(struct cfq_queue **cfqq, int gfp_flags)
+cfq_get_io_context(struct cfq_data *cfqd, pid_t pid, int gfp_mask)
 {
-	struct cfq_data *cfqd = (*cfqq)->cfqd;
-	struct cfq_queue *__cfqq = *cfqq;
+	struct io_context *ioc = NULL;
 	struct cfq_io_context *cic;
-	struct io_context *ioc;
 
-	might_sleep_if(gfp_flags & __GFP_WAIT);
+	might_sleep_if(gfp_mask & __GFP_WAIT);
 
-	ioc = get_io_context(gfp_flags);
+	ioc = get_io_context(gfp_mask);
 	if (!ioc)
 		return NULL;
 
 	if ((cic = ioc->cic) == NULL) {
-		cic = cfq_alloc_io_context(gfp_flags);
+		cic = cfq_alloc_io_context(cfqd, gfp_mask);
 
 		if (cic == NULL)
 			goto err;
 
+		/*
+		 * manually increment generic io_context usage count, it
+		 * cannot go away since we are already holding one ref to it
+		 */
 		ioc->cic = cic;
+		ioc->set_ioprio = cfq_ioc_set_ioprio;
 		cic->ioc = ioc;
-		cic->cfqq = __cfqq;
-		atomic_inc(&__cfqq->ref);
+		cic->key = cfqd;
+		atomic_inc(&cfqd->ref);
 	} else {
 		struct cfq_io_context *__cic;
-		unsigned long flags;
 
 		/*
-		 * since the first cic on the list is actually the head
-		 * itself, need to check this here or we'll duplicate an
-		 * cic per ioc for no reason
+		 * the first cic on the list is actually the head itself
 		 */
-		if (cic->cfqq == __cfqq)
+		if (cic->key == cfqd)
 			goto out;
 
 		/*
@@ -1142,152 +1618,255 @@ cfq_get_io_context(struct cfq_queue **cf
 		 * should be ok here, the list will usually not be more than
 		 * 1 or a few entries long
 		 */
-		spin_lock_irqsave(&ioc->lock, flags);
 		list_for_each_entry(__cic, &cic->list, list) {
 			/*
 			 * this process is already holding a reference to
 			 * this queue, so no need to get one more
 			 */
-			if (__cic->cfqq == __cfqq) {
+			if (__cic->key == cfqd) {
 				cic = __cic;
-				spin_unlock_irqrestore(&ioc->lock, flags);
 				goto out;
 			}
 		}
-		spin_unlock_irqrestore(&ioc->lock, flags);
 
 		/*
 		 * nope, process doesn't have a cic assoicated with this
 		 * cfqq yet. get a new one and add to list
 		 */
-		__cic = cfq_alloc_io_context(gfp_flags);
+		__cic = cfq_alloc_io_context(cfqd, gfp_mask);
 		if (__cic == NULL)
 			goto err;
 
 		__cic->ioc = ioc;
-		__cic->cfqq = __cfqq;
-		atomic_inc(&__cfqq->ref);
-		spin_lock_irqsave(&ioc->lock, flags);
+		__cic->key = cfqd;
+		atomic_inc(&cfqd->ref);
 		list_add(&__cic->list, &cic->list);
-		spin_unlock_irqrestore(&ioc->lock, flags);
-
 		cic = __cic;
-		*cfqq = __cfqq;
 	}
 
 out:
+	return cic;
+err:
+	put_io_context(ioc);
+	return NULL;
+}
+
+static void
+cfq_update_io_thinktime(struct cfq_data *cfqd, struct cfq_io_context *cic)
+{
+	unsigned long elapsed, ttime;
+
 	/*
-	 * if key_type has been changed on the fly, we lazily rehash
-	 * each queue at lookup time
+	 * if this context already has stuff queued, thinktime is from
+	 * last queue not last end
 	 */
-	if ((*cfqq)->key_type != cfqd->key_type)
-		cfq_rehash_cfqq(cfqd, cfqq, cic);
+#if 0
+	if (time_after(cic->last_end_request, cic->last_queue))
+		elapsed = jiffies - cic->last_end_request;
+	else
+		elapsed = jiffies - cic->last_queue;
+#else
+		elapsed = jiffies - cic->last_end_request;
+#endif
+
+	ttime = min(elapsed, 2UL * cfqd->cfq_slice_idle);
+
+	cic->ttime_samples = (7*cic->ttime_samples + 256) / 8;
+	cic->ttime_total = (7*cic->ttime_total + 256*ttime) / 8;
+	cic->ttime_mean = (cic->ttime_total + 128) / cic->ttime_samples;
+}
+
+#define sample_valid(samples)	((samples) > 80)
+
+/*
+ * Disable idle window if the process thinks too long or seeks so much that
+ * it doesn't matter
+ */
+static void
+cfq_update_idle_window(struct cfq_data *cfqd, struct cfq_queue *cfqq,
+		       struct cfq_io_context *cic)
+{
+	int enable_idle = cfq_cfqq_idle_window(cfqq);
+
+	if (!cic->ioc->task || !cfqd->cfq_slice_idle)
+		enable_idle = 0;
+	else if (sample_valid(cic->ttime_samples)) {
+		if (cic->ttime_mean > cfqd->cfq_slice_idle)
+			enable_idle = 0;
+		else
+			enable_idle = 1;
+	}
+
+	if (enable_idle)
+		cfq_mark_cfqq_idle_window(cfqq);
+	else
+		cfq_clear_cfqq_idle_window(cfqq);
+}
+
+
+/*
+ * Check if new_cfqq should preempt the currently active queue. Return 0 for
+ * no or if we aren't sure, a 1 will cause a preempt.
+ */
+static int
+cfq_should_preempt(struct cfq_data *cfqd, struct cfq_queue *new_cfqq,
+		   struct cfq_rq *crq)
+{
+	struct cfq_queue *cfqq = cfqd->active_queue;
+
+	if (cfq_class_idle(new_cfqq))
+		return 0;
+
+	if (!cfqq)
+		return 1;
+
+	if (cfq_class_idle(cfqq))
+		return 1;
+	if (!cfq_cfqq_wait_request(new_cfqq))
+		return 0;
+	/*
+	 * if it doesn't have slice left, forget it
+	 */
+	if (new_cfqq->slice_left < cfqd->cfq_slice_idle)
+		return 0;
+	if (cfq_crq_is_sync(crq) && !cfq_cfqq_sync(cfqq))
+		return 1;
+
+	return 0;
+}
+
+/*
+ * cfqq preempts the active queue. if we allowed preempt with no slice left,
+ * let it have half of its nominal slice.
+ */
+static void cfq_preempt_queue(struct cfq_data *cfqd, struct cfq_queue *cfqq)
+{
+	struct cfq_queue *__cfqq, *next;
+
+	list_for_each_entry_safe(__cfqq, next, &cfqd->cur_rr, cfq_list)
+		cfq_resort_rr_list(__cfqq, 1);
+
+	if (!cfqq->slice_left)
+		cfqq->slice_left = cfq_prio_to_slice(cfqd, cfqq) / 2;
 
-	return cic;
-err:
-	put_io_context(ioc);
-	return NULL;
+	cfqq->slice_end = cfqq->slice_left + jiffies;
+	__cfq_slice_expired(cfqd, cfqq, 1);
+	__cfq_set_active_queue(cfqd, cfqq);
 }
 
-static struct cfq_queue *
-__cfq_get_queue(struct cfq_data *cfqd, unsigned long key, int gfp_mask)
+/*
+ * should really be a ll_rw_blk.c helper
+ */
+static void cfq_start_queueing(struct cfq_data *cfqd, struct cfq_queue *cfqq)
 {
-	const int hashval = hash_long(key, CFQ_QHASH_SHIFT);
-	struct cfq_queue *cfqq, *new_cfqq = NULL;
-
-retry:
-	cfqq = __cfq_find_cfq_hash(cfqd, key, hashval);
+	request_queue_t *q = cfqd->queue;
 
-	if (!cfqq) {
-		if (new_cfqq) {
-			cfqq = new_cfqq;
-			new_cfqq = NULL;
-		} else {
-			spin_unlock_irq(cfqd->queue->queue_lock);
-			new_cfqq = kmem_cache_alloc(cfq_pool, gfp_mask);
-			spin_lock_irq(cfqd->queue->queue_lock);
+	if (!blk_queue_plugged(q))
+		q->request_fn(q);
+	else
+		__generic_unplug_device(q);
+}
 
-			if (!new_cfqq && !(gfp_mask & __GFP_WAIT))
-				goto out;
+/*
+ * Called when a new fs request (crq) is added (to cfqq). Check if there's
+ * something we should do about it
+ */
+static void
+cfq_crq_enqueued(struct cfq_data *cfqd, struct cfq_queue *cfqq,
+		 struct cfq_rq *crq)
+{
+	struct cfq_io_context *cic;
 
-			goto retry;
-		}
+	cfqq->next_crq = cfq_choose_req(cfqd, cfqq->next_crq, crq);
 
-		memset(cfqq, 0, sizeof(*cfqq));
+	/*
+	 * we never wait for an async request and we don't allow preemption
+	 * of an async request. so just return early
+	 */
+	if (!cfq_crq_is_sync(crq))
+		return;
 
-		INIT_HLIST_NODE(&cfqq->cfq_hash);
-		INIT_LIST_HEAD(&cfqq->cfq_list);
-		RB_CLEAR_ROOT(&cfqq->sort_list);
-		INIT_LIST_HEAD(&cfqq->fifo[0]);
-		INIT_LIST_HEAD(&cfqq->fifo[1]);
+	cic = crq->io_context;
 
-		cfqq->key = key;
-		hlist_add_head(&cfqq->cfq_hash, &cfqd->cfq_hash[hashval]);
-		atomic_set(&cfqq->ref, 0);
-		cfqq->cfqd = cfqd;
-		atomic_inc(&cfqd->ref);
-		cfqq->key_type = cfqd->key_type;
-		cfqq->service_start = ~0UL;
-	}
+	cfq_update_io_thinktime(cfqd, cic);
+	cfq_update_idle_window(cfqd, cfqq, cic);
 
-	if (new_cfqq)
-		kmem_cache_free(cfq_pool, new_cfqq);
+	cic->last_queue = jiffies;
 
-	atomic_inc(&cfqq->ref);
-out:
-	WARN_ON((gfp_mask & __GFP_WAIT) && !cfqq);
-	return cfqq;
+	if (cfqq == cfqd->active_queue) {
+		/*
+		 * if we are waiting for a request for this queue, let it rip
+		 * immediately and flag that we must not expire this queue
+		 * just now
+		 */
+		if (cfq_cfqq_wait_request(cfqq)) {
+			cfq_mark_cfqq_must_dispatch(cfqq);
+			del_timer(&cfqd->idle_slice_timer);
+			cfq_start_queueing(cfqd, cfqq);
+		}
+	} else if (cfq_should_preempt(cfqd, cfqq, crq)) {
+		/*
+		 * not the active queue - expire current slice if it is
+		 * idle and has expired it's mean thinktime or this new queue
+		 * has some old slice time left and is of higher priority
+		 */
+		cfq_preempt_queue(cfqd, cfqq);
+		cfq_mark_cfqq_must_dispatch(cfqq);
+		cfq_start_queueing(cfqd, cfqq);
+	}
 }
 
-static void cfq_enqueue(struct cfq_data *cfqd, struct cfq_rq *crq)
+static void cfq_enqueue(struct cfq_data *cfqd, struct request *rq)
 {
-	crq->is_sync = 0;
-	if (rq_data_dir(crq->request) == READ || current->flags & PF_SYNCWRITE)
-		crq->is_sync = 1;
+	struct cfq_rq *crq = RQ_DATA(rq);
+	struct cfq_queue *cfqq = crq->cfq_queue;
+
+	cfq_init_prio_data(cfqq);
 
 	cfq_add_crq_rb(crq);
-	crq->queue_start = jiffies;
 
-	list_add_tail(&crq->request->queuelist, &crq->cfq_queue->fifo[crq->is_sync]);
+	list_add_tail(&rq->queuelist, &cfqq->fifo);
+
+	if (rq_mergeable(rq)) {
+		cfq_add_crq_hash(cfqd, crq);
+
+		if (!cfqd->queue->last_merge)
+			cfqd->queue->last_merge = rq;
+	}
+
+	cfq_crq_enqueued(cfqd, cfqq, crq);
 }
 
 static void
 cfq_insert_request(request_queue_t *q, struct request *rq, int where)
 {
 	struct cfq_data *cfqd = q->elevator->elevator_data;
-	struct cfq_rq *crq = RQ_DATA(rq);
 
 	switch (where) {
 		case ELEVATOR_INSERT_BACK:
-			while (cfq_dispatch_requests(q, cfqd->cfq_quantum))
+			while (cfq_dispatch_requests(q, INT_MAX, 1))
 				;
 			list_add_tail(&rq->queuelist, &q->queue_head);
+			/*
+			 * If we were idling with pending requests on
+			 * inactive cfqqs, force dispatching will
+			 * remove the idle timer and the queue won't
+			 * be kicked by __make_request() afterward.
+			 * Kick it here.
+			 */
+			cfq_schedule_dispatch(cfqd);
 			break;
 		case ELEVATOR_INSERT_FRONT:
 			list_add(&rq->queuelist, &q->queue_head);
 			break;
 		case ELEVATOR_INSERT_SORT:
 			BUG_ON(!blk_fs_request(rq));
-			cfq_enqueue(cfqd, crq);
+			cfq_enqueue(cfqd, rq);
 			break;
 		default:
 			printk("%s: bad insert point %d\n", __FUNCTION__,where);
 			return;
 	}
-
-	if (rq_mergeable(rq)) {
-		cfq_add_crq_hash(cfqd, crq);
-
-		if (!q->last_merge)
-			q->last_merge = rq;
-	}
-}
-
-static int cfq_queue_empty(request_queue_t *q)
-{
-	struct cfq_data *cfqd = q->elevator->elevator_data;
-
-	return list_empty(&q->queue_head) && list_empty(&cfqd->rr_list);
 }
 
 static void cfq_completed_request(request_queue_t *q, struct request *rq)
@@ -1300,9 +1879,11 @@ static void cfq_completed_request(reques
 
 	cfqq = crq->cfq_queue;
 
-	if (crq->in_flight) {
-		WARN_ON(!cfqq->in_flight);
-		cfqq->in_flight--;
+	if (cfq_crq_in_flight(crq)) {
+		const int sync = cfq_crq_is_sync(crq);
+
+		WARN_ON(!cfqq->on_dispatch[sync]);
+		cfqq->on_dispatch[sync]--;
 	}
 
 	cfq_account_completion(cfqq, crq);
@@ -1332,51 +1913,136 @@ cfq_latter_request(request_queue_t *q, s
 	return NULL;
 }
 
-static int cfq_may_queue(request_queue_t *q, int rw)
+/*
+ * we temporarily boost lower priority queues if they are holding fs exclusive
+ * resources. they are boosted to normal prio (CLASS_BE/4)
+ */
+static void cfq_prio_boost(struct cfq_queue *cfqq)
 {
-	struct cfq_data *cfqd = q->elevator->elevator_data;
-	struct cfq_queue *cfqq;
-	int ret = ELV_MQUEUE_MAY;
+	const int ioprio_class = cfqq->ioprio_class;
+	const int ioprio = cfqq->ioprio;
 
-	if (current->flags & PF_MEMALLOC)
-		return ELV_MQUEUE_MAY;
+	if (has_fs_excl()) {
+		/*
+		 * boost idle prio on transactions that would lock out other
+		 * users of the filesystem
+		 */
+		if (cfq_class_idle(cfqq))
+			cfqq->ioprio_class = IOPRIO_CLASS_BE;
+		if (cfqq->ioprio > IOPRIO_NORM)
+			cfqq->ioprio = IOPRIO_NORM;
+	} else {
+		/*
+		 * check if we need to unboost the queue
+		 */
+		if (cfqq->ioprio_class != cfqq->org_ioprio_class)
+			cfqq->ioprio_class = cfqq->org_ioprio_class;
+		if (cfqq->ioprio != cfqq->org_ioprio)
+			cfqq->ioprio = cfqq->org_ioprio;
+	}
 
-	cfqq = cfq_find_cfq_hash(cfqd, cfq_hash_key(cfqd, current));
-	if (cfqq) {
-		int limit = cfqd->max_queued;
+	/*
+	 * refile between round-robin lists if we moved the priority class
+	 */
+	if ((ioprio_class != cfqq->ioprio_class || ioprio != cfqq->ioprio) &&
+	    cfq_cfqq_on_rr(cfqq))
+		cfq_resort_rr_list(cfqq, 0);
+}
 
-		if (cfqq->allocated[rw] < cfqd->cfq_queued)
-			return ELV_MQUEUE_MUST;
+static inline pid_t cfq_queue_pid(struct task_struct *task, int rw)
+{
+	if (rw == READ || process_sync(task))
+		return task->pid;
+
+	return CFQ_KEY_ASYNC;
+}
 
-		if (cfqd->busy_queues)
-			limit = q->nr_requests / cfqd->busy_queues;
+static inline int
+__cfq_may_queue(struct cfq_data *cfqd, struct cfq_queue *cfqq,
+		struct task_struct *task, int rw)
+{
+#if 1
+	if ((cfq_cfqq_wait_request(cfqq) || cfq_cfqq_must_alloc(cfqq)) &&
+	    !cfq_cfqq_must_alloc_slice(cfqq)) {
+		cfq_mark_cfqq_must_alloc_slice(cfqq);
+		return ELV_MQUEUE_MUST;
+	}
 
-		if (limit < cfqd->cfq_queued)
-			limit = cfqd->cfq_queued;
-		else if (limit > cfqd->max_queued)
-			limit = cfqd->max_queued;
-
-		if (cfqq->allocated[rw] >= limit) {
-			if (limit > cfqq->alloc_limit[rw])
-				cfqq->alloc_limit[rw] = limit;
+	return ELV_MQUEUE_MAY;
+#else
+	if (!cfqq || task->flags & PF_MEMALLOC)
+		return ELV_MQUEUE_MAY;
+	if (!cfqq->allocated[rw] || cfq_cfqq_must_alloc(cfqq)) {
+		if (cfq_cfqq_wait_request(cfqq))
+			return ELV_MQUEUE_MUST;
 
-			ret = ELV_MQUEUE_NO;
+		/*
+		 * only allow 1 ELV_MQUEUE_MUST per slice, otherwise we
+		 * can quickly flood the queue with writes from a single task
+		 */
+		if (rw == READ || !cfq_cfqq_must_alloc_slice(cfqq)) {
+			cfq_mark_cfqq_must_alloc_slice(cfqq);
+			return ELV_MQUEUE_MUST;
 		}
+
+		return ELV_MQUEUE_MAY;
 	}
+	if (cfq_class_idle(cfqq))
+		return ELV_MQUEUE_NO;
+	if (cfqq->allocated[rw] >= cfqd->max_queued) {
+		struct io_context *ioc = get_io_context(GFP_ATOMIC);
+		int ret = ELV_MQUEUE_NO;
 
-	return ret;
+		if (ioc && ioc->nr_batch_requests)
+			ret = ELV_MQUEUE_MAY;
+
+		put_io_context(ioc);
+		return ret;
+	}
+
+	return ELV_MQUEUE_MAY;
+#endif
+}
+
+static int cfq_may_queue(request_queue_t *q, int rw, struct bio *bio)
+{
+	struct cfq_data *cfqd = q->elevator->elevator_data;
+	struct task_struct *tsk = current;
+	struct cfq_queue *cfqq;
+
+	/*
+	 * don't force setup of a queue from here, as a call to may_queue
+	 * does not necessarily imply that a request actually will be queued.
+	 * so just lookup a possibly existing queue, or return 'may queue'
+	 * if that fails
+	 */
+	cfqq = cfq_find_cfq_hash(cfqd, cfq_queue_pid(tsk, rw), tsk->ioprio);
+	if (cfqq) {
+		cfq_init_prio_data(cfqq);
+		cfq_prio_boost(cfqq);
+
+		return __cfq_may_queue(cfqd, cfqq, tsk, rw);
+	}
+
+	return ELV_MQUEUE_MAY;
 }
 
 static void cfq_check_waiters(request_queue_t *q, struct cfq_queue *cfqq)
 {
+	struct cfq_data *cfqd = q->elevator->elevator_data;
 	struct request_list *rl = &q->rq;
-	const int write = waitqueue_active(&rl->wait[WRITE]);
-	const int read = waitqueue_active(&rl->wait[READ]);
 
-	if (read && cfqq->allocated[READ] < cfqq->alloc_limit[READ])
-		wake_up(&rl->wait[READ]);
-	if (write && cfqq->allocated[WRITE] < cfqq->alloc_limit[WRITE])
-		wake_up(&rl->wait[WRITE]);
+	if (cfqq->allocated[READ] <= cfqd->max_queued || cfqd->rq_starved) {
+		smp_mb();
+		if (waitqueue_active(&rl->wait[READ]))
+			wake_up(&rl->wait[READ]);
+	}
+
+	if (cfqq->allocated[WRITE] <= cfqd->max_queued || cfqd->rq_starved) {
+		smp_mb();
+		if (waitqueue_active(&rl->wait[WRITE]))
+			wake_up(&rl->wait[WRITE]);
+	}
 }
 
 /*
@@ -1389,69 +2055,61 @@ static void cfq_put_request(request_queu
 
 	if (crq) {
 		struct cfq_queue *cfqq = crq->cfq_queue;
+		const int rw = rq_data_dir(rq);
 
-		BUG_ON(q->last_merge == rq);
-		BUG_ON(!hlist_unhashed(&crq->hash));
-
-		if (crq->io_context)
-			put_io_context(crq->io_context->ioc);
+		BUG_ON(!cfqq->allocated[rw]);
+		cfqq->allocated[rw]--;
 
-		BUG_ON(!cfqq->allocated[crq->is_write]);
-		cfqq->allocated[crq->is_write]--;
+		put_io_context(crq->io_context->ioc);
 
 		mempool_free(crq, cfqd->crq_pool);
 		rq->elevator_private = NULL;
 
-		smp_mb();
 		cfq_check_waiters(q, cfqq);
 		cfq_put_queue(cfqq);
 	}
 }
 
 /*
- * Allocate cfq data structures associated with this request. A queue and
+ * Allocate cfq data structures associated with this request.
  */
-static int cfq_set_request(request_queue_t *q, struct request *rq, int gfp_mask)
+static int
+cfq_set_request(request_queue_t *q, struct request *rq, struct bio *bio,
+		int gfp_mask)
 {
 	struct cfq_data *cfqd = q->elevator->elevator_data;
+	struct task_struct *tsk = current;
 	struct cfq_io_context *cic;
 	const int rw = rq_data_dir(rq);
-	struct cfq_queue *cfqq, *saved_cfqq;
+	pid_t key = cfq_queue_pid(tsk, rw);
+	struct cfq_queue *cfqq;
 	struct cfq_rq *crq;
 	unsigned long flags;
 
 	might_sleep_if(gfp_mask & __GFP_WAIT);
 
+	cic = cfq_get_io_context(cfqd, key, gfp_mask);
+
 	spin_lock_irqsave(q->queue_lock, flags);
 
-	cfqq = __cfq_get_queue(cfqd, cfq_hash_key(cfqd, current), gfp_mask);
-	if (!cfqq)
-		goto out_lock;
+	if (!cic)
+		goto queue_fail;
 
-repeat:
-	if (cfqq->allocated[rw] >= cfqd->max_queued)
-		goto out_lock;
+	if (!cic->cfqq) {
+		cfqq = cfq_get_queue(cfqd, key, tsk->ioprio, gfp_mask);
+		if (!cfqq)
+			goto queue_fail;
+
+		cic->cfqq = cfqq;
+	} else
+		cfqq = cic->cfqq;
 
 	cfqq->allocated[rw]++;
+	cfq_clear_cfqq_must_alloc(cfqq);
+	cfqd->rq_starved = 0;
+	atomic_inc(&cfqq->ref);
 	spin_unlock_irqrestore(q->queue_lock, flags);
 
-	/*
-	 * if hashing type has changed, the cfq_queue might change here.
-	 */
-	saved_cfqq = cfqq;
-	cic = cfq_get_io_context(&cfqq, gfp_mask);
-	if (!cic)
-		goto err;
-
-	/*
-	 * repeat allocation checks on queue change
-	 */
-	if (unlikely(saved_cfqq != cfqq)) {
-		spin_lock_irqsave(q->queue_lock, flags);
-		saved_cfqq->allocated[rw]--;
-		goto repeat;
-	}
-
 	crq = mempool_alloc(cfqd->crq_pool, gfp_mask);
 	if (crq) {
 		RB_CLEAR(&crq->rb_node);
@@ -1460,24 +2118,141 @@ repeat:
 		INIT_HLIST_NODE(&crq->hash);
 		crq->cfq_queue = cfqq;
 		crq->io_context = cic;
-		crq->service_start = crq->queue_start = 0;
-		crq->in_flight = crq->accounted = crq->is_sync = 0;
-		crq->is_write = rw;
+		cfq_clear_crq_in_flight(crq);
+		cfq_clear_crq_in_driver(crq);
+		cfq_clear_crq_requeued(crq);
+
+		if (rw == READ || process_sync(tsk))
+			cfq_mark_crq_is_sync(crq);
+		else
+			cfq_clear_crq_is_sync(crq);
+
 		rq->elevator_private = crq;
-		cfqq->alloc_limit[rw] = 0;
 		return 0;
 	}
 
-	put_io_context(cic->ioc);
-err:
 	spin_lock_irqsave(q->queue_lock, flags);
 	cfqq->allocated[rw]--;
+	if (!(cfqq->allocated[0] + cfqq->allocated[1]))
+		cfq_mark_cfqq_must_alloc(cfqq);
 	cfq_put_queue(cfqq);
-out_lock:
+queue_fail:
+	if (cic)
+		put_io_context(cic->ioc);
+	/*
+	 * mark us rq allocation starved. we need to kickstart the process
+	 * ourselves if there are no pending requests that can do it for us.
+	 * that would be an extremely rare OOM situation
+	 */
+	cfqd->rq_starved = 1;
+	cfq_schedule_dispatch(cfqd);
 	spin_unlock_irqrestore(q->queue_lock, flags);
 	return 1;
 }
 
+static void cfq_kick_queue(void *data)
+{
+	request_queue_t *q = data;
+	struct cfq_data *cfqd = q->elevator->elevator_data;
+	unsigned long flags;
+
+	spin_lock_irqsave(q->queue_lock, flags);
+
+	if (cfqd->rq_starved) {
+		struct request_list *rl = &q->rq;
+
+		/*
+		 * we aren't guaranteed to get a request after this, but we
+		 * have to be opportunistic
+		 */
+		smp_mb();
+		if (waitqueue_active(&rl->wait[READ]))
+			wake_up(&rl->wait[READ]);
+		if (waitqueue_active(&rl->wait[WRITE]))
+			wake_up(&rl->wait[WRITE]);
+	}
+
+	blk_remove_plug(q);
+	q->request_fn(q);
+	spin_unlock_irqrestore(q->queue_lock, flags);
+}
+
+/*
+ * Timer running if the active_queue is currently idling inside its time slice
+ */
+static void cfq_idle_slice_timer(unsigned long data)
+{
+	struct cfq_data *cfqd = (struct cfq_data *) data;
+	struct cfq_queue *cfqq;
+	unsigned long flags;
+
+	spin_lock_irqsave(cfqd->queue->queue_lock, flags);
+
+	if ((cfqq = cfqd->active_queue) != NULL) {
+		unsigned long now = jiffies;
+
+		/*
+		 * expired
+		 */
+		if (time_after(now, cfqq->slice_end))
+			goto expire;
+
+		/*
+		 * only expire and reinvoke request handler, if there are
+		 * other queues with pending requests
+		 */
+		if (!cfq_pending_requests(cfqd)) {
+			cfqd->idle_slice_timer.expires = min(now + cfqd->cfq_slice_idle, cfqq->slice_end);
+			add_timer(&cfqd->idle_slice_timer);
+			goto out_cont;
+		}
+
+		/*
+		 * not expired and it has a request pending, let it dispatch
+		 */
+		if (!RB_EMPTY(&cfqq->sort_list)) {
+			cfq_mark_cfqq_must_dispatch(cfqq);
+			goto out_kick;
+		}
+	}
+expire:
+	cfq_slice_expired(cfqd, 0);
+out_kick:
+	cfq_schedule_dispatch(cfqd);
+out_cont:
+	spin_unlock_irqrestore(cfqd->queue->queue_lock, flags);
+}
+
+/*
+ * Timer running if an idle class queue is waiting for service
+ */
+static void cfq_idle_class_timer(unsigned long data)
+{
+	struct cfq_data *cfqd = (struct cfq_data *) data;
+	unsigned long flags, end;
+
+	spin_lock_irqsave(cfqd->queue->queue_lock, flags);
+
+	/*
+	 * race with a non-idle queue, reset timer
+	 */
+	end = cfqd->last_end_request + CFQ_IDLE_GRACE;
+	if (!time_after_eq(jiffies, end)) {
+		cfqd->idle_class_timer.expires = end;
+		add_timer(&cfqd->idle_class_timer);
+	} else
+		cfq_schedule_dispatch(cfqd);
+
+	spin_unlock_irqrestore(cfqd->queue->queue_lock, flags);
+}
+
+static void cfq_shutdown_timer_wq(struct cfq_data *cfqd)
+{
+	del_timer_sync(&cfqd->idle_slice_timer);
+	del_timer_sync(&cfqd->idle_class_timer);
+	blk_sync_queue(cfqd->queue);
+}
+
 static void cfq_put_cfqd(struct cfq_data *cfqd)
 {
 	request_queue_t *q = cfqd->queue;
@@ -1487,6 +2262,9 @@ static void cfq_put_cfqd(struct cfq_data
 
 	blk_put_queue(q);
 
+	cfq_shutdown_timer_wq(cfqd);
+	q->elevator->elevator_data = NULL;
+
 	mempool_destroy(cfqd->crq_pool);
 	kfree(cfqd->crq_hash);
 	kfree(cfqd->cfq_hash);
@@ -1495,7 +2273,10 @@ static void cfq_put_cfqd(struct cfq_data
 
 static void cfq_exit_queue(elevator_t *e)
 {
-	cfq_put_cfqd(e->elevator_data);
+	struct cfq_data *cfqd = e->elevator_data;
+
+	cfq_shutdown_timer_wq(cfqd);
+	cfq_put_cfqd(cfqd);
 }
 
 static int cfq_init_queue(request_queue_t *q, elevator_t *e)
@@ -1508,7 +2289,13 @@ static int cfq_init_queue(request_queue_
 		return -ENOMEM;
 
 	memset(cfqd, 0, sizeof(*cfqd));
-	INIT_LIST_HEAD(&cfqd->rr_list);
+
+	for (i = 0; i < CFQ_PRIO_LISTS; i++)
+		INIT_LIST_HEAD(&cfqd->rr_list[i]);
+
+	INIT_LIST_HEAD(&cfqd->busy_rr);
+	INIT_LIST_HEAD(&cfqd->cur_rr);
+	INIT_LIST_HEAD(&cfqd->idle_rr);
 	INIT_LIST_HEAD(&cfqd->empty_list);
 
 	cfqd->crq_hash = kmalloc(sizeof(struct hlist_head) * CFQ_MHASH_ENTRIES, GFP_KERNEL);
@@ -1533,24 +2320,32 @@ static int cfq_init_queue(request_queue_
 	cfqd->queue = q;
 	atomic_inc(&q->refcnt);
 
-	/*
-	 * just set it to some high value, we want anyone to be able to queue
-	 * some requests. fairness is handled differently
-	 */
-	q->nr_requests = 1024;
-	cfqd->max_queued = q->nr_requests / 16;
+	cfqd->max_queued = q->nr_requests / 4;
 	q->nr_batching = cfq_queued;
-	cfqd->key_type = CFQ_KEY_TGID;
-	cfqd->find_best_crq = 1;
+
+	init_timer(&cfqd->idle_slice_timer);
+	cfqd->idle_slice_timer.function = cfq_idle_slice_timer;
+	cfqd->idle_slice_timer.data = (unsigned long) cfqd;
+
+	init_timer(&cfqd->idle_class_timer);
+	cfqd->idle_class_timer.function = cfq_idle_class_timer;
+	cfqd->idle_class_timer.data = (unsigned long) cfqd;
+
+	INIT_WORK(&cfqd->unplug_work, cfq_kick_queue, q);
+
 	atomic_set(&cfqd->ref, 1);
 
 	cfqd->cfq_queued = cfq_queued;
 	cfqd->cfq_quantum = cfq_quantum;
-	cfqd->cfq_fifo_expire_r = cfq_fifo_expire_r;
-	cfqd->cfq_fifo_expire_w = cfq_fifo_expire_w;
-	cfqd->cfq_fifo_batch_expire = cfq_fifo_rate;
+	cfqd->cfq_fifo_expire[0] = cfq_fifo_expire[0];
+	cfqd->cfq_fifo_expire[1] = cfq_fifo_expire[1];
 	cfqd->cfq_back_max = cfq_back_max;
 	cfqd->cfq_back_penalty = cfq_back_penalty;
+	cfqd->cfq_slice[0] = cfq_slice_async;
+	cfqd->cfq_slice[1] = cfq_slice_sync;
+	cfqd->cfq_slice_async_rq = cfq_slice_async_rq;
+	cfqd->cfq_slice_idle = cfq_slice_idle;
+	cfqd->cfq_max_depth = cfq_max_depth;
 
 	return 0;
 out_crqpool:
@@ -1595,7 +2390,6 @@ fail:
 	return -ENOMEM;
 }
 
-
 /*
  * sysfs parts below -->
  */
@@ -1620,45 +2414,6 @@ cfq_var_store(unsigned int *var, const c
 	return count;
 }
 
-static ssize_t
-cfq_clear_elapsed(struct cfq_data *cfqd, const char *page, size_t count)
-{
-	max_elapsed_dispatch = max_elapsed_crq = 0;
-	return count;
-}
-
-static ssize_t
-cfq_set_key_type(struct cfq_data *cfqd, const char *page, size_t count)
-{
-	spin_lock_irq(cfqd->queue->queue_lock);
-	if (!strncmp(page, "pgid", 4))
-		cfqd->key_type = CFQ_KEY_PGID;
-	else if (!strncmp(page, "tgid", 4))
-		cfqd->key_type = CFQ_KEY_TGID;
-	else if (!strncmp(page, "uid", 3))
-		cfqd->key_type = CFQ_KEY_UID;
-	else if (!strncmp(page, "gid", 3))
-		cfqd->key_type = CFQ_KEY_GID;
-	spin_unlock_irq(cfqd->queue->queue_lock);
-	return count;
-}
-
-static ssize_t
-cfq_read_key_type(struct cfq_data *cfqd, char *page)
-{
-	ssize_t len = 0;
-	int i;
-
-	for (i = CFQ_KEY_PGID; i < CFQ_KEY_LAST; i++) {
-		if (cfqd->key_type == i)
-			len += sprintf(page+len, "[%s] ", cfq_key_types[i]);
-		else
-			len += sprintf(page+len, "%s ", cfq_key_types[i]);
-	}
-	len += sprintf(page+len, "\n");
-	return len;
-}
-
 #define SHOW_FUNCTION(__FUNC, __VAR, __CONV)				\
 static ssize_t __FUNC(struct cfq_data *cfqd, char *page)		\
 {									\
@@ -1669,12 +2424,15 @@ static ssize_t __FUNC(struct cfq_data *c
 }
 SHOW_FUNCTION(cfq_quantum_show, cfqd->cfq_quantum, 0);
 SHOW_FUNCTION(cfq_queued_show, cfqd->cfq_queued, 0);
-SHOW_FUNCTION(cfq_fifo_expire_r_show, cfqd->cfq_fifo_expire_r, 1);
-SHOW_FUNCTION(cfq_fifo_expire_w_show, cfqd->cfq_fifo_expire_w, 1);
-SHOW_FUNCTION(cfq_fifo_batch_expire_show, cfqd->cfq_fifo_batch_expire, 1);
-SHOW_FUNCTION(cfq_find_best_show, cfqd->find_best_crq, 0);
+SHOW_FUNCTION(cfq_fifo_expire_sync_show, cfqd->cfq_fifo_expire[1], 1);
+SHOW_FUNCTION(cfq_fifo_expire_async_show, cfqd->cfq_fifo_expire[0], 1);
 SHOW_FUNCTION(cfq_back_max_show, cfqd->cfq_back_max, 0);
 SHOW_FUNCTION(cfq_back_penalty_show, cfqd->cfq_back_penalty, 0);
+SHOW_FUNCTION(cfq_slice_idle_show, cfqd->cfq_slice_idle, 1);
+SHOW_FUNCTION(cfq_slice_sync_show, cfqd->cfq_slice[1], 1);
+SHOW_FUNCTION(cfq_slice_async_show, cfqd->cfq_slice[0], 1);
+SHOW_FUNCTION(cfq_slice_async_rq_show, cfqd->cfq_slice_async_rq, 0);
+SHOW_FUNCTION(cfq_max_depth_show, cfqd->cfq_max_depth, 0);
 #undef SHOW_FUNCTION
 
 #define STORE_FUNCTION(__FUNC, __PTR, MIN, MAX, __CONV)			\
@@ -1694,12 +2452,15 @@ static ssize_t __FUNC(struct cfq_data *c
 }
 STORE_FUNCTION(cfq_quantum_store, &cfqd->cfq_quantum, 1, UINT_MAX, 0);
 STORE_FUNCTION(cfq_queued_store, &cfqd->cfq_queued, 1, UINT_MAX, 0);
-STORE_FUNCTION(cfq_fifo_expire_r_store, &cfqd->cfq_fifo_expire_r, 1, UINT_MAX, 1);
-STORE_FUNCTION(cfq_fifo_expire_w_store, &cfqd->cfq_fifo_expire_w, 1, UINT_MAX, 1);
-STORE_FUNCTION(cfq_fifo_batch_expire_store, &cfqd->cfq_fifo_batch_expire, 0, UINT_MAX, 1);
-STORE_FUNCTION(cfq_find_best_store, &cfqd->find_best_crq, 0, 1, 0);
+STORE_FUNCTION(cfq_fifo_expire_sync_store, &cfqd->cfq_fifo_expire[1], 1, UINT_MAX, 1);
+STORE_FUNCTION(cfq_fifo_expire_async_store, &cfqd->cfq_fifo_expire[0], 1, UINT_MAX, 1);
 STORE_FUNCTION(cfq_back_max_store, &cfqd->cfq_back_max, 0, UINT_MAX, 0);
 STORE_FUNCTION(cfq_back_penalty_store, &cfqd->cfq_back_penalty, 1, UINT_MAX, 0);
+STORE_FUNCTION(cfq_slice_idle_store, &cfqd->cfq_slice_idle, 0, UINT_MAX, 1);
+STORE_FUNCTION(cfq_slice_sync_store, &cfqd->cfq_slice[1], 1, UINT_MAX, 1);
+STORE_FUNCTION(cfq_slice_async_store, &cfqd->cfq_slice[0], 1, UINT_MAX, 1);
+STORE_FUNCTION(cfq_slice_async_rq_store, &cfqd->cfq_slice_async_rq, 1, UINT_MAX, 0);
+STORE_FUNCTION(cfq_max_depth_store, &cfqd->cfq_max_depth, 1, UINT_MAX, 0);
 #undef STORE_FUNCTION
 
 static struct cfq_fs_entry cfq_quantum_entry = {
@@ -1712,25 +2473,15 @@ static struct cfq_fs_entry cfq_queued_en
 	.show = cfq_queued_show,
 	.store = cfq_queued_store,
 };
-static struct cfq_fs_entry cfq_fifo_expire_r_entry = {
+static struct cfq_fs_entry cfq_fifo_expire_sync_entry = {
 	.attr = {.name = "fifo_expire_sync", .mode = S_IRUGO | S_IWUSR },
-	.show = cfq_fifo_expire_r_show,
-	.store = cfq_fifo_expire_r_store,
+	.show = cfq_fifo_expire_sync_show,
+	.store = cfq_fifo_expire_sync_store,
 };
-static struct cfq_fs_entry cfq_fifo_expire_w_entry = {
+static struct cfq_fs_entry cfq_fifo_expire_async_entry = {
 	.attr = {.name = "fifo_expire_async", .mode = S_IRUGO | S_IWUSR },
-	.show = cfq_fifo_expire_w_show,
-	.store = cfq_fifo_expire_w_store,
-};
-static struct cfq_fs_entry cfq_fifo_batch_expire_entry = {
-	.attr = {.name = "fifo_batch_expire", .mode = S_IRUGO | S_IWUSR },
-	.show = cfq_fifo_batch_expire_show,
-	.store = cfq_fifo_batch_expire_store,
-};
-static struct cfq_fs_entry cfq_find_best_entry = {
-	.attr = {.name = "find_best_crq", .mode = S_IRUGO | S_IWUSR },
-	.show = cfq_find_best_show,
-	.store = cfq_find_best_store,
+	.show = cfq_fifo_expire_async_show,
+	.store = cfq_fifo_expire_async_store,
 };
 static struct cfq_fs_entry cfq_back_max_entry = {
 	.attr = {.name = "back_seek_max", .mode = S_IRUGO | S_IWUSR },
@@ -1742,27 +2493,44 @@ static struct cfq_fs_entry cfq_back_pena
 	.show = cfq_back_penalty_show,
 	.store = cfq_back_penalty_store,
 };
-static struct cfq_fs_entry cfq_clear_elapsed_entry = {
-	.attr = {.name = "clear_elapsed", .mode = S_IWUSR },
-	.store = cfq_clear_elapsed,
-};
-static struct cfq_fs_entry cfq_key_type_entry = {
-	.attr = {.name = "key_type", .mode = S_IRUGO | S_IWUSR },
-	.show = cfq_read_key_type,
-	.store = cfq_set_key_type,
+static struct cfq_fs_entry cfq_slice_sync_entry = {
+	.attr = {.name = "slice_sync", .mode = S_IRUGO | S_IWUSR },
+	.show = cfq_slice_sync_show,
+	.store = cfq_slice_sync_store,
+};
+static struct cfq_fs_entry cfq_slice_async_entry = {
+	.attr = {.name = "slice_async", .mode = S_IRUGO | S_IWUSR },
+	.show = cfq_slice_async_show,
+	.store = cfq_slice_async_store,
+};
+static struct cfq_fs_entry cfq_slice_async_rq_entry = {
+	.attr = {.name = "slice_async_rq", .mode = S_IRUGO | S_IWUSR },
+	.show = cfq_slice_async_rq_show,
+	.store = cfq_slice_async_rq_store,
+};
+static struct cfq_fs_entry cfq_slice_idle_entry = {
+	.attr = {.name = "slice_idle", .mode = S_IRUGO | S_IWUSR },
+	.show = cfq_slice_idle_show,
+	.store = cfq_slice_idle_store,
+};
+static struct cfq_fs_entry cfq_max_depth_entry = {
+	.attr = {.name = "max_depth", .mode = S_IRUGO | S_IWUSR },
+	.show = cfq_max_depth_show,
+	.store = cfq_max_depth_store,
 };
 
 static struct attribute *default_attrs[] = {
 	&cfq_quantum_entry.attr,
 	&cfq_queued_entry.attr,
-	&cfq_fifo_expire_r_entry.attr,
-	&cfq_fifo_expire_w_entry.attr,
-	&cfq_fifo_batch_expire_entry.attr,
-	&cfq_key_type_entry.attr,
-	&cfq_find_best_entry.attr,
+	&cfq_fifo_expire_sync_entry.attr,
+	&cfq_fifo_expire_async_entry.attr,
 	&cfq_back_max_entry.attr,
 	&cfq_back_penalty_entry.attr,
-	&cfq_clear_elapsed_entry.attr,
+	&cfq_slice_sync_entry.attr,
+	&cfq_slice_async_entry.attr,
+	&cfq_slice_async_rq_entry.attr,
+	&cfq_slice_idle_entry.attr,
+	&cfq_max_depth_entry.attr,
 	NULL,
 };
 
@@ -1775,7 +2543,7 @@ cfq_attr_show(struct kobject *kobj, stru
 	struct cfq_fs_entry *entry = to_cfq(attr);
 
 	if (!entry->show)
-		return 0;
+		return -EIO;
 
 	return entry->show(e->elevator_data, page);
 }
@@ -1788,7 +2556,7 @@ cfq_attr_store(struct kobject *kobj, str
 	struct cfq_fs_entry *entry = to_cfq(attr);
 
 	if (!entry->store)
-		return -EINVAL;
+		return -EIO;
 
 	return entry->store(e->elevator_data, page, length);
 }
@@ -1832,21 +2600,46 @@ static int __init cfq_init(void)
 {
 	int ret;
 
+	/*
+	 * could be 0 on HZ < 1000 setups
+	 */
+	if (!cfq_slice_async)
+		cfq_slice_async = 1;
+	if (!cfq_slice_idle)
+		cfq_slice_idle = 1;
+
 	if (cfq_slab_setup())
 		return -ENOMEM;
 
 	ret = elv_register(&iosched_cfq);
-	if (!ret) {
-		__module_get(THIS_MODULE);
-		return 0;
-	}
+	if (ret)
+		cfq_slab_kill();
 
-	cfq_slab_kill();
 	return ret;
 }
 
 static void __exit cfq_exit(void)
 {
+	struct task_struct *g, *p;
+	unsigned long flags;
+
+	read_lock_irqsave(&tasklist_lock, flags);
+
+	/*
+	 * iterate each process in the system, removing our io_context
+	 */
+	do_each_thread(g, p) {
+		struct io_context *ioc = p->io_context;
+
+		if (ioc && ioc->cic) {
+			ioc->cic->exit(ioc->cic);
+			cfq_free_io_context(ioc->cic);
+			ioc->cic = NULL;
+		}
+	} while_each_thread(g, p);
+
+	read_unlock_irqrestore(&tasklist_lock, flags);
+
 	cfq_slab_kill();
 	elv_unregister(&iosched_cfq);
 }
diff --git a/drivers/block/deadline-iosched.c b/drivers/block/deadline-iosched.c
--- a/drivers/block/deadline-iosched.c
+++ b/drivers/block/deadline-iosched.c
@@ -711,18 +711,20 @@ static int deadline_init_queue(request_q
 	if (!drq_pool)
 		return -ENOMEM;
 
-	dd = kmalloc(sizeof(*dd), GFP_KERNEL);
+	dd = kmalloc_node(sizeof(*dd), GFP_KERNEL, q->node);
 	if (!dd)
 		return -ENOMEM;
 	memset(dd, 0, sizeof(*dd));
 
-	dd->hash = kmalloc(sizeof(struct list_head)*DL_HASH_ENTRIES,GFP_KERNEL);
+	dd->hash = kmalloc_node(sizeof(struct list_head)*DL_HASH_ENTRIES,
+				GFP_KERNEL, q->node);
 	if (!dd->hash) {
 		kfree(dd);
 		return -ENOMEM;
 	}
 
-	dd->drq_pool = mempool_create(BLKDEV_MIN_RQ, mempool_alloc_slab, mempool_free_slab, drq_pool);
+	dd->drq_pool = mempool_create_node(BLKDEV_MIN_RQ, mempool_alloc_slab,
+					mempool_free_slab, drq_pool, q->node);
 	if (!dd->drq_pool) {
 		kfree(dd->hash);
 		kfree(dd);
@@ -758,7 +760,8 @@ static void deadline_put_request(request
 }
 
 static int
-deadline_set_request(request_queue_t *q, struct request *rq, int gfp_mask)
+deadline_set_request(request_queue_t *q, struct request *rq, struct bio *bio,
+		     int gfp_mask)
 {
 	struct deadline_data *dd = q->elevator->elevator_data;
 	struct deadline_rq *drq;
@@ -886,7 +889,7 @@ deadline_attr_show(struct kobject *kobj,
 	struct deadline_fs_entry *entry = to_deadline(attr);
 
 	if (!entry->show)
-		return 0;
+		return -EIO;
 
 	return entry->show(e->elevator_data, page);
 }
@@ -899,7 +902,7 @@ deadline_attr_store(struct kobject *kobj
 	struct deadline_fs_entry *entry = to_deadline(attr);
 
 	if (!entry->store)
-		return -EINVAL;
+		return -EIO;
 
 	return entry->store(e->elevator_data, page, length);
 }
diff --git a/drivers/block/elevator.c b/drivers/block/elevator.c
--- a/drivers/block/elevator.c
+++ b/drivers/block/elevator.c
@@ -286,6 +286,13 @@ void elv_requeue_request(request_queue_t
 	}
 
 	/*
+	 * the request is prepped and may have some resources allocated.
+	 * allowing unprepped requests to pass this one may cause resource
+	 * deadlock.  turn on softbarrier.
+	 */
+	rq->flags |= REQ_SOFTBARRIER;
+
+	/*
 	 * if iosched has an explicit requeue hook, then use that. otherwise
 	 * just put the request at the front of the queue
 	 */
@@ -381,6 +388,12 @@ struct request *elv_next_request(request
 		if (ret == BLKPREP_OK) {
 			break;
 		} else if (ret == BLKPREP_DEFER) {
+			/*
+			 * the request may have been (partially) prepped.
+			 * we need to keep this request in the front to
+			 * avoid resource deadlock.  turn on softbarrier.
+			 */
+			rq->flags |= REQ_SOFTBARRIER;
 			rq = NULL;
 			break;
 		} else if (ret == BLKPREP_KILL) {
@@ -473,12 +486,13 @@ struct request *elv_former_request(reque
 	return NULL;
 }
 
-int elv_set_request(request_queue_t *q, struct request *rq, int gfp_mask)
+int elv_set_request(request_queue_t *q, struct request *rq, struct bio *bio,
+		    int gfp_mask)
 {
 	elevator_t *e = q->elevator;
 
 	if (e->ops->elevator_set_req_fn)
-		return e->ops->elevator_set_req_fn(q, rq, gfp_mask);
+		return e->ops->elevator_set_req_fn(q, rq, bio, gfp_mask);
 
 	rq->elevator_private = NULL;
 	return 0;
@@ -492,12 +506,12 @@ void elv_put_request(request_queue_t *q,
 		e->ops->elevator_put_req_fn(q, rq);
 }
 
-int elv_may_queue(request_queue_t *q, int rw)
+int elv_may_queue(request_queue_t *q, int rw, struct bio *bio)
 {
 	elevator_t *e = q->elevator;
 
 	if (e->ops->elevator_may_queue_fn)
-		return e->ops->elevator_may_queue_fn(q, rw);
+		return e->ops->elevator_may_queue_fn(q, rw, bio);
 
 	return ELV_MQUEUE_MAY;
 }
diff --git a/drivers/block/genhd.c b/drivers/block/genhd.c
--- a/drivers/block/genhd.c
+++ b/drivers/block/genhd.c
@@ -40,7 +40,7 @@ static inline int major_to_index(int maj
 
 #ifdef CONFIG_PROC_FS
 /* get block device names in somewhat random order */
-int get_blkdev_list(char *p)
+int get_blkdev_list(char *p, int used)
 {
 	struct blk_major_name *n;
 	int i, len;
@@ -49,10 +49,18 @@ int get_blkdev_list(char *p)
 
 	down(&block_subsys_sem);
 	for (i = 0; i < ARRAY_SIZE(major_names); i++) {
-		for (n = major_names[i]; n; n = n->next)
+		for (n = major_names[i]; n; n = n->next) {
+			/*
+			 * If the curent string plus the 5 extra characters
+			 * in the line would run us off the page, then we're done
+			 */
+			if ((len + used + strlen(n->name) + 5) >= PAGE_SIZE)
+				goto page_full;
 			len += sprintf(p+len, "%3d %s\n",
 				       n->major, n->name);
+		}
 	}
+page_full:
 	up(&block_subsys_sem);
 
 	return len;
@@ -322,7 +330,7 @@ static ssize_t disk_attr_show(struct kob
 	struct gendisk *disk = to_disk(kobj);
 	struct disk_attribute *disk_attr =
 		container_of(attr,struct disk_attribute,attr);
-	ssize_t ret = 0;
+	ssize_t ret = -EIO;
 
 	if (disk_attr->show)
 		ret = disk_attr->show(disk,page);
@@ -582,10 +590,16 @@ struct seq_operations diskstats_op = {
 	.show	= diskstats_show
 };
 
-
 struct gendisk *alloc_disk(int minors)
 {
-	struct gendisk *disk = kmalloc(sizeof(struct gendisk), GFP_KERNEL);
+	return alloc_disk_node(minors, -1);
+}
+
+struct gendisk *alloc_disk_node(int minors, int node_id)
+{
+	struct gendisk *disk;
+
+	disk = kmalloc_node(sizeof(struct gendisk), GFP_KERNEL, node_id);
 	if (disk) {
 		memset(disk, 0, sizeof(struct gendisk));
 		if (!init_disk_stats(disk)) {
@@ -594,7 +608,7 @@ struct gendisk *alloc_disk(int minors)
 		}
 		if (minors > 1) {
 			int size = (minors - 1) * sizeof(struct hd_struct *);
-			disk->part = kmalloc(size, GFP_KERNEL);
+			disk->part = kmalloc_node(size, GFP_KERNEL, node_id);
 			if (!disk->part) {
 				kfree(disk);
 				return NULL;
@@ -610,6 +624,7 @@ struct gendisk *alloc_disk(int minors)
 }
 
 EXPORT_SYMBOL(alloc_disk);
+EXPORT_SYMBOL(alloc_disk_node);
 
 struct kobject *get_disk(struct gendisk *disk)
 {
diff --git a/drivers/block/ioctl.c b/drivers/block/ioctl.c
--- a/drivers/block/ioctl.c
+++ b/drivers/block/ioctl.c
@@ -133,11 +133,9 @@ static int put_u64(unsigned long arg, u6
 	return put_user(val, (u64 __user *)arg);
 }
 
-int blkdev_ioctl(struct inode *inode, struct file *file, unsigned cmd,
-			unsigned long arg)
+static int blkdev_locked_ioctl(struct file *file, struct block_device *bdev,
+				unsigned cmd, unsigned long arg)
 {
-	struct block_device *bdev = inode->i_bdev;
-	struct gendisk *disk = bdev->bd_disk;
 	struct backing_dev_info *bdi;
 	int ret, n;
 
@@ -190,36 +188,72 @@ int blkdev_ioctl(struct inode *inode, st
 		return put_ulong(arg, bdev->bd_inode->i_size >> 9);
 	case BLKGETSIZE64:
 		return put_u64(arg, bdev->bd_inode->i_size);
+	}
+	return -ENOIOCTLCMD;
+}
+
+static int blkdev_driver_ioctl(struct inode *inode, struct file *file,
+		struct gendisk *disk, unsigned cmd, unsigned long arg)
+{
+	int ret;
+	if (disk->fops->unlocked_ioctl)
+		return disk->fops->unlocked_ioctl(file, cmd, arg);
+
+	if (disk->fops->ioctl) {
+		lock_kernel();
+		ret = disk->fops->ioctl(inode, file, cmd, arg);
+		unlock_kernel();
+		return ret;
+	}
+
+	return -ENOTTY;
+}
+
+int blkdev_ioctl(struct inode *inode, struct file *file, unsigned cmd,
+			unsigned long arg)
+{
+	struct block_device *bdev = inode->i_bdev;
+	struct gendisk *disk = bdev->bd_disk;
+	int ret, n;
+
+	switch(cmd) {
 	case BLKFLSBUF:
 		if (!capable(CAP_SYS_ADMIN))
 			return -EACCES;
-		if (disk->fops->ioctl) {
-			ret = disk->fops->ioctl(inode, file, cmd, arg);
-			/* -EINVAL to handle old uncorrected drivers */
-			if (ret != -EINVAL && ret != -ENOTTY)
-				return ret;
-		}
+
+		ret = blkdev_driver_ioctl(inode, file, disk, cmd, arg);
+		/* -EINVAL to handle old uncorrected drivers */
+		if (ret != -EINVAL && ret != -ENOTTY)
+			return ret;
+
+		lock_kernel();
 		fsync_bdev(bdev);
 		invalidate_bdev(bdev, 0);
+		unlock_kernel();
 		return 0;
+
 	case BLKROSET:
-		if (disk->fops->ioctl) {
-			ret = disk->fops->ioctl(inode, file, cmd, arg);
-			/* -EINVAL to handle old uncorrected drivers */
-			if (ret != -EINVAL && ret != -ENOTTY)
-				return ret;
-		}
+		ret = blkdev_driver_ioctl(inode, file, disk, cmd, arg);
+		/* -EINVAL to handle old uncorrected drivers */
+		if (ret != -EINVAL && ret != -ENOTTY)
+			return ret;
 		if (!capable(CAP_SYS_ADMIN))
 			return -EACCES;
 		if (get_user(n, (int __user *)(arg)))
 			return -EFAULT;
+		lock_kernel();
 		set_device_ro(bdev, n);
+		unlock_kernel();
 		return 0;
-	default:
-		if (disk->fops->ioctl)
-			return disk->fops->ioctl(inode, file, cmd, arg);
 	}
-	return -ENOTTY;
+
+	lock_kernel();
+	ret = blkdev_locked_ioctl(file, bdev, cmd, arg);
+	unlock_kernel();
+	if (ret != -ENOIOCTLCMD)
+		return ret;
+
+	return blkdev_driver_ioctl(inode, file, disk, cmd, arg);
 }
 
 /* Most of the generic ioctls are handled in the normal fallback path.
diff --git a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c
--- a/drivers/block/ll_rw_blk.c
+++ b/drivers/block/ll_rw_blk.c
@@ -28,6 +28,7 @@
 #include <linux/slab.h>
 #include <linux/swap.h>
 #include <linux/writeback.h>
+#include <linux/blkdev.h>
 
 /*
  * for max sense size
@@ -36,6 +37,7 @@
 
 static void blk_unplug_work(void *data);
 static void blk_unplug_timeout(unsigned long data);
+static void drive_stat_acct(struct request *rq, int nr_sectors, int new_io);
 
 /*
  * For the allocated request tables
@@ -274,6 +276,7 @@ static inline void rq_init(request_queue
 	rq->errors = 0;
 	rq->rq_status = RQ_ACTIVE;
 	rq->bio = rq->biotail = NULL;
+	rq->ioprio = 0;
 	rq->buffer = NULL;
 	rq->ref_count = 1;
 	rq->q = q;
@@ -774,9 +777,9 @@ EXPORT_SYMBOL(blk_queue_free_tags);
 static int
 init_tag_map(request_queue_t *q, struct blk_queue_tag *tags, int depth)
 {
-	int bits, i;
 	struct request **tag_index;
 	unsigned long *tag_map;
+	int nr_ulongs;
 
 	if (depth > q->nr_requests * 2) {
 		depth = q->nr_requests * 2;
@@ -788,24 +791,18 @@ init_tag_map(request_queue_t *q, struct 
 	if (!tag_index)
 		goto fail;
 
-	bits = (depth / BLK_TAGS_PER_LONG) + 1;
-	tag_map = kmalloc(bits * sizeof(unsigned long), GFP_ATOMIC);
+	nr_ulongs = ALIGN(depth, BITS_PER_LONG) / BITS_PER_LONG;
+	tag_map = kmalloc(nr_ulongs * sizeof(unsigned long), GFP_ATOMIC);
 	if (!tag_map)
 		goto fail;
 
 	memset(tag_index, 0, depth * sizeof(struct request *));
-	memset(tag_map, 0, bits * sizeof(unsigned long));
+	memset(tag_map, 0, nr_ulongs * sizeof(unsigned long));
+	tags->real_max_depth = depth;
 	tags->max_depth = depth;
-	tags->real_max_depth = bits * BITS_PER_LONG;
 	tags->tag_index = tag_index;
 	tags->tag_map = tag_map;
 
-	/*
-	 * set the upper bits if the depth isn't a multiple of the word size
-	 */
-	for (i = depth; i < bits * BLK_TAGS_PER_LONG; i++)
-		__set_bit(i, tag_map);
-
 	return 0;
 fail:
 	kfree(tag_index);
@@ -870,13 +867,16 @@ int blk_queue_resize_tags(request_queue_
 	struct blk_queue_tag *bqt = q->queue_tags;
 	struct request **tag_index;
 	unsigned long *tag_map;
-	int bits, max_depth;
+	int max_depth, nr_ulongs;
 
 	if (!bqt)
 		return -ENXIO;
 
 	/*
-	 * don't bother sizing down
+	 * if we already have large enough real_max_depth.  just
+	 * adjust max_depth.  *NOTE* as requests with tag value
+	 * between new_depth and real_max_depth can be in-flight, tag
+	 * map can not be shrunk blindly here.
 	 */
 	if (new_depth <= bqt->real_max_depth) {
 		bqt->max_depth = new_depth;
@@ -894,8 +894,8 @@ int blk_queue_resize_tags(request_queue_
 		return -ENOMEM;
 
 	memcpy(bqt->tag_index, tag_index, max_depth * sizeof(struct request *));
-	bits = max_depth / BLK_TAGS_PER_LONG;
-	memcpy(bqt->tag_map, tag_map, bits * sizeof(unsigned long));
+	nr_ulongs = ALIGN(max_depth, BITS_PER_LONG) / BITS_PER_LONG;
+	memcpy(bqt->tag_map, tag_map, nr_ulongs * sizeof(unsigned long));
 
 	kfree(tag_index);
 	kfree(tag_map);
@@ -926,10 +926,15 @@ void blk_queue_end_tag(request_queue_t *
 	BUG_ON(tag == -1);
 
 	if (unlikely(tag >= bqt->real_max_depth))
+		/*
+		 * This can happen after tag depth has been reduced.
+		 * FIXME: how about a warning or info message here?
+		 */
 		return;
 
 	if (unlikely(!__test_and_clear_bit(tag, bqt->tag_map))) {
-		printk("attempt to clear non-busy tag (%d)\n", tag);
+		printk(KERN_ERR "%s: attempt to clear non-busy tag (%d)\n",
+		       __FUNCTION__, tag);
 		return;
 	}
 
@@ -938,7 +943,8 @@ void blk_queue_end_tag(request_queue_t *
 	rq->tag = -1;
 
 	if (unlikely(bqt->tag_index[tag] == NULL))
-		printk("tag %d is missing\n", tag);
+		printk(KERN_ERR "%s: tag %d is missing\n",
+		       __FUNCTION__, tag);
 
 	bqt->tag_index[tag] = NULL;
 	bqt->busy--;
@@ -967,24 +973,20 @@ EXPORT_SYMBOL(blk_queue_end_tag);
 int blk_queue_start_tag(request_queue_t *q, struct request *rq)
 {
 	struct blk_queue_tag *bqt = q->queue_tags;
-	unsigned long *map = bqt->tag_map;
-	int tag = 0;
+	int tag;
 
 	if (unlikely((rq->flags & REQ_QUEUED))) {
 		printk(KERN_ERR 
-		       "request %p for device [%s] already tagged %d",
-		       rq, rq->rq_disk ? rq->rq_disk->disk_name : "?", rq->tag);
+		       "%s: request %p for device [%s] already tagged %d",
+		       __FUNCTION__, rq,
+		       rq->rq_disk ? rq->rq_disk->disk_name : "?", rq->tag);
 		BUG();
 	}
 
-	for (map = bqt->tag_map; *map == -1UL; map++) {
-		tag += BLK_TAGS_PER_LONG;
-
-		if (tag >= bqt->max_depth)
-			return 1;
-	}
+	tag = find_first_zero_bit(bqt->tag_map, bqt->max_depth);
+	if (tag >= bqt->max_depth)
+		return 1;
 
-	tag += ffz(*map);
 	__set_bit(tag, bqt->tag_map);
 
 	rq->flags |= REQ_QUEUED;
@@ -1020,7 +1022,8 @@ void blk_queue_invalidate_tags(request_q
 		rq = list_entry_rq(tmp);
 
 		if (rq->tag == -1) {
-			printk("bad tag found on list\n");
+			printk(KERN_ERR
+			       "%s: bad tag found on list\n", __FUNCTION__);
 			list_del_init(&rq->queuelist);
 			rq->flags &= ~REQ_QUEUED;
 		} else
@@ -1148,7 +1151,7 @@ new_hw_segment:
 }
 
 
-int blk_phys_contig_segment(request_queue_t *q, struct bio *bio,
+static int blk_phys_contig_segment(request_queue_t *q, struct bio *bio,
 				   struct bio *nxt)
 {
 	if (!(q->queue_flags & (1 << QUEUE_FLAG_CLUSTER)))
@@ -1169,9 +1172,7 @@ int blk_phys_contig_segment(request_queu
 	return 0;
 }
 
-EXPORT_SYMBOL(blk_phys_contig_segment);
-
-int blk_hw_contig_segment(request_queue_t *q, struct bio *bio,
+static int blk_hw_contig_segment(request_queue_t *q, struct bio *bio,
 				 struct bio *nxt)
 {
 	if (unlikely(!bio_flagged(bio, BIO_SEG_VALID)))
@@ -1187,8 +1188,6 @@ int blk_hw_contig_segment(request_queue_
 	return 1;
 }
 
-EXPORT_SYMBOL(blk_hw_contig_segment);
-
 /*
  * map a request to scatterlist, return number of sg entries setup. Caller
  * must make sure sg can hold rq->nr_phys_segments entries
@@ -1358,8 +1357,8 @@ static int ll_front_merge_fn(request_que
 static int ll_merge_requests_fn(request_queue_t *q, struct request *req,
 				struct request *next)
 {
-	int total_phys_segments = req->nr_phys_segments +next->nr_phys_segments;
-	int total_hw_segments = req->nr_hw_segments + next->nr_hw_segments;
+	int total_phys_segments;
+	int total_hw_segments;
 
 	/*
 	 * First check if the either of the requests are re-queued
@@ -1369,7 +1368,7 @@ static int ll_merge_requests_fn(request_
 		return 0;
 
 	/*
-	 * Will it become to large?
+	 * Will it become too large?
 	 */
 	if ((req->nr_sectors + next->nr_sectors) > q->max_sectors)
 		return 0;
@@ -1450,17 +1449,13 @@ EXPORT_SYMBOL(blk_remove_plug);
  */
 void __generic_unplug_device(request_queue_t *q)
 {
-	if (test_bit(QUEUE_FLAG_STOPPED, &q->queue_flags))
+	if (unlikely(test_bit(QUEUE_FLAG_STOPPED, &q->queue_flags)))
 		return;
 
 	if (!blk_remove_plug(q))
 		return;
 
-	/*
-	 * was plugged, fire request_fn if queue has stuff to do
-	 */
-	if (elv_next_request(q))
-		q->request_fn(q);
+	q->request_fn(q);
 }
 EXPORT_SYMBOL(__generic_unplug_device);
 
@@ -1645,7 +1640,8 @@ static int blk_init_free_list(request_qu
 	init_waitqueue_head(&rl->wait[WRITE]);
 	init_waitqueue_head(&rl->drain);
 
-	rl->rq_pool = mempool_create(BLKDEV_MIN_RQ, mempool_alloc_slab, mempool_free_slab, request_cachep);
+	rl->rq_pool = mempool_create_node(BLKDEV_MIN_RQ, mempool_alloc_slab,
+				mempool_free_slab, request_cachep, q->node);
 
 	if (!rl->rq_pool)
 		return -ENOMEM;
@@ -1657,8 +1653,15 @@ static int __make_request(request_queue_
 
 request_queue_t *blk_alloc_queue(int gfp_mask)
 {
-	request_queue_t *q = kmem_cache_alloc(requestq_cachep, gfp_mask);
+	return blk_alloc_queue_node(gfp_mask, -1);
+}
+EXPORT_SYMBOL(blk_alloc_queue);
+
+request_queue_t *blk_alloc_queue_node(int gfp_mask, int node_id)
+{
+	request_queue_t *q;
 
+	q = kmem_cache_alloc_node(requestq_cachep, gfp_mask, node_id);
 	if (!q)
 		return NULL;
 
@@ -1671,8 +1674,7 @@ request_queue_t *blk_alloc_queue(int gfp
 
 	return q;
 }
-
-EXPORT_SYMBOL(blk_alloc_queue);
+EXPORT_SYMBOL(blk_alloc_queue_node);
 
 /**
  * blk_init_queue  - prepare a request queue for use with a block device
@@ -1705,13 +1707,22 @@ EXPORT_SYMBOL(blk_alloc_queue);
  *    blk_init_queue() must be paired with a blk_cleanup_queue() call
  *    when the block device is deactivated (such as at module unload).
  **/
+
 request_queue_t *blk_init_queue(request_fn_proc *rfn, spinlock_t *lock)
 {
-	request_queue_t *q = blk_alloc_queue(GFP_KERNEL);
+	return blk_init_queue_node(rfn, lock, -1);
+}
+EXPORT_SYMBOL(blk_init_queue);
+
+request_queue_t *
+blk_init_queue_node(request_fn_proc *rfn, spinlock_t *lock, int node_id)
+{
+	request_queue_t *q = blk_alloc_queue_node(GFP_KERNEL, node_id);
 
 	if (!q)
 		return NULL;
 
+	q->node = node_id;
 	if (blk_init_free_list(q))
 		goto out_init;
 
@@ -1754,12 +1765,11 @@ out_init:
 	kmem_cache_free(requestq_cachep, q);
 	return NULL;
 }
-
-EXPORT_SYMBOL(blk_init_queue);
+EXPORT_SYMBOL(blk_init_queue_node);
 
 int blk_get_queue(request_queue_t *q)
 {
-	if (!test_bit(QUEUE_FLAG_DEAD, &q->queue_flags)) {
+	if (likely(!test_bit(QUEUE_FLAG_DEAD, &q->queue_flags))) {
 		atomic_inc(&q->refcnt);
 		return 0;
 	}
@@ -1775,8 +1785,8 @@ static inline void blk_free_request(requ
 	mempool_free(rq, q->rq.rq_pool);
 }
 
-static inline struct request *blk_alloc_request(request_queue_t *q, int rw,
-						int gfp_mask)
+static inline struct request *
+blk_alloc_request(request_queue_t *q, int rw, struct bio *bio, int gfp_mask)
 {
 	struct request *rq = mempool_alloc(q->rq.rq_pool, gfp_mask);
 
@@ -1789,7 +1799,7 @@ static inline struct request *blk_alloc_
 	 */
 	rq->flags = rw;
 
-	if (!elv_set_request(q, rq, gfp_mask))
+	if (!elv_set_request(q, rq, bio, gfp_mask))
 		return rq;
 
 	mempool_free(rq, q->rq.rq_pool);
@@ -1821,7 +1831,7 @@ static inline int ioc_batching(request_q
  * is the behaviour we want though - once it gets a wakeup it should be given
  * a nice run.
  */
-void ioc_set_batching(request_queue_t *q, struct io_context *ioc)
+static void ioc_set_batching(request_queue_t *q, struct io_context *ioc)
 {
 	if (!ioc || ioc_batching(q, ioc))
 		return;
@@ -1838,7 +1848,6 @@ static void __freed_request(request_queu
 		clear_queue_congested(q, rw);
 
 	if (rl->count[rw] + 1 <= q->nr_requests) {
-		smp_mb();
 		if (waitqueue_active(&rl->wait[rw]))
 			wake_up(&rl->wait[rw]);
 
@@ -1870,18 +1879,20 @@ static void freed_request(request_queue_
 
 #define blkdev_free_rq(list) list_entry((list)->next, struct request, queuelist)
 /*
- * Get a free request, queue_lock must not be held
+ * Get a free request, queue_lock must be held.
+ * Returns NULL on failure, with queue_lock held.
+ * Returns !NULL on success, with queue_lock *not held*.
  */
-static struct request *get_request(request_queue_t *q, int rw, int gfp_mask)
+static struct request *get_request(request_queue_t *q, int rw, struct bio *bio,
+				   int gfp_mask)
 {
 	struct request *rq = NULL;
 	struct request_list *rl = &q->rq;
-	struct io_context *ioc = get_io_context(gfp_mask);
+	struct io_context *ioc = current_io_context(GFP_ATOMIC);
 
 	if (unlikely(test_bit(QUEUE_FLAG_DRAIN, &q->queue_flags)))
 		goto out;
 
-	spin_lock_irq(q->queue_lock);
 	if (rl->count[rw]+1 >= q->nr_requests) {
 		/*
 		 * The queue will fill after this allocation, so set it as
@@ -1895,7 +1906,7 @@ static struct request *get_request(reque
 		}
 	}
 
-	switch (elv_may_queue(q, rw)) {
+	switch (elv_may_queue(q, rw, bio)) {
 		case ELV_MQUEUE_NO:
 			goto rq_starved;
 		case ELV_MQUEUE_MAY:
@@ -1909,18 +1920,25 @@ static struct request *get_request(reque
 		 * The queue is full and the allocating process is not a
 		 * "batcher", and not exempted by the IO scheduler
 		 */
-		spin_unlock_irq(q->queue_lock);
 		goto out;
 	}
 
 get_rq:
+	/*
+	 * Only allow batching queuers to allocate up to 50% over the defined
+	 * limit of requests, otherwise we could have thousands of requests
+	 * allocated with any setting of ->nr_requests
+	 */
+	if (rl->count[rw] >= (3 * q->nr_requests / 2))
+		goto out;
+
 	rl->count[rw]++;
 	rl->starved[rw] = 0;
 	if (rl->count[rw] >= queue_congestion_on_threshold(q))
 		set_queue_congested(q, rw);
 	spin_unlock_irq(q->queue_lock);
 
-	rq = blk_alloc_request(q, rw, gfp_mask);
+	rq = blk_alloc_request(q, rw, bio, gfp_mask);
 	if (!rq) {
 		/*
 		 * Allocation failed presumably due to memory. Undo anything
@@ -1943,7 +1961,6 @@ rq_starved:
 		if (unlikely(rl->count[rw] == 0))
 			rl->starved[rw] = 1;
 
-		spin_unlock_irq(q->queue_lock);
 		goto out;
 	}
 
@@ -1953,31 +1970,35 @@ rq_starved:
 	rq_init(q, rq);
 	rq->rl = rl;
 out:
-	put_io_context(ioc);
 	return rq;
 }
 
 /*
  * No available requests for this queue, unplug the device and wait for some
  * requests to become available.
+ *
+ * Called with q->queue_lock held, and returns with it unlocked.
  */
-static struct request *get_request_wait(request_queue_t *q, int rw)
+static struct request *get_request_wait(request_queue_t *q, int rw,
+					struct bio *bio)
 {
-	DEFINE_WAIT(wait);
 	struct request *rq;
 
-	generic_unplug_device(q);
-	do {
+	rq = get_request(q, rw, bio, GFP_NOIO);
+	while (!rq) {
+		DEFINE_WAIT(wait);
 		struct request_list *rl = &q->rq;
 
 		prepare_to_wait_exclusive(&rl->wait[rw], &wait,
 				TASK_UNINTERRUPTIBLE);
 
-		rq = get_request(q, rw, GFP_NOIO);
+		rq = get_request(q, rw, bio, GFP_NOIO);
 
 		if (!rq) {
 			struct io_context *ioc;
 
+			__generic_unplug_device(q);
+			spin_unlock_irq(q->queue_lock);
 			io_schedule();
 
 			/*
@@ -1986,12 +2007,13 @@ static struct request *get_request_wait(
 			 * up to a big batch of them for a small period time.
 			 * See ioc_batching, ioc_set_batching
 			 */
-			ioc = get_io_context(GFP_NOIO);
+			ioc = current_io_context(GFP_NOIO);
 			ioc_set_batching(q, ioc);
-			put_io_context(ioc);
+
+			spin_lock_irq(q->queue_lock);
 		}
 		finish_wait(&rl->wait[rw], &wait);
-	} while (!rq);
+	}
 
 	return rq;
 }
@@ -2002,14 +2024,18 @@ struct request *blk_get_request(request_
 
 	BUG_ON(rw != READ && rw != WRITE);
 
-	if (gfp_mask & __GFP_WAIT)
-		rq = get_request_wait(q, rw);
-	else
-		rq = get_request(q, rw, gfp_mask);
+	spin_lock_irq(q->queue_lock);
+	if (gfp_mask & __GFP_WAIT) {
+		rq = get_request_wait(q, rw, NULL);
+	} else {
+		rq = get_request(q, rw, NULL, gfp_mask);
+		if (!rq)
+			spin_unlock_irq(q->queue_lock);
+	}
+	/* q->queue_lock is unlocked at this point */
 
 	return rq;
 }
-
 EXPORT_SYMBOL(blk_get_request);
 
 /**
@@ -2038,7 +2064,6 @@ EXPORT_SYMBOL(blk_requeue_request);
  * @rq:		request to be inserted
  * @at_head:	insert request at head or tail of queue
  * @data:	private data
- * @reinsert:	true if request it a reinsertion of previously processed one
  *
  * Description:
  *    Many block devices need to execute commands asynchronously, so they don't
@@ -2053,8 +2078,9 @@ EXPORT_SYMBOL(blk_requeue_request);
  *    host that is unable to accept a particular command.
  */
 void blk_insert_request(request_queue_t *q, struct request *rq,
-			int at_head, void *data, int reinsert)
+			int at_head, void *data)
 {
+	int where = at_head ? ELEVATOR_INSERT_FRONT : ELEVATOR_INSERT_BACK;
 	unsigned long flags;
 
 	/*
@@ -2071,20 +2097,12 @@ void blk_insert_request(request_queue_t 
 	/*
 	 * If command is tagged, release the tag
 	 */
-	if (reinsert)
-		blk_requeue_request(q, rq);
-	else {
-		int where = ELEVATOR_INSERT_BACK;
+	if (blk_rq_tagged(rq))
+		blk_queue_end_tag(q, rq);
 
-		if (at_head)
-			where = ELEVATOR_INSERT_FRONT;
+	drive_stat_acct(rq, rq->nr_sectors, 1);
+	__elv_add_request(q, rq, where, 0);
 
-		if (blk_rq_tagged(rq))
-			blk_queue_end_tag(q, rq);
-
-		drive_stat_acct(rq, rq->nr_sectors, 1);
-		__elv_add_request(q, rq, where, 0);
-	}
 	if (blk_queue_plugged(q))
 		__generic_unplug_device(q);
 	else
@@ -2259,45 +2277,7 @@ int blkdev_issue_flush(struct block_devi
 
 EXPORT_SYMBOL(blkdev_issue_flush);
 
-/**
- * blkdev_scsi_issue_flush_fn - issue flush for SCSI devices
- * @q:		device queue
- * @disk:	gendisk
- * @error_sector:	error offset
- *
- * Description:
- *    Devices understanding the SCSI command set, can use this function as
- *    a helper for issuing a cache flush. Note: driver is required to store
- *    the error offset (in case of error flushing) in ->sector of struct
- *    request.
- */
-int blkdev_scsi_issue_flush_fn(request_queue_t *q, struct gendisk *disk,
-			       sector_t *error_sector)
-{
-	struct request *rq = blk_get_request(q, WRITE, __GFP_WAIT);
-	int ret;
-
-	rq->flags |= REQ_BLOCK_PC | REQ_SOFTBARRIER;
-	rq->sector = 0;
-	memset(rq->cmd, 0, sizeof(rq->cmd));
-	rq->cmd[0] = 0x35;
-	rq->cmd_len = 12;
-	rq->data = NULL;
-	rq->data_len = 0;
-	rq->timeout = 60 * HZ;
-
-	ret = blk_execute_rq(q, disk, rq);
-
-	if (ret && error_sector)
-		*error_sector = rq->sector;
-
-	blk_put_request(rq);
-	return ret;
-}
-
-EXPORT_SYMBOL(blkdev_scsi_issue_flush_fn);
-
-void drive_stat_acct(struct request *rq, int nr_sectors, int new_io)
+static void drive_stat_acct(struct request *rq, int nr_sectors, int new_io)
 {
 	int rw = rq_data_dir(rq);
 
@@ -2379,7 +2359,6 @@ static void __blk_put_request(request_qu
 		return;
 
 	req->rq_status = RQ_INACTIVE;
-	req->q = NULL;
 	req->rl = NULL;
 
 	/*
@@ -2508,6 +2487,8 @@ static int attempt_merge(request_queue_t
 		req->rq_disk->in_flight--;
 	}
 
+	req->ioprio = ioprio_best(req->ioprio, next->ioprio);
+
 	__blk_put_request(q, next);
 	return 1;
 }
@@ -2556,25 +2537,17 @@ void blk_attempt_remerge(request_queue_t
 
 EXPORT_SYMBOL(blk_attempt_remerge);
 
-/*
- * Non-locking blk_attempt_remerge variant.
- */
-void __blk_attempt_remerge(request_queue_t *q, struct request *rq)
-{
-	attempt_back_merge(q, rq);
-}
-
-EXPORT_SYMBOL(__blk_attempt_remerge);
-
 static int __make_request(request_queue_t *q, struct bio *bio)
 {
-	struct request *req, *freereq = NULL;
+	struct request *req;
 	int el_ret, rw, nr_sectors, cur_nr_sectors, barrier, err, sync;
+	unsigned short prio;
 	sector_t sector;
 
 	sector = bio->bi_sector;
 	nr_sectors = bio_sectors(bio);
 	cur_nr_sectors = bio_cur_sectors(bio);
+	prio = bio_prio(bio);
 
 	rw = bio_data_dir(bio);
 	sync = bio_sync(bio);
@@ -2589,19 +2562,14 @@ static int __make_request(request_queue_
 	spin_lock_prefetch(q->queue_lock);
 
 	barrier = bio_barrier(bio);
-	if (barrier && (q->ordered == QUEUE_ORDERED_NONE)) {
+	if (unlikely(barrier) && (q->ordered == QUEUE_ORDERED_NONE)) {
 		err = -EOPNOTSUPP;
 		goto end_io;
 	}
 
-again:
 	spin_lock_irq(q->queue_lock);
 
-	if (elv_queue_empty(q)) {
-		blk_plug_device(q);
-		goto get_rq;
-	}
-	if (barrier)
+	if (unlikely(barrier) || elv_queue_empty(q))
 		goto get_rq;
 
 	el_ret = elv_merge(q, &req, bio);
@@ -2615,6 +2583,7 @@ again:
 			req->biotail->bi_next = bio;
 			req->biotail = bio;
 			req->nr_sectors = req->hard_nr_sectors += nr_sectors;
+			req->ioprio = ioprio_best(req->ioprio, prio);
 			drive_stat_acct(req, nr_sectors, 0);
 			if (!attempt_back_merge(q, req))
 				elv_merged_request(q, req);
@@ -2639,45 +2608,30 @@ again:
 			req->hard_cur_sectors = cur_nr_sectors;
 			req->sector = req->hard_sector = sector;
 			req->nr_sectors = req->hard_nr_sectors += nr_sectors;
+			req->ioprio = ioprio_best(req->ioprio, prio);
 			drive_stat_acct(req, nr_sectors, 0);
 			if (!attempt_front_merge(q, req))
 				elv_merged_request(q, req);
 			goto out;
 
-		/*
-		 * elevator says don't/can't merge. get new request
-		 */
-		case ELEVATOR_NO_MERGE:
-			break;
-
+		/* ELV_NO_MERGE: elevator says don't/can't merge. */
 		default:
-			printk("elevator returned crap (%d)\n", el_ret);
-			BUG();
+			;
 	}
 
+get_rq:
 	/*
-	 * Grab a free request from the freelist - if that is empty, check
-	 * if we are doing read ahead and abort instead of blocking for
-	 * a free slot.
+	 * Grab a free request. This is might sleep but can not fail.
+	 * Returns with the queue unlocked.
+	 */
+	req = get_request_wait(q, rw, bio);
+
+	/*
+	 * After dropping the lock and possibly sleeping here, our request
+	 * may now be mergeable after it had proven unmergeable (above).
+	 * We don't worry about that case for efficiency. It won't happen
+	 * often, and the elevators are able to handle it.
 	 */
-get_rq:
-	if (freereq) {
-		req = freereq;
-		freereq = NULL;
-	} else {
-		spin_unlock_irq(q->queue_lock);
-		if ((freereq = get_request(q, rw, GFP_ATOMIC)) == NULL) {
-			/*
-			 * READA bit set
-			 */
-			err = -EWOULDBLOCK;
-			if (bio_rw_ahead(bio))
-				goto end_io;
-	
-			freereq = get_request_wait(q, rw);
-		}
-		goto again;
-	}
 
 	req->flags |= REQ_CMD;
 
@@ -2690,7 +2644,7 @@ get_rq:
 	/*
 	 * REQ_BARRIER implies no merging, but lets make it explicit
 	 */
-	if (barrier)
+	if (unlikely(barrier))
 		req->flags |= (REQ_HARDBARRIER | REQ_NOMERGE);
 
 	req->errors = 0;
@@ -2702,13 +2656,15 @@ get_rq:
 	req->buffer = bio_data(bio);	/* see ->buffer comment above */
 	req->waiting = NULL;
 	req->bio = req->biotail = bio;
+	req->ioprio = prio;
 	req->rq_disk = bio->bi_bdev->bd_disk;
 	req->start_time = jiffies;
 
+	spin_lock_irq(q->queue_lock);
+	if (elv_queue_empty(q))
+		blk_plug_device(q);
 	add_request(q, req);
 out:
-	if (freereq)
-		__blk_put_request(q, freereq);
 	if (sync)
 		__generic_unplug_device(q);
 
@@ -2730,7 +2686,7 @@ static inline void blk_partition_remap(s
 	if (bdev != bdev->bd_contains) {
 		struct hd_struct *p = bdev->bd_part;
 
-		switch (bio->bi_rw) {
+		switch (bio_data_dir(bio)) {
 		case READ:
 			p->read_sectors += bio_sectors(bio);
 			p->reads++;
@@ -2749,6 +2705,7 @@ void blk_finish_queue_drain(request_queu
 {
 	struct request_list *rl = &q->rq;
 	struct request *rq;
+	int requeued = 0;
 
 	spin_lock_irq(q->queue_lock);
 	clear_bit(QUEUE_FLAG_DRAIN, &q->queue_flags);
@@ -2757,9 +2714,13 @@ void blk_finish_queue_drain(request_queu
 		rq = list_entry_rq(q->drain_list.next);
 
 		list_del_init(&rq->queuelist);
-		__elv_add_request(q, rq, ELEVATOR_INSERT_BACK, 1);
+		elv_requeue_request(q, rq);
+		requeued++;
 	}
 
+	if (requeued)
+		q->request_fn(q);
+
 	spin_unlock_irq(q->queue_lock);
 
 	wake_up(&rl->wait[0]);
@@ -2814,7 +2775,7 @@ static inline void block_wait_queue_runn
 {
 	DEFINE_WAIT(wait);
 
-	while (test_bit(QUEUE_FLAG_DRAIN, &q->queue_flags)) {
+	while (unlikely(test_bit(QUEUE_FLAG_DRAIN, &q->queue_flags))) {
 		struct request_list *rl = &q->rq;
 
 		prepare_to_wait_exclusive(&rl->drain, &wait,
@@ -2923,7 +2884,7 @@ end_io:
 			goto end_io;
 		}
 
-		if (test_bit(QUEUE_FLAG_DEAD, &q->queue_flags))
+		if (unlikely(test_bit(QUEUE_FLAG_DEAD, &q->queue_flags)))
 			goto end_io;
 
 		block_wait_queue_running(q);
@@ -2956,7 +2917,7 @@ void submit_bio(int rw, struct bio *bio)
 
 	BIO_BUG_ON(!bio->bi_size);
 	BIO_BUG_ON(!bio->bi_io_vec);
-	bio->bi_rw = rw;
+	bio->bi_rw |= rw;
 	if (rw & WRITE)
 		mod_page_state(pgpgout, count);
 	else
@@ -2976,7 +2937,7 @@ void submit_bio(int rw, struct bio *bio)
 
 EXPORT_SYMBOL(submit_bio);
 
-void blk_recalc_rq_segments(struct request *rq)
+static void blk_recalc_rq_segments(struct request *rq)
 {
 	struct bio *bio, *prevbio = NULL;
 	int nr_phys_segs, nr_hw_segs;
@@ -3018,7 +2979,7 @@ void blk_recalc_rq_segments(struct reque
 	rq->nr_hw_segments = nr_hw_segs;
 }
 
-void blk_recalc_rq_sectors(struct request *rq, int nsect)
+static void blk_recalc_rq_sectors(struct request *rq, int nsect)
 {
 	if (blk_fs_request(rq)) {
 		rq->hard_sector += nsect;
@@ -3313,8 +3274,11 @@ void exit_io_context(void)
 	struct io_context *ioc;
 
 	local_irq_save(flags);
+	task_lock(current);
 	ioc = current->io_context;
 	current->io_context = NULL;
+	ioc->task = NULL;
+	task_unlock(current);
 	local_irq_restore(flags);
 
 	if (ioc->aic && ioc->aic->exit)
@@ -3327,53 +3291,49 @@ void exit_io_context(void)
 
 /*
  * If the current task has no IO context then create one and initialise it.
- * If it does have a context, take a ref on it.
+ * Otherwise, return its existing IO context.
  *
- * This is always called in the context of the task which submitted the I/O.
- * But weird things happen, so we disable local interrupts to ensure exclusive
- * access to *current.
+ * This returned IO context doesn't have a specifically elevated refcount,
+ * but since the current task itself holds a reference, the context can be
+ * used in general code, so long as it stays within `current` context.
  */
-struct io_context *get_io_context(int gfp_flags)
+struct io_context *current_io_context(int gfp_flags)
 {
 	struct task_struct *tsk = current;
-	unsigned long flags;
 	struct io_context *ret;
 
-	local_irq_save(flags);
 	ret = tsk->io_context;
-	if (ret)
-		goto out;
-
-	local_irq_restore(flags);
+	if (likely(ret))
+		return ret;
 
 	ret = kmem_cache_alloc(iocontext_cachep, gfp_flags);
 	if (ret) {
 		atomic_set(&ret->refcount, 1);
-		ret->pid = tsk->pid;
+		ret->task = current;
+		ret->set_ioprio = NULL;
 		ret->last_waited = jiffies; /* doesn't matter... */
 		ret->nr_batch_requests = 0; /* because this is 0 */
 		ret->aic = NULL;
 		ret->cic = NULL;
-		spin_lock_init(&ret->lock);
-
-		local_irq_save(flags);
+		tsk->io_context = ret;
+	}
 
-		/*
-		 * very unlikely, someone raced with us in setting up the task
-		 * io context. free new context and just grab a reference.
-		 */
-		if (!tsk->io_context)
-			tsk->io_context = ret;
-		else {
-			kmem_cache_free(iocontext_cachep, ret);
-			ret = tsk->io_context;
-		}
+	return ret;
+}
+EXPORT_SYMBOL(current_io_context);
 
-out:
+/*
+ * If the current task has no IO context then create one and initialise it.
+ * If it does have a context, take a ref on it.
+ *
+ * This is always called in the context of the task which submitted the I/O.
+ */
+struct io_context *get_io_context(int gfp_flags)
+{
+	struct io_context *ret;
+	ret = current_io_context(gfp_flags);
+	if (likely(ret))
 		atomic_inc(&ret->refcount);
-		local_irq_restore(flags);
-	}
-
 	return ret;
 }
 EXPORT_SYMBOL(get_io_context);
@@ -3582,7 +3542,7 @@ queue_attr_show(struct kobject *kobj, st
 
 	q = container_of(kobj, struct request_queue, kobj);
 	if (!entry->show)
-		return 0;
+		return -EIO;
 
 	return entry->show(q, page);
 }
@@ -3596,7 +3556,7 @@ queue_attr_store(struct kobject *kobj, s
 
 	q = container_of(kobj, struct request_queue, kobj);
 	if (!entry->store)
-		return -EINVAL;
+		return -EIO;
 
 	return entry->store(q, page, length);
 }
@@ -3606,7 +3566,7 @@ static struct sysfs_ops queue_sysfs_ops 
 	.store	= queue_attr_store,
 };
 
-struct kobj_type queue_ktype = {
+static struct kobj_type queue_ktype = {
 	.sysfs_ops	= &queue_sysfs_ops,
 	.default_attrs	= default_attrs,
 };
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -472,17 +472,11 @@ static int do_bio_filebacked(struct loop
  */
 static void loop_add_bio(struct loop_device *lo, struct bio *bio)
 {
-	unsigned long flags;
-
-	spin_lock_irqsave(&lo->lo_lock, flags);
 	if (lo->lo_biotail) {
 		lo->lo_biotail->bi_next = bio;
 		lo->lo_biotail = bio;
 	} else
 		lo->lo_bio = lo->lo_biotail = bio;
-	spin_unlock_irqrestore(&lo->lo_lock, flags);
-
-	up(&lo->lo_bh_mutex);
 }
 
 /*
@@ -492,14 +486,12 @@ static struct bio *loop_get_bio(struct l
 {
 	struct bio *bio;
 
-	spin_lock_irq(&lo->lo_lock);
 	if ((bio = lo->lo_bio)) {
 		if (bio == lo->lo_biotail)
 			lo->lo_biotail = NULL;
 		lo->lo_bio = bio->bi_next;
 		bio->bi_next = NULL;
 	}
-	spin_unlock_irq(&lo->lo_lock);
 
 	return bio;
 }
@@ -509,35 +501,28 @@ static int loop_make_request(request_que
 	struct loop_device *lo = q->queuedata;
 	int rw = bio_rw(old_bio);
 
-	if (!lo)
-		goto out;
+	if (rw == READA)
+		rw = READ;
+
+	BUG_ON(!lo || (rw != READ && rw != WRITE));
 
 	spin_lock_irq(&lo->lo_lock);
 	if (lo->lo_state != Lo_bound)
-		goto inactive;
-	atomic_inc(&lo->lo_pending);
-	spin_unlock_irq(&lo->lo_lock);
-
-	if (rw == WRITE) {
-		if (lo->lo_flags & LO_FLAGS_READ_ONLY)
-			goto err;
-	} else if (rw == READA) {
-		rw = READ;
-	} else if (rw != READ) {
-		printk(KERN_ERR "loop: unknown command (%x)\n", rw);
-		goto err;
-	}
+		goto out;
+	if (unlikely(rw == WRITE && (lo->lo_flags & LO_FLAGS_READ_ONLY)))
+		goto out;
+	lo->lo_pending++;
 	loop_add_bio(lo, old_bio);
+	spin_unlock_irq(&lo->lo_lock);
+	up(&lo->lo_bh_mutex);
 	return 0;
-err:
-	if (atomic_dec_and_test(&lo->lo_pending))
-		up(&lo->lo_bh_mutex);
+
 out:
+	if (lo->lo_pending == 0)
+		up(&lo->lo_bh_mutex);
+	spin_unlock_irq(&lo->lo_lock);
 	bio_io_error(old_bio, old_bio->bi_size);
 	return 0;
-inactive:
-	spin_unlock_irq(&lo->lo_lock);
-	goto out;
 }
 
 /*
@@ -560,13 +545,11 @@ static void do_loop_switch(struct loop_d
 
 static inline void loop_handle_bio(struct loop_device *lo, struct bio *bio)
 {
-	int ret;
-
 	if (unlikely(!bio->bi_bdev)) {
 		do_loop_switch(lo, bio->bi_private);
 		bio_put(bio);
 	} else {
-		ret = do_bio_filebacked(lo, bio);
+		int ret = do_bio_filebacked(lo, bio);
 		bio_endio(bio, bio->bi_size, ret);
 	}
 }
@@ -594,7 +577,7 @@ static int loop_thread(void *data)
 	set_user_nice(current, -20);
 
 	lo->lo_state = Lo_bound;
-	atomic_inc(&lo->lo_pending);
+	lo->lo_pending = 1;
 
 	/*
 	 * up sem, we are running
@@ -602,26 +585,37 @@ static int loop_thread(void *data)
 	up(&lo->lo_sem);
 
 	for (;;) {
-		down_interruptible(&lo->lo_bh_mutex);
+		int pending;
+
+		/*
+		 * interruptible just to not contribute to load avg
+		 */
+		if (down_interruptible(&lo->lo_bh_mutex))
+			continue;
+
+		spin_lock_irq(&lo->lo_lock);
+
 		/*
-		 * could be upped because of tear-down, not because of
-		 * pending work
+		 * could be upped because of tear-down, not pending work
 		 */
-		if (!atomic_read(&lo->lo_pending))
+		if (unlikely(!lo->lo_pending)) {
+			spin_unlock_irq(&lo->lo_lock);
 			break;
+		}
 
 		bio = loop_get_bio(lo);
-		if (!bio) {
-			printk("loop: missing bio\n");
-			continue;
-		}
+		lo->lo_pending--;
+		pending = lo->lo_pending;
+		spin_unlock_irq(&lo->lo_lock);
+
+		BUG_ON(!bio);
 		loop_handle_bio(lo, bio);
 
 		/*
 		 * upped both for pending work and tear-down, lo_pending
 		 * will hit zero then
 		 */
-		if (atomic_dec_and_test(&lo->lo_pending))
+		if (unlikely(!pending))
 			break;
 	}
 
@@ -900,7 +894,8 @@ static int loop_clr_fd(struct loop_devic
 
 	spin_lock_irq(&lo->lo_lock);
 	lo->lo_state = Lo_rundown;
-	if (atomic_dec_and_test(&lo->lo_pending))
+	lo->lo_pending--;
+	if (!lo->lo_pending)
 		up(&lo->lo_bh_mutex);
 	spin_unlock_irq(&lo->lo_lock);
 
diff --git a/drivers/block/paride/pd.c b/drivers/block/paride/pd.c
--- a/drivers/block/paride/pd.c
+++ b/drivers/block/paride/pd.c
@@ -723,7 +723,7 @@ static int pd_special_command(struct pd_
 	rq.ref_count = 1;
 	rq.waiting = &wait;
 	rq.end_io = blk_end_sync_rq;
-	blk_insert_request(disk->gd->queue, &rq, 0, func, 0);
+	blk_insert_request(disk->gd->queue, &rq, 0, func);
 	wait_for_completion(&wait);
 	rq.waiting = NULL;
 	if (rq.errors)
diff --git a/drivers/block/paride/pg.c b/drivers/block/paride/pg.c
--- a/drivers/block/paride/pg.c
+++ b/drivers/block/paride/pg.c
@@ -222,7 +222,7 @@ static int pg_identify(struct pg *dev, i
 
 static char pg_scratch[512];	/* scratch block buffer */
 
-static struct class_simple *pg_class;
+static struct class *pg_class;
 
 /* kernel glue structures */
 
@@ -666,7 +666,7 @@ static int __init pg_init(void)
 		err = -1;
 		goto out;
 	}
-	pg_class = class_simple_create(THIS_MODULE, "pg");
+	pg_class = class_create(THIS_MODULE, "pg");
 	if (IS_ERR(pg_class)) {
 		err = PTR_ERR(pg_class);
 		goto out_chrdev;
@@ -675,7 +675,7 @@ static int __init pg_init(void)
 	for (unit = 0; unit < PG_UNITS; unit++) {
 		struct pg *dev = &devices[unit];
 		if (dev->present) {
-			class_simple_device_add(pg_class, MKDEV(major, unit), 
+			class_device_create(pg_class, MKDEV(major, unit),
 					NULL, "pg%u", unit);
 			err = devfs_mk_cdev(MKDEV(major, unit),
 				      S_IFCHR | S_IRUSR | S_IWUSR, "pg/%u",
@@ -688,8 +688,8 @@ static int __init pg_init(void)
 	goto out;
 
 out_class:
-	class_simple_device_remove(MKDEV(major, unit));
-	class_simple_destroy(pg_class);
+	class_device_destroy(pg_class, MKDEV(major, unit));
+	class_destroy(pg_class);
 out_chrdev:
 	unregister_chrdev(major, "pg");
 out:
@@ -703,11 +703,11 @@ static void __exit pg_exit(void)
 	for (unit = 0; unit < PG_UNITS; unit++) {
 		struct pg *dev = &devices[unit];
 		if (dev->present) {
-			class_simple_device_remove(MKDEV(major, unit));
+			class_device_destroy(pg_class, MKDEV(major, unit));
 			devfs_remove("pg/%u", unit);
 		}
 	}
-	class_simple_destroy(pg_class);
+	class_destroy(pg_class);
 	devfs_remove("pg");
 	unregister_chrdev(major, name);
 
diff --git a/drivers/block/paride/pt.c b/drivers/block/paride/pt.c
--- a/drivers/block/paride/pt.c
+++ b/drivers/block/paride/pt.c
@@ -242,7 +242,7 @@ static struct file_operations pt_fops = 
 };
 
 /* sysfs class support */
-static struct class_simple *pt_class;
+static struct class *pt_class;
 
 static inline int status_reg(struct pi_adapter *pi)
 {
@@ -963,7 +963,7 @@ static int __init pt_init(void)
 		err = -1;
 		goto out;
 	}
-	pt_class = class_simple_create(THIS_MODULE, "pt");
+	pt_class = class_create(THIS_MODULE, "pt");
 	if (IS_ERR(pt_class)) {
 		err = PTR_ERR(pt_class);
 		goto out_chrdev;
@@ -972,29 +972,29 @@ static int __init pt_init(void)
 	devfs_mk_dir("pt");
 	for (unit = 0; unit < PT_UNITS; unit++)
 		if (pt[unit].present) {
-			class_simple_device_add(pt_class, MKDEV(major, unit), 
+			class_device_create(pt_class, MKDEV(major, unit),
 					NULL, "pt%d", unit);
 			err = devfs_mk_cdev(MKDEV(major, unit),
 				      S_IFCHR | S_IRUSR | S_IWUSR,
 				      "pt/%d", unit);
 			if (err) {
-				class_simple_device_remove(MKDEV(major, unit));
+				class_device_destroy(pt_class, MKDEV(major, unit));
 				goto out_class;
 			}
-			class_simple_device_add(pt_class, MKDEV(major, unit + 128),
+			class_device_create(pt_class, MKDEV(major, unit + 128),
 					NULL, "pt%dn", unit);
 			err = devfs_mk_cdev(MKDEV(major, unit + 128),
 				      S_IFCHR | S_IRUSR | S_IWUSR,
 				      "pt/%dn", unit);
 			if (err) {
-				class_simple_device_remove(MKDEV(major, unit + 128));
+				class_device_destroy(pt_class, MKDEV(major, unit + 128));
 				goto out_class;
 			}
 		}
 	goto out;
 
 out_class:
-	class_simple_destroy(pt_class);
+	class_destroy(pt_class);
 out_chrdev:
 	unregister_chrdev(major, "pt");
 out:
@@ -1006,12 +1006,12 @@ static void __exit pt_exit(void)
 	int unit;
 	for (unit = 0; unit < PT_UNITS; unit++)
 		if (pt[unit].present) {
-			class_simple_device_remove(MKDEV(major, unit));
+			class_device_destroy(pt_class, MKDEV(major, unit));
 			devfs_remove("pt/%d", unit);
-			class_simple_device_remove(MKDEV(major, unit + 128));
+			class_device_destroy(pt_class, MKDEV(major, unit + 128));
 			devfs_remove("pt/%dn", unit);
 		}
-	class_simple_destroy(pt_class);
+	class_destroy(pt_class);
 	devfs_remove("pt");
 	unregister_chrdev(major, name);
 	for (unit = 0; unit < PT_UNITS; unit++)
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -467,14 +467,12 @@ static int pkt_set_speed(struct pktcdvd_
  * Queue a bio for processing by the low-level CD device. Must be called
  * from process context.
  */
-static void pkt_queue_bio(struct pktcdvd_device *pd, struct bio *bio, int high_prio_read)
+static void pkt_queue_bio(struct pktcdvd_device *pd, struct bio *bio)
 {
 	spin_lock(&pd->iosched.lock);
 	if (bio_data_dir(bio) == READ) {
 		pkt_add_list_last(bio, &pd->iosched.read_queue,
 				  &pd->iosched.read_queue_tail);
-		if (high_prio_read)
-			pd->iosched.high_prio_read = 1;
 	} else {
 		pkt_add_list_last(bio, &pd->iosched.write_queue,
 				  &pd->iosched.write_queue_tail);
@@ -490,15 +488,16 @@ static void pkt_queue_bio(struct pktcdvd
  * requirements for CDRW drives:
  * - A cache flush command must be inserted before a read request if the
  *   previous request was a write.
- * - Switching between reading and writing is slow, so don't it more often
+ * - Switching between reading and writing is slow, so don't do it more often
  *   than necessary.
+ * - Optimize for throughput at the expense of latency. This means that streaming
+ *   writes will never be interrupted by a read, but if the drive has to seek
+ *   before the next write, switch to reading instead if there are any pending
+ *   read requests.
  * - Set the read speed according to current usage pattern. When only reading
  *   from the device, it's best to use the highest possible read speed, but
  *   when switching often between reading and writing, it's better to have the
  *   same read and write speeds.
- * - Reads originating from user space should have higher priority than reads
- *   originating from pkt_gather_data, because some process is usually waiting
- *   on reads of the first kind.
  */
 static void pkt_iosched_process_queue(struct pktcdvd_device *pd)
 {
@@ -512,21 +511,24 @@ static void pkt_iosched_process_queue(st
 
 	for (;;) {
 		struct bio *bio;
-		int reads_queued, writes_queued, high_prio_read;
+		int reads_queued, writes_queued;
 
 		spin_lock(&pd->iosched.lock);
 		reads_queued = (pd->iosched.read_queue != NULL);
 		writes_queued = (pd->iosched.write_queue != NULL);
-		if (!reads_queued)
-			pd->iosched.high_prio_read = 0;
-		high_prio_read = pd->iosched.high_prio_read;
 		spin_unlock(&pd->iosched.lock);
 
 		if (!reads_queued && !writes_queued)
 			break;
 
 		if (pd->iosched.writing) {
-			if (high_prio_read || (!writes_queued && reads_queued)) {
+			int need_write_seek = 1;
+			spin_lock(&pd->iosched.lock);
+			bio = pd->iosched.write_queue;
+			spin_unlock(&pd->iosched.lock);
+			if (bio && (bio->bi_sector == pd->iosched.last_write))
+				need_write_seek = 0;
+			if (need_write_seek && reads_queued) {
 				if (atomic_read(&pd->cdrw.pending_bios) > 0) {
 					VPRINTK("pktcdvd: write, waiting\n");
 					break;
@@ -559,8 +561,10 @@ static void pkt_iosched_process_queue(st
 
 		if (bio_data_dir(bio) == READ)
 			pd->iosched.successive_reads += bio->bi_size >> 10;
-		else
+		else {
 			pd->iosched.successive_reads = 0;
+			pd->iosched.last_write = bio->bi_sector + bio_sectors(bio);
+		}
 		if (pd->iosched.successive_reads >= HI_SPEED_SWITCH) {
 			if (pd->read_speed == pd->write_speed) {
 				pd->read_speed = MAX_SPEED;
@@ -765,7 +769,7 @@ static void pkt_gather_data(struct pktcd
 
 		atomic_inc(&pkt->io_wait);
 		bio->bi_rw = READ;
-		pkt_queue_bio(pd, bio, 0);
+		pkt_queue_bio(pd, bio);
 		frames_read++;
 	}
 
@@ -1062,7 +1066,7 @@ static void pkt_start_write(struct pktcd
 
 	atomic_set(&pkt->io_wait, 1);
 	pkt->w_bio->bi_rw = WRITE;
-	pkt_queue_bio(pd, pkt->w_bio, 0);
+	pkt_queue_bio(pd, pkt->w_bio);
 }
 
 static void pkt_finish_packet(struct packet_data *pkt, int uptodate)
@@ -1247,8 +1251,7 @@ static int kcdrwd(void *foobar)
 			VPRINTK("kcdrwd: wake up\n");
 
 			/* make swsusp happy with our thread */
-			if (current->flags & PF_FREEZE)
-				refrigerator(PF_FREEZE);
+			try_to_freeze();
 
 			list_for_each_entry(pkt, &pd->cdrw.pkt_active_list, list) {
 				if (!pkt->sleep_time)
@@ -2120,7 +2123,7 @@ static int pkt_make_request(request_queu
 		cloned_bio->bi_private = psd;
 		cloned_bio->bi_end_io = pkt_end_io_read_cloned;
 		pd->stats.secs_r += bio->bi_size >> 9;
-		pkt_queue_bio(pd, cloned_bio, 1);
+		pkt_queue_bio(pd, cloned_bio);
 		return 0;
 	}
 
diff --git a/drivers/block/swim3.c b/drivers/block/swim3.c
--- a/drivers/block/swim3.c
+++ b/drivers/block/swim3.c
@@ -253,7 +253,7 @@ static int floppy_revalidate(struct gend
 static int swim3_add_device(struct device_node *swims);
 int swim3_init(void);
 
-#ifndef CONFIG_PMAC_PBOOK
+#ifndef CONFIG_PMAC_MEDIABAY
 #define check_media_bay(which, what)	1
 #endif
 
@@ -297,9 +297,11 @@ static void do_fd_request(request_queue_
 	int i;
 	for(i=0;i<floppy_count;i++)
 	{
+#ifdef CONFIG_PMAC_MEDIABAY
 		if (floppy_states[i].media_bay &&
 			check_media_bay(floppy_states[i].media_bay, MB_FD))
 			continue;
+#endif /* CONFIG_PMAC_MEDIABAY */
 		start_request(&floppy_states[i]);
 	}
 	sti();
@@ -856,8 +858,10 @@ static int floppy_ioctl(struct inode *in
 	if ((cmd & 0x80) && !capable(CAP_SYS_ADMIN))
 		return -EPERM;
 
+#ifdef CONFIG_PMAC_MEDIABAY
 	if (fs->media_bay && check_media_bay(fs->media_bay, MB_FD))
 		return -ENXIO;
+#endif
 
 	switch (cmd) {
 	case FDEJECT:
@@ -881,8 +885,10 @@ static int floppy_open(struct inode *ino
 	int n, err = 0;
 
 	if (fs->ref_count == 0) {
+#ifdef CONFIG_PMAC_MEDIABAY
 		if (fs->media_bay && check_media_bay(fs->media_bay, MB_FD))
 			return -ENXIO;
+#endif
 		out_8(&sw->setup, S_IBM_DRIVE | S_FCLK_DIV2);
 		out_8(&sw->control_bic, 0xff);
 		out_8(&sw->mode, 0x95);
@@ -967,8 +973,10 @@ static int floppy_revalidate(struct gend
 	struct swim3 __iomem *sw;
 	int ret, n;
 
+#ifdef CONFIG_PMAC_MEDIABAY
 	if (fs->media_bay && check_media_bay(fs->media_bay, MB_FD))
 		return -ENXIO;
+#endif
 
 	sw = fs->swim3;
 	grab_drive(fs, revalidating, 0);
diff --git a/drivers/block/sx8.c b/drivers/block/sx8.c
--- a/drivers/block/sx8.c
+++ b/drivers/block/sx8.c
@@ -26,6 +26,7 @@
 #include <linux/delay.h>
 #include <linux/time.h>
 #include <linux/hdreg.h>
+#include <linux/dma-mapping.h>
 #include <asm/io.h>
 #include <asm/semaphore.h>
 #include <asm/uaccess.h>
@@ -614,7 +615,7 @@ static int carm_array_info (struct carm_
 	spin_unlock_irq(&host->lock);
 
 	DPRINTK("blk_insert_request, tag == %u\n", idx);
-	blk_insert_request(host->oob_q, crq->rq, 1, crq, 0);
+	blk_insert_request(host->oob_q, crq->rq, 1, crq);
 
 	return 0;
 
@@ -653,7 +654,7 @@ static int carm_send_special (struct car
 	crq->msg_bucket = (u32) rc;
 
 	DPRINTK("blk_insert_request, tag == %u\n", idx);
-	blk_insert_request(host->oob_q, crq->rq, 1, crq, 0);
+	blk_insert_request(host->oob_q, crq->rq, 1, crq);
 
 	return 0;
 }
@@ -1581,10 +1582,10 @@ static int carm_init_one (struct pci_dev
 	if (rc)
 		goto err_out;
 
-#if IF_64BIT_DMA_IS_POSSIBLE /* grrrr... */
-	rc = pci_set_dma_mask(pdev, 0xffffffffffffffffULL);
+#ifdef IF_64BIT_DMA_IS_POSSIBLE /* grrrr... */
+	rc = pci_set_dma_mask(pdev, DMA_64BIT_MASK);
 	if (!rc) {
-		rc = pci_set_consistent_dma_mask(pdev, 0xffffffffffffffffULL);
+		rc = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
 		if (rc) {
 			printk(KERN_ERR DRV_NAME "(%s): consistent DMA mask failure\n",
 				pci_name(pdev));
@@ -1593,14 +1594,14 @@ static int carm_init_one (struct pci_dev
 		pci_dac = 1;
 	} else {
 #endif
-		rc = pci_set_dma_mask(pdev, 0xffffffffULL);
+		rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
 		if (rc) {
 			printk(KERN_ERR DRV_NAME "(%s): DMA mask failure\n",
 				pci_name(pdev));
 			goto err_out_regions;
 		}
 		pci_dac = 0;
-#if IF_64BIT_DMA_IS_POSSIBLE /* grrrr... */
+#ifdef IF_64BIT_DMA_IS_POSSIBLE /* grrrr... */
 	}
 #endif
 
diff --git a/drivers/block/ub.c b/drivers/block/ub.c
--- a/drivers/block/ub.c
+++ b/drivers/block/ub.c
@@ -23,6 +23,7 @@
  *  -- Exterminate P3 printks
  *  -- Resove XXX's
  *  -- Redo "benh's retries", perhaps have spin-up code to handle them. V:D=?
+ *  -- CLEAR, CLR2STS, CLRRS seem to be ripe for refactoring.
  */
 #include <linux/kernel.h>
 #include <linux/module.h>
@@ -38,6 +39,73 @@
 #define UB_MAJOR 180
 
 /*
+ * The command state machine is the key model for understanding of this driver.
+ *
+ * The general rule is that all transitions are done towards the bottom
+ * of the diagram, thus preventing any loops.
+ *
+ * An exception to that is how the STAT state is handled. A counter allows it
+ * to be re-entered along the path marked with [C].
+ *
+ *       +--------+
+ *       ! INIT   !
+ *       +--------+
+ *           !
+ *        ub_scsi_cmd_start fails ->--------------------------------------\
+ *           !                                                            !
+ *           V                                                            !
+ *       +--------+                                                       !
+ *       ! CMD    !                                                       !
+ *       +--------+                                                       !
+ *           !                                            +--------+      !
+ *         was -EPIPE -->-------------------------------->! CLEAR  !      !
+ *           !                                            +--------+      !
+ *           !                                                !           !
+ *         was error -->------------------------------------- ! --------->\
+ *           !                                                !           !
+ *  /--<-- cmd->dir == NONE ?                                 !           !
+ *  !        !                                                !           !
+ *  !        V                                                !           !
+ *  !    +--------+                                           !           !
+ *  !    ! DATA   !                                           !           !
+ *  !    +--------+                                           !           !
+ *  !        !                           +---------+          !           !
+ *  !      was -EPIPE -->--------------->! CLR2STS !          !           !
+ *  !        !                           +---------+          !           !
+ *  !        !                                !               !           !
+ *  !        !                              was error -->---- ! --------->\
+ *  !      was error -->--------------------- ! ------------- ! --------->\
+ *  !        !                                !               !           !
+ *  !        V                                !               !           !
+ *  \--->+--------+                           !               !           !
+ *       ! STAT   !<--------------------------/               !           !
+ *  /--->+--------+                                           !           !
+ *  !        !                                                !           !
+ * [C]     was -EPIPE -->-----------\                         !           !
+ *  !        !                      !                         !           !
+ *  +<---- len == 0                 !                         !           !
+ *  !        !                      !                         !           !
+ *  !      was error -->--------------------------------------!---------->\
+ *  !        !                      !                         !           !
+ *  +<---- bad CSW                  !                         !           !
+ *  +<---- bad tag                  !                         !           !
+ *  !        !                      V                         !           !
+ *  !        !                 +--------+                     !           !
+ *  !        !                 ! CLRRS  !                     !           !
+ *  !        !                 +--------+                     !           !
+ *  !        !                      !                         !           !
+ *  \------- ! --------------------[C]--------\               !           !
+ *           !                                !               !           !
+ *         cmd->error---\                +--------+           !           !
+ *           !          +--------------->! SENSE  !<----------/           !
+ *         STAT_FAIL----/                +--------+                       !
+ *           !                                !                           V
+ *           !                                V                      +--------+
+ *           \--------------------------------\--------------------->! DONE   !
+ *                                                                   +--------+
+ */
+
+/*
  * Definitions which have to be scattered once we understand the layout better.
  */
 
@@ -91,8 +159,6 @@ struct bulk_cs_wrap {
 
 #define US_BULK_CS_WRAP_LEN	13
 #define US_BULK_CS_SIGN		0x53425355	/* spells out 'USBS' */
-/* This is for Olympus Camedia digital cameras */
-#define US_BULK_CS_OLYMPUS_SIGN	0x55425355	/* spells out 'USBU' */
 #define US_BULK_STAT_OK		0
 #define US_BULK_STAT_FAIL	1
 #define US_BULK_STAT_PHASE	2
@@ -135,6 +201,7 @@ enum ub_scsi_cmd_state {
 	UB_CMDST_CLR2STS,		/* Clearing before requesting status */
 	UB_CMDST_STAT,			/* Status phase */
 	UB_CMDST_CLEAR,			/* Clearing a stall (halt, actually) */
+	UB_CMDST_CLRRS,			/* Clearing before retrying status */
 	UB_CMDST_SENSE,			/* Sending Request Sense */
 	UB_CMDST_DONE			/* Final state */
 };
@@ -146,6 +213,7 @@ static char *ub_scsi_cmd_stname[] = {
 	"c2s",
 	"sts",
 	"clr",
+	"crs",
 	"Sen",
 	"fin"
 };
@@ -316,6 +384,7 @@ struct ub_dev {
 	struct urb work_urb;
 	struct timer_list work_timer;
 	int last_pipe;			/* What might need clearing */
+	__le32 signature;		/* Learned signature */
 	struct bulk_cb_wrap work_bcb;
 	struct bulk_cs_wrap work_bcs;
 	struct usb_ctrlrequest work_cr;
@@ -339,8 +408,9 @@ static void ub_scsi_action(unsigned long
 static void ub_scsi_dispatch(struct ub_dev *sc);
 static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd);
 static void ub_state_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd, int rc);
-static void __ub_state_stat(struct ub_dev *sc, struct ub_scsi_cmd *cmd);
+static int __ub_state_stat(struct ub_dev *sc, struct ub_scsi_cmd *cmd);
 static void ub_state_stat(struct ub_dev *sc, struct ub_scsi_cmd *cmd);
+static void ub_state_stat_counted(struct ub_dev *sc, struct ub_scsi_cmd *cmd);
 static void ub_state_sense(struct ub_dev *sc, struct ub_scsi_cmd *cmd);
 static int ub_submit_clear_stall(struct ub_dev *sc, struct ub_scsi_cmd *cmd,
     int stalled_pipe);
@@ -430,7 +500,7 @@ static void ub_cmdtr_sense(struct ub_dev
 	}
 }
 
-static ssize_t ub_diag_show(struct device *dev, char *page)
+static ssize_t ub_diag_show(struct device *dev, struct device_attribute *attr, char *page)
 {
 	struct usb_interface *intf;
 	struct ub_dev *sc;
@@ -1085,6 +1155,28 @@ static void ub_scsi_urb_compl(struct ub_
 
 		ub_state_stat(sc, cmd);
 
+	} else if (cmd->state == UB_CMDST_CLRRS) {
+		if (urb->status == -EPIPE) {
+			/*
+			 * STALL while clearning STALL.
+			 * The control pipe clears itself - nothing to do.
+			 * XXX Might try to reset the device here and retry.
+			 */
+			printk(KERN_NOTICE "%s: stall on control pipe\n",
+			    sc->name);
+			goto Bad_End;
+		}
+
+		/*
+		 * We ignore the result for the halt clear.
+		 */
+
+		/* reset the endpoint toggle */
+		usb_settoggle(sc->dev, usb_pipeendpoint(sc->last_pipe),
+			usb_pipeout(sc->last_pipe), 0);
+
+		ub_state_stat_counted(sc, cmd);
+
 	} else if (cmd->state == UB_CMDST_CMD) {
 		if (urb->status == -EPIPE) {
 			rc = ub_submit_clear_stall(sc, cmd, sc->last_pipe);
@@ -1190,52 +1282,57 @@ static void ub_scsi_urb_compl(struct ub_
 				 */
 				goto Bad_End;
 			}
-			cmd->state = UB_CMDST_CLEAR;
+
+			/*
+			 * Having a stall when getting CSW is an error, so
+			 * make sure uppper levels are not oblivious to it.
+			 */
+			cmd->error = -EIO;		/* A cheap trick... */
+
+			cmd->state = UB_CMDST_CLRRS;
 			ub_cmdtr_state(sc, cmd);
 			return;
 		}
+		if (urb->status == -EOVERFLOW) {
+			/*
+			 * XXX We are screwed here. Retrying is pointless,
+			 * because the pipelined data will not get in until
+			 * we read with a big enough buffer. We must reset XXX.
+			 */
+			goto Bad_End;
+		}
 		if (urb->status != 0)
 			goto Bad_End;
 
 		if (urb->actual_length == 0) {
-			/*
-			 * Some broken devices add unnecessary zero-length
-			 * packets to the end of their data transfers.
-			 * Such packets show up as 0-length CSWs. If we
-			 * encounter such a thing, try to read the CSW again.
-			 */
-			if (++cmd->stat_count >= 4) {
-				printk(KERN_NOTICE "%s: unable to get CSW\n",
-				    sc->name);
-				goto Bad_End;
-			}
-			__ub_state_stat(sc, cmd);
+			ub_state_stat_counted(sc, cmd);
 			return;
 		}
 
 		/*
 		 * Check the returned Bulk protocol status.
+		 * The status block has to be validated first.
 		 */
 
 		bcs = &sc->work_bcs;
-		rc = le32_to_cpu(bcs->Residue);
-		if (rc != cmd->len - cmd->act_len) {
+
+		if (sc->signature == cpu_to_le32(0)) {
 			/*
-			 * It is all right to transfer less, the caller has
-			 * to check. But it's not all right if the device
-			 * counts disagree with our counts.
+			 * This is the first reply, so do not perform the check.
+			 * Instead, remember the signature the device uses
+			 * for future checks. But do not allow a nul.
 			 */
-			/* P3 */ printk("%s: resid %d len %d act %d\n",
-			    sc->name, rc, cmd->len, cmd->act_len);
-			goto Bad_End;
-		}
-
-#if 0
-		if (bcs->Signature != cpu_to_le32(US_BULK_CS_SIGN) &&
-		    bcs->Signature != cpu_to_le32(US_BULK_CS_OLYMPUS_SIGN)) {
-			/* Windows ignores signatures, so do we. */
+			sc->signature = bcs->Signature;
+			if (sc->signature == cpu_to_le32(0)) {
+				ub_state_stat_counted(sc, cmd);
+				return;
+			}
+		} else {
+			if (bcs->Signature != sc->signature) {
+				ub_state_stat_counted(sc, cmd);
+				return;
+			}
 		}
-#endif
 
 		if (bcs->Tag != cmd->tag) {
 			/*
@@ -1245,16 +1342,22 @@ static void ub_scsi_urb_compl(struct ub_
 			 * commands and reply at commands we timed out before.
 			 * Without flushing these replies we loop forever.
 			 */
-			if (++cmd->stat_count >= 4) {
-				printk(KERN_NOTICE "%s: "
-				    "tag mismatch orig 0x%x reply 0x%x\n",
-				    sc->name, cmd->tag, bcs->Tag);
-				goto Bad_End;
-			}
-			__ub_state_stat(sc, cmd);
+			ub_state_stat_counted(sc, cmd);
 			return;
 		}
 
+		rc = le32_to_cpu(bcs->Residue);
+		if (rc != cmd->len - cmd->act_len) {
+			/*
+			 * It is all right to transfer less, the caller has
+			 * to check. But it's not all right if the device
+			 * counts disagree with our counts.
+			 */
+			/* P3 */ printk("%s: resid %d len %d act %d\n",
+			    sc->name, rc, cmd->len, cmd->act_len);
+			goto Bad_End;
+		}
+
 		switch (bcs->Status) {
 		case US_BULK_STAT_OK:
 			break;
@@ -1272,6 +1375,10 @@ static void ub_scsi_urb_compl(struct ub_
 		}
 
 		/* Not zeroing error to preserve a babble indicator */
+		if (cmd->error != 0) {
+			ub_state_sense(sc, cmd);
+			return;
+		}
 		cmd->state = UB_CMDST_DONE;
 		ub_cmdtr_state(sc, cmd);
 		ub_cmdq_pop(sc);
@@ -1310,7 +1417,7 @@ static void ub_state_done(struct ub_dev 
  * Factorization helper for the command state machine:
  * Submit a CSW read.
  */
-static void __ub_state_stat(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
+static int __ub_state_stat(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
 {
 	int rc;
 
@@ -1328,11 +1435,12 @@ static void __ub_state_stat(struct ub_de
 		/* XXX Clear stalls */
 		ub_complete(&sc->work_done);
 		ub_state_done(sc, cmd, rc);
-		return;
+		return -1;
 	}
 
 	sc->work_timer.expires = jiffies + UB_STAT_TIMEOUT;
 	add_timer(&sc->work_timer);
+	return 0;
 }
 
 /*
@@ -1341,7 +1449,9 @@ static void __ub_state_stat(struct ub_de
  */
 static void ub_state_stat(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
 {
-	__ub_state_stat(sc, cmd);
+
+	if (__ub_state_stat(sc, cmd) != 0)
+		return;
 
 	cmd->stat_count = 0;
 	cmd->state = UB_CMDST_STAT;
@@ -1350,6 +1460,25 @@ static void ub_state_stat(struct ub_dev 
 
 /*
  * Factorization helper for the command state machine:
+ * Submit a CSW read and go to STAT state with counter (along [C] path).
+ */
+static void ub_state_stat_counted(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
+{
+
+	if (++cmd->stat_count >= 4) {
+		ub_state_sense(sc, cmd);
+		return;
+	}
+
+	if (__ub_state_stat(sc, cmd) != 0)
+		return;
+
+	cmd->state = UB_CMDST_STAT;
+	ub_cmdtr_state(sc, cmd);
+}
+
+/*
+ * Factorization helper for the command state machine:
  * Submit a REQUEST SENSE and go to SENSE state.
  */
 static void ub_state_sense(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
diff --git a/drivers/bluetooth/bluecard_cs.c b/drivers/bluetooth/bluecard_cs.c
--- a/drivers/bluetooth/bluecard_cs.c
+++ b/drivers/bluetooth/bluecard_cs.c
@@ -40,7 +40,6 @@
 #include <linux/skbuff.h>
 #include <asm/io.h>
 
-#include <pcmcia/version.h>
 #include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
@@ -895,11 +894,6 @@ static dev_link_t *bluecard_attach(void)
 	link->next = dev_list;
 	dev_list = link;
 	client_reg.dev_info = &dev_info;
-	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 = &bluecard_event;
 	client_reg.Version = 0x0210;
 	client_reg.event_callback_args.client_data = link;
 
@@ -1089,13 +1083,23 @@ static int bluecard_event(event_t event,
 	return 0;
 }
 
+static struct pcmcia_device_id bluecard_ids[] = {
+	PCMCIA_DEVICE_PROD_ID12("BlueCard", "LSE041", 0xbaf16fbf, 0x657cc15e),
+	PCMCIA_DEVICE_PROD_ID12("BTCFCARD", "LSE139", 0xe3987764, 0x2524b59c),
+	PCMCIA_DEVICE_PROD_ID12("WSS", "LSE039", 0x0a0736ec, 0x24e6dfab),
+	PCMCIA_DEVICE_NULL
+};
+MODULE_DEVICE_TABLE(pcmcia, bluecard_ids);
+
 static struct pcmcia_driver bluecard_driver = {
 	.owner		= THIS_MODULE,
 	.drv		= {
 		.name	= "bluecard_cs",
 	},
 	.attach		= bluecard_attach,
+	.event		= bluecard_event,
 	.detach		= bluecard_detach,
+	.id_table	= bluecard_ids,
 };
 
 static int __init init_bluecard_cs(void)
diff --git a/drivers/bluetooth/bpa10x.c b/drivers/bluetooth/bpa10x.c
--- a/drivers/bluetooth/bpa10x.c
+++ b/drivers/bluetooth/bpa10x.c
@@ -367,11 +367,8 @@ static inline void bpa10x_free_urb(struc
 	if (!urb)
 		return;
 
-	if (urb->setup_packet)
-		kfree(urb->setup_packet);
-
-	if (urb->transfer_buffer)
-		kfree(urb->transfer_buffer);
+	kfree(urb->setup_packet);
+	kfree(urb->transfer_buffer);
 
 	usb_free_urb(urb);
 }
diff --git a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c
--- a/drivers/bluetooth/bt3c_cs.c
+++ b/drivers/bluetooth/bt3c_cs.c
@@ -47,7 +47,6 @@
 #include <linux/device.h>
 #include <linux/firmware.h>
 
-#include <pcmcia/version.h>
 #include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
@@ -696,11 +695,6 @@ static dev_link_t *bt3c_attach(void)
 	link->next = dev_list;
 	dev_list = link;
 	client_reg.dev_info = &dev_info;
-	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 = &bt3c_event;
 	client_reg.Version = 0x0210;
 	client_reg.event_callback_args.client_data = link;
 
@@ -935,13 +929,21 @@ static int bt3c_event(event_t event, int
 	return 0;
 }
 
+static struct pcmcia_device_id bt3c_ids[] = {
+	PCMCIA_DEVICE_PROD_ID13("3COM", "Bluetooth PC Card", 0xefce0a31, 0xd4ce9b02),
+	PCMCIA_DEVICE_NULL
+};
+MODULE_DEVICE_TABLE(pcmcia, bt3c_ids);
+
 static struct pcmcia_driver bt3c_driver = {
 	.owner		= THIS_MODULE,
 	.drv		= {
 		.name	= "bt3c_cs",
 	},
 	.attach		= bt3c_attach,
+	.event		= bt3c_event,
 	.detach		= bt3c_detach,
+	.id_table	= bt3c_ids,
 };
 
 static int __init init_bt3c_cs(void)
diff --git a/drivers/bluetooth/btuart_cs.c b/drivers/bluetooth/btuart_cs.c
--- a/drivers/bluetooth/btuart_cs.c
+++ b/drivers/bluetooth/btuart_cs.c
@@ -43,7 +43,6 @@
 #include <asm/system.h>
 #include <asm/io.h>
 
-#include <pcmcia/version.h>
 #include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
@@ -615,11 +614,6 @@ static dev_link_t *btuart_attach(void)
 	link->next = dev_list;
 	dev_list = link;
 	client_reg.dev_info = &dev_info;
-	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 = &btuart_event;
 	client_reg.Version = 0x0210;
 	client_reg.event_callback_args.client_data = link;
 
@@ -855,13 +849,21 @@ static int btuart_event(event_t event, i
 	return 0;
 }
 
+static struct pcmcia_device_id btuart_ids[] = {
+	/* don't use this driver. Use serial_cs + hci_uart instead */
+	PCMCIA_DEVICE_NULL
+};
+MODULE_DEVICE_TABLE(pcmcia, btuart_ids);
+
 static struct pcmcia_driver btuart_driver = {
 	.owner		= THIS_MODULE,
 	.drv		= {
 		.name	= "btuart_cs",
 	},
 	.attach		= btuart_attach,
+	.event		= btuart_event,
 	.detach		= btuart_detach,
+	.id_table	= btuart_ids,
 };
 
 static int __init init_btuart_cs(void)
diff --git a/drivers/bluetooth/dtl1_cs.c b/drivers/bluetooth/dtl1_cs.c
--- a/drivers/bluetooth/dtl1_cs.c
+++ b/drivers/bluetooth/dtl1_cs.c
@@ -43,7 +43,6 @@
 #include <asm/system.h>
 #include <asm/io.h>
 
-#include <pcmcia/version.h>
 #include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
@@ -594,11 +593,6 @@ static dev_link_t *dtl1_attach(void)
 	link->next = dev_list;
 	dev_list = link;
 	client_reg.dev_info = &dev_info;
-	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 = &dtl1_event;
 	client_reg.Version = 0x0210;
 	client_reg.event_callback_args.client_data = link;
 
@@ -807,13 +801,22 @@ static int dtl1_event(event_t event, int
 	return 0;
 }
 
+static struct pcmcia_device_id dtl1_ids[] = {
+	PCMCIA_DEVICE_PROD_ID12("Nokia Mobile Phones", "DTL-1", 0xe1bfdd64, 0xe168480d),
+	PCMCIA_DEVICE_PROD_ID12("Socket", "CF", 0xb38bcc2e, 0x44ebf863),
+	PCMCIA_DEVICE_NULL
+};
+MODULE_DEVICE_TABLE(pcmcia, dtl1_ids);
+
 static struct pcmcia_driver dtl1_driver = {
 	.owner		= THIS_MODULE,
 	.drv		= {
 		.name	= "dtl1_cs",
 	},
 	.attach		= dtl1_attach,
+	.event		= dtl1_event,
 	.detach		= dtl1_detach,
+	.id_table	= dtl1_ids,
 };
 
 static int __init init_dtl1_cs(void)
diff --git a/drivers/bluetooth/hci_bcsp.c b/drivers/bluetooth/hci_bcsp.c
--- a/drivers/bluetooth/hci_bcsp.c
+++ b/drivers/bluetooth/hci_bcsp.c
@@ -58,8 +58,6 @@
 #ifndef CONFIG_BT_HCIUART_DEBUG
 #undef  BT_DBG
 #define BT_DBG( A... )
-#undef  BT_DMP
-#define BT_DMP( A... )
 #endif
 
 static int hciextn = 1;
diff --git a/drivers/bluetooth/hci_h4.c b/drivers/bluetooth/hci_h4.c
--- a/drivers/bluetooth/hci_h4.c
+++ b/drivers/bluetooth/hci_h4.c
@@ -57,8 +57,6 @@
 #ifndef CONFIG_BT_HCIUART_DEBUG
 #undef  BT_DBG
 #define BT_DBG( A... )
-#undef  BT_DMP
-#define BT_DMP( A... )
 #endif
 
 /* Initialize protocol */
@@ -125,7 +123,6 @@ static inline int h4_check_data_len(stru
 
 	BT_DBG("len %d room %d", len, room);
 	if (!len) {
-		BT_DMP(h4->rx_skb->data, h4->rx_skb->len);
 		hci_recv_frame(h4->rx_skb);
 	} else if (len > room) {
 		BT_ERR("Data length is too large");
@@ -169,8 +166,6 @@ static int h4_recv(struct hci_uart *hu, 
 			case H4_W4_DATA:
 				BT_DBG("Complete data");
 
-				BT_DMP(h4->rx_skb->data, h4->rx_skb->len);
-
 				hci_recv_frame(h4->rx_skb);
 
 				h4->rx_state = H4_W4_PACKET_TYPE;
diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c
--- a/drivers/bluetooth/hci_ldisc.c
+++ b/drivers/bluetooth/hci_ldisc.c
@@ -57,8 +57,6 @@
 #ifndef CONFIG_BT_HCIUART_DEBUG
 #undef  BT_DBG
 #define BT_DBG( A... )
-#undef  BT_DMP
-#define BT_DMP( A... )
 #endif
 
 static int reset = 0;
@@ -576,7 +574,7 @@ static void __exit hci_uart_exit(void)
 #endif
 
 	/* Release tty registration of line discipline */
-	if ((err = tty_register_ldisc(N_HCI, NULL)))
+	if ((err = tty_unregister_ldisc(N_HCI)))
 		BT_ERR("Can't unregister HCI line discipline (%d)", err);
 }
 
diff --git a/drivers/bluetooth/hci_usb.c b/drivers/bluetooth/hci_usb.c
--- a/drivers/bluetooth/hci_usb.c
+++ b/drivers/bluetooth/hci_usb.c
@@ -57,8 +57,6 @@
 #ifndef CONFIG_BT_HCIUSB_DEBUG
 #undef  BT_DBG
 #define BT_DBG(D...)
-#undef  BT_DMP
-#define BT_DMP(D...)
 #endif
 
 #ifndef CONFIG_BT_HCIUSB_ZERO_PACKET
@@ -110,6 +108,9 @@ static struct usb_device_id blacklist_id
 	/* Microsoft Wireless Transceiver for Bluetooth 2.0 */
 	{ USB_DEVICE(0x045e, 0x009c), .driver_info = HCI_RESET },
 
+	/* Kensington Bluetooth USB adapter */
+	{ USB_DEVICE(0x047d, 0x105d), .driver_info = HCI_RESET },
+
 	/* ISSC Bluetooth Adapter v3.1 */
 	{ USB_DEVICE(0x1131, 0x1001), .driver_info = HCI_RESET },
 
@@ -387,10 +388,8 @@ static void hci_usb_unlink_urbs(struct h
 			urb = &_urb->urb;
 			BT_DBG("%s freeing _urb %p type %d urb %p",
 					husb->hdev->name, _urb, _urb->type, urb);
-			if (urb->setup_packet)
-				kfree(urb->setup_packet);
-			if (urb->transfer_buffer)
-				kfree(urb->transfer_buffer);
+			kfree(urb->setup_packet);
+			kfree(urb->transfer_buffer);
 			_urb_free(_urb);
 		}
 
diff --git a/drivers/bluetooth/hci_vhci.c b/drivers/bluetooth/hci_vhci.c
--- a/drivers/bluetooth/hci_vhci.c
+++ b/drivers/bluetooth/hci_vhci.c
@@ -120,7 +120,7 @@ static unsigned int hci_vhci_chr_poll(st
 
 	poll_wait(file, &hci_vhci->read_wait, wait);
  
-	if (skb_queue_len(&hci_vhci->readq))
+	if (!skb_queue_empty(&hci_vhci->readq))
 		return POLLIN | POLLRDNORM;
 
 	return POLLOUT | POLLWRNORM;
diff --git a/drivers/cdrom/cm206.c b/drivers/cdrom/cm206.c
--- a/drivers/cdrom/cm206.c
+++ b/drivers/cdrom/cm206.c
@@ -307,7 +307,7 @@ static DEFINE_SPINLOCK(cm206_lock);
 /* First, we define some polling functions. These are actually
    only being used in the initialization. */
 
-void send_command_polled(int command)
+static void send_command_polled(int command)
 {
 	int loop = POLLOOP;
 	while (!(inw(r_line_status) & ls_transmitter_buffer_empty)
@@ -318,7 +318,7 @@ void send_command_polled(int command)
 	outw(command, r_uart_transmit);
 }
 
-uch receive_echo_polled(void)
+static uch receive_echo_polled(void)
 {
 	int loop = POLLOOP;
 	while (!(inw(r_line_status) & ls_receive_buffer_full) && loop > 0) {
@@ -328,13 +328,13 @@ uch receive_echo_polled(void)
 	return ((uch) inw(r_uart_receive));
 }
 
-uch send_receive_polled(int command)
+static uch send_receive_polled(int command)
 {
 	send_command_polled(command);
 	return receive_echo_polled();
 }
 
-inline void clear_ur(void)
+static inline void clear_ur(void)
 {
 	if (cd->ur_r != cd->ur_w) {
 		debug(("Deleting bytes from fifo:"));
@@ -439,7 +439,7 @@ static irqreturn_t cm206_interrupt(int s
 }
 
 /* we have put the address of the wait queue in who */
-void cm206_timeout(unsigned long who)
+static void cm206_timeout(unsigned long who)
 {
 	cd->timed_out = 1;
 	debug(("Timing out\n"));
@@ -448,7 +448,7 @@ void cm206_timeout(unsigned long who)
 
 /* This function returns 1 if a timeout occurred, 0 if an interrupt
    happened */
-int sleep_or_timeout(wait_queue_head_t * wait, int timeout)
+static int sleep_or_timeout(wait_queue_head_t * wait, int timeout)
 {
 	cd->timed_out = 0;
 	init_timer(&cd->timer);
@@ -465,13 +465,7 @@ int sleep_or_timeout(wait_queue_head_t *
 		return 0;
 }
 
-void cm206_delay(int nr_jiffies)
-{
-	DECLARE_WAIT_QUEUE_HEAD(wait);
-	sleep_or_timeout(&wait, nr_jiffies);
-}
-
-void send_command(int command)
+static void send_command(int command)
 {
 	debug(("Sending 0x%x\n", command));
 	if (!(inw(r_line_status) & ls_transmitter_buffer_empty)) {
@@ -490,7 +484,7 @@ void send_command(int command)
 		outw(command, r_uart_transmit);
 }
 
-uch receive_byte(int timeout)
+static uch receive_byte(int timeout)
 {
 	uch ret;
 	cli();
@@ -521,23 +515,23 @@ uch receive_byte(int timeout)
 	return ret;
 }
 
-inline uch receive_echo(void)
+static inline uch receive_echo(void)
 {
 	return receive_byte(UART_TIMEOUT);
 }
 
-inline uch send_receive(int command)
+static inline uch send_receive(int command)
 {
 	send_command(command);
 	return receive_echo();
 }
 
-inline uch wait_dsb(void)
+static inline uch wait_dsb(void)
 {
 	return receive_byte(DSB_TIMEOUT);
 }
 
-int type_0_command(int command, int expect_dsb)
+static int type_0_command(int command, int expect_dsb)
 {
 	int e;
 	clear_ur();
@@ -552,7 +546,7 @@ int type_0_command(int command, int expe
 	return 0;
 }
 
-int type_1_command(int command, int bytes, uch * status)
+static int type_1_command(int command, int bytes, uch * status)
 {				/* returns info */
 	int i;
 	if (type_0_command(command, 0))
@@ -564,7 +558,7 @@ int type_1_command(int command, int byte
 
 /* This function resets the adapter card. We'd better not do this too
  * often, because it tends to generate `lost interrupts.' */
-void reset_cm260(void)
+static void reset_cm260(void)
 {
 	outw(dc_normal | dc_initialize | READ_AHEAD, r_data_control);
 	udelay(10);		/* 3.3 mu sec minimum */
@@ -572,7 +566,7 @@ void reset_cm260(void)
 }
 
 /* fsm: frame-sec-min from linear address; one of many */
-void fsm(int lba, uch * fsm)
+static void fsm(int lba, uch * fsm)
 {
 	fsm[0] = lba % 75;
 	lba /= 75;
@@ -581,17 +575,17 @@ void fsm(int lba, uch * fsm)
 	fsm[2] = lba / 60;
 }
 
-inline int fsm2lba(uch * fsm)
+static inline int fsm2lba(uch * fsm)
 {
 	return fsm[0] + 75 * (fsm[1] - 2 + 60 * fsm[2]);
 }
 
-inline int f_s_m2lba(uch f, uch s, uch m)
+static inline int f_s_m2lba(uch f, uch s, uch m)
 {
 	return f + 75 * (s - 2 + 60 * m);
 }
 
-int start_read(int start)
+static int start_read(int start)
 {
 	uch read_sector[4] = { c_read_data, };
 	int i, e;
@@ -613,7 +607,7 @@ int start_read(int start)
 	return 0;
 }
 
-int stop_read(void)
+static int stop_read(void)
 {
 	int e;
 	type_0_command(c_stop, 0);
@@ -630,7 +624,7 @@ int stop_read(void)
    routine takes care of this. Set a flag `background' in the cd
    struct to indicate the process. */
 
-int read_background(int start, int reading)
+static int read_background(int start, int reading)
 {
 	if (cd->background)
 		return -1;	/* can't do twice */
@@ -658,7 +652,7 @@ void transport_data(int port, ush * dest
 
 
 #define MAX_TRIES 100
-int read_sector(int start)
+static int read_sector(int start)
 {
 	int tries = 0;
 	if (cd->background) {
@@ -753,7 +747,7 @@ static DECLARE_TASKLET(cm206_tasklet, cm
 /* This command clears the dsb_possible_media_change flag, so we must 
  * retain it.
  */
-void get_drive_status(void)
+static void get_drive_status(void)
 {
 	uch status[2];
 	type_1_command(c_drive_status, 2, status);	/* this might be done faster */
@@ -764,7 +758,7 @@ void get_drive_status(void)
 			  dsb_drive_not_ready | dsb_tray_not_closed));
 }
 
-void get_disc_status(void)
+static void get_disc_status(void)
 {
 	if (type_1_command(c_disc_status, 7, cd->disc_status)) {
 		debug(("get_disc_status: error\n"));
@@ -801,7 +795,7 @@ static void cm206_release(struct cdrom_d
 
 /* Empty buffer empties $sectors$ sectors of the adapter card buffer,
  * and then reads a sector in kernel memory.  */
-void empty_buffer(int sectors)
+static void empty_buffer(int sectors)
 {
 	while (sectors >= 0) {
 		transport_data(r_fifo_output_buffer,
@@ -819,7 +813,7 @@ void empty_buffer(int sectors)
 /* try_adapter. This function determines if the requested sector is
    in adapter memory, or will appear there soon. Returns 0 upon
    success */
-int try_adapter(int sector)
+static int try_adapter(int sector)
 {
 	if (cd->adapter_first <= sector && sector < cd->adapter_last) {
 		/* sector is in adapter memory */
@@ -910,7 +904,7 @@ static void do_cm206_request(request_que
 */
 
 /* seek seeks to address lba. It does wait to arrive there. */
-void seek(int lba)
+static void seek(int lba)
 {
 	int i;
 	uch seek_command[4] = { c_seek, };
@@ -926,7 +920,7 @@ uch bcdbin(unsigned char bcd)
 	return (bcd >> 4) * 10 + (bcd & 0xf);
 }
 
-inline uch normalize_track(uch track)
+static inline uch normalize_track(uch track)
 {
 	if (track < 1)
 		return 1;
@@ -939,7 +933,7 @@ inline uch normalize_track(uch track)
  * tracks seen in the process. Input $track$ must be between 1 and
  * #-of-tracks+1.  Note that the start of the disc must be in toc[1].fsm. 
  */
-int get_toc_lba(uch track)
+static int get_toc_lba(uch track)
 {
 	int max = 74 * 60 * 75 - 150, min = fsm2lba(cd->toc[1].fsm);
 	int i, lba, l, old_lba = 0;
@@ -991,7 +985,7 @@ int get_toc_lba(uch track)
 	return lba;
 }
 
-void update_toc_entry(uch track)
+static void update_toc_entry(uch track)
 {
 	track = normalize_track(track);
 	if (!cd->toc[track].track)
@@ -999,7 +993,7 @@ void update_toc_entry(uch track)
 }
 
 /* return 0 upon success */
-int read_toc_header(struct cdrom_tochdr *hp)
+static int read_toc_header(struct cdrom_tochdr *hp)
 {
 	if (!FIRST_TRACK)
 		get_disc_status();
@@ -1016,7 +1010,7 @@ int read_toc_header(struct cdrom_tochdr 
 	return -1;
 }
 
-void play_from_to_msf(struct cdrom_msf *msfp)
+static void play_from_to_msf(struct cdrom_msf *msfp)
 {
 	uch play_command[] = { c_play,
 		msfp->cdmsf_frame0, msfp->cdmsf_sec0, msfp->cdmsf_min0,
@@ -1032,7 +1026,7 @@ void play_from_to_msf(struct cdrom_msf *
 	cd->dsb = wait_dsb();
 }
 
-void play_from_to_track(int from, int to)
+static void play_from_to_track(int from, int to)
 {
 	uch play_command[8] = { c_play, };
 	int i;
@@ -1059,7 +1053,7 @@ void play_from_to_track(int from, int to
 	cd->dsb = wait_dsb();
 }
 
-int get_current_q(struct cdrom_subchnl *qp)
+static int get_current_q(struct cdrom_subchnl *qp)
 {
 	int i;
 	uch *q = cd->q;
@@ -1093,14 +1087,14 @@ int get_current_q(struct cdrom_subchnl *
 	return 0;
 }
 
-void invalidate_toc(void)
+static void invalidate_toc(void)
 {
 	memset(cd->toc, 0, sizeof(cd->toc));
 	memset(cd->disc_status, 0, sizeof(cd->disc_status));
 }
 
 /* cdrom.c guarantees that cdte_format == CDROM_MSF */
-void get_toc_entry(struct cdrom_tocentry *ep)
+static void get_toc_entry(struct cdrom_tocentry *ep)
 {
 	uch track = normalize_track(ep->cdte_track);
 	update_toc_entry(track);
@@ -1117,8 +1111,8 @@ void get_toc_entry(struct cdrom_tocentry
  * upon success. Memory checking has been done by cdrom_ioctl(), the
  * calling function, as well as LBA/MSF sanitization.
 */
-int cm206_audio_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
-		      void *arg)
+static int cm206_audio_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
+			     void *arg)
 {
 	switch (cmd) {
 	case CDROMREADTOCHDR:
@@ -1189,7 +1183,7 @@ static int cm206_ioctl(struct cdrom_devi
 	}
 }
 
-int cm206_media_changed(struct cdrom_device_info *cdi, int disc_nr)
+static int cm206_media_changed(struct cdrom_device_info *cdi, int disc_nr)
 {
 	if (cd != NULL) {
 		int r;
@@ -1204,16 +1198,9 @@ int cm206_media_changed(struct cdrom_dev
 /* The new generic cdrom support. Routines should be concise, most of
    the logic should be in cdrom.c */
 
-/* returns number of times device is in use */
-int cm206_open_files(struct cdrom_device_info *cdi)
-{
-	if (cd)
-		return cd->openfiles;
-	return -1;
-}
 
 /* controls tray movement */
-int cm206_tray_move(struct cdrom_device_info *cdi, int position)
+static int cm206_tray_move(struct cdrom_device_info *cdi, int position)
 {
 	if (position) {		/* 1: eject */
 		type_0_command(c_open_tray, 1);
@@ -1224,7 +1211,7 @@ int cm206_tray_move(struct cdrom_device_
 }
 
 /* gives current state of the drive */
-int cm206_drive_status(struct cdrom_device_info *cdi, int slot_nr)
+static int cm206_drive_status(struct cdrom_device_info *cdi, int slot_nr)
 {
 	get_drive_status();
 	if (cd->dsb & dsb_tray_not_closed)
@@ -1237,7 +1224,7 @@ int cm206_drive_status(struct cdrom_devi
 }
 
 /* locks or unlocks door lock==1: lock; return 0 upon success */
-int cm206_lock_door(struct cdrom_device_info *cdi, int lock)
+static int cm206_lock_door(struct cdrom_device_info *cdi, int lock)
 {
 	uch command = (lock) ? c_lock_tray : c_unlock_tray;
 	type_0_command(command, 1);	/* wait and get dsb */
@@ -1248,8 +1235,8 @@ int cm206_lock_door(struct cdrom_device_
 /* Although a session start should be in LBA format, we return it in 
    MSF format because it is slightly easier, and the new generic ioctl
    will take care of the necessary conversion. */
-int cm206_get_last_session(struct cdrom_device_info *cdi,
-			   struct cdrom_multisession *mssp)
+static int cm206_get_last_session(struct cdrom_device_info *cdi,
+				  struct cdrom_multisession *mssp)
 {
 	if (!FIRST_TRACK)
 		get_disc_status();
@@ -1268,7 +1255,7 @@ int cm206_get_last_session(struct cdrom_
 	return 0;
 }
 
-int cm206_get_upc(struct cdrom_device_info *cdi, struct cdrom_mcn *mcn)
+static int cm206_get_upc(struct cdrom_device_info *cdi, struct cdrom_mcn *mcn)
 {
 	uch upc[10];
 	char *ret = mcn->medium_catalog_number;
@@ -1287,7 +1274,7 @@ int cm206_get_upc(struct cdrom_device_in
 	return 0;
 }
 
-int cm206_reset(struct cdrom_device_info *cdi)
+static int cm206_reset(struct cdrom_device_info *cdi)
 {
 	stop_read();
 	reset_cm260();
@@ -1300,7 +1287,7 @@ int cm206_reset(struct cdrom_device_info
 	return 0;
 }
 
-int cm206_select_speed(struct cdrom_device_info *cdi, int speed)
+static int cm206_select_speed(struct cdrom_device_info *cdi, int speed)
 {
 	int r;
 	switch (speed) {
@@ -1392,7 +1379,7 @@ static struct gendisk *cm206_gendisk;
    request_region, 15 bits of one port and 6 of another make things
    likely enough to accept the region on the first hit...
  */
-int __init probe_base_port(int base)
+static int __init probe_base_port(int base)
 {
 	int b = 0x300, e = 0x370;	/* this is the range of start addresses */
 	volatile int fool, i;
@@ -1416,7 +1403,7 @@ int __init probe_base_port(int base)
 
 #if !defined(MODULE) || defined(AUTO_PROBE_MODULE)
 /* Probe for irq# nr. If nr==0, probe for all possible irq's. */
-int __init probe_irq(int nr)
+static int __init probe_irq(int nr)
 {
 	int irqs, irq;
 	outw(dc_normal | READ_AHEAD, r_data_control);	/* disable irq-generation */
@@ -1558,7 +1545,7 @@ static void __init parse_options(void)
 	}
 }
 
-int __cm206_init(void)
+static int __cm206_init(void)
 {
 	parse_options();
 #if !defined(AUTO_PROBE_MODULE)
@@ -1567,7 +1554,7 @@ int __cm206_init(void)
 	return cm206_init();
 }
 
-void __exit cm206_exit(void)
+static void __exit cm206_exit(void)
 {
 	del_gendisk(cm206_gendisk);
 	put_disk(cm206_gendisk);
diff --git a/drivers/cdrom/isp16.c b/drivers/cdrom/isp16.c
--- a/drivers/cdrom/isp16.c
+++ b/drivers/cdrom/isp16.c
@@ -18,7 +18,7 @@
  *
  *     19 June 2004     -- check_region() converted to request_region()
  *                         and return statement cleanups.
- *                         Jesper Juhl <juhl-lkml@dif.dk>
+ *                          - Jesper Juhl
  *
  *    Detect cdrom interface on ISP16 sound card.
  *    Configure cdrom interface.
diff --git a/drivers/cdrom/mcdx.c b/drivers/cdrom/mcdx.c
--- a/drivers/cdrom/mcdx.c
+++ b/drivers/cdrom/mcdx.c
@@ -51,7 +51,7 @@
  */
 
 
-#if RCS
+#ifdef RCS
 static const char *mcdx_c_version
     = "$Id: mcdx.c,v 1.21 1997/01/26 07:12:59 davem Exp $";
 #endif
@@ -706,7 +706,7 @@ static int mcdx_open(struct cdrom_device
 		xtrace(OPENCLOSE, "open() init irq generation\n");
 		if (-1 == mcdx_config(stuffp, 1))
 			return -EIO;
-#if FALLBACK
+#ifdef FALLBACK
 		/* Set the read speed */
 		xwarn("AAA %x AAA\n", stuffp->readcmd);
 		if (stuffp->readerrs)
@@ -1216,7 +1216,7 @@ static int __init mcdx_init_drive(int dr
 	}
 
 
-#if WE_KNOW_WHY
+#ifdef WE_KNOW_WHY
 	/* irq 11 -> channel register */
 	outb(0x50, stuffp->wreg_chn);
 #endif
@@ -1294,7 +1294,7 @@ static int mcdx_transfer(struct s_drive_
 
 	ans = mcdx_xfer(stuffp, p, sector, nr_sectors);
 	return ans;
-#if FALLBACK
+#ifdef FALLBACK
 	if (-1 == ans)
 		stuffp->readerrs++;
 	else
diff --git a/drivers/cdrom/optcd.c b/drivers/cdrom/optcd.c
--- a/drivers/cdrom/optcd.c
+++ b/drivers/cdrom/optcd.c
@@ -245,7 +245,7 @@ module_param(optcd_port, short, 0);
 
 
 /* Busy wait until FLAG goes low. Return 0 on timeout. */
-inline static int flag_low(int flag, unsigned long timeout)
+static inline int flag_low(int flag, unsigned long timeout)
 {
 	int flag_high;
 	unsigned long count = 0;
@@ -381,7 +381,7 @@ static int send_seek_params(struct cdrom
 
 /* Wait for command execution status. Choice between busy waiting
    and sleeping. Return value <0 indicates timeout. */
-inline static int get_exec_status(int busy_waiting)
+static inline int get_exec_status(int busy_waiting)
 {
 	unsigned char exec_status;
 
@@ -398,7 +398,7 @@ inline static int get_exec_status(int bu
 
 /* Wait busy for extra byte of data that a command returns.
    Return value <0 indicates timeout. */
-inline static int get_data(int short_timeout)
+static inline int get_data(int short_timeout)
 {
 	unsigned char data;
 
@@ -441,14 +441,14 @@ static int reset_drive(void)
 /* Facilities for asynchronous operation */
 
 /* Read status/data availability flags FL_STEN and FL_DTEN */
-inline static int stdt_flags(void)
+static inline int stdt_flags(void)
 {
 	return inb(STATUS_PORT) & FL_STDT;
 }
 
 
 /* Fetch status that has previously been waited for. <0 means not available */
-inline static int fetch_status(void)
+static inline int fetch_status(void)
 {
 	unsigned char status;
 
@@ -462,7 +462,7 @@ inline static int fetch_status(void)
 
 
 /* Fetch data that has previously been waited for. */
-inline static void fetch_data(char *buf, int n)
+static inline void fetch_data(char *buf, int n)
 {
 	insb(DATA_PORT, buf, n);
 	DEBUG((DEBUG_DRIVE_IF, "fetched 0x%x bytes", n));
@@ -470,7 +470,7 @@ inline static void fetch_data(char *buf,
 
 
 /* Flush status and data fifos */
-inline static void flush_data(void)
+static inline void flush_data(void)
 {
 	while ((inb(STATUS_PORT) & FL_STDT) != FL_STDT)
 		inb(DATA_PORT);
@@ -482,7 +482,7 @@ inline static void flush_data(void)
 
 /* Send a simple command and wait for response. Command codes < COMFETCH
    are quick response commands */
-inline static int exec_cmd(int cmd)
+static inline int exec_cmd(int cmd)
 {
 	int ack = send_cmd(cmd);
 	if (ack < 0)
@@ -493,7 +493,7 @@ inline static int exec_cmd(int cmd)
 
 /* Send a command with parameters. Don't wait for the response,
  * which consists of data blocks read from the CD. */
-inline static int exec_read_cmd(int cmd, struct cdrom_msf *params)
+static inline int exec_read_cmd(int cmd, struct cdrom_msf *params)
 {
 	int ack = send_cmd(cmd);
 	if (ack < 0)
@@ -503,7 +503,7 @@ inline static int exec_read_cmd(int cmd,
 
 
 /* Send a seek command with parameters and wait for response */
-inline static int exec_seek_cmd(int cmd, struct cdrom_msf *params)
+static inline int exec_seek_cmd(int cmd, struct cdrom_msf *params)
 {
 	int ack = send_cmd(cmd);
 	if (ack < 0)
@@ -516,7 +516,7 @@ inline static int exec_seek_cmd(int cmd,
 
 
 /* Send a command with parameters and wait for response */
-inline static int exec_long_cmd(int cmd, struct cdrom_msf *params)
+static inline int exec_long_cmd(int cmd, struct cdrom_msf *params)
 {
 	int ack = exec_read_cmd(cmd, params);
 	if (ack < 0)
@@ -528,7 +528,7 @@ inline static int exec_long_cmd(int cmd,
 
 
 /* Binary to BCD (2 digits) */
-inline static void single_bin2bcd(u_char *p)
+static inline void single_bin2bcd(u_char *p)
 {
 	DEBUG((DEBUG_CONV, "bin2bcd %02d", *p));
 	*p = (*p % 10) | ((*p / 10) << 4);
@@ -565,7 +565,7 @@ static void lba2msf(int lba, struct cdro
 
 
 /* Two BCD digits to binary */
-inline static u_char bcd2bin(u_char bcd)
+static inline u_char bcd2bin(u_char bcd)
 {
 	DEBUG((DEBUG_CONV, "bcd2bin %x%02x", bcd));
 	return (bcd >> 4) * 10 + (bcd & 0x0f);
@@ -988,7 +988,7 @@ static char buf[CD_FRAMESIZE * N_BUFS];
 static volatile int buf_bn[N_BUFS], next_bn;
 static volatile int buf_in = 0, buf_out = NOBUF;
 
-inline static void opt_invalidate_buffers(void)
+static inline void opt_invalidate_buffers(void)
 {
 	int i;
 
diff --git a/drivers/cdrom/sonycd535.c b/drivers/cdrom/sonycd535.c
--- a/drivers/cdrom/sonycd535.c
+++ b/drivers/cdrom/sonycd535.c
@@ -1605,8 +1605,7 @@ out7:
 	put_disk(cdu_disk);
 out6:
 	for (i = 0; i < sony_buffer_sectors; i++)
-		if (sony_buffer[i]) 
-			kfree(sony_buffer[i]);
+		kfree(sony_buffer[i]);
 out5:
 	kfree(sony_buffer);
 out4:
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -80,7 +80,7 @@ config SERIAL_NONSTANDARD
 
 config COMPUTONE
 	tristate "Computone IntelliPort Plus serial support"
-	depends on SERIAL_NONSTANDARD && BROKEN_ON_SMP
+	depends on SERIAL_NONSTANDARD && BROKEN_ON_SMP && (BROKEN || !SPARC32)
 	---help---
 	  This driver supports the entire family of Intelliport II/Plus
 	  controllers with the exception of the MicroChannel controllers and
@@ -138,7 +138,7 @@ config CYZ_INTR
 
 config DIGIEPCA
 	tristate "Digiboard Intelligent Async Support"
-	depends on SERIAL_NONSTANDARD && BROKEN_ON_SMP
+	depends on SERIAL_NONSTANDARD && BROKEN_ON_SMP && (!64BIT || BROKEN)
 	---help---
 	  This is a driver for Digi International's Xx, Xeve, and Xem series
 	  of cards which provide multiple serial ports. You would need
@@ -208,7 +208,7 @@ config SYNCLINK
 
 config SYNCLINKMP
 	tristate "SyncLink Multiport support"
-	depends on SERIAL_NONSTANDARD
+	depends on SERIAL_NONSTANDARD && (BROKEN || !SPARC32)
 	help
 	  Enable support for the SyncLink Multiport (2 or 4 ports)
 	  serial adapter, running asynchronous and HDLC communications up
@@ -735,7 +735,7 @@ config SGI_IP27_RTC
 
 config GEN_RTC
 	tristate "Generic /dev/rtc emulation"
-	depends on RTC!=y && !IA64 && !ARM
+	depends on RTC!=y && !IA64 && !ARM && !PPC64 && !M32R && !SPARC32
 	---help---
 	  If you say Y here and create a character special file /dev/rtc with
 	  major number 10 and minor number 135 using mknod ("man mknod"), you
@@ -929,6 +929,10 @@ config SCx200_GPIO
 
 	  If compiled as a module, it will be called scx200_gpio.
 
+config GPIO_VR41XX
+	tristate "NEC VR4100 series General-purpose I/O Unit support"
+	depends on CPU_VR41XX
+
 config RAW_DRIVER
 	tristate "RAW driver (/dev/raw/rawN) (OBSOLETE)"
 	help
@@ -936,8 +940,8 @@ config RAW_DRIVER
 	  Once bound, I/O against /dev/raw/rawN uses efficient zero-copy I/O. 
 	  See the raw(8) manpage for more details.
 
-          The raw driver is deprecated and may be removed from 2.7
-          kernels.  Applications should simply open the device (eg /dev/hda1)
+          The raw driver is deprecated and will be removed soon.
+          Applications should simply open the device (eg /dev/hda1)
           with the O_DIRECT flag.
 
 config HPET
diff --git a/drivers/char/Makefile b/drivers/char/Makefile
--- a/drivers/char/Makefile
+++ b/drivers/char/Makefile
@@ -40,7 +40,7 @@ obj-$(CONFIG_N_HDLC)		+= n_hdlc.o
 obj-$(CONFIG_AMIGA_BUILTIN_SERIAL) += amiserial.o
 obj-$(CONFIG_SX)		+= sx.o generic_serial.o
 obj-$(CONFIG_RIO)		+= rio/ generic_serial.o
-obj-$(CONFIG_HVC_CONSOLE)	+= hvc_console.o hvsi.o
+obj-$(CONFIG_HVC_CONSOLE)	+= hvc_console.o hvc_vio.o hvsi.o
 obj-$(CONFIG_RAW_DRIVER)	+= raw.o
 obj-$(CONFIG_SGI_SNSC)		+= snsc.o snsc_event.o
 obj-$(CONFIG_MMTIMER)		+= mmtimer.o
@@ -80,6 +80,7 @@ obj-$(CONFIG_PPDEV) += ppdev.o
 obj-$(CONFIG_NWBUTTON) += nwbutton.o
 obj-$(CONFIG_NWFLASH) += nwflash.o
 obj-$(CONFIG_SCx200_GPIO) += scx200_gpio.o
+obj-$(CONFIG_GPIO_VR41XX) += vr41xx_giu.o
 obj-$(CONFIG_TANBAC_TB0219) += tb0219.o
 
 obj-$(CONFIG_WATCHDOG)	+= watchdog/
diff --git a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h
--- a/drivers/char/agp/agp.h
+++ b/drivers/char/agp/agp.h
@@ -143,6 +143,7 @@ struct agp_bridge_data {
 	char major_version;
 	char minor_version;
 	struct list_head list;
+	u32 apbase_config;
 };
 
 #define KB(x)	((x) * 1024)
diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c
--- a/drivers/char/agp/amd64-agp.c
+++ b/drivers/char/agp/amd64-agp.c
@@ -686,6 +686,15 @@ static struct pci_device_id agp_amd64_pc
 	.subvendor	= PCI_ANY_ID,
 	.subdevice	= PCI_ANY_ID,
 	},
+	/* SIS 760 */
+	{
+	.class		= (PCI_CLASS_BRIDGE_HOST << 8),
+	.class_mask	= ~0,
+	.vendor		= PCI_VENDOR_ID_SI,
+	.device		= PCI_DEVICE_ID_SI_760,
+	.subvendor	= PCI_ANY_ID,
+	.subdevice	= PCI_ANY_ID,
+	},
 	{ }
 };
 
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
--- a/drivers/char/agp/intel-agp.c
+++ b/drivers/char/agp/intel-agp.c
@@ -1047,9 +1047,15 @@ static int intel_845_configure(void)
 	/* aperture size */
 	pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value);
 
-	/* address to map to */
-	pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp);
-	agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
+	if (agp_bridge->apbase_config != 0) {
+		pci_write_config_dword(agp_bridge->dev, AGP_APBASE,
+				       agp_bridge->apbase_config);
+	} else {
+		/* address to map to */
+		pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp);
+		agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
+		agp_bridge->apbase_config = temp;
+	}
 
 	/* attbase - aperture base */
 	pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr);
diff --git a/drivers/char/amiserial.c b/drivers/char/amiserial.c
--- a/drivers/char/amiserial.c
+++ b/drivers/char/amiserial.c
@@ -861,13 +861,18 @@ static void change_speed(struct async_st
 
 static void rs_put_char(struct tty_struct *tty, unsigned char ch)
 {
-	struct async_struct *info = (struct async_struct *)tty->driver_data;
+	struct async_struct *info;
 	unsigned long flags;
 
+	if (!tty)
+		return;
+
+	info = tty->driver_data;
+
 	if (serial_paranoia_check(info, tty->name, "rs_put_char"))
 		return;
 
-	if (!tty || !info->xmit.buf)
+	if (!info->xmit.buf)
 		return;
 
 	local_irq_save(flags);
@@ -910,13 +915,18 @@ static void rs_flush_chars(struct tty_st
 static int rs_write(struct tty_struct * tty, const unsigned char *buf, int count)
 {
 	int	c, ret = 0;
-	struct async_struct *info = (struct async_struct *)tty->driver_data;
+	struct async_struct *info;
 	unsigned long flags;
 
+	if (!tty)
+		return 0;
+
+	info = tty->driver_data;
+
 	if (serial_paranoia_check(info, tty->name, "rs_write"))
 		return 0;
 
-	if (!tty || !info->xmit.buf || !tmp_buf)
+	if (!info->xmit.buf || !tmp_buf)
 		return 0;
 
 	local_save_flags(flags);
@@ -1963,10 +1973,6 @@ static _INLINE_ void show_serial_version
 }
 
 
-int register_serial(struct serial_struct *req);
-void unregister_serial(int line);
-
-
 static struct tty_operations serial_ops = {
 	.open = rs_open,
 	.close = rs_close,
diff --git a/drivers/char/applicom.c b/drivers/char/applicom.c
--- a/drivers/char/applicom.c
+++ b/drivers/char/applicom.c
@@ -599,7 +599,7 @@ static ssize_t ac_read (struct file *fil
 
 #ifdef DEBUG
 		if (loopcount++ > 2) {
-			printk("Looping in ac_read. loopcount %d\n", loopcount);
+			printk(KERN_DEBUG "Looping in ac_read. loopcount %d\n", loopcount);
 		}
 #endif
 	} 
diff --git a/drivers/char/drm/Kconfig b/drivers/char/drm/Kconfig
--- a/drivers/char/drm/Kconfig
+++ b/drivers/char/drm/Kconfig
@@ -6,7 +6,7 @@
 #
 config DRM
 	tristate "Direct Rendering Manager (XFree86 4.1.0 and higher DRI support)"
-	depends on AGP || AGP=n
+	depends on (AGP || AGP=n) && PCI
 	help
 	  Kernel-level support for the Direct Rendering Infrastructure (DRI)
 	  introduced in XFree86 4.0. If you say Y here, you need to select
@@ -96,3 +96,10 @@ config DRM_SIS
           chipset. If M is selected the module will be called sis. AGP
           support is required for this driver to work.
 
+config DRM_VIA
+	tristate "Via unichrome video cards"
+	depends on DRM
+	help
+	  Choose this option if you have a Via unichrome or compatible video
+	  chipset. If M is selected the module will be called via.
+
diff --git a/drivers/char/drm/Makefile b/drivers/char/drm/Makefile
--- a/drivers/char/drm/Makefile
+++ b/drivers/char/drm/Makefile
@@ -18,6 +18,15 @@ i915-objs   := i915_drv.o i915_dma.o i91
 radeon-objs := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o radeon_irq.o
 ffb-objs    := ffb_drv.o ffb_context.o
 sis-objs    := sis_drv.o sis_ds.o sis_mm.o
+via-objs    := via_irq.o via_drv.o via_ds.o via_map.o via_mm.o via_dma.o via_verifier.o via_video.o
+
+ifeq ($(CONFIG_COMPAT),y)
+drm-objs    += drm_ioc32.o
+radeon-objs += radeon_ioc32.o
+mga-objs    += mga_ioc32.o
+r128-objs   += r128_ioc32.o
+i915-objs   += i915_ioc32.o
+endif
 
 obj-$(CONFIG_DRM)	+= drm.o
 obj-$(CONFIG_DRM_GAMMA) += gamma.o
@@ -30,4 +39,5 @@ obj-$(CONFIG_DRM_I830)	+= i830.o
 obj-$(CONFIG_DRM_I915)  += i915.o
 obj-$(CONFIG_DRM_FFB)   += ffb.o
 obj-$(CONFIG_DRM_SIS)   += sis.o
+obj-$(CONFIG_DRM_VIA)	+=via.o
 
diff --git a/drivers/char/drm/ati_pcigart.c b/drivers/char/drm/ati_pcigart.c
--- a/drivers/char/drm/ati_pcigart.c
+++ b/drivers/char/drm/ati_pcigart.c
@@ -52,7 +52,7 @@
 # define ATI_MAX_PCIGART_PAGES		8192	/**< 32 MB aperture, 4K pages */
 # define ATI_PCIGART_PAGE_SIZE		4096	/**< PCI GART page size */
 
-unsigned long drm_ati_alloc_pcigart_table( void )
+static unsigned long drm_ati_alloc_pcigart_table( void )
 {
 	unsigned long address;
 	struct page *page;
diff --git a/drivers/char/drm/drm.h b/drivers/char/drm/drm.h
--- a/drivers/char/drm/drm.h
+++ b/drivers/char/drm/drm.h
@@ -38,7 +38,9 @@
 #define _DRM_H_
 
 #if defined(__linux__)
+#if defined(__KERNEL__)
 #include <linux/config.h>
+#endif
 #include <asm/ioctl.h>		/* For _IO* macros */
 #define DRM_IOCTL_NR(n)		_IOC_NR(n)
 #define DRM_IOC_VOID		_IOC_NONE
diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h
--- a/drivers/char/drm/drmP.h
+++ b/drivers/char/drm/drmP.h
@@ -316,6 +316,9 @@ do {									\
 typedef int drm_ioctl_t( struct inode *inode, struct file *filp,
 			 unsigned int cmd, unsigned long arg );
 
+typedef int drm_ioctl_compat_t(struct file *filp, unsigned int cmd,
+			       unsigned long arg);
+
 typedef struct drm_ioctl_desc {
 	drm_ioctl_t	     *func;
 	int		     auth_needed;
@@ -771,37 +774,28 @@ extern int           drm_cpu_valid( void
 				/* Driver support (drm_drv.h) */
 extern int           drm_init(struct drm_driver *driver);
 extern void          drm_exit(struct drm_driver *driver);
-extern int           drm_version(struct inode *inode, struct file *filp,
-				  unsigned int cmd, unsigned long arg);
 extern int           drm_ioctl(struct inode *inode, struct file *filp,
 				unsigned int cmd, unsigned long arg);
+extern long	     drm_compat_ioctl(struct file *filp,
+				unsigned int cmd, unsigned long arg);
 extern int           drm_takedown(drm_device_t * dev);
 
 				/* Device support (drm_fops.h) */
 extern int           drm_open(struct inode *inode, struct file *filp);
 extern int           drm_stub_open(struct inode *inode, struct file *filp);
-extern int	     drm_open_helper(struct inode *inode, struct file *filp,
-				      drm_device_t *dev);
 extern int	     drm_flush(struct file *filp);
 extern int	     drm_fasync(int fd, struct file *filp, int on);
 extern int           drm_release(struct inode *inode, struct file *filp);
 
 				/* Mapping support (drm_vm.h) */
-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);
-extern int	     drm_mmap_dma(struct file *filp,
-				   struct vm_area_struct *vma);
 extern int	     drm_mmap(struct file *filp, struct vm_area_struct *vma);
 extern unsigned int  drm_poll(struct file *filp, struct poll_table_struct *wait);
-extern ssize_t       drm_read(struct file *filp, char __user *buf, size_t count, loff_t *off);
 
 				/* Memory management support (drm_memory.h) */
 #include "drm_memory.h"
 extern void	     drm_mem_init(void);
 extern int	     drm_mem_info(char *buf, char **start, off_t offset,
 				   int request, int *eof, void *data);
-extern void	     *drm_calloc(size_t nmemb, size_t size, int area);
 extern void	     *drm_realloc(void *oldpt, size_t oldsize, size_t size,
 				   int area);
 extern unsigned long drm_alloc_pages(int order, int area);
@@ -849,9 +843,6 @@ extern int	     drm_newctx( struct inode
 extern int	     drm_rmctx( struct inode *inode, struct file *filp,
 				 unsigned int cmd, unsigned long arg );
 
-extern int	     drm_context_switch(drm_device_t *dev, int old, int new);
-extern int	     drm_context_switch_complete(drm_device_t *dev, int new);
-
 extern int	     drm_ctxbitmap_init( drm_device_t *dev );
 extern void	     drm_ctxbitmap_cleanup( drm_device_t *dev );
 extern void          drm_ctxbitmap_free( drm_device_t *dev, int ctx_handle );
@@ -869,9 +860,6 @@ extern int	     drm_rmdraw(struct inode 
 
 
 				/* Authentication IOCTL support (drm_auth.h) */
-extern int	     drm_add_magic(drm_device_t *dev, drm_file_t *priv,
-				    drm_magic_t magic);
-extern int	     drm_remove_magic(drm_device_t *dev, drm_magic_t magic);
 extern int	     drm_getmagic(struct inode *inode, struct file *filp,
 				   unsigned int cmd, unsigned long arg);
 extern int	     drm_authmagic(struct inode *inode, struct file *filp,
@@ -888,13 +876,9 @@ extern int           drm_unlock(struct i
 				 unsigned int cmd, unsigned long arg);
 extern int	     drm_lock_take(__volatile__ unsigned int *lock,
 				    unsigned int context);
-extern int	     drm_lock_transfer(drm_device_t *dev,
-					__volatile__ unsigned int *lock,
-					unsigned int context);
 extern int	     drm_lock_free(drm_device_t *dev,
 				    __volatile__ unsigned int *lock,
 				    unsigned int context);
-extern int           drm_notifier(void *priv);
 
 				/* Buffer management support (drm_bufs.h) */
 extern int	     drm_order( unsigned long size );
@@ -922,7 +906,6 @@ extern void	     drm_core_reclaim_buffer
 				/* IRQ support (drm_irq.h) */
 extern int           drm_control( struct inode *inode, struct file *filp,
 				   unsigned int cmd, unsigned long arg );
-extern int           drm_irq_install( drm_device_t *dev );
 extern int           drm_irq_uninstall( drm_device_t *dev );
 extern irqreturn_t   drm_irq_handler( DRM_IRQ_ARGS );
 extern void          drm_driver_irq_preinstall( drm_device_t *dev );
@@ -962,7 +945,6 @@ extern int            drm_agp_unbind_mem
 extern int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
 		     struct drm_driver *driver);
 extern int drm_put_dev(drm_device_t * dev);
-extern int drm_get_head(drm_device_t * dev, drm_head_t *head);
 extern int drm_put_head(drm_head_t * head);
 extern unsigned int   drm_debug;
 extern unsigned int   drm_cards_limit;
@@ -1059,9 +1041,16 @@ static __inline__ void drm_free(void *pt
 {
 	kfree(pt);
 }
+
+/** Wrapper around kcalloc() */
+static __inline__ void *drm_calloc(size_t nmemb, size_t size, int area)
+{
+	return kcalloc(nmemb, size, GFP_KERNEL);
+}
 #else
 extern void *drm_alloc(size_t size, int area);
 extern void drm_free(void *pt, size_t size, int area);
+extern void *drm_calloc(size_t nmemb, size_t size, int area);
 #endif
 
 /*@}*/
diff --git a/drivers/char/drm/drm_auth.c b/drivers/char/drm/drm_auth.c
--- a/drivers/char/drm/drm_auth.c
+++ b/drivers/char/drm/drm_auth.c
@@ -87,7 +87,7 @@ static drm_file_t *drm_find_file(drm_dev
  * associated the magic number hash key in drm_device::magiclist, while holding
  * the drm_device::struct_sem lock.
  */
-int drm_add_magic(drm_device_t *dev, drm_file_t *priv, drm_magic_t magic)
+static int drm_add_magic(drm_device_t *dev, drm_file_t *priv, drm_magic_t magic)
 {
 	int		  hash;
 	drm_magic_entry_t *entry;
@@ -124,7 +124,7 @@ int drm_add_magic(drm_device_t *dev, drm
  * Searches and unlinks the entry in drm_device::magiclist with the magic
  * number hash key, while holding the drm_device::struct_sem lock.
  */
-int drm_remove_magic(drm_device_t *dev, drm_magic_t magic)
+static int drm_remove_magic(drm_device_t *dev, drm_magic_t magic)
 {
 	drm_magic_entry_t *prev = NULL;
 	drm_magic_entry_t *pt;
diff --git a/drivers/char/drm/drm_bufs.c b/drivers/char/drm/drm_bufs.c
--- a/drivers/char/drm/drm_bufs.c
+++ b/drivers/char/drm/drm_bufs.c
@@ -60,6 +60,15 @@ int drm_order( unsigned long size )
 }
 EXPORT_SYMBOL(drm_order);
 
+#ifdef CONFIG_COMPAT
+/*
+ * Used to allocate 32-bit handles for _DRM_SHM regions
+ * The 0x10000000 value is chosen to be out of the way of
+ * FB/register and GART physical addresses.
+ */
+static unsigned int map32_handle = 0x10000000;
+#endif
+
 /**
  * Ioctl to specify a range of memory that is available for mapping by a non-root process.
  *
@@ -187,16 +196,18 @@ int drm_addmap( struct inode *inode, str
 
 	down(&dev->struct_sem);
 	list_add(&list->head, &dev->maplist->head);
+#ifdef CONFIG_COMPAT
+	/* Assign a 32-bit handle for _DRM_SHM mappings */
+	/* We do it here so that dev->struct_sem protects the increment */
+	if (map->type == _DRM_SHM)
+		map->offset = map32_handle += PAGE_SIZE;
+#endif
  	up(&dev->struct_sem);
 
 	if ( copy_to_user( argp, map, sizeof(*map) ) )
 		return -EFAULT;
-	if ( map->type != _DRM_SHM ) {
-		if ( copy_to_user( &argp->handle,
-				   &map->offset,
-				   sizeof(map->offset) ) )
-			return -EFAULT;
-	}
+	if (copy_to_user(&argp->handle, &map->offset, sizeof(map->offset)))
+		return -EFAULT;
 	return 0;
 }
 
@@ -240,7 +251,7 @@ int drm_rmmap(struct inode *inode, struc
 		r_list = list_entry(list, drm_map_list_t, head);
 
 		if(r_list->map &&
-		   r_list->map->handle == request.handle &&
+		   r_list->map->offset == (unsigned long) request.handle &&
 		   r_list->map->flags & _DRM_REMOVABLE) break;
 	}
 
@@ -345,8 +356,8 @@ static void drm_cleanup_buf_error(drm_de
  * reallocates the buffer list of the same size order to accommodate the new
  * buffers.
  */
-int drm_addbufs_agp( struct inode *inode, struct file *filp,
-		      unsigned int cmd, unsigned long arg )
+static int drm_addbufs_agp( struct inode *inode, struct file *filp,
+			    unsigned int cmd, unsigned long arg )
 {
 	drm_file_t *priv = filp->private_data;
 	drm_device_t *dev = priv->head->dev;
@@ -510,8 +521,8 @@ int drm_addbufs_agp( struct inode *inode
 }
 #endif /* __OS_HAS_AGP */
 
-int drm_addbufs_pci( struct inode *inode, struct file *filp,
-		      unsigned int cmd, unsigned long arg )
+static int drm_addbufs_pci( struct inode *inode, struct file *filp,
+			    unsigned int cmd, unsigned long arg )
 {
    	drm_file_t *priv = filp->private_data;
 	drm_device_t *dev = priv->head->dev;
@@ -740,8 +751,8 @@ int drm_addbufs_pci( struct inode *inode
 
 }
 
-int drm_addbufs_sg( struct inode *inode, struct file *filp,
-                     unsigned int cmd, unsigned long arg )
+static int drm_addbufs_sg( struct inode *inode, struct file *filp,
+			   unsigned int cmd, unsigned long arg )
 {
 	drm_file_t *priv = filp->private_data;
 	drm_device_t *dev = priv->head->dev;
diff --git a/drivers/char/drm/drm_context.c b/drivers/char/drm/drm_context.c
--- a/drivers/char/drm/drm_context.c
+++ b/drivers/char/drm/drm_context.c
@@ -84,7 +84,7 @@ failed:
  * drm_device::context_sareas to accommodate the new entry while holding the
  * drm_device::struct_sem lock.
  */
-int drm_ctxbitmap_next( drm_device_t *dev )
+static int drm_ctxbitmap_next( drm_device_t *dev )
 {
 	int bit;
 
@@ -225,7 +225,7 @@ int drm_getsareactx(struct inode *inode,
 	map = dev->context_sareas[request.ctx_id];
 	up(&dev->struct_sem);
 
-	request.handle = map->handle;
+	request.handle = (void *) map->offset;
 	if (copy_to_user(argp, &request, sizeof(request)))
 		return -EFAULT;
 	return 0;
@@ -261,8 +261,8 @@ int drm_setsareactx(struct inode *inode,
 	down(&dev->struct_sem);
 	list_for_each(list, &dev->maplist->head) {
 		r_list = list_entry(list, drm_map_list_t, head);
-		if(r_list->map &&
-		   r_list->map->handle == request.handle)
+		if (r_list->map
+		    && r_list->map->offset == (unsigned long) request.handle)
 			goto found;
 	}
 bad:
@@ -326,7 +326,7 @@ int drm_context_switch( drm_device_t *de
  * hardware lock is held, clears the drm_device::context_flag and wakes up
  * drm_device::context_wait.
  */
-int drm_context_switch_complete( drm_device_t *dev, int new )
+static int drm_context_switch_complete( drm_device_t *dev, int new )
 {
         dev->last_context = new;  /* PRE/POST: This is the _only_ writer. */
         dev->last_switch  = jiffies;
diff --git a/drivers/char/drm/drm_drv.c b/drivers/char/drm/drm_drv.c
--- a/drivers/char/drm/drm_drv.c
+++ b/drivers/char/drm/drm_drv.c
@@ -51,8 +51,11 @@
 #include "drmP.h"
 #include "drm_core.h"
 
+static int drm_version(struct inode *inode, struct file *filp,
+		       unsigned int cmd, unsigned long arg);
+
 /** Ioctl table */
-drm_ioctl_desc_t		  drm_ioctls[] = {
+static drm_ioctl_desc_t		  drm_ioctls[] = {
 	[DRM_IOCTL_NR(DRM_IOCTL_VERSION)]       = { drm_version,     0, 0 },
 	[DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE)]    = { drm_getunique,   0, 0 },
 	[DRM_IOCTL_NR(DRM_IOCTL_GET_MAGIC)]     = { drm_getmagic,    0, 0 },
@@ -447,8 +450,8 @@ module_exit( drm_core_exit );
  *
  * Fills in the version information in \p arg.
  */
-int drm_version( struct inode *inode, struct file *filp,
-		  unsigned int cmd, unsigned long arg )
+static int drm_version( struct inode *inode, struct file *filp,
+			unsigned int cmd, unsigned long arg )
 {
 	drm_file_t *priv = filp->private_data;
 	drm_device_t *dev = priv->head->dev;
diff --git a/drivers/char/drm/drm_fops.c b/drivers/char/drm/drm_fops.c
--- a/drivers/char/drm/drm_fops.c
+++ b/drivers/char/drm/drm_fops.c
@@ -37,6 +37,8 @@
 #include "drmP.h"
 #include <linux/poll.h>
 
+static int drm_open_helper(struct inode *inode, struct file *filp, drm_device_t *dev);
+
 static int drm_setup( drm_device_t *dev )
 {
 	int i;
@@ -251,7 +253,7 @@ int drm_release( struct inode *inode, st
 		}
 	}
 	
-	if (drm_core_check_feature(dev, DRIVER_HAVE_DMA))
+	if (drm_core_check_feature(dev, DRIVER_HAVE_DMA) && !dev->driver->release)
 	{
 		dev->driver->reclaim_buffers(dev, filp);
 	}
@@ -259,7 +261,7 @@ int drm_release( struct inode *inode, st
 	drm_fasync( -1, filp, 0 );
 
 	down( &dev->ctxlist_sem );
-	if ( !list_empty( &dev->ctxlist->head ) ) {
+	if ( dev->ctxlist && (!list_empty(&dev->ctxlist->head))) {
 		drm_ctx_list_t *pos, *n;
 
 		list_for_each_entry_safe( pos, n, &dev->ctxlist->head, head ) {
@@ -341,7 +343,7 @@ EXPORT_SYMBOL(drm_release);
  * Creates and initializes a drm_file structure for the file private data in \p
  * filp and add it into the double linked list in \p dev.
  */
-int drm_open_helper(struct inode *inode, struct file *filp, drm_device_t *dev)
+static int drm_open_helper(struct inode *inode, struct file *filp, drm_device_t *dev)
 {
 	int	     minor = iminor(inode);
 	drm_file_t   *priv;
@@ -443,9 +445,3 @@ unsigned int drm_poll(struct file *filp,
 }
 EXPORT_SYMBOL(drm_poll);
 
-
-/** No-op. */
-ssize_t drm_read(struct file *filp, char __user *buf, size_t count, loff_t *off)
-{
-	return 0;
-}
diff --git a/drivers/char/drm/drm_ioc32.c b/drivers/char/drm/drm_ioc32.c
new file mode 100644
--- /dev/null
+++ b/drivers/char/drm/drm_ioc32.c
@@ -0,0 +1,1069 @@
+/**
+ * \file drm_ioc32.c
+ *
+ * 32-bit ioctl compatibility routines for the DRM.
+ *
+ * \author Paul Mackerras <paulus@samba.org>
+ *
+ * Copyright (C) Paul Mackerras 2005.
+ * 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
+ * THE AUTHOR 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.
+ */
+#include <linux/compat.h>
+#include <linux/ioctl32.h>
+
+#include "drmP.h"
+#include "drm_core.h"
+
+#define DRM_IOCTL_VERSION32		DRM_IOWR(0x00, drm_version32_t)
+#define DRM_IOCTL_GET_UNIQUE32		DRM_IOWR(0x01, drm_unique32_t)
+#define DRM_IOCTL_GET_MAP32		DRM_IOWR(0x04, drm_map32_t)
+#define DRM_IOCTL_GET_CLIENT32		DRM_IOWR(0x05, drm_client32_t)
+#define DRM_IOCTL_GET_STATS32		DRM_IOR( 0x06, drm_stats32_t)
+
+#define DRM_IOCTL_SET_UNIQUE32		DRM_IOW( 0x10, drm_unique32_t)
+#define DRM_IOCTL_ADD_MAP32		DRM_IOWR(0x15, drm_map32_t)
+#define DRM_IOCTL_ADD_BUFS32		DRM_IOWR(0x16, drm_buf_desc32_t)
+#define DRM_IOCTL_MARK_BUFS32		DRM_IOW( 0x17, drm_buf_desc32_t)
+#define DRM_IOCTL_INFO_BUFS32		DRM_IOWR(0x18, drm_buf_info32_t)
+#define DRM_IOCTL_MAP_BUFS32		DRM_IOWR(0x19, drm_buf_map32_t)
+#define DRM_IOCTL_FREE_BUFS32		DRM_IOW( 0x1a, drm_buf_free32_t)
+
+#define DRM_IOCTL_RM_MAP32		DRM_IOW( 0x1b, drm_map32_t)
+
+#define DRM_IOCTL_SET_SAREA_CTX32	DRM_IOW( 0x1c, drm_ctx_priv_map32_t)
+#define DRM_IOCTL_GET_SAREA_CTX32	DRM_IOWR(0x1d, drm_ctx_priv_map32_t)
+
+#define DRM_IOCTL_RES_CTX32		DRM_IOWR(0x26, drm_ctx_res32_t)
+#define DRM_IOCTL_DMA32			DRM_IOWR(0x29, drm_dma32_t)
+
+#define DRM_IOCTL_AGP_ENABLE32		DRM_IOW( 0x32, drm_agp_mode32_t)
+#define DRM_IOCTL_AGP_INFO32		DRM_IOR( 0x33, drm_agp_info32_t)
+#define DRM_IOCTL_AGP_ALLOC32		DRM_IOWR(0x34, drm_agp_buffer32_t)
+#define DRM_IOCTL_AGP_FREE32		DRM_IOW( 0x35, drm_agp_buffer32_t)
+#define DRM_IOCTL_AGP_BIND32		DRM_IOW( 0x36, drm_agp_binding32_t)
+#define DRM_IOCTL_AGP_UNBIND32		DRM_IOW( 0x37, drm_agp_binding32_t)
+
+#define DRM_IOCTL_SG_ALLOC32		DRM_IOW( 0x38, drm_scatter_gather32_t)
+#define DRM_IOCTL_SG_FREE32		DRM_IOW( 0x39, drm_scatter_gather32_t)
+
+#define DRM_IOCTL_WAIT_VBLANK32		DRM_IOWR(0x3a, drm_wait_vblank32_t)
+
+typedef struct drm_version_32 {
+	int	version_major;	  /**< Major version */
+	int	version_minor;	  /**< Minor version */
+	int	version_patchlevel;/**< Patch level */
+	u32	name_len;	  /**< Length of name buffer */
+	u32	name;		  /**< Name of driver */
+	u32	date_len;	  /**< Length of date buffer */
+	u32	date;		  /**< User-space buffer to hold date */
+	u32	desc_len;	  /**< Length of desc buffer */
+	u32	desc;		  /**< User-space buffer to hold desc */
+} drm_version32_t;
+
+static int compat_drm_version(struct file *file, unsigned int cmd,
+			      unsigned long arg)
+{
+	drm_version32_t v32;
+	drm_version_t __user *version;
+	int err;
+
+	if (copy_from_user(&v32, (void __user *) arg, sizeof(v32)))
+		return -EFAULT;
+
+	version = compat_alloc_user_space(sizeof(*version));
+	if (!access_ok(VERIFY_WRITE, version, sizeof(*version)))
+		return -EFAULT;
+	if (__put_user(v32.name_len, &version->name_len)
+	    || __put_user((void __user *)(unsigned long)v32.name,
+			  &version->name)
+	    || __put_user(v32.date_len, &version->date_len)
+	    || __put_user((void __user *)(unsigned long)v32.date,
+			  &version->date)
+	    || __put_user(v32.desc_len, &version->desc_len)
+	    || __put_user((void __user *)(unsigned long)v32.desc,
+			  &version->desc))
+		return -EFAULT;
+
+	err = drm_ioctl(file->f_dentry->d_inode, file,
+			DRM_IOCTL_VERSION, (unsigned long) version);
+	if (err)
+		return err;
+
+	if (__get_user(v32.version_major, &version->version_major)
+	    || __get_user(v32.version_minor, &version->version_minor)
+	    || __get_user(v32.version_patchlevel, &version->version_patchlevel)
+	    || __get_user(v32.name_len, &version->name_len)
+	    || __get_user(v32.date_len, &version->date_len)
+	    || __get_user(v32.desc_len, &version->desc_len))
+		return -EFAULT;
+
+	if (copy_to_user((void __user *) arg, &v32, sizeof(v32)))
+		return -EFAULT;
+	return 0;
+}
+
+typedef struct drm_unique32 {
+	u32 unique_len;	/**< Length of unique */
+	u32 unique;	/**< Unique name for driver instantiation */
+} drm_unique32_t;
+
+static int compat_drm_getunique(struct file *file, unsigned int cmd,
+				unsigned long arg)
+{
+	drm_unique32_t uq32;
+	drm_unique_t __user *u;
+	int err;
+
+	if (copy_from_user(&uq32, (void __user *) arg, sizeof(uq32)))
+		return -EFAULT;
+
+	u = compat_alloc_user_space(sizeof(*u));
+	if (!access_ok(VERIFY_WRITE, u, sizeof(*u)))
+		return -EFAULT;
+	if (__put_user(uq32.unique_len, &u->unique_len)
+	    || __put_user((void __user *)(unsigned long) uq32.unique,
+			  &u->unique))
+		return -EFAULT;
+
+	err = drm_ioctl(file->f_dentry->d_inode, file,
+			DRM_IOCTL_GET_UNIQUE, (unsigned long) u);
+	if (err)
+		return err;
+
+	if (__get_user(uq32.unique_len, &u->unique_len))
+		return -EFAULT;
+	if (copy_to_user((void __user *) arg, &uq32, sizeof(uq32)))
+		return -EFAULT;
+	return 0;
+}
+
+static int compat_drm_setunique(struct file *file, unsigned int cmd,
+				unsigned long arg)
+{
+	drm_unique32_t uq32;
+	drm_unique_t __user *u;
+
+	if (copy_from_user(&uq32, (void __user *) arg, sizeof(uq32)))
+		return -EFAULT;
+
+	u = compat_alloc_user_space(sizeof(*u));
+	if (!access_ok(VERIFY_WRITE, u, sizeof(*u)))
+		return -EFAULT;
+	if (__put_user(uq32.unique_len, &u->unique_len)
+	    || __put_user((void __user *)(unsigned long) uq32.unique,
+			  &u->unique))
+		return -EFAULT;
+
+	return drm_ioctl(file->f_dentry->d_inode, file,
+			 DRM_IOCTL_SET_UNIQUE, (unsigned long) u);
+}
+
+typedef struct drm_map32 {
+	u32	offset;	 	/**< Requested physical address (0 for SAREA)*/
+	u32	size;	 	/**< Requested physical size (bytes) */
+	drm_map_type_t	type;	/**< Type of memory to map */
+	drm_map_flags_t flags;	/**< Flags */
+	u32	handle;		/**< User-space: "Handle" to pass to mmap() */
+	int	mtrr;		/**< MTRR slot used */
+} drm_map32_t;
+
+static int compat_drm_getmap(struct file *file, unsigned int cmd,
+			     unsigned long arg)
+{
+	drm_map32_t __user *argp = (void __user *)arg;
+	drm_map32_t m32;
+	drm_map_t __user *map;
+	int idx, err;
+	void *handle;
+
+	if (get_user(idx, &argp->offset))
+		return -EFAULT;
+
+	map = compat_alloc_user_space(sizeof(*map));
+	if (!access_ok(VERIFY_WRITE, map, sizeof(*map)))
+		return -EFAULT;
+	if (__put_user(idx, &map->offset))
+		return -EFAULT;
+
+	err = drm_ioctl(file->f_dentry->d_inode, file,
+			DRM_IOCTL_GET_MAP, (unsigned long) map);
+	if (err)
+		return err;
+
+	if (__get_user(m32.offset, &map->offset)
+	    || __get_user(m32.size, &map->size)
+	    || __get_user(m32.type, &map->type)
+	    || __get_user(m32.flags, &map->flags)
+	    || __get_user(handle, &map->handle)
+	    || __get_user(m32.mtrr, &map->mtrr))
+		return -EFAULT;
+
+	m32.handle = (unsigned long) handle;
+	if (copy_to_user(argp, &m32, sizeof(m32)))
+		return -EFAULT;
+	return 0;
+
+}
+
+static int compat_drm_addmap(struct file *file, unsigned int cmd,
+			     unsigned long arg)
+{
+	drm_map32_t __user *argp = (void __user *)arg;
+	drm_map32_t m32;
+	drm_map_t __user *map;
+	int err;
+	void *handle;
+
+	if (copy_from_user(&m32, argp, sizeof(m32)))
+		return -EFAULT;
+
+	map = compat_alloc_user_space(sizeof(*map));
+	if (!access_ok(VERIFY_WRITE, map, sizeof(*map)))
+		return -EFAULT;
+	if (__put_user(m32.offset, &map->offset)
+	    || __put_user(m32.size, &map->size)
+	    || __put_user(m32.type, &map->type)
+	    || __put_user(m32.flags, &map->flags))
+		return -EFAULT;
+
+	err = drm_ioctl(file->f_dentry->d_inode, file,
+			DRM_IOCTL_ADD_MAP, (unsigned long) map);
+	if (err)
+		return err;
+
+	if (__get_user(m32.offset, &map->offset)
+	    || __get_user(m32.mtrr, &map->mtrr)
+	    || __get_user(handle, &map->handle))
+		return -EFAULT;
+
+	m32.handle = (unsigned long) handle;
+	if (m32.handle != (unsigned long) handle && printk_ratelimit())
+		printk(KERN_ERR "compat_drm_addmap truncated handle"
+		       " %p for type %d offset %x\n",
+		       handle, m32.type, m32.offset);
+
+	if (copy_to_user(argp, &m32, sizeof(m32)))
+		return -EFAULT;
+
+	return 0;
+}
+
+static int compat_drm_rmmap(struct file *file, unsigned int cmd,
+			    unsigned long arg)
+{
+	drm_map32_t __user *argp = (void __user *)arg;
+	drm_map_t __user *map;
+	u32 handle;
+
+	if (get_user(handle, &argp->handle))
+		return -EFAULT;
+
+	map = compat_alloc_user_space(sizeof(*map));
+	if (!access_ok(VERIFY_WRITE, map, sizeof(*map)))
+		return -EFAULT;
+	if (__put_user((void *)(unsigned long) handle, &map->handle))
+		return -EFAULT;
+
+	return drm_ioctl(file->f_dentry->d_inode, file,
+			 DRM_IOCTL_RM_MAP, (unsigned long) map);
+}
+
+typedef struct drm_client32 {
+	int	idx;	/**< Which client desired? */
+	int	auth;	/**< Is client authenticated? */
+	u32	pid;	/**< Process ID */
+	u32	uid;	/**< User ID */
+	u32	magic;	/**< Magic */
+	u32	iocs;	/**< Ioctl count */
+} drm_client32_t;
+
+static int compat_drm_getclient(struct file *file, unsigned int cmd,
+				unsigned long arg)
+{
+	drm_client32_t c32;
+	drm_client32_t __user *argp = (void __user *)arg;
+	drm_client_t __user *client;
+	int idx, err;
+
+	if (get_user(idx, &argp->idx))
+		return -EFAULT;
+
+	client = compat_alloc_user_space(sizeof(*client));
+	if (!access_ok(VERIFY_WRITE, client, sizeof(*client)))
+		return -EFAULT;
+	if (__put_user(idx, &client->idx))
+		return -EFAULT;
+
+	err = drm_ioctl(file->f_dentry->d_inode, file,
+			DRM_IOCTL_GET_CLIENT, (unsigned long) client);
+	if (err)
+		return err;
+
+	if (__get_user(c32.auth, &client->auth)
+	    || __get_user(c32.pid, &client->pid)
+	    || __get_user(c32.uid, &client->uid)
+	    || __get_user(c32.magic, &client->magic)
+	    || __get_user(c32.iocs, &client->iocs))
+		return -EFAULT;
+
+	if (copy_to_user(argp, &c32, sizeof(c32)))
+		return -EFAULT;
+	return 0;
+}
+
+typedef struct drm_stats32 {
+	u32 count;
+	struct {
+		u32 value;
+		drm_stat_type_t type;
+	} data[15];
+} drm_stats32_t;
+
+static int compat_drm_getstats(struct file *file, unsigned int cmd,
+			       unsigned long arg)
+{
+	drm_stats32_t s32;
+	drm_stats32_t __user *argp = (void __user *)arg;
+	drm_stats_t __user *stats;
+	int i, err;
+
+	stats = compat_alloc_user_space(sizeof(*stats));
+	if (!access_ok(VERIFY_WRITE, stats, sizeof(*stats)))
+		return -EFAULT;
+
+	err = drm_ioctl(file->f_dentry->d_inode, file,
+			DRM_IOCTL_GET_STATS, (unsigned long) stats);
+	if (err)
+		return err;
+
+	if (__get_user(s32.count, &stats->count))
+		return -EFAULT;
+	for (i = 0; i < 15; ++i)
+		if (__get_user(s32.data[i].value, &stats->data[i].value)
+		    || __get_user(s32.data[i].type, &stats->data[i].type))
+			return -EFAULT;
+
+	if (copy_to_user(argp, &s32, sizeof(s32)))
+		return -EFAULT;
+	return 0;
+}
+
+typedef struct drm_buf_desc32 {
+	int	      count;	 /**< Number of buffers of this size */
+	int	      size;	 /**< Size in bytes */
+	int	      low_mark;	 /**< Low water mark */
+	int	      high_mark; /**< High water mark */
+	int	      flags;
+	u32	      agp_start; /**< Start address in the AGP aperture */
+} drm_buf_desc32_t;
+
+static int compat_drm_addbufs(struct file *file, unsigned int cmd,
+			      unsigned long arg)
+{
+	drm_buf_desc32_t __user *argp = (void __user *)arg;
+	drm_buf_desc_t __user *buf;
+	int err;
+	unsigned long agp_start;
+
+	buf = compat_alloc_user_space(sizeof(*buf));
+	if (!access_ok(VERIFY_WRITE, buf, sizeof(*buf))
+	    || !access_ok(VERIFY_WRITE, argp, sizeof(*argp)))
+		return -EFAULT;
+
+	if (__copy_in_user(buf, argp, offsetof(drm_buf_desc32_t, agp_start))
+	    || __get_user(agp_start, &argp->agp_start)
+	    || __put_user(agp_start, &buf->agp_start))
+		return -EFAULT;
+
+	err = drm_ioctl(file->f_dentry->d_inode, file,
+			DRM_IOCTL_ADD_BUFS, (unsigned long) buf);
+	if (err)
+		return err;
+
+	if (__copy_in_user(argp, buf, offsetof(drm_buf_desc32_t, agp_start))
+	    || __get_user(agp_start, &buf->agp_start)
+	    || __put_user(agp_start, &argp->agp_start))
+		return -EFAULT;
+
+	return 0;
+}
+
+static int compat_drm_markbufs(struct file *file, unsigned int cmd,
+			       unsigned long arg)
+{
+	drm_buf_desc32_t b32;
+	drm_buf_desc32_t __user *argp = (void __user *)arg;
+	drm_buf_desc_t __user *buf;
+
+	if (copy_from_user(&b32, argp, sizeof(b32)))
+		return -EFAULT;
+
+	buf = compat_alloc_user_space(sizeof(*buf));
+	if (!access_ok(VERIFY_WRITE, buf, sizeof(*buf)))
+		return -EFAULT;
+
+	if (__put_user(b32.size, &buf->size)
+	    || __put_user(b32.low_mark, &buf->low_mark)
+	    || __put_user(b32.high_mark, &buf->high_mark))
+		return -EFAULT;
+
+	return drm_ioctl(file->f_dentry->d_inode, file,
+			 DRM_IOCTL_MARK_BUFS, (unsigned long) buf);
+}
+
+typedef struct drm_buf_info32 {
+	int	       count;	/**< Entries in list */
+	u32	       list;
+} drm_buf_info32_t;
+
+static int compat_drm_infobufs(struct file *file, unsigned int cmd,
+			       unsigned long arg)
+{
+	drm_buf_info32_t req32;
+	drm_buf_info32_t __user *argp = (void __user *)arg;
+	drm_buf_desc32_t __user *to;
+	drm_buf_info_t __user *request;
+	drm_buf_desc_t __user *list;
+	size_t nbytes;
+	int i, err;
+	int count, actual;
+
+	if (copy_from_user(&req32, argp, sizeof(req32)))
+		return -EFAULT;
+
+	count = req32.count;
+	to = (drm_buf_desc32_t __user *)(unsigned long) req32.list;
+	if (count < 0)
+		count = 0;
+	if (count > 0
+	    && !access_ok(VERIFY_WRITE, to, count * sizeof(drm_buf_desc32_t)))
+		return -EFAULT;
+
+	nbytes = sizeof(*request) + count * sizeof(drm_buf_desc_t);
+	request = compat_alloc_user_space(nbytes);
+	if (!access_ok(VERIFY_WRITE, request, nbytes))
+		return -EFAULT;
+	list = (drm_buf_desc_t *) (request + 1);
+
+	if (__put_user(count, &request->count)
+	    || __put_user(list, &request->list))
+		return -EFAULT;
+
+	err = drm_ioctl(file->f_dentry->d_inode, file,
+			DRM_IOCTL_INFO_BUFS, (unsigned long) request);
+	if (err)
+		return err;
+
+	if (__get_user(actual, &request->count))
+		return -EFAULT;
+	if (count >= actual)
+		for (i = 0; i < actual; ++i)
+			if (__copy_in_user(&to[i], &list[i],
+					   offsetof(drm_buf_desc_t, flags)))
+				return -EFAULT;
+
+	if (__put_user(actual, &argp->count))
+		return -EFAULT;
+
+	return 0;
+}
+
+typedef struct drm_buf_pub32 {
+	int	idx;		/**< Index into the master buffer list */
+	int	total;		/**< Buffer size */
+	int	used;		/**< Amount of buffer in use (for DMA) */
+	u32	address;	/**< Address of buffer */
+} drm_buf_pub32_t;
+
+typedef struct drm_buf_map32 {
+	int	count;		/**< Length of the buffer list */
+	u32	virtual;	/**< Mmap'd area in user-virtual */
+	u32	list;		/**< Buffer information */
+} drm_buf_map32_t;
+
+static int compat_drm_mapbufs(struct file *file, unsigned int cmd,
+			      unsigned long arg)
+{
+	drm_buf_map32_t __user *argp = (void __user *)arg;
+	drm_buf_map32_t req32;
+	drm_buf_pub32_t __user *list32;
+	drm_buf_map_t __user *request;
+	drm_buf_pub_t __user *list;
+	int i, err;
+	int count, actual;
+	size_t nbytes;
+	void __user *addr;
+
+	if (copy_from_user(&req32, argp, sizeof(req32)))
+		return -EFAULT;
+	count = req32.count;
+	list32 = (void __user *)(unsigned long)req32.list;
+
+	if (count < 0)
+		return -EINVAL;
+	nbytes = sizeof(*request) + count * sizeof(drm_buf_pub_t);
+	request = compat_alloc_user_space(nbytes);
+	if (!access_ok(VERIFY_WRITE, request, nbytes))
+		return -EFAULT;
+	list = (drm_buf_pub_t *) (request + 1);
+
+	if (__put_user(count, &request->count)
+	    || __put_user(list, &request->list))
+		return -EFAULT;
+
+	err = drm_ioctl(file->f_dentry->d_inode, file,
+			DRM_IOCTL_MAP_BUFS, (unsigned long) request);
+	if (err)
+		return err;
+
+	if (__get_user(actual, &request->count))
+		return -EFAULT;
+	if (count >= actual)
+		for (i = 0; i < actual; ++i)
+			if (__copy_in_user(&list32[i], &list[i],
+					   offsetof(drm_buf_pub_t, address))
+			    || __get_user(addr, &list[i].address)
+			    || __put_user((unsigned long) addr,
+					  &list32[i].address))
+				return -EFAULT;
+
+	if (__put_user(actual, &argp->count)
+	    || __get_user(addr, &request->virtual)
+	    || __put_user((unsigned long) addr, &argp->virtual))
+		return -EFAULT;
+
+	return 0;
+}
+
+typedef struct drm_buf_free32 {
+	int	count;
+	u32	list;
+} drm_buf_free32_t;
+
+static int compat_drm_freebufs(struct file *file, unsigned int cmd,
+			       unsigned long arg)
+{
+	drm_buf_free32_t req32;
+	drm_buf_free_t __user *request;
+	drm_buf_free32_t __user *argp = (void __user *)arg;
+
+	if (copy_from_user(&req32, argp, sizeof(req32)))
+		return -EFAULT;
+
+	request = compat_alloc_user_space(sizeof(*request));
+	if (!access_ok(VERIFY_WRITE, request, sizeof(*request)))
+		return -EFAULT;
+	if (__put_user(req32.count, &request->count)
+	    || __put_user((int __user *)(unsigned long) req32.list,
+			  &request->list))
+		return -EFAULT;
+
+	return drm_ioctl(file->f_dentry->d_inode, file,
+			 DRM_IOCTL_FREE_BUFS, (unsigned long) request);
+}
+
+typedef struct drm_ctx_priv_map32 {
+	unsigned int	ctx_id;  /**< Context requesting private mapping */
+	u32		handle; /**< Handle of map */
+} drm_ctx_priv_map32_t;
+
+static int compat_drm_setsareactx(struct file *file, unsigned int cmd,
+				  unsigned long arg)
+{
+	drm_ctx_priv_map32_t req32;
+	drm_ctx_priv_map_t __user *request;
+	drm_ctx_priv_map32_t __user *argp = (void __user *)arg;
+
+	if (copy_from_user(&req32, argp, sizeof(req32)))
+		return -EFAULT;
+
+	request = compat_alloc_user_space(sizeof(*request));
+	if (!access_ok(VERIFY_WRITE, request, sizeof(*request)))
+		return -EFAULT;
+	if (__put_user(req32.ctx_id, &request->ctx_id)
+	    || __put_user((void *)(unsigned long) req32.handle,
+			  &request->handle))
+		return -EFAULT;
+
+	return drm_ioctl(file->f_dentry->d_inode, file,
+			 DRM_IOCTL_SET_SAREA_CTX, (unsigned long) request);
+}
+
+static int compat_drm_getsareactx(struct file *file, unsigned int cmd,
+				  unsigned long arg)
+{
+	drm_ctx_priv_map_t __user *request;
+	drm_ctx_priv_map32_t __user *argp = (void __user *)arg;
+	int err;
+	unsigned int ctx_id;
+	void *handle;
+
+	if (!access_ok(VERIFY_WRITE, argp, sizeof(*argp))
+	    || __get_user(ctx_id, &argp->ctx_id))
+		return -EFAULT;
+
+	request = compat_alloc_user_space(sizeof(*request));
+	if (!access_ok(VERIFY_WRITE, request, sizeof(*request)))
+		return -EFAULT;
+	if (__put_user(ctx_id, &request->ctx_id))
+		return -EFAULT;
+
+	err = drm_ioctl(file->f_dentry->d_inode, file,
+			DRM_IOCTL_GET_SAREA_CTX, (unsigned long) request);
+	if (err)
+		return err;
+
+	if (__get_user(handle, &request->handle)
+	    || __put_user((unsigned long) handle, &argp->handle))
+		return -EFAULT;
+
+	return 0;
+}
+
+typedef struct drm_ctx_res32 {
+	int	count;
+	u32	contexts;
+} drm_ctx_res32_t;
+
+static int compat_drm_resctx(struct file *file, unsigned int cmd,
+			     unsigned long arg)
+{
+	drm_ctx_res32_t __user *argp = (void __user *)arg;
+	drm_ctx_res32_t res32;
+	drm_ctx_res_t __user *res;
+	int err;
+
+	if (copy_from_user(&res32, argp, sizeof(res32)))
+		return -EFAULT;
+
+	res = compat_alloc_user_space(sizeof(*res));
+	if (!access_ok(VERIFY_WRITE, res, sizeof(*res)))
+		return -EFAULT;
+	if (__put_user(res32.count, &res->count)
+	    || __put_user((drm_ctx_t __user *)(unsigned long) res32.contexts,
+			  &res->contexts))
+		return -EFAULT;
+
+	err = drm_ioctl(file->f_dentry->d_inode, file,
+			DRM_IOCTL_RES_CTX, (unsigned long) res);
+	if (err)
+		return err;
+
+	if (__get_user(res32.count, &res->count)
+	    || __put_user(res32.count, &argp->count))
+		return -EFAULT;
+
+	return 0;
+}
+
+typedef struct drm_dma32 {
+	int	context;	  /**< Context handle */
+	int	send_count;	  /**< Number of buffers to send */
+	u32	send_indices;	  /**< List of handles to buffers */
+	u32	send_sizes;	  /**< Lengths of data to send */
+	drm_dma_flags_t flags;		  /**< Flags */
+	int	request_count;	  /**< Number of buffers requested */
+	int	request_size;	  /**< Desired size for buffers */
+	u32	request_indices;  /**< Buffer information */
+	u32	request_sizes;
+	int	granted_count;	  /**< Number of buffers granted */
+} drm_dma32_t;
+
+static int compat_drm_dma(struct file *file, unsigned int cmd,
+			  unsigned long arg)
+{
+	drm_dma32_t d32;
+	drm_dma32_t __user *argp = (void __user *) arg;
+	drm_dma_t __user *d;
+	int err;
+
+	if (copy_from_user(&d32, argp, sizeof(d32)))
+		return -EFAULT;
+
+	d = compat_alloc_user_space(sizeof(*d));
+	if (!access_ok(VERIFY_WRITE, d, sizeof(*d)))
+		return -EFAULT;
+
+	if (__put_user(d32.context, &d->context)
+	    || __put_user(d32.send_count, &d->send_count)
+	    || __put_user((int __user *)(unsigned long) d32.send_indices,
+			  &d->send_indices)
+	    || __put_user((int __user *)(unsigned long) d32.send_sizes,
+			  &d->send_sizes)
+	    || __put_user(d32.flags, &d->flags)
+	    || __put_user(d32.request_count, &d->request_count)
+	    || __put_user((int __user *)(unsigned long) d32.request_indices,
+			  &d->request_indices)
+	    || __put_user((int __user *)(unsigned long) d32.request_sizes,
+			  &d->request_sizes))
+		return -EFAULT;
+
+	err = drm_ioctl(file->f_dentry->d_inode, file,
+			DRM_IOCTL_DMA, (unsigned long) d);
+	if (err)
+		return err;
+
+	if (__get_user(d32.request_size, &d->request_size)
+	    || __get_user(d32.granted_count, &d->granted_count)
+	    || __put_user(d32.request_size, &argp->request_size)
+	    || __put_user(d32.granted_count, &argp->granted_count))
+		return -EFAULT;
+
+	return 0;
+}
+
+#if __OS_HAS_AGP
+typedef struct drm_agp_mode32 {
+	u32 mode;	/**< AGP mode */
+} drm_agp_mode32_t;
+
+static int compat_drm_agp_enable(struct file *file, unsigned int cmd,
+				 unsigned long arg)
+{
+	drm_agp_mode32_t __user *argp = (void __user *)arg;
+	drm_agp_mode32_t m32;
+	drm_agp_mode_t __user *mode;
+
+	if (get_user(m32.mode, &argp->mode))
+		return -EFAULT;
+
+	mode = compat_alloc_user_space(sizeof(*mode));
+	if (put_user(m32.mode, &mode->mode))
+		return -EFAULT;
+
+	return drm_ioctl(file->f_dentry->d_inode, file,
+			 DRM_IOCTL_AGP_ENABLE, (unsigned long) mode);
+}
+
+typedef struct drm_agp_info32 {
+	int       agp_version_major;
+	int       agp_version_minor;
+	u32	  mode;
+	u32	  aperture_base;  /* physical address */
+	u32	  aperture_size;  /* bytes */
+	u32	  memory_allowed; /* bytes */
+	u32	  memory_used;
+
+				/* PCI information */
+	unsigned short id_vendor;
+	unsigned short id_device;
+} drm_agp_info32_t;
+
+static int compat_drm_agp_info(struct file *file, unsigned int cmd,
+			       unsigned long arg)
+{
+	drm_agp_info32_t __user *argp = (void __user *)arg;
+	drm_agp_info32_t i32;
+	drm_agp_info_t __user *info;
+	int err;
+
+	info = compat_alloc_user_space(sizeof(*info));
+	if (!access_ok(VERIFY_WRITE, info, sizeof(*info)))
+		return -EFAULT;
+
+	err = drm_ioctl(file->f_dentry->d_inode, file,
+			DRM_IOCTL_AGP_INFO, (unsigned long) info);
+	if (err)
+		return err;
+
+	if (__get_user(i32.agp_version_major, &info->agp_version_major)
+	    || __get_user(i32.agp_version_minor, &info->agp_version_minor)
+	    || __get_user(i32.mode, &info->mode)
+	    || __get_user(i32.aperture_base, &info->aperture_base)
+	    || __get_user(i32.aperture_size, &info->aperture_size)
+	    || __get_user(i32.memory_allowed, &info->memory_allowed)
+	    || __get_user(i32.memory_used, &info->memory_used)
+	    || __get_user(i32.id_vendor, &info->id_vendor)
+	    || __get_user(i32.id_device, &info->id_device))
+		return -EFAULT;
+
+	if (copy_to_user(argp, &i32, sizeof(i32)))
+		return -EFAULT;
+
+	return 0;
+}
+
+typedef struct drm_agp_buffer32 {
+	u32 size;	/**< In bytes -- will round to page boundary */
+	u32 handle;	/**< Used for binding / unbinding */
+	u32 type;	/**< Type of memory to allocate */
+        u32 physical;	/**< Physical used by i810 */
+} drm_agp_buffer32_t;
+
+static int compat_drm_agp_alloc(struct file *file, unsigned int cmd,
+				unsigned long arg)
+{
+	drm_agp_buffer32_t __user *argp = (void __user *)arg;
+	drm_agp_buffer32_t req32;
+	drm_agp_buffer_t __user *request;
+	int err;
+
+	if (copy_from_user(&req32, argp, sizeof(req32)))
+		return -EFAULT;
+
+	request = compat_alloc_user_space(sizeof(*request));
+	if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
+	    || __put_user(req32.size, &request->size)
+	    || __put_user(req32.type, &request->type))
+		return -EFAULT;
+
+	err = drm_ioctl(file->f_dentry->d_inode, file,
+			DRM_IOCTL_AGP_ALLOC, (unsigned long) request);
+	if (err)
+		return err;
+
+	if (__get_user(req32.handle, &request->handle)
+	    || __get_user(req32.physical, &request->physical)
+	    || copy_to_user(argp, &req32, sizeof(req32))) {
+		drm_ioctl(file->f_dentry->d_inode, file,
+			  DRM_IOCTL_AGP_FREE, (unsigned long) request);
+		return -EFAULT;
+	}
+
+	return 0;
+}
+
+static int compat_drm_agp_free(struct file *file, unsigned int cmd,
+			       unsigned long arg)
+{
+	drm_agp_buffer32_t __user *argp = (void __user *)arg;
+	drm_agp_buffer_t __user *request;
+	u32 handle;
+
+	request = compat_alloc_user_space(sizeof(*request));
+	if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
+	    || get_user(handle, &argp->handle)
+	    || __put_user(handle, &request->handle))
+		return -EFAULT;
+
+	return drm_ioctl(file->f_dentry->d_inode, file,
+			 DRM_IOCTL_AGP_FREE, (unsigned long) request);
+}
+
+typedef struct drm_agp_binding32 {
+	u32 handle;	/**< From drm_agp_buffer */
+	u32 offset;	/**< In bytes -- will round to page boundary */
+} drm_agp_binding32_t;
+
+static int compat_drm_agp_bind(struct file *file, unsigned int cmd,
+			       unsigned long arg)
+{
+	drm_agp_binding32_t __user *argp = (void __user *)arg;
+	drm_agp_binding32_t req32;
+	drm_agp_binding_t __user *request;
+
+	if (copy_from_user(&req32, argp, sizeof(req32)))
+		return -EFAULT;
+
+	request = compat_alloc_user_space(sizeof(*request));
+	if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
+	    || __put_user(req32.handle, &request->handle)
+	    || __put_user(req32.offset, &request->offset))
+		return -EFAULT;
+
+	return drm_ioctl(file->f_dentry->d_inode, file,
+			 DRM_IOCTL_AGP_BIND, (unsigned long) request);
+}
+
+static int compat_drm_agp_unbind(struct file *file, unsigned int cmd,
+				 unsigned long arg)
+{
+	drm_agp_binding32_t __user *argp = (void __user *)arg;
+	drm_agp_binding_t __user *request;
+	u32 handle;
+
+	request = compat_alloc_user_space(sizeof(*request));
+	if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
+	    || get_user(handle, &argp->handle)
+	    || __put_user(handle, &request->handle))
+		return -EFAULT;
+
+	return drm_ioctl(file->f_dentry->d_inode, file,
+			 DRM_IOCTL_AGP_UNBIND, (unsigned long) request);
+}
+#endif /* __OS_HAS_AGP */
+
+typedef struct drm_scatter_gather32 {
+	u32 size;	/**< In bytes -- will round to page boundary */
+	u32 handle;	/**< Used for mapping / unmapping */
+} drm_scatter_gather32_t;
+
+static int compat_drm_sg_alloc(struct file *file, unsigned int cmd,
+			       unsigned long arg)
+{
+	drm_scatter_gather32_t __user *argp = (void __user *)arg;
+	drm_scatter_gather_t __user *request;
+	int err;
+	unsigned long x;
+
+	request = compat_alloc_user_space(sizeof(*request));
+	if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
+	    || !access_ok(VERIFY_WRITE, argp, sizeof(*argp))
+	    || __get_user(x, &argp->size)
+	    || __put_user(x, &request->size))
+		return -EFAULT;
+
+	err = drm_ioctl(file->f_dentry->d_inode, file,
+			DRM_IOCTL_SG_ALLOC, (unsigned long) request);
+	if (err)
+		return err;
+
+	/* XXX not sure about the handle conversion here... */
+	if (__get_user(x, &request->handle)
+	    || __put_user(x >> PAGE_SHIFT, &argp->handle))
+		return -EFAULT;
+
+	return 0;
+}
+
+static int compat_drm_sg_free(struct file *file, unsigned int cmd,
+			      unsigned long arg)
+{
+	drm_scatter_gather32_t __user *argp = (void __user *)arg;
+	drm_scatter_gather_t __user *request;
+	unsigned long x;
+
+	request = compat_alloc_user_space(sizeof(*request));
+	if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
+	    || !access_ok(VERIFY_WRITE, argp, sizeof(*argp))
+	    || __get_user(x, &argp->handle)
+	    || __put_user(x << PAGE_SHIFT, &request->handle))
+		return -EFAULT;
+
+	return drm_ioctl(file->f_dentry->d_inode, file,
+			 DRM_IOCTL_SG_FREE, (unsigned long) request);
+}
+
+struct drm_wait_vblank_request32 {
+	drm_vblank_seq_type_t type;
+	unsigned int sequence;
+	u32 signal;
+};
+
+struct drm_wait_vblank_reply32 {
+	drm_vblank_seq_type_t type;
+	unsigned int sequence;
+	s32 tval_sec;
+	s32 tval_usec;
+};
+
+typedef union drm_wait_vblank32 {
+	struct drm_wait_vblank_request32 request;
+	struct drm_wait_vblank_reply32 reply;
+} drm_wait_vblank32_t;
+
+static int compat_drm_wait_vblank(struct file *file, unsigned int cmd,
+				  unsigned long arg)
+{
+	drm_wait_vblank32_t __user *argp = (void __user *)arg;
+	drm_wait_vblank32_t req32;
+	drm_wait_vblank_t __user *request;
+	int err;
+
+	if (copy_from_user(&req32, argp, sizeof(req32)))
+		return -EFAULT;
+
+	request = compat_alloc_user_space(sizeof(*request));
+	if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
+	    || __put_user(req32.request.type, &request->request.type)
+	    || __put_user(req32.request.sequence, &request->request.sequence)
+	    || __put_user(req32.request.signal, &request->request.signal))
+		return -EFAULT;
+
+	err = drm_ioctl(file->f_dentry->d_inode, file,
+			DRM_IOCTL_WAIT_VBLANK, (unsigned long) request);
+	if (err)
+		return err;
+
+	if (__get_user(req32.reply.type, &request->reply.type)
+	    || __get_user(req32.reply.sequence, &request->reply.sequence)
+	    || __get_user(req32.reply.tval_sec, &request->reply.tval_sec)
+	    || __get_user(req32.reply.tval_usec, &request->reply.tval_usec))
+		return -EFAULT;
+
+	if (copy_to_user(argp, &req32, sizeof(req32)))
+		return -EFAULT;
+
+	return 0;
+}
+
+drm_ioctl_compat_t *drm_compat_ioctls[] = {
+	[DRM_IOCTL_NR(DRM_IOCTL_VERSION32)] = compat_drm_version,
+	[DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE32)] = compat_drm_getunique,
+	[DRM_IOCTL_NR(DRM_IOCTL_GET_MAP32)] = compat_drm_getmap,
+	[DRM_IOCTL_NR(DRM_IOCTL_GET_CLIENT32)] = compat_drm_getclient,
+	[DRM_IOCTL_NR(DRM_IOCTL_GET_STATS32)] = compat_drm_getstats,
+	[DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE32)] = compat_drm_setunique,
+	[DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP32)] = compat_drm_addmap,
+	[DRM_IOCTL_NR(DRM_IOCTL_ADD_BUFS32)] = compat_drm_addbufs,
+	[DRM_IOCTL_NR(DRM_IOCTL_MARK_BUFS32)] = compat_drm_markbufs,
+	[DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS32)] = compat_drm_infobufs,
+	[DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS32)] = compat_drm_mapbufs,
+	[DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS32)] = compat_drm_freebufs,
+	[DRM_IOCTL_NR(DRM_IOCTL_RM_MAP32)] = compat_drm_rmmap,
+	[DRM_IOCTL_NR(DRM_IOCTL_SET_SAREA_CTX32)] = compat_drm_setsareactx,
+	[DRM_IOCTL_NR(DRM_IOCTL_GET_SAREA_CTX32)] = compat_drm_getsareactx,
+	[DRM_IOCTL_NR(DRM_IOCTL_RES_CTX32)] = compat_drm_resctx,
+	[DRM_IOCTL_NR(DRM_IOCTL_DMA32)] = compat_drm_dma,
+#if __OS_HAS_AGP
+	[DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE32)] = compat_drm_agp_enable,
+	[DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO32)] = compat_drm_agp_info,
+	[DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC32)] = compat_drm_agp_alloc,
+	[DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE32)] = compat_drm_agp_free,
+	[DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND32)] = compat_drm_agp_bind,
+	[DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND32)] = compat_drm_agp_unbind,
+#endif
+	[DRM_IOCTL_NR(DRM_IOCTL_SG_ALLOC32)] = compat_drm_sg_alloc,
+	[DRM_IOCTL_NR(DRM_IOCTL_SG_FREE32)] = compat_drm_sg_free,
+	[DRM_IOCTL_NR(DRM_IOCTL_WAIT_VBLANK32)] = compat_drm_wait_vblank,
+};
+
+/**
+ * Called whenever a 32-bit process running under a 64-bit kernel
+ * performs an ioctl on /dev/drm.
+ *
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg user argument.
+ * \return zero on success or negative number on failure.
+ */
+long drm_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+{
+	unsigned int nr = DRM_IOCTL_NR(cmd);
+	drm_ioctl_compat_t *fn;
+	int ret;
+
+	if (nr >= DRM_ARRAY_SIZE(drm_compat_ioctls))
+		return -ENOTTY;
+
+	fn = drm_compat_ioctls[nr];
+
+	lock_kernel();		/* XXX for now */
+	if (fn != NULL)
+		ret = (*fn)(filp, cmd, arg);
+	else
+		ret = drm_ioctl(filp->f_dentry->d_inode, filp, cmd, arg);
+	unlock_kernel();
+
+	return ret;
+}
+EXPORT_SYMBOL(drm_compat_ioctl);
diff --git a/drivers/char/drm/drm_irq.c b/drivers/char/drm/drm_irq.c
--- a/drivers/char/drm/drm_irq.c
+++ b/drivers/char/drm/drm_irq.c
@@ -89,7 +89,7 @@ int drm_irq_by_busid(struct inode *inode
  * \c drm_driver_irq_preinstall() and \c drm_driver_irq_postinstall() functions
  * before and after the installation.
  */
-int drm_irq_install( drm_device_t *dev )
+static int drm_irq_install( drm_device_t *dev )
 {
 	int ret;
 	unsigned long sh_flags=0;
diff --git a/drivers/char/drm/drm_lock.c b/drivers/char/drm/drm_lock.c
--- a/drivers/char/drm/drm_lock.c
+++ b/drivers/char/drm/drm_lock.c
@@ -35,6 +35,11 @@
 
 #include "drmP.h"
 
+static int drm_lock_transfer(drm_device_t *dev,
+			     __volatile__ unsigned int *lock,
+			     unsigned int context);
+static int drm_notifier(void *priv);
+
 /** 
  * Lock ioctl.
  *
@@ -225,8 +230,9 @@ int drm_lock_take(__volatile__ unsigned 
  * Resets the lock file pointer.
  * Marks the lock as held by the given context, via the \p cmpxchg instruction.
  */
-int drm_lock_transfer(drm_device_t *dev,
-		       __volatile__ unsigned int *lock, unsigned int context)
+static int drm_lock_transfer(drm_device_t *dev,
+			     __volatile__ unsigned int *lock,
+			     unsigned int context)
 {
 	unsigned int old, new, prev;
 
@@ -282,7 +288,7 @@ int drm_lock_free(drm_device_t *dev,
  * \return one if the signal should be delivered normally, or zero if the
  * signal should be blocked.
  */
-int drm_notifier(void *priv)
+static int drm_notifier(void *priv)
 {
 	drm_sigdata_t *s = (drm_sigdata_t *)priv;
 	unsigned int  old, new, prev;
diff --git a/drivers/char/drm/drm_memory.c b/drivers/char/drm/drm_memory.c
--- a/drivers/char/drm/drm_memory.c
+++ b/drivers/char/drm/drm_memory.c
@@ -65,19 +65,6 @@ int drm_mem_info(char *buf, char **start
 	return 0;
 }
 
-/** Wrapper around kmalloc() */
-void *drm_calloc(size_t nmemb, size_t size, int area)
-{
-	void *addr;
-
-	addr = kmalloc(size * nmemb, GFP_KERNEL);
-	if (addr != NULL)
-		memset((void *)addr, 0, size * nmemb);
-
-	return addr;
-}
-EXPORT_SYMBOL(drm_calloc);
-
 /** Wrapper around kmalloc() and kfree() */
 void *drm_realloc(void *oldpt, size_t oldsize, size_t size, int area)
 {
diff --git a/drivers/char/drm/drm_pciids.h b/drivers/char/drm/drm_pciids.h
--- a/drivers/char/drm/drm_pciids.h
+++ b/drivers/char/drm/drm_pciids.h
@@ -223,3 +223,10 @@
 	{0x8086, 0x2772, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
 	{0, 0, 0}
 
+#define viadrv_PCI_IDS \
+	{0x1106, 0x3022, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
+	{0x1106, 0x3122, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
+	{0x1106, 0x7205, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
+	{0x1106, 0x7204, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
+	{0, 0, 0}
+
diff --git a/drivers/char/drm/drm_proc.c b/drivers/char/drm/drm_proc.c
--- a/drivers/char/drm/drm_proc.c
+++ b/drivers/char/drm/drm_proc.c
@@ -57,7 +57,7 @@ static int	   drm_vma_info(char *buf, ch
 /**
  * Proc file list.
  */
-struct drm_proc_list {
+static struct drm_proc_list {
 	const char *name;	/**< file name */
 	int	   (*f)(char *, char **, off_t, int, int *, void *);	/**< proc callback*/
 } drm_proc_list[] = {
diff --git a/drivers/char/drm/drm_stub.c b/drivers/char/drm/drm_stub.c
--- a/drivers/char/drm/drm_stub.c
+++ b/drivers/char/drm/drm_stub.c
@@ -157,52 +157,6 @@ int drm_stub_open(struct inode *inode, s
 	return err;
 }
 
-
-/**
- * Register.
- *
- * \param pdev - PCI device structure
- * \param ent entry from the PCI ID table with device type flags
- * \return zero on success or a negative number on failure.
- *
- * Attempt to gets inter module "drm" information. If we are first
- * then register the character device and inter module information.
- * Try and register, if we fail to register, backout previous work.
- */
-int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
-	      struct drm_driver *driver)
-{
-	drm_device_t *dev;
-	int ret;
-
-	DRM_DEBUG("\n");
-
-	dev = drm_calloc(1, sizeof(*dev), DRM_MEM_STUB);
-	if (!dev)
-		return -ENOMEM;
-
-	pci_enable_device(pdev);
-
-	if ((ret = drm_fill_in_dev(dev, pdev, ent, driver))) {
-		printk(KERN_ERR "DRM: Fill_in_dev failed.\n");
-		goto err_g1;
-	}
-	if ((ret = drm_get_head(dev, &dev->primary)))
-		goto err_g1;
-
-	/* postinit is a required function to display the signon banner */
-	/* drivers add secondary heads here if needed */
-	if ((ret = dev->driver->postinit(dev, ent->driver_data)))
-		goto err_g1;
-
-	return 0;
-
-err_g1:
-	drm_free(dev, sizeof(*dev), DRM_MEM_STUB);
-	return ret;
-}
-EXPORT_SYMBOL(drm_get_dev);
-
 /**
  * Get a secondary minor number.
  *
@@ -214,7 +168,7 @@ EXPORT_SYMBOL(drm_get_dev);
  * create the proc init entry via proc_init(). This routines assigns
  * minor numbers to secondary heads of multi-headed cards
  */
-int drm_get_head(drm_device_t *dev, drm_head_t *head)
+static int drm_get_head(drm_device_t *dev, drm_head_t *head)
 {
 	drm_head_t **heads = drm_heads;
 	int ret;
@@ -262,6 +216,50 @@ err_g1:
 	return ret;
 }
 		
+/**
+ * Register.
+ *
+ * \param pdev - PCI device structure
+ * \param ent entry from the PCI ID table with device type flags
+ * \return zero on success or a negative number on failure.
+ *
+ * Attempt to gets inter module "drm" information. If we are first
+ * then register the character device and inter module information.
+ * Try and register, if we fail to register, backout previous work.
+ */
+int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
+	      struct drm_driver *driver)
+{
+	drm_device_t *dev;
+	int ret;
+
+	DRM_DEBUG("\n");
+
+	dev = drm_calloc(1, sizeof(*dev), DRM_MEM_STUB);
+	if (!dev)
+		return -ENOMEM;
+
+	pci_enable_device(pdev);
+
+	if ((ret = drm_fill_in_dev(dev, pdev, ent, driver))) {
+		printk(KERN_ERR "DRM: Fill_in_dev failed.\n");
+		goto err_g1;
+	}
+	if ((ret = drm_get_head(dev, &dev->primary)))
+		goto err_g1;
+
+	/* postinit is a required function to display the signon banner */
+	/* drivers add secondary heads here if needed */
+	if ((ret = dev->driver->postinit(dev, ent->driver_data)))
+		goto err_g1;
+
+	return 0;
+
+err_g1:
+	drm_free(dev, sizeof(*dev), DRM_MEM_STUB);
+	return ret;
+}
+EXPORT_SYMBOL(drm_get_dev);
 
 /**
  * Put a device minor number.
diff --git a/drivers/char/drm/drm_vm.c b/drivers/char/drm/drm_vm.c
--- a/drivers/char/drm/drm_vm.c
+++ b/drivers/char/drm/drm_vm.c
@@ -38,6 +38,8 @@
 #include <linux/efi.h>
 #endif
 
+static void drm_vm_open(struct vm_area_struct *vma);
+static void drm_vm_close(struct vm_area_struct *vma);
 
 /**
  * \c nopage method for AGP virtual memory.
@@ -163,7 +165,7 @@ static __inline__ struct page *drm_do_vm
  * Deletes map information if we are the last
  * person to close a mapping and it's not in the global maplist.
  */
-void drm_vm_shm_close(struct vm_area_struct *vma)
+static void drm_vm_shm_close(struct vm_area_struct *vma)
 {
 	drm_file_t	*priv	= vma->vm_file->private_data;
 	drm_device_t	*dev	= priv->head->dev;
@@ -399,7 +401,7 @@ static struct vm_operations_struct   drm
  * Create a new drm_vma_entry structure as the \p vma private data entry and
  * add it to drm_device::vmalist.
  */
-void drm_vm_open(struct vm_area_struct *vma)
+static void drm_vm_open(struct vm_area_struct *vma)
 {
 	drm_file_t	*priv	= vma->vm_file->private_data;
 	drm_device_t	*dev	= priv->head->dev;
@@ -428,7 +430,7 @@ void drm_vm_open(struct vm_area_struct *
  * Search the \p vma private data entry in drm_device::vmalist, unlink it, and
  * free it.
  */
-void drm_vm_close(struct vm_area_struct *vma)
+static void drm_vm_close(struct vm_area_struct *vma)
 {
 	drm_file_t	*priv	= vma->vm_file->private_data;
 	drm_device_t	*dev	= priv->head->dev;
@@ -463,7 +465,7 @@ void drm_vm_close(struct vm_area_struct 
  * Sets the virtual memory area operations structure to vm_dma_ops, the file
  * pointer, and calls vm_open().
  */
-int drm_mmap_dma(struct file *filp, struct vm_area_struct *vma)
+static int drm_mmap_dma(struct file *filp, struct vm_area_struct *vma)
 {
 	drm_file_t	 *priv	 = filp->private_data;
 	drm_device_t	 *dev;
diff --git a/drivers/char/drm/i810_dma.c b/drivers/char/drm/i810_dma.c
--- a/drivers/char/drm/i810_dma.c
+++ b/drivers/char/drm/i810_dma.c
@@ -90,16 +90,7 @@ static int i810_freelist_put(drm_device_
    	return 0;
 }
 
-static struct file_operations i810_buffer_fops = {
-	.open	 = drm_open,
-	.flush	 = drm_flush,
-	.release = drm_release,
-	.ioctl	 = drm_ioctl,
-	.mmap	 = i810_mmap_buffers,
-	.fasync  = drm_fasync,
-};
-
-int i810_mmap_buffers(struct file *filp, struct vm_area_struct *vma)
+static int i810_mmap_buffers(struct file *filp, struct vm_area_struct *vma)
 {
 	drm_file_t	    *priv	  = filp->private_data;
 	drm_device_t	    *dev;
@@ -126,6 +117,15 @@ int i810_mmap_buffers(struct file *filp,
 	return 0;
 }
 
+static struct file_operations i810_buffer_fops = {
+	.open	 = drm_open,
+	.flush	 = drm_flush,
+	.release = drm_release,
+	.ioctl	 = drm_ioctl,
+	.mmap	 = i810_mmap_buffers,
+	.fasync  = drm_fasync,
+};
+
 static int i810_map_buffer(drm_buf_t *buf, struct file *filp)
 {
 	drm_file_t	  *priv	  = filp->private_data;
@@ -1003,8 +1003,8 @@ void i810_reclaim_buffers(drm_device_t *
 	}
 }
 
-int i810_flush_ioctl(struct inode *inode, struct file *filp,
-		     unsigned int cmd, unsigned long arg)
+static int i810_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->head->dev;
diff --git a/drivers/char/drm/i810_drv.h b/drivers/char/drm/i810_drv.h
--- a/drivers/char/drm/i810_drv.h
+++ b/drivers/char/drm/i810_drv.h
@@ -115,7 +115,6 @@ typedef struct drm_i810_private {
 
 				/* i810_dma.c */
 extern void i810_reclaim_buffers(drm_device_t *dev, struct file *filp);
-extern int i810_mmap_buffers(struct file *filp, struct vm_area_struct *vma);
 
 extern int i810_driver_dma_quiescent(drm_device_t *dev);
 extern void i810_driver_release(drm_device_t *dev, struct file *filp);
diff --git a/drivers/char/drm/i830_dma.c b/drivers/char/drm/i830_dma.c
--- a/drivers/char/drm/i830_dma.c
+++ b/drivers/char/drm/i830_dma.c
@@ -92,16 +92,7 @@ static int i830_freelist_put(drm_device_
    	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,
-	.fasync  = drm_fasync,
-};
-
-int i830_mmap_buffers(struct file *filp, struct vm_area_struct *vma)
+static int i830_mmap_buffers(struct file *filp, struct vm_area_struct *vma)
 {
 	drm_file_t	    *priv	  = filp->private_data;
 	drm_device_t	    *dev;
@@ -128,6 +119,15 @@ int i830_mmap_buffers(struct file *filp,
 	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,
+	.fasync  = drm_fasync,
+};
+
 static int i830_map_buffer(drm_buf_t *buf, struct file *filp)
 {
 	drm_file_t	  *priv	  = filp->private_data;
diff --git a/drivers/char/drm/i830_drv.c b/drivers/char/drm/i830_drv.c
--- a/drivers/char/drm/i830_drv.c
+++ b/drivers/char/drm/i830_drv.c
@@ -40,7 +40,7 @@
 
 #include "drm_pciids.h"
 
-int postinit( struct drm_device *dev, unsigned long flags )
+static int postinit( struct drm_device *dev, unsigned long flags )
 {
 	dev->counters += 4;
 	dev->types[6] = _DRM_STAT_IRQ;
diff --git a/drivers/char/drm/i830_drv.h b/drivers/char/drm/i830_drv.h
--- a/drivers/char/drm/i830_drv.h
+++ b/drivers/char/drm/i830_drv.h
@@ -123,8 +123,6 @@ typedef struct drm_i830_private {
 /* i830_dma.c */
 extern void i830_reclaim_buffers(drm_device_t *dev, struct file *filp);
 
-extern int i830_mmap_buffers(struct file *filp, struct vm_area_struct *vma);
-
 /* i830_irq.c */
 extern int i830_irq_emit( struct inode *inode, struct file *filp, 
 			  unsigned int cmd, unsigned long arg );
diff --git a/drivers/char/drm/i830_irq.c b/drivers/char/drm/i830_irq.c
--- a/drivers/char/drm/i830_irq.c
+++ b/drivers/char/drm/i830_irq.c
@@ -54,8 +54,7 @@ irqreturn_t i830_driver_irq_handler( DRM
 	return IRQ_HANDLED;
 }
 
-
-int i830_emit_irq(drm_device_t *dev)
+static int i830_emit_irq(drm_device_t *dev)
 {
 	drm_i830_private_t *dev_priv = dev->dev_private;
 	RING_LOCALS;
@@ -73,7 +72,7 @@ int i830_emit_irq(drm_device_t *dev)
 }
 
 
-int i830_wait_irq(drm_device_t *dev, int irq_nr)
+static int i830_wait_irq(drm_device_t *dev, int irq_nr)
 {
   	drm_i830_private_t *dev_priv = 
 	   (drm_i830_private_t *)dev->dev_private;
diff --git a/drivers/char/drm/i915_dma.c b/drivers/char/drm/i915_dma.c
--- a/drivers/char/drm/i915_dma.c
+++ b/drivers/char/drm/i915_dma.c
@@ -1,10 +1,30 @@
 /* i915_dma.c -- DMA support for the I915 -*- linux-c -*-
  */
 /**************************************************************************
- * 
+ *
  * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
  * 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, sub license, 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 NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS 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.
+ *
  **************************************************************************/
 
 #include "drmP.h"
@@ -12,23 +32,6 @@
 #include "i915_drm.h"
 #include "i915_drv.h"
 
-drm_ioctl_desc_t i915_ioctls[] = {
-	[DRM_IOCTL_NR(DRM_I915_INIT)] = {i915_dma_init, 1, 1},
-	[DRM_IOCTL_NR(DRM_I915_FLUSH)] = {i915_flush_ioctl, 1, 0},
-	[DRM_IOCTL_NR(DRM_I915_FLIP)] = {i915_flip_bufs, 1, 0},
-	[DRM_IOCTL_NR(DRM_I915_BATCHBUFFER)] = {i915_batchbuffer, 1, 0},
-	[DRM_IOCTL_NR(DRM_I915_IRQ_EMIT)] = {i915_irq_emit, 1, 0},
-	[DRM_IOCTL_NR(DRM_I915_IRQ_WAIT)] = {i915_irq_wait, 1, 0},
-	[DRM_IOCTL_NR(DRM_I915_GETPARAM)] = {i915_getparam, 1, 0},
-	[DRM_IOCTL_NR(DRM_I915_SETPARAM)] = {i915_setparam, 1, 1},
-	[DRM_IOCTL_NR(DRM_I915_ALLOC)] = {i915_mem_alloc, 1, 0},
-	[DRM_IOCTL_NR(DRM_I915_FREE)] = {i915_mem_free, 1, 0},
-	[DRM_IOCTL_NR(DRM_I915_INIT_HEAP)] = {i915_mem_init_heap, 1, 1},
-	[DRM_IOCTL_NR(DRM_I915_CMDBUFFER)] = {i915_cmdbuffer, 1, 0}
-};
-
-int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls);
-
 /* Really want an OS-independent resettable timer.  Would like to have
  * this loop run for (eg) 3 sec, but have the timer reset every time
  * the head pointer changes, so that EBUSY only happens if the ring
@@ -75,7 +78,7 @@ void i915_kernel_lost_context(drm_device
 		dev_priv->sarea_priv->perf_boxes |= I915_BOX_RING_EMPTY;
 }
 
-int i915_dma_cleanup(drm_device_t * dev)
+static int i915_dma_cleanup(drm_device_t * dev)
 {
 	/* Make sure interrupts are disabled here because the uninstall ioctl
 	 * may not have been called from userspace and after dev_private
@@ -227,7 +230,7 @@ static int i915_resume(drm_device_t * de
 	return 0;
 }
 
-int i915_dma_init(DRM_IOCTL_ARGS)
+static int i915_dma_init(DRM_IOCTL_ARGS)
 {
 	DRM_DEVICE;
 	drm_i915_private_t *dev_priv;
@@ -538,7 +541,7 @@ static int i915_quiescent(drm_device_t *
 	return i915_wait_ring(dev, dev_priv->ring.Size - 8, __FUNCTION__);
 }
 
-int i915_flush_ioctl(DRM_IOCTL_ARGS)
+static int i915_flush_ioctl(DRM_IOCTL_ARGS)
 {
 	DRM_DEVICE;
 
@@ -547,7 +550,7 @@ int i915_flush_ioctl(DRM_IOCTL_ARGS)
 	return i915_quiescent(dev);
 }
 
-int i915_batchbuffer(DRM_IOCTL_ARGS)
+static int i915_batchbuffer(DRM_IOCTL_ARGS)
 {
 	DRM_DEVICE;
 	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
@@ -581,7 +584,7 @@ int i915_batchbuffer(DRM_IOCTL_ARGS)
 	return ret;
 }
 
-int i915_cmdbuffer(DRM_IOCTL_ARGS)
+static int i915_cmdbuffer(DRM_IOCTL_ARGS)
 {
 	DRM_DEVICE;
 	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
@@ -617,18 +620,7 @@ int i915_cmdbuffer(DRM_IOCTL_ARGS)
 	return 0;
 }
 
-int i915_do_cleanup_pageflip(drm_device_t * dev)
-{
-	drm_i915_private_t *dev_priv = dev->dev_private;
-
-	DRM_DEBUG("%s\n", __FUNCTION__);
-	if (dev_priv->current_page != 0)
-		i915_dispatch_flip(dev);
-
-	return 0;
-}
-
-int i915_flip_bufs(DRM_IOCTL_ARGS)
+static int i915_flip_bufs(DRM_IOCTL_ARGS)
 {
 	DRM_DEVICE;
 
@@ -639,7 +631,7 @@ int i915_flip_bufs(DRM_IOCTL_ARGS)
 	return i915_dispatch_flip(dev);
 }
 
-int i915_getparam(DRM_IOCTL_ARGS)
+static int i915_getparam(DRM_IOCTL_ARGS)
 {
 	DRM_DEVICE;
 	drm_i915_private_t *dev_priv = dev->dev_private;
@@ -674,7 +666,7 @@ int i915_getparam(DRM_IOCTL_ARGS)
 	return 0;
 }
 
-int i915_setparam(DRM_IOCTL_ARGS)
+static int i915_setparam(DRM_IOCTL_ARGS)
 {
 	DRM_DEVICE;
 	drm_i915_private_t *dev_priv = dev->dev_private;
@@ -723,3 +715,19 @@ void i915_driver_prerelease(drm_device_t
 	}
 }
 
+drm_ioctl_desc_t i915_ioctls[] = {
+	[DRM_IOCTL_NR(DRM_I915_INIT)] = {i915_dma_init, 1, 1},
+	[DRM_IOCTL_NR(DRM_I915_FLUSH)] = {i915_flush_ioctl, 1, 0},
+	[DRM_IOCTL_NR(DRM_I915_FLIP)] = {i915_flip_bufs, 1, 0},
+	[DRM_IOCTL_NR(DRM_I915_BATCHBUFFER)] = {i915_batchbuffer, 1, 0},
+	[DRM_IOCTL_NR(DRM_I915_IRQ_EMIT)] = {i915_irq_emit, 1, 0},
+	[DRM_IOCTL_NR(DRM_I915_IRQ_WAIT)] = {i915_irq_wait, 1, 0},
+	[DRM_IOCTL_NR(DRM_I915_GETPARAM)] = {i915_getparam, 1, 0},
+	[DRM_IOCTL_NR(DRM_I915_SETPARAM)] = {i915_setparam, 1, 1},
+	[DRM_IOCTL_NR(DRM_I915_ALLOC)] = {i915_mem_alloc, 1, 0},
+	[DRM_IOCTL_NR(DRM_I915_FREE)] = {i915_mem_free, 1, 0},
+	[DRM_IOCTL_NR(DRM_I915_INIT_HEAP)] = {i915_mem_init_heap, 1, 1},
+	[DRM_IOCTL_NR(DRM_I915_CMDBUFFER)] = {i915_cmdbuffer, 1, 0}
+};
+
+int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls);
diff --git a/drivers/char/drm/i915_drm.h b/drivers/char/drm/i915_drm.h
--- a/drivers/char/drm/i915_drm.h
+++ b/drivers/char/drm/i915_drm.h
@@ -1,3 +1,30 @@
+/**************************************************************************
+ *
+ * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * 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, sub license, 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 NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS 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.
+ *
+ **************************************************************************/
+
 #ifndef _I915_DRM_H_
 #define _I915_DRM_H_
 
diff --git a/drivers/char/drm/i915_drv.c b/drivers/char/drm/i915_drv.c
--- a/drivers/char/drm/i915_drv.c
+++ b/drivers/char/drm/i915_drv.c
@@ -1,11 +1,30 @@
 /* i915_drv.c -- i830,i845,i855,i865,i915 driver -*- linux-c -*-
  */
-
 /**************************************************************************
- * 
+ *
  * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
  * 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, sub license, 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 NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS 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.
+ *
  **************************************************************************/
 
 #include "drmP.h"
@@ -15,7 +34,7 @@
 
 #include "drm_pciids.h"
 
-int postinit( struct drm_device *dev, unsigned long flags )
+static int postinit( struct drm_device *dev, unsigned long flags )
 {
 	dev->counters += 4;
 	dev->types[6] = _DRM_STAT_IRQ;
@@ -78,6 +97,9 @@ static struct drm_driver driver = {
 		.mmap = drm_mmap,
 		.poll = drm_poll,
 		.fasync = drm_fasync,
+#ifdef CONFIG_COMPAT
+		.compat_ioctl = i915_compat_ioctl,
+#endif
 	},
 	.pci_driver = {
 		.name          = DRIVER_NAME,
diff --git a/drivers/char/drm/i915_drv.h b/drivers/char/drm/i915_drv.h
--- a/drivers/char/drm/i915_drv.h
+++ b/drivers/char/drm/i915_drv.h
@@ -1,10 +1,30 @@
 /* i915_drv.h -- Private header for the I915 driver -*- linux-c -*-
  */
 /**************************************************************************
- * 
+ *
  * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
  * 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, sub license, 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 NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS 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.
+ *
  **************************************************************************/
 
 #ifndef _I915_DRV_H_
@@ -79,14 +99,6 @@ typedef struct drm_i915_private {
 } drm_i915_private_t;
 
 				/* i915_dma.c */
-extern int i915_dma_init(DRM_IOCTL_ARGS);
-extern int i915_dma_cleanup(drm_device_t * dev);
-extern int i915_flush_ioctl(DRM_IOCTL_ARGS);
-extern int i915_batchbuffer(DRM_IOCTL_ARGS);
-extern int i915_flip_bufs(DRM_IOCTL_ARGS);
-extern int i915_getparam(DRM_IOCTL_ARGS);
-extern int i915_setparam(DRM_IOCTL_ARGS);
-extern int i915_cmdbuffer(DRM_IOCTL_ARGS);
 extern void i915_kernel_lost_context(drm_device_t * dev);
 extern void i915_driver_pretakedown(drm_device_t *dev);
 extern void i915_driver_prerelease(drm_device_t *dev, DRMFILE filp);
@@ -94,8 +106,6 @@ extern void i915_driver_prerelease(drm_d
 /* i915_irq.c */
 extern int i915_irq_emit(DRM_IOCTL_ARGS);
 extern int i915_irq_wait(DRM_IOCTL_ARGS);
-extern int i915_wait_irq(drm_device_t * dev, int irq_nr);
-extern int i915_emit_irq(drm_device_t * dev);
 
 extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS);
 extern void i915_driver_irq_preinstall(drm_device_t *dev);
@@ -110,6 +120,10 @@ extern void i915_mem_takedown(struct mem
 extern void i915_mem_release(drm_device_t * dev,
 			     DRMFILE filp, struct mem_block *heap);
 
+extern long i915_compat_ioctl(struct file *filp, unsigned int cmd,
+			      unsigned long arg);
+
+
 #define I915_READ(reg)          DRM_READ32(dev_priv->mmio_map, reg)
 #define I915_WRITE(reg,val)     DRM_WRITE32(dev_priv->mmio_map, reg, val)
 #define I915_READ16(reg) 	DRM_READ16(dev_priv->mmio_map, reg)
diff --git a/drivers/char/drm/i915_ioc32.c b/drivers/char/drm/i915_ioc32.c
new file mode 100644
--- /dev/null
+++ b/drivers/char/drm/i915_ioc32.c
@@ -0,0 +1,221 @@
+/**
+ * \file i915_ioc32.c
+ *
+ * 32-bit ioctl compatibility routines for the i915 DRM.
+ *
+ * \author Alan Hourihane <alanh@fairlite.demon.co.uk> 
+ *
+ *
+ * Copyright (C) Paul Mackerras 2005
+ * Copyright (C) Alan Hourihane 2005
+ * 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
+ * THE AUTHOR 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.
+ */
+#include <linux/compat.h>
+#include <linux/ioctl32.h>
+
+#include "drmP.h"
+#include "drm.h"
+#include "i915_drm.h"
+
+typedef struct _drm_i915_batchbuffer32 {
+	int start;		/* agp offset */
+	int used;		/* nr bytes in use */
+	int DR1;		/* hw flags for GFX_OP_DRAWRECT_INFO */
+	int DR4;		/* window origin for GFX_OP_DRAWRECT_INFO */
+	int num_cliprects;	/* mulitpass with multiple cliprects? */
+	u32 cliprects;	/* pointer to userspace cliprects */
+} drm_i915_batchbuffer32_t;
+
+static int compat_i915_batchbuffer(struct file *file, unsigned int cmd,
+			   unsigned long arg)
+{
+	drm_i915_batchbuffer32_t batchbuffer32;
+	drm_i915_batchbuffer_t __user *batchbuffer;
+	
+	if (copy_from_user(&batchbuffer32, (void __user *)arg, sizeof(batchbuffer32)))
+		return -EFAULT;
+	
+	batchbuffer = compat_alloc_user_space(sizeof(*batchbuffer));
+	if (!access_ok(VERIFY_WRITE, batchbuffer, sizeof(*batchbuffer))
+	    || __put_user(batchbuffer32.start, &batchbuffer->start)
+	    || __put_user(batchbuffer32.used, &batchbuffer->used)
+	    || __put_user(batchbuffer32.DR1, &batchbuffer->DR1)
+	    || __put_user(batchbuffer32.DR4, &batchbuffer->DR4)
+	    || __put_user(batchbuffer32.num_cliprects, &batchbuffer->num_cliprects)
+	    || __put_user((int __user *)(unsigned long)batchbuffer32.cliprects,
+			  &batchbuffer->cliprects))
+		return -EFAULT;
+	
+	return drm_ioctl(file->f_dentry->d_inode, file,
+			 DRM_IOCTL_I915_BATCHBUFFER, (unsigned long) batchbuffer);
+}
+
+typedef struct _drm_i915_cmdbuffer32 {
+	u32 buf;	/* pointer to userspace command buffer */
+	int sz;			/* nr bytes in buf */
+	int DR1;		/* hw flags for GFX_OP_DRAWRECT_INFO */
+	int DR4;		/* window origin for GFX_OP_DRAWRECT_INFO */
+	int num_cliprects;	/* mulitpass with multiple cliprects? */
+	u32 cliprects;	/* pointer to userspace cliprects */
+} drm_i915_cmdbuffer32_t;
+
+static int compat_i915_cmdbuffer(struct file *file, unsigned int cmd,
+			   unsigned long arg)
+{
+	drm_i915_cmdbuffer32_t cmdbuffer32;
+	drm_i915_cmdbuffer_t __user *cmdbuffer;
+	
+	if (copy_from_user(&cmdbuffer32, (void __user *)arg, sizeof(cmdbuffer32)))
+		return -EFAULT;
+	
+	cmdbuffer = compat_alloc_user_space(sizeof(*cmdbuffer));
+	if (!access_ok(VERIFY_WRITE, cmdbuffer, sizeof(*cmdbuffer))
+	    || __put_user((int __user *)(unsigned long)cmdbuffer32.buf,
+			  &cmdbuffer->buf)
+	    || __put_user(cmdbuffer32.sz, &cmdbuffer->sz)
+	    || __put_user(cmdbuffer32.DR1, &cmdbuffer->DR1)
+	    || __put_user(cmdbuffer32.DR4, &cmdbuffer->DR4)
+	    || __put_user(cmdbuffer32.num_cliprects, &cmdbuffer->num_cliprects)
+	    || __put_user((int __user *)(unsigned long)cmdbuffer32.cliprects,
+			  &cmdbuffer->cliprects))
+		return -EFAULT;
+	
+	return drm_ioctl(file->f_dentry->d_inode, file,
+			 DRM_IOCTL_I915_CMDBUFFER, (unsigned long) cmdbuffer);
+}
+
+typedef struct drm_i915_irq_emit32 {
+	u32 irq_seq;
+} drm_i915_irq_emit32_t;
+
+static int compat_i915_irq_emit(struct file *file, unsigned int cmd,
+				  unsigned long arg)
+{
+	drm_i915_irq_emit32_t req32;
+	drm_i915_irq_emit_t __user *request;
+
+	if (copy_from_user(&req32, (void __user *) arg, sizeof(req32)))
+		return -EFAULT;
+
+	request = compat_alloc_user_space(sizeof(*request));
+	if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
+	    || __put_user((int __user *)(unsigned long)req32.irq_seq,
+			  &request->irq_seq))
+		return -EFAULT;
+
+	return drm_ioctl(file->f_dentry->d_inode, file,
+			 DRM_IOCTL_I915_IRQ_EMIT, (unsigned long) request);
+}
+typedef struct drm_i915_getparam32 {
+	int param;
+	u32 value;
+} drm_i915_getparam32_t;
+
+static int compat_i915_getparam(struct file *file, unsigned int cmd,
+				     unsigned long arg)
+{
+	drm_i915_getparam32_t req32;
+	drm_i915_getparam_t __user *request;
+
+	if (copy_from_user(&req32, (void __user *) arg, sizeof(req32)))
+		return -EFAULT;
+
+	request = compat_alloc_user_space(sizeof(*request));
+	if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
+	    || __put_user(req32.param, &request->param)
+	    || __put_user((void __user *)(unsigned long)req32.value,
+			  &request->value))
+		return -EFAULT;
+
+	return drm_ioctl(file->f_dentry->d_inode, file,
+			 DRM_IOCTL_I915_GETPARAM, (unsigned long) request);
+}
+
+typedef struct drm_i915_mem_alloc32 {
+	int region;
+	int alignment;
+	int size;
+	u32 region_offset;	/* offset from start of fb or agp */
+} drm_i915_mem_alloc32_t;
+
+static int compat_i915_alloc(struct file *file, unsigned int cmd,
+				     unsigned long arg)
+{
+	drm_i915_mem_alloc32_t req32;
+	drm_i915_mem_alloc_t __user *request;
+
+	if (copy_from_user(&req32, (void __user *) arg, sizeof(req32)))
+		return -EFAULT;
+
+	request = compat_alloc_user_space(sizeof(*request));
+	if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
+	    || __put_user(req32.region, &request->region)
+	    || __put_user(req32.alignment, &request->alignment)
+	    || __put_user(req32.size, &request->size)
+	    || __put_user((void __user *)(unsigned long)req32.region_offset,
+			  &request->region_offset))
+		return -EFAULT;
+
+	return drm_ioctl(file->f_dentry->d_inode, file,
+			 DRM_IOCTL_I915_ALLOC, (unsigned long) request);
+}
+
+
+drm_ioctl_compat_t *i915_compat_ioctls[] = {
+	[DRM_I915_BATCHBUFFER] = compat_i915_batchbuffer,
+	[DRM_I915_CMDBUFFER] = compat_i915_cmdbuffer,
+	[DRM_I915_GETPARAM] = compat_i915_getparam,
+	[DRM_I915_IRQ_EMIT] = compat_i915_irq_emit,
+	[DRM_I915_ALLOC] = compat_i915_alloc
+};
+
+/**
+ * Called whenever a 32-bit process running under a 64-bit kernel
+ * performs an ioctl on /dev/dri/card<n>.
+ *
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg user argument.
+ * \return zero on success or negative number on failure.
+ */
+long i915_compat_ioctl(struct file *filp, unsigned int cmd,
+			 unsigned long arg)
+{
+	unsigned int nr = DRM_IOCTL_NR(cmd);
+	drm_ioctl_compat_t *fn = NULL;
+	int ret;
+
+	if (nr < DRM_COMMAND_BASE)
+		return drm_compat_ioctl(filp, cmd, arg);
+	
+	if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(i915_compat_ioctls))
+		fn = i915_compat_ioctls[nr - DRM_COMMAND_BASE];
+
+	lock_kernel();		/* XXX for now */
+	if (fn != NULL)
+		ret = (*fn)(filp, cmd, arg);
+	else
+		ret = drm_ioctl(filp->f_dentry->d_inode, filp, cmd, arg);
+	unlock_kernel();
+
+	return ret;
+}
diff --git a/drivers/char/drm/i915_irq.c b/drivers/char/drm/i915_irq.c
--- a/drivers/char/drm/i915_irq.c
+++ b/drivers/char/drm/i915_irq.c
@@ -1,10 +1,30 @@
 /* i915_dma.c -- DMA support for the I915 -*- linux-c -*-
  */
 /**************************************************************************
- * 
+ *
  * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
  * 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, sub license, 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 NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS 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.
+ *
  **************************************************************************/
 
 #include "drmP.h"
@@ -36,7 +56,7 @@ irqreturn_t i915_driver_irq_handler(DRM_
 	return IRQ_HANDLED;
 }
 
-int i915_emit_irq(drm_device_t * dev)
+static int i915_emit_irq(drm_device_t * dev)
 {
 	drm_i915_private_t *dev_priv = dev->dev_private;
 	u32 ret;
@@ -56,7 +76,7 @@ int i915_emit_irq(drm_device_t * dev)
 	return ret;
 }
 
-int i915_wait_irq(drm_device_t * dev, int irq_nr)
+static int i915_wait_irq(drm_device_t * dev, int irq_nr)
 {
 	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
 	int ret = 0;
diff --git a/drivers/char/drm/i915_mem.c b/drivers/char/drm/i915_mem.c
--- a/drivers/char/drm/i915_mem.c
+++ b/drivers/char/drm/i915_mem.c
@@ -1,10 +1,30 @@
 /* i915_mem.c -- Simple agp/fb memory manager for i915 -*- linux-c -*-
  */
 /**************************************************************************
- * 
+ *
  * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
  * 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, sub license, 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 NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS 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.
+ *
  **************************************************************************/
 
 #include "drmP.h"
diff --git a/drivers/char/drm/mga_drv.c b/drivers/char/drm/mga_drv.c
--- a/drivers/char/drm/mga_drv.c
+++ b/drivers/char/drm/mga_drv.c
@@ -101,6 +101,9 @@ static struct drm_driver driver = {
 		.mmap = drm_mmap,
 		.poll = drm_poll,
 		.fasync = drm_fasync,
+#ifdef CONFIG_COMPAT
+		.compat_ioctl = mga_compat_ioctl,
+#endif
 	},
 	.pci_driver = {
 		.name = DRIVER_NAME,
diff --git a/drivers/char/drm/mga_drv.h b/drivers/char/drm/mga_drv.h
--- a/drivers/char/drm/mga_drv.h
+++ b/drivers/char/drm/mga_drv.h
@@ -137,6 +137,8 @@ extern irqreturn_t mga_driver_irq_handle
 extern void mga_driver_irq_preinstall( drm_device_t *dev );
 extern void mga_driver_irq_postinstall( drm_device_t *dev );
 extern void mga_driver_irq_uninstall( drm_device_t *dev );
+extern long mga_compat_ioctl(struct file *filp, unsigned int cmd,
+			     unsigned long arg);
 
 #define mga_flush_write_combine()	DRM_WRITEMEMORYBARRIER()
 
diff --git a/drivers/char/drm/mga_ioc32.c b/drivers/char/drm/mga_ioc32.c
new file mode 100644
--- /dev/null
+++ b/drivers/char/drm/mga_ioc32.c
@@ -0,0 +1,167 @@
+/**
+ * \file mga_ioc32.c
+ *
+ * 32-bit ioctl compatibility routines for the MGA DRM.
+ *
+ * \author Dave Airlie <airlied@linux.ie> with code from patches by Egbert Eich
+ *
+ *
+ * Copyright (C) Paul Mackerras 2005
+ * Copyright (C) Egbert Eich 2003,2004
+ * Copyright (C) Dave Airlie 2005
+ * 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
+ * THE AUTHOR 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.
+ */
+#include <linux/compat.h>
+#include <linux/ioctl32.h>
+
+#include "drmP.h"
+#include "drm.h"
+#include "mga_drm.h"
+
+typedef struct drm32_mga_init {
+	int func;
+   	u32 sarea_priv_offset;
+	int chipset;
+   	int sgram;
+	unsigned int maccess;
+   	unsigned int fb_cpp;
+	unsigned int front_offset, front_pitch;
+   	unsigned int back_offset, back_pitch;
+   	unsigned int depth_cpp;
+   	unsigned int depth_offset, depth_pitch;
+   	unsigned int texture_offset[MGA_NR_TEX_HEAPS];
+   	unsigned int texture_size[MGA_NR_TEX_HEAPS];
+	u32 fb_offset;
+	u32 mmio_offset;
+	u32 status_offset;
+	u32 warp_offset;
+	u32 primary_offset;
+	u32 buffers_offset;
+} drm_mga_init32_t;
+
+static int compat_mga_init(struct file *file, unsigned int cmd,
+			   unsigned long arg)
+{
+	drm_mga_init32_t init32;
+	drm_mga_init_t __user *init;
+	int err = 0, i;
+	
+	if (copy_from_user(&init32, (void __user *)arg, sizeof(init32)))
+		return -EFAULT;
+	
+	init = compat_alloc_user_space(sizeof(*init));
+	if (!access_ok(VERIFY_WRITE, init, sizeof(*init))
+	    || __put_user(init32.func, &init->func)
+	    || __put_user(init32.sarea_priv_offset, &init->sarea_priv_offset)
+	    || __put_user(init32.chipset, &init->chipset)
+	    || __put_user(init32.sgram, &init->sgram)
+	    || __put_user(init32.maccess, &init->maccess)
+	    || __put_user(init32.fb_cpp, &init->fb_cpp)
+	    || __put_user(init32.front_offset, &init->front_offset)
+	    || __put_user(init32.front_pitch, &init->front_pitch)
+	    || __put_user(init32.back_offset, &init->back_offset)
+	    || __put_user(init32.back_pitch, &init->back_pitch)
+	    || __put_user(init32.depth_cpp, &init->depth_cpp)
+	    || __put_user(init32.depth_offset, &init->depth_offset)
+	    || __put_user(init32.depth_pitch, &init->depth_pitch)
+	    || __put_user(init32.fb_offset, &init->fb_offset)
+	    || __put_user(init32.mmio_offset, &init->mmio_offset)
+	    || __put_user(init32.status_offset, &init->status_offset)
+	    || __put_user(init32.warp_offset, &init->warp_offset)
+	    || __put_user(init32.primary_offset, &init->primary_offset)
+	    || __put_user(init32.buffers_offset, &init->buffers_offset))
+		return -EFAULT;
+	
+	for (i=0; i<MGA_NR_TEX_HEAPS; i++)
+	{
+		err |= __put_user(init32.texture_offset[i], &init->texture_offset[i]);
+		err |= __put_user(init32.texture_size[i], &init->texture_size[i]);
+	}
+	if (err)
+		return -EFAULT;
+	
+	return drm_ioctl(file->f_dentry->d_inode, file,
+			 DRM_IOCTL_MGA_INIT, (unsigned long) init);
+}
+
+
+typedef struct drm_mga_getparam32 {
+	int param;
+	u32 value;
+} drm_mga_getparam32_t;
+
+
+static int compat_mga_getparam(struct file *file, unsigned int cmd,
+			       unsigned long arg)
+{
+	drm_mga_getparam32_t getparam32;
+	drm_mga_getparam_t __user *getparam;
+	
+	if (copy_from_user(&getparam32, (void __user *)arg, sizeof(getparam32)))
+		return -EFAULT;
+
+	getparam = compat_alloc_user_space(sizeof(*getparam));
+	if (!access_ok(VERIFY_WRITE, getparam, sizeof(*getparam))
+	    || __put_user(getparam32.param, &getparam->param)
+	    || __put_user((void __user *)(unsigned long)getparam32.value, &getparam->value))
+		return -EFAULT;
+
+	return drm_ioctl(file->f_dentry->d_inode, file, 
+			 DRM_IOCTL_MGA_GETPARAM, (unsigned long)getparam);
+}
+
+drm_ioctl_compat_t *mga_compat_ioctls[] = {
+	[DRM_MGA_INIT] = compat_mga_init,
+	[DRM_MGA_GETPARAM] = compat_mga_getparam,
+};
+
+/**
+ * Called whenever a 32-bit process running under a 64-bit kernel
+ * performs an ioctl on /dev/dri/card<n>.
+ *
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg user argument.
+ * \return zero on success or negative number on failure.
+ */
+long mga_compat_ioctl(struct file *filp, unsigned int cmd,
+			 unsigned long arg)
+{
+	unsigned int nr = DRM_IOCTL_NR(cmd);
+	drm_ioctl_compat_t *fn = NULL;
+	int ret;
+
+	if (nr < DRM_COMMAND_BASE)
+		return drm_compat_ioctl(filp, cmd, arg);
+	
+	if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(mga_compat_ioctls))
+		fn = mga_compat_ioctls[nr - DRM_COMMAND_BASE];
+
+	lock_kernel();		/* XXX for now */
+	if (fn != NULL)
+		ret = (*fn)(filp, cmd, arg);
+	else
+		ret = drm_ioctl(filp->f_dentry->d_inode, filp, cmd, arg);
+	unlock_kernel();
+
+	return ret;
+}
diff --git a/drivers/char/drm/r128_drv.c b/drivers/char/drm/r128_drv.c
--- a/drivers/char/drm/r128_drv.c
+++ b/drivers/char/drm/r128_drv.c
@@ -96,6 +96,9 @@ static struct drm_driver driver = {
 		.mmap = drm_mmap,
 		.poll = drm_poll,
 		.fasync = drm_fasync,
+#ifdef CONFIG_COMPAT
+		.compat_ioctl = r128_compat_ioctl,
+#endif
 	},
 	.pci_driver = {
 		.name          = DRIVER_NAME,
diff --git a/drivers/char/drm/r128_drv.h b/drivers/char/drm/r128_drv.h
--- a/drivers/char/drm/r128_drv.h
+++ b/drivers/char/drm/r128_drv.h
@@ -156,6 +156,9 @@ extern void r128_driver_irq_uninstall( d
 extern void r128_driver_pretakedown(drm_device_t *dev);
 extern void r128_driver_prerelease(drm_device_t *dev, DRMFILE filp);
 
+extern long r128_compat_ioctl(struct file *filp, unsigned int cmd,
+			      unsigned long arg);
+
 /* Register definitions, register access macros and drmAddMap constants
  * for Rage 128 kernel driver.
  */
diff --git a/drivers/char/drm/r128_ioc32.c b/drivers/char/drm/r128_ioc32.c
new file mode 100644
--- /dev/null
+++ b/drivers/char/drm/r128_ioc32.c
@@ -0,0 +1,219 @@
+/**
+ * \file r128_ioc32.c
+ *
+ * 32-bit ioctl compatibility routines for the R128 DRM.
+ *
+ * \author Dave Airlie <airlied@linux.ie> with code from patches by Egbert Eich
+ *
+ * Copyright (C) Paul Mackerras 2005
+ * Copyright (C) Egbert Eich 2003,2004
+ * Copyright (C) Dave Airlie 2005
+ * 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
+ * THE AUTHOR 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.
+ */
+#include <linux/compat.h>
+#include <linux/ioctl32.h>
+
+#include "drmP.h"
+#include "drm.h"
+#include "r128_drm.h"
+
+typedef struct drm_r128_init32 {
+	int func;
+	unsigned int sarea_priv_offset;
+	int is_pci;
+	int cce_mode;
+	int cce_secure;
+	int ring_size;
+	int usec_timeout;
+
+	unsigned int fb_bpp;
+	unsigned int front_offset, front_pitch;
+	unsigned int back_offset, back_pitch;
+	unsigned int depth_bpp;
+	unsigned int depth_offset, depth_pitch;
+	unsigned int span_offset;
+
+	unsigned int fb_offset;
+	unsigned int mmio_offset;
+	unsigned int ring_offset;
+	unsigned int ring_rptr_offset;
+	unsigned int buffers_offset;
+	unsigned int agp_textures_offset;
+} drm_r128_init32_t;
+
+static int compat_r128_init(struct file *file, unsigned int cmd,
+			    unsigned long arg)
+{
+	drm_r128_init32_t init32;
+	drm_r128_init_t __user *init;
+	
+	if (copy_from_user(&init32, (void __user *)arg, sizeof(init32)))
+		return -EFAULT;
+	
+	init = compat_alloc_user_space(sizeof(*init));
+	if (!access_ok(VERIFY_WRITE, init, sizeof(*init))
+	    || __put_user(init32.func, &init->func)
+	    || __put_user(init32.sarea_priv_offset, &init->sarea_priv_offset)
+	    || __put_user(init32.is_pci, &init->is_pci)
+	    || __put_user(init32.cce_mode, &init->cce_mode)
+	    || __put_user(init32.cce_secure, &init->cce_secure)
+	    || __put_user(init32.ring_size, &init->ring_size)
+	    || __put_user(init32.usec_timeout, &init->usec_timeout)
+	    || __put_user(init32.fb_bpp, &init->fb_bpp)
+	    || __put_user(init32.front_offset, &init->front_offset)
+	    || __put_user(init32.front_pitch, &init->front_pitch)
+	    || __put_user(init32.back_offset, &init->back_offset)
+	    || __put_user(init32.back_pitch, &init->back_pitch)
+	    || __put_user(init32.depth_bpp, &init->depth_bpp)
+	    || __put_user(init32.depth_offset, &init->depth_offset)
+	    || __put_user(init32.depth_pitch, &init->depth_pitch)
+	    || __put_user(init32.span_offset, &init->span_offset)
+	    || __put_user(init32.fb_offset, &init->fb_offset)
+	    || __put_user(init32.mmio_offset, &init->mmio_offset)
+	    || __put_user(init32.ring_offset, &init->ring_offset)
+	    || __put_user(init32.ring_rptr_offset, &init->ring_rptr_offset)
+	    || __put_user(init32.buffers_offset, &init->buffers_offset)
+	    || __put_user(init32.agp_textures_offset, &init->agp_textures_offset))
+		return -EFAULT;
+	
+	return drm_ioctl(file->f_dentry->d_inode, file,
+			 DRM_IOCTL_R128_INIT, (unsigned long)init);
+}
+
+
+typedef struct drm_r128_depth32 {
+	int func;
+	int n;
+	u32 x;
+	u32 y;
+	u32 buffer;
+	u32 mask;
+} drm_r128_depth32_t;
+
+static int compat_r128_depth(struct file *file, unsigned int cmd,
+			     unsigned long arg)
+{
+	drm_r128_depth32_t depth32;
+	drm_r128_depth_t __user *depth;
+
+	if (copy_from_user(&depth32, (void __user *)arg, sizeof(depth32)))
+		return -EFAULT;
+
+	depth = compat_alloc_user_space(sizeof(*depth));
+	if (!access_ok(VERIFY_WRITE, depth, sizeof(*depth))
+	    || __put_user(depth32.func, &depth->func)
+	    || __put_user(depth32.n, &depth->n)
+	    || __put_user((int __user *)(unsigned long)depth32.x, &depth->x)
+	    || __put_user((int __user *)(unsigned long)depth32.y, &depth->y)
+	    || __put_user((unsigned int __user *)(unsigned long)depth32.buffer, &depth->buffer)
+	    || __put_user((unsigned char __user *)(unsigned long)depth32.mask, &depth->mask))
+		return -EFAULT;
+	
+	return drm_ioctl(file->f_dentry->d_inode, file,
+			 DRM_IOCTL_R128_DEPTH, (unsigned long)depth);	
+	
+}
+
+typedef struct drm_r128_stipple32 {
+	u32 mask;
+} drm_r128_stipple32_t;
+
+static int compat_r128_stipple(struct file *file, unsigned int cmd,
+			       unsigned long arg)
+{
+	drm_r128_stipple32_t stipple32;
+	drm_r128_stipple_t __user *stipple;
+
+	if (copy_from_user(&stipple32, (void __user *)arg, sizeof(stipple32)))
+		return -EFAULT;
+
+	stipple = compat_alloc_user_space(sizeof(*stipple));
+	if (!access_ok(VERIFY_WRITE, stipple, sizeof(*stipple))
+	    || __put_user((unsigned int __user *)(unsigned long)stipple32.mask, &stipple->mask))
+		return -EFAULT;
+
+	return drm_ioctl(file->f_dentry->d_inode, file,
+			 DRM_IOCTL_R128_STIPPLE, (unsigned long)stipple);
+}
+
+typedef struct drm_r128_getparam32 {
+	int param;
+	u32 value;
+} drm_r128_getparam32_t;
+
+static int compat_r128_getparam(struct file *file, unsigned int cmd,
+				unsigned long arg)
+{
+	drm_r128_getparam32_t getparam32;
+	drm_r128_getparam_t __user *getparam;
+
+	if (copy_from_user(&getparam32, (void __user *)arg, sizeof(getparam32)))
+		return -EFAULT;
+
+	getparam = compat_alloc_user_space(sizeof(*getparam));
+	if (!access_ok(VERIFY_WRITE, getparam, sizeof(*getparam))
+	    || __put_user(getparam32.param, &getparam->param)
+	    || __put_user((void __user *)(unsigned long)getparam32.value, &getparam->value))
+		return -EFAULT;
+	
+	return drm_ioctl(file->f_dentry->d_inode, file,
+			 DRM_IOCTL_R128_GETPARAM, (unsigned long)getparam);
+}
+
+drm_ioctl_compat_t *r128_compat_ioctls[] = {
+	[DRM_R128_INIT] = compat_r128_init,
+	[DRM_R128_DEPTH] = compat_r128_depth,
+	[DRM_R128_STIPPLE] = compat_r128_stipple,
+	[DRM_R128_GETPARAM] = compat_r128_getparam,
+};
+
+/**
+ * Called whenever a 32-bit process running under a 64-bit kernel
+ * performs an ioctl on /dev/dri/card<n>.
+ *
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg user argument.
+ * \return zero on success or negative number on failure.
+ */
+long r128_compat_ioctl(struct file *filp, unsigned int cmd,
+			 unsigned long arg)
+{
+	unsigned int nr = DRM_IOCTL_NR(cmd);
+	drm_ioctl_compat_t *fn = NULL;
+	int ret;
+
+	if (nr < DRM_COMMAND_BASE)
+		return drm_compat_ioctl(filp, cmd, arg);
+
+	if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(r128_compat_ioctls))
+		fn = r128_compat_ioctls[nr - DRM_COMMAND_BASE];
+
+	lock_kernel();		/* XXX for now */
+	if (fn != NULL)
+		ret = (*fn)(filp, cmd, arg);
+	else
+		ret = drm_ioctl(filp->f_dentry->d_inode, filp, cmd, arg);
+	unlock_kernel();
+
+	return ret;
+}
diff --git a/drivers/char/drm/r128_state.c b/drivers/char/drm/r128_state.c
--- a/drivers/char/drm/r128_state.c
+++ b/drivers/char/drm/r128_state.c
@@ -1307,7 +1307,7 @@ static int r128_do_init_pageflip( drm_de
 	return 0;
 }
 
-int r128_do_cleanup_pageflip( drm_device_t *dev )
+static int r128_do_cleanup_pageflip( drm_device_t *dev )
 {
 	drm_r128_private_t *dev_priv = dev->dev_private;
 	DRM_DEBUG( "\n" );
diff --git a/drivers/char/drm/radeon_drv.c b/drivers/char/drm/radeon_drv.c
--- a/drivers/char/drm/radeon_drv.c
+++ b/drivers/char/drm/radeon_drv.c
@@ -101,6 +101,9 @@ static struct drm_driver driver = {
 		.mmap = drm_mmap,
 		.poll = drm_poll,
 		.fasync = drm_fasync,
+#ifdef CONFIG_COMPAT
+		.compat_ioctl = radeon_compat_ioctl,
+#endif
 	},
 	.pci_driver = {
 		.name          = DRIVER_NAME,
diff --git a/drivers/char/drm/radeon_drv.h b/drivers/char/drm/radeon_drv.h
--- a/drivers/char/drm/radeon_drv.h
+++ b/drivers/char/drm/radeon_drv.h
@@ -317,6 +317,9 @@ extern int radeon_preinit( struct drm_de
 extern int radeon_postinit( struct drm_device *dev, unsigned long flags );
 extern int radeon_postcleanup( struct drm_device *dev );
 
+extern long radeon_compat_ioctl(struct file *filp, unsigned int cmd,
+				unsigned long arg);
+
 /* Flags for stats.boxes
  */
 #define RADEON_BOX_DMA_IDLE      0x1
diff --git a/drivers/char/drm/radeon_ioc32.c b/drivers/char/drm/radeon_ioc32.c
new file mode 100644
--- /dev/null
+++ b/drivers/char/drm/radeon_ioc32.c
@@ -0,0 +1,395 @@
+/**
+ * \file radeon_ioc32.c
+ *
+ * 32-bit ioctl compatibility routines for the Radeon DRM.
+ *
+ * \author Paul Mackerras <paulus@samba.org>
+ *
+ * Copyright (C) Paul Mackerras 2005
+ * 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
+ * THE AUTHOR 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.
+ */
+#include <linux/compat.h>
+#include <linux/ioctl32.h>
+
+#include "drmP.h"
+#include "drm.h"
+#include "radeon_drm.h"
+#include "radeon_drv.h"
+
+typedef struct drm_radeon_init32 {
+	int func;
+	u32 sarea_priv_offset;
+	int is_pci;
+	int cp_mode;
+	int gart_size;
+	int ring_size;
+	int usec_timeout;
+
+	unsigned int fb_bpp;
+	unsigned int front_offset, front_pitch;
+	unsigned int back_offset, back_pitch;
+	unsigned int depth_bpp;
+	unsigned int depth_offset, depth_pitch;
+
+	u32 fb_offset;
+	u32 mmio_offset;
+	u32 ring_offset;
+	u32 ring_rptr_offset;
+	u32 buffers_offset;
+	u32 gart_textures_offset;
+} drm_radeon_init32_t;
+
+static int compat_radeon_cp_init(struct file *file, unsigned int cmd,
+				 unsigned long arg)
+{
+	drm_radeon_init32_t init32;
+	drm_radeon_init_t __user *init;
+
+	if (copy_from_user(&init32, (void __user *)arg, sizeof(init32)))
+		return -EFAULT;
+
+	init = compat_alloc_user_space(sizeof(*init));
+	if (!access_ok(VERIFY_WRITE, init, sizeof(*init))
+	    || __put_user(init32.func, &init->func)
+	    || __put_user(init32.sarea_priv_offset, &init->sarea_priv_offset)
+	    || __put_user(init32.is_pci, &init->is_pci)
+	    || __put_user(init32.cp_mode, &init->cp_mode)
+	    || __put_user(init32.gart_size, &init->gart_size)
+	    || __put_user(init32.ring_size, &init->ring_size)
+	    || __put_user(init32.usec_timeout, &init->usec_timeout)
+	    || __put_user(init32.fb_bpp, &init->fb_bpp)
+	    || __put_user(init32.front_offset, &init->front_offset)
+	    || __put_user(init32.front_pitch, &init->front_pitch)
+	    || __put_user(init32.back_offset, &init->back_offset)
+	    || __put_user(init32.back_pitch, &init->back_pitch)
+	    || __put_user(init32.depth_bpp, &init->depth_bpp)
+	    || __put_user(init32.depth_offset, &init->depth_offset)
+	    || __put_user(init32.depth_pitch, &init->depth_pitch)
+	    || __put_user(init32.fb_offset, &init->fb_offset)
+	    || __put_user(init32.mmio_offset, &init->mmio_offset)
+	    || __put_user(init32.ring_offset, &init->ring_offset)
+	    || __put_user(init32.ring_rptr_offset, &init->ring_rptr_offset)
+	    || __put_user(init32.buffers_offset, &init->buffers_offset)
+	    || __put_user(init32.gart_textures_offset,
+			  &init->gart_textures_offset))
+		return -EFAULT;
+
+	return drm_ioctl(file->f_dentry->d_inode, file,
+			 DRM_IOCTL_RADEON_CP_INIT, (unsigned long) init);
+}
+
+typedef struct drm_radeon_clear32 {
+	unsigned int flags;
+	unsigned int clear_color;
+	unsigned int clear_depth;
+	unsigned int color_mask;
+	unsigned int depth_mask;   /* misnamed field:  should be stencil */
+	u32	     depth_boxes;
+} drm_radeon_clear32_t;
+
+static int compat_radeon_cp_clear(struct file *file, unsigned int cmd,
+				  unsigned long arg)
+{
+	drm_radeon_clear32_t clr32;
+	drm_radeon_clear_t __user *clr;
+
+	if (copy_from_user(&clr32, (void __user *)arg, sizeof(clr32)))
+		return -EFAULT;
+
+	clr = compat_alloc_user_space(sizeof(*clr));
+	if (!access_ok(VERIFY_WRITE, clr, sizeof(*clr))
+	    || __put_user(clr32.flags, &clr->flags)
+	    || __put_user(clr32.clear_color, &clr->clear_color)
+	    || __put_user(clr32.clear_depth, &clr->clear_depth)
+	    || __put_user(clr32.color_mask, &clr->color_mask)
+	    || __put_user(clr32.depth_mask, &clr->depth_mask)
+	    || __put_user((void __user *)(unsigned long)clr32.depth_boxes,
+			  &clr->depth_boxes))
+		return -EFAULT;
+
+	return drm_ioctl(file->f_dentry->d_inode, file,
+			 DRM_IOCTL_RADEON_CLEAR, (unsigned long) clr);
+}
+
+typedef struct drm_radeon_stipple32 {
+	u32 mask;
+} drm_radeon_stipple32_t;
+
+static int compat_radeon_cp_stipple(struct file *file, unsigned int cmd,
+				    unsigned long arg)
+{
+	drm_radeon_stipple32_t __user *argp = (void __user *) arg;
+	drm_radeon_stipple_t __user *request;
+	u32 mask;
+
+	if (get_user(mask, &argp->mask))
+		return -EFAULT;
+
+	request = compat_alloc_user_space(sizeof(*request));
+	if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
+	    || __put_user((unsigned int __user *)(unsigned long) mask,
+			  &request->mask))
+		return -EFAULT;
+
+	return drm_ioctl(file->f_dentry->d_inode, file,
+			 DRM_IOCTL_RADEON_STIPPLE, (unsigned long) request);
+}
+
+typedef struct drm_radeon_tex_image32 {
+	unsigned int x, y;		/* Blit coordinates */
+	unsigned int width, height;
+	u32 data;
+} drm_radeon_tex_image32_t;
+
+typedef struct drm_radeon_texture32 {
+	unsigned int offset;
+	int pitch;
+	int format;
+	int width;			/* Texture image coordinates */
+	int height;
+	u32 image;
+} drm_radeon_texture32_t;
+
+static int compat_radeon_cp_texture(struct file *file, unsigned int cmd,
+				    unsigned long arg)
+{
+	drm_radeon_texture32_t req32;
+	drm_radeon_texture_t __user *request;
+	drm_radeon_tex_image32_t img32;
+	drm_radeon_tex_image_t __user *image;
+
+	if (copy_from_user(&req32, (void __user *) arg, sizeof(req32)))
+		return -EFAULT;
+	if (req32.image == 0)
+		return -EINVAL;
+	if (copy_from_user(&img32, (void __user *)(unsigned long)req32.image,
+			   sizeof(img32)))
+		return -EFAULT;
+
+	request = compat_alloc_user_space(sizeof(*request) + sizeof(*image));
+	if (!access_ok(VERIFY_WRITE, request,
+		       sizeof(*request) + sizeof(*image)))
+		return -EFAULT;
+	image = (drm_radeon_tex_image_t __user *) (request + 1);
+
+	if (__put_user(req32.offset, &request->offset)
+	    || __put_user(req32.pitch, &request->pitch)
+	    || __put_user(req32.format, &request->format)
+	    || __put_user(req32.width, &request->width)
+	    || __put_user(req32.height, &request->height)
+	    || __put_user(image, &request->image)
+	    || __put_user(img32.x, &image->x)
+	    || __put_user(img32.y, &image->y)
+	    || __put_user(img32.width, &image->width)
+	    || __put_user(img32.height, &image->height)
+	    || __put_user((const void __user *)(unsigned long)img32.data,
+			  &image->data))
+		return -EFAULT;
+
+	return drm_ioctl(file->f_dentry->d_inode, file,
+			 DRM_IOCTL_RADEON_TEXTURE, (unsigned long) request);
+}
+
+typedef struct drm_radeon_vertex2_32 {
+	int idx;			/* Index of vertex buffer */
+	int discard;			/* Client finished with buffer? */
+	int nr_states;
+	u32 state;
+	int nr_prims;
+	u32 prim;
+} drm_radeon_vertex2_32_t;
+
+static int compat_radeon_cp_vertex2(struct file *file, unsigned int cmd,
+				    unsigned long arg)
+{
+	drm_radeon_vertex2_32_t req32;
+	drm_radeon_vertex2_t __user *request;
+
+	if (copy_from_user(&req32, (void __user *) arg, sizeof(req32)))
+		return -EFAULT;
+
+	request = compat_alloc_user_space(sizeof(*request));
+	if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
+	    || __put_user(req32.idx, &request->idx)
+	    || __put_user(req32.discard, &request->discard)
+	    || __put_user(req32.nr_states, &request->nr_states)
+	    || __put_user((void __user *)(unsigned long)req32.state,
+			  &request->state)
+	    || __put_user(req32.nr_prims, &request->nr_prims)
+	    || __put_user((void __user *)(unsigned long)req32.prim,
+			  &request->prim))
+		return -EFAULT;
+
+	return drm_ioctl(file->f_dentry->d_inode, file,
+			 DRM_IOCTL_RADEON_VERTEX2, (unsigned long) request);
+}
+
+typedef struct drm_radeon_cmd_buffer32 {
+	int bufsz;
+	u32 buf;
+	int nbox;
+	u32 boxes;
+} drm_radeon_cmd_buffer32_t;
+
+static int compat_radeon_cp_cmdbuf(struct file *file, unsigned int cmd,
+				   unsigned long arg)
+{
+	drm_radeon_cmd_buffer32_t req32;
+	drm_radeon_cmd_buffer_t __user *request;
+
+	if (copy_from_user(&req32, (void __user *) arg, sizeof(req32)))
+		return -EFAULT;
+
+	request = compat_alloc_user_space(sizeof(*request));
+	if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
+	    || __put_user(req32.bufsz, &request->bufsz)
+	    || __put_user((void __user *)(unsigned long)req32.buf,
+			  &request->buf)
+	    || __put_user(req32.nbox, &request->nbox)
+	    || __put_user((void __user *)(unsigned long)req32.boxes,
+			  &request->boxes))
+		return -EFAULT;
+
+	return drm_ioctl(file->f_dentry->d_inode, file,
+			 DRM_IOCTL_RADEON_CMDBUF, (unsigned long) request);
+}
+
+typedef struct drm_radeon_getparam32 {
+	int param;
+	u32 value;
+} drm_radeon_getparam32_t;
+
+static int compat_radeon_cp_getparam(struct file *file, unsigned int cmd,
+				     unsigned long arg)
+{
+	drm_radeon_getparam32_t req32;
+	drm_radeon_getparam_t __user *request;
+
+	if (copy_from_user(&req32, (void __user *) arg, sizeof(req32)))
+		return -EFAULT;
+
+	request = compat_alloc_user_space(sizeof(*request));
+	if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
+	    || __put_user(req32.param, &request->param)
+	    || __put_user((void __user *)(unsigned long)req32.value,
+			  &request->value))
+		return -EFAULT;
+
+	return drm_ioctl(file->f_dentry->d_inode, file,
+			 DRM_IOCTL_RADEON_GETPARAM, (unsigned long) request);
+}
+
+typedef struct drm_radeon_mem_alloc32 {
+	int region;
+	int alignment;
+	int size;
+	u32 region_offset;	/* offset from start of fb or GART */
+} drm_radeon_mem_alloc32_t;
+
+static int compat_radeon_mem_alloc(struct file *file, unsigned int cmd,
+				   unsigned long arg)
+{
+	drm_radeon_mem_alloc32_t req32;
+	drm_radeon_mem_alloc_t __user *request;
+
+	if (copy_from_user(&req32, (void __user *) arg, sizeof(req32)))
+		return -EFAULT;
+
+	request = compat_alloc_user_space(sizeof(*request));
+	if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
+	    || __put_user(req32.region, &request->region)
+	    || __put_user(req32.alignment, &request->alignment)
+	    || __put_user(req32.size, &request->size)
+	    || __put_user((int __user *)(unsigned long)req32.region_offset,
+			  &request->region_offset))
+		return -EFAULT;
+
+	return drm_ioctl(file->f_dentry->d_inode, file,
+			 DRM_IOCTL_RADEON_ALLOC, (unsigned long) request);
+}
+
+typedef struct drm_radeon_irq_emit32 {
+	u32 irq_seq;
+} drm_radeon_irq_emit32_t;
+
+static int compat_radeon_irq_emit(struct file *file, unsigned int cmd,
+				  unsigned long arg)
+{
+	drm_radeon_irq_emit32_t req32;
+	drm_radeon_irq_emit_t __user *request;
+
+	if (copy_from_user(&req32, (void __user *) arg, sizeof(req32)))
+		return -EFAULT;
+
+	request = compat_alloc_user_space(sizeof(*request));
+	if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
+	    || __put_user((int __user *)(unsigned long)req32.irq_seq,
+			  &request->irq_seq))
+		return -EFAULT;
+
+	return drm_ioctl(file->f_dentry->d_inode, file,
+			 DRM_IOCTL_RADEON_IRQ_EMIT, (unsigned long) request);
+}
+
+drm_ioctl_compat_t *radeon_compat_ioctls[] = {
+	[DRM_RADEON_CP_INIT] = compat_radeon_cp_init,
+	[DRM_RADEON_CLEAR] = compat_radeon_cp_clear,
+	[DRM_RADEON_STIPPLE] = compat_radeon_cp_stipple,
+	[DRM_RADEON_TEXTURE] = compat_radeon_cp_texture,
+	[DRM_RADEON_VERTEX2] = compat_radeon_cp_vertex2,
+	[DRM_RADEON_CMDBUF] = compat_radeon_cp_cmdbuf,
+	[DRM_RADEON_GETPARAM] = compat_radeon_cp_getparam,
+	[DRM_RADEON_ALLOC] = compat_radeon_mem_alloc,
+	[DRM_RADEON_IRQ_EMIT] = compat_radeon_irq_emit,
+};
+
+/**
+ * Called whenever a 32-bit process running under a 64-bit kernel
+ * performs an ioctl on /dev/dri/card<n>.
+ *
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg user argument.
+ * \return zero on success or negative number on failure.
+ */
+long radeon_compat_ioctl(struct file *filp, unsigned int cmd,
+			 unsigned long arg)
+{
+	unsigned int nr = DRM_IOCTL_NR(cmd);
+	drm_ioctl_compat_t *fn = NULL;
+	int ret;
+
+	if (nr < DRM_COMMAND_BASE)
+		return drm_compat_ioctl(filp, cmd, arg);
+
+	if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(radeon_compat_ioctls))
+		fn = radeon_compat_ioctls[nr - DRM_COMMAND_BASE];
+
+	lock_kernel();		/* XXX for now */
+	if (fn != NULL)
+		ret = (*fn)(filp, cmd, arg);
+	else
+		ret = drm_ioctl(filp->f_dentry->d_inode, filp, cmd, arg);
+	unlock_kernel();
+
+	return ret;
+}
diff --git a/drivers/char/drm/radeon_irq.c b/drivers/char/drm/radeon_irq.c
--- a/drivers/char/drm/radeon_irq.c
+++ b/drivers/char/drm/radeon_irq.c
@@ -35,6 +35,14 @@
 #include "radeon_drm.h"
 #include "radeon_drv.h"
 
+static __inline__ u32 radeon_acknowledge_irqs(drm_radeon_private_t *dev_priv, u32 mask)
+{
+	u32 irqs = RADEON_READ(RADEON_GEN_INT_STATUS) & mask;
+	if (irqs)
+		RADEON_WRITE(RADEON_GEN_INT_STATUS, irqs);
+	return irqs;
+}
+
 /* Interrupts - Used for device synchronization and flushing in the
  * following circumstances:
  *
@@ -63,8 +71,8 @@ irqreturn_t radeon_driver_irq_handler( D
 	/* Only consider the bits we're interested in - others could be used
 	 * outside the DRM
 	 */
-	stat = RADEON_READ(RADEON_GEN_INT_STATUS)
-	     & (RADEON_SW_INT_TEST | RADEON_CRTC_VBLANK_STAT);
+	stat = radeon_acknowledge_irqs(dev_priv, (RADEON_SW_INT_TEST_ACK | 
+						  RADEON_CRTC_VBLANK_STAT));
 	if (!stat)
 		return IRQ_NONE;
 
@@ -80,19 +88,9 @@ irqreturn_t radeon_driver_irq_handler( D
 		drm_vbl_send_signals( dev );
 	}
 
-	/* Acknowledge interrupts we handle */
-	RADEON_WRITE(RADEON_GEN_INT_STATUS, stat);
 	return IRQ_HANDLED;
 }
 
-static __inline__ void radeon_acknowledge_irqs(drm_radeon_private_t *dev_priv)
-{
-	u32 tmp = RADEON_READ( RADEON_GEN_INT_STATUS )
-		& (RADEON_SW_INT_TEST_ACK | RADEON_CRTC_VBLANK_STAT);
-	if (tmp)
-		RADEON_WRITE( RADEON_GEN_INT_STATUS, tmp );
-}
-
 static int radeon_emit_irq(drm_device_t *dev)
 {
 	drm_radeon_private_t *dev_priv = dev->dev_private;
@@ -141,7 +139,7 @@ int radeon_driver_vblank_wait(drm_device
 		return DRM_ERR(EINVAL);
 	}
 
-	radeon_acknowledge_irqs( dev_priv );
+	radeon_acknowledge_irqs(dev_priv, RADEON_CRTC_VBLANK_STAT);
 
 	dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
 
@@ -219,7 +217,8 @@ void radeon_driver_irq_preinstall( drm_d
       	RADEON_WRITE( RADEON_GEN_INT_CNTL, 0 );
 
 	/* Clear bits if they're already high */
-	radeon_acknowledge_irqs( dev_priv );
+	radeon_acknowledge_irqs(dev_priv, (RADEON_SW_INT_TEST_ACK |
+					   RADEON_CRTC_VBLANK_STAT));
 }
 
 void radeon_driver_irq_postinstall( drm_device_t *dev ) {
diff --git a/drivers/char/drm/via_3d_reg.h b/drivers/char/drm/via_3d_reg.h
new file mode 100644
--- /dev/null
+++ b/drivers/char/drm/via_3d_reg.h
@@ -0,0 +1,1651 @@
+/*
+ * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2003 S3 Graphics, Inc. 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, sub license,
+ * 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 NON-INFRINGEMENT. IN NO EVENT SHALL
+ * VIA, S3 GRAPHICS, 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.
+ */
+
+#ifndef VIA_3D_REG_H
+#define VIA_3D_REG_H
+#define HC_REG_BASE             0x0400
+
+#define HC_REG_TRANS_SPACE      0x0040
+
+#define HC_ParaN_MASK           0xffffffff
+#define HC_Para_MASK            0x00ffffff
+#define HC_SubA_MASK            0xff000000
+#define HC_SubA_SHIFT           24
+/* Transmission Setting
+ */
+#define HC_REG_TRANS_SET        0x003c
+#define HC_ParaSubType_MASK     0xff000000
+#define HC_ParaType_MASK        0x00ff0000
+#define HC_ParaOS_MASK          0x0000ff00
+#define HC_ParaAdr_MASK         0x000000ff
+#define HC_ParaSubType_SHIFT    24
+#define HC_ParaType_SHIFT       16
+#define HC_ParaOS_SHIFT         8
+#define HC_ParaAdr_SHIFT        0
+
+#define HC_ParaType_CmdVdata    0x0000
+#define HC_ParaType_NotTex      0x0001
+#define HC_ParaType_Tex         0x0002
+#define HC_ParaType_Palette     0x0003
+#define HC_ParaType_PreCR       0x0010
+#define HC_ParaType_Auto        0x00fe
+
+/* Transmission Space
+ */
+#define HC_REG_Hpara0           0x0040
+#define HC_REG_HpataAF          0x02fc
+
+/* Read
+ */
+#define HC_REG_HREngSt          0x0000
+#define HC_REG_HRFIFOempty      0x0004
+#define HC_REG_HRFIFOfull       0x0008
+#define HC_REG_HRErr            0x000c
+#define HC_REG_FIFOstatus       0x0010
+/* HC_REG_HREngSt          0x0000
+ */
+#define HC_HDASZC_MASK          0x00010000
+#define HC_HSGEMI_MASK          0x0000f000
+#define HC_HLGEMISt_MASK        0x00000f00
+#define HC_HCRSt_MASK           0x00000080
+#define HC_HSE0St_MASK          0x00000040
+#define HC_HSE1St_MASK          0x00000020
+#define HC_HPESt_MASK           0x00000010
+#define HC_HXESt_MASK           0x00000008
+#define HC_HBESt_MASK           0x00000004
+#define HC_HE2St_MASK           0x00000002
+#define HC_HE3St_MASK           0x00000001
+/* HC_REG_HRFIFOempty      0x0004
+ */
+#define HC_HRZDempty_MASK       0x00000010
+#define HC_HRTXAempty_MASK      0x00000008
+#define HC_HRTXDempty_MASK      0x00000004
+#define HC_HWZDempty_MASK       0x00000002
+#define HC_HWCDempty_MASK       0x00000001
+/* HC_REG_HRFIFOfull       0x0008
+ */
+#define HC_HRZDfull_MASK        0x00000010
+#define HC_HRTXAfull_MASK       0x00000008
+#define HC_HRTXDfull_MASK       0x00000004
+#define HC_HWZDfull_MASK        0x00000002
+#define HC_HWCDfull_MASK        0x00000001
+/* HC_REG_HRErr            0x000c
+ */
+#define HC_HAGPCMErr_MASK       0x80000000
+#define HC_HAGPCMErrC_MASK      0x70000000
+/* HC_REG_FIFOstatus       0x0010
+ */
+#define HC_HRFIFOATall_MASK     0x80000000
+#define HC_HRFIFOATbusy_MASK    0x40000000
+#define HC_HRATFGMDo_MASK       0x00000100
+#define HC_HRATFGMDi_MASK       0x00000080
+#define HC_HRATFRZD_MASK        0x00000040
+#define HC_HRATFRTXA_MASK       0x00000020
+#define HC_HRATFRTXD_MASK       0x00000010
+#define HC_HRATFWZD_MASK        0x00000008
+#define HC_HRATFWCD_MASK        0x00000004
+#define HC_HRATTXTAG_MASK       0x00000002
+#define HC_HRATTXCH_MASK        0x00000001
+
+/* AGP Command Setting
+ */
+#define HC_SubA_HAGPBstL        0x0060
+#define HC_SubA_HAGPBendL       0x0061
+#define HC_SubA_HAGPCMNT        0x0062
+#define HC_SubA_HAGPBpL         0x0063
+#define HC_SubA_HAGPBpH         0x0064
+/* HC_SubA_HAGPCMNT        0x0062
+ */
+#define HC_HAGPCMNT_MASK        0x00800000
+#define HC_HCmdErrClr_MASK      0x00400000
+#define HC_HAGPBendH_MASK       0x0000ff00
+#define HC_HAGPBstH_MASK        0x000000ff
+#define HC_HAGPBendH_SHIFT      8
+#define HC_HAGPBstH_SHIFT       0
+/* HC_SubA_HAGPBpL         0x0063
+ */
+#define HC_HAGPBpL_MASK         0x00fffffc
+#define HC_HAGPBpID_MASK        0x00000003
+#define HC_HAGPBpID_PAUSE       0x00000000
+#define HC_HAGPBpID_JUMP        0x00000001
+#define HC_HAGPBpID_STOP        0x00000002
+/* HC_SubA_HAGPBpH         0x0064
+ */
+#define HC_HAGPBpH_MASK         0x00ffffff
+
+/* Miscellaneous Settings
+ */
+#define HC_SubA_HClipTB         0x0070
+#define HC_SubA_HClipLR         0x0071
+#define HC_SubA_HFPClipTL       0x0072
+#define HC_SubA_HFPClipBL       0x0073
+#define HC_SubA_HFPClipLL       0x0074
+#define HC_SubA_HFPClipRL       0x0075
+#define HC_SubA_HFPClipTBH      0x0076
+#define HC_SubA_HFPClipLRH      0x0077
+#define HC_SubA_HLP             0x0078
+#define HC_SubA_HLPRF           0x0079
+#define HC_SubA_HSolidCL        0x007a
+#define HC_SubA_HPixGC          0x007b
+#define HC_SubA_HSPXYOS         0x007c
+#define HC_SubA_HVertexCNT      0x007d
+
+#define HC_HClipT_MASK          0x00fff000
+#define HC_HClipT_SHIFT         12
+#define HC_HClipB_MASK          0x00000fff
+#define HC_HClipB_SHIFT         0
+#define HC_HClipL_MASK          0x00fff000
+#define HC_HClipL_SHIFT         12
+#define HC_HClipR_MASK          0x00000fff
+#define HC_HClipR_SHIFT         0
+#define HC_HFPClipBH_MASK       0x0000ff00
+#define HC_HFPClipBH_SHIFT      8
+#define HC_HFPClipTH_MASK       0x000000ff
+#define HC_HFPClipTH_SHIFT      0
+#define HC_HFPClipRH_MASK       0x0000ff00
+#define HC_HFPClipRH_SHIFT      8
+#define HC_HFPClipLH_MASK       0x000000ff
+#define HC_HFPClipLH_SHIFT      0
+#define HC_HSolidCH_MASK        0x000000ff
+#define HC_HPixGC_MASK          0x00800000
+#define HC_HSPXOS_MASK          0x00fff000
+#define HC_HSPXOS_SHIFT         12
+#define HC_HSPYOS_MASK          0x00000fff
+
+/* Command
+ * Command A
+ */
+#define HC_HCmdHeader_MASK      0xfe000000	/*0xffe00000 */
+#define HC_HE3Fire_MASK         0x00100000
+#define HC_HPMType_MASK         0x000f0000
+#define HC_HEFlag_MASK          0x0000e000
+#define HC_HShading_MASK        0x00001c00
+#define HC_HPMValidN_MASK       0x00000200
+#define HC_HPLEND_MASK          0x00000100
+#define HC_HVCycle_MASK         0x000000ff
+#define HC_HVCycle_Style_MASK   0x000000c0
+#define HC_HVCycle_ChgA_MASK    0x00000030
+#define HC_HVCycle_ChgB_MASK    0x0000000c
+#define HC_HVCycle_ChgC_MASK    0x00000003
+#define HC_HPMType_Point        0x00000000
+#define HC_HPMType_Line         0x00010000
+#define HC_HPMType_Tri          0x00020000
+#define HC_HPMType_TriWF        0x00040000
+#define HC_HEFlag_NoAA          0x00000000
+#define HC_HEFlag_ab            0x00008000
+#define HC_HEFlag_bc            0x00004000
+#define HC_HEFlag_ca            0x00002000
+#define HC_HShading_Solid       0x00000000
+#define HC_HShading_FlatA       0x00000400
+#define HC_HShading_FlatB       0x00000800
+#define HC_HShading_FlatC       0x00000c00
+#define HC_HShading_Gouraud     0x00001000
+#define HC_HVCycle_Full         0x00000000
+#define HC_HVCycle_AFP          0x00000040
+#define HC_HVCycle_One          0x000000c0
+#define HC_HVCycle_NewA         0x00000000
+#define HC_HVCycle_AA           0x00000010
+#define HC_HVCycle_AB           0x00000020
+#define HC_HVCycle_AC           0x00000030
+#define HC_HVCycle_NewB         0x00000000
+#define HC_HVCycle_BA           0x00000004
+#define HC_HVCycle_BB           0x00000008
+#define HC_HVCycle_BC           0x0000000c
+#define HC_HVCycle_NewC         0x00000000
+#define HC_HVCycle_CA           0x00000001
+#define HC_HVCycle_CB           0x00000002
+#define HC_HVCycle_CC           0x00000003
+
+/* Command B
+ */
+#define HC_HLPrst_MASK          0x00010000
+#define HC_HLLastP_MASK         0x00008000
+#define HC_HVPMSK_MASK          0x00007f80
+#define HC_HBFace_MASK          0x00000040
+#define HC_H2nd1VT_MASK         0x0000003f
+#define HC_HVPMSK_X             0x00004000
+#define HC_HVPMSK_Y             0x00002000
+#define HC_HVPMSK_Z             0x00001000
+#define HC_HVPMSK_W             0x00000800
+#define HC_HVPMSK_Cd            0x00000400
+#define HC_HVPMSK_Cs            0x00000200
+#define HC_HVPMSK_S             0x00000100
+#define HC_HVPMSK_T             0x00000080
+
+/* Enable Setting
+ */
+#define HC_SubA_HEnable         0x0000
+#define HC_HenTXEnvMap_MASK     0x00200000
+#define HC_HenVertexCNT_MASK    0x00100000
+#define HC_HenCPUDAZ_MASK       0x00080000
+#define HC_HenDASZWC_MASK       0x00040000
+#define HC_HenFBCull_MASK       0x00020000
+#define HC_HenCW_MASK           0x00010000
+#define HC_HenAA_MASK           0x00008000
+#define HC_HenST_MASK           0x00004000
+#define HC_HenZT_MASK           0x00002000
+#define HC_HenZW_MASK           0x00001000
+#define HC_HenAT_MASK           0x00000800
+#define HC_HenAW_MASK           0x00000400
+#define HC_HenSP_MASK           0x00000200
+#define HC_HenLP_MASK           0x00000100
+#define HC_HenTXCH_MASK         0x00000080
+#define HC_HenTXMP_MASK         0x00000040
+#define HC_HenTXPP_MASK         0x00000020
+#define HC_HenTXTR_MASK         0x00000010
+#define HC_HenCS_MASK           0x00000008
+#define HC_HenFOG_MASK          0x00000004
+#define HC_HenABL_MASK          0x00000002
+#define HC_HenDT_MASK           0x00000001
+
+/* Z Setting
+ */
+#define HC_SubA_HZWBBasL        0x0010
+#define HC_SubA_HZWBBasH        0x0011
+#define HC_SubA_HZWBType        0x0012
+#define HC_SubA_HZBiasL         0x0013
+#define HC_SubA_HZWBend         0x0014
+#define HC_SubA_HZWTMD          0x0015
+#define HC_SubA_HZWCDL          0x0016
+#define HC_SubA_HZWCTAGnum      0x0017
+#define HC_SubA_HZCYNum         0x0018
+#define HC_SubA_HZWCFire        0x0019
+/* HC_SubA_HZWBType
+ */
+#define HC_HZWBType_MASK        0x00800000
+#define HC_HZBiasedWB_MASK      0x00400000
+#define HC_HZONEasFF_MASK       0x00200000
+#define HC_HZOONEasFF_MASK      0x00100000
+#define HC_HZWBFM_MASK          0x00030000
+#define HC_HZWBLoc_MASK         0x0000c000
+#define HC_HZWBPit_MASK         0x00003fff
+#define HC_HZWBFM_16            0x00000000
+#define HC_HZWBFM_32            0x00020000
+#define HC_HZWBFM_24            0x00030000
+#define HC_HZWBLoc_Local        0x00000000
+#define HC_HZWBLoc_SyS          0x00004000
+/* HC_SubA_HZWBend
+ */
+#define HC_HZWBend_MASK         0x00ffe000
+#define HC_HZBiasH_MASK         0x000000ff
+#define HC_HZWBend_SHIFT        10
+/* HC_SubA_HZWTMD
+ */
+#define HC_HZWTMD_MASK          0x00070000
+#define HC_HEBEBias_MASK        0x00007f00
+#define HC_HZNF_MASK            0x000000ff
+#define HC_HZWTMD_NeverPass     0x00000000
+#define HC_HZWTMD_LT            0x00010000
+#define HC_HZWTMD_EQ            0x00020000
+#define HC_HZWTMD_LE            0x00030000
+#define HC_HZWTMD_GT            0x00040000
+#define HC_HZWTMD_NE            0x00050000
+#define HC_HZWTMD_GE            0x00060000
+#define HC_HZWTMD_AllPass       0x00070000
+#define HC_HEBEBias_SHIFT       8
+/* HC_SubA_HZWCDL          0x0016
+ */
+#define HC_HZWCDL_MASK          0x00ffffff
+/* HC_SubA_HZWCTAGnum      0x0017
+ */
+#define HC_HZWCTAGnum_MASK      0x00ff0000
+#define HC_HZWCTAGnum_SHIFT     16
+#define HC_HZWCDH_MASK          0x000000ff
+#define HC_HZWCDH_SHIFT         0
+/* HC_SubA_HZCYNum         0x0018
+ */
+#define HC_HZCYNum_MASK         0x00030000
+#define HC_HZCYNum_SHIFT        16
+#define HC_HZWCQWnum_MASK       0x00003fff
+#define HC_HZWCQWnum_SHIFT      0
+/* HC_SubA_HZWCFire        0x0019
+ */
+#define HC_ZWCFire_MASK         0x00010000
+#define HC_HZWCQWnumLast_MASK   0x00003fff
+#define HC_HZWCQWnumLast_SHIFT  0
+
+/* Stencil Setting
+ */
+#define HC_SubA_HSTREF          0x0023
+#define HC_SubA_HSTMD           0x0024
+/* HC_SubA_HSBFM
+ */
+#define HC_HSBFM_MASK           0x00030000
+#define HC_HSBLoc_MASK          0x0000c000
+#define HC_HSBPit_MASK          0x00003fff
+/* HC_SubA_HSTREF
+ */
+#define HC_HSTREF_MASK          0x00ff0000
+#define HC_HSTOPMSK_MASK        0x0000ff00
+#define HC_HSTBMSK_MASK         0x000000ff
+#define HC_HSTREF_SHIFT         16
+#define HC_HSTOPMSK_SHIFT       8
+/* HC_SubA_HSTMD
+ */
+#define HC_HSTMD_MASK           0x00070000
+#define HC_HSTOPSF_MASK         0x000001c0
+#define HC_HSTOPSPZF_MASK       0x00000038
+#define HC_HSTOPSPZP_MASK       0x00000007
+#define HC_HSTMD_NeverPass      0x00000000
+#define HC_HSTMD_LT             0x00010000
+#define HC_HSTMD_EQ             0x00020000
+#define HC_HSTMD_LE             0x00030000
+#define HC_HSTMD_GT             0x00040000
+#define HC_HSTMD_NE             0x00050000
+#define HC_HSTMD_GE             0x00060000
+#define HC_HSTMD_AllPass        0x00070000
+#define HC_HSTOPSF_KEEP         0x00000000
+#define HC_HSTOPSF_ZERO         0x00000040
+#define HC_HSTOPSF_REPLACE      0x00000080
+#define HC_HSTOPSF_INCRSAT      0x000000c0
+#define HC_HSTOPSF_DECRSAT      0x00000100
+#define HC_HSTOPSF_INVERT       0x00000140
+#define HC_HSTOPSF_INCR         0x00000180
+#define HC_HSTOPSF_DECR         0x000001c0
+#define HC_HSTOPSPZF_KEEP       0x00000000
+#define HC_HSTOPSPZF_ZERO       0x00000008
+#define HC_HSTOPSPZF_REPLACE    0x00000010
+#define HC_HSTOPSPZF_INCRSAT    0x00000018
+#define HC_HSTOPSPZF_DECRSAT    0x00000020
+#define HC_HSTOPSPZF_INVERT     0x00000028
+#define HC_HSTOPSPZF_INCR       0x00000030
+#define HC_HSTOPSPZF_DECR       0x00000038
+#define HC_HSTOPSPZP_KEEP       0x00000000
+#define HC_HSTOPSPZP_ZERO       0x00000001
+#define HC_HSTOPSPZP_REPLACE    0x00000002
+#define HC_HSTOPSPZP_INCRSAT    0x00000003
+#define HC_HSTOPSPZP_DECRSAT    0x00000004
+#define HC_HSTOPSPZP_INVERT     0x00000005
+#define HC_HSTOPSPZP_INCR       0x00000006
+#define HC_HSTOPSPZP_DECR       0x00000007
+
+/* Alpha Setting
+ */
+#define HC_SubA_HABBasL         0x0030
+#define HC_SubA_HABBasH         0x0031
+#define HC_SubA_HABFM           0x0032
+#define HC_SubA_HATMD           0x0033
+#define HC_SubA_HABLCsat        0x0034
+#define HC_SubA_HABLCop         0x0035
+#define HC_SubA_HABLAsat        0x0036
+#define HC_SubA_HABLAop         0x0037
+#define HC_SubA_HABLRCa         0x0038
+#define HC_SubA_HABLRFCa        0x0039
+#define HC_SubA_HABLRCbias      0x003a
+#define HC_SubA_HABLRCb         0x003b
+#define HC_SubA_HABLRFCb        0x003c
+#define HC_SubA_HABLRAa         0x003d
+#define HC_SubA_HABLRAb         0x003e
+/* HC_SubA_HABFM
+ */
+#define HC_HABFM_MASK           0x00030000
+#define HC_HABLoc_MASK          0x0000c000
+#define HC_HABPit_MASK          0x000007ff
+/* HC_SubA_HATMD
+ */
+#define HC_HATMD_MASK           0x00000700
+#define HC_HATREF_MASK          0x000000ff
+#define HC_HATMD_NeverPass      0x00000000
+#define HC_HATMD_LT             0x00000100
+#define HC_HATMD_EQ             0x00000200
+#define HC_HATMD_LE             0x00000300
+#define HC_HATMD_GT             0x00000400
+#define HC_HATMD_NE             0x00000500
+#define HC_HATMD_GE             0x00000600
+#define HC_HATMD_AllPass        0x00000700
+/* HC_SubA_HABLCsat
+ */
+#define HC_HABLCsat_MASK        0x00010000
+#define HC_HABLCa_MASK          0x0000fc00
+#define HC_HABLCa_C_MASK        0x0000c000
+#define HC_HABLCa_OPC_MASK      0x00003c00
+#define HC_HABLFCa_MASK         0x000003f0
+#define HC_HABLFCa_C_MASK       0x00000300
+#define HC_HABLFCa_OPC_MASK     0x000000f0
+#define HC_HABLCbias_MASK       0x0000000f
+#define HC_HABLCbias_C_MASK     0x00000008
+#define HC_HABLCbias_OPC_MASK   0x00000007
+/*-- Define the input color.
+ */
+#define HC_XC_Csrc              0x00000000
+#define HC_XC_Cdst              0x00000001
+#define HC_XC_Asrc              0x00000002
+#define HC_XC_Adst              0x00000003
+#define HC_XC_Fog               0x00000004
+#define HC_XC_HABLRC            0x00000005
+#define HC_XC_minSrcDst         0x00000006
+#define HC_XC_maxSrcDst         0x00000007
+#define HC_XC_mimAsrcInvAdst    0x00000008
+#define HC_XC_OPC               0x00000000
+#define HC_XC_InvOPC            0x00000010
+#define HC_XC_OPCp5             0x00000020
+/*-- Define the input Alpha
+ */
+#define HC_XA_OPA               0x00000000
+#define HC_XA_InvOPA            0x00000010
+#define HC_XA_OPAp5             0x00000020
+#define HC_XA_0                 0x00000000
+#define HC_XA_Asrc              0x00000001
+#define HC_XA_Adst              0x00000002
+#define HC_XA_Fog               0x00000003
+#define HC_XA_minAsrcFog        0x00000004
+#define HC_XA_minAsrcAdst       0x00000005
+#define HC_XA_maxAsrcFog        0x00000006
+#define HC_XA_maxAsrcAdst       0x00000007
+#define HC_XA_HABLRA            0x00000008
+#define HC_XA_minAsrcInvAdst    0x00000008
+#define HC_XA_HABLFRA           0x00000009
+/*--
+ */
+#define HC_HABLCa_OPC           (HC_XC_OPC << 10)
+#define HC_HABLCa_InvOPC        (HC_XC_InvOPC << 10)
+#define HC_HABLCa_OPCp5         (HC_XC_OPCp5 << 10)
+#define HC_HABLCa_Csrc          (HC_XC_Csrc << 10)
+#define HC_HABLCa_Cdst          (HC_XC_Cdst << 10)
+#define HC_HABLCa_Asrc          (HC_XC_Asrc << 10)
+#define HC_HABLCa_Adst          (HC_XC_Adst << 10)
+#define HC_HABLCa_Fog           (HC_XC_Fog << 10)
+#define HC_HABLCa_HABLRCa       (HC_XC_HABLRC << 10)
+#define HC_HABLCa_minSrcDst     (HC_XC_minSrcDst << 10)
+#define HC_HABLCa_maxSrcDst     (HC_XC_maxSrcDst << 10)
+#define HC_HABLFCa_OPC              (HC_XC_OPC << 4)
+#define HC_HABLFCa_InvOPC           (HC_XC_InvOPC << 4)
+#define HC_HABLFCa_OPCp5            (HC_XC_OPCp5 << 4)
+#define HC_HABLFCa_Csrc             (HC_XC_Csrc << 4)
+#define HC_HABLFCa_Cdst             (HC_XC_Cdst << 4)
+#define HC_HABLFCa_Asrc             (HC_XC_Asrc << 4)
+#define HC_HABLFCa_Adst             (HC_XC_Adst << 4)
+#define HC_HABLFCa_Fog              (HC_XC_Fog << 4)
+#define HC_HABLFCa_HABLRCa          (HC_XC_HABLRC << 4)
+#define HC_HABLFCa_minSrcDst        (HC_XC_minSrcDst << 4)
+#define HC_HABLFCa_maxSrcDst        (HC_XC_maxSrcDst << 4)
+#define HC_HABLFCa_mimAsrcInvAdst   (HC_XC_mimAsrcInvAdst << 4)
+#define HC_HABLCbias_HABLRCbias 0x00000000
+#define HC_HABLCbias_Asrc       0x00000001
+#define HC_HABLCbias_Adst       0x00000002
+#define HC_HABLCbias_Fog        0x00000003
+#define HC_HABLCbias_Cin        0x00000004
+/* HC_SubA_HABLCop         0x0035
+ */
+#define HC_HABLdot_MASK         0x00010000
+#define HC_HABLCop_MASK         0x00004000
+#define HC_HABLCb_MASK          0x00003f00
+#define HC_HABLCb_C_MASK        0x00003000
+#define HC_HABLCb_OPC_MASK      0x00000f00
+#define HC_HABLFCb_MASK         0x000000fc
+#define HC_HABLFCb_C_MASK       0x000000c0
+#define HC_HABLFCb_OPC_MASK     0x0000003c
+#define HC_HABLCshift_MASK      0x00000003
+#define HC_HABLCb_OPC           (HC_XC_OPC << 8)
+#define HC_HABLCb_InvOPC        (HC_XC_InvOPC << 8)
+#define HC_HABLCb_OPCp5         (HC_XC_OPCp5 << 8)
+#define HC_HABLCb_Csrc          (HC_XC_Csrc << 8)
+#define HC_HABLCb_Cdst          (HC_XC_Cdst << 8)
+#define HC_HABLCb_Asrc          (HC_XC_Asrc << 8)
+#define HC_HABLCb_Adst          (HC_XC_Adst << 8)
+#define HC_HABLCb_Fog           (HC_XC_Fog << 8)
+#define HC_HABLCb_HABLRCa       (HC_XC_HABLRC << 8)
+#define HC_HABLCb_minSrcDst     (HC_XC_minSrcDst << 8)
+#define HC_HABLCb_maxSrcDst     (HC_XC_maxSrcDst << 8)
+#define HC_HABLFCb_OPC              (HC_XC_OPC << 2)
+#define HC_HABLFCb_InvOPC           (HC_XC_InvOPC << 2)
+#define HC_HABLFCb_OPCp5            (HC_XC_OPCp5 << 2)
+#define HC_HABLFCb_Csrc             (HC_XC_Csrc << 2)
+#define HC_HABLFCb_Cdst             (HC_XC_Cdst << 2)
+#define HC_HABLFCb_Asrc             (HC_XC_Asrc << 2)
+#define HC_HABLFCb_Adst             (HC_XC_Adst << 2)
+#define HC_HABLFCb_Fog              (HC_XC_Fog << 2)
+#define HC_HABLFCb_HABLRCb          (HC_XC_HABLRC << 2)
+#define HC_HABLFCb_minSrcDst        (HC_XC_minSrcDst << 2)
+#define HC_HABLFCb_maxSrcDst        (HC_XC_maxSrcDst << 2)
+#define HC_HABLFCb_mimAsrcInvAdst   (HC_XC_mimAsrcInvAdst << 2)
+/* HC_SubA_HABLAsat        0x0036
+ */
+#define HC_HABLAsat_MASK        0x00010000
+#define HC_HABLAa_MASK          0x0000fc00
+#define HC_HABLAa_A_MASK        0x0000c000
+#define HC_HABLAa_OPA_MASK      0x00003c00
+#define HC_HABLFAa_MASK         0x000003f0
+#define HC_HABLFAa_A_MASK       0x00000300
+#define HC_HABLFAa_OPA_MASK     0x000000f0
+#define HC_HABLAbias_MASK       0x0000000f
+#define HC_HABLAbias_A_MASK     0x00000008
+#define HC_HABLAbias_OPA_MASK   0x00000007
+#define HC_HABLAa_OPA           (HC_XA_OPA << 10)
+#define HC_HABLAa_InvOPA        (HC_XA_InvOPA << 10)
+#define HC_HABLAa_OPAp5         (HC_XA_OPAp5 << 10)
+#define HC_HABLAa_0             (HC_XA_0 << 10)
+#define HC_HABLAa_Asrc          (HC_XA_Asrc << 10)
+#define HC_HABLAa_Adst          (HC_XA_Adst << 10)
+#define HC_HABLAa_Fog           (HC_XA_Fog << 10)
+#define HC_HABLAa_minAsrcFog    (HC_XA_minAsrcFog << 10)
+#define HC_HABLAa_minAsrcAdst   (HC_XA_minAsrcAdst << 10)
+#define HC_HABLAa_maxAsrcFog    (HC_XA_maxAsrcFog << 10)
+#define HC_HABLAa_maxAsrcAdst   (HC_XA_maxAsrcAdst << 10)
+#define HC_HABLAa_HABLRA        (HC_XA_HABLRA << 10)
+#define HC_HABLFAa_OPA          (HC_XA_OPA << 4)
+#define HC_HABLFAa_InvOPA       (HC_XA_InvOPA << 4)
+#define HC_HABLFAa_OPAp5        (HC_XA_OPAp5 << 4)
+#define HC_HABLFAa_0            (HC_XA_0 << 4)
+#define HC_HABLFAa_Asrc         (HC_XA_Asrc << 4)
+#define HC_HABLFAa_Adst         (HC_XA_Adst << 4)
+#define HC_HABLFAa_Fog          (HC_XA_Fog << 4)
+#define HC_HABLFAa_minAsrcFog   (HC_XA_minAsrcFog << 4)
+#define HC_HABLFAa_minAsrcAdst  (HC_XA_minAsrcAdst << 4)
+#define HC_HABLFAa_maxAsrcFog   (HC_XA_maxAsrcFog << 4)
+#define HC_HABLFAa_maxAsrcAdst  (HC_XA_maxAsrcAdst << 4)
+#define HC_HABLFAa_minAsrcInvAdst   (HC_XA_minAsrcInvAdst << 4)
+#define HC_HABLFAa_HABLFRA          (HC_XA_HABLFRA << 4)
+#define HC_HABLAbias_HABLRAbias 0x00000000
+#define HC_HABLAbias_Asrc       0x00000001
+#define HC_HABLAbias_Adst       0x00000002
+#define HC_HABLAbias_Fog        0x00000003
+#define HC_HABLAbias_Aaa        0x00000004
+/* HC_SubA_HABLAop         0x0037
+ */
+#define HC_HABLAop_MASK         0x00004000
+#define HC_HABLAb_MASK          0x00003f00
+#define HC_HABLAb_OPA_MASK      0x00000f00
+#define HC_HABLFAb_MASK         0x000000fc
+#define HC_HABLFAb_OPA_MASK     0x0000003c
+#define HC_HABLAshift_MASK      0x00000003
+#define HC_HABLAb_OPA           (HC_XA_OPA << 8)
+#define HC_HABLAb_InvOPA        (HC_XA_InvOPA << 8)
+#define HC_HABLAb_OPAp5         (HC_XA_OPAp5 << 8)
+#define HC_HABLAb_0             (HC_XA_0 << 8)
+#define HC_HABLAb_Asrc          (HC_XA_Asrc << 8)
+#define HC_HABLAb_Adst          (HC_XA_Adst << 8)
+#define HC_HABLAb_Fog           (HC_XA_Fog << 8)
+#define HC_HABLAb_minAsrcFog    (HC_XA_minAsrcFog << 8)
+#define HC_HABLAb_minAsrcAdst   (HC_XA_minAsrcAdst << 8)
+#define HC_HABLAb_maxAsrcFog    (HC_XA_maxAsrcFog << 8)
+#define HC_HABLAb_maxAsrcAdst   (HC_XA_maxAsrcAdst << 8)
+#define HC_HABLAb_HABLRA        (HC_XA_HABLRA << 8)
+#define HC_HABLFAb_OPA          (HC_XA_OPA << 2)
+#define HC_HABLFAb_InvOPA       (HC_XA_InvOPA << 2)
+#define HC_HABLFAb_OPAp5        (HC_XA_OPAp5 << 2)
+#define HC_HABLFAb_0            (HC_XA_0 << 2)
+#define HC_HABLFAb_Asrc         (HC_XA_Asrc << 2)
+#define HC_HABLFAb_Adst         (HC_XA_Adst << 2)
+#define HC_HABLFAb_Fog          (HC_XA_Fog << 2)
+#define HC_HABLFAb_minAsrcFog   (HC_XA_minAsrcFog << 2)
+#define HC_HABLFAb_minAsrcAdst  (HC_XA_minAsrcAdst << 2)
+#define HC_HABLFAb_maxAsrcFog   (HC_XA_maxAsrcFog << 2)
+#define HC_HABLFAb_maxAsrcAdst  (HC_XA_maxAsrcAdst << 2)
+#define HC_HABLFAb_minAsrcInvAdst   (HC_XA_minAsrcInvAdst << 2)
+#define HC_HABLFAb_HABLFRA          (HC_XA_HABLFRA << 2)
+/* HC_SubA_HABLRAa         0x003d
+ */
+#define HC_HABLRAa_MASK         0x00ff0000
+#define HC_HABLRFAa_MASK        0x0000ff00
+#define HC_HABLRAbias_MASK      0x000000ff
+#define HC_HABLRAa_SHIFT        16
+#define HC_HABLRFAa_SHIFT       8
+/* HC_SubA_HABLRAb         0x003e
+ */
+#define HC_HABLRAb_MASK         0x0000ff00
+#define HC_HABLRFAb_MASK        0x000000ff
+#define HC_HABLRAb_SHIFT        8
+
+/* Destination Setting
+ */
+#define HC_SubA_HDBBasL         0x0040
+#define HC_SubA_HDBBasH         0x0041
+#define HC_SubA_HDBFM           0x0042
+#define HC_SubA_HFBBMSKL        0x0043
+#define HC_SubA_HROP            0x0044
+/* HC_SubA_HDBFM           0x0042
+ */
+#define HC_HDBFM_MASK           0x001f0000
+#define HC_HDBLoc_MASK          0x0000c000
+#define HC_HDBPit_MASK          0x00003fff
+#define HC_HDBFM_RGB555         0x00000000
+#define HC_HDBFM_RGB565         0x00010000
+#define HC_HDBFM_ARGB4444       0x00020000
+#define HC_HDBFM_ARGB1555       0x00030000
+#define HC_HDBFM_BGR555         0x00040000
+#define HC_HDBFM_BGR565         0x00050000
+#define HC_HDBFM_ABGR4444       0x00060000
+#define HC_HDBFM_ABGR1555       0x00070000
+#define HC_HDBFM_ARGB0888       0x00080000
+#define HC_HDBFM_ARGB8888       0x00090000
+#define HC_HDBFM_ABGR0888       0x000a0000
+#define HC_HDBFM_ABGR8888       0x000b0000
+#define HC_HDBLoc_Local         0x00000000
+#define HC_HDBLoc_Sys           0x00004000
+/* HC_SubA_HROP            0x0044
+ */
+#define HC_HROP_MASK            0x00000f00
+#define HC_HFBBMSKH_MASK        0x000000ff
+#define HC_HROP_BLACK           0x00000000
+#define HC_HROP_DPon            0x00000100
+#define HC_HROP_DPna            0x00000200
+#define HC_HROP_Pn              0x00000300
+#define HC_HROP_PDna            0x00000400
+#define HC_HROP_Dn              0x00000500
+#define HC_HROP_DPx             0x00000600
+#define HC_HROP_DPan            0x00000700
+#define HC_HROP_DPa             0x00000800
+#define HC_HROP_DPxn            0x00000900
+#define HC_HROP_D               0x00000a00
+#define HC_HROP_DPno            0x00000b00
+#define HC_HROP_P               0x00000c00
+#define HC_HROP_PDno            0x00000d00
+#define HC_HROP_DPo             0x00000e00
+#define HC_HROP_WHITE           0x00000f00
+
+/* Fog Setting
+ */
+#define HC_SubA_HFogLF          0x0050
+#define HC_SubA_HFogCL          0x0051
+#define HC_SubA_HFogCH          0x0052
+#define HC_SubA_HFogStL         0x0053
+#define HC_SubA_HFogStH         0x0054
+#define HC_SubA_HFogOOdMF       0x0055
+#define HC_SubA_HFogOOdEF       0x0056
+#define HC_SubA_HFogEndL        0x0057
+#define HC_SubA_HFogDenst       0x0058
+/* HC_SubA_FogLF           0x0050
+ */
+#define HC_FogLF_MASK           0x00000010
+#define HC_FogEq_MASK           0x00000008
+#define HC_FogMD_MASK           0x00000007
+#define HC_FogMD_LocalFog        0x00000000
+#define HC_FogMD_LinearFog       0x00000002
+#define HC_FogMD_ExponentialFog  0x00000004
+#define HC_FogMD_Exponential2Fog 0x00000005
+/* #define HC_FogMD_FogTable       0x00000003 */
+
+/* HC_SubA_HFogDenst        0x0058
+ */
+#define HC_FogDenst_MASK        0x001fff00
+#define HC_FogEndL_MASK         0x000000ff
+
+/* Texture subtype definitions
+ */
+#define HC_SubType_Tex0         0x00000000
+#define HC_SubType_Tex1         0x00000001
+#define HC_SubType_TexGeneral   0x000000fe
+
+/* Attribute of texture n
+ */
+#define HC_SubA_HTXnL0BasL      0x0000
+#define HC_SubA_HTXnL1BasL      0x0001
+#define HC_SubA_HTXnL2BasL      0x0002
+#define HC_SubA_HTXnL3BasL      0x0003
+#define HC_SubA_HTXnL4BasL      0x0004
+#define HC_SubA_HTXnL5BasL      0x0005
+#define HC_SubA_HTXnL6BasL      0x0006
+#define HC_SubA_HTXnL7BasL      0x0007
+#define HC_SubA_HTXnL8BasL      0x0008
+#define HC_SubA_HTXnL9BasL      0x0009
+#define HC_SubA_HTXnLaBasL      0x000a
+#define HC_SubA_HTXnLbBasL      0x000b
+#define HC_SubA_HTXnLcBasL      0x000c
+#define HC_SubA_HTXnLdBasL      0x000d
+#define HC_SubA_HTXnLeBasL      0x000e
+#define HC_SubA_HTXnLfBasL      0x000f
+#define HC_SubA_HTXnL10BasL     0x0010
+#define HC_SubA_HTXnL11BasL     0x0011
+#define HC_SubA_HTXnL012BasH    0x0020
+#define HC_SubA_HTXnL345BasH    0x0021
+#define HC_SubA_HTXnL678BasH    0x0022
+#define HC_SubA_HTXnL9abBasH    0x0023
+#define HC_SubA_HTXnLcdeBasH    0x0024
+#define HC_SubA_HTXnLf1011BasH  0x0025
+#define HC_SubA_HTXnL0Pit       0x002b
+#define HC_SubA_HTXnL1Pit       0x002c
+#define HC_SubA_HTXnL2Pit       0x002d
+#define HC_SubA_HTXnL3Pit       0x002e
+#define HC_SubA_HTXnL4Pit       0x002f
+#define HC_SubA_HTXnL5Pit       0x0030
+#define HC_SubA_HTXnL6Pit       0x0031
+#define HC_SubA_HTXnL7Pit       0x0032
+#define HC_SubA_HTXnL8Pit       0x0033
+#define HC_SubA_HTXnL9Pit       0x0034
+#define HC_SubA_HTXnLaPit       0x0035
+#define HC_SubA_HTXnLbPit       0x0036
+#define HC_SubA_HTXnLcPit       0x0037
+#define HC_SubA_HTXnLdPit       0x0038
+#define HC_SubA_HTXnLePit       0x0039
+#define HC_SubA_HTXnLfPit       0x003a
+#define HC_SubA_HTXnL10Pit      0x003b
+#define HC_SubA_HTXnL11Pit      0x003c
+#define HC_SubA_HTXnL0_5WE      0x004b
+#define HC_SubA_HTXnL6_bWE      0x004c
+#define HC_SubA_HTXnLc_11WE     0x004d
+#define HC_SubA_HTXnL0_5HE      0x0051
+#define HC_SubA_HTXnL6_bHE      0x0052
+#define HC_SubA_HTXnLc_11HE     0x0053
+#define HC_SubA_HTXnL0OS        0x0077
+#define HC_SubA_HTXnTB          0x0078
+#define HC_SubA_HTXnMPMD        0x0079
+#define HC_SubA_HTXnCLODu       0x007a
+#define HC_SubA_HTXnFM          0x007b
+#define HC_SubA_HTXnTRCH        0x007c
+#define HC_SubA_HTXnTRCL        0x007d
+#define HC_SubA_HTXnTBC         0x007e
+#define HC_SubA_HTXnTRAH        0x007f
+#define HC_SubA_HTXnTBLCsat     0x0080
+#define HC_SubA_HTXnTBLCop      0x0081
+#define HC_SubA_HTXnTBLMPfog    0x0082
+#define HC_SubA_HTXnTBLAsat     0x0083
+#define HC_SubA_HTXnTBLRCa      0x0085
+#define HC_SubA_HTXnTBLRCb      0x0086
+#define HC_SubA_HTXnTBLRCc      0x0087
+#define HC_SubA_HTXnTBLRCbias   0x0088
+#define HC_SubA_HTXnTBLRAa      0x0089
+#define HC_SubA_HTXnTBLRFog     0x008a
+#define HC_SubA_HTXnBumpM00     0x0090
+#define HC_SubA_HTXnBumpM01     0x0091
+#define HC_SubA_HTXnBumpM10     0x0092
+#define HC_SubA_HTXnBumpM11     0x0093
+#define HC_SubA_HTXnLScale      0x0094
+#define HC_SubA_HTXSMD          0x0000
+/* HC_SubA_HTXnL012BasH    0x0020
+ */
+#define HC_HTXnL0BasH_MASK      0x000000ff
+#define HC_HTXnL1BasH_MASK      0x0000ff00
+#define HC_HTXnL2BasH_MASK      0x00ff0000
+#define HC_HTXnL1BasH_SHIFT     8
+#define HC_HTXnL2BasH_SHIFT     16
+/* HC_SubA_HTXnL345BasH    0x0021
+ */
+#define HC_HTXnL3BasH_MASK      0x000000ff
+#define HC_HTXnL4BasH_MASK      0x0000ff00
+#define HC_HTXnL5BasH_MASK      0x00ff0000
+#define HC_HTXnL4BasH_SHIFT     8
+#define HC_HTXnL5BasH_SHIFT     16
+/* HC_SubA_HTXnL678BasH    0x0022
+ */
+#define HC_HTXnL6BasH_MASK      0x000000ff
+#define HC_HTXnL7BasH_MASK      0x0000ff00
+#define HC_HTXnL8BasH_MASK      0x00ff0000
+#define HC_HTXnL7BasH_SHIFT     8
+#define HC_HTXnL8BasH_SHIFT     16
+/* HC_SubA_HTXnL9abBasH    0x0023
+ */
+#define HC_HTXnL9BasH_MASK      0x000000ff
+#define HC_HTXnLaBasH_MASK      0x0000ff00
+#define HC_HTXnLbBasH_MASK      0x00ff0000
+#define HC_HTXnLaBasH_SHIFT     8
+#define HC_HTXnLbBasH_SHIFT     16
+/* HC_SubA_HTXnLcdeBasH    0x0024
+ */
+#define HC_HTXnLcBasH_MASK      0x000000ff
+#define HC_HTXnLdBasH_MASK      0x0000ff00
+#define HC_HTXnLeBasH_MASK      0x00ff0000
+#define HC_HTXnLdBasH_SHIFT     8
+#define HC_HTXnLeBasH_SHIFT     16
+/* HC_SubA_HTXnLcdeBasH    0x0025
+ */
+#define HC_HTXnLfBasH_MASK      0x000000ff
+#define HC_HTXnL10BasH_MASK      0x0000ff00
+#define HC_HTXnL11BasH_MASK      0x00ff0000
+#define HC_HTXnL10BasH_SHIFT     8
+#define HC_HTXnL11BasH_SHIFT     16
+/* HC_SubA_HTXnL0Pit       0x002b
+ */
+#define HC_HTXnLnPit_MASK       0x00003fff
+#define HC_HTXnEnPit_MASK       0x00080000
+#define HC_HTXnLnPitE_MASK      0x00f00000
+#define HC_HTXnLnPitE_SHIFT     20
+/* HC_SubA_HTXnL0_5WE      0x004b
+ */
+#define HC_HTXnL0WE_MASK        0x0000000f
+#define HC_HTXnL1WE_MASK        0x000000f0
+#define HC_HTXnL2WE_MASK        0x00000f00
+#define HC_HTXnL3WE_MASK        0x0000f000
+#define HC_HTXnL4WE_MASK        0x000f0000
+#define HC_HTXnL5WE_MASK        0x00f00000
+#define HC_HTXnL1WE_SHIFT       4
+#define HC_HTXnL2WE_SHIFT       8
+#define HC_HTXnL3WE_SHIFT       12
+#define HC_HTXnL4WE_SHIFT       16
+#define HC_HTXnL5WE_SHIFT       20
+/* HC_SubA_HTXnL6_bWE      0x004c
+ */
+#define HC_HTXnL6WE_MASK        0x0000000f
+#define HC_HTXnL7WE_MASK        0x000000f0
+#define HC_HTXnL8WE_MASK        0x00000f00
+#define HC_HTXnL9WE_MASK        0x0000f000
+#define HC_HTXnLaWE_MASK        0x000f0000
+#define HC_HTXnLbWE_MASK        0x00f00000
+#define HC_HTXnL7WE_SHIFT       4
+#define HC_HTXnL8WE_SHIFT       8
+#define HC_HTXnL9WE_SHIFT       12
+#define HC_HTXnLaWE_SHIFT       16
+#define HC_HTXnLbWE_SHIFT       20
+/* HC_SubA_HTXnLc_11WE      0x004d
+ */
+#define HC_HTXnLcWE_MASK        0x0000000f
+#define HC_HTXnLdWE_MASK        0x000000f0
+#define HC_HTXnLeWE_MASK        0x00000f00
+#define HC_HTXnLfWE_MASK        0x0000f000
+#define HC_HTXnL10WE_MASK       0x000f0000
+#define HC_HTXnL11WE_MASK       0x00f00000
+#define HC_HTXnLdWE_SHIFT       4
+#define HC_HTXnLeWE_SHIFT       8
+#define HC_HTXnLfWE_SHIFT       12
+#define HC_HTXnL10WE_SHIFT      16
+#define HC_HTXnL11WE_SHIFT      20
+/* HC_SubA_HTXnL0_5HE      0x0051
+ */
+#define HC_HTXnL0HE_MASK        0x0000000f
+#define HC_HTXnL1HE_MASK        0x000000f0
+#define HC_HTXnL2HE_MASK        0x00000f00
+#define HC_HTXnL3HE_MASK        0x0000f000
+#define HC_HTXnL4HE_MASK        0x000f0000
+#define HC_HTXnL5HE_MASK        0x00f00000
+#define HC_HTXnL1HE_SHIFT       4
+#define HC_HTXnL2HE_SHIFT       8
+#define HC_HTXnL3HE_SHIFT       12
+#define HC_HTXnL4HE_SHIFT       16
+#define HC_HTXnL5HE_SHIFT       20
+/* HC_SubA_HTXnL6_bHE      0x0052
+ */
+#define HC_HTXnL6HE_MASK        0x0000000f
+#define HC_HTXnL7HE_MASK        0x000000f0
+#define HC_HTXnL8HE_MASK        0x00000f00
+#define HC_HTXnL9HE_MASK        0x0000f000
+#define HC_HTXnLaHE_MASK        0x000f0000
+#define HC_HTXnLbHE_MASK        0x00f00000
+#define HC_HTXnL7HE_SHIFT       4
+#define HC_HTXnL8HE_SHIFT       8
+#define HC_HTXnL9HE_SHIFT       12
+#define HC_HTXnLaHE_SHIFT       16
+#define HC_HTXnLbHE_SHIFT       20
+/* HC_SubA_HTXnLc_11HE      0x0053
+ */
+#define HC_HTXnLcHE_MASK        0x0000000f
+#define HC_HTXnLdHE_MASK        0x000000f0
+#define HC_HTXnLeHE_MASK        0x00000f00
+#define HC_HTXnLfHE_MASK        0x0000f000
+#define HC_HTXnL10HE_MASK       0x000f0000
+#define HC_HTXnL11HE_MASK       0x00f00000
+#define HC_HTXnLdHE_SHIFT       4
+#define HC_HTXnLeHE_SHIFT       8
+#define HC_HTXnLfHE_SHIFT       12
+#define HC_HTXnL10HE_SHIFT      16
+#define HC_HTXnL11HE_SHIFT      20
+/* HC_SubA_HTXnL0OS        0x0077
+ */
+#define HC_HTXnL0OS_MASK        0x003ff000
+#define HC_HTXnLVmax_MASK       0x00000fc0
+#define HC_HTXnLVmin_MASK       0x0000003f
+#define HC_HTXnL0OS_SHIFT       12
+#define HC_HTXnLVmax_SHIFT      6
+/* HC_SubA_HTXnTB          0x0078
+ */
+#define HC_HTXnTB_MASK          0x00f00000
+#define HC_HTXnFLSe_MASK        0x0000e000
+#define HC_HTXnFLSs_MASK        0x00001c00
+#define HC_HTXnFLTe_MASK        0x00000380
+#define HC_HTXnFLTs_MASK        0x00000070
+#define HC_HTXnFLDs_MASK        0x0000000f
+#define HC_HTXnTB_NoTB          0x00000000
+#define HC_HTXnTB_TBC_S         0x00100000
+#define HC_HTXnTB_TBC_T         0x00200000
+#define HC_HTXnTB_TB_S          0x00400000
+#define HC_HTXnTB_TB_T          0x00800000
+#define HC_HTXnFLSe_Nearest     0x00000000
+#define HC_HTXnFLSe_Linear      0x00002000
+#define HC_HTXnFLSe_NonLinear   0x00004000
+#define HC_HTXnFLSe_Sharp       0x00008000
+#define HC_HTXnFLSe_Flat_Gaussian_Cubic 0x0000c000
+#define HC_HTXnFLSs_Nearest     0x00000000
+#define HC_HTXnFLSs_Linear      0x00000400
+#define HC_HTXnFLSs_NonLinear   0x00000800
+#define HC_HTXnFLSs_Flat_Gaussian_Cubic 0x00001800
+#define HC_HTXnFLTe_Nearest     0x00000000
+#define HC_HTXnFLTe_Linear      0x00000080
+#define HC_HTXnFLTe_NonLinear   0x00000100
+#define HC_HTXnFLTe_Sharp       0x00000180
+#define HC_HTXnFLTe_Flat_Gaussian_Cubic 0x00000300
+#define HC_HTXnFLTs_Nearest     0x00000000
+#define HC_HTXnFLTs_Linear      0x00000010
+#define HC_HTXnFLTs_NonLinear   0x00000020
+#define HC_HTXnFLTs_Flat_Gaussian_Cubic 0x00000060
+#define HC_HTXnFLDs_Tex0        0x00000000
+#define HC_HTXnFLDs_Nearest     0x00000001
+#define HC_HTXnFLDs_Linear      0x00000002
+#define HC_HTXnFLDs_NonLinear   0x00000003
+#define HC_HTXnFLDs_Dither      0x00000004
+#define HC_HTXnFLDs_ConstLOD    0x00000005
+#define HC_HTXnFLDs_Ani         0x00000006
+#define HC_HTXnFLDs_AniDither   0x00000007
+/* HC_SubA_HTXnMPMD        0x0079
+ */
+#define HC_HTXnMPMD_SMASK       0x00070000
+#define HC_HTXnMPMD_TMASK       0x00380000
+#define HC_HTXnLODDTf_MASK      0x00000007
+#define HC_HTXnXY2ST_MASK       0x00000008
+#define HC_HTXnMPMD_Tsingle     0x00000000
+#define HC_HTXnMPMD_Tclamp      0x00080000
+#define HC_HTXnMPMD_Trepeat     0x00100000
+#define HC_HTXnMPMD_Tmirror     0x00180000
+#define HC_HTXnMPMD_Twrap       0x00200000
+#define HC_HTXnMPMD_Ssingle     0x00000000
+#define HC_HTXnMPMD_Sclamp      0x00010000
+#define HC_HTXnMPMD_Srepeat     0x00020000
+#define HC_HTXnMPMD_Smirror     0x00030000
+#define HC_HTXnMPMD_Swrap       0x00040000
+/* HC_SubA_HTXnCLODu       0x007a
+ */
+#define HC_HTXnCLODu_MASK       0x000ffc00
+#define HC_HTXnCLODd_MASK       0x000003ff
+#define HC_HTXnCLODu_SHIFT      10
+/* HC_SubA_HTXnFM          0x007b
+ */
+#define HC_HTXnFM_MASK          0x00ff0000
+#define HC_HTXnLoc_MASK         0x00000003
+#define HC_HTXnFM_INDEX         0x00000000
+#define HC_HTXnFM_Intensity     0x00080000
+#define HC_HTXnFM_Lum           0x00100000
+#define HC_HTXnFM_Alpha         0x00180000
+#define HC_HTXnFM_DX            0x00280000
+#define HC_HTXnFM_ARGB16        0x00880000
+#define HC_HTXnFM_ARGB32        0x00980000
+#define HC_HTXnFM_ABGR16        0x00a80000
+#define HC_HTXnFM_ABGR32        0x00b80000
+#define HC_HTXnFM_RGBA16        0x00c80000
+#define HC_HTXnFM_RGBA32        0x00d80000
+#define HC_HTXnFM_BGRA16        0x00e80000
+#define HC_HTXnFM_BGRA32        0x00f80000
+#define HC_HTXnFM_BUMPMAP       0x00380000
+#define HC_HTXnFM_Index1        (HC_HTXnFM_INDEX     | 0x00000000)
+#define HC_HTXnFM_Index2        (HC_HTXnFM_INDEX     | 0x00010000)
+#define HC_HTXnFM_Index4        (HC_HTXnFM_INDEX     | 0x00020000)
+#define HC_HTXnFM_Index8        (HC_HTXnFM_INDEX     | 0x00030000)
+#define HC_HTXnFM_T1            (HC_HTXnFM_Intensity | 0x00000000)
+#define HC_HTXnFM_T2            (HC_HTXnFM_Intensity | 0x00010000)
+#define HC_HTXnFM_T4            (HC_HTXnFM_Intensity | 0x00020000)
+#define HC_HTXnFM_T8            (HC_HTXnFM_Intensity | 0x00030000)
+#define HC_HTXnFM_L1            (HC_HTXnFM_Lum       | 0x00000000)
+#define HC_HTXnFM_L2            (HC_HTXnFM_Lum       | 0x00010000)
+#define HC_HTXnFM_L4            (HC_HTXnFM_Lum       | 0x00020000)
+#define HC_HTXnFM_L8            (HC_HTXnFM_Lum       | 0x00030000)
+#define HC_HTXnFM_AL44          (HC_HTXnFM_Lum       | 0x00040000)
+#define HC_HTXnFM_AL88          (HC_HTXnFM_Lum       | 0x00050000)
+#define HC_HTXnFM_A1            (HC_HTXnFM_Alpha     | 0x00000000)
+#define HC_HTXnFM_A2            (HC_HTXnFM_Alpha     | 0x00010000)
+#define HC_HTXnFM_A4            (HC_HTXnFM_Alpha     | 0x00020000)
+#define HC_HTXnFM_A8            (HC_HTXnFM_Alpha     | 0x00030000)
+#define HC_HTXnFM_DX1           (HC_HTXnFM_DX        | 0x00010000)
+#define HC_HTXnFM_DX23          (HC_HTXnFM_DX        | 0x00020000)
+#define HC_HTXnFM_DX45          (HC_HTXnFM_DX        | 0x00030000)
+#define HC_HTXnFM_RGB555        (HC_HTXnFM_ARGB16    | 0x00000000)
+#define HC_HTXnFM_RGB565        (HC_HTXnFM_ARGB16    | 0x00010000)
+#define HC_HTXnFM_ARGB1555      (HC_HTXnFM_ARGB16    | 0x00020000)
+#define HC_HTXnFM_ARGB4444      (HC_HTXnFM_ARGB16    | 0x00030000)
+#define HC_HTXnFM_ARGB0888      (HC_HTXnFM_ARGB32    | 0x00000000)
+#define HC_HTXnFM_ARGB8888      (HC_HTXnFM_ARGB32    | 0x00010000)
+#define HC_HTXnFM_BGR555        (HC_HTXnFM_ABGR16    | 0x00000000)
+#define HC_HTXnFM_BGR565        (HC_HTXnFM_ABGR16    | 0x00010000)
+#define HC_HTXnFM_ABGR1555      (HC_HTXnFM_ABGR16    | 0x00020000)
+#define HC_HTXnFM_ABGR4444      (HC_HTXnFM_ABGR16    | 0x00030000)
+#define HC_HTXnFM_ABGR0888      (HC_HTXnFM_ABGR32    | 0x00000000)
+#define HC_HTXnFM_ABGR8888      (HC_HTXnFM_ABGR32    | 0x00010000)
+#define HC_HTXnFM_RGBA5550      (HC_HTXnFM_RGBA16    | 0x00000000)
+#define HC_HTXnFM_RGBA5551      (HC_HTXnFM_RGBA16    | 0x00020000)
+#define HC_HTXnFM_RGBA4444      (HC_HTXnFM_RGBA16    | 0x00030000)
+#define HC_HTXnFM_RGBA8880      (HC_HTXnFM_RGBA32    | 0x00000000)
+#define HC_HTXnFM_RGBA8888      (HC_HTXnFM_RGBA32    | 0x00010000)
+#define HC_HTXnFM_BGRA5550      (HC_HTXnFM_BGRA16    | 0x00000000)
+#define HC_HTXnFM_BGRA5551      (HC_HTXnFM_BGRA16    | 0x00020000)
+#define HC_HTXnFM_BGRA4444      (HC_HTXnFM_BGRA16    | 0x00030000)
+#define HC_HTXnFM_BGRA8880      (HC_HTXnFM_BGRA32    | 0x00000000)
+#define HC_HTXnFM_BGRA8888      (HC_HTXnFM_BGRA32    | 0x00010000)
+#define HC_HTXnFM_VU88          (HC_HTXnFM_BUMPMAP   | 0x00000000)
+#define HC_HTXnFM_LVU655        (HC_HTXnFM_BUMPMAP   | 0x00010000)
+#define HC_HTXnFM_LVU888        (HC_HTXnFM_BUMPMAP   | 0x00020000)
+#define HC_HTXnLoc_Local        0x00000000
+#define HC_HTXnLoc_Sys          0x00000002
+#define HC_HTXnLoc_AGP          0x00000003
+/* HC_SubA_HTXnTRAH        0x007f
+ */
+#define HC_HTXnTRAH_MASK        0x00ff0000
+#define HC_HTXnTRAL_MASK        0x0000ff00
+#define HC_HTXnTBA_MASK         0x000000ff
+#define HC_HTXnTRAH_SHIFT       16
+#define HC_HTXnTRAL_SHIFT       8
+/* HC_SubA_HTXnTBLCsat     0x0080
+ *-- Define the input texture.
+ */
+#define HC_XTC_TOPC             0x00000000
+#define HC_XTC_InvTOPC          0x00000010
+#define HC_XTC_TOPCp5           0x00000020
+#define HC_XTC_Cbias            0x00000000
+#define HC_XTC_InvCbias         0x00000010
+#define HC_XTC_0                0x00000000
+#define HC_XTC_Dif              0x00000001
+#define HC_XTC_Spec             0x00000002
+#define HC_XTC_Tex              0x00000003
+#define HC_XTC_Cur              0x00000004
+#define HC_XTC_Adif             0x00000005
+#define HC_XTC_Fog              0x00000006
+#define HC_XTC_Atex             0x00000007
+#define HC_XTC_Acur             0x00000008
+#define HC_XTC_HTXnTBLRC        0x00000009
+#define HC_XTC_Ctexnext         0x0000000a
+/*--
+ */
+#define HC_HTXnTBLCsat_MASK     0x00800000
+#define HC_HTXnTBLCa_MASK       0x000fc000
+#define HC_HTXnTBLCb_MASK       0x00001f80
+#define HC_HTXnTBLCc_MASK       0x0000003f
+#define HC_HTXnTBLCa_TOPC       (HC_XTC_TOPC << 14)
+#define HC_HTXnTBLCa_InvTOPC    (HC_XTC_InvTOPC << 14)
+#define HC_HTXnTBLCa_TOPCp5     (HC_XTC_TOPCp5 << 14)
+#define HC_HTXnTBLCa_0          (HC_XTC_0 << 14)
+#define HC_HTXnTBLCa_Dif        (HC_XTC_Dif << 14)
+#define HC_HTXnTBLCa_Spec       (HC_XTC_Spec << 14)
+#define HC_HTXnTBLCa_Tex        (HC_XTC_Tex << 14)
+#define HC_HTXnTBLCa_Cur        (HC_XTC_Cur << 14)
+#define HC_HTXnTBLCa_Adif       (HC_XTC_Adif << 14)
+#define HC_HTXnTBLCa_Fog        (HC_XTC_Fog << 14)
+#define HC_HTXnTBLCa_Atex       (HC_XTC_Atex << 14)
+#define HC_HTXnTBLCa_Acur       (HC_XTC_Acur << 14)
+#define HC_HTXnTBLCa_HTXnTBLRC  (HC_XTC_HTXnTBLRC << 14)
+#define HC_HTXnTBLCa_Ctexnext   (HC_XTC_Ctexnext << 14)
+#define HC_HTXnTBLCb_TOPC       (HC_XTC_TOPC << 7)
+#define HC_HTXnTBLCb_InvTOPC    (HC_XTC_InvTOPC << 7)
+#define HC_HTXnTBLCb_TOPCp5     (HC_XTC_TOPCp5 << 7)
+#define HC_HTXnTBLCb_0          (HC_XTC_0 << 7)
+#define HC_HTXnTBLCb_Dif        (HC_XTC_Dif << 7)
+#define HC_HTXnTBLCb_Spec       (HC_XTC_Spec << 7)
+#define HC_HTXnTBLCb_Tex        (HC_XTC_Tex << 7)
+#define HC_HTXnTBLCb_Cur        (HC_XTC_Cur << 7)
+#define HC_HTXnTBLCb_Adif       (HC_XTC_Adif << 7)
+#define HC_HTXnTBLCb_Fog        (HC_XTC_Fog << 7)
+#define HC_HTXnTBLCb_Atex       (HC_XTC_Atex << 7)
+#define HC_HTXnTBLCb_Acur       (HC_XTC_Acur << 7)
+#define HC_HTXnTBLCb_HTXnTBLRC  (HC_XTC_HTXnTBLRC << 7)
+#define HC_HTXnTBLCb_Ctexnext   (HC_XTC_Ctexnext << 7)
+#define HC_HTXnTBLCc_TOPC       (HC_XTC_TOPC << 0)
+#define HC_HTXnTBLCc_InvTOPC    (HC_XTC_InvTOPC << 0)
+#define HC_HTXnTBLCc_TOPCp5     (HC_XTC_TOPCp5 << 0)
+#define HC_HTXnTBLCc_0          (HC_XTC_0 << 0)
+#define HC_HTXnTBLCc_Dif        (HC_XTC_Dif << 0)
+#define HC_HTXnTBLCc_Spec       (HC_XTC_Spec << 0)
+#define HC_HTXnTBLCc_Tex        (HC_XTC_Tex << 0)
+#define HC_HTXnTBLCc_Cur        (HC_XTC_Cur << 0)
+#define HC_HTXnTBLCc_Adif       (HC_XTC_Adif << 0)
+#define HC_HTXnTBLCc_Fog        (HC_XTC_Fog << 0)
+#define HC_HTXnTBLCc_Atex       (HC_XTC_Atex << 0)
+#define HC_HTXnTBLCc_Acur       (HC_XTC_Acur << 0)
+#define HC_HTXnTBLCc_HTXnTBLRC  (HC_XTC_HTXnTBLRC << 0)
+#define HC_HTXnTBLCc_Ctexnext   (HC_XTC_Ctexnext << 0)
+/* HC_SubA_HTXnTBLCop      0x0081
+ */
+#define HC_HTXnTBLdot_MASK      0x00c00000
+#define HC_HTXnTBLCop_MASK      0x00380000
+#define HC_HTXnTBLCbias_MASK    0x0007c000
+#define HC_HTXnTBLCshift_MASK   0x00001800
+#define HC_HTXnTBLAop_MASK      0x00000380
+#define HC_HTXnTBLAbias_MASK    0x00000078
+#define HC_HTXnTBLAshift_MASK   0x00000003
+#define HC_HTXnTBLCop_Add       0x00000000
+#define HC_HTXnTBLCop_Sub       0x00080000
+#define HC_HTXnTBLCop_Min       0x00100000
+#define HC_HTXnTBLCop_Max       0x00180000
+#define HC_HTXnTBLCop_Mask      0x00200000
+#define HC_HTXnTBLCbias_Cbias           (HC_XTC_Cbias << 14)
+#define HC_HTXnTBLCbias_InvCbias        (HC_XTC_InvCbias << 14)
+#define HC_HTXnTBLCbias_0               (HC_XTC_0 << 14)
+#define HC_HTXnTBLCbias_Dif             (HC_XTC_Dif << 14)
+#define HC_HTXnTBLCbias_Spec            (HC_XTC_Spec << 14)
+#define HC_HTXnTBLCbias_Tex             (HC_XTC_Tex << 14)
+#define HC_HTXnTBLCbias_Cur             (HC_XTC_Cur << 14)
+#define HC_HTXnTBLCbias_Adif            (HC_XTC_Adif << 14)
+#define HC_HTXnTBLCbias_Fog             (HC_XTC_Fog << 14)
+#define HC_HTXnTBLCbias_Atex            (HC_XTC_Atex << 14)
+#define HC_HTXnTBLCbias_Acur            (HC_XTC_Acur << 14)
+#define HC_HTXnTBLCbias_HTXnTBLRC       (HC_XTC_HTXnTBLRC << 14)
+#define HC_HTXnTBLCshift_1      0x00000000
+#define HC_HTXnTBLCshift_2      0x00000800
+#define HC_HTXnTBLCshift_No     0x00001000
+#define HC_HTXnTBLCshift_DotP   0x00001800
+/*=* John Sheng [2003.7.18] texture combine *=*/
+#define HC_HTXnTBLDOT3   0x00080000
+#define HC_HTXnTBLDOT4   0x000C0000
+
+#define HC_HTXnTBLAop_Add       0x00000000
+#define HC_HTXnTBLAop_Sub       0x00000080
+#define HC_HTXnTBLAop_Min       0x00000100
+#define HC_HTXnTBLAop_Max       0x00000180
+#define HC_HTXnTBLAop_Mask      0x00000200
+#define HC_HTXnTBLAbias_Inv             0x00000040
+#define HC_HTXnTBLAbias_Adif            0x00000000
+#define HC_HTXnTBLAbias_Fog             0x00000008
+#define HC_HTXnTBLAbias_Acur            0x00000010
+#define HC_HTXnTBLAbias_HTXnTBLRAbias   0x00000018
+#define HC_HTXnTBLAbias_Atex            0x00000020
+#define HC_HTXnTBLAshift_1      0x00000000
+#define HC_HTXnTBLAshift_2      0x00000001
+#define HC_HTXnTBLAshift_No     0x00000002
+/* #define HC_HTXnTBLAshift_DotP   0x00000003 */
+/* HC_SubA_HTXnTBLMPFog    0x0082
+ */
+#define HC_HTXnTBLMPfog_MASK    0x00e00000
+#define HC_HTXnTBLMPfog_0       0x00000000
+#define HC_HTXnTBLMPfog_Adif    0x00200000
+#define HC_HTXnTBLMPfog_Fog     0x00400000
+#define HC_HTXnTBLMPfog_Atex    0x00600000
+#define HC_HTXnTBLMPfog_Acur    0x00800000
+#define HC_HTXnTBLMPfog_GHTXnTBLRFog    0x00a00000
+/* HC_SubA_HTXnTBLAsat     0x0083
+ *-- Define the texture alpha input.
+ */
+#define HC_XTA_TOPA             0x00000000
+#define HC_XTA_InvTOPA          0x00000008
+#define HC_XTA_TOPAp5           0x00000010
+#define HC_XTA_Adif             0x00000000
+#define HC_XTA_Fog              0x00000001
+#define HC_XTA_Acur             0x00000002
+#define HC_XTA_HTXnTBLRA        0x00000003
+#define HC_XTA_Atex             0x00000004
+#define HC_XTA_Atexnext         0x00000005
+/*--
+ */
+#define HC_HTXnTBLAsat_MASK     0x00800000
+#define HC_HTXnTBLAMB_MASK      0x00700000
+#define HC_HTXnTBLAa_MASK       0x0007c000
+#define HC_HTXnTBLAb_MASK       0x00000f80
+#define HC_HTXnTBLAc_MASK       0x0000001f
+#define HC_HTXnTBLAMB_SHIFT     20
+#define HC_HTXnTBLAa_TOPA       (HC_XTA_TOPA << 14)
+#define HC_HTXnTBLAa_InvTOPA    (HC_XTA_InvTOPA << 14)
+#define HC_HTXnTBLAa_TOPAp5     (HC_XTA_TOPAp5 << 14)
+#define HC_HTXnTBLAa_Adif       (HC_XTA_Adif << 14)
+#define HC_HTXnTBLAa_Fog        (HC_XTA_Fog << 14)
+#define HC_HTXnTBLAa_Acur       (HC_XTA_Acur << 14)
+#define HC_HTXnTBLAa_HTXnTBLRA  (HC_XTA_HTXnTBLRA << 14)
+#define HC_HTXnTBLAa_Atex       (HC_XTA_Atex << 14)
+#define HC_HTXnTBLAa_Atexnext   (HC_XTA_Atexnext << 14)
+#define HC_HTXnTBLAb_TOPA       (HC_XTA_TOPA << 7)
+#define HC_HTXnTBLAb_InvTOPA    (HC_XTA_InvTOPA << 7)
+#define HC_HTXnTBLAb_TOPAp5     (HC_XTA_TOPAp5 << 7)
+#define HC_HTXnTBLAb_Adif       (HC_XTA_Adif << 7)
+#define HC_HTXnTBLAb_Fog        (HC_XTA_Fog << 7)
+#define HC_HTXnTBLAb_Acur       (HC_XTA_Acur << 7)
+#define HC_HTXnTBLAb_HTXnTBLRA  (HC_XTA_HTXnTBLRA << 7)
+#define HC_HTXnTBLAb_Atex       (HC_XTA_Atex << 7)
+#define HC_HTXnTBLAb_Atexnext   (HC_XTA_Atexnext << 7)
+#define HC_HTXnTBLAc_TOPA       (HC_XTA_TOPA << 0)
+#define HC_HTXnTBLAc_InvTOPA    (HC_XTA_InvTOPA << 0)
+#define HC_HTXnTBLAc_TOPAp5     (HC_XTA_TOPAp5 << 0)
+#define HC_HTXnTBLAc_Adif       (HC_XTA_Adif << 0)
+#define HC_HTXnTBLAc_Fog        (HC_XTA_Fog << 0)
+#define HC_HTXnTBLAc_Acur       (HC_XTA_Acur << 0)
+#define HC_HTXnTBLAc_HTXnTBLRA  (HC_XTA_HTXnTBLRA << 0)
+#define HC_HTXnTBLAc_Atex       (HC_XTA_Atex << 0)
+#define HC_HTXnTBLAc_Atexnext   (HC_XTA_Atexnext << 0)
+/* HC_SubA_HTXnTBLRAa      0x0089
+ */
+#define HC_HTXnTBLRAa_MASK      0x00ff0000
+#define HC_HTXnTBLRAb_MASK      0x0000ff00
+#define HC_HTXnTBLRAc_MASK      0x000000ff
+#define HC_HTXnTBLRAa_SHIFT     16
+#define HC_HTXnTBLRAb_SHIFT     8
+#define HC_HTXnTBLRAc_SHIFT     0
+/* HC_SubA_HTXnTBLRFog     0x008a
+ */
+#define HC_HTXnTBLRFog_MASK     0x0000ff00
+#define HC_HTXnTBLRAbias_MASK   0x000000ff
+#define HC_HTXnTBLRFog_SHIFT    8
+#define HC_HTXnTBLRAbias_SHIFT  0
+/* HC_SubA_HTXnLScale      0x0094
+ */
+#define HC_HTXnLScale_MASK      0x0007fc00
+#define HC_HTXnLOff_MASK        0x000001ff
+#define HC_HTXnLScale_SHIFT     10
+/* HC_SubA_HTXSMD          0x0000
+ */
+#define HC_HTXSMD_MASK          0x00000080
+#define HC_HTXTMD_MASK          0x00000040
+#define HC_HTXNum_MASK          0x00000038
+#define HC_HTXTRMD_MASK         0x00000006
+#define HC_HTXCHCLR_MASK        0x00000001
+#define HC_HTXNum_SHIFT         3
+
+/* Texture Palette n
+ */
+#define HC_SubType_TexPalette0  0x00000000
+#define HC_SubType_TexPalette1  0x00000001
+#define HC_SubType_FogTable     0x00000010
+#define HC_SubType_Stipple      0x00000014
+/* HC_SubA_TexPalette0     0x0000
+ */
+#define HC_HTPnA_MASK           0xff000000
+#define HC_HTPnR_MASK           0x00ff0000
+#define HC_HTPnG_MASK           0x0000ff00
+#define HC_HTPnB_MASK           0x000000ff
+/* HC_SubA_FogTable        0x0010
+ */
+#define HC_HFPn3_MASK           0xff000000
+#define HC_HFPn2_MASK           0x00ff0000
+#define HC_HFPn1_MASK           0x0000ff00
+#define HC_HFPn_MASK            0x000000ff
+#define HC_HFPn3_SHIFT          24
+#define HC_HFPn2_SHIFT          16
+#define HC_HFPn1_SHIFT          8
+
+/* Auto Testing & Security
+ */
+#define HC_SubA_HenFIFOAT       0x0000
+#define HC_SubA_HFBDrawFirst    0x0004
+#define HC_SubA_HFBBasL         0x0005
+#define HC_SubA_HFBDst          0x0006
+/* HC_SubA_HenFIFOAT       0x0000
+ */
+#define HC_HenFIFOAT_MASK       0x00000020
+#define HC_HenGEMILock_MASK     0x00000010
+#define HC_HenFBASwap_MASK      0x00000008
+#define HC_HenOT_MASK           0x00000004
+#define HC_HenCMDQ_MASK         0x00000002
+#define HC_HenTXCTSU_MASK       0x00000001
+/* HC_SubA_HFBDrawFirst    0x0004
+ */
+#define HC_HFBDrawFirst_MASK    0x00000800
+#define HC_HFBQueue_MASK        0x00000400
+#define HC_HFBLock_MASK         0x00000200
+#define HC_HEOF_MASK            0x00000100
+#define HC_HFBBasH_MASK         0x000000ff
+
+/* GEMI Setting
+ */
+#define HC_SubA_HTArbRCM        0x0008
+#define HC_SubA_HTArbRZ         0x000a
+#define HC_SubA_HTArbWZ         0x000b
+#define HC_SubA_HTArbRTX        0x000c
+#define HC_SubA_HTArbRCW        0x000d
+#define HC_SubA_HTArbE2         0x000e
+#define HC_SubA_HArbRQCM        0x0010
+#define HC_SubA_HArbWQCM        0x0011
+#define HC_SubA_HGEMITout       0x0020
+#define HC_SubA_HFthRTXD        0x0040
+#define HC_SubA_HFthRTXA        0x0044
+#define HC_SubA_HCMDQstL        0x0050
+#define HC_SubA_HCMDQendL       0x0051
+#define HC_SubA_HCMDQLen        0x0052
+/* HC_SubA_HTArbRCM        0x0008
+ */
+#define HC_HTArbRCM_MASK        0x0000ffff
+/* HC_SubA_HTArbRZ         0x000a
+ */
+#define HC_HTArbRZ_MASK         0x0000ffff
+/* HC_SubA_HTArbWZ         0x000b
+ */
+#define HC_HTArbWZ_MASK         0x0000ffff
+/* HC_SubA_HTArbRTX        0x000c
+ */
+#define HC_HTArbRTX_MASK        0x0000ffff
+/* HC_SubA_HTArbRCW        0x000d
+ */
+#define HC_HTArbRCW_MASK        0x0000ffff
+/* HC_SubA_HTArbE2         0x000e
+ */
+#define HC_HTArbE2_MASK         0x0000ffff
+/* HC_SubA_HArbRQCM        0x0010
+ */
+#define HC_HTArbRQCM_MASK       0x0000ffff
+/* HC_SubA_HArbWQCM        0x0011
+ */
+#define HC_HArbWQCM_MASK        0x0000ffff
+/* HC_SubA_HGEMITout       0x0020
+ */
+#define HC_HGEMITout_MASK       0x000f0000
+#define HC_HNPArbZC_MASK        0x0000ffff
+#define HC_HGEMITout_SHIFT      16
+/* HC_SubA_HFthRTXD        0x0040
+ */
+#define HC_HFthRTXD_MASK        0x00ff0000
+#define HC_HFthRZD_MASK         0x0000ff00
+#define HC_HFthWZD_MASK         0x000000ff
+#define HC_HFthRTXD_SHIFT       16
+#define HC_HFthRZD_SHIFT        8
+/* HC_SubA_HFthRTXA        0x0044
+ */
+#define HC_HFthRTXA_MASK        0x000000ff
+
+/******************************************************************************
+** Define the Halcyon Internal register access constants. For simulator only.
+******************************************************************************/
+#define HC_SIMA_HAGPBstL        0x0000
+#define HC_SIMA_HAGPBendL       0x0001
+#define HC_SIMA_HAGPCMNT        0x0002
+#define HC_SIMA_HAGPBpL         0x0003
+#define HC_SIMA_HAGPBpH         0x0004
+#define HC_SIMA_HClipTB         0x0005
+#define HC_SIMA_HClipLR         0x0006
+#define HC_SIMA_HFPClipTL       0x0007
+#define HC_SIMA_HFPClipBL       0x0008
+#define HC_SIMA_HFPClipLL       0x0009
+#define HC_SIMA_HFPClipRL       0x000a
+#define HC_SIMA_HFPClipTBH      0x000b
+#define HC_SIMA_HFPClipLRH      0x000c
+#define HC_SIMA_HLP             0x000d
+#define HC_SIMA_HLPRF           0x000e
+#define HC_SIMA_HSolidCL        0x000f
+#define HC_SIMA_HPixGC          0x0010
+#define HC_SIMA_HSPXYOS         0x0011
+#define HC_SIMA_HCmdA           0x0012
+#define HC_SIMA_HCmdB           0x0013
+#define HC_SIMA_HEnable         0x0014
+#define HC_SIMA_HZWBBasL        0x0015
+#define HC_SIMA_HZWBBasH        0x0016
+#define HC_SIMA_HZWBType        0x0017
+#define HC_SIMA_HZBiasL         0x0018
+#define HC_SIMA_HZWBend         0x0019
+#define HC_SIMA_HZWTMD          0x001a
+#define HC_SIMA_HZWCDL          0x001b
+#define HC_SIMA_HZWCTAGnum      0x001c
+#define HC_SIMA_HZCYNum         0x001d
+#define HC_SIMA_HZWCFire        0x001e
+/* #define HC_SIMA_HSBBasL         0x001d */
+/* #define HC_SIMA_HSBBasH         0x001e */
+/* #define HC_SIMA_HSBFM           0x001f */
+#define HC_SIMA_HSTREF          0x0020
+#define HC_SIMA_HSTMD           0x0021
+#define HC_SIMA_HABBasL         0x0022
+#define HC_SIMA_HABBasH         0x0023
+#define HC_SIMA_HABFM           0x0024
+#define HC_SIMA_HATMD           0x0025
+#define HC_SIMA_HABLCsat        0x0026
+#define HC_SIMA_HABLCop         0x0027
+#define HC_SIMA_HABLAsat        0x0028
+#define HC_SIMA_HABLAop         0x0029
+#define HC_SIMA_HABLRCa         0x002a
+#define HC_SIMA_HABLRFCa        0x002b
+#define HC_SIMA_HABLRCbias      0x002c
+#define HC_SIMA_HABLRCb         0x002d
+#define HC_SIMA_HABLRFCb        0x002e
+#define HC_SIMA_HABLRAa         0x002f
+#define HC_SIMA_HABLRAb         0x0030
+#define HC_SIMA_HDBBasL         0x0031
+#define HC_SIMA_HDBBasH         0x0032
+#define HC_SIMA_HDBFM           0x0033
+#define HC_SIMA_HFBBMSKL        0x0034
+#define HC_SIMA_HROP            0x0035
+#define HC_SIMA_HFogLF          0x0036
+#define HC_SIMA_HFogCL          0x0037
+#define HC_SIMA_HFogCH          0x0038
+#define HC_SIMA_HFogStL         0x0039
+#define HC_SIMA_HFogStH         0x003a
+#define HC_SIMA_HFogOOdMF       0x003b
+#define HC_SIMA_HFogOOdEF       0x003c
+#define HC_SIMA_HFogEndL        0x003d
+#define HC_SIMA_HFogDenst       0x003e
+/*---- start of texture 0 setting ----
+ */
+#define HC_SIMA_HTX0L0BasL      0x0040
+#define HC_SIMA_HTX0L1BasL      0x0041
+#define HC_SIMA_HTX0L2BasL      0x0042
+#define HC_SIMA_HTX0L3BasL      0x0043
+#define HC_SIMA_HTX0L4BasL      0x0044
+#define HC_SIMA_HTX0L5BasL      0x0045
+#define HC_SIMA_HTX0L6BasL      0x0046
+#define HC_SIMA_HTX0L7BasL      0x0047
+#define HC_SIMA_HTX0L8BasL      0x0048
+#define HC_SIMA_HTX0L9BasL      0x0049
+#define HC_SIMA_HTX0LaBasL      0x004a
+#define HC_SIMA_HTX0LbBasL      0x004b
+#define HC_SIMA_HTX0LcBasL      0x004c
+#define HC_SIMA_HTX0LdBasL      0x004d
+#define HC_SIMA_HTX0LeBasL      0x004e
+#define HC_SIMA_HTX0LfBasL      0x004f
+#define HC_SIMA_HTX0L10BasL     0x0050
+#define HC_SIMA_HTX0L11BasL     0x0051
+#define HC_SIMA_HTX0L012BasH    0x0052
+#define HC_SIMA_HTX0L345BasH    0x0053
+#define HC_SIMA_HTX0L678BasH    0x0054
+#define HC_SIMA_HTX0L9abBasH    0x0055
+#define HC_SIMA_HTX0LcdeBasH    0x0056
+#define HC_SIMA_HTX0Lf1011BasH  0x0057
+#define HC_SIMA_HTX0L0Pit       0x0058
+#define HC_SIMA_HTX0L1Pit       0x0059
+#define HC_SIMA_HTX0L2Pit       0x005a
+#define HC_SIMA_HTX0L3Pit       0x005b
+#define HC_SIMA_HTX0L4Pit       0x005c
+#define HC_SIMA_HTX0L5Pit       0x005d
+#define HC_SIMA_HTX0L6Pit       0x005e
+#define HC_SIMA_HTX0L7Pit       0x005f
+#define HC_SIMA_HTX0L8Pit       0x0060
+#define HC_SIMA_HTX0L9Pit       0x0061
+#define HC_SIMA_HTX0LaPit       0x0062
+#define HC_SIMA_HTX0LbPit       0x0063
+#define HC_SIMA_HTX0LcPit       0x0064
+#define HC_SIMA_HTX0LdPit       0x0065
+#define HC_SIMA_HTX0LePit       0x0066
+#define HC_SIMA_HTX0LfPit       0x0067
+#define HC_SIMA_HTX0L10Pit      0x0068
+#define HC_SIMA_HTX0L11Pit      0x0069
+#define HC_SIMA_HTX0L0_5WE      0x006a
+#define HC_SIMA_HTX0L6_bWE      0x006b
+#define HC_SIMA_HTX0Lc_11WE     0x006c
+#define HC_SIMA_HTX0L0_5HE      0x006d
+#define HC_SIMA_HTX0L6_bHE      0x006e
+#define HC_SIMA_HTX0Lc_11HE     0x006f
+#define HC_SIMA_HTX0L0OS        0x0070
+#define HC_SIMA_HTX0TB          0x0071
+#define HC_SIMA_HTX0MPMD        0x0072
+#define HC_SIMA_HTX0CLODu       0x0073
+#define HC_SIMA_HTX0FM          0x0074
+#define HC_SIMA_HTX0TRCH        0x0075
+#define HC_SIMA_HTX0TRCL        0x0076
+#define HC_SIMA_HTX0TBC         0x0077
+#define HC_SIMA_HTX0TRAH        0x0078
+#define HC_SIMA_HTX0TBLCsat     0x0079
+#define HC_SIMA_HTX0TBLCop      0x007a
+#define HC_SIMA_HTX0TBLMPfog    0x007b
+#define HC_SIMA_HTX0TBLAsat     0x007c
+#define HC_SIMA_HTX0TBLRCa      0x007d
+#define HC_SIMA_HTX0TBLRCb      0x007e
+#define HC_SIMA_HTX0TBLRCc      0x007f
+#define HC_SIMA_HTX0TBLRCbias   0x0080
+#define HC_SIMA_HTX0TBLRAa      0x0081
+#define HC_SIMA_HTX0TBLRFog     0x0082
+#define HC_SIMA_HTX0BumpM00     0x0083
+#define HC_SIMA_HTX0BumpM01     0x0084
+#define HC_SIMA_HTX0BumpM10     0x0085
+#define HC_SIMA_HTX0BumpM11     0x0086
+#define HC_SIMA_HTX0LScale      0x0087
+/*---- end of texture 0 setting ----      0x008f
+ */
+#define HC_SIMA_TX0TX1_OFF      0x0050
+/*---- start of texture 1 setting ----
+ */
+#define HC_SIMA_HTX1L0BasL      (HC_SIMA_HTX0L0BasL + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L1BasL      (HC_SIMA_HTX0L1BasL + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L2BasL      (HC_SIMA_HTX0L2BasL + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L3BasL      (HC_SIMA_HTX0L3BasL + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L4BasL      (HC_SIMA_HTX0L4BasL + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L5BasL      (HC_SIMA_HTX0L5BasL + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L6BasL      (HC_SIMA_HTX0L6BasL + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L7BasL      (HC_SIMA_HTX0L7BasL + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L8BasL      (HC_SIMA_HTX0L8BasL + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L9BasL      (HC_SIMA_HTX0L9BasL + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1LaBasL      (HC_SIMA_HTX0LaBasL + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1LbBasL      (HC_SIMA_HTX0LbBasL + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1LcBasL      (HC_SIMA_HTX0LcBasL + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1LdBasL      (HC_SIMA_HTX0LdBasL + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1LeBasL      (HC_SIMA_HTX0LeBasL + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1LfBasL      (HC_SIMA_HTX0LfBasL + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L10BasL     (HC_SIMA_HTX0L10BasL + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L11BasL     (HC_SIMA_HTX0L11BasL + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L012BasH    (HC_SIMA_HTX0L012BasH + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L345BasH    (HC_SIMA_HTX0L345BasH + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L678BasH    (HC_SIMA_HTX0L678BasH + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L9abBasH    (HC_SIMA_HTX0L9abBasH + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1LcdeBasH    (HC_SIMA_HTX0LcdeBasH + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1Lf1011BasH  (HC_SIMA_HTX0Lf1011BasH + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L0Pit       (HC_SIMA_HTX0L0Pit + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L1Pit       (HC_SIMA_HTX0L1Pit + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L2Pit       (HC_SIMA_HTX0L2Pit + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L3Pit       (HC_SIMA_HTX0L3Pit + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L4Pit       (HC_SIMA_HTX0L4Pit + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L5Pit       (HC_SIMA_HTX0L5Pit + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L6Pit       (HC_SIMA_HTX0L6Pit + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L7Pit       (HC_SIMA_HTX0L7Pit + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L8Pit       (HC_SIMA_HTX0L8Pit + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L9Pit       (HC_SIMA_HTX0L9Pit + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1LaPit       (HC_SIMA_HTX0LaPit + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1LbPit       (HC_SIMA_HTX0LbPit + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1LcPit       (HC_SIMA_HTX0LcPit + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1LdPit       (HC_SIMA_HTX0LdPit + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1LePit       (HC_SIMA_HTX0LePit + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1LfPit       (HC_SIMA_HTX0LfPit + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L10Pit      (HC_SIMA_HTX0L10Pit + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L11Pit      (HC_SIMA_HTX0L11Pit + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L0_5WE      (HC_SIMA_HTX0L0_5WE + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L6_bWE      (HC_SIMA_HTX0L6_bWE + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1Lc_11WE     (HC_SIMA_HTX0Lc_11WE + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L0_5HE      (HC_SIMA_HTX0L0_5HE + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L6_bHE      (HC_SIMA_HTX0L6_bHE + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1Lc_11HE      (HC_SIMA_HTX0Lc_11HE + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1L0OS        (HC_SIMA_HTX0L0OS + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1TB          (HC_SIMA_HTX0TB + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1MPMD        (HC_SIMA_HTX0MPMD + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1CLODu       (HC_SIMA_HTX0CLODu + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1FM          (HC_SIMA_HTX0FM + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1TRCH        (HC_SIMA_HTX0TRCH + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1TRCL        (HC_SIMA_HTX0TRCL + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1TBC         (HC_SIMA_HTX0TBC + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1TRAH        (HC_SIMA_HTX0TRAH + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1LTC         (HC_SIMA_HTX0LTC + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1LTA         (HC_SIMA_HTX0LTA + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1TBLCsat     (HC_SIMA_HTX0TBLCsat + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1TBLCop      (HC_SIMA_HTX0TBLCop + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1TBLMPfog    (HC_SIMA_HTX0TBLMPfog + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1TBLAsat     (HC_SIMA_HTX0TBLAsat + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1TBLRCa      (HC_SIMA_HTX0TBLRCa + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1TBLRCb      (HC_SIMA_HTX0TBLRCb + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1TBLRCc      (HC_SIMA_HTX0TBLRCc + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1TBLRCbias   (HC_SIMA_HTX0TBLRCbias + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1TBLRAa      (HC_SIMA_HTX0TBLRAa + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1TBLRFog     (HC_SIMA_HTX0TBLRFog + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1BumpM00     (HC_SIMA_HTX0BumpM00 + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1BumpM01     (HC_SIMA_HTX0BumpM01 + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1BumpM10     (HC_SIMA_HTX0BumpM10 + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1BumpM11     (HC_SIMA_HTX0BumpM11 + HC_SIMA_TX0TX1_OFF)
+#define HC_SIMA_HTX1LScale      (HC_SIMA_HTX0LScale + HC_SIMA_TX0TX1_OFF)
+/*---- end of texture 1 setting ---- 0xaf
+ */
+#define HC_SIMA_HTXSMD          0x00b0
+#define HC_SIMA_HenFIFOAT       0x00b1
+#define HC_SIMA_HFBDrawFirst    0x00b2
+#define HC_SIMA_HFBBasL         0x00b3
+#define HC_SIMA_HTArbRCM        0x00b4
+#define HC_SIMA_HTArbRZ         0x00b5
+#define HC_SIMA_HTArbWZ         0x00b6
+#define HC_SIMA_HTArbRTX        0x00b7
+#define HC_SIMA_HTArbRCW        0x00b8
+#define HC_SIMA_HTArbE2         0x00b9
+#define HC_SIMA_HGEMITout       0x00ba
+#define HC_SIMA_HFthRTXD        0x00bb
+#define HC_SIMA_HFthRTXA        0x00bc
+/* Define the texture palette 0
+ */
+#define HC_SIMA_HTP0            0x0100
+#define HC_SIMA_HTP1            0x0200
+#define HC_SIMA_FOGTABLE        0x0300
+#define HC_SIMA_STIPPLE         0x0400
+#define HC_SIMA_HE3Fire         0x0440
+#define HC_SIMA_TRANS_SET       0x0441
+#define HC_SIMA_HREngSt         0x0442
+#define HC_SIMA_HRFIFOempty     0x0443
+#define HC_SIMA_HRFIFOfull      0x0444
+#define HC_SIMA_HRErr           0x0445
+#define HC_SIMA_FIFOstatus      0x0446
+
+/******************************************************************************
+** Define the AGP command header.
+******************************************************************************/
+#define HC_ACMD_MASK            0xfe000000
+#define HC_ACMD_SUB_MASK        0x0c000000
+#define HC_ACMD_HCmdA           0xee000000
+#define HC_ACMD_HCmdB           0xec000000
+#define HC_ACMD_HCmdC           0xea000000
+#define HC_ACMD_H1              0xf0000000
+#define HC_ACMD_H2              0xf2000000
+#define HC_ACMD_H3              0xf4000000
+#define HC_ACMD_H4              0xf6000000
+
+#define HC_ACMD_H1IO_MASK       0x000001ff
+#define HC_ACMD_H2IO1_MASK      0x001ff000
+#define HC_ACMD_H2IO2_MASK      0x000001ff
+#define HC_ACMD_H2IO1_SHIFT     12
+#define HC_ACMD_H2IO2_SHIFT     0
+#define HC_ACMD_H3IO_MASK       0x000001ff
+#define HC_ACMD_H3COUNT_MASK    0x01fff000
+#define HC_ACMD_H3COUNT_SHIFT   12
+#define HC_ACMD_H4ID_MASK       0x000001ff
+#define HC_ACMD_H4COUNT_MASK    0x01fffe00
+#define HC_ACMD_H4COUNT_SHIFT   9
+
+/********************************************************************************
+** Define Header
+********************************************************************************/
+#define HC_HEADER2		0xF210F110
+
+/********************************************************************************
+** Define Dummy Value
+********************************************************************************/
+#define HC_DUMMY		0xCCCCCCCC
+/********************************************************************************
+** Define for DMA use
+********************************************************************************/
+#define HALCYON_HEADER2     0XF210F110
+#define HALCYON_FIRECMD     0XEE100000
+#define HALCYON_FIREMASK    0XFFF00000
+#define HALCYON_CMDB        0XEC000000
+#define HALCYON_CMDBMASK    0XFFFE0000
+#define HALCYON_SUB_ADDR0   0X00000000
+#define HALCYON_HEADER1MASK 0XFFFFFC00
+#define HALCYON_HEADER1     0XF0000000
+#define HC_SubA_HAGPBstL        0x0060
+#define HC_SubA_HAGPBendL       0x0061
+#define HC_SubA_HAGPCMNT        0x0062
+#define HC_SubA_HAGPBpL         0x0063
+#define HC_SubA_HAGPBpH         0x0064
+#define HC_HAGPCMNT_MASK        0x00800000
+#define HC_HCmdErrClr_MASK      0x00400000
+#define HC_HAGPBendH_MASK       0x0000ff00
+#define HC_HAGPBstH_MASK        0x000000ff
+#define HC_HAGPBendH_SHIFT      8
+#define HC_HAGPBstH_SHIFT       0
+#define HC_HAGPBpL_MASK         0x00fffffc
+#define HC_HAGPBpID_MASK        0x00000003
+#define HC_HAGPBpID_PAUSE       0x00000000
+#define HC_HAGPBpID_JUMP        0x00000001
+#define HC_HAGPBpID_STOP        0x00000002
+#define HC_HAGPBpH_MASK         0x00ffffff
+
+
+#define VIA_VIDEO_HEADER5       0xFE040000
+#define VIA_VIDEO_HEADER6       0xFE050000
+#define VIA_VIDEO_HEADER7       0xFE060000
+#define VIA_VIDEOMASK           0xFFFF0000
+#endif
diff --git a/drivers/char/drm/via_dma.c b/drivers/char/drm/via_dma.c
new file mode 100644
--- /dev/null
+++ b/drivers/char/drm/via_dma.c
@@ -0,0 +1,741 @@
+/* via_dma.c -- DMA support for the VIA Unichrome/Pro
+ * 
+ * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Copyright 2004 Digeo, Inc., Palo Alto, CA, U.S.A.
+ * All Rights Reserved.
+ * 
+ * Copyright 2004 The Unichrome project.
+ * 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, sub license,
+ * 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 NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS 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: 
+ *    Tungsten Graphics, 
+ *    Erdi Chen, 
+ *    Thomas Hellstrom.
+ */
+
+#include "drmP.h"
+#include "drm.h"
+#include "via_drm.h"
+#include "via_drv.h"
+#include "via_3d_reg.h"
+
+#define CMDBUF_ALIGNMENT_SIZE   (0x100)
+#define CMDBUF_ALIGNMENT_MASK   (0x0ff)
+
+/* defines for VIA 3D registers */
+#define VIA_REG_STATUS          0x400
+#define VIA_REG_TRANSET         0x43C
+#define VIA_REG_TRANSPACE       0x440
+
+/* VIA_REG_STATUS(0x400): Engine Status */
+#define VIA_CMD_RGTR_BUSY       0x00000080	/* Command Regulator is busy */
+#define VIA_2D_ENG_BUSY         0x00000001	/* 2D Engine is busy */
+#define VIA_3D_ENG_BUSY         0x00000002	/* 3D Engine is busy */
+#define VIA_VR_QUEUE_BUSY       0x00020000	/* Virtual Queue is busy */
+
+#define SetReg2DAGP(nReg, nData) {				\
+	*((uint32_t *)(vb)) = ((nReg) >> 2) | HALCYON_HEADER1;	\
+	*((uint32_t *)(vb) + 1) = (nData);			\
+	vb = ((uint32_t *)vb) + 2;				\
+	dev_priv->dma_low +=8;					\
+}
+
+#define via_flush_write_combine() DRM_MEMORYBARRIER() 
+
+#define VIA_OUT_RING_QW(w1,w2)			\
+	*vb++ = (w1);				\
+	*vb++ = (w2);				\
+	dev_priv->dma_low += 8; 
+
+static void via_cmdbuf_start(drm_via_private_t * dev_priv);
+static void via_cmdbuf_pause(drm_via_private_t * dev_priv);
+static void via_cmdbuf_reset(drm_via_private_t * dev_priv);
+static void via_cmdbuf_rewind(drm_via_private_t * dev_priv);
+static int via_wait_idle(drm_via_private_t * dev_priv);
+static void via_pad_cache(drm_via_private_t *dev_priv, int qwords);
+
+
+/*
+ * Free space in command buffer.
+ */
+
+static uint32_t
+via_cmdbuf_space(drm_via_private_t *dev_priv)
+{
+	uint32_t agp_base = dev_priv->dma_offset + 
+		(uint32_t) dev_priv->agpAddr;
+	uint32_t hw_addr = *(dev_priv->hw_addr_ptr) - agp_base;
+	
+	return ((hw_addr <= dev_priv->dma_low) ? 
+		(dev_priv->dma_high + hw_addr - dev_priv->dma_low) : 
+		(hw_addr - dev_priv->dma_low));
+}
+
+/*
+ * How much does the command regulator lag behind?
+ */
+
+static uint32_t
+via_cmdbuf_lag(drm_via_private_t *dev_priv)
+{
+	uint32_t agp_base = dev_priv->dma_offset + 
+		(uint32_t) dev_priv->agpAddr;
+	uint32_t hw_addr = *(dev_priv->hw_addr_ptr) - agp_base;
+	
+	return ((hw_addr <= dev_priv->dma_low) ? 
+		(dev_priv->dma_low - hw_addr) : 
+		(dev_priv->dma_wrap + dev_priv->dma_low - hw_addr));
+}
+
+/*
+ * Check that the given size fits in the buffer, otherwise wait.
+ */
+
+static inline int
+via_cmdbuf_wait(drm_via_private_t * dev_priv, unsigned int size)
+{
+	uint32_t agp_base = dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr;
+	uint32_t cur_addr, hw_addr, next_addr;
+	volatile uint32_t *hw_addr_ptr;
+	uint32_t count;
+	hw_addr_ptr = dev_priv->hw_addr_ptr;
+	cur_addr = dev_priv->dma_low;
+	next_addr = cur_addr + size + 512*1024;
+	count = 1000000;
+	do {
+	        hw_addr = *hw_addr_ptr - agp_base;
+		if (count-- == 0) {
+			DRM_ERROR("via_cmdbuf_wait timed out hw %x cur_addr %x next_addr %x\n",
+				  hw_addr, cur_addr, next_addr);
+			return -1;
+		}
+	} while ((cur_addr < hw_addr) && (next_addr >= hw_addr));
+	return 0;
+}
+
+
+/*
+ * Checks whether buffer head has reach the end. Rewind the ring buffer
+ * when necessary.
+ *
+ * Returns virtual pointer to ring buffer.
+ */
+
+static inline uint32_t *via_check_dma(drm_via_private_t * dev_priv,
+				      unsigned int size)
+{
+	if ((dev_priv->dma_low + size + 4*CMDBUF_ALIGNMENT_SIZE) > dev_priv->dma_high) {
+		via_cmdbuf_rewind(dev_priv);
+	}
+	if (via_cmdbuf_wait(dev_priv, size) != 0) {
+		return NULL;
+	}
+
+	return (uint32_t *) (dev_priv->dma_ptr + dev_priv->dma_low);
+}
+
+int via_dma_cleanup(drm_device_t * dev)
+{
+	if (dev->dev_private) {
+		drm_via_private_t *dev_priv =
+			(drm_via_private_t *) dev->dev_private;
+
+		if (dev_priv->ring.virtual_start) {
+			via_cmdbuf_reset(dev_priv);
+
+			drm_core_ioremapfree(&dev_priv->ring.map, dev);
+			dev_priv->ring.virtual_start = NULL;
+		}
+
+	}
+
+	return 0;
+}
+
+static int via_initialize(drm_device_t * dev,
+			  drm_via_private_t * dev_priv,
+			  drm_via_dma_init_t * init)
+{
+	if (!dev_priv || !dev_priv->mmio) {
+		DRM_ERROR("via_dma_init called before via_map_init\n");
+		return DRM_ERR(EFAULT);
+	}
+
+	if (dev_priv->ring.virtual_start != NULL) {
+		DRM_ERROR("%s called again without calling cleanup\n",
+			  __FUNCTION__);
+		return DRM_ERR(EFAULT);
+	}
+
+	if (!dev->agp || !dev->agp->base) {
+		DRM_ERROR("%s called with no agp memory available\n", 
+			  __FUNCTION__);
+		return DRM_ERR(EFAULT);
+	}
+
+	dev_priv->ring.map.offset = dev->agp->base + init->offset;
+	dev_priv->ring.map.size = init->size;
+	dev_priv->ring.map.type = 0;
+	dev_priv->ring.map.flags = 0;
+	dev_priv->ring.map.mtrr = 0;
+
+	drm_core_ioremap(&dev_priv->ring.map, dev);
+
+	if (dev_priv->ring.map.handle == NULL) {
+		via_dma_cleanup(dev);
+		DRM_ERROR("can not ioremap virtual address for"
+			  " ring buffer\n");
+		return DRM_ERR(ENOMEM);
+	}
+
+	dev_priv->ring.virtual_start = dev_priv->ring.map.handle;
+
+	dev_priv->dma_ptr = dev_priv->ring.virtual_start;
+	dev_priv->dma_low = 0;
+	dev_priv->dma_high = init->size;
+	dev_priv->dma_wrap = init->size;
+	dev_priv->dma_offset = init->offset;
+	dev_priv->last_pause_ptr = NULL;
+	dev_priv->hw_addr_ptr = dev_priv->mmio->handle + init->reg_pause_addr;
+
+	via_cmdbuf_start(dev_priv);
+
+	return 0;
+}
+
+int via_dma_init(DRM_IOCTL_ARGS)
+{
+	DRM_DEVICE;
+	drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
+	drm_via_dma_init_t init;
+	int retcode = 0;
+
+	DRM_COPY_FROM_USER_IOCTL(init, (drm_via_dma_init_t __user *) data,
+				 sizeof(init));
+
+	switch (init.func) {
+	case VIA_INIT_DMA:
+		if (!capable(CAP_SYS_ADMIN))
+			retcode = DRM_ERR(EPERM);
+		else
+			retcode = via_initialize(dev, dev_priv, &init);
+		break;
+	case VIA_CLEANUP_DMA:
+		if (!capable(CAP_SYS_ADMIN))
+			retcode = DRM_ERR(EPERM);
+		else
+			retcode = via_dma_cleanup(dev);
+		break;
+        case VIA_DMA_INITIALIZED:
+		retcode = (dev_priv->ring.virtual_start != NULL) ? 
+			0: DRM_ERR( EFAULT );
+	        break;
+	default:
+		retcode = DRM_ERR(EINVAL);
+		break;
+	}
+
+	return retcode;
+}
+
+
+
+static int via_dispatch_cmdbuffer(drm_device_t * dev, drm_via_cmdbuffer_t * cmd)
+{
+	drm_via_private_t *dev_priv;
+	uint32_t *vb;
+	int ret;
+
+	dev_priv = (drm_via_private_t *) dev->dev_private;
+
+	if (dev_priv->ring.virtual_start == NULL) {
+		DRM_ERROR("%s called without initializing AGP ring buffer.\n",
+			  __FUNCTION__);
+		return DRM_ERR(EFAULT);
+	}
+
+	if (cmd->size > VIA_PCI_BUF_SIZE) {
+		return DRM_ERR(ENOMEM);
+	} 
+
+
+	if (DRM_COPY_FROM_USER(dev_priv->pci_buf, cmd->buf, cmd->size))
+		return DRM_ERR(EFAULT);
+
+	/*
+	 * Running this function on AGP memory is dead slow. Therefore
+	 * we run it on a temporary cacheable system memory buffer and
+	 * copy it to AGP memory when ready.
+	 */
+
+		
+	if ((ret = via_verify_command_stream((uint32_t *)dev_priv->pci_buf, cmd->size, dev, 1))) {
+		return ret;
+	}
+       	
+	
+	vb = via_check_dma(dev_priv, (cmd->size < 0x100) ? 0x102 : cmd->size);
+	if (vb == NULL) {
+		return DRM_ERR(EAGAIN);
+	}
+
+	memcpy(vb, dev_priv->pci_buf, cmd->size);
+	
+	dev_priv->dma_low += cmd->size;
+
+	/*
+	 * Small submissions somehow stalls the CPU. (AGP cache effects?)
+	 * pad to greater size.
+	 */
+
+	if (cmd->size < 0x100)
+	  via_pad_cache(dev_priv,(0x100 - cmd->size) >> 3);
+	via_cmdbuf_pause(dev_priv);
+
+	return 0;
+}
+
+int via_driver_dma_quiescent(drm_device_t * dev)
+{
+	drm_via_private_t *dev_priv = dev->dev_private;
+
+	if (!via_wait_idle(dev_priv)) {
+		return DRM_ERR(EBUSY);
+	}
+	return 0;
+}
+
+int via_flush_ioctl(DRM_IOCTL_ARGS)
+{
+	DRM_DEVICE;
+
+	LOCK_TEST_WITH_RETURN( dev, filp );
+
+	return via_driver_dma_quiescent(dev);
+}
+
+int via_cmdbuffer(DRM_IOCTL_ARGS)
+{
+	DRM_DEVICE;
+	drm_via_cmdbuffer_t cmdbuf;
+	int ret;
+
+	LOCK_TEST_WITH_RETURN( dev, filp );
+
+	DRM_COPY_FROM_USER_IOCTL(cmdbuf, (drm_via_cmdbuffer_t __user *) data,
+				 sizeof(cmdbuf));
+
+	DRM_DEBUG("via cmdbuffer, buf %p size %lu\n", cmdbuf.buf, cmdbuf.size);
+
+	ret = via_dispatch_cmdbuffer(dev, &cmdbuf);
+	if (ret) {
+		return ret;
+	}
+
+	return 0;
+}
+
+extern int 
+via_parse_command_stream(drm_device_t *dev, const uint32_t * buf, unsigned int size);
+static int via_dispatch_pci_cmdbuffer(drm_device_t * dev,
+				      drm_via_cmdbuffer_t * cmd)
+{
+	drm_via_private_t *dev_priv = dev->dev_private;
+	int ret;
+
+	if (cmd->size > VIA_PCI_BUF_SIZE) {
+		return DRM_ERR(ENOMEM);
+	} 
+	if (DRM_COPY_FROM_USER(dev_priv->pci_buf, cmd->buf, cmd->size))
+		return DRM_ERR(EFAULT);
+	
+	if ((ret = via_verify_command_stream((uint32_t *)dev_priv->pci_buf, cmd->size, dev, 0))) {
+		return ret;
+	}
+	
+	ret = via_parse_command_stream(dev, (const uint32_t *)dev_priv->pci_buf, cmd->size);
+	return ret;
+}
+
+int via_pci_cmdbuffer(DRM_IOCTL_ARGS)
+{
+	DRM_DEVICE;
+	drm_via_cmdbuffer_t cmdbuf;
+	int ret;
+
+	LOCK_TEST_WITH_RETURN( dev, filp );
+
+	DRM_COPY_FROM_USER_IOCTL(cmdbuf, (drm_via_cmdbuffer_t __user *) data,
+				 sizeof(cmdbuf));
+
+	DRM_DEBUG("via_pci_cmdbuffer, buf %p size %lu\n", cmdbuf.buf,
+		  cmdbuf.size);
+
+	ret = via_dispatch_pci_cmdbuffer(dev, &cmdbuf);
+	if (ret) {
+		return ret;
+	}
+
+	return 0;
+}
+
+
+static inline uint32_t *via_align_buffer(drm_via_private_t * dev_priv,
+					 uint32_t * vb, int qw_count)
+{
+        for (; qw_count > 0; --qw_count) {
+		VIA_OUT_RING_QW(HC_DUMMY, HC_DUMMY);
+	}
+	return vb;
+}
+
+
+/*
+ * This function is used internally by ring buffer mangement code.
+ *
+ * Returns virtual pointer to ring buffer.
+ */
+static inline uint32_t *via_get_dma(drm_via_private_t * dev_priv)
+{
+	return (uint32_t *) (dev_priv->dma_ptr + dev_priv->dma_low);
+}
+
+/*
+ * Hooks a segment of data into the tail of the ring-buffer by
+ * modifying the pause address stored in the buffer itself. If
+ * the regulator has already paused, restart it.
+ */
+static int via_hook_segment(drm_via_private_t *dev_priv,
+			    uint32_t pause_addr_hi, uint32_t pause_addr_lo,
+			    int no_pci_fire)
+{
+	int paused, count;
+	volatile uint32_t *paused_at = dev_priv->last_pause_ptr;
+
+	via_flush_write_combine();
+	while(! *(via_get_dma(dev_priv)-1));
+	*dev_priv->last_pause_ptr = pause_addr_lo;
+	via_flush_write_combine();
+
+	/*
+	 * The below statement is inserted to really force the flush.
+	 * Not sure it is needed.
+	 */
+
+	while(! *dev_priv->last_pause_ptr);
+	dev_priv->last_pause_ptr = via_get_dma(dev_priv) - 1;
+	while(! *dev_priv->last_pause_ptr);
+
+
+	paused = 0;
+	count = 20; 
+
+	while (!(paused = (VIA_READ(0x41c) & 0x80000000)) && count--);
+	if ((count <= 8) && (count >= 0)) {
+		uint32_t rgtr, ptr;
+		rgtr = *(dev_priv->hw_addr_ptr);
+		ptr = ((char *)dev_priv->last_pause_ptr - dev_priv->dma_ptr) + 
+			dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr + 4 - 
+			CMDBUF_ALIGNMENT_SIZE;
+		if (rgtr <= ptr) {
+			DRM_ERROR("Command regulator\npaused at count %d, address %x, "
+				  "while current pause address is %x.\n"
+				  "Please mail this message to "
+				  "<unichrome-devel@lists.sourceforge.net>\n",
+				  count, rgtr, ptr);
+		}
+	}
+		
+	if (paused && !no_pci_fire) {
+	        uint32_t rgtr,ptr;
+		uint32_t ptr_low;
+
+		count = 1000000;
+		while ((VIA_READ(VIA_REG_STATUS) & VIA_CMD_RGTR_BUSY) && count--);
+		
+		rgtr = *(dev_priv->hw_addr_ptr);
+		ptr = ((char *)paused_at - dev_priv->dma_ptr) + 
+			dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr + 4;
+		
+
+		ptr_low = (ptr > 3*CMDBUF_ALIGNMENT_SIZE) ? 
+			ptr - 3*CMDBUF_ALIGNMENT_SIZE : 0;
+		if (rgtr <= ptr && rgtr >= ptr_low) {
+			VIA_WRITE(VIA_REG_TRANSET, (HC_ParaType_PreCR << 16));
+			VIA_WRITE(VIA_REG_TRANSPACE, pause_addr_hi);
+			VIA_WRITE(VIA_REG_TRANSPACE, pause_addr_lo);
+		} 
+	}
+	return paused;
+}
+
+
+
+static int via_wait_idle(drm_via_private_t * dev_priv)
+{
+	int count = 10000000;
+	while (count-- && (VIA_READ(VIA_REG_STATUS) &
+			   (VIA_CMD_RGTR_BUSY | VIA_2D_ENG_BUSY |
+			    VIA_3D_ENG_BUSY))) ;
+	return count;
+}
+
+static uint32_t *via_align_cmd(drm_via_private_t * dev_priv, uint32_t cmd_type,
+			       uint32_t addr, uint32_t *cmd_addr_hi, 
+			       uint32_t *cmd_addr_lo,
+			       int skip_wait)
+{
+	uint32_t agp_base;
+	uint32_t cmd_addr, addr_lo, addr_hi;
+	uint32_t *vb;
+	uint32_t qw_pad_count;
+
+	if (!skip_wait)
+		via_cmdbuf_wait(dev_priv, 2*CMDBUF_ALIGNMENT_SIZE);
+
+	vb = via_get_dma(dev_priv);
+	VIA_OUT_RING_QW( HC_HEADER2 | ((VIA_REG_TRANSET >> 2) << 12) |
+			 (VIA_REG_TRANSPACE >> 2), HC_ParaType_PreCR << 16); 
+	agp_base = dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr;
+	qw_pad_count = (CMDBUF_ALIGNMENT_SIZE >> 3) -
+		((dev_priv->dma_low & CMDBUF_ALIGNMENT_MASK) >> 3);
+
+	
+	cmd_addr = (addr) ? addr : 
+		agp_base + dev_priv->dma_low - 8 + (qw_pad_count << 3);
+	addr_lo = ((HC_SubA_HAGPBpL << 24) | (cmd_type & HC_HAGPBpID_MASK) |
+		   (cmd_addr & HC_HAGPBpL_MASK));
+	addr_hi = ((HC_SubA_HAGPBpH << 24) | (cmd_addr >> 24));
+
+	vb = via_align_buffer(dev_priv, vb, qw_pad_count - 1);
+	VIA_OUT_RING_QW(*cmd_addr_hi = addr_hi, 
+			*cmd_addr_lo = addr_lo);
+	return vb;
+}
+
+
+
+
+static void via_cmdbuf_start(drm_via_private_t * dev_priv)
+{
+	uint32_t pause_addr_lo, pause_addr_hi;
+	uint32_t start_addr, start_addr_lo;
+	uint32_t end_addr, end_addr_lo;
+	uint32_t command;
+	uint32_t agp_base;
+
+
+	dev_priv->dma_low = 0;
+
+	agp_base = dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr;
+	start_addr = agp_base;
+	end_addr = agp_base + dev_priv->dma_high;
+
+	start_addr_lo = ((HC_SubA_HAGPBstL << 24) | (start_addr & 0xFFFFFF));
+	end_addr_lo = ((HC_SubA_HAGPBendL << 24) | (end_addr & 0xFFFFFF));
+	command = ((HC_SubA_HAGPCMNT << 24) | (start_addr >> 24) |
+		   ((end_addr & 0xff000000) >> 16));
+
+	dev_priv->last_pause_ptr = 
+		via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0, 
+			      &pause_addr_hi, & pause_addr_lo, 1) - 1;
+
+	via_flush_write_combine();
+	while(! *dev_priv->last_pause_ptr);
+
+	VIA_WRITE(VIA_REG_TRANSET, (HC_ParaType_PreCR << 16));
+	VIA_WRITE(VIA_REG_TRANSPACE, command);
+	VIA_WRITE(VIA_REG_TRANSPACE, start_addr_lo);
+	VIA_WRITE(VIA_REG_TRANSPACE, end_addr_lo);
+
+	VIA_WRITE(VIA_REG_TRANSPACE, pause_addr_hi);
+	VIA_WRITE(VIA_REG_TRANSPACE, pause_addr_lo);
+
+	VIA_WRITE(VIA_REG_TRANSPACE, command | HC_HAGPCMNT_MASK);
+}
+
+static void via_pad_cache(drm_via_private_t *dev_priv, int qwords)
+{
+	uint32_t *vb;
+
+	via_cmdbuf_wait(dev_priv, qwords + 2);
+	vb = via_get_dma(dev_priv);
+	VIA_OUT_RING_QW( HC_HEADER2, HC_ParaType_NotTex << 16);
+	via_align_buffer(dev_priv,vb,qwords);
+}
+
+static inline void via_dummy_bitblt(drm_via_private_t * dev_priv)
+{
+	uint32_t *vb = via_get_dma(dev_priv);
+	SetReg2DAGP(0x0C, (0 | (0 << 16)));
+	SetReg2DAGP(0x10, 0 | (0 << 16));
+	SetReg2DAGP(0x0, 0x1 | 0x2000 | 0xAA000000); 
+}
+
+
+static void via_cmdbuf_jump(drm_via_private_t * dev_priv)
+{
+	uint32_t agp_base;
+	uint32_t pause_addr_lo, pause_addr_hi;
+	uint32_t jump_addr_lo, jump_addr_hi;
+	volatile uint32_t *last_pause_ptr;
+	uint32_t dma_low_save1, dma_low_save2;
+
+	agp_base = dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr;
+	via_align_cmd(dev_priv,  HC_HAGPBpID_JUMP, 0, &jump_addr_hi, 
+		      &jump_addr_lo, 0);
+	
+	dev_priv->dma_wrap = dev_priv->dma_low;
+
+
+	/*
+	 * Wrap command buffer to the beginning.
+	 */
+
+	dev_priv->dma_low = 0;
+	if (via_cmdbuf_wait(dev_priv, CMDBUF_ALIGNMENT_SIZE) != 0) {
+		DRM_ERROR("via_cmdbuf_jump failed\n");
+	}
+
+	via_dummy_bitblt(dev_priv);
+	via_dummy_bitblt(dev_priv); 
+
+	last_pause_ptr = via_align_cmd(dev_priv,  HC_HAGPBpID_PAUSE, 0, &pause_addr_hi, 
+				       &pause_addr_lo, 0) -1;
+	via_align_cmd(dev_priv,  HC_HAGPBpID_PAUSE, 0, &pause_addr_hi, 
+		      &pause_addr_lo, 0);
+
+	*last_pause_ptr = pause_addr_lo;
+	dma_low_save1 = dev_priv->dma_low;
+
+	/*
+	 * Now, set a trap that will pause the regulator if it tries to rerun the old
+	 * command buffer. (Which may happen if via_hook_segment detecs a command regulator pause
+	 * and reissues the jump command over PCI, while the regulator has already taken the jump
+	 * and actually paused at the current buffer end).
+	 * There appears to be no other way to detect this condition, since the hw_addr_pointer
+	 * does not seem to get updated immediately when a jump occurs.
+	 */
+
+	last_pause_ptr = via_align_cmd(dev_priv,  HC_HAGPBpID_PAUSE, 0, &pause_addr_hi, 
+				       &pause_addr_lo, 0) -1;
+	via_align_cmd(dev_priv,  HC_HAGPBpID_PAUSE, 0, &pause_addr_hi, 
+		      &pause_addr_lo, 0);
+	*last_pause_ptr = pause_addr_lo;
+
+	dma_low_save2 = dev_priv->dma_low;
+	dev_priv->dma_low = dma_low_save1;	
+	via_hook_segment( dev_priv, jump_addr_hi, jump_addr_lo, 0);
+	dev_priv->dma_low = dma_low_save2;
+	via_hook_segment( dev_priv, pause_addr_hi, pause_addr_lo, 0);
+}
+
+
+static void via_cmdbuf_rewind(drm_via_private_t * dev_priv)
+{
+	via_cmdbuf_jump(dev_priv); 
+}
+
+static void via_cmdbuf_flush(drm_via_private_t * dev_priv, uint32_t cmd_type)
+{
+	uint32_t pause_addr_lo, pause_addr_hi;
+
+	via_align_cmd(dev_priv, cmd_type, 0, &pause_addr_hi, &pause_addr_lo, 0);
+	via_hook_segment( dev_priv, pause_addr_hi, pause_addr_lo, 0);
+}
+
+
+static void via_cmdbuf_pause(drm_via_private_t * dev_priv)
+{
+	via_cmdbuf_flush(dev_priv, HC_HAGPBpID_PAUSE);
+}
+
+static void via_cmdbuf_reset(drm_via_private_t * dev_priv)
+{
+	via_cmdbuf_flush(dev_priv, HC_HAGPBpID_STOP);
+	via_wait_idle(dev_priv);
+}
+
+/*
+ * User interface to the space and lag functions.
+ */
+
+int 
+via_cmdbuf_size(DRM_IOCTL_ARGS)
+{
+	DRM_DEVICE;
+	drm_via_cmdbuf_size_t d_siz;
+	int ret = 0;
+	uint32_t tmp_size, count;
+	drm_via_private_t *dev_priv;
+
+	DRM_DEBUG("via cmdbuf_size\n");
+	LOCK_TEST_WITH_RETURN( dev, filp );
+
+	dev_priv = (drm_via_private_t *) dev->dev_private;
+
+	if (dev_priv->ring.virtual_start == NULL) {
+		DRM_ERROR("%s called without initializing AGP ring buffer.\n",
+			  __FUNCTION__);
+		return DRM_ERR(EFAULT);
+	}
+
+	DRM_COPY_FROM_USER_IOCTL(d_siz, (drm_via_cmdbuf_size_t __user *) data,
+				 sizeof(d_siz));
+
+
+	count = 1000000;
+	tmp_size = d_siz.size;
+	switch(d_siz.func) {
+	case VIA_CMDBUF_SPACE:
+		while (((tmp_size = via_cmdbuf_space(dev_priv)) < d_siz.size) && count--) {
+			if (!d_siz.wait) {
+				break;
+			}
+		}
+		if (!count) {
+			DRM_ERROR("VIA_CMDBUF_SPACE timed out.\n");
+			ret = DRM_ERR(EAGAIN);
+		}
+		break;
+	case VIA_CMDBUF_LAG:
+		while (((tmp_size = via_cmdbuf_lag(dev_priv)) > d_siz.size) && count--) {
+			if (!d_siz.wait) {
+				break;
+			}
+		}
+		if (!count) {
+			DRM_ERROR("VIA_CMDBUF_LAG timed out.\n");
+			ret = DRM_ERR(EAGAIN);
+		}
+		break;
+	default:
+		ret = DRM_ERR(EFAULT);
+	}
+	d_siz.size = tmp_size;
+
+	DRM_COPY_TO_USER_IOCTL((drm_via_cmdbuf_size_t __user *) data, d_siz,
+			       sizeof(d_siz));
+	return ret;
+}
diff --git a/drivers/char/drm/via_drm.h b/drivers/char/drm/via_drm.h
new file mode 100644
--- /dev/null
+++ b/drivers/char/drm/via_drm.h
@@ -0,0 +1,243 @@
+/*
+ * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2003 S3 Graphics, Inc. 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, sub license,
+ * 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 NON-INFRINGEMENT. IN NO EVENT SHALL
+ * VIA, S3 GRAPHICS, 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.
+ */
+#ifndef _VIA_DRM_H_
+#define _VIA_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 _VIA_DEFINES_
+#define _VIA_DEFINES_
+
+#ifndef __KERNEL__
+#include "via_drmclient.h"
+#endif
+
+#define VIA_NR_SAREA_CLIPRECTS 		8
+#define VIA_NR_XVMC_PORTS               10
+#define VIA_NR_XVMC_LOCKS               5
+#define VIA_MAX_CACHELINE_SIZE          64
+#define XVMCLOCKPTR(saPriv,lockNo)					\
+	((volatile drm_hw_lock_t *)(((((unsigned long) (saPriv)->XvMCLockArea) + \
+				      (VIA_MAX_CACHELINE_SIZE - 1)) &	\
+				     ~(VIA_MAX_CACHELINE_SIZE - 1)) +	\
+				    VIA_MAX_CACHELINE_SIZE*(lockNo)))
+
+/* Each region is a minimum of 64k, and there are at most 64 of them.
+ */
+#define VIA_NR_TEX_REGIONS 64
+#define VIA_LOG_MIN_TEX_REGION_SIZE 16
+#endif
+
+#define VIA_UPLOAD_TEX0IMAGE  0x1	/* handled clientside */
+#define VIA_UPLOAD_TEX1IMAGE  0x2	/* handled clientside */
+#define VIA_UPLOAD_CTX        0x4
+#define VIA_UPLOAD_BUFFERS    0x8
+#define VIA_UPLOAD_TEX0       0x10
+#define VIA_UPLOAD_TEX1       0x20
+#define VIA_UPLOAD_CLIPRECTS  0x40
+#define VIA_UPLOAD_ALL        0xff
+
+/* VIA specific ioctls */
+#define DRM_VIA_ALLOCMEM	0x00
+#define DRM_VIA_FREEMEM	        0x01
+#define DRM_VIA_AGP_INIT	0x02
+#define DRM_VIA_FB_INIT	        0x03
+#define DRM_VIA_MAP_INIT	0x04
+#define DRM_VIA_DEC_FUTEX       0x05
+#define NOT_USED
+#define DRM_VIA_DMA_INIT	0x07
+#define DRM_VIA_CMDBUFFER	0x08
+#define DRM_VIA_FLUSH	        0x09
+#define DRM_VIA_PCICMD	        0x0a
+#define DRM_VIA_CMDBUF_SIZE	0x0b
+#define NOT_USED
+#define DRM_VIA_WAIT_IRQ        0x0d
+
+#define DRM_IOCTL_VIA_ALLOCMEM	  DRM_IOWR(DRM_COMMAND_BASE + DRM_VIA_ALLOCMEM, drm_via_mem_t)
+#define DRM_IOCTL_VIA_FREEMEM	  DRM_IOW( DRM_COMMAND_BASE + DRM_VIA_FREEMEM, drm_via_mem_t)
+#define DRM_IOCTL_VIA_AGP_INIT	  DRM_IOWR(DRM_COMMAND_BASE + DRM_VIA_AGP_INIT, drm_via_agp_t)
+#define DRM_IOCTL_VIA_FB_INIT	  DRM_IOWR(DRM_COMMAND_BASE + DRM_VIA_FB_INIT, drm_via_fb_t)
+#define DRM_IOCTL_VIA_MAP_INIT	  DRM_IOWR(DRM_COMMAND_BASE + DRM_VIA_MAP_INIT, drm_via_init_t)
+#define DRM_IOCTL_VIA_DEC_FUTEX   DRM_IOW( DRM_COMMAND_BASE + DRM_VIA_DEC_FUTEX, drm_via_futex_t)
+#define DRM_IOCTL_VIA_DMA_INIT	  DRM_IOWR(DRM_COMMAND_BASE + DRM_VIA_DMA_INIT, drm_via_dma_init_t)
+#define DRM_IOCTL_VIA_CMDBUFFER	  DRM_IOW( DRM_COMMAND_BASE + DRM_VIA_CMDBUFFER, drm_via_cmdbuffer_t)
+#define DRM_IOCTL_VIA_FLUSH	  DRM_IO(  DRM_COMMAND_BASE + DRM_VIA_FLUSH)
+#define DRM_IOCTL_VIA_PCICMD	  DRM_IOW( DRM_COMMAND_BASE + DRM_VIA_PCICMD, drm_via_cmdbuffer_t)
+#define DRM_IOCTL_VIA_CMDBUF_SIZE DRM_IOWR( DRM_COMMAND_BASE + DRM_VIA_CMDBUF_SIZE, \
+					    drm_via_cmdbuf_size_t)
+#define DRM_IOCTL_VIA_WAIT_IRQ    DRM_IOWR( DRM_COMMAND_BASE + DRM_VIA_WAIT_IRQ, drm_via_irqwait_t)
+
+/* 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.
+ */
+
+#define VIA_TEX_SETUP_SIZE 8
+
+/* Flags for clear ioctl
+ */
+#define VIA_FRONT   0x1
+#define VIA_BACK    0x2
+#define VIA_DEPTH   0x4
+#define VIA_STENCIL 0x8
+#define VIDEO 0
+#define AGP 1
+typedef struct {
+	uint32_t offset;
+	uint32_t size;
+} drm_via_agp_t;
+
+typedef struct {
+	uint32_t offset;
+	uint32_t size;
+} drm_via_fb_t;
+
+typedef struct {
+	uint32_t context;
+	uint32_t type;
+	uint32_t size;
+	unsigned long index;
+	unsigned long offset;
+} drm_via_mem_t;
+
+typedef struct _drm_via_init {
+	enum {
+		VIA_INIT_MAP = 0x01,
+		VIA_CLEANUP_MAP = 0x02
+	} func;
+
+	unsigned long sarea_priv_offset;
+	unsigned long fb_offset;
+	unsigned long mmio_offset;
+	unsigned long agpAddr;
+} drm_via_init_t;
+
+typedef struct _drm_via_futex {
+	enum {
+		VIA_FUTEX_WAIT = 0x00,
+		VIA_FUTEX_WAKE = 0X01
+	} func;
+	uint32_t ms;
+	uint32_t lock;
+	uint32_t val;
+} drm_via_futex_t;
+
+typedef struct _drm_via_dma_init {
+	enum {
+		VIA_INIT_DMA = 0x01,
+		VIA_CLEANUP_DMA = 0x02,
+                VIA_DMA_INITIALIZED = 0x03
+	} func;
+
+	unsigned long offset;
+	unsigned long size;
+	unsigned long reg_pause_addr;
+} drm_via_dma_init_t;
+
+typedef struct _drm_via_cmdbuffer {
+	char __user *buf;
+	unsigned long size;
+} drm_via_cmdbuffer_t;
+
+/* Warning: If you change the SAREA structure you must change the Xserver
+ * structure as well */
+
+typedef struct _drm_via_tex_region {
+	unsigned char next, prev;	/* indices to form a circular LRU  */
+	unsigned char inUse;	/* owned by a client, or free? */
+	int age;		/* tracked by clients to update local LRU's */
+} drm_via_tex_region_t;
+
+typedef struct _drm_via_sarea {
+	unsigned int dirty;
+	unsigned int nbox;
+	drm_clip_rect_t boxes[VIA_NR_SAREA_CLIPRECTS];
+	drm_via_tex_region_t texList[VIA_NR_TEX_REGIONS + 1];
+	int texAge;		/* last time texture was uploaded */
+	int ctxOwner;		/* last context to upload state */
+	int vertexPrim;
+
+	/*
+	 * Below is for XvMC.
+	 * We want the lock integers alone on, and aligned to, a cache line.
+	 * Therefore this somewhat strange construct.
+	 */
+
+	char XvMCLockArea[VIA_MAX_CACHELINE_SIZE * (VIA_NR_XVMC_LOCKS + 1)];
+
+	unsigned int XvMCDisplaying[VIA_NR_XVMC_PORTS];
+	unsigned int XvMCSubPicOn[VIA_NR_XVMC_PORTS];
+	unsigned int XvMCCtxNoGrabbed;	/* Last context to hold decoder */
+
+} drm_via_sarea_t;
+
+typedef struct _drm_via_cmdbuf_size {
+	enum {
+		VIA_CMDBUF_SPACE = 0x01,
+		VIA_CMDBUF_LAG = 0x02
+	} func;
+	int wait;
+	uint32_t size;
+} drm_via_cmdbuf_size_t;
+
+typedef enum {
+	VIA_IRQ_ABSOLUTE = 0x0,
+	VIA_IRQ_RELATIVE = 0x1,
+	VIA_IRQ_SIGNAL = 0x10000000,
+	VIA_IRQ_FORCE_SEQUENCE = 0x20000000
+} via_irq_seq_type_t;
+
+#define VIA_IRQ_FLAGS_MASK 0xF0000000
+
+struct drm_via_wait_irq_request{
+	unsigned irq;
+	via_irq_seq_type_t type;
+	uint32_t sequence;
+	uint32_t signal;
+};
+
+typedef union drm_via_irqwait {
+	struct drm_via_wait_irq_request request;
+	struct drm_wait_vblank_reply reply;
+} drm_via_irqwait_t;
+
+#ifdef __KERNEL__
+
+int via_fb_init(DRM_IOCTL_ARGS);
+int via_mem_alloc(DRM_IOCTL_ARGS);
+int via_mem_free(DRM_IOCTL_ARGS);
+int via_agp_init(DRM_IOCTL_ARGS);
+int via_map_init(DRM_IOCTL_ARGS);
+int via_decoder_futex(DRM_IOCTL_ARGS);
+int via_dma_init(DRM_IOCTL_ARGS);
+int via_cmdbuffer(DRM_IOCTL_ARGS);
+int via_flush_ioctl(DRM_IOCTL_ARGS);
+int via_pci_cmdbuffer(DRM_IOCTL_ARGS);
+int via_cmdbuf_size(DRM_IOCTL_ARGS);
+int via_wait_irq(DRM_IOCTL_ARGS);
+
+#endif
+#endif				/* _VIA_DRM_H_ */
diff --git a/drivers/char/drm/via_drv.c b/drivers/char/drm/via_drv.c
new file mode 100644
--- /dev/null
+++ b/drivers/char/drm/via_drv.c
@@ -0,0 +1,126 @@
+/*
+ * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2003 S3 Graphics, Inc. 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, sub license,
+ * 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 NON-INFRINGEMENT. IN NO EVENT SHALL
+ * VIA, S3 GRAPHICS, 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.
+ */
+
+#include <linux/config.h>
+#include "drmP.h"
+#include "via_drm.h"
+#include "via_drv.h"
+
+#include "drm_pciids.h"
+
+static int postinit(struct drm_device *dev, unsigned long flags)
+{
+	DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n",
+		 DRIVER_NAME,
+		 DRIVER_MAJOR,
+		 DRIVER_MINOR,
+		 DRIVER_PATCHLEVEL,
+		 DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev)
+	    );
+	return 0;
+}
+
+static int version(drm_version_t * version)
+{
+	int len;
+
+	version->version_major = DRIVER_MAJOR;
+	version->version_minor = DRIVER_MINOR;
+	version->version_patchlevel = DRIVER_PATCHLEVEL;
+	DRM_COPY(version->name, DRIVER_NAME);
+	DRM_COPY(version->date, DRIVER_DATE);
+	DRM_COPY(version->desc, DRIVER_DESC);
+	return 0;
+}
+
+static struct pci_device_id pciidlist[] = {
+	viadrv_PCI_IDS
+};
+
+static drm_ioctl_desc_t ioctls[] = {
+	[DRM_IOCTL_NR(DRM_VIA_ALLOCMEM)] = {via_mem_alloc, 1, 0},
+	[DRM_IOCTL_NR(DRM_VIA_FREEMEM)] = {via_mem_free, 1, 0},
+	[DRM_IOCTL_NR(DRM_VIA_AGP_INIT)] = {via_agp_init, 1, 0},
+	[DRM_IOCTL_NR(DRM_VIA_FB_INIT)] = {via_fb_init, 1, 0},
+	[DRM_IOCTL_NR(DRM_VIA_MAP_INIT)] = {via_map_init, 1, 0},
+	[DRM_IOCTL_NR(DRM_VIA_DEC_FUTEX)] = {via_decoder_futex, 1, 0},
+	[DRM_IOCTL_NR(DRM_VIA_DMA_INIT)] = {via_dma_init, 1, 0},
+	[DRM_IOCTL_NR(DRM_VIA_CMDBUFFER)] = {via_cmdbuffer, 1, 0},
+	[DRM_IOCTL_NR(DRM_VIA_FLUSH)] = {via_flush_ioctl, 1, 0},
+	[DRM_IOCTL_NR(DRM_VIA_PCICMD)] = {via_pci_cmdbuffer, 1, 0},
+	[DRM_IOCTL_NR(DRM_VIA_CMDBUF_SIZE)] = {via_cmdbuf_size, 1, 0},
+	[DRM_IOCTL_NR(DRM_VIA_WAIT_IRQ)] = {via_wait_irq, 1, 0}
+};
+
+static struct drm_driver driver = {
+	.driver_features =
+	    DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_IRQ |
+	    DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL,
+	.context_ctor = via_init_context,
+	.context_dtor = via_final_context,
+	.vblank_wait = via_driver_vblank_wait,
+	.irq_preinstall = via_driver_irq_preinstall,
+	.irq_postinstall = via_driver_irq_postinstall,
+	.irq_uninstall = via_driver_irq_uninstall,
+	.irq_handler = via_driver_irq_handler,
+	.dma_quiescent = via_driver_dma_quiescent,
+	.reclaim_buffers = drm_core_reclaim_buffers,
+	.get_map_ofs = drm_core_get_map_ofs,
+	.get_reg_ofs = drm_core_get_reg_ofs,
+	.postinit = postinit,
+	.version = version,
+	.ioctls = ioctls,
+	.num_ioctls = DRM_ARRAY_SIZE(ioctls),
+	.fops = {
+		.owner = THIS_MODULE,
+		.open = drm_open,
+		.release = drm_release,
+		.ioctl = drm_ioctl,
+		.mmap = drm_mmap,
+		.poll = drm_poll,
+		.fasync = drm_fasync,
+		},
+	.pci_driver = {
+		.name = DRIVER_NAME,
+		.id_table = pciidlist,
+	}
+};
+
+static int __init via_init(void)
+{
+	via_init_command_verifier();
+	return drm_init(&driver);
+}
+
+static void __exit via_exit(void)
+{
+	drm_exit(&driver);
+}
+
+module_init(via_init);
+module_exit(via_exit);
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL and additional rights");
diff --git a/drivers/char/drm/via_drv.h b/drivers/char/drm/via_drv.h
new file mode 100644
--- /dev/null
+++ b/drivers/char/drm/via_drv.h
@@ -0,0 +1,118 @@
+/*
+ * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2003 S3 Graphics, Inc. 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, sub license,
+ * 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 NON-INFRINGEMENT. IN NO EVENT SHALL
+ * VIA, S3 GRAPHICS, 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.
+ */
+#ifndef _VIA_DRV_H_
+#define _VIA_DRV_H_
+
+#define DRIVER_AUTHOR	"VIA"
+
+#define DRIVER_NAME		"via"
+#define DRIVER_DESC		"VIA Unichrome / Pro"
+#define DRIVER_DATE		"20050523"
+
+#define DRIVER_MAJOR		2
+#define DRIVER_MINOR		6
+#define DRIVER_PATCHLEVEL	3
+
+#include "via_verifier.h"
+
+#define VIA_PCI_BUF_SIZE 60000
+#define VIA_FIRE_BUF_SIZE  1024
+#define VIA_NUM_IRQS 2
+
+
+
+typedef struct drm_via_ring_buffer {
+	drm_map_t map;
+	char *virtual_start;
+} drm_via_ring_buffer_t;
+
+typedef uint32_t maskarray_t[5];
+
+typedef struct drm_via_irq {
+	atomic_t irq_received;
+	uint32_t pending_mask;
+	uint32_t enable_mask;
+	wait_queue_head_t irq_queue;
+} drm_via_irq_t;
+	
+typedef struct drm_via_private {
+	drm_via_sarea_t *sarea_priv;
+	drm_map_t *sarea;
+	drm_map_t *fb;
+	drm_map_t *mmio;
+	unsigned long agpAddr;
+	wait_queue_head_t decoder_queue[VIA_NR_XVMC_LOCKS];
+	char *dma_ptr;
+	unsigned int dma_low;
+	unsigned int dma_high;
+	unsigned int dma_offset;
+	uint32_t dma_wrap;
+	volatile uint32_t *last_pause_ptr;
+	volatile uint32_t *hw_addr_ptr;
+	drm_via_ring_buffer_t ring;
+        struct timeval last_vblank;
+        int last_vblank_valid;
+        unsigned usec_per_vblank;
+	drm_via_state_t hc_state;
+	char pci_buf[VIA_PCI_BUF_SIZE];
+	const uint32_t *fire_offsets[VIA_FIRE_BUF_SIZE];
+	uint32_t num_fire_offsets;
+	int pro_group_a;
+	drm_via_irq_t via_irqs[VIA_NUM_IRQS];
+	unsigned num_irqs;
+	maskarray_t *irq_masks;
+	uint32_t irq_enable_mask; 
+	uint32_t irq_pending_mask;	
+} drm_via_private_t;
+
+/* VIA MMIO register access */
+#define VIA_BASE ((dev_priv->mmio))
+
+#define VIA_READ(reg)		DRM_READ32(VIA_BASE, reg)
+#define VIA_WRITE(reg,val)	DRM_WRITE32(VIA_BASE, reg, val)
+#define VIA_READ8(reg)		DRM_READ8(VIA_BASE, reg)
+#define VIA_WRITE8(reg,val)	DRM_WRITE8(VIA_BASE, reg, val)
+
+extern int via_init_context(drm_device_t * dev, int context);
+extern int via_final_context(drm_device_t * dev, int context);
+
+extern int via_do_cleanup_map(drm_device_t * dev);
+extern int via_map_init(struct inode *inode, struct file *filp,
+			unsigned int cmd, unsigned long arg);
+extern int via_driver_vblank_wait(drm_device_t * dev, unsigned int *sequence);
+
+extern irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS);
+extern void via_driver_irq_preinstall(drm_device_t * dev);
+extern void via_driver_irq_postinstall(drm_device_t * dev);
+extern void via_driver_irq_uninstall(drm_device_t * dev);
+
+extern int via_dma_cleanup(drm_device_t * dev);
+extern void via_init_command_verifier(void);
+extern int via_driver_dma_quiescent(drm_device_t * dev);
+extern void via_init_futex(drm_via_private_t *dev_priv);
+extern void via_cleanup_futex(drm_via_private_t *dev_priv);
+extern void via_release_futex(drm_via_private_t *dev_priv, int context);
+
+
+#endif
diff --git a/drivers/char/drm/via_ds.c b/drivers/char/drm/via_ds.c
new file mode 100644
--- /dev/null
+++ b/drivers/char/drm/via_ds.c
@@ -0,0 +1,280 @@
+/*
+ * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
+ * Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan.
+ *
+ * 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, sub license,
+ * 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 NON-INFRINGEMENT. IN NO EVENT SHALL
+ * VIA, S3 GRAPHICS, 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.
+ */
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/poll.h>
+#include <linux/pci.h>
+#include <asm/io.h>
+
+#include "via_ds.h"
+extern unsigned int VIA_DEBUG;
+
+set_t *via_setInit(void)
+{
+	int i;
+	set_t *set;
+	set = (set_t *) drm_alloc(sizeof(set_t), DRM_MEM_DRIVER);
+	for (i = 0; i < SET_SIZE; i++) {
+		set->list[i].free_next = i + 1;
+		set->list[i].alloc_next = -1;
+	}
+	set->list[SET_SIZE - 1].free_next = -1;
+	set->free = 0;
+	set->alloc = -1;
+	set->trace = -1;
+	return set;
+}
+
+int via_setAdd(set_t * set, ITEM_TYPE item)
+{
+	int free = set->free;
+	if (free != -1) {
+		set->list[free].val = item;
+		set->free = set->list[free].free_next;
+	} else {
+		return 0;
+	}
+	set->list[free].alloc_next = set->alloc;
+	set->alloc = free;
+	set->list[free].free_next = -1;
+	return 1;
+}
+
+int via_setDel(set_t * set, ITEM_TYPE item)
+{
+	int alloc = set->alloc;
+	int prev = -1;
+
+	while (alloc != -1) {
+		if (set->list[alloc].val == item) {
+			if (prev != -1)
+				set->list[prev].alloc_next =
+				    set->list[alloc].alloc_next;
+			else
+				set->alloc = set->list[alloc].alloc_next;
+			break;
+		}
+		prev = alloc;
+		alloc = set->list[alloc].alloc_next;
+	}
+
+	if (alloc == -1)
+		return 0;
+
+	set->list[alloc].free_next = set->free;
+	set->free = alloc;
+	set->list[alloc].alloc_next = -1;
+
+	return 1;
+}
+
+/* setFirst -> setAdd -> setNext is wrong */
+
+int via_setFirst(set_t * set, ITEM_TYPE * item)
+{
+	if (set->alloc == -1)
+		return 0;
+
+	*item = set->list[set->alloc].val;
+	set->trace = set->list[set->alloc].alloc_next;
+
+	return 1;
+}
+
+int via_setNext(set_t * set, ITEM_TYPE * item)
+{
+	if (set->trace == -1)
+		return 0;
+
+	*item = set->list[set->trace].val;
+	set->trace = set->list[set->trace].alloc_next;
+
+	return 1;
+}
+
+int via_setDestroy(set_t * set)
+{
+	drm_free(set, sizeof(set_t), DRM_MEM_DRIVER);
+
+	return 1;
+}
+
+#define ISFREE(bptr) ((bptr)->free)
+
+#define fprintf(fmt, arg...) do{}while(0)
+
+memHeap_t *via_mmInit(int ofs, int size)
+{
+	PMemBlock blocks;
+
+	if (size <= 0)
+		return NULL;
+
+	blocks = (TMemBlock *) drm_calloc(1, sizeof(TMemBlock), DRM_MEM_DRIVER);
+
+	if (blocks) {
+		blocks->ofs = ofs;
+		blocks->size = size;
+		blocks->free = 1;
+		return (memHeap_t *) blocks;
+	} else
+		return NULL;
+}
+
+static TMemBlock *SliceBlock(TMemBlock * p,
+			     int startofs, int size,
+			     int reserved, int alignment)
+{
+	TMemBlock *newblock;
+
+	/* break left */
+	if (startofs > p->ofs) {
+		newblock =
+		    (TMemBlock *) drm_calloc(1, sizeof(TMemBlock),
+					     DRM_MEM_DRIVER);
+		newblock->ofs = startofs;
+		newblock->size = p->size - (startofs - p->ofs);
+		newblock->free = 1;
+		newblock->next = p->next;
+		p->size -= newblock->size;
+		p->next = newblock;
+		p = newblock;
+	}
+
+	/* break right */
+	if (size < p->size) {
+		newblock =
+		    (TMemBlock *) drm_calloc(1, sizeof(TMemBlock),
+					     DRM_MEM_DRIVER);
+		newblock->ofs = startofs + size;
+		newblock->size = p->size - size;
+		newblock->free = 1;
+		newblock->next = p->next;
+		p->size = size;
+		p->next = newblock;
+	}
+
+	/* p = middle block */
+	p->align = alignment;
+	p->free = 0;
+	p->reserved = reserved;
+	return p;
+}
+
+PMemBlock via_mmAllocMem(memHeap_t * heap, int size, int align2,
+			 int startSearch)
+{
+	int mask, startofs, endofs;
+	TMemBlock *p;
+
+	if (!heap || align2 < 0 || size <= 0)
+		return NULL;
+
+	mask = (1 << align2) - 1;
+	startofs = 0;
+	p = (TMemBlock *) heap;
+
+	while (p) {
+		if (ISFREE(p)) {
+			startofs = (p->ofs + mask) & ~mask;
+
+			if (startofs < startSearch)
+				startofs = startSearch;
+
+			endofs = startofs + size;
+
+			if (endofs <= (p->ofs + p->size))
+				break;
+		}
+
+		p = p->next;
+	}
+
+	if (!p)
+		return NULL;
+
+	p = SliceBlock(p, startofs, size, 0, mask + 1);
+	p->heap = heap;
+
+	return p;
+}
+
+static __inline__ int Join2Blocks(TMemBlock * p)
+{
+	if (p->free && p->next && p->next->free) {
+		TMemBlock *q = p->next;
+		p->size += q->size;
+		p->next = q->next;
+		drm_free(q, sizeof(TMemBlock), DRM_MEM_DRIVER);
+
+		return 1;
+	}
+
+	return 0;
+}
+
+int via_mmFreeMem(PMemBlock b)
+{
+	TMemBlock *p, *prev;
+
+	if (!b)
+		return 0;
+
+	if (!b->heap) {
+		fprintf(stderr, "no heap\n");
+
+		return -1;
+	}
+
+	p = b->heap;
+	prev = NULL;
+
+	while (p && p != b) {
+		prev = p;
+		p = p->next;
+	}
+
+	if (!p || p->free || p->reserved) {
+		if (!p)
+			fprintf(stderr, "block not found in heap\n");
+		else if (p->free)
+			fprintf(stderr, "block already free\n");
+		else
+			fprintf(stderr, "block is reserved\n");
+
+		return -1;
+	}
+
+	p->free = 1;
+	Join2Blocks(p);
+
+	if (prev)
+		Join2Blocks(prev);
+
+	return 0;
+}
diff --git a/drivers/char/drm/via_ds.h b/drivers/char/drm/via_ds.h
new file mode 100644
--- /dev/null
+++ b/drivers/char/drm/via_ds.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
+ * Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan.
+ * 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, sub license,
+ * 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 NON-INFRINGEMENT. IN NO EVENT SHALL
+ * VIA, S3 GRAPHICS, 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.
+ */
+#ifndef _via_ds_h_
+#define _via_ds_h_
+
+#include "drmP.h"
+
+/* Set Data Structure */
+#define SET_SIZE 5000
+typedef unsigned long ITEM_TYPE;
+
+typedef struct {
+	ITEM_TYPE val;
+	int alloc_next, free_next;
+} list_item_t;
+
+typedef struct {
+	int alloc;
+	int free;
+	int trace;
+	list_item_t list[SET_SIZE];
+} set_t;
+
+set_t *via_setInit(void);
+int via_setAdd(set_t * set, ITEM_TYPE item);
+int via_setDel(set_t * set, ITEM_TYPE item);
+int via_setFirst(set_t * set, ITEM_TYPE * item);
+int via_setNext(set_t * set, ITEM_TYPE * item);
+int via_setDestroy(set_t * set);
+
+#endif
+
+#ifndef MM_INC
+#define MM_INC
+
+struct mem_block_t {
+	struct mem_block_t *next;
+	struct mem_block_t *heap;
+	int ofs, size;
+	int align;
+	unsigned int free:1;
+	unsigned int reserved:1;
+};
+typedef struct mem_block_t TMemBlock;
+typedef struct mem_block_t *PMemBlock;
+
+/* a heap is just the first block in a chain */
+typedef struct mem_block_t memHeap_t;
+
+static __inline__ int mmBlockSize(PMemBlock b)
+{
+	return b->size;
+}
+
+static __inline__ int mmOffset(PMemBlock b)
+{
+	return b->ofs;
+}
+
+static __inline__ void mmMarkReserved(PMemBlock b)
+{
+	b->reserved = 1;
+}
+
+/*
+ * input: total size in bytes
+ * return: a heap pointer if OK, NULL if error
+ */
+memHeap_t *via_mmInit(int ofs, int size);
+
+PMemBlock via_mmAllocMem(memHeap_t * heap, int size, int align2,
+			 int startSearch);
+
+/*
+ * Free block starts at offset
+ * input: pointer to a block
+ * return: 0 if OK, -1 if error
+ */
+int via_mmFreeMem(PMemBlock b);
+
+#endif
diff --git a/drivers/char/drm/via_irq.c b/drivers/char/drm/via_irq.c
new file mode 100644
--- /dev/null
+++ b/drivers/char/drm/via_irq.c
@@ -0,0 +1,339 @@
+/* via_irq.c
+ *
+ * Copyright 2004 BEAM Ltd.
+ * Copyright 2002 Tungsten Graphics, Inc.
+ * Copyright 2005 Thomas Hellstrom.
+ * 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
+ * BEAM LTD, TUNGSTEN GRAPHICS  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:
+ *    Terry Barnaby <terry1@beam.ltd.uk>
+ *    Keith Whitwell <keith@tungstengraphics.com>
+ *    Thomas Hellstrom <unichrome@shipmail.org>
+ *
+ * This code provides standard DRM access to the Via Unichrome / Pro Vertical blank
+ * interrupt, as well as an infrastructure to handle other interrupts of the chip.
+ * The refresh rate is also calculated for video playback sync purposes.
+ */
+
+#include "drmP.h"
+#include "drm.h"
+#include "via_drm.h"
+#include "via_drv.h"
+
+#define VIA_REG_INTERRUPT       0x200
+
+/* VIA_REG_INTERRUPT */
+#define VIA_IRQ_GLOBAL          (1 << 31)
+#define VIA_IRQ_VBLANK_ENABLE   (1 << 19)
+#define VIA_IRQ_VBLANK_PENDING  (1 << 3)
+#define VIA_IRQ_HQV0_ENABLE     (1 << 11)
+#define VIA_IRQ_HQV1_ENABLE     (1 << 25)
+#define VIA_IRQ_HQV0_PENDING    (1 << 9)
+#define VIA_IRQ_HQV1_PENDING    (1 << 10)
+
+/*
+ * Device-specific IRQs go here. This type might need to be extended with
+ * the register if there are multiple IRQ control registers.
+ * Currently we activate the HQV interrupts of  Unichrome Pro group A. 
+ */
+
+static maskarray_t via_pro_group_a_irqs[] = {
+	{VIA_IRQ_HQV0_ENABLE, VIA_IRQ_HQV0_PENDING, 0x000003D0, 0x00008010, 0x00000000 },
+	{VIA_IRQ_HQV1_ENABLE, VIA_IRQ_HQV1_PENDING, 0x000013D0, 0x00008010, 0x00000000 }};
+static int via_num_pro_group_a = sizeof(via_pro_group_a_irqs)/sizeof(maskarray_t);
+
+static maskarray_t via_unichrome_irqs[] = {};
+static int via_num_unichrome = sizeof(via_unichrome_irqs)/sizeof(maskarray_t);
+
+
+static unsigned time_diff(struct timeval *now,struct timeval *then) 
+{
+    return (now->tv_usec >= then->tv_usec) ?
+        now->tv_usec - then->tv_usec :
+        1000000 - (then->tv_usec - now->tv_usec);
+}
+
+irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS)
+{
+	drm_device_t *dev = (drm_device_t *) arg;
+	drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
+	u32 status;
+	int handled = 0;
+	struct timeval cur_vblank;
+	drm_via_irq_t *cur_irq = dev_priv->via_irqs;
+	int i;
+
+	status = VIA_READ(VIA_REG_INTERRUPT);
+	if (status & VIA_IRQ_VBLANK_PENDING) {
+		atomic_inc(&dev->vbl_received);
+                if (!(atomic_read(&dev->vbl_received) & 0x0F)) {
+			do_gettimeofday(&cur_vblank);
+                        if (dev_priv->last_vblank_valid) {
+				dev_priv->usec_per_vblank = 
+					time_diff( &cur_vblank,&dev_priv->last_vblank) >> 4;
+			}
+			dev_priv->last_vblank = cur_vblank;
+			dev_priv->last_vblank_valid = 1;
+                }
+                if (!(atomic_read(&dev->vbl_received) & 0xFF)) {
+			DRM_DEBUG("US per vblank is: %u\n",
+				dev_priv->usec_per_vblank);
+		}
+		DRM_WAKEUP(&dev->vbl_queue);
+		drm_vbl_send_signals(dev);
+		handled = 1;
+	}
+	
+
+	for (i=0; i<dev_priv->num_irqs; ++i) {
+		if (status & cur_irq->pending_mask) {
+			atomic_inc( &cur_irq->irq_received );
+			DRM_WAKEUP( &cur_irq->irq_queue );
+			handled = 1;
+		}
+		cur_irq++;
+	}
+	
+	/* Acknowlege interrupts */
+	VIA_WRITE(VIA_REG_INTERRUPT, status);
+
+
+	if (handled)
+		return IRQ_HANDLED;
+	else
+		return IRQ_NONE;
+}
+
+static __inline__ void viadrv_acknowledge_irqs(drm_via_private_t * dev_priv)
+{
+	u32 status;
+
+	if (dev_priv) {
+		/* Acknowlege interrupts */
+		status = VIA_READ(VIA_REG_INTERRUPT);
+		VIA_WRITE(VIA_REG_INTERRUPT, status | 
+			  dev_priv->irq_pending_mask);
+	}
+}
+
+int via_driver_vblank_wait(drm_device_t * dev, unsigned int *sequence)
+{
+	drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
+	unsigned int cur_vblank;
+	int ret = 0;
+
+	DRM_DEBUG("viadrv_vblank_wait\n");
+	if (!dev_priv) {
+		DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+		return -EINVAL;
+	}
+
+	viadrv_acknowledge_irqs(dev_priv);
+
+	/* Assume that the user has missed the current sequence number
+	 * by about a day rather than she wants to wait for years
+	 * using vertical blanks...
+	 */
+
+	DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ,
+		    (((cur_vblank = atomic_read(&dev->vbl_received)) -
+		      *sequence) <= (1 << 23)));
+	
+	*sequence = cur_vblank;
+	return ret;
+}
+
+static int 
+via_driver_irq_wait(drm_device_t * dev, unsigned int irq, int force_sequence,
+		    unsigned int *sequence)
+{
+	drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
+	unsigned int cur_irq_sequence;
+	drm_via_irq_t *cur_irq = dev_priv->via_irqs;
+	int ret = 0;
+	maskarray_t *masks = dev_priv->irq_masks;
+
+	DRM_DEBUG("%s\n", __FUNCTION__);
+
+	if (!dev_priv) {
+		DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+		return DRM_ERR(EINVAL);
+	}
+
+	if (irq >= dev_priv->num_irqs ) {
+		DRM_ERROR("%s Trying to wait on unknown irq %d\n", __FUNCTION__, irq);
+		return DRM_ERR(EINVAL);
+	}
+		
+	cur_irq += irq;
+
+	if (masks[irq][2] && !force_sequence) {
+		DRM_WAIT_ON(ret, cur_irq->irq_queue, 3 * DRM_HZ,
+			    ((VIA_READ(masks[irq][2]) & masks[irq][3]) == masks[irq][4]));
+		cur_irq_sequence = atomic_read(&cur_irq->irq_received);
+	} else {
+		DRM_WAIT_ON(ret, cur_irq->irq_queue, 3 * DRM_HZ,
+			    (((cur_irq_sequence = atomic_read(&cur_irq->irq_received)) -
+			      *sequence) <= (1 << 23)));		
+	}
+	*sequence = cur_irq_sequence;
+	return ret;
+}
+
+
+/*
+ * drm_dma.h hooks
+ */
+
+void via_driver_irq_preinstall(drm_device_t * dev)
+{
+	drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
+	u32 status;
+	drm_via_irq_t *cur_irq = dev_priv->via_irqs;
+	int i;
+
+	DRM_DEBUG("driver_irq_preinstall: dev_priv: %p\n", dev_priv);
+	if (dev_priv) {
+
+		dev_priv->irq_enable_mask = VIA_IRQ_VBLANK_ENABLE;
+		dev_priv->irq_pending_mask = VIA_IRQ_VBLANK_PENDING;
+
+		dev_priv->irq_masks = (dev_priv->pro_group_a) ?
+			via_pro_group_a_irqs : via_unichrome_irqs;
+		dev_priv->num_irqs = (dev_priv->pro_group_a) ?
+			via_num_pro_group_a : via_num_unichrome;
+		
+		for(i=0; i < dev_priv->num_irqs; ++i) {
+			atomic_set(&cur_irq->irq_received, 0);
+			cur_irq->enable_mask = dev_priv->irq_masks[i][0]; 
+			cur_irq->pending_mask = dev_priv->irq_masks[i][1];
+			DRM_INIT_WAITQUEUE( &cur_irq->irq_queue );
+			dev_priv->irq_enable_mask |= cur_irq->enable_mask;
+			dev_priv->irq_pending_mask |= cur_irq->pending_mask;
+			cur_irq++;
+			
+			DRM_DEBUG("Initializing IRQ %d\n", i);
+		}
+			
+	        dev_priv->last_vblank_valid = 0;
+
+		// Clear VSync interrupt regs
+		status = VIA_READ(VIA_REG_INTERRUPT);
+		VIA_WRITE(VIA_REG_INTERRUPT, status & 
+			  ~(dev_priv->irq_enable_mask));
+		
+		/* Clear bits if they're already high */
+		viadrv_acknowledge_irqs(dev_priv);
+	}
+}
+
+void via_driver_irq_postinstall(drm_device_t * dev)
+{
+	drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
+	u32 status;
+
+	DRM_DEBUG("via_driver_irq_postinstall\n");
+	if (dev_priv) {
+		status = VIA_READ(VIA_REG_INTERRUPT);
+		VIA_WRITE(VIA_REG_INTERRUPT, status | VIA_IRQ_GLOBAL
+			  | dev_priv->irq_enable_mask);
+
+		/* Some magic, oh for some data sheets ! */
+
+		VIA_WRITE8(0x83d4, 0x11);
+		VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) | 0x30);
+		
+	}
+}
+
+void via_driver_irq_uninstall(drm_device_t * dev)
+{
+	drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
+	u32 status;
+
+	DRM_DEBUG("driver_irq_uninstall)\n");
+	if (dev_priv) {
+
+		/* Some more magic, oh for some data sheets ! */
+
+		VIA_WRITE8(0x83d4, 0x11);
+		VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) & ~0x30);
+
+		status = VIA_READ(VIA_REG_INTERRUPT);
+		VIA_WRITE(VIA_REG_INTERRUPT, status & 
+			  ~(VIA_IRQ_VBLANK_ENABLE | dev_priv->irq_enable_mask));
+	}
+}
+
+int via_wait_irq(DRM_IOCTL_ARGS)
+{
+	drm_file_t *priv = filp->private_data;
+	drm_device_t *dev = priv->head->dev;
+	drm_via_irqwait_t __user *argp = (void __user *)data;
+	drm_via_irqwait_t irqwait;
+	struct timeval now;
+	int ret = 0;
+	drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
+	drm_via_irq_t *cur_irq = dev_priv->via_irqs;
+	int force_sequence;
+
+	if (!dev->irq)
+		return DRM_ERR(EINVAL);
+
+	DRM_COPY_FROM_USER_IOCTL(irqwait, argp, sizeof(irqwait));
+	if (irqwait.request.irq >= dev_priv->num_irqs) {
+		DRM_ERROR("%s Trying to wait on unknown irq %d\n", __FUNCTION__, 
+			  irqwait.request.irq);
+		return DRM_ERR(EINVAL);
+	}
+
+	cur_irq += irqwait.request.irq;
+
+	switch (irqwait.request.type & ~VIA_IRQ_FLAGS_MASK) {
+	case VIA_IRQ_RELATIVE:
+		irqwait.request.sequence += atomic_read(&cur_irq->irq_received);
+		irqwait.request.type &= ~_DRM_VBLANK_RELATIVE;
+	case VIA_IRQ_ABSOLUTE:
+		break;
+	default:
+		return DRM_ERR(EINVAL);
+	}
+
+	if (irqwait.request.type & VIA_IRQ_SIGNAL) {
+		DRM_ERROR("%s Signals on Via IRQs not implemented yet.\n", 
+			  __FUNCTION__);
+		return DRM_ERR(EINVAL);
+	}
+
+	force_sequence = (irqwait.request.type & VIA_IRQ_FORCE_SEQUENCE);
+
+	ret = via_driver_irq_wait(dev, irqwait.request.irq, force_sequence,
+				  &irqwait.request.sequence);
+	do_gettimeofday(&now);
+	irqwait.reply.tval_sec = now.tv_sec;
+	irqwait.reply.tval_usec = now.tv_usec;
+
+	DRM_COPY_TO_USER_IOCTL(argp, irqwait, sizeof(irqwait));
+
+	return ret;
+}
diff --git a/drivers/char/drm/via_map.c b/drivers/char/drm/via_map.c
new file mode 100644
--- /dev/null
+++ b/drivers/char/drm/via_map.c
@@ -0,0 +1,111 @@
+/*
+ * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2003 S3 Graphics, Inc. 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, sub license,
+ * 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 NON-INFRINGEMENT. IN NO EVENT SHALL
+ * VIA, S3 GRAPHICS, 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.
+ */
+#include "drmP.h"
+#include "via_drm.h"
+#include "via_drv.h"
+
+static int via_do_init_map(drm_device_t * dev, drm_via_init_t * init)
+{
+	drm_via_private_t *dev_priv;
+
+	DRM_DEBUG("%s\n", __FUNCTION__);
+
+	dev_priv = drm_alloc(sizeof(drm_via_private_t), DRM_MEM_DRIVER);
+	if (dev_priv == NULL)
+		return -ENOMEM;
+
+	memset(dev_priv, 0, sizeof(drm_via_private_t));
+
+	DRM_GETSAREA();
+	if (!dev_priv->sarea) {
+		DRM_ERROR("could not find sarea!\n");
+		dev->dev_private = (void *)dev_priv;
+		via_do_cleanup_map(dev);
+		return -EINVAL;
+	}
+
+	dev_priv->fb = drm_core_findmap(dev, init->fb_offset);
+	if (!dev_priv->fb) {
+		DRM_ERROR("could not find framebuffer!\n");
+		dev->dev_private = (void *)dev_priv;
+		via_do_cleanup_map(dev);
+		return -EINVAL;
+	}
+	dev_priv->mmio = drm_core_findmap(dev, init->mmio_offset);
+	if (!dev_priv->mmio) {
+		DRM_ERROR("could not find mmio region!\n");
+		dev->dev_private = (void *)dev_priv;
+		via_do_cleanup_map(dev);
+		return -EINVAL;
+	}
+
+	dev_priv->sarea_priv =
+	    (drm_via_sarea_t *) ((u8 *) dev_priv->sarea->handle +
+				 init->sarea_priv_offset);
+
+	dev_priv->agpAddr = init->agpAddr;
+
+	via_init_futex( dev_priv );
+	dev_priv->pro_group_a = (dev->pdev->device == 0x3118);
+
+	dev->dev_private = (void *)dev_priv;
+	return 0;
+}
+
+int via_do_cleanup_map(drm_device_t * dev)
+{
+	if (dev->dev_private) {
+
+		drm_via_private_t *dev_priv = dev->dev_private;
+
+		via_dma_cleanup(dev);
+
+		drm_free(dev_priv, sizeof(drm_via_private_t), DRM_MEM_DRIVER);
+		dev->dev_private = NULL;
+	}
+
+	return 0;
+}
+
+int via_map_init(DRM_IOCTL_ARGS)
+{
+	DRM_DEVICE;
+	drm_via_init_t init;
+
+	DRM_DEBUG("%s\n", __FUNCTION__);
+
+	DRM_COPY_FROM_USER_IOCTL(init, (drm_via_init_t __user *) data,
+				 sizeof(init));
+
+	switch (init.func) {
+	case VIA_INIT_MAP:
+		return via_do_init_map(dev, &init);
+	case VIA_CLEANUP_MAP:
+		return via_do_cleanup_map(dev);
+	}
+
+	return -EINVAL;
+}
+
+
diff --git a/drivers/char/drm/via_mm.c b/drivers/char/drm/via_mm.c
new file mode 100644
--- /dev/null
+++ b/drivers/char/drm/via_mm.c
@@ -0,0 +1,361 @@
+/*
+ * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2003 S3 Graphics, Inc. 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, sub license,
+ * 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 NON-INFRINGEMENT. IN NO EVENT SHALL
+ * VIA, S3 GRAPHICS, 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.
+ */
+#include "drmP.h"
+#include "via_drm.h"
+#include "via_drv.h"
+#include "via_ds.h"
+#include "via_mm.h"
+
+#define MAX_CONTEXT 100
+
+typedef struct {
+	int used;
+	int context;
+	set_t *sets[2];		/* 0 for frame buffer, 1 for AGP , 2 for System */
+} via_context_t;
+
+static via_context_t global_ppriv[MAX_CONTEXT];
+
+static int via_agp_alloc(drm_via_mem_t * mem);
+static int via_agp_free(drm_via_mem_t * mem);
+static int via_fb_alloc(drm_via_mem_t * mem);
+static int via_fb_free(drm_via_mem_t * mem);
+
+static int add_alloc_set(int context, int type, unsigned int val)
+{
+	int i, retval = 0;
+
+	for (i = 0; i < MAX_CONTEXT; i++) {
+		if (global_ppriv[i].used && global_ppriv[i].context == context) {
+			retval = via_setAdd(global_ppriv[i].sets[type], val);
+			break;
+		}
+	}
+
+	return retval;
+}
+
+static int del_alloc_set(int context, int type, unsigned int val)
+{
+	int i, retval = 0;
+
+	for (i = 0; i < MAX_CONTEXT; i++)
+		if (global_ppriv[i].used && global_ppriv[i].context == context) {
+			retval = via_setDel(global_ppriv[i].sets[type], val);
+			break;
+		}
+
+	return retval;
+}
+
+/* agp memory management */
+static memHeap_t *AgpHeap = NULL;
+
+int via_agp_init(DRM_IOCTL_ARGS)
+{
+	drm_via_agp_t agp;
+
+	DRM_COPY_FROM_USER_IOCTL(agp, (drm_via_agp_t __user *) data,
+				 sizeof(agp));
+
+	AgpHeap = via_mmInit(agp.offset, agp.size);
+
+	DRM_DEBUG("offset = %lu, size = %lu", (unsigned long)agp.offset, (unsigned long)agp.size);
+
+	return 0;
+}
+
+/* fb memory management */
+static memHeap_t *FBHeap = NULL;
+
+int via_fb_init(DRM_IOCTL_ARGS)
+{
+	drm_via_fb_t fb;
+
+	DRM_COPY_FROM_USER_IOCTL(fb, (drm_via_fb_t __user *) data, sizeof(fb));
+
+	FBHeap = via_mmInit(fb.offset, fb.size);
+
+	DRM_DEBUG("offset = %lu, size = %lu", (unsigned long)fb.offset, (unsigned long)fb.size);
+
+	return 0;
+}
+
+int via_init_context(struct drm_device *dev, int context)
+{
+	int i;
+
+	for (i = 0; i < MAX_CONTEXT; i++)
+		if (global_ppriv[i].used &&
+		    (global_ppriv[i].context == context))
+			break;
+
+	if (i >= MAX_CONTEXT) {
+		for (i = 0; i < MAX_CONTEXT; i++) {
+			if (!global_ppriv[i].used) {
+				global_ppriv[i].context = context;
+				global_ppriv[i].used = 1;
+				global_ppriv[i].sets[0] = via_setInit();
+				global_ppriv[i].sets[1] = via_setInit();
+				DRM_DEBUG("init allocation set, socket=%d,"
+					  " context = %d\n", i, context);
+				break;
+			}
+		}
+
+		if ((i >= MAX_CONTEXT) || (global_ppriv[i].sets[0] == NULL) ||
+		    (global_ppriv[i].sets[1] == NULL)) {
+			return 0;
+		}
+	}
+
+	return 1;
+}
+
+int via_final_context(struct drm_device *dev, int context)
+{	
+        int i;
+	drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
+
+	for (i = 0; i < MAX_CONTEXT; i++)
+		if (global_ppriv[i].used &&
+		    (global_ppriv[i].context == context))
+			break;
+
+	if (i < MAX_CONTEXT) {
+		set_t *set;
+		ITEM_TYPE item;
+		int retval;
+
+		DRM_DEBUG("find socket %d, context = %d\n", i, context);
+
+		/* Video Memory */
+		set = global_ppriv[i].sets[0];
+		retval = via_setFirst(set, &item);
+		while (retval) {
+			DRM_DEBUG("free video memory 0x%lx\n", item);
+			via_mmFreeMem((PMemBlock) item);
+			retval = via_setNext(set, &item);
+		}
+		via_setDestroy(set);
+
+		/* AGP Memory */
+		set = global_ppriv[i].sets[1];
+		retval = via_setFirst(set, &item);
+		while (retval) {
+			DRM_DEBUG("free agp memory 0x%lx\n", item);
+			via_mmFreeMem((PMemBlock) item);
+			retval = via_setNext(set, &item);
+		}
+		via_setDestroy(set);
+		global_ppriv[i].used = 0;
+	}
+	via_release_futex(dev_priv, context); 
+	
+			
+#if defined(__linux__)
+	/* Linux specific until context tracking code gets ported to BSD */
+	/* Last context, perform cleanup */
+	if (dev->ctx_count == 1 && dev->dev_private) {
+	        DRM_DEBUG("Last Context\n");
+		if (dev->irq)
+			drm_irq_uninstall(dev);
+
+		via_cleanup_futex(dev_priv);
+		via_do_cleanup_map(dev);
+	}
+#endif
+
+	return 1;
+}
+
+int via_mem_alloc(DRM_IOCTL_ARGS)
+{
+	drm_via_mem_t mem;
+
+	DRM_COPY_FROM_USER_IOCTL(mem, (drm_via_mem_t __user *) data,
+				 sizeof(mem));
+
+	switch (mem.type) {
+	case VIDEO:
+		if (via_fb_alloc(&mem) < 0)
+			return -EFAULT;
+		DRM_COPY_TO_USER_IOCTL((drm_via_mem_t __user *) data, mem,
+				       sizeof(mem));
+		return 0;
+	case AGP:
+		if (via_agp_alloc(&mem) < 0)
+			return -EFAULT;
+		DRM_COPY_TO_USER_IOCTL((drm_via_mem_t __user *) data, mem,
+				       sizeof(mem));
+		return 0;
+	}
+
+	return -EFAULT;
+}
+
+static int via_fb_alloc(drm_via_mem_t * mem)
+{
+	drm_via_mm_t fb;
+	PMemBlock block;
+	int retval = 0;
+
+	if (!FBHeap)
+		return -1;
+
+	fb.size = mem->size;
+	fb.context = mem->context;
+
+	block = via_mmAllocMem(FBHeap, fb.size, 5, 0);
+	if (block) {
+		fb.offset = block->ofs;
+		fb.free = (unsigned long)block;
+		if (!add_alloc_set(fb.context, VIDEO, fb.free)) {
+			DRM_DEBUG("adding to allocation set fails\n");
+			via_mmFreeMem((PMemBlock) fb.free);
+			retval = -1;
+		}
+	} else {
+		fb.offset = 0;
+		fb.size = 0;
+		fb.free = 0;
+		retval = -1;
+	}
+
+	mem->offset = fb.offset;
+	mem->index = fb.free;
+
+	DRM_DEBUG("alloc fb, size = %d, offset = %d\n", fb.size,
+		  (int)fb.offset);
+
+	return retval;
+}
+
+static int via_agp_alloc(drm_via_mem_t * mem)
+{
+	drm_via_mm_t agp;
+	PMemBlock block;
+	int retval = 0;
+
+	if (!AgpHeap)
+		return -1;
+
+	agp.size = mem->size;
+	agp.context = mem->context;
+
+	block = via_mmAllocMem(AgpHeap, agp.size, 5, 0);
+	if (block) {
+		agp.offset = block->ofs;
+		agp.free = (unsigned long)block;
+		if (!add_alloc_set(agp.context, AGP, agp.free)) {
+			DRM_DEBUG("adding to allocation set fails\n");
+			via_mmFreeMem((PMemBlock) agp.free);
+			retval = -1;
+		}
+	} else {
+		agp.offset = 0;
+		agp.size = 0;
+		agp.free = 0;
+	}
+
+	mem->offset = agp.offset;
+	mem->index = agp.free;
+
+	DRM_DEBUG("alloc agp, size = %d, offset = %d\n", agp.size,
+		  (unsigned int)agp.offset);
+	return retval;
+}
+
+int via_mem_free(DRM_IOCTL_ARGS)
+{
+	drm_via_mem_t mem;
+
+	DRM_COPY_FROM_USER_IOCTL(mem, (drm_via_mem_t __user *) data,
+				 sizeof(mem));
+
+	switch (mem.type) {
+
+	case VIDEO:
+		if (via_fb_free(&mem) == 0)
+			return 0;
+		break;
+	case AGP:
+		if (via_agp_free(&mem) == 0)
+			return 0;
+		break;
+	}
+
+	return -EFAULT;
+}
+
+static int via_fb_free(drm_via_mem_t * mem)
+{
+	drm_via_mm_t fb;
+	int retval = 0;
+
+	if (!FBHeap) {
+		return -1;
+	}
+
+	fb.free = mem->index;
+	fb.context = mem->context;
+
+	if (!fb.free) {
+		return -1;
+
+	}
+
+	via_mmFreeMem((PMemBlock) fb.free);
+
+	if (!del_alloc_set(fb.context, VIDEO, fb.free)) {
+		retval = -1;
+	}
+
+	DRM_DEBUG("free fb, free = %ld\n", fb.free);
+
+	return retval;
+}
+
+static int via_agp_free(drm_via_mem_t * mem)
+{
+	drm_via_mm_t agp;
+
+	int retval = 0;
+
+	agp.free = mem->index;
+	agp.context = mem->context;
+
+	if (!agp.free)
+		return -1;
+
+	via_mmFreeMem((PMemBlock) agp.free);
+
+	if (!del_alloc_set(agp.context, AGP, agp.free)) {
+		retval = -1;
+	}
+
+	DRM_DEBUG("free agp, free = %ld\n", agp.free);
+
+	return retval;
+}
diff --git a/drivers/char/drm/via_mm.h b/drivers/char/drm/via_mm.h
new file mode 100644
--- /dev/null
+++ b/drivers/char/drm/via_mm.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2003 S3 Graphics, Inc. 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, sub license,
+ * 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 NON-INFRINGEMENT. IN NO EVENT SHALL
+ * VIA, S3 GRAPHICS, 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.
+ */
+#ifndef _via_drm_mm_h_
+#define _via_drm_mm_h_
+
+typedef struct {
+	unsigned int context;
+	unsigned int size;
+	unsigned long offset;
+	unsigned long free;
+} drm_via_mm_t;
+
+typedef struct {
+	unsigned int size;
+	unsigned long handle;
+	void *virtual;
+} drm_via_dma_t;
+
+#endif
diff --git a/drivers/char/drm/via_verifier.c b/drivers/char/drm/via_verifier.c
new file mode 100644
--- /dev/null
+++ b/drivers/char/drm/via_verifier.c
@@ -0,0 +1,1061 @@
+/*
+ * Copyright 2004 The Unichrome Project. All Rights Reserved.
+ * Copyright 2005 Thomas Hellstrom. 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, sub license,
+ * 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 NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHOR(S), AND/OR THE COPYRIGHT HOLDER(S) 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.
+ *
+ * Author: Thomas Hellstrom 2004, 2005.
+ * This code was written using docs obtained under NDA from VIA Inc.
+ *
+ * Don't run this code directly on an AGP buffer. Due to cache problems it will
+ * be very slow.
+ */
+
+
+#include "via_3d_reg.h"
+#include "drmP.h"
+#include "drm.h"
+#include "via_drm.h"
+#include "via_verifier.h"
+#include "via_drv.h"
+
+typedef enum{
+	state_command,
+	state_header2,
+	state_header1,
+	state_vheader5,
+	state_vheader6,
+	state_error
+} verifier_state_t;
+
+
+typedef enum{
+	no_check = 0,
+	check_for_header2,
+	check_for_header1,
+	check_for_header2_err,
+	check_for_header1_err,
+	check_for_fire,
+	check_z_buffer_addr0,
+	check_z_buffer_addr1,
+	check_z_buffer_addr_mode,
+	check_destination_addr0,
+	check_destination_addr1,
+	check_destination_addr_mode,
+	check_for_dummy,
+	check_for_dd,
+	check_texture_addr0,
+	check_texture_addr1,
+	check_texture_addr2,
+	check_texture_addr3,
+	check_texture_addr4,
+	check_texture_addr5,
+	check_texture_addr6,
+	check_texture_addr7,
+	check_texture_addr8,
+	check_texture_addr_mode,
+	check_for_vertex_count,
+	check_number_texunits,
+	forbidden_command
+}hazard_t;
+
+/*
+ * Associates each hazard above with a possible multi-command
+ * sequence. For example an address that is split over multiple
+ * commands and that needs to be checked at the first command 
+ * that does not include any part of the address.
+ */
+
+static drm_via_sequence_t seqs[] = { 
+	no_sequence,
+	no_sequence,
+	no_sequence,
+	no_sequence,
+	no_sequence,
+	no_sequence,
+	z_address,
+	z_address,
+	z_address,
+	dest_address,
+	dest_address,
+	dest_address,
+	no_sequence,
+	no_sequence,
+	tex_address,
+	tex_address,
+	tex_address,
+	tex_address,
+	tex_address,
+	tex_address,
+	tex_address,
+	tex_address,
+	tex_address,
+	tex_address,
+	no_sequence
+};
+    
+typedef struct{
+	unsigned int code;
+	hazard_t hz;
+} hz_init_t;
+
+
+
+static hz_init_t init_table1[] = {
+	{0xf2, check_for_header2_err},
+	{0xf0, check_for_header1_err},
+	{0xee, check_for_fire},
+	{0xcc, check_for_dummy},
+	{0xdd, check_for_dd},
+	{0x00, no_check},
+	{0x10, check_z_buffer_addr0},
+	{0x11, check_z_buffer_addr1},
+	{0x12, check_z_buffer_addr_mode},
+	{0x13, no_check},
+	{0x14, no_check},
+	{0x15, no_check},
+	{0x23, no_check},
+	{0x24, no_check},
+	{0x33, no_check},
+	{0x34, no_check},
+	{0x35, no_check},
+	{0x36, no_check},
+	{0x37, no_check},
+	{0x38, no_check},
+	{0x39, no_check},
+	{0x3A, no_check},
+	{0x3B, no_check},
+	{0x3C, no_check},
+	{0x3D, no_check},
+	{0x3E, no_check},
+	{0x40, check_destination_addr0},
+	{0x41, check_destination_addr1},
+	{0x42, check_destination_addr_mode},
+	{0x43, no_check},
+	{0x44, no_check},
+	{0x50, no_check},
+	{0x51, no_check},
+	{0x52, no_check},
+	{0x53, no_check},
+	{0x54, no_check},
+	{0x55, no_check},
+	{0x56, no_check},
+	{0x57, no_check},
+	{0x58, no_check},
+	{0x70, no_check},
+	{0x71, no_check},
+	{0x78, no_check},
+	{0x79, no_check},
+	{0x7A, no_check},
+	{0x7B, no_check},
+	{0x7C, no_check},
+	{0x7D, check_for_vertex_count}
+};
+
+   
+		       
+static hz_init_t init_table2[] = {
+	{0xf2, check_for_header2_err},
+	{0xf0, check_for_header1_err},
+	{0xee, check_for_fire},
+	{0xcc, check_for_dummy},
+	{0x00, check_texture_addr0},
+	{0x01, check_texture_addr0},
+	{0x02, check_texture_addr0},
+	{0x03, check_texture_addr0},
+	{0x04, check_texture_addr0},
+	{0x05, check_texture_addr0},
+	{0x06, check_texture_addr0},
+	{0x07, check_texture_addr0},
+	{0x08, check_texture_addr0},
+	{0x09, check_texture_addr0},
+	{0x20, check_texture_addr1},
+	{0x21, check_texture_addr1},
+	{0x22, check_texture_addr1},
+	{0x23, check_texture_addr4},
+	{0x2B, check_texture_addr3},
+	{0x2C, check_texture_addr3},
+	{0x2D, check_texture_addr3},
+	{0x2E, check_texture_addr3},
+	{0x2F, check_texture_addr3},
+	{0x30, check_texture_addr3},
+	{0x31, check_texture_addr3},
+	{0x32, check_texture_addr3},
+	{0x33, check_texture_addr3},
+	{0x34, check_texture_addr3},
+	{0x4B, check_texture_addr5},
+	{0x4C, check_texture_addr6},
+	{0x51, check_texture_addr7},
+	{0x52, check_texture_addr8},
+	{0x77, check_texture_addr2},
+	{0x78, no_check},
+	{0x79, no_check},
+	{0x7A, no_check},
+	{0x7B, check_texture_addr_mode},
+	{0x7C, no_check},
+	{0x7D, no_check},
+	{0x7E, no_check},
+	{0x7F, no_check},
+	{0x80, no_check},
+	{0x81, no_check},
+	{0x82, no_check},
+	{0x83, no_check},
+	{0x85, no_check},
+	{0x86, no_check},
+	{0x87, no_check},
+	{0x88, no_check},
+	{0x89, no_check},
+	{0x8A, no_check},
+	{0x90, no_check},
+	{0x91, no_check},
+	{0x92, no_check},
+	{0x93, no_check}
+};
+
+static hz_init_t init_table3[] = {
+	{0xf2, check_for_header2_err},
+	{0xf0, check_for_header1_err},
+	{0xcc, check_for_dummy},
+	{0x00, check_number_texunits}
+};
+   
+		       
+static hazard_t table1[256]; 
+static hazard_t table2[256]; 
+static hazard_t table3[256]; 
+
+
+
+static __inline__ int
+eat_words(const uint32_t **buf, const uint32_t *buf_end, unsigned num_words)
+{
+	if ((*buf - buf_end) >= num_words) {
+		*buf += num_words;
+		return 0;
+	} 
+	DRM_ERROR("Illegal termination of DMA command buffer\n");
+	return 1;
+}
+
+
+/*
+ * Partially stolen from drm_memory.h
+ */
+
+static __inline__ drm_map_t *
+via_drm_lookup_agp_map (drm_via_state_t *seq, unsigned long offset, unsigned long size, 
+			drm_device_t *dev)
+{
+	struct list_head *list;
+	drm_map_list_t *r_list;
+	drm_map_t *map = seq->map_cache;
+
+	if (map && map->offset <= offset && (offset + size) <= (map->offset + map->size)) {
+		return map;
+	}
+		
+	list_for_each(list, &dev->maplist->head) {
+		r_list = (drm_map_list_t *) list;
+		map = r_list->map;
+		if (!map)
+			continue;
+		if (map->offset <= offset && (offset + size) <= (map->offset + map->size) && 
+		    !(map->flags & _DRM_RESTRICTED) && (map->type == _DRM_AGP)) {
+			seq->map_cache = map;
+			return map;
+		}
+	}
+	return NULL;
+}
+
+
+/*
+ * Require that all AGP texture levels reside in the same AGP map which should 
+ * be mappable by the client. This is not a big restriction.
+ * FIXME: To actually enforce this security policy strictly, drm_rmmap 
+ * would have to wait for dma quiescent before removing an AGP map. 
+ * The via_drm_lookup_agp_map call in reality seems to take
+ * very little CPU time.
+ */
+
+
+static __inline__ int
+finish_current_sequence(drm_via_state_t *cur_seq) 
+{
+	switch(cur_seq->unfinished) {
+	case z_address:
+		DRM_DEBUG("Z Buffer start address is 0x%x\n", cur_seq->z_addr);
+		break;
+	case dest_address:
+		DRM_DEBUG("Destination start address is 0x%x\n", cur_seq->d_addr);
+		break;
+	case tex_address:
+		if (cur_seq->agp_texture) {			 
+			unsigned start = cur_seq->tex_level_lo[cur_seq->texture];
+			unsigned end = cur_seq->tex_level_hi[cur_seq->texture];
+			unsigned long lo=~0, hi=0, tmp;
+			uint32_t *addr, *pitch, *height, tex;
+			unsigned i;
+
+			if (end > 9) end = 9;
+			if (start > 9) start = 9;
+
+			addr =&(cur_seq->t_addr[tex = cur_seq->texture][start]);
+			pitch = &(cur_seq->pitch[tex][start]);
+			height = &(cur_seq->height[tex][start]);
+
+			for (i=start; i<= end; ++i) {
+				tmp = *addr++;
+				if (tmp < lo) lo = tmp;
+				tmp += (*height++ << *pitch++);
+				if (tmp > hi) hi = tmp;
+			}
+
+			if (! via_drm_lookup_agp_map (cur_seq, lo, hi - lo, cur_seq->dev)) {
+				DRM_ERROR("AGP texture is not in allowed map\n");
+				return 2;
+			}
+		}	
+		break;
+	default:
+		break;
+	}
+	cur_seq->unfinished = no_sequence;
+	return 0;
+}
+
+static __inline__ int 
+investigate_hazard( uint32_t cmd, hazard_t hz, drm_via_state_t *cur_seq)
+{
+	register uint32_t tmp, *tmp_addr;
+
+	if (cur_seq->unfinished && (cur_seq->unfinished != seqs[hz])) {
+		int ret;
+		if ((ret = finish_current_sequence(cur_seq))) return ret;
+	}
+
+	switch(hz) {
+	case check_for_header2:
+		if (cmd == HALCYON_HEADER2) return 1;
+		return 0;
+	case check_for_header1:
+		if ((cmd & HALCYON_HEADER1MASK) == HALCYON_HEADER1) return 1;
+		return 0;
+	case check_for_header2_err:
+		if (cmd == HALCYON_HEADER2) return 1;
+		DRM_ERROR("Illegal DMA HALCYON_HEADER2 command\n");
+		break;
+	case check_for_header1_err:
+		if ((cmd & HALCYON_HEADER1MASK) == HALCYON_HEADER1) return 1;
+		DRM_ERROR("Illegal DMA HALCYON_HEADER1 command\n");
+		break;
+	case check_for_fire:
+		if ((cmd & HALCYON_FIREMASK) == HALCYON_FIRECMD) return 1; 
+		DRM_ERROR("Illegal DMA HALCYON_FIRECMD command\n");
+		break;
+	case check_for_dummy:
+		if (HC_DUMMY == cmd) return 0;
+		DRM_ERROR("Illegal DMA HC_DUMMY command\n");
+		break;
+	case check_for_dd:
+		if (0xdddddddd == cmd) return 0;
+		DRM_ERROR("Illegal DMA 0xdddddddd command\n");
+		break;
+	case check_z_buffer_addr0:
+		cur_seq->unfinished = z_address;
+		cur_seq->z_addr = (cur_seq->z_addr & 0xFF000000) |
+			(cmd & 0x00FFFFFF);
+		return 0;
+	case check_z_buffer_addr1:
+		cur_seq->unfinished = z_address;
+		cur_seq->z_addr = (cur_seq->z_addr & 0x00FFFFFF) |
+			((cmd & 0xFF) << 24);
+		return 0;
+	case check_z_buffer_addr_mode:
+		cur_seq->unfinished = z_address;
+		if ((cmd & 0x0000C000) == 0) return 0;
+		DRM_ERROR("Attempt to place Z buffer in system memory\n");
+		return 2;
+	case check_destination_addr0:
+		cur_seq->unfinished = dest_address;
+		cur_seq->d_addr = (cur_seq->d_addr & 0xFF000000) |
+			(cmd & 0x00FFFFFF);
+		return 0;
+	case check_destination_addr1:
+		cur_seq->unfinished = dest_address;
+		cur_seq->d_addr = (cur_seq->d_addr & 0x00FFFFFF) |
+			((cmd & 0xFF) << 24);
+		return 0;
+	case check_destination_addr_mode:
+		cur_seq->unfinished = dest_address;
+		if ((cmd & 0x0000C000) == 0) return 0;
+		DRM_ERROR("Attempt to place 3D drawing buffer in system memory\n");
+		return 2;	    
+	case check_texture_addr0:
+		cur_seq->unfinished = tex_address;
+		tmp = (cmd >> 24);
+		tmp_addr = &cur_seq->t_addr[cur_seq->texture][tmp];
+		*tmp_addr = (*tmp_addr & 0xFF000000) | (cmd & 0x00FFFFFF);
+		return 0;
+	case check_texture_addr1:
+		cur_seq->unfinished = tex_address;
+		tmp = ((cmd >> 24) - 0x20);
+		tmp += tmp << 1;
+		tmp_addr = &cur_seq->t_addr[cur_seq->texture][tmp];
+		*tmp_addr = (*tmp_addr & 0x00FFFFFF) | ((cmd & 0xFF) << 24);
+		tmp_addr++;
+		*tmp_addr = (*tmp_addr & 0x00FFFFFF) | ((cmd & 0xFF00) << 16);
+		tmp_addr++;
+		*tmp_addr = (*tmp_addr & 0x00FFFFFF) | ((cmd & 0xFF0000) << 8);
+		return 0;
+	case check_texture_addr2:
+		cur_seq->unfinished = tex_address;
+		cur_seq->tex_level_lo[tmp = cur_seq->texture] = cmd & 0x3F;
+		cur_seq->tex_level_hi[tmp] = (cmd & 0xFC0) >> 6;
+		return 0;
+	case check_texture_addr3:
+		cur_seq->unfinished = tex_address;
+		tmp = ((cmd >> 24) - 0x2B);
+		cur_seq->pitch[cur_seq->texture][tmp] = (cmd & 0x00F00000) >> 20;
+		if (!tmp && (cmd & 0x000FFFFF)) {
+			DRM_ERROR("Unimplemented texture level 0 pitch mode.\n");
+			return 2;
+		}
+		return 0;
+	case check_texture_addr4:
+		cur_seq->unfinished = tex_address;
+		tmp_addr = &cur_seq->t_addr[cur_seq->texture][9];
+		*tmp_addr = (*tmp_addr & 0x00FFFFFF) | ((cmd & 0xFF) << 24);
+		return 0;
+	case check_texture_addr5:
+	case check_texture_addr6:
+		cur_seq->unfinished = tex_address;
+		/*
+		 * Texture width. We don't care since we have the pitch.
+		 */  
+		return 0;
+	case check_texture_addr7:
+		cur_seq->unfinished = tex_address;
+		tmp_addr = &(cur_seq->height[cur_seq->texture][0]);
+		tmp_addr[5] = 1 << ((cmd & 0x00F00000) >> 20);
+		tmp_addr[4] = 1 << ((cmd & 0x000F0000) >> 16);
+		tmp_addr[3] = 1 << ((cmd & 0x0000F000) >> 12);
+		tmp_addr[2] = 1 << ((cmd & 0x00000F00) >> 8);
+		tmp_addr[1] = 1 << ((cmd & 0x000000F0) >> 4);
+		tmp_addr[0] = 1 << (cmd & 0x0000000F);
+		return 0;
+	case check_texture_addr8:
+		cur_seq->unfinished = tex_address;
+		tmp_addr = &(cur_seq->height[cur_seq->texture][0]);
+		tmp_addr[9] = 1 << ((cmd & 0x0000F000) >> 12);
+	        tmp_addr[8] = 1 << ((cmd & 0x00000F00) >> 8);
+		tmp_addr[7] = 1 << ((cmd & 0x000000F0) >> 4);
+		tmp_addr[6] = 1 << (cmd & 0x0000000F);
+		return 0;
+	case check_texture_addr_mode:
+		cur_seq->unfinished = tex_address;
+		if ( 2 == (tmp = cmd & 0x00000003)) {
+			DRM_ERROR("Attempt to fetch texture from system memory.\n"); 
+			return 2;
+		}
+		cur_seq->agp_texture = (tmp == 3);
+		cur_seq->tex_palette_size[cur_seq->texture] = 
+			(cmd >> 16) & 0x000000007;
+		return 0;
+	case check_for_vertex_count:
+		cur_seq->vertex_count = cmd & 0x0000FFFF;
+		return 0;
+	case check_number_texunits:
+	        cur_seq->multitex = (cmd >> 3) & 1;
+		return 0;
+	default:
+		DRM_ERROR("Illegal DMA data: 0x%x\n", cmd);
+		return 2;
+	}
+	return 2;
+}
+
+
+static __inline__ int
+via_check_prim_list(uint32_t const **buffer, const uint32_t *buf_end,
+		    drm_via_state_t *cur_seq)
+{
+	drm_via_private_t *dev_priv = (drm_via_private_t *) cur_seq->dev->dev_private;
+	uint32_t a_fire, bcmd , dw_count;
+	int ret = 0;
+	int have_fire;
+	const uint32_t *buf = *buffer;
+
+	while(buf < buf_end) {
+	        have_fire = 0;
+		if ((buf_end - buf) < 2) {
+			DRM_ERROR("Unexpected termination of primitive list.\n");
+			ret = 1;
+			break;
+		}
+		if ((*buf & HC_ACMD_MASK) != HC_ACMD_HCmdB) break;
+		bcmd = *buf++;
+		if ((*buf & HC_ACMD_MASK) != HC_ACMD_HCmdA) {
+			DRM_ERROR("Expected Vertex List A command, got 0x%x\n",
+				  *buf);
+			ret = 1;
+			break;
+		}
+		a_fire = *buf++ | HC_HPLEND_MASK | HC_HPMValidN_MASK | HC_HE3Fire_MASK;	
+	
+		/*
+		 * How many dwords per vertex ?
+		 */ 
+		
+		if (cur_seq->agp && ((bcmd & (0xF << 11)) == 0)) {
+			DRM_ERROR("Illegal B command vertex data for AGP.\n");
+			ret = 1;
+			break;
+		} 
+
+		dw_count = 0;
+		if (bcmd & (1 << 7)) dw_count += (cur_seq->multitex) ? 2:1;
+		if (bcmd & (1 << 8)) dw_count += (cur_seq->multitex) ? 2:1;
+		if (bcmd & (1 << 9)) dw_count++;
+		if (bcmd & (1 << 10)) dw_count++;
+		if (bcmd & (1 << 11)) dw_count++;
+		if (bcmd & (1 << 12)) dw_count++;
+		if (bcmd & (1 << 13)) dw_count++;
+		if (bcmd & (1 << 14)) dw_count++;
+
+		while(buf < buf_end) {
+			if (*buf == a_fire) {
+				if (dev_priv->num_fire_offsets >= VIA_FIRE_BUF_SIZE) {
+					DRM_ERROR("Fire offset buffer full.\n");
+					ret = 1;
+					break;
+				}
+				dev_priv->fire_offsets[dev_priv->num_fire_offsets++] = buf;
+			        have_fire = 1;
+				buf++;
+				if (buf < buf_end && *buf == a_fire) 
+					buf++;
+				break;
+			}
+			if ((*buf == HALCYON_HEADER2) || 
+			    ((*buf & HALCYON_FIREMASK) == HALCYON_FIRECMD)) {
+				DRM_ERROR("Missing Vertex Fire command, "
+					  "Stray Vertex Fire command  or verifier "
+					  "lost sync.\n");
+				ret = 1;
+				break;
+			}
+			if ((ret = eat_words(&buf, buf_end, dw_count)))
+				break;
+		}
+		if (buf >= buf_end && !have_fire) {
+			DRM_ERROR("Missing Vertex Fire command or verifier "
+				  "lost sync.\n");
+			ret = 1;
+			break;
+		}
+		if (cur_seq->agp && ((buf - cur_seq->buf_start) & 0x01)) {
+			DRM_ERROR("AGP Primitive list end misaligned.\n");
+			ret = 1;
+			break;
+		}
+	} 
+	*buffer = buf;
+	return ret;
+}
+
+
+		       
+
+
+static __inline__ verifier_state_t
+via_check_header2( uint32_t const **buffer, const uint32_t *buf_end, 
+		   drm_via_state_t *hc_state)
+{
+	uint32_t cmd;
+	int hz_mode;
+	hazard_t hz;
+	const uint32_t *buf = *buffer;
+	const hazard_t *hz_table;
+
+
+	if ((buf_end - buf) < 2) {
+		DRM_ERROR("Illegal termination of DMA HALCYON_HEADER2 sequence.\n");
+		return state_error;
+	}
+	buf++;
+	cmd = (*buf++ & 0xFFFF0000) >> 16;
+
+	switch(cmd) {
+	case HC_ParaType_CmdVdata:
+		if (via_check_prim_list(&buf, buf_end, hc_state )) 
+			return state_error;
+		*buffer = buf;
+		return state_command;
+	case HC_ParaType_NotTex:
+		hz_table = table1;
+		break;
+	case HC_ParaType_Tex:
+		hc_state->texture = 0;
+		hz_table = table2;
+		break;
+	case (HC_ParaType_Tex | (HC_SubType_Tex1 << 8)):
+		hc_state->texture = 1;
+		hz_table = table2;
+		break;
+	case (HC_ParaType_Tex | (HC_SubType_TexGeneral << 8)):
+		hz_table = table3;
+		break;
+	case HC_ParaType_Auto:
+		if (eat_words(&buf, buf_end, 2))
+			return state_error;
+		*buffer = buf;
+		return state_command;
+	case (HC_ParaType_Palette | (HC_SubType_Stipple << 8)):
+		if (eat_words(&buf, buf_end, 32))
+			return state_error;
+		*buffer = buf;
+		return state_command;
+	case (HC_ParaType_Palette | (HC_SubType_TexPalette0 << 8)):
+	case (HC_ParaType_Palette | (HC_SubType_TexPalette1 << 8)):
+		DRM_ERROR("Texture palettes are rejected because of "
+			  "lack of info how to determine their size.\n");
+		return state_error;
+	case (HC_ParaType_Palette | (HC_SubType_FogTable << 8)):
+		DRM_ERROR("Fog factor palettes are rejected because of "
+			  "lack of info how to determine their size.\n");
+		return state_error;
+	default:
+
+		/*
+		 * There are some unimplemented HC_ParaTypes here, that
+		 * need to be implemented if the Mesa driver is extended.
+		 */
+
+		DRM_ERROR("Invalid or unimplemented HALCYON_HEADER2 "
+			  "DMA subcommand: 0x%x. Previous dword: 0x%x\n", 
+			  cmd, *(buf -2));
+		*buffer = buf;
+		return state_error;
+	}
+
+	while(buf < buf_end) {
+		cmd = *buf++;
+		if ((hz = hz_table[cmd >> 24])) {
+			if ((hz_mode = investigate_hazard(cmd, hz, hc_state))) {
+				if (hz_mode == 1) {
+					buf--;
+					break;
+				}
+				return state_error;
+			}
+		} else if (hc_state->unfinished && 
+			   finish_current_sequence(hc_state)) {
+			return state_error;
+		}
+	}
+	if (hc_state->unfinished && finish_current_sequence(hc_state)) {
+		return state_error;
+	}
+	*buffer = buf;
+	return state_command;
+}
+
+static __inline__ verifier_state_t
+via_parse_header2( drm_via_private_t *dev_priv, uint32_t const **buffer, const uint32_t *buf_end,
+		   int *fire_count)
+{
+	uint32_t cmd;
+	const uint32_t *buf = *buffer;
+	const uint32_t *next_fire; 
+	int burst = 0;
+
+	next_fire = dev_priv->fire_offsets[*fire_count];
+	buf++;
+	cmd = (*buf & 0xFFFF0000) >> 16;
+	VIA_WRITE(HC_REG_TRANS_SET + HC_REG_BASE, *buf++);
+	switch(cmd) {
+	case HC_ParaType_CmdVdata:
+		while ((buf < buf_end) &&
+		       (*fire_count < dev_priv->num_fire_offsets) && 
+		       (*buf & HC_ACMD_MASK) == HC_ACMD_HCmdB ) {
+			while(buf <= next_fire) {
+				VIA_WRITE(HC_REG_TRANS_SPACE + HC_REG_BASE + (burst & 63), *buf++);
+				burst += 4;
+			}
+			if ( ( buf < buf_end ) && ((*buf & HALCYON_FIREMASK) == HALCYON_FIRECMD))
+				buf++;
+
+			if (++(*fire_count) < dev_priv->num_fire_offsets) 
+				next_fire = dev_priv->fire_offsets[*fire_count];
+		}
+		break;
+	default:
+		while(buf < buf_end) {
+			
+			if ( *buf == HC_HEADER2 ||
+			     (*buf & HALCYON_HEADER1MASK) == HALCYON_HEADER1  ||
+			     (*buf & VIA_VIDEOMASK) == VIA_VIDEO_HEADER5 ||
+			     (*buf & VIA_VIDEOMASK) == VIA_VIDEO_HEADER6 ) break;
+			
+			VIA_WRITE(HC_REG_TRANS_SPACE + HC_REG_BASE + (burst & 63), *buf++);
+			burst +=4;
+		}
+	}
+	*buffer = buf;
+	return state_command;
+}
+
+
+
+static __inline__ int
+verify_mmio_address( uint32_t address)
+{
+	if ((address > 0x3FF) && (address < 0xC00 )) {
+		DRM_ERROR("Invalid VIDEO DMA command. "
+			  "Attempt to access 3D- or command burst area.\n");
+		return 1;
+	} else if ((address > 0xCFF) && (address < 0x1300)) {
+		DRM_ERROR("Invalid VIDEO DMA command. "
+			  "Attempt to access PCI DMA area.\n");
+		return 1;		
+	} else if (address > 0x13FF ) {
+		DRM_ERROR("Invalid VIDEO DMA command. "
+			  "Attempt to access VGA registers.\n");
+		return 1;
+	}
+	return 0;
+}
+
+static __inline__ int
+verify_video_tail( uint32_t const **buffer, const uint32_t *buf_end, uint32_t dwords) 
+{
+	const uint32_t *buf = *buffer;
+
+	if (buf_end - buf < dwords) {
+		DRM_ERROR("Illegal termination of video command.\n");
+		return 1;
+	}
+	while (dwords--) {
+		if (*buf++) {
+			DRM_ERROR("Illegal video command tail.\n");
+			return 1;
+		}
+	}
+	*buffer = buf;
+	return 0;
+}
+		
+
+static __inline__ verifier_state_t
+via_check_header1( uint32_t const **buffer, const uint32_t *buf_end )
+{
+	uint32_t cmd;
+	const uint32_t *buf = *buffer;
+	verifier_state_t ret = state_command;
+
+	while (buf < buf_end) {
+		cmd = *buf;
+		if ((cmd > ((0x3FF >> 2) | HALCYON_HEADER1)) &&
+		    (cmd < ((0xC00 >> 2) | HALCYON_HEADER1))) {			
+			if ((cmd & HALCYON_HEADER1MASK) != HALCYON_HEADER1) 
+				break;
+			DRM_ERROR("Invalid HALCYON_HEADER1 command. "
+				  "Attempt to access 3D- or command burst area.\n");
+			ret = state_error;
+			break;
+		} else if (cmd > ((0xCFF >> 2) | HALCYON_HEADER1)) {
+			if ((cmd & HALCYON_HEADER1MASK) != HALCYON_HEADER1) 
+				break;
+			DRM_ERROR("Invalid HALCYON_HEADER1 command. "
+				  "Attempt to access VGA registers.\n");
+			ret = state_error;
+			break;			
+		} else {			
+			buf += 2;
+		}
+	}
+	*buffer = buf;
+	return ret;
+}
+
+static __inline__ verifier_state_t
+via_parse_header1( drm_via_private_t *dev_priv, uint32_t const **buffer, const uint32_t *buf_end )
+{
+	register uint32_t cmd;
+	const uint32_t *buf = *buffer;
+
+	while (buf < buf_end) {
+		cmd = *buf;
+		if ((cmd & HALCYON_HEADER1MASK) != HALCYON_HEADER1) break;
+		VIA_WRITE( (cmd & ~HALCYON_HEADER1MASK) << 2, *++buf); 
+		buf++;
+	}
+	*buffer = buf;
+	return state_command;
+}
+
+static __inline__ verifier_state_t
+via_check_vheader5( uint32_t const **buffer, const uint32_t *buf_end )
+{
+	uint32_t data;
+	const uint32_t *buf = *buffer;
+
+	if (buf_end - buf < 4) {
+		DRM_ERROR("Illegal termination of video header5 command\n");
+		return state_error;
+	}
+
+	data = *buf++ & ~VIA_VIDEOMASK;
+	if (verify_mmio_address(data))
+		return state_error;
+
+	data = *buf++;
+	if (*buf++ != 0x00F50000) {
+		DRM_ERROR("Illegal header5 header data\n");
+		return state_error;
+	}
+	if (*buf++ != 0x00000000) {
+		DRM_ERROR("Illegal header5 header data\n");
+		return state_error;
+	}
+	if (eat_words(&buf, buf_end, data)) 
+		return state_error;
+	if ((data & 3) && verify_video_tail(&buf, buf_end, 4 - (data & 3))) 
+		return state_error;
+	*buffer = buf;
+	return state_command;
+	       
+} 
+
+static __inline__ verifier_state_t
+via_parse_vheader5( drm_via_private_t *dev_priv, uint32_t const **buffer, const uint32_t *buf_end )
+{
+  uint32_t addr, count, i;
+	const uint32_t *buf = *buffer;
+	
+	addr = *buf++ & ~VIA_VIDEOMASK;
+	i = count = *buf;
+	buf += 3;
+	while(i--) {
+		VIA_WRITE(addr, *buf++);
+	}
+	if (count & 3) buf += 4 - (count & 3);
+	*buffer = buf;
+	return state_command;	       
+} 
+
+
+static __inline__ verifier_state_t
+via_check_vheader6( uint32_t const **buffer, const uint32_t *buf_end )
+{
+	uint32_t data;
+	const uint32_t *buf = *buffer;
+	uint32_t i;
+
+
+	if (buf_end - buf < 4) {
+		DRM_ERROR("Illegal termination of video header6 command\n");
+		return state_error;
+	}
+	buf++;
+	data = *buf++;
+	if (*buf++ != 0x00F60000) {
+		DRM_ERROR("Illegal header6 header data\n");
+		return state_error;
+	}
+	if (*buf++ != 0x00000000) {
+		DRM_ERROR("Illegal header6 header data\n");
+		return state_error;
+	}
+	if ((buf_end - buf) < (data << 1)) {
+		DRM_ERROR("Illegal termination of video header6 command\n");
+		return state_error;
+	}
+	for (i=0; i<data; ++i) {
+		if (verify_mmio_address(*buf++))
+			return state_error;
+		buf++;
+	}
+	data <<= 1;
+	if ((data & 3) && verify_video_tail(&buf, buf_end, 4 - (data & 3)))
+		return state_error;
+	*buffer = buf;
+	return state_command;
+} 
+
+static __inline__ verifier_state_t
+via_parse_vheader6( drm_via_private_t *dev_priv, uint32_t const **buffer, const uint32_t *buf_end )
+{
+
+  uint32_t addr, count, i;
+	const uint32_t *buf = *buffer;
+
+	i = count = *++buf;
+	buf += 3;
+	while(i--) {
+		addr = *buf++;
+		VIA_WRITE(addr, *buf++);
+	}
+	count <<= 1;
+	if (count & 3) buf += 4 - (count & 3);
+	*buffer = buf;
+	return state_command;
+} 
+
+
+
+int 
+via_verify_command_stream(const uint32_t * buf, unsigned int size, drm_device_t *dev,
+			  int agp)
+{
+
+	drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
+	drm_via_state_t *hc_state = &dev_priv->hc_state;
+	drm_via_state_t saved_state = *hc_state;
+	uint32_t cmd;
+	const uint32_t *buf_end = buf + ( size >> 2 );
+	verifier_state_t state = state_command;
+	int pro_group_a = dev_priv->pro_group_a;
+	
+	hc_state->dev = dev;
+	hc_state->unfinished = no_sequence;
+	hc_state->map_cache = NULL;
+	hc_state->agp = agp;
+	hc_state->buf_start = buf;
+	dev_priv->num_fire_offsets = 0;
+
+	while (buf < buf_end) {
+
+		switch (state) {
+		case state_header2:
+		  state = via_check_header2( &buf, buf_end, hc_state );
+			break;
+		case state_header1:
+			state = via_check_header1( &buf, buf_end );
+			break;
+		case state_vheader5:
+			state = via_check_vheader5( &buf, buf_end );
+			break;
+		case state_vheader6:
+			state = via_check_vheader6( &buf, buf_end );
+			break;
+		case state_command:
+			if (HALCYON_HEADER2 == (cmd = *buf)) 
+				state = state_header2;
+			else if ((cmd & HALCYON_HEADER1MASK) == HALCYON_HEADER1) 
+				state = state_header1;
+			else if (pro_group_a && (cmd & VIA_VIDEOMASK) == VIA_VIDEO_HEADER5)
+				state = state_vheader5;
+			else if (pro_group_a && (cmd & VIA_VIDEOMASK) == VIA_VIDEO_HEADER6)
+				state = state_vheader6;
+			else {
+				DRM_ERROR("Invalid / Unimplemented DMA HEADER command. 0x%x\n",
+					  cmd);
+				state = state_error;
+			}
+			break;
+		case state_error:
+		default:
+			*hc_state = saved_state;
+			return DRM_ERR(EINVAL);			
+		}
+	}	
+	if (state == state_error) {
+		*hc_state = saved_state;
+		return DRM_ERR(EINVAL);
+	}
+	return 0;
+}
+
+int 
+via_parse_command_stream(drm_device_t *dev, const uint32_t * buf, unsigned int size)
+{
+
+	drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
+	uint32_t cmd;
+	const uint32_t *buf_end = buf + ( size >> 2 );
+	verifier_state_t state = state_command;
+	int fire_count = 0;
+	
+	while (buf < buf_end) {
+
+		switch (state) {
+		case state_header2:
+		  state = via_parse_header2( dev_priv, &buf, buf_end, &fire_count );
+			break;
+		case state_header1:
+			state = via_parse_header1( dev_priv, &buf, buf_end );
+			break;
+		case state_vheader5:
+			state = via_parse_vheader5( dev_priv, &buf, buf_end );
+			break;
+		case state_vheader6:
+			state = via_parse_vheader6( dev_priv, &buf, buf_end );
+			break;
+		case state_command:
+			if (HALCYON_HEADER2 == (cmd = *buf)) 
+				state = state_header2;
+			else if ((cmd & HALCYON_HEADER1MASK) == HALCYON_HEADER1) 
+				state = state_header1;
+			else if ((cmd & VIA_VIDEOMASK) == VIA_VIDEO_HEADER5)
+				state = state_vheader5;
+			else if ((cmd & VIA_VIDEOMASK) == VIA_VIDEO_HEADER6)
+				state = state_vheader6;
+			else {
+				DRM_ERROR("Invalid / Unimplemented DMA HEADER command. 0x%x\n",
+					  cmd);
+				state = state_error;
+			}
+			break;
+		case state_error:
+		default:
+			return DRM_ERR(EINVAL);			
+		}
+	}	
+	if (state == state_error) {
+		return DRM_ERR(EINVAL);
+	}
+	return 0;
+}
+
+
+
+static void 
+setup_hazard_table(hz_init_t init_table[], hazard_t table[], int size)
+{
+	int i;
+
+	for(i=0; i<256; ++i) {
+		table[i] = forbidden_command;
+	}
+
+	for(i=0; i<size; ++i) {
+		table[init_table[i].code] = init_table[i].hz;
+	}
+}
+
+void 
+via_init_command_verifier( void )
+{
+	setup_hazard_table(init_table1, table1, sizeof(init_table1) / sizeof(hz_init_t));
+	setup_hazard_table(init_table2, table2, sizeof(init_table2) / sizeof(hz_init_t));
+	setup_hazard_table(init_table3, table3, sizeof(init_table3) / sizeof(hz_init_t));
+}
diff --git a/drivers/char/drm/via_verifier.h b/drivers/char/drm/via_verifier.h
new file mode 100644
--- /dev/null
+++ b/drivers/char/drm/via_verifier.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2004 The Unichrome Project. 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, sub license,
+ * 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 NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE UNICHROME PROJECT, 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.
+ *
+ * Author: Thomas Hellström 2004.
+ */
+
+#ifndef _VIA_VERIFIER_H_
+#define _VIA_VERIFIER_H_
+
+typedef enum{
+	no_sequence = 0, 
+	z_address,
+	dest_address,
+	tex_address
+}drm_via_sequence_t;
+
+
+
+typedef struct{
+	unsigned texture;
+	uint32_t z_addr; 
+	uint32_t d_addr; 
+        uint32_t t_addr[2][10];
+	uint32_t pitch[2][10];
+	uint32_t height[2][10];
+	uint32_t tex_level_lo[2]; 
+	uint32_t tex_level_hi[2];
+	uint32_t tex_palette_size[2];
+	drm_via_sequence_t unfinished;
+	int agp_texture;
+	int multitex;
+	drm_device_t *dev;
+	drm_map_t *map_cache;
+	uint32_t vertex_count;
+	int agp;
+	const uint32_t *buf_start;
+} drm_via_state_t;
+
+extern int via_verify_command_stream(const uint32_t * buf, unsigned int size, 
+				     drm_device_t *dev, int agp);
+
+#endif
diff --git a/drivers/char/drm/via_video.c b/drivers/char/drm/via_video.c
new file mode 100644
--- /dev/null
+++ b/drivers/char/drm/via_video.c
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2005 Thomas Hellstrom. 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, sub license,
+ * 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 NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHOR(S), AND/OR THE COPYRIGHT HOLDER(S) 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.
+ *
+ * Author: Thomas Hellstrom 2005.
+ *
+ * Video and XvMC related functions.
+ */
+
+#include "drmP.h"
+#include "via_drm.h"
+#include "via_drv.h"
+
+void
+via_init_futex(drm_via_private_t *dev_priv)
+{
+	unsigned int i;
+
+	DRM_DEBUG("%s\n", __FUNCTION__);
+
+	for (i = 0; i < VIA_NR_XVMC_LOCKS; ++i) {
+		DRM_INIT_WAITQUEUE(&(dev_priv->decoder_queue[i]));
+		XVMCLOCKPTR(dev_priv->sarea_priv, i)->lock = 0;
+	}
+}
+
+void
+via_cleanup_futex(drm_via_private_t *dev_priv)
+{
+}	
+
+void
+via_release_futex(drm_via_private_t *dev_priv, int context)
+{
+	unsigned int i;
+	volatile int *lock;
+
+	for (i=0; i < VIA_NR_XVMC_LOCKS; ++i) {
+	        lock = (int *) XVMCLOCKPTR(dev_priv->sarea_priv, i);
+		if ( (_DRM_LOCKING_CONTEXT( *lock ) == context)) {
+			if (_DRM_LOCK_IS_HELD( *lock ) && (*lock & _DRM_LOCK_CONT)) {
+				DRM_WAKEUP( &(dev_priv->decoder_queue[i]));
+			}
+			*lock = 0;
+		}
+	}	
+}	
+
+int 
+via_decoder_futex(DRM_IOCTL_ARGS)
+{
+	DRM_DEVICE;
+	drm_via_futex_t fx;
+	volatile int *lock;
+	drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
+	drm_via_sarea_t *sAPriv = dev_priv->sarea_priv;
+	int ret = 0;
+
+	DRM_DEBUG("%s\n", __FUNCTION__);
+
+	DRM_COPY_FROM_USER_IOCTL(fx, (drm_via_futex_t __user *) data,
+				 sizeof(fx));
+
+	if (fx.lock > VIA_NR_XVMC_LOCKS)
+		return -EFAULT;
+
+	lock = (int *)XVMCLOCKPTR(sAPriv, fx.lock);
+
+	switch (fx.func) {
+	case VIA_FUTEX_WAIT:
+		DRM_WAIT_ON(ret, dev_priv->decoder_queue[fx.lock],
+			    (fx.ms / 10) * (DRM_HZ / 100), *lock != fx.val);
+		return ret;
+	case VIA_FUTEX_WAKE:
+		DRM_WAKEUP(&(dev_priv->decoder_queue[fx.lock]));
+		return 0;
+	}
+	return 0;
+}
+
diff --git a/drivers/char/ds1620.c b/drivers/char/ds1620.c
--- a/drivers/char/ds1620.c
+++ b/drivers/char/ds1620.c
@@ -163,8 +163,7 @@ static void ds1620_out(int cmd, int bits
 	netwinder_ds1620_reset();
 	netwinder_unlock(&flags);
 
-	set_current_state(TASK_INTERRUPTIBLE);
-	schedule_timeout(2);
+	msleep(20);
 }
 
 static unsigned int ds1620_in(int cmd, int bits)
diff --git a/drivers/char/dsp56k.c b/drivers/char/dsp56k.c
--- a/drivers/char/dsp56k.c
+++ b/drivers/char/dsp56k.c
@@ -144,7 +144,7 @@ static struct dsp56k_device {
 	int tx_wsize, rx_wsize;
 } dsp56k;
 
-static struct class_simple *dsp56k_class;
+static struct class *dsp56k_class;
 
 static int dsp56k_reset(void)
 {
@@ -510,12 +510,12 @@ static int __init dsp56k_init_driver(voi
 		printk("DSP56k driver: Unable to register driver\n");
 		return -ENODEV;
 	}
-	dsp56k_class = class_simple_create(THIS_MODULE, "dsp56k");
+	dsp56k_class = class_create(THIS_MODULE, "dsp56k");
 	if (IS_ERR(dsp56k_class)) {
 		err = PTR_ERR(dsp56k_class);
 		goto out_chrdev;
 	}
-	class_simple_device_add(dsp56k_class, MKDEV(DSP56K_MAJOR, 0), NULL, "dsp56k");
+	class_device_create(dsp56k_class, MKDEV(DSP56K_MAJOR, 0), NULL, "dsp56k");
 
 	err = devfs_mk_cdev(MKDEV(DSP56K_MAJOR, 0),
 		      S_IFCHR | S_IRUSR | S_IWUSR, "dsp56k");
@@ -526,8 +526,8 @@ static int __init dsp56k_init_driver(voi
 	goto out;
 
 out_class:
-	class_simple_device_remove(MKDEV(DSP56K_MAJOR, 0));
-	class_simple_destroy(dsp56k_class);
+	class_device_destroy(dsp56k_class, MKDEV(DSP56K_MAJOR, 0));
+	class_destroy(dsp56k_class);
 out_chrdev:
 	unregister_chrdev(DSP56K_MAJOR, "dsp56k");
 out:
@@ -537,8 +537,8 @@ module_init(dsp56k_init_driver);
 
 static void __exit dsp56k_cleanup_driver(void)
 {
-	class_simple_device_remove(MKDEV(DSP56K_MAJOR, 0));
-	class_simple_destroy(dsp56k_class);
+	class_device_destroy(dsp56k_class, MKDEV(DSP56K_MAJOR, 0));
+	class_destroy(dsp56k_class);
 	unregister_chrdev(DSP56K_MAJOR, "dsp56k");
 	devfs_remove("dsp56k");
 }
diff --git a/drivers/char/ftape/compressor/zftape-compress.c b/drivers/char/ftape/compressor/zftape-compress.c
--- a/drivers/char/ftape/compressor/zftape-compress.c
+++ b/drivers/char/ftape/compressor/zftape-compress.c
@@ -1176,8 +1176,8 @@ KERN_INFO "Compressor for zftape (lzrw3 
         }
 #else /* !MODULE */
 	/* print a short no-nonsense boot message */
-	printk("zftape compressor v1.00a 970514\n");
-	printk("For use with " FTAPE_VERSION "\n");
+	printk(KERN_INFO "zftape compressor v1.00a 970514\n");
+	printk(KERN_INFO "For use with " FTAPE_VERSION "\n");
 #endif /* MODULE */
 	TRACE(ft_t_info, "zft_compressor_init @ 0x%p", zft_compressor_init);
 	TRACE(ft_t_info, "installing compressor for zftape ...");
diff --git a/drivers/char/ftape/zftape/zftape-init.c b/drivers/char/ftape/zftape/zftape-init.c
--- a/drivers/char/ftape/zftape/zftape-init.c
+++ b/drivers/char/ftape/zftape/zftape-init.c
@@ -99,7 +99,7 @@ static struct file_operations zft_cdev =
 	.release	= zft_close,
 };
 
-static struct class_simple *zft_class;
+static struct class *zft_class;
 
 /*      Open floppy tape device
  */
@@ -329,29 +329,29 @@ KERN_INFO
 	      "installing zftape VFS interface for ftape driver ...");
 	TRACE_CATCH(register_chrdev(QIC117_TAPE_MAJOR, "zft", &zft_cdev),);
 
-	zft_class = class_simple_create(THIS_MODULE, "zft");
+	zft_class = class_create(THIS_MODULE, "zft");
 	for (i = 0; i < 4; i++) {
-		class_simple_device_add(zft_class, MKDEV(QIC117_TAPE_MAJOR, i), NULL, "qft%i", i);
+		class_device_create(zft_class, MKDEV(QIC117_TAPE_MAJOR, i), NULL, "qft%i", i);
 		devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i),
 				S_IFCHR | S_IRUSR | S_IWUSR,
 				"qft%i", i);
-		class_simple_device_add(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 4), NULL, "nqft%i", i);
+		class_device_create(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 4), NULL, "nqft%i", i);
 		devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i + 4),
 				S_IFCHR | S_IRUSR | S_IWUSR,
 				"nqft%i", i);
-		class_simple_device_add(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 16), NULL, "zqft%i", i);
+		class_device_create(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 16), NULL, "zqft%i", i);
 		devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i + 16),
 				S_IFCHR | S_IRUSR | S_IWUSR,
 				"zqft%i", i);
-		class_simple_device_add(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 20), NULL, "nzqft%i", i);
+		class_device_create(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 20), NULL, "nzqft%i", i);
 		devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i + 20),
 				S_IFCHR | S_IRUSR | S_IWUSR,
 				"nzqft%i", i);
-		class_simple_device_add(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 32), NULL, "rawqft%i", i);
+		class_device_create(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 32), NULL, "rawqft%i", i);
 		devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i + 32),
 				S_IFCHR | S_IRUSR | S_IWUSR,
 				"rawqft%i", i);
-		class_simple_device_add(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 36), NULL, "nrawrawqft%i", i);
+		class_device_create(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 36), NULL, "nrawrawqft%i", i);
 		devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i + 36),
 				S_IFCHR | S_IRUSR | S_IWUSR,
 				"nrawqft%i", i);
@@ -381,19 +381,19 @@ static void zft_exit(void)
 	}
         for (i = 0; i < 4; i++) {
 		devfs_remove("qft%i", i);
-		class_simple_device_remove(MKDEV(QIC117_TAPE_MAJOR, i));
+		class_device_destroy(zft_class, MKDEV(QIC117_TAPE_MAJOR, i));
 		devfs_remove("nqft%i", i);
-		class_simple_device_remove(MKDEV(QIC117_TAPE_MAJOR, i + 4));
+		class_device_destroy(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 4));
 		devfs_remove("zqft%i", i);
-		class_simple_device_remove(MKDEV(QIC117_TAPE_MAJOR, i + 16));
+		class_device_destroy(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 16));
 		devfs_remove("nzqft%i", i);
-		class_simple_device_remove(MKDEV(QIC117_TAPE_MAJOR, i + 20));
+		class_device_destroy(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 20));
 		devfs_remove("rawqft%i", i);
-		class_simple_device_remove(MKDEV(QIC117_TAPE_MAJOR, i + 32));
+		class_device_destroy(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 32));
 		devfs_remove("nrawqft%i", i);
-		class_simple_device_remove(MKDEV(QIC117_TAPE_MAJOR, i + 36));
+		class_device_destroy(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 36));
 	}
-	class_simple_destroy(zft_class);
+	class_destroy(zft_class);
 	zft_uninit_mem(); /* release remaining memory, if any */
         printk(KERN_INFO "zftape successfully unloaded.\n");
 	TRACE_EXIT;
diff --git a/drivers/char/hangcheck-timer.c b/drivers/char/hangcheck-timer.c
--- a/drivers/char/hangcheck-timer.c
+++ b/drivers/char/hangcheck-timer.c
@@ -173,7 +173,7 @@ static void hangcheck_fire(unsigned long
 		}
 		if (hangcheck_reboot) {
 			printk(KERN_CRIT "Hangcheck: hangcheck is restarting the machine.\n");
-			machine_restart(NULL);
+			emergency_restart();
 		} else {
 			printk(KERN_CRIT "Hangcheck: hangcheck value past margin!\n");
 		}
diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c
--- a/drivers/char/hpet.c
+++ b/drivers/char/hpet.c
@@ -834,7 +834,7 @@ int hpet_alloc(struct hpet_data *hdp)
 	printk("\n");
 
 	ns = hpetp->hp_period;	/* femptoseconds, 10^-15 */
-	do_div(ns, 1000000);	/* convert to nanoseconds, 10^-9 */
+	ns /= 1000000;		/* convert to nanoseconds, 10^-9 */
 	printk(KERN_INFO "hpet%d: %ldns tick, %d %d-bit timers\n",
 		hpetp->hp_which, ns, hpetp->hp_ntimer,
 		cap & HPET_COUNTER_SIZE_MASK ? 64 : 32);
diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c
--- a/drivers/char/hvc_console.c
+++ b/drivers/char/hvc_console.c
@@ -22,6 +22,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  */
 
+#include <linux/config.h>
 #include <linux/console.h>
 #include <linux/cpumask.h>
 #include <linux/init.h>
@@ -40,7 +41,6 @@
 #include <linux/delay.h>
 #include <asm/uaccess.h>
 #include <asm/hvconsole.h>
-#include <asm/vio.h>
 
 #define HVC_MAJOR	229
 #define HVC_MINOR	0
@@ -61,16 +61,21 @@
  */
 #define HVC_ALLOC_TTY_ADAPTERS	8
 
-static struct tty_driver *hvc_driver;
-#ifdef CONFIG_MAGIC_SYSRQ
-static int sysrq_pressed;
-#endif
-
 #define N_OUTBUF	16
 #define N_INBUF		16
 
 #define __ALIGNED__	__attribute__((__aligned__(8)))
 
+static struct tty_driver *hvc_driver;
+static struct task_struct *hvc_task;
+
+/* Picks up late kicks after list walk but before schedule() */
+static int hvc_kicked;
+
+#ifdef CONFIG_MAGIC_SYSRQ
+static int sysrq_pressed;
+#endif
+
 struct hvc_struct {
 	spinlock_t lock;
 	int index;
@@ -80,11 +85,11 @@ struct hvc_struct {
 	char outbuf[N_OUTBUF] __ALIGNED__;
 	int n_outbuf;
 	uint32_t vtermno;
+	struct hv_ops *ops;
 	int irq_requested;
 	int irq;
 	struct list_head next;
 	struct kobject kobj; /* ref count & hvc_struct lifetime */
-	struct vio_dev *vdev;
 };
 
 /* dynamic list of hvc_struct instances */
@@ -97,26 +102,185 @@ static struct list_head hvc_structs = LI
 static DEFINE_SPINLOCK(hvc_structs_lock);
 
 /*
+ * This value is used to assign a tty->index value to a hvc_struct based
+ * upon order of exposure via hvc_probe(), when we can not match it to
+ * a console canidate registered with hvc_instantiate().
+ */
+static int last_hvc = -1;
+
+/*
+ * Do not call this function with either the hvc_strucst_lock or the hvc_struct
+ * lock held.  If successful, this function increments the kobject reference
+ * count against the target hvc_struct so it should be released when finished.
+ */
+struct hvc_struct *hvc_get_by_index(int index)
+{
+	struct hvc_struct *hp;
+	unsigned long flags;
+
+	spin_lock(&hvc_structs_lock);
+
+	list_for_each_entry(hp, &hvc_structs, next) {
+		spin_lock_irqsave(&hp->lock, flags);
+		if (hp->index == index) {
+			kobject_get(&hp->kobj);
+			spin_unlock_irqrestore(&hp->lock, flags);
+			spin_unlock(&hvc_structs_lock);
+			return hp;
+		}
+		spin_unlock_irqrestore(&hp->lock, flags);
+	}
+	hp = NULL;
+
+	spin_unlock(&hvc_structs_lock);
+	return hp;
+}
+
+
+/*
  * Initial console vtermnos for console API usage prior to full console
  * initialization.  Any vty adapter outside this range will not have usable
  * console interfaces but can still be used as a tty device.  This has to be
  * static because kmalloc will not work during early console init.
  */
-static uint32_t vtermnos[MAX_NR_HVC_CONSOLES];
+static struct hv_ops *cons_ops[MAX_NR_HVC_CONSOLES];
+static uint32_t vtermnos[MAX_NR_HVC_CONSOLES] =
+	{[0 ... MAX_NR_HVC_CONSOLES - 1] = -1};
 
-/* Used for accounting purposes */
-static int num_vterms = 0;
+/*
+ * Console APIs, NOT TTY.  These APIs are available immediately when
+ * hvc_console_setup() finds adapters.
+ */
 
-static struct task_struct *hvc_task;
+void hvc_console_print(struct console *co, const char *b, unsigned count)
+{
+	char c[16] __ALIGNED__;
+	unsigned i = 0, n = 0;
+	int r, donecr = 0, index = co->index;
+
+	/* Console access attempt outside of acceptable console range. */
+	if (index >= MAX_NR_HVC_CONSOLES)
+		return;
+
+	/* This console adapter was removed so it is not useable. */
+	if (vtermnos[index] < 0)
+		return;
+
+	while (count > 0 || i > 0) {
+		if (count > 0 && i < sizeof(c)) {
+			if (b[n] == '\n' && !donecr) {
+				c[i++] = '\r';
+				donecr = 1;
+			} else {
+				c[i++] = b[n++];
+				donecr = 0;
+				--count;
+			}
+		} else {
+			r = cons_ops[index]->put_chars(vtermnos[index], c, i);
+			if (r < 0) {
+				/* throw away chars on error */
+				i = 0;
+			} else if (r > 0) {
+				i -= r;
+				if (i > 0)
+					memmove(c, c+r, i);
+			}
+		}
+	}
+}
+
+static struct tty_driver *hvc_console_device(struct console *c, int *index)
+{
+	if (vtermnos[c->index] == -1)
+		return NULL;
+
+	*index = c->index;
+	return hvc_driver;
+}
+
+static int __init hvc_console_setup(struct console *co, char *options)
+{
+	if (co->index < 0 || co->index >= MAX_NR_HVC_CONSOLES)
+		return -ENODEV;
+
+	if (vtermnos[co->index] == -1)
+		return -ENODEV;
+
+	return 0;
+}
+
+struct console hvc_con_driver = {
+	.name		= "hvc",
+	.write		= hvc_console_print,
+	.device		= hvc_console_device,
+	.setup		= hvc_console_setup,
+	.flags		= CON_PRINTBUFFER,
+	.index		= -1,
+};
 
 /*
- * This value is used to associate a tty->index value to a hvc_struct based
- * upon order of exposure via hvc_probe().
+ * Early console initialization.  Preceeds driver initialization.
+ *
+ * (1) we are first, and the user specified another driver
+ * -- index will remain -1
+ * (2) we are first and the user specified no driver
+ * -- index will be set to 0, then we will fail setup.
+ * (3)  we are first and the user specified our driver
+ * -- index will be set to user specified driver, and we will fail
+ * (4) we are after driver, and this initcall will register us
+ * -- if the user didn't specify a driver then the console will match
+ *
+ * Note that for cases 2 and 3, we will match later when the io driver
+ * calls hvc_instantiate() and call register again.
  */
-static int hvc_count = -1;
+static int __init hvc_console_init(void)
+{
+	register_console(&hvc_con_driver);
+	return 0;
+}
+console_initcall(hvc_console_init);
 
-/* Picks up late kicks after list walk but before schedule() */
-static int hvc_kicked;
+/*
+ * hvc_instantiate() is an early console discovery method which locates
+ * consoles * prior to the vio subsystem discovering them.  Hotplugged
+ * vty adapters do NOT get an hvc_instantiate() callback since they
+ * appear after early console init.
+ */
+int hvc_instantiate(uint32_t vtermno, int index, struct hv_ops *ops)
+{
+	struct hvc_struct *hp;
+
+	if (index < 0 || index >= MAX_NR_HVC_CONSOLES)
+		return -1;
+
+	if (vtermnos[index] != -1)
+		return -1;
+
+	/* make sure no no tty has been registerd in this index */
+	hp = hvc_get_by_index(index);
+	if (hp) {
+		kobject_put(&hp->kobj);
+		return -1;
+	}
+
+	vtermnos[index] = vtermno;
+	cons_ops[index] = ops;
+
+	/* reserve all indices upto and including this index */
+	if (last_hvc < index)
+		last_hvc = index;
+
+	/* if this index is what the user requested, then register
+	 * now (setup won't fail at this point).  It's ok to just
+	 * call register again if previously .setup failed.
+	 */
+	if (index == hvc_con_driver.index)
+		register_console(&hvc_con_driver);
+
+	return 0;
+}
+EXPORT_SYMBOL(hvc_instantiate);
 
 /* Wake the sleeping khvcd */
 static void hvc_kick(void)
@@ -125,13 +289,17 @@ static void hvc_kick(void)
 	wake_up_process(hvc_task);
 }
 
+static int hvc_poll(struct hvc_struct *hp);
+
 /*
  * NOTE: This API isn't used if the console adapter doesn't support interrupts.
  * In this case the console is poll driven.
  */
 static irqreturn_t hvc_handle_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
 {
-	hvc_kick();
+	/* if hvc_poll request a repoll, then kick the hvcd thread */
+	if (hvc_poll(dev_instance))
+		hvc_kick();
 	return IRQ_HANDLED;
 }
 
@@ -141,34 +309,6 @@ static void hvc_unthrottle(struct tty_st
 }
 
 /*
- * Do not call this function with either the hvc_strucst_lock or the hvc_struct
- * lock held.  If successful, this function increments the kobject reference
- * count against the target hvc_struct so it should be released when finished.
- */
-struct hvc_struct *hvc_get_by_index(int index)
-{
-	struct hvc_struct *hp;
-	unsigned long flags;
-
-	spin_lock(&hvc_structs_lock);
-
-	list_for_each_entry(hp, &hvc_structs, next) {
-		spin_lock_irqsave(&hp->lock, flags);
-		if (hp->index == index) {
-			kobject_get(&hp->kobj);
-			spin_unlock_irqrestore(&hp->lock, flags);
-			spin_unlock(&hvc_structs_lock);
-			return hp;
-		}
-		spin_unlock_irqrestore(&hp->lock, flags);
-	}
-	hp = NULL;
-
-	spin_unlock(&hvc_structs_lock);
-	return hp;
-}
-
-/*
  * The TTY interface won't be used until after the vio layer has exposed the vty
  * adapter to the kernel.
  */
@@ -329,7 +469,7 @@ static void hvc_push(struct hvc_struct *
 {
 	int n;
 
-	n = hvc_put_chars(hp->vtermno, hp->outbuf, hp->n_outbuf);
+	n = hp->ops->put_chars(hp->vtermno, hp->outbuf, hp->n_outbuf);
 	if (n <= 0) {
 		if (n == 0)
 			return;
@@ -467,7 +607,7 @@ static int hvc_poll(struct hvc_struct *h
 			break;
 		}
 
-		n = hvc_get_chars(hp->vtermno, buf, count);
+		n = hp->ops->get_chars(hp->vtermno, buf, count);
 		if (n <= 0) {
 			/* Hangup the tty when disconnected from host */
 			if (n == -EPIPE) {
@@ -479,14 +619,17 @@ static int hvc_poll(struct hvc_struct *h
 		}
 		for (i = 0; i < n; ++i) {
 #ifdef CONFIG_MAGIC_SYSRQ
-			/* Handle the SysRq Hack */
-			if (buf[i] == '\x0f') {	/* ^O -- should support a sequence */
-				sysrq_pressed = 1;
-				continue;
-			} else if (sysrq_pressed) {
-				handle_sysrq(buf[i], NULL, tty);
-				sysrq_pressed = 0;
-				continue;
+			if (hp->index == hvc_con_driver.index) {
+				/* Handle the SysRq Hack */
+				/* XXX should support a sequence */
+				if (buf[i] == '\x0f') {	/* ^O */
+					sysrq_pressed = 1;
+					continue;
+				} else if (sysrq_pressed) {
+					handle_sysrq(buf[i], NULL, tty);
+					sysrq_pressed = 0;
+					continue;
+				}
 			}
 #endif /* CONFIG_MAGIC_SYSRQ */
 			tty_insert_flip_char(tty, buf[i], 0);
@@ -497,8 +640,8 @@ static int hvc_poll(struct hvc_struct *h
 
 		/*
 		 * Account for the total amount read in one loop, and if above
-		 * 64 bytes, we do a quick schedule loop to let the tty grok the
-		 * data and eventually throttle us.
+		 * 64 bytes, we do a quick schedule loop to let the tty grok
+		 * the data and eventually throttle us.
 		 */
 		read_total += n;
 		if (read_total >= 64) {
@@ -542,7 +685,6 @@ int khvcd(void *unused)
 		if (cpus_empty(cpus_in_xmon)) {
 			spin_lock(&hvc_structs_lock);
 			list_for_each_entry(hp, &hvc_structs, next) {
-				/*hp = list_entry(node, struct hvc_struct, * next); */
 				poll_mask |= hvc_poll(hp);
 			}
 			spin_unlock(&hvc_structs_lock);
@@ -577,14 +719,6 @@ static struct tty_operations hvc_ops = {
 	.chars_in_buffer = hvc_chars_in_buffer,
 };
 
-char hvc_driver_name[] = "hvc_console";
-
-static struct vio_device_id hvc_driver_table[] __devinitdata= {
-	{"serial", "hvterm1"},
-	{ NULL, }
-};
-MODULE_DEVICE_TABLE(vio, hvc_driver_table);
-
 /* callback when the kboject ref count reaches zero. */
 static void destroy_hvc_struct(struct kobject *kobj)
 {
@@ -606,41 +740,51 @@ static struct kobj_type hvc_kobj_type = 
 	.release = destroy_hvc_struct,
 };
 
-static int __devinit hvc_probe(
-		struct vio_dev *dev,
-		const struct vio_device_id *id)
+struct hvc_struct __devinit *hvc_alloc(uint32_t vtermno, int irq,
+					struct hv_ops *ops)
 {
 	struct hvc_struct *hp;
-
-	/* probed with invalid parameters. */
-	if (!dev || !id)
-		return -EPERM;
+	int i;
 
 	hp = kmalloc(sizeof(*hp), GFP_KERNEL);
 	if (!hp)
-		return -ENOMEM;
+		return ERR_PTR(-ENOMEM);
 
 	memset(hp, 0x00, sizeof(*hp));
-	hp->vtermno = dev->unit_address;
-	hp->vdev = dev;
-	hp->vdev->dev.driver_data = hp;
-	hp->irq = dev->irq;
+
+	hp->vtermno = vtermno;
+	hp->irq = irq;
+	hp->ops = ops;
 
 	kobject_init(&hp->kobj);
 	hp->kobj.ktype = &hvc_kobj_type;
 
 	spin_lock_init(&hp->lock);
 	spin_lock(&hvc_structs_lock);
-	hp->index = ++hvc_count;
+
+	/*
+	 * find index to use:
+	 * see if this vterm id matches one registered for console.
+	 */
+	for (i=0; i < MAX_NR_HVC_CONSOLES; i++)
+		if (vtermnos[i] == hp->vtermno)
+			break;
+
+	/* no matching slot, just use a counter */
+	if (i >= MAX_NR_HVC_CONSOLES)
+		i = ++last_hvc;
+
+	hp->index = i;
+
 	list_add_tail(&(hp->next), &hvc_structs);
 	spin_unlock(&hvc_structs_lock);
 
-	return 0;
+	return hp;
 }
+EXPORT_SYMBOL(hvc_alloc);
 
-static int __devexit hvc_remove(struct vio_dev *dev)
+int __devexit hvc_remove(struct hvc_struct *hp)
 {
-	struct hvc_struct *hp = dev->dev.driver_data;
 	unsigned long flags;
 	struct kobject *kobjp;
 	struct tty_struct *tty;
@@ -673,23 +817,14 @@ static int __devexit hvc_remove(struct v
 		tty_hangup(tty);
 	return 0;
 }
-
-static struct vio_driver hvc_vio_driver = {
-	.name		= hvc_driver_name,
-	.id_table	= hvc_driver_table,
-	.probe		= hvc_probe,
-	.remove		= hvc_remove,
-};
+EXPORT_SYMBOL(hvc_remove);
 
 /* Driver initialization.  Follow console initialization.  This is where the TTY
  * interfaces start to become available. */
 int __init hvc_init(void)
 {
-	int rc;
-
-	/* We need more than num_vterms adapters due to hotplug additions. */
+	/* We need more than hvc_count adapters due to hotplug additions. */
 	hvc_driver = alloc_tty_driver(HVC_ALLOC_TTY_ADAPTERS);
-	/* hvc_driver = alloc_tty_driver(num_vterms); */
 	if (!hvc_driver)
 		return -ENOMEM;
 
@@ -716,116 +851,20 @@ int __init hvc_init(void)
 		return -EIO;
 	}
 
-	/* Register as a vio device to receive callbacks */
-	rc = vio_register_driver(&hvc_vio_driver);
-
-	return rc;
+	return 0;
 }
+module_init(hvc_init);
 
-/* This isn't particularily necessary due to this being a console driver but it
- * is nice to be thorough */
+/* This isn't particularily necessary due to this being a console driver
+ * but it is nice to be thorough.
+ */
 static void __exit hvc_exit(void)
 {
 	kthread_stop(hvc_task);
 
-	vio_unregister_driver(&hvc_vio_driver);
 	tty_unregister_driver(hvc_driver);
 	/* return tty_struct instances allocated in hvc_init(). */
 	put_tty_driver(hvc_driver);
+	unregister_console(&hvc_con_driver);
 }
-
-/*
- * Console APIs, NOT TTY.  These APIs are available immediately when
- * hvc_console_setup() finds adapters.
- */
-
-/*
- * hvc_instantiate() is an early console discovery method which locates consoles
- * prior to the vio subsystem discovering them.  Hotplugged vty adapters do NOT
- * get an hvc_instantiate() callback since the appear after early console init.
- */
-int hvc_instantiate(uint32_t vtermno, int index)
-{
-	if (index < 0 || index >= MAX_NR_HVC_CONSOLES)
-		return -1;
-
-	if (vtermnos[index] != -1)
-		return -1;
-
-	vtermnos[index] = vtermno;
-	return 0;
-}
-
-void hvc_console_print(struct console *co, const char *b, unsigned count)
-{
-	char c[16] __ALIGNED__;
-	unsigned i = 0, n = 0;
-	int r, donecr = 0;
-
-	/* Console access attempt outside of acceptable console range. */
-	if (co->index >= MAX_NR_HVC_CONSOLES)
-		return;
-
-	/* This console adapter was removed so it is not useable. */
-	if (vtermnos[co->index] < 0)
-		return;
-
-	while (count > 0 || i > 0) {
-		if (count > 0 && i < sizeof(c)) {
-			if (b[n] == '\n' && !donecr) {
-				c[i++] = '\r';
-				donecr = 1;
-			} else {
-				c[i++] = b[n++];
-				donecr = 0;
-				--count;
-			}
-		} else {
-			r = hvc_put_chars(vtermnos[co->index], c, i);
-			if (r < 0) {
-				/* throw away chars on error */
-				i = 0;
-			} else if (r > 0) {
-				i -= r;
-				if (i > 0)
-					memmove(c, c+r, i);
-			}
-		}
-	}
-}
-
-static struct tty_driver *hvc_console_device(struct console *c, int *index)
-{
-	*index = c->index;
-	return hvc_driver;
-}
-
-static int __init hvc_console_setup(struct console *co, char *options)
-{
-	return 0;
-}
-
-struct console hvc_con_driver = {
-	.name		= "hvc",
-	.write		= hvc_console_print,
-	.device		= hvc_console_device,
-	.setup		= hvc_console_setup,
-	.flags		= CON_PRINTBUFFER,
-	.index		= -1,
-};
-
-/* Early console initialization.  Preceeds driver initialization. */
-static int __init hvc_console_init(void)
-{
-	int i;
-
-	for (i=0; i<MAX_NR_HVC_CONSOLES; i++)
-		vtermnos[i] = -1;
-	num_vterms = hvc_find_vtys();
-	register_console(&hvc_con_driver);
-	return 0;
-}
-console_initcall(hvc_console_init);
-
-module_init(hvc_init);
 module_exit(hvc_exit);
diff --git a/drivers/char/hvc_vio.c b/drivers/char/hvc_vio.c
new file mode 100644
--- /dev/null
+++ b/drivers/char/hvc_vio.c
@@ -0,0 +1,152 @@
+/*
+ * vio driver interface to hvc_console.c
+ *
+ * This code was moved here to allow the remaing code to be reused as a
+ * generic polling mode with semi-reliable transport driver core to the
+ * console and tty subsystems.
+ *
+ *
+ * Copyright (C) 2001 Anton Blanchard <anton@au.ibm.com>, IBM
+ * Copyright (C) 2001 Paul Mackerras <paulus@au.ibm.com>, IBM
+ * Copyright (C) 2004 Benjamin Herrenschmidt <benh@kernel.crashing.org>, IBM Corp.
+ * Copyright (C) 2004 IBM Corporation
+ *
+ * Additional Author(s):
+ *  Ryan S. Arnold <rsa@us.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <asm/hvconsole.h>
+#include <asm/vio.h>
+#include <asm/prom.h>
+
+char hvc_driver_name[] = "hvc_console";
+
+static struct vio_device_id hvc_driver_table[] __devinitdata = {
+	{"serial", "hvterm1"},
+	{ NULL, }
+};
+MODULE_DEVICE_TABLE(vio, hvc_driver_table);
+
+static int filtered_get_chars(uint32_t vtermno, char *buf, int count)
+{
+	unsigned long got;
+	int i;
+
+	got = hvc_get_chars(vtermno, buf, count);
+
+	/*
+	 * Work around a HV bug where it gives us a null
+	 * after every \r.  -- paulus
+	 */
+	for (i = 1; i < got; ++i) {
+		if (buf[i] == 0 && buf[i-1] == '\r') {
+			--got;
+			if (i < got)
+				memmove(&buf[i], &buf[i+1],
+					got - i);
+		}
+	}
+	return got;
+}
+
+static struct hv_ops hvc_get_put_ops = {
+	.get_chars = filtered_get_chars,
+	.put_chars = hvc_put_chars,
+};
+
+static int __devinit hvc_vio_probe(struct vio_dev *vdev,
+				const struct vio_device_id *id)
+{
+	struct hvc_struct *hp;
+
+	/* probed with invalid parameters. */
+	if (!vdev || !id)
+		return -EPERM;
+
+	hp = hvc_alloc(vdev->unit_address, vdev->irq, &hvc_get_put_ops);
+	if (IS_ERR(hp))
+		return PTR_ERR(hp);
+	dev_set_drvdata(&vdev->dev, hp);
+
+	return 0;
+}
+
+static int __devexit hvc_vio_remove(struct vio_dev *vdev)
+{
+	struct hvc_struct *hp = dev_get_drvdata(&vdev->dev);
+
+	return hvc_remove(hp);
+}
+
+static struct vio_driver hvc_vio_driver = {
+	.name		= hvc_driver_name,
+	.id_table	= hvc_driver_table,
+	.probe		= hvc_vio_probe,
+	.remove		= hvc_vio_remove,
+	.driver		= {
+		.owner	= THIS_MODULE,
+	}
+};
+
+static int hvc_vio_init(void)
+{
+	int rc;
+
+	/* Register as a vio device to receive callbacks */
+	rc = vio_register_driver(&hvc_vio_driver);
+
+	return rc;
+}
+module_init(hvc_vio_init); /* after drivers/char/hvc_console.c */
+
+static void hvc_vio_exit(void)
+{
+	vio_unregister_driver(&hvc_vio_driver);
+}
+module_exit(hvc_vio_exit);
+
+/* the device tree order defines our numbering */
+static int hvc_find_vtys(void)
+{
+	struct device_node *vty;
+	int num_found = 0;
+
+	for (vty = of_find_node_by_name(NULL, "vty"); vty != NULL;
+			vty = of_find_node_by_name(vty, "vty")) {
+		uint32_t *vtermno;
+
+		/* We have statically defined space for only a certain number
+		 * of console adapters.
+		 */
+		if (num_found >= MAX_NR_HVC_CONSOLES)
+			break;
+
+		vtermno = (uint32_t *)get_property(vty, "reg", NULL);
+		if (!vtermno)
+			continue;
+
+		if (device_is_compatible(vty, "hvterm1")) {
+			hvc_instantiate(*vtermno, num_found, &hvc_get_put_ops);
+			++num_found;
+		}
+	}
+
+	return num_found;
+}
+console_initcall(hvc_find_vtys);
diff --git a/drivers/char/hvcs.c b/drivers/char/hvcs.c
--- a/drivers/char/hvcs.c
+++ b/drivers/char/hvcs.c
@@ -1466,7 +1466,7 @@ static inline struct hvcs_struct *from_v
 }
 /* The sysfs interface for the driver and devices */
 
-static ssize_t hvcs_partner_vtys_show(struct device *dev, char *buf)
+static ssize_t hvcs_partner_vtys_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct vio_dev *viod = to_vio_dev(dev);
 	struct hvcs_struct *hvcsd = from_vio_dev(viod);
@@ -1480,7 +1480,7 @@ static ssize_t hvcs_partner_vtys_show(st
 }
 static DEVICE_ATTR(partner_vtys, S_IRUGO, hvcs_partner_vtys_show, NULL);
 
-static ssize_t hvcs_partner_clcs_show(struct device *dev, char *buf)
+static ssize_t hvcs_partner_clcs_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct vio_dev *viod = to_vio_dev(dev);
 	struct hvcs_struct *hvcsd = from_vio_dev(viod);
@@ -1494,7 +1494,7 @@ static ssize_t hvcs_partner_clcs_show(st
 }
 static DEVICE_ATTR(partner_clcs, S_IRUGO, hvcs_partner_clcs_show, NULL);
 
-static ssize_t hvcs_current_vty_store(struct device *dev, const char * buf,
+static ssize_t hvcs_current_vty_store(struct device *dev, struct device_attribute *attr, const char * buf,
 		size_t count)
 {
 	/*
@@ -1505,7 +1505,7 @@ static ssize_t hvcs_current_vty_store(st
 	return -EPERM;
 }
 
-static ssize_t hvcs_current_vty_show(struct device *dev, char *buf)
+static ssize_t hvcs_current_vty_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct vio_dev *viod = to_vio_dev(dev);
 	struct hvcs_struct *hvcsd = from_vio_dev(viod);
@@ -1521,7 +1521,7 @@ static ssize_t hvcs_current_vty_show(str
 static DEVICE_ATTR(current_vty,
 	S_IRUGO | S_IWUSR, hvcs_current_vty_show, hvcs_current_vty_store);
 
-static ssize_t hvcs_vterm_state_store(struct device *dev, const char *buf,
+static ssize_t hvcs_vterm_state_store(struct device *dev, struct device_attribute *attr, const char *buf,
 		size_t count)
 {
 	struct vio_dev *viod = to_vio_dev(dev);
@@ -1559,7 +1559,7 @@ static ssize_t hvcs_vterm_state_store(st
 	return count;
 }
 
-static ssize_t hvcs_vterm_state_show(struct device *dev, char *buf)
+static ssize_t hvcs_vterm_state_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct vio_dev *viod = to_vio_dev(dev);
 	struct hvcs_struct *hvcsd = from_vio_dev(viod);
@@ -1574,7 +1574,7 @@ static ssize_t hvcs_vterm_state_show(str
 static DEVICE_ATTR(vterm_state, S_IRUGO | S_IWUSR,
 		hvcs_vterm_state_show, hvcs_vterm_state_store);
 
-static ssize_t hvcs_index_show(struct device *dev, char *buf)
+static ssize_t hvcs_index_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct vio_dev *viod = to_vio_dev(dev);
 	struct hvcs_struct *hvcsd = from_vio_dev(viod);
diff --git a/drivers/char/hvsi.c b/drivers/char/hvsi.c
--- a/drivers/char/hvsi.c
+++ b/drivers/char/hvsi.c
@@ -291,15 +291,13 @@ static void dump_packet(uint8_t *packet)
 	dump_hex(packet, header->len);
 }
 
-/* can't use hvc_get_chars because that strips CRs */
 static int hvsi_read(struct hvsi_struct *hp, char *buf, int count)
 {
 	unsigned long got;
 
-	if (plpar_hcall(H_GET_TERM_CHAR, hp->vtermno, 0, 0, 0, &got,
-			(unsigned long *)buf, (unsigned long *)buf+1) == H_Success)
-		return got;
-	return 0;
+	got = hvc_get_chars(hp->vtermno, buf, count);
+
+	return got;
 }
 
 static void hvsi_recv_control(struct hvsi_struct *hp, uint8_t *packet,
diff --git a/drivers/char/hw_random.c b/drivers/char/hw_random.c
--- a/drivers/char/hw_random.c
+++ b/drivers/char/hw_random.c
@@ -579,7 +579,7 @@ static int __init rng_init (void)
 
 	/* Probe for Intel, AMD RNGs */
 	for_each_pci_dev(pdev) {
-		ent = pci_match_device (rng_pci_tbl, pdev);
+		ent = pci_match_id(rng_pci_tbl, pdev);
 		if (ent) {
 			rng_ops = &rng_vendor_ops[ent->driver_data];
 			goto match;
diff --git a/drivers/char/i8k.c b/drivers/char/i8k.c
--- a/drivers/char/i8k.c
+++ b/drivers/char/i8k.c
@@ -20,13 +20,14 @@
 #include <linux/types.h>
 #include <linux/init.h>
 #include <linux/proc_fs.h>
-#include <linux/apm_bios.h>
+#include <linux/seq_file.h>
+#include <linux/dmi.h>
 #include <asm/uaccess.h>
 #include <asm/io.h>
 
 #include <linux/i8k.h>
 
-#define I8K_VERSION		"1.13 14/05/2002"
+#define I8K_VERSION		"1.14 21/02/2005"
 
 #define I8K_SMM_FN_STATUS	0x0025
 #define I8K_SMM_POWER_STATUS	0x0069
@@ -34,7 +35,8 @@
 #define I8K_SMM_GET_FAN		0x00a3
 #define I8K_SMM_GET_SPEED	0x02a3
 #define I8K_SMM_GET_TEMP	0x10a3
-#define I8K_SMM_GET_DELL_SIG	0xffa3
+#define I8K_SMM_GET_DELL_SIG1	0xfea3
+#define I8K_SMM_GET_DELL_SIG2	0xffa3
 #define I8K_SMM_BIOS_VERSION	0x00a6
 
 #define I8K_FAN_MULT		30
@@ -52,18 +54,7 @@
 
 #define I8K_TEMPERATURE_BUG	1
 
-#define DELL_SIGNATURE		"Dell Computer"
-
-static char *supported_models[] = {
-    "Inspiron",
-    "Latitude",
-    NULL
-};
-
-static char system_vendor[48] = "?";
-static char product_name [48] = "?";
-static char bios_version [4]  = "?";
-static char serial_number[16] = "?";
+static char bios_version[4];
 
 MODULE_AUTHOR("Massimo Dal Zotto (dz@debian.org)");
 MODULE_DESCRIPTION("Driver for accessing SMM BIOS on Dell laptops");
@@ -73,6 +64,10 @@ static int force;
 module_param(force, bool, 0);
 MODULE_PARM_DESC(force, "Force loading without checking for supported models");
 
+static int ignore_dmi;
+module_param(ignore_dmi, bool, 0);
+MODULE_PARM_DESC(ignore_dmi, "Continue probing hardware even if DMI data does not match");
+
 static int restricted;
 module_param(restricted, bool, 0);
 MODULE_PARM_DESC(restricted, "Allow fan control if SYS_ADMIN capability set");
@@ -81,69 +76,69 @@ static int power_status;
 module_param(power_status, bool, 0600);
 MODULE_PARM_DESC(power_status, "Report power status in /proc/i8k");
 
-static ssize_t i8k_read(struct file *, char __user *, size_t, loff_t *);
+static int i8k_open_fs(struct inode *inode, struct file *file);
 static int i8k_ioctl(struct inode *, struct file *, unsigned int,
 		     unsigned long);
 
 static struct file_operations i8k_fops = {
-    .read	= i8k_read,
-    .ioctl	= i8k_ioctl,
+	.open		= i8k_open_fs,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+	.ioctl		= i8k_ioctl,
 };
 
-typedef struct {
-    unsigned int eax;
-    unsigned int ebx __attribute__ ((packed));
-    unsigned int ecx __attribute__ ((packed));
-    unsigned int edx __attribute__ ((packed));
-    unsigned int esi __attribute__ ((packed));
-    unsigned int edi __attribute__ ((packed));
-} SMMRegisters;
-
-typedef struct {
-    u8	type;
-    u8	length;
-    u16	handle;
-} DMIHeader;
+struct smm_regs {
+	unsigned int eax;
+	unsigned int ebx __attribute__ ((packed));
+	unsigned int ecx __attribute__ ((packed));
+	unsigned int edx __attribute__ ((packed));
+	unsigned int esi __attribute__ ((packed));
+	unsigned int edi __attribute__ ((packed));
+};
+
+static inline char *i8k_get_dmi_data(int field)
+{
+	return dmi_get_system_info(field) ? : "N/A";
+}
 
 /*
  * Call the System Management Mode BIOS. Code provided by Jonathan Buzzard.
  */
-static int i8k_smm(SMMRegisters *regs)
+static int i8k_smm(struct smm_regs *regs)
 {
-    int rc;
-    int eax = regs->eax;
+	int rc;
+	int eax = regs->eax;
+
+	asm("pushl %%eax\n\t"
+	    "movl 0(%%eax),%%edx\n\t"
+	    "push %%edx\n\t"
+	    "movl 4(%%eax),%%ebx\n\t"
+	    "movl 8(%%eax),%%ecx\n\t"
+	    "movl 12(%%eax),%%edx\n\t"
+	    "movl 16(%%eax),%%esi\n\t"
+	    "movl 20(%%eax),%%edi\n\t"
+	    "popl %%eax\n\t"
+	    "out %%al,$0xb2\n\t"
+	    "out %%al,$0x84\n\t"
+	    "xchgl %%eax,(%%esp)\n\t"
+	    "movl %%ebx,4(%%eax)\n\t"
+	    "movl %%ecx,8(%%eax)\n\t"
+	    "movl %%edx,12(%%eax)\n\t"
+	    "movl %%esi,16(%%eax)\n\t"
+	    "movl %%edi,20(%%eax)\n\t"
+	    "popl %%edx\n\t"
+	    "movl %%edx,0(%%eax)\n\t"
+	    "lahf\n\t"
+	    "shrl $8,%%eax\n\t"
+	    "andl $1,%%eax\n":"=a"(rc)
+	    :    "a"(regs)
+	    :    "%ebx", "%ecx", "%edx", "%esi", "%edi", "memory");
 
-    asm("pushl %%eax\n\t" \
-	"movl 0(%%eax),%%edx\n\t" \
-	"push %%edx\n\t" \
-	"movl 4(%%eax),%%ebx\n\t" \
-	"movl 8(%%eax),%%ecx\n\t" \
-	"movl 12(%%eax),%%edx\n\t" \
-	"movl 16(%%eax),%%esi\n\t" \
-	"movl 20(%%eax),%%edi\n\t" \
-	"popl %%eax\n\t" \
-	"out %%al,$0xb2\n\t" \
-	"out %%al,$0x84\n\t" \
-	"xchgl %%eax,(%%esp)\n\t"
-	"movl %%ebx,4(%%eax)\n\t" \
-	"movl %%ecx,8(%%eax)\n\t" \
-	"movl %%edx,12(%%eax)\n\t" \
-	"movl %%esi,16(%%eax)\n\t" \
-	"movl %%edi,20(%%eax)\n\t" \
-	"popl %%edx\n\t" \
-	"movl %%edx,0(%%eax)\n\t" \
-	"lahf\n\t" \
-	"shrl $8,%%eax\n\t" \
-	"andl $1,%%eax\n" \
-	: "=a" (rc)
-	: "a" (regs)
-	: "%ebx", "%ecx", "%edx", "%esi", "%edi", "memory");
-
-    if ((rc != 0) || ((regs->eax & 0xffff) == 0xffff) || (regs->eax == eax)) {
-	return -EINVAL;
-    }
+	if (rc != 0 || (regs->eax & 0xffff) == 0xffff || regs->eax == eax)
+		return -EINVAL;
 
-    return 0;
+	return 0;
 }
 
 /*
@@ -152,24 +147,9 @@ static int i8k_smm(SMMRegisters *regs)
  */
 static int i8k_get_bios_version(void)
 {
-    SMMRegisters regs = { 0, 0, 0, 0, 0, 0 };
-    int rc;
-
-    regs.eax = I8K_SMM_BIOS_VERSION;
-    if ((rc=i8k_smm(&regs)) < 0) {
-	return rc;
-    }
+	struct smm_regs regs = { .eax = I8K_SMM_BIOS_VERSION, };
 
-    return regs.eax;
-}
-
-/*
- * Read the machine id.
- */
-static int i8k_get_serial_number(unsigned char *buff)
-{
-    strlcpy(buff, serial_number, sizeof(serial_number));
-    return 0;
+	return i8k_smm(&regs) ? : regs.eax;
 }
 
 /*
@@ -177,24 +157,22 @@ static int i8k_get_serial_number(unsigne
  */
 static int i8k_get_fn_status(void)
 {
-    SMMRegisters regs = { 0, 0, 0, 0, 0, 0 };
-    int rc;
+	struct smm_regs regs = { .eax = I8K_SMM_FN_STATUS, };
+	int rc;
 
-    regs.eax = I8K_SMM_FN_STATUS;
-    if ((rc=i8k_smm(&regs)) < 0) {
-	return rc;
-    }
-
-    switch ((regs.eax >> I8K_FN_SHIFT) & I8K_FN_MASK) {
-    case I8K_FN_UP:
-	return I8K_VOL_UP;
-    case I8K_FN_DOWN:
-	return I8K_VOL_DOWN;
-    case I8K_FN_MUTE:
-	return I8K_VOL_MUTE;
-    default:
-	return 0;
-    }
+	if ((rc = i8k_smm(&regs)) < 0)
+		return rc;
+
+	switch ((regs.eax >> I8K_FN_SHIFT) & I8K_FN_MASK) {
+	case I8K_FN_UP:
+		return I8K_VOL_UP;
+	case I8K_FN_DOWN:
+		return I8K_VOL_DOWN;
+	case I8K_FN_MUTE:
+		return I8K_VOL_MUTE;
+	default:
+		return 0;
+	}
 }
 
 /*
@@ -202,20 +180,13 @@ static int i8k_get_fn_status(void)
  */
 static int i8k_get_power_status(void)
 {
-    SMMRegisters regs = { 0, 0, 0, 0, 0, 0 };
-    int rc;
+	struct smm_regs regs = { .eax = I8K_SMM_POWER_STATUS, };
+	int rc;
+
+	if ((rc = i8k_smm(&regs)) < 0)
+		return rc;
 
-    regs.eax = I8K_SMM_POWER_STATUS;
-    if ((rc=i8k_smm(&regs)) < 0) {
-	return rc;
-    }
-
-    switch (regs.eax & 0xff) {
-    case I8K_POWER_AC:
-	return I8K_AC;
-    default:
-	return I8K_BATTERY;
-    }
+	return (regs.eax & 0xff) == I8K_POWER_AC ? I8K_AC : I8K_BATTERY;
 }
 
 /*
@@ -223,16 +194,10 @@ static int i8k_get_power_status(void)
  */
 static int i8k_get_fan_status(int fan)
 {
-    SMMRegisters regs = { 0, 0, 0, 0, 0, 0 };
-    int rc;
+	struct smm_regs regs = { .eax = I8K_SMM_GET_FAN, };
 
-    regs.eax = I8K_SMM_GET_FAN;
-    regs.ebx = fan & 0xff;
-    if ((rc=i8k_smm(&regs)) < 0) {
-	return rc;
-    }
-
-    return (regs.eax & 0xff);
+	regs.ebx = fan & 0xff;
+	return i8k_smm(&regs) ? : regs.eax & 0xff;
 }
 
 /*
@@ -240,16 +205,10 @@ static int i8k_get_fan_status(int fan)
  */
 static int i8k_get_fan_speed(int fan)
 {
-    SMMRegisters regs = { 0, 0, 0, 0, 0, 0 };
-    int rc;
-
-    regs.eax = I8K_SMM_GET_SPEED;
-    regs.ebx = fan & 0xff;
-    if ((rc=i8k_smm(&regs)) < 0) {
-	return rc;
-    }
+	struct smm_regs regs = { .eax = I8K_SMM_GET_SPEED, };
 
-    return (regs.eax & 0xffff) * I8K_FAN_MULT;
+	regs.ebx = fan & 0xff;
+	return i8k_smm(&regs) ? : (regs.eax & 0xffff) * I8K_FAN_MULT;
 }
 
 /*
@@ -257,532 +216,318 @@ static int i8k_get_fan_speed(int fan)
  */
 static int i8k_set_fan(int fan, int speed)
 {
-    SMMRegisters regs = { 0, 0, 0, 0, 0, 0 };
-    int rc;
+	struct smm_regs regs = { .eax = I8K_SMM_SET_FAN, };
 
-    speed = (speed < 0) ? 0 : ((speed > I8K_FAN_MAX) ? I8K_FAN_MAX : speed);
+	speed = (speed < 0) ? 0 : ((speed > I8K_FAN_MAX) ? I8K_FAN_MAX : speed);
+	regs.ebx = (fan & 0xff) | (speed << 8);
 
-    regs.eax = I8K_SMM_SET_FAN;
-    regs.ebx = (fan & 0xff) | (speed << 8);
-    if ((rc=i8k_smm(&regs)) < 0) {
-	return rc;
-    }
-
-    return (i8k_get_fan_status(fan));
+	return i8k_smm(&regs) ? : i8k_get_fan_status(fan);
 }
 
 /*
  * Read the cpu temperature.
  */
-static int i8k_get_cpu_temp(void)
+static int i8k_get_temp(int sensor)
 {
-    SMMRegisters regs = { 0, 0, 0, 0, 0, 0 };
-    int rc;
-    int temp;
+	struct smm_regs regs = { .eax = I8K_SMM_GET_TEMP, };
+	int rc;
+	int temp;
 
 #ifdef I8K_TEMPERATURE_BUG
-    static int prev = 0;
+	static int prev;
 #endif
+	regs.ebx = sensor & 0xff;
+	if ((rc = i8k_smm(&regs)) < 0)
+		return rc;
 
-    regs.eax = I8K_SMM_GET_TEMP;
-    if ((rc=i8k_smm(&regs)) < 0) {
-	return rc;
-    }
-    temp = regs.eax & 0xff;
+	temp = regs.eax & 0xff;
 
 #ifdef I8K_TEMPERATURE_BUG
-    /*
-     * Sometimes the temperature sensor returns 0x99, which is out of range.
-     * In this case we return (once) the previous cached value. For example:
-     # 1003655137 00000058 00005a4b
-     # 1003655138 00000099 00003a80 <--- 0x99 = 153 degrees
-     # 1003655139 00000054 00005c52
-     */
-    if (temp > I8K_MAX_TEMP) {
-	temp = prev;
-	prev = I8K_MAX_TEMP;
-    } else {
-	prev = temp;
-    }
+	/*
+	 * Sometimes the temperature sensor returns 0x99, which is out of range.
+	 * In this case we return (once) the previous cached value. For example:
+	 # 1003655137 00000058 00005a4b
+	 # 1003655138 00000099 00003a80 <--- 0x99 = 153 degrees
+	 # 1003655139 00000054 00005c52
+	 */
+	if (temp > I8K_MAX_TEMP) {
+		temp = prev;
+		prev = I8K_MAX_TEMP;
+	} else {
+		prev = temp;
+	}
 #endif
 
-    return temp;
+	return temp;
 }
 
-static int i8k_get_dell_signature(void)
+static int i8k_get_dell_signature(int req_fn)
 {
-    SMMRegisters regs = { 0, 0, 0, 0, 0, 0 };
-    int rc;
+	struct smm_regs regs = { .eax = req_fn, };
+	int rc;
 
-    regs.eax = I8K_SMM_GET_DELL_SIG;
-    if ((rc=i8k_smm(&regs)) < 0) {
-	return rc;
-    }
+	if ((rc = i8k_smm(&regs)) < 0)
+		return rc;
 
-    if ((regs.eax == 1145651527) && (regs.edx == 1145392204)) {
-	return 0;
-    } else {
-	return -1;
-    }
+	return regs.eax == 1145651527 && regs.edx == 1145392204 ? 0 : -1;
 }
 
 static int i8k_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
 		     unsigned long arg)
 {
-    int val;
-    int speed;
-    unsigned char buff[16];
-    int __user *argp = (int __user *)arg;
-
-    if (!argp)
-	return -EINVAL;
-
-    switch (cmd) {
-    case I8K_BIOS_VERSION:
-	val = i8k_get_bios_version();
-	break;
-
-    case I8K_MACHINE_ID:
-	memset(buff, 0, 16);
-	val = i8k_get_serial_number(buff);
-	break;
-
-    case I8K_FN_STATUS:
-	val = i8k_get_fn_status();
-	break;
-
-    case I8K_POWER_STATUS:
-	val = i8k_get_power_status();
-	break;
-
-    case I8K_GET_TEMP:
-	val = i8k_get_cpu_temp();
-	break;
-
-    case I8K_GET_SPEED:
-	if (copy_from_user(&val, argp, sizeof(int))) {
-	    return -EFAULT;
-	}
-	val = i8k_get_fan_speed(val);
-	break;
+	int val = 0;
+	int speed;
+	unsigned char buff[16];
+	int __user *argp = (int __user *)arg;
 
-    case I8K_GET_FAN:
-	if (copy_from_user(&val, argp, sizeof(int))) {
-	    return -EFAULT;
-	}
-	val = i8k_get_fan_status(val);
-	break;
+	if (!argp)
+		return -EINVAL;
 
-    case I8K_SET_FAN:
-	if (restricted && !capable(CAP_SYS_ADMIN)) {
-	    return -EPERM;
-	}
-	if (copy_from_user(&val, argp, sizeof(int))) {
-	    return -EFAULT;
-	}
-	if (copy_from_user(&speed, argp+1, sizeof(int))) {
-	    return -EFAULT;
-	}
-	val = i8k_set_fan(val, speed);
-	break;
+	switch (cmd) {
+	case I8K_BIOS_VERSION:
+		val = i8k_get_bios_version();
+		break;
 
-    default:
-	return -EINVAL;
-    }
-
-    if (val < 0) {
-	return val;
-    }
-
-    switch (cmd) {
-    case I8K_BIOS_VERSION:
-	if (copy_to_user(argp, &val, 4)) {
-	    return -EFAULT;
-	}
-	break;
-    case I8K_MACHINE_ID:
-	if (copy_to_user(argp, buff, 16)) {
-	    return -EFAULT;
-	}
-	break;
-    default:
-	if (copy_to_user(argp, &val, sizeof(int))) {
-	    return -EFAULT;
-	}
-	break;
-    }
+	case I8K_MACHINE_ID:
+		memset(buff, 0, 16);
+		strlcpy(buff, i8k_get_dmi_data(DMI_PRODUCT_SERIAL), sizeof(buff));
+		break;
 
-    return 0;
-}
+	case I8K_FN_STATUS:
+		val = i8k_get_fn_status();
+		break;
 
-/*
- * Print the information for /proc/i8k.
- */
-static int i8k_get_info(char *buffer, char **start, off_t fpos, int length)
-{
-    int n, fn_key, cpu_temp, ac_power;
-    int left_fan, right_fan, left_speed, right_speed;
+	case I8K_POWER_STATUS:
+		val = i8k_get_power_status();
+		break;
 
-    cpu_temp     = i8k_get_cpu_temp();			/* 11100 µs */
-    left_fan     = i8k_get_fan_status(I8K_FAN_LEFT);	/*   580 µs */
-    right_fan    = i8k_get_fan_status(I8K_FAN_RIGHT);	/*   580 µs */
-    left_speed   = i8k_get_fan_speed(I8K_FAN_LEFT);	/*   580 µs */
-    right_speed  = i8k_get_fan_speed(I8K_FAN_RIGHT);	/*   580 µs */
-    fn_key       = i8k_get_fn_status();			/*   750 µs */
-    if (power_status) {
-	ac_power = i8k_get_power_status();		/* 14700 µs */
-    } else {
-	ac_power = -1;
-    }
-
-    /*
-     * Info:
-     *
-     * 1)  Format version (this will change if format changes)
-     * 2)  BIOS version
-     * 3)  BIOS machine ID
-     * 4)  Cpu temperature
-     * 5)  Left fan status
-     * 6)  Right fan status
-     * 7)  Left fan speed
-     * 8)  Right fan speed
-     * 9)  AC power
-     * 10) Fn Key status
-     */
-    n = sprintf(buffer, "%s %s %s %d %d %d %d %d %d %d\n",
-		I8K_PROC_FMT,
-		bios_version,
-		serial_number,
-		cpu_temp,
-		left_fan,
-		right_fan,
-		left_speed,
-		right_speed,
-		ac_power,
-		fn_key);
-
-    return n;
-}
-
-static ssize_t i8k_read(struct file *f, char __user *buffer, size_t len, loff_t *fpos)
-{
-    int n;
-    char info[128];
-
-    n = i8k_get_info(info, NULL, 0, 128);
-    if (n <= 0) {
-	return n;
-    }
+	case I8K_GET_TEMP:
+		val = i8k_get_temp(0);
+		break;
 
-    if (*fpos >= n) {
-	return 0;
-    }
+	case I8K_GET_SPEED:
+		if (copy_from_user(&val, argp, sizeof(int)))
+			return -EFAULT;
 
-    if ((*fpos + len) >= n) {
-	len = n - *fpos;
-    }
+		val = i8k_get_fan_speed(val);
+		break;
 
-    if (copy_to_user(buffer, info, len) != 0) {
-	return -EFAULT;
-    }
+	case I8K_GET_FAN:
+		if (copy_from_user(&val, argp, sizeof(int)))
+			return -EFAULT;
 
-    *fpos += len;
-    return len;
-}
+		val = i8k_get_fan_status(val);
+		break;
 
-static char* __init string_trim(char *s, int size)
-{
-    int len;
-    char *p;
+	case I8K_SET_FAN:
+		if (restricted && !capable(CAP_SYS_ADMIN))
+			return -EPERM;
 
-    if ((len = strlen(s)) > size) {
-	len = size;
-    }
+		if (copy_from_user(&val, argp, sizeof(int)))
+			return -EFAULT;
 
-    for (p=s+len-1; len && (*p==' '); len--,p--) {
-	*p = '\0';
-    }
+		if (copy_from_user(&speed, argp + 1, sizeof(int)))
+			return -EFAULT;
 
-    return s;
-}
+		val = i8k_set_fan(val, speed);
+		break;
 
-/* DMI code, stolen from arch/i386/kernel/dmi_scan.c */
+	default:
+		return -EINVAL;
+	}
 
-/*
- * |<-- dmi->length -->|
- * |                   |
- * |dmi header    s=N  | string1,\0, ..., stringN,\0, ..., \0
- *                |                       |
- *                +-----------------------+
- */
-static char* __init dmi_string(DMIHeader *dmi, u8 s)
-{
-    u8 *p;
+	if (val < 0)
+		return val;
 
-    if (!s) {
-	return "";
-    }
-    s--;
+	switch (cmd) {
+	case I8K_BIOS_VERSION:
+		if (copy_to_user(argp, &val, 4))
+			return -EFAULT;
 
-    p = (u8 *)dmi + dmi->length;
-    while (s > 0) {
-	p += strlen(p);
-	p++;
-	s--;
-    }
+		break;
+	case I8K_MACHINE_ID:
+		if (copy_to_user(argp, buff, 16))
+			return -EFAULT;
 
-    return p;
-}
+		break;
+	default:
+		if (copy_to_user(argp, &val, sizeof(int)))
+			return -EFAULT;
 
-static void __init dmi_decode(DMIHeader *dmi)
-{
-    u8 *data = (u8 *) dmi;
-    char *p;
-
-#ifdef I8K_DEBUG
-    int i;
-    printk("%08x ", (int)data);
-    for (i=0; i<data[1] && i<64; i++) {
-	printk("%02x ", data[i]);
-    }
-    printk("\n");
-#endif
-
-    switch (dmi->type) {
-    case  0:	/* BIOS Information */
-	p = dmi_string(dmi,data[5]);
-	if (*p) {
-	    strlcpy(bios_version, p, sizeof(bios_version));
-	    string_trim(bios_version, sizeof(bios_version));
-	}
-	break;	
-    case 1:	/* System Information */
-	p = dmi_string(dmi,data[4]);
-	if (*p) {
-	    strlcpy(system_vendor, p, sizeof(system_vendor));
-	    string_trim(system_vendor, sizeof(system_vendor));
-	}
-	p = dmi_string(dmi,data[5]);
-	if (*p) {
-	    strlcpy(product_name, p, sizeof(product_name));
-	    string_trim(product_name, sizeof(product_name));
+		break;
 	}
-	p = dmi_string(dmi,data[7]);
-	if (*p) {
-	    strlcpy(serial_number, p, sizeof(serial_number));
-	    string_trim(serial_number, sizeof(serial_number));
-	}
-	break;
-    }
-}
 
-static int __init dmi_table(u32 base, int len, int num, void (*fn)(DMIHeader*))
-{
-    u8 *buf;
-    u8 *data;
-    DMIHeader *dmi;
-    int i = 1;
-
-    buf = ioremap(base, len);
-    if (buf == NULL) {
-	return -1;
-    }
-    data = buf;
-
-    /*
-     * Stop when we see al the items the table claimed to have
-     * or we run off the end of the table (also happens)
-     */
-    while ((i<num) && ((data-buf) < len)) {
-	dmi = (DMIHeader *)data;
-	/*
-	 * Avoid misparsing crud if the length of the last
-	 * record is crap
-	 */
-	if ((data-buf+dmi->length) >= len) {
-	    break;
-	}
-	fn(dmi);
-	data += dmi->length;
-	/*
-	 * Don't go off the end of the data if there is
-	 * stuff looking like string fill past the end
-	 */
-	while (((data-buf) < len) && (*data || data[1])) {
-	    data++;
-	}
-	data += 2;
-	i++;
-    }
-    iounmap(buf);
-
-    return 0;
-}
-
-static int __init dmi_iterate(void (*decode)(DMIHeader *))
-{
-	unsigned char buf[20];
-	void __iomem *p = ioremap(0xe0000, 0x20000), *q;
-
-	if (!p)
-		return -1;
-
-	for (q = p; q < p + 0x20000; q += 16) {
-		memcpy_fromio(buf, q, 20);
-		if (memcmp(buf, "_DMI_", 5)==0) {
-			u16 num  = buf[13]<<8  | buf[12];
-			u16 len  = buf [7]<<8  | buf [6];
-			u32 base = buf[11]<<24 | buf[10]<<16 | buf[9]<<8 | buf[8];
-#ifdef I8K_DEBUG
-			printk(KERN_INFO "DMI %d.%d present.\n",
-			   buf[14]>>4, buf[14]&0x0F);
-			printk(KERN_INFO "%d structures occupying %d bytes.\n",
-			   buf[13]<<8 | buf[12],
-			   buf [7]<<8 | buf[6]);
-			printk(KERN_INFO "DMI table at 0x%08X.\n",
-			   buf[11]<<24 | buf[10]<<16 | buf[9]<<8 | buf[8]);
-#endif
-			if (dmi_table(base, len, num, decode)==0) {
-				iounmap(p);
-				return 0;
-			}
-		}
-	}
-	iounmap(p);
-	return -1;
+	return 0;
 }
-/* end of DMI code */
 
 /*
- * Get DMI information.
+ * Print the information for /proc/i8k.
  */
-static int __init i8k_dmi_probe(void)
+static int i8k_proc_show(struct seq_file *seq, void *offset)
 {
-    char **p;
+	int fn_key, cpu_temp, ac_power;
+	int left_fan, right_fan, left_speed, right_speed;
 
-    if (dmi_iterate(dmi_decode) != 0) {
-	printk(KERN_INFO "i8k: unable to get DMI information\n");
-	return -ENODEV;
-    }
-
-    if (strncmp(system_vendor,DELL_SIGNATURE,strlen(DELL_SIGNATURE)) != 0) {
-	printk(KERN_INFO "i8k: not running on a Dell system\n");
-	return -ENODEV;
-    }
-
-    for (p=supported_models; ; p++) {
-	if (!*p) {
-	    printk(KERN_INFO "i8k: unsupported model: %s\n", product_name);
-	    return -ENODEV;
-	}
-	if (strncmp(product_name,*p,strlen(*p)) == 0) {
-	    break;
-	}
-    }
+	cpu_temp	= i8k_get_temp(0);			/* 11100 µs */
+	left_fan	= i8k_get_fan_status(I8K_FAN_LEFT);	/*   580 µs */
+	right_fan	= i8k_get_fan_status(I8K_FAN_RIGHT);	/*   580 µs */
+	left_speed	= i8k_get_fan_speed(I8K_FAN_LEFT);	/*   580 µs */
+	right_speed	= i8k_get_fan_speed(I8K_FAN_RIGHT);	/*   580 µs */
+	fn_key		= i8k_get_fn_status();			/*   750 µs */
+	if (power_status)
+		ac_power = i8k_get_power_status();		/* 14700 µs */
+	else
+		ac_power = -1;
 
-    return 0;
-}
+	/*
+	 * Info:
+	 *
+	 * 1)  Format version (this will change if format changes)
+	 * 2)  BIOS version
+	 * 3)  BIOS machine ID
+	 * 4)  Cpu temperature
+	 * 5)  Left fan status
+	 * 6)  Right fan status
+	 * 7)  Left fan speed
+	 * 8)  Right fan speed
+	 * 9)  AC power
+	 * 10) Fn Key status
+	 */
+	return seq_printf(seq, "%s %s %s %d %d %d %d %d %d %d\n",
+			  I8K_PROC_FMT,
+			  bios_version,
+			  dmi_get_system_info(DMI_PRODUCT_SERIAL) ? : "N/A",
+			  cpu_temp,
+			  left_fan, right_fan, left_speed, right_speed,
+			  ac_power, fn_key);
+}
+
+static int i8k_open_fs(struct inode *inode, struct file *file)
+{
+	return single_open(file, i8k_proc_show, NULL);
+}
+
+static struct dmi_system_id __initdata i8k_dmi_table[] = {
+	{
+		.ident = "Dell Inspiron",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron"),
+		},
+	},
+	{
+		.ident = "Dell Latitude",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Latitude"),
+		},
+	},
+	{
+		.ident = "Dell Inspiron 2",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron"),
+		},
+	},
+	{
+		.ident = "Dell Latitude 2",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Latitude"),
+		},
+	},
+	{ }
+};
 
 /*
  * Probe for the presence of a supported laptop.
  */
 static int __init i8k_probe(void)
 {
-    char buff[4];
-    int version;
-    int smm_found = 0;
-
-    /*
-     * Get DMI information
-     */
-    if (i8k_dmi_probe() != 0) {
-	printk(KERN_INFO "i8k: vendor=%s, model=%s, version=%s\n",
-	       system_vendor, product_name, bios_version);
-    }
-
-    /*
-     * Get SMM Dell signature
-     */
-    if (i8k_get_dell_signature() != 0) {
-	printk(KERN_INFO "i8k: unable to get SMM Dell signature\n");
-    } else {
-	smm_found = 1;
-    }
-
-    /*
-     * Get SMM BIOS version.
-     */
-    version = i8k_get_bios_version();
-    if (version <= 0) {
-	printk(KERN_INFO "i8k: unable to get SMM BIOS version\n");
-    } else {
-	smm_found = 1;
-	buff[0] = (version >> 16) & 0xff;
-	buff[1] = (version >>  8) & 0xff;
-	buff[2] = (version)       & 0xff;
-	buff[3] = '\0';
+	char buff[4];
+	int version;
+
 	/*
-	 * If DMI BIOS version is unknown use SMM BIOS version.
+	 * Get DMI information
 	 */
-	if (bios_version[0] == '?') {
-	    strcpy(bios_version, buff);
+	if (!dmi_check_system(i8k_dmi_table)) {
+		if (!ignore_dmi && !force)
+			return -ENODEV;
+
+		printk(KERN_INFO "i8k: not running on a supported Dell system.\n");
+		printk(KERN_INFO "i8k: vendor=%s, model=%s, version=%s\n",
+			i8k_get_dmi_data(DMI_SYS_VENDOR),
+			i8k_get_dmi_data(DMI_PRODUCT_NAME),
+			i8k_get_dmi_data(DMI_BIOS_VERSION));
 	}
+
+	strlcpy(bios_version, i8k_get_dmi_data(DMI_BIOS_VERSION), sizeof(bios_version));
+
 	/*
-	 * Check if the two versions match.
+	 * Get SMM Dell signature
 	 */
-	if (strncmp(buff,bios_version,sizeof(bios_version)) != 0) {
-	    printk(KERN_INFO "i8k: BIOS version mismatch: %s != %s\n",
-		   buff, bios_version);
+	if (i8k_get_dell_signature(I8K_SMM_GET_DELL_SIG1) &&
+	    i8k_get_dell_signature(I8K_SMM_GET_DELL_SIG2)) {
+		printk(KERN_ERR "i8k: unable to get SMM Dell signature\n");
+		if (!force)
+			return -ENODEV;
 	}
-    }
 
-    if (!smm_found && !force) {
-	return -ENODEV;
-    }
+	/*
+	 * Get SMM BIOS version.
+	 */
+	version = i8k_get_bios_version();
+	if (version <= 0) {
+		printk(KERN_WARNING "i8k: unable to get SMM BIOS version\n");
+	} else {
+		buff[0] = (version >> 16) & 0xff;
+		buff[1] = (version >> 8) & 0xff;
+		buff[2] = (version) & 0xff;
+		buff[3] = '\0';
+		/*
+		 * If DMI BIOS version is unknown use SMM BIOS version.
+		 */
+		if (!dmi_get_system_info(DMI_BIOS_VERSION))
+			strlcpy(bios_version, buff, sizeof(bios_version));
+
+		/*
+		 * Check if the two versions match.
+		 */
+		if (strncmp(buff, bios_version, sizeof(bios_version)) != 0)
+			printk(KERN_WARNING "i8k: BIOS version mismatch: %s != %s\n",
+				buff, bios_version);
+	}
 
-    return 0;
+	return 0;
 }
 
-#ifdef MODULE
-static
-#endif
-int __init i8k_init(void)
+static int __init i8k_init(void)
 {
-    struct proc_dir_entry *proc_i8k;
+	struct proc_dir_entry *proc_i8k;
 
-    /* Are we running on an supported laptop? */
-    if (i8k_probe() != 0) {
-	return -ENODEV;
-    }
+	/* Are we running on an supported laptop? */
+	if (i8k_probe())
+		return -ENODEV;
 
-    /* Register the proc entry */
-    proc_i8k = create_proc_info_entry("i8k", 0, NULL, i8k_get_info);
-    if (!proc_i8k) {
-	return -ENOENT;
-    }
-    proc_i8k->proc_fops = &i8k_fops;
-    proc_i8k->owner = THIS_MODULE;
+	/* Register the proc entry */
+	proc_i8k = create_proc_entry("i8k", 0, NULL);
+	if (!proc_i8k)
+		return -ENOENT;
 
-    printk(KERN_INFO
-	   "Dell laptop SMM driver v%s Massimo Dal Zotto (dz@debian.org)\n",
-	   I8K_VERSION);
+	proc_i8k->proc_fops = &i8k_fops;
+	proc_i8k->owner = THIS_MODULE;
 
-    return 0;
-}
+	printk(KERN_INFO
+	       "Dell laptop SMM driver v%s Massimo Dal Zotto (dz@debian.org)\n",
+	       I8K_VERSION);
 
-#ifdef MODULE
-int init_module(void)
-{
-    return i8k_init();
+	return 0;
 }
 
-void cleanup_module(void)
+static void __exit i8k_exit(void)
 {
-    /* Remove the proc entry */
-    remove_proc_entry("i8k", NULL);
-
-    printk(KERN_INFO "i8k: module unloaded\n");
+	remove_proc_entry("i8k", NULL);
 }
-#endif
 
-/* end of file */
+module_init(i8k_init);
+module_exit(i8k_exit);
diff --git a/drivers/char/ip2/i2cmd.c b/drivers/char/ip2/i2cmd.c
--- a/drivers/char/ip2/i2cmd.c
+++ b/drivers/char/ip2/i2cmd.c
@@ -97,7 +97,7 @@ static UCHAR ct41[] = { 1, BYP,     0x29
 //static UCHAR ct44[]={ 2, BTH,     0x2C,0                   }; // MS PING
 //static UCHAR ct45[]={ 1, BTH,     0x2D                     }; // HOTENAB
 //static UCHAR ct46[]={ 1, BTH,     0x2E                     }; // HOTDSAB
-static UCHAR ct47[] = { 7, BTH,     0x2F,0,0,0,0,0,0         }; // UNIX FLAGS
+//static UCHAR ct47[]={ 7, BTH,     0x2F,0,0,0,0,0,0         }; // UNIX FLAGS
 //static UCHAR ct48[]={ 1, BTH,     0x30                     }; // DSRFLOWENAB
 //static UCHAR ct49[]={ 1, BTH,     0x31                     }; // DSRFLOWDSAB
 //static UCHAR ct50[]={ 1, BTH,     0x32                     }; // DTRFLOWENAB
@@ -162,6 +162,7 @@ static UCHAR ct89[]={ 1, BYP,     0x59  
 // This routine sets the parameters of command 47 and returns a pointer to the
 // appropriate structure.
 //******************************************************************************
+#if 0
 cmdSyntaxPtr
 i2cmdUnixFlags(unsigned short iflag,unsigned short cflag,unsigned short lflag)
 {
@@ -175,6 +176,7 @@ i2cmdUnixFlags(unsigned short iflag,unsi
 	pCM->cmd[6] = (unsigned char) (lflag >> 8);
 	return pCM;
 }
+#endif  /*  0  */
 
 //******************************************************************************
 // Function:   i2cmdBaudDef(which, rate)
@@ -187,7 +189,7 @@ i2cmdUnixFlags(unsigned short iflag,unsi
 // This routine sets the parameters of commands 54 or 55 (according to the
 // argument which), and returns a pointer to the appropriate structure.
 //******************************************************************************
-cmdSyntaxPtr
+static cmdSyntaxPtr
 i2cmdBaudDef(int which, unsigned short rate)
 {
 	cmdSyntaxPtr pCM;
diff --git a/drivers/char/ip2/i2cmd.h b/drivers/char/ip2/i2cmd.h
--- a/drivers/char/ip2/i2cmd.h
+++ b/drivers/char/ip2/i2cmd.h
@@ -64,16 +64,6 @@ typedef struct _cmdSyntax
 						// directly from user-level
 #define VAR 0x10        // This command is of variable length!
 
-//-----------------------------------
-// External declarations for i2cmd.c
-//-----------------------------------
-// Routine to set up parameters for the "define hot-key sequence" command. Since
-// there is more than one parameter to assign, we must use a function rather
-// than a macro (used usually).
-//
-extern cmdSyntaxPtr i2cmdUnixFlags(USHORT iflag,USHORT cflag,USHORT lflag);
-extern cmdSyntaxPtr i2cmdBaudDef(int which, USHORT rate);
-
 // Declarations for the global arrays used to bear the commands and their
 // arguments.
 //
@@ -433,6 +423,7 @@ static UCHAR cc02[];
 #define CMD_HOT_ENAB (cmdSyntaxPtr)(ct45) // Enable Hot-key checking
 #define CMD_HOT_DSAB (cmdSyntaxPtr)(ct46) // Disable Hot-key checking
 
+#if 0
 // COMMAND 47: Send Protocol info via Unix flags:
 // iflag = Unix tty t_iflag
 // cflag = Unix tty t_cflag
@@ -441,6 +432,7 @@ static UCHAR cc02[];
 // within these flags
 //
 #define CMD_UNIX_FLAGS(iflag,cflag,lflag) i2cmdUnixFlags(iflag,cflag,lflag)
+#endif  /*  0  */
 
 #define CMD_DSRFL_ENAB  (cmdSyntaxPtr)(ct48) // Enable  DSR receiver ctrl
 #define CMD_DSRFL_DSAB  (cmdSyntaxPtr)(ct49) // Disable DSR receiver ctrl
diff --git a/drivers/char/ip2main.c b/drivers/char/ip2main.c
--- a/drivers/char/ip2main.c
+++ b/drivers/char/ip2main.c
@@ -302,7 +302,7 @@ static char rirqs[IP2_MAX_BOARDS];
 static int Valid_Irqs[] = { 3, 4, 5, 7, 10, 11, 12, 15, 0};
 
 /* for sysfs class support */
-static struct class_simple *ip2_class;
+static struct class *ip2_class;
 
 // Some functions to keep track of what irq's we have
 
@@ -414,9 +414,9 @@ cleanup_module(void)
 			iiResetDelay( i2BoardPtrTable[i] );
 			/* free io addresses and Tibet */
 			release_region( ip2config.addr[i], 8 );
-			class_simple_device_remove(MKDEV(IP2_IPL_MAJOR, 4 * i)); 
+			class_device_destroy(ip2_class, MKDEV(IP2_IPL_MAJOR, 4 * i));
 			devfs_remove("ip2/ipl%d", i);
-			class_simple_device_remove(MKDEV(IP2_IPL_MAJOR, 4 * i + 1));
+			class_device_destroy(ip2_class, MKDEV(IP2_IPL_MAJOR, 4 * i + 1));
 			devfs_remove("ip2/stat%d", i);
 		}
 		/* Disable and remove interrupt handler. */
@@ -425,7 +425,7 @@ cleanup_module(void)
 			clear_requested_irq( ip2config.irq[i]);
 		}
 	}
-	class_simple_destroy(ip2_class);
+	class_destroy(ip2_class);
 	devfs_remove("ip2");
 	if ( ( err = tty_unregister_driver ( ip2_tty_driver ) ) ) {
 		printk(KERN_ERR "IP2: failed to unregister tty driver (%d)\n", err);
@@ -700,7 +700,7 @@ ip2_loadmain(int *iop, int *irqp, unsign
 		printk(KERN_ERR "IP2: failed to register IPL device (%d)\n", err );
 	} else {
 		/* create the sysfs class */
-		ip2_class = class_simple_create(THIS_MODULE, "ip2");
+		ip2_class = class_create(THIS_MODULE, "ip2");
 		if (IS_ERR(ip2_class)) {
 			err = PTR_ERR(ip2_class);
 			goto out_chrdev;	
@@ -722,25 +722,25 @@ ip2_loadmain(int *iop, int *irqp, unsign
 			}
 
 			if ( NULL != ( pB = i2BoardPtrTable[i] ) ) {
-				class_simple_device_add(ip2_class, MKDEV(IP2_IPL_MAJOR, 
+				class_device_create(ip2_class, MKDEV(IP2_IPL_MAJOR,
 						4 * i), NULL, "ipl%d", i);
 				err = devfs_mk_cdev(MKDEV(IP2_IPL_MAJOR, 4 * i),
 						S_IRUSR | S_IWUSR | S_IRGRP | S_IFCHR,
 						"ip2/ipl%d", i);
 				if (err) {
-					class_simple_device_remove(MKDEV(IP2_IPL_MAJOR, 
-						4 * i));
+					class_device_destroy(ip2_class,
+						MKDEV(IP2_IPL_MAJOR, 4 * i));
 					goto out_class;
 				}
 
-				class_simple_device_add(ip2_class, MKDEV(IP2_IPL_MAJOR, 
+				class_device_create(ip2_class, MKDEV(IP2_IPL_MAJOR,
 						4 * i + 1), NULL, "stat%d", i);
 				err = devfs_mk_cdev(MKDEV(IP2_IPL_MAJOR, 4 * i + 1),
 						S_IRUSR | S_IWUSR | S_IRGRP | S_IFCHR,
 						"ip2/stat%d", i);
 				if (err) {
-					class_simple_device_remove(MKDEV(IP2_IPL_MAJOR, 
-						4 * i + 1));
+					class_device_destroy(ip2_class,
+						MKDEV(IP2_IPL_MAJOR, 4 * i + 1));
 					goto out_class;
 				}
 
@@ -798,7 +798,7 @@ retry:
 	goto out;
 
 out_class:
-	class_simple_destroy(ip2_class);
+	class_destroy(ip2_class);
 out_chrdev:
 	unregister_chrdev(IP2_IPL_MAJOR, "ip2");
 out:
@@ -2691,16 +2691,6 @@ no_xon:
 		pCh->flags	|= ASYNC_CHECK_CD;
 	}
 
-#ifdef XXX
-do_flags_thing:	// This is a test, we don't do the flags thing
-	
-	if ( (cflag & CRTSCTS) ) {
-		cflag |= 014000000000;
-	}
-	i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, 
-				CMD_UNIX_FLAGS(iflag,cflag,lflag));
-#endif
-		
 service_it:
 	i2DrainOutput( pCh, 100 );		
 }
diff --git a/drivers/char/ipmi/ipmi_devintf.c b/drivers/char/ipmi/ipmi_devintf.c
--- a/drivers/char/ipmi/ipmi_devintf.c
+++ b/drivers/char/ipmi/ipmi_devintf.c
@@ -45,6 +45,7 @@
 #include <asm/semaphore.h>
 #include <linux/init.h>
 #include <linux/device.h>
+#include <linux/compat.h>
 
 #define IPMI_DEVINTF_VERSION "v33"
 
@@ -500,10 +501,205 @@ static int ipmi_ioctl(struct inode  *ino
 	return rv;
 }
 
+#ifdef CONFIG_COMPAT
+
+/*
+ * The following code contains code for supporting 32-bit compatible
+ * ioctls on 64-bit kernels.  This allows running 32-bit apps on the
+ * 64-bit kernel
+ */
+#define COMPAT_IPMICTL_SEND_COMMAND	\
+	_IOR(IPMI_IOC_MAGIC, 13, struct compat_ipmi_req)
+#define COMPAT_IPMICTL_SEND_COMMAND_SETTIME	\
+	_IOR(IPMI_IOC_MAGIC, 21, struct compat_ipmi_req_settime)
+#define COMPAT_IPMICTL_RECEIVE_MSG	\
+	_IOWR(IPMI_IOC_MAGIC, 12, struct compat_ipmi_recv)
+#define COMPAT_IPMICTL_RECEIVE_MSG_TRUNC	\
+	_IOWR(IPMI_IOC_MAGIC, 11, struct compat_ipmi_recv)
+
+struct compat_ipmi_msg {
+	u8		netfn;
+	u8		cmd;
+	u16		data_len;
+	compat_uptr_t	data;
+};
+
+struct compat_ipmi_req {
+	compat_uptr_t		addr;
+	compat_uint_t		addr_len;
+	compat_long_t		msgid;
+	struct compat_ipmi_msg	msg;
+};
+
+struct compat_ipmi_recv {
+	compat_int_t		recv_type;
+	compat_uptr_t		addr;
+	compat_uint_t		addr_len;
+	compat_long_t		msgid;
+	struct compat_ipmi_msg	msg;
+};
+
+struct compat_ipmi_req_settime {
+	struct compat_ipmi_req	req;
+	compat_int_t		retries;
+	compat_uint_t		retry_time_ms;
+};
+
+/*
+ * Define some helper functions for copying IPMI data
+ */
+static long get_compat_ipmi_msg(struct ipmi_msg *p64,
+				struct compat_ipmi_msg __user *p32)
+{
+	compat_uptr_t tmp;
+
+	if (!access_ok(VERIFY_READ, p32, sizeof(*p32)) ||
+			__get_user(p64->netfn, &p32->netfn) ||
+			__get_user(p64->cmd, &p32->cmd) ||
+			__get_user(p64->data_len, &p32->data_len) ||
+			__get_user(tmp, &p32->data))
+		return -EFAULT;
+	p64->data = compat_ptr(tmp);
+	return 0;
+}
+
+static long put_compat_ipmi_msg(struct ipmi_msg *p64,
+				struct compat_ipmi_msg __user *p32)
+{
+	if (!access_ok(VERIFY_WRITE, p32, sizeof(*p32)) ||
+			__put_user(p64->netfn, &p32->netfn) ||
+			__put_user(p64->cmd, &p32->cmd) ||
+			__put_user(p64->data_len, &p32->data_len))
+		return -EFAULT;
+	return 0;
+}
+
+static long get_compat_ipmi_req(struct ipmi_req *p64,
+				struct compat_ipmi_req __user *p32)
+{
+
+	compat_uptr_t	tmp;
+
+	if (!access_ok(VERIFY_READ, p32, sizeof(*p32)) ||
+			__get_user(tmp, &p32->addr) ||
+			__get_user(p64->addr_len, &p32->addr_len) ||
+			__get_user(p64->msgid, &p32->msgid) ||
+			get_compat_ipmi_msg(&p64->msg, &p32->msg))
+		return -EFAULT;
+	p64->addr = compat_ptr(tmp);
+	return 0;
+}
+
+static long get_compat_ipmi_req_settime(struct ipmi_req_settime *p64,
+		struct compat_ipmi_req_settime __user *p32)
+{
+	if (!access_ok(VERIFY_READ, p32, sizeof(*p32)) ||
+			get_compat_ipmi_req(&p64->req, &p32->req) ||
+			__get_user(p64->retries, &p32->retries) ||
+			__get_user(p64->retry_time_ms, &p32->retry_time_ms))
+		return -EFAULT;
+	return 0;
+}
+
+static long get_compat_ipmi_recv(struct ipmi_recv *p64,
+				 struct compat_ipmi_recv __user *p32)
+{
+	compat_uptr_t tmp;
+
+	if (!access_ok(VERIFY_READ, p32, sizeof(*p32)) ||
+			__get_user(p64->recv_type, &p32->recv_type) ||
+			__get_user(tmp, &p32->addr) ||
+			__get_user(p64->addr_len, &p32->addr_len) ||
+			__get_user(p64->msgid, &p32->msgid) ||
+			get_compat_ipmi_msg(&p64->msg, &p32->msg))
+		return -EFAULT;
+	p64->addr = compat_ptr(tmp);
+	return 0;
+}
+
+static long put_compat_ipmi_recv(struct ipmi_recv *p64,
+				 struct compat_ipmi_recv __user *p32)
+{
+	if (!access_ok(VERIFY_WRITE, p32, sizeof(*p32)) ||
+			__put_user(p64->recv_type, &p32->recv_type) ||
+			__put_user(p64->addr_len, &p32->addr_len) ||
+			__put_user(p64->msgid, &p32->msgid) ||
+			put_compat_ipmi_msg(&p64->msg, &p32->msg))
+		return -EFAULT;
+	return 0;
+}
+
+/*
+ * Handle compatibility ioctls
+ */
+static long compat_ipmi_ioctl(struct file *filep, unsigned int cmd,
+			      unsigned long arg)
+{
+	int rc;
+	struct ipmi_file_private *priv = filep->private_data;
+
+	switch(cmd) {
+	case COMPAT_IPMICTL_SEND_COMMAND:
+	{
+		struct ipmi_req	rp;
+
+		if (get_compat_ipmi_req(&rp, compat_ptr(arg)))
+			return -EFAULT;
+
+		return handle_send_req(priv->user, &rp,
+				priv->default_retries,
+				priv->default_retry_time_ms);
+	}
+	case COMPAT_IPMICTL_SEND_COMMAND_SETTIME:
+	{
+		struct ipmi_req_settime	sp;
+
+		if (get_compat_ipmi_req_settime(&sp, compat_ptr(arg)))
+			return -EFAULT;
+
+		return handle_send_req(priv->user, &sp.req,
+				sp.retries, sp.retry_time_ms);
+	}
+	case COMPAT_IPMICTL_RECEIVE_MSG:
+	case COMPAT_IPMICTL_RECEIVE_MSG_TRUNC:
+	{
+		struct ipmi_recv   *precv64, recv64;
+
+		if (get_compat_ipmi_recv(&recv64, compat_ptr(arg)))
+			return -EFAULT;
+
+		precv64 = compat_alloc_user_space(sizeof(recv64));
+		if (copy_to_user(precv64, &recv64, sizeof(recv64)))
+			return -EFAULT;
+
+		rc = ipmi_ioctl(filep->f_dentry->d_inode, filep,
+				((cmd == COMPAT_IPMICTL_RECEIVE_MSG)
+				 ? IPMICTL_RECEIVE_MSG
+				 : IPMICTL_RECEIVE_MSG_TRUNC),
+				(long) precv64);
+		if (rc != 0)
+			return rc;
+
+		if (copy_from_user(&recv64, precv64, sizeof(recv64)))
+			return -EFAULT;
+
+		if (put_compat_ipmi_recv(&recv64, compat_ptr(arg)))
+			return -EFAULT;
+
+		return rc;
+	}
+	default:
+		return ipmi_ioctl(filep->f_dentry->d_inode, filep, cmd, arg);
+	}
+}
+#endif
 
 static struct file_operations ipmi_fops = {
 	.owner		= THIS_MODULE,
 	.ioctl		= ipmi_ioctl,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl   = compat_ipmi_ioctl,
+#endif
 	.open		= ipmi_open,
 	.release	= ipmi_release,
 	.fasync		= ipmi_fasync,
@@ -520,7 +716,7 @@ MODULE_PARM_DESC(ipmi_major, "Sets the m
 		 " interface.  Other values will set the major device number"
 		 " to that value.");
 
-static struct class_simple *ipmi_class;
+static struct class *ipmi_class;
 
 static void ipmi_new_smi(int if_num)
 {
@@ -529,12 +725,12 @@ static void ipmi_new_smi(int if_num)
 	devfs_mk_cdev(dev, S_IFCHR | S_IRUSR | S_IWUSR,
 		      "ipmidev/%d", if_num);
 
-	class_simple_device_add(ipmi_class, dev, NULL, "ipmi%d", if_num);
+	class_device_create(ipmi_class, dev, NULL, "ipmi%d", if_num);
 }
 
 static void ipmi_smi_gone(int if_num)
 {
-	class_simple_device_remove(MKDEV(ipmi_major, if_num));
+	class_device_destroy(ipmi_class, MKDEV(ipmi_major, if_num));
 	devfs_remove("ipmidev/%d", if_num);
 }
 
@@ -555,7 +751,7 @@ static __init int init_ipmi_devintf(void
 	printk(KERN_INFO "ipmi device interface version "
 	       IPMI_DEVINTF_VERSION "\n");
 
-	ipmi_class = class_simple_create(THIS_MODULE, "ipmi");
+	ipmi_class = class_create(THIS_MODULE, "ipmi");
 	if (IS_ERR(ipmi_class)) {
 		printk(KERN_ERR "ipmi: can't register device class\n");
 		return PTR_ERR(ipmi_class);
@@ -563,7 +759,7 @@ static __init int init_ipmi_devintf(void
 
 	rv = register_chrdev(ipmi_major, DEVICE_NAME, &ipmi_fops);
 	if (rv < 0) {
-		class_simple_destroy(ipmi_class);
+		class_destroy(ipmi_class);
 		printk(KERN_ERR "ipmi: can't get major %d\n", ipmi_major);
 		return rv;
 	}
@@ -577,7 +773,7 @@ static __init int init_ipmi_devintf(void
 	rv = ipmi_smi_watcher_register(&smi_watcher);
 	if (rv) {
 		unregister_chrdev(ipmi_major, DEVICE_NAME);
-		class_simple_destroy(ipmi_class);
+		class_destroy(ipmi_class);
 		printk(KERN_WARNING "ipmi: can't register smi watcher\n");
 		return rv;
 	}
@@ -588,7 +784,7 @@ module_init(init_ipmi_devintf);
 
 static __exit void cleanup_ipmi(void)
 {
-	class_simple_destroy(ipmi_class);
+	class_destroy(ipmi_class);
 	ipmi_smi_watcher_unregister(&smi_watcher);
 	devfs_remove(DEVICE_NAME);
 	unregister_chrdev(ipmi_major, DEVICE_NAME);
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
--- a/drivers/char/ipmi/ipmi_msghandler.c
+++ b/drivers/char/ipmi/ipmi_msghandler.c
@@ -54,7 +54,9 @@ static int ipmi_init_msghandler(void);
 
 static int initialized = 0;
 
-static struct proc_dir_entry *proc_ipmi_root = NULL;
+#ifdef CONFIG_PROC_FS
+struct proc_dir_entry *proc_ipmi_root = NULL;
+#endif /* CONFIG_PROC_FS */
 
 #define MAX_EVENTS_IN_QUEUE	25
 
@@ -124,11 +126,13 @@ struct ipmi_channel
 	unsigned char protocol;
 };
 
+#ifdef CONFIG_PROC_FS
 struct ipmi_proc_entry
 {
 	char                   *name;
 	struct ipmi_proc_entry *next;
 };
+#endif
 
 #define IPMI_IPMB_NUM_SEQ	64
 #define IPMI_MAX_CHANNELS       8
@@ -156,10 +160,13 @@ struct ipmi_smi
 	struct ipmi_smi_handlers *handlers;
 	void                     *send_info;
 
+#ifdef CONFIG_PROC_FS
 	/* A list of proc entries for this interface.  This does not
 	   need a lock, only one thread creates it and only one thread
 	   destroys it. */
+	spinlock_t             proc_entry_lock;
 	struct ipmi_proc_entry *proc_entries;
+#endif
 
 	/* A table of sequence numbers for this interface.  We use the
            sequence numbers for IPMB messages that go out of the
@@ -641,7 +648,7 @@ int ipmi_create_user(unsigned int       
 		return -ENOMEM;
 
 	down_read(&interfaces_sem);
-	if ((if_num > MAX_IPMI_INTERFACES) || ipmi_interfaces[if_num] == NULL)
+	if ((if_num >= MAX_IPMI_INTERFACES) || ipmi_interfaces[if_num] == NULL)
 	{
 		rv = -EINVAL;
 		goto out_unlock;
@@ -1081,8 +1088,8 @@ static inline int i_ipmi_request(ipmi_us
 		long                  seqid;
 		int                   broadcast = 0;
 
-		if (addr->channel > IPMI_NUM_CHANNELS) {
-			spin_lock_irqsave(&intf->counter_lock, flags);
+		if (addr->channel >= IPMI_MAX_CHANNELS) {
+		        spin_lock_irqsave(&intf->counter_lock, flags);
 			intf->sent_invalid_commands++;
 			spin_unlock_irqrestore(&intf->counter_lock, flags);
 			rv = -EINVAL;
@@ -1470,8 +1477,9 @@ int ipmi_smi_add_proc_entry(ipmi_smi_t s
 			    read_proc_t *read_proc, write_proc_t *write_proc,
 			    void *data, struct module *owner)
 {
-	struct proc_dir_entry  *file;
 	int                    rv = 0;
+#ifdef CONFIG_PROC_FS
+	struct proc_dir_entry  *file;
 	struct ipmi_proc_entry *entry;
 
 	/* Create a list element. */
@@ -1497,10 +1505,13 @@ int ipmi_smi_add_proc_entry(ipmi_smi_t s
 		file->write_proc = write_proc;
 		file->owner = owner;
 
+		spin_lock(&smi->proc_entry_lock);
 		/* Stick it on the list. */
 		entry->next = smi->proc_entries;
 		smi->proc_entries = entry;
+		spin_unlock(&smi->proc_entry_lock);
 	}
+#endif /* CONFIG_PROC_FS */
 
 	return rv;
 }
@@ -1509,6 +1520,7 @@ static int add_proc_entries(ipmi_smi_t s
 {
 	int rv = 0;
 
+#ifdef CONFIG_PROC_FS
 	sprintf(smi->proc_dir_name, "%d", num);
 	smi->proc_dir = proc_mkdir(smi->proc_dir_name, proc_ipmi_root);
 	if (!smi->proc_dir)
@@ -1531,14 +1543,17 @@ static int add_proc_entries(ipmi_smi_t s
 		rv = ipmi_smi_add_proc_entry(smi, "version",
 					     version_file_read_proc, NULL,
 					     smi, THIS_MODULE);
+#endif /* CONFIG_PROC_FS */
 
 	return rv;
 }
 
 static void remove_proc_entries(ipmi_smi_t smi)
 {
+#ifdef CONFIG_PROC_FS
 	struct ipmi_proc_entry *entry;
 
+	spin_lock(&smi->proc_entry_lock);
 	while (smi->proc_entries) {
 		entry = smi->proc_entries;
 		smi->proc_entries = entry->next;
@@ -1547,7 +1562,9 @@ static void remove_proc_entries(ipmi_smi
 		kfree(entry->name);
 		kfree(entry);
 	}
+	spin_unlock(&smi->proc_entry_lock);
 	remove_proc_entry(smi->proc_dir_name, proc_ipmi_root);
+#endif /* CONFIG_PROC_FS */
 }
 
 static int
@@ -1694,6 +1711,9 @@ int ipmi_register_smi(struct ipmi_smi_ha
 				new_intf->seq_table[j].seqid = 0;
 			}
 			new_intf->curr_seq = 0;
+#ifdef CONFIG_PROC_FS
+			spin_lock_init(&(new_intf->proc_entry_lock));
+#endif
 			spin_lock_init(&(new_intf->waiting_msgs_lock));
 			INIT_LIST_HEAD(&(new_intf->waiting_msgs));
 			spin_lock_init(&(new_intf->events_lock));
@@ -2747,16 +2767,13 @@ static struct timer_list ipmi_timer;
    the queue and this silliness can go away. */
 #define IPMI_REQUEST_EV_TIME	(1000 / (IPMI_TIMEOUT_TIME))
 
-static volatile int stop_operation = 0;
-static volatile int timer_stopped = 0;
+static atomic_t stop_operation;
 static unsigned int ticks_to_req_ev = IPMI_REQUEST_EV_TIME;
 
 static void ipmi_timeout(unsigned long data)
 {
-	if (stop_operation) {
-		timer_stopped = 1;
+	if (atomic_read(&stop_operation))
 		return;
-	}
 
 	ticks_to_req_ev--;
 	if (ticks_to_req_ev == 0) {
@@ -2766,8 +2783,7 @@ static void ipmi_timeout(unsigned long d
 
 	ipmi_timeout_handler(IPMI_TIMEOUT_TIME);
 
-	ipmi_timer.expires += IPMI_TIMEOUT_JIFFIES;
-	add_timer(&ipmi_timer);
+	mod_timer(&ipmi_timer, jiffies + IPMI_TIMEOUT_JIFFIES);
 }
 
 
@@ -3089,6 +3105,7 @@ static int ipmi_init_msghandler(void)
 		ipmi_interfaces[i] = NULL;
 	}
 
+#ifdef CONFIG_PROC_FS
 	proc_ipmi_root = proc_mkdir("ipmi", NULL);
 	if (!proc_ipmi_root) {
 	    printk(KERN_ERR PFX "Unable to create IPMI proc dir");
@@ -3096,6 +3113,7 @@ static int ipmi_init_msghandler(void)
 	}
 
 	proc_ipmi_root->owner = THIS_MODULE;
+#endif /* CONFIG_PROC_FS */
 
 	init_timer(&ipmi_timer);
 	ipmi_timer.data = 0;
@@ -3130,13 +3148,12 @@ static __exit void cleanup_ipmi(void)
 
 	/* Tell the timer to stop, then wait for it to stop.  This avoids
 	   problems with race conditions removing the timer here. */
-	stop_operation = 1;
-	while (!timer_stopped) {
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(1);
-	}
+	atomic_inc(&stop_operation);
+	del_timer_sync(&ipmi_timer);
 
+#ifdef CONFIG_PROC_FS
 	remove_proc_entry(proc_ipmi_root->name, &proc_root);
+#endif /* CONFIG_PROC_FS */
 
 	initialized = 0;
 
@@ -3177,4 +3194,5 @@ EXPORT_SYMBOL(ipmi_get_my_address);
 EXPORT_SYMBOL(ipmi_set_my_LUN);
 EXPORT_SYMBOL(ipmi_get_my_LUN);
 EXPORT_SYMBOL(ipmi_smi_add_proc_entry);
+EXPORT_SYMBOL(proc_ipmi_root);
 EXPORT_SYMBOL(ipmi_user_set_run_to_completion);
diff --git a/drivers/char/ipmi/ipmi_poweroff.c b/drivers/char/ipmi/ipmi_poweroff.c
--- a/drivers/char/ipmi/ipmi_poweroff.c
+++ b/drivers/char/ipmi/ipmi_poweroff.c
@@ -31,10 +31,13 @@
  *  with this program; if not, write to the Free Software Foundation, Inc.,
  *  675 Mass Ave, Cambridge, MA 02139, USA.
  */
-#include <asm/semaphore.h>
-#include <linux/kdev_t.h>
+#include <linux/config.h>
 #include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/proc_fs.h>
 #include <linux/string.h>
+#include <linux/completion.h>
+#include <linux/kdev_t.h>
 #include <linux/ipmi.h>
 #include <linux/ipmi_smi.h>
 
@@ -44,6 +47,18 @@
 /* Where to we insert our poweroff function? */
 extern void (*pm_power_off)(void);
 
+/* Definitions for controlling power off (if the system supports it).  It
+ * conveniently matches the IPMI chassis control values. */
+#define IPMI_CHASSIS_POWER_DOWN		0	/* power down, the default. */
+#define IPMI_CHASSIS_POWER_CYCLE	0x02	/* power cycle */
+
+/* the IPMI data command */
+static int poweroff_control = IPMI_CHASSIS_POWER_DOWN;
+
+/* parameter definition to allow user to flag power cycle */
+module_param(poweroff_control, int, IPMI_CHASSIS_POWER_DOWN);
+MODULE_PARM_DESC(poweroff_control, " Set to 2 to enable power cycle instead of power down. Power cycle is contingent on hardware support, otherwise it defaults back to power down.");
+
 /* Stuff from the get device id command. */
 static unsigned int mfg_id;
 static unsigned int prod_id;
@@ -75,10 +90,10 @@ static struct ipmi_recv_msg halt_recv_ms
 
 static void receive_handler(struct ipmi_recv_msg *recv_msg, void *handler_data)
 {
-	struct semaphore *sem = recv_msg->user_msg_data;
+	struct completion *comp = recv_msg->user_msg_data;
 
-	if (sem)
-		up(sem);
+	if (comp)
+		complete(comp);
 }
 
 static struct ipmi_user_hndl ipmi_poweroff_handler =
@@ -91,27 +106,27 @@ static int ipmi_request_wait_for_respons
 					  struct ipmi_addr       *addr,
 					  struct kernel_ipmi_msg *send_msg)
 {
-	int              rv;
-	struct semaphore sem;
+	int               rv;
+	struct completion comp;
 
-	sema_init (&sem, 0);
+	init_completion(&comp);
 
-	rv = ipmi_request_supply_msgs(user, addr, 0, send_msg, &sem,
+	rv = ipmi_request_supply_msgs(user, addr, 0, send_msg, &comp,
 				      &halt_smi_msg, &halt_recv_msg, 0);
 	if (rv)
 		return rv;
 
-	down (&sem);
+	wait_for_completion(&comp);
 
 	return halt_recv_msg.msg.data[0];
 }
 
-/* We are in run-to-completion mode, no semaphore is desired. */
+/* We are in run-to-completion mode, no completion is desired. */
 static int ipmi_request_in_rc_mode(ipmi_user_t            user,
 				   struct ipmi_addr       *addr,
 				   struct kernel_ipmi_msg *send_msg)
 {
-	int              rv;
+	int rv;
 
 	rv = ipmi_request_supply_msgs(user, addr, 0, send_msg, NULL,
 				      &halt_smi_msg, &halt_recv_msg, 0);
@@ -349,26 +364,38 @@ static void ipmi_poweroff_chassis (ipmi_
         smi_addr.channel = IPMI_BMC_CHANNEL;
         smi_addr.lun = 0;
 
-	printk(KERN_INFO PFX "Powering down via IPMI chassis control command\n");
+ powercyclefailed:
+	printk(KERN_INFO PFX "Powering %s via IPMI chassis control command\n",
+		((poweroff_control != IPMI_CHASSIS_POWER_CYCLE) ? "down" : "cycle"));
 
 	/*
 	 * Power down
 	 */
 	send_msg.netfn = IPMI_NETFN_CHASSIS_REQUEST;
 	send_msg.cmd = IPMI_CHASSIS_CONTROL_CMD;
-	data[0] = 0; /* Power down */
+	data[0] = poweroff_control;
 	send_msg.data = data;
 	send_msg.data_len = sizeof(data);
 	rv = ipmi_request_in_rc_mode(user,
 				     (struct ipmi_addr *) &smi_addr,
 				     &send_msg);
 	if (rv) {
-		printk(KERN_ERR PFX "Unable to send chassis powerdown message,"
-		       " IPMI error 0x%x\n", rv);
-		goto out;
+		switch (poweroff_control) {
+			case IPMI_CHASSIS_POWER_CYCLE:
+				/* power cycle failed, default to power down */
+				printk(KERN_ERR PFX "Unable to send chassis power " \
+					"cycle message, IPMI error 0x%x\n", rv);
+				poweroff_control = IPMI_CHASSIS_POWER_DOWN;
+				goto powercyclefailed;
+
+			case IPMI_CHASSIS_POWER_DOWN:
+			default:
+				printk(KERN_ERR PFX "Unable to send chassis power " \
+					"down message, IPMI error 0x%x\n", rv);
+				break;
+		}
 	}
 
- out:
 	return;
 }
 
@@ -430,7 +457,8 @@ static void ipmi_po_new_smi(int if_num)
 	if (ready)
 		return;
 
-	rv = ipmi_create_user(if_num, &ipmi_poweroff_handler, NULL, &ipmi_user);
+	rv = ipmi_create_user(if_num, &ipmi_poweroff_handler, NULL,
+			      &ipmi_user);
 	if (rv) {
 		printk(KERN_ERR PFX "could not create IPMI user, error %d\n",
 		       rv);
@@ -509,21 +537,84 @@ static struct ipmi_smi_watcher smi_watch
 };
 
 
+#ifdef CONFIG_PROC_FS
+/* displays properties to proc */
+static int proc_read_chassctrl(char *page, char **start, off_t off, int count,
+			       int *eof, void *data)
+{
+	return sprintf(page, "%d\t[ 0=powerdown 2=powercycle ]\n",
+			poweroff_control);
+}
+
+/* process property writes from proc */
+static int proc_write_chassctrl(struct file *file, const char *buffer,
+			        unsigned long count, void *data)
+{
+	int          rv = count;
+	unsigned int newval = 0;
+
+	sscanf(buffer, "%d", &newval);
+	switch (newval) {
+		case IPMI_CHASSIS_POWER_CYCLE:
+			printk(KERN_INFO PFX "power cycle is now enabled\n");
+			poweroff_control = newval;
+			break;
+
+		case IPMI_CHASSIS_POWER_DOWN:
+			poweroff_control = IPMI_CHASSIS_POWER_DOWN;
+			break;
+
+		default:
+			rv = -EINVAL;
+			break;
+	}
+
+	return rv;
+}
+#endif /* CONFIG_PROC_FS */
+
 /*
  * Startup and shutdown functions.
  */
 static int ipmi_poweroff_init (void)
 {
-	int rv;
+	int                   rv;
+	struct proc_dir_entry *file;
 
 	printk ("Copyright (C) 2004 MontaVista Software -"
 		" IPMI Powerdown via sys_reboot version "
 		IPMI_POWEROFF_VERSION ".\n");
 
+	switch (poweroff_control) {
+		case IPMI_CHASSIS_POWER_CYCLE:
+			printk(KERN_INFO PFX "Power cycle is enabled.\n");
+			break;
+
+		case IPMI_CHASSIS_POWER_DOWN:
+		default:
+			poweroff_control = IPMI_CHASSIS_POWER_DOWN;
+			break;
+	}
+
 	rv = ipmi_smi_watcher_register(&smi_watcher);
-	if (rv)
+	if (rv) {
 		printk(KERN_ERR PFX "Unable to register SMI watcher: %d\n", rv);
+		goto out_err;
+	}
 
+#ifdef CONFIG_PROC_FS
+	file = create_proc_entry("poweroff_control", 0, proc_ipmi_root);
+	if (!file) {
+		printk(KERN_ERR PFX "Unable to create proc power control\n");
+	} else {
+		file->nlink = 1;
+		file->read_proc = proc_read_chassctrl;
+		file->write_proc = proc_write_chassctrl;
+		file->owner = THIS_MODULE;
+	}
+#endif
+
+ out_err:
 	return rv;
 }
 
@@ -532,6 +623,10 @@ static __exit void ipmi_poweroff_cleanup
 {
 	int rv;
 
+#ifdef CONFIG_PROC_FS
+	remove_proc_entry("poweroff_control", proc_ipmi_root);
+#endif
+
 	ipmi_smi_watcher_unregister(&smi_watcher);
 
 	if (ready) {
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
--- a/drivers/char/ipmi/ipmi_si_intf.c
+++ b/drivers/char/ipmi/ipmi_si_intf.c
@@ -1726,7 +1726,7 @@ static int dmi_table(u32 base, int len, 
 	return status;
 }
 
-inline static int dmi_checksum(u8 *buf)
+static inline int dmi_checksum(u8 *buf)
 {
 	u8   sum=0;
 	int  a;
diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c
--- a/drivers/char/ipmi/ipmi_watchdog.c
+++ b/drivers/char/ipmi/ipmi_watchdog.c
@@ -131,11 +131,7 @@
 #define	WDIOC_GET_PRETIMEOUT     _IOW(WATCHDOG_IOCTL_BASE, 22, int)
 #endif
 
-#ifdef CONFIG_WATCHDOG_NOWAYOUT
-static int nowayout = 1;
-#else
-static int nowayout;
-#endif
+static int nowayout = WATCHDOG_NOWAYOUT;
 
 static ipmi_user_t watchdog_user = NULL;
 
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c
--- a/drivers/char/isicom.c
+++ b/drivers/char/isicom.c
@@ -1756,7 +1756,7 @@ static void isicom_flush_buffer(struct t
 }
 
 
-static int __init register_ioregion(void)
+static int __devinit register_ioregion(void)
 {
 	int count, done=0;
 	for (count=0; count < BOARD_COUNT; count++ ) {
@@ -1771,7 +1771,7 @@ static int __init register_ioregion(void
 	return done;
 }
 
-static void __exit unregister_ioregion(void)
+static void unregister_ioregion(void)
 {
 	int count;
 	for (count=0; count < BOARD_COUNT; count++ ) 
@@ -1803,7 +1803,7 @@ static struct tty_operations isicom_ops 
 	.tiocmset	= isicom_tiocmset,
 };
 
-static int __init register_drivers(void)
+static int __devinit register_drivers(void)
 {
 	int error;
 
@@ -1834,7 +1834,7 @@ static int __init register_drivers(void)
 	return 0;
 }
 
-static void __exit unregister_drivers(void)
+static void unregister_drivers(void)
 {
 	int error = tty_unregister_driver(isicom_normal);
 	if (error)
@@ -1842,7 +1842,7 @@ static void __exit unregister_drivers(vo
 	put_tty_driver(isicom_normal);
 }
 
-static int __init register_isr(void)
+static int __devinit register_isr(void)
 {
 	int count, done=0;
 	unsigned long irqflags;
@@ -1883,7 +1883,7 @@ static void __exit unregister_isr(void)
 	}
 }
 
-static int __init isicom_init(void)
+static int __devinit isicom_init(void)
 {
 	int card, channel, base;
 	struct isi_port * port;
diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c
--- a/drivers/char/istallion.c
+++ b/drivers/char/istallion.c
@@ -407,7 +407,6 @@ static unsigned long	stli_eisamemprobead
 };
 
 static int	stli_eisamempsize = sizeof(stli_eisamemprobeaddrs) / sizeof(unsigned long);
-int		stli_eisaprobe = STLI_EISAPROBE;
 
 /*
  *	Define the Stallion PCI vendor and device IDs.
@@ -792,7 +791,7 @@ static int	stli_timeron;
 
 /*****************************************************************************/
 
-static struct class_simple *istallion_class;
+static struct class *istallion_class;
 
 #ifdef MODULE
 
@@ -854,10 +853,10 @@ static void __exit istallion_module_exit
 	put_tty_driver(stli_serial);
 	for (i = 0; i < 4; i++) {
 		devfs_remove("staliomem/%d", i);
-		class_simple_device_remove(MKDEV(STL_SIOMEMMAJOR, i));
+		class_device_destroy(istallion_class, MKDEV(STL_SIOMEMMAJOR, i));
 	}
 	devfs_remove("staliomem");
-	class_simple_destroy(istallion_class);
+	class_destroy(istallion_class);
 	if ((i = unregister_chrdev(STL_SIOMEMMAJOR, "staliomem")))
 		printk("STALLION: failed to un-register serial memory device, "
 			"errno=%d\n", -i);
@@ -4685,7 +4684,7 @@ static int stli_initbrds(void)
 #ifdef MODULE
 	stli_argbrds();
 #endif
-	if (stli_eisaprobe)
+	if (STLI_EISAPROBE)
 		stli_findeisabrds();
 #ifdef CONFIG_PCI
 	stli_findpcibrds();
@@ -5242,12 +5241,12 @@ int __init stli_init(void)
 				"device\n");
 
 	devfs_mk_dir("staliomem");
-	istallion_class = class_simple_create(THIS_MODULE, "staliomem");
+	istallion_class = class_create(THIS_MODULE, "staliomem");
 	for (i = 0; i < 4; i++) {
 		devfs_mk_cdev(MKDEV(STL_SIOMEMMAJOR, i),
 			       S_IFCHR | S_IRUSR | S_IWUSR,
 			       "staliomem/%d", i);
-		class_simple_device_add(istallion_class, MKDEV(STL_SIOMEMMAJOR, i), 
+		class_device_create(istallion_class, MKDEV(STL_SIOMEMMAJOR, i),
 				NULL, "staliomem%d", i);
 	}
 
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c
--- a/drivers/char/keyboard.c
+++ b/drivers/char/keyboard.c
@@ -198,10 +198,10 @@ int setkeycode(unsigned int scancode, un
 
 	if (scancode >= dev->keycodemax)
 		return -EINVAL;
-	if (keycode > KEY_MAX)
-		return -EINVAL;
 	if (keycode < 0 || keycode > KEY_MAX)
 		return -EINVAL;
+	if (keycode >> (dev->keycodesize * 8))
+		return -EINVAL;
 
 	oldkey = SET_INPUT_KEYCODE(dev, scancode, keycode);
 
diff --git a/drivers/char/lp.c b/drivers/char/lp.c
--- a/drivers/char/lp.c
+++ b/drivers/char/lp.c
@@ -146,7 +146,7 @@
 static struct lp_struct lp_table[LP_NO];
 
 static unsigned int lp_count = 0;
-static struct class_simple *lp_class;
+static struct class *lp_class;
 
 #ifdef CONFIG_LP_CONSOLE
 static struct parport *console_registered; // initially NULL
@@ -804,7 +804,7 @@ static int lp_register(int nr, struct pa
 	if (reset)
 		lp_reset(nr);
 
-	class_simple_device_add(lp_class, MKDEV(LP_MAJOR, nr), NULL,
+	class_device_create(lp_class, MKDEV(LP_MAJOR, nr), NULL,
 				"lp%d", nr);
 	devfs_mk_cdev(MKDEV(LP_MAJOR, nr), S_IFCHR | S_IRUGO | S_IWUGO,
 			"printers/%d", nr);
@@ -907,7 +907,7 @@ static int __init lp_init (void)
 	}
 
 	devfs_mk_dir("printers");
-	lp_class = class_simple_create(THIS_MODULE, "printer");
+	lp_class = class_create(THIS_MODULE, "printer");
 	if (IS_ERR(lp_class)) {
 		err = PTR_ERR(lp_class);
 		goto out_devfs;
@@ -930,7 +930,7 @@ static int __init lp_init (void)
 	return 0;
 
 out_class:
-	class_simple_destroy(lp_class);
+	class_destroy(lp_class);
 out_devfs:
 	devfs_remove("printers");
 	unregister_chrdev(LP_MAJOR, "lp");
@@ -981,10 +981,10 @@ static void lp_cleanup_module (void)
 			continue;
 		parport_unregister_device(lp_table[offset].dev);
 		devfs_remove("printers/%d", offset);
-		class_simple_device_remove(MKDEV(LP_MAJOR, offset));
+		class_device_destroy(lp_class, MKDEV(LP_MAJOR, offset));
 	}
 	devfs_remove("printers");
-	class_simple_destroy(lp_class);
+	class_destroy(lp_class);
 }
 
 __setup("lp=", lp_setup);
diff --git a/drivers/char/mbcs.c b/drivers/char/mbcs.c
--- a/drivers/char/mbcs.c
+++ b/drivers/char/mbcs.c
@@ -699,7 +699,7 @@ static inline int mbcs_hw_init(struct mb
 	return 0;
 }
 
-static ssize_t show_algo(struct device *dev, char *buf)
+static ssize_t show_algo(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct cx_dev *cx_dev = to_cx_dev(dev);
 	struct mbcs_soft *soft = cx_dev->soft;
@@ -715,7 +715,7 @@ static ssize_t show_algo(struct device *
 		       (debug0 >> 32), (debug0 & 0xffffffff));
 }
 
-static ssize_t store_algo(struct device *dev, const char *buf, size_t count)
+static ssize_t store_algo(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	int n;
 	struct cx_dev *cx_dev = to_cx_dev(dev);
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -23,7 +23,10 @@
 #include <linux/devfs_fs_kernel.h>
 #include <linux/ptrace.h>
 #include <linux/device.h>
+#include <linux/highmem.h>
+#include <linux/crash_dump.h>
 #include <linux/backing-dev.h>
+#include <linux/bootmem.h>
 
 #include <asm/uaccess.h>
 #include <asm/io.h>
@@ -258,7 +261,11 @@ static int mmap_mem(struct file * file, 
 
 static int mmap_kmem(struct file * file, struct vm_area_struct * vma)
 {
-        unsigned long long val;
+	unsigned long pfn;
+
+	/* Turn a kernel-virtual address into a physical page frame */
+	pfn = __pa((u64)vma->vm_pgoff << PAGE_SHIFT) >> PAGE_SHIFT;
+
 	/*
 	 * RED-PEN: on some architectures there is more mapped memory
 	 * than available in mem_map which pfn_valid checks
@@ -266,13 +273,47 @@ static int mmap_kmem(struct file * file,
 	 *
 	 * RED-PEN: vmalloc is not supported right now.
 	 */
-	if (!pfn_valid(vma->vm_pgoff))
+	if (!pfn_valid(pfn))
 		return -EIO;
-	val = (u64)vma->vm_pgoff << PAGE_SHIFT;
-	vma->vm_pgoff = __pa(val) >> PAGE_SHIFT;
+
+	vma->vm_pgoff = pfn;
 	return mmap_mem(file, vma);
 }
 
+#ifdef CONFIG_CRASH_DUMP
+/*
+ * Read memory corresponding to the old kernel.
+ */
+static ssize_t read_oldmem(struct file *file, char __user *buf,
+				size_t count, loff_t *ppos)
+{
+	unsigned long pfn, offset;
+	size_t read = 0, csize;
+	int rc = 0;
+
+	while (count) {
+		pfn = *ppos / PAGE_SIZE;
+		if (pfn > saved_max_pfn)
+			return read;
+
+		offset = (unsigned long)(*ppos % PAGE_SIZE);
+		if (count > PAGE_SIZE - offset)
+			csize = PAGE_SIZE - offset;
+		else
+			csize = count;
+
+		rc = copy_oldmem_page(pfn, buf, csize, offset, 1);
+		if (rc < 0)
+			return rc;
+		buf += csize;
+		*ppos += csize;
+		read += csize;
+		count -= csize;
+	}
+	return read;
+}
+#endif
+
 extern long vread(char *buf, char *addr, unsigned long count);
 extern long vwrite(char *buf, char *addr, unsigned long count);
 
@@ -484,7 +525,7 @@ static ssize_t write_kmem(struct file * 
  	return virtr + wrote;
 }
 
-#if defined(CONFIG_ISA) || !defined(__mc68000__)
+#if (defined(CONFIG_ISA) || !defined(__mc68000__)) && (!defined(CONFIG_PPC_ISERIES) || defined(CONFIG_PCI))
 static ssize_t read_port(struct file * file, char __user * buf,
 			 size_t count, loff_t *ppos)
 {
@@ -721,6 +762,7 @@ static int open_port(struct inode * inod
 #define read_full       read_zero
 #define open_mem	open_port
 #define open_kmem	open_mem
+#define open_oldmem	open_mem
 
 static struct file_operations mem_fops = {
 	.llseek		= memory_lseek,
@@ -744,7 +786,7 @@ static struct file_operations null_fops 
 	.write		= write_null,
 };
 
-#if defined(CONFIG_ISA) || !defined(__mc68000__)
+#if (defined(CONFIG_ISA) || !defined(__mc68000__)) && (!defined(CONFIG_PPC_ISERIES) || defined(CONFIG_PCI))
 static struct file_operations port_fops = {
 	.llseek		= memory_lseek,
 	.read		= read_port,
@@ -770,6 +812,13 @@ static struct file_operations full_fops 
 	.write		= write_full,
 };
 
+#ifdef CONFIG_CRASH_DUMP
+static struct file_operations oldmem_fops = {
+	.read	= read_oldmem,
+	.open	= open_oldmem,
+};
+#endif
+
 static ssize_t kmsg_write(struct file * file, const char __user * buf,
 			  size_t count, loff_t *ppos)
 {
@@ -804,7 +853,7 @@ static int memory_open(struct inode * in
 		case 3:
 			filp->f_op = &null_fops;
 			break;
-#if defined(CONFIG_ISA) || !defined(__mc68000__)
+#if (defined(CONFIG_ISA) || !defined(__mc68000__)) && (!defined(CONFIG_PPC_ISERIES) || defined(CONFIG_PCI))
 		case 4:
 			filp->f_op = &port_fops;
 			break;
@@ -825,6 +874,11 @@ static int memory_open(struct inode * in
 		case 11:
 			filp->f_op = &kmsg_fops;
 			break;
+#ifdef CONFIG_CRASH_DUMP
+		case 12:
+			filp->f_op = &oldmem_fops;
+			break;
+#endif
 		default:
 			return -ENXIO;
 	}
@@ -846,7 +900,7 @@ static const struct {
 	{1, "mem",     S_IRUSR | S_IWUSR | S_IRGRP, &mem_fops},
 	{2, "kmem",    S_IRUSR | S_IWUSR | S_IRGRP, &kmem_fops},
 	{3, "null",    S_IRUGO | S_IWUGO,           &null_fops},
-#if defined(CONFIG_ISA) || !defined(__mc68000__)
+#if (defined(CONFIG_ISA) || !defined(__mc68000__)) && (!defined(CONFIG_PPC_ISERIES) || defined(CONFIG_PCI))
 	{4, "port",    S_IRUSR | S_IWUSR | S_IRGRP, &port_fops},
 #endif
 	{5, "zero",    S_IRUGO | S_IWUGO,           &zero_fops},
@@ -854,9 +908,12 @@ static const struct {
 	{8, "random",  S_IRUGO | S_IWUSR,           &random_fops},
 	{9, "urandom", S_IRUGO | S_IWUSR,           &urandom_fops},
 	{11,"kmsg",    S_IRUGO | S_IWUSR,           &kmsg_fops},
+#ifdef CONFIG_CRASH_DUMP
+	{12,"oldmem",    S_IRUSR | S_IWUSR | S_IRGRP, &oldmem_fops},
+#endif
 };
 
-static struct class_simple *mem_class;
+static struct class *mem_class;
 
 static int __init chr_dev_init(void)
 {
@@ -865,10 +922,9 @@ static int __init chr_dev_init(void)
 	if (register_chrdev(MEM_MAJOR,"mem",&memory_fops))
 		printk("unable to get major %d for memory devs\n", MEM_MAJOR);
 
-	mem_class = class_simple_create(THIS_MODULE, "mem");
+	mem_class = class_create(THIS_MODULE, "mem");
 	for (i = 0; i < ARRAY_SIZE(devlist); i++) {
-		class_simple_device_add(mem_class,
-					MKDEV(MEM_MAJOR, devlist[i].minor),
+		class_device_create(mem_class, MKDEV(MEM_MAJOR, devlist[i].minor),
 					NULL, devlist[i].name);
 		devfs_mk_cdev(MKDEV(MEM_MAJOR, devlist[i].minor),
 				S_IFCHR | devlist[i].mode, devlist[i].name);
diff --git a/drivers/char/misc.c b/drivers/char/misc.c
--- a/drivers/char/misc.c
+++ b/drivers/char/misc.c
@@ -66,8 +66,6 @@ static unsigned char misc_minors[DYNAMIC
 extern int rtc_DP8570A_init(void);
 extern int rtc_MK48T08_init(void);
 extern int pmu_device_init(void);
-extern int tosh_init(void);
-extern int i8k_init(void);
 
 #ifdef CONFIG_PROC_FS
 static void *misc_seq_start(struct seq_file *seq, loff_t *pos)
@@ -177,10 +175,10 @@ fail:
 
 /* 
  * TODO for 2.7:
- *  - add a struct class_device to struct miscdevice and make all usages of
+ *  - add a struct kref to struct miscdevice and make all usages of
  *    them dynamic.
  */
-static struct class_simple *misc_class;
+static struct class *misc_class;
 
 static struct file_operations misc_fops = {
 	.owner		= THIS_MODULE,
@@ -238,8 +236,8 @@ int misc_register(struct miscdevice * mi
 	}
 	dev = MKDEV(MISC_MAJOR, misc->minor);
 
-	misc->class = class_simple_device_add(misc_class, dev,
-					      misc->dev, misc->name);
+	misc->class = class_device_create(misc_class, dev, misc->dev,
+					  "%s", misc->name);
 	if (IS_ERR(misc->class)) {
 		err = PTR_ERR(misc->class);
 		goto out;
@@ -248,7 +246,7 @@ int misc_register(struct miscdevice * mi
 	err = devfs_mk_cdev(dev, S_IFCHR|S_IRUSR|S_IWUSR|S_IRGRP, 
 			    misc->devfs_name);
 	if (err) {
-		class_simple_device_remove(dev);
+		class_device_destroy(misc_class, dev);
 		goto out;
 	}
 
@@ -281,7 +279,7 @@ int misc_deregister(struct miscdevice * 
 
 	down(&misc_sem);
 	list_del(&misc->list);
-	class_simple_device_remove(MKDEV(MISC_MAJOR, misc->minor));
+	class_device_destroy(misc_class, MKDEV(MISC_MAJOR, misc->minor));
 	devfs_remove(misc->devfs_name);
 	if (i < DYNAMIC_MINORS && i>0) {
 		misc_minors[i>>3] &= ~(1 << (misc->minor & 7));
@@ -302,7 +300,7 @@ static int __init misc_init(void)
 	if (ent)
 		ent->proc_fops = &misc_proc_fops;
 #endif
-	misc_class = class_simple_create(THIS_MODULE, "misc");
+	misc_class = class_create(THIS_MODULE, "misc");
 	if (IS_ERR(misc_class))
 		return PTR_ERR(misc_class);
 #ifdef CONFIG_MVME16x
@@ -311,19 +309,10 @@ static int __init misc_init(void)
 #ifdef CONFIG_BVME6000
 	rtc_DP8570A_init();
 #endif
-#ifdef CONFIG_PMAC_PBOOK
-	pmu_device_init();
-#endif
-#ifdef CONFIG_TOSHIBA
-	tosh_init();
-#endif
-#ifdef CONFIG_I8K
-	i8k_init();
-#endif
 	if (register_chrdev(MISC_MAJOR,"misc",&misc_fops)) {
 		printk("unable to get major %d for misc devices\n",
 		       MISC_MAJOR);
-		class_simple_destroy(misc_class);
+		class_destroy(misc_class);
 		return -EIO;
 	}
 	return 0;
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c
--- a/drivers/char/moxa.c
+++ b/drivers/char/moxa.c
@@ -451,7 +451,7 @@ static int __init moxa_init(void)
 		int n = (sizeof(moxa_pcibrds) / sizeof(moxa_pcibrds[0])) - 1;
 		i = 0;
 		while (i < n) {
-			while ((p = pci_find_device(moxa_pcibrds[i].vendor, moxa_pcibrds[i].device, p))!=NULL)
+			while ((p = pci_get_device(moxa_pcibrds[i].vendor, moxa_pcibrds[i].device, p))!=NULL)
 			{
 				if (pci_enable_device(p))
 					continue;
diff --git a/drivers/char/mwave/3780i.c b/drivers/char/mwave/3780i.c
--- a/drivers/char/mwave/3780i.c
+++ b/drivers/char/mwave/3780i.c
@@ -107,8 +107,8 @@ void dsp3780I_WriteMsaCfg(unsigned short
 	spin_unlock_irqrestore(&dsp_lock, flags);
 }
 
-void dsp3780I_WriteGenCfg(unsigned short usDspBaseIO, unsigned uIndex,
-                          unsigned char ucValue)
+static void dsp3780I_WriteGenCfg(unsigned short usDspBaseIO, unsigned uIndex,
+				 unsigned char ucValue)
 {
 	DSP_ISA_SLAVE_CONTROL rSlaveControl;
 	DSP_ISA_SLAVE_CONTROL rSlaveControl_Save;
@@ -141,6 +141,7 @@ void dsp3780I_WriteGenCfg(unsigned short
 
 }
 
+#if 0
 unsigned char dsp3780I_ReadGenCfg(unsigned short usDspBaseIO,
                                   unsigned uIndex)
 {
@@ -167,6 +168,7 @@ unsigned char dsp3780I_ReadGenCfg(unsign
 
 	return ucValue;
 }
+#endif  /*  0  */
 
 int dsp3780I_EnableDSP(DSP_3780I_CONFIG_SETTINGS * pSettings,
                        unsigned short *pIrqMap,
diff --git a/drivers/char/mwave/3780i.h b/drivers/char/mwave/3780i.h
--- a/drivers/char/mwave/3780i.h
+++ b/drivers/char/mwave/3780i.h
@@ -338,10 +338,6 @@ unsigned short dsp3780I_ReadMsaCfg(unsig
                                    unsigned long ulMsaAddr);
 void dsp3780I_WriteMsaCfg(unsigned short usDspBaseIO,
                           unsigned long ulMsaAddr, unsigned short usValue);
-void dsp3780I_WriteGenCfg(unsigned short usDspBaseIO, unsigned uIndex,
-                          unsigned char ucValue);
-unsigned char dsp3780I_ReadGenCfg(unsigned short usDspBaseIO,
-                                  unsigned uIndex);
 int dsp3780I_GetIPCSource(unsigned short usDspBaseIO,
                           unsigned short *pusIPCSource);
 
diff --git a/drivers/char/mwave/mwavedd.c b/drivers/char/mwave/mwavedd.c
--- a/drivers/char/mwave/mwavedd.c
+++ b/drivers/char/mwave/mwavedd.c
@@ -472,7 +472,7 @@ struct device mwave_device;
 
 /* Prevent code redundancy, create a macro for mwave_show_* functions. */
 #define mwave_show_function(attr_name, format_string, field)		\
-static ssize_t mwave_show_##attr_name(struct device *dev, char *buf)	\
+static ssize_t mwave_show_##attr_name(struct device *dev, struct device_attribute *attr, char *buf)	\
 {									\
 	DSP_3780I_CONFIG_SETTINGS *pSettings =				\
 		&mwave_s_mdd.rBDData.rDspSettings;			\
diff --git a/drivers/char/mwave/tp3780i.c b/drivers/char/mwave/tp3780i.c
--- a/drivers/char/mwave/tp3780i.c
+++ b/drivers/char/mwave/tp3780i.c
@@ -242,20 +242,14 @@ int tp3780I_ClaimResources(THINKPAD_BD_D
 {
 	int retval = 0;
 	DSP_3780I_CONFIG_SETTINGS *pSettings = &pBDData->rDspSettings;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
 	struct resource *pres;
-#endif
 
 	PRINTK_2(TRACE_TP3780I,
 		"tp3780i::tp3780I_ClaimResources entry pBDData %p\n", pBDData);
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
 	pres = request_region(pSettings->usDspBaseIO, 16, "mwave_3780i");
 	if ( pres == NULL ) retval = -EIO;
-#else
-	retval = check_region(pSettings->usDspBaseIO, 16);
-	if (!retval) request_region(pSettings->usDspBaseIO, 16, "mwave_3780i");
-#endif
+
 	if (retval) {
 		PRINTK_ERROR(KERN_ERR_MWAVE "tp3780i::tp3780I_ClaimResources: Error: Could not claim I/O region starting at %x\n", pSettings->usDspBaseIO);
 		retval = -EIO;
@@ -292,7 +286,7 @@ int tp3780I_ReleaseResources(THINKPAD_BD
 int tp3780I_EnableDSP(THINKPAD_BD_DATA * pBDData)
 {
 	DSP_3780I_CONFIG_SETTINGS *pSettings = &pBDData->rDspSettings;
-	BOOLEAN bDSPPoweredUp = FALSE, bDSPEnabled = FALSE, bInterruptAllocated = FALSE;
+	BOOLEAN bDSPPoweredUp = FALSE, bInterruptAllocated = FALSE;
 
 	PRINTK_2(TRACE_TP3780I, "tp3780i::tp3780I_EnableDSP entry pBDData %p\n", pBDData);
 
@@ -397,8 +391,6 @@ int tp3780I_EnableDSP(THINKPAD_BD_DATA *
 	if (dsp3780I_EnableDSP(pSettings, s_ausThinkpadIrqToField, s_ausThinkpadDmaToField)) {
 		PRINTK_ERROR("tp3780i::tp3780I_EnableDSP: Error: dsp7880I_EnableDSP() failed\n");
 		goto exit_cleanup;
-	} else {
-		bDSPEnabled = TRUE;
 	}
 
 	EnableSRAM(pBDData);
@@ -411,8 +403,6 @@ int tp3780I_EnableDSP(THINKPAD_BD_DATA *
 
 exit_cleanup:
 	PRINTK_ERROR("tp3780i::tp3780I_EnableDSP: Cleaning up\n");
-	if (bDSPEnabled)
-		dsp3780I_DisableDSP(pSettings);
 	if (bDSPPoweredUp)
 		smapi_set_DSP_power_state(FALSE);
 	if (bInterruptAllocated) {
diff --git a/drivers/char/n_hdlc.c b/drivers/char/n_hdlc.c
--- a/drivers/char/n_hdlc.c
+++ b/drivers/char/n_hdlc.c
@@ -960,7 +960,7 @@ static char hdlc_unregister_fail[] __exi
 static void __exit n_hdlc_exit(void)
 {
 	/* Release tty registration of line discipline */
-	int status = tty_register_ldisc(N_HDLC, NULL);
+	int status = tty_unregister_ldisc(N_HDLC);
 
 	if (status)
 		printk(hdlc_unregister_fail, status);
diff --git a/drivers/char/n_r3964.c b/drivers/char/n_r3964.c
--- a/drivers/char/n_r3964.c
+++ b/drivers/char/n_r3964.c
@@ -200,7 +200,7 @@ static void __exit r3964_exit(void)
    
    TRACE_M ("cleanup_module()");
 
-   status=tty_register_ldisc(N_R3964, NULL);
+   status=tty_unregister_ldisc(N_R3964);
    
    if(status!=0)
    {
diff --git a/drivers/char/n_tty.c b/drivers/char/n_tty.c
--- a/drivers/char/n_tty.c
+++ b/drivers/char/n_tty.c
@@ -770,10 +770,8 @@ send_signal:
 		}
 		if (c == '\n') {
 			if (L_ECHO(tty) || L_ECHONL(tty)) {
-				if (tty->read_cnt >= N_TTY_BUF_SIZE-1) {
+				if (tty->read_cnt >= N_TTY_BUF_SIZE-1)
 					put_char('\a', tty);
-					return;
-				}
 				opost('\n', tty);
 			}
 			goto handle_newline;
@@ -790,10 +788,8 @@ send_signal:
 			 * XXX are EOL_CHAR and EOL2_CHAR echoed?!?
 			 */
 			if (L_ECHO(tty)) {
-				if (tty->read_cnt >= N_TTY_BUF_SIZE-1) {
+				if (tty->read_cnt >= N_TTY_BUF_SIZE-1)
 					put_char('\a', tty);
-					return;
-				}
 				/* Record the column of first canon char. */
 				if (tty->canon_head == tty->read_head)
 					tty->canon_column = tty->column;
@@ -862,12 +858,9 @@ static int n_tty_receive_room(struct tty
 	 * that erase characters will be handled.  Other excess
 	 * characters will be beeped.
 	 */
-	if (tty->icanon && !tty->canon_data)
-		return N_TTY_BUF_SIZE;
-
-	if (left > 0)
-		return left;
-	return 0;
+	if (left <= 0)
+		left = tty->icanon && !tty->canon_data;
+	return left;
 }
 
 /**
@@ -1473,13 +1466,17 @@ static ssize_t write_chan(struct tty_str
 			if (tty->driver->flush_chars)
 				tty->driver->flush_chars(tty);
 		} else {
-			c = tty->driver->write(tty, b, nr);
-			if (c < 0) {
-				retval = c;
-				goto break_out;
+			while (nr > 0) {
+				c = tty->driver->write(tty, b, nr);
+				if (c < 0) {
+					retval = c;
+					goto break_out;
+				}
+				if (!c)
+					break;
+				b += c;
+				nr -= c;
 			}
-			b += c;
-			nr -= c;
 		}
 		if (!nr)
 			break;
diff --git a/drivers/char/nvram.c b/drivers/char/nvram.c
--- a/drivers/char/nvram.c
+++ b/drivers/char/nvram.c
@@ -211,12 +211,13 @@ nvram_check_checksum(void)
 	return rv;
 }
 
-void
+static void
 __nvram_set_checksum(void)
 {
 	mach_set_checksum();
 }
 
+#if 0
 void
 nvram_set_checksum(void)
 {
@@ -226,6 +227,7 @@ nvram_set_checksum(void)
 	__nvram_set_checksum();
 	spin_unlock_irqrestore(&rtc_lock, flags);
 }
+#endif  /*  0  */
 
 /*
  * The are the file operation function for user access to /dev/nvram
@@ -921,6 +923,4 @@ EXPORT_SYMBOL(__nvram_write_byte);
 EXPORT_SYMBOL(nvram_write_byte);
 EXPORT_SYMBOL(__nvram_check_checksum);
 EXPORT_SYMBOL(nvram_check_checksum);
-EXPORT_SYMBOL(__nvram_set_checksum);
-EXPORT_SYMBOL(nvram_set_checksum);
 MODULE_ALIAS_MISCDEV(NVRAM_MINOR);
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c
--- a/drivers/char/pcmcia/synclink_cs.c
+++ b/drivers/char/pcmcia/synclink_cs.c
@@ -71,7 +71,6 @@
 #include <linux/workqueue.h>
 #include <linux/hdlc.h>
 
-#include <pcmcia/version.h>
 #include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
@@ -581,7 +580,7 @@ static dev_link_t *mgslpc_attach(void)
 
     /* Interrupt setup */
     link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
-    link->irq.IRQInfo1   = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
+    link->irq.IRQInfo1   = IRQ_LEVEL_ID;
     link->irq.Handler = NULL;
     
     link->conf.Attributes = 0;
@@ -593,11 +592,6 @@ static dev_link_t *mgslpc_attach(void)
     dev_list = link;
 
     client_reg.dev_info = &dev_info;
-    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 = &mgslpc_event;
     client_reg.Version = 0x0210;
     client_reg.event_callback_args.client_data = link;
 
@@ -3081,13 +3075,21 @@ void mgslpc_remove_device(MGSLPC_INFO *r
 	}
 }
 
+static struct pcmcia_device_id mgslpc_ids[] = {
+	PCMCIA_DEVICE_MANF_CARD(0x02c5, 0x0050),
+	PCMCIA_DEVICE_NULL
+};
+MODULE_DEVICE_TABLE(pcmcia, mgslpc_ids);
+
 static struct pcmcia_driver mgslpc_driver = {
 	.owner		= THIS_MODULE,
 	.drv		= {
 		.name	= "synclink_cs",
 	},
 	.attach		= mgslpc_attach,
+	.event		= mgslpc_event,
 	.detach		= mgslpc_detach,
+	.id_table	= mgslpc_ids,
 };
 
 static struct tty_operations mgslpc_ops = {
diff --git a/drivers/char/ppdev.c b/drivers/char/ppdev.c
--- a/drivers/char/ppdev.c
+++ b/drivers/char/ppdev.c
@@ -737,7 +737,7 @@ static unsigned int pp_poll (struct file
 	return mask;
 }
 
-static struct class_simple *ppdev_class;
+static struct class *ppdev_class;
 
 static struct file_operations pp_fops = {
 	.owner		= THIS_MODULE,
@@ -752,13 +752,13 @@ static struct file_operations pp_fops = 
 
 static void pp_attach(struct parport *port)
 {
-	class_simple_device_add(ppdev_class, MKDEV(PP_MAJOR, port->number),
+	class_device_create(ppdev_class, MKDEV(PP_MAJOR, port->number),
 			NULL, "parport%d", port->number);
 }
 
 static void pp_detach(struct parport *port)
 {
-	class_simple_device_remove(MKDEV(PP_MAJOR, port->number));
+	class_device_destroy(ppdev_class, MKDEV(PP_MAJOR, port->number));
 }
 
 static struct parport_driver pp_driver = {
@@ -776,7 +776,7 @@ static int __init ppdev_init (void)
 			PP_MAJOR);
 		return -EIO;
 	}
-	ppdev_class = class_simple_create(THIS_MODULE, CHRDEV);
+	ppdev_class = class_create(THIS_MODULE, CHRDEV);
 	if (IS_ERR(ppdev_class)) {
 		err = PTR_ERR(ppdev_class);
 		goto out_chrdev;
@@ -798,7 +798,7 @@ out_class:
 	for (i = 0; i < PARPORT_MAX; i++)
 		devfs_remove("parports/%d", i);
 	devfs_remove("parports");
-	class_simple_destroy(ppdev_class);
+	class_destroy(ppdev_class);
 out_chrdev:
 	unregister_chrdev(PP_MAJOR, CHRDEV);
 out:
@@ -813,7 +813,7 @@ static void __exit ppdev_cleanup (void)
 		devfs_remove("parports/%d", i);
 	parport_unregister_driver(&pp_driver);
 	devfs_remove("parports");
-	class_simple_destroy(ppdev_class);
+	class_destroy(ppdev_class);
 	unregister_chrdev (PP_MAJOR, CHRDEV);
 }
 
diff --git a/drivers/char/random.c b/drivers/char/random.c
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -271,7 +271,7 @@ static int random_write_wakeup_thresh = 
  * samples to avoid wasting CPU time and reduce lock contention.
  */
 
-static int trickle_thresh = INPUT_POOL_WORDS * 28;
+static int trickle_thresh __read_mostly = INPUT_POOL_WORDS * 28;
 
 static DEFINE_PER_CPU(int, trickle_count) = 0;
 
diff --git a/drivers/char/raw.c b/drivers/char/raw.c
--- a/drivers/char/raw.c
+++ b/drivers/char/raw.c
@@ -27,7 +27,7 @@ struct raw_device_data {
 	int inuse;
 };
 
-static struct class_simple *raw_class;
+static struct class *raw_class;
 static struct raw_device_data raw_devices[MAX_RAW_MINORS];
 static DECLARE_MUTEX(raw_mutex);
 static struct file_operations raw_ctl_fops;	     /* forward declaration */
@@ -127,8 +127,8 @@ raw_ioctl(struct inode *inode, struct fi
 
 static void bind_device(struct raw_config_request *rq)
 {
-	class_simple_device_remove(MKDEV(RAW_MAJOR, rq->raw_minor));
-	class_simple_device_add(raw_class, MKDEV(RAW_MAJOR, rq->raw_minor),
+	class_device_destroy(raw_class, MKDEV(RAW_MAJOR, rq->raw_minor));
+	class_device_create(raw_class, MKDEV(RAW_MAJOR, rq->raw_minor),
 				      NULL, "raw%d", rq->raw_minor);
 }
 
@@ -200,8 +200,8 @@ static int raw_ctl_ioctl(struct inode *i
 			if (rq.block_major == 0 && rq.block_minor == 0) {
 				/* unbind */
 				rawdev->binding = NULL;
-				class_simple_device_remove(MKDEV(RAW_MAJOR,
-								rq.raw_minor));
+				class_device_destroy(raw_class,
+						MKDEV(RAW_MAJOR, rq.raw_minor));
 			} else {
 				rawdev->binding = bdget(dev);
 				if (rawdev->binding == NULL)
@@ -300,14 +300,14 @@ static int __init raw_init(void)
 		goto error;
 	}
 
-	raw_class = class_simple_create(THIS_MODULE, "raw");
+	raw_class = class_create(THIS_MODULE, "raw");
 	if (IS_ERR(raw_class)) {
 		printk(KERN_ERR "Error creating raw class.\n");
 		cdev_del(&raw_cdev);
 		unregister_chrdev_region(dev, MAX_RAW_MINORS);
 		goto error;
 	}
-	class_simple_device_add(raw_class, MKDEV(RAW_MAJOR, 0), NULL, "rawctl");
+	class_device_create(raw_class, MKDEV(RAW_MAJOR, 0), NULL, "rawctl");
 
 	devfs_mk_cdev(MKDEV(RAW_MAJOR, 0),
 		      S_IFCHR | S_IRUGO | S_IWUGO,
@@ -331,8 +331,8 @@ static void __exit raw_exit(void)
 		devfs_remove("raw/raw%d", i);
 	devfs_remove("raw/rawctl");
 	devfs_remove("raw");
-	class_simple_device_remove(MKDEV(RAW_MAJOR, 0));
-	class_simple_destroy(raw_class);
+	class_device_destroy(raw_class, MKDEV(RAW_MAJOR, 0));
+	class_destroy(raw_class);
 	cdev_del(&raw_cdev);
 	unregister_chrdev_region(MKDEV(RAW_MAJOR, 0), MAX_RAW_MINORS);
 }
diff --git a/drivers/char/rio/func.h b/drivers/char/rio/func.h
--- a/drivers/char/rio/func.h
+++ b/drivers/char/rio/func.h
@@ -147,7 +147,6 @@ struct rio_info * rio_info_store( int cm
 extern int    rio_pcicopy(char *src, char *dst, int n);
 extern int rio_minor (struct tty_struct *tty);
 extern int rio_ismodem (struct tty_struct *tty);
-extern void rio_udelay (int usecs);
 
 extern void rio_start_card_running (struct Host * HostP);
 
diff --git a/drivers/char/rio/rio_linux.c b/drivers/char/rio/rio_linux.c
--- a/drivers/char/rio/rio_linux.c
+++ b/drivers/char/rio/rio_linux.c
@@ -354,11 +354,6 @@ int rio_ismodem(struct tty_struct *tty)
 }
 
 
-void rio_udelay (int usecs)
-{
-  udelay (usecs);
-}
-
 static int rio_set_real_termios (void *ptr)
 {
   int rv, modem;
@@ -1100,7 +1095,7 @@ static int __init rio_init(void) 
 
 #ifdef CONFIG_PCI
     /* First look for the JET devices: */
-    while ((pdev = pci_find_device (PCI_VENDOR_ID_SPECIALIX, 
+    while ((pdev = pci_get_device (PCI_VENDOR_ID_SPECIALIX,
                                     PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8, 
                                     pdev))) {
        if (pci_enable_device(pdev)) continue;
@@ -1174,7 +1169,7 @@ static int __init rio_init(void) 
   */
 
     /* Then look for the older RIO/PCI devices: */
-    while ((pdev = pci_find_device (PCI_VENDOR_ID_SPECIALIX, 
+    while ((pdev = pci_get_device (PCI_VENDOR_ID_SPECIALIX,
                                     PCI_DEVICE_ID_SPECIALIX_RIO, 
                                     pdev))) {
        if (pci_enable_device(pdev)) continue;
diff --git a/drivers/char/rio/rioboot.c b/drivers/char/rio/rioboot.c
--- a/drivers/char/rio/rioboot.c
+++ b/drivers/char/rio/rioboot.c
@@ -902,7 +902,7 @@ static int RIOBootComplete( struct rio_i
 	       (HostP->Mapping[entry].RtaUniqueNum==RtaUniq))
 	    {
 	        HostP->Mapping[entry].Flags |= RTA_BOOTED|RTA_NEWBOOT;
-#if NEED_TO_FIX
+#ifdef NEED_TO_FIX
 		RIO_SV_BROADCAST(HostP->svFlags[entry]);
 #endif
 		if ( (sysport=HostP->Mapping[entry].SysPort) != NO_PORT )
@@ -918,7 +918,7 @@ static int RIOBootComplete( struct rio_i
 		   {
 			entry2 = HostP->Mapping[entry].ID2 - 1;
 			HostP->Mapping[entry2].Flags |= RTA_BOOTED|RTA_NEWBOOT;
-#if NEED_TO_FIX
+#ifdef NEED_TO_FIX
 			RIO_SV_BROADCAST(HostP->svFlags[entry2]);
 #endif
 			sysport = HostP->Mapping[entry2].SysPort;
@@ -1143,7 +1143,7 @@ static int RIOBootComplete( struct rio_i
 		    CCOPY( MapP->Name, HostP->Mapping[entry].Name, MAX_NAME_LEN );
 		    HostP->Mapping[entry].Flags =
 		     SLOT_IN_USE | RTA_BOOTED | RTA_NEWBOOT;
-#if NEED_TO_FIX
+#ifdef NEED_TO_FIX
 		    RIO_SV_BROADCAST(HostP->svFlags[entry]);
 #endif
 		    RIOReMapPorts( p, HostP, &HostP->Mapping[entry] );
@@ -1159,7 +1159,7 @@ static int RIOBootComplete( struct rio_i
    "This RTA has a tentative entry on another host - delete that entry (1)\n");
 		    HostP->Mapping[entry].Flags =
 		     SLOT_TENTATIVE | RTA_BOOTED | RTA_NEWBOOT;
-#if NEED_TO_FIX
+#ifdef NEED_TO_FIX
 		    RIO_SV_BROADCAST(HostP->svFlags[entry]);
 #endif
 		}
@@ -1169,7 +1169,7 @@ static int RIOBootComplete( struct rio_i
 		    {
 			HostP->Mapping[entry2].Flags = SLOT_IN_USE |
 			 RTA_BOOTED | RTA_NEWBOOT | RTA16_SECOND_SLOT;
-#if NEED_TO_FIX
+#ifdef NEED_TO_FIX
 			RIO_SV_BROADCAST(HostP->svFlags[entry2]);
 #endif
 			HostP->Mapping[entry2].SysPort = MapP2->SysPort;
@@ -1188,7 +1188,7 @@ static int RIOBootComplete( struct rio_i
 		    else
 			HostP->Mapping[entry2].Flags = SLOT_TENTATIVE |
 			 RTA_BOOTED | RTA_NEWBOOT | RTA16_SECOND_SLOT;
-#if NEED_TO_FIX
+#ifdef NEED_TO_FIX
 			RIO_SV_BROADCAST(HostP->svFlags[entry2]);
 #endif
 		    bzero( (caddr_t)MapP2, sizeof(struct Map) );
diff --git a/drivers/char/rio/rioinit.c b/drivers/char/rio/rioinit.c
--- a/drivers/char/rio/rioinit.c
+++ b/drivers/char/rio/rioinit.c
@@ -37,6 +37,7 @@ static char *_rioinit_c_sccs_ = "@(#)rio
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/errno.h>
+#include <linux/delay.h>
 #include <asm/io.h>
 #include <asm/system.h>
 #include <asm/string.h>
@@ -1560,14 +1561,14 @@ uint Slot; 
 					  INTERRUPT_DISABLE | BYTE_OPERATION |
 					  SLOW_LINKS | SLOW_AT_BUS);
 			WBYTE(DpRamP->DpResetTpu, 0xFF);
-			rio_udelay (3);
+			udelay(3);
 
 			rio_dprintk (RIO_DEBUG_INIT,  "RIOHostReset: Don't know if it worked. Try reset again\n");
 			WBYTE(DpRamP->DpControl,  BOOT_FROM_RAM | EXTERNAL_BUS_OFF |
 					  INTERRUPT_DISABLE | BYTE_OPERATION |
 					  SLOW_LINKS | SLOW_AT_BUS);
 			WBYTE(DpRamP->DpResetTpu, 0xFF);
-			rio_udelay (3);
+			udelay(3);
 			break;
 #ifdef FUTURE_RELEASE
 	case RIO_EISA:
@@ -1599,7 +1600,7 @@ uint Slot; 
 		DpRamP->DpControl  = RIO_PCI_BOOT_FROM_RAM;
 		DpRamP->DpResetInt = 0xFF;
 		DpRamP->DpResetTpu = 0xFF;
-		rio_udelay (100);
+		udelay(100);
 		/* for (i=0; i<6000; i++);  */
 		/* suspend( 3 ); */
 		break;
diff --git a/drivers/char/rio/rioroute.c b/drivers/char/rio/rioroute.c
--- a/drivers/char/rio/rioroute.c
+++ b/drivers/char/rio/rioroute.c
@@ -1023,7 +1023,7 @@ RIOFreeDisconnected(struct rio_info *p, 
     if (link < LINKS_PER_UNIT)
 	    return 1;
 
-#if NEED_TO_FIX_THIS
+#ifdef NEED_TO_FIX_THIS
     /* Ok so all the links are disconnected. But we may have only just
     ** made this slot tentative and not yet received a topology update.
     ** Lets check how long ago we made it tentative.
diff --git a/drivers/char/rio/riotable.c b/drivers/char/rio/riotable.c
--- a/drivers/char/rio/riotable.c
+++ b/drivers/char/rio/riotable.c
@@ -771,7 +771,7 @@ int RIOAssignRta( struct rio_info *p, st
 	    if ((MapP->Flags & RTA16_SECOND_SLOT) == 0)
 	      CCOPY( MapP->Name, HostMapP->Name, MAX_NAME_LEN );
 	    HostMapP->Flags = SLOT_IN_USE | RTA_BOOTED;
-#if NEED_TO_FIX
+#ifdef NEED_TO_FIX
 	    RIO_SV_BROADCAST(p->RIOHosts[host].svFlags[MapP->ID-1]);
 #endif
 	    if (MapP->Flags & RTA16_SECOND_SLOT)
diff --git a/drivers/char/rio/riotty.c b/drivers/char/rio/riotty.c
--- a/drivers/char/rio/riotty.c
+++ b/drivers/char/rio/riotty.c
@@ -524,16 +524,16 @@ riotclose(void  *ptr)
 	register uint SysPort = dev;
 	struct ttystatics *tp;		/* pointer to our ttystruct */
 #endif
-	struct Port *PortP =ptr;	/* pointer to the port structure */
+	struct Port *PortP = ptr;	/* pointer to the port structure */
 	int deleted = 0;
 	int	try = -1; /* Disable the timeouts by setting them to -1 */
 	int	repeat_this = -1; /* Congrats to those having 15 years of 
 				     uptime! (You get to break the driver.) */
-	long end_time;
+	unsigned long end_time;
 	struct tty_struct * tty;
 	unsigned long flags;
 	int Modem;
-	int rv =0;
+	int rv = 0;
 	
 	rio_dprintk (RIO_DEBUG_TTY, "port close SysPort %d\n",PortP->PortNum);
 
@@ -620,7 +620,7 @@ riotclose(void  *ptr)
 		if (repeat_this -- <= 0) {
 			rv = -EINTR;
 			rio_dprintk (RIO_DEBUG_TTY, "Waiting for not idle closed broken by signal\n");
-			RIOPreemptiveCmd(p, PortP, FCLOSE ); 
+			RIOPreemptiveCmd(p, PortP, FCLOSE);
 			goto close_end;
 		}
 		rio_dprintk (RIO_DEBUG_TTY, "Calling timeout to flush in closing\n");
@@ -656,14 +656,12 @@ riotclose(void  *ptr)
 		goto close_end;
 	}
 
-	
-
 	/* Can't call RIOShortCommand with the port locked. */
 	rio_spin_unlock_irqrestore(&PortP->portSem, flags);
 
 	if (RIOShortCommand(p, PortP, CLOSE, 1, 0) == RIO_FAIL) {
-	  RIOPreemptiveCmd(p, PortP,FCLOSE);
-	  goto close_end;
+		RIOPreemptiveCmd(p, PortP, FCLOSE);
+		goto close_end;
 	}
 
 	if (!deleted)
@@ -698,7 +696,6 @@ riotclose(void  *ptr)
 */
 	PortP->Config &= ~(RIO_CTSFLOW|RIO_RTSFLOW);
 
-
 #ifdef STATS
 	PortP->Stat.CloseCnt++;
 #endif
diff --git a/drivers/char/rocket.c b/drivers/char/rocket.c
--- a/drivers/char/rocket.c
+++ b/drivers/char/rocket.c
@@ -161,6 +161,64 @@ static Word_t upci_aiop_intr_bits[AIOP_C
 	UPCI_AIOP_INTR_BIT_3
 };
 
+static Byte_t RData[RDATASIZE] = {
+	0x00, 0x09, 0xf6, 0x82,
+	0x02, 0x09, 0x86, 0xfb,
+	0x04, 0x09, 0x00, 0x0a,
+	0x06, 0x09, 0x01, 0x0a,
+	0x08, 0x09, 0x8a, 0x13,
+	0x0a, 0x09, 0xc5, 0x11,
+	0x0c, 0x09, 0x86, 0x85,
+	0x0e, 0x09, 0x20, 0x0a,
+	0x10, 0x09, 0x21, 0x0a,
+	0x12, 0x09, 0x41, 0xff,
+	0x14, 0x09, 0x82, 0x00,
+	0x16, 0x09, 0x82, 0x7b,
+	0x18, 0x09, 0x8a, 0x7d,
+	0x1a, 0x09, 0x88, 0x81,
+	0x1c, 0x09, 0x86, 0x7a,
+	0x1e, 0x09, 0x84, 0x81,
+	0x20, 0x09, 0x82, 0x7c,
+	0x22, 0x09, 0x0a, 0x0a
+};
+
+static Byte_t RRegData[RREGDATASIZE] = {
+	0x00, 0x09, 0xf6, 0x82,	/* 00: Stop Rx processor */
+	0x08, 0x09, 0x8a, 0x13,	/* 04: Tx software flow control */
+	0x0a, 0x09, 0xc5, 0x11,	/* 08: XON char */
+	0x0c, 0x09, 0x86, 0x85,	/* 0c: XANY */
+	0x12, 0x09, 0x41, 0xff,	/* 10: Rx mask char */
+	0x14, 0x09, 0x82, 0x00,	/* 14: Compare/Ignore #0 */
+	0x16, 0x09, 0x82, 0x7b,	/* 18: Compare #1 */
+	0x18, 0x09, 0x8a, 0x7d,	/* 1c: Compare #2 */
+	0x1a, 0x09, 0x88, 0x81,	/* 20: Interrupt #1 */
+	0x1c, 0x09, 0x86, 0x7a,	/* 24: Ignore/Replace #1 */
+	0x1e, 0x09, 0x84, 0x81,	/* 28: Interrupt #2 */
+	0x20, 0x09, 0x82, 0x7c,	/* 2c: Ignore/Replace #2 */
+	0x22, 0x09, 0x0a, 0x0a	/* 30: Rx FIFO Enable */
+};
+
+static CONTROLLER_T sController[CTL_SIZE] = {
+	{-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0},
+	 {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}},
+	{-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0},
+	 {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}},
+	{-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0},
+	 {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}},
+	{-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0},
+	 {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}}
+};
+
+static Byte_t sBitMapClrTbl[8] = {
+	0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f
+};
+
+static Byte_t sBitMapSetTbl[8] = {
+	0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80
+};
+
+static int sClockPrescale = 0x14;
+
 /*
  *  Line number is the ttySIx number (x), the Minor number.  We 
  *  assign them sequentially, starting at zero.  The following 
@@ -177,6 +235,26 @@ static void rmSpeakerReset(CONTROLLER_T 
 static unsigned char GetLineNumber(int ctrl, int aiop, int ch);
 static unsigned char SetLineNumber(int ctrl, int aiop, int ch);
 static void rp_start(struct tty_struct *tty);
+static int sInitChan(CONTROLLER_T * CtlP, CHANNEL_T * ChP, int AiopNum,
+		     int ChanNum);
+static void sSetInterfaceMode(CHANNEL_T * ChP, Byte_t mode);
+static void sFlushRxFIFO(CHANNEL_T * ChP);
+static void sFlushTxFIFO(CHANNEL_T * ChP);
+static void sEnInterrupts(CHANNEL_T * ChP, Word_t Flags);
+static void sDisInterrupts(CHANNEL_T * ChP, Word_t Flags);
+static void sModemReset(CONTROLLER_T * CtlP, int chan, int on);
+static void sPCIModemReset(CONTROLLER_T * CtlP, int chan, int on);
+static int sWriteTxPrioByte(CHANNEL_T * ChP, Byte_t Data);
+static int sPCIInitController(CONTROLLER_T * CtlP, int CtlNum,
+			      ByteIO_t * AiopIOList, int AiopIOListSize,
+			      WordIO_t ConfigIO, int IRQNum, Byte_t Frequency,
+			      int PeriodicOnly, int altChanRingIndicator,
+			      int UPCIRingInd);
+static int sInitController(CONTROLLER_T * CtlP, int CtlNum, ByteIO_t MudbacIO,
+			   ByteIO_t * AiopIOList, int AiopIOListSize,
+			   int IRQNum, Byte_t Frequency, int PeriodicOnly);
+static int sReadAiopID(ByteIO_t io);
+static int sReadAiopNumChan(WordIO_t io);
 
 #ifdef MODULE
 MODULE_AUTHOR("Theodore Ts'o");
@@ -277,7 +355,7 @@ static void rp_do_receive(struct r_port 
 		ToRecv = space;
 
 	if (ToRecv <= 0)
-		return;
+		goto done;
 
 	/*
 	 * if status indicates there are errored characters in the
@@ -359,6 +437,7 @@ static void rp_do_receive(struct r_port 
 	}
 	/*  Push the data up to the tty layer */
 	ld->receive_buf(tty, tty->flip.char_buf, tty->flip.flag_buf, count);
+done:
 	tty_ldisc_deref(ld);
 }
 
@@ -1798,7 +1877,7 @@ static void rp_flush_buffer(struct tty_s
  *  init's aiopic and serial port hardware.
  *  Inputs:  i is the board number (0-n)
  */
-__init int register_PCI(int i, struct pci_dev *dev)
+static __init int register_PCI(int i, struct pci_dev *dev)
 {
 	int num_aiops, aiop, max_num_aiops, num_chan, chan;
 	unsigned int aiopio[MAX_AIOPS_PER_BOARD];
@@ -2453,72 +2532,6 @@ static void rp_cleanup_module(void)
 }
 #endif
 
-#ifndef TRUE
-#define TRUE 1
-#endif
-
-#ifndef FALSE
-#define FALSE 0
-#endif
-
-static Byte_t RData[RDATASIZE] = {
-	0x00, 0x09, 0xf6, 0x82,
-	0x02, 0x09, 0x86, 0xfb,
-	0x04, 0x09, 0x00, 0x0a,
-	0x06, 0x09, 0x01, 0x0a,
-	0x08, 0x09, 0x8a, 0x13,
-	0x0a, 0x09, 0xc5, 0x11,
-	0x0c, 0x09, 0x86, 0x85,
-	0x0e, 0x09, 0x20, 0x0a,
-	0x10, 0x09, 0x21, 0x0a,
-	0x12, 0x09, 0x41, 0xff,
-	0x14, 0x09, 0x82, 0x00,
-	0x16, 0x09, 0x82, 0x7b,
-	0x18, 0x09, 0x8a, 0x7d,
-	0x1a, 0x09, 0x88, 0x81,
-	0x1c, 0x09, 0x86, 0x7a,
-	0x1e, 0x09, 0x84, 0x81,
-	0x20, 0x09, 0x82, 0x7c,
-	0x22, 0x09, 0x0a, 0x0a
-};
-
-static Byte_t RRegData[RREGDATASIZE] = {
-	0x00, 0x09, 0xf6, 0x82,	/* 00: Stop Rx processor */
-	0x08, 0x09, 0x8a, 0x13,	/* 04: Tx software flow control */
-	0x0a, 0x09, 0xc5, 0x11,	/* 08: XON char */
-	0x0c, 0x09, 0x86, 0x85,	/* 0c: XANY */
-	0x12, 0x09, 0x41, 0xff,	/* 10: Rx mask char */
-	0x14, 0x09, 0x82, 0x00,	/* 14: Compare/Ignore #0 */
-	0x16, 0x09, 0x82, 0x7b,	/* 18: Compare #1 */
-	0x18, 0x09, 0x8a, 0x7d,	/* 1c: Compare #2 */
-	0x1a, 0x09, 0x88, 0x81,	/* 20: Interrupt #1 */
-	0x1c, 0x09, 0x86, 0x7a,	/* 24: Ignore/Replace #1 */
-	0x1e, 0x09, 0x84, 0x81,	/* 28: Interrupt #2 */
-	0x20, 0x09, 0x82, 0x7c,	/* 2c: Ignore/Replace #2 */
-	0x22, 0x09, 0x0a, 0x0a	/* 30: Rx FIFO Enable */
-};
-
-CONTROLLER_T sController[CTL_SIZE] = {
-	{-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0},
-	 {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}},
-	{-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0},
-	 {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}},
-	{-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0},
-	 {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}},
-	{-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0},
-	 {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}}
-};
-
-Byte_t sBitMapClrTbl[8] = {
-	0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f
-};
-
-Byte_t sBitMapSetTbl[8] = {
-	0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80
-};
-
-int sClockPrescale = 0x14;
-
 /***************************************************************************
 Function: sInitController
 Purpose:  Initialization of controller global registers and controller
@@ -2554,22 +2567,22 @@ Call:     sInitController(CtlP,CtlNum,Mu
                       FREQ_4HZ - 4 Hertz
                    If IRQNum is set to 0 the Frequency parameter is
                    overidden, it is forced to a value of FREQ_DIS.
-          int PeriodicOnly: TRUE if all interrupts except the periodic
+          int PeriodicOnly: 1 if all interrupts except the periodic
                                interrupt are to be blocked.
-                            FALSE is both the periodic interrupt and
+                            0 is both the periodic interrupt and
                                other channel interrupts are allowed.
                             If IRQNum is set to 0 the PeriodicOnly parameter is
-                               overidden, it is forced to a value of FALSE.
+                               overidden, it is forced to a value of 0.
 Return:   int: Number of AIOPs on the controller, or CTLID_NULL if controller
                initialization failed.
 
 Comments:
           If periodic interrupts are to be disabled but AIOP interrupts
-          are allowed, set Frequency to FREQ_DIS and PeriodicOnly to FALSE.
+          are allowed, set Frequency to FREQ_DIS and PeriodicOnly to 0.
 
           If interrupts are to be completely disabled set IRQNum to 0.
 
-          Setting Frequency to FREQ_DIS and PeriodicOnly to TRUE is an
+          Setting Frequency to FREQ_DIS and PeriodicOnly to 1 is an
           invalid combination.
 
           This function performs initialization of global interrupt modes,
@@ -2589,9 +2602,9 @@ Warnings: No range checking on any of th
           After this function all AIOPs on the controller are disabled,
           they can be enabled with sEnAiop().
 */
-int sInitController(CONTROLLER_T * CtlP, int CtlNum, ByteIO_t MudbacIO,
-		    ByteIO_t * AiopIOList, int AiopIOListSize, int IRQNum,
-		    Byte_t Frequency, int PeriodicOnly)
+static int sInitController(CONTROLLER_T * CtlP, int CtlNum, ByteIO_t MudbacIO,
+			   ByteIO_t * AiopIOList, int AiopIOListSize,
+			   int IRQNum, Byte_t Frequency, int PeriodicOnly)
 {
 	int i;
 	ByteIO_t io;
@@ -2687,22 +2700,22 @@ Call:     sPCIInitController(CtlP,CtlNum
                       FREQ_4HZ - 4 Hertz
                    If IRQNum is set to 0 the Frequency parameter is
                    overidden, it is forced to a value of FREQ_DIS.
-          int PeriodicOnly: TRUE if all interrupts except the periodic
+          int PeriodicOnly: 1 if all interrupts except the periodic
                                interrupt are to be blocked.
-                            FALSE is both the periodic interrupt and
+                            0 is both the periodic interrupt and
                                other channel interrupts are allowed.
                             If IRQNum is set to 0 the PeriodicOnly parameter is
-                               overidden, it is forced to a value of FALSE.
+                               overidden, it is forced to a value of 0.
 Return:   int: Number of AIOPs on the controller, or CTLID_NULL if controller
                initialization failed.
 
 Comments:
           If periodic interrupts are to be disabled but AIOP interrupts
-          are allowed, set Frequency to FREQ_DIS and PeriodicOnly to FALSE.
+          are allowed, set Frequency to FREQ_DIS and PeriodicOnly to 0.
 
           If interrupts are to be completely disabled set IRQNum to 0.
 
-          Setting Frequency to FREQ_DIS and PeriodicOnly to TRUE is an
+          Setting Frequency to FREQ_DIS and PeriodicOnly to 1 is an
           invalid combination.
 
           This function performs initialization of global interrupt modes,
@@ -2722,11 +2735,11 @@ Warnings: No range checking on any of th
           After this function all AIOPs on the controller are disabled,
           they can be enabled with sEnAiop().
 */
-int sPCIInitController(CONTROLLER_T * CtlP, int CtlNum,
-		       ByteIO_t * AiopIOList, int AiopIOListSize,
-		       WordIO_t ConfigIO, int IRQNum, Byte_t Frequency,
-		       int PeriodicOnly, int altChanRingIndicator,
-		       int UPCIRingInd)
+static int sPCIInitController(CONTROLLER_T * CtlP, int CtlNum,
+			      ByteIO_t * AiopIOList, int AiopIOListSize,
+			      WordIO_t ConfigIO, int IRQNum, Byte_t Frequency,
+			      int PeriodicOnly, int altChanRingIndicator,
+			      int UPCIRingInd)
 {
 	int i;
 	ByteIO_t io;
@@ -2784,7 +2797,7 @@ Return:   int: Flag AIOPID_XXXX if a val
 Warnings: No context switches are allowed while executing this function.
 
 */
-int sReadAiopID(ByteIO_t io)
+static int sReadAiopID(ByteIO_t io)
 {
 	Byte_t AiopID;		/* ID byte from AIOP */
 
@@ -2810,7 +2823,7 @@ Comments: The number of channels is dete
           AIOP, otherwise it is an 8 channel.
 Warnings: No context switches are allowed while executing this function.
 */
-int sReadAiopNumChan(WordIO_t io)
+static int sReadAiopNumChan(WordIO_t io)
 {
 	Word_t x;
 	static Byte_t R[4] = { 0x00, 0x00, 0x34, 0x12 };
@@ -2834,15 +2847,15 @@ Call:     sInitChan(CtlP,ChP,AiopNum,Cha
           CHANNEL_T *ChP; Ptr to channel structure
           int AiopNum; AIOP number within controller
           int ChanNum; Channel number within AIOP
-Return:   int: TRUE if initialization succeeded, FALSE if it fails because channel
+Return:   int: 1 if initialization succeeded, 0 if it fails because channel
                number exceeds number of channels available in AIOP.
 Comments: This function must be called before a channel can be used.
 Warnings: No range checking on any of the parameters is done.
 
           No context switches are allowed while executing this function.
 */
-int sInitChan(CONTROLLER_T * CtlP, CHANNEL_T * ChP, int AiopNum,
-	      int ChanNum)
+static int sInitChan(CONTROLLER_T * CtlP, CHANNEL_T * ChP, int AiopNum,
+		     int ChanNum)
 {
 	int i;
 	WordIO_t AiopIO;
@@ -2853,7 +2866,7 @@ int sInitChan(CONTROLLER_T * CtlP, CHANN
 	int brd9600;
 
 	if (ChanNum >= CtlP->AiopNumChan[AiopNum])
-		return (FALSE);	/* exceeds num chans in AIOP */
+		return 0;	/* exceeds num chans in AIOP */
 
 	/* Channel, AIOP, and controller identifiers */
 	ChP->CtlP = CtlP;
@@ -2968,7 +2981,7 @@ int sInitChan(CONTROLLER_T * CtlP, CHANN
 	ChP->TxPrioBuf = ChOff + _TXP_BUF;
 	sEnRxProcessor(ChP);	/* start the Rx processor */
 
-	return (TRUE);
+	return 1;
 }
 
 /***************************************************************************
@@ -2989,7 +3002,7 @@ Warnings: No context switches are allowe
           After calling this function a delay of 4 uS is required to ensure
           that the receive processor is no longer processing this channel.
 */
-void sStopRxProcessor(CHANNEL_T * ChP)
+static void sStopRxProcessor(CHANNEL_T * ChP)
 {
 	Byte_t R[4];
 
@@ -3014,18 +3027,18 @@ Comments: To prevent data from being enq
           this function.
 Warnings: No context switches are allowed while executing this function.
 */
-void sFlushRxFIFO(CHANNEL_T * ChP)
+static void sFlushRxFIFO(CHANNEL_T * ChP)
 {
 	int i;
 	Byte_t Ch;		/* channel number within AIOP */
-	int RxFIFOEnabled;	/* TRUE if Rx FIFO enabled */
+	int RxFIFOEnabled;	/* 1 if Rx FIFO enabled */
 
 	if (sGetRxCnt(ChP) == 0)	/* Rx FIFO empty */
 		return;		/* don't need to flush */
 
-	RxFIFOEnabled = FALSE;
+	RxFIFOEnabled = 0;
 	if (ChP->R[0x32] == 0x08) {	/* Rx FIFO is enabled */
-		RxFIFOEnabled = TRUE;
+		RxFIFOEnabled = 1;
 		sDisRxFIFO(ChP);	/* disable it */
 		for (i = 0; i < 2000 / 200; i++)	/* delay 2 uS to allow proc to disable FIFO */
 			sInB(ChP->IntChan);	/* depends on bus i/o timing */
@@ -3056,18 +3069,18 @@ Comments: To prevent data from being enq
           this function.
 Warnings: No context switches are allowed while executing this function.
 */
-void sFlushTxFIFO(CHANNEL_T * ChP)
+static void sFlushTxFIFO(CHANNEL_T * ChP)
 {
 	int i;
 	Byte_t Ch;		/* channel number within AIOP */
-	int TxEnabled;		/* TRUE if transmitter enabled */
+	int TxEnabled;		/* 1 if transmitter enabled */
 
 	if (sGetTxCnt(ChP) == 0)	/* Tx FIFO empty */
 		return;		/* don't need to flush */
 
-	TxEnabled = FALSE;
+	TxEnabled = 0;
 	if (ChP->TxControl[3] & TX_ENABLE) {
-		TxEnabled = TRUE;
+		TxEnabled = 1;
 		sDisTransmit(ChP);	/* disable transmitter */
 	}
 	sStopRxProcessor(ChP);	/* stop Rx processor */
@@ -3096,7 +3109,7 @@ Comments: The priority byte is transmitt
 
 Warnings: No context switches are allowed while executing this function.
 */
-int sWriteTxPrioByte(CHANNEL_T * ChP, Byte_t Data)
+static int sWriteTxPrioByte(CHANNEL_T * ChP, Byte_t Data)
 {
 	Byte_t DWBuf[4];	/* buffer for double word writes */
 	Word_t *WordPtr;	/* must be far because Win SS != DS */
@@ -3158,7 +3171,7 @@ Comments: If an interrupt enable flag is
           enable channel interrupts.  This would allow the global interrupt
           status register to be used to determine which AIOPs need service.
 */
-void sEnInterrupts(CHANNEL_T * ChP, Word_t Flags)
+static void sEnInterrupts(CHANNEL_T * ChP, Word_t Flags)
 {
 	Byte_t Mask;		/* Interrupt Mask Register */
 
@@ -3202,7 +3215,7 @@ Comments: If an interrupt flag is set in
           this channel's bit from being set in the AIOP's Interrupt Channel
           Register.
 */
-void sDisInterrupts(CHANNEL_T * ChP, Word_t Flags)
+static void sDisInterrupts(CHANNEL_T * ChP, Word_t Flags)
 {
 	Byte_t Mask;		/* Interrupt Mask Register */
 
@@ -3218,7 +3231,7 @@ void sDisInterrupts(CHANNEL_T * ChP, Wor
 	}
 }
 
-void sSetInterfaceMode(CHANNEL_T * ChP, Byte_t mode)
+static void sSetInterfaceMode(CHANNEL_T * ChP, Byte_t mode)
 {
 	sOutB(ChP->CtlP->AiopIO[2], (mode & 0x18) | ChP->ChanNum);
 }
@@ -3227,7 +3240,7 @@ void sSetInterfaceMode(CHANNEL_T * ChP, 
  *  Not an official SSCI function, but how to reset RocketModems.
  *  ISA bus version
  */
-void sModemReset(CONTROLLER_T * CtlP, int chan, int on)
+static void sModemReset(CONTROLLER_T * CtlP, int chan, int on)
 {
 	ByteIO_t addr;
 	Byte_t val;
@@ -3252,7 +3265,7 @@ void sModemReset(CONTROLLER_T * CtlP, in
  *  Not an official SSCI function, but how to reset RocketModems.
  *  PCI bus version
  */
-void sPCIModemReset(CONTROLLER_T * CtlP, int chan, int on)
+static void sPCIModemReset(CONTROLLER_T * CtlP, int chan, int on)
 {
 	ByteIO_t addr;
 
diff --git a/drivers/char/rocket_int.h b/drivers/char/rocket_int.h
--- a/drivers/char/rocket_int.h
+++ b/drivers/char/rocket_int.h
@@ -1130,46 +1130,6 @@ Warnings: This function writes the data 
 */
 #define sWriteTxByte(IO,DATA) sOutB(IO,DATA)
 
-int sInitController(CONTROLLER_T * CtlP,
-		    int CtlNum,
-		    ByteIO_t MudbacIO,
-		    ByteIO_t * AiopIOList,
-		    int AiopIOListSize,
-		    int IRQNum, Byte_t Frequency, int PeriodicOnly);
-
-int sPCIInitController(CONTROLLER_T * CtlP,
-		       int CtlNum,
-		       ByteIO_t * AiopIOList,
-		       int AiopIOListSize,
-		       WordIO_t ConfigIO,
-		       int IRQNum,
-		       Byte_t Frequency,
-		       int PeriodicOnly,
-		       int altChanRingIndicator, int UPCIRingInd);
-
-int sReadAiopID(ByteIO_t io);
-int sReadAiopNumChan(WordIO_t io);
-int sInitChan(CONTROLLER_T * CtlP,
-	      CHANNEL_T * ChP, int AiopNum, int ChanNum);
-Byte_t sGetRxErrStatus(CHANNEL_T * ChP);
-void sStopRxProcessor(CHANNEL_T * ChP);
-void sStopSWInFlowCtl(CHANNEL_T * ChP);
-void sFlushRxFIFO(CHANNEL_T * ChP);
-void sFlushTxFIFO(CHANNEL_T * ChP);
-int sWriteTxPrioByte(CHANNEL_T * ChP, Byte_t Data);
-void sEnInterrupts(CHANNEL_T * ChP, Word_t Flags);
-void sDisInterrupts(CHANNEL_T * ChP, Word_t Flags);
-void sModemReset(CONTROLLER_T * CtlP, int chan, int on);
-void sPCIModemReset(CONTROLLER_T * CtlP, int chan, int on);
-void sSetInterfaceMode(CHANNEL_T * ChP, Byte_t mode);
-
-extern Byte_t R[RDATASIZE];
-extern CONTROLLER_T sController[CTL_SIZE];
-extern Byte_t sIRQMap[16];
-extern Byte_t sBitMapClrTbl[8];
-extern Byte_t sBitMapSetTbl[8];
-extern int sClockPrescale;
-
 /*
  * Begin Linux specific definitions for the Rocketport driver
  *
diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c
--- a/drivers/char/rtc.c
+++ b/drivers/char/rtc.c
@@ -78,6 +78,7 @@
 #include <linux/sysctl.h>
 #include <linux/wait.h>
 #include <linux/bcd.h>
+#include <linux/delay.h>
 
 #include <asm/current.h>
 #include <asm/uaccess.h>
@@ -894,7 +895,6 @@ static int __init rtc_init(void)
 	struct proc_dir_entry *ent;
 #if defined(__alpha__) || defined(__mips__)
 	unsigned int year, ctrl;
-	unsigned long uip_watchdog;
 	char *guess = NULL;
 #endif
 #ifdef __sparc__
@@ -1000,12 +1000,8 @@ no_irq:
 	/* Each operating system on an Alpha uses its own epoch.
 	   Let's try to guess which one we are using now. */
 	
-	uip_watchdog = jiffies;
 	if (rtc_is_updating() != 0)
-		while (jiffies - uip_watchdog < 2*HZ/100) { 
-			barrier();
-			cpu_relax();
-		}
+		msleep(20);
 	
 	spin_lock_irq(&rtc_lock);
 	year = CMOS_READ(RTC_YEAR);
@@ -1221,7 +1217,7 @@ void rtc_get_rtc_time(struct rtc_time *r
 
 	/*
 	 * read RTC once any update in progress is done. The update
-	 * can take just over 2ms. We wait 10 to 20ms. There is no need to
+	 * can take just over 2ms. We wait 20ms. There is no need to
 	 * to poll-wait (up to 1s - eeccch) for the falling edge of RTC_UIP.
 	 * If you need to know *exactly* when a second has started, enable
 	 * periodic update complete interrupts, (via ioctl) and then 
@@ -1229,11 +1225,10 @@ void rtc_get_rtc_time(struct rtc_time *r
 	 * Once the read clears, read the RTC time (again via ioctl). Easy.
 	 */
 
-	if (rtc_is_updating() != 0)
-		while (jiffies - uip_watchdog < 2*HZ/100) {
-			barrier();
-			cpu_relax();
-		}
+	while (rtc_is_updating() != 0 && jiffies - uip_watchdog < 2*HZ/100) {
+		barrier();
+		cpu_relax();
+	}
 
 	/*
 	 * Only the values that we read from the RTC are set. We leave
diff --git a/drivers/char/snsc.c b/drivers/char/snsc.c
--- a/drivers/char/snsc.c
+++ b/drivers/char/snsc.c
@@ -357,6 +357,8 @@ static struct file_operations scdrv_fops
 	.release =	scdrv_release,
 };
 
+static struct class *snsc_class;
+
 /*
  * scdrv_init
  *
@@ -372,7 +374,6 @@ scdrv_init(void)
 	char *devnamep;
 	struct sysctl_data_s *scd;
 	void *salbuf;
-	struct class_simple *snsc_class;
 	dev_t first_dev, dev;
 	nasid_t event_nasid = ia64_sn_get_console_nasid();
 
@@ -382,7 +383,7 @@ scdrv_init(void)
 		       __FUNCTION__);
 		return -ENODEV;
 	}
-	snsc_class = class_simple_create(THIS_MODULE, SYSCTL_BASENAME);
+	snsc_class = class_create(THIS_MODULE, SYSCTL_BASENAME);
 
 	for (cnode = 0; cnode < numionodes; cnode++) {
 			geoid = cnodeid_get_geoid(cnode);
@@ -436,7 +437,7 @@ scdrv_init(void)
 				continue;
 			}
 
-			class_simple_device_add(snsc_class, dev, NULL,
+			class_device_create(snsc_class, dev, NULL,
 						"%s", devname);
 
 			ia64_sn_irtr_intr_enable(scd->scd_nasid,
diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c
--- a/drivers/char/sonypi.c
+++ b/drivers/char/sonypi.c
@@ -439,6 +439,11 @@ static struct {
 	{ 0, 0 },
 };
 
+struct sonypi_keypress {
+	struct input_dev *dev;
+	int key;
+};
+
 static struct sonypi_device {
 	struct pci_dev *dev;
 	struct platform_device *pdev;
@@ -710,22 +715,61 @@ static void sonypi_setbluetoothpower(u8 
 
 static void input_keyrelease(void *data)
 {
-	struct input_dev *input_dev;
-	int key;
-
-	while (1) {
-		if (kfifo_get(sonypi_device.input_fifo,
-			      (unsigned char *)&input_dev,
-			      sizeof(input_dev)) != sizeof(input_dev))
-			return;
-		if (kfifo_get(sonypi_device.input_fifo,
-			      (unsigned char *)&key,
-			      sizeof(key)) != sizeof(key))
-			return;
+	struct sonypi_keypress kp;
 
+	while (kfifo_get(sonypi_device.input_fifo, (unsigned char *)&kp,
+			 sizeof(kp)) == sizeof(kp)) {
 		msleep(10);
-		input_report_key(input_dev, key, 0);
-		input_sync(input_dev);
+		input_report_key(kp.dev, kp.key, 0);
+		input_sync(kp.dev);
+	}
+}
+
+static void sonypi_report_input_event(u8 event)
+{
+	struct input_dev *jog_dev = &sonypi_device.input_jog_dev;
+	struct input_dev *key_dev = &sonypi_device.input_key_dev;
+	struct sonypi_keypress kp = { NULL };
+	int i;
+
+	switch (event) {
+	case SONYPI_EVENT_JOGDIAL_UP:
+	case SONYPI_EVENT_JOGDIAL_UP_PRESSED:
+		input_report_rel(jog_dev, REL_WHEEL, 1);
+		input_sync(jog_dev);
+		break;
+
+	case SONYPI_EVENT_JOGDIAL_DOWN:
+	case SONYPI_EVENT_JOGDIAL_DOWN_PRESSED:
+		input_report_rel(jog_dev, REL_WHEEL, -1);
+		input_sync(jog_dev);
+		break;
+
+	case SONYPI_EVENT_JOGDIAL_PRESSED:
+		kp.key = BTN_MIDDLE;
+		kp.dev = jog_dev;
+		break;
+
+	case SONYPI_EVENT_FNKEY_RELEASED:
+		/* Nothing, not all VAIOs generate this event */
+		break;
+
+	default:
+		for (i = 0; sonypi_inputkeys[i].sonypiev; i++)
+			if (event == sonypi_inputkeys[i].sonypiev) {
+				kp.dev = key_dev;
+				kp.key = sonypi_inputkeys[i].inputev;
+				break;
+			}
+		break;
+	}
+
+	if (kp.dev) {
+		input_report_key(kp.dev, kp.key, 1);
+		input_sync(kp.dev);
+		kfifo_put(sonypi_device.input_fifo,
+			  (unsigned char *)&kp, sizeof(kp));
+		schedule_work(&sonypi_device.input_work);
 	}
 }
 
@@ -768,51 +812,8 @@ found:
 		printk(KERN_INFO
 		       "sonypi: event port1=0x%02x,port2=0x%02x\n", v1, v2);
 
-	if (useinput) {
-		struct input_dev *input_jog_dev = &sonypi_device.input_jog_dev;
-		struct input_dev *input_key_dev = &sonypi_device.input_key_dev;
-		switch (event) {
-		case SONYPI_EVENT_JOGDIAL_UP:
-		case SONYPI_EVENT_JOGDIAL_UP_PRESSED:
-			input_report_rel(input_jog_dev, REL_WHEEL, 1);
-			break;
-		case SONYPI_EVENT_JOGDIAL_DOWN:
-		case SONYPI_EVENT_JOGDIAL_DOWN_PRESSED:
-			input_report_rel(input_jog_dev, REL_WHEEL, -1);
-			break;
-		case SONYPI_EVENT_JOGDIAL_PRESSED: {
-			int key = BTN_MIDDLE;
-			input_report_key(input_jog_dev, key, 1);
-			kfifo_put(sonypi_device.input_fifo,
-				  (unsigned char *)&input_jog_dev,
-				  sizeof(input_jog_dev));
-			kfifo_put(sonypi_device.input_fifo,
-				  (unsigned char *)&key, sizeof(key));
-			break;
-		}
-		case SONYPI_EVENT_FNKEY_RELEASED:
-			/* Nothing, not all VAIOs generate this event */
-			break;
-		}
-		input_sync(input_jog_dev);
-
-		for (i = 0; sonypi_inputkeys[i].sonypiev; i++) {
-			int key;
-
-			if (event != sonypi_inputkeys[i].sonypiev)
-				continue;
-
-			key = sonypi_inputkeys[i].inputev;
-			input_report_key(input_key_dev, key, 1);
-			kfifo_put(sonypi_device.input_fifo,
-				  (unsigned char *)&input_key_dev,
-				  sizeof(input_key_dev));
-			kfifo_put(sonypi_device.input_fifo,
-				  (unsigned char *)&key, sizeof(key));
-		}
-		input_sync(input_key_dev);
-		schedule_work(&sonypi_device.input_work);
-	}
+	if (useinput)
+		sonypi_report_input_event(event);
 
 	kfifo_put(sonypi_device.fifo, (unsigned char *)&event, sizeof(event));
 	kill_fasync(&sonypi_device.fifo_async, SIGIO, POLL_IN);
@@ -1227,14 +1228,7 @@ static int __devinit sonypi_probe(void)
 		sonypi_device.input_jog_dev.keybit[LONG(BTN_MOUSE)] =
 			BIT(BTN_MIDDLE);
 		sonypi_device.input_jog_dev.relbit[0] = BIT(REL_WHEEL);
-		sonypi_device.input_jog_dev.name =
-			kmalloc(sizeof(SONYPI_JOG_INPUTNAME), GFP_KERNEL);
-		if (!sonypi_device.input_jog_dev.name) {
-			printk(KERN_ERR "sonypi: kmalloc failed\n");
-			ret = -ENOMEM;
-			goto out_inkmallocinput1;
-		}
-		sprintf(sonypi_device.input_jog_dev.name, SONYPI_JOG_INPUTNAME);
+		sonypi_device.input_jog_dev.name = SONYPI_JOG_INPUTNAME;
 		sonypi_device.input_jog_dev.id.bustype = BUS_ISA;
 		sonypi_device.input_jog_dev.id.vendor = PCI_VENDOR_ID_SONY;
 
@@ -1248,14 +1242,7 @@ static int __devinit sonypi_probe(void)
 			if (sonypi_inputkeys[i].inputev)
 				set_bit(sonypi_inputkeys[i].inputev,
 					sonypi_device.input_key_dev.keybit);
-		sonypi_device.input_key_dev.name =
-			kmalloc(sizeof(SONYPI_KEY_INPUTNAME), GFP_KERNEL);
-		if (!sonypi_device.input_key_dev.name) {
-			printk(KERN_ERR "sonypi: kmalloc failed\n");
-			ret = -ENOMEM;
-			goto out_inkmallocinput2;
-		}
-		sprintf(sonypi_device.input_key_dev.name, SONYPI_KEY_INPUTNAME);
+		sonypi_device.input_key_dev.name = SONYPI_KEY_INPUTNAME;
 		sonypi_device.input_key_dev.id.bustype = BUS_ISA;
 		sonypi_device.input_key_dev.id.vendor = PCI_VENDOR_ID_SONY;
 
@@ -1313,11 +1300,7 @@ out_platformdev:
 	kfifo_free(sonypi_device.input_fifo);
 out_infifo:
 	input_unregister_device(&sonypi_device.input_key_dev);
-	kfree(sonypi_device.input_key_dev.name);
-out_inkmallocinput2:
 	input_unregister_device(&sonypi_device.input_jog_dev);
-	kfree(sonypi_device.input_jog_dev.name);
-out_inkmallocinput1:
 	free_irq(sonypi_device.irq, sonypi_irq);
 out_reqirq:
 	release_region(sonypi_device.ioport1, sonypi_device.region_size);
@@ -1337,13 +1320,14 @@ static void __devexit sonypi_remove(void
 {
 	sonypi_disable();
 
+	synchronize_sched();  /* Allow sonypi interrupt to complete. */
+	flush_scheduled_work();
+
 	platform_device_unregister(sonypi_device.pdev);
 
 	if (useinput) {
 		input_unregister_device(&sonypi_device.input_key_dev);
-		kfree(sonypi_device.input_key_dev.name);
 		input_unregister_device(&sonypi_device.input_jog_dev);
-		kfree(sonypi_device.input_jog_dev.name);
 		kfifo_free(sonypi_device.input_fifo);
 	}
 
diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c
--- a/drivers/char/stallion.c
+++ b/drivers/char/stallion.c
@@ -719,7 +719,7 @@ static struct file_operations	stl_fsiome
 
 /*****************************************************************************/
 
-static struct class_simple *stallion_class;
+static struct class *stallion_class;
 
 /*
  *	Loadable module initialization stuff.
@@ -777,13 +777,13 @@ static void __exit stallion_module_exit(
 	}
 	for (i = 0; i < 4; i++) {
 		devfs_remove("staliomem/%d", i);
-		class_simple_device_remove(MKDEV(STL_SIOMEMMAJOR, i));
+		class_device_destroy(stallion_class, MKDEV(STL_SIOMEMMAJOR, i));
 	}
 	devfs_remove("staliomem");
 	if ((i = unregister_chrdev(STL_SIOMEMMAJOR, "staliomem")))
 		printk("STALLION: failed to un-register serial memory device, "
 			"errno=%d\n", -i);
-	class_simple_destroy(stallion_class);
+	class_destroy(stallion_class);
 
 	if (stl_tmpwritebuf != (char *) NULL)
 		kfree(stl_tmpwritebuf);
@@ -3090,12 +3090,12 @@ static int __init stl_init(void)
 		printk("STALLION: failed to register serial board device\n");
 	devfs_mk_dir("staliomem");
 
-	stallion_class = class_simple_create(THIS_MODULE, "staliomem");
+	stallion_class = class_create(THIS_MODULE, "staliomem");
 	for (i = 0; i < 4; i++) {
 		devfs_mk_cdev(MKDEV(STL_SIOMEMMAJOR, i),
 				S_IFCHR|S_IRUSR|S_IWUSR,
 				"staliomem/%d", i);
-		class_simple_device_add(stallion_class, MKDEV(STL_SIOMEMMAJOR, i), NULL, "staliomem%d", i);
+		class_device_create(stallion_class, MKDEV(STL_SIOMEMMAJOR, i), NULL, "staliomem%d", i);
 	}
 
 	stl_serial->owner = THIS_MODULE;
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c
--- a/drivers/char/sysrq.c
+++ b/drivers/char/sysrq.c
@@ -35,6 +35,7 @@
 #include <linux/spinlock.h>
 #include <linux/vt_kern.h>
 #include <linux/workqueue.h>
+#include <linux/kexec.h>
 
 #include <asm/ptrace.h>
 
@@ -94,12 +95,27 @@ static struct sysrq_key_op sysrq_unraw_o
 };
 #endif /* CONFIG_VT */
 
+#ifdef CONFIG_KEXEC
+/* crashdump sysrq handler */
+static void sysrq_handle_crashdump(int key, struct pt_regs *pt_regs,
+				struct tty_struct *tty)
+{
+	crash_kexec(pt_regs);
+}
+static struct sysrq_key_op sysrq_crashdump_op = {
+	.handler	= sysrq_handle_crashdump,
+	.help_msg	= "Crashdump",
+	.action_msg	= "Trigger a crashdump",
+	.enable_mask	= SYSRQ_ENABLE_DUMP,
+};
+#endif
+
 /* reboot sysrq handler */
 static void sysrq_handle_reboot(int key, struct pt_regs *pt_regs,
 				struct tty_struct *tty) 
 {
 	local_irq_enable();
-	machine_restart(NULL);
+	emergency_restart();
 }
 
 static struct sysrq_key_op sysrq_reboot_op = {
@@ -212,7 +228,7 @@ static struct sysrq_key_op sysrq_term_op
 
 static void moom_callback(void *ignored)
 {
-	out_of_memory(GFP_KERNEL);
+	out_of_memory(GFP_KERNEL, 0);
 }
 
 static DECLARE_WORK(moom_work, moom_callback, NULL);
@@ -273,8 +289,12 @@ static struct sysrq_key_op *sysrq_key_ta
 		 it is handled specially on the sparc
 		 and will never arrive */
 /* b */	&sysrq_reboot_op,
-/* c */ NULL,
-/* d */	NULL,
+#ifdef CONFIG_KEXEC
+/* c */ &sysrq_crashdump_op,
+#else
+/* c */	NULL,
+#endif
+/* d */ NULL,
 /* e */	&sysrq_term_op,
 /* f */	&sysrq_moom_op,
 /* g */	NULL,
diff --git a/drivers/char/tb0219.c b/drivers/char/tb0219.c
--- a/drivers/char/tb0219.c
+++ b/drivers/char/tb0219.c
@@ -24,6 +24,8 @@
 
 #include <asm/io.h>
 #include <asm/reboot.h>
+#include <asm/vr41xx/giu.h>
+#include <asm/vr41xx/tb0219.h>
 
 MODULE_AUTHOR("Yoichi Yuasa <yuasa@hh.iij4u.or.jp>");
 MODULE_DESCRIPTION("TANBAC TB0219 base board driver");
@@ -266,6 +268,21 @@ static void tb0219_restart(char *command
 	tb0219_write(TB0219_RESET, 0);
 }
 
+static void tb0219_pci_irq_init(void)
+{
+	/* PCI Slot 1 */
+	vr41xx_set_irq_trigger(TB0219_PCI_SLOT1_PIN, IRQ_TRIGGER_LEVEL, IRQ_SIGNAL_THROUGH);
+	vr41xx_set_irq_level(TB0219_PCI_SLOT1_PIN, IRQ_LEVEL_LOW);
+
+	/* PCI Slot 2 */
+	vr41xx_set_irq_trigger(TB0219_PCI_SLOT2_PIN, IRQ_TRIGGER_LEVEL, IRQ_SIGNAL_THROUGH);
+	vr41xx_set_irq_level(TB0219_PCI_SLOT2_PIN, IRQ_LEVEL_LOW);
+
+	/* PCI Slot 3 */
+	vr41xx_set_irq_trigger(TB0219_PCI_SLOT3_PIN, IRQ_TRIGGER_LEVEL, IRQ_SIGNAL_THROUGH);
+	vr41xx_set_irq_level(TB0219_PCI_SLOT3_PIN, IRQ_LEVEL_LOW);
+}
+
 static int tb0219_probe(struct device *dev)
 {
 	int retval;
@@ -292,6 +309,8 @@ static int tb0219_probe(struct device *d
 	old_machine_restart = _machine_restart;
 	_machine_restart = tb0219_restart;
 
+	tb0219_pci_irq_init();
+
 	if (major == 0) {
 		major = retval;
 		printk(KERN_INFO "TB0219: major number %d\n", major);
diff --git a/drivers/char/tipar.c b/drivers/char/tipar.c
--- a/drivers/char/tipar.c
+++ b/drivers/char/tipar.c
@@ -90,7 +90,7 @@ static int timeout = TIMAXTIME;	/* timeo
 static unsigned int tp_count;	/* tipar count */
 static unsigned long opened;	/* opened devices */
 
-static struct class_simple *tipar_class;
+static struct class *tipar_class;
 
 /* --- macros for parport access -------------------------------------- */
 
@@ -396,7 +396,7 @@ static struct file_operations tipar_fops
 static int __init
 tipar_setup(char *str)
 {
-	int ints[2];
+	int ints[3];
 
 	str = get_options(str, ARRAY_SIZE(ints), ints);
 
@@ -436,7 +436,7 @@ tipar_register(int nr, struct parport *p
 		goto out;
 	}
 
-	class_simple_device_add(tipar_class, MKDEV(TIPAR_MAJOR,
+	class_device_create(tipar_class, MKDEV(TIPAR_MAJOR,
 			TIPAR_MINOR + nr), NULL, "par%d", nr);
 	/* Use devfs, tree: /dev/ticables/par/[0..2] */
 	err = devfs_mk_cdev(MKDEV(TIPAR_MAJOR, TIPAR_MINOR + nr),
@@ -458,8 +458,8 @@ tipar_register(int nr, struct parport *p
 	goto out;
 
 out_class:
-	class_simple_device_remove(MKDEV(TIPAR_MAJOR, TIPAR_MINOR + nr));
-	class_simple_destroy(tipar_class);
+	class_device_destroy(tipar_class, MKDEV(TIPAR_MAJOR, TIPAR_MINOR + nr));
+	class_destroy(tipar_class);
 out:
 	return err;
 }
@@ -505,7 +505,7 @@ tipar_init_module(void)
 	/* Use devfs with tree: /dev/ticables/par/[0..2] */
 	devfs_mk_dir("ticables/par");
 
-	tipar_class = class_simple_create(THIS_MODULE, "ticables");
+	tipar_class = class_create(THIS_MODULE, "ticables");
 	if (IS_ERR(tipar_class)) {
 		err = PTR_ERR(tipar_class);
 		goto out_chrdev;
@@ -539,10 +539,10 @@ tipar_cleanup_module(void)
 		if (table[i].dev == NULL)
 			continue;
 		parport_unregister_device(table[i].dev);
-		class_simple_device_remove(MKDEV(TIPAR_MAJOR, i));
+		class_device_destroy(tipar_class, MKDEV(TIPAR_MAJOR, i));
 		devfs_remove("ticables/par/%d", i);
 	}
-	class_simple_destroy(tipar_class);
+	class_destroy(tipar_class);
 	devfs_remove("ticables/par");
 
 	pr_info("tipar: module unloaded\n");
diff --git a/drivers/char/toshiba.c b/drivers/char/toshiba.c
--- a/drivers/char/toshiba.c
+++ b/drivers/char/toshiba.c
@@ -73,16 +73,20 @@
 
 #define TOSH_MINOR_DEV 181
 
-static int tosh_id = 0x0000;
-static int tosh_bios = 0x0000;
-static int tosh_date = 0x0000;
-static int tosh_sci = 0x0000;
-static int tosh_fan = 0;
-
-static int tosh_fn = 0;
-
-module_param(tosh_fn, int, 0);
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Jonathan Buzzard <jonathan@buzzard.org.uk>");
+MODULE_DESCRIPTION("Toshiba laptop SMM driver");
+MODULE_SUPPORTED_DEVICE("toshiba");
 
+static int tosh_fn;
+module_param_named(fn, tosh_fn, int, 0);
+MODULE_PARM_DESC(fn, "User specified Fn key detection port");
+
+static int tosh_id;
+static int tosh_bios;
+static int tosh_date;
+static int tosh_sci;
+static int tosh_fan;
 
 static int tosh_ioctl(struct inode *, struct file *, unsigned int,
 	unsigned long);
@@ -359,7 +363,7 @@ static int tosh_get_machine_id(void)
 	unsigned long address;
 
 	id = (0x100*(int) isa_readb(0xffffe))+((int) isa_readb(0xffffa));
-	
+
 	/* do we have a SCTTable machine identication number on our hands */
 
 	if (id==0xfc2f) {
@@ -424,7 +428,7 @@ static int tosh_probe(void)
 	}
 
 	/* call the Toshiba SCI support check routine */
-	
+
 	regs.eax = 0xf0f0;
 	regs.ebx = 0x0000;
 	regs.ecx = 0x0000;
@@ -440,7 +444,7 @@ static int tosh_probe(void)
 	/* if we get this far then we are running on a Toshiba (probably)! */
 
 	tosh_sci = regs.edx & 0xffff;
-	
+
 	/* next get the machine ID of the current laptop */
 
 	tosh_id = tosh_get_machine_id();
@@ -475,16 +479,15 @@ static int tosh_probe(void)
 	return 0;
 }
 
-int __init tosh_init(void)
+static int __init toshiba_init(void)
 {
 	int retval;
 	/* are we running on a Toshiba laptop */
 
-	if (tosh_probe()!=0)
-		return -EIO;
+	if (tosh_probe())
+		return -ENODEV;
 
-	printk(KERN_INFO "Toshiba System Managment Mode driver v"
-		TOSH_VERSION"\n");
+	printk(KERN_INFO "Toshiba System Managment Mode driver v" TOSH_VERSION "\n");
 
 	/* set the port to use for Fn status if not specified as a parameter */
 	if (tosh_fn==0x00)
@@ -492,12 +495,12 @@ int __init tosh_init(void)
 
 	/* register the device file */
 	retval = misc_register(&tosh_device);
-	if(retval < 0)
+	if (retval < 0)
 		return retval;
 
 #ifdef CONFIG_PROC_FS
 	/* register the proc entry */
-	if(create_proc_info_entry("toshiba", 0, NULL, tosh_get_info) == NULL){
+	if (create_proc_info_entry("toshiba", 0, NULL, tosh_get_info) == NULL) {
 		misc_deregister(&tosh_device);
 		return -ENOMEM;
 	}
@@ -506,27 +509,12 @@ int __init tosh_init(void)
 	return 0;
 }
 
-#ifdef MODULE
-int init_module(void)
+static void __exit toshiba_exit(void)
 {
-	return tosh_init();
-}
-
-void cleanup_module(void)
-{
-	/* remove the proc entry */
-
 	remove_proc_entry("toshiba", NULL);
-
-	/* unregister the device file */
-
 	misc_deregister(&tosh_device);
 }
-#endif
 
-MODULE_LICENSE("GPL");
-MODULE_PARM_DESC(tosh_fn, "User specified Fn key detection port");
-MODULE_AUTHOR("Jonathan Buzzard <jonathan@buzzard.org.uk>");
-MODULE_DESCRIPTION("Toshiba laptop SMM driver");
-MODULE_SUPPORTED_DEVICE("toshiba");
+module_init(toshiba_init);
+module_exit(toshiba_exit);
 
diff --git a/drivers/char/tpm/Kconfig b/drivers/char/tpm/Kconfig
--- a/drivers/char/tpm/Kconfig
+++ b/drivers/char/tpm/Kconfig
@@ -17,6 +17,8 @@ config TCG_TPM
 	  obtained at: <http://sourceforge.net/projects/trousers>.  To 
 	  compile this driver as a module, choose M here; the module 
 	  will be called tpm. If unsure, say N.
+	  Note: For more TPM drivers enable CONFIG_PNP, CONFIG_ACPI_BUS
+	  and CONFIG_PNPACPI.
 
 config TCG_NSC
 	tristate "National Semiconductor TPM Interface"
@@ -35,5 +37,17 @@ config TCG_ATMEL
 	  will be accessible from within Linux.  To compile this driver 
 	  as a module, choose M here; the module will be called tpm_atmel.
 
+config TCG_INFINEON
+	tristate "Infineon Technologies TPM Interface"
+	depends on TCG_TPM && PNPACPI
+	---help---
+	  If you have a TPM security chip from Infineon Technologies
+	  (either SLD 9630 TT 1.1 or SLB 9635 TT 1.2) say Yes and it
+	  will be accessible from within Linux.
+	  To compile this driver as a module, choose M here; the module
+	  will be called tpm_infineon.
+	  Further information on this driver and the supported hardware
+	  can be found at http://www.prosec.rub.de/tpm
+
 endmenu
 
diff --git a/drivers/char/tpm/Makefile b/drivers/char/tpm/Makefile
--- a/drivers/char/tpm/Makefile
+++ b/drivers/char/tpm/Makefile
@@ -4,4 +4,4 @@
 obj-$(CONFIG_TCG_TPM) += tpm.o
 obj-$(CONFIG_TCG_NSC) += tpm_nsc.o
 obj-$(CONFIG_TCG_ATMEL) += tpm_atmel.o
-
+obj-$(CONFIG_TCG_INFINEON) += tpm_infineon.o
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c
--- a/drivers/char/tpm/tpm.c
+++ b/drivers/char/tpm/tpm.c
@@ -19,7 +19,7 @@
  * 
  * Note, the TPM chip is not interrupt driven (only polling)
  * and can have very long timeouts (minutes!). Hence the unusual
- * calls to schedule_timeout.
+ * calls to msleep.
  *
  */
 
@@ -28,19 +28,16 @@
 #include <linux/spinlock.h>
 #include "tpm.h"
 
-#define	TPM_MINOR			224	/* officially assigned */
-
-#define	TPM_BUFSIZE			2048
-
-/* PCI configuration addresses */
-#define	PCI_GEN_PMCON_1			0xA0
-#define	PCI_GEN1_DEC			0xE4
-#define	PCI_LPC_EN			0xE6
-#define	PCI_GEN2_DEC			0xEC
+enum tpm_const {
+	TPM_MINOR = 224,	/* officially assigned */
+	TPM_BUFSIZE = 2048,
+	TPM_NUM_DEVICES = 256,
+	TPM_NUM_MASK_ENTRIES = TPM_NUM_DEVICES / (8 * sizeof(int))
+};
 
 static LIST_HEAD(tpm_chip_list);
 static DEFINE_SPINLOCK(driver_lock);
-static int dev_mask[32];
+static int dev_mask[TPM_NUM_MASK_ENTRIES];
 
 static void user_reader_timeout(unsigned long ptr)
 {
@@ -52,92 +49,17 @@ static void user_reader_timeout(unsigned
 	up(&chip->buffer_mutex);
 }
 
-void tpm_time_expired(unsigned long ptr)
-{
-	int *exp = (int *) ptr;
-	*exp = 1;
-}
-
-EXPORT_SYMBOL_GPL(tpm_time_expired);
-
-/*
- * Initialize the LPC bus and enable the TPM ports
- */
-int tpm_lpc_bus_init(struct pci_dev *pci_dev, u16 base)
-{
-	u32 lpcenable, tmp;
-	int is_lpcm = 0;
-
-	switch (pci_dev->vendor) {
-	case PCI_VENDOR_ID_INTEL:
-		switch (pci_dev->device) {
-		case PCI_DEVICE_ID_INTEL_82801CA_12:
-		case PCI_DEVICE_ID_INTEL_82801DB_12:
-			is_lpcm = 1;
-			break;
-		}
-		/* init ICH (enable LPC) */
-		pci_read_config_dword(pci_dev, PCI_GEN1_DEC, &lpcenable);
-		lpcenable |= 0x20000000;
-		pci_write_config_dword(pci_dev, PCI_GEN1_DEC, lpcenable);
-
-		if (is_lpcm) {
-			pci_read_config_dword(pci_dev, PCI_GEN1_DEC,
-					      &lpcenable);
-			if ((lpcenable & 0x20000000) == 0) {
-				dev_err(&pci_dev->dev,
-					"cannot enable LPC\n");
-				return -ENODEV;
-			}
-		}
-
-		/* initialize TPM registers */
-		pci_read_config_dword(pci_dev, PCI_GEN2_DEC, &tmp);
-
-		if (!is_lpcm)
-			tmp = (tmp & 0xFFFF0000) | (base & 0xFFF0);
-		else
-			tmp =
-			    (tmp & 0xFFFF0000) | (base & 0xFFF0) |
-			    0x00000001;
-
-		pci_write_config_dword(pci_dev, PCI_GEN2_DEC, tmp);
-
-		if (is_lpcm) {
-			pci_read_config_dword(pci_dev, PCI_GEN_PMCON_1,
-					      &tmp);
-			tmp |= 0x00000004;	/* enable CLKRUN */
-			pci_write_config_dword(pci_dev, PCI_GEN_PMCON_1,
-					       tmp);
-		}
-		tpm_write_index(0x0D, 0x55);	/* unlock 4F */
-		tpm_write_index(0x0A, 0x00);	/* int disable */
-		tpm_write_index(0x08, base);	/* base addr lo */
-		tpm_write_index(0x09, (base & 0xFF00) >> 8);	/* base addr hi */
-		tpm_write_index(0x0D, 0xAA);	/* lock 4F */
-		break;
-	case PCI_VENDOR_ID_AMD:
-		/* nothing yet */
-		break;
-	}
-
-	return 0;
-}
-
-EXPORT_SYMBOL_GPL(tpm_lpc_bus_init);
-
 /*
  * Internal kernel interface to transmit TPM commands
  */
 static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
 			    size_t bufsiz)
 {
-	ssize_t len;
+	ssize_t rc;
 	u32 count;
-	__be32 *native_size;
+	unsigned long stop;
 
-	native_size = (__force __be32 *) (buf + 2);
-	count = be32_to_cpu(*native_size);
+	count = be32_to_cpu(*((__be32 *) (buf + 2)));
 
 	if (count == 0)
 		return -ENODATA;
@@ -149,53 +71,49 @@ static ssize_t tpm_transmit(struct tpm_c
 
 	down(&chip->tpm_mutex);
 
-	if ((len = chip->vendor->send(chip, (u8 *) buf, count)) < 0) {
+	if ((rc = chip->vendor->send(chip, (u8 *) buf, count)) < 0) {
 		dev_err(&chip->pci_dev->dev,
-			"tpm_transmit: tpm_send: error %zd\n", len);
-		return len;
+			"tpm_transmit: tpm_send: error %zd\n", rc);
+		goto out;
 	}
 
-	down(&chip->timer_manipulation_mutex);
-	chip->time_expired = 0;
-	init_timer(&chip->device_timer);
-	chip->device_timer.function = tpm_time_expired;
-	chip->device_timer.expires = jiffies + 2 * 60 * HZ;
-	chip->device_timer.data = (unsigned long) &chip->time_expired;
-	add_timer(&chip->device_timer);
-	up(&chip->timer_manipulation_mutex);
-
+	stop = jiffies + 2 * 60 * HZ;
 	do {
 		u8 status = inb(chip->vendor->base + 1);
 		if ((status & chip->vendor->req_complete_mask) ==
 		    chip->vendor->req_complete_val) {
-			down(&chip->timer_manipulation_mutex);
-			del_singleshot_timer_sync(&chip->device_timer);
-			up(&chip->timer_manipulation_mutex);
 			goto out_recv;
 		}
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(TPM_TIMEOUT);
+
+		if ((status == chip->vendor->req_canceled)) {
+			dev_err(&chip->pci_dev->dev, "Operation Canceled\n");
+			rc = -ECANCELED;
+			goto out;
+		}
+
+		msleep(TPM_TIMEOUT);	/* CHECK */
 		rmb();
-	} while (!chip->time_expired);
+	} while (time_before(jiffies, stop));
 
 
 	chip->vendor->cancel(chip);
-	dev_err(&chip->pci_dev->dev, "Time expired\n");
-	up(&chip->tpm_mutex);
-	return -EIO;
+	dev_err(&chip->pci_dev->dev, "Operation Timed out\n");
+	rc = -ETIME;
+	goto out;
 
 out_recv:
-	len = chip->vendor->recv(chip, (u8 *) buf, bufsiz);
-	if (len < 0)
+	rc = chip->vendor->recv(chip, (u8 *) buf, bufsiz);
+	if (rc < 0)
 		dev_err(&chip->pci_dev->dev,
-			"tpm_transmit: tpm_recv: error %zd\n", len);
+			"tpm_transmit: tpm_recv: error %zd\n", rc);
+out:
 	up(&chip->tpm_mutex);
-	return len;
+	return rc;
 }
 
 #define TPM_DIGEST_SIZE 20
 #define CAP_PCR_RESULT_SIZE 18
-static u8 cap_pcr[] = {
+static const u8 cap_pcr[] = {
 	0, 193,			/* TPM_TAG_RQU_COMMAND */
 	0, 0, 0, 22,		/* length */
 	0, 0, 0, 101,		/* TPM_ORD_GetCapability */
@@ -205,75 +123,94 @@ static u8 cap_pcr[] = {
 };
 
 #define READ_PCR_RESULT_SIZE 30
-static u8 pcrread[] = {
+static const u8 pcrread[] = {
 	0, 193,			/* TPM_TAG_RQU_COMMAND */
 	0, 0, 0, 14,		/* length */
 	0, 0, 0, 21,		/* TPM_ORD_PcrRead */
 	0, 0, 0, 0		/* PCR index */
 };
 
-static ssize_t show_pcrs(struct device *dev, char *buf)
+ssize_t tpm_show_pcrs(struct device *dev, struct device_attribute *attr,
+		      char *buf)
 {
 	u8 data[READ_PCR_RESULT_SIZE];
 	ssize_t len;
-	int i, j, index, num_pcrs;
+	int i, j, num_pcrs;
+	__be32 index;
 	char *str = buf;
 
 	struct tpm_chip *chip =
-	    pci_get_drvdata(container_of(dev, struct pci_dev, dev));
+	    pci_get_drvdata(to_pci_dev(dev));
 	if (chip == NULL)
 		return -ENODEV;
 
 	memcpy(data, cap_pcr, sizeof(cap_pcr));
 	if ((len = tpm_transmit(chip, data, sizeof(data)))
-	    < CAP_PCR_RESULT_SIZE)
-		return len;
+	    < CAP_PCR_RESULT_SIZE) {
+		dev_dbg(&chip->pci_dev->dev, "A TPM error (%d) occurred "
+				"attempting to determine the number of PCRS\n",
+			be32_to_cpu(*((__be32 *) (data + 6))));
+		return 0;
+	}
 
-	num_pcrs = be32_to_cpu(*((__force __be32 *) (data + 14)));
+	num_pcrs = be32_to_cpu(*((__be32 *) (data + 14)));
 
 	for (i = 0; i < num_pcrs; i++) {
 		memcpy(data, pcrread, sizeof(pcrread));
 		index = cpu_to_be32(i);
 		memcpy(data + 10, &index, 4);
 		if ((len = tpm_transmit(chip, data, sizeof(data)))
-		    < READ_PCR_RESULT_SIZE)
-			return len;
+		    < READ_PCR_RESULT_SIZE){
+			dev_dbg(&chip->pci_dev->dev, "A TPM error (%d) occurred"
+				" attempting to read PCR %d of %d\n",
+				be32_to_cpu(*((__be32 *) (data + 6))), i, num_pcrs);
+			goto out;
+		}
 		str += sprintf(str, "PCR-%02d: ", i);
 		for (j = 0; j < TPM_DIGEST_SIZE; j++)
 			str += sprintf(str, "%02X ", *(data + 10 + j));
 		str += sprintf(str, "\n");
 	}
+out:
 	return str - buf;
 }
-
-static DEVICE_ATTR(pcrs, S_IRUGO, show_pcrs, NULL);
+EXPORT_SYMBOL_GPL(tpm_show_pcrs);
 
 #define  READ_PUBEK_RESULT_SIZE 314
-static u8 readpubek[] = {
+static const u8 readpubek[] = {
 	0, 193,			/* TPM_TAG_RQU_COMMAND */
 	0, 0, 0, 30,		/* length */
 	0, 0, 0, 124,		/* TPM_ORD_ReadPubek */
 };
 
-static ssize_t show_pubek(struct device *dev, char *buf)
+ssize_t tpm_show_pubek(struct device *dev, struct device_attribute *attr,
+		       char *buf)
 {
-	u8 data[READ_PUBEK_RESULT_SIZE];
+	u8 *data;
 	ssize_t len;
-	__be32 *native_val;
-	int i;
+	int i, rc;
 	char *str = buf;
 
 	struct tpm_chip *chip =
-	    pci_get_drvdata(container_of(dev, struct pci_dev, dev));
+	    pci_get_drvdata(to_pci_dev(dev));
 	if (chip == NULL)
 		return -ENODEV;
 
+	data = kmalloc(READ_PUBEK_RESULT_SIZE, GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
 	memcpy(data, readpubek, sizeof(readpubek));
 	memset(data + sizeof(readpubek), 0, 20);	/* zero nonce */
 
-	if ((len = tpm_transmit(chip, data, sizeof(data))) <
-	    READ_PUBEK_RESULT_SIZE)
-		return len;
+	if ((len = tpm_transmit(chip, data, READ_PUBEK_RESULT_SIZE)) <
+	    READ_PUBEK_RESULT_SIZE) {
+		dev_dbg(&chip->pci_dev->dev, "A TPM error (%d) occurred "
+				"attempting to read the PUBEK\n",
+			    be32_to_cpu(*((__be32 *) (data + 6))));
+		rc = 0;
+		goto out;
+	}
 
 	/* 
 	   ignore header 10 bytes
@@ -286,8 +223,6 @@ static ssize_t show_pubek(struct device 
 	   ignore checksum 20 bytes
 	 */
 
-	native_val = (__force __be32 *) (data + 34);
-
 	str +=
 	    sprintf(str,
 		    "Algorithm: %02X %02X %02X %02X\nEncscheme: %02X %02X\n"
@@ -298,21 +233,23 @@ static ssize_t show_pubek(struct device 
 		    data[15], data[16], data[17], data[22], data[23],
 		    data[24], data[25], data[26], data[27], data[28],
 		    data[29], data[30], data[31], data[32], data[33],
-		    be32_to_cpu(*native_val)
-	    );
+		    be32_to_cpu(*((__be32 *) (data + 34))));
 
 	for (i = 0; i < 256; i++) {
-		str += sprintf(str, "%02X ", data[i + 39]);
+		str += sprintf(str, "%02X ", data[i + 38]);
 		if ((i + 1) % 16 == 0)
 			str += sprintf(str, "\n");
 	}
-	return str - buf;
+	rc = str - buf;
+out:
+	kfree(data);
+	return rc;
 }
 
-static DEVICE_ATTR(pubek, S_IRUGO, show_pubek, NULL);
+EXPORT_SYMBOL_GPL(tpm_show_pubek);
 
 #define CAP_VER_RESULT_SIZE 18
-static u8 cap_version[] = {
+static const u8 cap_version[] = {
 	0, 193,			/* TPM_TAG_RQU_COMMAND */
 	0, 0, 0, 18,		/* length */
 	0, 0, 0, 101,		/* TPM_ORD_GetCapability */
@@ -321,7 +258,7 @@ static u8 cap_version[] = {
 };
 
 #define CAP_MANUFACTURER_RESULT_SIZE 18
-static u8 cap_manufacturer[] = {
+static const u8 cap_manufacturer[] = {
 	0, 193,			/* TPM_TAG_RQU_COMMAND */
 	0, 0, 0, 22,		/* length */
 	0, 0, 0, 101,		/* TPM_ORD_GetCapability */
@@ -330,14 +267,15 @@ static u8 cap_manufacturer[] = {
 	0, 0, 1, 3
 };
 
-static ssize_t show_caps(struct device *dev, char *buf)
+ssize_t tpm_show_caps(struct device *dev, struct device_attribute *attr,
+		      char *buf)
 {
-	u8 data[READ_PUBEK_RESULT_SIZE];
+	u8 data[sizeof(cap_manufacturer)];
 	ssize_t len;
 	char *str = buf;
 
 	struct tpm_chip *chip =
-	    pci_get_drvdata(container_of(dev, struct pci_dev, dev));
+	    pci_get_drvdata(to_pci_dev(dev));
 	if (chip == NULL)
 		return -ENODEV;
 
@@ -348,7 +286,7 @@ static ssize_t show_caps(struct device *
 		return len;
 
 	str += sprintf(str, "Manufacturer: 0x%x\n",
-		       be32_to_cpu(*(data + 14)));
+		       be32_to_cpu(*((__be32 *) (data + 14))));
 
 	memcpy(data, cap_version, sizeof(cap_version));
 
@@ -363,8 +301,20 @@ static ssize_t show_caps(struct device *
 
 	return str - buf;
 }
+EXPORT_SYMBOL_GPL(tpm_show_caps);
+
+ssize_t tpm_store_cancel(struct device *dev, struct device_attribute *attr,
+			const char *buf, size_t count)
+{
+	struct tpm_chip *chip = dev_get_drvdata(dev);
+	if (chip == NULL)
+		return 0;
+
+	chip->vendor->cancel(chip);
+	return count;
+}
+EXPORT_SYMBOL_GPL(tpm_store_cancel);
 
-static DEVICE_ATTR(caps, S_IRUGO, show_caps, NULL);
 
 /*
  * Device file system interface to the TPM
@@ -422,24 +372,15 @@ EXPORT_SYMBOL_GPL(tpm_open);
 int tpm_release(struct inode *inode, struct file *file)
 {
 	struct tpm_chip *chip = file->private_data;
-	
-	file->private_data = NULL;
 
 	spin_lock(&driver_lock);
+	file->private_data = NULL;
 	chip->num_opens--;
-	spin_unlock(&driver_lock);
-
-	down(&chip->timer_manipulation_mutex);
-	if (timer_pending(&chip->user_read_timer))
-		del_singleshot_timer_sync(&chip->user_read_timer);
-	else if (timer_pending(&chip->device_timer))
-		del_singleshot_timer_sync(&chip->device_timer);
-	up(&chip->timer_manipulation_mutex);
-
-	kfree(chip->data_buffer);
+	del_singleshot_timer_sync(&chip->user_read_timer);
 	atomic_set(&chip->data_pending, 0);
-
 	pci_dev_put(chip->pci_dev);
+	kfree(chip->data_buffer);
+	spin_unlock(&driver_lock);
 	return 0;
 }
 
@@ -453,10 +394,8 @@ ssize_t tpm_write(struct file * file, co
 
 	/* cannot perform a write until the read has cleared
 	   either via tpm_read or a user_read_timer timeout */
-	while (atomic_read(&chip->data_pending) != 0) {
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(TPM_TIMEOUT);
-	}
+	while (atomic_read(&chip->data_pending) != 0)
+		msleep(TPM_TIMEOUT);
 
 	down(&chip->buffer_mutex);
 
@@ -476,13 +415,7 @@ ssize_t tpm_write(struct file * file, co
 	up(&chip->buffer_mutex);
 
 	/* Set a timeout by which the reader must come claim the result */
-	down(&chip->timer_manipulation_mutex);
-	init_timer(&chip->user_read_timer);
-	chip->user_read_timer.function = user_reader_timeout;
-	chip->user_read_timer.data = (unsigned long) chip;
-	chip->user_read_timer.expires = jiffies + (60 * HZ);
-	add_timer(&chip->user_read_timer);
-	up(&chip->timer_manipulation_mutex);
+	mod_timer(&chip->user_read_timer, jiffies + (60 * HZ));
 
 	return in_size;
 }
@@ -493,29 +426,19 @@ ssize_t tpm_read(struct file * file, cha
 		 size_t size, loff_t * off)
 {
 	struct tpm_chip *chip = file->private_data;
-	int ret_size = -ENODATA;
+	int ret_size;
 
-	if (atomic_read(&chip->data_pending) != 0) {	/* Result available */
-		down(&chip->timer_manipulation_mutex);
-		del_singleshot_timer_sync(&chip->user_read_timer);
-		up(&chip->timer_manipulation_mutex);
+	del_singleshot_timer_sync(&chip->user_read_timer);
+	ret_size = atomic_read(&chip->data_pending);
+	atomic_set(&chip->data_pending, 0);
+	if (ret_size > 0) {	/* relay data */
+		if (size < ret_size)
+			ret_size = size;
 
 		down(&chip->buffer_mutex);
-
-		ret_size = atomic_read(&chip->data_pending);
-		atomic_set(&chip->data_pending, 0);
-
-		if (ret_size == 0)	/* timeout just occurred */
-			ret_size = -ETIME;
-		else if (ret_size > 0) {	/* relay data */
-			if (size < ret_size)
-				ret_size = size;
-
-			if (copy_to_user((void __user *) buf,
-					 chip->data_buffer, ret_size)) {
-				ret_size = -EFAULT;
-			}
-		}
+		if (copy_to_user
+		    ((void __user *) buf, chip->data_buffer, ret_size))
+			ret_size = -EFAULT;
 		up(&chip->buffer_mutex);
 	}
 
@@ -541,14 +464,13 @@ void __devexit tpm_remove(struct pci_dev
 
 	pci_set_drvdata(pci_dev, NULL);
 	misc_deregister(&chip->vendor->miscdev);
+	kfree(chip->vendor->miscdev.name);
 
-	device_remove_file(&pci_dev->dev, &dev_attr_pubek);
-	device_remove_file(&pci_dev->dev, &dev_attr_pcrs);
-	device_remove_file(&pci_dev->dev, &dev_attr_caps);
+	sysfs_remove_group(&pci_dev->dev.kobj, chip->vendor->attr_group);
 
 	pci_disable_device(pci_dev);
 
-	dev_mask[chip->dev_num / 32] &= !(1 << (chip->dev_num % 32));
+	dev_mask[chip->dev_num / TPM_NUM_MASK_ENTRIES ] &= !(1 << (chip->dev_num % TPM_NUM_MASK_ENTRIES));
 
 	kfree(chip);
 
@@ -590,10 +512,6 @@ int tpm_pm_resume(struct pci_dev *pci_de
 	if (chip == NULL)
 		return -ENODEV;
 
-	spin_lock(&driver_lock);
-	tpm_lpc_bus_init(pci_dev, chip->vendor->base);
-	spin_unlock(&driver_lock);
-
 	return 0;
 }
 
@@ -609,7 +527,9 @@ EXPORT_SYMBOL_GPL(tpm_pm_resume);
 int tpm_register_hardware(struct pci_dev *pci_dev,
 			  struct tpm_vendor_specific *entry)
 {
-	char devname[7];
+#define DEVNAME_SIZE 7
+
+	char *devname;
 	struct tpm_chip *chip;
 	int i, j;
 
@@ -622,17 +542,21 @@ int tpm_register_hardware(struct pci_dev
 
 	init_MUTEX(&chip->buffer_mutex);
 	init_MUTEX(&chip->tpm_mutex);
-	init_MUTEX(&chip->timer_manipulation_mutex);
 	INIT_LIST_HEAD(&chip->list);
 
+	init_timer(&chip->user_read_timer);
+	chip->user_read_timer.function = user_reader_timeout;
+	chip->user_read_timer.data = (unsigned long) chip;
+
 	chip->vendor = entry;
 
 	chip->dev_num = -1;
 
-	for (i = 0; i < 32; i++)
-		for (j = 0; j < 8; j++)
+	for (i = 0; i < TPM_NUM_MASK_ENTRIES; i++)
+		for (j = 0; j < 8 * sizeof(int); j++)
 			if ((dev_mask[i] & (1 << j)) == 0) {
-				chip->dev_num = i * 32 + j;
+				chip->dev_num =
+				    i * TPM_NUM_MASK_ENTRIES + j;
 				dev_mask[i] |= 1 << j;
 				goto dev_num_search_complete;
 			}
@@ -648,7 +572,8 @@ dev_num_search_complete:
 	else
 		chip->vendor->miscdev.minor = MISC_DYNAMIC_MINOR;
 
-	snprintf(devname, sizeof(devname), "%s%d", "tpm", chip->dev_num);
+	devname = kmalloc(DEVNAME_SIZE, GFP_KERNEL);
+	scnprintf(devname, DEVNAME_SIZE, "%s%d", "tpm", chip->dev_num);
 	chip->vendor->miscdev.name = devname;
 
 	chip->vendor->miscdev.dev = &(pci_dev->dev);
@@ -665,31 +590,20 @@ dev_num_search_complete:
 		return -ENODEV;
 	}
 
+	spin_lock(&driver_lock);
+
 	pci_set_drvdata(pci_dev, chip);
 
 	list_add(&chip->list, &tpm_chip_list);
 
-	device_create_file(&pci_dev->dev, &dev_attr_pubek);
-	device_create_file(&pci_dev->dev, &dev_attr_pcrs);
-	device_create_file(&pci_dev->dev, &dev_attr_caps);
-
-	return 0;
-}
+	spin_unlock(&driver_lock);
 
-EXPORT_SYMBOL_GPL(tpm_register_hardware);
+	sysfs_create_group(&pci_dev->dev.kobj, chip->vendor->attr_group);
 
-static int __init init_tpm(void)
-{
 	return 0;
 }
 
-static void __exit cleanup_tpm(void)
-{
-
-}
-
-module_init(init_tpm);
-module_exit(cleanup_tpm);
+EXPORT_SYMBOL_GPL(tpm_register_hardware);
 
 MODULE_AUTHOR("Leendert van Doorn (leendert@watson.ibm.com)");
 MODULE_DESCRIPTION("TPM Driver");
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -25,23 +25,38 @@
 #include <linux/fs.h>
 #include <linux/miscdevice.h>
 
-#define TPM_TIMEOUT msecs_to_jiffies(5)
+enum tpm_timeout {
+	TPM_TIMEOUT = 5,	/* msecs */
+};
 
 /* TPM addresses */
-#define	TPM_ADDR			0x4E
-#define	TPM_DATA			0x4F
+enum tpm_addr {
+	TPM_SUPERIO_ADDR = 0x2E,
+	TPM_ADDR = 0x4E,
+};
+
+extern ssize_t tpm_show_pubek(struct device *, struct device_attribute *attr,
+				char *);
+extern ssize_t tpm_show_pcrs(struct device *, struct device_attribute *attr,
+				char *);
+extern ssize_t tpm_show_caps(struct device *, struct device_attribute *attr,
+				char *);
+extern ssize_t tpm_store_cancel(struct device *, struct device_attribute *attr,
+				const char *, size_t);
 
 struct tpm_chip;
 
 struct tpm_vendor_specific {
 	u8 req_complete_mask;
 	u8 req_complete_val;
+	u8 req_canceled;
 	u16 base;		/* TPM base address */
 
 	int (*recv) (struct tpm_chip *, u8 *, size_t);
 	int (*send) (struct tpm_chip *, u8 *, size_t);
 	void (*cancel) (struct tpm_chip *);
 	struct miscdevice miscdev;
+	struct attribute_group *attr_group;
 };
 
 struct tpm_chip {
@@ -58,29 +73,24 @@ struct tpm_chip {
 
 	struct timer_list user_read_timer;	/* user needs to claim result */
 	struct semaphore tpm_mutex;	/* tpm is processing */
-	struct timer_list device_timer;	/* tpm is processing */
-	struct semaphore timer_manipulation_mutex;
 
 	struct tpm_vendor_specific *vendor;
 
 	struct list_head list;
 };
 
-static inline int tpm_read_index(int index)
+static inline int tpm_read_index(int base, int index)
 {
-	outb(index, TPM_ADDR);
-	return inb(TPM_DATA) & 0xFF;
+	outb(index, base);
+	return inb(base+1) & 0xFF;
 }
 
-static inline void tpm_write_index(int index, int value)
+static inline void tpm_write_index(int base, int index, int value)
 {
-	outb(index, TPM_ADDR);
-	outb(value & 0xFF, TPM_DATA);
+	outb(index, base);
+	outb(value & 0xFF, base+1);
 }
 
-extern void tpm_time_expired(unsigned long);
-extern int tpm_lpc_bus_init(struct pci_dev *, u16);
-
 extern int tpm_register_hardware(struct pci_dev *,
 				 struct tpm_vendor_specific *);
 extern int tpm_open(struct inode *, struct file *);
diff --git a/drivers/char/tpm/tpm_atmel.c b/drivers/char/tpm/tpm_atmel.c
--- a/drivers/char/tpm/tpm_atmel.c
+++ b/drivers/char/tpm/tpm_atmel.c
@@ -22,17 +22,23 @@
 #include "tpm.h"
 
 /* Atmel definitions */
-#define	TPM_ATML_BASE			0x400
+enum tpm_atmel_addr {
+	TPM_ATMEL_BASE_ADDR_LO = 0x08,
+	TPM_ATMEL_BASE_ADDR_HI = 0x09
+};
 
 /* write status bits */
-#define	ATML_STATUS_ABORT		0x01
-#define	ATML_STATUS_LASTBYTE		0x04
-
+enum tpm_atmel_write_status {
+	ATML_STATUS_ABORT = 0x01,
+	ATML_STATUS_LASTBYTE = 0x04
+};
 /* read status bits */
-#define	ATML_STATUS_BUSY		0x01
-#define	ATML_STATUS_DATA_AVAIL		0x02
-#define	ATML_STATUS_REWRITE		0x04
-
+enum tpm_atmel_read_status {
+	ATML_STATUS_BUSY = 0x01,
+	ATML_STATUS_DATA_AVAIL = 0x02,
+	ATML_STATUS_REWRITE = 0x04,
+	ATML_STATUS_READY = 0x08
+};
 
 static int tpm_atml_recv(struct tpm_chip *chip, u8 * buf, size_t count)
 {
@@ -121,13 +127,29 @@ static struct file_operations atmel_ops 
 	.release = tpm_release,
 };
 
+static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL);
+static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL);
+static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL);
+static DEVICE_ATTR(cancel, S_IWUSR |S_IWGRP, NULL, tpm_store_cancel);
+
+static struct attribute* atmel_attrs[] = {
+	&dev_attr_pubek.attr,
+	&dev_attr_pcrs.attr,
+	&dev_attr_caps.attr,
+	&dev_attr_cancel.attr,
+	0,
+};
+
+static struct attribute_group atmel_attr_grp = { .attrs = atmel_attrs };
+
 static struct tpm_vendor_specific tpm_atmel = {
 	.recv = tpm_atml_recv,
 	.send = tpm_atml_send,
 	.cancel = tpm_atml_cancel,
 	.req_complete_mask = ATML_STATUS_BUSY | ATML_STATUS_DATA_AVAIL,
 	.req_complete_val = ATML_STATUS_DATA_AVAIL,
-	.base = TPM_ATML_BASE,
+	.req_canceled = ATML_STATUS_READY,
+	.attr_group = &atmel_attr_grp,
 	.miscdev = { .fops = &atmel_ops, },
 };
 
@@ -136,27 +158,29 @@ static int __devinit tpm_atml_init(struc
 {
 	u8 version[4];
 	int rc = 0;
+	int lo, hi;
 
 	if (pci_enable_device(pci_dev))
 		return -EIO;
 
-	if (tpm_lpc_bus_init(pci_dev, TPM_ATML_BASE)) {
-		rc = -ENODEV;
-		goto out_err;
-	}
+	lo = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_LO);
+	hi = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_HI);
+
+	tpm_atmel.base = (hi<<8)|lo;
+	dev_dbg( &pci_dev->dev, "Operating with base: 0x%x\n", tpm_atmel.base);
 
 	/* verify that it is an Atmel part */
-	if (tpm_read_index(4) != 'A' || tpm_read_index(5) != 'T'
-	    || tpm_read_index(6) != 'M' || tpm_read_index(7) != 'L') {
+	if (tpm_read_index(TPM_ADDR, 4) != 'A' || tpm_read_index(TPM_ADDR, 5) != 'T'
+	    || tpm_read_index(TPM_ADDR, 6) != 'M' || tpm_read_index(TPM_ADDR, 7) != 'L') {
 		rc = -ENODEV;
 		goto out_err;
 	}
 
 	/* query chip for its version number */
-	if ((version[0] = tpm_read_index(0x00)) != 0xFF) {
-		version[1] = tpm_read_index(0x01);
-		version[2] = tpm_read_index(0x02);
-		version[3] = tpm_read_index(0x03);
+	if ((version[0] = tpm_read_index(TPM_ADDR, 0x00)) != 0xFF) {
+		version[1] = tpm_read_index(TPM_ADDR, 0x01);
+		version[2] = tpm_read_index(TPM_ADDR, 0x02);
+		version[3] = tpm_read_index(TPM_ADDR, 0x03);
 	} else {
 		dev_info(&pci_dev->dev, "version query failed\n");
 		rc = -ENODEV;
@@ -183,6 +207,7 @@ static struct pci_device_id tpm_pci_tbl[
 	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12)},
 	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0)},
 	{PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_LPC)},
+	{PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB6LPC)},
 	{0,}
 };
 
diff --git a/drivers/char/tpm/tpm_infineon.c b/drivers/char/tpm/tpm_infineon.c
new file mode 100644
--- /dev/null
+++ b/drivers/char/tpm/tpm_infineon.c
@@ -0,0 +1,533 @@
+/*
+ * Description:
+ * Device Driver for the Infineon Technologies
+ * SLD 9630 TT 1.1 and SLB 9635 TT 1.2 Trusted Platform Module
+ * Specifications at www.trustedcomputinggroup.org
+ *
+ * Copyright (C) 2005, Marcel Selhorst <selhorst@crypto.rub.de>
+ * Applied Data Security Group, Ruhr-University Bochum, Germany
+ * Project-Homepage: http://www.prosec.rub.de/tpm
+ *
+ * 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, version 2 of the
+ * License.
+ */
+
+#include <acpi/acpi_bus.h>
+#include <linux/pnp.h>
+#include "tpm.h"
+
+/* Infineon specific definitions */
+/* maximum number of WTX-packages */
+#define	TPM_MAX_WTX_PACKAGES 	50
+/* msleep-Time for WTX-packages */
+#define	TPM_WTX_MSLEEP_TIME 	20
+/* msleep-Time --> Interval to check status register */
+#define	TPM_MSLEEP_TIME 	3
+/* gives number of max. msleep()-calls before throwing timeout */
+#define	TPM_MAX_TRIES		5000
+#define	TPM_INFINEON_DEV_VEN_VALUE	0x15D1
+
+/* These values will be filled after ACPI-call */
+static int TPM_INF_DATA = 0;
+static int TPM_INF_ADDR = 0;
+
+/* TPM header definitions */
+enum infineon_tpm_header {
+	TPM_VL_VER = 0x01,
+	TPM_VL_CHANNEL_CONTROL = 0x07,
+	TPM_VL_CHANNEL_PERSONALISATION = 0x0A,
+	TPM_VL_CHANNEL_TPM = 0x0B,
+	TPM_VL_CONTROL = 0x00,
+	TPM_INF_NAK = 0x15,
+	TPM_CTRL_WTX = 0x10,
+	TPM_CTRL_WTX_ABORT = 0x18,
+	TPM_CTRL_WTX_ABORT_ACK = 0x18,
+	TPM_CTRL_ERROR = 0x20,
+	TPM_CTRL_CHAININGACK = 0x40,
+	TPM_CTRL_CHAINING = 0x80,
+	TPM_CTRL_DATA = 0x04,
+	TPM_CTRL_DATA_CHA = 0x84,
+	TPM_CTRL_DATA_CHA_ACK = 0xC4
+};
+
+enum infineon_tpm_register {
+	WRFIFO = 0x00,
+	RDFIFO = 0x01,
+	STAT = 0x02,
+	CMD = 0x03
+};
+
+enum infineon_tpm_command_bits {
+	CMD_DIS = 0x00,
+	CMD_LP = 0x01,
+	CMD_RES = 0x02,
+	CMD_IRQC = 0x06
+};
+
+enum infineon_tpm_status_bits {
+	STAT_XFE = 0x00,
+	STAT_LPA = 0x01,
+	STAT_FOK = 0x02,
+	STAT_TOK = 0x03,
+	STAT_IRQA = 0x06,
+	STAT_RDA = 0x07
+};
+
+/* some outgoing values */
+enum infineon_tpm_values {
+	CHIP_ID1 = 0x20,
+	CHIP_ID2 = 0x21,
+	TPM_DAR = 0x30,
+	RESET_LP_IRQC_DISABLE = 0x41,
+	ENABLE_REGISTER_PAIR = 0x55,
+	IOLIMH = 0x60,
+	IOLIML = 0x61,
+	DISABLE_REGISTER_PAIR = 0xAA,
+	IDVENL = 0xF1,
+	IDVENH = 0xF2,
+	IDPDL = 0xF3,
+	IDPDH = 0xF4
+};
+
+static int number_of_wtx;
+
+static int empty_fifo(struct tpm_chip *chip, int clear_wrfifo)
+{
+	int status;
+	int check = 0;
+	int i;
+
+	if (clear_wrfifo) {
+		for (i = 0; i < 4096; i++) {
+			status = inb(chip->vendor->base + WRFIFO);
+			if (status == 0xff) {
+				if (check == 5)
+					break;
+				else
+					check++;
+			}
+		}
+	}
+	/* Note: The values which are currently in the FIFO of the TPM
+	   are thrown away since there is no usage for them. Usually,
+	   this has nothing to say, since the TPM will give its answer
+	   immediately or will be aborted anyway, so the data here is
+	   usually garbage and useless.
+	   We have to clean this, because the next communication with
+	   the TPM would be rubbish, if there is still some old data
+	   in the Read FIFO.
+	 */
+	i = 0;
+	do {
+		status = inb(chip->vendor->base + RDFIFO);
+		status = inb(chip->vendor->base + STAT);
+		i++;
+		if (i == TPM_MAX_TRIES)
+			return -EIO;
+	} while ((status & (1 << STAT_RDA)) != 0);
+	return 0;
+}
+
+static int wait(struct tpm_chip *chip, int wait_for_bit)
+{
+	int status;
+	int i;
+	for (i = 0; i < TPM_MAX_TRIES; i++) {
+		status = inb(chip->vendor->base + STAT);
+		/* check the status-register if wait_for_bit is set */
+		if (status & 1 << wait_for_bit)
+			break;
+		msleep(TPM_MSLEEP_TIME);
+	}
+	if (i == TPM_MAX_TRIES) {	/* timeout occurs */
+		if (wait_for_bit == STAT_XFE)
+			dev_err(&chip->pci_dev->dev,
+				"Timeout in wait(STAT_XFE)\n");
+		if (wait_for_bit == STAT_RDA)
+			dev_err(&chip->pci_dev->dev,
+				"Timeout in wait(STAT_RDA)\n");
+		return -EIO;
+	}
+	return 0;
+};
+
+static void wait_and_send(struct tpm_chip *chip, u8 sendbyte)
+{
+	wait(chip, STAT_XFE);
+	outb(sendbyte, chip->vendor->base + WRFIFO);
+}
+
+    /* Note: WTX means Waiting-Time-Extension. Whenever the TPM needs more
+       calculation time, it sends a WTX-package, which has to be acknowledged
+       or aborted. This usually occurs if you are hammering the TPM with key
+       creation. Set the maximum number of WTX-packages in the definitions
+       above, if the number is reached, the waiting-time will be denied
+       and the TPM command has to be resend.
+     */
+
+static void tpm_wtx(struct tpm_chip *chip)
+{
+	number_of_wtx++;
+	dev_info(&chip->pci_dev->dev, "Granting WTX (%02d / %02d)\n",
+		 number_of_wtx, TPM_MAX_WTX_PACKAGES);
+	wait_and_send(chip, TPM_VL_VER);
+	wait_and_send(chip, TPM_CTRL_WTX);
+	wait_and_send(chip, 0x00);
+	wait_and_send(chip, 0x00);
+	msleep(TPM_WTX_MSLEEP_TIME);
+}
+
+static void tpm_wtx_abort(struct tpm_chip *chip)
+{
+	dev_info(&chip->pci_dev->dev, "Aborting WTX\n");
+	wait_and_send(chip, TPM_VL_VER);
+	wait_and_send(chip, TPM_CTRL_WTX_ABORT);
+	wait_and_send(chip, 0x00);
+	wait_and_send(chip, 0x00);
+	number_of_wtx = 0;
+	msleep(TPM_WTX_MSLEEP_TIME);
+}
+
+static int tpm_inf_recv(struct tpm_chip *chip, u8 * buf, size_t count)
+{
+	int i;
+	int ret;
+	u32 size = 0;
+
+recv_begin:
+	/* start receiving header */
+	for (i = 0; i < 4; i++) {
+		ret = wait(chip, STAT_RDA);
+		if (ret)
+			return -EIO;
+		buf[i] = inb(chip->vendor->base + RDFIFO);
+	}
+
+	if (buf[0] != TPM_VL_VER) {
+		dev_err(&chip->pci_dev->dev,
+			"Wrong transport protocol implementation!\n");
+		return -EIO;
+	}
+
+	if (buf[1] == TPM_CTRL_DATA) {
+		/* size of the data received */
+		size = ((buf[2] << 8) | buf[3]);
+
+		for (i = 0; i < size; i++) {
+			wait(chip, STAT_RDA);
+			buf[i] = inb(chip->vendor->base + RDFIFO);
+		}
+
+		if ((size == 0x6D00) && (buf[1] == 0x80)) {
+			dev_err(&chip->pci_dev->dev,
+				"Error handling on vendor layer!\n");
+			return -EIO;
+		}
+
+		for (i = 0; i < size; i++)
+			buf[i] = buf[i + 6];
+
+		size = size - 6;
+		return size;
+	}
+
+	if (buf[1] == TPM_CTRL_WTX) {
+		dev_info(&chip->pci_dev->dev, "WTX-package received\n");
+		if (number_of_wtx < TPM_MAX_WTX_PACKAGES) {
+			tpm_wtx(chip);
+			goto recv_begin;
+		} else {
+			tpm_wtx_abort(chip);
+			goto recv_begin;
+		}
+	}
+
+	if (buf[1] == TPM_CTRL_WTX_ABORT_ACK) {
+		dev_info(&chip->pci_dev->dev, "WTX-abort acknowledged\n");
+		return size;
+	}
+
+	if (buf[1] == TPM_CTRL_ERROR) {
+		dev_err(&chip->pci_dev->dev, "ERROR-package received:\n");
+		if (buf[4] == TPM_INF_NAK)
+			dev_err(&chip->pci_dev->dev,
+				"-> Negative acknowledgement"
+				" - retransmit command!\n");
+		return -EIO;
+	}
+	return -EIO;
+}
+
+static int tpm_inf_send(struct tpm_chip *chip, u8 * buf, size_t count)
+{
+	int i;
+	int ret;
+	u8 count_high, count_low, count_4, count_3, count_2, count_1;
+
+	/* Disabling Reset, LP and IRQC */
+	outb(RESET_LP_IRQC_DISABLE, chip->vendor->base + CMD);
+
+	ret = empty_fifo(chip, 1);
+	if (ret) {
+		dev_err(&chip->pci_dev->dev, "Timeout while clearing FIFO\n");
+		return -EIO;
+	}
+
+	ret = wait(chip, STAT_XFE);
+	if (ret)
+		return -EIO;
+
+	count_4 = (count & 0xff000000) >> 24;
+	count_3 = (count & 0x00ff0000) >> 16;
+	count_2 = (count & 0x0000ff00) >> 8;
+	count_1 = (count & 0x000000ff);
+	count_high = ((count + 6) & 0xffffff00) >> 8;
+	count_low = ((count + 6) & 0x000000ff);
+
+	/* Sending Header */
+	wait_and_send(chip, TPM_VL_VER);
+	wait_and_send(chip, TPM_CTRL_DATA);
+	wait_and_send(chip, count_high);
+	wait_and_send(chip, count_low);
+
+	/* Sending Data Header */
+	wait_and_send(chip, TPM_VL_VER);
+	wait_and_send(chip, TPM_VL_CHANNEL_TPM);
+	wait_and_send(chip, count_4);
+	wait_and_send(chip, count_3);
+	wait_and_send(chip, count_2);
+	wait_and_send(chip, count_1);
+
+	/* Sending Data */
+	for (i = 0; i < count; i++) {
+		wait_and_send(chip, buf[i]);
+	}
+	return count;
+}
+
+static void tpm_inf_cancel(struct tpm_chip *chip)
+{
+	/*
+	   Since we are using the legacy mode to communicate
+	   with the TPM, we have no cancel functions, but have
+	   a workaround for interrupting the TPM through WTX.
+	 */
+}
+
+static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL);
+static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL);
+static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL);
+static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel);
+
+static struct attribute *inf_attrs[] = {
+	&dev_attr_pubek.attr,
+	&dev_attr_pcrs.attr,
+	&dev_attr_caps.attr,
+	&dev_attr_cancel.attr,
+	NULL,
+};
+
+static struct attribute_group inf_attr_grp = {.attrs = inf_attrs };
+
+static struct file_operations inf_ops = {
+	.owner = THIS_MODULE,
+	.llseek = no_llseek,
+	.open = tpm_open,
+	.read = tpm_read,
+	.write = tpm_write,
+	.release = tpm_release,
+};
+
+static struct tpm_vendor_specific tpm_inf = {
+	.recv = tpm_inf_recv,
+	.send = tpm_inf_send,
+	.cancel = tpm_inf_cancel,
+	.req_complete_mask = 0,
+	.req_complete_val = 0,
+	.attr_group = &inf_attr_grp,
+	.miscdev = {.fops = &inf_ops,},
+};
+
+static const struct pnp_device_id tpm_pnp_tbl[] = {
+	/* Infineon TPMs */
+	{"IFX0101", 0},
+	{"IFX0102", 0},
+	{"", 0}
+};
+
+static int __devinit tpm_inf_acpi_probe(struct pnp_dev *dev,
+					const struct pnp_device_id *dev_id)
+{
+	TPM_INF_ADDR = (pnp_port_start(dev, 0) & 0xff);
+	TPM_INF_DATA = ((TPM_INF_ADDR + 1) & 0xff);
+	tpm_inf.base = pnp_port_start(dev, 1);
+	dev_info(&dev->dev, "Found %s with ID %s\n",
+		 dev->name, dev_id->id);
+	if (!((tpm_inf.base >> 8) & 0xff))
+		tpm_inf.base = 0;
+	return 0;
+}
+
+static struct pnp_driver tpm_inf_pnp = {
+	.name = "tpm_inf_pnp",
+	.id_table = tpm_pnp_tbl,
+	.probe = tpm_inf_acpi_probe,
+};
+
+static int __devinit tpm_inf_probe(struct pci_dev *pci_dev,
+				   const struct pci_device_id *pci_id)
+{
+	int rc = 0;
+	u8 iol, ioh;
+	int vendorid[2];
+	int version[2];
+	int productid[2];
+	char chipname[20];
+
+	if (pci_enable_device(pci_dev))
+		return -EIO;
+
+	dev_info(&pci_dev->dev, "LPC-bus found at 0x%x\n", pci_id->device);
+
+	/* read IO-ports from ACPI */
+	pnp_register_driver(&tpm_inf_pnp);
+	pnp_unregister_driver(&tpm_inf_pnp);
+
+	/* Make sure, we have received valid config ports */
+	if (!TPM_INF_ADDR) {
+		pci_disable_device(pci_dev);
+		return -EIO;
+	}
+
+	/* query chip for its vendor, its version number a.s.o. */
+	outb(ENABLE_REGISTER_PAIR, TPM_INF_ADDR);
+	outb(IDVENL, TPM_INF_ADDR);
+	vendorid[1] = inb(TPM_INF_DATA);
+	outb(IDVENH, TPM_INF_ADDR);
+	vendorid[0] = inb(TPM_INF_DATA);
+	outb(IDPDL, TPM_INF_ADDR);
+	productid[1] = inb(TPM_INF_DATA);
+	outb(IDPDH, TPM_INF_ADDR);
+	productid[0] = inb(TPM_INF_DATA);
+	outb(CHIP_ID1, TPM_INF_ADDR);
+	version[1] = inb(TPM_INF_DATA);
+	outb(CHIP_ID2, TPM_INF_ADDR);
+	version[0] = inb(TPM_INF_DATA);
+
+	switch ((productid[0] << 8) | productid[1]) {
+	case 6:
+		sprintf(chipname, " (SLD 9630 TT 1.1)");
+		break;
+	case 11:
+		sprintf(chipname, " (SLB 9635 TT 1.2)");
+		break;
+	default:
+		sprintf(chipname, " (unknown chip)");
+		break;
+	}
+	chipname[19] = 0;
+
+	if ((vendorid[0] << 8 | vendorid[1]) == (TPM_INFINEON_DEV_VEN_VALUE)) {
+
+		if (tpm_inf.base == 0) {
+			dev_err(&pci_dev->dev, "No IO-ports found!\n");
+			pci_disable_device(pci_dev);
+			return -EIO;
+		}
+		/* configure TPM with IO-ports */
+		outb(IOLIMH, TPM_INF_ADDR);
+		outb(((tpm_inf.base >> 8) & 0xff), TPM_INF_DATA);
+		outb(IOLIML, TPM_INF_ADDR);
+		outb((tpm_inf.base & 0xff), TPM_INF_DATA);
+
+		/* control if IO-ports are set correctly */
+		outb(IOLIMH, TPM_INF_ADDR);
+		ioh = inb(TPM_INF_DATA);
+		outb(IOLIML, TPM_INF_ADDR);
+		iol = inb(TPM_INF_DATA);
+
+		if ((ioh << 8 | iol) != tpm_inf.base) {
+			dev_err(&pci_dev->dev,
+				"Could not set IO-ports to %04x\n",
+				tpm_inf.base);
+			pci_disable_device(pci_dev);
+			return -EIO;
+		}
+
+		/* activate register */
+		outb(TPM_DAR, TPM_INF_ADDR);
+		outb(0x01, TPM_INF_DATA);
+		outb(DISABLE_REGISTER_PAIR, TPM_INF_ADDR);
+
+		/* disable RESET, LP and IRQC */
+		outb(RESET_LP_IRQC_DISABLE, tpm_inf.base + CMD);
+
+		/* Finally, we're done, print some infos */
+		dev_info(&pci_dev->dev, "TPM found: "
+			 "config base 0x%x, "
+			 "io base 0x%x, "
+			 "chip version %02x%02x, "
+			 "vendor id %x%x (Infineon), "
+			 "product id %02x%02x"
+			 "%s\n",
+			 TPM_INF_ADDR,
+			 tpm_inf.base,
+			 version[0], version[1],
+			 vendorid[0], vendorid[1],
+			 productid[0], productid[1], chipname);
+
+		rc = tpm_register_hardware(pci_dev, &tpm_inf);
+		if (rc < 0) {
+			pci_disable_device(pci_dev);
+			return -ENODEV;
+		}
+		return 0;
+	} else {
+		dev_info(&pci_dev->dev, "No Infineon TPM found!\n");
+		pci_disable_device(pci_dev);
+		return -ENODEV;
+	}
+}
+
+static struct pci_device_id tpm_pci_tbl[] __devinitdata = {
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0)},
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12)},
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0)},
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12)},
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0)},
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_0)},
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1)},
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_2)},
+	{0,}
+};
+
+MODULE_DEVICE_TABLE(pci, tpm_pci_tbl);
+
+static struct pci_driver inf_pci_driver = {
+	.name = "tpm_inf",
+	.id_table = tpm_pci_tbl,
+	.probe = tpm_inf_probe,
+	.remove = __devexit_p(tpm_remove),
+	.suspend = tpm_pm_suspend,
+	.resume = tpm_pm_resume,
+};
+
+static int __init init_inf(void)
+{
+	return pci_register_driver(&inf_pci_driver);
+}
+
+static void __exit cleanup_inf(void)
+{
+	pci_unregister_driver(&inf_pci_driver);
+}
+
+module_init(init_inf);
+module_exit(cleanup_inf);
+
+MODULE_AUTHOR("Marcel Selhorst <selhorst@crypto.rub.de>");
+MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT 1.1 / SLB 9635 TT 1.2");
+MODULE_VERSION("1.5");
+MODULE_LICENSE("GPL");
diff --git a/drivers/char/tpm/tpm_nsc.c b/drivers/char/tpm/tpm_nsc.c
--- a/drivers/char/tpm/tpm_nsc.c
+++ b/drivers/char/tpm/tpm_nsc.c
@@ -22,43 +22,52 @@
 #include "tpm.h"
 
 /* National definitions */
-#define	TPM_NSC_BASE			0x360
-#define	TPM_NSC_IRQ			0x07
+enum tpm_nsc_addr{
+	TPM_NSC_IRQ = 0x07,
+	TPM_NSC_BASE0_HI = 0x60,
+	TPM_NSC_BASE0_LO = 0x61,
+	TPM_NSC_BASE1_HI = 0x62,
+	TPM_NSC_BASE1_LO = 0x63
+};
+
+enum tpm_nsc_index {
+	NSC_LDN_INDEX = 0x07,
+	NSC_SID_INDEX = 0x20,
+	NSC_LDC_INDEX = 0x30,
+	NSC_DIO_INDEX = 0x60,
+	NSC_CIO_INDEX = 0x62,
+	NSC_IRQ_INDEX = 0x70,
+	NSC_ITS_INDEX = 0x71
+};
 
-#define	NSC_LDN_INDEX			0x07
-#define	NSC_SID_INDEX			0x20
-#define	NSC_LDC_INDEX			0x30
-#define	NSC_DIO_INDEX			0x60
-#define	NSC_CIO_INDEX			0x62
-#define	NSC_IRQ_INDEX			0x70
-#define	NSC_ITS_INDEX			0x71
-
-#define	NSC_STATUS			0x01
-#define	NSC_COMMAND			0x01
-#define	NSC_DATA			0x00
+enum tpm_nsc_status_loc {
+	NSC_STATUS = 0x01,
+	NSC_COMMAND = 0x01,
+	NSC_DATA = 0x00
+};
 
 /* status bits */
-#define	NSC_STATUS_OBF			0x01	/* output buffer full */
-#define	NSC_STATUS_IBF			0x02	/* input buffer full */
-#define	NSC_STATUS_F0			0x04	/* F0 */
-#define	NSC_STATUS_A2			0x08	/* A2 */
-#define	NSC_STATUS_RDY			0x10	/* ready to receive command */
-#define	NSC_STATUS_IBR			0x20	/* ready to receive data */
+enum tpm_nsc_status {
+	NSC_STATUS_OBF = 0x01,	/* output buffer full */
+	NSC_STATUS_IBF = 0x02,	/* input buffer full */
+	NSC_STATUS_F0 = 0x04,	/* F0 */
+	NSC_STATUS_A2 = 0x08,	/* A2 */
+	NSC_STATUS_RDY = 0x10,	/* ready to receive command */
+	NSC_STATUS_IBR = 0x20	/* ready to receive data */
+};
 
 /* command bits */
-#define	NSC_COMMAND_NORMAL		0x01	/* normal mode */
-#define	NSC_COMMAND_EOC			0x03
-#define	NSC_COMMAND_CANCEL		0x22
-
+enum tpm_nsc_cmd_mode {
+	NSC_COMMAND_NORMAL = 0x01,	/* normal mode */
+	NSC_COMMAND_EOC = 0x03,
+	NSC_COMMAND_CANCEL = 0x22
+};
 /*
  * Wait for a certain status to appear
  */
 static int wait_for_stat(struct tpm_chip *chip, u8 mask, u8 val, u8 * data)
 {
-	int expired = 0;
-	struct timer_list status_timer =
-	    TIMER_INITIALIZER(tpm_time_expired, jiffies + 10 * HZ,
-			      (unsigned long) &expired);
+	unsigned long stop;
 
 	/* status immediately available check */
 	*data = inb(chip->vendor->base + NSC_STATUS);
@@ -66,17 +75,14 @@ static int wait_for_stat(struct tpm_chip
 		return 0;
 
 	/* wait for status */
-	add_timer(&status_timer);
+	stop = jiffies + 10 * HZ;
 	do {
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(TPM_TIMEOUT);
+		msleep(TPM_TIMEOUT);
 		*data = inb(chip->vendor->base + 1);
-		if ((*data & mask) == val) {
-			del_singleshot_timer_sync(&status_timer);
+		if ((*data & mask) == val)
 			return 0;
-		}
 	}
-	while (!expired);
+	while (time_before(jiffies, stop));
 
 	return -EBUSY;
 }
@@ -84,10 +90,7 @@ static int wait_for_stat(struct tpm_chip
 static int nsc_wait_for_ready(struct tpm_chip *chip)
 {
 	int status;
-	int expired = 0;
-	struct timer_list status_timer =
-	    TIMER_INITIALIZER(tpm_time_expired, jiffies + 100,
-			      (unsigned long) &expired);
+	unsigned long stop;
 
 	/* status immediately available check */
 	status = inb(chip->vendor->base + NSC_STATUS);
@@ -97,19 +100,16 @@ static int nsc_wait_for_ready(struct tpm
 		return 0;
 
 	/* wait for status */
-	add_timer(&status_timer);
+	stop = jiffies + 100;
 	do {
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(TPM_TIMEOUT);
+		msleep(TPM_TIMEOUT);
 		status = inb(chip->vendor->base + NSC_STATUS);
 		if (status & NSC_STATUS_OBF)
 			status = inb(chip->vendor->base + NSC_DATA);
-		if (status & NSC_STATUS_RDY) {
-			del_singleshot_timer_sync(&status_timer);
+		if (status & NSC_STATUS_RDY)
 			return 0;
-		}
 	}
-	while (!expired);
+	while (time_before(jiffies, stop));
 
 	dev_info(&chip->pci_dev->dev, "wait for ready failed\n");
 	return -EBUSY;
@@ -150,7 +150,8 @@ static int tpm_nsc_recv(struct tpm_chip 
 		*p = inb(chip->vendor->base + NSC_DATA);
 	}
 
-	if ((data & NSC_STATUS_F0) == 0) {
+	if ((data & NSC_STATUS_F0) == 0 &&
+	(wait_for_stat(chip, NSC_STATUS_F0, NSC_STATUS_F0, &data) < 0)) {
 		dev_err(&chip->pci_dev->dev, "F0 not set\n");
 		return -EIO;
 	}
@@ -228,100 +229,95 @@ static struct file_operations nsc_ops = 
 	.release = tpm_release,
 };
 
+static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL);
+static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL);
+static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL);
+static DEVICE_ATTR(cancel, S_IWUSR|S_IWGRP, NULL, tpm_store_cancel);
+
+static struct attribute * nsc_attrs[] = {
+	&dev_attr_pubek.attr,
+	&dev_attr_pcrs.attr,
+	&dev_attr_caps.attr,
+	&dev_attr_cancel.attr,
+	0,
+};
+
+static struct attribute_group nsc_attr_grp = { .attrs = nsc_attrs };
+
 static struct tpm_vendor_specific tpm_nsc = {
 	.recv = tpm_nsc_recv,
 	.send = tpm_nsc_send,
 	.cancel = tpm_nsc_cancel,
 	.req_complete_mask = NSC_STATUS_OBF,
 	.req_complete_val = NSC_STATUS_OBF,
-	.base = TPM_NSC_BASE,
+	.req_canceled = NSC_STATUS_RDY,
+	.attr_group = &nsc_attr_grp,
 	.miscdev = { .fops = &nsc_ops, },
-	
 };
 
 static int __devinit tpm_nsc_init(struct pci_dev *pci_dev,
 				  const struct pci_device_id *pci_id)
 {
 	int rc = 0;
+	int lo, hi;
+	int nscAddrBase = TPM_ADDR;
+
 
 	if (pci_enable_device(pci_dev))
 		return -EIO;
 
-	if (tpm_lpc_bus_init(pci_dev, TPM_NSC_BASE)) {
-		rc = -ENODEV;
-		goto out_err;
-	}
+	/* select PM channel 1 */
+	tpm_write_index(nscAddrBase,NSC_LDN_INDEX, 0x12);
 
 	/* verify that it is a National part (SID) */
-	if (tpm_read_index(NSC_SID_INDEX) != 0xEF) {
-		rc = -ENODEV;
-		goto out_err;
+	if (tpm_read_index(TPM_ADDR, NSC_SID_INDEX) != 0xEF) {
+		nscAddrBase = (tpm_read_index(TPM_SUPERIO_ADDR, 0x2C)<<8)|
+			(tpm_read_index(TPM_SUPERIO_ADDR, 0x2B)&0xFE);
+		if (tpm_read_index(nscAddrBase, NSC_SID_INDEX) != 0xF6) {
+			rc = -ENODEV;
+			goto out_err;
+		}
 	}
 
+	hi = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_HI);
+	lo = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_LO);
+	tpm_nsc.base = (hi<<8) | lo;
+
 	dev_dbg(&pci_dev->dev, "NSC TPM detected\n");
 	dev_dbg(&pci_dev->dev,
 		"NSC LDN 0x%x, SID 0x%x, SRID 0x%x\n",
-		tpm_read_index(0x07), tpm_read_index(0x20),
-		tpm_read_index(0x27));
+		tpm_read_index(nscAddrBase,0x07), tpm_read_index(nscAddrBase,0x20),
+		tpm_read_index(nscAddrBase,0x27));
 	dev_dbg(&pci_dev->dev,
 		"NSC SIOCF1 0x%x SIOCF5 0x%x SIOCF6 0x%x SIOCF8 0x%x\n",
-		tpm_read_index(0x21), tpm_read_index(0x25),
-		tpm_read_index(0x26), tpm_read_index(0x28));
+		tpm_read_index(nscAddrBase,0x21), tpm_read_index(nscAddrBase,0x25),
+		tpm_read_index(nscAddrBase,0x26), tpm_read_index(nscAddrBase,0x28));
 	dev_dbg(&pci_dev->dev, "NSC IO Base0 0x%x\n",
-		(tpm_read_index(0x60) << 8) | tpm_read_index(0x61));
+		(tpm_read_index(nscAddrBase,0x60) << 8) | tpm_read_index(nscAddrBase,0x61));
 	dev_dbg(&pci_dev->dev, "NSC IO Base1 0x%x\n",
-		(tpm_read_index(0x62) << 8) | tpm_read_index(0x63));
+		(tpm_read_index(nscAddrBase,0x62) << 8) | tpm_read_index(nscAddrBase,0x63));
 	dev_dbg(&pci_dev->dev, "NSC Interrupt number and wakeup 0x%x\n",
-		tpm_read_index(0x70));
+		tpm_read_index(nscAddrBase,0x70));
 	dev_dbg(&pci_dev->dev, "NSC IRQ type select 0x%x\n",
-		tpm_read_index(0x71));
+		tpm_read_index(nscAddrBase,0x71));
 	dev_dbg(&pci_dev->dev,
 		"NSC DMA channel select0 0x%x, select1 0x%x\n",
-		tpm_read_index(0x74), tpm_read_index(0x75));
+		tpm_read_index(nscAddrBase,0x74), tpm_read_index(nscAddrBase,0x75));
 	dev_dbg(&pci_dev->dev,
 		"NSC Config "
 		"0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
-		tpm_read_index(0xF0), tpm_read_index(0xF1),
-		tpm_read_index(0xF2), tpm_read_index(0xF3),
-		tpm_read_index(0xF4), tpm_read_index(0xF5),
-		tpm_read_index(0xF6), tpm_read_index(0xF7),
-		tpm_read_index(0xF8), tpm_read_index(0xF9));
+		tpm_read_index(nscAddrBase,0xF0), tpm_read_index(nscAddrBase,0xF1),
+		tpm_read_index(nscAddrBase,0xF2), tpm_read_index(nscAddrBase,0xF3),
+		tpm_read_index(nscAddrBase,0xF4), tpm_read_index(nscAddrBase,0xF5),
+		tpm_read_index(nscAddrBase,0xF6), tpm_read_index(nscAddrBase,0xF7),
+		tpm_read_index(nscAddrBase,0xF8), tpm_read_index(nscAddrBase,0xF9));
 
 	dev_info(&pci_dev->dev,
-		 "NSC PC21100 TPM revision %d\n",
-		 tpm_read_index(0x27) & 0x1F);
-
-	if (tpm_read_index(NSC_LDC_INDEX) == 0)
-		dev_info(&pci_dev->dev, ": NSC TPM not active\n");
-
-	/* select PM channel 1 */
-	tpm_write_index(NSC_LDN_INDEX, 0x12);
-	tpm_read_index(NSC_LDN_INDEX);
-
-	/* disable the DPM module */
-	tpm_write_index(NSC_LDC_INDEX, 0);
-	tpm_read_index(NSC_LDC_INDEX);
-
-	/* set the data register base addresses */
-	tpm_write_index(NSC_DIO_INDEX, TPM_NSC_BASE >> 8);
-	tpm_write_index(NSC_DIO_INDEX + 1, TPM_NSC_BASE);
-	tpm_read_index(NSC_DIO_INDEX);
-	tpm_read_index(NSC_DIO_INDEX + 1);
-
-	/* set the command register base addresses */
-	tpm_write_index(NSC_CIO_INDEX, (TPM_NSC_BASE + 1) >> 8);
-	tpm_write_index(NSC_CIO_INDEX + 1, (TPM_NSC_BASE + 1));
-	tpm_read_index(NSC_DIO_INDEX);
-	tpm_read_index(NSC_DIO_INDEX + 1);
-
-	/* set the interrupt number to be used for the host interface */
-	tpm_write_index(NSC_IRQ_INDEX, TPM_NSC_IRQ);
-	tpm_write_index(NSC_ITS_INDEX, 0x00);
-	tpm_read_index(NSC_IRQ_INDEX);
+		 "NSC TPM revision %d\n",
+		 tpm_read_index(nscAddrBase, 0x27) & 0x1F);
 
 	/* enable the DPM module */
-	tpm_write_index(NSC_LDC_INDEX, 0x01);
-	tpm_read_index(NSC_LDC_INDEX);
+	tpm_write_index(nscAddrBase, NSC_LDC_INDEX, 0x01);
 
 	if ((rc = tpm_register_hardware(pci_dev, &tpm_nsc)) < 0)
 		goto out_err;
@@ -339,6 +335,9 @@ static struct pci_device_id tpm_pci_tbl[
 	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0)},
 	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12)},
 	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0)},
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_0)},
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1)},
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0)},
 	{PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_LPC)},
 	{0,}
 };
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -94,6 +94,7 @@
 #include <linux/idr.h>
 #include <linux/wait.h>
 #include <linux/bitops.h>
+#include <linux/delay.h>
 
 #include <asm/uaccess.h>
 #include <asm/system.h>
@@ -251,7 +252,7 @@ static void tty_set_termios_ldisc(struct
  
 static DEFINE_SPINLOCK(tty_ldisc_lock);
 static DECLARE_WAIT_QUEUE_HEAD(tty_ldisc_wait);
-static struct tty_ldisc tty_ldiscs[NR_LDISCS];	/* line disc dispatch table	*/
+static struct tty_ldisc tty_ldiscs[NR_LDISCS];	/* line disc dispatch table */
 
 int tty_register_ldisc(int disc, struct tty_ldisc *new_ldisc)
 {
@@ -262,24 +263,35 @@ int tty_register_ldisc(int disc, struct 
 		return -EINVAL;
 	
 	spin_lock_irqsave(&tty_ldisc_lock, flags);
-	if (new_ldisc) {
-		tty_ldiscs[disc] = *new_ldisc;
-		tty_ldiscs[disc].num = disc;
-		tty_ldiscs[disc].flags |= LDISC_FLAG_DEFINED;
-		tty_ldiscs[disc].refcount = 0;
-	} else {
-		if(tty_ldiscs[disc].refcount)
-			ret = -EBUSY;
-		else
-			tty_ldiscs[disc].flags &= ~LDISC_FLAG_DEFINED;
-	}
+	tty_ldiscs[disc] = *new_ldisc;
+	tty_ldiscs[disc].num = disc;
+	tty_ldiscs[disc].flags |= LDISC_FLAG_DEFINED;
+	tty_ldiscs[disc].refcount = 0;
 	spin_unlock_irqrestore(&tty_ldisc_lock, flags);
 	
 	return ret;
 }
-
 EXPORT_SYMBOL(tty_register_ldisc);
 
+int tty_unregister_ldisc(int disc)
+{
+	unsigned long flags;
+	int ret = 0;
+
+	if (disc < N_TTY || disc >= NR_LDISCS)
+		return -EINVAL;
+
+	spin_lock_irqsave(&tty_ldisc_lock, flags);
+	if (tty_ldiscs[disc].refcount)
+		ret = -EBUSY;
+	else
+		tty_ldiscs[disc].flags &= ~LDISC_FLAG_DEFINED;
+	spin_unlock_irqrestore(&tty_ldisc_lock, flags);
+
+	return ret;
+}
+EXPORT_SYMBOL(tty_unregister_ldisc);
+
 struct tty_ldisc *tty_ldisc_get(int disc)
 {
 	unsigned long flags;
@@ -2169,12 +2181,11 @@ static int tiocsetd(struct tty_struct *t
 	return tty_set_ldisc(tty, ldisc);
 }
 
-static int send_break(struct tty_struct *tty, int duration)
+static int send_break(struct tty_struct *tty, unsigned int duration)
 {
 	tty->driver->break_ctl(tty, -1);
 	if (!signal_pending(current)) {
-		set_current_state(TASK_INTERRUPTIBLE);
-		schedule_timeout(duration);
+		msleep_interruptible(duration);
 	}
 	tty->driver->break_ctl(tty, 0);
 	if (signal_pending(current))
@@ -2355,10 +2366,10 @@ int tty_ioctl(struct inode * inode, stru
 			 * all by anyone?
 			 */
 			if (!arg)
-				return send_break(tty, HZ/4);
+				return send_break(tty, 250);
 			return 0;
 		case TCSBRKP:	/* support for POSIX tcsendbreak() */	
-			return send_break(tty, arg ? arg*(HZ/10) : HZ/4);
+			return send_break(tty, arg ? arg*100 : 250);
 
 		case TIOCMGET:
 			return tty_tiocmget(tty, file, p);
@@ -2654,7 +2665,7 @@ static void tty_default_put_char(struct 
 	tty->driver->write(tty, &ch, 1);
 }
 
-static struct class_simple *tty_class;
+static struct class *tty_class;
 
 /**
  * tty_register_device - register a tty device
@@ -2687,7 +2698,7 @@ void tty_register_device(struct tty_driv
 		pty_line_name(driver, index, name);
 	else
 		tty_line_name(driver, index, name);
-	class_simple_device_add(tty_class, dev, device, name);
+	class_device_create(tty_class, dev, device, name);
 }
 
 /**
@@ -2701,7 +2712,7 @@ void tty_register_device(struct tty_driv
 void tty_unregister_device(struct tty_driver *driver, unsigned index)
 {
 	devfs_remove("%s%d", driver->devfs_name, index + driver->name_base);
-	class_simple_device_remove(MKDEV(driver->major, driver->minor_start) + index);
+	class_device_destroy(tty_class, MKDEV(driver->major, driver->minor_start) + index);
 }
 
 EXPORT_SYMBOL(tty_register_device);
@@ -2918,7 +2929,7 @@ extern int vty_init(void);
 
 static int __init tty_class_init(void)
 {
-	tty_class = class_simple_create(THIS_MODULE, "tty");
+	tty_class = class_create(THIS_MODULE, "tty");
 	if (IS_ERR(tty_class))
 		return PTR_ERR(tty_class);
 	return 0;
@@ -2947,14 +2958,14 @@ static int __init tty_init(void)
 	    register_chrdev_region(MKDEV(TTYAUX_MAJOR, 0), 1, "/dev/tty") < 0)
 		panic("Couldn't register /dev/tty driver\n");
 	devfs_mk_cdev(MKDEV(TTYAUX_MAJOR, 0), S_IFCHR|S_IRUGO|S_IWUGO, "tty");
-	class_simple_device_add(tty_class, MKDEV(TTYAUX_MAJOR, 0), NULL, "tty");
+	class_device_create(tty_class, MKDEV(TTYAUX_MAJOR, 0), NULL, "tty");
 
 	cdev_init(&console_cdev, &console_fops);
 	if (cdev_add(&console_cdev, MKDEV(TTYAUX_MAJOR, 1), 1) ||
 	    register_chrdev_region(MKDEV(TTYAUX_MAJOR, 1), 1, "/dev/console") < 0)
 		panic("Couldn't register /dev/console driver\n");
 	devfs_mk_cdev(MKDEV(TTYAUX_MAJOR, 1), S_IFCHR|S_IRUSR|S_IWUSR, "console");
-	class_simple_device_add(tty_class, MKDEV(TTYAUX_MAJOR, 1), NULL, "console");
+	class_device_create(tty_class, MKDEV(TTYAUX_MAJOR, 1), NULL, "console");
 
 #ifdef CONFIG_UNIX98_PTYS
 	cdev_init(&ptmx_cdev, &ptmx_fops);
@@ -2962,7 +2973,7 @@ static int __init tty_init(void)
 	    register_chrdev_region(MKDEV(TTYAUX_MAJOR, 2), 1, "/dev/ptmx") < 0)
 		panic("Couldn't register /dev/ptmx driver\n");
 	devfs_mk_cdev(MKDEV(TTYAUX_MAJOR, 2), S_IFCHR|S_IRUGO|S_IWUGO, "ptmx");
-	class_simple_device_add(tty_class, MKDEV(TTYAUX_MAJOR, 2), NULL, "ptmx");
+	class_device_create(tty_class, MKDEV(TTYAUX_MAJOR, 2), NULL, "ptmx");
 #endif
 
 #ifdef CONFIG_VT
@@ -2971,7 +2982,7 @@ static int __init tty_init(void)
 	    register_chrdev_region(MKDEV(TTY_MAJOR, 0), 1, "/dev/vc/0") < 0)
 		panic("Couldn't register /dev/tty0 driver\n");
 	devfs_mk_cdev(MKDEV(TTY_MAJOR, 0), S_IFCHR|S_IRUSR|S_IWUSR, "vc/0");
-	class_simple_device_add(tty_class, MKDEV(TTY_MAJOR, 0), NULL, "tty0");
+	class_device_create(tty_class, MKDEV(TTY_MAJOR, 0), NULL, "tty0");
 
 	vty_init();
 #endif
diff --git a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c
--- a/drivers/char/tty_ioctl.c
+++ b/drivers/char/tty_ioctl.c
@@ -476,11 +476,11 @@ int n_tty_ioctl(struct tty_struct * tty,
 			ld = tty_ldisc_ref(tty);
 			switch (arg) {
 			case TCIFLUSH:
-				if (ld->flush_buffer)
+				if (ld && ld->flush_buffer)
 					ld->flush_buffer(tty);
 				break;
 			case TCIOFLUSH:
-				if (ld->flush_buffer)
+				if (ld && ld->flush_buffer)
 					ld->flush_buffer(tty);
 				/* fall through */
 			case TCOFLUSH:
diff --git a/drivers/char/vc_screen.c b/drivers/char/vc_screen.c
--- a/drivers/char/vc_screen.c
+++ b/drivers/char/vc_screen.c
@@ -474,7 +474,7 @@ static struct file_operations vcs_fops =
 	.open		= vcs_open,
 };
 
-static struct class_simple *vc_class;
+static struct class *vc_class;
 
 void vcs_make_devfs(struct tty_struct *tty)
 {
@@ -484,26 +484,26 @@ void vcs_make_devfs(struct tty_struct *t
 	devfs_mk_cdev(MKDEV(VCS_MAJOR, tty->index + 129),
 			S_IFCHR|S_IRUSR|S_IWUSR,
 			"vcc/a%u", tty->index + 1);
-	class_simple_device_add(vc_class, MKDEV(VCS_MAJOR, tty->index + 1), NULL, "vcs%u", tty->index + 1);
-	class_simple_device_add(vc_class, MKDEV(VCS_MAJOR, tty->index + 129), NULL, "vcsa%u", tty->index + 1);
+	class_device_create(vc_class, MKDEV(VCS_MAJOR, tty->index + 1), NULL, "vcs%u", tty->index + 1);
+	class_device_create(vc_class, MKDEV(VCS_MAJOR, tty->index + 129), NULL, "vcsa%u", tty->index + 1);
 }
 void vcs_remove_devfs(struct tty_struct *tty)
 {
 	devfs_remove("vcc/%u", tty->index + 1);
 	devfs_remove("vcc/a%u", tty->index + 1);
-	class_simple_device_remove(MKDEV(VCS_MAJOR, tty->index + 1));
-	class_simple_device_remove(MKDEV(VCS_MAJOR, tty->index + 129));
+	class_device_destroy(vc_class, MKDEV(VCS_MAJOR, tty->index + 1));
+	class_device_destroy(vc_class, MKDEV(VCS_MAJOR, tty->index + 129));
 }
 
 int __init vcs_init(void)
 {
 	if (register_chrdev(VCS_MAJOR, "vcs", &vcs_fops))
 		panic("unable to get major %d for vcs device", VCS_MAJOR);
-	vc_class = class_simple_create(THIS_MODULE, "vc");
+	vc_class = class_create(THIS_MODULE, "vc");
 
 	devfs_mk_cdev(MKDEV(VCS_MAJOR, 0), S_IFCHR|S_IRUSR|S_IWUSR, "vcc/0");
 	devfs_mk_cdev(MKDEV(VCS_MAJOR, 128), S_IFCHR|S_IRUSR|S_IWUSR, "vcc/a0");
-	class_simple_device_add(vc_class, MKDEV(VCS_MAJOR, 0), NULL, "vcs");
-	class_simple_device_add(vc_class, MKDEV(VCS_MAJOR, 128), NULL, "vcsa");
+	class_device_create(vc_class, MKDEV(VCS_MAJOR, 0), NULL, "vcs");
+	class_device_create(vc_class, MKDEV(VCS_MAJOR, 128), NULL, "vcsa");
 	return 0;
 }
diff --git a/drivers/char/viotape.c b/drivers/char/viotape.c
--- a/drivers/char/viotape.c
+++ b/drivers/char/viotape.c
@@ -237,7 +237,7 @@ static dma_addr_t viotape_unitinfo_token
 
 static struct mtget viomtget[VIOTAPE_MAX_TAPE];
 
-static struct class_simple *tape_class;
+static struct class *tape_class;
 
 static struct device *tape_device[VIOTAPE_MAX_TAPE];
 
@@ -956,9 +956,9 @@ static int viotape_probe(struct vio_dev 
 	state[i].cur_part = 0;
 	for (j = 0; j < MAX_PARTITIONS; ++j)
 		state[i].part_stat_rwi[j] = VIOT_IDLE;
-	class_simple_device_add(tape_class, MKDEV(VIOTAPE_MAJOR, i), NULL,
+	class_device_create(tape_class, MKDEV(VIOTAPE_MAJOR, i), NULL,
 			"iseries!vt%d", i);
-	class_simple_device_add(tape_class, MKDEV(VIOTAPE_MAJOR, i | 0x80),
+	class_device_create(tape_class, MKDEV(VIOTAPE_MAJOR, i | 0x80),
 			NULL, "iseries!nvt%d", i);
 	devfs_mk_cdev(MKDEV(VIOTAPE_MAJOR, i), S_IFCHR | S_IRUSR | S_IWUSR,
 			"iseries/vt%d", i);
@@ -980,8 +980,8 @@ static int viotape_remove(struct vio_dev
 	devfs_remove("iseries/nvt%d", i);
 	devfs_remove("iseries/vt%d", i);
 	devfs_unregister_tape(state[i].dev_handle);
-	class_simple_device_remove(MKDEV(VIOTAPE_MAJOR, i | 0x80));
-	class_simple_device_remove(MKDEV(VIOTAPE_MAJOR, i));
+	class_device_destroy(tape_class, MKDEV(VIOTAPE_MAJOR, i | 0x80));
+	class_device_destroy(tape_class, MKDEV(VIOTAPE_MAJOR, i));
 	return 0;
 }
 
@@ -1045,7 +1045,7 @@ int __init viotap_init(void)
 		goto clear_handler;
 	}
 
-	tape_class = class_simple_create(THIS_MODULE, "tape");
+	tape_class = class_create(THIS_MODULE, "tape");
 	if (IS_ERR(tape_class)) {
 		printk(VIOTAPE_KERN_WARN "Unable to allocat class\n");
 		ret = PTR_ERR(tape_class);
@@ -1070,7 +1070,7 @@ int __init viotap_init(void)
 	return 0;
 
 unreg_class:
-	class_simple_destroy(tape_class);
+	class_destroy(tape_class);
 unreg_chrdev:
 	unregister_chrdev(VIOTAPE_MAJOR, "viotape");
 clear_handler:
@@ -1110,7 +1110,7 @@ static void __exit viotap_exit(void)
 
 	remove_proc_entry("iSeries/viotape", NULL);
 	vio_unregister_driver(&viotape_driver);
-	class_simple_destroy(tape_class);
+	class_destroy(tape_class);
 	ret = unregister_chrdev(VIOTAPE_MAJOR, "viotape");
 	if (ret < 0)
 		printk(VIOTAPE_KERN_WARN "Error unregistering device: %d\n",
diff --git a/drivers/char/vr41xx_giu.c b/drivers/char/vr41xx_giu.c
new file mode 100644
--- /dev/null
+++ b/drivers/char/vr41xx_giu.c
@@ -0,0 +1,743 @@
+/*
+ *  Driver for NEC VR4100 series General-purpose I/O Unit.
+ *
+ *  Copyright (C) 2002 MontaVista Software Inc.
+ *	Author: Yoichi Yuasa <yyuasa@mvista.com or source@mvista.com>
+ *  Copyright (C) 2003-2005  Yoichi Yuasa <yuasa@hh.iij4u.or.jp>
+ *
+ *  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/device.h>
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+
+#include <asm/cpu.h>
+#include <asm/io.h>
+#include <asm/vr41xx/giu.h>
+#include <asm/vr41xx/vr41xx.h>
+
+MODULE_AUTHOR("Yoichi Yuasa <yuasa@hh.iij4u.or.jp>");
+MODULE_DESCRIPTION("NEC VR4100 series General-purpose I/O Unit driver");
+MODULE_LICENSE("GPL");
+
+static int major;	/* default is dynamic major device number */
+module_param(major, int, 0);
+MODULE_PARM_DESC(major, "Major device number");
+
+#define GIU_TYPE1_START		0x0b000100UL
+#define GIU_TYPE1_SIZE		0x20UL
+
+#define GIU_TYPE2_START		0x0f000140UL
+#define GIU_TYPE2_SIZE		0x20UL
+
+#define GIU_TYPE3_START		0x0f000140UL
+#define GIU_TYPE3_SIZE		0x28UL
+
+#define GIU_PULLUPDOWN_START	0x0b0002e0UL
+#define GIU_PULLUPDOWN_SIZE	0x04UL
+
+#define GIUIOSELL	0x00
+#define GIUIOSELH	0x02
+#define GIUPIODL	0x04
+#define GIUPIODH	0x06
+#define GIUINTSTATL	0x08
+#define GIUINTSTATH	0x0a
+#define GIUINTENL	0x0c
+#define GIUINTENH	0x0e
+#define GIUINTTYPL	0x10
+#define GIUINTTYPH	0x12
+#define GIUINTALSELL	0x14
+#define GIUINTALSELH	0x16
+#define GIUINTHTSELL	0x18
+#define GIUINTHTSELH	0x1a
+#define GIUPODATL	0x1c
+#define GIUPODATEN	0x1c
+#define GIUPODATH	0x1e
+ #define PIOEN0		0x0100
+ #define PIOEN1		0x0200
+#define GIUPODAT	0x1e
+#define GIUFEDGEINHL	0x20
+#define GIUFEDGEINHH	0x22
+#define GIUREDGEINHL	0x24
+#define GIUREDGEINHH	0x26
+
+#define GIUUSEUPDN	0x1e0
+#define GIUTERMUPDN	0x1e2
+
+#define GPIO_HAS_PULLUPDOWN_IO		0x0001
+#define GPIO_HAS_OUTPUT_ENABLE		0x0002
+#define GPIO_HAS_INTERRUPT_EDGE_SELECT	0x0100
+
+static spinlock_t giu_lock;
+static struct resource *giu_resource1;
+static struct resource *giu_resource2;
+static unsigned long giu_flags;
+static unsigned int giu_nr_pins;
+
+static void __iomem *giu_base;
+
+#define giu_read(offset)		readw(giu_base + (offset))
+#define giu_write(offset, value)	writew((value), giu_base + (offset))
+
+#define GPIO_PIN_OF_IRQ(irq)	((irq) - GIU_IRQ_BASE)
+#define GIUINT_HIGH_OFFSET	16
+#define GIUINT_HIGH_MAX		32
+
+static inline uint16_t giu_set(uint16_t offset, uint16_t set)
+{
+	uint16_t data;
+
+	data = giu_read(offset);
+	data |= set;
+	giu_write(offset, data);
+
+	return data;
+}
+
+static inline uint16_t giu_clear(uint16_t offset, uint16_t clear)
+{
+	uint16_t data;
+
+	data = giu_read(offset);
+	data &= ~clear;
+	giu_write(offset, data);
+
+	return data;
+}
+
+static unsigned int startup_giuint_low_irq(unsigned int irq)
+{
+	unsigned int pin;
+
+	pin = GPIO_PIN_OF_IRQ(irq);
+	giu_write(GIUINTSTATL, 1 << pin);
+	giu_set(GIUINTENL, 1 << pin);
+
+	return 0;
+}
+
+static void shutdown_giuint_low_irq(unsigned int irq)
+{
+	giu_clear(GIUINTENL, 1 << GPIO_PIN_OF_IRQ(irq));
+}
+
+static void enable_giuint_low_irq(unsigned int irq)
+{
+	giu_set(GIUINTENL, 1 << GPIO_PIN_OF_IRQ(irq));
+}
+
+#define disable_giuint_low_irq	shutdown_giuint_low_irq
+
+static void ack_giuint_low_irq(unsigned int irq)
+{
+	unsigned int pin;
+
+	pin = GPIO_PIN_OF_IRQ(irq);
+	giu_clear(GIUINTENL, 1 << pin);
+	giu_write(GIUINTSTATL, 1 << pin);
+}
+
+static void end_giuint_low_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+		giu_set(GIUINTENL, 1 << GPIO_PIN_OF_IRQ(irq));
+}
+
+static struct hw_interrupt_type giuint_low_irq_type = {
+	.typename	= "GIUINTL",
+	.startup	= startup_giuint_low_irq,
+	.shutdown	= shutdown_giuint_low_irq,
+	.enable		= enable_giuint_low_irq,
+	.disable	= disable_giuint_low_irq,
+	.ack		= ack_giuint_low_irq,
+	.end		= end_giuint_low_irq,
+};
+
+static unsigned int startup_giuint_high_irq(unsigned int irq)
+{
+	unsigned int pin;
+
+	pin = GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET;
+	giu_write(GIUINTSTATH, 1 << pin);
+	giu_set(GIUINTENH, 1 << pin);
+
+	return 0;
+}
+
+static void shutdown_giuint_high_irq(unsigned int irq)
+{
+	giu_clear(GIUINTENH, 1 << (GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET));
+}
+
+static void enable_giuint_high_irq(unsigned int irq)
+{
+	giu_set(GIUINTENH, 1 << (GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET));
+}
+
+#define disable_giuint_high_irq	shutdown_giuint_high_irq
+
+static void ack_giuint_high_irq(unsigned int irq)
+{
+	unsigned int pin;
+
+	pin = GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET;
+	giu_clear(GIUINTENH, 1 << pin);
+	giu_write(GIUINTSTATH, 1 << pin);
+}
+
+static void end_giuint_high_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+		giu_set(GIUINTENH, 1 << (GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET));
+}
+
+static struct hw_interrupt_type giuint_high_irq_type = {
+	.typename	= "GIUINTH",
+	.startup	= startup_giuint_high_irq,
+	.shutdown	= shutdown_giuint_high_irq,
+	.enable		= enable_giuint_high_irq,
+	.disable	= disable_giuint_high_irq,
+	.ack		= ack_giuint_high_irq,
+	.end		= end_giuint_high_irq,
+};
+
+static int giu_get_irq(unsigned int irq, struct pt_regs *regs)
+{
+	uint16_t pendl, pendh, maskl, maskh;
+	int i;
+
+	pendl = giu_read(GIUINTSTATL);
+	pendh = giu_read(GIUINTSTATH);
+	maskl = giu_read(GIUINTENL);
+	maskh = giu_read(GIUINTENH);
+
+	maskl &= pendl;
+	maskh &= pendh;
+
+	if (maskl) {
+		for (i = 0; i < 16; i++) {
+			if (maskl & (1 << i))
+				return GIU_IRQ(i);
+		}
+	} else if (maskh) {
+		for (i = 0; i < 16; i++) {
+			if (maskh & (1 << i))
+				return GIU_IRQ(i + GIUINT_HIGH_OFFSET);
+		}
+	}
+
+	printk(KERN_ERR "spurious GIU interrupt: %04x(%04x),%04x(%04x)\n",
+	       maskl, pendl, maskh, pendh);
+
+	atomic_inc(&irq_err_count);
+
+	return -EINVAL;
+}
+
+void vr41xx_set_irq_trigger(unsigned int pin, irq_trigger_t trigger, irq_signal_t signal)
+{
+	uint16_t mask;
+
+	if (pin < GIUINT_HIGH_OFFSET) {
+		mask = 1 << pin;
+		if (trigger != IRQ_TRIGGER_LEVEL) {
+        		giu_set(GIUINTTYPL, mask);
+			if (signal == IRQ_SIGNAL_HOLD)
+				giu_set(GIUINTHTSELL, mask);
+			else
+				giu_clear(GIUINTHTSELL, mask);
+			if (current_cpu_data.cputype == CPU_VR4133) {
+				switch (trigger) {
+				case IRQ_TRIGGER_EDGE_FALLING:
+					giu_set(GIUFEDGEINHL, mask);
+					giu_clear(GIUREDGEINHL, mask);
+					break;
+				case IRQ_TRIGGER_EDGE_RISING:
+					giu_clear(GIUFEDGEINHL, mask);
+					giu_set(GIUREDGEINHL, mask);
+					break;
+				default:
+					giu_set(GIUFEDGEINHL, mask);
+					giu_set(GIUREDGEINHL, mask);
+					break;
+				}
+			}
+		} else {
+			giu_clear(GIUINTTYPL, mask);
+			giu_clear(GIUINTHTSELL, mask);
+		}
+		giu_write(GIUINTSTATL, mask);
+	} else if (pin < GIUINT_HIGH_MAX) {
+		mask = 1 << (pin - GIUINT_HIGH_OFFSET);
+		if (trigger != IRQ_TRIGGER_LEVEL) {
+			giu_set(GIUINTTYPH, mask);
+			if (signal == IRQ_SIGNAL_HOLD)
+				giu_set(GIUINTHTSELH, mask);
+			else
+				giu_clear(GIUINTHTSELH, mask);
+			if (current_cpu_data.cputype == CPU_VR4133) {
+				switch (trigger) {
+				case IRQ_TRIGGER_EDGE_FALLING:
+					giu_set(GIUFEDGEINHH, mask);
+					giu_clear(GIUREDGEINHH, mask);
+					break;
+				case IRQ_TRIGGER_EDGE_RISING:
+					giu_clear(GIUFEDGEINHH, mask);
+					giu_set(GIUREDGEINHH, mask);
+					break;
+				default:
+					giu_set(GIUFEDGEINHH, mask);
+					giu_set(GIUREDGEINHH, mask);
+					break;
+				}
+			}
+		} else {
+			giu_clear(GIUINTTYPH, mask);
+			giu_clear(GIUINTHTSELH, mask);
+		}
+		giu_write(GIUINTSTATH, mask);
+	}
+}
+
+EXPORT_SYMBOL_GPL(vr41xx_set_irq_trigger);
+
+void vr41xx_set_irq_level(unsigned int pin, irq_level_t level)
+{
+	uint16_t mask;
+
+	if (pin < GIUINT_HIGH_OFFSET) {
+		mask = 1 << pin;
+		if (level == IRQ_LEVEL_HIGH)
+			giu_set(GIUINTALSELL, mask);
+		else
+			giu_clear(GIUINTALSELL, mask);
+		giu_write(GIUINTSTATL, mask);
+	} else if (pin < GIUINT_HIGH_MAX) {
+		mask = 1 << (pin - GIUINT_HIGH_OFFSET);
+		if (level == IRQ_LEVEL_HIGH)
+			giu_set(GIUINTALSELH, mask);
+		else
+			giu_clear(GIUINTALSELH, mask);
+		giu_write(GIUINTSTATH, mask);
+	}
+}
+
+EXPORT_SYMBOL_GPL(vr41xx_set_irq_level);
+
+gpio_data_t vr41xx_gpio_get_pin(unsigned int pin)
+{
+	uint16_t reg, mask;
+
+	if (pin >= giu_nr_pins)
+		return GPIO_DATA_INVAL;
+
+	if (pin < 16) {
+		reg = giu_read(GIUPIODL);
+		mask = (uint16_t)1 << pin;
+	} else if (pin < 32) {
+		reg = giu_read(GIUPIODH);
+		mask = (uint16_t)1 << (pin - 16);
+	} else if (pin < 48) {
+		reg = giu_read(GIUPODATL);
+		mask = (uint16_t)1 << (pin - 32);
+	} else {
+		reg = giu_read(GIUPODATH);
+		mask = (uint16_t)1 << (pin - 48);
+	}
+
+	if (reg & mask)
+		return GPIO_DATA_HIGH;
+
+	return GPIO_DATA_LOW;
+}
+
+EXPORT_SYMBOL_GPL(vr41xx_gpio_get_pin);
+
+int vr41xx_gpio_set_pin(unsigned int pin, gpio_data_t data)
+{
+	uint16_t offset, mask, reg;
+	unsigned long flags;
+
+	if (pin >= giu_nr_pins)
+		return -EINVAL;
+
+	if (pin < 16) {
+		offset = GIUPIODL;
+		mask = (uint16_t)1 << pin;
+	} else if (pin < 32) {
+		offset = GIUPIODH;
+		mask = (uint16_t)1 << (pin - 16);
+	} else if (pin < 48) {
+		offset = GIUPODATL;
+		mask = (uint16_t)1 << (pin - 32);
+	} else {
+		offset = GIUPODATH;
+		mask = (uint16_t)1 << (pin - 48);
+	}
+
+	spin_lock_irqsave(&giu_lock, flags);
+
+	reg = giu_read(offset);
+	if (data == GPIO_DATA_HIGH)
+		reg |= mask;
+	else
+		reg &= ~mask;
+	giu_write(offset, reg);
+
+	spin_unlock_irqrestore(&giu_lock, flags);
+
+	return 0;
+}
+
+EXPORT_SYMBOL_GPL(vr41xx_gpio_set_pin);
+
+int vr41xx_gpio_set_direction(unsigned int pin, gpio_direction_t dir)
+{
+	uint16_t offset, mask, reg;
+	unsigned long flags;
+
+	if (pin >= giu_nr_pins)
+		return -EINVAL;
+
+	if (pin < 16) {
+		offset = GIUIOSELL;
+		mask = (uint16_t)1 << pin;
+	} else if (pin < 32) {
+		offset = GIUIOSELH;
+		mask = (uint16_t)1 << (pin - 16);
+	} else {
+		if (giu_flags & GPIO_HAS_OUTPUT_ENABLE) {
+			offset = GIUPODATEN;
+			mask = (uint16_t)1 << (pin - 32);
+		} else {
+			switch (pin) {
+			case 48:
+				offset = GIUPODATH;
+				mask = PIOEN0;
+				break;
+			case 49:
+				offset = GIUPODATH;
+				mask = PIOEN1;
+				break;
+			default:
+				return -EINVAL;
+			}
+		}
+	}
+
+	spin_lock_irqsave(&giu_lock, flags);
+
+	reg = giu_read(offset);
+	if (dir == GPIO_OUTPUT)
+		reg |= mask;
+	else
+		reg &= ~mask;
+	giu_write(offset, reg);
+
+	spin_unlock_irqrestore(&giu_lock, flags);
+
+	return 0;
+}
+
+EXPORT_SYMBOL_GPL(vr41xx_gpio_set_direction);
+
+int vr41xx_gpio_pullupdown(unsigned int pin, gpio_pull_t pull)
+{
+	uint16_t reg, mask;
+	unsigned long flags;
+
+	if ((giu_flags & GPIO_HAS_PULLUPDOWN_IO) != GPIO_HAS_PULLUPDOWN_IO)
+		return -EPERM;
+
+	if (pin >= 15)
+		return -EINVAL;
+
+	mask = (uint16_t)1 << pin;
+
+	spin_lock_irqsave(&giu_lock, flags);
+
+	if (pull == GPIO_PULL_UP || pull == GPIO_PULL_DOWN) {
+		reg = giu_read(GIUTERMUPDN);
+		if (pull == GPIO_PULL_UP)
+			reg |= mask;
+		else
+			reg &= ~mask;
+		giu_write(GIUTERMUPDN, reg);
+
+		reg = giu_read(GIUUSEUPDN);
+		reg |= mask;
+		giu_write(GIUUSEUPDN, reg);
+	} else {
+		reg = giu_read(GIUUSEUPDN);
+		reg &= ~mask;
+		giu_write(GIUUSEUPDN, reg);
+	}
+
+	spin_unlock_irqrestore(&giu_lock, flags);
+
+	return 0;
+}
+
+EXPORT_SYMBOL_GPL(vr41xx_gpio_pullupdown);
+
+static ssize_t gpio_read(struct file *file, char __user *buf, size_t len,
+                         loff_t *ppos)
+{
+	unsigned int pin;
+	char value = '0';
+
+	pin = iminor(file->f_dentry->d_inode);
+	if (pin >= giu_nr_pins)
+		return -EBADF;
+
+	if (vr41xx_gpio_get_pin(pin) == GPIO_DATA_HIGH)
+		value = '1';
+
+	if (len <= 0)
+		return -EFAULT;
+
+	if (put_user(value, buf))
+		return -EFAULT;
+
+	return 1;
+}
+
+static ssize_t gpio_write(struct file *file, const char __user *data,
+                          size_t len, loff_t *ppos)
+{
+	unsigned int pin;
+	size_t i;
+	char c;
+	int retval = 0;
+
+	pin = iminor(file->f_dentry->d_inode);
+	if (pin >= giu_nr_pins)
+		return -EBADF;
+
+	for (i = 0; i < len; i++) {
+		if (get_user(c, data + i))
+			return -EFAULT;
+
+		switch (c) {
+		case '0':
+			retval = vr41xx_gpio_set_pin(pin, GPIO_DATA_LOW);
+			break;
+		case '1':
+			retval = vr41xx_gpio_set_pin(pin, GPIO_DATA_HIGH);
+			break;
+		case 'D':
+			printk(KERN_INFO "GPIO%d: pull down\n", pin);
+			retval = vr41xx_gpio_pullupdown(pin, GPIO_PULL_DOWN);
+			break;
+		case 'd':
+			printk(KERN_INFO "GPIO%d: pull up/down disable\n", pin);
+			retval = vr41xx_gpio_pullupdown(pin, GPIO_PULL_DISABLE);
+			break;
+		case 'I':
+			printk(KERN_INFO "GPIO%d: input\n", pin);
+			retval = vr41xx_gpio_set_direction(pin, GPIO_INPUT);
+			break;
+		case 'O':
+			printk(KERN_INFO "GPIO%d: output\n", pin);
+			retval = vr41xx_gpio_set_direction(pin, GPIO_OUTPUT);
+			break;
+		case 'o':
+			printk(KERN_INFO "GPIO%d: output disable\n", pin);
+			retval = vr41xx_gpio_set_direction(pin, GPIO_OUTPUT_DISABLE);
+			break;
+		case 'P':
+			printk(KERN_INFO "GPIO%d: pull up\n", pin);
+			retval = vr41xx_gpio_pullupdown(pin, GPIO_PULL_UP);
+			break;
+		case 'p':
+			printk(KERN_INFO "GPIO%d: pull up/down disable\n", pin);
+			retval = vr41xx_gpio_pullupdown(pin, GPIO_PULL_DISABLE);
+			break;
+		default:
+			break;
+		}
+
+		if (retval < 0)
+			break;
+	}
+
+	return i;
+}
+
+static int gpio_open(struct inode *inode, struct file *file)
+{
+	unsigned int pin;
+
+	pin = iminor(inode);
+	if (pin >= giu_nr_pins)
+		return -EBADF;
+
+	return nonseekable_open(inode, file);
+}
+
+static int gpio_release(struct inode *inode, struct file *file)
+{
+	unsigned int pin;
+
+	pin = iminor(inode);
+	if (pin >= giu_nr_pins)
+		return -EBADF;
+
+	return 0;
+}
+
+static struct file_operations gpio_fops = {
+	.owner		= THIS_MODULE,
+	.read		= gpio_read,
+	.write		= gpio_write,
+	.open		= gpio_open,
+	.release	= gpio_release,
+};
+
+static int giu_probe(struct device *dev)
+{
+	unsigned long start, size, flags = 0;
+	unsigned int nr_pins = 0;
+	struct resource *res1, *res2 = NULL;
+	void *base;
+	int retval, i;
+
+	switch (current_cpu_data.cputype) {
+	case CPU_VR4111:
+	case CPU_VR4121:
+		start = GIU_TYPE1_START;
+		size = GIU_TYPE1_SIZE;
+		flags = GPIO_HAS_PULLUPDOWN_IO;
+		nr_pins = 50;
+		break;
+	case CPU_VR4122:
+	case CPU_VR4131:
+		start = GIU_TYPE2_START;
+		size = GIU_TYPE2_SIZE;
+		nr_pins = 36;
+		break;
+	case CPU_VR4133:
+		start = GIU_TYPE3_START;
+		size = GIU_TYPE3_SIZE;
+		flags = GPIO_HAS_INTERRUPT_EDGE_SELECT;
+		nr_pins = 48;
+		break;
+	default:
+		return -ENODEV;
+	}
+
+	res1 = request_mem_region(start, size, "GIU");
+	if (res1 == NULL)
+		return -EBUSY;
+
+	base = ioremap(start, size);
+	if (base == NULL) {
+		release_resource(res1);
+		return -ENOMEM;
+	}
+
+	if (flags & GPIO_HAS_PULLUPDOWN_IO) {
+		res2 = request_mem_region(GIU_PULLUPDOWN_START, GIU_PULLUPDOWN_SIZE, "GIU");
+		if (res2 == NULL) {
+			iounmap(base);
+			release_resource(res1);
+			return -EBUSY;
+		}
+	}
+
+	retval = register_chrdev(major, "GIU", &gpio_fops);
+	if (retval < 0) {
+		iounmap(base);
+		release_resource(res1);
+		release_resource(res2);
+		return retval;
+	}
+
+	if (major == 0) {
+		major = retval;
+		printk(KERN_INFO "GIU: major number %d\n", major);
+	}
+
+	spin_lock_init(&giu_lock);
+	giu_base = base;
+	giu_resource1 = res1;
+	giu_resource2 = res2;
+	giu_flags = flags;
+	giu_nr_pins = nr_pins;
+
+	giu_write(GIUINTENL, 0);
+	giu_write(GIUINTENH, 0);
+
+	for (i = GIU_IRQ_BASE; i <= GIU_IRQ_LAST; i++) {
+		if (i < GIU_IRQ(GIUINT_HIGH_OFFSET))
+			irq_desc[i].handler = &giuint_low_irq_type;
+		else
+			irq_desc[i].handler = &giuint_high_irq_type;
+	}
+
+	return cascade_irq(GIUINT_IRQ, giu_get_irq);
+}
+
+static int giu_remove(struct device *dev)
+{
+	iounmap(giu_base);
+
+	release_resource(giu_resource1);
+	if (giu_flags & GPIO_HAS_PULLUPDOWN_IO)
+		release_resource(giu_resource2);
+
+	return 0;
+}
+
+static struct platform_device *giu_platform_device;
+
+static struct device_driver giu_device_driver = {
+	.name		= "GIU",
+	.bus		= &platform_bus_type,
+	.probe		= giu_probe,
+	.remove		= giu_remove,
+};
+
+static int __devinit vr41xx_giu_init(void)
+{
+	int retval;
+
+	giu_platform_device = platform_device_register_simple("GIU", -1, NULL, 0);
+	if (IS_ERR(giu_platform_device))
+		return PTR_ERR(giu_platform_device);
+
+	retval = driver_register(&giu_device_driver);
+	if (retval < 0)
+		platform_device_unregister(giu_platform_device);
+
+	return retval;
+}
+
+static void __devexit vr41xx_giu_exit(void)
+{
+	driver_unregister(&giu_device_driver);
+
+	platform_device_unregister(giu_platform_device);
+}
+
+module_init(vr41xx_giu_init);
+module_exit(vr41xx_giu_exit);
diff --git a/drivers/char/vt.c b/drivers/char/vt.c
--- a/drivers/char/vt.c
+++ b/drivers/char/vt.c
@@ -2433,7 +2433,7 @@ static int con_open(struct tty_struct *t
 	int ret = 0;
 
 	acquire_console_sem();
-	if (tty->count == 1) {
+	if (tty->driver_data == NULL) {
 		ret = vc_allocate(currcons);
 		if (ret == 0) {
 			struct vc_data *vc = vc_cons[currcons].d;
@@ -2796,7 +2796,7 @@ void do_blank_screen(int entering_gfx)
 		return;
 
 	if (vesa_off_interval) {
-		blank_state = blank_vesa_wait,
+		blank_state = blank_vesa_wait;
 		mod_timer(&console_timer, jiffies + vesa_off_interval);
 	}
 
@@ -2867,6 +2867,10 @@ void unblank_screen(void)
  */
 static void blank_screen_t(unsigned long dummy)
 {
+	if (unlikely(!keventd_up())) {
+		mod_timer(&console_timer, jiffies + blankinterval);
+		return;
+	}
 	blank_timer_expired = 1;
 	schedule_work(&console_work);
 }
diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c
--- a/drivers/char/vt_ioctl.c
+++ b/drivers/char/vt_ioctl.c
@@ -25,6 +25,7 @@
 #include <linux/fs.h>
 #include <linux/console.h>
 #include <linux/signal.h>
+#include <linux/timex.h>
 
 #include <asm/io.h>
 #include <asm/uaccess.h>
@@ -386,7 +387,7 @@ int vt_ioctl(struct tty_struct *tty, str
 		if (!perm)
 			return -EPERM;
 		if (arg)
-			arg = 1193182 / arg;
+			arg = CLOCK_TICK_RATE / arg;
 		kd_mksound(arg, 0);
 		return 0;
 
@@ -403,7 +404,7 @@ int vt_ioctl(struct tty_struct *tty, str
 		ticks = HZ * ((arg >> 16) & 0xffff) / 1000;
 		count = ticks ? (arg & 0xffff) : 0;
 		if (count)
-			count = 1193182 / count;
+			count = CLOCK_TICK_RATE / count;
 		kd_mksound(count, ticks);
 		return 0;
 	}
diff --git a/drivers/char/watchdog/Kconfig b/drivers/char/watchdog/Kconfig
--- a/drivers/char/watchdog/Kconfig
+++ b/drivers/char/watchdog/Kconfig
@@ -414,6 +414,16 @@ config WATCHDOG_RIO
 	  machines.  The watchdog timeout period is normally one minute but
 	  can be changed with a boot-time parameter.
 
+# ppc64 RTAS watchdog
+config WATCHDOG_RTAS
+	tristate "RTAS watchdog"
+	depends on WATCHDOG && PPC_RTAS
+	help
+	  This driver adds watchdog support for the RTAS watchdog.
+
+          To compile this driver as a module, choose M here. The module
+	  will be called wdrtas.
+
 #
 # ISA-based Watchdog Cards
 #
diff --git a/drivers/char/watchdog/Makefile b/drivers/char/watchdog/Makefile
--- a/drivers/char/watchdog/Makefile
+++ b/drivers/char/watchdog/Makefile
@@ -33,6 +33,7 @@ obj-$(CONFIG_USBPCWATCHDOG) += pcwd_usb.
 obj-$(CONFIG_IXP4XX_WATCHDOG) += ixp4xx_wdt.o
 obj-$(CONFIG_IXP2000_WATCHDOG) += ixp2000_wdt.o
 obj-$(CONFIG_8xx_WDT) += mpc8xx_wdt.o
+obj-$(CONFIG_WATCHDOG_RTAS) += wdrtas.o
 
 # Only one watchdog can succeed. We probe the hardware watchdog
 # drivers first, then the softdog driver.  This means if your hardware
diff --git a/drivers/char/watchdog/acquirewdt.c b/drivers/char/watchdog/acquirewdt.c
--- a/drivers/char/watchdog/acquirewdt.c
+++ b/drivers/char/watchdog/acquirewdt.c
@@ -82,12 +82,7 @@ static int wdt_start = 0x443;
 module_param(wdt_start, int, 0);
 MODULE_PARM_DESC(wdt_start, "Acquire WDT 'start' io port (default 0x443)");
 
-#ifdef CONFIG_WATCHDOG_NOWAYOUT
-static int nowayout = 1;
-#else
-static int nowayout = 0;
-#endif
-
+static int nowayout = WATCHDOG_NOWAYOUT;
 module_param(nowayout, int, 0);
 MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
 
diff --git a/drivers/char/watchdog/advantechwdt.c b/drivers/char/watchdog/advantechwdt.c
--- a/drivers/char/watchdog/advantechwdt.c
+++ b/drivers/char/watchdog/advantechwdt.c
@@ -73,12 +73,7 @@ static int timeout = WATCHDOG_TIMEOUT;	/
 module_param(timeout, int, 0);
 MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. 1<= timeout <=63, default=" __MODULE_STRING(WATCHDOG_TIMEOUT) ".");
 
-#ifdef CONFIG_WATCHDOG_NOWAYOUT
-static int nowayout = 1;
-#else
-static int nowayout = 0;
-#endif
-
+static int nowayout = WATCHDOG_NOWAYOUT;
 module_param(nowayout, int, 0);
 MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
 
diff --git a/drivers/char/watchdog/alim1535_wdt.c b/drivers/char/watchdog/alim1535_wdt.c
--- a/drivers/char/watchdog/alim1535_wdt.c
+++ b/drivers/char/watchdog/alim1535_wdt.c
@@ -38,12 +38,7 @@ static int timeout = WATCHDOG_TIMEOUT;
 module_param(timeout, int, 0);
 MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (0<timeout<18000, default=" __MODULE_STRING(WATCHDOG_TIMEOUT) ")");
 
-#ifdef CONFIG_WATCHDOG_NOWAYOUT
-static int nowayout = 1;
-#else
-static int nowayout = 0;
-#endif
-
+static int nowayout = WATCHDOG_NOWAYOUT;
 module_param(nowayout, int, 0);
 MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
 
@@ -317,7 +312,7 @@ static int ali_notify_sys(struct notifie
  */
 
 static struct pci_device_id ali_pci_tbl[] = {
-	{ PCI_VENDOR_ID_AL, 1535, PCI_ANY_ID, PCI_ANY_ID,},
+	{ PCI_VENDOR_ID_AL, 0x1535, PCI_ANY_ID, PCI_ANY_ID,},
 	{ 0, },
 };
 MODULE_DEVICE_TABLE(pci, ali_pci_tbl);
diff --git a/drivers/char/watchdog/alim7101_wdt.c b/drivers/char/watchdog/alim7101_wdt.c
--- a/drivers/char/watchdog/alim7101_wdt.c
+++ b/drivers/char/watchdog/alim7101_wdt.c
@@ -75,12 +75,7 @@ static unsigned long wdt_is_open;
 static char wdt_expect_close;
 static struct pci_dev *alim7101_pmu;
 
-#ifdef CONFIG_WATCHDOG_NOWAYOUT
-static int nowayout = 1;
-#else
-static int nowayout = 0;
-#endif
-
+static int nowayout = WATCHDOG_NOWAYOUT;
 module_param(nowayout, int, 0);
 MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
 
diff --git a/drivers/char/watchdog/eurotechwdt.c b/drivers/char/watchdog/eurotechwdt.c
--- a/drivers/char/watchdog/eurotechwdt.c
+++ b/drivers/char/watchdog/eurotechwdt.c
@@ -72,12 +72,7 @@ static char *ev = "int";
 
 #define WDT_TIMEOUT		60                /* 1 minute */
 
-#ifdef CONFIG_WATCHDOG_NOWAYOUT
-static int nowayout = 1;
-#else
-static int nowayout = 0;
-#endif
-
+static int nowayout = WATCHDOG_NOWAYOUT;
 module_param(nowayout, int, 0);
 MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
 
@@ -167,7 +162,7 @@ static irqreturn_t eurwdt_interrupt(int 
 	printk(KERN_CRIT "Would Reboot.\n");
 #else
 	printk(KERN_CRIT "Initiating system reboot.\n");
-	machine_restart(NULL);
+	emergency_restart();
 #endif
 	return IRQ_HANDLED;
 }
diff --git a/drivers/char/watchdog/i8xx_tco.c b/drivers/char/watchdog/i8xx_tco.c
--- a/drivers/char/watchdog/i8xx_tco.c
+++ b/drivers/char/watchdog/i8xx_tco.c
@@ -1,5 +1,5 @@
 /*
- *	i8xx_tco 0.07:	TCO timer driver for i8xx chipsets
+ *	i8xx_tco:	TCO timer driver for i8xx chipsets
  *
  *	(c) Copyright 2000 kernel concepts <nils@kernelconcepts.de>, All Rights Reserved.
  *				http://www.kernelconcepts.de
@@ -63,6 +63,9 @@
  *  20050128 Wim Van Sebroeck <wim@iguana.be>
  *	0.07 Added support for the ICH4-M, ICH6, ICH6R, ICH6-M, ICH6W and ICH6RW
  *	     chipsets. Also added support for the "undocumented" ICH7 chipset.
+ *  20050807 Wim Van Sebroeck <wim@iguana.be>
+ *	0.08 Make sure that the watchdog is only "armed" when started.
+ *	     (Kernel Bug 4251)
  */
 
 /*
@@ -87,7 +90,7 @@
 #include "i8xx_tco.h"
 
 /* Module and version information */
-#define TCO_VERSION "0.07"
+#define TCO_VERSION "0.08"
 #define TCO_MODULE_NAME "i8xx TCO timer"
 #define TCO_DRIVER_NAME   TCO_MODULE_NAME ", v" TCO_VERSION
 #define PFX TCO_MODULE_NAME ": "
@@ -105,12 +108,7 @@ static int heartbeat = WATCHDOG_HEARTBEA
 module_param(heartbeat, int, 0);
 MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (2<heartbeat<39, default=" __MODULE_STRING(WATCHDOG_HEARTBEAT) ")");
 
-#ifdef CONFIG_WATCHDOG_NOWAYOUT
-static int nowayout = 1;
-#else
-static int nowayout = 0;
-#endif
-
+static int nowayout = WATCHDOG_NOWAYOUT;
 module_param(nowayout, int, 0);
 MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
 
@@ -130,10 +128,18 @@ static int tco_timer_start (void)
 	unsigned char val;
 
 	spin_lock(&tco_lock);
+
+	/* disable chipset's NO_REBOOT bit */
+	pci_read_config_byte (i8xx_tco_pci, 0xd4, &val);
+	val &= 0xfd;
+	pci_write_config_byte (i8xx_tco_pci, 0xd4, val);
+
+	/* Bit 11: TCO Timer Halt -> 0 = The TCO timer is enabled to count */
 	val = inb (TCO1_CNT + 1);
 	val &= 0xf7;
 	outb (val, TCO1_CNT + 1);
 	val = inb (TCO1_CNT + 1);
+
 	spin_unlock(&tco_lock);
 
 	if (val & 0x08)
@@ -143,13 +149,20 @@ static int tco_timer_start (void)
 
 static int tco_timer_stop (void)
 {
-	unsigned char val;
+	unsigned char val, val1;
 
 	spin_lock(&tco_lock);
+	/* Bit 11: TCO Timer Halt -> 1 = The TCO timer is disabled */
 	val = inb (TCO1_CNT + 1);
 	val |= 0x08;
 	outb (val, TCO1_CNT + 1);
 	val = inb (TCO1_CNT + 1);
+
+	/* Set the NO_REBOOT bit to prevent later reboots, just for sure */
+	pci_read_config_byte (i8xx_tco_pci, 0xd4, &val1);
+	val1 |= 0x02;
+	pci_write_config_byte (i8xx_tco_pci, 0xd4, val1);
+
 	spin_unlock(&tco_lock);
 
 	if ((val & 0x08) == 0)
@@ -160,6 +173,7 @@ static int tco_timer_stop (void)
 static int tco_timer_keepalive (void)
 {
 	spin_lock(&tco_lock);
+	/* Reload the timer by writing to the TCO Timer Reload register */
 	outb (0x01, TCO1_RLD);
 	spin_unlock(&tco_lock);
 	return 0;
@@ -401,7 +415,7 @@ static unsigned char __init i8xx_tco_get
 	 */
 
 	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
-		if (pci_match_device(i8xx_tco_pci_tbl, dev)) {
+		if (pci_match_id(i8xx_tco_pci_tbl, dev)) {
 			i8xx_tco_pci = dev;
 			break;
 		}
@@ -422,9 +436,8 @@ static unsigned char __init i8xx_tco_get
 			printk (KERN_ERR PFX "failed to get TCOBASE address\n");
 			return 0;
 		}
-		/*
-		 * Check chipset's NO_REBOOT bit
-		 */
+
+		/* Check chipset's NO_REBOOT bit */
 		pci_read_config_byte (i8xx_tco_pci, 0xd4, &val1);
 		if (val1 & 0x02) {
 			val1 &= 0xfd;
@@ -435,6 +448,10 @@ static unsigned char __init i8xx_tco_get
 				return 0;	/* Cannot reset NO_REBOOT bit */
 			}
 		}
+		/* Disable reboots untill the watchdog starts */
+		val1 |= 0x02;
+		pci_write_config_byte (i8xx_tco_pci, 0xd4, val1);
+
 		/* Set the TCO_EN bit in SMI_EN register */
 		if (!request_region (SMI_EN + 1, 1, "i8xx TCO")) {
 			printk (KERN_ERR PFX "I/O address 0x%04x already in use\n",
@@ -510,17 +527,10 @@ out:
 
 static void __exit watchdog_cleanup (void)
 {
-	u8 val;
-
 	/* Stop the timer before we leave */
 	if (!nowayout)
 		tco_timer_stop ();
 
-	/* Set the NO_REBOOT bit to prevent later reboots, just for sure */
-	pci_read_config_byte (i8xx_tco_pci, 0xd4, &val);
-	val |= 0x02;
-	pci_write_config_byte (i8xx_tco_pci, 0xd4, val);
-
 	/* Deregister */
 	misc_deregister (&i8xx_tco_miscdev);
 	unregister_reboot_notifier(&i8xx_tco_notifier);
diff --git a/drivers/char/watchdog/ib700wdt.c b/drivers/char/watchdog/ib700wdt.c
--- a/drivers/char/watchdog/ib700wdt.c
+++ b/drivers/char/watchdog/ib700wdt.c
@@ -117,12 +117,7 @@ static int wd_times[] = {
 
 static int wd_margin = WD_TIMO;
 
-#ifdef CONFIG_WATCHDOG_NOWAYOUT
-static int nowayout = 1;
-#else
-static int nowayout = 0;
-#endif
-
+static int nowayout = WATCHDOG_NOWAYOUT;
 module_param(nowayout, int, 0);
 MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
 
diff --git a/drivers/char/watchdog/indydog.c b/drivers/char/watchdog/indydog.c
--- a/drivers/char/watchdog/indydog.c
+++ b/drivers/char/watchdog/indydog.c
@@ -29,14 +29,9 @@
 #define PFX "indydog: "
 static int indydog_alive;
 
-#ifdef CONFIG_WATCHDOG_NOWAYOUT
-static int nowayout = 1;
-#else
-static int nowayout = 0;
-#endif
-
 #define WATCHDOG_TIMEOUT 30		/* 30 sec default timeout */
 
+static int nowayout = WATCHDOG_NOWAYOUT;
 module_param(nowayout, int, 0);
 MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
 
diff --git a/drivers/char/watchdog/ixp2000_wdt.c b/drivers/char/watchdog/ixp2000_wdt.c
--- a/drivers/char/watchdog/ixp2000_wdt.c
+++ b/drivers/char/watchdog/ixp2000_wdt.c
@@ -30,11 +30,7 @@
 #include <asm/hardware.h>
 #include <asm/uaccess.h>
 
-#ifdef CONFIG_WATCHDOG_NOWAYOUT
-static int nowayout = 1;
-#else
-static int nowayout = 0;
-#endif
+static int nowayout = WATCHDOG_NOWAYOUT;
 static unsigned int heartbeat = 60;	/* (secs) Default is 1 minute */
 static unsigned long wdt_status;
 
@@ -162,7 +158,7 @@ ixp2000_wdt_release(struct inode *inode,
 	if (test_bit(WDT_OK_TO_CLOSE, &wdt_status)) {
 		wdt_disable();
 	} else {
-		printk(KERN_CRIT "WATCHDOG: Device closed unexpectdly - "
+		printk(KERN_CRIT "WATCHDOG: Device closed unexpectedly - "
 					"timer will not stop\n");
 	}
 
@@ -192,7 +188,12 @@ static struct miscdevice ixp2000_wdt_mis
 
 static int __init ixp2000_wdt_init(void)
 {
-	wdt_tick_rate = (*IXP2000_T1_CLD * HZ)/ 256;;
+	if ((*IXP2000_PRODUCT_ID & 0x001ffef0) == 0x00000000) {
+		printk(KERN_INFO "Unable to use IXP2000 watchdog due to IXP2800 erratum #25.\n");
+		return -EIO;
+	}
+
+	wdt_tick_rate = (*IXP2000_T1_CLD * HZ) / 256;
 
 	return misc_register(&ixp2000_wdt_miscdev);
 }
diff --git a/drivers/char/watchdog/ixp4xx_wdt.c b/drivers/char/watchdog/ixp4xx_wdt.c
--- a/drivers/char/watchdog/ixp4xx_wdt.c
+++ b/drivers/char/watchdog/ixp4xx_wdt.c
@@ -27,11 +27,7 @@
 #include <asm/hardware.h>
 #include <asm/uaccess.h>
 
-#ifdef CONFIG_WATCHDOG_NOWAYOUT
-static int nowayout = 1;
-#else
-static int nowayout = 0;
-#endif
+static int nowayout = WATCHDOG_NOWAYOUT;
 static int heartbeat = 60;	/* (secs) Default is 1 minute */
 static unsigned long wdt_status;
 static unsigned long boot_status;
@@ -156,7 +152,7 @@ ixp4xx_wdt_release(struct inode *inode, 
 	if (test_bit(WDT_OK_TO_CLOSE, &wdt_status)) {
 		wdt_disable();
 	} else {
-		printk(KERN_CRIT "WATCHDOG: Device closed unexpectdly - "
+		printk(KERN_CRIT "WATCHDOG: Device closed unexpectedly - "
 					"timer will not stop\n");
 	}
 
diff --git a/drivers/char/watchdog/machzwd.c b/drivers/char/watchdog/machzwd.c
--- a/drivers/char/watchdog/machzwd.c
+++ b/drivers/char/watchdog/machzwd.c
@@ -94,12 +94,7 @@ MODULE_DESCRIPTION("MachZ ZF-Logic Watch
 MODULE_LICENSE("GPL");
 MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
 
-#ifdef CONFIG_WATCHDOG_NOWAYOUT
-static int nowayout = 1;
-#else
-static int nowayout = 0;
-#endif
-
+static int nowayout = WATCHDOG_NOWAYOUT;
 module_param(nowayout, int, 0);
 MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
 
diff --git a/drivers/char/watchdog/mixcomwd.c b/drivers/char/watchdog/mixcomwd.c
--- a/drivers/char/watchdog/mixcomwd.c
+++ b/drivers/char/watchdog/mixcomwd.c
@@ -62,12 +62,7 @@ static int mixcomwd_timer_alive;
 static struct timer_list mixcomwd_timer = TIMER_INITIALIZER(NULL, 0, 0);
 static char expect_close;
 
-#ifdef CONFIG_WATCHDOG_NOWAYOUT
-static int nowayout = 1;
-#else
-static int nowayout = 0;
-#endif
-
+static int nowayout = WATCHDOG_NOWAYOUT;
 module_param(nowayout, int, 0);
 MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
 
diff --git a/drivers/char/watchdog/pcwd.c b/drivers/char/watchdog/pcwd.c
--- a/drivers/char/watchdog/pcwd.c
+++ b/drivers/char/watchdog/pcwd.c
@@ -146,12 +146,7 @@ static int heartbeat = WATCHDOG_HEARTBEA
 module_param(heartbeat, int, 0);
 MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (2<=heartbeat<=7200, default=" __MODULE_STRING(WATCHDOG_HEARTBEAT) ")");
 
-#ifdef CONFIG_WATCHDOG_NOWAYOUT
-static int nowayout = 1;
-#else
-static int nowayout = 0;
-#endif
-
+static int nowayout = WATCHDOG_NOWAYOUT;
 module_param(nowayout, int, 0);
 MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
 
@@ -344,7 +339,7 @@ static int pcwd_get_status(int *status)
 			*status |= WDIOF_OVERHEAT;
 			if (temp_panic) {
 				printk (KERN_INFO PFX "Temperature overheat trip!\n");
-				machine_power_off();
+				kernel_power_off();
 			}
 		}
 	} else {
@@ -355,7 +350,7 @@ static int pcwd_get_status(int *status)
 			*status |= WDIOF_OVERHEAT;
 			if (temp_panic) {
 				printk (KERN_INFO PFX "Temperature overheat trip!\n");
-				machine_power_off();
+				kernel_power_off();
 			}
 		}
 	}
diff --git a/drivers/char/watchdog/pcwd_pci.c b/drivers/char/watchdog/pcwd_pci.c
--- a/drivers/char/watchdog/pcwd_pci.c
+++ b/drivers/char/watchdog/pcwd_pci.c
@@ -103,12 +103,7 @@ static int heartbeat = WATCHDOG_HEARTBEA
 module_param(heartbeat, int, 0);
 MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (0<heartbeat<65536, default=" __MODULE_STRING(WATCHDOG_HEARTBEAT) ")");
 
-#ifdef CONFIG_WATCHDOG_NOWAYOUT
-static int nowayout = 1;
-#else
-static int nowayout = 0;
-#endif
-
+static int nowayout = WATCHDOG_NOWAYOUT;
 module_param(nowayout, int, 0);
 MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
 
diff --git a/drivers/char/watchdog/pcwd_usb.c b/drivers/char/watchdog/pcwd_usb.c
--- a/drivers/char/watchdog/pcwd_usb.c
+++ b/drivers/char/watchdog/pcwd_usb.c
@@ -79,12 +79,7 @@ static int heartbeat = WATCHDOG_HEARTBEA
 module_param(heartbeat, int, 0);
 MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (0<heartbeat<65536, default=" __MODULE_STRING(WATCHDOG_HEARTBEAT) ")");
 
-#ifdef CONFIG_WATCHDOG_NOWAYOUT
-static int nowayout = 1;
-#else
-static int nowayout = 0;
-#endif
-
+static int nowayout = WATCHDOG_NOWAYOUT;
 module_param(nowayout, int, 0);
 MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
 
diff --git a/drivers/char/watchdog/s3c2410_wdt.c b/drivers/char/watchdog/s3c2410_wdt.c
--- a/drivers/char/watchdog/s3c2410_wdt.c
+++ b/drivers/char/watchdog/s3c2410_wdt.c
@@ -62,12 +62,7 @@
 #define CONFIG_S3C2410_WATCHDOG_ATBOOT		(0)
 #define CONFIG_S3C2410_WATCHDOG_DEFAULT_TIME	(15)
 
-#ifdef CONFIG_WATCHDOG_NOWAYOUT
-static int nowayout = 1;
-#else
-static int nowayout = 0;
-#endif
-
+static int nowayout = WATCHDOG_NOWAYOUT;
 static int tmr_margin	= CONFIG_S3C2410_WATCHDOG_DEFAULT_TIME;
 static int tmr_atboot	= CONFIG_S3C2410_WATCHDOG_ATBOOT;
 static int soft_noboot	= 0;
diff --git a/drivers/char/watchdog/sa1100_wdt.c b/drivers/char/watchdog/sa1100_wdt.c
--- a/drivers/char/watchdog/sa1100_wdt.c
+++ b/drivers/char/watchdog/sa1100_wdt.c
@@ -36,17 +36,10 @@
 #include <asm/uaccess.h>
 
 #define OSCR_FREQ		CLOCK_TICK_RATE
-#define SA1100_CLOSE_MAGIC	(0x5afc4453)
 
 static unsigned long sa1100wdt_users;
-static int expect_close;
 static int pre_margin;
 static int boot_status;
-#ifdef CONFIG_WATCHDOG_NOWAYOUT
-static int nowayout = 1;
-#else
-static int nowayout = 0;
-#endif
 
 /*
  *	Allow only one person to hold it open
@@ -66,55 +59,33 @@ static int sa1100dog_open(struct inode *
 }
 
 /*
- *	Shut off the timer.
- * 	Lock it in if it's a module and we defined ...NOWAYOUT
- *	Oddly, the watchdog can only be enabled, but we can turn off
- *	the interrupt, which appears to prevent the watchdog timing out.
+ * The watchdog cannot be disabled.
+ *
+ * Previous comments suggested that turning off the interrupt by
+ * clearing OIER[E3] would prevent the watchdog timing out but this
+ * does not appear to be true (at least on the PXA255).
  */
 static int sa1100dog_release(struct inode *inode, struct file *file)
 {
-	OSMR3 = OSCR + pre_margin;
-
-	if (expect_close == SA1100_CLOSE_MAGIC) {
-		OIER &= ~OIER_E3;
-	} else {
-		printk(KERN_CRIT "WATCHDOG: WDT device closed unexpectedly.  WDT will not stop!\n");
-	}
+	printk(KERN_CRIT "WATCHDOG: Device closed - timer will not stop\n");
 
 	clear_bit(1, &sa1100wdt_users);
-	expect_close = 0;
 
 	return 0;
 }
 
 static ssize_t sa1100dog_write(struct file *file, const char *data, size_t len, loff_t *ppos)
 {
-	if (len) {
-		if (!nowayout) {
-			size_t i;
-
-			expect_close = 0;
-
-			for (i = 0; i != len; i++) {
-				char c;
-
-				if (get_user(c, data + i))
-					return -EFAULT;
-				if (c == 'V')
-					expect_close = SA1100_CLOSE_MAGIC;
-			}
-		}
+	if (len)
 		/* Refresh OSMR3 timer. */
 		OSMR3 = OSCR + pre_margin;
-	}
 
 	return len;
 }
 
 static struct watchdog_info ident = {
-	.options	= WDIOF_CARDRESET | WDIOF_MAGICCLOSE |
-			  WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
-	.identity	= "SA1100 Watchdog",
+	.options	= WDIOF_CARDRESET | WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
+	.identity	= "SA1100/PXA255 Watchdog",
 };
 
 static int sa1100dog_ioctl(struct inode *inode, struct file *file,
@@ -176,7 +147,7 @@ static struct file_operations sa1100dog_
 static struct miscdevice sa1100dog_miscdev =
 {
 	.minor		= WATCHDOG_MINOR,
-	.name		= "SA1100/PXA2xx watchdog",
+	.name		= "watchdog",
 	.fops		= &sa1100dog_fops,
 };
 
@@ -198,7 +169,6 @@ static int __init sa1100dog_init(void)
 	if (ret == 0)
 		printk("SA1100/PXA2xx Watchdog Timer: timer margin %d sec\n",
 		       margin);
-
 	return ret;
 }
 
@@ -216,8 +186,5 @@ MODULE_DESCRIPTION("SA1100/PXA2xx Watchd
 module_param(margin, int, 0);
 MODULE_PARM_DESC(margin, "Watchdog margin in seconds (default 60s)");
 
-module_param(nowayout, int, 0);
-MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started");
-
 MODULE_LICENSE("GPL");
 MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
diff --git a/drivers/char/watchdog/sbc60xxwdt.c b/drivers/char/watchdog/sbc60xxwdt.c
--- a/drivers/char/watchdog/sbc60xxwdt.c
+++ b/drivers/char/watchdog/sbc60xxwdt.c
@@ -98,12 +98,7 @@ static int timeout = WATCHDOG_TIMEOUT;	/
 module_param(timeout, int, 0);
 MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (1<=timeout<=3600, default=" __MODULE_STRING(WATCHDOG_TIMEOUT) ")");
 
-#ifdef CONFIG_WATCHDOG_NOWAYOUT
-static int nowayout = 1;
-#else
-static int nowayout = 0;
-#endif
-
+static int nowayout = WATCHDOG_NOWAYOUT;
 module_param(nowayout, int, 0);
 MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
 
diff --git a/drivers/char/watchdog/sc1200wdt.c b/drivers/char/watchdog/sc1200wdt.c
--- a/drivers/char/watchdog/sc1200wdt.c
+++ b/drivers/char/watchdog/sc1200wdt.c
@@ -91,12 +91,7 @@ MODULE_PARM_DESC(io, "io port");
 module_param(timeout, int, 0);
 MODULE_PARM_DESC(timeout, "range is 0-255 minutes, default is 1");
 
-#ifdef CONFIG_WATCHDOG_NOWAYOUT
-static int nowayout = 1;
-#else
-static int nowayout = 0;
-#endif
-
+static int nowayout = WATCHDOG_NOWAYOUT;
 module_param(nowayout, int, 0);
 MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
 
diff --git a/drivers/char/watchdog/sc520_wdt.c b/drivers/char/watchdog/sc520_wdt.c
--- a/drivers/char/watchdog/sc520_wdt.c
+++ b/drivers/char/watchdog/sc520_wdt.c
@@ -94,12 +94,7 @@ static int timeout = WATCHDOG_TIMEOUT;	/
 module_param(timeout, int, 0);
 MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (1<=timeout<=3600, default=" __MODULE_STRING(WATCHDOG_TIMEOUT) ")");
 
-#ifdef CONFIG_WATCHDOG_NOWAYOUT
-static int nowayout = 1;
-#else
-static int nowayout = 0;
-#endif
-
+static int nowayout = WATCHDOG_NOWAYOUT;
 module_param(nowayout, int, 0);
 MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
 
diff --git a/drivers/char/watchdog/scx200_wdt.c b/drivers/char/watchdog/scx200_wdt.c
--- a/drivers/char/watchdog/scx200_wdt.c
+++ b/drivers/char/watchdog/scx200_wdt.c
@@ -39,15 +39,11 @@ MODULE_DESCRIPTION("NatSemi SCx200 Watch
 MODULE_LICENSE("GPL");
 MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
 
-#ifndef CONFIG_WATCHDOG_NOWAYOUT
-#define CONFIG_WATCHDOG_NOWAYOUT 0
-#endif
-
 static int margin = 60;		/* in seconds */
 module_param(margin, int, 0);
 MODULE_PARM_DESC(margin, "Watchdog margin in seconds");
 
-static int nowayout = CONFIG_WATCHDOG_NOWAYOUT;
+static int nowayout = WATCHDOG_NOWAYOUT;
 module_param(nowayout, int, 0);
 MODULE_PARM_DESC(nowayout, "Disable watchdog shutdown on close");
 
diff --git a/drivers/char/watchdog/shwdt.c b/drivers/char/watchdog/shwdt.c
--- a/drivers/char/watchdog/shwdt.c
+++ b/drivers/char/watchdog/shwdt.c
@@ -75,11 +75,7 @@ static unsigned long next_heartbeat;
 #define WATCHDOG_HEARTBEAT 30			/* 30 sec default heartbeat */
 static int heartbeat = WATCHDOG_HEARTBEAT;	/* in seconds */
 
-#ifdef CONFIG_WATCHDOG_NOWAYOUT
-static int nowayout = 1;
-#else
-static int nowayout = 0;
-#endif
+static int nowayout = WATCHDOG_NOWAYOUT;
 
 /**
  * 	sh_wdt_start - Start the Watchdog
diff --git a/drivers/char/watchdog/softdog.c b/drivers/char/watchdog/softdog.c
--- a/drivers/char/watchdog/softdog.c
+++ b/drivers/char/watchdog/softdog.c
@@ -56,12 +56,7 @@ static int soft_margin = TIMER_MARGIN;	/
 module_param(soft_margin, int, 0);
 MODULE_PARM_DESC(soft_margin, "Watchdog soft_margin in seconds. (0<soft_margin<65536, default=" __MODULE_STRING(TIMER_MARGIN) ")");
 
-#ifdef CONFIG_WATCHDOG_NOWAYOUT
-static int nowayout = 1;
-#else
-static int nowayout = 0;
-#endif
-
+static int nowayout = WATCHDOG_NOWAYOUT;
 module_param(nowayout, int, 0);
 MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
 
@@ -97,7 +92,7 @@ static void watchdog_fire(unsigned long 
 	else
 	{
 		printk(KERN_CRIT PFX "Initiating system reboot.\n");
-		machine_restart(NULL);
+		emergency_restart();
 		printk(KERN_CRIT PFX "Reboot didn't ?????\n");
 	}
 }
diff --git a/drivers/char/watchdog/w83627hf_wdt.c b/drivers/char/watchdog/w83627hf_wdt.c
--- a/drivers/char/watchdog/w83627hf_wdt.c
+++ b/drivers/char/watchdog/w83627hf_wdt.c
@@ -54,12 +54,7 @@ static int timeout = WATCHDOG_TIMEOUT;	/
 module_param(timeout, int, 0);
 MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. 1<= timeout <=63, default=" __MODULE_STRING(WATCHDOG_TIMEOUT) ".");
 
-#ifdef CONFIG_WATCHDOG_NOWAYOUT
-static int nowayout = 1;
-#else
-static int nowayout = 0;
-#endif
-
+static int nowayout = WATCHDOG_NOWAYOUT;
 module_param(nowayout, int, 0);
 MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
 
diff --git a/drivers/char/watchdog/w83877f_wdt.c b/drivers/char/watchdog/w83877f_wdt.c
--- a/drivers/char/watchdog/w83877f_wdt.c
+++ b/drivers/char/watchdog/w83877f_wdt.c
@@ -85,12 +85,7 @@ module_param(timeout, int, 0);
 MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (1<=timeout<=3600, default=" __MODULE_STRING(WATCHDOG_TIMEOUT) ")");
 
 
-#ifdef CONFIG_WATCHDOG_NOWAYOUT
-static int nowayout = 1;
-#else
-static int nowayout = 0;
-#endif
-
+static int nowayout = WATCHDOG_NOWAYOUT;
 module_param(nowayout, int, 0);
 MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
 
diff --git a/drivers/char/watchdog/wafer5823wdt.c b/drivers/char/watchdog/wafer5823wdt.c
--- a/drivers/char/watchdog/wafer5823wdt.c
+++ b/drivers/char/watchdog/wafer5823wdt.c
@@ -63,12 +63,7 @@ static int timeout = WD_TIMO;  /* in sec
 module_param(timeout, int, 0);
 MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. 1<= timeout <=255, default=" __MODULE_STRING(WD_TIMO) ".");
 
-#ifdef CONFIG_WATCHDOG_NOWAYOUT
-static int nowayout = 1;
-#else
-static int nowayout = 0;
-#endif
-
+static int nowayout = WATCHDOG_NOWAYOUT;
 module_param(nowayout, int, 0);
 MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
 
diff --git a/drivers/char/watchdog/wdrtas.c b/drivers/char/watchdog/wdrtas.c
new file mode 100644
--- /dev/null
+++ b/drivers/char/watchdog/wdrtas.c
@@ -0,0 +1,696 @@
+/*
+ * FIXME: add wdrtas_get_status and wdrtas_get_boot_status as soon as
+ * RTAS calls are available
+ */
+
+/*
+ * RTAS watchdog driver
+ *
+ * (C) Copyright IBM Corp. 2005
+ * device driver to exploit watchdog RTAS functions
+ *
+ * Authors : Utz Bacher <utz.bacher@de.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, 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 <linux/config.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/miscdevice.h>
+#include <linux/module.h>
+#include <linux/notifier.h>
+#include <linux/reboot.h>
+#include <linux/types.h>
+#include <linux/watchdog.h>
+
+#include <asm/rtas.h>
+#include <asm/uaccess.h>
+
+#define WDRTAS_MAGIC_CHAR		42
+#define WDRTAS_SUPPORTED_MASK		(WDIOF_SETTIMEOUT | \
+					 WDIOF_MAGICCLOSE)
+
+MODULE_AUTHOR("Utz Bacher <utz.bacher@de.ibm.com>");
+MODULE_DESCRIPTION("RTAS watchdog driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
+MODULE_ALIAS_MISCDEV(TEMP_MINOR);
+
+#ifdef CONFIG_WATCHDOG_NOWAYOUT
+static int wdrtas_nowayout = 1;
+#else
+static int wdrtas_nowayout = 0;
+#endif
+
+static atomic_t wdrtas_miscdev_open = ATOMIC_INIT(0);
+static char wdrtas_expect_close = 0;
+
+static int wdrtas_interval;
+
+#define WDRTAS_THERMAL_SENSOR		3
+static int wdrtas_token_get_sensor_state;
+#define WDRTAS_SURVEILLANCE_IND		9000
+static int wdrtas_token_set_indicator;
+#define WDRTAS_SP_SPI			28
+static int wdrtas_token_get_sp;
+static int wdrtas_token_event_scan;
+
+#define WDRTAS_DEFAULT_INTERVAL		300
+
+#define WDRTAS_LOGBUFFER_LEN		128
+static char wdrtas_logbuffer[WDRTAS_LOGBUFFER_LEN];
+
+
+/*** watchdog access functions */
+
+/**
+ * wdrtas_set_interval - sets the watchdog interval
+ * @interval: new interval
+ *
+ * returns 0 on success, <0 on failures
+ *
+ * wdrtas_set_interval sets the watchdog keepalive interval by calling the
+ * RTAS function set-indicator (surveillance). The unit of interval is
+ * seconds.
+ */
+static int
+wdrtas_set_interval(int interval)
+{
+	long result;
+	static int print_msg = 10;
+
+	/* rtas uses minutes */
+	interval = (interval + 59) / 60;
+
+	result = rtas_call(wdrtas_token_set_indicator, 3, 1, NULL,
+			   WDRTAS_SURVEILLANCE_IND, 0, interval);
+	if ( (result < 0) && (print_msg) ) {
+		printk(KERN_ERR "wdrtas: setting the watchdog to %i "
+		       "timeout failed: %li\n", interval, result);
+		print_msg--;
+	}
+
+	return result;
+}
+
+/**
+ * wdrtas_get_interval - returns the current watchdog interval
+ * @fallback_value: value (in seconds) to use, if the RTAS call fails
+ *
+ * returns the interval
+ *
+ * wdrtas_get_interval returns the current watchdog keepalive interval
+ * as reported by the RTAS function ibm,get-system-parameter. The unit
+ * of the return value is seconds.
+ */
+static int
+wdrtas_get_interval(int fallback_value)
+{
+	long result;
+	char value[4];
+
+	result = rtas_call(wdrtas_token_get_sp, 3, 1, NULL,
+			   WDRTAS_SP_SPI, (void *)__pa(&value), 4);
+	if ( (value[0] != 0) || (value[1] != 2) || (value[3] != 0) ||
+	     (result < 0) ) {
+		printk(KERN_WARNING "wdrtas: could not get sp_spi watchdog "
+		       "timeout (%li). Continuing\n", result);
+		return fallback_value;
+	}
+
+	/* rtas uses minutes */
+	return ((int)value[2]) * 60;
+}
+
+/**
+ * wdrtas_timer_start - starts watchdog
+ *
+ * wdrtas_timer_start starts the watchdog by calling the RTAS function
+ * set-interval (surveillance)
+ */
+static void
+wdrtas_timer_start(void)
+{
+	wdrtas_set_interval(wdrtas_interval);
+}
+
+/**
+ * wdrtas_timer_stop - stops watchdog
+ *
+ * wdrtas_timer_stop stops the watchdog timer by calling the RTAS function
+ * set-interval (surveillance)
+ */
+static void
+wdrtas_timer_stop(void)
+{
+	wdrtas_set_interval(0);
+}
+
+/**
+ * wdrtas_log_scanned_event - logs an event we received during keepalive
+ *
+ * wdrtas_log_scanned_event prints a message to the log buffer dumping
+ * the results of the last event-scan call
+ */
+static void
+wdrtas_log_scanned_event(void)
+{
+	int i;
+
+	for (i = 0; i < WDRTAS_LOGBUFFER_LEN; i += 16)
+		printk(KERN_INFO "wdrtas: dumping event (line %i/%i), data = "
+		       "%02x %02x %02x %02x  %02x %02x %02x %02x   "
+		       "%02x %02x %02x %02x  %02x %02x %02x %02x\n",
+		       (i / 16) + 1, (WDRTAS_LOGBUFFER_LEN / 16),
+		       wdrtas_logbuffer[i + 0], wdrtas_logbuffer[i + 1], 
+		       wdrtas_logbuffer[i + 2], wdrtas_logbuffer[i + 3], 
+		       wdrtas_logbuffer[i + 4], wdrtas_logbuffer[i + 5], 
+		       wdrtas_logbuffer[i + 6], wdrtas_logbuffer[i + 7], 
+		       wdrtas_logbuffer[i + 8], wdrtas_logbuffer[i + 9], 
+		       wdrtas_logbuffer[i + 10], wdrtas_logbuffer[i + 11], 
+		       wdrtas_logbuffer[i + 12], wdrtas_logbuffer[i + 13], 
+		       wdrtas_logbuffer[i + 14], wdrtas_logbuffer[i + 15]);
+}
+
+/**
+ * wdrtas_timer_keepalive - resets watchdog timer to keep system alive
+ *
+ * wdrtas_timer_keepalive restarts the watchdog timer by calling the
+ * RTAS function event-scan and repeats these calls as long as there are
+ * events available. All events will be dumped.
+ */
+static void
+wdrtas_timer_keepalive(void)
+{
+	long result;
+
+	do {
+		result = rtas_call(wdrtas_token_event_scan, 4, 1, NULL,
+				   RTAS_EVENT_SCAN_ALL_EVENTS, 0,
+				   (void *)__pa(wdrtas_logbuffer),
+				   WDRTAS_LOGBUFFER_LEN);
+		if (result < 0)
+			printk(KERN_ERR "wdrtas: event-scan failed: %li\n",
+			       result);
+		if (result == 0)
+			wdrtas_log_scanned_event();
+	} while (result == 0);
+}
+
+/**
+ * wdrtas_get_temperature - returns current temperature
+ *
+ * returns temperature or <0 on failures
+ *
+ * wdrtas_get_temperature returns the current temperature in Fahrenheit. It
+ * uses the RTAS call get-sensor-state, token 3 to do so
+ */
+static int
+wdrtas_get_temperature(void)
+{
+	long result;
+	int temperature = 0;
+
+	result = rtas_call(wdrtas_token_get_sensor_state, 2, 2,
+			   (void *)__pa(&temperature),
+			   WDRTAS_THERMAL_SENSOR, 0);
+
+	if (result < 0)
+		printk(KERN_WARNING "wdrtas: reading the thermal sensor "
+		       "faild: %li\n", result);
+	else
+		temperature = ((temperature * 9) / 5) + 32; /* fahrenheit */
+
+	return temperature;
+}
+
+/**
+ * wdrtas_get_status - returns the status of the watchdog
+ *
+ * returns a bitmask of defines WDIOF_... as defined in
+ * include/linux/watchdog.h
+ */
+static int
+wdrtas_get_status(void)
+{
+	return 0; /* TODO */
+}
+
+/**
+ * wdrtas_get_boot_status - returns the reason for the last boot
+ *
+ * returns a bitmask of defines WDIOF_... as defined in
+ * include/linux/watchdog.h, indicating why the watchdog rebooted the system
+ */
+static int
+wdrtas_get_boot_status(void)
+{
+	return 0; /* TODO */
+}
+
+/*** watchdog API and operations stuff */
+
+/* wdrtas_write - called when watchdog device is written to
+ * @file: file structure
+ * @buf: user buffer with data
+ * @len: amount to data written
+ * @ppos: position in file
+ *
+ * returns the number of successfully processed characters, which is always
+ * the number of bytes passed to this function
+ *
+ * wdrtas_write processes all the data given to it and looks for the magic
+ * character 'V'. This character allows the watchdog device to be closed
+ * properly.
+ */
+static ssize_t
+wdrtas_write(struct file *file, const char __user *buf,
+	     size_t len, loff_t *ppos)
+{
+	int i;
+	char c;
+
+	if (!len)
+		goto out;
+
+	if (!wdrtas_nowayout) {
+		wdrtas_expect_close = 0;
+		/* look for 'V' */
+		for (i = 0; i < len; i++) {
+			if (get_user(c, buf + i))
+				return -EFAULT;
+			/* allow to close device */
+			if (c == 'V')
+				wdrtas_expect_close = WDRTAS_MAGIC_CHAR;
+		}
+	}
+
+	wdrtas_timer_keepalive();
+
+out:
+	return len;
+}
+
+/**
+ * wdrtas_ioctl - ioctl function for the watchdog device
+ * @inode: inode structure
+ * @file: file structure
+ * @cmd: command for ioctl
+ * @arg: argument pointer
+ *
+ * returns 0 on success, <0 on failure
+ *
+ * wdrtas_ioctl implements the watchdog API ioctls
+ */
+static int
+wdrtas_ioctl(struct inode *inode, struct file *file,
+	     unsigned int cmd, unsigned long arg)
+{
+	int __user *argp = (void *)arg;
+	int i;
+	static struct watchdog_info wdinfo = {
+		.options = WDRTAS_SUPPORTED_MASK,
+		.firmware_version = 0,
+		.identity = "wdrtas"
+	};
+
+	switch (cmd) {
+	case WDIOC_GETSUPPORT:
+		if (copy_to_user(argp, &wdinfo, sizeof(wdinfo)))
+			return -EFAULT;
+		return 0;
+
+	case WDIOC_GETSTATUS:
+		i = wdrtas_get_status();
+		return put_user(i, argp);
+
+	case WDIOC_GETBOOTSTATUS:
+		i = wdrtas_get_boot_status();
+		return put_user(i, argp);
+
+	case WDIOC_GETTEMP:
+		if (wdrtas_token_get_sensor_state == RTAS_UNKNOWN_SERVICE)
+			return -EOPNOTSUPP;
+
+		i = wdrtas_get_temperature();
+		return put_user(i, argp);
+
+	case WDIOC_SETOPTIONS:
+		if (get_user(i, argp))
+			return -EFAULT;
+		if (i & WDIOS_DISABLECARD)
+			wdrtas_timer_stop();
+		if (i & WDIOS_ENABLECARD) {
+			wdrtas_timer_keepalive();
+			wdrtas_timer_start();
+		}
+		if (i & WDIOS_TEMPPANIC) {
+			/* not implemented. Done by H8 */
+		}
+		return 0;
+
+	case WDIOC_KEEPALIVE:
+		wdrtas_timer_keepalive();
+		return 0;
+
+	case WDIOC_SETTIMEOUT:
+		if (get_user(i, argp))
+			return -EFAULT;
+
+		if (wdrtas_set_interval(i))
+			return -EINVAL;
+
+		wdrtas_timer_keepalive();
+
+		if (wdrtas_token_get_sp == RTAS_UNKNOWN_SERVICE)
+			wdrtas_interval = i;
+		else
+			wdrtas_interval = wdrtas_get_interval(i);
+		/* fallthrough */
+
+	case WDIOC_GETTIMEOUT:
+		return put_user(wdrtas_interval, argp);
+
+	default:
+		return -ENOIOCTLCMD;
+	}
+}
+
+/**
+ * wdrtas_open - open function of watchdog device
+ * @inode: inode structure
+ * @file: file structure
+ *
+ * returns 0 on success, -EBUSY if the file has been opened already, <0 on
+ * other failures
+ *
+ * function called when watchdog device is opened
+ */
+static int
+wdrtas_open(struct inode *inode, struct file *file)
+{
+	/* only open once */
+	if (atomic_inc_return(&wdrtas_miscdev_open) > 1) {
+		atomic_dec(&wdrtas_miscdev_open);
+		return -EBUSY;
+	}
+
+	wdrtas_timer_start();
+	wdrtas_timer_keepalive();
+
+	return nonseekable_open(inode, file);
+}
+
+/**
+ * wdrtas_close - close function of watchdog device
+ * @inode: inode structure
+ * @file: file structure
+ *
+ * returns 0 on success
+ *
+ * close function. Always succeeds
+ */
+static int
+wdrtas_close(struct inode *inode, struct file *file)
+{
+	/* only stop watchdog, if this was announced using 'V' before */
+	if (wdrtas_expect_close == WDRTAS_MAGIC_CHAR)
+		wdrtas_timer_stop();
+	else {
+		printk(KERN_WARNING "wdrtas: got unexpected close. Watchdog "
+		       "not stopped.\n");
+		wdrtas_timer_keepalive();
+	}
+
+	wdrtas_expect_close = 0;
+	atomic_dec(&wdrtas_miscdev_open);
+	return 0;
+}
+
+/**
+ * wdrtas_temp_read - gives back the temperature in fahrenheit
+ * @file: file structure
+ * @buf: user buffer
+ * @count: number of bytes to be read
+ * @ppos: position in file
+ *
+ * returns always 1 or -EFAULT in case of user space copy failures, <0 on
+ * other failures
+ *
+ * wdrtas_temp_read gives the temperature to the users by copying this
+ * value as one byte into the user space buffer. The unit is Fahrenheit...
+ */
+static ssize_t
+wdrtas_temp_read(struct file *file, char __user *buf,
+		 size_t count, loff_t *ppos)
+{
+	int temperature = 0;
+
+	temperature = wdrtas_get_temperature();
+	if (temperature < 0)
+		return temperature;
+
+	if (copy_to_user(buf, &temperature, 1))
+		return -EFAULT;
+
+	return 1;
+}
+
+/**
+ * wdrtas_temp_open - open function of temperature device
+ * @inode: inode structure
+ * @file: file structure
+ *
+ * returns 0 on success, <0 on failure
+ *
+ * function called when temperature device is opened
+ */
+static int
+wdrtas_temp_open(struct inode *inode, struct file *file)
+{
+	return nonseekable_open(inode, file);
+}
+
+/**
+ * wdrtas_temp_close - close function of temperature device
+ * @inode: inode structure
+ * @file: file structure
+ *
+ * returns 0 on success
+ *
+ * close function. Always succeeds
+ */
+static int
+wdrtas_temp_close(struct inode *inode, struct file *file)
+{
+	return 0;
+}
+
+/**
+ * wdrtas_reboot - reboot notifier function
+ * @nb: notifier block structure
+ * @code: reboot code
+ * @ptr: unused
+ *
+ * returns NOTIFY_DONE
+ *
+ * wdrtas_reboot stops the watchdog in case of a reboot
+ */
+static int
+wdrtas_reboot(struct notifier_block *this, unsigned long code, void *ptr)
+{
+	if ( (code==SYS_DOWN) || (code==SYS_HALT) )
+		wdrtas_timer_stop();
+
+	return NOTIFY_DONE;
+}
+
+/*** initialization stuff */
+
+static struct file_operations wdrtas_fops = {
+	.owner		= THIS_MODULE,
+	.llseek		= no_llseek,
+	.write		= wdrtas_write,
+	.ioctl		= wdrtas_ioctl,
+	.open		= wdrtas_open,
+	.release	= wdrtas_close,
+};
+
+static struct miscdevice wdrtas_miscdev = {
+	.minor =	WATCHDOG_MINOR,
+	.name =		"watchdog",
+	.fops =		&wdrtas_fops,
+};
+
+static struct file_operations wdrtas_temp_fops = {
+	.owner		= THIS_MODULE,
+	.llseek		= no_llseek,
+	.read		= wdrtas_temp_read,
+	.open		= wdrtas_temp_open,
+	.release	= wdrtas_temp_close,
+};
+
+static struct miscdevice wdrtas_tempdev = {
+	.minor =	TEMP_MINOR,
+	.name =		"temperature",
+	.fops =		&wdrtas_temp_fops,
+};
+
+static struct notifier_block wdrtas_notifier = {
+	.notifier_call =	wdrtas_reboot,
+};
+
+/**
+ * wdrtas_get_tokens - reads in RTAS tokens
+ *
+ * returns 0 on succes, <0 on failure
+ *
+ * wdrtas_get_tokens reads in the tokens for the RTAS calls used in
+ * this watchdog driver. It tolerates, if "get-sensor-state" and
+ * "ibm,get-system-parameter" are not available.
+ */
+static int
+wdrtas_get_tokens(void)
+{
+	wdrtas_token_get_sensor_state = rtas_token("get-sensor-state");
+	if (wdrtas_token_get_sensor_state == RTAS_UNKNOWN_SERVICE) {
+		printk(KERN_WARNING "wdrtas: couldn't get token for "
+		       "get-sensor-state. Trying to continue without "
+		       "temperature support.\n");
+	}
+
+	wdrtas_token_get_sp = rtas_token("ibm,get-system-parameter");
+	if (wdrtas_token_get_sp == RTAS_UNKNOWN_SERVICE) {
+		printk(KERN_WARNING "wdrtas: couldn't get token for "
+		       "ibm,get-system-parameter. Trying to continue with "
+		       "a default timeout value of %i seconds.\n",
+		       WDRTAS_DEFAULT_INTERVAL);
+	}
+
+	wdrtas_token_set_indicator = rtas_token("set-indicator");
+	if (wdrtas_token_set_indicator == RTAS_UNKNOWN_SERVICE) {
+		printk(KERN_ERR "wdrtas: couldn't get token for "
+		       "set-indicator. Terminating watchdog code.\n");
+		return -EIO;
+	}
+
+	wdrtas_token_event_scan = rtas_token("event-scan");
+	if (wdrtas_token_event_scan == RTAS_UNKNOWN_SERVICE) {
+		printk(KERN_ERR "wdrtas: couldn't get token for event-scan. "
+		       "Terminating watchdog code.\n");
+		return -EIO;
+	}
+
+	return 0;
+}
+
+/**
+ * wdrtas_unregister_devs - unregisters the misc dev handlers
+ *
+ * wdrtas_register_devs unregisters the watchdog and temperature watchdog
+ * misc devs
+ */
+static void
+wdrtas_unregister_devs(void)
+{
+	misc_deregister(&wdrtas_miscdev);
+	if (wdrtas_token_get_sensor_state != RTAS_UNKNOWN_SERVICE)
+		misc_deregister(&wdrtas_tempdev);
+}
+
+/**
+ * wdrtas_register_devs - registers the misc dev handlers
+ *
+ * returns 0 on succes, <0 on failure
+ *
+ * wdrtas_register_devs registers the watchdog and temperature watchdog
+ * misc devs
+ */
+static int
+wdrtas_register_devs(void)
+{
+	int result;
+
+	result = misc_register(&wdrtas_miscdev);
+	if (result) {
+		printk(KERN_ERR "wdrtas: couldn't register watchdog misc "
+		       "device. Terminating watchdog code.\n");
+		return result;
+	}
+
+	if (wdrtas_token_get_sensor_state != RTAS_UNKNOWN_SERVICE) {
+		result = misc_register(&wdrtas_tempdev);
+		if (result) {
+			printk(KERN_WARNING "wdrtas: couldn't register "
+			       "watchdog temperature misc device. Continuing "
+			       "without temperature support.\n");
+			wdrtas_token_get_sensor_state = RTAS_UNKNOWN_SERVICE;
+		}
+	}
+
+	return 0;
+}
+
+/**
+ * wdrtas_init - init function of the watchdog driver
+ *
+ * returns 0 on succes, <0 on failure
+ *
+ * registers the file handlers and the reboot notifier
+ */
+static int __init
+wdrtas_init(void)
+{
+	if (wdrtas_get_tokens())
+		return -ENODEV;
+
+	if (wdrtas_register_devs())
+		return -ENODEV;
+
+	if (register_reboot_notifier(&wdrtas_notifier)) {
+		printk(KERN_ERR "wdrtas: could not register reboot notifier. "
+		       "Terminating watchdog code.\n");
+		wdrtas_unregister_devs();
+		return -ENODEV;
+	}
+
+	if (wdrtas_token_get_sp == RTAS_UNKNOWN_SERVICE)
+		wdrtas_interval = WDRTAS_DEFAULT_INTERVAL;
+	else
+		wdrtas_interval = wdrtas_get_interval(WDRTAS_DEFAULT_INTERVAL);
+
+	return 0;
+}
+
+/**
+ * wdrtas_exit - exit function of the watchdog driver
+ *
+ * unregisters the file handlers and the reboot notifier
+ */
+static void __exit
+wdrtas_exit(void)
+{
+	if (!wdrtas_nowayout)
+		wdrtas_timer_stop();
+
+	wdrtas_unregister_devs();
+
+	unregister_reboot_notifier(&wdrtas_notifier);
+}
+
+module_init(wdrtas_init);
+module_exit(wdrtas_exit);
diff --git a/drivers/char/watchdog/wdt.c b/drivers/char/watchdog/wdt.c
--- a/drivers/char/watchdog/wdt.c
+++ b/drivers/char/watchdog/wdt.c
@@ -63,12 +63,7 @@ static int wd_heartbeat;
 module_param(heartbeat, int, 0);
 MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (0<heartbeat<65536, default=" __MODULE_STRING(WD_TIMO) ")");
 
-#ifdef CONFIG_WATCHDOG_NOWAYOUT
-static int nowayout = 1;
-#else
-static int nowayout = 0;
-#endif
-
+static int nowayout = WATCHDOG_NOWAYOUT;
 module_param(nowayout, int, 0);
 MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
 
@@ -266,7 +261,7 @@ static irqreturn_t wdt_interrupt(int irq
 		printk(KERN_CRIT "Would Reboot.\n");
 #else
 		printk(KERN_CRIT "Initiating system reboot.\n");
-		machine_restart(NULL);
+		emergency_restart();
 #endif
 #else
 		printk(KERN_CRIT "Reset in 5ms.\n");
diff --git a/drivers/char/watchdog/wdt977.c b/drivers/char/watchdog/wdt977.c
--- a/drivers/char/watchdog/wdt977.c
+++ b/drivers/char/watchdog/wdt977.c
@@ -53,12 +53,7 @@ MODULE_PARM_DESC(timeout,"Watchdog timeo
 module_param(testmode, int, 0);
 MODULE_PARM_DESC(testmode,"Watchdog testmode (1 = no reboot), default=0");
 
-#ifdef CONFIG_WATCHDOG_NOWAYOUT
-static int nowayout = 1;
-#else
-static int nowayout = 0;
-#endif
-
+static int nowayout = WATCHDOG_NOWAYOUT;
 module_param(nowayout, int, 0);
 MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
 
diff --git a/drivers/char/watchdog/wdt_pci.c b/drivers/char/watchdog/wdt_pci.c
--- a/drivers/char/watchdog/wdt_pci.c
+++ b/drivers/char/watchdog/wdt_pci.c
@@ -89,12 +89,7 @@ static int wd_heartbeat;
 module_param(heartbeat, int, 0);
 MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (0<heartbeat<65536, default=" __MODULE_STRING(WD_TIMO) ")");
 
-#ifdef CONFIG_WATCHDOG_NOWAYOUT
-static int nowayout = 1;
-#else
-static int nowayout = 0;
-#endif
-
+static int nowayout = WATCHDOG_NOWAYOUT;
 module_param(nowayout, int, 0);
 MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
 
@@ -311,7 +306,7 @@ static irqreturn_t wdtpci_interrupt(int 
 		printk(KERN_CRIT PFX "Would Reboot.\n");
 #else
 		printk(KERN_CRIT PFX "Initiating system reboot.\n");
-		machine_restart(NULL);
+		emergency_restart(NULL);
 #endif
 #else
 		printk(KERN_CRIT PFX "Reset in 5ms.\n");
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -521,7 +521,7 @@ static ssize_t show(struct kobject * kob
 	policy = cpufreq_cpu_get(policy->cpu);
 	if (!policy)
 		return -EINVAL;
-	ret = fattr->show ? fattr->show(policy,buf) : 0;
+	ret = fattr->show ? fattr->show(policy,buf) : -EIO;
 	cpufreq_cpu_put(policy);
 	return ret;
 }
@@ -535,7 +535,7 @@ static ssize_t store(struct kobject * ko
 	policy = cpufreq_cpu_get(policy->cpu);
 	if (!policy)
 		return -EINVAL;
-	ret = fattr->store ? fattr->store(policy,buf,count) : 0;
+	ret = fattr->store ? fattr->store(policy,buf,count) : -EIO;
 	cpufreq_cpu_put(policy);
 	return ret;
 }
@@ -869,7 +869,7 @@ EXPORT_SYMBOL(cpufreq_get);
  *	cpufreq_suspend - let the low level driver prepare for suspend
  */
 
-static int cpufreq_suspend(struct sys_device * sysdev, u32 state)
+static int cpufreq_suspend(struct sys_device * sysdev, pm_message_t pmsg)
 {
 	int cpu = sysdev->id;
 	unsigned int ret = 0;
@@ -897,7 +897,7 @@ static int cpufreq_suspend(struct sys_de
 	}
 
 	if (cpufreq_driver->suspend) {
-		ret = cpufreq_driver->suspend(cpu_policy, state);
+		ret = cpufreq_driver->suspend(cpu_policy, pmsg);
 		if (ret) {
 			printk(KERN_ERR "cpufreq: suspend failed in ->suspend "
 					"step on CPU %u\n", cpu_policy->cpu);
@@ -1130,7 +1130,7 @@ int cpufreq_driver_target(struct cpufreq
 			  unsigned int target_freq,
 			  unsigned int relation)
 {
-	unsigned int ret;
+	int ret;
 
 	policy = cpufreq_cpu_get(policy->cpu);
 	if (!policy)
@@ -1151,7 +1151,7 @@ EXPORT_SYMBOL_GPL(cpufreq_driver_target)
 
 static int __cpufreq_governor(struct cpufreq_policy *policy, unsigned int event)
 {
-	int ret = -EINVAL;
+	int ret;
 
 	if (!try_module_get(policy->governor->owner))
 		return -EINVAL;
diff --git a/drivers/crypto/padlock-aes.c b/drivers/crypto/padlock-aes.c
--- a/drivers/crypto/padlock-aes.c
+++ b/drivers/crypto/padlock-aes.c
@@ -49,6 +49,7 @@
 #include <linux/errno.h>
 #include <linux/crypto.h>
 #include <linux/interrupt.h>
+#include <linux/kernel.h>
 #include <asm/byteorder.h>
 #include "padlock.h"
 
@@ -59,8 +60,12 @@
 #define AES_EXTENDED_KEY_SIZE_B	(AES_EXTENDED_KEY_SIZE * sizeof(uint32_t))
 
 struct aes_ctx {
-	uint32_t e_data[AES_EXTENDED_KEY_SIZE+4];
-	uint32_t d_data[AES_EXTENDED_KEY_SIZE+4];
+	uint32_t e_data[AES_EXTENDED_KEY_SIZE];
+	uint32_t d_data[AES_EXTENDED_KEY_SIZE];
+	struct {
+		struct cword encrypt;
+		struct cword decrypt;
+	} cword;
 	uint32_t *E;
 	uint32_t *D;
 	int key_length;
@@ -280,10 +285,15 @@ aes_hw_extkey_available(uint8_t key_len)
 	return 0;
 }
 
+static inline struct aes_ctx *aes_ctx(void *ctx)
+{
+	return (struct aes_ctx *)ALIGN((unsigned long)ctx, PADLOCK_ALIGNMENT);
+}
+
 static int
 aes_set_key(void *ctx_arg, const uint8_t *in_key, unsigned int key_len, uint32_t *flags)
 {
-	struct aes_ctx *ctx = ctx_arg;
+	struct aes_ctx *ctx = aes_ctx(ctx_arg);
 	uint32_t i, t, u, v, w;
 	uint32_t P[AES_EXTENDED_KEY_SIZE];
 	uint32_t rounds;
@@ -295,25 +305,36 @@ aes_set_key(void *ctx_arg, const uint8_t
 
 	ctx->key_length = key_len;
 
+	/*
+	 * If the hardware is capable of generating the extended key
+	 * itself we must supply the plain key for both encryption
+	 * and decryption.
+	 */
 	ctx->E = ctx->e_data;
-	ctx->D = ctx->d_data;
-
-	/* Ensure 16-Bytes alignmentation of keys for VIA PadLock. */
-	if ((int)(ctx->e_data) & 0x0F)
-		ctx->E += 4 - (((int)(ctx->e_data) & 0x0F) / sizeof (ctx->e_data[0]));
-
-	if ((int)(ctx->d_data) & 0x0F)
-		ctx->D += 4 - (((int)(ctx->d_data) & 0x0F) / sizeof (ctx->d_data[0]));
+	ctx->D = ctx->e_data;
 
 	E_KEY[0] = uint32_t_in (in_key);
 	E_KEY[1] = uint32_t_in (in_key + 4);
 	E_KEY[2] = uint32_t_in (in_key + 8);
 	E_KEY[3] = uint32_t_in (in_key + 12);
 
+	/* Prepare control words. */
+	memset(&ctx->cword, 0, sizeof(ctx->cword));
+
+	ctx->cword.decrypt.encdec = 1;
+	ctx->cword.encrypt.rounds = 10 + (key_len - 16) / 4;
+	ctx->cword.decrypt.rounds = ctx->cword.encrypt.rounds;
+	ctx->cword.encrypt.ksize = (key_len - 16) / 8;
+	ctx->cword.decrypt.ksize = ctx->cword.encrypt.ksize;
+
 	/* Don't generate extended keys if the hardware can do it. */
 	if (aes_hw_extkey_available(key_len))
 		return 0;
 
+	ctx->D = ctx->d_data;
+	ctx->cword.encrypt.keygen = 1;
+	ctx->cword.decrypt.keygen = 1;
+
 	switch (key_len) {
 	case 16:
 		t = E_KEY[3];
@@ -369,10 +390,9 @@ aes_set_key(void *ctx_arg, const uint8_t
 
 /* ====== Encryption/decryption routines ====== */
 
-/* This is the real call to PadLock. */
-static inline void
-padlock_xcrypt_ecb(uint8_t *input, uint8_t *output, uint8_t *key,
-		   void *control_word, uint32_t count)
+/* These are the real call to PadLock. */
+static inline void padlock_xcrypt_ecb(const u8 *input, u8 *output, void *key,
+				      void *control_word, u32 count)
 {
 	asm volatile ("pushfl; popfl");		/* enforce key reload. */
 	asm volatile (".byte 0xf3,0x0f,0xa7,0xc8"	/* rep xcryptecb */
@@ -380,60 +400,70 @@ padlock_xcrypt_ecb(uint8_t *input, uint8
 		      : "d"(control_word), "b"(key), "c"(count));
 }
 
-static void
-aes_padlock(void *ctx_arg, uint8_t *out_arg, const uint8_t *in_arg, int encdec)
+static inline u8 *padlock_xcrypt_cbc(const u8 *input, u8 *output, void *key,
+				     u8 *iv, void *control_word, u32 count)
 {
-	/* Don't blindly modify this structure - the items must 
-	   fit on 16-Bytes boundaries! */
-	struct padlock_xcrypt_data {
-		uint8_t buf[AES_BLOCK_SIZE];
-		union cword cword;
-	};
-
-	struct aes_ctx *ctx = ctx_arg;
-	char bigbuf[sizeof(struct padlock_xcrypt_data) + 16];
-	struct padlock_xcrypt_data *data;
-	void *key;
-
-	/* Place 'data' at the first 16-Bytes aligned address in 'bigbuf'. */
-	if (((long)bigbuf) & 0x0F)
-		data = (void*)(bigbuf + 16 - ((long)bigbuf & 0x0F));
-	else
-		data = (void*)bigbuf;
-
-	/* Prepare Control word. */
-	memset (data, 0, sizeof(struct padlock_xcrypt_data));
-	data->cword.b.encdec = !encdec;	/* in the rest of cryptoapi ENC=1/DEC=0 */
-	data->cword.b.rounds = 10 + (ctx->key_length - 16) / 4;
-	data->cword.b.ksize = (ctx->key_length - 16) / 8;
-
-	/* Is the hardware capable to generate the extended key? */
-	if (!aes_hw_extkey_available(ctx->key_length))
-		data->cword.b.keygen = 1;
-
-	/* ctx->E starts with a plain key - if the hardware is capable
-	   to generate the extended key itself we must supply
-	   the plain key for both Encryption and Decryption. */
-	if (encdec == CRYPTO_DIR_ENCRYPT || data->cword.b.keygen == 0)
-		key = ctx->E;
-	else
-		key = ctx->D;
-	
-	memcpy(data->buf, in_arg, AES_BLOCK_SIZE);
-	padlock_xcrypt_ecb(data->buf, data->buf, key, &data->cword, 1);
-	memcpy(out_arg, data->buf, AES_BLOCK_SIZE);
+	/* Enforce key reload. */
+	asm volatile ("pushfl; popfl");
+	/* rep xcryptcbc */
+	asm volatile (".byte 0xf3,0x0f,0xa7,0xd0"
+		      : "+S" (input), "+D" (output), "+a" (iv)
+		      : "d" (control_word), "b" (key), "c" (count));
+	return iv;
 }
 
 static void
 aes_encrypt(void *ctx_arg, uint8_t *out, const uint8_t *in)
 {
-	aes_padlock(ctx_arg, out, in, CRYPTO_DIR_ENCRYPT);
+	struct aes_ctx *ctx = aes_ctx(ctx_arg);
+	padlock_xcrypt_ecb(in, out, ctx->E, &ctx->cword.encrypt, 1);
 }
 
 static void
 aes_decrypt(void *ctx_arg, uint8_t *out, const uint8_t *in)
 {
-	aes_padlock(ctx_arg, out, in, CRYPTO_DIR_DECRYPT);
+	struct aes_ctx *ctx = aes_ctx(ctx_arg);
+	padlock_xcrypt_ecb(in, out, ctx->D, &ctx->cword.decrypt, 1);
+}
+
+static unsigned int aes_encrypt_ecb(const struct cipher_desc *desc, u8 *out,
+				    const u8 *in, unsigned int nbytes)
+{
+	struct aes_ctx *ctx = aes_ctx(crypto_tfm_ctx(desc->tfm));
+	padlock_xcrypt_ecb(in, out, ctx->E, &ctx->cword.encrypt,
+			   nbytes / AES_BLOCK_SIZE);
+	return nbytes & ~(AES_BLOCK_SIZE - 1);
+}
+
+static unsigned int aes_decrypt_ecb(const struct cipher_desc *desc, u8 *out,
+				    const u8 *in, unsigned int nbytes)
+{
+	struct aes_ctx *ctx = aes_ctx(crypto_tfm_ctx(desc->tfm));
+	padlock_xcrypt_ecb(in, out, ctx->D, &ctx->cword.decrypt,
+			   nbytes / AES_BLOCK_SIZE);
+	return nbytes & ~(AES_BLOCK_SIZE - 1);
+}
+
+static unsigned int aes_encrypt_cbc(const struct cipher_desc *desc, u8 *out,
+				    const u8 *in, unsigned int nbytes)
+{
+	struct aes_ctx *ctx = aes_ctx(crypto_tfm_ctx(desc->tfm));
+	u8 *iv;
+
+	iv = padlock_xcrypt_cbc(in, out, ctx->E, desc->info,
+				&ctx->cword.encrypt, nbytes / AES_BLOCK_SIZE);
+	memcpy(desc->info, iv, AES_BLOCK_SIZE);
+
+	return nbytes & ~(AES_BLOCK_SIZE - 1);
+}
+
+static unsigned int aes_decrypt_cbc(const struct cipher_desc *desc, u8 *out,
+				    const u8 *in, unsigned int nbytes)
+{
+	struct aes_ctx *ctx = aes_ctx(crypto_tfm_ctx(desc->tfm));
+	padlock_xcrypt_cbc(in, out, ctx->D, desc->info, &ctx->cword.decrypt,
+			   nbytes / AES_BLOCK_SIZE);
+	return nbytes & ~(AES_BLOCK_SIZE - 1);
 }
 
 static struct crypto_alg aes_alg = {
@@ -441,6 +471,7 @@ static struct crypto_alg aes_alg = {
 	.cra_flags		=	CRYPTO_ALG_TYPE_CIPHER,
 	.cra_blocksize		=	AES_BLOCK_SIZE,
 	.cra_ctxsize		=	sizeof(struct aes_ctx),
+	.cra_alignmask		=	PADLOCK_ALIGNMENT - 1,
 	.cra_module		=	THIS_MODULE,
 	.cra_list		=	LIST_HEAD_INIT(aes_alg.cra_list),
 	.cra_u			=	{
@@ -449,7 +480,11 @@ static struct crypto_alg aes_alg = {
 			.cia_max_keysize	=	AES_MAX_KEY_SIZE,
 			.cia_setkey	   	= 	aes_set_key,
 			.cia_encrypt	 	=	aes_encrypt,
-			.cia_decrypt	  	=	aes_decrypt
+			.cia_decrypt	  	=	aes_decrypt,
+			.cia_encrypt_ecb 	=	aes_encrypt_ecb,
+			.cia_decrypt_ecb  	=	aes_decrypt_ecb,
+			.cia_encrypt_cbc 	=	aes_encrypt_cbc,
+			.cia_decrypt_cbc  	=	aes_decrypt_cbc,
 		}
 	}
 };
diff --git a/drivers/crypto/padlock.h b/drivers/crypto/padlock.h
--- a/drivers/crypto/padlock.h
+++ b/drivers/crypto/padlock.h
@@ -13,18 +13,18 @@
 #ifndef _CRYPTO_PADLOCK_H
 #define _CRYPTO_PADLOCK_H
 
+#define PADLOCK_ALIGNMENT 16
+
 /* Control word. */
-union cword {
-	uint32_t cword[4];
-	struct {
-		int rounds:4;
-		int algo:3;
-		int keygen:1;
-		int interm:1;
-		int encdec:1;
-		int ksize:2;
-	} b;
-};
+struct cword {
+	int __attribute__ ((__packed__))
+		rounds:4,
+		algo:3,
+		keygen:1,
+		interm:1,
+		encdec:1,
+		ksize:2;
+} __attribute__ ((__aligned__(PADLOCK_ALIGNMENT)));
 
 #define PFX	"padlock: "
 
diff --git a/drivers/dio/dio-sysfs.c b/drivers/dio/dio-sysfs.c
--- a/drivers/dio/dio-sysfs.c
+++ b/drivers/dio/dio-sysfs.c
@@ -17,7 +17,7 @@
 
 /* show configuration fields */
 
-static ssize_t dio_show_id(struct device *dev, char *buf)
+static ssize_t dio_show_id(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct dio_dev *d;
 
@@ -26,7 +26,7 @@ static ssize_t dio_show_id(struct device
 }
 static DEVICE_ATTR(id, S_IRUGO, dio_show_id, NULL);
 
-static ssize_t dio_show_ipl(struct device *dev, char *buf)
+static ssize_t dio_show_ipl(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct dio_dev *d;
 
@@ -35,7 +35,7 @@ static ssize_t dio_show_ipl(struct devic
 }
 static DEVICE_ATTR(ipl, S_IRUGO, dio_show_ipl, NULL);
 
-static ssize_t dio_show_secid(struct device *dev, char *buf)
+static ssize_t dio_show_secid(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct dio_dev *d;
 
@@ -44,7 +44,7 @@ static ssize_t dio_show_secid(struct dev
 }
 static DEVICE_ATTR(secid, S_IRUGO, dio_show_secid, NULL);
 
-static ssize_t dio_show_name(struct device *dev, char *buf)
+static ssize_t dio_show_name(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct dio_dev *d;
 
@@ -53,7 +53,7 @@ static ssize_t dio_show_name(struct devi
 }
 static DEVICE_ATTR(name, S_IRUGO, dio_show_name, NULL);
 
-static ssize_t dio_show_resource(struct device *dev, char *buf)
+static ssize_t dio_show_resource(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct dio_dev *d = to_dio_dev(dev);
 
diff --git a/drivers/eisa/eisa-bus.c b/drivers/eisa/eisa-bus.c
--- a/drivers/eisa/eisa-bus.c
+++ b/drivers/eisa/eisa-bus.c
@@ -149,7 +149,7 @@ void eisa_driver_unregister (struct eisa
 	driver_unregister (&edrv->driver);
 }
 
-static ssize_t eisa_show_sig (struct device *dev, char *buf)
+static ssize_t eisa_show_sig (struct device *dev, struct device_attribute *attr, char *buf)
 {
         struct eisa_device *edev = to_eisa_device (dev);
         return sprintf (buf,"%s\n", edev->id.sig);
@@ -157,7 +157,7 @@ static ssize_t eisa_show_sig (struct dev
 
 static DEVICE_ATTR(signature, S_IRUGO, eisa_show_sig, NULL);
 
-static ssize_t eisa_show_state (struct device *dev, char *buf)
+static ssize_t eisa_show_state (struct device *dev, struct device_attribute *attr, char *buf)
 {
         struct eisa_device *edev = to_eisa_device (dev);
         return sprintf (buf,"%d\n", edev->state & EISA_CONFIG_ENABLED);
diff --git a/drivers/fc4/fc.c b/drivers/fc4/fc.c
--- a/drivers/fc4/fc.c
+++ b/drivers/fc4/fc.c
@@ -365,6 +365,7 @@ void fcp_register(fc_channel *fc, u8 typ
 			kfree (fc->scsi_bitmap);
 			kfree (fc->cmd_slots);
 			FCND(("Unregistering\n"));
+#if 0
 			if (fc->rst_pkt) {
 				if (fc->rst_pkt->eh_state == SCSI_STATE_UNUSED)
 					kfree(fc->rst_pkt);
@@ -373,6 +374,7 @@ void fcp_register(fc_channel *fc, u8 typ
 					printk("FC: Reset in progress. Now?!");
 				}
 			}
+#endif
 			FCND(("Unregistered\n"));
 		}
 	} else
@@ -765,12 +767,8 @@ void fcp_release(fc_channel *fcchain, in
 
 static void fcp_scsi_done (Scsi_Cmnd *SCpnt)
 {
-	unsigned long flags;
-
-	spin_lock_irqsave(SCpnt->device->host->host_lock, flags);
 	if (FCP_CMND(SCpnt)->done)
 		FCP_CMND(SCpnt)->done(SCpnt);
-	spin_unlock_irqrestore(SCpnt->device->host->host_lock, flags);
 }
 
 static int fcp_scsi_queue_it(fc_channel *fc, Scsi_Cmnd *SCpnt, fcp_cmnd *fcmd, int prepare)
@@ -909,12 +907,8 @@ int fcp_scsi_abort(Scsi_Cmnd *SCpnt)
 	 */
 
 	if (++fc->abort_count < (fc->can_queue >> 1)) {
-		unsigned long flags;
-
 		SCpnt->result = DID_ABORT;
-		spin_lock_irqsave(SCpnt->device->host->host_lock, flags);
 		fcmd->done(SCpnt);
-		spin_unlock_irqrestore(SCpnt->device->host->host_lock, flags);
 		printk("FC: soft abort\n");
 		return SUCCESS;
 	} else {
@@ -923,6 +917,7 @@ int fcp_scsi_abort(Scsi_Cmnd *SCpnt)
 	}
 }
 
+#if 0
 void fcp_scsi_reset_done(Scsi_Cmnd *SCpnt)
 {
 	fc_channel *fc = FC_SCMND(SCpnt);
@@ -930,11 +925,14 @@ void fcp_scsi_reset_done(Scsi_Cmnd *SCpn
 	fc->rst_pkt->eh_state = SCSI_STATE_FINISHED;
 	up(fc->rst_pkt->device->host->eh_action);
 }
+#endif
 
 #define FCP_RESET_TIMEOUT (2*HZ)
 
 int fcp_scsi_dev_reset(Scsi_Cmnd *SCpnt)
 {
+#if 0 /* broken junk, but if davem wants to compile this driver, let him.. */
+	unsigned long flags;
 	fcp_cmd *cmd;
 	fcp_cmnd *fcmd;
 	fc_channel *fc = FC_SCMND(SCpnt);
@@ -987,7 +985,10 @@ int fcp_scsi_dev_reset(Scsi_Cmnd *SCpnt)
 	fc->rst_pkt->request->rq_status = RQ_SCSI_BUSY;
 
 	fc->rst_pkt->done = fcp_scsi_reset_done;
+
+	spin_lock_irqsave(SCpnt->device->host->host_lock, flags);
 	fcp_scsi_queue_it(fc, fc->rst_pkt, fcmd, 0);
+	spin_unlock_irqrestore(SCpnt->device->host->host_lock, flags);
 	
 	down(&sem);
 
@@ -1003,16 +1004,11 @@ int fcp_scsi_dev_reset(Scsi_Cmnd *SCpnt)
 		return FAILED;
 	}
 	fc->rst_pkt->eh_state = SCSI_STATE_UNUSED;
+#endif
 	return SUCCESS;
 }
 
-int fcp_scsi_bus_reset(Scsi_Cmnd *SCpnt)
-{
-	printk ("FC: bus reset!\n");
-	return FAILED;
-}
-
-int fcp_scsi_host_reset(Scsi_Cmnd *SCpnt)
+static int __fcp_scsi_host_reset(Scsi_Cmnd *SCpnt)
 {
 	fc_channel *fc = FC_SCMND(SCpnt);
 	fcp_cmnd *fcmd = FCP_CMND(SCpnt);
@@ -1033,6 +1029,18 @@ int fcp_scsi_host_reset(Scsi_Cmnd *SCpnt
 	else return FAILED;
 }
 
+int fcp_scsi_host_reset(Scsi_Cmnd *SCpnt)
+{
+	unsigned long flags;
+	int rc;
+
+	spin_lock_irqsave(SCpnt->device->host->host_lock, flags);
+	rc = __fcp_scsi_host_reset(SCpnt);
+	spin_unlock_irqrestore(SCpnt->device->host->host_lock, flags);
+
+	return rc;
+}
+
 static int fcp_els_queue_it(fc_channel *fc, fcp_cmnd *fcmd)
 {
 	long i;
diff --git a/drivers/fc4/fc_syms.c b/drivers/fc4/fc_syms.c
--- a/drivers/fc4/fc_syms.c
+++ b/drivers/fc4/fc_syms.c
@@ -27,7 +27,6 @@ EXPORT_SYMBOL(fc_do_prli);
 EXPORT_SYMBOL(fcp_scsi_queuecommand);
 EXPORT_SYMBOL(fcp_scsi_abort);
 EXPORT_SYMBOL(fcp_scsi_dev_reset);
-EXPORT_SYMBOL(fcp_scsi_bus_reset);
 EXPORT_SYMBOL(fcp_scsi_host_reset);
 
 #endif /* CONFIG_MODULES */
diff --git a/drivers/fc4/fcp_impl.h b/drivers/fc4/fcp_impl.h
--- a/drivers/fc4/fcp_impl.h
+++ b/drivers/fc4/fcp_impl.h
@@ -158,7 +158,6 @@ int fc_do_prli(fc_channel *, unsigned ch
 int fcp_scsi_queuecommand(Scsi_Cmnd *, void (* done)(Scsi_Cmnd *));
 int fcp_scsi_abort(Scsi_Cmnd *);
 int fcp_scsi_dev_reset(Scsi_Cmnd *);
-int fcp_scsi_bus_reset(Scsi_Cmnd *);
 int fcp_scsi_host_reset(Scsi_Cmnd *);
 
 #endif /* !(_FCP_SCSI_H) */
diff --git a/drivers/firmware/edd.c b/drivers/firmware/edd.c
--- a/drivers/firmware/edd.c
+++ b/drivers/firmware/edd.c
@@ -115,7 +115,7 @@ edd_attr_show(struct kobject * kobj, str
 {
 	struct edd_device *dev = to_edd_device(kobj);
 	struct edd_attribute *edd_attr = to_edd_attr(attr);
-	ssize_t ret = 0;
+	ssize_t ret = -EIO;
 
 	if (edd_attr->show)
 		ret = edd_attr->show(dev, buf);
diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c
--- a/drivers/firmware/efivars.c
+++ b/drivers/firmware/efivars.c
@@ -352,7 +352,7 @@ static ssize_t efivar_attr_show(struct k
 {
 	struct efivar_entry *var = to_efivar_entry(kobj);
 	struct efivar_attribute *efivar_attr = to_efivar_attr(attr);
-	ssize_t ret = 0;
+	ssize_t ret = -EIO;
 
 	if (!capable(CAP_SYS_ADMIN))
 		return -EACCES;
@@ -368,7 +368,7 @@ static ssize_t efivar_attr_store(struct 
 {
 	struct efivar_entry *var = to_efivar_entry(kobj);
 	struct efivar_attribute *efivar_attr = to_efivar_attr(attr);
-	ssize_t ret = 0;
+	ssize_t ret = -EIO;
 
 	if (!capable(CAP_SYS_ADMIN))
 		return -EACCES;
@@ -618,8 +618,8 @@ efivar_create_sysfs_entry(unsigned long 
 	new_efivar = kmalloc(sizeof(struct efivar_entry), GFP_KERNEL);
 
 	if (!short_name || !new_efivar)  {
-		if (short_name)        kfree(short_name);
-		if (new_efivar)        kfree(new_efivar);
+		kfree(short_name);
+		kfree(new_efivar);
 		return 1;
 	}
 	memset(short_name, 0, short_name_size+1);
@@ -644,7 +644,8 @@ efivar_create_sysfs_entry(unsigned long 
 	kobj_set_kset_s(new_efivar, vars_subsys);
 	kobject_register(&new_efivar->kobj);
 
-	kfree(short_name); short_name = NULL;
+	kfree(short_name);
+	short_name = NULL;
 
 	spin_lock(&efivars_lock);
 	list_add(&new_efivar->list, &efivar_list);
diff --git a/drivers/firmware/pcdp.c b/drivers/firmware/pcdp.c
--- a/drivers/firmware/pcdp.c
+++ b/drivers/firmware/pcdp.c
@@ -16,6 +16,7 @@
 #include <linux/console.h>
 #include <linux/efi.h>
 #include <linux/serial.h>
+#include <asm/vga.h>
 #include "pcdp.h"
 
 static int __init
@@ -23,12 +24,23 @@ setup_serial_console(struct pcdp_uart *u
 {
 #ifdef CONFIG_SERIAL_8250_CONSOLE
 	int mmio;
-	static char options[64];
+	static char options[64], *p = options;
+	char parity;
 
 	mmio = (uart->addr.address_space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY);
-	snprintf(options, sizeof(options), "console=uart,%s,0x%lx,%lun%d",
-		mmio ? "mmio" : "io", uart->addr.address, uart->baud,
-		uart->bits ? uart->bits : 8);
+	p += sprintf(p, "console=uart,%s,0x%lx",
+		mmio ? "mmio" : "io", uart->addr.address);
+	if (uart->baud) {
+		p += sprintf(p, ",%lu", uart->baud);
+		if (uart->bits) {
+			switch (uart->parity) {
+			    case 0x2: parity = 'e'; break;
+			    case 0x3: parity = 'o'; break;
+			    default:  parity = 'n';
+			}
+			p += sprintf(p, "%c%d", parity, uart->bits);
+		}
+	}
 
 	return early_serial_console_init(options);
 #else
@@ -37,10 +49,27 @@ setup_serial_console(struct pcdp_uart *u
 }
 
 static int __init
-setup_vga_console(struct pcdp_vga *vga)
+setup_vga_console(struct pcdp_device *dev)
 {
 #if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE)
-	if (efi_mem_type(0xA0000) == EFI_CONVENTIONAL_MEMORY) {
+	u8 *if_ptr;
+
+	if_ptr = ((u8 *)dev + sizeof(struct pcdp_device));
+	if (if_ptr[0] == PCDP_IF_PCI) {
+		struct pcdp_if_pci if_pci;
+
+		/* struct copy since ifptr might not be correctly aligned */
+
+		memcpy(&if_pci, if_ptr, sizeof(if_pci));
+
+		if (if_pci.trans & PCDP_PCI_TRANS_IOPORT)
+			vga_console_iobase = if_pci.ioport_tra;
+
+		if (if_pci.trans & PCDP_PCI_TRANS_MMIO)
+			vga_console_membase = if_pci.mmio_tra;
+	}
+
+	if (efi_mem_type(vga_console_membase + 0xA0000) == EFI_CONVENTIONAL_MEMORY) {
 		printk(KERN_ERR "PCDP: VGA selected, but frame buffer is not MMIO!\n");
 		return -ENODEV;
 	}
@@ -92,7 +121,7 @@ efi_setup_pcdp_console(char *cmdline)
 	     dev = (struct pcdp_device *) ((u8 *) dev + dev->length)) {
 		if (dev->flags & PCDP_PRIMARY_CONSOLE) {
 			if (dev->type == PCDP_CONSOLE_VGA) {
-				return setup_vga_console((struct pcdp_vga *) dev);
+				return setup_vga_console(dev);
 			}
 		}
 	}
diff --git a/drivers/firmware/pcdp.h b/drivers/firmware/pcdp.h
--- a/drivers/firmware/pcdp.h
+++ b/drivers/firmware/pcdp.h
@@ -2,7 +2,7 @@
  * Definitions for PCDP-defined console devices
  *
  * v1.0a: http://www.dig64.org/specifications/DIG64_HCDPv10a_01.pdf
- * v2.0:  http://www.dig64.org/specifications/DIG64_HCDPv20_042804.pdf
+ * v2.0:  http://www.dig64.org/specifications/DIG64_PCDPv20.pdf
  *
  * (c) Copyright 2002, 2004 Hewlett-Packard Development Company, L.P.
  *	Khalid Aziz <khalid.aziz@hp.com>
@@ -52,11 +52,36 @@ struct pcdp_uart {
 	u32				clock_rate;
 	u8				pci_prog_intfc;
 	u8				flags;
-};
+	u16				conout_index;
+	u32				reserved;
+} __attribute__((packed));
+
+#define PCDP_IF_PCI	1
+
+/* pcdp_if_pci.trans */
+#define PCDP_PCI_TRANS_IOPORT	0x02
+#define PCDP_PCI_TRANS_MMIO	0x01
+
+struct pcdp_if_pci {
+	u8			interconnect;
+	u8			reserved;
+	u16			length;
+	u8			segment;
+	u8			bus;
+	u8			dev;
+	u8			fun;
+	u16			dev_id;
+	u16			vendor_id;
+	u32			acpi_interrupt;
+	u64			mmio_tra;
+	u64			ioport_tra;
+	u8			flags;
+	u8			trans;
+} __attribute__((packed));
 
 struct pcdp_vga {
 	u8			count;		/* address space descriptors */
-};
+} __attribute__((packed));
 
 /* pcdp_device.flags */
 #define PCDP_PRIMARY_CONSOLE	1
@@ -66,7 +91,9 @@ struct pcdp_device {
 	u8			flags;
 	u16			length;
 	u16			efi_index;
-};
+	/* next data is pcdp_if_pci or pcdp_if_acpi (not yet supported) */
+	/* next data is device specific type (currently only pcdp_vga) */
+} __attribute__((packed));
 
 struct pcdp {
 	u8			signature[4];
@@ -81,4 +108,4 @@ struct pcdp {
 	u32			num_uarts;
 	struct pcdp_uart	uart[0];	/* actual size is num_uarts */
 	/* remainder of table is pcdp_device structures */
-};
+} __attribute__((packed));
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
new file mode 100644
--- /dev/null
+++ b/drivers/hwmon/Kconfig
@@ -0,0 +1,420 @@
+#
+# I2C Sensor chip drivers configuration
+#
+
+menu "Hardware Monitoring support"
+
+config HWMON
+	tristate "Hardware Monitoring support"
+	default y
+	help
+	  Hardware monitoring devices let you monitor the hardware health
+	  of a system. Most modern motherboards include such a device. It
+	  can include temperature sensors, voltage sensors, fan speed
+	  sensors and various additional features such as the ability to
+	  control the speed of the fans.
+
+config SENSORS_ADM1021
+	tristate "Analog Devices ADM1021 and compatibles"
+	depends on HWMON && I2C
+	select I2C_SENSOR
+	help
+	  If you say yes here you get support for Analog Devices ADM1021
+	  and ADM1023 sensor chips and clones: Maxim MAX1617 and MAX1617A,
+	  Genesys Logic GL523SM, National Semiconductor LM84, TI THMC10,
+	  and the XEON processor built-in sensor.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called adm1021.
+
+config SENSORS_ADM1025
+	tristate "Analog Devices ADM1025 and compatibles"
+	depends on HWMON && I2C && EXPERIMENTAL
+	select I2C_SENSOR
+	help
+	  If you say yes here you get support for Analog Devices ADM1025
+	  and Philips NE1619 sensor chips.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called adm1025.
+
+config SENSORS_ADM1026
+	tristate "Analog Devices ADM1026 and compatibles"
+	depends on HWMON && I2C && EXPERIMENTAL
+	select I2C_SENSOR
+	help
+	  If you say yes here you get support for Analog Devices ADM1026
+	  sensor chip.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called adm1026.
+
+config SENSORS_ADM1031
+	tristate "Analog Devices ADM1031 and compatibles"
+	depends on HWMON && I2C && EXPERIMENTAL
+	select I2C_SENSOR
+	help
+	  If you say yes here you get support for Analog Devices ADM1031
+	  and ADM1030 sensor chips.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called adm1031.
+
+config SENSORS_ADM9240
+	tristate "Analog Devices ADM9240 and compatibles"
+	depends on HWMON && I2C && EXPERIMENTAL
+	select I2C_SENSOR
+	help
+	  If you say yes here you get support for Analog Devices ADM9240,
+	  Dallas DS1780, National Semiconductor LM81 sensor chips.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called adm9240.
+
+config SENSORS_ASB100
+	tristate "Asus ASB100 Bach"
+	depends on HWMON && I2C && EXPERIMENTAL
+	select I2C_SENSOR
+	help
+	  If you say yes here you get support for the ASB100 Bach sensor
+	  chip found on some Asus mainboards.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called asb100.
+
+config SENSORS_ATXP1
+	tristate "Attansic ATXP1 VID controller"
+	depends on HWMON && I2C && EXPERIMENTAL
+	select I2C_SENSOR
+	help
+	  If you say yes here you get support for the Attansic ATXP1 VID
+	  controller.
+
+	  If your board have such a chip, you are able to control your CPU
+	  core and other voltages.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called atxp1.
+
+config SENSORS_DS1621
+	tristate "Dallas Semiconductor DS1621 and DS1625"
+	depends on HWMON && I2C && EXPERIMENTAL
+	select I2C_SENSOR
+	help
+	  If you say yes here you get support for Dallas Semiconductor
+	  DS1621 and DS1625 sensor chips.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called ds1621.
+
+config SENSORS_FSCHER
+	tristate "FSC Hermes"
+	depends on HWMON && I2C && EXPERIMENTAL
+	select I2C_SENSOR
+	help
+	  If you say yes here you get support for Fujitsu Siemens
+	  Computers Hermes sensor chips.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called fscher.
+
+config SENSORS_FSCPOS
+	tristate "FSC Poseidon"
+	depends on HWMON && I2C && EXPERIMENTAL
+	select I2C_SENSOR
+	help
+	  If you say yes here you get support for Fujitsu Siemens
+	  Computers Poseidon sensor chips.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called fscpos.
+
+config SENSORS_GL518SM
+	tristate "Genesys Logic GL518SM"
+	depends on HWMON && I2C
+	select I2C_SENSOR
+	help
+	  If you say yes here you get support for Genesys Logic GL518SM
+	  sensor chips.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called gl518sm.
+
+config SENSORS_GL520SM
+	tristate "Genesys Logic GL520SM"
+	depends on HWMON && I2C && EXPERIMENTAL
+	select I2C_SENSOR
+	help
+	  If you say yes here you get support for Genesys Logic GL520SM
+	  sensor chips.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called gl520sm.
+
+config SENSORS_IT87
+	tristate "ITE IT87xx and compatibles"
+	depends on HWMON && I2C
+	select I2C_SENSOR
+	help
+	  If you say yes here you get support for ITE IT87xx sensor chips
+	  and clones: SiS960.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called it87.
+
+config SENSORS_LM63
+	tristate "National Semiconductor LM63"
+	depends on HWMON && I2C && EXPERIMENTAL
+	select I2C_SENSOR
+	help
+	  If you say yes here you get support for the National Semiconductor
+	  LM63 remote diode digital temperature sensor with integrated fan
+	  control.  Such chips are found on the Tyan S4882 (Thunder K8QS Pro)
+	  motherboard, among others.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called lm63.
+
+config SENSORS_LM75
+	tristate "National Semiconductor LM75 and compatibles"
+	depends on HWMON && I2C
+	select I2C_SENSOR
+	help
+	  If you say yes here you get support for National Semiconductor LM75
+	  sensor chips and clones: Dallas Semiconductor DS75 and DS1775 (in
+	  9-bit precision mode), and TelCom (now Microchip) TCN75.
+
+	  The DS75 and DS1775 in 10- to 12-bit precision modes will require
+	  a force module parameter. The driver will not handle the extra
+	  precision anyhow.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called lm75.
+
+config SENSORS_LM77
+	tristate "National Semiconductor LM77"
+	depends on HWMON && I2C && EXPERIMENTAL
+	select I2C_SENSOR
+	help
+	  If you say yes here you get support for National Semiconductor LM77
+	  sensor chips.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called lm77.
+
+config SENSORS_LM78
+	tristate "National Semiconductor LM78 and compatibles"
+	depends on HWMON && I2C && EXPERIMENTAL
+	select I2C_SENSOR
+	help
+	  If you say yes here you get support for National Semiconductor LM78,
+	  LM78-J and LM79.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called lm78.
+
+config SENSORS_LM80
+	tristate "National Semiconductor LM80"
+	depends on HWMON && I2C && EXPERIMENTAL
+	select I2C_SENSOR
+	help
+	  If you say yes here you get support for National Semiconductor
+	  LM80 sensor chips.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called lm80.
+
+config SENSORS_LM83
+	tristate "National Semiconductor LM83"
+	depends on HWMON && I2C
+	select I2C_SENSOR
+	help
+	  If you say yes here you get support for National Semiconductor
+	  LM83 sensor chips.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called lm83.
+
+config SENSORS_LM85
+	tristate "National Semiconductor LM85 and compatibles"
+	depends on HWMON && I2C && EXPERIMENTAL
+	select I2C_SENSOR
+	help
+	  If you say yes here you get support for National Semiconductor LM85
+	  sensor chips and clones: ADT7463, EMC6D100, EMC6D102 and ADM1027.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called lm85.
+
+config SENSORS_LM87
+	tristate "National Semiconductor LM87"
+	depends on HWMON && I2C && EXPERIMENTAL
+	select I2C_SENSOR
+	help
+	  If you say yes here you get support for National Semiconductor LM87
+	  sensor chips.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called lm87.
+
+config SENSORS_LM90
+	tristate "National Semiconductor LM90 and compatibles"
+	depends on HWMON && I2C
+	select I2C_SENSOR
+	help
+	  If you say yes here you get support for National Semiconductor LM90,
+	  LM86, LM89 and LM99, Analog Devices ADM1032 and Maxim MAX6657 and
+	  MAX6658 sensor chips.
+
+	  The Analog Devices ADT7461 sensor chip is also supported, but only
+	  if found in ADM1032 compatibility mode.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called lm90.
+
+config SENSORS_LM92
+	tristate "National Semiconductor LM92 and compatibles"
+	depends on HWMON && I2C && EXPERIMENTAL
+	select I2C_SENSOR
+	help
+	  If you say yes here you get support for National Semiconductor LM92
+	  and Maxim MAX6635 sensor chips.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called lm92.
+
+config SENSORS_MAX1619
+	tristate "Maxim MAX1619 sensor chip"
+	depends on HWMON && I2C && EXPERIMENTAL
+	select I2C_SENSOR
+	help
+	  If you say yes here you get support for MAX1619 sensor chip.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called max1619.
+
+config SENSORS_PC87360
+	tristate "National Semiconductor PC87360 family"
+	depends on HWMON && I2C && EXPERIMENTAL
+	select I2C_SENSOR
+	select I2C_ISA
+	help
+	  If you say yes here you get access to the hardware monitoring
+	  functions of the National Semiconductor PC8736x Super-I/O chips.
+	  The PC87360, PC87363 and PC87364 only have fan monitoring and
+	  control.  The PC87365 and PC87366 additionally have voltage and
+	  temperature monitoring.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called pc87360.
+
+config SENSORS_SIS5595
+	tristate "Silicon Integrated Systems Corp. SiS5595"
+	depends on HWMON && I2C && PCI && EXPERIMENTAL
+	select I2C_SENSOR
+	select I2C_ISA
+	help
+	  If you say yes here you get support for the integrated sensors in
+	  SiS5595 South Bridges.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called sis5595.
+
+config SENSORS_SMSC47M1
+	tristate "SMSC LPC47M10x and compatibles"
+	depends on HWMON && I2C && EXPERIMENTAL
+	select I2C_SENSOR
+	select I2C_ISA
+	help
+	  If you say yes here you get support for the integrated fan
+	  monitoring and control capabilities of the SMSC LPC47B27x,
+	  LPC47M10x, LPC47M13x, LPC47M14x, LPC47M15x and LPC47M192 chips.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called smsc47m1.
+
+config SENSORS_SMSC47B397
+	tristate "SMSC LPC47B397-NC"
+	depends on HWMON && I2C && EXPERIMENTAL
+	select I2C_SENSOR
+	select I2C_ISA
+	help
+	  If you say yes here you get support for the SMSC LPC47B397-NC
+	  sensor chip.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called smsc47b397.
+
+config SENSORS_VIA686A
+	tristate "VIA686A"
+	depends on HWMON && I2C && PCI
+	select I2C_SENSOR
+	select I2C_ISA
+	help
+	  If you say yes here you get support for the integrated sensors in
+	  Via 686A/B South Bridges.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called via686a.
+
+config SENSORS_W83781D
+	tristate "Winbond W83781D, W83782D, W83783S, W83627HF, Asus AS99127F"
+	depends on HWMON && I2C
+	select I2C_SENSOR
+	help
+	  If you say yes here you get support for the Winbond W8378x series
+	  of sensor chips: the W83781D, W83782D, W83783S and W83627HF,
+	  and the similar Asus AS99127F.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called w83781d.
+
+config SENSORS_W83L785TS
+	tristate "Winbond W83L785TS-S"
+	depends on HWMON && I2C && EXPERIMENTAL
+	select I2C_SENSOR
+	help
+	  If you say yes here you get support for the Winbond W83L785TS-S
+	  sensor chip, which is used on the Asus A7N8X, among other
+	  motherboards.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called w83l785ts.
+
+config SENSORS_W83627HF
+	tristate "Winbond W83627HF, W83627THF, W83637HF, W83697HF"
+	depends on HWMON && I2C && EXPERIMENTAL
+	select I2C_SENSOR
+	select I2C_ISA
+	help
+	  If you say yes here you get support for the Winbond W836X7 series
+	  of sensor chips: the W83627HF, W83627THF, W83637HF, and the W83697HF
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called w83627hf.
+
+config SENSORS_W83627EHF
+	tristate "Winbond W83627EHF"
+	depends on HWMON && I2C && EXPERIMENTAL
+	select I2C_SENSOR
+	select I2C_ISA
+	help
+	  If you say yes here you get preliminary support for the hardware
+	  monitoring functionality of the Winbond W83627EHF Super-I/O chip.
+	  Only fan and temperature inputs are supported at the moment, while
+	  the chip does much more than that.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called w83627ehf.
+
+config HWMON_DEBUG_CHIP
+	bool "Hardware Monitoring Chip debugging messages"
+	depends on HWMON
+	default n
+	help
+	  Say Y here if you want the I2C chip drivers to produce a bunch of
+	  debug messages to the system log.  Select this if you are having
+	  a problem with I2C support and want to see more of what is going
+	  on.
+
+endmenu
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
new file mode 100644
--- /dev/null
+++ b/drivers/hwmon/Makefile
@@ -0,0 +1,44 @@
+#
+# Makefile for sensor chip drivers.
+#
+
+# asb100, then w83781d go first, as they can override other drivers' addresses.
+obj-$(CONFIG_SENSORS_ASB100)	+= asb100.o
+obj-$(CONFIG_SENSORS_W83627HF)	+= w83627hf.o
+obj-$(CONFIG_SENSORS_W83781D)	+= w83781d.o
+
+obj-$(CONFIG_SENSORS_ADM1021)	+= adm1021.o
+obj-$(CONFIG_SENSORS_ADM1025)	+= adm1025.o
+obj-$(CONFIG_SENSORS_ADM1026)	+= adm1026.o
+obj-$(CONFIG_SENSORS_ADM1031)	+= adm1031.o
+obj-$(CONFIG_SENSORS_ADM9240)	+= adm9240.o
+obj-$(CONFIG_SENSORS_ATXP1)	+= atxp1.o
+obj-$(CONFIG_SENSORS_DS1621)	+= ds1621.o
+obj-$(CONFIG_SENSORS_FSCHER)	+= fscher.o
+obj-$(CONFIG_SENSORS_FSCPOS)	+= fscpos.o
+obj-$(CONFIG_SENSORS_GL518SM)	+= gl518sm.o
+obj-$(CONFIG_SENSORS_GL520SM)	+= gl520sm.o
+obj-$(CONFIG_SENSORS_IT87)	+= it87.o
+obj-$(CONFIG_SENSORS_LM63)	+= lm63.o
+obj-$(CONFIG_SENSORS_LM75)	+= lm75.o
+obj-$(CONFIG_SENSORS_LM77)	+= lm77.o
+obj-$(CONFIG_SENSORS_LM78)	+= lm78.o
+obj-$(CONFIG_SENSORS_LM80)	+= lm80.o
+obj-$(CONFIG_SENSORS_LM83)	+= lm83.o
+obj-$(CONFIG_SENSORS_LM85)	+= lm85.o
+obj-$(CONFIG_SENSORS_LM87)	+= lm87.o
+obj-$(CONFIG_SENSORS_LM90)	+= lm90.o
+obj-$(CONFIG_SENSORS_LM92)	+= lm92.o
+obj-$(CONFIG_SENSORS_MAX1619)	+= max1619.o
+obj-$(CONFIG_SENSORS_PC87360)	+= pc87360.o
+obj-$(CONFIG_SENSORS_SIS5595)	+= sis5595.o
+obj-$(CONFIG_SENSORS_SMSC47B397)+= smsc47b397.o
+obj-$(CONFIG_SENSORS_SMSC47M1)	+= smsc47m1.o
+obj-$(CONFIG_SENSORS_VIA686A)	+= via686a.o
+obj-$(CONFIG_SENSORS_W83627EHF)	+= w83627ehf.o
+obj-$(CONFIG_SENSORS_W83L785TS)	+= w83l785ts.o
+
+ifeq ($(CONFIG_HWMON_DEBUG_CHIP),y)
+EXTRA_CFLAGS += -DDEBUG
+endif
+
diff --git a/drivers/hwmon/adm1021.c b/drivers/hwmon/adm1021.c
new file mode 100644
--- /dev/null
+++ b/drivers/hwmon/adm1021.c
@@ -0,0 +1,402 @@
+/*
+    adm1021.c - Part of lm_sensors, Linux kernel modules for hardware
+             monitoring
+    Copyright (c) 1998, 1999  Frodo Looijaard <frodol@dds.nl> and
+    Philip Edelbrock <phil@netroedge.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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+#include <linux/i2c.h>
+#include <linux/i2c-sensor.h>
+
+
+/* Addresses to scan */
+static unsigned short normal_i2c[] = { 0x18, 0x19, 0x1a,
+					0x29, 0x2a, 0x2b,
+					0x4c, 0x4d, 0x4e, 
+					I2C_CLIENT_END };
+static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
+
+/* Insmod parameters */
+SENSORS_INSMOD_8(adm1021, adm1023, max1617, max1617a, thmc10, lm84, gl523sm, mc1066);
+
+/* adm1021 constants specified below */
+
+/* The adm1021 registers */
+/* Read-only */
+#define ADM1021_REG_TEMP		0x00
+#define ADM1021_REG_REMOTE_TEMP		0x01
+#define ADM1021_REG_STATUS		0x02
+#define ADM1021_REG_MAN_ID		0x0FE	/* 0x41 = AMD, 0x49 = TI, 0x4D = Maxim, 0x23 = Genesys , 0x54 = Onsemi*/
+#define ADM1021_REG_DEV_ID		0x0FF	/* ADM1021 = 0x0X, ADM1023 = 0x3X */
+#define ADM1021_REG_DIE_CODE		0x0FF	/* MAX1617A */
+/* These use different addresses for reading/writing */
+#define ADM1021_REG_CONFIG_R		0x03
+#define ADM1021_REG_CONFIG_W		0x09
+#define ADM1021_REG_CONV_RATE_R		0x04
+#define ADM1021_REG_CONV_RATE_W		0x0A
+/* These are for the ADM1023's additional precision on the remote temp sensor */
+#define ADM1021_REG_REM_TEMP_PREC	0x010
+#define ADM1021_REG_REM_OFFSET		0x011
+#define ADM1021_REG_REM_OFFSET_PREC	0x012
+#define ADM1021_REG_REM_TOS_PREC	0x013
+#define ADM1021_REG_REM_THYST_PREC	0x014
+/* limits */
+#define ADM1021_REG_TOS_R		0x05
+#define ADM1021_REG_TOS_W		0x0B
+#define ADM1021_REG_REMOTE_TOS_R	0x07
+#define ADM1021_REG_REMOTE_TOS_W	0x0D
+#define ADM1021_REG_THYST_R		0x06
+#define ADM1021_REG_THYST_W		0x0C
+#define ADM1021_REG_REMOTE_THYST_R	0x08
+#define ADM1021_REG_REMOTE_THYST_W	0x0E
+/* write-only */
+#define ADM1021_REG_ONESHOT		0x0F
+
+
+/* Conversions. Rounding and limit checking is only done on the TO_REG
+   variants. Note that you should be a bit careful with which arguments
+   these macros are called: arguments may be evaluated more than once.
+   Fixing this is just not worth it. */
+/* Conversions  note: 1021 uses normal integer signed-byte format*/
+#define TEMP_FROM_REG(val)	(val > 127 ? (val-256)*1000 : val*1000)
+#define TEMP_TO_REG(val)	(SENSORS_LIMIT((val < 0 ? (val/1000)+256 : val/1000),0,255))
+
+/* Initial values */
+
+/* Note: Even though I left the low and high limits named os and hyst, 
+they don't quite work like a thermostat the way the LM75 does.  I.e., 
+a lower temp than THYST actually triggers an alarm instead of 
+clearing it.  Weird, ey?   --Phil  */
+
+/* Each client has this additional data */
+struct adm1021_data {
+	struct i2c_client client;
+	enum chips type;
+
+	struct semaphore update_lock;
+	char valid;		/* !=0 if following fields are valid */
+	unsigned long last_updated;	/* In jiffies */
+
+	u8	temp_max;	/* Register values */
+	u8	temp_hyst;
+	u8	temp_input;
+	u8	remote_temp_max;
+	u8	remote_temp_hyst;
+	u8	remote_temp_input;
+	u8	alarms;
+        /* Special values for ADM1023 only */
+	u8	remote_temp_prec;
+	u8	remote_temp_os_prec;
+	u8	remote_temp_hyst_prec;
+	u8	remote_temp_offset;
+	u8	remote_temp_offset_prec;
+};
+
+static int adm1021_attach_adapter(struct i2c_adapter *adapter);
+static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind);
+static void adm1021_init_client(struct i2c_client *client);
+static int adm1021_detach_client(struct i2c_client *client);
+static int adm1021_read_value(struct i2c_client *client, u8 reg);
+static int adm1021_write_value(struct i2c_client *client, u8 reg,
+			       u16 value);
+static struct adm1021_data *adm1021_update_device(struct device *dev);
+
+/* (amalysh) read only mode, otherwise any limit's writing confuse BIOS */
+static int read_only = 0;
+
+
+/* This is the driver that will be inserted */
+static struct i2c_driver adm1021_driver = {
+	.owner		= THIS_MODULE,
+	.name		= "adm1021",
+	.id		= I2C_DRIVERID_ADM1021,
+	.flags		= I2C_DF_NOTIFY,
+	.attach_adapter	= adm1021_attach_adapter,
+	.detach_client	= adm1021_detach_client,
+};
+
+#define show(value)	\
+static ssize_t show_##value(struct device *dev, struct device_attribute *attr, char *buf)		\
+{									\
+	struct adm1021_data *data = adm1021_update_device(dev);		\
+	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->value));	\
+}
+show(temp_max);
+show(temp_hyst);
+show(temp_input);
+show(remote_temp_max);
+show(remote_temp_hyst);
+show(remote_temp_input);
+
+#define show2(value)	\
+static ssize_t show_##value(struct device *dev, struct device_attribute *attr, char *buf)		\
+{									\
+	struct adm1021_data *data = adm1021_update_device(dev);		\
+	return sprintf(buf, "%d\n", data->value);			\
+}
+show2(alarms);
+
+#define set(value, reg)	\
+static ssize_t set_##value(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)	\
+{								\
+	struct i2c_client *client = to_i2c_client(dev);		\
+	struct adm1021_data *data = i2c_get_clientdata(client);	\
+	int temp = simple_strtoul(buf, NULL, 10);		\
+								\
+	down(&data->update_lock);				\
+	data->value = TEMP_TO_REG(temp);			\
+	adm1021_write_value(client, reg, data->value);		\
+	up(&data->update_lock);					\
+	return count;						\
+}
+set(temp_max, ADM1021_REG_TOS_W);
+set(temp_hyst, ADM1021_REG_THYST_W);
+set(remote_temp_max, ADM1021_REG_REMOTE_TOS_W);
+set(remote_temp_hyst, ADM1021_REG_REMOTE_THYST_W);
+
+static DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp_max, set_temp_max);
+static DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, show_temp_hyst, set_temp_hyst);
+static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp_input, NULL);
+static DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_remote_temp_max, set_remote_temp_max);
+static DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_remote_temp_hyst, set_remote_temp_hyst);
+static DEVICE_ATTR(temp2_input, S_IRUGO, show_remote_temp_input, NULL);
+static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
+
+
+static int adm1021_attach_adapter(struct i2c_adapter *adapter)
+{
+	if (!(adapter->class & I2C_CLASS_HWMON))
+		return 0;
+	return i2c_detect(adapter, &addr_data, adm1021_detect);
+}
+
+static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind)
+{
+	int i;
+	struct i2c_client *new_client;
+	struct adm1021_data *data;
+	int err = 0;
+	const char *type_name = "";
+
+	/* Make sure we aren't probing the ISA bus!! This is just a safety check
+	   at this moment; i2c_detect really won't call us. */
+#ifdef DEBUG
+	if (i2c_is_isa_adapter(adapter)) {
+		dev_dbg(&adapter->dev, "adm1021_detect called for an ISA bus adapter?!?\n");
+		return 0;
+	}
+#endif
+
+	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+		goto error0;
+
+	/* OK. For now, we presume we have a valid client. We now create the
+	   client structure, even though we cannot fill it completely yet.
+	   But it allows us to access adm1021_{read,write}_value. */
+
+	if (!(data = kmalloc(sizeof(struct adm1021_data), GFP_KERNEL))) {
+		err = -ENOMEM;
+		goto error0;
+	}
+	memset(data, 0, sizeof(struct adm1021_data));
+
+	new_client = &data->client;
+	i2c_set_clientdata(new_client, data);
+	new_client->addr = address;
+	new_client->adapter = adapter;
+	new_client->driver = &adm1021_driver;
+	new_client->flags = 0;
+
+	/* Now, we do the remaining detection. */
+	if (kind < 0) {
+		if ((adm1021_read_value(new_client, ADM1021_REG_STATUS) & 0x03) != 0x00
+		 || (adm1021_read_value(new_client, ADM1021_REG_CONFIG_R) & 0x3F) != 0x00
+		 || (adm1021_read_value(new_client, ADM1021_REG_CONV_RATE_R) & 0xF8) != 0x00) {
+			err = -ENODEV;
+			goto error1;
+		}
+	}
+
+	/* Determine the chip type. */
+	if (kind <= 0) {
+		i = adm1021_read_value(new_client, ADM1021_REG_MAN_ID);
+		if (i == 0x41)
+			if ((adm1021_read_value(new_client, ADM1021_REG_DEV_ID) & 0x0F0) == 0x030)
+				kind = adm1023;
+			else
+				kind = adm1021;
+		else if (i == 0x49)
+			kind = thmc10;
+		else if (i == 0x23)
+			kind = gl523sm;
+		else if ((i == 0x4d) &&
+			 (adm1021_read_value(new_client, ADM1021_REG_DEV_ID) == 0x01))
+			kind = max1617a;
+		else if (i == 0x54)
+			kind = mc1066;
+		/* LM84 Mfr ID in a different place, and it has more unused bits */
+		else if (adm1021_read_value(new_client, ADM1021_REG_CONV_RATE_R) == 0x00
+		      && (kind == 0 /* skip extra detection */
+		       || ((adm1021_read_value(new_client, ADM1021_REG_CONFIG_R) & 0x7F) == 0x00
+			&& (adm1021_read_value(new_client, ADM1021_REG_STATUS) & 0xAB) == 0x00)))
+			kind = lm84;
+		else
+			kind = max1617;
+	}
+
+	if (kind == max1617) {
+		type_name = "max1617";
+	} else if (kind == max1617a) {
+		type_name = "max1617a";
+	} else if (kind == adm1021) {
+		type_name = "adm1021";
+	} else if (kind == adm1023) {
+		type_name = "adm1023";
+	} else if (kind == thmc10) {
+		type_name = "thmc10";
+	} else if (kind == lm84) {
+		type_name = "lm84";
+	} else if (kind == gl523sm) {
+		type_name = "gl523sm";
+	} else if (kind == mc1066) {
+		type_name = "mc1066";
+	}
+
+	/* Fill in the remaining client fields and put it into the global list */
+	strlcpy(new_client->name, type_name, I2C_NAME_SIZE);
+	data->type = kind;
+	data->valid = 0;
+	init_MUTEX(&data->update_lock);
+
+	/* Tell the I2C layer a new client has arrived */
+	if ((err = i2c_attach_client(new_client)))
+		goto error1;
+
+	/* Initialize the ADM1021 chip */
+	if (kind != lm84)
+		adm1021_init_client(new_client);
+
+	/* Register sysfs hooks */
+	device_create_file(&new_client->dev, &dev_attr_temp1_max);
+	device_create_file(&new_client->dev, &dev_attr_temp1_min);
+	device_create_file(&new_client->dev, &dev_attr_temp1_input);
+	device_create_file(&new_client->dev, &dev_attr_temp2_max);
+	device_create_file(&new_client->dev, &dev_attr_temp2_min);
+	device_create_file(&new_client->dev, &dev_attr_temp2_input);
+	device_create_file(&new_client->dev, &dev_attr_alarms);
+
+	return 0;
+
+error1:
+	kfree(data);
+error0:
+	return err;
+}
+
+static void adm1021_init_client(struct i2c_client *client)
+{
+	/* Enable ADC and disable suspend mode */
+	adm1021_write_value(client, ADM1021_REG_CONFIG_W,
+		adm1021_read_value(client, ADM1021_REG_CONFIG_R) & 0xBF);
+	/* Set Conversion rate to 1/sec (this can be tinkered with) */
+	adm1021_write_value(client, ADM1021_REG_CONV_RATE_W, 0x04);
+}
+
+static int adm1021_detach_client(struct i2c_client *client)
+{
+	int err;
+
+	if ((err = i2c_detach_client(client))) {
+		dev_err(&client->dev, "Client deregistration failed, client not detached.\n");
+		return err;
+	}
+
+	kfree(i2c_get_clientdata(client));
+	return 0;
+}
+
+/* All registers are byte-sized */
+static int adm1021_read_value(struct i2c_client *client, u8 reg)
+{
+	return i2c_smbus_read_byte_data(client, reg);
+}
+
+static int adm1021_write_value(struct i2c_client *client, u8 reg, u16 value)
+{
+	if (!read_only)
+		return i2c_smbus_write_byte_data(client, reg, value);
+	return 0;
+}
+
+static struct adm1021_data *adm1021_update_device(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct adm1021_data *data = i2c_get_clientdata(client);
+
+	down(&data->update_lock);
+
+	if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
+	    || !data->valid) {
+		dev_dbg(&client->dev, "Starting adm1021 update\n");
+
+		data->temp_input = adm1021_read_value(client, ADM1021_REG_TEMP);
+		data->temp_max = adm1021_read_value(client, ADM1021_REG_TOS_R);
+		data->temp_hyst = adm1021_read_value(client, ADM1021_REG_THYST_R);
+		data->remote_temp_input = adm1021_read_value(client, ADM1021_REG_REMOTE_TEMP);
+		data->remote_temp_max = adm1021_read_value(client, ADM1021_REG_REMOTE_TOS_R);
+		data->remote_temp_hyst = adm1021_read_value(client, ADM1021_REG_REMOTE_THYST_R);
+		data->alarms = adm1021_read_value(client, ADM1021_REG_STATUS) & 0x7c;
+		if (data->type == adm1023) {
+			data->remote_temp_prec = adm1021_read_value(client, ADM1021_REG_REM_TEMP_PREC);
+			data->remote_temp_os_prec = adm1021_read_value(client, ADM1021_REG_REM_TOS_PREC);
+			data->remote_temp_hyst_prec = adm1021_read_value(client, ADM1021_REG_REM_THYST_PREC);
+			data->remote_temp_offset = adm1021_read_value(client, ADM1021_REG_REM_OFFSET);
+			data->remote_temp_offset_prec = adm1021_read_value(client, ADM1021_REG_REM_OFFSET_PREC);
+		}
+		data->last_updated = jiffies;
+		data->valid = 1;
+	}
+
+	up(&data->update_lock);
+
+	return data;
+}
+
+static int __init sensors_adm1021_init(void)
+{
+	return i2c_add_driver(&adm1021_driver);
+}
+
+static void __exit sensors_adm1021_exit(void)
+{
+	i2c_del_driver(&adm1021_driver);
+}
+
+MODULE_AUTHOR ("Frodo Looijaard <frodol@dds.nl> and "
+		"Philip Edelbrock <phil@netroedge.com>");
+MODULE_DESCRIPTION("adm1021 driver");
+MODULE_LICENSE("GPL");
+
+module_param(read_only, bool, 0);
+MODULE_PARM_DESC(read_only, "Don't set any values, read only mode");
+
+module_init(sensors_adm1021_init)
+module_exit(sensors_adm1021_exit)
diff --git a/drivers/hwmon/adm1025.c b/drivers/hwmon/adm1025.c
new file mode 100644
--- /dev/null
+++ b/drivers/hwmon/adm1025.c
@@ -0,0 +1,577 @@
+/*
+ * adm1025.c
+ *
+ * Copyright (C) 2000       Chen-Yuan Wu <gwu@esoft.com>
+ * Copyright (C) 2003-2004  Jean Delvare <khali@linux-fr.org>
+ *
+ * The ADM1025 is a sensor chip made by Analog Devices. It reports up to 6
+ * voltages (including its own power source) and up to two temperatures
+ * (its own plus up to one external one). Voltages are scaled internally
+ * (which is not the common way) with ratios such that the nominal value
+ * of each voltage correspond to a register value of 192 (which means a
+ * resolution of about 0.5% of the nominal value). Temperature values are
+ * reported with a 1 deg resolution and a 3 deg accuracy. Complete
+ * datasheet can be obtained from Analog's website at:
+ *   http://www.analog.com/Analog_Root/productPage/productHome/0,2121,ADM1025,00.html
+ *
+ * This driver also supports the ADM1025A, which differs from the ADM1025
+ * only in that it has "open-drain VID inputs while the ADM1025 has
+ * on-chip 100k pull-ups on the VID inputs". It doesn't make any
+ * difference for us.
+ *
+ * This driver also supports the NE1619, a sensor chip made by Philips.
+ * That chip is similar to the ADM1025A, with a few differences. The only
+ * difference that matters to us is that the NE1619 has only two possible
+ * addresses while the ADM1025A has a third one. Complete datasheet can be
+ * obtained from Philips's website at:
+ *   http://www.semiconductors.philips.com/pip/NE1619DS.html
+ *
+ * Since the ADM1025 was the first chipset supported by this driver, most
+ * comments will refer to this chipset, but are actually general and
+ * concern all supported chipsets, unless mentioned otherwise.
+ *
+ * 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 <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+#include <linux/i2c.h>
+#include <linux/i2c-sensor.h>
+#include <linux/i2c-vid.h>
+
+/*
+ * Addresses to scan
+ * ADM1025 and ADM1025A have three possible addresses: 0x2c, 0x2d and 0x2e.
+ * NE1619 has two possible addresses: 0x2c and 0x2d.
+ */
+
+static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END };
+static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
+
+/*
+ * Insmod parameters
+ */
+
+SENSORS_INSMOD_2(adm1025, ne1619);
+
+/*
+ * The ADM1025 registers
+ */
+
+#define ADM1025_REG_MAN_ID		0x3E
+#define ADM1025_REG_CHIP_ID 		0x3F
+#define ADM1025_REG_CONFIG		0x40
+#define ADM1025_REG_STATUS1		0x41
+#define ADM1025_REG_STATUS2		0x42
+#define ADM1025_REG_IN(nr)		(0x20 + (nr))
+#define ADM1025_REG_IN_MAX(nr)		(0x2B + (nr) * 2)
+#define ADM1025_REG_IN_MIN(nr)		(0x2C + (nr) * 2)
+#define ADM1025_REG_TEMP(nr)		(0x26 + (nr))
+#define ADM1025_REG_TEMP_HIGH(nr)	(0x37 + (nr) * 2)
+#define ADM1025_REG_TEMP_LOW(nr)	(0x38 + (nr) * 2)
+#define ADM1025_REG_VID			0x47
+#define ADM1025_REG_VID4		0x49
+
+/*
+ * Conversions and various macros
+ * The ADM1025 uses signed 8-bit values for temperatures.
+ */
+
+static int in_scale[6] = { 2500, 2250, 3300, 5000, 12000, 3300 };
+
+#define IN_FROM_REG(reg,scale)	(((reg) * (scale) + 96) / 192)
+#define IN_TO_REG(val,scale)	((val) <= 0 ? 0 : \
+				 (val) * 192 >= (scale) * 255 ? 255 : \
+				 ((val) * 192 + (scale)/2) / (scale))
+
+#define TEMP_FROM_REG(reg)	((reg) * 1000)
+#define TEMP_TO_REG(val)	((val) <= -127500 ? -128 : \
+				 (val) >= 126500 ? 127 : \
+				 (((val) < 0 ? (val)-500 : (val)+500) / 1000))
+
+/*
+ * Functions declaration
+ */
+
+static int adm1025_attach_adapter(struct i2c_adapter *adapter);
+static int adm1025_detect(struct i2c_adapter *adapter, int address, int kind);
+static void adm1025_init_client(struct i2c_client *client);
+static int adm1025_detach_client(struct i2c_client *client);
+static struct adm1025_data *adm1025_update_device(struct device *dev);
+
+/*
+ * Driver data (common to all clients)
+ */
+
+static struct i2c_driver adm1025_driver = {
+	.owner		= THIS_MODULE,
+	.name		= "adm1025",
+	.id		= I2C_DRIVERID_ADM1025,
+	.flags		= I2C_DF_NOTIFY,
+	.attach_adapter	= adm1025_attach_adapter,
+	.detach_client	= adm1025_detach_client,
+};
+
+/*
+ * Client data (each client gets its own)
+ */
+
+struct adm1025_data {
+	struct i2c_client client;
+	struct semaphore update_lock;
+	char valid; /* zero until following fields are valid */
+	unsigned long last_updated; /* in jiffies */
+
+	u8 in[6];		/* register value */
+	u8 in_max[6];		/* register value */
+	u8 in_min[6];		/* register value */
+	s8 temp[2];		/* register value */
+	s8 temp_min[2];		/* register value */
+	s8 temp_max[2];		/* register value */
+	u16 alarms;		/* register values, combined */
+	u8 vid;			/* register values, combined */
+	u8 vrm;
+};
+
+/*
+ * Sysfs stuff
+ */
+
+#define show_in(offset) \
+static ssize_t show_in##offset(struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+	struct adm1025_data *data = adm1025_update_device(dev); \
+	return sprintf(buf, "%u\n", IN_FROM_REG(data->in[offset], \
+		       in_scale[offset])); \
+} \
+static ssize_t show_in##offset##_min(struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+	struct adm1025_data *data = adm1025_update_device(dev); \
+	return sprintf(buf, "%u\n", IN_FROM_REG(data->in_min[offset], \
+		       in_scale[offset])); \
+} \
+static ssize_t show_in##offset##_max(struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+	struct adm1025_data *data = adm1025_update_device(dev); \
+	return sprintf(buf, "%u\n", IN_FROM_REG(data->in_max[offset], \
+		       in_scale[offset])); \
+} \
+static DEVICE_ATTR(in##offset##_input, S_IRUGO, show_in##offset, NULL);
+show_in(0);
+show_in(1);
+show_in(2);
+show_in(3);
+show_in(4);
+show_in(5);
+
+#define show_temp(offset) \
+static ssize_t show_temp##offset(struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+	struct adm1025_data *data = adm1025_update_device(dev); \
+	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp[offset-1])); \
+} \
+static ssize_t show_temp##offset##_min(struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+	struct adm1025_data *data = adm1025_update_device(dev); \
+	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_min[offset-1])); \
+} \
+static ssize_t show_temp##offset##_max(struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+	struct adm1025_data *data = adm1025_update_device(dev); \
+	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_max[offset-1])); \
+}\
+static DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_temp##offset, NULL);
+show_temp(1);
+show_temp(2);
+
+#define set_in(offset) \
+static ssize_t set_in##offset##_min(struct device *dev, struct device_attribute *attr, const char *buf, \
+	size_t count) \
+{ \
+	struct i2c_client *client = to_i2c_client(dev); \
+	struct adm1025_data *data = i2c_get_clientdata(client); \
+	long val = simple_strtol(buf, NULL, 10); \
+ \
+	down(&data->update_lock); \
+	data->in_min[offset] = IN_TO_REG(val, in_scale[offset]); \
+	i2c_smbus_write_byte_data(client, ADM1025_REG_IN_MIN(offset), \
+				  data->in_min[offset]); \
+	up(&data->update_lock); \
+	return count; \
+} \
+static ssize_t set_in##offset##_max(struct device *dev, struct device_attribute *attr, const char *buf, \
+	size_t count) \
+{ \
+	struct i2c_client *client = to_i2c_client(dev); \
+	struct adm1025_data *data = i2c_get_clientdata(client); \
+	long val = simple_strtol(buf, NULL, 10); \
+ \
+	down(&data->update_lock); \
+	data->in_max[offset] = IN_TO_REG(val, in_scale[offset]); \
+	i2c_smbus_write_byte_data(client, ADM1025_REG_IN_MAX(offset), \
+				  data->in_max[offset]); \
+	up(&data->update_lock); \
+	return count; \
+} \
+static DEVICE_ATTR(in##offset##_min, S_IWUSR | S_IRUGO, \
+	show_in##offset##_min, set_in##offset##_min); \
+static DEVICE_ATTR(in##offset##_max, S_IWUSR | S_IRUGO, \
+	show_in##offset##_max, set_in##offset##_max);
+set_in(0);
+set_in(1);
+set_in(2);
+set_in(3);
+set_in(4);
+set_in(5);
+
+#define set_temp(offset) \
+static ssize_t set_temp##offset##_min(struct device *dev, struct device_attribute *attr, const char *buf, \
+	size_t count) \
+{ \
+	struct i2c_client *client = to_i2c_client(dev); \
+	struct adm1025_data *data = i2c_get_clientdata(client); \
+	long val = simple_strtol(buf, NULL, 10); \
+ \
+	down(&data->update_lock); \
+	data->temp_min[offset-1] = TEMP_TO_REG(val); \
+	i2c_smbus_write_byte_data(client, ADM1025_REG_TEMP_LOW(offset-1), \
+				  data->temp_min[offset-1]); \
+	up(&data->update_lock); \
+	return count; \
+} \
+static ssize_t set_temp##offset##_max(struct device *dev, struct device_attribute *attr, const char *buf, \
+	size_t count) \
+{ \
+	struct i2c_client *client = to_i2c_client(dev); \
+	struct adm1025_data *data = i2c_get_clientdata(client); \
+	long val = simple_strtol(buf, NULL, 10); \
+ \
+	down(&data->update_lock); \
+	data->temp_max[offset-1] = TEMP_TO_REG(val); \
+	i2c_smbus_write_byte_data(client, ADM1025_REG_TEMP_HIGH(offset-1), \
+				  data->temp_max[offset-1]); \
+	up(&data->update_lock); \
+	return count; \
+} \
+static DEVICE_ATTR(temp##offset##_min, S_IWUSR | S_IRUGO, \
+	show_temp##offset##_min, set_temp##offset##_min); \
+static DEVICE_ATTR(temp##offset##_max, S_IWUSR | S_IRUGO, \
+	show_temp##offset##_max, set_temp##offset##_max);
+set_temp(1);
+set_temp(2);
+
+static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct adm1025_data *data = adm1025_update_device(dev);
+	return sprintf(buf, "%u\n", data->alarms);
+}
+static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
+
+static ssize_t show_vid(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct adm1025_data *data = adm1025_update_device(dev);
+	return sprintf(buf, "%u\n", vid_from_reg(data->vid, data->vrm));
+}
+/* in1_ref is deprecated in favour of cpu0_vid, remove after 2005-11-11 */
+static DEVICE_ATTR(in1_ref, S_IRUGO, show_vid, NULL);
+static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL);
+
+static ssize_t show_vrm(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct adm1025_data *data = adm1025_update_device(dev);
+	return sprintf(buf, "%u\n", data->vrm);
+}
+static ssize_t set_vrm(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct adm1025_data *data = i2c_get_clientdata(client);
+	data->vrm = simple_strtoul(buf, NULL, 10);
+	return count;
+}
+static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm, set_vrm);
+
+/*
+ * Real code
+ */
+
+static int adm1025_attach_adapter(struct i2c_adapter *adapter)
+{
+	if (!(adapter->class & I2C_CLASS_HWMON))
+		return 0;
+	return i2c_detect(adapter, &addr_data, adm1025_detect);
+}
+
+/*
+ * The following function does more than just detection. If detection
+ * succeeds, it also registers the new chip.
+ */
+static int adm1025_detect(struct i2c_adapter *adapter, int address, int kind)
+{
+	struct i2c_client *new_client;
+	struct adm1025_data *data;
+	int err = 0;
+	const char *name = "";
+	u8 config;
+
+	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+		goto exit;
+
+	if (!(data = kmalloc(sizeof(struct adm1025_data), GFP_KERNEL))) {
+		err = -ENOMEM;
+		goto exit;
+	}
+	memset(data, 0, sizeof(struct adm1025_data));
+
+	/* The common I2C client data is placed right before the
+	   ADM1025-specific data. */
+	new_client = &data->client;
+	i2c_set_clientdata(new_client, data);
+	new_client->addr = address;
+	new_client->adapter = adapter;
+	new_client->driver = &adm1025_driver;
+	new_client->flags = 0;
+
+	/*
+	 * Now we do the remaining detection. A negative kind means that
+	 * the driver was loaded with no force parameter (default), so we
+	 * must both detect and identify the chip. A zero kind means that
+	 * the driver was loaded with the force parameter, the detection
+	 * step shall be skipped. A positive kind means that the driver
+	 * was loaded with the force parameter and a given kind of chip is
+	 * requested, so both the detection and the identification steps
+	 * are skipped.
+	 */
+	config = i2c_smbus_read_byte_data(new_client, ADM1025_REG_CONFIG);
+	if (kind < 0) { /* detection */
+		if ((config & 0x80) != 0x00
+		 || (i2c_smbus_read_byte_data(new_client,
+		     ADM1025_REG_STATUS1) & 0xC0) != 0x00
+		 || (i2c_smbus_read_byte_data(new_client,
+		     ADM1025_REG_STATUS2) & 0xBC) != 0x00) {
+			dev_dbg(&adapter->dev,
+				"ADM1025 detection failed at 0x%02x.\n",
+				address);
+			goto exit_free;
+		}
+	}
+
+	if (kind <= 0) { /* identification */
+		u8 man_id, chip_id;
+
+		man_id = i2c_smbus_read_byte_data(new_client,
+			 ADM1025_REG_MAN_ID);
+		chip_id = i2c_smbus_read_byte_data(new_client,
+			  ADM1025_REG_CHIP_ID);
+		
+		if (man_id == 0x41) { /* Analog Devices */
+			if ((chip_id & 0xF0) == 0x20) { /* ADM1025/ADM1025A */
+				kind = adm1025;
+			}
+		} else
+		if (man_id == 0xA1) { /* Philips */
+			if (address != 0x2E
+			 && (chip_id & 0xF0) == 0x20) { /* NE1619 */
+				kind = ne1619;
+			}
+		}
+
+		if (kind <= 0) { /* identification failed */
+			dev_info(&adapter->dev,
+			    "Unsupported chip (man_id=0x%02X, "
+			    "chip_id=0x%02X).\n", man_id, chip_id);
+			goto exit_free;
+		}
+	}
+
+	if (kind == adm1025) {
+		name = "adm1025";
+	} else if (kind == ne1619) {
+		name = "ne1619";
+	}
+
+	/* We can fill in the remaining client fields */
+	strlcpy(new_client->name, name, I2C_NAME_SIZE);
+	data->valid = 0;
+	init_MUTEX(&data->update_lock);
+
+	/* Tell the I2C layer a new client has arrived */
+	if ((err = i2c_attach_client(new_client)))
+		goto exit_free;
+
+	/* Initialize the ADM1025 chip */
+	adm1025_init_client(new_client);
+
+	/* Register sysfs hooks */
+	device_create_file(&new_client->dev, &dev_attr_in0_input);
+	device_create_file(&new_client->dev, &dev_attr_in1_input);
+	device_create_file(&new_client->dev, &dev_attr_in2_input);
+	device_create_file(&new_client->dev, &dev_attr_in3_input);
+	device_create_file(&new_client->dev, &dev_attr_in5_input);
+	device_create_file(&new_client->dev, &dev_attr_in0_min);
+	device_create_file(&new_client->dev, &dev_attr_in1_min);
+	device_create_file(&new_client->dev, &dev_attr_in2_min);
+	device_create_file(&new_client->dev, &dev_attr_in3_min);
+	device_create_file(&new_client->dev, &dev_attr_in5_min);
+	device_create_file(&new_client->dev, &dev_attr_in0_max);
+	device_create_file(&new_client->dev, &dev_attr_in1_max);
+	device_create_file(&new_client->dev, &dev_attr_in2_max);
+	device_create_file(&new_client->dev, &dev_attr_in3_max);
+	device_create_file(&new_client->dev, &dev_attr_in5_max);
+	device_create_file(&new_client->dev, &dev_attr_temp1_input);
+	device_create_file(&new_client->dev, &dev_attr_temp2_input);
+	device_create_file(&new_client->dev, &dev_attr_temp1_min);
+	device_create_file(&new_client->dev, &dev_attr_temp2_min);
+	device_create_file(&new_client->dev, &dev_attr_temp1_max);
+	device_create_file(&new_client->dev, &dev_attr_temp2_max);
+	device_create_file(&new_client->dev, &dev_attr_alarms);
+	/* in1_ref is deprecated, remove after 2005-11-11 */
+	device_create_file(&new_client->dev, &dev_attr_in1_ref);
+	device_create_file(&new_client->dev, &dev_attr_cpu0_vid);
+	device_create_file(&new_client->dev, &dev_attr_vrm);
+
+	/* Pin 11 is either in4 (+12V) or VID4 */
+	if (!(config & 0x20)) {
+		device_create_file(&new_client->dev, &dev_attr_in4_input);
+		device_create_file(&new_client->dev, &dev_attr_in4_min);
+		device_create_file(&new_client->dev, &dev_attr_in4_max);
+	}
+
+	return 0;
+
+exit_free:
+	kfree(data);
+exit:
+	return err;
+}
+
+static void adm1025_init_client(struct i2c_client *client)
+{
+	u8 reg;
+	struct adm1025_data *data = i2c_get_clientdata(client);
+	int i;
+
+	data->vrm = i2c_which_vrm();
+
+	/*
+	 * Set high limits
+	 * Usually we avoid setting limits on driver init, but it happens
+	 * that the ADM1025 comes with stupid default limits (all registers
+	 * set to 0). In case the chip has not gone through any limit
+	 * setting yet, we better set the high limits to the max so that
+	 * no alarm triggers.
+	 */
+	for (i=0; i<6; i++) {
+		reg = i2c_smbus_read_byte_data(client,
+					       ADM1025_REG_IN_MAX(i));
+		if (reg == 0)
+			i2c_smbus_write_byte_data(client,
+						  ADM1025_REG_IN_MAX(i),
+						  0xFF);
+	}
+	for (i=0; i<2; i++) {
+		reg = i2c_smbus_read_byte_data(client,
+					       ADM1025_REG_TEMP_HIGH(i));
+		if (reg == 0)
+			i2c_smbus_write_byte_data(client,
+						  ADM1025_REG_TEMP_HIGH(i),
+						  0x7F);
+	}
+
+	/*
+	 * Start the conversions
+	 */
+	reg = i2c_smbus_read_byte_data(client, ADM1025_REG_CONFIG);
+	if (!(reg & 0x01))
+		i2c_smbus_write_byte_data(client, ADM1025_REG_CONFIG,
+					  (reg&0x7E)|0x01);
+}
+
+static int adm1025_detach_client(struct i2c_client *client)
+{
+	int err;
+
+	if ((err = i2c_detach_client(client))) {
+		dev_err(&client->dev, "Client deregistration failed, "
+			"client not detached.\n");
+		return err;
+	}
+
+	kfree(i2c_get_clientdata(client));
+	return 0;
+}
+
+static struct adm1025_data *adm1025_update_device(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct adm1025_data *data = i2c_get_clientdata(client);
+
+	down(&data->update_lock);
+
+	if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) {
+		int i;
+
+		dev_dbg(&client->dev, "Updating data.\n");
+		for (i=0; i<6; i++) {
+			data->in[i] = i2c_smbus_read_byte_data(client,
+				      ADM1025_REG_IN(i));
+			data->in_min[i] = i2c_smbus_read_byte_data(client,
+					  ADM1025_REG_IN_MIN(i));
+			data->in_max[i] = i2c_smbus_read_byte_data(client,
+					  ADM1025_REG_IN_MAX(i));
+		}
+		for (i=0; i<2; i++) {
+			data->temp[i] = i2c_smbus_read_byte_data(client,
+					ADM1025_REG_TEMP(i));
+			data->temp_min[i] = i2c_smbus_read_byte_data(client,
+					    ADM1025_REG_TEMP_LOW(i));
+			data->temp_max[i] = i2c_smbus_read_byte_data(client,
+					    ADM1025_REG_TEMP_HIGH(i));
+		}
+		data->alarms = i2c_smbus_read_byte_data(client,
+			       ADM1025_REG_STATUS1)
+			     | (i2c_smbus_read_byte_data(client,
+				ADM1025_REG_STATUS2) << 8);
+		data->vid = (i2c_smbus_read_byte_data(client,
+			     ADM1025_REG_VID) & 0x0f)
+			  | ((i2c_smbus_read_byte_data(client,
+			      ADM1025_REG_VID4) & 0x01) << 4);
+
+		data->last_updated = jiffies;
+		data->valid = 1;
+	}
+
+	up(&data->update_lock);
+
+	return data;
+}
+
+static int __init sensors_adm1025_init(void)
+{
+	return i2c_add_driver(&adm1025_driver);
+}
+
+static void __exit sensors_adm1025_exit(void)
+{
+	i2c_del_driver(&adm1025_driver);
+}
+
+MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>");
+MODULE_DESCRIPTION("ADM1025 driver");
+MODULE_LICENSE("GPL");
+
+module_init(sensors_adm1025_init);
+module_exit(sensors_adm1025_exit);
diff --git a/drivers/hwmon/adm1026.c b/drivers/hwmon/adm1026.c
new file mode 100644
--- /dev/null
+++ b/drivers/hwmon/adm1026.c
@@ -0,0 +1,1714 @@
+/*
+    adm1026.c - Part of lm_sensors, Linux kernel modules for hardware
+	     monitoring
+    Copyright (C) 2002, 2003  Philip Pokorny <ppokorny@penguincomputing.com>
+    Copyright (C) 2004 Justin Thiessen <jthiessen@penguincomputing.com>
+
+    Chip details at:
+
+    <http://www.analog.com/UploadedFiles/Data_Sheets/779263102ADM1026_a.pdf>
+
+    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 <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+#include <linux/i2c.h>
+#include <linux/i2c-sensor.h>
+#include <linux/i2c-vid.h>
+#include <linux/hwmon-sysfs.h>
+
+/* Addresses to scan */
+static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END };
+static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
+
+/* Insmod parameters */
+SENSORS_INSMOD_1(adm1026);
+
+static int gpio_input[17]  = { -1, -1, -1, -1, -1, -1, -1, -1, -1,
+				-1, -1, -1, -1, -1, -1, -1, -1 }; 
+static int gpio_output[17] = { -1, -1, -1, -1, -1, -1, -1, -1, -1,
+				-1, -1, -1, -1, -1, -1, -1, -1 };
+static int gpio_inverted[17] = { -1, -1, -1, -1, -1, -1, -1, -1, -1,
+				-1, -1, -1, -1, -1, -1, -1, -1 };
+static int gpio_normal[17] = { -1, -1, -1, -1, -1, -1, -1, -1, -1,
+				-1, -1, -1, -1, -1, -1, -1, -1 };
+static int gpio_fan[8] = { -1, -1, -1, -1, -1, -1, -1, -1 };
+module_param_array(gpio_input,int,NULL,0);
+MODULE_PARM_DESC(gpio_input,"List of GPIO pins (0-16) to program as inputs");
+module_param_array(gpio_output,int,NULL,0);
+MODULE_PARM_DESC(gpio_output,"List of GPIO pins (0-16) to program as "
+	"outputs");
+module_param_array(gpio_inverted,int,NULL,0);
+MODULE_PARM_DESC(gpio_inverted,"List of GPIO pins (0-16) to program as "
+	"inverted");
+module_param_array(gpio_normal,int,NULL,0);
+MODULE_PARM_DESC(gpio_normal,"List of GPIO pins (0-16) to program as "
+	"normal/non-inverted");
+module_param_array(gpio_fan,int,NULL,0);
+MODULE_PARM_DESC(gpio_fan,"List of GPIO pins (0-7) to program as fan tachs");
+
+/* Many ADM1026 constants specified below */
+
+/* The ADM1026 registers */
+#define ADM1026_REG_CONFIG1  0x00
+#define CFG1_MONITOR     0x01
+#define CFG1_INT_ENABLE  0x02
+#define CFG1_INT_CLEAR   0x04
+#define CFG1_AIN8_9      0x08
+#define CFG1_THERM_HOT   0x10
+#define CFG1_DAC_AFC     0x20
+#define CFG1_PWM_AFC     0x40
+#define CFG1_RESET       0x80
+#define ADM1026_REG_CONFIG2  0x01
+/* CONFIG2 controls FAN0/GPIO0 through FAN7/GPIO7 */
+#define ADM1026_REG_CONFIG3  0x07
+#define CFG3_GPIO16_ENABLE  0x01
+#define CFG3_CI_CLEAR  0x02
+#define CFG3_VREF_250  0x04
+#define CFG3_GPIO16_DIR  0x40
+#define CFG3_GPIO16_POL  0x80
+#define ADM1026_REG_E2CONFIG  0x13
+#define E2CFG_READ  0x01
+#define E2CFG_WRITE  0x02
+#define E2CFG_ERASE  0x04
+#define E2CFG_ROM  0x08
+#define E2CFG_CLK_EXT  0x80
+
+/* There are 10 general analog inputs and 7 dedicated inputs
+ * They are:
+ *    0 - 9  =  AIN0 - AIN9
+ *       10  =  Vbat
+ *       11  =  3.3V Standby
+ *       12  =  3.3V Main
+ *       13  =  +5V
+ *       14  =  Vccp (CPU core voltage)
+ *       15  =  +12V
+ *       16  =  -12V
+ */
+static u16 ADM1026_REG_IN[] = {
+		0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
+		0x36, 0x37, 0x27, 0x29, 0x26, 0x2a,
+		0x2b, 0x2c, 0x2d, 0x2e, 0x2f
+	};
+static u16 ADM1026_REG_IN_MIN[] = {
+		0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d,
+		0x5e, 0x5f, 0x6d, 0x49, 0x6b, 0x4a,
+		0x4b, 0x4c, 0x4d, 0x4e, 0x4f
+	};
+static u16 ADM1026_REG_IN_MAX[] = {
+		0x50, 0x51, 0x52, 0x53, 0x54, 0x55,
+		0x56, 0x57, 0x6c, 0x41, 0x6a, 0x42,
+		0x43, 0x44, 0x45, 0x46, 0x47
+	};
+
+/* Temperatures are:
+ *    0 - Internal
+ *    1 - External 1
+ *    2 - External 2
+ */
+static u16 ADM1026_REG_TEMP[] = { 0x1f, 0x28, 0x29 };
+static u16 ADM1026_REG_TEMP_MIN[] = { 0x69, 0x48, 0x49 };
+static u16 ADM1026_REG_TEMP_MAX[] = { 0x68, 0x40, 0x41 };
+static u16 ADM1026_REG_TEMP_TMIN[] = { 0x10, 0x11, 0x12 };
+static u16 ADM1026_REG_TEMP_THERM[] = { 0x0d, 0x0e, 0x0f };
+static u16 ADM1026_REG_TEMP_OFFSET[] = { 0x1e, 0x6e, 0x6f };
+
+#define ADM1026_REG_FAN(nr) (0x38 + (nr))
+#define ADM1026_REG_FAN_MIN(nr) (0x60 + (nr))
+#define ADM1026_REG_FAN_DIV_0_3 0x02
+#define ADM1026_REG_FAN_DIV_4_7 0x03
+
+#define ADM1026_REG_DAC  0x04
+#define ADM1026_REG_PWM  0x05
+
+#define ADM1026_REG_GPIO_CFG_0_3 0x08
+#define ADM1026_REG_GPIO_CFG_4_7 0x09
+#define ADM1026_REG_GPIO_CFG_8_11 0x0a
+#define ADM1026_REG_GPIO_CFG_12_15 0x0b
+/* CFG_16 in REG_CFG3 */
+#define ADM1026_REG_GPIO_STATUS_0_7 0x24
+#define ADM1026_REG_GPIO_STATUS_8_15 0x25
+/* STATUS_16 in REG_STATUS4 */
+#define ADM1026_REG_GPIO_MASK_0_7 0x1c
+#define ADM1026_REG_GPIO_MASK_8_15 0x1d
+/* MASK_16 in REG_MASK4 */
+
+#define ADM1026_REG_COMPANY 0x16
+#define ADM1026_REG_VERSTEP 0x17
+/* These are the recognized values for the above regs */
+#define ADM1026_COMPANY_ANALOG_DEV 0x41
+#define ADM1026_VERSTEP_GENERIC 0x40
+#define ADM1026_VERSTEP_ADM1026 0x44
+
+#define ADM1026_REG_MASK1 0x18
+#define ADM1026_REG_MASK2 0x19
+#define ADM1026_REG_MASK3 0x1a
+#define ADM1026_REG_MASK4 0x1b
+
+#define ADM1026_REG_STATUS1 0x20
+#define ADM1026_REG_STATUS2 0x21
+#define ADM1026_REG_STATUS3 0x22
+#define ADM1026_REG_STATUS4 0x23
+
+#define ADM1026_FAN_ACTIVATION_TEMP_HYST -6
+#define ADM1026_FAN_CONTROL_TEMP_RANGE 20
+#define ADM1026_PWM_MAX 255
+
+/* Conversions. Rounding and limit checking is only done on the TO_REG 
+ * variants. Note that you should be a bit careful with which arguments
+ * these macros are called: arguments may be evaluated more than once.
+ */
+
+/* IN are scaled acording to built-in resistors.  These are the
+ *   voltages corresponding to 3/4 of full scale (192 or 0xc0)
+ *   NOTE: The -12V input needs an additional factor to account
+ *      for the Vref pullup resistor.
+ *      NEG12_OFFSET = SCALE * Vref / V-192 - Vref
+ *                   = 13875 * 2.50 / 1.875 - 2500
+ *                   = 16000
+ *
+ * The values in this table are based on Table II, page 15 of the
+ *    datasheet.
+ */
+static int adm1026_scaling[] = {  /* .001 Volts */
+		2250, 2250, 2250, 2250, 2250, 2250, 
+		1875, 1875, 1875, 1875, 3000, 3330, 
+		3330, 4995, 2250, 12000, 13875
+	};
+#define NEG12_OFFSET  16000
+#define SCALE(val,from,to) (((val)*(to) + ((from)/2))/(from))
+#define INS_TO_REG(n,val)  (SENSORS_LIMIT(SCALE(val,adm1026_scaling[n],192),\
+	0,255))
+#define INS_FROM_REG(n,val) (SCALE(val,192,adm1026_scaling[n]))
+
+/* FAN speed is measured using 22.5kHz clock and counts for 2 pulses
+ *   and we assume a 2 pulse-per-rev fan tach signal
+ *      22500 kHz * 60 (sec/min) * 2 (pulse) / 2 (pulse/rev) == 1350000
+ */
+#define FAN_TO_REG(val,div)  ((val)<=0 ? 0xff : SENSORS_LIMIT(1350000/((val)*\
+	(div)),1,254)) 
+#define FAN_FROM_REG(val,div) ((val)==0?-1:(val)==0xff ? 0 : 1350000/((val)*\
+	(div)))
+#define DIV_FROM_REG(val) (1<<(val))
+#define DIV_TO_REG(val) ((val)>=8 ? 3 : (val)>=4 ? 2 : (val)>=2 ? 1 : 0)
+
+/* Temperature is reported in 1 degC increments */
+#define TEMP_TO_REG(val) (SENSORS_LIMIT(((val)+((val)<0 ? -500 : 500))/1000,\
+	-127,127))
+#define TEMP_FROM_REG(val) ((val) * 1000)
+#define OFFSET_TO_REG(val) (SENSORS_LIMIT(((val)+((val)<0 ? -500 : 500))/1000,\
+	-127,127))
+#define OFFSET_FROM_REG(val) ((val) * 1000)
+
+#define PWM_TO_REG(val) (SENSORS_LIMIT(val,0,255))
+#define PWM_FROM_REG(val) (val)
+
+#define PWM_MIN_TO_REG(val) ((val) & 0xf0)
+#define PWM_MIN_FROM_REG(val) (((val) & 0xf0) + ((val) >> 4))
+
+/* Analog output is a voltage, and scaled to millivolts.  The datasheet 
+ *   indicates that the DAC could be used to drive the fans, but in our 
+ *   example board (Arima HDAMA) it isn't connected to the fans at all.
+ */
+#define DAC_TO_REG(val) (SENSORS_LIMIT(((((val)*255)+500)/2500),0,255)) 
+#define DAC_FROM_REG(val) (((val)*2500)/255)
+
+/* Typically used with systems using a v9.1 VRM spec ? */
+#define ADM1026_INIT_VRM  91
+
+/* Chip sampling rates
+ *
+ * Some sensors are not updated more frequently than once per second
+ *    so it doesn't make sense to read them more often than that.
+ *    We cache the results and return the saved data if the driver
+ *    is called again before a second has elapsed.
+ *
+ * Also, there is significant configuration data for this chip
+ *    So, we keep the config data up to date in the cache
+ *    when it is written and only sample it once every 5 *minutes*
+ */
+#define ADM1026_DATA_INTERVAL  (1 * HZ)
+#define ADM1026_CONFIG_INTERVAL  (5 * 60 * HZ)
+
+/* We allow for multiple chips in a single system.
+ *
+ * For each registered ADM1026, we need to keep state information
+ * at client->data. The adm1026_data structure is dynamically
+ * allocated, when a new client structure is allocated. */
+
+struct pwm_data {
+	u8 pwm;
+	u8 enable;
+	u8 auto_pwm_min;
+};
+
+struct adm1026_data {
+	struct i2c_client client;
+	struct semaphore lock;
+	enum chips type;
+
+	struct semaphore update_lock;
+	int valid;		/* !=0 if following fields are valid */
+	unsigned long last_reading;	/* In jiffies */
+	unsigned long last_config;	/* In jiffies */
+
+	u8 in[17];              /* Register value */
+	u8 in_max[17];          /* Register value */
+	u8 in_min[17];          /* Register value */
+	s8 temp[3];             /* Register value */
+	s8 temp_min[3];         /* Register value */
+	s8 temp_max[3];         /* Register value */
+	s8 temp_tmin[3];        /* Register value */
+	s8 temp_crit[3];        /* Register value */
+	s8 temp_offset[3];      /* Register value */
+	u8 fan[8];              /* Register value */
+	u8 fan_min[8];          /* Register value */
+	u8 fan_div[8];          /* Decoded value */
+	struct pwm_data pwm1;   /* Pwm control values */
+	int vid;                /* Decoded value */
+	u8 vrm;                 /* VRM version */
+	u8 analog_out;		/* Register value (DAC) */
+	long alarms;            /* Register encoding, combined */
+	long alarm_mask;        /* Register encoding, combined */
+	long gpio;              /* Register encoding, combined */
+	long gpio_mask;         /* Register encoding, combined */
+	u8 gpio_config[17];     /* Decoded value */
+	u8 config1;             /* Register value */
+	u8 config2;             /* Register value */
+	u8 config3;             /* Register value */
+};
+
+static int adm1026_attach_adapter(struct i2c_adapter *adapter);
+static int adm1026_detect(struct i2c_adapter *adapter, int address,
+	int kind);
+static int adm1026_detach_client(struct i2c_client *client);
+static int adm1026_read_value(struct i2c_client *client, u8 register);
+static int adm1026_write_value(struct i2c_client *client, u8 register,
+	int value); 
+static void adm1026_print_gpio(struct i2c_client *client);
+static void adm1026_fixup_gpio(struct i2c_client *client); 
+static struct adm1026_data *adm1026_update_device(struct device *dev);
+static void adm1026_init_client(struct i2c_client *client);
+
+
+static struct i2c_driver adm1026_driver = {
+	.owner          = THIS_MODULE,
+	.name           = "adm1026",
+	.flags          = I2C_DF_NOTIFY,
+	.attach_adapter = adm1026_attach_adapter,
+	.detach_client  = adm1026_detach_client,
+};
+
+int adm1026_attach_adapter(struct i2c_adapter *adapter)
+{
+	if (!(adapter->class & I2C_CLASS_HWMON)) {
+		return 0;
+	}
+	return i2c_detect(adapter, &addr_data, adm1026_detect);
+}
+
+int adm1026_detach_client(struct i2c_client *client)
+{
+	i2c_detach_client(client);
+	kfree(i2c_get_clientdata(client));
+	return 0;
+}
+
+int adm1026_read_value(struct i2c_client *client, u8 reg)
+{
+	int res;
+
+	if (reg < 0x80) {
+		/* "RAM" locations */
+		res = i2c_smbus_read_byte_data(client, reg) & 0xff;
+	} else {
+		/* EEPROM, do nothing */
+		res = 0;
+	}
+	return res;
+}
+
+int adm1026_write_value(struct i2c_client *client, u8 reg, int value)
+{
+	int res;
+
+	if (reg < 0x80) {
+		/* "RAM" locations */
+		res = i2c_smbus_write_byte_data(client, reg, value);
+	} else {
+		/* EEPROM, do nothing */
+		res = 0;
+	}
+	return res;
+}
+
+void adm1026_init_client(struct i2c_client *client)
+{
+	int value, i;
+	struct adm1026_data *data = i2c_get_clientdata(client);
+
+        dev_dbg(&client->dev, "Initializing device\n");
+	/* Read chip config */
+	data->config1 = adm1026_read_value(client, ADM1026_REG_CONFIG1);
+	data->config2 = adm1026_read_value(client, ADM1026_REG_CONFIG2);
+	data->config3 = adm1026_read_value(client, ADM1026_REG_CONFIG3);
+
+	/* Inform user of chip config */
+	dev_dbg(&client->dev, "ADM1026_REG_CONFIG1 is: 0x%02x\n",
+		data->config1);
+	if ((data->config1 & CFG1_MONITOR) == 0) {
+		dev_dbg(&client->dev, "Monitoring not currently "
+			"enabled.\n");
+	}
+	if (data->config1 & CFG1_INT_ENABLE) {
+		dev_dbg(&client->dev, "SMBALERT interrupts are "
+			"enabled.\n");
+	}
+	if (data->config1 & CFG1_AIN8_9) {
+		dev_dbg(&client->dev, "in8 and in9 enabled. "
+			"temp3 disabled.\n");
+	} else {
+		dev_dbg(&client->dev, "temp3 enabled.  in8 and "
+			"in9 disabled.\n");
+	}
+	if (data->config1 & CFG1_THERM_HOT) {
+		dev_dbg(&client->dev, "Automatic THERM, PWM, "
+			"and temp limits enabled.\n");
+	}
+
+	value = data->config3;
+	if (data->config3 & CFG3_GPIO16_ENABLE) {
+		dev_dbg(&client->dev, "GPIO16 enabled.  THERM "
+			"pin disabled.\n");
+	} else {
+		dev_dbg(&client->dev, "THERM pin enabled.  "
+			"GPIO16 disabled.\n");
+	}
+	if (data->config3 & CFG3_VREF_250) {
+		dev_dbg(&client->dev, "Vref is 2.50 Volts.\n");
+	} else {
+		dev_dbg(&client->dev, "Vref is 1.82 Volts.\n");
+	}
+	/* Read and pick apart the existing GPIO configuration */
+	value = 0;
+	for (i = 0;i <= 15;++i) {
+		if ((i & 0x03) == 0) {
+			value = adm1026_read_value(client,
+					ADM1026_REG_GPIO_CFG_0_3 + i/4);
+		}
+		data->gpio_config[i] = value & 0x03;
+		value >>= 2;
+	}
+	data->gpio_config[16] = (data->config3 >> 6) & 0x03;
+
+	/* ... and then print it */
+	adm1026_print_gpio(client);
+
+	/* If the user asks us to reprogram the GPIO config, then
+	 * do it now.
+	 */
+	if (gpio_input[0] != -1 || gpio_output[0] != -1
+		|| gpio_inverted[0] != -1 || gpio_normal[0] != -1
+		|| gpio_fan[0] != -1) {
+		adm1026_fixup_gpio(client);
+	}
+
+	/* WE INTENTIONALLY make no changes to the limits,
+	 *   offsets, pwms, fans and zones.  If they were
+	 *   configured, we don't want to mess with them.
+	 *   If they weren't, the default is 100% PWM, no
+	 *   control and will suffice until 'sensors -s'
+	 *   can be run by the user.  We DO set the default 
+	 *   value for pwm1.auto_pwm_min to its maximum
+	 *   so that enabling automatic pwm fan control
+	 *   without first setting a value for pwm1.auto_pwm_min 
+	 *   will not result in potentially dangerous fan speed decrease.
+	 */
+	data->pwm1.auto_pwm_min=255;
+	/* Start monitoring */
+	value = adm1026_read_value(client, ADM1026_REG_CONFIG1);
+	/* Set MONITOR, clear interrupt acknowledge and s/w reset */
+	value = (value | CFG1_MONITOR) & (~CFG1_INT_CLEAR & ~CFG1_RESET);
+	dev_dbg(&client->dev, "Setting CONFIG to: 0x%02x\n", value);
+	data->config1 = value;
+	adm1026_write_value(client, ADM1026_REG_CONFIG1, value);
+
+	/* initialize fan_div[] to hardware defaults */
+	value = adm1026_read_value(client, ADM1026_REG_FAN_DIV_0_3) |
+		(adm1026_read_value(client, ADM1026_REG_FAN_DIV_4_7) << 8);
+	for (i = 0;i <= 7;++i) {
+		data->fan_div[i] = DIV_FROM_REG(value & 0x03);
+		value >>= 2;
+	}
+}
+
+void adm1026_print_gpio(struct i2c_client *client)
+{
+	struct adm1026_data *data = i2c_get_clientdata(client);
+	int  i;
+
+	dev_dbg(&client->dev, "GPIO config is:");
+	for (i = 0;i <= 7;++i) {
+		if (data->config2 & (1 << i)) {
+			dev_dbg(&client->dev, "\t%sGP%s%d\n",
+				data->gpio_config[i] & 0x02 ? "" : "!",
+				data->gpio_config[i] & 0x01 ? "OUT" : "IN",
+				i);
+		} else {
+			dev_dbg(&client->dev, "\tFAN%d\n", i);
+		}
+	}
+	for (i = 8;i <= 15;++i) {
+		dev_dbg(&client->dev, "\t%sGP%s%d\n",
+			data->gpio_config[i] & 0x02 ? "" : "!",
+			data->gpio_config[i] & 0x01 ? "OUT" : "IN",
+			i);
+	}
+	if (data->config3 & CFG3_GPIO16_ENABLE) {
+		dev_dbg(&client->dev, "\t%sGP%s16\n",
+			data->gpio_config[16] & 0x02 ? "" : "!",
+			data->gpio_config[16] & 0x01 ? "OUT" : "IN");
+	} else {
+		/* GPIO16 is THERM  */
+		dev_dbg(&client->dev, "\tTHERM\n");
+	}
+}
+
+void adm1026_fixup_gpio(struct i2c_client *client)
+{
+	struct adm1026_data *data = i2c_get_clientdata(client);
+	int  i;
+	int  value;
+
+	/* Make the changes requested. */
+	/* We may need to unlock/stop monitoring or soft-reset the
+	 *    chip before we can make changes.  This hasn't been
+	 *    tested much.  FIXME
+	 */
+
+	/* Make outputs */
+	for (i = 0;i <= 16;++i) {
+		if (gpio_output[i] >= 0 && gpio_output[i] <= 16) {
+			data->gpio_config[gpio_output[i]] |= 0x01;
+		}
+		/* if GPIO0-7 is output, it isn't a FAN tach */
+		if (gpio_output[i] >= 0 && gpio_output[i] <= 7) {
+			data->config2 |= 1 << gpio_output[i];
+		}
+	}
+
+	/* Input overrides output */
+	for (i = 0;i <= 16;++i) {
+		if (gpio_input[i] >= 0 && gpio_input[i] <= 16) {
+			data->gpio_config[gpio_input[i]] &= ~ 0x01;
+		}
+		/* if GPIO0-7 is input, it isn't a FAN tach */
+		if (gpio_input[i] >= 0 && gpio_input[i] <= 7) {
+			data->config2 |= 1 << gpio_input[i];
+		}
+	}
+
+	/* Inverted  */
+	for (i = 0;i <= 16;++i) {
+		if (gpio_inverted[i] >= 0 && gpio_inverted[i] <= 16) {
+			data->gpio_config[gpio_inverted[i]] &= ~ 0x02;
+		}
+	}
+
+	/* Normal overrides inverted  */
+	for (i = 0;i <= 16;++i) {
+		if (gpio_normal[i] >= 0 && gpio_normal[i] <= 16) {
+			data->gpio_config[gpio_normal[i]] |= 0x02;
+		}
+	}
+
+	/* Fan overrides input and output */
+	for (i = 0;i <= 7;++i) {
+		if (gpio_fan[i] >= 0 && gpio_fan[i] <= 7) {
+			data->config2 &= ~(1 << gpio_fan[i]);
+		}
+	}
+
+	/* Write new configs to registers */
+	adm1026_write_value(client, ADM1026_REG_CONFIG2, data->config2);
+	data->config3 = (data->config3 & 0x3f)
+			| ((data->gpio_config[16] & 0x03) << 6);
+	adm1026_write_value(client, ADM1026_REG_CONFIG3, data->config3);
+	for (i = 15, value = 0;i >= 0;--i) {
+		value <<= 2;
+		value |= data->gpio_config[i] & 0x03;
+		if ((i & 0x03) == 0) {
+			adm1026_write_value(client,
+					ADM1026_REG_GPIO_CFG_0_3 + i/4,
+					value);
+			value = 0;
+		}
+	}
+
+	/* Print the new config */
+	adm1026_print_gpio(client);
+}
+
+
+static struct adm1026_data *adm1026_update_device(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct adm1026_data *data = i2c_get_clientdata(client);
+	int i;
+	long value, alarms, gpio;
+
+	down(&data->update_lock);
+	if (!data->valid
+	    || time_after(jiffies, data->last_reading + ADM1026_DATA_INTERVAL)) {
+		/* Things that change quickly */
+		dev_dbg(&client->dev,"Reading sensor values\n");
+		for (i = 0;i <= 16;++i) {
+			data->in[i] =
+			    adm1026_read_value(client, ADM1026_REG_IN[i]);
+		}
+
+		for (i = 0;i <= 7;++i) {
+			data->fan[i] =
+			    adm1026_read_value(client, ADM1026_REG_FAN(i));
+		}
+
+		for (i = 0;i <= 2;++i) {
+			/* NOTE: temp[] is s8 and we assume 2's complement
+			 *   "conversion" in the assignment   */
+			data->temp[i] =
+			    adm1026_read_value(client, ADM1026_REG_TEMP[i]);
+		}
+
+		data->pwm1.pwm = adm1026_read_value(client, 
+			ADM1026_REG_PWM);
+		data->analog_out = adm1026_read_value(client, 
+			ADM1026_REG_DAC);
+		/* GPIO16 is MSbit of alarms, move it to gpio */
+		alarms = adm1026_read_value(client, ADM1026_REG_STATUS4);
+		gpio = alarms & 0x80 ? 0x0100 : 0;  /* GPIO16 */
+		alarms &= 0x7f;
+		alarms <<= 8;
+		alarms |= adm1026_read_value(client, ADM1026_REG_STATUS3);
+		alarms <<= 8;
+		alarms |= adm1026_read_value(client, ADM1026_REG_STATUS2);
+		alarms <<= 8;
+		alarms |= adm1026_read_value(client, ADM1026_REG_STATUS1);
+		data->alarms = alarms;
+
+		/* Read the GPIO values */
+		gpio |= adm1026_read_value(client, 
+			ADM1026_REG_GPIO_STATUS_8_15);
+		gpio <<= 8;
+		gpio |= adm1026_read_value(client, 
+			ADM1026_REG_GPIO_STATUS_0_7);
+		data->gpio = gpio;
+
+		data->last_reading = jiffies;
+	};  /* last_reading */
+
+	if (!data->valid ||
+	    time_after(jiffies, data->last_config + ADM1026_CONFIG_INTERVAL)) {
+		/* Things that don't change often */
+		dev_dbg(&client->dev, "Reading config values\n");
+		for (i = 0;i <= 16;++i) {
+			data->in_min[i] = adm1026_read_value(client, 
+				ADM1026_REG_IN_MIN[i]);
+			data->in_max[i] = adm1026_read_value(client, 
+				ADM1026_REG_IN_MAX[i]);
+		}
+
+		value = adm1026_read_value(client, ADM1026_REG_FAN_DIV_0_3)
+			| (adm1026_read_value(client, ADM1026_REG_FAN_DIV_4_7)
+			<< 8);
+		for (i = 0;i <= 7;++i) {
+			data->fan_min[i] = adm1026_read_value(client, 
+				ADM1026_REG_FAN_MIN(i));
+			data->fan_div[i] = DIV_FROM_REG(value & 0x03);
+			value >>= 2;
+		}
+
+		for (i = 0; i <= 2; ++i) {
+			/* NOTE: temp_xxx[] are s8 and we assume 2's 
+			 *    complement "conversion" in the assignment
+			 */
+			data->temp_min[i] = adm1026_read_value(client, 
+				ADM1026_REG_TEMP_MIN[i]);
+			data->temp_max[i] = adm1026_read_value(client, 
+				ADM1026_REG_TEMP_MAX[i]);
+			data->temp_tmin[i] = adm1026_read_value(client, 
+				ADM1026_REG_TEMP_TMIN[i]);
+			data->temp_crit[i] = adm1026_read_value(client, 
+				ADM1026_REG_TEMP_THERM[i]);
+			data->temp_offset[i] = adm1026_read_value(client, 
+				ADM1026_REG_TEMP_OFFSET[i]);
+		}
+
+		/* Read the STATUS/alarm masks */
+		alarms  = adm1026_read_value(client, ADM1026_REG_MASK4);
+		gpio    = alarms & 0x80 ? 0x0100 : 0;  /* GPIO16 */
+		alarms  = (alarms & 0x7f) << 8;
+		alarms |= adm1026_read_value(client, ADM1026_REG_MASK3);
+		alarms <<= 8;
+		alarms |= adm1026_read_value(client, ADM1026_REG_MASK2);
+		alarms <<= 8;
+		alarms |= adm1026_read_value(client, ADM1026_REG_MASK1);
+		data->alarm_mask = alarms;
+
+		/* Read the GPIO values */
+		gpio |= adm1026_read_value(client, 
+			ADM1026_REG_GPIO_MASK_8_15);
+		gpio <<= 8;
+		gpio |= adm1026_read_value(client, ADM1026_REG_GPIO_MASK_0_7);
+		data->gpio_mask = gpio;
+
+		/* Read various values from CONFIG1 */
+		data->config1 = adm1026_read_value(client, 
+			ADM1026_REG_CONFIG1);
+		if (data->config1 & CFG1_PWM_AFC) {
+			data->pwm1.enable = 2;
+			data->pwm1.auto_pwm_min = 
+				PWM_MIN_FROM_REG(data->pwm1.pwm);
+		}
+		/* Read the GPIO config */
+		data->config2 = adm1026_read_value(client, 
+			ADM1026_REG_CONFIG2);
+		data->config3 = adm1026_read_value(client, 
+			ADM1026_REG_CONFIG3);
+		data->gpio_config[16] = (data->config3 >> 6) & 0x03;
+
+		value = 0;
+		for (i = 0;i <= 15;++i) {
+			if ((i & 0x03) == 0) {
+				value = adm1026_read_value(client,
+					    ADM1026_REG_GPIO_CFG_0_3 + i/4);
+			}
+			data->gpio_config[i] = value & 0x03;
+			value >>= 2;
+		}
+
+		data->last_config = jiffies;
+	};  /* last_config */
+
+	dev_dbg(&client->dev, "Setting VID from GPIO11-15.\n");
+	data->vid = (data->gpio >> 11) & 0x1f;
+	data->valid = 1;
+	up(&data->update_lock);
+	return data;
+}
+
+static ssize_t show_in(struct device *dev, struct device_attribute *attr,
+		char *buf)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+	struct adm1026_data *data = adm1026_update_device(dev);
+	return sprintf(buf,"%d\n", INS_FROM_REG(nr, data->in[nr]));
+}
+static ssize_t show_in_min(struct device *dev, struct device_attribute *attr,
+		char *buf)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+	struct adm1026_data *data = adm1026_update_device(dev); 
+	return sprintf(buf,"%d\n", INS_FROM_REG(nr, data->in_min[nr]));
+}
+static ssize_t set_in_min(struct device *dev, struct device_attribute *attr,
+		const char *buf, size_t count)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+	struct i2c_client *client = to_i2c_client(dev);
+	struct adm1026_data *data = i2c_get_clientdata(client);
+	int val = simple_strtol(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->in_min[nr] = INS_TO_REG(nr, val);
+	adm1026_write_value(client, ADM1026_REG_IN_MIN[nr], data->in_min[nr]);
+	up(&data->update_lock);
+	return count; 
+}
+static ssize_t show_in_max(struct device *dev, struct device_attribute *attr,
+		char *buf)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+	struct adm1026_data *data = adm1026_update_device(dev);
+	return sprintf(buf,"%d\n", INS_FROM_REG(nr, data->in_max[nr]));
+}
+static ssize_t set_in_max(struct device *dev, struct device_attribute *attr,
+		const char *buf, size_t count)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+	struct i2c_client *client = to_i2c_client(dev);
+	struct adm1026_data *data = i2c_get_clientdata(client);
+	int val = simple_strtol(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->in_max[nr] = INS_TO_REG(nr, val);
+	adm1026_write_value(client, ADM1026_REG_IN_MAX[nr], data->in_max[nr]);
+	up(&data->update_lock);
+	return count;
+}
+
+#define in_reg(offset)						\
+static SENSOR_DEVICE_ATTR(in##offset##_input, S_IRUGO, show_in,	\
+		NULL, offset);					\
+static SENSOR_DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR,	\
+		show_in_min, set_in_min, offset);		\
+static SENSOR_DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR,	\
+		show_in_max, set_in_max, offset);
+
+
+in_reg(0);
+in_reg(1);
+in_reg(2);
+in_reg(3);
+in_reg(4);
+in_reg(5);
+in_reg(6);
+in_reg(7);
+in_reg(8);
+in_reg(9);
+in_reg(10);
+in_reg(11);
+in_reg(12);
+in_reg(13);
+in_reg(14);
+in_reg(15);
+
+static ssize_t show_in16(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct adm1026_data *data = adm1026_update_device(dev);
+	return sprintf(buf,"%d\n", INS_FROM_REG(16, data->in[16]) -
+		NEG12_OFFSET);
+}
+static ssize_t show_in16_min(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct adm1026_data *data = adm1026_update_device(dev); 
+	return sprintf(buf,"%d\n", INS_FROM_REG(16, data->in_min[16])
+		- NEG12_OFFSET);
+}
+static ssize_t set_in16_min(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct adm1026_data *data = i2c_get_clientdata(client);
+	int val = simple_strtol(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->in_min[16] = INS_TO_REG(16, val + NEG12_OFFSET);
+	adm1026_write_value(client, ADM1026_REG_IN_MIN[16], data->in_min[16]);
+	up(&data->update_lock);
+	return count; 
+}
+static ssize_t show_in16_max(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct adm1026_data *data = adm1026_update_device(dev);
+	return sprintf(buf,"%d\n", INS_FROM_REG(16, data->in_max[16])
+			- NEG12_OFFSET);
+}
+static ssize_t set_in16_max(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct adm1026_data *data = i2c_get_clientdata(client);
+	int val = simple_strtol(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->in_max[16] = INS_TO_REG(16, val+NEG12_OFFSET);
+	adm1026_write_value(client, ADM1026_REG_IN_MAX[16], data->in_max[16]);
+	up(&data->update_lock);
+	return count;
+}
+
+static SENSOR_DEVICE_ATTR(in16_input, S_IRUGO, show_in16, NULL, 16);
+static SENSOR_DEVICE_ATTR(in16_min, S_IRUGO | S_IWUSR, show_in16_min, set_in16_min, 16);
+static SENSOR_DEVICE_ATTR(in16_max, S_IRUGO | S_IWUSR, show_in16_max, set_in16_max, 16);
+
+
+
+
+/* Now add fan read/write functions */
+
+static ssize_t show_fan(struct device *dev, struct device_attribute *attr,
+		char *buf)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+	struct adm1026_data *data = adm1026_update_device(dev);
+	return sprintf(buf,"%d\n", FAN_FROM_REG(data->fan[nr],
+		data->fan_div[nr]));
+}
+static ssize_t show_fan_min(struct device *dev, struct device_attribute *attr,
+		char *buf)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+	struct adm1026_data *data = adm1026_update_device(dev);
+	return sprintf(buf,"%d\n", FAN_FROM_REG(data->fan_min[nr],
+		data->fan_div[nr]));
+}
+static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr,
+		const char *buf, size_t count)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+	struct i2c_client *client = to_i2c_client(dev);
+	struct adm1026_data *data = i2c_get_clientdata(client);
+	int val = simple_strtol(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->fan_min[nr] = FAN_TO_REG(val, data->fan_div[nr]);
+	adm1026_write_value(client, ADM1026_REG_FAN_MIN(nr),
+		data->fan_min[nr]);
+	up(&data->update_lock);
+	return count;
+}
+
+#define fan_offset(offset)                                         		\
+static SENSOR_DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_fan, NULL, 	\
+		offset - 1);							\
+static SENSOR_DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR,           	\
+		show_fan_min, set_fan_min, offset - 1);
+
+fan_offset(1);
+fan_offset(2);
+fan_offset(3);
+fan_offset(4);
+fan_offset(5);
+fan_offset(6);
+fan_offset(7);
+fan_offset(8);
+
+/* Adjust fan_min to account for new fan divisor */
+static void fixup_fan_min(struct device *dev, int fan, int old_div)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct adm1026_data *data = i2c_get_clientdata(client);
+	int    new_min;
+	int    new_div = data->fan_div[fan];
+
+	/* 0 and 0xff are special.  Don't adjust them */
+	if (data->fan_min[fan] == 0 || data->fan_min[fan] == 0xff) {
+		return;
+	}
+
+	new_min = data->fan_min[fan] * old_div / new_div;
+	new_min = SENSORS_LIMIT(new_min, 1, 254);
+	data->fan_min[fan] = new_min;
+	adm1026_write_value(client, ADM1026_REG_FAN_MIN(fan), new_min);
+}
+
+/* Now add fan_div read/write functions */
+static ssize_t show_fan_div(struct device *dev, struct device_attribute *attr,
+		char *buf)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+	struct adm1026_data *data = adm1026_update_device(dev);
+	return sprintf(buf,"%d\n", data->fan_div[nr]);
+}
+static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr,
+		const char *buf, size_t count)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+	struct i2c_client *client = to_i2c_client(dev);
+	struct adm1026_data *data = i2c_get_clientdata(client);
+	int    val,orig_div,new_div,shift;
+
+	val = simple_strtol(buf, NULL, 10);
+	new_div = DIV_TO_REG(val); 
+	if (new_div == 0) {
+		return -EINVAL;
+	}
+	down(&data->update_lock);
+	orig_div = data->fan_div[nr];
+	data->fan_div[nr] = DIV_FROM_REG(new_div);
+
+	if (nr < 4) { /* 0 <= nr < 4 */
+		shift = 2 * nr;
+		adm1026_write_value(client, ADM1026_REG_FAN_DIV_0_3,
+			((DIV_TO_REG(orig_div) & (~(0x03 << shift))) |
+			(new_div << shift)));
+	} else { /* 3 < nr < 8 */
+		shift = 2 * (nr - 4);
+		adm1026_write_value(client, ADM1026_REG_FAN_DIV_4_7,
+			((DIV_TO_REG(orig_div) & (~(0x03 << (2 * shift)))) |
+			(new_div << shift)));
+	}
+
+	if (data->fan_div[nr] != orig_div) {
+		fixup_fan_min(dev,nr,orig_div);
+	}
+	up(&data->update_lock);
+	return count;
+}
+
+#define fan_offset_div(offset)                                          \
+static SENSOR_DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR,         \
+		show_fan_div, set_fan_div, offset - 1);
+
+fan_offset_div(1);
+fan_offset_div(2);
+fan_offset_div(3);
+fan_offset_div(4);
+fan_offset_div(5);
+fan_offset_div(6);
+fan_offset_div(7);
+fan_offset_div(8);
+
+/* Temps */
+static ssize_t show_temp(struct device *dev, struct device_attribute *attr,
+		char *buf)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+	struct adm1026_data *data = adm1026_update_device(dev);
+	return sprintf(buf,"%d\n", TEMP_FROM_REG(data->temp[nr]));
+}
+static ssize_t show_temp_min(struct device *dev, struct device_attribute *attr,
+		char *buf)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+	struct adm1026_data *data = adm1026_update_device(dev);
+	return sprintf(buf,"%d\n", TEMP_FROM_REG(data->temp_min[nr]));
+}
+static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr,
+		const char *buf, size_t count)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+	struct i2c_client *client = to_i2c_client(dev);
+	struct adm1026_data *data = i2c_get_clientdata(client);
+	int val = simple_strtol(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->temp_min[nr] = TEMP_TO_REG(val);
+	adm1026_write_value(client, ADM1026_REG_TEMP_MIN[nr],
+		data->temp_min[nr]);
+	up(&data->update_lock);
+	return count;
+}
+static ssize_t show_temp_max(struct device *dev, struct device_attribute *attr,
+		char *buf)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+	struct adm1026_data *data = adm1026_update_device(dev);
+	return sprintf(buf,"%d\n", TEMP_FROM_REG(data->temp_max[nr]));
+}
+static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr,
+		const char *buf, size_t count)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+	struct i2c_client *client = to_i2c_client(dev);
+	struct adm1026_data *data = i2c_get_clientdata(client);
+	int val = simple_strtol(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->temp_max[nr] = TEMP_TO_REG(val);
+	adm1026_write_value(client, ADM1026_REG_TEMP_MAX[nr],
+		data->temp_max[nr]);
+	up(&data->update_lock);
+	return count;
+}
+
+#define temp_reg(offset)						\
+static SENSOR_DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_temp, 	\
+		NULL, offset - 1);					\
+static SENSOR_DEVICE_ATTR(temp##offset##_min, S_IRUGO | S_IWUSR,	\
+		show_temp_min, set_temp_min, offset - 1);		\
+static SENSOR_DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR,	\
+		show_temp_max, set_temp_max, offset - 1);
+
+
+temp_reg(1);
+temp_reg(2);
+temp_reg(3);
+
+static ssize_t show_temp_offset(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+	struct adm1026_data *data = adm1026_update_device(dev);
+	return sprintf(buf,"%d\n", TEMP_FROM_REG(data->temp_offset[nr]));
+}
+static ssize_t set_temp_offset(struct device *dev,
+		struct device_attribute *attr, const char *buf,
+		size_t count)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+	struct i2c_client *client = to_i2c_client(dev);
+	struct adm1026_data *data = i2c_get_clientdata(client);
+	int val = simple_strtol(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->temp_offset[nr] = TEMP_TO_REG(val);
+	adm1026_write_value(client, ADM1026_REG_TEMP_OFFSET[nr],
+		data->temp_offset[nr]);
+	up(&data->update_lock);
+	return count;
+}
+
+#define temp_offset_reg(offset)							\
+static SENSOR_DEVICE_ATTR(temp##offset##_offset, S_IRUGO | S_IWUSR,		\
+		show_temp_offset, set_temp_offset, offset - 1);
+
+temp_offset_reg(1);
+temp_offset_reg(2);
+temp_offset_reg(3);
+
+static ssize_t show_temp_auto_point1_temp_hyst(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+	struct adm1026_data *data = adm1026_update_device(dev);
+	return sprintf(buf,"%d\n", TEMP_FROM_REG(
+		ADM1026_FAN_ACTIVATION_TEMP_HYST + data->temp_tmin[nr]));
+}
+static ssize_t show_temp_auto_point2_temp(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+	struct adm1026_data *data = adm1026_update_device(dev);
+	return sprintf(buf,"%d\n", TEMP_FROM_REG(data->temp_tmin[nr] +
+		ADM1026_FAN_CONTROL_TEMP_RANGE));
+}
+static ssize_t show_temp_auto_point1_temp(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+	struct adm1026_data *data = adm1026_update_device(dev);
+	return sprintf(buf,"%d\n", TEMP_FROM_REG(data->temp_tmin[nr]));
+}
+static ssize_t set_temp_auto_point1_temp(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+	struct i2c_client *client = to_i2c_client(dev);
+	struct adm1026_data *data = i2c_get_clientdata(client);
+	int val = simple_strtol(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->temp_tmin[nr] = TEMP_TO_REG(val);
+	adm1026_write_value(client, ADM1026_REG_TEMP_TMIN[nr],
+		data->temp_tmin[nr]);
+	up(&data->update_lock);
+	return count;
+}
+
+#define temp_auto_point(offset)							\
+static SENSOR_DEVICE_ATTR(temp##offset##_auto_point1_temp, S_IRUGO | S_IWUSR,	\
+		show_temp_auto_point1_temp, set_temp_auto_point1_temp, 		\
+		offset - 1);							\
+static SENSOR_DEVICE_ATTR(temp##offset##_auto_point1_temp_hyst, S_IRUGO,	\
+		show_temp_auto_point1_temp_hyst, NULL, offset - 1);		\
+static SENSOR_DEVICE_ATTR(temp##offset##_auto_point2_temp, S_IRUGO,		\
+		show_temp_auto_point2_temp, NULL, offset - 1);
+
+temp_auto_point(1);
+temp_auto_point(2);
+temp_auto_point(3);
+
+static ssize_t show_temp_crit_enable(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct adm1026_data *data = adm1026_update_device(dev);
+	return sprintf(buf,"%d\n", (data->config1 & CFG1_THERM_HOT) >> 4);
+}
+static ssize_t set_temp_crit_enable(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct adm1026_data *data = i2c_get_clientdata(client);
+	int val = simple_strtol(buf, NULL, 10);
+
+	if ((val == 1) || (val==0)) {
+		down(&data->update_lock);
+		data->config1 = (data->config1 & ~CFG1_THERM_HOT) | (val << 4);
+		adm1026_write_value(client, ADM1026_REG_CONFIG1, 
+			data->config1);
+		up(&data->update_lock);
+	}
+	return count;
+}
+
+#define temp_crit_enable(offset)				\
+static DEVICE_ATTR(temp##offset##_crit_enable, S_IRUGO | S_IWUSR, \
+	show_temp_crit_enable, set_temp_crit_enable);
+
+temp_crit_enable(1);
+temp_crit_enable(2);
+temp_crit_enable(3);
+
+static ssize_t show_temp_crit(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+	struct adm1026_data *data = adm1026_update_device(dev);
+	return sprintf(buf,"%d\n", TEMP_FROM_REG(data->temp_crit[nr]));
+}
+static ssize_t set_temp_crit(struct device *dev, struct device_attribute *attr,
+		const char *buf, size_t count)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+	struct i2c_client *client = to_i2c_client(dev);
+	struct adm1026_data *data = i2c_get_clientdata(client);
+	int val = simple_strtol(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->temp_crit[nr] = TEMP_TO_REG(val);
+	adm1026_write_value(client, ADM1026_REG_TEMP_THERM[nr],
+		data->temp_crit[nr]);
+	up(&data->update_lock);
+	return count;
+}
+
+#define temp_crit_reg(offset)						\
+static SENSOR_DEVICE_ATTR(temp##offset##_crit, S_IRUGO | S_IWUSR,	\
+		show_temp_crit, set_temp_crit, offset - 1);
+
+temp_crit_reg(1);
+temp_crit_reg(2);
+temp_crit_reg(3);
+
+static ssize_t show_analog_out_reg(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct adm1026_data *data = adm1026_update_device(dev);
+	return sprintf(buf,"%d\n", DAC_FROM_REG(data->analog_out));
+}
+static ssize_t set_analog_out_reg(struct device *dev, struct device_attribute *attr, const char *buf,
+		size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct adm1026_data *data = i2c_get_clientdata(client);
+	int val = simple_strtol(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->analog_out = DAC_TO_REG(val);
+	adm1026_write_value(client, ADM1026_REG_DAC, data->analog_out);
+	up(&data->update_lock);
+	return count;
+}
+
+static DEVICE_ATTR(analog_out, S_IRUGO | S_IWUSR, show_analog_out_reg, 
+	set_analog_out_reg);
+
+static ssize_t show_vid_reg(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct adm1026_data *data = adm1026_update_device(dev);
+	return sprintf(buf,"%d\n", vid_from_reg(data->vid & 0x3f, data->vrm));
+}
+/* vid deprecated in favour of cpu0_vid, remove after 2005-11-11 */
+static DEVICE_ATTR(vid, S_IRUGO, show_vid_reg, NULL);
+static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid_reg, NULL);
+
+static ssize_t show_vrm_reg(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct adm1026_data *data = adm1026_update_device(dev);
+	return sprintf(buf,"%d\n", data->vrm);
+}
+static ssize_t store_vrm_reg(struct device *dev, struct device_attribute *attr, const char *buf,
+		size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct adm1026_data *data = i2c_get_clientdata(client);
+
+	data->vrm = simple_strtol(buf, NULL, 10);
+	return count;
+}
+
+static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg);
+
+static ssize_t show_alarms_reg(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct adm1026_data *data = adm1026_update_device(dev);
+	return sprintf(buf, "%ld\n", (long) (data->alarms));
+}
+
+static DEVICE_ATTR(alarms, S_IRUGO, show_alarms_reg, NULL);
+
+static ssize_t show_alarm_mask(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct adm1026_data *data = adm1026_update_device(dev);
+	return sprintf(buf,"%ld\n", data->alarm_mask);
+}
+static ssize_t set_alarm_mask(struct device *dev, struct device_attribute *attr, const char *buf,
+		size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct adm1026_data *data = i2c_get_clientdata(client);
+	int val = simple_strtol(buf, NULL, 10);
+	unsigned long mask;
+
+	down(&data->update_lock);
+	data->alarm_mask = val & 0x7fffffff;
+	mask = data->alarm_mask
+		| (data->gpio_mask & 0x10000 ? 0x80000000 : 0);
+	adm1026_write_value(client, ADM1026_REG_MASK1,
+		mask & 0xff);
+	mask >>= 8;
+	adm1026_write_value(client, ADM1026_REG_MASK2,
+		mask & 0xff);
+	mask >>= 8;
+	adm1026_write_value(client, ADM1026_REG_MASK3,
+		mask & 0xff);
+	mask >>= 8;
+	adm1026_write_value(client, ADM1026_REG_MASK4,
+		mask & 0xff);
+	up(&data->update_lock);
+	return count;
+}
+
+static DEVICE_ATTR(alarm_mask, S_IRUGO | S_IWUSR, show_alarm_mask,
+	set_alarm_mask);
+
+
+static ssize_t show_gpio(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct adm1026_data *data = adm1026_update_device(dev);
+	return sprintf(buf,"%ld\n", data->gpio);
+}
+static ssize_t set_gpio(struct device *dev, struct device_attribute *attr, const char *buf,
+		size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct adm1026_data *data = i2c_get_clientdata(client);
+	int val = simple_strtol(buf, NULL, 10);
+	long   gpio;
+
+	down(&data->update_lock);
+	data->gpio = val & 0x1ffff;
+	gpio = data->gpio;
+	adm1026_write_value(client, ADM1026_REG_GPIO_STATUS_0_7,gpio & 0xff);
+	gpio >>= 8;
+	adm1026_write_value(client, ADM1026_REG_GPIO_STATUS_8_15,gpio & 0xff);
+	gpio = ((gpio >> 1) & 0x80) | (data->alarms >> 24 & 0x7f);
+	adm1026_write_value(client, ADM1026_REG_STATUS4,gpio & 0xff);
+	up(&data->update_lock);
+	return count;
+}
+
+static DEVICE_ATTR(gpio, S_IRUGO | S_IWUSR, show_gpio, set_gpio);
+
+
+static ssize_t show_gpio_mask(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct adm1026_data *data = adm1026_update_device(dev);
+	return sprintf(buf,"%ld\n", data->gpio_mask);
+}
+static ssize_t set_gpio_mask(struct device *dev, struct device_attribute *attr, const char *buf,
+		size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct adm1026_data *data = i2c_get_clientdata(client);
+	int val = simple_strtol(buf, NULL, 10);
+	long   mask;
+
+	down(&data->update_lock);
+	data->gpio_mask = val & 0x1ffff;
+	mask = data->gpio_mask;
+	adm1026_write_value(client, ADM1026_REG_GPIO_MASK_0_7,mask & 0xff);
+	mask >>= 8;
+	adm1026_write_value(client, ADM1026_REG_GPIO_MASK_8_15,mask & 0xff);
+	mask = ((mask >> 1) & 0x80) | (data->alarm_mask >> 24 & 0x7f);
+	adm1026_write_value(client, ADM1026_REG_MASK1,mask & 0xff);
+	up(&data->update_lock);
+	return count;
+}
+
+static DEVICE_ATTR(gpio_mask, S_IRUGO | S_IWUSR, show_gpio_mask, set_gpio_mask);
+
+static ssize_t show_pwm_reg(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct adm1026_data *data = adm1026_update_device(dev);
+	return sprintf(buf,"%d\n", PWM_FROM_REG(data->pwm1.pwm));
+}
+static ssize_t set_pwm_reg(struct device *dev, struct device_attribute *attr, const char *buf,
+		size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct adm1026_data *data = i2c_get_clientdata(client);
+
+	if (data->pwm1.enable == 1) {
+		int val = simple_strtol(buf, NULL, 10);
+
+		down(&data->update_lock);
+		data->pwm1.pwm = PWM_TO_REG(val);
+		adm1026_write_value(client, ADM1026_REG_PWM, data->pwm1.pwm);
+		up(&data->update_lock);
+	}
+	return count;
+}
+static ssize_t show_auto_pwm_min(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct adm1026_data *data = adm1026_update_device(dev);
+	return sprintf(buf,"%d\n", data->pwm1.auto_pwm_min);
+}
+static ssize_t set_auto_pwm_min(struct device *dev, struct device_attribute *attr, const char *buf,
+		size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct adm1026_data *data = i2c_get_clientdata(client);
+	int val = simple_strtol(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->pwm1.auto_pwm_min = SENSORS_LIMIT(val,0,255);
+	if (data->pwm1.enable == 2) { /* apply immediately */
+		data->pwm1.pwm = PWM_TO_REG((data->pwm1.pwm & 0x0f) |
+			PWM_MIN_TO_REG(data->pwm1.auto_pwm_min)); 
+		adm1026_write_value(client, ADM1026_REG_PWM, data->pwm1.pwm);
+	}
+	up(&data->update_lock);
+	return count;
+}
+static ssize_t show_auto_pwm_max(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	return sprintf(buf,"%d\n", ADM1026_PWM_MAX);
+}
+static ssize_t show_pwm_enable(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct adm1026_data *data = adm1026_update_device(dev);
+	return sprintf(buf,"%d\n", data->pwm1.enable);
+}
+static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *attr, const char *buf,
+		size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct adm1026_data *data = i2c_get_clientdata(client);
+	int val = simple_strtol(buf, NULL, 10);
+	int     old_enable;
+
+	if ((val >= 0) && (val < 3)) {
+		down(&data->update_lock);
+		old_enable = data->pwm1.enable;
+		data->pwm1.enable = val;
+		data->config1 = (data->config1 & ~CFG1_PWM_AFC)
+				| ((val == 2) ? CFG1_PWM_AFC : 0);
+		adm1026_write_value(client, ADM1026_REG_CONFIG1,
+			data->config1);
+		if (val == 2) {  /* apply pwm1_auto_pwm_min to pwm1 */
+			data->pwm1.pwm = PWM_TO_REG((data->pwm1.pwm & 0x0f) |
+				PWM_MIN_TO_REG(data->pwm1.auto_pwm_min)); 
+			adm1026_write_value(client, ADM1026_REG_PWM, 
+				data->pwm1.pwm);
+		} else if (!((old_enable == 1) && (val == 1))) {
+			/* set pwm to safe value */
+			data->pwm1.pwm = 255;
+			adm1026_write_value(client, ADM1026_REG_PWM, 
+				data->pwm1.pwm);
+		}
+		up(&data->update_lock);
+	}
+	return count;
+}
+
+/* enable PWM fan control */
+static DEVICE_ATTR(pwm1, S_IRUGO | S_IWUSR, show_pwm_reg, set_pwm_reg); 
+static DEVICE_ATTR(pwm2, S_IRUGO | S_IWUSR, show_pwm_reg, set_pwm_reg); 
+static DEVICE_ATTR(pwm3, S_IRUGO | S_IWUSR, show_pwm_reg, set_pwm_reg); 
+static DEVICE_ATTR(pwm1_enable, S_IRUGO | S_IWUSR, show_pwm_enable, 
+	set_pwm_enable);
+static DEVICE_ATTR(pwm2_enable, S_IRUGO | S_IWUSR, show_pwm_enable, 
+	set_pwm_enable);
+static DEVICE_ATTR(pwm3_enable, S_IRUGO | S_IWUSR, show_pwm_enable, 
+	set_pwm_enable);
+static DEVICE_ATTR(temp1_auto_point1_pwm, S_IRUGO | S_IWUSR, 
+	show_auto_pwm_min, set_auto_pwm_min);
+static DEVICE_ATTR(temp2_auto_point1_pwm, S_IRUGO | S_IWUSR, 
+	show_auto_pwm_min, set_auto_pwm_min);
+static DEVICE_ATTR(temp3_auto_point1_pwm, S_IRUGO | S_IWUSR, 
+	show_auto_pwm_min, set_auto_pwm_min);
+
+static DEVICE_ATTR(temp1_auto_point2_pwm, S_IRUGO, show_auto_pwm_max, NULL);
+static DEVICE_ATTR(temp2_auto_point2_pwm, S_IRUGO, show_auto_pwm_max, NULL);
+static DEVICE_ATTR(temp3_auto_point2_pwm, S_IRUGO, show_auto_pwm_max, NULL);
+
+int adm1026_detect(struct i2c_adapter *adapter, int address,
+		int kind)
+{
+	int company, verstep;
+	struct i2c_client *new_client;
+	struct adm1026_data *data;
+	int err = 0;
+	const char *type_name = "";
+
+	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
+		/* We need to be able to do byte I/O */
+		goto exit;
+	};
+
+	/* OK. For now, we presume we have a valid client. We now create the
+	   client structure, even though we cannot fill it completely yet.
+	   But it allows us to access adm1026_{read,write}_value. */
+
+	if (!(data = kmalloc(sizeof(struct adm1026_data), GFP_KERNEL))) {
+		err = -ENOMEM;
+		goto exit;
+	}
+
+	memset(data, 0, sizeof(struct adm1026_data));
+
+	new_client = &data->client;
+	i2c_set_clientdata(new_client, data);
+	new_client->addr = address;
+	new_client->adapter = adapter;
+	new_client->driver = &adm1026_driver;
+	new_client->flags = 0;
+
+	/* Now, we do the remaining detection. */
+
+	company = adm1026_read_value(new_client, ADM1026_REG_COMPANY);
+	verstep = adm1026_read_value(new_client, ADM1026_REG_VERSTEP);
+
+	dev_dbg(&new_client->dev, "Detecting device at %d,0x%02x with"
+		" COMPANY: 0x%02x and VERSTEP: 0x%02x\n",
+		i2c_adapter_id(new_client->adapter), new_client->addr,
+		company, verstep);
+
+	/* If auto-detecting, Determine the chip type. */
+	if (kind <= 0) {
+		dev_dbg(&new_client->dev, "Autodetecting device at %d,0x%02x "
+			"...\n", i2c_adapter_id(adapter), address);
+		if (company == ADM1026_COMPANY_ANALOG_DEV
+		    && verstep == ADM1026_VERSTEP_ADM1026) {
+			kind = adm1026;
+		} else if (company == ADM1026_COMPANY_ANALOG_DEV
+			&& (verstep & 0xf0) == ADM1026_VERSTEP_GENERIC) {
+			dev_err(&adapter->dev, ": Unrecognized stepping "
+				"0x%02x. Defaulting to ADM1026.\n", verstep);
+			kind = adm1026;
+		} else if ((verstep & 0xf0) == ADM1026_VERSTEP_GENERIC) {
+			dev_err(&adapter->dev, ": Found version/stepping "
+				"0x%02x. Assuming generic ADM1026.\n",
+				verstep);
+			kind = any_chip;
+		} else {
+			dev_dbg(&new_client->dev, ": Autodetection "
+				"failed\n");
+			/* Not an ADM1026 ... */
+			if (kind == 0)  { /* User used force=x,y */
+				dev_err(&adapter->dev, "Generic ADM1026 not "
+					"found at %d,0x%02x.  Try "
+					"force_adm1026.\n",
+					i2c_adapter_id(adapter), address);
+			}
+			err = 0;
+			goto exitfree;
+		}
+	}
+
+	/* Fill in the chip specific driver values */
+	switch (kind) {
+	case any_chip :
+		type_name = "adm1026";
+		break;
+	case adm1026 :
+		type_name = "adm1026";
+		break;
+	default :
+		dev_err(&adapter->dev, ": Internal error, invalid "
+			"kind (%d)!", kind);
+		err = -EFAULT;
+		goto exitfree;
+	}
+	strlcpy(new_client->name, type_name, I2C_NAME_SIZE);
+
+	/* Fill in the remaining client fields */
+	data->type = kind;
+	data->valid = 0;
+	init_MUTEX(&data->update_lock);
+
+	/* Tell the I2C layer a new client has arrived */
+	if ((err = i2c_attach_client(new_client)))
+		goto exitfree;
+
+	/* Set the VRM version */
+	data->vrm = i2c_which_vrm();
+
+	/* Initialize the ADM1026 chip */
+	adm1026_init_client(new_client);
+
+	/* Register sysfs hooks */
+	device_create_file(&new_client->dev, &sensor_dev_attr_in0_input.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in0_max.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in0_min.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in1_input.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in1_max.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in1_min.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in2_input.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in2_max.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in2_min.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in3_input.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in3_max.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in3_min.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in4_input.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in4_max.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in4_min.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in5_input.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in5_max.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in5_min.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in6_input.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in6_max.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in6_min.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in7_input.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in7_max.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in7_min.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in8_input.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in8_max.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in8_min.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in9_input.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in9_max.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in9_min.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in10_input.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in10_max.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in10_min.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in11_input.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in11_max.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in11_min.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in12_input.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in12_max.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in12_min.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in13_input.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in13_max.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in13_min.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in14_input.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in14_max.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in14_min.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in15_input.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in15_max.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in15_min.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in16_input.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in16_max.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in16_min.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_fan1_input.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_fan1_div.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_fan1_min.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_fan2_input.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_fan2_div.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_fan2_min.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_fan3_input.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_fan3_div.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_fan3_min.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_fan4_input.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_fan4_div.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_fan4_min.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_fan5_input.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_fan5_div.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_fan5_min.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_fan6_input.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_fan6_div.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_fan6_min.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_fan7_input.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_fan7_div.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_fan7_min.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_fan8_input.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_fan8_div.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_fan8_min.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_temp1_input.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_temp1_max.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_temp1_min.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_temp2_input.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_temp2_max.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_temp2_min.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_temp3_input.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_temp3_max.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_temp3_min.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_temp1_offset.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_temp2_offset.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_temp3_offset.dev_attr);
+	device_create_file(&new_client->dev, 
+		&sensor_dev_attr_temp1_auto_point1_temp.dev_attr);
+	device_create_file(&new_client->dev, 
+		&sensor_dev_attr_temp2_auto_point1_temp.dev_attr);
+	device_create_file(&new_client->dev, 
+		&sensor_dev_attr_temp3_auto_point1_temp.dev_attr);
+	device_create_file(&new_client->dev,
+		&sensor_dev_attr_temp1_auto_point1_temp_hyst.dev_attr);
+	device_create_file(&new_client->dev,
+		&sensor_dev_attr_temp2_auto_point1_temp_hyst.dev_attr);
+	device_create_file(&new_client->dev,
+		&sensor_dev_attr_temp3_auto_point1_temp_hyst.dev_attr);
+	device_create_file(&new_client->dev, 
+		&sensor_dev_attr_temp1_auto_point2_temp.dev_attr);
+	device_create_file(&new_client->dev, 
+		&sensor_dev_attr_temp2_auto_point2_temp.dev_attr);
+	device_create_file(&new_client->dev, 
+		&sensor_dev_attr_temp3_auto_point2_temp.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_temp1_crit.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_temp2_crit.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_temp3_crit.dev_attr);
+	device_create_file(&new_client->dev, &dev_attr_temp1_crit_enable);
+	device_create_file(&new_client->dev, &dev_attr_temp2_crit_enable);
+	device_create_file(&new_client->dev, &dev_attr_temp3_crit_enable);
+	/* vid deprecated in favour of cpu0_vid, remove after 2005-11-11 */
+	device_create_file(&new_client->dev, &dev_attr_vid);
+	device_create_file(&new_client->dev, &dev_attr_cpu0_vid);
+	device_create_file(&new_client->dev, &dev_attr_vrm);
+	device_create_file(&new_client->dev, &dev_attr_alarms);
+	device_create_file(&new_client->dev, &dev_attr_alarm_mask);
+	device_create_file(&new_client->dev, &dev_attr_gpio);
+	device_create_file(&new_client->dev, &dev_attr_gpio_mask);
+	device_create_file(&new_client->dev, &dev_attr_pwm1);
+	device_create_file(&new_client->dev, &dev_attr_pwm2);
+	device_create_file(&new_client->dev, &dev_attr_pwm3);
+	device_create_file(&new_client->dev, &dev_attr_pwm1_enable);
+	device_create_file(&new_client->dev, &dev_attr_pwm2_enable);
+	device_create_file(&new_client->dev, &dev_attr_pwm3_enable);
+	device_create_file(&new_client->dev, &dev_attr_temp1_auto_point1_pwm);
+	device_create_file(&new_client->dev, &dev_attr_temp2_auto_point1_pwm);
+	device_create_file(&new_client->dev, &dev_attr_temp3_auto_point1_pwm);
+	device_create_file(&new_client->dev, &dev_attr_temp1_auto_point2_pwm);
+	device_create_file(&new_client->dev, &dev_attr_temp2_auto_point2_pwm);
+	device_create_file(&new_client->dev, &dev_attr_temp3_auto_point2_pwm);
+	device_create_file(&new_client->dev, &dev_attr_analog_out);
+	return 0;
+
+	/* Error out and cleanup code */
+exitfree:
+	kfree(data);
+exit:
+	return err;
+}
+static int __init sm_adm1026_init(void)
+{
+	return i2c_add_driver(&adm1026_driver);
+}
+
+static void  __exit sm_adm1026_exit(void)
+{
+	i2c_del_driver(&adm1026_driver);
+}
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Philip Pokorny <ppokorny@penguincomputing.com>, "
+              "Justin Thiessen <jthiessen@penguincomputing.com>");
+MODULE_DESCRIPTION("ADM1026 driver");
+
+module_init(sm_adm1026_init);
+module_exit(sm_adm1026_exit);
diff --git a/drivers/hwmon/adm1031.c b/drivers/hwmon/adm1031.c
new file mode 100644
--- /dev/null
+++ b/drivers/hwmon/adm1031.c
@@ -0,0 +1,977 @@
+/*
+  adm1031.c - Part of lm_sensors, Linux kernel modules for hardware
+  monitoring
+  Based on lm75.c and lm85.c
+  Supports adm1030 / adm1031
+  Copyright (C) 2004 Alexandre d'Alton <alex@alexdalton.org>
+  Reworked by Jean Delvare <khali@linux-fr.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.
+*/
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+#include <linux/i2c.h>
+#include <linux/i2c-sensor.h>
+
+/* Following macros takes channel parameter starting from 0 to 2 */
+#define ADM1031_REG_FAN_SPEED(nr)	(0x08 + (nr))
+#define ADM1031_REG_FAN_DIV(nr)		(0x20  + (nr))
+#define ADM1031_REG_PWM			(0x22)
+#define ADM1031_REG_FAN_MIN(nr)		(0x10 + (nr))
+
+#define ADM1031_REG_TEMP_MAX(nr)	(0x14  + 4*(nr))
+#define ADM1031_REG_TEMP_MIN(nr)	(0x15  + 4*(nr))
+#define ADM1031_REG_TEMP_CRIT(nr)	(0x16  + 4*(nr))
+
+#define ADM1031_REG_TEMP(nr)		(0xa + (nr))
+#define ADM1031_REG_AUTO_TEMP(nr)	(0x24 + (nr))
+
+#define ADM1031_REG_STATUS(nr)		(0x2 + (nr))
+
+#define ADM1031_REG_CONF1		0x0
+#define ADM1031_REG_CONF2		0x1
+#define ADM1031_REG_EXT_TEMP		0x6
+
+#define ADM1031_CONF1_MONITOR_ENABLE	0x01	/* Monitoring enable */
+#define ADM1031_CONF1_PWM_INVERT	0x08	/* PWM Invert */
+#define ADM1031_CONF1_AUTO_MODE		0x80	/* Auto FAN */
+
+#define ADM1031_CONF2_PWM1_ENABLE	0x01
+#define ADM1031_CONF2_PWM2_ENABLE	0x02
+#define ADM1031_CONF2_TACH1_ENABLE	0x04
+#define ADM1031_CONF2_TACH2_ENABLE	0x08
+#define ADM1031_CONF2_TEMP_ENABLE(chan)	(0x10 << (chan))
+
+/* Addresses to scan */
+static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END };
+static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
+
+/* Insmod parameters */
+SENSORS_INSMOD_2(adm1030, adm1031);
+
+typedef u8 auto_chan_table_t[8][2];
+
+/* Each client has this additional data */
+struct adm1031_data {
+	struct i2c_client client;
+	struct semaphore update_lock;
+	int chip_type;
+	char valid;		/* !=0 if following fields are valid */
+	unsigned long last_updated;	/* In jiffies */
+	/* The chan_select_table contains the possible configurations for
+	 * auto fan control.
+	 */
+	auto_chan_table_t *chan_select_table;
+	u16 alarm;
+	u8 conf1;
+	u8 conf2;
+	u8 fan[2];
+	u8 fan_div[2];
+	u8 fan_min[2];
+	u8 pwm[2];
+	u8 old_pwm[2];
+	s8 temp[3];
+	u8 ext_temp[3];
+	u8 auto_temp[3];
+	u8 auto_temp_min[3];
+	u8 auto_temp_off[3];
+	u8 auto_temp_max[3];
+	s8 temp_min[3];
+	s8 temp_max[3];
+	s8 temp_crit[3];
+};
+
+static int adm1031_attach_adapter(struct i2c_adapter *adapter);
+static int adm1031_detect(struct i2c_adapter *adapter, int address, int kind);
+static void adm1031_init_client(struct i2c_client *client);
+static int adm1031_detach_client(struct i2c_client *client);
+static struct adm1031_data *adm1031_update_device(struct device *dev);
+
+/* This is the driver that will be inserted */
+static struct i2c_driver adm1031_driver = {
+	.owner = THIS_MODULE,
+	.name = "adm1031",
+	.flags = I2C_DF_NOTIFY,
+	.attach_adapter = adm1031_attach_adapter,
+	.detach_client = adm1031_detach_client,
+};
+
+static inline u8 adm1031_read_value(struct i2c_client *client, u8 reg)
+{
+	return i2c_smbus_read_byte_data(client, reg);
+}
+
+static inline int
+adm1031_write_value(struct i2c_client *client, u8 reg, unsigned int value)
+{
+	return i2c_smbus_write_byte_data(client, reg, value);
+}
+
+
+#define TEMP_TO_REG(val)		(((val) < 0 ? ((val - 500) / 1000) : \
+					((val + 500) / 1000)))
+
+#define TEMP_FROM_REG(val)		((val) * 1000)
+
+#define TEMP_FROM_REG_EXT(val, ext)	(TEMP_FROM_REG(val) + (ext) * 125)
+
+#define FAN_FROM_REG(reg, div)		((reg) ? (11250 * 60) / ((reg) * (div)) : 0)
+
+static int FAN_TO_REG(int reg, int div)
+{
+	int tmp;
+	tmp = FAN_FROM_REG(SENSORS_LIMIT(reg, 0, 65535), div);
+	return tmp > 255 ? 255 : tmp;
+}
+
+#define FAN_DIV_FROM_REG(reg)		(1<<(((reg)&0xc0)>>6))
+
+#define PWM_TO_REG(val)			(SENSORS_LIMIT((val), 0, 255) >> 4)
+#define PWM_FROM_REG(val)		((val) << 4)
+
+#define FAN_CHAN_FROM_REG(reg)		(((reg) >> 5) & 7)
+#define FAN_CHAN_TO_REG(val, reg)	\
+	(((reg) & 0x1F) | (((val) << 5) & 0xe0))
+
+#define AUTO_TEMP_MIN_TO_REG(val, reg)	\
+	((((val)/500) & 0xf8)|((reg) & 0x7))
+#define AUTO_TEMP_RANGE_FROM_REG(reg)	(5000 * (1<< ((reg)&0x7)))
+#define AUTO_TEMP_MIN_FROM_REG(reg)	(1000 * ((((reg) >> 3) & 0x1f) << 2))
+
+#define AUTO_TEMP_MIN_FROM_REG_DEG(reg)	((((reg) >> 3) & 0x1f) << 2)
+
+#define AUTO_TEMP_OFF_FROM_REG(reg)		\
+	(AUTO_TEMP_MIN_FROM_REG(reg) - 5000)
+
+#define AUTO_TEMP_MAX_FROM_REG(reg)		\
+	(AUTO_TEMP_RANGE_FROM_REG(reg) +	\
+	AUTO_TEMP_MIN_FROM_REG(reg))
+
+static int AUTO_TEMP_MAX_TO_REG(int val, int reg, int pwm)
+{
+	int ret;
+	int range = val - AUTO_TEMP_MIN_FROM_REG(reg);
+
+	range = ((val - AUTO_TEMP_MIN_FROM_REG(reg))*10)/(16 - pwm);
+	ret = ((reg & 0xf8) |
+	       (range < 10000 ? 0 :
+		range < 20000 ? 1 :
+		range < 40000 ? 2 : range < 80000 ? 3 : 4));
+	return ret;
+}
+
+/* FAN auto control */
+#define GET_FAN_AUTO_BITFIELD(data, idx)	\
+	(*(data)->chan_select_table)[FAN_CHAN_FROM_REG((data)->conf1)][idx%2]
+
+/* The tables below contains the possible values for the auto fan 
+ * control bitfields. the index in the table is the register value.
+ * MSb is the auto fan control enable bit, so the four first entries
+ * in the table disables auto fan control when both bitfields are zero.
+ */
+static auto_chan_table_t auto_channel_select_table_adm1031 = {
+	{0, 0}, {0, 0}, {0, 0}, {0, 0},
+	{2 /*0b010 */ , 4 /*0b100 */ },
+	{2 /*0b010 */ , 2 /*0b010 */ },
+	{4 /*0b100 */ , 4 /*0b100 */ },
+	{7 /*0b111 */ , 7 /*0b111 */ },
+};
+
+static auto_chan_table_t auto_channel_select_table_adm1030 = {
+	{0, 0}, {0, 0}, {0, 0}, {0, 0},
+	{2 /*0b10 */		, 0},
+	{0xff /*invalid */	, 0},
+	{0xff /*invalid */	, 0},
+	{3 /*0b11 */		, 0},
+};
+
+/* That function checks if a bitfield is valid and returns the other bitfield
+ * nearest match if no exact match where found.
+ */
+static int
+get_fan_auto_nearest(struct adm1031_data *data,
+		     int chan, u8 val, u8 reg, u8 * new_reg)
+{
+	int i;
+	int first_match = -1, exact_match = -1;
+	u8 other_reg_val =
+	    (*data->chan_select_table)[FAN_CHAN_FROM_REG(reg)][chan ? 0 : 1];
+
+	if (val == 0) {
+		*new_reg = 0;
+		return 0;
+	}
+
+	for (i = 0; i < 8; i++) {
+		if ((val == (*data->chan_select_table)[i][chan]) &&
+		    ((*data->chan_select_table)[i][chan ? 0 : 1] ==
+		     other_reg_val)) {
+			/* We found an exact match */
+			exact_match = i;
+			break;
+		} else if (val == (*data->chan_select_table)[i][chan] &&
+			   first_match == -1) {
+			/* Save the first match in case of an exact match has not been
+			 * found 
+			 */
+			first_match = i;
+		}
+	}
+
+	if (exact_match >= 0) {
+		*new_reg = exact_match;
+	} else if (first_match >= 0) {
+		*new_reg = first_match;
+	} else {
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static ssize_t show_fan_auto_channel(struct device *dev, char *buf, int nr)
+{
+	struct adm1031_data *data = adm1031_update_device(dev);
+	return sprintf(buf, "%d\n", GET_FAN_AUTO_BITFIELD(data, nr));
+}
+
+static ssize_t
+set_fan_auto_channel(struct device *dev, const char *buf, size_t count, int nr)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct adm1031_data *data = i2c_get_clientdata(client);
+	int val = simple_strtol(buf, NULL, 10);
+	u8 reg;
+	int ret;
+	u8 old_fan_mode;
+
+	old_fan_mode = data->conf1;
+
+	down(&data->update_lock);
+	
+	if ((ret = get_fan_auto_nearest(data, nr, val, data->conf1, &reg))) {
+		up(&data->update_lock);
+		return ret;
+	}
+	if (((data->conf1 = FAN_CHAN_TO_REG(reg, data->conf1)) & ADM1031_CONF1_AUTO_MODE) ^ 
+	    (old_fan_mode & ADM1031_CONF1_AUTO_MODE)) {
+		if (data->conf1 & ADM1031_CONF1_AUTO_MODE){
+			/* Switch to Auto Fan Mode 
+			 * Save PWM registers 
+			 * Set PWM registers to 33% Both */
+			data->old_pwm[0] = data->pwm[0];
+			data->old_pwm[1] = data->pwm[1];
+			adm1031_write_value(client, ADM1031_REG_PWM, 0x55);
+		} else {
+			/* Switch to Manual Mode */
+			data->pwm[0] = data->old_pwm[0];
+			data->pwm[1] = data->old_pwm[1];
+			/* Restore PWM registers */
+			adm1031_write_value(client, ADM1031_REG_PWM, 
+					    data->pwm[0] | (data->pwm[1] << 4));
+		}
+	}
+	data->conf1 = FAN_CHAN_TO_REG(reg, data->conf1);
+	adm1031_write_value(client, ADM1031_REG_CONF1, data->conf1);
+	up(&data->update_lock);
+	return count;
+}
+
+#define fan_auto_channel_offset(offset)						\
+static ssize_t show_fan_auto_channel_##offset (struct device *dev, struct device_attribute *attr, char *buf)	\
+{										\
+	return show_fan_auto_channel(dev, buf, offset - 1);			\
+}										\
+static ssize_t set_fan_auto_channel_##offset (struct device *dev, struct device_attribute *attr,		\
+	const char *buf, size_t count)						\
+{										\
+	return set_fan_auto_channel(dev, buf, count, offset - 1);		\
+}										\
+static DEVICE_ATTR(auto_fan##offset##_channel, S_IRUGO | S_IWUSR,		\
+		   show_fan_auto_channel_##offset,				\
+		   set_fan_auto_channel_##offset)
+
+fan_auto_channel_offset(1);
+fan_auto_channel_offset(2);
+
+/* Auto Temps */
+static ssize_t show_auto_temp_off(struct device *dev, char *buf, int nr)
+{
+	struct adm1031_data *data = adm1031_update_device(dev);
+	return sprintf(buf, "%d\n", 
+		       AUTO_TEMP_OFF_FROM_REG(data->auto_temp[nr]));
+}
+static ssize_t show_auto_temp_min(struct device *dev, char *buf, int nr)
+{
+	struct adm1031_data *data = adm1031_update_device(dev);
+	return sprintf(buf, "%d\n",
+		       AUTO_TEMP_MIN_FROM_REG(data->auto_temp[nr]));
+}
+static ssize_t
+set_auto_temp_min(struct device *dev, const char *buf, size_t count, int nr)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct adm1031_data *data = i2c_get_clientdata(client);
+	int val = simple_strtol(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->auto_temp[nr] = AUTO_TEMP_MIN_TO_REG(val, data->auto_temp[nr]);
+	adm1031_write_value(client, ADM1031_REG_AUTO_TEMP(nr),
+			    data->auto_temp[nr]);
+	up(&data->update_lock);
+	return count;
+}
+static ssize_t show_auto_temp_max(struct device *dev, char *buf, int nr)
+{
+	struct adm1031_data *data = adm1031_update_device(dev);
+	return sprintf(buf, "%d\n",
+		       AUTO_TEMP_MAX_FROM_REG(data->auto_temp[nr]));
+}
+static ssize_t
+set_auto_temp_max(struct device *dev, const char *buf, size_t count, int nr)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct adm1031_data *data = i2c_get_clientdata(client);
+	int val = simple_strtol(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->temp_max[nr] = AUTO_TEMP_MAX_TO_REG(val, data->auto_temp[nr], data->pwm[nr]);
+	adm1031_write_value(client, ADM1031_REG_AUTO_TEMP(nr),
+			    data->temp_max[nr]);
+	up(&data->update_lock);
+	return count;
+}
+
+#define auto_temp_reg(offset)							\
+static ssize_t show_auto_temp_##offset##_off (struct device *dev, struct device_attribute *attr, char *buf)	\
+{										\
+	return show_auto_temp_off(dev, buf, offset - 1);			\
+}										\
+static ssize_t show_auto_temp_##offset##_min (struct device *dev, struct device_attribute *attr, char *buf)	\
+{										\
+	return show_auto_temp_min(dev, buf, offset - 1);			\
+}										\
+static ssize_t show_auto_temp_##offset##_max (struct device *dev, struct device_attribute *attr, char *buf)	\
+{										\
+	return show_auto_temp_max(dev, buf, offset - 1);			\
+}										\
+static ssize_t set_auto_temp_##offset##_min (struct device *dev, struct device_attribute *attr,		\
+					     const char *buf, size_t count)	\
+{										\
+	return set_auto_temp_min(dev, buf, count, offset - 1);		\
+}										\
+static ssize_t set_auto_temp_##offset##_max (struct device *dev, struct device_attribute *attr,		\
+					     const char *buf, size_t count)	\
+{										\
+	return set_auto_temp_max(dev, buf, count, offset - 1);		\
+}										\
+static DEVICE_ATTR(auto_temp##offset##_off, S_IRUGO,				\
+		   show_auto_temp_##offset##_off, NULL);			\
+static DEVICE_ATTR(auto_temp##offset##_min, S_IRUGO | S_IWUSR,			\
+		   show_auto_temp_##offset##_min, set_auto_temp_##offset##_min);\
+static DEVICE_ATTR(auto_temp##offset##_max, S_IRUGO | S_IWUSR,			\
+		   show_auto_temp_##offset##_max, set_auto_temp_##offset##_max)
+
+auto_temp_reg(1);
+auto_temp_reg(2);
+auto_temp_reg(3);
+
+/* pwm */
+static ssize_t show_pwm(struct device *dev, char *buf, int nr)
+{
+	struct adm1031_data *data = adm1031_update_device(dev);
+	return sprintf(buf, "%d\n", PWM_FROM_REG(data->pwm[nr]));
+}
+static ssize_t
+set_pwm(struct device *dev, const char *buf, size_t count, int nr)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct adm1031_data *data = i2c_get_clientdata(client);
+	int val = simple_strtol(buf, NULL, 10);
+	int reg;
+
+	down(&data->update_lock);
+	if ((data->conf1 & ADM1031_CONF1_AUTO_MODE) && 
+	    (((val>>4) & 0xf) != 5)) {
+		/* In automatic mode, the only PWM accepted is 33% */
+		up(&data->update_lock);
+		return -EINVAL;
+	}
+	data->pwm[nr] = PWM_TO_REG(val);
+	reg = adm1031_read_value(client, ADM1031_REG_PWM);
+	adm1031_write_value(client, ADM1031_REG_PWM,
+			    nr ? ((data->pwm[nr] << 4) & 0xf0) | (reg & 0xf)
+			    : (data->pwm[nr] & 0xf) | (reg & 0xf0));
+	up(&data->update_lock);
+	return count;
+}
+
+#define pwm_reg(offset)							\
+static ssize_t show_pwm_##offset (struct device *dev, struct device_attribute *attr, char *buf)	\
+{									\
+	return show_pwm(dev, buf, offset - 1);			\
+}									\
+static ssize_t set_pwm_##offset (struct device *dev, struct device_attribute *attr,			\
+				 const char *buf, size_t count)		\
+{									\
+	return set_pwm(dev, buf, count, offset - 1);		\
+}									\
+static DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR,			\
+		   show_pwm_##offset, set_pwm_##offset)
+
+pwm_reg(1);
+pwm_reg(2);
+
+/* Fans */
+
+/*
+ * That function checks the cases where the fan reading is not
+ * relevant.  It is used to provide 0 as fan reading when the fan is
+ * not supposed to run
+ */
+static int trust_fan_readings(struct adm1031_data *data, int chan)
+{
+	int res = 0;
+
+	if (data->conf1 & ADM1031_CONF1_AUTO_MODE) {
+		switch (data->conf1 & 0x60) {
+		case 0x00:	/* remote temp1 controls fan1 remote temp2 controls fan2 */
+			res = data->temp[chan+1] >=
+			      AUTO_TEMP_MIN_FROM_REG_DEG(data->auto_temp[chan+1]);
+			break;
+		case 0x20:	/* remote temp1 controls both fans */
+			res =
+			    data->temp[1] >=
+			    AUTO_TEMP_MIN_FROM_REG_DEG(data->auto_temp[1]);
+			break;
+		case 0x40:	/* remote temp2 controls both fans */
+			res =
+			    data->temp[2] >=
+			    AUTO_TEMP_MIN_FROM_REG_DEG(data->auto_temp[2]);
+			break;
+		case 0x60:	/* max controls both fans */
+			res =
+			    data->temp[0] >=
+			    AUTO_TEMP_MIN_FROM_REG_DEG(data->auto_temp[0])
+			    || data->temp[1] >=
+			    AUTO_TEMP_MIN_FROM_REG_DEG(data->auto_temp[1])
+			    || (data->chip_type == adm1031 
+				&& data->temp[2] >=
+				AUTO_TEMP_MIN_FROM_REG_DEG(data->auto_temp[2]));
+			break;
+		}
+	} else {
+		res = data->pwm[chan] > 0;
+	}
+	return res;
+}
+
+
+static ssize_t show_fan(struct device *dev, char *buf, int nr)
+{
+	struct adm1031_data *data = adm1031_update_device(dev);
+	int value;
+
+	value = trust_fan_readings(data, nr) ? FAN_FROM_REG(data->fan[nr],
+				 FAN_DIV_FROM_REG(data->fan_div[nr])) : 0;
+	return sprintf(buf, "%d\n", value);
+}
+
+static ssize_t show_fan_div(struct device *dev, char *buf, int nr)
+{
+	struct adm1031_data *data = adm1031_update_device(dev);
+	return sprintf(buf, "%d\n", FAN_DIV_FROM_REG(data->fan_div[nr]));
+}
+static ssize_t show_fan_min(struct device *dev, char *buf, int nr)
+{
+	struct adm1031_data *data = adm1031_update_device(dev);
+	return sprintf(buf, "%d\n",
+		       FAN_FROM_REG(data->fan_min[nr],
+				    FAN_DIV_FROM_REG(data->fan_div[nr])));
+}
+static ssize_t
+set_fan_min(struct device *dev, const char *buf, size_t count, int nr)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct adm1031_data *data = i2c_get_clientdata(client);
+	int val = simple_strtol(buf, NULL, 10);
+
+	down(&data->update_lock);
+	if (val) {
+		data->fan_min[nr] = 
+			FAN_TO_REG(val, FAN_DIV_FROM_REG(data->fan_div[nr]));
+	} else {
+		data->fan_min[nr] = 0xff;
+	}
+	adm1031_write_value(client, ADM1031_REG_FAN_MIN(nr), data->fan_min[nr]);
+	up(&data->update_lock);
+	return count;
+}
+static ssize_t
+set_fan_div(struct device *dev, const char *buf, size_t count, int nr)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct adm1031_data *data = i2c_get_clientdata(client);
+	int val = simple_strtol(buf, NULL, 10);
+	u8 tmp;
+	int old_div;
+	int new_min;
+
+	tmp = val == 8 ? 0xc0 :
+	      val == 4 ? 0x80 :
+	      val == 2 ? 0x40 :	
+	      val == 1 ? 0x00 :  
+	      0xff;
+	if (tmp == 0xff)
+		return -EINVAL;
+	
+	down(&data->update_lock);
+	old_div = FAN_DIV_FROM_REG(data->fan_div[nr]);
+	data->fan_div[nr] = (tmp & 0xC0) | (0x3f & data->fan_div[nr]);
+	new_min = data->fan_min[nr] * old_div / 
+		FAN_DIV_FROM_REG(data->fan_div[nr]);
+	data->fan_min[nr] = new_min > 0xff ? 0xff : new_min;
+	data->fan[nr] = data->fan[nr] * old_div / 
+		FAN_DIV_FROM_REG(data->fan_div[nr]);
+
+	adm1031_write_value(client, ADM1031_REG_FAN_DIV(nr), 
+			    data->fan_div[nr]);
+	adm1031_write_value(client, ADM1031_REG_FAN_MIN(nr), 
+			    data->fan_min[nr]);
+	up(&data->update_lock);
+	return count;
+}
+
+#define fan_offset(offset)						\
+static ssize_t show_fan_##offset (struct device *dev, struct device_attribute *attr, char *buf)	\
+{									\
+	return show_fan(dev, buf, offset - 1);			\
+}									\
+static ssize_t show_fan_##offset##_min (struct device *dev, struct device_attribute *attr, char *buf)	\
+{									\
+	return show_fan_min(dev, buf, offset - 1);			\
+}									\
+static ssize_t show_fan_##offset##_div (struct device *dev, struct device_attribute *attr, char *buf)	\
+{									\
+	return show_fan_div(dev, buf, offset - 1);			\
+}									\
+static ssize_t set_fan_##offset##_min (struct device *dev, struct device_attribute *attr,		\
+	const char *buf, size_t count)					\
+{									\
+	return set_fan_min(dev, buf, count, offset - 1);		\
+}									\
+static ssize_t set_fan_##offset##_div (struct device *dev, struct device_attribute *attr,		\
+	const char *buf, size_t count)					\
+{									\
+	return set_fan_div(dev, buf, count, offset - 1);		\
+}									\
+static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_fan_##offset,	\
+		   NULL);						\
+static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR,		\
+		   show_fan_##offset##_min, set_fan_##offset##_min);	\
+static DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR,		\
+		   show_fan_##offset##_div, set_fan_##offset##_div);	\
+static DEVICE_ATTR(auto_fan##offset##_min_pwm, S_IRUGO | S_IWUSR,	\
+		   show_pwm_##offset, set_pwm_##offset)
+
+fan_offset(1);
+fan_offset(2);
+
+
+/* Temps */
+static ssize_t show_temp(struct device *dev, char *buf, int nr)
+{
+	struct adm1031_data *data = adm1031_update_device(dev);
+	int ext;
+	ext = nr == 0 ?
+	    ((data->ext_temp[nr] >> 6) & 0x3) * 2 :
+	    (((data->ext_temp[nr] >> ((nr - 1) * 3)) & 7));
+	return sprintf(buf, "%d\n", TEMP_FROM_REG_EXT(data->temp[nr], ext));
+}
+static ssize_t show_temp_min(struct device *dev, char *buf, int nr)
+{
+	struct adm1031_data *data = adm1031_update_device(dev);
+	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_min[nr]));
+}
+static ssize_t show_temp_max(struct device *dev, char *buf, int nr)
+{
+	struct adm1031_data *data = adm1031_update_device(dev);
+	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_max[nr]));
+}
+static ssize_t show_temp_crit(struct device *dev, char *buf, int nr)
+{
+	struct adm1031_data *data = adm1031_update_device(dev);
+	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_crit[nr]));
+}
+static ssize_t
+set_temp_min(struct device *dev, const char *buf, size_t count, int nr)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct adm1031_data *data = i2c_get_clientdata(client);
+	int val;
+
+	val = simple_strtol(buf, NULL, 10);
+	val = SENSORS_LIMIT(val, -55000, nr == 0 ? 127750 : 127875);
+	down(&data->update_lock);
+	data->temp_min[nr] = TEMP_TO_REG(val);
+	adm1031_write_value(client, ADM1031_REG_TEMP_MIN(nr),
+			    data->temp_min[nr]);
+	up(&data->update_lock);
+	return count;
+}
+static ssize_t
+set_temp_max(struct device *dev, const char *buf, size_t count, int nr)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct adm1031_data *data = i2c_get_clientdata(client);
+	int val;
+
+	val = simple_strtol(buf, NULL, 10);
+	val = SENSORS_LIMIT(val, -55000, nr == 0 ? 127750 : 127875);
+	down(&data->update_lock);
+	data->temp_max[nr] = TEMP_TO_REG(val);
+	adm1031_write_value(client, ADM1031_REG_TEMP_MAX(nr),
+			    data->temp_max[nr]);
+	up(&data->update_lock);
+	return count;
+}
+static ssize_t
+set_temp_crit(struct device *dev, const char *buf, size_t count, int nr)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct adm1031_data *data = i2c_get_clientdata(client);
+	int val;
+
+	val = simple_strtol(buf, NULL, 10);
+	val = SENSORS_LIMIT(val, -55000, nr == 0 ? 127750 : 127875);
+	down(&data->update_lock);
+	data->temp_crit[nr] = TEMP_TO_REG(val);
+	adm1031_write_value(client, ADM1031_REG_TEMP_CRIT(nr),
+			    data->temp_crit[nr]);
+	up(&data->update_lock);
+	return count;
+}
+
+#define temp_reg(offset)							\
+static ssize_t show_temp_##offset (struct device *dev, struct device_attribute *attr, char *buf)		\
+{										\
+	return show_temp(dev, buf, offset - 1);				\
+}										\
+static ssize_t show_temp_##offset##_min (struct device *dev, struct device_attribute *attr, char *buf)		\
+{										\
+	return show_temp_min(dev, buf, offset - 1);				\
+}										\
+static ssize_t show_temp_##offset##_max (struct device *dev, struct device_attribute *attr, char *buf)		\
+{										\
+	return show_temp_max(dev, buf, offset - 1);				\
+}										\
+static ssize_t show_temp_##offset##_crit (struct device *dev, struct device_attribute *attr, char *buf)	\
+{										\
+	return show_temp_crit(dev, buf, offset - 1);			\
+}										\
+static ssize_t set_temp_##offset##_min (struct device *dev, struct device_attribute *attr,			\
+					const char *buf, size_t count)		\
+{										\
+	return set_temp_min(dev, buf, count, offset - 1);			\
+}										\
+static ssize_t set_temp_##offset##_max (struct device *dev, struct device_attribute *attr,			\
+					const char *buf, size_t count)		\
+{										\
+	return set_temp_max(dev, buf, count, offset - 1);			\
+}										\
+static ssize_t set_temp_##offset##_crit (struct device *dev, struct device_attribute *attr,			\
+					 const char *buf, size_t count)		\
+{										\
+	return set_temp_crit(dev, buf, count, offset - 1);			\
+}										\
+static DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_temp_##offset,		\
+		   NULL);							\
+static DEVICE_ATTR(temp##offset##_min, S_IRUGO | S_IWUSR,			\
+		   show_temp_##offset##_min, set_temp_##offset##_min);		\
+static DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR,			\
+		   show_temp_##offset##_max, set_temp_##offset##_max);		\
+static DEVICE_ATTR(temp##offset##_crit, S_IRUGO | S_IWUSR,			\
+		   show_temp_##offset##_crit, set_temp_##offset##_crit)
+
+temp_reg(1);
+temp_reg(2);
+temp_reg(3);
+
+/* Alarms */
+static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct adm1031_data *data = adm1031_update_device(dev);
+	return sprintf(buf, "%d\n", data->alarm);
+}
+
+static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
+
+
+static int adm1031_attach_adapter(struct i2c_adapter *adapter)
+{
+	if (!(adapter->class & I2C_CLASS_HWMON))
+		return 0;
+	return i2c_detect(adapter, &addr_data, adm1031_detect);
+}
+
+/* This function is called by i2c_detect */
+static int adm1031_detect(struct i2c_adapter *adapter, int address, int kind)
+{
+	struct i2c_client *new_client;
+	struct adm1031_data *data;
+	int err = 0;
+	const char *name = "";
+
+	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+		goto exit;
+
+	if (!(data = kmalloc(sizeof(struct adm1031_data), GFP_KERNEL))) {
+		err = -ENOMEM;
+		goto exit;
+	}
+	memset(data, 0, sizeof(struct adm1031_data));
+
+	new_client = &data->client;
+	i2c_set_clientdata(new_client, data);
+	new_client->addr = address;
+	new_client->adapter = adapter;
+	new_client->driver = &adm1031_driver;
+	new_client->flags = 0;
+
+	if (kind < 0) {
+		int id, co;
+		id = i2c_smbus_read_byte_data(new_client, 0x3d);
+		co = i2c_smbus_read_byte_data(new_client, 0x3e);
+
+		if (!((id == 0x31 || id == 0x30) && co == 0x41))
+			goto exit_free;
+		kind = (id == 0x30) ? adm1030 : adm1031;
+	}
+
+	if (kind <= 0)
+		kind = adm1031;
+
+	/* Given the detected chip type, set the chip name and the
+	 * auto fan control helper table. */
+	if (kind == adm1030) {
+		name = "adm1030";
+		data->chan_select_table = &auto_channel_select_table_adm1030;
+	} else if (kind == adm1031) {
+		name = "adm1031";
+		data->chan_select_table = &auto_channel_select_table_adm1031;
+	}
+	data->chip_type = kind;
+
+	strlcpy(new_client->name, name, I2C_NAME_SIZE);
+	data->valid = 0;
+	init_MUTEX(&data->update_lock);
+
+	/* Tell the I2C layer a new client has arrived */
+	if ((err = i2c_attach_client(new_client)))
+		goto exit_free;
+
+	/* Initialize the ADM1031 chip */
+	adm1031_init_client(new_client);
+
+	/* Register sysfs hooks */
+	device_create_file(&new_client->dev, &dev_attr_fan1_input);
+	device_create_file(&new_client->dev, &dev_attr_fan1_div);
+	device_create_file(&new_client->dev, &dev_attr_fan1_min);
+	device_create_file(&new_client->dev, &dev_attr_pwm1);
+	device_create_file(&new_client->dev, &dev_attr_auto_fan1_channel);
+	device_create_file(&new_client->dev, &dev_attr_temp1_input);
+	device_create_file(&new_client->dev, &dev_attr_temp1_min);
+	device_create_file(&new_client->dev, &dev_attr_temp1_max);
+	device_create_file(&new_client->dev, &dev_attr_temp1_crit);
+	device_create_file(&new_client->dev, &dev_attr_temp2_input);
+	device_create_file(&new_client->dev, &dev_attr_temp2_min);
+	device_create_file(&new_client->dev, &dev_attr_temp2_max);
+	device_create_file(&new_client->dev, &dev_attr_temp2_crit);
+
+	device_create_file(&new_client->dev, &dev_attr_auto_temp1_off);
+	device_create_file(&new_client->dev, &dev_attr_auto_temp1_min);
+	device_create_file(&new_client->dev, &dev_attr_auto_temp1_max);
+
+	device_create_file(&new_client->dev, &dev_attr_auto_temp2_off);
+	device_create_file(&new_client->dev, &dev_attr_auto_temp2_min);
+	device_create_file(&new_client->dev, &dev_attr_auto_temp2_max);
+
+	device_create_file(&new_client->dev, &dev_attr_auto_fan1_min_pwm);
+
+	device_create_file(&new_client->dev, &dev_attr_alarms);
+
+	if (kind == adm1031) {
+		device_create_file(&new_client->dev, &dev_attr_fan2_input);
+		device_create_file(&new_client->dev, &dev_attr_fan2_div);
+		device_create_file(&new_client->dev, &dev_attr_fan2_min);
+		device_create_file(&new_client->dev, &dev_attr_pwm2);
+		device_create_file(&new_client->dev,
+				   &dev_attr_auto_fan2_channel);
+		device_create_file(&new_client->dev, &dev_attr_temp3_input);
+		device_create_file(&new_client->dev, &dev_attr_temp3_min);
+		device_create_file(&new_client->dev, &dev_attr_temp3_max);
+		device_create_file(&new_client->dev, &dev_attr_temp3_crit);
+		device_create_file(&new_client->dev, &dev_attr_auto_temp3_off);
+		device_create_file(&new_client->dev, &dev_attr_auto_temp3_min);
+		device_create_file(&new_client->dev, &dev_attr_auto_temp3_max);
+		device_create_file(&new_client->dev, &dev_attr_auto_fan2_min_pwm);
+	}
+
+	return 0;
+
+exit_free:
+	kfree(data);
+exit:
+	return err;
+}
+
+static int adm1031_detach_client(struct i2c_client *client)
+{
+	int ret;
+	if ((ret = i2c_detach_client(client)) != 0) {
+		return ret;
+	}
+	kfree(i2c_get_clientdata(client));
+	return 0;
+}
+
+static void adm1031_init_client(struct i2c_client *client)
+{
+	unsigned int read_val;
+	unsigned int mask;
+	struct adm1031_data *data = i2c_get_clientdata(client);
+
+	mask = (ADM1031_CONF2_PWM1_ENABLE | ADM1031_CONF2_TACH1_ENABLE);
+	if (data->chip_type == adm1031) {
+		mask |= (ADM1031_CONF2_PWM2_ENABLE |
+			ADM1031_CONF2_TACH2_ENABLE);
+	} 
+	/* Initialize the ADM1031 chip (enables fan speed reading ) */
+	read_val = adm1031_read_value(client, ADM1031_REG_CONF2);
+	if ((read_val | mask) != read_val) {
+	    adm1031_write_value(client, ADM1031_REG_CONF2, read_val | mask);
+	}
+
+	read_val = adm1031_read_value(client, ADM1031_REG_CONF1);
+	if ((read_val | ADM1031_CONF1_MONITOR_ENABLE) != read_val) {
+	    adm1031_write_value(client, ADM1031_REG_CONF1, read_val |
+				ADM1031_CONF1_MONITOR_ENABLE);
+	}
+
+}
+
+static struct adm1031_data *adm1031_update_device(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct adm1031_data *data = i2c_get_clientdata(client);
+	int chan;
+
+	down(&data->update_lock);
+
+	if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
+	    || !data->valid) {
+
+		dev_dbg(&client->dev, "Starting adm1031 update\n");
+		for (chan = 0;
+		     chan < ((data->chip_type == adm1031) ? 3 : 2); chan++) {
+			u8 oldh, newh;
+
+			oldh =
+			    adm1031_read_value(client, ADM1031_REG_TEMP(chan));
+			data->ext_temp[chan] =
+			    adm1031_read_value(client, ADM1031_REG_EXT_TEMP);
+			newh =
+			    adm1031_read_value(client, ADM1031_REG_TEMP(chan));
+			if (newh != oldh) {
+				data->ext_temp[chan] =
+				    adm1031_read_value(client,
+						       ADM1031_REG_EXT_TEMP);
+#ifdef DEBUG
+				oldh =
+				    adm1031_read_value(client,
+						       ADM1031_REG_TEMP(chan));
+
+				/* oldh is actually newer */
+				if (newh != oldh)
+					dev_warn(&client->dev,
+						 "Remote temperature may be "
+						 "wrong.\n");
+#endif
+			}
+			data->temp[chan] = newh;
+
+			data->temp_min[chan] =
+			    adm1031_read_value(client,
+					       ADM1031_REG_TEMP_MIN(chan));
+			data->temp_max[chan] =
+			    adm1031_read_value(client,
+					       ADM1031_REG_TEMP_MAX(chan));
+			data->temp_crit[chan] =
+			    adm1031_read_value(client,
+					       ADM1031_REG_TEMP_CRIT(chan));
+			data->auto_temp[chan] =
+			    adm1031_read_value(client,
+					       ADM1031_REG_AUTO_TEMP(chan));
+
+		}
+
+		data->conf1 = adm1031_read_value(client, ADM1031_REG_CONF1);
+		data->conf2 = adm1031_read_value(client, ADM1031_REG_CONF2);
+
+		data->alarm = adm1031_read_value(client, ADM1031_REG_STATUS(0))
+			     | (adm1031_read_value(client, ADM1031_REG_STATUS(1))
+				<< 8);
+		if (data->chip_type == adm1030) {
+			data->alarm &= 0xc0ff;
+		}
+		
+		for (chan=0; chan<(data->chip_type == adm1030 ? 1 : 2); chan++) {
+			data->fan_div[chan] =
+			    adm1031_read_value(client, ADM1031_REG_FAN_DIV(chan));
+			data->fan_min[chan] =
+			    adm1031_read_value(client, ADM1031_REG_FAN_MIN(chan));
+			data->fan[chan] =
+			    adm1031_read_value(client, ADM1031_REG_FAN_SPEED(chan));
+			data->pwm[chan] =
+			    0xf & (adm1031_read_value(client, ADM1031_REG_PWM) >> 
+				   (4*chan));
+		}
+		data->last_updated = jiffies;
+		data->valid = 1;
+	}
+
+	up(&data->update_lock);
+
+	return data;
+}
+
+static int __init sensors_adm1031_init(void)
+{
+	return i2c_add_driver(&adm1031_driver);
+}
+
+static void __exit sensors_adm1031_exit(void)
+{
+	i2c_del_driver(&adm1031_driver);
+}
+
+MODULE_AUTHOR("Alexandre d'Alton <alex@alexdalton.org>");
+MODULE_DESCRIPTION("ADM1031/ADM1030 driver");
+MODULE_LICENSE("GPL");
+
+module_init(sensors_adm1031_init);
+module_exit(sensors_adm1031_exit);
diff --git a/drivers/hwmon/adm9240.c b/drivers/hwmon/adm9240.c
new file mode 100644
--- /dev/null
+++ b/drivers/hwmon/adm9240.c
@@ -0,0 +1,791 @@
+/*
+ * adm9240.c	Part of lm_sensors, Linux kernel modules for hardware
+ * 		monitoring
+ *
+ * Copyright (C) 1999	Frodo Looijaard <frodol@dds.nl>
+ *			Philip Edelbrock <phil@netroedge.com>
+ * Copyright (C) 2003	Michiel Rook <michiel@grendelproject.nl>
+ * Copyright (C) 2005	Grant Coady <gcoady@gmail.com> with valuable
+ * 				guidance from Jean Delvare
+ *
+ * Driver supports	Analog Devices		ADM9240
+ *			Dallas Semiconductor	DS1780
+ *			National Semiconductor	LM81
+ *
+ * ADM9240 is the reference, DS1780 and LM81 are register compatibles
+ *
+ * Voltage	Six inputs are scaled by chip, VID also reported
+ * Temperature	Chip temperature to 0.5'C, maximum and max_hysteris
+ * Fans		2 fans, low speed alarm, automatic fan clock divider
+ * Alarms	16-bit map of active alarms
+ * Analog Out	0..1250 mV output
+ *
+ * Chassis Intrusion: clear CI latch with 'echo 1 > chassis_clear'
+ *
+ * Test hardware: Intel SE440BX-2 desktop motherboard --Grant
+ *
+ * LM81 extended temp reading not implemented
+ *
+ * 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 <linux/init.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/i2c-sensor.h>
+#include <linux/i2c-vid.h>
+
+/* Addresses to scan */
+static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f,
+					I2C_CLIENT_END };
+
+static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
+
+/* Insmod parameters */
+SENSORS_INSMOD_3(adm9240, ds1780, lm81);
+
+/* ADM9240 registers */
+#define ADM9240_REG_MAN_ID		0x3e
+#define ADM9240_REG_DIE_REV		0x3f
+#define ADM9240_REG_CONFIG		0x40
+
+#define ADM9240_REG_IN(nr)		(0x20 + (nr))   /* 0..5 */
+#define ADM9240_REG_IN_MAX(nr)		(0x2b + (nr) * 2)
+#define ADM9240_REG_IN_MIN(nr)		(0x2c + (nr) * 2)
+#define ADM9240_REG_FAN(nr)		(0x28 + (nr))   /* 0..1 */
+#define ADM9240_REG_FAN_MIN(nr)		(0x3b + (nr))
+#define ADM9240_REG_INT(nr)		(0x41 + (nr))
+#define ADM9240_REG_INT_MASK(nr)	(0x43 + (nr))
+#define ADM9240_REG_TEMP		0x27
+#define ADM9240_REG_TEMP_HIGH		0x39
+#define ADM9240_REG_TEMP_HYST		0x3a
+#define ADM9240_REG_ANALOG_OUT		0x19
+#define ADM9240_REG_CHASSIS_CLEAR	0x46
+#define ADM9240_REG_VID_FAN_DIV		0x47
+#define ADM9240_REG_I2C_ADDR		0x48
+#define ADM9240_REG_VID4		0x49
+#define ADM9240_REG_TEMP_CONF		0x4b
+
+/* generalised scaling with integer rounding */
+static inline int SCALE(long val, int mul, int div)
+{
+	if (val < 0)
+		return (val * mul - div / 2) / div;
+	else
+		return (val * mul + div / 2) / div;
+}
+
+/* adm9240 internally scales voltage measurements */
+static const u16 nom_mv[] = { 2500, 2700, 3300, 5000, 12000, 2700 };
+
+static inline unsigned int IN_FROM_REG(u8 reg, int n)
+{
+	return SCALE(reg, nom_mv[n], 192);
+}
+
+static inline u8 IN_TO_REG(unsigned long val, int n)
+{
+	return SENSORS_LIMIT(SCALE(val, 192, nom_mv[n]), 0, 255);
+}
+
+/* temperature range: -40..125, 127 disables temperature alarm */
+static inline s8 TEMP_TO_REG(long val)
+{
+	return SENSORS_LIMIT(SCALE(val, 1, 1000), -40, 127);
+}
+
+/* two fans, each with low fan speed limit */
+static inline unsigned int FAN_FROM_REG(u8 reg, u8 div)
+{
+	if (!reg) /* error */
+		return -1;
+
+	if (reg == 255)
+		return 0;
+
+	return SCALE(1350000, 1, reg * div);
+}
+
+/* analog out 0..1250mV */
+static inline u8 AOUT_TO_REG(unsigned long val)
+{
+	return SENSORS_LIMIT(SCALE(val, 255, 1250), 0, 255);
+}
+
+static inline unsigned int AOUT_FROM_REG(u8 reg)
+{
+	return SCALE(reg, 1250, 255);
+}
+
+static int adm9240_attach_adapter(struct i2c_adapter *adapter);
+static int adm9240_detect(struct i2c_adapter *adapter, int address, int kind);
+static void adm9240_init_client(struct i2c_client *client);
+static int adm9240_detach_client(struct i2c_client *client);
+static struct adm9240_data *adm9240_update_device(struct device *dev);
+
+/* driver data */
+static struct i2c_driver adm9240_driver = {
+	.owner		= THIS_MODULE,
+	.name		= "adm9240",
+	.id		= I2C_DRIVERID_ADM9240,
+	.flags		= I2C_DF_NOTIFY,
+	.attach_adapter	= adm9240_attach_adapter,
+	.detach_client	= adm9240_detach_client,
+};
+
+/* per client data */
+struct adm9240_data {
+	enum chips type;
+	struct i2c_client client;
+	struct semaphore update_lock;
+	char valid;
+	unsigned long last_updated_measure;
+	unsigned long last_updated_config;
+
+	u8 in[6];		/* ro	in0_input */
+	u8 in_max[6];		/* rw	in0_max */
+	u8 in_min[6];		/* rw	in0_min */
+	u8 fan[2];		/* ro	fan1_input */
+	u8 fan_min[2];		/* rw	fan1_min */
+	u8 fan_div[2];		/* rw	fan1_div, read-only accessor */
+	s16 temp;		/* ro	temp1_input, 9-bit sign-extended */
+	s8 temp_high;		/* rw	temp1_max */
+	s8 temp_hyst;		/* rw	temp1_max_hyst */
+	u16 alarms;		/* ro	alarms */
+	u8 aout;		/* rw	aout_output */
+	u8 vid;			/* ro	vid */
+	u8 vrm;			/* --	vrm set on startup, no accessor */
+};
+
+/* i2c byte read/write interface */
+static int adm9240_read_value(struct i2c_client *client, u8 reg)
+{
+	return i2c_smbus_read_byte_data(client, reg);
+}
+
+static int adm9240_write_value(struct i2c_client *client, u8 reg, u8 value)
+{
+	return i2c_smbus_write_byte_data(client, reg, value);
+}
+
+/*** sysfs accessors ***/
+
+/* temperature */
+#define show_temp(value, scale)					\
+static ssize_t show_##value(struct device *dev,			\
+			    struct device_attribute *attr,	\
+			    char *buf)				\
+{								\
+	struct adm9240_data *data = adm9240_update_device(dev);	\
+	return sprintf(buf, "%d\n", data->value * scale);	\
+}
+show_temp(temp_high, 1000);
+show_temp(temp_hyst, 1000);
+show_temp(temp, 500); /* 0.5'C per bit */
+
+#define set_temp(value, reg)					\
+static ssize_t set_##value(struct device *dev, 			\
+			   struct device_attribute *attr,	\
+			   const char *buf, size_t count)	\
+{								\
+	struct i2c_client *client = to_i2c_client(dev);		\
+	struct adm9240_data *data = adm9240_update_device(dev);	\
+	long temp = simple_strtoul(buf, NULL, 10);		\
+								\
+	down(&data->update_lock);				\
+	data->value = TEMP_TO_REG(temp);			\
+	adm9240_write_value(client, reg, data->value);		\
+	up(&data->update_lock);					\
+	return count;						\
+}
+
+set_temp(temp_high, ADM9240_REG_TEMP_HIGH);
+set_temp(temp_hyst, ADM9240_REG_TEMP_HYST);
+
+static DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO,
+		show_temp_high, set_temp_high);
+static DEVICE_ATTR(temp1_max_hyst, S_IWUSR | S_IRUGO,
+		show_temp_hyst, set_temp_hyst);
+static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL);
+
+/* voltage */
+static ssize_t show_in(struct device *dev, char *buf, int nr)
+{
+	struct adm9240_data *data = adm9240_update_device(dev);
+	return sprintf(buf, "%d\n", IN_FROM_REG(data->in[nr], nr));
+}
+
+static ssize_t show_in_min(struct device *dev, char *buf, int nr)
+{
+	struct adm9240_data *data = adm9240_update_device(dev);
+	return sprintf(buf, "%d\n", IN_FROM_REG(data->in_min[nr], nr));
+}
+
+static ssize_t show_in_max(struct device *dev, char *buf, int nr)
+{
+	struct adm9240_data *data = adm9240_update_device(dev);
+	return sprintf(buf, "%d\n", IN_FROM_REG(data->in_max[nr], nr));
+}
+
+static ssize_t set_in_min(struct device *dev, const char *buf,
+		size_t count, int nr)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct adm9240_data *data = i2c_get_clientdata(client);
+	unsigned long val = simple_strtoul(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->in_min[nr] = IN_TO_REG(val, nr);
+	adm9240_write_value(client, ADM9240_REG_IN_MIN(nr), data->in_min[nr]);
+	up(&data->update_lock);
+	return count;
+}
+
+static ssize_t set_in_max(struct device *dev, const char *buf,
+		size_t count, int nr)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct adm9240_data *data = i2c_get_clientdata(client);
+	unsigned long val = simple_strtoul(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->in_max[nr] = IN_TO_REG(val, nr);
+	adm9240_write_value(client, ADM9240_REG_IN_MAX(nr), data->in_max[nr]);
+	up(&data->update_lock);
+	return count;
+}
+
+#define show_in_offset(offset)						\
+static ssize_t show_in##offset(struct device *dev,			\
+			       struct device_attribute *attr,		\
+			       char *buf)				\
+{									\
+	return show_in(dev, buf, offset);				\
+}									\
+static DEVICE_ATTR(in##offset##_input, S_IRUGO, show_in##offset, NULL);	\
+static ssize_t show_in##offset##_min(struct device *dev,		\
+				     struct device_attribute *attr,	\
+				     char *buf)				\
+{									\
+	return show_in_min(dev, buf, offset);				\
+}									\
+static ssize_t show_in##offset##_max(struct device *dev,		\
+				     struct device_attribute *attr,	\
+				     char *buf)				\
+{									\
+	return show_in_max(dev, buf, offset);				\
+}									\
+static ssize_t								\
+set_in##offset##_min(struct device *dev,				\
+		     struct device_attribute *attr, const char *buf,	\
+		     size_t count)					\
+{									\
+	return set_in_min(dev, buf, count, offset);			\
+}									\
+static ssize_t								\
+set_in##offset##_max(struct device *dev,				\
+		     struct device_attribute *attr, const char *buf,	\
+		     size_t count)					\
+{									\
+	return set_in_max(dev, buf, count, offset);			\
+}									\
+static DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR,			\
+		show_in##offset##_min, set_in##offset##_min);		\
+static DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR,			\
+		show_in##offset##_max, set_in##offset##_max);
+
+show_in_offset(0);
+show_in_offset(1);
+show_in_offset(2);
+show_in_offset(3);
+show_in_offset(4);
+show_in_offset(5);
+
+/* fans */
+static ssize_t show_fan(struct device *dev, char *buf, int nr)
+{
+	struct adm9240_data *data = adm9240_update_device(dev);
+	return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[nr],
+				1 << data->fan_div[nr]));
+}
+
+static ssize_t show_fan_min(struct device *dev, char *buf, int nr)
+{
+	struct adm9240_data *data = adm9240_update_device(dev);
+	return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan_min[nr],
+				1 << data->fan_div[nr]));
+}
+
+static ssize_t show_fan_div(struct device *dev, char *buf, int nr)
+{
+	struct adm9240_data *data = adm9240_update_device(dev);
+	return sprintf(buf, "%d\n", 1 << data->fan_div[nr]);
+}
+
+/* write new fan div, callers must hold data->update_lock */
+static void adm9240_write_fan_div(struct i2c_client *client, int nr,
+		u8 fan_div)
+{
+	u8 reg, old, shift = (nr + 2) * 2;
+
+	reg = adm9240_read_value(client, ADM9240_REG_VID_FAN_DIV);
+	old = (reg >> shift) & 3;
+	reg &= ~(3 << shift);
+	reg |= (fan_div << shift);
+	adm9240_write_value(client, ADM9240_REG_VID_FAN_DIV, reg);
+	dev_dbg(&client->dev, "fan%d clock divider changed from %u "
+			"to %u\n", nr + 1, 1 << old, 1 << fan_div);
+}
+
+/* 
+ * set fan speed low limit:
+ *
+ * - value is zero: disable fan speed low limit alarm
+ *
+ * - value is below fan speed measurement range: enable fan speed low
+ *   limit alarm to be asserted while fan speed too slow to measure
+ *
+ * - otherwise: select fan clock divider to suit fan speed low limit,
+ *   measurement code may adjust registers to ensure fan speed reading
+ */
+static ssize_t set_fan_min(struct device *dev, const char *buf,
+		size_t count, int nr)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct adm9240_data *data = i2c_get_clientdata(client);
+	unsigned long val = simple_strtoul(buf, NULL, 10);
+	u8 new_div;
+
+	down(&data->update_lock);
+
+	if (!val) {
+		data->fan_min[nr] = 255;
+		new_div = data->fan_div[nr];
+
+		dev_dbg(&client->dev, "fan%u low limit set disabled\n",
+				nr + 1);
+
+	} else if (val < 1350000 / (8 * 254)) {
+		new_div = 3;
+		data->fan_min[nr] = 254;
+
+		dev_dbg(&client->dev, "fan%u low limit set minimum %u\n",
+				nr + 1, FAN_FROM_REG(254, 1 << new_div));
+
+	} else {
+		unsigned int new_min = 1350000 / val;
+
+		new_div = 0;
+		while (new_min > 192 && new_div < 3) {
+			new_div++;
+			new_min /= 2;
+		}
+		if (!new_min) /* keep > 0 */
+			new_min++;
+
+		data->fan_min[nr] = new_min;
+
+		dev_dbg(&client->dev, "fan%u low limit set fan speed %u\n",
+				nr + 1, FAN_FROM_REG(new_min, 1 << new_div));
+	}
+
+	if (new_div != data->fan_div[nr]) {
+		data->fan_div[nr] = new_div;
+		adm9240_write_fan_div(client, nr, new_div);
+	}
+	adm9240_write_value(client, ADM9240_REG_FAN_MIN(nr),
+			data->fan_min[nr]);
+
+	up(&data->update_lock);
+	return count;
+}
+
+#define show_fan_offset(offset)						\
+static ssize_t show_fan_##offset (struct device *dev,			\
+				  struct device_attribute *attr,	\
+				  char *buf)				\
+{									\
+return show_fan(dev, buf, offset - 1);					\
+}									\
+static ssize_t show_fan_##offset##_div (struct device *dev,		\
+					struct device_attribute *attr,	\
+					char *buf)			\
+{									\
+return show_fan_div(dev, buf, offset - 1);				\
+}									\
+static ssize_t show_fan_##offset##_min (struct device *dev,		\
+					struct device_attribute *attr,	\
+					char *buf)			\
+{									\
+return show_fan_min(dev, buf, offset - 1);				\
+}									\
+static ssize_t set_fan_##offset##_min (struct device *dev, 		\
+				       struct device_attribute *attr,	\
+				       const char *buf, size_t count)	\
+{									\
+return set_fan_min(dev, buf, count, offset - 1);			\
+}									\
+static DEVICE_ATTR(fan##offset##_input, S_IRUGO, 			\
+		show_fan_##offset, NULL);				\
+static DEVICE_ATTR(fan##offset##_div, S_IRUGO, 				\
+		show_fan_##offset##_div, NULL);				\
+static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, 		\
+		show_fan_##offset##_min, set_fan_##offset##_min);
+
+show_fan_offset(1);
+show_fan_offset(2);
+
+/* alarms */
+static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct adm9240_data *data = adm9240_update_device(dev);
+	return sprintf(buf, "%u\n", data->alarms);
+}
+static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
+
+/* vid */
+static ssize_t show_vid(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct adm9240_data *data = adm9240_update_device(dev);
+	return sprintf(buf, "%d\n", vid_from_reg(data->vid, data->vrm));
+}
+static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL);
+
+/* analog output */
+static ssize_t show_aout(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct adm9240_data *data = adm9240_update_device(dev);
+	return sprintf(buf, "%d\n", AOUT_FROM_REG(data->aout));
+}
+
+static ssize_t set_aout(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct adm9240_data *data = i2c_get_clientdata(client);
+	unsigned long val = simple_strtol(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->aout = AOUT_TO_REG(val);
+	adm9240_write_value(client, ADM9240_REG_ANALOG_OUT, data->aout);
+	up(&data->update_lock);
+	return count;
+}
+static DEVICE_ATTR(aout_output, S_IRUGO | S_IWUSR, show_aout, set_aout);
+
+/* chassis_clear */
+static ssize_t chassis_clear(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	unsigned long val = simple_strtol(buf, NULL, 10);
+
+	if (val == 1) {
+		adm9240_write_value(client, ADM9240_REG_CHASSIS_CLEAR, 0x80);
+		dev_dbg(&client->dev, "chassis intrusion latch cleared\n");
+	}
+	return count;
+}
+static DEVICE_ATTR(chassis_clear, S_IWUSR, NULL, chassis_clear);
+
+
+/*** sensor chip detect and driver install ***/
+
+static int adm9240_detect(struct i2c_adapter *adapter, int address, int kind)
+{
+	struct i2c_client *new_client;
+	struct adm9240_data *data;
+	int err = 0;
+	const char *name = "";
+	u8 man_id, die_rev;
+
+	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+		goto exit;
+
+	if (!(data = kmalloc(sizeof(struct adm9240_data), GFP_KERNEL))) {
+		err = -ENOMEM;
+		goto exit;
+	}
+	memset(data, 0, sizeof(struct adm9240_data));
+
+	new_client = &data->client;
+	i2c_set_clientdata(new_client, data);
+	new_client->addr = address;
+	new_client->adapter = adapter;
+	new_client->driver = &adm9240_driver;
+	new_client->flags = 0;
+
+	if (kind == 0) {
+		kind = adm9240;
+	}
+
+	if (kind < 0) {
+
+		/* verify chip: reg address should match i2c address */
+		if (adm9240_read_value(new_client, ADM9240_REG_I2C_ADDR)
+				!= address) {
+			dev_err(&adapter->dev, "detect fail: address match, "
+					"0x%02x\n", address);
+			goto exit_free;
+		}
+
+		/* check known chip manufacturer */
+		man_id = adm9240_read_value(new_client, ADM9240_REG_MAN_ID);
+
+		if (man_id == 0x23) {
+			kind = adm9240;
+		} else if (man_id == 0xda) {
+			kind = ds1780;
+		} else if (man_id == 0x01) {
+			kind = lm81;
+		} else {
+			dev_err(&adapter->dev, "detect fail: unknown manuf, "
+					"0x%02x\n", man_id);
+			goto exit_free;
+		}
+
+		/* successful detect, print chip info */
+		die_rev = adm9240_read_value(new_client, ADM9240_REG_DIE_REV);
+		dev_info(&adapter->dev, "found %s revision %u\n",
+				man_id == 0x23 ? "ADM9240" :
+				man_id == 0xda ? "DS1780" : "LM81", die_rev);
+	}
+
+	/* either forced or detected chip kind */
+	if (kind == adm9240) {
+		name = "adm9240";
+	} else if (kind == ds1780) {
+		name = "ds1780";
+	} else if (kind == lm81) {
+		name = "lm81";
+	}
+
+	/* fill in the remaining client fields and attach */
+	strlcpy(new_client->name, name, I2C_NAME_SIZE);
+	data->type = kind;
+	init_MUTEX(&data->update_lock);
+
+	if ((err = i2c_attach_client(new_client)))
+		goto exit_free;
+
+	adm9240_init_client(new_client);
+
+	/* populate sysfs filesystem */
+	device_create_file(&new_client->dev, &dev_attr_in0_input);
+	device_create_file(&new_client->dev, &dev_attr_in0_min);
+	device_create_file(&new_client->dev, &dev_attr_in0_max);
+	device_create_file(&new_client->dev, &dev_attr_in1_input);
+	device_create_file(&new_client->dev, &dev_attr_in1_min);
+	device_create_file(&new_client->dev, &dev_attr_in1_max);
+	device_create_file(&new_client->dev, &dev_attr_in2_input);
+	device_create_file(&new_client->dev, &dev_attr_in2_min);
+	device_create_file(&new_client->dev, &dev_attr_in2_max);
+	device_create_file(&new_client->dev, &dev_attr_in3_input);
+	device_create_file(&new_client->dev, &dev_attr_in3_min);
+	device_create_file(&new_client->dev, &dev_attr_in3_max);
+	device_create_file(&new_client->dev, &dev_attr_in4_input);
+	device_create_file(&new_client->dev, &dev_attr_in4_min);
+	device_create_file(&new_client->dev, &dev_attr_in4_max);
+	device_create_file(&new_client->dev, &dev_attr_in5_input);
+	device_create_file(&new_client->dev, &dev_attr_in5_min);
+	device_create_file(&new_client->dev, &dev_attr_in5_max);
+	device_create_file(&new_client->dev, &dev_attr_temp1_max);
+	device_create_file(&new_client->dev, &dev_attr_temp1_max_hyst);
+	device_create_file(&new_client->dev, &dev_attr_temp1_input);
+	device_create_file(&new_client->dev, &dev_attr_fan1_input);
+	device_create_file(&new_client->dev, &dev_attr_fan1_div);
+	device_create_file(&new_client->dev, &dev_attr_fan1_min);
+	device_create_file(&new_client->dev, &dev_attr_fan2_input);
+	device_create_file(&new_client->dev, &dev_attr_fan2_div);
+	device_create_file(&new_client->dev, &dev_attr_fan2_min);
+	device_create_file(&new_client->dev, &dev_attr_alarms);
+	device_create_file(&new_client->dev, &dev_attr_aout_output);
+	device_create_file(&new_client->dev, &dev_attr_chassis_clear);
+	device_create_file(&new_client->dev, &dev_attr_cpu0_vid);
+
+	return 0;
+exit_free:
+	kfree(data);
+exit:
+	return err;
+}
+
+static int adm9240_attach_adapter(struct i2c_adapter *adapter)
+{
+	if (!(adapter->class & I2C_CLASS_HWMON))
+		return 0;
+	return i2c_detect(adapter, &addr_data, adm9240_detect);
+}
+
+static int adm9240_detach_client(struct i2c_client *client)
+{
+	int err;
+
+	if ((err = i2c_detach_client(client))) {
+		dev_err(&client->dev, "Client deregistration failed, "
+				"client not detached.\n");
+		return err;
+	}
+
+	kfree(i2c_get_clientdata(client));
+	return 0;
+}
+
+static void adm9240_init_client(struct i2c_client *client)
+{
+	struct adm9240_data *data = i2c_get_clientdata(client);
+	u8 conf = adm9240_read_value(client, ADM9240_REG_CONFIG);
+	u8 mode = adm9240_read_value(client, ADM9240_REG_TEMP_CONF) & 3;
+
+	data->vrm = i2c_which_vrm(); /* need this to report vid as mV */
+
+	dev_info(&client->dev, "Using VRM: %d.%d\n", data->vrm / 10,
+			data->vrm % 10);
+
+	if (conf & 1) { /* measurement cycle running: report state */
+
+		dev_info(&client->dev, "status: config 0x%02x mode %u\n",
+				conf, mode);
+
+	} else { /* cold start: open limits before starting chip */
+		int i;
+
+		for (i = 0; i < 6; i++)
+		{
+			adm9240_write_value(client,
+					ADM9240_REG_IN_MIN(i), 0);
+			adm9240_write_value(client,
+					ADM9240_REG_IN_MAX(i), 255);
+		}
+		adm9240_write_value(client, ADM9240_REG_FAN_MIN(0), 255);
+		adm9240_write_value(client, ADM9240_REG_FAN_MIN(1), 255);
+		adm9240_write_value(client, ADM9240_REG_TEMP_HIGH, 127);
+		adm9240_write_value(client, ADM9240_REG_TEMP_HYST, 127);
+
+		/* start measurement cycle */
+		adm9240_write_value(client, ADM9240_REG_CONFIG, 1);
+
+		dev_info(&client->dev, "cold start: config was 0x%02x "
+				"mode %u\n", conf, mode);
+	}
+}
+
+static struct adm9240_data *adm9240_update_device(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct adm9240_data *data = i2c_get_clientdata(client);
+	int i;
+
+	down(&data->update_lock);
+
+	/* minimum measurement cycle: 1.75 seconds */
+	if (time_after(jiffies, data->last_updated_measure + (HZ * 7 / 4))
+			|| !data->valid) {
+
+		for (i = 0; i < 6; i++) /* read voltages */
+		{
+			data->in[i] = adm9240_read_value(client,
+					ADM9240_REG_IN(i));
+		}
+		data->alarms = adm9240_read_value(client,
+					ADM9240_REG_INT(0)) |
+					adm9240_read_value(client,
+					ADM9240_REG_INT(1)) << 8;
+
+		/* read temperature: assume temperature changes less than
+		 * 0.5'C per two measurement cycles thus ignore possible
+		 * but unlikely aliasing error on lsb reading. --Grant */
+		data->temp = ((adm9240_read_value(client,
+					ADM9240_REG_TEMP) << 8) |
+					adm9240_read_value(client,
+					ADM9240_REG_TEMP_CONF)) / 128;
+
+		for (i = 0; i < 2; i++) /* read fans */
+		{
+			data->fan[i] = adm9240_read_value(client,
+					ADM9240_REG_FAN(i));
+
+			/* adjust fan clock divider on overflow */
+			if (data->valid && data->fan[i] == 255 &&
+					data->fan_div[i] < 3) {
+
+				adm9240_write_fan_div(client, i,
+						++data->fan_div[i]);
+
+				/* adjust fan_min if active, but not to 0 */
+				if (data->fan_min[i] < 255 &&
+						data->fan_min[i] >= 2)
+					data->fan_min[i] /= 2;
+			}
+		}
+		data->last_updated_measure = jiffies;
+	}
+
+	/* minimum config reading cycle: 300 seconds */
+	if (time_after(jiffies, data->last_updated_config + (HZ * 300))
+			|| !data->valid) {
+
+		for (i = 0; i < 6; i++)
+		{
+			data->in_min[i] = adm9240_read_value(client,
+					ADM9240_REG_IN_MIN(i));
+			data->in_max[i] = adm9240_read_value(client,
+					ADM9240_REG_IN_MAX(i));
+		}
+		for (i = 0; i < 2; i++)
+		{
+			data->fan_min[i] = adm9240_read_value(client,
+					ADM9240_REG_FAN_MIN(i));
+		}
+		data->temp_high = adm9240_read_value(client,
+				ADM9240_REG_TEMP_HIGH);
+		data->temp_hyst = adm9240_read_value(client,
+				ADM9240_REG_TEMP_HYST);
+
+		/* read fan divs and 5-bit VID */
+		i = adm9240_read_value(client, ADM9240_REG_VID_FAN_DIV);
+		data->fan_div[0] = (i >> 4) & 3;
+		data->fan_div[1] = (i >> 6) & 3;
+		data->vid = i & 0x0f;
+		data->vid |= (adm9240_read_value(client,
+					ADM9240_REG_VID4) & 1) << 4;
+		/* read analog out */
+		data->aout = adm9240_read_value(client,
+				ADM9240_REG_ANALOG_OUT);
+
+		data->last_updated_config = jiffies;
+		data->valid = 1;
+	}
+	up(&data->update_lock);
+	return data;
+}
+
+static int __init sensors_adm9240_init(void)
+{
+	return i2c_add_driver(&adm9240_driver);
+}
+
+static void __exit sensors_adm9240_exit(void)
+{
+	i2c_del_driver(&adm9240_driver);
+}
+
+MODULE_AUTHOR("Michiel Rook <michiel@grendelproject.nl>, "
+		"Grant Coady <gcoady@gmail.com> and others");
+MODULE_DESCRIPTION("ADM9240/DS1780/LM81 driver");
+MODULE_LICENSE("GPL");
+
+module_init(sensors_adm9240_init);
+module_exit(sensors_adm9240_exit);
+
diff --git a/drivers/hwmon/asb100.c b/drivers/hwmon/asb100.c
new file mode 100644
--- /dev/null
+++ b/drivers/hwmon/asb100.c
@@ -0,0 +1,1065 @@
+/*
+    asb100.c - Part of lm_sensors, Linux kernel modules for hardware
+	        monitoring
+
+    Copyright (C) 2004 Mark M. Hoffman <mhoffman@lightlink.com>
+
+	(derived from w83781d.c)
+
+    Copyright (C) 1998 - 2003  Frodo Looijaard <frodol@dds.nl>,
+    Philip Edelbrock <phil@netroedge.com>, and
+    Mark Studebaker <mdsxyz123@yahoo.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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/*
+    This driver supports the hardware sensor chips: Asus ASB100 and
+    ASB100-A "BACH".
+
+    ASB100-A supports pwm1, while plain ASB100 does not.  There is no known
+    way for the driver to tell which one is there.
+
+    Chip	#vin	#fanin	#pwm	#temp	wchipid	vendid	i2c	ISA
+    asb100	7	3	1	4	0x31	0x0694	yes	no
+*/
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/i2c-sensor.h>
+#include <linux/i2c-vid.h>
+#include <linux/init.h>
+#include <linux/jiffies.h>
+#include "lm75.h"
+
+/*
+	HISTORY:
+	2003-12-29	1.0.0	Ported from lm_sensors project for kernel 2.6
+*/
+#define ASB100_VERSION "1.0.0"
+
+/* I2C addresses to scan */
+static unsigned short normal_i2c[] = { 0x2d, I2C_CLIENT_END };
+
+/* ISA addresses to scan (none) */
+static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
+
+/* Insmod parameters */
+SENSORS_INSMOD_1(asb100);
+I2C_CLIENT_MODULE_PARM(force_subclients, "List of subclient addresses: "
+	"{bus, clientaddr, subclientaddr1, subclientaddr2}");
+
+/* Voltage IN registers 0-6 */
+#define ASB100_REG_IN(nr)	(0x20 + (nr))
+#define ASB100_REG_IN_MAX(nr)	(0x2b + (nr * 2))
+#define ASB100_REG_IN_MIN(nr)	(0x2c + (nr * 2))
+
+/* FAN IN registers 1-3 */
+#define ASB100_REG_FAN(nr)	(0x28 + (nr))
+#define ASB100_REG_FAN_MIN(nr)	(0x3b + (nr))
+
+/* TEMPERATURE registers 1-4 */
+static const u16 asb100_reg_temp[]	= {0, 0x27, 0x150, 0x250, 0x17};
+static const u16 asb100_reg_temp_max[]	= {0, 0x39, 0x155, 0x255, 0x18};
+static const u16 asb100_reg_temp_hyst[]	= {0, 0x3a, 0x153, 0x253, 0x19};
+
+#define ASB100_REG_TEMP(nr) (asb100_reg_temp[nr])
+#define ASB100_REG_TEMP_MAX(nr) (asb100_reg_temp_max[nr])
+#define ASB100_REG_TEMP_HYST(nr) (asb100_reg_temp_hyst[nr])
+
+#define ASB100_REG_TEMP2_CONFIG	0x0152
+#define ASB100_REG_TEMP3_CONFIG	0x0252
+
+
+#define ASB100_REG_CONFIG	0x40
+#define ASB100_REG_ALARM1	0x41
+#define ASB100_REG_ALARM2	0x42
+#define ASB100_REG_SMIM1	0x43
+#define ASB100_REG_SMIM2	0x44
+#define ASB100_REG_VID_FANDIV	0x47
+#define ASB100_REG_I2C_ADDR	0x48
+#define ASB100_REG_CHIPID	0x49
+#define ASB100_REG_I2C_SUBADDR	0x4a
+#define ASB100_REG_PIN		0x4b
+#define ASB100_REG_IRQ		0x4c
+#define ASB100_REG_BANK		0x4e
+#define ASB100_REG_CHIPMAN	0x4f
+
+#define ASB100_REG_WCHIPID	0x58
+
+/* bit 7 -> enable, bits 0-3 -> duty cycle */
+#define ASB100_REG_PWM1		0x59
+
+/* CONVERSIONS
+   Rounding and limit checking is only done on the TO_REG variants. */
+
+/* These constants are a guess, consistent w/ w83781d */
+#define ASB100_IN_MIN (   0)
+#define ASB100_IN_MAX (4080)
+
+/* IN: 1/1000 V (0V to 4.08V)
+   REG: 16mV/bit */
+static u8 IN_TO_REG(unsigned val)
+{
+	unsigned nval = SENSORS_LIMIT(val, ASB100_IN_MIN, ASB100_IN_MAX);
+	return (nval + 8) / 16;
+}
+
+static unsigned IN_FROM_REG(u8 reg)
+{
+	return reg * 16;
+}
+
+static u8 FAN_TO_REG(long rpm, int div)
+{
+	if (rpm == -1)
+		return 0;
+	if (rpm == 0)
+		return 255;
+	rpm = SENSORS_LIMIT(rpm, 1, 1000000);
+	return SENSORS_LIMIT((1350000 + rpm * div / 2) / (rpm * div), 1, 254);
+}
+
+static int FAN_FROM_REG(u8 val, int div)
+{
+	return val==0 ? -1 : val==255 ? 0 : 1350000/(val*div);
+}
+
+/* These constants are a guess, consistent w/ w83781d */
+#define ASB100_TEMP_MIN (-128000)
+#define ASB100_TEMP_MAX ( 127000)
+
+/* TEMP: 0.001C/bit (-128C to +127C)
+   REG: 1C/bit, two's complement */
+static u8 TEMP_TO_REG(int temp)
+{
+	int ntemp = SENSORS_LIMIT(temp, ASB100_TEMP_MIN, ASB100_TEMP_MAX);
+	ntemp += (ntemp<0 ? -500 : 500);
+	return (u8)(ntemp / 1000);
+}
+
+static int TEMP_FROM_REG(u8 reg)
+{
+	return (s8)reg * 1000;
+}
+
+/* PWM: 0 - 255 per sensors documentation
+   REG: (6.25% duty cycle per bit) */
+static u8 ASB100_PWM_TO_REG(int pwm)
+{
+	pwm = SENSORS_LIMIT(pwm, 0, 255);
+	return (u8)(pwm / 16);
+}
+
+static int ASB100_PWM_FROM_REG(u8 reg)
+{
+	return reg * 16;
+}
+
+#define DIV_FROM_REG(val) (1 << (val))
+
+/* FAN DIV: 1, 2, 4, or 8 (defaults to 2)
+   REG: 0, 1, 2, or 3 (respectively) (defaults to 1) */
+static u8 DIV_TO_REG(long val)
+{
+	return val==8 ? 3 : val==4 ? 2 : val==1 ? 0 : 1;
+}
+
+/* For each registered client, we need to keep some data in memory. That
+   data is pointed to by client->data. The structure itself is
+   dynamically allocated, at the same time the client itself is allocated. */
+struct asb100_data {
+	struct i2c_client client;
+	struct semaphore lock;
+	enum chips type;
+
+	struct semaphore update_lock;
+	unsigned long last_updated;	/* In jiffies */
+
+	/* array of 2 pointers to subclients */
+	struct i2c_client *lm75[2];
+
+	char valid;		/* !=0 if following fields are valid */
+	u8 in[7];		/* Register value */
+	u8 in_max[7];		/* Register value */
+	u8 in_min[7];		/* Register value */
+	u8 fan[3];		/* Register value */
+	u8 fan_min[3];		/* Register value */
+	u16 temp[4];		/* Register value (0 and 3 are u8 only) */
+	u16 temp_max[4];	/* Register value (0 and 3 are u8 only) */
+	u16 temp_hyst[4];	/* Register value (0 and 3 are u8 only) */
+	u8 fan_div[3];		/* Register encoding, right justified */
+	u8 pwm;			/* Register encoding */
+	u8 vid;			/* Register encoding, combined */
+	u32 alarms;		/* Register encoding, combined */
+	u8 vrm;
+};
+
+static int asb100_read_value(struct i2c_client *client, u16 reg);
+static void asb100_write_value(struct i2c_client *client, u16 reg, u16 val);
+
+static int asb100_attach_adapter(struct i2c_adapter *adapter);
+static int asb100_detect(struct i2c_adapter *adapter, int address, int kind);
+static int asb100_detach_client(struct i2c_client *client);
+static struct asb100_data *asb100_update_device(struct device *dev);
+static void asb100_init_client(struct i2c_client *client);
+
+static struct i2c_driver asb100_driver = {
+	.owner		= THIS_MODULE,
+	.name		= "asb100",
+	.id		= I2C_DRIVERID_ASB100,
+	.flags		= I2C_DF_NOTIFY,
+	.attach_adapter	= asb100_attach_adapter,
+	.detach_client	= asb100_detach_client,
+};
+
+/* 7 Voltages */
+#define show_in_reg(reg) \
+static ssize_t show_##reg (struct device *dev, char *buf, int nr) \
+{ \
+	struct asb100_data *data = asb100_update_device(dev); \
+	return sprintf(buf, "%d\n", IN_FROM_REG(data->reg[nr])); \
+}
+
+show_in_reg(in)
+show_in_reg(in_min)
+show_in_reg(in_max)
+
+#define set_in_reg(REG, reg) \
+static ssize_t set_in_##reg(struct device *dev, const char *buf, \
+		size_t count, int nr) \
+{ \
+	struct i2c_client *client = to_i2c_client(dev); \
+	struct asb100_data *data = i2c_get_clientdata(client); \
+	unsigned long val = simple_strtoul(buf, NULL, 10); \
+ \
+	down(&data->update_lock); \
+	data->in_##reg[nr] = IN_TO_REG(val); \
+	asb100_write_value(client, ASB100_REG_IN_##REG(nr), \
+		data->in_##reg[nr]); \
+	up(&data->update_lock); \
+	return count; \
+}
+
+set_in_reg(MIN, min)
+set_in_reg(MAX, max)
+
+#define sysfs_in(offset) \
+static ssize_t \
+	show_in##offset (struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+	return show_in(dev, buf, offset); \
+} \
+static DEVICE_ATTR(in##offset##_input, S_IRUGO, \
+		show_in##offset, NULL); \
+static ssize_t \
+	show_in##offset##_min (struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+	return show_in_min(dev, buf, offset); \
+} \
+static ssize_t \
+	show_in##offset##_max (struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+	return show_in_max(dev, buf, offset); \
+} \
+static ssize_t set_in##offset##_min (struct device *dev, struct device_attribute *attr, \
+		const char *buf, size_t count) \
+{ \
+	return set_in_min(dev, buf, count, offset); \
+} \
+static ssize_t set_in##offset##_max (struct device *dev, struct device_attribute *attr, \
+		const char *buf, size_t count) \
+{ \
+	return set_in_max(dev, buf, count, offset); \
+} \
+static DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \
+		show_in##offset##_min, set_in##offset##_min); \
+static DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \
+		show_in##offset##_max, set_in##offset##_max);
+
+sysfs_in(0);
+sysfs_in(1);
+sysfs_in(2);
+sysfs_in(3);
+sysfs_in(4);
+sysfs_in(5);
+sysfs_in(6);
+
+#define device_create_file_in(client, offset) do { \
+	device_create_file(&client->dev, &dev_attr_in##offset##_input); \
+	device_create_file(&client->dev, &dev_attr_in##offset##_min); \
+	device_create_file(&client->dev, &dev_attr_in##offset##_max); \
+} while (0)
+
+/* 3 Fans */
+static ssize_t show_fan(struct device *dev, char *buf, int nr)
+{
+	struct asb100_data *data = asb100_update_device(dev);
+	return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[nr],
+		DIV_FROM_REG(data->fan_div[nr])));
+}
+
+static ssize_t show_fan_min(struct device *dev, char *buf, int nr)
+{
+	struct asb100_data *data = asb100_update_device(dev);
+	return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan_min[nr],
+		DIV_FROM_REG(data->fan_div[nr])));
+}
+
+static ssize_t show_fan_div(struct device *dev, char *buf, int nr)
+{
+	struct asb100_data *data = asb100_update_device(dev);
+	return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[nr]));
+}
+
+static ssize_t set_fan_min(struct device *dev, const char *buf,
+				size_t count, int nr)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct asb100_data *data = i2c_get_clientdata(client);
+	u32 val = simple_strtoul(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr]));
+	asb100_write_value(client, ASB100_REG_FAN_MIN(nr), data->fan_min[nr]);
+	up(&data->update_lock);
+	return count;
+}
+
+/* Note: we save and restore the fan minimum here, because its value is
+   determined in part by the fan divisor.  This follows the principle of
+   least suprise; the user doesn't expect the fan minimum to change just
+   because the divisor changed. */
+static ssize_t set_fan_div(struct device *dev, const char *buf,
+				size_t count, int nr)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct asb100_data *data = i2c_get_clientdata(client);
+	unsigned long min;
+	unsigned long val = simple_strtoul(buf, NULL, 10);
+	int reg;
+	
+	down(&data->update_lock);
+
+	min = FAN_FROM_REG(data->fan_min[nr],
+			DIV_FROM_REG(data->fan_div[nr]));
+	data->fan_div[nr] = DIV_TO_REG(val);
+
+	switch(nr) {
+	case 0:	/* fan 1 */
+		reg = asb100_read_value(client, ASB100_REG_VID_FANDIV);
+		reg = (reg & 0xcf) | (data->fan_div[0] << 4);
+		asb100_write_value(client, ASB100_REG_VID_FANDIV, reg);
+		break;
+
+	case 1:	/* fan 2 */
+		reg = asb100_read_value(client, ASB100_REG_VID_FANDIV);
+		reg = (reg & 0x3f) | (data->fan_div[1] << 6);
+		asb100_write_value(client, ASB100_REG_VID_FANDIV, reg);
+		break;
+
+	case 2:	/* fan 3 */
+		reg = asb100_read_value(client, ASB100_REG_PIN);
+		reg = (reg & 0x3f) | (data->fan_div[2] << 6);
+		asb100_write_value(client, ASB100_REG_PIN, reg);
+		break;
+	}
+
+	data->fan_min[nr] =
+		FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr]));
+	asb100_write_value(client, ASB100_REG_FAN_MIN(nr), data->fan_min[nr]);
+
+	up(&data->update_lock);
+
+	return count;
+}
+
+#define sysfs_fan(offset) \
+static ssize_t show_fan##offset(struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+	return show_fan(dev, buf, offset - 1); \
+} \
+static ssize_t show_fan##offset##_min(struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+	return show_fan_min(dev, buf, offset - 1); \
+} \
+static ssize_t show_fan##offset##_div(struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+	return show_fan_div(dev, buf, offset - 1); \
+} \
+static ssize_t set_fan##offset##_min(struct device *dev, struct device_attribute *attr, const char *buf, \
+					size_t count) \
+{ \
+	return set_fan_min(dev, buf, count, offset - 1); \
+} \
+static ssize_t set_fan##offset##_div(struct device *dev, struct device_attribute *attr, const char *buf, \
+					size_t count) \
+{ \
+	return set_fan_div(dev, buf, count, offset - 1); \
+} \
+static DEVICE_ATTR(fan##offset##_input, S_IRUGO, \
+		show_fan##offset, NULL); \
+static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \
+		show_fan##offset##_min, set_fan##offset##_min); \
+static DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, \
+		show_fan##offset##_div, set_fan##offset##_div);
+
+sysfs_fan(1);
+sysfs_fan(2);
+sysfs_fan(3);
+
+#define device_create_file_fan(client, offset) do { \
+	device_create_file(&client->dev, &dev_attr_fan##offset##_input); \
+	device_create_file(&client->dev, &dev_attr_fan##offset##_min); \
+	device_create_file(&client->dev, &dev_attr_fan##offset##_div); \
+} while (0)
+
+/* 4 Temp. Sensors */
+static int sprintf_temp_from_reg(u16 reg, char *buf, int nr)
+{
+	int ret = 0;
+
+	switch (nr) {
+	case 1: case 2:
+		ret = sprintf(buf, "%d\n", LM75_TEMP_FROM_REG(reg));
+		break;
+	case 0: case 3: default:
+		ret = sprintf(buf, "%d\n", TEMP_FROM_REG(reg));
+		break;
+	}
+	return ret;
+}
+		 	
+#define show_temp_reg(reg) \
+static ssize_t show_##reg(struct device *dev, char *buf, int nr) \
+{ \
+	struct asb100_data *data = asb100_update_device(dev); \
+	return sprintf_temp_from_reg(data->reg[nr], buf, nr); \
+}
+
+show_temp_reg(temp);
+show_temp_reg(temp_max);
+show_temp_reg(temp_hyst);
+
+#define set_temp_reg(REG, reg) \
+static ssize_t set_##reg(struct device *dev, const char *buf, \
+			size_t count, int nr) \
+{ \
+	struct i2c_client *client = to_i2c_client(dev); \
+	struct asb100_data *data = i2c_get_clientdata(client); \
+	unsigned long val = simple_strtoul(buf, NULL, 10); \
+ \
+	down(&data->update_lock); \
+	switch (nr) { \
+	case 1: case 2: \
+		data->reg[nr] = LM75_TEMP_TO_REG(val); \
+		break; \
+	case 0: case 3: default: \
+		data->reg[nr] = TEMP_TO_REG(val); \
+		break; \
+	} \
+	asb100_write_value(client, ASB100_REG_TEMP_##REG(nr+1), \
+			data->reg[nr]); \
+	up(&data->update_lock); \
+	return count; \
+}
+
+set_temp_reg(MAX, temp_max);
+set_temp_reg(HYST, temp_hyst);
+
+#define sysfs_temp(num) \
+static ssize_t show_temp##num(struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+	return show_temp(dev, buf, num-1); \
+} \
+static DEVICE_ATTR(temp##num##_input, S_IRUGO, show_temp##num, NULL); \
+static ssize_t show_temp_max##num(struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+	return show_temp_max(dev, buf, num-1); \
+} \
+static ssize_t set_temp_max##num(struct device *dev, struct device_attribute *attr, const char *buf, \
+					size_t count) \
+{ \
+	return set_temp_max(dev, buf, count, num-1); \
+} \
+static DEVICE_ATTR(temp##num##_max, S_IRUGO | S_IWUSR, \
+		show_temp_max##num, set_temp_max##num); \
+static ssize_t show_temp_hyst##num(struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+	return show_temp_hyst(dev, buf, num-1); \
+} \
+static ssize_t set_temp_hyst##num(struct device *dev, struct device_attribute *attr, const char *buf, \
+					size_t count) \
+{ \
+	return set_temp_hyst(dev, buf, count, num-1); \
+} \
+static DEVICE_ATTR(temp##num##_max_hyst, S_IRUGO | S_IWUSR, \
+		show_temp_hyst##num, set_temp_hyst##num);
+
+sysfs_temp(1);
+sysfs_temp(2);
+sysfs_temp(3);
+sysfs_temp(4);
+
+/* VID */
+#define device_create_file_temp(client, num) do { \
+	device_create_file(&client->dev, &dev_attr_temp##num##_input); \
+	device_create_file(&client->dev, &dev_attr_temp##num##_max); \
+	device_create_file(&client->dev, &dev_attr_temp##num##_max_hyst); \
+} while (0)
+
+static ssize_t show_vid(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct asb100_data *data = asb100_update_device(dev);
+	return sprintf(buf, "%d\n", vid_from_reg(data->vid, data->vrm));
+}
+
+static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL);
+#define device_create_file_vid(client) \
+device_create_file(&client->dev, &dev_attr_cpu0_vid)
+
+/* VRM */
+static ssize_t show_vrm(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct asb100_data *data = asb100_update_device(dev);
+	return sprintf(buf, "%d\n", data->vrm);
+}
+
+static ssize_t set_vrm(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct asb100_data *data = i2c_get_clientdata(client);
+	unsigned long val = simple_strtoul(buf, NULL, 10);
+	data->vrm = val;
+	return count;
+}
+
+/* Alarms */
+static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm, set_vrm);
+#define device_create_file_vrm(client) \
+device_create_file(&client->dev, &dev_attr_vrm);
+
+static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct asb100_data *data = asb100_update_device(dev);
+	return sprintf(buf, "%u\n", data->alarms);
+}
+
+static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
+#define device_create_file_alarms(client) \
+device_create_file(&client->dev, &dev_attr_alarms)
+
+/* 1 PWM */
+static ssize_t show_pwm1(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct asb100_data *data = asb100_update_device(dev);
+	return sprintf(buf, "%d\n", ASB100_PWM_FROM_REG(data->pwm & 0x0f));
+}
+
+static ssize_t set_pwm1(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct asb100_data *data = i2c_get_clientdata(client);
+	unsigned long val = simple_strtoul(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->pwm &= 0x80; /* keep the enable bit */
+	data->pwm |= (0x0f & ASB100_PWM_TO_REG(val));
+	asb100_write_value(client, ASB100_REG_PWM1, data->pwm);
+	up(&data->update_lock);
+	return count;
+}
+
+static ssize_t show_pwm_enable1(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct asb100_data *data = asb100_update_device(dev);
+	return sprintf(buf, "%d\n", (data->pwm & 0x80) ? 1 : 0);
+}
+
+static ssize_t set_pwm_enable1(struct device *dev, struct device_attribute *attr, const char *buf,
+				size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct asb100_data *data = i2c_get_clientdata(client);
+	unsigned long val = simple_strtoul(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->pwm &= 0x0f; /* keep the duty cycle bits */
+	data->pwm |= (val ? 0x80 : 0x00);
+	asb100_write_value(client, ASB100_REG_PWM1, data->pwm);
+	up(&data->update_lock);
+	return count;
+}
+
+static DEVICE_ATTR(pwm1, S_IRUGO | S_IWUSR, show_pwm1, set_pwm1);
+static DEVICE_ATTR(pwm1_enable, S_IRUGO | S_IWUSR,
+		show_pwm_enable1, set_pwm_enable1);
+#define device_create_file_pwm1(client) do { \
+	device_create_file(&new_client->dev, &dev_attr_pwm1); \
+	device_create_file(&new_client->dev, &dev_attr_pwm1_enable); \
+} while (0)
+
+/* This function is called when:
+	asb100_driver is inserted (when this module is loaded), for each
+		available adapter
+	when a new adapter is inserted (and asb100_driver is still present)
+ */
+static int asb100_attach_adapter(struct i2c_adapter *adapter)
+{
+	if (!(adapter->class & I2C_CLASS_HWMON))
+		return 0;
+	return i2c_detect(adapter, &addr_data, asb100_detect);
+}
+
+static int asb100_detect_subclients(struct i2c_adapter *adapter, int address,
+		int kind, struct i2c_client *new_client)
+{
+	int i, id, err;
+	struct asb100_data *data = i2c_get_clientdata(new_client);
+
+	data->lm75[0] = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
+	if (!(data->lm75[0])) {
+		err = -ENOMEM;
+		goto ERROR_SC_0;
+	}
+	memset(data->lm75[0], 0x00, sizeof(struct i2c_client));
+
+	data->lm75[1] = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
+	if (!(data->lm75[1])) {
+		err = -ENOMEM;
+		goto ERROR_SC_1;
+	}
+	memset(data->lm75[1], 0x00, sizeof(struct i2c_client));
+
+	id = i2c_adapter_id(adapter);
+
+	if (force_subclients[0] == id && force_subclients[1] == address) {
+		for (i = 2; i <= 3; i++) {
+			if (force_subclients[i] < 0x48 ||
+			    force_subclients[i] > 0x4f) {
+				dev_err(&new_client->dev, "invalid subclient "
+					"address %d; must be 0x48-0x4f\n",
+					force_subclients[i]);
+				err = -ENODEV;
+				goto ERROR_SC_2;
+			}
+		}
+		asb100_write_value(new_client, ASB100_REG_I2C_SUBADDR,
+					(force_subclients[2] & 0x07) |
+					((force_subclients[3] & 0x07) <<4));
+		data->lm75[0]->addr = force_subclients[2];
+		data->lm75[1]->addr = force_subclients[3];
+	} else {
+		int val = asb100_read_value(new_client, ASB100_REG_I2C_SUBADDR);
+		data->lm75[0]->addr = 0x48 + (val & 0x07);
+		data->lm75[1]->addr = 0x48 + ((val >> 4) & 0x07);
+	}
+
+	if(data->lm75[0]->addr == data->lm75[1]->addr) {
+		dev_err(&new_client->dev, "duplicate addresses 0x%x "
+				"for subclients\n", data->lm75[0]->addr);
+		err = -ENODEV;
+		goto ERROR_SC_2;
+	}
+
+	for (i = 0; i <= 1; i++) {
+		i2c_set_clientdata(data->lm75[i], NULL);
+		data->lm75[i]->adapter = adapter;
+		data->lm75[i]->driver = &asb100_driver;
+		data->lm75[i]->flags = 0;
+		strlcpy(data->lm75[i]->name, "asb100 subclient", I2C_NAME_SIZE);
+	}
+
+	if ((err = i2c_attach_client(data->lm75[0]))) {
+		dev_err(&new_client->dev, "subclient %d registration "
+			"at address 0x%x failed.\n", i, data->lm75[0]->addr);
+		goto ERROR_SC_2;
+	}
+
+	if ((err = i2c_attach_client(data->lm75[1]))) {
+		dev_err(&new_client->dev, "subclient %d registration "
+			"at address 0x%x failed.\n", i, data->lm75[1]->addr);
+		goto ERROR_SC_3;
+	}
+
+	return 0;
+
+/* Undo inits in case of errors */
+ERROR_SC_3:
+	i2c_detach_client(data->lm75[0]);
+ERROR_SC_2:
+	kfree(data->lm75[1]);
+ERROR_SC_1:
+	kfree(data->lm75[0]);
+ERROR_SC_0:
+	return err;
+}
+
+static int asb100_detect(struct i2c_adapter *adapter, int address, int kind)
+{
+	int err;
+	struct i2c_client *new_client;
+	struct asb100_data *data;
+
+	/* asb100 is SMBus only */
+	if (i2c_is_isa_adapter(adapter)) {
+		pr_debug("asb100.o: detect failed, "
+				"cannot attach to legacy adapter!\n");
+		err = -ENODEV;
+		goto ERROR0;
+	}
+
+	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
+		pr_debug("asb100.o: detect failed, "
+				"smbus byte data not supported!\n");
+		err = -ENODEV;
+		goto ERROR0;
+	}
+
+	/* OK. For now, we presume we have a valid client. We now create the
+	   client structure, even though we cannot fill it completely yet.
+	   But it allows us to access asb100_{read,write}_value. */
+
+	if (!(data = kmalloc(sizeof(struct asb100_data), GFP_KERNEL))) {
+		pr_debug("asb100.o: detect failed, kmalloc failed!\n");
+		err = -ENOMEM;
+		goto ERROR0;
+	}
+	memset(data, 0, sizeof(struct asb100_data));
+
+	new_client = &data->client;
+	init_MUTEX(&data->lock);
+	i2c_set_clientdata(new_client, data);
+	new_client->addr = address;
+	new_client->adapter = adapter;
+	new_client->driver = &asb100_driver;
+	new_client->flags = 0;
+
+	/* Now, we do the remaining detection. */
+
+	/* The chip may be stuck in some other bank than bank 0. This may
+	   make reading other information impossible. Specify a force=... or
+	   force_*=... parameter, and the chip will be reset to the right
+	   bank. */
+	if (kind < 0) {
+
+		int val1 = asb100_read_value(new_client, ASB100_REG_BANK);
+		int val2 = asb100_read_value(new_client, ASB100_REG_CHIPMAN);
+
+		/* If we're in bank 0 */
+		if ( (!(val1 & 0x07)) &&
+				/* Check for ASB100 ID (low byte) */
+				( ((!(val1 & 0x80)) && (val2 != 0x94)) ||
+				/* Check for ASB100 ID (high byte ) */
+				((val1 & 0x80) && (val2 != 0x06)) ) ) {
+			pr_debug("asb100.o: detect failed, "
+					"bad chip id 0x%02x!\n", val2);
+			err = -ENODEV;
+			goto ERROR1;
+		}
+
+	} /* kind < 0 */
+
+	/* We have either had a force parameter, or we have already detected
+	   Winbond. Put it now into bank 0 and Vendor ID High Byte */
+	asb100_write_value(new_client, ASB100_REG_BANK,
+		(asb100_read_value(new_client, ASB100_REG_BANK) & 0x78) | 0x80);
+
+	/* Determine the chip type. */
+	if (kind <= 0) {
+		int val1 = asb100_read_value(new_client, ASB100_REG_WCHIPID);
+		int val2 = asb100_read_value(new_client, ASB100_REG_CHIPMAN);
+
+		if ((val1 == 0x31) && (val2 == 0x06))
+			kind = asb100;
+		else {
+			if (kind == 0)
+				dev_warn(&new_client->dev, "ignoring "
+					"'force' parameter for unknown chip "
+					"at adapter %d, address 0x%02x.\n",
+					i2c_adapter_id(adapter), address);
+			err = -ENODEV;
+			goto ERROR1;
+		}
+	}
+
+	/* Fill in remaining client fields and put it into the global list */
+	strlcpy(new_client->name, "asb100", I2C_NAME_SIZE);
+	data->type = kind;
+
+	data->valid = 0;
+	init_MUTEX(&data->update_lock);
+
+	/* Tell the I2C layer a new client has arrived */
+	if ((err = i2c_attach_client(new_client)))
+		goto ERROR1;
+
+	/* Attach secondary lm75 clients */
+	if ((err = asb100_detect_subclients(adapter, address, kind,
+			new_client)))
+		goto ERROR2;
+
+	/* Initialize the chip */
+	asb100_init_client(new_client);
+
+	/* A few vars need to be filled upon startup */
+	data->fan_min[0] = asb100_read_value(new_client, ASB100_REG_FAN_MIN(0));
+	data->fan_min[1] = asb100_read_value(new_client, ASB100_REG_FAN_MIN(1));
+	data->fan_min[2] = asb100_read_value(new_client, ASB100_REG_FAN_MIN(2));
+
+	/* Register sysfs hooks */
+	device_create_file_in(new_client, 0);
+	device_create_file_in(new_client, 1);
+	device_create_file_in(new_client, 2);
+	device_create_file_in(new_client, 3);
+	device_create_file_in(new_client, 4);
+	device_create_file_in(new_client, 5);
+	device_create_file_in(new_client, 6);
+
+	device_create_file_fan(new_client, 1);
+	device_create_file_fan(new_client, 2);
+	device_create_file_fan(new_client, 3);
+
+	device_create_file_temp(new_client, 1);
+	device_create_file_temp(new_client, 2);
+	device_create_file_temp(new_client, 3);
+	device_create_file_temp(new_client, 4);
+
+	device_create_file_vid(new_client);
+	device_create_file_vrm(new_client);
+
+	device_create_file_alarms(new_client);
+
+	device_create_file_pwm1(new_client);
+
+	return 0;
+
+ERROR2:
+	i2c_detach_client(new_client);
+ERROR1:
+	kfree(data);
+ERROR0:
+	return err;
+}
+
+static int asb100_detach_client(struct i2c_client *client)
+{
+	int err;
+
+	if ((err = i2c_detach_client(client))) {
+		dev_err(&client->dev, "client deregistration failed; "
+			"client not detached.\n");
+		return err;
+	}
+
+	if (i2c_get_clientdata(client)==NULL) {
+		/* subclients */
+		kfree(client);
+	} else {
+		/* main client */
+		kfree(i2c_get_clientdata(client));
+	}
+
+	return 0;
+}
+
+/* The SMBus locks itself, usually, but nothing may access the chip between
+   bank switches. */
+static int asb100_read_value(struct i2c_client *client, u16 reg)
+{
+	struct asb100_data *data = i2c_get_clientdata(client);
+	struct i2c_client *cl;
+	int res, bank;
+
+	down(&data->lock);
+
+	bank = (reg >> 8) & 0x0f;
+	if (bank > 2)
+		/* switch banks */
+		i2c_smbus_write_byte_data(client, ASB100_REG_BANK, bank);
+
+	if (bank == 0 || bank > 2) {
+		res = i2c_smbus_read_byte_data(client, reg & 0xff);
+	} else {
+		/* switch to subclient */
+		cl = data->lm75[bank - 1];
+
+		/* convert from ISA to LM75 I2C addresses */
+		switch (reg & 0xff) {
+		case 0x50: /* TEMP */
+			res = swab16(i2c_smbus_read_word_data (cl, 0));
+			break;
+		case 0x52: /* CONFIG */
+			res = i2c_smbus_read_byte_data(cl, 1);
+			break;
+		case 0x53: /* HYST */
+			res = swab16(i2c_smbus_read_word_data (cl, 2));
+			break;
+		case 0x55: /* MAX */
+		default:
+			res = swab16(i2c_smbus_read_word_data (cl, 3));
+			break;
+		}
+	}
+
+	if (bank > 2)
+		i2c_smbus_write_byte_data(client, ASB100_REG_BANK, 0);
+
+	up(&data->lock);
+
+	return res;
+}
+
+static void asb100_write_value(struct i2c_client *client, u16 reg, u16 value)
+{
+	struct asb100_data *data = i2c_get_clientdata(client);
+	struct i2c_client *cl;
+	int bank;
+
+	down(&data->lock);
+
+	bank = (reg >> 8) & 0x0f;
+	if (bank > 2)
+		/* switch banks */
+		i2c_smbus_write_byte_data(client, ASB100_REG_BANK, bank);
+
+	if (bank == 0 || bank > 2) {
+		i2c_smbus_write_byte_data(client, reg & 0xff, value & 0xff);
+	} else {
+		/* switch to subclient */
+		cl = data->lm75[bank - 1];
+
+		/* convert from ISA to LM75 I2C addresses */
+		switch (reg & 0xff) {
+		case 0x52: /* CONFIG */
+			i2c_smbus_write_byte_data(cl, 1, value & 0xff);
+			break;
+		case 0x53: /* HYST */
+			i2c_smbus_write_word_data(cl, 2, swab16(value));
+			break;
+		case 0x55: /* MAX */
+			i2c_smbus_write_word_data(cl, 3, swab16(value));
+			break;
+		}
+	}
+
+	if (bank > 2)
+		i2c_smbus_write_byte_data(client, ASB100_REG_BANK, 0);
+
+	up(&data->lock);
+}
+
+static void asb100_init_client(struct i2c_client *client)
+{
+	struct asb100_data *data = i2c_get_clientdata(client);
+	int vid = 0;
+
+	vid = asb100_read_value(client, ASB100_REG_VID_FANDIV) & 0x0f;
+	vid |= (asb100_read_value(client, ASB100_REG_CHIPID) & 0x01) << 4;
+	data->vrm = i2c_which_vrm();
+	vid = vid_from_reg(vid, data->vrm);
+
+	/* Start monitoring */
+	asb100_write_value(client, ASB100_REG_CONFIG, 
+		(asb100_read_value(client, ASB100_REG_CONFIG) & 0xf7) | 0x01);
+}
+
+static struct asb100_data *asb100_update_device(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct asb100_data *data = i2c_get_clientdata(client);
+	int i;
+
+	down(&data->update_lock);
+
+	if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
+		|| !data->valid) {
+
+		dev_dbg(&client->dev, "starting device update...\n");
+
+		/* 7 voltage inputs */
+		for (i = 0; i < 7; i++) {
+			data->in[i] = asb100_read_value(client,
+				ASB100_REG_IN(i));
+			data->in_min[i] = asb100_read_value(client,
+				ASB100_REG_IN_MIN(i));
+			data->in_max[i] = asb100_read_value(client,
+				ASB100_REG_IN_MAX(i));
+		}
+
+		/* 3 fan inputs */
+		for (i = 0; i < 3; i++) {
+			data->fan[i] = asb100_read_value(client,
+					ASB100_REG_FAN(i));
+			data->fan_min[i] = asb100_read_value(client,
+					ASB100_REG_FAN_MIN(i));
+		}
+
+		/* 4 temperature inputs */
+		for (i = 1; i <= 4; i++) {
+			data->temp[i-1] = asb100_read_value(client,
+					ASB100_REG_TEMP(i));
+			data->temp_max[i-1] = asb100_read_value(client,
+					ASB100_REG_TEMP_MAX(i));
+			data->temp_hyst[i-1] = asb100_read_value(client,
+					ASB100_REG_TEMP_HYST(i));
+		}
+
+		/* VID and fan divisors */
+		i = asb100_read_value(client, ASB100_REG_VID_FANDIV);
+		data->vid = i & 0x0f;
+		data->vid |= (asb100_read_value(client,
+				ASB100_REG_CHIPID) & 0x01) << 4;
+		data->fan_div[0] = (i >> 4) & 0x03;
+		data->fan_div[1] = (i >> 6) & 0x03;
+		data->fan_div[2] = (asb100_read_value(client,
+				ASB100_REG_PIN) >> 6) & 0x03;
+
+		/* PWM */
+		data->pwm = asb100_read_value(client, ASB100_REG_PWM1);
+
+		/* alarms */
+		data->alarms = asb100_read_value(client, ASB100_REG_ALARM1) +
+			(asb100_read_value(client, ASB100_REG_ALARM2) << 8);
+
+		data->last_updated = jiffies;
+		data->valid = 1;
+
+		dev_dbg(&client->dev, "... device update complete\n");
+	}
+
+	up(&data->update_lock);
+
+	return data;
+}
+
+static int __init asb100_init(void)
+{
+	return i2c_add_driver(&asb100_driver);
+}
+
+static void __exit asb100_exit(void)
+{
+	i2c_del_driver(&asb100_driver);
+}
+
+MODULE_AUTHOR("Mark M. Hoffman <mhoffman@lightlink.com>");
+MODULE_DESCRIPTION("ASB100 Bach driver");
+MODULE_LICENSE("GPL");
+
+module_init(asb100_init);
+module_exit(asb100_exit);
+
diff --git a/drivers/hwmon/atxp1.c b/drivers/hwmon/atxp1.c
new file mode 100644
--- /dev/null
+++ b/drivers/hwmon/atxp1.c
@@ -0,0 +1,360 @@
+/*
+    atxp1.c - kernel module for setting CPU VID and general purpose
+                     I/Os using the Attansic ATXP1 chip.
+
+    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 <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/jiffies.h>
+#include <linux/i2c.h>
+#include <linux/i2c-sensor.h>
+#include <linux/i2c-vid.h>
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("System voltages control via Attansic ATXP1");
+MODULE_VERSION("0.6.2");
+MODULE_AUTHOR("Sebastian Witt <se.witt@gmx.net>");
+
+#define ATXP1_VID	0x00
+#define ATXP1_CVID	0x01
+#define ATXP1_GPIO1	0x06
+#define ATXP1_GPIO2	0x0a
+#define ATXP1_VIDENA	0x20
+#define ATXP1_VIDMASK	0x1f
+#define ATXP1_GPIO1MASK	0x0f
+
+static unsigned short normal_i2c[] = { 0x37, 0x4e, I2C_CLIENT_END };
+static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
+
+SENSORS_INSMOD_1(atxp1);
+
+static int atxp1_attach_adapter(struct i2c_adapter * adapter);
+static int atxp1_detach_client(struct i2c_client * client);
+static struct atxp1_data * atxp1_update_device(struct device *dev);
+static int atxp1_detect(struct i2c_adapter *adapter, int address, int kind);
+
+static struct i2c_driver atxp1_driver = {
+	.owner		= THIS_MODULE,
+	.name		= "atxp1",
+	.flags		= I2C_DF_NOTIFY,
+	.attach_adapter = atxp1_attach_adapter,
+	.detach_client	= atxp1_detach_client,
+};
+
+struct atxp1_data {
+	struct i2c_client client;
+	struct semaphore update_lock;
+	unsigned long last_updated;
+	u8 valid;
+	struct {
+		u8 vid;		/* VID output register */
+		u8 cpu_vid; /* VID input from CPU */
+		u8 gpio1;   /* General purpose I/O register 1 */
+		u8 gpio2;   /* General purpose I/O register 2 */
+	} reg;
+	u8 vrm;			/* Detected CPU VRM */
+};
+
+static struct atxp1_data * atxp1_update_device(struct device *dev)
+{
+	struct i2c_client *client;
+	struct atxp1_data *data;
+
+	client = to_i2c_client(dev);
+	data = i2c_get_clientdata(client);
+
+	down(&data->update_lock);
+
+	if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
+
+		/* Update local register data */
+		data->reg.vid = i2c_smbus_read_byte_data(client, ATXP1_VID);
+		data->reg.cpu_vid = i2c_smbus_read_byte_data(client, ATXP1_CVID);
+		data->reg.gpio1 = i2c_smbus_read_byte_data(client, ATXP1_GPIO1);
+		data->reg.gpio2 = i2c_smbus_read_byte_data(client, ATXP1_GPIO2);
+
+		data->valid = 1;
+	}
+
+	up(&data->update_lock);
+
+	return(data);
+}
+
+/* sys file functions for cpu0_vid */
+static ssize_t atxp1_showvcore(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	int size;
+	struct atxp1_data *data;
+
+	data = atxp1_update_device(dev);
+
+	size = sprintf(buf, "%d\n", vid_from_reg(data->reg.vid & ATXP1_VIDMASK, data->vrm));
+
+	return size;
+}
+
+static ssize_t atxp1_storevcore(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct atxp1_data *data;
+	struct i2c_client *client;
+	char vid;
+	char cvid;
+	unsigned int vcore;
+
+	client = to_i2c_client(dev);
+	data = atxp1_update_device(dev);
+
+	vcore = simple_strtoul(buf, NULL, 10);
+	vcore /= 25;
+	vcore *= 25;
+
+	/* Calculate VID */
+	vid = vid_to_reg(vcore, data->vrm);
+
+	if (vid < 0) {
+		dev_err(dev, "VID calculation failed.\n");
+		return -1;
+	}
+
+	/* If output enabled, use control register value. Otherwise original CPU VID */
+	if (data->reg.vid & ATXP1_VIDENA)
+		cvid = data->reg.vid & ATXP1_VIDMASK;
+	else
+		cvid = data->reg.cpu_vid;
+
+	/* Nothing changed, aborting */
+	if (vid == cvid)
+		return count;
+
+	dev_dbg(dev, "Setting VCore to %d mV (0x%02x)\n", vcore, vid);
+
+	/* Write every 25 mV step to increase stability */
+	if (cvid > vid) {
+		for (; cvid >= vid; cvid--) {
+        		i2c_smbus_write_byte_data(client, ATXP1_VID, cvid | ATXP1_VIDENA);
+		}
+	}
+	else {
+		for (; cvid <= vid; cvid++) {
+        		i2c_smbus_write_byte_data(client, ATXP1_VID, cvid | ATXP1_VIDENA);
+		}
+	}
+
+	data->valid = 0;
+
+	return count;
+}
+
+/* CPU core reference voltage
+    unit: millivolt
+*/
+static DEVICE_ATTR(cpu0_vid, S_IRUGO | S_IWUSR, atxp1_showvcore, atxp1_storevcore);
+
+/* sys file functions for GPIO1 */
+static ssize_t atxp1_showgpio1(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	int size;
+	struct atxp1_data *data;
+
+	data = atxp1_update_device(dev);
+
+	size = sprintf(buf, "0x%02x\n", data->reg.gpio1 & ATXP1_GPIO1MASK);
+
+	return size;
+}
+
+static ssize_t atxp1_storegpio1(struct device *dev, struct device_attribute *attr, const char*buf, size_t count)
+{
+	struct atxp1_data *data;
+	struct i2c_client *client;
+	unsigned int value;
+
+	client = to_i2c_client(dev);
+	data = atxp1_update_device(dev);
+
+	value = simple_strtoul(buf, NULL, 16);
+
+	value &= ATXP1_GPIO1MASK;
+
+	if (value != (data->reg.gpio1 & ATXP1_GPIO1MASK)) {
+		dev_info(dev, "Writing 0x%x to GPIO1.\n", value);
+
+		i2c_smbus_write_byte_data(client, ATXP1_GPIO1, value);
+
+		data->valid = 0;
+	}
+
+	return count;
+}
+
+/* GPIO1 data register
+    unit: Four bit as hex (e.g. 0x0f)
+*/
+static DEVICE_ATTR(gpio1, S_IRUGO | S_IWUSR, atxp1_showgpio1, atxp1_storegpio1);
+
+/* sys file functions for GPIO2 */
+static ssize_t atxp1_showgpio2(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	int size;
+	struct atxp1_data *data;
+
+	data = atxp1_update_device(dev);
+
+	size = sprintf(buf, "0x%02x\n", data->reg.gpio2);
+
+	return size;
+}
+
+static ssize_t atxp1_storegpio2(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct atxp1_data *data;
+	struct i2c_client *client;
+	unsigned int value;
+
+	client = to_i2c_client(dev);
+	data = atxp1_update_device(dev);
+
+	value = simple_strtoul(buf, NULL, 16) & 0xff;
+
+	if (value != data->reg.gpio2) {
+		dev_info(dev, "Writing 0x%x to GPIO1.\n", value);
+
+		i2c_smbus_write_byte_data(client, ATXP1_GPIO2, value);
+
+		data->valid = 0;
+	}
+
+	return count;
+}
+
+/* GPIO2 data register
+    unit: Eight bit as hex (e.g. 0xff)
+*/
+static DEVICE_ATTR(gpio2, S_IRUGO | S_IWUSR, atxp1_showgpio2, atxp1_storegpio2);
+
+
+static int atxp1_attach_adapter(struct i2c_adapter *adapter)
+{
+	return i2c_detect(adapter, &addr_data, &atxp1_detect);
+};
+
+static int atxp1_detect(struct i2c_adapter *adapter, int address, int kind)
+{
+	struct i2c_client * new_client;
+	struct atxp1_data * data;
+	int err = 0;
+	u8 temp;
+
+	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+		goto exit;
+
+	if (!(data = kmalloc(sizeof(struct atxp1_data), GFP_KERNEL))) {
+		err = -ENOMEM;
+		goto exit;
+	}
+
+	memset(data, 0, sizeof(struct atxp1_data));
+	new_client = &data->client;
+	i2c_set_clientdata(new_client, data);
+
+	new_client->addr = address;
+	new_client->adapter = adapter;
+	new_client->driver = &atxp1_driver;
+	new_client->flags = 0;
+
+	/* Detect ATXP1, checking if vendor ID registers are all zero */
+	if (!((i2c_smbus_read_byte_data(new_client, 0x3e) == 0) &&
+	     (i2c_smbus_read_byte_data(new_client, 0x3f) == 0) &&
+	     (i2c_smbus_read_byte_data(new_client, 0xfe) == 0) &&
+	     (i2c_smbus_read_byte_data(new_client, 0xff) == 0) )) {
+
+		/* No vendor ID, now checking if registers 0x10,0x11 (non-existent)
+		 * showing the same as register 0x00 */
+		temp = i2c_smbus_read_byte_data(new_client, 0x00);
+
+		if (!((i2c_smbus_read_byte_data(new_client, 0x10) == temp) &&
+			 (i2c_smbus_read_byte_data(new_client, 0x11) == temp) ))
+			goto exit_free;
+	}
+
+	/* Get VRM */
+	data->vrm = i2c_which_vrm();
+
+	if ((data->vrm != 90) && (data->vrm != 91)) {
+		dev_err(&new_client->dev, "Not supporting VRM %d.%d\n",
+				data->vrm / 10, data->vrm % 10);
+		goto exit_free;
+	}
+
+	strncpy(new_client->name, "atxp1", I2C_NAME_SIZE);
+
+	data->valid = 0;
+
+	init_MUTEX(&data->update_lock);
+
+	err = i2c_attach_client(new_client);
+
+	if (err)
+	{
+		dev_err(&new_client->dev, "Attach client error.\n");
+		goto exit_free;
+	}
+
+	device_create_file(&new_client->dev, &dev_attr_gpio1);
+	device_create_file(&new_client->dev, &dev_attr_gpio2);
+	device_create_file(&new_client->dev, &dev_attr_cpu0_vid);
+
+	dev_info(&new_client->dev, "Using VRM: %d.%d\n",
+			 data->vrm / 10, data->vrm % 10);
+
+	return 0;
+
+exit_free:
+	kfree(data);
+exit:
+	return err;
+};
+
+static int atxp1_detach_client(struct i2c_client * client)
+{
+	int err;
+
+	err = i2c_detach_client(client);
+
+	if (err)
+		dev_err(&client->dev, "Failed to detach client.\n");
+	else
+		kfree(i2c_get_clientdata(client));
+
+	return err;
+};
+
+static int __init atxp1_init(void)
+{
+	return i2c_add_driver(&atxp1_driver);
+};
+
+static void __exit atxp1_exit(void)
+{
+	i2c_del_driver(&atxp1_driver);
+};
+
+module_init(atxp1_init);
+module_exit(atxp1_exit);
diff --git a/drivers/hwmon/ds1621.c b/drivers/hwmon/ds1621.c
new file mode 100644
--- /dev/null
+++ b/drivers/hwmon/ds1621.c
@@ -0,0 +1,341 @@
+/*
+    ds1621.c - Part of lm_sensors, Linux kernel modules for hardware
+             monitoring
+    Christian W. Zuckschwerdt  <zany@triq.net>  2000-11-23
+    based on lm75.c by Frodo Looijaard <frodol@dds.nl>
+    Ported to Linux 2.6 by Aurelien Jarno <aurelien@aurel32.net> with 
+    the help of Jean Delvare <khali@linux-fr.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.
+*/
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+#include <linux/i2c.h>
+#include <linux/i2c-sensor.h>
+#include "lm75.h"
+
+/* Addresses to scan */
+static unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, 0x4c,
+					0x4d, 0x4e, 0x4f, I2C_CLIENT_END };
+static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
+
+/* Insmod parameters */
+SENSORS_INSMOD_1(ds1621);
+static int polarity = -1;
+module_param(polarity, int, 0);
+MODULE_PARM_DESC(polarity, "Output's polarity: 0 = active high, 1 = active low");
+
+/* Many DS1621 constants specified below */
+/* Config register used for detection         */
+/*  7    6    5    4    3    2    1    0      */
+/* |Done|THF |TLF |NVB | X  | X  |POL |1SHOT| */
+#define DS1621_REG_CONFIG_NVB		0x10
+#define DS1621_REG_CONFIG_POLARITY	0x02
+#define DS1621_REG_CONFIG_1SHOT		0x01
+#define DS1621_REG_CONFIG_DONE		0x80
+
+/* The DS1621 registers */
+#define DS1621_REG_TEMP			0xAA /* word, RO */
+#define DS1621_REG_TEMP_MIN		0xA1 /* word, RW */
+#define DS1621_REG_TEMP_MAX		0xA2 /* word, RW */
+#define DS1621_REG_CONF			0xAC /* byte, RW */
+#define DS1621_COM_START		0xEE /* no data */
+#define DS1621_COM_STOP			0x22 /* no data */
+
+/* The DS1621 configuration register */
+#define DS1621_ALARM_TEMP_HIGH		0x40
+#define DS1621_ALARM_TEMP_LOW		0x20
+
+/* Conversions. Rounding and limit checking is only done on the TO_REG
+   variants. Note that you should be a bit careful with which arguments
+   these macros are called: arguments may be evaluated more than once.
+   Fixing this is just not worth it. */
+#define ALARMS_FROM_REG(val) ((val) & \
+                              (DS1621_ALARM_TEMP_HIGH | DS1621_ALARM_TEMP_LOW))
+
+/* Each client has this additional data */
+struct ds1621_data {
+	struct i2c_client client;
+	struct semaphore update_lock;
+	char valid;			/* !=0 if following fields are valid */
+	unsigned long last_updated;	/* In jiffies */
+
+	u16 temp, temp_min, temp_max;	/* Register values, word */
+	u8 conf;			/* Register encoding, combined */
+};
+
+static int ds1621_attach_adapter(struct i2c_adapter *adapter);
+static int ds1621_detect(struct i2c_adapter *adapter, int address,
+			 int kind);
+static void ds1621_init_client(struct i2c_client *client);
+static int ds1621_detach_client(struct i2c_client *client);
+static struct ds1621_data *ds1621_update_client(struct device *dev);
+
+/* This is the driver that will be inserted */
+static struct i2c_driver ds1621_driver = {
+	.owner		= THIS_MODULE,
+	.name		= "ds1621",
+	.id		= I2C_DRIVERID_DS1621,
+	.flags		= I2C_DF_NOTIFY,
+	.attach_adapter	= ds1621_attach_adapter,
+	.detach_client	= ds1621_detach_client,
+};
+
+/* All registers are word-sized, except for the configuration register.
+   DS1621 uses a high-byte first convention, which is exactly opposite to
+   the usual practice. */
+static int ds1621_read_value(struct i2c_client *client, u8 reg)
+{
+	if (reg == DS1621_REG_CONF)
+		return i2c_smbus_read_byte_data(client, reg);
+	else
+		return swab16(i2c_smbus_read_word_data(client, reg));
+}
+
+/* All registers are word-sized, except for the configuration register.
+   DS1621 uses a high-byte first convention, which is exactly opposite to
+   the usual practice. */
+static int ds1621_write_value(struct i2c_client *client, u8 reg, u16 value)
+{
+	if (reg == DS1621_REG_CONF)
+		return i2c_smbus_write_byte_data(client, reg, value);
+	else
+		return i2c_smbus_write_word_data(client, reg, swab16(value));
+}
+
+static void ds1621_init_client(struct i2c_client *client)
+{
+	int reg = ds1621_read_value(client, DS1621_REG_CONF);
+	/* switch to continuous conversion mode */
+	reg &= ~ DS1621_REG_CONFIG_1SHOT;
+
+	/* setup output polarity */
+	if (polarity == 0)
+		reg &= ~DS1621_REG_CONFIG_POLARITY;
+	else if (polarity == 1)
+		reg |= DS1621_REG_CONFIG_POLARITY;
+	
+	ds1621_write_value(client, DS1621_REG_CONF, reg);
+	
+	/* start conversion */
+	i2c_smbus_write_byte(client, DS1621_COM_START);
+}
+
+#define show(value)							\
+static ssize_t show_##value(struct device *dev, struct device_attribute *attr, char *buf)		\
+{									\
+	struct ds1621_data *data = ds1621_update_client(dev);		\
+	return sprintf(buf, "%d\n", LM75_TEMP_FROM_REG(data->value));	\
+}
+
+show(temp);
+show(temp_min);
+show(temp_max);
+
+#define set_temp(suffix, value, reg)					\
+static ssize_t set_temp_##suffix(struct device *dev, struct device_attribute *attr, const char *buf,	\
+				 size_t count)				\
+{									\
+	struct i2c_client *client = to_i2c_client(dev);			\
+	struct ds1621_data *data = ds1621_update_client(dev);		\
+	u16 val = LM75_TEMP_TO_REG(simple_strtoul(buf, NULL, 10));	\
+									\
+	down(&data->update_lock);					\
+	data->value = val;						\
+	ds1621_write_value(client, reg, data->value);			\
+	up(&data->update_lock);						\
+	return count;							\
+}
+
+set_temp(min, temp_min, DS1621_REG_TEMP_MIN);
+set_temp(max, temp_max, DS1621_REG_TEMP_MAX);
+
+static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct ds1621_data *data = ds1621_update_client(dev);
+	return sprintf(buf, "%d\n", ALARMS_FROM_REG(data->conf));
+}
+
+static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
+static DEVICE_ATTR(temp1_input, S_IRUGO , show_temp, NULL);
+static DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO , show_temp_min, set_temp_min);
+static DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp_max, set_temp_max);
+
+
+static int ds1621_attach_adapter(struct i2c_adapter *adapter)
+{
+	return i2c_detect(adapter, &addr_data, ds1621_detect);
+}
+
+/* This function is called by i2c_detect */
+int ds1621_detect(struct i2c_adapter *adapter, int address,
+                  int kind)
+{
+	int conf, temp;
+	struct i2c_client *new_client;
+	struct ds1621_data *data;
+	int err = 0;
+
+	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA 
+				     | I2C_FUNC_SMBUS_WORD_DATA 
+				     | I2C_FUNC_SMBUS_WRITE_BYTE))
+		goto exit;
+
+	/* OK. For now, we presume we have a valid client. We now create the
+	   client structure, even though we cannot fill it completely yet.
+	   But it allows us to access ds1621_{read,write}_value. */
+	if (!(data = kmalloc(sizeof(struct ds1621_data), GFP_KERNEL))) {
+		err = -ENOMEM;
+		goto exit;
+	}
+	memset(data, 0, sizeof(struct ds1621_data));
+	
+	new_client = &data->client;
+	i2c_set_clientdata(new_client, data);
+	new_client->addr = address;
+	new_client->adapter = adapter;
+	new_client->driver = &ds1621_driver;
+	new_client->flags = 0;
+
+
+	/* Now, we do the remaining detection. It is lousy. */
+	if (kind < 0) {
+		/* The NVB bit should be low if no EEPROM write has been 
+		   requested during the latest 10ms, which is highly 
+		   improbable in our case. */
+		conf = ds1621_read_value(new_client, DS1621_REG_CONF);
+		if (conf & DS1621_REG_CONFIG_NVB)
+			goto exit_free;
+		/* The 7 lowest bits of a temperature should always be 0. */
+		temp = ds1621_read_value(new_client, DS1621_REG_TEMP);
+		if (temp & 0x007f)
+			goto exit_free;
+		temp = ds1621_read_value(new_client, DS1621_REG_TEMP_MIN);
+		if (temp & 0x007f)
+			goto exit_free;
+		temp = ds1621_read_value(new_client, DS1621_REG_TEMP_MAX);
+		if (temp & 0x007f)
+			goto exit_free;
+	}
+
+	/* Determine the chip type - only one kind supported! */
+	if (kind <= 0)
+		kind = ds1621;
+
+	/* Fill in remaining client fields and put it into the global list */
+	strlcpy(new_client->name, "ds1621", I2C_NAME_SIZE);
+	data->valid = 0;
+	init_MUTEX(&data->update_lock);
+
+	/* Tell the I2C layer a new client has arrived */
+	if ((err = i2c_attach_client(new_client)))
+		goto exit_free;
+
+	/* Initialize the DS1621 chip */
+	ds1621_init_client(new_client);
+
+	/* Register sysfs hooks */
+	device_create_file(&new_client->dev, &dev_attr_alarms);
+	device_create_file(&new_client->dev, &dev_attr_temp1_input);
+	device_create_file(&new_client->dev, &dev_attr_temp1_min);
+	device_create_file(&new_client->dev, &dev_attr_temp1_max);
+	
+	return 0;
+
+/* OK, this is not exactly good programming practice, usually. But it is
+   very code-efficient in this case. */
+      exit_free:
+	kfree(data);
+      exit:
+	return err;
+}
+
+static int ds1621_detach_client(struct i2c_client *client)
+{
+	int err;
+
+	if ((err = i2c_detach_client(client))) {
+		dev_err(&client->dev, "Client deregistration failed, "
+			"client not detached.\n");
+		return err;
+	}
+
+	kfree(i2c_get_clientdata(client));
+
+	return 0;
+}
+
+
+static struct ds1621_data *ds1621_update_client(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct ds1621_data *data = i2c_get_clientdata(client);
+	u8 new_conf;
+
+	down(&data->update_lock);
+
+	if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
+	    || !data->valid) {
+
+		dev_dbg(&client->dev, "Starting ds1621 update\n");
+
+		data->conf = ds1621_read_value(client, DS1621_REG_CONF);
+
+		data->temp = ds1621_read_value(client, DS1621_REG_TEMP);
+		
+		data->temp_min = ds1621_read_value(client,
+		                                    DS1621_REG_TEMP_MIN);
+		data->temp_max = ds1621_read_value(client,
+						    DS1621_REG_TEMP_MAX);
+
+		/* reset alarms if necessary */
+		new_conf = data->conf;
+		if (data->temp < data->temp_min)
+			new_conf &= ~DS1621_ALARM_TEMP_LOW;
+		if (data->temp > data->temp_max)
+			new_conf &= ~DS1621_ALARM_TEMP_HIGH;
+		if (data->conf != new_conf)
+			ds1621_write_value(client, DS1621_REG_CONF,
+					   new_conf);
+
+		data->last_updated = jiffies;
+		data->valid = 1;
+	}
+
+	up(&data->update_lock);
+
+	return data;
+}
+
+static int __init ds1621_init(void)
+{
+	return i2c_add_driver(&ds1621_driver);
+}
+
+static void __exit ds1621_exit(void)
+{
+	i2c_del_driver(&ds1621_driver);
+}
+
+
+MODULE_AUTHOR("Christian W. Zuckschwerdt <zany@triq.net>");
+MODULE_DESCRIPTION("DS1621 driver");
+MODULE_LICENSE("GPL");
+
+module_init(ds1621_init);
+module_exit(ds1621_exit);
diff --git a/drivers/hwmon/fscher.c b/drivers/hwmon/fscher.c
new file mode 100644
--- /dev/null
+++ b/drivers/hwmon/fscher.c
@@ -0,0 +1,691 @@
+/*
+ * fscher.c - Part of lm_sensors, Linux kernel modules for hardware
+ * monitoring
+ * Copyright (C) 2003, 2004 Reinhard Nissl <rnissl@gmx.de>
+ * 
+ * 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.
+ */
+
+/* 
+ *  fujitsu siemens hermes chip, 
+ *  module based on fscpos.c 
+ *  Copyright (C) 2000 Hermann Jung <hej@odn.de>
+ *  Copyright (C) 1998, 1999 Frodo Looijaard <frodol@dds.nl>
+ *  and Philip Edelbrock <phil@netroedge.com>
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+#include <linux/i2c.h>
+#include <linux/i2c-sensor.h>
+
+/*
+ * Addresses to scan
+ */
+
+static unsigned short normal_i2c[] = { 0x73, I2C_CLIENT_END };
+static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
+
+/*
+ * Insmod parameters
+ */
+
+SENSORS_INSMOD_1(fscher);
+
+/*
+ * The FSCHER registers
+ */
+
+/* chip identification */
+#define FSCHER_REG_IDENT_0		0x00
+#define FSCHER_REG_IDENT_1		0x01
+#define FSCHER_REG_IDENT_2		0x02
+#define FSCHER_REG_REVISION		0x03
+
+/* global control and status */
+#define FSCHER_REG_EVENT_STATE		0x04
+#define FSCHER_REG_CONTROL		0x05
+
+/* watchdog */
+#define FSCHER_REG_WDOG_PRESET		0x28
+#define FSCHER_REG_WDOG_STATE		0x23
+#define FSCHER_REG_WDOG_CONTROL		0x21
+
+/* fan 0 */
+#define FSCHER_REG_FAN0_MIN		0x55
+#define FSCHER_REG_FAN0_ACT		0x0e
+#define FSCHER_REG_FAN0_STATE		0x0d
+#define FSCHER_REG_FAN0_RIPPLE		0x0f
+
+/* fan 1 */
+#define FSCHER_REG_FAN1_MIN		0x65
+#define FSCHER_REG_FAN1_ACT		0x6b
+#define FSCHER_REG_FAN1_STATE		0x62
+#define FSCHER_REG_FAN1_RIPPLE		0x6f
+
+/* fan 2 */
+#define FSCHER_REG_FAN2_MIN		0xb5
+#define FSCHER_REG_FAN2_ACT		0xbb
+#define FSCHER_REG_FAN2_STATE		0xb2
+#define FSCHER_REG_FAN2_RIPPLE		0xbf
+
+/* voltage supervision */
+#define FSCHER_REG_VOLT_12		0x45
+#define FSCHER_REG_VOLT_5		0x42
+#define FSCHER_REG_VOLT_BATT		0x48
+
+/* temperature 0 */
+#define FSCHER_REG_TEMP0_ACT		0x64
+#define FSCHER_REG_TEMP0_STATE		0x71
+
+/* temperature 1 */
+#define FSCHER_REG_TEMP1_ACT		0x32
+#define FSCHER_REG_TEMP1_STATE		0x81
+
+/* temperature 2 */
+#define FSCHER_REG_TEMP2_ACT		0x35
+#define FSCHER_REG_TEMP2_STATE		0x91
+
+/*
+ * Functions declaration
+ */
+
+static int fscher_attach_adapter(struct i2c_adapter *adapter);
+static int fscher_detect(struct i2c_adapter *adapter, int address, int kind);
+static int fscher_detach_client(struct i2c_client *client);
+static struct fscher_data *fscher_update_device(struct device *dev);
+static void fscher_init_client(struct i2c_client *client);
+
+static int fscher_read_value(struct i2c_client *client, u8 reg);
+static int fscher_write_value(struct i2c_client *client, u8 reg, u8 value);
+
+/*
+ * Driver data (common to all clients)
+ */
+ 
+static struct i2c_driver fscher_driver = {
+	.owner		= THIS_MODULE,
+	.name		= "fscher",
+	.id		= I2C_DRIVERID_FSCHER,
+	.flags		= I2C_DF_NOTIFY,
+	.attach_adapter	= fscher_attach_adapter,
+	.detach_client	= fscher_detach_client,
+};
+
+/*
+ * Client data (each client gets its own)
+ */
+
+struct fscher_data {
+	struct i2c_client client;
+	struct semaphore update_lock;
+	char valid; /* zero until following fields are valid */
+	unsigned long last_updated; /* in jiffies */
+
+	/* register values */
+	u8 revision;		/* revision of chip */
+	u8 global_event;	/* global event status */
+	u8 global_control;	/* global control register */
+	u8 watchdog[3];		/* watchdog */
+	u8 volt[3];		/* 12, 5, battery voltage */ 
+	u8 temp_act[3];		/* temperature */
+	u8 temp_status[3];	/* status of sensor */
+	u8 fan_act[3];		/* fans revolutions per second */
+	u8 fan_status[3];	/* fan status */
+	u8 fan_min[3];		/* fan min value for rps */
+	u8 fan_ripple[3];	/* divider for rps */
+};
+
+/*
+ * Sysfs stuff
+ */
+
+#define sysfs_r(kind, sub, offset, reg) \
+static ssize_t show_##kind##sub (struct fscher_data *, char *, int); \
+static ssize_t show_##kind##offset##sub (struct device *, struct device_attribute *attr, char *); \
+static ssize_t show_##kind##offset##sub (struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+	struct fscher_data *data = fscher_update_device(dev); \
+	return show_##kind##sub(data, buf, (offset)); \
+}
+
+#define sysfs_w(kind, sub, offset, reg) \
+static ssize_t set_##kind##sub (struct i2c_client *, struct fscher_data *, const char *, size_t, int, int); \
+static ssize_t set_##kind##offset##sub (struct device *, struct device_attribute *attr, const char *, size_t); \
+static ssize_t set_##kind##offset##sub (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \
+{ \
+	struct i2c_client *client = to_i2c_client(dev); \
+	struct fscher_data *data = i2c_get_clientdata(client); \
+	return set_##kind##sub(client, data, buf, count, (offset), reg); \
+}
+
+#define sysfs_rw_n(kind, sub, offset, reg) \
+sysfs_r(kind, sub, offset, reg) \
+sysfs_w(kind, sub, offset, reg) \
+static DEVICE_ATTR(kind##offset##sub, S_IRUGO | S_IWUSR, show_##kind##offset##sub, set_##kind##offset##sub);
+
+#define sysfs_rw(kind, sub, reg) \
+sysfs_r(kind, sub, 0, reg) \
+sysfs_w(kind, sub, 0, reg) \
+static DEVICE_ATTR(kind##sub, S_IRUGO | S_IWUSR, show_##kind##0##sub, set_##kind##0##sub);
+
+#define sysfs_ro_n(kind, sub, offset, reg) \
+sysfs_r(kind, sub, offset, reg) \
+static DEVICE_ATTR(kind##offset##sub, S_IRUGO, show_##kind##offset##sub, NULL);
+
+#define sysfs_ro(kind, sub, reg) \
+sysfs_r(kind, sub, 0, reg) \
+static DEVICE_ATTR(kind, S_IRUGO, show_##kind##0##sub, NULL);
+
+#define sysfs_fan(offset, reg_status, reg_min, reg_ripple, reg_act) \
+sysfs_rw_n(pwm,        , offset, reg_min) \
+sysfs_rw_n(fan, _status, offset, reg_status) \
+sysfs_rw_n(fan, _div   , offset, reg_ripple) \
+sysfs_ro_n(fan, _input , offset, reg_act)
+
+#define sysfs_temp(offset, reg_status, reg_act) \
+sysfs_rw_n(temp, _status, offset, reg_status) \
+sysfs_ro_n(temp, _input , offset, reg_act)
+    
+#define sysfs_in(offset, reg_act) \
+sysfs_ro_n(in, _input, offset, reg_act)
+
+#define sysfs_revision(reg_revision) \
+sysfs_ro(revision, , reg_revision)
+
+#define sysfs_alarms(reg_events) \
+sysfs_ro(alarms, , reg_events)
+
+#define sysfs_control(reg_control) \
+sysfs_rw(control, , reg_control)
+
+#define sysfs_watchdog(reg_control, reg_status, reg_preset) \
+sysfs_rw(watchdog, _control, reg_control) \
+sysfs_rw(watchdog, _status , reg_status) \
+sysfs_rw(watchdog, _preset , reg_preset)
+
+sysfs_fan(1, FSCHER_REG_FAN0_STATE, FSCHER_REG_FAN0_MIN,
+	     FSCHER_REG_FAN0_RIPPLE, FSCHER_REG_FAN0_ACT)
+sysfs_fan(2, FSCHER_REG_FAN1_STATE, FSCHER_REG_FAN1_MIN,
+	     FSCHER_REG_FAN1_RIPPLE, FSCHER_REG_FAN1_ACT)
+sysfs_fan(3, FSCHER_REG_FAN2_STATE, FSCHER_REG_FAN2_MIN,
+	     FSCHER_REG_FAN2_RIPPLE, FSCHER_REG_FAN2_ACT)
+
+sysfs_temp(1, FSCHER_REG_TEMP0_STATE, FSCHER_REG_TEMP0_ACT)
+sysfs_temp(2, FSCHER_REG_TEMP1_STATE, FSCHER_REG_TEMP1_ACT)
+sysfs_temp(3, FSCHER_REG_TEMP2_STATE, FSCHER_REG_TEMP2_ACT)
+
+sysfs_in(0, FSCHER_REG_VOLT_12)
+sysfs_in(1, FSCHER_REG_VOLT_5)
+sysfs_in(2, FSCHER_REG_VOLT_BATT)
+
+sysfs_revision(FSCHER_REG_REVISION)
+sysfs_alarms(FSCHER_REG_EVENTS)
+sysfs_control(FSCHER_REG_CONTROL)
+sysfs_watchdog(FSCHER_REG_WDOG_CONTROL, FSCHER_REG_WDOG_STATE, FSCHER_REG_WDOG_PRESET)
+  
+#define device_create_file_fan(client, offset) \
+do { \
+	device_create_file(&client->dev, &dev_attr_fan##offset##_status); \
+	device_create_file(&client->dev, &dev_attr_pwm##offset); \
+	device_create_file(&client->dev, &dev_attr_fan##offset##_div); \
+	device_create_file(&client->dev, &dev_attr_fan##offset##_input); \
+} while (0)
+
+#define device_create_file_temp(client, offset) \
+do { \
+	device_create_file(&client->dev, &dev_attr_temp##offset##_status); \
+	device_create_file(&client->dev, &dev_attr_temp##offset##_input); \
+} while (0)
+
+#define device_create_file_in(client, offset) \
+do { \
+	device_create_file(&client->dev, &dev_attr_in##offset##_input); \
+} while (0)
+
+#define device_create_file_revision(client) \
+do { \
+	device_create_file(&client->dev, &dev_attr_revision); \
+} while (0)
+
+#define device_create_file_alarms(client) \
+do { \
+	device_create_file(&client->dev, &dev_attr_alarms); \
+} while (0)
+
+#define device_create_file_control(client) \
+do { \
+	device_create_file(&client->dev, &dev_attr_control); \
+} while (0)
+
+#define device_create_file_watchdog(client) \
+do { \
+	device_create_file(&client->dev, &dev_attr_watchdog_status); \
+	device_create_file(&client->dev, &dev_attr_watchdog_control); \
+	device_create_file(&client->dev, &dev_attr_watchdog_preset); \
+} while (0)
+  
+/*
+ * Real code
+ */
+
+static int fscher_attach_adapter(struct i2c_adapter *adapter)
+{
+	if (!(adapter->class & I2C_CLASS_HWMON))
+		return 0;
+	return i2c_detect(adapter, &addr_data, fscher_detect);
+}
+
+static int fscher_detect(struct i2c_adapter *adapter, int address, int kind)
+{
+	struct i2c_client *new_client;
+	struct fscher_data *data;
+	int err = 0;
+
+	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+		goto exit;
+
+	/* OK. For now, we presume we have a valid client. We now create the
+	 * client structure, even though we cannot fill it completely yet.
+	 * But it allows us to access i2c_smbus_read_byte_data. */
+	if (!(data = kmalloc(sizeof(struct fscher_data), GFP_KERNEL))) {
+		err = -ENOMEM;
+		goto exit;
+  	}
+	memset(data, 0, sizeof(struct fscher_data));
+
+	/* The common I2C client data is placed right before the
+	 * Hermes-specific data. */
+	new_client = &data->client;
+	i2c_set_clientdata(new_client, data);
+	new_client->addr = address;
+	new_client->adapter = adapter;
+	new_client->driver = &fscher_driver;
+	new_client->flags = 0;
+
+	/* Do the remaining detection unless force or force_fscher parameter */
+	if (kind < 0) {
+		if ((i2c_smbus_read_byte_data(new_client,
+		     FSCHER_REG_IDENT_0) != 0x48)	/* 'H' */
+		 || (i2c_smbus_read_byte_data(new_client,
+		     FSCHER_REG_IDENT_1) != 0x45)	/* 'E' */
+		 || (i2c_smbus_read_byte_data(new_client,
+		     FSCHER_REG_IDENT_2) != 0x52))	/* 'R' */
+			goto exit_free;
+	}
+
+	/* Fill in the remaining client fields and put it into the
+	 * global list */
+	strlcpy(new_client->name, "fscher", I2C_NAME_SIZE);
+	data->valid = 0;
+	init_MUTEX(&data->update_lock);
+
+	/* Tell the I2C layer a new client has arrived */
+	if ((err = i2c_attach_client(new_client)))
+		goto exit_free;
+
+	fscher_init_client(new_client);
+
+	/* Register sysfs hooks */
+	device_create_file_revision(new_client);
+	device_create_file_alarms(new_client);
+	device_create_file_control(new_client);
+	device_create_file_watchdog(new_client);
+
+	device_create_file_in(new_client, 0);
+	device_create_file_in(new_client, 1);
+	device_create_file_in(new_client, 2);
+
+	device_create_file_fan(new_client, 1);
+	device_create_file_fan(new_client, 2);
+	device_create_file_fan(new_client, 3);
+
+	device_create_file_temp(new_client, 1);
+	device_create_file_temp(new_client, 2);
+	device_create_file_temp(new_client, 3);
+
+	return 0;
+
+exit_free:
+	kfree(data);
+exit:
+	return err;
+}
+
+static int fscher_detach_client(struct i2c_client *client)
+{
+	int err;
+
+	if ((err = i2c_detach_client(client))) {
+		dev_err(&client->dev, "Client deregistration failed, "
+			"client not detached.\n");
+		return err;
+	}
+
+	kfree(i2c_get_clientdata(client));
+	return 0;
+}
+
+static int fscher_read_value(struct i2c_client *client, u8 reg)
+{
+	dev_dbg(&client->dev, "read reg 0x%02x\n", reg);
+
+	return i2c_smbus_read_byte_data(client, reg);
+}
+
+static int fscher_write_value(struct i2c_client *client, u8 reg, u8 value)
+{
+	dev_dbg(&client->dev, "write reg 0x%02x, val 0x%02x\n",
+		reg, value);
+
+	return i2c_smbus_write_byte_data(client, reg, value);
+}
+
+/* Called when we have found a new FSC Hermes. */
+static void fscher_init_client(struct i2c_client *client)
+{
+	struct fscher_data *data = i2c_get_clientdata(client);
+
+	/* Read revision from chip */
+	data->revision =  fscher_read_value(client, FSCHER_REG_REVISION);
+}
+
+static struct fscher_data *fscher_update_device(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct fscher_data *data = i2c_get_clientdata(client);
+
+	down(&data->update_lock);
+
+	if (time_after(jiffies, data->last_updated + 2 * HZ) || !data->valid) {
+
+		dev_dbg(&client->dev, "Starting fscher update\n");
+
+		data->temp_act[0] = fscher_read_value(client, FSCHER_REG_TEMP0_ACT);
+		data->temp_act[1] = fscher_read_value(client, FSCHER_REG_TEMP1_ACT);
+		data->temp_act[2] = fscher_read_value(client, FSCHER_REG_TEMP2_ACT);
+		data->temp_status[0] = fscher_read_value(client, FSCHER_REG_TEMP0_STATE);
+		data->temp_status[1] = fscher_read_value(client, FSCHER_REG_TEMP1_STATE);
+		data->temp_status[2] = fscher_read_value(client, FSCHER_REG_TEMP2_STATE);
+
+		data->volt[0] = fscher_read_value(client, FSCHER_REG_VOLT_12);
+		data->volt[1] = fscher_read_value(client, FSCHER_REG_VOLT_5);
+		data->volt[2] = fscher_read_value(client, FSCHER_REG_VOLT_BATT);
+
+		data->fan_act[0] = fscher_read_value(client, FSCHER_REG_FAN0_ACT);
+		data->fan_act[1] = fscher_read_value(client, FSCHER_REG_FAN1_ACT);
+		data->fan_act[2] = fscher_read_value(client, FSCHER_REG_FAN2_ACT);
+		data->fan_status[0] = fscher_read_value(client, FSCHER_REG_FAN0_STATE);
+		data->fan_status[1] = fscher_read_value(client, FSCHER_REG_FAN1_STATE);
+		data->fan_status[2] = fscher_read_value(client, FSCHER_REG_FAN2_STATE);
+		data->fan_min[0] = fscher_read_value(client, FSCHER_REG_FAN0_MIN);
+		data->fan_min[1] = fscher_read_value(client, FSCHER_REG_FAN1_MIN);
+		data->fan_min[2] = fscher_read_value(client, FSCHER_REG_FAN2_MIN);
+		data->fan_ripple[0] = fscher_read_value(client, FSCHER_REG_FAN0_RIPPLE);
+		data->fan_ripple[1] = fscher_read_value(client, FSCHER_REG_FAN1_RIPPLE);
+		data->fan_ripple[2] = fscher_read_value(client, FSCHER_REG_FAN2_RIPPLE);
+
+		data->watchdog[0] = fscher_read_value(client, FSCHER_REG_WDOG_PRESET);
+		data->watchdog[1] = fscher_read_value(client, FSCHER_REG_WDOG_STATE);
+		data->watchdog[2] = fscher_read_value(client, FSCHER_REG_WDOG_CONTROL);
+
+		data->global_event = fscher_read_value(client, FSCHER_REG_EVENT_STATE);
+
+		data->last_updated = jiffies;
+		data->valid = 1;                 
+	}
+
+	up(&data->update_lock);
+
+	return data;
+}
+
+
+
+#define FAN_INDEX_FROM_NUM(nr)	((nr) - 1)
+
+static ssize_t set_fan_status(struct i2c_client *client, struct fscher_data *data,
+			      const char *buf, size_t count, int nr, int reg)
+{
+	/* bits 0..1, 3..7 reserved => mask with 0x04 */  
+	unsigned long v = simple_strtoul(buf, NULL, 10) & 0x04;
+	
+	down(&data->update_lock);
+	data->fan_status[FAN_INDEX_FROM_NUM(nr)] &= ~v;
+	fscher_write_value(client, reg, v);
+	up(&data->update_lock);
+	return count;
+}
+
+static ssize_t show_fan_status(struct fscher_data *data, char *buf, int nr)
+{
+	/* bits 0..1, 3..7 reserved => mask with 0x04 */  
+	return sprintf(buf, "%u\n", data->fan_status[FAN_INDEX_FROM_NUM(nr)] & 0x04);
+}
+
+static ssize_t set_pwm(struct i2c_client *client, struct fscher_data *data,
+		       const char *buf, size_t count, int nr, int reg)
+{
+	unsigned long v = simple_strtoul(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->fan_min[FAN_INDEX_FROM_NUM(nr)] = v > 0xff ? 0xff : v;
+	fscher_write_value(client, reg, data->fan_min[FAN_INDEX_FROM_NUM(nr)]);
+	up(&data->update_lock);
+	return count;
+}
+
+static ssize_t show_pwm(struct fscher_data *data, char *buf, int nr)
+{
+	return sprintf(buf, "%u\n", data->fan_min[FAN_INDEX_FROM_NUM(nr)]);
+}
+
+static ssize_t set_fan_div(struct i2c_client *client, struct fscher_data *data,
+			   const char *buf, size_t count, int nr, int reg)
+{
+	/* supported values: 2, 4, 8 */
+	unsigned long v = simple_strtoul(buf, NULL, 10);
+
+	switch (v) {
+	case 2: v = 1; break;
+	case 4: v = 2; break;
+	case 8: v = 3; break;
+	default:
+		dev_err(&client->dev, "fan_div value %ld not "
+			 "supported. Choose one of 2, 4 or 8!\n", v);
+		return -EINVAL;
+	}
+
+	down(&data->update_lock);
+
+	/* bits 2..7 reserved => mask with 0x03 */
+	data->fan_ripple[FAN_INDEX_FROM_NUM(nr)] &= ~0x03;
+	data->fan_ripple[FAN_INDEX_FROM_NUM(nr)] |= v;
+
+	fscher_write_value(client, reg, data->fan_ripple[FAN_INDEX_FROM_NUM(nr)]);
+	up(&data->update_lock);
+	return count;
+}
+
+static ssize_t show_fan_div(struct fscher_data *data, char *buf, int nr)
+{
+	/* bits 2..7 reserved => mask with 0x03 */  
+	return sprintf(buf, "%u\n", 1 << (data->fan_ripple[FAN_INDEX_FROM_NUM(nr)] & 0x03));
+}
+
+#define RPM_FROM_REG(val)	(val*60)
+
+static ssize_t show_fan_input (struct fscher_data *data, char *buf, int nr)
+{
+	return sprintf(buf, "%u\n", RPM_FROM_REG(data->fan_act[FAN_INDEX_FROM_NUM(nr)]));
+}
+
+
+
+#define TEMP_INDEX_FROM_NUM(nr)		((nr) - 1)
+
+static ssize_t set_temp_status(struct i2c_client *client, struct fscher_data *data,
+			       const char *buf, size_t count, int nr, int reg)
+{
+	/* bits 2..7 reserved, 0 read only => mask with 0x02 */  
+	unsigned long v = simple_strtoul(buf, NULL, 10) & 0x02;
+
+	down(&data->update_lock);
+	data->temp_status[TEMP_INDEX_FROM_NUM(nr)] &= ~v;
+	fscher_write_value(client, reg, v);
+	up(&data->update_lock);
+	return count;
+}
+
+static ssize_t show_temp_status(struct fscher_data *data, char *buf, int nr)
+{
+	/* bits 2..7 reserved => mask with 0x03 */
+	return sprintf(buf, "%u\n", data->temp_status[TEMP_INDEX_FROM_NUM(nr)] & 0x03);
+}
+
+#define TEMP_FROM_REG(val)	(((val) - 128) * 1000)
+
+static ssize_t show_temp_input(struct fscher_data *data, char *buf, int nr)
+{
+	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_act[TEMP_INDEX_FROM_NUM(nr)]));
+}
+
+/*
+ * The final conversion is specified in sensors.conf, as it depends on
+ * mainboard specific values. We export the registers contents as
+ * pseudo-hundredths-of-Volts (range 0V - 2.55V). Not that it makes much
+ * sense per se, but it minimizes the conversions count and keeps the
+ * values within a usual range.
+ */
+#define VOLT_FROM_REG(val)	((val) * 10)
+
+static ssize_t show_in_input(struct fscher_data *data, char *buf, int nr)
+{
+	return sprintf(buf, "%u\n", VOLT_FROM_REG(data->volt[nr]));
+}
+
+
+
+static ssize_t show_revision(struct fscher_data *data, char *buf, int nr)
+{
+	return sprintf(buf, "%u\n", data->revision);
+}
+
+
+
+static ssize_t show_alarms(struct fscher_data *data, char *buf, int nr)
+{
+	/* bits 2, 5..6 reserved => mask with 0x9b */
+	return sprintf(buf, "%u\n", data->global_event & 0x9b);
+}
+
+
+
+static ssize_t set_control(struct i2c_client *client, struct fscher_data *data,
+			   const char *buf, size_t count, int nr, int reg)
+{
+	/* bits 1..7 reserved => mask with 0x01 */  
+	unsigned long v = simple_strtoul(buf, NULL, 10) & 0x01;
+
+	down(&data->update_lock);
+	data->global_control &= ~v;
+	fscher_write_value(client, reg, v);
+	up(&data->update_lock);
+	return count;
+}
+
+static ssize_t show_control(struct fscher_data *data, char *buf, int nr)
+{
+	/* bits 1..7 reserved => mask with 0x01 */
+	return sprintf(buf, "%u\n", data->global_control & 0x01);
+}
+
+
+
+static ssize_t set_watchdog_control(struct i2c_client *client, struct
+				    fscher_data *data, const char *buf, size_t count,
+				    int nr, int reg)
+{
+	/* bits 0..3 reserved => mask with 0xf0 */  
+	unsigned long v = simple_strtoul(buf, NULL, 10) & 0xf0;
+
+	down(&data->update_lock);
+	data->watchdog[2] &= ~0xf0;
+	data->watchdog[2] |= v;
+	fscher_write_value(client, reg, data->watchdog[2]);
+	up(&data->update_lock);
+	return count;
+}
+
+static ssize_t show_watchdog_control(struct fscher_data *data, char *buf, int nr)
+{
+	/* bits 0..3 reserved, bit 5 write only => mask with 0xd0 */
+	return sprintf(buf, "%u\n", data->watchdog[2] & 0xd0);
+}
+
+static ssize_t set_watchdog_status(struct i2c_client *client, struct fscher_data *data,
+				   const char *buf, size_t count, int nr, int reg)
+{
+	/* bits 0, 2..7 reserved => mask with 0x02 */  
+	unsigned long v = simple_strtoul(buf, NULL, 10) & 0x02;
+
+	down(&data->update_lock);
+	data->watchdog[1] &= ~v;
+	fscher_write_value(client, reg, v);
+	up(&data->update_lock);
+	return count;
+}
+
+static ssize_t show_watchdog_status(struct fscher_data *data, char *buf, int nr)
+{
+	/* bits 0, 2..7 reserved => mask with 0x02 */
+	return sprintf(buf, "%u\n", data->watchdog[1] & 0x02);
+}
+
+static ssize_t set_watchdog_preset(struct i2c_client *client, struct fscher_data *data,
+				   const char *buf, size_t count, int nr, int reg)
+{
+	unsigned long v = simple_strtoul(buf, NULL, 10) & 0xff;
+	
+	down(&data->update_lock);
+	data->watchdog[0] = v;
+	fscher_write_value(client, reg, data->watchdog[0]);
+	up(&data->update_lock);
+	return count;
+}
+
+static ssize_t show_watchdog_preset(struct fscher_data *data, char *buf, int nr)
+{
+	return sprintf(buf, "%u\n", data->watchdog[0]);
+}
+
+static int __init sensors_fscher_init(void)
+{
+	return i2c_add_driver(&fscher_driver);
+}
+
+static void __exit sensors_fscher_exit(void)
+{
+	i2c_del_driver(&fscher_driver);
+}
+
+MODULE_AUTHOR("Reinhard Nissl <rnissl@gmx.de>");
+MODULE_DESCRIPTION("FSC Hermes driver");
+MODULE_LICENSE("GPL");
+
+module_init(sensors_fscher_init);
+module_exit(sensors_fscher_exit);
diff --git a/drivers/hwmon/fscpos.c b/drivers/hwmon/fscpos.c
new file mode 100644
--- /dev/null
+++ b/drivers/hwmon/fscpos.c
@@ -0,0 +1,641 @@
+/*
+	fscpos.c - Kernel module for hardware monitoring with FSC Poseidon chips
+	Copyright (C) 2004, 2005 Stefan Ott <stefan@desire.ch>
+
+	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.
+*/
+
+/*
+	fujitsu siemens poseidon chip,
+	module based on the old fscpos module by Hermann Jung <hej@odn.de> and
+	the fscher module by Reinhard Nissl <rnissl@gmx.de>
+
+	original module based on lm80.c
+	Copyright (C) 1998, 1999 Frodo Looijaard <frodol@dds.nl>
+	and Philip Edelbrock <phil@netroedge.com>
+
+	Thanks to Jean Delvare for reviewing my code and suggesting a lot of
+	improvements.
+*/
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+#include <linux/i2c.h>
+#include <linux/i2c-sensor.h>
+#include <linux/init.h>
+
+/*
+ * Addresses to scan
+ */
+static unsigned short normal_i2c[] = { 0x73, I2C_CLIENT_END };
+static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
+
+/*
+ * Insmod parameters
+ */
+SENSORS_INSMOD_1(fscpos);
+
+/*
+ * The FSCPOS registers
+ */
+
+/* chip identification */
+#define FSCPOS_REG_IDENT_0		0x00
+#define FSCPOS_REG_IDENT_1		0x01
+#define FSCPOS_REG_IDENT_2		0x02
+#define FSCPOS_REG_REVISION		0x03
+
+/* global control and status */
+#define FSCPOS_REG_EVENT_STATE		0x04
+#define FSCPOS_REG_CONTROL		0x05
+
+/* watchdog */
+#define FSCPOS_REG_WDOG_PRESET		0x28
+#define FSCPOS_REG_WDOG_STATE		0x23
+#define FSCPOS_REG_WDOG_CONTROL		0x21
+
+/* voltages */
+#define FSCPOS_REG_VOLT_12		0x45
+#define FSCPOS_REG_VOLT_5		0x42
+#define FSCPOS_REG_VOLT_BATT		0x48
+
+/* fans - the chip does not support minimum speed for fan2 */
+static u8 FSCPOS_REG_PWM[] = { 0x55, 0x65 };
+static u8 FSCPOS_REG_FAN_ACT[] = { 0x0e, 0x6b, 0xab };
+static u8 FSCPOS_REG_FAN_STATE[] = { 0x0d, 0x62, 0xa2 };
+static u8 FSCPOS_REG_FAN_RIPPLE[] = { 0x0f, 0x6f, 0xaf };
+
+/* temperatures */
+static u8 FSCPOS_REG_TEMP_ACT[] = { 0x64, 0x32, 0x35 };
+static u8 FSCPOS_REG_TEMP_STATE[] = { 0x71, 0x81, 0x91 };
+
+/*
+ * Functions declaration
+ */
+static int fscpos_attach_adapter(struct i2c_adapter *adapter);
+static int fscpos_detect(struct i2c_adapter *adapter, int address, int kind);
+static int fscpos_detach_client(struct i2c_client *client);
+
+static int fscpos_read_value(struct i2c_client *client, u8 register);
+static int fscpos_write_value(struct i2c_client *client, u8 register, u8 value);
+static struct fscpos_data *fscpos_update_device(struct device *dev);
+static void fscpos_init_client(struct i2c_client *client);
+
+static void reset_fan_alarm(struct i2c_client *client, int nr);
+
+/*
+ * Driver data (common to all clients)
+ */
+static struct i2c_driver fscpos_driver = {
+	.owner		= THIS_MODULE,
+	.name		= "fscpos",
+	.id		= I2C_DRIVERID_FSCPOS,
+	.flags		= I2C_DF_NOTIFY,
+	.attach_adapter	= fscpos_attach_adapter,
+	.detach_client	= fscpos_detach_client,
+};
+
+/*
+ * Client data (each client gets its own)
+ */
+struct fscpos_data {
+	struct i2c_client client;
+	struct semaphore update_lock;
+	char valid; 		/* 0 until following fields are valid */
+	unsigned long last_updated;	/* In jiffies */
+
+	/* register values */
+	u8 revision;		/* revision of chip */
+	u8 global_event;	/* global event status */
+	u8 global_control;	/* global control register */
+	u8 wdog_control;	/* watchdog control */
+	u8 wdog_state;		/* watchdog status */
+	u8 wdog_preset;		/* watchdog preset */
+	u8 volt[3];		/* 12, 5, battery current */
+	u8 temp_act[3];		/* temperature */
+	u8 temp_status[3];	/* status of sensor */
+	u8 fan_act[3];		/* fans revolutions per second */
+	u8 fan_status[3];	/* fan status */
+	u8 pwm[2];		/* fan min value for rps */
+	u8 fan_ripple[3];	/* divider for rps */
+};
+
+/* Temperature */
+#define TEMP_FROM_REG(val)	(((val) - 128) * 1000)
+
+static ssize_t show_temp_input(struct fscpos_data *data, char *buf, int nr)
+{
+	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_act[nr - 1]));
+}
+
+static ssize_t show_temp_status(struct fscpos_data *data, char *buf, int nr)
+{
+	/* bits 2..7 reserved => mask with 0x03 */
+	return sprintf(buf, "%u\n", data->temp_status[nr - 1] & 0x03);
+}
+
+static ssize_t show_temp_reset(struct fscpos_data *data, char *buf, int nr)
+{
+	return sprintf(buf, "1\n");
+}
+
+static ssize_t set_temp_reset(struct i2c_client *client, struct fscpos_data
+			*data, const char *buf,	size_t count, int nr, int reg)
+{
+	unsigned long v = simple_strtoul(buf, NULL, 10);
+	if (v != 1) {
+		dev_err(&client->dev, "temp_reset value %ld not supported. "
+					"Use 1 to reset the alarm!\n", v);
+		return -EINVAL;
+	}
+
+	dev_info(&client->dev, "You used the temp_reset feature which has not "
+				"been proplerly tested. Please report your "
+				"experience to the module author.\n");
+
+	/* Supported value: 2 (clears the status) */
+	fscpos_write_value(client, FSCPOS_REG_TEMP_STATE[nr - 1], 2);
+	return count;
+}
+
+/* Fans */
+#define RPM_FROM_REG(val)	((val) * 60)
+
+static ssize_t show_fan_status(struct fscpos_data *data, char *buf, int nr)
+{
+	/* bits 0..1, 3..7 reserved => mask with 0x04 */
+	return sprintf(buf, "%u\n", data->fan_status[nr - 1] & 0x04);
+}
+
+static ssize_t show_fan_input(struct fscpos_data *data, char *buf, int nr)
+{
+	return sprintf(buf, "%u\n", RPM_FROM_REG(data->fan_act[nr - 1]));
+}
+
+static ssize_t show_fan_ripple(struct fscpos_data *data, char *buf, int nr)
+{
+	/* bits 2..7 reserved => mask with 0x03 */
+	return sprintf(buf, "%u\n", data->fan_ripple[nr - 1] & 0x03);
+}
+
+static ssize_t set_fan_ripple(struct i2c_client *client, struct fscpos_data
+			*data, const char *buf,	size_t count, int nr, int reg)
+{
+	/* supported values: 2, 4, 8 */
+	unsigned long v = simple_strtoul(buf, NULL, 10);
+
+	switch (v) {
+		case 2: v = 1; break;
+		case 4: v = 2; break;
+		case 8: v = 3; break;
+	default:
+		dev_err(&client->dev, "fan_ripple value %ld not supported. "
+					"Must be one of 2, 4 or 8!\n", v);
+		return -EINVAL;
+	}
+	
+	down(&data->update_lock);
+	/* bits 2..7 reserved => mask with 0x03 */
+	data->fan_ripple[nr - 1] &= ~0x03;
+	data->fan_ripple[nr - 1] |= v;
+	
+	fscpos_write_value(client, reg, data->fan_ripple[nr - 1]);
+	up(&data->update_lock);
+	return count;
+}
+
+static ssize_t show_pwm(struct fscpos_data *data, char *buf, int nr)
+{
+	return sprintf(buf, "%u\n", data->pwm[nr - 1]);
+}
+
+static ssize_t set_pwm(struct i2c_client *client, struct fscpos_data *data,
+				const char *buf, size_t count, int nr, int reg)
+{
+	unsigned long v = simple_strtoul(buf, NULL, 10);
+
+	/* Range: 0..255 */
+	if (v < 0) v = 0;
+	if (v > 255) v = 255;
+
+	down(&data->update_lock);
+	data->pwm[nr - 1] = v;
+	fscpos_write_value(client, reg, data->pwm[nr - 1]);
+	up(&data->update_lock);
+	return count;
+}
+
+static void reset_fan_alarm(struct i2c_client *client, int nr)
+{
+	fscpos_write_value(client, FSCPOS_REG_FAN_STATE[nr], 4);
+}
+
+/* Volts */
+#define VOLT_FROM_REG(val, mult)	((val) * (mult) / 255)
+
+static ssize_t show_volt_12(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct fscpos_data *data = fscpos_update_device(dev);
+	return sprintf(buf, "%u\n", VOLT_FROM_REG(data->volt[0], 14200));
+}
+
+static ssize_t show_volt_5(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct fscpos_data *data = fscpos_update_device(dev);
+	return sprintf(buf, "%u\n", VOLT_FROM_REG(data->volt[1], 6600));
+}
+
+static ssize_t show_volt_batt(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct fscpos_data *data = fscpos_update_device(dev);
+	return sprintf(buf, "%u\n", VOLT_FROM_REG(data->volt[2], 3300));
+}
+
+/* Watchdog */
+static ssize_t show_wdog_control(struct fscpos_data *data, char *buf)
+{
+	/* bits 0..3 reserved, bit 6 write only => mask with 0xb0 */
+	return sprintf(buf, "%u\n", data->wdog_control & 0xb0);
+}
+
+static ssize_t set_wdog_control(struct i2c_client *client, struct fscpos_data
+				*data, const char *buf,	size_t count, int reg)
+{
+	/* bits 0..3 reserved => mask with 0xf0 */
+	unsigned long v = simple_strtoul(buf, NULL, 10) & 0xf0;
+
+	down(&data->update_lock);
+	data->wdog_control &= ~0xf0;
+	data->wdog_control |= v;
+	fscpos_write_value(client, reg, data->wdog_control);
+	up(&data->update_lock);
+	return count;
+}
+
+static ssize_t show_wdog_state(struct fscpos_data *data, char *buf)
+{
+	/* bits 0, 2..7 reserved => mask with 0x02 */
+	return sprintf(buf, "%u\n", data->wdog_state & 0x02);
+}
+
+static ssize_t set_wdog_state(struct i2c_client *client, struct fscpos_data
+				*data, const char *buf, size_t count, int reg)
+{
+	unsigned long v = simple_strtoul(buf, NULL, 10) & 0x02;
+
+	/* Valid values: 2 (clear) */
+	if (v != 2) {
+		dev_err(&client->dev, "wdog_state value %ld not supported. "
+					"Must be 2 to clear the state!\n", v);
+		return -EINVAL;
+	}
+
+	down(&data->update_lock);
+	data->wdog_state &= ~v;
+	fscpos_write_value(client, reg, v);
+	up(&data->update_lock);
+	return count;
+}
+
+static ssize_t show_wdog_preset(struct fscpos_data *data, char *buf)
+{
+	return sprintf(buf, "%u\n", data->wdog_preset);
+}
+
+static ssize_t set_wdog_preset(struct i2c_client *client, struct fscpos_data
+				*data, const char *buf,	size_t count, int reg)
+{
+	unsigned long v = simple_strtoul(buf, NULL, 10) & 0xff;
+
+	down(&data->update_lock);
+	data->wdog_preset = v;
+	fscpos_write_value(client, reg, data->wdog_preset);
+	up(&data->update_lock);
+	return count;
+}
+
+/* Event */
+static ssize_t show_event(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	/* bits 5..7 reserved => mask with 0x1f */
+	struct fscpos_data *data = fscpos_update_device(dev);
+	return sprintf(buf, "%u\n", data->global_event & 0x9b);
+}
+
+/*
+ * Sysfs stuff
+ */
+#define create_getter(kind, sub) \
+	static ssize_t sysfs_show_##kind##sub(struct device *dev, struct device_attribute *attr, char *buf) \
+	{ \
+		struct fscpos_data *data = fscpos_update_device(dev); \
+		return show_##kind##sub(data, buf); \
+	}
+
+#define create_getter_n(kind, offset, sub) \
+	static ssize_t sysfs_show_##kind##offset##sub(struct device *dev, struct device_attribute *attr, char\
+								 	*buf) \
+	{ \
+		struct fscpos_data *data = fscpos_update_device(dev); \
+		return show_##kind##sub(data, buf, offset); \
+	}
+
+#define create_setter(kind, sub, reg) \
+	static ssize_t sysfs_set_##kind##sub (struct device *dev, struct device_attribute *attr, const char \
+							*buf, size_t count) \
+	{ \
+		struct i2c_client *client = to_i2c_client(dev); \
+		struct fscpos_data *data = i2c_get_clientdata(client); \
+		return set_##kind##sub(client, data, buf, count, reg); \
+	}
+
+#define create_setter_n(kind, offset, sub, reg) \
+	static ssize_t sysfs_set_##kind##offset##sub (struct device *dev, struct device_attribute *attr, \
+					const char *buf, size_t count) \
+	{ \
+		struct i2c_client *client = to_i2c_client(dev); \
+		struct fscpos_data *data = i2c_get_clientdata(client); \
+		return set_##kind##sub(client, data, buf, count, offset, reg);\
+	}
+
+#define create_sysfs_device_ro(kind, sub, offset) \
+	static DEVICE_ATTR(kind##offset##sub, S_IRUGO, \
+					sysfs_show_##kind##offset##sub, NULL);
+
+#define create_sysfs_device_rw(kind, sub, offset) \
+	static DEVICE_ATTR(kind##offset##sub, S_IRUGO | S_IWUSR, \
+		sysfs_show_##kind##offset##sub, sysfs_set_##kind##offset##sub);
+
+#define sysfs_ro_n(kind, sub, offset) \
+	create_getter_n(kind, offset, sub); \
+	create_sysfs_device_ro(kind, sub, offset);
+
+#define sysfs_rw_n(kind, sub, offset, reg) \
+	create_getter_n(kind, offset, sub); \
+	create_setter_n(kind, offset, sub, reg); \
+	create_sysfs_device_rw(kind, sub, offset);
+
+#define sysfs_rw(kind, sub, reg) \
+	create_getter(kind, sub); \
+	create_setter(kind, sub, reg); \
+	create_sysfs_device_rw(kind, sub,);
+
+#define sysfs_fan_with_min(offset, reg_status, reg_ripple, reg_min) \
+	sysfs_fan(offset, reg_status, reg_ripple); \
+	sysfs_rw_n(pwm,, offset, reg_min);
+
+#define sysfs_fan(offset, reg_status, reg_ripple) \
+	sysfs_ro_n(fan, _input, offset); \
+	sysfs_ro_n(fan, _status, offset); \
+	sysfs_rw_n(fan, _ripple, offset, reg_ripple);
+
+#define sysfs_temp(offset, reg_status) \
+	sysfs_ro_n(temp, _input, offset); \
+	sysfs_ro_n(temp, _status, offset); \
+	sysfs_rw_n(temp, _reset, offset, reg_status);
+
+#define sysfs_watchdog(reg_wdog_preset, reg_wdog_state, reg_wdog_control) \
+	sysfs_rw(wdog, _control, reg_wdog_control); \
+	sysfs_rw(wdog, _preset, reg_wdog_preset); \
+	sysfs_rw(wdog, _state, reg_wdog_state);
+
+sysfs_fan_with_min(1, FSCPOS_REG_FAN_STATE[0], FSCPOS_REG_FAN_RIPPLE[0],
+							FSCPOS_REG_PWM[0]);
+sysfs_fan_with_min(2, FSCPOS_REG_FAN_STATE[1], FSCPOS_REG_FAN_RIPPLE[1],
+							FSCPOS_REG_PWM[1]);
+sysfs_fan(3, FSCPOS_REG_FAN_STATE[2], FSCPOS_REG_FAN_RIPPLE[2]);
+
+sysfs_temp(1, FSCPOS_REG_TEMP_STATE[0]);
+sysfs_temp(2, FSCPOS_REG_TEMP_STATE[1]);
+sysfs_temp(3, FSCPOS_REG_TEMP_STATE[2]);
+
+sysfs_watchdog(FSCPOS_REG_WDOG_PRESET, FSCPOS_REG_WDOG_STATE,
+						FSCPOS_REG_WDOG_CONTROL);
+
+static DEVICE_ATTR(event, S_IRUGO, show_event, NULL);
+static DEVICE_ATTR(in0_input, S_IRUGO, show_volt_12, NULL);
+static DEVICE_ATTR(in1_input, S_IRUGO, show_volt_5, NULL);
+static DEVICE_ATTR(in2_input, S_IRUGO, show_volt_batt, NULL);
+
+static int fscpos_attach_adapter(struct i2c_adapter *adapter)
+{
+	if (!(adapter->class & I2C_CLASS_HWMON))
+		return 0;
+	return i2c_detect(adapter, &addr_data, fscpos_detect);
+}
+
+int fscpos_detect(struct i2c_adapter *adapter, int address, int kind)
+{
+	struct i2c_client *new_client;
+	struct fscpos_data *data;
+	int err = 0;
+
+	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+		goto exit;
+
+	/*
+	 * OK. For now, we presume we have a valid client. We now create the
+	 * client structure, even though we cannot fill it completely yet.
+	 * But it allows us to access fscpos_{read,write}_value.
+	 */
+
+	if (!(data = kmalloc(sizeof(struct fscpos_data), GFP_KERNEL))) {
+		err = -ENOMEM;
+		goto exit;
+	}
+	memset(data, 0, sizeof(struct fscpos_data));
+
+	new_client = &data->client;
+	i2c_set_clientdata(new_client, data);
+	new_client->addr = address;
+	new_client->adapter = adapter;
+	new_client->driver = &fscpos_driver;
+	new_client->flags = 0;
+
+	/* Do the remaining detection unless force or force_fscpos parameter */
+	if (kind < 0) {
+		if ((fscpos_read_value(new_client, FSCPOS_REG_IDENT_0)
+			!= 0x50) /* 'P' */
+		|| (fscpos_read_value(new_client, FSCPOS_REG_IDENT_1)
+			!= 0x45) /* 'E' */
+		|| (fscpos_read_value(new_client, FSCPOS_REG_IDENT_2)
+			!= 0x47))/* 'G' */
+		{
+			dev_dbg(&new_client->dev, "fscpos detection failed\n");
+			goto exit_free;
+		}
+	}
+
+	/* Fill in the remaining client fields and put it in the global list */
+	strlcpy(new_client->name, "fscpos", I2C_NAME_SIZE);
+
+	data->valid = 0;
+	init_MUTEX(&data->update_lock);
+
+	/* Tell the I2C layer a new client has arrived */
+	if ((err = i2c_attach_client(new_client)))
+		goto exit_free;
+
+	/* Inizialize the fscpos chip */
+	fscpos_init_client(new_client);
+
+	/* Announce that the chip was found */
+	dev_info(&new_client->dev, "Found fscpos chip, rev %u\n", data->revision);
+
+	/* Register sysfs hooks */
+	device_create_file(&new_client->dev, &dev_attr_event);
+	device_create_file(&new_client->dev, &dev_attr_in0_input);
+	device_create_file(&new_client->dev, &dev_attr_in1_input);
+	device_create_file(&new_client->dev, &dev_attr_in2_input);
+	device_create_file(&new_client->dev, &dev_attr_wdog_control);
+	device_create_file(&new_client->dev, &dev_attr_wdog_preset);
+	device_create_file(&new_client->dev, &dev_attr_wdog_state);
+	device_create_file(&new_client->dev, &dev_attr_temp1_input);
+	device_create_file(&new_client->dev, &dev_attr_temp1_status);
+	device_create_file(&new_client->dev, &dev_attr_temp1_reset);
+	device_create_file(&new_client->dev, &dev_attr_temp2_input);
+	device_create_file(&new_client->dev, &dev_attr_temp2_status);
+	device_create_file(&new_client->dev, &dev_attr_temp2_reset);
+	device_create_file(&new_client->dev, &dev_attr_temp3_input);
+	device_create_file(&new_client->dev, &dev_attr_temp3_status);
+	device_create_file(&new_client->dev, &dev_attr_temp3_reset);
+	device_create_file(&new_client->dev, &dev_attr_fan1_input);
+	device_create_file(&new_client->dev, &dev_attr_fan1_status);
+	device_create_file(&new_client->dev, &dev_attr_fan1_ripple);
+	device_create_file(&new_client->dev, &dev_attr_pwm1);
+	device_create_file(&new_client->dev, &dev_attr_fan2_input);
+	device_create_file(&new_client->dev, &dev_attr_fan2_status);
+	device_create_file(&new_client->dev, &dev_attr_fan2_ripple);
+	device_create_file(&new_client->dev, &dev_attr_pwm2);
+	device_create_file(&new_client->dev, &dev_attr_fan3_input);
+	device_create_file(&new_client->dev, &dev_attr_fan3_status);
+	device_create_file(&new_client->dev, &dev_attr_fan3_ripple);
+
+	return 0;
+
+exit_free:
+	kfree(data);
+exit:
+	return err;
+}
+
+static int fscpos_detach_client(struct i2c_client *client)
+{
+	int err;
+
+	if ((err = i2c_detach_client(client))) {
+		dev_err(&client->dev, "Client deregistration failed, client"
+							" not detached.\n");
+		return err;
+	}
+	kfree(i2c_get_clientdata(client));
+	return 0;
+}
+
+static int fscpos_read_value(struct i2c_client *client, u8 reg)
+{
+	dev_dbg(&client->dev, "Read reg 0x%02x\n", reg);
+	return i2c_smbus_read_byte_data(client, reg);
+}
+
+static int fscpos_write_value(struct i2c_client *client, u8 reg, u8 value)
+{
+	dev_dbg(&client->dev, "Write reg 0x%02x, val 0x%02x\n", reg, value);
+	return i2c_smbus_write_byte_data(client, reg, value);
+}
+
+/* Called when we have found a new FSCPOS chip */
+static void fscpos_init_client(struct i2c_client *client)
+{
+	struct fscpos_data *data = i2c_get_clientdata(client);
+
+	/* read revision from chip */
+	data->revision = fscpos_read_value(client, FSCPOS_REG_REVISION);
+}
+
+static struct fscpos_data *fscpos_update_device(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct fscpos_data *data = i2c_get_clientdata(client);
+
+	down(&data->update_lock);
+
+	if (time_after(jiffies, data->last_updated + 2 * HZ) || !data->valid) {
+		int i;
+
+		dev_dbg(&client->dev, "Starting fscpos update\n");
+
+		for (i = 0; i < 3; i++) {
+			data->temp_act[i] = fscpos_read_value(client,
+						FSCPOS_REG_TEMP_ACT[i]);
+			data->temp_status[i] = fscpos_read_value(client,
+						FSCPOS_REG_TEMP_STATE[i]);
+			data->fan_act[i] = fscpos_read_value(client,
+						FSCPOS_REG_FAN_ACT[i]);
+			data->fan_status[i] = fscpos_read_value(client,
+						FSCPOS_REG_FAN_STATE[i]);
+			data->fan_ripple[i] = fscpos_read_value(client,
+						FSCPOS_REG_FAN_RIPPLE[i]);
+			if (i < 2) {
+				/* fan2_min is not supported by the chip */
+				data->pwm[i] = fscpos_read_value(client,
+							FSCPOS_REG_PWM[i]);
+			}
+			/* reset fan status if speed is back to > 0 */
+			if (data->fan_status[i] != 0 && data->fan_act[i] > 0) {
+				reset_fan_alarm(client, i);
+			}
+		}
+
+		data->volt[0] = fscpos_read_value(client, FSCPOS_REG_VOLT_12);
+		data->volt[1] = fscpos_read_value(client, FSCPOS_REG_VOLT_5);
+		data->volt[2] = fscpos_read_value(client, FSCPOS_REG_VOLT_BATT);
+
+		data->wdog_preset = fscpos_read_value(client,
+							FSCPOS_REG_WDOG_PRESET);
+		data->wdog_state = fscpos_read_value(client,
+							FSCPOS_REG_WDOG_STATE);
+		data->wdog_control = fscpos_read_value(client,
+						FSCPOS_REG_WDOG_CONTROL);
+
+		data->global_event = fscpos_read_value(client,
+						FSCPOS_REG_EVENT_STATE);
+
+		data->last_updated = jiffies;
+		data->valid = 1;
+	}
+	up(&data->update_lock);
+	return data;
+}
+
+static int __init sm_fscpos_init(void)
+{
+	return i2c_add_driver(&fscpos_driver);
+}
+
+static void __exit sm_fscpos_exit(void)
+{
+	i2c_del_driver(&fscpos_driver);
+}
+
+MODULE_AUTHOR("Stefan Ott <stefan@desire.ch> based on work from Hermann Jung "
+				"<hej@odn.de>, Frodo Looijaard <frodol@dds.nl>"
+				" and Philip Edelbrock <phil@netroedge.com>");
+MODULE_DESCRIPTION("fujitsu siemens poseidon chip driver");
+MODULE_LICENSE("GPL");
+
+module_init(sm_fscpos_init);
+module_exit(sm_fscpos_exit);
diff --git a/drivers/hwmon/gl518sm.c b/drivers/hwmon/gl518sm.c
new file mode 100644
--- /dev/null
+++ b/drivers/hwmon/gl518sm.c
@@ -0,0 +1,604 @@
+/*
+ * gl518sm.c - Part of lm_sensors, Linux kernel modules for hardware
+ *             monitoring
+ * Copyright (C) 1998, 1999 Frodo Looijaard <frodol@dds.nl> and
+ * Kyosti Malkki <kmalkki@cc.hut.fi>
+ * Copyright (C) 2004 Hong-Gunn Chew <hglinux@gunnet.org> and
+ * Jean Delvare <khali@linux-fr.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.
+ *
+ * Ported to Linux 2.6 by Hong-Gunn Chew with the help of Jean Delvare
+ * and advice of Greg Kroah-Hartman.
+ *
+ * Notes about the port:
+ * Release 0x00 of the GL518SM chipset doesn't support reading of in0,
+ * in1 nor in2. The original driver had an ugly workaround to get them
+ * anyway (changing limits and watching alarms trigger and wear off).
+ * We did not keep that part of the original driver in the Linux 2.6
+ * version, since it was making the driver significantly more complex
+ * with no real benefit.
+ *
+ * History:
+ * 2004-01-28  Original port. (Hong-Gunn Chew)
+ * 2004-01-31  Code review and approval. (Jean Delvare)
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+#include <linux/i2c.h>
+#include <linux/i2c-sensor.h>
+
+/* Addresses to scan */
+static unsigned short normal_i2c[] = { 0x2c, 0x2d, I2C_CLIENT_END };
+static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
+
+/* Insmod parameters */
+SENSORS_INSMOD_2(gl518sm_r00, gl518sm_r80);
+
+/* Many GL518 constants specified below */
+
+/* The GL518 registers */
+#define GL518_REG_CHIP_ID	0x00
+#define GL518_REG_REVISION	0x01
+#define GL518_REG_VENDOR_ID	0x02
+#define GL518_REG_CONF		0x03
+#define GL518_REG_TEMP_IN	0x04
+#define GL518_REG_TEMP_MAX	0x05
+#define GL518_REG_TEMP_HYST	0x06
+#define GL518_REG_FAN_COUNT	0x07
+#define GL518_REG_FAN_LIMIT	0x08
+#define GL518_REG_VIN1_LIMIT	0x09
+#define GL518_REG_VIN2_LIMIT	0x0a
+#define GL518_REG_VIN3_LIMIT	0x0b
+#define GL518_REG_VDD_LIMIT	0x0c
+#define GL518_REG_VIN3		0x0d
+#define GL518_REG_MISC		0x0f
+#define GL518_REG_ALARM		0x10
+#define GL518_REG_MASK		0x11
+#define GL518_REG_INT		0x12
+#define GL518_REG_VIN2		0x13
+#define GL518_REG_VIN1		0x14
+#define GL518_REG_VDD		0x15
+
+
+/*
+ * Conversions. Rounding and limit checking is only done on the TO_REG
+ * variants. Note that you should be a bit careful with which arguments
+ * these macros are called: arguments may be evaluated more than once.
+ * Fixing this is just not worth it.
+ */
+
+#define RAW_FROM_REG(val)	val
+
+#define BOOL_FROM_REG(val)	((val)?0:1)
+#define BOOL_TO_REG(val)	((val)?0:1)
+
+#define TEMP_TO_REG(val)	(SENSORS_LIMIT(((((val)<0? \
+				(val)-500:(val)+500)/1000)+119),0,255))
+#define TEMP_FROM_REG(val)	(((val) - 119) * 1000)
+
+static inline u8 FAN_TO_REG(long rpm, int div)
+{
+	long rpmdiv;
+	if (rpm == 0)
+		return 0;
+	rpmdiv = SENSORS_LIMIT(rpm, 1, 1920000) * div;
+	return SENSORS_LIMIT((960000 + rpmdiv / 2) / rpmdiv, 1, 255);
+}
+#define FAN_FROM_REG(val,div)	((val)==0 ? 0 : (960000/((val)*(div))))
+
+#define IN_TO_REG(val)		(SENSORS_LIMIT((((val)+9)/19),0,255))
+#define IN_FROM_REG(val)	((val)*19)
+
+#define VDD_TO_REG(val)		(SENSORS_LIMIT((((val)*4+47)/95),0,255))
+#define VDD_FROM_REG(val)	(((val)*95+2)/4)
+
+#define DIV_TO_REG(val)		((val)==4?2:(val)==2?1:(val)==1?0:3)
+#define DIV_FROM_REG(val)	(1 << (val))
+
+#define BEEP_MASK_TO_REG(val)	((val) & 0x7f & data->alarm_mask)
+#define BEEP_MASK_FROM_REG(val)	((val) & 0x7f)
+
+/* Each client has this additional data */
+struct gl518_data {
+	struct i2c_client client;
+	enum chips type;
+
+	struct semaphore update_lock;
+	char valid;		/* !=0 if following fields are valid */
+	unsigned long last_updated;	/* In jiffies */
+
+	u8 voltage_in[4];	/* Register values; [0] = VDD */
+	u8 voltage_min[4];	/* Register values; [0] = VDD */
+	u8 voltage_max[4];	/* Register values; [0] = VDD */
+	u8 iter_voltage_in[4];	/* Register values; [0] = VDD */
+	u8 fan_in[2];
+	u8 fan_min[2];
+	u8 fan_div[2];		/* Register encoding, shifted right */
+	u8 fan_auto1;		/* Boolean */
+	u8 temp_in;		/* Register values */
+	u8 temp_max;		/* Register values */
+	u8 temp_hyst;		/* Register values */
+	u8 alarms;		/* Register value */
+	u8 alarm_mask;		/* Register value */
+	u8 beep_mask;		/* Register value */
+	u8 beep_enable;		/* Boolean */
+};
+
+static int gl518_attach_adapter(struct i2c_adapter *adapter);
+static int gl518_detect(struct i2c_adapter *adapter, int address, int kind);
+static void gl518_init_client(struct i2c_client *client);
+static int gl518_detach_client(struct i2c_client *client);
+static int gl518_read_value(struct i2c_client *client, u8 reg);
+static int gl518_write_value(struct i2c_client *client, u8 reg, u16 value);
+static struct gl518_data *gl518_update_device(struct device *dev);
+
+/* This is the driver that will be inserted */
+static struct i2c_driver gl518_driver = {
+	.owner		= THIS_MODULE,
+	.name		= "gl518sm",
+	.id		= I2C_DRIVERID_GL518,
+	.flags		= I2C_DF_NOTIFY,
+	.attach_adapter	= gl518_attach_adapter,
+	.detach_client	= gl518_detach_client,
+};
+
+/*
+ * Sysfs stuff
+ */
+
+#define show(type, suffix, value)					\
+static ssize_t show_##suffix(struct device *dev, struct device_attribute *attr, char *buf)		\
+{									\
+	struct gl518_data *data = gl518_update_device(dev);		\
+	return sprintf(buf, "%d\n", type##_FROM_REG(data->value));	\
+}
+
+#define show_fan(suffix, value, index)					\
+static ssize_t show_##suffix(struct device *dev, struct device_attribute *attr, char *buf)		\
+{									\
+	struct gl518_data *data = gl518_update_device(dev);		\
+	return sprintf(buf, "%d\n", FAN_FROM_REG(data->value[index],	\
+		DIV_FROM_REG(data->fan_div[index])));			\
+}
+
+show(TEMP, temp_input1, temp_in);
+show(TEMP, temp_max1, temp_max);
+show(TEMP, temp_hyst1, temp_hyst);
+show(BOOL, fan_auto1, fan_auto1);
+show_fan(fan_input1, fan_in, 0);
+show_fan(fan_input2, fan_in, 1);
+show_fan(fan_min1, fan_min, 0);
+show_fan(fan_min2, fan_min, 1);
+show(DIV, fan_div1, fan_div[0]);
+show(DIV, fan_div2, fan_div[1]);
+show(VDD, in_input0, voltage_in[0]);
+show(IN, in_input1, voltage_in[1]);
+show(IN, in_input2, voltage_in[2]);
+show(IN, in_input3, voltage_in[3]);
+show(VDD, in_min0, voltage_min[0]);
+show(IN, in_min1, voltage_min[1]);
+show(IN, in_min2, voltage_min[2]);
+show(IN, in_min3, voltage_min[3]);
+show(VDD, in_max0, voltage_max[0]);
+show(IN, in_max1, voltage_max[1]);
+show(IN, in_max2, voltage_max[2]);
+show(IN, in_max3, voltage_max[3]);
+show(RAW, alarms, alarms);
+show(BOOL, beep_enable, beep_enable);
+show(BEEP_MASK, beep_mask, beep_mask);
+
+#define set(type, suffix, value, reg)					\
+static ssize_t set_##suffix(struct device *dev, struct device_attribute *attr, const char *buf,	\
+	size_t count)							\
+{									\
+	struct i2c_client *client = to_i2c_client(dev);			\
+	struct gl518_data *data = i2c_get_clientdata(client);		\
+	long val = simple_strtol(buf, NULL, 10);			\
+									\
+	down(&data->update_lock);					\
+	data->value = type##_TO_REG(val);				\
+	gl518_write_value(client, reg, data->value);			\
+	up(&data->update_lock);						\
+	return count;							\
+}
+
+#define set_bits(type, suffix, value, reg, mask, shift)			\
+static ssize_t set_##suffix(struct device *dev, struct device_attribute *attr, const char *buf,	\
+	size_t count)							\
+{									\
+	struct i2c_client *client = to_i2c_client(dev);			\
+	struct gl518_data *data = i2c_get_clientdata(client);		\
+	int regvalue;							\
+	unsigned long val = simple_strtoul(buf, NULL, 10);		\
+									\
+	down(&data->update_lock);					\
+	regvalue = gl518_read_value(client, reg);			\
+	data->value = type##_TO_REG(val);				\
+	regvalue = (regvalue & ~mask) | (data->value << shift);		\
+	gl518_write_value(client, reg, regvalue);			\
+	up(&data->update_lock);						\
+	return count;							\
+}
+
+#define set_low(type, suffix, value, reg)				\
+	set_bits(type, suffix, value, reg, 0x00ff, 0)
+#define set_high(type, suffix, value, reg)				\
+	set_bits(type, suffix, value, reg, 0xff00, 8)
+
+set(TEMP, temp_max1, temp_max, GL518_REG_TEMP_MAX);
+set(TEMP, temp_hyst1, temp_hyst, GL518_REG_TEMP_HYST);
+set_bits(BOOL, fan_auto1, fan_auto1, GL518_REG_MISC, 0x08, 3);
+set_bits(DIV, fan_div1, fan_div[0], GL518_REG_MISC, 0xc0, 6);
+set_bits(DIV, fan_div2, fan_div[1], GL518_REG_MISC, 0x30, 4);
+set_low(VDD, in_min0, voltage_min[0], GL518_REG_VDD_LIMIT);
+set_low(IN, in_min1, voltage_min[1], GL518_REG_VIN1_LIMIT);
+set_low(IN, in_min2, voltage_min[2], GL518_REG_VIN2_LIMIT);
+set_low(IN, in_min3, voltage_min[3], GL518_REG_VIN3_LIMIT);
+set_high(VDD, in_max0, voltage_max[0], GL518_REG_VDD_LIMIT);
+set_high(IN, in_max1, voltage_max[1], GL518_REG_VIN1_LIMIT);
+set_high(IN, in_max2, voltage_max[2], GL518_REG_VIN2_LIMIT);
+set_high(IN, in_max3, voltage_max[3], GL518_REG_VIN3_LIMIT);
+set_bits(BOOL, beep_enable, beep_enable, GL518_REG_CONF, 0x04, 2);
+set(BEEP_MASK, beep_mask, beep_mask, GL518_REG_ALARM);
+
+static ssize_t set_fan_min1(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct gl518_data *data = i2c_get_clientdata(client);
+	int regvalue;
+	unsigned long val = simple_strtoul(buf, NULL, 10);
+
+	down(&data->update_lock);
+	regvalue = gl518_read_value(client, GL518_REG_FAN_LIMIT);
+	data->fan_min[0] = FAN_TO_REG(val,
+		DIV_FROM_REG(data->fan_div[0]));
+	regvalue = (regvalue & 0x00ff) | (data->fan_min[0] << 8);
+	gl518_write_value(client, GL518_REG_FAN_LIMIT, regvalue);
+
+	data->beep_mask = gl518_read_value(client, GL518_REG_ALARM);
+	if (data->fan_min[0] == 0)
+		data->alarm_mask &= ~0x20;
+	else
+		data->alarm_mask |= 0x20;
+	data->beep_mask &= data->alarm_mask;
+	gl518_write_value(client, GL518_REG_ALARM, data->beep_mask);
+
+	up(&data->update_lock);
+	return count;
+}
+
+static ssize_t set_fan_min2(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct gl518_data *data = i2c_get_clientdata(client);
+	int regvalue;
+	unsigned long val = simple_strtoul(buf, NULL, 10);
+
+	down(&data->update_lock);
+	regvalue = gl518_read_value(client, GL518_REG_FAN_LIMIT);
+	data->fan_min[1] = FAN_TO_REG(val,
+		DIV_FROM_REG(data->fan_div[1]));
+	regvalue = (regvalue & 0xff00) | data->fan_min[1];
+	gl518_write_value(client, GL518_REG_FAN_LIMIT, regvalue);
+
+	data->beep_mask = gl518_read_value(client, GL518_REG_ALARM);
+	if (data->fan_min[1] == 0)
+		data->alarm_mask &= ~0x40;
+	else
+		data->alarm_mask |= 0x40;
+	data->beep_mask &= data->alarm_mask;
+	gl518_write_value(client, GL518_REG_ALARM, data->beep_mask);
+
+	up(&data->update_lock);
+	return count;
+}
+
+static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp_input1, NULL);
+static DEVICE_ATTR(temp1_max, S_IWUSR|S_IRUGO, show_temp_max1, set_temp_max1);
+static DEVICE_ATTR(temp1_max_hyst, S_IWUSR|S_IRUGO,
+	show_temp_hyst1, set_temp_hyst1);
+static DEVICE_ATTR(fan1_auto, S_IWUSR|S_IRUGO, show_fan_auto1, set_fan_auto1);
+static DEVICE_ATTR(fan1_input, S_IRUGO, show_fan_input1, NULL);
+static DEVICE_ATTR(fan2_input, S_IRUGO, show_fan_input2, NULL);
+static DEVICE_ATTR(fan1_min, S_IWUSR|S_IRUGO, show_fan_min1, set_fan_min1);
+static DEVICE_ATTR(fan2_min, S_IWUSR|S_IRUGO, show_fan_min2, set_fan_min2);
+static DEVICE_ATTR(fan1_div, S_IWUSR|S_IRUGO, show_fan_div1, set_fan_div1);
+static DEVICE_ATTR(fan2_div, S_IWUSR|S_IRUGO, show_fan_div2, set_fan_div2);
+static DEVICE_ATTR(in0_input, S_IRUGO, show_in_input0, NULL);
+static DEVICE_ATTR(in1_input, S_IRUGO, show_in_input1, NULL);
+static DEVICE_ATTR(in2_input, S_IRUGO, show_in_input2, NULL);
+static DEVICE_ATTR(in3_input, S_IRUGO, show_in_input3, NULL);
+static DEVICE_ATTR(in0_min, S_IWUSR|S_IRUGO, show_in_min0, set_in_min0);
+static DEVICE_ATTR(in1_min, S_IWUSR|S_IRUGO, show_in_min1, set_in_min1);
+static DEVICE_ATTR(in2_min, S_IWUSR|S_IRUGO, show_in_min2, set_in_min2);
+static DEVICE_ATTR(in3_min, S_IWUSR|S_IRUGO, show_in_min3, set_in_min3);
+static DEVICE_ATTR(in0_max, S_IWUSR|S_IRUGO, show_in_max0, set_in_max0);
+static DEVICE_ATTR(in1_max, S_IWUSR|S_IRUGO, show_in_max1, set_in_max1);
+static DEVICE_ATTR(in2_max, S_IWUSR|S_IRUGO, show_in_max2, set_in_max2);
+static DEVICE_ATTR(in3_max, S_IWUSR|S_IRUGO, show_in_max3, set_in_max3);
+static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
+static DEVICE_ATTR(beep_enable, S_IWUSR|S_IRUGO,
+	show_beep_enable, set_beep_enable);
+static DEVICE_ATTR(beep_mask, S_IWUSR|S_IRUGO,
+	show_beep_mask, set_beep_mask);
+
+/*
+ * Real code
+ */
+
+static int gl518_attach_adapter(struct i2c_adapter *adapter)
+{
+	if (!(adapter->class & I2C_CLASS_HWMON))
+		return 0;
+	return i2c_detect(adapter, &addr_data, gl518_detect);
+}
+
+static int gl518_detect(struct i2c_adapter *adapter, int address, int kind)
+{
+	int i;
+	struct i2c_client *new_client;
+	struct gl518_data *data;
+	int err = 0;
+
+	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
+				     I2C_FUNC_SMBUS_WORD_DATA))
+		goto exit;
+
+	/* OK. For now, we presume we have a valid client. We now create the
+	   client structure, even though we cannot fill it completely yet.
+	   But it allows us to access gl518_{read,write}_value. */
+
+	if (!(data = kmalloc(sizeof(struct gl518_data), GFP_KERNEL))) {
+		err = -ENOMEM;
+		goto exit;
+	}
+	memset(data, 0, sizeof(struct gl518_data));
+
+	new_client = &data->client;
+	i2c_set_clientdata(new_client, data);
+
+	new_client->addr = address;
+	new_client->adapter = adapter;
+	new_client->driver = &gl518_driver;
+	new_client->flags = 0;
+
+	/* Now, we do the remaining detection. */
+
+	if (kind < 0) {
+		if ((gl518_read_value(new_client, GL518_REG_CHIP_ID) != 0x80)
+		 || (gl518_read_value(new_client, GL518_REG_CONF) & 0x80))
+			goto exit_free;
+	}
+
+	/* Determine the chip type. */
+	if (kind <= 0) {
+		i = gl518_read_value(new_client, GL518_REG_REVISION);
+		if (i == 0x00) {
+			kind = gl518sm_r00;
+		} else if (i == 0x80) {
+			kind = gl518sm_r80;
+		} else {
+			if (kind <= 0)
+				dev_info(&adapter->dev,
+				    "Ignoring 'force' parameter for unknown "
+				    "chip at adapter %d, address 0x%02x\n",
+				    i2c_adapter_id(adapter), address);
+			goto exit_free;
+		}
+	}
+
+	/* Fill in the remaining client fields */
+	strlcpy(new_client->name, "gl518sm", I2C_NAME_SIZE);
+	data->type = kind;
+	data->valid = 0;
+	init_MUTEX(&data->update_lock);
+
+	/* Tell the I2C layer a new client has arrived */
+	if ((err = i2c_attach_client(new_client)))
+		goto exit_free;
+
+	/* Initialize the GL518SM chip */
+	data->alarm_mask = 0xff;
+	data->voltage_in[0]=data->voltage_in[1]=data->voltage_in[2]=0;
+	gl518_init_client((struct i2c_client *) new_client);
+
+	/* Register sysfs hooks */
+	device_create_file(&new_client->dev, &dev_attr_in0_input);
+	device_create_file(&new_client->dev, &dev_attr_in1_input);
+	device_create_file(&new_client->dev, &dev_attr_in2_input);
+	device_create_file(&new_client->dev, &dev_attr_in3_input);
+	device_create_file(&new_client->dev, &dev_attr_in0_min);
+	device_create_file(&new_client->dev, &dev_attr_in1_min);
+	device_create_file(&new_client->dev, &dev_attr_in2_min);
+	device_create_file(&new_client->dev, &dev_attr_in3_min);
+	device_create_file(&new_client->dev, &dev_attr_in0_max);
+	device_create_file(&new_client->dev, &dev_attr_in1_max);
+	device_create_file(&new_client->dev, &dev_attr_in2_max);
+	device_create_file(&new_client->dev, &dev_attr_in3_max);
+	device_create_file(&new_client->dev, &dev_attr_fan1_auto);
+	device_create_file(&new_client->dev, &dev_attr_fan1_input);
+	device_create_file(&new_client->dev, &dev_attr_fan2_input);
+	device_create_file(&new_client->dev, &dev_attr_fan1_min);
+	device_create_file(&new_client->dev, &dev_attr_fan2_min);
+	device_create_file(&new_client->dev, &dev_attr_fan1_div);
+	device_create_file(&new_client->dev, &dev_attr_fan2_div);
+	device_create_file(&new_client->dev, &dev_attr_temp1_input);
+	device_create_file(&new_client->dev, &dev_attr_temp1_max);
+	device_create_file(&new_client->dev, &dev_attr_temp1_max_hyst);
+	device_create_file(&new_client->dev, &dev_attr_alarms);
+	device_create_file(&new_client->dev, &dev_attr_beep_enable);
+	device_create_file(&new_client->dev, &dev_attr_beep_mask);
+
+	return 0;
+
+/* OK, this is not exactly good programming practice, usually. But it is
+   very code-efficient in this case. */
+
+exit_free:
+	kfree(data);
+exit:
+	return err;
+}
+
+
+/* Called when we have found a new GL518SM.
+   Note that we preserve D4:NoFan2 and D2:beep_enable. */
+static void gl518_init_client(struct i2c_client *client)
+{
+	/* Make sure we leave D7:Reset untouched */
+	u8 regvalue = gl518_read_value(client, GL518_REG_CONF) & 0x7f;
+
+	/* Comparator mode (D3=0), standby mode (D6=0) */
+	gl518_write_value(client, GL518_REG_CONF, (regvalue &= 0x37));
+
+	/* Never interrupts */
+	gl518_write_value(client, GL518_REG_MASK, 0x00);
+
+	/* Clear status register (D5=1), start (D6=1) */
+	gl518_write_value(client, GL518_REG_CONF, 0x20 | regvalue);
+	gl518_write_value(client, GL518_REG_CONF, 0x40 | regvalue);
+}
+
+static int gl518_detach_client(struct i2c_client *client)
+{
+	int err;
+
+	if ((err = i2c_detach_client(client))) {
+		dev_err(&client->dev, "Client deregistration failed, "
+			"client not detached.\n");
+		return err;
+	}
+
+	kfree(i2c_get_clientdata(client));
+
+	return 0;
+}
+
+/* Registers 0x07 to 0x0c are word-sized, others are byte-sized 
+   GL518 uses a high-byte first convention, which is exactly opposite to
+   the usual practice. */
+static int gl518_read_value(struct i2c_client *client, u8 reg)
+{
+	if ((reg >= 0x07) && (reg <= 0x0c))
+		return swab16(i2c_smbus_read_word_data(client, reg));
+	else
+		return i2c_smbus_read_byte_data(client, reg);
+}
+
+/* Registers 0x07 to 0x0c are word-sized, others are byte-sized 
+   GL518 uses a high-byte first convention, which is exactly opposite to
+   the usual practice. */
+static int gl518_write_value(struct i2c_client *client, u8 reg, u16 value)
+{
+	if ((reg >= 0x07) && (reg <= 0x0c))
+		return i2c_smbus_write_word_data(client, reg, swab16(value));
+	else
+		return i2c_smbus_write_byte_data(client, reg, value);
+}
+
+static struct gl518_data *gl518_update_device(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct gl518_data *data = i2c_get_clientdata(client);
+	int val;
+
+	down(&data->update_lock);
+
+	if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
+	    || !data->valid) {
+		dev_dbg(&client->dev, "Starting gl518 update\n");
+
+		data->alarms = gl518_read_value(client, GL518_REG_INT);
+		data->beep_mask = gl518_read_value(client, GL518_REG_ALARM);
+
+		val = gl518_read_value(client, GL518_REG_VDD_LIMIT);
+		data->voltage_min[0] = val & 0xff;
+		data->voltage_max[0] = (val >> 8) & 0xff;
+		val = gl518_read_value(client, GL518_REG_VIN1_LIMIT);
+		data->voltage_min[1] = val & 0xff;
+		data->voltage_max[1] = (val >> 8) & 0xff;
+		val = gl518_read_value(client, GL518_REG_VIN2_LIMIT);
+		data->voltage_min[2] = val & 0xff;
+		data->voltage_max[2] = (val >> 8) & 0xff;
+		val = gl518_read_value(client, GL518_REG_VIN3_LIMIT);
+		data->voltage_min[3] = val & 0xff;
+		data->voltage_max[3] = (val >> 8) & 0xff;
+
+		val = gl518_read_value(client, GL518_REG_FAN_COUNT);
+		data->fan_in[0] = (val >> 8) & 0xff;
+		data->fan_in[1] = val & 0xff;
+
+		val = gl518_read_value(client, GL518_REG_FAN_LIMIT);
+		data->fan_min[0] = (val >> 8) & 0xff;
+		data->fan_min[1] = val & 0xff;
+
+		data->temp_in = gl518_read_value(client, GL518_REG_TEMP_IN);
+		data->temp_max =
+		    gl518_read_value(client, GL518_REG_TEMP_MAX);
+		data->temp_hyst =
+		    gl518_read_value(client, GL518_REG_TEMP_HYST);
+
+		val = gl518_read_value(client, GL518_REG_MISC);
+		data->fan_div[0] = (val >> 6) & 0x03;
+		data->fan_div[1] = (val >> 4) & 0x03;
+		data->fan_auto1  = (val >> 3) & 0x01;
+
+		data->alarms &= data->alarm_mask;
+
+		val = gl518_read_value(client, GL518_REG_CONF);
+		data->beep_enable = (val >> 2) & 1;
+
+		if (data->type != gl518sm_r00) {
+			data->voltage_in[0] =
+			    gl518_read_value(client, GL518_REG_VDD);
+			data->voltage_in[1] =
+			    gl518_read_value(client, GL518_REG_VIN1);
+			data->voltage_in[2] =
+			    gl518_read_value(client, GL518_REG_VIN2);
+		}
+		data->voltage_in[3] =
+		    gl518_read_value(client, GL518_REG_VIN3);
+
+		data->last_updated = jiffies;
+		data->valid = 1;
+	}
+
+	up(&data->update_lock);
+
+	return data;
+}
+
+static int __init sensors_gl518sm_init(void)
+{
+	return i2c_add_driver(&gl518_driver);
+}
+
+static void __exit sensors_gl518sm_exit(void)
+{
+	i2c_del_driver(&gl518_driver);
+}
+
+MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>, "
+	"Kyosti Malkki <kmalkki@cc.hut.fi> and "
+	"Hong-Gunn Chew <hglinux@gunnet.org>");
+MODULE_DESCRIPTION("GL518SM driver");
+MODULE_LICENSE("GPL");
+
+module_init(sensors_gl518sm_init);
+module_exit(sensors_gl518sm_exit);
diff --git a/drivers/hwmon/gl520sm.c b/drivers/hwmon/gl520sm.c
new file mode 100644
--- /dev/null
+++ b/drivers/hwmon/gl520sm.c
@@ -0,0 +1,769 @@
+/*
+    gl520sm.c - Part of lm_sensors, Linux kernel modules for hardware
+                monitoring
+    Copyright (c) 1998, 1999  Frodo Looijaard <frodol@dds.nl>,
+                              Kyösti Mälkki <kmalkki@cc.hut.fi>
+    Copyright (c) 2005        Maarten Deprez <maartendeprez@users.sourceforge.net>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This 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 <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+#include <linux/i2c.h>
+#include <linux/i2c-sensor.h>
+#include <linux/i2c-vid.h>
+
+/* Type of the extra sensor */
+static unsigned short extra_sensor_type;
+module_param(extra_sensor_type, ushort, 0);
+MODULE_PARM_DESC(extra_sensor_type, "Type of extra sensor (0=autodetect, 1=temperature, 2=voltage)");
+
+/* Addresses to scan */
+static unsigned short normal_i2c[] = { 0x2c, 0x2d, I2C_CLIENT_END };
+static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
+
+/* Insmod parameters */
+SENSORS_INSMOD_1(gl520sm);
+
+/* Many GL520 constants specified below 
+One of the inputs can be configured as either temp or voltage.
+That's why _TEMP2 and _IN4 access the same register 
+*/
+
+/* The GL520 registers */
+#define GL520_REG_CHIP_ID		0x00
+#define GL520_REG_REVISION		0x01
+#define GL520_REG_CONF			0x03
+#define GL520_REG_MASK			0x11
+
+#define GL520_REG_VID_INPUT		0x02
+
+#define GL520_REG_IN0_INPUT		0x15
+#define GL520_REG_IN0_LIMIT		0x0c
+#define GL520_REG_IN0_MIN		GL520_REG_IN0_LIMIT
+#define GL520_REG_IN0_MAX		GL520_REG_IN0_LIMIT
+
+#define GL520_REG_IN1_INPUT		0x14
+#define GL520_REG_IN1_LIMIT		0x09
+#define GL520_REG_IN1_MIN		GL520_REG_IN1_LIMIT
+#define GL520_REG_IN1_MAX		GL520_REG_IN1_LIMIT
+
+#define GL520_REG_IN2_INPUT		0x13
+#define GL520_REG_IN2_LIMIT		0x0a
+#define GL520_REG_IN2_MIN		GL520_REG_IN2_LIMIT
+#define GL520_REG_IN2_MAX		GL520_REG_IN2_LIMIT
+
+#define GL520_REG_IN3_INPUT		0x0d
+#define GL520_REG_IN3_LIMIT		0x0b
+#define GL520_REG_IN3_MIN		GL520_REG_IN3_LIMIT
+#define GL520_REG_IN3_MAX		GL520_REG_IN3_LIMIT
+
+#define GL520_REG_IN4_INPUT		0x0e
+#define GL520_REG_IN4_MAX		0x17
+#define GL520_REG_IN4_MIN		0x18
+
+#define GL520_REG_TEMP1_INPUT		0x04
+#define GL520_REG_TEMP1_MAX		0x05
+#define GL520_REG_TEMP1_MAX_HYST	0x06
+
+#define GL520_REG_TEMP2_INPUT		0x0e
+#define GL520_REG_TEMP2_MAX		0x17
+#define GL520_REG_TEMP2_MAX_HYST	0x18
+
+#define GL520_REG_FAN_INPUT		0x07
+#define GL520_REG_FAN_MIN		0x08
+#define GL520_REG_FAN_DIV		0x0f
+#define GL520_REG_FAN_OFF		GL520_REG_FAN_DIV
+
+#define GL520_REG_ALARMS		0x12
+#define GL520_REG_BEEP_MASK		0x10
+#define GL520_REG_BEEP_ENABLE		GL520_REG_CONF
+
+/*
+ * Function declarations
+ */
+
+static int gl520_attach_adapter(struct i2c_adapter *adapter);
+static int gl520_detect(struct i2c_adapter *adapter, int address, int kind);
+static void gl520_init_client(struct i2c_client *client);
+static int gl520_detach_client(struct i2c_client *client);
+static int gl520_read_value(struct i2c_client *client, u8 reg);
+static int gl520_write_value(struct i2c_client *client, u8 reg, u16 value);
+static struct gl520_data *gl520_update_device(struct device *dev);
+
+/* Driver data */
+static struct i2c_driver gl520_driver = {
+	.owner		= THIS_MODULE,
+	.name		= "gl520sm",
+	.id		= I2C_DRIVERID_GL520,
+	.flags		= I2C_DF_NOTIFY,
+	.attach_adapter	= gl520_attach_adapter,
+	.detach_client	= gl520_detach_client,
+};
+
+/* Client data */
+struct gl520_data {
+	struct i2c_client client;
+	struct semaphore update_lock;
+	char valid;		/* zero until the following fields are valid */
+	unsigned long last_updated;	/* in jiffies */
+
+	u8 vid;
+	u8 vrm;
+	u8 in_input[5];		/* [0] = VVD */
+	u8 in_min[5];		/* [0] = VDD */
+	u8 in_max[5];		/* [0] = VDD */
+	u8 fan_input[2];
+	u8 fan_min[2];
+	u8 fan_div[2];
+	u8 fan_off;
+	u8 temp_input[2];
+	u8 temp_max[2];
+	u8 temp_max_hyst[2];
+	u8 alarms;
+	u8 beep_enable;
+	u8 beep_mask;
+	u8 alarm_mask;
+	u8 two_temps;
+};
+
+/*
+ * Sysfs stuff
+ */
+
+#define sysfs_r(type, n, item, reg) \
+static ssize_t get_##type##item (struct gl520_data *, char *, int); \
+static ssize_t get_##type##n##item (struct device *, struct device_attribute *attr, char *); \
+static ssize_t get_##type##n##item (struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+	struct gl520_data *data = gl520_update_device(dev); \
+	return get_##type##item(data, buf, (n)); \
+}
+
+#define sysfs_w(type, n, item, reg) \
+static ssize_t set_##type##item (struct i2c_client *, struct gl520_data *, const char *, size_t, int, int); \
+static ssize_t set_##type##n##item (struct device *, struct device_attribute *attr, const char *, size_t); \
+static ssize_t set_##type##n##item (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \
+{ \
+	struct i2c_client *client = to_i2c_client(dev); \
+	struct gl520_data *data = i2c_get_clientdata(client); \
+	return set_##type##item(client, data, buf, count, (n), reg); \
+}
+
+#define sysfs_rw_n(type, n, item, reg) \
+sysfs_r(type, n, item, reg) \
+sysfs_w(type, n, item, reg) \
+static DEVICE_ATTR(type##n##item, S_IRUGO | S_IWUSR, get_##type##n##item, set_##type##n##item);
+
+#define sysfs_ro_n(type, n, item, reg) \
+sysfs_r(type, n, item, reg) \
+static DEVICE_ATTR(type##n##item, S_IRUGO, get_##type##n##item, NULL);
+
+#define sysfs_rw(type, item, reg) \
+sysfs_r(type, 0, item, reg) \
+sysfs_w(type, 0, item, reg) \
+static DEVICE_ATTR(type##item, S_IRUGO | S_IWUSR, get_##type##0##item, set_##type##0##item);
+
+#define sysfs_ro(type, item, reg) \
+sysfs_r(type, 0, item, reg) \
+static DEVICE_ATTR(type##item, S_IRUGO, get_##type##0##item, NULL);
+
+
+#define sysfs_vid(n) \
+sysfs_ro_n(cpu, n, _vid, GL520_REG_VID_INPUT)
+
+#define device_create_file_vid(client, n) \
+device_create_file(&client->dev, &dev_attr_cpu##n##_vid)
+
+#define sysfs_in(n) \
+sysfs_ro_n(in, n, _input, GL520_REG_IN##n##INPUT) \
+sysfs_rw_n(in, n, _min, GL520_REG_IN##n##_MIN) \
+sysfs_rw_n(in, n, _max, GL520_REG_IN##n##_MAX) \
+
+#define device_create_file_in(client, n) \
+({device_create_file(&client->dev, &dev_attr_in##n##_input); \
+device_create_file(&client->dev, &dev_attr_in##n##_min); \
+device_create_file(&client->dev, &dev_attr_in##n##_max);})
+
+#define sysfs_fan(n) \
+sysfs_ro_n(fan, n, _input, GL520_REG_FAN_INPUT) \
+sysfs_rw_n(fan, n, _min, GL520_REG_FAN_MIN) \
+sysfs_rw_n(fan, n, _div, GL520_REG_FAN_DIV)
+
+#define device_create_file_fan(client, n) \
+({device_create_file(&client->dev, &dev_attr_fan##n##_input); \
+device_create_file(&client->dev, &dev_attr_fan##n##_min); \
+device_create_file(&client->dev, &dev_attr_fan##n##_div);})
+
+#define sysfs_fan_off(n) \
+sysfs_rw_n(fan, n, _off, GL520_REG_FAN_OFF) \
+
+#define device_create_file_fan_off(client, n) \
+device_create_file(&client->dev, &dev_attr_fan##n##_off)
+
+#define sysfs_temp(n) \
+sysfs_ro_n(temp, n, _input, GL520_REG_TEMP##n##_INPUT) \
+sysfs_rw_n(temp, n, _max, GL520_REG_TEMP##n##_MAX) \
+sysfs_rw_n(temp, n, _max_hyst, GL520_REG_TEMP##n##_MAX_HYST)
+
+#define device_create_file_temp(client, n) \
+({device_create_file(&client->dev, &dev_attr_temp##n##_input); \
+device_create_file(&client->dev, &dev_attr_temp##n##_max); \
+device_create_file(&client->dev, &dev_attr_temp##n##_max_hyst);})
+
+#define sysfs_alarms() \
+sysfs_ro(alarms, , GL520_REG_ALARMS) \
+sysfs_rw(beep_enable, , GL520_REG_BEEP_ENABLE) \
+sysfs_rw(beep_mask, , GL520_REG_BEEP_MASK)
+
+#define device_create_file_alarms(client) \
+({device_create_file(&client->dev, &dev_attr_alarms); \
+device_create_file(&client->dev, &dev_attr_beep_enable); \
+device_create_file(&client->dev, &dev_attr_beep_mask);})
+
+
+sysfs_vid(0)
+
+sysfs_in(0)
+sysfs_in(1)
+sysfs_in(2)
+sysfs_in(3)
+sysfs_in(4)
+
+sysfs_fan(1)
+sysfs_fan(2)
+sysfs_fan_off(1)
+
+sysfs_temp(1)
+sysfs_temp(2)
+
+sysfs_alarms()
+
+
+static ssize_t get_cpu_vid(struct gl520_data *data, char *buf, int n)
+{
+	return sprintf(buf, "%u\n", vid_from_reg(data->vid, data->vrm));
+}
+
+#define VDD_FROM_REG(val) (((val)*95+2)/4)
+#define VDD_TO_REG(val) (SENSORS_LIMIT((((val)*4+47)/95),0,255))
+
+#define IN_FROM_REG(val) ((val)*19)
+#define IN_TO_REG(val) (SENSORS_LIMIT((((val)+9)/19),0,255))
+
+static ssize_t get_in_input(struct gl520_data *data, char *buf, int n)
+{
+	u8 r = data->in_input[n];
+
+	if (n == 0)
+		return sprintf(buf, "%d\n", VDD_FROM_REG(r));
+	else
+		return sprintf(buf, "%d\n", IN_FROM_REG(r));
+}
+
+static ssize_t get_in_min(struct gl520_data *data, char *buf, int n)
+{
+	u8 r = data->in_min[n];
+
+	if (n == 0)
+		return sprintf(buf, "%d\n", VDD_FROM_REG(r));
+	else
+		return sprintf(buf, "%d\n", IN_FROM_REG(r));
+}
+
+static ssize_t get_in_max(struct gl520_data *data, char *buf, int n)
+{
+	u8 r = data->in_max[n];
+
+	if (n == 0)
+		return sprintf(buf, "%d\n", VDD_FROM_REG(r));
+	else
+		return sprintf(buf, "%d\n", IN_FROM_REG(r));
+}
+
+static ssize_t set_in_min(struct i2c_client *client, struct gl520_data *data, const char *buf, size_t count, int n, int reg)
+{
+	long v = simple_strtol(buf, NULL, 10);
+	u8 r;
+
+	down(&data->update_lock);
+
+	if (n == 0)
+		r = VDD_TO_REG(v);
+	else
+		r = IN_TO_REG(v);
+
+	data->in_min[n] = r;
+
+	if (n < 4)
+		gl520_write_value(client, reg, (gl520_read_value(client, reg) & ~0xff) | r);
+	else
+		gl520_write_value(client, reg, r);
+
+	up(&data->update_lock);
+	return count;
+}
+
+static ssize_t set_in_max(struct i2c_client *client, struct gl520_data *data, const char *buf, size_t count, int n, int reg)
+{
+	long v = simple_strtol(buf, NULL, 10);
+	u8 r;
+
+	if (n == 0)
+		r = VDD_TO_REG(v);
+	else
+		r = IN_TO_REG(v);
+
+	down(&data->update_lock);
+
+	data->in_max[n] = r;
+
+	if (n < 4)
+		gl520_write_value(client, reg, (gl520_read_value(client, reg) & ~0xff00) | (r << 8));
+	else
+		gl520_write_value(client, reg, r);
+
+	up(&data->update_lock);
+	return count;
+}
+
+#define DIV_FROM_REG(val) (1 << (val))
+#define FAN_FROM_REG(val,div) ((val)==0 ? 0 : (480000/((val) << (div))))
+#define FAN_TO_REG(val,div) ((val)<=0?0:SENSORS_LIMIT((480000 + ((val) << ((div)-1))) / ((val) << (div)), 1, 255));
+
+static ssize_t get_fan_input(struct gl520_data *data, char *buf, int n)
+{
+	return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan_input[n - 1], data->fan_div[n - 1]));
+}
+
+static ssize_t get_fan_min(struct gl520_data *data, char *buf, int n)
+{
+	return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan_min[n - 1], data->fan_div[n - 1]));
+}
+
+static ssize_t get_fan_div(struct gl520_data *data, char *buf, int n)
+{
+	return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[n - 1]));
+}
+
+static ssize_t get_fan_off(struct gl520_data *data, char *buf, int n)
+{
+	return sprintf(buf, "%d\n", data->fan_off);
+}
+
+static ssize_t set_fan_min(struct i2c_client *client, struct gl520_data *data, const char *buf, size_t count, int n, int reg)
+{
+	unsigned long v = simple_strtoul(buf, NULL, 10);
+	u8 r;
+
+	down(&data->update_lock);
+	r = FAN_TO_REG(v, data->fan_div[n - 1]);
+	data->fan_min[n - 1] = r;
+
+	if (n == 1)
+		gl520_write_value(client, reg, (gl520_read_value(client, reg) & ~0xff00) | (r << 8));
+	else
+		gl520_write_value(client, reg, (gl520_read_value(client, reg) & ~0xff) | r);
+
+	data->beep_mask = gl520_read_value(client, GL520_REG_BEEP_MASK);
+	if (data->fan_min[n - 1] == 0)
+		data->alarm_mask &= (n == 1) ? ~0x20 : ~0x40;
+	else
+		data->alarm_mask |= (n == 1) ? 0x20 : 0x40;
+	data->beep_mask &= data->alarm_mask;
+	gl520_write_value(client, GL520_REG_BEEP_MASK, data->beep_mask);
+
+	up(&data->update_lock);
+	return count;
+}
+
+static ssize_t set_fan_div(struct i2c_client *client, struct gl520_data *data, const char *buf, size_t count, int n, int reg)
+{
+	unsigned long v = simple_strtoul(buf, NULL, 10);
+	u8 r;
+
+	switch (v) {
+	case 1: r = 0; break;
+	case 2: r = 1; break;
+	case 4: r = 2; break;
+	case 8: r = 3; break;
+	default:
+		dev_err(&client->dev, "fan_div value %ld not supported. Choose one of 1, 2, 4 or 8!\n", v);
+		return -EINVAL;
+	}
+
+	down(&data->update_lock);
+	data->fan_div[n - 1] = r;
+
+	if (n == 1)
+		gl520_write_value(client, reg, (gl520_read_value(client, reg) & ~0xc0) | (r << 6));
+	else
+		gl520_write_value(client, reg, (gl520_read_value(client, reg) & ~0x30) | (r << 4));
+
+	up(&data->update_lock);
+	return count;
+}
+
+static ssize_t set_fan_off(struct i2c_client *client, struct gl520_data *data, const char *buf, size_t count, int n, int reg)
+{
+	u8 r = simple_strtoul(buf, NULL, 10)?1:0;
+
+	down(&data->update_lock);
+	data->fan_off = r;
+	gl520_write_value(client, reg, (gl520_read_value(client, reg) & ~0x0c) | (r << 2));
+	up(&data->update_lock);
+	return count;
+}
+
+#define TEMP_FROM_REG(val) (((val) - 130) * 1000)
+#define TEMP_TO_REG(val) (SENSORS_LIMIT(((((val)<0?(val)-500:(val)+500) / 1000)+130),0,255))
+
+static ssize_t get_temp_input(struct gl520_data *data, char *buf, int n)
+{
+	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_input[n - 1]));
+}
+
+static ssize_t get_temp_max(struct gl520_data *data, char *buf, int n)
+{
+	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_max[n - 1]));
+}
+
+static ssize_t get_temp_max_hyst(struct gl520_data *data, char *buf, int n)
+{
+	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_max_hyst[n - 1]));
+}
+
+static ssize_t set_temp_max(struct i2c_client *client, struct gl520_data *data, const char *buf, size_t count, int n, int reg)
+{
+	long v = simple_strtol(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->temp_max[n - 1] = TEMP_TO_REG(v);;
+	gl520_write_value(client, reg, data->temp_max[n - 1]);
+	up(&data->update_lock);
+	return count;
+}
+
+static ssize_t set_temp_max_hyst(struct i2c_client *client, struct gl520_data *data, const char *buf, size_t count, int n, int reg)
+{
+	long v = simple_strtol(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->temp_max_hyst[n - 1] = TEMP_TO_REG(v);
+	gl520_write_value(client, reg, data->temp_max_hyst[n - 1]);
+	up(&data->update_lock);
+	return count;
+}
+
+static ssize_t get_alarms(struct gl520_data *data, char *buf, int n)
+{
+	return sprintf(buf, "%d\n", data->alarms);
+}
+
+static ssize_t get_beep_enable(struct gl520_data *data, char *buf, int n)
+{
+	return sprintf(buf, "%d\n", data->beep_enable);
+}
+
+static ssize_t get_beep_mask(struct gl520_data *data, char *buf, int n)
+{
+	return sprintf(buf, "%d\n", data->beep_mask);
+}
+
+static ssize_t set_beep_enable(struct i2c_client *client, struct gl520_data *data, const char *buf, size_t count, int n, int reg)
+{
+	u8 r = simple_strtoul(buf, NULL, 10)?0:1;
+
+	down(&data->update_lock);
+	data->beep_enable = !r;
+	gl520_write_value(client, reg, (gl520_read_value(client, reg) & ~0x04) | (r << 2));
+	up(&data->update_lock);
+	return count;
+}
+
+static ssize_t set_beep_mask(struct i2c_client *client, struct gl520_data *data, const char *buf, size_t count, int n, int reg)
+{
+	u8 r = simple_strtoul(buf, NULL, 10);
+	
+	down(&data->update_lock);
+	r &= data->alarm_mask;
+	data->beep_mask = r;
+	gl520_write_value(client, reg, r);
+	up(&data->update_lock);
+	return count;
+}
+
+
+/*
+ * Real code
+ */
+
+static int gl520_attach_adapter(struct i2c_adapter *adapter)
+{
+	if (!(adapter->class & I2C_CLASS_HWMON))
+		return 0;
+	return i2c_detect(adapter, &addr_data, gl520_detect);
+}
+
+static int gl520_detect(struct i2c_adapter *adapter, int address, int kind)
+{
+	struct i2c_client *new_client;
+	struct gl520_data *data;
+	int err = 0;
+
+	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
+				     I2C_FUNC_SMBUS_WORD_DATA))
+		goto exit;
+
+	/* OK. For now, we presume we have a valid client. We now create the
+	   client structure, even though we cannot fill it completely yet.
+	   But it allows us to access gl520_{read,write}_value. */
+
+	if (!(data = kmalloc(sizeof(struct gl520_data), GFP_KERNEL))) {
+		err = -ENOMEM;
+		goto exit;
+	}
+	memset(data, 0, sizeof(struct gl520_data));
+
+	new_client = &data->client;
+	i2c_set_clientdata(new_client, data);
+	new_client->addr = address;
+	new_client->adapter = adapter;
+	new_client->driver = &gl520_driver;
+	new_client->flags = 0;
+
+	/* Determine the chip type. */
+	if (kind < 0) {
+		if ((gl520_read_value(new_client, GL520_REG_CHIP_ID) != 0x20) ||
+		    ((gl520_read_value(new_client, GL520_REG_REVISION) & 0x7f) != 0x00) ||
+		    ((gl520_read_value(new_client, GL520_REG_CONF) & 0x80) != 0x00)) {
+			dev_dbg(&new_client->dev, "Unknown chip type, skipping\n");
+			goto exit_free;
+		}
+	}
+
+	/* Fill in the remaining client fields */
+	strlcpy(new_client->name, "gl520sm", I2C_NAME_SIZE);
+	data->valid = 0;
+	init_MUTEX(&data->update_lock);
+
+	/* Tell the I2C layer a new client has arrived */
+	if ((err = i2c_attach_client(new_client)))
+		goto exit_free;
+
+	/* Initialize the GL520SM chip */
+	gl520_init_client(new_client);
+
+	/* Register sysfs hooks */
+	device_create_file_vid(new_client, 0);
+
+	device_create_file_in(new_client, 0);
+	device_create_file_in(new_client, 1);
+	device_create_file_in(new_client, 2);
+	device_create_file_in(new_client, 3);
+	if (!data->two_temps)
+		device_create_file_in(new_client, 4);
+
+	device_create_file_fan(new_client, 1);
+	device_create_file_fan(new_client, 2);
+	device_create_file_fan_off(new_client, 1);
+
+	device_create_file_temp(new_client, 1);
+	if (data->two_temps)
+		device_create_file_temp(new_client, 2);
+
+	device_create_file_alarms(new_client);
+
+	return 0;
+
+exit_free:
+	kfree(data);
+exit:
+	return err;
+}
+
+
+/* Called when we have found a new GL520SM. */
+static void gl520_init_client(struct i2c_client *client)
+{
+	struct gl520_data *data = i2c_get_clientdata(client);
+	u8 oldconf, conf;
+
+	conf = oldconf = gl520_read_value(client, GL520_REG_CONF);
+
+	data->alarm_mask = 0xff;
+	data->vrm = i2c_which_vrm();
+
+	if (extra_sensor_type == 1)
+		conf &= ~0x10;
+	else if (extra_sensor_type == 2)
+		conf |= 0x10;
+	data->two_temps = !(conf & 0x10);
+
+	/* If IRQ# is disabled, we can safely force comparator mode */
+	if (!(conf & 0x20))
+		conf &= 0xf7;
+
+	/* Enable monitoring if needed */
+	conf |= 0x40;
+
+	if (conf != oldconf)
+		gl520_write_value(client, GL520_REG_CONF, conf);
+
+	gl520_update_device(&(client->dev));
+
+	if (data->fan_min[0] == 0)
+		data->alarm_mask &= ~0x20;
+	if (data->fan_min[1] == 0)
+		data->alarm_mask &= ~0x40;
+
+	data->beep_mask &= data->alarm_mask;
+	gl520_write_value(client, GL520_REG_BEEP_MASK, data->beep_mask);
+}
+
+static int gl520_detach_client(struct i2c_client *client)
+{
+	int err;
+
+	if ((err = i2c_detach_client(client))) {
+		dev_err(&client->dev, "Client deregistration failed, "
+			"client not detached.\n");
+		return err;
+	}
+
+	kfree(i2c_get_clientdata(client));
+	return 0;
+}
+
+
+/* Registers 0x07 to 0x0c are word-sized, others are byte-sized 
+   GL520 uses a high-byte first convention */
+static int gl520_read_value(struct i2c_client *client, u8 reg)
+{
+	if ((reg >= 0x07) && (reg <= 0x0c))
+		return swab16(i2c_smbus_read_word_data(client, reg));
+	else
+		return i2c_smbus_read_byte_data(client, reg);
+}
+
+static int gl520_write_value(struct i2c_client *client, u8 reg, u16 value)
+{
+	if ((reg >= 0x07) && (reg <= 0x0c))
+		return i2c_smbus_write_word_data(client, reg, swab16(value));
+	else
+		return i2c_smbus_write_byte_data(client, reg, value);
+}
+
+
+static struct gl520_data *gl520_update_device(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct gl520_data *data = i2c_get_clientdata(client);
+	int val;
+
+	down(&data->update_lock);
+
+	if (time_after(jiffies, data->last_updated + 2 * HZ) || !data->valid) {
+
+		dev_dbg(&client->dev, "Starting gl520sm update\n");
+
+		data->alarms = gl520_read_value(client, GL520_REG_ALARMS);
+		data->beep_mask = gl520_read_value(client, GL520_REG_BEEP_MASK);
+		data->vid = gl520_read_value(client, GL520_REG_VID_INPUT) & 0x1f;
+
+		val = gl520_read_value(client, GL520_REG_IN0_LIMIT);
+		data->in_min[0] = val & 0xff;
+		data->in_max[0] = (val >> 8) & 0xff;
+		val = gl520_read_value(client, GL520_REG_IN1_LIMIT);
+		data->in_min[1] = val & 0xff;
+		data->in_max[1] = (val >> 8) & 0xff;
+		val = gl520_read_value(client, GL520_REG_IN2_LIMIT);
+		data->in_min[2] = val & 0xff;
+		data->in_max[2] = (val >> 8) & 0xff;
+		val = gl520_read_value(client, GL520_REG_IN3_LIMIT);
+		data->in_min[3] = val & 0xff;
+		data->in_max[3] = (val >> 8) & 0xff;
+
+		val = gl520_read_value(client, GL520_REG_FAN_INPUT);
+		data->fan_input[0] = (val >> 8) & 0xff;
+		data->fan_input[1] = val & 0xff;
+
+		val = gl520_read_value(client, GL520_REG_FAN_MIN);
+		data->fan_min[0] = (val >> 8) & 0xff;
+		data->fan_min[1] = val & 0xff;
+
+		data->temp_input[0] = gl520_read_value(client, GL520_REG_TEMP1_INPUT);
+		data->temp_max[0] = gl520_read_value(client, GL520_REG_TEMP1_MAX);
+		data->temp_max_hyst[0] = gl520_read_value(client, GL520_REG_TEMP1_MAX_HYST);
+
+		val = gl520_read_value(client, GL520_REG_FAN_DIV);
+		data->fan_div[0] = (val >> 6) & 0x03;
+		data->fan_div[1] = (val >> 4) & 0x03;
+		data->fan_off = (val >> 2) & 0x01;
+
+		data->alarms &= data->alarm_mask;
+
+		val = gl520_read_value(client, GL520_REG_CONF);
+		data->beep_enable = !((val >> 2) & 1);
+
+		data->in_input[0] = gl520_read_value(client, GL520_REG_IN0_INPUT);
+		data->in_input[1] = gl520_read_value(client, GL520_REG_IN1_INPUT);
+		data->in_input[2] = gl520_read_value(client, GL520_REG_IN2_INPUT);
+		data->in_input[3] = gl520_read_value(client, GL520_REG_IN3_INPUT);
+
+		/* Temp1 and Vin4 are the same input */
+		if (data->two_temps) {
+			data->temp_input[1] = gl520_read_value(client, GL520_REG_TEMP2_INPUT);
+			data->temp_max[1] = gl520_read_value(client, GL520_REG_TEMP2_MAX);
+			data->temp_max_hyst[1] = gl520_read_value(client, GL520_REG_TEMP2_MAX_HYST);
+		} else {
+			data->in_input[4] = gl520_read_value(client, GL520_REG_IN4_INPUT);
+			data->in_min[4] = gl520_read_value(client, GL520_REG_IN4_MIN);
+			data->in_max[4] = gl520_read_value(client, GL520_REG_IN4_MAX);
+		}
+
+		data->last_updated = jiffies;
+		data->valid = 1;
+	}
+
+	up(&data->update_lock);
+
+	return data;
+}
+
+
+static int __init sensors_gl520sm_init(void)
+{
+	return i2c_add_driver(&gl520_driver);
+}
+
+static void __exit sensors_gl520sm_exit(void)
+{
+	i2c_del_driver(&gl520_driver);
+}
+
+
+MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>, "
+	"Kyösti Mälkki <kmalkki@cc.hut.fi>, "
+	"Maarten Deprez <maartendeprez@users.sourceforge.net>");
+MODULE_DESCRIPTION("GL520SM driver");
+MODULE_LICENSE("GPL");
+
+module_init(sensors_gl520sm_init);
+module_exit(sensors_gl520sm_exit);
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
new file mode 100644
--- /dev/null
+++ b/drivers/hwmon/it87.c
@@ -0,0 +1,1184 @@
+/*
+    it87.c - Part of lm_sensors, Linux kernel modules for hardware
+             monitoring.
+
+    Supports: IT8705F  Super I/O chip w/LPC interface & SMBus
+              IT8712F  Super I/O chip w/LPC interface & SMBus
+              Sis950   A clone of the IT8705F
+
+    Copyright (C) 2001 Chris Gauthron <chrisg@0-in.com> 
+    Largely inspired by lm78.c of the same package
+
+    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.
+*/
+
+/*
+    djg@pdp8.net David Gesswein 7/18/01
+    Modified to fix bug with not all alarms enabled.
+    Added ability to read battery voltage and select temperature sensor
+    type at module load time.
+*/
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+#include <linux/i2c.h>
+#include <linux/i2c-sensor.h>
+#include <linux/i2c-vid.h>
+#include <linux/hwmon-sysfs.h>
+#include <asm/io.h>
+
+
+/* Addresses to scan */
+static unsigned short normal_i2c[] = { 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d,
+					0x2e, 0x2f, I2C_CLIENT_END };
+static unsigned int normal_isa[] = { 0x0290, I2C_CLIENT_ISA_END };
+
+/* Insmod parameters */
+SENSORS_INSMOD_2(it87, it8712);
+
+#define	REG	0x2e	/* The register to read/write */
+#define	DEV	0x07	/* Register: Logical device select */
+#define	VAL	0x2f	/* The value to read/write */
+#define PME	0x04	/* The device with the fan registers in it */
+#define	DEVID	0x20	/* Register: Device ID */
+#define	DEVREV	0x22	/* Register: Device Revision */
+
+static inline int
+superio_inb(int reg)
+{
+	outb(reg, REG);
+	return inb(VAL);
+}
+
+static int superio_inw(int reg)
+{
+	int val;
+	outb(reg++, REG);
+	val = inb(VAL) << 8;
+	outb(reg, REG);
+	val |= inb(VAL);
+	return val;
+}
+
+static inline void
+superio_select(void)
+{
+	outb(DEV, REG);
+	outb(PME, VAL);
+}
+
+static inline void
+superio_enter(void)
+{
+	outb(0x87, REG);
+	outb(0x01, REG);
+	outb(0x55, REG);
+	outb(0x55, REG);
+}
+
+static inline void
+superio_exit(void)
+{
+	outb(0x02, REG);
+	outb(0x02, VAL);
+}
+
+#define IT8712F_DEVID 0x8712
+#define IT8705F_DEVID 0x8705
+#define IT87_ACT_REG  0x30
+#define IT87_BASE_REG 0x60
+
+/* Update battery voltage after every reading if true */
+static int update_vbat;
+
+/* Not all BIOSes properly configure the PWM registers */
+static int fix_pwm_polarity;
+
+/* Chip Type */
+
+static u16 chip_type;
+
+/* Many IT87 constants specified below */
+
+/* Length of ISA address segment */
+#define IT87_EXTENT 8
+
+/* Where are the ISA address/data registers relative to the base address */
+#define IT87_ADDR_REG_OFFSET 5
+#define IT87_DATA_REG_OFFSET 6
+
+/*----- The IT87 registers -----*/
+
+#define IT87_REG_CONFIG        0x00
+
+#define IT87_REG_ALARM1        0x01
+#define IT87_REG_ALARM2        0x02
+#define IT87_REG_ALARM3        0x03
+
+#define IT87_REG_VID           0x0a
+#define IT87_REG_FAN_DIV       0x0b
+
+/* Monitors: 9 voltage (0 to 7, battery), 3 temp (1 to 3), 3 fan (1 to 3) */
+
+#define IT87_REG_FAN(nr)       (0x0d + (nr))
+#define IT87_REG_FAN_MIN(nr)   (0x10 + (nr))
+#define IT87_REG_FAN_MAIN_CTRL 0x13
+#define IT87_REG_FAN_CTL       0x14
+#define IT87_REG_PWM(nr)       (0x15 + (nr))
+
+#define IT87_REG_VIN(nr)       (0x20 + (nr))
+#define IT87_REG_TEMP(nr)      (0x29 + (nr))
+
+#define IT87_REG_VIN_MAX(nr)   (0x30 + (nr) * 2)
+#define IT87_REG_VIN_MIN(nr)   (0x31 + (nr) * 2)
+#define IT87_REG_TEMP_HIGH(nr) (0x40 + (nr) * 2)
+#define IT87_REG_TEMP_LOW(nr)  (0x41 + (nr) * 2)
+
+#define IT87_REG_I2C_ADDR      0x48
+
+#define IT87_REG_VIN_ENABLE    0x50
+#define IT87_REG_TEMP_ENABLE   0x51
+
+#define IT87_REG_CHIPID        0x58
+
+#define IN_TO_REG(val)  (SENSORS_LIMIT((((val) + 8)/16),0,255))
+#define IN_FROM_REG(val) ((val) * 16)
+
+static inline u8 FAN_TO_REG(long rpm, int div)
+{
+	if (rpm == 0)
+		return 255;
+	rpm = SENSORS_LIMIT(rpm, 1, 1000000);
+	return SENSORS_LIMIT((1350000 + rpm * div / 2) / (rpm * div), 1,
+			     254);
+}
+
+#define FAN_FROM_REG(val,div) ((val)==0?-1:(val)==255?0:1350000/((val)*(div)))
+
+#define TEMP_TO_REG(val) (SENSORS_LIMIT(((val)<0?(((val)-500)/1000):\
+					((val)+500)/1000),-128,127))
+#define TEMP_FROM_REG(val) (((val)>0x80?(val)-0x100:(val))*1000)
+
+#define PWM_TO_REG(val)   ((val) >> 1)
+#define PWM_FROM_REG(val) (((val)&0x7f) << 1)
+
+static int DIV_TO_REG(int val)
+{
+	int answer = 0;
+	while ((val >>= 1) != 0)
+		answer++;
+	return answer;
+}
+#define DIV_FROM_REG(val) (1 << (val))
+
+
+/* For each registered IT87, we need to keep some data in memory. That
+   data is pointed to by it87_list[NR]->data. The structure itself is
+   dynamically allocated, at the same time when a new it87 client is
+   allocated. */
+struct it87_data {
+	struct i2c_client client;
+	struct semaphore lock;
+	enum chips type;
+
+	struct semaphore update_lock;
+	char valid;		/* !=0 if following fields are valid */
+	unsigned long last_updated;	/* In jiffies */
+
+	u8 in[9];		/* Register value */
+	u8 in_max[9];		/* Register value */
+	u8 in_min[9];		/* Register value */
+	u8 fan[3];		/* Register value */
+	u8 fan_min[3];		/* Register value */
+	u8 temp[3];		/* Register value */
+	u8 temp_high[3];	/* Register value */
+	u8 temp_low[3];		/* Register value */
+	u8 sensor;		/* Register value */
+	u8 fan_div[3];		/* Register encoding, shifted right */
+	u8 vid;			/* Register encoding, combined */
+	int vrm;
+	u32 alarms;		/* Register encoding, combined */
+	u8 fan_main_ctrl;	/* Register value */
+	u8 manual_pwm_ctl[3];   /* manual PWM value set by user */
+};
+
+
+static int it87_attach_adapter(struct i2c_adapter *adapter);
+static int it87_find(int *address);
+static int it87_detect(struct i2c_adapter *adapter, int address, int kind);
+static int it87_detach_client(struct i2c_client *client);
+
+static int it87_read_value(struct i2c_client *client, u8 register);
+static int it87_write_value(struct i2c_client *client, u8 register,
+			u8 value);
+static struct it87_data *it87_update_device(struct device *dev);
+static int it87_check_pwm(struct i2c_client *client);
+static void it87_init_client(struct i2c_client *client, struct it87_data *data);
+
+
+static struct i2c_driver it87_driver = {
+	.owner		= THIS_MODULE,
+	.name		= "it87",
+	.id		= I2C_DRIVERID_IT87,
+	.flags		= I2C_DF_NOTIFY,
+	.attach_adapter	= it87_attach_adapter,
+	.detach_client	= it87_detach_client,
+};
+
+static ssize_t show_in(struct device *dev, struct device_attribute *attr,
+		char *buf)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+
+	struct it87_data *data = it87_update_device(dev);
+	return sprintf(buf, "%d\n", IN_FROM_REG(data->in[nr]));
+}
+
+static ssize_t show_in_min(struct device *dev, struct device_attribute *attr,
+		char *buf)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+
+	struct it87_data *data = it87_update_device(dev);
+	return sprintf(buf, "%d\n", IN_FROM_REG(data->in_min[nr]));
+}
+
+static ssize_t show_in_max(struct device *dev, struct device_attribute *attr,
+		char *buf)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+
+	struct it87_data *data = it87_update_device(dev);
+	return sprintf(buf, "%d\n", IN_FROM_REG(data->in_max[nr]));
+}
+
+static ssize_t set_in_min(struct device *dev, struct device_attribute *attr,
+		const char *buf, size_t count)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+
+	struct i2c_client *client = to_i2c_client(dev);
+	struct it87_data *data = i2c_get_clientdata(client);
+	unsigned long val = simple_strtoul(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->in_min[nr] = IN_TO_REG(val);
+	it87_write_value(client, IT87_REG_VIN_MIN(nr), 
+			data->in_min[nr]);
+	up(&data->update_lock);
+	return count;
+}
+static ssize_t set_in_max(struct device *dev, struct device_attribute *attr,
+		const char *buf, size_t count)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+
+	struct i2c_client *client = to_i2c_client(dev);
+	struct it87_data *data = i2c_get_clientdata(client);
+	unsigned long val = simple_strtoul(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->in_max[nr] = IN_TO_REG(val);
+	it87_write_value(client, IT87_REG_VIN_MAX(nr), 
+			data->in_max[nr]);
+	up(&data->update_lock);
+	return count;
+}
+
+#define show_in_offset(offset)					\
+static SENSOR_DEVICE_ATTR(in##offset##_input, S_IRUGO,		\
+		show_in, NULL, offset);
+
+#define limit_in_offset(offset)					\
+static SENSOR_DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR,	\
+		show_in_min, set_in_min, offset);		\
+static SENSOR_DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR,	\
+		show_in_max, set_in_max, offset);
+
+show_in_offset(0);
+limit_in_offset(0);
+show_in_offset(1);
+limit_in_offset(1);
+show_in_offset(2);
+limit_in_offset(2);
+show_in_offset(3);
+limit_in_offset(3);
+show_in_offset(4);
+limit_in_offset(4);
+show_in_offset(5);
+limit_in_offset(5);
+show_in_offset(6);
+limit_in_offset(6);
+show_in_offset(7);
+limit_in_offset(7);
+show_in_offset(8);
+
+/* 3 temperatures */
+static ssize_t show_temp(struct device *dev, struct device_attribute *attr,
+		char *buf)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+
+	struct it87_data *data = it87_update_device(dev);
+	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp[nr]));
+}
+static ssize_t show_temp_max(struct device *dev, struct device_attribute *attr,
+		char *buf)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+
+	struct it87_data *data = it87_update_device(dev);
+	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_high[nr]));
+}
+static ssize_t show_temp_min(struct device *dev, struct device_attribute *attr,
+		char *buf)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+
+	struct it87_data *data = it87_update_device(dev);
+	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_low[nr]));
+}
+static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr,
+		const char *buf, size_t count)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+
+	struct i2c_client *client = to_i2c_client(dev);
+	struct it87_data *data = i2c_get_clientdata(client);
+	int val = simple_strtol(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->temp_high[nr] = TEMP_TO_REG(val);
+	it87_write_value(client, IT87_REG_TEMP_HIGH(nr), data->temp_high[nr]);
+	up(&data->update_lock);
+	return count;
+}
+static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr,
+		const char *buf, size_t count)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+
+	struct i2c_client *client = to_i2c_client(dev);
+	struct it87_data *data = i2c_get_clientdata(client);
+	int val = simple_strtol(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->temp_low[nr] = TEMP_TO_REG(val);
+	it87_write_value(client, IT87_REG_TEMP_LOW(nr), data->temp_low[nr]);
+	up(&data->update_lock);
+	return count;
+}
+#define show_temp_offset(offset)					\
+static SENSOR_DEVICE_ATTR(temp##offset##_input, S_IRUGO,		\
+		show_temp, NULL, offset - 1);				\
+static SENSOR_DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR,	\
+		show_temp_max, set_temp_max, offset - 1);		\
+static SENSOR_DEVICE_ATTR(temp##offset##_min, S_IRUGO | S_IWUSR,	\
+		show_temp_min, set_temp_min, offset - 1);
+
+show_temp_offset(1);
+show_temp_offset(2);
+show_temp_offset(3);
+
+static ssize_t show_sensor(struct device *dev, struct device_attribute *attr,
+		char *buf)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+
+	struct it87_data *data = it87_update_device(dev);
+	u8 reg = data->sensor; /* In case the value is updated while we use it */
+	
+	if (reg & (1 << nr))
+		return sprintf(buf, "3\n");  /* thermal diode */
+	if (reg & (8 << nr))
+		return sprintf(buf, "2\n");  /* thermistor */
+	return sprintf(buf, "0\n");      /* disabled */
+}
+static ssize_t set_sensor(struct device *dev, struct device_attribute *attr,
+		const char *buf, size_t count)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+
+	struct i2c_client *client = to_i2c_client(dev);
+	struct it87_data *data = i2c_get_clientdata(client);
+	int val = simple_strtol(buf, NULL, 10);
+
+	down(&data->update_lock);
+
+	data->sensor &= ~(1 << nr);
+	data->sensor &= ~(8 << nr);
+	/* 3 = thermal diode; 2 = thermistor; 0 = disabled */
+	if (val == 3)
+	    data->sensor |= 1 << nr;
+	else if (val == 2)
+	    data->sensor |= 8 << nr;
+	else if (val != 0) {
+		up(&data->update_lock);
+		return -EINVAL;
+	}
+	it87_write_value(client, IT87_REG_TEMP_ENABLE, data->sensor);
+	up(&data->update_lock);
+	return count;
+}
+#define show_sensor_offset(offset)					\
+static SENSOR_DEVICE_ATTR(temp##offset##_type, S_IRUGO | S_IWUSR,	\
+		show_sensor, set_sensor, offset - 1);
+
+show_sensor_offset(1);
+show_sensor_offset(2);
+show_sensor_offset(3);
+
+/* 3 Fans */
+static ssize_t show_fan(struct device *dev, struct device_attribute *attr,
+		char *buf)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+
+	struct it87_data *data = it87_update_device(dev);
+	return sprintf(buf,"%d\n", FAN_FROM_REG(data->fan[nr], 
+				DIV_FROM_REG(data->fan_div[nr])));
+}
+static ssize_t show_fan_min(struct device *dev, struct device_attribute *attr,
+		char *buf)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+
+	struct it87_data *data = it87_update_device(dev);
+	return sprintf(buf,"%d\n",
+		FAN_FROM_REG(data->fan_min[nr], DIV_FROM_REG(data->fan_div[nr])));
+}
+static ssize_t show_fan_div(struct device *dev, struct device_attribute *attr,
+		char *buf)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+
+	struct it87_data *data = it87_update_device(dev);
+	return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[nr]));
+}
+static ssize_t show_pwm_enable(struct device *dev, struct device_attribute *attr,
+		char *buf)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+
+	struct it87_data *data = it87_update_device(dev);
+	return sprintf(buf,"%d\n", (data->fan_main_ctrl & (1 << nr)) ? 1 : 0);
+}
+static ssize_t show_pwm(struct device *dev, struct device_attribute *attr,
+		char *buf)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+
+	struct it87_data *data = it87_update_device(dev);
+	return sprintf(buf,"%d\n", data->manual_pwm_ctl[nr]);
+}
+static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr,
+		const char *buf, size_t count)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+
+	struct i2c_client *client = to_i2c_client(dev);
+	struct it87_data *data = i2c_get_clientdata(client);
+	int val = simple_strtol(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr]));
+	it87_write_value(client, IT87_REG_FAN_MIN(nr), data->fan_min[nr]);
+	up(&data->update_lock);
+	return count;
+}
+static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr,
+		const char *buf, size_t count)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+
+	struct i2c_client *client = to_i2c_client(dev);
+	struct it87_data *data = i2c_get_clientdata(client);
+	int val = simple_strtol(buf, NULL, 10);
+	int i, min[3];
+	u8 old;
+
+	down(&data->update_lock);
+	old = it87_read_value(client, IT87_REG_FAN_DIV);
+
+	for (i = 0; i < 3; i++)
+		min[i] = FAN_FROM_REG(data->fan_min[i], DIV_FROM_REG(data->fan_div[i]));
+
+	switch (nr) {
+	case 0:
+	case 1:
+		data->fan_div[nr] = DIV_TO_REG(val);
+		break;
+	case 2:
+		if (val < 8)
+			data->fan_div[nr] = 1;
+		else
+			data->fan_div[nr] = 3;
+	}
+	val = old & 0x80;
+	val |= (data->fan_div[0] & 0x07);
+	val |= (data->fan_div[1] & 0x07) << 3;
+	if (data->fan_div[2] == 3)
+		val |= 0x1 << 6;
+	it87_write_value(client, IT87_REG_FAN_DIV, val);
+
+	for (i = 0; i < 3; i++) {
+		data->fan_min[i]=FAN_TO_REG(min[i], DIV_FROM_REG(data->fan_div[i]));
+		it87_write_value(client, IT87_REG_FAN_MIN(i), data->fan_min[i]);
+	}
+	up(&data->update_lock);
+	return count;
+}
+static ssize_t set_pwm_enable(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+
+	struct i2c_client *client = to_i2c_client(dev);
+	struct it87_data *data = i2c_get_clientdata(client);
+	int val = simple_strtol(buf, NULL, 10);
+
+	down(&data->update_lock);
+
+	if (val == 0) {
+		int tmp;
+		/* make sure the fan is on when in on/off mode */
+		tmp = it87_read_value(client, IT87_REG_FAN_CTL);
+		it87_write_value(client, IT87_REG_FAN_CTL, tmp | (1 << nr));
+		/* set on/off mode */
+		data->fan_main_ctrl &= ~(1 << nr);
+		it87_write_value(client, IT87_REG_FAN_MAIN_CTRL, data->fan_main_ctrl);
+	} else if (val == 1) {
+		/* set SmartGuardian mode */
+		data->fan_main_ctrl |= (1 << nr);
+		it87_write_value(client, IT87_REG_FAN_MAIN_CTRL, data->fan_main_ctrl);
+		/* set saved pwm value, clear FAN_CTLX PWM mode bit */
+		it87_write_value(client, IT87_REG_PWM(nr), PWM_TO_REG(data->manual_pwm_ctl[nr]));
+	} else {
+		up(&data->update_lock);
+		return -EINVAL;
+	}
+
+	up(&data->update_lock);
+	return count;
+}
+static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
+		const char *buf, size_t count)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+
+	struct i2c_client *client = to_i2c_client(dev);
+	struct it87_data *data = i2c_get_clientdata(client);
+	int val = simple_strtol(buf, NULL, 10);
+
+	if (val < 0 || val > 255)
+		return -EINVAL;
+
+	down(&data->update_lock);
+	data->manual_pwm_ctl[nr] = val;
+	if (data->fan_main_ctrl & (1 << nr))
+		it87_write_value(client, IT87_REG_PWM(nr), PWM_TO_REG(data->manual_pwm_ctl[nr]));
+	up(&data->update_lock);
+	return count;
+}
+
+#define show_fan_offset(offset)					\
+static SENSOR_DEVICE_ATTR(fan##offset##_input, S_IRUGO,		\
+		show_fan, NULL, offset - 1);			\
+static SENSOR_DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \
+		show_fan_min, set_fan_min, offset - 1);		\
+static SENSOR_DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, \
+		show_fan_div, set_fan_div, offset - 1);
+
+show_fan_offset(1);
+show_fan_offset(2);
+show_fan_offset(3);
+
+#define show_pwm_offset(offset)						\
+static SENSOR_DEVICE_ATTR(pwm##offset##_enable, S_IRUGO | S_IWUSR,	\
+		show_pwm_enable, set_pwm_enable, offset - 1);		\
+static SENSOR_DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR,		\
+		show_pwm, set_pwm, offset - 1);
+
+show_pwm_offset(1);
+show_pwm_offset(2);
+show_pwm_offset(3);
+
+/* Alarms */
+static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct it87_data *data = it87_update_device(dev);
+	return sprintf(buf, "%u\n", data->alarms);
+}
+static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
+
+static ssize_t
+show_vrm_reg(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct it87_data *data = it87_update_device(dev);
+	return sprintf(buf, "%ld\n", (long) data->vrm);
+}
+static ssize_t
+store_vrm_reg(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct it87_data *data = i2c_get_clientdata(client);
+	u32 val;
+
+	val = simple_strtoul(buf, NULL, 10);
+	data->vrm = val;
+
+	return count;
+}
+static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg);
+#define device_create_file_vrm(client) \
+device_create_file(&client->dev, &dev_attr_vrm)
+
+static ssize_t
+show_vid_reg(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct it87_data *data = it87_update_device(dev);
+	return sprintf(buf, "%ld\n", (long) vid_from_reg(data->vid, data->vrm));
+}
+static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid_reg, NULL);
+#define device_create_file_vid(client) \
+device_create_file(&client->dev, &dev_attr_cpu0_vid)
+
+/* This function is called when:
+     * it87_driver is inserted (when this module is loaded), for each
+       available adapter
+     * when a new adapter is inserted (and it87_driver is still present) */
+static int it87_attach_adapter(struct i2c_adapter *adapter)
+{
+	if (!(adapter->class & I2C_CLASS_HWMON))
+		return 0;
+	return i2c_detect(adapter, &addr_data, it87_detect);
+}
+
+/* SuperIO detection - will change normal_isa[0] if a chip is found */
+static int it87_find(int *address)
+{
+	int err = -ENODEV;
+
+	superio_enter();
+	chip_type = superio_inw(DEVID);
+	if (chip_type != IT8712F_DEVID
+	 && chip_type != IT8705F_DEVID)
+	 	goto exit;
+
+	superio_select();
+	if (!(superio_inb(IT87_ACT_REG) & 0x01)) {
+		pr_info("it87: Device not activated, skipping\n");
+		goto exit;
+	}
+
+	*address = superio_inw(IT87_BASE_REG) & ~(IT87_EXTENT - 1);
+	if (*address == 0) {
+		pr_info("it87: Base address not set, skipping\n");
+		goto exit;
+	}
+
+	err = 0;
+	pr_info("it87: Found IT%04xF chip at 0x%x, revision %d\n",
+		chip_type, *address, superio_inb(DEVREV) & 0x0f);
+
+exit:
+	superio_exit();
+	return err;
+}
+
+/* This function is called by i2c_detect */
+int it87_detect(struct i2c_adapter *adapter, int address, int kind)
+{
+	int i;
+	struct i2c_client *new_client;
+	struct it87_data *data;
+	int err = 0;
+	const char *name = "";
+	int is_isa = i2c_is_isa_adapter(adapter);
+	int enable_pwm_interface;
+
+	if (!is_isa && 
+	    !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+		goto ERROR0;
+
+	/* Reserve the ISA region */
+	if (is_isa)
+		if (!request_region(address, IT87_EXTENT, it87_driver.name))
+			goto ERROR0;
+
+	/* Probe whether there is anything available on this address. Already
+	   done for SMBus and Super-I/O clients */
+	if (kind < 0) {
+		if (is_isa && !chip_type) {
+#define REALLY_SLOW_IO
+			/* We need the timeouts for at least some IT87-like chips. But only
+			   if we read 'undefined' registers. */
+			i = inb_p(address + 1);
+			if (inb_p(address + 2) != i
+			 || inb_p(address + 3) != i
+			 || inb_p(address + 7) != i) {
+		 		err = -ENODEV;
+				goto ERROR1;
+			}
+#undef REALLY_SLOW_IO
+
+			/* Let's just hope nothing breaks here */
+			i = inb_p(address + 5) & 0x7f;
+			outb_p(~i & 0x7f, address + 5);
+			if ((inb_p(address + 5) & 0x7f) != (~i & 0x7f)) {
+				outb_p(i, address + 5);
+				err = -ENODEV;
+				goto ERROR1;
+			}
+		}
+	}
+
+	/* OK. For now, we presume we have a valid client. We now create the
+	   client structure, even though we cannot fill it completely yet.
+	   But it allows us to access it87_{read,write}_value. */
+
+	if (!(data = kmalloc(sizeof(struct it87_data), GFP_KERNEL))) {
+		err = -ENOMEM;
+		goto ERROR1;
+	}
+	memset(data, 0, sizeof(struct it87_data));
+
+	new_client = &data->client;
+	if (is_isa)
+		init_MUTEX(&data->lock);
+	i2c_set_clientdata(new_client, data);
+	new_client->addr = address;
+	new_client->adapter = adapter;
+	new_client->driver = &it87_driver;
+	new_client->flags = 0;
+
+	/* Now, we do the remaining detection. */
+
+	if (kind < 0) {
+		if ((it87_read_value(new_client, IT87_REG_CONFIG) & 0x80)
+		  || (!is_isa
+		   && it87_read_value(new_client, IT87_REG_I2C_ADDR) != address)) {
+		   	err = -ENODEV;
+			goto ERROR2;
+		}
+	}
+
+	/* Determine the chip type. */
+	if (kind <= 0) {
+		i = it87_read_value(new_client, IT87_REG_CHIPID);
+		if (i == 0x90) {
+			kind = it87;
+			if ((is_isa) && (chip_type == IT8712F_DEVID))
+				kind = it8712;
+		}
+		else {
+			if (kind == 0)
+				dev_info(&adapter->dev, 
+					"Ignoring 'force' parameter for unknown chip at "
+					"adapter %d, address 0x%02x\n",
+					i2c_adapter_id(adapter), address);
+			err = -ENODEV;
+			goto ERROR2;
+		}
+	}
+
+	if (kind == it87) {
+		name = "it87";
+	} else if (kind == it8712) {
+		name = "it8712";
+	}
+
+	/* Fill in the remaining client fields and put it into the global list */
+	strlcpy(new_client->name, name, I2C_NAME_SIZE);
+	data->type = kind;
+	data->valid = 0;
+	init_MUTEX(&data->update_lock);
+
+	/* Tell the I2C layer a new client has arrived */
+	if ((err = i2c_attach_client(new_client)))
+		goto ERROR2;
+
+	/* Check PWM configuration */
+	enable_pwm_interface = it87_check_pwm(new_client);
+
+	/* Initialize the IT87 chip */
+	it87_init_client(new_client, data);
+
+	/* Register sysfs hooks */
+	device_create_file(&new_client->dev, &sensor_dev_attr_in0_input.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in1_input.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in2_input.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in3_input.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in4_input.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in5_input.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in6_input.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in7_input.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in8_input.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in0_min.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in1_min.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in2_min.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in3_min.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in4_min.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in5_min.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in6_min.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in7_min.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in0_max.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in1_max.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in2_max.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in3_max.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in4_max.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in5_max.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in6_max.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_in7_max.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_temp1_input.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_temp2_input.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_temp3_input.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_temp1_max.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_temp2_max.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_temp3_max.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_temp1_min.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_temp2_min.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_temp3_min.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_temp1_type.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_temp2_type.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_temp3_type.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_fan1_input.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_fan2_input.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_fan3_input.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_fan1_min.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_fan2_min.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_fan3_min.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_fan1_div.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_fan2_div.dev_attr);
+	device_create_file(&new_client->dev, &sensor_dev_attr_fan3_div.dev_attr);
+	device_create_file(&new_client->dev, &dev_attr_alarms);
+	if (enable_pwm_interface) {
+		device_create_file(&new_client->dev, &sensor_dev_attr_pwm1_enable.dev_attr);
+		device_create_file(&new_client->dev, &sensor_dev_attr_pwm2_enable.dev_attr);
+		device_create_file(&new_client->dev, &sensor_dev_attr_pwm3_enable.dev_attr);
+		device_create_file(&new_client->dev, &sensor_dev_attr_pwm1.dev_attr);
+		device_create_file(&new_client->dev, &sensor_dev_attr_pwm2.dev_attr);
+		device_create_file(&new_client->dev, &sensor_dev_attr_pwm3.dev_attr);
+	}
+
+	if (data->type == it8712) {
+		data->vrm = i2c_which_vrm();
+		device_create_file_vrm(new_client);
+		device_create_file_vid(new_client);
+	}
+
+	return 0;
+
+ERROR2:
+	kfree(data);
+ERROR1:
+	if (is_isa)
+		release_region(address, IT87_EXTENT);
+ERROR0:
+	return err;
+}
+
+static int it87_detach_client(struct i2c_client *client)
+{
+	int err;
+
+	if ((err = i2c_detach_client(client))) {
+		dev_err(&client->dev,
+			"Client deregistration failed, client not detached.\n");
+		return err;
+	}
+
+	if(i2c_is_isa_client(client))
+		release_region(client->addr, IT87_EXTENT);
+	kfree(i2c_get_clientdata(client));
+
+	return 0;
+}
+
+/* The SMBus locks itself, but ISA access must be locked explicitly! 
+   We don't want to lock the whole ISA bus, so we lock each client
+   separately.
+   We ignore the IT87 BUSY flag at this moment - it could lead to deadlocks,
+   would slow down the IT87 access and should not be necessary. */
+static int it87_read_value(struct i2c_client *client, u8 reg)
+{
+	struct it87_data *data = i2c_get_clientdata(client);
+
+	int res;
+	if (i2c_is_isa_client(client)) {
+		down(&data->lock);
+		outb_p(reg, client->addr + IT87_ADDR_REG_OFFSET);
+		res = inb_p(client->addr + IT87_DATA_REG_OFFSET);
+		up(&data->lock);
+		return res;
+	} else
+		return i2c_smbus_read_byte_data(client, reg);
+}
+
+/* The SMBus locks itself, but ISA access muse be locked explicitly! 
+   We don't want to lock the whole ISA bus, so we lock each client
+   separately.
+   We ignore the IT87 BUSY flag at this moment - it could lead to deadlocks,
+   would slow down the IT87 access and should not be necessary. */
+static int it87_write_value(struct i2c_client *client, u8 reg, u8 value)
+{
+	struct it87_data *data = i2c_get_clientdata(client);
+
+	if (i2c_is_isa_client(client)) {
+		down(&data->lock);
+		outb_p(reg, client->addr + IT87_ADDR_REG_OFFSET);
+		outb_p(value, client->addr + IT87_DATA_REG_OFFSET);
+		up(&data->lock);
+		return 0;
+	} else
+		return i2c_smbus_write_byte_data(client, reg, value);
+}
+
+/* Return 1 if and only if the PWM interface is safe to use */
+static int it87_check_pwm(struct i2c_client *client)
+{
+	/* Some BIOSes fail to correctly configure the IT87 fans. All fans off
+	 * and polarity set to active low is sign that this is the case so we
+	 * disable pwm control to protect the user. */
+	int tmp = it87_read_value(client, IT87_REG_FAN_CTL);
+	if ((tmp & 0x87) == 0) {
+		if (fix_pwm_polarity) {
+			/* The user asks us to attempt a chip reconfiguration.
+			 * This means switching to active high polarity and
+			 * inverting all fan speed values. */
+			int i;
+			u8 pwm[3];
+
+			for (i = 0; i < 3; i++)
+				pwm[i] = it87_read_value(client,
+							 IT87_REG_PWM(i));
+
+			/* If any fan is in automatic pwm mode, the polarity
+			 * might be correct, as suspicious as it seems, so we
+			 * better don't change anything (but still disable the
+			 * PWM interface). */
+			if (!((pwm[0] | pwm[1] | pwm[2]) & 0x80)) {
+				dev_info(&client->dev, "Reconfiguring PWM to "
+					 "active high polarity\n");
+				it87_write_value(client, IT87_REG_FAN_CTL,
+						 tmp | 0x87);
+				for (i = 0; i < 3; i++)
+					it87_write_value(client,
+							 IT87_REG_PWM(i),
+							 0x7f & ~pwm[i]);
+				return 1;
+			}
+
+			dev_info(&client->dev, "PWM configuration is "
+				 "too broken to be fixed\n");
+		}
+
+		dev_info(&client->dev, "Detected broken BIOS "
+			 "defaults, disabling PWM interface\n");
+		return 0;
+	} else if (fix_pwm_polarity) {
+		dev_info(&client->dev, "PWM configuration looks "
+			 "sane, won't touch\n");
+	}
+
+	return 1;
+}
+
+/* Called when we have found a new IT87. */
+static void it87_init_client(struct i2c_client *client, struct it87_data *data)
+{
+	int tmp, i;
+
+	/* initialize to sane defaults:
+	 * - if the chip is in manual pwm mode, this will be overwritten with
+	 *   the actual settings on the chip (so in this case, initialization
+	 *   is not needed)
+	 * - if in automatic or on/off mode, we could switch to manual mode,
+	 *   read the registers and set manual_pwm_ctl accordingly, but currently
+	 *   this is not implemented, so we initialize to something sane */
+	for (i = 0; i < 3; i++) {
+		data->manual_pwm_ctl[i] = 0xff;
+	}
+
+	/* Check if temperature channnels are reset manually or by some reason */
+	tmp = it87_read_value(client, IT87_REG_TEMP_ENABLE);
+	if ((tmp & 0x3f) == 0) {
+		/* Temp1,Temp3=thermistor; Temp2=thermal diode */
+		tmp = (tmp & 0xc0) | 0x2a;
+		it87_write_value(client, IT87_REG_TEMP_ENABLE, tmp);
+	}
+	data->sensor = tmp;
+
+	/* Check if voltage monitors are reset manually or by some reason */
+	tmp = it87_read_value(client, IT87_REG_VIN_ENABLE);
+	if ((tmp & 0xff) == 0) {
+		/* Enable all voltage monitors */
+		it87_write_value(client, IT87_REG_VIN_ENABLE, 0xff);
+	}
+
+	/* Check if tachometers are reset manually or by some reason */
+	data->fan_main_ctrl = it87_read_value(client, IT87_REG_FAN_MAIN_CTRL);
+	if ((data->fan_main_ctrl & 0x70) == 0) {
+		/* Enable all fan tachometers */
+		data->fan_main_ctrl |= 0x70;
+		it87_write_value(client, IT87_REG_FAN_MAIN_CTRL, data->fan_main_ctrl);
+	}
+
+	/* Set current fan mode registers and the default settings for the
+	 * other mode registers */
+	for (i = 0; i < 3; i++) {
+		if (data->fan_main_ctrl & (1 << i)) {
+			/* pwm mode */
+			tmp = it87_read_value(client, IT87_REG_PWM(i));
+			if (tmp & 0x80) {
+				/* automatic pwm - not yet implemented, but
+				 * leave the settings made by the BIOS alone
+				 * until a change is requested via the sysfs
+				 * interface */
+			} else {
+				/* manual pwm */
+				data->manual_pwm_ctl[i] = PWM_FROM_REG(tmp);
+			}
+		}
+ 	}
+
+	/* Start monitoring */
+	it87_write_value(client, IT87_REG_CONFIG,
+			 (it87_read_value(client, IT87_REG_CONFIG) & 0x36)
+			 | (update_vbat ? 0x41 : 0x01));
+}
+
+static struct it87_data *it87_update_device(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct it87_data *data = i2c_get_clientdata(client);
+	int i;
+
+	down(&data->update_lock);
+
+	if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
+	    || !data->valid) {
+
+		if (update_vbat) {
+			/* Cleared after each update, so reenable.  Value
+		 	  returned by this read will be previous value */	
+			it87_write_value(client, IT87_REG_CONFIG,
+			   it87_read_value(client, IT87_REG_CONFIG) | 0x40);
+		}
+		for (i = 0; i <= 7; i++) {
+			data->in[i] =
+			    it87_read_value(client, IT87_REG_VIN(i));
+			data->in_min[i] =
+			    it87_read_value(client, IT87_REG_VIN_MIN(i));
+			data->in_max[i] =
+			    it87_read_value(client, IT87_REG_VIN_MAX(i));
+		}
+		data->in[8] =
+		    it87_read_value(client, IT87_REG_VIN(8));
+		/* Temperature sensor doesn't have limit registers, set
+		   to min and max value */
+		data->in_min[8] = 0;
+		data->in_max[8] = 255;
+
+		for (i = 0; i < 3; i++) {
+			data->fan[i] =
+			    it87_read_value(client, IT87_REG_FAN(i));
+			data->fan_min[i] =
+			    it87_read_value(client, IT87_REG_FAN_MIN(i));
+		}
+		for (i = 0; i < 3; i++) {
+			data->temp[i] =
+			    it87_read_value(client, IT87_REG_TEMP(i));
+			data->temp_high[i] =
+			    it87_read_value(client, IT87_REG_TEMP_HIGH(i));
+			data->temp_low[i] =
+			    it87_read_value(client, IT87_REG_TEMP_LOW(i));
+		}
+
+		i = it87_read_value(client, IT87_REG_FAN_DIV);
+		data->fan_div[0] = i & 0x07;
+		data->fan_div[1] = (i >> 3) & 0x07;
+		data->fan_div[2] = (i & 0x40) ? 3 : 1;
+
+		data->alarms =
+			it87_read_value(client, IT87_REG_ALARM1) |
+			(it87_read_value(client, IT87_REG_ALARM2) << 8) |
+			(it87_read_value(client, IT87_REG_ALARM3) << 16);
+		data->fan_main_ctrl = it87_read_value(client, IT87_REG_FAN_MAIN_CTRL);
+
+		data->sensor = it87_read_value(client, IT87_REG_TEMP_ENABLE);
+		/* The 8705 does not have VID capability */
+		if (data->type == it8712) {
+			data->vid = it87_read_value(client, IT87_REG_VID);
+			data->vid &= 0x1f;
+		}
+		data->last_updated = jiffies;
+		data->valid = 1;
+	}
+
+	up(&data->update_lock);
+
+	return data;
+}
+
+static int __init sm_it87_init(void)
+{
+	int addr;
+
+	if (!it87_find(&addr)) {
+		normal_isa[0] = addr;
+	}
+	return i2c_add_driver(&it87_driver);
+}
+
+static void __exit sm_it87_exit(void)
+{
+	i2c_del_driver(&it87_driver);
+}
+
+
+MODULE_AUTHOR("Chris Gauthron <chrisg@0-in.com>");
+MODULE_DESCRIPTION("IT8705F, IT8712F, Sis950 driver");
+module_param(update_vbat, bool, 0);
+MODULE_PARM_DESC(update_vbat, "Update vbat if set else return powerup value");
+module_param(fix_pwm_polarity, bool, 0);
+MODULE_PARM_DESC(fix_pwm_polarity, "Force PWM polarity to active high (DANGEROUS)");
+MODULE_LICENSE("GPL");
+
+module_init(sm_it87_init);
+module_exit(sm_it87_exit);
diff --git a/drivers/hwmon/lm63.c b/drivers/hwmon/lm63.c
new file mode 100644
--- /dev/null
+++ b/drivers/hwmon/lm63.c
@@ -0,0 +1,597 @@
+/*
+ * lm63.c - driver for the National Semiconductor LM63 temperature sensor
+ *          with integrated fan control
+ * Copyright (C) 2004-2005  Jean Delvare <khali@linux-fr.org>
+ * Based on the lm90 driver.
+ *
+ * The LM63 is a sensor chip made by National Semiconductor. It measures
+ * two temperatures (its own and one external one) and the speed of one
+ * fan, those speed it can additionally control. Complete datasheet can be
+ * obtained from National's website at:
+ *   http://www.national.com/pf/LM/LM63.html
+ *
+ * The LM63 is basically an LM86 with fan speed monitoring and control
+ * capabilities added. It misses some of the LM86 features though:
+ *  - No low limit for local temperature.
+ *  - No critical limit for local temperature.
+ *  - Critical limit for remote temperature can be changed only once. We
+ *    will consider that the critical limit is read-only.
+ *
+ * The datasheet isn't very clear about what the tachometer reading is.
+ * I had a explanation from National Semiconductor though. The two lower
+ * bits of the read value have to be masked out. The value is still 16 bit
+ * in width.
+ *
+ * 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 <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+#include <linux/i2c.h>
+#include <linux/i2c-sensor.h>
+#include <linux/hwmon-sysfs.h>
+
+/*
+ * Addresses to scan
+ * Address is fully defined internally and cannot be changed.
+ */
+
+static unsigned short normal_i2c[] = { 0x4c, I2C_CLIENT_END };
+static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
+
+/*
+ * Insmod parameters
+ */
+
+SENSORS_INSMOD_1(lm63);
+
+/*
+ * The LM63 registers
+ */
+
+#define LM63_REG_CONFIG1		0x03
+#define LM63_REG_CONFIG2		0xBF
+#define LM63_REG_CONFIG_FAN		0x4A
+
+#define LM63_REG_TACH_COUNT_MSB		0x47
+#define LM63_REG_TACH_COUNT_LSB		0x46
+#define LM63_REG_TACH_LIMIT_MSB		0x49
+#define LM63_REG_TACH_LIMIT_LSB		0x48
+
+#define LM63_REG_PWM_VALUE		0x4C
+#define LM63_REG_PWM_FREQ		0x4D
+
+#define LM63_REG_LOCAL_TEMP		0x00
+#define LM63_REG_LOCAL_HIGH		0x05
+
+#define LM63_REG_REMOTE_TEMP_MSB	0x01
+#define LM63_REG_REMOTE_TEMP_LSB	0x10
+#define LM63_REG_REMOTE_OFFSET_MSB	0x11
+#define LM63_REG_REMOTE_OFFSET_LSB	0x12
+#define LM63_REG_REMOTE_HIGH_MSB	0x07
+#define LM63_REG_REMOTE_HIGH_LSB	0x13
+#define LM63_REG_REMOTE_LOW_MSB		0x08
+#define LM63_REG_REMOTE_LOW_LSB		0x14
+#define LM63_REG_REMOTE_TCRIT		0x19
+#define LM63_REG_REMOTE_TCRIT_HYST	0x21
+
+#define LM63_REG_ALERT_STATUS		0x02
+#define LM63_REG_ALERT_MASK		0x16
+
+#define LM63_REG_MAN_ID			0xFE
+#define LM63_REG_CHIP_ID		0xFF
+
+/*
+ * Conversions and various macros
+ * For tachometer counts, the LM63 uses 16-bit values.
+ * For local temperature and high limit, remote critical limit and hysteresis
+ * value, it uses signed 8-bit values with LSB = 1 degree Celsius.
+ * For remote temperature, low and high limits, it uses signed 11-bit values
+ * with LSB = 0.125 degree Celsius, left-justified in 16-bit registers.
+ */
+
+#define FAN_FROM_REG(reg)	((reg) == 0xFFFC || (reg) == 0 ? 0 : \
+				 5400000 / (reg))
+#define FAN_TO_REG(val)		((val) <= 82 ? 0xFFFC : \
+				 (5400000 / (val)) & 0xFFFC)
+#define TEMP8_FROM_REG(reg)	((reg) * 1000)
+#define TEMP8_TO_REG(val)	((val) <= -128000 ? -128 : \
+				 (val) >= 127000 ? 127 : \
+				 (val) < 0 ? ((val) - 500) / 1000 : \
+				 ((val) + 500) / 1000)
+#define TEMP11_FROM_REG(reg)	((reg) / 32 * 125)
+#define TEMP11_TO_REG(val)	((val) <= -128000 ? 0x8000 : \
+				 (val) >= 127875 ? 0x7FE0 : \
+				 (val) < 0 ? ((val) - 62) / 125 * 32 : \
+				 ((val) + 62) / 125 * 32)
+#define HYST_TO_REG(val)	((val) <= 0 ? 0 : \
+				 (val) >= 127000 ? 127 : \
+				 ((val) + 500) / 1000)
+
+/*
+ * Functions declaration
+ */
+
+static int lm63_attach_adapter(struct i2c_adapter *adapter);
+static int lm63_detach_client(struct i2c_client *client);
+
+static struct lm63_data *lm63_update_device(struct device *dev);
+
+static int lm63_detect(struct i2c_adapter *adapter, int address, int kind);
+static void lm63_init_client(struct i2c_client *client);
+
+/*
+ * Driver data (common to all clients)
+ */
+
+static struct i2c_driver lm63_driver = {
+	.owner		= THIS_MODULE,
+	.name		= "lm63",
+	.flags		= I2C_DF_NOTIFY,
+	.attach_adapter	= lm63_attach_adapter,
+	.detach_client	= lm63_detach_client,
+};
+
+/*
+ * Client data (each client gets its own)
+ */
+
+struct lm63_data {
+	struct i2c_client client;
+	struct semaphore update_lock;
+	char valid; /* zero until following fields are valid */
+	unsigned long last_updated; /* in jiffies */
+
+	/* registers values */
+	u8 config, config_fan;
+	u16 fan[2];	/* 0: input
+			   1: low limit */
+	u8 pwm1_freq;
+	u8 pwm1_value;
+	s8 temp8[3];	/* 0: local input
+			   1: local high limit
+			   2: remote critical limit */
+	s16 temp11[3];	/* 0: remote input
+			   1: remote low limit
+			   2: remote high limit */
+	u8 temp2_crit_hyst;
+	u8 alarms;
+};
+
+/*
+ * Sysfs callback functions and files
+ */
+
+static ssize_t show_fan(struct device *dev, struct device_attribute *devattr,
+			char *buf)
+{
+	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+	struct lm63_data *data = lm63_update_device(dev);
+	return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[attr->index]));
+}
+
+static ssize_t set_fan(struct device *dev, struct device_attribute *dummy,
+		       const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm63_data *data = i2c_get_clientdata(client);
+	unsigned long val = simple_strtoul(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->fan[1] = FAN_TO_REG(val);
+	i2c_smbus_write_byte_data(client, LM63_REG_TACH_LIMIT_LSB,
+				  data->fan[1] & 0xFF);
+	i2c_smbus_write_byte_data(client, LM63_REG_TACH_LIMIT_MSB,
+				  data->fan[1] >> 8);
+	up(&data->update_lock);
+	return count;
+}
+
+static ssize_t show_pwm1(struct device *dev, struct device_attribute *dummy,
+			 char *buf)
+{
+	struct lm63_data *data = lm63_update_device(dev);
+	return sprintf(buf, "%d\n", data->pwm1_value >= 2 * data->pwm1_freq ?
+		       255 : (data->pwm1_value * 255 + data->pwm1_freq) /
+		       (2 * data->pwm1_freq));
+}
+
+static ssize_t set_pwm1(struct device *dev, struct device_attribute *dummy,
+			const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm63_data *data = i2c_get_clientdata(client);
+	unsigned long val;
+	
+	if (!(data->config_fan & 0x20)) /* register is read-only */
+		return -EPERM;
+
+	val = simple_strtoul(buf, NULL, 10);
+	down(&data->update_lock);
+	data->pwm1_value = val <= 0 ? 0 :
+			   val >= 255 ? 2 * data->pwm1_freq :
+			   (val * data->pwm1_freq * 2 + 127) / 255;
+	i2c_smbus_write_byte_data(client, LM63_REG_PWM_VALUE, data->pwm1_value);
+	up(&data->update_lock);
+	return count;
+}
+
+static ssize_t show_pwm1_enable(struct device *dev, struct device_attribute *dummy,
+				char *buf)
+{
+	struct lm63_data *data = lm63_update_device(dev);
+	return sprintf(buf, "%d\n", data->config_fan & 0x20 ? 1 : 2);
+}
+
+static ssize_t show_temp8(struct device *dev, struct device_attribute *devattr,
+			  char *buf)
+{
+	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+	struct lm63_data *data = lm63_update_device(dev);
+	return sprintf(buf, "%d\n", TEMP8_FROM_REG(data->temp8[attr->index]));
+}
+
+static ssize_t set_temp8(struct device *dev, struct device_attribute *dummy,
+			 const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm63_data *data = i2c_get_clientdata(client);
+	long val = simple_strtol(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->temp8[1] = TEMP8_TO_REG(val);
+	i2c_smbus_write_byte_data(client, LM63_REG_LOCAL_HIGH, data->temp8[1]);
+	up(&data->update_lock);
+	return count;
+}
+
+static ssize_t show_temp11(struct device *dev, struct device_attribute *devattr,
+			   char *buf)
+{
+	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+	struct lm63_data *data = lm63_update_device(dev);
+	return sprintf(buf, "%d\n", TEMP11_FROM_REG(data->temp11[attr->index]));
+}
+
+static ssize_t set_temp11(struct device *dev, struct device_attribute *devattr,
+			  const char *buf, size_t count)
+{
+	static const u8 reg[4] = {
+		LM63_REG_REMOTE_LOW_MSB,
+		LM63_REG_REMOTE_LOW_LSB,
+		LM63_REG_REMOTE_HIGH_MSB,
+		LM63_REG_REMOTE_HIGH_LSB,
+	};
+
+	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm63_data *data = i2c_get_clientdata(client);
+	long val = simple_strtol(buf, NULL, 10);
+	int nr = attr->index;
+
+	down(&data->update_lock);
+	data->temp11[nr] = TEMP11_TO_REG(val);
+	i2c_smbus_write_byte_data(client, reg[(nr - 1) * 2],
+				  data->temp11[nr] >> 8);
+	i2c_smbus_write_byte_data(client, reg[(nr - 1) * 2 + 1],
+				  data->temp11[nr] & 0xff);
+	up(&data->update_lock);
+	return count;
+}
+
+/* Hysteresis register holds a relative value, while we want to present
+   an absolute to user-space */
+static ssize_t show_temp2_crit_hyst(struct device *dev, struct device_attribute *dummy,
+				    char *buf)
+{
+	struct lm63_data *data = lm63_update_device(dev);
+	return sprintf(buf, "%d\n", TEMP8_FROM_REG(data->temp8[2])
+		       - TEMP8_FROM_REG(data->temp2_crit_hyst));
+}
+
+/* And now the other way around, user-space provides an absolute
+   hysteresis value and we have to store a relative one */
+static ssize_t set_temp2_crit_hyst(struct device *dev, struct device_attribute *dummy,
+				   const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm63_data *data = i2c_get_clientdata(client);
+	long val = simple_strtol(buf, NULL, 10);
+	long hyst;
+
+	down(&data->update_lock);
+	hyst = TEMP8_FROM_REG(data->temp8[2]) - val;
+	i2c_smbus_write_byte_data(client, LM63_REG_REMOTE_TCRIT_HYST,
+				  HYST_TO_REG(hyst));
+	up(&data->update_lock);
+	return count;
+}
+
+static ssize_t show_alarms(struct device *dev, struct device_attribute *dummy,
+			   char *buf)
+{
+	struct lm63_data *data = lm63_update_device(dev);
+	return sprintf(buf, "%u\n", data->alarms);
+}
+
+static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0);
+static SENSOR_DEVICE_ATTR(fan1_min, S_IWUSR | S_IRUGO, show_fan,
+	set_fan, 1);
+
+static DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm1, set_pwm1);
+static DEVICE_ATTR(pwm1_enable, S_IRUGO, show_pwm1_enable, NULL);
+
+static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp8, NULL, 0);
+static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp8,
+	set_temp8, 1);
+
+static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp11, NULL, 0);
+static SENSOR_DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_temp11,
+	set_temp11, 1);
+static SENSOR_DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_temp11,
+	set_temp11, 2);
+static SENSOR_DEVICE_ATTR(temp2_crit, S_IRUGO, show_temp8, NULL, 2);
+static DEVICE_ATTR(temp2_crit_hyst, S_IWUSR | S_IRUGO, show_temp2_crit_hyst,
+	set_temp2_crit_hyst);
+
+static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
+
+/*
+ * Real code
+ */
+
+static int lm63_attach_adapter(struct i2c_adapter *adapter)
+{
+	if (!(adapter->class & I2C_CLASS_HWMON))
+		return 0;
+	return i2c_detect(adapter, &addr_data, lm63_detect);
+}
+
+/*
+ * The following function does more than just detection. If detection
+ * succeeds, it also registers the new chip.
+ */
+static int lm63_detect(struct i2c_adapter *adapter, int address, int kind)
+{
+	struct i2c_client *new_client;
+	struct lm63_data *data;
+	int err = 0;
+
+	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+		goto exit;
+
+	if (!(data = kmalloc(sizeof(struct lm63_data), GFP_KERNEL))) {
+		err = -ENOMEM;
+		goto exit;
+	}
+	memset(data, 0, sizeof(struct lm63_data));
+
+	/* The common I2C client data is placed right before the
+	   LM63-specific data. */
+	new_client = &data->client;
+	i2c_set_clientdata(new_client, data);
+	new_client->addr = address;
+	new_client->adapter = adapter;
+	new_client->driver = &lm63_driver;
+	new_client->flags = 0;
+
+	/* Default to an LM63 if forced */
+	if (kind == 0)
+		kind = lm63;
+
+	if (kind < 0) { /* must identify */
+		u8 man_id, chip_id, reg_config1, reg_config2;
+		u8 reg_alert_status, reg_alert_mask;
+
+		man_id = i2c_smbus_read_byte_data(new_client,
+			 LM63_REG_MAN_ID);
+		chip_id = i2c_smbus_read_byte_data(new_client,
+			  LM63_REG_CHIP_ID);
+		reg_config1 = i2c_smbus_read_byte_data(new_client,
+			      LM63_REG_CONFIG1);
+		reg_config2 = i2c_smbus_read_byte_data(new_client,
+			      LM63_REG_CONFIG2);
+		reg_alert_status = i2c_smbus_read_byte_data(new_client,
+				   LM63_REG_ALERT_STATUS);
+		reg_alert_mask = i2c_smbus_read_byte_data(new_client,
+				 LM63_REG_ALERT_MASK);
+
+		if (man_id == 0x01 /* National Semiconductor */
+		 && chip_id == 0x41 /* LM63 */
+		 && (reg_config1 & 0x18) == 0x00
+		 && (reg_config2 & 0xF8) == 0x00
+		 && (reg_alert_status & 0x20) == 0x00
+		 && (reg_alert_mask & 0xA4) == 0xA4) {
+			kind = lm63;
+		} else { /* failed */
+			dev_dbg(&adapter->dev, "Unsupported chip "
+				"(man_id=0x%02X, chip_id=0x%02X).\n",
+				man_id, chip_id);
+			goto exit_free;
+		}
+	}
+
+	strlcpy(new_client->name, "lm63", I2C_NAME_SIZE);
+	data->valid = 0;
+	init_MUTEX(&data->update_lock);
+
+	/* Tell the I2C layer a new client has arrived */
+	if ((err = i2c_attach_client(new_client)))
+		goto exit_free;
+
+	/* Initialize the LM63 chip */
+	lm63_init_client(new_client);
+
+	/* Register sysfs hooks */
+	if (data->config & 0x04) { /* tachometer enabled */
+		device_create_file(&new_client->dev,
+				   &sensor_dev_attr_fan1_input.dev_attr);
+		device_create_file(&new_client->dev,
+				   &sensor_dev_attr_fan1_min.dev_attr);
+	}
+	device_create_file(&new_client->dev, &dev_attr_pwm1);
+	device_create_file(&new_client->dev, &dev_attr_pwm1_enable);
+	device_create_file(&new_client->dev,
+			   &sensor_dev_attr_temp1_input.dev_attr);
+	device_create_file(&new_client->dev,
+			   &sensor_dev_attr_temp2_input.dev_attr);
+	device_create_file(&new_client->dev,
+			   &sensor_dev_attr_temp2_min.dev_attr);
+	device_create_file(&new_client->dev,
+			   &sensor_dev_attr_temp1_max.dev_attr);
+	device_create_file(&new_client->dev,
+			   &sensor_dev_attr_temp2_max.dev_attr);
+	device_create_file(&new_client->dev,
+			   &sensor_dev_attr_temp2_crit.dev_attr);
+	device_create_file(&new_client->dev, &dev_attr_temp2_crit_hyst);
+	device_create_file(&new_client->dev, &dev_attr_alarms);
+
+	return 0;
+
+exit_free:
+	kfree(data);
+exit:
+	return err;
+}
+
+/* Idealy we shouldn't have to initialize anything, since the BIOS
+   should have taken care of everything */
+static void lm63_init_client(struct i2c_client *client)
+{
+	struct lm63_data *data = i2c_get_clientdata(client);
+
+	data->config = i2c_smbus_read_byte_data(client, LM63_REG_CONFIG1);
+	data->config_fan = i2c_smbus_read_byte_data(client,
+						    LM63_REG_CONFIG_FAN);
+
+	/* Start converting if needed */
+	if (data->config & 0x40) { /* standby */
+		dev_dbg(&client->dev, "Switching to operational mode");
+		data->config &= 0xA7;
+		i2c_smbus_write_byte_data(client, LM63_REG_CONFIG1,
+					  data->config);
+	}
+
+	/* We may need pwm1_freq before ever updating the client data */
+	data->pwm1_freq = i2c_smbus_read_byte_data(client, LM63_REG_PWM_FREQ);
+	if (data->pwm1_freq == 0)
+		data->pwm1_freq = 1;
+
+	/* Show some debug info about the LM63 configuration */
+	dev_dbg(&client->dev, "Alert/tach pin configured for %s\n",
+		(data->config & 0x04) ? "tachometer input" :
+		"alert output");
+	dev_dbg(&client->dev, "PWM clock %s kHz, output frequency %u Hz\n",
+		(data->config_fan & 0x08) ? "1.4" : "360",
+		((data->config_fan & 0x08) ? 700 : 180000) / data->pwm1_freq);
+	dev_dbg(&client->dev, "PWM output active %s, %s mode\n",
+		(data->config_fan & 0x10) ? "low" : "high",
+		(data->config_fan & 0x20) ? "manual" : "auto");
+}
+
+static int lm63_detach_client(struct i2c_client *client)
+{
+	int err;
+
+	if ((err = i2c_detach_client(client))) {
+		dev_err(&client->dev, "Client deregistration failed, "
+			"client not detached\n");
+		return err;
+	}
+
+	kfree(i2c_get_clientdata(client));
+	return 0;
+}
+
+static struct lm63_data *lm63_update_device(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm63_data *data = i2c_get_clientdata(client);
+
+	down(&data->update_lock);
+
+	if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
+		if (data->config & 0x04) { /* tachometer enabled  */
+			/* order matters for fan1_input */
+			data->fan[0] = i2c_smbus_read_byte_data(client,
+				       LM63_REG_TACH_COUNT_LSB) & 0xFC;
+			data->fan[0] |= i2c_smbus_read_byte_data(client,
+					LM63_REG_TACH_COUNT_MSB) << 8;
+			data->fan[1] = (i2c_smbus_read_byte_data(client,
+					LM63_REG_TACH_LIMIT_LSB) & 0xFC)
+				     | (i2c_smbus_read_byte_data(client,
+					LM63_REG_TACH_LIMIT_MSB) << 8);
+		}
+
+		data->pwm1_freq = i2c_smbus_read_byte_data(client,
+				  LM63_REG_PWM_FREQ);
+		if (data->pwm1_freq == 0)
+			data->pwm1_freq = 1;
+		data->pwm1_value = i2c_smbus_read_byte_data(client,
+				   LM63_REG_PWM_VALUE);
+
+		data->temp8[0] = i2c_smbus_read_byte_data(client,
+				 LM63_REG_LOCAL_TEMP);
+		data->temp8[1] = i2c_smbus_read_byte_data(client,
+				 LM63_REG_LOCAL_HIGH);
+
+		/* order matters for temp2_input */
+		data->temp11[0] = i2c_smbus_read_byte_data(client,
+				  LM63_REG_REMOTE_TEMP_MSB) << 8;
+		data->temp11[0] |= i2c_smbus_read_byte_data(client,
+				   LM63_REG_REMOTE_TEMP_LSB);
+		data->temp11[1] = (i2c_smbus_read_byte_data(client,
+				  LM63_REG_REMOTE_LOW_MSB) << 8)
+				| i2c_smbus_read_byte_data(client,
+				  LM63_REG_REMOTE_LOW_LSB);
+		data->temp11[2] = (i2c_smbus_read_byte_data(client,
+				  LM63_REG_REMOTE_HIGH_MSB) << 8)
+				| i2c_smbus_read_byte_data(client,
+				  LM63_REG_REMOTE_HIGH_LSB);
+		data->temp8[2] = i2c_smbus_read_byte_data(client,
+				 LM63_REG_REMOTE_TCRIT);
+		data->temp2_crit_hyst = i2c_smbus_read_byte_data(client,
+					LM63_REG_REMOTE_TCRIT_HYST);
+
+		data->alarms = i2c_smbus_read_byte_data(client,
+			       LM63_REG_ALERT_STATUS) & 0x7F;
+
+		data->last_updated = jiffies;
+		data->valid = 1;
+	}
+
+	up(&data->update_lock);
+
+	return data;
+}
+
+static int __init sensors_lm63_init(void)
+{
+	return i2c_add_driver(&lm63_driver);
+}
+
+static void __exit sensors_lm63_exit(void)
+{
+	i2c_del_driver(&lm63_driver);
+}
+
+MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>");
+MODULE_DESCRIPTION("LM63 driver");
+MODULE_LICENSE("GPL");
+
+module_init(sensors_lm63_init);
+module_exit(sensors_lm63_exit);
diff --git a/drivers/hwmon/lm75.c b/drivers/hwmon/lm75.c
new file mode 100644
--- /dev/null
+++ b/drivers/hwmon/lm75.c
@@ -0,0 +1,296 @@
+/*
+    lm75.c - Part of lm_sensors, Linux kernel modules for hardware
+             monitoring
+    Copyright (c) 1998, 1999  Frodo Looijaard <frodol@dds.nl>
+
+    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 <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+#include <linux/i2c.h>
+#include <linux/i2c-sensor.h>
+#include "lm75.h"
+
+
+/* Addresses to scan */
+static unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, 0x4c,
+					0x4d, 0x4e, 0x4f, I2C_CLIENT_END };
+static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
+
+/* Insmod parameters */
+SENSORS_INSMOD_1(lm75);
+
+/* Many LM75 constants specified below */
+
+/* The LM75 registers */
+#define LM75_REG_TEMP		0x00
+#define LM75_REG_CONF		0x01
+#define LM75_REG_TEMP_HYST	0x02
+#define LM75_REG_TEMP_OS	0x03
+
+/* Each client has this additional data */
+struct lm75_data {
+	struct i2c_client	client;
+	struct semaphore	update_lock;
+	char			valid;		/* !=0 if following fields are valid */
+	unsigned long		last_updated;	/* In jiffies */
+	u16			temp_input;	/* Register values */
+	u16			temp_max;
+	u16			temp_hyst;
+};
+
+static int lm75_attach_adapter(struct i2c_adapter *adapter);
+static int lm75_detect(struct i2c_adapter *adapter, int address, int kind);
+static void lm75_init_client(struct i2c_client *client);
+static int lm75_detach_client(struct i2c_client *client);
+static int lm75_read_value(struct i2c_client *client, u8 reg);
+static int lm75_write_value(struct i2c_client *client, u8 reg, u16 value);
+static struct lm75_data *lm75_update_device(struct device *dev);
+
+
+/* This is the driver that will be inserted */
+static struct i2c_driver lm75_driver = {
+	.owner		= THIS_MODULE,
+	.name		= "lm75",
+	.id		= I2C_DRIVERID_LM75,
+	.flags		= I2C_DF_NOTIFY,
+	.attach_adapter	= lm75_attach_adapter,
+	.detach_client	= lm75_detach_client,
+};
+
+#define show(value)	\
+static ssize_t show_##value(struct device *dev, struct device_attribute *attr, char *buf)		\
+{									\
+	struct lm75_data *data = lm75_update_device(dev);		\
+	return sprintf(buf, "%d\n", LM75_TEMP_FROM_REG(data->value));	\
+}
+show(temp_max);
+show(temp_hyst);
+show(temp_input);
+
+#define set(value, reg)	\
+static ssize_t set_##value(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)	\
+{								\
+	struct i2c_client *client = to_i2c_client(dev);		\
+	struct lm75_data *data = i2c_get_clientdata(client);	\
+	int temp = simple_strtoul(buf, NULL, 10);		\
+								\
+	down(&data->update_lock);				\
+	data->value = LM75_TEMP_TO_REG(temp);			\
+	lm75_write_value(client, reg, data->value);		\
+	up(&data->update_lock);					\
+	return count;						\
+}
+set(temp_max, LM75_REG_TEMP_OS);
+set(temp_hyst, LM75_REG_TEMP_HYST);
+
+static DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp_max, set_temp_max);
+static DEVICE_ATTR(temp1_max_hyst, S_IWUSR | S_IRUGO, show_temp_hyst, set_temp_hyst);
+static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp_input, NULL);
+
+static int lm75_attach_adapter(struct i2c_adapter *adapter)
+{
+	if (!(adapter->class & I2C_CLASS_HWMON))
+		return 0;
+	return i2c_detect(adapter, &addr_data, lm75_detect);
+}
+
+/* This function is called by i2c_detect */
+static int lm75_detect(struct i2c_adapter *adapter, int address, int kind)
+{
+	int i;
+	struct i2c_client *new_client;
+	struct lm75_data *data;
+	int err = 0;
+	const char *name = "";
+
+	/* Make sure we aren't probing the ISA bus!! This is just a safety check
+	   at this moment; i2c_detect really won't call us. */
+#ifdef DEBUG
+	if (i2c_is_isa_adapter(adapter)) {
+		dev_dbg(&adapter->dev,
+			"lm75_detect called for an ISA bus adapter?!?\n");
+		goto exit;
+	}
+#endif
+
+	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
+				     I2C_FUNC_SMBUS_WORD_DATA))
+		goto exit;
+
+	/* OK. For now, we presume we have a valid client. We now create the
+	   client structure, even though we cannot fill it completely yet.
+	   But it allows us to access lm75_{read,write}_value. */
+	if (!(data = kmalloc(sizeof(struct lm75_data), GFP_KERNEL))) {
+		err = -ENOMEM;
+		goto exit;
+	}
+	memset(data, 0, sizeof(struct lm75_data));
+
+	new_client = &data->client;
+	i2c_set_clientdata(new_client, data);
+	new_client->addr = address;
+	new_client->adapter = adapter;
+	new_client->driver = &lm75_driver;
+	new_client->flags = 0;
+
+	/* Now, we do the remaining detection. There is no identification-
+	   dedicated register so we have to rely on several tricks:
+	   unused bits, registers cycling over 8-address boundaries,
+	   addresses 0x04-0x07 returning the last read value.
+	   The cycling+unused addresses combination is not tested,
+	   since it would significantly slow the detection down and would
+	   hardly add any value. */
+	if (kind < 0) {
+		int cur, conf, hyst, os;
+
+		/* Unused addresses */
+		cur = i2c_smbus_read_word_data(new_client, 0);
+		conf = i2c_smbus_read_byte_data(new_client, 1);
+		hyst = i2c_smbus_read_word_data(new_client, 2);
+		if (i2c_smbus_read_word_data(new_client, 4) != hyst
+		 || i2c_smbus_read_word_data(new_client, 5) != hyst
+		 || i2c_smbus_read_word_data(new_client, 6) != hyst
+		 || i2c_smbus_read_word_data(new_client, 7) != hyst)
+		 	goto exit_free;
+		os = i2c_smbus_read_word_data(new_client, 3);
+		if (i2c_smbus_read_word_data(new_client, 4) != os
+		 || i2c_smbus_read_word_data(new_client, 5) != os
+		 || i2c_smbus_read_word_data(new_client, 6) != os
+		 || i2c_smbus_read_word_data(new_client, 7) != os)
+		 	goto exit_free;
+
+		/* Unused bits */
+		if (conf & 0xe0)
+		 	goto exit_free;
+
+		/* Addresses cycling */
+		for (i = 8; i < 0xff; i += 8)
+			if (i2c_smbus_read_byte_data(new_client, i + 1) != conf
+			 || i2c_smbus_read_word_data(new_client, i + 2) != hyst
+			 || i2c_smbus_read_word_data(new_client, i + 3) != os)
+				goto exit_free;
+	}
+
+	/* Determine the chip type - only one kind supported! */
+	if (kind <= 0)
+		kind = lm75;
+
+	if (kind == lm75) {
+		name = "lm75";
+	}
+
+	/* Fill in the remaining client fields and put it into the global list */
+	strlcpy(new_client->name, name, I2C_NAME_SIZE);
+	data->valid = 0;
+	init_MUTEX(&data->update_lock);
+
+	/* Tell the I2C layer a new client has arrived */
+	if ((err = i2c_attach_client(new_client)))
+		goto exit_free;
+
+	/* Initialize the LM75 chip */
+	lm75_init_client(new_client);
+	
+	/* Register sysfs hooks */
+	device_create_file(&new_client->dev, &dev_attr_temp1_max);
+	device_create_file(&new_client->dev, &dev_attr_temp1_max_hyst);
+	device_create_file(&new_client->dev, &dev_attr_temp1_input);
+
+	return 0;
+
+exit_free:
+	kfree(data);
+exit:
+	return err;
+}
+
+static int lm75_detach_client(struct i2c_client *client)
+{
+	i2c_detach_client(client);
+	kfree(i2c_get_clientdata(client));
+	return 0;
+}
+
+/* All registers are word-sized, except for the configuration register.
+   LM75 uses a high-byte first convention, which is exactly opposite to
+   the usual practice. */
+static int lm75_read_value(struct i2c_client *client, u8 reg)
+{
+	if (reg == LM75_REG_CONF)
+		return i2c_smbus_read_byte_data(client, reg);
+	else
+		return swab16(i2c_smbus_read_word_data(client, reg));
+}
+
+/* All registers are word-sized, except for the configuration register.
+   LM75 uses a high-byte first convention, which is exactly opposite to
+   the usual practice. */
+static int lm75_write_value(struct i2c_client *client, u8 reg, u16 value)
+{
+	if (reg == LM75_REG_CONF)
+		return i2c_smbus_write_byte_data(client, reg, value);
+	else
+		return i2c_smbus_write_word_data(client, reg, swab16(value));
+}
+
+static void lm75_init_client(struct i2c_client *client)
+{
+	/* Initialize the LM75 chip */
+	lm75_write_value(client, LM75_REG_CONF, 0);
+}
+
+static struct lm75_data *lm75_update_device(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm75_data *data = i2c_get_clientdata(client);
+
+	down(&data->update_lock);
+
+	if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
+	    || !data->valid) {
+		dev_dbg(&client->dev, "Starting lm75 update\n");
+
+		data->temp_input = lm75_read_value(client, LM75_REG_TEMP);
+		data->temp_max = lm75_read_value(client, LM75_REG_TEMP_OS);
+		data->temp_hyst = lm75_read_value(client, LM75_REG_TEMP_HYST);
+		data->last_updated = jiffies;
+		data->valid = 1;
+	}
+
+	up(&data->update_lock);
+
+	return data;
+}
+
+static int __init sensors_lm75_init(void)
+{
+	return i2c_add_driver(&lm75_driver);
+}
+
+static void __exit sensors_lm75_exit(void)
+{
+	i2c_del_driver(&lm75_driver);
+}
+
+MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>");
+MODULE_DESCRIPTION("LM75 driver");
+MODULE_LICENSE("GPL");
+
+module_init(sensors_lm75_init);
+module_exit(sensors_lm75_exit);
diff --git a/drivers/hwmon/lm75.h b/drivers/hwmon/lm75.h
new file mode 100644
--- /dev/null
+++ b/drivers/hwmon/lm75.h
@@ -0,0 +1,49 @@
+/*
+    lm75.h - Part of lm_sensors, Linux kernel modules for hardware
+             monitoring
+    Copyright (c) 2003 Mark M. Hoffman <mhoffman@lightlink.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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/*
+    This file contains common code for encoding/decoding LM75 type
+    temperature readings, which are emulated by many of the chips
+    we support.  As the user is unlikely to load more than one driver
+    which contains this code, we don't worry about the wasted space.
+*/
+
+#include <linux/i2c-sensor.h>
+
+/* straight from the datasheet */
+#define LM75_TEMP_MIN (-55000)
+#define LM75_TEMP_MAX 125000
+
+/* TEMP: 0.001C/bit (-55C to +125C)
+   REG: (0.5C/bit, two's complement) << 7 */
+static inline u16 LM75_TEMP_TO_REG(int temp)
+{
+	int ntemp = SENSORS_LIMIT(temp, LM75_TEMP_MIN, LM75_TEMP_MAX);
+	ntemp += (ntemp<0 ? -250 : 250);
+	return (u16)((ntemp / 500) << 7);
+}
+
+static inline int LM75_TEMP_FROM_REG(u16 reg)
+{
+	/* use integer division instead of equivalent right shift to
+	   guarantee arithmetic shift and preserve the sign */
+	return ((s16)reg / 128) * 500;
+}
+
diff --git a/drivers/hwmon/lm77.c b/drivers/hwmon/lm77.c
new file mode 100644
--- /dev/null
+++ b/drivers/hwmon/lm77.c
@@ -0,0 +1,420 @@
+/*
+    lm77.c - Part of lm_sensors, Linux kernel modules for hardware
+             monitoring
+
+    Copyright (c) 2004  Andras BALI <drewie@freemail.hu>
+
+    Heavily based on lm75.c by Frodo Looijaard <frodol@dds.nl>.  The LM77
+    is a temperature sensor and thermal window comparator with 0.5 deg
+    resolution made by National Semiconductor.  Complete datasheet can be
+    obtained at their site:
+       http://www.national.com/pf/LM/LM77.html
+
+    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 <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+#include <linux/i2c.h>
+#include <linux/i2c-sensor.h>
+
+
+/* Addresses to scan */
+static unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, I2C_CLIENT_END };
+static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
+
+/* Insmod parameters */
+SENSORS_INSMOD_1(lm77);
+
+/* The LM77 registers */
+#define LM77_REG_TEMP		0x00
+#define LM77_REG_CONF		0x01
+#define LM77_REG_TEMP_HYST	0x02
+#define LM77_REG_TEMP_CRIT	0x03
+#define LM77_REG_TEMP_MIN	0x04
+#define LM77_REG_TEMP_MAX	0x05
+
+/* Each client has this additional data */
+struct lm77_data {
+	struct i2c_client	client;
+	struct semaphore	update_lock;
+	char			valid;
+	unsigned long		last_updated;	/* In jiffies */
+	int			temp_input;	/* Temperatures */
+	int			temp_crit;
+	int			temp_min;
+	int			temp_max;
+	int			temp_hyst;
+	u8			alarms;
+};
+
+static int lm77_attach_adapter(struct i2c_adapter *adapter);
+static int lm77_detect(struct i2c_adapter *adapter, int address, int kind);
+static void lm77_init_client(struct i2c_client *client);
+static int lm77_detach_client(struct i2c_client *client);
+static u16 lm77_read_value(struct i2c_client *client, u8 reg);
+static int lm77_write_value(struct i2c_client *client, u8 reg, u16 value);
+
+static struct lm77_data *lm77_update_device(struct device *dev);
+
+
+/* This is the driver that will be inserted */
+static struct i2c_driver lm77_driver = {
+	.owner		= THIS_MODULE,
+	.name		= "lm77",
+	.flags		= I2C_DF_NOTIFY,
+	.attach_adapter = lm77_attach_adapter,
+	.detach_client	= lm77_detach_client,
+};
+
+/* straight from the datasheet */
+#define LM77_TEMP_MIN (-55000)
+#define LM77_TEMP_MAX 125000
+
+/* In the temperature registers, the low 3 bits are not part of the
+   temperature values; they are the status bits. */
+static inline u16 LM77_TEMP_TO_REG(int temp)
+{
+	int ntemp = SENSORS_LIMIT(temp, LM77_TEMP_MIN, LM77_TEMP_MAX);
+	return (u16)((ntemp / 500) * 8);
+}
+
+static inline int LM77_TEMP_FROM_REG(u16 reg)
+{
+	return ((int)reg / 8) * 500;
+}
+
+/* sysfs stuff */
+
+/* read routines for temperature limits */
+#define show(value)	\
+static ssize_t show_##value(struct device *dev, struct device_attribute *attr, char *buf)	\
+{								\
+	struct lm77_data *data = lm77_update_device(dev);	\
+	return sprintf(buf, "%d\n", data->value);		\
+}
+
+show(temp_input);
+show(temp_crit);
+show(temp_min);
+show(temp_max);
+show(alarms);
+
+/* read routines for hysteresis values */
+static ssize_t show_temp_crit_hyst(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct lm77_data *data = lm77_update_device(dev);
+	return sprintf(buf, "%d\n", data->temp_crit - data->temp_hyst);
+}
+static ssize_t show_temp_min_hyst(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct lm77_data *data = lm77_update_device(dev);
+	return sprintf(buf, "%d\n", data->temp_min + data->temp_hyst);
+}
+static ssize_t show_temp_max_hyst(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct lm77_data *data = lm77_update_device(dev);
+	return sprintf(buf, "%d\n", data->temp_max - data->temp_hyst);
+}
+
+/* write routines */
+#define set(value, reg)	\
+static ssize_t set_##value(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)	\
+{										\
+	struct i2c_client *client = to_i2c_client(dev);				\
+	struct lm77_data *data = i2c_get_clientdata(client);			\
+	long val = simple_strtoul(buf, NULL, 10);				\
+										\
+	down(&data->update_lock);						\
+	data->value = val;				\
+	lm77_write_value(client, reg, LM77_TEMP_TO_REG(data->value));		\
+	up(&data->update_lock);							\
+	return count;								\
+}
+
+set(temp_min, LM77_REG_TEMP_MIN);
+set(temp_max, LM77_REG_TEMP_MAX);
+
+/* hysteresis is stored as a relative value on the chip, so it has to be
+   converted first */
+static ssize_t set_temp_crit_hyst(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm77_data *data = i2c_get_clientdata(client);
+	unsigned long val = simple_strtoul(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->temp_hyst = data->temp_crit - val;
+	lm77_write_value(client, LM77_REG_TEMP_HYST,
+			 LM77_TEMP_TO_REG(data->temp_hyst));
+	up(&data->update_lock);
+	return count;
+}
+
+/* preserve hysteresis when setting T_crit */
+static ssize_t set_temp_crit(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm77_data *data = i2c_get_clientdata(client);
+	long val = simple_strtoul(buf, NULL, 10);
+	int oldcrithyst;
+	
+	down(&data->update_lock);
+	oldcrithyst = data->temp_crit - data->temp_hyst;
+	data->temp_crit = val;
+	data->temp_hyst = data->temp_crit - oldcrithyst;
+	lm77_write_value(client, LM77_REG_TEMP_CRIT,
+			 LM77_TEMP_TO_REG(data->temp_crit));
+	lm77_write_value(client, LM77_REG_TEMP_HYST,
+			 LM77_TEMP_TO_REG(data->temp_hyst));
+	up(&data->update_lock);
+	return count;
+}
+
+static DEVICE_ATTR(temp1_input, S_IRUGO,
+		   show_temp_input, NULL);
+static DEVICE_ATTR(temp1_crit, S_IWUSR | S_IRUGO,
+		   show_temp_crit, set_temp_crit);
+static DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO,
+		   show_temp_min, set_temp_min);
+static DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO,
+		   show_temp_max, set_temp_max);
+
+static DEVICE_ATTR(temp1_crit_hyst, S_IWUSR | S_IRUGO,
+		   show_temp_crit_hyst, set_temp_crit_hyst);
+static DEVICE_ATTR(temp1_min_hyst, S_IRUGO,
+		   show_temp_min_hyst, NULL);
+static DEVICE_ATTR(temp1_max_hyst, S_IRUGO,
+		   show_temp_max_hyst, NULL);
+
+static DEVICE_ATTR(alarms, S_IRUGO,
+		   show_alarms, NULL);
+
+static int lm77_attach_adapter(struct i2c_adapter *adapter)
+{
+	if (!(adapter->class & I2C_CLASS_HWMON))
+		return 0;
+	return i2c_detect(adapter, &addr_data, lm77_detect);
+}
+
+/* This function is called by i2c_detect */
+static int lm77_detect(struct i2c_adapter *adapter, int address, int kind)
+{
+	struct i2c_client *new_client;
+	struct lm77_data *data;
+	int err = 0;
+	const char *name = "";
+
+	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
+				     I2C_FUNC_SMBUS_WORD_DATA))
+		goto exit;
+
+	/* OK. For now, we presume we have a valid client. We now create the
+	   client structure, even though we cannot fill it completely yet.
+	   But it allows us to access lm77_{read,write}_value. */
+	if (!(data = kmalloc(sizeof(struct lm77_data), GFP_KERNEL))) {
+		err = -ENOMEM;
+		goto exit;
+	}
+	memset(data, 0, sizeof(struct lm77_data));
+
+	new_client = &data->client;
+	i2c_set_clientdata(new_client, data);
+	new_client->addr = address;
+	new_client->adapter = adapter;
+	new_client->driver = &lm77_driver;
+	new_client->flags = 0;
+
+	/* Here comes the remaining detection.  Since the LM77 has no
+	   register dedicated to identification, we have to rely on the
+	   following tricks:
+
+	   1. the high 4 bits represent the sign and thus they should
+	      always be the same
+	   2. the high 3 bits are unused in the configuration register
+	   3. addresses 0x06 and 0x07 return the last read value
+	   4. registers cycling over 8-address boundaries
+
+	   Word-sized registers are high-byte first. */
+	if (kind < 0) {
+		int i, cur, conf, hyst, crit, min, max;
+
+		/* addresses cycling */
+		cur = i2c_smbus_read_word_data(new_client, 0);
+		conf = i2c_smbus_read_byte_data(new_client, 1);
+		hyst = i2c_smbus_read_word_data(new_client, 2);
+		crit = i2c_smbus_read_word_data(new_client, 3);
+		min = i2c_smbus_read_word_data(new_client, 4);
+		max = i2c_smbus_read_word_data(new_client, 5);
+		for (i = 8; i <= 0xff; i += 8)
+			if (i2c_smbus_read_byte_data(new_client, i + 1) != conf
+			    || i2c_smbus_read_word_data(new_client, i + 2) != hyst
+			    || i2c_smbus_read_word_data(new_client, i + 3) != crit
+			    || i2c_smbus_read_word_data(new_client, i + 4) != min
+			    || i2c_smbus_read_word_data(new_client, i + 5) != max)
+				goto exit_free;
+
+		/* sign bits */
+		if (((cur & 0x00f0) != 0xf0 && (cur & 0x00f0) != 0x0)
+		    || ((hyst & 0x00f0) != 0xf0 && (hyst & 0x00f0) != 0x0)
+		    || ((crit & 0x00f0) != 0xf0 && (crit & 0x00f0) != 0x0)
+		    || ((min & 0x00f0) != 0xf0 && (min & 0x00f0) != 0x0)
+		    || ((max & 0x00f0) != 0xf0 && (max & 0x00f0) != 0x0))
+			goto exit_free;
+
+		/* unused bits */
+		if (conf & 0xe0)
+			goto exit_free;
+
+		/* 0x06 and 0x07 return the last read value */
+		cur = i2c_smbus_read_word_data(new_client, 0);
+		if (i2c_smbus_read_word_data(new_client, 6) != cur
+		    || i2c_smbus_read_word_data(new_client, 7) != cur)
+			goto exit_free;
+		hyst = i2c_smbus_read_word_data(new_client, 2);
+		if (i2c_smbus_read_word_data(new_client, 6) != hyst
+		    || i2c_smbus_read_word_data(new_client, 7) != hyst)
+			goto exit_free;
+		min = i2c_smbus_read_word_data(new_client, 4);
+		if (i2c_smbus_read_word_data(new_client, 6) != min
+		    || i2c_smbus_read_word_data(new_client, 7) != min)
+			goto exit_free;
+
+	}
+
+	/* Determine the chip type - only one kind supported! */
+	if (kind <= 0)
+		kind = lm77;
+
+	if (kind == lm77) {
+		name = "lm77";
+	}
+
+	/* Fill in the remaining client fields and put it into the global list */
+	strlcpy(new_client->name, name, I2C_NAME_SIZE);
+	data->valid = 0;
+	init_MUTEX(&data->update_lock);
+
+	/* Tell the I2C layer a new client has arrived */
+	if ((err = i2c_attach_client(new_client)))
+		goto exit_free;
+
+	/* Initialize the LM77 chip */
+	lm77_init_client(new_client);
+
+	/* Register sysfs hooks */
+	device_create_file(&new_client->dev, &dev_attr_temp1_input);
+	device_create_file(&new_client->dev, &dev_attr_temp1_crit);
+	device_create_file(&new_client->dev, &dev_attr_temp1_min);
+	device_create_file(&new_client->dev, &dev_attr_temp1_max);
+	device_create_file(&new_client->dev, &dev_attr_temp1_crit_hyst);
+	device_create_file(&new_client->dev, &dev_attr_temp1_min_hyst);
+	device_create_file(&new_client->dev, &dev_attr_temp1_max_hyst);
+	device_create_file(&new_client->dev, &dev_attr_alarms);
+	return 0;
+
+exit_free:
+	kfree(data);
+exit:
+	return err;
+}
+
+static int lm77_detach_client(struct i2c_client *client)
+{
+	i2c_detach_client(client);
+	kfree(i2c_get_clientdata(client));
+	return 0;
+}
+
+/* All registers are word-sized, except for the configuration register.
+   The LM77 uses the high-byte first convention. */
+static u16 lm77_read_value(struct i2c_client *client, u8 reg)
+{
+	if (reg == LM77_REG_CONF)
+		return i2c_smbus_read_byte_data(client, reg);
+	else
+		return swab16(i2c_smbus_read_word_data(client, reg));
+}
+
+static int lm77_write_value(struct i2c_client *client, u8 reg, u16 value)
+{
+	if (reg == LM77_REG_CONF)
+		return i2c_smbus_write_byte_data(client, reg, value);
+	else
+		return i2c_smbus_write_word_data(client, reg, swab16(value));
+}
+
+static void lm77_init_client(struct i2c_client *client)
+{
+	/* Initialize the LM77 chip - turn off shutdown mode */
+	int conf = lm77_read_value(client, LM77_REG_CONF);
+	if (conf & 1)
+		lm77_write_value(client, LM77_REG_CONF, conf & 0xfe);
+}
+
+static struct lm77_data *lm77_update_device(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm77_data *data = i2c_get_clientdata(client);
+
+	down(&data->update_lock);
+
+	if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
+	    || !data->valid) {
+		dev_dbg(&client->dev, "Starting lm77 update\n");
+		data->temp_input =
+			LM77_TEMP_FROM_REG(lm77_read_value(client,
+							   LM77_REG_TEMP));
+		data->temp_hyst =
+			LM77_TEMP_FROM_REG(lm77_read_value(client,
+							   LM77_REG_TEMP_HYST));
+		data->temp_crit =
+			LM77_TEMP_FROM_REG(lm77_read_value(client,
+							   LM77_REG_TEMP_CRIT));
+		data->temp_min =
+			LM77_TEMP_FROM_REG(lm77_read_value(client,
+							   LM77_REG_TEMP_MIN));
+		data->temp_max =
+			LM77_TEMP_FROM_REG(lm77_read_value(client,
+							   LM77_REG_TEMP_MAX));
+		data->alarms =
+			lm77_read_value(client, LM77_REG_TEMP) & 0x0007;
+		data->last_updated = jiffies;
+		data->valid = 1;
+	}
+
+	up(&data->update_lock);
+
+	return data;
+}
+
+static int __init sensors_lm77_init(void)
+{
+	return i2c_add_driver(&lm77_driver);
+}
+
+static void __exit sensors_lm77_exit(void)
+{
+	i2c_del_driver(&lm77_driver);
+}
+
+MODULE_AUTHOR("Andras BALI <drewie@freemail.hu>");
+MODULE_DESCRIPTION("LM77 driver");
+MODULE_LICENSE("GPL");
+
+module_init(sensors_lm77_init);
+module_exit(sensors_lm77_exit);
diff --git a/drivers/hwmon/lm78.c b/drivers/hwmon/lm78.c
new file mode 100644
--- /dev/null
+++ b/drivers/hwmon/lm78.c
@@ -0,0 +1,795 @@
+/*
+    lm78.c - Part of lm_sensors, Linux kernel modules for hardware
+             monitoring
+    Copyright (c) 1998, 1999  Frodo Looijaard <frodol@dds.nl> 
+
+    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 <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+#include <linux/i2c.h>
+#include <linux/i2c-sensor.h>
+#include <asm/io.h>
+
+/* Addresses to scan */
+static unsigned short normal_i2c[] = { 0x20, 0x21, 0x22, 0x23, 0x24,
+					0x25, 0x26, 0x27, 0x28, 0x29,
+					0x2a, 0x2b, 0x2c, 0x2d, 0x2e,
+					0x2f, I2C_CLIENT_END };
+static unsigned int normal_isa[] = { 0x0290, I2C_CLIENT_ISA_END };
+
+/* Insmod parameters */
+SENSORS_INSMOD_3(lm78, lm78j, lm79);
+
+/* Many LM78 constants specified below */
+
+/* Length of ISA address segment */
+#define LM78_EXTENT 8
+
+/* Where are the ISA address/data registers relative to the base address */
+#define LM78_ADDR_REG_OFFSET 5
+#define LM78_DATA_REG_OFFSET 6
+
+/* The LM78 registers */
+#define LM78_REG_IN_MAX(nr) (0x2b + (nr) * 2)
+#define LM78_REG_IN_MIN(nr) (0x2c + (nr) * 2)
+#define LM78_REG_IN(nr) (0x20 + (nr))
+
+#define LM78_REG_FAN_MIN(nr) (0x3b + (nr))
+#define LM78_REG_FAN(nr) (0x28 + (nr))
+
+#define LM78_REG_TEMP 0x27
+#define LM78_REG_TEMP_OVER 0x39
+#define LM78_REG_TEMP_HYST 0x3a
+
+#define LM78_REG_ALARM1 0x41
+#define LM78_REG_ALARM2 0x42
+
+#define LM78_REG_VID_FANDIV 0x47
+
+#define LM78_REG_CONFIG 0x40
+#define LM78_REG_CHIPID 0x49
+#define LM78_REG_I2C_ADDR 0x48
+
+
+/* Conversions. Rounding and limit checking is only done on the TO_REG 
+   variants. */
+
+/* IN: mV, (0V to 4.08V)
+   REG: 16mV/bit */
+static inline u8 IN_TO_REG(unsigned long val)
+{
+	unsigned long nval = SENSORS_LIMIT(val, 0, 4080);
+	return (nval + 8) / 16;
+}
+#define IN_FROM_REG(val) ((val) *  16)
+
+static inline u8 FAN_TO_REG(long rpm, int div)
+{
+	if (rpm <= 0)
+		return 255;
+	return SENSORS_LIMIT((1350000 + rpm * div / 2) / (rpm * div), 1, 254);
+}
+
+static inline int FAN_FROM_REG(u8 val, int div)
+{
+	return val==0 ? -1 : val==255 ? 0 : 1350000/(val*div);
+}
+
+/* TEMP: mC (-128C to +127C)
+   REG: 1C/bit, two's complement */
+static inline s8 TEMP_TO_REG(int val)
+{
+	int nval = SENSORS_LIMIT(val, -128000, 127000) ;
+	return nval<0 ? (nval-500)/1000 : (nval+500)/1000;
+}
+
+static inline int TEMP_FROM_REG(s8 val)
+{
+	return val * 1000;
+}
+
+/* VID: mV
+   REG: (see doc/vid) */
+static inline int VID_FROM_REG(u8 val)
+{
+	return val==0x1f ? 0 : val>=0x10 ? 5100-val*100 : 2050-val*50;
+}
+
+#define DIV_FROM_REG(val) (1 << (val))
+
+/* There are some complications in a module like this. First off, LM78 chips
+   may be both present on the SMBus and the ISA bus, and we have to handle
+   those cases separately at some places. Second, there might be several
+   LM78 chips available (well, actually, that is probably never done; but
+   it is a clean illustration of how to handle a case like that). Finally,
+   a specific chip may be attached to *both* ISA and SMBus, and we would
+   not like to detect it double. Fortunately, in the case of the LM78 at
+   least, a register tells us what SMBus address we are on, so that helps
+   a bit - except if there could be more than one SMBus. Groan. No solution
+   for this yet. */
+
+/* This module may seem overly long and complicated. In fact, it is not so
+   bad. Quite a lot of bookkeeping is done. A real driver can often cut
+   some corners. */
+
+/* For each registered LM78, we need to keep some data in memory. That
+   data is pointed to by lm78_list[NR]->data. The structure itself is
+   dynamically allocated, at the same time when a new lm78 client is
+   allocated. */
+struct lm78_data {
+	struct i2c_client client;
+	struct semaphore lock;
+	enum chips type;
+
+	struct semaphore update_lock;
+	char valid;		/* !=0 if following fields are valid */
+	unsigned long last_updated;	/* In jiffies */
+
+	u8 in[7];		/* Register value */
+	u8 in_max[7];		/* Register value */
+	u8 in_min[7];		/* Register value */
+	u8 fan[3];		/* Register value */
+	u8 fan_min[3];		/* Register value */
+	s8 temp;		/* Register value */
+	s8 temp_over;		/* Register value */
+	s8 temp_hyst;		/* Register value */
+	u8 fan_div[3];		/* Register encoding, shifted right */
+	u8 vid;			/* Register encoding, combined */
+	u16 alarms;		/* Register encoding, combined */
+};
+
+
+static int lm78_attach_adapter(struct i2c_adapter *adapter);
+static int lm78_detect(struct i2c_adapter *adapter, int address, int kind);
+static int lm78_detach_client(struct i2c_client *client);
+
+static int lm78_read_value(struct i2c_client *client, u8 register);
+static int lm78_write_value(struct i2c_client *client, u8 register, u8 value);
+static struct lm78_data *lm78_update_device(struct device *dev);
+static void lm78_init_client(struct i2c_client *client);
+
+
+static struct i2c_driver lm78_driver = {
+	.owner		= THIS_MODULE,
+	.name		= "lm78",
+	.id		= I2C_DRIVERID_LM78,
+	.flags		= I2C_DF_NOTIFY,
+	.attach_adapter	= lm78_attach_adapter,
+	.detach_client	= lm78_detach_client,
+};
+
+/* 7 Voltages */
+static ssize_t show_in(struct device *dev, char *buf, int nr)
+{
+	struct lm78_data *data = lm78_update_device(dev);
+	return sprintf(buf, "%d\n", IN_FROM_REG(data->in[nr]));
+}
+
+static ssize_t show_in_min(struct device *dev, char *buf, int nr)
+{
+	struct lm78_data *data = lm78_update_device(dev);
+	return sprintf(buf, "%d\n", IN_FROM_REG(data->in_min[nr]));
+}
+
+static ssize_t show_in_max(struct device *dev, char *buf, int nr)
+{
+	struct lm78_data *data = lm78_update_device(dev);
+	return sprintf(buf, "%d\n", IN_FROM_REG(data->in_max[nr]));
+}
+
+static ssize_t set_in_min(struct device *dev, const char *buf,
+		size_t count, int nr)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm78_data *data = i2c_get_clientdata(client);
+	unsigned long val = simple_strtoul(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->in_min[nr] = IN_TO_REG(val);
+	lm78_write_value(client, LM78_REG_IN_MIN(nr), data->in_min[nr]);
+	up(&data->update_lock);
+	return count;
+}
+
+static ssize_t set_in_max(struct device *dev, const char *buf,
+		size_t count, int nr)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm78_data *data = i2c_get_clientdata(client);
+	unsigned long val = simple_strtoul(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->in_max[nr] = IN_TO_REG(val);
+	lm78_write_value(client, LM78_REG_IN_MAX(nr), data->in_max[nr]);
+	up(&data->update_lock);
+	return count;
+}
+	
+#define show_in_offset(offset)					\
+static ssize_t							\
+	show_in##offset (struct device *dev, struct device_attribute *attr, char *buf)		\
+{								\
+	return show_in(dev, buf, offset);			\
+}								\
+static DEVICE_ATTR(in##offset##_input, S_IRUGO, 		\
+		show_in##offset, NULL);				\
+static ssize_t							\
+	show_in##offset##_min (struct device *dev, struct device_attribute *attr, char *buf)   \
+{								\
+	return show_in_min(dev, buf, offset);			\
+}								\
+static ssize_t							\
+	show_in##offset##_max (struct device *dev, struct device_attribute *attr, char *buf)   \
+{								\
+	return show_in_max(dev, buf, offset);			\
+}								\
+static ssize_t set_in##offset##_min (struct device *dev, struct device_attribute *attr,	\
+		const char *buf, size_t count)			\
+{								\
+	return set_in_min(dev, buf, count, offset);		\
+}								\
+static ssize_t set_in##offset##_max (struct device *dev, struct device_attribute *attr,	\
+		const char *buf, size_t count)			\
+{								\
+	return set_in_max(dev, buf, count, offset);		\
+}								\
+static DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR,		\
+		show_in##offset##_min, set_in##offset##_min);	\
+static DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR,		\
+		show_in##offset##_max, set_in##offset##_max);
+
+show_in_offset(0);
+show_in_offset(1);
+show_in_offset(2);
+show_in_offset(3);
+show_in_offset(4);
+show_in_offset(5);
+show_in_offset(6);
+
+/* Temperature */
+static ssize_t show_temp(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct lm78_data *data = lm78_update_device(dev);
+	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp));
+}
+
+static ssize_t show_temp_over(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct lm78_data *data = lm78_update_device(dev);
+	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_over));
+}
+
+static ssize_t set_temp_over(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm78_data *data = i2c_get_clientdata(client);
+	long val = simple_strtol(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->temp_over = TEMP_TO_REG(val);
+	lm78_write_value(client, LM78_REG_TEMP_OVER, data->temp_over);
+	up(&data->update_lock);
+	return count;
+}
+
+static ssize_t show_temp_hyst(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct lm78_data *data = lm78_update_device(dev);
+	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_hyst));
+}
+
+static ssize_t set_temp_hyst(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm78_data *data = i2c_get_clientdata(client);
+	long val = simple_strtol(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->temp_hyst = TEMP_TO_REG(val);
+	lm78_write_value(client, LM78_REG_TEMP_HYST, data->temp_hyst);
+	up(&data->update_lock);
+	return count;
+}
+
+static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL);
+static DEVICE_ATTR(temp1_max, S_IRUGO | S_IWUSR,
+		show_temp_over, set_temp_over);
+static DEVICE_ATTR(temp1_max_hyst, S_IRUGO | S_IWUSR,
+		show_temp_hyst, set_temp_hyst);
+
+/* 3 Fans */
+static ssize_t show_fan(struct device *dev, char *buf, int nr)
+{
+	struct lm78_data *data = lm78_update_device(dev);
+	return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[nr],
+		DIV_FROM_REG(data->fan_div[nr])) );
+}
+
+static ssize_t show_fan_min(struct device *dev, char *buf, int nr)
+{
+	struct lm78_data *data = lm78_update_device(dev);
+	return sprintf(buf,"%d\n", FAN_FROM_REG(data->fan_min[nr],
+		DIV_FROM_REG(data->fan_div[nr])) );
+}
+
+static ssize_t set_fan_min(struct device *dev, const char *buf,
+		size_t count, int nr)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm78_data *data = i2c_get_clientdata(client);
+	unsigned long val = simple_strtoul(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr]));
+	lm78_write_value(client, LM78_REG_FAN_MIN(nr), data->fan_min[nr]);
+	up(&data->update_lock);
+	return count;
+}
+
+static ssize_t show_fan_div(struct device *dev, char *buf, int nr)
+{
+	struct lm78_data *data = lm78_update_device(dev);
+	return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[nr]) );
+}
+
+/* Note: we save and restore the fan minimum here, because its value is
+   determined in part by the fan divisor.  This follows the principle of
+   least suprise; the user doesn't expect the fan minimum to change just
+   because the divisor changed. */
+static ssize_t set_fan_div(struct device *dev, const char *buf,
+	size_t count, int nr)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm78_data *data = i2c_get_clientdata(client);
+	unsigned long val = simple_strtoul(buf, NULL, 10);
+	unsigned long min;
+	u8 reg;
+
+	down(&data->update_lock);
+	min = FAN_FROM_REG(data->fan_min[nr],
+			   DIV_FROM_REG(data->fan_div[nr]));
+
+	switch (val) {
+	case 1: data->fan_div[nr] = 0; break;
+	case 2: data->fan_div[nr] = 1; break;
+	case 4: data->fan_div[nr] = 2; break;
+	case 8: data->fan_div[nr] = 3; break;
+	default:
+		dev_err(&client->dev, "fan_div value %ld not "
+			"supported. Choose one of 1, 2, 4 or 8!\n", val);
+		up(&data->update_lock);
+		return -EINVAL;
+	}
+
+	reg = lm78_read_value(client, LM78_REG_VID_FANDIV);
+	switch (nr) {
+	case 0:
+		reg = (reg & 0xcf) | (data->fan_div[nr] << 4);
+		break;
+	case 1:
+		reg = (reg & 0x3f) | (data->fan_div[nr] << 6);
+		break;
+	}
+	lm78_write_value(client, LM78_REG_VID_FANDIV, reg);
+
+	data->fan_min[nr] =
+		FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr]));
+	lm78_write_value(client, LM78_REG_FAN_MIN(nr), data->fan_min[nr]);
+	up(&data->update_lock);
+
+	return count;
+}
+
+#define show_fan_offset(offset)						\
+static ssize_t show_fan_##offset (struct device *dev, struct device_attribute *attr, char *buf)	\
+{									\
+	return show_fan(dev, buf, offset - 1);				\
+}									\
+static ssize_t show_fan_##offset##_min (struct device *dev, struct device_attribute *attr, char *buf)  \
+{									\
+	return show_fan_min(dev, buf, offset - 1);			\
+}									\
+static ssize_t show_fan_##offset##_div (struct device *dev, struct device_attribute *attr, char *buf)  \
+{									\
+	return show_fan_div(dev, buf, offset - 1);			\
+}									\
+static ssize_t set_fan_##offset##_min (struct device *dev, struct device_attribute *attr,		\
+		const char *buf, size_t count)				\
+{									\
+	return set_fan_min(dev, buf, count, offset - 1);		\
+}									\
+static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_fan_##offset, NULL);\
+static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR,		\
+		show_fan_##offset##_min, set_fan_##offset##_min);
+
+static ssize_t set_fan_1_div(struct device *dev, struct device_attribute *attr, const char *buf,
+		size_t count)
+{
+	return set_fan_div(dev, buf, count, 0) ;
+}
+
+static ssize_t set_fan_2_div(struct device *dev, struct device_attribute *attr, const char *buf,
+		size_t count)
+{
+	return set_fan_div(dev, buf, count, 1) ;
+}
+
+show_fan_offset(1);
+show_fan_offset(2);
+show_fan_offset(3);
+
+/* Fan 3 divisor is locked in H/W */
+static DEVICE_ATTR(fan1_div, S_IRUGO | S_IWUSR,
+		show_fan_1_div, set_fan_1_div);
+static DEVICE_ATTR(fan2_div, S_IRUGO | S_IWUSR,
+		show_fan_2_div, set_fan_2_div);
+static DEVICE_ATTR(fan3_div, S_IRUGO, show_fan_3_div, NULL);
+
+/* VID */
+static ssize_t show_vid(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct lm78_data *data = lm78_update_device(dev);
+	return sprintf(buf, "%d\n", VID_FROM_REG(data->vid));
+}
+static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL);
+
+/* Alarms */
+static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct lm78_data *data = lm78_update_device(dev);
+	return sprintf(buf, "%u\n", data->alarms);
+}
+static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
+
+/* This function is called when:
+     * lm78_driver is inserted (when this module is loaded), for each
+       available adapter
+     * when a new adapter is inserted (and lm78_driver is still present) */
+static int lm78_attach_adapter(struct i2c_adapter *adapter)
+{
+	if (!(adapter->class & I2C_CLASS_HWMON))
+		return 0;
+	return i2c_detect(adapter, &addr_data, lm78_detect);
+}
+
+/* This function is called by i2c_detect */
+int lm78_detect(struct i2c_adapter *adapter, int address, int kind)
+{
+	int i, err;
+	struct i2c_client *new_client;
+	struct lm78_data *data;
+	const char *client_name = "";
+	int is_isa = i2c_is_isa_adapter(adapter);
+
+	if (!is_isa &&
+	    !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
+		err = -ENODEV;
+		goto ERROR0;
+	}
+
+	/* Reserve the ISA region */
+	if (is_isa)
+		if (!request_region(address, LM78_EXTENT, lm78_driver.name)) {
+			err = -EBUSY;
+			goto ERROR0;
+		}
+
+	/* Probe whether there is anything available on this address. Already
+	   done for SMBus clients */
+	if (kind < 0) {
+		if (is_isa) {
+
+#define REALLY_SLOW_IO
+			/* We need the timeouts for at least some LM78-like
+			   chips. But only if we read 'undefined' registers. */
+			i = inb_p(address + 1);
+			if (inb_p(address + 2) != i) {
+				err = -ENODEV;
+				goto ERROR1;
+			}
+			if (inb_p(address + 3) != i) {
+				err = -ENODEV;
+				goto ERROR1;
+			}
+			if (inb_p(address + 7) != i) {
+				err = -ENODEV;
+				goto ERROR1;
+			}
+#undef REALLY_SLOW_IO
+
+			/* Let's just hope nothing breaks here */
+			i = inb_p(address + 5) & 0x7f;
+			outb_p(~i & 0x7f, address + 5);
+			if ((inb_p(address + 5) & 0x7f) != (~i & 0x7f)) {
+				outb_p(i, address + 5);
+				err = -ENODEV;
+				goto ERROR1;
+			}
+		}
+	}
+
+	/* OK. For now, we presume we have a valid client. We now create the
+	   client structure, even though we cannot fill it completely yet.
+	   But it allows us to access lm78_{read,write}_value. */
+
+	if (!(data = kmalloc(sizeof(struct lm78_data), GFP_KERNEL))) {
+		err = -ENOMEM;
+		goto ERROR1;
+	}
+	memset(data, 0, sizeof(struct lm78_data));
+
+	new_client = &data->client;
+	if (is_isa)
+		init_MUTEX(&data->lock);
+	i2c_set_clientdata(new_client, data);
+	new_client->addr = address;
+	new_client->adapter = adapter;
+	new_client->driver = &lm78_driver;
+	new_client->flags = 0;
+
+	/* Now, we do the remaining detection. */
+	if (kind < 0) {
+		if (lm78_read_value(new_client, LM78_REG_CONFIG) & 0x80) {
+			err = -ENODEV;
+			goto ERROR2;
+		}
+		if (!is_isa && (lm78_read_value(
+				new_client, LM78_REG_I2C_ADDR) != address)) {
+			err = -ENODEV;
+			goto ERROR2;
+		}
+	}
+
+	/* Determine the chip type. */
+	if (kind <= 0) {
+		i = lm78_read_value(new_client, LM78_REG_CHIPID);
+		if (i == 0x00 || i == 0x20)
+			kind = lm78;
+		else if (i == 0x40)
+			kind = lm78j;
+		else if ((i & 0xfe) == 0xc0)
+			kind = lm79;
+		else {
+			if (kind == 0)
+				dev_warn(&adapter->dev, "Ignoring 'force' "
+					"parameter for unknown chip at "
+					"adapter %d, address 0x%02x\n",
+					i2c_adapter_id(adapter), address);
+			err = -ENODEV;
+			goto ERROR2;
+		}
+	}
+
+	if (kind == lm78) {
+		client_name = "lm78";
+	} else if (kind == lm78j) {
+		client_name = "lm78-j";
+	} else if (kind == lm79) {
+		client_name = "lm79";
+	}
+
+	/* Fill in the remaining client fields and put into the global list */
+	strlcpy(new_client->name, client_name, I2C_NAME_SIZE);
+	data->type = kind;
+
+	data->valid = 0;
+	init_MUTEX(&data->update_lock);
+
+	/* Tell the I2C layer a new client has arrived */
+	if ((err = i2c_attach_client(new_client)))
+		goto ERROR2;
+
+	/* Initialize the LM78 chip */
+	lm78_init_client(new_client);
+
+	/* A few vars need to be filled upon startup */
+	for (i = 0; i < 3; i++) {
+		data->fan_min[i] = lm78_read_value(new_client,
+					LM78_REG_FAN_MIN(i));
+	}
+
+	/* Register sysfs hooks */
+	device_create_file(&new_client->dev, &dev_attr_in0_input);
+	device_create_file(&new_client->dev, &dev_attr_in0_min);
+	device_create_file(&new_client->dev, &dev_attr_in0_max);
+	device_create_file(&new_client->dev, &dev_attr_in1_input);
+	device_create_file(&new_client->dev, &dev_attr_in1_min);
+	device_create_file(&new_client->dev, &dev_attr_in1_max);
+	device_create_file(&new_client->dev, &dev_attr_in2_input);
+	device_create_file(&new_client->dev, &dev_attr_in2_min);
+	device_create_file(&new_client->dev, &dev_attr_in2_max);
+	device_create_file(&new_client->dev, &dev_attr_in3_input);
+	device_create_file(&new_client->dev, &dev_attr_in3_min);
+	device_create_file(&new_client->dev, &dev_attr_in3_max);
+	device_create_file(&new_client->dev, &dev_attr_in4_input);
+	device_create_file(&new_client->dev, &dev_attr_in4_min);
+	device_create_file(&new_client->dev, &dev_attr_in4_max);
+	device_create_file(&new_client->dev, &dev_attr_in5_input);
+	device_create_file(&new_client->dev, &dev_attr_in5_min);
+	device_create_file(&new_client->dev, &dev_attr_in5_max);
+	device_create_file(&new_client->dev, &dev_attr_in6_input);
+	device_create_file(&new_client->dev, &dev_attr_in6_min);
+	device_create_file(&new_client->dev, &dev_attr_in6_max);
+	device_create_file(&new_client->dev, &dev_attr_temp1_input);
+	device_create_file(&new_client->dev, &dev_attr_temp1_max);
+	device_create_file(&new_client->dev, &dev_attr_temp1_max_hyst);
+	device_create_file(&new_client->dev, &dev_attr_fan1_input);
+	device_create_file(&new_client->dev, &dev_attr_fan1_min);
+	device_create_file(&new_client->dev, &dev_attr_fan1_div);
+	device_create_file(&new_client->dev, &dev_attr_fan2_input);
+	device_create_file(&new_client->dev, &dev_attr_fan2_min);
+	device_create_file(&new_client->dev, &dev_attr_fan2_div);
+	device_create_file(&new_client->dev, &dev_attr_fan3_input);
+	device_create_file(&new_client->dev, &dev_attr_fan3_min);
+	device_create_file(&new_client->dev, &dev_attr_fan3_div);
+	device_create_file(&new_client->dev, &dev_attr_alarms);
+	device_create_file(&new_client->dev, &dev_attr_cpu0_vid);
+
+	return 0;
+
+ERROR2:
+	kfree(data);
+ERROR1:
+	if (is_isa)
+		release_region(address, LM78_EXTENT);
+ERROR0:
+	return err;
+}
+
+static int lm78_detach_client(struct i2c_client *client)
+{
+	int err;
+
+	if ((err = i2c_detach_client(client))) {
+		dev_err(&client->dev,
+		    "Client deregistration failed, client not detached.\n");
+		return err;
+	}
+
+	if(i2c_is_isa_client(client))
+		release_region(client->addr, LM78_EXTENT);
+
+	kfree(i2c_get_clientdata(client));
+
+	return 0;
+}
+
+/* The SMBus locks itself, but ISA access must be locked explicitly! 
+   We don't want to lock the whole ISA bus, so we lock each client
+   separately.
+   We ignore the LM78 BUSY flag at this moment - it could lead to deadlocks,
+   would slow down the LM78 access and should not be necessary.  */
+static int lm78_read_value(struct i2c_client *client, u8 reg)
+{
+	int res;
+	if (i2c_is_isa_client(client)) {
+		struct lm78_data *data = i2c_get_clientdata(client);
+		down(&data->lock);
+		outb_p(reg, client->addr + LM78_ADDR_REG_OFFSET);
+		res = inb_p(client->addr + LM78_DATA_REG_OFFSET);
+		up(&data->lock);
+		return res;
+	} else
+		return i2c_smbus_read_byte_data(client, reg);
+}
+
+/* The SMBus locks itself, but ISA access muse be locked explicitly! 
+   We don't want to lock the whole ISA bus, so we lock each client
+   separately.
+   We ignore the LM78 BUSY flag at this moment - it could lead to deadlocks,
+   would slow down the LM78 access and should not be necessary. 
+   There are some ugly typecasts here, but the good new is - they should
+   nowhere else be necessary! */
+static int lm78_write_value(struct i2c_client *client, u8 reg, u8 value)
+{
+	if (i2c_is_isa_client(client)) {
+		struct lm78_data *data = i2c_get_clientdata(client);
+		down(&data->lock);
+		outb_p(reg, client->addr + LM78_ADDR_REG_OFFSET);
+		outb_p(value, client->addr + LM78_DATA_REG_OFFSET);
+		up(&data->lock);
+		return 0;
+	} else
+		return i2c_smbus_write_byte_data(client, reg, value);
+}
+
+/* Called when we have found a new LM78. It should set limits, etc. */
+static void lm78_init_client(struct i2c_client *client)
+{
+	u8 config = lm78_read_value(client, LM78_REG_CONFIG);
+
+	/* Start monitoring */
+	if (!(config & 0x01))
+		lm78_write_value(client, LM78_REG_CONFIG,
+				 (config & 0xf7) | 0x01);
+}
+
+static struct lm78_data *lm78_update_device(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm78_data *data = i2c_get_clientdata(client);
+	int i;
+
+	down(&data->update_lock);
+
+	if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
+	    || !data->valid) {
+
+		dev_dbg(&client->dev, "Starting lm78 update\n");
+
+		for (i = 0; i <= 6; i++) {
+			data->in[i] =
+			    lm78_read_value(client, LM78_REG_IN(i));
+			data->in_min[i] =
+			    lm78_read_value(client, LM78_REG_IN_MIN(i));
+			data->in_max[i] =
+			    lm78_read_value(client, LM78_REG_IN_MAX(i));
+		}
+		for (i = 0; i < 3; i++) {
+			data->fan[i] =
+			    lm78_read_value(client, LM78_REG_FAN(i));
+			data->fan_min[i] =
+			    lm78_read_value(client, LM78_REG_FAN_MIN(i));
+		}
+		data->temp = lm78_read_value(client, LM78_REG_TEMP);
+		data->temp_over =
+		    lm78_read_value(client, LM78_REG_TEMP_OVER);
+		data->temp_hyst =
+		    lm78_read_value(client, LM78_REG_TEMP_HYST);
+		i = lm78_read_value(client, LM78_REG_VID_FANDIV);
+		data->vid = i & 0x0f;
+		if (data->type == lm79)
+			data->vid |=
+			    (lm78_read_value(client, LM78_REG_CHIPID) &
+			     0x01) << 4;
+		else
+			data->vid |= 0x10;
+		data->fan_div[0] = (i >> 4) & 0x03;
+		data->fan_div[1] = i >> 6;
+		data->alarms = lm78_read_value(client, LM78_REG_ALARM1) +
+		    (lm78_read_value(client, LM78_REG_ALARM2) << 8);
+		data->last_updated = jiffies;
+		data->valid = 1;
+
+		data->fan_div[2] = 1;
+	}
+
+	up(&data->update_lock);
+
+	return data;
+}
+
+static int __init sm_lm78_init(void)
+{
+	return i2c_add_driver(&lm78_driver);
+}
+
+static void __exit sm_lm78_exit(void)
+{
+	i2c_del_driver(&lm78_driver);
+}
+
+
+
+MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>");
+MODULE_DESCRIPTION("LM78, LM78-J and LM79 driver");
+MODULE_LICENSE("GPL");
+
+module_init(sm_lm78_init);
+module_exit(sm_lm78_exit);
diff --git a/drivers/hwmon/lm80.c b/drivers/hwmon/lm80.c
new file mode 100644
--- /dev/null
+++ b/drivers/hwmon/lm80.c
@@ -0,0 +1,601 @@
+/*
+ * lm80.c - From lm_sensors, Linux kernel modules for hardware
+ * monitoring
+ * Copyright (C) 1998, 1999  Frodo Looijaard <frodol@dds.nl>
+ * and Philip Edelbrock <phil@netroedge.com>
+ *
+ * Ported to Linux 2.6 by Tiago Sousa <mirage@kaotik.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.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+#include <linux/i2c.h>
+#include <linux/i2c-sensor.h>
+
+/* Addresses to scan */
+static unsigned short normal_i2c[] = { 0x28, 0x29, 0x2a, 0x2b, 0x2c,
+					0x2d, 0x2e, 0x2f, I2C_CLIENT_END };
+static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
+
+/* Insmod parameters */
+SENSORS_INSMOD_1(lm80);
+
+/* Many LM80 constants specified below */
+
+/* The LM80 registers */
+#define LM80_REG_IN_MAX(nr)		(0x2a + (nr) * 2)
+#define LM80_REG_IN_MIN(nr)		(0x2b + (nr) * 2)
+#define LM80_REG_IN(nr)			(0x20 + (nr))
+
+#define LM80_REG_FAN1			0x28
+#define LM80_REG_FAN2			0x29
+#define LM80_REG_FAN_MIN(nr)		(0x3b + (nr))
+
+#define LM80_REG_TEMP			0x27
+#define LM80_REG_TEMP_HOT_MAX		0x38
+#define LM80_REG_TEMP_HOT_HYST		0x39
+#define LM80_REG_TEMP_OS_MAX		0x3a
+#define LM80_REG_TEMP_OS_HYST		0x3b
+
+#define LM80_REG_CONFIG			0x00
+#define LM80_REG_ALARM1			0x01
+#define LM80_REG_ALARM2			0x02
+#define LM80_REG_MASK1			0x03
+#define LM80_REG_MASK2			0x04
+#define LM80_REG_FANDIV			0x05
+#define LM80_REG_RES			0x06
+
+
+/* Conversions. Rounding and limit checking is only done on the TO_REG
+   variants. Note that you should be a bit careful with which arguments
+   these macros are called: arguments may be evaluated more than once.
+   Fixing this is just not worth it. */
+
+#define IN_TO_REG(val)		(SENSORS_LIMIT(((val)+5)/10,0,255))
+#define IN_FROM_REG(val)	((val)*10)
+
+static inline unsigned char FAN_TO_REG(unsigned rpm, unsigned div)
+{
+	if (rpm == 0)
+		return 255;
+	rpm = SENSORS_LIMIT(rpm, 1, 1000000);
+	return SENSORS_LIMIT((1350000 + rpm*div / 2) / (rpm*div), 1, 254);
+}
+
+#define FAN_FROM_REG(val,div)	((val)==0?-1:\
+				(val)==255?0:1350000/((div)*(val)))
+
+static inline long TEMP_FROM_REG(u16 temp)
+{
+	long res;
+
+	temp >>= 4;
+	if (temp < 0x0800)
+		res = 625 * (long) temp;
+	else
+		res = ((long) temp - 0x01000) * 625;
+
+	return res / 10;
+}
+
+#define TEMP_LIMIT_FROM_REG(val)	(((val)>0x80?(val)-0x100:(val))*1000)
+
+#define TEMP_LIMIT_TO_REG(val)		SENSORS_LIMIT((val)<0?\
+					((val)-500)/1000:((val)+500)/1000,0,255)
+
+#define DIV_FROM_REG(val)		(1 << (val))
+
+/*
+ * Client data (each client gets its own)
+ */
+
+struct lm80_data {
+	struct i2c_client client;
+	struct semaphore update_lock;
+	char valid;		/* !=0 if following fields are valid */
+	unsigned long last_updated;	/* In jiffies */
+
+	u8 in[7];		/* Register value */
+	u8 in_max[7];		/* Register value */
+	u8 in_min[7];		/* Register value */
+	u8 fan[2];		/* Register value */
+	u8 fan_min[2];		/* Register value */
+	u8 fan_div[2];		/* Register encoding, shifted right */
+	u16 temp;		/* Register values, shifted right */
+	u8 temp_hot_max;	/* Register value */
+	u8 temp_hot_hyst;	/* Register value */
+	u8 temp_os_max;		/* Register value */
+	u8 temp_os_hyst;	/* Register value */
+	u16 alarms;		/* Register encoding, combined */
+};
+
+/* 
+ * Functions declaration
+ */
+
+static int lm80_attach_adapter(struct i2c_adapter *adapter);
+static int lm80_detect(struct i2c_adapter *adapter, int address, int kind);
+static void lm80_init_client(struct i2c_client *client);
+static int lm80_detach_client(struct i2c_client *client);
+static struct lm80_data *lm80_update_device(struct device *dev);
+static int lm80_read_value(struct i2c_client *client, u8 reg);
+static int lm80_write_value(struct i2c_client *client, u8 reg, u8 value);
+
+/*
+ * Driver data (common to all clients)
+ */
+
+static struct i2c_driver lm80_driver = {
+	.owner		= THIS_MODULE,
+	.name		= "lm80",
+	.id		= I2C_DRIVERID_LM80,
+	.flags		= I2C_DF_NOTIFY,
+	.attach_adapter	= lm80_attach_adapter,
+	.detach_client	= lm80_detach_client,
+};
+
+/*
+ * Sysfs stuff
+ */
+
+#define show_in(suffix, value) \
+static ssize_t show_in_##suffix(struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+	struct lm80_data *data = lm80_update_device(dev); \
+	return sprintf(buf, "%d\n", IN_FROM_REG(data->value)); \
+}
+show_in(min0, in_min[0]);
+show_in(min1, in_min[1]);
+show_in(min2, in_min[2]);
+show_in(min3, in_min[3]);
+show_in(min4, in_min[4]);
+show_in(min5, in_min[5]);
+show_in(min6, in_min[6]);
+show_in(max0, in_max[0]);
+show_in(max1, in_max[1]);
+show_in(max2, in_max[2]);
+show_in(max3, in_max[3]);
+show_in(max4, in_max[4]);
+show_in(max5, in_max[5]);
+show_in(max6, in_max[6]);
+show_in(input0, in[0]);
+show_in(input1, in[1]);
+show_in(input2, in[2]);
+show_in(input3, in[3]);
+show_in(input4, in[4]);
+show_in(input5, in[5]);
+show_in(input6, in[6]);
+
+#define set_in(suffix, value, reg) \
+static ssize_t set_in_##suffix(struct device *dev, struct device_attribute *attr, const char *buf, \
+	size_t count) \
+{ \
+	struct i2c_client *client = to_i2c_client(dev); \
+	struct lm80_data *data = i2c_get_clientdata(client); \
+	long val = simple_strtol(buf, NULL, 10); \
+ \
+	down(&data->update_lock);\
+	data->value = IN_TO_REG(val); \
+	lm80_write_value(client, reg, data->value); \
+	up(&data->update_lock);\
+	return count; \
+}
+set_in(min0, in_min[0], LM80_REG_IN_MIN(0));
+set_in(min1, in_min[1], LM80_REG_IN_MIN(1));
+set_in(min2, in_min[2], LM80_REG_IN_MIN(2));
+set_in(min3, in_min[3], LM80_REG_IN_MIN(3));
+set_in(min4, in_min[4], LM80_REG_IN_MIN(4));
+set_in(min5, in_min[5], LM80_REG_IN_MIN(5));
+set_in(min6, in_min[6], LM80_REG_IN_MIN(6));
+set_in(max0, in_max[0], LM80_REG_IN_MAX(0));
+set_in(max1, in_max[1], LM80_REG_IN_MAX(1));
+set_in(max2, in_max[2], LM80_REG_IN_MAX(2));
+set_in(max3, in_max[3], LM80_REG_IN_MAX(3));
+set_in(max4, in_max[4], LM80_REG_IN_MAX(4));
+set_in(max5, in_max[5], LM80_REG_IN_MAX(5));
+set_in(max6, in_max[6], LM80_REG_IN_MAX(6));
+
+#define show_fan(suffix, value, div) \
+static ssize_t show_fan_##suffix(struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+	struct lm80_data *data = lm80_update_device(dev); \
+	return sprintf(buf, "%d\n", FAN_FROM_REG(data->value, \
+		       DIV_FROM_REG(data->div))); \
+}
+show_fan(min1, fan_min[0], fan_div[0]);
+show_fan(min2, fan_min[1], fan_div[1]);
+show_fan(input1, fan[0], fan_div[0]);
+show_fan(input2, fan[1], fan_div[1]);
+
+#define show_fan_div(suffix, value) \
+static ssize_t show_fan_div##suffix(struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+	struct lm80_data *data = lm80_update_device(dev); \
+	return sprintf(buf, "%d\n", DIV_FROM_REG(data->value)); \
+}
+show_fan_div(1, fan_div[0]);
+show_fan_div(2, fan_div[1]);
+
+#define set_fan(suffix, value, reg, div) \
+static ssize_t set_fan_##suffix(struct device *dev, struct device_attribute *attr, const char *buf, \
+	size_t count) \
+{ \
+	struct i2c_client *client = to_i2c_client(dev); \
+	struct lm80_data *data = i2c_get_clientdata(client); \
+	long val = simple_strtoul(buf, NULL, 10); \
+ \
+	down(&data->update_lock);\
+	data->value = FAN_TO_REG(val, DIV_FROM_REG(data->div)); \
+	lm80_write_value(client, reg, data->value); \
+	up(&data->update_lock);\
+	return count; \
+}
+set_fan(min1, fan_min[0], LM80_REG_FAN_MIN(1), fan_div[0]);
+set_fan(min2, fan_min[1], LM80_REG_FAN_MIN(2), fan_div[1]);
+
+/* Note: we save and restore the fan minimum here, because its value is
+   determined in part by the fan divisor.  This follows the principle of
+   least suprise; the user doesn't expect the fan minimum to change just
+   because the divisor changed. */
+static ssize_t set_fan_div(struct device *dev, const char *buf,
+	size_t count, int nr)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm80_data *data = i2c_get_clientdata(client);
+	unsigned long min, val = simple_strtoul(buf, NULL, 10);
+	u8 reg;
+
+	/* Save fan_min */
+	down(&data->update_lock);
+	min = FAN_FROM_REG(data->fan_min[nr],
+			   DIV_FROM_REG(data->fan_div[nr]));
+
+	switch (val) {
+	case 1: data->fan_div[nr] = 0; break;
+	case 2: data->fan_div[nr] = 1; break;
+	case 4: data->fan_div[nr] = 2; break;
+	case 8: data->fan_div[nr] = 3; break;
+	default:
+		dev_err(&client->dev, "fan_div value %ld not "
+			"supported. Choose one of 1, 2, 4 or 8!\n", val);
+		up(&data->update_lock);
+		return -EINVAL;
+	}
+
+	reg = (lm80_read_value(client, LM80_REG_FANDIV) & ~(3 << (2 * (nr + 1))))
+	    | (data->fan_div[nr] << (2 * (nr + 1)));
+	lm80_write_value(client, LM80_REG_FANDIV, reg);
+
+	/* Restore fan_min */
+	data->fan_min[nr] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr]));
+	lm80_write_value(client, LM80_REG_FAN_MIN(nr + 1), data->fan_min[nr]);
+	up(&data->update_lock);
+
+	return count;
+}
+
+#define set_fan_div(number) \
+static ssize_t set_fan_div##number(struct device *dev, struct device_attribute *attr, const char *buf, \
+	size_t count) \
+{ \
+	return set_fan_div(dev, buf, count, number - 1); \
+}
+set_fan_div(1);
+set_fan_div(2);
+
+static ssize_t show_temp_input1(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct lm80_data *data = lm80_update_device(dev);
+	return sprintf(buf, "%ld\n", TEMP_FROM_REG(data->temp));
+}
+
+#define show_temp(suffix, value) \
+static ssize_t show_temp_##suffix(struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+	struct lm80_data *data = lm80_update_device(dev); \
+	return sprintf(buf, "%d\n", TEMP_LIMIT_FROM_REG(data->value)); \
+}
+show_temp(hot_max, temp_hot_max);
+show_temp(hot_hyst, temp_hot_hyst);
+show_temp(os_max, temp_os_max);
+show_temp(os_hyst, temp_os_hyst);
+
+#define set_temp(suffix, value, reg) \
+static ssize_t set_temp_##suffix(struct device *dev, struct device_attribute *attr, const char *buf, \
+	size_t count) \
+{ \
+	struct i2c_client *client = to_i2c_client(dev); \
+	struct lm80_data *data = i2c_get_clientdata(client); \
+	long val = simple_strtoul(buf, NULL, 10); \
+ \
+	down(&data->update_lock); \
+	data->value = TEMP_LIMIT_TO_REG(val); \
+	lm80_write_value(client, reg, data->value); \
+	up(&data->update_lock); \
+	return count; \
+}
+set_temp(hot_max, temp_hot_max, LM80_REG_TEMP_HOT_MAX);
+set_temp(hot_hyst, temp_hot_hyst, LM80_REG_TEMP_HOT_HYST);
+set_temp(os_max, temp_os_max, LM80_REG_TEMP_OS_MAX);
+set_temp(os_hyst, temp_os_hyst, LM80_REG_TEMP_OS_HYST);
+
+static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct lm80_data *data = lm80_update_device(dev);
+	return sprintf(buf, "%u\n", data->alarms);
+}
+
+static DEVICE_ATTR(in0_min, S_IWUSR | S_IRUGO, show_in_min0, set_in_min0);
+static DEVICE_ATTR(in1_min, S_IWUSR | S_IRUGO, show_in_min1, set_in_min1);
+static DEVICE_ATTR(in2_min, S_IWUSR | S_IRUGO, show_in_min2, set_in_min2);
+static DEVICE_ATTR(in3_min, S_IWUSR | S_IRUGO, show_in_min3, set_in_min3);
+static DEVICE_ATTR(in4_min, S_IWUSR | S_IRUGO, show_in_min4, set_in_min4);
+static DEVICE_ATTR(in5_min, S_IWUSR | S_IRUGO, show_in_min5, set_in_min5);
+static DEVICE_ATTR(in6_min, S_IWUSR | S_IRUGO, show_in_min6, set_in_min6);
+static DEVICE_ATTR(in0_max, S_IWUSR | S_IRUGO, show_in_max0, set_in_max0);
+static DEVICE_ATTR(in1_max, S_IWUSR | S_IRUGO, show_in_max1, set_in_max1);
+static DEVICE_ATTR(in2_max, S_IWUSR | S_IRUGO, show_in_max2, set_in_max2);
+static DEVICE_ATTR(in3_max, S_IWUSR | S_IRUGO, show_in_max3, set_in_max3);
+static DEVICE_ATTR(in4_max, S_IWUSR | S_IRUGO, show_in_max4, set_in_max4);
+static DEVICE_ATTR(in5_max, S_IWUSR | S_IRUGO, show_in_max5, set_in_max5);
+static DEVICE_ATTR(in6_max, S_IWUSR | S_IRUGO, show_in_max6, set_in_max6);
+static DEVICE_ATTR(in0_input, S_IRUGO, show_in_input0, NULL);
+static DEVICE_ATTR(in1_input, S_IRUGO, show_in_input1, NULL);
+static DEVICE_ATTR(in2_input, S_IRUGO, show_in_input2, NULL);
+static DEVICE_ATTR(in3_input, S_IRUGO, show_in_input3, NULL);
+static DEVICE_ATTR(in4_input, S_IRUGO, show_in_input4, NULL);
+static DEVICE_ATTR(in5_input, S_IRUGO, show_in_input5, NULL);
+static DEVICE_ATTR(in6_input, S_IRUGO, show_in_input6, NULL);
+static DEVICE_ATTR(fan1_min, S_IWUSR | S_IRUGO, show_fan_min1,
+    set_fan_min1);
+static DEVICE_ATTR(fan2_min, S_IWUSR | S_IRUGO, show_fan_min2,
+    set_fan_min2);
+static DEVICE_ATTR(fan1_input, S_IRUGO, show_fan_input1, NULL);
+static DEVICE_ATTR(fan2_input, S_IRUGO, show_fan_input2, NULL);
+static DEVICE_ATTR(fan1_div, S_IWUSR | S_IRUGO, show_fan_div1, set_fan_div1);
+static DEVICE_ATTR(fan2_div, S_IWUSR | S_IRUGO, show_fan_div2, set_fan_div2);
+static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp_input1, NULL);
+static DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp_hot_max,
+    set_temp_hot_max);
+static DEVICE_ATTR(temp1_max_hyst, S_IWUSR | S_IRUGO, show_temp_hot_hyst,
+    set_temp_hot_hyst);
+static DEVICE_ATTR(temp1_crit, S_IWUSR | S_IRUGO, show_temp_os_max,
+    set_temp_os_max);
+static DEVICE_ATTR(temp1_crit_hyst, S_IWUSR | S_IRUGO, show_temp_os_hyst,
+    set_temp_os_hyst);
+static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
+
+/*
+ * Real code
+ */
+
+static int lm80_attach_adapter(struct i2c_adapter *adapter)
+{
+	if (!(adapter->class & I2C_CLASS_HWMON))
+		return 0;
+	return i2c_detect(adapter, &addr_data, lm80_detect);
+}
+
+int lm80_detect(struct i2c_adapter *adapter, int address, int kind)
+{
+	int i, cur;
+	struct i2c_client *new_client;
+	struct lm80_data *data;
+	int err = 0;
+	const char *name;
+
+	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+		goto exit;
+
+	/* OK. For now, we presume we have a valid client. We now create the
+	   client structure, even though we cannot fill it completely yet.
+	   But it allows us to access lm80_{read,write}_value. */
+	if (!(data = kmalloc(sizeof(struct lm80_data), GFP_KERNEL))) {
+		err = -ENOMEM;
+		goto exit;
+	}
+	memset(data, 0, sizeof(struct lm80_data));
+
+	new_client = &data->client;
+	i2c_set_clientdata(new_client, data);
+	new_client->addr = address;
+	new_client->adapter = adapter;
+	new_client->driver = &lm80_driver;
+	new_client->flags = 0;
+
+	/* Now, we do the remaining detection. It is lousy. */
+	if (lm80_read_value(new_client, LM80_REG_ALARM2) & 0xc0)
+		goto error_free;
+	for (i = 0x2a; i <= 0x3d; i++) {
+		cur = i2c_smbus_read_byte_data(new_client, i);
+		if ((i2c_smbus_read_byte_data(new_client, i + 0x40) != cur)
+		 || (i2c_smbus_read_byte_data(new_client, i + 0x80) != cur)
+		 || (i2c_smbus_read_byte_data(new_client, i + 0xc0) != cur))
+		    goto error_free;
+	}
+
+	/* Determine the chip type - only one kind supported! */
+	kind = lm80;
+	name = "lm80";
+
+	/* Fill in the remaining client fields and put it into the global list */
+	strlcpy(new_client->name, name, I2C_NAME_SIZE);
+	data->valid = 0;
+	init_MUTEX(&data->update_lock);
+
+	/* Tell the I2C layer a new client has arrived */
+	if ((err = i2c_attach_client(new_client)))
+		goto error_free;
+
+	/* Initialize the LM80 chip */
+	lm80_init_client(new_client);
+
+	/* A few vars need to be filled upon startup */
+	data->fan_min[0] = lm80_read_value(new_client, LM80_REG_FAN_MIN(1));
+	data->fan_min[1] = lm80_read_value(new_client, LM80_REG_FAN_MIN(2));
+
+	/* Register sysfs hooks */
+	device_create_file(&new_client->dev, &dev_attr_in0_min);
+	device_create_file(&new_client->dev, &dev_attr_in1_min);
+	device_create_file(&new_client->dev, &dev_attr_in2_min);
+	device_create_file(&new_client->dev, &dev_attr_in3_min);
+	device_create_file(&new_client->dev, &dev_attr_in4_min);
+	device_create_file(&new_client->dev, &dev_attr_in5_min);
+	device_create_file(&new_client->dev, &dev_attr_in6_min);
+	device_create_file(&new_client->dev, &dev_attr_in0_max);
+	device_create_file(&new_client->dev, &dev_attr_in1_max);
+	device_create_file(&new_client->dev, &dev_attr_in2_max);
+	device_create_file(&new_client->dev, &dev_attr_in3_max);
+	device_create_file(&new_client->dev, &dev_attr_in4_max);
+	device_create_file(&new_client->dev, &dev_attr_in5_max);
+	device_create_file(&new_client->dev, &dev_attr_in6_max);
+	device_create_file(&new_client->dev, &dev_attr_in0_input);
+	device_create_file(&new_client->dev, &dev_attr_in1_input);
+	device_create_file(&new_client->dev, &dev_attr_in2_input);
+	device_create_file(&new_client->dev, &dev_attr_in3_input);
+	device_create_file(&new_client->dev, &dev_attr_in4_input);
+	device_create_file(&new_client->dev, &dev_attr_in5_input);
+	device_create_file(&new_client->dev, &dev_attr_in6_input);
+	device_create_file(&new_client->dev, &dev_attr_fan1_min);
+	device_create_file(&new_client->dev, &dev_attr_fan2_min);
+	device_create_file(&new_client->dev, &dev_attr_fan1_input);
+	device_create_file(&new_client->dev, &dev_attr_fan2_input);
+	device_create_file(&new_client->dev, &dev_attr_fan1_div);
+	device_create_file(&new_client->dev, &dev_attr_fan2_div);
+	device_create_file(&new_client->dev, &dev_attr_temp1_input);
+	device_create_file(&new_client->dev, &dev_attr_temp1_max);
+	device_create_file(&new_client->dev, &dev_attr_temp1_max_hyst);
+	device_create_file(&new_client->dev, &dev_attr_temp1_crit);
+	device_create_file(&new_client->dev, &dev_attr_temp1_crit_hyst);
+	device_create_file(&new_client->dev, &dev_attr_alarms);
+
+	return 0;
+
+error_free:
+	kfree(data);
+exit:
+	return err;
+}
+
+static int lm80_detach_client(struct i2c_client *client)
+{
+	int err;
+
+	if ((err = i2c_detach_client(client))) {
+		dev_err(&client->dev, "Client deregistration failed, "
+			"client not detached.\n");
+		return err;
+	}
+
+	kfree(i2c_get_clientdata(client));
+	return 0;
+}
+
+static int lm80_read_value(struct i2c_client *client, u8 reg)
+{
+	return i2c_smbus_read_byte_data(client, reg);
+}
+
+static int lm80_write_value(struct i2c_client *client, u8 reg, u8 value)
+{
+	return i2c_smbus_write_byte_data(client, reg, value);
+}
+
+/* Called when we have found a new LM80. */
+static void lm80_init_client(struct i2c_client *client)
+{
+	/* Reset all except Watchdog values and last conversion values
+	   This sets fan-divs to 2, among others. This makes most other
+	   initializations unnecessary */
+	lm80_write_value(client, LM80_REG_CONFIG, 0x80);
+	/* Set 11-bit temperature resolution */
+	lm80_write_value(client, LM80_REG_RES, 0x08);
+
+	/* Start monitoring */
+	lm80_write_value(client, LM80_REG_CONFIG, 0x01);
+}
+
+static struct lm80_data *lm80_update_device(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm80_data *data = i2c_get_clientdata(client);
+	int i;
+
+	down(&data->update_lock);
+
+	if (time_after(jiffies, data->last_updated + 2 * HZ) || !data->valid) {
+		dev_dbg(&client->dev, "Starting lm80 update\n");
+		for (i = 0; i <= 6; i++) {
+			data->in[i] =
+			    lm80_read_value(client, LM80_REG_IN(i));
+			data->in_min[i] =
+			    lm80_read_value(client, LM80_REG_IN_MIN(i));
+			data->in_max[i] =
+			    lm80_read_value(client, LM80_REG_IN_MAX(i));
+		}
+		data->fan[0] = lm80_read_value(client, LM80_REG_FAN1);
+		data->fan_min[0] =
+		    lm80_read_value(client, LM80_REG_FAN_MIN(1));
+		data->fan[1] = lm80_read_value(client, LM80_REG_FAN2);
+		data->fan_min[1] =
+		    lm80_read_value(client, LM80_REG_FAN_MIN(2));
+
+		data->temp =
+		    (lm80_read_value(client, LM80_REG_TEMP) << 8) |
+		    (lm80_read_value(client, LM80_REG_RES) & 0xf0);
+		data->temp_os_max =
+		    lm80_read_value(client, LM80_REG_TEMP_OS_MAX);
+		data->temp_os_hyst =
+		    lm80_read_value(client, LM80_REG_TEMP_OS_HYST);
+		data->temp_hot_max =
+		    lm80_read_value(client, LM80_REG_TEMP_HOT_MAX);
+		data->temp_hot_hyst =
+		    lm80_read_value(client, LM80_REG_TEMP_HOT_HYST);
+
+		i = lm80_read_value(client, LM80_REG_FANDIV);
+		data->fan_div[0] = (i >> 2) & 0x03;
+		data->fan_div[1] = (i >> 4) & 0x03;
+		data->alarms = lm80_read_value(client, LM80_REG_ALARM1) +
+		    (lm80_read_value(client, LM80_REG_ALARM2) << 8);
+		data->last_updated = jiffies;
+		data->valid = 1;
+	}
+
+	up(&data->update_lock);
+
+	return data;
+}
+
+static int __init sensors_lm80_init(void)
+{
+	return i2c_add_driver(&lm80_driver);
+}
+
+static void __exit sensors_lm80_exit(void)
+{
+	i2c_del_driver(&lm80_driver);
+}
+
+MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl> and "
+	"Philip Edelbrock <phil@netroedge.com>");
+MODULE_DESCRIPTION("LM80 driver");
+MODULE_LICENSE("GPL");
+
+module_init(sensors_lm80_init);
+module_exit(sensors_lm80_exit);
diff --git a/drivers/hwmon/lm83.c b/drivers/hwmon/lm83.c
new file mode 100644
--- /dev/null
+++ b/drivers/hwmon/lm83.c
@@ -0,0 +1,408 @@
+/*
+ * lm83.c - Part of lm_sensors, Linux kernel modules for hardware
+ *          monitoring
+ * Copyright (C) 2003-2005  Jean Delvare <khali@linux-fr.org>
+ *
+ * Heavily inspired from the lm78, lm75 and adm1021 drivers. The LM83 is
+ * a sensor chip made by National Semiconductor. It reports up to four
+ * temperatures (its own plus up to three external ones) with a 1 deg
+ * resolution and a 3-4 deg accuracy. Complete datasheet can be obtained
+ * from National's website at:
+ *   http://www.national.com/pf/LM/LM83.html
+ * Since the datasheet omits to give the chip stepping code, I give it
+ * here: 0x03 (at register 0xff).
+ *
+ * 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 <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+#include <linux/i2c.h>
+#include <linux/i2c-sensor.h>
+#include <linux/hwmon-sysfs.h>
+
+/*
+ * Addresses to scan
+ * Address is selected using 2 three-level pins, resulting in 9 possible
+ * addresses.
+ */
+
+static unsigned short normal_i2c[] = { 0x18, 0x19, 0x1a,
+					0x29, 0x2a, 0x2b,
+					0x4c, 0x4d, 0x4e,
+					I2C_CLIENT_END };
+static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
+
+/*
+ * Insmod parameters
+ */
+
+SENSORS_INSMOD_1(lm83);
+
+/*
+ * The LM83 registers
+ * Manufacturer ID is 0x01 for National Semiconductor.
+ */
+
+#define LM83_REG_R_MAN_ID		0xFE
+#define LM83_REG_R_CHIP_ID		0xFF
+#define LM83_REG_R_CONFIG		0x03
+#define LM83_REG_W_CONFIG		0x09
+#define LM83_REG_R_STATUS1		0x02
+#define LM83_REG_R_STATUS2		0x35
+#define LM83_REG_R_LOCAL_TEMP		0x00
+#define LM83_REG_R_LOCAL_HIGH		0x05
+#define LM83_REG_W_LOCAL_HIGH		0x0B
+#define LM83_REG_R_REMOTE1_TEMP		0x30
+#define LM83_REG_R_REMOTE1_HIGH		0x38
+#define LM83_REG_W_REMOTE1_HIGH		0x50
+#define LM83_REG_R_REMOTE2_TEMP		0x01
+#define LM83_REG_R_REMOTE2_HIGH		0x07
+#define LM83_REG_W_REMOTE2_HIGH		0x0D
+#define LM83_REG_R_REMOTE3_TEMP		0x31
+#define LM83_REG_R_REMOTE3_HIGH		0x3A
+#define LM83_REG_W_REMOTE3_HIGH		0x52
+#define LM83_REG_R_TCRIT		0x42
+#define LM83_REG_W_TCRIT		0x5A
+
+/*
+ * Conversions and various macros
+ * The LM83 uses signed 8-bit values with LSB = 1 degree Celsius.
+ */
+
+#define TEMP_FROM_REG(val)	((val) * 1000)
+#define TEMP_TO_REG(val)	((val) <= -128000 ? -128 : \
+				 (val) >= 127000 ? 127 : \
+				 (val) < 0 ? ((val) - 500) / 1000 : \
+				 ((val) + 500) / 1000)
+
+static const u8 LM83_REG_R_TEMP[] = {
+	LM83_REG_R_LOCAL_TEMP,
+	LM83_REG_R_REMOTE1_TEMP,
+	LM83_REG_R_REMOTE2_TEMP,
+	LM83_REG_R_REMOTE3_TEMP,
+	LM83_REG_R_LOCAL_HIGH,
+	LM83_REG_R_REMOTE1_HIGH,
+	LM83_REG_R_REMOTE2_HIGH,
+	LM83_REG_R_REMOTE3_HIGH,
+	LM83_REG_R_TCRIT,
+};
+
+static const u8 LM83_REG_W_HIGH[] = {
+	LM83_REG_W_LOCAL_HIGH,
+	LM83_REG_W_REMOTE1_HIGH,
+	LM83_REG_W_REMOTE2_HIGH,
+	LM83_REG_W_REMOTE3_HIGH,
+	LM83_REG_W_TCRIT,
+};
+
+/*
+ * Functions declaration
+ */
+
+static int lm83_attach_adapter(struct i2c_adapter *adapter);
+static int lm83_detect(struct i2c_adapter *adapter, int address, int kind);
+static int lm83_detach_client(struct i2c_client *client);
+static struct lm83_data *lm83_update_device(struct device *dev);
+
+/*
+ * Driver data (common to all clients)
+ */
+ 
+static struct i2c_driver lm83_driver = {
+	.owner		= THIS_MODULE,
+	.name		= "lm83",
+	.id		= I2C_DRIVERID_LM83,
+	.flags		= I2C_DF_NOTIFY,
+	.attach_adapter	= lm83_attach_adapter,
+	.detach_client	= lm83_detach_client,
+};
+
+/*
+ * Client data (each client gets its own)
+ */
+
+struct lm83_data {
+	struct i2c_client client;
+	struct semaphore update_lock;
+	char valid; /* zero until following fields are valid */
+	unsigned long last_updated; /* in jiffies */
+
+	/* registers values */
+	s8 temp[9];	/* 0..3: input 1-4,
+			   4..7: high limit 1-4,
+			   8   : critical limit */
+	u16 alarms; /* bitvector, combined */
+};
+
+/*
+ * Sysfs stuff
+ */
+
+static ssize_t show_temp(struct device *dev, struct device_attribute *devattr,
+			 char *buf)
+{
+	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+	struct lm83_data *data = lm83_update_device(dev);
+	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp[attr->index]));
+}
+
+static ssize_t set_temp(struct device *dev, struct device_attribute *devattr,
+			const char *buf, size_t count)
+{
+	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm83_data *data = i2c_get_clientdata(client);
+	long val = simple_strtol(buf, NULL, 10);
+	int nr = attr->index;
+
+	down(&data->update_lock);
+	data->temp[nr] = TEMP_TO_REG(val);
+	i2c_smbus_write_byte_data(client, LM83_REG_W_HIGH[nr - 4],
+				  data->temp[nr]);
+	up(&data->update_lock);
+	return count;
+}
+
+static ssize_t show_alarms(struct device *dev, struct device_attribute *dummy,
+			   char *buf)
+{
+	struct lm83_data *data = lm83_update_device(dev);
+	return sprintf(buf, "%d\n", data->alarms);
+}
+
+static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0);
+static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 1);
+static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_temp, NULL, 2);
+static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, show_temp, NULL, 3);
+static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp,
+	set_temp, 4);
+static SENSOR_DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_temp,
+	set_temp, 5);
+static SENSOR_DEVICE_ATTR(temp3_max, S_IWUSR | S_IRUGO, show_temp,
+	set_temp, 6);
+static SENSOR_DEVICE_ATTR(temp4_max, S_IWUSR | S_IRUGO, show_temp,
+	set_temp, 7);
+static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO, show_temp, NULL, 8);
+static SENSOR_DEVICE_ATTR(temp2_crit, S_IRUGO, show_temp, NULL, 8);
+static SENSOR_DEVICE_ATTR(temp3_crit, S_IWUSR | S_IRUGO, show_temp,
+	set_temp, 8);
+static SENSOR_DEVICE_ATTR(temp4_crit, S_IRUGO, show_temp, NULL, 8);
+static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
+
+/*
+ * Real code
+ */
+
+static int lm83_attach_adapter(struct i2c_adapter *adapter)
+{
+	if (!(adapter->class & I2C_CLASS_HWMON))
+		return 0;
+	return i2c_detect(adapter, &addr_data, lm83_detect);
+}
+
+/*
+ * The following function does more than just detection. If detection
+ * succeeds, it also registers the new chip.
+ */
+static int lm83_detect(struct i2c_adapter *adapter, int address, int kind)
+{
+	struct i2c_client *new_client;
+	struct lm83_data *data;
+	int err = 0;
+	const char *name = "";
+
+	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+		goto exit;
+
+	if (!(data = kmalloc(sizeof(struct lm83_data), GFP_KERNEL))) {
+		err = -ENOMEM;
+		goto exit;
+	}
+	memset(data, 0, sizeof(struct lm83_data));
+
+	/* The common I2C client data is placed right after the
+	 * LM83-specific data. */
+	new_client = &data->client;
+	i2c_set_clientdata(new_client, data);
+	new_client->addr = address;
+	new_client->adapter = adapter;
+	new_client->driver = &lm83_driver;
+	new_client->flags = 0;
+
+	/* Now we do the detection and identification. A negative kind
+	 * means that the driver was loaded with no force parameter
+	 * (default), so we must both detect and identify the chip
+	 * (actually there is only one possible kind of chip for now, LM83).
+	 * A zero kind means that the driver was loaded with the force
+	 * parameter, the detection step shall be skipped. A positive kind
+	 * means that the driver was loaded with the force parameter and a
+	 * given kind of chip is requested, so both the detection and the
+	 * identification steps are skipped. */
+
+	/* Default to an LM83 if forced */
+	if (kind == 0)
+		kind = lm83;
+
+	if (kind < 0) { /* detection */
+		if (((i2c_smbus_read_byte_data(new_client, LM83_REG_R_STATUS1)
+		    & 0xA8) != 0x00) ||
+		    ((i2c_smbus_read_byte_data(new_client, LM83_REG_R_STATUS2)
+		    & 0x48) != 0x00) ||
+		    ((i2c_smbus_read_byte_data(new_client, LM83_REG_R_CONFIG)
+		    & 0x41) != 0x00)) {
+			dev_dbg(&adapter->dev,
+			    "LM83 detection failed at 0x%02x.\n", address);
+			goto exit_free;
+		}
+	}
+
+	if (kind <= 0) { /* identification */
+		u8 man_id, chip_id;
+
+		man_id = i2c_smbus_read_byte_data(new_client,
+		    LM83_REG_R_MAN_ID);
+		chip_id = i2c_smbus_read_byte_data(new_client,
+		    LM83_REG_R_CHIP_ID);
+
+		if (man_id == 0x01) { /* National Semiconductor */
+			if (chip_id == 0x03) {
+				kind = lm83;
+			}
+		}
+
+		if (kind <= 0) { /* identification failed */
+			dev_info(&adapter->dev,
+			    "Unsupported chip (man_id=0x%02X, "
+			    "chip_id=0x%02X).\n", man_id, chip_id);
+			goto exit_free;
+		}
+	}
+
+	if (kind == lm83) {
+		name = "lm83";
+	}
+
+	/* We can fill in the remaining client fields */
+	strlcpy(new_client->name, name, I2C_NAME_SIZE);
+	data->valid = 0;
+	init_MUTEX(&data->update_lock);
+
+	/* Tell the I2C layer a new client has arrived */
+	if ((err = i2c_attach_client(new_client)))
+		goto exit_free;
+
+	/*
+	 * Initialize the LM83 chip
+	 * (Nothing to do for this one.)
+	 */
+
+	/* Register sysfs hooks */
+	device_create_file(&new_client->dev,
+			   &sensor_dev_attr_temp1_input.dev_attr);
+	device_create_file(&new_client->dev,
+			   &sensor_dev_attr_temp2_input.dev_attr);
+	device_create_file(&new_client->dev,
+			   &sensor_dev_attr_temp3_input.dev_attr);
+	device_create_file(&new_client->dev,
+			   &sensor_dev_attr_temp4_input.dev_attr);
+	device_create_file(&new_client->dev,
+			   &sensor_dev_attr_temp1_max.dev_attr);
+	device_create_file(&new_client->dev,
+			   &sensor_dev_attr_temp2_max.dev_attr);
+	device_create_file(&new_client->dev,
+			   &sensor_dev_attr_temp3_max.dev_attr);
+	device_create_file(&new_client->dev,
+			   &sensor_dev_attr_temp4_max.dev_attr);
+	device_create_file(&new_client->dev,
+			   &sensor_dev_attr_temp1_crit.dev_attr);
+	device_create_file(&new_client->dev,
+			   &sensor_dev_attr_temp2_crit.dev_attr);
+	device_create_file(&new_client->dev,
+			   &sensor_dev_attr_temp3_crit.dev_attr);
+	device_create_file(&new_client->dev,
+			   &sensor_dev_attr_temp4_crit.dev_attr);
+	device_create_file(&new_client->dev, &dev_attr_alarms);
+
+	return 0;
+
+exit_free:
+	kfree(data);
+exit:
+	return err;
+}
+
+static int lm83_detach_client(struct i2c_client *client)
+{
+	int err;
+
+	if ((err = i2c_detach_client(client))) {
+		dev_err(&client->dev,
+		    "Client deregistration failed, client not detached.\n");
+		return err;
+	}
+
+	kfree(i2c_get_clientdata(client));
+	return 0;
+}
+
+static struct lm83_data *lm83_update_device(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm83_data *data = i2c_get_clientdata(client);
+
+	down(&data->update_lock);
+
+	if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) {
+		int nr;
+
+		dev_dbg(&client->dev, "Updating lm83 data.\n");
+		for (nr = 0; nr < 9; nr++) {
+			data->temp[nr] =
+			    i2c_smbus_read_byte_data(client,
+			    LM83_REG_R_TEMP[nr]);
+		}
+		data->alarms =
+		    i2c_smbus_read_byte_data(client, LM83_REG_R_STATUS1)
+		    + (i2c_smbus_read_byte_data(client, LM83_REG_R_STATUS2)
+		    << 8);
+
+		data->last_updated = jiffies;
+		data->valid = 1;
+	}
+
+	up(&data->update_lock);
+
+	return data;
+}
+
+static int __init sensors_lm83_init(void)
+{
+	return i2c_add_driver(&lm83_driver);
+}
+
+static void __exit sensors_lm83_exit(void)
+{
+	i2c_del_driver(&lm83_driver);
+}
+
+MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>");
+MODULE_DESCRIPTION("LM83 driver");
+MODULE_LICENSE("GPL");
+
+module_init(sensors_lm83_init);
+module_exit(sensors_lm83_exit);
diff --git a/drivers/hwmon/lm85.c b/drivers/hwmon/lm85.c
new file mode 100644
--- /dev/null
+++ b/drivers/hwmon/lm85.c
@@ -0,0 +1,1575 @@
+/*
+    lm85.c - Part of lm_sensors, Linux kernel modules for hardware
+             monitoring
+    Copyright (c) 1998, 1999  Frodo Looijaard <frodol@dds.nl> 
+    Copyright (c) 2002, 2003  Philip Pokorny <ppokorny@penguincomputing.com>
+    Copyright (c) 2003        Margit Schubert-While <margitsw@t-online.de>
+    Copyright (c) 2004        Justin Thiessen <jthiessen@penguincomputing.com>
+
+    Chip details at	      <http://www.national.com/ds/LM/LM85.pdf>
+
+    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 <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+#include <linux/i2c.h>
+#include <linux/i2c-sensor.h>
+#include <linux/i2c-vid.h>
+
+/* Addresses to scan */
+static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END };
+static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
+
+/* Insmod parameters */
+SENSORS_INSMOD_6(lm85b, lm85c, adm1027, adt7463, emc6d100, emc6d102);
+
+/* The LM85 registers */
+
+#define	LM85_REG_IN(nr)			(0x20 + (nr))
+#define	LM85_REG_IN_MIN(nr)		(0x44 + (nr) * 2)
+#define	LM85_REG_IN_MAX(nr)		(0x45 + (nr) * 2)
+
+#define	LM85_REG_TEMP(nr)		(0x25 + (nr))
+#define	LM85_REG_TEMP_MIN(nr)		(0x4e + (nr) * 2)
+#define	LM85_REG_TEMP_MAX(nr)		(0x4f + (nr) * 2)
+
+/* Fan speeds are LSB, MSB (2 bytes) */
+#define	LM85_REG_FAN(nr)		(0x28 + (nr) *2)
+#define	LM85_REG_FAN_MIN(nr)		(0x54 + (nr) *2)
+
+#define	LM85_REG_PWM(nr)		(0x30 + (nr))
+
+#define	ADT7463_REG_OPPOINT(nr)		(0x33 + (nr))
+
+#define	ADT7463_REG_TMIN_CTL1		0x36
+#define	ADT7463_REG_TMIN_CTL2		0x37
+
+#define	LM85_REG_DEVICE			0x3d
+#define	LM85_REG_COMPANY		0x3e
+#define	LM85_REG_VERSTEP		0x3f
+/* These are the recognized values for the above regs */
+#define	LM85_DEVICE_ADX			0x27
+#define	LM85_COMPANY_NATIONAL		0x01
+#define	LM85_COMPANY_ANALOG_DEV		0x41
+#define	LM85_COMPANY_SMSC      		0x5c
+#define	LM85_VERSTEP_VMASK              0xf0
+#define	LM85_VERSTEP_GENERIC		0x60
+#define	LM85_VERSTEP_LM85C		0x60
+#define	LM85_VERSTEP_LM85B		0x62
+#define	LM85_VERSTEP_ADM1027		0x60
+#define	LM85_VERSTEP_ADT7463		0x62
+#define	LM85_VERSTEP_ADT7463C		0x6A
+#define	LM85_VERSTEP_EMC6D100_A0        0x60
+#define	LM85_VERSTEP_EMC6D100_A1        0x61
+#define	LM85_VERSTEP_EMC6D102		0x65
+
+#define	LM85_REG_CONFIG			0x40
+
+#define	LM85_REG_ALARM1			0x41
+#define	LM85_REG_ALARM2			0x42
+
+#define	LM85_REG_VID			0x43
+
+/* Automated FAN control */
+#define	LM85_REG_AFAN_CONFIG(nr)	(0x5c + (nr))
+#define	LM85_REG_AFAN_RANGE(nr)		(0x5f + (nr))
+#define	LM85_REG_AFAN_SPIKE1		0x62
+#define	LM85_REG_AFAN_SPIKE2		0x63
+#define	LM85_REG_AFAN_MINPWM(nr)	(0x64 + (nr))
+#define	LM85_REG_AFAN_LIMIT(nr)		(0x67 + (nr))
+#define	LM85_REG_AFAN_CRITICAL(nr)	(0x6a + (nr))
+#define	LM85_REG_AFAN_HYST1		0x6d
+#define	LM85_REG_AFAN_HYST2		0x6e
+
+#define	LM85_REG_TACH_MODE		0x74
+#define	LM85_REG_SPINUP_CTL		0x75
+
+#define	ADM1027_REG_TEMP_OFFSET(nr)	(0x70 + (nr))
+#define	ADM1027_REG_CONFIG2		0x73
+#define	ADM1027_REG_INTMASK1		0x74
+#define	ADM1027_REG_INTMASK2		0x75
+#define	ADM1027_REG_EXTEND_ADC1		0x76
+#define	ADM1027_REG_EXTEND_ADC2		0x77
+#define	ADM1027_REG_CONFIG3		0x78
+#define	ADM1027_REG_FAN_PPR		0x7b
+
+#define	ADT7463_REG_THERM		0x79
+#define	ADT7463_REG_THERM_LIMIT		0x7A
+
+#define EMC6D100_REG_ALARM3             0x7d
+/* IN5, IN6 and IN7 */
+#define	EMC6D100_REG_IN(nr)             (0x70 + ((nr)-5))
+#define	EMC6D100_REG_IN_MIN(nr)         (0x73 + ((nr)-5) * 2)
+#define	EMC6D100_REG_IN_MAX(nr)         (0x74 + ((nr)-5) * 2)
+#define	EMC6D102_REG_EXTEND_ADC1	0x85
+#define	EMC6D102_REG_EXTEND_ADC2	0x86
+#define	EMC6D102_REG_EXTEND_ADC3	0x87
+#define	EMC6D102_REG_EXTEND_ADC4	0x88
+
+#define	LM85_ALARM_IN0			0x0001
+#define	LM85_ALARM_IN1			0x0002
+#define	LM85_ALARM_IN2			0x0004
+#define	LM85_ALARM_IN3			0x0008
+#define	LM85_ALARM_TEMP1		0x0010
+#define	LM85_ALARM_TEMP2		0x0020
+#define	LM85_ALARM_TEMP3		0x0040
+#define	LM85_ALARM_ALARM2		0x0080
+#define	LM85_ALARM_IN4			0x0100
+#define	LM85_ALARM_RESERVED		0x0200
+#define	LM85_ALARM_FAN1			0x0400
+#define	LM85_ALARM_FAN2			0x0800
+#define	LM85_ALARM_FAN3			0x1000
+#define	LM85_ALARM_FAN4			0x2000
+#define	LM85_ALARM_TEMP1_FAULT		0x4000
+#define	LM85_ALARM_TEMP3_FAULT		0x8000
+
+
+/* Conversions. Rounding and limit checking is only done on the TO_REG 
+   variants. Note that you should be a bit careful with which arguments
+   these macros are called: arguments may be evaluated more than once.
+ */
+
+/* IN are scaled acording to built-in resistors */
+static int lm85_scaling[] = {  /* .001 Volts */
+		2500, 2250, 3300, 5000, 12000,
+		3300, 1500, 1800 /*EMC6D100*/
+	};
+#define SCALE(val,from,to)		(((val)*(to) + ((from)/2))/(from))
+
+#define INS_TO_REG(n,val)	\
+		SENSORS_LIMIT(SCALE(val,lm85_scaling[n],192),0,255)
+
+#define INSEXT_FROM_REG(n,val,ext,scale)	\
+		SCALE((val)*(scale) + (ext),192*(scale),lm85_scaling[n])
+
+#define INS_FROM_REG(n,val)   INSEXT_FROM_REG(n,val,0,1)
+
+/* FAN speed is measured using 90kHz clock */
+#define FAN_TO_REG(val)		(SENSORS_LIMIT( (val)<=0?0: 5400000/(val),0,65534))
+#define FAN_FROM_REG(val)	((val)==0?-1:(val)==0xffff?0:5400000/(val))
+
+/* Temperature is reported in .001 degC increments */
+#define TEMP_TO_REG(val)	\
+		SENSORS_LIMIT(SCALE(val,1000,1),-127,127)
+#define TEMPEXT_FROM_REG(val,ext,scale)	\
+		SCALE((val)*scale + (ext),scale,1000)
+#define TEMP_FROM_REG(val)	\
+		TEMPEXT_FROM_REG(val,0,1)
+
+#define PWM_TO_REG(val)			(SENSORS_LIMIT(val,0,255))
+#define PWM_FROM_REG(val)		(val)
+
+
+/* ZONEs have the following parameters:
+ *    Limit (low) temp,           1. degC
+ *    Hysteresis (below limit),   1. degC (0-15)
+ *    Range of speed control,     .1 degC (2-80)
+ *    Critical (high) temp,       1. degC
+ *
+ * FAN PWMs have the following parameters:
+ *    Reference Zone,                 1, 2, 3, etc.
+ *    Spinup time,                    .05 sec
+ *    PWM value at limit/low temp,    1 count
+ *    PWM Frequency,                  1. Hz
+ *    PWM is Min or OFF below limit,  flag
+ *    Invert PWM output,              flag
+ *
+ * Some chips filter the temp, others the fan.
+ *    Filter constant (or disabled)   .1 seconds
+ */
+
+/* These are the zone temperature range encodings in .001 degree C */
+static int lm85_range_map[] = {   
+		2000,  2500,  3300,  4000,  5000,  6600,
+		8000, 10000, 13300, 16000, 20000, 26600,
+		32000, 40000, 53300, 80000
+	};
+static int RANGE_TO_REG( int range )
+{
+	int i;
+
+	if ( range < lm85_range_map[0] ) { 
+		return 0 ;
+	} else if ( range > lm85_range_map[15] ) {
+		return 15 ;
+	} else {  /* find closest match */
+		for ( i = 14 ; i >= 0 ; --i ) {
+			if ( range > lm85_range_map[i] ) { /* range bracketed */
+				if ((lm85_range_map[i+1] - range) < 
+					(range - lm85_range_map[i])) {
+					i++;
+					break;
+				}
+				break;
+			}
+		}
+	}
+	return( i & 0x0f );
+}
+#define RANGE_FROM_REG(val) (lm85_range_map[(val)&0x0f])
+
+/* These are the Acoustic Enhancement, or Temperature smoothing encodings
+ * NOTE: The enable/disable bit is INCLUDED in these encodings as the
+ *       MSB (bit 3, value 8).  If the enable bit is 0, the encoded value
+ *       is ignored, or set to 0.
+ */
+/* These are the PWM frequency encodings */
+static int lm85_freq_map[] = { /* .1 Hz */
+		100, 150, 230, 300, 380, 470, 620, 940
+	};
+static int FREQ_TO_REG( int freq )
+{
+	int i;
+
+	if( freq >= lm85_freq_map[7] ) { return 7 ; }
+	for( i = 0 ; i < 7 ; ++i )
+		if( freq <= lm85_freq_map[i] )
+			break ;
+	return( i & 0x07 );
+}
+#define FREQ_FROM_REG(val) (lm85_freq_map[(val)&0x07])
+
+/* Since we can't use strings, I'm abusing these numbers
+ *   to stand in for the following meanings:
+ *      1 -- PWM responds to Zone 1
+ *      2 -- PWM responds to Zone 2
+ *      3 -- PWM responds to Zone 3
+ *     23 -- PWM responds to the higher temp of Zone 2 or 3
+ *    123 -- PWM responds to highest of Zone 1, 2, or 3
+ *      0 -- PWM is always at 0% (ie, off)
+ *     -1 -- PWM is always at 100%
+ *     -2 -- PWM responds to manual control
+ */
+
+static int lm85_zone_map[] = { 1, 2, 3, -1, 0, 23, 123, -2 };
+#define ZONE_FROM_REG(val) (lm85_zone_map[((val)>>5)&0x07])
+
+static int ZONE_TO_REG( int zone )
+{
+	int i;
+
+	for( i = 0 ; i <= 7 ; ++i )
+		if( zone == lm85_zone_map[i] )
+			break ;
+	if( i > 7 )   /* Not found. */
+		i = 3;  /* Always 100% */
+	return( (i & 0x07)<<5 );
+}
+
+#define HYST_TO_REG(val) (SENSORS_LIMIT(((val)+500)/1000,0,15))
+#define HYST_FROM_REG(val) ((val)*1000)
+
+#define OFFSET_TO_REG(val) (SENSORS_LIMIT((val)/25,-127,127))
+#define OFFSET_FROM_REG(val) ((val)*25)
+
+#define PPR_MASK(fan) (0x03<<(fan *2))
+#define PPR_TO_REG(val,fan) (SENSORS_LIMIT((val)-1,0,3)<<(fan *2))
+#define PPR_FROM_REG(val,fan) ((((val)>>(fan * 2))&0x03)+1)
+
+/* i2c-vid.h defines vid_from_reg() */
+#define VID_FROM_REG(val,vrm) (vid_from_reg((val),(vrm)))
+
+/* Unlike some other drivers we DO NOT set initial limits.  Use
+ * the config file to set limits.  Some users have reported
+ * motherboards shutting down when we set limits in a previous
+ * version of the driver.
+ */
+
+/* Chip sampling rates
+ *
+ * Some sensors are not updated more frequently than once per second
+ *    so it doesn't make sense to read them more often than that.
+ *    We cache the results and return the saved data if the driver
+ *    is called again before a second has elapsed.
+ *
+ * Also, there is significant configuration data for this chip
+ *    given the automatic PWM fan control that is possible.  There
+ *    are about 47 bytes of config data to only 22 bytes of actual
+ *    readings.  So, we keep the config data up to date in the cache
+ *    when it is written and only sample it once every 1 *minute*
+ */
+#define LM85_DATA_INTERVAL  (HZ + HZ / 2)
+#define LM85_CONFIG_INTERVAL  (1 * 60 * HZ)
+
+/* For each registered LM85, we need to keep some data in memory. That
+   data is pointed to by lm85_list[NR]->data. The structure itself is
+   dynamically allocated, at the same time when a new lm85 client is
+   allocated. */
+
+/* LM85 can automatically adjust fan speeds based on temperature
+ * This structure encapsulates an entire Zone config.  There are
+ * three zones (one for each temperature input) on the lm85
+ */
+struct lm85_zone {
+	s8 limit;	/* Low temp limit */
+	u8 hyst;	/* Low limit hysteresis. (0-15) */
+	u8 range;	/* Temp range, encoded */
+	s8 critical;	/* "All fans ON" temp limit */
+	u8 off_desired; /* Actual "off" temperature specified.  Preserved 
+			 * to prevent "drift" as other autofan control
+			 * values change.
+			 */
+	u8 max_desired; /* Actual "max" temperature specified.  Preserved 
+			 * to prevent "drift" as other autofan control
+			 * values change.
+			 */
+};
+
+struct lm85_autofan {
+	u8 config;	/* Register value */
+	u8 freq;	/* PWM frequency, encoded */
+	u8 min_pwm;	/* Minimum PWM value, encoded */
+	u8 min_off;	/* Min PWM or OFF below "limit", flag */
+};
+
+struct lm85_data {
+	struct i2c_client client;
+	struct semaphore lock;
+	enum chips type;
+
+	struct semaphore update_lock;
+	int valid;		/* !=0 if following fields are valid */
+	unsigned long last_reading;	/* In jiffies */
+	unsigned long last_config;	/* In jiffies */
+
+	u8 in[8];		/* Register value */
+	u8 in_max[8];		/* Register value */
+	u8 in_min[8];		/* Register value */
+	s8 temp[3];		/* Register value */
+	s8 temp_min[3];		/* Register value */
+	s8 temp_max[3];		/* Register value */
+	s8 temp_offset[3];	/* Register value */
+	u16 fan[4];		/* Register value */
+	u16 fan_min[4];		/* Register value */
+	u8 pwm[3];		/* Register value */
+	u8 spinup_ctl;		/* Register encoding, combined */
+	u8 tach_mode;		/* Register encoding, combined */
+	u8 temp_ext[3];		/* Decoded values */
+	u8 in_ext[8];		/* Decoded values */
+	u8 adc_scale;		/* ADC Extended bits scaling factor */
+	u8 fan_ppr;		/* Register value */
+	u8 smooth[3];		/* Register encoding */
+	u8 vid;			/* Register value */
+	u8 vrm;			/* VRM version */
+	u8 syncpwm3;		/* Saved PWM3 for TACH 2,3,4 config */
+	u8 oppoint[3];		/* Register value */
+	u16 tmin_ctl;		/* Register value */
+	unsigned long therm_total; /* Cummulative therm count */
+	u8 therm_limit;		/* Register value */
+	u32 alarms;		/* Register encoding, combined */
+	struct lm85_autofan autofan[3];
+	struct lm85_zone zone[3];
+};
+
+static int lm85_attach_adapter(struct i2c_adapter *adapter);
+static int lm85_detect(struct i2c_adapter *adapter, int address,
+			int kind);
+static int lm85_detach_client(struct i2c_client *client);
+
+static int lm85_read_value(struct i2c_client *client, u8 register);
+static int lm85_write_value(struct i2c_client *client, u8 register, int value);
+static struct lm85_data *lm85_update_device(struct device *dev);
+static void lm85_init_client(struct i2c_client *client);
+
+
+static struct i2c_driver lm85_driver = {
+	.owner          = THIS_MODULE,
+	.name           = "lm85",
+	.id             = I2C_DRIVERID_LM85,
+	.flags          = I2C_DF_NOTIFY,
+	.attach_adapter = lm85_attach_adapter,
+	.detach_client  = lm85_detach_client,
+};
+
+
+/* 4 Fans */
+static ssize_t show_fan(struct device *dev, char *buf, int nr)
+{
+	struct lm85_data *data = lm85_update_device(dev);
+	return sprintf(buf,"%d\n", FAN_FROM_REG(data->fan[nr]) );
+}
+static ssize_t show_fan_min(struct device *dev, char *buf, int nr)
+{
+	struct lm85_data *data = lm85_update_device(dev);
+	return sprintf(buf,"%d\n", FAN_FROM_REG(data->fan_min[nr]) );
+}
+static ssize_t set_fan_min(struct device *dev, const char *buf, 
+		size_t count, int nr)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm85_data *data = i2c_get_clientdata(client);
+	long val = simple_strtol(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->fan_min[nr] = FAN_TO_REG(val);
+	lm85_write_value(client, LM85_REG_FAN_MIN(nr), data->fan_min[nr]);
+	up(&data->update_lock);
+	return count;
+}
+
+#define show_fan_offset(offset)						\
+static ssize_t show_fan_##offset (struct device *dev, struct device_attribute *attr, char *buf)	\
+{									\
+	return show_fan(dev, buf, offset - 1);				\
+}									\
+static ssize_t show_fan_##offset##_min (struct device *dev, struct device_attribute *attr, char *buf)	\
+{									\
+	return show_fan_min(dev, buf, offset - 1);			\
+}									\
+static ssize_t set_fan_##offset##_min (struct device *dev, struct device_attribute *attr, 		\
+	const char *buf, size_t count) 					\
+{									\
+	return set_fan_min(dev, buf, count, offset - 1);		\
+}									\
+static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_fan_##offset,	\
+		NULL);							\
+static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, 		\
+		show_fan_##offset##_min, set_fan_##offset##_min);
+
+show_fan_offset(1);
+show_fan_offset(2);
+show_fan_offset(3);
+show_fan_offset(4);
+
+/* vid, vrm, alarms */
+
+static ssize_t show_vid_reg(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct lm85_data *data = lm85_update_device(dev);
+	return sprintf(buf, "%ld\n", (long) vid_from_reg(data->vid, data->vrm));
+}
+
+static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid_reg, NULL);
+
+static ssize_t show_vrm_reg(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct lm85_data *data = lm85_update_device(dev);
+	return sprintf(buf, "%ld\n", (long) data->vrm);
+}
+
+static ssize_t store_vrm_reg(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm85_data *data = i2c_get_clientdata(client);
+	u32 val;
+
+	val = simple_strtoul(buf, NULL, 10);
+	data->vrm = val;
+	return count;
+}
+
+static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg);
+
+static ssize_t show_alarms_reg(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct lm85_data *data = lm85_update_device(dev);
+	return sprintf(buf, "%u\n", data->alarms);
+}
+
+static DEVICE_ATTR(alarms, S_IRUGO, show_alarms_reg, NULL);
+
+/* pwm */
+
+static ssize_t show_pwm(struct device *dev, char *buf, int nr)
+{
+	struct lm85_data *data = lm85_update_device(dev);
+	return sprintf(buf,"%d\n", PWM_FROM_REG(data->pwm[nr]) );
+}
+static ssize_t set_pwm(struct device *dev, const char *buf, 
+		size_t count, int nr)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm85_data *data = i2c_get_clientdata(client);
+	long val = simple_strtol(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->pwm[nr] = PWM_TO_REG(val);
+	lm85_write_value(client, LM85_REG_PWM(nr), data->pwm[nr]);
+	up(&data->update_lock);
+	return count;
+}
+static ssize_t show_pwm_enable(struct device *dev, char *buf, int nr)
+{
+	struct lm85_data *data = lm85_update_device(dev);
+	int	pwm_zone;
+
+	pwm_zone = ZONE_FROM_REG(data->autofan[nr].config);
+	return sprintf(buf,"%d\n", (pwm_zone != 0 && pwm_zone != -1) );
+}
+
+#define show_pwm_reg(offset)						\
+static ssize_t show_pwm_##offset (struct device *dev, struct device_attribute *attr, char *buf)	\
+{									\
+	return show_pwm(dev, buf, offset - 1);				\
+}									\
+static ssize_t set_pwm_##offset (struct device *dev, struct device_attribute *attr,			\
+				 const char *buf, size_t count)		\
+{									\
+	return set_pwm(dev, buf, count, offset - 1);			\
+}									\
+static ssize_t show_pwm_enable##offset (struct device *dev, struct device_attribute *attr, char *buf)	\
+{									\
+	return show_pwm_enable(dev, buf, offset - 1);			\
+}									\
+static DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR, 			\
+		show_pwm_##offset, set_pwm_##offset);			\
+static DEVICE_ATTR(pwm##offset##_enable, S_IRUGO, 			\
+		show_pwm_enable##offset, NULL);
+
+show_pwm_reg(1);
+show_pwm_reg(2);
+show_pwm_reg(3);
+
+/* Voltages */
+
+static ssize_t show_in(struct device *dev, char *buf, int nr)
+{
+	struct lm85_data *data = lm85_update_device(dev);
+	return sprintf(	buf, "%d\n", INSEXT_FROM_REG(nr,
+						     data->in[nr],
+						     data->in_ext[nr],
+						     data->adc_scale) );
+}
+static ssize_t show_in_min(struct device *dev, char *buf, int nr)
+{
+	struct lm85_data *data = lm85_update_device(dev);
+	return sprintf(buf,"%d\n", INS_FROM_REG(nr, data->in_min[nr]) );
+}
+static ssize_t set_in_min(struct device *dev, const char *buf, 
+		size_t count, int nr)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm85_data *data = i2c_get_clientdata(client);
+	long val = simple_strtol(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->in_min[nr] = INS_TO_REG(nr, val);
+	lm85_write_value(client, LM85_REG_IN_MIN(nr), data->in_min[nr]);
+	up(&data->update_lock);
+	return count;
+}
+static ssize_t show_in_max(struct device *dev, char *buf, int nr)
+{
+	struct lm85_data *data = lm85_update_device(dev);
+	return sprintf(buf,"%d\n", INS_FROM_REG(nr, data->in_max[nr]) );
+}
+static ssize_t set_in_max(struct device *dev, const char *buf, 
+		size_t count, int nr)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm85_data *data = i2c_get_clientdata(client);
+	long val = simple_strtol(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->in_max[nr] = INS_TO_REG(nr, val);
+	lm85_write_value(client, LM85_REG_IN_MAX(nr), data->in_max[nr]);
+	up(&data->update_lock);
+	return count;
+}
+#define show_in_reg(offset)						\
+static ssize_t show_in_##offset (struct device *dev, struct device_attribute *attr, char *buf)		\
+{									\
+	return show_in(dev, buf, offset);				\
+}									\
+static ssize_t show_in_##offset##_min (struct device *dev, struct device_attribute *attr, char *buf)	\
+{									\
+	return show_in_min(dev, buf, offset);				\
+}									\
+static ssize_t show_in_##offset##_max (struct device *dev, struct device_attribute *attr, char *buf)	\
+{									\
+	return show_in_max(dev, buf, offset);				\
+}									\
+static ssize_t set_in_##offset##_min (struct device *dev, struct device_attribute *attr, 		\
+	const char *buf, size_t count) 					\
+{									\
+	return set_in_min(dev, buf, count, offset);			\
+}									\
+static ssize_t set_in_##offset##_max (struct device *dev, struct device_attribute *attr, 		\
+	const char *buf, size_t count) 					\
+{									\
+	return set_in_max(dev, buf, count, offset);			\
+}									\
+static DEVICE_ATTR(in##offset##_input, S_IRUGO, show_in_##offset, 	\
+		NULL);							\
+static DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, 		\
+		show_in_##offset##_min, set_in_##offset##_min);		\
+static DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, 		\
+		show_in_##offset##_max, set_in_##offset##_max);
+
+show_in_reg(0);
+show_in_reg(1);
+show_in_reg(2);
+show_in_reg(3);
+show_in_reg(4);
+
+/* Temps */
+
+static ssize_t show_temp(struct device *dev, char *buf, int nr)
+{
+	struct lm85_data *data = lm85_update_device(dev);
+	return sprintf(buf,"%d\n", TEMPEXT_FROM_REG(data->temp[nr],
+						    data->temp_ext[nr],
+						    data->adc_scale) );
+}
+static ssize_t show_temp_min(struct device *dev, char *buf, int nr)
+{
+	struct lm85_data *data = lm85_update_device(dev);
+	return sprintf(buf,"%d\n", TEMP_FROM_REG(data->temp_min[nr]) );
+}
+static ssize_t set_temp_min(struct device *dev, const char *buf, 
+		size_t count, int nr)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm85_data *data = i2c_get_clientdata(client);
+	long val = simple_strtol(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->temp_min[nr] = TEMP_TO_REG(val);
+	lm85_write_value(client, LM85_REG_TEMP_MIN(nr), data->temp_min[nr]);
+	up(&data->update_lock);
+	return count;
+}
+static ssize_t show_temp_max(struct device *dev, char *buf, int nr)
+{
+	struct lm85_data *data = lm85_update_device(dev);
+	return sprintf(buf,"%d\n", TEMP_FROM_REG(data->temp_max[nr]) );
+}
+static ssize_t set_temp_max(struct device *dev, const char *buf, 
+		size_t count, int nr)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm85_data *data = i2c_get_clientdata(client);
+	long val = simple_strtol(buf, NULL, 10);	
+
+	down(&data->update_lock);
+	data->temp_max[nr] = TEMP_TO_REG(val);
+	lm85_write_value(client, LM85_REG_TEMP_MAX(nr), data->temp_max[nr]);
+	up(&data->update_lock);
+	return count;
+}
+#define show_temp_reg(offset)						\
+static ssize_t show_temp_##offset (struct device *dev, struct device_attribute *attr, char *buf)	\
+{									\
+	return show_temp(dev, buf, offset - 1);				\
+}									\
+static ssize_t show_temp_##offset##_min (struct device *dev, struct device_attribute *attr, char *buf)	\
+{									\
+	return show_temp_min(dev, buf, offset - 1);			\
+}									\
+static ssize_t show_temp_##offset##_max (struct device *dev, struct device_attribute *attr, char *buf)	\
+{									\
+	return show_temp_max(dev, buf, offset - 1);			\
+}									\
+static ssize_t set_temp_##offset##_min (struct device *dev, struct device_attribute *attr, 		\
+	const char *buf, size_t count) 					\
+{									\
+	return set_temp_min(dev, buf, count, offset - 1);		\
+}									\
+static ssize_t set_temp_##offset##_max (struct device *dev, struct device_attribute *attr, 		\
+	const char *buf, size_t count) 					\
+{									\
+	return set_temp_max(dev, buf, count, offset - 1);		\
+}									\
+static DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_temp_##offset,	\
+		NULL);							\
+static DEVICE_ATTR(temp##offset##_min, S_IRUGO | S_IWUSR, 		\
+		show_temp_##offset##_min, set_temp_##offset##_min);	\
+static DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR, 		\
+		show_temp_##offset##_max, set_temp_##offset##_max);
+
+show_temp_reg(1);
+show_temp_reg(2);
+show_temp_reg(3);
+
+
+/* Automatic PWM control */
+
+static ssize_t show_pwm_auto_channels(struct device *dev, char *buf, int nr)
+{
+	struct lm85_data *data = lm85_update_device(dev);
+	return sprintf(buf,"%d\n", ZONE_FROM_REG(data->autofan[nr].config));
+}
+static ssize_t set_pwm_auto_channels(struct device *dev, const char *buf,
+	size_t count, int nr)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm85_data *data = i2c_get_clientdata(client);
+	long val = simple_strtol(buf, NULL, 10);   
+
+	down(&data->update_lock);
+	data->autofan[nr].config = (data->autofan[nr].config & (~0xe0))
+		| ZONE_TO_REG(val) ;
+	lm85_write_value(client, LM85_REG_AFAN_CONFIG(nr),
+		data->autofan[nr].config);
+	up(&data->update_lock);
+	return count;
+}
+static ssize_t show_pwm_auto_pwm_min(struct device *dev, char *buf, int nr)
+{
+	struct lm85_data *data = lm85_update_device(dev);
+	return sprintf(buf,"%d\n", PWM_FROM_REG(data->autofan[nr].min_pwm));
+}
+static ssize_t set_pwm_auto_pwm_min(struct device *dev, const char *buf,
+	size_t count, int nr)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm85_data *data = i2c_get_clientdata(client);
+	long val = simple_strtol(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->autofan[nr].min_pwm = PWM_TO_REG(val);
+	lm85_write_value(client, LM85_REG_AFAN_MINPWM(nr),
+		data->autofan[nr].min_pwm);
+	up(&data->update_lock);
+	return count;
+}
+static ssize_t show_pwm_auto_pwm_minctl(struct device *dev, char *buf, int nr)
+{
+	struct lm85_data *data = lm85_update_device(dev);
+	return sprintf(buf,"%d\n", data->autofan[nr].min_off);
+}
+static ssize_t set_pwm_auto_pwm_minctl(struct device *dev, const char *buf,
+	size_t count, int nr)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm85_data *data = i2c_get_clientdata(client);
+	long val = simple_strtol(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->autofan[nr].min_off = val;
+	lm85_write_value(client, LM85_REG_AFAN_SPIKE1, data->smooth[0]
+		| data->syncpwm3
+		| (data->autofan[0].min_off ? 0x20 : 0)
+		| (data->autofan[1].min_off ? 0x40 : 0)
+		| (data->autofan[2].min_off ? 0x80 : 0)
+	);
+	up(&data->update_lock);
+	return count;
+}
+static ssize_t show_pwm_auto_pwm_freq(struct device *dev, char *buf, int nr)
+{
+	struct lm85_data *data = lm85_update_device(dev);
+	return sprintf(buf,"%d\n", FREQ_FROM_REG(data->autofan[nr].freq));
+}
+static ssize_t set_pwm_auto_pwm_freq(struct device *dev, const char *buf,
+		size_t count, int nr)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm85_data *data = i2c_get_clientdata(client);
+	long val = simple_strtol(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->autofan[nr].freq = FREQ_TO_REG(val);
+	lm85_write_value(client, LM85_REG_AFAN_RANGE(nr),
+		(data->zone[nr].range << 4)
+		| data->autofan[nr].freq
+	); 
+	up(&data->update_lock);
+	return count;
+}
+#define pwm_auto(offset)						\
+static ssize_t show_pwm##offset##_auto_channels (struct device *dev, struct device_attribute *attr,	\
+	char *buf)							\
+{									\
+	return show_pwm_auto_channels(dev, buf, offset - 1);		\
+}									\
+static ssize_t set_pwm##offset##_auto_channels (struct device *dev, struct device_attribute *attr,	\
+	const char *buf, size_t count)					\
+{									\
+	return set_pwm_auto_channels(dev, buf, count, offset - 1);	\
+}									\
+static ssize_t show_pwm##offset##_auto_pwm_min (struct device *dev, struct device_attribute *attr,	\
+	char *buf)							\
+{									\
+	return show_pwm_auto_pwm_min(dev, buf, offset - 1);		\
+}									\
+static ssize_t set_pwm##offset##_auto_pwm_min (struct device *dev, struct device_attribute *attr,	\
+	const char *buf, size_t count)					\
+{									\
+	return set_pwm_auto_pwm_min(dev, buf, count, offset - 1);	\
+}									\
+static ssize_t show_pwm##offset##_auto_pwm_minctl (struct device *dev, struct device_attribute *attr,	\
+	char *buf)							\
+{									\
+	return show_pwm_auto_pwm_minctl(dev, buf, offset - 1);		\
+}									\
+static ssize_t set_pwm##offset##_auto_pwm_minctl (struct device *dev, struct device_attribute *attr,	\
+	const char *buf, size_t count)					\
+{									\
+	return set_pwm_auto_pwm_minctl(dev, buf, count, offset - 1);	\
+}									\
+static ssize_t show_pwm##offset##_auto_pwm_freq (struct device *dev, struct device_attribute *attr,	\
+	char *buf)							\
+{									\
+	return show_pwm_auto_pwm_freq(dev, buf, offset - 1);		\
+}									\
+static ssize_t set_pwm##offset##_auto_pwm_freq(struct device *dev, struct device_attribute *attr,	\
+	const char *buf, size_t count)					\
+{									\
+	return set_pwm_auto_pwm_freq(dev, buf, count, offset - 1);	\
+}									\
+static DEVICE_ATTR(pwm##offset##_auto_channels, S_IRUGO | S_IWUSR,	\
+		show_pwm##offset##_auto_channels,			\
+		set_pwm##offset##_auto_channels);			\
+static DEVICE_ATTR(pwm##offset##_auto_pwm_min, S_IRUGO | S_IWUSR,	\
+		show_pwm##offset##_auto_pwm_min,			\
+		set_pwm##offset##_auto_pwm_min);			\
+static DEVICE_ATTR(pwm##offset##_auto_pwm_minctl, S_IRUGO | S_IWUSR,	\
+		show_pwm##offset##_auto_pwm_minctl,			\
+		set_pwm##offset##_auto_pwm_minctl);			\
+static DEVICE_ATTR(pwm##offset##_auto_pwm_freq, S_IRUGO | S_IWUSR,	\
+		show_pwm##offset##_auto_pwm_freq,			\
+		set_pwm##offset##_auto_pwm_freq);              
+pwm_auto(1);
+pwm_auto(2);
+pwm_auto(3);
+
+/* Temperature settings for automatic PWM control */
+
+static ssize_t show_temp_auto_temp_off(struct device *dev, char *buf, int nr)
+{
+	struct lm85_data *data = lm85_update_device(dev);
+	return sprintf(buf,"%d\n", TEMP_FROM_REG(data->zone[nr].limit) -
+		HYST_FROM_REG(data->zone[nr].hyst));
+}
+static ssize_t set_temp_auto_temp_off(struct device *dev, const char *buf,
+	size_t count, int nr)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm85_data *data = i2c_get_clientdata(client);
+	int min;
+	long val = simple_strtol(buf, NULL, 10);
+
+	down(&data->update_lock);
+	min = TEMP_FROM_REG(data->zone[nr].limit);
+	data->zone[nr].off_desired = TEMP_TO_REG(val);
+	data->zone[nr].hyst = HYST_TO_REG(min - val);
+	if ( nr == 0 || nr == 1 ) {
+		lm85_write_value(client, LM85_REG_AFAN_HYST1,
+			(data->zone[0].hyst << 4)
+			| data->zone[1].hyst
+			);
+	} else {
+		lm85_write_value(client, LM85_REG_AFAN_HYST2,
+			(data->zone[2].hyst << 4)
+		);
+	}
+	up(&data->update_lock);
+	return count;
+}
+static ssize_t show_temp_auto_temp_min(struct device *dev, char *buf, int nr)
+{
+	struct lm85_data *data = lm85_update_device(dev);
+	return sprintf(buf,"%d\n", TEMP_FROM_REG(data->zone[nr].limit) );
+}
+static ssize_t set_temp_auto_temp_min(struct device *dev, const char *buf,
+	size_t count, int nr)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm85_data *data = i2c_get_clientdata(client);
+	long val = simple_strtol(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->zone[nr].limit = TEMP_TO_REG(val);
+	lm85_write_value(client, LM85_REG_AFAN_LIMIT(nr),
+		data->zone[nr].limit);
+
+/* Update temp_auto_max and temp_auto_range */
+	data->zone[nr].range = RANGE_TO_REG(
+		TEMP_FROM_REG(data->zone[nr].max_desired) -
+		TEMP_FROM_REG(data->zone[nr].limit));
+	lm85_write_value(client, LM85_REG_AFAN_RANGE(nr),
+		((data->zone[nr].range & 0x0f) << 4)
+		| (data->autofan[nr].freq & 0x07));
+
+/* Update temp_auto_hyst and temp_auto_off */
+	data->zone[nr].hyst = HYST_TO_REG(TEMP_FROM_REG(
+		data->zone[nr].limit) - TEMP_FROM_REG(
+		data->zone[nr].off_desired));
+	if ( nr == 0 || nr == 1 ) {
+		lm85_write_value(client, LM85_REG_AFAN_HYST1,
+			(data->zone[0].hyst << 4)
+			| data->zone[1].hyst
+			);
+	} else {
+		lm85_write_value(client, LM85_REG_AFAN_HYST2,
+			(data->zone[2].hyst << 4)
+		);
+	}
+	up(&data->update_lock);
+	return count;
+}
+static ssize_t show_temp_auto_temp_max(struct device *dev, char *buf, int nr)
+{
+	struct lm85_data *data = lm85_update_device(dev);
+	return sprintf(buf,"%d\n", TEMP_FROM_REG(data->zone[nr].limit) +
+		RANGE_FROM_REG(data->zone[nr].range));
+}
+static ssize_t set_temp_auto_temp_max(struct device *dev, const char *buf,
+	size_t count, int nr)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm85_data *data = i2c_get_clientdata(client);
+	int min;
+	long val = simple_strtol(buf, NULL, 10);
+
+	down(&data->update_lock);
+	min = TEMP_FROM_REG(data->zone[nr].limit);
+	data->zone[nr].max_desired = TEMP_TO_REG(val);
+	data->zone[nr].range = RANGE_TO_REG(
+		val - min);
+	lm85_write_value(client, LM85_REG_AFAN_RANGE(nr),
+		((data->zone[nr].range & 0x0f) << 4)
+		| (data->autofan[nr].freq & 0x07));
+	up(&data->update_lock);
+	return count;
+}
+static ssize_t show_temp_auto_temp_crit(struct device *dev, char *buf, int nr)
+{
+	struct lm85_data *data = lm85_update_device(dev);
+	return sprintf(buf,"%d\n", TEMP_FROM_REG(data->zone[nr].critical));
+}
+static ssize_t set_temp_auto_temp_crit(struct device *dev, const char *buf,
+		size_t count, int nr)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm85_data *data = i2c_get_clientdata(client);
+	long val = simple_strtol(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->zone[nr].critical = TEMP_TO_REG(val);
+	lm85_write_value(client, LM85_REG_AFAN_CRITICAL(nr),
+		data->zone[nr].critical);
+	up(&data->update_lock);
+	return count;
+}
+#define temp_auto(offset)						\
+static ssize_t show_temp##offset##_auto_temp_off (struct device *dev, struct device_attribute *attr,	\
+	char *buf)							\
+{									\
+	return show_temp_auto_temp_off(dev, buf, offset - 1);		\
+}									\
+static ssize_t set_temp##offset##_auto_temp_off (struct device *dev, struct device_attribute *attr,	\
+	const char *buf, size_t count)					\
+{									\
+	return set_temp_auto_temp_off(dev, buf, count, offset - 1);	\
+}									\
+static ssize_t show_temp##offset##_auto_temp_min (struct device *dev, struct device_attribute *attr,	\
+	char *buf)							\
+{									\
+	return show_temp_auto_temp_min(dev, buf, offset - 1);		\
+}									\
+static ssize_t set_temp##offset##_auto_temp_min (struct device *dev, struct device_attribute *attr,	\
+	const char *buf, size_t count)					\
+{									\
+	return set_temp_auto_temp_min(dev, buf, count, offset - 1);	\
+}									\
+static ssize_t show_temp##offset##_auto_temp_max (struct device *dev, struct device_attribute *attr,	\
+	char *buf)							\
+{									\
+	return show_temp_auto_temp_max(dev, buf, offset - 1);		\
+}									\
+static ssize_t set_temp##offset##_auto_temp_max (struct device *dev, struct device_attribute *attr,	\
+	const char *buf, size_t count)					\
+{									\
+	return set_temp_auto_temp_max(dev, buf, count, offset - 1);	\
+}									\
+static ssize_t show_temp##offset##_auto_temp_crit (struct device *dev, struct device_attribute *attr,	\
+	char *buf)							\
+{									\
+	return show_temp_auto_temp_crit(dev, buf, offset - 1);		\
+}									\
+static ssize_t set_temp##offset##_auto_temp_crit (struct device *dev, struct device_attribute *attr,	\
+	const char *buf, size_t count)					\
+{									\
+	return set_temp_auto_temp_crit(dev, buf, count, offset - 1);	\
+}									\
+static DEVICE_ATTR(temp##offset##_auto_temp_off, S_IRUGO | S_IWUSR,	\
+		show_temp##offset##_auto_temp_off,			\
+		set_temp##offset##_auto_temp_off);			\
+static DEVICE_ATTR(temp##offset##_auto_temp_min, S_IRUGO | S_IWUSR,	\
+		show_temp##offset##_auto_temp_min,			\
+		set_temp##offset##_auto_temp_min);			\
+static DEVICE_ATTR(temp##offset##_auto_temp_max, S_IRUGO | S_IWUSR,	\
+		show_temp##offset##_auto_temp_max,			\
+		set_temp##offset##_auto_temp_max);			\
+static DEVICE_ATTR(temp##offset##_auto_temp_crit, S_IRUGO | S_IWUSR,	\
+		show_temp##offset##_auto_temp_crit,			\
+		set_temp##offset##_auto_temp_crit);
+temp_auto(1);
+temp_auto(2);
+temp_auto(3);
+
+int lm85_attach_adapter(struct i2c_adapter *adapter)
+{
+	if (!(adapter->class & I2C_CLASS_HWMON))
+		return 0;
+	return i2c_detect(adapter, &addr_data, lm85_detect);
+}
+
+int lm85_detect(struct i2c_adapter *adapter, int address,
+		int kind)
+{
+	int company, verstep ;
+	struct i2c_client *new_client = NULL;
+	struct lm85_data *data;
+	int err = 0;
+	const char *type_name = "";
+
+	if (i2c_is_isa_adapter(adapter)) {
+		/* This chip has no ISA interface */
+		goto ERROR0 ;
+	};
+
+	if (!i2c_check_functionality(adapter,
+					I2C_FUNC_SMBUS_BYTE_DATA)) {
+		/* We need to be able to do byte I/O */
+		goto ERROR0 ;
+	};
+
+	/* OK. For now, we presume we have a valid client. We now create the
+	   client structure, even though we cannot fill it completely yet.
+	   But it allows us to access lm85_{read,write}_value. */
+
+	if (!(data = kmalloc(sizeof(struct lm85_data), GFP_KERNEL))) {
+		err = -ENOMEM;
+		goto ERROR0;
+	}
+	memset(data, 0, sizeof(struct lm85_data));
+
+	new_client = &data->client;
+	i2c_set_clientdata(new_client, data);
+	new_client->addr = address;
+	new_client->adapter = adapter;
+	new_client->driver = &lm85_driver;
+	new_client->flags = 0;
+
+	/* Now, we do the remaining detection. */
+
+	company = lm85_read_value(new_client, LM85_REG_COMPANY);
+	verstep = lm85_read_value(new_client, LM85_REG_VERSTEP);
+
+	dev_dbg(&adapter->dev, "Detecting device at %d,0x%02x with"
+		" COMPANY: 0x%02x and VERSTEP: 0x%02x\n",
+		i2c_adapter_id(new_client->adapter), new_client->addr,
+		company, verstep);
+
+	/* If auto-detecting, Determine the chip type. */
+	if (kind <= 0) {
+		dev_dbg(&adapter->dev, "Autodetecting device at %d,0x%02x ...\n",
+			i2c_adapter_id(adapter), address );
+		if( company == LM85_COMPANY_NATIONAL
+		    && verstep == LM85_VERSTEP_LM85C ) {
+			kind = lm85c ;
+		} else if( company == LM85_COMPANY_NATIONAL
+		    && verstep == LM85_VERSTEP_LM85B ) {
+			kind = lm85b ;
+		} else if( company == LM85_COMPANY_NATIONAL
+		    && (verstep & LM85_VERSTEP_VMASK) == LM85_VERSTEP_GENERIC ) {
+			dev_err(&adapter->dev, "Unrecognized version/stepping 0x%02x"
+				" Defaulting to LM85.\n", verstep);
+			kind = any_chip ;
+		} else if( company == LM85_COMPANY_ANALOG_DEV
+		    && verstep == LM85_VERSTEP_ADM1027 ) {
+			kind = adm1027 ;
+		} else if( company == LM85_COMPANY_ANALOG_DEV
+		    && (verstep == LM85_VERSTEP_ADT7463
+			 || verstep == LM85_VERSTEP_ADT7463C) ) {
+			kind = adt7463 ;
+		} else if( company == LM85_COMPANY_ANALOG_DEV
+		    && (verstep & LM85_VERSTEP_VMASK) == LM85_VERSTEP_GENERIC ) {
+			dev_err(&adapter->dev, "Unrecognized version/stepping 0x%02x"
+				" Defaulting to Generic LM85.\n", verstep );
+			kind = any_chip ;
+		} else if( company == LM85_COMPANY_SMSC
+		    && (verstep == LM85_VERSTEP_EMC6D100_A0
+			 || verstep == LM85_VERSTEP_EMC6D100_A1) ) {
+			/* Unfortunately, we can't tell a '100 from a '101
+			 * from the registers.  Since a '101 is a '100
+			 * in a package with fewer pins and therefore no
+			 * 3.3V, 1.5V or 1.8V inputs, perhaps if those
+			 * inputs read 0, then it's a '101.
+			 */
+			kind = emc6d100 ;
+		} else if( company == LM85_COMPANY_SMSC
+		    && verstep == LM85_VERSTEP_EMC6D102) {
+			kind = emc6d102 ;
+		} else if( company == LM85_COMPANY_SMSC
+		    && (verstep & LM85_VERSTEP_VMASK) == LM85_VERSTEP_GENERIC) {
+			dev_err(&adapter->dev, "lm85: Detected SMSC chip\n");
+			dev_err(&adapter->dev, "lm85: Unrecognized version/stepping 0x%02x"
+			    " Defaulting to Generic LM85.\n", verstep );
+			kind = any_chip ;
+		} else if( kind == any_chip
+		    && (verstep & LM85_VERSTEP_VMASK) == LM85_VERSTEP_GENERIC) {
+			dev_err(&adapter->dev, "Generic LM85 Version 6 detected\n");
+			/* Leave kind as "any_chip" */
+		} else {
+			dev_dbg(&adapter->dev, "Autodetection failed\n");
+			/* Not an LM85 ... */
+			if( kind == any_chip ) {  /* User used force=x,y */
+				dev_err(&adapter->dev, "Generic LM85 Version 6 not"
+					" found at %d,0x%02x. Try force_lm85c.\n",
+					i2c_adapter_id(adapter), address );
+			}
+			err = 0 ;
+			goto ERROR1;
+		}
+	}
+
+	/* Fill in the chip specific driver values */
+	if ( kind == any_chip ) {
+		type_name = "lm85";
+	} else if ( kind == lm85b ) {
+		type_name = "lm85b";
+	} else if ( kind == lm85c ) {
+		type_name = "lm85c";
+	} else if ( kind == adm1027 ) {
+		type_name = "adm1027";
+	} else if ( kind == adt7463 ) {
+		type_name = "adt7463";
+	} else if ( kind == emc6d100){
+		type_name = "emc6d100";
+	} else if ( kind == emc6d102 ) {
+		type_name = "emc6d102";
+	}
+	strlcpy(new_client->name, type_name, I2C_NAME_SIZE);
+
+	/* Fill in the remaining client fields */
+	data->type = kind;
+	data->valid = 0;
+	init_MUTEX(&data->update_lock);
+
+	/* Tell the I2C layer a new client has arrived */
+	if ((err = i2c_attach_client(new_client)))
+		goto ERROR1;
+
+	/* Set the VRM version */
+	data->vrm = i2c_which_vrm();
+
+	/* Initialize the LM85 chip */
+	lm85_init_client(new_client);
+
+	/* Register sysfs hooks */
+	device_create_file(&new_client->dev, &dev_attr_fan1_input);
+	device_create_file(&new_client->dev, &dev_attr_fan2_input);
+	device_create_file(&new_client->dev, &dev_attr_fan3_input);
+	device_create_file(&new_client->dev, &dev_attr_fan4_input);
+	device_create_file(&new_client->dev, &dev_attr_fan1_min);
+	device_create_file(&new_client->dev, &dev_attr_fan2_min);
+	device_create_file(&new_client->dev, &dev_attr_fan3_min);
+	device_create_file(&new_client->dev, &dev_attr_fan4_min);
+	device_create_file(&new_client->dev, &dev_attr_pwm1);
+	device_create_file(&new_client->dev, &dev_attr_pwm2);
+	device_create_file(&new_client->dev, &dev_attr_pwm3);
+	device_create_file(&new_client->dev, &dev_attr_pwm1_enable);
+	device_create_file(&new_client->dev, &dev_attr_pwm2_enable);
+	device_create_file(&new_client->dev, &dev_attr_pwm3_enable);
+	device_create_file(&new_client->dev, &dev_attr_in0_input);
+	device_create_file(&new_client->dev, &dev_attr_in1_input);
+	device_create_file(&new_client->dev, &dev_attr_in2_input);
+	device_create_file(&new_client->dev, &dev_attr_in3_input);
+	device_create_file(&new_client->dev, &dev_attr_in4_input);
+	device_create_file(&new_client->dev, &dev_attr_in0_min);
+	device_create_file(&new_client->dev, &dev_attr_in1_min);
+	device_create_file(&new_client->dev, &dev_attr_in2_min);
+	device_create_file(&new_client->dev, &dev_attr_in3_min);
+	device_create_file(&new_client->dev, &dev_attr_in4_min);
+	device_create_file(&new_client->dev, &dev_attr_in0_max);
+	device_create_file(&new_client->dev, &dev_attr_in1_max);
+	device_create_file(&new_client->dev, &dev_attr_in2_max);
+	device_create_file(&new_client->dev, &dev_attr_in3_max);
+	device_create_file(&new_client->dev, &dev_attr_in4_max);
+	device_create_file(&new_client->dev, &dev_attr_temp1_input);
+	device_create_file(&new_client->dev, &dev_attr_temp2_input);
+	device_create_file(&new_client->dev, &dev_attr_temp3_input);
+	device_create_file(&new_client->dev, &dev_attr_temp1_min);
+	device_create_file(&new_client->dev, &dev_attr_temp2_min);
+	device_create_file(&new_client->dev, &dev_attr_temp3_min);
+	device_create_file(&new_client->dev, &dev_attr_temp1_max);
+	device_create_file(&new_client->dev, &dev_attr_temp2_max);
+	device_create_file(&new_client->dev, &dev_attr_temp3_max);
+	device_create_file(&new_client->dev, &dev_attr_vrm);
+	device_create_file(&new_client->dev, &dev_attr_cpu0_vid);
+	device_create_file(&new_client->dev, &dev_attr_alarms);
+	device_create_file(&new_client->dev, &dev_attr_pwm1_auto_channels);
+	device_create_file(&new_client->dev, &dev_attr_pwm2_auto_channels);
+	device_create_file(&new_client->dev, &dev_attr_pwm3_auto_channels);
+	device_create_file(&new_client->dev, &dev_attr_pwm1_auto_pwm_min);
+	device_create_file(&new_client->dev, &dev_attr_pwm2_auto_pwm_min);
+	device_create_file(&new_client->dev, &dev_attr_pwm3_auto_pwm_min);
+	device_create_file(&new_client->dev, &dev_attr_pwm1_auto_pwm_minctl);
+	device_create_file(&new_client->dev, &dev_attr_pwm2_auto_pwm_minctl);
+	device_create_file(&new_client->dev, &dev_attr_pwm3_auto_pwm_minctl);
+	device_create_file(&new_client->dev, &dev_attr_pwm1_auto_pwm_freq);
+	device_create_file(&new_client->dev, &dev_attr_pwm2_auto_pwm_freq);
+	device_create_file(&new_client->dev, &dev_attr_pwm3_auto_pwm_freq);
+	device_create_file(&new_client->dev, &dev_attr_temp1_auto_temp_off);
+	device_create_file(&new_client->dev, &dev_attr_temp2_auto_temp_off);
+	device_create_file(&new_client->dev, &dev_attr_temp3_auto_temp_off);
+	device_create_file(&new_client->dev, &dev_attr_temp1_auto_temp_min);
+	device_create_file(&new_client->dev, &dev_attr_temp2_auto_temp_min);
+	device_create_file(&new_client->dev, &dev_attr_temp3_auto_temp_min);
+	device_create_file(&new_client->dev, &dev_attr_temp1_auto_temp_max);
+	device_create_file(&new_client->dev, &dev_attr_temp2_auto_temp_max);
+	device_create_file(&new_client->dev, &dev_attr_temp3_auto_temp_max);
+	device_create_file(&new_client->dev, &dev_attr_temp1_auto_temp_crit);
+	device_create_file(&new_client->dev, &dev_attr_temp2_auto_temp_crit);
+	device_create_file(&new_client->dev, &dev_attr_temp3_auto_temp_crit);
+
+	return 0;
+
+	/* Error out and cleanup code */
+    ERROR1:
+	kfree(data);
+    ERROR0:
+	return err;
+}
+
+int lm85_detach_client(struct i2c_client *client)
+{
+	i2c_detach_client(client);
+	kfree(i2c_get_clientdata(client));
+	return 0;
+}
+
+
+int lm85_read_value(struct i2c_client *client, u8 reg)
+{
+	int res;
+
+	/* What size location is it? */
+	switch( reg ) {
+	case LM85_REG_FAN(0) :  /* Read WORD data */
+	case LM85_REG_FAN(1) :
+	case LM85_REG_FAN(2) :
+	case LM85_REG_FAN(3) :
+	case LM85_REG_FAN_MIN(0) :
+	case LM85_REG_FAN_MIN(1) :
+	case LM85_REG_FAN_MIN(2) :
+	case LM85_REG_FAN_MIN(3) :
+	case LM85_REG_ALARM1 :	/* Read both bytes at once */
+		res = i2c_smbus_read_byte_data(client, reg) & 0xff ;
+		res |= i2c_smbus_read_byte_data(client, reg+1) << 8 ;
+		break ;
+	case ADT7463_REG_TMIN_CTL1 :  /* Read WORD MSB, LSB */
+		res = i2c_smbus_read_byte_data(client, reg) << 8 ;
+		res |= i2c_smbus_read_byte_data(client, reg+1) & 0xff ;
+		break ;
+	default:	/* Read BYTE data */
+		res = i2c_smbus_read_byte_data(client, reg);
+		break ;
+	}
+
+	return res ;
+}
+
+int lm85_write_value(struct i2c_client *client, u8 reg, int value)
+{
+	int res ;
+
+	switch( reg ) {
+	case LM85_REG_FAN(0) :  /* Write WORD data */
+	case LM85_REG_FAN(1) :
+	case LM85_REG_FAN(2) :
+	case LM85_REG_FAN(3) :
+	case LM85_REG_FAN_MIN(0) :
+	case LM85_REG_FAN_MIN(1) :
+	case LM85_REG_FAN_MIN(2) :
+	case LM85_REG_FAN_MIN(3) :
+	/* NOTE: ALARM is read only, so not included here */
+		res = i2c_smbus_write_byte_data(client, reg, value & 0xff) ;
+		res |= i2c_smbus_write_byte_data(client, reg+1, (value>>8) & 0xff) ;
+		break ;
+	case ADT7463_REG_TMIN_CTL1 :  /* Write WORD MSB, LSB */
+		res = i2c_smbus_write_byte_data(client, reg, (value>>8) & 0xff);
+		res |= i2c_smbus_write_byte_data(client, reg+1, value & 0xff) ;
+		break ;
+	default:	/* Write BYTE data */
+		res = i2c_smbus_write_byte_data(client, reg, value);
+		break ;
+	}
+
+	return res ;
+}
+
+void lm85_init_client(struct i2c_client *client)
+{
+	int value;
+	struct lm85_data *data = i2c_get_clientdata(client);
+
+	dev_dbg(&client->dev, "Initializing device\n");
+
+	/* Warn if part was not "READY" */
+	value = lm85_read_value(client, LM85_REG_CONFIG);
+	dev_dbg(&client->dev, "LM85_REG_CONFIG is: 0x%02x\n", value);
+	if( value & 0x02 ) {
+		dev_err(&client->dev, "Client (%d,0x%02x) config is locked.\n",
+			    i2c_adapter_id(client->adapter), client->addr );
+	};
+	if( ! (value & 0x04) ) {
+		dev_err(&client->dev, "Client (%d,0x%02x) is not ready.\n",
+			    i2c_adapter_id(client->adapter), client->addr );
+	};
+	if( value & 0x10
+	    && ( data->type == adm1027
+		|| data->type == adt7463 ) ) {
+		dev_err(&client->dev, "Client (%d,0x%02x) VxI mode is set.  "
+			"Please report this to the lm85 maintainer.\n",
+			    i2c_adapter_id(client->adapter), client->addr );
+	};
+
+	/* WE INTENTIONALLY make no changes to the limits,
+	 *   offsets, pwms, fans and zones.  If they were
+	 *   configured, we don't want to mess with them.
+	 *   If they weren't, the default is 100% PWM, no
+	 *   control and will suffice until 'sensors -s'
+	 *   can be run by the user.
+	 */
+
+	/* Start monitoring */
+	value = lm85_read_value(client, LM85_REG_CONFIG);
+	/* Try to clear LOCK, Set START, save everything else */
+	value = (value & ~ 0x02) | 0x01 ;
+	dev_dbg(&client->dev, "Setting CONFIG to: 0x%02x\n", value);
+	lm85_write_value(client, LM85_REG_CONFIG, value);
+}
+
+static struct lm85_data *lm85_update_device(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm85_data *data = i2c_get_clientdata(client);
+	int i;
+
+	down(&data->update_lock);
+
+	if ( !data->valid ||
+	     time_after(jiffies, data->last_reading + LM85_DATA_INTERVAL) ) {
+		/* Things that change quickly */
+		dev_dbg(&client->dev, "Reading sensor values\n");
+		
+		/* Have to read extended bits first to "freeze" the
+		 * more significant bits that are read later.
+		 */
+		if ( (data->type == adm1027) || (data->type == adt7463) ) {
+			int ext1 = lm85_read_value(client,
+						   ADM1027_REG_EXTEND_ADC1);
+			int ext2 =  lm85_read_value(client,
+						    ADM1027_REG_EXTEND_ADC2);
+			int val = (ext1 << 8) + ext2;
+
+			for(i = 0; i <= 4; i++)
+				data->in_ext[i] = (val>>(i * 2))&0x03;
+
+			for(i = 0; i <= 2; i++)
+				data->temp_ext[i] = (val>>((i + 5) * 2))&0x03;
+		}
+
+		/* adc_scale is 2^(number of LSBs). There are 4 extra bits in
+		   the emc6d102 and 2 in the adt7463 and adm1027. In all
+		   other chips ext is always 0 and the value of scale is
+		   irrelevant. So it is left in 4*/
+		data->adc_scale = (data->type == emc6d102 ) ? 16 : 4;
+
+		for (i = 0; i <= 4; ++i) {
+			data->in[i] =
+			    lm85_read_value(client, LM85_REG_IN(i));
+		}
+
+		for (i = 0; i <= 3; ++i) {
+			data->fan[i] =
+			    lm85_read_value(client, LM85_REG_FAN(i));
+		}
+
+		for (i = 0; i <= 2; ++i) {
+			data->temp[i] =
+			    lm85_read_value(client, LM85_REG_TEMP(i));
+		}
+
+		for (i = 0; i <= 2; ++i) {
+			data->pwm[i] =
+			    lm85_read_value(client, LM85_REG_PWM(i));
+		}
+
+		data->alarms = lm85_read_value(client, LM85_REG_ALARM1);
+
+		if ( data->type == adt7463 ) {
+			if( data->therm_total < ULONG_MAX - 256 ) {
+			    data->therm_total +=
+				lm85_read_value(client, ADT7463_REG_THERM );
+			}
+		} else if ( data->type == emc6d100 ) {
+			/* Three more voltage sensors */
+			for (i = 5; i <= 7; ++i) {
+				data->in[i] =
+					lm85_read_value(client, EMC6D100_REG_IN(i));
+			}
+			/* More alarm bits */
+			data->alarms |=
+				lm85_read_value(client, EMC6D100_REG_ALARM3) << 16;
+		} else if (data->type == emc6d102 ) {
+			/* Have to read LSB bits after the MSB ones because
+			   the reading of the MSB bits has frozen the
+			   LSBs (backward from the ADM1027).
+			 */
+			int ext1 = lm85_read_value(client,
+						   EMC6D102_REG_EXTEND_ADC1);
+			int ext2 = lm85_read_value(client,
+						   EMC6D102_REG_EXTEND_ADC2);
+			int ext3 = lm85_read_value(client,
+						   EMC6D102_REG_EXTEND_ADC3);
+			int ext4 = lm85_read_value(client,
+						   EMC6D102_REG_EXTEND_ADC4);
+			data->in_ext[0] = ext3 & 0x0f;
+			data->in_ext[1] = ext4 & 0x0f;
+			data->in_ext[2] = (ext4 >> 4) & 0x0f;
+			data->in_ext[3] = (ext3 >> 4) & 0x0f;
+			data->in_ext[4] = (ext2 >> 4) & 0x0f;
+
+			data->temp_ext[0] = ext1 & 0x0f;
+			data->temp_ext[1] = ext2 & 0x0f;
+			data->temp_ext[2] = (ext1 >> 4) & 0x0f;
+		}
+
+		data->last_reading = jiffies ;
+	};  /* last_reading */
+
+	if ( !data->valid ||
+	     time_after(jiffies, data->last_config + LM85_CONFIG_INTERVAL) ) {
+		/* Things that don't change often */
+		dev_dbg(&client->dev, "Reading config values\n");
+
+		for (i = 0; i <= 4; ++i) {
+			data->in_min[i] =
+			    lm85_read_value(client, LM85_REG_IN_MIN(i));
+			data->in_max[i] =
+			    lm85_read_value(client, LM85_REG_IN_MAX(i));
+		}
+
+		if ( data->type == emc6d100 ) {
+			for (i = 5; i <= 7; ++i) {
+				data->in_min[i] =
+					lm85_read_value(client, EMC6D100_REG_IN_MIN(i));
+				data->in_max[i] =
+					lm85_read_value(client, EMC6D100_REG_IN_MAX(i));
+			}
+		}
+
+		for (i = 0; i <= 3; ++i) {
+			data->fan_min[i] =
+			    lm85_read_value(client, LM85_REG_FAN_MIN(i));
+		}
+
+		for (i = 0; i <= 2; ++i) {
+			data->temp_min[i] =
+			    lm85_read_value(client, LM85_REG_TEMP_MIN(i));
+			data->temp_max[i] =
+			    lm85_read_value(client, LM85_REG_TEMP_MAX(i));
+		}
+
+		data->vid = lm85_read_value(client, LM85_REG_VID);
+
+		for (i = 0; i <= 2; ++i) {
+			int val ;
+			data->autofan[i].config =
+			    lm85_read_value(client, LM85_REG_AFAN_CONFIG(i));
+			val = lm85_read_value(client, LM85_REG_AFAN_RANGE(i));
+			data->autofan[i].freq = val & 0x07 ;
+			data->zone[i].range = (val >> 4) & 0x0f ;
+			data->autofan[i].min_pwm =
+			    lm85_read_value(client, LM85_REG_AFAN_MINPWM(i));
+			data->zone[i].limit =
+			    lm85_read_value(client, LM85_REG_AFAN_LIMIT(i));
+			data->zone[i].critical =
+			    lm85_read_value(client, LM85_REG_AFAN_CRITICAL(i));
+		}
+
+		i = lm85_read_value(client, LM85_REG_AFAN_SPIKE1);
+		data->smooth[0] = i & 0x0f ;
+		data->syncpwm3 = i & 0x10 ;  /* Save PWM3 config */
+		data->autofan[0].min_off = (i & 0x20) != 0 ;
+		data->autofan[1].min_off = (i & 0x40) != 0 ;
+		data->autofan[2].min_off = (i & 0x80) != 0 ;
+		i = lm85_read_value(client, LM85_REG_AFAN_SPIKE2);
+		data->smooth[1] = (i>>4) & 0x0f ;
+		data->smooth[2] = i & 0x0f ;
+
+		i = lm85_read_value(client, LM85_REG_AFAN_HYST1);
+		data->zone[0].hyst = (i>>4) & 0x0f ;
+		data->zone[1].hyst = i & 0x0f ;
+
+		i = lm85_read_value(client, LM85_REG_AFAN_HYST2);
+		data->zone[2].hyst = (i>>4) & 0x0f ;
+
+		if ( (data->type == lm85b) || (data->type == lm85c) ) {
+			data->tach_mode = lm85_read_value(client,
+				LM85_REG_TACH_MODE );
+			data->spinup_ctl = lm85_read_value(client,
+				LM85_REG_SPINUP_CTL );
+		} else if ( (data->type == adt7463) || (data->type == adm1027) ) {
+			if ( data->type == adt7463 ) {
+				for (i = 0; i <= 2; ++i) {
+				    data->oppoint[i] = lm85_read_value(client,
+					ADT7463_REG_OPPOINT(i) );
+				}
+				data->tmin_ctl = lm85_read_value(client,
+					ADT7463_REG_TMIN_CTL1 );
+				data->therm_limit = lm85_read_value(client,
+					ADT7463_REG_THERM_LIMIT );
+			}
+			for (i = 0; i <= 2; ++i) {
+			    data->temp_offset[i] = lm85_read_value(client,
+				ADM1027_REG_TEMP_OFFSET(i) );
+			}
+			data->tach_mode = lm85_read_value(client,
+				ADM1027_REG_CONFIG3 );
+			data->fan_ppr = lm85_read_value(client,
+				ADM1027_REG_FAN_PPR );
+		}
+	
+		data->last_config = jiffies;
+	};  /* last_config */
+
+	data->valid = 1;
+
+	up(&data->update_lock);
+
+	return data;
+}
+
+
+static int __init sm_lm85_init(void)
+{
+	return i2c_add_driver(&lm85_driver);
+}
+
+static void  __exit sm_lm85_exit(void)
+{
+	i2c_del_driver(&lm85_driver);
+}
+
+/* Thanks to Richard Barrington for adding the LM85 to sensors-detect.
+ * Thanks to Margit Schubert-While <margitsw@t-online.de> for help with
+ *     post 2.7.0 CVS changes.
+ */
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Philip Pokorny <ppokorny@penguincomputing.com>, Margit Schubert-While <margitsw@t-online.de>, Justin Thiessen <jthiessen@penguincomputing.com");
+MODULE_DESCRIPTION("LM85-B, LM85-C driver");
+
+module_init(sm_lm85_init);
+module_exit(sm_lm85_exit);
diff --git a/drivers/hwmon/lm87.c b/drivers/hwmon/lm87.c
new file mode 100644
--- /dev/null
+++ b/drivers/hwmon/lm87.c
@@ -0,0 +1,828 @@
+/*
+ * lm87.c
+ *
+ * Copyright (C) 2000       Frodo Looijaard <frodol@dds.nl>
+ *                          Philip Edelbrock <phil@netroedge.com>
+ *                          Stephen Rousset <stephen.rousset@rocketlogix.com>
+ *                          Dan Eaton <dan.eaton@rocketlogix.com>
+ * Copyright (C) 2004       Jean Delvare <khali@linux-fr.org>
+ *
+ * Original port to Linux 2.6 by Jeff Oliver.
+ *
+ * The LM87 is a sensor chip made by National Semiconductor. It monitors up
+ * to 8 voltages (including its own power source), up to three temperatures
+ * (its own plus up to two external ones) and up to two fans. The default
+ * configuration is 6 voltages, two temperatures and two fans (see below).
+ * Voltages are scaled internally with ratios such that the nominal value of
+ * each voltage correspond to a register value of 192 (which means a
+ * resolution of about 0.5% of the nominal value). Temperature values are
+ * reported with a 1 deg resolution and a 3-4 deg accuracy. Complete
+ * datasheet can be obtained from National's website at:
+ *   http://www.national.com/pf/LM/LM87.html
+ *
+ * Some functions share pins, so not all functions are available at the same
+ * time. Which are depends on the hardware setup. This driver assumes that
+ * the BIOS configured the chip correctly. In that respect, it  differs from
+ * the original driver (from lm_sensors for Linux 2.4), which would force the
+ * LM87 to an arbitrary, compile-time chosen mode, regardless of the actual
+ * chipset wiring.
+ * For reference, here is the list of exclusive functions:
+ *  - in0+in5 (default) or temp3
+ *  - fan1 (default) or in6
+ *  - fan2 (default) or in7
+ *  - VID lines (default) or IRQ lines (not handled by this driver)
+ *
+ * The LM87 additionally features an analog output, supposedly usable to
+ * control the speed of a fan. All new chips use pulse width modulation
+ * instead. The LM87 is the only hardware monitoring chipset I know of
+ * which uses amplitude modulation. Be careful when using this feature.
+ *
+ * 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 <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+#include <linux/i2c.h>
+#include <linux/i2c-sensor.h>
+#include <linux/i2c-vid.h>
+
+/*
+ * Addresses to scan
+ * LM87 has three possible addresses: 0x2c, 0x2d and 0x2e.
+ */
+
+static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END };
+static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
+
+/*
+ * Insmod parameters
+ */
+
+SENSORS_INSMOD_1(lm87);
+
+/*
+ * The LM87 registers
+ */
+
+/* nr in 0..5 */
+#define LM87_REG_IN(nr)			(0x20 + (nr))
+#define LM87_REG_IN_MAX(nr)		(0x2B + (nr) * 2)
+#define LM87_REG_IN_MIN(nr)		(0x2C + (nr) * 2)
+/* nr in 0..1 */
+#define LM87_REG_AIN(nr)		(0x28 + (nr))
+#define LM87_REG_AIN_MIN(nr)		(0x1A + (nr))
+#define LM87_REG_AIN_MAX(nr)		(0x3B + (nr))
+
+static u8 LM87_REG_TEMP[3] = { 0x27, 0x26, 0x20 };
+static u8 LM87_REG_TEMP_HIGH[3] = { 0x39, 0x37, 0x2B };
+static u8 LM87_REG_TEMP_LOW[3] = { 0x3A, 0x38, 0x2C };
+
+#define LM87_REG_TEMP_HW_INT_LOCK	0x13
+#define LM87_REG_TEMP_HW_EXT_LOCK	0x14
+#define LM87_REG_TEMP_HW_INT		0x17
+#define LM87_REG_TEMP_HW_EXT		0x18
+
+/* nr in 0..1 */
+#define LM87_REG_FAN(nr)		(0x28 + (nr))
+#define LM87_REG_FAN_MIN(nr)		(0x3B + (nr))
+#define LM87_REG_AOUT			0x19
+
+#define LM87_REG_CONFIG			0x40
+#define LM87_REG_CHANNEL_MODE		0x16
+#define LM87_REG_VID_FAN_DIV		0x47
+#define LM87_REG_VID4			0x49
+
+#define LM87_REG_ALARMS1		0x41
+#define LM87_REG_ALARMS2		0x42
+
+#define LM87_REG_COMPANY_ID		0x3E
+#define LM87_REG_REVISION		0x3F
+
+/*
+ * Conversions and various macros
+ * The LM87 uses signed 8-bit values for temperatures.
+ */
+
+#define IN_FROM_REG(reg,scale)	(((reg) * (scale) + 96) / 192)
+#define IN_TO_REG(val,scale)	((val) <= 0 ? 0 : \
+				 (val) * 192 >= (scale) * 255 ? 255 : \
+				 ((val) * 192 + (scale)/2) / (scale))
+
+#define TEMP_FROM_REG(reg)	((reg) * 1000)
+#define TEMP_TO_REG(val)	((val) <= -127500 ? -128 : \
+				 (val) >= 126500 ? 127 : \
+				 (((val) < 0 ? (val)-500 : (val)+500) / 1000))
+
+#define FAN_FROM_REG(reg,div)	((reg) == 255 || (reg) == 0 ? 0 : \
+				 1350000 + (reg)*(div) / 2) / ((reg)*(div))
+#define FAN_TO_REG(val,div)	((val)*(div) * 255 <= 1350000 ? 255 : \
+				 (1350000 + (val)*(div) / 2) / ((val)*(div)))
+
+#define FAN_DIV_FROM_REG(reg)	(1 << (reg))
+
+/* analog out is 9.80mV/LSB */
+#define AOUT_FROM_REG(reg)	(((reg) * 98 + 5) / 10)
+#define AOUT_TO_REG(val)	((val) <= 0 ? 0 : \
+				 (val) >= 2500 ? 255 : \
+				 ((val) * 10 + 49) / 98)
+
+/* nr in 0..1 */
+#define CHAN_NO_FAN(nr)		(1 << (nr))
+#define CHAN_TEMP3		(1 << 2)
+#define CHAN_VCC_5V		(1 << 3)
+#define CHAN_NO_VID		(1 << 8)
+
+/*
+ * Functions declaration
+ */
+
+static int lm87_attach_adapter(struct i2c_adapter *adapter);
+static int lm87_detect(struct i2c_adapter *adapter, int address, int kind);
+static void lm87_init_client(struct i2c_client *client);
+static int lm87_detach_client(struct i2c_client *client);
+static struct lm87_data *lm87_update_device(struct device *dev);
+
+/*
+ * Driver data (common to all clients)
+ */
+
+static struct i2c_driver lm87_driver = {
+	.owner		= THIS_MODULE,
+	.name		= "lm87",
+	.id		= I2C_DRIVERID_LM87,
+	.flags		= I2C_DF_NOTIFY,
+	.attach_adapter	= lm87_attach_adapter,
+	.detach_client	= lm87_detach_client,
+};
+
+/*
+ * Client data (each client gets its own)
+ */
+
+struct lm87_data {
+	struct i2c_client client;
+	struct semaphore update_lock;
+	char valid; /* zero until following fields are valid */
+	unsigned long last_updated; /* In jiffies */
+
+	u8 channel;		/* register value */
+
+	u8 in[8];		/* register value */
+	u8 in_max[8];		/* register value */
+	u8 in_min[8];		/* register value */
+	u16 in_scale[8];
+
+	s8 temp[3];		/* register value */
+	s8 temp_high[3];	/* register value */
+	s8 temp_low[3];		/* register value */
+	s8 temp_crit_int;	/* min of two register values */
+	s8 temp_crit_ext;	/* min of two register values */
+
+	u8 fan[2];		/* register value */
+	u8 fan_min[2];		/* register value */
+	u8 fan_div[2];		/* register value, shifted right */
+	u8 aout;		/* register value */
+
+	u16 alarms;		/* register values, combined */
+	u8 vid;			/* register values, combined */
+	u8 vrm;
+};
+
+/*
+ * Sysfs stuff
+ */
+
+static inline int lm87_read_value(struct i2c_client *client, u8 reg)
+{
+	return i2c_smbus_read_byte_data(client, reg);
+}
+
+static inline int lm87_write_value(struct i2c_client *client, u8 reg, u8 value)
+{
+	return i2c_smbus_write_byte_data(client, reg, value);
+}
+
+#define show_in(offset) \
+static ssize_t show_in##offset##_input(struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+	struct lm87_data *data = lm87_update_device(dev); \
+	return sprintf(buf, "%u\n", IN_FROM_REG(data->in[offset], \
+		       data->in_scale[offset])); \
+} \
+static ssize_t show_in##offset##_min(struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+	struct lm87_data *data = lm87_update_device(dev); \
+	return sprintf(buf, "%u\n", IN_FROM_REG(data->in_min[offset], \
+		       data->in_scale[offset])); \
+} \
+static ssize_t show_in##offset##_max(struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+	struct lm87_data *data = lm87_update_device(dev); \
+	return sprintf(buf, "%u\n", IN_FROM_REG(data->in_max[offset], \
+		       data->in_scale[offset])); \
+} \
+static DEVICE_ATTR(in##offset##_input, S_IRUGO, \
+		show_in##offset##_input, NULL);
+show_in(0);
+show_in(1);
+show_in(2);
+show_in(3);
+show_in(4);
+show_in(5);
+show_in(6);
+show_in(7);
+
+static void set_in_min(struct device *dev, const char *buf, int nr)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm87_data *data = i2c_get_clientdata(client);
+	long val = simple_strtol(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->in_min[nr] = IN_TO_REG(val, data->in_scale[nr]);
+	lm87_write_value(client, nr<6 ? LM87_REG_IN_MIN(nr) :
+			 LM87_REG_AIN_MIN(nr-6), data->in_min[nr]);
+	up(&data->update_lock);
+}
+
+static void set_in_max(struct device *dev, const char *buf, int nr)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm87_data *data = i2c_get_clientdata(client);
+	long val = simple_strtol(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->in_max[nr] = IN_TO_REG(val, data->in_scale[nr]);
+	lm87_write_value(client, nr<6 ? LM87_REG_IN_MAX(nr) :
+			 LM87_REG_AIN_MAX(nr-6), data->in_max[nr]);
+	up(&data->update_lock);
+}
+
+#define set_in(offset) \
+static ssize_t set_in##offset##_min(struct device *dev, struct device_attribute *attr, \
+		const char *buf, size_t count) \
+{ \
+	set_in_min(dev, buf, offset); \
+	return count; \
+} \
+static ssize_t set_in##offset##_max(struct device *dev, struct device_attribute *attr, \
+		const char *buf, size_t count) \
+{ \
+	set_in_max(dev, buf, offset); \
+	return count; \
+} \
+static DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \
+		show_in##offset##_min, set_in##offset##_min); \
+static DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \
+		show_in##offset##_max, set_in##offset##_max);
+set_in(0);
+set_in(1);
+set_in(2);
+set_in(3);
+set_in(4);
+set_in(5);
+set_in(6);
+set_in(7);
+
+#define show_temp(offset) \
+static ssize_t show_temp##offset##_input(struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+	struct lm87_data *data = lm87_update_device(dev); \
+	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp[offset-1])); \
+} \
+static ssize_t show_temp##offset##_low(struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+	struct lm87_data *data = lm87_update_device(dev); \
+	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_low[offset-1])); \
+} \
+static ssize_t show_temp##offset##_high(struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+	struct lm87_data *data = lm87_update_device(dev); \
+	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_high[offset-1])); \
+}\
+static DEVICE_ATTR(temp##offset##_input, S_IRUGO, \
+		show_temp##offset##_input, NULL);
+show_temp(1);
+show_temp(2);
+show_temp(3);
+
+static void set_temp_low(struct device *dev, const char *buf, int nr)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm87_data *data = i2c_get_clientdata(client);
+	long val = simple_strtol(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->temp_low[nr] = TEMP_TO_REG(val);
+	lm87_write_value(client, LM87_REG_TEMP_LOW[nr], data->temp_low[nr]);
+	up(&data->update_lock);
+}
+
+static void set_temp_high(struct device *dev, const char *buf, int nr)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm87_data *data = i2c_get_clientdata(client);
+	long val = simple_strtol(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->temp_high[nr] = TEMP_TO_REG(val);
+	lm87_write_value(client, LM87_REG_TEMP_HIGH[nr], data->temp_high[nr]);
+	up(&data->update_lock);
+}
+
+#define set_temp(offset) \
+static ssize_t set_temp##offset##_low(struct device *dev, struct device_attribute *attr, \
+		const char *buf, size_t count) \
+{ \
+	set_temp_low(dev, buf, offset-1); \
+	return count; \
+} \
+static ssize_t set_temp##offset##_high(struct device *dev, struct device_attribute *attr, \
+		const char *buf, size_t count) \
+{ \
+	set_temp_high(dev, buf, offset-1); \
+	return count; \
+} \
+static DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR, \
+		show_temp##offset##_high, set_temp##offset##_high); \
+static DEVICE_ATTR(temp##offset##_min, S_IRUGO | S_IWUSR, \
+		show_temp##offset##_low, set_temp##offset##_low);
+set_temp(1);
+set_temp(2);
+set_temp(3);
+
+static ssize_t show_temp_crit_int(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct lm87_data *data = lm87_update_device(dev);
+	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_crit_int));
+}
+
+static ssize_t show_temp_crit_ext(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct lm87_data *data = lm87_update_device(dev);
+	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_crit_ext));
+}
+
+static DEVICE_ATTR(temp1_crit, S_IRUGO, show_temp_crit_int, NULL);
+static DEVICE_ATTR(temp2_crit, S_IRUGO, show_temp_crit_ext, NULL);
+static DEVICE_ATTR(temp3_crit, S_IRUGO, show_temp_crit_ext, NULL);
+
+#define show_fan(offset) \
+static ssize_t show_fan##offset##_input(struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+	struct lm87_data *data = lm87_update_device(dev); \
+	return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[offset-1], \
+		       FAN_DIV_FROM_REG(data->fan_div[offset-1]))); \
+} \
+static ssize_t show_fan##offset##_min(struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+	struct lm87_data *data = lm87_update_device(dev); \
+	return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan_min[offset-1], \
+		       FAN_DIV_FROM_REG(data->fan_div[offset-1]))); \
+} \
+static ssize_t show_fan##offset##_div(struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+	struct lm87_data *data = lm87_update_device(dev); \
+	return sprintf(buf, "%d\n", FAN_DIV_FROM_REG(data->fan_div[offset-1])); \
+} \
+static DEVICE_ATTR(fan##offset##_input, S_IRUGO, \
+		show_fan##offset##_input, NULL);
+show_fan(1);
+show_fan(2);
+
+static void set_fan_min(struct device *dev, const char *buf, int nr)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm87_data *data = i2c_get_clientdata(client);
+	long val = simple_strtol(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->fan_min[nr] = FAN_TO_REG(val,
+			    FAN_DIV_FROM_REG(data->fan_div[nr]));
+	lm87_write_value(client, LM87_REG_FAN_MIN(nr), data->fan_min[nr]);
+	up(&data->update_lock);
+}
+
+/* Note: we save and restore the fan minimum here, because its value is
+   determined in part by the fan clock divider.  This follows the principle
+   of least suprise; the user doesn't expect the fan minimum to change just
+   because the divider changed. */
+static ssize_t set_fan_div(struct device *dev, const char *buf,
+		size_t count, int nr)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm87_data *data = i2c_get_clientdata(client);
+	long val = simple_strtol(buf, NULL, 10);
+	unsigned long min;
+	u8 reg;
+
+	down(&data->update_lock);
+	min = FAN_FROM_REG(data->fan_min[nr],
+			   FAN_DIV_FROM_REG(data->fan_div[nr]));
+
+	switch (val) {
+	case 1: data->fan_div[nr] = 0; break;
+	case 2: data->fan_div[nr] = 1; break;
+	case 4: data->fan_div[nr] = 2; break;
+	case 8: data->fan_div[nr] = 3; break;
+	default:
+		up(&data->update_lock);
+		return -EINVAL;
+	}
+
+	reg = lm87_read_value(client, LM87_REG_VID_FAN_DIV);
+	switch (nr) {
+	case 0:
+	    reg = (reg & 0xCF) | (data->fan_div[0] << 4);
+	    break;
+	case 1:
+	    reg = (reg & 0x3F) | (data->fan_div[1] << 6);
+	    break;
+	}
+	lm87_write_value(client, LM87_REG_VID_FAN_DIV, reg);
+
+	data->fan_min[nr] = FAN_TO_REG(min, val);
+	lm87_write_value(client, LM87_REG_FAN_MIN(nr),
+			 data->fan_min[nr]);
+	up(&data->update_lock);
+
+	return count;
+}
+
+#define set_fan(offset) \
+static ssize_t set_fan##offset##_min(struct device *dev, struct device_attribute *attr, const char *buf, \
+		size_t count) \
+{ \
+	set_fan_min(dev, buf, offset-1); \
+	return count; \
+} \
+static ssize_t set_fan##offset##_div(struct device *dev, struct device_attribute *attr, const char *buf, \
+		size_t count) \
+{ \
+	return set_fan_div(dev, buf, count, offset-1); \
+} \
+static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \
+		show_fan##offset##_min, set_fan##offset##_min); \
+static DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, \
+		show_fan##offset##_div, set_fan##offset##_div);
+set_fan(1);
+set_fan(2);
+
+static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct lm87_data *data = lm87_update_device(dev);
+	return sprintf(buf, "%d\n", data->alarms);
+}
+static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
+
+static ssize_t show_vid(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct lm87_data *data = lm87_update_device(dev);
+	return sprintf(buf, "%d\n", vid_from_reg(data->vid, data->vrm));
+}
+static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL);
+
+static ssize_t show_vrm(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct lm87_data *data = lm87_update_device(dev);
+	return sprintf(buf, "%d\n", data->vrm);
+}
+static ssize_t set_vrm(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm87_data *data = i2c_get_clientdata(client);
+	data->vrm = simple_strtoul(buf, NULL, 10);
+	return count;
+}
+static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm, set_vrm);
+
+static ssize_t show_aout(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct lm87_data *data = lm87_update_device(dev);
+	return sprintf(buf, "%d\n", AOUT_FROM_REG(data->aout));
+}
+static ssize_t set_aout(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm87_data *data = i2c_get_clientdata(client);
+	long val = simple_strtol(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->aout = AOUT_TO_REG(val);
+	lm87_write_value(client, LM87_REG_AOUT, data->aout);
+	up(&data->update_lock);
+	return count;
+}
+static DEVICE_ATTR(aout_output, S_IRUGO | S_IWUSR, show_aout, set_aout);
+
+/*
+ * Real code
+ */
+
+static int lm87_attach_adapter(struct i2c_adapter *adapter)
+{
+	if (!(adapter->class & I2C_CLASS_HWMON))
+		return 0;
+	return i2c_detect(adapter, &addr_data, lm87_detect);
+}
+
+/*
+ * The following function does more than just detection. If detection
+ * succeeds, it also registers the new chip.
+ */
+static int lm87_detect(struct i2c_adapter *adapter, int address, int kind)
+{
+	struct i2c_client *new_client;
+	struct lm87_data *data;
+	int err = 0;
+
+	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+		goto exit;
+
+	if (!(data = kmalloc(sizeof(struct lm87_data), GFP_KERNEL))) {
+		err = -ENOMEM;
+		goto exit;
+	}
+	memset(data, 0, sizeof(struct lm87_data));
+
+	/* The common I2C client data is placed right before the
+	   LM87-specific data. */
+	new_client = &data->client;
+	i2c_set_clientdata(new_client, data);
+	new_client->addr = address;
+	new_client->adapter = adapter;
+	new_client->driver = &lm87_driver;
+	new_client->flags = 0;
+
+	/* Default to an LM87 if forced */
+	if (kind == 0)
+		kind = lm87;
+
+	/* Now, we do the remaining detection. */
+	if (kind < 0) {
+		u8 rev = lm87_read_value(new_client, LM87_REG_REVISION);
+
+		if (rev < 0x01 || rev > 0x08
+		 || (lm87_read_value(new_client, LM87_REG_CONFIG) & 0x80)
+		 || lm87_read_value(new_client, LM87_REG_COMPANY_ID) != 0x02) {
+			dev_dbg(&adapter->dev,
+				"LM87 detection failed at 0x%02x.\n",
+				address);
+			goto exit_free;
+		}
+	}
+
+	/* We can fill in the remaining client fields */
+	strlcpy(new_client->name, "lm87", I2C_NAME_SIZE);
+	data->valid = 0;
+	init_MUTEX(&data->update_lock);
+
+	/* Tell the I2C layer a new client has arrived */
+	if ((err = i2c_attach_client(new_client)))
+		goto exit_free;
+
+	/* Initialize the LM87 chip */
+	lm87_init_client(new_client);
+
+	data->in_scale[0] = 2500;
+	data->in_scale[1] = 2700;
+	data->in_scale[2] = (data->channel & CHAN_VCC_5V) ? 5000 : 3300;
+	data->in_scale[3] = 5000;
+	data->in_scale[4] = 12000;
+	data->in_scale[5] = 2700;
+	data->in_scale[6] = 1875;
+	data->in_scale[7] = 1875;
+
+	/* Register sysfs hooks */
+	device_create_file(&new_client->dev, &dev_attr_in1_input);
+	device_create_file(&new_client->dev, &dev_attr_in1_min);
+	device_create_file(&new_client->dev, &dev_attr_in1_max);
+	device_create_file(&new_client->dev, &dev_attr_in2_input);
+	device_create_file(&new_client->dev, &dev_attr_in2_min);
+	device_create_file(&new_client->dev, &dev_attr_in2_max);
+	device_create_file(&new_client->dev, &dev_attr_in3_input);
+	device_create_file(&new_client->dev, &dev_attr_in3_min);
+	device_create_file(&new_client->dev, &dev_attr_in3_max);
+	device_create_file(&new_client->dev, &dev_attr_in4_input);
+	device_create_file(&new_client->dev, &dev_attr_in4_min);
+	device_create_file(&new_client->dev, &dev_attr_in4_max);
+
+	if (data->channel & CHAN_NO_FAN(0)) {
+		device_create_file(&new_client->dev, &dev_attr_in6_input);
+		device_create_file(&new_client->dev, &dev_attr_in6_min);
+		device_create_file(&new_client->dev, &dev_attr_in6_max);
+	} else {
+		device_create_file(&new_client->dev, &dev_attr_fan1_input);
+		device_create_file(&new_client->dev, &dev_attr_fan1_min);
+		device_create_file(&new_client->dev, &dev_attr_fan1_div);
+	}
+	if (data->channel & CHAN_NO_FAN(1)) {
+		device_create_file(&new_client->dev, &dev_attr_in7_input);
+		device_create_file(&new_client->dev, &dev_attr_in7_min);
+		device_create_file(&new_client->dev, &dev_attr_in7_max);
+	} else {
+		device_create_file(&new_client->dev, &dev_attr_fan2_input);
+		device_create_file(&new_client->dev, &dev_attr_fan2_min);
+		device_create_file(&new_client->dev, &dev_attr_fan2_div);
+	}
+
+	device_create_file(&new_client->dev, &dev_attr_temp1_input);
+	device_create_file(&new_client->dev, &dev_attr_temp1_max);
+	device_create_file(&new_client->dev, &dev_attr_temp1_min);
+	device_create_file(&new_client->dev, &dev_attr_temp1_crit);
+	device_create_file(&new_client->dev, &dev_attr_temp2_input);
+	device_create_file(&new_client->dev, &dev_attr_temp2_max);
+	device_create_file(&new_client->dev, &dev_attr_temp2_min);
+	device_create_file(&new_client->dev, &dev_attr_temp2_crit);
+
+	if (data->channel & CHAN_TEMP3) {
+		device_create_file(&new_client->dev, &dev_attr_temp3_input);
+		device_create_file(&new_client->dev, &dev_attr_temp3_max);
+		device_create_file(&new_client->dev, &dev_attr_temp3_min);
+		device_create_file(&new_client->dev, &dev_attr_temp3_crit);
+	} else {
+		device_create_file(&new_client->dev, &dev_attr_in0_input);
+		device_create_file(&new_client->dev, &dev_attr_in0_min);
+		device_create_file(&new_client->dev, &dev_attr_in0_max);
+		device_create_file(&new_client->dev, &dev_attr_in5_input);
+		device_create_file(&new_client->dev, &dev_attr_in5_min);
+		device_create_file(&new_client->dev, &dev_attr_in5_max);
+	}
+
+	if (!(data->channel & CHAN_NO_VID)) {
+		device_create_file(&new_client->dev, &dev_attr_cpu0_vid);
+		device_create_file(&new_client->dev, &dev_attr_vrm);
+	}
+
+	device_create_file(&new_client->dev, &dev_attr_alarms);
+	device_create_file(&new_client->dev, &dev_attr_aout_output);
+
+	return 0;
+
+exit_free:
+	kfree(data);
+exit:
+	return err;
+}
+
+static void lm87_init_client(struct i2c_client *client)
+{
+	struct lm87_data *data = i2c_get_clientdata(client);
+	u8 config;
+
+	data->channel = lm87_read_value(client, LM87_REG_CHANNEL_MODE);
+	data->vrm = i2c_which_vrm();
+
+	config = lm87_read_value(client, LM87_REG_CONFIG);
+	if (!(config & 0x01)) {
+		int i;
+
+		/* Limits are left uninitialized after power-up */
+		for (i = 1; i < 6; i++) {
+			lm87_write_value(client, LM87_REG_IN_MIN(i), 0x00);
+			lm87_write_value(client, LM87_REG_IN_MAX(i), 0xFF);
+		}
+		for (i = 0; i < 2; i++) {
+			lm87_write_value(client, LM87_REG_TEMP_HIGH[i], 0x7F);
+			lm87_write_value(client, LM87_REG_TEMP_LOW[i], 0x00);
+			lm87_write_value(client, LM87_REG_AIN_MIN(i), 0x00);
+			lm87_write_value(client, LM87_REG_AIN_MAX(i), 0xFF);
+		}
+		if (data->channel & CHAN_TEMP3) {
+			lm87_write_value(client, LM87_REG_TEMP_HIGH[2], 0x7F);
+			lm87_write_value(client, LM87_REG_TEMP_LOW[2], 0x00);
+		} else {
+			lm87_write_value(client, LM87_REG_IN_MIN(0), 0x00);
+			lm87_write_value(client, LM87_REG_IN_MAX(0), 0xFF);
+		}
+	}
+	if ((config & 0x81) != 0x01) {
+		/* Start monitoring */
+		lm87_write_value(client, LM87_REG_CONFIG,
+				 (config & 0xF7) | 0x01);
+	}
+}
+
+static int lm87_detach_client(struct i2c_client *client)
+{
+	int err;
+
+	if ((err = i2c_detach_client(client))) {
+		dev_err(&client->dev, "Client deregistration failed, "
+			"client not detached.\n");
+		return err;
+	}
+
+	kfree(i2c_get_clientdata(client));
+	return 0;
+}
+
+static struct lm87_data *lm87_update_device(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm87_data *data = i2c_get_clientdata(client);
+
+	down(&data->update_lock);
+
+	if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
+		int i, j;
+
+		dev_dbg(&client->dev, "Updating data.\n");
+
+		i = (data->channel & CHAN_TEMP3) ? 1 : 0;
+		j = (data->channel & CHAN_TEMP3) ? 5 : 6;
+		for (; i < j; i++) {
+			data->in[i] = lm87_read_value(client,
+				      LM87_REG_IN(i));
+			data->in_min[i] = lm87_read_value(client,
+					  LM87_REG_IN_MIN(i));
+			data->in_max[i] = lm87_read_value(client,
+					  LM87_REG_IN_MAX(i));
+		}
+
+		for (i = 0; i < 2; i++) {
+			if (data->channel & CHAN_NO_FAN(i)) {
+				data->in[6+i] = lm87_read_value(client,
+						LM87_REG_AIN(i));
+				data->in_max[6+i] = lm87_read_value(client,
+						    LM87_REG_AIN_MAX(i));
+				data->in_min[6+i] = lm87_read_value(client,
+						    LM87_REG_AIN_MIN(i));
+
+			} else {
+				data->fan[i] = lm87_read_value(client,
+					       LM87_REG_FAN(i));
+				data->fan_min[i] = lm87_read_value(client,
+						   LM87_REG_FAN_MIN(i));
+			}
+		}
+
+		j = (data->channel & CHAN_TEMP3) ? 3 : 2;
+		for (i = 0 ; i < j; i++) {
+			data->temp[i] = lm87_read_value(client,
+					LM87_REG_TEMP[i]);
+			data->temp_high[i] = lm87_read_value(client,
+					     LM87_REG_TEMP_HIGH[i]);
+			data->temp_low[i] = lm87_read_value(client,
+					    LM87_REG_TEMP_LOW[i]);
+		}
+
+		i = lm87_read_value(client, LM87_REG_TEMP_HW_INT_LOCK);
+		j = lm87_read_value(client, LM87_REG_TEMP_HW_INT);
+		data->temp_crit_int = min(i, j);
+
+		i = lm87_read_value(client, LM87_REG_TEMP_HW_EXT_LOCK);
+		j = lm87_read_value(client, LM87_REG_TEMP_HW_EXT);
+		data->temp_crit_ext = min(i, j);
+
+		i = lm87_read_value(client, LM87_REG_VID_FAN_DIV);
+		data->fan_div[0] = (i >> 4) & 0x03;
+		data->fan_div[1] = (i >> 6) & 0x03;
+		data->vid = (i & 0x0F)
+			  | (lm87_read_value(client, LM87_REG_VID4) & 0x01)
+			     << 4;
+
+		data->alarms = lm87_read_value(client, LM87_REG_ALARMS1)
+			     | (lm87_read_value(client, LM87_REG_ALARMS2)
+				<< 8);
+		data->aout = lm87_read_value(client, LM87_REG_AOUT);
+
+		data->last_updated = jiffies;
+		data->valid = 1;
+	}
+
+	up(&data->update_lock);
+
+	return data;
+}
+
+static int __init sensors_lm87_init(void)
+{
+	return i2c_add_driver(&lm87_driver);
+}
+
+static void __exit sensors_lm87_exit(void)
+{
+	i2c_del_driver(&lm87_driver);
+}
+
+MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org> and others");
+MODULE_DESCRIPTION("LM87 driver");
+MODULE_LICENSE("GPL");
+
+module_init(sensors_lm87_init);
+module_exit(sensors_lm87_exit);
diff --git a/drivers/hwmon/lm90.c b/drivers/hwmon/lm90.c
new file mode 100644
--- /dev/null
+++ b/drivers/hwmon/lm90.c
@@ -0,0 +1,655 @@
+/*
+ * lm90.c - Part of lm_sensors, Linux kernel modules for hardware
+ *          monitoring
+ * Copyright (C) 2003-2005  Jean Delvare <khali@linux-fr.org>
+ *
+ * Based on the lm83 driver. The LM90 is a sensor chip made by National
+ * Semiconductor. It reports up to two temperatures (its own plus up to
+ * one external one) with a 0.125 deg resolution (1 deg for local
+ * temperature) and a 3-4 deg accuracy. Complete datasheet can be
+ * obtained from National's website at:
+ *   http://www.national.com/pf/LM/LM90.html
+ *
+ * This driver also supports the LM89 and LM99, two other sensor chips
+ * made by National Semiconductor. Both have an increased remote
+ * temperature measurement accuracy (1 degree), and the LM99
+ * additionally shifts remote temperatures (measured and limits) by 16
+ * degrees, which allows for higher temperatures measurement. The
+ * driver doesn't handle it since it can be done easily in user-space.
+ * Complete datasheets can be obtained from National's website at:
+ *   http://www.national.com/pf/LM/LM89.html
+ *   http://www.national.com/pf/LM/LM99.html
+ * Note that there is no way to differentiate between both chips.
+ *
+ * This driver also supports the LM86, another sensor chip made by
+ * National Semiconductor. It is exactly similar to the LM90 except it
+ * has a higher accuracy.
+ * Complete datasheet can be obtained from National's website at:
+ *   http://www.national.com/pf/LM/LM86.html
+ *
+ * This driver also supports the ADM1032, a sensor chip made by Analog
+ * Devices. That chip is similar to the LM90, with a few differences
+ * that are not handled by this driver. Complete datasheet can be
+ * obtained from Analog's website at:
+ *   http://products.analog.com/products/info.asp?product=ADM1032
+ * Among others, it has a higher accuracy than the LM90, much like the
+ * LM86 does.
+ *
+ * This driver also supports the MAX6657, MAX6658 and MAX6659 sensor
+ * chips made by Maxim. These chips are similar to the LM86. Complete
+ * datasheet can be obtained at Maxim's website at:
+ *   http://www.maxim-ic.com/quick_view2.cfm/qv_pk/2578
+ * Note that there is no easy way to differentiate between the three
+ * variants. The extra address and features of the MAX6659 are not
+ * supported by this driver.
+ *
+ * This driver also supports the ADT7461 chip from Analog Devices but
+ * only in its "compatability mode". If an ADT7461 chip is found but
+ * is configured in non-compatible mode (where its temperature
+ * register values are decoded differently) it is ignored by this
+ * driver. Complete datasheet can be obtained from Analog's website
+ * at:
+ *   http://products.analog.com/products/info.asp?product=ADT7461
+ *
+ * Since the LM90 was the first chipset supported by this driver, most
+ * comments will refer to this chipset, but are actually general and
+ * concern all supported chipsets, unless mentioned otherwise.
+ *
+ * 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 <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+#include <linux/i2c.h>
+#include <linux/i2c-sensor.h>
+#include <linux/hwmon-sysfs.h>
+
+/*
+ * Addresses to scan
+ * Address is fully defined internally and cannot be changed except for
+ * MAX6659.
+ * LM86, LM89, LM90, LM99, ADM1032, MAX6657 and MAX6658 have address 0x4c.
+ * LM89-1, and LM99-1 have address 0x4d.
+ * MAX6659 can have address 0x4c, 0x4d or 0x4e (unsupported).
+ * ADT7461 always has address 0x4c.
+ */
+
+static unsigned short normal_i2c[] = { 0x4c, 0x4d, I2C_CLIENT_END };
+static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
+
+/*
+ * Insmod parameters
+ */
+
+SENSORS_INSMOD_6(lm90, adm1032, lm99, lm86, max6657, adt7461);
+
+/*
+ * The LM90 registers
+ */
+
+#define LM90_REG_R_MAN_ID		0xFE
+#define LM90_REG_R_CHIP_ID		0xFF
+#define LM90_REG_R_CONFIG1		0x03
+#define LM90_REG_W_CONFIG1		0x09
+#define LM90_REG_R_CONFIG2		0xBF
+#define LM90_REG_W_CONFIG2		0xBF
+#define LM90_REG_R_CONVRATE		0x04
+#define LM90_REG_W_CONVRATE		0x0A
+#define LM90_REG_R_STATUS		0x02
+#define LM90_REG_R_LOCAL_TEMP		0x00
+#define LM90_REG_R_LOCAL_HIGH		0x05
+#define LM90_REG_W_LOCAL_HIGH		0x0B
+#define LM90_REG_R_LOCAL_LOW		0x06
+#define LM90_REG_W_LOCAL_LOW		0x0C
+#define LM90_REG_R_LOCAL_CRIT		0x20
+#define LM90_REG_W_LOCAL_CRIT		0x20
+#define LM90_REG_R_REMOTE_TEMPH		0x01
+#define LM90_REG_R_REMOTE_TEMPL		0x10
+#define LM90_REG_R_REMOTE_OFFSH		0x11
+#define LM90_REG_W_REMOTE_OFFSH		0x11
+#define LM90_REG_R_REMOTE_OFFSL		0x12
+#define LM90_REG_W_REMOTE_OFFSL		0x12
+#define LM90_REG_R_REMOTE_HIGHH		0x07
+#define LM90_REG_W_REMOTE_HIGHH		0x0D
+#define LM90_REG_R_REMOTE_HIGHL		0x13
+#define LM90_REG_W_REMOTE_HIGHL		0x13
+#define LM90_REG_R_REMOTE_LOWH		0x08
+#define LM90_REG_W_REMOTE_LOWH		0x0E
+#define LM90_REG_R_REMOTE_LOWL		0x14
+#define LM90_REG_W_REMOTE_LOWL		0x14
+#define LM90_REG_R_REMOTE_CRIT		0x19
+#define LM90_REG_W_REMOTE_CRIT		0x19
+#define LM90_REG_R_TCRIT_HYST		0x21
+#define LM90_REG_W_TCRIT_HYST		0x21
+
+/*
+ * Conversions and various macros
+ * For local temperatures and limits, critical limits and the hysteresis
+ * value, the LM90 uses signed 8-bit values with LSB = 1 degree Celsius.
+ * For remote temperatures and limits, it uses signed 11-bit values with
+ * LSB = 0.125 degree Celsius, left-justified in 16-bit registers.
+ */
+
+#define TEMP1_FROM_REG(val)	((val) * 1000)
+#define TEMP1_TO_REG(val)	((val) <= -128000 ? -128 : \
+				 (val) >= 127000 ? 127 : \
+				 (val) < 0 ? ((val) - 500) / 1000 : \
+				 ((val) + 500) / 1000)
+#define TEMP2_FROM_REG(val)	((val) / 32 * 125)
+#define TEMP2_TO_REG(val)	((val) <= -128000 ? 0x8000 : \
+				 (val) >= 127875 ? 0x7FE0 : \
+				 (val) < 0 ? ((val) - 62) / 125 * 32 : \
+				 ((val) + 62) / 125 * 32)
+#define HYST_TO_REG(val)	((val) <= 0 ? 0 : (val) >= 30500 ? 31 : \
+				 ((val) + 500) / 1000)
+
+/* 
+ * ADT7461 is almost identical to LM90 except that attempts to write
+ * values that are outside the range 0 < temp < 127 are treated as
+ * the boundary value. 
+ */
+
+#define TEMP1_TO_REG_ADT7461(val) ((val) <= 0 ? 0 : \
+				 (val) >= 127000 ? 127 : \
+				 ((val) + 500) / 1000)
+#define TEMP2_TO_REG_ADT7461(val) ((val) <= 0 ? 0 : \
+				 (val) >= 127750 ? 0x7FC0 : \
+				 ((val) + 125) / 250 * 64)
+
+/*
+ * Functions declaration
+ */
+
+static int lm90_attach_adapter(struct i2c_adapter *adapter);
+static int lm90_detect(struct i2c_adapter *adapter, int address,
+	int kind);
+static void lm90_init_client(struct i2c_client *client);
+static int lm90_detach_client(struct i2c_client *client);
+static struct lm90_data *lm90_update_device(struct device *dev);
+
+/*
+ * Driver data (common to all clients)
+ */
+
+static struct i2c_driver lm90_driver = {
+	.owner		= THIS_MODULE,
+	.name		= "lm90",
+	.id		= I2C_DRIVERID_LM90,
+	.flags		= I2C_DF_NOTIFY,
+	.attach_adapter	= lm90_attach_adapter,
+	.detach_client	= lm90_detach_client,
+};
+
+/*
+ * Client data (each client gets its own)
+ */
+
+struct lm90_data {
+	struct i2c_client client;
+	struct semaphore update_lock;
+	char valid; /* zero until following fields are valid */
+	unsigned long last_updated; /* in jiffies */
+	int kind;
+
+	/* registers values */
+	s8 temp8[5];	/* 0: local input
+			   1: local low limit
+			   2: local high limit
+			   3: local critical limit
+			   4: remote critical limit */
+	s16 temp11[3];	/* 0: remote input
+			   1: remote low limit
+			   2: remote high limit */
+	u8 temp_hyst;
+	u8 alarms; /* bitvector */
+};
+
+/*
+ * Sysfs stuff
+ */
+
+static ssize_t show_temp8(struct device *dev, struct device_attribute *devattr,
+			  char *buf)
+{
+	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+	struct lm90_data *data = lm90_update_device(dev);
+	return sprintf(buf, "%d\n", TEMP1_FROM_REG(data->temp8[attr->index]));
+}
+
+static ssize_t set_temp8(struct device *dev, struct device_attribute *devattr,
+			 const char *buf, size_t count)
+{
+	static const u8 reg[4] = {
+		LM90_REG_W_LOCAL_LOW,
+		LM90_REG_W_LOCAL_HIGH,
+		LM90_REG_W_LOCAL_CRIT,
+		LM90_REG_W_REMOTE_CRIT,
+	};
+
+	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm90_data *data = i2c_get_clientdata(client);
+	long val = simple_strtol(buf, NULL, 10);
+	int nr = attr->index;
+
+	down(&data->update_lock);
+	if (data->kind == adt7461)
+		data->temp8[nr] = TEMP1_TO_REG_ADT7461(val);
+	else
+		data->temp8[nr] = TEMP1_TO_REG(val);
+	i2c_smbus_write_byte_data(client, reg[nr - 1], data->temp8[nr]);
+	up(&data->update_lock);
+	return count;
+}
+
+static ssize_t show_temp11(struct device *dev, struct device_attribute *devattr,
+			   char *buf)
+{
+	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+	struct lm90_data *data = lm90_update_device(dev);
+	return sprintf(buf, "%d\n", TEMP2_FROM_REG(data->temp11[attr->index]));
+}
+
+static ssize_t set_temp11(struct device *dev, struct device_attribute *devattr,
+			  const char *buf, size_t count)
+{
+	static const u8 reg[4] = {
+		LM90_REG_W_REMOTE_LOWH,
+		LM90_REG_W_REMOTE_LOWL,
+		LM90_REG_W_REMOTE_HIGHH,
+		LM90_REG_W_REMOTE_HIGHL,
+	};
+
+	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm90_data *data = i2c_get_clientdata(client);
+	long val = simple_strtol(buf, NULL, 10);
+	int nr = attr->index;
+
+	down(&data->update_lock);
+	if (data->kind == adt7461)
+		data->temp11[nr] = TEMP2_TO_REG_ADT7461(val);
+	else
+		data->temp11[nr] = TEMP2_TO_REG(val);
+	i2c_smbus_write_byte_data(client, reg[(nr - 1) * 2],
+				  data->temp11[nr] >> 8);
+	i2c_smbus_write_byte_data(client, reg[(nr - 1) * 2 + 1],
+				  data->temp11[nr] & 0xff);
+	up(&data->update_lock);
+	return count;
+}
+
+static ssize_t show_temphyst(struct device *dev, struct device_attribute *devattr,
+			     char *buf)
+{
+	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+	struct lm90_data *data = lm90_update_device(dev);
+	return sprintf(buf, "%d\n", TEMP1_FROM_REG(data->temp8[attr->index])
+		       - TEMP1_FROM_REG(data->temp_hyst));
+}
+
+static ssize_t set_temphyst(struct device *dev, struct device_attribute *dummy,
+			    const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm90_data *data = i2c_get_clientdata(client);
+	long val = simple_strtol(buf, NULL, 10);
+	long hyst;
+
+	down(&data->update_lock);
+	hyst = TEMP1_FROM_REG(data->temp8[3]) - val;
+	i2c_smbus_write_byte_data(client, LM90_REG_W_TCRIT_HYST,
+				  HYST_TO_REG(hyst));
+	up(&data->update_lock);
+	return count;
+}
+
+static ssize_t show_alarms(struct device *dev, struct device_attribute *dummy,
+			   char *buf)
+{
+	struct lm90_data *data = lm90_update_device(dev);
+	return sprintf(buf, "%d\n", data->alarms);
+}
+
+static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp8, NULL, 0);
+static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp11, NULL, 0);
+static SENSOR_DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, show_temp8,
+	set_temp8, 1);
+static SENSOR_DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_temp11,
+	set_temp11, 1);
+static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp8,
+	set_temp8, 2);
+static SENSOR_DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_temp11,
+	set_temp11, 2);
+static SENSOR_DEVICE_ATTR(temp1_crit, S_IWUSR | S_IRUGO, show_temp8,
+	set_temp8, 3);
+static SENSOR_DEVICE_ATTR(temp2_crit, S_IWUSR | S_IRUGO, show_temp8,
+	set_temp8, 4);
+static SENSOR_DEVICE_ATTR(temp1_crit_hyst, S_IWUSR | S_IRUGO, show_temphyst,
+	set_temphyst, 3);
+static SENSOR_DEVICE_ATTR(temp2_crit_hyst, S_IRUGO, show_temphyst, NULL, 4);
+static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
+
+/*
+ * Real code
+ */
+
+static int lm90_attach_adapter(struct i2c_adapter *adapter)
+{
+	if (!(adapter->class & I2C_CLASS_HWMON))
+		return 0;
+	return i2c_detect(adapter, &addr_data, lm90_detect);
+}
+
+/*
+ * The following function does more than just detection. If detection
+ * succeeds, it also registers the new chip.
+ */
+static int lm90_detect(struct i2c_adapter *adapter, int address, int kind)
+{
+	struct i2c_client *new_client;
+	struct lm90_data *data;
+	int err = 0;
+	const char *name = "";
+
+	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+		goto exit;
+
+	if (!(data = kmalloc(sizeof(struct lm90_data), GFP_KERNEL))) {
+		err = -ENOMEM;
+		goto exit;
+	}
+	memset(data, 0, sizeof(struct lm90_data));
+
+	/* The common I2C client data is placed right before the
+	   LM90-specific data. */
+	new_client = &data->client;
+	i2c_set_clientdata(new_client, data);
+	new_client->addr = address;
+	new_client->adapter = adapter;
+	new_client->driver = &lm90_driver;
+	new_client->flags = 0;
+
+	/*
+	 * Now we do the remaining detection. A negative kind means that
+	 * the driver was loaded with no force parameter (default), so we
+	 * must both detect and identify the chip. A zero kind means that
+	 * the driver was loaded with the force parameter, the detection
+	 * step shall be skipped. A positive kind means that the driver
+	 * was loaded with the force parameter and a given kind of chip is
+	 * requested, so both the detection and the identification steps
+	 * are skipped.
+	 */
+
+	/* Default to an LM90 if forced */
+	if (kind == 0)
+		kind = lm90;
+
+	if (kind < 0) { /* detection and identification */
+		u8 man_id, chip_id, reg_config1, reg_convrate;
+
+		man_id = i2c_smbus_read_byte_data(new_client,
+			 LM90_REG_R_MAN_ID);
+		chip_id = i2c_smbus_read_byte_data(new_client,
+			  LM90_REG_R_CHIP_ID);
+		reg_config1 = i2c_smbus_read_byte_data(new_client,
+			      LM90_REG_R_CONFIG1);
+		reg_convrate = i2c_smbus_read_byte_data(new_client,
+			       LM90_REG_R_CONVRATE);
+		
+		if (man_id == 0x01) { /* National Semiconductor */
+			u8 reg_config2;
+
+			reg_config2 = i2c_smbus_read_byte_data(new_client,
+				      LM90_REG_R_CONFIG2);
+
+			if ((reg_config1 & 0x2A) == 0x00
+			 && (reg_config2 & 0xF8) == 0x00
+			 && reg_convrate <= 0x09) {
+				if (address == 0x4C
+				 && (chip_id & 0xF0) == 0x20) { /* LM90 */
+					kind = lm90;
+				} else
+				if ((chip_id & 0xF0) == 0x30) { /* LM89/LM99 */
+					kind = lm99;
+				} else
+				if (address == 0x4C
+				 && (chip_id & 0xF0) == 0x10) { /* LM86 */
+					kind = lm86;
+				}
+			}
+		} else
+		if (man_id == 0x41) { /* Analog Devices */
+			if (address == 0x4C
+			 && (chip_id & 0xF0) == 0x40 /* ADM1032 */
+			 && (reg_config1 & 0x3F) == 0x00
+			 && reg_convrate <= 0x0A) {
+				kind = adm1032;
+			} else
+			if (address == 0x4c
+			 && chip_id == 0x51 /* ADT7461 */
+			 && (reg_config1 & 0x1F) == 0x00 /* check compat mode */
+			 && reg_convrate <= 0x0A) {
+				kind = adt7461;
+			}
+		} else
+		if (man_id == 0x4D) { /* Maxim */
+			/*
+			 * The Maxim variants do NOT have a chip_id register.
+			 * Reading from that address will return the last read
+			 * value, which in our case is those of the man_id
+			 * register. Likewise, the config1 register seems to
+			 * lack a low nibble, so the value will be those of the
+			 * previous read, so in our case those of the man_id
+			 * register.
+			 */
+			if (chip_id == man_id
+			 && (reg_config1 & 0x1F) == (man_id & 0x0F)
+			 && reg_convrate <= 0x09) {
+			 	kind = max6657;
+			}
+		}
+
+		if (kind <= 0) { /* identification failed */
+			dev_info(&adapter->dev,
+			    "Unsupported chip (man_id=0x%02X, "
+			    "chip_id=0x%02X).\n", man_id, chip_id);
+			goto exit_free;
+		}
+	}
+
+	if (kind == lm90) {
+		name = "lm90";
+	} else if (kind == adm1032) {
+		name = "adm1032";
+	} else if (kind == lm99) {
+		name = "lm99";
+	} else if (kind == lm86) {
+		name = "lm86";
+	} else if (kind == max6657) {
+		name = "max6657";
+	} else if (kind == adt7461) {
+		name = "adt7461";
+	}
+
+	/* We can fill in the remaining client fields */
+	strlcpy(new_client->name, name, I2C_NAME_SIZE);
+	data->valid = 0;
+	data->kind = kind;
+	init_MUTEX(&data->update_lock);
+
+	/* Tell the I2C layer a new client has arrived */
+	if ((err = i2c_attach_client(new_client)))
+		goto exit_free;
+
+	/* Initialize the LM90 chip */
+	lm90_init_client(new_client);
+
+	/* Register sysfs hooks */
+	device_create_file(&new_client->dev,
+			   &sensor_dev_attr_temp1_input.dev_attr);
+	device_create_file(&new_client->dev,
+			   &sensor_dev_attr_temp2_input.dev_attr);
+	device_create_file(&new_client->dev,
+			   &sensor_dev_attr_temp1_min.dev_attr);
+	device_create_file(&new_client->dev,
+			   &sensor_dev_attr_temp2_min.dev_attr);
+	device_create_file(&new_client->dev,
+			   &sensor_dev_attr_temp1_max.dev_attr);
+	device_create_file(&new_client->dev,
+			   &sensor_dev_attr_temp2_max.dev_attr);
+	device_create_file(&new_client->dev,
+			   &sensor_dev_attr_temp1_crit.dev_attr);
+	device_create_file(&new_client->dev,
+			   &sensor_dev_attr_temp2_crit.dev_attr);
+	device_create_file(&new_client->dev,
+			   &sensor_dev_attr_temp1_crit_hyst.dev_attr);
+	device_create_file(&new_client->dev,
+			   &sensor_dev_attr_temp2_crit_hyst.dev_attr);
+	device_create_file(&new_client->dev, &dev_attr_alarms);
+
+	return 0;
+
+exit_free:
+	kfree(data);
+exit:
+	return err;
+}
+
+static void lm90_init_client(struct i2c_client *client)
+{
+	u8 config;
+
+	/*
+	 * Start the conversions.
+	 */
+	i2c_smbus_write_byte_data(client, LM90_REG_W_CONVRATE,
+				  5); /* 2 Hz */
+	config = i2c_smbus_read_byte_data(client, LM90_REG_R_CONFIG1);
+	if (config & 0x40)
+		i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1,
+					  config & 0xBF); /* run */
+}
+
+static int lm90_detach_client(struct i2c_client *client)
+{
+	int err;
+
+	if ((err = i2c_detach_client(client))) {
+		dev_err(&client->dev, "Client deregistration failed, "
+			"client not detached.\n");
+		return err;
+	}
+
+	kfree(i2c_get_clientdata(client));
+	return 0;
+}
+
+static struct lm90_data *lm90_update_device(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm90_data *data = i2c_get_clientdata(client);
+
+	down(&data->update_lock);
+
+	if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) {
+		u8 oldh, newh;
+
+		dev_dbg(&client->dev, "Updating lm90 data.\n");
+		data->temp8[0] = i2c_smbus_read_byte_data(client,
+				 LM90_REG_R_LOCAL_TEMP);
+		data->temp8[1] = i2c_smbus_read_byte_data(client,
+				 LM90_REG_R_LOCAL_LOW);
+		data->temp8[2] = i2c_smbus_read_byte_data(client,
+				 LM90_REG_R_LOCAL_HIGH);
+		data->temp8[3] = i2c_smbus_read_byte_data(client,
+				 LM90_REG_R_LOCAL_CRIT);
+		data->temp8[4] = i2c_smbus_read_byte_data(client,
+				 LM90_REG_R_REMOTE_CRIT);
+		data->temp_hyst = i2c_smbus_read_byte_data(client,
+				  LM90_REG_R_TCRIT_HYST);
+
+		/*
+		 * There is a trick here. We have to read two registers to
+		 * have the remote sensor temperature, but we have to beware
+		 * a conversion could occur inbetween the readings. The
+		 * datasheet says we should either use the one-shot
+		 * conversion register, which we don't want to do (disables
+		 * hardware monitoring) or monitor the busy bit, which is
+		 * impossible (we can't read the values and monitor that bit
+		 * at the exact same time). So the solution used here is to
+		 * read the high byte once, then the low byte, then the high
+		 * byte again. If the new high byte matches the old one,
+		 * then we have a valid reading. Else we have to read the low
+		 * byte again, and now we believe we have a correct reading.
+		 */
+		oldh = i2c_smbus_read_byte_data(client,
+		       LM90_REG_R_REMOTE_TEMPH);
+		data->temp11[0] = i2c_smbus_read_byte_data(client,
+				  LM90_REG_R_REMOTE_TEMPL);
+		newh = i2c_smbus_read_byte_data(client,
+		       LM90_REG_R_REMOTE_TEMPH);
+		if (newh != oldh) {
+			data->temp11[0] = i2c_smbus_read_byte_data(client,
+					  LM90_REG_R_REMOTE_TEMPL);
+#ifdef DEBUG
+			oldh = i2c_smbus_read_byte_data(client,
+			       LM90_REG_R_REMOTE_TEMPH);
+			/* oldh is actually newer */
+			if (newh != oldh)
+				dev_warn(&client->dev, "Remote temperature may be "
+					 "wrong.\n");
+#endif
+		}
+		data->temp11[0] |= (newh << 8);
+
+		data->temp11[1] = (i2c_smbus_read_byte_data(client,
+				   LM90_REG_R_REMOTE_LOWH) << 8) +
+				   i2c_smbus_read_byte_data(client,
+				   LM90_REG_R_REMOTE_LOWL);
+		data->temp11[2] = (i2c_smbus_read_byte_data(client,
+				   LM90_REG_R_REMOTE_HIGHH) << 8) +
+				   i2c_smbus_read_byte_data(client,
+				   LM90_REG_R_REMOTE_HIGHL);
+		data->alarms = i2c_smbus_read_byte_data(client,
+			       LM90_REG_R_STATUS);
+
+		data->last_updated = jiffies;
+		data->valid = 1;
+	}
+
+	up(&data->update_lock);
+
+	return data;
+}
+
+static int __init sensors_lm90_init(void)
+{
+	return i2c_add_driver(&lm90_driver);
+}
+
+static void __exit sensors_lm90_exit(void)
+{
+	i2c_del_driver(&lm90_driver);
+}
+
+MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>");
+MODULE_DESCRIPTION("LM90/ADM1032 driver");
+MODULE_LICENSE("GPL");
+
+module_init(sensors_lm90_init);
+module_exit(sensors_lm90_exit);
diff --git a/drivers/hwmon/lm92.c b/drivers/hwmon/lm92.c
new file mode 100644
--- /dev/null
+++ b/drivers/hwmon/lm92.c
@@ -0,0 +1,429 @@
+/*
+ * lm92 - Hardware monitoring driver
+ * Copyright (C) 2005  Jean Delvare <khali@linux-fr.org>
+ *
+ * Based on the lm90 driver, with some ideas taken from the lm_sensors
+ * lm92 driver as well.
+ *
+ * The LM92 is a sensor chip made by National Semiconductor. It reports
+ * its own temperature with a 0.0625 deg resolution and a 0.33 deg
+ * accuracy. Complete datasheet can be obtained from National's website
+ * at:
+ *   http://www.national.com/pf/LM/LM92.html
+ *
+ * This driver also supports the MAX6635 sensor chip made by Maxim.
+ * This chip is compatible with the LM92, but has a lesser accuracy
+ * (1.0 deg). Complete datasheet can be obtained from Maxim's website
+ * at:
+ *   http://www.maxim-ic.com/quick_view2.cfm/qv_pk/3074
+ *
+ * Since the LM92 was the first chipset supported by this driver, most
+ * comments will refer to this chipset, but are actually general and
+ * concern all supported chipsets, unless mentioned otherwise.
+ *
+ * Support could easily be added for the National Semiconductor LM76
+ * and Maxim MAX6633 and MAX6634 chips, which are mostly compatible
+ * with the LM92.
+ *
+ * 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 <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/i2c-sensor.h>
+
+
+/* The LM92 and MAX6635 have 2 two-state pins for address selection,
+   resulting in 4 possible addresses. */
+static unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b,
+				       I2C_CLIENT_END };
+static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
+
+/* Insmod parameters */
+SENSORS_INSMOD_1(lm92);
+
+/* The LM92 registers */
+#define LM92_REG_CONFIG			0x01 /* 8-bit, RW */
+#define LM92_REG_TEMP			0x00 /* 16-bit, RO */
+#define LM92_REG_TEMP_HYST		0x02 /* 16-bit, RW */
+#define LM92_REG_TEMP_CRIT		0x03 /* 16-bit, RW */
+#define LM92_REG_TEMP_LOW		0x04 /* 16-bit, RW */
+#define LM92_REG_TEMP_HIGH		0x05 /* 16-bit, RW */
+#define LM92_REG_MAN_ID			0x07 /* 16-bit, RO, LM92 only */
+
+/* The LM92 uses signed 13-bit values with LSB = 0.0625 degree Celsius,
+   left-justified in 16-bit registers. No rounding is done, with such
+   a resolution it's just not worth it. Note that the MAX6635 doesn't
+   make use of the 4 lower bits for limits (i.e. effective resolution
+   for limits is 1 degree Celsius). */
+static inline int TEMP_FROM_REG(s16 reg)
+{
+	return reg / 8 * 625 / 10;
+}
+
+static inline s16 TEMP_TO_REG(int val)
+{
+	if (val <= -60000)
+		return -60000 * 10 / 625 * 8;
+	if (val >= 160000)
+		return 160000 * 10 / 625 * 8;
+	return val * 10 / 625 * 8;
+}
+
+/* Alarm flags are stored in the 3 LSB of the temperature register */
+static inline u8 ALARMS_FROM_REG(s16 reg)
+{
+	return reg & 0x0007;
+}
+
+/* Driver data (common to all clients) */
+static struct i2c_driver lm92_driver;
+
+/* Client data (each client gets its own) */
+struct lm92_data {
+	struct i2c_client client;
+	struct semaphore update_lock;
+	char valid; /* zero until following fields are valid */
+	unsigned long last_updated; /* in jiffies */
+
+	/* registers values */
+	s16 temp1_input, temp1_crit, temp1_min, temp1_max, temp1_hyst;
+};
+
+
+/*
+ * Sysfs attributes and callback functions
+ */
+
+static struct lm92_data *lm92_update_device(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm92_data *data = i2c_get_clientdata(client);
+
+	down(&data->update_lock);
+
+	if (time_after(jiffies, data->last_updated + HZ)
+	 || !data->valid) {
+		dev_dbg(&client->dev, "Updating lm92 data\n");
+		data->temp1_input = swab16(i2c_smbus_read_word_data(client,
+				    LM92_REG_TEMP));
+		data->temp1_hyst = swab16(i2c_smbus_read_word_data(client,
+				    LM92_REG_TEMP_HYST));
+		data->temp1_crit = swab16(i2c_smbus_read_word_data(client,
+				    LM92_REG_TEMP_CRIT));
+		data->temp1_min = swab16(i2c_smbus_read_word_data(client,
+				    LM92_REG_TEMP_LOW));
+		data->temp1_max = swab16(i2c_smbus_read_word_data(client,
+				    LM92_REG_TEMP_HIGH));
+
+		data->last_updated = jiffies;
+		data->valid = 1;
+	}
+
+	up(&data->update_lock);
+
+	return data;
+}
+
+#define show_temp(value) \
+static ssize_t show_##value(struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+	struct lm92_data *data = lm92_update_device(dev); \
+	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->value)); \
+}
+show_temp(temp1_input);
+show_temp(temp1_crit);
+show_temp(temp1_min);
+show_temp(temp1_max);
+
+#define set_temp(value, reg) \
+static ssize_t set_##value(struct device *dev, struct device_attribute *attr, const char *buf, \
+	size_t count) \
+{ \
+	struct i2c_client *client = to_i2c_client(dev); \
+	struct lm92_data *data = i2c_get_clientdata(client); \
+	long val = simple_strtol(buf, NULL, 10); \
+ \
+	down(&data->update_lock); \
+	data->value = TEMP_TO_REG(val); \
+	i2c_smbus_write_word_data(client, reg, swab16(data->value)); \
+	up(&data->update_lock); \
+	return count; \
+}
+set_temp(temp1_crit, LM92_REG_TEMP_CRIT);
+set_temp(temp1_min, LM92_REG_TEMP_LOW);
+set_temp(temp1_max, LM92_REG_TEMP_HIGH);
+
+static ssize_t show_temp1_crit_hyst(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct lm92_data *data = lm92_update_device(dev);
+	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp1_crit)
+		       - TEMP_FROM_REG(data->temp1_hyst));
+}
+static ssize_t show_temp1_max_hyst(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct lm92_data *data = lm92_update_device(dev);
+	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp1_max)
+		       - TEMP_FROM_REG(data->temp1_hyst));
+}
+static ssize_t show_temp1_min_hyst(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct lm92_data *data = lm92_update_device(dev);
+	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp1_min)
+		       + TEMP_FROM_REG(data->temp1_hyst));
+}
+
+static ssize_t set_temp1_crit_hyst(struct device *dev, struct device_attribute *attr, const char *buf,
+	size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm92_data *data = i2c_get_clientdata(client);
+	long val = simple_strtol(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->temp1_hyst = TEMP_FROM_REG(data->temp1_crit) - val;
+	i2c_smbus_write_word_data(client, LM92_REG_TEMP_HYST,
+				  swab16(TEMP_TO_REG(data->temp1_hyst)));
+	up(&data->update_lock);
+	return count;
+}
+
+static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct lm92_data *data = lm92_update_device(dev);
+	return sprintf(buf, "%d\n", ALARMS_FROM_REG(data->temp1_input));
+}
+
+static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp1_input, NULL);
+static DEVICE_ATTR(temp1_crit, S_IWUSR | S_IRUGO, show_temp1_crit,
+	set_temp1_crit);
+static DEVICE_ATTR(temp1_crit_hyst, S_IWUSR | S_IRUGO, show_temp1_crit_hyst,
+	set_temp1_crit_hyst);
+static DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, show_temp1_min,
+	set_temp1_min);
+static DEVICE_ATTR(temp1_min_hyst, S_IRUGO, show_temp1_min_hyst, NULL);
+static DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp1_max,
+	set_temp1_max);
+static DEVICE_ATTR(temp1_max_hyst, S_IRUGO, show_temp1_max_hyst, NULL);
+static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
+
+
+/*
+ * Detection and registration
+ */
+
+static void lm92_init_client(struct i2c_client *client)
+{
+	u8 config;
+
+	/* Start the conversions if needed */
+	config = i2c_smbus_read_byte_data(client, LM92_REG_CONFIG);
+	if (config & 0x01)
+		i2c_smbus_write_byte_data(client, LM92_REG_CONFIG,
+					  config & 0xFE);
+}
+
+/* The MAX6635 has no identification register, so we have to use tricks
+   to identify it reliably. This is somewhat slow.
+   Note that we do NOT rely on the 2 MSB of the configuration register
+   always reading 0, as suggested by the datasheet, because it was once
+   reported not to be true. */
+static int max6635_check(struct i2c_client *client)
+{
+	u16 temp_low, temp_high, temp_hyst, temp_crit;
+	u8 conf;
+	int i;
+
+	/* No manufacturer ID register, so a read from this address will
+	   always return the last read value. */
+	temp_low = i2c_smbus_read_word_data(client, LM92_REG_TEMP_LOW);
+	if (i2c_smbus_read_word_data(client, LM92_REG_MAN_ID) != temp_low)
+		return 0;
+	temp_high = i2c_smbus_read_word_data(client, LM92_REG_TEMP_HIGH);
+	if (i2c_smbus_read_word_data(client, LM92_REG_MAN_ID) != temp_high)
+		return 0;
+	
+	/* Limits are stored as integer values (signed, 9-bit). */
+	if ((temp_low & 0x7f00) || (temp_high & 0x7f00))
+		return 0;
+	temp_hyst = i2c_smbus_read_word_data(client, LM92_REG_TEMP_HYST);
+	temp_crit = i2c_smbus_read_word_data(client, LM92_REG_TEMP_CRIT);
+	if ((temp_hyst & 0x7f00) || (temp_crit & 0x7f00))
+		return 0;
+
+	/* Registers addresses were found to cycle over 16-byte boundaries.
+	   We don't test all registers with all offsets so as to save some
+	   reads and time, but this should still be sufficient to dismiss
+	   non-MAX6635 chips. */
+	conf = i2c_smbus_read_byte_data(client, LM92_REG_CONFIG);
+	for (i=16; i<96; i*=2) {
+		if (temp_hyst != i2c_smbus_read_word_data(client,
+		 		 LM92_REG_TEMP_HYST + i - 16)
+		 || temp_crit != i2c_smbus_read_word_data(client,
+		 		 LM92_REG_TEMP_CRIT + i)
+		 || temp_low != i2c_smbus_read_word_data(client,
+				LM92_REG_TEMP_LOW + i + 16)
+		 || temp_high != i2c_smbus_read_word_data(client,
+		 		 LM92_REG_TEMP_HIGH + i + 32)
+		 || conf != i2c_smbus_read_byte_data(client,
+		 	    LM92_REG_CONFIG + i))
+			return 0;
+	}
+
+	return 1;
+}
+
+/* The following function does more than just detection. If detection
+   succeeds, it also registers the new chip. */
+static int lm92_detect(struct i2c_adapter *adapter, int address, int kind)
+{
+	struct i2c_client *new_client;
+	struct lm92_data *data;
+	int err = 0;
+	char *name;
+
+	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA
+					    | I2C_FUNC_SMBUS_WORD_DATA))
+		goto exit;
+
+	if (!(data = kmalloc(sizeof(struct lm92_data), GFP_KERNEL))) {
+		err = -ENOMEM;
+		goto exit;
+	}
+	memset(data, 0, sizeof(struct lm92_data));
+
+	/* Fill in enough client fields so that we can read from the chip,
+	   which is required for identication */
+	new_client = &data->client;
+	i2c_set_clientdata(new_client, data);
+	new_client->addr = address;
+	new_client->adapter = adapter;
+	new_client->driver = &lm92_driver;
+	new_client->flags = 0;
+
+	/* A negative kind means that the driver was loaded with no force
+	   parameter (default), so we must identify the chip. */
+	if (kind < 0) {
+		u8 config = i2c_smbus_read_byte_data(new_client,
+			     LM92_REG_CONFIG);
+		u16 man_id = i2c_smbus_read_word_data(new_client,
+			     LM92_REG_MAN_ID);
+
+		if ((config & 0xe0) == 0x00
+		 && man_id == 0x0180) {
+			pr_info("lm92: Found National Semiconductor LM92 chip\n");
+	 		kind = lm92;
+		} else
+		if (max6635_check(new_client)) {
+			pr_info("lm92: Found Maxim MAX6635 chip\n");
+			kind = lm92; /* No separate prefix */
+		}
+		else
+			goto exit_free;
+	} else
+	if (kind == 0) /* Default to an LM92 if forced */
+		kind = lm92;
+
+	/* Give it the proper name */
+	if (kind == lm92) {
+		name = "lm92";
+	} else { /* Supposedly cannot happen */
+		dev_dbg(&new_client->dev, "Kind out of range?\n");
+		goto exit_free;
+	}
+
+	/* Fill in the remaining client fields */
+	strlcpy(new_client->name, name, I2C_NAME_SIZE);
+	data->valid = 0;
+	init_MUTEX(&data->update_lock);
+
+	/* Tell the i2c subsystem a new client has arrived */
+	if ((err = i2c_attach_client(new_client)))
+		goto exit_free;
+
+	/* Initialize the chipset */
+	lm92_init_client(new_client);
+
+	/* Register sysfs hooks */
+	device_create_file(&new_client->dev, &dev_attr_temp1_input);
+	device_create_file(&new_client->dev, &dev_attr_temp1_crit);
+	device_create_file(&new_client->dev, &dev_attr_temp1_crit_hyst);
+	device_create_file(&new_client->dev, &dev_attr_temp1_min);
+	device_create_file(&new_client->dev, &dev_attr_temp1_min_hyst);
+	device_create_file(&new_client->dev, &dev_attr_temp1_max);
+	device_create_file(&new_client->dev, &dev_attr_temp1_max_hyst);
+	device_create_file(&new_client->dev, &dev_attr_alarms);
+
+	return 0;
+
+exit_free:
+	kfree(data);
+exit:
+	return err;
+}
+
+static int lm92_attach_adapter(struct i2c_adapter *adapter)
+{
+	if (!(adapter->class & I2C_CLASS_HWMON))
+		return 0;
+	return i2c_detect(adapter, &addr_data, lm92_detect);
+}
+
+static int lm92_detach_client(struct i2c_client *client)
+{
+	int err;
+
+	if ((err = i2c_detach_client(client))) {
+		dev_err(&client->dev, "Client deregistration failed, "
+			"client not detached.\n");
+		return err;
+	}
+
+	kfree(i2c_get_clientdata(client));
+	return 0;
+}
+
+
+/*
+ * Module and driver stuff
+ */
+
+static struct i2c_driver lm92_driver = {
+	.owner		= THIS_MODULE,
+	.name		= "lm92",
+	.id		= I2C_DRIVERID_LM92,
+	.flags		= I2C_DF_NOTIFY,
+	.attach_adapter	= lm92_attach_adapter,
+	.detach_client	= lm92_detach_client,
+};
+
+static int __init sensors_lm92_init(void)
+{
+	return i2c_add_driver(&lm92_driver);
+}
+
+static void __exit sensors_lm92_exit(void)
+{
+	i2c_del_driver(&lm92_driver);
+}
+
+MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>");
+MODULE_DESCRIPTION("LM92/MAX6635 driver");
+MODULE_LICENSE("GPL");
+
+module_init(sensors_lm92_init);
+module_exit(sensors_lm92_exit);
diff --git a/drivers/hwmon/max1619.c b/drivers/hwmon/max1619.c
new file mode 100644
--- /dev/null
+++ b/drivers/hwmon/max1619.c
@@ -0,0 +1,372 @@
+/*
+ * max1619.c - Part of lm_sensors, Linux kernel modules for hardware
+ *             monitoring
+ * Copyright (C) 2003-2004 Alexey Fisher <fishor@mail.ru>
+ *                         Jean Delvare <khali@linux-fr.org>
+ *
+ * Based on the lm90 driver. The MAX1619 is a sensor chip made by Maxim.
+ * It reports up to two temperatures (its own plus up to
+ * one external one). Complete datasheet can be
+ * obtained from Maxim's website at:
+ *   http://pdfserv.maxim-ic.com/en/ds/MAX1619.pdf
+ *
+ * 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 <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+#include <linux/i2c.h>
+#include <linux/i2c-sensor.h>
+
+
+static unsigned short normal_i2c[] = { 0x18, 0x19, 0x1a,
+					0x29, 0x2a, 0x2b,
+					0x4c, 0x4d, 0x4e,
+					I2C_CLIENT_END };
+static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
+
+/*
+ * Insmod parameters
+ */
+
+SENSORS_INSMOD_1(max1619);
+
+/*
+ * The MAX1619 registers
+ */
+
+#define MAX1619_REG_R_MAN_ID		0xFE
+#define MAX1619_REG_R_CHIP_ID		0xFF
+#define MAX1619_REG_R_CONFIG		0x03
+#define MAX1619_REG_W_CONFIG		0x09
+#define MAX1619_REG_R_CONVRATE		0x04
+#define MAX1619_REG_W_CONVRATE		0x0A
+#define MAX1619_REG_R_STATUS		0x02
+#define MAX1619_REG_R_LOCAL_TEMP	0x00
+#define MAX1619_REG_R_REMOTE_TEMP	0x01
+#define MAX1619_REG_R_REMOTE_HIGH	0x07
+#define MAX1619_REG_W_REMOTE_HIGH	0x0D
+#define MAX1619_REG_R_REMOTE_LOW	0x08
+#define MAX1619_REG_W_REMOTE_LOW	0x0E
+#define MAX1619_REG_R_REMOTE_CRIT	0x10
+#define MAX1619_REG_W_REMOTE_CRIT	0x12
+#define MAX1619_REG_R_TCRIT_HYST	0x11
+#define MAX1619_REG_W_TCRIT_HYST	0x13
+
+/*
+ * Conversions and various macros
+ */
+
+#define TEMP_FROM_REG(val)	((val & 0x80 ? val-0x100 : val) * 1000)
+#define TEMP_TO_REG(val)	((val < 0 ? val+0x100*1000 : val) / 1000)
+
+/*
+ * Functions declaration
+ */
+
+static int max1619_attach_adapter(struct i2c_adapter *adapter);
+static int max1619_detect(struct i2c_adapter *adapter, int address,
+	int kind);
+static void max1619_init_client(struct i2c_client *client);
+static int max1619_detach_client(struct i2c_client *client);
+static struct max1619_data *max1619_update_device(struct device *dev);
+
+/*
+ * Driver data (common to all clients)
+ */
+
+static struct i2c_driver max1619_driver = {
+	.owner		= THIS_MODULE,
+	.name		= "max1619",
+	.flags		= I2C_DF_NOTIFY,
+	.attach_adapter	= max1619_attach_adapter,
+	.detach_client	= max1619_detach_client,
+};
+
+/*
+ * Client data (each client gets its own)
+ */
+
+struct max1619_data {
+	struct i2c_client client;
+	struct semaphore update_lock;
+	char valid; /* zero until following fields are valid */
+	unsigned long last_updated; /* in jiffies */
+
+	/* registers values */
+	u8 temp_input1; /* local */
+	u8 temp_input2, temp_low2, temp_high2; /* remote */
+	u8 temp_crit2;
+	u8 temp_hyst2;
+	u8 alarms; 
+};
+
+/*
+ * Sysfs stuff
+ */
+
+#define show_temp(value) \
+static ssize_t show_##value(struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+	struct max1619_data *data = max1619_update_device(dev); \
+	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->value)); \
+}
+show_temp(temp_input1);
+show_temp(temp_input2);
+show_temp(temp_low2);
+show_temp(temp_high2);
+show_temp(temp_crit2);
+show_temp(temp_hyst2);
+
+#define set_temp2(value, reg) \
+static ssize_t set_##value(struct device *dev, struct device_attribute *attr, const char *buf, \
+	size_t count) \
+{ \
+	struct i2c_client *client = to_i2c_client(dev); \
+	struct max1619_data *data = i2c_get_clientdata(client); \
+	long val = simple_strtol(buf, NULL, 10); \
+ \
+	down(&data->update_lock); \
+	data->value = TEMP_TO_REG(val); \
+	i2c_smbus_write_byte_data(client, reg, data->value); \
+	up(&data->update_lock); \
+	return count; \
+}
+
+set_temp2(temp_low2, MAX1619_REG_W_REMOTE_LOW);
+set_temp2(temp_high2, MAX1619_REG_W_REMOTE_HIGH);
+set_temp2(temp_crit2, MAX1619_REG_W_REMOTE_CRIT);
+set_temp2(temp_hyst2, MAX1619_REG_W_TCRIT_HYST);
+
+static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct max1619_data *data = max1619_update_device(dev);
+	return sprintf(buf, "%d\n", data->alarms);
+}
+
+static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp_input1, NULL);
+static DEVICE_ATTR(temp2_input, S_IRUGO, show_temp_input2, NULL);
+static DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_temp_low2,
+	set_temp_low2);
+static DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_temp_high2,
+	set_temp_high2);
+static DEVICE_ATTR(temp2_crit, S_IWUSR | S_IRUGO, show_temp_crit2,
+	set_temp_crit2);
+static DEVICE_ATTR(temp2_crit_hyst, S_IWUSR | S_IRUGO, show_temp_hyst2,
+	set_temp_hyst2);
+static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
+
+/*
+ * Real code
+ */
+
+static int max1619_attach_adapter(struct i2c_adapter *adapter)
+{
+	if (!(adapter->class & I2C_CLASS_HWMON))
+		return 0;
+	return i2c_detect(adapter, &addr_data, max1619_detect);
+}
+
+/*
+ * The following function does more than just detection. If detection
+ * succeeds, it also registers the new chip.
+ */
+static int max1619_detect(struct i2c_adapter *adapter, int address, int kind)
+{
+	struct i2c_client *new_client;
+	struct max1619_data *data;
+	int err = 0;
+	const char *name = "";	
+	u8 reg_config=0, reg_convrate=0, reg_status=0;
+	u8 man_id, chip_id;
+	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+		goto exit;
+
+	if (!(data = kmalloc(sizeof(struct max1619_data), GFP_KERNEL))) {
+		err = -ENOMEM;
+		goto exit;
+	}
+	memset(data, 0, sizeof(struct max1619_data));
+
+	/* The common I2C client data is placed right before the
+	   MAX1619-specific data. */
+	new_client = &data->client;
+	i2c_set_clientdata(new_client, data);
+	new_client->addr = address;
+	new_client->adapter = adapter;
+	new_client->driver = &max1619_driver;
+	new_client->flags = 0;
+
+	/*
+	 * Now we do the remaining detection. A negative kind means that
+	 * the driver was loaded with no force parameter (default), so we
+	 * must both detect and identify the chip. A zero kind means that
+	 * the driver was loaded with the force parameter, the detection
+	 * step shall be skipped. A positive kind means that the driver
+	 * was loaded with the force parameter and a given kind of chip is
+	 * requested, so both the detection and the identification steps
+	 * are skipped.
+	 */
+	if (kind < 0) { /* detection */
+		reg_config = i2c_smbus_read_byte_data(new_client,
+			      MAX1619_REG_R_CONFIG);
+		reg_convrate = i2c_smbus_read_byte_data(new_client,
+			       MAX1619_REG_R_CONVRATE);
+		reg_status = i2c_smbus_read_byte_data(new_client,
+				MAX1619_REG_R_STATUS);
+		if ((reg_config & 0x03) != 0x00
+		 || reg_convrate > 0x07 || (reg_status & 0x61 ) !=0x00) {
+			dev_dbg(&adapter->dev,
+				"MAX1619 detection failed at 0x%02x.\n",
+				address);
+			goto exit_free;
+		}
+	}
+
+	if (kind <= 0) { /* identification */
+	
+		man_id = i2c_smbus_read_byte_data(new_client,
+			 MAX1619_REG_R_MAN_ID);
+		chip_id = i2c_smbus_read_byte_data(new_client,
+			  MAX1619_REG_R_CHIP_ID);
+		
+		if ((man_id == 0x4D) && (chip_id == 0x04)){  
+				kind = max1619;
+			}
+		}
+
+		if (kind <= 0) { /* identification failed */
+			dev_info(&adapter->dev,
+			    "Unsupported chip (man_id=0x%02X, "
+			    "chip_id=0x%02X).\n", man_id, chip_id);
+			goto exit_free;
+		}
+	
+
+	if (kind == max1619){
+		name = "max1619";
+	}
+
+	/* We can fill in the remaining client fields */
+	strlcpy(new_client->name, name, I2C_NAME_SIZE);
+	data->valid = 0;
+	init_MUTEX(&data->update_lock);
+
+	/* Tell the I2C layer a new client has arrived */
+	if ((err = i2c_attach_client(new_client)))
+		goto exit_free;
+
+	/* Initialize the MAX1619 chip */
+	max1619_init_client(new_client);
+
+	/* Register sysfs hooks */
+	device_create_file(&new_client->dev, &dev_attr_temp1_input);
+	device_create_file(&new_client->dev, &dev_attr_temp2_input);
+	device_create_file(&new_client->dev, &dev_attr_temp2_min);
+	device_create_file(&new_client->dev, &dev_attr_temp2_max);
+	device_create_file(&new_client->dev, &dev_attr_temp2_crit);
+	device_create_file(&new_client->dev, &dev_attr_temp2_crit_hyst);
+	device_create_file(&new_client->dev, &dev_attr_alarms);
+
+	return 0;
+
+exit_free:
+	kfree(data);
+exit:
+	return err;
+}
+
+static void max1619_init_client(struct i2c_client *client)
+{
+	u8 config;
+
+	/*
+	 * Start the conversions.
+	 */
+	i2c_smbus_write_byte_data(client, MAX1619_REG_W_CONVRATE,
+				  5); /* 2 Hz */
+	config = i2c_smbus_read_byte_data(client, MAX1619_REG_R_CONFIG);
+	if (config & 0x40)
+		i2c_smbus_write_byte_data(client, MAX1619_REG_W_CONFIG,
+					  config & 0xBF); /* run */
+}
+
+static int max1619_detach_client(struct i2c_client *client)
+{
+	int err;
+
+	if ((err = i2c_detach_client(client))) {
+		dev_err(&client->dev, "Client deregistration failed, "
+			"client not detached.\n");
+		return err;
+	}
+
+	kfree(i2c_get_clientdata(client));
+	return 0;
+}
+
+static struct max1619_data *max1619_update_device(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct max1619_data *data = i2c_get_clientdata(client);
+
+	down(&data->update_lock);
+
+	if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) {
+		dev_dbg(&client->dev, "Updating max1619 data.\n");
+		data->temp_input1 = i2c_smbus_read_byte_data(client,
+					MAX1619_REG_R_LOCAL_TEMP);
+		data->temp_input2 = i2c_smbus_read_byte_data(client,
+					MAX1619_REG_R_REMOTE_TEMP);
+		data->temp_high2 = i2c_smbus_read_byte_data(client,
+					MAX1619_REG_R_REMOTE_HIGH);
+		data->temp_low2 = i2c_smbus_read_byte_data(client,
+					MAX1619_REG_R_REMOTE_LOW);
+		data->temp_crit2 = i2c_smbus_read_byte_data(client,
+					MAX1619_REG_R_REMOTE_CRIT);
+		data->temp_hyst2 = i2c_smbus_read_byte_data(client,
+					MAX1619_REG_R_TCRIT_HYST);
+		data->alarms = i2c_smbus_read_byte_data(client,
+					MAX1619_REG_R_STATUS);
+
+		data->last_updated = jiffies;
+		data->valid = 1;
+	}
+
+	up(&data->update_lock);
+
+	return data;
+}
+
+static int __init sensors_max1619_init(void)
+{
+	return i2c_add_driver(&max1619_driver);
+}
+
+static void __exit sensors_max1619_exit(void)
+{
+	i2c_del_driver(&max1619_driver);
+}
+
+MODULE_AUTHOR("Alexey Fisher <fishor@mail.ru> and "
+	"Jean Delvare <khali@linux-fr.org>");
+MODULE_DESCRIPTION("MAX1619 sensor driver");
+MODULE_LICENSE("GPL");
+
+module_init(sensors_max1619_init);
+module_exit(sensors_max1619_exit);
diff --git a/drivers/hwmon/pc87360.c b/drivers/hwmon/pc87360.c
new file mode 100644
--- /dev/null
+++ b/drivers/hwmon/pc87360.c
@@ -0,0 +1,1348 @@
+/*
+ *  pc87360.c - Part of lm_sensors, Linux kernel modules
+ *              for hardware monitoring
+ *  Copyright (C) 2004 Jean Delvare <khali@linux-fr.org>
+ *
+ *  Copied from smsc47m1.c:
+ *  Copyright (C) 2002 Mark D. Studebaker <mdsxyz123@yahoo.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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *  Supports the following chips:
+ *
+ *  Chip        #vin    #fan    #pwm    #temp   devid
+ *  PC87360     -       2       2       -       0xE1
+ *  PC87363     -       2       2       -       0xE8
+ *  PC87364     -       3       3       -       0xE4
+ *  PC87365     11      3       3       2       0xE5
+ *  PC87366     11      3       3       3-4     0xE9
+ *
+ *  This driver assumes that no more than one chip is present, and one of
+ *  the standard Super-I/O addresses is used (0x2E/0x2F or 0x4E/0x4F).
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+#include <linux/i2c.h>
+#include <linux/i2c-sensor.h>
+#include <linux/i2c-vid.h>
+#include <asm/io.h>
+
+static unsigned short normal_i2c[] = { I2C_CLIENT_END };
+static unsigned int normal_isa[] = { 0, I2C_CLIENT_ISA_END };
+static struct i2c_force_data forces[] = {{ NULL }};
+static u8 devid;
+static unsigned int extra_isa[3];
+static u8 confreg[4];
+
+enum chips { any_chip, pc87360, pc87363, pc87364, pc87365, pc87366 };
+static struct i2c_address_data addr_data = {
+	.normal_i2c		= normal_i2c,
+	.normal_isa		= normal_isa,
+	.forces			= forces,
+};
+
+static int init = 1;
+module_param(init, int, 0);
+MODULE_PARM_DESC(init,
+ "Chip initialization level:\n"
+ " 0: None\n"
+ "*1: Forcibly enable internal voltage and temperature channels, except in9\n"
+ " 2: Forcibly enable all voltage and temperature channels, except in9\n"
+ " 3: Forcibly enable all voltage and temperature channels, including in9");
+
+/*
+ * Super-I/O registers and operations
+ */
+
+#define DEV	0x07	/* Register: Logical device select */
+#define DEVID	0x20	/* Register: Device ID */
+#define ACT	0x30	/* Register: Device activation */
+#define BASE	0x60	/* Register: Base address */
+
+#define FSCM	0x09	/* Logical device: fans */
+#define VLM	0x0d	/* Logical device: voltages */
+#define TMS	0x0e	/* Logical device: temperatures */
+static const u8 logdev[3] = { FSCM, VLM, TMS };
+
+#define LD_FAN		0
+#define LD_IN		1
+#define LD_TEMP		2
+
+static inline void superio_outb(int sioaddr, int reg, int val)
+{
+	outb(reg, sioaddr);
+	outb(val, sioaddr+1);
+}
+
+static inline int superio_inb(int sioaddr, int reg)
+{
+	outb(reg, sioaddr);
+	return inb(sioaddr+1);
+}
+
+static inline void superio_exit(int sioaddr)
+{
+	outb(0x02, sioaddr);
+	outb(0x02, sioaddr+1);
+}
+
+/*
+ * Logical devices
+ */
+
+#define PC87360_EXTENT		0x10
+#define PC87365_REG_BANK	0x09
+#define NO_BANK			0xff
+
+/*
+ * Fan registers and conversions
+ */
+
+/* nr has to be 0 or 1 (PC87360/87363) or 2 (PC87364/87365/87366) */
+#define PC87360_REG_PRESCALE(nr)	(0x00 + 2 * (nr))
+#define PC87360_REG_PWM(nr)		(0x01 + 2 * (nr))
+#define PC87360_REG_FAN_MIN(nr)		(0x06 + 3 * (nr))
+#define PC87360_REG_FAN(nr)		(0x07 + 3 * (nr))
+#define PC87360_REG_FAN_STATUS(nr)	(0x08 + 3 * (nr))
+
+#define FAN_FROM_REG(val,div)		((val) == 0 ? 0: \
+					 480000 / ((val)*(div)))
+#define FAN_TO_REG(val,div)		((val) <= 100 ? 0 : \
+					 480000 / ((val)*(div)))
+#define FAN_DIV_FROM_REG(val)		(1 << ((val >> 5) & 0x03))
+#define FAN_STATUS_FROM_REG(val)	((val) & 0x07)
+
+#define FAN_CONFIG_MONITOR(val,nr)	(((val) >> (2 + nr * 3)) & 1)
+#define FAN_CONFIG_CONTROL(val,nr)	(((val) >> (3 + nr * 3)) & 1)
+#define FAN_CONFIG_INVERT(val,nr)	(((val) >> (4 + nr * 3)) & 1)
+
+#define PWM_FROM_REG(val,inv)		((inv) ? 255 - (val) : (val))
+static inline u8 PWM_TO_REG(int val, int inv)
+{
+	if (inv)
+		val = 255 - val;
+	if (val < 0)
+		return 0;
+	if (val > 255)
+		return 255;
+	return val;
+}
+
+/*
+ * Voltage registers and conversions
+ */
+
+#define PC87365_REG_IN_CONVRATE		0x07
+#define PC87365_REG_IN_CONFIG		0x08
+#define PC87365_REG_IN			0x0B
+#define PC87365_REG_IN_MIN		0x0D
+#define PC87365_REG_IN_MAX		0x0C
+#define PC87365_REG_IN_STATUS		0x0A
+#define PC87365_REG_IN_ALARMS1		0x00
+#define PC87365_REG_IN_ALARMS2		0x01
+#define PC87365_REG_VID			0x06
+
+#define IN_FROM_REG(val,ref)		(((val) * (ref) + 128) / 256)
+#define IN_TO_REG(val,ref)		((val) < 0 ? 0 : \
+					 (val)*256 >= (ref)*255 ? 255: \
+					 ((val) * 256 + (ref)/2) / (ref))
+
+/*
+ * Temperature registers and conversions
+ */
+
+#define PC87365_REG_TEMP_CONFIG		0x08
+#define PC87365_REG_TEMP		0x0B
+#define PC87365_REG_TEMP_MIN		0x0D
+#define PC87365_REG_TEMP_MAX		0x0C
+#define PC87365_REG_TEMP_CRIT		0x0E
+#define PC87365_REG_TEMP_STATUS		0x0A
+#define PC87365_REG_TEMP_ALARMS		0x00
+
+#define TEMP_FROM_REG(val)		((val) * 1000)
+#define TEMP_TO_REG(val)		((val) < -55000 ? -55 : \
+					 (val) > 127000 ? 127 : \
+					 (val) < 0 ? ((val) - 500) / 1000 : \
+					 ((val) + 500) / 1000)
+
+/*
+ * Client data (each client gets its own)
+ */
+
+struct pc87360_data {
+	struct i2c_client client;
+	struct semaphore lock;
+	struct semaphore update_lock;
+	char valid;		/* !=0 if following fields are valid */
+	unsigned long last_updated;	/* In jiffies */
+
+	int address[3];
+
+	u8 fannr, innr, tempnr;
+
+	u8 fan[3];		/* Register value */
+	u8 fan_min[3];		/* Register value */
+	u8 fan_status[3];	/* Register value */
+	u8 pwm[3];		/* Register value */
+	u16 fan_conf;		/* Configuration register values, combined */
+
+	u16 in_vref;		/* 1 mV/bit */
+	u8 in[14];		/* Register value */
+	u8 in_min[14];		/* Register value */
+	u8 in_max[14];		/* Register value */
+	u8 in_crit[3];		/* Register value */
+	u8 in_status[14];	/* Register value */
+	u16 in_alarms;		/* Register values, combined, masked */
+	u8 vid_conf;		/* Configuration register value */
+	u8 vrm;
+	u8 vid;			/* Register value */
+
+	s8 temp[3];		/* Register value */
+	s8 temp_min[3];		/* Register value */
+	s8 temp_max[3];		/* Register value */
+	s8 temp_crit[3];	/* Register value */
+	u8 temp_status[3];	/* Register value */
+	u8 temp_alarms;		/* Register value, masked */
+};
+
+/*
+ * Functions declaration
+ */
+
+static int pc87360_attach_adapter(struct i2c_adapter *adapter);
+static int pc87360_detect(struct i2c_adapter *adapter, int address, int kind);
+static int pc87360_detach_client(struct i2c_client *client);
+
+static int pc87360_read_value(struct pc87360_data *data, u8 ldi, u8 bank,
+			      u8 reg);
+static void pc87360_write_value(struct pc87360_data *data, u8 ldi, u8 bank,
+				u8 reg, u8 value);
+static void pc87360_init_client(struct i2c_client *client, int use_thermistors);
+static struct pc87360_data *pc87360_update_device(struct device *dev);
+
+/*
+ * Driver data (common to all clients)
+ */
+
+static struct i2c_driver pc87360_driver = {
+	.owner		= THIS_MODULE,
+	.name		= "pc87360",
+	.flags		= I2C_DF_NOTIFY,
+	.attach_adapter	= pc87360_attach_adapter,
+	.detach_client	= pc87360_detach_client,
+};
+
+/*
+ * Sysfs stuff
+ */
+
+static ssize_t set_fan_min(struct device *dev, const char *buf,
+	size_t count, int nr)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct pc87360_data *data = i2c_get_clientdata(client);
+	long fan_min = simple_strtol(buf, NULL, 10);
+
+	down(&data->update_lock);
+	fan_min = FAN_TO_REG(fan_min, FAN_DIV_FROM_REG(data->fan_status[nr]));
+
+	/* If it wouldn't fit, change clock divisor */
+	while (fan_min > 255
+	    && (data->fan_status[nr] & 0x60) != 0x60) {
+		fan_min >>= 1;
+		data->fan[nr] >>= 1;
+		data->fan_status[nr] += 0x20;
+	}
+	data->fan_min[nr] = fan_min > 255 ? 255 : fan_min;
+	pc87360_write_value(data, LD_FAN, NO_BANK, PC87360_REG_FAN_MIN(nr),
+			    data->fan_min[nr]);
+
+	/* Write new divider, preserve alarm bits */
+	pc87360_write_value(data, LD_FAN, NO_BANK, PC87360_REG_FAN_STATUS(nr),
+			    data->fan_status[nr] & 0xF9);
+	up(&data->update_lock);
+
+	return count;
+}
+
+#define show_and_set_fan(offset) \
+static ssize_t show_fan##offset##_input(struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+	struct pc87360_data *data = pc87360_update_device(dev); \
+	return sprintf(buf, "%u\n", FAN_FROM_REG(data->fan[offset-1], \
+		       FAN_DIV_FROM_REG(data->fan_status[offset-1]))); \
+} \
+static ssize_t show_fan##offset##_min(struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+	struct pc87360_data *data = pc87360_update_device(dev); \
+	return sprintf(buf, "%u\n", FAN_FROM_REG(data->fan_min[offset-1], \
+		       FAN_DIV_FROM_REG(data->fan_status[offset-1]))); \
+} \
+static ssize_t show_fan##offset##_div(struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+	struct pc87360_data *data = pc87360_update_device(dev); \
+	return sprintf(buf, "%u\n", \
+		       FAN_DIV_FROM_REG(data->fan_status[offset-1])); \
+} \
+static ssize_t show_fan##offset##_status(struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+	struct pc87360_data *data = pc87360_update_device(dev); \
+	return sprintf(buf, "%u\n", \
+		       FAN_STATUS_FROM_REG(data->fan_status[offset-1])); \
+} \
+static ssize_t set_fan##offset##_min(struct device *dev, struct device_attribute *attr, const char *buf, \
+	size_t count) \
+{ \
+	return set_fan_min(dev, buf, count, offset-1); \
+} \
+static DEVICE_ATTR(fan##offset##_input, S_IRUGO, \
+	show_fan##offset##_input, NULL); \
+static DEVICE_ATTR(fan##offset##_min, S_IWUSR | S_IRUGO, \
+	show_fan##offset##_min, set_fan##offset##_min); \
+static DEVICE_ATTR(fan##offset##_div, S_IRUGO, \
+	show_fan##offset##_div, NULL); \
+static DEVICE_ATTR(fan##offset##_status, S_IRUGO, \
+	show_fan##offset##_status, NULL);
+show_and_set_fan(1)
+show_and_set_fan(2)
+show_and_set_fan(3)
+
+#define show_and_set_pwm(offset) \
+static ssize_t show_pwm##offset(struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+	struct pc87360_data *data = pc87360_update_device(dev); \
+	return sprintf(buf, "%u\n", \
+		       PWM_FROM_REG(data->pwm[offset-1], \
+				    FAN_CONFIG_INVERT(data->fan_conf, \
+						      offset-1))); \
+} \
+static ssize_t set_pwm##offset(struct device *dev, struct device_attribute *attr, const char *buf, \
+	size_t count) \
+{ \
+	struct i2c_client *client = to_i2c_client(dev); \
+	struct pc87360_data *data = i2c_get_clientdata(client); \
+	long val = simple_strtol(buf, NULL, 10); \
+ \
+	down(&data->update_lock); \
+	data->pwm[offset-1] = PWM_TO_REG(val, \
+			      FAN_CONFIG_INVERT(data->fan_conf, offset-1)); \
+	pc87360_write_value(data, LD_FAN, NO_BANK, PC87360_REG_PWM(offset-1), \
+			    data->pwm[offset-1]); \
+	up(&data->update_lock); \
+	return count; \
+} \
+static DEVICE_ATTR(pwm##offset, S_IWUSR | S_IRUGO, \
+	show_pwm##offset, set_pwm##offset);
+show_and_set_pwm(1)
+show_and_set_pwm(2)
+show_and_set_pwm(3)
+
+#define show_and_set_in(offset) \
+static ssize_t show_in##offset##_input(struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+	struct pc87360_data *data = pc87360_update_device(dev); \
+	return sprintf(buf, "%u\n", IN_FROM_REG(data->in[offset], \
+		       data->in_vref)); \
+} \
+static ssize_t show_in##offset##_min(struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+	struct pc87360_data *data = pc87360_update_device(dev); \
+	return sprintf(buf, "%u\n", IN_FROM_REG(data->in_min[offset], \
+		       data->in_vref)); \
+} \
+static ssize_t show_in##offset##_max(struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+	struct pc87360_data *data = pc87360_update_device(dev); \
+	return sprintf(buf, "%u\n", IN_FROM_REG(data->in_max[offset], \
+		       data->in_vref)); \
+} \
+static ssize_t show_in##offset##_status(struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+	struct pc87360_data *data = pc87360_update_device(dev); \
+	return sprintf(buf, "%u\n", data->in_status[offset]); \
+} \
+static ssize_t set_in##offset##_min(struct device *dev, struct device_attribute *attr, const char *buf, \
+	size_t count) \
+{ \
+	struct i2c_client *client = to_i2c_client(dev); \
+	struct pc87360_data *data = i2c_get_clientdata(client); \
+	long val = simple_strtol(buf, NULL, 10); \
+ \
+	down(&data->update_lock); \
+	data->in_min[offset] = IN_TO_REG(val, data->in_vref); \
+	pc87360_write_value(data, LD_IN, offset, PC87365_REG_IN_MIN, \
+			    data->in_min[offset]); \
+	up(&data->update_lock); \
+	return count; \
+} \
+static ssize_t set_in##offset##_max(struct device *dev, struct device_attribute *attr, const char *buf, \
+	size_t count) \
+{ \
+	struct i2c_client *client = to_i2c_client(dev); \
+	struct pc87360_data *data = i2c_get_clientdata(client); \
+	long val = simple_strtol(buf, NULL, 10); \
+ \
+	down(&data->update_lock); \
+	data->in_max[offset] = IN_TO_REG(val, \
+			       data->in_vref); \
+	pc87360_write_value(data, LD_IN, offset, PC87365_REG_IN_MAX, \
+			    data->in_max[offset]); \
+	up(&data->update_lock); \
+	return count; \
+} \
+static DEVICE_ATTR(in##offset##_input, S_IRUGO, \
+	show_in##offset##_input, NULL); \
+static DEVICE_ATTR(in##offset##_min, S_IWUSR | S_IRUGO, \
+	show_in##offset##_min, set_in##offset##_min); \
+static DEVICE_ATTR(in##offset##_max, S_IWUSR | S_IRUGO, \
+	show_in##offset##_max, set_in##offset##_max); \
+static DEVICE_ATTR(in##offset##_status, S_IRUGO, \
+	show_in##offset##_status, NULL);
+show_and_set_in(0)
+show_and_set_in(1)
+show_and_set_in(2)
+show_and_set_in(3)
+show_and_set_in(4)
+show_and_set_in(5)
+show_and_set_in(6)
+show_and_set_in(7)
+show_and_set_in(8)
+show_and_set_in(9)
+show_and_set_in(10)
+
+#define show_and_set_therm(offset) \
+static ssize_t show_temp##offset##_input(struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+	struct pc87360_data *data = pc87360_update_device(dev); \
+	return sprintf(buf, "%u\n", IN_FROM_REG(data->in[offset+7], \
+		       data->in_vref)); \
+} \
+static ssize_t show_temp##offset##_min(struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+	struct pc87360_data *data = pc87360_update_device(dev); \
+	return sprintf(buf, "%u\n", IN_FROM_REG(data->in_min[offset+7], \
+		       data->in_vref)); \
+} \
+static ssize_t show_temp##offset##_max(struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+	struct pc87360_data *data = pc87360_update_device(dev); \
+	return sprintf(buf, "%u\n", IN_FROM_REG(data->in_max[offset+7], \
+		       data->in_vref)); \
+} \
+static ssize_t show_temp##offset##_crit(struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+	struct pc87360_data *data = pc87360_update_device(dev); \
+	return sprintf(buf, "%u\n", IN_FROM_REG(data->in_crit[offset-4], \
+		       data->in_vref)); \
+} \
+static ssize_t show_temp##offset##_status(struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+	struct pc87360_data *data = pc87360_update_device(dev); \
+	return sprintf(buf, "%u\n", data->in_status[offset+7]); \
+} \
+static ssize_t set_temp##offset##_min(struct device *dev, struct device_attribute *attr, const char *buf, \
+	size_t count) \
+{ \
+	struct i2c_client *client = to_i2c_client(dev); \
+	struct pc87360_data *data = i2c_get_clientdata(client); \
+	long val = simple_strtol(buf, NULL, 10); \
+ \
+	down(&data->update_lock); \
+	data->in_min[offset+7] = IN_TO_REG(val, data->in_vref); \
+	pc87360_write_value(data, LD_IN, offset+7, PC87365_REG_TEMP_MIN, \
+			    data->in_min[offset+7]); \
+	up(&data->update_lock); \
+	return count; \
+} \
+static ssize_t set_temp##offset##_max(struct device *dev, struct device_attribute *attr, const char *buf, \
+	size_t count) \
+{ \
+	struct i2c_client *client = to_i2c_client(dev); \
+	struct pc87360_data *data = i2c_get_clientdata(client); \
+	long val = simple_strtol(buf, NULL, 10); \
+ \
+	down(&data->update_lock); \
+	data->in_max[offset+7] = IN_TO_REG(val, data->in_vref); \
+	pc87360_write_value(data, LD_IN, offset+7, PC87365_REG_TEMP_MAX, \
+			    data->in_max[offset+7]); \
+	up(&data->update_lock); \
+	return count; \
+} \
+static ssize_t set_temp##offset##_crit(struct device *dev, struct device_attribute *attr, const char *buf, \
+	size_t count) \
+{ \
+	struct i2c_client *client = to_i2c_client(dev); \
+	struct pc87360_data *data = i2c_get_clientdata(client); \
+	long val = simple_strtol(buf, NULL, 10); \
+ \
+	down(&data->update_lock); \
+	data->in_crit[offset-4] = IN_TO_REG(val, data->in_vref); \
+	pc87360_write_value(data, LD_IN, offset+7, PC87365_REG_TEMP_CRIT, \
+			    data->in_crit[offset-4]); \
+	up(&data->update_lock); \
+	return count; \
+} \
+static DEVICE_ATTR(temp##offset##_input, S_IRUGO, \
+	show_temp##offset##_input, NULL); \
+static DEVICE_ATTR(temp##offset##_min, S_IWUSR | S_IRUGO, \
+	show_temp##offset##_min, set_temp##offset##_min); \
+static DEVICE_ATTR(temp##offset##_max, S_IWUSR | S_IRUGO, \
+	show_temp##offset##_max, set_temp##offset##_max); \
+static DEVICE_ATTR(temp##offset##_crit, S_IWUSR | S_IRUGO, \
+	show_temp##offset##_crit, set_temp##offset##_crit); \
+static DEVICE_ATTR(temp##offset##_status, S_IRUGO, \
+	show_temp##offset##_status, NULL);
+show_and_set_therm(4)
+show_and_set_therm(5)
+show_and_set_therm(6)
+
+static ssize_t show_vid(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct pc87360_data *data = pc87360_update_device(dev);
+	return sprintf(buf, "%u\n", vid_from_reg(data->vid, data->vrm));
+}
+static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL);
+
+static ssize_t show_vrm(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct pc87360_data *data = pc87360_update_device(dev);
+	return sprintf(buf, "%u\n", data->vrm);
+}
+static ssize_t set_vrm(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct pc87360_data *data = i2c_get_clientdata(client);
+	data->vrm = simple_strtoul(buf, NULL, 10);
+	return count;
+}
+static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm, set_vrm);
+
+static ssize_t show_in_alarms(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct pc87360_data *data = pc87360_update_device(dev);
+	return sprintf(buf, "%u\n", data->in_alarms);
+}
+static DEVICE_ATTR(alarms_in, S_IRUGO, show_in_alarms, NULL);
+
+#define show_and_set_temp(offset) \
+static ssize_t show_temp##offset##_input(struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+	struct pc87360_data *data = pc87360_update_device(dev); \
+	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp[offset-1])); \
+} \
+static ssize_t show_temp##offset##_min(struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+	struct pc87360_data *data = pc87360_update_device(dev); \
+	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_min[offset-1])); \
+} \
+static ssize_t show_temp##offset##_max(struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+	struct pc87360_data *data = pc87360_update_device(dev); \
+	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_max[offset-1])); \
+}\
+static ssize_t show_temp##offset##_crit(struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+	struct pc87360_data *data = pc87360_update_device(dev); \
+	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_crit[offset-1])); \
+}\
+static ssize_t show_temp##offset##_status(struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+	struct pc87360_data *data = pc87360_update_device(dev); \
+	return sprintf(buf, "%d\n", data->temp_status[offset-1]); \
+}\
+static ssize_t set_temp##offset##_min(struct device *dev, struct device_attribute *attr, const char *buf, \
+	size_t count) \
+{ \
+	struct i2c_client *client = to_i2c_client(dev); \
+	struct pc87360_data *data = i2c_get_clientdata(client); \
+	long val = simple_strtol(buf, NULL, 10); \
+ \
+	down(&data->update_lock); \
+	data->temp_min[offset-1] = TEMP_TO_REG(val); \
+	pc87360_write_value(data, LD_TEMP, offset-1, PC87365_REG_TEMP_MIN, \
+			    data->temp_min[offset-1]); \
+	up(&data->update_lock); \
+	return count; \
+} \
+static ssize_t set_temp##offset##_max(struct device *dev, struct device_attribute *attr, const char *buf, \
+	size_t count) \
+{ \
+	struct i2c_client *client = to_i2c_client(dev); \
+	struct pc87360_data *data = i2c_get_clientdata(client); \
+	long val = simple_strtol(buf, NULL, 10); \
+ \
+	down(&data->update_lock); \
+	data->temp_max[offset-1] = TEMP_TO_REG(val); \
+	pc87360_write_value(data, LD_TEMP, offset-1, PC87365_REG_TEMP_MAX, \
+			    data->temp_max[offset-1]); \
+	up(&data->update_lock); \
+	return count; \
+} \
+static ssize_t set_temp##offset##_crit(struct device *dev, struct device_attribute *attr, const char *buf, \
+	size_t count) \
+{ \
+	struct i2c_client *client = to_i2c_client(dev); \
+	struct pc87360_data *data = i2c_get_clientdata(client); \
+	long val = simple_strtol(buf, NULL, 10); \
+ \
+	down(&data->update_lock); \
+	data->temp_crit[offset-1] = TEMP_TO_REG(val); \
+	pc87360_write_value(data, LD_TEMP, offset-1, PC87365_REG_TEMP_CRIT, \
+			    data->temp_crit[offset-1]); \
+	up(&data->update_lock); \
+	return count; \
+} \
+static DEVICE_ATTR(temp##offset##_input, S_IRUGO, \
+	show_temp##offset##_input, NULL); \
+static DEVICE_ATTR(temp##offset##_min, S_IWUSR | S_IRUGO, \
+	show_temp##offset##_min, set_temp##offset##_min); \
+static DEVICE_ATTR(temp##offset##_max, S_IWUSR | S_IRUGO, \
+	show_temp##offset##_max, set_temp##offset##_max); \
+static DEVICE_ATTR(temp##offset##_crit, S_IWUSR | S_IRUGO, \
+	show_temp##offset##_crit, set_temp##offset##_crit); \
+static DEVICE_ATTR(temp##offset##_status, S_IRUGO, \
+	show_temp##offset##_status, NULL);
+show_and_set_temp(1)
+show_and_set_temp(2)
+show_and_set_temp(3)
+
+static ssize_t show_temp_alarms(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct pc87360_data *data = pc87360_update_device(dev);
+	return sprintf(buf, "%u\n", data->temp_alarms);
+}
+static DEVICE_ATTR(alarms_temp, S_IRUGO, show_temp_alarms, NULL);
+
+/*
+ * Device detection, registration and update
+ */
+
+static int pc87360_attach_adapter(struct i2c_adapter *adapter)
+{
+	return i2c_detect(adapter, &addr_data, pc87360_detect);
+}
+
+static int pc87360_find(int sioaddr, u8 *devid, int *address)
+{
+	u16 val;
+	int i;
+	int nrdev; /* logical device count */
+
+	/* No superio_enter */
+
+	/* Identify device */
+	val = superio_inb(sioaddr, DEVID);
+	switch (val) {
+	case 0xE1: /* PC87360 */
+	case 0xE8: /* PC87363 */
+	case 0xE4: /* PC87364 */
+		nrdev = 1;
+		break;
+	case 0xE5: /* PC87365 */
+	case 0xE9: /* PC87366 */
+		nrdev = 3;
+		break;
+	default:
+		superio_exit(sioaddr);
+		return -ENODEV;
+	}
+	/* Remember the device id */
+	*devid = val;
+
+	for (i = 0; i < nrdev; i++) {
+		/* select logical device */
+		superio_outb(sioaddr, DEV, logdev[i]);
+
+		val = superio_inb(sioaddr, ACT);
+		if (!(val & 0x01)) {
+			printk(KERN_INFO "pc87360: Device 0x%02x not "
+			       "activated\n", logdev[i]);
+			continue;
+		}
+
+		val = (superio_inb(sioaddr, BASE) << 8)
+		    | superio_inb(sioaddr, BASE + 1);
+		if (!val) {
+			printk(KERN_INFO "pc87360: Base address not set for "
+			       "device 0x%02x\n", logdev[i]);
+			continue;
+		}
+
+		address[i] = val;
+
+		if (i==0) { /* Fans */
+			confreg[0] = superio_inb(sioaddr, 0xF0);
+			confreg[1] = superio_inb(sioaddr, 0xF1);
+
+#ifdef DEBUG
+			printk(KERN_DEBUG "pc87360: Fan 1: mon=%d "
+			       "ctrl=%d inv=%d\n", (confreg[0]>>2)&1,
+			       (confreg[0]>>3)&1, (confreg[0]>>4)&1);
+			printk(KERN_DEBUG "pc87360: Fan 2: mon=%d "
+			       "ctrl=%d inv=%d\n", (confreg[0]>>5)&1,
+			       (confreg[0]>>6)&1, (confreg[0]>>7)&1);
+			printk(KERN_DEBUG "pc87360: Fan 3: mon=%d "
+			       "ctrl=%d inv=%d\n", confreg[1]&1,
+			       (confreg[1]>>1)&1, (confreg[1]>>2)&1);
+#endif
+		} else if (i==1) { /* Voltages */
+			/* Are we using thermistors? */
+			if (*devid == 0xE9) { /* PC87366 */
+				/* These registers are not logical-device
+				   specific, just that we won't need them if
+				   we don't use the VLM device */
+				confreg[2] = superio_inb(sioaddr, 0x2B);
+				confreg[3] = superio_inb(sioaddr, 0x25);
+
+				if (confreg[2] & 0x40) {
+					printk(KERN_INFO "pc87360: Using "
+					       "thermistors for temperature "
+					       "monitoring\n");
+				}
+				if (confreg[3] & 0xE0) {
+					printk(KERN_INFO "pc87360: VID "
+					       "inputs routed (mode %u)\n",
+					       confreg[3] >> 5);
+				}
+			}
+		}
+	}
+
+	superio_exit(sioaddr);
+	return 0;
+}
+
+/* We don't really care about the address.
+   Read from extra_isa instead. */
+int pc87360_detect(struct i2c_adapter *adapter, int address, int kind)
+{
+	int i;
+	struct i2c_client *new_client;
+	struct pc87360_data *data;
+	int err = 0;
+	const char *name = "pc87360";
+	int use_thermistors = 0;
+
+	if (!i2c_is_isa_adapter(adapter))
+		return -ENODEV;
+
+	if (!(data = kmalloc(sizeof(struct pc87360_data), GFP_KERNEL)))
+		return -ENOMEM;
+	memset(data, 0x00, sizeof(struct pc87360_data));
+
+	new_client = &data->client;
+	i2c_set_clientdata(new_client, data);
+	new_client->addr = address;
+	init_MUTEX(&data->lock);
+	new_client->adapter = adapter;
+	new_client->driver = &pc87360_driver;
+	new_client->flags = 0;
+
+	data->fannr = 2;
+	data->innr = 0;
+	data->tempnr = 0;
+
+	switch (devid) {
+	case 0xe8:
+		name = "pc87363";
+		break;
+	case 0xe4:
+		name = "pc87364";
+		data->fannr = 3;
+		break;
+	case 0xe5:
+		name = "pc87365";
+		data->fannr = extra_isa[0] ? 3 : 0;
+		data->innr = extra_isa[1] ? 11 : 0;
+		data->tempnr = extra_isa[2] ? 2 : 0;
+		break;
+	case 0xe9:
+		name = "pc87366";
+		data->fannr = extra_isa[0] ? 3 : 0;
+		data->innr = extra_isa[1] ? 14 : 0;
+		data->tempnr = extra_isa[2] ? 3 : 0;
+		break;
+	}
+
+	strcpy(new_client->name, name);
+	data->valid = 0;
+	init_MUTEX(&data->update_lock);
+
+	for (i = 0; i < 3; i++) {
+		if (((data->address[i] = extra_isa[i]))
+		 && !request_region(extra_isa[i], PC87360_EXTENT,
+		 		    pc87360_driver.name)) {
+			dev_err(&new_client->dev, "Region 0x%x-0x%x already "
+				"in use!\n", extra_isa[i],
+				extra_isa[i]+PC87360_EXTENT-1);
+			for (i--; i >= 0; i--)
+				release_region(extra_isa[i], PC87360_EXTENT);
+			err = -EBUSY;
+			goto ERROR1;
+		}
+	}
+
+	/* Retrieve the fans configuration from Super-I/O space */
+	if (data->fannr)
+		data->fan_conf = confreg[0] | (confreg[1] << 8);
+
+	if ((err = i2c_attach_client(new_client)))
+		goto ERROR2;
+
+	/* Use the correct reference voltage
+	   Unless both the VLM and the TMS logical devices agree to
+	   use an external Vref, the internal one is used. */
+	if (data->innr) {
+		i = pc87360_read_value(data, LD_IN, NO_BANK,
+				       PC87365_REG_IN_CONFIG);
+		if (data->tempnr) {
+			i &= pc87360_read_value(data, LD_TEMP, NO_BANK,
+						PC87365_REG_TEMP_CONFIG);
+		}
+		data->in_vref = (i&0x02) ? 3025 : 2966;
+		dev_dbg(&new_client->dev, "Using %s reference voltage\n",
+			(i&0x02) ? "external" : "internal");
+
+		data->vid_conf = confreg[3];
+		data->vrm = 90;
+	}
+
+	/* Fan clock dividers may be needed before any data is read */
+	for (i = 0; i < data->fannr; i++) {
+		if (FAN_CONFIG_MONITOR(data->fan_conf, i))
+			data->fan_status[i] = pc87360_read_value(data,
+					      LD_FAN, NO_BANK,
+					      PC87360_REG_FAN_STATUS(i));
+	}
+
+	if (init > 0) {
+		if (devid == 0xe9 && data->address[1]) /* PC87366 */
+			use_thermistors = confreg[2] & 0x40;
+
+		pc87360_init_client(new_client, use_thermistors);
+	}
+
+	/* Register sysfs hooks */
+	if (data->innr) {
+		device_create_file(&new_client->dev, &dev_attr_in0_input);
+		device_create_file(&new_client->dev, &dev_attr_in1_input);
+		device_create_file(&new_client->dev, &dev_attr_in2_input);
+		device_create_file(&new_client->dev, &dev_attr_in3_input);
+		device_create_file(&new_client->dev, &dev_attr_in4_input);
+		device_create_file(&new_client->dev, &dev_attr_in5_input);
+		device_create_file(&new_client->dev, &dev_attr_in6_input);
+		device_create_file(&new_client->dev, &dev_attr_in7_input);
+		device_create_file(&new_client->dev, &dev_attr_in8_input);
+		device_create_file(&new_client->dev, &dev_attr_in9_input);
+		device_create_file(&new_client->dev, &dev_attr_in10_input);
+		device_create_file(&new_client->dev, &dev_attr_in0_min);
+		device_create_file(&new_client->dev, &dev_attr_in1_min);
+		device_create_file(&new_client->dev, &dev_attr_in2_min);
+		device_create_file(&new_client->dev, &dev_attr_in3_min);
+		device_create_file(&new_client->dev, &dev_attr_in4_min);
+		device_create_file(&new_client->dev, &dev_attr_in5_min);
+		device_create_file(&new_client->dev, &dev_attr_in6_min);
+		device_create_file(&new_client->dev, &dev_attr_in7_min);
+		device_create_file(&new_client->dev, &dev_attr_in8_min);
+		device_create_file(&new_client->dev, &dev_attr_in9_min);
+		device_create_file(&new_client->dev, &dev_attr_in10_min);
+		device_create_file(&new_client->dev, &dev_attr_in0_max);
+		device_create_file(&new_client->dev, &dev_attr_in1_max);
+		device_create_file(&new_client->dev, &dev_attr_in2_max);
+		device_create_file(&new_client->dev, &dev_attr_in3_max);
+		device_create_file(&new_client->dev, &dev_attr_in4_max);
+		device_create_file(&new_client->dev, &dev_attr_in5_max);
+		device_create_file(&new_client->dev, &dev_attr_in6_max);
+		device_create_file(&new_client->dev, &dev_attr_in7_max);
+		device_create_file(&new_client->dev, &dev_attr_in8_max);
+		device_create_file(&new_client->dev, &dev_attr_in9_max);
+		device_create_file(&new_client->dev, &dev_attr_in10_max);
+		device_create_file(&new_client->dev, &dev_attr_in0_status);
+		device_create_file(&new_client->dev, &dev_attr_in1_status);
+		device_create_file(&new_client->dev, &dev_attr_in2_status);
+		device_create_file(&new_client->dev, &dev_attr_in3_status);
+		device_create_file(&new_client->dev, &dev_attr_in4_status);
+		device_create_file(&new_client->dev, &dev_attr_in5_status);
+		device_create_file(&new_client->dev, &dev_attr_in6_status);
+		device_create_file(&new_client->dev, &dev_attr_in7_status);
+		device_create_file(&new_client->dev, &dev_attr_in8_status);
+		device_create_file(&new_client->dev, &dev_attr_in9_status);
+		device_create_file(&new_client->dev, &dev_attr_in10_status);
+
+		device_create_file(&new_client->dev, &dev_attr_cpu0_vid);
+		device_create_file(&new_client->dev, &dev_attr_vrm);
+		device_create_file(&new_client->dev, &dev_attr_alarms_in);
+	}
+
+	if (data->tempnr) {
+		device_create_file(&new_client->dev, &dev_attr_temp1_input);
+		device_create_file(&new_client->dev, &dev_attr_temp2_input);
+		device_create_file(&new_client->dev, &dev_attr_temp1_min);
+		device_create_file(&new_client->dev, &dev_attr_temp2_min);
+		device_create_file(&new_client->dev, &dev_attr_temp1_max);
+		device_create_file(&new_client->dev, &dev_attr_temp2_max);
+		device_create_file(&new_client->dev, &dev_attr_temp1_crit);
+		device_create_file(&new_client->dev, &dev_attr_temp2_crit);
+		device_create_file(&new_client->dev, &dev_attr_temp1_status);
+		device_create_file(&new_client->dev, &dev_attr_temp2_status);
+
+		device_create_file(&new_client->dev, &dev_attr_alarms_temp);
+	}
+	if (data->tempnr == 3) {
+		device_create_file(&new_client->dev, &dev_attr_temp3_input);
+		device_create_file(&new_client->dev, &dev_attr_temp3_min);
+		device_create_file(&new_client->dev, &dev_attr_temp3_max);
+		device_create_file(&new_client->dev, &dev_attr_temp3_crit);
+		device_create_file(&new_client->dev, &dev_attr_temp3_status);
+	}
+	if (data->innr == 14) {
+		device_create_file(&new_client->dev, &dev_attr_temp4_input);
+		device_create_file(&new_client->dev, &dev_attr_temp5_input);
+		device_create_file(&new_client->dev, &dev_attr_temp6_input);
+		device_create_file(&new_client->dev, &dev_attr_temp4_min);
+		device_create_file(&new_client->dev, &dev_attr_temp5_min);
+		device_create_file(&new_client->dev, &dev_attr_temp6_min);
+		device_create_file(&new_client->dev, &dev_attr_temp4_max);
+		device_create_file(&new_client->dev, &dev_attr_temp5_max);
+		device_create_file(&new_client->dev, &dev_attr_temp6_max);
+		device_create_file(&new_client->dev, &dev_attr_temp4_crit);
+		device_create_file(&new_client->dev, &dev_attr_temp5_crit);
+		device_create_file(&new_client->dev, &dev_attr_temp6_crit);
+		device_create_file(&new_client->dev, &dev_attr_temp4_status);
+		device_create_file(&new_client->dev, &dev_attr_temp5_status);
+		device_create_file(&new_client->dev, &dev_attr_temp6_status);
+	}
+
+	if (data->fannr) {
+		if (FAN_CONFIG_MONITOR(data->fan_conf, 0)) {
+			device_create_file(&new_client->dev,
+					   &dev_attr_fan1_input);
+			device_create_file(&new_client->dev,
+					   &dev_attr_fan1_min);
+			device_create_file(&new_client->dev,
+					   &dev_attr_fan1_div);
+			device_create_file(&new_client->dev,
+					   &dev_attr_fan1_status);
+		}
+
+		if (FAN_CONFIG_MONITOR(data->fan_conf, 1)) {
+			device_create_file(&new_client->dev,
+					   &dev_attr_fan2_input);
+			device_create_file(&new_client->dev,
+					   &dev_attr_fan2_min);
+			device_create_file(&new_client->dev,
+					   &dev_attr_fan2_div);
+			device_create_file(&new_client->dev,
+					   &dev_attr_fan2_status);
+		}
+
+		if (FAN_CONFIG_CONTROL(data->fan_conf, 0))
+			device_create_file(&new_client->dev, &dev_attr_pwm1);
+		if (FAN_CONFIG_CONTROL(data->fan_conf, 1))
+			device_create_file(&new_client->dev, &dev_attr_pwm2);
+	}
+	if (data->fannr == 3) {
+		if (FAN_CONFIG_MONITOR(data->fan_conf, 2)) {
+			device_create_file(&new_client->dev,
+					   &dev_attr_fan3_input);
+			device_create_file(&new_client->dev,
+					   &dev_attr_fan3_min);
+			device_create_file(&new_client->dev,
+					   &dev_attr_fan3_div);
+			device_create_file(&new_client->dev,
+					   &dev_attr_fan3_status);
+		}
+
+		if (FAN_CONFIG_CONTROL(data->fan_conf, 2))
+			device_create_file(&new_client->dev, &dev_attr_pwm3);
+	}
+
+	return 0;
+
+ERROR2:
+	for (i = 0; i < 3; i++) {
+		if (data->address[i]) {
+			release_region(data->address[i], PC87360_EXTENT);
+		}
+	}
+ERROR1:
+	kfree(data);
+	return err;
+}
+
+static int pc87360_detach_client(struct i2c_client *client)
+{
+	struct pc87360_data *data = i2c_get_clientdata(client);
+	int i;
+
+	if ((i = i2c_detach_client(client))) {
+		dev_err(&client->dev, "Client deregistration failed, "
+			"client not detached.\n");
+		return i;
+	}
+
+	for (i = 0; i < 3; i++) {
+		if (data->address[i]) {
+			release_region(data->address[i], PC87360_EXTENT);
+		}
+	}
+	kfree(data);
+
+	return 0;
+}
+
+/* ldi is the logical device index
+   bank is for voltages and temperatures only */
+static int pc87360_read_value(struct pc87360_data *data, u8 ldi, u8 bank,
+			      u8 reg)
+{
+	int res;
+
+	down(&(data->lock));
+	if (bank != NO_BANK)
+		outb_p(bank, data->address[ldi] + PC87365_REG_BANK);
+	res = inb_p(data->address[ldi] + reg);
+	up(&(data->lock));
+
+	return res;
+}
+
+static void pc87360_write_value(struct pc87360_data *data, u8 ldi, u8 bank,
+				u8 reg, u8 value)
+{
+	down(&(data->lock));
+	if (bank != NO_BANK)
+		outb_p(bank, data->address[ldi] + PC87365_REG_BANK);
+	outb_p(value, data->address[ldi] + reg);
+	up(&(data->lock));
+}
+
+static void pc87360_init_client(struct i2c_client *client, int use_thermistors)
+{
+	struct pc87360_data *data = i2c_get_clientdata(client);
+	int i, nr;
+	const u8 init_in[14] = { 2, 2, 2, 2, 2, 2, 2, 1, 1, 3, 1, 2, 2, 2 };
+	const u8 init_temp[3] = { 2, 2, 1 };
+	u8 reg;
+
+	if (init >= 2 && data->innr) {
+		reg = pc87360_read_value(data, LD_IN, NO_BANK,
+					 PC87365_REG_IN_CONVRATE);
+		dev_info(&client->dev, "VLM conversion set to "
+			 "1s period, 160us delay\n");
+		pc87360_write_value(data, LD_IN, NO_BANK,
+				    PC87365_REG_IN_CONVRATE,
+				    (reg & 0xC0) | 0x11);
+	}
+
+	nr = data->innr < 11 ? data->innr : 11;
+	for (i=0; i<nr; i++) {
+		if (init >= init_in[i]) {
+			/* Forcibly enable voltage channel */
+			reg = pc87360_read_value(data, LD_IN, i,
+						 PC87365_REG_IN_STATUS);
+			if (!(reg & 0x01)) {
+				dev_dbg(&client->dev, "Forcibly "
+					"enabling in%d\n", i);
+				pc87360_write_value(data, LD_IN, i,
+						    PC87365_REG_IN_STATUS,
+						    (reg & 0x68) | 0x87);
+			}
+		}
+	}
+
+	/* We can't blindly trust the Super-I/O space configuration bit,
+	   most BIOS won't set it properly */
+	for (i=11; i<data->innr; i++) {
+		reg = pc87360_read_value(data, LD_IN, i,
+					 PC87365_REG_TEMP_STATUS);
+		use_thermistors = use_thermistors || (reg & 0x01);
+	}
+
+	i = use_thermistors ? 2 : 0;
+	for (; i<data->tempnr; i++) {
+		if (init >= init_temp[i]) {
+			/* Forcibly enable temperature channel */
+			reg = pc87360_read_value(data, LD_TEMP, i,
+						 PC87365_REG_TEMP_STATUS);
+			if (!(reg & 0x01)) {
+				dev_dbg(&client->dev, "Forcibly "
+					"enabling temp%d\n", i+1);
+				pc87360_write_value(data, LD_TEMP, i,
+						    PC87365_REG_TEMP_STATUS,
+						    0xCF);
+			}
+		}
+	}
+
+	if (use_thermistors) {
+		for (i=11; i<data->innr; i++) {
+			if (init >= init_in[i]) {
+				/* The pin may already be used by thermal
+				   diodes */
+				reg = pc87360_read_value(data, LD_TEMP,
+				      (i-11)/2, PC87365_REG_TEMP_STATUS);
+				if (reg & 0x01) {
+					dev_dbg(&client->dev, "Skipping "
+						"temp%d, pin already in use "
+						"by temp%d\n", i-7, (i-11)/2);
+					continue;
+				}
+
+				/* Forcibly enable thermistor channel */
+				reg = pc87360_read_value(data, LD_IN, i,
+							 PC87365_REG_IN_STATUS);
+				if (!(reg & 0x01)) {
+					dev_dbg(&client->dev, "Forcibly "
+						"enabling temp%d\n", i-7);
+					pc87360_write_value(data, LD_IN, i,
+						PC87365_REG_TEMP_STATUS,
+						(reg & 0x60) | 0x8F);
+				}
+			}
+		}
+	}
+
+	if (data->innr) {
+		reg = pc87360_read_value(data, LD_IN, NO_BANK,
+					 PC87365_REG_IN_CONFIG);
+		if (reg & 0x01) {
+			dev_dbg(&client->dev, "Forcibly "
+				"enabling monitoring (VLM)\n");
+			pc87360_write_value(data, LD_IN, NO_BANK,
+					    PC87365_REG_IN_CONFIG,
+					    reg & 0xFE);
+		}
+	}
+
+	if (data->tempnr) {
+		reg = pc87360_read_value(data, LD_TEMP, NO_BANK,
+					 PC87365_REG_TEMP_CONFIG);
+		if (reg & 0x01) {
+			dev_dbg(&client->dev, "Forcibly enabling "
+				"monitoring (TMS)\n");
+			pc87360_write_value(data, LD_TEMP, NO_BANK,
+					    PC87365_REG_TEMP_CONFIG,
+					    reg & 0xFE);
+		}
+
+		if (init >= 2) {
+			/* Chip config as documented by National Semi. */
+			pc87360_write_value(data, LD_TEMP, 0xF, 0xA, 0x08);
+			/* We voluntarily omit the bank here, in case the
+			   sequence itself matters. It shouldn't be a problem,
+			   since nobody else is supposed to access the
+			   device at that point. */
+			pc87360_write_value(data, LD_TEMP, NO_BANK, 0xB, 0x04);
+			pc87360_write_value(data, LD_TEMP, NO_BANK, 0xC, 0x35);
+			pc87360_write_value(data, LD_TEMP, NO_BANK, 0xD, 0x05);
+			pc87360_write_value(data, LD_TEMP, NO_BANK, 0xE, 0x05);
+		}
+	}
+}
+
+static void pc87360_autodiv(struct i2c_client *client, int nr)
+{
+	struct pc87360_data *data = i2c_get_clientdata(client);
+	u8 old_min = data->fan_min[nr];
+
+	/* Increase clock divider if needed and possible */
+	if ((data->fan_status[nr] & 0x04) /* overflow flag */
+	 || (data->fan[nr] >= 224)) { /* next to overflow */
+		if ((data->fan_status[nr] & 0x60) != 0x60) {
+			data->fan_status[nr] += 0x20;
+			data->fan_min[nr] >>= 1;
+			data->fan[nr] >>= 1;
+			dev_dbg(&client->dev, "Increasing "
+				"clock divider to %d for fan %d\n",
+				FAN_DIV_FROM_REG(data->fan_status[nr]), nr+1);
+		}
+	} else {
+		/* Decrease clock divider if possible */
+		while (!(data->fan_min[nr] & 0x80) /* min "nails" divider */
+		 && data->fan[nr] < 85 /* bad accuracy */
+		 && (data->fan_status[nr] & 0x60) != 0x00) {
+			data->fan_status[nr] -= 0x20;
+			data->fan_min[nr] <<= 1;
+			data->fan[nr] <<= 1;
+			dev_dbg(&client->dev, "Decreasing "
+				"clock divider to %d for fan %d\n",
+				FAN_DIV_FROM_REG(data->fan_status[nr]),
+				nr+1);
+		}
+	}
+
+	/* Write new fan min if it changed */
+	if (old_min != data->fan_min[nr]) {
+		pc87360_write_value(data, LD_FAN, NO_BANK,
+				    PC87360_REG_FAN_MIN(nr),
+				    data->fan_min[nr]);
+	}
+}
+
+static struct pc87360_data *pc87360_update_device(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct pc87360_data *data = i2c_get_clientdata(client);
+	u8 i;
+
+	down(&data->update_lock);
+
+	if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) {
+		dev_dbg(&client->dev, "Data update\n");
+
+		/* Fans */
+		for (i = 0; i < data->fannr; i++) {
+			if (FAN_CONFIG_MONITOR(data->fan_conf, i)) {
+				data->fan_status[i] =
+					pc87360_read_value(data, LD_FAN,
+					NO_BANK, PC87360_REG_FAN_STATUS(i));
+				data->fan[i] = pc87360_read_value(data, LD_FAN,
+					       NO_BANK, PC87360_REG_FAN(i));
+				data->fan_min[i] = pc87360_read_value(data,
+						   LD_FAN, NO_BANK,
+						   PC87360_REG_FAN_MIN(i));
+				/* Change clock divider if needed */
+				pc87360_autodiv(client, i);
+				/* Clear bits and write new divider */
+				pc87360_write_value(data, LD_FAN, NO_BANK,
+						    PC87360_REG_FAN_STATUS(i),
+						    data->fan_status[i]);
+			}
+			if (FAN_CONFIG_CONTROL(data->fan_conf, i))
+				data->pwm[i] = pc87360_read_value(data, LD_FAN,
+					       NO_BANK, PC87360_REG_PWM(i));
+		}
+
+		/* Voltages */
+		for (i = 0; i < data->innr; i++) {
+			data->in_status[i] = pc87360_read_value(data, LD_IN, i,
+					     PC87365_REG_IN_STATUS);
+			/* Clear bits */
+			pc87360_write_value(data, LD_IN, i,
+					    PC87365_REG_IN_STATUS,
+					    data->in_status[i]);
+			if ((data->in_status[i] & 0x81) == 0x81) {
+				data->in[i] = pc87360_read_value(data, LD_IN,
+					      i, PC87365_REG_IN);
+			}
+			if (data->in_status[i] & 0x01) {
+				data->in_min[i] = pc87360_read_value(data,
+						  LD_IN, i,
+						  PC87365_REG_IN_MIN);
+				data->in_max[i] = pc87360_read_value(data,
+						  LD_IN, i,
+						  PC87365_REG_IN_MAX);
+				if (i >= 11)
+					data->in_crit[i-11] =
+						pc87360_read_value(data, LD_IN,
+						i, PC87365_REG_TEMP_CRIT);
+			}
+		}
+		if (data->innr) {
+			data->in_alarms = pc87360_read_value(data, LD_IN,
+					  NO_BANK, PC87365_REG_IN_ALARMS1)
+					| ((pc87360_read_value(data, LD_IN,
+					    NO_BANK, PC87365_REG_IN_ALARMS2)
+					    & 0x07) << 8);
+			data->vid = (data->vid_conf & 0xE0) ?
+				    pc87360_read_value(data, LD_IN,
+				    NO_BANK, PC87365_REG_VID) : 0x1F;
+		}
+
+		/* Temperatures */
+		for (i = 0; i < data->tempnr; i++) {
+			data->temp_status[i] = pc87360_read_value(data,
+					       LD_TEMP, i,
+					       PC87365_REG_TEMP_STATUS);
+			/* Clear bits */
+			pc87360_write_value(data, LD_TEMP, i,
+					    PC87365_REG_TEMP_STATUS,
+					    data->temp_status[i]);
+			if ((data->temp_status[i] & 0x81) == 0x81) {
+				data->temp[i] = pc87360_read_value(data,
+						LD_TEMP, i,
+						PC87365_REG_TEMP);
+			}
+			if (data->temp_status[i] & 0x01) {
+				data->temp_min[i] = pc87360_read_value(data,
+						    LD_TEMP, i,
+						    PC87365_REG_TEMP_MIN);
+				data->temp_max[i] = pc87360_read_value(data,
+						    LD_TEMP, i,
+						    PC87365_REG_TEMP_MAX);
+				data->temp_crit[i] = pc87360_read_value(data,
+						     LD_TEMP, i,
+						     PC87365_REG_TEMP_CRIT);
+			}
+		}
+		if (data->tempnr) {
+			data->temp_alarms = pc87360_read_value(data, LD_TEMP,
+					    NO_BANK, PC87365_REG_TEMP_ALARMS)
+					    & 0x3F;
+		}
+
+		data->last_updated = jiffies;
+		data->valid = 1;
+	}
+
+	up(&data->update_lock);
+
+	return data;
+}
+
+static int __init pc87360_init(void)
+{
+	int i;
+
+	if (pc87360_find(0x2e, &devid, extra_isa)
+	 && pc87360_find(0x4e, &devid, extra_isa)) {
+		printk(KERN_WARNING "pc87360: PC8736x not detected, "
+		       "module not inserted.\n");
+		return -ENODEV;
+	}
+
+	/* Arbitrarily pick one of the addresses */
+	for (i = 0; i < 3; i++) {
+		if (extra_isa[i] != 0x0000) {
+			normal_isa[0] = extra_isa[i];
+			break;
+		}
+	}
+
+	if (normal_isa[0] == 0x0000) {
+		printk(KERN_WARNING "pc87360: No active logical device, "
+		       "module not inserted.\n");
+		return -ENODEV;
+	}
+
+	return i2c_add_driver(&pc87360_driver);
+}
+
+static void __exit pc87360_exit(void)
+{
+	i2c_del_driver(&pc87360_driver);
+}
+
+
+MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>");
+MODULE_DESCRIPTION("PC8736x hardware monitor");
+MODULE_LICENSE("GPL");
+
+module_init(pc87360_init);
+module_exit(pc87360_exit);
diff --git a/drivers/hwmon/sis5595.c b/drivers/hwmon/sis5595.c
new file mode 100644
--- /dev/null
+++ b/drivers/hwmon/sis5595.c
@@ -0,0 +1,817 @@
+/*
+    sis5595.c - Part of lm_sensors, Linux kernel modules
+		for hardware monitoring
+
+    Copyright (C) 1998 - 2001 Frodo Looijaard <frodol@dds.nl>,
+			Kyösti Mälkki <kmalkki@cc.hut.fi>, and
+			Mark D. Studebaker <mdsxyz123@yahoo.com>
+    Ported to Linux 2.6 by Aurelien Jarno <aurelien@aurel32.net> with
+    the help of Jean Delvare <khali@linux-fr.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.
+*/
+
+/*
+   SiS southbridge has a LM78-like chip integrated on the same IC.
+   This driver is a customized copy of lm78.c
+   
+   Supports following revisions:
+	Version		PCI ID		PCI Revision
+	1		1039/0008	AF or less
+	2		1039/0008	B0 or greater
+
+   Note: these chips contain a 0008 device which is incompatible with the
+	 5595. We recognize these by the presence of the listed
+	 "blacklist" PCI ID and refuse to load.
+
+   NOT SUPPORTED	PCI ID		BLACKLIST PCI ID	
+	 540		0008		0540
+	 550		0008		0550
+	5513		0008		5511
+	5581		0008		5597
+	5582		0008		5597
+	5597		0008		5597
+	5598		0008		5597/5598
+	 630		0008		0630
+	 645		0008		0645
+	 730		0008		0730
+	 735		0008		0735
+*/
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/ioport.h>
+#include <linux/pci.h>
+#include <linux/i2c.h>
+#include <linux/i2c-sensor.h>
+#include <linux/init.h>
+#include <linux/jiffies.h>
+#include <asm/io.h>
+
+
+/* If force_addr is set to anything different from 0, we forcibly enable
+   the device at the given address. */
+static u16 force_addr;
+module_param(force_addr, ushort, 0);
+MODULE_PARM_DESC(force_addr,
+		 "Initialize the base address of the sensors");
+
+/* Addresses to scan.
+   Note that we can't determine the ISA address until we have initialized
+   our module */
+static unsigned short normal_i2c[] = { I2C_CLIENT_END };
+static unsigned int normal_isa[] = { 0x0000, I2C_CLIENT_ISA_END };
+
+/* Insmod parameters */
+SENSORS_INSMOD_1(sis5595);
+
+/* Many SIS5595 constants specified below */
+
+/* Length of ISA address segment */
+#define SIS5595_EXTENT 8
+/* PCI Config Registers */
+#define SIS5595_REVISION_REG 0x08
+#define SIS5595_BASE_REG 0x68
+#define SIS5595_PIN_REG 0x7A
+#define SIS5595_ENABLE_REG 0x7B
+
+/* Where are the ISA address/data registers relative to the base address */
+#define SIS5595_ADDR_REG_OFFSET 5
+#define SIS5595_DATA_REG_OFFSET 6
+
+/* The SIS5595 registers */
+#define SIS5595_REG_IN_MAX(nr) (0x2b + (nr) * 2)
+#define SIS5595_REG_IN_MIN(nr) (0x2c + (nr) * 2)
+#define SIS5595_REG_IN(nr) (0x20 + (nr))
+
+#define SIS5595_REG_FAN_MIN(nr) (0x3b + (nr))
+#define SIS5595_REG_FAN(nr) (0x28 + (nr))
+
+/* On the first version of the chip, the temp registers are separate.
+   On the second version,
+   TEMP pin is shared with IN4, configured in PCI register 0x7A.
+   The registers are the same as well.
+   OVER and HYST are really MAX and MIN. */
+
+#define REV2MIN	0xb0
+#define SIS5595_REG_TEMP 	(( data->revision) >= REV2MIN) ? \
+					SIS5595_REG_IN(4) : 0x27
+#define SIS5595_REG_TEMP_OVER	(( data->revision) >= REV2MIN) ? \
+					SIS5595_REG_IN_MAX(4) : 0x39
+#define SIS5595_REG_TEMP_HYST	(( data->revision) >= REV2MIN) ? \
+					SIS5595_REG_IN_MIN(4) : 0x3a
+
+#define SIS5595_REG_CONFIG 0x40
+#define SIS5595_REG_ALARM1 0x41
+#define SIS5595_REG_ALARM2 0x42
+#define SIS5595_REG_FANDIV 0x47
+
+/* Conversions. Limit checking is only done on the TO_REG
+   variants. */
+
+/* IN: mV, (0V to 4.08V)
+   REG: 16mV/bit */
+static inline u8 IN_TO_REG(unsigned long val)
+{
+	unsigned long nval = SENSORS_LIMIT(val, 0, 4080);
+	return (nval + 8) / 16;
+}
+#define IN_FROM_REG(val) ((val) *  16)
+
+static inline u8 FAN_TO_REG(long rpm, int div)
+{
+	if (rpm <= 0)
+		return 255;
+	return SENSORS_LIMIT((1350000 + rpm * div / 2) / (rpm * div), 1, 254);
+}
+
+static inline int FAN_FROM_REG(u8 val, int div)
+{
+	return val==0 ? -1 : val==255 ? 0 : 1350000/(val*div);
+}
+
+/* TEMP: mC (-54.12C to +157.53C)
+   REG: 0.83C/bit + 52.12, two's complement  */
+static inline int TEMP_FROM_REG(s8 val)
+{
+	return val * 830 + 52120;
+}
+static inline s8 TEMP_TO_REG(int val)
+{
+	int nval = SENSORS_LIMIT(val, -54120, 157530) ;
+	return nval<0 ? (nval-5212-415)/830 : (nval-5212+415)/830;
+}
+
+/* FAN DIV: 1, 2, 4, or 8 (defaults to 2)
+   REG: 0, 1, 2, or 3 (respectively) (defaults to 1) */
+static inline u8 DIV_TO_REG(int val)
+{
+	return val==8 ? 3 : val==4 ? 2 : val==1 ? 0 : 1;
+}
+#define DIV_FROM_REG(val) (1 << (val))
+
+/* For the SIS5595, we need to keep some data in memory. That
+   data is pointed to by sis5595_list[NR]->data. The structure itself is
+   dynamically allocated, at the time when the new sis5595 client is
+   allocated. */
+struct sis5595_data {
+	struct i2c_client client;
+	struct semaphore lock;
+
+	struct semaphore update_lock;
+	char valid;		/* !=0 if following fields are valid */
+	unsigned long last_updated;	/* In jiffies */
+	char maxins;		/* == 3 if temp enabled, otherwise == 4 */
+	u8 revision;		/* Reg. value */
+
+	u8 in[5];		/* Register value */
+	u8 in_max[5];		/* Register value */
+	u8 in_min[5];		/* Register value */
+	u8 fan[2];		/* Register value */
+	u8 fan_min[2];		/* Register value */
+	s8 temp;		/* Register value */
+	s8 temp_over;		/* Register value */
+	s8 temp_hyst;		/* Register value */
+	u8 fan_div[2];		/* Register encoding, shifted right */
+	u16 alarms;		/* Register encoding, combined */
+};
+
+static struct pci_dev *s_bridge;	/* pointer to the (only) sis5595 */
+
+static int sis5595_attach_adapter(struct i2c_adapter *adapter);
+static int sis5595_detect(struct i2c_adapter *adapter, int address, int kind);
+static int sis5595_detach_client(struct i2c_client *client);
+
+static int sis5595_read_value(struct i2c_client *client, u8 register);
+static int sis5595_write_value(struct i2c_client *client, u8 register, u8 value);
+static struct sis5595_data *sis5595_update_device(struct device *dev);
+static void sis5595_init_client(struct i2c_client *client);
+
+static struct i2c_driver sis5595_driver = {
+	.owner		= THIS_MODULE,
+	.name		= "sis5595",
+	.id		= I2C_DRIVERID_SIS5595,
+	.flags		= I2C_DF_NOTIFY,
+	.attach_adapter	= sis5595_attach_adapter,
+	.detach_client	= sis5595_detach_client,
+};
+
+/* 4 Voltages */
+static ssize_t show_in(struct device *dev, char *buf, int nr)
+{
+	struct sis5595_data *data = sis5595_update_device(dev);
+	return sprintf(buf, "%d\n", IN_FROM_REG(data->in[nr]));
+}
+
+static ssize_t show_in_min(struct device *dev, char *buf, int nr)
+{
+	struct sis5595_data *data = sis5595_update_device(dev);
+	return sprintf(buf, "%d\n", IN_FROM_REG(data->in_min[nr]));
+}
+
+static ssize_t show_in_max(struct device *dev, char *buf, int nr)
+{
+	struct sis5595_data *data = sis5595_update_device(dev);
+	return sprintf(buf, "%d\n", IN_FROM_REG(data->in_max[nr]));
+}
+
+static ssize_t set_in_min(struct device *dev, const char *buf,
+	       size_t count, int nr)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct sis5595_data *data = i2c_get_clientdata(client);
+	unsigned long val = simple_strtoul(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->in_min[nr] = IN_TO_REG(val);
+	sis5595_write_value(client, SIS5595_REG_IN_MIN(nr), data->in_min[nr]);
+	up(&data->update_lock);
+	return count;
+}
+
+static ssize_t set_in_max(struct device *dev, const char *buf,
+	       size_t count, int nr)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct sis5595_data *data = i2c_get_clientdata(client);
+	unsigned long val = simple_strtoul(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->in_max[nr] = IN_TO_REG(val);
+	sis5595_write_value(client, SIS5595_REG_IN_MAX(nr), data->in_max[nr]);
+	up(&data->update_lock);
+	return count;
+}
+
+#define show_in_offset(offset)					\
+static ssize_t							\
+	show_in##offset (struct device *dev, struct device_attribute *attr, char *buf)		\
+{								\
+	return show_in(dev, buf, offset);			\
+}								\
+static DEVICE_ATTR(in##offset##_input, S_IRUGO, 		\
+		show_in##offset, NULL);				\
+static ssize_t							\
+	show_in##offset##_min (struct device *dev, struct device_attribute *attr, char *buf)	\
+{								\
+	return show_in_min(dev, buf, offset);			\
+}								\
+static ssize_t							\
+	show_in##offset##_max (struct device *dev, struct device_attribute *attr, char *buf)	\
+{								\
+	return show_in_max(dev, buf, offset);			\
+}								\
+static ssize_t set_in##offset##_min (struct device *dev, struct device_attribute *attr,	\
+		const char *buf, size_t count)			\
+{								\
+	return set_in_min(dev, buf, count, offset);		\
+}								\
+static ssize_t set_in##offset##_max (struct device *dev, struct device_attribute *attr,	\
+		const char *buf, size_t count)			\
+{								\
+	return set_in_max(dev, buf, count, offset);		\
+}								\
+static DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR,		\
+		show_in##offset##_min, set_in##offset##_min);	\
+static DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR,		\
+		show_in##offset##_max, set_in##offset##_max);
+
+show_in_offset(0);
+show_in_offset(1);
+show_in_offset(2);
+show_in_offset(3);
+show_in_offset(4);
+
+/* Temperature */
+static ssize_t show_temp(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct sis5595_data *data = sis5595_update_device(dev);
+	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp));
+}
+
+static ssize_t show_temp_over(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct sis5595_data *data = sis5595_update_device(dev);
+	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_over));
+}
+
+static ssize_t set_temp_over(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct sis5595_data *data = i2c_get_clientdata(client);
+	long val = simple_strtol(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->temp_over = TEMP_TO_REG(val);
+	sis5595_write_value(client, SIS5595_REG_TEMP_OVER, data->temp_over);
+	up(&data->update_lock);
+	return count;
+}
+
+static ssize_t show_temp_hyst(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct sis5595_data *data = sis5595_update_device(dev);
+	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_hyst));
+}
+
+static ssize_t set_temp_hyst(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct sis5595_data *data = i2c_get_clientdata(client);
+	long val = simple_strtol(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->temp_hyst = TEMP_TO_REG(val);
+	sis5595_write_value(client, SIS5595_REG_TEMP_HYST, data->temp_hyst);
+	up(&data->update_lock);
+	return count;
+}
+
+static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL);
+static DEVICE_ATTR(temp1_max, S_IRUGO | S_IWUSR,
+		show_temp_over, set_temp_over);
+static DEVICE_ATTR(temp1_max_hyst, S_IRUGO | S_IWUSR,
+		show_temp_hyst, set_temp_hyst);
+
+/* 2 Fans */
+static ssize_t show_fan(struct device *dev, char *buf, int nr)
+{
+	struct sis5595_data *data = sis5595_update_device(dev);
+	return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[nr],
+		DIV_FROM_REG(data->fan_div[nr])) );
+}
+
+static ssize_t show_fan_min(struct device *dev, char *buf, int nr)
+{
+	struct sis5595_data *data = sis5595_update_device(dev);
+	return sprintf(buf,"%d\n", FAN_FROM_REG(data->fan_min[nr],
+		DIV_FROM_REG(data->fan_div[nr])) );
+}
+
+static ssize_t set_fan_min(struct device *dev, const char *buf,
+		size_t count, int nr)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct sis5595_data *data = i2c_get_clientdata(client);
+	unsigned long val = simple_strtoul(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr]));
+	sis5595_write_value(client, SIS5595_REG_FAN_MIN(nr), data->fan_min[nr]);
+	up(&data->update_lock);
+	return count;
+}
+
+static ssize_t show_fan_div(struct device *dev, char *buf, int nr)
+{
+	struct sis5595_data *data = sis5595_update_device(dev);
+	return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[nr]) );
+}
+
+/* Note: we save and restore the fan minimum here, because its value is
+   determined in part by the fan divisor.  This follows the principle of
+   least suprise; the user doesn't expect the fan minimum to change just
+   because the divisor changed. */
+static ssize_t set_fan_div(struct device *dev, const char *buf,
+	size_t count, int nr)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct sis5595_data *data = i2c_get_clientdata(client);
+	unsigned long min;
+	unsigned long val = simple_strtoul(buf, NULL, 10);
+	int reg;
+
+	down(&data->update_lock);
+	min = FAN_FROM_REG(data->fan_min[nr],
+			DIV_FROM_REG(data->fan_div[nr]));
+	reg = sis5595_read_value(client, SIS5595_REG_FANDIV);
+
+	switch (val) {
+	case 1: data->fan_div[nr] = 0; break;
+	case 2: data->fan_div[nr] = 1; break;
+	case 4: data->fan_div[nr] = 2; break;
+	case 8: data->fan_div[nr] = 3; break;
+	default:
+		dev_err(&client->dev, "fan_div value %ld not "
+			"supported. Choose one of 1, 2, 4 or 8!\n", val);
+		up(&data->update_lock);
+		return -EINVAL;
+	}
+	
+	switch (nr) {
+	case 0:
+		reg = (reg & 0xcf) | (data->fan_div[nr] << 4);
+		break;
+	case 1:
+		reg = (reg & 0x3f) | (data->fan_div[nr] << 6);
+		break;
+	}
+	sis5595_write_value(client, SIS5595_REG_FANDIV, reg);
+	data->fan_min[nr] =
+		FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr]));
+	sis5595_write_value(client, SIS5595_REG_FAN_MIN(nr), data->fan_min[nr]);
+	up(&data->update_lock);
+	return count;
+}
+
+#define show_fan_offset(offset)						\
+static ssize_t show_fan_##offset (struct device *dev, struct device_attribute *attr, char *buf)	\
+{									\
+	return show_fan(dev, buf, offset - 1);			\
+}									\
+static ssize_t show_fan_##offset##_min (struct device *dev, struct device_attribute *attr, char *buf)	\
+{									\
+	return show_fan_min(dev, buf, offset - 1);			\
+}									\
+static ssize_t show_fan_##offset##_div (struct device *dev, struct device_attribute *attr, char *buf)	\
+{									\
+	return show_fan_div(dev, buf, offset - 1);			\
+}									\
+static ssize_t set_fan_##offset##_min (struct device *dev, struct device_attribute *attr,		\
+		const char *buf, size_t count)				\
+{									\
+	return set_fan_min(dev, buf, count, offset - 1);		\
+}									\
+static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_fan_##offset, NULL);\
+static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR,		\
+		show_fan_##offset##_min, set_fan_##offset##_min);
+
+show_fan_offset(1);
+show_fan_offset(2);
+
+static ssize_t set_fan_1_div(struct device *dev, struct device_attribute *attr, const char *buf,
+		size_t count)
+{
+	return set_fan_div(dev, buf, count, 0) ;
+}
+
+static ssize_t set_fan_2_div(struct device *dev, struct device_attribute *attr, const char *buf,
+		size_t count)
+{
+	return set_fan_div(dev, buf, count, 1) ;
+}
+static DEVICE_ATTR(fan1_div, S_IRUGO | S_IWUSR,
+		show_fan_1_div, set_fan_1_div);
+static DEVICE_ATTR(fan2_div, S_IRUGO | S_IWUSR,
+		show_fan_2_div, set_fan_2_div);
+
+/* Alarms */
+static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct sis5595_data *data = sis5595_update_device(dev);
+	return sprintf(buf, "%d\n", data->alarms);
+}
+static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
+ 
+/* This is called when the module is loaded */
+static int sis5595_attach_adapter(struct i2c_adapter *adapter)
+{
+	if (!(adapter->class & I2C_CLASS_HWMON))
+		return 0;
+	return i2c_detect(adapter, &addr_data, sis5595_detect);
+}
+
+int sis5595_detect(struct i2c_adapter *adapter, int address, int kind)
+{
+	int err = 0;
+	int i;
+	struct i2c_client *new_client;
+	struct sis5595_data *data;
+	char val;
+	u16 a;
+
+	/* Make sure we are probing the ISA bus!!  */
+	if (!i2c_is_isa_adapter(adapter))
+		goto exit;
+
+	if (force_addr)
+		address = force_addr & ~(SIS5595_EXTENT - 1);
+	/* Reserve the ISA region */
+	if (!request_region(address, SIS5595_EXTENT, sis5595_driver.name)) {
+		err = -EBUSY;
+		goto exit;
+	}
+	if (force_addr) {
+		dev_warn(&adapter->dev, "forcing ISA address 0x%04X\n", address);
+		if (PCIBIOS_SUCCESSFUL !=
+		    pci_write_config_word(s_bridge, SIS5595_BASE_REG, address))
+			goto exit_release;
+		if (PCIBIOS_SUCCESSFUL !=
+		    pci_read_config_word(s_bridge, SIS5595_BASE_REG, &a))
+			goto exit_release;
+		if ((a & ~(SIS5595_EXTENT - 1)) != address)
+			/* doesn't work for some chips? */
+			goto exit_release;
+	}
+
+	if (PCIBIOS_SUCCESSFUL !=
+	    pci_read_config_byte(s_bridge, SIS5595_ENABLE_REG, &val)) {
+		goto exit_release;
+	}
+	if ((val & 0x80) == 0) {
+		if (PCIBIOS_SUCCESSFUL !=
+		    pci_write_config_byte(s_bridge, SIS5595_ENABLE_REG,
+					  val | 0x80))
+			goto exit_release;
+		if (PCIBIOS_SUCCESSFUL !=
+		    pci_read_config_byte(s_bridge, SIS5595_ENABLE_REG, &val))
+			goto exit_release;
+		if ((val & 0x80) == 0) 
+			/* doesn't work for some chips! */
+			goto exit_release;
+	}
+
+	if (!(data = kmalloc(sizeof(struct sis5595_data), GFP_KERNEL))) {
+		err = -ENOMEM;
+		goto exit_release;
+	}
+	memset(data, 0, sizeof(struct sis5595_data));
+
+	new_client = &data->client;
+	new_client->addr = address;
+	init_MUTEX(&data->lock);
+	i2c_set_clientdata(new_client, data);
+	new_client->adapter = adapter;
+	new_client->driver = &sis5595_driver;
+	new_client->flags = 0;
+
+	/* Check revision and pin registers to determine whether 4 or 5 voltages */
+	pci_read_config_byte(s_bridge, SIS5595_REVISION_REG, &(data->revision));
+	/* 4 voltages, 1 temp */
+	data->maxins = 3;
+	if (data->revision >= REV2MIN) {
+		pci_read_config_byte(s_bridge, SIS5595_PIN_REG, &val);
+		if (!(val & 0x80))
+			/* 5 voltages, no temps */
+			data->maxins = 4;
+	}
+	
+	/* Fill in the remaining client fields and put it into the global list */
+	strlcpy(new_client->name, "sis5595", I2C_NAME_SIZE);
+
+	data->valid = 0;
+	init_MUTEX(&data->update_lock);
+
+	/* Tell the I2C layer a new client has arrived */
+	if ((err = i2c_attach_client(new_client)))
+		goto exit_free;
+	
+	/* Initialize the SIS5595 chip */
+	sis5595_init_client(new_client);
+
+	/* A few vars need to be filled upon startup */
+	for (i = 0; i < 2; i++) {
+		data->fan_min[i] = sis5595_read_value(new_client,
+					SIS5595_REG_FAN_MIN(i));
+	}
+
+	/* Register sysfs hooks */
+	device_create_file(&new_client->dev, &dev_attr_in0_input);
+	device_create_file(&new_client->dev, &dev_attr_in0_min);
+	device_create_file(&new_client->dev, &dev_attr_in0_max);
+	device_create_file(&new_client->dev, &dev_attr_in1_input);
+	device_create_file(&new_client->dev, &dev_attr_in1_min);
+	device_create_file(&new_client->dev, &dev_attr_in1_max);
+	device_create_file(&new_client->dev, &dev_attr_in2_input);
+	device_create_file(&new_client->dev, &dev_attr_in2_min);
+	device_create_file(&new_client->dev, &dev_attr_in2_max);
+	device_create_file(&new_client->dev, &dev_attr_in3_input);
+	device_create_file(&new_client->dev, &dev_attr_in3_min);
+	device_create_file(&new_client->dev, &dev_attr_in3_max);
+	if (data->maxins == 4) {
+		device_create_file(&new_client->dev, &dev_attr_in4_input);
+		device_create_file(&new_client->dev, &dev_attr_in4_min);
+		device_create_file(&new_client->dev, &dev_attr_in4_max);
+	}
+	device_create_file(&new_client->dev, &dev_attr_fan1_input);
+	device_create_file(&new_client->dev, &dev_attr_fan1_min);
+	device_create_file(&new_client->dev, &dev_attr_fan1_div);
+	device_create_file(&new_client->dev, &dev_attr_fan2_input);
+	device_create_file(&new_client->dev, &dev_attr_fan2_min);
+	device_create_file(&new_client->dev, &dev_attr_fan2_div);
+	device_create_file(&new_client->dev, &dev_attr_alarms);
+	if (data->maxins == 3) {
+		device_create_file(&new_client->dev, &dev_attr_temp1_input);
+		device_create_file(&new_client->dev, &dev_attr_temp1_max);
+		device_create_file(&new_client->dev, &dev_attr_temp1_max_hyst);
+	}
+	return 0;
+	
+exit_free:
+	kfree(data);
+exit_release:
+	release_region(address, SIS5595_EXTENT);
+exit:
+	return err;
+}
+
+static int sis5595_detach_client(struct i2c_client *client)
+{
+	int err;
+
+	if ((err = i2c_detach_client(client))) {
+		dev_err(&client->dev,
+		    "Client deregistration failed, client not detached.\n");
+		return err;
+	}
+
+	if (i2c_is_isa_client(client))
+		release_region(client->addr, SIS5595_EXTENT);
+
+	kfree(i2c_get_clientdata(client));
+
+	return 0;
+}
+
+
+/* ISA access must be locked explicitly. */
+static int sis5595_read_value(struct i2c_client *client, u8 reg)
+{
+	int res;
+
+	struct sis5595_data *data = i2c_get_clientdata(client);
+	down(&data->lock);
+	outb_p(reg, client->addr + SIS5595_ADDR_REG_OFFSET);
+	res = inb_p(client->addr + SIS5595_DATA_REG_OFFSET);
+	up(&data->lock);
+	return res;
+}
+
+static int sis5595_write_value(struct i2c_client *client, u8 reg, u8 value)
+{
+	struct sis5595_data *data = i2c_get_clientdata(client);
+	down(&data->lock);
+	outb_p(reg, client->addr + SIS5595_ADDR_REG_OFFSET);
+	outb_p(value, client->addr + SIS5595_DATA_REG_OFFSET);
+	up(&data->lock);
+	return 0;
+}
+
+/* Called when we have found a new SIS5595. */
+static void sis5595_init_client(struct i2c_client *client)
+{
+	u8 config = sis5595_read_value(client, SIS5595_REG_CONFIG);
+	if (!(config & 0x01))
+		sis5595_write_value(client, SIS5595_REG_CONFIG,
+				(config & 0xf7) | 0x01);
+}
+
+static struct sis5595_data *sis5595_update_device(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct sis5595_data *data = i2c_get_clientdata(client);
+	int i;
+
+	down(&data->update_lock);
+
+	if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
+	    || !data->valid) {
+
+		for (i = 0; i <= data->maxins; i++) {
+			data->in[i] =
+			    sis5595_read_value(client, SIS5595_REG_IN(i));
+			data->in_min[i] =
+			    sis5595_read_value(client,
+					       SIS5595_REG_IN_MIN(i));
+			data->in_max[i] =
+			    sis5595_read_value(client,
+					       SIS5595_REG_IN_MAX(i));
+		}
+		for (i = 0; i < 2; i++) {
+			data->fan[i] =
+			    sis5595_read_value(client, SIS5595_REG_FAN(i));
+			data->fan_min[i] =
+			    sis5595_read_value(client,
+					       SIS5595_REG_FAN_MIN(i));
+		}
+		if (data->maxins == 3) {
+			data->temp =
+			    sis5595_read_value(client, SIS5595_REG_TEMP);
+			data->temp_over =
+			    sis5595_read_value(client, SIS5595_REG_TEMP_OVER);
+			data->temp_hyst =
+			    sis5595_read_value(client, SIS5595_REG_TEMP_HYST);
+		}
+		i = sis5595_read_value(client, SIS5595_REG_FANDIV);
+		data->fan_div[0] = (i >> 4) & 0x03;
+		data->fan_div[1] = i >> 6;
+		data->alarms =
+		    sis5595_read_value(client, SIS5595_REG_ALARM1) |
+		    (sis5595_read_value(client, SIS5595_REG_ALARM2) << 8);
+		data->last_updated = jiffies;
+		data->valid = 1;
+	}
+
+	up(&data->update_lock);
+
+	return data;
+}
+
+static struct pci_device_id sis5595_pci_ids[] = {
+	{ PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) },
+	{ 0, }
+};
+
+MODULE_DEVICE_TABLE(pci, sis5595_pci_ids);
+
+static int blacklist[] __devinitdata = {
+	PCI_DEVICE_ID_SI_540,
+	PCI_DEVICE_ID_SI_550,
+	PCI_DEVICE_ID_SI_630,
+	PCI_DEVICE_ID_SI_645,
+	PCI_DEVICE_ID_SI_730,
+	PCI_DEVICE_ID_SI_735,
+	PCI_DEVICE_ID_SI_5511, /* 5513 chip has the 0008 device but
+				  that ID shows up in other chips so we
+				  use the 5511 ID for recognition */
+	PCI_DEVICE_ID_SI_5597,
+	PCI_DEVICE_ID_SI_5598,
+	0 };
+
+static int __devinit sis5595_pci_probe(struct pci_dev *dev,
+				       const struct pci_device_id *id)
+{
+	u16 val;
+	int *i;
+	int addr = 0;
+
+	for (i = blacklist; *i != 0; i++) {
+		struct pci_dev *dev;
+		dev = pci_get_device(PCI_VENDOR_ID_SI, *i, NULL);
+		if (dev) {
+			dev_err(&dev->dev, "Looked for SIS5595 but found unsupported device %.4x\n", *i);
+			pci_dev_put(dev);
+			return -ENODEV;
+		}
+	}
+	
+	if (PCIBIOS_SUCCESSFUL !=
+	    pci_read_config_word(dev, SIS5595_BASE_REG, &val))
+		return -ENODEV;
+	
+	addr = val & ~(SIS5595_EXTENT - 1);
+	if (addr == 0 && force_addr == 0) {
+		dev_err(&dev->dev, "Base address not set - upgrade BIOS or use force_addr=0xaddr\n");
+		return -ENODEV;
+	}
+	if (force_addr)
+		addr = force_addr;	/* so detect will get called */
+
+	if (!addr) {
+		dev_err(&dev->dev,"No SiS 5595 sensors found.\n");
+		return -ENODEV;
+	}
+	normal_isa[0] = addr;
+
+	s_bridge = pci_dev_get(dev);
+	if (i2c_add_driver(&sis5595_driver)) {
+		pci_dev_put(s_bridge);
+		s_bridge = NULL;
+	}
+
+	/* Always return failure here.  This is to allow other drivers to bind
+	 * to this pci device.  We don't really want to have control over the
+	 * pci device, we only wanted to read as few register values from it.
+	 */
+	return -ENODEV;
+}
+
+static struct pci_driver sis5595_pci_driver = {
+	.name            = "sis5595",
+	.id_table        = sis5595_pci_ids,
+	.probe           = sis5595_pci_probe,
+};
+
+static int __init sm_sis5595_init(void)
+{
+	return pci_register_driver(&sis5595_pci_driver);
+}
+
+static void __exit sm_sis5595_exit(void)
+{
+	pci_unregister_driver(&sis5595_pci_driver);
+	if (s_bridge != NULL) {
+		i2c_del_driver(&sis5595_driver);
+		pci_dev_put(s_bridge);
+		s_bridge = NULL;
+	}
+}
+
+MODULE_AUTHOR("Aurelien Jarno <aurelien@aurel32.net>");
+MODULE_DESCRIPTION("SiS 5595 Sensor device");
+MODULE_LICENSE("GPL");
+
+module_init(sm_sis5595_init);
+module_exit(sm_sis5595_exit);
diff --git a/drivers/hwmon/smsc47b397.c b/drivers/hwmon/smsc47b397.c
new file mode 100644
--- /dev/null
+++ b/drivers/hwmon/smsc47b397.c
@@ -0,0 +1,352 @@
+/*
+    smsc47b397.c - Part of lm_sensors, Linux kernel modules
+			for hardware monitoring
+
+    Supports the SMSC LPC47B397-NC Super-I/O chip.
+
+    Author/Maintainer: Mark M. Hoffman <mhoffman@lightlink.com>
+	Copyright (C) 2004 Utilitek Systems, Inc.
+
+    derived in part from smsc47m1.c:
+	Copyright (C) 2002 Mark D. Studebaker <mdsxyz123@yahoo.com>
+	Copyright (C) 2004 Jean Delvare <khali@linux-fr.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.
+*/
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/ioport.h>
+#include <linux/jiffies.h>
+#include <linux/i2c.h>
+#include <linux/i2c-sensor.h>
+#include <linux/init.h>
+#include <asm/io.h>
+
+static unsigned short normal_i2c[] = { I2C_CLIENT_END };
+/* Address is autodetected, there is no default value */
+static unsigned int normal_isa[] = { 0x0000, I2C_CLIENT_ISA_END };
+static struct i2c_force_data forces[] = {{NULL}};
+
+enum chips { any_chip, smsc47b397 };
+static struct i2c_address_data addr_data = {
+	.normal_i2c		= normal_i2c,
+	.normal_isa		= normal_isa,
+	.probe			= normal_i2c,		/* cheat */
+	.ignore			= normal_i2c,		/* cheat */
+	.forces			= forces,
+};
+
+/* Super-I/0 registers and commands */
+
+#define	REG	0x2e	/* The register to read/write */
+#define	VAL	0x2f	/* The value to read/write */
+
+static inline void superio_outb(int reg, int val)
+{
+	outb(reg, REG);
+	outb(val, VAL);
+}
+
+static inline int superio_inb(int reg)
+{
+	outb(reg, REG);
+	return inb(VAL);
+}
+
+/* select superio logical device */
+static inline void superio_select(int ld)
+{
+	superio_outb(0x07, ld);
+}
+
+static inline void superio_enter(void)
+{
+	outb(0x55, REG);
+}
+
+static inline void superio_exit(void)
+{
+	outb(0xAA, REG);
+}
+
+#define SUPERIO_REG_DEVID	0x20
+#define SUPERIO_REG_DEVREV	0x21
+#define SUPERIO_REG_BASE_MSB	0x60
+#define SUPERIO_REG_BASE_LSB	0x61
+#define SUPERIO_REG_LD8		0x08
+
+#define SMSC_EXTENT		0x02
+
+/* 0 <= nr <= 3 */
+static u8 smsc47b397_reg_temp[] = {0x25, 0x26, 0x27, 0x80};
+#define SMSC47B397_REG_TEMP(nr)	(smsc47b397_reg_temp[(nr)])
+
+/* 0 <= nr <= 3 */
+#define SMSC47B397_REG_FAN_LSB(nr) (0x28 + 2 * (nr))
+#define SMSC47B397_REG_FAN_MSB(nr) (0x29 + 2 * (nr))
+
+struct smsc47b397_data {
+	struct i2c_client client;
+	struct semaphore lock;
+
+	struct semaphore update_lock;
+	unsigned long last_updated; /* in jiffies */
+	int valid;
+
+	/* register values */
+	u16 fan[4];
+	u8 temp[4];
+};
+
+static int smsc47b397_read_value(struct i2c_client *client, u8 reg)
+{
+	struct smsc47b397_data *data = i2c_get_clientdata(client);
+	int res;
+
+	down(&data->lock);
+	outb(reg, client->addr);
+	res = inb_p(client->addr + 1);
+	up(&data->lock);
+	return res;
+}
+
+static struct smsc47b397_data *smsc47b397_update_device(struct device *dev)
+{
+ 	struct i2c_client *client = to_i2c_client(dev);
+	struct smsc47b397_data *data = i2c_get_clientdata(client);
+	int i;
+
+	down(&data->update_lock);
+
+	if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
+		dev_dbg(&client->dev, "starting device update...\n");
+
+		/* 4 temperature inputs, 4 fan inputs */
+		for (i = 0; i < 4; i++) {
+			data->temp[i] = smsc47b397_read_value(client,
+					SMSC47B397_REG_TEMP(i));
+
+			/* must read LSB first */
+			data->fan[i]  = smsc47b397_read_value(client,
+					SMSC47B397_REG_FAN_LSB(i));
+			data->fan[i] |= smsc47b397_read_value(client,
+					SMSC47B397_REG_FAN_MSB(i)) << 8;
+		}
+
+		data->last_updated = jiffies;
+		data->valid = 1;
+
+		dev_dbg(&client->dev, "... device update complete\n");
+	}
+
+	up(&data->update_lock);
+
+	return data;
+}
+
+/* TEMP: 0.001C/bit (-128C to +127C)
+   REG: 1C/bit, two's complement */
+static int temp_from_reg(u8 reg)
+{
+	return (s8)reg * 1000;
+}
+
+/* 0 <= nr <= 3 */
+static ssize_t show_temp(struct device *dev, char *buf, int nr)
+{
+	struct smsc47b397_data *data = smsc47b397_update_device(dev);
+	return sprintf(buf, "%d\n", temp_from_reg(data->temp[nr]));
+}
+
+#define sysfs_temp(num) \
+static ssize_t show_temp##num(struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+	return show_temp(dev, buf, num-1); \
+} \
+static DEVICE_ATTR(temp##num##_input, S_IRUGO, show_temp##num, NULL)
+
+sysfs_temp(1);
+sysfs_temp(2);
+sysfs_temp(3);
+sysfs_temp(4);
+
+#define device_create_file_temp(client, num) \
+	device_create_file(&client->dev, &dev_attr_temp##num##_input)
+
+/* FAN: 1 RPM/bit
+   REG: count of 90kHz pulses / revolution */
+static int fan_from_reg(u16 reg)
+{
+	return 90000 * 60 / reg;
+}
+
+/* 0 <= nr <= 3 */
+static ssize_t show_fan(struct device *dev, char *buf, int nr)
+{
+        struct smsc47b397_data *data = smsc47b397_update_device(dev);
+        return sprintf(buf, "%d\n", fan_from_reg(data->fan[nr]));
+}
+
+#define sysfs_fan(num) \
+static ssize_t show_fan##num(struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+	return show_fan(dev, buf, num-1); \
+} \
+static DEVICE_ATTR(fan##num##_input, S_IRUGO, show_fan##num, NULL)
+
+sysfs_fan(1);
+sysfs_fan(2);
+sysfs_fan(3);
+sysfs_fan(4);
+
+#define device_create_file_fan(client, num) \
+	device_create_file(&client->dev, &dev_attr_fan##num##_input)
+
+static int smsc47b397_detect(struct i2c_adapter *adapter, int addr, int kind);
+
+static int smsc47b397_attach_adapter(struct i2c_adapter *adapter)
+{
+	if (!(adapter->class & I2C_CLASS_HWMON))
+		return 0;
+	return i2c_detect(adapter, &addr_data, smsc47b397_detect);
+}
+
+static int smsc47b397_detach_client(struct i2c_client *client)
+{
+	int err;
+
+	if ((err = i2c_detach_client(client))) {
+		dev_err(&client->dev, "Client deregistration failed, "
+			"client not detached.\n");
+		return err;
+	}
+
+	release_region(client->addr, SMSC_EXTENT);
+	kfree(i2c_get_clientdata(client));
+
+	return 0;
+}
+
+static struct i2c_driver smsc47b397_driver = {
+	.owner		= THIS_MODULE,
+	.name		= "smsc47b397",
+	.id		= I2C_DRIVERID_SMSC47B397,
+	.flags		= I2C_DF_NOTIFY,
+	.attach_adapter	= smsc47b397_attach_adapter,
+	.detach_client	= smsc47b397_detach_client,
+};
+
+static int smsc47b397_detect(struct i2c_adapter *adapter, int addr, int kind)
+{
+	struct i2c_client *new_client;
+	struct smsc47b397_data *data;
+	int err = 0;
+
+	if (!i2c_is_isa_adapter(adapter)) {
+		return 0;
+	}
+
+	if (!request_region(addr, SMSC_EXTENT, smsc47b397_driver.name)) {
+		dev_err(&adapter->dev, "Region 0x%x already in use!\n", addr);
+		return -EBUSY;
+	}
+
+	if (!(data = kmalloc(sizeof(struct smsc47b397_data), GFP_KERNEL))) {
+		err = -ENOMEM;
+		goto error_release;
+	}
+	memset(data, 0x00, sizeof(struct smsc47b397_data));
+
+	new_client = &data->client;
+	i2c_set_clientdata(new_client, data);
+	new_client->addr = addr;
+	init_MUTEX(&data->lock);
+	new_client->adapter = adapter;
+	new_client->driver = &smsc47b397_driver;
+	new_client->flags = 0;
+
+	strlcpy(new_client->name, "smsc47b397", I2C_NAME_SIZE);
+
+	init_MUTEX(&data->update_lock);
+
+	if ((err = i2c_attach_client(new_client)))
+		goto error_free;
+
+	device_create_file_temp(new_client, 1);
+	device_create_file_temp(new_client, 2);
+	device_create_file_temp(new_client, 3);
+	device_create_file_temp(new_client, 4);
+
+	device_create_file_fan(new_client, 1);
+	device_create_file_fan(new_client, 2);
+	device_create_file_fan(new_client, 3);
+	device_create_file_fan(new_client, 4);
+
+	return 0;
+
+error_free:
+	kfree(data);
+error_release:
+	release_region(addr, SMSC_EXTENT);
+	return err;
+}
+
+static int __init smsc47b397_find(unsigned int *addr)
+{
+	u8 id, rev;
+
+	superio_enter();
+	id = superio_inb(SUPERIO_REG_DEVID);
+
+	if (id != 0x6f) {
+		superio_exit();
+		return -ENODEV;
+	}
+
+	rev = superio_inb(SUPERIO_REG_DEVREV);
+
+	superio_select(SUPERIO_REG_LD8);
+	*addr = (superio_inb(SUPERIO_REG_BASE_MSB) << 8)
+		 |  superio_inb(SUPERIO_REG_BASE_LSB);
+
+	printk(KERN_INFO "smsc47b397: found SMSC LPC47B397-NC "
+		"(base address 0x%04x, revision %u)\n", *addr, rev);
+
+	superio_exit();
+	return 0;
+}
+
+static int __init smsc47b397_init(void)
+{
+	int ret;
+
+	if ((ret = smsc47b397_find(normal_isa)))
+		return ret;
+
+	return i2c_add_driver(&smsc47b397_driver);
+}
+
+static void __exit smsc47b397_exit(void)
+{
+	i2c_del_driver(&smsc47b397_driver);
+}
+
+MODULE_AUTHOR("Mark M. Hoffman <mhoffman@lightlink.com>");
+MODULE_DESCRIPTION("SMSC LPC47B397 driver");
+MODULE_LICENSE("GPL");
+
+module_init(smsc47b397_init);
+module_exit(smsc47b397_exit);
diff --git a/drivers/hwmon/smsc47m1.c b/drivers/hwmon/smsc47m1.c
new file mode 100644
--- /dev/null
+++ b/drivers/hwmon/smsc47m1.c
@@ -0,0 +1,593 @@
+/*
+    smsc47m1.c - Part of lm_sensors, Linux kernel modules
+                 for hardware monitoring
+
+    Supports the SMSC LPC47B27x, LPC47M10x, LPC47M13x and LPC47M14x
+    Super-I/O chips.
+
+    Copyright (C) 2002 Mark D. Studebaker <mdsxyz123@yahoo.com>
+    Copyright (C) 2004 Jean Delvare <khali@linux-fr.org>
+    Ported to Linux 2.6 by Gabriele Gorla <gorlik@yahoo.com>
+                        and Jean Delvare
+
+    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 <linux/module.h>
+#include <linux/slab.h>
+#include <linux/ioport.h>
+#include <linux/jiffies.h>
+#include <linux/i2c.h>
+#include <linux/i2c-sensor.h>
+#include <linux/init.h>
+#include <asm/io.h>
+
+static unsigned short normal_i2c[] = { I2C_CLIENT_END };
+/* Address is autodetected, there is no default value */
+static unsigned int normal_isa[] = { 0x0000, I2C_CLIENT_ISA_END };
+static struct i2c_force_data forces[] = {{NULL}};
+
+enum chips { any_chip, smsc47m1 };
+static struct i2c_address_data addr_data = {
+	.normal_i2c		= normal_i2c,
+	.normal_isa		= normal_isa,
+	.forces			= forces,
+};
+
+/* Super-I/0 registers and commands */
+
+#define	REG	0x2e	/* The register to read/write */
+#define	VAL	0x2f	/* The value to read/write */
+
+static inline void
+superio_outb(int reg, int val)
+{
+	outb(reg, REG);
+	outb(val, VAL);
+}
+
+static inline int
+superio_inb(int reg)
+{
+	outb(reg, REG);
+	return inb(VAL);
+}
+
+/* logical device for fans is 0x0A */
+#define superio_select() superio_outb(0x07, 0x0A)
+
+static inline void
+superio_enter(void)
+{
+	outb(0x55, REG);
+}
+
+static inline void
+superio_exit(void)
+{
+	outb(0xAA, REG);
+}
+
+#define SUPERIO_REG_ACT		0x30
+#define SUPERIO_REG_BASE	0x60
+#define SUPERIO_REG_DEVID	0x20
+
+/* Logical device registers */
+
+#define SMSC_EXTENT		0x80
+
+/* nr is 0 or 1 in the macros below */
+#define SMSC47M1_REG_ALARM		0x04
+#define SMSC47M1_REG_TPIN(nr)		(0x34 - (nr))
+#define SMSC47M1_REG_PPIN(nr)		(0x36 - (nr))
+#define SMSC47M1_REG_PWM(nr)		(0x56 + (nr))
+#define SMSC47M1_REG_FANDIV		0x58
+#define SMSC47M1_REG_FAN(nr)		(0x59 + (nr))
+#define SMSC47M1_REG_FAN_PRELOAD(nr)	(0x5B + (nr))
+
+#define MIN_FROM_REG(reg,div)		((reg)>=192 ? 0 : \
+					 983040/((192-(reg))*(div)))
+#define FAN_FROM_REG(reg,div,preload)	((reg)<=(preload) || (reg)==255 ? 0 : \
+					 983040/(((reg)-(preload))*(div)))
+#define DIV_FROM_REG(reg)		(1 << (reg))
+#define PWM_FROM_REG(reg)		(((reg) & 0x7E) << 1)
+#define PWM_EN_FROM_REG(reg)		((~(reg)) & 0x01)
+#define PWM_TO_REG(reg)			(((reg) >> 1) & 0x7E)
+
+struct smsc47m1_data {
+	struct i2c_client client;
+	struct semaphore lock;
+
+	struct semaphore update_lock;
+	unsigned long last_updated;	/* In jiffies */
+
+	u8 fan[2];		/* Register value */
+	u8 fan_preload[2];	/* Register value */
+	u8 fan_div[2];		/* Register encoding, shifted right */
+	u8 alarms;		/* Register encoding */
+	u8 pwm[2];		/* Register value (bit 7 is enable) */
+};
+
+
+static int smsc47m1_attach_adapter(struct i2c_adapter *adapter);
+static int smsc47m1_find(int *address);
+static int smsc47m1_detect(struct i2c_adapter *adapter, int address, int kind);
+static int smsc47m1_detach_client(struct i2c_client *client);
+
+static int smsc47m1_read_value(struct i2c_client *client, u8 reg);
+static void smsc47m1_write_value(struct i2c_client *client, u8 reg, u8 value);
+
+static struct smsc47m1_data *smsc47m1_update_device(struct device *dev,
+		int init);
+
+
+static struct i2c_driver smsc47m1_driver = {
+	.owner		= THIS_MODULE,
+	.name		= "smsc47m1",
+	.id		= I2C_DRIVERID_SMSC47M1,
+	.flags		= I2C_DF_NOTIFY,
+	.attach_adapter	= smsc47m1_attach_adapter,
+	.detach_client	= smsc47m1_detach_client,
+};
+
+/* nr is 0 or 1 in the callback functions below */
+
+static ssize_t get_fan(struct device *dev, char *buf, int nr)
+{
+	struct smsc47m1_data *data = smsc47m1_update_device(dev, 0);
+	/* This chip (stupidly) stops monitoring fan speed if PWM is
+	   enabled and duty cycle is 0%. This is fine if the monitoring
+	   and control concern the same fan, but troublesome if they are
+	   not (which could as well happen). */
+	int rpm = (data->pwm[nr] & 0x7F) == 0x00 ? 0 :
+		  FAN_FROM_REG(data->fan[nr],
+			       DIV_FROM_REG(data->fan_div[nr]),
+			       data->fan_preload[nr]);
+	return sprintf(buf, "%d\n", rpm);
+}
+
+static ssize_t get_fan_min(struct device *dev, char *buf, int nr)
+{
+	struct smsc47m1_data *data = smsc47m1_update_device(dev, 0);
+	int rpm = MIN_FROM_REG(data->fan_preload[nr],
+			       DIV_FROM_REG(data->fan_div[nr]));
+	return sprintf(buf, "%d\n", rpm);
+}
+
+static ssize_t get_fan_div(struct device *dev, char *buf, int nr)
+{
+	struct smsc47m1_data *data = smsc47m1_update_device(dev, 0);
+	return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[nr]));
+}
+
+static ssize_t get_pwm(struct device *dev, char *buf, int nr)
+{
+	struct smsc47m1_data *data = smsc47m1_update_device(dev, 0);
+	return sprintf(buf, "%d\n", PWM_FROM_REG(data->pwm[nr]));
+}
+
+static ssize_t get_pwm_en(struct device *dev, char *buf, int nr)
+{
+	struct smsc47m1_data *data = smsc47m1_update_device(dev, 0);
+	return sprintf(buf, "%d\n", PWM_EN_FROM_REG(data->pwm[nr]));
+}
+
+static ssize_t get_alarms(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct smsc47m1_data *data = smsc47m1_update_device(dev, 0);
+	return sprintf(buf, "%d\n", data->alarms);
+}
+
+static ssize_t set_fan_min(struct device *dev, const char *buf,
+		size_t count, int nr)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct smsc47m1_data *data = i2c_get_clientdata(client);
+	long rpmdiv, val = simple_strtol(buf, NULL, 10);
+
+	down(&data->update_lock);
+	rpmdiv = val * DIV_FROM_REG(data->fan_div[nr]);
+
+	if (983040 > 192 * rpmdiv || 2 * rpmdiv > 983040) {
+		up(&data->update_lock);
+		return -EINVAL;
+	}
+
+	data->fan_preload[nr] = 192 - ((983040 + rpmdiv / 2) / rpmdiv);
+	smsc47m1_write_value(client, SMSC47M1_REG_FAN_PRELOAD(nr),
+			     data->fan_preload[nr]);
+	up(&data->update_lock);
+
+	return count;
+}
+
+/* Note: we save and restore the fan minimum here, because its value is
+   determined in part by the fan clock divider.  This follows the principle
+   of least suprise; the user doesn't expect the fan minimum to change just
+   because the divider changed. */
+static ssize_t set_fan_div(struct device *dev, const char *buf,
+		size_t count, int nr)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct smsc47m1_data *data = i2c_get_clientdata(client);
+
+	long new_div = simple_strtol(buf, NULL, 10), tmp;
+	u8 old_div = DIV_FROM_REG(data->fan_div[nr]);
+
+	if (new_div == old_div) /* No change */
+		return count;
+
+	down(&data->update_lock);
+	switch (new_div) {
+	case 1: data->fan_div[nr] = 0; break;
+	case 2: data->fan_div[nr] = 1; break;
+	case 4: data->fan_div[nr] = 2; break;
+	case 8: data->fan_div[nr] = 3; break;
+	default:
+		up(&data->update_lock);
+		return -EINVAL;
+	}
+
+	tmp = smsc47m1_read_value(client, SMSC47M1_REG_FANDIV) & 0x0F;
+	tmp |= (data->fan_div[0] << 4) | (data->fan_div[1] << 6);
+	smsc47m1_write_value(client, SMSC47M1_REG_FANDIV, tmp);
+
+	/* Preserve fan min */
+	tmp = 192 - (old_div * (192 - data->fan_preload[nr])
+		     + new_div / 2) / new_div;
+	data->fan_preload[nr] = SENSORS_LIMIT(tmp, 0, 191);
+	smsc47m1_write_value(client, SMSC47M1_REG_FAN_PRELOAD(nr),
+			     data->fan_preload[nr]);
+	up(&data->update_lock);
+
+	return count;
+}
+
+static ssize_t set_pwm(struct device *dev, const char *buf,
+		size_t count, int nr)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct smsc47m1_data *data = i2c_get_clientdata(client);
+
+	long val = simple_strtol(buf, NULL, 10);
+
+	if (val < 0 || val > 255)
+		return -EINVAL;
+
+	down(&data->update_lock);
+	data->pwm[nr] &= 0x81; /* Preserve additional bits */
+	data->pwm[nr] |= PWM_TO_REG(val);
+	smsc47m1_write_value(client, SMSC47M1_REG_PWM(nr),
+			     data->pwm[nr]);
+	up(&data->update_lock);
+
+	return count;
+}
+
+static ssize_t set_pwm_en(struct device *dev, const char *buf,
+		size_t count, int nr)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct smsc47m1_data *data = i2c_get_clientdata(client);
+
+	long val = simple_strtol(buf, NULL, 10);
+	
+	if (val != 0 && val != 1)
+		return -EINVAL;
+
+	down(&data->update_lock);
+	data->pwm[nr] &= 0xFE; /* preserve the other bits */
+	data->pwm[nr] |= !val;
+	smsc47m1_write_value(client, SMSC47M1_REG_PWM(nr),
+			     data->pwm[nr]);
+	up(&data->update_lock);
+
+	return count;
+}
+
+#define fan_present(offset)						\
+static ssize_t get_fan##offset (struct device *dev, struct device_attribute *attr, char *buf)		\
+{									\
+	return get_fan(dev, buf, offset - 1);				\
+}									\
+static ssize_t get_fan##offset##_min (struct device *dev, struct device_attribute *attr, char *buf)	\
+{									\
+	return get_fan_min(dev, buf, offset - 1);			\
+}									\
+static ssize_t set_fan##offset##_min (struct device *dev, struct device_attribute *attr,		\
+		const char *buf, size_t count)				\
+{									\
+	return set_fan_min(dev, buf, count, offset - 1);		\
+}									\
+static ssize_t get_fan##offset##_div (struct device *dev, struct device_attribute *attr, char *buf)	\
+{									\
+	return get_fan_div(dev, buf, offset - 1);			\
+}									\
+static ssize_t set_fan##offset##_div (struct device *dev, struct device_attribute *attr,		\
+		const char *buf, size_t count)				\
+{									\
+	return set_fan_div(dev, buf, count, offset - 1);		\
+}									\
+static ssize_t get_pwm##offset (struct device *dev, struct device_attribute *attr, char *buf)		\
+{									\
+	return get_pwm(dev, buf, offset - 1);				\
+}									\
+static ssize_t set_pwm##offset (struct device *dev, struct device_attribute *attr,			\
+		const char *buf, size_t count)				\
+{									\
+	return set_pwm(dev, buf, count, offset - 1);			\
+}									\
+static ssize_t get_pwm##offset##_en (struct device *dev, struct device_attribute *attr, char *buf)	\
+{									\
+	return get_pwm_en(dev, buf, offset - 1);			\
+}									\
+static ssize_t set_pwm##offset##_en (struct device *dev, struct device_attribute *attr,		\
+		const char *buf, size_t count)				\
+{									\
+	return set_pwm_en(dev, buf, count, offset - 1);			\
+}									\
+static DEVICE_ATTR(fan##offset##_input, S_IRUGO, get_fan##offset,	\
+		NULL);							\
+static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR,		\
+		get_fan##offset##_min, set_fan##offset##_min);		\
+static DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR,		\
+		get_fan##offset##_div, set_fan##offset##_div);		\
+static DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR,			\
+		get_pwm##offset, set_pwm##offset);			\
+static DEVICE_ATTR(pwm##offset##_enable, S_IRUGO | S_IWUSR,		\
+		get_pwm##offset##_en, set_pwm##offset##_en);
+
+fan_present(1);
+fan_present(2);
+
+static DEVICE_ATTR(alarms, S_IRUGO, get_alarms, NULL);
+
+static int smsc47m1_attach_adapter(struct i2c_adapter *adapter)
+{
+	if (!(adapter->class & I2C_CLASS_HWMON))
+		return 0;
+	return i2c_detect(adapter, &addr_data, smsc47m1_detect);
+}
+
+static int smsc47m1_find(int *address)
+{
+	u8 val;
+
+	superio_enter();
+	val = superio_inb(SUPERIO_REG_DEVID);
+
+	/*
+	 * SMSC LPC47M10x/LPC47M13x (device id 0x59), LPC47M14x (device id
+	 * 0x5F) and LPC47B27x (device id 0x51) have fan control.
+	 * The LPC47M15x and LPC47M192 chips "with hardware monitoring block"
+	 * can do much more besides (device id 0x60).
+	 */
+	if (val == 0x51)
+		printk(KERN_INFO "smsc47m1: Found SMSC LPC47B27x\n");
+	else if (val == 0x59)
+		printk(KERN_INFO "smsc47m1: Found SMSC LPC47M10x/LPC47M13x\n");
+	else if (val == 0x5F)
+		printk(KERN_INFO "smsc47m1: Found SMSC LPC47M14x\n");
+	else if (val == 0x60)
+		printk(KERN_INFO "smsc47m1: Found SMSC LPC47M15x/LPC47M192\n");
+	else {
+		superio_exit();
+		return -ENODEV;
+	}
+
+	superio_select();
+	*address = (superio_inb(SUPERIO_REG_BASE) << 8)
+		 |  superio_inb(SUPERIO_REG_BASE + 1);
+	val = superio_inb(SUPERIO_REG_ACT);
+	if (*address == 0 || (val & 0x01) == 0) {
+		printk(KERN_INFO "smsc47m1: Device is disabled, will not use\n");
+		superio_exit();
+		return -ENODEV;
+	}
+
+	superio_exit();
+	return 0;
+}
+
+static int smsc47m1_detect(struct i2c_adapter *adapter, int address, int kind)
+{
+	struct i2c_client *new_client;
+	struct smsc47m1_data *data;
+	int err = 0;
+	int fan1, fan2, pwm1, pwm2;
+
+	if (!i2c_is_isa_adapter(adapter)) {
+		return 0;
+	}
+
+	if (!request_region(address, SMSC_EXTENT, smsc47m1_driver.name)) {
+		dev_err(&adapter->dev, "Region 0x%x already in use!\n", address);
+		return -EBUSY;
+	}
+
+	if (!(data = kmalloc(sizeof(struct smsc47m1_data), GFP_KERNEL))) {
+		err = -ENOMEM;
+		goto error_release;
+	}
+	memset(data, 0x00, sizeof(struct smsc47m1_data));
+
+	new_client = &data->client;
+	i2c_set_clientdata(new_client, data);
+	new_client->addr = address;
+	init_MUTEX(&data->lock);
+	new_client->adapter = adapter;
+	new_client->driver = &smsc47m1_driver;
+	new_client->flags = 0;
+
+	strlcpy(new_client->name, "smsc47m1", I2C_NAME_SIZE);
+	init_MUTEX(&data->update_lock);
+
+	/* If no function is properly configured, there's no point in
+	   actually registering the chip. */
+	fan1 = (smsc47m1_read_value(new_client, SMSC47M1_REG_TPIN(0)) & 0x05)
+	       == 0x05;
+	fan2 = (smsc47m1_read_value(new_client, SMSC47M1_REG_TPIN(1)) & 0x05)
+	       == 0x05;
+	pwm1 = (smsc47m1_read_value(new_client, SMSC47M1_REG_PPIN(0)) & 0x05)
+	       == 0x04;
+	pwm2 = (smsc47m1_read_value(new_client, SMSC47M1_REG_PPIN(1)) & 0x05)
+	       == 0x04;
+	if (!(fan1 || fan2 || pwm1 || pwm2)) {
+		dev_warn(&new_client->dev, "Device is not configured, will not use\n");
+		err = -ENODEV;
+		goto error_free;
+	}
+
+	if ((err = i2c_attach_client(new_client)))
+		goto error_free;
+
+	/* Some values (fan min, clock dividers, pwm registers) may be
+	   needed before any update is triggered, so we better read them
+	   at least once here. We don't usually do it that way, but in
+	   this particular case, manually reading 5 registers out of 8
+	   doesn't make much sense and we're better using the existing
+	   function. */
+	smsc47m1_update_device(&new_client->dev, 1);
+
+	if (fan1) {
+		device_create_file(&new_client->dev, &dev_attr_fan1_input);
+		device_create_file(&new_client->dev, &dev_attr_fan1_min);
+		device_create_file(&new_client->dev, &dev_attr_fan1_div);
+	} else
+		dev_dbg(&new_client->dev, "Fan 1 not enabled by hardware, "
+			"skipping\n");
+
+	if (fan2) {
+		device_create_file(&new_client->dev, &dev_attr_fan2_input);
+		device_create_file(&new_client->dev, &dev_attr_fan2_min);
+		device_create_file(&new_client->dev, &dev_attr_fan2_div);
+	} else
+		dev_dbg(&new_client->dev, "Fan 2 not enabled by hardware, "
+			"skipping\n");
+
+	if (pwm1) {
+		device_create_file(&new_client->dev, &dev_attr_pwm1);
+		device_create_file(&new_client->dev, &dev_attr_pwm1_enable);
+	} else
+		dev_dbg(&new_client->dev, "PWM 1 not enabled by hardware, "
+			"skipping\n");
+	if (pwm2) {
+		device_create_file(&new_client->dev, &dev_attr_pwm2);
+		device_create_file(&new_client->dev, &dev_attr_pwm2_enable);
+	} else
+		dev_dbg(&new_client->dev, "PWM 2 not enabled by hardware, "
+			"skipping\n");
+
+	device_create_file(&new_client->dev, &dev_attr_alarms);
+
+	return 0;
+
+error_free:
+	kfree(data);
+error_release:
+	release_region(address, SMSC_EXTENT);
+	return err;
+}
+
+static int smsc47m1_detach_client(struct i2c_client *client)
+{
+	int err;
+
+	if ((err = i2c_detach_client(client))) {
+		dev_err(&client->dev, "Client deregistration failed, "
+			"client not detached.\n");
+		return err;
+	}
+
+	release_region(client->addr, SMSC_EXTENT);
+	kfree(i2c_get_clientdata(client));
+
+	return 0;
+}
+
+static int smsc47m1_read_value(struct i2c_client *client, u8 reg)
+{
+	int res;
+
+	down(&((struct smsc47m1_data *) i2c_get_clientdata(client))->lock);
+	res = inb_p(client->addr + reg);
+	up(&((struct smsc47m1_data *) i2c_get_clientdata(client))->lock);
+	return res;
+}
+
+static void smsc47m1_write_value(struct i2c_client *client, u8 reg, u8 value)
+{
+	down(&((struct smsc47m1_data *) i2c_get_clientdata(client))->lock);
+	outb_p(value, client->addr + reg);
+	up(&((struct smsc47m1_data *) i2c_get_clientdata(client))->lock);
+}
+
+static struct smsc47m1_data *smsc47m1_update_device(struct device *dev,
+		int init)
+{
+ 	struct i2c_client *client = to_i2c_client(dev);
+	struct smsc47m1_data *data = i2c_get_clientdata(client);
+
+	down(&data->update_lock);
+
+	if (time_after(jiffies, data->last_updated + HZ + HZ / 2) || init) {
+		int i;
+
+		for (i = 0; i < 2; i++) {
+			data->fan[i] = smsc47m1_read_value(client,
+				       SMSC47M1_REG_FAN(i));
+			data->fan_preload[i] = smsc47m1_read_value(client,
+					       SMSC47M1_REG_FAN_PRELOAD(i));
+			data->pwm[i] = smsc47m1_read_value(client,
+				       SMSC47M1_REG_PWM(i));
+		}
+
+		i = smsc47m1_read_value(client, SMSC47M1_REG_FANDIV);
+		data->fan_div[0] = (i >> 4) & 0x03;
+		data->fan_div[1] = i >> 6;
+
+		data->alarms = smsc47m1_read_value(client,
+			       SMSC47M1_REG_ALARM) >> 6;
+		/* Clear alarms if needed */
+		if (data->alarms)
+			smsc47m1_write_value(client, SMSC47M1_REG_ALARM, 0xC0);
+
+		data->last_updated = jiffies;
+	}
+
+	up(&data->update_lock);
+	return data;
+}
+
+static int __init sm_smsc47m1_init(void)
+{
+	if (smsc47m1_find(normal_isa)) {
+		return -ENODEV;
+	}
+
+	return i2c_add_driver(&smsc47m1_driver);
+}
+
+static void __exit sm_smsc47m1_exit(void)
+{
+	i2c_del_driver(&smsc47m1_driver);
+}
+
+MODULE_AUTHOR("Mark D. Studebaker <mdsxyz123@yahoo.com>");
+MODULE_DESCRIPTION("SMSC LPC47M1xx fan sensors driver");
+MODULE_LICENSE("GPL");
+
+module_init(sm_smsc47m1_init);
+module_exit(sm_smsc47m1_exit);
diff --git a/drivers/hwmon/via686a.c b/drivers/hwmon/via686a.c
new file mode 100644
--- /dev/null
+++ b/drivers/hwmon/via686a.c
@@ -0,0 +1,875 @@
+/*
+    via686a.c - Part of lm_sensors, Linux kernel modules
+		for hardware monitoring
+
+    Copyright (c) 1998 - 2002  Frodo Looijaard <frodol@dds.nl>,
+			Kyösti Mälkki <kmalkki@cc.hut.fi>,
+			Mark Studebaker <mdsxyz123@yahoo.com>,
+			and Bob Dougherty <bobd@stanford.edu>
+    (Some conversion-factor data were contributed by Jonathan Teh Soon Yew
+    <j.teh@iname.com> and Alex van Kaam <darkside@chello.nl>.)
+
+    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.
+*/
+
+/*
+    Supports the Via VT82C686A, VT82C686B south bridges.
+    Reports all as a 686A.
+    Warning - only supports a single device.
+*/
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/pci.h>
+#include <linux/jiffies.h>
+#include <linux/i2c.h>
+#include <linux/i2c-sensor.h>
+#include <linux/init.h>
+#include <asm/io.h>
+
+
+/* If force_addr is set to anything different from 0, we forcibly enable
+   the device at the given address. */
+static unsigned short force_addr = 0;
+module_param(force_addr, ushort, 0);
+MODULE_PARM_DESC(force_addr,
+		 "Initialize the base address of the sensors");
+
+/* Addresses to scan.
+   Note that we can't determine the ISA address until we have initialized
+   our module */
+static unsigned short normal_i2c[] = { I2C_CLIENT_END };
+static unsigned int normal_isa[] = { 0x0000, I2C_CLIENT_ISA_END };
+
+/* Insmod parameters */
+SENSORS_INSMOD_1(via686a);
+
+/*
+   The Via 686a southbridge has a LM78-like chip integrated on the same IC.
+   This driver is a customized copy of lm78.c
+*/
+
+/* Many VIA686A constants specified below */
+
+/* Length of ISA address segment */
+#define VIA686A_EXTENT		0x80
+#define VIA686A_BASE_REG	0x70
+#define VIA686A_ENABLE_REG	0x74
+
+/* The VIA686A registers */
+/* ins numbered 0-4 */
+#define VIA686A_REG_IN_MAX(nr)	(0x2b + ((nr) * 2))
+#define VIA686A_REG_IN_MIN(nr)	(0x2c + ((nr) * 2))
+#define VIA686A_REG_IN(nr)	(0x22 + (nr))
+
+/* fans numbered 1-2 */
+#define VIA686A_REG_FAN_MIN(nr)	(0x3a + (nr))
+#define VIA686A_REG_FAN(nr)	(0x28 + (nr))
+
+/* temps numbered 1-3 */
+static const u8 VIA686A_REG_TEMP[]	= { 0x20, 0x21, 0x1f };
+static const u8 VIA686A_REG_TEMP_OVER[]	= { 0x39, 0x3d, 0x1d };
+static const u8 VIA686A_REG_TEMP_HYST[]	= { 0x3a, 0x3e, 0x1e };
+/* bits 7-6 */
+#define VIA686A_REG_TEMP_LOW1	0x4b
+/* 2 = bits 5-4, 3 = bits 7-6 */
+#define VIA686A_REG_TEMP_LOW23	0x49
+
+#define VIA686A_REG_ALARM1	0x41
+#define VIA686A_REG_ALARM2	0x42
+#define VIA686A_REG_FANDIV	0x47
+#define VIA686A_REG_CONFIG	0x40
+/* The following register sets temp interrupt mode (bits 1-0 for temp1,
+ 3-2 for temp2, 5-4 for temp3).  Modes are:
+    00 interrupt stays as long as value is out-of-range
+    01 interrupt is cleared once register is read (default)
+    10 comparator mode- like 00, but ignores hysteresis
+    11 same as 00 */
+#define VIA686A_REG_TEMP_MODE		0x4b
+/* We'll just assume that you want to set all 3 simultaneously: */
+#define VIA686A_TEMP_MODE_MASK		0x3F
+#define VIA686A_TEMP_MODE_CONTINUOUS	0x00
+
+/* Conversions. Limit checking is only done on the TO_REG
+   variants.
+
+********* VOLTAGE CONVERSIONS (Bob Dougherty) ********
+ From HWMon.cpp (Copyright 1998-2000 Jonathan Teh Soon Yew):
+ voltagefactor[0]=1.25/2628; (2628/1.25=2102.4)   // Vccp
+ voltagefactor[1]=1.25/2628; (2628/1.25=2102.4)   // +2.5V
+ voltagefactor[2]=1.67/2628; (2628/1.67=1573.7)   // +3.3V
+ voltagefactor[3]=2.6/2628;  (2628/2.60=1010.8)   // +5V
+ voltagefactor[4]=6.3/2628;  (2628/6.30=417.14)   // +12V
+ in[i]=(data[i+2]*25.0+133)*voltagefactor[i];
+ That is:
+ volts = (25*regVal+133)*factor
+ regVal = (volts/factor-133)/25
+ (These conversions were contributed by Jonathan Teh Soon Yew
+ <j.teh@iname.com>) */
+static inline u8 IN_TO_REG(long val, int inNum)
+{
+	/* To avoid floating point, we multiply constants by 10 (100 for +12V).
+	   Rounding is done (120500 is actually 133000 - 12500).
+	   Remember that val is expressed in 0.001V/bit, which is why we divide
+	   by an additional 10000 (100000 for +12V): 1000 for val and 10 (100)
+	   for the constants. */
+	if (inNum <= 1)
+		return (u8)
+		    SENSORS_LIMIT((val * 21024 - 1205000) / 250000, 0, 255);
+	else if (inNum == 2)
+		return (u8)
+		    SENSORS_LIMIT((val * 15737 - 1205000) / 250000, 0, 255);
+	else if (inNum == 3)
+		return (u8)
+		    SENSORS_LIMIT((val * 10108 - 1205000) / 250000, 0, 255);
+	else
+		return (u8)
+		    SENSORS_LIMIT((val * 41714 - 12050000) / 2500000, 0, 255);
+}
+
+static inline long IN_FROM_REG(u8 val, int inNum)
+{
+	/* To avoid floating point, we multiply constants by 10 (100 for +12V).
+	   We also multiply them by 1000 because we want 0.001V/bit for the
+	   output value. Rounding is done. */
+	if (inNum <= 1)
+		return (long) ((250000 * val + 1330000 + 21024 / 2) / 21024);
+	else if (inNum == 2)
+		return (long) ((250000 * val + 1330000 + 15737 / 2) / 15737);
+	else if (inNum == 3)
+		return (long) ((250000 * val + 1330000 + 10108 / 2) / 10108);
+	else
+		return (long) ((2500000 * val + 13300000 + 41714 / 2) / 41714);
+}
+
+/********* FAN RPM CONVERSIONS ********/
+/* Higher register values = slower fans (the fan's strobe gates a counter).
+ But this chip saturates back at 0, not at 255 like all the other chips.
+ So, 0 means 0 RPM */
+static inline u8 FAN_TO_REG(long rpm, int div)
+{
+	if (rpm == 0)
+		return 0;
+	rpm = SENSORS_LIMIT(rpm, 1, 1000000);
+	return SENSORS_LIMIT((1350000 + rpm * div / 2) / (rpm * div), 1, 255);
+}
+
+#define FAN_FROM_REG(val,div) ((val)==0?0:(val)==255?0:1350000/((val)*(div)))
+
+/******** TEMP CONVERSIONS (Bob Dougherty) *********/
+/* linear fits from HWMon.cpp (Copyright 1998-2000 Jonathan Teh Soon Yew)
+      if(temp<169)
+	      return double(temp)*0.427-32.08;
+      else if(temp>=169 && temp<=202)
+	      return double(temp)*0.582-58.16;
+      else
+	      return double(temp)*0.924-127.33;
+
+ A fifth-order polynomial fits the unofficial data (provided by Alex van
+ Kaam <darkside@chello.nl>) a bit better.  It also give more reasonable
+ numbers on my machine (ie. they agree with what my BIOS tells me).
+ Here's the fifth-order fit to the 8-bit data:
+ temp = 1.625093e-10*val^5 - 1.001632e-07*val^4 + 2.457653e-05*val^3 -
+	2.967619e-03*val^2 + 2.175144e-01*val - 7.090067e+0.
+
+ (2000-10-25- RFD: thanks to Uwe Andersen <uandersen@mayah.com> for
+ finding my typos in this formula!)
+
+ Alas, none of the elegant function-fit solutions will work because we
+ aren't allowed to use floating point in the kernel and doing it with
+ integers doesn't provide enough precision.  So we'll do boring old
+ look-up table stuff.  The unofficial data (see below) have effectively
+ 7-bit resolution (they are rounded to the nearest degree).  I'm assuming
+ that the transfer function of the device is monotonic and smooth, so a
+ smooth function fit to the data will allow us to get better precision.
+ I used the 5th-order poly fit described above and solved for
+ VIA register values 0-255.  I *10 before rounding, so we get tenth-degree
+ precision.  (I could have done all 1024 values for our 10-bit readings,
+ but the function is very linear in the useful range (0-80 deg C), so
+ we'll just use linear interpolation for 10-bit readings.)  So, tempLUT
+ is the temp at via register values 0-255: */
+static const long tempLUT[] =
+{ -709, -688, -667, -646, -627, -607, -589, -570, -553, -536, -519,
+	-503, -487, -471, -456, -442, -428, -414, -400, -387, -375,
+	-362, -350, -339, -327, -316, -305, -295, -285, -275, -265,
+	-255, -246, -237, -229, -220, -212, -204, -196, -188, -180,
+	-173, -166, -159, -152, -145, -139, -132, -126, -120, -114,
+	-108, -102, -96, -91, -85, -80, -74, -69, -64, -59, -54, -49,
+	-44, -39, -34, -29, -25, -20, -15, -11, -6, -2, 3, 7, 12, 16,
+	20, 25, 29, 33, 37, 42, 46, 50, 54, 59, 63, 67, 71, 75, 79, 84,
+	88, 92, 96, 100, 104, 109, 113, 117, 121, 125, 130, 134, 138,
+	142, 146, 151, 155, 159, 163, 168, 172, 176, 181, 185, 189,
+	193, 198, 202, 206, 211, 215, 219, 224, 228, 232, 237, 241,
+	245, 250, 254, 259, 263, 267, 272, 276, 281, 285, 290, 294,
+	299, 303, 307, 312, 316, 321, 325, 330, 334, 339, 344, 348,
+	353, 357, 362, 366, 371, 376, 380, 385, 390, 395, 399, 404,
+	409, 414, 419, 423, 428, 433, 438, 443, 449, 454, 459, 464,
+	469, 475, 480, 486, 491, 497, 502, 508, 514, 520, 526, 532,
+	538, 544, 551, 557, 564, 571, 578, 584, 592, 599, 606, 614,
+	621, 629, 637, 645, 654, 662, 671, 680, 689, 698, 708, 718,
+	728, 738, 749, 759, 770, 782, 793, 805, 818, 830, 843, 856,
+	870, 883, 898, 912, 927, 943, 958, 975, 991, 1008, 1026, 1044,
+	1062, 1081, 1101, 1121, 1141, 1162, 1184, 1206, 1229, 1252,
+	1276, 1301, 1326, 1352, 1378, 1406, 1434, 1462
+};
+
+/* the original LUT values from Alex van Kaam <darkside@chello.nl>
+   (for via register values 12-240):
+{-50,-49,-47,-45,-43,-41,-39,-38,-37,-35,-34,-33,-32,-31,
+-30,-29,-28,-27,-26,-25,-24,-24,-23,-22,-21,-20,-20,-19,-18,-17,-17,-16,-15,
+-15,-14,-14,-13,-12,-12,-11,-11,-10,-9,-9,-8,-8,-7,-7,-6,-6,-5,-5,-4,-4,-3,
+-3,-2,-2,-1,-1,0,0,1,1,1,3,3,3,4,4,4,5,5,5,6,6,7,7,8,8,9,9,9,10,10,11,11,12,
+12,12,13,13,13,14,14,15,15,16,16,16,17,17,18,18,19,19,20,20,21,21,21,22,22,
+22,23,23,24,24,25,25,26,26,26,27,27,27,28,28,29,29,30,30,30,31,31,32,32,33,
+33,34,34,35,35,35,36,36,37,37,38,38,39,39,40,40,41,41,42,42,43,43,44,44,45,
+45,46,46,47,48,48,49,49,50,51,51,52,52,53,53,54,55,55,56,57,57,58,59,59,60,
+61,62,62,63,64,65,66,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,83,84,
+85,86,88,89,91,92,94,96,97,99,101,103,105,107,109,110};
+
+
+ Here's the reverse LUT.  I got it by doing a 6-th order poly fit (needed
+ an extra term for a good fit to these inverse data!) and then
+ solving for each temp value from -50 to 110 (the useable range for
+ this chip).  Here's the fit:
+ viaRegVal = -1.160370e-10*val^6 +3.193693e-08*val^5 - 1.464447e-06*val^4
+ - 2.525453e-04*val^3 + 1.424593e-02*val^2 + 2.148941e+00*val +7.275808e+01)
+ Note that n=161: */
+static const u8 viaLUT[] =
+{ 12, 12, 13, 14, 14, 15, 16, 16, 17, 18, 18, 19, 20, 20, 21, 22, 23,
+	23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 35, 36, 37, 39, 40,
+	41, 43, 45, 46, 48, 49, 51, 53, 55, 57, 59, 60, 62, 64, 66,
+	69, 71, 73, 75, 77, 79, 82, 84, 86, 88, 91, 93, 95, 98, 100,
+	103, 105, 107, 110, 112, 115, 117, 119, 122, 124, 126, 129,
+	131, 134, 136, 138, 140, 143, 145, 147, 150, 152, 154, 156,
+	158, 160, 162, 164, 166, 168, 170, 172, 174, 176, 178, 180,
+	182, 183, 185, 187, 188, 190, 192, 193, 195, 196, 198, 199,
+	200, 202, 203, 205, 206, 207, 208, 209, 210, 211, 212, 213,
+	214, 215, 216, 217, 218, 219, 220, 221, 222, 222, 223, 224,
+	225, 226, 226, 227, 228, 228, 229, 230, 230, 231, 232, 232,
+	233, 233, 234, 235, 235, 236, 236, 237, 237, 238, 238, 239,
+	239, 240
+};
+
+/* Converting temps to (8-bit) hyst and over registers
+   No interpolation here.
+   The +50 is because the temps start at -50 */
+static inline u8 TEMP_TO_REG(long val)
+{
+	return viaLUT[val <= -50000 ? 0 : val >= 110000 ? 160 :
+		      (val < 0 ? val - 500 : val + 500) / 1000 + 50];
+}
+
+/* for 8-bit temperature hyst and over registers */
+#define TEMP_FROM_REG(val) (tempLUT[(val)] * 100)
+
+/* for 10-bit temperature readings */
+static inline long TEMP_FROM_REG10(u16 val)
+{
+	u16 eightBits = val >> 2;
+	u16 twoBits = val & 3;
+
+	/* no interpolation for these */
+	if (twoBits == 0 || eightBits == 255)
+		return TEMP_FROM_REG(eightBits);
+
+	/* do some linear interpolation */
+	return (tempLUT[eightBits] * (4 - twoBits) +
+		tempLUT[eightBits + 1] * twoBits) * 25;
+}
+
+#define DIV_FROM_REG(val) (1 << (val))
+#define DIV_TO_REG(val) ((val)==8?3:(val)==4?2:(val)==1?0:1)
+
+/* For the VIA686A, we need to keep some data in memory.
+   The structure is dynamically allocated, at the same time when a new
+   via686a client is allocated. */
+struct via686a_data {
+	struct i2c_client client;
+	struct semaphore update_lock;
+	char valid;		/* !=0 if following fields are valid */
+	unsigned long last_updated;	/* In jiffies */
+
+	u8 in[5];		/* Register value */
+	u8 in_max[5];		/* Register value */
+	u8 in_min[5];		/* Register value */
+	u8 fan[2];		/* Register value */
+	u8 fan_min[2];		/* Register value */
+	u16 temp[3];		/* Register value 10 bit */
+	u8 temp_over[3];	/* Register value */
+	u8 temp_hyst[3];	/* Register value */
+	u8 fan_div[2];		/* Register encoding, shifted right */
+	u16 alarms;		/* Register encoding, combined */
+};
+
+static struct pci_dev *s_bridge;	/* pointer to the (only) via686a */
+
+static int via686a_attach_adapter(struct i2c_adapter *adapter);
+static int via686a_detect(struct i2c_adapter *adapter, int address, int kind);
+static int via686a_detach_client(struct i2c_client *client);
+
+static inline int via686a_read_value(struct i2c_client *client, u8 reg)
+{
+	return (inb_p(client->addr + reg));
+}
+
+static inline void via686a_write_value(struct i2c_client *client, u8 reg,
+				       u8 value)
+{
+	outb_p(value, client->addr + reg);
+}
+
+static struct via686a_data *via686a_update_device(struct device *dev);
+static void via686a_init_client(struct i2c_client *client);
+
+/* following are the sysfs callback functions */
+
+/* 7 voltage sensors */
+static ssize_t show_in(struct device *dev, char *buf, int nr) {
+	struct via686a_data *data = via686a_update_device(dev);
+	return sprintf(buf, "%ld\n", IN_FROM_REG(data->in[nr], nr));
+}
+
+static ssize_t show_in_min(struct device *dev, char *buf, int nr) {
+	struct via686a_data *data = via686a_update_device(dev);
+	return sprintf(buf, "%ld\n", IN_FROM_REG(data->in_min[nr], nr));
+}
+
+static ssize_t show_in_max(struct device *dev, char *buf, int nr) {
+	struct via686a_data *data = via686a_update_device(dev);
+	return sprintf(buf, "%ld\n", IN_FROM_REG(data->in_max[nr], nr));
+}
+
+static ssize_t set_in_min(struct device *dev, const char *buf,
+		size_t count, int nr) {
+	struct i2c_client *client = to_i2c_client(dev);
+	struct via686a_data *data = i2c_get_clientdata(client);
+	unsigned long val = simple_strtoul(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->in_min[nr] = IN_TO_REG(val, nr);
+	via686a_write_value(client, VIA686A_REG_IN_MIN(nr),
+			data->in_min[nr]);
+	up(&data->update_lock);
+	return count;
+}
+static ssize_t set_in_max(struct device *dev, const char *buf,
+		size_t count, int nr) {
+	struct i2c_client *client = to_i2c_client(dev);
+	struct via686a_data *data = i2c_get_clientdata(client);
+	unsigned long val = simple_strtoul(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->in_max[nr] = IN_TO_REG(val, nr);
+	via686a_write_value(client, VIA686A_REG_IN_MAX(nr),
+			data->in_max[nr]);
+	up(&data->update_lock);
+	return count;
+}
+#define show_in_offset(offset)					\
+static ssize_t 							\
+	show_in##offset (struct device *dev, struct device_attribute *attr, char *buf)		\
+{								\
+	return show_in(dev, buf, offset);			\
+}								\
+static ssize_t 							\
+	show_in##offset##_min (struct device *dev, struct device_attribute *attr, char *buf)	\
+{								\
+	return show_in_min(dev, buf, offset);		\
+}								\
+static ssize_t 							\
+	show_in##offset##_max (struct device *dev, struct device_attribute *attr, char *buf)	\
+{								\
+	return show_in_max(dev, buf, offset);		\
+}								\
+static ssize_t set_in##offset##_min (struct device *dev, struct device_attribute *attr, 	\
+		const char *buf, size_t count) 			\
+{								\
+	return set_in_min(dev, buf, count, offset);		\
+}								\
+static ssize_t set_in##offset##_max (struct device *dev, struct device_attribute *attr,	\
+			const char *buf, size_t count)		\
+{								\
+	return set_in_max(dev, buf, count, offset);		\
+}								\
+static DEVICE_ATTR(in##offset##_input, S_IRUGO, show_in##offset, NULL);\
+static DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, 	\
+		show_in##offset##_min, set_in##offset##_min);	\
+static DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, 	\
+		show_in##offset##_max, set_in##offset##_max);
+
+show_in_offset(0);
+show_in_offset(1);
+show_in_offset(2);
+show_in_offset(3);
+show_in_offset(4);
+
+/* 3 temperatures */
+static ssize_t show_temp(struct device *dev, char *buf, int nr) {
+	struct via686a_data *data = via686a_update_device(dev);
+	return sprintf(buf, "%ld\n", TEMP_FROM_REG10(data->temp[nr]));
+}
+static ssize_t show_temp_over(struct device *dev, char *buf, int nr) {
+	struct via686a_data *data = via686a_update_device(dev);
+	return sprintf(buf, "%ld\n", TEMP_FROM_REG(data->temp_over[nr]));
+}
+static ssize_t show_temp_hyst(struct device *dev, char *buf, int nr) {
+	struct via686a_data *data = via686a_update_device(dev);
+	return sprintf(buf, "%ld\n", TEMP_FROM_REG(data->temp_hyst[nr]));
+}
+static ssize_t set_temp_over(struct device *dev, const char *buf,
+		size_t count, int nr) {
+	struct i2c_client *client = to_i2c_client(dev);
+	struct via686a_data *data = i2c_get_clientdata(client);
+	int val = simple_strtol(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->temp_over[nr] = TEMP_TO_REG(val);
+	via686a_write_value(client, VIA686A_REG_TEMP_OVER[nr],
+			    data->temp_over[nr]);
+	up(&data->update_lock);
+	return count;
+}
+static ssize_t set_temp_hyst(struct device *dev, const char *buf,
+		size_t count, int nr) {
+	struct i2c_client *client = to_i2c_client(dev);
+	struct via686a_data *data = i2c_get_clientdata(client);
+	int val = simple_strtol(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->temp_hyst[nr] = TEMP_TO_REG(val);
+	via686a_write_value(client, VIA686A_REG_TEMP_HYST[nr],
+			    data->temp_hyst[nr]);
+	up(&data->update_lock);
+	return count;
+}
+#define show_temp_offset(offset)					\
+static ssize_t show_temp_##offset (struct device *dev, struct device_attribute *attr, char *buf)	\
+{									\
+	return show_temp(dev, buf, offset - 1);				\
+}									\
+static ssize_t								\
+show_temp_##offset##_over (struct device *dev, struct device_attribute *attr, char *buf)		\
+{									\
+	return show_temp_over(dev, buf, offset - 1);			\
+}									\
+static ssize_t								\
+show_temp_##offset##_hyst (struct device *dev, struct device_attribute *attr, char *buf)		\
+{									\
+	return show_temp_hyst(dev, buf, offset - 1);			\
+}									\
+static ssize_t set_temp_##offset##_over (struct device *dev, struct device_attribute *attr, 		\
+		const char *buf, size_t count) 				\
+{									\
+	return set_temp_over(dev, buf, count, offset - 1);		\
+}									\
+static ssize_t set_temp_##offset##_hyst (struct device *dev, struct device_attribute *attr, 		\
+		const char *buf, size_t count) 				\
+{									\
+	return set_temp_hyst(dev, buf, count, offset - 1);		\
+}									\
+static DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_temp_##offset, NULL);\
+static DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR, 		\
+		show_temp_##offset##_over, set_temp_##offset##_over);	\
+static DEVICE_ATTR(temp##offset##_max_hyst, S_IRUGO | S_IWUSR, 		\
+		show_temp_##offset##_hyst, set_temp_##offset##_hyst);
+
+show_temp_offset(1);
+show_temp_offset(2);
+show_temp_offset(3);
+
+/* 2 Fans */
+static ssize_t show_fan(struct device *dev, char *buf, int nr) {
+	struct via686a_data *data = via686a_update_device(dev);
+	return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[nr],
+				DIV_FROM_REG(data->fan_div[nr])) );
+}
+static ssize_t show_fan_min(struct device *dev, char *buf, int nr) {
+	struct via686a_data *data = via686a_update_device(dev);
+	return sprintf(buf, "%d\n",
+		FAN_FROM_REG(data->fan_min[nr], DIV_FROM_REG(data->fan_div[nr])) );
+}
+static ssize_t show_fan_div(struct device *dev, char *buf, int nr) {
+	struct via686a_data *data = via686a_update_device(dev);
+	return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[nr]) );
+}
+static ssize_t set_fan_min(struct device *dev, const char *buf,
+		size_t count, int nr) {
+	struct i2c_client *client = to_i2c_client(dev);
+	struct via686a_data *data = i2c_get_clientdata(client);
+	int val = simple_strtol(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr]));
+	via686a_write_value(client, VIA686A_REG_FAN_MIN(nr+1), data->fan_min[nr]);
+	up(&data->update_lock);
+	return count;
+}
+static ssize_t set_fan_div(struct device *dev, const char *buf,
+		size_t count, int nr) {
+	struct i2c_client *client = to_i2c_client(dev);
+	struct via686a_data *data = i2c_get_clientdata(client);
+	int val = simple_strtol(buf, NULL, 10);
+	int old;
+
+	down(&data->update_lock);
+	old = via686a_read_value(client, VIA686A_REG_FANDIV);
+	data->fan_div[nr] = DIV_TO_REG(val);
+	old = (old & 0x0f) | (data->fan_div[1] << 6) | (data->fan_div[0] << 4);
+	via686a_write_value(client, VIA686A_REG_FANDIV, old);
+	up(&data->update_lock);
+	return count;
+}
+
+#define show_fan_offset(offset)						\
+static ssize_t show_fan_##offset (struct device *dev, struct device_attribute *attr, char *buf)	\
+{									\
+	return show_fan(dev, buf, offset - 1);				\
+}									\
+static ssize_t show_fan_##offset##_min (struct device *dev, struct device_attribute *attr, char *buf)	\
+{									\
+	return show_fan_min(dev, buf, offset - 1);			\
+}									\
+static ssize_t show_fan_##offset##_div (struct device *dev, struct device_attribute *attr, char *buf)	\
+{									\
+	return show_fan_div(dev, buf, offset - 1);			\
+}									\
+static ssize_t set_fan_##offset##_min (struct device *dev, struct device_attribute *attr, 		\
+	const char *buf, size_t count) 					\
+{									\
+	return set_fan_min(dev, buf, count, offset - 1);		\
+}									\
+static ssize_t set_fan_##offset##_div (struct device *dev, struct device_attribute *attr, 		\
+		const char *buf, size_t count) 				\
+{									\
+	return set_fan_div(dev, buf, count, offset - 1);		\
+}									\
+static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_fan_##offset, NULL);\
+static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, 		\
+		show_fan_##offset##_min, set_fan_##offset##_min);	\
+static DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, 		\
+		show_fan_##offset##_div, set_fan_##offset##_div);
+
+show_fan_offset(1);
+show_fan_offset(2);
+
+/* Alarms */
+static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf) {
+	struct via686a_data *data = via686a_update_device(dev);
+	return sprintf(buf, "%u\n", data->alarms);
+}
+static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
+
+/* The driver. I choose to use type i2c_driver, as at is identical to both
+   smbus_driver and isa_driver, and clients could be of either kind */
+static struct i2c_driver via686a_driver = {
+	.owner		= THIS_MODULE,
+	.name		= "via686a",
+	.id		= I2C_DRIVERID_VIA686A,
+	.flags		= I2C_DF_NOTIFY,
+	.attach_adapter	= via686a_attach_adapter,
+	.detach_client	= via686a_detach_client,
+};
+
+
+/* This is called when the module is loaded */
+static int via686a_attach_adapter(struct i2c_adapter *adapter)
+{
+	if (!(adapter->class & I2C_CLASS_HWMON))
+		return 0;
+	return i2c_detect(adapter, &addr_data, via686a_detect);
+}
+
+static int via686a_detect(struct i2c_adapter *adapter, int address, int kind)
+{
+	struct i2c_client *new_client;
+	struct via686a_data *data;
+	int err = 0;
+	const char client_name[] = "via686a";
+	u16 val;
+
+	/* Make sure we are probing the ISA bus!!  */
+	if (!i2c_is_isa_adapter(adapter)) {
+		dev_err(&adapter->dev,
+		"via686a_detect called for an I2C bus adapter?!?\n");
+		return 0;
+	}
+
+	/* 8231 requires multiple of 256, we enforce that on 686 as well */
+	if (force_addr)
+		address = force_addr & 0xFF00;
+
+	if (force_addr) {
+		dev_warn(&adapter->dev, "forcing ISA address 0x%04X\n",
+			 address);
+		if (PCIBIOS_SUCCESSFUL !=
+		    pci_write_config_word(s_bridge, VIA686A_BASE_REG, address))
+			return -ENODEV;
+	}
+	if (PCIBIOS_SUCCESSFUL !=
+	    pci_read_config_word(s_bridge, VIA686A_ENABLE_REG, &val))
+		return -ENODEV;
+	if (!(val & 0x0001)) {
+		dev_warn(&adapter->dev, "enabling sensors\n");
+		if (PCIBIOS_SUCCESSFUL !=
+		    pci_write_config_word(s_bridge, VIA686A_ENABLE_REG,
+					  val | 0x0001))
+			return -ENODEV;
+	}
+
+	/* Reserve the ISA region */
+	if (!request_region(address, VIA686A_EXTENT, via686a_driver.name)) {
+		dev_err(&adapter->dev, "region 0x%x already in use!\n",
+			address);
+		return -ENODEV;
+	}
+
+	if (!(data = kmalloc(sizeof(struct via686a_data), GFP_KERNEL))) {
+		err = -ENOMEM;
+		goto ERROR0;
+	}
+	memset(data, 0, sizeof(struct via686a_data));
+
+	new_client = &data->client;
+	i2c_set_clientdata(new_client, data);
+	new_client->addr = address;
+	new_client->adapter = adapter;
+	new_client->driver = &via686a_driver;
+	new_client->flags = 0;
+
+	/* Fill in the remaining client fields and put into the global list */
+	strlcpy(new_client->name, client_name, I2C_NAME_SIZE);
+
+	data->valid = 0;
+	init_MUTEX(&data->update_lock);
+	/* Tell the I2C layer a new client has arrived */
+	if ((err = i2c_attach_client(new_client)))
+		goto ERROR3;
+
+	/* Initialize the VIA686A chip */
+	via686a_init_client(new_client);
+
+	/* Register sysfs hooks */
+	device_create_file(&new_client->dev, &dev_attr_in0_input);
+	device_create_file(&new_client->dev, &dev_attr_in1_input);
+	device_create_file(&new_client->dev, &dev_attr_in2_input);
+	device_create_file(&new_client->dev, &dev_attr_in3_input);
+	device_create_file(&new_client->dev, &dev_attr_in4_input);
+	device_create_file(&new_client->dev, &dev_attr_in0_min);
+	device_create_file(&new_client->dev, &dev_attr_in1_min);
+	device_create_file(&new_client->dev, &dev_attr_in2_min);
+	device_create_file(&new_client->dev, &dev_attr_in3_min);
+	device_create_file(&new_client->dev, &dev_attr_in4_min);
+	device_create_file(&new_client->dev, &dev_attr_in0_max);
+	device_create_file(&new_client->dev, &dev_attr_in1_max);
+	device_create_file(&new_client->dev, &dev_attr_in2_max);
+	device_create_file(&new_client->dev, &dev_attr_in3_max);
+	device_create_file(&new_client->dev, &dev_attr_in4_max);
+	device_create_file(&new_client->dev, &dev_attr_temp1_input);
+	device_create_file(&new_client->dev, &dev_attr_temp2_input);
+	device_create_file(&new_client->dev, &dev_attr_temp3_input);
+	device_create_file(&new_client->dev, &dev_attr_temp1_max);
+	device_create_file(&new_client->dev, &dev_attr_temp2_max);
+	device_create_file(&new_client->dev, &dev_attr_temp3_max);
+	device_create_file(&new_client->dev, &dev_attr_temp1_max_hyst);
+	device_create_file(&new_client->dev, &dev_attr_temp2_max_hyst);
+	device_create_file(&new_client->dev, &dev_attr_temp3_max_hyst);
+	device_create_file(&new_client->dev, &dev_attr_fan1_input);
+	device_create_file(&new_client->dev, &dev_attr_fan2_input);
+	device_create_file(&new_client->dev, &dev_attr_fan1_min);
+	device_create_file(&new_client->dev, &dev_attr_fan2_min);
+	device_create_file(&new_client->dev, &dev_attr_fan1_div);
+	device_create_file(&new_client->dev, &dev_attr_fan2_div);
+	device_create_file(&new_client->dev, &dev_attr_alarms);
+
+	return 0;
+
+ERROR3:
+	kfree(data);
+ERROR0:
+	release_region(address, VIA686A_EXTENT);
+	return err;
+}
+
+static int via686a_detach_client(struct i2c_client *client)
+{
+	int err;
+
+	if ((err = i2c_detach_client(client))) {
+		dev_err(&client->dev,
+		"Client deregistration failed, client not detached.\n");
+		return err;
+	}
+
+	release_region(client->addr, VIA686A_EXTENT);
+	kfree(i2c_get_clientdata(client));
+
+	return 0;
+}
+
+/* Called when we have found a new VIA686A. Set limits, etc. */
+static void via686a_init_client(struct i2c_client *client)
+{
+	u8 reg;
+
+	/* Start monitoring */
+	reg = via686a_read_value(client, VIA686A_REG_CONFIG);
+	via686a_write_value(client, VIA686A_REG_CONFIG, (reg|0x01)&0x7F);
+
+	/* Configure temp interrupt mode for continuous-interrupt operation */
+	via686a_write_value(client, VIA686A_REG_TEMP_MODE,
+			    via686a_read_value(client, VIA686A_REG_TEMP_MODE) &
+			    !(VIA686A_TEMP_MODE_MASK | VIA686A_TEMP_MODE_CONTINUOUS));
+}
+
+static struct via686a_data *via686a_update_device(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct via686a_data *data = i2c_get_clientdata(client);
+	int i;
+
+	down(&data->update_lock);
+
+	if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
+	    || !data->valid) {
+		for (i = 0; i <= 4; i++) {
+			data->in[i] =
+			    via686a_read_value(client, VIA686A_REG_IN(i));
+			data->in_min[i] = via686a_read_value(client,
+							     VIA686A_REG_IN_MIN
+							     (i));
+			data->in_max[i] =
+			    via686a_read_value(client, VIA686A_REG_IN_MAX(i));
+		}
+		for (i = 1; i <= 2; i++) {
+			data->fan[i - 1] =
+			    via686a_read_value(client, VIA686A_REG_FAN(i));
+			data->fan_min[i - 1] = via686a_read_value(client,
+						     VIA686A_REG_FAN_MIN(i));
+		}
+		for (i = 0; i <= 2; i++) {
+			data->temp[i] = via686a_read_value(client,
+						 VIA686A_REG_TEMP[i]) << 2;
+			data->temp_over[i] =
+			    via686a_read_value(client,
+					       VIA686A_REG_TEMP_OVER[i]);
+			data->temp_hyst[i] =
+			    via686a_read_value(client,
+					       VIA686A_REG_TEMP_HYST[i]);
+		}
+		/* add in lower 2 bits
+		   temp1 uses bits 7-6 of VIA686A_REG_TEMP_LOW1
+		   temp2 uses bits 5-4 of VIA686A_REG_TEMP_LOW23
+		   temp3 uses bits 7-6 of VIA686A_REG_TEMP_LOW23
+		 */
+		data->temp[0] |= (via686a_read_value(client,
+						     VIA686A_REG_TEMP_LOW1)
+				  & 0xc0) >> 6;
+		data->temp[1] |=
+		    (via686a_read_value(client, VIA686A_REG_TEMP_LOW23) &
+		     0x30) >> 4;
+		data->temp[2] |=
+		    (via686a_read_value(client, VIA686A_REG_TEMP_LOW23) &
+		     0xc0) >> 6;
+
+		i = via686a_read_value(client, VIA686A_REG_FANDIV);
+		data->fan_div[0] = (i >> 4) & 0x03;
+		data->fan_div[1] = i >> 6;
+		data->alarms =
+		    via686a_read_value(client,
+				       VIA686A_REG_ALARM1) |
+		    (via686a_read_value(client, VIA686A_REG_ALARM2) << 8);
+		data->last_updated = jiffies;
+		data->valid = 1;
+	}
+
+	up(&data->update_lock);
+
+	return data;
+}
+
+static struct pci_device_id via686a_pci_ids[] = {
+	{ PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4) },
+	{ 0, }
+};
+
+MODULE_DEVICE_TABLE(pci, via686a_pci_ids);
+
+static int __devinit via686a_pci_probe(struct pci_dev *dev,
+				       const struct pci_device_id *id)
+{
+	u16 val;
+	int addr = 0;
+
+	if (PCIBIOS_SUCCESSFUL !=
+	    pci_read_config_word(dev, VIA686A_BASE_REG, &val))
+		return -ENODEV;
+
+	addr = val & ~(VIA686A_EXTENT - 1);
+	if (addr == 0 && force_addr == 0) {
+		dev_err(&dev->dev, "base address not set - upgrade BIOS "
+			"or use force_addr=0xaddr\n");
+		return -ENODEV;
+	}
+	if (force_addr)
+		addr = force_addr;	/* so detect will get called */
+
+	if (!addr) {
+		dev_err(&dev->dev, "No Via 686A sensors found.\n");
+		return -ENODEV;
+	}
+	normal_isa[0] = addr;
+
+	s_bridge = pci_dev_get(dev);
+	if (i2c_add_driver(&via686a_driver)) {
+		pci_dev_put(s_bridge);
+		s_bridge = NULL;
+	}
+
+	/* Always return failure here.  This is to allow other drivers to bind
+	 * to this pci device.  We don't really want to have control over the
+	 * pci device, we only wanted to read as few register values from it.
+	 */
+	return -ENODEV;
+}
+
+static struct pci_driver via686a_pci_driver = {
+	.name		= "via686a",
+	.id_table	= via686a_pci_ids,
+	.probe		= via686a_pci_probe,
+};
+
+static int __init sm_via686a_init(void)
+{
+	return pci_register_driver(&via686a_pci_driver);
+}
+
+static void __exit sm_via686a_exit(void)
+{
+	pci_unregister_driver(&via686a_pci_driver);
+	if (s_bridge != NULL) {
+		i2c_del_driver(&via686a_driver);
+		pci_dev_put(s_bridge);
+		s_bridge = NULL;
+	}
+}
+
+MODULE_AUTHOR("Kyösti Mälkki <kmalkki@cc.hut.fi>, "
+	      "Mark Studebaker <mdsxyz123@yahoo.com> "
+	      "and Bob Dougherty <bobd@stanford.edu>");
+MODULE_DESCRIPTION("VIA 686A Sensor device");
+MODULE_LICENSE("GPL");
+
+module_init(sm_via686a_init);
+module_exit(sm_via686a_exit);
diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c
new file mode 100644
--- /dev/null
+++ b/drivers/hwmon/w83627ehf.c
@@ -0,0 +1,846 @@
+/*
+    w83627ehf - Driver for the hardware monitoring functionality of
+                the Winbond W83627EHF Super-I/O chip
+    Copyright (C) 2005  Jean Delvare <khali@linux-fr.org>
+
+    Shamelessly ripped from the w83627hf driver
+    Copyright (C) 2003  Mark Studebaker
+
+    Thanks to Leon Moonen, Steve Cliffe and Grant Coady for their help
+    in testing and debugging this driver.
+
+    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.
+
+
+    Supports the following chips:
+
+    Chip        #vin    #fan    #pwm    #temp   chip_id man_id
+    w83627ehf   -       5       -       3       0x88    0x5ca3
+
+    This is a preliminary version of the driver, only supporting the
+    fan and temperature inputs. The chip does much more than that.
+*/
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/i2c-sensor.h>
+#include <asm/io.h>
+#include "lm75.h"
+
+/* Addresses to scan
+   The actual ISA address is read from Super-I/O configuration space */
+static unsigned short normal_i2c[] = { I2C_CLIENT_END };
+static unsigned int normal_isa[] = { 0, I2C_CLIENT_ISA_END };
+
+/* Insmod parameters */
+SENSORS_INSMOD_1(w83627ehf);
+
+/*
+ * Super-I/O constants and functions
+ */
+
+static int REG;		/* The register to read/write */
+static int VAL;		/* The value to read/write */
+
+#define W83627EHF_LD_HWM	0x0b
+
+#define SIO_REG_LDSEL		0x07	/* Logical device select */
+#define SIO_REG_DEVID		0x20	/* Device ID (2 bytes) */
+#define SIO_REG_ENABLE		0x30	/* Logical device enable */
+#define SIO_REG_ADDR		0x60	/* Logical device address (2 bytes) */
+
+#define SIO_W83627EHF_ID	0x8840
+#define SIO_ID_MASK		0xFFC0
+
+static inline void
+superio_outb(int reg, int val)
+{
+	outb(reg, REG);
+	outb(val, VAL);
+}
+
+static inline int
+superio_inb(int reg)
+{
+	outb(reg, REG);
+	return inb(VAL);
+}
+
+static inline void
+superio_select(int ld)
+{
+	outb(SIO_REG_LDSEL, REG);
+	outb(ld, VAL);
+}
+
+static inline void
+superio_enter(void)
+{
+	outb(0x87, REG);
+	outb(0x87, REG);
+}
+
+static inline void
+superio_exit(void)
+{
+	outb(0x02, REG);
+	outb(0x02, VAL);
+}
+
+/*
+ * ISA constants
+ */
+
+#define REGION_LENGTH		8
+#define ADDR_REG_OFFSET		5
+#define DATA_REG_OFFSET		6
+
+#define W83627EHF_REG_BANK		0x4E
+#define W83627EHF_REG_CONFIG		0x40
+#define W83627EHF_REG_CHIP_ID		0x49
+#define W83627EHF_REG_MAN_ID		0x4F
+
+static const u16 W83627EHF_REG_FAN[] = { 0x28, 0x29, 0x2a, 0x3f, 0x553 };
+static const u16 W83627EHF_REG_FAN_MIN[] = { 0x3b, 0x3c, 0x3d, 0x3e, 0x55c };
+
+#define W83627EHF_REG_TEMP1		0x27
+#define W83627EHF_REG_TEMP1_HYST	0x3a
+#define W83627EHF_REG_TEMP1_OVER	0x39
+static const u16 W83627EHF_REG_TEMP[] = { 0x150, 0x250 };
+static const u16 W83627EHF_REG_TEMP_HYST[] = { 0x153, 0x253 };
+static const u16 W83627EHF_REG_TEMP_OVER[] = { 0x155, 0x255 };
+static const u16 W83627EHF_REG_TEMP_CONFIG[] = { 0x152, 0x252 };
+
+/* Fan clock dividers are spread over the following five registers */
+#define W83627EHF_REG_FANDIV1		0x47
+#define W83627EHF_REG_FANDIV2		0x4B
+#define W83627EHF_REG_VBAT		0x5D
+#define W83627EHF_REG_DIODE		0x59
+#define W83627EHF_REG_SMI_OVT		0x4C
+
+/*
+ * Conversions
+ */
+
+static inline unsigned int
+fan_from_reg(u8 reg, unsigned int div)
+{
+	if (reg == 0 || reg == 255)
+		return 0;
+	return 1350000U / (reg * div);
+}
+
+static inline unsigned int
+div_from_reg(u8 reg)
+{
+	return 1 << reg;
+}
+
+static inline int
+temp1_from_reg(s8 reg)
+{
+	return reg * 1000;
+}
+
+static inline s8
+temp1_to_reg(int temp)
+{
+	if (temp <= -128000)
+		return -128;
+	if (temp >= 127000)
+		return 127;
+	if (temp < 0)
+		return (temp - 500) / 1000;
+	return (temp + 500) / 1000;
+}
+
+/*
+ * Data structures and manipulation thereof
+ */
+
+struct w83627ehf_data {
+	struct i2c_client client;
+	struct semaphore lock;
+
+	struct semaphore update_lock;
+	char valid;		/* !=0 if following fields are valid */
+	unsigned long last_updated;	/* In jiffies */
+
+	/* Register values */
+	u8 fan[5];
+	u8 fan_min[5];
+	u8 fan_div[5];
+	u8 has_fan;		/* some fan inputs can be disabled */
+	s8 temp1;
+	s8 temp1_max;
+	s8 temp1_max_hyst;
+	s16 temp[2];
+	s16 temp_max[2];
+	s16 temp_max_hyst[2];
+};
+
+static inline int is_word_sized(u16 reg)
+{
+	return (((reg & 0xff00) == 0x100
+	      || (reg & 0xff00) == 0x200)
+	     && ((reg & 0x00ff) == 0x50
+	      || (reg & 0x00ff) == 0x53
+	      || (reg & 0x00ff) == 0x55));
+}
+
+/* We assume that the default bank is 0, thus the following two functions do
+   nothing for registers which live in bank 0. For others, they respectively
+   set the bank register to the correct value (before the register is
+   accessed), and back to 0 (afterwards). */
+static inline void w83627ehf_set_bank(struct i2c_client *client, u16 reg)
+{
+	if (reg & 0xff00) {
+		outb_p(W83627EHF_REG_BANK, client->addr + ADDR_REG_OFFSET);
+		outb_p(reg >> 8, client->addr + DATA_REG_OFFSET);
+	}
+}
+
+static inline void w83627ehf_reset_bank(struct i2c_client *client, u16 reg)
+{
+	if (reg & 0xff00) {
+		outb_p(W83627EHF_REG_BANK, client->addr + ADDR_REG_OFFSET);
+		outb_p(0, client->addr + DATA_REG_OFFSET);
+	}
+}
+
+static u16 w83627ehf_read_value(struct i2c_client *client, u16 reg)
+{
+	struct w83627ehf_data *data = i2c_get_clientdata(client);
+	int res, word_sized = is_word_sized(reg);
+
+	down(&data->lock);
+
+	w83627ehf_set_bank(client, reg);
+	outb_p(reg & 0xff, client->addr + ADDR_REG_OFFSET);
+	res = inb_p(client->addr + DATA_REG_OFFSET);
+	if (word_sized) {
+		outb_p((reg & 0xff) + 1,
+		       client->addr + ADDR_REG_OFFSET);
+		res = (res << 8) + inb_p(client->addr + DATA_REG_OFFSET);
+	}
+	w83627ehf_reset_bank(client, reg);
+
+	up(&data->lock);
+
+	return res;
+}
+
+static int w83627ehf_write_value(struct i2c_client *client, u16 reg, u16 value)
+{
+	struct w83627ehf_data *data = i2c_get_clientdata(client);
+	int word_sized = is_word_sized(reg);
+
+	down(&data->lock);
+
+	w83627ehf_set_bank(client, reg);
+	outb_p(reg & 0xff, client->addr + ADDR_REG_OFFSET);
+	if (word_sized) {
+		outb_p(value >> 8, client->addr + DATA_REG_OFFSET);
+		outb_p((reg & 0xff) + 1,
+		       client->addr + ADDR_REG_OFFSET);
+	}
+	outb_p(value & 0xff, client->addr + DATA_REG_OFFSET);
+	w83627ehf_reset_bank(client, reg);
+
+	up(&data->lock);
+	return 0;
+}
+
+/* This function assumes that the caller holds data->update_lock */
+static void w83627ehf_write_fan_div(struct i2c_client *client, int nr)
+{
+	struct w83627ehf_data *data = i2c_get_clientdata(client);
+	u8 reg;
+
+	switch (nr) {
+	case 0:
+		reg = (w83627ehf_read_value(client, W83627EHF_REG_FANDIV1) & 0xcf)
+		    | ((data->fan_div[0] & 0x03) << 4);
+		w83627ehf_write_value(client, W83627EHF_REG_FANDIV1, reg);
+		reg = (w83627ehf_read_value(client, W83627EHF_REG_VBAT) & 0xdf)
+		    | ((data->fan_div[0] & 0x04) << 3);
+		w83627ehf_write_value(client, W83627EHF_REG_VBAT, reg);
+		break;
+	case 1:
+		reg = (w83627ehf_read_value(client, W83627EHF_REG_FANDIV1) & 0x3f)
+		    | ((data->fan_div[1] & 0x03) << 6);
+		w83627ehf_write_value(client, W83627EHF_REG_FANDIV1, reg);
+		reg = (w83627ehf_read_value(client, W83627EHF_REG_VBAT) & 0xbf)
+		    | ((data->fan_div[1] & 0x04) << 4);
+		w83627ehf_write_value(client, W83627EHF_REG_VBAT, reg);
+		break;
+	case 2:
+		reg = (w83627ehf_read_value(client, W83627EHF_REG_FANDIV2) & 0x3f)
+		    | ((data->fan_div[2] & 0x03) << 6);
+		w83627ehf_write_value(client, W83627EHF_REG_FANDIV2, reg);
+		reg = (w83627ehf_read_value(client, W83627EHF_REG_VBAT) & 0x7f)
+		    | ((data->fan_div[2] & 0x04) << 5);
+		w83627ehf_write_value(client, W83627EHF_REG_VBAT, reg);
+		break;
+	case 3:
+		reg = (w83627ehf_read_value(client, W83627EHF_REG_DIODE) & 0xfc)
+		    | (data->fan_div[3] & 0x03);
+		w83627ehf_write_value(client, W83627EHF_REG_DIODE, reg);
+		reg = (w83627ehf_read_value(client, W83627EHF_REG_SMI_OVT) & 0x7f)
+		    | ((data->fan_div[3] & 0x04) << 5);
+		w83627ehf_write_value(client, W83627EHF_REG_SMI_OVT, reg);
+		break;
+	case 4:
+		reg = (w83627ehf_read_value(client, W83627EHF_REG_DIODE) & 0x73)
+		    | ((data->fan_div[4] & 0x03) << 3)
+		    | ((data->fan_div[4] & 0x04) << 5);
+		w83627ehf_write_value(client, W83627EHF_REG_DIODE, reg);
+		break;
+	}
+}
+
+static struct w83627ehf_data *w83627ehf_update_device(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct w83627ehf_data *data = i2c_get_clientdata(client);
+	int i;
+
+	down(&data->update_lock);
+
+	if (time_after(jiffies, data->last_updated + HZ)
+	 || !data->valid) {
+		/* Fan clock dividers */
+		i = w83627ehf_read_value(client, W83627EHF_REG_FANDIV1);
+		data->fan_div[0] = (i >> 4) & 0x03;
+		data->fan_div[1] = (i >> 6) & 0x03;
+		i = w83627ehf_read_value(client, W83627EHF_REG_FANDIV2);
+		data->fan_div[2] = (i >> 6) & 0x03;
+		i = w83627ehf_read_value(client, W83627EHF_REG_VBAT);
+		data->fan_div[0] |= (i >> 3) & 0x04;
+		data->fan_div[1] |= (i >> 4) & 0x04;
+		data->fan_div[2] |= (i >> 5) & 0x04;
+		if (data->has_fan & ((1 << 3) | (1 << 4))) {
+			i = w83627ehf_read_value(client, W83627EHF_REG_DIODE);
+			data->fan_div[3] = i & 0x03;
+			data->fan_div[4] = ((i >> 2) & 0x03)
+					 | ((i >> 5) & 0x04);
+		}
+		if (data->has_fan & (1 << 3)) {
+			i = w83627ehf_read_value(client, W83627EHF_REG_SMI_OVT);
+			data->fan_div[3] |= (i >> 5) & 0x04;
+		}
+
+		/* Measured fan speeds and limits */
+		for (i = 0; i < 5; i++) {
+			if (!(data->has_fan & (1 << i)))
+				continue;
+
+			data->fan[i] = w83627ehf_read_value(client,
+				       W83627EHF_REG_FAN[i]);
+			data->fan_min[i] = w83627ehf_read_value(client,
+					   W83627EHF_REG_FAN_MIN[i]);
+
+			/* If we failed to measure the fan speed and clock
+			   divider can be increased, let's try that for next
+			   time */
+			if (data->fan[i] == 0xff
+			 && data->fan_div[i] < 0x07) {
+			 	dev_dbg(&client->dev, "Increasing fan %d "
+					"clock divider from %u to %u\n",
+					i, div_from_reg(data->fan_div[i]),
+					div_from_reg(data->fan_div[i] + 1));
+				data->fan_div[i]++;
+				w83627ehf_write_fan_div(client, i);
+				/* Preserve min limit if possible */
+				if (data->fan_min[i] >= 2
+				 && data->fan_min[i] != 255)
+					w83627ehf_write_value(client,
+						W83627EHF_REG_FAN_MIN[i],
+						(data->fan_min[i] /= 2));
+			}
+		}
+
+		/* Measured temperatures and limits */
+		data->temp1 = w83627ehf_read_value(client,
+			      W83627EHF_REG_TEMP1);
+		data->temp1_max = w83627ehf_read_value(client,
+				  W83627EHF_REG_TEMP1_OVER);
+		data->temp1_max_hyst = w83627ehf_read_value(client,
+				       W83627EHF_REG_TEMP1_HYST);
+		for (i = 0; i < 2; i++) {
+			data->temp[i] = w83627ehf_read_value(client,
+					W83627EHF_REG_TEMP[i]);
+			data->temp_max[i] = w83627ehf_read_value(client,
+					    W83627EHF_REG_TEMP_OVER[i]);
+			data->temp_max_hyst[i] = w83627ehf_read_value(client,
+						 W83627EHF_REG_TEMP_HYST[i]);
+		}
+
+		data->last_updated = jiffies;
+		data->valid = 1;
+	}
+
+	up(&data->update_lock);
+	return data;
+}
+
+/*
+ * Sysfs callback functions
+ */
+
+#define show_fan_reg(reg) \
+static ssize_t \
+show_##reg(struct device *dev, char *buf, int nr) \
+{ \
+	struct w83627ehf_data *data = w83627ehf_update_device(dev); \
+	return sprintf(buf, "%d\n", \
+		       fan_from_reg(data->reg[nr], \
+				    div_from_reg(data->fan_div[nr]))); \
+}
+show_fan_reg(fan);
+show_fan_reg(fan_min);
+
+static ssize_t
+show_fan_div(struct device *dev, char *buf, int nr)
+{
+	struct w83627ehf_data *data = w83627ehf_update_device(dev);
+	return sprintf(buf, "%u\n",
+		       div_from_reg(data->fan_div[nr]));
+}
+
+static ssize_t
+store_fan_min(struct device *dev, const char *buf, size_t count, int nr)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct w83627ehf_data *data = i2c_get_clientdata(client);
+	unsigned int val = simple_strtoul(buf, NULL, 10);
+	unsigned int reg;
+	u8 new_div;
+
+	down(&data->update_lock);
+	if (!val) {
+		/* No min limit, alarm disabled */
+		data->fan_min[nr] = 255;
+		new_div = data->fan_div[nr]; /* No change */
+		dev_info(dev, "fan%u low limit and alarm disabled\n", nr + 1);
+	} else if ((reg = 1350000U / val) >= 128 * 255) {
+		/* Speed below this value cannot possibly be represented,
+		   even with the highest divider (128) */
+		data->fan_min[nr] = 254;
+		new_div = 7; /* 128 == (1 << 7) */
+		dev_warn(dev, "fan%u low limit %u below minimum %u, set to "
+			 "minimum\n", nr + 1, val, fan_from_reg(254, 128));
+	} else if (!reg) {
+		/* Speed above this value cannot possibly be represented,
+		   even with the lowest divider (1) */
+		data->fan_min[nr] = 1;
+		new_div = 0; /* 1 == (1 << 0) */
+		dev_warn(dev, "fan%u low limit %u above maximum %u, set to "
+			 "maximum\n", nr + 1, val, fan_from_reg(1, 1));
+	} else {
+		/* Automatically pick the best divider, i.e. the one such
+		   that the min limit will correspond to a register value
+		   in the 96..192 range */
+		new_div = 0;
+		while (reg > 192 && new_div < 7) {
+			reg >>= 1;
+			new_div++;
+		}
+		data->fan_min[nr] = reg;
+	}
+
+	/* Write both the fan clock divider (if it changed) and the new
+	   fan min (unconditionally) */
+	if (new_div != data->fan_div[nr]) {
+		if (new_div > data->fan_div[nr])
+			data->fan[nr] >>= (data->fan_div[nr] - new_div);
+		else
+			data->fan[nr] <<= (new_div - data->fan_div[nr]);
+
+		dev_dbg(dev, "fan%u clock divider changed from %u to %u\n",
+			nr + 1, div_from_reg(data->fan_div[nr]),
+			div_from_reg(new_div));
+		data->fan_div[nr] = new_div;
+		w83627ehf_write_fan_div(client, nr);
+	}
+	w83627ehf_write_value(client, W83627EHF_REG_FAN_MIN[nr],
+			      data->fan_min[nr]);
+	up(&data->update_lock);
+
+	return count;
+}
+
+#define sysfs_fan_offset(offset) \
+static ssize_t \
+show_reg_fan_##offset(struct device *dev, struct device_attribute *attr, \
+		      char *buf) \
+{ \
+	return show_fan(dev, buf, offset-1); \
+} \
+static DEVICE_ATTR(fan##offset##_input, S_IRUGO, \
+		   show_reg_fan_##offset, NULL);
+
+#define sysfs_fan_min_offset(offset) \
+static ssize_t \
+show_reg_fan##offset##_min(struct device *dev, struct device_attribute *attr, \
+			   char *buf) \
+{ \
+	return show_fan_min(dev, buf, offset-1); \
+} \
+static ssize_t \
+store_reg_fan##offset##_min(struct device *dev, struct device_attribute *attr, \
+			    const char *buf, size_t count) \
+{ \
+	return store_fan_min(dev, buf, count, offset-1); \
+} \
+static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \
+		   show_reg_fan##offset##_min, \
+		   store_reg_fan##offset##_min);
+
+#define sysfs_fan_div_offset(offset) \
+static ssize_t \
+show_reg_fan##offset##_div(struct device *dev, struct device_attribute *attr, \
+			   char *buf) \
+{ \
+	return show_fan_div(dev, buf, offset - 1); \
+} \
+static DEVICE_ATTR(fan##offset##_div, S_IRUGO, \
+		   show_reg_fan##offset##_div, NULL);
+
+sysfs_fan_offset(1);
+sysfs_fan_min_offset(1);
+sysfs_fan_div_offset(1);
+sysfs_fan_offset(2);
+sysfs_fan_min_offset(2);
+sysfs_fan_div_offset(2);
+sysfs_fan_offset(3);
+sysfs_fan_min_offset(3);
+sysfs_fan_div_offset(3);
+sysfs_fan_offset(4);
+sysfs_fan_min_offset(4);
+sysfs_fan_div_offset(4);
+sysfs_fan_offset(5);
+sysfs_fan_min_offset(5);
+sysfs_fan_div_offset(5);
+
+#define show_temp1_reg(reg) \
+static ssize_t \
+show_##reg(struct device *dev, struct device_attribute *attr, \
+	   char *buf) \
+{ \
+	struct w83627ehf_data *data = w83627ehf_update_device(dev); \
+	return sprintf(buf, "%d\n", temp1_from_reg(data->reg)); \
+}
+show_temp1_reg(temp1);
+show_temp1_reg(temp1_max);
+show_temp1_reg(temp1_max_hyst);
+
+#define store_temp1_reg(REG, reg) \
+static ssize_t \
+store_temp1_##reg(struct device *dev, struct device_attribute *attr, \
+		  const char *buf, size_t count) \
+{ \
+	struct i2c_client *client = to_i2c_client(dev); \
+	struct w83627ehf_data *data = i2c_get_clientdata(client); \
+	u32 val = simple_strtoul(buf, NULL, 10); \
+ \
+	down(&data->update_lock); \
+	data->temp1_##reg = temp1_to_reg(val); \
+	w83627ehf_write_value(client, W83627EHF_REG_TEMP1_##REG, \
+			      data->temp1_##reg); \
+	up(&data->update_lock); \
+	return count; \
+}
+store_temp1_reg(OVER, max);
+store_temp1_reg(HYST, max_hyst);
+
+static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp1, NULL);
+static DEVICE_ATTR(temp1_max, S_IRUGO| S_IWUSR,
+		   show_temp1_max, store_temp1_max);
+static DEVICE_ATTR(temp1_max_hyst, S_IRUGO| S_IWUSR,
+		   show_temp1_max_hyst, store_temp1_max_hyst);
+
+#define show_temp_reg(reg) \
+static ssize_t \
+show_##reg (struct device *dev, char *buf, int nr) \
+{ \
+	struct w83627ehf_data *data = w83627ehf_update_device(dev); \
+	return sprintf(buf, "%d\n", \
+		       LM75_TEMP_FROM_REG(data->reg[nr])); \
+}
+show_temp_reg(temp);
+show_temp_reg(temp_max);
+show_temp_reg(temp_max_hyst);
+
+#define store_temp_reg(REG, reg) \
+static ssize_t \
+store_##reg (struct device *dev, const char *buf, size_t count, int nr) \
+{ \
+	struct i2c_client *client = to_i2c_client(dev); \
+	struct w83627ehf_data *data = i2c_get_clientdata(client); \
+	u32 val = simple_strtoul(buf, NULL, 10); \
+ \
+	down(&data->update_lock); \
+	data->reg[nr] = LM75_TEMP_TO_REG(val); \
+	w83627ehf_write_value(client, W83627EHF_REG_TEMP_##REG[nr], \
+			      data->reg[nr]); \
+	up(&data->update_lock); \
+	return count; \
+}
+store_temp_reg(OVER, temp_max);
+store_temp_reg(HYST, temp_max_hyst);
+
+#define sysfs_temp_offset(offset) \
+static ssize_t \
+show_reg_temp##offset (struct device *dev, struct device_attribute *attr, \
+		       char *buf) \
+{ \
+	return show_temp(dev, buf, offset - 2); \
+} \
+static DEVICE_ATTR(temp##offset##_input, S_IRUGO, \
+		   show_reg_temp##offset, NULL);
+
+#define sysfs_temp_reg_offset(reg, offset) \
+static ssize_t \
+show_reg_temp##offset##_##reg(struct device *dev, struct device_attribute *attr, \
+			      char *buf) \
+{ \
+	return show_temp_##reg(dev, buf, offset - 2); \
+} \
+static ssize_t \
+store_reg_temp##offset##_##reg(struct device *dev, struct device_attribute *attr, \
+			       const char *buf, size_t count) \
+{ \
+	return store_temp_##reg(dev, buf, count, offset - 2); \
+} \
+static DEVICE_ATTR(temp##offset##_##reg, S_IRUGO| S_IWUSR, \
+		   show_reg_temp##offset##_##reg, \
+		   store_reg_temp##offset##_##reg);
+
+sysfs_temp_offset(2);
+sysfs_temp_reg_offset(max, 2);
+sysfs_temp_reg_offset(max_hyst, 2);
+sysfs_temp_offset(3);
+sysfs_temp_reg_offset(max, 3);
+sysfs_temp_reg_offset(max_hyst, 3);
+
+/*
+ * Driver and client management
+ */
+
+static struct i2c_driver w83627ehf_driver;
+
+static void w83627ehf_init_client(struct i2c_client *client)
+{
+	int i;
+	u8 tmp;
+
+	/* Start monitoring is needed */
+	tmp = w83627ehf_read_value(client, W83627EHF_REG_CONFIG);
+	if (!(tmp & 0x01))
+		w83627ehf_write_value(client, W83627EHF_REG_CONFIG,
+				      tmp | 0x01);
+
+	/* Enable temp2 and temp3 if needed */
+	for (i = 0; i < 2; i++) {
+		tmp = w83627ehf_read_value(client,
+					   W83627EHF_REG_TEMP_CONFIG[i]);
+		if (tmp & 0x01)
+			w83627ehf_write_value(client,
+					      W83627EHF_REG_TEMP_CONFIG[i],
+					      tmp & 0xfe);
+	}
+}
+
+static int w83627ehf_detect(struct i2c_adapter *adapter, int address, int kind)
+{
+	struct i2c_client *client;
+	struct w83627ehf_data *data;
+	int i, err = 0;
+
+	if (!i2c_is_isa_adapter(adapter))
+		return 0;
+
+	if (!request_region(address, REGION_LENGTH, w83627ehf_driver.name)) {
+		err = -EBUSY;
+		goto exit;
+	}
+
+	if (!(data = kmalloc(sizeof(struct w83627ehf_data), GFP_KERNEL))) {
+		err = -ENOMEM;
+		goto exit_release;
+	}
+	memset(data, 0, sizeof(struct w83627ehf_data));
+
+	client = &data->client;
+	i2c_set_clientdata(client, data);
+	client->addr = address;
+	init_MUTEX(&data->lock);
+	client->adapter = adapter;
+	client->driver = &w83627ehf_driver;
+	client->flags = 0;
+
+	strlcpy(client->name, "w83627ehf", I2C_NAME_SIZE);
+	data->valid = 0;
+	init_MUTEX(&data->update_lock);
+
+	/* Tell the i2c layer a new client has arrived */
+	if ((err = i2c_attach_client(client)))
+		goto exit_free;
+
+	/* Initialize the chip */
+	w83627ehf_init_client(client);
+
+	/* A few vars need to be filled upon startup */
+	for (i = 0; i < 5; i++)
+		data->fan_min[i] = w83627ehf_read_value(client,
+				   W83627EHF_REG_FAN_MIN[i]);
+
+	/* It looks like fan4 and fan5 pins can be alternatively used
+	   as fan on/off switches */
+	data->has_fan = 0x07; /* fan1, fan2 and fan3 */
+	i = w83627ehf_read_value(client, W83627EHF_REG_FANDIV1);
+	if (i & (1 << 2))
+		data->has_fan |= (1 << 3);
+	if (i & (1 << 0))
+		data->has_fan |= (1 << 4);
+
+	/* Register sysfs hooks */
+	device_create_file(&client->dev, &dev_attr_fan1_input);
+	device_create_file(&client->dev, &dev_attr_fan1_min);
+	device_create_file(&client->dev, &dev_attr_fan1_div);
+	device_create_file(&client->dev, &dev_attr_fan2_input);
+	device_create_file(&client->dev, &dev_attr_fan2_min);
+	device_create_file(&client->dev, &dev_attr_fan2_div);
+	device_create_file(&client->dev, &dev_attr_fan3_input);
+	device_create_file(&client->dev, &dev_attr_fan3_min);
+	device_create_file(&client->dev, &dev_attr_fan3_div);
+
+	if (data->has_fan & (1 << 3)) {
+		device_create_file(&client->dev, &dev_attr_fan4_input);
+		device_create_file(&client->dev, &dev_attr_fan4_min);
+		device_create_file(&client->dev, &dev_attr_fan4_div);
+	}
+	if (data->has_fan & (1 << 4)) {
+		device_create_file(&client->dev, &dev_attr_fan5_input);
+		device_create_file(&client->dev, &dev_attr_fan5_min);
+		device_create_file(&client->dev, &dev_attr_fan5_div);
+	}
+
+	device_create_file(&client->dev, &dev_attr_temp1_input);
+	device_create_file(&client->dev, &dev_attr_temp1_max);
+	device_create_file(&client->dev, &dev_attr_temp1_max_hyst);
+	device_create_file(&client->dev, &dev_attr_temp2_input);
+	device_create_file(&client->dev, &dev_attr_temp2_max);
+	device_create_file(&client->dev, &dev_attr_temp2_max_hyst);
+	device_create_file(&client->dev, &dev_attr_temp3_input);
+	device_create_file(&client->dev, &dev_attr_temp3_max);
+	device_create_file(&client->dev, &dev_attr_temp3_max_hyst);
+
+	return 0;
+
+exit_free:
+	kfree(data);
+exit_release:
+	release_region(address, REGION_LENGTH);
+exit:
+	return err;
+}
+
+static int w83627ehf_attach_adapter(struct i2c_adapter *adapter)
+{
+	if (!(adapter->class & I2C_CLASS_HWMON))
+		return 0;
+	return i2c_detect(adapter, &addr_data, w83627ehf_detect);
+}
+
+static int w83627ehf_detach_client(struct i2c_client *client)
+{
+	int err;
+
+	if ((err = i2c_detach_client(client))) {
+		dev_err(&client->dev, "Client deregistration failed, "
+			"client not detached.\n");
+		return err;
+	}
+	release_region(client->addr, REGION_LENGTH);
+	kfree(i2c_get_clientdata(client));
+
+	return 0;
+}
+
+static struct i2c_driver w83627ehf_driver = {
+	.owner		= THIS_MODULE,
+	.name		= "w83627ehf",
+	.flags		= I2C_DF_NOTIFY,
+	.attach_adapter	= w83627ehf_attach_adapter,
+	.detach_client	= w83627ehf_detach_client,
+};
+
+static int __init w83627ehf_find(int sioaddr, int *address)
+{
+	u16 val;
+
+	REG = sioaddr;
+	VAL = sioaddr + 1;
+	superio_enter();
+
+	val = (superio_inb(SIO_REG_DEVID) << 8)
+	    | superio_inb(SIO_REG_DEVID + 1);
+	if ((val & SIO_ID_MASK) != SIO_W83627EHF_ID) {
+		superio_exit();
+		return -ENODEV;
+	}
+
+	superio_select(W83627EHF_LD_HWM);
+	val = (superio_inb(SIO_REG_ADDR) << 8)
+	    | superio_inb(SIO_REG_ADDR + 1);
+	*address = val & ~(REGION_LENGTH - 1);
+	if (*address == 0) {
+		superio_exit();
+		return -ENODEV;
+	}
+
+	/* Activate logical device if needed */
+	val = superio_inb(SIO_REG_ENABLE);
+	if (!(val & 0x01))
+		superio_outb(SIO_REG_ENABLE, val | 0x01);
+
+	superio_exit();
+	return 0;
+}
+
+static int __init sensors_w83627ehf_init(void)
+{
+	if (w83627ehf_find(0x2e, &normal_isa[0])
+	 && w83627ehf_find(0x4e, &normal_isa[0]))
+		return -ENODEV;
+
+	return i2c_add_driver(&w83627ehf_driver);
+}
+
+static void __exit sensors_w83627ehf_exit(void)
+{
+	i2c_del_driver(&w83627ehf_driver);
+}
+
+MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>");
+MODULE_DESCRIPTION("W83627EHF driver");
+MODULE_LICENSE("GPL");
+
+module_init(sensors_w83627ehf_init);
+module_exit(sensors_w83627ehf_exit);
diff --git a/drivers/hwmon/w83627hf.c b/drivers/hwmon/w83627hf.c
new file mode 100644
--- /dev/null
+++ b/drivers/hwmon/w83627hf.c
@@ -0,0 +1,1511 @@
+/*
+    w83627hf.c - Part of lm_sensors, Linux kernel modules for hardware
+                monitoring
+    Copyright (c) 1998 - 2003  Frodo Looijaard <frodol@dds.nl>,
+    Philip Edelbrock <phil@netroedge.com>,
+    and Mark Studebaker <mdsxyz123@yahoo.com>
+    Ported to 2.6 by Bernhard C. Schrenk <clemy@clemy.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.
+*/
+
+/*
+    Supports following chips:
+
+    Chip	#vin	#fanin	#pwm	#temp	wchipid	vendid	i2c	ISA
+    w83627hf	9	3	2	3	0x20	0x5ca3	no	yes(LPC)
+    w83627thf	7	3	3	3	0x90	0x5ca3	no	yes(LPC)
+    w83637hf	7	3	3	3	0x80	0x5ca3	no	yes(LPC)
+    w83697hf	8	2	2	2	0x60	0x5ca3	no	yes(LPC)
+
+    For other winbond chips, and for i2c support in the above chips,
+    use w83781d.c.
+
+    Note: automatic ("cruise") fan control for 697, 637 & 627thf not
+    supported yet.
+*/
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+#include <linux/i2c.h>
+#include <linux/i2c-sensor.h>
+#include <linux/i2c-vid.h>
+#include <asm/io.h>
+#include "lm75.h"
+
+static u16 force_addr;
+module_param(force_addr, ushort, 0);
+MODULE_PARM_DESC(force_addr,
+		 "Initialize the base address of the sensors");
+static u8 force_i2c = 0x1f;
+module_param(force_i2c, byte, 0);
+MODULE_PARM_DESC(force_i2c,
+		 "Initialize the i2c address of the sensors");
+
+/* Addresses to scan */
+static unsigned short normal_i2c[] = { I2C_CLIENT_END };
+static unsigned int normal_isa[] = { 0, I2C_CLIENT_ISA_END };
+
+/* Insmod parameters */
+SENSORS_INSMOD_4(w83627hf, w83627thf, w83697hf, w83637hf);
+
+static int init = 1;
+module_param(init, bool, 0);
+MODULE_PARM_DESC(init, "Set to zero to bypass chip initialization");
+
+/* modified from kernel/include/traps.c */
+static int REG;		/* The register to read/write */
+#define	DEV	0x07	/* Register: Logical device select */
+static int VAL;		/* The value to read/write */
+
+/* logical device numbers for superio_select (below) */
+#define W83627HF_LD_FDC		0x00
+#define W83627HF_LD_PRT		0x01
+#define W83627HF_LD_UART1	0x02
+#define W83627HF_LD_UART2	0x03
+#define W83627HF_LD_KBC		0x05
+#define W83627HF_LD_CIR		0x06 /* w83627hf only */
+#define W83627HF_LD_GAME	0x07
+#define W83627HF_LD_MIDI	0x07
+#define W83627HF_LD_GPIO1	0x07
+#define W83627HF_LD_GPIO5	0x07 /* w83627thf only */
+#define W83627HF_LD_GPIO2	0x08
+#define W83627HF_LD_GPIO3	0x09
+#define W83627HF_LD_GPIO4	0x09 /* w83627thf only */
+#define W83627HF_LD_ACPI	0x0a
+#define W83627HF_LD_HWM		0x0b
+
+#define	DEVID	0x20	/* Register: Device ID */
+
+#define W83627THF_GPIO5_EN	0x30 /* w83627thf only */
+#define W83627THF_GPIO5_IOSR	0xf3 /* w83627thf only */
+#define W83627THF_GPIO5_DR	0xf4 /* w83627thf only */
+
+static inline void
+superio_outb(int reg, int val)
+{
+	outb(reg, REG);
+	outb(val, VAL);
+}
+
+static inline int
+superio_inb(int reg)
+{
+	outb(reg, REG);
+	return inb(VAL);
+}
+
+static inline void
+superio_select(int ld)
+{
+	outb(DEV, REG);
+	outb(ld, VAL);
+}
+
+static inline void
+superio_enter(void)
+{
+	outb(0x87, REG);
+	outb(0x87, REG);
+}
+
+static inline void
+superio_exit(void)
+{
+	outb(0xAA, REG);
+}
+
+#define W627_DEVID 0x52
+#define W627THF_DEVID 0x82
+#define W697_DEVID 0x60
+#define W637_DEVID 0x70
+#define WINB_ACT_REG 0x30
+#define WINB_BASE_REG 0x60
+/* Constants specified below */
+
+/* Length of ISA address segment */
+#define WINB_EXTENT 8
+
+/* Where are the ISA address/data registers relative to the base address */
+#define W83781D_ADDR_REG_OFFSET 5
+#define W83781D_DATA_REG_OFFSET 6
+
+/* The W83781D registers */
+/* The W83782D registers for nr=7,8 are in bank 5 */
+#define W83781D_REG_IN_MAX(nr) ((nr < 7) ? (0x2b + (nr) * 2) : \
+					   (0x554 + (((nr) - 7) * 2)))
+#define W83781D_REG_IN_MIN(nr) ((nr < 7) ? (0x2c + (nr) * 2) : \
+					   (0x555 + (((nr) - 7) * 2)))
+#define W83781D_REG_IN(nr)     ((nr < 7) ? (0x20 + (nr)) : \
+					   (0x550 + (nr) - 7))
+
+#define W83781D_REG_FAN_MIN(nr) (0x3a + (nr))
+#define W83781D_REG_FAN(nr) (0x27 + (nr))
+
+#define W83781D_REG_TEMP2_CONFIG 0x152
+#define W83781D_REG_TEMP3_CONFIG 0x252
+#define W83781D_REG_TEMP(nr)		((nr == 3) ? (0x0250) : \
+					((nr == 2) ? (0x0150) : \
+					             (0x27)))
+#define W83781D_REG_TEMP_HYST(nr)	((nr == 3) ? (0x253) : \
+					((nr == 2) ? (0x153) : \
+					             (0x3A)))
+#define W83781D_REG_TEMP_OVER(nr)	((nr == 3) ? (0x255) : \
+					((nr == 2) ? (0x155) : \
+					             (0x39)))
+
+#define W83781D_REG_BANK 0x4E
+
+#define W83781D_REG_CONFIG 0x40
+#define W83781D_REG_ALARM1 0x41
+#define W83781D_REG_ALARM2 0x42
+#define W83781D_REG_ALARM3 0x450
+
+#define W83781D_REG_IRQ 0x4C
+#define W83781D_REG_BEEP_CONFIG 0x4D
+#define W83781D_REG_BEEP_INTS1 0x56
+#define W83781D_REG_BEEP_INTS2 0x57
+#define W83781D_REG_BEEP_INTS3 0x453
+
+#define W83781D_REG_VID_FANDIV 0x47
+
+#define W83781D_REG_CHIPID 0x49
+#define W83781D_REG_WCHIPID 0x58
+#define W83781D_REG_CHIPMAN 0x4F
+#define W83781D_REG_PIN 0x4B
+
+#define W83781D_REG_VBAT 0x5D
+
+#define W83627HF_REG_PWM1 0x5A
+#define W83627HF_REG_PWM2 0x5B
+#define W83627HF_REG_PWMCLK12 0x5C
+
+#define W83627THF_REG_PWM1		0x01	/* 697HF and 637HF too */
+#define W83627THF_REG_PWM2		0x03	/* 697HF and 637HF too */
+#define W83627THF_REG_PWM3		0x11	/* 637HF too */
+
+#define W83627THF_REG_VRM_OVT_CFG 	0x18	/* 637HF too */
+
+static const u8 regpwm_627hf[] = { W83627HF_REG_PWM1, W83627HF_REG_PWM2 };
+static const u8 regpwm[] = { W83627THF_REG_PWM1, W83627THF_REG_PWM2,
+                             W83627THF_REG_PWM3 };
+#define W836X7HF_REG_PWM(type, nr) (((type) == w83627hf) ? \
+                                     regpwm_627hf[(nr) - 1] : regpwm[(nr) - 1])
+
+#define W83781D_REG_I2C_ADDR 0x48
+#define W83781D_REG_I2C_SUBADDR 0x4A
+
+/* Sensor selection */
+#define W83781D_REG_SCFG1 0x5D
+static const u8 BIT_SCFG1[] = { 0x02, 0x04, 0x08 };
+#define W83781D_REG_SCFG2 0x59
+static const u8 BIT_SCFG2[] = { 0x10, 0x20, 0x40 };
+#define W83781D_DEFAULT_BETA 3435
+
+/* Conversions. Limit checking is only done on the TO_REG
+   variants. Note that you should be a bit careful with which arguments
+   these macros are called: arguments may be evaluated more than once.
+   Fixing this is just not worth it. */
+#define IN_TO_REG(val)  (SENSORS_LIMIT((((val) + 8)/16),0,255))
+#define IN_FROM_REG(val) ((val) * 16)
+
+static inline u8 FAN_TO_REG(long rpm, int div)
+{
+	if (rpm == 0)
+		return 255;
+	rpm = SENSORS_LIMIT(rpm, 1, 1000000);
+	return SENSORS_LIMIT((1350000 + rpm * div / 2) / (rpm * div), 1,
+			     254);
+}
+
+#define TEMP_MIN (-128000)
+#define TEMP_MAX ( 127000)
+
+/* TEMP: 0.001C/bit (-128C to +127C)
+   REG: 1C/bit, two's complement */
+static u8 TEMP_TO_REG(int temp)
+{
+        int ntemp = SENSORS_LIMIT(temp, TEMP_MIN, TEMP_MAX);
+        ntemp += (ntemp<0 ? -500 : 500);
+        return (u8)(ntemp / 1000);
+}
+
+static int TEMP_FROM_REG(u8 reg)
+{
+        return (s8)reg * 1000;
+}
+
+#define FAN_FROM_REG(val,div) ((val)==0?-1:(val)==255?0:1350000/((val)*(div)))
+
+#define PWM_TO_REG(val) (SENSORS_LIMIT((val),0,255))
+
+#define BEEP_MASK_FROM_REG(val)		 (val)
+#define BEEP_MASK_TO_REG(val)		((val) & 0xffffff)
+#define BEEP_ENABLE_TO_REG(val)		((val)?1:0)
+#define BEEP_ENABLE_FROM_REG(val)	((val)?1:0)
+
+#define DIV_FROM_REG(val) (1 << (val))
+
+static inline u8 DIV_TO_REG(long val)
+{
+	int i;
+	val = SENSORS_LIMIT(val, 1, 128) >> 1;
+	for (i = 0; i < 7; i++) {
+		if (val == 0)
+			break;
+		val >>= 1;
+	}
+	return ((u8) i);
+}
+
+/* For each registered chip, we need to keep some data in memory. That
+   data is pointed to by w83627hf_list[NR]->data. The structure itself is
+   dynamically allocated, at the same time when a new client is allocated. */
+struct w83627hf_data {
+	struct i2c_client client;
+	struct semaphore lock;
+	enum chips type;
+
+	struct semaphore update_lock;
+	char valid;		/* !=0 if following fields are valid */
+	unsigned long last_updated;	/* In jiffies */
+
+	struct i2c_client *lm75;	/* for secondary I2C addresses */
+	/* pointer to array of 2 subclients */
+
+	u8 in[9];		/* Register value */
+	u8 in_max[9];		/* Register value */
+	u8 in_min[9];		/* Register value */
+	u8 fan[3];		/* Register value */
+	u8 fan_min[3];		/* Register value */
+	u8 temp;
+	u8 temp_max;		/* Register value */
+	u8 temp_max_hyst;	/* Register value */
+	u16 temp_add[2];	/* Register value */
+	u16 temp_max_add[2];	/* Register value */
+	u16 temp_max_hyst_add[2]; /* Register value */
+	u8 fan_div[3];		/* Register encoding, shifted right */
+	u8 vid;			/* Register encoding, combined */
+	u32 alarms;		/* Register encoding, combined */
+	u32 beep_mask;		/* Register encoding, combined */
+	u8 beep_enable;		/* Boolean */
+	u8 pwm[3];		/* Register value */
+	u16 sens[3];		/* 782D/783S only.
+				   1 = pentium diode; 2 = 3904 diode;
+				   3000-5000 = thermistor beta.
+				   Default = 3435.
+				   Other Betas unimplemented */
+	u8 vrm;
+	u8 vrm_ovt;		/* Register value, 627thf & 637hf only */
+};
+
+
+static int w83627hf_attach_adapter(struct i2c_adapter *adapter);
+static int w83627hf_detect(struct i2c_adapter *adapter, int address,
+			  int kind);
+static int w83627hf_detach_client(struct i2c_client *client);
+
+static int w83627hf_read_value(struct i2c_client *client, u16 register);
+static int w83627hf_write_value(struct i2c_client *client, u16 register,
+			       u16 value);
+static struct w83627hf_data *w83627hf_update_device(struct device *dev);
+static void w83627hf_init_client(struct i2c_client *client);
+
+static struct i2c_driver w83627hf_driver = {
+	.owner		= THIS_MODULE,
+	.name		= "w83627hf",
+	.id		= I2C_DRIVERID_W83627HF,
+	.flags		= I2C_DF_NOTIFY,
+	.attach_adapter	= w83627hf_attach_adapter,
+	.detach_client	= w83627hf_detach_client,
+};
+
+/* following are the sysfs callback functions */
+#define show_in_reg(reg) \
+static ssize_t show_##reg (struct device *dev, char *buf, int nr) \
+{ \
+	struct w83627hf_data *data = w83627hf_update_device(dev); \
+	return sprintf(buf,"%ld\n", (long)IN_FROM_REG(data->reg[nr])); \
+}
+show_in_reg(in)
+show_in_reg(in_min)
+show_in_reg(in_max)
+
+#define store_in_reg(REG, reg) \
+static ssize_t \
+store_in_##reg (struct device *dev, const char *buf, size_t count, int nr) \
+{ \
+	struct i2c_client *client = to_i2c_client(dev); \
+	struct w83627hf_data *data = i2c_get_clientdata(client); \
+	u32 val; \
+	 \
+	val = simple_strtoul(buf, NULL, 10); \
+	 \
+	down(&data->update_lock); \
+	data->in_##reg[nr] = IN_TO_REG(val); \
+	w83627hf_write_value(client, W83781D_REG_IN_##REG(nr), \
+			    data->in_##reg[nr]); \
+	 \
+	up(&data->update_lock); \
+	return count; \
+}
+store_in_reg(MIN, min)
+store_in_reg(MAX, max)
+
+#define sysfs_in_offset(offset) \
+static ssize_t \
+show_regs_in_##offset (struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+        return show_in(dev, buf, offset); \
+} \
+static DEVICE_ATTR(in##offset##_input, S_IRUGO, show_regs_in_##offset, NULL);
+
+#define sysfs_in_reg_offset(reg, offset) \
+static ssize_t show_regs_in_##reg##offset (struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+	return show_in_##reg (dev, buf, offset); \
+} \
+static ssize_t \
+store_regs_in_##reg##offset (struct device *dev, struct device_attribute *attr, \
+			    const char *buf, size_t count) \
+{ \
+	return store_in_##reg (dev, buf, count, offset); \
+} \
+static DEVICE_ATTR(in##offset##_##reg, S_IRUGO| S_IWUSR, \
+		  show_regs_in_##reg##offset, store_regs_in_##reg##offset);
+
+#define sysfs_in_offsets(offset) \
+sysfs_in_offset(offset) \
+sysfs_in_reg_offset(min, offset) \
+sysfs_in_reg_offset(max, offset)
+
+sysfs_in_offsets(1);
+sysfs_in_offsets(2);
+sysfs_in_offsets(3);
+sysfs_in_offsets(4);
+sysfs_in_offsets(5);
+sysfs_in_offsets(6);
+sysfs_in_offsets(7);
+sysfs_in_offsets(8);
+
+/* use a different set of functions for in0 */
+static ssize_t show_in_0(struct w83627hf_data *data, char *buf, u8 reg)
+{
+	long in0;
+
+	if ((data->vrm_ovt & 0x01) &&
+		(w83627thf == data->type || w83637hf == data->type))
+
+		/* use VRM9 calculation */
+		in0 = (long)((reg * 488 + 70000 + 50) / 100);
+	else
+		/* use VRM8 (standard) calculation */
+		in0 = (long)IN_FROM_REG(reg);
+
+	return sprintf(buf,"%ld\n", in0);
+}
+
+static ssize_t show_regs_in_0(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct w83627hf_data *data = w83627hf_update_device(dev);
+	return show_in_0(data, buf, data->in[0]);
+}
+
+static ssize_t show_regs_in_min0(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct w83627hf_data *data = w83627hf_update_device(dev);
+	return show_in_0(data, buf, data->in_min[0]);
+}
+
+static ssize_t show_regs_in_max0(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct w83627hf_data *data = w83627hf_update_device(dev);
+	return show_in_0(data, buf, data->in_max[0]);
+}
+
+static ssize_t store_regs_in_min0(struct device *dev, struct device_attribute *attr,
+	const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct w83627hf_data *data = i2c_get_clientdata(client);
+	u32 val;
+
+	val = simple_strtoul(buf, NULL, 10);
+
+	down(&data->update_lock);
+	
+	if ((data->vrm_ovt & 0x01) &&
+		(w83627thf == data->type || w83637hf == data->type))
+
+		/* use VRM9 calculation */
+		data->in_min[0] = (u8)(((val * 100) - 70000 + 244) / 488);
+	else
+		/* use VRM8 (standard) calculation */
+		data->in_min[0] = IN_TO_REG(val);
+
+	w83627hf_write_value(client, W83781D_REG_IN_MIN(0), data->in_min[0]);
+	up(&data->update_lock);
+	return count;
+}
+
+static ssize_t store_regs_in_max0(struct device *dev, struct device_attribute *attr,
+	const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct w83627hf_data *data = i2c_get_clientdata(client);
+	u32 val;
+
+	val = simple_strtoul(buf, NULL, 10);
+
+	down(&data->update_lock);
+
+	if ((data->vrm_ovt & 0x01) &&
+		(w83627thf == data->type || w83637hf == data->type))
+		
+		/* use VRM9 calculation */
+		data->in_max[0] = (u8)(((val * 100) - 70000 + 244) / 488);
+	else
+		/* use VRM8 (standard) calculation */
+		data->in_max[0] = IN_TO_REG(val);
+
+	w83627hf_write_value(client, W83781D_REG_IN_MAX(0), data->in_max[0]);
+	up(&data->update_lock);
+	return count;
+}
+
+static DEVICE_ATTR(in0_input, S_IRUGO, show_regs_in_0, NULL);
+static DEVICE_ATTR(in0_min, S_IRUGO | S_IWUSR,
+	show_regs_in_min0, store_regs_in_min0);
+static DEVICE_ATTR(in0_max, S_IRUGO | S_IWUSR,
+	show_regs_in_max0, store_regs_in_max0);
+
+#define device_create_file_in(client, offset) \
+do { \
+device_create_file(&client->dev, &dev_attr_in##offset##_input); \
+device_create_file(&client->dev, &dev_attr_in##offset##_min); \
+device_create_file(&client->dev, &dev_attr_in##offset##_max); \
+} while (0)
+
+#define show_fan_reg(reg) \
+static ssize_t show_##reg (struct device *dev, char *buf, int nr) \
+{ \
+	struct w83627hf_data *data = w83627hf_update_device(dev); \
+	return sprintf(buf,"%ld\n", \
+		FAN_FROM_REG(data->reg[nr-1], \
+			    (long)DIV_FROM_REG(data->fan_div[nr-1]))); \
+}
+show_fan_reg(fan);
+show_fan_reg(fan_min);
+
+static ssize_t
+store_fan_min(struct device *dev, const char *buf, size_t count, int nr)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct w83627hf_data *data = i2c_get_clientdata(client);
+	u32 val;
+
+	val = simple_strtoul(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->fan_min[nr - 1] =
+	    FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr - 1]));
+	w83627hf_write_value(client, W83781D_REG_FAN_MIN(nr),
+			    data->fan_min[nr - 1]);
+
+	up(&data->update_lock);
+	return count;
+}
+
+#define sysfs_fan_offset(offset) \
+static ssize_t show_regs_fan_##offset (struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+	return show_fan(dev, buf, offset); \
+} \
+static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_regs_fan_##offset, NULL);
+
+#define sysfs_fan_min_offset(offset) \
+static ssize_t show_regs_fan_min##offset (struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+	return show_fan_min(dev, buf, offset); \
+} \
+static ssize_t \
+store_regs_fan_min##offset (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \
+{ \
+	return store_fan_min(dev, buf, count, offset); \
+} \
+static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \
+		  show_regs_fan_min##offset, store_regs_fan_min##offset);
+
+sysfs_fan_offset(1);
+sysfs_fan_min_offset(1);
+sysfs_fan_offset(2);
+sysfs_fan_min_offset(2);
+sysfs_fan_offset(3);
+sysfs_fan_min_offset(3);
+
+#define device_create_file_fan(client, offset) \
+do { \
+device_create_file(&client->dev, &dev_attr_fan##offset##_input); \
+device_create_file(&client->dev, &dev_attr_fan##offset##_min); \
+} while (0)
+
+#define show_temp_reg(reg) \
+static ssize_t show_##reg (struct device *dev, char *buf, int nr) \
+{ \
+	struct w83627hf_data *data = w83627hf_update_device(dev); \
+	if (nr >= 2) {	/* TEMP2 and TEMP3 */ \
+		return sprintf(buf,"%ld\n", \
+			(long)LM75_TEMP_FROM_REG(data->reg##_add[nr-2])); \
+	} else {	/* TEMP1 */ \
+		return sprintf(buf,"%ld\n", (long)TEMP_FROM_REG(data->reg)); \
+	} \
+}
+show_temp_reg(temp);
+show_temp_reg(temp_max);
+show_temp_reg(temp_max_hyst);
+
+#define store_temp_reg(REG, reg) \
+static ssize_t \
+store_temp_##reg (struct device *dev, const char *buf, size_t count, int nr) \
+{ \
+	struct i2c_client *client = to_i2c_client(dev); \
+	struct w83627hf_data *data = i2c_get_clientdata(client); \
+	u32 val; \
+	 \
+	val = simple_strtoul(buf, NULL, 10); \
+	 \
+	down(&data->update_lock); \
+	 \
+	if (nr >= 2) {	/* TEMP2 and TEMP3 */ \
+		data->temp_##reg##_add[nr-2] = LM75_TEMP_TO_REG(val); \
+		w83627hf_write_value(client, W83781D_REG_TEMP_##REG(nr), \
+				data->temp_##reg##_add[nr-2]); \
+	} else {	/* TEMP1 */ \
+		data->temp_##reg = TEMP_TO_REG(val); \
+		w83627hf_write_value(client, W83781D_REG_TEMP_##REG(nr), \
+			data->temp_##reg); \
+	} \
+	 \
+	up(&data->update_lock); \
+	return count; \
+}
+store_temp_reg(OVER, max);
+store_temp_reg(HYST, max_hyst);
+
+#define sysfs_temp_offset(offset) \
+static ssize_t \
+show_regs_temp_##offset (struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+	return show_temp(dev, buf, offset); \
+} \
+static DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_regs_temp_##offset, NULL);
+
+#define sysfs_temp_reg_offset(reg, offset) \
+static ssize_t show_regs_temp_##reg##offset (struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+	return show_temp_##reg (dev, buf, offset); \
+} \
+static ssize_t \
+store_regs_temp_##reg##offset (struct device *dev, struct device_attribute *attr, \
+			      const char *buf, size_t count) \
+{ \
+	return store_temp_##reg (dev, buf, count, offset); \
+} \
+static DEVICE_ATTR(temp##offset##_##reg, S_IRUGO| S_IWUSR, \
+		  show_regs_temp_##reg##offset, store_regs_temp_##reg##offset);
+
+#define sysfs_temp_offsets(offset) \
+sysfs_temp_offset(offset) \
+sysfs_temp_reg_offset(max, offset) \
+sysfs_temp_reg_offset(max_hyst, offset)
+
+sysfs_temp_offsets(1);
+sysfs_temp_offsets(2);
+sysfs_temp_offsets(3);
+
+#define device_create_file_temp(client, offset) \
+do { \
+device_create_file(&client->dev, &dev_attr_temp##offset##_input); \
+device_create_file(&client->dev, &dev_attr_temp##offset##_max); \
+device_create_file(&client->dev, &dev_attr_temp##offset##_max_hyst); \
+} while (0)
+
+static ssize_t
+show_vid_reg(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct w83627hf_data *data = w83627hf_update_device(dev);
+	return sprintf(buf, "%ld\n", (long) vid_from_reg(data->vid, data->vrm));
+}
+static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid_reg, NULL);
+#define device_create_file_vid(client) \
+device_create_file(&client->dev, &dev_attr_cpu0_vid)
+
+static ssize_t
+show_vrm_reg(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct w83627hf_data *data = w83627hf_update_device(dev);
+	return sprintf(buf, "%ld\n", (long) data->vrm);
+}
+static ssize_t
+store_vrm_reg(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct w83627hf_data *data = i2c_get_clientdata(client);
+	u32 val;
+
+	val = simple_strtoul(buf, NULL, 10);
+	data->vrm = val;
+
+	return count;
+}
+static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg);
+#define device_create_file_vrm(client) \
+device_create_file(&client->dev, &dev_attr_vrm)
+
+static ssize_t
+show_alarms_reg(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct w83627hf_data *data = w83627hf_update_device(dev);
+	return sprintf(buf, "%ld\n", (long) data->alarms);
+}
+static DEVICE_ATTR(alarms, S_IRUGO, show_alarms_reg, NULL);
+#define device_create_file_alarms(client) \
+device_create_file(&client->dev, &dev_attr_alarms)
+
+#define show_beep_reg(REG, reg) \
+static ssize_t show_beep_##reg (struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+	struct w83627hf_data *data = w83627hf_update_device(dev); \
+	return sprintf(buf,"%ld\n", \
+		      (long)BEEP_##REG##_FROM_REG(data->beep_##reg)); \
+}
+show_beep_reg(ENABLE, enable)
+show_beep_reg(MASK, mask)
+
+#define BEEP_ENABLE			0	/* Store beep_enable */
+#define BEEP_MASK			1	/* Store beep_mask */
+
+static ssize_t
+store_beep_reg(struct device *dev, const char *buf, size_t count,
+	       int update_mask)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct w83627hf_data *data = i2c_get_clientdata(client);
+	u32 val, val2;
+
+	val = simple_strtoul(buf, NULL, 10);
+
+	down(&data->update_lock);
+
+	if (update_mask == BEEP_MASK) {	/* We are storing beep_mask */
+		data->beep_mask = BEEP_MASK_TO_REG(val);
+		w83627hf_write_value(client, W83781D_REG_BEEP_INTS1,
+				    data->beep_mask & 0xff);
+		w83627hf_write_value(client, W83781D_REG_BEEP_INTS3,
+				    ((data->beep_mask) >> 16) & 0xff);
+		val2 = (data->beep_mask >> 8) & 0x7f;
+	} else {		/* We are storing beep_enable */
+		val2 =
+		    w83627hf_read_value(client, W83781D_REG_BEEP_INTS2) & 0x7f;
+		data->beep_enable = BEEP_ENABLE_TO_REG(val);
+	}
+
+	w83627hf_write_value(client, W83781D_REG_BEEP_INTS2,
+			    val2 | data->beep_enable << 7);
+
+	up(&data->update_lock);
+	return count;
+}
+
+#define sysfs_beep(REG, reg) \
+static ssize_t show_regs_beep_##reg (struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+	return show_beep_##reg(dev, attr, buf); \
+} \
+static ssize_t \
+store_regs_beep_##reg (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \
+{ \
+	return store_beep_reg(dev, buf, count, BEEP_##REG); \
+} \
+static DEVICE_ATTR(beep_##reg, S_IRUGO | S_IWUSR, \
+		  show_regs_beep_##reg, store_regs_beep_##reg);
+
+sysfs_beep(ENABLE, enable);
+sysfs_beep(MASK, mask);
+
+#define device_create_file_beep(client) \
+do { \
+device_create_file(&client->dev, &dev_attr_beep_enable); \
+device_create_file(&client->dev, &dev_attr_beep_mask); \
+} while (0)
+
+static ssize_t
+show_fan_div_reg(struct device *dev, char *buf, int nr)
+{
+	struct w83627hf_data *data = w83627hf_update_device(dev);
+	return sprintf(buf, "%ld\n",
+		       (long) DIV_FROM_REG(data->fan_div[nr - 1]));
+}
+
+/* Note: we save and restore the fan minimum here, because its value is
+   determined in part by the fan divisor.  This follows the principle of
+   least suprise; the user doesn't expect the fan minimum to change just
+   because the divisor changed. */
+static ssize_t
+store_fan_div_reg(struct device *dev, const char *buf, size_t count, int nr)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct w83627hf_data *data = i2c_get_clientdata(client);
+	unsigned long min;
+	u8 reg;
+	unsigned long val = simple_strtoul(buf, NULL, 10);
+
+	down(&data->update_lock);
+
+	/* Save fan_min */
+	min = FAN_FROM_REG(data->fan_min[nr],
+			   DIV_FROM_REG(data->fan_div[nr]));
+
+	data->fan_div[nr] = DIV_TO_REG(val);
+
+	reg = (w83627hf_read_value(client, nr==2 ? W83781D_REG_PIN : W83781D_REG_VID_FANDIV)
+	       & (nr==0 ? 0xcf : 0x3f))
+	    | ((data->fan_div[nr] & 0x03) << (nr==0 ? 4 : 6));
+	w83627hf_write_value(client, nr==2 ? W83781D_REG_PIN : W83781D_REG_VID_FANDIV, reg);
+
+	reg = (w83627hf_read_value(client, W83781D_REG_VBAT)
+	       & ~(1 << (5 + nr)))
+	    | ((data->fan_div[nr] & 0x04) << (3 + nr));
+	w83627hf_write_value(client, W83781D_REG_VBAT, reg);
+
+	/* Restore fan_min */
+	data->fan_min[nr] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr]));
+	w83627hf_write_value(client, W83781D_REG_FAN_MIN(nr+1), data->fan_min[nr]);
+
+	up(&data->update_lock);
+	return count;
+}
+
+#define sysfs_fan_div(offset) \
+static ssize_t show_regs_fan_div_##offset (struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+	return show_fan_div_reg(dev, buf, offset); \
+} \
+static ssize_t \
+store_regs_fan_div_##offset (struct device *dev, struct device_attribute *attr, \
+			    const char *buf, size_t count) \
+{ \
+	return store_fan_div_reg(dev, buf, count, offset - 1); \
+} \
+static DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, \
+		  show_regs_fan_div_##offset, store_regs_fan_div_##offset);
+
+sysfs_fan_div(1);
+sysfs_fan_div(2);
+sysfs_fan_div(3);
+
+#define device_create_file_fan_div(client, offset) \
+do { \
+device_create_file(&client->dev, &dev_attr_fan##offset##_div); \
+} while (0)
+
+static ssize_t
+show_pwm_reg(struct device *dev, char *buf, int nr)
+{
+	struct w83627hf_data *data = w83627hf_update_device(dev);
+	return sprintf(buf, "%ld\n", (long) data->pwm[nr - 1]);
+}
+
+static ssize_t
+store_pwm_reg(struct device *dev, const char *buf, size_t count, int nr)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct w83627hf_data *data = i2c_get_clientdata(client);
+	u32 val;
+
+	val = simple_strtoul(buf, NULL, 10);
+
+	down(&data->update_lock);
+
+	if (data->type == w83627thf) {
+		/* bits 0-3 are reserved  in 627THF */
+		data->pwm[nr - 1] = PWM_TO_REG(val) & 0xf0;
+		w83627hf_write_value(client,
+				     W836X7HF_REG_PWM(data->type, nr),
+				     data->pwm[nr - 1] |
+				     (w83627hf_read_value(client,
+				     W836X7HF_REG_PWM(data->type, nr)) & 0x0f));
+	} else {
+		data->pwm[nr - 1] = PWM_TO_REG(val);
+		w83627hf_write_value(client,
+				     W836X7HF_REG_PWM(data->type, nr),
+				     data->pwm[nr - 1]);
+	}
+
+	up(&data->update_lock);
+	return count;
+}
+
+#define sysfs_pwm(offset) \
+static ssize_t show_regs_pwm_##offset (struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+	return show_pwm_reg(dev, buf, offset); \
+} \
+static ssize_t \
+store_regs_pwm_##offset (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \
+{ \
+	return store_pwm_reg(dev, buf, count, offset); \
+} \
+static DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR, \
+		  show_regs_pwm_##offset, store_regs_pwm_##offset);
+
+sysfs_pwm(1);
+sysfs_pwm(2);
+sysfs_pwm(3);
+
+#define device_create_file_pwm(client, offset) \
+do { \
+device_create_file(&client->dev, &dev_attr_pwm##offset); \
+} while (0)
+
+static ssize_t
+show_sensor_reg(struct device *dev, char *buf, int nr)
+{
+	struct w83627hf_data *data = w83627hf_update_device(dev);
+	return sprintf(buf, "%ld\n", (long) data->sens[nr - 1]);
+}
+
+static ssize_t
+store_sensor_reg(struct device *dev, const char *buf, size_t count, int nr)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct w83627hf_data *data = i2c_get_clientdata(client);
+	u32 val, tmp;
+
+	val = simple_strtoul(buf, NULL, 10);
+
+	down(&data->update_lock);
+
+	switch (val) {
+	case 1:		/* PII/Celeron diode */
+		tmp = w83627hf_read_value(client, W83781D_REG_SCFG1);
+		w83627hf_write_value(client, W83781D_REG_SCFG1,
+				    tmp | BIT_SCFG1[nr - 1]);
+		tmp = w83627hf_read_value(client, W83781D_REG_SCFG2);
+		w83627hf_write_value(client, W83781D_REG_SCFG2,
+				    tmp | BIT_SCFG2[nr - 1]);
+		data->sens[nr - 1] = val;
+		break;
+	case 2:		/* 3904 */
+		tmp = w83627hf_read_value(client, W83781D_REG_SCFG1);
+		w83627hf_write_value(client, W83781D_REG_SCFG1,
+				    tmp | BIT_SCFG1[nr - 1]);
+		tmp = w83627hf_read_value(client, W83781D_REG_SCFG2);
+		w83627hf_write_value(client, W83781D_REG_SCFG2,
+				    tmp & ~BIT_SCFG2[nr - 1]);
+		data->sens[nr - 1] = val;
+		break;
+	case W83781D_DEFAULT_BETA:	/* thermistor */
+		tmp = w83627hf_read_value(client, W83781D_REG_SCFG1);
+		w83627hf_write_value(client, W83781D_REG_SCFG1,
+				    tmp & ~BIT_SCFG1[nr - 1]);
+		data->sens[nr - 1] = val;
+		break;
+	default:
+		dev_err(&client->dev,
+		       "Invalid sensor type %ld; must be 1, 2, or %d\n",
+		       (long) val, W83781D_DEFAULT_BETA);
+		break;
+	}
+
+	up(&data->update_lock);
+	return count;
+}
+
+#define sysfs_sensor(offset) \
+static ssize_t show_regs_sensor_##offset (struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+    return show_sensor_reg(dev, buf, offset); \
+} \
+static ssize_t \
+store_regs_sensor_##offset (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \
+{ \
+    return store_sensor_reg(dev, buf, count, offset); \
+} \
+static DEVICE_ATTR(temp##offset##_type, S_IRUGO | S_IWUSR, \
+		  show_regs_sensor_##offset, store_regs_sensor_##offset);
+
+sysfs_sensor(1);
+sysfs_sensor(2);
+sysfs_sensor(3);
+
+#define device_create_file_sensor(client, offset) \
+do { \
+device_create_file(&client->dev, &dev_attr_temp##offset##_type); \
+} while (0)
+
+
+/* This function is called when:
+     * w83627hf_driver is inserted (when this module is loaded), for each
+       available adapter
+     * when a new adapter is inserted (and w83627hf_driver is still present) */
+static int w83627hf_attach_adapter(struct i2c_adapter *adapter)
+{
+	return i2c_detect(adapter, &addr_data, w83627hf_detect);
+}
+
+static int w83627hf_find(int sioaddr, int *address)
+{
+	u16 val;
+
+	REG = sioaddr;
+	VAL = sioaddr + 1;
+
+	superio_enter();
+	val= superio_inb(DEVID);
+	if(val != W627_DEVID &&
+	   val != W627THF_DEVID &&
+	   val != W697_DEVID &&
+	   val != W637_DEVID) {
+		superio_exit();
+		return -ENODEV;
+	}
+
+	superio_select(W83627HF_LD_HWM);
+	val = (superio_inb(WINB_BASE_REG) << 8) |
+	       superio_inb(WINB_BASE_REG + 1);
+	*address = val & ~(WINB_EXTENT - 1);
+	if (*address == 0 && force_addr == 0) {
+		superio_exit();
+		return -ENODEV;
+	}
+	if (force_addr)
+		*address = force_addr;	/* so detect will get called */
+
+	superio_exit();
+	return 0;
+}
+
+int w83627hf_detect(struct i2c_adapter *adapter, int address,
+		   int kind)
+{
+	int val;
+	struct i2c_client *new_client;
+	struct w83627hf_data *data;
+	int err = 0;
+	const char *client_name = "";
+
+	if (!i2c_is_isa_adapter(adapter)) {
+		err = -ENODEV;
+		goto ERROR0;
+	}
+
+	if(force_addr)
+		address = force_addr & ~(WINB_EXTENT - 1);
+
+	if (!request_region(address, WINB_EXTENT, w83627hf_driver.name)) {
+		err = -EBUSY;
+		goto ERROR0;
+	}
+
+	if(force_addr) {
+		printk("w83627hf.o: forcing ISA address 0x%04X\n", address);
+		superio_enter();
+		superio_select(W83627HF_LD_HWM);
+		superio_outb(WINB_BASE_REG, address >> 8);
+		superio_outb(WINB_BASE_REG+1, address & 0xff);
+		superio_exit();
+	}
+
+	superio_enter();
+	val= superio_inb(DEVID);
+	if(val == W627_DEVID)
+		kind = w83627hf;
+	else if(val == W697_DEVID)
+		kind = w83697hf;
+	else if(val == W627THF_DEVID)
+		kind = w83627thf;
+	else if(val == W637_DEVID)
+		kind = w83637hf;
+	else {
+		dev_info(&adapter->dev,
+			 "Unsupported chip (dev_id=0x%02X).\n", val);
+		goto ERROR1;
+	}
+
+	superio_select(W83627HF_LD_HWM);
+	if((val = 0x01 & superio_inb(WINB_ACT_REG)) == 0)
+		superio_outb(WINB_ACT_REG, 1);
+	superio_exit();
+
+	/* OK. For now, we presume we have a valid client. We now create the
+	   client structure, even though we cannot fill it completely yet.
+	   But it allows us to access w83627hf_{read,write}_value. */
+
+	if (!(data = kmalloc(sizeof(struct w83627hf_data), GFP_KERNEL))) {
+		err = -ENOMEM;
+		goto ERROR1;
+	}
+	memset(data, 0, sizeof(struct w83627hf_data));
+
+	new_client = &data->client;
+	i2c_set_clientdata(new_client, data);
+	new_client->addr = address;
+	init_MUTEX(&data->lock);
+	new_client->adapter = adapter;
+	new_client->driver = &w83627hf_driver;
+	new_client->flags = 0;
+
+
+	if (kind == w83627hf) {
+		client_name = "w83627hf";
+	} else if (kind == w83627thf) {
+		client_name = "w83627thf";
+	} else if (kind == w83697hf) {
+		client_name = "w83697hf";
+	} else if (kind == w83637hf) {
+		client_name = "w83637hf";
+	}
+
+	/* Fill in the remaining client fields and put into the global list */
+	strlcpy(new_client->name, client_name, I2C_NAME_SIZE);
+	data->type = kind;
+	data->valid = 0;
+	init_MUTEX(&data->update_lock);
+
+	/* Tell the I2C layer a new client has arrived */
+	if ((err = i2c_attach_client(new_client)))
+		goto ERROR2;
+
+	data->lm75 = NULL;
+
+	/* Initialize the chip */
+	w83627hf_init_client(new_client);
+
+	/* A few vars need to be filled upon startup */
+	data->fan_min[0] = w83627hf_read_value(new_client, W83781D_REG_FAN_MIN(1));
+	data->fan_min[1] = w83627hf_read_value(new_client, W83781D_REG_FAN_MIN(2));
+	data->fan_min[2] = w83627hf_read_value(new_client, W83781D_REG_FAN_MIN(3));
+
+	/* Register sysfs hooks */
+	device_create_file_in(new_client, 0);
+	if (kind != w83697hf)
+		device_create_file_in(new_client, 1);
+	device_create_file_in(new_client, 2);
+	device_create_file_in(new_client, 3);
+	device_create_file_in(new_client, 4);
+	if (kind != w83627thf && kind != w83637hf) {
+		device_create_file_in(new_client, 5);
+		device_create_file_in(new_client, 6);
+	}
+	device_create_file_in(new_client, 7);
+	device_create_file_in(new_client, 8);
+
+	device_create_file_fan(new_client, 1);
+	device_create_file_fan(new_client, 2);
+	if (kind != w83697hf)
+		device_create_file_fan(new_client, 3);
+
+	device_create_file_temp(new_client, 1);
+	device_create_file_temp(new_client, 2);
+	if (kind != w83697hf)
+		device_create_file_temp(new_client, 3);
+
+	if (kind != w83697hf)
+		device_create_file_vid(new_client);
+
+	if (kind != w83697hf)
+		device_create_file_vrm(new_client);
+
+	device_create_file_fan_div(new_client, 1);
+	device_create_file_fan_div(new_client, 2);
+	if (kind != w83697hf)
+		device_create_file_fan_div(new_client, 3);
+
+	device_create_file_alarms(new_client);
+
+	device_create_file_beep(new_client);
+
+	device_create_file_pwm(new_client, 1);
+	device_create_file_pwm(new_client, 2);
+	if (kind == w83627thf || kind == w83637hf)
+		device_create_file_pwm(new_client, 3);
+
+	device_create_file_sensor(new_client, 1);
+	device_create_file_sensor(new_client, 2);
+	if (kind != w83697hf)
+		device_create_file_sensor(new_client, 3);
+
+	return 0;
+
+      ERROR2:
+	kfree(data);
+      ERROR1:
+	release_region(address, WINB_EXTENT);
+      ERROR0:
+	return err;
+}
+
+static int w83627hf_detach_client(struct i2c_client *client)
+{
+	int err;
+
+	if ((err = i2c_detach_client(client))) {
+		dev_err(&client->dev,
+		       "Client deregistration failed, client not detached.\n");
+		return err;
+	}
+
+	release_region(client->addr, WINB_EXTENT);
+	kfree(i2c_get_clientdata(client));
+
+	return 0;
+}
+
+
+/*
+   ISA access must always be locked explicitly!
+   We ignore the W83781D BUSY flag at this moment - it could lead to deadlocks,
+   would slow down the W83781D access and should not be necessary.
+   There are some ugly typecasts here, but the good news is - they should
+   nowhere else be necessary! */
+static int w83627hf_read_value(struct i2c_client *client, u16 reg)
+{
+	struct w83627hf_data *data = i2c_get_clientdata(client);
+	int res, word_sized;
+
+	down(&data->lock);
+	word_sized = (((reg & 0xff00) == 0x100)
+		   || ((reg & 0xff00) == 0x200))
+		  && (((reg & 0x00ff) == 0x50)
+		   || ((reg & 0x00ff) == 0x53)
+		   || ((reg & 0x00ff) == 0x55));
+	if (reg & 0xff00) {
+		outb_p(W83781D_REG_BANK,
+		       client->addr + W83781D_ADDR_REG_OFFSET);
+		outb_p(reg >> 8,
+		       client->addr + W83781D_DATA_REG_OFFSET);
+	}
+	outb_p(reg & 0xff, client->addr + W83781D_ADDR_REG_OFFSET);
+	res = inb_p(client->addr + W83781D_DATA_REG_OFFSET);
+	if (word_sized) {
+		outb_p((reg & 0xff) + 1,
+		       client->addr + W83781D_ADDR_REG_OFFSET);
+		res =
+		    (res << 8) + inb_p(client->addr +
+				       W83781D_DATA_REG_OFFSET);
+	}
+	if (reg & 0xff00) {
+		outb_p(W83781D_REG_BANK,
+		       client->addr + W83781D_ADDR_REG_OFFSET);
+		outb_p(0, client->addr + W83781D_DATA_REG_OFFSET);
+	}
+	up(&data->lock);
+	return res;
+}
+
+static int w83627thf_read_gpio5(struct i2c_client *client)
+{
+	int res = 0xff, sel;
+
+	superio_enter();
+	superio_select(W83627HF_LD_GPIO5);
+
+	/* Make sure these GPIO pins are enabled */
+	if (!(superio_inb(W83627THF_GPIO5_EN) & (1<<3))) {
+		dev_dbg(&client->dev, "GPIO5 disabled, no VID function\n");
+		goto exit;
+	}
+
+	/* Make sure the pins are configured for input
+	   There must be at least five (VRM 9), and possibly 6 (VRM 10) */
+	sel = superio_inb(W83627THF_GPIO5_IOSR);
+	if ((sel & 0x1f) != 0x1f) {
+		dev_dbg(&client->dev, "GPIO5 not configured for VID "
+			"function\n");
+		goto exit;
+	}
+
+	dev_info(&client->dev, "Reading VID from GPIO5\n");
+	res = superio_inb(W83627THF_GPIO5_DR) & sel;
+
+exit:
+	superio_exit();
+	return res;
+}
+
+static int w83627hf_write_value(struct i2c_client *client, u16 reg, u16 value)
+{
+	struct w83627hf_data *data = i2c_get_clientdata(client);
+	int word_sized;
+
+	down(&data->lock);
+	word_sized = (((reg & 0xff00) == 0x100)
+		   || ((reg & 0xff00) == 0x200))
+		  && (((reg & 0x00ff) == 0x53)
+		   || ((reg & 0x00ff) == 0x55));
+	if (reg & 0xff00) {
+		outb_p(W83781D_REG_BANK,
+		       client->addr + W83781D_ADDR_REG_OFFSET);
+		outb_p(reg >> 8,
+		       client->addr + W83781D_DATA_REG_OFFSET);
+	}
+	outb_p(reg & 0xff, client->addr + W83781D_ADDR_REG_OFFSET);
+	if (word_sized) {
+		outb_p(value >> 8,
+		       client->addr + W83781D_DATA_REG_OFFSET);
+		outb_p((reg & 0xff) + 1,
+		       client->addr + W83781D_ADDR_REG_OFFSET);
+	}
+	outb_p(value & 0xff,
+	       client->addr + W83781D_DATA_REG_OFFSET);
+	if (reg & 0xff00) {
+		outb_p(W83781D_REG_BANK,
+		       client->addr + W83781D_ADDR_REG_OFFSET);
+		outb_p(0, client->addr + W83781D_DATA_REG_OFFSET);
+	}
+	up(&data->lock);
+	return 0;
+}
+
+/* Called when we have found a new W83781D. It should set limits, etc. */
+static void w83627hf_init_client(struct i2c_client *client)
+{
+	struct w83627hf_data *data = i2c_get_clientdata(client);
+	int i;
+	int type = data->type;
+	u8 tmp;
+
+	if(init) {
+		/* save this register */
+		i = w83627hf_read_value(client, W83781D_REG_BEEP_CONFIG);
+		/* Reset all except Watchdog values and last conversion values
+		   This sets fan-divs to 2, among others */
+		w83627hf_write_value(client, W83781D_REG_CONFIG, 0x80);
+		/* Restore the register and disable power-on abnormal beep.
+		   This saves FAN 1/2/3 input/output values set by BIOS. */
+		w83627hf_write_value(client, W83781D_REG_BEEP_CONFIG, i | 0x80);
+		/* Disable master beep-enable (reset turns it on).
+		   Individual beeps should be reset to off but for some reason
+		   disabling this bit helps some people not get beeped */
+		w83627hf_write_value(client, W83781D_REG_BEEP_INTS2, 0);
+	}
+
+	/* Minimize conflicts with other winbond i2c-only clients...  */
+	/* disable i2c subclients... how to disable main i2c client?? */
+	/* force i2c address to relatively uncommon address */
+	w83627hf_write_value(client, W83781D_REG_I2C_SUBADDR, 0x89);
+	w83627hf_write_value(client, W83781D_REG_I2C_ADDR, force_i2c);
+
+	/* Read VID only once */
+	if (w83627hf == data->type || w83637hf == data->type) {
+		int lo = w83627hf_read_value(client, W83781D_REG_VID_FANDIV);
+		int hi = w83627hf_read_value(client, W83781D_REG_CHIPID);
+		data->vid = (lo & 0x0f) | ((hi & 0x01) << 4);
+	} else if (w83627thf == data->type) {
+		data->vid = w83627thf_read_gpio5(client) & 0x3f;
+	}
+
+	/* Read VRM & OVT Config only once */
+	if (w83627thf == data->type || w83637hf == data->type) {
+		data->vrm_ovt = 
+			w83627hf_read_value(client, W83627THF_REG_VRM_OVT_CFG);
+		data->vrm = (data->vrm_ovt & 0x01) ? 90 : 82;
+	} else {
+		/* Convert VID to voltage based on default VRM */
+		data->vrm = i2c_which_vrm();
+	}
+
+	tmp = w83627hf_read_value(client, W83781D_REG_SCFG1);
+	for (i = 1; i <= 3; i++) {
+		if (!(tmp & BIT_SCFG1[i - 1])) {
+			data->sens[i - 1] = W83781D_DEFAULT_BETA;
+		} else {
+			if (w83627hf_read_value
+			    (client,
+			     W83781D_REG_SCFG2) & BIT_SCFG2[i - 1])
+				data->sens[i - 1] = 1;
+			else
+				data->sens[i - 1] = 2;
+		}
+		if ((type == w83697hf) && (i == 2))
+			break;
+	}
+
+	if(init) {
+		/* Enable temp2 */
+		tmp = w83627hf_read_value(client, W83781D_REG_TEMP2_CONFIG);
+		if (tmp & 0x01) {
+			dev_warn(&client->dev, "Enabling temp2, readings "
+				 "might not make sense\n");
+			w83627hf_write_value(client, W83781D_REG_TEMP2_CONFIG,
+				tmp & 0xfe);
+		}
+
+		/* Enable temp3 */
+		if (type != w83697hf) {
+			tmp = w83627hf_read_value(client,
+				W83781D_REG_TEMP3_CONFIG);
+			if (tmp & 0x01) {
+				dev_warn(&client->dev, "Enabling temp3, "
+					 "readings might not make sense\n");
+				w83627hf_write_value(client,
+					W83781D_REG_TEMP3_CONFIG, tmp & 0xfe);
+			}
+		}
+
+		if (type == w83627hf) {
+			/* enable PWM2 control (can't hurt since PWM reg
+		           should have been reset to 0xff) */
+			w83627hf_write_value(client, W83627HF_REG_PWMCLK12,
+					    0x19);
+		}
+		/* enable comparator mode for temp2 and temp3 so
+	           alarm indication will work correctly */
+		i = w83627hf_read_value(client, W83781D_REG_IRQ);
+		if (!(i & 0x40))
+			w83627hf_write_value(client, W83781D_REG_IRQ,
+					    i | 0x40);
+	}
+
+	/* Start monitoring */
+	w83627hf_write_value(client, W83781D_REG_CONFIG,
+			    (w83627hf_read_value(client,
+						W83781D_REG_CONFIG) & 0xf7)
+			    | 0x01);
+}
+
+static struct w83627hf_data *w83627hf_update_device(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct w83627hf_data *data = i2c_get_clientdata(client);
+	int i;
+
+	down(&data->update_lock);
+
+	if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
+	    || !data->valid) {
+		for (i = 0; i <= 8; i++) {
+			/* skip missing sensors */
+			if (((data->type == w83697hf) && (i == 1)) ||
+			    ((data->type == w83627thf || data->type == w83637hf)
+			    && (i == 4 || i == 5)))
+				continue;
+			data->in[i] =
+			    w83627hf_read_value(client, W83781D_REG_IN(i));
+			data->in_min[i] =
+			    w83627hf_read_value(client,
+					       W83781D_REG_IN_MIN(i));
+			data->in_max[i] =
+			    w83627hf_read_value(client,
+					       W83781D_REG_IN_MAX(i));
+		}
+		for (i = 1; i <= 3; i++) {
+			data->fan[i - 1] =
+			    w83627hf_read_value(client, W83781D_REG_FAN(i));
+			data->fan_min[i - 1] =
+			    w83627hf_read_value(client,
+					       W83781D_REG_FAN_MIN(i));
+		}
+		for (i = 1; i <= 3; i++) {
+			u8 tmp = w83627hf_read_value(client,
+				W836X7HF_REG_PWM(data->type, i));
+ 			/* bits 0-3 are reserved  in 627THF */
+ 			if (data->type == w83627thf)
+				tmp &= 0xf0;
+			data->pwm[i - 1] = tmp;
+			if(i == 2 &&
+			   (data->type == w83627hf || data->type == w83697hf))
+				break;
+		}
+
+		data->temp = w83627hf_read_value(client, W83781D_REG_TEMP(1));
+		data->temp_max =
+		    w83627hf_read_value(client, W83781D_REG_TEMP_OVER(1));
+		data->temp_max_hyst =
+		    w83627hf_read_value(client, W83781D_REG_TEMP_HYST(1));
+		data->temp_add[0] =
+		    w83627hf_read_value(client, W83781D_REG_TEMP(2));
+		data->temp_max_add[0] =
+		    w83627hf_read_value(client, W83781D_REG_TEMP_OVER(2));
+		data->temp_max_hyst_add[0] =
+		    w83627hf_read_value(client, W83781D_REG_TEMP_HYST(2));
+		if (data->type != w83697hf) {
+			data->temp_add[1] =
+			  w83627hf_read_value(client, W83781D_REG_TEMP(3));
+			data->temp_max_add[1] =
+			  w83627hf_read_value(client, W83781D_REG_TEMP_OVER(3));
+			data->temp_max_hyst_add[1] =
+			  w83627hf_read_value(client, W83781D_REG_TEMP_HYST(3));
+		}
+
+		i = w83627hf_read_value(client, W83781D_REG_VID_FANDIV);
+		data->fan_div[0] = (i >> 4) & 0x03;
+		data->fan_div[1] = (i >> 6) & 0x03;
+		if (data->type != w83697hf) {
+			data->fan_div[2] = (w83627hf_read_value(client,
+					       W83781D_REG_PIN) >> 6) & 0x03;
+		}
+		i = w83627hf_read_value(client, W83781D_REG_VBAT);
+		data->fan_div[0] |= (i >> 3) & 0x04;
+		data->fan_div[1] |= (i >> 4) & 0x04;
+		if (data->type != w83697hf)
+			data->fan_div[2] |= (i >> 5) & 0x04;
+		data->alarms =
+		    w83627hf_read_value(client, W83781D_REG_ALARM1) |
+		    (w83627hf_read_value(client, W83781D_REG_ALARM2) << 8) |
+		    (w83627hf_read_value(client, W83781D_REG_ALARM3) << 16);
+		i = w83627hf_read_value(client, W83781D_REG_BEEP_INTS2);
+		data->beep_enable = i >> 7;
+		data->beep_mask = ((i & 0x7f) << 8) |
+		    w83627hf_read_value(client, W83781D_REG_BEEP_INTS1) |
+		    w83627hf_read_value(client, W83781D_REG_BEEP_INTS3) << 16;
+		data->last_updated = jiffies;
+		data->valid = 1;
+	}
+
+	up(&data->update_lock);
+
+	return data;
+}
+
+static int __init sensors_w83627hf_init(void)
+{
+	int addr;
+
+	if (w83627hf_find(0x2e, &addr)
+	 && w83627hf_find(0x4e, &addr)) {
+		return -ENODEV;
+	}
+	normal_isa[0] = addr;
+
+	return i2c_add_driver(&w83627hf_driver);
+}
+
+static void __exit sensors_w83627hf_exit(void)
+{
+	i2c_del_driver(&w83627hf_driver);
+}
+
+MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>, "
+	      "Philip Edelbrock <phil@netroedge.com>, "
+	      "and Mark Studebaker <mdsxyz123@yahoo.com>");
+MODULE_DESCRIPTION("W83627HF driver");
+MODULE_LICENSE("GPL");
+
+module_init(sensors_w83627hf_init);
+module_exit(sensors_w83627hf_exit);
diff --git a/drivers/hwmon/w83781d.c b/drivers/hwmon/w83781d.c
new file mode 100644
--- /dev/null
+++ b/drivers/hwmon/w83781d.c
@@ -0,0 +1,1632 @@
+/*
+    w83781d.c - Part of lm_sensors, Linux kernel modules for hardware
+                monitoring
+    Copyright (c) 1998 - 2001  Frodo Looijaard <frodol@dds.nl>,
+    Philip Edelbrock <phil@netroedge.com>,
+    and Mark Studebaker <mdsxyz123@yahoo.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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/*
+    Supports following chips:
+
+    Chip	#vin	#fanin	#pwm	#temp	wchipid	vendid	i2c	ISA
+    as99127f	7	3	0	3	0x31	0x12c3	yes	no
+    as99127f rev.2 (type_name = as99127f)	0x31	0x5ca3	yes	no
+    w83781d	7	3	0	3	0x10-1	0x5ca3	yes	yes
+    w83627hf	9	3	2	3	0x21	0x5ca3	yes	yes(LPC)
+    w83782d	9	3	2-4	3	0x30	0x5ca3	yes	yes
+    w83783s	5-6	3	2	1-2	0x40	0x5ca3	yes	no
+
+*/
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+#include <linux/i2c.h>
+#include <linux/i2c-sensor.h>
+#include <linux/i2c-vid.h>
+#include <asm/io.h>
+#include "lm75.h"
+
+/* Addresses to scan */
+static unsigned short normal_i2c[] = { 0x20, 0x21, 0x22, 0x23, 0x24, 0x25,
+					0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b,
+					0x2c, 0x2d, 0x2e, 0x2f, I2C_CLIENT_END };
+static unsigned int normal_isa[] = { 0x0290, I2C_CLIENT_ISA_END };
+
+/* Insmod parameters */
+SENSORS_INSMOD_5(w83781d, w83782d, w83783s, w83627hf, as99127f);
+I2C_CLIENT_MODULE_PARM(force_subclients, "List of subclient addresses: "
+		    "{bus, clientaddr, subclientaddr1, subclientaddr2}");
+
+static int init = 1;
+module_param(init, bool, 0);
+MODULE_PARM_DESC(init, "Set to zero to bypass chip initialization");
+
+/* Constants specified below */
+
+/* Length of ISA address segment */
+#define W83781D_EXTENT			8
+
+/* Where are the ISA address/data registers relative to the base address */
+#define W83781D_ADDR_REG_OFFSET		5
+#define W83781D_DATA_REG_OFFSET		6
+
+/* The W83781D registers */
+/* The W83782D registers for nr=7,8 are in bank 5 */
+#define W83781D_REG_IN_MAX(nr)		((nr < 7) ? (0x2b + (nr) * 2) : \
+						    (0x554 + (((nr) - 7) * 2)))
+#define W83781D_REG_IN_MIN(nr)		((nr < 7) ? (0x2c + (nr) * 2) : \
+						    (0x555 + (((nr) - 7) * 2)))
+#define W83781D_REG_IN(nr)		((nr < 7) ? (0x20 + (nr)) : \
+						    (0x550 + (nr) - 7))
+
+#define W83781D_REG_FAN_MIN(nr)		(0x3a + (nr))
+#define W83781D_REG_FAN(nr)		(0x27 + (nr))
+
+#define W83781D_REG_BANK		0x4E
+#define W83781D_REG_TEMP2_CONFIG	0x152
+#define W83781D_REG_TEMP3_CONFIG	0x252
+#define W83781D_REG_TEMP(nr)		((nr == 3) ? (0x0250) : \
+					((nr == 2) ? (0x0150) : \
+						     (0x27)))
+#define W83781D_REG_TEMP_HYST(nr)	((nr == 3) ? (0x253) : \
+					((nr == 2) ? (0x153) : \
+						     (0x3A)))
+#define W83781D_REG_TEMP_OVER(nr)	((nr == 3) ? (0x255) : \
+					((nr == 2) ? (0x155) : \
+						     (0x39)))
+
+#define W83781D_REG_CONFIG		0x40
+#define W83781D_REG_ALARM1		0x41
+#define W83781D_REG_ALARM2		0x42
+#define W83781D_REG_ALARM3		0x450	/* not on W83781D */
+
+#define W83781D_REG_IRQ			0x4C
+#define W83781D_REG_BEEP_CONFIG		0x4D
+#define W83781D_REG_BEEP_INTS1		0x56
+#define W83781D_REG_BEEP_INTS2		0x57
+#define W83781D_REG_BEEP_INTS3		0x453	/* not on W83781D */
+
+#define W83781D_REG_VID_FANDIV		0x47
+
+#define W83781D_REG_CHIPID		0x49
+#define W83781D_REG_WCHIPID		0x58
+#define W83781D_REG_CHIPMAN		0x4F
+#define W83781D_REG_PIN			0x4B
+
+/* 782D/783S only */
+#define W83781D_REG_VBAT		0x5D
+
+/* PWM 782D (1-4) and 783S (1-2) only */
+#define W83781D_REG_PWM1		0x5B	/* 782d and 783s/627hf datasheets disagree */
+						/* on which is which; */
+#define W83781D_REG_PWM2		0x5A	/* We follow the 782d convention here, */
+						/* However 782d is probably wrong. */
+#define W83781D_REG_PWM3		0x5E
+#define W83781D_REG_PWM4		0x5F
+#define W83781D_REG_PWMCLK12		0x5C
+#define W83781D_REG_PWMCLK34		0x45C
+static const u8 regpwm[] = { W83781D_REG_PWM1, W83781D_REG_PWM2,
+	W83781D_REG_PWM3, W83781D_REG_PWM4
+};
+
+#define W83781D_REG_PWM(nr)		(regpwm[(nr) - 1])
+
+#define W83781D_REG_I2C_ADDR		0x48
+#define W83781D_REG_I2C_SUBADDR		0x4A
+
+/* The following are undocumented in the data sheets however we
+   received the information in an email from Winbond tech support */
+/* Sensor selection - not on 781d */
+#define W83781D_REG_SCFG1		0x5D
+static const u8 BIT_SCFG1[] = { 0x02, 0x04, 0x08 };
+
+#define W83781D_REG_SCFG2		0x59
+static const u8 BIT_SCFG2[] = { 0x10, 0x20, 0x40 };
+
+#define W83781D_DEFAULT_BETA		3435
+
+/* RT Table registers */
+#define W83781D_REG_RT_IDX		0x50
+#define W83781D_REG_RT_VAL		0x51
+
+/* Conversions. Rounding and limit checking is only done on the TO_REG
+   variants. Note that you should be a bit careful with which arguments
+   these macros are called: arguments may be evaluated more than once.
+   Fixing this is just not worth it. */
+#define IN_TO_REG(val)			(SENSORS_LIMIT((((val) * 10 + 8)/16),0,255))
+#define IN_FROM_REG(val)		(((val) * 16) / 10)
+
+static inline u8
+FAN_TO_REG(long rpm, int div)
+{
+	if (rpm == 0)
+		return 255;
+	rpm = SENSORS_LIMIT(rpm, 1, 1000000);
+	return SENSORS_LIMIT((1350000 + rpm * div / 2) / (rpm * div), 1, 254);
+}
+
+#define FAN_FROM_REG(val,div)		((val) == 0   ? -1 : \
+					((val) == 255 ? 0 : \
+							1350000 / ((val) * (div))))
+
+#define TEMP_TO_REG(val)		(SENSORS_LIMIT(((val) < 0 ? (val)+0x100*1000 \
+						: (val)) / 1000, 0, 0xff))
+#define TEMP_FROM_REG(val)		(((val) & 0x80 ? (val)-0x100 : (val)) * 1000)
+
+#define PWM_FROM_REG(val)		(val)
+#define PWM_TO_REG(val)			(SENSORS_LIMIT((val),0,255))
+#define BEEP_MASK_FROM_REG(val,type)	((type) == as99127f ? \
+					 (val) ^ 0x7fff : (val))
+#define BEEP_MASK_TO_REG(val,type)	((type) == as99127f ? \
+					 (~(val)) & 0x7fff : (val) & 0xffffff)
+
+#define BEEP_ENABLE_TO_REG(val)		((val) ? 1 : 0)
+#define BEEP_ENABLE_FROM_REG(val)	((val) ? 1 : 0)
+
+#define DIV_FROM_REG(val)		(1 << (val))
+
+static inline u8
+DIV_TO_REG(long val, enum chips type)
+{
+	int i;
+	val = SENSORS_LIMIT(val, 1,
+			    ((type == w83781d
+			      || type == as99127f) ? 8 : 128)) >> 1;
+	for (i = 0; i < 7; i++) {
+		if (val == 0)
+			break;
+		val >>= 1;
+	}
+	return ((u8) i);
+}
+
+/* There are some complications in a module like this. First off, W83781D chips
+   may be both present on the SMBus and the ISA bus, and we have to handle
+   those cases separately at some places. Second, there might be several
+   W83781D chips available (well, actually, that is probably never done; but
+   it is a clean illustration of how to handle a case like that). Finally,
+   a specific chip may be attached to *both* ISA and SMBus, and we would
+   not like to detect it double. Fortunately, in the case of the W83781D at
+   least, a register tells us what SMBus address we are on, so that helps
+   a bit - except if there could be more than one SMBus. Groan. No solution
+   for this yet. */
+
+/* This module may seem overly long and complicated. In fact, it is not so
+   bad. Quite a lot of bookkeeping is done. A real driver can often cut
+   some corners. */
+
+/* For each registered W83781D, we need to keep some data in memory. That
+   data is pointed to by w83781d_list[NR]->data. The structure itself is
+   dynamically allocated, at the same time when a new w83781d client is
+   allocated. */
+struct w83781d_data {
+	struct i2c_client client;
+	struct semaphore lock;
+	enum chips type;
+
+	struct semaphore update_lock;
+	char valid;		/* !=0 if following fields are valid */
+	unsigned long last_updated;	/* In jiffies */
+
+	struct i2c_client *lm75[2];	/* for secondary I2C addresses */
+	/* array of 2 pointers to subclients */
+
+	u8 in[9];		/* Register value - 8 & 9 for 782D only */
+	u8 in_max[9];		/* Register value - 8 & 9 for 782D only */
+	u8 in_min[9];		/* Register value - 8 & 9 for 782D only */
+	u8 fan[3];		/* Register value */
+	u8 fan_min[3];		/* Register value */
+	u8 temp;
+	u8 temp_max;		/* Register value */
+	u8 temp_max_hyst;	/* Register value */
+	u16 temp_add[2];	/* Register value */
+	u16 temp_max_add[2];	/* Register value */
+	u16 temp_max_hyst_add[2];	/* Register value */
+	u8 fan_div[3];		/* Register encoding, shifted right */
+	u8 vid;			/* Register encoding, combined */
+	u32 alarms;		/* Register encoding, combined */
+	u32 beep_mask;		/* Register encoding, combined */
+	u8 beep_enable;		/* Boolean */
+	u8 pwm[4];		/* Register value */
+	u8 pwmenable[4];	/* Boolean */
+	u16 sens[3];		/* 782D/783S only.
+				   1 = pentium diode; 2 = 3904 diode;
+				   3000-5000 = thermistor beta.
+				   Default = 3435. 
+				   Other Betas unimplemented */
+	u8 vrm;
+};
+
+static int w83781d_attach_adapter(struct i2c_adapter *adapter);
+static int w83781d_detect(struct i2c_adapter *adapter, int address, int kind);
+static int w83781d_detach_client(struct i2c_client *client);
+
+static int w83781d_read_value(struct i2c_client *client, u16 register);
+static int w83781d_write_value(struct i2c_client *client, u16 register,
+			       u16 value);
+static struct w83781d_data *w83781d_update_device(struct device *dev);
+static void w83781d_init_client(struct i2c_client *client);
+
+static struct i2c_driver w83781d_driver = {
+	.owner = THIS_MODULE,
+	.name = "w83781d",
+	.id = I2C_DRIVERID_W83781D,
+	.flags = I2C_DF_NOTIFY,
+	.attach_adapter = w83781d_attach_adapter,
+	.detach_client = w83781d_detach_client,
+};
+
+/* following are the sysfs callback functions */
+#define show_in_reg(reg) \
+static ssize_t show_##reg (struct device *dev, char *buf, int nr) \
+{ \
+	struct w83781d_data *data = w83781d_update_device(dev); \
+	return sprintf(buf,"%ld\n", (long)IN_FROM_REG(data->reg[nr] * 10)); \
+}
+show_in_reg(in);
+show_in_reg(in_min);
+show_in_reg(in_max);
+
+#define store_in_reg(REG, reg) \
+static ssize_t store_in_##reg (struct device *dev, const char *buf, size_t count, int nr) \
+{ \
+	struct i2c_client *client = to_i2c_client(dev); \
+	struct w83781d_data *data = i2c_get_clientdata(client); \
+	u32 val; \
+	 \
+	val = simple_strtoul(buf, NULL, 10) / 10; \
+	 \
+	down(&data->update_lock); \
+	data->in_##reg[nr] = IN_TO_REG(val); \
+	w83781d_write_value(client, W83781D_REG_IN_##REG(nr), data->in_##reg[nr]); \
+	 \
+	up(&data->update_lock); \
+	return count; \
+}
+store_in_reg(MIN, min);
+store_in_reg(MAX, max);
+
+#define sysfs_in_offset(offset) \
+static ssize_t \
+show_regs_in_##offset (struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+        return show_in(dev, buf, offset); \
+} \
+static DEVICE_ATTR(in##offset##_input, S_IRUGO, show_regs_in_##offset, NULL);
+
+#define sysfs_in_reg_offset(reg, offset) \
+static ssize_t show_regs_in_##reg##offset (struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+	return show_in_##reg (dev, buf, offset); \
+} \
+static ssize_t store_regs_in_##reg##offset (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \
+{ \
+	return store_in_##reg (dev, buf, count, offset); \
+} \
+static DEVICE_ATTR(in##offset##_##reg, S_IRUGO| S_IWUSR, show_regs_in_##reg##offset, store_regs_in_##reg##offset);
+
+#define sysfs_in_offsets(offset) \
+sysfs_in_offset(offset); \
+sysfs_in_reg_offset(min, offset); \
+sysfs_in_reg_offset(max, offset);
+
+sysfs_in_offsets(0);
+sysfs_in_offsets(1);
+sysfs_in_offsets(2);
+sysfs_in_offsets(3);
+sysfs_in_offsets(4);
+sysfs_in_offsets(5);
+sysfs_in_offsets(6);
+sysfs_in_offsets(7);
+sysfs_in_offsets(8);
+
+#define device_create_file_in(client, offset) \
+do { \
+device_create_file(&client->dev, &dev_attr_in##offset##_input); \
+device_create_file(&client->dev, &dev_attr_in##offset##_min); \
+device_create_file(&client->dev, &dev_attr_in##offset##_max); \
+} while (0)
+
+#define show_fan_reg(reg) \
+static ssize_t show_##reg (struct device *dev, char *buf, int nr) \
+{ \
+	struct w83781d_data *data = w83781d_update_device(dev); \
+	return sprintf(buf,"%ld\n", \
+		FAN_FROM_REG(data->reg[nr-1], (long)DIV_FROM_REG(data->fan_div[nr-1]))); \
+}
+show_fan_reg(fan);
+show_fan_reg(fan_min);
+
+static ssize_t
+store_fan_min(struct device *dev, const char *buf, size_t count, int nr)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct w83781d_data *data = i2c_get_clientdata(client);
+	u32 val;
+
+	val = simple_strtoul(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->fan_min[nr - 1] =
+	    FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr - 1]));
+	w83781d_write_value(client, W83781D_REG_FAN_MIN(nr),
+			    data->fan_min[nr - 1]);
+
+	up(&data->update_lock);
+	return count;
+}
+
+#define sysfs_fan_offset(offset) \
+static ssize_t show_regs_fan_##offset (struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+	return show_fan(dev, buf, offset); \
+} \
+static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_regs_fan_##offset, NULL);
+
+#define sysfs_fan_min_offset(offset) \
+static ssize_t show_regs_fan_min##offset (struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+	return show_fan_min(dev, buf, offset); \
+} \
+static ssize_t store_regs_fan_min##offset (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \
+{ \
+	return store_fan_min(dev, buf, count, offset); \
+} \
+static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, show_regs_fan_min##offset, store_regs_fan_min##offset);
+
+sysfs_fan_offset(1);
+sysfs_fan_min_offset(1);
+sysfs_fan_offset(2);
+sysfs_fan_min_offset(2);
+sysfs_fan_offset(3);
+sysfs_fan_min_offset(3);
+
+#define device_create_file_fan(client, offset) \
+do { \
+device_create_file(&client->dev, &dev_attr_fan##offset##_input); \
+device_create_file(&client->dev, &dev_attr_fan##offset##_min); \
+} while (0)
+
+#define show_temp_reg(reg) \
+static ssize_t show_##reg (struct device *dev, char *buf, int nr) \
+{ \
+	struct w83781d_data *data = w83781d_update_device(dev); \
+	if (nr >= 2) {	/* TEMP2 and TEMP3 */ \
+		return sprintf(buf,"%d\n", \
+			LM75_TEMP_FROM_REG(data->reg##_add[nr-2])); \
+	} else {	/* TEMP1 */ \
+		return sprintf(buf,"%ld\n", (long)TEMP_FROM_REG(data->reg)); \
+	} \
+}
+show_temp_reg(temp);
+show_temp_reg(temp_max);
+show_temp_reg(temp_max_hyst);
+
+#define store_temp_reg(REG, reg) \
+static ssize_t store_temp_##reg (struct device *dev, const char *buf, size_t count, int nr) \
+{ \
+	struct i2c_client *client = to_i2c_client(dev); \
+	struct w83781d_data *data = i2c_get_clientdata(client); \
+	s32 val; \
+	 \
+	val = simple_strtol(buf, NULL, 10); \
+	 \
+	down(&data->update_lock); \
+	 \
+	if (nr >= 2) {	/* TEMP2 and TEMP3 */ \
+		data->temp_##reg##_add[nr-2] = LM75_TEMP_TO_REG(val); \
+		w83781d_write_value(client, W83781D_REG_TEMP_##REG(nr), \
+				data->temp_##reg##_add[nr-2]); \
+	} else {	/* TEMP1 */ \
+		data->temp_##reg = TEMP_TO_REG(val); \
+		w83781d_write_value(client, W83781D_REG_TEMP_##REG(nr), \
+			data->temp_##reg); \
+	} \
+	 \
+	up(&data->update_lock); \
+	return count; \
+}
+store_temp_reg(OVER, max);
+store_temp_reg(HYST, max_hyst);
+
+#define sysfs_temp_offset(offset) \
+static ssize_t \
+show_regs_temp_##offset (struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+	return show_temp(dev, buf, offset); \
+} \
+static DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_regs_temp_##offset, NULL);
+
+#define sysfs_temp_reg_offset(reg, offset) \
+static ssize_t show_regs_temp_##reg##offset (struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+	return show_temp_##reg (dev, buf, offset); \
+} \
+static ssize_t store_regs_temp_##reg##offset (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \
+{ \
+	return store_temp_##reg (dev, buf, count, offset); \
+} \
+static DEVICE_ATTR(temp##offset##_##reg, S_IRUGO| S_IWUSR, show_regs_temp_##reg##offset, store_regs_temp_##reg##offset);
+
+#define sysfs_temp_offsets(offset) \
+sysfs_temp_offset(offset); \
+sysfs_temp_reg_offset(max, offset); \
+sysfs_temp_reg_offset(max_hyst, offset);
+
+sysfs_temp_offsets(1);
+sysfs_temp_offsets(2);
+sysfs_temp_offsets(3);
+
+#define device_create_file_temp(client, offset) \
+do { \
+device_create_file(&client->dev, &dev_attr_temp##offset##_input); \
+device_create_file(&client->dev, &dev_attr_temp##offset##_max); \
+device_create_file(&client->dev, &dev_attr_temp##offset##_max_hyst); \
+} while (0)
+
+static ssize_t
+show_vid_reg(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct w83781d_data *data = w83781d_update_device(dev);
+	return sprintf(buf, "%ld\n", (long) vid_from_reg(data->vid, data->vrm));
+}
+
+static
+DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid_reg, NULL);
+#define device_create_file_vid(client) \
+device_create_file(&client->dev, &dev_attr_cpu0_vid);
+static ssize_t
+show_vrm_reg(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct w83781d_data *data = w83781d_update_device(dev);
+	return sprintf(buf, "%ld\n", (long) data->vrm);
+}
+
+static ssize_t
+store_vrm_reg(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct w83781d_data *data = i2c_get_clientdata(client);
+	u32 val;
+
+	val = simple_strtoul(buf, NULL, 10);
+	data->vrm = val;
+
+	return count;
+}
+
+static
+DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg);
+#define device_create_file_vrm(client) \
+device_create_file(&client->dev, &dev_attr_vrm);
+static ssize_t
+show_alarms_reg(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct w83781d_data *data = w83781d_update_device(dev);
+	return sprintf(buf, "%u\n", data->alarms);
+}
+
+static
+DEVICE_ATTR(alarms, S_IRUGO, show_alarms_reg, NULL);
+#define device_create_file_alarms(client) \
+device_create_file(&client->dev, &dev_attr_alarms);
+static ssize_t show_beep_mask (struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct w83781d_data *data = w83781d_update_device(dev);
+	return sprintf(buf, "%ld\n",
+		       (long)BEEP_MASK_FROM_REG(data->beep_mask, data->type));
+}
+static ssize_t show_beep_enable (struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct w83781d_data *data = w83781d_update_device(dev);
+	return sprintf(buf, "%ld\n",
+		       (long)BEEP_ENABLE_FROM_REG(data->beep_enable));
+}
+
+#define BEEP_ENABLE			0	/* Store beep_enable */
+#define BEEP_MASK			1	/* Store beep_mask */
+
+static ssize_t
+store_beep_reg(struct device *dev, const char *buf, size_t count,
+	       int update_mask)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct w83781d_data *data = i2c_get_clientdata(client);
+	u32 val, val2;
+
+	val = simple_strtoul(buf, NULL, 10);
+
+	down(&data->update_lock);
+
+	if (update_mask == BEEP_MASK) {	/* We are storing beep_mask */
+		data->beep_mask = BEEP_MASK_TO_REG(val, data->type);
+		w83781d_write_value(client, W83781D_REG_BEEP_INTS1,
+				    data->beep_mask & 0xff);
+
+		if ((data->type != w83781d) && (data->type != as99127f)) {
+			w83781d_write_value(client, W83781D_REG_BEEP_INTS3,
+					    ((data->beep_mask) >> 16) & 0xff);
+		}
+
+		val2 = (data->beep_mask >> 8) & 0x7f;
+	} else {		/* We are storing beep_enable */
+		val2 = w83781d_read_value(client, W83781D_REG_BEEP_INTS2) & 0x7f;
+		data->beep_enable = BEEP_ENABLE_TO_REG(val);
+	}
+
+	w83781d_write_value(client, W83781D_REG_BEEP_INTS2,
+			    val2 | data->beep_enable << 7);
+
+	up(&data->update_lock);
+	return count;
+}
+
+#define sysfs_beep(REG, reg) \
+static ssize_t show_regs_beep_##reg (struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+	return show_beep_##reg(dev, attr, buf); \
+} \
+static ssize_t store_regs_beep_##reg (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \
+{ \
+	return store_beep_reg(dev, buf, count, BEEP_##REG); \
+} \
+static DEVICE_ATTR(beep_##reg, S_IRUGO | S_IWUSR, show_regs_beep_##reg, store_regs_beep_##reg);
+
+sysfs_beep(ENABLE, enable);
+sysfs_beep(MASK, mask);
+
+#define device_create_file_beep(client) \
+do { \
+device_create_file(&client->dev, &dev_attr_beep_enable); \
+device_create_file(&client->dev, &dev_attr_beep_mask); \
+} while (0)
+
+static ssize_t
+show_fan_div_reg(struct device *dev, char *buf, int nr)
+{
+	struct w83781d_data *data = w83781d_update_device(dev);
+	return sprintf(buf, "%ld\n",
+		       (long) DIV_FROM_REG(data->fan_div[nr - 1]));
+}
+
+/* Note: we save and restore the fan minimum here, because its value is
+   determined in part by the fan divisor.  This follows the principle of
+   least suprise; the user doesn't expect the fan minimum to change just
+   because the divisor changed. */
+static ssize_t
+store_fan_div_reg(struct device *dev, const char *buf, size_t count, int nr)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct w83781d_data *data = i2c_get_clientdata(client);
+	unsigned long min;
+	u8 reg;
+	unsigned long val = simple_strtoul(buf, NULL, 10);
+
+	down(&data->update_lock);
+	
+	/* Save fan_min */
+	min = FAN_FROM_REG(data->fan_min[nr],
+			   DIV_FROM_REG(data->fan_div[nr]));
+
+	data->fan_div[nr] = DIV_TO_REG(val, data->type);
+
+	reg = (w83781d_read_value(client, nr==2 ? W83781D_REG_PIN : W83781D_REG_VID_FANDIV)
+	       & (nr==0 ? 0xcf : 0x3f))
+	    | ((data->fan_div[nr] & 0x03) << (nr==0 ? 4 : 6));
+	w83781d_write_value(client, nr==2 ? W83781D_REG_PIN : W83781D_REG_VID_FANDIV, reg);
+
+	/* w83781d and as99127f don't have extended divisor bits */
+	if (data->type != w83781d && data->type != as99127f) {
+		reg = (w83781d_read_value(client, W83781D_REG_VBAT)
+		       & ~(1 << (5 + nr)))
+		    | ((data->fan_div[nr] & 0x04) << (3 + nr));
+		w83781d_write_value(client, W83781D_REG_VBAT, reg);
+	}
+
+	/* Restore fan_min */
+	data->fan_min[nr] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr]));
+	w83781d_write_value(client, W83781D_REG_FAN_MIN(nr+1), data->fan_min[nr]);
+
+	up(&data->update_lock);
+	return count;
+}
+
+#define sysfs_fan_div(offset) \
+static ssize_t show_regs_fan_div_##offset (struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+	return show_fan_div_reg(dev, buf, offset); \
+} \
+static ssize_t store_regs_fan_div_##offset (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \
+{ \
+	return store_fan_div_reg(dev, buf, count, offset - 1); \
+} \
+static DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, show_regs_fan_div_##offset, store_regs_fan_div_##offset);
+
+sysfs_fan_div(1);
+sysfs_fan_div(2);
+sysfs_fan_div(3);
+
+#define device_create_file_fan_div(client, offset) \
+do { \
+device_create_file(&client->dev, &dev_attr_fan##offset##_div); \
+} while (0)
+
+static ssize_t
+show_pwm_reg(struct device *dev, char *buf, int nr)
+{
+	struct w83781d_data *data = w83781d_update_device(dev);
+	return sprintf(buf, "%ld\n", (long) PWM_FROM_REG(data->pwm[nr - 1]));
+}
+
+static ssize_t
+show_pwmenable_reg(struct device *dev, char *buf, int nr)
+{
+	struct w83781d_data *data = w83781d_update_device(dev);
+	return sprintf(buf, "%ld\n", (long) data->pwmenable[nr - 1]);
+}
+
+static ssize_t
+store_pwm_reg(struct device *dev, const char *buf, size_t count, int nr)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct w83781d_data *data = i2c_get_clientdata(client);
+	u32 val;
+
+	val = simple_strtoul(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->pwm[nr - 1] = PWM_TO_REG(val);
+	w83781d_write_value(client, W83781D_REG_PWM(nr), data->pwm[nr - 1]);
+	up(&data->update_lock);
+	return count;
+}
+
+static ssize_t
+store_pwmenable_reg(struct device *dev, const char *buf, size_t count, int nr)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct w83781d_data *data = i2c_get_clientdata(client);
+	u32 val, reg;
+
+	val = simple_strtoul(buf, NULL, 10);
+
+	down(&data->update_lock);
+
+	switch (val) {
+	case 0:
+	case 1:
+		reg = w83781d_read_value(client, W83781D_REG_PWMCLK12);
+		w83781d_write_value(client, W83781D_REG_PWMCLK12,
+				    (reg & 0xf7) | (val << 3));
+
+		reg = w83781d_read_value(client, W83781D_REG_BEEP_CONFIG);
+		w83781d_write_value(client, W83781D_REG_BEEP_CONFIG,
+				    (reg & 0xef) | (!val << 4));
+
+		data->pwmenable[nr - 1] = val;
+		break;
+
+	default:
+		up(&data->update_lock);
+		return -EINVAL;
+	}
+
+	up(&data->update_lock);
+	return count;
+}
+
+#define sysfs_pwm(offset) \
+static ssize_t show_regs_pwm_##offset (struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+	return show_pwm_reg(dev, buf, offset); \
+} \
+static ssize_t store_regs_pwm_##offset (struct device *dev, struct device_attribute *attr, \
+		const char *buf, size_t count) \
+{ \
+	return store_pwm_reg(dev, buf, count, offset); \
+} \
+static DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR, \
+		show_regs_pwm_##offset, store_regs_pwm_##offset);
+
+#define sysfs_pwmenable(offset) \
+static ssize_t show_regs_pwmenable_##offset (struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+	return show_pwmenable_reg(dev, buf, offset); \
+} \
+static ssize_t store_regs_pwmenable_##offset (struct device *dev, struct device_attribute *attr, \
+		const char *buf, size_t count) \
+{ \
+	return store_pwmenable_reg(dev, buf, count, offset); \
+} \
+static DEVICE_ATTR(pwm##offset##_enable, S_IRUGO | S_IWUSR, \
+		show_regs_pwmenable_##offset, store_regs_pwmenable_##offset);
+
+sysfs_pwm(1);
+sysfs_pwm(2);
+sysfs_pwmenable(2);		/* only PWM2 can be enabled/disabled */
+sysfs_pwm(3);
+sysfs_pwm(4);
+
+#define device_create_file_pwm(client, offset) \
+do { \
+device_create_file(&client->dev, &dev_attr_pwm##offset); \
+} while (0)
+
+#define device_create_file_pwmenable(client, offset) \
+do { \
+device_create_file(&client->dev, &dev_attr_pwm##offset##_enable); \
+} while (0)
+
+static ssize_t
+show_sensor_reg(struct device *dev, char *buf, int nr)
+{
+	struct w83781d_data *data = w83781d_update_device(dev);
+	return sprintf(buf, "%ld\n", (long) data->sens[nr - 1]);
+}
+
+static ssize_t
+store_sensor_reg(struct device *dev, const char *buf, size_t count, int nr)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct w83781d_data *data = i2c_get_clientdata(client);
+	u32 val, tmp;
+
+	val = simple_strtoul(buf, NULL, 10);
+
+	down(&data->update_lock);
+
+	switch (val) {
+	case 1:		/* PII/Celeron diode */
+		tmp = w83781d_read_value(client, W83781D_REG_SCFG1);
+		w83781d_write_value(client, W83781D_REG_SCFG1,
+				    tmp | BIT_SCFG1[nr - 1]);
+		tmp = w83781d_read_value(client, W83781D_REG_SCFG2);
+		w83781d_write_value(client, W83781D_REG_SCFG2,
+				    tmp | BIT_SCFG2[nr - 1]);
+		data->sens[nr - 1] = val;
+		break;
+	case 2:		/* 3904 */
+		tmp = w83781d_read_value(client, W83781D_REG_SCFG1);
+		w83781d_write_value(client, W83781D_REG_SCFG1,
+				    tmp | BIT_SCFG1[nr - 1]);
+		tmp = w83781d_read_value(client, W83781D_REG_SCFG2);
+		w83781d_write_value(client, W83781D_REG_SCFG2,
+				    tmp & ~BIT_SCFG2[nr - 1]);
+		data->sens[nr - 1] = val;
+		break;
+	case W83781D_DEFAULT_BETA:	/* thermistor */
+		tmp = w83781d_read_value(client, W83781D_REG_SCFG1);
+		w83781d_write_value(client, W83781D_REG_SCFG1,
+				    tmp & ~BIT_SCFG1[nr - 1]);
+		data->sens[nr - 1] = val;
+		break;
+	default:
+		dev_err(dev, "Invalid sensor type %ld; must be 1, 2, or %d\n",
+		       (long) val, W83781D_DEFAULT_BETA);
+		break;
+	}
+
+	up(&data->update_lock);
+	return count;
+}
+
+#define sysfs_sensor(offset) \
+static ssize_t show_regs_sensor_##offset (struct device *dev, struct device_attribute *attr, char *buf) \
+{ \
+    return show_sensor_reg(dev, buf, offset); \
+} \
+static ssize_t store_regs_sensor_##offset (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \
+{ \
+    return store_sensor_reg(dev, buf, count, offset); \
+} \
+static DEVICE_ATTR(temp##offset##_type, S_IRUGO | S_IWUSR, show_regs_sensor_##offset, store_regs_sensor_##offset);
+
+sysfs_sensor(1);
+sysfs_sensor(2);
+sysfs_sensor(3);
+
+#define device_create_file_sensor(client, offset) \
+do { \
+device_create_file(&client->dev, &dev_attr_temp##offset##_type); \
+} while (0)
+
+/* This function is called when:
+     * w83781d_driver is inserted (when this module is loaded), for each
+       available adapter
+     * when a new adapter is inserted (and w83781d_driver is still present) */
+static int
+w83781d_attach_adapter(struct i2c_adapter *adapter)
+{
+	if (!(adapter->class & I2C_CLASS_HWMON))
+		return 0;
+	return i2c_detect(adapter, &addr_data, w83781d_detect);
+}
+
+/* Assumes that adapter is of I2C, not ISA variety.
+ * OTHERWISE DON'T CALL THIS
+ */
+static int
+w83781d_detect_subclients(struct i2c_adapter *adapter, int address, int kind,
+		struct i2c_client *new_client)
+{
+	int i, val1 = 0, id;
+	int err;
+	const char *client_name = "";
+	struct w83781d_data *data = i2c_get_clientdata(new_client);
+
+	data->lm75[0] = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
+	if (!(data->lm75[0])) {
+		err = -ENOMEM;
+		goto ERROR_SC_0;
+	}
+	memset(data->lm75[0], 0x00, sizeof (struct i2c_client));
+
+	id = i2c_adapter_id(adapter);
+
+	if (force_subclients[0] == id && force_subclients[1] == address) {
+		for (i = 2; i <= 3; i++) {
+			if (force_subclients[i] < 0x48 ||
+			    force_subclients[i] > 0x4f) {
+				dev_err(&new_client->dev, "Invalid subclient "
+					"address %d; must be 0x48-0x4f\n",
+					force_subclients[i]);
+				err = -EINVAL;
+				goto ERROR_SC_1;
+			}
+		}
+		w83781d_write_value(new_client, W83781D_REG_I2C_SUBADDR,
+				(force_subclients[2] & 0x07) |
+				((force_subclients[3] & 0x07) << 4));
+		data->lm75[0]->addr = force_subclients[2];
+	} else {
+		val1 = w83781d_read_value(new_client, W83781D_REG_I2C_SUBADDR);
+		data->lm75[0]->addr = 0x48 + (val1 & 0x07);
+	}
+
+	if (kind != w83783s) {
+
+		data->lm75[1] = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
+		if (!(data->lm75[1])) {
+			err = -ENOMEM;
+			goto ERROR_SC_1;
+		}
+		memset(data->lm75[1], 0x0, sizeof(struct i2c_client));
+
+		if (force_subclients[0] == id &&
+		    force_subclients[1] == address) {
+			data->lm75[1]->addr = force_subclients[3];
+		} else {
+			data->lm75[1]->addr = 0x48 + ((val1 >> 4) & 0x07);
+		}
+		if (data->lm75[0]->addr == data->lm75[1]->addr) {
+			dev_err(&new_client->dev,
+			       "Duplicate addresses 0x%x for subclients.\n",
+			       data->lm75[0]->addr);
+			err = -EBUSY;
+			goto ERROR_SC_2;
+		}
+	}
+
+	if (kind == w83781d)
+		client_name = "w83781d subclient";
+	else if (kind == w83782d)
+		client_name = "w83782d subclient";
+	else if (kind == w83783s)
+		client_name = "w83783s subclient";
+	else if (kind == w83627hf)
+		client_name = "w83627hf subclient";
+	else if (kind == as99127f)
+		client_name = "as99127f subclient";
+
+	for (i = 0; i <= 1; i++) {
+		/* store all data in w83781d */
+		i2c_set_clientdata(data->lm75[i], NULL);
+		data->lm75[i]->adapter = adapter;
+		data->lm75[i]->driver = &w83781d_driver;
+		data->lm75[i]->flags = 0;
+		strlcpy(data->lm75[i]->name, client_name,
+			I2C_NAME_SIZE);
+		if ((err = i2c_attach_client(data->lm75[i]))) {
+			dev_err(&new_client->dev, "Subclient %d "
+				"registration at address 0x%x "
+				"failed.\n", i, data->lm75[i]->addr);
+			if (i == 1)
+				goto ERROR_SC_3;
+			goto ERROR_SC_2;
+		}
+		if (kind == w83783s)
+			break;
+	}
+
+	return 0;
+
+/* Undo inits in case of errors */
+ERROR_SC_3:
+	i2c_detach_client(data->lm75[0]);
+ERROR_SC_2:
+	if (NULL != data->lm75[1])
+		kfree(data->lm75[1]);
+ERROR_SC_1:
+	if (NULL != data->lm75[0])
+		kfree(data->lm75[0]);
+ERROR_SC_0:
+	return err;
+}
+
+static int
+w83781d_detect(struct i2c_adapter *adapter, int address, int kind)
+{
+	int i = 0, val1 = 0, val2;
+	struct i2c_client *new_client;
+	struct w83781d_data *data;
+	int err;
+	const char *client_name = "";
+	int is_isa = i2c_is_isa_adapter(adapter);
+	enum vendor { winbond, asus } vendid;
+
+	if (!is_isa
+	    && !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
+		err = -EINVAL;
+		goto ERROR0;
+	}
+
+	/* Prevent users from forcing a kind for a bus it isn't supposed
+	   to possibly be on */
+	if (is_isa && (kind == as99127f || kind == w83783s)) {
+		dev_err(&adapter->dev,
+			"Cannot force I2C-only chip for ISA address 0x%02x.\n",
+			address);
+		err = -EINVAL;
+		goto ERROR0;
+	}
+	
+	if (is_isa)
+		if (!request_region(address, W83781D_EXTENT,
+				    w83781d_driver.name)) {
+			dev_dbg(&adapter->dev, "Request of region "
+				"0x%x-0x%x for w83781d failed\n", address,
+				address + W83781D_EXTENT - 1);
+			err = -EBUSY;
+			goto ERROR0;
+		}
+
+	/* Probe whether there is anything available on this address. Already
+	   done for SMBus clients */
+	if (kind < 0) {
+		if (is_isa) {
+
+#define REALLY_SLOW_IO
+			/* We need the timeouts for at least some LM78-like
+			   chips. But only if we read 'undefined' registers. */
+			i = inb_p(address + 1);
+			if (inb_p(address + 2) != i
+			 || inb_p(address + 3) != i
+			 || inb_p(address + 7) != i) {
+				dev_dbg(&adapter->dev, "Detection of w83781d "
+					"chip failed at step 1\n");
+				err = -ENODEV;
+				goto ERROR1;
+			}
+#undef REALLY_SLOW_IO
+
+			/* Let's just hope nothing breaks here */
+			i = inb_p(address + 5) & 0x7f;
+			outb_p(~i & 0x7f, address + 5);
+			val2 = inb_p(address + 5) & 0x7f;
+			if (val2 != (~i & 0x7f)) {
+				outb_p(i, address + 5);
+				dev_dbg(&adapter->dev, "Detection of w83781d "
+					"chip failed at step 2 (0x%x != "
+					"0x%x at 0x%x)\n", val2, ~i & 0x7f,
+					address + 5);
+				err = -ENODEV;
+				goto ERROR1;
+			}
+		}
+	}
+
+	/* OK. For now, we presume we have a valid client. We now create the
+	   client structure, even though we cannot fill it completely yet.
+	   But it allows us to access w83781d_{read,write}_value. */
+
+	if (!(data = kmalloc(sizeof(struct w83781d_data), GFP_KERNEL))) {
+		err = -ENOMEM;
+		goto ERROR1;
+	}
+	memset(data, 0, sizeof(struct w83781d_data));
+
+	new_client = &data->client;
+	i2c_set_clientdata(new_client, data);
+	new_client->addr = address;
+	init_MUTEX(&data->lock);
+	new_client->adapter = adapter;
+	new_client->driver = &w83781d_driver;
+	new_client->flags = 0;
+
+	/* Now, we do the remaining detection. */
+
+	/* The w8378?d may be stuck in some other bank than bank 0. This may
+	   make reading other information impossible. Specify a force=... or
+	   force_*=... parameter, and the Winbond will be reset to the right
+	   bank. */
+	if (kind < 0) {
+		if (w83781d_read_value(new_client, W83781D_REG_CONFIG) & 0x80) {
+			dev_dbg(&new_client->dev, "Detection failed at step "
+				"3\n");
+			err = -ENODEV;
+			goto ERROR2;
+		}
+		val1 = w83781d_read_value(new_client, W83781D_REG_BANK);
+		val2 = w83781d_read_value(new_client, W83781D_REG_CHIPMAN);
+		/* Check for Winbond or Asus ID if in bank 0 */
+		if ((!(val1 & 0x07)) &&
+		    (((!(val1 & 0x80)) && (val2 != 0xa3) && (val2 != 0xc3))
+		     || ((val1 & 0x80) && (val2 != 0x5c) && (val2 != 0x12)))) {
+			dev_dbg(&new_client->dev, "Detection failed at step "
+				"4\n");
+			err = -ENODEV;
+			goto ERROR2;
+		}
+		/* If Winbond SMBus, check address at 0x48.
+		   Asus doesn't support, except for as99127f rev.2 */
+		if ((!is_isa) && (((!(val1 & 0x80)) && (val2 == 0xa3)) ||
+				  ((val1 & 0x80) && (val2 == 0x5c)))) {
+			if (w83781d_read_value
+			    (new_client, W83781D_REG_I2C_ADDR) != address) {
+				dev_dbg(&new_client->dev, "Detection failed "
+					"at step 5\n");
+				err = -ENODEV;
+				goto ERROR2;
+			}
+		}
+	}
+
+	/* We have either had a force parameter, or we have already detected the
+	   Winbond. Put it now into bank 0 and Vendor ID High Byte */
+	w83781d_write_value(new_client, W83781D_REG_BANK,
+			    (w83781d_read_value(new_client,
+						W83781D_REG_BANK) & 0x78) |
+			    0x80);
+
+	/* Determine the chip type. */
+	if (kind <= 0) {
+		/* get vendor ID */
+		val2 = w83781d_read_value(new_client, W83781D_REG_CHIPMAN);
+		if (val2 == 0x5c)
+			vendid = winbond;
+		else if (val2 == 0x12)
+			vendid = asus;
+		else {
+			dev_dbg(&new_client->dev, "Chip was made by neither "
+				"Winbond nor Asus?\n");
+			err = -ENODEV;
+			goto ERROR2;
+		}
+
+		val1 = w83781d_read_value(new_client, W83781D_REG_WCHIPID);
+		if ((val1 == 0x10 || val1 == 0x11) && vendid == winbond)
+			kind = w83781d;
+		else if (val1 == 0x30 && vendid == winbond)
+			kind = w83782d;
+		else if (val1 == 0x40 && vendid == winbond && !is_isa
+				&& address == 0x2d)
+			kind = w83783s;
+		else if (val1 == 0x21 && vendid == winbond)
+			kind = w83627hf;
+		else if (val1 == 0x31 && !is_isa && address >= 0x28)
+			kind = as99127f;
+		else {
+			if (kind == 0)
+				dev_warn(&new_client->dev, "Ignoring 'force' "
+					 "parameter for unknown chip at "
+					 "adapter %d, address 0x%02x\n",
+					 i2c_adapter_id(adapter), address);
+			err = -EINVAL;
+			goto ERROR2;
+		}
+	}
+
+	if (kind == w83781d) {
+		client_name = "w83781d";
+	} else if (kind == w83782d) {
+		client_name = "w83782d";
+	} else if (kind == w83783s) {
+		client_name = "w83783s";
+	} else if (kind == w83627hf) {
+		client_name = "w83627hf";
+	} else if (kind == as99127f) {
+		client_name = "as99127f";
+	}
+
+	/* Fill in the remaining client fields and put into the global list */
+	strlcpy(new_client->name, client_name, I2C_NAME_SIZE);
+	data->type = kind;
+
+	data->valid = 0;
+	init_MUTEX(&data->update_lock);
+
+	/* Tell the I2C layer a new client has arrived */
+	if ((err = i2c_attach_client(new_client)))
+		goto ERROR2;
+
+	/* attach secondary i2c lm75-like clients */
+	if (!is_isa) {
+		if ((err = w83781d_detect_subclients(adapter, address,
+				kind, new_client)))
+			goto ERROR3;
+	} else {
+		data->lm75[0] = NULL;
+		data->lm75[1] = NULL;
+	}
+
+	/* Initialize the chip */
+	w83781d_init_client(new_client);
+
+	/* A few vars need to be filled upon startup */
+	for (i = 1; i <= 3; i++) {
+		data->fan_min[i - 1] = w83781d_read_value(new_client,
+					W83781D_REG_FAN_MIN(i));
+	}
+	if (kind != w83781d && kind != as99127f)
+		for (i = 0; i < 4; i++)
+			data->pwmenable[i] = 1;
+
+	/* Register sysfs hooks */
+	device_create_file_in(new_client, 0);
+	if (kind != w83783s)
+		device_create_file_in(new_client, 1);
+	device_create_file_in(new_client, 2);
+	device_create_file_in(new_client, 3);
+	device_create_file_in(new_client, 4);
+	device_create_file_in(new_client, 5);
+	device_create_file_in(new_client, 6);
+	if (kind != as99127f && kind != w83781d && kind != w83783s) {
+		device_create_file_in(new_client, 7);
+		device_create_file_in(new_client, 8);
+	}
+
+	device_create_file_fan(new_client, 1);
+	device_create_file_fan(new_client, 2);
+	device_create_file_fan(new_client, 3);
+
+	device_create_file_temp(new_client, 1);
+	device_create_file_temp(new_client, 2);
+	if (kind != w83783s)
+		device_create_file_temp(new_client, 3);
+
+	device_create_file_vid(new_client);
+	device_create_file_vrm(new_client);
+
+	device_create_file_fan_div(new_client, 1);
+	device_create_file_fan_div(new_client, 2);
+	device_create_file_fan_div(new_client, 3);
+
+	device_create_file_alarms(new_client);
+
+	device_create_file_beep(new_client);
+
+	if (kind != w83781d && kind != as99127f) {
+		device_create_file_pwm(new_client, 1);
+		device_create_file_pwm(new_client, 2);
+		device_create_file_pwmenable(new_client, 2);
+	}
+	if (kind == w83782d && !is_isa) {
+		device_create_file_pwm(new_client, 3);
+		device_create_file_pwm(new_client, 4);
+	}
+
+	if (kind != as99127f && kind != w83781d) {
+		device_create_file_sensor(new_client, 1);
+		device_create_file_sensor(new_client, 2);
+		if (kind != w83783s)
+			device_create_file_sensor(new_client, 3);
+	}
+
+	return 0;
+
+ERROR3:
+	i2c_detach_client(new_client);
+ERROR2:
+	kfree(data);
+ERROR1:
+	if (is_isa)
+		release_region(address, W83781D_EXTENT);
+ERROR0:
+	return err;
+}
+
+static int
+w83781d_detach_client(struct i2c_client *client)
+{
+	int err;
+
+	if (i2c_is_isa_client(client))
+		release_region(client->addr, W83781D_EXTENT);
+
+	if ((err = i2c_detach_client(client))) {
+		dev_err(&client->dev,
+		       "Client deregistration failed, client not detached.\n");
+		return err;
+	}
+
+	if (i2c_get_clientdata(client)==NULL) {
+		/* subclients */
+		kfree(client);
+	} else {
+		/* main client */
+		kfree(i2c_get_clientdata(client));
+	}
+
+	return 0;
+}
+
+/* The SMBus locks itself, usually, but nothing may access the Winbond between
+   bank switches. ISA access must always be locked explicitly! 
+   We ignore the W83781D BUSY flag at this moment - it could lead to deadlocks,
+   would slow down the W83781D access and should not be necessary. 
+   There are some ugly typecasts here, but the good news is - they should
+   nowhere else be necessary! */
+static int
+w83781d_read_value(struct i2c_client *client, u16 reg)
+{
+	struct w83781d_data *data = i2c_get_clientdata(client);
+	int res, word_sized, bank;
+	struct i2c_client *cl;
+
+	down(&data->lock);
+	if (i2c_is_isa_client(client)) {
+		word_sized = (((reg & 0xff00) == 0x100)
+			      || ((reg & 0xff00) == 0x200))
+		    && (((reg & 0x00ff) == 0x50)
+			|| ((reg & 0x00ff) == 0x53)
+			|| ((reg & 0x00ff) == 0x55));
+		if (reg & 0xff00) {
+			outb_p(W83781D_REG_BANK,
+			       client->addr + W83781D_ADDR_REG_OFFSET);
+			outb_p(reg >> 8,
+			       client->addr + W83781D_DATA_REG_OFFSET);
+		}
+		outb_p(reg & 0xff, client->addr + W83781D_ADDR_REG_OFFSET);
+		res = inb_p(client->addr + W83781D_DATA_REG_OFFSET);
+		if (word_sized) {
+			outb_p((reg & 0xff) + 1,
+			       client->addr + W83781D_ADDR_REG_OFFSET);
+			res =
+			    (res << 8) + inb_p(client->addr +
+					       W83781D_DATA_REG_OFFSET);
+		}
+		if (reg & 0xff00) {
+			outb_p(W83781D_REG_BANK,
+			       client->addr + W83781D_ADDR_REG_OFFSET);
+			outb_p(0, client->addr + W83781D_DATA_REG_OFFSET);
+		}
+	} else {
+		bank = (reg >> 8) & 0x0f;
+		if (bank > 2)
+			/* switch banks */
+			i2c_smbus_write_byte_data(client, W83781D_REG_BANK,
+						  bank);
+		if (bank == 0 || bank > 2) {
+			res = i2c_smbus_read_byte_data(client, reg & 0xff);
+		} else {
+			/* switch to subclient */
+			cl = data->lm75[bank - 1];
+			/* convert from ISA to LM75 I2C addresses */
+			switch (reg & 0xff) {
+			case 0x50:	/* TEMP */
+				res = swab16(i2c_smbus_read_word_data(cl, 0));
+				break;
+			case 0x52:	/* CONFIG */
+				res = i2c_smbus_read_byte_data(cl, 1);
+				break;
+			case 0x53:	/* HYST */
+				res = swab16(i2c_smbus_read_word_data(cl, 2));
+				break;
+			case 0x55:	/* OVER */
+			default:
+				res = swab16(i2c_smbus_read_word_data(cl, 3));
+				break;
+			}
+		}
+		if (bank > 2)
+			i2c_smbus_write_byte_data(client, W83781D_REG_BANK, 0);
+	}
+	up(&data->lock);
+	return res;
+}
+
+static int
+w83781d_write_value(struct i2c_client *client, u16 reg, u16 value)
+{
+	struct w83781d_data *data = i2c_get_clientdata(client);
+	int word_sized, bank;
+	struct i2c_client *cl;
+
+	down(&data->lock);
+	if (i2c_is_isa_client(client)) {
+		word_sized = (((reg & 0xff00) == 0x100)
+			      || ((reg & 0xff00) == 0x200))
+		    && (((reg & 0x00ff) == 0x53)
+			|| ((reg & 0x00ff) == 0x55));
+		if (reg & 0xff00) {
+			outb_p(W83781D_REG_BANK,
+			       client->addr + W83781D_ADDR_REG_OFFSET);
+			outb_p(reg >> 8,
+			       client->addr + W83781D_DATA_REG_OFFSET);
+		}
+		outb_p(reg & 0xff, client->addr + W83781D_ADDR_REG_OFFSET);
+		if (word_sized) {
+			outb_p(value >> 8,
+			       client->addr + W83781D_DATA_REG_OFFSET);
+			outb_p((reg & 0xff) + 1,
+			       client->addr + W83781D_ADDR_REG_OFFSET);
+		}
+		outb_p(value & 0xff, client->addr + W83781D_DATA_REG_OFFSET);
+		if (reg & 0xff00) {
+			outb_p(W83781D_REG_BANK,
+			       client->addr + W83781D_ADDR_REG_OFFSET);
+			outb_p(0, client->addr + W83781D_DATA_REG_OFFSET);
+		}
+	} else {
+		bank = (reg >> 8) & 0x0f;
+		if (bank > 2)
+			/* switch banks */
+			i2c_smbus_write_byte_data(client, W83781D_REG_BANK,
+						  bank);
+		if (bank == 0 || bank > 2) {
+			i2c_smbus_write_byte_data(client, reg & 0xff,
+						  value & 0xff);
+		} else {
+			/* switch to subclient */
+			cl = data->lm75[bank - 1];
+			/* convert from ISA to LM75 I2C addresses */
+			switch (reg & 0xff) {
+			case 0x52:	/* CONFIG */
+				i2c_smbus_write_byte_data(cl, 1, value & 0xff);
+				break;
+			case 0x53:	/* HYST */
+				i2c_smbus_write_word_data(cl, 2, swab16(value));
+				break;
+			case 0x55:	/* OVER */
+				i2c_smbus_write_word_data(cl, 3, swab16(value));
+				break;
+			}
+		}
+		if (bank > 2)
+			i2c_smbus_write_byte_data(client, W83781D_REG_BANK, 0);
+	}
+	up(&data->lock);
+	return 0;
+}
+
+/* Called when we have found a new W83781D. It should set limits, etc. */
+static void
+w83781d_init_client(struct i2c_client *client)
+{
+	struct w83781d_data *data = i2c_get_clientdata(client);
+	int i, p;
+	int type = data->type;
+	u8 tmp;
+
+	if (init && type != as99127f) {	/* this resets registers we don't have
+					   documentation for on the as99127f */
+		/* save these registers */
+		i = w83781d_read_value(client, W83781D_REG_BEEP_CONFIG);
+		p = w83781d_read_value(client, W83781D_REG_PWMCLK12);
+		/* Reset all except Watchdog values and last conversion values
+		   This sets fan-divs to 2, among others */
+		w83781d_write_value(client, W83781D_REG_CONFIG, 0x80);
+		/* Restore the registers and disable power-on abnormal beep.
+		   This saves FAN 1/2/3 input/output values set by BIOS. */
+		w83781d_write_value(client, W83781D_REG_BEEP_CONFIG, i | 0x80);
+		w83781d_write_value(client, W83781D_REG_PWMCLK12, p);
+		/* Disable master beep-enable (reset turns it on).
+		   Individual beep_mask should be reset to off but for some reason
+		   disabling this bit helps some people not get beeped */
+		w83781d_write_value(client, W83781D_REG_BEEP_INTS2, 0);
+	}
+
+	data->vrm = i2c_which_vrm();
+
+	if ((type != w83781d) && (type != as99127f)) {
+		tmp = w83781d_read_value(client, W83781D_REG_SCFG1);
+		for (i = 1; i <= 3; i++) {
+			if (!(tmp & BIT_SCFG1[i - 1])) {
+				data->sens[i - 1] = W83781D_DEFAULT_BETA;
+			} else {
+				if (w83781d_read_value
+				    (client,
+				     W83781D_REG_SCFG2) & BIT_SCFG2[i - 1])
+					data->sens[i - 1] = 1;
+				else
+					data->sens[i - 1] = 2;
+			}
+			if (type == w83783s && i == 2)
+				break;
+		}
+	}
+
+	if (init && type != as99127f) {
+		/* Enable temp2 */
+		tmp = w83781d_read_value(client, W83781D_REG_TEMP2_CONFIG);
+		if (tmp & 0x01) {
+			dev_warn(&client->dev, "Enabling temp2, readings "
+				 "might not make sense\n");
+			w83781d_write_value(client, W83781D_REG_TEMP2_CONFIG,
+				tmp & 0xfe);
+		}
+
+		/* Enable temp3 */
+		if (type != w83783s) {
+			tmp = w83781d_read_value(client,
+				W83781D_REG_TEMP3_CONFIG);
+			if (tmp & 0x01) {
+				dev_warn(&client->dev, "Enabling temp3, "
+					 "readings might not make sense\n");
+				w83781d_write_value(client,
+					W83781D_REG_TEMP3_CONFIG, tmp & 0xfe);
+			}
+		}
+
+		if (type != w83781d) {
+			/* enable comparator mode for temp2 and temp3 so
+			   alarm indication will work correctly */
+			i = w83781d_read_value(client, W83781D_REG_IRQ);
+			if (!(i & 0x40))
+				w83781d_write_value(client, W83781D_REG_IRQ,
+						    i | 0x40);
+		}
+	}
+
+	/* Start monitoring */
+	w83781d_write_value(client, W83781D_REG_CONFIG,
+			    (w83781d_read_value(client,
+						W83781D_REG_CONFIG) & 0xf7)
+			    | 0x01);
+}
+
+static struct w83781d_data *w83781d_update_device(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct w83781d_data *data = i2c_get_clientdata(client);
+	int i;
+
+	down(&data->update_lock);
+
+	if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
+	    || !data->valid) {
+		dev_dbg(dev, "Starting device update\n");
+
+		for (i = 0; i <= 8; i++) {
+			if (data->type == w83783s && i == 1)
+				continue;	/* 783S has no in1 */
+			data->in[i] =
+			    w83781d_read_value(client, W83781D_REG_IN(i));
+			data->in_min[i] =
+			    w83781d_read_value(client, W83781D_REG_IN_MIN(i));
+			data->in_max[i] =
+			    w83781d_read_value(client, W83781D_REG_IN_MAX(i));
+			if ((data->type != w83782d)
+			    && (data->type != w83627hf) && (i == 6))
+				break;
+		}
+		for (i = 1; i <= 3; i++) {
+			data->fan[i - 1] =
+			    w83781d_read_value(client, W83781D_REG_FAN(i));
+			data->fan_min[i - 1] =
+			    w83781d_read_value(client, W83781D_REG_FAN_MIN(i));
+		}
+		if (data->type != w83781d && data->type != as99127f) {
+			for (i = 1; i <= 4; i++) {
+				data->pwm[i - 1] =
+				    w83781d_read_value(client,
+						       W83781D_REG_PWM(i));
+				if ((data->type != w83782d
+				     || i2c_is_isa_client(client))
+				    && i == 2)
+					break;
+			}
+			/* Only PWM2 can be disabled */
+			data->pwmenable[1] = (w83781d_read_value(client,
+					      W83781D_REG_PWMCLK12) & 0x08) >> 3;
+		}
+
+		data->temp = w83781d_read_value(client, W83781D_REG_TEMP(1));
+		data->temp_max =
+		    w83781d_read_value(client, W83781D_REG_TEMP_OVER(1));
+		data->temp_max_hyst =
+		    w83781d_read_value(client, W83781D_REG_TEMP_HYST(1));
+		data->temp_add[0] =
+		    w83781d_read_value(client, W83781D_REG_TEMP(2));
+		data->temp_max_add[0] =
+		    w83781d_read_value(client, W83781D_REG_TEMP_OVER(2));
+		data->temp_max_hyst_add[0] =
+		    w83781d_read_value(client, W83781D_REG_TEMP_HYST(2));
+		if (data->type != w83783s) {
+			data->temp_add[1] =
+			    w83781d_read_value(client, W83781D_REG_TEMP(3));
+			data->temp_max_add[1] =
+			    w83781d_read_value(client,
+					       W83781D_REG_TEMP_OVER(3));
+			data->temp_max_hyst_add[1] =
+			    w83781d_read_value(client,
+					       W83781D_REG_TEMP_HYST(3));
+		}
+		i = w83781d_read_value(client, W83781D_REG_VID_FANDIV);
+		data->vid = i & 0x0f;
+		data->vid |= (w83781d_read_value(client,
+					W83781D_REG_CHIPID) & 0x01) << 4;
+		data->fan_div[0] = (i >> 4) & 0x03;
+		data->fan_div[1] = (i >> 6) & 0x03;
+		data->fan_div[2] = (w83781d_read_value(client,
+					W83781D_REG_PIN) >> 6) & 0x03;
+		if ((data->type != w83781d) && (data->type != as99127f)) {
+			i = w83781d_read_value(client, W83781D_REG_VBAT);
+			data->fan_div[0] |= (i >> 3) & 0x04;
+			data->fan_div[1] |= (i >> 4) & 0x04;
+			data->fan_div[2] |= (i >> 5) & 0x04;
+		}
+		data->alarms =
+		    w83781d_read_value(client,
+				       W83781D_REG_ALARM1) +
+		    (w83781d_read_value(client, W83781D_REG_ALARM2) << 8);
+		if ((data->type == w83782d) || (data->type == w83627hf)) {
+			data->alarms |=
+			    w83781d_read_value(client,
+					       W83781D_REG_ALARM3) << 16;
+		}
+		i = w83781d_read_value(client, W83781D_REG_BEEP_INTS2);
+		data->beep_enable = i >> 7;
+		data->beep_mask = ((i & 0x7f) << 8) +
+		    w83781d_read_value(client, W83781D_REG_BEEP_INTS1);
+		if ((data->type != w83781d) && (data->type != as99127f)) {
+			data->beep_mask |=
+			    w83781d_read_value(client,
+					       W83781D_REG_BEEP_INTS3) << 16;
+		}
+		data->last_updated = jiffies;
+		data->valid = 1;
+	}
+
+	up(&data->update_lock);
+
+	return data;
+}
+
+static int __init
+sensors_w83781d_init(void)
+{
+	return i2c_add_driver(&w83781d_driver);
+}
+
+static void __exit
+sensors_w83781d_exit(void)
+{
+	i2c_del_driver(&w83781d_driver);
+}
+
+MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>, "
+	      "Philip Edelbrock <phil@netroedge.com>, "
+	      "and Mark Studebaker <mdsxyz123@yahoo.com>");
+MODULE_DESCRIPTION("W83781D driver");
+MODULE_LICENSE("GPL");
+
+module_init(sensors_w83781d_init);
+module_exit(sensors_w83781d_exit);
diff --git a/drivers/hwmon/w83l785ts.c b/drivers/hwmon/w83l785ts.c
new file mode 100644
--- /dev/null
+++ b/drivers/hwmon/w83l785ts.c
@@ -0,0 +1,328 @@
+/*
+ * w83l785ts.c - Part of lm_sensors, Linux kernel modules for hardware
+ *               monitoring
+ * Copyright (C) 2003-2004  Jean Delvare <khali@linux-fr.org>
+ *
+ * Inspired from the lm83 driver. The W83L785TS-S is a sensor chip made
+ * by Winbond. It reports a single external temperature with a 1 deg
+ * resolution and a 3 deg accuracy. Datasheet can be obtained from
+ * Winbond's website at:
+ *   http://www.winbond-usa.com/products/winbond_products/pdfs/PCIC/W83L785TS-S.pdf
+ *
+ * Ported to Linux 2.6 by Wolfgang Ziegler <nuppla@gmx.at> and Jean Delvare
+ * <khali@linux-fr.org>.
+ *
+ * Thanks to James Bolt <james@evilpenguin.com> for benchmarking the read
+ * error handling mechanism.
+ *
+ * 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 <linux/module.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+#include <linux/i2c.h>
+#include <linux/i2c-sensor.h>
+
+/* How many retries on register read error */
+#define MAX_RETRIES	5
+
+/*
+ * Address to scan
+ * Address is fully defined internally and cannot be changed.
+ */
+
+static unsigned short normal_i2c[] = { 0x2e, I2C_CLIENT_END };
+static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
+
+/*
+ * Insmod parameters
+ */
+
+SENSORS_INSMOD_1(w83l785ts);
+
+/*
+ * The W83L785TS-S registers
+ * Manufacturer ID is 0x5CA3 for Winbond.
+ */
+
+#define W83L785TS_REG_MAN_ID1		0x4D
+#define W83L785TS_REG_MAN_ID2		0x4C
+#define W83L785TS_REG_CHIP_ID		0x4E
+#define W83L785TS_REG_CONFIG		0x40
+#define W83L785TS_REG_TYPE		0x52
+#define W83L785TS_REG_TEMP		0x27
+#define W83L785TS_REG_TEMP_OVER		0x53 /* not sure about this one */
+
+/*
+ * Conversions
+ * The W83L785TS-S uses signed 8-bit values.
+ */
+
+#define TEMP_FROM_REG(val)	((val & 0x80 ? val-0x100 : val) * 1000)
+
+/*
+ * Functions declaration
+ */
+
+static int w83l785ts_attach_adapter(struct i2c_adapter *adapter);
+static int w83l785ts_detect(struct i2c_adapter *adapter, int address,
+	int kind);
+static int w83l785ts_detach_client(struct i2c_client *client);
+static u8 w83l785ts_read_value(struct i2c_client *client, u8 reg, u8 defval);
+static struct w83l785ts_data *w83l785ts_update_device(struct device *dev);
+
+/*
+ * Driver data (common to all clients)
+ */
+ 
+static struct i2c_driver w83l785ts_driver = {
+	.owner		= THIS_MODULE,
+	.name		= "w83l785ts",
+	.id		= I2C_DRIVERID_W83L785TS,
+	.flags		= I2C_DF_NOTIFY,
+	.attach_adapter	= w83l785ts_attach_adapter,
+	.detach_client	= w83l785ts_detach_client,
+};
+
+/*
+ * Client data (each client gets its own)
+ */
+
+struct w83l785ts_data {
+	struct i2c_client client;
+	struct semaphore update_lock;
+	char valid; /* zero until following fields are valid */
+	unsigned long last_updated; /* in jiffies */
+
+	/* registers values */
+	u8 temp, temp_over;
+};
+
+/*
+ * Sysfs stuff
+ */
+
+static ssize_t show_temp(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct w83l785ts_data *data = w83l785ts_update_device(dev);
+	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp));
+}
+
+static ssize_t show_temp_over(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct w83l785ts_data *data = w83l785ts_update_device(dev);
+	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_over));
+}
+
+static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL);
+static DEVICE_ATTR(temp1_max, S_IRUGO, show_temp_over, NULL);
+
+/*
+ * Real code
+ */
+
+static int w83l785ts_attach_adapter(struct i2c_adapter *adapter)
+{
+	if (!(adapter->class & I2C_CLASS_HWMON))
+		return 0;
+	return i2c_detect(adapter, &addr_data, w83l785ts_detect);
+}
+
+/*
+ * The following function does more than just detection. If detection
+ * succeeds, it also registers the new chip.
+ */
+static int w83l785ts_detect(struct i2c_adapter *adapter, int address, int kind)
+{
+	struct i2c_client *new_client;
+	struct w83l785ts_data *data;
+	int err = 0;
+
+
+	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+		goto exit;
+
+	if (!(data = kmalloc(sizeof(struct w83l785ts_data), GFP_KERNEL))) {
+		err = -ENOMEM;
+		goto exit;
+	}
+	memset(data, 0, sizeof(struct w83l785ts_data));
+
+
+	/* The common I2C client data is placed right before the
+	 * W83L785TS-specific data. */
+	new_client = &data->client;
+	i2c_set_clientdata(new_client, data);
+	new_client->addr = address;
+	new_client->adapter = adapter;
+	new_client->driver = &w83l785ts_driver;
+	new_client->flags = 0;
+
+	/*
+	 * Now we do the remaining detection. A negative kind means that
+	 * the driver was loaded with no force parameter (default), so we
+	 * must both detect and identify the chip (actually there is only
+	 * one possible kind of chip for now, W83L785TS-S). A zero kind means
+	 * that the driver was loaded with the force parameter, the detection
+	 * step shall be skipped. A positive kind means that the driver
+	 * was loaded with the force parameter and a given kind of chip is
+	 * requested, so both the detection and the identification steps
+	 * are skipped.
+	 */
+	if (kind < 0) { /* detection */
+		if (((w83l785ts_read_value(new_client,
+		      W83L785TS_REG_CONFIG, 0) & 0x80) != 0x00)
+		 || ((w83l785ts_read_value(new_client,
+		      W83L785TS_REG_TYPE, 0) & 0xFC) != 0x00)) {
+			dev_dbg(&adapter->dev,
+				"W83L785TS-S detection failed at 0x%02x.\n",
+				address);
+			goto exit_free;
+		}
+	}
+
+	if (kind <= 0) { /* identification */
+		u16 man_id;
+		u8 chip_id;
+
+		man_id = (w83l785ts_read_value(new_client,
+			 W83L785TS_REG_MAN_ID1, 0) << 8) +
+			 w83l785ts_read_value(new_client,
+			 W83L785TS_REG_MAN_ID2, 0);
+		chip_id = w83l785ts_read_value(new_client,
+			  W83L785TS_REG_CHIP_ID, 0);
+
+		if (man_id == 0x5CA3) { /* Winbond */
+			if (chip_id == 0x70) { /* W83L785TS-S */
+				kind = w83l785ts;			
+			}
+		}
+	
+		if (kind <= 0) { /* identification failed */
+			dev_info(&adapter->dev,
+				 "Unsupported chip (man_id=0x%04X, "
+				 "chip_id=0x%02X).\n", man_id, chip_id);
+			goto exit_free;
+		}
+	}
+
+	/* We can fill in the remaining client fields. */
+	strlcpy(new_client->name, "w83l785ts", I2C_NAME_SIZE);
+	data->valid = 0;
+	init_MUTEX(&data->update_lock);
+
+	/* Default values in case the first read fails (unlikely). */
+	data->temp_over = data->temp = 0;
+
+	/* Tell the I2C layer a new client has arrived. */
+	if ((err = i2c_attach_client(new_client))) 
+		goto exit_free;
+
+	/*
+	 * Initialize the W83L785TS chip
+	 * Nothing yet, assume it is already started.
+	 */
+
+	/* Register sysfs hooks */
+	device_create_file(&new_client->dev, &dev_attr_temp1_input);
+	device_create_file(&new_client->dev, &dev_attr_temp1_max);
+
+	return 0;
+
+exit_free:
+	kfree(data);
+exit:
+	return err;
+}
+
+static int w83l785ts_detach_client(struct i2c_client *client)
+{
+	int err;
+
+	if ((err = i2c_detach_client(client))) {
+		dev_err(&client->dev, "Client deregistration failed, "
+			"client not detached.\n");
+		return err;
+	}
+
+	kfree(i2c_get_clientdata(client));
+	return 0;
+}
+
+static u8 w83l785ts_read_value(struct i2c_client *client, u8 reg, u8 defval)
+{
+	int value, i;
+
+	/* Frequent read errors have been reported on Asus boards, so we
+	 * retry on read errors. If it still fails (unlikely), return the
+	 * default value requested by the caller. */
+	for (i = 1; i <= MAX_RETRIES; i++) {
+		value = i2c_smbus_read_byte_data(client, reg);
+		if (value >= 0) {
+			dev_dbg(&client->dev, "Read 0x%02x from register "
+				"0x%02x.\n", value, reg);
+			return value;
+		}
+		dev_dbg(&client->dev, "Read failed, will retry in %d.\n", i);
+		msleep(i);
+	}
+
+	dev_err(&client->dev, "Couldn't read value from register 0x%02x. "
+		"Please report.\n", reg);
+	return defval;
+}
+
+static struct w83l785ts_data *w83l785ts_update_device(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct w83l785ts_data *data = i2c_get_clientdata(client);
+
+	down(&data->update_lock);
+
+	if (!data->valid || time_after(jiffies, data->last_updated + HZ * 2)) {
+		dev_dbg(&client->dev, "Updating w83l785ts data.\n");
+		data->temp = w83l785ts_read_value(client,
+			     W83L785TS_REG_TEMP, data->temp);
+		data->temp_over = w83l785ts_read_value(client,
+				  W83L785TS_REG_TEMP_OVER, data->temp_over);
+
+		data->last_updated = jiffies;
+		data->valid = 1;
+	}
+
+	up(&data->update_lock);
+
+	return data;
+}
+
+static int __init sensors_w83l785ts_init(void)
+{
+	return i2c_add_driver(&w83l785ts_driver);
+}
+
+static void __exit sensors_w83l785ts_exit(void)
+{
+	i2c_del_driver(&w83l785ts_driver);
+}
+
+MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>");
+MODULE_DESCRIPTION("W83L785TS-S driver");
+MODULE_LICENSE("GPL");
+
+module_init(sensors_w83l785ts_init);
+module_exit(sensors_w83l785ts_exit);
diff --git a/drivers/i2c/algos/i2c-algo-ite.c b/drivers/i2c/algos/i2c-algo-ite.c
--- a/drivers/i2c/algos/i2c-algo-ite.c
+++ b/drivers/i2c/algos/i2c-algo-ite.c
@@ -208,7 +208,7 @@ static int test_bus(struct i2c_algo_iic_
 		goto bailout;
 	}
 	sdalo(adap);
-	printk("test_bus:1 scl: %d  sda: %d \n",getscl(adap),
+	printk("test_bus:1 scl: %d  sda: %d\n", getscl(adap),
 	       getsda(adap));
 	if ( 0 != getsda(adap) ) {
 		printk("test_bus: %s SDA stuck high!\n",name);
@@ -221,7 +221,7 @@ static int test_bus(struct i2c_algo_iic_
 		goto bailout;
 	}		
 	sdahi(adap);
-	printk("test_bus:2 scl: %d  sda: %d \n",getscl(adap),
+	printk("test_bus:2 scl: %d  sda: %d\n", getscl(adap),
 	       getsda(adap));
 	if ( 0 == getsda(adap) ) {
 		printk("test_bus: %s SDA stuck low!\n",name);
@@ -234,7 +234,7 @@ static int test_bus(struct i2c_algo_iic_
 	goto bailout;
 	}
 	scllo(adap);
-	printk("test_bus:3 scl: %d  sda: %d \n",getscl(adap),
+	printk("test_bus:3 scl: %d  sda: %d\n", getscl(adap),
 	       getsda(adap));
 	if ( 0 != getscl(adap) ) {
 
@@ -247,7 +247,7 @@ static int test_bus(struct i2c_algo_iic_
 		goto bailout;
 	}
 	sclhi(adap);
-	printk("test_bus:4 scl: %d  sda: %d \n",getscl(adap),
+	printk("test_bus:4 scl: %d  sda: %d\n", getscl(adap),
 	       getsda(adap));
 	if ( 0 == getscl(adap) ) {
 		printk("test_bus: %s SCL stuck low!\n",name);
diff --git a/drivers/i2c/algos/i2c-algo-pca.c b/drivers/i2c/algos/i2c-algo-pca.c
--- a/drivers/i2c/algos/i2c-algo-pca.c
+++ b/drivers/i2c/algos/i2c-algo-pca.c
@@ -49,7 +49,7 @@ static int i2c_debug=0;
 /*
  * Generate a start condition on the i2c bus.
  *
- * returns after the start condition has occured
+ * returns after the start condition has occurred
  */
 static void pca_start(struct i2c_algo_pca_data *adap)
 {
@@ -62,9 +62,9 @@ static void pca_start(struct i2c_algo_pc
 }
 
 /*
- * Generate a repeated start condition on the i2c bus 
+ * Generate a repeated start condition on the i2c bus
  *
- * return after the repeated start condition has occured
+ * return after the repeated start condition has occurred
  */
 static void pca_repeated_start(struct i2c_algo_pca_data *adap)
 {
@@ -82,7 +82,7 @@ static void pca_repeated_start(struct i2
  * returns after the stop condition has been generated
  *
  * STOPs do not generate an interrupt or set the SI flag, since the
- * part returns the the idle state (0xf8). Hence we don't need to
+ * part returns the idle state (0xf8). Hence we don't need to
  * pca_wait here.
  */
 static void pca_stop(struct i2c_algo_pca_data *adap)
diff --git a/drivers/i2c/algos/i2c-algo-sibyte.c b/drivers/i2c/algos/i2c-algo-sibyte.c
--- a/drivers/i2c/algos/i2c-algo-sibyte.c
+++ b/drivers/i2c/algos/i2c-algo-sibyte.c
@@ -24,7 +24,6 @@
 
 /* Ported for SiByte SOCs by Broadcom Corporation.  */
 
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -7,7 +7,7 @@ menu "I2C Hardware Bus support"
 
 config I2C_ALI1535
 	tristate "ALI 1535"
-	depends on I2C && PCI && EXPERIMENTAL
+	depends on I2C && PCI
 	help
 	  If you say yes to this option, support will be included for the SMB
 	  Host controller on Acer Labs Inc. (ALI) M1535 South Bridges.  The SMB
@@ -31,7 +31,7 @@ config I2C_ALI1563
 
 config I2C_ALI15X3
 	tristate "ALI 15x3"
-	depends on I2C && PCI && EXPERIMENTAL
+	depends on I2C && PCI
 	help
 	  If you say yes to this option, support will be included for the
 	  Acer Labs Inc. (ALI) M1514 and M1543 motherboard I2C interfaces.
@@ -41,7 +41,7 @@ config I2C_ALI15X3
 
 config I2C_AMD756
 	tristate "AMD 756/766/768/8111 and nVidia nForce"
-	depends on I2C && PCI && EXPERIMENTAL
+	depends on I2C && PCI
 	help
 	  If you say yes to this option, support will be included for the AMD
 	  756/766/768 mainboard I2C interfaces.  The driver also includes
@@ -66,7 +66,7 @@ config I2C_AMD756_S4882
 
 config I2C_AMD8111
 	tristate "AMD 8111"
-	depends on I2C && PCI && EXPERIMENTAL
+	depends on I2C && PCI
 	help
 	  If you say yes to this option, support will be included for the
 	  second (SMBus 2.0) AMD 8111 mainboard I2C interface.
@@ -109,7 +109,7 @@ config I2C_HYDRA
 
 config I2C_I801
 	tristate "Intel 82801 (ICH)"
-	depends on I2C && PCI && EXPERIMENTAL
+	depends on I2C && PCI
 	help
 	  If you say yes to this option, support will be included for the Intel
 	  801 family of mainboard I2C interfaces.  Specifically, the following
@@ -130,7 +130,7 @@ config I2C_I801
 
 config I2C_I810
 	tristate "Intel 810/815"
-	depends on I2C && PCI && EXPERIMENTAL
+	depends on I2C && PCI
 	select I2C_ALGOBIT
 	help
 	  If you say yes to this option, support will be included for the Intel
@@ -183,7 +183,7 @@ config I2C_IOP3XX
 
 config I2C_ISA
 	tristate "ISA Bus support"
-	depends on I2C && EXPERIMENTAL
+	depends on I2C
 	help
 	  If you say yes to this option, support will be included for i2c
 	  interfaces that are on the ISA bus.
@@ -248,12 +248,11 @@ config I2C_MPC
 	  will be called i2c-mpc.
 
 config I2C_NFORCE2
-	tristate "Nvidia Nforce2"
-	depends on I2C && PCI && EXPERIMENTAL
+	tristate "Nvidia nForce2, nForce3 and nForce4"
+	depends on I2C && PCI
 	help
 	  If you say yes to this option, support will be included for the Nvidia
-	  Nforce2 family of mainboard I2C interfaces.
-	  This driver also supports the nForce3 Pro 150 MCP.
+	  nForce2, nForce3 and nForce4 families of mainboard I2C interfaces.
 
 	  This driver can also be built as a module.  If so, the module
 	  will be called i2c-nforce2.
@@ -305,7 +304,7 @@ config I2C_PARPORT_LIGHT
 
 config I2C_PROSAVAGE
 	tristate "S3/VIA (Pro)Savage"
-	depends on I2C && PCI && EXPERIMENTAL
+	depends on I2C && PCI
 	select I2C_ALGOBIT
 	help
 	  If you say yes to this option, support will be included for the
@@ -388,7 +387,7 @@ config SCx200_ACB
 
 config I2C_SIS5595
 	tristate "SiS 5595"
-	depends on I2C && PCI && EXPERIMENTAL
+	depends on I2C && PCI
 	help
 	  If you say yes to this option, support will be included for the 
 	  SiS5595 SMBus (a subset of I2C) interface.
@@ -398,7 +397,7 @@ config I2C_SIS5595
 
 config I2C_SIS630
 	tristate "SiS 630/730"
-	depends on I2C && PCI && EXPERIMENTAL
+	depends on I2C && PCI
 	help
 	  If you say yes to this option, support will be included for the 
 	  SiS630 and SiS730 SMBus (a subset of I2C) interface.
@@ -408,7 +407,7 @@ config I2C_SIS630
 
 config I2C_SIS96X
 	tristate "SiS 96x"
-	depends on I2C && PCI && EXPERIMENTAL
+	depends on I2C && PCI
 	help
 	  If you say yes to this option, support will be included for the SiS
 	  96x SMBus (a subset of I2C) interfaces.  Specifically, the following
@@ -419,6 +418,7 @@ config I2C_SIS96X
 	    648/961
 	    650/961
 	    735
+	    745
 
 	  This driver can also be built as a module.  If so, the module
 	  will be called i2c-sis96x.
@@ -449,7 +449,7 @@ config I2C_VIA
 
 config I2C_VIAPRO
 	tristate "VIA 82C596/82C686/823x"
-	depends on I2C && PCI && EXPERIMENTAL
+	depends on I2C && PCI
 	help
 	  If you say yes to this option, support will be included for the VIA
 	  82C596/82C686/823x I2C interfaces.  Specifically, the following 
@@ -467,7 +467,7 @@ config I2C_VIAPRO
 
 config I2C_VOODOO3
 	tristate "Voodoo 3"
-	depends on I2C && PCI && EXPERIMENTAL
+	depends on I2C && PCI
 	select I2C_ALGOBIT
 	help
 	  If you say yes to this option, support will be included for the
diff --git a/drivers/i2c/busses/i2c-ali1535.c b/drivers/i2c/busses/i2c-ali1535.c
--- a/drivers/i2c/busses/i2c-ali1535.c
+++ b/drivers/i2c/busses/i2c-ali1535.c
@@ -53,7 +53,6 @@
 
 /* Note: we assume there can only be one ALI1535, with one SMBus interface */
 
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/kernel.h>
diff --git a/drivers/i2c/busses/i2c-ali15x3.c b/drivers/i2c/busses/i2c-ali15x3.c
--- a/drivers/i2c/busses/i2c-ali15x3.c
+++ b/drivers/i2c/busses/i2c-ali15x3.c
@@ -60,7 +60,6 @@
 
 /* Note: we assume there can only be one ALI15X3, with one SMBus interface */
 
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/kernel.h>
diff --git a/drivers/i2c/busses/i2c-amd756.c b/drivers/i2c/busses/i2c-amd756.c
--- a/drivers/i2c/busses/i2c-amd756.c
+++ b/drivers/i2c/busses/i2c-amd756.c
@@ -37,7 +37,6 @@
    Note: we assume there can only be one device, with one SMBus interface.
 */
 
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/kernel.h>
diff --git a/drivers/i2c/busses/i2c-amd8111.c b/drivers/i2c/busses/i2c-amd8111.c
--- a/drivers/i2c/busses/i2c-amd8111.c
+++ b/drivers/i2c/busses/i2c-amd8111.c
@@ -8,7 +8,6 @@
  * the Free Software Foundation version 2.
  */
 
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/kernel.h>
diff --git a/drivers/i2c/busses/i2c-au1550.c b/drivers/i2c/busses/i2c-au1550.c
--- a/drivers/i2c/busses/i2c-au1550.c
+++ b/drivers/i2c/busses/i2c-au1550.c
@@ -27,7 +27,6 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 
-#include <linux/config.h>
 #include <linux/delay.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
diff --git a/drivers/i2c/busses/i2c-elektor.c b/drivers/i2c/busses/i2c-elektor.c
--- a/drivers/i2c/busses/i2c-elektor.c
+++ b/drivers/i2c/busses/i2c-elektor.c
@@ -25,7 +25,6 @@
 /* Partialy rewriten by Oleg I. Vdovikin for mmapped support of 
    for Alpha Processor Inc. UP-2000(+) boards */
 
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/ioport.h>
 #include <linux/module.h>
diff --git a/drivers/i2c/busses/i2c-frodo.c b/drivers/i2c/busses/i2c-frodo.c
--- a/drivers/i2c/busses/i2c-frodo.c
+++ b/drivers/i2c/busses/i2c-frodo.c
@@ -12,7 +12,6 @@
  * version 2 as published by the Free Software Foundation.
  */
 
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
--- a/drivers/i2c/busses/i2c-i801.c
+++ b/drivers/i2c/busses/i2c-i801.c
@@ -41,7 +41,6 @@
 
 /* Note: we assume there can only be one I801, with one SMBus interface */
 
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/kernel.h>
@@ -138,7 +137,7 @@ static int i801_setup(struct pci_dev *de
 		pci_read_config_word(I801_dev, SMBBA, &i801_smba);
 		i801_smba &= 0xfff0;
 		if(i801_smba == 0) {
-			dev_err(&dev->dev, "SMB base address uninitialized"
+			dev_err(&dev->dev, "SMB base address uninitialized "
 				"- upgrade BIOS or use force_addr=0xaddr\n");
 			return -ENODEV;
 		}
@@ -187,7 +186,7 @@ static int i801_transaction(void)
 	int result = 0;
 	int timeout = 0;
 
-	dev_dbg(&I801_dev->dev, "Transaction (pre): CNT=%02x, CMD=%02x,"
+	dev_dbg(&I801_dev->dev, "Transaction (pre): CNT=%02x, CMD=%02x, "
 		"ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTCNT),
 		inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0),
 		inb_p(SMBHSTDAT1));
@@ -195,7 +194,7 @@ static int i801_transaction(void)
 	/* Make sure the SMBus host is ready to start transmitting */
 	/* 0x1f = Failed, Bus_Err, Dev_Err, Intr, Host_Busy */
 	if ((temp = (0x1f & inb_p(SMBHSTSTS))) != 0x00) {
-		dev_dbg(&I801_dev->dev, "SMBus busy (%02x). Resetting... \n",
+		dev_dbg(&I801_dev->dev, "SMBus busy (%02x). Resetting...\n",
 			temp);
 		outb_p(temp, SMBHSTSTS);
 		if ((temp = (0x1f & inb_p(SMBHSTSTS))) != 0x00) {
@@ -241,7 +240,7 @@ static int i801_transaction(void)
 		outb_p(inb(SMBHSTSTS), SMBHSTSTS);
 
 	if ((temp = (0x1f & inb_p(SMBHSTSTS))) != 0x00) {
-		dev_dbg(&I801_dev->dev, "Failed reset at end of transaction"
+		dev_dbg(&I801_dev->dev, "Failed reset at end of transaction "
 			"(%02x)\n", temp);
 	}
 	dev_dbg(&I801_dev->dev, "Transaction (post): CNT=%02x, CMD=%02x, "
@@ -316,7 +315,7 @@ static int i801_block_transaction(union 
 		}
 		if (temp & errmask) {
 			dev_dbg(&I801_dev->dev, "SMBus busy (%02x). "
-				"Resetting... \n", temp);
+				"Resetting...\n", temp);
 			outb_p(temp, SMBHSTSTS);
 			if (((temp = inb_p(SMBHSTSTS)) & errmask) != 0x00) {
 				dev_err(&I801_dev->dev,
diff --git a/drivers/i2c/busses/i2c-i810.c b/drivers/i2c/busses/i2c-i810.c
--- a/drivers/i2c/busses/i2c-i810.c
+++ b/drivers/i2c/busses/i2c-i810.c
@@ -34,7 +34,6 @@
    i815			1132           
 */
 
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
diff --git a/drivers/i2c/busses/i2c-ibm_iic.c b/drivers/i2c/busses/i2c-ibm_iic.c
--- a/drivers/i2c/busses/i2c-ibm_iic.c
+++ b/drivers/i2c/busses/i2c-ibm_iic.c
@@ -695,7 +695,7 @@ static int __devinit iic_probe(struct oc
 
 	dev->irq = iic_force_poll ? -1 : ocp->def->irq;
 	if (dev->irq >= 0){
-		/* Disable interrupts until we finish intialization,
+		/* Disable interrupts until we finish initialization,
 		   assumes level-sensitive IRQ setup...
 		 */
 		iic_interrupt_mode(dev, 0);
diff --git a/drivers/i2c/busses/i2c-ibm_iic.h b/drivers/i2c/busses/i2c-ibm_iic.h
--- a/drivers/i2c/busses/i2c-ibm_iic.h
+++ b/drivers/i2c/busses/i2c-ibm_iic.h
@@ -22,7 +22,6 @@
 #ifndef __I2C_IBM_IIC_H_
 #define __I2C_IBM_IIC_H_
 
-#include <linux/config.h>
 #include <linux/i2c.h> 
 
 struct iic_regs {
diff --git a/drivers/i2c/busses/i2c-iop3xx.c b/drivers/i2c/busses/i2c-iop3xx.c
--- a/drivers/i2c/busses/i2c-iop3xx.c
+++ b/drivers/i2c/busses/i2c-iop3xx.c
@@ -85,7 +85,7 @@ iop3xx_i2c_enable(struct i2c_algo_iop3xx
 	u32 cr = IOP3XX_ICR_GCD | IOP3XX_ICR_SCLEN | IOP3XX_ICR_UE;
 
 	/* 
-	 * Everytime unit enable is asserted, GPOD needs to be cleared
+	 * Every time unit enable is asserted, GPOD needs to be cleared
 	 * on IOP321 to avoid data corruption on the bus.
 	 */
 #ifdef CONFIG_ARCH_IOP321
diff --git a/drivers/i2c/busses/i2c-isa.c b/drivers/i2c/busses/i2c-isa.c
--- a/drivers/i2c/busses/i2c-isa.c
+++ b/drivers/i2c/busses/i2c-isa.c
@@ -24,7 +24,6 @@
    the SMBus and the ISA bus very much easier. See lm78.c for an example
    of this. */
 
-#include <linux/config.h>
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
diff --git a/drivers/i2c/busses/i2c-ite.c b/drivers/i2c/busses/i2c-ite.c
--- a/drivers/i2c/busses/i2c-ite.c
+++ b/drivers/i2c/busses/i2c-ite.c
@@ -33,7 +33,6 @@
 /* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and even
    Frodo Looijaard <frodol@dds.nl> */
 
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/ioport.h>
 #include <linux/module.h>
diff --git a/drivers/i2c/busses/i2c-ixp2000.c b/drivers/i2c/busses/i2c-ixp2000.c
--- a/drivers/i2c/busses/i2c-ixp2000.c
+++ b/drivers/i2c/busses/i2c-ixp2000.c
@@ -26,11 +26,6 @@
  * 'enabled' to drive the GPIOs.
  */
 
-#include <linux/config.h>
-#ifdef CONFIG_I2C_DEBUG_BUS
-#define DEBUG	1
-#endif
-
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/device.h>
@@ -38,7 +33,8 @@
 #include <linux/i2c.h>
 #include <linux/i2c-algo-bit.h>
 
-#include <asm/hardware.h>	/* Pick up IXP42000-specific bits */
+#include <asm/hardware.h>	/* Pick up IXP2000-specific bits */
+#include <asm/arch/gpio.h>
 
 static inline int ixp2000_scl_pin(void *data)
 {
diff --git a/drivers/i2c/busses/i2c-ixp4xx.c b/drivers/i2c/busses/i2c-ixp4xx.c
--- a/drivers/i2c/busses/i2c-ixp4xx.c
+++ b/drivers/i2c/busses/i2c-ixp4xx.c
@@ -26,11 +26,6 @@
  *       that is passed as the platform_data to this driver.
  */
 
-#include <linux/config.h>
-#ifdef CONFIG_I2C_DEBUG_BUS
-#define DEBUG	1
-#endif
-
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/device.h>
diff --git a/drivers/i2c/busses/i2c-keywest.c b/drivers/i2c/busses/i2c-keywest.c
--- a/drivers/i2c/busses/i2c-keywest.c
+++ b/drivers/i2c/busses/i2c-keywest.c
@@ -46,7 +46,6 @@
     sound driver to be happy
 */
 
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/ioport.h>
@@ -699,7 +698,7 @@ dispose_iface(struct device *dev)
 }
 
 static int
-create_iface_macio(struct macio_dev* dev, const struct of_match *match)
+create_iface_macio(struct macio_dev* dev, const struct of_device_id *match)
 {
 	return create_iface(dev->ofdev.node, &dev->ofdev.dev);
 }
@@ -711,7 +710,7 @@ dispose_iface_macio(struct macio_dev* de
 }
 
 static int
-create_iface_of_platform(struct of_device* dev, const struct of_match *match)
+create_iface_of_platform(struct of_device* dev, const struct of_device_id *match)
 {
 	return create_iface(dev->node, &dev->dev);
 }
@@ -722,10 +721,9 @@ dispose_iface_of_platform(struct of_devi
 	return dispose_iface(&dev->dev);
 }
 
-static struct of_match i2c_keywest_match[] = 
+static struct of_device_id i2c_keywest_match[] = 
 {
 	{
-	.name 		= OF_ANY_MATCH,
 	.type		= "i2c",
 	.compatible	= "keywest"
 	},
diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c
--- a/drivers/i2c/busses/i2c-mpc.c
+++ b/drivers/i2c/busses/i2c-mpc.c
@@ -20,13 +20,7 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <asm/io.h>
-#ifdef CONFIG_FSL_OCP
-#include <asm/ocp.h>
-#define FSL_I2C_DEV_SEPARATE_DFSRR FS_I2C_SEPARATE_DFSRR
-#define FSL_I2C_DEV_CLOCK_5200 FS_I2C_CLOCK_5200
-#else
 #include <linux/fsl_devices.h>
-#endif
 #include <linux/i2c.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
@@ -294,107 +288,6 @@ static struct i2c_adapter mpc_ops = {
 	.retries = 1
 };
 
-#ifdef CONFIG_FSL_OCP
-static int __devinit mpc_i2c_probe(struct ocp_device *ocp)
-{
-	int result = 0;
-	struct mpc_i2c *i2c;
-
-	if (!(i2c = kmalloc(sizeof(*i2c), GFP_KERNEL))) {
-		return -ENOMEM;
-	}
-	memset(i2c, 0, sizeof(*i2c));
-
-	i2c->irq = ocp->def->irq;
-	i2c->flags = ((struct ocp_fs_i2c_data *)ocp->def->additions)->flags;
-	init_waitqueue_head(&i2c->queue);
-
-	if (!request_mem_region(ocp->def->paddr, MPC_I2C_REGION, "i2c-mpc")) {
-		printk(KERN_ERR "i2c-mpc - resource unavailable\n");
-		return -ENODEV;
-	}
-
-	i2c->base = ioremap(ocp->def->paddr, MPC_I2C_REGION);
-
-	if (!i2c->base) {
-		printk(KERN_ERR "i2c-mpc - failed to map controller\n");
-		result = -ENOMEM;
-		goto fail_map;
-	}
-
-	if (i2c->irq != OCP_IRQ_NA)
-	{
-		if ((result = request_irq(ocp->def->irq, mpc_i2c_isr,
-					  0, "i2c-mpc", i2c)) < 0) {
-			printk(KERN_ERR
-			       "i2c-mpc - failed to attach interrupt\n");
-			goto fail_irq;
-		}
-	} else
-		i2c->irq = 0;
-
-	i2c->adap = mpc_ops;
-	i2c_set_adapdata(&i2c->adap, i2c);
-
-	if ((result = i2c_add_adapter(&i2c->adap)) < 0) {
-		printk(KERN_ERR "i2c-mpc - failed to add adapter\n");
-		goto fail_add;
-	}
-
-	mpc_i2c_setclock(i2c);
-	ocp_set_drvdata(ocp, i2c);
-	return result;
-
-      fail_add:
-	if (ocp->def->irq != OCP_IRQ_NA)
-		free_irq(ocp->def->irq, 0);
-      fail_irq:
-	iounmap(i2c->base);
-      fail_map:
-	release_mem_region(ocp->def->paddr, MPC_I2C_REGION);
-	kfree(i2c);
-	return result;
-}
-static void __devexit mpc_i2c_remove(struct ocp_device *ocp)
-{
-	struct mpc_i2c *i2c = ocp_get_drvdata(ocp);
-	ocp_set_drvdata(ocp, NULL);
-	i2c_del_adapter(&i2c->adap);
-
-	if (ocp->def->irq != OCP_IRQ_NA)
-		free_irq(i2c->irq, i2c);
-	iounmap(i2c->base);
-	release_mem_region(ocp->def->paddr, MPC_I2C_REGION);
-	kfree(i2c);
-}
-
-static struct ocp_device_id mpc_iic_ids[] __devinitdata = {
-	{.vendor = OCP_VENDOR_FREESCALE,.function = OCP_FUNC_IIC},
-	{.vendor = OCP_VENDOR_INVALID}
-};
-
-MODULE_DEVICE_TABLE(ocp, mpc_iic_ids);
-
-static struct ocp_driver mpc_iic_driver = {
-	.name = "iic",
-	.id_table = mpc_iic_ids,
-	.probe = mpc_i2c_probe,
-	.remove = __devexit_p(mpc_i2c_remove)
-};
-
-static int __init iic_init(void)
-{
-	return ocp_register_driver(&mpc_iic_driver);
-}
-
-static void __exit iic_exit(void)
-{
-	ocp_unregister_driver(&mpc_iic_driver);
-}
-
-module_init(iic_init);
-module_exit(iic_exit);
-#else
 static int fsl_i2c_probe(struct device *device)
 {
 	int result = 0;
@@ -424,12 +317,15 @@ static int fsl_i2c_probe(struct device *
 
 	if (i2c->irq != 0)
 		if ((result = request_irq(i2c->irq, mpc_i2c_isr,
-					  0, "fsl-i2c", i2c)) < 0) {
+					  SA_SHIRQ, "i2c-mpc", i2c)) < 0) {
 			printk(KERN_ERR
 			       "i2c-mpc - failed to attach interrupt\n");
 			goto fail_irq;
 		}
 
+	mpc_i2c_setclock(i2c);
+	dev_set_drvdata(device, i2c);
+
 	i2c->adap = mpc_ops;
 	i2c_set_adapdata(&i2c->adap, i2c);
 	i2c->adap.dev.parent = &pdev->dev;
@@ -438,8 +334,6 @@ static int fsl_i2c_probe(struct device *
 		goto fail_add;
 	}
 
-	mpc_i2c_setclock(i2c);
-	dev_set_drvdata(device, i2c);
 	return result;
 
       fail_add:
@@ -456,8 +350,8 @@ static int fsl_i2c_remove(struct device 
 {
 	struct mpc_i2c *i2c = dev_get_drvdata(device);
 
-	dev_set_drvdata(device, NULL);
 	i2c_del_adapter(&i2c->adap);
+	dev_set_drvdata(device, NULL);
 
 	if (i2c->irq != 0)
 		free_irq(i2c->irq, i2c);
@@ -488,8 +382,6 @@ static void __exit fsl_i2c_exit(void)
 module_init(fsl_i2c_init);
 module_exit(fsl_i2c_exit);
 
-#endif /* CONFIG_FSL_OCP */
-
 MODULE_AUTHOR("Adrian Cox <adrian@humboldt.co.uk>");
 MODULE_DESCRIPTION
     ("I2C-Bus adapter for MPC107 bridge and MPC824x/85xx/52xx processors");
diff --git a/drivers/i2c/busses/i2c-nforce2.c b/drivers/i2c/busses/i2c-nforce2.c
--- a/drivers/i2c/busses/i2c-nforce2.c
+++ b/drivers/i2c/busses/i2c-nforce2.c
@@ -37,7 +37,6 @@
 
 /* Note: we assume there can only be one nForce2, with two SMBus interfaces */
 
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/kernel.h>
diff --git a/drivers/i2c/busses/i2c-parport-light.c b/drivers/i2c/busses/i2c-parport-light.c
--- a/drivers/i2c/busses/i2c-parport-light.c
+++ b/drivers/i2c/busses/i2c-parport-light.c
@@ -24,7 +24,6 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  * ------------------------------------------------------------------------ */
 
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
diff --git a/drivers/i2c/busses/i2c-parport.c b/drivers/i2c/busses/i2c-parport.c
--- a/drivers/i2c/busses/i2c-parport.c
+++ b/drivers/i2c/busses/i2c-parport.c
@@ -24,7 +24,6 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  * ------------------------------------------------------------------------ */
 
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
@@ -131,7 +130,7 @@ static int parport_getsda(void *data)
 /* Encapsulate the functions above in the correct structure.
    Note that this is only a template, from which the real structures are
    copied. The attaching code will set getscl to NULL for adapters that
-   cannot read SCL back, and will also make the the data field point to
+   cannot read SCL back, and will also make the data field point to
    the parallel port structure. */
 static struct i2c_algo_bit_data parport_algo_data = {
 	.setsda		= parport_setsda,
diff --git a/drivers/i2c/busses/i2c-pca-isa.c b/drivers/i2c/busses/i2c-pca-isa.c
--- a/drivers/i2c/busses/i2c-pca-isa.c
+++ b/drivers/i2c/busses/i2c-pca-isa.c
@@ -17,7 +17,6 @@
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/ioport.h>
 #include <linux/module.h>
diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c
--- a/drivers/i2c/busses/i2c-piix4.c
+++ b/drivers/i2c/busses/i2c-piix4.c
@@ -28,7 +28,6 @@
    Note: we assume there can only be one device, with one SMBus interface.
 */
 
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/pci.h>
@@ -244,7 +243,7 @@ static int piix4_transaction(void)
 	/* Make sure the SMBus host is ready to start transmitting */
 	if ((temp = inb_p(SMBHSTSTS)) != 0x00) {
 		dev_dbg(&piix4_adapter.dev, "SMBus busy (%02x). "
-			"Resetting... \n", temp);
+			"Resetting...\n", temp);
 		outb_p(temp, SMBHSTSTS);
 		if ((temp = inb_p(SMBHSTSTS)) != 0x00) {
 			dev_err(&piix4_adapter.dev, "Failed! (%02x)\n", temp);
diff --git a/drivers/i2c/busses/i2c-prosavage.c b/drivers/i2c/busses/i2c-prosavage.c
--- a/drivers/i2c/busses/i2c-prosavage.c
+++ b/drivers/i2c/busses/i2c-prosavage.c
@@ -54,7 +54,6 @@
  *    (Additional documentation needed :(
  */
 
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/pci.h>
diff --git a/drivers/i2c/busses/i2c-rpx.c b/drivers/i2c/busses/i2c-rpx.c
--- a/drivers/i2c/busses/i2c-rpx.c
+++ b/drivers/i2c/busses/i2c-rpx.c
@@ -11,7 +11,6 @@
  * changed to eliminate RPXLite references.
  */
 
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c
--- a/drivers/i2c/busses/i2c-s3c2410.c
+++ b/drivers/i2c/busses/i2c-s3c2410.c
@@ -20,6 +20,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
 
+#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 
@@ -533,7 +534,7 @@ static int s3c24xx_i2c_doxfer(struct s3c
 /* s3c24xx_i2c_xfer
  *
  * first port of call from the i2c bus code when an message needs
- * transfering across the i2c bus.
+ * transferring across the i2c bus.
 */
 
 static int s3c24xx_i2c_xfer(struct i2c_adapter *adap,
diff --git a/drivers/i2c/busses/i2c-savage4.c b/drivers/i2c/busses/i2c-savage4.c
--- a/drivers/i2c/busses/i2c-savage4.c
+++ b/drivers/i2c/busses/i2c-savage4.c
@@ -29,7 +29,6 @@
    it easier to add later.
 */
 
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
diff --git a/drivers/i2c/busses/i2c-sibyte.c b/drivers/i2c/busses/i2c-sibyte.c
--- a/drivers/i2c/busses/i2c-sibyte.c
+++ b/drivers/i2c/busses/i2c-sibyte.c
@@ -17,15 +17,14 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/i2c-algo-sibyte.h>
 #include <asm/sibyte/sb1250_regs.h>
 #include <asm/sibyte/sb1250_smbus.h>
 
 static struct i2c_algo_sibyte_data sibyte_board_data[2] = {
-	{ NULL, 0, (void *) (KSEG1+A_SMB_BASE(0)) },
-	{ NULL, 1, (void *) (KSEG1+A_SMB_BASE(1)) }
+	{ NULL, 0, (void *) (CKSEG1+A_SMB_BASE(0)) },
+	{ NULL, 1, (void *) (CKSEG1+A_SMB_BASE(1)) }
 };
 
 static struct i2c_adapter sibyte_board_adapter[2] = {
diff --git a/drivers/i2c/busses/i2c-sis5595.c b/drivers/i2c/busses/i2c-sis5595.c
--- a/drivers/i2c/busses/i2c-sis5595.c
+++ b/drivers/i2c/busses/i2c-sis5595.c
@@ -55,7 +55,6 @@
  * Add adapter resets
  */
 
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/delay.h>
@@ -229,7 +228,7 @@ static int sis5595_transaction(struct i2
 	/* Make sure the SMBus host is ready to start transmitting */
 	temp = sis5595_read(SMB_STS_LO) + (sis5595_read(SMB_STS_HI) << 8);
 	if (temp != 0x00) {
-		dev_dbg(&adap->dev, "SMBus busy (%04x). Resetting... \n", temp);
+		dev_dbg(&adap->dev, "SMBus busy (%04x). Resetting...\n", temp);
 		sis5595_write(SMB_STS_LO, temp & 0xff);
 		sis5595_write(SMB_STS_HI, temp >> 8);
 		if ((temp = sis5595_read(SMB_STS_LO) + (sis5595_read(SMB_STS_HI) << 8)) != 0x00) {
diff --git a/drivers/i2c/busses/i2c-sis630.c b/drivers/i2c/busses/i2c-sis630.c
--- a/drivers/i2c/busses/i2c-sis630.c
+++ b/drivers/i2c/busses/i2c-sis630.c
@@ -48,7 +48,6 @@
    Note: we assume there can only be one device, with one SMBus interface.
 */
 
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/delay.h>
diff --git a/drivers/i2c/busses/i2c-sis96x.c b/drivers/i2c/busses/i2c-sis96x.c
--- a/drivers/i2c/busses/i2c-sis96x.c
+++ b/drivers/i2c/busses/i2c-sis96x.c
@@ -32,7 +32,6 @@
     We assume there can only be one SiS96x with one SMBus interface.
 */
 
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/kernel.h>
diff --git a/drivers/i2c/busses/i2c-stub.c b/drivers/i2c/busses/i2c-stub.c
--- a/drivers/i2c/busses/i2c-stub.c
+++ b/drivers/i2c/busses/i2c-stub.c
@@ -21,7 +21,6 @@
 
 #define DEBUG 1
 
-#include <linux/config.h>
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
diff --git a/drivers/i2c/busses/i2c-via.c b/drivers/i2c/busses/i2c-via.c
--- a/drivers/i2c/busses/i2c-via.c
+++ b/drivers/i2c/busses/i2c-via.c
@@ -21,7 +21,6 @@
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/pci.h>
diff --git a/drivers/i2c/busses/i2c-viapro.c b/drivers/i2c/busses/i2c-viapro.c
--- a/drivers/i2c/busses/i2c-viapro.c
+++ b/drivers/i2c/busses/i2c-viapro.c
@@ -33,7 +33,6 @@
    Note: we assume there can only be one device, with one SMBus interface.
 */
 
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/delay.h>
 #include <linux/pci.h>
diff --git a/drivers/i2c/busses/i2c-voodoo3.c b/drivers/i2c/busses/i2c-voodoo3.c
--- a/drivers/i2c/busses/i2c-voodoo3.c
+++ b/drivers/i2c/busses/i2c-voodoo3.c
@@ -27,7 +27,6 @@
 /* This interfaces to the I2C bus of the Voodoo3 to gain access to
     the BT869 and possibly other I2C devices. */
 
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
diff --git a/drivers/i2c/busses/scx200_acb.c b/drivers/i2c/busses/scx200_acb.c
--- a/drivers/i2c/busses/scx200_acb.c
+++ b/drivers/i2c/busses/scx200_acb.c
@@ -24,7 +24,6 @@
 
 */
 
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/errno.h>
 #include <linux/kernel.h>
diff --git a/drivers/i2c/chips/Kconfig b/drivers/i2c/chips/Kconfig
--- a/drivers/i2c/chips/Kconfig
+++ b/drivers/i2c/chips/Kconfig
@@ -1,380 +1,35 @@
 #
-# I2C Sensor device configuration
+# Miscellaneous I2C chip drivers configuration
 #
 
-menu "Hardware Sensors Chip support"
-	depends on I2C
-
 config I2C_SENSOR
 	tristate
 	default n
 
-config SENSORS_ADM1021
-	tristate "Analog Devices ADM1021 and compatibles"
-	depends on I2C && EXPERIMENTAL
-	select I2C_SENSOR
-	help
-	  If you say yes here you get support for Analog Devices ADM1021 
-	  and ADM1023 sensor chips and clones: Maxim MAX1617 and MAX1617A,
-	  Genesys Logic GL523SM, National Semiconductor LM84, TI THMC10,
-	  and the XEON processor built-in sensor.
-
-	  This driver can also be built as a module.  If so, the module
-	  will be called adm1021.
-
-config SENSORS_ADM1025
-	tristate "Analog Devices ADM1025 and compatibles"
-	depends on I2C && EXPERIMENTAL
-	select I2C_SENSOR
-	help
-	  If you say yes here you get support for Analog Devices ADM1025
-	  and Philips NE1619 sensor chips.
-	  This driver can also be built as a module.  If so, the module
-	  will be called adm1025.
-
-config SENSORS_ADM1026
-	tristate "Analog Devices ADM1026 and compatibles"
-	depends on I2C && EXPERIMENTAL
-	select I2C_SENSOR
-	help
-	  If you say yes here you get support for Analog Devices ADM1026
-	  This driver can also be built as a module.  If so, the module
-	  will be called adm1026.
-
-config SENSORS_ADM1031
-	tristate "Analog Devices ADM1031 and compatibles"
-	depends on I2C && EXPERIMENTAL
-	select I2C_SENSOR
-	help
-	  If you say yes here you get support for Analog Devices ADM1031 
-	  and ADM1030 sensor chips.
-	  This driver can also be built as a module.  If so, the module
-	  will be called adm1031.
-
-config SENSORS_ASB100
-	tristate "Asus ASB100 Bach"
-	depends on I2C && EXPERIMENTAL
-	select I2C_SENSOR
-	help
-	  If you say yes here you get support for the ASB100 Bach sensor
-	  chip found on some Asus mainboards.
-
-	  This driver can also be built as a module.  If so, the module
-	  will be called asb100.
-
-config SENSORS_DS1621
-	tristate "Dallas Semiconductor DS1621 and DS1625"
-	depends on I2C && EXPERIMENTAL
-	select I2C_SENSOR
-	help
-	  If you say yes here you get support for Dallas Semiconductor
-	  DS1621 and DS1625 sensor chips. 
-
-	  This driver can also be built as a module.  If so, the module
-	  will be called ds1621.
-
-config SENSORS_FSCHER
-	tristate "FSC Hermes"
-	depends on I2C && EXPERIMENTAL
-	select I2C_SENSOR
-	help
-	  If you say yes here you get support for Fujitsu Siemens
-	  Computers Hermes sensor chips.
-
-	  This driver can also be built as a module.  If so, the module
-	  will be called fscher.
-
-config SENSORS_FSCPOS
-	tristate "FSC Poseidon"
-	depends on I2C && EXPERIMENTAL
-	select I2C_SENSOR
-	help
-	  If you say yes here you get support for Fujitsu Siemens
-	  Computers Poseidon sensor chips.
-
-	  This driver can also be built as a module.  If so, the module
-	  will be called fscpos.
-
-config SENSORS_GL518SM
-	tristate "Genesys Logic GL518SM"
-	depends on I2C && EXPERIMENTAL
-	select I2C_SENSOR
-	help
-	  If you say yes here you get support for Genesys Logic GL518SM
-	  sensor chips.
-
-	  This driver can also be built as a module.  If so, the module
-	  will be called gl518sm.
-
-config SENSORS_GL520SM
-	tristate "Genesys Logic GL520SM"
-	depends on I2C && EXPERIMENTAL
-	select I2C_SENSOR
-	help
-	  If you say yes here you get support for Genesys Logic GL520SM
-	  sensor chips.
-
-	  This driver can also be built as a module.  If so, the module
-	  will be called gl520sm.
-
-config SENSORS_IT87
-	tristate "ITE IT87xx and compatibles"
-	depends on I2C && EXPERIMENTAL
-	select I2C_SENSOR
-	help
-	  If you say yes here you get support for ITE IT87xx sensor chips
-	  and clones: SiS960.
-
-	  This driver can also be built as a module.  If so, the module
-	  will be called it87.
-
-config SENSORS_LM63
-	tristate "National Semiconductor LM63"
-	depends on I2C && EXPERIMENTAL
-	select I2C_SENSOR
-	help
-	  If you say yes here you get support for the National Semiconductor
-	  LM63 remote diode digital temperature sensor with integrated fan
-	  control.  Such chips are found on the Tyan S4882 (Thunder K8QS Pro)
-	  motherboard, among others.
-
-	  This driver can also be built as a module.  If so, the module
-	  will be called lm63.
-
-config SENSORS_LM75
-	tristate "National Semiconductor LM75 and compatibles"
-	depends on I2C && EXPERIMENTAL
-	select I2C_SENSOR
-	help
-	  If you say yes here you get support for National Semiconductor LM75
-	  sensor chips and clones: Dallas Semiconductor DS75 and DS1775 (in
-	  9-bit precision mode), and TelCom (now Microchip) TCN75.
-
-	  The DS75 and DS1775 in 10- to 12-bit precision modes will require
-	  a force module parameter. The driver will not handle the extra
-	  precision anyhow.
-
-	  This driver can also be built as a module.  If so, the module
-	  will be called lm75.
-
-config SENSORS_LM77
-	tristate "National Semiconductor LM77"
-	depends on I2C && EXPERIMENTAL
-	select I2C_SENSOR
-	help
-	  If you say yes here you get support for National Semiconductor LM77
-	  sensor chips.
-
-	  This driver can also be built as a module.  If so, the module
-	  will be called lm77.
-
-config SENSORS_LM78
-	tristate "National Semiconductor LM78 and compatibles"
-	depends on I2C && EXPERIMENTAL
-	select I2C_SENSOR
-	help
-	  If you say yes here you get support for National Semiconductor LM78,
-	  LM78-J and LM79.  This can also be built as a module which can be
-	  inserted and removed while the kernel is running.
-
-	  This driver can also be built as a module.  If so, the module
-	  will be called lm78.
-
-config SENSORS_LM80
-	tristate "National Semiconductor LM80"
-	depends on I2C && EXPERIMENTAL
-	select I2C_SENSOR
-	help
-	  If you say yes here you get support for National Semiconductor
-	  LM80 sensor chips.
-
-	  This driver can also be built as a module.  If so, the module
-	  will be called lm80.
-
-config SENSORS_LM83
-	tristate "National Semiconductor LM83"
-	depends on I2C
-	select I2C_SENSOR
-	help
-	  If you say yes here you get support for National Semiconductor
-	  LM83 sensor chips.
-
-	  This driver can also be built as a module.  If so, the module
-	  will be called lm83.
-
-config SENSORS_LM85
-	tristate "National Semiconductor LM85 and compatibles"
-	depends on I2C && EXPERIMENTAL
-	select I2C_SENSOR
-	help
-	  If you say yes here you get support for National Semiconductor LM85
-	  sensor chips and clones: ADT7463 and ADM1027.
-
-	  This driver can also be built as a module.  If so, the module
-	  will be called lm85.
-
-config SENSORS_LM87
-	tristate "National Semiconductor LM87"
-	depends on I2C && EXPERIMENTAL
-	select I2C_SENSOR
-	help
-	  If you say yes here you get support for National Semiconductor LM87
-	  sensor chips.
-
-	  This driver can also be built as a module.  If so, the module
-	  will be called lm87.
-
-config SENSORS_LM90
-	tristate "National Semiconductor LM90 and compatibles"
+menu "Miscellaneous I2C Chip support"
 	depends on I2C
-	select I2C_SENSOR
-	help
-	  If you say yes here you get support for National Semiconductor LM90,
-	  LM86, LM89 and LM99, Analog Devices ADM1032 and Maxim MAX6657 and
-	  MAX6658 sensor chips.
-
-	  The Analog Devices ADT7461 sensor chip is also supported, but only
-	  if found in ADM1032 compatibility mode.
-
-	  This driver can also be built as a module.  If so, the module
-	  will be called lm90.
-
-config SENSORS_LM92
-	tristate "National Semiconductor LM92 and compatibles"
-	depends on I2C && EXPERIMENTAL
-	select I2C_SENSOR
-	help
-	  If you say yes here you get support for National Semiconductor LM92
-	  and Maxim MAX6635 sensor chips.
-
-	  This driver can also be built as a module.  If so, the module
-	  will be called lm92.
-
-config SENSORS_MAX1619
-	tristate "Maxim MAX1619 sensor chip"
-	depends on I2C && EXPERIMENTAL
-	select I2C_SENSOR
-	help
-	  If you say yes here you get support for MAX1619 sensor chip.
-	  
-	  This driver can also be built as a module.  If so, the module
-	  will be called max1619.
-
-config SENSORS_PC87360
-	tristate "National Semiconductor PC87360 family"
-	depends on I2C && EXPERIMENTAL
-	select I2C_SENSOR
-	select I2C_ISA
-	help
-	  If you say yes here you get access to the hardware monitoring
-	  functions of the National Semiconductor PC8736x Super-I/O chips.
-	  The PC87360, PC87363 and PC87364 only have fan monitoring and
-	  control.  The PC87365 and PC87366 additionally have voltage and
-	  temperature monitoring.
-
-	  This driver can also be built as a module.  If so, the module
-	  will be called pc87360.
-
-config SENSORS_SMSC47B397
-	tristate "SMSC LPC47B397-NC"
-	depends on I2C && EXPERIMENTAL
-	select I2C_SENSOR
-	select I2C_ISA
-	help
-	  If you say yes here you get support for the SMSC LPC47B397-NC
-	  sensor chip.
-
-	  This driver can also be built as a module.  If so, the module
-	  will be called smsc47b397.
-
-config SENSORS_SIS5595
-	tristate "Silicon Integrated Systems Corp. SiS5595"
-	depends on I2C && PCI && EXPERIMENTAL
-	select I2C_SENSOR
-	select I2C_ISA
-	help
-	  If you say yes here you get support for the integrated sensors in
-	  SiS5595 South Bridges.
 
-	  This driver can also be built as a module.  If so, the module
-	  will be called sis5595.
-
-config SENSORS_SMSC47M1
-	tristate "SMSC LPC47M10x and compatibles"
-	depends on I2C && EXPERIMENTAL
-	select I2C_SENSOR
-	select I2C_ISA
-	help
-	  If you say yes here you get support for the integrated fan
-	  monitoring and control capabilities of the SMSC LPC47B27x,
-	  LPC47M10x, LPC47M13x and LPC47M14x chips.
-
-	  This driver can also be built as a module.  If so, the module
-	  will be called smsc47m1.
-
-config SENSORS_VIA686A
-	tristate "VIA686A"
-	depends on I2C && PCI && EXPERIMENTAL
-	select I2C_SENSOR
-	select I2C_ISA
-	help
-	  If you say yes here you get support for the integrated sensors in
-	  Via 686A/B South Bridges.
-
-	  This driver can also be built as a module.  If so, the module
-	  will be called via686a.
-
-config SENSORS_W83781D
-	tristate "Winbond W83781D, W83782D, W83783S, W83627HF, Asus AS99127F"
-	depends on I2C && EXPERIMENTAL
-	select I2C_SENSOR
-	help
-	  If you say yes here you get support for the Winbond W8378x series
-	  of sensor chips: the W83781D, W83782D, W83783S and W83627HF,
-	  and the similar Asus AS99127F.
-	  
-	  This driver can also be built as a module.  If so, the module
-	  will be called w83781d.
-
-config SENSORS_W83L785TS
-	tristate "Winbond W83L785TS-S"
-	depends on I2C && EXPERIMENTAL
-	select I2C_SENSOR
-	help
-	  If you say yes here you get support for the Winbond W83L785TS-S
-	  sensor chip, which is used on the Asus A7N8X, among other
-	  motherboards.
-	  
-	  This driver can also be built as a module.  If so, the module
-	  will be called w83l785ts.
-
-config SENSORS_W83627HF
-	tristate "Winbond W83627HF, W83627THF, W83637HF, W83697HF"
+config SENSORS_DS1337
+	tristate "Dallas Semiconductor DS1337 and DS1339 Real Time Clock"
 	depends on I2C && EXPERIMENTAL
 	select I2C_SENSOR
-	select I2C_ISA
 	help
-	  If you say yes here you get support for the Winbond W836X7 series
-	  of sensor chips: the W83627HF, W83627THF, W83637HF, and the W83697HF
+	  If you say yes here you get support for Dallas Semiconductor
+	  DS1337 and DS1339 real-time clock chips.
 
 	  This driver can also be built as a module.  If so, the module
-	  will be called w83627hf.
-
-endmenu
-
-menu "Other I2C Chip support"
-	depends on I2C
+	  will be called ds1337.
 
-config SENSORS_DS1337
-	tristate "Dallas Semiconductor DS1337 Real Time Clock"
+config SENSORS_DS1374
+	tristate "Maxim/Dallas Semiconductor DS1374 Real Time Clock"
 	depends on I2C && EXPERIMENTAL
 	select I2C_SENSOR
 	help
 	  If you say yes here you get support for Dallas Semiconductor
-	  DS1337 real-time clock chips. 
+	  DS1374 real-time clock chips.
 
 	  This driver can also be built as a module.  If so, the module
-	  will be called ds1337.
+	  will be called ds1374.
 
 config SENSORS_EEPROM
 	tristate "EEPROM reader"
@@ -399,6 +54,16 @@ config SENSORS_PCF8574
 	  This driver can also be built as a module.  If so, the module
 	  will be called pcf8574.
 
+config SENSORS_PCA9539
+	tristate "Philips PCA9539 16-bit I/O port"
+	depends on I2C && EXPERIMENTAL
+	help
+	  If you say yes here you get support for the Philips PCA9539
+	  16-bit I/O port.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called pca9539.
+
 config SENSORS_PCF8591
 	tristate "Philips PCF8591"
 	depends on I2C && EXPERIMENTAL
@@ -431,6 +96,22 @@ config ISP1301_OMAP
 	  This driver can also be built as a module.  If so, the module
 	  will be called isp1301_omap.
 
+# NOTE:  This isn't really OMAP-specific, except for the current
+# interface location in  <include/asm-arm/arch-omap/tps65010.h>
+# and having mostly OMAP-specific board support
+config TPS65010
+	tristate "TPS6501x Power Management chips"
+	depends on I2C && ARCH_OMAP
+	default y if MACH_OMAP_H2 || MACH_OMAP_H3 || MACH_OMAP_OSK
+	help
+	  If you say yes here you get support for the TPS6501x series of
+	  Power Management chips.  These include voltage regulators,
+	  lithium ion/polymer battery charging, and other features that
+	  are often used in portable devices like cell phones and cameras.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called tps65010.
+
 config SENSORS_M41T00
 	tristate "ST M41T00 RTC chip"
 	depends on I2C && PPC32
@@ -440,4 +121,19 @@ config SENSORS_M41T00
 	  This driver can also be built as a module.  If so, the module
 	  will be called m41t00.
 
+config SENSORS_MAX6875
+	tristate "Maxim MAX6875 Power supply supervisor"
+	depends on I2C && EXPERIMENTAL
+	help
+	  If you say yes here you get support for the Maxim MAX6875
+	  EEPROM-programmable, quad power-supply sequencer/supervisor.
+
+	  This provides an interface to program the EEPROM and reset the chip.
+
+	  This driver also supports the Maxim MAX6874 hex power-supply
+	  sequencer/supervisor if found at a compatible address.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called max6875.
+
 endmenu
diff --git a/drivers/i2c/chips/Makefile b/drivers/i2c/chips/Makefile
--- a/drivers/i2c/chips/Makefile
+++ b/drivers/i2c/chips/Makefile
@@ -1,46 +1,18 @@
 #
-# Makefile for the kernel hardware sensors chip drivers.
+# Makefile for miscellaneous I2C chip drivers.
 #
 
-# asb100, then w83781d go first, as they can override other drivers' addresses.
-obj-$(CONFIG_SENSORS_ASB100)	+= asb100.o
-obj-$(CONFIG_SENSORS_W83627HF)	+= w83627hf.o
-obj-$(CONFIG_SENSORS_W83781D)	+= w83781d.o
-
-obj-$(CONFIG_SENSORS_ADM1021)	+= adm1021.o
-obj-$(CONFIG_SENSORS_ADM1025)	+= adm1025.o
-obj-$(CONFIG_SENSORS_ADM1026)	+= adm1026.o
-obj-$(CONFIG_SENSORS_ADM1031)	+= adm1031.o
 obj-$(CONFIG_SENSORS_DS1337)	+= ds1337.o
-obj-$(CONFIG_SENSORS_DS1621)	+= ds1621.o
+obj-$(CONFIG_SENSORS_DS1374)	+= ds1374.o
 obj-$(CONFIG_SENSORS_EEPROM)	+= eeprom.o
-obj-$(CONFIG_SENSORS_FSCHER)	+= fscher.o
-obj-$(CONFIG_SENSORS_FSCPOS)	+= fscpos.o
-obj-$(CONFIG_SENSORS_GL518SM)	+= gl518sm.o
-obj-$(CONFIG_SENSORS_GL520SM)	+= gl520sm.o
-obj-$(CONFIG_SENSORS_IT87)	+= it87.o
-obj-$(CONFIG_SENSORS_LM63)	+= lm63.o
-obj-$(CONFIG_SENSORS_LM75)	+= lm75.o
-obj-$(CONFIG_SENSORS_LM77)	+= lm77.o
-obj-$(CONFIG_SENSORS_LM78)	+= lm78.o
-obj-$(CONFIG_SENSORS_LM80)	+= lm80.o
-obj-$(CONFIG_SENSORS_LM83)	+= lm83.o
-obj-$(CONFIG_SENSORS_LM85)	+= lm85.o
-obj-$(CONFIG_SENSORS_LM87)	+= lm87.o
-obj-$(CONFIG_SENSORS_LM90)	+= lm90.o
-obj-$(CONFIG_SENSORS_LM92)	+= lm92.o
-obj-$(CONFIG_SENSORS_MAX1619)	+= max1619.o
+obj-$(CONFIG_SENSORS_MAX6875)	+= max6875.o
 obj-$(CONFIG_SENSORS_M41T00)	+= m41t00.o
-obj-$(CONFIG_SENSORS_PC87360)	+= pc87360.o
+obj-$(CONFIG_SENSORS_PCA9539)	+= pca9539.o
 obj-$(CONFIG_SENSORS_PCF8574)	+= pcf8574.o
 obj-$(CONFIG_SENSORS_PCF8591)	+= pcf8591.o
 obj-$(CONFIG_SENSORS_RTC8564)	+= rtc8564.o
-obj-$(CONFIG_SENSORS_SIS5595)	+= sis5595.o
-obj-$(CONFIG_SENSORS_SMSC47B397)+= smsc47b397.o
-obj-$(CONFIG_SENSORS_SMSC47M1)	+= smsc47m1.o
-obj-$(CONFIG_SENSORS_VIA686A)	+= via686a.o
-obj-$(CONFIG_SENSORS_W83L785TS)	+= w83l785ts.o
 obj-$(CONFIG_ISP1301_OMAP)	+= isp1301_omap.o
+obj-$(CONFIG_TPS65010)		+= tps65010.o
 
 ifeq ($(CONFIG_I2C_DEBUG_CHIP),y)
 EXTRA_CFLAGS += -DDEBUG
diff --git a/drivers/i2c/chips/adm1021.c b/drivers/i2c/chips/adm1021.c
deleted file mode 100644
--- a/drivers/i2c/chips/adm1021.c
+++ /dev/null
@@ -1,411 +0,0 @@
-/*
-    adm1021.c - Part of lm_sensors, Linux kernel modules for hardware
-             monitoring
-    Copyright (c) 1998, 1999  Frodo Looijaard <frodol@dds.nl> and
-    Philip Edelbrock <phil@netroedge.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., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/jiffies.h>
-#include <linux/i2c.h>
-#include <linux/i2c-sensor.h>
-
-
-/* Addresses to scan */
-static unsigned short normal_i2c[] = { 0x18, 0x19, 0x1a,
-					0x29, 0x2a, 0x2b,
-					0x4c, 0x4d, 0x4e, 
-					I2C_CLIENT_END };
-static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
-
-/* Insmod parameters */
-SENSORS_INSMOD_8(adm1021, adm1023, max1617, max1617a, thmc10, lm84, gl523sm, mc1066);
-
-/* adm1021 constants specified below */
-
-/* The adm1021 registers */
-/* Read-only */
-#define ADM1021_REG_TEMP		0x00
-#define ADM1021_REG_REMOTE_TEMP		0x01
-#define ADM1021_REG_STATUS		0x02
-#define ADM1021_REG_MAN_ID		0x0FE	/* 0x41 = AMD, 0x49 = TI, 0x4D = Maxim, 0x23 = Genesys , 0x54 = Onsemi*/
-#define ADM1021_REG_DEV_ID		0x0FF	/* ADM1021 = 0x0X, ADM1023 = 0x3X */
-#define ADM1021_REG_DIE_CODE		0x0FF	/* MAX1617A */
-/* These use different addresses for reading/writing */
-#define ADM1021_REG_CONFIG_R		0x03
-#define ADM1021_REG_CONFIG_W		0x09
-#define ADM1021_REG_CONV_RATE_R		0x04
-#define ADM1021_REG_CONV_RATE_W		0x0A
-/* These are for the ADM1023's additional precision on the remote temp sensor */
-#define ADM1021_REG_REM_TEMP_PREC	0x010
-#define ADM1021_REG_REM_OFFSET		0x011
-#define ADM1021_REG_REM_OFFSET_PREC	0x012
-#define ADM1021_REG_REM_TOS_PREC	0x013
-#define ADM1021_REG_REM_THYST_PREC	0x014
-/* limits */
-#define ADM1021_REG_TOS_R		0x05
-#define ADM1021_REG_TOS_W		0x0B
-#define ADM1021_REG_REMOTE_TOS_R	0x07
-#define ADM1021_REG_REMOTE_TOS_W	0x0D
-#define ADM1021_REG_THYST_R		0x06
-#define ADM1021_REG_THYST_W		0x0C
-#define ADM1021_REG_REMOTE_THYST_R	0x08
-#define ADM1021_REG_REMOTE_THYST_W	0x0E
-/* write-only */
-#define ADM1021_REG_ONESHOT		0x0F
-
-
-/* Conversions. Rounding and limit checking is only done on the TO_REG
-   variants. Note that you should be a bit careful with which arguments
-   these macros are called: arguments may be evaluated more than once.
-   Fixing this is just not worth it. */
-/* Conversions  note: 1021 uses normal integer signed-byte format*/
-#define TEMP_FROM_REG(val)	(val > 127 ? (val-256)*1000 : val*1000)
-#define TEMP_TO_REG(val)	(SENSORS_LIMIT((val < 0 ? (val/1000)+256 : val/1000),0,255))
-
-/* Initial values */
-
-/* Note: Even though I left the low and high limits named os and hyst, 
-they don't quite work like a thermostat the way the LM75 does.  I.e., 
-a lower temp than THYST actually triggers an alarm instead of 
-clearing it.  Weird, ey?   --Phil  */
-
-/* Each client has this additional data */
-struct adm1021_data {
-	struct i2c_client client;
-	enum chips type;
-
-	struct semaphore update_lock;
-	char valid;		/* !=0 if following fields are valid */
-	unsigned long last_updated;	/* In jiffies */
-
-	u8	temp_max;	/* Register values */
-	u8	temp_hyst;
-	u8	temp_input;
-	u8	remote_temp_max;
-	u8	remote_temp_hyst;
-	u8	remote_temp_input;
-	u8	alarms;
-	/* special values for ADM1021 only */
-	u8	die_code;
-        /* Special values for ADM1023 only */
-	u8	remote_temp_prec;
-	u8	remote_temp_os_prec;
-	u8	remote_temp_hyst_prec;
-	u8	remote_temp_offset;
-	u8	remote_temp_offset_prec;
-};
-
-static int adm1021_attach_adapter(struct i2c_adapter *adapter);
-static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind);
-static void adm1021_init_client(struct i2c_client *client);
-static int adm1021_detach_client(struct i2c_client *client);
-static int adm1021_read_value(struct i2c_client *client, u8 reg);
-static int adm1021_write_value(struct i2c_client *client, u8 reg,
-			       u16 value);
-static struct adm1021_data *adm1021_update_device(struct device *dev);
-
-/* (amalysh) read only mode, otherwise any limit's writing confuse BIOS */
-static int read_only = 0;
-
-
-/* This is the driver that will be inserted */
-static struct i2c_driver adm1021_driver = {
-	.owner		= THIS_MODULE,
-	.name		= "adm1021",
-	.id		= I2C_DRIVERID_ADM1021,
-	.flags		= I2C_DF_NOTIFY,
-	.attach_adapter	= adm1021_attach_adapter,
-	.detach_client	= adm1021_detach_client,
-};
-
-#define show(value)	\
-static ssize_t show_##value(struct device *dev, char *buf)		\
-{									\
-	struct adm1021_data *data = adm1021_update_device(dev);		\
-	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->value));	\
-}
-show(temp_max);
-show(temp_hyst);
-show(temp_input);
-show(remote_temp_max);
-show(remote_temp_hyst);
-show(remote_temp_input);
-
-#define show2(value)	\
-static ssize_t show_##value(struct device *dev, char *buf)		\
-{									\
-	struct adm1021_data *data = adm1021_update_device(dev);		\
-	return sprintf(buf, "%d\n", data->value);			\
-}
-show2(alarms);
-show2(die_code);
-
-#define set(value, reg)	\
-static ssize_t set_##value(struct device *dev, const char *buf, size_t count)	\
-{								\
-	struct i2c_client *client = to_i2c_client(dev);		\
-	struct adm1021_data *data = i2c_get_clientdata(client);	\
-	int temp = simple_strtoul(buf, NULL, 10);		\
-								\
-	down(&data->update_lock);				\
-	data->value = TEMP_TO_REG(temp);			\
-	adm1021_write_value(client, reg, data->value);		\
-	up(&data->update_lock);					\
-	return count;						\
-}
-set(temp_max, ADM1021_REG_TOS_W);
-set(temp_hyst, ADM1021_REG_THYST_W);
-set(remote_temp_max, ADM1021_REG_REMOTE_TOS_W);
-set(remote_temp_hyst, ADM1021_REG_REMOTE_THYST_W);
-
-static DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp_max, set_temp_max);
-static DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, show_temp_hyst, set_temp_hyst);
-static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp_input, NULL);
-static DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_remote_temp_max, set_remote_temp_max);
-static DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_remote_temp_hyst, set_remote_temp_hyst);
-static DEVICE_ATTR(temp2_input, S_IRUGO, show_remote_temp_input, NULL);
-static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
-static DEVICE_ATTR(die_code, S_IRUGO, show_die_code, NULL);
-
-
-static int adm1021_attach_adapter(struct i2c_adapter *adapter)
-{
-	if (!(adapter->class & I2C_CLASS_HWMON))
-		return 0;
-	return i2c_detect(adapter, &addr_data, adm1021_detect);
-}
-
-static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind)
-{
-	int i;
-	struct i2c_client *new_client;
-	struct adm1021_data *data;
-	int err = 0;
-	const char *type_name = "";
-
-	/* Make sure we aren't probing the ISA bus!! This is just a safety check
-	   at this moment; i2c_detect really won't call us. */
-#ifdef DEBUG
-	if (i2c_is_isa_adapter(adapter)) {
-		dev_dbg(&adapter->dev, "adm1021_detect called for an ISA bus adapter?!?\n");
-		return 0;
-	}
-#endif
-
-	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
-		goto error0;
-
-	/* OK. For now, we presume we have a valid client. We now create the
-	   client structure, even though we cannot fill it completely yet.
-	   But it allows us to access adm1021_{read,write}_value. */
-
-	if (!(data = kmalloc(sizeof(struct adm1021_data), GFP_KERNEL))) {
-		err = -ENOMEM;
-		goto error0;
-	}
-	memset(data, 0, sizeof(struct adm1021_data));
-
-	new_client = &data->client;
-	i2c_set_clientdata(new_client, data);
-	new_client->addr = address;
-	new_client->adapter = adapter;
-	new_client->driver = &adm1021_driver;
-	new_client->flags = 0;
-
-	/* Now, we do the remaining detection. */
-	if (kind < 0) {
-		if ((adm1021_read_value(new_client, ADM1021_REG_STATUS) & 0x03) != 0x00
-		 || (adm1021_read_value(new_client, ADM1021_REG_CONFIG_R) & 0x3F) != 0x00
-		 || (adm1021_read_value(new_client, ADM1021_REG_CONV_RATE_R) & 0xF8) != 0x00) {
-			err = -ENODEV;
-			goto error1;
-		}
-	}
-
-	/* Determine the chip type. */
-	if (kind <= 0) {
-		i = adm1021_read_value(new_client, ADM1021_REG_MAN_ID);
-		if (i == 0x41)
-			if ((adm1021_read_value(new_client, ADM1021_REG_DEV_ID) & 0x0F0) == 0x030)
-				kind = adm1023;
-			else
-				kind = adm1021;
-		else if (i == 0x49)
-			kind = thmc10;
-		else if (i == 0x23)
-			kind = gl523sm;
-		else if ((i == 0x4d) &&
-			 (adm1021_read_value(new_client, ADM1021_REG_DEV_ID) == 0x01))
-			kind = max1617a;
-		else if (i == 0x54)
-			kind = mc1066;
-		/* LM84 Mfr ID in a different place, and it has more unused bits */
-		else if (adm1021_read_value(new_client, ADM1021_REG_CONV_RATE_R) == 0x00
-		      && (kind == 0 /* skip extra detection */
-		       || ((adm1021_read_value(new_client, ADM1021_REG_CONFIG_R) & 0x7F) == 0x00
-			&& (adm1021_read_value(new_client, ADM1021_REG_STATUS) & 0xAB) == 0x00)))
-			kind = lm84;
-		else
-			kind = max1617;
-	}
-
-	if (kind == max1617) {
-		type_name = "max1617";
-	} else if (kind == max1617a) {
-		type_name = "max1617a";
-	} else if (kind == adm1021) {
-		type_name = "adm1021";
-	} else if (kind == adm1023) {
-		type_name = "adm1023";
-	} else if (kind == thmc10) {
-		type_name = "thmc10";
-	} else if (kind == lm84) {
-		type_name = "lm84";
-	} else if (kind == gl523sm) {
-		type_name = "gl523sm";
-	} else if (kind == mc1066) {
-		type_name = "mc1066";
-	}
-
-	/* Fill in the remaining client fields and put it into the global list */
-	strlcpy(new_client->name, type_name, I2C_NAME_SIZE);
-	data->type = kind;
-	data->valid = 0;
-	init_MUTEX(&data->update_lock);
-
-	/* Tell the I2C layer a new client has arrived */
-	if ((err = i2c_attach_client(new_client)))
-		goto error1;
-
-	/* Initialize the ADM1021 chip */
-	if (kind != lm84)
-		adm1021_init_client(new_client);
-
-	/* Register sysfs hooks */
-	device_create_file(&new_client->dev, &dev_attr_temp1_max);
-	device_create_file(&new_client->dev, &dev_attr_temp1_min);
-	device_create_file(&new_client->dev, &dev_attr_temp1_input);
-	device_create_file(&new_client->dev, &dev_attr_temp2_max);
-	device_create_file(&new_client->dev, &dev_attr_temp2_min);
-	device_create_file(&new_client->dev, &dev_attr_temp2_input);
-	device_create_file(&new_client->dev, &dev_attr_alarms);
-	if (data->type == adm1021)
-		device_create_file(&new_client->dev, &dev_attr_die_code);
-
-	return 0;
-
-error1:
-	kfree(data);
-error0:
-	return err;
-}
-
-static void adm1021_init_client(struct i2c_client *client)
-{
-	/* Enable ADC and disable suspend mode */
-	adm1021_write_value(client, ADM1021_REG_CONFIG_W,
-		adm1021_read_value(client, ADM1021_REG_CONFIG_R) & 0xBF);
-	/* Set Conversion rate to 1/sec (this can be tinkered with) */
-	adm1021_write_value(client, ADM1021_REG_CONV_RATE_W, 0x04);
-}
-
-static int adm1021_detach_client(struct i2c_client *client)
-{
-	int err;
-
-	if ((err = i2c_detach_client(client))) {
-		dev_err(&client->dev, "Client deregistration failed, client not detached.\n");
-		return err;
-	}
-
-	kfree(i2c_get_clientdata(client));
-	return 0;
-}
-
-/* All registers are byte-sized */
-static int adm1021_read_value(struct i2c_client *client, u8 reg)
-{
-	return i2c_smbus_read_byte_data(client, reg);
-}
-
-static int adm1021_write_value(struct i2c_client *client, u8 reg, u16 value)
-{
-	if (!read_only)
-		return i2c_smbus_write_byte_data(client, reg, value);
-	return 0;
-}
-
-static struct adm1021_data *adm1021_update_device(struct device *dev)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm1021_data *data = i2c_get_clientdata(client);
-
-	down(&data->update_lock);
-
-	if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
-	    || !data->valid) {
-		dev_dbg(&client->dev, "Starting adm1021 update\n");
-
-		data->temp_input = adm1021_read_value(client, ADM1021_REG_TEMP);
-		data->temp_max = adm1021_read_value(client, ADM1021_REG_TOS_R);
-		data->temp_hyst = adm1021_read_value(client, ADM1021_REG_THYST_R);
-		data->remote_temp_input = adm1021_read_value(client, ADM1021_REG_REMOTE_TEMP);
-		data->remote_temp_max = adm1021_read_value(client, ADM1021_REG_REMOTE_TOS_R);
-		data->remote_temp_hyst = adm1021_read_value(client, ADM1021_REG_REMOTE_THYST_R);
-		data->alarms = adm1021_read_value(client, ADM1021_REG_STATUS) & 0x7c;
-		if (data->type == adm1021)
-			data->die_code = adm1021_read_value(client, ADM1021_REG_DIE_CODE);
-		if (data->type == adm1023) {
-			data->remote_temp_prec = adm1021_read_value(client, ADM1021_REG_REM_TEMP_PREC);
-			data->remote_temp_os_prec = adm1021_read_value(client, ADM1021_REG_REM_TOS_PREC);
-			data->remote_temp_hyst_prec = adm1021_read_value(client, ADM1021_REG_REM_THYST_PREC);
-			data->remote_temp_offset = adm1021_read_value(client, ADM1021_REG_REM_OFFSET);
-			data->remote_temp_offset_prec = adm1021_read_value(client, ADM1021_REG_REM_OFFSET_PREC);
-		}
-		data->last_updated = jiffies;
-		data->valid = 1;
-	}
-
-	up(&data->update_lock);
-
-	return data;
-}
-
-static int __init sensors_adm1021_init(void)
-{
-	return i2c_add_driver(&adm1021_driver);
-}
-
-static void __exit sensors_adm1021_exit(void)
-{
-	i2c_del_driver(&adm1021_driver);
-}
-
-MODULE_AUTHOR ("Frodo Looijaard <frodol@dds.nl> and "
-		"Philip Edelbrock <phil@netroedge.com>");
-MODULE_DESCRIPTION("adm1021 driver");
-MODULE_LICENSE("GPL");
-
-module_param(read_only, bool, 0);
-MODULE_PARM_DESC(read_only, "Don't set any values, read only mode");
-
-module_init(sensors_adm1021_init)
-module_exit(sensors_adm1021_exit)
diff --git a/drivers/i2c/chips/adm1025.c b/drivers/i2c/chips/adm1025.c
deleted file mode 100644
--- a/drivers/i2c/chips/adm1025.c
+++ /dev/null
@@ -1,574 +0,0 @@
-/*
- * adm1025.c
- *
- * Copyright (C) 2000       Chen-Yuan Wu <gwu@esoft.com>
- * Copyright (C) 2003-2004  Jean Delvare <khali@linux-fr.org>
- *
- * The ADM1025 is a sensor chip made by Analog Devices. It reports up to 6
- * voltages (including its own power source) and up to two temperatures
- * (its own plus up to one external one). Voltages are scaled internally
- * (which is not the common way) with ratios such that the nominal value
- * of each voltage correspond to a register value of 192 (which means a
- * resolution of about 0.5% of the nominal value). Temperature values are
- * reported with a 1 deg resolution and a 3 deg accuracy. Complete
- * datasheet can be obtained from Analog's website at:
- *   http://www.analog.com/Analog_Root/productPage/productHome/0,2121,ADM1025,00.html
- *
- * This driver also supports the ADM1025A, which differs from the ADM1025
- * only in that it has "open-drain VID inputs while the ADM1025 has
- * on-chip 100k pull-ups on the VID inputs". It doesn't make any
- * difference for us.
- *
- * This driver also supports the NE1619, a sensor chip made by Philips.
- * That chip is similar to the ADM1025A, with a few differences. The only
- * difference that matters to us is that the NE1619 has only two possible
- * addresses while the ADM1025A has a third one. Complete datasheet can be
- * obtained from Philips's website at:
- *   http://www.semiconductors.philips.com/pip/NE1619DS.html
- *
- * Since the ADM1025 was the first chipset supported by this driver, most
- * comments will refer to this chipset, but are actually general and
- * concern all supported chipsets, unless mentioned otherwise.
- *
- * 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 <linux/config.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/jiffies.h>
-#include <linux/i2c.h>
-#include <linux/i2c-sensor.h>
-#include <linux/i2c-vid.h>
-
-/*
- * Addresses to scan
- * ADM1025 and ADM1025A have three possible addresses: 0x2c, 0x2d and 0x2e.
- * NE1619 has two possible addresses: 0x2c and 0x2d.
- */
-
-static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END };
-static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
-
-/*
- * Insmod parameters
- */
-
-SENSORS_INSMOD_2(adm1025, ne1619);
-
-/*
- * The ADM1025 registers
- */
-
-#define ADM1025_REG_MAN_ID		0x3E
-#define ADM1025_REG_CHIP_ID 		0x3F
-#define ADM1025_REG_CONFIG		0x40
-#define ADM1025_REG_STATUS1		0x41
-#define ADM1025_REG_STATUS2		0x42
-#define ADM1025_REG_IN(nr)		(0x20 + (nr))
-#define ADM1025_REG_IN_MAX(nr)		(0x2B + (nr) * 2)
-#define ADM1025_REG_IN_MIN(nr)		(0x2C + (nr) * 2)
-#define ADM1025_REG_TEMP(nr)		(0x26 + (nr))
-#define ADM1025_REG_TEMP_HIGH(nr)	(0x37 + (nr) * 2)
-#define ADM1025_REG_TEMP_LOW(nr)	(0x38 + (nr) * 2)
-#define ADM1025_REG_VID			0x47
-#define ADM1025_REG_VID4		0x49
-
-/*
- * Conversions and various macros
- * The ADM1025 uses signed 8-bit values for temperatures.
- */
-
-static int in_scale[6] = { 2500, 2250, 3300, 5000, 12000, 3300 };
-
-#define IN_FROM_REG(reg,scale)	(((reg) * (scale) + 96) / 192)
-#define IN_TO_REG(val,scale)	((val) <= 0 ? 0 : \
-				 (val) * 192 >= (scale) * 255 ? 255 : \
-				 ((val) * 192 + (scale)/2) / (scale))
-
-#define TEMP_FROM_REG(reg)	((reg) * 1000)
-#define TEMP_TO_REG(val)	((val) <= -127500 ? -128 : \
-				 (val) >= 126500 ? 127 : \
-				 (((val) < 0 ? (val)-500 : (val)+500) / 1000))
-
-/*
- * Functions declaration
- */
-
-static int adm1025_attach_adapter(struct i2c_adapter *adapter);
-static int adm1025_detect(struct i2c_adapter *adapter, int address, int kind);
-static void adm1025_init_client(struct i2c_client *client);
-static int adm1025_detach_client(struct i2c_client *client);
-static struct adm1025_data *adm1025_update_device(struct device *dev);
-
-/*
- * Driver data (common to all clients)
- */
-
-static struct i2c_driver adm1025_driver = {
-	.owner		= THIS_MODULE,
-	.name		= "adm1025",
-	.id		= I2C_DRIVERID_ADM1025,
-	.flags		= I2C_DF_NOTIFY,
-	.attach_adapter	= adm1025_attach_adapter,
-	.detach_client	= adm1025_detach_client,
-};
-
-/*
- * Client data (each client gets its own)
- */
-
-struct adm1025_data {
-	struct i2c_client client;
-	struct semaphore update_lock;
-	char valid; /* zero until following fields are valid */
-	unsigned long last_updated; /* in jiffies */
-
-	u8 in[6];		/* register value */
-	u8 in_max[6];		/* register value */
-	u8 in_min[6];		/* register value */
-	s8 temp[2];		/* register value */
-	s8 temp_min[2];		/* register value */
-	s8 temp_max[2];		/* register value */
-	u16 alarms;		/* register values, combined */
-	u8 vid;			/* register values, combined */
-	u8 vrm;
-};
-
-/*
- * Sysfs stuff
- */
-
-#define show_in(offset) \
-static ssize_t show_in##offset(struct device *dev, char *buf) \
-{ \
-	struct adm1025_data *data = adm1025_update_device(dev); \
-	return sprintf(buf, "%u\n", IN_FROM_REG(data->in[offset], \
-		       in_scale[offset])); \
-} \
-static ssize_t show_in##offset##_min(struct device *dev, char *buf) \
-{ \
-	struct adm1025_data *data = adm1025_update_device(dev); \
-	return sprintf(buf, "%u\n", IN_FROM_REG(data->in_min[offset], \
-		       in_scale[offset])); \
-} \
-static ssize_t show_in##offset##_max(struct device *dev, char *buf) \
-{ \
-	struct adm1025_data *data = adm1025_update_device(dev); \
-	return sprintf(buf, "%u\n", IN_FROM_REG(data->in_max[offset], \
-		       in_scale[offset])); \
-} \
-static DEVICE_ATTR(in##offset##_input, S_IRUGO, show_in##offset, NULL);
-show_in(0);
-show_in(1);
-show_in(2);
-show_in(3);
-show_in(4);
-show_in(5);
-
-#define show_temp(offset) \
-static ssize_t show_temp##offset(struct device *dev, char *buf) \
-{ \
-	struct adm1025_data *data = adm1025_update_device(dev); \
-	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp[offset-1])); \
-} \
-static ssize_t show_temp##offset##_min(struct device *dev, char *buf) \
-{ \
-	struct adm1025_data *data = adm1025_update_device(dev); \
-	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_min[offset-1])); \
-} \
-static ssize_t show_temp##offset##_max(struct device *dev, char *buf) \
-{ \
-	struct adm1025_data *data = adm1025_update_device(dev); \
-	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_max[offset-1])); \
-}\
-static DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_temp##offset, NULL);
-show_temp(1);
-show_temp(2);
-
-#define set_in(offset) \
-static ssize_t set_in##offset##_min(struct device *dev, const char *buf, \
-	size_t count) \
-{ \
-	struct i2c_client *client = to_i2c_client(dev); \
-	struct adm1025_data *data = i2c_get_clientdata(client); \
-	long val = simple_strtol(buf, NULL, 10); \
- \
-	down(&data->update_lock); \
-	data->in_min[offset] = IN_TO_REG(val, in_scale[offset]); \
-	i2c_smbus_write_byte_data(client, ADM1025_REG_IN_MIN(offset), \
-				  data->in_min[offset]); \
-	up(&data->update_lock); \
-	return count; \
-} \
-static ssize_t set_in##offset##_max(struct device *dev, const char *buf, \
-	size_t count) \
-{ \
-	struct i2c_client *client = to_i2c_client(dev); \
-	struct adm1025_data *data = i2c_get_clientdata(client); \
-	long val = simple_strtol(buf, NULL, 10); \
- \
-	down(&data->update_lock); \
-	data->in_max[offset] = IN_TO_REG(val, in_scale[offset]); \
-	i2c_smbus_write_byte_data(client, ADM1025_REG_IN_MAX(offset), \
-				  data->in_max[offset]); \
-	up(&data->update_lock); \
-	return count; \
-} \
-static DEVICE_ATTR(in##offset##_min, S_IWUSR | S_IRUGO, \
-	show_in##offset##_min, set_in##offset##_min); \
-static DEVICE_ATTR(in##offset##_max, S_IWUSR | S_IRUGO, \
-	show_in##offset##_max, set_in##offset##_max);
-set_in(0);
-set_in(1);
-set_in(2);
-set_in(3);
-set_in(4);
-set_in(5);
-
-#define set_temp(offset) \
-static ssize_t set_temp##offset##_min(struct device *dev, const char *buf, \
-	size_t count) \
-{ \
-	struct i2c_client *client = to_i2c_client(dev); \
-	struct adm1025_data *data = i2c_get_clientdata(client); \
-	long val = simple_strtol(buf, NULL, 10); \
- \
-	down(&data->update_lock); \
-	data->temp_min[offset-1] = TEMP_TO_REG(val); \
-	i2c_smbus_write_byte_data(client, ADM1025_REG_TEMP_LOW(offset-1), \
-				  data->temp_min[offset-1]); \
-	up(&data->update_lock); \
-	return count; \
-} \
-static ssize_t set_temp##offset##_max(struct device *dev, const char *buf, \
-	size_t count) \
-{ \
-	struct i2c_client *client = to_i2c_client(dev); \
-	struct adm1025_data *data = i2c_get_clientdata(client); \
-	long val = simple_strtol(buf, NULL, 10); \
- \
-	down(&data->update_lock); \
-	data->temp_max[offset-1] = TEMP_TO_REG(val); \
-	i2c_smbus_write_byte_data(client, ADM1025_REG_TEMP_HIGH(offset-1), \
-				  data->temp_max[offset-1]); \
-	up(&data->update_lock); \
-	return count; \
-} \
-static DEVICE_ATTR(temp##offset##_min, S_IWUSR | S_IRUGO, \
-	show_temp##offset##_min, set_temp##offset##_min); \
-static DEVICE_ATTR(temp##offset##_max, S_IWUSR | S_IRUGO, \
-	show_temp##offset##_max, set_temp##offset##_max);
-set_temp(1);
-set_temp(2);
-
-static ssize_t show_alarms(struct device *dev, char *buf)
-{
-	struct adm1025_data *data = adm1025_update_device(dev);
-	return sprintf(buf, "%u\n", data->alarms);
-}
-static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
-
-static ssize_t show_vid(struct device *dev, char *buf)
-{
-	struct adm1025_data *data = adm1025_update_device(dev);
-	return sprintf(buf, "%u\n", vid_from_reg(data->vid, data->vrm));
-}
-static DEVICE_ATTR(in1_ref, S_IRUGO, show_vid, NULL);
-
-static ssize_t show_vrm(struct device *dev, char *buf)
-{
-	struct adm1025_data *data = adm1025_update_device(dev);
-	return sprintf(buf, "%u\n", data->vrm);
-}
-static ssize_t set_vrm(struct device *dev, const char *buf, size_t count)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm1025_data *data = i2c_get_clientdata(client);
-	data->vrm = simple_strtoul(buf, NULL, 10);
-	return count;
-}
-static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm, set_vrm);
-
-/*
- * Real code
- */
-
-static int adm1025_attach_adapter(struct i2c_adapter *adapter)
-{
-	if (!(adapter->class & I2C_CLASS_HWMON))
-		return 0;
-	return i2c_detect(adapter, &addr_data, adm1025_detect);
-}
-
-/*
- * The following function does more than just detection. If detection
- * succeeds, it also registers the new chip.
- */
-static int adm1025_detect(struct i2c_adapter *adapter, int address, int kind)
-{
-	struct i2c_client *new_client;
-	struct adm1025_data *data;
-	int err = 0;
-	const char *name = "";
-	u8 config;
-
-	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
-		goto exit;
-
-	if (!(data = kmalloc(sizeof(struct adm1025_data), GFP_KERNEL))) {
-		err = -ENOMEM;
-		goto exit;
-	}
-	memset(data, 0, sizeof(struct adm1025_data));
-
-	/* The common I2C client data is placed right before the
-	   ADM1025-specific data. */
-	new_client = &data->client;
-	i2c_set_clientdata(new_client, data);
-	new_client->addr = address;
-	new_client->adapter = adapter;
-	new_client->driver = &adm1025_driver;
-	new_client->flags = 0;
-
-	/*
-	 * Now we do the remaining detection. A negative kind means that
-	 * the driver was loaded with no force parameter (default), so we
-	 * must both detect and identify the chip. A zero kind means that
-	 * the driver was loaded with the force parameter, the detection
-	 * step shall be skipped. A positive kind means that the driver
-	 * was loaded with the force parameter and a given kind of chip is
-	 * requested, so both the detection and the identification steps
-	 * are skipped.
-	 */
-	config = i2c_smbus_read_byte_data(new_client, ADM1025_REG_CONFIG);
-	if (kind < 0) { /* detection */
-		if ((config & 0x80) != 0x00
-		 || (i2c_smbus_read_byte_data(new_client,
-		     ADM1025_REG_STATUS1) & 0xC0) != 0x00
-		 || (i2c_smbus_read_byte_data(new_client,
-		     ADM1025_REG_STATUS2) & 0xBC) != 0x00) {
-			dev_dbg(&adapter->dev,
-				"ADM1025 detection failed at 0x%02x.\n",
-				address);
-			goto exit_free;
-		}
-	}
-
-	if (kind <= 0) { /* identification */
-		u8 man_id, chip_id;
-
-		man_id = i2c_smbus_read_byte_data(new_client,
-			 ADM1025_REG_MAN_ID);
-		chip_id = i2c_smbus_read_byte_data(new_client,
-			  ADM1025_REG_CHIP_ID);
-		
-		if (man_id == 0x41) { /* Analog Devices */
-			if ((chip_id & 0xF0) == 0x20) { /* ADM1025/ADM1025A */
-				kind = adm1025;
-			}
-		} else
-		if (man_id == 0xA1) { /* Philips */
-			if (address != 0x2E
-			 && (chip_id & 0xF0) == 0x20) { /* NE1619 */
-				kind = ne1619;
-			}
-		}
-
-		if (kind <= 0) { /* identification failed */
-			dev_info(&adapter->dev,
-			    "Unsupported chip (man_id=0x%02X, "
-			    "chip_id=0x%02X).\n", man_id, chip_id);
-			goto exit_free;
-		}
-	}
-
-	if (kind == adm1025) {
-		name = "adm1025";
-	} else if (kind == ne1619) {
-		name = "ne1619";
-	}
-
-	/* We can fill in the remaining client fields */
-	strlcpy(new_client->name, name, I2C_NAME_SIZE);
-	data->valid = 0;
-	init_MUTEX(&data->update_lock);
-
-	/* Tell the I2C layer a new client has arrived */
-	if ((err = i2c_attach_client(new_client)))
-		goto exit_free;
-
-	/* Initialize the ADM1025 chip */
-	adm1025_init_client(new_client);
-
-	/* Register sysfs hooks */
-	device_create_file(&new_client->dev, &dev_attr_in0_input);
-	device_create_file(&new_client->dev, &dev_attr_in1_input);
-	device_create_file(&new_client->dev, &dev_attr_in2_input);
-	device_create_file(&new_client->dev, &dev_attr_in3_input);
-	device_create_file(&new_client->dev, &dev_attr_in5_input);
-	device_create_file(&new_client->dev, &dev_attr_in0_min);
-	device_create_file(&new_client->dev, &dev_attr_in1_min);
-	device_create_file(&new_client->dev, &dev_attr_in2_min);
-	device_create_file(&new_client->dev, &dev_attr_in3_min);
-	device_create_file(&new_client->dev, &dev_attr_in5_min);
-	device_create_file(&new_client->dev, &dev_attr_in0_max);
-	device_create_file(&new_client->dev, &dev_attr_in1_max);
-	device_create_file(&new_client->dev, &dev_attr_in2_max);
-	device_create_file(&new_client->dev, &dev_attr_in3_max);
-	device_create_file(&new_client->dev, &dev_attr_in5_max);
-	device_create_file(&new_client->dev, &dev_attr_temp1_input);
-	device_create_file(&new_client->dev, &dev_attr_temp2_input);
-	device_create_file(&new_client->dev, &dev_attr_temp1_min);
-	device_create_file(&new_client->dev, &dev_attr_temp2_min);
-	device_create_file(&new_client->dev, &dev_attr_temp1_max);
-	device_create_file(&new_client->dev, &dev_attr_temp2_max);
-	device_create_file(&new_client->dev, &dev_attr_alarms);
-	device_create_file(&new_client->dev, &dev_attr_in1_ref);
-	device_create_file(&new_client->dev, &dev_attr_vrm);
-
-	/* Pin 11 is either in4 (+12V) or VID4 */
-	if (!(config & 0x20)) {
-		device_create_file(&new_client->dev, &dev_attr_in4_input);
-		device_create_file(&new_client->dev, &dev_attr_in4_min);
-		device_create_file(&new_client->dev, &dev_attr_in4_max);
-	}
-
-	return 0;
-
-exit_free:
-	kfree(data);
-exit:
-	return err;
-}
-
-static void adm1025_init_client(struct i2c_client *client)
-{
-	u8 reg;
-	struct adm1025_data *data = i2c_get_clientdata(client);
-	int i;
-
-	data->vrm = i2c_which_vrm();
-
-	/*
-	 * Set high limits
-	 * Usually we avoid setting limits on driver init, but it happens
-	 * that the ADM1025 comes with stupid default limits (all registers
-	 * set to 0). In case the chip has not gone through any limit
-	 * setting yet, we better set the high limits to the max so that
-	 * no alarm triggers.
-	 */
-	for (i=0; i<6; i++) {
-		reg = i2c_smbus_read_byte_data(client,
-					       ADM1025_REG_IN_MAX(i));
-		if (reg == 0)
-			i2c_smbus_write_byte_data(client,
-						  ADM1025_REG_IN_MAX(i),
-						  0xFF);
-	}
-	for (i=0; i<2; i++) {
-		reg = i2c_smbus_read_byte_data(client,
-					       ADM1025_REG_TEMP_HIGH(i));
-		if (reg == 0)
-			i2c_smbus_write_byte_data(client,
-						  ADM1025_REG_TEMP_HIGH(i),
-						  0x7F);
-	}
-
-	/*
-	 * Start the conversions
-	 */
-	reg = i2c_smbus_read_byte_data(client, ADM1025_REG_CONFIG);
-	if (!(reg & 0x01))
-		i2c_smbus_write_byte_data(client, ADM1025_REG_CONFIG,
-					  (reg&0x7E)|0x01);
-}
-
-static int adm1025_detach_client(struct i2c_client *client)
-{
-	int err;
-
-	if ((err = i2c_detach_client(client))) {
-		dev_err(&client->dev, "Client deregistration failed, "
-			"client not detached.\n");
-		return err;
-	}
-
-	kfree(i2c_get_clientdata(client));
-	return 0;
-}
-
-static struct adm1025_data *adm1025_update_device(struct device *dev)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm1025_data *data = i2c_get_clientdata(client);
-
-	down(&data->update_lock);
-
-	if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) {
-		int i;
-
-		dev_dbg(&client->dev, "Updating data.\n");
-		for (i=0; i<6; i++) {
-			data->in[i] = i2c_smbus_read_byte_data(client,
-				      ADM1025_REG_IN(i));
-			data->in_min[i] = i2c_smbus_read_byte_data(client,
-					  ADM1025_REG_IN_MIN(i));
-			data->in_max[i] = i2c_smbus_read_byte_data(client,
-					  ADM1025_REG_IN_MAX(i));
-		}
-		for (i=0; i<2; i++) {
-			data->temp[i] = i2c_smbus_read_byte_data(client,
-					ADM1025_REG_TEMP(i));
-			data->temp_min[i] = i2c_smbus_read_byte_data(client,
-					    ADM1025_REG_TEMP_LOW(i));
-			data->temp_max[i] = i2c_smbus_read_byte_data(client,
-					    ADM1025_REG_TEMP_HIGH(i));
-		}
-		data->alarms = i2c_smbus_read_byte_data(client,
-			       ADM1025_REG_STATUS1)
-			     | (i2c_smbus_read_byte_data(client,
-				ADM1025_REG_STATUS2) << 8);
-		data->vid = (i2c_smbus_read_byte_data(client,
-			     ADM1025_REG_VID) & 0x0f)
-			  | ((i2c_smbus_read_byte_data(client,
-			      ADM1025_REG_VID4) & 0x01) << 4);
-
-		data->last_updated = jiffies;
-		data->valid = 1;
-	}
-
-	up(&data->update_lock);
-
-	return data;
-}
-
-static int __init sensors_adm1025_init(void)
-{
-	return i2c_add_driver(&adm1025_driver);
-}
-
-static void __exit sensors_adm1025_exit(void)
-{
-	i2c_del_driver(&adm1025_driver);
-}
-
-MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>");
-MODULE_DESCRIPTION("ADM1025 driver");
-MODULE_LICENSE("GPL");
-
-module_init(sensors_adm1025_init);
-module_exit(sensors_adm1025_exit);
diff --git a/drivers/i2c/chips/adm1026.c b/drivers/i2c/chips/adm1026.c
deleted file mode 100644
--- a/drivers/i2c/chips/adm1026.c
+++ /dev/null
@@ -1,1754 +0,0 @@
-/*
-    adm1026.c - Part of lm_sensors, Linux kernel modules for hardware
-	     monitoring
-    Copyright (C) 2002, 2003  Philip Pokorny <ppokorny@penguincomputing.com>
-    Copyright (C) 2004 Justin Thiessen <jthiessen@penguincomputing.com>
-
-    Chip details at:
-
-    <http://www.analog.com/UploadedFiles/Data_Sheets/779263102ADM1026_a.pdf>
-
-    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 <linux/config.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/jiffies.h>
-#include <linux/i2c.h>
-#include <linux/i2c-sensor.h>
-#include <linux/i2c-vid.h>
-
-/* Addresses to scan */
-static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END };
-static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
-
-/* Insmod parameters */
-SENSORS_INSMOD_1(adm1026);
-
-static int gpio_input[17]  = { -1, -1, -1, -1, -1, -1, -1, -1, -1,
-				-1, -1, -1, -1, -1, -1, -1, -1 }; 
-static int gpio_output[17] = { -1, -1, -1, -1, -1, -1, -1, -1, -1,
-				-1, -1, -1, -1, -1, -1, -1, -1 };
-static int gpio_inverted[17] = { -1, -1, -1, -1, -1, -1, -1, -1, -1,
-				-1, -1, -1, -1, -1, -1, -1, -1 };
-static int gpio_normal[17] = { -1, -1, -1, -1, -1, -1, -1, -1, -1,
-				-1, -1, -1, -1, -1, -1, -1, -1 };
-static int gpio_fan[8] = { -1, -1, -1, -1, -1, -1, -1, -1 };
-module_param_array(gpio_input,int,NULL,0);
-MODULE_PARM_DESC(gpio_input,"List of GPIO pins (0-16) to program as inputs");
-module_param_array(gpio_output,int,NULL,0);
-MODULE_PARM_DESC(gpio_output,"List of GPIO pins (0-16) to program as "
-	"outputs");
-module_param_array(gpio_inverted,int,NULL,0);
-MODULE_PARM_DESC(gpio_inverted,"List of GPIO pins (0-16) to program as "
-	"inverted");
-module_param_array(gpio_normal,int,NULL,0);
-MODULE_PARM_DESC(gpio_normal,"List of GPIO pins (0-16) to program as "
-	"normal/non-inverted");
-module_param_array(gpio_fan,int,NULL,0);
-MODULE_PARM_DESC(gpio_fan,"List of GPIO pins (0-7) to program as fan tachs");
-
-/* Many ADM1026 constants specified below */
-
-/* The ADM1026 registers */
-#define ADM1026_REG_CONFIG1  0x00
-#define CFG1_MONITOR     0x01
-#define CFG1_INT_ENABLE  0x02
-#define CFG1_INT_CLEAR   0x04
-#define CFG1_AIN8_9      0x08
-#define CFG1_THERM_HOT   0x10
-#define CFG1_DAC_AFC     0x20
-#define CFG1_PWM_AFC     0x40
-#define CFG1_RESET       0x80
-#define ADM1026_REG_CONFIG2  0x01
-/* CONFIG2 controls FAN0/GPIO0 through FAN7/GPIO7 */
-#define ADM1026_REG_CONFIG3  0x07
-#define CFG3_GPIO16_ENABLE  0x01
-#define CFG3_CI_CLEAR  0x02
-#define CFG3_VREF_250  0x04
-#define CFG3_GPIO16_DIR  0x40
-#define CFG3_GPIO16_POL  0x80
-#define ADM1026_REG_E2CONFIG  0x13
-#define E2CFG_READ  0x01
-#define E2CFG_WRITE  0x02
-#define E2CFG_ERASE  0x04
-#define E2CFG_ROM  0x08
-#define E2CFG_CLK_EXT  0x80
-
-/* There are 10 general analog inputs and 7 dedicated inputs
- * They are:
- *    0 - 9  =  AIN0 - AIN9
- *       10  =  Vbat
- *       11  =  3.3V Standby
- *       12  =  3.3V Main
- *       13  =  +5V
- *       14  =  Vccp (CPU core voltage)
- *       15  =  +12V
- *       16  =  -12V
- */
-static u16 ADM1026_REG_IN[] = {
-		0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
-		0x36, 0x37, 0x27, 0x29, 0x26, 0x2a,
-		0x2b, 0x2c, 0x2d, 0x2e, 0x2f
-	};
-static u16 ADM1026_REG_IN_MIN[] = {
-		0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d,
-		0x5e, 0x5f, 0x6d, 0x49, 0x6b, 0x4a,
-		0x4b, 0x4c, 0x4d, 0x4e, 0x4f
-	};
-static u16 ADM1026_REG_IN_MAX[] = {
-		0x50, 0x51, 0x52, 0x53, 0x54, 0x55,
-		0x56, 0x57, 0x6c, 0x41, 0x6a, 0x42,
-		0x43, 0x44, 0x45, 0x46, 0x47
-	};
-
-/* Temperatures are:
- *    0 - Internal
- *    1 - External 1
- *    2 - External 2
- */
-static u16 ADM1026_REG_TEMP[] = { 0x1f, 0x28, 0x29 };
-static u16 ADM1026_REG_TEMP_MIN[] = { 0x69, 0x48, 0x49 };
-static u16 ADM1026_REG_TEMP_MAX[] = { 0x68, 0x40, 0x41 };
-static u16 ADM1026_REG_TEMP_TMIN[] = { 0x10, 0x11, 0x12 };
-static u16 ADM1026_REG_TEMP_THERM[] = { 0x0d, 0x0e, 0x0f };
-static u16 ADM1026_REG_TEMP_OFFSET[] = { 0x1e, 0x6e, 0x6f };
-
-#define ADM1026_REG_FAN(nr) (0x38 + (nr))
-#define ADM1026_REG_FAN_MIN(nr) (0x60 + (nr))
-#define ADM1026_REG_FAN_DIV_0_3 0x02
-#define ADM1026_REG_FAN_DIV_4_7 0x03
-
-#define ADM1026_REG_DAC  0x04
-#define ADM1026_REG_PWM  0x05
-
-#define ADM1026_REG_GPIO_CFG_0_3 0x08
-#define ADM1026_REG_GPIO_CFG_4_7 0x09
-#define ADM1026_REG_GPIO_CFG_8_11 0x0a
-#define ADM1026_REG_GPIO_CFG_12_15 0x0b
-/* CFG_16 in REG_CFG3 */
-#define ADM1026_REG_GPIO_STATUS_0_7 0x24
-#define ADM1026_REG_GPIO_STATUS_8_15 0x25
-/* STATUS_16 in REG_STATUS4 */
-#define ADM1026_REG_GPIO_MASK_0_7 0x1c
-#define ADM1026_REG_GPIO_MASK_8_15 0x1d
-/* MASK_16 in REG_MASK4 */
-
-#define ADM1026_REG_COMPANY 0x16
-#define ADM1026_REG_VERSTEP 0x17
-/* These are the recognized values for the above regs */
-#define ADM1026_COMPANY_ANALOG_DEV 0x41
-#define ADM1026_VERSTEP_GENERIC 0x40
-#define ADM1026_VERSTEP_ADM1026 0x44
-
-#define ADM1026_REG_MASK1 0x18
-#define ADM1026_REG_MASK2 0x19
-#define ADM1026_REG_MASK3 0x1a
-#define ADM1026_REG_MASK4 0x1b
-
-#define ADM1026_REG_STATUS1 0x20
-#define ADM1026_REG_STATUS2 0x21
-#define ADM1026_REG_STATUS3 0x22
-#define ADM1026_REG_STATUS4 0x23
-
-#define ADM1026_FAN_ACTIVATION_TEMP_HYST -6
-#define ADM1026_FAN_CONTROL_TEMP_RANGE 20
-#define ADM1026_PWM_MAX 255
-
-/* Conversions. Rounding and limit checking is only done on the TO_REG 
- * variants. Note that you should be a bit careful with which arguments
- * these macros are called: arguments may be evaluated more than once.
- */
-
-/* IN are scaled acording to built-in resistors.  These are the
- *   voltages corresponding to 3/4 of full scale (192 or 0xc0)
- *   NOTE: The -12V input needs an additional factor to account
- *      for the Vref pullup resistor.
- *      NEG12_OFFSET = SCALE * Vref / V-192 - Vref
- *                   = 13875 * 2.50 / 1.875 - 2500
- *                   = 16000
- *
- * The values in this table are based on Table II, page 15 of the
- *    datasheet.
- */
-static int adm1026_scaling[] = {  /* .001 Volts */
-		2250, 2250, 2250, 2250, 2250, 2250, 
-		1875, 1875, 1875, 1875, 3000, 3330, 
-		3330, 4995, 2250, 12000, 13875
-	};
-#define NEG12_OFFSET  16000
-#define SCALE(val,from,to) (((val)*(to) + ((from)/2))/(from))
-#define INS_TO_REG(n,val)  (SENSORS_LIMIT(SCALE(val,adm1026_scaling[n],192),\
-	0,255))
-#define INS_FROM_REG(n,val) (SCALE(val,192,adm1026_scaling[n]))
-
-/* FAN speed is measured using 22.5kHz clock and counts for 2 pulses
- *   and we assume a 2 pulse-per-rev fan tach signal
- *      22500 kHz * 60 (sec/min) * 2 (pulse) / 2 (pulse/rev) == 1350000
- */
-#define FAN_TO_REG(val,div)  ((val)<=0 ? 0xff : SENSORS_LIMIT(1350000/((val)*\
-	(div)),1,254)) 
-#define FAN_FROM_REG(val,div) ((val)==0?-1:(val)==0xff ? 0 : 1350000/((val)*\
-	(div)))
-#define DIV_FROM_REG(val) (1<<(val))
-#define DIV_TO_REG(val) ((val)>=8 ? 3 : (val)>=4 ? 2 : (val)>=2 ? 1 : 0)
-
-/* Temperature is reported in 1 degC increments */
-#define TEMP_TO_REG(val) (SENSORS_LIMIT(((val)+((val)<0 ? -500 : 500))/1000,\
-	-127,127))
-#define TEMP_FROM_REG(val) ((val) * 1000)
-#define OFFSET_TO_REG(val) (SENSORS_LIMIT(((val)+((val)<0 ? -500 : 500))/1000,\
-	-127,127))
-#define OFFSET_FROM_REG(val) ((val) * 1000)
-
-#define PWM_TO_REG(val) (SENSORS_LIMIT(val,0,255))
-#define PWM_FROM_REG(val) (val)
-
-#define PWM_MIN_TO_REG(val) ((val) & 0xf0)
-#define PWM_MIN_FROM_REG(val) (((val) & 0xf0) + ((val) >> 4))
-
-/* Analog output is a voltage, and scaled to millivolts.  The datasheet 
- *   indicates that the DAC could be used to drive the fans, but in our 
- *   example board (Arima HDAMA) it isn't connected to the fans at all.
- */
-#define DAC_TO_REG(val) (SENSORS_LIMIT(((((val)*255)+500)/2500),0,255)) 
-#define DAC_FROM_REG(val) (((val)*2500)/255)
-
-/* Typically used with systems using a v9.1 VRM spec ? */
-#define ADM1026_INIT_VRM  91
-
-/* Chip sampling rates
- *
- * Some sensors are not updated more frequently than once per second
- *    so it doesn't make sense to read them more often than that.
- *    We cache the results and return the saved data if the driver
- *    is called again before a second has elapsed.
- *
- * Also, there is significant configuration data for this chip
- *    So, we keep the config data up to date in the cache
- *    when it is written and only sample it once every 5 *minutes*
- */
-#define ADM1026_DATA_INTERVAL  (1 * HZ)
-#define ADM1026_CONFIG_INTERVAL  (5 * 60 * HZ)
-
-/* We allow for multiple chips in a single system.
- *
- * For each registered ADM1026, we need to keep state information
- * at client->data. The adm1026_data structure is dynamically
- * allocated, when a new client structure is allocated. */
-
-struct pwm_data {
-	u8 pwm;
-	u8 enable;
-	u8 auto_pwm_min;
-};
-
-struct adm1026_data {
-	struct i2c_client client;
-	struct semaphore lock;
-	enum chips type;
-
-	struct semaphore update_lock;
-	int valid;		/* !=0 if following fields are valid */
-	unsigned long last_reading;	/* In jiffies */
-	unsigned long last_config;	/* In jiffies */
-
-	u8 in[17];              /* Register value */
-	u8 in_max[17];          /* Register value */
-	u8 in_min[17];          /* Register value */
-	s8 temp[3];             /* Register value */
-	s8 temp_min[3];         /* Register value */
-	s8 temp_max[3];         /* Register value */
-	s8 temp_tmin[3];        /* Register value */
-	s8 temp_crit[3];        /* Register value */
-	s8 temp_offset[3];      /* Register value */
-	u8 fan[8];              /* Register value */
-	u8 fan_min[8];          /* Register value */
-	u8 fan_div[8];          /* Decoded value */
-	struct pwm_data pwm1;   /* Pwm control values */
-	int vid;                /* Decoded value */
-	u8 vrm;                 /* VRM version */
-	u8 analog_out;		/* Register value (DAC) */
-	long alarms;            /* Register encoding, combined */
-	long alarm_mask;        /* Register encoding, combined */
-	long gpio;              /* Register encoding, combined */
-	long gpio_mask;         /* Register encoding, combined */
-	u8 gpio_config[17];     /* Decoded value */
-	u8 config1;             /* Register value */
-	u8 config2;             /* Register value */
-	u8 config3;             /* Register value */
-};
-
-static int adm1026_attach_adapter(struct i2c_adapter *adapter);
-static int adm1026_detect(struct i2c_adapter *adapter, int address,
-	int kind);
-static int adm1026_detach_client(struct i2c_client *client);
-static int adm1026_read_value(struct i2c_client *client, u8 register);
-static int adm1026_write_value(struct i2c_client *client, u8 register,
-	int value); 
-static void adm1026_print_gpio(struct i2c_client *client);
-static void adm1026_fixup_gpio(struct i2c_client *client); 
-static struct adm1026_data *adm1026_update_device(struct device *dev);
-static void adm1026_init_client(struct i2c_client *client);
-
-
-static struct i2c_driver adm1026_driver = {
-	.owner          = THIS_MODULE,
-	.name           = "adm1026",
-	.flags          = I2C_DF_NOTIFY,
-	.attach_adapter = adm1026_attach_adapter,
-	.detach_client  = adm1026_detach_client,
-};
-
-int adm1026_attach_adapter(struct i2c_adapter *adapter)
-{
-	if (!(adapter->class & I2C_CLASS_HWMON)) {
-		return 0;
-	}
-	return i2c_detect(adapter, &addr_data, adm1026_detect);
-}
-
-int adm1026_detach_client(struct i2c_client *client)
-{
-	i2c_detach_client(client);
-	kfree(client);
-	return 0;
-}
-
-int adm1026_read_value(struct i2c_client *client, u8 reg)
-{
-	int res;
-
-	if (reg < 0x80) {
-		/* "RAM" locations */
-		res = i2c_smbus_read_byte_data(client, reg) & 0xff;
-	} else {
-		/* EEPROM, do nothing */
-		res = 0;
-	}
-	return res;
-}
-
-int adm1026_write_value(struct i2c_client *client, u8 reg, int value)
-{
-	int res;
-
-	if (reg < 0x80) {
-		/* "RAM" locations */
-		res = i2c_smbus_write_byte_data(client, reg, value);
-	} else {
-		/* EEPROM, do nothing */
-		res = 0;
-	}
-	return res;
-}
-
-void adm1026_init_client(struct i2c_client *client)
-{
-	int value, i;
-	struct adm1026_data *data = i2c_get_clientdata(client);
-
-        dev_dbg(&client->dev, "Initializing device\n");
-	/* Read chip config */
-	data->config1 = adm1026_read_value(client, ADM1026_REG_CONFIG1);
-	data->config2 = adm1026_read_value(client, ADM1026_REG_CONFIG2);
-	data->config3 = adm1026_read_value(client, ADM1026_REG_CONFIG3);
-
-	/* Inform user of chip config */
-	dev_dbg(&client->dev, "ADM1026_REG_CONFIG1 is: 0x%02x\n",
-		data->config1);
-	if ((data->config1 & CFG1_MONITOR) == 0) {
-		dev_dbg(&client->dev, "Monitoring not currently "
-			"enabled.\n");
-	}
-	if (data->config1 & CFG1_INT_ENABLE) {
-		dev_dbg(&client->dev, "SMBALERT interrupts are "
-			"enabled.\n");
-	}
-	if (data->config1 & CFG1_AIN8_9) {
-		dev_dbg(&client->dev, "in8 and in9 enabled. "
-			"temp3 disabled.\n");
-	} else {
-		dev_dbg(&client->dev, "temp3 enabled.  in8 and "
-			"in9 disabled.\n");
-	}
-	if (data->config1 & CFG1_THERM_HOT) {
-		dev_dbg(&client->dev, "Automatic THERM, PWM, "
-			"and temp limits enabled.\n");
-	}
-
-	value = data->config3;
-	if (data->config3 & CFG3_GPIO16_ENABLE) {
-		dev_dbg(&client->dev, "GPIO16 enabled.  THERM"
-			"pin disabled.\n");
-	} else {
-		dev_dbg(&client->dev, "THERM pin enabled.  "
-			"GPIO16 disabled.\n");
-	}
-	if (data->config3 & CFG3_VREF_250) {
-		dev_dbg(&client->dev, "Vref is 2.50 Volts.\n");
-	} else {
-		dev_dbg(&client->dev, "Vref is 1.82 Volts.\n");
-	}
-	/* Read and pick apart the existing GPIO configuration */
-	value = 0;
-	for (i = 0;i <= 15;++i) {
-		if ((i & 0x03) == 0) {
-			value = adm1026_read_value(client,
-					ADM1026_REG_GPIO_CFG_0_3 + i/4);
-		}
-		data->gpio_config[i] = value & 0x03;
-		value >>= 2;
-	}
-	data->gpio_config[16] = (data->config3 >> 6) & 0x03;
-
-	/* ... and then print it */
-	adm1026_print_gpio(client);
-
-	/* If the user asks us to reprogram the GPIO config, then
-	 * do it now.
-	 */
-	if (gpio_input[0] != -1 || gpio_output[0] != -1
-		|| gpio_inverted[0] != -1 || gpio_normal[0] != -1
-		|| gpio_fan[0] != -1) {
-		adm1026_fixup_gpio(client);
-	}
-
-	/* WE INTENTIONALLY make no changes to the limits,
-	 *   offsets, pwms, fans and zones.  If they were
-	 *   configured, we don't want to mess with them.
-	 *   If they weren't, the default is 100% PWM, no
-	 *   control and will suffice until 'sensors -s'
-	 *   can be run by the user.  We DO set the default 
-	 *   value for pwm1.auto_pwm_min to its maximum
-	 *   so that enabling automatic pwm fan control
-	 *   without first setting a value for pwm1.auto_pwm_min 
-	 *   will not result in potentially dangerous fan speed decrease.
-	 */
-	data->pwm1.auto_pwm_min=255;
-	/* Start monitoring */
-	value = adm1026_read_value(client, ADM1026_REG_CONFIG1);
-	/* Set MONITOR, clear interrupt acknowledge and s/w reset */
-	value = (value | CFG1_MONITOR) & (~CFG1_INT_CLEAR & ~CFG1_RESET);
-	dev_dbg(&client->dev, "Setting CONFIG to: 0x%02x\n", value);
-	data->config1 = value;
-	adm1026_write_value(client, ADM1026_REG_CONFIG1, value);
-
-	/* initialize fan_div[] to hardware defaults */
-	value = adm1026_read_value(client, ADM1026_REG_FAN_DIV_0_3) |
-		(adm1026_read_value(client, ADM1026_REG_FAN_DIV_4_7) << 8);
-	for (i = 0;i <= 7;++i) {
-		data->fan_div[i] = DIV_FROM_REG(value & 0x03);
-		value >>= 2;
-	}
-}
-
-void adm1026_print_gpio(struct i2c_client *client)
-{
-	struct adm1026_data *data = i2c_get_clientdata(client);
-	int  i;
-
-	dev_dbg(&client->dev, "GPIO config is:");
-	for (i = 0;i <= 7;++i) {
-		if (data->config2 & (1 << i)) {
-			dev_dbg(&client->dev, "\t%sGP%s%d\n",
-				data->gpio_config[i] & 0x02 ? "" : "!",
-				data->gpio_config[i] & 0x01 ? "OUT" : "IN",
-				i);
-		} else {
-			dev_dbg(&client->dev, "\tFAN%d\n", i);
-		}
-	}
-	for (i = 8;i <= 15;++i) {
-		dev_dbg(&client->dev, "\t%sGP%s%d\n",
-			data->gpio_config[i] & 0x02 ? "" : "!",
-			data->gpio_config[i] & 0x01 ? "OUT" : "IN",
-			i);
-	}
-	if (data->config3 & CFG3_GPIO16_ENABLE) {
-		dev_dbg(&client->dev, "\t%sGP%s16\n",
-			data->gpio_config[16] & 0x02 ? "" : "!",
-			data->gpio_config[16] & 0x01 ? "OUT" : "IN");
-	} else {
-		/* GPIO16 is THERM  */
-		dev_dbg(&client->dev, "\tTHERM\n");
-	}
-}
-
-void adm1026_fixup_gpio(struct i2c_client *client)
-{
-	struct adm1026_data *data = i2c_get_clientdata(client);
-	int  i;
-	int  value;
-
-	/* Make the changes requested. */
-	/* We may need to unlock/stop monitoring or soft-reset the
-	 *    chip before we can make changes.  This hasn't been
-	 *    tested much.  FIXME
-	 */
-
-	/* Make outputs */
-	for (i = 0;i <= 16;++i) {
-		if (gpio_output[i] >= 0 && gpio_output[i] <= 16) {
-			data->gpio_config[gpio_output[i]] |= 0x01;
-		}
-		/* if GPIO0-7 is output, it isn't a FAN tach */
-		if (gpio_output[i] >= 0 && gpio_output[i] <= 7) {
-			data->config2 |= 1 << gpio_output[i];
-		}
-	}
-
-	/* Input overrides output */
-	for (i = 0;i <= 16;++i) {
-		if (gpio_input[i] >= 0 && gpio_input[i] <= 16) {
-			data->gpio_config[gpio_input[i]] &= ~ 0x01;
-		}
-		/* if GPIO0-7 is input, it isn't a FAN tach */
-		if (gpio_input[i] >= 0 && gpio_input[i] <= 7) {
-			data->config2 |= 1 << gpio_input[i];
-		}
-	}
-
-	/* Inverted  */
-	for (i = 0;i <= 16;++i) {
-		if (gpio_inverted[i] >= 0 && gpio_inverted[i] <= 16) {
-			data->gpio_config[gpio_inverted[i]] &= ~ 0x02;
-		}
-	}
-
-	/* Normal overrides inverted  */
-	for (i = 0;i <= 16;++i) {
-		if (gpio_normal[i] >= 0 && gpio_normal[i] <= 16) {
-			data->gpio_config[gpio_normal[i]] |= 0x02;
-		}
-	}
-
-	/* Fan overrides input and output */
-	for (i = 0;i <= 7;++i) {
-		if (gpio_fan[i] >= 0 && gpio_fan[i] <= 7) {
-			data->config2 &= ~(1 << gpio_fan[i]);
-		}
-	}
-
-	/* Write new configs to registers */
-	adm1026_write_value(client, ADM1026_REG_CONFIG2, data->config2);
-	data->config3 = (data->config3 & 0x3f)
-			| ((data->gpio_config[16] & 0x03) << 6);
-	adm1026_write_value(client, ADM1026_REG_CONFIG3, data->config3);
-	for (i = 15, value = 0;i >= 0;--i) {
-		value <<= 2;
-		value |= data->gpio_config[i] & 0x03;
-		if ((i & 0x03) == 0) {
-			adm1026_write_value(client,
-					ADM1026_REG_GPIO_CFG_0_3 + i/4,
-					value);
-			value = 0;
-		}
-	}
-
-	/* Print the new config */
-	adm1026_print_gpio(client);
-}
-
-
-static struct adm1026_data *adm1026_update_device(struct device *dev)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm1026_data *data = i2c_get_clientdata(client);
-	int i;
-	long value, alarms, gpio;
-
-	down(&data->update_lock);
-	if (!data->valid
-	    || time_after(jiffies, data->last_reading + ADM1026_DATA_INTERVAL)) {
-		/* Things that change quickly */
-		dev_dbg(&client->dev,"Reading sensor values\n");
-		for (i = 0;i <= 16;++i) {
-			data->in[i] =
-			    adm1026_read_value(client, ADM1026_REG_IN[i]);
-		}
-
-		for (i = 0;i <= 7;++i) {
-			data->fan[i] =
-			    adm1026_read_value(client, ADM1026_REG_FAN(i));
-		}
-
-		for (i = 0;i <= 2;++i) {
-			/* NOTE: temp[] is s8 and we assume 2's complement
-			 *   "conversion" in the assignment   */
-			data->temp[i] =
-			    adm1026_read_value(client, ADM1026_REG_TEMP[i]);
-		}
-
-		data->pwm1.pwm = adm1026_read_value(client, 
-			ADM1026_REG_PWM);
-		data->analog_out = adm1026_read_value(client, 
-			ADM1026_REG_DAC);
-		/* GPIO16 is MSbit of alarms, move it to gpio */
-		alarms = adm1026_read_value(client, ADM1026_REG_STATUS4);
-		gpio = alarms & 0x80 ? 0x0100 : 0;  /* GPIO16 */
-		alarms &= 0x7f;
-		alarms <<= 8;
-		alarms |= adm1026_read_value(client, ADM1026_REG_STATUS3);
-		alarms <<= 8;
-		alarms |= adm1026_read_value(client, ADM1026_REG_STATUS2);
-		alarms <<= 8;
-		alarms |= adm1026_read_value(client, ADM1026_REG_STATUS1);
-		data->alarms = alarms;
-
-		/* Read the GPIO values */
-		gpio |= adm1026_read_value(client, 
-			ADM1026_REG_GPIO_STATUS_8_15);
-		gpio <<= 8;
-		gpio |= adm1026_read_value(client, 
-			ADM1026_REG_GPIO_STATUS_0_7);
-		data->gpio = gpio;
-
-		data->last_reading = jiffies;
-	};  /* last_reading */
-
-	if (!data->valid ||
-	    time_after(jiffies, data->last_config + ADM1026_CONFIG_INTERVAL)) {
-		/* Things that don't change often */
-		dev_dbg(&client->dev, "Reading config values\n");
-		for (i = 0;i <= 16;++i) {
-			data->in_min[i] = adm1026_read_value(client, 
-				ADM1026_REG_IN_MIN[i]);
-			data->in_max[i] = adm1026_read_value(client, 
-				ADM1026_REG_IN_MAX[i]);
-		}
-
-		value = adm1026_read_value(client, ADM1026_REG_FAN_DIV_0_3)
-			| (adm1026_read_value(client, ADM1026_REG_FAN_DIV_4_7)
-			<< 8);
-		for (i = 0;i <= 7;++i) {
-			data->fan_min[i] = adm1026_read_value(client, 
-				ADM1026_REG_FAN_MIN(i));
-			data->fan_div[i] = DIV_FROM_REG(value & 0x03);
-			value >>= 2;
-		}
-
-		for (i = 0; i <= 2; ++i) {
-			/* NOTE: temp_xxx[] are s8 and we assume 2's 
-			 *    complement "conversion" in the assignment
-			 */
-			data->temp_min[i] = adm1026_read_value(client, 
-				ADM1026_REG_TEMP_MIN[i]);
-			data->temp_max[i] = adm1026_read_value(client, 
-				ADM1026_REG_TEMP_MAX[i]);
-			data->temp_tmin[i] = adm1026_read_value(client, 
-				ADM1026_REG_TEMP_TMIN[i]);
-			data->temp_crit[i] = adm1026_read_value(client, 
-				ADM1026_REG_TEMP_THERM[i]);
-			data->temp_offset[i] = adm1026_read_value(client, 
-				ADM1026_REG_TEMP_OFFSET[i]);
-		}
-
-		/* Read the STATUS/alarm masks */
-		alarms  = adm1026_read_value(client, ADM1026_REG_MASK4);
-		gpio    = alarms & 0x80 ? 0x0100 : 0;  /* GPIO16 */
-		alarms  = (alarms & 0x7f) << 8;
-		alarms |= adm1026_read_value(client, ADM1026_REG_MASK3);
-		alarms <<= 8;
-		alarms |= adm1026_read_value(client, ADM1026_REG_MASK2);
-		alarms <<= 8;
-		alarms |= adm1026_read_value(client, ADM1026_REG_MASK1);
-		data->alarm_mask = alarms;
-
-		/* Read the GPIO values */
-		gpio |= adm1026_read_value(client, 
-			ADM1026_REG_GPIO_MASK_8_15);
-		gpio <<= 8;
-		gpio |= adm1026_read_value(client, ADM1026_REG_GPIO_MASK_0_7);
-		data->gpio_mask = gpio;
-
-		/* Read various values from CONFIG1 */
-		data->config1 = adm1026_read_value(client, 
-			ADM1026_REG_CONFIG1);
-		if (data->config1 & CFG1_PWM_AFC) {
-			data->pwm1.enable = 2;
-			data->pwm1.auto_pwm_min = 
-				PWM_MIN_FROM_REG(data->pwm1.pwm);
-		}
-		/* Read the GPIO config */
-		data->config2 = adm1026_read_value(client, 
-			ADM1026_REG_CONFIG2);
-		data->config3 = adm1026_read_value(client, 
-			ADM1026_REG_CONFIG3);
-		data->gpio_config[16] = (data->config3 >> 6) & 0x03;
-
-		value = 0;
-		for (i = 0;i <= 15;++i) {
-			if ((i & 0x03) == 0) {
-				value = adm1026_read_value(client,
-					    ADM1026_REG_GPIO_CFG_0_3 + i/4);
-			}
-			data->gpio_config[i] = value & 0x03;
-			value >>= 2;
-		}
-
-		data->last_config = jiffies;
-	};  /* last_config */
-
-	dev_dbg(&client->dev, "Setting VID from GPIO11-15.\n");
-	data->vid = (data->gpio >> 11) & 0x1f;
-	data->valid = 1;
-	up(&data->update_lock);
-	return data;
-}
-
-static ssize_t show_in(struct device *dev, char *buf, int nr)
-{
-	struct adm1026_data *data = adm1026_update_device(dev);
-	return sprintf(buf,"%d\n", INS_FROM_REG(nr, data->in[nr]));
-}
-static ssize_t show_in_min(struct device *dev, char *buf, int nr) 
-{
-	struct adm1026_data *data = adm1026_update_device(dev); 
-	return sprintf(buf,"%d\n", INS_FROM_REG(nr, data->in_min[nr]));
-}
-static ssize_t set_in_min(struct device *dev, const char *buf, 
-		size_t count, int nr)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm1026_data *data = i2c_get_clientdata(client);
-	int val = simple_strtol(buf, NULL, 10);
-
-	down(&data->update_lock);
-	data->in_min[nr] = INS_TO_REG(nr, val);
-	adm1026_write_value(client, ADM1026_REG_IN_MIN[nr], data->in_min[nr]);
-	up(&data->update_lock);
-	return count; 
-}
-static ssize_t show_in_max(struct device *dev, char *buf, int nr)
-{
-	struct adm1026_data *data = adm1026_update_device(dev);
-	return sprintf(buf,"%d\n", INS_FROM_REG(nr, data->in_max[nr]));
-}
-static ssize_t set_in_max(struct device *dev, const char *buf,
-		size_t count, int nr)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm1026_data *data = i2c_get_clientdata(client);
-	int val = simple_strtol(buf, NULL, 10);
-
-	down(&data->update_lock);
-	data->in_max[nr] = INS_TO_REG(nr, val);
-	adm1026_write_value(client, ADM1026_REG_IN_MAX[nr], data->in_max[nr]);
-	up(&data->update_lock);
-	return count;
-}
-
-#define in_reg(offset)                                                    \
-static ssize_t show_in##offset (struct device *dev, char *buf)            \
-{                                                                         \
-	return show_in(dev, buf, offset);                                 \
-}                                                                         \
-static ssize_t show_in##offset##_min (struct device *dev, char *buf)      \
-{                                                                         \
-	return show_in_min(dev, buf, offset);                             \
-}                                                                         \
-static ssize_t set_in##offset##_min (struct device *dev,                  \
-	const char *buf, size_t count)                                    \
-{                                                                         \
-	return set_in_min(dev, buf, count, offset);                       \
-}                                                                         \
-static ssize_t show_in##offset##_max (struct device *dev, char *buf)      \
-{                                                                         \
-	return show_in_max(dev, buf, offset);                             \
-}                                                                         \
-static ssize_t set_in##offset##_max (struct device *dev,                  \
-	const char *buf, size_t count)                                    \
-{                                                                         \
-	return set_in_max(dev, buf, count, offset);                       \
-}                                                                         \
-static DEVICE_ATTR(in##offset##_input, S_IRUGO, show_in##offset, NULL);   \
-static DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR,                   \
-		show_in##offset##_min, set_in##offset##_min);             \
-static DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR,                   \
-		show_in##offset##_max, set_in##offset##_max);
-
-
-in_reg(0);
-in_reg(1);
-in_reg(2);
-in_reg(3);
-in_reg(4);
-in_reg(5);
-in_reg(6);
-in_reg(7);
-in_reg(8);
-in_reg(9);
-in_reg(10);
-in_reg(11);
-in_reg(12);
-in_reg(13);
-in_reg(14);
-in_reg(15);
-
-static ssize_t show_in16(struct device *dev, char *buf)
-{
-	struct adm1026_data *data = adm1026_update_device(dev);
-	return sprintf(buf,"%d\n", INS_FROM_REG(16, data->in[16]) -
-		NEG12_OFFSET);
-}
-static ssize_t show_in16_min(struct device *dev, char *buf) 
-{
-	struct adm1026_data *data = adm1026_update_device(dev); 
-	return sprintf(buf,"%d\n", INS_FROM_REG(16, data->in_min[16])
-		- NEG12_OFFSET);
-}
-static ssize_t set_in16_min(struct device *dev, const char *buf, size_t count)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm1026_data *data = i2c_get_clientdata(client);
-	int val = simple_strtol(buf, NULL, 10);
-
-	down(&data->update_lock);
-	data->in_min[16] = INS_TO_REG(16, val + NEG12_OFFSET);
-	adm1026_write_value(client, ADM1026_REG_IN_MIN[16], data->in_min[16]);
-	up(&data->update_lock);
-	return count; 
-}
-static ssize_t show_in16_max(struct device *dev, char *buf)
-{
-	struct adm1026_data *data = adm1026_update_device(dev);
-	return sprintf(buf,"%d\n", INS_FROM_REG(16, data->in_max[16])
-			- NEG12_OFFSET);
-}
-static ssize_t set_in16_max(struct device *dev, const char *buf, size_t count)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm1026_data *data = i2c_get_clientdata(client);
-	int val = simple_strtol(buf, NULL, 10);
-
-	down(&data->update_lock);
-	data->in_max[16] = INS_TO_REG(16, val+NEG12_OFFSET);
-	adm1026_write_value(client, ADM1026_REG_IN_MAX[16], data->in_max[16]);
-	up(&data->update_lock);
-	return count;
-}
-
-static DEVICE_ATTR(in16_input, S_IRUGO, show_in16, NULL);
-static DEVICE_ATTR(in16_min, S_IRUGO | S_IWUSR, show_in16_min, set_in16_min);
-static DEVICE_ATTR(in16_max, S_IRUGO | S_IWUSR, show_in16_max, set_in16_max);
-
-
-
-
-/* Now add fan read/write functions */
-
-static ssize_t show_fan(struct device *dev, char *buf, int nr)
-{
-	struct adm1026_data *data = adm1026_update_device(dev);
-	return sprintf(buf,"%d\n", FAN_FROM_REG(data->fan[nr],
-		data->fan_div[nr]));
-}
-static ssize_t show_fan_min(struct device *dev, char *buf, int nr)
-{
-	struct adm1026_data *data = adm1026_update_device(dev);
-	return sprintf(buf,"%d\n", FAN_FROM_REG(data->fan_min[nr],
-		data->fan_div[nr]));
-}
-static ssize_t set_fan_min(struct device *dev, const char *buf,
-		size_t count, int nr)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm1026_data *data = i2c_get_clientdata(client);
-	int val = simple_strtol(buf, NULL, 10);
-
-	down(&data->update_lock);
-	data->fan_min[nr] = FAN_TO_REG(val, data->fan_div[nr]);
-	adm1026_write_value(client, ADM1026_REG_FAN_MIN(nr),
-		data->fan_min[nr]);
-	up(&data->update_lock);
-	return count;
-}
-
-#define fan_offset(offset)                                                  \
-static ssize_t show_fan_##offset (struct device *dev, char *buf)            \
-{                                                                           \
-	return show_fan(dev, buf, offset - 1);                              \
-}                                                                           \
-static ssize_t show_fan_##offset##_min (struct device *dev, char *buf)      \
-{                                                                           \
-	return show_fan_min(dev, buf, offset - 1);                          \
-}                                                                           \
-static ssize_t set_fan_##offset##_min (struct device *dev,                  \
-	const char *buf, size_t count)                                      \
-{                                                                           \
-	return set_fan_min(dev, buf, count, offset - 1);                    \
-}                                                                           \
-static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_fan_##offset, NULL);  \
-static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR,                    \
-		show_fan_##offset##_min, set_fan_##offset##_min);
-
-fan_offset(1);
-fan_offset(2);
-fan_offset(3);
-fan_offset(4);
-fan_offset(5);
-fan_offset(6);
-fan_offset(7);
-fan_offset(8);
-
-/* Adjust fan_min to account for new fan divisor */
-static void fixup_fan_min(struct device *dev, int fan, int old_div)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm1026_data *data = i2c_get_clientdata(client);
-	int    new_min;
-	int    new_div = data->fan_div[fan];
-
-	/* 0 and 0xff are special.  Don't adjust them */
-	if (data->fan_min[fan] == 0 || data->fan_min[fan] == 0xff) {
-		return;
-	}
-
-	new_min = data->fan_min[fan] * old_div / new_div;
-	new_min = SENSORS_LIMIT(new_min, 1, 254);
-	data->fan_min[fan] = new_min;
-	adm1026_write_value(client, ADM1026_REG_FAN_MIN(fan), new_min);
-}
-
-/* Now add fan_div read/write functions */
-static ssize_t show_fan_div(struct device *dev, char *buf, int nr)
-{
-	struct adm1026_data *data = adm1026_update_device(dev);
-	return sprintf(buf,"%d\n", data->fan_div[nr]);
-}
-static ssize_t set_fan_div(struct device *dev, const char *buf,
-		size_t count, int nr)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm1026_data *data = i2c_get_clientdata(client);
-	int    val,orig_div,new_div,shift;
-
-	val = simple_strtol(buf, NULL, 10);
-	new_div = DIV_TO_REG(val); 
-	if (new_div == 0) {
-		return -EINVAL;
-	}
-	down(&data->update_lock);
-	orig_div = data->fan_div[nr];
-	data->fan_div[nr] = DIV_FROM_REG(new_div);
-
-	if (nr < 4) { /* 0 <= nr < 4 */
-		shift = 2 * nr;
-		adm1026_write_value(client, ADM1026_REG_FAN_DIV_0_3,
-			((DIV_TO_REG(orig_div) & (~(0x03 << shift))) |
-			(new_div << shift)));
-	} else { /* 3 < nr < 8 */
-		shift = 2 * (nr - 4);
-		adm1026_write_value(client, ADM1026_REG_FAN_DIV_4_7,
-			((DIV_TO_REG(orig_div) & (~(0x03 << (2 * shift)))) |
-			(new_div << shift)));
-	}
-
-	if (data->fan_div[nr] != orig_div) {
-		fixup_fan_min(dev,nr,orig_div);
-	}
-	up(&data->update_lock);
-	return count;
-}
-
-#define fan_offset_div(offset)                                          \
-static ssize_t show_fan_##offset##_div (struct device *dev, char *buf)  \
-{                                                                       \
-	return show_fan_div(dev, buf, offset - 1);                      \
-}                                                                       \
-static ssize_t set_fan_##offset##_div (struct device *dev,              \
-	const char *buf, size_t count)                                  \
-{                                                                       \
-	return set_fan_div(dev, buf, count, offset - 1);                \
-}                                                                       \
-static DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR,                \
-		show_fan_##offset##_div, set_fan_##offset##_div);
-
-fan_offset_div(1);
-fan_offset_div(2);
-fan_offset_div(3);
-fan_offset_div(4);
-fan_offset_div(5);
-fan_offset_div(6);
-fan_offset_div(7);
-fan_offset_div(8);
-
-/* Temps */
-static ssize_t show_temp(struct device *dev, char *buf, int nr)
-{
-	struct adm1026_data *data = adm1026_update_device(dev);
-	return sprintf(buf,"%d\n", TEMP_FROM_REG(data->temp[nr]));
-}
-static ssize_t show_temp_min(struct device *dev, char *buf, int nr)
-{
-	struct adm1026_data *data = adm1026_update_device(dev);
-	return sprintf(buf,"%d\n", TEMP_FROM_REG(data->temp_min[nr]));
-}
-static ssize_t set_temp_min(struct device *dev, const char *buf,
-		size_t count, int nr)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm1026_data *data = i2c_get_clientdata(client);
-	int val = simple_strtol(buf, NULL, 10);
-
-	down(&data->update_lock);
-	data->temp_min[nr] = TEMP_TO_REG(val);
-	adm1026_write_value(client, ADM1026_REG_TEMP_MIN[nr],
-		data->temp_min[nr]);
-	up(&data->update_lock);
-	return count;
-}
-static ssize_t show_temp_max(struct device *dev, char *buf, int nr)
-{
-	struct adm1026_data *data = adm1026_update_device(dev);
-	return sprintf(buf,"%d\n", TEMP_FROM_REG(data->temp_max[nr]));
-}
-static ssize_t set_temp_max(struct device *dev, const char *buf,
-		size_t count, int nr)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm1026_data *data = i2c_get_clientdata(client);
-	int val = simple_strtol(buf, NULL, 10);
-
-	down(&data->update_lock);
-	data->temp_max[nr] = TEMP_TO_REG(val);
-	adm1026_write_value(client, ADM1026_REG_TEMP_MAX[nr],
-		data->temp_max[nr]);
-	up(&data->update_lock);
-	return count;
-}
-#define temp_reg(offset)                                                      \
-static ssize_t show_temp_##offset (struct device *dev, char *buf)             \
-{                                                                             \
-	return show_temp(dev, buf, offset - 1);                               \
-}                                                                             \
-static ssize_t show_temp_##offset##_min (struct device *dev, char *buf)       \
-{                                                                             \
-	return show_temp_min(dev, buf, offset - 1);                           \
-}                                                                             \
-static ssize_t show_temp_##offset##_max (struct device *dev, char *buf)       \
-{                                                                             \
-	return show_temp_max(dev, buf, offset - 1);                           \
-}                                                                             \
-static ssize_t set_temp_##offset##_min (struct device *dev,                   \
-	const char *buf, size_t count)                                        \
-{                                                                             \
-	return set_temp_min(dev, buf, count, offset - 1);                     \
-}                                                                             \
-static ssize_t set_temp_##offset##_max (struct device *dev,                   \
-	const char *buf, size_t count)                                        \
-{                                                                             \
-	return set_temp_max(dev, buf, count, offset - 1);                     \
-}                                                                             \
-static DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_temp_##offset, NULL);  \
-static DEVICE_ATTR(temp##offset##_min, S_IRUGO | S_IWUSR,                     \
-		show_temp_##offset##_min, set_temp_##offset##_min);           \
-static DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR,                     \
-		show_temp_##offset##_max, set_temp_##offset##_max);
-
-
-temp_reg(1);
-temp_reg(2);
-temp_reg(3);
-
-static ssize_t show_temp_offset(struct device *dev, char *buf, int nr)
-{
-	struct adm1026_data *data = adm1026_update_device(dev);
-	return sprintf(buf,"%d\n", TEMP_FROM_REG(data->temp_offset[nr]));
-}
-static ssize_t set_temp_offset(struct device *dev, const char *buf,
-		size_t count, int nr)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm1026_data *data = i2c_get_clientdata(client);
-	int val = simple_strtol(buf, NULL, 10);
-
-	down(&data->update_lock);
-	data->temp_offset[nr] = TEMP_TO_REG(val);
-	adm1026_write_value(client, ADM1026_REG_TEMP_OFFSET[nr],
-		data->temp_offset[nr]);
-	up(&data->update_lock);
-	return count;
-}
-
-#define temp_offset_reg(offset)                                             \
-static ssize_t show_temp_##offset##_offset (struct device *dev, char *buf)  \
-{                                                                           \
-	return show_temp_offset(dev, buf, offset - 1);                      \
-}                                                                           \
-static ssize_t set_temp_##offset##_offset (struct device *dev,              \
-	const char *buf, size_t count)                                      \
-{                                                                           \
-	return set_temp_offset(dev, buf, count, offset - 1);                \
-}                                                                           \
-static DEVICE_ATTR(temp##offset##_offset, S_IRUGO | S_IWUSR,                \
-		show_temp_##offset##_offset, set_temp_##offset##_offset);
-
-temp_offset_reg(1);
-temp_offset_reg(2);
-temp_offset_reg(3);
-
-static ssize_t show_temp_auto_point1_temp_hyst(struct device *dev, char *buf,
-		int nr)
-{
-	struct adm1026_data *data = adm1026_update_device(dev);
-	return sprintf(buf,"%d\n", TEMP_FROM_REG(
-		ADM1026_FAN_ACTIVATION_TEMP_HYST + data->temp_tmin[nr]));
-}
-static ssize_t show_temp_auto_point2_temp(struct device *dev, char *buf,
-		int nr)
-{
-	struct adm1026_data *data = adm1026_update_device(dev);
-	return sprintf(buf,"%d\n", TEMP_FROM_REG(data->temp_tmin[nr] +
-		ADM1026_FAN_CONTROL_TEMP_RANGE));
-}
-static ssize_t show_temp_auto_point1_temp(struct device *dev, char *buf,
-		int nr)
-{
-	struct adm1026_data *data = adm1026_update_device(dev);
-	return sprintf(buf,"%d\n", TEMP_FROM_REG(data->temp_tmin[nr]));
-}
-static ssize_t set_temp_auto_point1_temp(struct device *dev, const char *buf,
-		size_t count, int nr)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm1026_data *data = i2c_get_clientdata(client);
-	int val = simple_strtol(buf, NULL, 10);
-
-	down(&data->update_lock);
-	data->temp_tmin[nr] = TEMP_TO_REG(val);
-	adm1026_write_value(client, ADM1026_REG_TEMP_TMIN[nr],
-		data->temp_tmin[nr]);
-	up(&data->update_lock);
-	return count;
-}
-
-#define temp_auto_point(offset)                                             \
-static ssize_t show_temp##offset##_auto_point1_temp (struct device *dev,    \
-	char *buf)                                                          \
-{                                                                           \
-	return show_temp_auto_point1_temp(dev, buf, offset - 1);            \
-}                                                                           \
-static ssize_t set_temp##offset##_auto_point1_temp (struct device *dev,     \
-	const char *buf, size_t count)                                      \
-{                                                                           \
-	return set_temp_auto_point1_temp(dev, buf, count, offset - 1);      \
-}                                                                           \
-static ssize_t show_temp##offset##_auto_point1_temp_hyst (struct device     \
-	*dev, char *buf)                                                    \
-{                                                                           \
-	return show_temp_auto_point1_temp_hyst(dev, buf, offset - 1);       \
-}                                                                           \
-static ssize_t show_temp##offset##_auto_point2_temp (struct device *dev,    \
-	 char *buf)                                                         \
-{                                                                           \
-	return show_temp_auto_point2_temp(dev, buf, offset - 1);            \
-}                                                                           \
-static DEVICE_ATTR(temp##offset##_auto_point1_temp, S_IRUGO | S_IWUSR,      \
-		show_temp##offset##_auto_point1_temp,                       \
-		set_temp##offset##_auto_point1_temp);                       \
-static DEVICE_ATTR(temp##offset##_auto_point1_temp_hyst, S_IRUGO,           \
-		show_temp##offset##_auto_point1_temp_hyst, NULL);           \
-static DEVICE_ATTR(temp##offset##_auto_point2_temp, S_IRUGO,                \
-		show_temp##offset##_auto_point2_temp, NULL);
-
-temp_auto_point(1);
-temp_auto_point(2);
-temp_auto_point(3);
-
-static ssize_t show_temp_crit_enable(struct device *dev, char *buf)
-{
-	struct adm1026_data *data = adm1026_update_device(dev);
-	return sprintf(buf,"%d\n", (data->config1 & CFG1_THERM_HOT) >> 4);
-}
-static ssize_t set_temp_crit_enable(struct device *dev, const char *buf,
-		size_t count)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm1026_data *data = i2c_get_clientdata(client);
-	int val = simple_strtol(buf, NULL, 10);
-
-	if ((val == 1) || (val==0)) {
-		down(&data->update_lock);
-		data->config1 = (data->config1 & ~CFG1_THERM_HOT) | (val << 4);
-		adm1026_write_value(client, ADM1026_REG_CONFIG1, 
-			data->config1);
-		up(&data->update_lock);
-	}
-	return count;
-}
-
-static DEVICE_ATTR(temp1_crit_enable, S_IRUGO | S_IWUSR, 
-	show_temp_crit_enable, set_temp_crit_enable);
-
-static DEVICE_ATTR(temp2_crit_enable, S_IRUGO | S_IWUSR, 
-	show_temp_crit_enable, set_temp_crit_enable);
-
-static DEVICE_ATTR(temp3_crit_enable, S_IRUGO | S_IWUSR, 
-	show_temp_crit_enable, set_temp_crit_enable);
-
-
-static ssize_t show_temp_crit(struct device *dev, char *buf, int nr)
-{
-	struct adm1026_data *data = adm1026_update_device(dev);
-	return sprintf(buf,"%d\n", TEMP_FROM_REG(data->temp_crit[nr]));
-}
-static ssize_t set_temp_crit(struct device *dev, const char *buf,
-		size_t count, int nr)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm1026_data *data = i2c_get_clientdata(client);
-	int val = simple_strtol(buf, NULL, 10);
-
-	down(&data->update_lock);
-	data->temp_crit[nr] = TEMP_TO_REG(val);
-	adm1026_write_value(client, ADM1026_REG_TEMP_THERM[nr],
-		data->temp_crit[nr]);
-	up(&data->update_lock);
-	return count;
-}
-
-#define temp_crit_reg(offset)                                             \
-static ssize_t show_temp_##offset##_crit (struct device *dev, char *buf)  \
-{                                                                         \
-	return show_temp_crit(dev, buf, offset - 1);                      \
-}                                                                         \
-static ssize_t set_temp_##offset##_crit (struct device *dev,              \
-	const char *buf, size_t count)                                    \
-{                                                                         \
-	return set_temp_crit(dev, buf, count, offset - 1);                \
-}                                                                         \
-static DEVICE_ATTR(temp##offset##_crit, S_IRUGO | S_IWUSR,                \
-		show_temp_##offset##_crit, set_temp_##offset##_crit);
-
-temp_crit_reg(1);
-temp_crit_reg(2);
-temp_crit_reg(3);
-
-static ssize_t show_analog_out_reg(struct device *dev, char *buf)
-{
-	struct adm1026_data *data = adm1026_update_device(dev);
-	return sprintf(buf,"%d\n", DAC_FROM_REG(data->analog_out));
-}
-static ssize_t set_analog_out_reg(struct device *dev, const char *buf,
-		size_t count)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm1026_data *data = i2c_get_clientdata(client);
-	int val = simple_strtol(buf, NULL, 10);
-
-	down(&data->update_lock);
-	data->analog_out = DAC_TO_REG(val);
-	adm1026_write_value(client, ADM1026_REG_DAC, data->analog_out);
-	up(&data->update_lock);
-	return count;
-}
-
-static DEVICE_ATTR(analog_out, S_IRUGO | S_IWUSR, show_analog_out_reg, 
-	set_analog_out_reg);
-
-static ssize_t show_vid_reg(struct device *dev, char *buf)
-{
-	struct adm1026_data *data = adm1026_update_device(dev);
-	return sprintf(buf,"%d\n", vid_from_reg(data->vid & 0x3f, data->vrm));
-}
-
-static DEVICE_ATTR(vid, S_IRUGO, show_vid_reg, NULL);
-
-static ssize_t show_vrm_reg(struct device *dev, char *buf)
-{
-	struct adm1026_data *data = adm1026_update_device(dev);
-	return sprintf(buf,"%d\n", data->vrm);
-}
-static ssize_t store_vrm_reg(struct device *dev, const char *buf,
-		size_t count)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm1026_data *data = i2c_get_clientdata(client);
-
-	data->vrm = simple_strtol(buf, NULL, 10);
-	return count;
-}
-
-static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg);
-
-static ssize_t show_alarms_reg(struct device *dev, char *buf)
-{
-	struct adm1026_data *data = adm1026_update_device(dev);
-	return sprintf(buf, "%ld\n", (long) (data->alarms));
-}
-
-static DEVICE_ATTR(alarms, S_IRUGO, show_alarms_reg, NULL);
-
-static ssize_t show_alarm_mask(struct device *dev, char *buf)
-{
-	struct adm1026_data *data = adm1026_update_device(dev);
-	return sprintf(buf,"%ld\n", data->alarm_mask);
-}
-static ssize_t set_alarm_mask(struct device *dev, const char *buf,
-		size_t count)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm1026_data *data = i2c_get_clientdata(client);
-	int val = simple_strtol(buf, NULL, 10);
-	unsigned long mask;
-
-	down(&data->update_lock);
-	data->alarm_mask = val & 0x7fffffff;
-	mask = data->alarm_mask
-		| (data->gpio_mask & 0x10000 ? 0x80000000 : 0);
-	adm1026_write_value(client, ADM1026_REG_MASK1,
-		mask & 0xff);
-	mask >>= 8;
-	adm1026_write_value(client, ADM1026_REG_MASK2,
-		mask & 0xff);
-	mask >>= 8;
-	adm1026_write_value(client, ADM1026_REG_MASK3,
-		mask & 0xff);
-	mask >>= 8;
-	adm1026_write_value(client, ADM1026_REG_MASK4,
-		mask & 0xff);
-	up(&data->update_lock);
-	return count;
-}
-
-static DEVICE_ATTR(alarm_mask, S_IRUGO | S_IWUSR, show_alarm_mask,
-	set_alarm_mask);
-
-
-static ssize_t show_gpio(struct device *dev, char *buf)
-{
-	struct adm1026_data *data = adm1026_update_device(dev);
-	return sprintf(buf,"%ld\n", data->gpio);
-}
-static ssize_t set_gpio(struct device *dev, const char *buf,
-		size_t count)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm1026_data *data = i2c_get_clientdata(client);
-	int val = simple_strtol(buf, NULL, 10);
-	long   gpio;
-
-	down(&data->update_lock);
-	data->gpio = val & 0x1ffff;
-	gpio = data->gpio;
-	adm1026_write_value(client, ADM1026_REG_GPIO_STATUS_0_7,gpio & 0xff);
-	gpio >>= 8;
-	adm1026_write_value(client, ADM1026_REG_GPIO_STATUS_8_15,gpio & 0xff);
-	gpio = ((gpio >> 1) & 0x80) | (data->alarms >> 24 & 0x7f);
-	adm1026_write_value(client, ADM1026_REG_STATUS4,gpio & 0xff);
-	up(&data->update_lock);
-	return count;
-}
-
-static DEVICE_ATTR(gpio, S_IRUGO | S_IWUSR, show_gpio, set_gpio);
-
-
-static ssize_t show_gpio_mask(struct device *dev, char *buf)
-{
-	struct adm1026_data *data = adm1026_update_device(dev);
-	return sprintf(buf,"%ld\n", data->gpio_mask);
-}
-static ssize_t set_gpio_mask(struct device *dev, const char *buf,
-		size_t count)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm1026_data *data = i2c_get_clientdata(client);
-	int val = simple_strtol(buf, NULL, 10);
-	long   mask;
-
-	down(&data->update_lock);
-	data->gpio_mask = val & 0x1ffff;
-	mask = data->gpio_mask;
-	adm1026_write_value(client, ADM1026_REG_GPIO_MASK_0_7,mask & 0xff);
-	mask >>= 8;
-	adm1026_write_value(client, ADM1026_REG_GPIO_MASK_8_15,mask & 0xff);
-	mask = ((mask >> 1) & 0x80) | (data->alarm_mask >> 24 & 0x7f);
-	adm1026_write_value(client, ADM1026_REG_MASK1,mask & 0xff);
-	up(&data->update_lock);
-	return count;
-}
-
-static DEVICE_ATTR(gpio_mask, S_IRUGO | S_IWUSR, show_gpio_mask, set_gpio_mask);
-
-static ssize_t show_pwm_reg(struct device *dev, char *buf)
-{
-	struct adm1026_data *data = adm1026_update_device(dev);
-	return sprintf(buf,"%d\n", PWM_FROM_REG(data->pwm1.pwm));
-}
-static ssize_t set_pwm_reg(struct device *dev, const char *buf,
-		size_t count)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm1026_data *data = i2c_get_clientdata(client);
-
-	if (data->pwm1.enable == 1) {
-		int val = simple_strtol(buf, NULL, 10);
-
-		down(&data->update_lock);
-		data->pwm1.pwm = PWM_TO_REG(val);
-		adm1026_write_value(client, ADM1026_REG_PWM, data->pwm1.pwm);
-		up(&data->update_lock);
-	}
-	return count;
-}
-static ssize_t show_auto_pwm_min(struct device *dev, char *buf)
-{
-	struct adm1026_data *data = adm1026_update_device(dev);
-	return sprintf(buf,"%d\n", data->pwm1.auto_pwm_min);
-}
-static ssize_t set_auto_pwm_min(struct device *dev, const char *buf,
-		size_t count)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm1026_data *data = i2c_get_clientdata(client);
-	int val = simple_strtol(buf, NULL, 10);
-
-	down(&data->update_lock);
-	data->pwm1.auto_pwm_min = SENSORS_LIMIT(val,0,255);
-	if (data->pwm1.enable == 2) { /* apply immediately */
-		data->pwm1.pwm = PWM_TO_REG((data->pwm1.pwm & 0x0f) |
-			PWM_MIN_TO_REG(data->pwm1.auto_pwm_min)); 
-		adm1026_write_value(client, ADM1026_REG_PWM, data->pwm1.pwm);
-	}
-	up(&data->update_lock);
-	return count;
-}
-static ssize_t show_auto_pwm_max(struct device *dev, char *buf)
-{
-	return sprintf(buf,"%d\n", ADM1026_PWM_MAX);
-}
-static ssize_t show_pwm_enable(struct device *dev, char *buf)
-{
-	struct adm1026_data *data = adm1026_update_device(dev);
-	return sprintf(buf,"%d\n", data->pwm1.enable);
-}
-static ssize_t set_pwm_enable(struct device *dev, const char *buf,
-		size_t count)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm1026_data *data = i2c_get_clientdata(client);
-	int val = simple_strtol(buf, NULL, 10);
-	int     old_enable;
-
-	if ((val >= 0) && (val < 3)) {
-		down(&data->update_lock);
-		old_enable = data->pwm1.enable;
-		data->pwm1.enable = val;
-		data->config1 = (data->config1 & ~CFG1_PWM_AFC)
-				| ((val == 2) ? CFG1_PWM_AFC : 0);
-		adm1026_write_value(client, ADM1026_REG_CONFIG1,
-			data->config1);
-		if (val == 2) {  /* apply pwm1_auto_pwm_min to pwm1 */
-			data->pwm1.pwm = PWM_TO_REG((data->pwm1.pwm & 0x0f) |
-				PWM_MIN_TO_REG(data->pwm1.auto_pwm_min)); 
-			adm1026_write_value(client, ADM1026_REG_PWM, 
-				data->pwm1.pwm);
-		} else if (!((old_enable == 1) && (val == 1))) {
-			/* set pwm to safe value */
-			data->pwm1.pwm = 255;
-			adm1026_write_value(client, ADM1026_REG_PWM, 
-				data->pwm1.pwm);
-		}
-		up(&data->update_lock);
-	}
-	return count;
-}
-
-/* enable PWM fan control */
-static DEVICE_ATTR(pwm1, S_IRUGO | S_IWUSR, show_pwm_reg, set_pwm_reg); 
-static DEVICE_ATTR(pwm2, S_IRUGO | S_IWUSR, show_pwm_reg, set_pwm_reg); 
-static DEVICE_ATTR(pwm3, S_IRUGO | S_IWUSR, show_pwm_reg, set_pwm_reg); 
-static DEVICE_ATTR(pwm1_enable, S_IRUGO | S_IWUSR, show_pwm_enable, 
-	set_pwm_enable);
-static DEVICE_ATTR(pwm2_enable, S_IRUGO | S_IWUSR, show_pwm_enable, 
-	set_pwm_enable);
-static DEVICE_ATTR(pwm3_enable, S_IRUGO | S_IWUSR, show_pwm_enable, 
-	set_pwm_enable);
-static DEVICE_ATTR(temp1_auto_point1_pwm, S_IRUGO | S_IWUSR, 
-	show_auto_pwm_min, set_auto_pwm_min);
-static DEVICE_ATTR(temp2_auto_point1_pwm, S_IRUGO | S_IWUSR, 
-	show_auto_pwm_min, set_auto_pwm_min);
-static DEVICE_ATTR(temp3_auto_point1_pwm, S_IRUGO | S_IWUSR, 
-	show_auto_pwm_min, set_auto_pwm_min);
-
-static DEVICE_ATTR(temp1_auto_point2_pwm, S_IRUGO, show_auto_pwm_max, NULL);
-static DEVICE_ATTR(temp2_auto_point2_pwm, S_IRUGO, show_auto_pwm_max, NULL);
-static DEVICE_ATTR(temp3_auto_point2_pwm, S_IRUGO, show_auto_pwm_max, NULL);
-
-int adm1026_detect(struct i2c_adapter *adapter, int address,
-		int kind)
-{
-	int company, verstep;
-	struct i2c_client *new_client;
-	struct adm1026_data *data;
-	int err = 0;
-	const char *type_name = "";
-
-	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
-		/* We need to be able to do byte I/O */
-		goto exit;
-	};
-
-	/* OK. For now, we presume we have a valid client. We now create the
-	   client structure, even though we cannot fill it completely yet.
-	   But it allows us to access adm1026_{read,write}_value. */
-
-	if (!(data = kmalloc(sizeof(struct adm1026_data), GFP_KERNEL))) {
-		err = -ENOMEM;
-		goto exit;
-	}
-
-	memset(data, 0, sizeof(struct adm1026_data));
-
-	new_client = &data->client;
-	i2c_set_clientdata(new_client, data);
-	new_client->addr = address;
-	new_client->adapter = adapter;
-	new_client->driver = &adm1026_driver;
-	new_client->flags = 0;
-
-	/* Now, we do the remaining detection. */
-
-	company = adm1026_read_value(new_client, ADM1026_REG_COMPANY);
-	verstep = adm1026_read_value(new_client, ADM1026_REG_VERSTEP);
-
-	dev_dbg(&new_client->dev, "Detecting device at %d,0x%02x with"
-		" COMPANY: 0x%02x and VERSTEP: 0x%02x\n",
-		i2c_adapter_id(new_client->adapter), new_client->addr,
-		company, verstep);
-
-	/* If auto-detecting, Determine the chip type. */
-	if (kind <= 0) {
-		dev_dbg(&new_client->dev, "Autodetecting device at %d,0x%02x "
-			"...\n", i2c_adapter_id(adapter), address);
-		if (company == ADM1026_COMPANY_ANALOG_DEV
-		    && verstep == ADM1026_VERSTEP_ADM1026) {
-			kind = adm1026;
-		} else if (company == ADM1026_COMPANY_ANALOG_DEV
-			&& (verstep & 0xf0) == ADM1026_VERSTEP_GENERIC) {
-			dev_err(&adapter->dev, ": Unrecognized stepping "
-				"0x%02x. Defaulting to ADM1026.\n", verstep);
-			kind = adm1026;
-		} else if ((verstep & 0xf0) == ADM1026_VERSTEP_GENERIC) {
-			dev_err(&adapter->dev, ": Found version/stepping "
-				"0x%02x. Assuming generic ADM1026.\n",
-				verstep);
-			kind = any_chip;
-		} else {
-			dev_dbg(&new_client->dev, ": Autodetection "
-				"failed\n");
-			/* Not an ADM1026 ... */
-			if (kind == 0)  { /* User used force=x,y */
-				dev_err(&adapter->dev, "Generic ADM1026 not "
-					"found at %d,0x%02x.  Try "
-					"force_adm1026.\n",
-					i2c_adapter_id(adapter), address);
-			}
-			err = 0;
-			goto exitfree;
-		}
-	}
-
-	/* Fill in the chip specific driver values */
-	switch (kind) {
-	case any_chip :
-		type_name = "adm1026";
-		break;
-	case adm1026 :
-		type_name = "adm1026";
-		break;
-	default :
-		dev_err(&adapter->dev, ": Internal error, invalid "
-			"kind (%d)!", kind);
-		err = -EFAULT;
-		goto exitfree;
-	}
-	strlcpy(new_client->name, type_name, I2C_NAME_SIZE);
-
-	/* Fill in the remaining client fields */
-	data->type = kind;
-	data->valid = 0;
-	init_MUTEX(&data->update_lock);
-
-	/* Tell the I2C layer a new client has arrived */
-	if ((err = i2c_attach_client(new_client)))
-		goto exitfree;
-
-	/* Set the VRM version */
-	data->vrm = i2c_which_vrm();
-
-	/* Initialize the ADM1026 chip */
-	adm1026_init_client(new_client);
-
-	/* Register sysfs hooks */
-	device_create_file(&new_client->dev, &dev_attr_in0_input);
-	device_create_file(&new_client->dev, &dev_attr_in0_max);
-	device_create_file(&new_client->dev, &dev_attr_in0_min);
-	device_create_file(&new_client->dev, &dev_attr_in1_input);
-	device_create_file(&new_client->dev, &dev_attr_in1_max);
-	device_create_file(&new_client->dev, &dev_attr_in1_min);
-	device_create_file(&new_client->dev, &dev_attr_in2_input);
-	device_create_file(&new_client->dev, &dev_attr_in2_max);
-	device_create_file(&new_client->dev, &dev_attr_in2_min);
-	device_create_file(&new_client->dev, &dev_attr_in3_input);
-	device_create_file(&new_client->dev, &dev_attr_in3_max);
-	device_create_file(&new_client->dev, &dev_attr_in3_min);
-	device_create_file(&new_client->dev, &dev_attr_in4_input);
-	device_create_file(&new_client->dev, &dev_attr_in4_max);
-	device_create_file(&new_client->dev, &dev_attr_in4_min);
-	device_create_file(&new_client->dev, &dev_attr_in5_input);
-	device_create_file(&new_client->dev, &dev_attr_in5_max);
-	device_create_file(&new_client->dev, &dev_attr_in5_min);
-	device_create_file(&new_client->dev, &dev_attr_in6_input);
-	device_create_file(&new_client->dev, &dev_attr_in6_max);
-	device_create_file(&new_client->dev, &dev_attr_in6_min);
-	device_create_file(&new_client->dev, &dev_attr_in7_input);
-	device_create_file(&new_client->dev, &dev_attr_in7_max);
-	device_create_file(&new_client->dev, &dev_attr_in7_min);
-	device_create_file(&new_client->dev, &dev_attr_in8_input);
-	device_create_file(&new_client->dev, &dev_attr_in8_max);
-	device_create_file(&new_client->dev, &dev_attr_in8_min);
-	device_create_file(&new_client->dev, &dev_attr_in9_input);
-	device_create_file(&new_client->dev, &dev_attr_in9_max);
-	device_create_file(&new_client->dev, &dev_attr_in9_min);
-	device_create_file(&new_client->dev, &dev_attr_in10_input);
-	device_create_file(&new_client->dev, &dev_attr_in10_max);
-	device_create_file(&new_client->dev, &dev_attr_in10_min);
-	device_create_file(&new_client->dev, &dev_attr_in11_input);
-	device_create_file(&new_client->dev, &dev_attr_in11_max);
-	device_create_file(&new_client->dev, &dev_attr_in11_min);
-	device_create_file(&new_client->dev, &dev_attr_in12_input);
-	device_create_file(&new_client->dev, &dev_attr_in12_max);
-	device_create_file(&new_client->dev, &dev_attr_in12_min);
-	device_create_file(&new_client->dev, &dev_attr_in13_input);
-	device_create_file(&new_client->dev, &dev_attr_in13_max);
-	device_create_file(&new_client->dev, &dev_attr_in13_min);
-	device_create_file(&new_client->dev, &dev_attr_in14_input);
-	device_create_file(&new_client->dev, &dev_attr_in14_max);
-	device_create_file(&new_client->dev, &dev_attr_in14_min);
-	device_create_file(&new_client->dev, &dev_attr_in15_input);
-	device_create_file(&new_client->dev, &dev_attr_in15_max);
-	device_create_file(&new_client->dev, &dev_attr_in15_min);
-	device_create_file(&new_client->dev, &dev_attr_in16_input);
-	device_create_file(&new_client->dev, &dev_attr_in16_max);
-	device_create_file(&new_client->dev, &dev_attr_in16_min);
-	device_create_file(&new_client->dev, &dev_attr_fan1_input);
-	device_create_file(&new_client->dev, &dev_attr_fan1_div);
-	device_create_file(&new_client->dev, &dev_attr_fan1_min);
-	device_create_file(&new_client->dev, &dev_attr_fan2_input);
-	device_create_file(&new_client->dev, &dev_attr_fan2_div);
-	device_create_file(&new_client->dev, &dev_attr_fan2_min);
-	device_create_file(&new_client->dev, &dev_attr_fan3_input);
-	device_create_file(&new_client->dev, &dev_attr_fan3_div);
-	device_create_file(&new_client->dev, &dev_attr_fan3_min);
-	device_create_file(&new_client->dev, &dev_attr_fan4_input);
-	device_create_file(&new_client->dev, &dev_attr_fan4_div);
-	device_create_file(&new_client->dev, &dev_attr_fan4_min);
-	device_create_file(&new_client->dev, &dev_attr_fan5_input);
-	device_create_file(&new_client->dev, &dev_attr_fan5_div);
-	device_create_file(&new_client->dev, &dev_attr_fan5_min);
-	device_create_file(&new_client->dev, &dev_attr_fan6_input);
-	device_create_file(&new_client->dev, &dev_attr_fan6_div);
-	device_create_file(&new_client->dev, &dev_attr_fan6_min);
-	device_create_file(&new_client->dev, &dev_attr_fan7_input);
-	device_create_file(&new_client->dev, &dev_attr_fan7_div);
-	device_create_file(&new_client->dev, &dev_attr_fan7_min);
-	device_create_file(&new_client->dev, &dev_attr_fan8_input);
-	device_create_file(&new_client->dev, &dev_attr_fan8_div);
-	device_create_file(&new_client->dev, &dev_attr_fan8_min);
-	device_create_file(&new_client->dev, &dev_attr_temp1_input);
-	device_create_file(&new_client->dev, &dev_attr_temp1_max);
-	device_create_file(&new_client->dev, &dev_attr_temp1_min);
-	device_create_file(&new_client->dev, &dev_attr_temp2_input);
-	device_create_file(&new_client->dev, &dev_attr_temp2_max);
-	device_create_file(&new_client->dev, &dev_attr_temp2_min);
-	device_create_file(&new_client->dev, &dev_attr_temp3_input);
-	device_create_file(&new_client->dev, &dev_attr_temp3_max);
-	device_create_file(&new_client->dev, &dev_attr_temp3_min);
-	device_create_file(&new_client->dev, &dev_attr_temp1_offset);
-	device_create_file(&new_client->dev, &dev_attr_temp2_offset);
-	device_create_file(&new_client->dev, &dev_attr_temp3_offset);
-	device_create_file(&new_client->dev, 
-		&dev_attr_temp1_auto_point1_temp);
-	device_create_file(&new_client->dev, 
-		&dev_attr_temp2_auto_point1_temp);
-	device_create_file(&new_client->dev, 
-		&dev_attr_temp3_auto_point1_temp);
-	device_create_file(&new_client->dev,
-		&dev_attr_temp1_auto_point1_temp_hyst);
-	device_create_file(&new_client->dev,
-		&dev_attr_temp2_auto_point1_temp_hyst);
-	device_create_file(&new_client->dev,
-		&dev_attr_temp3_auto_point1_temp_hyst);
-	device_create_file(&new_client->dev, 
-		&dev_attr_temp1_auto_point2_temp);
-	device_create_file(&new_client->dev, 
-		&dev_attr_temp2_auto_point2_temp);
-	device_create_file(&new_client->dev, 
-		&dev_attr_temp3_auto_point2_temp);
-	device_create_file(&new_client->dev, &dev_attr_temp1_crit);
-	device_create_file(&new_client->dev, &dev_attr_temp2_crit);
-	device_create_file(&new_client->dev, &dev_attr_temp3_crit);
-	device_create_file(&new_client->dev, &dev_attr_temp1_crit_enable);
-	device_create_file(&new_client->dev, &dev_attr_temp2_crit_enable);
-	device_create_file(&new_client->dev, &dev_attr_temp3_crit_enable);
-	device_create_file(&new_client->dev, &dev_attr_vid);
-	device_create_file(&new_client->dev, &dev_attr_vrm);
-	device_create_file(&new_client->dev, &dev_attr_alarms);
-	device_create_file(&new_client->dev, &dev_attr_alarm_mask);
-	device_create_file(&new_client->dev, &dev_attr_gpio);
-	device_create_file(&new_client->dev, &dev_attr_gpio_mask);
-	device_create_file(&new_client->dev, &dev_attr_pwm1);
-	device_create_file(&new_client->dev, &dev_attr_pwm2);
-	device_create_file(&new_client->dev, &dev_attr_pwm3);
-	device_create_file(&new_client->dev, &dev_attr_pwm1_enable);
-	device_create_file(&new_client->dev, &dev_attr_pwm2_enable);
-	device_create_file(&new_client->dev, &dev_attr_pwm3_enable);
-	device_create_file(&new_client->dev, &dev_attr_temp1_auto_point1_pwm);
-	device_create_file(&new_client->dev, &dev_attr_temp2_auto_point1_pwm);
-	device_create_file(&new_client->dev, &dev_attr_temp3_auto_point1_pwm);
-	device_create_file(&new_client->dev, &dev_attr_temp1_auto_point2_pwm);
-	device_create_file(&new_client->dev, &dev_attr_temp2_auto_point2_pwm);
-	device_create_file(&new_client->dev, &dev_attr_temp3_auto_point2_pwm);
-	device_create_file(&new_client->dev, &dev_attr_analog_out);
-	return 0;
-
-	/* Error out and cleanup code */
-exitfree:
-	kfree(new_client);
-exit:
-	return err;
-}
-static int __init sm_adm1026_init(void)
-{
-	return i2c_add_driver(&adm1026_driver);
-}
-
-static void  __exit sm_adm1026_exit(void)
-{
-	i2c_del_driver(&adm1026_driver);
-}
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Philip Pokorny <ppokorny@penguincomputing.com>, "
-              "Justin Thiessen <jthiessen@penguincomputing.com>");
-MODULE_DESCRIPTION("ADM1026 driver");
-
-module_init(sm_adm1026_init);
-module_exit(sm_adm1026_exit);
diff --git a/drivers/i2c/chips/adm1031.c b/drivers/i2c/chips/adm1031.c
deleted file mode 100644
--- a/drivers/i2c/chips/adm1031.c
+++ /dev/null
@@ -1,977 +0,0 @@
-/*
-  adm1031.c - Part of lm_sensors, Linux kernel modules for hardware
-  monitoring
-  Based on lm75.c and lm85.c
-  Supports adm1030 / adm1031
-  Copyright (C) 2004 Alexandre d'Alton <alex@alexdalton.org>
-  Reworked by Jean Delvare <khali@linux-fr.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.
-*/
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/jiffies.h>
-#include <linux/i2c.h>
-#include <linux/i2c-sensor.h>
-
-/* Following macros takes channel parameter starting from 0 to 2 */
-#define ADM1031_REG_FAN_SPEED(nr)	(0x08 + (nr))
-#define ADM1031_REG_FAN_DIV(nr)		(0x20  + (nr))
-#define ADM1031_REG_PWM			(0x22)
-#define ADM1031_REG_FAN_MIN(nr)		(0x10 + (nr))
-
-#define ADM1031_REG_TEMP_MAX(nr)	(0x14  + 4*(nr))
-#define ADM1031_REG_TEMP_MIN(nr)	(0x15  + 4*(nr))
-#define ADM1031_REG_TEMP_CRIT(nr)	(0x16  + 4*(nr))
-
-#define ADM1031_REG_TEMP(nr)		(0xa + (nr))
-#define ADM1031_REG_AUTO_TEMP(nr)	(0x24 + (nr))
-
-#define ADM1031_REG_STATUS(nr)		(0x2 + (nr))
-
-#define ADM1031_REG_CONF1		0x0
-#define ADM1031_REG_CONF2		0x1
-#define ADM1031_REG_EXT_TEMP		0x6
-
-#define ADM1031_CONF1_MONITOR_ENABLE	0x01	/* Monitoring enable */
-#define ADM1031_CONF1_PWM_INVERT	0x08	/* PWM Invert */
-#define ADM1031_CONF1_AUTO_MODE		0x80	/* Auto FAN */
-
-#define ADM1031_CONF2_PWM1_ENABLE	0x01
-#define ADM1031_CONF2_PWM2_ENABLE	0x02
-#define ADM1031_CONF2_TACH1_ENABLE	0x04
-#define ADM1031_CONF2_TACH2_ENABLE	0x08
-#define ADM1031_CONF2_TEMP_ENABLE(chan)	(0x10 << (chan))
-
-/* Addresses to scan */
-static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END };
-static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
-
-/* Insmod parameters */
-SENSORS_INSMOD_2(adm1030, adm1031);
-
-typedef u8 auto_chan_table_t[8][2];
-
-/* Each client has this additional data */
-struct adm1031_data {
-	struct i2c_client client;
-	struct semaphore update_lock;
-	int chip_type;
-	char valid;		/* !=0 if following fields are valid */
-	unsigned long last_updated;	/* In jiffies */
-	/* The chan_select_table contains the possible configurations for
-	 * auto fan control.
-	 */
-	auto_chan_table_t *chan_select_table;
-	u16 alarm;
-	u8 conf1;
-	u8 conf2;
-	u8 fan[2];
-	u8 fan_div[2];
-	u8 fan_min[2];
-	u8 pwm[2];
-	u8 old_pwm[2];
-	s8 temp[3];
-	u8 ext_temp[3];
-	u8 auto_temp[3];
-	u8 auto_temp_min[3];
-	u8 auto_temp_off[3];
-	u8 auto_temp_max[3];
-	s8 temp_min[3];
-	s8 temp_max[3];
-	s8 temp_crit[3];
-};
-
-static int adm1031_attach_adapter(struct i2c_adapter *adapter);
-static int adm1031_detect(struct i2c_adapter *adapter, int address, int kind);
-static void adm1031_init_client(struct i2c_client *client);
-static int adm1031_detach_client(struct i2c_client *client);
-static struct adm1031_data *adm1031_update_device(struct device *dev);
-
-/* This is the driver that will be inserted */
-static struct i2c_driver adm1031_driver = {
-	.owner = THIS_MODULE,
-	.name = "adm1031",
-	.flags = I2C_DF_NOTIFY,
-	.attach_adapter = adm1031_attach_adapter,
-	.detach_client = adm1031_detach_client,
-};
-
-static inline u8 adm1031_read_value(struct i2c_client *client, u8 reg)
-{
-	return i2c_smbus_read_byte_data(client, reg);
-}
-
-static inline int
-adm1031_write_value(struct i2c_client *client, u8 reg, unsigned int value)
-{
-	return i2c_smbus_write_byte_data(client, reg, value);
-}
-
-
-#define TEMP_TO_REG(val)		(((val) < 0 ? ((val - 500) / 1000) : \
-					((val + 500) / 1000)))
-
-#define TEMP_FROM_REG(val)		((val) * 1000)
-
-#define TEMP_FROM_REG_EXT(val, ext)	(TEMP_FROM_REG(val) + (ext) * 125)
-
-#define FAN_FROM_REG(reg, div)		((reg) ? (11250 * 60) / ((reg) * (div)) : 0)
-
-static int FAN_TO_REG(int reg, int div)
-{
-	int tmp;
-	tmp = FAN_FROM_REG(SENSORS_LIMIT(reg, 0, 65535), div);
-	return tmp > 255 ? 255 : tmp;
-}
-
-#define FAN_DIV_FROM_REG(reg)		(1<<(((reg)&0xc0)>>6))
-
-#define PWM_TO_REG(val)			(SENSORS_LIMIT((val), 0, 255) >> 4)
-#define PWM_FROM_REG(val)		((val) << 4)
-
-#define FAN_CHAN_FROM_REG(reg)		(((reg) >> 5) & 7)
-#define FAN_CHAN_TO_REG(val, reg)	\
-	(((reg) & 0x1F) | (((val) << 5) & 0xe0))
-
-#define AUTO_TEMP_MIN_TO_REG(val, reg)	\
-	((((val)/500) & 0xf8)|((reg) & 0x7))
-#define AUTO_TEMP_RANGE_FROM_REG(reg)	(5000 * (1<< ((reg)&0x7)))
-#define AUTO_TEMP_MIN_FROM_REG(reg)	(1000 * ((((reg) >> 3) & 0x1f) << 2))
-
-#define AUTO_TEMP_MIN_FROM_REG_DEG(reg)	((((reg) >> 3) & 0x1f) << 2)
-
-#define AUTO_TEMP_OFF_FROM_REG(reg)		\
-	(AUTO_TEMP_MIN_FROM_REG(reg) - 5000)
-
-#define AUTO_TEMP_MAX_FROM_REG(reg)		\
-	(AUTO_TEMP_RANGE_FROM_REG(reg) +	\
-	AUTO_TEMP_MIN_FROM_REG(reg))
-
-static int AUTO_TEMP_MAX_TO_REG(int val, int reg, int pwm)
-{
-	int ret;
-	int range = val - AUTO_TEMP_MIN_FROM_REG(reg);
-
-	range = ((val - AUTO_TEMP_MIN_FROM_REG(reg))*10)/(16 - pwm);
-	ret = ((reg & 0xf8) |
-	       (range < 10000 ? 0 :
-		range < 20000 ? 1 :
-		range < 40000 ? 2 : range < 80000 ? 3 : 4));
-	return ret;
-}
-
-/* FAN auto control */
-#define GET_FAN_AUTO_BITFIELD(data, idx)	\
-	(*(data)->chan_select_table)[FAN_CHAN_FROM_REG((data)->conf1)][idx%2]
-
-/* The tables below contains the possible values for the auto fan 
- * control bitfields. the index in the table is the register value.
- * MSb is the auto fan control enable bit, so the four first entries
- * in the table disables auto fan control when both bitfields are zero.
- */
-static auto_chan_table_t auto_channel_select_table_adm1031 = {
-	{0, 0}, {0, 0}, {0, 0}, {0, 0},
-	{2 /*0b010 */ , 4 /*0b100 */ },
-	{2 /*0b010 */ , 2 /*0b010 */ },
-	{4 /*0b100 */ , 4 /*0b100 */ },
-	{7 /*0b111 */ , 7 /*0b111 */ },
-};
-
-static auto_chan_table_t auto_channel_select_table_adm1030 = {
-	{0, 0}, {0, 0}, {0, 0}, {0, 0},
-	{2 /*0b10 */		, 0},
-	{0xff /*invalid */	, 0},
-	{0xff /*invalid */	, 0},
-	{3 /*0b11 */		, 0},
-};
-
-/* That function checks if a bitfield is valid and returns the other bitfield
- * nearest match if no exact match where found.
- */
-static int
-get_fan_auto_nearest(struct adm1031_data *data,
-		     int chan, u8 val, u8 reg, u8 * new_reg)
-{
-	int i;
-	int first_match = -1, exact_match = -1;
-	u8 other_reg_val =
-	    (*data->chan_select_table)[FAN_CHAN_FROM_REG(reg)][chan ? 0 : 1];
-
-	if (val == 0) {
-		*new_reg = 0;
-		return 0;
-	}
-
-	for (i = 0; i < 8; i++) {
-		if ((val == (*data->chan_select_table)[i][chan]) &&
-		    ((*data->chan_select_table)[i][chan ? 0 : 1] ==
-		     other_reg_val)) {
-			/* We found an exact match */
-			exact_match = i;
-			break;
-		} else if (val == (*data->chan_select_table)[i][chan] &&
-			   first_match == -1) {
-			/* Save the first match in case of an exact match has not been
-			 * found 
-			 */
-			first_match = i;
-		}
-	}
-
-	if (exact_match >= 0) {
-		*new_reg = exact_match;
-	} else if (first_match >= 0) {
-		*new_reg = first_match;
-	} else {
-		return -EINVAL;
-	}
-	return 0;
-}
-
-static ssize_t show_fan_auto_channel(struct device *dev, char *buf, int nr)
-{
-	struct adm1031_data *data = adm1031_update_device(dev);
-	return sprintf(buf, "%d\n", GET_FAN_AUTO_BITFIELD(data, nr));
-}
-
-static ssize_t
-set_fan_auto_channel(struct device *dev, const char *buf, size_t count, int nr)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm1031_data *data = i2c_get_clientdata(client);
-	int val = simple_strtol(buf, NULL, 10);
-	u8 reg;
-	int ret;
-	u8 old_fan_mode;
-
-	old_fan_mode = data->conf1;
-
-	down(&data->update_lock);
-	
-	if ((ret = get_fan_auto_nearest(data, nr, val, data->conf1, &reg))) {
-		up(&data->update_lock);
-		return ret;
-	}
-	if (((data->conf1 = FAN_CHAN_TO_REG(reg, data->conf1)) & ADM1031_CONF1_AUTO_MODE) ^ 
-	    (old_fan_mode & ADM1031_CONF1_AUTO_MODE)) {
-		if (data->conf1 & ADM1031_CONF1_AUTO_MODE){
-			/* Switch to Auto Fan Mode 
-			 * Save PWM registers 
-			 * Set PWM registers to 33% Both */
-			data->old_pwm[0] = data->pwm[0];
-			data->old_pwm[1] = data->pwm[1];
-			adm1031_write_value(client, ADM1031_REG_PWM, 0x55);
-		} else {
-			/* Switch to Manual Mode */
-			data->pwm[0] = data->old_pwm[0];
-			data->pwm[1] = data->old_pwm[1];
-			/* Restore PWM registers */
-			adm1031_write_value(client, ADM1031_REG_PWM, 
-					    data->pwm[0] | (data->pwm[1] << 4));
-		}
-	}
-	data->conf1 = FAN_CHAN_TO_REG(reg, data->conf1);
-	adm1031_write_value(client, ADM1031_REG_CONF1, data->conf1);
-	up(&data->update_lock);
-	return count;
-}
-
-#define fan_auto_channel_offset(offset)						\
-static ssize_t show_fan_auto_channel_##offset (struct device *dev, char *buf)	\
-{										\
-	return show_fan_auto_channel(dev, buf, offset - 1);			\
-}										\
-static ssize_t set_fan_auto_channel_##offset (struct device *dev,		\
-	const char *buf, size_t count)						\
-{										\
-	return set_fan_auto_channel(dev, buf, count, offset - 1);		\
-}										\
-static DEVICE_ATTR(auto_fan##offset##_channel, S_IRUGO | S_IWUSR,		\
-		   show_fan_auto_channel_##offset,				\
-		   set_fan_auto_channel_##offset)
-
-fan_auto_channel_offset(1);
-fan_auto_channel_offset(2);
-
-/* Auto Temps */
-static ssize_t show_auto_temp_off(struct device *dev, char *buf, int nr)
-{
-	struct adm1031_data *data = adm1031_update_device(dev);
-	return sprintf(buf, "%d\n", 
-		       AUTO_TEMP_OFF_FROM_REG(data->auto_temp[nr]));
-}
-static ssize_t show_auto_temp_min(struct device *dev, char *buf, int nr)
-{
-	struct adm1031_data *data = adm1031_update_device(dev);
-	return sprintf(buf, "%d\n",
-		       AUTO_TEMP_MIN_FROM_REG(data->auto_temp[nr]));
-}
-static ssize_t
-set_auto_temp_min(struct device *dev, const char *buf, size_t count, int nr)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm1031_data *data = i2c_get_clientdata(client);
-	int val = simple_strtol(buf, NULL, 10);
-
-	down(&data->update_lock);
-	data->auto_temp[nr] = AUTO_TEMP_MIN_TO_REG(val, data->auto_temp[nr]);
-	adm1031_write_value(client, ADM1031_REG_AUTO_TEMP(nr),
-			    data->auto_temp[nr]);
-	up(&data->update_lock);
-	return count;
-}
-static ssize_t show_auto_temp_max(struct device *dev, char *buf, int nr)
-{
-	struct adm1031_data *data = adm1031_update_device(dev);
-	return sprintf(buf, "%d\n",
-		       AUTO_TEMP_MAX_FROM_REG(data->auto_temp[nr]));
-}
-static ssize_t
-set_auto_temp_max(struct device *dev, const char *buf, size_t count, int nr)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm1031_data *data = i2c_get_clientdata(client);
-	int val = simple_strtol(buf, NULL, 10);
-
-	down(&data->update_lock);
-	data->temp_max[nr] = AUTO_TEMP_MAX_TO_REG(val, data->auto_temp[nr], data->pwm[nr]);
-	adm1031_write_value(client, ADM1031_REG_AUTO_TEMP(nr),
-			    data->temp_max[nr]);
-	up(&data->update_lock);
-	return count;
-}
-
-#define auto_temp_reg(offset)							\
-static ssize_t show_auto_temp_##offset##_off (struct device *dev, char *buf)	\
-{										\
-	return show_auto_temp_off(dev, buf, offset - 1);			\
-}										\
-static ssize_t show_auto_temp_##offset##_min (struct device *dev, char *buf)	\
-{										\
-	return show_auto_temp_min(dev, buf, offset - 1);			\
-}										\
-static ssize_t show_auto_temp_##offset##_max (struct device *dev, char *buf)	\
-{										\
-	return show_auto_temp_max(dev, buf, offset - 1);			\
-}										\
-static ssize_t set_auto_temp_##offset##_min (struct device *dev,		\
-					     const char *buf, size_t count)	\
-{										\
-	return set_auto_temp_min(dev, buf, count, offset - 1);		\
-}										\
-static ssize_t set_auto_temp_##offset##_max (struct device *dev,		\
-					     const char *buf, size_t count)	\
-{										\
-	return set_auto_temp_max(dev, buf, count, offset - 1);		\
-}										\
-static DEVICE_ATTR(auto_temp##offset##_off, S_IRUGO,				\
-		   show_auto_temp_##offset##_off, NULL);			\
-static DEVICE_ATTR(auto_temp##offset##_min, S_IRUGO | S_IWUSR,			\
-		   show_auto_temp_##offset##_min, set_auto_temp_##offset##_min);\
-static DEVICE_ATTR(auto_temp##offset##_max, S_IRUGO | S_IWUSR,			\
-		   show_auto_temp_##offset##_max, set_auto_temp_##offset##_max)
-
-auto_temp_reg(1);
-auto_temp_reg(2);
-auto_temp_reg(3);
-
-/* pwm */
-static ssize_t show_pwm(struct device *dev, char *buf, int nr)
-{
-	struct adm1031_data *data = adm1031_update_device(dev);
-	return sprintf(buf, "%d\n", PWM_FROM_REG(data->pwm[nr]));
-}
-static ssize_t
-set_pwm(struct device *dev, const char *buf, size_t count, int nr)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm1031_data *data = i2c_get_clientdata(client);
-	int val = simple_strtol(buf, NULL, 10);
-	int reg;
-
-	down(&data->update_lock);
-	if ((data->conf1 & ADM1031_CONF1_AUTO_MODE) && 
-	    (((val>>4) & 0xf) != 5)) {
-		/* In automatic mode, the only PWM accepted is 33% */
-		up(&data->update_lock);
-		return -EINVAL;
-	}
-	data->pwm[nr] = PWM_TO_REG(val);
-	reg = adm1031_read_value(client, ADM1031_REG_PWM);
-	adm1031_write_value(client, ADM1031_REG_PWM,
-			    nr ? ((data->pwm[nr] << 4) & 0xf0) | (reg & 0xf)
-			    : (data->pwm[nr] & 0xf) | (reg & 0xf0));
-	up(&data->update_lock);
-	return count;
-}
-
-#define pwm_reg(offset)							\
-static ssize_t show_pwm_##offset (struct device *dev, char *buf)	\
-{									\
-	return show_pwm(dev, buf, offset - 1);			\
-}									\
-static ssize_t set_pwm_##offset (struct device *dev,			\
-				 const char *buf, size_t count)		\
-{									\
-	return set_pwm(dev, buf, count, offset - 1);		\
-}									\
-static DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR,			\
-		   show_pwm_##offset, set_pwm_##offset)
-
-pwm_reg(1);
-pwm_reg(2);
-
-/* Fans */
-
-/*
- * That function checks the cases where the fan reading is not
- * relevent.  It is used to provide 0 as fan reading when the fan is
- * not supposed to run
- */
-static int trust_fan_readings(struct adm1031_data *data, int chan)
-{
-	int res = 0;
-
-	if (data->conf1 & ADM1031_CONF1_AUTO_MODE) {
-		switch (data->conf1 & 0x60) {
-		case 0x00:	/* remote temp1 controls fan1 remote temp2 controls fan2 */
-			res = data->temp[chan+1] >=
-			      AUTO_TEMP_MIN_FROM_REG_DEG(data->auto_temp[chan+1]);
-			break;
-		case 0x20:	/* remote temp1 controls both fans */
-			res =
-			    data->temp[1] >=
-			    AUTO_TEMP_MIN_FROM_REG_DEG(data->auto_temp[1]);
-			break;
-		case 0x40:	/* remote temp2 controls both fans */
-			res =
-			    data->temp[2] >=
-			    AUTO_TEMP_MIN_FROM_REG_DEG(data->auto_temp[2]);
-			break;
-		case 0x60:	/* max controls both fans */
-			res =
-			    data->temp[0] >=
-			    AUTO_TEMP_MIN_FROM_REG_DEG(data->auto_temp[0])
-			    || data->temp[1] >=
-			    AUTO_TEMP_MIN_FROM_REG_DEG(data->auto_temp[1])
-			    || (data->chip_type == adm1031 
-				&& data->temp[2] >=
-				AUTO_TEMP_MIN_FROM_REG_DEG(data->auto_temp[2]));
-			break;
-		}
-	} else {
-		res = data->pwm[chan] > 0;
-	}
-	return res;
-}
-
-
-static ssize_t show_fan(struct device *dev, char *buf, int nr)
-{
-	struct adm1031_data *data = adm1031_update_device(dev);
-	int value;
-
-	value = trust_fan_readings(data, nr) ? FAN_FROM_REG(data->fan[nr],
-				 FAN_DIV_FROM_REG(data->fan_div[nr])) : 0;
-	return sprintf(buf, "%d\n", value);
-}
-
-static ssize_t show_fan_div(struct device *dev, char *buf, int nr)
-{
-	struct adm1031_data *data = adm1031_update_device(dev);
-	return sprintf(buf, "%d\n", FAN_DIV_FROM_REG(data->fan_div[nr]));
-}
-static ssize_t show_fan_min(struct device *dev, char *buf, int nr)
-{
-	struct adm1031_data *data = adm1031_update_device(dev);
-	return sprintf(buf, "%d\n",
-		       FAN_FROM_REG(data->fan_min[nr],
-				    FAN_DIV_FROM_REG(data->fan_div[nr])));
-}
-static ssize_t
-set_fan_min(struct device *dev, const char *buf, size_t count, int nr)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm1031_data *data = i2c_get_clientdata(client);
-	int val = simple_strtol(buf, NULL, 10);
-
-	down(&data->update_lock);
-	if (val) {
-		data->fan_min[nr] = 
-			FAN_TO_REG(val, FAN_DIV_FROM_REG(data->fan_div[nr]));
-	} else {
-		data->fan_min[nr] = 0xff;
-	}
-	adm1031_write_value(client, ADM1031_REG_FAN_MIN(nr), data->fan_min[nr]);
-	up(&data->update_lock);
-	return count;
-}
-static ssize_t
-set_fan_div(struct device *dev, const char *buf, size_t count, int nr)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm1031_data *data = i2c_get_clientdata(client);
-	int val = simple_strtol(buf, NULL, 10);
-	u8 tmp;
-	int old_div;
-	int new_min;
-
-	tmp = val == 8 ? 0xc0 :
-	      val == 4 ? 0x80 :
-	      val == 2 ? 0x40 :	
-	      val == 1 ? 0x00 :  
-	      0xff;
-	if (tmp == 0xff)
-		return -EINVAL;
-	
-	down(&data->update_lock);
-	old_div = FAN_DIV_FROM_REG(data->fan_div[nr]);
-	data->fan_div[nr] = (tmp & 0xC0) | (0x3f & data->fan_div[nr]);
-	new_min = data->fan_min[nr] * old_div / 
-		FAN_DIV_FROM_REG(data->fan_div[nr]);
-	data->fan_min[nr] = new_min > 0xff ? 0xff : new_min;
-	data->fan[nr] = data->fan[nr] * old_div / 
-		FAN_DIV_FROM_REG(data->fan_div[nr]);
-
-	adm1031_write_value(client, ADM1031_REG_FAN_DIV(nr), 
-			    data->fan_div[nr]);
-	adm1031_write_value(client, ADM1031_REG_FAN_MIN(nr), 
-			    data->fan_min[nr]);
-	up(&data->update_lock);
-	return count;
-}
-
-#define fan_offset(offset)						\
-static ssize_t show_fan_##offset (struct device *dev, char *buf)	\
-{									\
-	return show_fan(dev, buf, offset - 1);			\
-}									\
-static ssize_t show_fan_##offset##_min (struct device *dev, char *buf)	\
-{									\
-	return show_fan_min(dev, buf, offset - 1);			\
-}									\
-static ssize_t show_fan_##offset##_div (struct device *dev, char *buf)	\
-{									\
-	return show_fan_div(dev, buf, offset - 1);			\
-}									\
-static ssize_t set_fan_##offset##_min (struct device *dev,		\
-	const char *buf, size_t count)					\
-{									\
-	return set_fan_min(dev, buf, count, offset - 1);		\
-}									\
-static ssize_t set_fan_##offset##_div (struct device *dev,		\
-	const char *buf, size_t count)					\
-{									\
-	return set_fan_div(dev, buf, count, offset - 1);		\
-}									\
-static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_fan_##offset,	\
-		   NULL);						\
-static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR,		\
-		   show_fan_##offset##_min, set_fan_##offset##_min);	\
-static DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR,		\
-		   show_fan_##offset##_div, set_fan_##offset##_div);	\
-static DEVICE_ATTR(auto_fan##offset##_min_pwm, S_IRUGO | S_IWUSR,	\
-		   show_pwm_##offset, set_pwm_##offset)
-
-fan_offset(1);
-fan_offset(2);
-
-
-/* Temps */
-static ssize_t show_temp(struct device *dev, char *buf, int nr)
-{
-	struct adm1031_data *data = adm1031_update_device(dev);
-	int ext;
-	ext = nr == 0 ?
-	    ((data->ext_temp[nr] >> 6) & 0x3) * 2 :
-	    (((data->ext_temp[nr] >> ((nr - 1) * 3)) & 7));
-	return sprintf(buf, "%d\n", TEMP_FROM_REG_EXT(data->temp[nr], ext));
-}
-static ssize_t show_temp_min(struct device *dev, char *buf, int nr)
-{
-	struct adm1031_data *data = adm1031_update_device(dev);
-	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_min[nr]));
-}
-static ssize_t show_temp_max(struct device *dev, char *buf, int nr)
-{
-	struct adm1031_data *data = adm1031_update_device(dev);
-	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_max[nr]));
-}
-static ssize_t show_temp_crit(struct device *dev, char *buf, int nr)
-{
-	struct adm1031_data *data = adm1031_update_device(dev);
-	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_crit[nr]));
-}
-static ssize_t
-set_temp_min(struct device *dev, const char *buf, size_t count, int nr)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm1031_data *data = i2c_get_clientdata(client);
-	int val;
-
-	val = simple_strtol(buf, NULL, 10);
-	val = SENSORS_LIMIT(val, -55000, nr == 0 ? 127750 : 127875);
-	down(&data->update_lock);
-	data->temp_min[nr] = TEMP_TO_REG(val);
-	adm1031_write_value(client, ADM1031_REG_TEMP_MIN(nr),
-			    data->temp_min[nr]);
-	up(&data->update_lock);
-	return count;
-}
-static ssize_t
-set_temp_max(struct device *dev, const char *buf, size_t count, int nr)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm1031_data *data = i2c_get_clientdata(client);
-	int val;
-
-	val = simple_strtol(buf, NULL, 10);
-	val = SENSORS_LIMIT(val, -55000, nr == 0 ? 127750 : 127875);
-	down(&data->update_lock);
-	data->temp_max[nr] = TEMP_TO_REG(val);
-	adm1031_write_value(client, ADM1031_REG_TEMP_MAX(nr),
-			    data->temp_max[nr]);
-	up(&data->update_lock);
-	return count;
-}
-static ssize_t
-set_temp_crit(struct device *dev, const char *buf, size_t count, int nr)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm1031_data *data = i2c_get_clientdata(client);
-	int val;
-
-	val = simple_strtol(buf, NULL, 10);
-	val = SENSORS_LIMIT(val, -55000, nr == 0 ? 127750 : 127875);
-	down(&data->update_lock);
-	data->temp_crit[nr] = TEMP_TO_REG(val);
-	adm1031_write_value(client, ADM1031_REG_TEMP_CRIT(nr),
-			    data->temp_crit[nr]);
-	up(&data->update_lock);
-	return count;
-}
-
-#define temp_reg(offset)							\
-static ssize_t show_temp_##offset (struct device *dev, char *buf)		\
-{										\
-	return show_temp(dev, buf, offset - 1);				\
-}										\
-static ssize_t show_temp_##offset##_min (struct device *dev, char *buf)		\
-{										\
-	return show_temp_min(dev, buf, offset - 1);				\
-}										\
-static ssize_t show_temp_##offset##_max (struct device *dev, char *buf)		\
-{										\
-	return show_temp_max(dev, buf, offset - 1);				\
-}										\
-static ssize_t show_temp_##offset##_crit (struct device *dev, char *buf)	\
-{										\
-	return show_temp_crit(dev, buf, offset - 1);			\
-}										\
-static ssize_t set_temp_##offset##_min (struct device *dev,			\
-					const char *buf, size_t count)		\
-{										\
-	return set_temp_min(dev, buf, count, offset - 1);			\
-}										\
-static ssize_t set_temp_##offset##_max (struct device *dev,			\
-					const char *buf, size_t count)		\
-{										\
-	return set_temp_max(dev, buf, count, offset - 1);			\
-}										\
-static ssize_t set_temp_##offset##_crit (struct device *dev,			\
-					 const char *buf, size_t count)		\
-{										\
-	return set_temp_crit(dev, buf, count, offset - 1);			\
-}										\
-static DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_temp_##offset,		\
-		   NULL);							\
-static DEVICE_ATTR(temp##offset##_min, S_IRUGO | S_IWUSR,			\
-		   show_temp_##offset##_min, set_temp_##offset##_min);		\
-static DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR,			\
-		   show_temp_##offset##_max, set_temp_##offset##_max);		\
-static DEVICE_ATTR(temp##offset##_crit, S_IRUGO | S_IWUSR,			\
-		   show_temp_##offset##_crit, set_temp_##offset##_crit)
-
-temp_reg(1);
-temp_reg(2);
-temp_reg(3);
-
-/* Alarms */
-static ssize_t show_alarms(struct device *dev, char *buf)
-{
-	struct adm1031_data *data = adm1031_update_device(dev);
-	return sprintf(buf, "%d\n", data->alarm);
-}
-
-static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
-
-
-static int adm1031_attach_adapter(struct i2c_adapter *adapter)
-{
-	if (!(adapter->class & I2C_CLASS_HWMON))
-		return 0;
-	return i2c_detect(adapter, &addr_data, adm1031_detect);
-}
-
-/* This function is called by i2c_detect */
-static int adm1031_detect(struct i2c_adapter *adapter, int address, int kind)
-{
-	struct i2c_client *new_client;
-	struct adm1031_data *data;
-	int err = 0;
-	const char *name = "";
-
-	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
-		goto exit;
-
-	if (!(data = kmalloc(sizeof(struct adm1031_data), GFP_KERNEL))) {
-		err = -ENOMEM;
-		goto exit;
-	}
-	memset(data, 0, sizeof(struct adm1031_data));
-
-	new_client = &data->client;
-	i2c_set_clientdata(new_client, data);
-	new_client->addr = address;
-	new_client->adapter = adapter;
-	new_client->driver = &adm1031_driver;
-	new_client->flags = 0;
-
-	if (kind < 0) {
-		int id, co;
-		id = i2c_smbus_read_byte_data(new_client, 0x3d);
-		co = i2c_smbus_read_byte_data(new_client, 0x3e);
-
-		if (!((id == 0x31 || id == 0x30) && co == 0x41))
-			goto exit_free;
-		kind = (id == 0x30) ? adm1030 : adm1031;
-	}
-
-	if (kind <= 0)
-		kind = adm1031;
-
-	/* Given the detected chip type, set the chip name and the
-	 * auto fan control helper table. */
-	if (kind == adm1030) {
-		name = "adm1030";
-		data->chan_select_table = &auto_channel_select_table_adm1030;
-	} else if (kind == adm1031) {
-		name = "adm1031";
-		data->chan_select_table = &auto_channel_select_table_adm1031;
-	}
-	data->chip_type = kind;
-
-	strlcpy(new_client->name, name, I2C_NAME_SIZE);
-	data->valid = 0;
-	init_MUTEX(&data->update_lock);
-
-	/* Tell the I2C layer a new client has arrived */
-	if ((err = i2c_attach_client(new_client)))
-		goto exit_free;
-
-	/* Initialize the ADM1031 chip */
-	adm1031_init_client(new_client);
-
-	/* Register sysfs hooks */
-	device_create_file(&new_client->dev, &dev_attr_fan1_input);
-	device_create_file(&new_client->dev, &dev_attr_fan1_div);
-	device_create_file(&new_client->dev, &dev_attr_fan1_min);
-	device_create_file(&new_client->dev, &dev_attr_pwm1);
-	device_create_file(&new_client->dev, &dev_attr_auto_fan1_channel);
-	device_create_file(&new_client->dev, &dev_attr_temp1_input);
-	device_create_file(&new_client->dev, &dev_attr_temp1_min);
-	device_create_file(&new_client->dev, &dev_attr_temp1_max);
-	device_create_file(&new_client->dev, &dev_attr_temp1_crit);
-	device_create_file(&new_client->dev, &dev_attr_temp2_input);
-	device_create_file(&new_client->dev, &dev_attr_temp2_min);
-	device_create_file(&new_client->dev, &dev_attr_temp2_max);
-	device_create_file(&new_client->dev, &dev_attr_temp2_crit);
-
-	device_create_file(&new_client->dev, &dev_attr_auto_temp1_off);
-	device_create_file(&new_client->dev, &dev_attr_auto_temp1_min);
-	device_create_file(&new_client->dev, &dev_attr_auto_temp1_max);
-
-	device_create_file(&new_client->dev, &dev_attr_auto_temp2_off);
-	device_create_file(&new_client->dev, &dev_attr_auto_temp2_min);
-	device_create_file(&new_client->dev, &dev_attr_auto_temp2_max);
-
-	device_create_file(&new_client->dev, &dev_attr_auto_fan1_min_pwm);
-
-	device_create_file(&new_client->dev, &dev_attr_alarms);
-
-	if (kind == adm1031) {
-		device_create_file(&new_client->dev, &dev_attr_fan2_input);
-		device_create_file(&new_client->dev, &dev_attr_fan2_div);
-		device_create_file(&new_client->dev, &dev_attr_fan2_min);
-		device_create_file(&new_client->dev, &dev_attr_pwm2);
-		device_create_file(&new_client->dev,
-				   &dev_attr_auto_fan2_channel);
-		device_create_file(&new_client->dev, &dev_attr_temp3_input);
-		device_create_file(&new_client->dev, &dev_attr_temp3_min);
-		device_create_file(&new_client->dev, &dev_attr_temp3_max);
-		device_create_file(&new_client->dev, &dev_attr_temp3_crit);
-		device_create_file(&new_client->dev, &dev_attr_auto_temp3_off);
-		device_create_file(&new_client->dev, &dev_attr_auto_temp3_min);
-		device_create_file(&new_client->dev, &dev_attr_auto_temp3_max);
-		device_create_file(&new_client->dev, &dev_attr_auto_fan2_min_pwm);
-	}
-
-	return 0;
-
-exit_free:
-	kfree(new_client);
-exit:
-	return err;
-}
-
-static int adm1031_detach_client(struct i2c_client *client)
-{
-	int ret;
-	if ((ret = i2c_detach_client(client)) != 0) {
-		return ret;
-	}
-	kfree(client);
-	return 0;
-}
-
-static void adm1031_init_client(struct i2c_client *client)
-{
-	unsigned int read_val;
-	unsigned int mask;
-	struct adm1031_data *data = i2c_get_clientdata(client);
-
-	mask = (ADM1031_CONF2_PWM1_ENABLE | ADM1031_CONF2_TACH1_ENABLE);
-	if (data->chip_type == adm1031) {
-		mask |= (ADM1031_CONF2_PWM2_ENABLE |
-			ADM1031_CONF2_TACH2_ENABLE);
-	} 
-	/* Initialize the ADM1031 chip (enables fan speed reading ) */
-	read_val = adm1031_read_value(client, ADM1031_REG_CONF2);
-	if ((read_val | mask) != read_val) {
-	    adm1031_write_value(client, ADM1031_REG_CONF2, read_val | mask);
-	}
-
-	read_val = adm1031_read_value(client, ADM1031_REG_CONF1);
-	if ((read_val | ADM1031_CONF1_MONITOR_ENABLE) != read_val) {
-	    adm1031_write_value(client, ADM1031_REG_CONF1, read_val |
-				ADM1031_CONF1_MONITOR_ENABLE);
-	}
-
-}
-
-static struct adm1031_data *adm1031_update_device(struct device *dev)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm1031_data *data = i2c_get_clientdata(client);
-	int chan;
-
-	down(&data->update_lock);
-
-	if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
-	    || !data->valid) {
-
-		dev_dbg(&client->dev, "Starting adm1031 update\n");
-		for (chan = 0;
-		     chan < ((data->chip_type == adm1031) ? 3 : 2); chan++) {
-			u8 oldh, newh;
-
-			oldh =
-			    adm1031_read_value(client, ADM1031_REG_TEMP(chan));
-			data->ext_temp[chan] =
-			    adm1031_read_value(client, ADM1031_REG_EXT_TEMP);
-			newh =
-			    adm1031_read_value(client, ADM1031_REG_TEMP(chan));
-			if (newh != oldh) {
-				data->ext_temp[chan] =
-				    adm1031_read_value(client,
-						       ADM1031_REG_EXT_TEMP);
-#ifdef DEBUG
-				oldh =
-				    adm1031_read_value(client,
-						       ADM1031_REG_TEMP(chan));
-
-				/* oldh is actually newer */
-				if (newh != oldh)
-					dev_warn(&client->dev,
-						 "Remote temperature may be "
-						 "wrong.\n");
-#endif
-			}
-			data->temp[chan] = newh;
-
-			data->temp_min[chan] =
-			    adm1031_read_value(client,
-					       ADM1031_REG_TEMP_MIN(chan));
-			data->temp_max[chan] =
-			    adm1031_read_value(client,
-					       ADM1031_REG_TEMP_MAX(chan));
-			data->temp_crit[chan] =
-			    adm1031_read_value(client,
-					       ADM1031_REG_TEMP_CRIT(chan));
-			data->auto_temp[chan] =
-			    adm1031_read_value(client,
-					       ADM1031_REG_AUTO_TEMP(chan));
-
-		}
-
-		data->conf1 = adm1031_read_value(client, ADM1031_REG_CONF1);
-		data->conf2 = adm1031_read_value(client, ADM1031_REG_CONF2);
-
-		data->alarm = adm1031_read_value(client, ADM1031_REG_STATUS(0))
-			     | (adm1031_read_value(client, ADM1031_REG_STATUS(1))
-				<< 8);
-		if (data->chip_type == adm1030) {
-			data->alarm &= 0xc0ff;
-		}
-		
-		for (chan=0; chan<(data->chip_type == adm1030 ? 1 : 2); chan++) {
-			data->fan_div[chan] =
-			    adm1031_read_value(client, ADM1031_REG_FAN_DIV(chan));
-			data->fan_min[chan] =
-			    adm1031_read_value(client, ADM1031_REG_FAN_MIN(chan));
-			data->fan[chan] =
-			    adm1031_read_value(client, ADM1031_REG_FAN_SPEED(chan));
-			data->pwm[chan] =
-			    0xf & (adm1031_read_value(client, ADM1031_REG_PWM) >> 
-				   (4*chan));
-		}
-		data->last_updated = jiffies;
-		data->valid = 1;
-	}
-
-	up(&data->update_lock);
-
-	return data;
-}
-
-static int __init sensors_adm1031_init(void)
-{
-	return i2c_add_driver(&adm1031_driver);
-}
-
-static void __exit sensors_adm1031_exit(void)
-{
-	i2c_del_driver(&adm1031_driver);
-}
-
-MODULE_AUTHOR("Alexandre d'Alton <alex@alexdalton.org>");
-MODULE_DESCRIPTION("ADM1031/ADM1030 driver");
-MODULE_LICENSE("GPL");
-
-module_init(sensors_adm1031_init);
-module_exit(sensors_adm1031_exit);
diff --git a/drivers/i2c/chips/asb100.c b/drivers/i2c/chips/asb100.c
deleted file mode 100644
--- a/drivers/i2c/chips/asb100.c
+++ /dev/null
@@ -1,1066 +0,0 @@
-/*
-    asb100.c - Part of lm_sensors, Linux kernel modules for hardware
-	        monitoring
-
-    Copyright (C) 2004 Mark M. Hoffman <mhoffman@lightlink.com>
-
-	(derived from w83781d.c)
-
-    Copyright (C) 1998 - 2003  Frodo Looijaard <frodol@dds.nl>,
-    Philip Edelbrock <phil@netroedge.com>, and
-    Mark Studebaker <mdsxyz123@yahoo.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., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-/*
-    This driver supports the hardware sensor chips: Asus ASB100 and
-    ASB100-A "BACH".
-
-    ASB100-A supports pwm1, while plain ASB100 does not.  There is no known
-    way for the driver to tell which one is there.
-
-    Chip	#vin	#fanin	#pwm	#temp	wchipid	vendid	i2c	ISA
-    asb100	7	3	1	4	0x31	0x0694	yes	no
-*/
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-#include <linux/i2c-sensor.h>
-#include <linux/i2c-vid.h>
-#include <linux/init.h>
-#include "lm75.h"
-
-/*
-	HISTORY:
-	2003-12-29	1.0.0	Ported from lm_sensors project for kernel 2.6
-*/
-#define ASB100_VERSION "1.0.0"
-
-/* I2C addresses to scan */
-static unsigned short normal_i2c[] = { 0x2d, I2C_CLIENT_END };
-
-/* ISA addresses to scan (none) */
-static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
-
-/* Insmod parameters */
-SENSORS_INSMOD_1(asb100);
-I2C_CLIENT_MODULE_PARM(force_subclients, "List of subclient addresses: "
-	"{bus, clientaddr, subclientaddr1, subclientaddr2}");
-
-/* Voltage IN registers 0-6 */
-#define ASB100_REG_IN(nr)	(0x20 + (nr))
-#define ASB100_REG_IN_MAX(nr)	(0x2b + (nr * 2))
-#define ASB100_REG_IN_MIN(nr)	(0x2c + (nr * 2))
-
-/* FAN IN registers 1-3 */
-#define ASB100_REG_FAN(nr)	(0x28 + (nr))
-#define ASB100_REG_FAN_MIN(nr)	(0x3b + (nr))
-
-/* TEMPERATURE registers 1-4 */
-static const u16 asb100_reg_temp[]	= {0, 0x27, 0x150, 0x250, 0x17};
-static const u16 asb100_reg_temp_max[]	= {0, 0x39, 0x155, 0x255, 0x18};
-static const u16 asb100_reg_temp_hyst[]	= {0, 0x3a, 0x153, 0x253, 0x19};
-
-#define ASB100_REG_TEMP(nr) (asb100_reg_temp[nr])
-#define ASB100_REG_TEMP_MAX(nr) (asb100_reg_temp_max[nr])
-#define ASB100_REG_TEMP_HYST(nr) (asb100_reg_temp_hyst[nr])
-
-#define ASB100_REG_TEMP2_CONFIG	0x0152
-#define ASB100_REG_TEMP3_CONFIG	0x0252
-
-
-#define ASB100_REG_CONFIG	0x40
-#define ASB100_REG_ALARM1	0x41
-#define ASB100_REG_ALARM2	0x42
-#define ASB100_REG_SMIM1	0x43
-#define ASB100_REG_SMIM2	0x44
-#define ASB100_REG_VID_FANDIV	0x47
-#define ASB100_REG_I2C_ADDR	0x48
-#define ASB100_REG_CHIPID	0x49
-#define ASB100_REG_I2C_SUBADDR	0x4a
-#define ASB100_REG_PIN		0x4b
-#define ASB100_REG_IRQ		0x4c
-#define ASB100_REG_BANK		0x4e
-#define ASB100_REG_CHIPMAN	0x4f
-
-#define ASB100_REG_WCHIPID	0x58
-
-/* bit 7 -> enable, bits 0-3 -> duty cycle */
-#define ASB100_REG_PWM1		0x59
-
-/* CONVERSIONS
-   Rounding and limit checking is only done on the TO_REG variants. */
-
-/* These constants are a guess, consistent w/ w83781d */
-#define ASB100_IN_MIN (   0)
-#define ASB100_IN_MAX (4080)
-
-/* IN: 1/1000 V (0V to 4.08V)
-   REG: 16mV/bit */
-static u8 IN_TO_REG(unsigned val)
-{
-	unsigned nval = SENSORS_LIMIT(val, ASB100_IN_MIN, ASB100_IN_MAX);
-	return (nval + 8) / 16;
-}
-
-static unsigned IN_FROM_REG(u8 reg)
-{
-	return reg * 16;
-}
-
-static u8 FAN_TO_REG(long rpm, int div)
-{
-	if (rpm == -1)
-		return 0;
-	if (rpm == 0)
-		return 255;
-	rpm = SENSORS_LIMIT(rpm, 1, 1000000);
-	return SENSORS_LIMIT((1350000 + rpm * div / 2) / (rpm * div), 1, 254);
-}
-
-static int FAN_FROM_REG(u8 val, int div)
-{
-	return val==0 ? -1 : val==255 ? 0 : 1350000/(val*div);
-}
-
-/* These constants are a guess, consistent w/ w83781d */
-#define ASB100_TEMP_MIN (-128000)
-#define ASB100_TEMP_MAX ( 127000)
-
-/* TEMP: 0.001C/bit (-128C to +127C)
-   REG: 1C/bit, two's complement */
-static u8 TEMP_TO_REG(int temp)
-{
-	int ntemp = SENSORS_LIMIT(temp, ASB100_TEMP_MIN, ASB100_TEMP_MAX);
-	ntemp += (ntemp<0 ? -500 : 500);
-	return (u8)(ntemp / 1000);
-}
-
-static int TEMP_FROM_REG(u8 reg)
-{
-	return (s8)reg * 1000;
-}
-
-/* PWM: 0 - 255 per sensors documentation
-   REG: (6.25% duty cycle per bit) */
-static u8 ASB100_PWM_TO_REG(int pwm)
-{
-	pwm = SENSORS_LIMIT(pwm, 0, 255);
-	return (u8)(pwm / 16);
-}
-
-static int ASB100_PWM_FROM_REG(u8 reg)
-{
-	return reg * 16;
-}
-
-#define ALARMS_FROM_REG(val) (val)
-
-#define DIV_FROM_REG(val) (1 << (val))
-
-/* FAN DIV: 1, 2, 4, or 8 (defaults to 2)
-   REG: 0, 1, 2, or 3 (respectively) (defaults to 1) */
-static u8 DIV_TO_REG(long val)
-{
-	return val==8 ? 3 : val==4 ? 2 : val==1 ? 0 : 1;
-}
-
-/* For each registered client, we need to keep some data in memory. That
-   data is pointed to by client->data. The structure itself is
-   dynamically allocated, at the same time the client itself is allocated. */
-struct asb100_data {
-	struct i2c_client client;
-	struct semaphore lock;
-	enum chips type;
-
-	struct semaphore update_lock;
-	unsigned long last_updated;	/* In jiffies */
-
-	/* array of 2 pointers to subclients */
-	struct i2c_client *lm75[2];
-
-	char valid;		/* !=0 if following fields are valid */
-	u8 in[7];		/* Register value */
-	u8 in_max[7];		/* Register value */
-	u8 in_min[7];		/* Register value */
-	u8 fan[3];		/* Register value */
-	u8 fan_min[3];		/* Register value */
-	u16 temp[4];		/* Register value (0 and 3 are u8 only) */
-	u16 temp_max[4];	/* Register value (0 and 3 are u8 only) */
-	u16 temp_hyst[4];	/* Register value (0 and 3 are u8 only) */
-	u8 fan_div[3];		/* Register encoding, right justified */
-	u8 pwm;			/* Register encoding */
-	u8 vid;			/* Register encoding, combined */
-	u32 alarms;		/* Register encoding, combined */
-	u8 vrm;
-};
-
-static int asb100_read_value(struct i2c_client *client, u16 reg);
-static void asb100_write_value(struct i2c_client *client, u16 reg, u16 val);
-
-static int asb100_attach_adapter(struct i2c_adapter *adapter);
-static int asb100_detect(struct i2c_adapter *adapter, int address, int kind);
-static int asb100_detach_client(struct i2c_client *client);
-static struct asb100_data *asb100_update_device(struct device *dev);
-static void asb100_init_client(struct i2c_client *client);
-
-static struct i2c_driver asb100_driver = {
-	.owner		= THIS_MODULE,
-	.name		= "asb100",
-	.id		= I2C_DRIVERID_ASB100,
-	.flags		= I2C_DF_NOTIFY,
-	.attach_adapter	= asb100_attach_adapter,
-	.detach_client	= asb100_detach_client,
-};
-
-/* 7 Voltages */
-#define show_in_reg(reg) \
-static ssize_t show_##reg (struct device *dev, char *buf, int nr) \
-{ \
-	struct asb100_data *data = asb100_update_device(dev); \
-	return sprintf(buf, "%d\n", IN_FROM_REG(data->reg[nr])); \
-}
-
-show_in_reg(in)
-show_in_reg(in_min)
-show_in_reg(in_max)
-
-#define set_in_reg(REG, reg) \
-static ssize_t set_in_##reg(struct device *dev, const char *buf, \
-		size_t count, int nr) \
-{ \
-	struct i2c_client *client = to_i2c_client(dev); \
-	struct asb100_data *data = i2c_get_clientdata(client); \
-	unsigned long val = simple_strtoul(buf, NULL, 10); \
- \
-	down(&data->update_lock); \
-	data->in_##reg[nr] = IN_TO_REG(val); \
-	asb100_write_value(client, ASB100_REG_IN_##REG(nr), \
-		data->in_##reg[nr]); \
-	up(&data->update_lock); \
-	return count; \
-}
-
-set_in_reg(MIN, min)
-set_in_reg(MAX, max)
-
-#define sysfs_in(offset) \
-static ssize_t \
-	show_in##offset (struct device *dev, char *buf) \
-{ \
-	return show_in(dev, buf, offset); \
-} \
-static DEVICE_ATTR(in##offset##_input, S_IRUGO, \
-		show_in##offset, NULL); \
-static ssize_t \
-	show_in##offset##_min (struct device *dev, char *buf) \
-{ \
-	return show_in_min(dev, buf, offset); \
-} \
-static ssize_t \
-	show_in##offset##_max (struct device *dev, char *buf) \
-{ \
-	return show_in_max(dev, buf, offset); \
-} \
-static ssize_t set_in##offset##_min (struct device *dev, \
-		const char *buf, size_t count) \
-{ \
-	return set_in_min(dev, buf, count, offset); \
-} \
-static ssize_t set_in##offset##_max (struct device *dev, \
-		const char *buf, size_t count) \
-{ \
-	return set_in_max(dev, buf, count, offset); \
-} \
-static DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \
-		show_in##offset##_min, set_in##offset##_min); \
-static DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \
-		show_in##offset##_max, set_in##offset##_max);
-
-sysfs_in(0);
-sysfs_in(1);
-sysfs_in(2);
-sysfs_in(3);
-sysfs_in(4);
-sysfs_in(5);
-sysfs_in(6);
-
-#define device_create_file_in(client, offset) do { \
-	device_create_file(&client->dev, &dev_attr_in##offset##_input); \
-	device_create_file(&client->dev, &dev_attr_in##offset##_min); \
-	device_create_file(&client->dev, &dev_attr_in##offset##_max); \
-} while (0)
-
-/* 3 Fans */
-static ssize_t show_fan(struct device *dev, char *buf, int nr)
-{
-	struct asb100_data *data = asb100_update_device(dev);
-	return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[nr],
-		DIV_FROM_REG(data->fan_div[nr])));
-}
-
-static ssize_t show_fan_min(struct device *dev, char *buf, int nr)
-{
-	struct asb100_data *data = asb100_update_device(dev);
-	return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan_min[nr],
-		DIV_FROM_REG(data->fan_div[nr])));
-}
-
-static ssize_t show_fan_div(struct device *dev, char *buf, int nr)
-{
-	struct asb100_data *data = asb100_update_device(dev);
-	return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[nr]));
-}
-
-static ssize_t set_fan_min(struct device *dev, const char *buf,
-				size_t count, int nr)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct asb100_data *data = i2c_get_clientdata(client);
-	u32 val = simple_strtoul(buf, NULL, 10);
-
-	down(&data->update_lock);
-	data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr]));
-	asb100_write_value(client, ASB100_REG_FAN_MIN(nr), data->fan_min[nr]);
-	up(&data->update_lock);
-	return count;
-}
-
-/* Note: we save and restore the fan minimum here, because its value is
-   determined in part by the fan divisor.  This follows the principle of
-   least suprise; the user doesn't expect the fan minimum to change just
-   because the divisor changed. */
-static ssize_t set_fan_div(struct device *dev, const char *buf,
-				size_t count, int nr)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct asb100_data *data = i2c_get_clientdata(client);
-	unsigned long min;
-	unsigned long val = simple_strtoul(buf, NULL, 10);
-	int reg;
-	
-	down(&data->update_lock);
-
-	min = FAN_FROM_REG(data->fan_min[nr],
-			DIV_FROM_REG(data->fan_div[nr]));
-	data->fan_div[nr] = DIV_TO_REG(val);
-
-	switch(nr) {
-	case 0:	/* fan 1 */
-		reg = asb100_read_value(client, ASB100_REG_VID_FANDIV);
-		reg = (reg & 0xcf) | (data->fan_div[0] << 4);
-		asb100_write_value(client, ASB100_REG_VID_FANDIV, reg);
-		break;
-
-	case 1:	/* fan 2 */
-		reg = asb100_read_value(client, ASB100_REG_VID_FANDIV);
-		reg = (reg & 0x3f) | (data->fan_div[1] << 6);
-		asb100_write_value(client, ASB100_REG_VID_FANDIV, reg);
-		break;
-
-	case 2:	/* fan 3 */
-		reg = asb100_read_value(client, ASB100_REG_PIN);
-		reg = (reg & 0x3f) | (data->fan_div[2] << 6);
-		asb100_write_value(client, ASB100_REG_PIN, reg);
-		break;
-	}
-
-	data->fan_min[nr] =
-		FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr]));
-	asb100_write_value(client, ASB100_REG_FAN_MIN(nr), data->fan_min[nr]);
-
-	up(&data->update_lock);
-
-	return count;
-}
-
-#define sysfs_fan(offset) \
-static ssize_t show_fan##offset(struct device *dev, char *buf) \
-{ \
-	return show_fan(dev, buf, offset - 1); \
-} \
-static ssize_t show_fan##offset##_min(struct device *dev, char *buf) \
-{ \
-	return show_fan_min(dev, buf, offset - 1); \
-} \
-static ssize_t show_fan##offset##_div(struct device *dev, char *buf) \
-{ \
-	return show_fan_div(dev, buf, offset - 1); \
-} \
-static ssize_t set_fan##offset##_min(struct device *dev, const char *buf, \
-					size_t count) \
-{ \
-	return set_fan_min(dev, buf, count, offset - 1); \
-} \
-static ssize_t set_fan##offset##_div(struct device *dev, const char *buf, \
-					size_t count) \
-{ \
-	return set_fan_div(dev, buf, count, offset - 1); \
-} \
-static DEVICE_ATTR(fan##offset##_input, S_IRUGO, \
-		show_fan##offset, NULL); \
-static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \
-		show_fan##offset##_min, set_fan##offset##_min); \
-static DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, \
-		show_fan##offset##_div, set_fan##offset##_div);
-
-sysfs_fan(1);
-sysfs_fan(2);
-sysfs_fan(3);
-
-#define device_create_file_fan(client, offset) do { \
-	device_create_file(&client->dev, &dev_attr_fan##offset##_input); \
-	device_create_file(&client->dev, &dev_attr_fan##offset##_min); \
-	device_create_file(&client->dev, &dev_attr_fan##offset##_div); \
-} while (0)
-
-/* 4 Temp. Sensors */
-static int sprintf_temp_from_reg(u16 reg, char *buf, int nr)
-{
-	int ret = 0;
-
-	switch (nr) {
-	case 1: case 2:
-		ret = sprintf(buf, "%d\n", LM75_TEMP_FROM_REG(reg));
-		break;
-	case 0: case 3: default:
-		ret = sprintf(buf, "%d\n", TEMP_FROM_REG(reg));
-		break;
-	}
-	return ret;
-}
-		 	
-#define show_temp_reg(reg) \
-static ssize_t show_##reg(struct device *dev, char *buf, int nr) \
-{ \
-	struct asb100_data *data = asb100_update_device(dev); \
-	return sprintf_temp_from_reg(data->reg[nr], buf, nr); \
-}
-
-show_temp_reg(temp);
-show_temp_reg(temp_max);
-show_temp_reg(temp_hyst);
-
-#define set_temp_reg(REG, reg) \
-static ssize_t set_##reg(struct device *dev, const char *buf, \
-			size_t count, int nr) \
-{ \
-	struct i2c_client *client = to_i2c_client(dev); \
-	struct asb100_data *data = i2c_get_clientdata(client); \
-	unsigned long val = simple_strtoul(buf, NULL, 10); \
- \
-	down(&data->update_lock); \
-	switch (nr) { \
-	case 1: case 2: \
-		data->reg[nr] = LM75_TEMP_TO_REG(val); \
-		break; \
-	case 0: case 3: default: \
-		data->reg[nr] = TEMP_TO_REG(val); \
-		break; \
-	} \
-	asb100_write_value(client, ASB100_REG_TEMP_##REG(nr+1), \
-			data->reg[nr]); \
-	up(&data->update_lock); \
-	return count; \
-}
-
-set_temp_reg(MAX, temp_max);
-set_temp_reg(HYST, temp_hyst);
-
-#define sysfs_temp(num) \
-static ssize_t show_temp##num(struct device *dev, char *buf) \
-{ \
-	return show_temp(dev, buf, num-1); \
-} \
-static DEVICE_ATTR(temp##num##_input, S_IRUGO, show_temp##num, NULL); \
-static ssize_t show_temp_max##num(struct device *dev, char *buf) \
-{ \
-	return show_temp_max(dev, buf, num-1); \
-} \
-static ssize_t set_temp_max##num(struct device *dev, const char *buf, \
-					size_t count) \
-{ \
-	return set_temp_max(dev, buf, count, num-1); \
-} \
-static DEVICE_ATTR(temp##num##_max, S_IRUGO | S_IWUSR, \
-		show_temp_max##num, set_temp_max##num); \
-static ssize_t show_temp_hyst##num(struct device *dev, char *buf) \
-{ \
-	return show_temp_hyst(dev, buf, num-1); \
-} \
-static ssize_t set_temp_hyst##num(struct device *dev, const char *buf, \
-					size_t count) \
-{ \
-	return set_temp_hyst(dev, buf, count, num-1); \
-} \
-static DEVICE_ATTR(temp##num##_max_hyst, S_IRUGO | S_IWUSR, \
-		show_temp_hyst##num, set_temp_hyst##num);
-
-sysfs_temp(1);
-sysfs_temp(2);
-sysfs_temp(3);
-sysfs_temp(4);
-
-/* VID */
-#define device_create_file_temp(client, num) do { \
-	device_create_file(&client->dev, &dev_attr_temp##num##_input); \
-	device_create_file(&client->dev, &dev_attr_temp##num##_max); \
-	device_create_file(&client->dev, &dev_attr_temp##num##_max_hyst); \
-} while (0)
-
-static ssize_t show_vid(struct device *dev, char *buf)
-{
-	struct asb100_data *data = asb100_update_device(dev);
-	return sprintf(buf, "%d\n", vid_from_reg(data->vid, data->vrm));
-}
-
-static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL);
-#define device_create_file_vid(client) \
-device_create_file(&client->dev, &dev_attr_cpu0_vid)
-
-/* VRM */
-static ssize_t show_vrm(struct device *dev, char *buf)
-{
-	struct asb100_data *data = asb100_update_device(dev);
-	return sprintf(buf, "%d\n", data->vrm);
-}
-
-static ssize_t set_vrm(struct device *dev, const char *buf, size_t count)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct asb100_data *data = i2c_get_clientdata(client);
-	unsigned long val = simple_strtoul(buf, NULL, 10);
-	data->vrm = val;
-	return count;
-}
-
-/* Alarms */
-static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm, set_vrm);
-#define device_create_file_vrm(client) \
-device_create_file(&client->dev, &dev_attr_vrm);
-
-static ssize_t show_alarms(struct device *dev, char *buf)
-{
-	struct asb100_data *data = asb100_update_device(dev);
-	return sprintf(buf, "%d\n", ALARMS_FROM_REG(data->alarms));
-}
-
-static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
-#define device_create_file_alarms(client) \
-device_create_file(&client->dev, &dev_attr_alarms)
-
-/* 1 PWM */
-static ssize_t show_pwm1(struct device *dev, char *buf)
-{
-	struct asb100_data *data = asb100_update_device(dev);
-	return sprintf(buf, "%d\n", ASB100_PWM_FROM_REG(data->pwm & 0x0f));
-}
-
-static ssize_t set_pwm1(struct device *dev, const char *buf, size_t count)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct asb100_data *data = i2c_get_clientdata(client);
-	unsigned long val = simple_strtoul(buf, NULL, 10);
-
-	down(&data->update_lock);
-	data->pwm &= 0x80; /* keep the enable bit */
-	data->pwm |= (0x0f & ASB100_PWM_TO_REG(val));
-	asb100_write_value(client, ASB100_REG_PWM1, data->pwm);
-	up(&data->update_lock);
-	return count;
-}
-
-static ssize_t show_pwm_enable1(struct device *dev, char *buf)
-{
-	struct asb100_data *data = asb100_update_device(dev);
-	return sprintf(buf, "%d\n", (data->pwm & 0x80) ? 1 : 0);
-}
-
-static ssize_t set_pwm_enable1(struct device *dev, const char *buf,
-				size_t count)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct asb100_data *data = i2c_get_clientdata(client);
-	unsigned long val = simple_strtoul(buf, NULL, 10);
-
-	down(&data->update_lock);
-	data->pwm &= 0x0f; /* keep the duty cycle bits */
-	data->pwm |= (val ? 0x80 : 0x00);
-	asb100_write_value(client, ASB100_REG_PWM1, data->pwm);
-	up(&data->update_lock);
-	return count;
-}
-
-static DEVICE_ATTR(pwm1, S_IRUGO | S_IWUSR, show_pwm1, set_pwm1);
-static DEVICE_ATTR(pwm1_enable, S_IRUGO | S_IWUSR,
-		show_pwm_enable1, set_pwm_enable1);
-#define device_create_file_pwm1(client) do { \
-	device_create_file(&new_client->dev, &dev_attr_pwm1); \
-	device_create_file(&new_client->dev, &dev_attr_pwm1_enable); \
-} while (0)
-
-/* This function is called when:
-	asb100_driver is inserted (when this module is loaded), for each
-		available adapter
-	when a new adapter is inserted (and asb100_driver is still present)
- */
-static int asb100_attach_adapter(struct i2c_adapter *adapter)
-{
-	if (!(adapter->class & I2C_CLASS_HWMON))
-		return 0;
-	return i2c_detect(adapter, &addr_data, asb100_detect);
-}
-
-static int asb100_detect_subclients(struct i2c_adapter *adapter, int address,
-		int kind, struct i2c_client *new_client)
-{
-	int i, id, err;
-	struct asb100_data *data = i2c_get_clientdata(new_client);
-
-	data->lm75[0] = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
-	if (!(data->lm75[0])) {
-		err = -ENOMEM;
-		goto ERROR_SC_0;
-	}
-	memset(data->lm75[0], 0x00, sizeof(struct i2c_client));
-
-	data->lm75[1] = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
-	if (!(data->lm75[1])) {
-		err = -ENOMEM;
-		goto ERROR_SC_1;
-	}
-	memset(data->lm75[1], 0x00, sizeof(struct i2c_client));
-
-	id = i2c_adapter_id(adapter);
-
-	if (force_subclients[0] == id && force_subclients[1] == address) {
-		for (i = 2; i <= 3; i++) {
-			if (force_subclients[i] < 0x48 ||
-			    force_subclients[i] > 0x4f) {
-				dev_err(&new_client->dev, "invalid subclient "
-					"address %d; must be 0x48-0x4f\n",
-					force_subclients[i]);
-				err = -ENODEV;
-				goto ERROR_SC_2;
-			}
-		}
-		asb100_write_value(new_client, ASB100_REG_I2C_SUBADDR,
-					(force_subclients[2] & 0x07) |
-					((force_subclients[3] & 0x07) <<4));
-		data->lm75[0]->addr = force_subclients[2];
-		data->lm75[1]->addr = force_subclients[3];
-	} else {
-		int val = asb100_read_value(new_client, ASB100_REG_I2C_SUBADDR);
-		data->lm75[0]->addr = 0x48 + (val & 0x07);
-		data->lm75[1]->addr = 0x48 + ((val >> 4) & 0x07);
-	}
-
-	if(data->lm75[0]->addr == data->lm75[1]->addr) {
-		dev_err(&new_client->dev, "duplicate addresses 0x%x "
-				"for subclients\n", data->lm75[0]->addr);
-		err = -ENODEV;
-		goto ERROR_SC_2;
-	}
-
-	for (i = 0; i <= 1; i++) {
-		i2c_set_clientdata(data->lm75[i], NULL);
-		data->lm75[i]->adapter = adapter;
-		data->lm75[i]->driver = &asb100_driver;
-		data->lm75[i]->flags = 0;
-		strlcpy(data->lm75[i]->name, "asb100 subclient", I2C_NAME_SIZE);
-	}
-
-	if ((err = i2c_attach_client(data->lm75[0]))) {
-		dev_err(&new_client->dev, "subclient %d registration "
-			"at address 0x%x failed.\n", i, data->lm75[0]->addr);
-		goto ERROR_SC_2;
-	}
-
-	if ((err = i2c_attach_client(data->lm75[1]))) {
-		dev_err(&new_client->dev, "subclient %d registration "
-			"at address 0x%x failed.\n", i, data->lm75[1]->addr);
-		goto ERROR_SC_3;
-	}
-
-	return 0;
-
-/* Undo inits in case of errors */
-ERROR_SC_3:
-	i2c_detach_client(data->lm75[0]);
-ERROR_SC_2:
-	kfree(data->lm75[1]);
-ERROR_SC_1:
-	kfree(data->lm75[0]);
-ERROR_SC_0:
-	return err;
-}
-
-static int asb100_detect(struct i2c_adapter *adapter, int address, int kind)
-{
-	int err;
-	struct i2c_client *new_client;
-	struct asb100_data *data;
-
-	/* asb100 is SMBus only */
-	if (i2c_is_isa_adapter(adapter)) {
-		pr_debug("asb100.o: detect failed, "
-				"cannot attach to legacy adapter!\n");
-		err = -ENODEV;
-		goto ERROR0;
-	}
-
-	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
-		pr_debug("asb100.o: detect failed, "
-				"smbus byte data not supported!\n");
-		err = -ENODEV;
-		goto ERROR0;
-	}
-
-	/* OK. For now, we presume we have a valid client. We now create the
-	   client structure, even though we cannot fill it completely yet.
-	   But it allows us to access asb100_{read,write}_value. */
-
-	if (!(data = kmalloc(sizeof(struct asb100_data), GFP_KERNEL))) {
-		pr_debug("asb100.o: detect failed, kmalloc failed!\n");
-		err = -ENOMEM;
-		goto ERROR0;
-	}
-	memset(data, 0, sizeof(struct asb100_data));
-
-	new_client = &data->client;
-	init_MUTEX(&data->lock);
-	i2c_set_clientdata(new_client, data);
-	new_client->addr = address;
-	new_client->adapter = adapter;
-	new_client->driver = &asb100_driver;
-	new_client->flags = 0;
-
-	/* Now, we do the remaining detection. */
-
-	/* The chip may be stuck in some other bank than bank 0. This may
-	   make reading other information impossible. Specify a force=... or
-	   force_*=... parameter, and the chip will be reset to the right
-	   bank. */
-	if (kind < 0) {
-
-		int val1 = asb100_read_value(new_client, ASB100_REG_BANK);
-		int val2 = asb100_read_value(new_client, ASB100_REG_CHIPMAN);
-
-		/* If we're in bank 0 */
-		if ( (!(val1 & 0x07)) &&
-				/* Check for ASB100 ID (low byte) */
-				( ((!(val1 & 0x80)) && (val2 != 0x94)) ||
-				/* Check for ASB100 ID (high byte ) */
-				((val1 & 0x80) && (val2 != 0x06)) ) ) {
-			pr_debug("asb100.o: detect failed, "
-					"bad chip id 0x%02x!\n", val2);
-			err = -ENODEV;
-			goto ERROR1;
-		}
-
-	} /* kind < 0 */
-
-	/* We have either had a force parameter, or we have already detected
-	   Winbond. Put it now into bank 0 and Vendor ID High Byte */
-	asb100_write_value(new_client, ASB100_REG_BANK,
-		(asb100_read_value(new_client, ASB100_REG_BANK) & 0x78) | 0x80);
-
-	/* Determine the chip type. */
-	if (kind <= 0) {
-		int val1 = asb100_read_value(new_client, ASB100_REG_WCHIPID);
-		int val2 = asb100_read_value(new_client, ASB100_REG_CHIPMAN);
-
-		if ((val1 == 0x31) && (val2 == 0x06))
-			kind = asb100;
-		else {
-			if (kind == 0)
-				dev_warn(&new_client->dev, "ignoring "
-					"'force' parameter for unknown chip "
-					"at adapter %d, address 0x%02x.\n",
-					i2c_adapter_id(adapter), address);
-			err = -ENODEV;
-			goto ERROR1;
-		}
-	}
-
-	/* Fill in remaining client fields and put it into the global list */
-	strlcpy(new_client->name, "asb100", I2C_NAME_SIZE);
-	data->type = kind;
-
-	data->valid = 0;
-	init_MUTEX(&data->update_lock);
-
-	/* Tell the I2C layer a new client has arrived */
-	if ((err = i2c_attach_client(new_client)))
-		goto ERROR1;
-
-	/* Attach secondary lm75 clients */
-	if ((err = asb100_detect_subclients(adapter, address, kind,
-			new_client)))
-		goto ERROR2;
-
-	/* Initialize the chip */
-	asb100_init_client(new_client);
-
-	/* A few vars need to be filled upon startup */
-	data->fan_min[0] = asb100_read_value(new_client, ASB100_REG_FAN_MIN(0));
-	data->fan_min[1] = asb100_read_value(new_client, ASB100_REG_FAN_MIN(1));
-	data->fan_min[2] = asb100_read_value(new_client, ASB100_REG_FAN_MIN(2));
-
-	/* Register sysfs hooks */
-	device_create_file_in(new_client, 0);
-	device_create_file_in(new_client, 1);
-	device_create_file_in(new_client, 2);
-	device_create_file_in(new_client, 3);
-	device_create_file_in(new_client, 4);
-	device_create_file_in(new_client, 5);
-	device_create_file_in(new_client, 6);
-
-	device_create_file_fan(new_client, 1);
-	device_create_file_fan(new_client, 2);
-	device_create_file_fan(new_client, 3);
-
-	device_create_file_temp(new_client, 1);
-	device_create_file_temp(new_client, 2);
-	device_create_file_temp(new_client, 3);
-	device_create_file_temp(new_client, 4);
-
-	device_create_file_vid(new_client);
-	device_create_file_vrm(new_client);
-
-	device_create_file_alarms(new_client);
-
-	device_create_file_pwm1(new_client);
-
-	return 0;
-
-ERROR2:
-	i2c_detach_client(new_client);
-ERROR1:
-	kfree(data);
-ERROR0:
-	return err;
-}
-
-static int asb100_detach_client(struct i2c_client *client)
-{
-	int err;
-
-	if ((err = i2c_detach_client(client))) {
-		dev_err(&client->dev, "client deregistration failed; "
-			"client not detached.\n");
-		return err;
-	}
-
-	if (i2c_get_clientdata(client)==NULL) {
-		/* subclients */
-		kfree(client);
-	} else {
-		/* main client */
-		kfree(i2c_get_clientdata(client));
-	}
-
-	return 0;
-}
-
-/* The SMBus locks itself, usually, but nothing may access the chip between
-   bank switches. */
-static int asb100_read_value(struct i2c_client *client, u16 reg)
-{
-	struct asb100_data *data = i2c_get_clientdata(client);
-	struct i2c_client *cl;
-	int res, bank;
-
-	down(&data->lock);
-
-	bank = (reg >> 8) & 0x0f;
-	if (bank > 2)
-		/* switch banks */
-		i2c_smbus_write_byte_data(client, ASB100_REG_BANK, bank);
-
-	if (bank == 0 || bank > 2) {
-		res = i2c_smbus_read_byte_data(client, reg & 0xff);
-	} else {
-		/* switch to subclient */
-		cl = data->lm75[bank - 1];
-
-		/* convert from ISA to LM75 I2C addresses */
-		switch (reg & 0xff) {
-		case 0x50: /* TEMP */
-			res = swab16(i2c_smbus_read_word_data (cl, 0));
-			break;
-		case 0x52: /* CONFIG */
-			res = i2c_smbus_read_byte_data(cl, 1);
-			break;
-		case 0x53: /* HYST */
-			res = swab16(i2c_smbus_read_word_data (cl, 2));
-			break;
-		case 0x55: /* MAX */
-		default:
-			res = swab16(i2c_smbus_read_word_data (cl, 3));
-			break;
-		}
-	}
-
-	if (bank > 2)
-		i2c_smbus_write_byte_data(client, ASB100_REG_BANK, 0);
-
-	up(&data->lock);
-
-	return res;
-}
-
-static void asb100_write_value(struct i2c_client *client, u16 reg, u16 value)
-{
-	struct asb100_data *data = i2c_get_clientdata(client);
-	struct i2c_client *cl;
-	int bank;
-
-	down(&data->lock);
-
-	bank = (reg >> 8) & 0x0f;
-	if (bank > 2)
-		/* switch banks */
-		i2c_smbus_write_byte_data(client, ASB100_REG_BANK, bank);
-
-	if (bank == 0 || bank > 2) {
-		i2c_smbus_write_byte_data(client, reg & 0xff, value & 0xff);
-	} else {
-		/* switch to subclient */
-		cl = data->lm75[bank - 1];
-
-		/* convert from ISA to LM75 I2C addresses */
-		switch (reg & 0xff) {
-		case 0x52: /* CONFIG */
-			i2c_smbus_write_byte_data(cl, 1, value & 0xff);
-			break;
-		case 0x53: /* HYST */
-			i2c_smbus_write_word_data(cl, 2, swab16(value));
-			break;
-		case 0x55: /* MAX */
-			i2c_smbus_write_word_data(cl, 3, swab16(value));
-			break;
-		}
-	}
-
-	if (bank > 2)
-		i2c_smbus_write_byte_data(client, ASB100_REG_BANK, 0);
-
-	up(&data->lock);
-}
-
-static void asb100_init_client(struct i2c_client *client)
-{
-	struct asb100_data *data = i2c_get_clientdata(client);
-	int vid = 0;
-
-	vid = asb100_read_value(client, ASB100_REG_VID_FANDIV) & 0x0f;
-	vid |= (asb100_read_value(client, ASB100_REG_CHIPID) & 0x01) << 4;
-	data->vrm = i2c_which_vrm();
-	vid = vid_from_reg(vid, data->vrm);
-
-	/* Start monitoring */
-	asb100_write_value(client, ASB100_REG_CONFIG, 
-		(asb100_read_value(client, ASB100_REG_CONFIG) & 0xf7) | 0x01);
-}
-
-static struct asb100_data *asb100_update_device(struct device *dev)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct asb100_data *data = i2c_get_clientdata(client);
-	int i;
-
-	down(&data->update_lock);
-
-	if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
-		|| !data->valid) {
-
-		dev_dbg(&client->dev, "starting device update...\n");
-
-		/* 7 voltage inputs */
-		for (i = 0; i < 7; i++) {
-			data->in[i] = asb100_read_value(client,
-				ASB100_REG_IN(i));
-			data->in_min[i] = asb100_read_value(client,
-				ASB100_REG_IN_MIN(i));
-			data->in_max[i] = asb100_read_value(client,
-				ASB100_REG_IN_MAX(i));
-		}
-
-		/* 3 fan inputs */
-		for (i = 0; i < 3; i++) {
-			data->fan[i] = asb100_read_value(client,
-					ASB100_REG_FAN(i));
-			data->fan_min[i] = asb100_read_value(client,
-					ASB100_REG_FAN_MIN(i));
-		}
-
-		/* 4 temperature inputs */
-		for (i = 1; i <= 4; i++) {
-			data->temp[i-1] = asb100_read_value(client,
-					ASB100_REG_TEMP(i));
-			data->temp_max[i-1] = asb100_read_value(client,
-					ASB100_REG_TEMP_MAX(i));
-			data->temp_hyst[i-1] = asb100_read_value(client,
-					ASB100_REG_TEMP_HYST(i));
-		}
-
-		/* VID and fan divisors */
-		i = asb100_read_value(client, ASB100_REG_VID_FANDIV);
-		data->vid = i & 0x0f;
-		data->vid |= (asb100_read_value(client,
-				ASB100_REG_CHIPID) & 0x01) << 4;
-		data->fan_div[0] = (i >> 4) & 0x03;
-		data->fan_div[1] = (i >> 6) & 0x03;
-		data->fan_div[2] = (asb100_read_value(client,
-				ASB100_REG_PIN) >> 6) & 0x03;
-
-		/* PWM */
-		data->pwm = asb100_read_value(client, ASB100_REG_PWM1);
-
-		/* alarms */
-		data->alarms = asb100_read_value(client, ASB100_REG_ALARM1) +
-			(asb100_read_value(client, ASB100_REG_ALARM2) << 8);
-
-		data->last_updated = jiffies;
-		data->valid = 1;
-
-		dev_dbg(&client->dev, "... device update complete\n");
-	}
-
-	up(&data->update_lock);
-
-	return data;
-}
-
-static int __init asb100_init(void)
-{
-	return i2c_add_driver(&asb100_driver);
-}
-
-static void __exit asb100_exit(void)
-{
-	i2c_del_driver(&asb100_driver);
-}
-
-MODULE_AUTHOR("Mark M. Hoffman <mhoffman@lightlink.com>");
-MODULE_DESCRIPTION("ASB100 Bach driver");
-MODULE_LICENSE("GPL");
-
-module_init(asb100_init);
-module_exit(asb100_exit);
-
diff --git a/drivers/i2c/chips/ds1337.c b/drivers/i2c/chips/ds1337.c
--- a/drivers/i2c/chips/ds1337.c
+++ b/drivers/i2c/chips/ds1337.c
@@ -3,17 +3,16 @@
  *
  *  Copyright (C) 2005 James Chapman <jchapman@katalix.com>
  *
- *	based on linux/drivers/acron/char/pcf8583.c
+ *	based on linux/drivers/acorn/char/pcf8583.c
  *  Copyright (C) 2000 Russell King
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  *
- * Driver for Dallas Semiconductor DS1337 real time clock chip
+ * Driver for Dallas Semiconductor DS1337 and DS1339 real time clock chip
  */
 
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/slab.h>
@@ -69,13 +68,11 @@ static struct i2c_driver ds1337_driver =
 struct ds1337_data {
 	struct i2c_client client;
 	struct list_head list;
-	int id;
 };
 
 /*
  * Internal variables
  */
-static int ds1337_id;
 static LIST_HEAD(ds1337_clients);
 
 static inline int ds1337_read(struct i2c_client *client, u8 reg, u8 *value)
@@ -95,7 +92,6 @@ static inline int ds1337_read(struct i2c
  */
 static int ds1337_get_datetime(struct i2c_client *client, struct rtc_time *dt)
 {
-	struct ds1337_data *data = i2c_get_clientdata(client);
 	int result;
 	u8 buf[7];
 	u8 val;
@@ -103,9 +99,7 @@ static int ds1337_get_datetime(struct i2
 	u8 offs = 0;
 
 	if (!dt) {
-		dev_dbg(&client->adapter->dev, "%s: EINVAL: dt=NULL\n",
-			__FUNCTION__);
-
+		dev_dbg(&client->dev, "%s: EINVAL: dt=NULL\n", __FUNCTION__);
 		return -EINVAL;
 	}
 
@@ -119,98 +113,86 @@ static int ds1337_get_datetime(struct i2
 	msg[1].len = sizeof(buf);
 	msg[1].buf = &buf[0];
 
-	result = client->adapter->algo->master_xfer(client->adapter,
-						    &msg[0], 2);
+	result = i2c_transfer(client->adapter, msg, 2);
 
-	dev_dbg(&client->adapter->dev,
-		"%s: [%d] %02x %02x %02x %02x %02x %02x %02x\n",
+	dev_dbg(&client->dev, "%s: [%d] %02x %02x %02x %02x %02x %02x %02x\n",
 		__FUNCTION__, result, buf[0], buf[1], buf[2], buf[3],
 		buf[4], buf[5], buf[6]);
 
-	if (result >= 0) {
-		dt->tm_sec = BCD_TO_BIN(buf[0]);
-		dt->tm_min = BCD_TO_BIN(buf[1]);
+	if (result == 2) {
+		dt->tm_sec = BCD2BIN(buf[0]);
+		dt->tm_min = BCD2BIN(buf[1]);
 		val = buf[2] & 0x3f;
-		dt->tm_hour = BCD_TO_BIN(val);
-		dt->tm_wday = BCD_TO_BIN(buf[3]) - 1;
-		dt->tm_mday = BCD_TO_BIN(buf[4]);
+		dt->tm_hour = BCD2BIN(val);
+		dt->tm_wday = BCD2BIN(buf[3]) - 1;
+		dt->tm_mday = BCD2BIN(buf[4]);
 		val = buf[5] & 0x7f;
-		dt->tm_mon = BCD_TO_BIN(val);
-		dt->tm_year = 1900 + BCD_TO_BIN(buf[6]);
+		dt->tm_mon = BCD2BIN(val) - 1;
+		dt->tm_year = BCD2BIN(buf[6]);
 		if (buf[5] & 0x80)
 			dt->tm_year += 100;
 
-		dev_dbg(&client->adapter->dev, "%s: secs=%d, mins=%d, "
+		dev_dbg(&client->dev, "%s: secs=%d, mins=%d, "
 			"hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n",
 			__FUNCTION__, dt->tm_sec, dt->tm_min,
 			dt->tm_hour, dt->tm_mday,
 			dt->tm_mon, dt->tm_year, dt->tm_wday);
-	} else {
-		dev_err(&client->adapter->dev, "ds1337[%d]: error reading "
-			"data! %d\n", data->id, result);
-		result = -EIO;
+
+		return 0;
 	}
 
-	return result;
+	dev_err(&client->dev, "error reading data! %d\n", result);
+	return -EIO;
 }
 
 static int ds1337_set_datetime(struct i2c_client *client, struct rtc_time *dt)
 {
-	struct ds1337_data *data = i2c_get_clientdata(client);
 	int result;
 	u8 buf[8];
 	u8 val;
 	struct i2c_msg msg[1];
 
 	if (!dt) {
-		dev_dbg(&client->adapter->dev, "%s: EINVAL: dt=NULL\n",
-			__FUNCTION__);
-
+		dev_dbg(&client->dev, "%s: EINVAL: dt=NULL\n", __FUNCTION__);
 		return -EINVAL;
 	}
 
-	dev_dbg(&client->adapter->dev, "%s: secs=%d, mins=%d, hours=%d, "
+	dev_dbg(&client->dev, "%s: secs=%d, mins=%d, hours=%d, "
 		"mday=%d, mon=%d, year=%d, wday=%d\n", __FUNCTION__,
 		dt->tm_sec, dt->tm_min, dt->tm_hour,
 		dt->tm_mday, dt->tm_mon, dt->tm_year, dt->tm_wday);
 
 	buf[0] = 0;		/* reg offset */
-	buf[1] = BIN_TO_BCD(dt->tm_sec);
-	buf[2] = BIN_TO_BCD(dt->tm_min);
-	buf[3] = BIN_TO_BCD(dt->tm_hour) | (1 << 6);
-	buf[4] = BIN_TO_BCD(dt->tm_wday) + 1;
-	buf[5] = BIN_TO_BCD(dt->tm_mday);
-	buf[6] = BIN_TO_BCD(dt->tm_mon);
-	if (dt->tm_year >= 2000) {
-		val = dt->tm_year - 2000;
+	buf[1] = BIN2BCD(dt->tm_sec);
+	buf[2] = BIN2BCD(dt->tm_min);
+	buf[3] = BIN2BCD(dt->tm_hour);
+	buf[4] = BIN2BCD(dt->tm_wday) + 1;
+	buf[5] = BIN2BCD(dt->tm_mday);
+	buf[6] = BIN2BCD(dt->tm_mon) + 1;
+	val = dt->tm_year;
+	if (val >= 100) {
+		val -= 100;
 		buf[6] |= (1 << 7);
-	} else {
-		val = dt->tm_year - 1900;
 	}
-	buf[7] = BIN_TO_BCD(val);
+	buf[7] = BIN2BCD(val);
 
 	msg[0].addr = client->addr;
 	msg[0].flags = 0;
 	msg[0].len = sizeof(buf);
 	msg[0].buf = &buf[0];
 
-	result = client->adapter->algo->master_xfer(client->adapter,
-						    &msg[0], 1);
-	if (result < 0) {
-		dev_err(&client->adapter->dev, "ds1337[%d]: error "
-			"writing data! %d\n", data->id, result);
-		result = -EIO;
-	} else {
-		result = 0;
-	}
+	result = i2c_transfer(client->adapter, msg, 1);
+	if (result == 1)
+		return 0;
 
-	return result;
+	dev_err(&client->dev, "error writing data! %d\n", result);
+	return -EIO;
 }
 
 static int ds1337_command(struct i2c_client *client, unsigned int cmd,
 			  void *arg)
 {
-	dev_dbg(&client->adapter->dev, "%s: cmd=%d\n", __FUNCTION__, cmd);
+	dev_dbg(&client->dev, "%s: cmd=%d\n", __FUNCTION__, cmd);
 
 	switch (cmd) {
 	case DS1337_GET_DATE:
@@ -228,7 +210,7 @@ static int ds1337_command(struct i2c_cli
  * Public API for access to specific device. Useful for low-level
  * RTC access from kernel code.
  */
-int ds1337_do_command(int id, int cmd, void *arg)
+int ds1337_do_command(int bus, int cmd, void *arg)
 {
 	struct list_head *walk;
 	struct list_head *tmp;
@@ -236,7 +218,7 @@ int ds1337_do_command(int id, int cmd, v
 
 	list_for_each_safe(walk, tmp, &ds1337_clients) {
 		data = list_entry(walk, struct ds1337_data, list);
-		if (data->id == id)
+		if (data->client.adapter->nr == bus)
 			return ds1337_command(&data->client, cmd, arg);
 	}
 
@@ -346,7 +328,6 @@ static int ds1337_detect(struct i2c_adap
 	ds1337_init_client(new_client);
 
 	/* Add client to local list */
-	data->id = ds1337_id++;
 	list_add(&data->list, &ds1337_clients);
 
 	return 0;
@@ -363,9 +344,9 @@ static void ds1337_init_client(struct i2
 
 	/* Ensure that device is set in 24-hour mode */
 	val = i2c_smbus_read_byte_data(client, DS1337_REG_HOUR);
-	if ((val >= 0) && (val & (1 << 6)) == 0)
+	if ((val >= 0) && (val & (1 << 6)))
 		i2c_smbus_write_byte_data(client, DS1337_REG_HOUR,
-					  val | (1 << 6));
+					  val & 0x3f);
 }
 
 static int ds1337_detach_client(struct i2c_client *client)
@@ -398,5 +379,7 @@ MODULE_AUTHOR("James Chapman <jchapman@k
 MODULE_DESCRIPTION("DS1337 RTC driver");
 MODULE_LICENSE("GPL");
 
+EXPORT_SYMBOL_GPL(ds1337_do_command);
+
 module_init(ds1337_init);
 module_exit(ds1337_exit);
diff --git a/drivers/i2c/chips/ds1374.c b/drivers/i2c/chips/ds1374.c
new file mode 100644
--- /dev/null
+++ b/drivers/i2c/chips/ds1374.c
@@ -0,0 +1,260 @@
+/*
+ * drivers/i2c/chips/ds1374.c
+ *
+ * I2C client/driver for the Maxim/Dallas DS1374 Real-Time Clock
+ *
+ * Author: Randy Vinson <rvinson@mvista.com>
+ *
+ * Based on the m41t00.c by Mark Greer <mgreer@mvista.com>
+ *
+ * 2005 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+/*
+ * This i2c client/driver wedges between the drivers/char/genrtc.c RTC
+ * interface and the SMBus interface of the i2c subsystem.
+ * It would be more efficient to use i2c msgs/i2c_transfer directly but, as
+ * recommened in .../Documentation/i2c/writing-clients section
+ * "Sending and receiving", using SMBus level communication is preferred.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/rtc.h>
+#include <linux/bcd.h>
+
+#define DS1374_REG_TOD0		0x00
+#define DS1374_REG_TOD1		0x01
+#define DS1374_REG_TOD2		0x02
+#define DS1374_REG_TOD3		0x03
+#define DS1374_REG_WDALM0	0x04
+#define DS1374_REG_WDALM1	0x05
+#define DS1374_REG_WDALM2	0x06
+#define DS1374_REG_CR		0x07
+#define DS1374_REG_SR		0x08
+#define DS1374_REG_SR_OSF	0x80
+#define DS1374_REG_TCR		0x09
+
+#define	DS1374_DRV_NAME		"ds1374"
+
+static DECLARE_MUTEX(ds1374_mutex);
+
+static struct i2c_driver ds1374_driver;
+static struct i2c_client *save_client;
+
+static unsigned short ignore[] = { I2C_CLIENT_END };
+static unsigned short normal_addr[] = { 0x68, I2C_CLIENT_END };
+
+static struct i2c_client_address_data addr_data = {
+	.normal_i2c = normal_addr,
+	.probe = ignore,
+	.ignore = ignore,
+	.force = ignore,
+};
+
+static ulong ds1374_read_rtc(void)
+{
+	ulong time = 0;
+	int reg = DS1374_REG_WDALM0;
+
+	while (reg--) {
+		s32 tmp;
+		if ((tmp = i2c_smbus_read_byte_data(save_client, reg)) < 0) {
+			dev_warn(&save_client->dev,
+				 "can't read from rtc chip\n");
+			return 0;
+		}
+		time = (time << 8) | (tmp & 0xff);
+	}
+	return time;
+}
+
+static void ds1374_write_rtc(ulong time)
+{
+	int reg;
+
+	for (reg = DS1374_REG_TOD0; reg < DS1374_REG_WDALM0; reg++) {
+		if (i2c_smbus_write_byte_data(save_client, reg, time & 0xff)
+		    < 0) {
+			dev_warn(&save_client->dev,
+				 "can't write to rtc chip\n");
+			break;
+		}
+		time = time >> 8;
+	}
+}
+
+static void ds1374_check_rtc_status(void)
+{
+	s32 tmp;
+
+	tmp = i2c_smbus_read_byte_data(save_client, DS1374_REG_SR);
+	if (tmp < 0) {
+		dev_warn(&save_client->dev,
+			 "can't read status from rtc chip\n");
+		return;
+	}
+	if (tmp & DS1374_REG_SR_OSF) {
+		dev_warn(&save_client->dev,
+			 "oscillator discontinuity flagged, time unreliable\n");
+		tmp &= ~DS1374_REG_SR_OSF;
+		tmp = i2c_smbus_write_byte_data(save_client, DS1374_REG_SR,
+						tmp & 0xff);
+		if (tmp < 0)
+			dev_warn(&save_client->dev,
+				 "can't clear discontinuity notification\n");
+	}
+}
+
+ulong ds1374_get_rtc_time(void)
+{
+	ulong t1, t2;
+	int limit = 10;		/* arbitrary retry limit */
+
+	down(&ds1374_mutex);
+
+	/*
+	 * Since the reads are being performed one byte at a time using
+	 * the SMBus vs a 4-byte i2c transfer, there is a chance that a
+	 * carry will occur during the read. To detect this, 2 reads are
+	 * performed and compared.
+	 */
+	do {
+		t1 = ds1374_read_rtc();
+		t2 = ds1374_read_rtc();
+	} while (t1 != t2 && limit--);
+
+	up(&ds1374_mutex);
+
+	if (t1 != t2) {
+		dev_warn(&save_client->dev,
+			 "can't get consistent time from rtc chip\n");
+		t1 = 0;
+	}
+
+	return t1;
+}
+
+static void ds1374_set_tlet(ulong arg)
+{
+	ulong t1, t2;
+	int limit = 10;		/* arbitrary retry limit */
+
+	t1 = *(ulong *) arg;
+
+	down(&ds1374_mutex);
+
+	/*
+	 * Since the writes are being performed one byte at a time using
+	 * the SMBus vs a 4-byte i2c transfer, there is a chance that a
+	 * carry will occur during the write. To detect this, the write
+	 * value is read back and compared.
+	 */
+	do {
+		ds1374_write_rtc(t1);
+		t2 = ds1374_read_rtc();
+	} while (t1 != t2 && limit--);
+
+	up(&ds1374_mutex);
+
+	if (t1 != t2)
+		dev_warn(&save_client->dev,
+			 "can't confirm time set from rtc chip\n");
+}
+
+ulong new_time;
+
+DECLARE_TASKLET_DISABLED(ds1374_tasklet, ds1374_set_tlet, (ulong) & new_time);
+
+int ds1374_set_rtc_time(ulong nowtime)
+{
+	new_time = nowtime;
+
+	if (in_interrupt())
+		tasklet_schedule(&ds1374_tasklet);
+	else
+		ds1374_set_tlet((ulong) & new_time);
+
+	return 0;
+}
+
+/*
+ *****************************************************************************
+ *
+ *	Driver Interface
+ *
+ *****************************************************************************
+ */
+static int ds1374_probe(struct i2c_adapter *adap, int addr, int kind)
+{
+	struct i2c_client *client;
+	int rc;
+
+	client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
+	if (!client)
+		return -ENOMEM;
+
+	memset(client, 0, sizeof(struct i2c_client));
+	strncpy(client->name, DS1374_DRV_NAME, I2C_NAME_SIZE);
+	client->flags = I2C_DF_NOTIFY;
+	client->addr = addr;
+	client->adapter = adap;
+	client->driver = &ds1374_driver;
+
+	if ((rc = i2c_attach_client(client)) != 0) {
+		kfree(client);
+		return rc;
+	}
+
+	save_client = client;
+
+	ds1374_check_rtc_status();
+
+	return 0;
+}
+
+static int ds1374_attach(struct i2c_adapter *adap)
+{
+	return i2c_probe(adap, &addr_data, ds1374_probe);
+}
+
+static int ds1374_detach(struct i2c_client *client)
+{
+	int rc;
+
+	if ((rc = i2c_detach_client(client)) == 0) {
+		kfree(i2c_get_clientdata(client));
+		tasklet_kill(&ds1374_tasklet);
+	}
+	return rc;
+}
+
+static struct i2c_driver ds1374_driver = {
+	.owner = THIS_MODULE,
+	.name = DS1374_DRV_NAME,
+	.id = I2C_DRIVERID_DS1374,
+	.flags = I2C_DF_NOTIFY,
+	.attach_adapter = ds1374_attach,
+	.detach_client = ds1374_detach,
+};
+
+static int __init ds1374_init(void)
+{
+	return i2c_add_driver(&ds1374_driver);
+}
+
+static void __exit ds1374_exit(void)
+{
+	i2c_del_driver(&ds1374_driver);
+}
+
+module_init(ds1374_init);
+module_exit(ds1374_exit);
+
+MODULE_AUTHOR("Randy Vinson <rvinson@mvista.com>");
+MODULE_DESCRIPTION("Maxim/Dallas DS1374 RTC I2C Client Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/i2c/chips/ds1621.c b/drivers/i2c/chips/ds1621.c
deleted file mode 100644
--- a/drivers/i2c/chips/ds1621.c
+++ /dev/null
@@ -1,341 +0,0 @@
-/*
-    ds1621.c - Part of lm_sensors, Linux kernel modules for hardware
-             monitoring
-    Christian W. Zuckschwerdt  <zany@triq.net>  2000-11-23
-    based on lm75.c by Frodo Looijaard <frodol@dds.nl>
-    Ported to Linux 2.6 by Aurelien Jarno <aurelien@aurel32.net> with 
-    the help of Jean Delvare <khali@linux-fr.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.
-*/
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/jiffies.h>
-#include <linux/i2c.h>
-#include <linux/i2c-sensor.h>
-#include "lm75.h"
-
-/* Addresses to scan */
-static unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, 0x4c,
-					0x4d, 0x4e, 0x4f, I2C_CLIENT_END };
-static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
-
-/* Insmod parameters */
-SENSORS_INSMOD_1(ds1621);
-static int polarity = -1;
-module_param(polarity, int, 0);
-MODULE_PARM_DESC(polarity, "Output's polarity: 0 = active high, 1 = active low");
-
-/* Many DS1621 constants specified below */
-/* Config register used for detection         */
-/*  7    6    5    4    3    2    1    0      */
-/* |Done|THF |TLF |NVB | X  | X  |POL |1SHOT| */
-#define DS1621_REG_CONFIG_NVB		0x10
-#define DS1621_REG_CONFIG_POLARITY	0x02
-#define DS1621_REG_CONFIG_1SHOT		0x01
-#define DS1621_REG_CONFIG_DONE		0x80
-
-/* The DS1621 registers */
-#define DS1621_REG_TEMP			0xAA /* word, RO */
-#define DS1621_REG_TEMP_MIN		0xA1 /* word, RW */
-#define DS1621_REG_TEMP_MAX		0xA2 /* word, RW */
-#define DS1621_REG_CONF			0xAC /* byte, RW */
-#define DS1621_COM_START		0xEE /* no data */
-#define DS1621_COM_STOP			0x22 /* no data */
-
-/* The DS1621 configuration register */
-#define DS1621_ALARM_TEMP_HIGH		0x40
-#define DS1621_ALARM_TEMP_LOW		0x20
-
-/* Conversions. Rounding and limit checking is only done on the TO_REG
-   variants. Note that you should be a bit careful with which arguments
-   these macros are called: arguments may be evaluated more than once.
-   Fixing this is just not worth it. */
-#define ALARMS_FROM_REG(val) ((val) & \
-                              (DS1621_ALARM_TEMP_HIGH | DS1621_ALARM_TEMP_LOW))
-
-/* Each client has this additional data */
-struct ds1621_data {
-	struct i2c_client client;
-	struct semaphore update_lock;
-	char valid;			/* !=0 if following fields are valid */
-	unsigned long last_updated;	/* In jiffies */
-
-	u16 temp, temp_min, temp_max;	/* Register values, word */
-	u8 conf;			/* Register encoding, combined */
-};
-
-static int ds1621_attach_adapter(struct i2c_adapter *adapter);
-static int ds1621_detect(struct i2c_adapter *adapter, int address,
-			 int kind);
-static void ds1621_init_client(struct i2c_client *client);
-static int ds1621_detach_client(struct i2c_client *client);
-static struct ds1621_data *ds1621_update_client(struct device *dev);
-
-/* This is the driver that will be inserted */
-static struct i2c_driver ds1621_driver = {
-	.owner		= THIS_MODULE,
-	.name		= "ds1621",
-	.id		= I2C_DRIVERID_DS1621,
-	.flags		= I2C_DF_NOTIFY,
-	.attach_adapter	= ds1621_attach_adapter,
-	.detach_client	= ds1621_detach_client,
-};
-
-/* All registers are word-sized, except for the configuration register.
-   DS1621 uses a high-byte first convention, which is exactly opposite to
-   the usual practice. */
-static int ds1621_read_value(struct i2c_client *client, u8 reg)
-{
-	if (reg == DS1621_REG_CONF)
-		return i2c_smbus_read_byte_data(client, reg);
-	else
-		return swab16(i2c_smbus_read_word_data(client, reg));
-}
-
-/* All registers are word-sized, except for the configuration register.
-   DS1621 uses a high-byte first convention, which is exactly opposite to
-   the usual practice. */
-static int ds1621_write_value(struct i2c_client *client, u8 reg, u16 value)
-{
-	if (reg == DS1621_REG_CONF)
-		return i2c_smbus_write_byte_data(client, reg, value);
-	else
-		return i2c_smbus_write_word_data(client, reg, swab16(value));
-}
-
-static void ds1621_init_client(struct i2c_client *client)
-{
-	int reg = ds1621_read_value(client, DS1621_REG_CONF);
-	/* switch to continous conversion mode */
-	reg &= ~ DS1621_REG_CONFIG_1SHOT;
-
-	/* setup output polarity */
-	if (polarity == 0)
-		reg &= ~DS1621_REG_CONFIG_POLARITY;
-	else if (polarity == 1)
-		reg |= DS1621_REG_CONFIG_POLARITY;
-	
-	ds1621_write_value(client, DS1621_REG_CONF, reg);
-	
-	/* start conversion */
-	i2c_smbus_write_byte(client, DS1621_COM_START);
-}
-
-#define show(value)							\
-static ssize_t show_##value(struct device *dev, char *buf)		\
-{									\
-	struct ds1621_data *data = ds1621_update_client(dev);		\
-	return sprintf(buf, "%d\n", LM75_TEMP_FROM_REG(data->value));	\
-}
-
-show(temp);
-show(temp_min);
-show(temp_max);
-
-#define set_temp(suffix, value, reg)					\
-static ssize_t set_temp_##suffix(struct device *dev, const char *buf,	\
-				 size_t count)				\
-{									\
-	struct i2c_client *client = to_i2c_client(dev);			\
-	struct ds1621_data *data = ds1621_update_client(dev);		\
-	u16 val = LM75_TEMP_TO_REG(simple_strtoul(buf, NULL, 10));	\
-									\
-	down(&data->update_lock);					\
-	data->value = val;						\
-	ds1621_write_value(client, reg, data->value);			\
-	up(&data->update_lock);						\
-	return count;							\
-}
-
-set_temp(min, temp_min, DS1621_REG_TEMP_MIN);
-set_temp(max, temp_max, DS1621_REG_TEMP_MAX);
-
-static ssize_t show_alarms(struct device *dev, char *buf)
-{
-	struct ds1621_data *data = ds1621_update_client(dev);
-	return sprintf(buf, "%d\n", ALARMS_FROM_REG(data->conf));
-}
-
-static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
-static DEVICE_ATTR(temp1_input, S_IRUGO , show_temp, NULL);
-static DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO , show_temp_min, set_temp_min);
-static DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp_max, set_temp_max);
-
-
-static int ds1621_attach_adapter(struct i2c_adapter *adapter)
-{
-	return i2c_detect(adapter, &addr_data, ds1621_detect);
-}
-
-/* This function is called by i2c_detect */
-int ds1621_detect(struct i2c_adapter *adapter, int address,
-                  int kind)
-{
-	int conf, temp;
-	struct i2c_client *new_client;
-	struct ds1621_data *data;
-	int err = 0;
-
-	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA 
-				     | I2C_FUNC_SMBUS_WORD_DATA 
-				     | I2C_FUNC_SMBUS_WRITE_BYTE))
-		goto exit;
-
-	/* OK. For now, we presume we have a valid client. We now create the
-	   client structure, even though we cannot fill it completely yet.
-	   But it allows us to access ds1621_{read,write}_value. */
-	if (!(data = kmalloc(sizeof(struct ds1621_data), GFP_KERNEL))) {
-		err = -ENOMEM;
-		goto exit;
-	}
-	memset(data, 0, sizeof(struct ds1621_data));
-	
-	new_client = &data->client;
-	i2c_set_clientdata(new_client, data);
-	new_client->addr = address;
-	new_client->adapter = adapter;
-	new_client->driver = &ds1621_driver;
-	new_client->flags = 0;
-
-
-	/* Now, we do the remaining detection. It is lousy. */
-	if (kind < 0) {
-		/* The NVB bit should be low if no EEPROM write has been 
-		   requested during the latest 10ms, which is highly 
-		   improbable in our case. */
-		conf = ds1621_read_value(new_client, DS1621_REG_CONF);
-		if (conf & DS1621_REG_CONFIG_NVB)
-			goto exit_free;
-		/* The 7 lowest bits of a temperature should always be 0. */
-		temp = ds1621_read_value(new_client, DS1621_REG_TEMP);
-		if (temp & 0x007f)
-			goto exit_free;
-		temp = ds1621_read_value(new_client, DS1621_REG_TEMP_MIN);
-		if (temp & 0x007f)
-			goto exit_free;
-		temp = ds1621_read_value(new_client, DS1621_REG_TEMP_MAX);
-		if (temp & 0x007f)
-			goto exit_free;
-	}
-
-	/* Determine the chip type - only one kind supported! */
-	if (kind <= 0)
-		kind = ds1621;
-
-	/* Fill in remaining client fields and put it into the global list */
-	strlcpy(new_client->name, "ds1621", I2C_NAME_SIZE);
-	data->valid = 0;
-	init_MUTEX(&data->update_lock);
-
-	/* Tell the I2C layer a new client has arrived */
-	if ((err = i2c_attach_client(new_client)))
-		goto exit_free;
-
-	/* Initialize the DS1621 chip */
-	ds1621_init_client(new_client);
-
-	/* Register sysfs hooks */
-	device_create_file(&new_client->dev, &dev_attr_alarms);
-	device_create_file(&new_client->dev, &dev_attr_temp1_input);
-	device_create_file(&new_client->dev, &dev_attr_temp1_min);
-	device_create_file(&new_client->dev, &dev_attr_temp1_max);
-	
-	return 0;
-
-/* OK, this is not exactly good programming practice, usually. But it is
-   very code-efficient in this case. */
-      exit_free:
-	kfree(data);
-      exit:
-	return err;
-}
-
-static int ds1621_detach_client(struct i2c_client *client)
-{
-	int err;
-
-	if ((err = i2c_detach_client(client))) {
-		dev_err(&client->dev, "Client deregistration failed, "
-			"client not detached.\n");
-		return err;
-	}
-
-	kfree(i2c_get_clientdata(client));
-
-	return 0;
-}
-
-
-static struct ds1621_data *ds1621_update_client(struct device *dev)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct ds1621_data *data = i2c_get_clientdata(client);
-	u8 new_conf;
-
-	down(&data->update_lock);
-
-	if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
-	    || !data->valid) {
-
-		dev_dbg(&client->dev, "Starting ds1621 update\n");
-
-		data->conf = ds1621_read_value(client, DS1621_REG_CONF);
-
-		data->temp = ds1621_read_value(client, DS1621_REG_TEMP);
-		
-		data->temp_min = ds1621_read_value(client,
-		                                    DS1621_REG_TEMP_MIN);
-		data->temp_max = ds1621_read_value(client,
-						    DS1621_REG_TEMP_MAX);
-
-		/* reset alarms if neccessary */
-		new_conf = data->conf;
-		if (data->temp < data->temp_min)
-			new_conf &= ~DS1621_ALARM_TEMP_LOW;
-		if (data->temp > data->temp_max)
-			new_conf &= ~DS1621_ALARM_TEMP_HIGH;
-		if (data->conf != new_conf)
-			ds1621_write_value(client, DS1621_REG_CONF,
-					   new_conf);
-
-		data->last_updated = jiffies;
-		data->valid = 1;
-	}
-
-	up(&data->update_lock);
-
-	return data;
-}
-
-static int __init ds1621_init(void)
-{
-	return i2c_add_driver(&ds1621_driver);
-}
-
-static void __exit ds1621_exit(void)
-{
-	i2c_del_driver(&ds1621_driver);
-}
-
-
-MODULE_AUTHOR("Christian W. Zuckschwerdt <zany@triq.net>");
-MODULE_DESCRIPTION("DS1621 driver");
-MODULE_LICENSE("GPL");
-
-module_init(ds1621_init);
-module_exit(ds1621_exit);
diff --git a/drivers/i2c/chips/eeprom.c b/drivers/i2c/chips/eeprom.c
--- a/drivers/i2c/chips/eeprom.c
+++ b/drivers/i2c/chips/eeprom.c
@@ -26,7 +26,6 @@
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/module.h>
@@ -164,6 +163,11 @@ int eeprom_detect(struct i2c_adapter *ad
 	struct eeprom_data *data;
 	int err = 0;
 
+	/* prevent 24RF08 corruption */
+	if (kind < 0)
+		i2c_smbus_xfer(adapter, address, 0, 0, 0,
+			       I2C_SMBUS_QUICK, NULL);
+
 	/* There are three ways we can read the EEPROM data:
 	   (1) I2C block reads (faster, but unsupported by most adapters)
 	   (2) Consecutive byte reads (100% overhead)
@@ -174,9 +178,6 @@ int eeprom_detect(struct i2c_adapter *ad
 					    | I2C_FUNC_SMBUS_BYTE))
 		goto exit;
 
-	/* OK. For now, we presume we have a valid client. We now create the
-	   client structure, even though we cannot fill it completely yet.
-	   But it allows us to access eeprom_{read,write}_value. */
 	if (!(data = kmalloc(sizeof(struct eeprom_data), GFP_KERNEL))) {
 		err = -ENOMEM;
 		goto exit;
@@ -191,9 +192,6 @@ int eeprom_detect(struct i2c_adapter *ad
 	new_client->driver = &eeprom_driver;
 	new_client->flags = 0;
 
-	/* prevent 24RF08 corruption */
-	i2c_smbus_write_quick(new_client, 0);
-
 	/* Fill in the remaining client fields */
 	strlcpy(new_client->name, "eeprom", I2C_NAME_SIZE);
 	data->valid = 0;
diff --git a/drivers/i2c/chips/fscher.c b/drivers/i2c/chips/fscher.c
deleted file mode 100644
--- a/drivers/i2c/chips/fscher.c
+++ /dev/null
@@ -1,692 +0,0 @@
-/*
- * fscher.c - Part of lm_sensors, Linux kernel modules for hardware
- * monitoring
- * Copyright (C) 2003, 2004 Reinhard Nissl <rnissl@gmx.de>
- * 
- * 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.
- */
-
-/* 
- *  fujitsu siemens hermes chip, 
- *  module based on fscpos.c 
- *  Copyright (C) 2000 Hermann Jung <hej@odn.de>
- *  Copyright (C) 1998, 1999 Frodo Looijaard <frodol@dds.nl>
- *  and Philip Edelbrock <phil@netroedge.com>
- */
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/jiffies.h>
-#include <linux/i2c.h>
-#include <linux/i2c-sensor.h>
-
-/*
- * Addresses to scan
- */
-
-static unsigned short normal_i2c[] = { 0x73, I2C_CLIENT_END };
-static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
-
-/*
- * Insmod parameters
- */
-
-SENSORS_INSMOD_1(fscher);
-
-/*
- * The FSCHER registers
- */
-
-/* chip identification */
-#define FSCHER_REG_IDENT_0		0x00
-#define FSCHER_REG_IDENT_1		0x01
-#define FSCHER_REG_IDENT_2		0x02
-#define FSCHER_REG_REVISION		0x03
-
-/* global control and status */
-#define FSCHER_REG_EVENT_STATE		0x04
-#define FSCHER_REG_CONTROL		0x05
-
-/* watchdog */
-#define FSCHER_REG_WDOG_PRESET		0x28
-#define FSCHER_REG_WDOG_STATE		0x23
-#define FSCHER_REG_WDOG_CONTROL		0x21
-
-/* fan 0 */
-#define FSCHER_REG_FAN0_MIN		0x55
-#define FSCHER_REG_FAN0_ACT		0x0e
-#define FSCHER_REG_FAN0_STATE		0x0d
-#define FSCHER_REG_FAN0_RIPPLE		0x0f
-
-/* fan 1 */
-#define FSCHER_REG_FAN1_MIN		0x65
-#define FSCHER_REG_FAN1_ACT		0x6b
-#define FSCHER_REG_FAN1_STATE		0x62
-#define FSCHER_REG_FAN1_RIPPLE		0x6f
-
-/* fan 2 */
-#define FSCHER_REG_FAN2_MIN		0xb5
-#define FSCHER_REG_FAN2_ACT		0xbb
-#define FSCHER_REG_FAN2_STATE		0xb2
-#define FSCHER_REG_FAN2_RIPPLE		0xbf
-
-/* voltage supervision */
-#define FSCHER_REG_VOLT_12		0x45
-#define FSCHER_REG_VOLT_5		0x42
-#define FSCHER_REG_VOLT_BATT		0x48
-
-/* temperature 0 */
-#define FSCHER_REG_TEMP0_ACT		0x64
-#define FSCHER_REG_TEMP0_STATE		0x71
-
-/* temperature 1 */
-#define FSCHER_REG_TEMP1_ACT		0x32
-#define FSCHER_REG_TEMP1_STATE		0x81
-
-/* temperature 2 */
-#define FSCHER_REG_TEMP2_ACT		0x35
-#define FSCHER_REG_TEMP2_STATE		0x91
-
-/*
- * Functions declaration
- */
-
-static int fscher_attach_adapter(struct i2c_adapter *adapter);
-static int fscher_detect(struct i2c_adapter *adapter, int address, int kind);
-static int fscher_detach_client(struct i2c_client *client);
-static struct fscher_data *fscher_update_device(struct device *dev);
-static void fscher_init_client(struct i2c_client *client);
-
-static int fscher_read_value(struct i2c_client *client, u8 reg);
-static int fscher_write_value(struct i2c_client *client, u8 reg, u8 value);
-
-/*
- * Driver data (common to all clients)
- */
- 
-static struct i2c_driver fscher_driver = {
-	.owner		= THIS_MODULE,
-	.name		= "fscher",
-	.id		= I2C_DRIVERID_FSCHER,
-	.flags		= I2C_DF_NOTIFY,
-	.attach_adapter	= fscher_attach_adapter,
-	.detach_client	= fscher_detach_client,
-};
-
-/*
- * Client data (each client gets its own)
- */
-
-struct fscher_data {
-	struct i2c_client client;
-	struct semaphore update_lock;
-	char valid; /* zero until following fields are valid */
-	unsigned long last_updated; /* in jiffies */
-
-	/* register values */
-	u8 revision;		/* revision of chip */
-	u8 global_event;	/* global event status */
-	u8 global_control;	/* global control register */
-	u8 watchdog[3];		/* watchdog */
-	u8 volt[3];		/* 12, 5, battery voltage */ 
-	u8 temp_act[3];		/* temperature */
-	u8 temp_status[3];	/* status of sensor */
-	u8 fan_act[3];		/* fans revolutions per second */
-	u8 fan_status[3];	/* fan status */
-	u8 fan_min[3];		/* fan min value for rps */
-	u8 fan_ripple[3];	/* divider for rps */
-};
-
-/*
- * Sysfs stuff
- */
-
-#define sysfs_r(kind, sub, offset, reg) \
-static ssize_t show_##kind##sub (struct fscher_data *, char *, int); \
-static ssize_t show_##kind##offset##sub (struct device *, char *); \
-static ssize_t show_##kind##offset##sub (struct device *dev, char *buf) \
-{ \
-	struct fscher_data *data = fscher_update_device(dev); \
-	return show_##kind##sub(data, buf, (offset)); \
-}
-
-#define sysfs_w(kind, sub, offset, reg) \
-static ssize_t set_##kind##sub (struct i2c_client *, struct fscher_data *, const char *, size_t, int, int); \
-static ssize_t set_##kind##offset##sub (struct device *, const char *, size_t); \
-static ssize_t set_##kind##offset##sub (struct device *dev, const char *buf, size_t count) \
-{ \
-	struct i2c_client *client = to_i2c_client(dev); \
-	struct fscher_data *data = i2c_get_clientdata(client); \
-	return set_##kind##sub(client, data, buf, count, (offset), reg); \
-}
-
-#define sysfs_rw_n(kind, sub, offset, reg) \
-sysfs_r(kind, sub, offset, reg) \
-sysfs_w(kind, sub, offset, reg) \
-static DEVICE_ATTR(kind##offset##sub, S_IRUGO | S_IWUSR, show_##kind##offset##sub, set_##kind##offset##sub);
-
-#define sysfs_rw(kind, sub, reg) \
-sysfs_r(kind, sub, 0, reg) \
-sysfs_w(kind, sub, 0, reg) \
-static DEVICE_ATTR(kind##sub, S_IRUGO | S_IWUSR, show_##kind##0##sub, set_##kind##0##sub);
-
-#define sysfs_ro_n(kind, sub, offset, reg) \
-sysfs_r(kind, sub, offset, reg) \
-static DEVICE_ATTR(kind##offset##sub, S_IRUGO, show_##kind##offset##sub, NULL);
-
-#define sysfs_ro(kind, sub, reg) \
-sysfs_r(kind, sub, 0, reg) \
-static DEVICE_ATTR(kind, S_IRUGO, show_##kind##0##sub, NULL);
-
-#define sysfs_fan(offset, reg_status, reg_min, reg_ripple, reg_act) \
-sysfs_rw_n(pwm,        , offset, reg_min) \
-sysfs_rw_n(fan, _status, offset, reg_status) \
-sysfs_rw_n(fan, _div   , offset, reg_ripple) \
-sysfs_ro_n(fan, _input , offset, reg_act)
-
-#define sysfs_temp(offset, reg_status, reg_act) \
-sysfs_rw_n(temp, _status, offset, reg_status) \
-sysfs_ro_n(temp, _input , offset, reg_act)
-    
-#define sysfs_in(offset, reg_act) \
-sysfs_ro_n(in, _input, offset, reg_act)
-
-#define sysfs_revision(reg_revision) \
-sysfs_ro(revision, , reg_revision)
-
-#define sysfs_alarms(reg_events) \
-sysfs_ro(alarms, , reg_events)
-
-#define sysfs_control(reg_control) \
-sysfs_rw(control, , reg_control)
-
-#define sysfs_watchdog(reg_control, reg_status, reg_preset) \
-sysfs_rw(watchdog, _control, reg_control) \
-sysfs_rw(watchdog, _status , reg_status) \
-sysfs_rw(watchdog, _preset , reg_preset)
-
-sysfs_fan(1, FSCHER_REG_FAN0_STATE, FSCHER_REG_FAN0_MIN,
-	     FSCHER_REG_FAN0_RIPPLE, FSCHER_REG_FAN0_ACT)
-sysfs_fan(2, FSCHER_REG_FAN1_STATE, FSCHER_REG_FAN1_MIN,
-	     FSCHER_REG_FAN1_RIPPLE, FSCHER_REG_FAN1_ACT)
-sysfs_fan(3, FSCHER_REG_FAN2_STATE, FSCHER_REG_FAN2_MIN,
-	     FSCHER_REG_FAN2_RIPPLE, FSCHER_REG_FAN2_ACT)
-
-sysfs_temp(1, FSCHER_REG_TEMP0_STATE, FSCHER_REG_TEMP0_ACT)
-sysfs_temp(2, FSCHER_REG_TEMP1_STATE, FSCHER_REG_TEMP1_ACT)
-sysfs_temp(3, FSCHER_REG_TEMP2_STATE, FSCHER_REG_TEMP2_ACT)
-
-sysfs_in(0, FSCHER_REG_VOLT_12)
-sysfs_in(1, FSCHER_REG_VOLT_5)
-sysfs_in(2, FSCHER_REG_VOLT_BATT)
-
-sysfs_revision(FSCHER_REG_REVISION)
-sysfs_alarms(FSCHER_REG_EVENTS)
-sysfs_control(FSCHER_REG_CONTROL)
-sysfs_watchdog(FSCHER_REG_WDOG_CONTROL, FSCHER_REG_WDOG_STATE, FSCHER_REG_WDOG_PRESET)
-  
-#define device_create_file_fan(client, offset) \
-do { \
-	device_create_file(&client->dev, &dev_attr_fan##offset##_status); \
-	device_create_file(&client->dev, &dev_attr_pwm##offset); \
-	device_create_file(&client->dev, &dev_attr_fan##offset##_div); \
-	device_create_file(&client->dev, &dev_attr_fan##offset##_input); \
-} while (0)
-
-#define device_create_file_temp(client, offset) \
-do { \
-	device_create_file(&client->dev, &dev_attr_temp##offset##_status); \
-	device_create_file(&client->dev, &dev_attr_temp##offset##_input); \
-} while (0)
-
-#define device_create_file_in(client, offset) \
-do { \
-	device_create_file(&client->dev, &dev_attr_in##offset##_input); \
-} while (0)
-
-#define device_create_file_revision(client) \
-do { \
-	device_create_file(&client->dev, &dev_attr_revision); \
-} while (0)
-
-#define device_create_file_alarms(client) \
-do { \
-	device_create_file(&client->dev, &dev_attr_alarms); \
-} while (0)
-
-#define device_create_file_control(client) \
-do { \
-	device_create_file(&client->dev, &dev_attr_control); \
-} while (0)
-
-#define device_create_file_watchdog(client) \
-do { \
-	device_create_file(&client->dev, &dev_attr_watchdog_status); \
-	device_create_file(&client->dev, &dev_attr_watchdog_control); \
-	device_create_file(&client->dev, &dev_attr_watchdog_preset); \
-} while (0)
-  
-/*
- * Real code
- */
-
-static int fscher_attach_adapter(struct i2c_adapter *adapter)
-{
-	if (!(adapter->class & I2C_CLASS_HWMON))
-		return 0;
-	return i2c_detect(adapter, &addr_data, fscher_detect);
-}
-
-static int fscher_detect(struct i2c_adapter *adapter, int address, int kind)
-{
-	struct i2c_client *new_client;
-	struct fscher_data *data;
-	int err = 0;
-
-	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
-		goto exit;
-
-	/* OK. For now, we presume we have a valid client. We now create the
-	 * client structure, even though we cannot fill it completely yet.
-	 * But it allows us to access i2c_smbus_read_byte_data. */
-	if (!(data = kmalloc(sizeof(struct fscher_data), GFP_KERNEL))) {
-		err = -ENOMEM;
-		goto exit;
-  	}
-	memset(data, 0, sizeof(struct fscher_data));
-
-	/* The common I2C client data is placed right before the
-	 * Hermes-specific data. */
-	new_client = &data->client;
-	i2c_set_clientdata(new_client, data);
-	new_client->addr = address;
-	new_client->adapter = adapter;
-	new_client->driver = &fscher_driver;
-	new_client->flags = 0;
-
-	/* Do the remaining detection unless force or force_fscher parameter */
-	if (kind < 0) {
-		if ((i2c_smbus_read_byte_data(new_client,
-		     FSCHER_REG_IDENT_0) != 0x48)	/* 'H' */
-		 || (i2c_smbus_read_byte_data(new_client,
-		     FSCHER_REG_IDENT_1) != 0x45)	/* 'E' */
-		 || (i2c_smbus_read_byte_data(new_client,
-		     FSCHER_REG_IDENT_2) != 0x52))	/* 'R' */
-			goto exit_free;
-	}
-
-	/* Fill in the remaining client fields and put it into the
-	 * global list */
-	strlcpy(new_client->name, "fscher", I2C_NAME_SIZE);
-	data->valid = 0;
-	init_MUTEX(&data->update_lock);
-
-	/* Tell the I2C layer a new client has arrived */
-	if ((err = i2c_attach_client(new_client)))
-		goto exit_free;
-
-	fscher_init_client(new_client);
-
-	/* Register sysfs hooks */
-	device_create_file_revision(new_client);
-	device_create_file_alarms(new_client);
-	device_create_file_control(new_client);
-	device_create_file_watchdog(new_client);
-
-	device_create_file_in(new_client, 0);
-	device_create_file_in(new_client, 1);
-	device_create_file_in(new_client, 2);
-
-	device_create_file_fan(new_client, 1);
-	device_create_file_fan(new_client, 2);
-	device_create_file_fan(new_client, 3);
-
-	device_create_file_temp(new_client, 1);
-	device_create_file_temp(new_client, 2);
-	device_create_file_temp(new_client, 3);
-
-	return 0;
-
-exit_free:
-	kfree(data);
-exit:
-	return err;
-}
-
-static int fscher_detach_client(struct i2c_client *client)
-{
-	int err;
-
-	if ((err = i2c_detach_client(client))) {
-		dev_err(&client->dev, "Client deregistration failed, "
-			"client not detached.\n");
-		return err;
-	}
-
-	kfree(i2c_get_clientdata(client));
-	return 0;
-}
-
-static int fscher_read_value(struct i2c_client *client, u8 reg)
-{
-	dev_dbg(&client->dev, "read reg 0x%02x\n", reg);
-
-	return i2c_smbus_read_byte_data(client, reg);
-}
-
-static int fscher_write_value(struct i2c_client *client, u8 reg, u8 value)
-{
-	dev_dbg(&client->dev, "write reg 0x%02x, val 0x%02x\n",
-		reg, value);
-
-	return i2c_smbus_write_byte_data(client, reg, value);
-}
-
-/* Called when we have found a new FSC Hermes. */
-static void fscher_init_client(struct i2c_client *client)
-{
-	struct fscher_data *data = i2c_get_clientdata(client);
-
-	/* Read revision from chip */
-	data->revision =  fscher_read_value(client, FSCHER_REG_REVISION);
-}
-
-static struct fscher_data *fscher_update_device(struct device *dev)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct fscher_data *data = i2c_get_clientdata(client);
-
-	down(&data->update_lock);
-
-	if (time_after(jiffies, data->last_updated + 2 * HZ) || !data->valid) {
-
-		dev_dbg(&client->dev, "Starting fscher update\n");
-
-		data->temp_act[0] = fscher_read_value(client, FSCHER_REG_TEMP0_ACT);
-		data->temp_act[1] = fscher_read_value(client, FSCHER_REG_TEMP1_ACT);
-		data->temp_act[2] = fscher_read_value(client, FSCHER_REG_TEMP2_ACT);
-		data->temp_status[0] = fscher_read_value(client, FSCHER_REG_TEMP0_STATE);
-		data->temp_status[1] = fscher_read_value(client, FSCHER_REG_TEMP1_STATE);
-		data->temp_status[2] = fscher_read_value(client, FSCHER_REG_TEMP2_STATE);
-
-		data->volt[0] = fscher_read_value(client, FSCHER_REG_VOLT_12);
-		data->volt[1] = fscher_read_value(client, FSCHER_REG_VOLT_5);
-		data->volt[2] = fscher_read_value(client, FSCHER_REG_VOLT_BATT);
-
-		data->fan_act[0] = fscher_read_value(client, FSCHER_REG_FAN0_ACT);
-		data->fan_act[1] = fscher_read_value(client, FSCHER_REG_FAN1_ACT);
-		data->fan_act[2] = fscher_read_value(client, FSCHER_REG_FAN2_ACT);
-		data->fan_status[0] = fscher_read_value(client, FSCHER_REG_FAN0_STATE);
-		data->fan_status[1] = fscher_read_value(client, FSCHER_REG_FAN1_STATE);
-		data->fan_status[2] = fscher_read_value(client, FSCHER_REG_FAN2_STATE);
-		data->fan_min[0] = fscher_read_value(client, FSCHER_REG_FAN0_MIN);
-		data->fan_min[1] = fscher_read_value(client, FSCHER_REG_FAN1_MIN);
-		data->fan_min[2] = fscher_read_value(client, FSCHER_REG_FAN2_MIN);
-		data->fan_ripple[0] = fscher_read_value(client, FSCHER_REG_FAN0_RIPPLE);
-		data->fan_ripple[1] = fscher_read_value(client, FSCHER_REG_FAN1_RIPPLE);
-		data->fan_ripple[2] = fscher_read_value(client, FSCHER_REG_FAN2_RIPPLE);
-
-		data->watchdog[0] = fscher_read_value(client, FSCHER_REG_WDOG_PRESET);
-		data->watchdog[1] = fscher_read_value(client, FSCHER_REG_WDOG_STATE);
-		data->watchdog[2] = fscher_read_value(client, FSCHER_REG_WDOG_CONTROL);
-
-		data->global_event = fscher_read_value(client, FSCHER_REG_EVENT_STATE);
-
-		data->last_updated = jiffies;
-		data->valid = 1;                 
-	}
-
-	up(&data->update_lock);
-
-	return data;
-}
-
-
-
-#define FAN_INDEX_FROM_NUM(nr)	((nr) - 1)
-
-static ssize_t set_fan_status(struct i2c_client *client, struct fscher_data *data,
-			      const char *buf, size_t count, int nr, int reg)
-{
-	/* bits 0..1, 3..7 reserved => mask with 0x04 */  
-	unsigned long v = simple_strtoul(buf, NULL, 10) & 0x04;
-	
-	down(&data->update_lock);
-	data->fan_status[FAN_INDEX_FROM_NUM(nr)] &= ~v;
-	fscher_write_value(client, reg, v);
-	up(&data->update_lock);
-	return count;
-}
-
-static ssize_t show_fan_status(struct fscher_data *data, char *buf, int nr)
-{
-	/* bits 0..1, 3..7 reserved => mask with 0x04 */  
-	return sprintf(buf, "%u\n", data->fan_status[FAN_INDEX_FROM_NUM(nr)] & 0x04);
-}
-
-static ssize_t set_pwm(struct i2c_client *client, struct fscher_data *data,
-		       const char *buf, size_t count, int nr, int reg)
-{
-	unsigned long v = simple_strtoul(buf, NULL, 10);
-
-	down(&data->update_lock);
-	data->fan_min[FAN_INDEX_FROM_NUM(nr)] = v > 0xff ? 0xff : v;
-	fscher_write_value(client, reg, data->fan_min[FAN_INDEX_FROM_NUM(nr)]);
-	up(&data->update_lock);
-	return count;
-}
-
-static ssize_t show_pwm(struct fscher_data *data, char *buf, int nr)
-{
-	return sprintf(buf, "%u\n", data->fan_min[FAN_INDEX_FROM_NUM(nr)]);
-}
-
-static ssize_t set_fan_div(struct i2c_client *client, struct fscher_data *data,
-			   const char *buf, size_t count, int nr, int reg)
-{
-	/* supported values: 2, 4, 8 */
-	unsigned long v = simple_strtoul(buf, NULL, 10);
-
-	switch (v) {
-	case 2: v = 1; break;
-	case 4: v = 2; break;
-	case 8: v = 3; break;
-	default:
-		dev_err(&client->dev, "fan_div value %ld not "
-			 "supported. Choose one of 2, 4 or 8!\n", v);
-		return -EINVAL;
-	}
-
-	down(&data->update_lock);
-
-	/* bits 2..7 reserved => mask with 0x03 */
-	data->fan_ripple[FAN_INDEX_FROM_NUM(nr)] &= ~0x03;
-	data->fan_ripple[FAN_INDEX_FROM_NUM(nr)] |= v;
-
-	fscher_write_value(client, reg, data->fan_ripple[FAN_INDEX_FROM_NUM(nr)]);
-	up(&data->update_lock);
-	return count;
-}
-
-static ssize_t show_fan_div(struct fscher_data *data, char *buf, int nr)
-{
-	/* bits 2..7 reserved => mask with 0x03 */  
-	return sprintf(buf, "%u\n", 1 << (data->fan_ripple[FAN_INDEX_FROM_NUM(nr)] & 0x03));
-}
-
-#define RPM_FROM_REG(val)	(val*60)
-
-static ssize_t show_fan_input (struct fscher_data *data, char *buf, int nr)
-{
-	return sprintf(buf, "%u\n", RPM_FROM_REG(data->fan_act[FAN_INDEX_FROM_NUM(nr)]));
-}
-
-
-
-#define TEMP_INDEX_FROM_NUM(nr)		((nr) - 1)
-
-static ssize_t set_temp_status(struct i2c_client *client, struct fscher_data *data,
-			       const char *buf, size_t count, int nr, int reg)
-{
-	/* bits 2..7 reserved, 0 read only => mask with 0x02 */  
-	unsigned long v = simple_strtoul(buf, NULL, 10) & 0x02;
-
-	down(&data->update_lock);
-	data->temp_status[TEMP_INDEX_FROM_NUM(nr)] &= ~v;
-	fscher_write_value(client, reg, v);
-	up(&data->update_lock);
-	return count;
-}
-
-static ssize_t show_temp_status(struct fscher_data *data, char *buf, int nr)
-{
-	/* bits 2..7 reserved => mask with 0x03 */
-	return sprintf(buf, "%u\n", data->temp_status[TEMP_INDEX_FROM_NUM(nr)] & 0x03);
-}
-
-#define TEMP_FROM_REG(val)	(((val) - 128) * 1000)
-
-static ssize_t show_temp_input(struct fscher_data *data, char *buf, int nr)
-{
-	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_act[TEMP_INDEX_FROM_NUM(nr)]));
-}
-
-/*
- * The final conversion is specified in sensors.conf, as it depends on
- * mainboard specific values. We export the registers contents as
- * pseudo-hundredths-of-Volts (range 0V - 2.55V). Not that it makes much
- * sense per se, but it minimizes the conversions count and keeps the
- * values within a usual range.
- */
-#define VOLT_FROM_REG(val)	((val) * 10)
-
-static ssize_t show_in_input(struct fscher_data *data, char *buf, int nr)
-{
-	return sprintf(buf, "%u\n", VOLT_FROM_REG(data->volt[nr]));
-}
-
-
-
-static ssize_t show_revision(struct fscher_data *data, char *buf, int nr)
-{
-	return sprintf(buf, "%u\n", data->revision);
-}
-
-
-
-static ssize_t show_alarms(struct fscher_data *data, char *buf, int nr)
-{
-	/* bits 2, 5..6 reserved => mask with 0x9b */
-	return sprintf(buf, "%u\n", data->global_event & 0x9b);
-}
-
-
-
-static ssize_t set_control(struct i2c_client *client, struct fscher_data *data,
-			   const char *buf, size_t count, int nr, int reg)
-{
-	/* bits 1..7 reserved => mask with 0x01 */  
-	unsigned long v = simple_strtoul(buf, NULL, 10) & 0x01;
-
-	down(&data->update_lock);
-	data->global_control &= ~v;
-	fscher_write_value(client, reg, v);
-	up(&data->update_lock);
-	return count;
-}
-
-static ssize_t show_control(struct fscher_data *data, char *buf, int nr)
-{
-	/* bits 1..7 reserved => mask with 0x01 */
-	return sprintf(buf, "%u\n", data->global_control & 0x01);
-}
-
-
-
-static ssize_t set_watchdog_control(struct i2c_client *client, struct
-				    fscher_data *data, const char *buf, size_t count,
-				    int nr, int reg)
-{
-	/* bits 0..3 reserved => mask with 0xf0 */  
-	unsigned long v = simple_strtoul(buf, NULL, 10) & 0xf0;
-
-	down(&data->update_lock);
-	data->watchdog[2] &= ~0xf0;
-	data->watchdog[2] |= v;
-	fscher_write_value(client, reg, data->watchdog[2]);
-	up(&data->update_lock);
-	return count;
-}
-
-static ssize_t show_watchdog_control(struct fscher_data *data, char *buf, int nr)
-{
-	/* bits 0..3 reserved, bit 5 write only => mask with 0xd0 */
-	return sprintf(buf, "%u\n", data->watchdog[2] & 0xd0);
-}
-
-static ssize_t set_watchdog_status(struct i2c_client *client, struct fscher_data *data,
-				   const char *buf, size_t count, int nr, int reg)
-{
-	/* bits 0, 2..7 reserved => mask with 0x02 */  
-	unsigned long v = simple_strtoul(buf, NULL, 10) & 0x02;
-
-	down(&data->update_lock);
-	data->watchdog[1] &= ~v;
-	fscher_write_value(client, reg, v);
-	up(&data->update_lock);
-	return count;
-}
-
-static ssize_t show_watchdog_status(struct fscher_data *data, char *buf, int nr)
-{
-	/* bits 0, 2..7 reserved => mask with 0x02 */
-	return sprintf(buf, "%u\n", data->watchdog[1] & 0x02);
-}
-
-static ssize_t set_watchdog_preset(struct i2c_client *client, struct fscher_data *data,
-				   const char *buf, size_t count, int nr, int reg)
-{
-	unsigned long v = simple_strtoul(buf, NULL, 10) & 0xff;
-	
-	down(&data->update_lock);
-	data->watchdog[0] = v;
-	fscher_write_value(client, reg, data->watchdog[0]);
-	up(&data->update_lock);
-	return count;
-}
-
-static ssize_t show_watchdog_preset(struct fscher_data *data, char *buf, int nr)
-{
-	return sprintf(buf, "%u\n", data->watchdog[0]);
-}
-
-static int __init sensors_fscher_init(void)
-{
-	return i2c_add_driver(&fscher_driver);
-}
-
-static void __exit sensors_fscher_exit(void)
-{
-	i2c_del_driver(&fscher_driver);
-}
-
-MODULE_AUTHOR("Reinhard Nissl <rnissl@gmx.de>");
-MODULE_DESCRIPTION("FSC Hermes driver");
-MODULE_LICENSE("GPL");
-
-module_init(sensors_fscher_init);
-module_exit(sensors_fscher_exit);
diff --git a/drivers/i2c/chips/fscpos.c b/drivers/i2c/chips/fscpos.c
deleted file mode 100644
--- a/drivers/i2c/chips/fscpos.c
+++ /dev/null
@@ -1,641 +0,0 @@
-/*
-	fscpos.c - Kernel module for hardware monitoring with FSC Poseidon chips
-	Copyright (C) 2004, 2005 Stefan Ott <stefan@desire.ch>
-
-	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.
-*/
-
-/*
-	fujitsu siemens poseidon chip,
-	module based on the old fscpos module by Hermann Jung <hej@odn.de> and
-	the fscher module by Reinhard Nissl <rnissl@gmx.de>
-
-	original module based on lm80.c
-	Copyright (C) 1998, 1999 Frodo Looijaard <frodol@dds.nl>
-	and Philip Edelbrock <phil@netroedge.com>
-
-	Thanks to Jean Delvare for reviewing my code and suggesting a lot of
-	improvements.
-*/
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-#include <linux/i2c-sensor.h>
-#include <linux/init.h>
-
-/*
- * Addresses to scan
- */
-static unsigned short normal_i2c[] = { 0x73, I2C_CLIENT_END };
-static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
-
-/*
- * Insmod parameters
- */
-SENSORS_INSMOD_1(fscpos);
-
-/*
- * The FSCPOS registers
- */
-
-/* chip identification */
-#define FSCPOS_REG_IDENT_0		0x00
-#define FSCPOS_REG_IDENT_1		0x01
-#define FSCPOS_REG_IDENT_2		0x02
-#define FSCPOS_REG_REVISION		0x03
-
-/* global control and status */
-#define FSCPOS_REG_EVENT_STATE		0x04
-#define FSCPOS_REG_CONTROL		0x05
-
-/* watchdog */
-#define FSCPOS_REG_WDOG_PRESET		0x28
-#define FSCPOS_REG_WDOG_STATE		0x23
-#define FSCPOS_REG_WDOG_CONTROL		0x21
-
-/* voltages */
-#define FSCPOS_REG_VOLT_12		0x45
-#define FSCPOS_REG_VOLT_5		0x42
-#define FSCPOS_REG_VOLT_BATT		0x48
-
-/* fans - the chip does not support minimum speed for fan2 */
-static u8 FSCPOS_REG_PWM[] = { 0x55, 0x65 };
-static u8 FSCPOS_REG_FAN_ACT[] = { 0x0e, 0x6b, 0xab };
-static u8 FSCPOS_REG_FAN_STATE[] = { 0x0d, 0x62, 0xa2 };
-static u8 FSCPOS_REG_FAN_RIPPLE[] = { 0x0f, 0x6f, 0xaf };
-
-/* temperatures */
-static u8 FSCPOS_REG_TEMP_ACT[] = { 0x64, 0x32, 0x35 };
-static u8 FSCPOS_REG_TEMP_STATE[] = { 0x71, 0x81, 0x91 };
-
-/*
- * Functions declaration
- */
-static int fscpos_attach_adapter(struct i2c_adapter *adapter);
-static int fscpos_detect(struct i2c_adapter *adapter, int address, int kind);
-static int fscpos_detach_client(struct i2c_client *client);
-
-static int fscpos_read_value(struct i2c_client *client, u8 register);
-static int fscpos_write_value(struct i2c_client *client, u8 register, u8 value);
-static struct fscpos_data *fscpos_update_device(struct device *dev);
-static void fscpos_init_client(struct i2c_client *client);
-
-static void reset_fan_alarm(struct i2c_client *client, int nr);
-
-/*
- * Driver data (common to all clients)
- */
-static struct i2c_driver fscpos_driver = {
-	.owner		= THIS_MODULE,
-	.name		= "fscpos",
-	.id		= I2C_DRIVERID_FSCPOS,
-	.flags		= I2C_DF_NOTIFY,
-	.attach_adapter	= fscpos_attach_adapter,
-	.detach_client	= fscpos_detach_client,
-};
-
-/*
- * Client data (each client gets its own)
- */
-struct fscpos_data {
-	struct i2c_client client;
-	struct semaphore update_lock;
-	char valid; 		/* 0 until following fields are valid */
-	unsigned long last_updated;	/* In jiffies */
-
-	/* register values */
-	u8 revision;		/* revision of chip */
-	u8 global_event;	/* global event status */
-	u8 global_control;	/* global control register */
-	u8 wdog_control;	/* watchdog control */
-	u8 wdog_state;		/* watchdog status */
-	u8 wdog_preset;		/* watchdog preset */
-	u8 volt[3];		/* 12, 5, battery current */
-	u8 temp_act[3];		/* temperature */
-	u8 temp_status[3];	/* status of sensor */
-	u8 fan_act[3];		/* fans revolutions per second */
-	u8 fan_status[3];	/* fan status */
-	u8 pwm[2];		/* fan min value for rps */
-	u8 fan_ripple[3];	/* divider for rps */
-};
-
-/* Temperature */
-#define TEMP_FROM_REG(val)	(((val) - 128) * 1000)
-
-static ssize_t show_temp_input(struct fscpos_data *data, char *buf, int nr)
-{
-	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_act[nr - 1]));
-}
-
-static ssize_t show_temp_status(struct fscpos_data *data, char *buf, int nr)
-{
-	/* bits 2..7 reserved => mask with 0x03 */
-	return sprintf(buf, "%u\n", data->temp_status[nr - 1] & 0x03);
-}
-
-static ssize_t show_temp_reset(struct fscpos_data *data, char *buf, int nr)
-{
-	return sprintf(buf, "1\n");
-}
-
-static ssize_t set_temp_reset(struct i2c_client *client, struct fscpos_data
-			*data, const char *buf,	size_t count, int nr, int reg)
-{
-	unsigned long v = simple_strtoul(buf, NULL, 10);
-	if (v != 1) {
-		dev_err(&client->dev, "temp_reset value %ld not supported. "
-					"Use 1 to reset the alarm!\n", v);
-		return -EINVAL;
-	}
-
-	dev_info(&client->dev, "You used the temp_reset feature which has not "
-				"been proplerly tested. Please report your "
-				"experience to the module author.\n");
-
-	/* Supported value: 2 (clears the status) */
-	fscpos_write_value(client, FSCPOS_REG_TEMP_STATE[nr], 2);
-	return count;
-}
-
-/* Fans */
-#define RPM_FROM_REG(val)	((val) * 60)
-
-static ssize_t show_fan_status(struct fscpos_data *data, char *buf, int nr)
-{
-	/* bits 0..1, 3..7 reserved => mask with 0x04 */
-	return sprintf(buf, "%u\n", data->fan_status[nr - 1] & 0x04);
-}
-
-static ssize_t show_fan_input(struct fscpos_data *data, char *buf, int nr)
-{
-	return sprintf(buf, "%u\n", RPM_FROM_REG(data->fan_act[nr - 1]));
-}
-
-static ssize_t show_fan_ripple(struct fscpos_data *data, char *buf, int nr)
-{
-	/* bits 2..7 reserved => mask with 0x03 */
-	return sprintf(buf, "%u\n", data->fan_ripple[nr - 1] & 0x03);
-}
-
-static ssize_t set_fan_ripple(struct i2c_client *client, struct fscpos_data
-			*data, const char *buf,	size_t count, int nr, int reg)
-{
-	/* supported values: 2, 4, 8 */
-	unsigned long v = simple_strtoul(buf, NULL, 10);
-
-	switch (v) {
-		case 2: v = 1; break;
-		case 4: v = 2; break;
-		case 8: v = 3; break;
-	default:
-		dev_err(&client->dev, "fan_ripple value %ld not supported. "
-					"Must be one of 2, 4 or 8!\n", v);
-		return -EINVAL;
-	}
-	
-	down(&data->update_lock);
-	/* bits 2..7 reserved => mask with 0x03 */
-	data->fan_ripple[nr - 1] &= ~0x03;
-	data->fan_ripple[nr - 1] |= v;
-	
-	fscpos_write_value(client, reg, data->fan_ripple[nr - 1]);
-	up(&data->update_lock);
-	return count;
-}
-
-static ssize_t show_pwm(struct fscpos_data *data, char *buf, int nr)
-{
-	return sprintf(buf, "%u\n", data->pwm[nr - 1]);
-}
-
-static ssize_t set_pwm(struct i2c_client *client, struct fscpos_data *data,
-				const char *buf, size_t count, int nr, int reg)
-{
-	unsigned long v = simple_strtoul(buf, NULL, 10);
-
-	/* Range: 0..255 */
-	if (v < 0) v = 0;
-	if (v > 255) v = 255;
-
-	down(&data->update_lock);
-	data->pwm[nr - 1] = v;
-	fscpos_write_value(client, reg, data->pwm[nr - 1]);
-	up(&data->update_lock);
-	return count;
-}
-
-static void reset_fan_alarm(struct i2c_client *client, int nr)
-{
-	fscpos_write_value(client, FSCPOS_REG_FAN_STATE[nr], 4);
-}
-
-/* Volts */
-#define VOLT_FROM_REG(val, mult)	((val) * (mult) / 255)
-
-static ssize_t show_volt_12(struct device *dev, char *buf)
-{
-	struct fscpos_data *data = fscpos_update_device(dev);
-	return sprintf(buf, "%u\n", VOLT_FROM_REG(data->volt[0], 14200));
-}
-
-static ssize_t show_volt_5(struct device *dev, char *buf)
-{
-	struct fscpos_data *data = fscpos_update_device(dev);
-	return sprintf(buf, "%u\n", VOLT_FROM_REG(data->volt[1], 6600));
-}
-
-static ssize_t show_volt_batt(struct device *dev, char *buf)
-{
-	struct fscpos_data *data = fscpos_update_device(dev);
-	return sprintf(buf, "%u\n", VOLT_FROM_REG(data->volt[2], 3300));
-}
-
-/* Watchdog */
-static ssize_t show_wdog_control(struct fscpos_data *data, char *buf)
-{
-	/* bits 0..3 reserved, bit 6 write only => mask with 0xb0 */
-	return sprintf(buf, "%u\n", data->wdog_control & 0xb0);
-}
-
-static ssize_t set_wdog_control(struct i2c_client *client, struct fscpos_data
-				*data, const char *buf,	size_t count, int reg)
-{
-	/* bits 0..3 reserved => mask with 0xf0 */
-	unsigned long v = simple_strtoul(buf, NULL, 10) & 0xf0;
-
-	down(&data->update_lock);
-	data->wdog_control &= ~0xf0;
-	data->wdog_control |= v;
-	fscpos_write_value(client, reg, data->wdog_control);
-	up(&data->update_lock);
-	return count;
-}
-
-static ssize_t show_wdog_state(struct fscpos_data *data, char *buf)
-{
-	/* bits 0, 2..7 reserved => mask with 0x02 */
-	return sprintf(buf, "%u\n", data->wdog_state & 0x02);
-}
-
-static ssize_t set_wdog_state(struct i2c_client *client, struct fscpos_data
-				*data, const char *buf, size_t count, int reg)
-{
-	unsigned long v = simple_strtoul(buf, NULL, 10) & 0x02;
-
-	/* Valid values: 2 (clear) */
-	if (v != 2) {
-		dev_err(&client->dev, "wdog_state value %ld not supported. "
-					"Must be 2 to clear the state!\n", v);
-		return -EINVAL;
-	}
-
-	down(&data->update_lock);
-	data->wdog_state &= ~v;
-	fscpos_write_value(client, reg, v);
-	up(&data->update_lock);
-	return count;
-}
-
-static ssize_t show_wdog_preset(struct fscpos_data *data, char *buf)
-{
-	return sprintf(buf, "%u\n", data->wdog_preset);
-}
-
-static ssize_t set_wdog_preset(struct i2c_client *client, struct fscpos_data
-				*data, const char *buf,	size_t count, int reg)
-{
-	unsigned long v = simple_strtoul(buf, NULL, 10) & 0xff;
-
-	down(&data->update_lock);
-	data->wdog_preset = v;
-	fscpos_write_value(client, reg, data->wdog_preset);
-	up(&data->update_lock);
-	return count;
-}
-
-/* Event */
-static ssize_t show_event(struct device *dev, char *buf)
-{
-	/* bits 5..7 reserved => mask with 0x1f */
-	struct fscpos_data *data = fscpos_update_device(dev);
-	return sprintf(buf, "%u\n", data->global_event & 0x9b);
-}
-
-/*
- * Sysfs stuff
- */
-#define create_getter(kind, sub) \
-	static ssize_t sysfs_show_##kind##sub(struct device *dev, char *buf) \
-	{ \
-		struct fscpos_data *data = fscpos_update_device(dev); \
-		return show_##kind##sub(data, buf); \
-	}
-
-#define create_getter_n(kind, offset, sub) \
-	static ssize_t sysfs_show_##kind##offset##sub(struct device *dev, char\
-								 	*buf) \
-	{ \
-		struct fscpos_data *data = fscpos_update_device(dev); \
-		return show_##kind##sub(data, buf, offset); \
-	}
-
-#define create_setter(kind, sub, reg) \
-	static ssize_t sysfs_set_##kind##sub (struct device *dev, const char \
-							*buf, size_t count) \
-	{ \
-		struct i2c_client *client = to_i2c_client(dev); \
-		struct fscpos_data *data = i2c_get_clientdata(client); \
-		return set_##kind##sub(client, data, buf, count, reg); \
-	}
-
-#define create_setter_n(kind, offset, sub, reg) \
-	static ssize_t sysfs_set_##kind##offset##sub (struct device *dev, \
-					const char *buf, size_t count) \
-	{ \
-		struct i2c_client *client = to_i2c_client(dev); \
-		struct fscpos_data *data = i2c_get_clientdata(client); \
-		return set_##kind##sub(client, data, buf, count, offset, reg);\
-	}
-
-#define create_sysfs_device_ro(kind, sub, offset) \
-	static DEVICE_ATTR(kind##offset##sub, S_IRUGO, \
-					sysfs_show_##kind##offset##sub, NULL);
-
-#define create_sysfs_device_rw(kind, sub, offset) \
-	static DEVICE_ATTR(kind##offset##sub, S_IRUGO | S_IWUSR, \
-		sysfs_show_##kind##offset##sub, sysfs_set_##kind##offset##sub);
-
-#define sysfs_ro_n(kind, sub, offset) \
-	create_getter_n(kind, offset, sub); \
-	create_sysfs_device_ro(kind, sub, offset);
-
-#define sysfs_rw_n(kind, sub, offset, reg) \
-	create_getter_n(kind, offset, sub); \
-	create_setter_n(kind, offset, sub, reg); \
-	create_sysfs_device_rw(kind, sub, offset);
-
-#define sysfs_rw(kind, sub, reg) \
-	create_getter(kind, sub); \
-	create_setter(kind, sub, reg); \
-	create_sysfs_device_rw(kind, sub,);
-
-#define sysfs_fan_with_min(offset, reg_status, reg_ripple, reg_min) \
-	sysfs_fan(offset, reg_status, reg_ripple); \
-	sysfs_rw_n(pwm,, offset, reg_min);
-
-#define sysfs_fan(offset, reg_status, reg_ripple) \
-	sysfs_ro_n(fan, _input, offset); \
-	sysfs_ro_n(fan, _status, offset); \
-	sysfs_rw_n(fan, _ripple, offset, reg_ripple);
-
-#define sysfs_temp(offset, reg_status) \
-	sysfs_ro_n(temp, _input, offset); \
-	sysfs_ro_n(temp, _status, offset); \
-	sysfs_rw_n(temp, _reset, offset, reg_status);
-
-#define sysfs_watchdog(reg_wdog_preset, reg_wdog_state, reg_wdog_control) \
-	sysfs_rw(wdog, _control, reg_wdog_control); \
-	sysfs_rw(wdog, _preset, reg_wdog_preset); \
-	sysfs_rw(wdog, _state, reg_wdog_state);
-
-sysfs_fan_with_min(1, FSCPOS_REG_FAN_STATE[0], FSCPOS_REG_FAN_RIPPLE[0],
-							FSCPOS_REG_PWM[0]);
-sysfs_fan_with_min(2, FSCPOS_REG_FAN_STATE[1], FSCPOS_REG_FAN_RIPPLE[1],
-							FSCPOS_REG_PWM[1]);
-sysfs_fan(3, FSCPOS_REG_FAN_STATE[2], FSCPOS_REG_FAN_RIPPLE[2]);
-
-sysfs_temp(1, FSCPOS_REG_TEMP_STATE[0]);
-sysfs_temp(2, FSCPOS_REG_TEMP_STATE[1]);
-sysfs_temp(3, FSCPOS_REG_TEMP_STATE[2]);
-
-sysfs_watchdog(FSCPOS_REG_WDOG_PRESET, FSCPOS_REG_WDOG_STATE,
-						FSCPOS_REG_WDOG_CONTROL);
-
-static DEVICE_ATTR(event, S_IRUGO, show_event, NULL);
-static DEVICE_ATTR(in0_input, S_IRUGO, show_volt_12, NULL);
-static DEVICE_ATTR(in1_input, S_IRUGO, show_volt_5, NULL);
-static DEVICE_ATTR(in2_input, S_IRUGO, show_volt_batt, NULL);
-
-static int fscpos_attach_adapter(struct i2c_adapter *adapter)
-{
-	if (!(adapter->class & I2C_CLASS_HWMON))
-		return 0;
-	return i2c_detect(adapter, &addr_data, fscpos_detect);
-}
-
-int fscpos_detect(struct i2c_adapter *adapter, int address, int kind)
-{
-	struct i2c_client *new_client;
-	struct fscpos_data *data;
-	int err = 0;
-
-	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
-		goto exit;
-
-	/*
-	 * OK. For now, we presume we have a valid client. We now create the
-	 * client structure, even though we cannot fill it completely yet.
-	 * But it allows us to access fscpos_{read,write}_value.
-	 */
-
-	if (!(data = kmalloc(sizeof(struct fscpos_data), GFP_KERNEL))) {
-		err = -ENOMEM;
-		goto exit;
-	}
-	memset(data, 0, sizeof(struct fscpos_data));
-
-	new_client = &data->client;
-	i2c_set_clientdata(new_client, data);
-	new_client->addr = address;
-	new_client->adapter = adapter;
-	new_client->driver = &fscpos_driver;
-	new_client->flags = 0;
-
-	/* Do the remaining detection unless force or force_fscpos parameter */
-	if (kind < 0) {
-		if ((fscpos_read_value(new_client, FSCPOS_REG_IDENT_0)
-			!= 0x50) /* 'P' */
-		|| (fscpos_read_value(new_client, FSCPOS_REG_IDENT_1)
-			!= 0x45) /* 'E' */
-		|| (fscpos_read_value(new_client, FSCPOS_REG_IDENT_2)
-			!= 0x47))/* 'G' */
-		{
-			dev_dbg(&new_client->dev, "fscpos detection failed\n");
-			goto exit_free;
-		}
-	}
-
-	/* Fill in the remaining client fields and put it in the global list */
-	strlcpy(new_client->name, "fscpos", I2C_NAME_SIZE);
-
-	data->valid = 0;
-	init_MUTEX(&data->update_lock);
-
-	/* Tell the I2C layer a new client has arrived */
-	if ((err = i2c_attach_client(new_client)))
-		goto exit_free;
-
-	/* Inizialize the fscpos chip */
-	fscpos_init_client(new_client);
-
-	/* Announce that the chip was found */
-	dev_info(&new_client->dev, "Found fscpos chip, rev %u\n", data->revision);
-
-	/* Register sysfs hooks */
-	device_create_file(&new_client->dev, &dev_attr_event);
-	device_create_file(&new_client->dev, &dev_attr_in0_input);
-	device_create_file(&new_client->dev, &dev_attr_in1_input);
-	device_create_file(&new_client->dev, &dev_attr_in2_input);
-	device_create_file(&new_client->dev, &dev_attr_wdog_control);
-	device_create_file(&new_client->dev, &dev_attr_wdog_preset);
-	device_create_file(&new_client->dev, &dev_attr_wdog_state);
-	device_create_file(&new_client->dev, &dev_attr_temp1_input);
-	device_create_file(&new_client->dev, &dev_attr_temp1_status);
-	device_create_file(&new_client->dev, &dev_attr_temp1_reset);
-	device_create_file(&new_client->dev, &dev_attr_temp2_input);
-	device_create_file(&new_client->dev, &dev_attr_temp2_status);
-	device_create_file(&new_client->dev, &dev_attr_temp2_reset);
-	device_create_file(&new_client->dev, &dev_attr_temp3_input);
-	device_create_file(&new_client->dev, &dev_attr_temp3_status);
-	device_create_file(&new_client->dev, &dev_attr_temp3_reset);
-	device_create_file(&new_client->dev, &dev_attr_fan1_input);
-	device_create_file(&new_client->dev, &dev_attr_fan1_status);
-	device_create_file(&new_client->dev, &dev_attr_fan1_ripple);
-	device_create_file(&new_client->dev, &dev_attr_pwm1);
-	device_create_file(&new_client->dev, &dev_attr_fan2_input);
-	device_create_file(&new_client->dev, &dev_attr_fan2_status);
-	device_create_file(&new_client->dev, &dev_attr_fan2_ripple);
-	device_create_file(&new_client->dev, &dev_attr_pwm2);
-	device_create_file(&new_client->dev, &dev_attr_fan3_input);
-	device_create_file(&new_client->dev, &dev_attr_fan3_status);
-	device_create_file(&new_client->dev, &dev_attr_fan3_ripple);
-
-	return 0;
-
-exit_free:
-	kfree(data);
-exit:
-	return err;
-}
-
-static int fscpos_detach_client(struct i2c_client *client)
-{
-	int err;
-
-	if ((err = i2c_detach_client(client))) {
-		dev_err(&client->dev, "Client deregistration failed, client"
-							" not detached.\n");
-		return err;
-	}
-	kfree(i2c_get_clientdata(client));
-	return 0;
-}
-
-static int fscpos_read_value(struct i2c_client *client, u8 reg)
-{
-	dev_dbg(&client->dev, "Read reg 0x%02x\n", reg);
-	return i2c_smbus_read_byte_data(client, reg);
-}
-
-static int fscpos_write_value(struct i2c_client *client, u8 reg, u8 value)
-{
-	dev_dbg(&client->dev, "Write reg 0x%02x, val 0x%02x\n", reg, value);
-	return i2c_smbus_write_byte_data(client, reg, value);
-}
-
-/* Called when we have found a new FSCPOS chip */
-static void fscpos_init_client(struct i2c_client *client)
-{
-	struct fscpos_data *data = i2c_get_clientdata(client);
-
-	/* read revision from chip */
-	data->revision = fscpos_read_value(client, FSCPOS_REG_REVISION);
-}
-
-static struct fscpos_data *fscpos_update_device(struct device *dev)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct fscpos_data *data = i2c_get_clientdata(client);
-
-	down(&data->update_lock);
-
-	if ((jiffies - data->last_updated > 2 * HZ) ||
-			(jiffies < data->last_updated) || !data->valid) {
-		int i;
-
-		dev_dbg(&client->dev, "Starting fscpos update\n");
-
-		for (i = 0; i < 3; i++) {
-			data->temp_act[i] = fscpos_read_value(client,
-						FSCPOS_REG_TEMP_ACT[i]);
-			data->temp_status[i] = fscpos_read_value(client,
-						FSCPOS_REG_TEMP_STATE[i]);
-			data->fan_act[i] = fscpos_read_value(client,
-						FSCPOS_REG_FAN_ACT[i]);
-			data->fan_status[i] = fscpos_read_value(client,
-						FSCPOS_REG_FAN_STATE[i]);
-			data->fan_ripple[i] = fscpos_read_value(client,
-						FSCPOS_REG_FAN_RIPPLE[i]);
-			if (i < 2) {
-				/* fan2_min is not supported by the chip */
-				data->pwm[i] = fscpos_read_value(client,
-							FSCPOS_REG_PWM[i]);
-			}
-			/* reset fan status if speed is back to > 0 */
-			if (data->fan_status[i] != 0 && data->fan_act[i] > 0) {
-				reset_fan_alarm(client, i);
-			}
-		}
-
-		data->volt[0] = fscpos_read_value(client, FSCPOS_REG_VOLT_12);
-		data->volt[1] = fscpos_read_value(client, FSCPOS_REG_VOLT_5);
-		data->volt[2] = fscpos_read_value(client, FSCPOS_REG_VOLT_BATT);
-
-		data->wdog_preset = fscpos_read_value(client,
-							FSCPOS_REG_WDOG_PRESET);
-		data->wdog_state = fscpos_read_value(client,
-							FSCPOS_REG_WDOG_STATE);
-		data->wdog_control = fscpos_read_value(client,
-						FSCPOS_REG_WDOG_CONTROL);
-
-		data->global_event = fscpos_read_value(client,
-						FSCPOS_REG_EVENT_STATE);
-
-		data->last_updated = jiffies;
-		data->valid = 1;
-	}
-	up(&data->update_lock);
-	return data;
-}
-
-static int __init sm_fscpos_init(void)
-{
-	return i2c_add_driver(&fscpos_driver);
-}
-
-static void __exit sm_fscpos_exit(void)
-{
-	i2c_del_driver(&fscpos_driver);
-}
-
-MODULE_AUTHOR("Stefan Ott <stefan@desire.ch> based on work from Hermann Jung "
-				"<hej@odn.de>, Frodo Looijaard <frodol@dds.nl>"
-				" and Philip Edelbrock <phil@netroedge.com>");
-MODULE_DESCRIPTION("fujitsu siemens poseidon chip driver");
-MODULE_LICENSE("GPL");
-
-module_init(sm_fscpos_init);
-module_exit(sm_fscpos_exit);
diff --git a/drivers/i2c/chips/gl518sm.c b/drivers/i2c/chips/gl518sm.c
deleted file mode 100644
--- a/drivers/i2c/chips/gl518sm.c
+++ /dev/null
@@ -1,605 +0,0 @@
-/*
- * gl518sm.c - Part of lm_sensors, Linux kernel modules for hardware
- *             monitoring
- * Copyright (C) 1998, 1999 Frodo Looijaard <frodol@dds.nl> and
- * Kyosti Malkki <kmalkki@cc.hut.fi>
- * Copyright (C) 2004 Hong-Gunn Chew <hglinux@gunnet.org> and
- * Jean Delvare <khali@linux-fr.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.
- *
- * Ported to Linux 2.6 by Hong-Gunn Chew with the help of Jean Delvare
- * and advice of Greg Kroah-Hartman.
- *
- * Notes about the port:
- * Release 0x00 of the GL518SM chipset doesn't support reading of in0,
- * in1 nor in2. The original driver had an ugly workaround to get them
- * anyway (changing limits and watching alarms trigger and wear off).
- * We did not keep that part of the original driver in the Linux 2.6
- * version, since it was making the driver significantly more complex
- * with no real benefit.
- *
- * History:
- * 2004-01-28  Original port. (Hong-Gunn Chew)
- * 2004-01-31  Code review and approval. (Jean Delvare)
- */
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/jiffies.h>
-#include <linux/i2c.h>
-#include <linux/i2c-sensor.h>
-
-/* Addresses to scan */
-static unsigned short normal_i2c[] = { 0x2c, 0x2d, I2C_CLIENT_END };
-static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
-
-/* Insmod parameters */
-SENSORS_INSMOD_2(gl518sm_r00, gl518sm_r80);
-
-/* Many GL518 constants specified below */
-
-/* The GL518 registers */
-#define GL518_REG_CHIP_ID	0x00
-#define GL518_REG_REVISION	0x01
-#define GL518_REG_VENDOR_ID	0x02
-#define GL518_REG_CONF		0x03
-#define GL518_REG_TEMP_IN	0x04
-#define GL518_REG_TEMP_MAX	0x05
-#define GL518_REG_TEMP_HYST	0x06
-#define GL518_REG_FAN_COUNT	0x07
-#define GL518_REG_FAN_LIMIT	0x08
-#define GL518_REG_VIN1_LIMIT	0x09
-#define GL518_REG_VIN2_LIMIT	0x0a
-#define GL518_REG_VIN3_LIMIT	0x0b
-#define GL518_REG_VDD_LIMIT	0x0c
-#define GL518_REG_VIN3		0x0d
-#define GL518_REG_MISC		0x0f
-#define GL518_REG_ALARM		0x10
-#define GL518_REG_MASK		0x11
-#define GL518_REG_INT		0x12
-#define GL518_REG_VIN2		0x13
-#define GL518_REG_VIN1		0x14
-#define GL518_REG_VDD		0x15
-
-
-/*
- * Conversions. Rounding and limit checking is only done on the TO_REG
- * variants. Note that you should be a bit careful with which arguments
- * these macros are called: arguments may be evaluated more than once.
- * Fixing this is just not worth it.
- */
-
-#define RAW_FROM_REG(val)	val
-
-#define BOOL_FROM_REG(val)	((val)?0:1)
-#define BOOL_TO_REG(val)	((val)?0:1)
-
-#define TEMP_TO_REG(val)	(SENSORS_LIMIT(((((val)<0? \
-				(val)-500:(val)+500)/1000)+119),0,255))
-#define TEMP_FROM_REG(val)	(((val) - 119) * 1000)
-
-static inline u8 FAN_TO_REG(long rpm, int div)
-{
-	long rpmdiv;
-	if (rpm == 0)
-		return 0;
-	rpmdiv = SENSORS_LIMIT(rpm, 1, 1920000) * div;
-	return SENSORS_LIMIT((960000 + rpmdiv / 2) / rpmdiv, 1, 255);
-}
-#define FAN_FROM_REG(val,div)	((val)==0 ? 0 : (960000/((val)*(div))))
-
-#define IN_TO_REG(val)		(SENSORS_LIMIT((((val)+9)/19),0,255))
-#define IN_FROM_REG(val)	((val)*19)
-
-#define VDD_TO_REG(val)		(SENSORS_LIMIT((((val)*4+47)/95),0,255))
-#define VDD_FROM_REG(val)	(((val)*95+2)/4)
-
-#define DIV_TO_REG(val)		((val)==4?2:(val)==2?1:(val)==1?0:3)
-#define DIV_FROM_REG(val)	(1 << (val))
-
-#define BEEP_MASK_TO_REG(val)	((val) & 0x7f & data->alarm_mask)
-#define BEEP_MASK_FROM_REG(val)	((val) & 0x7f)
-
-/* Each client has this additional data */
-struct gl518_data {
-	struct i2c_client client;
-	enum chips type;
-
-	struct semaphore update_lock;
-	char valid;		/* !=0 if following fields are valid */
-	unsigned long last_updated;	/* In jiffies */
-
-	u8 voltage_in[4];	/* Register values; [0] = VDD */
-	u8 voltage_min[4];	/* Register values; [0] = VDD */
-	u8 voltage_max[4];	/* Register values; [0] = VDD */
-	u8 iter_voltage_in[4];	/* Register values; [0] = VDD */
-	u8 fan_in[2];
-	u8 fan_min[2];
-	u8 fan_div[2];		/* Register encoding, shifted right */
-	u8 fan_auto1;		/* Boolean */
-	u8 temp_in;		/* Register values */
-	u8 temp_max;		/* Register values */
-	u8 temp_hyst;		/* Register values */
-	u8 alarms;		/* Register value */
-	u8 alarm_mask;		/* Register value */
-	u8 beep_mask;		/* Register value */
-	u8 beep_enable;		/* Boolean */
-};
-
-static int gl518_attach_adapter(struct i2c_adapter *adapter);
-static int gl518_detect(struct i2c_adapter *adapter, int address, int kind);
-static void gl518_init_client(struct i2c_client *client);
-static int gl518_detach_client(struct i2c_client *client);
-static int gl518_read_value(struct i2c_client *client, u8 reg);
-static int gl518_write_value(struct i2c_client *client, u8 reg, u16 value);
-static struct gl518_data *gl518_update_device(struct device *dev);
-
-/* This is the driver that will be inserted */
-static struct i2c_driver gl518_driver = {
-	.owner		= THIS_MODULE,
-	.name		= "gl518sm",
-	.id		= I2C_DRIVERID_GL518,
-	.flags		= I2C_DF_NOTIFY,
-	.attach_adapter	= gl518_attach_adapter,
-	.detach_client	= gl518_detach_client,
-};
-
-/*
- * Sysfs stuff
- */
-
-#define show(type, suffix, value)					\
-static ssize_t show_##suffix(struct device *dev, char *buf)		\
-{									\
-	struct gl518_data *data = gl518_update_device(dev);		\
-	return sprintf(buf, "%d\n", type##_FROM_REG(data->value));	\
-}
-
-#define show_fan(suffix, value, index)					\
-static ssize_t show_##suffix(struct device *dev, char *buf)		\
-{									\
-	struct gl518_data *data = gl518_update_device(dev);		\
-	return sprintf(buf, "%d\n", FAN_FROM_REG(data->value[index],	\
-		DIV_FROM_REG(data->fan_div[index])));			\
-}
-
-show(TEMP, temp_input1, temp_in);
-show(TEMP, temp_max1, temp_max);
-show(TEMP, temp_hyst1, temp_hyst);
-show(BOOL, fan_auto1, fan_auto1);
-show_fan(fan_input1, fan_in, 0);
-show_fan(fan_input2, fan_in, 1);
-show_fan(fan_min1, fan_min, 0);
-show_fan(fan_min2, fan_min, 1);
-show(DIV, fan_div1, fan_div[0]);
-show(DIV, fan_div2, fan_div[1]);
-show(VDD, in_input0, voltage_in[0]);
-show(IN, in_input1, voltage_in[1]);
-show(IN, in_input2, voltage_in[2]);
-show(IN, in_input3, voltage_in[3]);
-show(VDD, in_min0, voltage_min[0]);
-show(IN, in_min1, voltage_min[1]);
-show(IN, in_min2, voltage_min[2]);
-show(IN, in_min3, voltage_min[3]);
-show(VDD, in_max0, voltage_max[0]);
-show(IN, in_max1, voltage_max[1]);
-show(IN, in_max2, voltage_max[2]);
-show(IN, in_max3, voltage_max[3]);
-show(RAW, alarms, alarms);
-show(BOOL, beep_enable, beep_enable);
-show(BEEP_MASK, beep_mask, beep_mask);
-
-#define set(type, suffix, value, reg)					\
-static ssize_t set_##suffix(struct device *dev, const char *buf,	\
-	size_t count)							\
-{									\
-	struct i2c_client *client = to_i2c_client(dev);			\
-	struct gl518_data *data = i2c_get_clientdata(client);		\
-	long val = simple_strtol(buf, NULL, 10);			\
-									\
-	down(&data->update_lock);					\
-	data->value = type##_TO_REG(val);				\
-	gl518_write_value(client, reg, data->value);			\
-	up(&data->update_lock);						\
-	return count;							\
-}
-
-#define set_bits(type, suffix, value, reg, mask, shift)			\
-static ssize_t set_##suffix(struct device *dev, const char *buf,	\
-	size_t count)							\
-{									\
-	struct i2c_client *client = to_i2c_client(dev);			\
-	struct gl518_data *data = i2c_get_clientdata(client);		\
-	int regvalue;							\
-	unsigned long val = simple_strtoul(buf, NULL, 10);		\
-									\
-	down(&data->update_lock);					\
-	regvalue = gl518_read_value(client, reg);			\
-	data->value = type##_TO_REG(val);				\
-	regvalue = (regvalue & ~mask) | (data->value << shift);		\
-	gl518_write_value(client, reg, regvalue);			\
-	up(&data->update_lock);						\
-	return count;							\
-}
-
-#define set_low(type, suffix, value, reg)				\
-	set_bits(type, suffix, value, reg, 0x00ff, 0)
-#define set_high(type, suffix, value, reg)				\
-	set_bits(type, suffix, value, reg, 0xff00, 8)
-
-set(TEMP, temp_max1, temp_max, GL518_REG_TEMP_MAX);
-set(TEMP, temp_hyst1, temp_hyst, GL518_REG_TEMP_HYST);
-set_bits(BOOL, fan_auto1, fan_auto1, GL518_REG_MISC, 0x08, 3);
-set_bits(DIV, fan_div1, fan_div[0], GL518_REG_MISC, 0xc0, 6);
-set_bits(DIV, fan_div2, fan_div[1], GL518_REG_MISC, 0x30, 4);
-set_low(VDD, in_min0, voltage_min[0], GL518_REG_VDD_LIMIT);
-set_low(IN, in_min1, voltage_min[1], GL518_REG_VIN1_LIMIT);
-set_low(IN, in_min2, voltage_min[2], GL518_REG_VIN2_LIMIT);
-set_low(IN, in_min3, voltage_min[3], GL518_REG_VIN3_LIMIT);
-set_high(VDD, in_max0, voltage_max[0], GL518_REG_VDD_LIMIT);
-set_high(IN, in_max1, voltage_max[1], GL518_REG_VIN1_LIMIT);
-set_high(IN, in_max2, voltage_max[2], GL518_REG_VIN2_LIMIT);
-set_high(IN, in_max3, voltage_max[3], GL518_REG_VIN3_LIMIT);
-set_bits(BOOL, beep_enable, beep_enable, GL518_REG_CONF, 0x04, 2);
-set(BEEP_MASK, beep_mask, beep_mask, GL518_REG_ALARM);
-
-static ssize_t set_fan_min1(struct device *dev, const char *buf, size_t count)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct gl518_data *data = i2c_get_clientdata(client);
-	int regvalue;
-	unsigned long val = simple_strtoul(buf, NULL, 10);
-
-	down(&data->update_lock);
-	regvalue = gl518_read_value(client, GL518_REG_FAN_LIMIT);
-	data->fan_min[0] = FAN_TO_REG(val,
-		DIV_FROM_REG(data->fan_div[0]));
-	regvalue = (regvalue & 0x00ff) | (data->fan_min[0] << 8);
-	gl518_write_value(client, GL518_REG_FAN_LIMIT, regvalue);
-
-	data->beep_mask = gl518_read_value(client, GL518_REG_ALARM);
-	if (data->fan_min[0] == 0)
-		data->alarm_mask &= ~0x20;
-	else
-		data->alarm_mask |= 0x20;
-	data->beep_mask &= data->alarm_mask;
-	gl518_write_value(client, GL518_REG_ALARM, data->beep_mask);
-
-	up(&data->update_lock);
-	return count;
-}
-
-static ssize_t set_fan_min2(struct device *dev, const char *buf, size_t count)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct gl518_data *data = i2c_get_clientdata(client);
-	int regvalue;
-	unsigned long val = simple_strtoul(buf, NULL, 10);
-
-	down(&data->update_lock);
-	regvalue = gl518_read_value(client, GL518_REG_FAN_LIMIT);
-	data->fan_min[1] = FAN_TO_REG(val,
-		DIV_FROM_REG(data->fan_div[1]));
-	regvalue = (regvalue & 0xff00) | data->fan_min[1];
-	gl518_write_value(client, GL518_REG_FAN_LIMIT, regvalue);
-
-	data->beep_mask = gl518_read_value(client, GL518_REG_ALARM);
-	if (data->fan_min[1] == 0)
-		data->alarm_mask &= ~0x40;
-	else
-		data->alarm_mask |= 0x40;
-	data->beep_mask &= data->alarm_mask;
-	gl518_write_value(client, GL518_REG_ALARM, data->beep_mask);
-
-	up(&data->update_lock);
-	return count;
-}
-
-static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp_input1, NULL);
-static DEVICE_ATTR(temp1_max, S_IWUSR|S_IRUGO, show_temp_max1, set_temp_max1);
-static DEVICE_ATTR(temp1_max_hyst, S_IWUSR|S_IRUGO,
-	show_temp_hyst1, set_temp_hyst1);
-static DEVICE_ATTR(fan1_auto, S_IWUSR|S_IRUGO, show_fan_auto1, set_fan_auto1);
-static DEVICE_ATTR(fan1_input, S_IRUGO, show_fan_input1, NULL);
-static DEVICE_ATTR(fan2_input, S_IRUGO, show_fan_input2, NULL);
-static DEVICE_ATTR(fan1_min, S_IWUSR|S_IRUGO, show_fan_min1, set_fan_min1);
-static DEVICE_ATTR(fan2_min, S_IWUSR|S_IRUGO, show_fan_min2, set_fan_min2);
-static DEVICE_ATTR(fan1_div, S_IWUSR|S_IRUGO, show_fan_div1, set_fan_div1);
-static DEVICE_ATTR(fan2_div, S_IWUSR|S_IRUGO, show_fan_div2, set_fan_div2);
-static DEVICE_ATTR(in0_input, S_IRUGO, show_in_input0, NULL);
-static DEVICE_ATTR(in1_input, S_IRUGO, show_in_input1, NULL);
-static DEVICE_ATTR(in2_input, S_IRUGO, show_in_input2, NULL);
-static DEVICE_ATTR(in3_input, S_IRUGO, show_in_input3, NULL);
-static DEVICE_ATTR(in0_min, S_IWUSR|S_IRUGO, show_in_min0, set_in_min0);
-static DEVICE_ATTR(in1_min, S_IWUSR|S_IRUGO, show_in_min1, set_in_min1);
-static DEVICE_ATTR(in2_min, S_IWUSR|S_IRUGO, show_in_min2, set_in_min2);
-static DEVICE_ATTR(in3_min, S_IWUSR|S_IRUGO, show_in_min3, set_in_min3);
-static DEVICE_ATTR(in0_max, S_IWUSR|S_IRUGO, show_in_max0, set_in_max0);
-static DEVICE_ATTR(in1_max, S_IWUSR|S_IRUGO, show_in_max1, set_in_max1);
-static DEVICE_ATTR(in2_max, S_IWUSR|S_IRUGO, show_in_max2, set_in_max2);
-static DEVICE_ATTR(in3_max, S_IWUSR|S_IRUGO, show_in_max3, set_in_max3);
-static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
-static DEVICE_ATTR(beep_enable, S_IWUSR|S_IRUGO,
-	show_beep_enable, set_beep_enable);
-static DEVICE_ATTR(beep_mask, S_IWUSR|S_IRUGO,
-	show_beep_mask, set_beep_mask);
-
-/*
- * Real code
- */
-
-static int gl518_attach_adapter(struct i2c_adapter *adapter)
-{
-	if (!(adapter->class & I2C_CLASS_HWMON))
-		return 0;
-	return i2c_detect(adapter, &addr_data, gl518_detect);
-}
-
-static int gl518_detect(struct i2c_adapter *adapter, int address, int kind)
-{
-	int i;
-	struct i2c_client *new_client;
-	struct gl518_data *data;
-	int err = 0;
-
-	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
-				     I2C_FUNC_SMBUS_WORD_DATA))
-		goto exit;
-
-	/* OK. For now, we presume we have a valid client. We now create the
-	   client structure, even though we cannot fill it completely yet.
-	   But it allows us to access gl518_{read,write}_value. */
-
-	if (!(data = kmalloc(sizeof(struct gl518_data), GFP_KERNEL))) {
-		err = -ENOMEM;
-		goto exit;
-	}
-	memset(data, 0, sizeof(struct gl518_data));
-
-	new_client = &data->client;
-	i2c_set_clientdata(new_client, data);
-
-	new_client->addr = address;
-	new_client->adapter = adapter;
-	new_client->driver = &gl518_driver;
-	new_client->flags = 0;
-
-	/* Now, we do the remaining detection. */
-
-	if (kind < 0) {
-		if ((gl518_read_value(new_client, GL518_REG_CHIP_ID) != 0x80)
-		 || (gl518_read_value(new_client, GL518_REG_CONF) & 0x80))
-			goto exit_free;
-	}
-
-	/* Determine the chip type. */
-	if (kind <= 0) {
-		i = gl518_read_value(new_client, GL518_REG_REVISION);
-		if (i == 0x00) {
-			kind = gl518sm_r00;
-		} else if (i == 0x80) {
-			kind = gl518sm_r80;
-		} else {
-			if (kind <= 0)
-				dev_info(&adapter->dev,
-				    "Ignoring 'force' parameter for unknown "
-				    "chip at adapter %d, address 0x%02x\n",
-				    i2c_adapter_id(adapter), address);
-			goto exit_free;
-		}
-	}
-
-	/* Fill in the remaining client fields */
-	strlcpy(new_client->name, "gl518sm", I2C_NAME_SIZE);
-	data->type = kind;
-	data->valid = 0;
-	init_MUTEX(&data->update_lock);
-
-	/* Tell the I2C layer a new client has arrived */
-	if ((err = i2c_attach_client(new_client)))
-		goto exit_free;
-
-	/* Initialize the GL518SM chip */
-	data->alarm_mask = 0xff;
-	data->voltage_in[0]=data->voltage_in[1]=data->voltage_in[2]=0;
-	gl518_init_client((struct i2c_client *) new_client);
-
-	/* Register sysfs hooks */
-	device_create_file(&new_client->dev, &dev_attr_in0_input);
-	device_create_file(&new_client->dev, &dev_attr_in1_input);
-	device_create_file(&new_client->dev, &dev_attr_in2_input);
-	device_create_file(&new_client->dev, &dev_attr_in3_input);
-	device_create_file(&new_client->dev, &dev_attr_in0_min);
-	device_create_file(&new_client->dev, &dev_attr_in1_min);
-	device_create_file(&new_client->dev, &dev_attr_in2_min);
-	device_create_file(&new_client->dev, &dev_attr_in3_min);
-	device_create_file(&new_client->dev, &dev_attr_in0_max);
-	device_create_file(&new_client->dev, &dev_attr_in1_max);
-	device_create_file(&new_client->dev, &dev_attr_in2_max);
-	device_create_file(&new_client->dev, &dev_attr_in3_max);
-	device_create_file(&new_client->dev, &dev_attr_fan1_auto);
-	device_create_file(&new_client->dev, &dev_attr_fan1_input);
-	device_create_file(&new_client->dev, &dev_attr_fan2_input);
-	device_create_file(&new_client->dev, &dev_attr_fan1_min);
-	device_create_file(&new_client->dev, &dev_attr_fan2_min);
-	device_create_file(&new_client->dev, &dev_attr_fan1_div);
-	device_create_file(&new_client->dev, &dev_attr_fan2_div);
-	device_create_file(&new_client->dev, &dev_attr_temp1_input);
-	device_create_file(&new_client->dev, &dev_attr_temp1_max);
-	device_create_file(&new_client->dev, &dev_attr_temp1_max_hyst);
-	device_create_file(&new_client->dev, &dev_attr_alarms);
-	device_create_file(&new_client->dev, &dev_attr_beep_enable);
-	device_create_file(&new_client->dev, &dev_attr_beep_mask);
-
-	return 0;
-
-/* OK, this is not exactly good programming practice, usually. But it is
-   very code-efficient in this case. */
-
-exit_free:
-	kfree(data);
-exit:
-	return err;
-}
-
-
-/* Called when we have found a new GL518SM.
-   Note that we preserve D4:NoFan2 and D2:beep_enable. */
-static void gl518_init_client(struct i2c_client *client)
-{
-	/* Make sure we leave D7:Reset untouched */
-	u8 regvalue = gl518_read_value(client, GL518_REG_CONF) & 0x7f;
-
-	/* Comparator mode (D3=0), standby mode (D6=0) */
-	gl518_write_value(client, GL518_REG_CONF, (regvalue &= 0x37));
-
-	/* Never interrupts */
-	gl518_write_value(client, GL518_REG_MASK, 0x00);
-
-	/* Clear status register (D5=1), start (D6=1) */
-	gl518_write_value(client, GL518_REG_CONF, 0x20 | regvalue);
-	gl518_write_value(client, GL518_REG_CONF, 0x40 | regvalue);
-}
-
-static int gl518_detach_client(struct i2c_client *client)
-{
-	int err;
-
-	if ((err = i2c_detach_client(client))) {
-		dev_err(&client->dev, "Client deregistration failed, "
-			"client not detached.\n");
-		return err;
-	}
-
-	kfree(i2c_get_clientdata(client));
-
-	return 0;
-}
-
-/* Registers 0x07 to 0x0c are word-sized, others are byte-sized 
-   GL518 uses a high-byte first convention, which is exactly opposite to
-   the usual practice. */
-static int gl518_read_value(struct i2c_client *client, u8 reg)
-{
-	if ((reg >= 0x07) && (reg <= 0x0c))
-		return swab16(i2c_smbus_read_word_data(client, reg));
-	else
-		return i2c_smbus_read_byte_data(client, reg);
-}
-
-/* Registers 0x07 to 0x0c are word-sized, others are byte-sized 
-   GL518 uses a high-byte first convention, which is exactly opposite to
-   the usual practice. */
-static int gl518_write_value(struct i2c_client *client, u8 reg, u16 value)
-{
-	if ((reg >= 0x07) && (reg <= 0x0c))
-		return i2c_smbus_write_word_data(client, reg, swab16(value));
-	else
-		return i2c_smbus_write_byte_data(client, reg, value);
-}
-
-static struct gl518_data *gl518_update_device(struct device *dev)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct gl518_data *data = i2c_get_clientdata(client);
-	int val;
-
-	down(&data->update_lock);
-
-	if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
-	    || !data->valid) {
-		dev_dbg(&client->dev, "Starting gl518 update\n");
-
-		data->alarms = gl518_read_value(client, GL518_REG_INT);
-		data->beep_mask = gl518_read_value(client, GL518_REG_ALARM);
-
-		val = gl518_read_value(client, GL518_REG_VDD_LIMIT);
-		data->voltage_min[0] = val & 0xff;
-		data->voltage_max[0] = (val >> 8) & 0xff;
-		val = gl518_read_value(client, GL518_REG_VIN1_LIMIT);
-		data->voltage_min[1] = val & 0xff;
-		data->voltage_max[1] = (val >> 8) & 0xff;
-		val = gl518_read_value(client, GL518_REG_VIN2_LIMIT);
-		data->voltage_min[2] = val & 0xff;
-		data->voltage_max[2] = (val >> 8) & 0xff;
-		val = gl518_read_value(client, GL518_REG_VIN3_LIMIT);
-		data->voltage_min[3] = val & 0xff;
-		data->voltage_max[3] = (val >> 8) & 0xff;
-
-		val = gl518_read_value(client, GL518_REG_FAN_COUNT);
-		data->fan_in[0] = (val >> 8) & 0xff;
-		data->fan_in[1] = val & 0xff;
-
-		val = gl518_read_value(client, GL518_REG_FAN_LIMIT);
-		data->fan_min[0] = (val >> 8) & 0xff;
-		data->fan_min[1] = val & 0xff;
-
-		data->temp_in = gl518_read_value(client, GL518_REG_TEMP_IN);
-		data->temp_max =
-		    gl518_read_value(client, GL518_REG_TEMP_MAX);
-		data->temp_hyst =
-		    gl518_read_value(client, GL518_REG_TEMP_HYST);
-
-		val = gl518_read_value(client, GL518_REG_MISC);
-		data->fan_div[0] = (val >> 6) & 0x03;
-		data->fan_div[1] = (val >> 4) & 0x03;
-		data->fan_auto1  = (val >> 3) & 0x01;
-
-		data->alarms &= data->alarm_mask;
-
-		val = gl518_read_value(client, GL518_REG_CONF);
-		data->beep_enable = (val >> 2) & 1;
-
-		if (data->type != gl518sm_r00) {
-			data->voltage_in[0] =
-			    gl518_read_value(client, GL518_REG_VDD);
-			data->voltage_in[1] =
-			    gl518_read_value(client, GL518_REG_VIN1);
-			data->voltage_in[2] =
-			    gl518_read_value(client, GL518_REG_VIN2);
-		}
-		data->voltage_in[3] =
-		    gl518_read_value(client, GL518_REG_VIN3);
-
-		data->last_updated = jiffies;
-		data->valid = 1;
-	}
-
-	up(&data->update_lock);
-
-	return data;
-}
-
-static int __init sensors_gl518sm_init(void)
-{
-	return i2c_add_driver(&gl518_driver);
-}
-
-static void __exit sensors_gl518sm_exit(void)
-{
-	i2c_del_driver(&gl518_driver);
-}
-
-MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>, "
-	"Kyosti Malkki <kmalkki@cc.hut.fi> and "
-	"Hong-Gunn Chew <hglinux@gunnet.org>");
-MODULE_DESCRIPTION("GL518SM driver");
-MODULE_LICENSE("GPL");
-
-module_init(sensors_gl518sm_init);
-module_exit(sensors_gl518sm_exit);
diff --git a/drivers/i2c/chips/gl520sm.c b/drivers/i2c/chips/gl520sm.c
deleted file mode 100644
--- a/drivers/i2c/chips/gl520sm.c
+++ /dev/null
@@ -1,769 +0,0 @@
-/*
-    gl520sm.c - Part of lm_sensors, Linux kernel modules for hardware
-                monitoring
-    Copyright (c) 1998, 1999  Frodo Looijaard <frodol@dds.nl>,
-                              Kyösti Mälkki <kmalkki@cc.hut.fi>
-    Copyright (c) 2005        Maarten Deprez <maartendeprez@users.sourceforge.net>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This 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 <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-#include <linux/i2c-sensor.h>
-#include <linux/i2c-vid.h>
-
-/* Type of the extra sensor */
-static unsigned short extra_sensor_type;
-module_param(extra_sensor_type, ushort, 0);
-MODULE_PARM_DESC(extra_sensor_type, "Type of extra sensor (0=autodetect, 1=temperature, 2=voltage)");
-
-/* Addresses to scan */
-static unsigned short normal_i2c[] = { 0x2c, 0x2d, I2C_CLIENT_END };
-static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
-
-/* Insmod parameters */
-SENSORS_INSMOD_1(gl520sm);
-
-/* Many GL520 constants specified below 
-One of the inputs can be configured as either temp or voltage.
-That's why _TEMP2 and _IN4 access the same register 
-*/
-
-/* The GL520 registers */
-#define GL520_REG_CHIP_ID		0x00
-#define GL520_REG_REVISION		0x01
-#define GL520_REG_CONF			0x03
-#define GL520_REG_MASK			0x11
-
-#define GL520_REG_VID_INPUT		0x02
-
-#define GL520_REG_IN0_INPUT		0x15
-#define GL520_REG_IN0_LIMIT		0x0c
-#define GL520_REG_IN0_MIN		GL520_REG_IN0_LIMIT
-#define GL520_REG_IN0_MAX		GL520_REG_IN0_LIMIT
-
-#define GL520_REG_IN1_INPUT		0x14
-#define GL520_REG_IN1_LIMIT		0x09
-#define GL520_REG_IN1_MIN		GL520_REG_IN1_LIMIT
-#define GL520_REG_IN1_MAX		GL520_REG_IN1_LIMIT
-
-#define GL520_REG_IN2_INPUT		0x13
-#define GL520_REG_IN2_LIMIT		0x0a
-#define GL520_REG_IN2_MIN		GL520_REG_IN2_LIMIT
-#define GL520_REG_IN2_MAX		GL520_REG_IN2_LIMIT
-
-#define GL520_REG_IN3_INPUT		0x0d
-#define GL520_REG_IN3_LIMIT		0x0b
-#define GL520_REG_IN3_MIN		GL520_REG_IN3_LIMIT
-#define GL520_REG_IN3_MAX		GL520_REG_IN3_LIMIT
-
-#define GL520_REG_IN4_INPUT		0x0e
-#define GL520_REG_IN4_MAX		0x17
-#define GL520_REG_IN4_MIN		0x18
-
-#define GL520_REG_TEMP1_INPUT		0x04
-#define GL520_REG_TEMP1_MAX		0x05
-#define GL520_REG_TEMP1_MAX_HYST	0x06
-
-#define GL520_REG_TEMP2_INPUT		0x0e
-#define GL520_REG_TEMP2_MAX		0x17
-#define GL520_REG_TEMP2_MAX_HYST	0x18
-
-#define GL520_REG_FAN_INPUT		0x07
-#define GL520_REG_FAN_MIN		0x08
-#define GL520_REG_FAN_DIV		0x0f
-#define GL520_REG_FAN_OFF		GL520_REG_FAN_DIV
-
-#define GL520_REG_ALARMS		0x12
-#define GL520_REG_BEEP_MASK		0x10
-#define GL520_REG_BEEP_ENABLE		GL520_REG_CONF
-
-/*
- * Function declarations
- */
-
-static int gl520_attach_adapter(struct i2c_adapter *adapter);
-static int gl520_detect(struct i2c_adapter *adapter, int address, int kind);
-static void gl520_init_client(struct i2c_client *client);
-static int gl520_detach_client(struct i2c_client *client);
-static int gl520_read_value(struct i2c_client *client, u8 reg);
-static int gl520_write_value(struct i2c_client *client, u8 reg, u16 value);
-static struct gl520_data *gl520_update_device(struct device *dev);
-
-/* Driver data */
-static struct i2c_driver gl520_driver = {
-	.owner		= THIS_MODULE,
-	.name		= "gl520sm",
-	.id		= I2C_DRIVERID_GL520,
-	.flags		= I2C_DF_NOTIFY,
-	.attach_adapter	= gl520_attach_adapter,
-	.detach_client	= gl520_detach_client,
-};
-
-/* Client data */
-struct gl520_data {
-	struct i2c_client client;
-	struct semaphore update_lock;
-	char valid;		/* zero until the following fields are valid */
-	unsigned long last_updated;	/* in jiffies */
-
-	u8 vid;
-	u8 vrm;
-	u8 in_input[5];		/* [0] = VVD */
-	u8 in_min[5];		/* [0] = VDD */
-	u8 in_max[5];		/* [0] = VDD */
-	u8 fan_input[2];
-	u8 fan_min[2];
-	u8 fan_div[2];
-	u8 fan_off;
-	u8 temp_input[2];
-	u8 temp_max[2];
-	u8 temp_max_hyst[2];
-	u8 alarms;
-	u8 beep_enable;
-	u8 beep_mask;
-	u8 alarm_mask;
-	u8 two_temps;
-};
-
-/*
- * Sysfs stuff
- */
-
-#define sysfs_r(type, n, item, reg) \
-static ssize_t get_##type##item (struct gl520_data *, char *, int); \
-static ssize_t get_##type##n##item (struct device *, char *); \
-static ssize_t get_##type##n##item (struct device *dev, char *buf) \
-{ \
-	struct gl520_data *data = gl520_update_device(dev); \
-	return get_##type##item(data, buf, (n)); \
-}
-
-#define sysfs_w(type, n, item, reg) \
-static ssize_t set_##type##item (struct i2c_client *, struct gl520_data *, const char *, size_t, int, int); \
-static ssize_t set_##type##n##item (struct device *, const char *, size_t); \
-static ssize_t set_##type##n##item (struct device *dev, const char *buf, size_t count) \
-{ \
-	struct i2c_client *client = to_i2c_client(dev); \
-	struct gl520_data *data = i2c_get_clientdata(client); \
-	return set_##type##item(client, data, buf, count, (n), reg); \
-}
-
-#define sysfs_rw_n(type, n, item, reg) \
-sysfs_r(type, n, item, reg) \
-sysfs_w(type, n, item, reg) \
-static DEVICE_ATTR(type##n##item, S_IRUGO | S_IWUSR, get_##type##n##item, set_##type##n##item);
-
-#define sysfs_ro_n(type, n, item, reg) \
-sysfs_r(type, n, item, reg) \
-static DEVICE_ATTR(type##n##item, S_IRUGO, get_##type##n##item, NULL);
-
-#define sysfs_rw(type, item, reg) \
-sysfs_r(type, 0, item, reg) \
-sysfs_w(type, 0, item, reg) \
-static DEVICE_ATTR(type##item, S_IRUGO | S_IWUSR, get_##type##0##item, set_##type##0##item);
-
-#define sysfs_ro(type, item, reg) \
-sysfs_r(type, 0, item, reg) \
-static DEVICE_ATTR(type##item, S_IRUGO, get_##type##0##item, NULL);
-
-
-#define sysfs_vid(n) \
-sysfs_ro_n(cpu, n, _vid, GL520_REG_VID_INPUT)
-
-#define device_create_file_vid(client, n) \
-device_create_file(&client->dev, &dev_attr_cpu##n##_vid)
-
-#define sysfs_in(n) \
-sysfs_ro_n(in, n, _input, GL520_REG_IN##n##INPUT) \
-sysfs_rw_n(in, n, _min, GL520_REG_IN##n##_MIN) \
-sysfs_rw_n(in, n, _max, GL520_REG_IN##n##_MAX) \
-
-#define device_create_file_in(client, n) \
-({device_create_file(&client->dev, &dev_attr_in##n##_input); \
-device_create_file(&client->dev, &dev_attr_in##n##_min); \
-device_create_file(&client->dev, &dev_attr_in##n##_max);})
-
-#define sysfs_fan(n) \
-sysfs_ro_n(fan, n, _input, GL520_REG_FAN_INPUT) \
-sysfs_rw_n(fan, n, _min, GL520_REG_FAN_MIN) \
-sysfs_rw_n(fan, n, _div, GL520_REG_FAN_DIV)
-
-#define device_create_file_fan(client, n) \
-({device_create_file(&client->dev, &dev_attr_fan##n##_input); \
-device_create_file(&client->dev, &dev_attr_fan##n##_min); \
-device_create_file(&client->dev, &dev_attr_fan##n##_div);})
-
-#define sysfs_fan_off(n) \
-sysfs_rw_n(fan, n, _off, GL520_REG_FAN_OFF) \
-
-#define device_create_file_fan_off(client, n) \
-device_create_file(&client->dev, &dev_attr_fan##n##_off)
-
-#define sysfs_temp(n) \
-sysfs_ro_n(temp, n, _input, GL520_REG_TEMP##n##_INPUT) \
-sysfs_rw_n(temp, n, _max, GL520_REG_TEMP##n##_MAX) \
-sysfs_rw_n(temp, n, _max_hyst, GL520_REG_TEMP##n##_MAX_HYST)
-
-#define device_create_file_temp(client, n) \
-({device_create_file(&client->dev, &dev_attr_temp##n##_input); \
-device_create_file(&client->dev, &dev_attr_temp##n##_max); \
-device_create_file(&client->dev, &dev_attr_temp##n##_max_hyst);})
-
-#define sysfs_alarms() \
-sysfs_ro(alarms, , GL520_REG_ALARMS) \
-sysfs_rw(beep_enable, , GL520_REG_BEEP_ENABLE) \
-sysfs_rw(beep_mask, , GL520_REG_BEEP_MASK)
-
-#define device_create_file_alarms(client) \
-({device_create_file(&client->dev, &dev_attr_alarms); \
-device_create_file(&client->dev, &dev_attr_beep_enable); \
-device_create_file(&client->dev, &dev_attr_beep_mask);})
-
-
-sysfs_vid(0)
-
-sysfs_in(0)
-sysfs_in(1)
-sysfs_in(2)
-sysfs_in(3)
-sysfs_in(4)
-
-sysfs_fan(1)
-sysfs_fan(2)
-sysfs_fan_off(1)
-
-sysfs_temp(1)
-sysfs_temp(2)
-
-sysfs_alarms()
-
-
-static ssize_t get_cpu_vid(struct gl520_data *data, char *buf, int n)
-{
-	return sprintf(buf, "%u\n", vid_from_reg(data->vid, data->vrm));
-}
-
-#define VDD_FROM_REG(val) (((val)*95+2)/4)
-#define VDD_TO_REG(val) (SENSORS_LIMIT((((val)*4+47)/95),0,255))
-
-#define IN_FROM_REG(val) ((val)*19)
-#define IN_TO_REG(val) (SENSORS_LIMIT((((val)+9)/19),0,255))
-
-static ssize_t get_in_input(struct gl520_data *data, char *buf, int n)
-{
-	u8 r = data->in_input[n];
-
-	if (n == 0)
-		return sprintf(buf, "%d\n", VDD_FROM_REG(r));
-	else
-		return sprintf(buf, "%d\n", IN_FROM_REG(r));
-}
-
-static ssize_t get_in_min(struct gl520_data *data, char *buf, int n)
-{
-	u8 r = data->in_min[n];
-
-	if (n == 0)
-		return sprintf(buf, "%d\n", VDD_FROM_REG(r));
-	else
-		return sprintf(buf, "%d\n", IN_FROM_REG(r));
-}
-
-static ssize_t get_in_max(struct gl520_data *data, char *buf, int n)
-{
-	u8 r = data->in_max[n];
-
-	if (n == 0)
-		return sprintf(buf, "%d\n", VDD_FROM_REG(r));
-	else
-		return sprintf(buf, "%d\n", IN_FROM_REG(r));
-}
-
-static ssize_t set_in_min(struct i2c_client *client, struct gl520_data *data, const char *buf, size_t count, int n, int reg)
-{
-	long v = simple_strtol(buf, NULL, 10);
-	u8 r;
-
-	down(&data->update_lock);
-
-	if (n == 0)
-		r = VDD_TO_REG(v);
-	else
-		r = IN_TO_REG(v);
-
-	data->in_min[n] = r;
-
-	if (n < 4)
-		gl520_write_value(client, reg, (gl520_read_value(client, reg) & ~0xff) | r);
-	else
-		gl520_write_value(client, reg, r);
-
-	up(&data->update_lock);
-	return count;
-}
-
-static ssize_t set_in_max(struct i2c_client *client, struct gl520_data *data, const char *buf, size_t count, int n, int reg)
-{
-	long v = simple_strtol(buf, NULL, 10);
-	u8 r;
-
-	if (n == 0)
-		r = VDD_TO_REG(v);
-	else
-		r = IN_TO_REG(v);
-
-	down(&data->update_lock);
-
-	data->in_max[n] = r;
-
-	if (n < 4)
-		gl520_write_value(client, reg, (gl520_read_value(client, reg) & ~0xff00) | (r << 8));
-	else
-		gl520_write_value(client, reg, r);
-
-	up(&data->update_lock);
-	return count;
-}
-
-#define DIV_FROM_REG(val) (1 << (val))
-#define FAN_FROM_REG(val,div) ((val)==0 ? 0 : (480000/((val) << (div))))
-#define FAN_TO_REG(val,div) ((val)<=0?0:SENSORS_LIMIT((480000 + ((val) << ((div)-1))) / ((val) << (div)), 1, 255));
-
-static ssize_t get_fan_input(struct gl520_data *data, char *buf, int n)
-{
-	return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan_input[n - 1], data->fan_div[n - 1]));
-}
-
-static ssize_t get_fan_min(struct gl520_data *data, char *buf, int n)
-{
-	return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan_min[n - 1], data->fan_div[n - 1]));
-}
-
-static ssize_t get_fan_div(struct gl520_data *data, char *buf, int n)
-{
-	return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[n - 1]));
-}
-
-static ssize_t get_fan_off(struct gl520_data *data, char *buf, int n)
-{
-	return sprintf(buf, "%d\n", data->fan_off);
-}
-
-static ssize_t set_fan_min(struct i2c_client *client, struct gl520_data *data, const char *buf, size_t count, int n, int reg)
-{
-	unsigned long v = simple_strtoul(buf, NULL, 10);
-	u8 r;
-
-	down(&data->update_lock);
-	r = FAN_TO_REG(v, data->fan_div[n - 1]);
-	data->fan_min[n - 1] = r;
-
-	if (n == 1)
-		gl520_write_value(client, reg, (gl520_read_value(client, reg) & ~0xff00) | (r << 8));
-	else
-		gl520_write_value(client, reg, (gl520_read_value(client, reg) & ~0xff) | r);
-
-	data->beep_mask = gl520_read_value(client, GL520_REG_BEEP_MASK);
-	if (data->fan_min[n - 1] == 0)
-		data->alarm_mask &= (n == 1) ? ~0x20 : ~0x40;
-	else
-		data->alarm_mask |= (n == 1) ? 0x20 : 0x40;
-	data->beep_mask &= data->alarm_mask;
-	gl520_write_value(client, GL520_REG_BEEP_MASK, data->beep_mask);
-
-	up(&data->update_lock);
-	return count;
-}
-
-static ssize_t set_fan_div(struct i2c_client *client, struct gl520_data *data, const char *buf, size_t count, int n, int reg)
-{
-	unsigned long v = simple_strtoul(buf, NULL, 10);
-	u8 r;
-
-	switch (v) {
-	case 1: r = 0; break;
-	case 2: r = 1; break;
-	case 4: r = 2; break;
-	case 8: r = 3; break;
-	default:
-		dev_err(&client->dev, "fan_div value %ld not supported. Choose one of 1, 2, 4 or 8!\n", v);
-		return -EINVAL;
-	}
-
-	down(&data->update_lock);
-	data->fan_div[n - 1] = r;
-
-	if (n == 1)
-		gl520_write_value(client, reg, (gl520_read_value(client, reg) & ~0xc0) | (r << 6));
-	else
-		gl520_write_value(client, reg, (gl520_read_value(client, reg) & ~0x30) | (r << 4));
-
-	up(&data->update_lock);
-	return count;
-}
-
-static ssize_t set_fan_off(struct i2c_client *client, struct gl520_data *data, const char *buf, size_t count, int n, int reg)
-{
-	u8 r = simple_strtoul(buf, NULL, 10)?1:0;
-
-	down(&data->update_lock);
-	data->fan_off = r;
-	gl520_write_value(client, reg, (gl520_read_value(client, reg) & ~0x0c) | (r << 2));
-	up(&data->update_lock);
-	return count;
-}
-
-#define TEMP_FROM_REG(val) (((val) - 130) * 1000)
-#define TEMP_TO_REG(val) (SENSORS_LIMIT(((((val)<0?(val)-500:(val)+500) / 1000)+130),0,255))
-
-static ssize_t get_temp_input(struct gl520_data *data, char *buf, int n)
-{
-	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_input[n - 1]));
-}
-
-static ssize_t get_temp_max(struct gl520_data *data, char *buf, int n)
-{
-	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_max[n - 1]));
-}
-
-static ssize_t get_temp_max_hyst(struct gl520_data *data, char *buf, int n)
-{
-	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_max_hyst[n - 1]));
-}
-
-static ssize_t set_temp_max(struct i2c_client *client, struct gl520_data *data, const char *buf, size_t count, int n, int reg)
-{
-	long v = simple_strtol(buf, NULL, 10);
-
-	down(&data->update_lock);
-	data->temp_max[n - 1] = TEMP_TO_REG(v);;
-	gl520_write_value(client, reg, data->temp_max[n - 1]);
-	up(&data->update_lock);
-	return count;
-}
-
-static ssize_t set_temp_max_hyst(struct i2c_client *client, struct gl520_data *data, const char *buf, size_t count, int n, int reg)
-{
-	long v = simple_strtol(buf, NULL, 10);
-
-	down(&data->update_lock);
-	data->temp_max_hyst[n - 1] = TEMP_TO_REG(v);
-	gl520_write_value(client, reg, data->temp_max_hyst[n - 1]);
-	up(&data->update_lock);
-	return count;
-}
-
-static ssize_t get_alarms(struct gl520_data *data, char *buf, int n)
-{
-	return sprintf(buf, "%d\n", data->alarms);
-}
-
-static ssize_t get_beep_enable(struct gl520_data *data, char *buf, int n)
-{
-	return sprintf(buf, "%d\n", data->beep_enable);
-}
-
-static ssize_t get_beep_mask(struct gl520_data *data, char *buf, int n)
-{
-	return sprintf(buf, "%d\n", data->beep_mask);
-}
-
-static ssize_t set_beep_enable(struct i2c_client *client, struct gl520_data *data, const char *buf, size_t count, int n, int reg)
-{
-	u8 r = simple_strtoul(buf, NULL, 10)?0:1;
-
-	down(&data->update_lock);
-	data->beep_enable = !r;
-	gl520_write_value(client, reg, (gl520_read_value(client, reg) & ~0x04) | (r << 2));
-	up(&data->update_lock);
-	return count;
-}
-
-static ssize_t set_beep_mask(struct i2c_client *client, struct gl520_data *data, const char *buf, size_t count, int n, int reg)
-{
-	u8 r = simple_strtoul(buf, NULL, 10);
-	
-	down(&data->update_lock);
-	r &= data->alarm_mask;
-	data->beep_mask = r;
-	gl520_write_value(client, reg, r);
-	up(&data->update_lock);
-	return count;
-}
-
-
-/*
- * Real code
- */
-
-static int gl520_attach_adapter(struct i2c_adapter *adapter)
-{
-	if (!(adapter->class & I2C_CLASS_HWMON))
-		return 0;
-	return i2c_detect(adapter, &addr_data, gl520_detect);
-}
-
-static int gl520_detect(struct i2c_adapter *adapter, int address, int kind)
-{
-	struct i2c_client *new_client;
-	struct gl520_data *data;
-	int err = 0;
-
-	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
-				     I2C_FUNC_SMBUS_WORD_DATA))
-		goto exit;
-
-	/* OK. For now, we presume we have a valid client. We now create the
-	   client structure, even though we cannot fill it completely yet.
-	   But it allows us to access gl520_{read,write}_value. */
-
-	if (!(data = kmalloc(sizeof(struct gl520_data), GFP_KERNEL))) {
-		err = -ENOMEM;
-		goto exit;
-	}
-	memset(data, 0, sizeof(struct gl520_data));
-
-	new_client = &data->client;
-	i2c_set_clientdata(new_client, data);
-	new_client->addr = address;
-	new_client->adapter = adapter;
-	new_client->driver = &gl520_driver;
-	new_client->flags = 0;
-
-	/* Determine the chip type. */
-	if (kind < 0) {
-		if ((gl520_read_value(new_client, GL520_REG_CHIP_ID) != 0x20) ||
-		    ((gl520_read_value(new_client, GL520_REG_REVISION) & 0x7f) != 0x00) ||
-		    ((gl520_read_value(new_client, GL520_REG_CONF) & 0x80) != 0x00)) {
-			dev_dbg(&new_client->dev, "Unknown chip type, skipping\n");
-			goto exit_free;
-		}
-	}
-
-	/* Fill in the remaining client fields */
-	strlcpy(new_client->name, "gl520sm", I2C_NAME_SIZE);
-	data->valid = 0;
-	init_MUTEX(&data->update_lock);
-
-	/* Tell the I2C layer a new client has arrived */
-	if ((err = i2c_attach_client(new_client)))
-		goto exit_free;
-
-	/* Initialize the GL520SM chip */
-	gl520_init_client(new_client);
-
-	/* Register sysfs hooks */
-	device_create_file_vid(new_client, 0);
-
-	device_create_file_in(new_client, 0);
-	device_create_file_in(new_client, 1);
-	device_create_file_in(new_client, 2);
-	device_create_file_in(new_client, 3);
-	if (!data->two_temps)
-		device_create_file_in(new_client, 4);
-
-	device_create_file_fan(new_client, 1);
-	device_create_file_fan(new_client, 2);
-	device_create_file_fan_off(new_client, 1);
-
-	device_create_file_temp(new_client, 1);
-	if (data->two_temps)
-		device_create_file_temp(new_client, 2);
-
-	device_create_file_alarms(new_client);
-
-	return 0;
-
-exit_free:
-	kfree(data);
-exit:
-	return err;
-}
-
-
-/* Called when we have found a new GL520SM. */
-static void gl520_init_client(struct i2c_client *client)
-{
-	struct gl520_data *data = i2c_get_clientdata(client);
-	u8 oldconf, conf;
-
-	conf = oldconf = gl520_read_value(client, GL520_REG_CONF);
-
-	data->alarm_mask = 0xff;
-	data->vrm = i2c_which_vrm();
-
-	if (extra_sensor_type == 1)
-		conf &= ~0x10;
-	else if (extra_sensor_type == 2)
-		conf |= 0x10;
-	data->two_temps = !(conf & 0x10);
-
-	/* If IRQ# is disabled, we can safely force comparator mode */
-	if (!(conf & 0x20))
-		conf &= 0xf7;
-
-	/* Enable monitoring if needed */
-	conf |= 0x40;
-
-	if (conf != oldconf)
-		gl520_write_value(client, GL520_REG_CONF, conf);
-
-	gl520_update_device(&(client->dev));
-
-	if (data->fan_min[0] == 0)
-		data->alarm_mask &= ~0x20;
-	if (data->fan_min[1] == 0)
-		data->alarm_mask &= ~0x40;
-
-	data->beep_mask &= data->alarm_mask;
-	gl520_write_value(client, GL520_REG_BEEP_MASK, data->beep_mask);
-}
-
-static int gl520_detach_client(struct i2c_client *client)
-{
-	int err;
-
-	if ((err = i2c_detach_client(client))) {
-		dev_err(&client->dev, "Client deregistration failed, "
-			"client not detached.\n");
-		return err;
-	}
-
-	kfree(i2c_get_clientdata(client));
-	return 0;
-}
-
-
-/* Registers 0x07 to 0x0c are word-sized, others are byte-sized 
-   GL520 uses a high-byte first convention */
-static int gl520_read_value(struct i2c_client *client, u8 reg)
-{
-	if ((reg >= 0x07) && (reg <= 0x0c))
-		return swab16(i2c_smbus_read_word_data(client, reg));
-	else
-		return i2c_smbus_read_byte_data(client, reg);
-}
-
-static int gl520_write_value(struct i2c_client *client, u8 reg, u16 value)
-{
-	if ((reg >= 0x07) && (reg <= 0x0c))
-		return i2c_smbus_write_word_data(client, reg, swab16(value));
-	else
-		return i2c_smbus_write_byte_data(client, reg, value);
-}
-
-
-static struct gl520_data *gl520_update_device(struct device *dev)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct gl520_data *data = i2c_get_clientdata(client);
-	int val;
-
-	down(&data->update_lock);
-
-	if ((jiffies - data->last_updated > 2 * HZ) ||
-	    (jiffies < data->last_updated) || !data->valid) {
-
-		dev_dbg(&client->dev, "Starting gl520sm update\n");
-
-		data->alarms = gl520_read_value(client, GL520_REG_ALARMS);
-		data->beep_mask = gl520_read_value(client, GL520_REG_BEEP_MASK);
-		data->vid = gl520_read_value(client, GL520_REG_VID_INPUT) & 0x1f;
-
-		val = gl520_read_value(client, GL520_REG_IN0_LIMIT);
-		data->in_min[0] = val & 0xff;
-		data->in_max[0] = (val >> 8) & 0xff;
-		val = gl520_read_value(client, GL520_REG_IN1_LIMIT);
-		data->in_min[1] = val & 0xff;
-		data->in_max[1] = (val >> 8) & 0xff;
-		val = gl520_read_value(client, GL520_REG_IN2_LIMIT);
-		data->in_min[2] = val & 0xff;
-		data->in_max[2] = (val >> 8) & 0xff;
-		val = gl520_read_value(client, GL520_REG_IN3_LIMIT);
-		data->in_min[3] = val & 0xff;
-		data->in_max[3] = (val >> 8) & 0xff;
-
-		val = gl520_read_value(client, GL520_REG_FAN_INPUT);
-		data->fan_input[0] = (val >> 8) & 0xff;
-		data->fan_input[1] = val & 0xff;
-
-		val = gl520_read_value(client, GL520_REG_FAN_MIN);
-		data->fan_min[0] = (val >> 8) & 0xff;
-		data->fan_min[1] = val & 0xff;
-
-		data->temp_input[0] = gl520_read_value(client, GL520_REG_TEMP1_INPUT);
-		data->temp_max[0] = gl520_read_value(client, GL520_REG_TEMP1_MAX);
-		data->temp_max_hyst[0] = gl520_read_value(client, GL520_REG_TEMP1_MAX_HYST);
-
-		val = gl520_read_value(client, GL520_REG_FAN_DIV);
-		data->fan_div[0] = (val >> 6) & 0x03;
-		data->fan_div[1] = (val >> 4) & 0x03;
-		data->fan_off = (val >> 2) & 0x01;
-
-		data->alarms &= data->alarm_mask;
-
-		val = gl520_read_value(client, GL520_REG_CONF);
-		data->beep_enable = !((val >> 2) & 1);
-
-		data->in_input[0] = gl520_read_value(client, GL520_REG_IN0_INPUT);
-		data->in_input[1] = gl520_read_value(client, GL520_REG_IN1_INPUT);
-		data->in_input[2] = gl520_read_value(client, GL520_REG_IN2_INPUT);
-		data->in_input[3] = gl520_read_value(client, GL520_REG_IN3_INPUT);
-
-		/* Temp1 and Vin4 are the same input */
-		if (data->two_temps) {
-			data->temp_input[1] = gl520_read_value(client, GL520_REG_TEMP2_INPUT);
-			data->temp_max[1] = gl520_read_value(client, GL520_REG_TEMP2_MAX);
-			data->temp_max_hyst[1] = gl520_read_value(client, GL520_REG_TEMP2_MAX_HYST);
-		} else {
-			data->in_input[4] = gl520_read_value(client, GL520_REG_IN4_INPUT);
-			data->in_min[4] = gl520_read_value(client, GL520_REG_IN4_MIN);
-			data->in_max[4] = gl520_read_value(client, GL520_REG_IN4_MAX);
-		}
-
-		data->last_updated = jiffies;
-		data->valid = 1;
-	}
-
-	up(&data->update_lock);
-
-	return data;
-}
-
-
-static int __init sensors_gl520sm_init(void)
-{
-	return i2c_add_driver(&gl520_driver);
-}
-
-static void __exit sensors_gl520sm_exit(void)
-{
-	i2c_del_driver(&gl520_driver);
-}
-
-
-MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>, "
-	"Kyösti Mälkki <kmalkki@cc.hut.fi>, "
-	"Maarten Deprez <maartendeprez@users.sourceforge.net>");
-MODULE_DESCRIPTION("GL520SM driver");
-MODULE_LICENSE("GPL");
-
-module_init(sensors_gl520sm_init);
-module_exit(sensors_gl520sm_exit);
diff --git a/drivers/i2c/chips/isp1301_omap.c b/drivers/i2c/chips/isp1301_omap.c
--- a/drivers/i2c/chips/isp1301_omap.c
+++ b/drivers/i2c/chips/isp1301_omap.c
@@ -145,7 +145,6 @@ static inline void notresponding(struct 
 static unsigned short normal_i2c[] = {
 	ISP_BASE, ISP_BASE + 1,
 	I2C_CLIENT_END };
-static unsigned short normal_i2c_range[] = { I2C_CLIENT_END };
 
 I2C_CLIENT_INSMOD;
 
diff --git a/drivers/i2c/chips/it87.c b/drivers/i2c/chips/it87.c
deleted file mode 100644
--- a/drivers/i2c/chips/it87.c
+++ /dev/null
@@ -1,1208 +0,0 @@
-/*
-    it87.c - Part of lm_sensors, Linux kernel modules for hardware
-             monitoring.
-
-    Supports: IT8705F  Super I/O chip w/LPC interface & SMBus
-              IT8712F  Super I/O chip w/LPC interface & SMBus
-              Sis950   A clone of the IT8705F
-
-    Copyright (C) 2001 Chris Gauthron <chrisg@0-in.com> 
-    Largely inspired by lm78.c of the same package
-
-    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.
-*/
-
-/*
-    djg@pdp8.net David Gesswein 7/18/01
-    Modified to fix bug with not all alarms enabled.
-    Added ability to read battery voltage and select temperature sensor
-    type at module load time.
-*/
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/jiffies.h>
-#include <linux/i2c.h>
-#include <linux/i2c-sensor.h>
-#include <linux/i2c-vid.h>
-#include <asm/io.h>
-
-
-/* Addresses to scan */
-static unsigned short normal_i2c[] = { 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d,
-					0x2e, 0x2f, I2C_CLIENT_END };
-static unsigned int normal_isa[] = { 0x0290, I2C_CLIENT_ISA_END };
-
-/* Insmod parameters */
-SENSORS_INSMOD_2(it87, it8712);
-
-#define	REG	0x2e	/* The register to read/write */
-#define	DEV	0x07	/* Register: Logical device select */
-#define	VAL	0x2f	/* The value to read/write */
-#define PME	0x04	/* The device with the fan registers in it */
-#define	DEVID	0x20	/* Register: Device ID */
-#define	DEVREV	0x22	/* Register: Device Revision */
-
-static inline int
-superio_inb(int reg)
-{
-	outb(reg, REG);
-	return inb(VAL);
-}
-
-static int superio_inw(int reg)
-{
-	int val;
-	outb(reg++, REG);
-	val = inb(VAL) << 8;
-	outb(reg, REG);
-	val |= inb(VAL);
-	return val;
-}
-
-static inline void
-superio_select(void)
-{
-	outb(DEV, REG);
-	outb(PME, VAL);
-}
-
-static inline void
-superio_enter(void)
-{
-	outb(0x87, REG);
-	outb(0x01, REG);
-	outb(0x55, REG);
-	outb(0x55, REG);
-}
-
-static inline void
-superio_exit(void)
-{
-	outb(0x02, REG);
-	outb(0x02, VAL);
-}
-
-#define IT8712F_DEVID 0x8712
-#define IT8705F_DEVID 0x8705
-#define IT87_ACT_REG  0x30
-#define IT87_BASE_REG 0x60
-
-/* Update battery voltage after every reading if true */
-static int update_vbat;
-
-/* Not all BIOSes properly configure the PWM registers */
-static int fix_pwm_polarity;
-
-/* Chip Type */
-
-static u16 chip_type;
-
-/* Many IT87 constants specified below */
-
-/* Length of ISA address segment */
-#define IT87_EXTENT 8
-
-/* Where are the ISA address/data registers relative to the base address */
-#define IT87_ADDR_REG_OFFSET 5
-#define IT87_DATA_REG_OFFSET 6
-
-/*----- The IT87 registers -----*/
-
-#define IT87_REG_CONFIG        0x00
-
-#define IT87_REG_ALARM1        0x01
-#define IT87_REG_ALARM2        0x02
-#define IT87_REG_ALARM3        0x03
-
-#define IT87_REG_VID           0x0a
-#define IT87_REG_FAN_DIV       0x0b
-
-/* Monitors: 9 voltage (0 to 7, battery), 3 temp (1 to 3), 3 fan (1 to 3) */
-
-#define IT87_REG_FAN(nr)       (0x0d + (nr))
-#define IT87_REG_FAN_MIN(nr)   (0x10 + (nr))
-#define IT87_REG_FAN_MAIN_CTRL 0x13
-#define IT87_REG_FAN_CTL       0x14
-#define IT87_REG_PWM(nr)       (0x15 + (nr))
-
-#define IT87_REG_VIN(nr)       (0x20 + (nr))
-#define IT87_REG_TEMP(nr)      (0x29 + (nr))
-
-#define IT87_REG_VIN_MAX(nr)   (0x30 + (nr) * 2)
-#define IT87_REG_VIN_MIN(nr)   (0x31 + (nr) * 2)
-#define IT87_REG_TEMP_HIGH(nr) (0x40 + (nr) * 2)
-#define IT87_REG_TEMP_LOW(nr)  (0x41 + (nr) * 2)
-
-#define IT87_REG_I2C_ADDR      0x48
-
-#define IT87_REG_VIN_ENABLE    0x50
-#define IT87_REG_TEMP_ENABLE   0x51
-
-#define IT87_REG_CHIPID        0x58
-
-#define IN_TO_REG(val)  (SENSORS_LIMIT((((val) + 8)/16),0,255))
-#define IN_FROM_REG(val) ((val) * 16)
-
-static inline u8 FAN_TO_REG(long rpm, int div)
-{
-	if (rpm == 0)
-		return 255;
-	rpm = SENSORS_LIMIT(rpm, 1, 1000000);
-	return SENSORS_LIMIT((1350000 + rpm * div / 2) / (rpm * div), 1,
-			     254);
-}
-
-#define FAN_FROM_REG(val,div) ((val)==0?-1:(val)==255?0:1350000/((val)*(div)))
-
-#define TEMP_TO_REG(val) (SENSORS_LIMIT(((val)<0?(((val)-500)/1000):\
-					((val)+500)/1000),-128,127))
-#define TEMP_FROM_REG(val) (((val)>0x80?(val)-0x100:(val))*1000)
-
-#define ALARMS_FROM_REG(val) (val)
-
-#define PWM_TO_REG(val)   ((val) >> 1)
-#define PWM_FROM_REG(val) (((val)&0x7f) << 1)
-
-static int DIV_TO_REG(int val)
-{
-	int answer = 0;
-	while ((val >>= 1) != 0)
-		answer++;
-	return answer;
-}
-#define DIV_FROM_REG(val) (1 << (val))
-
-
-/* For each registered IT87, we need to keep some data in memory. That
-   data is pointed to by it87_list[NR]->data. The structure itself is
-   dynamically allocated, at the same time when a new it87 client is
-   allocated. */
-struct it87_data {
-	struct i2c_client client;
-	struct semaphore lock;
-	enum chips type;
-
-	struct semaphore update_lock;
-	char valid;		/* !=0 if following fields are valid */
-	unsigned long last_updated;	/* In jiffies */
-
-	u8 in[9];		/* Register value */
-	u8 in_max[9];		/* Register value */
-	u8 in_min[9];		/* Register value */
-	u8 fan[3];		/* Register value */
-	u8 fan_min[3];		/* Register value */
-	u8 temp[3];		/* Register value */
-	u8 temp_high[3];	/* Register value */
-	u8 temp_low[3];		/* Register value */
-	u8 sensor;		/* Register value */
-	u8 fan_div[3];		/* Register encoding, shifted right */
-	u8 vid;			/* Register encoding, combined */
-	int vrm;
-	u32 alarms;		/* Register encoding, combined */
-	u8 fan_main_ctrl;	/* Register value */
-	u8 manual_pwm_ctl[3];   /* manual PWM value set by user */
-};
-
-
-static int it87_attach_adapter(struct i2c_adapter *adapter);
-static int it87_find(int *address);
-static int it87_detect(struct i2c_adapter *adapter, int address, int kind);
-static int it87_detach_client(struct i2c_client *client);
-
-static int it87_read_value(struct i2c_client *client, u8 register);
-static int it87_write_value(struct i2c_client *client, u8 register,
-			u8 value);
-static struct it87_data *it87_update_device(struct device *dev);
-static int it87_check_pwm(struct i2c_client *client);
-static void it87_init_client(struct i2c_client *client, struct it87_data *data);
-
-
-static struct i2c_driver it87_driver = {
-	.owner		= THIS_MODULE,
-	.name		= "it87",
-	.id		= I2C_DRIVERID_IT87,
-	.flags		= I2C_DF_NOTIFY,
-	.attach_adapter	= it87_attach_adapter,
-	.detach_client	= it87_detach_client,
-};
-
-static ssize_t show_in(struct device *dev, char *buf, int nr)
-{
-	struct it87_data *data = it87_update_device(dev);
-	return sprintf(buf, "%d\n", IN_FROM_REG(data->in[nr]));
-}
-
-static ssize_t show_in_min(struct device *dev, char *buf, int nr)
-{
-	struct it87_data *data = it87_update_device(dev);
-	return sprintf(buf, "%d\n", IN_FROM_REG(data->in_min[nr]));
-}
-
-static ssize_t show_in_max(struct device *dev, char *buf, int nr)
-{
-	struct it87_data *data = it87_update_device(dev);
-	return sprintf(buf, "%d\n", IN_FROM_REG(data->in_max[nr]));
-}
-
-static ssize_t set_in_min(struct device *dev, const char *buf, 
-		size_t count, int nr)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct it87_data *data = i2c_get_clientdata(client);
-	unsigned long val = simple_strtoul(buf, NULL, 10);
-
-	down(&data->update_lock);
-	data->in_min[nr] = IN_TO_REG(val);
-	it87_write_value(client, IT87_REG_VIN_MIN(nr), 
-			data->in_min[nr]);
-	up(&data->update_lock);
-	return count;
-}
-static ssize_t set_in_max(struct device *dev, const char *buf, 
-		size_t count, int nr)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct it87_data *data = i2c_get_clientdata(client);
-	unsigned long val = simple_strtoul(buf, NULL, 10);
-
-	down(&data->update_lock);
-	data->in_max[nr] = IN_TO_REG(val);
-	it87_write_value(client, IT87_REG_VIN_MAX(nr), 
-			data->in_max[nr]);
-	up(&data->update_lock);
-	return count;
-}
-
-#define show_in_offset(offset)					\
-static ssize_t							\
-	show_in##offset (struct device *dev, char *buf)		\
-{								\
-	return show_in(dev, buf, offset);			\
-}								\
-static DEVICE_ATTR(in##offset##_input, S_IRUGO, show_in##offset, NULL);
-
-#define limit_in_offset(offset)					\
-static ssize_t							\
-	show_in##offset##_min (struct device *dev, char *buf)	\
-{								\
-	return show_in_min(dev, buf, offset);			\
-}								\
-static ssize_t							\
-	show_in##offset##_max (struct device *dev, char *buf)	\
-{								\
-	return show_in_max(dev, buf, offset);			\
-}								\
-static ssize_t set_in##offset##_min (struct device *dev, 	\
-		const char *buf, size_t count) 			\
-{								\
-	return set_in_min(dev, buf, count, offset);		\
-}								\
-static ssize_t set_in##offset##_max (struct device *dev,	\
-			const char *buf, size_t count)		\
-{								\
-	return set_in_max(dev, buf, count, offset);		\
-}								\
-static DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, 	\
-		show_in##offset##_min, set_in##offset##_min);	\
-static DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, 	\
-		show_in##offset##_max, set_in##offset##_max);
-
-show_in_offset(0);
-limit_in_offset(0);
-show_in_offset(1);
-limit_in_offset(1);
-show_in_offset(2);
-limit_in_offset(2);
-show_in_offset(3);
-limit_in_offset(3);
-show_in_offset(4);
-limit_in_offset(4);
-show_in_offset(5);
-limit_in_offset(5);
-show_in_offset(6);
-limit_in_offset(6);
-show_in_offset(7);
-limit_in_offset(7);
-show_in_offset(8);
-
-/* 3 temperatures */
-static ssize_t show_temp(struct device *dev, char *buf, int nr)
-{
-	struct it87_data *data = it87_update_device(dev);
-	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp[nr]));
-}
-static ssize_t show_temp_max(struct device *dev, char *buf, int nr)
-{
-	struct it87_data *data = it87_update_device(dev);
-	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_high[nr]));
-}
-static ssize_t show_temp_min(struct device *dev, char *buf, int nr)
-{
-	struct it87_data *data = it87_update_device(dev);
-	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_low[nr]));
-}
-static ssize_t set_temp_max(struct device *dev, const char *buf, 
-		size_t count, int nr)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct it87_data *data = i2c_get_clientdata(client);
-	int val = simple_strtol(buf, NULL, 10);
-
-	down(&data->update_lock);
-	data->temp_high[nr] = TEMP_TO_REG(val);
-	it87_write_value(client, IT87_REG_TEMP_HIGH(nr), data->temp_high[nr]);
-	up(&data->update_lock);
-	return count;
-}
-static ssize_t set_temp_min(struct device *dev, const char *buf, 
-		size_t count, int nr)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct it87_data *data = i2c_get_clientdata(client);
-	int val = simple_strtol(buf, NULL, 10);
-
-	down(&data->update_lock);
-	data->temp_low[nr] = TEMP_TO_REG(val);
-	it87_write_value(client, IT87_REG_TEMP_LOW(nr), data->temp_low[nr]);
-	up(&data->update_lock);
-	return count;
-}
-#define show_temp_offset(offset)					\
-static ssize_t show_temp_##offset (struct device *dev, char *buf)	\
-{									\
-	return show_temp(dev, buf, offset - 1);				\
-}									\
-static ssize_t								\
-show_temp_##offset##_max (struct device *dev, char *buf)		\
-{									\
-	return show_temp_max(dev, buf, offset - 1);			\
-}									\
-static ssize_t								\
-show_temp_##offset##_min (struct device *dev, char *buf)		\
-{									\
-	return show_temp_min(dev, buf, offset - 1);			\
-}									\
-static ssize_t set_temp_##offset##_max (struct device *dev, 		\
-		const char *buf, size_t count) 				\
-{									\
-	return set_temp_max(dev, buf, count, offset - 1);		\
-}									\
-static ssize_t set_temp_##offset##_min (struct device *dev, 		\
-		const char *buf, size_t count) 				\
-{									\
-	return set_temp_min(dev, buf, count, offset - 1);		\
-}									\
-static DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_temp_##offset, NULL); \
-static DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR, 		\
-		show_temp_##offset##_max, set_temp_##offset##_max); 	\
-static DEVICE_ATTR(temp##offset##_min, S_IRUGO | S_IWUSR, 		\
-		show_temp_##offset##_min, set_temp_##offset##_min);	
-
-show_temp_offset(1);
-show_temp_offset(2);
-show_temp_offset(3);
-
-static ssize_t show_sensor(struct device *dev, char *buf, int nr)
-{
-	struct it87_data *data = it87_update_device(dev);
-	u8 reg = data->sensor; /* In case the value is updated while we use it */
-	
-	if (reg & (1 << nr))
-		return sprintf(buf, "3\n");  /* thermal diode */
-	if (reg & (8 << nr))
-		return sprintf(buf, "2\n");  /* thermistor */
-	return sprintf(buf, "0\n");      /* disabled */
-}
-static ssize_t set_sensor(struct device *dev, const char *buf, 
-		size_t count, int nr)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct it87_data *data = i2c_get_clientdata(client);
-	int val = simple_strtol(buf, NULL, 10);
-
-	down(&data->update_lock);
-
-	data->sensor &= ~(1 << nr);
-	data->sensor &= ~(8 << nr);
-	/* 3 = thermal diode; 2 = thermistor; 0 = disabled */
-	if (val == 3)
-	    data->sensor |= 1 << nr;
-	else if (val == 2)
-	    data->sensor |= 8 << nr;
-	else if (val != 0) {
-		up(&data->update_lock);
-		return -EINVAL;
-	}
-	it87_write_value(client, IT87_REG_TEMP_ENABLE, data->sensor);
-	up(&data->update_lock);
-	return count;
-}
-#define show_sensor_offset(offset)					\
-static ssize_t show_sensor_##offset (struct device *dev, char *buf)	\
-{									\
-	return show_sensor(dev, buf, offset - 1);			\
-}									\
-static ssize_t set_sensor_##offset (struct device *dev, 		\
-		const char *buf, size_t count) 				\
-{									\
-	return set_sensor(dev, buf, count, offset - 1);			\
-}									\
-static DEVICE_ATTR(temp##offset##_type, S_IRUGO | S_IWUSR, 		\
-		show_sensor_##offset, set_sensor_##offset);
-
-show_sensor_offset(1);
-show_sensor_offset(2);
-show_sensor_offset(3);
-
-/* 3 Fans */
-static ssize_t show_fan(struct device *dev, char *buf, int nr)
-{
-	struct it87_data *data = it87_update_device(dev);
-	return sprintf(buf,"%d\n", FAN_FROM_REG(data->fan[nr], 
-				DIV_FROM_REG(data->fan_div[nr])));
-}
-static ssize_t show_fan_min(struct device *dev, char *buf, int nr)
-{
-	struct it87_data *data = it87_update_device(dev);
-	return sprintf(buf,"%d\n",
-		FAN_FROM_REG(data->fan_min[nr], DIV_FROM_REG(data->fan_div[nr])));
-}
-static ssize_t show_fan_div(struct device *dev, char *buf, int nr)
-{
-	struct it87_data *data = it87_update_device(dev);
-	return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[nr]));
-}
-static ssize_t show_pwm_enable(struct device *dev, char *buf, int nr)
-{
-	struct it87_data *data = it87_update_device(dev);
-	return sprintf(buf,"%d\n", (data->fan_main_ctrl & (1 << nr)) ? 1 : 0);
-}
-static ssize_t show_pwm(struct device *dev, char *buf, int nr)
-{
-	struct it87_data *data = it87_update_device(dev);
-	return sprintf(buf,"%d\n", data->manual_pwm_ctl[nr]);
-}
-static ssize_t set_fan_min(struct device *dev, const char *buf, 
-		size_t count, int nr)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct it87_data *data = i2c_get_clientdata(client);
-	int val = simple_strtol(buf, NULL, 10);
-
-	down(&data->update_lock);
-	data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr]));
-	it87_write_value(client, IT87_REG_FAN_MIN(nr), data->fan_min[nr]);
-	up(&data->update_lock);
-	return count;
-}
-static ssize_t set_fan_div(struct device *dev, const char *buf, 
-		size_t count, int nr)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct it87_data *data = i2c_get_clientdata(client);
-	int val = simple_strtol(buf, NULL, 10);
-	int i, min[3];
-	u8 old;
-
-	down(&data->update_lock);
-	old = it87_read_value(client, IT87_REG_FAN_DIV);
-
-	for (i = 0; i < 3; i++)
-		min[i] = FAN_FROM_REG(data->fan_min[i], DIV_FROM_REG(data->fan_div[i]));
-
-	switch (nr) {
-	case 0:
-	case 1:
-		data->fan_div[nr] = DIV_TO_REG(val);
-		break;
-	case 2:
-		if (val < 8)
-			data->fan_div[nr] = 1;
-		else
-			data->fan_div[nr] = 3;
-	}
-	val = old & 0x80;
-	val |= (data->fan_div[0] & 0x07);
-	val |= (data->fan_div[1] & 0x07) << 3;
-	if (data->fan_div[2] == 3)
-		val |= 0x1 << 6;
-	it87_write_value(client, IT87_REG_FAN_DIV, val);
-
-	for (i = 0; i < 3; i++) {
-		data->fan_min[i]=FAN_TO_REG(min[i], DIV_FROM_REG(data->fan_div[i]));
-		it87_write_value(client, IT87_REG_FAN_MIN(i), data->fan_min[i]);
-	}
-	up(&data->update_lock);
-	return count;
-}
-static ssize_t set_pwm_enable(struct device *dev, const char *buf,
-		size_t count, int nr)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct it87_data *data = i2c_get_clientdata(client);
-	int val = simple_strtol(buf, NULL, 10);
-
-	down(&data->update_lock);
-
-	if (val == 0) {
-		int tmp;
-		/* make sure the fan is on when in on/off mode */
-		tmp = it87_read_value(client, IT87_REG_FAN_CTL);
-		it87_write_value(client, IT87_REG_FAN_CTL, tmp | (1 << nr));
-		/* set on/off mode */
-		data->fan_main_ctrl &= ~(1 << nr);
-		it87_write_value(client, IT87_REG_FAN_MAIN_CTRL, data->fan_main_ctrl);
-	} else if (val == 1) {
-		/* set SmartGuardian mode */
-		data->fan_main_ctrl |= (1 << nr);
-		it87_write_value(client, IT87_REG_FAN_MAIN_CTRL, data->fan_main_ctrl);
-		/* set saved pwm value, clear FAN_CTLX PWM mode bit */
-		it87_write_value(client, IT87_REG_PWM(nr), PWM_TO_REG(data->manual_pwm_ctl[nr]));
-	} else {
-		up(&data->update_lock);
-		return -EINVAL;
-	}
-
-	up(&data->update_lock);
-	return count;
-}
-static ssize_t set_pwm(struct device *dev, const char *buf,
-		size_t count, int nr)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct it87_data *data = i2c_get_clientdata(client);
-	int val = simple_strtol(buf, NULL, 10);
-
-	if (val < 0 || val > 255)
-		return -EINVAL;
-
-	down(&data->update_lock);
-	data->manual_pwm_ctl[nr] = val;
-	if (data->fan_main_ctrl & (1 << nr))
-		it87_write_value(client, IT87_REG_PWM(nr), PWM_TO_REG(data->manual_pwm_ctl[nr]));
-	up(&data->update_lock);
-	return count;
-}
-
-#define show_fan_offset(offset)						\
-static ssize_t show_fan_##offset (struct device *dev, char *buf)	\
-{									\
-	return show_fan(dev, buf, offset - 1);				\
-}									\
-static ssize_t show_fan_##offset##_min (struct device *dev, char *buf)	\
-{									\
-	return show_fan_min(dev, buf, offset - 1);			\
-}									\
-static ssize_t show_fan_##offset##_div (struct device *dev, char *buf)	\
-{									\
-	return show_fan_div(dev, buf, offset - 1);			\
-}									\
-static ssize_t set_fan_##offset##_min (struct device *dev, 		\
-	const char *buf, size_t count) 					\
-{									\
-	return set_fan_min(dev, buf, count, offset - 1);		\
-}									\
-static ssize_t set_fan_##offset##_div (struct device *dev, 		\
-		const char *buf, size_t count) 				\
-{									\
-	return set_fan_div(dev, buf, count, offset - 1);		\
-}									\
-static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_fan_##offset, NULL); \
-static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, 		\
-		show_fan_##offset##_min, set_fan_##offset##_min); 	\
-static DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, 		\
-		show_fan_##offset##_div, set_fan_##offset##_div);
-
-show_fan_offset(1);
-show_fan_offset(2);
-show_fan_offset(3);
-
-#define show_pwm_offset(offset)						\
-static ssize_t show_pwm##offset##_enable (struct device *dev,		\
-	char *buf)							\
-{									\
-	return show_pwm_enable(dev, buf, offset - 1);			\
-}									\
-static ssize_t show_pwm##offset (struct device *dev, char *buf)		\
-{									\
-	return show_pwm(dev, buf, offset - 1);				\
-}									\
-static ssize_t set_pwm##offset##_enable (struct device *dev,		\
-		const char *buf, size_t count)				\
-{									\
-	return set_pwm_enable(dev, buf, count, offset - 1);		\
-}									\
-static ssize_t set_pwm##offset (struct device *dev,			\
-		const char *buf, size_t count)				\
-{									\
-	return set_pwm(dev, buf, count, offset - 1);			\
-}									\
-static DEVICE_ATTR(pwm##offset##_enable, S_IRUGO | S_IWUSR,		\
-		show_pwm##offset##_enable,				\
-		set_pwm##offset##_enable);				\
-static DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR,			\
-		show_pwm##offset , set_pwm##offset );
-
-show_pwm_offset(1);
-show_pwm_offset(2);
-show_pwm_offset(3);
-
-/* Alarms */
-static ssize_t show_alarms(struct device *dev, char *buf)
-{
-	struct it87_data *data = it87_update_device(dev);
-	return sprintf(buf,"%d\n", ALARMS_FROM_REG(data->alarms));
-}
-static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
-
-static ssize_t
-show_vrm_reg(struct device *dev, char *buf)
-{
-	struct it87_data *data = it87_update_device(dev);
-	return sprintf(buf, "%ld\n", (long) data->vrm);
-}
-static ssize_t
-store_vrm_reg(struct device *dev, const char *buf, size_t count)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct it87_data *data = i2c_get_clientdata(client);
-	u32 val;
-
-	val = simple_strtoul(buf, NULL, 10);
-	data->vrm = val;
-
-	return count;
-}
-static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg);
-#define device_create_file_vrm(client) \
-device_create_file(&client->dev, &dev_attr_vrm)
-
-static ssize_t
-show_vid_reg(struct device *dev, char *buf)
-{
-	struct it87_data *data = it87_update_device(dev);
-	return sprintf(buf, "%ld\n", (long) vid_from_reg(data->vid, data->vrm));
-}
-static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid_reg, NULL);
-#define device_create_file_vid(client) \
-device_create_file(&client->dev, &dev_attr_cpu0_vid)
-
-/* This function is called when:
-     * it87_driver is inserted (when this module is loaded), for each
-       available adapter
-     * when a new adapter is inserted (and it87_driver is still present) */
-static int it87_attach_adapter(struct i2c_adapter *adapter)
-{
-	if (!(adapter->class & I2C_CLASS_HWMON))
-		return 0;
-	return i2c_detect(adapter, &addr_data, it87_detect);
-}
-
-/* SuperIO detection - will change normal_isa[0] if a chip is found */
-static int it87_find(int *address)
-{
-	int err = -ENODEV;
-
-	superio_enter();
-	chip_type = superio_inw(DEVID);
-	if (chip_type != IT8712F_DEVID
-	 && chip_type != IT8705F_DEVID)
-	 	goto exit;
-
-	superio_select();
-	if (!(superio_inb(IT87_ACT_REG) & 0x01)) {
-		pr_info("it87: Device not activated, skipping\n");
-		goto exit;
-	}
-
-	*address = superio_inw(IT87_BASE_REG) & ~(IT87_EXTENT - 1);
-	if (*address == 0) {
-		pr_info("it87: Base address not set, skipping\n");
-		goto exit;
-	}
-
-	err = 0;
-	pr_info("it87: Found IT%04xF chip at 0x%x, revision %d\n",
-		chip_type, *address, superio_inb(DEVREV) & 0x0f);
-
-exit:
-	superio_exit();
-	return err;
-}
-
-/* This function is called by i2c_detect */
-int it87_detect(struct i2c_adapter *adapter, int address, int kind)
-{
-	int i;
-	struct i2c_client *new_client;
-	struct it87_data *data;
-	int err = 0;
-	const char *name = "";
-	int is_isa = i2c_is_isa_adapter(adapter);
-	int enable_pwm_interface;
-
-	if (!is_isa && 
-	    !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
-		goto ERROR0;
-
-	/* Reserve the ISA region */
-	if (is_isa)
-		if (!request_region(address, IT87_EXTENT, it87_driver.name))
-			goto ERROR0;
-
-	/* Probe whether there is anything available on this address. Already
-	   done for SMBus and Super-I/O clients */
-	if (kind < 0) {
-		if (is_isa && !chip_type) {
-#define REALLY_SLOW_IO
-			/* We need the timeouts for at least some IT87-like chips. But only
-			   if we read 'undefined' registers. */
-			i = inb_p(address + 1);
-			if (inb_p(address + 2) != i
-			 || inb_p(address + 3) != i
-			 || inb_p(address + 7) != i) {
-		 		err = -ENODEV;
-				goto ERROR1;
-			}
-#undef REALLY_SLOW_IO
-
-			/* Let's just hope nothing breaks here */
-			i = inb_p(address + 5) & 0x7f;
-			outb_p(~i & 0x7f, address + 5);
-			if ((inb_p(address + 5) & 0x7f) != (~i & 0x7f)) {
-				outb_p(i, address + 5);
-				err = -ENODEV;
-				goto ERROR1;
-			}
-		}
-	}
-
-	/* OK. For now, we presume we have a valid client. We now create the
-	   client structure, even though we cannot fill it completely yet.
-	   But it allows us to access it87_{read,write}_value. */
-
-	if (!(data = kmalloc(sizeof(struct it87_data), GFP_KERNEL))) {
-		err = -ENOMEM;
-		goto ERROR1;
-	}
-	memset(data, 0, sizeof(struct it87_data));
-
-	new_client = &data->client;
-	if (is_isa)
-		init_MUTEX(&data->lock);
-	i2c_set_clientdata(new_client, data);
-	new_client->addr = address;
-	new_client->adapter = adapter;
-	new_client->driver = &it87_driver;
-	new_client->flags = 0;
-
-	/* Now, we do the remaining detection. */
-
-	if (kind < 0) {
-		if ((it87_read_value(new_client, IT87_REG_CONFIG) & 0x80)
-		  || (!is_isa
-		   && it87_read_value(new_client, IT87_REG_I2C_ADDR) != address)) {
-		   	err = -ENODEV;
-			goto ERROR2;
-		}
-	}
-
-	/* Determine the chip type. */
-	if (kind <= 0) {
-		i = it87_read_value(new_client, IT87_REG_CHIPID);
-		if (i == 0x90) {
-			kind = it87;
-			if ((is_isa) && (chip_type == IT8712F_DEVID))
-				kind = it8712;
-		}
-		else {
-			if (kind == 0)
-				dev_info(&adapter->dev, 
-					"Ignoring 'force' parameter for unknown chip at "
-					"adapter %d, address 0x%02x\n",
-					i2c_adapter_id(adapter), address);
-			err = -ENODEV;
-			goto ERROR2;
-		}
-	}
-
-	if (kind == it87) {
-		name = "it87";
-	} else if (kind == it8712) {
-		name = "it8712";
-	}
-
-	/* Fill in the remaining client fields and put it into the global list */
-	strlcpy(new_client->name, name, I2C_NAME_SIZE);
-	data->type = kind;
-	data->valid = 0;
-	init_MUTEX(&data->update_lock);
-
-	/* Tell the I2C layer a new client has arrived */
-	if ((err = i2c_attach_client(new_client)))
-		goto ERROR2;
-
-	/* Check PWM configuration */
-	enable_pwm_interface = it87_check_pwm(new_client);
-
-	/* Initialize the IT87 chip */
-	it87_init_client(new_client, data);
-
-	/* Register sysfs hooks */
-	device_create_file(&new_client->dev, &dev_attr_in0_input);
-	device_create_file(&new_client->dev, &dev_attr_in1_input);
-	device_create_file(&new_client->dev, &dev_attr_in2_input);
-	device_create_file(&new_client->dev, &dev_attr_in3_input);
-	device_create_file(&new_client->dev, &dev_attr_in4_input);
-	device_create_file(&new_client->dev, &dev_attr_in5_input);
-	device_create_file(&new_client->dev, &dev_attr_in6_input);
-	device_create_file(&new_client->dev, &dev_attr_in7_input);
-	device_create_file(&new_client->dev, &dev_attr_in8_input);
-	device_create_file(&new_client->dev, &dev_attr_in0_min);
-	device_create_file(&new_client->dev, &dev_attr_in1_min);
-	device_create_file(&new_client->dev, &dev_attr_in2_min);
-	device_create_file(&new_client->dev, &dev_attr_in3_min);
-	device_create_file(&new_client->dev, &dev_attr_in4_min);
-	device_create_file(&new_client->dev, &dev_attr_in5_min);
-	device_create_file(&new_client->dev, &dev_attr_in6_min);
-	device_create_file(&new_client->dev, &dev_attr_in7_min);
-	device_create_file(&new_client->dev, &dev_attr_in0_max);
-	device_create_file(&new_client->dev, &dev_attr_in1_max);
-	device_create_file(&new_client->dev, &dev_attr_in2_max);
-	device_create_file(&new_client->dev, &dev_attr_in3_max);
-	device_create_file(&new_client->dev, &dev_attr_in4_max);
-	device_create_file(&new_client->dev, &dev_attr_in5_max);
-	device_create_file(&new_client->dev, &dev_attr_in6_max);
-	device_create_file(&new_client->dev, &dev_attr_in7_max);
-	device_create_file(&new_client->dev, &dev_attr_temp1_input);
-	device_create_file(&new_client->dev, &dev_attr_temp2_input);
-	device_create_file(&new_client->dev, &dev_attr_temp3_input);
-	device_create_file(&new_client->dev, &dev_attr_temp1_max);
-	device_create_file(&new_client->dev, &dev_attr_temp2_max);
-	device_create_file(&new_client->dev, &dev_attr_temp3_max);
-	device_create_file(&new_client->dev, &dev_attr_temp1_min);
-	device_create_file(&new_client->dev, &dev_attr_temp2_min);
-	device_create_file(&new_client->dev, &dev_attr_temp3_min);
-	device_create_file(&new_client->dev, &dev_attr_temp1_type);
-	device_create_file(&new_client->dev, &dev_attr_temp2_type);
-	device_create_file(&new_client->dev, &dev_attr_temp3_type);
-	device_create_file(&new_client->dev, &dev_attr_fan1_input);
-	device_create_file(&new_client->dev, &dev_attr_fan2_input);
-	device_create_file(&new_client->dev, &dev_attr_fan3_input);
-	device_create_file(&new_client->dev, &dev_attr_fan1_min);
-	device_create_file(&new_client->dev, &dev_attr_fan2_min);
-	device_create_file(&new_client->dev, &dev_attr_fan3_min);
-	device_create_file(&new_client->dev, &dev_attr_fan1_div);
-	device_create_file(&new_client->dev, &dev_attr_fan2_div);
-	device_create_file(&new_client->dev, &dev_attr_fan3_div);
-	device_create_file(&new_client->dev, &dev_attr_alarms);
-	if (enable_pwm_interface) {
-		device_create_file(&new_client->dev, &dev_attr_pwm1_enable);
-		device_create_file(&new_client->dev, &dev_attr_pwm2_enable);
-		device_create_file(&new_client->dev, &dev_attr_pwm3_enable);
-		device_create_file(&new_client->dev, &dev_attr_pwm1);
-		device_create_file(&new_client->dev, &dev_attr_pwm2);
-		device_create_file(&new_client->dev, &dev_attr_pwm3);
-	}
-
-	if (data->type == it8712) {
-		data->vrm = i2c_which_vrm();
-		device_create_file_vrm(new_client);
-		device_create_file_vid(new_client);
-	}
-
-	return 0;
-
-ERROR2:
-	kfree(data);
-ERROR1:
-	if (is_isa)
-		release_region(address, IT87_EXTENT);
-ERROR0:
-	return err;
-}
-
-static int it87_detach_client(struct i2c_client *client)
-{
-	int err;
-
-	if ((err = i2c_detach_client(client))) {
-		dev_err(&client->dev,
-			"Client deregistration failed, client not detached.\n");
-		return err;
-	}
-
-	if(i2c_is_isa_client(client))
-		release_region(client->addr, IT87_EXTENT);
-	kfree(i2c_get_clientdata(client));
-
-	return 0;
-}
-
-/* The SMBus locks itself, but ISA access must be locked explicitely! 
-   We don't want to lock the whole ISA bus, so we lock each client
-   separately.
-   We ignore the IT87 BUSY flag at this moment - it could lead to deadlocks,
-   would slow down the IT87 access and should not be necessary. */
-static int it87_read_value(struct i2c_client *client, u8 reg)
-{
-	struct it87_data *data = i2c_get_clientdata(client);
-
-	int res;
-	if (i2c_is_isa_client(client)) {
-		down(&data->lock);
-		outb_p(reg, client->addr + IT87_ADDR_REG_OFFSET);
-		res = inb_p(client->addr + IT87_DATA_REG_OFFSET);
-		up(&data->lock);
-		return res;
-	} else
-		return i2c_smbus_read_byte_data(client, reg);
-}
-
-/* The SMBus locks itself, but ISA access muse be locked explicitely! 
-   We don't want to lock the whole ISA bus, so we lock each client
-   separately.
-   We ignore the IT87 BUSY flag at this moment - it could lead to deadlocks,
-   would slow down the IT87 access and should not be necessary. */
-static int it87_write_value(struct i2c_client *client, u8 reg, u8 value)
-{
-	struct it87_data *data = i2c_get_clientdata(client);
-
-	if (i2c_is_isa_client(client)) {
-		down(&data->lock);
-		outb_p(reg, client->addr + IT87_ADDR_REG_OFFSET);
-		outb_p(value, client->addr + IT87_DATA_REG_OFFSET);
-		up(&data->lock);
-		return 0;
-	} else
-		return i2c_smbus_write_byte_data(client, reg, value);
-}
-
-/* Return 1 if and only if the PWM interface is safe to use */
-static int it87_check_pwm(struct i2c_client *client)
-{
-	/* Some BIOSes fail to correctly configure the IT87 fans. All fans off
-	 * and polarity set to active low is sign that this is the case so we
-	 * disable pwm control to protect the user. */
-	int tmp = it87_read_value(client, IT87_REG_FAN_CTL);
-	if ((tmp & 0x87) == 0) {
-		if (fix_pwm_polarity) {
-			/* The user asks us to attempt a chip reconfiguration.
-			 * This means switching to active high polarity and
-			 * inverting all fan speed values. */
-			int i;
-			u8 pwm[3];
-
-			for (i = 0; i < 3; i++)
-				pwm[i] = it87_read_value(client,
-							 IT87_REG_PWM(i));
-
-			/* If any fan is in automatic pwm mode, the polarity
-			 * might be correct, as suspicious as it seems, so we
-			 * better don't change anything (but still disable the
-			 * PWM interface). */
-			if (!((pwm[0] | pwm[1] | pwm[2]) & 0x80)) {
-				dev_info(&client->dev, "Reconfiguring PWM to "
-					 "active high polarity\n");
-				it87_write_value(client, IT87_REG_FAN_CTL,
-						 tmp | 0x87);
-				for (i = 0; i < 3; i++)
-					it87_write_value(client,
-							 IT87_REG_PWM(i),
-							 0x7f & ~pwm[i]);
-				return 1;
-			}
-
-			dev_info(&client->dev, "PWM configuration is "
-				 "too broken to be fixed\n");
-		}
-
-		dev_info(&client->dev, "Detected broken BIOS "
-			 "defaults, disabling PWM interface\n");
-		return 0;
-	} else if (fix_pwm_polarity) {
-		dev_info(&client->dev, "PWM configuration looks "
-			 "sane, won't touch\n");
-	}
-
-	return 1;
-}
-
-/* Called when we have found a new IT87. */
-static void it87_init_client(struct i2c_client *client, struct it87_data *data)
-{
-	int tmp, i;
-
-	/* initialize to sane defaults:
-	 * - if the chip is in manual pwm mode, this will be overwritten with
-	 *   the actual settings on the chip (so in this case, initialization
-	 *   is not needed)
-	 * - if in automatic or on/off mode, we could switch to manual mode,
-	 *   read the registers and set manual_pwm_ctl accordingly, but currently
-	 *   this is not implemented, so we initialize to something sane */
-	for (i = 0; i < 3; i++) {
-		data->manual_pwm_ctl[i] = 0xff;
-	}
-
-	/* Check if temperature channnels are reset manually or by some reason */
-	tmp = it87_read_value(client, IT87_REG_TEMP_ENABLE);
-	if ((tmp & 0x3f) == 0) {
-		/* Temp1,Temp3=thermistor; Temp2=thermal diode */
-		tmp = (tmp & 0xc0) | 0x2a;
-		it87_write_value(client, IT87_REG_TEMP_ENABLE, tmp);
-	}
-	data->sensor = tmp;
-
-	/* Check if voltage monitors are reset manually or by some reason */
-	tmp = it87_read_value(client, IT87_REG_VIN_ENABLE);
-	if ((tmp & 0xff) == 0) {
-		/* Enable all voltage monitors */
-		it87_write_value(client, IT87_REG_VIN_ENABLE, 0xff);
-	}
-
-	/* Check if tachometers are reset manually or by some reason */
-	data->fan_main_ctrl = it87_read_value(client, IT87_REG_FAN_MAIN_CTRL);
-	if ((data->fan_main_ctrl & 0x70) == 0) {
-		/* Enable all fan tachometers */
-		data->fan_main_ctrl |= 0x70;
-		it87_write_value(client, IT87_REG_FAN_MAIN_CTRL, data->fan_main_ctrl);
-	}
-
-	/* Set current fan mode registers and the default settings for the
-	 * other mode registers */
-	for (i = 0; i < 3; i++) {
-		if (data->fan_main_ctrl & (1 << i)) {
-			/* pwm mode */
-			tmp = it87_read_value(client, IT87_REG_PWM(i));
-			if (tmp & 0x80) {
-				/* automatic pwm - not yet implemented, but
-				 * leave the settings made by the BIOS alone
-				 * until a change is requested via the sysfs
-				 * interface */
-			} else {
-				/* manual pwm */
-				data->manual_pwm_ctl[i] = PWM_FROM_REG(tmp);
-			}
-		}
- 	}
-
-	/* Start monitoring */
-	it87_write_value(client, IT87_REG_CONFIG,
-			 (it87_read_value(client, IT87_REG_CONFIG) & 0x36)
-			 | (update_vbat ? 0x41 : 0x01));
-}
-
-static struct it87_data *it87_update_device(struct device *dev)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct it87_data *data = i2c_get_clientdata(client);
-	int i;
-
-	down(&data->update_lock);
-
-	if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
-	    || !data->valid) {
-
-		if (update_vbat) {
-			/* Cleared after each update, so reenable.  Value
-		 	  returned by this read will be previous value */	
-			it87_write_value(client, IT87_REG_CONFIG,
-			   it87_read_value(client, IT87_REG_CONFIG) | 0x40);
-		}
-		for (i = 0; i <= 7; i++) {
-			data->in[i] =
-			    it87_read_value(client, IT87_REG_VIN(i));
-			data->in_min[i] =
-			    it87_read_value(client, IT87_REG_VIN_MIN(i));
-			data->in_max[i] =
-			    it87_read_value(client, IT87_REG_VIN_MAX(i));
-		}
-		data->in[8] =
-		    it87_read_value(client, IT87_REG_VIN(8));
-		/* Temperature sensor doesn't have limit registers, set
-		   to min and max value */
-		data->in_min[8] = 0;
-		data->in_max[8] = 255;
-
-		for (i = 0; i < 3; i++) {
-			data->fan[i] =
-			    it87_read_value(client, IT87_REG_FAN(i));
-			data->fan_min[i] =
-			    it87_read_value(client, IT87_REG_FAN_MIN(i));
-		}
-		for (i = 0; i < 3; i++) {
-			data->temp[i] =
-			    it87_read_value(client, IT87_REG_TEMP(i));
-			data->temp_high[i] =
-			    it87_read_value(client, IT87_REG_TEMP_HIGH(i));
-			data->temp_low[i] =
-			    it87_read_value(client, IT87_REG_TEMP_LOW(i));
-		}
-
-		i = it87_read_value(client, IT87_REG_FAN_DIV);
-		data->fan_div[0] = i & 0x07;
-		data->fan_div[1] = (i >> 3) & 0x07;
-		data->fan_div[2] = (i & 0x40) ? 3 : 1;
-
-		data->alarms =
-			it87_read_value(client, IT87_REG_ALARM1) |
-			(it87_read_value(client, IT87_REG_ALARM2) << 8) |
-			(it87_read_value(client, IT87_REG_ALARM3) << 16);
-		data->fan_main_ctrl = it87_read_value(client, IT87_REG_FAN_MAIN_CTRL);
-
-		data->sensor = it87_read_value(client, IT87_REG_TEMP_ENABLE);
-		/* The 8705 does not have VID capability */
-		if (data->type == it8712) {
-			data->vid = it87_read_value(client, IT87_REG_VID);
-			data->vid &= 0x1f;
-		}
-		data->last_updated = jiffies;
-		data->valid = 1;
-	}
-
-	up(&data->update_lock);
-
-	return data;
-}
-
-static int __init sm_it87_init(void)
-{
-	int addr;
-
-	if (!it87_find(&addr)) {
-		normal_isa[0] = addr;
-	}
-	return i2c_add_driver(&it87_driver);
-}
-
-static void __exit sm_it87_exit(void)
-{
-	i2c_del_driver(&it87_driver);
-}
-
-
-MODULE_AUTHOR("Chris Gauthron <chrisg@0-in.com>");
-MODULE_DESCRIPTION("IT8705F, IT8712F, Sis950 driver");
-module_param(update_vbat, bool, 0);
-MODULE_PARM_DESC(update_vbat, "Update vbat if set else return powerup value");
-module_param(fix_pwm_polarity, bool, 0);
-MODULE_PARM_DESC(fix_pwm_polarity, "Force PWM polarity to active high (DANGEROUS)");
-MODULE_LICENSE("GPL");
-
-module_init(sm_it87_init);
-module_exit(sm_it87_exit);
diff --git a/drivers/i2c/chips/lm63.c b/drivers/i2c/chips/lm63.c
deleted file mode 100644
--- a/drivers/i2c/chips/lm63.c
+++ /dev/null
@@ -1,581 +0,0 @@
-/*
- * lm63.c - driver for the National Semiconductor LM63 temperature sensor
- *          with integrated fan control
- * Copyright (C) 2004  Jean Delvare <khali@linux-fr.org>
- * Based on the lm90 driver.
- *
- * The LM63 is a sensor chip made by National Semiconductor. It measures
- * two temperatures (its own and one external one) and the speed of one
- * fan, those speed it can additionally control. Complete datasheet can be
- * obtained from National's website at:
- *   http://www.national.com/pf/LM/LM63.html
- *
- * The LM63 is basically an LM86 with fan speed monitoring and control
- * capabilities added. It misses some of the LM86 features though:
- *  - No low limit for local temperature.
- *  - No critical limit for local temperature.
- *  - Critical limit for remote temperature can be changed only once. We
- *    will consider that the critical limit is read-only.
- *
- * The datasheet isn't very clear about what the tachometer reading is.
- * I had a explanation from National Semiconductor though. The two lower
- * bits of the read value have to be masked out. The value is still 16 bit
- * in width.
- *
- * 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 <linux/config.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/jiffies.h>
-#include <linux/i2c.h>
-#include <linux/i2c-sensor.h>
-
-/*
- * Addresses to scan
- * Address is fully defined internally and cannot be changed.
- */
-
-static unsigned short normal_i2c[] = { 0x4c, I2C_CLIENT_END };
-static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
-
-/*
- * Insmod parameters
- */
-
-SENSORS_INSMOD_1(lm63);
-
-/*
- * The LM63 registers
- */
-
-#define LM63_REG_CONFIG1		0x03
-#define LM63_REG_CONFIG2		0xBF
-#define LM63_REG_CONFIG_FAN		0x4A
-
-#define LM63_REG_TACH_COUNT_MSB		0x47
-#define LM63_REG_TACH_COUNT_LSB		0x46
-#define LM63_REG_TACH_LIMIT_MSB		0x49
-#define LM63_REG_TACH_LIMIT_LSB		0x48
-
-#define LM63_REG_PWM_VALUE		0x4C
-#define LM63_REG_PWM_FREQ		0x4D
-
-#define LM63_REG_LOCAL_TEMP		0x00
-#define LM63_REG_LOCAL_HIGH		0x05
-
-#define LM63_REG_REMOTE_TEMP_MSB	0x01
-#define LM63_REG_REMOTE_TEMP_LSB	0x10
-#define LM63_REG_REMOTE_OFFSET_MSB	0x11
-#define LM63_REG_REMOTE_OFFSET_LSB	0x12
-#define LM63_REG_REMOTE_HIGH_MSB	0x07
-#define LM63_REG_REMOTE_HIGH_LSB	0x13
-#define LM63_REG_REMOTE_LOW_MSB		0x08
-#define LM63_REG_REMOTE_LOW_LSB		0x14
-#define LM63_REG_REMOTE_TCRIT		0x19
-#define LM63_REG_REMOTE_TCRIT_HYST	0x21
-
-#define LM63_REG_ALERT_STATUS		0x02
-#define LM63_REG_ALERT_MASK		0x16
-
-#define LM63_REG_MAN_ID			0xFE
-#define LM63_REG_CHIP_ID		0xFF
-
-/*
- * Conversions and various macros
- * For tachometer counts, the LM63 uses 16-bit values.
- * For local temperature and high limit, remote critical limit and hysteresis
- * value, it uses signed 8-bit values with LSB = 1 degree Celcius.
- * For remote temperature, low and high limits, it uses signed 11-bit values
- * with LSB = 0.125 degree Celcius, left-justified in 16-bit registers.
- */
-
-#define FAN_FROM_REG(reg)	((reg) == 0xFFFC || (reg) == 0 ? 0 : \
-				 5400000 / (reg))
-#define FAN_TO_REG(val)		((val) <= 82 ? 0xFFFC : \
-				 (5400000 / (val)) & 0xFFFC)
-#define TEMP8_FROM_REG(reg)	((reg) * 1000)
-#define TEMP8_TO_REG(val)	((val) <= -128000 ? -128 : \
-				 (val) >= 127000 ? 127 : \
-				 (val) < 0 ? ((val) - 500) / 1000 : \
-				 ((val) + 500) / 1000)
-#define TEMP11_FROM_REG(reg)	((reg) / 32 * 125)
-#define TEMP11_TO_REG(val)	((val) <= -128000 ? 0x8000 : \
-				 (val) >= 127875 ? 0x7FE0 : \
-				 (val) < 0 ? ((val) - 62) / 125 * 32 : \
-				 ((val) + 62) / 125 * 32)
-#define HYST_TO_REG(val)	((val) <= 0 ? 0 : \
-				 (val) >= 127000 ? 127 : \
-				 ((val) + 500) / 1000)
-
-/*
- * Functions declaration
- */
-
-static int lm63_attach_adapter(struct i2c_adapter *adapter);
-static int lm63_detach_client(struct i2c_client *client);
-
-static struct lm63_data *lm63_update_device(struct device *dev);
-
-static int lm63_detect(struct i2c_adapter *adapter, int address, int kind);
-static void lm63_init_client(struct i2c_client *client);
-
-/*
- * Driver data (common to all clients)
- */
-
-static struct i2c_driver lm63_driver = {
-	.owner		= THIS_MODULE,
-	.name		= "lm63",
-	.flags		= I2C_DF_NOTIFY,
-	.attach_adapter	= lm63_attach_adapter,
-	.detach_client	= lm63_detach_client,
-};
-
-/*
- * Client data (each client gets its own)
- */
-
-struct lm63_data {
-	struct i2c_client client;
-	struct semaphore update_lock;
-	char valid; /* zero until following fields are valid */
-	unsigned long last_updated; /* in jiffies */
-
-	/* registers values */
-	u8 config, config_fan;
-	u16 fan1_input;
-	u16 fan1_low;
-	u8 pwm1_freq;
-	u8 pwm1_value;
-	s8 temp1_input;
-	s8 temp1_high;
-	s16 temp2_input;
-	s16 temp2_high;
-	s16 temp2_low;
-	s8 temp2_crit;
-	u8 temp2_crit_hyst;
-	u8 alarms;
-};
-
-/*
- * Sysfs callback functions and files
- */
-
-#define show_fan(value) \
-static ssize_t show_##value(struct device *dev, char *buf) \
-{ \
-	struct lm63_data *data = lm63_update_device(dev); \
-	return sprintf(buf, "%d\n", FAN_FROM_REG(data->value)); \
-}
-show_fan(fan1_input);
-show_fan(fan1_low);
-
-static ssize_t set_fan1_low(struct device *dev, const char *buf,
-	size_t count)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm63_data *data = i2c_get_clientdata(client);
-	unsigned long val = simple_strtoul(buf, NULL, 10);
-
-	down(&data->update_lock);
-	data->fan1_low = FAN_TO_REG(val);
-	i2c_smbus_write_byte_data(client, LM63_REG_TACH_LIMIT_LSB,
-				  data->fan1_low & 0xFF);
-	i2c_smbus_write_byte_data(client, LM63_REG_TACH_LIMIT_MSB,
-				  data->fan1_low >> 8);
-	up(&data->update_lock);
-	return count;
-}
-
-static ssize_t show_pwm1(struct device *dev, char *buf)
-{
-	struct lm63_data *data = lm63_update_device(dev);
-	return sprintf(buf, "%d\n", data->pwm1_value >= 2 * data->pwm1_freq ?
-		       255 : (data->pwm1_value * 255 + data->pwm1_freq) /
-		       (2 * data->pwm1_freq));
-}
-
-static ssize_t set_pwm1(struct device *dev, const char *buf, size_t count)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm63_data *data = i2c_get_clientdata(client);
-	unsigned long val;
-	
-	if (!(data->config_fan & 0x20)) /* register is read-only */
-		return -EPERM;
-
-	val = simple_strtoul(buf, NULL, 10);
-	down(&data->update_lock);
-	data->pwm1_value = val <= 0 ? 0 :
-			   val >= 255 ? 2 * data->pwm1_freq :
-			   (val * data->pwm1_freq * 2 + 127) / 255;
-	i2c_smbus_write_byte_data(client, LM63_REG_PWM_VALUE, data->pwm1_value);
-	up(&data->update_lock);
-	return count;
-}
-
-static ssize_t show_pwm1_enable(struct device *dev, char *buf)
-{
-	struct lm63_data *data = lm63_update_device(dev);
-	return sprintf(buf, "%d\n", data->config_fan & 0x20 ? 1 : 2);
-}
-
-#define show_temp8(value) \
-static ssize_t show_##value(struct device *dev, char *buf) \
-{ \
-	struct lm63_data *data = lm63_update_device(dev); \
-	return sprintf(buf, "%d\n", TEMP8_FROM_REG(data->value)); \
-}
-#define show_temp11(value) \
-static ssize_t show_##value(struct device *dev, char *buf) \
-{ \
-	struct lm63_data *data = lm63_update_device(dev); \
-	return sprintf(buf, "%d\n", TEMP11_FROM_REG(data->value)); \
-}
-show_temp8(temp1_input);
-show_temp8(temp1_high);
-show_temp11(temp2_input);
-show_temp11(temp2_high);
-show_temp11(temp2_low);
-show_temp8(temp2_crit);
-
-#define set_temp8(value, reg) \
-static ssize_t set_##value(struct device *dev, const char *buf, \
-	size_t count) \
-{ \
-	struct i2c_client *client = to_i2c_client(dev); \
-	struct lm63_data *data = i2c_get_clientdata(client); \
-	long val = simple_strtol(buf, NULL, 10); \
- \
-	down(&data->update_lock); \
-	data->value = TEMP8_TO_REG(val); \
-	i2c_smbus_write_byte_data(client, reg, data->value); \
-	up(&data->update_lock); \
-	return count; \
-}
-#define set_temp11(value, reg_msb, reg_lsb) \
-static ssize_t set_##value(struct device *dev, const char *buf, \
-	size_t count) \
-{ \
-	struct i2c_client *client = to_i2c_client(dev); \
-	struct lm63_data *data = i2c_get_clientdata(client); \
-	long val = simple_strtol(buf, NULL, 10); \
- \
-	down(&data->update_lock); \
-	data->value = TEMP11_TO_REG(val); \
-	i2c_smbus_write_byte_data(client, reg_msb, data->value >> 8); \
-	i2c_smbus_write_byte_data(client, reg_lsb, data->value & 0xff); \
-	up(&data->update_lock); \
-	return count; \
-}
-set_temp8(temp1_high, LM63_REG_LOCAL_HIGH);
-set_temp11(temp2_high, LM63_REG_REMOTE_HIGH_MSB, LM63_REG_REMOTE_HIGH_LSB);
-set_temp11(temp2_low, LM63_REG_REMOTE_LOW_MSB, LM63_REG_REMOTE_LOW_LSB);
-
-/* Hysteresis register holds a relative value, while we want to present
-   an absolute to user-space */
-static ssize_t show_temp2_crit_hyst(struct device *dev, char *buf)
-{
-	struct lm63_data *data = lm63_update_device(dev);
-	return sprintf(buf, "%d\n", TEMP8_FROM_REG(data->temp2_crit)
-		       - TEMP8_FROM_REG(data->temp2_crit_hyst));
-}
-
-/* And now the other way around, user-space provides an absolute
-   hysteresis value and we have to store a relative one */
-static ssize_t set_temp2_crit_hyst(struct device *dev, const char *buf,
-	size_t count)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm63_data *data = i2c_get_clientdata(client);
-	long val = simple_strtol(buf, NULL, 10);
-	long hyst;
-
-	down(&data->update_lock);
-	hyst = TEMP8_FROM_REG(data->temp2_crit) - val;
-	i2c_smbus_write_byte_data(client, LM63_REG_REMOTE_TCRIT_HYST,
-				  HYST_TO_REG(hyst));
-	up(&data->update_lock);
-	return count;
-}
-
-static ssize_t show_alarms(struct device *dev, char *buf)
-{
-	struct lm63_data *data = lm63_update_device(dev);
-	return sprintf(buf, "%u\n", data->alarms);
-}
-
-static DEVICE_ATTR(fan1_input, S_IRUGO, show_fan1_input, NULL);
-static DEVICE_ATTR(fan1_min, S_IWUSR | S_IRUGO, show_fan1_low,
-	set_fan1_low);
-
-static DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm1, set_pwm1);
-static DEVICE_ATTR(pwm1_enable, S_IRUGO, show_pwm1_enable, NULL);
-
-static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp1_input, NULL);
-static DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp1_high,
-	set_temp1_high);
-
-static DEVICE_ATTR(temp2_input, S_IRUGO, show_temp2_input, NULL);
-static DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_temp2_low,
-	set_temp2_low);
-static DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_temp2_high,
-	set_temp2_high);
-static DEVICE_ATTR(temp2_crit, S_IRUGO, show_temp2_crit, NULL);
-static DEVICE_ATTR(temp2_crit_hyst, S_IWUSR | S_IRUGO, show_temp2_crit_hyst,
-	set_temp2_crit_hyst);
-
-static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
-
-/*
- * Real code
- */
-
-static int lm63_attach_adapter(struct i2c_adapter *adapter)
-{
-	if (!(adapter->class & I2C_CLASS_HWMON))
-		return 0;
-	return i2c_detect(adapter, &addr_data, lm63_detect);
-}
-
-/*
- * The following function does more than just detection. If detection
- * succeeds, it also registers the new chip.
- */
-static int lm63_detect(struct i2c_adapter *adapter, int address, int kind)
-{
-	struct i2c_client *new_client;
-	struct lm63_data *data;
-	int err = 0;
-
-	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
-		goto exit;
-
-	if (!(data = kmalloc(sizeof(struct lm63_data), GFP_KERNEL))) {
-		err = -ENOMEM;
-		goto exit;
-	}
-	memset(data, 0, sizeof(struct lm63_data));
-
-	/* The common I2C client data is placed right before the
-	   LM63-specific data. */
-	new_client = &data->client;
-	i2c_set_clientdata(new_client, data);
-	new_client->addr = address;
-	new_client->adapter = adapter;
-	new_client->driver = &lm63_driver;
-	new_client->flags = 0;
-
-	/* Default to an LM63 if forced */
-	if (kind == 0)
-		kind = lm63;
-
-	if (kind < 0) { /* must identify */
-		u8 man_id, chip_id, reg_config1, reg_config2;
-		u8 reg_alert_status, reg_alert_mask;
-
-		man_id = i2c_smbus_read_byte_data(new_client,
-			 LM63_REG_MAN_ID);
-		chip_id = i2c_smbus_read_byte_data(new_client,
-			  LM63_REG_CHIP_ID);
-		reg_config1 = i2c_smbus_read_byte_data(new_client,
-			      LM63_REG_CONFIG1);
-		reg_config2 = i2c_smbus_read_byte_data(new_client,
-			      LM63_REG_CONFIG2);
-		reg_alert_status = i2c_smbus_read_byte_data(new_client,
-				   LM63_REG_ALERT_STATUS);
-		reg_alert_mask = i2c_smbus_read_byte_data(new_client,
-				 LM63_REG_ALERT_MASK);
-
-		if (man_id == 0x01 /* National Semiconductor */
-		 && chip_id == 0x41 /* LM63 */
-		 && (reg_config1 & 0x18) == 0x00
-		 && (reg_config2 & 0xF8) == 0x00
-		 && (reg_alert_status & 0x20) == 0x00
-		 && (reg_alert_mask & 0xA4) == 0xA4) {
-			kind = lm63;
-		} else { /* failed */
-			dev_dbg(&adapter->dev, "Unsupported chip "
-				"(man_id=0x%02X, chip_id=0x%02X).\n",
-				man_id, chip_id);
-			goto exit_free;
-		}
-	}
-
-	strlcpy(new_client->name, "lm63", I2C_NAME_SIZE);
-	data->valid = 0;
-	init_MUTEX(&data->update_lock);
-
-	/* Tell the I2C layer a new client has arrived */
-	if ((err = i2c_attach_client(new_client)))
-		goto exit_free;
-
-	/* Initialize the LM63 chip */
-	lm63_init_client(new_client);
-
-	/* Register sysfs hooks */
-	if (data->config & 0x04) { /* tachometer enabled */
-		device_create_file(&new_client->dev, &dev_attr_fan1_input);
-		device_create_file(&new_client->dev, &dev_attr_fan1_min);
-	}
-	device_create_file(&new_client->dev, &dev_attr_pwm1);
-	device_create_file(&new_client->dev, &dev_attr_pwm1_enable);
-	device_create_file(&new_client->dev, &dev_attr_temp1_input);
-	device_create_file(&new_client->dev, &dev_attr_temp2_input);
-	device_create_file(&new_client->dev, &dev_attr_temp2_min);
-	device_create_file(&new_client->dev, &dev_attr_temp1_max);
-	device_create_file(&new_client->dev, &dev_attr_temp2_max);
-	device_create_file(&new_client->dev, &dev_attr_temp2_crit);
-	device_create_file(&new_client->dev, &dev_attr_temp2_crit_hyst);
-	device_create_file(&new_client->dev, &dev_attr_alarms);
-
-	return 0;
-
-exit_free:
-	kfree(data);
-exit:
-	return err;
-}
-
-/* Idealy we shouldn't have to initialize anything, since the BIOS
-   should have taken care of everything */
-static void lm63_init_client(struct i2c_client *client)
-{
-	struct lm63_data *data = i2c_get_clientdata(client);
-
-	data->config = i2c_smbus_read_byte_data(client, LM63_REG_CONFIG1);
-	data->config_fan = i2c_smbus_read_byte_data(client,
-						    LM63_REG_CONFIG_FAN);
-
-	/* Start converting if needed */
-	if (data->config & 0x40) { /* standby */
-		dev_dbg(&client->dev, "Switching to operational mode");
-		data->config &= 0xA7;
-		i2c_smbus_write_byte_data(client, LM63_REG_CONFIG1,
-					  data->config);
-	}
-
-	/* We may need pwm1_freq before ever updating the client data */
-	data->pwm1_freq = i2c_smbus_read_byte_data(client, LM63_REG_PWM_FREQ);
-	if (data->pwm1_freq == 0)
-		data->pwm1_freq = 1;
-
-	/* Show some debug info about the LM63 configuration */
-	dev_dbg(&client->dev, "Alert/tach pin configured for %s\n",
-		(data->config & 0x04) ? "tachometer input" :
-		"alert output");
-	dev_dbg(&client->dev, "PWM clock %s kHz, output frequency %u Hz\n",
-		(data->config_fan & 0x08) ? "1.4" : "360",
-		((data->config_fan & 0x08) ? 700 : 180000) / data->pwm1_freq);
-	dev_dbg(&client->dev, "PWM output active %s, %s mode\n",
-		(data->config_fan & 0x10) ? "low" : "high",
-		(data->config_fan & 0x20) ? "manual" : "auto");
-}
-
-static int lm63_detach_client(struct i2c_client *client)
-{
-	int err;
-
-	if ((err = i2c_detach_client(client))) {
-		dev_err(&client->dev, "Client deregistration failed, "
-			"client not detached\n");
-		return err;
-	}
-
-	kfree(i2c_get_clientdata(client));
-	return 0;
-}
-
-static struct lm63_data *lm63_update_device(struct device *dev)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm63_data *data = i2c_get_clientdata(client);
-
-	down(&data->update_lock);
-
-	if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
-		if (data->config & 0x04) { /* tachometer enabled  */
-			/* order matters for fan1_input */
-			data->fan1_input = i2c_smbus_read_byte_data(client,
-					   LM63_REG_TACH_COUNT_LSB) & 0xFC;
-			data->fan1_input |= i2c_smbus_read_byte_data(client,
-					    LM63_REG_TACH_COUNT_MSB) << 8;
-			data->fan1_low = (i2c_smbus_read_byte_data(client,
-					  LM63_REG_TACH_LIMIT_LSB) & 0xFC)
-				       | (i2c_smbus_read_byte_data(client,
-					  LM63_REG_TACH_LIMIT_MSB) << 8);
-		}
-
-		data->pwm1_freq = i2c_smbus_read_byte_data(client,
-				  LM63_REG_PWM_FREQ);
-		if (data->pwm1_freq == 0)
-			data->pwm1_freq = 1;
-		data->pwm1_value = i2c_smbus_read_byte_data(client,
-				   LM63_REG_PWM_VALUE);
-
-		data->temp1_input = i2c_smbus_read_byte_data(client,
-				    LM63_REG_LOCAL_TEMP);
-		data->temp1_high = i2c_smbus_read_byte_data(client,
-				   LM63_REG_LOCAL_HIGH);
-
-		/* order matters for temp2_input */
-		data->temp2_input = i2c_smbus_read_byte_data(client,
-				    LM63_REG_REMOTE_TEMP_MSB) << 8;
-		data->temp2_input |= i2c_smbus_read_byte_data(client,
-				     LM63_REG_REMOTE_TEMP_LSB);
-		data->temp2_high = (i2c_smbus_read_byte_data(client,
-				   LM63_REG_REMOTE_HIGH_MSB) << 8)
-				 | i2c_smbus_read_byte_data(client,
-				   LM63_REG_REMOTE_HIGH_LSB);
-		data->temp2_low = (i2c_smbus_read_byte_data(client,
-				  LM63_REG_REMOTE_LOW_MSB) << 8)
-				| i2c_smbus_read_byte_data(client,
-				  LM63_REG_REMOTE_LOW_LSB);
-		data->temp2_crit = i2c_smbus_read_byte_data(client,
-				   LM63_REG_REMOTE_TCRIT);
-		data->temp2_crit_hyst = i2c_smbus_read_byte_data(client,
-					LM63_REG_REMOTE_TCRIT_HYST);
-
-		data->alarms = i2c_smbus_read_byte_data(client,
-			       LM63_REG_ALERT_STATUS) & 0x7F;
-
-		data->last_updated = jiffies;
-		data->valid = 1;
-	}
-
-	up(&data->update_lock);
-
-	return data;
-}
-
-static int __init sensors_lm63_init(void)
-{
-	return i2c_add_driver(&lm63_driver);
-}
-
-static void __exit sensors_lm63_exit(void)
-{
-	i2c_del_driver(&lm63_driver);
-}
-
-MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>");
-MODULE_DESCRIPTION("LM63 driver");
-MODULE_LICENSE("GPL");
-
-module_init(sensors_lm63_init);
-module_exit(sensors_lm63_exit);
diff --git a/drivers/i2c/chips/lm75.c b/drivers/i2c/chips/lm75.c
deleted file mode 100644
--- a/drivers/i2c/chips/lm75.c
+++ /dev/null
@@ -1,297 +0,0 @@
-/*
-    lm75.c - Part of lm_sensors, Linux kernel modules for hardware
-             monitoring
-    Copyright (c) 1998, 1999  Frodo Looijaard <frodol@dds.nl>
-
-    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 <linux/config.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/jiffies.h>
-#include <linux/i2c.h>
-#include <linux/i2c-sensor.h>
-#include "lm75.h"
-
-
-/* Addresses to scan */
-static unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, 0x4c,
-					0x4d, 0x4e, 0x4f, I2C_CLIENT_END };
-static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
-
-/* Insmod parameters */
-SENSORS_INSMOD_1(lm75);
-
-/* Many LM75 constants specified below */
-
-/* The LM75 registers */
-#define LM75_REG_TEMP		0x00
-#define LM75_REG_CONF		0x01
-#define LM75_REG_TEMP_HYST	0x02
-#define LM75_REG_TEMP_OS	0x03
-
-/* Each client has this additional data */
-struct lm75_data {
-	struct i2c_client	client;
-	struct semaphore	update_lock;
-	char			valid;		/* !=0 if following fields are valid */
-	unsigned long		last_updated;	/* In jiffies */
-	u16			temp_input;	/* Register values */
-	u16			temp_max;
-	u16			temp_hyst;
-};
-
-static int lm75_attach_adapter(struct i2c_adapter *adapter);
-static int lm75_detect(struct i2c_adapter *adapter, int address, int kind);
-static void lm75_init_client(struct i2c_client *client);
-static int lm75_detach_client(struct i2c_client *client);
-static int lm75_read_value(struct i2c_client *client, u8 reg);
-static int lm75_write_value(struct i2c_client *client, u8 reg, u16 value);
-static struct lm75_data *lm75_update_device(struct device *dev);
-
-
-/* This is the driver that will be inserted */
-static struct i2c_driver lm75_driver = {
-	.owner		= THIS_MODULE,
-	.name		= "lm75",
-	.id		= I2C_DRIVERID_LM75,
-	.flags		= I2C_DF_NOTIFY,
-	.attach_adapter	= lm75_attach_adapter,
-	.detach_client	= lm75_detach_client,
-};
-
-#define show(value)	\
-static ssize_t show_##value(struct device *dev, char *buf)		\
-{									\
-	struct lm75_data *data = lm75_update_device(dev);		\
-	return sprintf(buf, "%d\n", LM75_TEMP_FROM_REG(data->value));	\
-}
-show(temp_max);
-show(temp_hyst);
-show(temp_input);
-
-#define set(value, reg)	\
-static ssize_t set_##value(struct device *dev, const char *buf, size_t count)	\
-{								\
-	struct i2c_client *client = to_i2c_client(dev);		\
-	struct lm75_data *data = i2c_get_clientdata(client);	\
-	int temp = simple_strtoul(buf, NULL, 10);		\
-								\
-	down(&data->update_lock);				\
-	data->value = LM75_TEMP_TO_REG(temp);			\
-	lm75_write_value(client, reg, data->value);		\
-	up(&data->update_lock);					\
-	return count;						\
-}
-set(temp_max, LM75_REG_TEMP_OS);
-set(temp_hyst, LM75_REG_TEMP_HYST);
-
-static DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp_max, set_temp_max);
-static DEVICE_ATTR(temp1_max_hyst, S_IWUSR | S_IRUGO, show_temp_hyst, set_temp_hyst);
-static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp_input, NULL);
-
-static int lm75_attach_adapter(struct i2c_adapter *adapter)
-{
-	if (!(adapter->class & I2C_CLASS_HWMON))
-		return 0;
-	return i2c_detect(adapter, &addr_data, lm75_detect);
-}
-
-/* This function is called by i2c_detect */
-static int lm75_detect(struct i2c_adapter *adapter, int address, int kind)
-{
-	int i;
-	struct i2c_client *new_client;
-	struct lm75_data *data;
-	int err = 0;
-	const char *name = "";
-
-	/* Make sure we aren't probing the ISA bus!! This is just a safety check
-	   at this moment; i2c_detect really won't call us. */
-#ifdef DEBUG
-	if (i2c_is_isa_adapter(adapter)) {
-		dev_dbg(&adapter->dev,
-			"lm75_detect called for an ISA bus adapter?!?\n");
-		goto exit;
-	}
-#endif
-
-	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
-				     I2C_FUNC_SMBUS_WORD_DATA))
-		goto exit;
-
-	/* OK. For now, we presume we have a valid client. We now create the
-	   client structure, even though we cannot fill it completely yet.
-	   But it allows us to access lm75_{read,write}_value. */
-	if (!(data = kmalloc(sizeof(struct lm75_data), GFP_KERNEL))) {
-		err = -ENOMEM;
-		goto exit;
-	}
-	memset(data, 0, sizeof(struct lm75_data));
-
-	new_client = &data->client;
-	i2c_set_clientdata(new_client, data);
-	new_client->addr = address;
-	new_client->adapter = adapter;
-	new_client->driver = &lm75_driver;
-	new_client->flags = 0;
-
-	/* Now, we do the remaining detection. There is no identification-
-	   dedicated register so we have to rely on several tricks:
-	   unused bits, registers cycling over 8-address boundaries,
-	   addresses 0x04-0x07 returning the last read value.
-	   The cycling+unused addresses combination is not tested,
-	   since it would significantly slow the detection down and would
-	   hardly add any value. */
-	if (kind < 0) {
-		int cur, conf, hyst, os;
-
-		/* Unused addresses */
-		cur = i2c_smbus_read_word_data(new_client, 0);
-		conf = i2c_smbus_read_byte_data(new_client, 1);
-		hyst = i2c_smbus_read_word_data(new_client, 2);
-		if (i2c_smbus_read_word_data(new_client, 4) != hyst
-		 || i2c_smbus_read_word_data(new_client, 5) != hyst
-		 || i2c_smbus_read_word_data(new_client, 6) != hyst
-		 || i2c_smbus_read_word_data(new_client, 7) != hyst)
-		 	goto exit_free;
-		os = i2c_smbus_read_word_data(new_client, 3);
-		if (i2c_smbus_read_word_data(new_client, 4) != os
-		 || i2c_smbus_read_word_data(new_client, 5) != os
-		 || i2c_smbus_read_word_data(new_client, 6) != os
-		 || i2c_smbus_read_word_data(new_client, 7) != os)
-		 	goto exit_free;
-
-		/* Unused bits */
-		if (conf & 0xe0)
-		 	goto exit_free;
-
-		/* Addresses cycling */
-		for (i = 8; i < 0xff; i += 8)
-			if (i2c_smbus_read_byte_data(new_client, i + 1) != conf
-			 || i2c_smbus_read_word_data(new_client, i + 2) != hyst
-			 || i2c_smbus_read_word_data(new_client, i + 3) != os)
-				goto exit_free;
-	}
-
-	/* Determine the chip type - only one kind supported! */
-	if (kind <= 0)
-		kind = lm75;
-
-	if (kind == lm75) {
-		name = "lm75";
-	}
-
-	/* Fill in the remaining client fields and put it into the global list */
-	strlcpy(new_client->name, name, I2C_NAME_SIZE);
-	data->valid = 0;
-	init_MUTEX(&data->update_lock);
-
-	/* Tell the I2C layer a new client has arrived */
-	if ((err = i2c_attach_client(new_client)))
-		goto exit_free;
-
-	/* Initialize the LM75 chip */
-	lm75_init_client(new_client);
-	
-	/* Register sysfs hooks */
-	device_create_file(&new_client->dev, &dev_attr_temp1_max);
-	device_create_file(&new_client->dev, &dev_attr_temp1_max_hyst);
-	device_create_file(&new_client->dev, &dev_attr_temp1_input);
-
-	return 0;
-
-exit_free:
-	kfree(data);
-exit:
-	return err;
-}
-
-static int lm75_detach_client(struct i2c_client *client)
-{
-	i2c_detach_client(client);
-	kfree(i2c_get_clientdata(client));
-	return 0;
-}
-
-/* All registers are word-sized, except for the configuration register.
-   LM75 uses a high-byte first convention, which is exactly opposite to
-   the usual practice. */
-static int lm75_read_value(struct i2c_client *client, u8 reg)
-{
-	if (reg == LM75_REG_CONF)
-		return i2c_smbus_read_byte_data(client, reg);
-	else
-		return swab16(i2c_smbus_read_word_data(client, reg));
-}
-
-/* All registers are word-sized, except for the configuration register.
-   LM75 uses a high-byte first convention, which is exactly opposite to
-   the usual practice. */
-static int lm75_write_value(struct i2c_client *client, u8 reg, u16 value)
-{
-	if (reg == LM75_REG_CONF)
-		return i2c_smbus_write_byte_data(client, reg, value);
-	else
-		return i2c_smbus_write_word_data(client, reg, swab16(value));
-}
-
-static void lm75_init_client(struct i2c_client *client)
-{
-	/* Initialize the LM75 chip */
-	lm75_write_value(client, LM75_REG_CONF, 0);
-}
-
-static struct lm75_data *lm75_update_device(struct device *dev)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm75_data *data = i2c_get_clientdata(client);
-
-	down(&data->update_lock);
-
-	if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
-	    || !data->valid) {
-		dev_dbg(&client->dev, "Starting lm75 update\n");
-
-		data->temp_input = lm75_read_value(client, LM75_REG_TEMP);
-		data->temp_max = lm75_read_value(client, LM75_REG_TEMP_OS);
-		data->temp_hyst = lm75_read_value(client, LM75_REG_TEMP_HYST);
-		data->last_updated = jiffies;
-		data->valid = 1;
-	}
-
-	up(&data->update_lock);
-
-	return data;
-}
-
-static int __init sensors_lm75_init(void)
-{
-	return i2c_add_driver(&lm75_driver);
-}
-
-static void __exit sensors_lm75_exit(void)
-{
-	i2c_del_driver(&lm75_driver);
-}
-
-MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>");
-MODULE_DESCRIPTION("LM75 driver");
-MODULE_LICENSE("GPL");
-
-module_init(sensors_lm75_init);
-module_exit(sensors_lm75_exit);
diff --git a/drivers/i2c/chips/lm75.h b/drivers/i2c/chips/lm75.h
deleted file mode 100644
--- a/drivers/i2c/chips/lm75.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
-    lm75.h - Part of lm_sensors, Linux kernel modules for hardware
-             monitoring
-    Copyright (c) 2003 Mark M. Hoffman <mhoffman@lightlink.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., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-/*
-    This file contains common code for encoding/decoding LM75 type
-    temperature readings, which are emulated by many of the chips
-    we support.  As the user is unlikely to load more than one driver
-    which contains this code, we don't worry about the wasted space.
-*/
-
-#include <linux/i2c-sensor.h>
-
-/* straight from the datasheet */
-#define LM75_TEMP_MIN (-55000)
-#define LM75_TEMP_MAX 125000
-
-/* TEMP: 0.001C/bit (-55C to +125C)
-   REG: (0.5C/bit, two's complement) << 7 */
-static inline u16 LM75_TEMP_TO_REG(int temp)
-{
-	int ntemp = SENSORS_LIMIT(temp, LM75_TEMP_MIN, LM75_TEMP_MAX);
-	ntemp += (ntemp<0 ? -250 : 250);
-	return (u16)((ntemp / 500) << 7);
-}
-
-static inline int LM75_TEMP_FROM_REG(u16 reg)
-{
-	/* use integer division instead of equivalent right shift to
-	   guarantee arithmetic shift and preserve the sign */
-	return ((s16)reg / 128) * 500;
-}
-
diff --git a/drivers/i2c/chips/lm77.c b/drivers/i2c/chips/lm77.c
deleted file mode 100644
--- a/drivers/i2c/chips/lm77.c
+++ /dev/null
@@ -1,421 +0,0 @@
-/*
-    lm77.c - Part of lm_sensors, Linux kernel modules for hardware
-             monitoring
-
-    Copyright (c) 2004  Andras BALI <drewie@freemail.hu>
-
-    Heavily based on lm75.c by Frodo Looijaard <frodol@dds.nl>.  The LM77
-    is a temperature sensor and thermal window comparator with 0.5 deg
-    resolution made by National Semiconductor.  Complete datasheet can be
-    obtained at their site:
-       http://www.national.com/pf/LM/LM77.html
-
-    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 <linux/config.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/jiffies.h>
-#include <linux/i2c.h>
-#include <linux/i2c-sensor.h>
-
-
-/* Addresses to scan */
-static unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, I2C_CLIENT_END };
-static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
-
-/* Insmod parameters */
-SENSORS_INSMOD_1(lm77);
-
-/* The LM77 registers */
-#define LM77_REG_TEMP		0x00
-#define LM77_REG_CONF		0x01
-#define LM77_REG_TEMP_HYST	0x02
-#define LM77_REG_TEMP_CRIT	0x03
-#define LM77_REG_TEMP_MIN	0x04
-#define LM77_REG_TEMP_MAX	0x05
-
-/* Each client has this additional data */
-struct lm77_data {
-	struct i2c_client	client;
-	struct semaphore	update_lock;
-	char			valid;
-	unsigned long		last_updated;	/* In jiffies */
-	int			temp_input;	/* Temperatures */
-	int			temp_crit;
-	int			temp_min;
-	int			temp_max;
-	int			temp_hyst;
-	u8			alarms;
-};
-
-static int lm77_attach_adapter(struct i2c_adapter *adapter);
-static int lm77_detect(struct i2c_adapter *adapter, int address, int kind);
-static void lm77_init_client(struct i2c_client *client);
-static int lm77_detach_client(struct i2c_client *client);
-static u16 lm77_read_value(struct i2c_client *client, u8 reg);
-static int lm77_write_value(struct i2c_client *client, u8 reg, u16 value);
-
-static struct lm77_data *lm77_update_device(struct device *dev);
-
-
-/* This is the driver that will be inserted */
-static struct i2c_driver lm77_driver = {
-	.owner		= THIS_MODULE,
-	.name		= "lm77",
-	.flags		= I2C_DF_NOTIFY,
-	.attach_adapter = lm77_attach_adapter,
-	.detach_client	= lm77_detach_client,
-};
-
-/* straight from the datasheet */
-#define LM77_TEMP_MIN (-55000)
-#define LM77_TEMP_MAX 125000
-
-/* In the temperature registers, the low 3 bits are not part of the
-   temperature values; they are the status bits. */
-static inline u16 LM77_TEMP_TO_REG(int temp)
-{
-	int ntemp = SENSORS_LIMIT(temp, LM77_TEMP_MIN, LM77_TEMP_MAX);
-	return (u16)((ntemp / 500) * 8);
-}
-
-static inline int LM77_TEMP_FROM_REG(u16 reg)
-{
-	return ((int)reg / 8) * 500;
-}
-
-/* sysfs stuff */
-
-/* read routines for temperature limits */
-#define show(value)	\
-static ssize_t show_##value(struct device *dev, char *buf)	\
-{								\
-	struct lm77_data *data = lm77_update_device(dev);	\
-	return sprintf(buf, "%d\n", data->value);		\
-}
-
-show(temp_input);
-show(temp_crit);
-show(temp_min);
-show(temp_max);
-show(alarms);
-
-/* read routines for hysteresis values */
-static ssize_t show_temp_crit_hyst(struct device *dev, char *buf)
-{
-	struct lm77_data *data = lm77_update_device(dev);
-	return sprintf(buf, "%d\n", data->temp_crit - data->temp_hyst);
-}
-static ssize_t show_temp_min_hyst(struct device *dev, char *buf)
-{
-	struct lm77_data *data = lm77_update_device(dev);
-	return sprintf(buf, "%d\n", data->temp_min + data->temp_hyst);
-}
-static ssize_t show_temp_max_hyst(struct device *dev, char *buf)
-{
-	struct lm77_data *data = lm77_update_device(dev);
-	return sprintf(buf, "%d\n", data->temp_max - data->temp_hyst);
-}
-
-/* write routines */
-#define set(value, reg)	\
-static ssize_t set_##value(struct device *dev, const char *buf, size_t count)	\
-{										\
-	struct i2c_client *client = to_i2c_client(dev);				\
-	struct lm77_data *data = i2c_get_clientdata(client);			\
-	long val = simple_strtoul(buf, NULL, 10);				\
-										\
-	down(&data->update_lock);						\
-	data->value = val;				\
-	lm77_write_value(client, reg, LM77_TEMP_TO_REG(data->value));		\
-	up(&data->update_lock);							\
-	return count;								\
-}
-
-set(temp_min, LM77_REG_TEMP_MIN);
-set(temp_max, LM77_REG_TEMP_MAX);
-
-/* hysteresis is stored as a relative value on the chip, so it has to be
-   converted first */
-static ssize_t set_temp_crit_hyst(struct device *dev, const char *buf, size_t count)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm77_data *data = i2c_get_clientdata(client);
-	unsigned long val = simple_strtoul(buf, NULL, 10);
-
-	down(&data->update_lock);
-	data->temp_hyst = data->temp_crit - val;
-	lm77_write_value(client, LM77_REG_TEMP_HYST,
-			 LM77_TEMP_TO_REG(data->temp_hyst));
-	up(&data->update_lock);
-	return count;
-}
-
-/* preserve hysteresis when setting T_crit */
-static ssize_t set_temp_crit(struct device *dev, const char *buf, size_t count)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm77_data *data = i2c_get_clientdata(client);
-	long val = simple_strtoul(buf, NULL, 10);
-	int oldcrithyst;
-	
-	down(&data->update_lock);
-	oldcrithyst = data->temp_crit - data->temp_hyst;
-	data->temp_crit = val;
-	data->temp_hyst = data->temp_crit - oldcrithyst;
-	lm77_write_value(client, LM77_REG_TEMP_CRIT,
-			 LM77_TEMP_TO_REG(data->temp_crit));
-	lm77_write_value(client, LM77_REG_TEMP_HYST,
-			 LM77_TEMP_TO_REG(data->temp_hyst));
-	up(&data->update_lock);
-	return count;
-}
-
-static DEVICE_ATTR(temp1_input, S_IRUGO,
-		   show_temp_input, NULL);
-static DEVICE_ATTR(temp1_crit, S_IWUSR | S_IRUGO,
-		   show_temp_crit, set_temp_crit);
-static DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO,
-		   show_temp_min, set_temp_min);
-static DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO,
-		   show_temp_max, set_temp_max);
-
-static DEVICE_ATTR(temp1_crit_hyst, S_IWUSR | S_IRUGO,
-		   show_temp_crit_hyst, set_temp_crit_hyst);
-static DEVICE_ATTR(temp1_min_hyst, S_IRUGO,
-		   show_temp_min_hyst, NULL);
-static DEVICE_ATTR(temp1_max_hyst, S_IRUGO,
-		   show_temp_max_hyst, NULL);
-
-static DEVICE_ATTR(alarms, S_IRUGO,
-		   show_alarms, NULL);
-
-static int lm77_attach_adapter(struct i2c_adapter *adapter)
-{
-	if (!(adapter->class & I2C_CLASS_HWMON))
-		return 0;
-	return i2c_detect(adapter, &addr_data, lm77_detect);
-}
-
-/* This function is called by i2c_detect */
-static int lm77_detect(struct i2c_adapter *adapter, int address, int kind)
-{
-	struct i2c_client *new_client;
-	struct lm77_data *data;
-	int err = 0;
-	const char *name = "";
-
-	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
-				     I2C_FUNC_SMBUS_WORD_DATA))
-		goto exit;
-
-	/* OK. For now, we presume we have a valid client. We now create the
-	   client structure, even though we cannot fill it completely yet.
-	   But it allows us to access lm77_{read,write}_value. */
-	if (!(data = kmalloc(sizeof(struct lm77_data), GFP_KERNEL))) {
-		err = -ENOMEM;
-		goto exit;
-	}
-	memset(data, 0, sizeof(struct lm77_data));
-
-	new_client = &data->client;
-	i2c_set_clientdata(new_client, data);
-	new_client->addr = address;
-	new_client->adapter = adapter;
-	new_client->driver = &lm77_driver;
-	new_client->flags = 0;
-
-	/* Here comes the remaining detection.  Since the LM77 has no
-	   register dedicated to identification, we have to rely on the
-	   following tricks:
-
-	   1. the high 4 bits represent the sign and thus they should
-	      always be the same
-	   2. the high 3 bits are unused in the configuration register
-	   3. addresses 0x06 and 0x07 return the last read value
-	   4. registers cycling over 8-address boundaries
-
-	   Word-sized registers are high-byte first. */
-	if (kind < 0) {
-		int i, cur, conf, hyst, crit, min, max;
-
-		/* addresses cycling */
-		cur = i2c_smbus_read_word_data(new_client, 0);
-		conf = i2c_smbus_read_byte_data(new_client, 1);
-		hyst = i2c_smbus_read_word_data(new_client, 2);
-		crit = i2c_smbus_read_word_data(new_client, 3);
-		min = i2c_smbus_read_word_data(new_client, 4);
-		max = i2c_smbus_read_word_data(new_client, 5);
-		for (i = 8; i <= 0xff; i += 8)
-			if (i2c_smbus_read_byte_data(new_client, i + 1) != conf
-			    || i2c_smbus_read_word_data(new_client, i + 2) != hyst
-			    || i2c_smbus_read_word_data(new_client, i + 3) != crit
-			    || i2c_smbus_read_word_data(new_client, i + 4) != min
-			    || i2c_smbus_read_word_data(new_client, i + 5) != max)
-				goto exit_free;
-
-		/* sign bits */
-		if (((cur & 0x00f0) != 0xf0 && (cur & 0x00f0) != 0x0)
-		    || ((hyst & 0x00f0) != 0xf0 && (hyst & 0x00f0) != 0x0)
-		    || ((crit & 0x00f0) != 0xf0 && (crit & 0x00f0) != 0x0)
-		    || ((min & 0x00f0) != 0xf0 && (min & 0x00f0) != 0x0)
-		    || ((max & 0x00f0) != 0xf0 && (max & 0x00f0) != 0x0))
-			goto exit_free;
-
-		/* unused bits */
-		if (conf & 0xe0)
-			goto exit_free;
-
-		/* 0x06 and 0x07 return the last read value */
-		cur = i2c_smbus_read_word_data(new_client, 0);
-		if (i2c_smbus_read_word_data(new_client, 6) != cur
-		    || i2c_smbus_read_word_data(new_client, 7) != cur)
-			goto exit_free;
-		hyst = i2c_smbus_read_word_data(new_client, 2);
-		if (i2c_smbus_read_word_data(new_client, 6) != hyst
-		    || i2c_smbus_read_word_data(new_client, 7) != hyst)
-			goto exit_free;
-		min = i2c_smbus_read_word_data(new_client, 4);
-		if (i2c_smbus_read_word_data(new_client, 6) != min
-		    || i2c_smbus_read_word_data(new_client, 7) != min)
-			goto exit_free;
-
-	}
-
-	/* Determine the chip type - only one kind supported! */
-	if (kind <= 0)
-		kind = lm77;
-
-	if (kind == lm77) {
-		name = "lm77";
-	}
-
-	/* Fill in the remaining client fields and put it into the global list */
-	strlcpy(new_client->name, name, I2C_NAME_SIZE);
-	data->valid = 0;
-	init_MUTEX(&data->update_lock);
-
-	/* Tell the I2C layer a new client has arrived */
-	if ((err = i2c_attach_client(new_client)))
-		goto exit_free;
-
-	/* Initialize the LM77 chip */
-	lm77_init_client(new_client);
-
-	/* Register sysfs hooks */
-	device_create_file(&new_client->dev, &dev_attr_temp1_input);
-	device_create_file(&new_client->dev, &dev_attr_temp1_crit);
-	device_create_file(&new_client->dev, &dev_attr_temp1_min);
-	device_create_file(&new_client->dev, &dev_attr_temp1_max);
-	device_create_file(&new_client->dev, &dev_attr_temp1_crit_hyst);
-	device_create_file(&new_client->dev, &dev_attr_temp1_min_hyst);
-	device_create_file(&new_client->dev, &dev_attr_temp1_max_hyst);
-	device_create_file(&new_client->dev, &dev_attr_alarms);
-	return 0;
-
-exit_free:
-	kfree(data);
-exit:
-	return err;
-}
-
-static int lm77_detach_client(struct i2c_client *client)
-{
-	i2c_detach_client(client);
-	kfree(i2c_get_clientdata(client));
-	return 0;
-}
-
-/* All registers are word-sized, except for the configuration register.
-   The LM77 uses the high-byte first convention. */
-static u16 lm77_read_value(struct i2c_client *client, u8 reg)
-{
-	if (reg == LM77_REG_CONF)
-		return i2c_smbus_read_byte_data(client, reg);
-	else
-		return swab16(i2c_smbus_read_word_data(client, reg));
-}
-
-static int lm77_write_value(struct i2c_client *client, u8 reg, u16 value)
-{
-	if (reg == LM77_REG_CONF)
-		return i2c_smbus_write_byte_data(client, reg, value);
-	else
-		return i2c_smbus_write_word_data(client, reg, swab16(value));
-}
-
-static void lm77_init_client(struct i2c_client *client)
-{
-	/* Initialize the LM77 chip - turn off shutdown mode */
-	int conf = lm77_read_value(client, LM77_REG_CONF);
-	if (conf & 1)
-		lm77_write_value(client, LM77_REG_CONF, conf & 0xfe);
-}
-
-static struct lm77_data *lm77_update_device(struct device *dev)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm77_data *data = i2c_get_clientdata(client);
-
-	down(&data->update_lock);
-
-	if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
-	    || !data->valid) {
-		dev_dbg(&client->dev, "Starting lm77 update\n");
-		data->temp_input =
-			LM77_TEMP_FROM_REG(lm77_read_value(client,
-							   LM77_REG_TEMP));
-		data->temp_hyst =
-			LM77_TEMP_FROM_REG(lm77_read_value(client,
-							   LM77_REG_TEMP_HYST));
-		data->temp_crit =
-			LM77_TEMP_FROM_REG(lm77_read_value(client,
-							   LM77_REG_TEMP_CRIT));
-		data->temp_min =
-			LM77_TEMP_FROM_REG(lm77_read_value(client,
-							   LM77_REG_TEMP_MIN));
-		data->temp_max =
-			LM77_TEMP_FROM_REG(lm77_read_value(client,
-							   LM77_REG_TEMP_MAX));
-		data->alarms =
-			lm77_read_value(client, LM77_REG_TEMP) & 0x0007;
-		data->last_updated = jiffies;
-		data->valid = 1;
-	}
-
-	up(&data->update_lock);
-
-	return data;
-}
-
-static int __init sensors_lm77_init(void)
-{
-	return i2c_add_driver(&lm77_driver);
-}
-
-static void __exit sensors_lm77_exit(void)
-{
-	i2c_del_driver(&lm77_driver);
-}
-
-MODULE_AUTHOR("Andras BALI <drewie@freemail.hu>");
-MODULE_DESCRIPTION("LM77 driver");
-MODULE_LICENSE("GPL");
-
-module_init(sensors_lm77_init);
-module_exit(sensors_lm77_exit);
diff --git a/drivers/i2c/chips/lm78.c b/drivers/i2c/chips/lm78.c
deleted file mode 100644
--- a/drivers/i2c/chips/lm78.c
+++ /dev/null
@@ -1,796 +0,0 @@
-/*
-    lm78.c - Part of lm_sensors, Linux kernel modules for hardware
-             monitoring
-    Copyright (c) 1998, 1999  Frodo Looijaard <frodol@dds.nl> 
-
-    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 <linux/config.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/jiffies.h>
-#include <linux/i2c.h>
-#include <linux/i2c-sensor.h>
-#include <asm/io.h>
-
-/* Addresses to scan */
-static unsigned short normal_i2c[] = { 0x20, 0x21, 0x22, 0x23, 0x24,
-					0x25, 0x26, 0x27, 0x28, 0x29,
-					0x2a, 0x2b, 0x2c, 0x2d, 0x2e,
-					0x2f, I2C_CLIENT_END };
-static unsigned int normal_isa[] = { 0x0290, I2C_CLIENT_ISA_END };
-
-/* Insmod parameters */
-SENSORS_INSMOD_3(lm78, lm78j, lm79);
-
-/* Many LM78 constants specified below */
-
-/* Length of ISA address segment */
-#define LM78_EXTENT 8
-
-/* Where are the ISA address/data registers relative to the base address */
-#define LM78_ADDR_REG_OFFSET 5
-#define LM78_DATA_REG_OFFSET 6
-
-/* The LM78 registers */
-#define LM78_REG_IN_MAX(nr) (0x2b + (nr) * 2)
-#define LM78_REG_IN_MIN(nr) (0x2c + (nr) * 2)
-#define LM78_REG_IN(nr) (0x20 + (nr))
-
-#define LM78_REG_FAN_MIN(nr) (0x3b + (nr))
-#define LM78_REG_FAN(nr) (0x28 + (nr))
-
-#define LM78_REG_TEMP 0x27
-#define LM78_REG_TEMP_OVER 0x39
-#define LM78_REG_TEMP_HYST 0x3a
-
-#define LM78_REG_ALARM1 0x41
-#define LM78_REG_ALARM2 0x42
-
-#define LM78_REG_VID_FANDIV 0x47
-
-#define LM78_REG_CONFIG 0x40
-#define LM78_REG_CHIPID 0x49
-#define LM78_REG_I2C_ADDR 0x48
-
-
-/* Conversions. Rounding and limit checking is only done on the TO_REG 
-   variants. */
-
-/* IN: mV, (0V to 4.08V)
-   REG: 16mV/bit */
-static inline u8 IN_TO_REG(unsigned long val)
-{
-	unsigned long nval = SENSORS_LIMIT(val, 0, 4080);
-	return (nval + 8) / 16;
-}
-#define IN_FROM_REG(val) ((val) *  16)
-
-static inline u8 FAN_TO_REG(long rpm, int div)
-{
-	if (rpm <= 0)
-		return 255;
-	return SENSORS_LIMIT((1350000 + rpm * div / 2) / (rpm * div), 1, 254);
-}
-
-static inline int FAN_FROM_REG(u8 val, int div)
-{
-	return val==0 ? -1 : val==255 ? 0 : 1350000/(val*div);
-}
-
-/* TEMP: mC (-128C to +127C)
-   REG: 1C/bit, two's complement */
-static inline s8 TEMP_TO_REG(int val)
-{
-	int nval = SENSORS_LIMIT(val, -128000, 127000) ;
-	return nval<0 ? (nval-500)/1000 : (nval+500)/1000;
-}
-
-static inline int TEMP_FROM_REG(s8 val)
-{
-	return val * 1000;
-}
-
-/* VID: mV
-   REG: (see doc/vid) */
-static inline int VID_FROM_REG(u8 val)
-{
-	return val==0x1f ? 0 : val>=0x10 ? 5100-val*100 : 2050-val*50;
-}
-
-#define DIV_FROM_REG(val) (1 << (val))
-
-/* There are some complications in a module like this. First off, LM78 chips
-   may be both present on the SMBus and the ISA bus, and we have to handle
-   those cases separately at some places. Second, there might be several
-   LM78 chips available (well, actually, that is probably never done; but
-   it is a clean illustration of how to handle a case like that). Finally,
-   a specific chip may be attached to *both* ISA and SMBus, and we would
-   not like to detect it double. Fortunately, in the case of the LM78 at
-   least, a register tells us what SMBus address we are on, so that helps
-   a bit - except if there could be more than one SMBus. Groan. No solution
-   for this yet. */
-
-/* This module may seem overly long and complicated. In fact, it is not so
-   bad. Quite a lot of bookkeeping is done. A real driver can often cut
-   some corners. */
-
-/* For each registered LM78, we need to keep some data in memory. That
-   data is pointed to by lm78_list[NR]->data. The structure itself is
-   dynamically allocated, at the same time when a new lm78 client is
-   allocated. */
-struct lm78_data {
-	struct i2c_client client;
-	struct semaphore lock;
-	enum chips type;
-
-	struct semaphore update_lock;
-	char valid;		/* !=0 if following fields are valid */
-	unsigned long last_updated;	/* In jiffies */
-
-	u8 in[7];		/* Register value */
-	u8 in_max[7];		/* Register value */
-	u8 in_min[7];		/* Register value */
-	u8 fan[3];		/* Register value */
-	u8 fan_min[3];		/* Register value */
-	s8 temp;		/* Register value */
-	s8 temp_over;		/* Register value */
-	s8 temp_hyst;		/* Register value */
-	u8 fan_div[3];		/* Register encoding, shifted right */
-	u8 vid;			/* Register encoding, combined */
-	u16 alarms;		/* Register encoding, combined */
-};
-
-
-static int lm78_attach_adapter(struct i2c_adapter *adapter);
-static int lm78_detect(struct i2c_adapter *adapter, int address, int kind);
-static int lm78_detach_client(struct i2c_client *client);
-
-static int lm78_read_value(struct i2c_client *client, u8 register);
-static int lm78_write_value(struct i2c_client *client, u8 register, u8 value);
-static struct lm78_data *lm78_update_device(struct device *dev);
-static void lm78_init_client(struct i2c_client *client);
-
-
-static struct i2c_driver lm78_driver = {
-	.owner		= THIS_MODULE,
-	.name		= "lm78",
-	.id		= I2C_DRIVERID_LM78,
-	.flags		= I2C_DF_NOTIFY,
-	.attach_adapter	= lm78_attach_adapter,
-	.detach_client	= lm78_detach_client,
-};
-
-/* 7 Voltages */
-static ssize_t show_in(struct device *dev, char *buf, int nr)
-{
-	struct lm78_data *data = lm78_update_device(dev);
-	return sprintf(buf, "%d\n", IN_FROM_REG(data->in[nr]));
-}
-
-static ssize_t show_in_min(struct device *dev, char *buf, int nr)
-{
-	struct lm78_data *data = lm78_update_device(dev);
-	return sprintf(buf, "%d\n", IN_FROM_REG(data->in_min[nr]));
-}
-
-static ssize_t show_in_max(struct device *dev, char *buf, int nr)
-{
-	struct lm78_data *data = lm78_update_device(dev);
-	return sprintf(buf, "%d\n", IN_FROM_REG(data->in_max[nr]));
-}
-
-static ssize_t set_in_min(struct device *dev, const char *buf,
-		size_t count, int nr)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm78_data *data = i2c_get_clientdata(client);
-	unsigned long val = simple_strtoul(buf, NULL, 10);
-
-	down(&data->update_lock);
-	data->in_min[nr] = IN_TO_REG(val);
-	lm78_write_value(client, LM78_REG_IN_MIN(nr), data->in_min[nr]);
-	up(&data->update_lock);
-	return count;
-}
-
-static ssize_t set_in_max(struct device *dev, const char *buf,
-		size_t count, int nr)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm78_data *data = i2c_get_clientdata(client);
-	unsigned long val = simple_strtoul(buf, NULL, 10);
-
-	down(&data->update_lock);
-	data->in_max[nr] = IN_TO_REG(val);
-	lm78_write_value(client, LM78_REG_IN_MAX(nr), data->in_max[nr]);
-	up(&data->update_lock);
-	return count;
-}
-	
-#define show_in_offset(offset)					\
-static ssize_t							\
-	show_in##offset (struct device *dev, char *buf)		\
-{								\
-	return show_in(dev, buf, offset);			\
-}								\
-static DEVICE_ATTR(in##offset##_input, S_IRUGO, 		\
-		show_in##offset, NULL);				\
-static ssize_t							\
-	show_in##offset##_min (struct device *dev, char *buf)   \
-{								\
-	return show_in_min(dev, buf, offset);			\
-}								\
-static ssize_t							\
-	show_in##offset##_max (struct device *dev, char *buf)   \
-{								\
-	return show_in_max(dev, buf, offset);			\
-}								\
-static ssize_t set_in##offset##_min (struct device *dev,	\
-		const char *buf, size_t count)			\
-{								\
-	return set_in_min(dev, buf, count, offset);		\
-}								\
-static ssize_t set_in##offset##_max (struct device *dev,	\
-		const char *buf, size_t count)			\
-{								\
-	return set_in_max(dev, buf, count, offset);		\
-}								\
-static DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR,		\
-		show_in##offset##_min, set_in##offset##_min);	\
-static DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR,		\
-		show_in##offset##_max, set_in##offset##_max);
-
-show_in_offset(0);
-show_in_offset(1);
-show_in_offset(2);
-show_in_offset(3);
-show_in_offset(4);
-show_in_offset(5);
-show_in_offset(6);
-
-/* Temperature */
-static ssize_t show_temp(struct device *dev, char *buf)
-{
-	struct lm78_data *data = lm78_update_device(dev);
-	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp));
-}
-
-static ssize_t show_temp_over(struct device *dev, char *buf)
-{
-	struct lm78_data *data = lm78_update_device(dev);
-	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_over));
-}
-
-static ssize_t set_temp_over(struct device *dev, const char *buf, size_t count)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm78_data *data = i2c_get_clientdata(client);
-	long val = simple_strtol(buf, NULL, 10);
-
-	down(&data->update_lock);
-	data->temp_over = TEMP_TO_REG(val);
-	lm78_write_value(client, LM78_REG_TEMP_OVER, data->temp_over);
-	up(&data->update_lock);
-	return count;
-}
-
-static ssize_t show_temp_hyst(struct device *dev, char *buf)
-{
-	struct lm78_data *data = lm78_update_device(dev);
-	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_hyst));
-}
-
-static ssize_t set_temp_hyst(struct device *dev, const char *buf, size_t count)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm78_data *data = i2c_get_clientdata(client);
-	long val = simple_strtol(buf, NULL, 10);
-
-	down(&data->update_lock);
-	data->temp_hyst = TEMP_TO_REG(val);
-	lm78_write_value(client, LM78_REG_TEMP_HYST, data->temp_hyst);
-	up(&data->update_lock);
-	return count;
-}
-
-static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL);
-static DEVICE_ATTR(temp1_max, S_IRUGO | S_IWUSR,
-		show_temp_over, set_temp_over);
-static DEVICE_ATTR(temp1_max_hyst, S_IRUGO | S_IWUSR,
-		show_temp_hyst, set_temp_hyst);
-
-/* 3 Fans */
-static ssize_t show_fan(struct device *dev, char *buf, int nr)
-{
-	struct lm78_data *data = lm78_update_device(dev);
-	return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[nr],
-		DIV_FROM_REG(data->fan_div[nr])) );
-}
-
-static ssize_t show_fan_min(struct device *dev, char *buf, int nr)
-{
-	struct lm78_data *data = lm78_update_device(dev);
-	return sprintf(buf,"%d\n", FAN_FROM_REG(data->fan_min[nr],
-		DIV_FROM_REG(data->fan_div[nr])) );
-}
-
-static ssize_t set_fan_min(struct device *dev, const char *buf,
-		size_t count, int nr)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm78_data *data = i2c_get_clientdata(client);
-	unsigned long val = simple_strtoul(buf, NULL, 10);
-
-	down(&data->update_lock);
-	data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr]));
-	lm78_write_value(client, LM78_REG_FAN_MIN(nr), data->fan_min[nr]);
-	up(&data->update_lock);
-	return count;
-}
-
-static ssize_t show_fan_div(struct device *dev, char *buf, int nr)
-{
-	struct lm78_data *data = lm78_update_device(dev);
-	return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[nr]) );
-}
-
-/* Note: we save and restore the fan minimum here, because its value is
-   determined in part by the fan divisor.  This follows the principle of
-   least suprise; the user doesn't expect the fan minimum to change just
-   because the divisor changed. */
-static ssize_t set_fan_div(struct device *dev, const char *buf,
-	size_t count, int nr)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm78_data *data = i2c_get_clientdata(client);
-	unsigned long val = simple_strtoul(buf, NULL, 10);
-	unsigned long min;
-	u8 reg;
-
-	down(&data->update_lock);
-	min = FAN_FROM_REG(data->fan_min[nr],
-			   DIV_FROM_REG(data->fan_div[nr]));
-
-	switch (val) {
-	case 1: data->fan_div[nr] = 0; break;
-	case 2: data->fan_div[nr] = 1; break;
-	case 4: data->fan_div[nr] = 2; break;
-	case 8: data->fan_div[nr] = 3; break;
-	default:
-		dev_err(&client->dev, "fan_div value %ld not "
-			"supported. Choose one of 1, 2, 4 or 8!\n", val);
-		up(&data->update_lock);
-		return -EINVAL;
-	}
-
-	reg = lm78_read_value(client, LM78_REG_VID_FANDIV);
-	switch (nr) {
-	case 0:
-		reg = (reg & 0xcf) | (data->fan_div[nr] << 4);
-		break;
-	case 1:
-		reg = (reg & 0x3f) | (data->fan_div[nr] << 6);
-		break;
-	}
-	lm78_write_value(client, LM78_REG_VID_FANDIV, reg);
-
-	data->fan_min[nr] =
-		FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr]));
-	lm78_write_value(client, LM78_REG_FAN_MIN(nr), data->fan_min[nr]);
-	up(&data->update_lock);
-
-	return count;
-}
-
-#define show_fan_offset(offset)						\
-static ssize_t show_fan_##offset (struct device *dev, char *buf)	\
-{									\
-	return show_fan(dev, buf, offset - 1);				\
-}									\
-static ssize_t show_fan_##offset##_min (struct device *dev, char *buf)  \
-{									\
-	return show_fan_min(dev, buf, offset - 1);			\
-}									\
-static ssize_t show_fan_##offset##_div (struct device *dev, char *buf)  \
-{									\
-	return show_fan_div(dev, buf, offset - 1);			\
-}									\
-static ssize_t set_fan_##offset##_min (struct device *dev,		\
-		const char *buf, size_t count)				\
-{									\
-	return set_fan_min(dev, buf, count, offset - 1);		\
-}									\
-static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_fan_##offset, NULL);\
-static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR,		\
-		show_fan_##offset##_min, set_fan_##offset##_min);
-
-static ssize_t set_fan_1_div(struct device *dev, const char *buf,
-		size_t count)
-{
-	return set_fan_div(dev, buf, count, 0) ;
-}
-
-static ssize_t set_fan_2_div(struct device *dev, const char *buf,
-		size_t count)
-{
-	return set_fan_div(dev, buf, count, 1) ;
-}
-
-show_fan_offset(1);
-show_fan_offset(2);
-show_fan_offset(3);
-
-/* Fan 3 divisor is locked in H/W */
-static DEVICE_ATTR(fan1_div, S_IRUGO | S_IWUSR,
-		show_fan_1_div, set_fan_1_div);
-static DEVICE_ATTR(fan2_div, S_IRUGO | S_IWUSR,
-		show_fan_2_div, set_fan_2_div);
-static DEVICE_ATTR(fan3_div, S_IRUGO, show_fan_3_div, NULL);
-
-/* VID */
-static ssize_t show_vid(struct device *dev, char *buf)
-{
-	struct lm78_data *data = lm78_update_device(dev);
-	return sprintf(buf, "%d\n", VID_FROM_REG(data->vid));
-}
-static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL);
-
-/* Alarms */
-static ssize_t show_alarms(struct device *dev, char *buf)
-{
-	struct lm78_data *data = lm78_update_device(dev);
-	return sprintf(buf, "%u\n", data->alarms);
-}
-static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
-
-/* This function is called when:
-     * lm78_driver is inserted (when this module is loaded), for each
-       available adapter
-     * when a new adapter is inserted (and lm78_driver is still present) */
-static int lm78_attach_adapter(struct i2c_adapter *adapter)
-{
-	if (!(adapter->class & I2C_CLASS_HWMON))
-		return 0;
-	return i2c_detect(adapter, &addr_data, lm78_detect);
-}
-
-/* This function is called by i2c_detect */
-int lm78_detect(struct i2c_adapter *adapter, int address, int kind)
-{
-	int i, err;
-	struct i2c_client *new_client;
-	struct lm78_data *data;
-	const char *client_name = "";
-	int is_isa = i2c_is_isa_adapter(adapter);
-
-	if (!is_isa &&
-	    !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
-		err = -ENODEV;
-		goto ERROR0;
-	}
-
-	/* Reserve the ISA region */
-	if (is_isa)
-		if (!request_region(address, LM78_EXTENT, lm78_driver.name)) {
-			err = -EBUSY;
-			goto ERROR0;
-		}
-
-	/* Probe whether there is anything available on this address. Already
-	   done for SMBus clients */
-	if (kind < 0) {
-		if (is_isa) {
-
-#define REALLY_SLOW_IO
-			/* We need the timeouts for at least some LM78-like
-			   chips. But only if we read 'undefined' registers. */
-			i = inb_p(address + 1);
-			if (inb_p(address + 2) != i) {
-				err = -ENODEV;
-				goto ERROR1;
-			}
-			if (inb_p(address + 3) != i) {
-				err = -ENODEV;
-				goto ERROR1;
-			}
-			if (inb_p(address + 7) != i) {
-				err = -ENODEV;
-				goto ERROR1;
-			}
-#undef REALLY_SLOW_IO
-
-			/* Let's just hope nothing breaks here */
-			i = inb_p(address + 5) & 0x7f;
-			outb_p(~i & 0x7f, address + 5);
-			if ((inb_p(address + 5) & 0x7f) != (~i & 0x7f)) {
-				outb_p(i, address + 5);
-				err = -ENODEV;
-				goto ERROR1;
-			}
-		}
-	}
-
-	/* OK. For now, we presume we have a valid client. We now create the
-	   client structure, even though we cannot fill it completely yet.
-	   But it allows us to access lm78_{read,write}_value. */
-
-	if (!(data = kmalloc(sizeof(struct lm78_data), GFP_KERNEL))) {
-		err = -ENOMEM;
-		goto ERROR1;
-	}
-	memset(data, 0, sizeof(struct lm78_data));
-
-	new_client = &data->client;
-	if (is_isa)
-		init_MUTEX(&data->lock);
-	i2c_set_clientdata(new_client, data);
-	new_client->addr = address;
-	new_client->adapter = adapter;
-	new_client->driver = &lm78_driver;
-	new_client->flags = 0;
-
-	/* Now, we do the remaining detection. */
-	if (kind < 0) {
-		if (lm78_read_value(new_client, LM78_REG_CONFIG) & 0x80) {
-			err = -ENODEV;
-			goto ERROR2;
-		}
-		if (!is_isa && (lm78_read_value(
-				new_client, LM78_REG_I2C_ADDR) != address)) {
-			err = -ENODEV;
-			goto ERROR2;
-		}
-	}
-
-	/* Determine the chip type. */
-	if (kind <= 0) {
-		i = lm78_read_value(new_client, LM78_REG_CHIPID);
-		if (i == 0x00 || i == 0x20)
-			kind = lm78;
-		else if (i == 0x40)
-			kind = lm78j;
-		else if ((i & 0xfe) == 0xc0)
-			kind = lm79;
-		else {
-			if (kind == 0)
-				dev_warn(&adapter->dev, "Ignoring 'force' "
-					"parameter for unknown chip at "
-					"adapter %d, address 0x%02x\n",
-					i2c_adapter_id(adapter), address);
-			err = -ENODEV;
-			goto ERROR2;
-		}
-	}
-
-	if (kind == lm78) {
-		client_name = "lm78";
-	} else if (kind == lm78j) {
-		client_name = "lm78-j";
-	} else if (kind == lm79) {
-		client_name = "lm79";
-	}
-
-	/* Fill in the remaining client fields and put into the global list */
-	strlcpy(new_client->name, client_name, I2C_NAME_SIZE);
-	data->type = kind;
-
-	data->valid = 0;
-	init_MUTEX(&data->update_lock);
-
-	/* Tell the I2C layer a new client has arrived */
-	if ((err = i2c_attach_client(new_client)))
-		goto ERROR2;
-
-	/* Initialize the LM78 chip */
-	lm78_init_client(new_client);
-
-	/* A few vars need to be filled upon startup */
-	for (i = 0; i < 3; i++) {
-		data->fan_min[i] = lm78_read_value(new_client,
-					LM78_REG_FAN_MIN(i));
-	}
-
-	/* Register sysfs hooks */
-	device_create_file(&new_client->dev, &dev_attr_in0_input);
-	device_create_file(&new_client->dev, &dev_attr_in0_min);
-	device_create_file(&new_client->dev, &dev_attr_in0_max);
-	device_create_file(&new_client->dev, &dev_attr_in1_input);
-	device_create_file(&new_client->dev, &dev_attr_in1_min);
-	device_create_file(&new_client->dev, &dev_attr_in1_max);
-	device_create_file(&new_client->dev, &dev_attr_in2_input);
-	device_create_file(&new_client->dev, &dev_attr_in2_min);
-	device_create_file(&new_client->dev, &dev_attr_in2_max);
-	device_create_file(&new_client->dev, &dev_attr_in3_input);
-	device_create_file(&new_client->dev, &dev_attr_in3_min);
-	device_create_file(&new_client->dev, &dev_attr_in3_max);
-	device_create_file(&new_client->dev, &dev_attr_in4_input);
-	device_create_file(&new_client->dev, &dev_attr_in4_min);
-	device_create_file(&new_client->dev, &dev_attr_in4_max);
-	device_create_file(&new_client->dev, &dev_attr_in5_input);
-	device_create_file(&new_client->dev, &dev_attr_in5_min);
-	device_create_file(&new_client->dev, &dev_attr_in5_max);
-	device_create_file(&new_client->dev, &dev_attr_in6_input);
-	device_create_file(&new_client->dev, &dev_attr_in6_min);
-	device_create_file(&new_client->dev, &dev_attr_in6_max);
-	device_create_file(&new_client->dev, &dev_attr_temp1_input);
-	device_create_file(&new_client->dev, &dev_attr_temp1_max);
-	device_create_file(&new_client->dev, &dev_attr_temp1_max_hyst);
-	device_create_file(&new_client->dev, &dev_attr_fan1_input);
-	device_create_file(&new_client->dev, &dev_attr_fan1_min);
-	device_create_file(&new_client->dev, &dev_attr_fan1_div);
-	device_create_file(&new_client->dev, &dev_attr_fan2_input);
-	device_create_file(&new_client->dev, &dev_attr_fan2_min);
-	device_create_file(&new_client->dev, &dev_attr_fan2_div);
-	device_create_file(&new_client->dev, &dev_attr_fan3_input);
-	device_create_file(&new_client->dev, &dev_attr_fan3_min);
-	device_create_file(&new_client->dev, &dev_attr_fan3_div);
-	device_create_file(&new_client->dev, &dev_attr_alarms);
-	device_create_file(&new_client->dev, &dev_attr_cpu0_vid);
-
-	return 0;
-
-ERROR2:
-	kfree(data);
-ERROR1:
-	if (is_isa)
-		release_region(address, LM78_EXTENT);
-ERROR0:
-	return err;
-}
-
-static int lm78_detach_client(struct i2c_client *client)
-{
-	int err;
-
-	if ((err = i2c_detach_client(client))) {
-		dev_err(&client->dev,
-		    "Client deregistration failed, client not detached.\n");
-		return err;
-	}
-
-	if(i2c_is_isa_client(client))
-		release_region(client->addr, LM78_EXTENT);
-
-	kfree(i2c_get_clientdata(client));
-
-	return 0;
-}
-
-/* The SMBus locks itself, but ISA access must be locked explicitely! 
-   We don't want to lock the whole ISA bus, so we lock each client
-   separately.
-   We ignore the LM78 BUSY flag at this moment - it could lead to deadlocks,
-   would slow down the LM78 access and should not be necessary.  */
-static int lm78_read_value(struct i2c_client *client, u8 reg)
-{
-	int res;
-	if (i2c_is_isa_client(client)) {
-		struct lm78_data *data = i2c_get_clientdata(client);
-		down(&data->lock);
-		outb_p(reg, client->addr + LM78_ADDR_REG_OFFSET);
-		res = inb_p(client->addr + LM78_DATA_REG_OFFSET);
-		up(&data->lock);
-		return res;
-	} else
-		return i2c_smbus_read_byte_data(client, reg);
-}
-
-/* The SMBus locks itself, but ISA access muse be locked explicitely! 
-   We don't want to lock the whole ISA bus, so we lock each client
-   separately.
-   We ignore the LM78 BUSY flag at this moment - it could lead to deadlocks,
-   would slow down the LM78 access and should not be necessary. 
-   There are some ugly typecasts here, but the good new is - they should
-   nowhere else be necessary! */
-static int lm78_write_value(struct i2c_client *client, u8 reg, u8 value)
-{
-	if (i2c_is_isa_client(client)) {
-		struct lm78_data *data = i2c_get_clientdata(client);
-		down(&data->lock);
-		outb_p(reg, client->addr + LM78_ADDR_REG_OFFSET);
-		outb_p(value, client->addr + LM78_DATA_REG_OFFSET);
-		up(&data->lock);
-		return 0;
-	} else
-		return i2c_smbus_write_byte_data(client, reg, value);
-}
-
-/* Called when we have found a new LM78. It should set limits, etc. */
-static void lm78_init_client(struct i2c_client *client)
-{
-	u8 config = lm78_read_value(client, LM78_REG_CONFIG);
-
-	/* Start monitoring */
-	if (!(config & 0x01))
-		lm78_write_value(client, LM78_REG_CONFIG,
-				 (config & 0xf7) | 0x01);
-}
-
-static struct lm78_data *lm78_update_device(struct device *dev)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm78_data *data = i2c_get_clientdata(client);
-	int i;
-
-	down(&data->update_lock);
-
-	if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
-	    || !data->valid) {
-
-		dev_dbg(&client->dev, "Starting lm78 update\n");
-
-		for (i = 0; i <= 6; i++) {
-			data->in[i] =
-			    lm78_read_value(client, LM78_REG_IN(i));
-			data->in_min[i] =
-			    lm78_read_value(client, LM78_REG_IN_MIN(i));
-			data->in_max[i] =
-			    lm78_read_value(client, LM78_REG_IN_MAX(i));
-		}
-		for (i = 0; i < 3; i++) {
-			data->fan[i] =
-			    lm78_read_value(client, LM78_REG_FAN(i));
-			data->fan_min[i] =
-			    lm78_read_value(client, LM78_REG_FAN_MIN(i));
-		}
-		data->temp = lm78_read_value(client, LM78_REG_TEMP);
-		data->temp_over =
-		    lm78_read_value(client, LM78_REG_TEMP_OVER);
-		data->temp_hyst =
-		    lm78_read_value(client, LM78_REG_TEMP_HYST);
-		i = lm78_read_value(client, LM78_REG_VID_FANDIV);
-		data->vid = i & 0x0f;
-		if (data->type == lm79)
-			data->vid |=
-			    (lm78_read_value(client, LM78_REG_CHIPID) &
-			     0x01) << 4;
-		else
-			data->vid |= 0x10;
-		data->fan_div[0] = (i >> 4) & 0x03;
-		data->fan_div[1] = i >> 6;
-		data->alarms = lm78_read_value(client, LM78_REG_ALARM1) +
-		    (lm78_read_value(client, LM78_REG_ALARM2) << 8);
-		data->last_updated = jiffies;
-		data->valid = 1;
-
-		data->fan_div[2] = 1;
-	}
-
-	up(&data->update_lock);
-
-	return data;
-}
-
-static int __init sm_lm78_init(void)
-{
-	return i2c_add_driver(&lm78_driver);
-}
-
-static void __exit sm_lm78_exit(void)
-{
-	i2c_del_driver(&lm78_driver);
-}
-
-
-
-MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>");
-MODULE_DESCRIPTION("LM78, LM78-J and LM79 driver");
-MODULE_LICENSE("GPL");
-
-module_init(sm_lm78_init);
-module_exit(sm_lm78_exit);
diff --git a/drivers/i2c/chips/lm80.c b/drivers/i2c/chips/lm80.c
deleted file mode 100644
--- a/drivers/i2c/chips/lm80.c
+++ /dev/null
@@ -1,602 +0,0 @@
-/*
- * lm80.c - From lm_sensors, Linux kernel modules for hardware
- * monitoring
- * Copyright (C) 1998, 1999  Frodo Looijaard <frodol@dds.nl>
- * and Philip Edelbrock <phil@netroedge.com>
- *
- * Ported to Linux 2.6 by Tiago Sousa <mirage@kaotik.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.
- */
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/jiffies.h>
-#include <linux/i2c.h>
-#include <linux/i2c-sensor.h>
-
-/* Addresses to scan */
-static unsigned short normal_i2c[] = { 0x28, 0x29, 0x2a, 0x2b, 0x2c,
-					0x2d, 0x2e, 0x2f, I2C_CLIENT_END };
-static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
-
-/* Insmod parameters */
-SENSORS_INSMOD_1(lm80);
-
-/* Many LM80 constants specified below */
-
-/* The LM80 registers */
-#define LM80_REG_IN_MAX(nr)		(0x2a + (nr) * 2)
-#define LM80_REG_IN_MIN(nr)		(0x2b + (nr) * 2)
-#define LM80_REG_IN(nr)			(0x20 + (nr))
-
-#define LM80_REG_FAN1			0x28
-#define LM80_REG_FAN2			0x29
-#define LM80_REG_FAN_MIN(nr)		(0x3b + (nr))
-
-#define LM80_REG_TEMP			0x27
-#define LM80_REG_TEMP_HOT_MAX		0x38
-#define LM80_REG_TEMP_HOT_HYST		0x39
-#define LM80_REG_TEMP_OS_MAX		0x3a
-#define LM80_REG_TEMP_OS_HYST		0x3b
-
-#define LM80_REG_CONFIG			0x00
-#define LM80_REG_ALARM1			0x01
-#define LM80_REG_ALARM2			0x02
-#define LM80_REG_MASK1			0x03
-#define LM80_REG_MASK2			0x04
-#define LM80_REG_FANDIV			0x05
-#define LM80_REG_RES			0x06
-
-
-/* Conversions. Rounding and limit checking is only done on the TO_REG
-   variants. Note that you should be a bit careful with which arguments
-   these macros are called: arguments may be evaluated more than once.
-   Fixing this is just not worth it. */
-
-#define IN_TO_REG(val)		(SENSORS_LIMIT(((val)+5)/10,0,255))
-#define IN_FROM_REG(val)	((val)*10)
-
-static inline unsigned char FAN_TO_REG(unsigned rpm, unsigned div)
-{
-	if (rpm == 0)
-		return 255;
-	rpm = SENSORS_LIMIT(rpm, 1, 1000000);
-	return SENSORS_LIMIT((1350000 + rpm*div / 2) / (rpm*div), 1, 254);
-}
-
-#define FAN_FROM_REG(val,div)	((val)==0?-1:\
-				(val)==255?0:1350000/((div)*(val)))
-
-static inline long TEMP_FROM_REG(u16 temp)
-{
-	long res;
-
-	temp >>= 4;
-	if (temp < 0x0800)
-		res = 625 * (long) temp;
-	else
-		res = ((long) temp - 0x01000) * 625;
-
-	return res / 10;
-}
-
-#define TEMP_LIMIT_FROM_REG(val)	(((val)>0x80?(val)-0x100:(val))*1000)
-
-#define TEMP_LIMIT_TO_REG(val)		SENSORS_LIMIT((val)<0?\
-					((val)-500)/1000:((val)+500)/1000,0,255)
-
-#define DIV_FROM_REG(val)		(1 << (val))
-
-/*
- * Client data (each client gets its own)
- */
-
-struct lm80_data {
-	struct i2c_client client;
-	struct semaphore update_lock;
-	char valid;		/* !=0 if following fields are valid */
-	unsigned long last_updated;	/* In jiffies */
-
-	u8 in[7];		/* Register value */
-	u8 in_max[7];		/* Register value */
-	u8 in_min[7];		/* Register value */
-	u8 fan[2];		/* Register value */
-	u8 fan_min[2];		/* Register value */
-	u8 fan_div[2];		/* Register encoding, shifted right */
-	u16 temp;		/* Register values, shifted right */
-	u8 temp_hot_max;	/* Register value */
-	u8 temp_hot_hyst;	/* Register value */
-	u8 temp_os_max;		/* Register value */
-	u8 temp_os_hyst;	/* Register value */
-	u16 alarms;		/* Register encoding, combined */
-};
-
-/* 
- * Functions declaration
- */
-
-static int lm80_attach_adapter(struct i2c_adapter *adapter);
-static int lm80_detect(struct i2c_adapter *adapter, int address, int kind);
-static void lm80_init_client(struct i2c_client *client);
-static int lm80_detach_client(struct i2c_client *client);
-static struct lm80_data *lm80_update_device(struct device *dev);
-static int lm80_read_value(struct i2c_client *client, u8 reg);
-static int lm80_write_value(struct i2c_client *client, u8 reg, u8 value);
-
-/*
- * Driver data (common to all clients)
- */
-
-static struct i2c_driver lm80_driver = {
-	.owner		= THIS_MODULE,
-	.name		= "lm80",
-	.id		= I2C_DRIVERID_LM80,
-	.flags		= I2C_DF_NOTIFY,
-	.attach_adapter	= lm80_attach_adapter,
-	.detach_client	= lm80_detach_client,
-};
-
-/*
- * Sysfs stuff
- */
-
-#define show_in(suffix, value) \
-static ssize_t show_in_##suffix(struct device *dev, char *buf) \
-{ \
-	struct lm80_data *data = lm80_update_device(dev); \
-	return sprintf(buf, "%d\n", IN_FROM_REG(data->value)); \
-}
-show_in(min0, in_min[0]);
-show_in(min1, in_min[1]);
-show_in(min2, in_min[2]);
-show_in(min3, in_min[3]);
-show_in(min4, in_min[4]);
-show_in(min5, in_min[5]);
-show_in(min6, in_min[6]);
-show_in(max0, in_max[0]);
-show_in(max1, in_max[1]);
-show_in(max2, in_max[2]);
-show_in(max3, in_max[3]);
-show_in(max4, in_max[4]);
-show_in(max5, in_max[5]);
-show_in(max6, in_max[6]);
-show_in(input0, in[0]);
-show_in(input1, in[1]);
-show_in(input2, in[2]);
-show_in(input3, in[3]);
-show_in(input4, in[4]);
-show_in(input5, in[5]);
-show_in(input6, in[6]);
-
-#define set_in(suffix, value, reg) \
-static ssize_t set_in_##suffix(struct device *dev, const char *buf, \
-	size_t count) \
-{ \
-	struct i2c_client *client = to_i2c_client(dev); \
-	struct lm80_data *data = i2c_get_clientdata(client); \
-	long val = simple_strtol(buf, NULL, 10); \
- \
-	down(&data->update_lock);\
-	data->value = IN_TO_REG(val); \
-	lm80_write_value(client, reg, data->value); \
-	up(&data->update_lock);\
-	return count; \
-}
-set_in(min0, in_min[0], LM80_REG_IN_MIN(0));
-set_in(min1, in_min[1], LM80_REG_IN_MIN(1));
-set_in(min2, in_min[2], LM80_REG_IN_MIN(2));
-set_in(min3, in_min[3], LM80_REG_IN_MIN(3));
-set_in(min4, in_min[4], LM80_REG_IN_MIN(4));
-set_in(min5, in_min[5], LM80_REG_IN_MIN(5));
-set_in(min6, in_min[6], LM80_REG_IN_MIN(6));
-set_in(max0, in_max[0], LM80_REG_IN_MAX(0));
-set_in(max1, in_max[1], LM80_REG_IN_MAX(1));
-set_in(max2, in_max[2], LM80_REG_IN_MAX(2));
-set_in(max3, in_max[3], LM80_REG_IN_MAX(3));
-set_in(max4, in_max[4], LM80_REG_IN_MAX(4));
-set_in(max5, in_max[5], LM80_REG_IN_MAX(5));
-set_in(max6, in_max[6], LM80_REG_IN_MAX(6));
-
-#define show_fan(suffix, value, div) \
-static ssize_t show_fan_##suffix(struct device *dev, char *buf) \
-{ \
-	struct lm80_data *data = lm80_update_device(dev); \
-	return sprintf(buf, "%d\n", FAN_FROM_REG(data->value, \
-		       DIV_FROM_REG(data->div))); \
-}
-show_fan(min1, fan_min[0], fan_div[0]);
-show_fan(min2, fan_min[1], fan_div[1]);
-show_fan(input1, fan[0], fan_div[0]);
-show_fan(input2, fan[1], fan_div[1]);
-
-#define show_fan_div(suffix, value) \
-static ssize_t show_fan_div##suffix(struct device *dev, char *buf) \
-{ \
-	struct lm80_data *data = lm80_update_device(dev); \
-	return sprintf(buf, "%d\n", DIV_FROM_REG(data->value)); \
-}
-show_fan_div(1, fan_div[0]);
-show_fan_div(2, fan_div[1]);
-
-#define set_fan(suffix, value, reg, div) \
-static ssize_t set_fan_##suffix(struct device *dev, const char *buf, \
-	size_t count) \
-{ \
-	struct i2c_client *client = to_i2c_client(dev); \
-	struct lm80_data *data = i2c_get_clientdata(client); \
-	long val = simple_strtoul(buf, NULL, 10); \
- \
-	down(&data->update_lock);\
-	data->value = FAN_TO_REG(val, DIV_FROM_REG(data->div)); \
-	lm80_write_value(client, reg, data->value); \
-	up(&data->update_lock);\
-	return count; \
-}
-set_fan(min1, fan_min[0], LM80_REG_FAN_MIN(1), fan_div[0]);
-set_fan(min2, fan_min[1], LM80_REG_FAN_MIN(2), fan_div[1]);
-
-/* Note: we save and restore the fan minimum here, because its value is
-   determined in part by the fan divisor.  This follows the principle of
-   least suprise; the user doesn't expect the fan minimum to change just
-   because the divisor changed. */
-static ssize_t set_fan_div(struct device *dev, const char *buf,
-	size_t count, int nr)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm80_data *data = i2c_get_clientdata(client);
-	unsigned long min, val = simple_strtoul(buf, NULL, 10);
-	u8 reg;
-
-	/* Save fan_min */
-	down(&data->update_lock);
-	min = FAN_FROM_REG(data->fan_min[nr],
-			   DIV_FROM_REG(data->fan_div[nr]));
-
-	switch (val) {
-	case 1: data->fan_div[nr] = 0; break;
-	case 2: data->fan_div[nr] = 1; break;
-	case 4: data->fan_div[nr] = 2; break;
-	case 8: data->fan_div[nr] = 3; break;
-	default:
-		dev_err(&client->dev, "fan_div value %ld not "
-			"supported. Choose one of 1, 2, 4 or 8!\n", val);
-		up(&data->update_lock);
-		return -EINVAL;
-	}
-
-	reg = (lm80_read_value(client, LM80_REG_FANDIV) & ~(3 << (2 * (nr + 1))))
-	    | (data->fan_div[nr] << (2 * (nr + 1)));
-	lm80_write_value(client, LM80_REG_FANDIV, reg);
-
-	/* Restore fan_min */
-	data->fan_min[nr] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr]));
-	lm80_write_value(client, LM80_REG_FAN_MIN(nr + 1), data->fan_min[nr]);
-	up(&data->update_lock);
-
-	return count;
-}
-
-#define set_fan_div(number) \
-static ssize_t set_fan_div##number(struct device *dev, const char *buf, \
-	size_t count) \
-{ \
-	return set_fan_div(dev, buf, count, number - 1); \
-}
-set_fan_div(1);
-set_fan_div(2);
-
-static ssize_t show_temp_input1(struct device *dev, char *buf)
-{
-	struct lm80_data *data = lm80_update_device(dev);
-	return sprintf(buf, "%ld\n", TEMP_FROM_REG(data->temp));
-}
-
-#define show_temp(suffix, value) \
-static ssize_t show_temp_##suffix(struct device *dev, char *buf) \
-{ \
-	struct lm80_data *data = lm80_update_device(dev); \
-	return sprintf(buf, "%d\n", TEMP_LIMIT_FROM_REG(data->value)); \
-}
-show_temp(hot_max, temp_hot_max);
-show_temp(hot_hyst, temp_hot_hyst);
-show_temp(os_max, temp_os_max);
-show_temp(os_hyst, temp_os_hyst);
-
-#define set_temp(suffix, value, reg) \
-static ssize_t set_temp_##suffix(struct device *dev, const char *buf, \
-	size_t count) \
-{ \
-	struct i2c_client *client = to_i2c_client(dev); \
-	struct lm80_data *data = i2c_get_clientdata(client); \
-	long val = simple_strtoul(buf, NULL, 10); \
- \
-	down(&data->update_lock); \
-	data->value = TEMP_LIMIT_TO_REG(val); \
-	lm80_write_value(client, reg, data->value); \
-	up(&data->update_lock); \
-	return count; \
-}
-set_temp(hot_max, temp_hot_max, LM80_REG_TEMP_HOT_MAX);
-set_temp(hot_hyst, temp_hot_hyst, LM80_REG_TEMP_HOT_HYST);
-set_temp(os_max, temp_os_max, LM80_REG_TEMP_OS_MAX);
-set_temp(os_hyst, temp_os_hyst, LM80_REG_TEMP_OS_HYST);
-
-static ssize_t show_alarms(struct device *dev, char *buf)
-{
-	struct lm80_data *data = lm80_update_device(dev);
-	return sprintf(buf, "%u\n", data->alarms);
-}
-
-static DEVICE_ATTR(in0_min, S_IWUSR | S_IRUGO, show_in_min0, set_in_min0);
-static DEVICE_ATTR(in1_min, S_IWUSR | S_IRUGO, show_in_min1, set_in_min1);
-static DEVICE_ATTR(in2_min, S_IWUSR | S_IRUGO, show_in_min2, set_in_min2);
-static DEVICE_ATTR(in3_min, S_IWUSR | S_IRUGO, show_in_min3, set_in_min3);
-static DEVICE_ATTR(in4_min, S_IWUSR | S_IRUGO, show_in_min4, set_in_min4);
-static DEVICE_ATTR(in5_min, S_IWUSR | S_IRUGO, show_in_min5, set_in_min5);
-static DEVICE_ATTR(in6_min, S_IWUSR | S_IRUGO, show_in_min6, set_in_min6);
-static DEVICE_ATTR(in0_max, S_IWUSR | S_IRUGO, show_in_max0, set_in_max0);
-static DEVICE_ATTR(in1_max, S_IWUSR | S_IRUGO, show_in_max1, set_in_max1);
-static DEVICE_ATTR(in2_max, S_IWUSR | S_IRUGO, show_in_max2, set_in_max2);
-static DEVICE_ATTR(in3_max, S_IWUSR | S_IRUGO, show_in_max3, set_in_max3);
-static DEVICE_ATTR(in4_max, S_IWUSR | S_IRUGO, show_in_max4, set_in_max4);
-static DEVICE_ATTR(in5_max, S_IWUSR | S_IRUGO, show_in_max5, set_in_max5);
-static DEVICE_ATTR(in6_max, S_IWUSR | S_IRUGO, show_in_max6, set_in_max6);
-static DEVICE_ATTR(in0_input, S_IRUGO, show_in_input0, NULL);
-static DEVICE_ATTR(in1_input, S_IRUGO, show_in_input1, NULL);
-static DEVICE_ATTR(in2_input, S_IRUGO, show_in_input2, NULL);
-static DEVICE_ATTR(in3_input, S_IRUGO, show_in_input3, NULL);
-static DEVICE_ATTR(in4_input, S_IRUGO, show_in_input4, NULL);
-static DEVICE_ATTR(in5_input, S_IRUGO, show_in_input5, NULL);
-static DEVICE_ATTR(in6_input, S_IRUGO, show_in_input6, NULL);
-static DEVICE_ATTR(fan1_min, S_IWUSR | S_IRUGO, show_fan_min1,
-    set_fan_min1);
-static DEVICE_ATTR(fan2_min, S_IWUSR | S_IRUGO, show_fan_min2,
-    set_fan_min2);
-static DEVICE_ATTR(fan1_input, S_IRUGO, show_fan_input1, NULL);
-static DEVICE_ATTR(fan2_input, S_IRUGO, show_fan_input2, NULL);
-static DEVICE_ATTR(fan1_div, S_IWUSR | S_IRUGO, show_fan_div1, set_fan_div1);
-static DEVICE_ATTR(fan2_div, S_IWUSR | S_IRUGO, show_fan_div2, set_fan_div2);
-static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp_input1, NULL);
-static DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp_hot_max,
-    set_temp_hot_max);
-static DEVICE_ATTR(temp1_max_hyst, S_IWUSR | S_IRUGO, show_temp_hot_hyst,
-    set_temp_hot_hyst);
-static DEVICE_ATTR(temp1_crit, S_IWUSR | S_IRUGO, show_temp_os_max,
-    set_temp_os_max);
-static DEVICE_ATTR(temp1_crit_hyst, S_IWUSR | S_IRUGO, show_temp_os_hyst,
-    set_temp_os_hyst);
-static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
-
-/*
- * Real code
- */
-
-static int lm80_attach_adapter(struct i2c_adapter *adapter)
-{
-	if (!(adapter->class & I2C_CLASS_HWMON))
-		return 0;
-	return i2c_detect(adapter, &addr_data, lm80_detect);
-}
-
-int lm80_detect(struct i2c_adapter *adapter, int address, int kind)
-{
-	int i, cur;
-	struct i2c_client *new_client;
-	struct lm80_data *data;
-	int err = 0;
-	const char *name;
-
-	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
-		goto exit;
-
-	/* OK. For now, we presume we have a valid client. We now create the
-	   client structure, even though we cannot fill it completely yet.
-	   But it allows us to access lm80_{read,write}_value. */
-	if (!(data = kmalloc(sizeof(struct lm80_data), GFP_KERNEL))) {
-		err = -ENOMEM;
-		goto exit;
-	}
-	memset(data, 0, sizeof(struct lm80_data));
-
-	new_client = &data->client;
-	i2c_set_clientdata(new_client, data);
-	new_client->addr = address;
-	new_client->adapter = adapter;
-	new_client->driver = &lm80_driver;
-	new_client->flags = 0;
-
-	/* Now, we do the remaining detection. It is lousy. */
-	if (lm80_read_value(new_client, LM80_REG_ALARM2) & 0xc0)
-		goto error_free;
-	for (i = 0x2a; i <= 0x3d; i++) {
-		cur = i2c_smbus_read_byte_data(new_client, i);
-		if ((i2c_smbus_read_byte_data(new_client, i + 0x40) != cur)
-		 || (i2c_smbus_read_byte_data(new_client, i + 0x80) != cur)
-		 || (i2c_smbus_read_byte_data(new_client, i + 0xc0) != cur))
-		    goto error_free;
-	}
-
-	/* Determine the chip type - only one kind supported! */
-	kind = lm80;
-	name = "lm80";
-
-	/* Fill in the remaining client fields and put it into the global list */
-	strlcpy(new_client->name, name, I2C_NAME_SIZE);
-	data->valid = 0;
-	init_MUTEX(&data->update_lock);
-
-	/* Tell the I2C layer a new client has arrived */
-	if ((err = i2c_attach_client(new_client)))
-		goto error_free;
-
-	/* Initialize the LM80 chip */
-	lm80_init_client(new_client);
-
-	/* A few vars need to be filled upon startup */
-	data->fan_min[0] = lm80_read_value(new_client, LM80_REG_FAN_MIN(1));
-	data->fan_min[1] = lm80_read_value(new_client, LM80_REG_FAN_MIN(2));
-
-	/* Register sysfs hooks */
-	device_create_file(&new_client->dev, &dev_attr_in0_min);
-	device_create_file(&new_client->dev, &dev_attr_in1_min);
-	device_create_file(&new_client->dev, &dev_attr_in2_min);
-	device_create_file(&new_client->dev, &dev_attr_in3_min);
-	device_create_file(&new_client->dev, &dev_attr_in4_min);
-	device_create_file(&new_client->dev, &dev_attr_in5_min);
-	device_create_file(&new_client->dev, &dev_attr_in6_min);
-	device_create_file(&new_client->dev, &dev_attr_in0_max);
-	device_create_file(&new_client->dev, &dev_attr_in1_max);
-	device_create_file(&new_client->dev, &dev_attr_in2_max);
-	device_create_file(&new_client->dev, &dev_attr_in3_max);
-	device_create_file(&new_client->dev, &dev_attr_in4_max);
-	device_create_file(&new_client->dev, &dev_attr_in5_max);
-	device_create_file(&new_client->dev, &dev_attr_in6_max);
-	device_create_file(&new_client->dev, &dev_attr_in0_input);
-	device_create_file(&new_client->dev, &dev_attr_in1_input);
-	device_create_file(&new_client->dev, &dev_attr_in2_input);
-	device_create_file(&new_client->dev, &dev_attr_in3_input);
-	device_create_file(&new_client->dev, &dev_attr_in4_input);
-	device_create_file(&new_client->dev, &dev_attr_in5_input);
-	device_create_file(&new_client->dev, &dev_attr_in6_input);
-	device_create_file(&new_client->dev, &dev_attr_fan1_min);
-	device_create_file(&new_client->dev, &dev_attr_fan2_min);
-	device_create_file(&new_client->dev, &dev_attr_fan1_input);
-	device_create_file(&new_client->dev, &dev_attr_fan2_input);
-	device_create_file(&new_client->dev, &dev_attr_fan1_div);
-	device_create_file(&new_client->dev, &dev_attr_fan2_div);
-	device_create_file(&new_client->dev, &dev_attr_temp1_input);
-	device_create_file(&new_client->dev, &dev_attr_temp1_max);
-	device_create_file(&new_client->dev, &dev_attr_temp1_max_hyst);
-	device_create_file(&new_client->dev, &dev_attr_temp1_crit);
-	device_create_file(&new_client->dev, &dev_attr_temp1_crit_hyst);
-	device_create_file(&new_client->dev, &dev_attr_alarms);
-
-	return 0;
-
-error_free:
-	kfree(data);
-exit:
-	return err;
-}
-
-static int lm80_detach_client(struct i2c_client *client)
-{
-	int err;
-
-	if ((err = i2c_detach_client(client))) {
-		dev_err(&client->dev, "Client deregistration failed, "
-			"client not detached.\n");
-		return err;
-	}
-
-	kfree(i2c_get_clientdata(client));
-	return 0;
-}
-
-static int lm80_read_value(struct i2c_client *client, u8 reg)
-{
-	return i2c_smbus_read_byte_data(client, reg);
-}
-
-static int lm80_write_value(struct i2c_client *client, u8 reg, u8 value)
-{
-	return i2c_smbus_write_byte_data(client, reg, value);
-}
-
-/* Called when we have found a new LM80. */
-static void lm80_init_client(struct i2c_client *client)
-{
-	/* Reset all except Watchdog values and last conversion values
-	   This sets fan-divs to 2, among others. This makes most other
-	   initializations unnecessary */
-	lm80_write_value(client, LM80_REG_CONFIG, 0x80);
-	/* Set 11-bit temperature resolution */
-	lm80_write_value(client, LM80_REG_RES, 0x08);
-
-	/* Start monitoring */
-	lm80_write_value(client, LM80_REG_CONFIG, 0x01);
-}
-
-static struct lm80_data *lm80_update_device(struct device *dev)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm80_data *data = i2c_get_clientdata(client);
-	int i;
-
-	down(&data->update_lock);
-
-	if (time_after(jiffies, data->last_updated + 2 * HZ) || !data->valid) {
-		dev_dbg(&client->dev, "Starting lm80 update\n");
-		for (i = 0; i <= 6; i++) {
-			data->in[i] =
-			    lm80_read_value(client, LM80_REG_IN(i));
-			data->in_min[i] =
-			    lm80_read_value(client, LM80_REG_IN_MIN(i));
-			data->in_max[i] =
-			    lm80_read_value(client, LM80_REG_IN_MAX(i));
-		}
-		data->fan[0] = lm80_read_value(client, LM80_REG_FAN1);
-		data->fan_min[0] =
-		    lm80_read_value(client, LM80_REG_FAN_MIN(1));
-		data->fan[1] = lm80_read_value(client, LM80_REG_FAN2);
-		data->fan_min[1] =
-		    lm80_read_value(client, LM80_REG_FAN_MIN(2));
-
-		data->temp =
-		    (lm80_read_value(client, LM80_REG_TEMP) << 8) |
-		    (lm80_read_value(client, LM80_REG_RES) & 0xf0);
-		data->temp_os_max =
-		    lm80_read_value(client, LM80_REG_TEMP_OS_MAX);
-		data->temp_os_hyst =
-		    lm80_read_value(client, LM80_REG_TEMP_OS_HYST);
-		data->temp_hot_max =
-		    lm80_read_value(client, LM80_REG_TEMP_HOT_MAX);
-		data->temp_hot_hyst =
-		    lm80_read_value(client, LM80_REG_TEMP_HOT_HYST);
-
-		i = lm80_read_value(client, LM80_REG_FANDIV);
-		data->fan_div[0] = (i >> 2) & 0x03;
-		data->fan_div[1] = (i >> 4) & 0x03;
-		data->alarms = lm80_read_value(client, LM80_REG_ALARM1) +
-		    (lm80_read_value(client, LM80_REG_ALARM2) << 8);
-		data->last_updated = jiffies;
-		data->valid = 1;
-	}
-
-	up(&data->update_lock);
-
-	return data;
-}
-
-static int __init sensors_lm80_init(void)
-{
-	return i2c_add_driver(&lm80_driver);
-}
-
-static void __exit sensors_lm80_exit(void)
-{
-	i2c_del_driver(&lm80_driver);
-}
-
-MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl> and "
-	"Philip Edelbrock <phil@netroedge.com>");
-MODULE_DESCRIPTION("LM80 driver");
-MODULE_LICENSE("GPL");
-
-module_init(sensors_lm80_init);
-module_exit(sensors_lm80_exit);
diff --git a/drivers/i2c/chips/lm83.c b/drivers/i2c/chips/lm83.c
deleted file mode 100644
--- a/drivers/i2c/chips/lm83.c
+++ /dev/null
@@ -1,412 +0,0 @@
-/*
- * lm83.c - Part of lm_sensors, Linux kernel modules for hardware
- *          monitoring
- * Copyright (C) 2003  Jean Delvare <khali@linux-fr.org>
- *
- * Heavily inspired from the lm78, lm75 and adm1021 drivers. The LM83 is
- * a sensor chip made by National Semiconductor. It reports up to four
- * temperatures (its own plus up to three external ones) with a 1 deg
- * resolution and a 3-4 deg accuracy. Complete datasheet can be obtained
- * from National's website at:
- *   http://www.national.com/pf/LM/LM83.html
- * Since the datasheet omits to give the chip stepping code, I give it
- * here: 0x03 (at register 0xff).
- *
- * 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 <linux/config.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/jiffies.h>
-#include <linux/i2c.h>
-#include <linux/i2c-sensor.h>
-
-/*
- * Addresses to scan
- * Address is selected using 2 three-level pins, resulting in 9 possible
- * addresses.
- */
-
-static unsigned short normal_i2c[] = { 0x18, 0x19, 0x1a,
-					0x29, 0x2a, 0x2b,
-					0x4c, 0x4d, 0x4e,
-					I2C_CLIENT_END };
-static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
-
-/*
- * Insmod parameters
- */
-
-SENSORS_INSMOD_1(lm83);
-
-/*
- * The LM83 registers
- * Manufacturer ID is 0x01 for National Semiconductor.
- */
-
-#define LM83_REG_R_MAN_ID		0xFE
-#define LM83_REG_R_CHIP_ID		0xFF
-#define LM83_REG_R_CONFIG		0x03
-#define LM83_REG_W_CONFIG		0x09
-#define LM83_REG_R_STATUS1		0x02
-#define LM83_REG_R_STATUS2		0x35
-#define LM83_REG_R_LOCAL_TEMP		0x00
-#define LM83_REG_R_LOCAL_HIGH		0x05
-#define LM83_REG_W_LOCAL_HIGH		0x0B
-#define LM83_REG_R_REMOTE1_TEMP		0x30
-#define LM83_REG_R_REMOTE1_HIGH		0x38
-#define LM83_REG_W_REMOTE1_HIGH		0x50
-#define LM83_REG_R_REMOTE2_TEMP		0x01
-#define LM83_REG_R_REMOTE2_HIGH		0x07
-#define LM83_REG_W_REMOTE2_HIGH		0x0D
-#define LM83_REG_R_REMOTE3_TEMP		0x31
-#define LM83_REG_R_REMOTE3_HIGH		0x3A
-#define LM83_REG_W_REMOTE3_HIGH		0x52
-#define LM83_REG_R_TCRIT		0x42
-#define LM83_REG_W_TCRIT		0x5A
-
-/*
- * Conversions and various macros
- * The LM83 uses signed 8-bit values with LSB = 1 degree Celcius.
- */
-
-#define TEMP_FROM_REG(val)	((val) * 1000)
-#define TEMP_TO_REG(val)	((val) <= -128000 ? -128 : \
-				 (val) >= 127000 ? 127 : \
-				 (val) < 0 ? ((val) - 500) / 1000 : \
-				 ((val) + 500) / 1000)
-
-static const u8 LM83_REG_R_TEMP[] = {
-	LM83_REG_R_LOCAL_TEMP,
-	LM83_REG_R_REMOTE1_TEMP,
-	LM83_REG_R_REMOTE2_TEMP,
-	LM83_REG_R_REMOTE3_TEMP
-};
-
-static const u8 LM83_REG_R_HIGH[] = {
-	LM83_REG_R_LOCAL_HIGH,
-	LM83_REG_R_REMOTE1_HIGH,
-	LM83_REG_R_REMOTE2_HIGH,
-	LM83_REG_R_REMOTE3_HIGH
-};
-
-static const u8 LM83_REG_W_HIGH[] = {
-	LM83_REG_W_LOCAL_HIGH,
-	LM83_REG_W_REMOTE1_HIGH,
-	LM83_REG_W_REMOTE2_HIGH,
-	LM83_REG_W_REMOTE3_HIGH
-};
-
-/*
- * Functions declaration
- */
-
-static int lm83_attach_adapter(struct i2c_adapter *adapter);
-static int lm83_detect(struct i2c_adapter *adapter, int address, int kind);
-static int lm83_detach_client(struct i2c_client *client);
-static struct lm83_data *lm83_update_device(struct device *dev);
-
-/*
- * Driver data (common to all clients)
- */
- 
-static struct i2c_driver lm83_driver = {
-	.owner		= THIS_MODULE,
-	.name		= "lm83",
-	.id		= I2C_DRIVERID_LM83,
-	.flags		= I2C_DF_NOTIFY,
-	.attach_adapter	= lm83_attach_adapter,
-	.detach_client	= lm83_detach_client,
-};
-
-/*
- * Client data (each client gets its own)
- */
-
-struct lm83_data {
-	struct i2c_client client;
-	struct semaphore update_lock;
-	char valid; /* zero until following fields are valid */
-	unsigned long last_updated; /* in jiffies */
-
-	/* registers values */
-	s8 temp_input[4];
-	s8 temp_high[4];
-	s8 temp_crit;
-	u16 alarms; /* bitvector, combined */
-};
-
-/*
- * Sysfs stuff
- */
-
-#define show_temp(suffix, value) \
-static ssize_t show_temp_##suffix(struct device *dev, char *buf) \
-{ \
-	struct lm83_data *data = lm83_update_device(dev); \
-	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->value)); \
-}
-show_temp(input1, temp_input[0]);
-show_temp(input2, temp_input[1]);
-show_temp(input3, temp_input[2]);
-show_temp(input4, temp_input[3]);
-show_temp(high1, temp_high[0]);
-show_temp(high2, temp_high[1]);
-show_temp(high3, temp_high[2]);
-show_temp(high4, temp_high[3]);
-show_temp(crit, temp_crit);
-
-#define set_temp(suffix, value, reg) \
-static ssize_t set_temp_##suffix(struct device *dev, const char *buf, \
-	size_t count) \
-{ \
-	struct i2c_client *client = to_i2c_client(dev); \
-	struct lm83_data *data = i2c_get_clientdata(client); \
-	long val = simple_strtol(buf, NULL, 10); \
- \
-	down(&data->update_lock); \
-	data->value = TEMP_TO_REG(val); \
-	i2c_smbus_write_byte_data(client, reg, data->value); \
-	up(&data->update_lock); \
-	return count; \
-}
-set_temp(high1, temp_high[0], LM83_REG_W_LOCAL_HIGH);
-set_temp(high2, temp_high[1], LM83_REG_W_REMOTE1_HIGH);
-set_temp(high3, temp_high[2], LM83_REG_W_REMOTE2_HIGH);
-set_temp(high4, temp_high[3], LM83_REG_W_REMOTE3_HIGH);
-set_temp(crit, temp_crit, LM83_REG_W_TCRIT);
-
-static ssize_t show_alarms(struct device *dev, char *buf)
-{
-	struct lm83_data *data = lm83_update_device(dev);
-	return sprintf(buf, "%d\n", data->alarms);
-}
-
-static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp_input1, NULL);
-static DEVICE_ATTR(temp2_input, S_IRUGO, show_temp_input2, NULL);
-static DEVICE_ATTR(temp3_input, S_IRUGO, show_temp_input3, NULL);
-static DEVICE_ATTR(temp4_input, S_IRUGO, show_temp_input4, NULL);
-static DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp_high1,
-    set_temp_high1);
-static DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_temp_high2,
-    set_temp_high2);
-static DEVICE_ATTR(temp3_max, S_IWUSR | S_IRUGO, show_temp_high3,
-    set_temp_high3);
-static DEVICE_ATTR(temp4_max, S_IWUSR | S_IRUGO, show_temp_high4,
-    set_temp_high4);
-static DEVICE_ATTR(temp1_crit, S_IRUGO, show_temp_crit, NULL);
-static DEVICE_ATTR(temp2_crit, S_IRUGO, show_temp_crit, NULL);
-static DEVICE_ATTR(temp3_crit, S_IWUSR | S_IRUGO, show_temp_crit,
-    set_temp_crit);
-static DEVICE_ATTR(temp4_crit, S_IRUGO, show_temp_crit, NULL);
-static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
-
-/*
- * Real code
- */
-
-static int lm83_attach_adapter(struct i2c_adapter *adapter)
-{
-	if (!(adapter->class & I2C_CLASS_HWMON))
-		return 0;
-	return i2c_detect(adapter, &addr_data, lm83_detect);
-}
-
-/*
- * The following function does more than just detection. If detection
- * succeeds, it also registers the new chip.
- */
-static int lm83_detect(struct i2c_adapter *adapter, int address, int kind)
-{
-	struct i2c_client *new_client;
-	struct lm83_data *data;
-	int err = 0;
-	const char *name = "";
-
-	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
-		goto exit;
-
-	if (!(data = kmalloc(sizeof(struct lm83_data), GFP_KERNEL))) {
-		err = -ENOMEM;
-		goto exit;
-	}
-	memset(data, 0, sizeof(struct lm83_data));
-
-	/* The common I2C client data is placed right after the
-	 * LM83-specific data. */
-	new_client = &data->client;
-	i2c_set_clientdata(new_client, data);
-	new_client->addr = address;
-	new_client->adapter = adapter;
-	new_client->driver = &lm83_driver;
-	new_client->flags = 0;
-
-	/* Now we do the detection and identification. A negative kind
-	 * means that the driver was loaded with no force parameter
-	 * (default), so we must both detect and identify the chip
-	 * (actually there is only one possible kind of chip for now, LM83).
-	 * A zero kind means that the driver was loaded with the force
-	 * parameter, the detection step shall be skipped. A positive kind
-	 * means that the driver was loaded with the force parameter and a
-	 * given kind of chip is requested, so both the detection and the
-	 * identification steps are skipped. */
-
-	/* Default to an LM83 if forced */
-	if (kind == 0)
-		kind = lm83;
-
-	if (kind < 0) { /* detection */
-		if (((i2c_smbus_read_byte_data(new_client, LM83_REG_R_STATUS1)
-		    & 0xA8) != 0x00) ||
-		    ((i2c_smbus_read_byte_data(new_client, LM83_REG_R_STATUS2)
-		    & 0x48) != 0x00) ||
-		    ((i2c_smbus_read_byte_data(new_client, LM83_REG_R_CONFIG)
-		    & 0x41) != 0x00)) {
-			dev_dbg(&adapter->dev,
-			    "LM83 detection failed at 0x%02x.\n", address);
-			goto exit_free;
-		}
-	}
-
-	if (kind <= 0) { /* identification */
-		u8 man_id, chip_id;
-
-		man_id = i2c_smbus_read_byte_data(new_client,
-		    LM83_REG_R_MAN_ID);
-		chip_id = i2c_smbus_read_byte_data(new_client,
-		    LM83_REG_R_CHIP_ID);
-
-		if (man_id == 0x01) { /* National Semiconductor */
-			if (chip_id == 0x03) {
-				kind = lm83;
-			}
-		}
-
-		if (kind <= 0) { /* identification failed */
-			dev_info(&adapter->dev,
-			    "Unsupported chip (man_id=0x%02X, "
-			    "chip_id=0x%02X).\n", man_id, chip_id);
-			goto exit_free;
-		}
-	}
-
-	if (kind == lm83) {
-		name = "lm83";
-	}
-
-	/* We can fill in the remaining client fields */
-	strlcpy(new_client->name, name, I2C_NAME_SIZE);
-	data->valid = 0;
-	init_MUTEX(&data->update_lock);
-
-	/* Tell the I2C layer a new client has arrived */
-	if ((err = i2c_attach_client(new_client)))
-		goto exit_free;
-
-	/*
-	 * Initialize the LM83 chip
-	 * (Nothing to do for this one.)
-	 */
-
-	/* Register sysfs hooks */
-	device_create_file(&new_client->dev, &dev_attr_temp1_input);
-	device_create_file(&new_client->dev, &dev_attr_temp2_input);
-	device_create_file(&new_client->dev, &dev_attr_temp3_input);
-	device_create_file(&new_client->dev, &dev_attr_temp4_input);
-	device_create_file(&new_client->dev, &dev_attr_temp1_max);
-	device_create_file(&new_client->dev, &dev_attr_temp2_max);
-	device_create_file(&new_client->dev, &dev_attr_temp3_max);
-	device_create_file(&new_client->dev, &dev_attr_temp4_max);
-	device_create_file(&new_client->dev, &dev_attr_temp1_crit);
-	device_create_file(&new_client->dev, &dev_attr_temp2_crit);
-	device_create_file(&new_client->dev, &dev_attr_temp3_crit);
-	device_create_file(&new_client->dev, &dev_attr_temp4_crit);
-	device_create_file(&new_client->dev, &dev_attr_alarms);
-
-	return 0;
-
-exit_free:
-	kfree(data);
-exit:
-	return err;
-}
-
-static int lm83_detach_client(struct i2c_client *client)
-{
-	int err;
-
-	if ((err = i2c_detach_client(client))) {
-		dev_err(&client->dev,
-		    "Client deregistration failed, client not detached.\n");
-		return err;
-	}
-
-	kfree(i2c_get_clientdata(client));
-	return 0;
-}
-
-static struct lm83_data *lm83_update_device(struct device *dev)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm83_data *data = i2c_get_clientdata(client);
-
-	down(&data->update_lock);
-
-	if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) {
-		int nr;
-
-		dev_dbg(&client->dev, "Updating lm83 data.\n");
-		for (nr = 0; nr < 4 ; nr++) {
-			data->temp_input[nr] =
-			    i2c_smbus_read_byte_data(client,
-			    LM83_REG_R_TEMP[nr]);
-			data->temp_high[nr] =
-			    i2c_smbus_read_byte_data(client,
-			    LM83_REG_R_HIGH[nr]);
-		}
-		data->temp_crit =
-		    i2c_smbus_read_byte_data(client, LM83_REG_R_TCRIT);
-		data->alarms =
-		    i2c_smbus_read_byte_data(client, LM83_REG_R_STATUS1)
-		    + (i2c_smbus_read_byte_data(client, LM83_REG_R_STATUS2)
-		    << 8);
-
-		data->last_updated = jiffies;
-		data->valid = 1;
-	}
-
-	up(&data->update_lock);
-
-	return data;
-}
-
-static int __init sensors_lm83_init(void)
-{
-	return i2c_add_driver(&lm83_driver);
-}
-
-static void __exit sensors_lm83_exit(void)
-{
-	i2c_del_driver(&lm83_driver);
-}
-
-MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>");
-MODULE_DESCRIPTION("LM83 driver");
-MODULE_LICENSE("GPL");
-
-module_init(sensors_lm83_init);
-module_exit(sensors_lm83_exit);
diff --git a/drivers/i2c/chips/lm85.c b/drivers/i2c/chips/lm85.c
deleted file mode 100644
--- a/drivers/i2c/chips/lm85.c
+++ /dev/null
@@ -1,1578 +0,0 @@
-/*
-    lm85.c - Part of lm_sensors, Linux kernel modules for hardware
-             monitoring
-    Copyright (c) 1998, 1999  Frodo Looijaard <frodol@dds.nl> 
-    Copyright (c) 2002, 2003  Philip Pokorny <ppokorny@penguincomputing.com>
-    Copyright (c) 2003        Margit Schubert-While <margitsw@t-online.de>
-    Copyright (c) 2004        Justin Thiessen <jthiessen@penguincomputing.com>
-
-    Chip details at	      <http://www.national.com/ds/LM/LM85.pdf>
-
-    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 <linux/config.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/jiffies.h>
-#include <linux/i2c.h>
-#include <linux/i2c-sensor.h>
-#include <linux/i2c-vid.h>
-
-/* Addresses to scan */
-static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END };
-static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
-
-/* Insmod parameters */
-SENSORS_INSMOD_6(lm85b, lm85c, adm1027, adt7463, emc6d100, emc6d102);
-
-/* The LM85 registers */
-
-#define	LM85_REG_IN(nr)			(0x20 + (nr))
-#define	LM85_REG_IN_MIN(nr)		(0x44 + (nr) * 2)
-#define	LM85_REG_IN_MAX(nr)		(0x45 + (nr) * 2)
-
-#define	LM85_REG_TEMP(nr)		(0x25 + (nr))
-#define	LM85_REG_TEMP_MIN(nr)		(0x4e + (nr) * 2)
-#define	LM85_REG_TEMP_MAX(nr)		(0x4f + (nr) * 2)
-
-/* Fan speeds are LSB, MSB (2 bytes) */
-#define	LM85_REG_FAN(nr)		(0x28 + (nr) *2)
-#define	LM85_REG_FAN_MIN(nr)		(0x54 + (nr) *2)
-
-#define	LM85_REG_PWM(nr)		(0x30 + (nr))
-
-#define	ADT7463_REG_OPPOINT(nr)		(0x33 + (nr))
-
-#define	ADT7463_REG_TMIN_CTL1		0x36
-#define	ADT7463_REG_TMIN_CTL2		0x37
-
-#define	LM85_REG_DEVICE			0x3d
-#define	LM85_REG_COMPANY		0x3e
-#define	LM85_REG_VERSTEP		0x3f
-/* These are the recognized values for the above regs */
-#define	LM85_DEVICE_ADX			0x27
-#define	LM85_COMPANY_NATIONAL		0x01
-#define	LM85_COMPANY_ANALOG_DEV		0x41
-#define	LM85_COMPANY_SMSC      		0x5c
-#define	LM85_VERSTEP_VMASK              0xf0
-#define	LM85_VERSTEP_GENERIC		0x60
-#define	LM85_VERSTEP_LM85C		0x60
-#define	LM85_VERSTEP_LM85B		0x62
-#define	LM85_VERSTEP_ADM1027		0x60
-#define	LM85_VERSTEP_ADT7463		0x62
-#define	LM85_VERSTEP_ADT7463C		0x6A
-#define	LM85_VERSTEP_EMC6D100_A0        0x60
-#define	LM85_VERSTEP_EMC6D100_A1        0x61
-#define	LM85_VERSTEP_EMC6D102		0x65
-
-#define	LM85_REG_CONFIG			0x40
-
-#define	LM85_REG_ALARM1			0x41
-#define	LM85_REG_ALARM2			0x42
-
-#define	LM85_REG_VID			0x43
-
-/* Automated FAN control */
-#define	LM85_REG_AFAN_CONFIG(nr)	(0x5c + (nr))
-#define	LM85_REG_AFAN_RANGE(nr)		(0x5f + (nr))
-#define	LM85_REG_AFAN_SPIKE1		0x62
-#define	LM85_REG_AFAN_SPIKE2		0x63
-#define	LM85_REG_AFAN_MINPWM(nr)	(0x64 + (nr))
-#define	LM85_REG_AFAN_LIMIT(nr)		(0x67 + (nr))
-#define	LM85_REG_AFAN_CRITICAL(nr)	(0x6a + (nr))
-#define	LM85_REG_AFAN_HYST1		0x6d
-#define	LM85_REG_AFAN_HYST2		0x6e
-
-#define	LM85_REG_TACH_MODE		0x74
-#define	LM85_REG_SPINUP_CTL		0x75
-
-#define	ADM1027_REG_TEMP_OFFSET(nr)	(0x70 + (nr))
-#define	ADM1027_REG_CONFIG2		0x73
-#define	ADM1027_REG_INTMASK1		0x74
-#define	ADM1027_REG_INTMASK2		0x75
-#define	ADM1027_REG_EXTEND_ADC1		0x76
-#define	ADM1027_REG_EXTEND_ADC2		0x77
-#define	ADM1027_REG_CONFIG3		0x78
-#define	ADM1027_REG_FAN_PPR		0x7b
-
-#define	ADT7463_REG_THERM		0x79
-#define	ADT7463_REG_THERM_LIMIT		0x7A
-
-#define EMC6D100_REG_ALARM3             0x7d
-/* IN5, IN6 and IN7 */
-#define	EMC6D100_REG_IN(nr)             (0x70 + ((nr)-5))
-#define	EMC6D100_REG_IN_MIN(nr)         (0x73 + ((nr)-5) * 2)
-#define	EMC6D100_REG_IN_MAX(nr)         (0x74 + ((nr)-5) * 2)
-#define	EMC6D102_REG_EXTEND_ADC1	0x85
-#define	EMC6D102_REG_EXTEND_ADC2	0x86
-#define	EMC6D102_REG_EXTEND_ADC3	0x87
-#define	EMC6D102_REG_EXTEND_ADC4	0x88
-
-#define	LM85_ALARM_IN0			0x0001
-#define	LM85_ALARM_IN1			0x0002
-#define	LM85_ALARM_IN2			0x0004
-#define	LM85_ALARM_IN3			0x0008
-#define	LM85_ALARM_TEMP1		0x0010
-#define	LM85_ALARM_TEMP2		0x0020
-#define	LM85_ALARM_TEMP3		0x0040
-#define	LM85_ALARM_ALARM2		0x0080
-#define	LM85_ALARM_IN4			0x0100
-#define	LM85_ALARM_RESERVED		0x0200
-#define	LM85_ALARM_FAN1			0x0400
-#define	LM85_ALARM_FAN2			0x0800
-#define	LM85_ALARM_FAN3			0x1000
-#define	LM85_ALARM_FAN4			0x2000
-#define	LM85_ALARM_TEMP1_FAULT		0x4000
-#define	LM85_ALARM_TEMP3_FAULT		0x8000
-
-
-/* Conversions. Rounding and limit checking is only done on the TO_REG 
-   variants. Note that you should be a bit careful with which arguments
-   these macros are called: arguments may be evaluated more than once.
- */
-
-/* IN are scaled acording to built-in resistors */
-static int lm85_scaling[] = {  /* .001 Volts */
-		2500, 2250, 3300, 5000, 12000,
-		3300, 1500, 1800 /*EMC6D100*/
-	};
-#define SCALE(val,from,to)		(((val)*(to) + ((from)/2))/(from))
-
-#define INS_TO_REG(n,val)	\
-		SENSORS_LIMIT(SCALE(val,lm85_scaling[n],192),0,255)
-
-#define INSEXT_FROM_REG(n,val,ext,scale)	\
-		SCALE((val)*(scale) + (ext),192*(scale),lm85_scaling[n])
-
-#define INS_FROM_REG(n,val)   INSEXT_FROM_REG(n,val,0,1)
-
-/* FAN speed is measured using 90kHz clock */
-#define FAN_TO_REG(val)		(SENSORS_LIMIT( (val)<=0?0: 5400000/(val),0,65534))
-#define FAN_FROM_REG(val)	((val)==0?-1:(val)==0xffff?0:5400000/(val))
-
-/* Temperature is reported in .001 degC increments */
-#define TEMP_TO_REG(val)	\
-		SENSORS_LIMIT(SCALE(val,1000,1),-127,127)
-#define TEMPEXT_FROM_REG(val,ext,scale)	\
-		SCALE((val)*scale + (ext),scale,1000)
-#define TEMP_FROM_REG(val)	\
-		TEMPEXT_FROM_REG(val,0,1)
-
-#define PWM_TO_REG(val)			(SENSORS_LIMIT(val,0,255))
-#define PWM_FROM_REG(val)		(val)
-
-
-/* ZONEs have the following parameters:
- *    Limit (low) temp,           1. degC
- *    Hysteresis (below limit),   1. degC (0-15)
- *    Range of speed control,     .1 degC (2-80)
- *    Critical (high) temp,       1. degC
- *
- * FAN PWMs have the following parameters:
- *    Reference Zone,                 1, 2, 3, etc.
- *    Spinup time,                    .05 sec
- *    PWM value at limit/low temp,    1 count
- *    PWM Frequency,                  1. Hz
- *    PWM is Min or OFF below limit,  flag
- *    Invert PWM output,              flag
- *
- * Some chips filter the temp, others the fan.
- *    Filter constant (or disabled)   .1 seconds
- */
-
-/* These are the zone temperature range encodings in .001 degree C */
-static int lm85_range_map[] = {   
-		2000,  2500,  3300,  4000,  5000,  6600,
-		8000, 10000, 13300, 16000, 20000, 26600,
-		32000, 40000, 53300, 80000
-	};
-static int RANGE_TO_REG( int range )
-{
-	int i;
-
-	if ( range < lm85_range_map[0] ) { 
-		return 0 ;
-	} else if ( range > lm85_range_map[15] ) {
-		return 15 ;
-	} else {  /* find closest match */
-		for ( i = 14 ; i >= 0 ; --i ) {
-			if ( range > lm85_range_map[i] ) { /* range bracketed */
-				if ((lm85_range_map[i+1] - range) < 
-					(range - lm85_range_map[i])) {
-					i++;
-					break;
-				}
-				break;
-			}
-		}
-	}
-	return( i & 0x0f );
-}
-#define RANGE_FROM_REG(val) (lm85_range_map[(val)&0x0f])
-
-/* These are the Acoustic Enhancement, or Temperature smoothing encodings
- * NOTE: The enable/disable bit is INCLUDED in these encodings as the
- *       MSB (bit 3, value 8).  If the enable bit is 0, the encoded value
- *       is ignored, or set to 0.
- */
-/* These are the PWM frequency encodings */
-static int lm85_freq_map[] = { /* .1 Hz */
-		100, 150, 230, 300, 380, 470, 620, 940
-	};
-static int FREQ_TO_REG( int freq )
-{
-	int i;
-
-	if( freq >= lm85_freq_map[7] ) { return 7 ; }
-	for( i = 0 ; i < 7 ; ++i )
-		if( freq <= lm85_freq_map[i] )
-			break ;
-	return( i & 0x07 );
-}
-#define FREQ_FROM_REG(val) (lm85_freq_map[(val)&0x07])
-
-/* Since we can't use strings, I'm abusing these numbers
- *   to stand in for the following meanings:
- *      1 -- PWM responds to Zone 1
- *      2 -- PWM responds to Zone 2
- *      3 -- PWM responds to Zone 3
- *     23 -- PWM responds to the higher temp of Zone 2 or 3
- *    123 -- PWM responds to highest of Zone 1, 2, or 3
- *      0 -- PWM is always at 0% (ie, off)
- *     -1 -- PWM is always at 100%
- *     -2 -- PWM responds to manual control
- */
-
-static int lm85_zone_map[] = { 1, 2, 3, -1, 0, 23, 123, -2 };
-#define ZONE_FROM_REG(val) (lm85_zone_map[((val)>>5)&0x07])
-
-static int ZONE_TO_REG( int zone )
-{
-	int i;
-
-	for( i = 0 ; i <= 7 ; ++i )
-		if( zone == lm85_zone_map[i] )
-			break ;
-	if( i > 7 )   /* Not found. */
-		i = 3;  /* Always 100% */
-	return( (i & 0x07)<<5 );
-}
-
-#define HYST_TO_REG(val) (SENSORS_LIMIT(((val)+500)/1000,0,15))
-#define HYST_FROM_REG(val) ((val)*1000)
-
-#define OFFSET_TO_REG(val) (SENSORS_LIMIT((val)/25,-127,127))
-#define OFFSET_FROM_REG(val) ((val)*25)
-
-#define PPR_MASK(fan) (0x03<<(fan *2))
-#define PPR_TO_REG(val,fan) (SENSORS_LIMIT((val)-1,0,3)<<(fan *2))
-#define PPR_FROM_REG(val,fan) ((((val)>>(fan * 2))&0x03)+1)
-
-/* i2c-vid.h defines vid_from_reg() */
-#define VID_FROM_REG(val,vrm) (vid_from_reg((val),(vrm)))
-
-#define ALARMS_FROM_REG(val) (val)
-
-/* Unlike some other drivers we DO NOT set initial limits.  Use
- * the config file to set limits.  Some users have reported
- * motherboards shutting down when we set limits in a previous
- * version of the driver.
- */
-
-/* Chip sampling rates
- *
- * Some sensors are not updated more frequently than once per second
- *    so it doesn't make sense to read them more often than that.
- *    We cache the results and return the saved data if the driver
- *    is called again before a second has elapsed.
- *
- * Also, there is significant configuration data for this chip
- *    given the automatic PWM fan control that is possible.  There
- *    are about 47 bytes of config data to only 22 bytes of actual
- *    readings.  So, we keep the config data up to date in the cache
- *    when it is written and only sample it once every 1 *minute*
- */
-#define LM85_DATA_INTERVAL  (HZ + HZ / 2)
-#define LM85_CONFIG_INTERVAL  (1 * 60 * HZ)
-
-/* For each registered LM85, we need to keep some data in memory. That
-   data is pointed to by lm85_list[NR]->data. The structure itself is
-   dynamically allocated, at the same time when a new lm85 client is
-   allocated. */
-
-/* LM85 can automatically adjust fan speeds based on temperature
- * This structure encapsulates an entire Zone config.  There are
- * three zones (one for each temperature input) on the lm85
- */
-struct lm85_zone {
-	s8 limit;	/* Low temp limit */
-	u8 hyst;	/* Low limit hysteresis. (0-15) */
-	u8 range;	/* Temp range, encoded */
-	s8 critical;	/* "All fans ON" temp limit */
-	u8 off_desired; /* Actual "off" temperature specified.  Preserved 
-			 * to prevent "drift" as other autofan control
-			 * values change.
-			 */
-	u8 max_desired; /* Actual "max" temperature specified.  Preserved 
-			 * to prevent "drift" as other autofan control
-			 * values change.
-			 */
-};
-
-struct lm85_autofan {
-	u8 config;	/* Register value */
-	u8 freq;	/* PWM frequency, encoded */
-	u8 min_pwm;	/* Minimum PWM value, encoded */
-	u8 min_off;	/* Min PWM or OFF below "limit", flag */
-};
-
-struct lm85_data {
-	struct i2c_client client;
-	struct semaphore lock;
-	enum chips type;
-
-	struct semaphore update_lock;
-	int valid;		/* !=0 if following fields are valid */
-	unsigned long last_reading;	/* In jiffies */
-	unsigned long last_config;	/* In jiffies */
-
-	u8 in[8];		/* Register value */
-	u8 in_max[8];		/* Register value */
-	u8 in_min[8];		/* Register value */
-	s8 temp[3];		/* Register value */
-	s8 temp_min[3];		/* Register value */
-	s8 temp_max[3];		/* Register value */
-	s8 temp_offset[3];	/* Register value */
-	u16 fan[4];		/* Register value */
-	u16 fan_min[4];		/* Register value */
-	u8 pwm[3];		/* Register value */
-	u8 spinup_ctl;		/* Register encoding, combined */
-	u8 tach_mode;		/* Register encoding, combined */
-	u8 temp_ext[3];		/* Decoded values */
-	u8 in_ext[8];		/* Decoded values */
-	u8 adc_scale;		/* ADC Extended bits scaling factor */
-	u8 fan_ppr;		/* Register value */
-	u8 smooth[3];		/* Register encoding */
-	u8 vid;			/* Register value */
-	u8 vrm;			/* VRM version */
-	u8 syncpwm3;		/* Saved PWM3 for TACH 2,3,4 config */
-	u8 oppoint[3];		/* Register value */
-	u16 tmin_ctl;		/* Register value */
-	unsigned long therm_total; /* Cummulative therm count */
-	u8 therm_limit;		/* Register value */
-	u32 alarms;		/* Register encoding, combined */
-	struct lm85_autofan autofan[3];
-	struct lm85_zone zone[3];
-};
-
-static int lm85_attach_adapter(struct i2c_adapter *adapter);
-static int lm85_detect(struct i2c_adapter *adapter, int address,
-			int kind);
-static int lm85_detach_client(struct i2c_client *client);
-
-static int lm85_read_value(struct i2c_client *client, u8 register);
-static int lm85_write_value(struct i2c_client *client, u8 register, int value);
-static struct lm85_data *lm85_update_device(struct device *dev);
-static void lm85_init_client(struct i2c_client *client);
-
-
-static struct i2c_driver lm85_driver = {
-	.owner          = THIS_MODULE,
-	.name           = "lm85",
-	.id             = I2C_DRIVERID_LM85,
-	.flags          = I2C_DF_NOTIFY,
-	.attach_adapter = lm85_attach_adapter,
-	.detach_client  = lm85_detach_client,
-};
-
-
-/* 4 Fans */
-static ssize_t show_fan(struct device *dev, char *buf, int nr)
-{
-	struct lm85_data *data = lm85_update_device(dev);
-	return sprintf(buf,"%d\n", FAN_FROM_REG(data->fan[nr]) );
-}
-static ssize_t show_fan_min(struct device *dev, char *buf, int nr)
-{
-	struct lm85_data *data = lm85_update_device(dev);
-	return sprintf(buf,"%d\n", FAN_FROM_REG(data->fan_min[nr]) );
-}
-static ssize_t set_fan_min(struct device *dev, const char *buf, 
-		size_t count, int nr)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm85_data *data = i2c_get_clientdata(client);
-	long val = simple_strtol(buf, NULL, 10);
-
-	down(&data->update_lock);
-	data->fan_min[nr] = FAN_TO_REG(val);
-	lm85_write_value(client, LM85_REG_FAN_MIN(nr), data->fan_min[nr]);
-	up(&data->update_lock);
-	return count;
-}
-
-#define show_fan_offset(offset)						\
-static ssize_t show_fan_##offset (struct device *dev, char *buf)	\
-{									\
-	return show_fan(dev, buf, offset - 1);				\
-}									\
-static ssize_t show_fan_##offset##_min (struct device *dev, char *buf)	\
-{									\
-	return show_fan_min(dev, buf, offset - 1);			\
-}									\
-static ssize_t set_fan_##offset##_min (struct device *dev, 		\
-	const char *buf, size_t count) 					\
-{									\
-	return set_fan_min(dev, buf, count, offset - 1);		\
-}									\
-static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_fan_##offset,	\
-		NULL);							\
-static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, 		\
-		show_fan_##offset##_min, set_fan_##offset##_min);
-
-show_fan_offset(1);
-show_fan_offset(2);
-show_fan_offset(3);
-show_fan_offset(4);
-
-/* vid, vrm, alarms */
-
-static ssize_t show_vid_reg(struct device *dev, char *buf)
-{
-	struct lm85_data *data = lm85_update_device(dev);
-	return sprintf(buf, "%ld\n", (long) vid_from_reg(data->vid, data->vrm));
-}
-
-static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid_reg, NULL);
-
-static ssize_t show_vrm_reg(struct device *dev, char *buf)
-{
-	struct lm85_data *data = lm85_update_device(dev);
-	return sprintf(buf, "%ld\n", (long) data->vrm);
-}
-
-static ssize_t store_vrm_reg(struct device *dev, const char *buf, size_t count)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm85_data *data = i2c_get_clientdata(client);
-	u32 val;
-
-	val = simple_strtoul(buf, NULL, 10);
-	data->vrm = val;
-	return count;
-}
-
-static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg);
-
-static ssize_t show_alarms_reg(struct device *dev, char *buf)
-{
-	struct lm85_data *data = lm85_update_device(dev);
-	return sprintf(buf, "%ld\n", (long) ALARMS_FROM_REG(data->alarms));
-}
-
-static DEVICE_ATTR(alarms, S_IRUGO, show_alarms_reg, NULL);
-
-/* pwm */
-
-static ssize_t show_pwm(struct device *dev, char *buf, int nr)
-{
-	struct lm85_data *data = lm85_update_device(dev);
-	return sprintf(buf,"%d\n", PWM_FROM_REG(data->pwm[nr]) );
-}
-static ssize_t set_pwm(struct device *dev, const char *buf, 
-		size_t count, int nr)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm85_data *data = i2c_get_clientdata(client);
-	long val = simple_strtol(buf, NULL, 10);
-
-	down(&data->update_lock);
-	data->pwm[nr] = PWM_TO_REG(val);
-	lm85_write_value(client, LM85_REG_PWM(nr), data->pwm[nr]);
-	up(&data->update_lock);
-	return count;
-}
-static ssize_t show_pwm_enable(struct device *dev, char *buf, int nr)
-{
-	struct lm85_data *data = lm85_update_device(dev);
-	int	pwm_zone;
-
-	pwm_zone = ZONE_FROM_REG(data->autofan[nr].config);
-	return sprintf(buf,"%d\n", (pwm_zone != 0 && pwm_zone != -1) );
-}
-
-#define show_pwm_reg(offset)						\
-static ssize_t show_pwm_##offset (struct device *dev, char *buf)	\
-{									\
-	return show_pwm(dev, buf, offset - 1);				\
-}									\
-static ssize_t set_pwm_##offset (struct device *dev,			\
-				 const char *buf, size_t count)		\
-{									\
-	return set_pwm(dev, buf, count, offset - 1);			\
-}									\
-static ssize_t show_pwm_enable##offset (struct device *dev, char *buf)	\
-{									\
-	return show_pwm_enable(dev, buf, offset - 1);			\
-}									\
-static DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR, 			\
-		show_pwm_##offset, set_pwm_##offset);			\
-static DEVICE_ATTR(pwm##offset##_enable, S_IRUGO, 			\
-		show_pwm_enable##offset, NULL);
-
-show_pwm_reg(1);
-show_pwm_reg(2);
-show_pwm_reg(3);
-
-/* Voltages */
-
-static ssize_t show_in(struct device *dev, char *buf, int nr)
-{
-	struct lm85_data *data = lm85_update_device(dev);
-	return sprintf(	buf, "%d\n", INSEXT_FROM_REG(nr,
-						     data->in[nr],
-						     data->in_ext[nr],
-						     data->adc_scale) );
-}
-static ssize_t show_in_min(struct device *dev, char *buf, int nr)
-{
-	struct lm85_data *data = lm85_update_device(dev);
-	return sprintf(buf,"%d\n", INS_FROM_REG(nr, data->in_min[nr]) );
-}
-static ssize_t set_in_min(struct device *dev, const char *buf, 
-		size_t count, int nr)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm85_data *data = i2c_get_clientdata(client);
-	long val = simple_strtol(buf, NULL, 10);
-
-	down(&data->update_lock);
-	data->in_min[nr] = INS_TO_REG(nr, val);
-	lm85_write_value(client, LM85_REG_IN_MIN(nr), data->in_min[nr]);
-	up(&data->update_lock);
-	return count;
-}
-static ssize_t show_in_max(struct device *dev, char *buf, int nr)
-{
-	struct lm85_data *data = lm85_update_device(dev);
-	return sprintf(buf,"%d\n", INS_FROM_REG(nr, data->in_max[nr]) );
-}
-static ssize_t set_in_max(struct device *dev, const char *buf, 
-		size_t count, int nr)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm85_data *data = i2c_get_clientdata(client);
-	long val = simple_strtol(buf, NULL, 10);
-
-	down(&data->update_lock);
-	data->in_max[nr] = INS_TO_REG(nr, val);
-	lm85_write_value(client, LM85_REG_IN_MAX(nr), data->in_max[nr]);
-	up(&data->update_lock);
-	return count;
-}
-#define show_in_reg(offset)						\
-static ssize_t show_in_##offset (struct device *dev, char *buf)		\
-{									\
-	return show_in(dev, buf, offset);				\
-}									\
-static ssize_t show_in_##offset##_min (struct device *dev, char *buf)	\
-{									\
-	return show_in_min(dev, buf, offset);				\
-}									\
-static ssize_t show_in_##offset##_max (struct device *dev, char *buf)	\
-{									\
-	return show_in_max(dev, buf, offset);				\
-}									\
-static ssize_t set_in_##offset##_min (struct device *dev, 		\
-	const char *buf, size_t count) 					\
-{									\
-	return set_in_min(dev, buf, count, offset);			\
-}									\
-static ssize_t set_in_##offset##_max (struct device *dev, 		\
-	const char *buf, size_t count) 					\
-{									\
-	return set_in_max(dev, buf, count, offset);			\
-}									\
-static DEVICE_ATTR(in##offset##_input, S_IRUGO, show_in_##offset, 	\
-		NULL);							\
-static DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, 		\
-		show_in_##offset##_min, set_in_##offset##_min);		\
-static DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, 		\
-		show_in_##offset##_max, set_in_##offset##_max);
-
-show_in_reg(0);
-show_in_reg(1);
-show_in_reg(2);
-show_in_reg(3);
-show_in_reg(4);
-
-/* Temps */
-
-static ssize_t show_temp(struct device *dev, char *buf, int nr)
-{
-	struct lm85_data *data = lm85_update_device(dev);
-	return sprintf(buf,"%d\n", TEMPEXT_FROM_REG(data->temp[nr],
-						    data->temp_ext[nr],
-						    data->adc_scale) );
-}
-static ssize_t show_temp_min(struct device *dev, char *buf, int nr)
-{
-	struct lm85_data *data = lm85_update_device(dev);
-	return sprintf(buf,"%d\n", TEMP_FROM_REG(data->temp_min[nr]) );
-}
-static ssize_t set_temp_min(struct device *dev, const char *buf, 
-		size_t count, int nr)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm85_data *data = i2c_get_clientdata(client);
-	long val = simple_strtol(buf, NULL, 10);
-
-	down(&data->update_lock);
-	data->temp_min[nr] = TEMP_TO_REG(val);
-	lm85_write_value(client, LM85_REG_TEMP_MIN(nr), data->temp_min[nr]);
-	up(&data->update_lock);
-	return count;
-}
-static ssize_t show_temp_max(struct device *dev, char *buf, int nr)
-{
-	struct lm85_data *data = lm85_update_device(dev);
-	return sprintf(buf,"%d\n", TEMP_FROM_REG(data->temp_max[nr]) );
-}
-static ssize_t set_temp_max(struct device *dev, const char *buf, 
-		size_t count, int nr)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm85_data *data = i2c_get_clientdata(client);
-	long val = simple_strtol(buf, NULL, 10);	
-
-	down(&data->update_lock);
-	data->temp_max[nr] = TEMP_TO_REG(val);
-	lm85_write_value(client, LM85_REG_TEMP_MAX(nr), data->temp_max[nr]);
-	up(&data->update_lock);
-	return count;
-}
-#define show_temp_reg(offset)						\
-static ssize_t show_temp_##offset (struct device *dev, char *buf)	\
-{									\
-	return show_temp(dev, buf, offset - 1);				\
-}									\
-static ssize_t show_temp_##offset##_min (struct device *dev, char *buf)	\
-{									\
-	return show_temp_min(dev, buf, offset - 1);			\
-}									\
-static ssize_t show_temp_##offset##_max (struct device *dev, char *buf)	\
-{									\
-	return show_temp_max(dev, buf, offset - 1);			\
-}									\
-static ssize_t set_temp_##offset##_min (struct device *dev, 		\
-	const char *buf, size_t count) 					\
-{									\
-	return set_temp_min(dev, buf, count, offset - 1);		\
-}									\
-static ssize_t set_temp_##offset##_max (struct device *dev, 		\
-	const char *buf, size_t count) 					\
-{									\
-	return set_temp_max(dev, buf, count, offset - 1);		\
-}									\
-static DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_temp_##offset,	\
-		NULL);							\
-static DEVICE_ATTR(temp##offset##_min, S_IRUGO | S_IWUSR, 		\
-		show_temp_##offset##_min, set_temp_##offset##_min);	\
-static DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR, 		\
-		show_temp_##offset##_max, set_temp_##offset##_max);
-
-show_temp_reg(1);
-show_temp_reg(2);
-show_temp_reg(3);
-
-
-/* Automatic PWM control */
-
-static ssize_t show_pwm_auto_channels(struct device *dev, char *buf, int nr)
-{
-	struct lm85_data *data = lm85_update_device(dev);
-	return sprintf(buf,"%d\n", ZONE_FROM_REG(data->autofan[nr].config));
-}
-static ssize_t set_pwm_auto_channels(struct device *dev, const char *buf,
-	size_t count, int nr)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm85_data *data = i2c_get_clientdata(client);
-	long val = simple_strtol(buf, NULL, 10);   
-
-	down(&data->update_lock);
-	data->autofan[nr].config = (data->autofan[nr].config & (~0xe0))
-		| ZONE_TO_REG(val) ;
-	lm85_write_value(client, LM85_REG_AFAN_CONFIG(nr),
-		data->autofan[nr].config);
-	up(&data->update_lock);
-	return count;
-}
-static ssize_t show_pwm_auto_pwm_min(struct device *dev, char *buf, int nr)
-{
-	struct lm85_data *data = lm85_update_device(dev);
-	return sprintf(buf,"%d\n", PWM_FROM_REG(data->autofan[nr].min_pwm));
-}
-static ssize_t set_pwm_auto_pwm_min(struct device *dev, const char *buf,
-	size_t count, int nr)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm85_data *data = i2c_get_clientdata(client);
-	long val = simple_strtol(buf, NULL, 10);
-
-	down(&data->update_lock);
-	data->autofan[nr].min_pwm = PWM_TO_REG(val);
-	lm85_write_value(client, LM85_REG_AFAN_MINPWM(nr),
-		data->autofan[nr].min_pwm);
-	up(&data->update_lock);
-	return count;
-}
-static ssize_t show_pwm_auto_pwm_minctl(struct device *dev, char *buf, int nr)
-{
-	struct lm85_data *data = lm85_update_device(dev);
-	return sprintf(buf,"%d\n", data->autofan[nr].min_off);
-}
-static ssize_t set_pwm_auto_pwm_minctl(struct device *dev, const char *buf,
-	size_t count, int nr)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm85_data *data = i2c_get_clientdata(client);
-	long val = simple_strtol(buf, NULL, 10);
-
-	down(&data->update_lock);
-	data->autofan[nr].min_off = val;
-	lm85_write_value(client, LM85_REG_AFAN_SPIKE1, data->smooth[0]
-		| data->syncpwm3
-		| (data->autofan[0].min_off ? 0x20 : 0)
-		| (data->autofan[1].min_off ? 0x40 : 0)
-		| (data->autofan[2].min_off ? 0x80 : 0)
-	);
-	up(&data->update_lock);
-	return count;
-}
-static ssize_t show_pwm_auto_pwm_freq(struct device *dev, char *buf, int nr)
-{
-	struct lm85_data *data = lm85_update_device(dev);
-	return sprintf(buf,"%d\n", FREQ_FROM_REG(data->autofan[nr].freq));
-}
-static ssize_t set_pwm_auto_pwm_freq(struct device *dev, const char *buf,
-		size_t count, int nr)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm85_data *data = i2c_get_clientdata(client);
-	long val = simple_strtol(buf, NULL, 10);
-
-	down(&data->update_lock);
-	data->autofan[nr].freq = FREQ_TO_REG(val);
-	lm85_write_value(client, LM85_REG_AFAN_RANGE(nr),
-		(data->zone[nr].range << 4)
-		| data->autofan[nr].freq
-	); 
-	up(&data->update_lock);
-	return count;
-}
-#define pwm_auto(offset)						\
-static ssize_t show_pwm##offset##_auto_channels (struct device *dev,	\
-	char *buf)							\
-{									\
-	return show_pwm_auto_channels(dev, buf, offset - 1);		\
-}									\
-static ssize_t set_pwm##offset##_auto_channels (struct device *dev,	\
-	const char *buf, size_t count)					\
-{									\
-	return set_pwm_auto_channels(dev, buf, count, offset - 1);	\
-}									\
-static ssize_t show_pwm##offset##_auto_pwm_min (struct device *dev,	\
-	char *buf)							\
-{									\
-	return show_pwm_auto_pwm_min(dev, buf, offset - 1);		\
-}									\
-static ssize_t set_pwm##offset##_auto_pwm_min (struct device *dev,	\
-	const char *buf, size_t count)					\
-{									\
-	return set_pwm_auto_pwm_min(dev, buf, count, offset - 1);	\
-}									\
-static ssize_t show_pwm##offset##_auto_pwm_minctl (struct device *dev,	\
-	char *buf)							\
-{									\
-	return show_pwm_auto_pwm_minctl(dev, buf, offset - 1);		\
-}									\
-static ssize_t set_pwm##offset##_auto_pwm_minctl (struct device *dev,	\
-	const char *buf, size_t count)					\
-{									\
-	return set_pwm_auto_pwm_minctl(dev, buf, count, offset - 1);	\
-}									\
-static ssize_t show_pwm##offset##_auto_pwm_freq (struct device *dev,	\
-	char *buf)							\
-{									\
-	return show_pwm_auto_pwm_freq(dev, buf, offset - 1);		\
-}									\
-static ssize_t set_pwm##offset##_auto_pwm_freq(struct device *dev,	\
-	const char *buf, size_t count)					\
-{									\
-	return set_pwm_auto_pwm_freq(dev, buf, count, offset - 1);	\
-}									\
-static DEVICE_ATTR(pwm##offset##_auto_channels, S_IRUGO | S_IWUSR,	\
-		show_pwm##offset##_auto_channels,			\
-		set_pwm##offset##_auto_channels);			\
-static DEVICE_ATTR(pwm##offset##_auto_pwm_min, S_IRUGO | S_IWUSR,	\
-		show_pwm##offset##_auto_pwm_min,			\
-		set_pwm##offset##_auto_pwm_min);			\
-static DEVICE_ATTR(pwm##offset##_auto_pwm_minctl, S_IRUGO | S_IWUSR,	\
-		show_pwm##offset##_auto_pwm_minctl,			\
-		set_pwm##offset##_auto_pwm_minctl);			\
-static DEVICE_ATTR(pwm##offset##_auto_pwm_freq, S_IRUGO | S_IWUSR,	\
-		show_pwm##offset##_auto_pwm_freq,			\
-		set_pwm##offset##_auto_pwm_freq);              
-pwm_auto(1);
-pwm_auto(2);
-pwm_auto(3);
-
-/* Temperature settings for automatic PWM control */
-
-static ssize_t show_temp_auto_temp_off(struct device *dev, char *buf, int nr)
-{
-	struct lm85_data *data = lm85_update_device(dev);
-	return sprintf(buf,"%d\n", TEMP_FROM_REG(data->zone[nr].limit) -
-		HYST_FROM_REG(data->zone[nr].hyst));
-}
-static ssize_t set_temp_auto_temp_off(struct device *dev, const char *buf,
-	size_t count, int nr)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm85_data *data = i2c_get_clientdata(client);
-	int min;
-	long val = simple_strtol(buf, NULL, 10);
-
-	down(&data->update_lock);
-	min = TEMP_FROM_REG(data->zone[nr].limit);
-	data->zone[nr].off_desired = TEMP_TO_REG(val);
-	data->zone[nr].hyst = HYST_TO_REG(min - val);
-	if ( nr == 0 || nr == 1 ) {
-		lm85_write_value(client, LM85_REG_AFAN_HYST1,
-			(data->zone[0].hyst << 4)
-			| data->zone[1].hyst
-			);
-	} else {
-		lm85_write_value(client, LM85_REG_AFAN_HYST2,
-			(data->zone[2].hyst << 4)
-		);
-	}
-	up(&data->update_lock);
-	return count;
-}
-static ssize_t show_temp_auto_temp_min(struct device *dev, char *buf, int nr)
-{
-	struct lm85_data *data = lm85_update_device(dev);
-	return sprintf(buf,"%d\n", TEMP_FROM_REG(data->zone[nr].limit) );
-}
-static ssize_t set_temp_auto_temp_min(struct device *dev, const char *buf,
-	size_t count, int nr)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm85_data *data = i2c_get_clientdata(client);
-	long val = simple_strtol(buf, NULL, 10);
-
-	down(&data->update_lock);
-	data->zone[nr].limit = TEMP_TO_REG(val);
-	lm85_write_value(client, LM85_REG_AFAN_LIMIT(nr),
-		data->zone[nr].limit);
-
-/* Update temp_auto_max and temp_auto_range */
-	data->zone[nr].range = RANGE_TO_REG(
-		TEMP_FROM_REG(data->zone[nr].max_desired) -
-		TEMP_FROM_REG(data->zone[nr].limit));
-	lm85_write_value(client, LM85_REG_AFAN_RANGE(nr),
-		((data->zone[nr].range & 0x0f) << 4)
-		| (data->autofan[nr].freq & 0x07));
-
-/* Update temp_auto_hyst and temp_auto_off */
-	data->zone[nr].hyst = HYST_TO_REG(TEMP_FROM_REG(
-		data->zone[nr].limit) - TEMP_FROM_REG(
-		data->zone[nr].off_desired));
-	if ( nr == 0 || nr == 1 ) {
-		lm85_write_value(client, LM85_REG_AFAN_HYST1,
-			(data->zone[0].hyst << 4)
-			| data->zone[1].hyst
-			);
-	} else {
-		lm85_write_value(client, LM85_REG_AFAN_HYST2,
-			(data->zone[2].hyst << 4)
-		);
-	}
-	up(&data->update_lock);
-	return count;
-}
-static ssize_t show_temp_auto_temp_max(struct device *dev, char *buf, int nr)
-{
-	struct lm85_data *data = lm85_update_device(dev);
-	return sprintf(buf,"%d\n", TEMP_FROM_REG(data->zone[nr].limit) +
-		RANGE_FROM_REG(data->zone[nr].range));
-}
-static ssize_t set_temp_auto_temp_max(struct device *dev, const char *buf,
-	size_t count, int nr)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm85_data *data = i2c_get_clientdata(client);
-	int min;
-	long val = simple_strtol(buf, NULL, 10);
-
-	down(&data->update_lock);
-	min = TEMP_FROM_REG(data->zone[nr].limit);
-	data->zone[nr].max_desired = TEMP_TO_REG(val);
-	data->zone[nr].range = RANGE_TO_REG(
-		val - min);
-	lm85_write_value(client, LM85_REG_AFAN_RANGE(nr),
-		((data->zone[nr].range & 0x0f) << 4)
-		| (data->autofan[nr].freq & 0x07));
-	up(&data->update_lock);
-	return count;
-}
-static ssize_t show_temp_auto_temp_crit(struct device *dev, char *buf, int nr)
-{
-	struct lm85_data *data = lm85_update_device(dev);
-	return sprintf(buf,"%d\n", TEMP_FROM_REG(data->zone[nr].critical));
-}
-static ssize_t set_temp_auto_temp_crit(struct device *dev, const char *buf,
-		size_t count, int nr)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm85_data *data = i2c_get_clientdata(client);
-	long val = simple_strtol(buf, NULL, 10);
-
-	down(&data->update_lock);
-	data->zone[nr].critical = TEMP_TO_REG(val);
-	lm85_write_value(client, LM85_REG_AFAN_CRITICAL(nr),
-		data->zone[nr].critical);
-	up(&data->update_lock);
-	return count;
-}
-#define temp_auto(offset)						\
-static ssize_t show_temp##offset##_auto_temp_off (struct device *dev,	\
-	char *buf)							\
-{									\
-	return show_temp_auto_temp_off(dev, buf, offset - 1);		\
-}									\
-static ssize_t set_temp##offset##_auto_temp_off (struct device *dev,	\
-	const char *buf, size_t count)					\
-{									\
-	return set_temp_auto_temp_off(dev, buf, count, offset - 1);	\
-}									\
-static ssize_t show_temp##offset##_auto_temp_min (struct device *dev,	\
-	char *buf)							\
-{									\
-	return show_temp_auto_temp_min(dev, buf, offset - 1);		\
-}									\
-static ssize_t set_temp##offset##_auto_temp_min (struct device *dev,	\
-	const char *buf, size_t count)					\
-{									\
-	return set_temp_auto_temp_min(dev, buf, count, offset - 1);	\
-}									\
-static ssize_t show_temp##offset##_auto_temp_max (struct device *dev,	\
-	char *buf)							\
-{									\
-	return show_temp_auto_temp_max(dev, buf, offset - 1);		\
-}									\
-static ssize_t set_temp##offset##_auto_temp_max (struct device *dev,	\
-	const char *buf, size_t count)					\
-{									\
-	return set_temp_auto_temp_max(dev, buf, count, offset - 1);	\
-}									\
-static ssize_t show_temp##offset##_auto_temp_crit (struct device *dev,	\
-	char *buf)							\
-{									\
-	return show_temp_auto_temp_crit(dev, buf, offset - 1);		\
-}									\
-static ssize_t set_temp##offset##_auto_temp_crit (struct device *dev,	\
-	const char *buf, size_t count)					\
-{									\
-	return set_temp_auto_temp_crit(dev, buf, count, offset - 1);	\
-}									\
-static DEVICE_ATTR(temp##offset##_auto_temp_off, S_IRUGO | S_IWUSR,	\
-		show_temp##offset##_auto_temp_off,			\
-		set_temp##offset##_auto_temp_off);			\
-static DEVICE_ATTR(temp##offset##_auto_temp_min, S_IRUGO | S_IWUSR,	\
-		show_temp##offset##_auto_temp_min,			\
-		set_temp##offset##_auto_temp_min);			\
-static DEVICE_ATTR(temp##offset##_auto_temp_max, S_IRUGO | S_IWUSR,	\
-		show_temp##offset##_auto_temp_max,			\
-		set_temp##offset##_auto_temp_max);			\
-static DEVICE_ATTR(temp##offset##_auto_temp_crit, S_IRUGO | S_IWUSR,	\
-		show_temp##offset##_auto_temp_crit,			\
-		set_temp##offset##_auto_temp_crit);
-temp_auto(1);
-temp_auto(2);
-temp_auto(3);
-
-int lm85_attach_adapter(struct i2c_adapter *adapter)
-{
-	if (!(adapter->class & I2C_CLASS_HWMON))
-		return 0;
-	return i2c_detect(adapter, &addr_data, lm85_detect);
-}
-
-int lm85_detect(struct i2c_adapter *adapter, int address,
-		int kind)
-{
-	int company, verstep ;
-	struct i2c_client *new_client = NULL;
-	struct lm85_data *data;
-	int err = 0;
-	const char *type_name = "";
-
-	if (i2c_is_isa_adapter(adapter)) {
-		/* This chip has no ISA interface */
-		goto ERROR0 ;
-	};
-
-	if (!i2c_check_functionality(adapter,
-					I2C_FUNC_SMBUS_BYTE_DATA)) {
-		/* We need to be able to do byte I/O */
-		goto ERROR0 ;
-	};
-
-	/* OK. For now, we presume we have a valid client. We now create the
-	   client structure, even though we cannot fill it completely yet.
-	   But it allows us to access lm85_{read,write}_value. */
-
-	if (!(data = kmalloc(sizeof(struct lm85_data), GFP_KERNEL))) {
-		err = -ENOMEM;
-		goto ERROR0;
-	}
-	memset(data, 0, sizeof(struct lm85_data));
-
-	new_client = &data->client;
-	i2c_set_clientdata(new_client, data);
-	new_client->addr = address;
-	new_client->adapter = adapter;
-	new_client->driver = &lm85_driver;
-	new_client->flags = 0;
-
-	/* Now, we do the remaining detection. */
-
-	company = lm85_read_value(new_client, LM85_REG_COMPANY);
-	verstep = lm85_read_value(new_client, LM85_REG_VERSTEP);
-
-	dev_dbg(&adapter->dev, "Detecting device at %d,0x%02x with"
-		" COMPANY: 0x%02x and VERSTEP: 0x%02x\n",
-		i2c_adapter_id(new_client->adapter), new_client->addr,
-		company, verstep);
-
-	/* If auto-detecting, Determine the chip type. */
-	if (kind <= 0) {
-		dev_dbg(&adapter->dev, "Autodetecting device at %d,0x%02x ...\n",
-			i2c_adapter_id(adapter), address );
-		if( company == LM85_COMPANY_NATIONAL
-		    && verstep == LM85_VERSTEP_LM85C ) {
-			kind = lm85c ;
-		} else if( company == LM85_COMPANY_NATIONAL
-		    && verstep == LM85_VERSTEP_LM85B ) {
-			kind = lm85b ;
-		} else if( company == LM85_COMPANY_NATIONAL
-		    && (verstep & LM85_VERSTEP_VMASK) == LM85_VERSTEP_GENERIC ) {
-			dev_err(&adapter->dev, "Unrecognized version/stepping 0x%02x"
-				" Defaulting to LM85.\n", verstep);
-			kind = any_chip ;
-		} else if( company == LM85_COMPANY_ANALOG_DEV
-		    && verstep == LM85_VERSTEP_ADM1027 ) {
-			kind = adm1027 ;
-		} else if( company == LM85_COMPANY_ANALOG_DEV
-		    && (verstep == LM85_VERSTEP_ADT7463
-			 || verstep == LM85_VERSTEP_ADT7463C) ) {
-			kind = adt7463 ;
-		} else if( company == LM85_COMPANY_ANALOG_DEV
-		    && (verstep & LM85_VERSTEP_VMASK) == LM85_VERSTEP_GENERIC ) {
-			dev_err(&adapter->dev, "Unrecognized version/stepping 0x%02x"
-				" Defaulting to Generic LM85.\n", verstep );
-			kind = any_chip ;
-		} else if( company == LM85_COMPANY_SMSC
-		    && (verstep == LM85_VERSTEP_EMC6D100_A0
-			 || verstep == LM85_VERSTEP_EMC6D100_A1) ) {
-			/* Unfortunately, we can't tell a '100 from a '101
-			 * from the registers.  Since a '101 is a '100
-			 * in a package with fewer pins and therefore no
-			 * 3.3V, 1.5V or 1.8V inputs, perhaps if those
-			 * inputs read 0, then it's a '101.
-			 */
-			kind = emc6d100 ;
-		} else if( company == LM85_COMPANY_SMSC
-		    && verstep == LM85_VERSTEP_EMC6D102) {
-			kind = emc6d102 ;
-		} else if( company == LM85_COMPANY_SMSC
-		    && (verstep & LM85_VERSTEP_VMASK) == LM85_VERSTEP_GENERIC) {
-			dev_err(&adapter->dev, "lm85: Detected SMSC chip\n");
-			dev_err(&adapter->dev, "lm85: Unrecognized version/stepping 0x%02x"
-			    " Defaulting to Generic LM85.\n", verstep );
-			kind = any_chip ;
-		} else if( kind == any_chip
-		    && (verstep & LM85_VERSTEP_VMASK) == LM85_VERSTEP_GENERIC) {
-			dev_err(&adapter->dev, "Generic LM85 Version 6 detected\n");
-			/* Leave kind as "any_chip" */
-		} else {
-			dev_dbg(&adapter->dev, "Autodetection failed\n");
-			/* Not an LM85 ... */
-			if( kind == any_chip ) {  /* User used force=x,y */
-				dev_err(&adapter->dev, "Generic LM85 Version 6 not"
-					" found at %d,0x%02x. Try force_lm85c.\n",
-					i2c_adapter_id(adapter), address );
-			}
-			err = 0 ;
-			goto ERROR1;
-		}
-	}
-
-	/* Fill in the chip specific driver values */
-	if ( kind == any_chip ) {
-		type_name = "lm85";
-	} else if ( kind == lm85b ) {
-		type_name = "lm85b";
-	} else if ( kind == lm85c ) {
-		type_name = "lm85c";
-	} else if ( kind == adm1027 ) {
-		type_name = "adm1027";
-	} else if ( kind == adt7463 ) {
-		type_name = "adt7463";
-	} else if ( kind == emc6d100){
-		type_name = "emc6d100";
-	} else if ( kind == emc6d102 ) {
-		type_name = "emc6d102";
-	}
-	strlcpy(new_client->name, type_name, I2C_NAME_SIZE);
-
-	/* Fill in the remaining client fields */
-	data->type = kind;
-	data->valid = 0;
-	init_MUTEX(&data->update_lock);
-
-	/* Tell the I2C layer a new client has arrived */
-	if ((err = i2c_attach_client(new_client)))
-		goto ERROR1;
-
-	/* Set the VRM version */
-	data->vrm = i2c_which_vrm();
-
-	/* Initialize the LM85 chip */
-	lm85_init_client(new_client);
-
-	/* Register sysfs hooks */
-	device_create_file(&new_client->dev, &dev_attr_fan1_input);
-	device_create_file(&new_client->dev, &dev_attr_fan2_input);
-	device_create_file(&new_client->dev, &dev_attr_fan3_input);
-	device_create_file(&new_client->dev, &dev_attr_fan4_input);
-	device_create_file(&new_client->dev, &dev_attr_fan1_min);
-	device_create_file(&new_client->dev, &dev_attr_fan2_min);
-	device_create_file(&new_client->dev, &dev_attr_fan3_min);
-	device_create_file(&new_client->dev, &dev_attr_fan4_min);
-	device_create_file(&new_client->dev, &dev_attr_pwm1);
-	device_create_file(&new_client->dev, &dev_attr_pwm2);
-	device_create_file(&new_client->dev, &dev_attr_pwm3);
-	device_create_file(&new_client->dev, &dev_attr_pwm1_enable);
-	device_create_file(&new_client->dev, &dev_attr_pwm2_enable);
-	device_create_file(&new_client->dev, &dev_attr_pwm3_enable);
-	device_create_file(&new_client->dev, &dev_attr_in0_input);
-	device_create_file(&new_client->dev, &dev_attr_in1_input);
-	device_create_file(&new_client->dev, &dev_attr_in2_input);
-	device_create_file(&new_client->dev, &dev_attr_in3_input);
-	device_create_file(&new_client->dev, &dev_attr_in4_input);
-	device_create_file(&new_client->dev, &dev_attr_in0_min);
-	device_create_file(&new_client->dev, &dev_attr_in1_min);
-	device_create_file(&new_client->dev, &dev_attr_in2_min);
-	device_create_file(&new_client->dev, &dev_attr_in3_min);
-	device_create_file(&new_client->dev, &dev_attr_in4_min);
-	device_create_file(&new_client->dev, &dev_attr_in0_max);
-	device_create_file(&new_client->dev, &dev_attr_in1_max);
-	device_create_file(&new_client->dev, &dev_attr_in2_max);
-	device_create_file(&new_client->dev, &dev_attr_in3_max);
-	device_create_file(&new_client->dev, &dev_attr_in4_max);
-	device_create_file(&new_client->dev, &dev_attr_temp1_input);
-	device_create_file(&new_client->dev, &dev_attr_temp2_input);
-	device_create_file(&new_client->dev, &dev_attr_temp3_input);
-	device_create_file(&new_client->dev, &dev_attr_temp1_min);
-	device_create_file(&new_client->dev, &dev_attr_temp2_min);
-	device_create_file(&new_client->dev, &dev_attr_temp3_min);
-	device_create_file(&new_client->dev, &dev_attr_temp1_max);
-	device_create_file(&new_client->dev, &dev_attr_temp2_max);
-	device_create_file(&new_client->dev, &dev_attr_temp3_max);
-	device_create_file(&new_client->dev, &dev_attr_vrm);
-	device_create_file(&new_client->dev, &dev_attr_cpu0_vid);
-	device_create_file(&new_client->dev, &dev_attr_alarms);
-	device_create_file(&new_client->dev, &dev_attr_pwm1_auto_channels);
-	device_create_file(&new_client->dev, &dev_attr_pwm2_auto_channels);
-	device_create_file(&new_client->dev, &dev_attr_pwm3_auto_channels);
-	device_create_file(&new_client->dev, &dev_attr_pwm1_auto_pwm_min);
-	device_create_file(&new_client->dev, &dev_attr_pwm2_auto_pwm_min);
-	device_create_file(&new_client->dev, &dev_attr_pwm3_auto_pwm_min);
-	device_create_file(&new_client->dev, &dev_attr_pwm1_auto_pwm_minctl);
-	device_create_file(&new_client->dev, &dev_attr_pwm2_auto_pwm_minctl);
-	device_create_file(&new_client->dev, &dev_attr_pwm3_auto_pwm_minctl);
-	device_create_file(&new_client->dev, &dev_attr_pwm1_auto_pwm_freq);
-	device_create_file(&new_client->dev, &dev_attr_pwm2_auto_pwm_freq);
-	device_create_file(&new_client->dev, &dev_attr_pwm3_auto_pwm_freq);
-	device_create_file(&new_client->dev, &dev_attr_temp1_auto_temp_off);
-	device_create_file(&new_client->dev, &dev_attr_temp2_auto_temp_off);
-	device_create_file(&new_client->dev, &dev_attr_temp3_auto_temp_off);
-	device_create_file(&new_client->dev, &dev_attr_temp1_auto_temp_min);
-	device_create_file(&new_client->dev, &dev_attr_temp2_auto_temp_min);
-	device_create_file(&new_client->dev, &dev_attr_temp3_auto_temp_min);
-	device_create_file(&new_client->dev, &dev_attr_temp1_auto_temp_max);
-	device_create_file(&new_client->dev, &dev_attr_temp2_auto_temp_max);
-	device_create_file(&new_client->dev, &dev_attr_temp3_auto_temp_max);
-	device_create_file(&new_client->dev, &dev_attr_temp1_auto_temp_crit);
-	device_create_file(&new_client->dev, &dev_attr_temp2_auto_temp_crit);
-	device_create_file(&new_client->dev, &dev_attr_temp3_auto_temp_crit);
-
-	return 0;
-
-	/* Error out and cleanup code */
-    ERROR1:
-	kfree(data);
-    ERROR0:
-	return err;
-}
-
-int lm85_detach_client(struct i2c_client *client)
-{
-	i2c_detach_client(client);
-	kfree(i2c_get_clientdata(client));
-	return 0;
-}
-
-
-int lm85_read_value(struct i2c_client *client, u8 reg)
-{
-	int res;
-
-	/* What size location is it? */
-	switch( reg ) {
-	case LM85_REG_FAN(0) :  /* Read WORD data */
-	case LM85_REG_FAN(1) :
-	case LM85_REG_FAN(2) :
-	case LM85_REG_FAN(3) :
-	case LM85_REG_FAN_MIN(0) :
-	case LM85_REG_FAN_MIN(1) :
-	case LM85_REG_FAN_MIN(2) :
-	case LM85_REG_FAN_MIN(3) :
-	case LM85_REG_ALARM1 :	/* Read both bytes at once */
-		res = i2c_smbus_read_byte_data(client, reg) & 0xff ;
-		res |= i2c_smbus_read_byte_data(client, reg+1) << 8 ;
-		break ;
-	case ADT7463_REG_TMIN_CTL1 :  /* Read WORD MSB, LSB */
-		res = i2c_smbus_read_byte_data(client, reg) << 8 ;
-		res |= i2c_smbus_read_byte_data(client, reg+1) & 0xff ;
-		break ;
-	default:	/* Read BYTE data */
-		res = i2c_smbus_read_byte_data(client, reg);
-		break ;
-	}
-
-	return res ;
-}
-
-int lm85_write_value(struct i2c_client *client, u8 reg, int value)
-{
-	int res ;
-
-	switch( reg ) {
-	case LM85_REG_FAN(0) :  /* Write WORD data */
-	case LM85_REG_FAN(1) :
-	case LM85_REG_FAN(2) :
-	case LM85_REG_FAN(3) :
-	case LM85_REG_FAN_MIN(0) :
-	case LM85_REG_FAN_MIN(1) :
-	case LM85_REG_FAN_MIN(2) :
-	case LM85_REG_FAN_MIN(3) :
-	/* NOTE: ALARM is read only, so not included here */
-		res = i2c_smbus_write_byte_data(client, reg, value & 0xff) ;
-		res |= i2c_smbus_write_byte_data(client, reg+1, (value>>8) & 0xff) ;
-		break ;
-	case ADT7463_REG_TMIN_CTL1 :  /* Write WORD MSB, LSB */
-		res = i2c_smbus_write_byte_data(client, reg, (value>>8) & 0xff);
-		res |= i2c_smbus_write_byte_data(client, reg+1, value & 0xff) ;
-		break ;
-	default:	/* Write BYTE data */
-		res = i2c_smbus_write_byte_data(client, reg, value);
-		break ;
-	}
-
-	return res ;
-}
-
-void lm85_init_client(struct i2c_client *client)
-{
-	int value;
-	struct lm85_data *data = i2c_get_clientdata(client);
-
-	dev_dbg(&client->dev, "Initializing device\n");
-
-	/* Warn if part was not "READY" */
-	value = lm85_read_value(client, LM85_REG_CONFIG);
-	dev_dbg(&client->dev, "LM85_REG_CONFIG is: 0x%02x\n", value);
-	if( value & 0x02 ) {
-		dev_err(&client->dev, "Client (%d,0x%02x) config is locked.\n",
-			    i2c_adapter_id(client->adapter), client->addr );
-	};
-	if( ! (value & 0x04) ) {
-		dev_err(&client->dev, "Client (%d,0x%02x) is not ready.\n",
-			    i2c_adapter_id(client->adapter), client->addr );
-	};
-	if( value & 0x10
-	    && ( data->type == adm1027
-		|| data->type == adt7463 ) ) {
-		dev_err(&client->dev, "Client (%d,0x%02x) VxI mode is set.  "
-			"Please report this to the lm85 maintainer.\n",
-			    i2c_adapter_id(client->adapter), client->addr );
-	};
-
-	/* WE INTENTIONALLY make no changes to the limits,
-	 *   offsets, pwms, fans and zones.  If they were
-	 *   configured, we don't want to mess with them.
-	 *   If they weren't, the default is 100% PWM, no
-	 *   control and will suffice until 'sensors -s'
-	 *   can be run by the user.
-	 */
-
-	/* Start monitoring */
-	value = lm85_read_value(client, LM85_REG_CONFIG);
-	/* Try to clear LOCK, Set START, save everything else */
-	value = (value & ~ 0x02) | 0x01 ;
-	dev_dbg(&client->dev, "Setting CONFIG to: 0x%02x\n", value);
-	lm85_write_value(client, LM85_REG_CONFIG, value);
-}
-
-static struct lm85_data *lm85_update_device(struct device *dev)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm85_data *data = i2c_get_clientdata(client);
-	int i;
-
-	down(&data->update_lock);
-
-	if ( !data->valid ||
-	     time_after(jiffies, data->last_reading + LM85_DATA_INTERVAL) ) {
-		/* Things that change quickly */
-		dev_dbg(&client->dev, "Reading sensor values\n");
-		
-		/* Have to read extended bits first to "freeze" the
-		 * more significant bits that are read later.
-		 */
-		if ( (data->type == adm1027) || (data->type == adt7463) ) {
-			int ext1 = lm85_read_value(client,
-						   ADM1027_REG_EXTEND_ADC1);
-			int ext2 =  lm85_read_value(client,
-						    ADM1027_REG_EXTEND_ADC2);
-			int val = (ext1 << 8) + ext2;
-
-			for(i = 0; i <= 4; i++)
-				data->in_ext[i] = (val>>(i * 2))&0x03;
-
-			for(i = 0; i <= 2; i++)
-				data->temp_ext[i] = (val>>((i + 5) * 2))&0x03;
-		}
-
-		/* adc_scale is 2^(number of LSBs). There are 4 extra bits in
-		   the emc6d102 and 2 in the adt7463 and adm1027. In all
-		   other chips ext is always 0 and the value of scale is
-		   irrelevant. So it is left in 4*/
-		data->adc_scale = (data->type == emc6d102 ) ? 16 : 4;
-
-		for (i = 0; i <= 4; ++i) {
-			data->in[i] =
-			    lm85_read_value(client, LM85_REG_IN(i));
-		}
-
-		for (i = 0; i <= 3; ++i) {
-			data->fan[i] =
-			    lm85_read_value(client, LM85_REG_FAN(i));
-		}
-
-		for (i = 0; i <= 2; ++i) {
-			data->temp[i] =
-			    lm85_read_value(client, LM85_REG_TEMP(i));
-		}
-
-		for (i = 0; i <= 2; ++i) {
-			data->pwm[i] =
-			    lm85_read_value(client, LM85_REG_PWM(i));
-		}
-
-		data->alarms = lm85_read_value(client, LM85_REG_ALARM1);
-
-		if ( data->type == adt7463 ) {
-			if( data->therm_total < ULONG_MAX - 256 ) {
-			    data->therm_total +=
-				lm85_read_value(client, ADT7463_REG_THERM );
-			}
-		} else if ( data->type == emc6d100 ) {
-			/* Three more voltage sensors */
-			for (i = 5; i <= 7; ++i) {
-				data->in[i] =
-					lm85_read_value(client, EMC6D100_REG_IN(i));
-			}
-			/* More alarm bits */
-			data->alarms |=
-				lm85_read_value(client, EMC6D100_REG_ALARM3) << 16;
-		} else if (data->type == emc6d102 ) {
-			/* Have to read LSB bits after the MSB ones because
-			   the reading of the MSB bits has frozen the
-			   LSBs (backward from the ADM1027).
-			 */
-			int ext1 = lm85_read_value(client,
-						   EMC6D102_REG_EXTEND_ADC1);
-			int ext2 = lm85_read_value(client,
-						   EMC6D102_REG_EXTEND_ADC2);
-			int ext3 = lm85_read_value(client,
-						   EMC6D102_REG_EXTEND_ADC3);
-			int ext4 = lm85_read_value(client,
-						   EMC6D102_REG_EXTEND_ADC4);
-			data->in_ext[0] = ext3 & 0x0f;
-			data->in_ext[1] = ext4 & 0x0f;
-			data->in_ext[2] = (ext4 >> 4) & 0x0f;
-			data->in_ext[3] = (ext3 >> 4) & 0x0f;
-			data->in_ext[4] = (ext2 >> 4) & 0x0f;
-
-			data->temp_ext[0] = ext1 & 0x0f;
-			data->temp_ext[1] = ext2 & 0x0f;
-			data->temp_ext[2] = (ext1 >> 4) & 0x0f;
-		}
-
-		data->last_reading = jiffies ;
-	};  /* last_reading */
-
-	if ( !data->valid ||
-	     time_after(jiffies, data->last_config + LM85_CONFIG_INTERVAL) ) {
-		/* Things that don't change often */
-		dev_dbg(&client->dev, "Reading config values\n");
-
-		for (i = 0; i <= 4; ++i) {
-			data->in_min[i] =
-			    lm85_read_value(client, LM85_REG_IN_MIN(i));
-			data->in_max[i] =
-			    lm85_read_value(client, LM85_REG_IN_MAX(i));
-		}
-
-		if ( data->type == emc6d100 ) {
-			for (i = 5; i <= 7; ++i) {
-				data->in_min[i] =
-					lm85_read_value(client, EMC6D100_REG_IN_MIN(i));
-				data->in_max[i] =
-					lm85_read_value(client, EMC6D100_REG_IN_MAX(i));
-			}
-		}
-
-		for (i = 0; i <= 3; ++i) {
-			data->fan_min[i] =
-			    lm85_read_value(client, LM85_REG_FAN_MIN(i));
-		}
-
-		for (i = 0; i <= 2; ++i) {
-			data->temp_min[i] =
-			    lm85_read_value(client, LM85_REG_TEMP_MIN(i));
-			data->temp_max[i] =
-			    lm85_read_value(client, LM85_REG_TEMP_MAX(i));
-		}
-
-		data->vid = lm85_read_value(client, LM85_REG_VID);
-
-		for (i = 0; i <= 2; ++i) {
-			int val ;
-			data->autofan[i].config =
-			    lm85_read_value(client, LM85_REG_AFAN_CONFIG(i));
-			val = lm85_read_value(client, LM85_REG_AFAN_RANGE(i));
-			data->autofan[i].freq = val & 0x07 ;
-			data->zone[i].range = (val >> 4) & 0x0f ;
-			data->autofan[i].min_pwm =
-			    lm85_read_value(client, LM85_REG_AFAN_MINPWM(i));
-			data->zone[i].limit =
-			    lm85_read_value(client, LM85_REG_AFAN_LIMIT(i));
-			data->zone[i].critical =
-			    lm85_read_value(client, LM85_REG_AFAN_CRITICAL(i));
-		}
-
-		i = lm85_read_value(client, LM85_REG_AFAN_SPIKE1);
-		data->smooth[0] = i & 0x0f ;
-		data->syncpwm3 = i & 0x10 ;  /* Save PWM3 config */
-		data->autofan[0].min_off = (i & 0x20) != 0 ;
-		data->autofan[1].min_off = (i & 0x40) != 0 ;
-		data->autofan[2].min_off = (i & 0x80) != 0 ;
-		i = lm85_read_value(client, LM85_REG_AFAN_SPIKE2);
-		data->smooth[1] = (i>>4) & 0x0f ;
-		data->smooth[2] = i & 0x0f ;
-
-		i = lm85_read_value(client, LM85_REG_AFAN_HYST1);
-		data->zone[0].hyst = (i>>4) & 0x0f ;
-		data->zone[1].hyst = i & 0x0f ;
-
-		i = lm85_read_value(client, LM85_REG_AFAN_HYST2);
-		data->zone[2].hyst = (i>>4) & 0x0f ;
-
-		if ( (data->type == lm85b) || (data->type == lm85c) ) {
-			data->tach_mode = lm85_read_value(client,
-				LM85_REG_TACH_MODE );
-			data->spinup_ctl = lm85_read_value(client,
-				LM85_REG_SPINUP_CTL );
-		} else if ( (data->type == adt7463) || (data->type == adm1027) ) {
-			if ( data->type == adt7463 ) {
-				for (i = 0; i <= 2; ++i) {
-				    data->oppoint[i] = lm85_read_value(client,
-					ADT7463_REG_OPPOINT(i) );
-				}
-				data->tmin_ctl = lm85_read_value(client,
-					ADT7463_REG_TMIN_CTL1 );
-				data->therm_limit = lm85_read_value(client,
-					ADT7463_REG_THERM_LIMIT );
-			}
-			for (i = 0; i <= 2; ++i) {
-			    data->temp_offset[i] = lm85_read_value(client,
-				ADM1027_REG_TEMP_OFFSET(i) );
-			}
-			data->tach_mode = lm85_read_value(client,
-				ADM1027_REG_CONFIG3 );
-			data->fan_ppr = lm85_read_value(client,
-				ADM1027_REG_FAN_PPR );
-		}
-	
-		data->last_config = jiffies;
-	};  /* last_config */
-
-	data->valid = 1;
-
-	up(&data->update_lock);
-
-	return data;
-}
-
-
-static int __init sm_lm85_init(void)
-{
-	return i2c_add_driver(&lm85_driver);
-}
-
-static void  __exit sm_lm85_exit(void)
-{
-	i2c_del_driver(&lm85_driver);
-}
-
-/* Thanks to Richard Barrington for adding the LM85 to sensors-detect.
- * Thanks to Margit Schubert-While <margitsw@t-online.de> for help with
- *     post 2.7.0 CVS changes.
- */
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Philip Pokorny <ppokorny@penguincomputing.com>, Margit Schubert-While <margitsw@t-online.de>, Justin Thiessen <jthiessen@penguincomputing.com");
-MODULE_DESCRIPTION("LM85-B, LM85-C driver");
-
-module_init(sm_lm85_init);
-module_exit(sm_lm85_exit);
diff --git a/drivers/i2c/chips/lm87.c b/drivers/i2c/chips/lm87.c
deleted file mode 100644
--- a/drivers/i2c/chips/lm87.c
+++ /dev/null
@@ -1,829 +0,0 @@
-/*
- * lm87.c
- *
- * Copyright (C) 2000       Frodo Looijaard <frodol@dds.nl>
- *                          Philip Edelbrock <phil@netroedge.com>
- *                          Stephen Rousset <stephen.rousset@rocketlogix.com>
- *                          Dan Eaton <dan.eaton@rocketlogix.com>
- * Copyright (C) 2004       Jean Delvare <khali@linux-fr.org>
- *
- * Original port to Linux 2.6 by Jeff Oliver.
- *
- * The LM87 is a sensor chip made by National Semiconductor. It monitors up
- * to 8 voltages (including its own power source), up to three temperatures
- * (its own plus up to two external ones) and up to two fans. The default
- * configuration is 6 voltages, two temperatures and two fans (see below).
- * Voltages are scaled internally with ratios such that the nominal value of
- * each voltage correspond to a register value of 192 (which means a
- * resolution of about 0.5% of the nominal value). Temperature values are
- * reported with a 1 deg resolution and a 3-4 deg accuracy. Complete
- * datasheet can be obtained from National's website at:
- *   http://www.national.com/pf/LM/LM87.html
- *
- * Some functions share pins, so not all functions are available at the same
- * time. Which are depends on the hardware setup. This driver assumes that
- * the BIOS configured the chip correctly. In that respect, it  differs from
- * the original driver (from lm_sensors for Linux 2.4), which would force the
- * LM87 to an arbitrary, compile-time chosen mode, regardless of the actual
- * chipset wiring.
- * For reference, here is the list of exclusive functions:
- *  - in0+in5 (default) or temp3
- *  - fan1 (default) or in6
- *  - fan2 (default) or in7
- *  - VID lines (default) or IRQ lines (not handled by this driver)
- *
- * The LM87 additionally features an analog output, supposedly usable to
- * control the speed of a fan. All new chips use pulse width modulation
- * instead. The LM87 is the only hardware monitoring chipset I know of
- * which uses amplitude modulation. Be careful when using this feature.
- *
- * 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 <linux/config.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/jiffies.h>
-#include <linux/i2c.h>
-#include <linux/i2c-sensor.h>
-#include <linux/i2c-vid.h>
-
-/*
- * Addresses to scan
- * LM87 has three possible addresses: 0x2c, 0x2d and 0x2e.
- */
-
-static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END };
-static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
-
-/*
- * Insmod parameters
- */
-
-SENSORS_INSMOD_1(lm87);
-
-/*
- * The LM87 registers
- */
-
-/* nr in 0..5 */
-#define LM87_REG_IN(nr)			(0x20 + (nr))
-#define LM87_REG_IN_MAX(nr)		(0x2B + (nr) * 2)
-#define LM87_REG_IN_MIN(nr)		(0x2C + (nr) * 2)
-/* nr in 0..1 */
-#define LM87_REG_AIN(nr)		(0x28 + (nr))
-#define LM87_REG_AIN_MIN(nr)		(0x1A + (nr))
-#define LM87_REG_AIN_MAX(nr)		(0x3B + (nr))
-
-static u8 LM87_REG_TEMP[3] = { 0x27, 0x26, 0x20 };
-static u8 LM87_REG_TEMP_HIGH[3] = { 0x39, 0x37, 0x2B };
-static u8 LM87_REG_TEMP_LOW[3] = { 0x3A, 0x38, 0x2C };
-
-#define LM87_REG_TEMP_HW_INT_LOCK	0x13
-#define LM87_REG_TEMP_HW_EXT_LOCK	0x14
-#define LM87_REG_TEMP_HW_INT		0x17
-#define LM87_REG_TEMP_HW_EXT		0x18
-
-/* nr in 0..1 */
-#define LM87_REG_FAN(nr)		(0x28 + (nr))
-#define LM87_REG_FAN_MIN(nr)		(0x3B + (nr))
-#define LM87_REG_AOUT			0x19
-
-#define LM87_REG_CONFIG			0x40
-#define LM87_REG_CHANNEL_MODE		0x16
-#define LM87_REG_VID_FAN_DIV		0x47
-#define LM87_REG_VID4			0x49
-
-#define LM87_REG_ALARMS1		0x41
-#define LM87_REG_ALARMS2		0x42
-
-#define LM87_REG_COMPANY_ID		0x3E
-#define LM87_REG_REVISION		0x3F
-
-/*
- * Conversions and various macros
- * The LM87 uses signed 8-bit values for temperatures.
- */
-
-#define IN_FROM_REG(reg,scale)	(((reg) * (scale) + 96) / 192)
-#define IN_TO_REG(val,scale)	((val) <= 0 ? 0 : \
-				 (val) * 192 >= (scale) * 255 ? 255 : \
-				 ((val) * 192 + (scale)/2) / (scale))
-
-#define TEMP_FROM_REG(reg)	((reg) * 1000)
-#define TEMP_TO_REG(val)	((val) <= -127500 ? -128 : \
-				 (val) >= 126500 ? 127 : \
-				 (((val) < 0 ? (val)-500 : (val)+500) / 1000))
-
-#define FAN_FROM_REG(reg,div)	((reg) == 255 || (reg) == 0 ? 0 : \
-				 1350000 + (reg)*(div) / 2) / ((reg)*(div))
-#define FAN_TO_REG(val,div)	((val)*(div) * 255 <= 1350000 ? 255 : \
-				 (1350000 + (val)*(div) / 2) / ((val)*(div)))
-
-#define FAN_DIV_FROM_REG(reg)	(1 << (reg))
-
-/* analog out is 9.80mV/LSB */
-#define AOUT_FROM_REG(reg)	(((reg) * 98 + 5) / 10)
-#define AOUT_TO_REG(val)	((val) <= 0 ? 0 : \
-				 (val) >= 2500 ? 255 : \
-				 ((val) * 10 + 49) / 98)
-
-/* nr in 0..1 */
-#define CHAN_NO_FAN(nr)		(1 << (nr))
-#define CHAN_TEMP3		(1 << 2)
-#define CHAN_VCC_5V		(1 << 3)
-#define CHAN_NO_VID		(1 << 8)
-
-/*
- * Functions declaration
- */
-
-static int lm87_attach_adapter(struct i2c_adapter *adapter);
-static int lm87_detect(struct i2c_adapter *adapter, int address, int kind);
-static void lm87_init_client(struct i2c_client *client);
-static int lm87_detach_client(struct i2c_client *client);
-static struct lm87_data *lm87_update_device(struct device *dev);
-
-/*
- * Driver data (common to all clients)
- */
-
-static struct i2c_driver lm87_driver = {
-	.owner		= THIS_MODULE,
-	.name		= "lm87",
-	.id		= I2C_DRIVERID_LM87,
-	.flags		= I2C_DF_NOTIFY,
-	.attach_adapter	= lm87_attach_adapter,
-	.detach_client	= lm87_detach_client,
-};
-
-/*
- * Client data (each client gets its own)
- */
-
-struct lm87_data {
-	struct i2c_client client;
-	struct semaphore update_lock;
-	char valid; /* zero until following fields are valid */
-	unsigned long last_updated; /* In jiffies */
-
-	u8 channel;		/* register value */
-
-	u8 in[8];		/* register value */
-	u8 in_max[8];		/* register value */
-	u8 in_min[8];		/* register value */
-	u16 in_scale[8];
-
-	s8 temp[3];		/* register value */
-	s8 temp_high[3];	/* register value */
-	s8 temp_low[3];		/* register value */
-	s8 temp_crit_int;	/* min of two register values */
-	s8 temp_crit_ext;	/* min of two register values */
-
-	u8 fan[2];		/* register value */
-	u8 fan_min[2];		/* register value */
-	u8 fan_div[2];		/* register value, shifted right */
-	u8 aout;		/* register value */
-
-	u16 alarms;		/* register values, combined */
-	u8 vid;			/* register values, combined */
-	u8 vrm;
-};
-
-/*
- * Sysfs stuff
- */
-
-static inline int lm87_read_value(struct i2c_client *client, u8 reg)
-{
-	return i2c_smbus_read_byte_data(client, reg);
-}
-
-static inline int lm87_write_value(struct i2c_client *client, u8 reg, u8 value)
-{
-	return i2c_smbus_write_byte_data(client, reg, value);
-}
-
-#define show_in(offset) \
-static ssize_t show_in##offset##_input(struct device *dev, char *buf) \
-{ \
-	struct lm87_data *data = lm87_update_device(dev); \
-	return sprintf(buf, "%u\n", IN_FROM_REG(data->in[offset], \
-		       data->in_scale[offset])); \
-} \
-static ssize_t show_in##offset##_min(struct device *dev, char *buf) \
-{ \
-	struct lm87_data *data = lm87_update_device(dev); \
-	return sprintf(buf, "%u\n", IN_FROM_REG(data->in_min[offset], \
-		       data->in_scale[offset])); \
-} \
-static ssize_t show_in##offset##_max(struct device *dev, char *buf) \
-{ \
-	struct lm87_data *data = lm87_update_device(dev); \
-	return sprintf(buf, "%u\n", IN_FROM_REG(data->in_max[offset], \
-		       data->in_scale[offset])); \
-} \
-static DEVICE_ATTR(in##offset##_input, S_IRUGO, \
-		show_in##offset##_input, NULL);
-show_in(0);
-show_in(1);
-show_in(2);
-show_in(3);
-show_in(4);
-show_in(5);
-show_in(6);
-show_in(7);
-
-static void set_in_min(struct device *dev, const char *buf, int nr)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm87_data *data = i2c_get_clientdata(client);
-	long val = simple_strtol(buf, NULL, 10);
-
-	down(&data->update_lock);
-	data->in_min[nr] = IN_TO_REG(val, data->in_scale[nr]);
-	lm87_write_value(client, nr<6 ? LM87_REG_IN_MIN(nr) :
-			 LM87_REG_AIN_MIN(nr-6), data->in_min[nr]);
-	up(&data->update_lock);
-}
-
-static void set_in_max(struct device *dev, const char *buf, int nr)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm87_data *data = i2c_get_clientdata(client);
-	long val = simple_strtol(buf, NULL, 10);
-
-	down(&data->update_lock);
-	data->in_max[nr] = IN_TO_REG(val, data->in_scale[nr]);
-	lm87_write_value(client, nr<6 ? LM87_REG_IN_MAX(nr) :
-			 LM87_REG_AIN_MAX(nr-6), data->in_max[nr]);
-	up(&data->update_lock);
-}
-
-#define set_in(offset) \
-static ssize_t set_in##offset##_min(struct device *dev, \
-		const char *buf, size_t count) \
-{ \
-	set_in_min(dev, buf, offset); \
-	return count; \
-} \
-static ssize_t set_in##offset##_max(struct device *dev, \
-		const char *buf, size_t count) \
-{ \
-	set_in_max(dev, buf, offset); \
-	return count; \
-} \
-static DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \
-		show_in##offset##_min, set_in##offset##_min); \
-static DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \
-		show_in##offset##_max, set_in##offset##_max);
-set_in(0);
-set_in(1);
-set_in(2);
-set_in(3);
-set_in(4);
-set_in(5);
-set_in(6);
-set_in(7);
-
-#define show_temp(offset) \
-static ssize_t show_temp##offset##_input(struct device *dev, char *buf) \
-{ \
-	struct lm87_data *data = lm87_update_device(dev); \
-	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp[offset-1])); \
-} \
-static ssize_t show_temp##offset##_low(struct device *dev, char *buf) \
-{ \
-	struct lm87_data *data = lm87_update_device(dev); \
-	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_low[offset-1])); \
-} \
-static ssize_t show_temp##offset##_high(struct device *dev, char *buf) \
-{ \
-	struct lm87_data *data = lm87_update_device(dev); \
-	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_high[offset-1])); \
-}\
-static DEVICE_ATTR(temp##offset##_input, S_IRUGO, \
-		show_temp##offset##_input, NULL);
-show_temp(1);
-show_temp(2);
-show_temp(3);
-
-static void set_temp_low(struct device *dev, const char *buf, int nr)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm87_data *data = i2c_get_clientdata(client);
-	long val = simple_strtol(buf, NULL, 10);
-
-	down(&data->update_lock);
-	data->temp_low[nr] = TEMP_TO_REG(val);
-	lm87_write_value(client, LM87_REG_TEMP_LOW[nr], data->temp_low[nr]);
-	up(&data->update_lock);
-}
-
-static void set_temp_high(struct device *dev, const char *buf, int nr)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm87_data *data = i2c_get_clientdata(client);
-	long val = simple_strtol(buf, NULL, 10);
-
-	down(&data->update_lock);
-	data->temp_high[nr] = TEMP_TO_REG(val);
-	lm87_write_value(client, LM87_REG_TEMP_HIGH[nr], data->temp_high[nr]);
-	up(&data->update_lock);
-}
-
-#define set_temp(offset) \
-static ssize_t set_temp##offset##_low(struct device *dev, \
-		const char *buf, size_t count) \
-{ \
-	set_temp_low(dev, buf, offset-1); \
-	return count; \
-} \
-static ssize_t set_temp##offset##_high(struct device *dev, \
-		const char *buf, size_t count) \
-{ \
-	set_temp_high(dev, buf, offset-1); \
-	return count; \
-} \
-static DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR, \
-		show_temp##offset##_high, set_temp##offset##_high); \
-static DEVICE_ATTR(temp##offset##_min, S_IRUGO | S_IWUSR, \
-		show_temp##offset##_low, set_temp##offset##_low);
-set_temp(1);
-set_temp(2);
-set_temp(3);
-
-static ssize_t show_temp_crit_int(struct device *dev, char *buf)
-{
-	struct lm87_data *data = lm87_update_device(dev);
-	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_crit_int));
-}
-
-static ssize_t show_temp_crit_ext(struct device *dev, char *buf)
-{
-	struct lm87_data *data = lm87_update_device(dev);
-	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_crit_ext));
-}
-
-static DEVICE_ATTR(temp1_crit, S_IRUGO, show_temp_crit_int, NULL);
-static DEVICE_ATTR(temp2_crit, S_IRUGO, show_temp_crit_ext, NULL);
-static DEVICE_ATTR(temp3_crit, S_IRUGO, show_temp_crit_ext, NULL);
-
-#define show_fan(offset) \
-static ssize_t show_fan##offset##_input(struct device *dev, char *buf) \
-{ \
-	struct lm87_data *data = lm87_update_device(dev); \
-	return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[offset-1], \
-		       FAN_DIV_FROM_REG(data->fan_div[offset-1]))); \
-} \
-static ssize_t show_fan##offset##_min(struct device *dev, char *buf) \
-{ \
-	struct lm87_data *data = lm87_update_device(dev); \
-	return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan_min[offset-1], \
-		       FAN_DIV_FROM_REG(data->fan_div[offset-1]))); \
-} \
-static ssize_t show_fan##offset##_div(struct device *dev, char *buf) \
-{ \
-	struct lm87_data *data = lm87_update_device(dev); \
-	return sprintf(buf, "%d\n", FAN_DIV_FROM_REG(data->fan_div[offset-1])); \
-} \
-static DEVICE_ATTR(fan##offset##_input, S_IRUGO, \
-		show_fan##offset##_input, NULL);
-show_fan(1);
-show_fan(2);
-
-static void set_fan_min(struct device *dev, const char *buf, int nr)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm87_data *data = i2c_get_clientdata(client);
-	long val = simple_strtol(buf, NULL, 10);
-
-	down(&data->update_lock);
-	data->fan_min[nr] = FAN_TO_REG(val,
-			    FAN_DIV_FROM_REG(data->fan_div[nr]));
-	lm87_write_value(client, LM87_REG_FAN_MIN(nr), data->fan_min[nr]);
-	up(&data->update_lock);
-}
-
-/* Note: we save and restore the fan minimum here, because its value is
-   determined in part by the fan clock divider.  This follows the principle
-   of least suprise; the user doesn't expect the fan minimum to change just
-   because the divider changed. */
-static ssize_t set_fan_div(struct device *dev, const char *buf,
-		size_t count, int nr)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm87_data *data = i2c_get_clientdata(client);
-	long val = simple_strtol(buf, NULL, 10);
-	unsigned long min;
-	u8 reg;
-
-	down(&data->update_lock);
-	min = FAN_FROM_REG(data->fan_min[nr],
-			   FAN_DIV_FROM_REG(data->fan_div[nr]));
-
-	switch (val) {
-	case 1: data->fan_div[nr] = 0; break;
-	case 2: data->fan_div[nr] = 1; break;
-	case 4: data->fan_div[nr] = 2; break;
-	case 8: data->fan_div[nr] = 3; break;
-	default:
-		up(&data->update_lock);
-		return -EINVAL;
-	}
-
-	reg = lm87_read_value(client, LM87_REG_VID_FAN_DIV);
-	switch (nr) {
-	case 0:
-	    reg = (reg & 0xCF) | (data->fan_div[0] << 4);
-	    break;
-	case 1:
-	    reg = (reg & 0x3F) | (data->fan_div[1] << 6);
-	    break;
-	}
-	lm87_write_value(client, LM87_REG_VID_FAN_DIV, reg);
-
-	data->fan_min[nr] = FAN_TO_REG(min, val);
-	lm87_write_value(client, LM87_REG_FAN_MIN(nr),
-			 data->fan_min[nr]);
-	up(&data->update_lock);
-
-	return count;
-}
-
-#define set_fan(offset) \
-static ssize_t set_fan##offset##_min(struct device *dev, const char *buf, \
-		size_t count) \
-{ \
-	set_fan_min(dev, buf, offset-1); \
-	return count; \
-} \
-static ssize_t set_fan##offset##_div(struct device *dev, const char *buf, \
-		size_t count) \
-{ \
-	return set_fan_div(dev, buf, count, offset-1); \
-} \
-static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \
-		show_fan##offset##_min, set_fan##offset##_min); \
-static DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, \
-		show_fan##offset##_div, set_fan##offset##_div);
-set_fan(1);
-set_fan(2);
-
-static ssize_t show_alarms(struct device *dev, char *buf)
-{
-	struct lm87_data *data = lm87_update_device(dev);
-	return sprintf(buf, "%d\n", data->alarms);
-}
-static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
-
-static ssize_t show_vid(struct device *dev, char *buf)
-{
-	struct lm87_data *data = lm87_update_device(dev);
-	return sprintf(buf, "%d\n", vid_from_reg(data->vid, data->vrm));
-}
-static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL);
-
-static ssize_t show_vrm(struct device *dev, char *buf)
-{
-	struct lm87_data *data = lm87_update_device(dev);
-	return sprintf(buf, "%d\n", data->vrm);
-}
-static ssize_t set_vrm(struct device *dev, const char *buf, size_t count)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm87_data *data = i2c_get_clientdata(client);
-	data->vrm = simple_strtoul(buf, NULL, 10);
-	return count;
-}
-static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm, set_vrm);
-
-static ssize_t show_aout(struct device *dev, char *buf)
-{
-	struct lm87_data *data = lm87_update_device(dev);
-	return sprintf(buf, "%d\n", AOUT_FROM_REG(data->aout));
-}
-static ssize_t set_aout(struct device *dev, const char *buf, size_t count)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm87_data *data = i2c_get_clientdata(client);
-	long val = simple_strtol(buf, NULL, 10);
-
-	down(&data->update_lock);
-	data->aout = AOUT_TO_REG(val);
-	lm87_write_value(client, LM87_REG_AOUT, data->aout);
-	up(&data->update_lock);
-	return count;
-}
-static DEVICE_ATTR(aout_output, S_IRUGO | S_IWUSR, show_aout, set_aout);
-
-/*
- * Real code
- */
-
-static int lm87_attach_adapter(struct i2c_adapter *adapter)
-{
-	if (!(adapter->class & I2C_CLASS_HWMON))
-		return 0;
-	return i2c_detect(adapter, &addr_data, lm87_detect);
-}
-
-/*
- * The following function does more than just detection. If detection
- * succeeds, it also registers the new chip.
- */
-static int lm87_detect(struct i2c_adapter *adapter, int address, int kind)
-{
-	struct i2c_client *new_client;
-	struct lm87_data *data;
-	int err = 0;
-
-	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
-		goto exit;
-
-	if (!(data = kmalloc(sizeof(struct lm87_data), GFP_KERNEL))) {
-		err = -ENOMEM;
-		goto exit;
-	}
-	memset(data, 0, sizeof(struct lm87_data));
-
-	/* The common I2C client data is placed right before the
-	   LM87-specific data. */
-	new_client = &data->client;
-	i2c_set_clientdata(new_client, data);
-	new_client->addr = address;
-	new_client->adapter = adapter;
-	new_client->driver = &lm87_driver;
-	new_client->flags = 0;
-
-	/* Default to an LM87 if forced */
-	if (kind == 0)
-		kind = lm87;
-
-	/* Now, we do the remaining detection. */
-	if (kind < 0) {
-		u8 rev = lm87_read_value(new_client, LM87_REG_REVISION);
-
-		if (rev < 0x01 || rev > 0x08
-		 || (lm87_read_value(new_client, LM87_REG_CONFIG) & 0x80)
-		 || lm87_read_value(new_client, LM87_REG_COMPANY_ID) != 0x02) {
-			dev_dbg(&adapter->dev,
-				"LM87 detection failed at 0x%02x.\n",
-				address);
-			goto exit_free;
-		}
-	}
-
-	/* We can fill in the remaining client fields */
-	strlcpy(new_client->name, "lm87", I2C_NAME_SIZE);
-	data->valid = 0;
-	init_MUTEX(&data->update_lock);
-
-	/* Tell the I2C layer a new client has arrived */
-	if ((err = i2c_attach_client(new_client)))
-		goto exit_free;
-
-	/* Initialize the LM87 chip */
-	lm87_init_client(new_client);
-
-	data->in_scale[0] = 2500;
-	data->in_scale[1] = 2700;
-	data->in_scale[2] = (data->channel & CHAN_VCC_5V) ? 5000 : 3300;
-	data->in_scale[3] = 5000;
-	data->in_scale[4] = 12000;
-	data->in_scale[5] = 2700;
-	data->in_scale[6] = 1875;
-	data->in_scale[7] = 1875;
-
-	/* Register sysfs hooks */
-	device_create_file(&new_client->dev, &dev_attr_in1_input);
-	device_create_file(&new_client->dev, &dev_attr_in1_min);
-	device_create_file(&new_client->dev, &dev_attr_in1_max);
-	device_create_file(&new_client->dev, &dev_attr_in2_input);
-	device_create_file(&new_client->dev, &dev_attr_in2_min);
-	device_create_file(&new_client->dev, &dev_attr_in2_max);
-	device_create_file(&new_client->dev, &dev_attr_in3_input);
-	device_create_file(&new_client->dev, &dev_attr_in3_min);
-	device_create_file(&new_client->dev, &dev_attr_in3_max);
-	device_create_file(&new_client->dev, &dev_attr_in4_input);
-	device_create_file(&new_client->dev, &dev_attr_in4_min);
-	device_create_file(&new_client->dev, &dev_attr_in4_max);
-
-	if (data->channel & CHAN_NO_FAN(0)) {
-		device_create_file(&new_client->dev, &dev_attr_in6_input);
-		device_create_file(&new_client->dev, &dev_attr_in6_min);
-		device_create_file(&new_client->dev, &dev_attr_in6_max);
-	} else {
-		device_create_file(&new_client->dev, &dev_attr_fan1_input);
-		device_create_file(&new_client->dev, &dev_attr_fan1_min);
-		device_create_file(&new_client->dev, &dev_attr_fan1_div);
-	}
-	if (data->channel & CHAN_NO_FAN(1)) {
-		device_create_file(&new_client->dev, &dev_attr_in7_input);
-		device_create_file(&new_client->dev, &dev_attr_in7_min);
-		device_create_file(&new_client->dev, &dev_attr_in7_max);
-	} else {
-		device_create_file(&new_client->dev, &dev_attr_fan2_input);
-		device_create_file(&new_client->dev, &dev_attr_fan2_min);
-		device_create_file(&new_client->dev, &dev_attr_fan2_div);
-	}
-
-	device_create_file(&new_client->dev, &dev_attr_temp1_input);
-	device_create_file(&new_client->dev, &dev_attr_temp1_max);
-	device_create_file(&new_client->dev, &dev_attr_temp1_min);
-	device_create_file(&new_client->dev, &dev_attr_temp1_crit);
-	device_create_file(&new_client->dev, &dev_attr_temp2_input);
-	device_create_file(&new_client->dev, &dev_attr_temp2_max);
-	device_create_file(&new_client->dev, &dev_attr_temp2_min);
-	device_create_file(&new_client->dev, &dev_attr_temp2_crit);
-
-	if (data->channel & CHAN_TEMP3) {
-		device_create_file(&new_client->dev, &dev_attr_temp3_input);
-		device_create_file(&new_client->dev, &dev_attr_temp3_max);
-		device_create_file(&new_client->dev, &dev_attr_temp3_min);
-		device_create_file(&new_client->dev, &dev_attr_temp3_crit);
-	} else {
-		device_create_file(&new_client->dev, &dev_attr_in0_input);
-		device_create_file(&new_client->dev, &dev_attr_in0_min);
-		device_create_file(&new_client->dev, &dev_attr_in0_max);
-		device_create_file(&new_client->dev, &dev_attr_in5_input);
-		device_create_file(&new_client->dev, &dev_attr_in5_min);
-		device_create_file(&new_client->dev, &dev_attr_in5_max);
-	}
-
-	if (!(data->channel & CHAN_NO_VID)) {
-		device_create_file(&new_client->dev, &dev_attr_cpu0_vid);
-		device_create_file(&new_client->dev, &dev_attr_vrm);
-	}
-
-	device_create_file(&new_client->dev, &dev_attr_alarms);
-	device_create_file(&new_client->dev, &dev_attr_aout_output);
-
-	return 0;
-
-exit_free:
-	kfree(data);
-exit:
-	return err;
-}
-
-static void lm87_init_client(struct i2c_client *client)
-{
-	struct lm87_data *data = i2c_get_clientdata(client);
-	u8 config;
-
-	data->channel = lm87_read_value(client, LM87_REG_CHANNEL_MODE);
-	data->vrm = i2c_which_vrm();
-
-	config = lm87_read_value(client, LM87_REG_CONFIG);
-	if (!(config & 0x01)) {
-		int i;
-
-		/* Limits are left uninitialized after power-up */
-		for (i = 1; i < 6; i++) {
-			lm87_write_value(client, LM87_REG_IN_MIN(i), 0x00);
-			lm87_write_value(client, LM87_REG_IN_MAX(i), 0xFF);
-		}
-		for (i = 0; i < 2; i++) {
-			lm87_write_value(client, LM87_REG_TEMP_HIGH[i], 0x7F);
-			lm87_write_value(client, LM87_REG_TEMP_LOW[i], 0x00);
-			lm87_write_value(client, LM87_REG_AIN_MIN(i), 0x00);
-			lm87_write_value(client, LM87_REG_AIN_MAX(i), 0xFF);
-		}
-		if (data->channel & CHAN_TEMP3) {
-			lm87_write_value(client, LM87_REG_TEMP_HIGH[2], 0x7F);
-			lm87_write_value(client, LM87_REG_TEMP_LOW[2], 0x00);
-		} else {
-			lm87_write_value(client, LM87_REG_IN_MIN(0), 0x00);
-			lm87_write_value(client, LM87_REG_IN_MAX(0), 0xFF);
-		}
-	}
-	if ((config & 0x81) != 0x01) {
-		/* Start monitoring */
-		lm87_write_value(client, LM87_REG_CONFIG,
-				 (config & 0xF7) | 0x01);
-	}
-}
-
-static int lm87_detach_client(struct i2c_client *client)
-{
-	int err;
-
-	if ((err = i2c_detach_client(client))) {
-		dev_err(&client->dev, "Client deregistration failed, "
-			"client not detached.\n");
-		return err;
-	}
-
-	kfree(i2c_get_clientdata(client));
-	return 0;
-}
-
-static struct lm87_data *lm87_update_device(struct device *dev)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm87_data *data = i2c_get_clientdata(client);
-
-	down(&data->update_lock);
-
-	if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
-		int i, j;
-
-		dev_dbg(&client->dev, "Updating data.\n");
-
-		i = (data->channel & CHAN_TEMP3) ? 1 : 0;
-		j = (data->channel & CHAN_TEMP3) ? 5 : 6;
-		for (; i < j; i++) {
-			data->in[i] = lm87_read_value(client,
-				      LM87_REG_IN(i));
-			data->in_min[i] = lm87_read_value(client,
-					  LM87_REG_IN_MIN(i));
-			data->in_max[i] = lm87_read_value(client,
-					  LM87_REG_IN_MAX(i));
-		}
-
-		for (i = 0; i < 2; i++) {
-			if (data->channel & CHAN_NO_FAN(i)) {
-				data->in[6+i] = lm87_read_value(client,
-						LM87_REG_AIN(i));
-				data->in_max[6+i] = lm87_read_value(client,
-						    LM87_REG_AIN_MAX(i));
-				data->in_min[6+i] = lm87_read_value(client,
-						    LM87_REG_AIN_MIN(i));
-
-			} else {
-				data->fan[i] = lm87_read_value(client,
-					       LM87_REG_FAN(i));
-				data->fan_min[i] = lm87_read_value(client,
-						   LM87_REG_FAN_MIN(i));
-			}
-		}
-
-		j = (data->channel & CHAN_TEMP3) ? 3 : 2;
-		for (i = 0 ; i < j; i++) {
-			data->temp[i] = lm87_read_value(client,
-					LM87_REG_TEMP[i]);
-			data->temp_high[i] = lm87_read_value(client,
-					     LM87_REG_TEMP_HIGH[i]);
-			data->temp_low[i] = lm87_read_value(client,
-					    LM87_REG_TEMP_LOW[i]);
-		}
-
-		i = lm87_read_value(client, LM87_REG_TEMP_HW_INT_LOCK);
-		j = lm87_read_value(client, LM87_REG_TEMP_HW_INT);
-		data->temp_crit_int = min(i, j);
-
-		i = lm87_read_value(client, LM87_REG_TEMP_HW_EXT_LOCK);
-		j = lm87_read_value(client, LM87_REG_TEMP_HW_EXT);
-		data->temp_crit_ext = min(i, j);
-
-		i = lm87_read_value(client, LM87_REG_VID_FAN_DIV);
-		data->fan_div[0] = (i >> 4) & 0x03;
-		data->fan_div[1] = (i >> 6) & 0x03;
-		data->vid = (i & 0x0F)
-			  | (lm87_read_value(client, LM87_REG_VID4) & 0x01)
-			     << 4;
-
-		data->alarms = lm87_read_value(client, LM87_REG_ALARMS1)
-			     | (lm87_read_value(client, LM87_REG_ALARMS2)
-				<< 8);
-		data->aout = lm87_read_value(client, LM87_REG_AOUT);
-
-		data->last_updated = jiffies;
-		data->valid = 1;
-	}
-
-	up(&data->update_lock);
-
-	return data;
-}
-
-static int __init sensors_lm87_init(void)
-{
-	return i2c_add_driver(&lm87_driver);
-}
-
-static void __exit sensors_lm87_exit(void)
-{
-	i2c_del_driver(&lm87_driver);
-}
-
-MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org> and others");
-MODULE_DESCRIPTION("LM87 driver");
-MODULE_LICENSE("GPL");
-
-module_init(sensors_lm87_init);
-module_exit(sensors_lm87_exit);
diff --git a/drivers/i2c/chips/lm90.c b/drivers/i2c/chips/lm90.c
deleted file mode 100644
--- a/drivers/i2c/chips/lm90.c
+++ /dev/null
@@ -1,626 +0,0 @@
-/*
- * lm90.c - Part of lm_sensors, Linux kernel modules for hardware
- *          monitoring
- * Copyright (C) 2003-2004  Jean Delvare <khali@linux-fr.org>
- *
- * Based on the lm83 driver. The LM90 is a sensor chip made by National
- * Semiconductor. It reports up to two temperatures (its own plus up to
- * one external one) with a 0.125 deg resolution (1 deg for local
- * temperature) and a 3-4 deg accuracy. Complete datasheet can be
- * obtained from National's website at:
- *   http://www.national.com/pf/LM/LM90.html
- *
- * This driver also supports the LM89 and LM99, two other sensor chips
- * made by National Semiconductor. Both have an increased remote
- * temperature measurement accuracy (1 degree), and the LM99
- * additionally shifts remote temperatures (measured and limits) by 16
- * degrees, which allows for higher temperatures measurement. The
- * driver doesn't handle it since it can be done easily in user-space.
- * Complete datasheets can be obtained from National's website at:
- *   http://www.national.com/pf/LM/LM89.html
- *   http://www.national.com/pf/LM/LM99.html
- * Note that there is no way to differenciate between both chips.
- *
- * This driver also supports the LM86, another sensor chip made by
- * National Semiconductor. It is exactly similar to the LM90 except it
- * has a higher accuracy.
- * Complete datasheet can be obtained from National's website at:
- *   http://www.national.com/pf/LM/LM86.html
- *
- * This driver also supports the ADM1032, a sensor chip made by Analog
- * Devices. That chip is similar to the LM90, with a few differences
- * that are not handled by this driver. Complete datasheet can be
- * obtained from Analog's website at:
- *   http://products.analog.com/products/info.asp?product=ADM1032
- * Among others, it has a higher accuracy than the LM90, much like the
- * LM86 does.
- *
- * This driver also supports the MAX6657, MAX6658 and MAX6659 sensor
- * chips made by Maxim. These chips are similar to the LM86. Complete
- * datasheet can be obtained at Maxim's website at:
- *   http://www.maxim-ic.com/quick_view2.cfm/qv_pk/2578
- * Note that there is no easy way to differenciate between the three
- * variants. The extra address and features of the MAX6659 are not
- * supported by this driver.
- *
- * This driver also supports the ADT7461 chip from Analog Devices but
- * only in its "compatability mode". If an ADT7461 chip is found but
- * is configured in non-compatible mode (where its temperature
- * register values are decoded differently) it is ignored by this
- * driver. Complete datasheet can be obtained from Analog's website
- * at:
- *   http://products.analog.com/products/info.asp?product=ADT7461
- *
- * Since the LM90 was the first chipset supported by this driver, most
- * comments will refer to this chipset, but are actually general and
- * concern all supported chipsets, unless mentioned otherwise.
- *
- * 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 <linux/config.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/jiffies.h>
-#include <linux/i2c.h>
-#include <linux/i2c-sensor.h>
-
-/*
- * Addresses to scan
- * Address is fully defined internally and cannot be changed except for
- * MAX6659.
- * LM86, LM89, LM90, LM99, ADM1032, MAX6657 and MAX6658 have address 0x4c.
- * LM89-1, and LM99-1 have address 0x4d.
- * MAX6659 can have address 0x4c, 0x4d or 0x4e (unsupported).
- * ADT7461 always has address 0x4c.
- */
-
-static unsigned short normal_i2c[] = { 0x4c, 0x4d, I2C_CLIENT_END };
-static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
-
-/*
- * Insmod parameters
- */
-
-SENSORS_INSMOD_6(lm90, adm1032, lm99, lm86, max6657, adt7461);
-
-/*
- * The LM90 registers
- */
-
-#define LM90_REG_R_MAN_ID		0xFE
-#define LM90_REG_R_CHIP_ID		0xFF
-#define LM90_REG_R_CONFIG1		0x03
-#define LM90_REG_W_CONFIG1		0x09
-#define LM90_REG_R_CONFIG2		0xBF
-#define LM90_REG_W_CONFIG2		0xBF
-#define LM90_REG_R_CONVRATE		0x04
-#define LM90_REG_W_CONVRATE		0x0A
-#define LM90_REG_R_STATUS		0x02
-#define LM90_REG_R_LOCAL_TEMP		0x00
-#define LM90_REG_R_LOCAL_HIGH		0x05
-#define LM90_REG_W_LOCAL_HIGH		0x0B
-#define LM90_REG_R_LOCAL_LOW		0x06
-#define LM90_REG_W_LOCAL_LOW		0x0C
-#define LM90_REG_R_LOCAL_CRIT		0x20
-#define LM90_REG_W_LOCAL_CRIT		0x20
-#define LM90_REG_R_REMOTE_TEMPH		0x01
-#define LM90_REG_R_REMOTE_TEMPL		0x10
-#define LM90_REG_R_REMOTE_OFFSH		0x11
-#define LM90_REG_W_REMOTE_OFFSH		0x11
-#define LM90_REG_R_REMOTE_OFFSL		0x12
-#define LM90_REG_W_REMOTE_OFFSL		0x12
-#define LM90_REG_R_REMOTE_HIGHH		0x07
-#define LM90_REG_W_REMOTE_HIGHH		0x0D
-#define LM90_REG_R_REMOTE_HIGHL		0x13
-#define LM90_REG_W_REMOTE_HIGHL		0x13
-#define LM90_REG_R_REMOTE_LOWH		0x08
-#define LM90_REG_W_REMOTE_LOWH		0x0E
-#define LM90_REG_R_REMOTE_LOWL		0x14
-#define LM90_REG_W_REMOTE_LOWL		0x14
-#define LM90_REG_R_REMOTE_CRIT		0x19
-#define LM90_REG_W_REMOTE_CRIT		0x19
-#define LM90_REG_R_TCRIT_HYST		0x21
-#define LM90_REG_W_TCRIT_HYST		0x21
-
-/*
- * Conversions and various macros
- * For local temperatures and limits, critical limits and the hysteresis
- * value, the LM90 uses signed 8-bit values with LSB = 1 degree Celcius.
- * For remote temperatures and limits, it uses signed 11-bit values with
- * LSB = 0.125 degree Celcius, left-justified in 16-bit registers.
- */
-
-#define TEMP1_FROM_REG(val)	((val) * 1000)
-#define TEMP1_TO_REG(val)	((val) <= -128000 ? -128 : \
-				 (val) >= 127000 ? 127 : \
-				 (val) < 0 ? ((val) - 500) / 1000 : \
-				 ((val) + 500) / 1000)
-#define TEMP2_FROM_REG(val)	((val) / 32 * 125)
-#define TEMP2_TO_REG(val)	((val) <= -128000 ? 0x8000 : \
-				 (val) >= 127875 ? 0x7FE0 : \
-				 (val) < 0 ? ((val) - 62) / 125 * 32 : \
-				 ((val) + 62) / 125 * 32)
-#define HYST_TO_REG(val)	((val) <= 0 ? 0 : (val) >= 30500 ? 31 : \
-				 ((val) + 500) / 1000)
-
-/* 
- * ADT7461 is almost identical to LM90 except that attempts to write
- * values that are outside the range 0 < temp < 127 are treated as
- * the boundary value. 
- */
-
-#define TEMP1_TO_REG_ADT7461(val) ((val) <= 0 ? 0 : \
-				 (val) >= 127000 ? 127 : \
-				 ((val) + 500) / 1000)
-#define TEMP2_TO_REG_ADT7461(val) ((val) <= 0 ? 0 : \
-				 (val) >= 127750 ? 0x7FC0 : \
-				 ((val) + 125) / 250 * 64)
-
-/*
- * Functions declaration
- */
-
-static int lm90_attach_adapter(struct i2c_adapter *adapter);
-static int lm90_detect(struct i2c_adapter *adapter, int address,
-	int kind);
-static void lm90_init_client(struct i2c_client *client);
-static int lm90_detach_client(struct i2c_client *client);
-static struct lm90_data *lm90_update_device(struct device *dev);
-
-/*
- * Driver data (common to all clients)
- */
-
-static struct i2c_driver lm90_driver = {
-	.owner		= THIS_MODULE,
-	.name		= "lm90",
-	.id		= I2C_DRIVERID_LM90,
-	.flags		= I2C_DF_NOTIFY,
-	.attach_adapter	= lm90_attach_adapter,
-	.detach_client	= lm90_detach_client,
-};
-
-/*
- * Client data (each client gets its own)
- */
-
-struct lm90_data {
-	struct i2c_client client;
-	struct semaphore update_lock;
-	char valid; /* zero until following fields are valid */
-	unsigned long last_updated; /* in jiffies */
-	int kind;
-
-	/* registers values */
-	s8 temp_input1, temp_low1, temp_high1; /* local */
-	s16 temp_input2, temp_low2, temp_high2; /* remote, combined */
-	s8 temp_crit1, temp_crit2;
-	u8 temp_hyst;
-	u8 alarms; /* bitvector */
-};
-
-/*
- * Sysfs stuff
- */
-
-#define show_temp(value, converter) \
-static ssize_t show_##value(struct device *dev, char *buf) \
-{ \
-	struct lm90_data *data = lm90_update_device(dev); \
-	return sprintf(buf, "%d\n", converter(data->value)); \
-}
-show_temp(temp_input1, TEMP1_FROM_REG);
-show_temp(temp_input2, TEMP2_FROM_REG);
-show_temp(temp_low1, TEMP1_FROM_REG);
-show_temp(temp_low2, TEMP2_FROM_REG);
-show_temp(temp_high1, TEMP1_FROM_REG);
-show_temp(temp_high2, TEMP2_FROM_REG);
-show_temp(temp_crit1, TEMP1_FROM_REG);
-show_temp(temp_crit2, TEMP1_FROM_REG);
-
-#define set_temp1(value, reg) \
-static ssize_t set_##value(struct device *dev, const char *buf, \
-	size_t count) \
-{ \
-	struct i2c_client *client = to_i2c_client(dev); \
-	struct lm90_data *data = i2c_get_clientdata(client); \
-	long val = simple_strtol(buf, NULL, 10); \
- \
-	down(&data->update_lock); \
-	if (data->kind == adt7461) \
-		data->value = TEMP1_TO_REG_ADT7461(val); \
-	else \
-		data->value = TEMP1_TO_REG(val); \
-	i2c_smbus_write_byte_data(client, reg, data->value); \
-	up(&data->update_lock); \
-	return count; \
-}
-#define set_temp2(value, regh, regl) \
-static ssize_t set_##value(struct device *dev, const char *buf, \
-	size_t count) \
-{ \
-	struct i2c_client *client = to_i2c_client(dev); \
-	struct lm90_data *data = i2c_get_clientdata(client); \
-	long val = simple_strtol(buf, NULL, 10); \
- \
-	down(&data->update_lock); \
-	if (data->kind == adt7461) \
-		data->value = TEMP2_TO_REG_ADT7461(val); \
-	else \
-		data->value = TEMP2_TO_REG(val); \
-	i2c_smbus_write_byte_data(client, regh, data->value >> 8); \
-	i2c_smbus_write_byte_data(client, regl, data->value & 0xff); \
-	up(&data->update_lock); \
-	return count; \
-}
-set_temp1(temp_low1, LM90_REG_W_LOCAL_LOW);
-set_temp2(temp_low2, LM90_REG_W_REMOTE_LOWH, LM90_REG_W_REMOTE_LOWL);
-set_temp1(temp_high1, LM90_REG_W_LOCAL_HIGH);
-set_temp2(temp_high2, LM90_REG_W_REMOTE_HIGHH, LM90_REG_W_REMOTE_HIGHL);
-set_temp1(temp_crit1, LM90_REG_W_LOCAL_CRIT);
-set_temp1(temp_crit2, LM90_REG_W_REMOTE_CRIT);
-
-#define show_temp_hyst(value, basereg) \
-static ssize_t show_##value(struct device *dev, char *buf) \
-{ \
-	struct lm90_data *data = lm90_update_device(dev); \
-	return sprintf(buf, "%d\n", TEMP1_FROM_REG(data->basereg) \
-		       - TEMP1_FROM_REG(data->temp_hyst)); \
-}
-show_temp_hyst(temp_hyst1, temp_crit1);
-show_temp_hyst(temp_hyst2, temp_crit2);
-
-static ssize_t set_temp_hyst1(struct device *dev, const char *buf,
-	size_t count)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm90_data *data = i2c_get_clientdata(client);
-	long val = simple_strtol(buf, NULL, 10);
-	long hyst;
-
-	down(&data->update_lock);
-	hyst = TEMP1_FROM_REG(data->temp_crit1) - val;
-	i2c_smbus_write_byte_data(client, LM90_REG_W_TCRIT_HYST,
-				  HYST_TO_REG(hyst));
-	up(&data->update_lock);
-	return count;
-}
-
-static ssize_t show_alarms(struct device *dev, char *buf)
-{
-	struct lm90_data *data = lm90_update_device(dev);
-	return sprintf(buf, "%d\n", data->alarms);
-}
-
-static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp_input1, NULL);
-static DEVICE_ATTR(temp2_input, S_IRUGO, show_temp_input2, NULL);
-static DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, show_temp_low1,
-	set_temp_low1);
-static DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_temp_low2,
-	set_temp_low2);
-static DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp_high1,
-	set_temp_high1);
-static DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_temp_high2,
-	set_temp_high2);
-static DEVICE_ATTR(temp1_crit, S_IWUSR | S_IRUGO, show_temp_crit1,
-	set_temp_crit1);
-static DEVICE_ATTR(temp2_crit, S_IWUSR | S_IRUGO, show_temp_crit2,
-	set_temp_crit2);
-static DEVICE_ATTR(temp1_crit_hyst, S_IWUSR | S_IRUGO, show_temp_hyst1,
-	set_temp_hyst1);
-static DEVICE_ATTR(temp2_crit_hyst, S_IRUGO, show_temp_hyst2, NULL);
-static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
-
-/*
- * Real code
- */
-
-static int lm90_attach_adapter(struct i2c_adapter *adapter)
-{
-	if (!(adapter->class & I2C_CLASS_HWMON))
-		return 0;
-	return i2c_detect(adapter, &addr_data, lm90_detect);
-}
-
-/*
- * The following function does more than just detection. If detection
- * succeeds, it also registers the new chip.
- */
-static int lm90_detect(struct i2c_adapter *adapter, int address, int kind)
-{
-	struct i2c_client *new_client;
-	struct lm90_data *data;
-	int err = 0;
-	const char *name = "";
-
-	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
-		goto exit;
-
-	if (!(data = kmalloc(sizeof(struct lm90_data), GFP_KERNEL))) {
-		err = -ENOMEM;
-		goto exit;
-	}
-	memset(data, 0, sizeof(struct lm90_data));
-
-	/* The common I2C client data is placed right before the
-	   LM90-specific data. */
-	new_client = &data->client;
-	i2c_set_clientdata(new_client, data);
-	new_client->addr = address;
-	new_client->adapter = adapter;
-	new_client->driver = &lm90_driver;
-	new_client->flags = 0;
-
-	/*
-	 * Now we do the remaining detection. A negative kind means that
-	 * the driver was loaded with no force parameter (default), so we
-	 * must both detect and identify the chip. A zero kind means that
-	 * the driver was loaded with the force parameter, the detection
-	 * step shall be skipped. A positive kind means that the driver
-	 * was loaded with the force parameter and a given kind of chip is
-	 * requested, so both the detection and the identification steps
-	 * are skipped.
-	 */
-
-	/* Default to an LM90 if forced */
-	if (kind == 0)
-		kind = lm90;
-
-	if (kind < 0) { /* detection and identification */
-		u8 man_id, chip_id, reg_config1, reg_convrate;
-
-		man_id = i2c_smbus_read_byte_data(new_client,
-			 LM90_REG_R_MAN_ID);
-		chip_id = i2c_smbus_read_byte_data(new_client,
-			  LM90_REG_R_CHIP_ID);
-		reg_config1 = i2c_smbus_read_byte_data(new_client,
-			      LM90_REG_R_CONFIG1);
-		reg_convrate = i2c_smbus_read_byte_data(new_client,
-			       LM90_REG_R_CONVRATE);
-		
-		if (man_id == 0x01) { /* National Semiconductor */
-			u8 reg_config2;
-
-			reg_config2 = i2c_smbus_read_byte_data(new_client,
-				      LM90_REG_R_CONFIG2);
-
-			if ((reg_config1 & 0x2A) == 0x00
-			 && (reg_config2 & 0xF8) == 0x00
-			 && reg_convrate <= 0x09) {
-				if (address == 0x4C
-				 && (chip_id & 0xF0) == 0x20) { /* LM90 */
-					kind = lm90;
-				} else
-				if ((chip_id & 0xF0) == 0x30) { /* LM89/LM99 */
-					kind = lm99;
-				} else
-				if (address == 0x4C
-				 && (chip_id & 0xF0) == 0x10) { /* LM86 */
-					kind = lm86;
-				}
-			}
-		} else
-		if (man_id == 0x41) { /* Analog Devices */
-			if (address == 0x4C
-			 && (chip_id & 0xF0) == 0x40 /* ADM1032 */
-			 && (reg_config1 & 0x3F) == 0x00
-			 && reg_convrate <= 0x0A) {
-				kind = adm1032;
-			} else
-			if (address == 0x4c
-			 && chip_id == 0x51 /* ADT7461 */
-			 && (reg_config1 & 0x1F) == 0x00 /* check compat mode */
-			 && reg_convrate <= 0x0A) {
-				kind = adt7461;
-			}
-		} else
-		if (man_id == 0x4D) { /* Maxim */
-			/*
-			 * The Maxim variants do NOT have a chip_id register.
-			 * Reading from that address will return the last read
-			 * value, which in our case is those of the man_id
-			 * register. Likewise, the config1 register seems to
-			 * lack a low nibble, so the value will be those of the
-			 * previous read, so in our case those of the man_id
-			 * register.
-			 */
-			if (chip_id == man_id
-			 && (reg_config1 & 0x1F) == (man_id & 0x0F)
-			 && reg_convrate <= 0x09) {
-			 	kind = max6657;
-			}
-		}
-
-		if (kind <= 0) { /* identification failed */
-			dev_info(&adapter->dev,
-			    "Unsupported chip (man_id=0x%02X, "
-			    "chip_id=0x%02X).\n", man_id, chip_id);
-			goto exit_free;
-		}
-	}
-
-	if (kind == lm90) {
-		name = "lm90";
-	} else if (kind == adm1032) {
-		name = "adm1032";
-	} else if (kind == lm99) {
-		name = "lm99";
-	} else if (kind == lm86) {
-		name = "lm86";
-	} else if (kind == max6657) {
-		name = "max6657";
-	} else if (kind == adt7461) {
-		name = "adt7461";
-	}
-
-	/* We can fill in the remaining client fields */
-	strlcpy(new_client->name, name, I2C_NAME_SIZE);
-	data->valid = 0;
-	data->kind = kind;
-	init_MUTEX(&data->update_lock);
-
-	/* Tell the I2C layer a new client has arrived */
-	if ((err = i2c_attach_client(new_client)))
-		goto exit_free;
-
-	/* Initialize the LM90 chip */
-	lm90_init_client(new_client);
-
-	/* Register sysfs hooks */
-	device_create_file(&new_client->dev, &dev_attr_temp1_input);
-	device_create_file(&new_client->dev, &dev_attr_temp2_input);
-	device_create_file(&new_client->dev, &dev_attr_temp1_min);
-	device_create_file(&new_client->dev, &dev_attr_temp2_min);
-	device_create_file(&new_client->dev, &dev_attr_temp1_max);
-	device_create_file(&new_client->dev, &dev_attr_temp2_max);
-	device_create_file(&new_client->dev, &dev_attr_temp1_crit);
-	device_create_file(&new_client->dev, &dev_attr_temp2_crit);
-	device_create_file(&new_client->dev, &dev_attr_temp1_crit_hyst);
-	device_create_file(&new_client->dev, &dev_attr_temp2_crit_hyst);
-	device_create_file(&new_client->dev, &dev_attr_alarms);
-
-	return 0;
-
-exit_free:
-	kfree(data);
-exit:
-	return err;
-}
-
-static void lm90_init_client(struct i2c_client *client)
-{
-	u8 config;
-
-	/*
-	 * Start the conversions.
-	 */
-	i2c_smbus_write_byte_data(client, LM90_REG_W_CONVRATE,
-				  5); /* 2 Hz */
-	config = i2c_smbus_read_byte_data(client, LM90_REG_R_CONFIG1);
-	if (config & 0x40)
-		i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1,
-					  config & 0xBF); /* run */
-}
-
-static int lm90_detach_client(struct i2c_client *client)
-{
-	int err;
-
-	if ((err = i2c_detach_client(client))) {
-		dev_err(&client->dev, "Client deregistration failed, "
-			"client not detached.\n");
-		return err;
-	}
-
-	kfree(i2c_get_clientdata(client));
-	return 0;
-}
-
-static struct lm90_data *lm90_update_device(struct device *dev)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm90_data *data = i2c_get_clientdata(client);
-
-	down(&data->update_lock);
-
-	if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) {
-		u8 oldh, newh;
-
-		dev_dbg(&client->dev, "Updating lm90 data.\n");
-		data->temp_input1 = i2c_smbus_read_byte_data(client,
-				    LM90_REG_R_LOCAL_TEMP);
-		data->temp_high1 = i2c_smbus_read_byte_data(client,
-				   LM90_REG_R_LOCAL_HIGH);
-		data->temp_low1 = i2c_smbus_read_byte_data(client,
-				  LM90_REG_R_LOCAL_LOW);
-		data->temp_crit1 = i2c_smbus_read_byte_data(client,
-				   LM90_REG_R_LOCAL_CRIT);
-		data->temp_crit2 = i2c_smbus_read_byte_data(client,
-				   LM90_REG_R_REMOTE_CRIT);
-		data->temp_hyst = i2c_smbus_read_byte_data(client,
-				  LM90_REG_R_TCRIT_HYST);
-
-		/*
-		 * There is a trick here. We have to read two registers to
-		 * have the remote sensor temperature, but we have to beware
-		 * a conversion could occur inbetween the readings. The
-		 * datasheet says we should either use the one-shot
-		 * conversion register, which we don't want to do (disables
-		 * hardware monitoring) or monitor the busy bit, which is
-		 * impossible (we can't read the values and monitor that bit
-		 * at the exact same time). So the solution used here is to
-		 * read the high byte once, then the low byte, then the high
-		 * byte again. If the new high byte matches the old one,
-		 * then we have a valid reading. Else we have to read the low
-		 * byte again, and now we believe we have a correct reading.
-		 */
-		oldh = i2c_smbus_read_byte_data(client,
-		       LM90_REG_R_REMOTE_TEMPH);
-		data->temp_input2 = i2c_smbus_read_byte_data(client,
-				    LM90_REG_R_REMOTE_TEMPL);
-		newh = i2c_smbus_read_byte_data(client,
-		       LM90_REG_R_REMOTE_TEMPH);
-		if (newh != oldh) {
-			data->temp_input2 = i2c_smbus_read_byte_data(client,
-					    LM90_REG_R_REMOTE_TEMPL);
-#ifdef DEBUG
-			oldh = i2c_smbus_read_byte_data(client,
-			       LM90_REG_R_REMOTE_TEMPH);
-			/* oldh is actually newer */
-			if (newh != oldh)
-				dev_warn(&client->dev, "Remote temperature may be "
-					 "wrong.\n");
-#endif
-		}
-		data->temp_input2 |= (newh << 8);
-
-		data->temp_high2 = (i2c_smbus_read_byte_data(client,
-				   LM90_REG_R_REMOTE_HIGHH) << 8) +
-				   i2c_smbus_read_byte_data(client,
-				   LM90_REG_R_REMOTE_HIGHL);
-		data->temp_low2 = (i2c_smbus_read_byte_data(client,
-				  LM90_REG_R_REMOTE_LOWH) << 8) +
-				  i2c_smbus_read_byte_data(client,
-				  LM90_REG_R_REMOTE_LOWL);
-		data->alarms = i2c_smbus_read_byte_data(client,
-			       LM90_REG_R_STATUS);
-
-		data->last_updated = jiffies;
-		data->valid = 1;
-	}
-
-	up(&data->update_lock);
-
-	return data;
-}
-
-static int __init sensors_lm90_init(void)
-{
-	return i2c_add_driver(&lm90_driver);
-}
-
-static void __exit sensors_lm90_exit(void)
-{
-	i2c_del_driver(&lm90_driver);
-}
-
-MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>");
-MODULE_DESCRIPTION("LM90/ADM1032 driver");
-MODULE_LICENSE("GPL");
-
-module_init(sensors_lm90_init);
-module_exit(sensors_lm90_exit);
diff --git a/drivers/i2c/chips/lm92.c b/drivers/i2c/chips/lm92.c
deleted file mode 100644
--- a/drivers/i2c/chips/lm92.c
+++ /dev/null
@@ -1,429 +0,0 @@
-/*
- * lm92 - Hardware monitoring driver
- * Copyright (C) 2005  Jean Delvare <khali@linux-fr.org>
- *
- * Based on the lm90 driver, with some ideas taken from the lm_sensors
- * lm92 driver as well.
- *
- * The LM92 is a sensor chip made by National Semiconductor. It reports
- * its own temperature with a 0.0625 deg resolution and a 0.33 deg
- * accuracy. Complete datasheet can be obtained from National's website
- * at:
- *   http://www.national.com/pf/LM/LM92.html
- *
- * This driver also supports the MAX6635 sensor chip made by Maxim.
- * This chip is compatible with the LM92, but has a lesser accuracy
- * (1.0 deg). Complete datasheet can be obtained from Maxim's website
- * at:
- *   http://www.maxim-ic.com/quick_view2.cfm/qv_pk/3074
- *
- * Since the LM92 was the first chipset supported by this driver, most
- * comments will refer to this chipset, but are actually general and
- * concern all supported chipsets, unless mentioned otherwise.
- *
- * Support could easily be added for the National Semiconductor LM76
- * and Maxim MAX6633 and MAX6634 chips, which are mostly compatible
- * with the LM92.
- *
- * 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 <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-#include <linux/i2c-sensor.h>
-
-
-/* The LM92 and MAX6635 have 2 two-state pins for address selection,
-   resulting in 4 possible addresses. */
-static unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b,
-				       I2C_CLIENT_END };
-static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
-
-/* Insmod parameters */
-SENSORS_INSMOD_1(lm92);
-
-/* The LM92 registers */
-#define LM92_REG_CONFIG			0x01 /* 8-bit, RW */
-#define LM92_REG_TEMP			0x00 /* 16-bit, RO */
-#define LM92_REG_TEMP_HYST		0x02 /* 16-bit, RW */
-#define LM92_REG_TEMP_CRIT		0x03 /* 16-bit, RW */
-#define LM92_REG_TEMP_LOW		0x04 /* 16-bit, RW */
-#define LM92_REG_TEMP_HIGH		0x05 /* 16-bit, RW */
-#define LM92_REG_MAN_ID			0x07 /* 16-bit, RO, LM92 only */
-
-/* The LM92 uses signed 13-bit values with LSB = 0.0625 degree Celsius,
-   left-justified in 16-bit registers. No rounding is done, with such
-   a resolution it's just not worth it. Note that the MAX6635 doesn't
-   make use of the 4 lower bits for limits (i.e. effective resolution
-   for limits is 1 degree Celsius). */
-static inline int TEMP_FROM_REG(s16 reg)
-{
-	return reg / 8 * 625 / 10;
-}
-
-static inline s16 TEMP_TO_REG(int val)
-{
-	if (val <= -60000)
-		return -60000 * 10 / 625 * 8;
-	if (val >= 160000)
-		return 160000 * 10 / 625 * 8;
-	return val * 10 / 625 * 8;
-}
-
-/* Alarm flags are stored in the 3 LSB of the temperature register */
-static inline u8 ALARMS_FROM_REG(s16 reg)
-{
-	return reg & 0x0007;
-}
-
-/* Driver data (common to all clients) */
-static struct i2c_driver lm92_driver;
-
-/* Client data (each client gets its own) */
-struct lm92_data {
-	struct i2c_client client;
-	struct semaphore update_lock;
-	char valid; /* zero until following fields are valid */
-	unsigned long last_updated; /* in jiffies */
-
-	/* registers values */
-	s16 temp1_input, temp1_crit, temp1_min, temp1_max, temp1_hyst;
-};
-
-
-/*
- * Sysfs attributes and callback functions
- */
-
-static struct lm92_data *lm92_update_device(struct device *dev)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm92_data *data = i2c_get_clientdata(client);
-
-	down(&data->update_lock);
-
-	if (time_after(jiffies, data->last_updated + HZ)
-	 || !data->valid) {
-		dev_dbg(&client->dev, "Updating lm92 data\n");
-		data->temp1_input = swab16(i2c_smbus_read_word_data(client,
-				    LM92_REG_TEMP));
-		data->temp1_hyst = swab16(i2c_smbus_read_word_data(client,
-				    LM92_REG_TEMP_HYST));
-		data->temp1_crit = swab16(i2c_smbus_read_word_data(client,
-				    LM92_REG_TEMP_CRIT));
-		data->temp1_min = swab16(i2c_smbus_read_word_data(client,
-				    LM92_REG_TEMP_LOW));
-		data->temp1_max = swab16(i2c_smbus_read_word_data(client,
-				    LM92_REG_TEMP_HIGH));
-
-		data->last_updated = jiffies;
-		data->valid = 1;
-	}
-
-	up(&data->update_lock);
-
-	return data;
-}
-
-#define show_temp(value) \
-static ssize_t show_##value(struct device *dev, char *buf) \
-{ \
-	struct lm92_data *data = lm92_update_device(dev); \
-	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->value)); \
-}
-show_temp(temp1_input);
-show_temp(temp1_crit);
-show_temp(temp1_min);
-show_temp(temp1_max);
-
-#define set_temp(value, reg) \
-static ssize_t set_##value(struct device *dev, const char *buf, \
-	size_t count) \
-{ \
-	struct i2c_client *client = to_i2c_client(dev); \
-	struct lm92_data *data = i2c_get_clientdata(client); \
-	long val = simple_strtol(buf, NULL, 10); \
- \
-	down(&data->update_lock); \
-	data->value = TEMP_TO_REG(val); \
-	i2c_smbus_write_word_data(client, reg, swab16(data->value)); \
-	up(&data->update_lock); \
-	return count; \
-}
-set_temp(temp1_crit, LM92_REG_TEMP_CRIT);
-set_temp(temp1_min, LM92_REG_TEMP_LOW);
-set_temp(temp1_max, LM92_REG_TEMP_HIGH);
-
-static ssize_t show_temp1_crit_hyst(struct device *dev, char *buf)
-{
-	struct lm92_data *data = lm92_update_device(dev);
-	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp1_crit)
-		       - TEMP_FROM_REG(data->temp1_hyst));
-}
-static ssize_t show_temp1_max_hyst(struct device *dev, char *buf)
-{
-	struct lm92_data *data = lm92_update_device(dev);
-	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp1_max)
-		       - TEMP_FROM_REG(data->temp1_hyst));
-}
-static ssize_t show_temp1_min_hyst(struct device *dev, char *buf)
-{
-	struct lm92_data *data = lm92_update_device(dev);
-	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp1_min)
-		       + TEMP_FROM_REG(data->temp1_hyst));
-}
-
-static ssize_t set_temp1_crit_hyst(struct device *dev, const char *buf,
-	size_t count)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm92_data *data = i2c_get_clientdata(client);
-	long val = simple_strtol(buf, NULL, 10);
-
-	down(&data->update_lock);
-	data->temp1_hyst = TEMP_FROM_REG(data->temp1_crit) - val;
-	i2c_smbus_write_word_data(client, LM92_REG_TEMP_HYST,
-				  swab16(TEMP_TO_REG(data->temp1_hyst)));
-	up(&data->update_lock);
-	return count;
-}
-
-static ssize_t show_alarms(struct device *dev, char *buf)
-{
-	struct lm92_data *data = lm92_update_device(dev);
-	return sprintf(buf, "%d\n", ALARMS_FROM_REG(data->temp1_input));
-}
-
-static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp1_input, NULL);
-static DEVICE_ATTR(temp1_crit, S_IWUSR | S_IRUGO, show_temp1_crit,
-	set_temp1_crit);
-static DEVICE_ATTR(temp1_crit_hyst, S_IWUSR | S_IRUGO, show_temp1_crit_hyst,
-	set_temp1_crit_hyst);
-static DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, show_temp1_min,
-	set_temp1_min);
-static DEVICE_ATTR(temp1_min_hyst, S_IRUGO, show_temp1_min_hyst, NULL);
-static DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp1_max,
-	set_temp1_max);
-static DEVICE_ATTR(temp1_max_hyst, S_IRUGO, show_temp1_max_hyst, NULL);
-static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
-
-
-/*
- * Detection and registration
- */
-
-static void lm92_init_client(struct i2c_client *client)
-{
-	u8 config;
-
-	/* Start the conversions if needed */
-	config = i2c_smbus_read_byte_data(client, LM92_REG_CONFIG);
-	if (config & 0x01)
-		i2c_smbus_write_byte_data(client, LM92_REG_CONFIG,
-					  config & 0xFE);
-}
-
-/* The MAX6635 has no identification register, so we have to use tricks
-   to identify it reliably. This is somewhat slow.
-   Note that we do NOT rely on the 2 MSB of the configuration register
-   always reading 0, as suggested by the datasheet, because it was once
-   reported not to be true. */
-static int max6635_check(struct i2c_client *client)
-{
-	u16 temp_low, temp_high, temp_hyst, temp_crit;
-	u8 conf;
-	int i;
-
-	/* No manufacturer ID register, so a read from this address will
-	   always return the last read value. */
-	temp_low = i2c_smbus_read_word_data(client, LM92_REG_TEMP_LOW);
-	if (i2c_smbus_read_word_data(client, LM92_REG_MAN_ID) != temp_low)
-		return 0;
-	temp_high = i2c_smbus_read_word_data(client, LM92_REG_TEMP_HIGH);
-	if (i2c_smbus_read_word_data(client, LM92_REG_MAN_ID) != temp_high)
-		return 0;
-	
-	/* Limits are stored as integer values (signed, 9-bit). */
-	if ((temp_low & 0x7f00) || (temp_high & 0x7f00))
-		return 0;
-	temp_hyst = i2c_smbus_read_word_data(client, LM92_REG_TEMP_HYST);
-	temp_crit = i2c_smbus_read_word_data(client, LM92_REG_TEMP_CRIT);
-	if ((temp_hyst & 0x7f00) || (temp_crit & 0x7f00))
-		return 0;
-
-	/* Registers addresses were found to cycle over 16-byte boundaries.
-	   We don't test all registers with all offsets so as to save some
-	   reads and time, but this should still be sufficient to dismiss
-	   non-MAX6635 chips. */
-	conf = i2c_smbus_read_byte_data(client, LM92_REG_CONFIG);
-	for (i=16; i<96; i*=2) {
-		if (temp_hyst != i2c_smbus_read_word_data(client,
-		 		 LM92_REG_TEMP_HYST + i - 16)
-		 || temp_crit != i2c_smbus_read_word_data(client,
-		 		 LM92_REG_TEMP_CRIT + i)
-		 || temp_low != i2c_smbus_read_word_data(client,
-				LM92_REG_TEMP_LOW + i + 16)
-		 || temp_high != i2c_smbus_read_word_data(client,
-		 		 LM92_REG_TEMP_HIGH + i + 32)
-		 || conf != i2c_smbus_read_byte_data(client,
-		 	    LM92_REG_CONFIG + i))
-			return 0;
-	}
-
-	return 1;
-}
-
-/* The following function does more than just detection. If detection
-   succeeds, it also registers the new chip. */
-static int lm92_detect(struct i2c_adapter *adapter, int address, int kind)
-{
-	struct i2c_client *new_client;
-	struct lm92_data *data;
-	int err = 0;
-	char *name;
-
-	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA
-					    | I2C_FUNC_SMBUS_WORD_DATA))
-		goto exit;
-
-	if (!(data = kmalloc(sizeof(struct lm92_data), GFP_KERNEL))) {
-		err = -ENOMEM;
-		goto exit;
-	}
-	memset(data, 0, sizeof(struct lm92_data));
-
-	/* Fill in enough client fields so that we can read from the chip,
-	   which is required for identication */
-	new_client = &data->client;
-	i2c_set_clientdata(new_client, data);
-	new_client->addr = address;
-	new_client->adapter = adapter;
-	new_client->driver = &lm92_driver;
-	new_client->flags = 0;
-
-	/* A negative kind means that the driver was loaded with no force
-	   parameter (default), so we must identify the chip. */
-	if (kind < 0) {
-		u8 config = i2c_smbus_read_byte_data(new_client,
-			     LM92_REG_CONFIG);
-		u16 man_id = i2c_smbus_read_word_data(new_client,
-			     LM92_REG_MAN_ID);
-
-		if ((config & 0xe0) == 0x00
-		 && man_id == 0x0180) {
-			pr_info("lm92: Found National Semiconductor LM92 chip\n");
-	 		kind = lm92;
-		} else
-		if (max6635_check(new_client)) {
-			pr_info("lm92: Found Maxim MAX6635 chip\n");
-			kind = lm92; /* No separate prefix */
-		}
-		else
-			goto exit_free;
-	} else
-	if (kind == 0) /* Default to an LM92 if forced */
-		kind = lm92;
-
-	/* Give it the proper name */
-	if (kind == lm92) {
-		name = "lm92";
-	} else { /* Supposedly cannot happen */
-		dev_dbg(&new_client->dev, "Kind out of range?\n");
-		goto exit_free;
-	}
-
-	/* Fill in the remaining client fields */
-	strlcpy(new_client->name, name, I2C_NAME_SIZE);
-	data->valid = 0;
-	init_MUTEX(&data->update_lock);
-
-	/* Tell the i2c subsystem a new client has arrived */
-	if ((err = i2c_attach_client(new_client)))
-		goto exit_free;
-
-	/* Initialize the chipset */
-	lm92_init_client(new_client);
-
-	/* Register sysfs hooks */
-	device_create_file(&new_client->dev, &dev_attr_temp1_input);
-	device_create_file(&new_client->dev, &dev_attr_temp1_crit);
-	device_create_file(&new_client->dev, &dev_attr_temp1_crit_hyst);
-	device_create_file(&new_client->dev, &dev_attr_temp1_min);
-	device_create_file(&new_client->dev, &dev_attr_temp1_min_hyst);
-	device_create_file(&new_client->dev, &dev_attr_temp1_max);
-	device_create_file(&new_client->dev, &dev_attr_temp1_max_hyst);
-	device_create_file(&new_client->dev, &dev_attr_alarms);
-
-	return 0;
-
-exit_free:
-	kfree(data);
-exit:
-	return err;
-}
-
-static int lm92_attach_adapter(struct i2c_adapter *adapter)
-{
-	if (!(adapter->class & I2C_CLASS_HWMON))
-		return 0;
-	return i2c_detect(adapter, &addr_data, lm92_detect);
-}
-
-static int lm92_detach_client(struct i2c_client *client)
-{
-	int err;
-
-	if ((err = i2c_detach_client(client))) {
-		dev_err(&client->dev, "Client deregistration failed, "
-			"client not detached.\n");
-		return err;
-	}
-
-	kfree(i2c_get_clientdata(client));
-	return 0;
-}
-
-
-/*
- * Module and driver stuff
- */
-
-static struct i2c_driver lm92_driver = {
-	.owner		= THIS_MODULE,
-	.name		= "lm92",
-	.id		= I2C_DRIVERID_LM92,
-	.flags		= I2C_DF_NOTIFY,
-	.attach_adapter	= lm92_attach_adapter,
-	.detach_client	= lm92_detach_client,
-};
-
-static int __init sensors_lm92_init(void)
-{
-	return i2c_add_driver(&lm92_driver);
-}
-
-static void __exit sensors_lm92_exit(void)
-{
-	i2c_del_driver(&lm92_driver);
-}
-
-MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>");
-MODULE_DESCRIPTION("LM92/MAX6635 driver");
-MODULE_LICENSE("GPL");
-
-module_init(sensors_lm92_init);
-module_exit(sensors_lm92_exit);
diff --git a/drivers/i2c/chips/m41t00.c b/drivers/i2c/chips/m41t00.c
--- a/drivers/i2c/chips/m41t00.c
+++ b/drivers/i2c/chips/m41t00.c
@@ -40,11 +40,8 @@ static unsigned short normal_addr[] = { 
 
 static struct i2c_client_address_data addr_data = {
 	.normal_i2c		= normal_addr,
-	.normal_i2c_range	= ignore,
 	.probe			= ignore,
-	.probe_range		= ignore,
 	.ignore			= ignore,
-	.ignore_range		= ignore,
 	.force			= ignore,
 };
 
@@ -210,7 +207,7 @@ m41t00_detach(struct i2c_client *client)
 	int	rc;
 
 	if ((rc = i2c_detach_client(client)) == 0) {
-		kfree(i2c_get_clientdata(client));
+		kfree(client);
 		tasklet_kill(&m41t00_tasklet);
 	}
 	return rc;
diff --git a/drivers/i2c/chips/max1619.c b/drivers/i2c/chips/max1619.c
deleted file mode 100644
--- a/drivers/i2c/chips/max1619.c
+++ /dev/null
@@ -1,373 +0,0 @@
-/*
- * max1619.c - Part of lm_sensors, Linux kernel modules for hardware
- *             monitoring
- * Copyright (C) 2003-2004 Alexey Fisher <fishor@mail.ru>
- *                         Jean Delvare <khali@linux-fr.org>
- *
- * Based on the lm90 driver. The MAX1619 is a sensor chip made by Maxim.
- * It reports up to two temperatures (its own plus up to
- * one external one). Complete datasheet can be
- * obtained from Maxim's website at:
- *   http://pdfserv.maxim-ic.com/en/ds/MAX1619.pdf
- *
- * 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 <linux/config.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/jiffies.h>
-#include <linux/i2c.h>
-#include <linux/i2c-sensor.h>
-
-
-static unsigned short normal_i2c[] = { 0x18, 0x19, 0x1a,
-					0x29, 0x2a, 0x2b,
-					0x4c, 0x4d, 0x4e,
-					I2C_CLIENT_END };
-static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
-
-/*
- * Insmod parameters
- */
-
-SENSORS_INSMOD_1(max1619);
-
-/*
- * The MAX1619 registers
- */
-
-#define MAX1619_REG_R_MAN_ID		0xFE
-#define MAX1619_REG_R_CHIP_ID		0xFF
-#define MAX1619_REG_R_CONFIG		0x03
-#define MAX1619_REG_W_CONFIG		0x09
-#define MAX1619_REG_R_CONVRATE		0x04
-#define MAX1619_REG_W_CONVRATE		0x0A
-#define MAX1619_REG_R_STATUS		0x02
-#define MAX1619_REG_R_LOCAL_TEMP	0x00
-#define MAX1619_REG_R_REMOTE_TEMP	0x01
-#define MAX1619_REG_R_REMOTE_HIGH	0x07
-#define MAX1619_REG_W_REMOTE_HIGH	0x0D
-#define MAX1619_REG_R_REMOTE_LOW	0x08
-#define MAX1619_REG_W_REMOTE_LOW	0x0E
-#define MAX1619_REG_R_REMOTE_CRIT	0x10
-#define MAX1619_REG_W_REMOTE_CRIT	0x12
-#define MAX1619_REG_R_TCRIT_HYST	0x11
-#define MAX1619_REG_W_TCRIT_HYST	0x13
-
-/*
- * Conversions and various macros
- */
-
-#define TEMP_FROM_REG(val)	((val & 0x80 ? val-0x100 : val) * 1000)
-#define TEMP_TO_REG(val)	((val < 0 ? val+0x100*1000 : val) / 1000)
-
-/*
- * Functions declaration
- */
-
-static int max1619_attach_adapter(struct i2c_adapter *adapter);
-static int max1619_detect(struct i2c_adapter *adapter, int address,
-	int kind);
-static void max1619_init_client(struct i2c_client *client);
-static int max1619_detach_client(struct i2c_client *client);
-static struct max1619_data *max1619_update_device(struct device *dev);
-
-/*
- * Driver data (common to all clients)
- */
-
-static struct i2c_driver max1619_driver = {
-	.owner		= THIS_MODULE,
-	.name		= "max1619",
-	.flags		= I2C_DF_NOTIFY,
-	.attach_adapter	= max1619_attach_adapter,
-	.detach_client	= max1619_detach_client,
-};
-
-/*
- * Client data (each client gets its own)
- */
-
-struct max1619_data {
-	struct i2c_client client;
-	struct semaphore update_lock;
-	char valid; /* zero until following fields are valid */
-	unsigned long last_updated; /* in jiffies */
-
-	/* registers values */
-	u8 temp_input1; /* local */
-	u8 temp_input2, temp_low2, temp_high2; /* remote */
-	u8 temp_crit2;
-	u8 temp_hyst2;
-	u8 alarms; 
-};
-
-/*
- * Sysfs stuff
- */
-
-#define show_temp(value) \
-static ssize_t show_##value(struct device *dev, char *buf) \
-{ \
-	struct max1619_data *data = max1619_update_device(dev); \
-	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->value)); \
-}
-show_temp(temp_input1);
-show_temp(temp_input2);
-show_temp(temp_low2);
-show_temp(temp_high2);
-show_temp(temp_crit2);
-show_temp(temp_hyst2);
-
-#define set_temp2(value, reg) \
-static ssize_t set_##value(struct device *dev, const char *buf, \
-	size_t count) \
-{ \
-	struct i2c_client *client = to_i2c_client(dev); \
-	struct max1619_data *data = i2c_get_clientdata(client); \
-	long val = simple_strtol(buf, NULL, 10); \
- \
-	down(&data->update_lock); \
-	data->value = TEMP_TO_REG(val); \
-	i2c_smbus_write_byte_data(client, reg, data->value); \
-	up(&data->update_lock); \
-	return count; \
-}
-
-set_temp2(temp_low2, MAX1619_REG_W_REMOTE_LOW);
-set_temp2(temp_high2, MAX1619_REG_W_REMOTE_HIGH);
-set_temp2(temp_crit2, MAX1619_REG_W_REMOTE_CRIT);
-set_temp2(temp_hyst2, MAX1619_REG_W_TCRIT_HYST);
-
-static ssize_t show_alarms(struct device *dev, char *buf)
-{
-	struct max1619_data *data = max1619_update_device(dev);
-	return sprintf(buf, "%d\n", data->alarms);
-}
-
-static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp_input1, NULL);
-static DEVICE_ATTR(temp2_input, S_IRUGO, show_temp_input2, NULL);
-static DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_temp_low2,
-	set_temp_low2);
-static DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_temp_high2,
-	set_temp_high2);
-static DEVICE_ATTR(temp2_crit, S_IWUSR | S_IRUGO, show_temp_crit2,
-	set_temp_crit2);
-static DEVICE_ATTR(temp2_crit_hyst, S_IWUSR | S_IRUGO, show_temp_hyst2,
-	set_temp_hyst2);
-static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
-
-/*
- * Real code
- */
-
-static int max1619_attach_adapter(struct i2c_adapter *adapter)
-{
-	if (!(adapter->class & I2C_CLASS_HWMON))
-		return 0;
-	return i2c_detect(adapter, &addr_data, max1619_detect);
-}
-
-/*
- * The following function does more than just detection. If detection
- * succeeds, it also registers the new chip.
- */
-static int max1619_detect(struct i2c_adapter *adapter, int address, int kind)
-{
-	struct i2c_client *new_client;
-	struct max1619_data *data;
-	int err = 0;
-	const char *name = "";	
-	u8 reg_config=0, reg_convrate=0, reg_status=0;
-	u8 man_id, chip_id;
-	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
-		goto exit;
-
-	if (!(data = kmalloc(sizeof(struct max1619_data), GFP_KERNEL))) {
-		err = -ENOMEM;
-		goto exit;
-	}
-	memset(data, 0, sizeof(struct max1619_data));
-
-	/* The common I2C client data is placed right before the
-	   MAX1619-specific data. */
-	new_client = &data->client;
-	i2c_set_clientdata(new_client, data);
-	new_client->addr = address;
-	new_client->adapter = adapter;
-	new_client->driver = &max1619_driver;
-	new_client->flags = 0;
-
-	/*
-	 * Now we do the remaining detection. A negative kind means that
-	 * the driver was loaded with no force parameter (default), so we
-	 * must both detect and identify the chip. A zero kind means that
-	 * the driver was loaded with the force parameter, the detection
-	 * step shall be skipped. A positive kind means that the driver
-	 * was loaded with the force parameter and a given kind of chip is
-	 * requested, so both the detection and the identification steps
-	 * are skipped.
-	 */
-	if (kind < 0) { /* detection */
-		reg_config = i2c_smbus_read_byte_data(new_client,
-			      MAX1619_REG_R_CONFIG);
-		reg_convrate = i2c_smbus_read_byte_data(new_client,
-			       MAX1619_REG_R_CONVRATE);
-		reg_status = i2c_smbus_read_byte_data(new_client,
-				MAX1619_REG_R_STATUS);
-		if ((reg_config & 0x03) != 0x00
-		 || reg_convrate > 0x07 || (reg_status & 0x61 ) !=0x00) {
-			dev_dbg(&adapter->dev,
-				"MAX1619 detection failed at 0x%02x.\n",
-				address);
-			goto exit_free;
-		}
-	}
-
-	if (kind <= 0) { /* identification */
-	
-		man_id = i2c_smbus_read_byte_data(new_client,
-			 MAX1619_REG_R_MAN_ID);
-		chip_id = i2c_smbus_read_byte_data(new_client,
-			  MAX1619_REG_R_CHIP_ID);
-		
-		if ((man_id == 0x4D) && (chip_id == 0x04)){  
-				kind = max1619;
-			}
-		}
-
-		if (kind <= 0) { /* identification failed */
-			dev_info(&adapter->dev,
-			    "Unsupported chip (man_id=0x%02X, "
-			    "chip_id=0x%02X).\n", man_id, chip_id);
-			goto exit_free;
-		}
-	
-
-	if (kind == max1619){
-		name = "max1619";
-	}
-
-	/* We can fill in the remaining client fields */
-	strlcpy(new_client->name, name, I2C_NAME_SIZE);
-	data->valid = 0;
-	init_MUTEX(&data->update_lock);
-
-	/* Tell the I2C layer a new client has arrived */
-	if ((err = i2c_attach_client(new_client)))
-		goto exit_free;
-
-	/* Initialize the MAX1619 chip */
-	max1619_init_client(new_client);
-
-	/* Register sysfs hooks */
-	device_create_file(&new_client->dev, &dev_attr_temp1_input);
-	device_create_file(&new_client->dev, &dev_attr_temp2_input);
-	device_create_file(&new_client->dev, &dev_attr_temp2_min);
-	device_create_file(&new_client->dev, &dev_attr_temp2_max);
-	device_create_file(&new_client->dev, &dev_attr_temp2_crit);
-	device_create_file(&new_client->dev, &dev_attr_temp2_crit_hyst);
-	device_create_file(&new_client->dev, &dev_attr_alarms);
-
-	return 0;
-
-exit_free:
-	kfree(data);
-exit:
-	return err;
-}
-
-static void max1619_init_client(struct i2c_client *client)
-{
-	u8 config;
-
-	/*
-	 * Start the conversions.
-	 */
-	i2c_smbus_write_byte_data(client, MAX1619_REG_W_CONVRATE,
-				  5); /* 2 Hz */
-	config = i2c_smbus_read_byte_data(client, MAX1619_REG_R_CONFIG);
-	if (config & 0x40)
-		i2c_smbus_write_byte_data(client, MAX1619_REG_W_CONFIG,
-					  config & 0xBF); /* run */
-}
-
-static int max1619_detach_client(struct i2c_client *client)
-{
-	int err;
-
-	if ((err = i2c_detach_client(client))) {
-		dev_err(&client->dev, "Client deregistration failed, "
-			"client not detached.\n");
-		return err;
-	}
-
-	kfree(i2c_get_clientdata(client));
-	return 0;
-}
-
-static struct max1619_data *max1619_update_device(struct device *dev)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct max1619_data *data = i2c_get_clientdata(client);
-
-	down(&data->update_lock);
-
-	if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) {
-		dev_dbg(&client->dev, "Updating max1619 data.\n");
-		data->temp_input1 = i2c_smbus_read_byte_data(client,
-					MAX1619_REG_R_LOCAL_TEMP);
-		data->temp_input2 = i2c_smbus_read_byte_data(client,
-					MAX1619_REG_R_REMOTE_TEMP);
-		data->temp_high2 = i2c_smbus_read_byte_data(client,
-					MAX1619_REG_R_REMOTE_HIGH);
-		data->temp_low2 = i2c_smbus_read_byte_data(client,
-					MAX1619_REG_R_REMOTE_LOW);
-		data->temp_crit2 = i2c_smbus_read_byte_data(client,
-					MAX1619_REG_R_REMOTE_CRIT);
-		data->temp_hyst2 = i2c_smbus_read_byte_data(client,
-					MAX1619_REG_R_TCRIT_HYST);
-		data->alarms = i2c_smbus_read_byte_data(client,
-					MAX1619_REG_R_STATUS);
-
-		data->last_updated = jiffies;
-		data->valid = 1;
-	}
-
-	up(&data->update_lock);
-
-	return data;
-}
-
-static int __init sensors_max1619_init(void)
-{
-	return i2c_add_driver(&max1619_driver);
-}
-
-static void __exit sensors_max1619_exit(void)
-{
-	i2c_del_driver(&max1619_driver);
-}
-
-MODULE_AUTHOR("Alexey Fisher <fishor@mail.ru> and"
-	"Jean Delvare <khali@linux-fr.org>");
-MODULE_DESCRIPTION("MAX1619 sensor driver");
-MODULE_LICENSE("GPL");
-
-module_init(sensors_max1619_init);
-module_exit(sensors_max1619_exit);
diff --git a/drivers/i2c/chips/max6875.c b/drivers/i2c/chips/max6875.c
new file mode 100644
--- /dev/null
+++ b/drivers/i2c/chips/max6875.c
@@ -0,0 +1,479 @@
+/*
+    max6875.c - driver for MAX6874/MAX6875
+
+    Copyright (C) 2005 Ben Gardner <bgardner@wabtec.com>
+
+    Based on i2c/chips/eeprom.c
+
+    The MAX6875 has two EEPROM sections: config and user.
+    At reset, the config EEPROM is read into the registers.
+
+    This driver make 3 binary files available in sysfs:
+      reg_config    - direct access to the registers
+      eeprom_config - acesses configuration eeprom space
+      eeprom_user   - free for application use
+
+    In our application, we put device serial & model numbers in user eeprom.
+
+    Notes:
+      1) The datasheet says that register 0x44 / EEPROM 0x8044 should NOT
+         be overwritten, so the driver explicitly prevents that.
+      2) It's a good idea to keep the config (0x45) locked in config EEPROM.
+         You can temporarily enable config writes by changing register 0x45.
+
+    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; version 2 of the License.
+*/
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/i2c-sensor.h>
+
+/* Addresses to scan */
+/* No address scanned by default, as this could corrupt standard EEPROMS. */
+static unsigned short normal_i2c[] = {I2C_CLIENT_END};
+static unsigned int normal_isa[] = {I2C_CLIENT_ISA_END};
+
+/* Insmod parameters */
+SENSORS_INSMOD_1(max6875);
+
+/* this param will prevent 'accidental' writes to the eeprom */
+static int allow_write = 0;
+module_param(allow_write, int, 0);
+MODULE_PARM_DESC(allow_write,
+		 "Enable write access:\n"
+		 "*0: Read only\n"
+		 " 1: Read/Write access");
+
+/* The MAX6875 can only read/write 16 bytes at a time */
+#define SLICE_SIZE			16
+#define SLICE_BITS			4
+
+/* CONFIG EEPROM is at addresses 0x8000 - 0x8045, registers are at 0 - 0x45 */
+#define CONFIG_EEPROM_BASE		0x8000
+#define CONFIG_EEPROM_SIZE		0x0046
+#define CONFIG_EEPROM_SLICES		5
+
+/* USER EEPROM is at addresses 0x8100 - 0x82FF */
+#define USER_EEPROM_BASE		0x8100
+#define USER_EEPROM_SIZE		0x0200
+#define USER_EEPROM_SLICES		32
+
+/* MAX6875 commands */
+#define MAX6875_CMD_BLOCK_WRITE		0x83
+#define MAX6875_CMD_BLOCK_READ		0x84
+#define MAX6875_CMD_REBOOT		0x88
+
+enum max6875_area_type {
+	max6875_register_config=0,
+	max6875_eeprom_config,
+	max6875_eeprom_user,
+	max6857_max
+};
+
+struct eeprom_block {
+	enum max6875_area_type	type;
+	u8			slices;
+	u32			size;
+	u32			valid;
+	u32			base;
+	unsigned long		*updated;
+	u8			*data;
+};
+
+/* Each client has this additional data */
+struct max6875_data {
+	struct i2c_client	client;
+	struct semaphore	update_lock;
+	struct eeprom_block	blocks[max6857_max];
+	/* the above structs point into the arrays below */
+	u8 data[USER_EEPROM_SIZE + (CONFIG_EEPROM_SIZE*2)];
+	unsigned long last_updated[USER_EEPROM_SLICES + (CONFIG_EEPROM_SLICES*2)];
+};
+
+static int max6875_attach_adapter(struct i2c_adapter *adapter);
+static int max6875_detect(struct i2c_adapter *adapter, int address, int kind);
+static int max6875_detach_client(struct i2c_client *client);
+
+/* This is the driver that will be inserted */
+static struct i2c_driver max6875_driver = {
+	.owner		= THIS_MODULE,
+	.name		= "max6875",
+	.flags		= I2C_DF_NOTIFY,
+	.attach_adapter	= max6875_attach_adapter,
+	.detach_client	= max6875_detach_client,
+};
+
+static int max6875_update_slice(struct i2c_client *client,
+				struct eeprom_block *blk,
+				int slice)
+{
+	struct max6875_data *data = i2c_get_clientdata(client);
+	int i, j, addr, count;
+	u8 rdbuf[SLICE_SIZE];
+	int retval = 0;
+
+	if (slice >= blk->slices)
+		return -1;
+
+	down(&data->update_lock);
+
+	if (!(blk->valid & (1 << slice)) ||
+	    (jiffies - blk->updated[slice] > 300 * HZ) ||
+	    (jiffies < blk->updated[slice])) {
+		dev_dbg(&client->dev, "Starting eeprom update, slice %u, base %u\n",
+			slice, blk->base);
+
+		addr = blk->base + (slice << SLICE_BITS);
+		count = blk->size - (slice << SLICE_BITS);
+		if (count > SLICE_SIZE) {
+			count = SLICE_SIZE;
+		}
+
+		/* Preset the read address */
+		if (addr < 0x100) {
+			/* select the register */
+			if (i2c_smbus_write_byte(client, addr & 0xFF)) {
+				dev_dbg(&client->dev, "max6875 register select has failed!\n");
+				retval = -1;
+				goto exit;
+			}
+		} else {
+			/* select the eeprom */
+			if (i2c_smbus_write_byte_data(client, addr >> 8, addr & 0xFF)) {
+				dev_dbg(&client->dev, "max6875 address set has failed!\n");
+				retval = -1;
+				goto exit;
+			}
+		}
+
+		if (i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_READ_I2C_BLOCK)) {
+			if (i2c_smbus_read_i2c_block_data(client, MAX6875_CMD_BLOCK_READ,
+							  rdbuf) != SLICE_SIZE)
+			{
+				retval = -1;
+				goto exit;
+			}
+
+			memcpy(&blk->data[slice << SLICE_BITS], rdbuf, count);
+		} else {
+			for (i = 0; i < count; i++) {
+				j = i2c_smbus_read_byte(client);
+				if (j < 0)
+				{
+					retval = -1;
+					goto exit;
+				}
+				blk->data[(slice << SLICE_BITS) + i] = (u8) j;
+			}
+		}
+		blk->updated[slice] = jiffies;
+		blk->valid |= (1 << slice);
+	}
+	exit:
+	up(&data->update_lock);
+	return retval;
+}
+
+static ssize_t max6875_read(struct kobject *kobj, char *buf, loff_t off, size_t count,
+			    enum max6875_area_type area_type)
+{
+	struct i2c_client *client = to_i2c_client(container_of(kobj, struct device, kobj));
+	struct max6875_data *data = i2c_get_clientdata(client);
+	struct eeprom_block *blk;
+	int slice;
+
+	blk = &data->blocks[area_type];
+
+	if (off > blk->size)
+		return 0;
+	if (off + count > blk->size)
+		count = blk->size - off;
+
+	/* Only refresh slices which contain requested bytes */
+	for (slice = (off >> SLICE_BITS); slice <= ((off + count - 1) >> SLICE_BITS); slice++)
+		max6875_update_slice(client, blk, slice);
+
+	memcpy(buf, &blk->data[off], count);
+
+	return count;
+}
+
+static ssize_t max6875_user_read(struct kobject *kobj, char *buf, loff_t off, size_t count)
+{
+	return max6875_read(kobj, buf, off, count, max6875_eeprom_user);
+}
+
+static ssize_t max6875_config_read(struct kobject *kobj, char *buf, loff_t off, size_t count)
+{
+	return max6875_read(kobj, buf, off, count, max6875_eeprom_config);
+}
+
+static ssize_t max6875_cfgreg_read(struct kobject *kobj, char *buf, loff_t off, size_t count)
+{
+	return max6875_read(kobj, buf, off, count, max6875_register_config);
+}
+
+
+static ssize_t max6875_write(struct kobject *kobj, char *buf, loff_t off, size_t count,
+			     enum max6875_area_type area_type)
+{
+	struct i2c_client *client = to_i2c_client(container_of(kobj, struct device, kobj));
+	struct max6875_data *data = i2c_get_clientdata(client);
+	struct eeprom_block *blk;
+	int slice, addr, retval;
+	ssize_t sent = 0;
+
+	blk = &data->blocks[area_type];
+
+	if (off > blk->size)
+		return 0;
+	if ((off + count) > blk->size)
+		count = blk->size - off;
+
+	if (down_interruptible(&data->update_lock))
+		return -EAGAIN;
+
+	/* writing to a register is done with i2c_smbus_write_byte_data() */
+	if (blk->type == max6875_register_config) {
+		for (sent = 0; sent < count; sent++) {
+			addr = off + sent;
+			if (addr == 0x44)
+				continue;
+
+			retval = i2c_smbus_write_byte_data(client, addr, buf[sent]);
+		}
+	} else {
+		int cmd, val;
+
+		/* We are writing to EEPROM */
+		for (sent = 0; sent < count; sent++) {
+			addr = blk->base + off + sent;
+			cmd = addr >> 8;
+			val = (addr & 0xff) | (buf[sent] << 8);	// reversed
+
+			if (addr == 0x8044)
+				continue;
+
+			retval = i2c_smbus_write_word_data(client, cmd, val);
+
+			if (retval) {
+				goto error_exit;
+			}
+
+			/* A write takes up to 11 ms */
+			msleep(11);
+		}
+	}
+
+	/* Invalidate the scratch buffer */
+	for (slice = (off >> SLICE_BITS); slice <= ((off + count - 1) >> SLICE_BITS); slice++)
+		blk->valid &= ~(1 << slice);
+
+	error_exit:
+	up(&data->update_lock);
+
+	return sent;
+}
+
+static ssize_t max6875_user_write(struct kobject *kobj, char *buf, loff_t off, size_t count)
+{
+	return max6875_write(kobj, buf, off, count, max6875_eeprom_user);
+}
+
+static ssize_t max6875_config_write(struct kobject *kobj, char *buf, loff_t off, size_t count)
+{
+	return max6875_write(kobj, buf, off, count, max6875_eeprom_config);
+}
+
+static ssize_t max6875_cfgreg_write(struct kobject *kobj, char *buf, loff_t off, size_t count)
+{
+	return max6875_write(kobj, buf, off, count, max6875_register_config);
+}
+
+static struct bin_attribute user_eeprom_attr = {
+	.attr = {
+		.name = "eeprom_user",
+		.mode = S_IRUGO | S_IWUSR | S_IWGRP,
+		.owner = THIS_MODULE,
+	},
+	.size  = USER_EEPROM_SIZE,
+	.read  = max6875_user_read,
+	.write = max6875_user_write,
+};
+
+static struct bin_attribute config_eeprom_attr = {
+	.attr = {
+		.name = "eeprom_config",
+		.mode = S_IRUGO | S_IWUSR,
+		.owner = THIS_MODULE,
+	},
+	.size  = CONFIG_EEPROM_SIZE,
+	.read  = max6875_config_read,
+	.write = max6875_config_write,
+};
+
+static struct bin_attribute config_register_attr = {
+	.attr = {
+		.name = "reg_config",
+		.mode = S_IRUGO | S_IWUSR,
+		.owner = THIS_MODULE,
+	},
+	.size  = CONFIG_EEPROM_SIZE,
+	.read  = max6875_cfgreg_read,
+	.write = max6875_cfgreg_write,
+};
+
+static int max6875_attach_adapter(struct i2c_adapter *adapter)
+{
+	return i2c_detect(adapter, &addr_data, max6875_detect);
+}
+
+/* This function is called by i2c_detect */
+static int max6875_detect(struct i2c_adapter *adapter, int address, int kind)
+{
+	struct i2c_client *new_client;
+	struct max6875_data *data;
+	int err = 0;
+
+	/* Prevent 24RF08 corruption (in case of user error) */
+	if (kind < 0)
+		i2c_smbus_xfer(adapter, address, 0, 0, 0,
+			       I2C_SMBUS_QUICK, NULL);
+
+	/* There are three ways we can read the EEPROM data:
+	   (1) I2C block reads (faster, but unsupported by most adapters)
+	   (2) Consecutive byte reads (100% overhead)
+	   (3) Regular byte data reads (200% overhead)
+	   The third method is not implemented by this driver because all
+	   known adapters support at least the second. */
+	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_BYTE_DATA |
+				     I2C_FUNC_SMBUS_BYTE |
+				     I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
+		goto exit;
+
+	/* OK. For now, we presume we have a valid client. We now create the
+	   client structure, even though we cannot fill it completely yet.
+	   But it allows us to access eeprom_{read,write}_value. */
+	if (!(data = kmalloc(sizeof(struct max6875_data), GFP_KERNEL))) {
+		err = -ENOMEM;
+		goto exit;
+	}
+	memset(data, 0, sizeof(struct max6875_data));
+
+	new_client = &data->client;
+	i2c_set_clientdata(new_client, data);
+	new_client->addr = address;
+	new_client->adapter = adapter;
+	new_client->driver = &max6875_driver;
+	new_client->flags = 0;
+
+	/* Setup the user section */
+	data->blocks[max6875_eeprom_user].type    = max6875_eeprom_user;
+	data->blocks[max6875_eeprom_user].slices  = USER_EEPROM_SLICES;
+	data->blocks[max6875_eeprom_user].size    = USER_EEPROM_SIZE;
+	data->blocks[max6875_eeprom_user].base    = USER_EEPROM_BASE;
+	data->blocks[max6875_eeprom_user].data    = data->data;
+	data->blocks[max6875_eeprom_user].updated = data->last_updated;
+
+	/* Setup the config section */
+	data->blocks[max6875_eeprom_config].type    = max6875_eeprom_config;
+	data->blocks[max6875_eeprom_config].slices  = CONFIG_EEPROM_SLICES;
+	data->blocks[max6875_eeprom_config].size    = CONFIG_EEPROM_SIZE;
+	data->blocks[max6875_eeprom_config].base    = CONFIG_EEPROM_BASE;
+	data->blocks[max6875_eeprom_config].data    = &data->data[USER_EEPROM_SIZE];
+	data->blocks[max6875_eeprom_config].updated = &data->last_updated[USER_EEPROM_SLICES];
+
+	/* Setup the register section */
+	data->blocks[max6875_register_config].type    = max6875_register_config;
+	data->blocks[max6875_register_config].slices  = CONFIG_EEPROM_SLICES;
+	data->blocks[max6875_register_config].size    = CONFIG_EEPROM_SIZE;
+	data->blocks[max6875_register_config].base    = 0;
+	data->blocks[max6875_register_config].data    = &data->data[USER_EEPROM_SIZE+CONFIG_EEPROM_SIZE];
+	data->blocks[max6875_register_config].updated = &data->last_updated[USER_EEPROM_SLICES+CONFIG_EEPROM_SLICES];
+
+	/* Init the data */
+	memset(data->data, 0xff, sizeof(data->data));
+
+	/* Fill in the remaining client fields */
+	strlcpy(new_client->name, "max6875", I2C_NAME_SIZE);
+	init_MUTEX(&data->update_lock);
+
+	/* Verify that the chip is really what we think it is */
+	if ((max6875_update_slice(new_client, &data->blocks[max6875_eeprom_config], 4) < 0) ||
+	    (max6875_update_slice(new_client, &data->blocks[max6875_register_config], 4) < 0))
+		goto exit_kfree;
+
+	/* 0x41,0x42 must be zero and 0x40 must match in eeprom and registers */
+	if ((data->blocks[max6875_eeprom_config].data[0x41] != 0) ||
+	    (data->blocks[max6875_eeprom_config].data[0x42] != 0) ||
+	    (data->blocks[max6875_register_config].data[0x41] != 0) ||
+	    (data->blocks[max6875_register_config].data[0x42] != 0) ||
+	    (data->blocks[max6875_eeprom_config].data[0x40] !=
+	     data->blocks[max6875_register_config].data[0x40]))
+		goto exit_kfree;
+
+	/* Tell the I2C layer a new client has arrived */
+	if ((err = i2c_attach_client(new_client)))
+		goto exit_kfree;
+
+	/* create the sysfs eeprom files with the correct permissions */
+	if (allow_write == 0) {
+		user_eeprom_attr.attr.mode &= ~S_IWUGO;
+		user_eeprom_attr.write = NULL;
+		config_eeprom_attr.attr.mode &= ~S_IWUGO;
+		config_eeprom_attr.write = NULL;
+		config_register_attr.attr.mode &= ~S_IWUGO;
+		config_register_attr.write = NULL;
+	}
+	sysfs_create_bin_file(&new_client->dev.kobj, &user_eeprom_attr);
+	sysfs_create_bin_file(&new_client->dev.kobj, &config_eeprom_attr);
+	sysfs_create_bin_file(&new_client->dev.kobj, &config_register_attr);
+
+	return 0;
+
+exit_kfree:
+	kfree(data);
+exit:
+	return err;
+}
+
+static int max6875_detach_client(struct i2c_client *client)
+{
+	int err;
+
+	err = i2c_detach_client(client);
+	if (err) {
+		dev_err(&client->dev, "Client deregistration failed, client not detached.\n");
+		return err;
+	}
+
+	kfree(i2c_get_clientdata(client));
+
+	return 0;
+}
+
+static int __init max6875_init(void)
+{
+	return i2c_add_driver(&max6875_driver);
+}
+
+static void __exit max6875_exit(void)
+{
+	i2c_del_driver(&max6875_driver);
+}
+
+
+MODULE_AUTHOR("Ben Gardner <bgardner@wabtec.com>");
+MODULE_DESCRIPTION("MAX6875 driver");
+MODULE_LICENSE("GPL");
+
+module_init(max6875_init);
+module_exit(max6875_exit);
diff --git a/drivers/i2c/chips/pc87360.c b/drivers/i2c/chips/pc87360.c
deleted file mode 100644
--- a/drivers/i2c/chips/pc87360.c
+++ /dev/null
@@ -1,1349 +0,0 @@
-/*
- *  pc87360.c - Part of lm_sensors, Linux kernel modules
- *              for hardware monitoring
- *  Copyright (C) 2004 Jean Delvare <khali@linux-fr.org>
- *
- *  Copied from smsc47m1.c:
- *  Copyright (C) 2002 Mark D. Studebaker <mdsxyz123@yahoo.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., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *  Supports the following chips:
- *
- *  Chip        #vin    #fan    #pwm    #temp   devid
- *  PC87360     -       2       2       -       0xE1
- *  PC87363     -       2       2       -       0xE8
- *  PC87364     -       3       3       -       0xE4
- *  PC87365     11      3       3       2       0xE5
- *  PC87366     11      3       3       3-4     0xE9
- *
- *  This driver assumes that no more than one chip is present, and one of
- *  the standard Super-I/O addresses is used (0x2E/0x2F or 0x4E/0x4F).
- */
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/jiffies.h>
-#include <linux/i2c.h>
-#include <linux/i2c-sensor.h>
-#include <linux/i2c-vid.h>
-#include <asm/io.h>
-
-static unsigned short normal_i2c[] = { I2C_CLIENT_END };
-static unsigned int normal_isa[] = { 0, I2C_CLIENT_ISA_END };
-static struct i2c_force_data forces[] = {{ NULL }};
-static u8 devid;
-static unsigned int extra_isa[3];
-static u8 confreg[4];
-
-enum chips { any_chip, pc87360, pc87363, pc87364, pc87365, pc87366 };
-static struct i2c_address_data addr_data = {
-	.normal_i2c		= normal_i2c,
-	.normal_isa		= normal_isa,
-	.forces			= forces,
-};
-
-static int init = 1;
-module_param(init, int, 0);
-MODULE_PARM_DESC(init,
- "Chip initialization level:\n"
- " 0: None\n"
- "*1: Forcibly enable internal voltage and temperature channels, except in9\n"
- " 2: Forcibly enable all voltage and temperature channels, except in9\n"
- " 3: Forcibly enable all voltage and temperature channels, including in9");
-
-/*
- * Super-I/O registers and operations
- */
-
-#define DEV	0x07	/* Register: Logical device select */
-#define DEVID	0x20	/* Register: Device ID */
-#define ACT	0x30	/* Register: Device activation */
-#define BASE	0x60	/* Register: Base address */
-
-#define FSCM	0x09	/* Logical device: fans */
-#define VLM	0x0d	/* Logical device: voltages */
-#define TMS	0x0e	/* Logical device: temperatures */
-static const u8 logdev[3] = { FSCM, VLM, TMS };
-
-#define LD_FAN		0
-#define LD_IN		1
-#define LD_TEMP		2
-
-static inline void superio_outb(int sioaddr, int reg, int val)
-{
-	outb(reg, sioaddr);
-	outb(val, sioaddr+1);
-}
-
-static inline int superio_inb(int sioaddr, int reg)
-{
-	outb(reg, sioaddr);
-	return inb(sioaddr+1);
-}
-
-static inline void superio_exit(int sioaddr)
-{
-	outb(0x02, sioaddr);
-	outb(0x02, sioaddr+1);
-}
-
-/*
- * Logical devices
- */
-
-#define PC87360_EXTENT		0x10
-#define PC87365_REG_BANK	0x09
-#define NO_BANK			0xff
-
-/*
- * Fan registers and conversions
- */
-
-/* nr has to be 0 or 1 (PC87360/87363) or 2 (PC87364/87365/87366) */
-#define PC87360_REG_PRESCALE(nr)	(0x00 + 2 * (nr))
-#define PC87360_REG_PWM(nr)		(0x01 + 2 * (nr))
-#define PC87360_REG_FAN_MIN(nr)		(0x06 + 3 * (nr))
-#define PC87360_REG_FAN(nr)		(0x07 + 3 * (nr))
-#define PC87360_REG_FAN_STATUS(nr)	(0x08 + 3 * (nr))
-
-#define FAN_FROM_REG(val,div)		((val) == 0 ? 0: \
-					 480000 / ((val)*(div)))
-#define FAN_TO_REG(val,div)		((val) <= 100 ? 0 : \
-					 480000 / ((val)*(div)))
-#define FAN_DIV_FROM_REG(val)		(1 << ((val >> 5) & 0x03))
-#define FAN_STATUS_FROM_REG(val)	((val) & 0x07)
-
-#define FAN_CONFIG_MONITOR(val,nr)	(((val) >> (2 + nr * 3)) & 1)
-#define FAN_CONFIG_CONTROL(val,nr)	(((val) >> (3 + nr * 3)) & 1)
-#define FAN_CONFIG_INVERT(val,nr)	(((val) >> (4 + nr * 3)) & 1)
-
-#define PWM_FROM_REG(val,inv)		((inv) ? 255 - (val) : (val))
-static inline u8 PWM_TO_REG(int val, int inv)
-{
-	if (inv)
-		val = 255 - val;
-	if (val < 0)
-		return 0;
-	if (val > 255)
-		return 255;
-	return val;
-}
-
-/*
- * Voltage registers and conversions
- */
-
-#define PC87365_REG_IN_CONVRATE		0x07
-#define PC87365_REG_IN_CONFIG		0x08
-#define PC87365_REG_IN			0x0B
-#define PC87365_REG_IN_MIN		0x0D
-#define PC87365_REG_IN_MAX		0x0C
-#define PC87365_REG_IN_STATUS		0x0A
-#define PC87365_REG_IN_ALARMS1		0x00
-#define PC87365_REG_IN_ALARMS2		0x01
-#define PC87365_REG_VID			0x06
-
-#define IN_FROM_REG(val,ref)		(((val) * (ref) + 128) / 256)
-#define IN_TO_REG(val,ref)		((val) < 0 ? 0 : \
-					 (val)*256 >= (ref)*255 ? 255: \
-					 ((val) * 256 + (ref)/2) / (ref))
-
-/*
- * Temperature registers and conversions
- */
-
-#define PC87365_REG_TEMP_CONFIG		0x08
-#define PC87365_REG_TEMP		0x0B
-#define PC87365_REG_TEMP_MIN		0x0D
-#define PC87365_REG_TEMP_MAX		0x0C
-#define PC87365_REG_TEMP_CRIT		0x0E
-#define PC87365_REG_TEMP_STATUS		0x0A
-#define PC87365_REG_TEMP_ALARMS		0x00
-
-#define TEMP_FROM_REG(val)		((val) * 1000)
-#define TEMP_TO_REG(val)		((val) < -55000 ? -55 : \
-					 (val) > 127000 ? 127 : \
-					 (val) < 0 ? ((val) - 500) / 1000 : \
-					 ((val) + 500) / 1000)
-
-/*
- * Client data (each client gets its own)
- */
-
-struct pc87360_data {
-	struct i2c_client client;
-	struct semaphore lock;
-	struct semaphore update_lock;
-	char valid;		/* !=0 if following fields are valid */
-	unsigned long last_updated;	/* In jiffies */
-
-	int address[3];
-
-	u8 fannr, innr, tempnr;
-
-	u8 fan[3];		/* Register value */
-	u8 fan_min[3];		/* Register value */
-	u8 fan_status[3];	/* Register value */
-	u8 pwm[3];		/* Register value */
-	u16 fan_conf;		/* Configuration register values, combined */
-
-	u16 in_vref;		/* 1 mV/bit */
-	u8 in[14];		/* Register value */
-	u8 in_min[14];		/* Register value */
-	u8 in_max[14];		/* Register value */
-	u8 in_crit[3];		/* Register value */
-	u8 in_status[14];	/* Register value */
-	u16 in_alarms;		/* Register values, combined, masked */
-	u8 vid_conf;		/* Configuration register value */
-	u8 vrm;
-	u8 vid;			/* Register value */
-
-	s8 temp[3];		/* Register value */
-	s8 temp_min[3];		/* Register value */
-	s8 temp_max[3];		/* Register value */
-	s8 temp_crit[3];	/* Register value */
-	u8 temp_status[3];	/* Register value */
-	u8 temp_alarms;		/* Register value, masked */
-};
-
-/*
- * Functions declaration
- */
-
-static int pc87360_attach_adapter(struct i2c_adapter *adapter);
-static int pc87360_detect(struct i2c_adapter *adapter, int address, int kind);
-static int pc87360_detach_client(struct i2c_client *client);
-
-static int pc87360_read_value(struct pc87360_data *data, u8 ldi, u8 bank,
-			      u8 reg);
-static void pc87360_write_value(struct pc87360_data *data, u8 ldi, u8 bank,
-				u8 reg, u8 value);
-static void pc87360_init_client(struct i2c_client *client, int use_thermistors);
-static struct pc87360_data *pc87360_update_device(struct device *dev);
-
-/*
- * Driver data (common to all clients)
- */
-
-static struct i2c_driver pc87360_driver = {
-	.owner		= THIS_MODULE,
-	.name		= "pc87360",
-	.flags		= I2C_DF_NOTIFY,
-	.attach_adapter	= pc87360_attach_adapter,
-	.detach_client	= pc87360_detach_client,
-};
-
-/*
- * Sysfs stuff
- */
-
-static ssize_t set_fan_min(struct device *dev, const char *buf,
-	size_t count, int nr)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct pc87360_data *data = i2c_get_clientdata(client);
-	long fan_min = simple_strtol(buf, NULL, 10);
-
-	down(&data->update_lock);
-	fan_min = FAN_TO_REG(fan_min, FAN_DIV_FROM_REG(data->fan_status[nr]));
-
-	/* If it wouldn't fit, change clock divisor */
-	while (fan_min > 255
-	    && (data->fan_status[nr] & 0x60) != 0x60) {
-		fan_min >>= 1;
-		data->fan[nr] >>= 1;
-		data->fan_status[nr] += 0x20;
-	}
-	data->fan_min[nr] = fan_min > 255 ? 255 : fan_min;
-	pc87360_write_value(data, LD_FAN, NO_BANK, PC87360_REG_FAN_MIN(nr),
-			    data->fan_min[nr]);
-
-	/* Write new divider, preserve alarm bits */
-	pc87360_write_value(data, LD_FAN, NO_BANK, PC87360_REG_FAN_STATUS(nr),
-			    data->fan_status[nr] & 0xF9);
-	up(&data->update_lock);
-
-	return count;
-}
-
-#define show_and_set_fan(offset) \
-static ssize_t show_fan##offset##_input(struct device *dev, char *buf) \
-{ \
-	struct pc87360_data *data = pc87360_update_device(dev); \
-	return sprintf(buf, "%u\n", FAN_FROM_REG(data->fan[offset-1], \
-		       FAN_DIV_FROM_REG(data->fan_status[offset-1]))); \
-} \
-static ssize_t show_fan##offset##_min(struct device *dev, char *buf) \
-{ \
-	struct pc87360_data *data = pc87360_update_device(dev); \
-	return sprintf(buf, "%u\n", FAN_FROM_REG(data->fan_min[offset-1], \
-		       FAN_DIV_FROM_REG(data->fan_status[offset-1]))); \
-} \
-static ssize_t show_fan##offset##_div(struct device *dev, char *buf) \
-{ \
-	struct pc87360_data *data = pc87360_update_device(dev); \
-	return sprintf(buf, "%u\n", \
-		       FAN_DIV_FROM_REG(data->fan_status[offset-1])); \
-} \
-static ssize_t show_fan##offset##_status(struct device *dev, char *buf) \
-{ \
-	struct pc87360_data *data = pc87360_update_device(dev); \
-	return sprintf(buf, "%u\n", \
-		       FAN_STATUS_FROM_REG(data->fan_status[offset-1])); \
-} \
-static ssize_t set_fan##offset##_min(struct device *dev, const char *buf, \
-	size_t count) \
-{ \
-	return set_fan_min(dev, buf, count, offset-1); \
-} \
-static DEVICE_ATTR(fan##offset##_input, S_IRUGO, \
-	show_fan##offset##_input, NULL); \
-static DEVICE_ATTR(fan##offset##_min, S_IWUSR | S_IRUGO, \
-	show_fan##offset##_min, set_fan##offset##_min); \
-static DEVICE_ATTR(fan##offset##_div, S_IRUGO, \
-	show_fan##offset##_div, NULL); \
-static DEVICE_ATTR(fan##offset##_status, S_IRUGO, \
-	show_fan##offset##_status, NULL);
-show_and_set_fan(1)
-show_and_set_fan(2)
-show_and_set_fan(3)
-
-#define show_and_set_pwm(offset) \
-static ssize_t show_pwm##offset(struct device *dev, char *buf) \
-{ \
-	struct pc87360_data *data = pc87360_update_device(dev); \
-	return sprintf(buf, "%u\n", \
-		       PWM_FROM_REG(data->pwm[offset-1], \
-				    FAN_CONFIG_INVERT(data->fan_conf, \
-						      offset-1))); \
-} \
-static ssize_t set_pwm##offset(struct device *dev, const char *buf, \
-	size_t count) \
-{ \
-	struct i2c_client *client = to_i2c_client(dev); \
-	struct pc87360_data *data = i2c_get_clientdata(client); \
-	long val = simple_strtol(buf, NULL, 10); \
- \
-	down(&data->update_lock); \
-	data->pwm[offset-1] = PWM_TO_REG(val, \
-			      FAN_CONFIG_INVERT(data->fan_conf, offset-1)); \
-	pc87360_write_value(data, LD_FAN, NO_BANK, PC87360_REG_PWM(offset-1), \
-			    data->pwm[offset-1]); \
-	up(&data->update_lock); \
-	return count; \
-} \
-static DEVICE_ATTR(pwm##offset, S_IWUSR | S_IRUGO, \
-	show_pwm##offset, set_pwm##offset);
-show_and_set_pwm(1)
-show_and_set_pwm(2)
-show_and_set_pwm(3)
-
-#define show_and_set_in(offset) \
-static ssize_t show_in##offset##_input(struct device *dev, char *buf) \
-{ \
-	struct pc87360_data *data = pc87360_update_device(dev); \
-	return sprintf(buf, "%u\n", IN_FROM_REG(data->in[offset], \
-		       data->in_vref)); \
-} \
-static ssize_t show_in##offset##_min(struct device *dev, char *buf) \
-{ \
-	struct pc87360_data *data = pc87360_update_device(dev); \
-	return sprintf(buf, "%u\n", IN_FROM_REG(data->in_min[offset], \
-		       data->in_vref)); \
-} \
-static ssize_t show_in##offset##_max(struct device *dev, char *buf) \
-{ \
-	struct pc87360_data *data = pc87360_update_device(dev); \
-	return sprintf(buf, "%u\n", IN_FROM_REG(data->in_max[offset], \
-		       data->in_vref)); \
-} \
-static ssize_t show_in##offset##_status(struct device *dev, char *buf) \
-{ \
-	struct pc87360_data *data = pc87360_update_device(dev); \
-	return sprintf(buf, "%u\n", data->in_status[offset]); \
-} \
-static ssize_t set_in##offset##_min(struct device *dev, const char *buf, \
-	size_t count) \
-{ \
-	struct i2c_client *client = to_i2c_client(dev); \
-	struct pc87360_data *data = i2c_get_clientdata(client); \
-	long val = simple_strtol(buf, NULL, 10); \
- \
-	down(&data->update_lock); \
-	data->in_min[offset] = IN_TO_REG(val, data->in_vref); \
-	pc87360_write_value(data, LD_IN, offset, PC87365_REG_IN_MIN, \
-			    data->in_min[offset]); \
-	up(&data->update_lock); \
-	return count; \
-} \
-static ssize_t set_in##offset##_max(struct device *dev, const char *buf, \
-	size_t count) \
-{ \
-	struct i2c_client *client = to_i2c_client(dev); \
-	struct pc87360_data *data = i2c_get_clientdata(client); \
-	long val = simple_strtol(buf, NULL, 10); \
- \
-	down(&data->update_lock); \
-	data->in_max[offset] = IN_TO_REG(val, \
-			       data->in_vref); \
-	pc87360_write_value(data, LD_IN, offset, PC87365_REG_IN_MAX, \
-			    data->in_max[offset]); \
-	up(&data->update_lock); \
-	return count; \
-} \
-static DEVICE_ATTR(in##offset##_input, S_IRUGO, \
-	show_in##offset##_input, NULL); \
-static DEVICE_ATTR(in##offset##_min, S_IWUSR | S_IRUGO, \
-	show_in##offset##_min, set_in##offset##_min); \
-static DEVICE_ATTR(in##offset##_max, S_IWUSR | S_IRUGO, \
-	show_in##offset##_max, set_in##offset##_max); \
-static DEVICE_ATTR(in##offset##_status, S_IRUGO, \
-	show_in##offset##_status, NULL);
-show_and_set_in(0)
-show_and_set_in(1)
-show_and_set_in(2)
-show_and_set_in(3)
-show_and_set_in(4)
-show_and_set_in(5)
-show_and_set_in(6)
-show_and_set_in(7)
-show_and_set_in(8)
-show_and_set_in(9)
-show_and_set_in(10)
-
-#define show_and_set_therm(offset) \
-static ssize_t show_temp##offset##_input(struct device *dev, char *buf) \
-{ \
-	struct pc87360_data *data = pc87360_update_device(dev); \
-	return sprintf(buf, "%u\n", IN_FROM_REG(data->in[offset+7], \
-		       data->in_vref)); \
-} \
-static ssize_t show_temp##offset##_min(struct device *dev, char *buf) \
-{ \
-	struct pc87360_data *data = pc87360_update_device(dev); \
-	return sprintf(buf, "%u\n", IN_FROM_REG(data->in_min[offset+7], \
-		       data->in_vref)); \
-} \
-static ssize_t show_temp##offset##_max(struct device *dev, char *buf) \
-{ \
-	struct pc87360_data *data = pc87360_update_device(dev); \
-	return sprintf(buf, "%u\n", IN_FROM_REG(data->in_max[offset+7], \
-		       data->in_vref)); \
-} \
-static ssize_t show_temp##offset##_crit(struct device *dev, char *buf) \
-{ \
-	struct pc87360_data *data = pc87360_update_device(dev); \
-	return sprintf(buf, "%u\n", IN_FROM_REG(data->in_crit[offset-4], \
-		       data->in_vref)); \
-} \
-static ssize_t show_temp##offset##_status(struct device *dev, char *buf) \
-{ \
-	struct pc87360_data *data = pc87360_update_device(dev); \
-	return sprintf(buf, "%u\n", data->in_status[offset+7]); \
-} \
-static ssize_t set_temp##offset##_min(struct device *dev, const char *buf, \
-	size_t count) \
-{ \
-	struct i2c_client *client = to_i2c_client(dev); \
-	struct pc87360_data *data = i2c_get_clientdata(client); \
-	long val = simple_strtol(buf, NULL, 10); \
- \
-	down(&data->update_lock); \
-	data->in_min[offset+7] = IN_TO_REG(val, data->in_vref); \
-	pc87360_write_value(data, LD_IN, offset+7, PC87365_REG_TEMP_MIN, \
-			    data->in_min[offset+7]); \
-	up(&data->update_lock); \
-	return count; \
-} \
-static ssize_t set_temp##offset##_max(struct device *dev, const char *buf, \
-	size_t count) \
-{ \
-	struct i2c_client *client = to_i2c_client(dev); \
-	struct pc87360_data *data = i2c_get_clientdata(client); \
-	long val = simple_strtol(buf, NULL, 10); \
- \
-	down(&data->update_lock); \
-	data->in_max[offset+7] = IN_TO_REG(val, data->in_vref); \
-	pc87360_write_value(data, LD_IN, offset+7, PC87365_REG_TEMP_MAX, \
-			    data->in_max[offset+7]); \
-	up(&data->update_lock); \
-	return count; \
-} \
-static ssize_t set_temp##offset##_crit(struct device *dev, const char *buf, \
-	size_t count) \
-{ \
-	struct i2c_client *client = to_i2c_client(dev); \
-	struct pc87360_data *data = i2c_get_clientdata(client); \
-	long val = simple_strtol(buf, NULL, 10); \
- \
-	down(&data->update_lock); \
-	data->in_crit[offset-4] = IN_TO_REG(val, data->in_vref); \
-	pc87360_write_value(data, LD_IN, offset+7, PC87365_REG_TEMP_CRIT, \
-			    data->in_crit[offset-4]); \
-	up(&data->update_lock); \
-	return count; \
-} \
-static DEVICE_ATTR(temp##offset##_input, S_IRUGO, \
-	show_temp##offset##_input, NULL); \
-static DEVICE_ATTR(temp##offset##_min, S_IWUSR | S_IRUGO, \
-	show_temp##offset##_min, set_temp##offset##_min); \
-static DEVICE_ATTR(temp##offset##_max, S_IWUSR | S_IRUGO, \
-	show_temp##offset##_max, set_temp##offset##_max); \
-static DEVICE_ATTR(temp##offset##_crit, S_IWUSR | S_IRUGO, \
-	show_temp##offset##_crit, set_temp##offset##_crit); \
-static DEVICE_ATTR(temp##offset##_status, S_IRUGO, \
-	show_temp##offset##_status, NULL);
-show_and_set_therm(4)
-show_and_set_therm(5)
-show_and_set_therm(6)
-
-static ssize_t show_vid(struct device *dev, char *buf)
-{
-	struct pc87360_data *data = pc87360_update_device(dev);
-	return sprintf(buf, "%u\n", vid_from_reg(data->vid, data->vrm));
-}
-static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL);
-
-static ssize_t show_vrm(struct device *dev, char *buf)
-{
-	struct pc87360_data *data = pc87360_update_device(dev);
-	return sprintf(buf, "%u\n", data->vrm);
-}
-static ssize_t set_vrm(struct device *dev, const char *buf, size_t count)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct pc87360_data *data = i2c_get_clientdata(client);
-	data->vrm = simple_strtoul(buf, NULL, 10);
-	return count;
-}
-static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm, set_vrm);
-
-static ssize_t show_in_alarms(struct device *dev, char *buf)
-{
-	struct pc87360_data *data = pc87360_update_device(dev);
-	return sprintf(buf, "%u\n", data->in_alarms);
-}
-static DEVICE_ATTR(alarms_in, S_IRUGO, show_in_alarms, NULL);
-
-#define show_and_set_temp(offset) \
-static ssize_t show_temp##offset##_input(struct device *dev, char *buf) \
-{ \
-	struct pc87360_data *data = pc87360_update_device(dev); \
-	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp[offset-1])); \
-} \
-static ssize_t show_temp##offset##_min(struct device *dev, char *buf) \
-{ \
-	struct pc87360_data *data = pc87360_update_device(dev); \
-	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_min[offset-1])); \
-} \
-static ssize_t show_temp##offset##_max(struct device *dev, char *buf) \
-{ \
-	struct pc87360_data *data = pc87360_update_device(dev); \
-	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_max[offset-1])); \
-}\
-static ssize_t show_temp##offset##_crit(struct device *dev, char *buf) \
-{ \
-	struct pc87360_data *data = pc87360_update_device(dev); \
-	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_crit[offset-1])); \
-}\
-static ssize_t show_temp##offset##_status(struct device *dev, char *buf) \
-{ \
-	struct pc87360_data *data = pc87360_update_device(dev); \
-	return sprintf(buf, "%d\n", data->temp_status[offset-1]); \
-}\
-static ssize_t set_temp##offset##_min(struct device *dev, const char *buf, \
-	size_t count) \
-{ \
-	struct i2c_client *client = to_i2c_client(dev); \
-	struct pc87360_data *data = i2c_get_clientdata(client); \
-	long val = simple_strtol(buf, NULL, 10); \
- \
-	down(&data->update_lock); \
-	data->temp_min[offset-1] = TEMP_TO_REG(val); \
-	pc87360_write_value(data, LD_TEMP, offset-1, PC87365_REG_TEMP_MIN, \
-			    data->temp_min[offset-1]); \
-	up(&data->update_lock); \
-	return count; \
-} \
-static ssize_t set_temp##offset##_max(struct device *dev, const char *buf, \
-	size_t count) \
-{ \
-	struct i2c_client *client = to_i2c_client(dev); \
-	struct pc87360_data *data = i2c_get_clientdata(client); \
-	long val = simple_strtol(buf, NULL, 10); \
- \
-	down(&data->update_lock); \
-	data->temp_max[offset-1] = TEMP_TO_REG(val); \
-	pc87360_write_value(data, LD_TEMP, offset-1, PC87365_REG_TEMP_MAX, \
-			    data->temp_max[offset-1]); \
-	up(&data->update_lock); \
-	return count; \
-} \
-static ssize_t set_temp##offset##_crit(struct device *dev, const char *buf, \
-	size_t count) \
-{ \
-	struct i2c_client *client = to_i2c_client(dev); \
-	struct pc87360_data *data = i2c_get_clientdata(client); \
-	long val = simple_strtol(buf, NULL, 10); \
- \
-	down(&data->update_lock); \
-	data->temp_crit[offset-1] = TEMP_TO_REG(val); \
-	pc87360_write_value(data, LD_TEMP, offset-1, PC87365_REG_TEMP_CRIT, \
-			    data->temp_crit[offset-1]); \
-	up(&data->update_lock); \
-	return count; \
-} \
-static DEVICE_ATTR(temp##offset##_input, S_IRUGO, \
-	show_temp##offset##_input, NULL); \
-static DEVICE_ATTR(temp##offset##_min, S_IWUSR | S_IRUGO, \
-	show_temp##offset##_min, set_temp##offset##_min); \
-static DEVICE_ATTR(temp##offset##_max, S_IWUSR | S_IRUGO, \
-	show_temp##offset##_max, set_temp##offset##_max); \
-static DEVICE_ATTR(temp##offset##_crit, S_IWUSR | S_IRUGO, \
-	show_temp##offset##_crit, set_temp##offset##_crit); \
-static DEVICE_ATTR(temp##offset##_status, S_IRUGO, \
-	show_temp##offset##_status, NULL);
-show_and_set_temp(1)
-show_and_set_temp(2)
-show_and_set_temp(3)
-
-static ssize_t show_temp_alarms(struct device *dev, char *buf)
-{
-	struct pc87360_data *data = pc87360_update_device(dev);
-	return sprintf(buf, "%u\n", data->temp_alarms);
-}
-static DEVICE_ATTR(alarms_temp, S_IRUGO, show_temp_alarms, NULL);
-
-/*
- * Device detection, registration and update
- */
-
-static int pc87360_attach_adapter(struct i2c_adapter *adapter)
-{
-	return i2c_detect(adapter, &addr_data, pc87360_detect);
-}
-
-static int pc87360_find(int sioaddr, u8 *devid, int *address)
-{
-	u16 val;
-	int i;
-	int nrdev; /* logical device count */
-
-	/* No superio_enter */
-
-	/* Identify device */
-	val = superio_inb(sioaddr, DEVID);
-	switch (val) {
-	case 0xE1: /* PC87360 */
-	case 0xE8: /* PC87363 */
-	case 0xE4: /* PC87364 */
-		nrdev = 1;
-		break;
-	case 0xE5: /* PC87365 */
-	case 0xE9: /* PC87366 */
-		nrdev = 3;
-		break;
-	default:
-		superio_exit(sioaddr);
-		return -ENODEV;
-	}
-	/* Remember the device id */
-	*devid = val;
-
-	for (i = 0; i < nrdev; i++) {
-		/* select logical device */
-		superio_outb(sioaddr, DEV, logdev[i]);
-
-		val = superio_inb(sioaddr, ACT);
-		if (!(val & 0x01)) {
-			printk(KERN_INFO "pc87360: Device 0x%02x not "
-			       "activated\n", logdev[i]);
-			continue;
-		}
-
-		val = (superio_inb(sioaddr, BASE) << 8)
-		    | superio_inb(sioaddr, BASE + 1);
-		if (!val) {
-			printk(KERN_INFO "pc87360: Base address not set for "
-			       "device 0x%02x\n", logdev[i]);
-			continue;
-		}
-
-		address[i] = val;
-
-		if (i==0) { /* Fans */
-			confreg[0] = superio_inb(sioaddr, 0xF0);
-			confreg[1] = superio_inb(sioaddr, 0xF1);
-
-#ifdef DEBUG
-			printk(KERN_DEBUG "pc87360: Fan 1: mon=%d "
-			       "ctrl=%d inv=%d\n", (confreg[0]>>2)&1,
-			       (confreg[0]>>3)&1, (confreg[0]>>4)&1);
-			printk(KERN_DEBUG "pc87360: Fan 2: mon=%d "
-			       "ctrl=%d inv=%d\n", (confreg[0]>>5)&1,
-			       (confreg[0]>>6)&1, (confreg[0]>>7)&1);
-			printk(KERN_DEBUG "pc87360: Fan 3: mon=%d "
-			       "ctrl=%d inv=%d\n", confreg[1]&1,
-			       (confreg[1]>>1)&1, (confreg[1]>>2)&1);
-#endif
-		} else if (i==1) { /* Voltages */
-			/* Are we using thermistors? */
-			if (*devid == 0xE9) { /* PC87366 */
-				/* These registers are not logical-device
-				   specific, just that we won't need them if
-				   we don't use the VLM device */
-				confreg[2] = superio_inb(sioaddr, 0x2B);
-				confreg[3] = superio_inb(sioaddr, 0x25);
-
-				if (confreg[2] & 0x40) {
-					printk(KERN_INFO "pc87360: Using "
-					       "thermistors for temperature "
-					       "monitoring\n");
-				}
-				if (confreg[3] & 0xE0) {
-					printk(KERN_INFO "pc87360: VID "
-					       "inputs routed (mode %u)\n",
-					       confreg[3] >> 5);
-				}
-			}
-		}
-	}
-
-	superio_exit(sioaddr);
-	return 0;
-}
-
-/* We don't really care about the address.
-   Read from extra_isa instead. */
-int pc87360_detect(struct i2c_adapter *adapter, int address, int kind)
-{
-	int i;
-	struct i2c_client *new_client;
-	struct pc87360_data *data;
-	int err = 0;
-	const char *name = "pc87360";
-	int use_thermistors = 0;
-
-	if (!i2c_is_isa_adapter(adapter))
-		return -ENODEV;
-
-	if (!(data = kmalloc(sizeof(struct pc87360_data), GFP_KERNEL)))
-		return -ENOMEM;
-	memset(data, 0x00, sizeof(struct pc87360_data));
-
-	new_client = &data->client;
-	i2c_set_clientdata(new_client, data);
-	new_client->addr = address;
-	init_MUTEX(&data->lock);
-	new_client->adapter = adapter;
-	new_client->driver = &pc87360_driver;
-	new_client->flags = 0;
-
-	data->fannr = 2;
-	data->innr = 0;
-	data->tempnr = 0;
-
-	switch (devid) {
-	case 0xe8:
-		name = "pc87363";
-		break;
-	case 0xe4:
-		name = "pc87364";
-		data->fannr = 3;
-		break;
-	case 0xe5:
-		name = "pc87365";
-		data->fannr = extra_isa[0] ? 3 : 0;
-		data->innr = extra_isa[1] ? 11 : 0;
-		data->tempnr = extra_isa[2] ? 2 : 0;
-		break;
-	case 0xe9:
-		name = "pc87366";
-		data->fannr = extra_isa[0] ? 3 : 0;
-		data->innr = extra_isa[1] ? 14 : 0;
-		data->tempnr = extra_isa[2] ? 3 : 0;
-		break;
-	}
-
-	strcpy(new_client->name, name);
-	data->valid = 0;
-	init_MUTEX(&data->update_lock);
-
-	for (i = 0; i < 3; i++) {
-		if (((data->address[i] = extra_isa[i]))
-		 && !request_region(extra_isa[i], PC87360_EXTENT,
-		 		    pc87360_driver.name)) {
-			dev_err(&new_client->dev, "Region 0x%x-0x%x already "
-				"in use!\n", extra_isa[i],
-				extra_isa[i]+PC87360_EXTENT-1);
-			for (i--; i >= 0; i--)
-				release_region(extra_isa[i], PC87360_EXTENT);
-			err = -EBUSY;
-			goto ERROR1;
-		}
-	}
-
-	/* Retrieve the fans configuration from Super-I/O space */
-	if (data->fannr)
-		data->fan_conf = confreg[0] | (confreg[1] << 8);
-
-	if ((err = i2c_attach_client(new_client)))
-		goto ERROR2;
-
-	/* Use the correct reference voltage
-	   Unless both the VLM and the TMS logical devices agree to
-	   use an external Vref, the internal one is used. */
-	if (data->innr) {
-		i = pc87360_read_value(data, LD_IN, NO_BANK,
-				       PC87365_REG_IN_CONFIG);
-		if (data->tempnr) {
-			i &= pc87360_read_value(data, LD_TEMP, NO_BANK,
-						PC87365_REG_TEMP_CONFIG);
-		}
-		data->in_vref = (i&0x02) ? 3025 : 2966;
-		dev_dbg(&new_client->dev, "Using %s reference voltage\n",
-			(i&0x02) ? "external" : "internal");
-
-		data->vid_conf = confreg[3];
-		data->vrm = 90;
-	}
-
-	/* Fan clock dividers may be needed before any data is read */
-	for (i = 0; i < data->fannr; i++) {
-		if (FAN_CONFIG_MONITOR(data->fan_conf, i))
-			data->fan_status[i] = pc87360_read_value(data,
-					      LD_FAN, NO_BANK,
-					      PC87360_REG_FAN_STATUS(i));
-	}
-
-	if (init > 0) {
-		if (devid == 0xe9 && data->address[1]) /* PC87366 */
-			use_thermistors = confreg[2] & 0x40;
-
-		pc87360_init_client(new_client, use_thermistors);
-	}
-
-	/* Register sysfs hooks */
-	if (data->innr) {
-		device_create_file(&new_client->dev, &dev_attr_in0_input);
-		device_create_file(&new_client->dev, &dev_attr_in1_input);
-		device_create_file(&new_client->dev, &dev_attr_in2_input);
-		device_create_file(&new_client->dev, &dev_attr_in3_input);
-		device_create_file(&new_client->dev, &dev_attr_in4_input);
-		device_create_file(&new_client->dev, &dev_attr_in5_input);
-		device_create_file(&new_client->dev, &dev_attr_in6_input);
-		device_create_file(&new_client->dev, &dev_attr_in7_input);
-		device_create_file(&new_client->dev, &dev_attr_in8_input);
-		device_create_file(&new_client->dev, &dev_attr_in9_input);
-		device_create_file(&new_client->dev, &dev_attr_in10_input);
-		device_create_file(&new_client->dev, &dev_attr_in0_min);
-		device_create_file(&new_client->dev, &dev_attr_in1_min);
-		device_create_file(&new_client->dev, &dev_attr_in2_min);
-		device_create_file(&new_client->dev, &dev_attr_in3_min);
-		device_create_file(&new_client->dev, &dev_attr_in4_min);
-		device_create_file(&new_client->dev, &dev_attr_in5_min);
-		device_create_file(&new_client->dev, &dev_attr_in6_min);
-		device_create_file(&new_client->dev, &dev_attr_in7_min);
-		device_create_file(&new_client->dev, &dev_attr_in8_min);
-		device_create_file(&new_client->dev, &dev_attr_in9_min);
-		device_create_file(&new_client->dev, &dev_attr_in10_min);
-		device_create_file(&new_client->dev, &dev_attr_in0_max);
-		device_create_file(&new_client->dev, &dev_attr_in1_max);
-		device_create_file(&new_client->dev, &dev_attr_in2_max);
-		device_create_file(&new_client->dev, &dev_attr_in3_max);
-		device_create_file(&new_client->dev, &dev_attr_in4_max);
-		device_create_file(&new_client->dev, &dev_attr_in5_max);
-		device_create_file(&new_client->dev, &dev_attr_in6_max);
-		device_create_file(&new_client->dev, &dev_attr_in7_max);
-		device_create_file(&new_client->dev, &dev_attr_in8_max);
-		device_create_file(&new_client->dev, &dev_attr_in9_max);
-		device_create_file(&new_client->dev, &dev_attr_in10_max);
-		device_create_file(&new_client->dev, &dev_attr_in0_status);
-		device_create_file(&new_client->dev, &dev_attr_in1_status);
-		device_create_file(&new_client->dev, &dev_attr_in2_status);
-		device_create_file(&new_client->dev, &dev_attr_in3_status);
-		device_create_file(&new_client->dev, &dev_attr_in4_status);
-		device_create_file(&new_client->dev, &dev_attr_in5_status);
-		device_create_file(&new_client->dev, &dev_attr_in6_status);
-		device_create_file(&new_client->dev, &dev_attr_in7_status);
-		device_create_file(&new_client->dev, &dev_attr_in8_status);
-		device_create_file(&new_client->dev, &dev_attr_in9_status);
-		device_create_file(&new_client->dev, &dev_attr_in10_status);
-
-		device_create_file(&new_client->dev, &dev_attr_cpu0_vid);
-		device_create_file(&new_client->dev, &dev_attr_vrm);
-		device_create_file(&new_client->dev, &dev_attr_alarms_in);
-	}
-
-	if (data->tempnr) {
-		device_create_file(&new_client->dev, &dev_attr_temp1_input);
-		device_create_file(&new_client->dev, &dev_attr_temp2_input);
-		device_create_file(&new_client->dev, &dev_attr_temp1_min);
-		device_create_file(&new_client->dev, &dev_attr_temp2_min);
-		device_create_file(&new_client->dev, &dev_attr_temp1_max);
-		device_create_file(&new_client->dev, &dev_attr_temp2_max);
-		device_create_file(&new_client->dev, &dev_attr_temp1_crit);
-		device_create_file(&new_client->dev, &dev_attr_temp2_crit);
-		device_create_file(&new_client->dev, &dev_attr_temp1_status);
-		device_create_file(&new_client->dev, &dev_attr_temp2_status);
-
-		device_create_file(&new_client->dev, &dev_attr_alarms_temp);
-	}
-	if (data->tempnr == 3) {
-		device_create_file(&new_client->dev, &dev_attr_temp3_input);
-		device_create_file(&new_client->dev, &dev_attr_temp3_min);
-		device_create_file(&new_client->dev, &dev_attr_temp3_max);
-		device_create_file(&new_client->dev, &dev_attr_temp3_crit);
-		device_create_file(&new_client->dev, &dev_attr_temp3_status);
-	}
-	if (data->innr == 14) {
-		device_create_file(&new_client->dev, &dev_attr_temp4_input);
-		device_create_file(&new_client->dev, &dev_attr_temp5_input);
-		device_create_file(&new_client->dev, &dev_attr_temp6_input);
-		device_create_file(&new_client->dev, &dev_attr_temp4_min);
-		device_create_file(&new_client->dev, &dev_attr_temp5_min);
-		device_create_file(&new_client->dev, &dev_attr_temp6_min);
-		device_create_file(&new_client->dev, &dev_attr_temp4_max);
-		device_create_file(&new_client->dev, &dev_attr_temp5_max);
-		device_create_file(&new_client->dev, &dev_attr_temp6_max);
-		device_create_file(&new_client->dev, &dev_attr_temp4_crit);
-		device_create_file(&new_client->dev, &dev_attr_temp5_crit);
-		device_create_file(&new_client->dev, &dev_attr_temp6_crit);
-		device_create_file(&new_client->dev, &dev_attr_temp4_status);
-		device_create_file(&new_client->dev, &dev_attr_temp5_status);
-		device_create_file(&new_client->dev, &dev_attr_temp6_status);
-	}
-
-	if (data->fannr) {
-		if (FAN_CONFIG_MONITOR(data->fan_conf, 0)) {
-			device_create_file(&new_client->dev,
-					   &dev_attr_fan1_input);
-			device_create_file(&new_client->dev,
-					   &dev_attr_fan1_min);
-			device_create_file(&new_client->dev,
-					   &dev_attr_fan1_div);
-			device_create_file(&new_client->dev,
-					   &dev_attr_fan1_status);
-		}
-
-		if (FAN_CONFIG_MONITOR(data->fan_conf, 1)) {
-			device_create_file(&new_client->dev,
-					   &dev_attr_fan2_input);
-			device_create_file(&new_client->dev,
-					   &dev_attr_fan2_min);
-			device_create_file(&new_client->dev,
-					   &dev_attr_fan2_div);
-			device_create_file(&new_client->dev,
-					   &dev_attr_fan2_status);
-		}
-
-		if (FAN_CONFIG_CONTROL(data->fan_conf, 0))
-			device_create_file(&new_client->dev, &dev_attr_pwm1);
-		if (FAN_CONFIG_CONTROL(data->fan_conf, 1))
-			device_create_file(&new_client->dev, &dev_attr_pwm2);
-	}
-	if (data->fannr == 3) {
-		if (FAN_CONFIG_MONITOR(data->fan_conf, 2)) {
-			device_create_file(&new_client->dev,
-					   &dev_attr_fan3_input);
-			device_create_file(&new_client->dev,
-					   &dev_attr_fan3_min);
-			device_create_file(&new_client->dev,
-					   &dev_attr_fan3_div);
-			device_create_file(&new_client->dev,
-					   &dev_attr_fan3_status);
-		}
-
-		if (FAN_CONFIG_CONTROL(data->fan_conf, 2))
-			device_create_file(&new_client->dev, &dev_attr_pwm3);
-	}
-
-	return 0;
-
-ERROR2:
-	for (i = 0; i < 3; i++) {
-		if (data->address[i]) {
-			release_region(data->address[i], PC87360_EXTENT);
-		}
-	}
-ERROR1:
-	kfree(data);
-	return err;
-}
-
-static int pc87360_detach_client(struct i2c_client *client)
-{
-	struct pc87360_data *data = i2c_get_clientdata(client);
-	int i;
-
-	if ((i = i2c_detach_client(client))) {
-		dev_err(&client->dev, "Client deregistration failed, "
-			"client not detached.\n");
-		return i;
-	}
-
-	for (i = 0; i < 3; i++) {
-		if (data->address[i]) {
-			release_region(data->address[i], PC87360_EXTENT);
-		}
-	}
-	kfree(data);
-
-	return 0;
-}
-
-/* ldi is the logical device index
-   bank is for voltages and temperatures only */
-static int pc87360_read_value(struct pc87360_data *data, u8 ldi, u8 bank,
-			      u8 reg)
-{
-	int res;
-
-	down(&(data->lock));
-	if (bank != NO_BANK)
-		outb_p(bank, data->address[ldi] + PC87365_REG_BANK);
-	res = inb_p(data->address[ldi] + reg);
-	up(&(data->lock));
-
-	return res;
-}
-
-static void pc87360_write_value(struct pc87360_data *data, u8 ldi, u8 bank,
-				u8 reg, u8 value)
-{
-	down(&(data->lock));
-	if (bank != NO_BANK)
-		outb_p(bank, data->address[ldi] + PC87365_REG_BANK);
-	outb_p(value, data->address[ldi] + reg);
-	up(&(data->lock));
-}
-
-static void pc87360_init_client(struct i2c_client *client, int use_thermistors)
-{
-	struct pc87360_data *data = i2c_get_clientdata(client);
-	int i, nr;
-	const u8 init_in[14] = { 2, 2, 2, 2, 2, 2, 2, 1, 1, 3, 1, 2, 2, 2 };
-	const u8 init_temp[3] = { 2, 2, 1 };
-	u8 reg;
-
-	if (init >= 2 && data->innr) {
-		reg = pc87360_read_value(data, LD_IN, NO_BANK,
-					 PC87365_REG_IN_CONVRATE);
-		dev_info(&client->dev, "VLM conversion set to"
-			 "1s period, 160us delay\n");
-		pc87360_write_value(data, LD_IN, NO_BANK,
-				    PC87365_REG_IN_CONVRATE,
-				    (reg & 0xC0) | 0x11);
-	}
-
-	nr = data->innr < 11 ? data->innr : 11;
-	for (i=0; i<nr; i++) {
-		if (init >= init_in[i]) {
-			/* Forcibly enable voltage channel */
-			reg = pc87360_read_value(data, LD_IN, i,
-						 PC87365_REG_IN_STATUS);
-			if (!(reg & 0x01)) {
-				dev_dbg(&client->dev, "Forcibly "
-					"enabling in%d\n", i);
-				pc87360_write_value(data, LD_IN, i,
-						    PC87365_REG_IN_STATUS,
-						    (reg & 0x68) | 0x87);
-			}
-		}
-	}
-
-	/* We can't blindly trust the Super-I/O space configuration bit,
-	   most BIOS won't set it properly */
-	for (i=11; i<data->innr; i++) {
-		reg = pc87360_read_value(data, LD_IN, i,
-					 PC87365_REG_TEMP_STATUS);
-		use_thermistors = use_thermistors || (reg & 0x01);
-	}
-
-	i = use_thermistors ? 2 : 0;
-	for (; i<data->tempnr; i++) {
-		if (init >= init_temp[i]) {
-			/* Forcibly enable temperature channel */
-			reg = pc87360_read_value(data, LD_TEMP, i,
-						 PC87365_REG_TEMP_STATUS);
-			if (!(reg & 0x01)) {
-				dev_dbg(&client->dev, "Forcibly "
-					"enabling temp%d\n", i+1);
-				pc87360_write_value(data, LD_TEMP, i,
-						    PC87365_REG_TEMP_STATUS,
-						    0xCF);
-			}
-		}
-	}
-
-	if (use_thermistors) {
-		for (i=11; i<data->innr; i++) {
-			if (init >= init_in[i]) {
-				/* The pin may already be used by thermal
-				   diodes */
-				reg = pc87360_read_value(data, LD_TEMP,
-				      (i-11)/2, PC87365_REG_TEMP_STATUS);
-				if (reg & 0x01) {
-					dev_dbg(&client->dev, "Skipping "
-						"temp%d, pin already in use "
-						"by temp%d\n", i-7, (i-11)/2);
-					continue;
-				}
-
-				/* Forcibly enable thermistor channel */
-				reg = pc87360_read_value(data, LD_IN, i,
-							 PC87365_REG_IN_STATUS);
-				if (!(reg & 0x01)) {
-					dev_dbg(&client->dev, "Forcibly "
-						"enabling temp%d\n", i-7);
-					pc87360_write_value(data, LD_IN, i,
-						PC87365_REG_TEMP_STATUS,
-						(reg & 0x60) | 0x8F);
-				}
-			}
-		}
-	}
-
-	if (data->innr) {
-		reg = pc87360_read_value(data, LD_IN, NO_BANK,
-					 PC87365_REG_IN_CONFIG);
-		if (reg & 0x01) {
-			dev_dbg(&client->dev, "Forcibly "
-				"enabling monitoring (VLM)\n");
-			pc87360_write_value(data, LD_IN, NO_BANK,
-					    PC87365_REG_IN_CONFIG,
-					    reg & 0xFE);
-		}
-	}
-
-	if (data->tempnr) {
-		reg = pc87360_read_value(data, LD_TEMP, NO_BANK,
-					 PC87365_REG_TEMP_CONFIG);
-		if (reg & 0x01) {
-			dev_dbg(&client->dev, "Forcibly enabling "
-				"monitoring (TMS)\n");
-			pc87360_write_value(data, LD_TEMP, NO_BANK,
-					    PC87365_REG_TEMP_CONFIG,
-					    reg & 0xFE);
-		}
-
-		if (init >= 2) {
-			/* Chip config as documented by National Semi. */
-			pc87360_write_value(data, LD_TEMP, 0xF, 0xA, 0x08);
-			/* We voluntarily omit the bank here, in case the
-			   sequence itself matters. It shouldn't be a problem,
-			   since nobody else is supposed to access the
-			   device at that point. */
-			pc87360_write_value(data, LD_TEMP, NO_BANK, 0xB, 0x04);
-			pc87360_write_value(data, LD_TEMP, NO_BANK, 0xC, 0x35);
-			pc87360_write_value(data, LD_TEMP, NO_BANK, 0xD, 0x05);
-			pc87360_write_value(data, LD_TEMP, NO_BANK, 0xE, 0x05);
-		}
-	}
-}
-
-static void pc87360_autodiv(struct i2c_client *client, int nr)
-{
-	struct pc87360_data *data = i2c_get_clientdata(client);
-	u8 old_min = data->fan_min[nr];
-
-	/* Increase clock divider if needed and possible */
-	if ((data->fan_status[nr] & 0x04) /* overflow flag */
-	 || (data->fan[nr] >= 224)) { /* next to overflow */
-		if ((data->fan_status[nr] & 0x60) != 0x60) {
-			data->fan_status[nr] += 0x20;
-			data->fan_min[nr] >>= 1;
-			data->fan[nr] >>= 1;
-			dev_dbg(&client->dev, "Increasing "
-				"clock divider to %d for fan %d\n",
-				FAN_DIV_FROM_REG(data->fan_status[nr]), nr+1);
-		}
-	} else {
-		/* Decrease clock divider if possible */
-		while (!(data->fan_min[nr] & 0x80) /* min "nails" divider */
-		 && data->fan[nr] < 85 /* bad accuracy */
-		 && (data->fan_status[nr] & 0x60) != 0x00) {
-			data->fan_status[nr] -= 0x20;
-			data->fan_min[nr] <<= 1;
-			data->fan[nr] <<= 1;
-			dev_dbg(&client->dev, "Decreasing "
-				"clock divider to %d for fan %d\n",
-				FAN_DIV_FROM_REG(data->fan_status[nr]),
-				nr+1);
-		}
-	}
-
-	/* Write new fan min if it changed */
-	if (old_min != data->fan_min[nr]) {
-		pc87360_write_value(data, LD_FAN, NO_BANK,
-				    PC87360_REG_FAN_MIN(nr),
-				    data->fan_min[nr]);
-	}
-}
-
-static struct pc87360_data *pc87360_update_device(struct device *dev)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct pc87360_data *data = i2c_get_clientdata(client);
-	u8 i;
-
-	down(&data->update_lock);
-
-	if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) {
-		dev_dbg(&client->dev, "Data update\n");
-
-		/* Fans */
-		for (i = 0; i < data->fannr; i++) {
-			if (FAN_CONFIG_MONITOR(data->fan_conf, i)) {
-				data->fan_status[i] =
-					pc87360_read_value(data, LD_FAN,
-					NO_BANK, PC87360_REG_FAN_STATUS(i));
-				data->fan[i] = pc87360_read_value(data, LD_FAN,
-					       NO_BANK, PC87360_REG_FAN(i));
-				data->fan_min[i] = pc87360_read_value(data,
-						   LD_FAN, NO_BANK,
-						   PC87360_REG_FAN_MIN(i));
-				/* Change clock divider if needed */
-				pc87360_autodiv(client, i);
-				/* Clear bits and write new divider */
-				pc87360_write_value(data, LD_FAN, NO_BANK,
-						    PC87360_REG_FAN_STATUS(i),
-						    data->fan_status[i]);
-			}
-			if (FAN_CONFIG_CONTROL(data->fan_conf, i))
-				data->pwm[i] = pc87360_read_value(data, LD_FAN,
-					       NO_BANK, PC87360_REG_PWM(i));
-		}
-
-		/* Voltages */
-		for (i = 0; i < data->innr; i++) {
-			data->in_status[i] = pc87360_read_value(data, LD_IN, i,
-					     PC87365_REG_IN_STATUS);
-			/* Clear bits */
-			pc87360_write_value(data, LD_IN, i,
-					    PC87365_REG_IN_STATUS,
-					    data->in_status[i]);
-			if ((data->in_status[i] & 0x81) == 0x81) {
-				data->in[i] = pc87360_read_value(data, LD_IN,
-					      i, PC87365_REG_IN);
-			}
-			if (data->in_status[i] & 0x01) {
-				data->in_min[i] = pc87360_read_value(data,
-						  LD_IN, i,
-						  PC87365_REG_IN_MIN);
-				data->in_max[i] = pc87360_read_value(data,
-						  LD_IN, i,
-						  PC87365_REG_IN_MAX);
-				if (i >= 11)
-					data->in_crit[i-11] =
-						pc87360_read_value(data, LD_IN,
-						i, PC87365_REG_TEMP_CRIT);
-			}
-		}
-		if (data->innr) {
-			data->in_alarms = pc87360_read_value(data, LD_IN,
-					  NO_BANK, PC87365_REG_IN_ALARMS1)
-					| ((pc87360_read_value(data, LD_IN,
-					    NO_BANK, PC87365_REG_IN_ALARMS2)
-					    & 0x07) << 8);
-			data->vid = (data->vid_conf & 0xE0) ?
-				    pc87360_read_value(data, LD_IN,
-				    NO_BANK, PC87365_REG_VID) : 0x1F;
-		}
-
-		/* Temperatures */
-		for (i = 0; i < data->tempnr; i++) {
-			data->temp_status[i] = pc87360_read_value(data,
-					       LD_TEMP, i,
-					       PC87365_REG_TEMP_STATUS);
-			/* Clear bits */
-			pc87360_write_value(data, LD_TEMP, i,
-					    PC87365_REG_TEMP_STATUS,
-					    data->temp_status[i]);
-			if ((data->temp_status[i] & 0x81) == 0x81) {
-				data->temp[i] = pc87360_read_value(data,
-						LD_TEMP, i,
-						PC87365_REG_TEMP);
-			}
-			if (data->temp_status[i] & 0x01) {
-				data->temp_min[i] = pc87360_read_value(data,
-						    LD_TEMP, i,
-						    PC87365_REG_TEMP_MIN);
-				data->temp_max[i] = pc87360_read_value(data,
-						    LD_TEMP, i,
-						    PC87365_REG_TEMP_MAX);
-				data->temp_crit[i] = pc87360_read_value(data,
-						     LD_TEMP, i,
-						     PC87365_REG_TEMP_CRIT);
-			}
-		}
-		if (data->tempnr) {
-			data->temp_alarms = pc87360_read_value(data, LD_TEMP,
-					    NO_BANK, PC87365_REG_TEMP_ALARMS)
-					    & 0x3F;
-		}
-
-		data->last_updated = jiffies;
-		data->valid = 1;
-	}
-
-	up(&data->update_lock);
-
-	return data;
-}
-
-static int __init pc87360_init(void)
-{
-	int i;
-
-	if (pc87360_find(0x2e, &devid, extra_isa)
-	 && pc87360_find(0x4e, &devid, extra_isa)) {
-		printk(KERN_WARNING "pc87360: PC8736x not detected, "
-		       "module not inserted.\n");
-		return -ENODEV;
-	}
-
-	/* Arbitrarily pick one of the addresses */
-	for (i = 0; i < 3; i++) {
-		if (extra_isa[i] != 0x0000) {
-			normal_isa[0] = extra_isa[i];
-			break;
-		}
-	}
-
-	if (normal_isa[0] == 0x0000) {
-		printk(KERN_WARNING "pc87360: No active logical device, "
-		       "module not inserted.\n");
-		return -ENODEV;
-	}
-
-	return i2c_add_driver(&pc87360_driver);
-}
-
-static void __exit pc87360_exit(void)
-{
-	i2c_del_driver(&pc87360_driver);
-}
-
-
-MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>");
-MODULE_DESCRIPTION("PC8736x hardware monitor");
-MODULE_LICENSE("GPL");
-
-module_init(pc87360_init);
-module_exit(pc87360_exit);
diff --git a/drivers/i2c/chips/pca9539.c b/drivers/i2c/chips/pca9539.c
new file mode 100644
--- /dev/null
+++ b/drivers/i2c/chips/pca9539.c
@@ -0,0 +1,192 @@
+/*
+    pca9539.c - 16-bit I/O port with interrupt and reset
+
+    Copyright (C) 2005 Ben Gardner <bgardner@wabtec.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; version 2 of the License.
+*/
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/i2c-sensor.h>
+
+/* Addresses to scan */
+static unsigned short normal_i2c[] = {0x74, 0x75, 0x76, 0x77, I2C_CLIENT_END};
+static unsigned int normal_isa[] = {I2C_CLIENT_ISA_END};
+
+/* Insmod parameters */
+SENSORS_INSMOD_1(pca9539);
+
+enum pca9539_cmd
+{
+	PCA9539_INPUT_0		= 0,
+	PCA9539_INPUT_1		= 1,
+	PCA9539_OUTPUT_0	= 2,
+	PCA9539_OUTPUT_1	= 3,
+	PCA9539_INVERT_0	= 4,
+	PCA9539_INVERT_1	= 5,
+	PCA9539_DIRECTION_0	= 6,
+	PCA9539_DIRECTION_1	= 7,
+};
+
+static int pca9539_attach_adapter(struct i2c_adapter *adapter);
+static int pca9539_detect(struct i2c_adapter *adapter, int address, int kind);
+static int pca9539_detach_client(struct i2c_client *client);
+
+/* This is the driver that will be inserted */
+static struct i2c_driver pca9539_driver = {
+	.owner		= THIS_MODULE,
+	.name		= "pca9539",
+	.flags		= I2C_DF_NOTIFY,
+	.attach_adapter	= pca9539_attach_adapter,
+	.detach_client	= pca9539_detach_client,
+};
+
+struct pca9539_data {
+	struct i2c_client client;
+};
+
+/* following are the sysfs callback functions */
+static ssize_t pca9539_show(struct device *dev, struct device_attribute *attr,
+			    char *buf)
+{
+	struct sensor_device_attribute *psa = to_sensor_dev_attr(attr);
+	struct i2c_client *client = to_i2c_client(dev);
+	return sprintf(buf, "%d\n", i2c_smbus_read_byte_data(client,
+							     psa->index));
+}
+
+static ssize_t pca9539_store(struct device *dev, struct device_attribute *attr,
+			     const char *buf, size_t count)
+{
+	struct sensor_device_attribute *psa = to_sensor_dev_attr(attr);
+	struct i2c_client *client = to_i2c_client(dev);
+	unsigned long val = simple_strtoul(buf, NULL, 0);
+	if (val > 0xff)
+		return -EINVAL;
+	i2c_smbus_write_byte_data(client, psa->index, val);
+	return count;
+}
+
+/* Define the device attributes */
+
+#define PCA9539_ENTRY_RO(name, cmd_idx) \
+	static SENSOR_DEVICE_ATTR(name, S_IRUGO, pca9539_show, NULL, cmd_idx)
+
+#define PCA9539_ENTRY_RW(name, cmd_idx) \
+	static SENSOR_DEVICE_ATTR(name, S_IRUGO | S_IWUSR, pca9539_show, \
+				  pca9539_store, cmd_idx)
+
+PCA9539_ENTRY_RO(input0, PCA9539_INPUT_0);
+PCA9539_ENTRY_RO(input1, PCA9539_INPUT_1);
+PCA9539_ENTRY_RW(output0, PCA9539_OUTPUT_0);
+PCA9539_ENTRY_RW(output1, PCA9539_OUTPUT_1);
+PCA9539_ENTRY_RW(invert0, PCA9539_INVERT_0);
+PCA9539_ENTRY_RW(invert1, PCA9539_INVERT_1);
+PCA9539_ENTRY_RW(direction0, PCA9539_DIRECTION_0);
+PCA9539_ENTRY_RW(direction1, PCA9539_DIRECTION_1);
+
+static struct attribute *pca9539_attributes[] = {
+	&sensor_dev_attr_input0.dev_attr.attr,
+	&sensor_dev_attr_input1.dev_attr.attr,
+	&sensor_dev_attr_output0.dev_attr.attr,
+	&sensor_dev_attr_output1.dev_attr.attr,
+	&sensor_dev_attr_invert0.dev_attr.attr,
+	&sensor_dev_attr_invert1.dev_attr.attr,
+	&sensor_dev_attr_direction0.dev_attr.attr,
+	&sensor_dev_attr_direction1.dev_attr.attr,
+	NULL
+};
+
+static struct attribute_group pca9539_defattr_group = {
+	.attrs = pca9539_attributes,
+};
+
+static int pca9539_attach_adapter(struct i2c_adapter *adapter)
+{
+	return i2c_detect(adapter, &addr_data, pca9539_detect);
+}
+
+/* This function is called by i2c_detect */
+static int pca9539_detect(struct i2c_adapter *adapter, int address, int kind)
+{
+	struct i2c_client *new_client;
+	struct pca9539_data *data;
+	int err = 0;
+
+	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+		goto exit;
+
+	/* OK. For now, we presume we have a valid client. We now create the
+	   client structure, even though we cannot fill it completely yet. */
+	if (!(data = kmalloc(sizeof(struct pca9539_data), GFP_KERNEL))) {
+		err = -ENOMEM;
+		goto exit;
+	}
+	memset(data, 0, sizeof(struct pca9539_data));
+
+	new_client = &data->client;
+	i2c_set_clientdata(new_client, data);
+	new_client->addr = address;
+	new_client->adapter = adapter;
+	new_client->driver = &pca9539_driver;
+	new_client->flags = 0;
+
+	/* Detection: the pca9539 only has 8 registers (0-7).
+	   A read of 7 should succeed, but a read of 8 should fail. */
+	if ((i2c_smbus_read_byte_data(new_client, 7) < 0) ||
+	    (i2c_smbus_read_byte_data(new_client, 8) >= 0))
+		goto exit_kfree;
+
+	strlcpy(new_client->name, "pca9539", I2C_NAME_SIZE);
+
+	/* Tell the I2C layer a new client has arrived */
+	if ((err = i2c_attach_client(new_client)))
+		goto exit_kfree;
+
+	/* Register sysfs hooks (don't care about failure) */
+	sysfs_create_group(&new_client->dev.kobj, &pca9539_defattr_group);
+
+	return 0;
+
+exit_kfree:
+	kfree(data);
+exit:
+	return err;
+}
+
+static int pca9539_detach_client(struct i2c_client *client)
+{
+	int err;
+
+	if ((err = i2c_detach_client(client))) {
+		dev_err(&client->dev, "Client deregistration failed.\n");
+		return err;
+	}
+
+	kfree(i2c_get_clientdata(client));
+	return 0;
+}
+
+static int __init pca9539_init(void)
+{
+	return i2c_add_driver(&pca9539_driver);
+}
+
+static void __exit pca9539_exit(void)
+{
+	i2c_del_driver(&pca9539_driver);
+}
+
+MODULE_AUTHOR("Ben Gardner <bgardner@wabtec.com>");
+MODULE_DESCRIPTION("PCA9539 driver");
+MODULE_LICENSE("GPL");
+
+module_init(pca9539_init);
+module_exit(pca9539_exit);
+
diff --git a/drivers/i2c/chips/pcf8574.c b/drivers/i2c/chips/pcf8574.c
--- a/drivers/i2c/chips/pcf8574.c
+++ b/drivers/i2c/chips/pcf8574.c
@@ -57,7 +57,7 @@ SENSORS_INSMOD_2(pcf8574, pcf8574a);
 struct pcf8574_data {
 	struct i2c_client client;
 
-	u8 read, write;			/* Register values */
+	u8 write;			/* Remember last written value */
 };
 
 static int pcf8574_attach_adapter(struct i2c_adapter *adapter);
@@ -76,23 +76,21 @@ static struct i2c_driver pcf8574_driver 
 };
 
 /* following are the sysfs callback functions */
-static ssize_t show_read(struct device *dev, char *buf)
+static ssize_t show_read(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct i2c_client *client = to_i2c_client(dev);
-	struct pcf8574_data *data = i2c_get_clientdata(client);
-	data->read = i2c_smbus_read_byte(client); 
-	return sprintf(buf, "%u\n", data->read);
+	return sprintf(buf, "%u\n", i2c_smbus_read_byte(client));
 }
 
 static DEVICE_ATTR(read, S_IRUGO, show_read, NULL);
 
-static ssize_t show_write(struct device *dev, char *buf)
+static ssize_t show_write(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct pcf8574_data *data = i2c_get_clientdata(to_i2c_client(dev));
 	return sprintf(buf, "%u\n", data->write);
 }
 
-static ssize_t set_write(struct device *dev, const char *buf,
+static ssize_t set_write(struct device *dev, struct device_attribute *attr, const char *buf,
 			 size_t count)
 {
 	struct i2c_client *client = to_i2c_client(dev);
diff --git a/drivers/i2c/chips/pcf8591.c b/drivers/i2c/chips/pcf8591.c
--- a/drivers/i2c/chips/pcf8591.c
+++ b/drivers/i2c/chips/pcf8591.c
@@ -100,7 +100,7 @@ static struct i2c_driver pcf8591_driver 
 
 /* following are the sysfs callback functions */
 #define show_in_channel(channel)					\
-static ssize_t show_in##channel##_input(struct device *dev, char *buf)	\
+static ssize_t show_in##channel##_input(struct device *dev, struct device_attribute *attr, char *buf)	\
 {									\
 	return sprintf(buf, "%d\n", pcf8591_read_channel(dev, channel));\
 }									\
@@ -112,13 +112,13 @@ show_in_channel(1);
 show_in_channel(2);
 show_in_channel(3);
 
-static ssize_t show_out0_ouput(struct device *dev, char *buf)
+static ssize_t show_out0_ouput(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct pcf8591_data *data = i2c_get_clientdata(to_i2c_client(dev));
 	return sprintf(buf, "%d\n", data->aout * 10);
 }
 
-static ssize_t set_out0_output(struct device *dev, const char *buf, size_t count)
+static ssize_t set_out0_output(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	unsigned int value;
 	struct i2c_client *client = to_i2c_client(dev);
@@ -134,13 +134,13 @@ static ssize_t set_out0_output(struct de
 static DEVICE_ATTR(out0_output, S_IWUSR | S_IRUGO, 
 		   show_out0_ouput, set_out0_output);
 
-static ssize_t show_out0_enable(struct device *dev, char *buf)
+static ssize_t show_out0_enable(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct pcf8591_data *data = i2c_get_clientdata(to_i2c_client(dev));
 	return sprintf(buf, "%u\n", !(!(data->control & PCF8591_CONTROL_AOEF)));
 }
 
-static ssize_t set_out0_enable(struct device *dev, const char *buf, size_t count)
+static ssize_t set_out0_enable(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	struct pcf8591_data *data = i2c_get_clientdata(client);
diff --git a/drivers/i2c/chips/rtc8564.c b/drivers/i2c/chips/rtc8564.c
--- a/drivers/i2c/chips/rtc8564.c
+++ b/drivers/i2c/chips/rtc8564.c
@@ -19,7 +19,6 @@
 #include <linux/string.h>
 #include <linux/rtc.h>		/* get the user-level API */
 #include <linux/init.h>
-#include <linux/init.h>
 
 #include "rtc8564.h"
 
@@ -66,11 +65,8 @@ static unsigned short normal_addr[] = { 
 
 static struct i2c_client_address_data addr_data = {
 	.normal_i2c		= normal_addr,
-	.normal_i2c_range	= ignore,
 	.probe			= ignore,
-	.probe_range		= ignore,
 	.ignore			= ignore,
-	.ignore_range		= ignore,
 	.force			= ignore,
 };
 
diff --git a/drivers/i2c/chips/sis5595.c b/drivers/i2c/chips/sis5595.c
deleted file mode 100644
--- a/drivers/i2c/chips/sis5595.c
+++ /dev/null
@@ -1,816 +0,0 @@
-/*
-    sis5595.c - Part of lm_sensors, Linux kernel modules
-		for hardware monitoring
-
-    Copyright (C) 1998 - 2001 Frodo Looijaard <frodol@dds.nl>,
-			Kyösti Mälkki <kmalkki@cc.hut.fi>, and
-			Mark D. Studebaker <mdsxyz123@yahoo.com>
-    Ported to Linux 2.6 by Aurelien Jarno <aurelien@aurel32.net> with
-    the help of Jean Delvare <khali@linux-fr.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.
-*/
-
-/*
-   SiS southbridge has a LM78-like chip integrated on the same IC.
-   This driver is a customized copy of lm78.c
-   
-   Supports following revisions:
-	Version		PCI ID		PCI Revision
-	1		1039/0008	AF or less
-	2		1039/0008	B0 or greater
-
-   Note: these chips contain a 0008 device which is incompatible with the
-	 5595. We recognize these by the presence of the listed
-	 "blacklist" PCI ID and refuse to load.
-
-   NOT SUPPORTED	PCI ID		BLACKLIST PCI ID	
-	 540		0008		0540
-	 550		0008		0550
-	5513		0008		5511
-	5581		0008		5597
-	5582		0008		5597
-	5597		0008		5597
-	5598		0008		5597/5598
-	 630		0008		0630
-	 645		0008		0645
-	 730		0008		0730
-	 735		0008		0735
-*/
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/ioport.h>
-#include <linux/pci.h>
-#include <linux/i2c.h>
-#include <linux/i2c-sensor.h>
-#include <linux/init.h>
-#include <asm/io.h>
-
-
-/* If force_addr is set to anything different from 0, we forcibly enable
-   the device at the given address. */
-static u16 force_addr;
-module_param(force_addr, ushort, 0);
-MODULE_PARM_DESC(force_addr,
-		 "Initialize the base address of the sensors");
-
-/* Addresses to scan.
-   Note that we can't determine the ISA address until we have initialized
-   our module */
-static unsigned short normal_i2c[] = { I2C_CLIENT_END };
-static unsigned int normal_isa[] = { 0x0000, I2C_CLIENT_ISA_END };
-
-/* Insmod parameters */
-SENSORS_INSMOD_1(sis5595);
-
-/* Many SIS5595 constants specified below */
-
-/* Length of ISA address segment */
-#define SIS5595_EXTENT 8
-/* PCI Config Registers */
-#define SIS5595_REVISION_REG 0x08
-#define SIS5595_BASE_REG 0x68
-#define SIS5595_PIN_REG 0x7A
-#define SIS5595_ENABLE_REG 0x7B
-
-/* Where are the ISA address/data registers relative to the base address */
-#define SIS5595_ADDR_REG_OFFSET 5
-#define SIS5595_DATA_REG_OFFSET 6
-
-/* The SIS5595 registers */
-#define SIS5595_REG_IN_MAX(nr) (0x2b + (nr) * 2)
-#define SIS5595_REG_IN_MIN(nr) (0x2c + (nr) * 2)
-#define SIS5595_REG_IN(nr) (0x20 + (nr))
-
-#define SIS5595_REG_FAN_MIN(nr) (0x3b + (nr))
-#define SIS5595_REG_FAN(nr) (0x28 + (nr))
-
-/* On the first version of the chip, the temp registers are separate.
-   On the second version,
-   TEMP pin is shared with IN4, configured in PCI register 0x7A.
-   The registers are the same as well.
-   OVER and HYST are really MAX and MIN. */
-
-#define REV2MIN	0xb0
-#define SIS5595_REG_TEMP 	(( data->revision) >= REV2MIN) ? \
-					SIS5595_REG_IN(4) : 0x27
-#define SIS5595_REG_TEMP_OVER	(( data->revision) >= REV2MIN) ? \
-					SIS5595_REG_IN_MAX(4) : 0x39
-#define SIS5595_REG_TEMP_HYST	(( data->revision) >= REV2MIN) ? \
-					SIS5595_REG_IN_MIN(4) : 0x3a
-
-#define SIS5595_REG_CONFIG 0x40
-#define SIS5595_REG_ALARM1 0x41
-#define SIS5595_REG_ALARM2 0x42
-#define SIS5595_REG_FANDIV 0x47
-
-/* Conversions. Limit checking is only done on the TO_REG
-   variants. */
-
-/* IN: mV, (0V to 4.08V)
-   REG: 16mV/bit */
-static inline u8 IN_TO_REG(unsigned long val)
-{
-	unsigned long nval = SENSORS_LIMIT(val, 0, 4080);
-	return (nval + 8) / 16;
-}
-#define IN_FROM_REG(val) ((val) *  16)
-
-static inline u8 FAN_TO_REG(long rpm, int div)
-{
-	if (rpm <= 0)
-		return 255;
-	return SENSORS_LIMIT((1350000 + rpm * div / 2) / (rpm * div), 1, 254);
-}
-
-static inline int FAN_FROM_REG(u8 val, int div)
-{
-	return val==0 ? -1 : val==255 ? 0 : 1350000/(val*div);
-}
-
-/* TEMP: mC (-54.12C to +157.53C)
-   REG: 0.83C/bit + 52.12, two's complement  */
-static inline int TEMP_FROM_REG(s8 val)
-{
-	return val * 830 + 52120;
-}
-static inline s8 TEMP_TO_REG(int val)
-{
-	int nval = SENSORS_LIMIT(val, -54120, 157530) ;
-	return nval<0 ? (nval-5212-415)/830 : (nval-5212+415)/830;
-}
-
-/* FAN DIV: 1, 2, 4, or 8 (defaults to 2)
-   REG: 0, 1, 2, or 3 (respectively) (defaults to 1) */
-static inline u8 DIV_TO_REG(int val)
-{
-	return val==8 ? 3 : val==4 ? 2 : val==1 ? 0 : 1;
-}
-#define DIV_FROM_REG(val) (1 << (val))
-
-/* For the SIS5595, we need to keep some data in memory. That
-   data is pointed to by sis5595_list[NR]->data. The structure itself is
-   dynamically allocated, at the time when the new sis5595 client is
-   allocated. */
-struct sis5595_data {
-	struct i2c_client client;
-	struct semaphore lock;
-
-	struct semaphore update_lock;
-	char valid;		/* !=0 if following fields are valid */
-	unsigned long last_updated;	/* In jiffies */
-	char maxins;		/* == 3 if temp enabled, otherwise == 4 */
-	u8 revision;		/* Reg. value */
-
-	u8 in[5];		/* Register value */
-	u8 in_max[5];		/* Register value */
-	u8 in_min[5];		/* Register value */
-	u8 fan[2];		/* Register value */
-	u8 fan_min[2];		/* Register value */
-	s8 temp;		/* Register value */
-	s8 temp_over;		/* Register value */
-	s8 temp_hyst;		/* Register value */
-	u8 fan_div[2];		/* Register encoding, shifted right */
-	u16 alarms;		/* Register encoding, combined */
-};
-
-static struct pci_dev *s_bridge;	/* pointer to the (only) sis5595 */
-
-static int sis5595_attach_adapter(struct i2c_adapter *adapter);
-static int sis5595_detect(struct i2c_adapter *adapter, int address, int kind);
-static int sis5595_detach_client(struct i2c_client *client);
-
-static int sis5595_read_value(struct i2c_client *client, u8 register);
-static int sis5595_write_value(struct i2c_client *client, u8 register, u8 value);
-static struct sis5595_data *sis5595_update_device(struct device *dev);
-static void sis5595_init_client(struct i2c_client *client);
-
-static struct i2c_driver sis5595_driver = {
-	.owner		= THIS_MODULE,
-	.name		= "sis5595",
-	.id		= I2C_DRIVERID_SIS5595,
-	.flags		= I2C_DF_NOTIFY,
-	.attach_adapter	= sis5595_attach_adapter,
-	.detach_client	= sis5595_detach_client,
-};
-
-/* 4 Voltages */
-static ssize_t show_in(struct device *dev, char *buf, int nr)
-{
-	struct sis5595_data *data = sis5595_update_device(dev);
-	return sprintf(buf, "%d\n", IN_FROM_REG(data->in[nr]));
-}
-
-static ssize_t show_in_min(struct device *dev, char *buf, int nr)
-{
-	struct sis5595_data *data = sis5595_update_device(dev);
-	return sprintf(buf, "%d\n", IN_FROM_REG(data->in_min[nr]));
-}
-
-static ssize_t show_in_max(struct device *dev, char *buf, int nr)
-{
-	struct sis5595_data *data = sis5595_update_device(dev);
-	return sprintf(buf, "%d\n", IN_FROM_REG(data->in_max[nr]));
-}
-
-static ssize_t set_in_min(struct device *dev, const char *buf,
-	       size_t count, int nr)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct sis5595_data *data = i2c_get_clientdata(client);
-	unsigned long val = simple_strtoul(buf, NULL, 10);
-
-	down(&data->update_lock);
-	data->in_min[nr] = IN_TO_REG(val);
-	sis5595_write_value(client, SIS5595_REG_IN_MIN(nr), data->in_min[nr]);
-	up(&data->update_lock);
-	return count;
-}
-
-static ssize_t set_in_max(struct device *dev, const char *buf,
-	       size_t count, int nr)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct sis5595_data *data = i2c_get_clientdata(client);
-	unsigned long val = simple_strtoul(buf, NULL, 10);
-
-	down(&data->update_lock);
-	data->in_max[nr] = IN_TO_REG(val);
-	sis5595_write_value(client, SIS5595_REG_IN_MAX(nr), data->in_max[nr]);
-	up(&data->update_lock);
-	return count;
-}
-
-#define show_in_offset(offset)					\
-static ssize_t							\
-	show_in##offset (struct device *dev, char *buf)		\
-{								\
-	return show_in(dev, buf, offset);			\
-}								\
-static DEVICE_ATTR(in##offset##_input, S_IRUGO, 		\
-		show_in##offset, NULL);				\
-static ssize_t							\
-	show_in##offset##_min (struct device *dev, char *buf)	\
-{								\
-	return show_in_min(dev, buf, offset);			\
-}								\
-static ssize_t							\
-	show_in##offset##_max (struct device *dev, char *buf)	\
-{								\
-	return show_in_max(dev, buf, offset);			\
-}								\
-static ssize_t set_in##offset##_min (struct device *dev,	\
-		const char *buf, size_t count)			\
-{								\
-	return set_in_min(dev, buf, count, offset);		\
-}								\
-static ssize_t set_in##offset##_max (struct device *dev,	\
-		const char *buf, size_t count)			\
-{								\
-	return set_in_max(dev, buf, count, offset);		\
-}								\
-static DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR,		\
-		show_in##offset##_min, set_in##offset##_min);	\
-static DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR,		\
-		show_in##offset##_max, set_in##offset##_max);
-
-show_in_offset(0);
-show_in_offset(1);
-show_in_offset(2);
-show_in_offset(3);
-show_in_offset(4);
-
-/* Temperature */
-static ssize_t show_temp(struct device *dev, char *buf)
-{
-	struct sis5595_data *data = sis5595_update_device(dev);
-	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp));
-}
-
-static ssize_t show_temp_over(struct device *dev, char *buf)
-{
-	struct sis5595_data *data = sis5595_update_device(dev);
-	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_over));
-}
-
-static ssize_t set_temp_over(struct device *dev, const char *buf, size_t count)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct sis5595_data *data = i2c_get_clientdata(client);
-	long val = simple_strtol(buf, NULL, 10);
-
-	down(&data->update_lock);
-	data->temp_over = TEMP_TO_REG(val);
-	sis5595_write_value(client, SIS5595_REG_TEMP_OVER, data->temp_over);
-	up(&data->update_lock);
-	return count;
-}
-
-static ssize_t show_temp_hyst(struct device *dev, char *buf)
-{
-	struct sis5595_data *data = sis5595_update_device(dev);
-	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_hyst));
-}
-
-static ssize_t set_temp_hyst(struct device *dev, const char *buf, size_t count)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct sis5595_data *data = i2c_get_clientdata(client);
-	long val = simple_strtol(buf, NULL, 10);
-
-	down(&data->update_lock);
-	data->temp_hyst = TEMP_TO_REG(val);
-	sis5595_write_value(client, SIS5595_REG_TEMP_HYST, data->temp_hyst);
-	up(&data->update_lock);
-	return count;
-}
-
-static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL);
-static DEVICE_ATTR(temp1_max, S_IRUGO | S_IWUSR,
-		show_temp_over, set_temp_over);
-static DEVICE_ATTR(temp1_max_hyst, S_IRUGO | S_IWUSR,
-		show_temp_hyst, set_temp_hyst);
-
-/* 2 Fans */
-static ssize_t show_fan(struct device *dev, char *buf, int nr)
-{
-	struct sis5595_data *data = sis5595_update_device(dev);
-	return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[nr],
-		DIV_FROM_REG(data->fan_div[nr])) );
-}
-
-static ssize_t show_fan_min(struct device *dev, char *buf, int nr)
-{
-	struct sis5595_data *data = sis5595_update_device(dev);
-	return sprintf(buf,"%d\n", FAN_FROM_REG(data->fan_min[nr],
-		DIV_FROM_REG(data->fan_div[nr])) );
-}
-
-static ssize_t set_fan_min(struct device *dev, const char *buf,
-		size_t count, int nr)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct sis5595_data *data = i2c_get_clientdata(client);
-	unsigned long val = simple_strtoul(buf, NULL, 10);
-
-	down(&data->update_lock);
-	data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr]));
-	sis5595_write_value(client, SIS5595_REG_FAN_MIN(nr), data->fan_min[nr]);
-	up(&data->update_lock);
-	return count;
-}
-
-static ssize_t show_fan_div(struct device *dev, char *buf, int nr)
-{
-	struct sis5595_data *data = sis5595_update_device(dev);
-	return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[nr]) );
-}
-
-/* Note: we save and restore the fan minimum here, because its value is
-   determined in part by the fan divisor.  This follows the principle of
-   least suprise; the user doesn't expect the fan minimum to change just
-   because the divisor changed. */
-static ssize_t set_fan_div(struct device *dev, const char *buf,
-	size_t count, int nr)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct sis5595_data *data = i2c_get_clientdata(client);
-	unsigned long min;
-	unsigned long val = simple_strtoul(buf, NULL, 10);
-	int reg;
-
-	down(&data->update_lock);
-	min = FAN_FROM_REG(data->fan_min[nr],
-			DIV_FROM_REG(data->fan_div[nr]));
-	reg = sis5595_read_value(client, SIS5595_REG_FANDIV);
-
-	switch (val) {
-	case 1: data->fan_div[nr] = 0; break;
-	case 2: data->fan_div[nr] = 1; break;
-	case 4: data->fan_div[nr] = 2; break;
-	case 8: data->fan_div[nr] = 3; break;
-	default:
-		dev_err(&client->dev, "fan_div value %ld not "
-			"supported. Choose one of 1, 2, 4 or 8!\n", val);
-		up(&data->update_lock);
-		return -EINVAL;
-	}
-	
-	switch (nr) {
-	case 0:
-		reg = (reg & 0xcf) | (data->fan_div[nr] << 4);
-		break;
-	case 1:
-		reg = (reg & 0x3f) | (data->fan_div[nr] << 6);
-		break;
-	}
-	sis5595_write_value(client, SIS5595_REG_FANDIV, reg);
-	data->fan_min[nr] =
-		FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr]));
-	sis5595_write_value(client, SIS5595_REG_FAN_MIN(nr), data->fan_min[nr]);
-	up(&data->update_lock);
-	return count;
-}
-
-#define show_fan_offset(offset)						\
-static ssize_t show_fan_##offset (struct device *dev, char *buf)	\
-{									\
-	return show_fan(dev, buf, offset - 1);			\
-}									\
-static ssize_t show_fan_##offset##_min (struct device *dev, char *buf)	\
-{									\
-	return show_fan_min(dev, buf, offset - 1);			\
-}									\
-static ssize_t show_fan_##offset##_div (struct device *dev, char *buf)	\
-{									\
-	return show_fan_div(dev, buf, offset - 1);			\
-}									\
-static ssize_t set_fan_##offset##_min (struct device *dev,		\
-		const char *buf, size_t count)				\
-{									\
-	return set_fan_min(dev, buf, count, offset - 1);		\
-}									\
-static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_fan_##offset, NULL);\
-static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR,		\
-		show_fan_##offset##_min, set_fan_##offset##_min);
-
-show_fan_offset(1);
-show_fan_offset(2);
-
-static ssize_t set_fan_1_div(struct device *dev, const char *buf,
-		size_t count)
-{
-	return set_fan_div(dev, buf, count, 0) ;
-}
-
-static ssize_t set_fan_2_div(struct device *dev, const char *buf,
-		size_t count)
-{
-	return set_fan_div(dev, buf, count, 1) ;
-}
-static DEVICE_ATTR(fan1_div, S_IRUGO | S_IWUSR,
-		show_fan_1_div, set_fan_1_div);
-static DEVICE_ATTR(fan2_div, S_IRUGO | S_IWUSR,
-		show_fan_2_div, set_fan_2_div);
-
-/* Alarms */
-static ssize_t show_alarms(struct device *dev, char *buf)
-{
-	struct sis5595_data *data = sis5595_update_device(dev);
-	return sprintf(buf, "%d\n", data->alarms);
-}
-static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
- 
-/* This is called when the module is loaded */
-static int sis5595_attach_adapter(struct i2c_adapter *adapter)
-{
-	if (!(adapter->class & I2C_CLASS_HWMON))
-		return 0;
-	return i2c_detect(adapter, &addr_data, sis5595_detect);
-}
-
-int sis5595_detect(struct i2c_adapter *adapter, int address, int kind)
-{
-	int err = 0;
-	int i;
-	struct i2c_client *new_client;
-	struct sis5595_data *data;
-	char val;
-	u16 a;
-
-	/* Make sure we are probing the ISA bus!!  */
-	if (!i2c_is_isa_adapter(adapter))
-		goto exit;
-
-	if (force_addr)
-		address = force_addr & ~(SIS5595_EXTENT - 1);
-	/* Reserve the ISA region */
-	if (!request_region(address, SIS5595_EXTENT, sis5595_driver.name)) {
-		err = -EBUSY;
-		goto exit;
-	}
-	if (force_addr) {
-		dev_warn(&adapter->dev, "forcing ISA address 0x%04X\n", address);
-		if (PCIBIOS_SUCCESSFUL !=
-		    pci_write_config_word(s_bridge, SIS5595_BASE_REG, address))
-			goto exit_release;
-		if (PCIBIOS_SUCCESSFUL !=
-		    pci_read_config_word(s_bridge, SIS5595_BASE_REG, &a))
-			goto exit_release;
-		if ((a & ~(SIS5595_EXTENT - 1)) != address)
-			/* doesn't work for some chips? */
-			goto exit_release;
-	}
-
-	if (PCIBIOS_SUCCESSFUL !=
-	    pci_read_config_byte(s_bridge, SIS5595_ENABLE_REG, &val)) {
-		goto exit_release;
-	}
-	if ((val & 0x80) == 0) {
-		if (PCIBIOS_SUCCESSFUL !=
-		    pci_write_config_byte(s_bridge, SIS5595_ENABLE_REG,
-					  val | 0x80))
-			goto exit_release;
-		if (PCIBIOS_SUCCESSFUL !=
-		    pci_read_config_byte(s_bridge, SIS5595_ENABLE_REG, &val))
-			goto exit_release;
-		if ((val & 0x80) == 0) 
-			/* doesn't work for some chips! */
-			goto exit_release;
-	}
-
-	if (!(data = kmalloc(sizeof(struct sis5595_data), GFP_KERNEL))) {
-		err = -ENOMEM;
-		goto exit_release;
-	}
-	memset(data, 0, sizeof(struct sis5595_data));
-
-	new_client = &data->client;
-	new_client->addr = address;
-	init_MUTEX(&data->lock);
-	i2c_set_clientdata(new_client, data);
-	new_client->adapter = adapter;
-	new_client->driver = &sis5595_driver;
-	new_client->flags = 0;
-
-	/* Check revision and pin registers to determine whether 4 or 5 voltages */
-	pci_read_config_byte(s_bridge, SIS5595_REVISION_REG, &(data->revision));
-	/* 4 voltages, 1 temp */
-	data->maxins = 3;
-	if (data->revision >= REV2MIN) {
-		pci_read_config_byte(s_bridge, SIS5595_PIN_REG, &val);
-		if (!(val & 0x80))
-			/* 5 voltages, no temps */
-			data->maxins = 4;
-	}
-	
-	/* Fill in the remaining client fields and put it into the global list */
-	strlcpy(new_client->name, "sis5595", I2C_NAME_SIZE);
-
-	data->valid = 0;
-	init_MUTEX(&data->update_lock);
-
-	/* Tell the I2C layer a new client has arrived */
-	if ((err = i2c_attach_client(new_client)))
-		goto exit_free;
-	
-	/* Initialize the SIS5595 chip */
-	sis5595_init_client(new_client);
-
-	/* A few vars need to be filled upon startup */
-	for (i = 0; i < 2; i++) {
-		data->fan_min[i] = sis5595_read_value(new_client,
-					SIS5595_REG_FAN_MIN(i));
-	}
-
-	/* Register sysfs hooks */
-	device_create_file(&new_client->dev, &dev_attr_in0_input);
-	device_create_file(&new_client->dev, &dev_attr_in0_min);
-	device_create_file(&new_client->dev, &dev_attr_in0_max);
-	device_create_file(&new_client->dev, &dev_attr_in1_input);
-	device_create_file(&new_client->dev, &dev_attr_in1_min);
-	device_create_file(&new_client->dev, &dev_attr_in1_max);
-	device_create_file(&new_client->dev, &dev_attr_in2_input);
-	device_create_file(&new_client->dev, &dev_attr_in2_min);
-	device_create_file(&new_client->dev, &dev_attr_in2_max);
-	device_create_file(&new_client->dev, &dev_attr_in3_input);
-	device_create_file(&new_client->dev, &dev_attr_in3_min);
-	device_create_file(&new_client->dev, &dev_attr_in3_max);
-	if (data->maxins == 4) {
-		device_create_file(&new_client->dev, &dev_attr_in4_input);
-		device_create_file(&new_client->dev, &dev_attr_in4_min);
-		device_create_file(&new_client->dev, &dev_attr_in4_max);
-	}
-	device_create_file(&new_client->dev, &dev_attr_fan1_input);
-	device_create_file(&new_client->dev, &dev_attr_fan1_min);
-	device_create_file(&new_client->dev, &dev_attr_fan1_div);
-	device_create_file(&new_client->dev, &dev_attr_fan2_input);
-	device_create_file(&new_client->dev, &dev_attr_fan2_min);
-	device_create_file(&new_client->dev, &dev_attr_fan2_div);
-	device_create_file(&new_client->dev, &dev_attr_alarms);
-	if (data->maxins == 3) {
-		device_create_file(&new_client->dev, &dev_attr_temp1_input);
-		device_create_file(&new_client->dev, &dev_attr_temp1_max);
-		device_create_file(&new_client->dev, &dev_attr_temp1_max_hyst);
-	}
-	return 0;
-	
-exit_free:
-	kfree(data);
-exit_release:
-	release_region(address, SIS5595_EXTENT);
-exit:
-	return err;
-}
-
-static int sis5595_detach_client(struct i2c_client *client)
-{
-	int err;
-
-	if ((err = i2c_detach_client(client))) {
-		dev_err(&client->dev,
-		    "Client deregistration failed, client not detached.\n");
-		return err;
-	}
-
-	if (i2c_is_isa_client(client))
-		release_region(client->addr, SIS5595_EXTENT);
-
-	kfree(i2c_get_clientdata(client));
-
-	return 0;
-}
-
-
-/* ISA access must be locked explicitly. */
-static int sis5595_read_value(struct i2c_client *client, u8 reg)
-{
-	int res;
-
-	struct sis5595_data *data = i2c_get_clientdata(client);
-	down(&data->lock);
-	outb_p(reg, client->addr + SIS5595_ADDR_REG_OFFSET);
-	res = inb_p(client->addr + SIS5595_DATA_REG_OFFSET);
-	up(&data->lock);
-	return res;
-}
-
-static int sis5595_write_value(struct i2c_client *client, u8 reg, u8 value)
-{
-	struct sis5595_data *data = i2c_get_clientdata(client);
-	down(&data->lock);
-	outb_p(reg, client->addr + SIS5595_ADDR_REG_OFFSET);
-	outb_p(value, client->addr + SIS5595_DATA_REG_OFFSET);
-	up(&data->lock);
-	return 0;
-}
-
-/* Called when we have found a new SIS5595. */
-static void sis5595_init_client(struct i2c_client *client)
-{
-	u8 config = sis5595_read_value(client, SIS5595_REG_CONFIG);
-	if (!(config & 0x01))
-		sis5595_write_value(client, SIS5595_REG_CONFIG,
-				(config & 0xf7) | 0x01);
-}
-
-static struct sis5595_data *sis5595_update_device(struct device *dev)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct sis5595_data *data = i2c_get_clientdata(client);
-	int i;
-
-	down(&data->update_lock);
-
-	if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
-	    || !data->valid) {
-
-		for (i = 0; i <= data->maxins; i++) {
-			data->in[i] =
-			    sis5595_read_value(client, SIS5595_REG_IN(i));
-			data->in_min[i] =
-			    sis5595_read_value(client,
-					       SIS5595_REG_IN_MIN(i));
-			data->in_max[i] =
-			    sis5595_read_value(client,
-					       SIS5595_REG_IN_MAX(i));
-		}
-		for (i = 0; i < 2; i++) {
-			data->fan[i] =
-			    sis5595_read_value(client, SIS5595_REG_FAN(i));
-			data->fan_min[i] =
-			    sis5595_read_value(client,
-					       SIS5595_REG_FAN_MIN(i));
-		}
-		if (data->maxins == 3) {
-			data->temp =
-			    sis5595_read_value(client, SIS5595_REG_TEMP);
-			data->temp_over =
-			    sis5595_read_value(client, SIS5595_REG_TEMP_OVER);
-			data->temp_hyst =
-			    sis5595_read_value(client, SIS5595_REG_TEMP_HYST);
-		}
-		i = sis5595_read_value(client, SIS5595_REG_FANDIV);
-		data->fan_div[0] = (i >> 4) & 0x03;
-		data->fan_div[1] = i >> 6;
-		data->alarms =
-		    sis5595_read_value(client, SIS5595_REG_ALARM1) |
-		    (sis5595_read_value(client, SIS5595_REG_ALARM2) << 8);
-		data->last_updated = jiffies;
-		data->valid = 1;
-	}
-
-	up(&data->update_lock);
-
-	return data;
-}
-
-static struct pci_device_id sis5595_pci_ids[] = {
-	{ PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) },
-	{ 0, }
-};
-
-MODULE_DEVICE_TABLE(pci, sis5595_pci_ids);
-
-static int blacklist[] __devinitdata = {
-	PCI_DEVICE_ID_SI_540,
-	PCI_DEVICE_ID_SI_550,
-	PCI_DEVICE_ID_SI_630,
-	PCI_DEVICE_ID_SI_645,
-	PCI_DEVICE_ID_SI_730,
-	PCI_DEVICE_ID_SI_735,
-	PCI_DEVICE_ID_SI_5511, /* 5513 chip has the 0008 device but
-				  that ID shows up in other chips so we
-				  use the 5511 ID for recognition */
-	PCI_DEVICE_ID_SI_5597,
-	PCI_DEVICE_ID_SI_5598,
-	0 };
-
-static int __devinit sis5595_pci_probe(struct pci_dev *dev,
-				       const struct pci_device_id *id)
-{
-	u16 val;
-	int *i;
-	int addr = 0;
-
-	for (i = blacklist; *i != 0; i++) {
-		struct pci_dev *dev;
-		dev = pci_get_device(PCI_VENDOR_ID_SI, *i, NULL);
-		if (dev) {
-			dev_err(&dev->dev, "Looked for SIS5595 but found unsupported device %.4x\n", *i);
-			pci_dev_put(dev);
-			return -ENODEV;
-		}
-	}
-	
-	if (PCIBIOS_SUCCESSFUL !=
-	    pci_read_config_word(dev, SIS5595_BASE_REG, &val))
-		return -ENODEV;
-	
-	addr = val & ~(SIS5595_EXTENT - 1);
-	if (addr == 0 && force_addr == 0) {
-		dev_err(&dev->dev, "Base address not set - upgrade BIOS or use force_addr=0xaddr\n");
-		return -ENODEV;
-	}
-	if (force_addr)
-		addr = force_addr;	/* so detect will get called */
-
-	if (!addr) {
-		dev_err(&dev->dev,"No SiS 5595 sensors found.\n");
-		return -ENODEV;
-	}
-	normal_isa[0] = addr;
-
-	s_bridge = pci_dev_get(dev);
-	if (i2c_add_driver(&sis5595_driver)) {
-		pci_dev_put(s_bridge);
-		s_bridge = NULL;
-	}
-
-	/* Always return failure here.  This is to allow other drivers to bind
-	 * to this pci device.  We don't really want to have control over the
-	 * pci device, we only wanted to read as few register values from it.
-	 */
-	return -ENODEV;
-}
-
-static struct pci_driver sis5595_pci_driver = {
-	.name            = "sis5595",
-	.id_table        = sis5595_pci_ids,
-	.probe           = sis5595_pci_probe,
-};
-
-static int __init sm_sis5595_init(void)
-{
-	return pci_register_driver(&sis5595_pci_driver);
-}
-
-static void __exit sm_sis5595_exit(void)
-{
-	pci_unregister_driver(&sis5595_pci_driver);
-	if (s_bridge != NULL) {
-		i2c_del_driver(&sis5595_driver);
-		pci_dev_put(s_bridge);
-		s_bridge = NULL;
-	}
-}
-
-MODULE_AUTHOR("Aurelien Jarno <aurelien@aurel32.net>");
-MODULE_DESCRIPTION("SiS 5595 Sensor device");
-MODULE_LICENSE("GPL");
-
-module_init(sm_sis5595_init);
-module_exit(sm_sis5595_exit);
diff --git a/drivers/i2c/chips/smsc47b397.c b/drivers/i2c/chips/smsc47b397.c
deleted file mode 100644
--- a/drivers/i2c/chips/smsc47b397.c
+++ /dev/null
@@ -1,352 +0,0 @@
-/*
-    smsc47b397.c - Part of lm_sensors, Linux kernel modules
-			for hardware monitoring
-
-    Supports the SMSC LPC47B397-NC Super-I/O chip.
-
-    Author/Maintainer: Mark M. Hoffman <mhoffman@lightlink.com>
-	Copyright (C) 2004 Utilitek Systems, Inc.
-
-    derived in part from smsc47m1.c:
-	Copyright (C) 2002 Mark D. Studebaker <mdsxyz123@yahoo.com>
-	Copyright (C) 2004 Jean Delvare <khali@linux-fr.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.
-*/
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/ioport.h>
-#include <linux/jiffies.h>
-#include <linux/i2c.h>
-#include <linux/i2c-sensor.h>
-#include <linux/init.h>
-#include <asm/io.h>
-
-static unsigned short normal_i2c[] = { I2C_CLIENT_END };
-/* Address is autodetected, there is no default value */
-static unsigned int normal_isa[] = { 0x0000, I2C_CLIENT_ISA_END };
-static struct i2c_force_data forces[] = {{NULL}};
-
-enum chips { any_chip, smsc47b397 };
-static struct i2c_address_data addr_data = {
-	.normal_i2c		= normal_i2c,
-	.normal_isa		= normal_isa,
-	.probe			= normal_i2c,		/* cheat */
-	.ignore			= normal_i2c,		/* cheat */
-	.forces			= forces,
-};
-
-/* Super-I/0 registers and commands */
-
-#define	REG	0x2e	/* The register to read/write */
-#define	VAL	0x2f	/* The value to read/write */
-
-static inline void superio_outb(int reg, int val)
-{
-	outb(reg, REG);
-	outb(val, VAL);
-}
-
-static inline int superio_inb(int reg)
-{
-	outb(reg, REG);
-	return inb(VAL);
-}
-
-/* select superio logical device */
-static inline void superio_select(int ld)
-{
-	superio_outb(0x07, ld);
-}
-
-static inline void superio_enter(void)
-{
-	outb(0x55, REG);
-}
-
-static inline void superio_exit(void)
-{
-	outb(0xAA, REG);
-}
-
-#define SUPERIO_REG_DEVID	0x20
-#define SUPERIO_REG_DEVREV	0x21
-#define SUPERIO_REG_BASE_MSB	0x60
-#define SUPERIO_REG_BASE_LSB	0x61
-#define SUPERIO_REG_LD8		0x08
-
-#define SMSC_EXTENT		0x02
-
-/* 0 <= nr <= 3 */
-static u8 smsc47b397_reg_temp[] = {0x25, 0x26, 0x27, 0x80};
-#define SMSC47B397_REG_TEMP(nr)	(smsc47b397_reg_temp[(nr)])
-
-/* 0 <= nr <= 3 */
-#define SMSC47B397_REG_FAN_LSB(nr) (0x28 + 2 * (nr))
-#define SMSC47B397_REG_FAN_MSB(nr) (0x29 + 2 * (nr))
-
-struct smsc47b397_data {
-	struct i2c_client client;
-	struct semaphore lock;
-
-	struct semaphore update_lock;
-	unsigned long last_updated; /* in jiffies */
-	int valid;
-
-	/* register values */
-	u16 fan[4];
-	u8 temp[4];
-};
-
-static int smsc47b397_read_value(struct i2c_client *client, u8 reg)
-{
-	struct smsc47b397_data *data = i2c_get_clientdata(client);
-	int res;
-
-	down(&data->lock);
-	outb(reg, client->addr);
-	res = inb_p(client->addr + 1);
-	up(&data->lock);
-	return res;
-}
-
-static struct smsc47b397_data *smsc47b397_update_device(struct device *dev)
-{
- 	struct i2c_client *client = to_i2c_client(dev);
-	struct smsc47b397_data *data = i2c_get_clientdata(client);
-	int i;
-
-	down(&data->update_lock);
-
-	if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
-		dev_dbg(&client->dev, "starting device update...\n");
-
-		/* 4 temperature inputs, 4 fan inputs */
-		for (i = 0; i < 4; i++) {
-			data->temp[i] = smsc47b397_read_value(client,
-					SMSC47B397_REG_TEMP(i));
-
-			/* must read LSB first */
-			data->fan[i]  = smsc47b397_read_value(client,
-					SMSC47B397_REG_FAN_LSB(i));
-			data->fan[i] |= smsc47b397_read_value(client,
-					SMSC47B397_REG_FAN_MSB(i)) << 8;
-		}
-
-		data->last_updated = jiffies;
-		data->valid = 1;
-
-		dev_dbg(&client->dev, "... device update complete\n");
-	}
-
-	up(&data->update_lock);
-
-	return data;
-}
-
-/* TEMP: 0.001C/bit (-128C to +127C)
-   REG: 1C/bit, two's complement */
-static int temp_from_reg(u8 reg)
-{
-	return (s8)reg * 1000;
-}
-
-/* 0 <= nr <= 3 */
-static ssize_t show_temp(struct device *dev, char *buf, int nr)
-{
-	struct smsc47b397_data *data = smsc47b397_update_device(dev);
-	return sprintf(buf, "%d\n", temp_from_reg(data->temp[nr]));
-}
-
-#define sysfs_temp(num) \
-static ssize_t show_temp##num(struct device *dev, char *buf) \
-{ \
-	return show_temp(dev, buf, num-1); \
-} \
-static DEVICE_ATTR(temp##num##_input, S_IRUGO, show_temp##num, NULL)
-
-sysfs_temp(1);
-sysfs_temp(2);
-sysfs_temp(3);
-sysfs_temp(4);
-
-#define device_create_file_temp(client, num) \
-	device_create_file(&client->dev, &dev_attr_temp##num##_input)
-
-/* FAN: 1 RPM/bit
-   REG: count of 90kHz pulses / revolution */
-static int fan_from_reg(u16 reg)
-{
-	return 90000 * 60 / reg;
-}
-
-/* 0 <= nr <= 3 */
-static ssize_t show_fan(struct device *dev, char *buf, int nr)
-{
-        struct smsc47b397_data *data = smsc47b397_update_device(dev);
-        return sprintf(buf, "%d\n", fan_from_reg(data->fan[nr]));
-}
-
-#define sysfs_fan(num) \
-static ssize_t show_fan##num(struct device *dev, char *buf) \
-{ \
-	return show_fan(dev, buf, num-1); \
-} \
-static DEVICE_ATTR(fan##num##_input, S_IRUGO, show_fan##num, NULL)
-
-sysfs_fan(1);
-sysfs_fan(2);
-sysfs_fan(3);
-sysfs_fan(4);
-
-#define device_create_file_fan(client, num) \
-	device_create_file(&client->dev, &dev_attr_fan##num##_input)
-
-static int smsc47b397_detect(struct i2c_adapter *adapter, int addr, int kind);
-
-static int smsc47b397_attach_adapter(struct i2c_adapter *adapter)
-{
-	if (!(adapter->class & I2C_CLASS_HWMON))
-		return 0;
-	return i2c_detect(adapter, &addr_data, smsc47b397_detect);
-}
-
-static int smsc47b397_detach_client(struct i2c_client *client)
-{
-	int err;
-
-	if ((err = i2c_detach_client(client))) {
-		dev_err(&client->dev, "Client deregistration failed, "
-			"client not detached.\n");
-		return err;
-	}
-
-	release_region(client->addr, SMSC_EXTENT);
-	kfree(i2c_get_clientdata(client));
-
-	return 0;
-}
-
-static struct i2c_driver smsc47b397_driver = {
-	.owner		= THIS_MODULE,
-	.name		= "smsc47b397",
-	.id		= I2C_DRIVERID_SMSC47B397,
-	.flags		= I2C_DF_NOTIFY,
-	.attach_adapter	= smsc47b397_attach_adapter,
-	.detach_client	= smsc47b397_detach_client,
-};
-
-static int smsc47b397_detect(struct i2c_adapter *adapter, int addr, int kind)
-{
-	struct i2c_client *new_client;
-	struct smsc47b397_data *data;
-	int err = 0;
-
-	if (!i2c_is_isa_adapter(adapter)) {
-		return 0;
-	}
-
-	if (!request_region(addr, SMSC_EXTENT, smsc47b397_driver.name)) {
-		dev_err(&adapter->dev, "Region 0x%x already in use!\n", addr);
-		return -EBUSY;
-	}
-
-	if (!(data = kmalloc(sizeof(struct smsc47b397_data), GFP_KERNEL))) {
-		err = -ENOMEM;
-		goto error_release;
-	}
-	memset(data, 0x00, sizeof(struct smsc47b397_data));
-
-	new_client = &data->client;
-	i2c_set_clientdata(new_client, data);
-	new_client->addr = addr;
-	init_MUTEX(&data->lock);
-	new_client->adapter = adapter;
-	new_client->driver = &smsc47b397_driver;
-	new_client->flags = 0;
-
-	strlcpy(new_client->name, "smsc47b397", I2C_NAME_SIZE);
-
-	init_MUTEX(&data->update_lock);
-
-	if ((err = i2c_attach_client(new_client)))
-		goto error_free;
-
-	device_create_file_temp(new_client, 1);
-	device_create_file_temp(new_client, 2);
-	device_create_file_temp(new_client, 3);
-	device_create_file_temp(new_client, 4);
-
-	device_create_file_fan(new_client, 1);
-	device_create_file_fan(new_client, 2);
-	device_create_file_fan(new_client, 3);
-	device_create_file_fan(new_client, 4);
-
-	return 0;
-
-error_free:
-	kfree(new_client);
-error_release:
-	release_region(addr, SMSC_EXTENT);
-	return err;
-}
-
-static int __init smsc47b397_find(unsigned int *addr)
-{
-	u8 id, rev;
-
-	superio_enter();
-	id = superio_inb(SUPERIO_REG_DEVID);
-
-	if (id != 0x6f) {
-		superio_exit();
-		return -ENODEV;
-	}
-
-	rev = superio_inb(SUPERIO_REG_DEVREV);
-
-	superio_select(SUPERIO_REG_LD8);
-	*addr = (superio_inb(SUPERIO_REG_BASE_MSB) << 8)
-		 |  superio_inb(SUPERIO_REG_BASE_LSB);
-
-	printk(KERN_INFO "smsc47b397: found SMSC LPC47B397-NC "
-		"(base address 0x%04x, revision %u)\n", *addr, rev);
-
-	superio_exit();
-	return 0;
-}
-
-static int __init smsc47b397_init(void)
-{
-	int ret;
-
-	if ((ret = smsc47b397_find(normal_isa)))
-		return ret;
-
-	return i2c_add_driver(&smsc47b397_driver);
-}
-
-static void __exit smsc47b397_exit(void)
-{
-	i2c_del_driver(&smsc47b397_driver);
-}
-
-MODULE_AUTHOR("Mark M. Hoffman <mhoffman@lightlink.com>");
-MODULE_DESCRIPTION("SMSC LPC47B397 driver");
-MODULE_LICENSE("GPL");
-
-module_init(smsc47b397_init);
-module_exit(smsc47b397_exit);
diff --git a/drivers/i2c/chips/smsc47m1.c b/drivers/i2c/chips/smsc47m1.c
deleted file mode 100644
--- a/drivers/i2c/chips/smsc47m1.c
+++ /dev/null
@@ -1,591 +0,0 @@
-/*
-    smsc47m1.c - Part of lm_sensors, Linux kernel modules
-                 for hardware monitoring
-
-    Supports the SMSC LPC47B27x, LPC47M10x, LPC47M13x and LPC47M14x
-    Super-I/O chips.
-
-    Copyright (C) 2002 Mark D. Studebaker <mdsxyz123@yahoo.com>
-    Copyright (C) 2004 Jean Delvare <khali@linux-fr.org>
-    Ported to Linux 2.6 by Gabriele Gorla <gorlik@yahoo.com>
-                        and Jean Delvare
-
-    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 <linux/module.h>
-#include <linux/slab.h>
-#include <linux/ioport.h>
-#include <linux/jiffies.h>
-#include <linux/i2c.h>
-#include <linux/i2c-sensor.h>
-#include <linux/init.h>
-#include <asm/io.h>
-
-static unsigned short normal_i2c[] = { I2C_CLIENT_END };
-/* Address is autodetected, there is no default value */
-static unsigned int normal_isa[] = { 0x0000, I2C_CLIENT_ISA_END };
-static struct i2c_force_data forces[] = {{NULL}};
-
-enum chips { any_chip, smsc47m1 };
-static struct i2c_address_data addr_data = {
-	.normal_i2c		= normal_i2c,
-	.normal_isa		= normal_isa,
-	.forces			= forces,
-};
-
-/* Super-I/0 registers and commands */
-
-#define	REG	0x2e	/* The register to read/write */
-#define	VAL	0x2f	/* The value to read/write */
-
-static inline void
-superio_outb(int reg, int val)
-{
-	outb(reg, REG);
-	outb(val, VAL);
-}
-
-static inline int
-superio_inb(int reg)
-{
-	outb(reg, REG);
-	return inb(VAL);
-}
-
-/* logical device for fans is 0x0A */
-#define superio_select() superio_outb(0x07, 0x0A)
-
-static inline void
-superio_enter(void)
-{
-	outb(0x55, REG);
-}
-
-static inline void
-superio_exit(void)
-{
-	outb(0xAA, REG);
-}
-
-#define SUPERIO_REG_ACT		0x30
-#define SUPERIO_REG_BASE	0x60
-#define SUPERIO_REG_DEVID	0x20
-
-/* Logical device registers */
-
-#define SMSC_EXTENT		0x80
-
-/* nr is 0 or 1 in the macros below */
-#define SMSC47M1_REG_ALARM		0x04
-#define SMSC47M1_REG_TPIN(nr)		(0x34 - (nr))
-#define SMSC47M1_REG_PPIN(nr)		(0x36 - (nr))
-#define SMSC47M1_REG_PWM(nr)		(0x56 + (nr))
-#define SMSC47M1_REG_FANDIV		0x58
-#define SMSC47M1_REG_FAN(nr)		(0x59 + (nr))
-#define SMSC47M1_REG_FAN_PRELOAD(nr)	(0x5B + (nr))
-
-#define MIN_FROM_REG(reg,div)		((reg)>=192 ? 0 : \
-					 983040/((192-(reg))*(div)))
-#define FAN_FROM_REG(reg,div,preload)	((reg)<=(preload) || (reg)==255 ? 0 : \
-					 983040/(((reg)-(preload))*(div)))
-#define DIV_FROM_REG(reg)		(1 << (reg))
-#define PWM_FROM_REG(reg)		(((reg) & 0x7E) << 1)
-#define PWM_EN_FROM_REG(reg)		((~(reg)) & 0x01)
-#define PWM_TO_REG(reg)			(((reg) >> 1) & 0x7E)
-
-struct smsc47m1_data {
-	struct i2c_client client;
-	struct semaphore lock;
-
-	struct semaphore update_lock;
-	unsigned long last_updated;	/* In jiffies */
-
-	u8 fan[2];		/* Register value */
-	u8 fan_preload[2];	/* Register value */
-	u8 fan_div[2];		/* Register encoding, shifted right */
-	u8 alarms;		/* Register encoding */
-	u8 pwm[2];		/* Register value (bit 7 is enable) */
-};
-
-
-static int smsc47m1_attach_adapter(struct i2c_adapter *adapter);
-static int smsc47m1_find(int *address);
-static int smsc47m1_detect(struct i2c_adapter *adapter, int address, int kind);
-static int smsc47m1_detach_client(struct i2c_client *client);
-
-static int smsc47m1_read_value(struct i2c_client *client, u8 reg);
-static void smsc47m1_write_value(struct i2c_client *client, u8 reg, u8 value);
-
-static struct smsc47m1_data *smsc47m1_update_device(struct device *dev,
-		int init);
-
-
-static struct i2c_driver smsc47m1_driver = {
-	.owner		= THIS_MODULE,
-	.name		= "smsc47m1",
-	.id		= I2C_DRIVERID_SMSC47M1,
-	.flags		= I2C_DF_NOTIFY,
-	.attach_adapter	= smsc47m1_attach_adapter,
-	.detach_client	= smsc47m1_detach_client,
-};
-
-/* nr is 0 or 1 in the callback functions below */
-
-static ssize_t get_fan(struct device *dev, char *buf, int nr)
-{
-	struct smsc47m1_data *data = smsc47m1_update_device(dev, 0);
-	/* This chip (stupidly) stops monitoring fan speed if PWM is
-	   enabled and duty cycle is 0%. This is fine if the monitoring
-	   and control concern the same fan, but troublesome if they are
-	   not (which could as well happen). */
-	int rpm = (data->pwm[nr] & 0x7F) == 0x00 ? 0 :
-		  FAN_FROM_REG(data->fan[nr],
-			       DIV_FROM_REG(data->fan_div[nr]),
-			       data->fan_preload[nr]);
-	return sprintf(buf, "%d\n", rpm);
-}
-
-static ssize_t get_fan_min(struct device *dev, char *buf, int nr)
-{
-	struct smsc47m1_data *data = smsc47m1_update_device(dev, 0);
-	int rpm = MIN_FROM_REG(data->fan_preload[nr],
-			       DIV_FROM_REG(data->fan_div[nr]));
-	return sprintf(buf, "%d\n", rpm);
-}
-
-static ssize_t get_fan_div(struct device *dev, char *buf, int nr)
-{
-	struct smsc47m1_data *data = smsc47m1_update_device(dev, 0);
-	return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[nr]));
-}
-
-static ssize_t get_pwm(struct device *dev, char *buf, int nr)
-{
-	struct smsc47m1_data *data = smsc47m1_update_device(dev, 0);
-	return sprintf(buf, "%d\n", PWM_FROM_REG(data->pwm[nr]));
-}
-
-static ssize_t get_pwm_en(struct device *dev, char *buf, int nr)
-{
-	struct smsc47m1_data *data = smsc47m1_update_device(dev, 0);
-	return sprintf(buf, "%d\n", PWM_EN_FROM_REG(data->pwm[nr]));
-}
-
-static ssize_t get_alarms(struct device *dev, char *buf)
-{
-	struct smsc47m1_data *data = smsc47m1_update_device(dev, 0);
-	return sprintf(buf, "%d\n", data->alarms);
-}
-
-static ssize_t set_fan_min(struct device *dev, const char *buf,
-		size_t count, int nr)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct smsc47m1_data *data = i2c_get_clientdata(client);
-	long rpmdiv, val = simple_strtol(buf, NULL, 10);
-
-	down(&data->update_lock);
-	rpmdiv = val * DIV_FROM_REG(data->fan_div[nr]);
-
-	if (983040 > 192 * rpmdiv || 2 * rpmdiv > 983040) {
-		up(&data->update_lock);
-		return -EINVAL;
-	}
-
-	data->fan_preload[nr] = 192 - ((983040 + rpmdiv / 2) / rpmdiv);
-	smsc47m1_write_value(client, SMSC47M1_REG_FAN_PRELOAD(nr),
-			     data->fan_preload[nr]);
-	up(&data->update_lock);
-
-	return count;
-}
-
-/* Note: we save and restore the fan minimum here, because its value is
-   determined in part by the fan clock divider.  This follows the principle
-   of least suprise; the user doesn't expect the fan minimum to change just
-   because the divider changed. */
-static ssize_t set_fan_div(struct device *dev, const char *buf,
-		size_t count, int nr)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct smsc47m1_data *data = i2c_get_clientdata(client);
-
-	long new_div = simple_strtol(buf, NULL, 10), tmp;
-	u8 old_div = DIV_FROM_REG(data->fan_div[nr]);
-
-	if (new_div == old_div) /* No change */
-		return count;
-
-	down(&data->update_lock);
-	switch (new_div) {
-	case 1: data->fan_div[nr] = 0; break;
-	case 2: data->fan_div[nr] = 1; break;
-	case 4: data->fan_div[nr] = 2; break;
-	case 8: data->fan_div[nr] = 3; break;
-	default:
-		up(&data->update_lock);
-		return -EINVAL;
-	}
-
-	tmp = smsc47m1_read_value(client, SMSC47M1_REG_FANDIV) & 0x0F;
-	tmp |= (data->fan_div[0] << 4) | (data->fan_div[1] << 6);
-	smsc47m1_write_value(client, SMSC47M1_REG_FANDIV, tmp);
-
-	/* Preserve fan min */
-	tmp = 192 - (old_div * (192 - data->fan_preload[nr])
-		     + new_div / 2) / new_div;
-	data->fan_preload[nr] = SENSORS_LIMIT(tmp, 0, 191);
-	smsc47m1_write_value(client, SMSC47M1_REG_FAN_PRELOAD(nr),
-			     data->fan_preload[nr]);
-	up(&data->update_lock);
-
-	return count;
-}
-
-static ssize_t set_pwm(struct device *dev, const char *buf,
-		size_t count, int nr)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct smsc47m1_data *data = i2c_get_clientdata(client);
-
-	long val = simple_strtol(buf, NULL, 10);
-
-	if (val < 0 || val > 255)
-		return -EINVAL;
-
-	down(&data->update_lock);
-	data->pwm[nr] &= 0x81; /* Preserve additional bits */
-	data->pwm[nr] |= PWM_TO_REG(val);
-	smsc47m1_write_value(client, SMSC47M1_REG_PWM(nr),
-			     data->pwm[nr]);
-	up(&data->update_lock);
-
-	return count;
-}
-
-static ssize_t set_pwm_en(struct device *dev, const char *buf,
-		size_t count, int nr)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct smsc47m1_data *data = i2c_get_clientdata(client);
-
-	long val = simple_strtol(buf, NULL, 10);
-	
-	if (val != 0 && val != 1)
-		return -EINVAL;
-
-	down(&data->update_lock);
-	data->pwm[nr] &= 0xFE; /* preserve the other bits */
-	data->pwm[nr] |= !val;
-	smsc47m1_write_value(client, SMSC47M1_REG_PWM(nr),
-			     data->pwm[nr]);
-	up(&data->update_lock);
-
-	return count;
-}
-
-#define fan_present(offset)						\
-static ssize_t get_fan##offset (struct device *dev, char *buf)		\
-{									\
-	return get_fan(dev, buf, offset - 1);				\
-}									\
-static ssize_t get_fan##offset##_min (struct device *dev, char *buf)	\
-{									\
-	return get_fan_min(dev, buf, offset - 1);			\
-}									\
-static ssize_t set_fan##offset##_min (struct device *dev,		\
-		const char *buf, size_t count)				\
-{									\
-	return set_fan_min(dev, buf, count, offset - 1);		\
-}									\
-static ssize_t get_fan##offset##_div (struct device *dev, char *buf)	\
-{									\
-	return get_fan_div(dev, buf, offset - 1);			\
-}									\
-static ssize_t set_fan##offset##_div (struct device *dev,		\
-		const char *buf, size_t count)				\
-{									\
-	return set_fan_div(dev, buf, count, offset - 1);		\
-}									\
-static ssize_t get_pwm##offset (struct device *dev, char *buf)		\
-{									\
-	return get_pwm(dev, buf, offset - 1);				\
-}									\
-static ssize_t set_pwm##offset (struct device *dev,			\
-		const char *buf, size_t count)				\
-{									\
-	return set_pwm(dev, buf, count, offset - 1);			\
-}									\
-static ssize_t get_pwm##offset##_en (struct device *dev, char *buf)	\
-{									\
-	return get_pwm_en(dev, buf, offset - 1);			\
-}									\
-static ssize_t set_pwm##offset##_en (struct device *dev,		\
-		const char *buf, size_t count)				\
-{									\
-	return set_pwm_en(dev, buf, count, offset - 1);			\
-}									\
-static DEVICE_ATTR(fan##offset##_input, S_IRUGO, get_fan##offset,	\
-		NULL);							\
-static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR,		\
-		get_fan##offset##_min, set_fan##offset##_min);		\
-static DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR,		\
-		get_fan##offset##_div, set_fan##offset##_div);		\
-static DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR,			\
-		get_pwm##offset, set_pwm##offset);			\
-static DEVICE_ATTR(pwm##offset##_enable, S_IRUGO | S_IWUSR,		\
-		get_pwm##offset##_en, set_pwm##offset##_en);
-
-fan_present(1);
-fan_present(2);
-
-static DEVICE_ATTR(alarms, S_IRUGO, get_alarms, NULL);
-
-static int smsc47m1_attach_adapter(struct i2c_adapter *adapter)
-{
-	if (!(adapter->class & I2C_CLASS_HWMON))
-		return 0;
-	return i2c_detect(adapter, &addr_data, smsc47m1_detect);
-}
-
-static int smsc47m1_find(int *address)
-{
-	u8 val;
-
-	superio_enter();
-	val = superio_inb(SUPERIO_REG_DEVID);
-
-	/*
-	 * SMSC LPC47M10x/LPC47M13x (device id 0x59), LPC47M14x (device id
-	 * 0x5F) and LPC47B27x (device id 0x51) have fan control.
-	 * The LPC47M15x and LPC47M192 chips "with hardware monitoring block"
-	 * can do much more besides (device id 0x60, unsupported).
-	 */
-	if (val == 0x51)
-		printk(KERN_INFO "smsc47m1: Found SMSC47B27x\n");
-	else if (val == 0x59)
-		printk(KERN_INFO "smsc47m1: Found SMSC47M10x/SMSC47M13x\n");
-	else if (val == 0x5F)
-		printk(KERN_INFO "smsc47m1: Found SMSC47M14x\n");
-	else {
-		superio_exit();
-		return -ENODEV;
-	}
-
-	superio_select();
-	*address = (superio_inb(SUPERIO_REG_BASE) << 8)
-		 |  superio_inb(SUPERIO_REG_BASE + 1);
-	val = superio_inb(SUPERIO_REG_ACT);
-	if (*address == 0 || (val & 0x01) == 0) {
-		printk(KERN_INFO "smsc47m1: Device is disabled, will not use\n");
-		superio_exit();
-		return -ENODEV;
-	}
-
-	superio_exit();
-	return 0;
-}
-
-static int smsc47m1_detect(struct i2c_adapter *adapter, int address, int kind)
-{
-	struct i2c_client *new_client;
-	struct smsc47m1_data *data;
-	int err = 0;
-	int fan1, fan2, pwm1, pwm2;
-
-	if (!i2c_is_isa_adapter(adapter)) {
-		return 0;
-	}
-
-	if (!request_region(address, SMSC_EXTENT, smsc47m1_driver.name)) {
-		dev_err(&adapter->dev, "Region 0x%x already in use!\n", address);
-		return -EBUSY;
-	}
-
-	if (!(data = kmalloc(sizeof(struct smsc47m1_data), GFP_KERNEL))) {
-		err = -ENOMEM;
-		goto error_release;
-	}
-	memset(data, 0x00, sizeof(struct smsc47m1_data));
-
-	new_client = &data->client;
-	i2c_set_clientdata(new_client, data);
-	new_client->addr = address;
-	init_MUTEX(&data->lock);
-	new_client->adapter = adapter;
-	new_client->driver = &smsc47m1_driver;
-	new_client->flags = 0;
-
-	strlcpy(new_client->name, "smsc47m1", I2C_NAME_SIZE);
-	init_MUTEX(&data->update_lock);
-
-	/* If no function is properly configured, there's no point in
-	   actually registering the chip. */
-	fan1 = (smsc47m1_read_value(new_client, SMSC47M1_REG_TPIN(0)) & 0x05)
-	       == 0x05;
-	fan2 = (smsc47m1_read_value(new_client, SMSC47M1_REG_TPIN(1)) & 0x05)
-	       == 0x05;
-	pwm1 = (smsc47m1_read_value(new_client, SMSC47M1_REG_PPIN(0)) & 0x05)
-	       == 0x04;
-	pwm2 = (smsc47m1_read_value(new_client, SMSC47M1_REG_PPIN(1)) & 0x05)
-	       == 0x04;
-	if (!(fan1 || fan2 || pwm1 || pwm2)) {
-		dev_warn(&new_client->dev, "Device is not configured, will not use\n");
-		err = -ENODEV;
-		goto error_free;
-	}
-
-	if ((err = i2c_attach_client(new_client)))
-		goto error_free;
-
-	/* Some values (fan min, clock dividers, pwm registers) may be
-	   needed before any update is triggered, so we better read them
-	   at least once here. We don't usually do it that way, but in
-	   this particular case, manually reading 5 registers out of 8
-	   doesn't make much sense and we're better using the existing
-	   function. */
-	smsc47m1_update_device(&new_client->dev, 1);
-
-	if (fan1) {
-		device_create_file(&new_client->dev, &dev_attr_fan1_input);
-		device_create_file(&new_client->dev, &dev_attr_fan1_min);
-		device_create_file(&new_client->dev, &dev_attr_fan1_div);
-	} else
-		dev_dbg(&new_client->dev, "Fan 1 not enabled by hardware, "
-			"skipping\n");
-
-	if (fan2) {
-		device_create_file(&new_client->dev, &dev_attr_fan2_input);
-		device_create_file(&new_client->dev, &dev_attr_fan2_min);
-		device_create_file(&new_client->dev, &dev_attr_fan2_div);
-	} else
-		dev_dbg(&new_client->dev, "Fan 2 not enabled by hardware, "
-			"skipping\n");
-
-	if (pwm1) {
-		device_create_file(&new_client->dev, &dev_attr_pwm1);
-		device_create_file(&new_client->dev, &dev_attr_pwm1_enable);
-	} else
-		dev_dbg(&new_client->dev, "PWM 1 not enabled by hardware, "
-			"skipping\n");
-	if (pwm2) {
-		device_create_file(&new_client->dev, &dev_attr_pwm2);
-		device_create_file(&new_client->dev, &dev_attr_pwm2_enable);
-	} else
-		dev_dbg(&new_client->dev, "PWM 2 not enabled by hardware, "
-			"skipping\n");
-
-	device_create_file(&new_client->dev, &dev_attr_alarms);
-
-	return 0;
-
-error_free:
-	kfree(new_client);
-error_release:
-	release_region(address, SMSC_EXTENT);
-	return err;
-}
-
-static int smsc47m1_detach_client(struct i2c_client *client)
-{
-	int err;
-
-	if ((err = i2c_detach_client(client))) {
-		dev_err(&client->dev, "Client deregistration failed, "
-			"client not detached.\n");
-		return err;
-	}
-
-	release_region(client->addr, SMSC_EXTENT);
-	kfree(i2c_get_clientdata(client));
-
-	return 0;
-}
-
-static int smsc47m1_read_value(struct i2c_client *client, u8 reg)
-{
-	int res;
-
-	down(&((struct smsc47m1_data *) i2c_get_clientdata(client))->lock);
-	res = inb_p(client->addr + reg);
-	up(&((struct smsc47m1_data *) i2c_get_clientdata(client))->lock);
-	return res;
-}
-
-static void smsc47m1_write_value(struct i2c_client *client, u8 reg, u8 value)
-{
-	down(&((struct smsc47m1_data *) i2c_get_clientdata(client))->lock);
-	outb_p(value, client->addr + reg);
-	up(&((struct smsc47m1_data *) i2c_get_clientdata(client))->lock);
-}
-
-static struct smsc47m1_data *smsc47m1_update_device(struct device *dev,
-		int init)
-{
- 	struct i2c_client *client = to_i2c_client(dev);
-	struct smsc47m1_data *data = i2c_get_clientdata(client);
-
-	down(&data->update_lock);
-
-	if (time_after(jiffies, data->last_updated + HZ + HZ / 2) || init) {
-		int i;
-
-		for (i = 0; i < 2; i++) {
-			data->fan[i] = smsc47m1_read_value(client,
-				       SMSC47M1_REG_FAN(i));
-			data->fan_preload[i] = smsc47m1_read_value(client,
-					       SMSC47M1_REG_FAN_PRELOAD(i));
-			data->pwm[i] = smsc47m1_read_value(client,
-				       SMSC47M1_REG_PWM(i));
-		}
-
-		i = smsc47m1_read_value(client, SMSC47M1_REG_FANDIV);
-		data->fan_div[0] = (i >> 4) & 0x03;
-		data->fan_div[1] = i >> 6;
-
-		data->alarms = smsc47m1_read_value(client,
-			       SMSC47M1_REG_ALARM) >> 6;
-		/* Clear alarms if needed */
-		if (data->alarms)
-			smsc47m1_write_value(client, SMSC47M1_REG_ALARM, 0xC0);
-
-		data->last_updated = jiffies;
-	}
-
-	up(&data->update_lock);
-	return data;
-}
-
-static int __init sm_smsc47m1_init(void)
-{
-	if (smsc47m1_find(normal_isa)) {
-		return -ENODEV;
-	}
-
-	return i2c_add_driver(&smsc47m1_driver);
-}
-
-static void __exit sm_smsc47m1_exit(void)
-{
-	i2c_del_driver(&smsc47m1_driver);
-}
-
-MODULE_AUTHOR("Mark D. Studebaker <mdsxyz123@yahoo.com>");
-MODULE_DESCRIPTION("SMSC LPC47M1xx fan sensors driver");
-MODULE_LICENSE("GPL");
-
-module_init(sm_smsc47m1_init);
-module_exit(sm_smsc47m1_exit);
diff --git a/drivers/i2c/chips/tps65010.c b/drivers/i2c/chips/tps65010.c
new file mode 100644
--- /dev/null
+++ b/drivers/i2c/chips/tps65010.c
@@ -0,0 +1,1069 @@
+/*
+ * tps65010 - driver for tps6501x power management chips
+ *
+ * Copyright (C) 2004 Texas Instruments
+ * Copyright (C) 2004-2005 David Brownell
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the 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 <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/device.h>
+#include <linux/i2c.h>
+#include <linux/delay.h>
+#include <linux/workqueue.h>
+#include <linux/suspend.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <asm/arch/gpio.h>
+#include <asm/arch/mux.h>
+#include <asm/arch/tps65010.h>
+
+/*-------------------------------------------------------------------------*/
+
+#define	DRIVER_VERSION	"2 May 2005"
+#define	DRIVER_NAME	(tps65010_driver.name)
+
+MODULE_DESCRIPTION("TPS6501x Power Management Driver");
+MODULE_LICENSE("GPL");
+
+static unsigned short normal_i2c[] = { 0x48, /* 0x49, */ I2C_CLIENT_END };
+static unsigned short normal_i2c_range[] = { I2C_CLIENT_END };
+
+I2C_CLIENT_INSMOD;
+
+static struct i2c_driver tps65010_driver;
+
+/*-------------------------------------------------------------------------*/
+
+/* This driver handles a family of multipurpose chips, which incorporate
+ * voltage regulators, lithium ion/polymer battery charging, GPIOs, LEDs,
+ * and other features often needed in portable devices like cell phones
+ * or digital cameras.
+ *
+ * The tps65011 and tps65013 have different voltage settings compared
+ * to tps65010 and tps65012.  The tps65013 has a NO_CHG status/irq.
+ * All except tps65010 have "wait" mode, possibly defaulted so that
+ * battery-insert != device-on.
+ *
+ * We could distinguish between some models by checking VDCDC1.UVLO or
+ * other registers, unless they've been changed already after powerup
+ * as part of board setup by a bootloader.
+ */
+enum tps_model {
+	TPS_UNKNOWN = 0,
+	TPS65010,
+	TPS65011,
+	TPS65012,
+	TPS65013,
+};
+
+struct tps65010 {
+	struct i2c_client	client;
+	struct semaphore	lock;
+	int			irq;
+	struct work_struct	work;
+	struct dentry		*file;
+	unsigned		charging:1;
+	unsigned		por:1;
+	unsigned		model:8;
+	u16			vbus;
+	unsigned long		flags;
+#define	FLAG_VBUS_CHANGED	0
+#define	FLAG_IRQ_ENABLE		1
+
+	/* copies of last register state */
+	u8			chgstatus, regstatus, chgconf;
+	u8			nmask1, nmask2;
+
+	/* not currently tracking GPIO state */
+};
+
+#define	POWER_POLL_DELAY	msecs_to_jiffies(800)
+
+/*-------------------------------------------------------------------------*/
+
+#if	defined(DEBUG) || defined(CONFIG_DEBUG_FS)
+
+static void dbg_chgstat(char *buf, size_t len, u8 chgstatus)
+{
+	snprintf(buf, len, "%02x%s%s%s%s%s%s%s%s\n",
+		chgstatus,
+		(chgstatus & TPS_CHG_USB) ? " USB" : "",
+		(chgstatus & TPS_CHG_AC) ? " AC" : "",
+		(chgstatus & TPS_CHG_THERM) ? " therm" : "",
+		(chgstatus & TPS_CHG_TERM) ? " done" :
+			((chgstatus & (TPS_CHG_USB|TPS_CHG_AC))
+				? " (charging)" : ""),
+		(chgstatus & TPS_CHG_TAPER_TMO) ? " taper_tmo" : "",
+		(chgstatus & TPS_CHG_CHG_TMO) ? " charge_tmo" : "",
+		(chgstatus & TPS_CHG_PRECHG_TMO) ? " prechg_tmo" : "",
+		(chgstatus & TPS_CHG_TEMP_ERR) ? " temp_err" : "");
+}
+
+static void dbg_regstat(char *buf, size_t len, u8 regstatus)
+{
+	snprintf(buf, len, "%02x %s%s%s%s%s%s%s%s\n",
+		regstatus,
+		(regstatus & TPS_REG_ONOFF) ? "off" : "(on)",
+		(regstatus & TPS_REG_COVER) ? " uncover" : "",
+		(regstatus & TPS_REG_UVLO) ? " UVLO" : "",
+		(regstatus & TPS_REG_NO_CHG) ? " NO_CHG" : "",
+		(regstatus & TPS_REG_PG_LD02) ? " ld02_bad" : "",
+		(regstatus & TPS_REG_PG_LD01) ? " ld01_bad" : "",
+		(regstatus & TPS_REG_PG_MAIN) ? " main_bad" : "",
+		(regstatus & TPS_REG_PG_CORE) ? " core_bad" : "");
+}
+
+static void dbg_chgconf(int por, char *buf, size_t len, u8 chgconfig)
+{
+	const char *hibit;
+
+	if (por)
+		hibit = (chgconfig & TPS_CHARGE_POR)
+				? "POR=69ms" : "POR=1sec";
+	else
+		hibit = (chgconfig & TPS65013_AUA) ? "AUA" : "";
+
+	snprintf(buf, len, "%02x %s%s%s AC=%d%% USB=%dmA %sCharge\n",
+		chgconfig, hibit,
+		(chgconfig & TPS_CHARGE_RESET) ? " reset" : "",
+		(chgconfig & TPS_CHARGE_FAST) ? " fast" : "",
+		({int p; switch ((chgconfig >> 3) & 3) {
+		case 3:		p = 100; break;
+		case 2:		p = 75; break;
+		case 1:		p = 50; break;
+		default:	p = 25; break;
+		}; p; }),
+		(chgconfig & TPS_VBUS_CHARGING)
+			? ((chgconfig & TPS_VBUS_500MA) ? 500 : 100)
+			: 0,
+		(chgconfig & TPS_CHARGE_ENABLE) ? "" : "No");
+}
+
+#endif
+
+#ifdef	DEBUG
+
+static void show_chgstatus(const char *label, u8 chgstatus)
+{
+	char buf [100];
+
+	dbg_chgstat(buf, sizeof buf, chgstatus);
+	pr_debug("%s: %s %s", DRIVER_NAME, label, buf);
+}
+
+static void show_regstatus(const char *label, u8 regstatus)
+{
+	char buf [100];
+
+	dbg_regstat(buf, sizeof buf, regstatus);
+	pr_debug("%s: %s %s", DRIVER_NAME, label, buf);
+}
+
+static void show_chgconfig(int por, const char *label, u8 chgconfig)
+{
+	char buf [100];
+
+	dbg_chgconf(por, buf, sizeof buf, chgconfig);
+	pr_debug("%s: %s %s", DRIVER_NAME, label, buf);
+}
+
+#else
+
+static inline void show_chgstatus(const char *label, u8 chgstatus) { }
+static inline void show_regstatus(const char *label, u8 chgstatus) { }
+static inline void show_chgconfig(int por, const char *label, u8 chgconfig) { }
+
+#endif
+
+#ifdef	CONFIG_DEBUG_FS
+
+static int dbg_show(struct seq_file *s, void *_)
+{
+	struct tps65010	*tps = s->private;
+	u8		value, v2;
+	unsigned	i;
+	char		buf[100];
+	const char	*chip;
+
+	switch (tps->model) {
+	case TPS65010:	chip = "tps65010"; break;
+	case TPS65011:	chip = "tps65011"; break;
+	case TPS65012:	chip = "tps65012"; break;
+	case TPS65013:	chip = "tps65013"; break;
+	default:	chip = NULL; break;
+	}
+	seq_printf(s, "driver  %s\nversion %s\nchip    %s\n\n",
+			DRIVER_NAME, DRIVER_VERSION, chip);
+
+	down(&tps->lock);
+
+	/* FIXME how can we tell whether a battery is present?
+	 * likely involves a charge gauging chip (like BQ26501).
+	 */
+
+	seq_printf(s, "%scharging\n\n", tps->charging ? "" : "(not) ");
+
+
+	/* registers for monitoring battery charging and status; note
+	 * that reading chgstat and regstat may ack IRQs...
+	 */
+	value = i2c_smbus_read_byte_data(&tps->client, TPS_CHGCONFIG);
+	dbg_chgconf(tps->por, buf, sizeof buf, value);
+	seq_printf(s, "chgconfig %s", buf);
+
+	value = i2c_smbus_read_byte_data(&tps->client, TPS_CHGSTATUS);
+	dbg_chgstat(buf, sizeof buf, value);
+	seq_printf(s, "chgstat   %s", buf);
+	value = i2c_smbus_read_byte_data(&tps->client, TPS_MASK1);
+	dbg_chgstat(buf, sizeof buf, value);
+	seq_printf(s, "mask1     %s", buf);
+	/* ignore ackint1 */
+
+	value = i2c_smbus_read_byte_data(&tps->client, TPS_REGSTATUS);
+	dbg_regstat(buf, sizeof buf, value);
+	seq_printf(s, "regstat   %s", buf);
+	value = i2c_smbus_read_byte_data(&tps->client, TPS_MASK2);
+	dbg_regstat(buf, sizeof buf, value);
+	seq_printf(s, "mask2     %s\n", buf);
+	/* ignore ackint2 */
+
+	(void) schedule_delayed_work(&tps->work, POWER_POLL_DELAY);
+
+
+	/* VMAIN voltage, enable lowpower, etc */
+	value = i2c_smbus_read_byte_data(&tps->client, TPS_VDCDC1);
+	seq_printf(s, "vdcdc1    %02x\n", value);
+
+	/* VCORE voltage, vibrator on/off */
+	value = i2c_smbus_read_byte_data(&tps->client, TPS_VDCDC2);
+	seq_printf(s, "vdcdc2    %02x\n", value);
+
+	/* both LD0s, and their lowpower behavior */
+	value = i2c_smbus_read_byte_data(&tps->client, TPS_VREGS1);
+	seq_printf(s, "vregs1    %02x\n\n", value);
+
+
+	/* LEDs and GPIOs */
+	value = i2c_smbus_read_byte_data(&tps->client, TPS_LED1_ON);
+	v2 = i2c_smbus_read_byte_data(&tps->client, TPS_LED1_PER);
+	seq_printf(s, "led1 %s, on=%02x, per=%02x, %d/%d msec\n",
+		(value & 0x80)
+			? ((v2 & 0x80) ? "on" : "off")
+			: ((v2 & 0x80) ? "blink" : "(nPG)"),
+		value, v2,
+		(value & 0x7f) * 10, (v2 & 0x7f) * 100);
+
+	value = i2c_smbus_read_byte_data(&tps->client, TPS_LED2_ON);
+	v2 = i2c_smbus_read_byte_data(&tps->client, TPS_LED2_PER);
+	seq_printf(s, "led2 %s, on=%02x, per=%02x, %d/%d msec\n",
+		(value & 0x80)
+			? ((v2 & 0x80) ? "on" : "off")
+			: ((v2 & 0x80) ? "blink" : "off"),
+		value, v2,
+		(value & 0x7f) * 10, (v2 & 0x7f) * 100);
+
+	value = i2c_smbus_read_byte_data(&tps->client, TPS_DEFGPIO);
+	v2 = i2c_smbus_read_byte_data(&tps->client, TPS_MASK3);
+	seq_printf(s, "defgpio %02x mask3 %02x\n", value, v2);
+
+	for (i = 0; i < 4; i++) {
+		if (value & (1 << (4 + i)))
+			seq_printf(s, "  gpio%d-out %s\n", i + 1,
+				(value & (1 << i)) ? "low" : "hi ");
+		else
+			seq_printf(s, "  gpio%d-in  %s %s %s\n", i + 1,
+				(value & (1 << i)) ? "hi " : "low",
+				(v2 & (1 << i)) ? "no-irq" : "irq",
+				(v2 & (1 << (4 + i))) ? "rising" : "falling");
+	}
+
+	up(&tps->lock);
+	return 0;
+}
+
+static int dbg_tps_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, dbg_show, inode->u.generic_ip);
+}
+
+static struct file_operations debug_fops = {
+	.open		= dbg_tps_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+#define	DEBUG_FOPS	&debug_fops
+
+#else
+#define	DEBUG_FOPS	NULL
+#endif
+
+/*-------------------------------------------------------------------------*/
+
+/* handle IRQS in a task context, so we can use I2C calls */
+static void tps65010_interrupt(struct tps65010 *tps)
+{
+	u8 tmp = 0, mask, poll;
+
+	/* IRQs won't trigger irqs for certain events, but we can get
+	 * others by polling (normally, with external power applied).
+	 */
+	poll = 0;
+
+	/* regstatus irqs */
+	if (tps->nmask2) {
+		tmp = i2c_smbus_read_byte_data(&tps->client, TPS_REGSTATUS);
+		mask = tmp ^ tps->regstatus;
+		tps->regstatus = tmp;
+		mask &= tps->nmask2;
+	} else
+		mask = 0;
+	if (mask) {
+		tps->regstatus =  tmp;
+		/* may need to shut something down ... */
+
+		/* "off" usually means deep sleep */
+		if (tmp & TPS_REG_ONOFF) {
+			pr_info("%s: power off button\n", DRIVER_NAME);
+#if 0
+			/* REVISIT:  this might need its own workqueue
+			 * plus tweaks including deadlock avoidance ...
+			 */
+			software_suspend();
+#endif
+			poll = 1;
+		}
+	}
+
+	/* chgstatus irqs */
+	if (tps->nmask1) {
+		tmp = i2c_smbus_read_byte_data(&tps->client, TPS_CHGSTATUS);
+		mask = tmp ^ tps->chgstatus;
+		tps->chgstatus = tmp;
+		mask &= tps->nmask1;
+	} else
+		mask = 0;
+	if (mask) {
+		unsigned	charging = 0;
+
+		show_chgstatus("chg/irq", tmp);
+		if (tmp & (TPS_CHG_USB|TPS_CHG_AC))
+			show_chgconfig(tps->por, "conf", tps->chgconf);
+
+		/* Unless it was turned off or disabled, we charge any
+		 * battery whenever there's power available for it
+		 * and the charger hasn't been disabled.
+		 */
+		if (!(tps->chgstatus & ~(TPS_CHG_USB|TPS_CHG_AC))
+				&& (tps->chgstatus & (TPS_CHG_USB|TPS_CHG_AC))
+				&& (tps->chgconf & TPS_CHARGE_ENABLE)
+				) {
+			if (tps->chgstatus & TPS_CHG_USB) {
+				/* VBUS options are readonly until reconnect */
+				if (mask & TPS_CHG_USB)
+					set_bit(FLAG_VBUS_CHANGED, &tps->flags);
+				charging = 1;
+			} else if (tps->chgstatus & TPS_CHG_AC)
+				charging = 1;
+		}
+		if (charging != tps->charging) {
+			tps->charging = charging;
+			pr_info("%s: battery %scharging\n",
+				DRIVER_NAME, charging ? "" :
+				((tps->chgstatus & (TPS_CHG_USB|TPS_CHG_AC))
+					? "NOT " : "dis"));
+		}
+	}
+
+	/* always poll to detect (a) power removal, without tps65013
+	 * NO_CHG IRQ; or (b) restart of charging after stop.
+	 */
+	if ((tps->model != TPS65013 || !tps->charging)
+			&& (tps->chgstatus & (TPS_CHG_USB|TPS_CHG_AC)))
+		poll = 1;
+	if (poll)
+		(void) schedule_delayed_work(&tps->work, POWER_POLL_DELAY);
+
+	/* also potentially gpio-in rise or fall */
+}
+
+/* handle IRQs and polling using keventd for now */
+static void tps65010_work(void *_tps)
+{
+	struct tps65010		*tps = _tps;
+
+	down(&tps->lock);
+
+	tps65010_interrupt(tps);
+
+	if (test_and_clear_bit(FLAG_VBUS_CHANGED, &tps->flags)) {
+		int	status;
+		u8	chgconfig, tmp;
+
+		chgconfig = i2c_smbus_read_byte_data(&tps->client,
+					TPS_CHGCONFIG);
+		chgconfig &= ~(TPS_VBUS_500MA | TPS_VBUS_CHARGING);
+		if (tps->vbus == 500)
+			chgconfig |= TPS_VBUS_500MA | TPS_VBUS_CHARGING;
+		else if (tps->vbus >= 100)
+			chgconfig |= TPS_VBUS_CHARGING;
+
+		status = i2c_smbus_write_byte_data(&tps->client,
+				TPS_CHGCONFIG, chgconfig);
+
+		/* vbus update fails unless VBUS is connected! */
+		tmp = i2c_smbus_read_byte_data(&tps->client, TPS_CHGCONFIG);
+		tps->chgconf = tmp;
+		show_chgconfig(tps->por, "update vbus", tmp);
+	}
+
+	if (test_and_clear_bit(FLAG_IRQ_ENABLE, &tps->flags))
+		enable_irq(tps->irq);
+
+	up(&tps->lock);
+}
+
+static irqreturn_t tps65010_irq(int irq, void *_tps, struct pt_regs *regs)
+{
+	struct tps65010		*tps = _tps;
+
+	disable_irq_nosync(irq);
+	set_bit(FLAG_IRQ_ENABLE, &tps->flags);
+	(void) schedule_work(&tps->work);
+	return IRQ_HANDLED;
+}
+
+/*-------------------------------------------------------------------------*/
+
+static struct tps65010 *the_tps;
+
+static int __exit tps65010_detach_client(struct i2c_client *client)
+{
+	struct tps65010		*tps;
+
+	tps = container_of(client, struct tps65010, client);
+#ifdef	CONFIG_ARM
+	if (machine_is_omap_h2())
+		omap_free_gpio(58);
+	if (machine_is_omap_osk())
+		omap_free_gpio(OMAP_MPUIO(1));
+#endif
+	free_irq(tps->irq, tps);
+	debugfs_remove(tps->file);
+	if (i2c_detach_client(client) == 0)
+		kfree(tps);
+	the_tps = NULL;
+	return 0;
+}
+
+static int tps65010_noscan(struct i2c_adapter *bus)
+{
+	/* pure paranoia, in case someone adds another i2c bus
+	 * after our init section's gone...
+	 */
+	return -ENODEV;
+}
+
+/* no error returns, they'd just make bus scanning stop */
+static int __init
+tps65010_probe(struct i2c_adapter *bus, int address, int kind)
+{
+	struct tps65010		*tps;
+	int			status;
+
+	if (the_tps) {
+		dev_dbg(&bus->dev, "only one %s for now\n", DRIVER_NAME);
+		return 0;
+	}
+
+	tps = kmalloc(sizeof *tps, GFP_KERNEL);
+	if (!tps)
+		return 0;
+
+	memset(tps, 0, sizeof *tps);
+	init_MUTEX(&tps->lock);
+	INIT_WORK(&tps->work, tps65010_work, tps);
+	tps->irq = -1;
+	tps->client.addr = address;
+	tps->client.adapter = bus;
+	tps->client.driver = &tps65010_driver;
+	strlcpy(tps->client.name, DRIVER_NAME, I2C_NAME_SIZE);
+
+	status = i2c_attach_client(&tps->client);
+	if (status < 0) {
+		dev_dbg(&bus->dev, "can't attach %s to device %d, err %d\n",
+				DRIVER_NAME, address, status);
+		goto fail1;
+	}
+
+#ifdef	CONFIG_ARM
+	if (machine_is_omap_h2()) {
+		tps->model = TPS65010;
+		omap_cfg_reg(W4_GPIO58);
+		tps->irq = OMAP_GPIO_IRQ(58);
+		omap_request_gpio(58);
+		omap_set_gpio_direction(58, 1);
+		set_irq_type(tps->irq, IRQT_FALLING);
+	}
+	if (machine_is_omap_osk()) {
+		tps->model = TPS65010;
+		// omap_cfg_reg(U19_1610_MPUIO1);
+		tps->irq = OMAP_GPIO_IRQ(OMAP_MPUIO(1));
+		omap_request_gpio(OMAP_MPUIO(1));
+		omap_set_gpio_direction(OMAP_MPUIO(1), 1);
+		set_irq_type(tps->irq, IRQT_FALLING);
+	}
+	if (machine_is_omap_h3()) {
+		tps->model = TPS65013;
+
+		// FIXME set up this board's IRQ ...
+	}
+#else
+#define set_irq_type(num,trigger)	do{}while(0)
+#endif
+
+	if (tps->irq > 0) {
+		set_irq_type(tps->irq, IRQT_LOW);
+		status = request_irq(tps->irq, tps65010_irq,
+			SA_SAMPLE_RANDOM, DRIVER_NAME, tps);
+		if (status < 0) {
+			dev_dbg(&tps->client.dev, "can't get IRQ %d, err %d\n",
+					tps->irq, status);
+			i2c_detach_client(&tps->client);
+			goto fail1;
+		}
+#ifdef	CONFIG_ARM
+		/* annoying race here, ideally we'd have an option
+		 * to claim the irq now and enable it later.
+		 */
+		disable_irq(tps->irq);
+		set_bit(FLAG_IRQ_ENABLE, &tps->flags);
+#endif
+	} else
+		printk(KERN_WARNING "%s: IRQ not configured!\n",
+				DRIVER_NAME);
+
+
+	switch (tps->model) {
+	case TPS65010:
+	case TPS65012:
+		tps->por = 1;
+		break;
+	case TPS_UNKNOWN:
+		printk(KERN_WARNING "%s: unknown TPS chip\n", DRIVER_NAME);
+		break;
+	/* else CHGCONFIG.POR is replaced by AUA, enabling a WAIT mode */
+	}
+	tps->chgconf = i2c_smbus_read_byte_data(&tps->client, TPS_CHGCONFIG);
+	show_chgconfig(tps->por, "conf/init", tps->chgconf);
+
+	show_chgstatus("chg/init",
+		i2c_smbus_read_byte_data(&tps->client, TPS_CHGSTATUS));
+	show_regstatus("reg/init",
+		i2c_smbus_read_byte_data(&tps->client, TPS_REGSTATUS));
+
+	pr_debug("%s: vdcdc1 0x%02x, vdcdc2 %02x, vregs1 %02x\n", DRIVER_NAME,
+		i2c_smbus_read_byte_data(&tps->client, TPS_VDCDC1),
+		i2c_smbus_read_byte_data(&tps->client, TPS_VDCDC2),
+		i2c_smbus_read_byte_data(&tps->client, TPS_VREGS1));
+	pr_debug("%s: defgpio 0x%02x, mask3 0x%02x\n", DRIVER_NAME,
+		i2c_smbus_read_byte_data(&tps->client, TPS_DEFGPIO),
+		i2c_smbus_read_byte_data(&tps->client, TPS_MASK3));
+
+	tps65010_driver.attach_adapter = tps65010_noscan;
+	the_tps = tps;
+
+#if	defined(CONFIG_USB_GADGET) && !defined(CONFIG_USB_OTG)
+	/* USB hosts can't draw VBUS.  OTG devices could, later
+	 * when OTG infrastructure enables it.  USB peripherals
+	 * could be relying on VBUS while booting, though.
+	 */
+	tps->vbus = 100;
+#endif
+
+	/* unmask the "interesting" irqs, then poll once to
+	 * kickstart monitoring, initialize shadowed status
+	 * registers, and maybe disable VBUS draw.
+	 */
+	tps->nmask1 = ~0;
+	(void) i2c_smbus_write_byte_data(&tps->client, TPS_MASK1, ~tps->nmask1);
+
+	tps->nmask2 = TPS_REG_ONOFF;
+	if (tps->model == TPS65013)
+		tps->nmask2 |= TPS_REG_NO_CHG;
+	(void) i2c_smbus_write_byte_data(&tps->client, TPS_MASK2, ~tps->nmask2);
+
+	(void) i2c_smbus_write_byte_data(&tps->client, TPS_MASK3, 0x0f
+		| i2c_smbus_read_byte_data(&tps->client, TPS_MASK3));
+
+	tps65010_work(tps);
+
+	tps->file = debugfs_create_file(DRIVER_NAME, S_IRUGO, NULL,
+				tps, DEBUG_FOPS);
+	return 0;
+fail1:
+	kfree(tps);
+	return 0;
+}
+
+static int __init tps65010_scan_bus(struct i2c_adapter *bus)
+{
+	if (!i2c_check_functionality(bus, I2C_FUNC_SMBUS_BYTE_DATA))
+		return -EINVAL;
+	return i2c_probe(bus, &addr_data, tps65010_probe);
+}
+
+static struct i2c_driver tps65010_driver = {
+	.owner		= THIS_MODULE,
+	.name		= "tps65010",
+	.flags		= I2C_DF_NOTIFY,
+	.attach_adapter	= tps65010_scan_bus,
+	.detach_client	= __exit_p(tps65010_detach_client),
+};
+
+/*-------------------------------------------------------------------------*/
+
+/* Draw from VBUS:
+ *   0 mA -- DON'T DRAW (might supply power instead)
+ * 100 mA -- usb unit load (slowest charge rate)
+ * 500 mA -- usb high power (fast battery charge)
+ */
+int tps65010_set_vbus_draw(unsigned mA)
+{
+	unsigned long	flags;
+
+	if (!the_tps)
+		return -ENODEV;
+
+	/* assumes non-SMP */
+	local_irq_save(flags);
+	if (mA >= 500)
+		mA = 500;
+	else if (mA >= 100)
+		mA = 100;
+	else
+		mA = 0;
+	the_tps->vbus = mA;
+	if ((the_tps->chgstatus & TPS_CHG_USB)
+			&& test_and_set_bit(
+				FLAG_VBUS_CHANGED, &the_tps->flags)) {
+		/* gadget drivers call this in_irq() */
+		(void) schedule_work(&the_tps->work);
+	}
+	local_irq_restore(flags);
+
+	return 0;
+}
+EXPORT_SYMBOL(tps65010_set_vbus_draw);
+
+/*-------------------------------------------------------------------------*/
+/* tps65010_set_gpio_out_value parameter:
+ * gpio:  GPIO1, GPIO2, GPIO3 or GPIO4
+ * value: LOW or HIGH
+ */
+int tps65010_set_gpio_out_value(unsigned gpio, unsigned value)
+{
+	int	 status;
+	unsigned defgpio;
+
+	if (!the_tps)
+		return -ENODEV;
+	if ((gpio < GPIO1) || (gpio > GPIO4))
+		return -EINVAL;
+
+	down(&the_tps->lock);
+
+	defgpio = i2c_smbus_read_byte_data(&the_tps->client, TPS_DEFGPIO);
+
+	/* Configure GPIO for output */
+	defgpio |= 1 << (gpio + 3);
+
+	/* Writing 1 forces a logic 0 on that GPIO and vice versa */
+	switch (value) {
+	case LOW:
+		defgpio |= 1 << (gpio - 1);    /* set GPIO low by writing 1 */
+		break;
+	/* case HIGH: */
+	default:
+		defgpio &= ~(1 << (gpio - 1)); /* set GPIO high by writing 0 */
+		break;
+	}
+
+	status = i2c_smbus_write_byte_data(&the_tps->client,
+		TPS_DEFGPIO, defgpio);
+
+	pr_debug("%s: gpio%dout = %s, defgpio 0x%02x\n", DRIVER_NAME,
+		gpio, value ? "high" : "low",
+		i2c_smbus_read_byte_data(&the_tps->client, TPS_DEFGPIO));
+
+	up(&the_tps->lock);
+	return status;
+}
+EXPORT_SYMBOL(tps65010_set_gpio_out_value);
+
+/*-------------------------------------------------------------------------*/
+/* tps65010_set_led parameter:
+ * led:  LED1 or LED2
+ * mode: ON, OFF or BLINK
+ */
+int tps65010_set_led(unsigned led, unsigned mode)
+{
+	int	 status;
+	unsigned led_on, led_per, offs;
+
+	if (!the_tps)
+		return -ENODEV;
+
+	if (led == LED1)
+		offs = 0;
+	else {
+		offs = 2;
+		led = LED2;
+	}
+
+	down(&the_tps->lock);
+
+	pr_debug("%s: led%i_on   0x%02x\n", DRIVER_NAME, led,
+		i2c_smbus_read_byte_data(&the_tps->client,
+				TPS_LED1_ON + offs));
+
+	pr_debug("%s: led%i_per  0x%02x\n", DRIVER_NAME, led,
+		i2c_smbus_read_byte_data(&the_tps->client,
+				TPS_LED1_PER + offs));
+
+	switch (mode) {
+	case OFF:
+		led_on  = 1 << 7;
+		led_per = 0 << 7;
+		break;
+	case ON:
+		led_on  = 1 << 7;
+		led_per = 1 << 7;
+		break;
+	case BLINK:
+		led_on  = 0x30 | (0 << 7);
+		led_per = 0x08 | (1 << 7);
+		break;
+	default:
+		printk(KERN_ERR "%s: Wrong mode parameter for set_led()\n",
+		       DRIVER_NAME);
+		up(&the_tps->lock);
+		return -EINVAL;
+	}
+
+	status = i2c_smbus_write_byte_data(&the_tps->client,
+			TPS_LED1_ON + offs, led_on);
+
+	if (status != 0) {
+		printk(KERN_ERR "%s: Failed to write led%i_on register\n",
+		       DRIVER_NAME, led);
+		up(&the_tps->lock);
+		return status;
+	}
+
+	pr_debug("%s: led%i_on   0x%02x\n", DRIVER_NAME, led,
+		i2c_smbus_read_byte_data(&the_tps->client, TPS_LED1_ON + offs));
+
+	status = i2c_smbus_write_byte_data(&the_tps->client,
+			TPS_LED1_PER + offs, led_per);
+
+	if (status != 0) {
+		printk(KERN_ERR "%s: Failed to write led%i_per register\n",
+		       DRIVER_NAME, led);
+		up(&the_tps->lock);
+		return status;
+	}
+
+	pr_debug("%s: led%i_per  0x%02x\n", DRIVER_NAME, led,
+		i2c_smbus_read_byte_data(&the_tps->client,
+				TPS_LED1_PER + offs));
+
+	up(&the_tps->lock);
+
+	return status;
+}
+EXPORT_SYMBOL(tps65010_set_led);
+
+/*-------------------------------------------------------------------------*/
+/* tps65010_set_vib parameter:
+ * value: ON or OFF
+ */
+int tps65010_set_vib(unsigned value)
+{
+	int	 status;
+	unsigned vdcdc2;
+
+	if (!the_tps)
+		return -ENODEV;
+
+	down(&the_tps->lock);
+
+	vdcdc2 = i2c_smbus_read_byte_data(&the_tps->client, TPS_VDCDC2);
+	vdcdc2 &= ~(1 << 1);
+	if (value)
+		vdcdc2 |= (1 << 1);
+	status = i2c_smbus_write_byte_data(&the_tps->client,
+		TPS_VDCDC2, vdcdc2);
+
+	pr_debug("%s: vibrator %s\n", DRIVER_NAME, value ? "on" : "off");
+
+	up(&the_tps->lock);
+	return status;
+}
+EXPORT_SYMBOL(tps65010_set_vib);
+
+/*-------------------------------------------------------------------------*/
+/* tps65010_set_low_pwr parameter:
+ * mode: ON or OFF
+ */
+int tps65010_set_low_pwr(unsigned mode)
+{
+	int	 status;
+	unsigned vdcdc1;
+
+	if (!the_tps)
+		return -ENODEV;
+
+	down(&the_tps->lock);
+
+	pr_debug("%s: %s low_pwr, vdcdc1 0x%02x\n", DRIVER_NAME,
+		mode ? "enable" : "disable",
+		i2c_smbus_read_byte_data(&the_tps->client, TPS_VDCDC1));
+
+	vdcdc1 = i2c_smbus_read_byte_data(&the_tps->client, TPS_VDCDC1);
+
+	switch (mode) {
+	case OFF:
+		vdcdc1 &= ~TPS_ENABLE_LP; /* disable ENABLE_LP bit */
+		break;
+	/* case ON: */
+	default:
+		vdcdc1 |= TPS_ENABLE_LP;  /* enable ENABLE_LP bit */
+		break;
+	}
+
+	status = i2c_smbus_write_byte_data(&the_tps->client,
+			TPS_VDCDC1, vdcdc1);
+
+	if (status != 0)
+		printk(KERN_ERR "%s: Failed to write vdcdc1 register\n",
+			DRIVER_NAME);
+	else
+		pr_debug("%s: vdcdc1 0x%02x\n", DRIVER_NAME,
+			i2c_smbus_read_byte_data(&the_tps->client, TPS_VDCDC1));
+
+	up(&the_tps->lock);
+
+	return status;
+}
+EXPORT_SYMBOL(tps65010_set_low_pwr);
+
+/*-------------------------------------------------------------------------*/
+/* tps65010_config_vregs1 parameter:
+ * value to be written to VREGS1 register
+ * Note: The complete register is written, set all bits you need
+ */
+int tps65010_config_vregs1(unsigned value)
+{
+	int	 status;
+
+	if (!the_tps)
+		return -ENODEV;
+
+	down(&the_tps->lock);
+
+	pr_debug("%s: vregs1 0x%02x\n", DRIVER_NAME,
+			i2c_smbus_read_byte_data(&the_tps->client, TPS_VREGS1));
+
+	status = i2c_smbus_write_byte_data(&the_tps->client,
+			TPS_VREGS1, value);
+
+	if (status != 0)
+		printk(KERN_ERR "%s: Failed to write vregs1 register\n",
+			DRIVER_NAME);
+	else
+		pr_debug("%s: vregs1 0x%02x\n", DRIVER_NAME,
+			i2c_smbus_read_byte_data(&the_tps->client, TPS_VREGS1));
+
+	up(&the_tps->lock);
+
+	return status;
+}
+EXPORT_SYMBOL(tps65010_config_vregs1);
+
+/*-------------------------------------------------------------------------*/
+/* tps65013_set_low_pwr parameter:
+ * mode: ON or OFF
+ */
+
+/* FIXME: Assumes AC or USB power is present. Setting AUA bit is not
+	required if power supply is through a battery */
+
+int tps65013_set_low_pwr(unsigned mode)
+{
+	int	 status;
+	unsigned vdcdc1, chgconfig;
+
+	if (!the_tps || the_tps->por)
+		return -ENODEV;
+
+	down(&the_tps->lock);
+
+	pr_debug("%s: %s low_pwr, chgconfig 0x%02x vdcdc1 0x%02x\n",
+		DRIVER_NAME,
+		mode ? "enable" : "disable",
+		i2c_smbus_read_byte_data(&the_tps->client, TPS_CHGCONFIG),
+		i2c_smbus_read_byte_data(&the_tps->client, TPS_VDCDC1));
+
+	chgconfig = i2c_smbus_read_byte_data(&the_tps->client, TPS_CHGCONFIG);
+	vdcdc1 = i2c_smbus_read_byte_data(&the_tps->client, TPS_VDCDC1);
+
+	switch (mode) {
+	case OFF:
+		chgconfig &= ~TPS65013_AUA; /* disable AUA bit */
+		vdcdc1 &= ~TPS_ENABLE_LP; /* disable ENABLE_LP bit */
+		break;
+	/* case ON: */
+	default:
+		chgconfig |= TPS65013_AUA;  /* enable AUA bit */
+		vdcdc1 |= TPS_ENABLE_LP;  /* enable ENABLE_LP bit */
+		break;
+	}
+
+	status = i2c_smbus_write_byte_data(&the_tps->client,
+			TPS_CHGCONFIG, chgconfig);
+	if (status != 0) {
+		printk(KERN_ERR "%s: Failed to write chconfig register\n",
+	 DRIVER_NAME);
+		up(&the_tps->lock);
+		return status;
+	}
+
+	chgconfig = i2c_smbus_read_byte_data(&the_tps->client, TPS_CHGCONFIG);
+	the_tps->chgconf = chgconfig;
+	show_chgconfig(0, "chgconf", chgconfig);
+
+	status = i2c_smbus_write_byte_data(&the_tps->client,
+			TPS_VDCDC1, vdcdc1);
+
+	if (status != 0)
+		printk(KERN_ERR "%s: Failed to write vdcdc1 register\n",
+	 DRIVER_NAME);
+	else
+		pr_debug("%s: vdcdc1 0x%02x\n", DRIVER_NAME,
+			i2c_smbus_read_byte_data(&the_tps->client, TPS_VDCDC1));
+
+	up(&the_tps->lock);
+
+	return status;
+}
+EXPORT_SYMBOL(tps65013_set_low_pwr);
+
+/*-------------------------------------------------------------------------*/
+
+static int __init tps_init(void)
+{
+	u32	tries = 3;
+	int	status = -ENODEV;
+
+	printk(KERN_INFO "%s: version %s\n", DRIVER_NAME, DRIVER_VERSION);
+
+	/* some boards have startup glitches */
+	while (tries--) {
+		status = i2c_add_driver(&tps65010_driver);
+		if (the_tps)
+			break;
+		i2c_del_driver(&tps65010_driver);
+		if (!tries) {
+			printk(KERN_ERR "%s: no chip?\n", DRIVER_NAME);
+			return -ENODEV;
+		}
+		pr_debug("%s: re-probe ...\n", DRIVER_NAME);
+		msleep(10);
+	}
+
+#ifdef	CONFIG_ARM
+	if (machine_is_omap_osk()) {
+
+		// FIXME: More should be placed in the initialization code
+		//	  of the submodules (DSP, ethernet, power management,
+		//	  board-osk.c). Careful: I2C is initialized "late".
+
+		/* Let LED1 (D9) blink */
+		tps65010_set_led(LED1, BLINK);
+
+		/* Disable LED 2 (D2) */
+		tps65010_set_led(LED2, OFF);
+
+		/* Set GPIO 1 HIGH to disable VBUS power supply;
+		 * OHCI driver powers it up/down as needed.
+		 */
+		tps65010_set_gpio_out_value(GPIO1, HIGH);
+
+		/* Set GPIO 2 low to turn on LED D3 */
+		tps65010_set_gpio_out_value(GPIO2, HIGH);
+
+		/* Set GPIO 3 low to take ethernet out of reset */
+		tps65010_set_gpio_out_value(GPIO3, LOW);
+
+		/* gpio4 for VDD_DSP */
+
+		/* Enable LOW_PWR */
+		tps65010_set_low_pwr(ON);
+
+		/* Switch VLDO2 to 3.0V for AIC23 */
+		tps65010_config_vregs1(TPS_LDO2_ENABLE | TPS_VLDO2_3_0V | TPS_LDO1_ENABLE);
+
+	} else if (machine_is_omap_h2()) {
+		/* gpio3 for SD, gpio4 for VDD_DSP */
+
+		/* Enable LOW_PWR */
+		tps65010_set_low_pwr(ON);
+	} else if (machine_is_omap_h3()) {
+		/* gpio4 for SD, gpio3 for VDD_DSP */
+#ifdef CONFIG_PM
+		/* Enable LOW_PWR */
+		tps65013_set_low_pwr(ON);
+#endif
+	}
+#endif
+
+	return status;
+}
+/* NOTE:  this MUST be initialized before the other parts of the system
+ * that rely on it ... but after the i2c bus on which this relies.
+ * That is, much earlier than on PC-type systems, which don't often use
+ * I2C as a core system bus.
+ */
+subsys_initcall(tps_init);
+
+static void __exit tps_exit(void)
+{
+	i2c_del_driver(&tps65010_driver);
+}
+module_exit(tps_exit);
+
diff --git a/drivers/i2c/chips/via686a.c b/drivers/i2c/chips/via686a.c
deleted file mode 100644
--- a/drivers/i2c/chips/via686a.c
+++ /dev/null
@@ -1,878 +0,0 @@
-/*
-    via686a.c - Part of lm_sensors, Linux kernel modules
-                for hardware monitoring
-                
-    Copyright (c) 1998 - 2002  Frodo Looijaard <frodol@dds.nl>,
-                        Kyösti Mälkki <kmalkki@cc.hut.fi>,
-			Mark Studebaker <mdsxyz123@yahoo.com>,
-			and Bob Dougherty <bobd@stanford.edu>
-    (Some conversion-factor data were contributed by Jonathan Teh Soon Yew 
-    <j.teh@iname.com> and Alex van Kaam <darkside@chello.nl>.)
-
-    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.
-*/
-
-/*
-    Supports the Via VT82C686A, VT82C686B south bridges.
-    Reports all as a 686A.
-    Warning - only supports a single device.
-*/
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/pci.h>
-#include <linux/delay.h>
-#include <linux/jiffies.h>
-#include <linux/i2c.h>
-#include <linux/i2c-sensor.h>
-#include <linux/init.h>
-#include <asm/io.h>
-
-
-/* If force_addr is set to anything different from 0, we forcibly enable
-   the device at the given address. */
-static unsigned short force_addr = 0;
-module_param(force_addr, ushort, 0);
-MODULE_PARM_DESC(force_addr,
-		 "Initialize the base address of the sensors");
-
-/* Addresses to scan.
-   Note that we can't determine the ISA address until we have initialized
-   our module */
-static unsigned short normal_i2c[] = { I2C_CLIENT_END };
-static unsigned int normal_isa[] = { 0x0000, I2C_CLIENT_ISA_END };
-
-/* Insmod parameters */
-SENSORS_INSMOD_1(via686a);
-
-/*
-   The Via 686a southbridge has a LM78-like chip integrated on the same IC.
-   This driver is a customized copy of lm78.c
-*/
-
-/* Many VIA686A constants specified below */
-
-/* Length of ISA address segment */
-#define VIA686A_EXTENT 0x80
-#define VIA686A_BASE_REG 0x70
-#define VIA686A_ENABLE_REG 0x74
-
-/* The VIA686A registers */
-/* ins numbered 0-4 */
-#define VIA686A_REG_IN_MAX(nr) (0x2b + ((nr) * 2))
-#define VIA686A_REG_IN_MIN(nr) (0x2c + ((nr) * 2))
-#define VIA686A_REG_IN(nr)     (0x22 + (nr))
-
-/* fans numbered 1-2 */
-#define VIA686A_REG_FAN_MIN(nr) (0x3a + (nr))
-#define VIA686A_REG_FAN(nr)     (0x28 + (nr))
-
-/* the following values are as speced by VIA: */
-static const u8 regtemp[] = { 0x20, 0x21, 0x1f };
-static const u8 regover[] = { 0x39, 0x3d, 0x1d };
-static const u8 reghyst[] = { 0x3a, 0x3e, 0x1e };
-
-/* temps numbered 1-3 */
-#define VIA686A_REG_TEMP(nr)		(regtemp[nr])
-#define VIA686A_REG_TEMP_OVER(nr)	(regover[nr])
-#define VIA686A_REG_TEMP_HYST(nr)	(reghyst[nr])
-#define VIA686A_REG_TEMP_LOW1	0x4b	// bits 7-6
-#define VIA686A_REG_TEMP_LOW23	0x49	// 2 = bits 5-4, 3 = bits 7-6
-
-#define VIA686A_REG_ALARM1 0x41
-#define VIA686A_REG_ALARM2 0x42
-#define VIA686A_REG_FANDIV 0x47
-#define VIA686A_REG_CONFIG 0x40
-/* The following register sets temp interrupt mode (bits 1-0 for temp1, 
- 3-2 for temp2, 5-4 for temp3).  Modes are:
-    00 interrupt stays as long as value is out-of-range
-    01 interrupt is cleared once register is read (default)
-    10 comparator mode- like 00, but ignores hysteresis
-    11 same as 00 */
-#define VIA686A_REG_TEMP_MODE 0x4b
-/* We'll just assume that you want to set all 3 simultaneously: */
-#define VIA686A_TEMP_MODE_MASK 0x3F
-#define VIA686A_TEMP_MODE_CONTINUOUS (0x00)
-
-/* Conversions. Limit checking is only done on the TO_REG
-   variants. 
-
-********* VOLTAGE CONVERSIONS (Bob Dougherty) ********
- From HWMon.cpp (Copyright 1998-2000 Jonathan Teh Soon Yew):
- voltagefactor[0]=1.25/2628; (2628/1.25=2102.4)   // Vccp
- voltagefactor[1]=1.25/2628; (2628/1.25=2102.4)   // +2.5V
- voltagefactor[2]=1.67/2628; (2628/1.67=1573.7)   // +3.3V
- voltagefactor[3]=2.6/2628;  (2628/2.60=1010.8)   // +5V
- voltagefactor[4]=6.3/2628;  (2628/6.30=417.14)   // +12V
- in[i]=(data[i+2]*25.0+133)*voltagefactor[i];
- That is:
- volts = (25*regVal+133)*factor
- regVal = (volts/factor-133)/25
- (These conversions were contributed by Jonathan Teh Soon Yew 
- <j.teh@iname.com>) */
-static inline u8 IN_TO_REG(long val, int inNum)
-{
-	/* To avoid floating point, we multiply constants by 10 (100 for +12V).
-	   Rounding is done (120500 is actually 133000 - 12500).
-	   Remember that val is expressed in 0.001V/bit, which is why we divide
-	   by an additional 10000 (100000 for +12V): 1000 for val and 10 (100)
-	   for the constants. */
-	if (inNum <= 1)
-		return (u8)
-		    SENSORS_LIMIT((val * 21024 - 1205000) / 250000, 0, 255);
-	else if (inNum == 2)
-		return (u8)
-		    SENSORS_LIMIT((val * 15737 - 1205000) / 250000, 0, 255);
-	else if (inNum == 3)
-		return (u8)
-		    SENSORS_LIMIT((val * 10108 - 1205000) / 250000, 0, 255);
-	else
-		return (u8)
-		    SENSORS_LIMIT((val * 41714 - 12050000) / 2500000, 0, 255);
-}
-
-static inline long IN_FROM_REG(u8 val, int inNum)
-{
-	/* To avoid floating point, we multiply constants by 10 (100 for +12V).
-	   We also multiply them by 1000 because we want 0.001V/bit for the
-	   output value. Rounding is done. */
-	if (inNum <= 1)
-		return (long) ((250000 * val + 1330000 + 21024 / 2) / 21024);
-	else if (inNum == 2)
-		return (long) ((250000 * val + 1330000 + 15737 / 2) / 15737);
-	else if (inNum == 3)
-		return (long) ((250000 * val + 1330000 + 10108 / 2) / 10108);
-	else
-		return (long) ((2500000 * val + 13300000 + 41714 / 2) / 41714);
-}
-
-/********* FAN RPM CONVERSIONS ********/
-/* Higher register values = slower fans (the fan's strobe gates a counter).
- But this chip saturates back at 0, not at 255 like all the other chips.
- So, 0 means 0 RPM */
-static inline u8 FAN_TO_REG(long rpm, int div)
-{
-	if (rpm == 0)
-		return 0;
-	rpm = SENSORS_LIMIT(rpm, 1, 1000000);
-	return SENSORS_LIMIT((1350000 + rpm * div / 2) / (rpm * div), 1, 255);
-}
-
-#define FAN_FROM_REG(val,div) ((val)==0?0:(val)==255?0:1350000/((val)*(div)))
-
-/******** TEMP CONVERSIONS (Bob Dougherty) *********/
-/* linear fits from HWMon.cpp (Copyright 1998-2000 Jonathan Teh Soon Yew)
-      if(temp<169)
-              return double(temp)*0.427-32.08;
-      else if(temp>=169 && temp<=202)
-              return double(temp)*0.582-58.16;
-      else
-              return double(temp)*0.924-127.33;
-
- A fifth-order polynomial fits the unofficial data (provided by Alex van 
- Kaam <darkside@chello.nl>) a bit better.  It also give more reasonable 
- numbers on my machine (ie. they agree with what my BIOS tells me).  
- Here's the fifth-order fit to the 8-bit data:
- temp = 1.625093e-10*val^5 - 1.001632e-07*val^4 + 2.457653e-05*val^3 - 
-        2.967619e-03*val^2 + 2.175144e-01*val - 7.090067e+0.
-
- (2000-10-25- RFD: thanks to Uwe Andersen <uandersen@mayah.com> for 
- finding my typos in this formula!)
-
- Alas, none of the elegant function-fit solutions will work because we 
- aren't allowed to use floating point in the kernel and doing it with 
- integers doesn't rpovide enough precision.  So we'll do boring old 
- look-up table stuff.  The unofficial data (see below) have effectively 
- 7-bit resolution (they are rounded to the nearest degree).  I'm assuming 
- that the transfer function of the device is monotonic and smooth, so a 
- smooth function fit to the data will allow us to get better precision.  
- I used the 5th-order poly fit described above and solved for
- VIA register values 0-255.  I *10 before rounding, so we get tenth-degree 
- precision.  (I could have done all 1024 values for our 10-bit readings, 
- but the function is very linear in the useful range (0-80 deg C), so 
- we'll just use linear interpolation for 10-bit readings.)  So, tempLUT 
- is the temp at via register values 0-255: */
-static const long tempLUT[] =
-    { -709, -688, -667, -646, -627, -607, -589, -570, -553, -536, -519,
-	    -503, -487, -471, -456, -442, -428, -414, -400, -387, -375,
-	    -362, -350, -339, -327, -316, -305, -295, -285, -275, -265,
-	    -255, -246, -237, -229, -220, -212, -204, -196, -188, -180,
-	    -173, -166, -159, -152, -145, -139, -132, -126, -120, -114,
-	    -108, -102, -96, -91, -85, -80, -74, -69, -64, -59, -54, -49,
-	    -44, -39, -34, -29, -25, -20, -15, -11, -6, -2, 3, 7, 12, 16,
-	    20, 25, 29, 33, 37, 42, 46, 50, 54, 59, 63, 67, 71, 75, 79, 84,
-	    88, 92, 96, 100, 104, 109, 113, 117, 121, 125, 130, 134, 138,
-	    142, 146, 151, 155, 159, 163, 168, 172, 176, 181, 185, 189,
-	    193, 198, 202, 206, 211, 215, 219, 224, 228, 232, 237, 241,
-	    245, 250, 254, 259, 263, 267, 272, 276, 281, 285, 290, 294,
-	    299, 303, 307, 312, 316, 321, 325, 330, 334, 339, 344, 348,
-	    353, 357, 362, 366, 371, 376, 380, 385, 390, 395, 399, 404,
-	    409, 414, 419, 423, 428, 433, 438, 443, 449, 454, 459, 464,
-	    469, 475, 480, 486, 491, 497, 502, 508, 514, 520, 526, 532,
-	    538, 544, 551, 557, 564, 571, 578, 584, 592, 599, 606, 614,
-	    621, 629, 637, 645, 654, 662, 671, 680, 689, 698, 708, 718,
-	    728, 738, 749, 759, 770, 782, 793, 805, 818, 830, 843, 856,
-	    870, 883, 898, 912, 927, 943, 958, 975, 991, 1008, 1026, 1044,
-	    1062, 1081, 1101, 1121, 1141, 1162, 1184, 1206, 1229, 1252,
-	    1276, 1301, 1326, 1352, 1378, 1406, 1434, 1462
-};
-
-/* the original LUT values from Alex van Kaam <darkside@chello.nl> 
-   (for via register values 12-240):
-{-50,-49,-47,-45,-43,-41,-39,-38,-37,-35,-34,-33,-32,-31,
--30,-29,-28,-27,-26,-25,-24,-24,-23,-22,-21,-20,-20,-19,-18,-17,-17,-16,-15,
--15,-14,-14,-13,-12,-12,-11,-11,-10,-9,-9,-8,-8,-7,-7,-6,-6,-5,-5,-4,-4,-3,
--3,-2,-2,-1,-1,0,0,1,1,1,3,3,3,4,4,4,5,5,5,6,6,7,7,8,8,9,9,9,10,10,11,11,12,
-12,12,13,13,13,14,14,15,15,16,16,16,17,17,18,18,19,19,20,20,21,21,21,22,22,
-22,23,23,24,24,25,25,26,26,26,27,27,27,28,28,29,29,30,30,30,31,31,32,32,33,
-33,34,34,35,35,35,36,36,37,37,38,38,39,39,40,40,41,41,42,42,43,43,44,44,45,
-45,46,46,47,48,48,49,49,50,51,51,52,52,53,53,54,55,55,56,57,57,58,59,59,60,
-61,62,62,63,64,65,66,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,83,84,
-85,86,88,89,91,92,94,96,97,99,101,103,105,107,109,110};
-
-
- Here's the reverse LUT.  I got it by doing a 6-th order poly fit (needed
- an extra term for a good fit to these inverse data!) and then 
- solving for each temp value from -50 to 110 (the useable range for 
- this chip).  Here's the fit: 
- viaRegVal = -1.160370e-10*val^6 +3.193693e-08*val^5 - 1.464447e-06*val^4 
- - 2.525453e-04*val^3 + 1.424593e-02*val^2 + 2.148941e+00*val +7.275808e+01)
- Note that n=161: */
-static const u8 viaLUT[] =
-    { 12, 12, 13, 14, 14, 15, 16, 16, 17, 18, 18, 19, 20, 20, 21, 22, 23,
-	    23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 35, 36, 37, 39, 40,
-	    41, 43, 45, 46, 48, 49, 51, 53, 55, 57, 59, 60, 62, 64, 66,
-	    69, 71, 73, 75, 77, 79, 82, 84, 86, 88, 91, 93, 95, 98, 100,
-	    103, 105, 107, 110, 112, 115, 117, 119, 122, 124, 126, 129,
-	    131, 134, 136, 138, 140, 143, 145, 147, 150, 152, 154, 156,
-	    158, 160, 162, 164, 166, 168, 170, 172, 174, 176, 178, 180,
-	    182, 183, 185, 187, 188, 190, 192, 193, 195, 196, 198, 199,
-	    200, 202, 203, 205, 206, 207, 208, 209, 210, 211, 212, 213,
-	    214, 215, 216, 217, 218, 219, 220, 221, 222, 222, 223, 224,
-	    225, 226, 226, 227, 228, 228, 229, 230, 230, 231, 232, 232,
-	    233, 233, 234, 235, 235, 236, 236, 237, 237, 238, 238, 239,
-	    239, 240
-};
-
-/* Converting temps to (8-bit) hyst and over registers
-   No interpolation here.
-   The +50 is because the temps start at -50 */
-static inline u8 TEMP_TO_REG(long val)
-{
-	return viaLUT[val <= -50000 ? 0 : val >= 110000 ? 160 : 
-		      (val < 0 ? val - 500 : val + 500) / 1000 + 50];
-}
-
-/* for 8-bit temperature hyst and over registers */
-#define TEMP_FROM_REG(val) (tempLUT[(val)] * 100)
-
-/* for 10-bit temperature readings */
-static inline long TEMP_FROM_REG10(u16 val)
-{
-	u16 eightBits = val >> 2;
-	u16 twoBits = val & 3;
-
-	/* no interpolation for these */
-	if (twoBits == 0 || eightBits == 255)
-		return TEMP_FROM_REG(eightBits);
-
-	/* do some linear interpolation */
-	return (tempLUT[eightBits] * (4 - twoBits) +
-	        tempLUT[eightBits + 1] * twoBits) * 25;
-}
-
-#define ALARMS_FROM_REG(val) (val)
-
-#define DIV_FROM_REG(val) (1 << (val))
-#define DIV_TO_REG(val) ((val)==8?3:(val)==4?2:(val)==1?0:1)
-
-/* For the VIA686A, we need to keep some data in memory.
-   The structure is dynamically allocated, at the same time when a new
-   via686a client is allocated. */
-struct via686a_data {
-	struct i2c_client client;
-	struct semaphore update_lock;
-	char valid;		/* !=0 if following fields are valid */
-	unsigned long last_updated;	/* In jiffies */
-
-	u8 in[5];		/* Register value */
-	u8 in_max[5];		/* Register value */
-	u8 in_min[5];		/* Register value */
-	u8 fan[2];		/* Register value */
-	u8 fan_min[2];		/* Register value */
-	u16 temp[3];		/* Register value 10 bit */
-	u8 temp_over[3];	/* Register value */
-	u8 temp_hyst[3];	/* Register value */
-	u8 fan_div[2];		/* Register encoding, shifted right */
-	u16 alarms;		/* Register encoding, combined */
-};
-
-static struct pci_dev *s_bridge;	/* pointer to the (only) via686a */
-
-static int via686a_attach_adapter(struct i2c_adapter *adapter);
-static int via686a_detect(struct i2c_adapter *adapter, int address, int kind);
-static int via686a_detach_client(struct i2c_client *client);
-
-static inline int via686a_read_value(struct i2c_client *client, u8 reg)
-{
-	return (inb_p(client->addr + reg));
-}
-
-static inline void via686a_write_value(struct i2c_client *client, u8 reg,
-				       u8 value)
-{
-	outb_p(value, client->addr + reg);
-}
-
-static struct via686a_data *via686a_update_device(struct device *dev);
-static void via686a_init_client(struct i2c_client *client);
-
-/* following are the sysfs callback functions */
-
-/* 7 voltage sensors */
-static ssize_t show_in(struct device *dev, char *buf, int nr) {
-	struct via686a_data *data = via686a_update_device(dev);
-	return sprintf(buf, "%ld\n", IN_FROM_REG(data->in[nr], nr));
-}
-
-static ssize_t show_in_min(struct device *dev, char *buf, int nr) {
-	struct via686a_data *data = via686a_update_device(dev);
-	return sprintf(buf, "%ld\n", IN_FROM_REG(data->in_min[nr], nr));
-}
-
-static ssize_t show_in_max(struct device *dev, char *buf, int nr) {
-	struct via686a_data *data = via686a_update_device(dev);
-	return sprintf(buf, "%ld\n", IN_FROM_REG(data->in_max[nr], nr));
-}
-
-static ssize_t set_in_min(struct device *dev, const char *buf, 
-		size_t count, int nr) {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct via686a_data *data = i2c_get_clientdata(client);
-	unsigned long val = simple_strtoul(buf, NULL, 10);
-
-	down(&data->update_lock);
-	data->in_min[nr] = IN_TO_REG(val,nr);
-	via686a_write_value(client, VIA686A_REG_IN_MIN(nr), 
-			data->in_min[nr]);
-	up(&data->update_lock);
-	return count;
-}
-static ssize_t set_in_max(struct device *dev, const char *buf, 
-		size_t count, int nr) {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct via686a_data *data = i2c_get_clientdata(client);
-	unsigned long val = simple_strtoul(buf, NULL, 10);
-
-	down(&data->update_lock);
-	data->in_max[nr] = IN_TO_REG(val,nr);
-	via686a_write_value(client, VIA686A_REG_IN_MAX(nr), 
-			data->in_max[nr]);
-	up(&data->update_lock);
-	return count;
-}
-#define show_in_offset(offset)					\
-static ssize_t 							\
-	show_in##offset (struct device *dev, char *buf)		\
-{								\
-	return show_in(dev, buf, offset);			\
-}								\
-static ssize_t 							\
-	show_in##offset##_min (struct device *dev, char *buf)	\
-{								\
-	return show_in_min(dev, buf, offset);		\
-}								\
-static ssize_t 							\
-	show_in##offset##_max (struct device *dev, char *buf)	\
-{								\
-	return show_in_max(dev, buf, offset);		\
-}								\
-static ssize_t set_in##offset##_min (struct device *dev, 	\
-		const char *buf, size_t count) 			\
-{								\
-	return set_in_min(dev, buf, count, offset);		\
-}								\
-static ssize_t set_in##offset##_max (struct device *dev,	\
-			const char *buf, size_t count)		\
-{								\
-	return set_in_max(dev, buf, count, offset);		\
-}								\
-static DEVICE_ATTR(in##offset##_input, S_IRUGO, show_in##offset, NULL);\
-static DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, 	\
-		show_in##offset##_min, set_in##offset##_min);	\
-static DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, 	\
-		show_in##offset##_max, set_in##offset##_max);
-
-show_in_offset(0);
-show_in_offset(1);
-show_in_offset(2);
-show_in_offset(3);
-show_in_offset(4);
-
-/* 3 temperatures */
-static ssize_t show_temp(struct device *dev, char *buf, int nr) {
-	struct via686a_data *data = via686a_update_device(dev);
-	return sprintf(buf, "%ld\n", TEMP_FROM_REG10(data->temp[nr]));
-}
-static ssize_t show_temp_over(struct device *dev, char *buf, int nr) {
-	struct via686a_data *data = via686a_update_device(dev);
-	return sprintf(buf, "%ld\n", TEMP_FROM_REG(data->temp_over[nr]));
-}
-static ssize_t show_temp_hyst(struct device *dev, char *buf, int nr) {
-	struct via686a_data *data = via686a_update_device(dev);
-	return sprintf(buf, "%ld\n", TEMP_FROM_REG(data->temp_hyst[nr]));
-}
-static ssize_t set_temp_over(struct device *dev, const char *buf, 
-		size_t count, int nr) {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct via686a_data *data = i2c_get_clientdata(client);
-	int val = simple_strtol(buf, NULL, 10);
-
-	down(&data->update_lock);
-	data->temp_over[nr] = TEMP_TO_REG(val);
-	via686a_write_value(client, VIA686A_REG_TEMP_OVER(nr), data->temp_over[nr]);
-	up(&data->update_lock);
-	return count;
-}
-static ssize_t set_temp_hyst(struct device *dev, const char *buf, 
-		size_t count, int nr) {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct via686a_data *data = i2c_get_clientdata(client);
-	int val = simple_strtol(buf, NULL, 10);
-
-	down(&data->update_lock);
-	data->temp_hyst[nr] = TEMP_TO_REG(val);
-	via686a_write_value(client, VIA686A_REG_TEMP_HYST(nr), data->temp_hyst[nr]);
-	up(&data->update_lock);
-	return count;
-}
-#define show_temp_offset(offset)					\
-static ssize_t show_temp_##offset (struct device *dev, char *buf)	\
-{									\
-	return show_temp(dev, buf, offset - 1);				\
-}									\
-static ssize_t								\
-show_temp_##offset##_over (struct device *dev, char *buf)		\
-{									\
-	return show_temp_over(dev, buf, offset - 1);			\
-}									\
-static ssize_t								\
-show_temp_##offset##_hyst (struct device *dev, char *buf)		\
-{									\
-	return show_temp_hyst(dev, buf, offset - 1);			\
-}									\
-static ssize_t set_temp_##offset##_over (struct device *dev, 		\
-		const char *buf, size_t count) 				\
-{									\
-	return set_temp_over(dev, buf, count, offset - 1);		\
-}									\
-static ssize_t set_temp_##offset##_hyst (struct device *dev, 		\
-		const char *buf, size_t count) 				\
-{									\
-	return set_temp_hyst(dev, buf, count, offset - 1);		\
-}									\
-static DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_temp_##offset, NULL);\
-static DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR, 		\
-		show_temp_##offset##_over, set_temp_##offset##_over);	\
-static DEVICE_ATTR(temp##offset##_max_hyst, S_IRUGO | S_IWUSR, 		\
-		show_temp_##offset##_hyst, set_temp_##offset##_hyst);	
-
-show_temp_offset(1);
-show_temp_offset(2);
-show_temp_offset(3);
-
-/* 2 Fans */
-static ssize_t show_fan(struct device *dev, char *buf, int nr) {
-	struct via686a_data *data = via686a_update_device(dev);
-	return sprintf(buf,"%d\n", FAN_FROM_REG(data->fan[nr], 
-				DIV_FROM_REG(data->fan_div[nr])) );
-}
-static ssize_t show_fan_min(struct device *dev, char *buf, int nr) {
-	struct via686a_data *data = via686a_update_device(dev);
-	return sprintf(buf,"%d\n",
-		FAN_FROM_REG(data->fan_min[nr], DIV_FROM_REG(data->fan_div[nr])) );
-}
-static ssize_t show_fan_div(struct device *dev, char *buf, int nr) {
-	struct via686a_data *data = via686a_update_device(dev);
-	return sprintf(buf,"%d\n", DIV_FROM_REG(data->fan_div[nr]) );
-}
-static ssize_t set_fan_min(struct device *dev, const char *buf, 
-		size_t count, int nr) {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct via686a_data *data = i2c_get_clientdata(client);
-	int val = simple_strtol(buf, NULL, 10);
-
-	down(&data->update_lock);
-	data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr]));
-	via686a_write_value(client, VIA686A_REG_FAN_MIN(nr+1), data->fan_min[nr]);
-	up(&data->update_lock);
-	return count;
-}
-static ssize_t set_fan_div(struct device *dev, const char *buf, 
-		size_t count, int nr) {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct via686a_data *data = i2c_get_clientdata(client);
-	int val = simple_strtol(buf, NULL, 10);
-	int old;
-
-	down(&data->update_lock);
-	old = via686a_read_value(client, VIA686A_REG_FANDIV);
-	data->fan_div[nr] = DIV_TO_REG(val);
-	old = (old & 0x0f) | (data->fan_div[1] << 6) | (data->fan_div[0] << 4);
-	via686a_write_value(client, VIA686A_REG_FANDIV, old);
-	up(&data->update_lock);
-	return count;
-}
-
-#define show_fan_offset(offset)						\
-static ssize_t show_fan_##offset (struct device *dev, char *buf)	\
-{									\
-	return show_fan(dev, buf, offset - 1);				\
-}									\
-static ssize_t show_fan_##offset##_min (struct device *dev, char *buf)	\
-{									\
-	return show_fan_min(dev, buf, offset - 1);			\
-}									\
-static ssize_t show_fan_##offset##_div (struct device *dev, char *buf)	\
-{									\
-	return show_fan_div(dev, buf, offset - 1);			\
-}									\
-static ssize_t set_fan_##offset##_min (struct device *dev, 		\
-	const char *buf, size_t count) 					\
-{									\
-	return set_fan_min(dev, buf, count, offset - 1);		\
-}									\
-static ssize_t set_fan_##offset##_div (struct device *dev, 		\
-		const char *buf, size_t count) 				\
-{									\
-	return set_fan_div(dev, buf, count, offset - 1);		\
-}									\
-static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_fan_##offset, NULL);\
-static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, 		\
-		show_fan_##offset##_min, set_fan_##offset##_min);	\
-static DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, 		\
-		show_fan_##offset##_div, set_fan_##offset##_div);
-
-show_fan_offset(1);
-show_fan_offset(2);
-
-/* Alarms */
-static ssize_t show_alarms(struct device *dev, char *buf) {
-	struct via686a_data *data = via686a_update_device(dev);
-	return sprintf(buf,"%d\n", ALARMS_FROM_REG(data->alarms));
-}
-static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
-
-/* The driver. I choose to use type i2c_driver, as at is identical to both
-   smbus_driver and isa_driver, and clients could be of either kind */
-static struct i2c_driver via686a_driver = {
-	.owner		= THIS_MODULE,
-	.name		= "via686a",
-	.id		= I2C_DRIVERID_VIA686A,
-	.flags		= I2C_DF_NOTIFY,
-	.attach_adapter	= via686a_attach_adapter,
-	.detach_client	= via686a_detach_client,
-};
-
-
-/* This is called when the module is loaded */
-static int via686a_attach_adapter(struct i2c_adapter *adapter)
-{
-	if (!(adapter->class & I2C_CLASS_HWMON))
-		return 0;
-	return i2c_detect(adapter, &addr_data, via686a_detect);
-}
-
-static int via686a_detect(struct i2c_adapter *adapter, int address, int kind)
-{
-	struct i2c_client *new_client;
-	struct via686a_data *data;
-	int err = 0;
-	const char client_name[] = "via686a";
-	u16 val;
-
-	/* Make sure we are probing the ISA bus!!  */
-	if (!i2c_is_isa_adapter(adapter)) {
-		dev_err(&adapter->dev,
-		"via686a_detect called for an I2C bus adapter?!?\n");
-		return 0;
-	}
-
-	/* 8231 requires multiple of 256, we enforce that on 686 as well */
-	if(force_addr)
-		address = force_addr & 0xFF00;
-
-	if(force_addr) {
-		dev_warn(&adapter->dev,"forcing ISA address 0x%04X\n", address);
-		if (PCIBIOS_SUCCESSFUL !=
-		    pci_write_config_word(s_bridge, VIA686A_BASE_REG, address))
-			return -ENODEV;
-	}
-	if (PCIBIOS_SUCCESSFUL !=
-	    pci_read_config_word(s_bridge, VIA686A_ENABLE_REG, &val))
-		return -ENODEV;
-	if (!(val & 0x0001)) {
-		dev_warn(&adapter->dev,"enabling sensors\n");
-		if (PCIBIOS_SUCCESSFUL !=
-		    pci_write_config_word(s_bridge, VIA686A_ENABLE_REG,
-		                      val | 0x0001))
-			return -ENODEV;
-	}
-
-	/* Reserve the ISA region */
-	if (!request_region(address, VIA686A_EXTENT, via686a_driver.name)) {
-		dev_err(&adapter->dev,"region 0x%x already in use!\n",
-		       address);
-		return -ENODEV;
-	}
-
-	if (!(data = kmalloc(sizeof(struct via686a_data), GFP_KERNEL))) {
-		err = -ENOMEM;
-		goto ERROR0;
-	}
-	memset(data, 0, sizeof(struct via686a_data));
-
-	new_client = &data->client;
-	i2c_set_clientdata(new_client, data);
-	new_client->addr = address;
-	new_client->adapter = adapter;
-	new_client->driver = &via686a_driver;
-	new_client->flags = 0;
-
-	/* Fill in the remaining client fields and put into the global list */
-	strlcpy(new_client->name, client_name, I2C_NAME_SIZE);
-
-	data->valid = 0;
-	init_MUTEX(&data->update_lock);
-	/* Tell the I2C layer a new client has arrived */
-	if ((err = i2c_attach_client(new_client)))
-		goto ERROR3;
-	
-	/* Initialize the VIA686A chip */
-	via686a_init_client(new_client);
-
-	/* Register sysfs hooks */
-	device_create_file(&new_client->dev, &dev_attr_in0_input);
-	device_create_file(&new_client->dev, &dev_attr_in1_input);
-	device_create_file(&new_client->dev, &dev_attr_in2_input);
-	device_create_file(&new_client->dev, &dev_attr_in3_input);
-	device_create_file(&new_client->dev, &dev_attr_in4_input);
-	device_create_file(&new_client->dev, &dev_attr_in0_min);
-	device_create_file(&new_client->dev, &dev_attr_in1_min);
-	device_create_file(&new_client->dev, &dev_attr_in2_min);
-	device_create_file(&new_client->dev, &dev_attr_in3_min);
-	device_create_file(&new_client->dev, &dev_attr_in4_min);
-	device_create_file(&new_client->dev, &dev_attr_in0_max);
-	device_create_file(&new_client->dev, &dev_attr_in1_max);
-	device_create_file(&new_client->dev, &dev_attr_in2_max);
-	device_create_file(&new_client->dev, &dev_attr_in3_max);
-	device_create_file(&new_client->dev, &dev_attr_in4_max);
-	device_create_file(&new_client->dev, &dev_attr_temp1_input);
-	device_create_file(&new_client->dev, &dev_attr_temp2_input);
-	device_create_file(&new_client->dev, &dev_attr_temp3_input);
-	device_create_file(&new_client->dev, &dev_attr_temp1_max);
-	device_create_file(&new_client->dev, &dev_attr_temp2_max);
-	device_create_file(&new_client->dev, &dev_attr_temp3_max);
-	device_create_file(&new_client->dev, &dev_attr_temp1_max_hyst);
-	device_create_file(&new_client->dev, &dev_attr_temp2_max_hyst);
-	device_create_file(&new_client->dev, &dev_attr_temp3_max_hyst);
-	device_create_file(&new_client->dev, &dev_attr_fan1_input);
-	device_create_file(&new_client->dev, &dev_attr_fan2_input);
-	device_create_file(&new_client->dev, &dev_attr_fan1_min);
-	device_create_file(&new_client->dev, &dev_attr_fan2_min);
-	device_create_file(&new_client->dev, &dev_attr_fan1_div);
-	device_create_file(&new_client->dev, &dev_attr_fan2_div);
-	device_create_file(&new_client->dev, &dev_attr_alarms);
-
-	return 0;
-
-      ERROR3:
-	kfree(data);
-      ERROR0:
-	release_region(address, VIA686A_EXTENT);
-	return err;
-}
-
-static int via686a_detach_client(struct i2c_client *client)
-{
-	int err;
-
-	if ((err = i2c_detach_client(client))) {
-		dev_err(&client->dev,
-		"Client deregistration failed, client not detached.\n");
-		return err;
-	}
-
-	release_region(client->addr, VIA686A_EXTENT);
-	kfree(i2c_get_clientdata(client));
-
-	return 0;
-}
-
-/* Called when we have found a new VIA686A. Set limits, etc. */
-static void via686a_init_client(struct i2c_client *client)
-{
-	u8 reg;
-
-	/* Start monitoring */
-	reg = via686a_read_value(client, VIA686A_REG_CONFIG);
-	via686a_write_value(client, VIA686A_REG_CONFIG, (reg|0x01)&0x7F);
-
-	/* Configure temp interrupt mode for continuous-interrupt operation */
-	via686a_write_value(client, VIA686A_REG_TEMP_MODE, 
-			    via686a_read_value(client, VIA686A_REG_TEMP_MODE) &
-			    !(VIA686A_TEMP_MODE_MASK | VIA686A_TEMP_MODE_CONTINUOUS));
-}
-
-static struct via686a_data *via686a_update_device(struct device *dev)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct via686a_data *data = i2c_get_clientdata(client);
-	int i;
-
-	down(&data->update_lock);
-
-	if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
-	    || !data->valid) {
-		for (i = 0; i <= 4; i++) {
-			data->in[i] =
-			    via686a_read_value(client, VIA686A_REG_IN(i));
-			data->in_min[i] = via686a_read_value(client,
-							     VIA686A_REG_IN_MIN
-							     (i));
-			data->in_max[i] =
-			    via686a_read_value(client, VIA686A_REG_IN_MAX(i));
-		}
-		for (i = 1; i <= 2; i++) {
-			data->fan[i - 1] =
-			    via686a_read_value(client, VIA686A_REG_FAN(i));
-			data->fan_min[i - 1] = via686a_read_value(client,
-						     VIA686A_REG_FAN_MIN(i));
-		}
-		for (i = 0; i <= 2; i++) {
-			data->temp[i] = via686a_read_value(client,
-						 VIA686A_REG_TEMP(i)) << 2;
-			data->temp_over[i] =
-			    via686a_read_value(client,
-					       VIA686A_REG_TEMP_OVER(i));
-			data->temp_hyst[i] =
-			    via686a_read_value(client,
-					       VIA686A_REG_TEMP_HYST(i));
-		}
-		/* add in lower 2 bits 
-		   temp1 uses bits 7-6 of VIA686A_REG_TEMP_LOW1
-		   temp2 uses bits 5-4 of VIA686A_REG_TEMP_LOW23
-		   temp3 uses bits 7-6 of VIA686A_REG_TEMP_LOW23
-		 */
-		data->temp[0] |= (via686a_read_value(client,
-						     VIA686A_REG_TEMP_LOW1)
-				  & 0xc0) >> 6;
-		data->temp[1] |=
-		    (via686a_read_value(client, VIA686A_REG_TEMP_LOW23) &
-		     0x30) >> 4;
-		data->temp[2] |=
-		    (via686a_read_value(client, VIA686A_REG_TEMP_LOW23) &
-		     0xc0) >> 6;
-
-		i = via686a_read_value(client, VIA686A_REG_FANDIV);
-		data->fan_div[0] = (i >> 4) & 0x03;
-		data->fan_div[1] = i >> 6;
-		data->alarms =
-		    via686a_read_value(client,
-				       VIA686A_REG_ALARM1) |
-		    (via686a_read_value(client, VIA686A_REG_ALARM2) << 8);
-		data->last_updated = jiffies;
-		data->valid = 1;
-	}
-
-	up(&data->update_lock);
-
-	return data;
-}
-
-static struct pci_device_id via686a_pci_ids[] = {
-       { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4) },
-       { 0, }
-};
-
-MODULE_DEVICE_TABLE(pci, via686a_pci_ids);
-
-static int __devinit via686a_pci_probe(struct pci_dev *dev,
-                                      const struct pci_device_id *id)
-{
-       u16 val;
-       int addr = 0;
-
-       if (PCIBIOS_SUCCESSFUL !=
-           pci_read_config_word(dev, VIA686A_BASE_REG, &val))
-               return -ENODEV;
-
-       addr = val & ~(VIA686A_EXTENT - 1);
-       if (addr == 0 && force_addr == 0) {
-               dev_err(&dev->dev,"base address not set - upgrade BIOS or use force_addr=0xaddr\n");
-               return -ENODEV;
-       }
-       if (force_addr)
-               addr = force_addr;      /* so detect will get called */
-
-       if (!addr) {
-               dev_err(&dev->dev,"No Via 686A sensors found.\n");
-               return -ENODEV;
-       }
-       normal_isa[0] = addr;
-
-	s_bridge = pci_dev_get(dev);
-	if (i2c_add_driver(&via686a_driver)) {
-		pci_dev_put(s_bridge);
-		s_bridge = NULL;
-	}
-
-	/* Always return failure here.  This is to allow other drivers to bind
-	 * to this pci device.  We don't really want to have control over the
-	 * pci device, we only wanted to read as few register values from it.
-	 */
-	return -ENODEV;
-}
-
-static struct pci_driver via686a_pci_driver = {
-       .name		= "via686a",
-       .id_table	= via686a_pci_ids,
-       .probe		= via686a_pci_probe,
-};
-
-static int __init sm_via686a_init(void)
-{
-       return pci_register_driver(&via686a_pci_driver);
-}
-
-static void __exit sm_via686a_exit(void)
-{
-	pci_unregister_driver(&via686a_pci_driver);
-	if (s_bridge != NULL) {
-		i2c_del_driver(&via686a_driver);
-		pci_dev_put(s_bridge);
-		s_bridge = NULL;
-	}
-}
-
-MODULE_AUTHOR("Kyösti Mälkki <kmalkki@cc.hut.fi>, "
-              "Mark Studebaker <mdsxyz123@yahoo.com> "
-             "and Bob Dougherty <bobd@stanford.edu>");
-MODULE_DESCRIPTION("VIA 686A Sensor device");
-MODULE_LICENSE("GPL");
-
-module_init(sm_via686a_init);
-module_exit(sm_via686a_exit);
diff --git a/drivers/i2c/chips/w83627hf.c b/drivers/i2c/chips/w83627hf.c
deleted file mode 100644
--- a/drivers/i2c/chips/w83627hf.c
+++ /dev/null
@@ -1,1511 +0,0 @@
-/*
-    w83627hf.c - Part of lm_sensors, Linux kernel modules for hardware
-                monitoring
-    Copyright (c) 1998 - 2003  Frodo Looijaard <frodol@dds.nl>,
-    Philip Edelbrock <phil@netroedge.com>,
-    and Mark Studebaker <mdsxyz123@yahoo.com>
-    Ported to 2.6 by Bernhard C. Schrenk <clemy@clemy.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.
-*/
-
-/*
-    Supports following chips:
-
-    Chip	#vin	#fanin	#pwm	#temp	wchipid	vendid	i2c	ISA
-    w83627hf	9	3	2	3	0x20	0x5ca3	no	yes(LPC)
-    w83627thf	7	3	3	3	0x90	0x5ca3	no	yes(LPC)
-    w83637hf	7	3	3	3	0x80	0x5ca3	no	yes(LPC)
-    w83697hf	8	2	2	2	0x60	0x5ca3	no	yes(LPC)
-
-    For other winbond chips, and for i2c support in the above chips,
-    use w83781d.c.
-
-    Note: automatic ("cruise") fan control for 697, 637 & 627thf not
-    supported yet.
-*/
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/jiffies.h>
-#include <linux/i2c.h>
-#include <linux/i2c-sensor.h>
-#include <linux/i2c-vid.h>
-#include <asm/io.h>
-#include "lm75.h"
-
-static u16 force_addr;
-module_param(force_addr, ushort, 0);
-MODULE_PARM_DESC(force_addr,
-		 "Initialize the base address of the sensors");
-static u8 force_i2c = 0x1f;
-module_param(force_i2c, byte, 0);
-MODULE_PARM_DESC(force_i2c,
-		 "Initialize the i2c address of the sensors");
-
-/* Addresses to scan */
-static unsigned short normal_i2c[] = { I2C_CLIENT_END };
-static unsigned int normal_isa[] = { 0, I2C_CLIENT_ISA_END };
-
-/* Insmod parameters */
-SENSORS_INSMOD_4(w83627hf, w83627thf, w83697hf, w83637hf);
-
-static int init = 1;
-module_param(init, bool, 0);
-MODULE_PARM_DESC(init, "Set to zero to bypass chip initialization");
-
-/* modified from kernel/include/traps.c */
-static int REG;		/* The register to read/write */
-#define	DEV	0x07	/* Register: Logical device select */
-static int VAL;		/* The value to read/write */
-
-/* logical device numbers for superio_select (below) */
-#define W83627HF_LD_FDC		0x00
-#define W83627HF_LD_PRT		0x01
-#define W83627HF_LD_UART1	0x02
-#define W83627HF_LD_UART2	0x03
-#define W83627HF_LD_KBC		0x05
-#define W83627HF_LD_CIR		0x06 /* w83627hf only */
-#define W83627HF_LD_GAME	0x07
-#define W83627HF_LD_MIDI	0x07
-#define W83627HF_LD_GPIO1	0x07
-#define W83627HF_LD_GPIO5	0x07 /* w83627thf only */
-#define W83627HF_LD_GPIO2	0x08
-#define W83627HF_LD_GPIO3	0x09
-#define W83627HF_LD_GPIO4	0x09 /* w83627thf only */
-#define W83627HF_LD_ACPI	0x0a
-#define W83627HF_LD_HWM		0x0b
-
-#define	DEVID	0x20	/* Register: Device ID */
-
-#define W83627THF_GPIO5_EN	0x30 /* w83627thf only */
-#define W83627THF_GPIO5_IOSR	0xf3 /* w83627thf only */
-#define W83627THF_GPIO5_DR	0xf4 /* w83627thf only */
-
-static inline void
-superio_outb(int reg, int val)
-{
-	outb(reg, REG);
-	outb(val, VAL);
-}
-
-static inline int
-superio_inb(int reg)
-{
-	outb(reg, REG);
-	return inb(VAL);
-}
-
-static inline void
-superio_select(int ld)
-{
-	outb(DEV, REG);
-	outb(ld, VAL);
-}
-
-static inline void
-superio_enter(void)
-{
-	outb(0x87, REG);
-	outb(0x87, REG);
-}
-
-static inline void
-superio_exit(void)
-{
-	outb(0xAA, REG);
-}
-
-#define W627_DEVID 0x52
-#define W627THF_DEVID 0x82
-#define W697_DEVID 0x60
-#define W637_DEVID 0x70
-#define WINB_ACT_REG 0x30
-#define WINB_BASE_REG 0x60
-/* Constants specified below */
-
-/* Length of ISA address segment */
-#define WINB_EXTENT 8
-
-/* Where are the ISA address/data registers relative to the base address */
-#define W83781D_ADDR_REG_OFFSET 5
-#define W83781D_DATA_REG_OFFSET 6
-
-/* The W83781D registers */
-/* The W83782D registers for nr=7,8 are in bank 5 */
-#define W83781D_REG_IN_MAX(nr) ((nr < 7) ? (0x2b + (nr) * 2) : \
-					   (0x554 + (((nr) - 7) * 2)))
-#define W83781D_REG_IN_MIN(nr) ((nr < 7) ? (0x2c + (nr) * 2) : \
-					   (0x555 + (((nr) - 7) * 2)))
-#define W83781D_REG_IN(nr)     ((nr < 7) ? (0x20 + (nr)) : \
-					   (0x550 + (nr) - 7))
-
-#define W83781D_REG_FAN_MIN(nr) (0x3a + (nr))
-#define W83781D_REG_FAN(nr) (0x27 + (nr))
-
-#define W83781D_REG_TEMP2_CONFIG 0x152
-#define W83781D_REG_TEMP3_CONFIG 0x252
-#define W83781D_REG_TEMP(nr)		((nr == 3) ? (0x0250) : \
-					((nr == 2) ? (0x0150) : \
-					             (0x27)))
-#define W83781D_REG_TEMP_HYST(nr)	((nr == 3) ? (0x253) : \
-					((nr == 2) ? (0x153) : \
-					             (0x3A)))
-#define W83781D_REG_TEMP_OVER(nr)	((nr == 3) ? (0x255) : \
-					((nr == 2) ? (0x155) : \
-					             (0x39)))
-
-#define W83781D_REG_BANK 0x4E
-
-#define W83781D_REG_CONFIG 0x40
-#define W83781D_REG_ALARM1 0x41
-#define W83781D_REG_ALARM2 0x42
-#define W83781D_REG_ALARM3 0x450
-
-#define W83781D_REG_IRQ 0x4C
-#define W83781D_REG_BEEP_CONFIG 0x4D
-#define W83781D_REG_BEEP_INTS1 0x56
-#define W83781D_REG_BEEP_INTS2 0x57
-#define W83781D_REG_BEEP_INTS3 0x453
-
-#define W83781D_REG_VID_FANDIV 0x47
-
-#define W83781D_REG_CHIPID 0x49
-#define W83781D_REG_WCHIPID 0x58
-#define W83781D_REG_CHIPMAN 0x4F
-#define W83781D_REG_PIN 0x4B
-
-#define W83781D_REG_VBAT 0x5D
-
-#define W83627HF_REG_PWM1 0x5A
-#define W83627HF_REG_PWM2 0x5B
-#define W83627HF_REG_PWMCLK12 0x5C
-
-#define W83627THF_REG_PWM1		0x01	/* 697HF and 637HF too */
-#define W83627THF_REG_PWM2		0x03	/* 697HF and 637HF too */
-#define W83627THF_REG_PWM3		0x11	/* 637HF too */
-
-#define W83627THF_REG_VRM_OVT_CFG 	0x18	/* 637HF too */
-
-static const u8 regpwm_627hf[] = { W83627HF_REG_PWM1, W83627HF_REG_PWM2 };
-static const u8 regpwm[] = { W83627THF_REG_PWM1, W83627THF_REG_PWM2,
-                             W83627THF_REG_PWM3 };
-#define W836X7HF_REG_PWM(type, nr) (((type) == w83627hf) ? \
-                                     regpwm_627hf[(nr) - 1] : regpwm[(nr) - 1])
-
-#define W83781D_REG_I2C_ADDR 0x48
-#define W83781D_REG_I2C_SUBADDR 0x4A
-
-/* Sensor selection */
-#define W83781D_REG_SCFG1 0x5D
-static const u8 BIT_SCFG1[] = { 0x02, 0x04, 0x08 };
-#define W83781D_REG_SCFG2 0x59
-static const u8 BIT_SCFG2[] = { 0x10, 0x20, 0x40 };
-#define W83781D_DEFAULT_BETA 3435
-
-/* Conversions. Limit checking is only done on the TO_REG
-   variants. Note that you should be a bit careful with which arguments
-   these macros are called: arguments may be evaluated more than once.
-   Fixing this is just not worth it. */
-#define IN_TO_REG(val)  (SENSORS_LIMIT((((val) + 8)/16),0,255))
-#define IN_FROM_REG(val) ((val) * 16)
-
-static inline u8 FAN_TO_REG(long rpm, int div)
-{
-	if (rpm == 0)
-		return 255;
-	rpm = SENSORS_LIMIT(rpm, 1, 1000000);
-	return SENSORS_LIMIT((1350000 + rpm * div / 2) / (rpm * div), 1,
-			     254);
-}
-
-#define TEMP_MIN (-128000)
-#define TEMP_MAX ( 127000)
-
-/* TEMP: 0.001C/bit (-128C to +127C)
-   REG: 1C/bit, two's complement */
-static u8 TEMP_TO_REG(int temp)
-{
-        int ntemp = SENSORS_LIMIT(temp, TEMP_MIN, TEMP_MAX);
-        ntemp += (ntemp<0 ? -500 : 500);
-        return (u8)(ntemp / 1000);
-}
-
-static int TEMP_FROM_REG(u8 reg)
-{
-        return (s8)reg * 1000;
-}
-
-#define FAN_FROM_REG(val,div) ((val)==0?-1:(val)==255?0:1350000/((val)*(div)))
-
-#define PWM_TO_REG(val) (SENSORS_LIMIT((val),0,255))
-
-#define BEEP_MASK_FROM_REG(val)		 (val)
-#define BEEP_MASK_TO_REG(val)		((val) & 0xffffff)
-#define BEEP_ENABLE_TO_REG(val)		((val)?1:0)
-#define BEEP_ENABLE_FROM_REG(val)	((val)?1:0)
-
-#define DIV_FROM_REG(val) (1 << (val))
-
-static inline u8 DIV_TO_REG(long val)
-{
-	int i;
-	val = SENSORS_LIMIT(val, 1, 128) >> 1;
-	for (i = 0; i < 6; i++) {
-		if (val == 0)
-			break;
-		val >>= 1;
-	}
-	return ((u8) i);
-}
-
-/* For each registered chip, we need to keep some data in memory. That
-   data is pointed to by w83627hf_list[NR]->data. The structure itself is
-   dynamically allocated, at the same time when a new client is allocated. */
-struct w83627hf_data {
-	struct i2c_client client;
-	struct semaphore lock;
-	enum chips type;
-
-	struct semaphore update_lock;
-	char valid;		/* !=0 if following fields are valid */
-	unsigned long last_updated;	/* In jiffies */
-
-	struct i2c_client *lm75;	/* for secondary I2C addresses */
-	/* pointer to array of 2 subclients */
-
-	u8 in[9];		/* Register value */
-	u8 in_max[9];		/* Register value */
-	u8 in_min[9];		/* Register value */
-	u8 fan[3];		/* Register value */
-	u8 fan_min[3];		/* Register value */
-	u8 temp;
-	u8 temp_max;		/* Register value */
-	u8 temp_max_hyst;	/* Register value */
-	u16 temp_add[2];	/* Register value */
-	u16 temp_max_add[2];	/* Register value */
-	u16 temp_max_hyst_add[2]; /* Register value */
-	u8 fan_div[3];		/* Register encoding, shifted right */
-	u8 vid;			/* Register encoding, combined */
-	u32 alarms;		/* Register encoding, combined */
-	u32 beep_mask;		/* Register encoding, combined */
-	u8 beep_enable;		/* Boolean */
-	u8 pwm[3];		/* Register value */
-	u16 sens[3];		/* 782D/783S only.
-				   1 = pentium diode; 2 = 3904 diode;
-				   3000-5000 = thermistor beta.
-				   Default = 3435.
-				   Other Betas unimplemented */
-	u8 vrm;
-	u8 vrm_ovt;		/* Register value, 627thf & 637hf only */
-};
-
-
-static int w83627hf_attach_adapter(struct i2c_adapter *adapter);
-static int w83627hf_detect(struct i2c_adapter *adapter, int address,
-			  int kind);
-static int w83627hf_detach_client(struct i2c_client *client);
-
-static int w83627hf_read_value(struct i2c_client *client, u16 register);
-static int w83627hf_write_value(struct i2c_client *client, u16 register,
-			       u16 value);
-static struct w83627hf_data *w83627hf_update_device(struct device *dev);
-static void w83627hf_init_client(struct i2c_client *client);
-
-static struct i2c_driver w83627hf_driver = {
-	.owner		= THIS_MODULE,
-	.name		= "w83627hf",
-	.id		= I2C_DRIVERID_W83627HF,
-	.flags		= I2C_DF_NOTIFY,
-	.attach_adapter	= w83627hf_attach_adapter,
-	.detach_client	= w83627hf_detach_client,
-};
-
-/* following are the sysfs callback functions */
-#define show_in_reg(reg) \
-static ssize_t show_##reg (struct device *dev, char *buf, int nr) \
-{ \
-	struct w83627hf_data *data = w83627hf_update_device(dev); \
-	return sprintf(buf,"%ld\n", (long)IN_FROM_REG(data->reg[nr])); \
-}
-show_in_reg(in)
-show_in_reg(in_min)
-show_in_reg(in_max)
-
-#define store_in_reg(REG, reg) \
-static ssize_t \
-store_in_##reg (struct device *dev, const char *buf, size_t count, int nr) \
-{ \
-	struct i2c_client *client = to_i2c_client(dev); \
-	struct w83627hf_data *data = i2c_get_clientdata(client); \
-	u32 val; \
-	 \
-	val = simple_strtoul(buf, NULL, 10); \
-	 \
-	down(&data->update_lock); \
-	data->in_##reg[nr] = IN_TO_REG(val); \
-	w83627hf_write_value(client, W83781D_REG_IN_##REG(nr), \
-			    data->in_##reg[nr]); \
-	 \
-	up(&data->update_lock); \
-	return count; \
-}
-store_in_reg(MIN, min)
-store_in_reg(MAX, max)
-
-#define sysfs_in_offset(offset) \
-static ssize_t \
-show_regs_in_##offset (struct device *dev, char *buf) \
-{ \
-        return show_in(dev, buf, offset); \
-} \
-static DEVICE_ATTR(in##offset##_input, S_IRUGO, show_regs_in_##offset, NULL);
-
-#define sysfs_in_reg_offset(reg, offset) \
-static ssize_t show_regs_in_##reg##offset (struct device *dev, char *buf) \
-{ \
-	return show_in_##reg (dev, buf, offset); \
-} \
-static ssize_t \
-store_regs_in_##reg##offset (struct device *dev, \
-			    const char *buf, size_t count) \
-{ \
-	return store_in_##reg (dev, buf, count, offset); \
-} \
-static DEVICE_ATTR(in##offset##_##reg, S_IRUGO| S_IWUSR, \
-		  show_regs_in_##reg##offset, store_regs_in_##reg##offset);
-
-#define sysfs_in_offsets(offset) \
-sysfs_in_offset(offset) \
-sysfs_in_reg_offset(min, offset) \
-sysfs_in_reg_offset(max, offset)
-
-sysfs_in_offsets(1);
-sysfs_in_offsets(2);
-sysfs_in_offsets(3);
-sysfs_in_offsets(4);
-sysfs_in_offsets(5);
-sysfs_in_offsets(6);
-sysfs_in_offsets(7);
-sysfs_in_offsets(8);
-
-/* use a different set of functions for in0 */
-static ssize_t show_in_0(struct w83627hf_data *data, char *buf, u8 reg)
-{
-	long in0;
-
-	if ((data->vrm_ovt & 0x01) &&
-		(w83627thf == data->type || w83637hf == data->type))
-
-		/* use VRM9 calculation */
-		in0 = (long)((reg * 488 + 70000 + 50) / 100);
-	else
-		/* use VRM8 (standard) calculation */
-		in0 = (long)IN_FROM_REG(reg);
-
-	return sprintf(buf,"%ld\n", in0);
-}
-
-static ssize_t show_regs_in_0(struct device *dev, char *buf)
-{
-	struct w83627hf_data *data = w83627hf_update_device(dev);
-	return show_in_0(data, buf, data->in[0]);
-}
-
-static ssize_t show_regs_in_min0(struct device *dev, char *buf)
-{
-	struct w83627hf_data *data = w83627hf_update_device(dev);
-	return show_in_0(data, buf, data->in_min[0]);
-}
-
-static ssize_t show_regs_in_max0(struct device *dev, char *buf)
-{
-	struct w83627hf_data *data = w83627hf_update_device(dev);
-	return show_in_0(data, buf, data->in_max[0]);
-}
-
-static ssize_t store_regs_in_min0(struct device *dev,
-	const char *buf, size_t count)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct w83627hf_data *data = i2c_get_clientdata(client);
-	u32 val;
-
-	val = simple_strtoul(buf, NULL, 10);
-
-	down(&data->update_lock);
-	
-	if ((data->vrm_ovt & 0x01) &&
-		(w83627thf == data->type || w83637hf == data->type))
-
-		/* use VRM9 calculation */
-		data->in_min[0] = (u8)(((val * 100) - 70000 + 244) / 488);
-	else
-		/* use VRM8 (standard) calculation */
-		data->in_min[0] = IN_TO_REG(val);
-
-	w83627hf_write_value(client, W83781D_REG_IN_MIN(0), data->in_min[0]);
-	up(&data->update_lock);
-	return count;
-}
-
-static ssize_t store_regs_in_max0(struct device *dev,
-	const char *buf, size_t count)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct w83627hf_data *data = i2c_get_clientdata(client);
-	u32 val;
-
-	val = simple_strtoul(buf, NULL, 10);
-
-	down(&data->update_lock);
-
-	if ((data->vrm_ovt & 0x01) &&
-		(w83627thf == data->type || w83637hf == data->type))
-		
-		/* use VRM9 calculation */
-		data->in_max[0] = (u8)(((val * 100) - 70000 + 244) / 488);
-	else
-		/* use VRM8 (standard) calculation */
-		data->in_max[0] = IN_TO_REG(val);
-
-	w83627hf_write_value(client, W83781D_REG_IN_MAX(0), data->in_max[0]);
-	up(&data->update_lock);
-	return count;
-}
-
-static DEVICE_ATTR(in0_input, S_IRUGO, show_regs_in_0, NULL);
-static DEVICE_ATTR(in0_min, S_IRUGO | S_IWUSR,
-	show_regs_in_min0, store_regs_in_min0);
-static DEVICE_ATTR(in0_max, S_IRUGO | S_IWUSR,
-	show_regs_in_max0, store_regs_in_max0);
-
-#define device_create_file_in(client, offset) \
-do { \
-device_create_file(&client->dev, &dev_attr_in##offset##_input); \
-device_create_file(&client->dev, &dev_attr_in##offset##_min); \
-device_create_file(&client->dev, &dev_attr_in##offset##_max); \
-} while (0)
-
-#define show_fan_reg(reg) \
-static ssize_t show_##reg (struct device *dev, char *buf, int nr) \
-{ \
-	struct w83627hf_data *data = w83627hf_update_device(dev); \
-	return sprintf(buf,"%ld\n", \
-		FAN_FROM_REG(data->reg[nr-1], \
-			    (long)DIV_FROM_REG(data->fan_div[nr-1]))); \
-}
-show_fan_reg(fan);
-show_fan_reg(fan_min);
-
-static ssize_t
-store_fan_min(struct device *dev, const char *buf, size_t count, int nr)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct w83627hf_data *data = i2c_get_clientdata(client);
-	u32 val;
-
-	val = simple_strtoul(buf, NULL, 10);
-
-	down(&data->update_lock);
-	data->fan_min[nr - 1] =
-	    FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr - 1]));
-	w83627hf_write_value(client, W83781D_REG_FAN_MIN(nr),
-			    data->fan_min[nr - 1]);
-
-	up(&data->update_lock);
-	return count;
-}
-
-#define sysfs_fan_offset(offset) \
-static ssize_t show_regs_fan_##offset (struct device *dev, char *buf) \
-{ \
-	return show_fan(dev, buf, offset); \
-} \
-static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_regs_fan_##offset, NULL);
-
-#define sysfs_fan_min_offset(offset) \
-static ssize_t show_regs_fan_min##offset (struct device *dev, char *buf) \
-{ \
-	return show_fan_min(dev, buf, offset); \
-} \
-static ssize_t \
-store_regs_fan_min##offset (struct device *dev, const char *buf, size_t count) \
-{ \
-	return store_fan_min(dev, buf, count, offset); \
-} \
-static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \
-		  show_regs_fan_min##offset, store_regs_fan_min##offset);
-
-sysfs_fan_offset(1);
-sysfs_fan_min_offset(1);
-sysfs_fan_offset(2);
-sysfs_fan_min_offset(2);
-sysfs_fan_offset(3);
-sysfs_fan_min_offset(3);
-
-#define device_create_file_fan(client, offset) \
-do { \
-device_create_file(&client->dev, &dev_attr_fan##offset##_input); \
-device_create_file(&client->dev, &dev_attr_fan##offset##_min); \
-} while (0)
-
-#define show_temp_reg(reg) \
-static ssize_t show_##reg (struct device *dev, char *buf, int nr) \
-{ \
-	struct w83627hf_data *data = w83627hf_update_device(dev); \
-	if (nr >= 2) {	/* TEMP2 and TEMP3 */ \
-		return sprintf(buf,"%ld\n", \
-			(long)LM75_TEMP_FROM_REG(data->reg##_add[nr-2])); \
-	} else {	/* TEMP1 */ \
-		return sprintf(buf,"%ld\n", (long)TEMP_FROM_REG(data->reg)); \
-	} \
-}
-show_temp_reg(temp);
-show_temp_reg(temp_max);
-show_temp_reg(temp_max_hyst);
-
-#define store_temp_reg(REG, reg) \
-static ssize_t \
-store_temp_##reg (struct device *dev, const char *buf, size_t count, int nr) \
-{ \
-	struct i2c_client *client = to_i2c_client(dev); \
-	struct w83627hf_data *data = i2c_get_clientdata(client); \
-	u32 val; \
-	 \
-	val = simple_strtoul(buf, NULL, 10); \
-	 \
-	down(&data->update_lock); \
-	 \
-	if (nr >= 2) {	/* TEMP2 and TEMP3 */ \
-		data->temp_##reg##_add[nr-2] = LM75_TEMP_TO_REG(val); \
-		w83627hf_write_value(client, W83781D_REG_TEMP_##REG(nr), \
-				data->temp_##reg##_add[nr-2]); \
-	} else {	/* TEMP1 */ \
-		data->temp_##reg = TEMP_TO_REG(val); \
-		w83627hf_write_value(client, W83781D_REG_TEMP_##REG(nr), \
-			data->temp_##reg); \
-	} \
-	 \
-	up(&data->update_lock); \
-	return count; \
-}
-store_temp_reg(OVER, max);
-store_temp_reg(HYST, max_hyst);
-
-#define sysfs_temp_offset(offset) \
-static ssize_t \
-show_regs_temp_##offset (struct device *dev, char *buf) \
-{ \
-	return show_temp(dev, buf, offset); \
-} \
-static DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_regs_temp_##offset, NULL);
-
-#define sysfs_temp_reg_offset(reg, offset) \
-static ssize_t show_regs_temp_##reg##offset (struct device *dev, char *buf) \
-{ \
-	return show_temp_##reg (dev, buf, offset); \
-} \
-static ssize_t \
-store_regs_temp_##reg##offset (struct device *dev, \
-			      const char *buf, size_t count) \
-{ \
-	return store_temp_##reg (dev, buf, count, offset); \
-} \
-static DEVICE_ATTR(temp##offset##_##reg, S_IRUGO| S_IWUSR, \
-		  show_regs_temp_##reg##offset, store_regs_temp_##reg##offset);
-
-#define sysfs_temp_offsets(offset) \
-sysfs_temp_offset(offset) \
-sysfs_temp_reg_offset(max, offset) \
-sysfs_temp_reg_offset(max_hyst, offset)
-
-sysfs_temp_offsets(1);
-sysfs_temp_offsets(2);
-sysfs_temp_offsets(3);
-
-#define device_create_file_temp(client, offset) \
-do { \
-device_create_file(&client->dev, &dev_attr_temp##offset##_input); \
-device_create_file(&client->dev, &dev_attr_temp##offset##_max); \
-device_create_file(&client->dev, &dev_attr_temp##offset##_max_hyst); \
-} while (0)
-
-static ssize_t
-show_vid_reg(struct device *dev, char *buf)
-{
-	struct w83627hf_data *data = w83627hf_update_device(dev);
-	return sprintf(buf, "%ld\n", (long) vid_from_reg(data->vid, data->vrm));
-}
-static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid_reg, NULL);
-#define device_create_file_vid(client) \
-device_create_file(&client->dev, &dev_attr_cpu0_vid)
-
-static ssize_t
-show_vrm_reg(struct device *dev, char *buf)
-{
-	struct w83627hf_data *data = w83627hf_update_device(dev);
-	return sprintf(buf, "%ld\n", (long) data->vrm);
-}
-static ssize_t
-store_vrm_reg(struct device *dev, const char *buf, size_t count)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct w83627hf_data *data = i2c_get_clientdata(client);
-	u32 val;
-
-	val = simple_strtoul(buf, NULL, 10);
-	data->vrm = val;
-
-	return count;
-}
-static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg);
-#define device_create_file_vrm(client) \
-device_create_file(&client->dev, &dev_attr_vrm)
-
-static ssize_t
-show_alarms_reg(struct device *dev, char *buf)
-{
-	struct w83627hf_data *data = w83627hf_update_device(dev);
-	return sprintf(buf, "%ld\n", (long) data->alarms);
-}
-static DEVICE_ATTR(alarms, S_IRUGO, show_alarms_reg, NULL);
-#define device_create_file_alarms(client) \
-device_create_file(&client->dev, &dev_attr_alarms)
-
-#define show_beep_reg(REG, reg) \
-static ssize_t show_beep_##reg (struct device *dev, char *buf) \
-{ \
-	struct w83627hf_data *data = w83627hf_update_device(dev); \
-	return sprintf(buf,"%ld\n", \
-		      (long)BEEP_##REG##_FROM_REG(data->beep_##reg)); \
-}
-show_beep_reg(ENABLE, enable)
-show_beep_reg(MASK, mask)
-
-#define BEEP_ENABLE			0	/* Store beep_enable */
-#define BEEP_MASK			1	/* Store beep_mask */
-
-static ssize_t
-store_beep_reg(struct device *dev, const char *buf, size_t count,
-	       int update_mask)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct w83627hf_data *data = i2c_get_clientdata(client);
-	u32 val, val2;
-
-	val = simple_strtoul(buf, NULL, 10);
-
-	down(&data->update_lock);
-
-	if (update_mask == BEEP_MASK) {	/* We are storing beep_mask */
-		data->beep_mask = BEEP_MASK_TO_REG(val);
-		w83627hf_write_value(client, W83781D_REG_BEEP_INTS1,
-				    data->beep_mask & 0xff);
-		w83627hf_write_value(client, W83781D_REG_BEEP_INTS3,
-				    ((data->beep_mask) >> 16) & 0xff);
-		val2 = (data->beep_mask >> 8) & 0x7f;
-	} else {		/* We are storing beep_enable */
-		val2 =
-		    w83627hf_read_value(client, W83781D_REG_BEEP_INTS2) & 0x7f;
-		data->beep_enable = BEEP_ENABLE_TO_REG(val);
-	}
-
-	w83627hf_write_value(client, W83781D_REG_BEEP_INTS2,
-			    val2 | data->beep_enable << 7);
-
-	up(&data->update_lock);
-	return count;
-}
-
-#define sysfs_beep(REG, reg) \
-static ssize_t show_regs_beep_##reg (struct device *dev, char *buf) \
-{ \
-	return show_beep_##reg(dev, buf); \
-} \
-static ssize_t \
-store_regs_beep_##reg (struct device *dev, const char *buf, size_t count) \
-{ \
-	return store_beep_reg(dev, buf, count, BEEP_##REG); \
-} \
-static DEVICE_ATTR(beep_##reg, S_IRUGO | S_IWUSR, \
-		  show_regs_beep_##reg, store_regs_beep_##reg);
-
-sysfs_beep(ENABLE, enable);
-sysfs_beep(MASK, mask);
-
-#define device_create_file_beep(client) \
-do { \
-device_create_file(&client->dev, &dev_attr_beep_enable); \
-device_create_file(&client->dev, &dev_attr_beep_mask); \
-} while (0)
-
-static ssize_t
-show_fan_div_reg(struct device *dev, char *buf, int nr)
-{
-	struct w83627hf_data *data = w83627hf_update_device(dev);
-	return sprintf(buf, "%ld\n",
-		       (long) DIV_FROM_REG(data->fan_div[nr - 1]));
-}
-
-/* Note: we save and restore the fan minimum here, because its value is
-   determined in part by the fan divisor.  This follows the principle of
-   least suprise; the user doesn't expect the fan minimum to change just
-   because the divisor changed. */
-static ssize_t
-store_fan_div_reg(struct device *dev, const char *buf, size_t count, int nr)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct w83627hf_data *data = i2c_get_clientdata(client);
-	unsigned long min;
-	u8 reg;
-	unsigned long val = simple_strtoul(buf, NULL, 10);
-
-	down(&data->update_lock);
-
-	/* Save fan_min */
-	min = FAN_FROM_REG(data->fan_min[nr],
-			   DIV_FROM_REG(data->fan_div[nr]));
-
-	data->fan_div[nr] = DIV_TO_REG(val);
-
-	reg = (w83627hf_read_value(client, nr==2 ? W83781D_REG_PIN : W83781D_REG_VID_FANDIV)
-	       & (nr==0 ? 0xcf : 0x3f))
-	    | ((data->fan_div[nr] & 0x03) << (nr==0 ? 4 : 6));
-	w83627hf_write_value(client, nr==2 ? W83781D_REG_PIN : W83781D_REG_VID_FANDIV, reg);
-
-	reg = (w83627hf_read_value(client, W83781D_REG_VBAT)
-	       & ~(1 << (5 + nr)))
-	    | ((data->fan_div[nr] & 0x04) << (3 + nr));
-	w83627hf_write_value(client, W83781D_REG_VBAT, reg);
-
-	/* Restore fan_min */
-	data->fan_min[nr] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr]));
-	w83627hf_write_value(client, W83781D_REG_FAN_MIN(nr+1), data->fan_min[nr]);
-
-	up(&data->update_lock);
-	return count;
-}
-
-#define sysfs_fan_div(offset) \
-static ssize_t show_regs_fan_div_##offset (struct device *dev, char *buf) \
-{ \
-	return show_fan_div_reg(dev, buf, offset); \
-} \
-static ssize_t \
-store_regs_fan_div_##offset (struct device *dev, \
-			    const char *buf, size_t count) \
-{ \
-	return store_fan_div_reg(dev, buf, count, offset - 1); \
-} \
-static DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, \
-		  show_regs_fan_div_##offset, store_regs_fan_div_##offset);
-
-sysfs_fan_div(1);
-sysfs_fan_div(2);
-sysfs_fan_div(3);
-
-#define device_create_file_fan_div(client, offset) \
-do { \
-device_create_file(&client->dev, &dev_attr_fan##offset##_div); \
-} while (0)
-
-static ssize_t
-show_pwm_reg(struct device *dev, char *buf, int nr)
-{
-	struct w83627hf_data *data = w83627hf_update_device(dev);
-	return sprintf(buf, "%ld\n", (long) data->pwm[nr - 1]);
-}
-
-static ssize_t
-store_pwm_reg(struct device *dev, const char *buf, size_t count, int nr)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct w83627hf_data *data = i2c_get_clientdata(client);
-	u32 val;
-
-	val = simple_strtoul(buf, NULL, 10);
-
-	down(&data->update_lock);
-
-	if (data->type == w83627thf) {
-		/* bits 0-3 are reserved  in 627THF */
-		data->pwm[nr - 1] = PWM_TO_REG(val) & 0xf0;
-		w83627hf_write_value(client,
-				     W836X7HF_REG_PWM(data->type, nr),
-				     data->pwm[nr - 1] |
-				     (w83627hf_read_value(client,
-				     W836X7HF_REG_PWM(data->type, nr)) & 0x0f));
-	} else {
-		data->pwm[nr - 1] = PWM_TO_REG(val);
-		w83627hf_write_value(client,
-				     W836X7HF_REG_PWM(data->type, nr),
-				     data->pwm[nr - 1]);
-	}
-
-	up(&data->update_lock);
-	return count;
-}
-
-#define sysfs_pwm(offset) \
-static ssize_t show_regs_pwm_##offset (struct device *dev, char *buf) \
-{ \
-	return show_pwm_reg(dev, buf, offset); \
-} \
-static ssize_t \
-store_regs_pwm_##offset (struct device *dev, const char *buf, size_t count) \
-{ \
-	return store_pwm_reg(dev, buf, count, offset); \
-} \
-static DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR, \
-		  show_regs_pwm_##offset, store_regs_pwm_##offset);
-
-sysfs_pwm(1);
-sysfs_pwm(2);
-sysfs_pwm(3);
-
-#define device_create_file_pwm(client, offset) \
-do { \
-device_create_file(&client->dev, &dev_attr_pwm##offset); \
-} while (0)
-
-static ssize_t
-show_sensor_reg(struct device *dev, char *buf, int nr)
-{
-	struct w83627hf_data *data = w83627hf_update_device(dev);
-	return sprintf(buf, "%ld\n", (long) data->sens[nr - 1]);
-}
-
-static ssize_t
-store_sensor_reg(struct device *dev, const char *buf, size_t count, int nr)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct w83627hf_data *data = i2c_get_clientdata(client);
-	u32 val, tmp;
-
-	val = simple_strtoul(buf, NULL, 10);
-
-	down(&data->update_lock);
-
-	switch (val) {
-	case 1:		/* PII/Celeron diode */
-		tmp = w83627hf_read_value(client, W83781D_REG_SCFG1);
-		w83627hf_write_value(client, W83781D_REG_SCFG1,
-				    tmp | BIT_SCFG1[nr - 1]);
-		tmp = w83627hf_read_value(client, W83781D_REG_SCFG2);
-		w83627hf_write_value(client, W83781D_REG_SCFG2,
-				    tmp | BIT_SCFG2[nr - 1]);
-		data->sens[nr - 1] = val;
-		break;
-	case 2:		/* 3904 */
-		tmp = w83627hf_read_value(client, W83781D_REG_SCFG1);
-		w83627hf_write_value(client, W83781D_REG_SCFG1,
-				    tmp | BIT_SCFG1[nr - 1]);
-		tmp = w83627hf_read_value(client, W83781D_REG_SCFG2);
-		w83627hf_write_value(client, W83781D_REG_SCFG2,
-				    tmp & ~BIT_SCFG2[nr - 1]);
-		data->sens[nr - 1] = val;
-		break;
-	case W83781D_DEFAULT_BETA:	/* thermistor */
-		tmp = w83627hf_read_value(client, W83781D_REG_SCFG1);
-		w83627hf_write_value(client, W83781D_REG_SCFG1,
-				    tmp & ~BIT_SCFG1[nr - 1]);
-		data->sens[nr - 1] = val;
-		break;
-	default:
-		dev_err(&client->dev,
-		       "Invalid sensor type %ld; must be 1, 2, or %d\n",
-		       (long) val, W83781D_DEFAULT_BETA);
-		break;
-	}
-
-	up(&data->update_lock);
-	return count;
-}
-
-#define sysfs_sensor(offset) \
-static ssize_t show_regs_sensor_##offset (struct device *dev, char *buf) \
-{ \
-    return show_sensor_reg(dev, buf, offset); \
-} \
-static ssize_t \
-store_regs_sensor_##offset (struct device *dev, const char *buf, size_t count) \
-{ \
-    return store_sensor_reg(dev, buf, count, offset); \
-} \
-static DEVICE_ATTR(temp##offset##_type, S_IRUGO | S_IWUSR, \
-		  show_regs_sensor_##offset, store_regs_sensor_##offset);
-
-sysfs_sensor(1);
-sysfs_sensor(2);
-sysfs_sensor(3);
-
-#define device_create_file_sensor(client, offset) \
-do { \
-device_create_file(&client->dev, &dev_attr_temp##offset##_type); \
-} while (0)
-
-
-/* This function is called when:
-     * w83627hf_driver is inserted (when this module is loaded), for each
-       available adapter
-     * when a new adapter is inserted (and w83627hf_driver is still present) */
-static int w83627hf_attach_adapter(struct i2c_adapter *adapter)
-{
-	return i2c_detect(adapter, &addr_data, w83627hf_detect);
-}
-
-static int w83627hf_find(int sioaddr, int *address)
-{
-	u16 val;
-
-	REG = sioaddr;
-	VAL = sioaddr + 1;
-
-	superio_enter();
-	val= superio_inb(DEVID);
-	if(val != W627_DEVID &&
-	   val != W627THF_DEVID &&
-	   val != W697_DEVID &&
-	   val != W637_DEVID) {
-		superio_exit();
-		return -ENODEV;
-	}
-
-	superio_select(W83627HF_LD_HWM);
-	val = (superio_inb(WINB_BASE_REG) << 8) |
-	       superio_inb(WINB_BASE_REG + 1);
-	*address = val & ~(WINB_EXTENT - 1);
-	if (*address == 0 && force_addr == 0) {
-		superio_exit();
-		return -ENODEV;
-	}
-	if (force_addr)
-		*address = force_addr;	/* so detect will get called */
-
-	superio_exit();
-	return 0;
-}
-
-int w83627hf_detect(struct i2c_adapter *adapter, int address,
-		   int kind)
-{
-	int val;
-	struct i2c_client *new_client;
-	struct w83627hf_data *data;
-	int err = 0;
-	const char *client_name = "";
-
-	if (!i2c_is_isa_adapter(adapter)) {
-		err = -ENODEV;
-		goto ERROR0;
-	}
-
-	if(force_addr)
-		address = force_addr & ~(WINB_EXTENT - 1);
-
-	if (!request_region(address, WINB_EXTENT, w83627hf_driver.name)) {
-		err = -EBUSY;
-		goto ERROR0;
-	}
-
-	if(force_addr) {
-		printk("w83627hf.o: forcing ISA address 0x%04X\n", address);
-		superio_enter();
-		superio_select(W83627HF_LD_HWM);
-		superio_outb(WINB_BASE_REG, address >> 8);
-		superio_outb(WINB_BASE_REG+1, address & 0xff);
-		superio_exit();
-	}
-
-	superio_enter();
-	val= superio_inb(DEVID);
-	if(val == W627_DEVID)
-		kind = w83627hf;
-	else if(val == W697_DEVID)
-		kind = w83697hf;
-	else if(val == W627THF_DEVID)
-		kind = w83627thf;
-	else if(val == W637_DEVID)
-		kind = w83637hf;
-	else {
-		dev_info(&adapter->dev,
-			 "Unsupported chip (dev_id=0x%02X).\n", val);
-		goto ERROR1;
-	}
-
-	superio_select(W83627HF_LD_HWM);
-	if((val = 0x01 & superio_inb(WINB_ACT_REG)) == 0)
-		superio_outb(WINB_ACT_REG, 1);
-	superio_exit();
-
-	/* OK. For now, we presume we have a valid client. We now create the
-	   client structure, even though we cannot fill it completely yet.
-	   But it allows us to access w83627hf_{read,write}_value. */
-
-	if (!(data = kmalloc(sizeof(struct w83627hf_data), GFP_KERNEL))) {
-		err = -ENOMEM;
-		goto ERROR1;
-	}
-	memset(data, 0, sizeof(struct w83627hf_data));
-
-	new_client = &data->client;
-	i2c_set_clientdata(new_client, data);
-	new_client->addr = address;
-	init_MUTEX(&data->lock);
-	new_client->adapter = adapter;
-	new_client->driver = &w83627hf_driver;
-	new_client->flags = 0;
-
-
-	if (kind == w83627hf) {
-		client_name = "w83627hf";
-	} else if (kind == w83627thf) {
-		client_name = "w83627thf";
-	} else if (kind == w83697hf) {
-		client_name = "w83697hf";
-	} else if (kind == w83637hf) {
-		client_name = "w83637hf";
-	}
-
-	/* Fill in the remaining client fields and put into the global list */
-	strlcpy(new_client->name, client_name, I2C_NAME_SIZE);
-	data->type = kind;
-	data->valid = 0;
-	init_MUTEX(&data->update_lock);
-
-	/* Tell the I2C layer a new client has arrived */
-	if ((err = i2c_attach_client(new_client)))
-		goto ERROR2;
-
-	data->lm75 = NULL;
-
-	/* Initialize the chip */
-	w83627hf_init_client(new_client);
-
-	/* A few vars need to be filled upon startup */
-	data->fan_min[0] = w83627hf_read_value(new_client, W83781D_REG_FAN_MIN(1));
-	data->fan_min[1] = w83627hf_read_value(new_client, W83781D_REG_FAN_MIN(2));
-	data->fan_min[2] = w83627hf_read_value(new_client, W83781D_REG_FAN_MIN(3));
-
-	/* Register sysfs hooks */
-	device_create_file_in(new_client, 0);
-	if (kind != w83697hf)
-		device_create_file_in(new_client, 1);
-	device_create_file_in(new_client, 2);
-	device_create_file_in(new_client, 3);
-	device_create_file_in(new_client, 4);
-	if (kind != w83627thf && kind != w83637hf) {
-		device_create_file_in(new_client, 5);
-		device_create_file_in(new_client, 6);
-	}
-	device_create_file_in(new_client, 7);
-	device_create_file_in(new_client, 8);
-
-	device_create_file_fan(new_client, 1);
-	device_create_file_fan(new_client, 2);
-	if (kind != w83697hf)
-		device_create_file_fan(new_client, 3);
-
-	device_create_file_temp(new_client, 1);
-	device_create_file_temp(new_client, 2);
-	if (kind != w83697hf)
-		device_create_file_temp(new_client, 3);
-
-	if (kind != w83697hf)
-		device_create_file_vid(new_client);
-
-	if (kind != w83697hf)
-		device_create_file_vrm(new_client);
-
-	device_create_file_fan_div(new_client, 1);
-	device_create_file_fan_div(new_client, 2);
-	if (kind != w83697hf)
-		device_create_file_fan_div(new_client, 3);
-
-	device_create_file_alarms(new_client);
-
-	device_create_file_beep(new_client);
-
-	device_create_file_pwm(new_client, 1);
-	device_create_file_pwm(new_client, 2);
-	if (kind == w83627thf || kind == w83637hf)
-		device_create_file_pwm(new_client, 3);
-
-	device_create_file_sensor(new_client, 1);
-	device_create_file_sensor(new_client, 2);
-	if (kind != w83697hf)
-		device_create_file_sensor(new_client, 3);
-
-	return 0;
-
-      ERROR2:
-	kfree(data);
-      ERROR1:
-	release_region(address, WINB_EXTENT);
-      ERROR0:
-	return err;
-}
-
-static int w83627hf_detach_client(struct i2c_client *client)
-{
-	int err;
-
-	if ((err = i2c_detach_client(client))) {
-		dev_err(&client->dev,
-		       "Client deregistration failed, client not detached.\n");
-		return err;
-	}
-
-	release_region(client->addr, WINB_EXTENT);
-	kfree(i2c_get_clientdata(client));
-
-	return 0;
-}
-
-
-/*
-   ISA access must always be locked explicitly!
-   We ignore the W83781D BUSY flag at this moment - it could lead to deadlocks,
-   would slow down the W83781D access and should not be necessary.
-   There are some ugly typecasts here, but the good news is - they should
-   nowhere else be necessary! */
-static int w83627hf_read_value(struct i2c_client *client, u16 reg)
-{
-	struct w83627hf_data *data = i2c_get_clientdata(client);
-	int res, word_sized;
-
-	down(&data->lock);
-	word_sized = (((reg & 0xff00) == 0x100)
-		   || ((reg & 0xff00) == 0x200))
-		  && (((reg & 0x00ff) == 0x50)
-		   || ((reg & 0x00ff) == 0x53)
-		   || ((reg & 0x00ff) == 0x55));
-	if (reg & 0xff00) {
-		outb_p(W83781D_REG_BANK,
-		       client->addr + W83781D_ADDR_REG_OFFSET);
-		outb_p(reg >> 8,
-		       client->addr + W83781D_DATA_REG_OFFSET);
-	}
-	outb_p(reg & 0xff, client->addr + W83781D_ADDR_REG_OFFSET);
-	res = inb_p(client->addr + W83781D_DATA_REG_OFFSET);
-	if (word_sized) {
-		outb_p((reg & 0xff) + 1,
-		       client->addr + W83781D_ADDR_REG_OFFSET);
-		res =
-		    (res << 8) + inb_p(client->addr +
-				       W83781D_DATA_REG_OFFSET);
-	}
-	if (reg & 0xff00) {
-		outb_p(W83781D_REG_BANK,
-		       client->addr + W83781D_ADDR_REG_OFFSET);
-		outb_p(0, client->addr + W83781D_DATA_REG_OFFSET);
-	}
-	up(&data->lock);
-	return res;
-}
-
-static int w83627thf_read_gpio5(struct i2c_client *client)
-{
-	int res = 0xff, sel;
-
-	superio_enter();
-	superio_select(W83627HF_LD_GPIO5);
-
-	/* Make sure these GPIO pins are enabled */
-	if (!(superio_inb(W83627THF_GPIO5_EN) & (1<<3))) {
-		dev_dbg(&client->dev, "GPIO5 disabled, no VID function\n");
-		goto exit;
-	}
-
-	/* Make sure the pins are configured for input
-	   There must be at least five (VRM 9), and possibly 6 (VRM 10) */
-	sel = superio_inb(W83627THF_GPIO5_IOSR);
-	if ((sel & 0x1f) != 0x1f) {
-		dev_dbg(&client->dev, "GPIO5 not configured for VID "
-			"function\n");
-		goto exit;
-	}
-
-	dev_info(&client->dev, "Reading VID from GPIO5\n");
-	res = superio_inb(W83627THF_GPIO5_DR) & sel;
-
-exit:
-	superio_exit();
-	return res;
-}
-
-static int w83627hf_write_value(struct i2c_client *client, u16 reg, u16 value)
-{
-	struct w83627hf_data *data = i2c_get_clientdata(client);
-	int word_sized;
-
-	down(&data->lock);
-	word_sized = (((reg & 0xff00) == 0x100)
-		   || ((reg & 0xff00) == 0x200))
-		  && (((reg & 0x00ff) == 0x53)
-		   || ((reg & 0x00ff) == 0x55));
-	if (reg & 0xff00) {
-		outb_p(W83781D_REG_BANK,
-		       client->addr + W83781D_ADDR_REG_OFFSET);
-		outb_p(reg >> 8,
-		       client->addr + W83781D_DATA_REG_OFFSET);
-	}
-	outb_p(reg & 0xff, client->addr + W83781D_ADDR_REG_OFFSET);
-	if (word_sized) {
-		outb_p(value >> 8,
-		       client->addr + W83781D_DATA_REG_OFFSET);
-		outb_p((reg & 0xff) + 1,
-		       client->addr + W83781D_ADDR_REG_OFFSET);
-	}
-	outb_p(value & 0xff,
-	       client->addr + W83781D_DATA_REG_OFFSET);
-	if (reg & 0xff00) {
-		outb_p(W83781D_REG_BANK,
-		       client->addr + W83781D_ADDR_REG_OFFSET);
-		outb_p(0, client->addr + W83781D_DATA_REG_OFFSET);
-	}
-	up(&data->lock);
-	return 0;
-}
-
-/* Called when we have found a new W83781D. It should set limits, etc. */
-static void w83627hf_init_client(struct i2c_client *client)
-{
-	struct w83627hf_data *data = i2c_get_clientdata(client);
-	int i;
-	int type = data->type;
-	u8 tmp;
-
-	if(init) {
-		/* save this register */
-		i = w83627hf_read_value(client, W83781D_REG_BEEP_CONFIG);
-		/* Reset all except Watchdog values and last conversion values
-		   This sets fan-divs to 2, among others */
-		w83627hf_write_value(client, W83781D_REG_CONFIG, 0x80);
-		/* Restore the register and disable power-on abnormal beep.
-		   This saves FAN 1/2/3 input/output values set by BIOS. */
-		w83627hf_write_value(client, W83781D_REG_BEEP_CONFIG, i | 0x80);
-		/* Disable master beep-enable (reset turns it on).
-		   Individual beeps should be reset to off but for some reason
-		   disabling this bit helps some people not get beeped */
-		w83627hf_write_value(client, W83781D_REG_BEEP_INTS2, 0);
-	}
-
-	/* Minimize conflicts with other winbond i2c-only clients...  */
-	/* disable i2c subclients... how to disable main i2c client?? */
-	/* force i2c address to relatively uncommon address */
-	w83627hf_write_value(client, W83781D_REG_I2C_SUBADDR, 0x89);
-	w83627hf_write_value(client, W83781D_REG_I2C_ADDR, force_i2c);
-
-	/* Read VID only once */
-	if (w83627hf == data->type || w83637hf == data->type) {
-		int lo = w83627hf_read_value(client, W83781D_REG_VID_FANDIV);
-		int hi = w83627hf_read_value(client, W83781D_REG_CHIPID);
-		data->vid = (lo & 0x0f) | ((hi & 0x01) << 4);
-	} else if (w83627thf == data->type) {
-		data->vid = w83627thf_read_gpio5(client) & 0x3f;
-	}
-
-	/* Read VRM & OVT Config only once */
-	if (w83627thf == data->type || w83637hf == data->type) {
-		data->vrm_ovt = 
-			w83627hf_read_value(client, W83627THF_REG_VRM_OVT_CFG);
-		data->vrm = (data->vrm_ovt & 0x01) ? 90 : 82;
-	} else {
-		/* Convert VID to voltage based on default VRM */
-		data->vrm = i2c_which_vrm();
-	}
-
-	tmp = w83627hf_read_value(client, W83781D_REG_SCFG1);
-	for (i = 1; i <= 3; i++) {
-		if (!(tmp & BIT_SCFG1[i - 1])) {
-			data->sens[i - 1] = W83781D_DEFAULT_BETA;
-		} else {
-			if (w83627hf_read_value
-			    (client,
-			     W83781D_REG_SCFG2) & BIT_SCFG2[i - 1])
-				data->sens[i - 1] = 1;
-			else
-				data->sens[i - 1] = 2;
-		}
-		if ((type == w83697hf) && (i == 2))
-			break;
-	}
-
-	if(init) {
-		/* Enable temp2 */
-		tmp = w83627hf_read_value(client, W83781D_REG_TEMP2_CONFIG);
-		if (tmp & 0x01) {
-			dev_warn(&client->dev, "Enabling temp2, readings "
-				 "might not make sense\n");
-			w83627hf_write_value(client, W83781D_REG_TEMP2_CONFIG,
-				tmp & 0xfe);
-		}
-
-		/* Enable temp3 */
-		if (type != w83697hf) {
-			tmp = w83627hf_read_value(client,
-				W83781D_REG_TEMP3_CONFIG);
-			if (tmp & 0x01) {
-				dev_warn(&client->dev, "Enabling temp3, "
-					 "readings might not make sense\n");
-				w83627hf_write_value(client,
-					W83781D_REG_TEMP3_CONFIG, tmp & 0xfe);
-			}
-		}
-
-		if (type == w83627hf) {
-			/* enable PWM2 control (can't hurt since PWM reg
-		           should have been reset to 0xff) */
-			w83627hf_write_value(client, W83627HF_REG_PWMCLK12,
-					    0x19);
-		}
-		/* enable comparator mode for temp2 and temp3 so
-	           alarm indication will work correctly */
-		i = w83627hf_read_value(client, W83781D_REG_IRQ);
-		if (!(i & 0x40))
-			w83627hf_write_value(client, W83781D_REG_IRQ,
-					    i | 0x40);
-	}
-
-	/* Start monitoring */
-	w83627hf_write_value(client, W83781D_REG_CONFIG,
-			    (w83627hf_read_value(client,
-						W83781D_REG_CONFIG) & 0xf7)
-			    | 0x01);
-}
-
-static struct w83627hf_data *w83627hf_update_device(struct device *dev)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct w83627hf_data *data = i2c_get_clientdata(client);
-	int i;
-
-	down(&data->update_lock);
-
-	if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
-	    || !data->valid) {
-		for (i = 0; i <= 8; i++) {
-			/* skip missing sensors */
-			if (((data->type == w83697hf) && (i == 1)) ||
-			    ((data->type == w83627thf || data->type == w83637hf)
-			    && (i == 4 || i == 5)))
-				continue;
-			data->in[i] =
-			    w83627hf_read_value(client, W83781D_REG_IN(i));
-			data->in_min[i] =
-			    w83627hf_read_value(client,
-					       W83781D_REG_IN_MIN(i));
-			data->in_max[i] =
-			    w83627hf_read_value(client,
-					       W83781D_REG_IN_MAX(i));
-		}
-		for (i = 1; i <= 3; i++) {
-			data->fan[i - 1] =
-			    w83627hf_read_value(client, W83781D_REG_FAN(i));
-			data->fan_min[i - 1] =
-			    w83627hf_read_value(client,
-					       W83781D_REG_FAN_MIN(i));
-		}
-		for (i = 1; i <= 3; i++) {
-			u8 tmp = w83627hf_read_value(client,
-				W836X7HF_REG_PWM(data->type, i));
- 			/* bits 0-3 are reserved  in 627THF */
- 			if (data->type == w83627thf)
-				tmp &= 0xf0;
-			data->pwm[i - 1] = tmp;
-			if(i == 2 &&
-			   (data->type == w83627hf || data->type == w83697hf))
-				break;
-		}
-
-		data->temp = w83627hf_read_value(client, W83781D_REG_TEMP(1));
-		data->temp_max =
-		    w83627hf_read_value(client, W83781D_REG_TEMP_OVER(1));
-		data->temp_max_hyst =
-		    w83627hf_read_value(client, W83781D_REG_TEMP_HYST(1));
-		data->temp_add[0] =
-		    w83627hf_read_value(client, W83781D_REG_TEMP(2));
-		data->temp_max_add[0] =
-		    w83627hf_read_value(client, W83781D_REG_TEMP_OVER(2));
-		data->temp_max_hyst_add[0] =
-		    w83627hf_read_value(client, W83781D_REG_TEMP_HYST(2));
-		if (data->type != w83697hf) {
-			data->temp_add[1] =
-			  w83627hf_read_value(client, W83781D_REG_TEMP(3));
-			data->temp_max_add[1] =
-			  w83627hf_read_value(client, W83781D_REG_TEMP_OVER(3));
-			data->temp_max_hyst_add[1] =
-			  w83627hf_read_value(client, W83781D_REG_TEMP_HYST(3));
-		}
-
-		i = w83627hf_read_value(client, W83781D_REG_VID_FANDIV);
-		data->fan_div[0] = (i >> 4) & 0x03;
-		data->fan_div[1] = (i >> 6) & 0x03;
-		if (data->type != w83697hf) {
-			data->fan_div[2] = (w83627hf_read_value(client,
-					       W83781D_REG_PIN) >> 6) & 0x03;
-		}
-		i = w83627hf_read_value(client, W83781D_REG_VBAT);
-		data->fan_div[0] |= (i >> 3) & 0x04;
-		data->fan_div[1] |= (i >> 4) & 0x04;
-		if (data->type != w83697hf)
-			data->fan_div[2] |= (i >> 5) & 0x04;
-		data->alarms =
-		    w83627hf_read_value(client, W83781D_REG_ALARM1) |
-		    (w83627hf_read_value(client, W83781D_REG_ALARM2) << 8) |
-		    (w83627hf_read_value(client, W83781D_REG_ALARM3) << 16);
-		i = w83627hf_read_value(client, W83781D_REG_BEEP_INTS2);
-		data->beep_enable = i >> 7;
-		data->beep_mask = ((i & 0x7f) << 8) |
-		    w83627hf_read_value(client, W83781D_REG_BEEP_INTS1) |
-		    w83627hf_read_value(client, W83781D_REG_BEEP_INTS3) << 16;
-		data->last_updated = jiffies;
-		data->valid = 1;
-	}
-
-	up(&data->update_lock);
-
-	return data;
-}
-
-static int __init sensors_w83627hf_init(void)
-{
-	int addr;
-
-	if (w83627hf_find(0x2e, &addr)
-	 && w83627hf_find(0x4e, &addr)) {
-		return -ENODEV;
-	}
-	normal_isa[0] = addr;
-
-	return i2c_add_driver(&w83627hf_driver);
-}
-
-static void __exit sensors_w83627hf_exit(void)
-{
-	i2c_del_driver(&w83627hf_driver);
-}
-
-MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>, "
-	      "Philip Edelbrock <phil@netroedge.com>, "
-	      "and Mark Studebaker <mdsxyz123@yahoo.com>");
-MODULE_DESCRIPTION("W83627HF driver");
-MODULE_LICENSE("GPL");
-
-module_init(sensors_w83627hf_init);
-module_exit(sensors_w83627hf_exit);
diff --git a/drivers/i2c/chips/w83781d.c b/drivers/i2c/chips/w83781d.c
deleted file mode 100644
--- a/drivers/i2c/chips/w83781d.c
+++ /dev/null
@@ -1,1664 +0,0 @@
-/*
-    w83781d.c - Part of lm_sensors, Linux kernel modules for hardware
-                monitoring
-    Copyright (c) 1998 - 2001  Frodo Looijaard <frodol@dds.nl>,
-    Philip Edelbrock <phil@netroedge.com>,
-    and Mark Studebaker <mdsxyz123@yahoo.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., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-/*
-    Supports following chips:
-
-    Chip	#vin	#fanin	#pwm	#temp	wchipid	vendid	i2c	ISA
-    as99127f	7	3	0	3	0x31	0x12c3	yes	no
-    as99127f rev.2 (type_name = as99127f)	0x31	0x5ca3	yes	no
-    w83781d	7	3	0	3	0x10-1	0x5ca3	yes	yes
-    w83627hf	9	3	2	3	0x21	0x5ca3	yes	yes(LPC)
-    w83627thf	9	3	2	3	0x90	0x5ca3	no	yes(LPC)
-    w83782d	9	3	2-4	3	0x30	0x5ca3	yes	yes
-    w83783s	5-6	3	2	1-2	0x40	0x5ca3	yes	no
-    w83697hf	8	2	2	2	0x60	0x5ca3	no	yes(LPC)
-
-*/
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/jiffies.h>
-#include <linux/i2c.h>
-#include <linux/i2c-sensor.h>
-#include <linux/i2c-vid.h>
-#include <asm/io.h>
-#include "lm75.h"
-
-/* Addresses to scan */
-static unsigned short normal_i2c[] = { 0x20, 0x21, 0x22, 0x23, 0x24, 0x25,
-					0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b,
-					0x2c, 0x2d, 0x2e, 0x2f, I2C_CLIENT_END };
-static unsigned int normal_isa[] = { 0x0290, I2C_CLIENT_ISA_END };
-
-/* Insmod parameters */
-SENSORS_INSMOD_6(w83781d, w83782d, w83783s, w83627hf, as99127f, w83697hf);
-I2C_CLIENT_MODULE_PARM(force_subclients, "List of subclient addresses: "
-		    "{bus, clientaddr, subclientaddr1, subclientaddr2}");
-
-static int init = 1;
-module_param(init, bool, 0);
-MODULE_PARM_DESC(init, "Set to zero to bypass chip initialization");
-
-/* Constants specified below */
-
-/* Length of ISA address segment */
-#define W83781D_EXTENT			8
-
-/* Where are the ISA address/data registers relative to the base address */
-#define W83781D_ADDR_REG_OFFSET		5
-#define W83781D_DATA_REG_OFFSET		6
-
-/* The W83781D registers */
-/* The W83782D registers for nr=7,8 are in bank 5 */
-#define W83781D_REG_IN_MAX(nr)		((nr < 7) ? (0x2b + (nr) * 2) : \
-						    (0x554 + (((nr) - 7) * 2)))
-#define W83781D_REG_IN_MIN(nr)		((nr < 7) ? (0x2c + (nr) * 2) : \
-						    (0x555 + (((nr) - 7) * 2)))
-#define W83781D_REG_IN(nr)		((nr < 7) ? (0x20 + (nr)) : \
-						    (0x550 + (nr) - 7))
-
-#define W83781D_REG_FAN_MIN(nr)		(0x3a + (nr))
-#define W83781D_REG_FAN(nr)		(0x27 + (nr))
-
-#define W83781D_REG_BANK		0x4E
-#define W83781D_REG_TEMP2_CONFIG	0x152
-#define W83781D_REG_TEMP3_CONFIG	0x252
-#define W83781D_REG_TEMP(nr)		((nr == 3) ? (0x0250) : \
-					((nr == 2) ? (0x0150) : \
-						     (0x27)))
-#define W83781D_REG_TEMP_HYST(nr)	((nr == 3) ? (0x253) : \
-					((nr == 2) ? (0x153) : \
-						     (0x3A)))
-#define W83781D_REG_TEMP_OVER(nr)	((nr == 3) ? (0x255) : \
-					((nr == 2) ? (0x155) : \
-						     (0x39)))
-
-#define W83781D_REG_CONFIG		0x40
-#define W83781D_REG_ALARM1		0x41
-#define W83781D_REG_ALARM2		0x42
-#define W83781D_REG_ALARM3		0x450	/* not on W83781D */
-
-#define W83781D_REG_IRQ			0x4C
-#define W83781D_REG_BEEP_CONFIG		0x4D
-#define W83781D_REG_BEEP_INTS1		0x56
-#define W83781D_REG_BEEP_INTS2		0x57
-#define W83781D_REG_BEEP_INTS3		0x453	/* not on W83781D */
-
-#define W83781D_REG_VID_FANDIV		0x47
-
-#define W83781D_REG_CHIPID		0x49
-#define W83781D_REG_WCHIPID		0x58
-#define W83781D_REG_CHIPMAN		0x4F
-#define W83781D_REG_PIN			0x4B
-
-/* 782D/783S only */
-#define W83781D_REG_VBAT		0x5D
-
-/* PWM 782D (1-4) and 783S (1-2) only */
-#define W83781D_REG_PWM1		0x5B	/* 782d and 783s/627hf datasheets disagree */
-						/* on which is which; */
-#define W83781D_REG_PWM2		0x5A	/* We follow the 782d convention here, */
-						/* However 782d is probably wrong. */
-#define W83781D_REG_PWM3		0x5E
-#define W83781D_REG_PWM4		0x5F
-#define W83781D_REG_PWMCLK12		0x5C
-#define W83781D_REG_PWMCLK34		0x45C
-static const u8 regpwm[] = { W83781D_REG_PWM1, W83781D_REG_PWM2,
-	W83781D_REG_PWM3, W83781D_REG_PWM4
-};
-
-#define W83781D_REG_PWM(nr)		(regpwm[(nr) - 1])
-
-#define W83781D_REG_I2C_ADDR		0x48
-#define W83781D_REG_I2C_SUBADDR		0x4A
-
-/* The following are undocumented in the data sheets however we
-   received the information in an email from Winbond tech support */
-/* Sensor selection - not on 781d */
-#define W83781D_REG_SCFG1		0x5D
-static const u8 BIT_SCFG1[] = { 0x02, 0x04, 0x08 };
-
-#define W83781D_REG_SCFG2		0x59
-static const u8 BIT_SCFG2[] = { 0x10, 0x20, 0x40 };
-
-#define W83781D_DEFAULT_BETA		3435
-
-/* RT Table registers */
-#define W83781D_REG_RT_IDX		0x50
-#define W83781D_REG_RT_VAL		0x51
-
-/* Conversions. Rounding and limit checking is only done on the TO_REG
-   variants. Note that you should be a bit careful with which arguments
-   these macros are called: arguments may be evaluated more than once.
-   Fixing this is just not worth it. */
-#define IN_TO_REG(val)			(SENSORS_LIMIT((((val) * 10 + 8)/16),0,255))
-#define IN_FROM_REG(val)		(((val) * 16) / 10)
-
-static inline u8
-FAN_TO_REG(long rpm, int div)
-{
-	if (rpm == 0)
-		return 255;
-	rpm = SENSORS_LIMIT(rpm, 1, 1000000);
-	return SENSORS_LIMIT((1350000 + rpm * div / 2) / (rpm * div), 1, 254);
-}
-
-#define FAN_FROM_REG(val,div)		((val) == 0   ? -1 : \
-					((val) == 255 ? 0 : \
-							1350000 / ((val) * (div))))
-
-#define TEMP_TO_REG(val)		(SENSORS_LIMIT(((val) < 0 ? (val)+0x100*1000 \
-						: (val)) / 1000, 0, 0xff))
-#define TEMP_FROM_REG(val)		(((val) & 0x80 ? (val)-0x100 : (val)) * 1000)
-
-#define ALARMS_FROM_REG(val)		(val)
-#define PWM_FROM_REG(val)		(val)
-#define PWM_TO_REG(val)			(SENSORS_LIMIT((val),0,255))
-#define BEEP_MASK_FROM_REG(val,type)	((type) == as99127f ? \
-					 (val) ^ 0x7fff : (val))
-#define BEEP_MASK_TO_REG(val,type)	((type) == as99127f ? \
-					 (~(val)) & 0x7fff : (val) & 0xffffff)
-
-#define BEEP_ENABLE_TO_REG(val)		((val) ? 1 : 0)
-#define BEEP_ENABLE_FROM_REG(val)	((val) ? 1 : 0)
-
-#define DIV_FROM_REG(val)		(1 << (val))
-
-static inline u8
-DIV_TO_REG(long val, enum chips type)
-{
-	int i;
-	val = SENSORS_LIMIT(val, 1,
-			    ((type == w83781d
-			      || type == as99127f) ? 8 : 128)) >> 1;
-	for (i = 0; i < 6; i++) {
-		if (val == 0)
-			break;
-		val >>= 1;
-	}
-	return ((u8) i);
-}
-
-/* There are some complications in a module like this. First off, W83781D chips
-   may be both present on the SMBus and the ISA bus, and we have to handle
-   those cases separately at some places. Second, there might be several
-   W83781D chips available (well, actually, that is probably never done; but
-   it is a clean illustration of how to handle a case like that). Finally,
-   a specific chip may be attached to *both* ISA and SMBus, and we would
-   not like to detect it double. Fortunately, in the case of the W83781D at
-   least, a register tells us what SMBus address we are on, so that helps
-   a bit - except if there could be more than one SMBus. Groan. No solution
-   for this yet. */
-
-/* This module may seem overly long and complicated. In fact, it is not so
-   bad. Quite a lot of bookkeeping is done. A real driver can often cut
-   some corners. */
-
-/* For each registered W83781D, we need to keep some data in memory. That
-   data is pointed to by w83781d_list[NR]->data. The structure itself is
-   dynamically allocated, at the same time when a new w83781d client is
-   allocated. */
-struct w83781d_data {
-	struct i2c_client client;
-	struct semaphore lock;
-	enum chips type;
-
-	struct semaphore update_lock;
-	char valid;		/* !=0 if following fields are valid */
-	unsigned long last_updated;	/* In jiffies */
-
-	struct i2c_client *lm75[2];	/* for secondary I2C addresses */
-	/* array of 2 pointers to subclients */
-
-	u8 in[9];		/* Register value - 8 & 9 for 782D only */
-	u8 in_max[9];		/* Register value - 8 & 9 for 782D only */
-	u8 in_min[9];		/* Register value - 8 & 9 for 782D only */
-	u8 fan[3];		/* Register value */
-	u8 fan_min[3];		/* Register value */
-	u8 temp;
-	u8 temp_max;		/* Register value */
-	u8 temp_max_hyst;	/* Register value */
-	u16 temp_add[2];	/* Register value */
-	u16 temp_max_add[2];	/* Register value */
-	u16 temp_max_hyst_add[2];	/* Register value */
-	u8 fan_div[3];		/* Register encoding, shifted right */
-	u8 vid;			/* Register encoding, combined */
-	u32 alarms;		/* Register encoding, combined */
-	u32 beep_mask;		/* Register encoding, combined */
-	u8 beep_enable;		/* Boolean */
-	u8 pwm[4];		/* Register value */
-	u8 pwmenable[4];	/* Boolean */
-	u16 sens[3];		/* 782D/783S only.
-				   1 = pentium diode; 2 = 3904 diode;
-				   3000-5000 = thermistor beta.
-				   Default = 3435. 
-				   Other Betas unimplemented */
-	u8 vrm;
-};
-
-static int w83781d_attach_adapter(struct i2c_adapter *adapter);
-static int w83781d_detect(struct i2c_adapter *adapter, int address, int kind);
-static int w83781d_detach_client(struct i2c_client *client);
-
-static int w83781d_read_value(struct i2c_client *client, u16 register);
-static int w83781d_write_value(struct i2c_client *client, u16 register,
-			       u16 value);
-static struct w83781d_data *w83781d_update_device(struct device *dev);
-static void w83781d_init_client(struct i2c_client *client);
-
-static struct i2c_driver w83781d_driver = {
-	.owner = THIS_MODULE,
-	.name = "w83781d",
-	.id = I2C_DRIVERID_W83781D,
-	.flags = I2C_DF_NOTIFY,
-	.attach_adapter = w83781d_attach_adapter,
-	.detach_client = w83781d_detach_client,
-};
-
-/* following are the sysfs callback functions */
-#define show_in_reg(reg) \
-static ssize_t show_##reg (struct device *dev, char *buf, int nr) \
-{ \
-	struct w83781d_data *data = w83781d_update_device(dev); \
-	return sprintf(buf,"%ld\n", (long)IN_FROM_REG(data->reg[nr] * 10)); \
-}
-show_in_reg(in);
-show_in_reg(in_min);
-show_in_reg(in_max);
-
-#define store_in_reg(REG, reg) \
-static ssize_t store_in_##reg (struct device *dev, const char *buf, size_t count, int nr) \
-{ \
-	struct i2c_client *client = to_i2c_client(dev); \
-	struct w83781d_data *data = i2c_get_clientdata(client); \
-	u32 val; \
-	 \
-	val = simple_strtoul(buf, NULL, 10) / 10; \
-	 \
-	down(&data->update_lock); \
-	data->in_##reg[nr] = IN_TO_REG(val); \
-	w83781d_write_value(client, W83781D_REG_IN_##REG(nr), data->in_##reg[nr]); \
-	 \
-	up(&data->update_lock); \
-	return count; \
-}
-store_in_reg(MIN, min);
-store_in_reg(MAX, max);
-
-#define sysfs_in_offset(offset) \
-static ssize_t \
-show_regs_in_##offset (struct device *dev, char *buf) \
-{ \
-        return show_in(dev, buf, offset); \
-} \
-static DEVICE_ATTR(in##offset##_input, S_IRUGO, show_regs_in_##offset, NULL);
-
-#define sysfs_in_reg_offset(reg, offset) \
-static ssize_t show_regs_in_##reg##offset (struct device *dev, char *buf) \
-{ \
-	return show_in_##reg (dev, buf, offset); \
-} \
-static ssize_t store_regs_in_##reg##offset (struct device *dev, const char *buf, size_t count) \
-{ \
-	return store_in_##reg (dev, buf, count, offset); \
-} \
-static DEVICE_ATTR(in##offset##_##reg, S_IRUGO| S_IWUSR, show_regs_in_##reg##offset, store_regs_in_##reg##offset);
-
-#define sysfs_in_offsets(offset) \
-sysfs_in_offset(offset); \
-sysfs_in_reg_offset(min, offset); \
-sysfs_in_reg_offset(max, offset);
-
-sysfs_in_offsets(0);
-sysfs_in_offsets(1);
-sysfs_in_offsets(2);
-sysfs_in_offsets(3);
-sysfs_in_offsets(4);
-sysfs_in_offsets(5);
-sysfs_in_offsets(6);
-sysfs_in_offsets(7);
-sysfs_in_offsets(8);
-
-#define device_create_file_in(client, offset) \
-do { \
-device_create_file(&client->dev, &dev_attr_in##offset##_input); \
-device_create_file(&client->dev, &dev_attr_in##offset##_min); \
-device_create_file(&client->dev, &dev_attr_in##offset##_max); \
-} while (0)
-
-#define show_fan_reg(reg) \
-static ssize_t show_##reg (struct device *dev, char *buf, int nr) \
-{ \
-	struct w83781d_data *data = w83781d_update_device(dev); \
-	return sprintf(buf,"%ld\n", \
-		FAN_FROM_REG(data->reg[nr-1], (long)DIV_FROM_REG(data->fan_div[nr-1]))); \
-}
-show_fan_reg(fan);
-show_fan_reg(fan_min);
-
-static ssize_t
-store_fan_min(struct device *dev, const char *buf, size_t count, int nr)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct w83781d_data *data = i2c_get_clientdata(client);
-	u32 val;
-
-	val = simple_strtoul(buf, NULL, 10);
-
-	down(&data->update_lock);
-	data->fan_min[nr - 1] =
-	    FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr - 1]));
-	w83781d_write_value(client, W83781D_REG_FAN_MIN(nr),
-			    data->fan_min[nr - 1]);
-
-	up(&data->update_lock);
-	return count;
-}
-
-#define sysfs_fan_offset(offset) \
-static ssize_t show_regs_fan_##offset (struct device *dev, char *buf) \
-{ \
-	return show_fan(dev, buf, offset); \
-} \
-static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_regs_fan_##offset, NULL);
-
-#define sysfs_fan_min_offset(offset) \
-static ssize_t show_regs_fan_min##offset (struct device *dev, char *buf) \
-{ \
-	return show_fan_min(dev, buf, offset); \
-} \
-static ssize_t store_regs_fan_min##offset (struct device *dev, const char *buf, size_t count) \
-{ \
-	return store_fan_min(dev, buf, count, offset); \
-} \
-static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, show_regs_fan_min##offset, store_regs_fan_min##offset);
-
-sysfs_fan_offset(1);
-sysfs_fan_min_offset(1);
-sysfs_fan_offset(2);
-sysfs_fan_min_offset(2);
-sysfs_fan_offset(3);
-sysfs_fan_min_offset(3);
-
-#define device_create_file_fan(client, offset) \
-do { \
-device_create_file(&client->dev, &dev_attr_fan##offset##_input); \
-device_create_file(&client->dev, &dev_attr_fan##offset##_min); \
-} while (0)
-
-#define show_temp_reg(reg) \
-static ssize_t show_##reg (struct device *dev, char *buf, int nr) \
-{ \
-	struct w83781d_data *data = w83781d_update_device(dev); \
-	if (nr >= 2) {	/* TEMP2 and TEMP3 */ \
-		return sprintf(buf,"%d\n", \
-			LM75_TEMP_FROM_REG(data->reg##_add[nr-2])); \
-	} else {	/* TEMP1 */ \
-		return sprintf(buf,"%ld\n", (long)TEMP_FROM_REG(data->reg)); \
-	} \
-}
-show_temp_reg(temp);
-show_temp_reg(temp_max);
-show_temp_reg(temp_max_hyst);
-
-#define store_temp_reg(REG, reg) \
-static ssize_t store_temp_##reg (struct device *dev, const char *buf, size_t count, int nr) \
-{ \
-	struct i2c_client *client = to_i2c_client(dev); \
-	struct w83781d_data *data = i2c_get_clientdata(client); \
-	s32 val; \
-	 \
-	val = simple_strtol(buf, NULL, 10); \
-	 \
-	down(&data->update_lock); \
-	 \
-	if (nr >= 2) {	/* TEMP2 and TEMP3 */ \
-		data->temp_##reg##_add[nr-2] = LM75_TEMP_TO_REG(val); \
-		w83781d_write_value(client, W83781D_REG_TEMP_##REG(nr), \
-				data->temp_##reg##_add[nr-2]); \
-	} else {	/* TEMP1 */ \
-		data->temp_##reg = TEMP_TO_REG(val); \
-		w83781d_write_value(client, W83781D_REG_TEMP_##REG(nr), \
-			data->temp_##reg); \
-	} \
-	 \
-	up(&data->update_lock); \
-	return count; \
-}
-store_temp_reg(OVER, max);
-store_temp_reg(HYST, max_hyst);
-
-#define sysfs_temp_offset(offset) \
-static ssize_t \
-show_regs_temp_##offset (struct device *dev, char *buf) \
-{ \
-	return show_temp(dev, buf, offset); \
-} \
-static DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_regs_temp_##offset, NULL);
-
-#define sysfs_temp_reg_offset(reg, offset) \
-static ssize_t show_regs_temp_##reg##offset (struct device *dev, char *buf) \
-{ \
-	return show_temp_##reg (dev, buf, offset); \
-} \
-static ssize_t store_regs_temp_##reg##offset (struct device *dev, const char *buf, size_t count) \
-{ \
-	return store_temp_##reg (dev, buf, count, offset); \
-} \
-static DEVICE_ATTR(temp##offset##_##reg, S_IRUGO| S_IWUSR, show_regs_temp_##reg##offset, store_regs_temp_##reg##offset);
-
-#define sysfs_temp_offsets(offset) \
-sysfs_temp_offset(offset); \
-sysfs_temp_reg_offset(max, offset); \
-sysfs_temp_reg_offset(max_hyst, offset);
-
-sysfs_temp_offsets(1);
-sysfs_temp_offsets(2);
-sysfs_temp_offsets(3);
-
-#define device_create_file_temp(client, offset) \
-do { \
-device_create_file(&client->dev, &dev_attr_temp##offset##_input); \
-device_create_file(&client->dev, &dev_attr_temp##offset##_max); \
-device_create_file(&client->dev, &dev_attr_temp##offset##_max_hyst); \
-} while (0)
-
-static ssize_t
-show_vid_reg(struct device *dev, char *buf)
-{
-	struct w83781d_data *data = w83781d_update_device(dev);
-	return sprintf(buf, "%ld\n", (long) vid_from_reg(data->vid, data->vrm));
-}
-
-static
-DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid_reg, NULL);
-#define device_create_file_vid(client) \
-device_create_file(&client->dev, &dev_attr_cpu0_vid);
-static ssize_t
-show_vrm_reg(struct device *dev, char *buf)
-{
-	struct w83781d_data *data = w83781d_update_device(dev);
-	return sprintf(buf, "%ld\n", (long) data->vrm);
-}
-
-static ssize_t
-store_vrm_reg(struct device *dev, const char *buf, size_t count)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct w83781d_data *data = i2c_get_clientdata(client);
-	u32 val;
-
-	val = simple_strtoul(buf, NULL, 10);
-	data->vrm = val;
-
-	return count;
-}
-
-static
-DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg);
-#define device_create_file_vrm(client) \
-device_create_file(&client->dev, &dev_attr_vrm);
-static ssize_t
-show_alarms_reg(struct device *dev, char *buf)
-{
-	struct w83781d_data *data = w83781d_update_device(dev);
-	return sprintf(buf, "%ld\n", (long) ALARMS_FROM_REG(data->alarms));
-}
-
-static
-DEVICE_ATTR(alarms, S_IRUGO, show_alarms_reg, NULL);
-#define device_create_file_alarms(client) \
-device_create_file(&client->dev, &dev_attr_alarms);
-static ssize_t show_beep_mask (struct device *dev, char *buf)
-{
-	struct w83781d_data *data = w83781d_update_device(dev);
-	return sprintf(buf, "%ld\n",
-		       (long)BEEP_MASK_FROM_REG(data->beep_mask, data->type));
-}
-static ssize_t show_beep_enable (struct device *dev, char *buf)
-{
-	struct w83781d_data *data = w83781d_update_device(dev);
-	return sprintf(buf, "%ld\n",
-		       (long)BEEP_ENABLE_FROM_REG(data->beep_enable));
-}
-
-#define BEEP_ENABLE			0	/* Store beep_enable */
-#define BEEP_MASK			1	/* Store beep_mask */
-
-static ssize_t
-store_beep_reg(struct device *dev, const char *buf, size_t count,
-	       int update_mask)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct w83781d_data *data = i2c_get_clientdata(client);
-	u32 val, val2;
-
-	val = simple_strtoul(buf, NULL, 10);
-
-	down(&data->update_lock);
-
-	if (update_mask == BEEP_MASK) {	/* We are storing beep_mask */
-		data->beep_mask = BEEP_MASK_TO_REG(val, data->type);
-		w83781d_write_value(client, W83781D_REG_BEEP_INTS1,
-				    data->beep_mask & 0xff);
-
-		if ((data->type != w83781d) && (data->type != as99127f)) {
-			w83781d_write_value(client, W83781D_REG_BEEP_INTS3,
-					    ((data->beep_mask) >> 16) & 0xff);
-		}
-
-		val2 = (data->beep_mask >> 8) & 0x7f;
-	} else {		/* We are storing beep_enable */
-		val2 = w83781d_read_value(client, W83781D_REG_BEEP_INTS2) & 0x7f;
-		data->beep_enable = BEEP_ENABLE_TO_REG(val);
-	}
-
-	w83781d_write_value(client, W83781D_REG_BEEP_INTS2,
-			    val2 | data->beep_enable << 7);
-
-	up(&data->update_lock);
-	return count;
-}
-
-#define sysfs_beep(REG, reg) \
-static ssize_t show_regs_beep_##reg (struct device *dev, char *buf) \
-{ \
-	return show_beep_##reg(dev, buf); \
-} \
-static ssize_t store_regs_beep_##reg (struct device *dev, const char *buf, size_t count) \
-{ \
-	return store_beep_reg(dev, buf, count, BEEP_##REG); \
-} \
-static DEVICE_ATTR(beep_##reg, S_IRUGO | S_IWUSR, show_regs_beep_##reg, store_regs_beep_##reg);
-
-sysfs_beep(ENABLE, enable);
-sysfs_beep(MASK, mask);
-
-#define device_create_file_beep(client) \
-do { \
-device_create_file(&client->dev, &dev_attr_beep_enable); \
-device_create_file(&client->dev, &dev_attr_beep_mask); \
-} while (0)
-
-static ssize_t
-show_fan_div_reg(struct device *dev, char *buf, int nr)
-{
-	struct w83781d_data *data = w83781d_update_device(dev);
-	return sprintf(buf, "%ld\n",
-		       (long) DIV_FROM_REG(data->fan_div[nr - 1]));
-}
-
-/* Note: we save and restore the fan minimum here, because its value is
-   determined in part by the fan divisor.  This follows the principle of
-   least suprise; the user doesn't expect the fan minimum to change just
-   because the divisor changed. */
-static ssize_t
-store_fan_div_reg(struct device *dev, const char *buf, size_t count, int nr)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct w83781d_data *data = i2c_get_clientdata(client);
-	unsigned long min;
-	u8 reg;
-	unsigned long val = simple_strtoul(buf, NULL, 10);
-
-	down(&data->update_lock);
-	
-	/* Save fan_min */
-	min = FAN_FROM_REG(data->fan_min[nr],
-			   DIV_FROM_REG(data->fan_div[nr]));
-
-	data->fan_div[nr] = DIV_TO_REG(val, data->type);
-
-	reg = (w83781d_read_value(client, nr==2 ? W83781D_REG_PIN : W83781D_REG_VID_FANDIV)
-	       & (nr==0 ? 0xcf : 0x3f))
-	    | ((data->fan_div[nr] & 0x03) << (nr==0 ? 4 : 6));
-	w83781d_write_value(client, nr==2 ? W83781D_REG_PIN : W83781D_REG_VID_FANDIV, reg);
-
-	/* w83781d and as99127f don't have extended divisor bits */
-	if (data->type != w83781d && data->type != as99127f) {
-		reg = (w83781d_read_value(client, W83781D_REG_VBAT)
-		       & ~(1 << (5 + nr)))
-		    | ((data->fan_div[nr] & 0x04) << (3 + nr));
-		w83781d_write_value(client, W83781D_REG_VBAT, reg);
-	}
-
-	/* Restore fan_min */
-	data->fan_min[nr] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr]));
-	w83781d_write_value(client, W83781D_REG_FAN_MIN(nr+1), data->fan_min[nr]);
-
-	up(&data->update_lock);
-	return count;
-}
-
-#define sysfs_fan_div(offset) \
-static ssize_t show_regs_fan_div_##offset (struct device *dev, char *buf) \
-{ \
-	return show_fan_div_reg(dev, buf, offset); \
-} \
-static ssize_t store_regs_fan_div_##offset (struct device *dev, const char *buf, size_t count) \
-{ \
-	return store_fan_div_reg(dev, buf, count, offset - 1); \
-} \
-static DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, show_regs_fan_div_##offset, store_regs_fan_div_##offset);
-
-sysfs_fan_div(1);
-sysfs_fan_div(2);
-sysfs_fan_div(3);
-
-#define device_create_file_fan_div(client, offset) \
-do { \
-device_create_file(&client->dev, &dev_attr_fan##offset##_div); \
-} while (0)
-
-static ssize_t
-show_pwm_reg(struct device *dev, char *buf, int nr)
-{
-	struct w83781d_data *data = w83781d_update_device(dev);
-	return sprintf(buf, "%ld\n", (long) PWM_FROM_REG(data->pwm[nr - 1]));
-}
-
-static ssize_t
-show_pwmenable_reg(struct device *dev, char *buf, int nr)
-{
-	struct w83781d_data *data = w83781d_update_device(dev);
-	return sprintf(buf, "%ld\n", (long) data->pwmenable[nr - 1]);
-}
-
-static ssize_t
-store_pwm_reg(struct device *dev, const char *buf, size_t count, int nr)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct w83781d_data *data = i2c_get_clientdata(client);
-	u32 val;
-
-	val = simple_strtoul(buf, NULL, 10);
-
-	down(&data->update_lock);
-	data->pwm[nr - 1] = PWM_TO_REG(val);
-	w83781d_write_value(client, W83781D_REG_PWM(nr), data->pwm[nr - 1]);
-	up(&data->update_lock);
-	return count;
-}
-
-static ssize_t
-store_pwmenable_reg(struct device *dev, const char *buf, size_t count, int nr)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct w83781d_data *data = i2c_get_clientdata(client);
-	u32 val, reg;
-
-	val = simple_strtoul(buf, NULL, 10);
-
-	down(&data->update_lock);
-
-	switch (val) {
-	case 0:
-	case 1:
-		reg = w83781d_read_value(client, W83781D_REG_PWMCLK12);
-		w83781d_write_value(client, W83781D_REG_PWMCLK12,
-				    (reg & 0xf7) | (val << 3));
-
-		reg = w83781d_read_value(client, W83781D_REG_BEEP_CONFIG);
-		w83781d_write_value(client, W83781D_REG_BEEP_CONFIG,
-				    (reg & 0xef) | (!val << 4));
-
-		data->pwmenable[nr - 1] = val;
-		break;
-
-	default:
-		up(&data->update_lock);
-		return -EINVAL;
-	}
-
-	up(&data->update_lock);
-	return count;
-}
-
-#define sysfs_pwm(offset) \
-static ssize_t show_regs_pwm_##offset (struct device *dev, char *buf) \
-{ \
-	return show_pwm_reg(dev, buf, offset); \
-} \
-static ssize_t store_regs_pwm_##offset (struct device *dev, \
-		const char *buf, size_t count) \
-{ \
-	return store_pwm_reg(dev, buf, count, offset); \
-} \
-static DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR, \
-		show_regs_pwm_##offset, store_regs_pwm_##offset);
-
-#define sysfs_pwmenable(offset) \
-static ssize_t show_regs_pwmenable_##offset (struct device *dev, char *buf) \
-{ \
-	return show_pwmenable_reg(dev, buf, offset); \
-} \
-static ssize_t store_regs_pwmenable_##offset (struct device *dev, \
-		const char *buf, size_t count) \
-{ \
-	return store_pwmenable_reg(dev, buf, count, offset); \
-} \
-static DEVICE_ATTR(pwm##offset##_enable, S_IRUGO | S_IWUSR, \
-		show_regs_pwmenable_##offset, store_regs_pwmenable_##offset);
-
-sysfs_pwm(1);
-sysfs_pwm(2);
-sysfs_pwmenable(2);		/* only PWM2 can be enabled/disabled */
-sysfs_pwm(3);
-sysfs_pwm(4);
-
-#define device_create_file_pwm(client, offset) \
-do { \
-device_create_file(&client->dev, &dev_attr_pwm##offset); \
-} while (0)
-
-#define device_create_file_pwmenable(client, offset) \
-do { \
-device_create_file(&client->dev, &dev_attr_pwm##offset##_enable); \
-} while (0)
-
-static ssize_t
-show_sensor_reg(struct device *dev, char *buf, int nr)
-{
-	struct w83781d_data *data = w83781d_update_device(dev);
-	return sprintf(buf, "%ld\n", (long) data->sens[nr - 1]);
-}
-
-static ssize_t
-store_sensor_reg(struct device *dev, const char *buf, size_t count, int nr)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct w83781d_data *data = i2c_get_clientdata(client);
-	u32 val, tmp;
-
-	val = simple_strtoul(buf, NULL, 10);
-
-	down(&data->update_lock);
-
-	switch (val) {
-	case 1:		/* PII/Celeron diode */
-		tmp = w83781d_read_value(client, W83781D_REG_SCFG1);
-		w83781d_write_value(client, W83781D_REG_SCFG1,
-				    tmp | BIT_SCFG1[nr - 1]);
-		tmp = w83781d_read_value(client, W83781D_REG_SCFG2);
-		w83781d_write_value(client, W83781D_REG_SCFG2,
-				    tmp | BIT_SCFG2[nr - 1]);
-		data->sens[nr - 1] = val;
-		break;
-	case 2:		/* 3904 */
-		tmp = w83781d_read_value(client, W83781D_REG_SCFG1);
-		w83781d_write_value(client, W83781D_REG_SCFG1,
-				    tmp | BIT_SCFG1[nr - 1]);
-		tmp = w83781d_read_value(client, W83781D_REG_SCFG2);
-		w83781d_write_value(client, W83781D_REG_SCFG2,
-				    tmp & ~BIT_SCFG2[nr - 1]);
-		data->sens[nr - 1] = val;
-		break;
-	case W83781D_DEFAULT_BETA:	/* thermistor */
-		tmp = w83781d_read_value(client, W83781D_REG_SCFG1);
-		w83781d_write_value(client, W83781D_REG_SCFG1,
-				    tmp & ~BIT_SCFG1[nr - 1]);
-		data->sens[nr - 1] = val;
-		break;
-	default:
-		dev_err(dev, "Invalid sensor type %ld; must be 1, 2, or %d\n",
-		       (long) val, W83781D_DEFAULT_BETA);
-		break;
-	}
-
-	up(&data->update_lock);
-	return count;
-}
-
-#define sysfs_sensor(offset) \
-static ssize_t show_regs_sensor_##offset (struct device *dev, char *buf) \
-{ \
-    return show_sensor_reg(dev, buf, offset); \
-} \
-static ssize_t store_regs_sensor_##offset (struct device *dev, const char *buf, size_t count) \
-{ \
-    return store_sensor_reg(dev, buf, count, offset); \
-} \
-static DEVICE_ATTR(temp##offset##_type, S_IRUGO | S_IWUSR, show_regs_sensor_##offset, store_regs_sensor_##offset);
-
-sysfs_sensor(1);
-sysfs_sensor(2);
-sysfs_sensor(3);
-
-#define device_create_file_sensor(client, offset) \
-do { \
-device_create_file(&client->dev, &dev_attr_temp##offset##_type); \
-} while (0)
-
-/* This function is called when:
-     * w83781d_driver is inserted (when this module is loaded), for each
-       available adapter
-     * when a new adapter is inserted (and w83781d_driver is still present) */
-static int
-w83781d_attach_adapter(struct i2c_adapter *adapter)
-{
-	if (!(adapter->class & I2C_CLASS_HWMON))
-		return 0;
-	return i2c_detect(adapter, &addr_data, w83781d_detect);
-}
-
-/* Assumes that adapter is of I2C, not ISA variety.
- * OTHERWISE DON'T CALL THIS
- */
-static int
-w83781d_detect_subclients(struct i2c_adapter *adapter, int address, int kind,
-		struct i2c_client *new_client)
-{
-	int i, val1 = 0, id;
-	int err;
-	const char *client_name = "";
-	struct w83781d_data *data = i2c_get_clientdata(new_client);
-
-	data->lm75[0] = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
-	if (!(data->lm75[0])) {
-		err = -ENOMEM;
-		goto ERROR_SC_0;
-	}
-	memset(data->lm75[0], 0x00, sizeof (struct i2c_client));
-
-	id = i2c_adapter_id(adapter);
-
-	if (force_subclients[0] == id && force_subclients[1] == address) {
-		for (i = 2; i <= 3; i++) {
-			if (force_subclients[i] < 0x48 ||
-			    force_subclients[i] > 0x4f) {
-				dev_err(&new_client->dev, "Invalid subclient "
-					"address %d; must be 0x48-0x4f\n",
-					force_subclients[i]);
-				err = -EINVAL;
-				goto ERROR_SC_1;
-			}
-		}
-		w83781d_write_value(new_client, W83781D_REG_I2C_SUBADDR,
-				(force_subclients[2] & 0x07) |
-				((force_subclients[3] & 0x07) << 4));
-		data->lm75[0]->addr = force_subclients[2];
-	} else {
-		val1 = w83781d_read_value(new_client, W83781D_REG_I2C_SUBADDR);
-		data->lm75[0]->addr = 0x48 + (val1 & 0x07);
-	}
-
-	if (kind != w83783s) {
-
-		data->lm75[1] = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
-		if (!(data->lm75[1])) {
-			err = -ENOMEM;
-			goto ERROR_SC_1;
-		}
-		memset(data->lm75[1], 0x0, sizeof(struct i2c_client));
-
-		if (force_subclients[0] == id &&
-		    force_subclients[1] == address) {
-			data->lm75[1]->addr = force_subclients[3];
-		} else {
-			data->lm75[1]->addr = 0x48 + ((val1 >> 4) & 0x07);
-		}
-		if (data->lm75[0]->addr == data->lm75[1]->addr) {
-			dev_err(&new_client->dev,
-			       "Duplicate addresses 0x%x for subclients.\n",
-			       data->lm75[0]->addr);
-			err = -EBUSY;
-			goto ERROR_SC_2;
-		}
-	}
-
-	if (kind == w83781d)
-		client_name = "w83781d subclient";
-	else if (kind == w83782d)
-		client_name = "w83782d subclient";
-	else if (kind == w83783s)
-		client_name = "w83783s subclient";
-	else if (kind == w83627hf)
-		client_name = "w83627hf subclient";
-	else if (kind == as99127f)
-		client_name = "as99127f subclient";
-
-	for (i = 0; i <= 1; i++) {
-		/* store all data in w83781d */
-		i2c_set_clientdata(data->lm75[i], NULL);
-		data->lm75[i]->adapter = adapter;
-		data->lm75[i]->driver = &w83781d_driver;
-		data->lm75[i]->flags = 0;
-		strlcpy(data->lm75[i]->name, client_name,
-			I2C_NAME_SIZE);
-		if ((err = i2c_attach_client(data->lm75[i]))) {
-			dev_err(&new_client->dev, "Subclient %d "
-				"registration at address 0x%x "
-				"failed.\n", i, data->lm75[i]->addr);
-			if (i == 1)
-				goto ERROR_SC_3;
-			goto ERROR_SC_2;
-		}
-		if (kind == w83783s)
-			break;
-	}
-
-	return 0;
-
-/* Undo inits in case of errors */
-ERROR_SC_3:
-	i2c_detach_client(data->lm75[0]);
-ERROR_SC_2:
-	if (NULL != data->lm75[1])
-		kfree(data->lm75[1]);
-ERROR_SC_1:
-	if (NULL != data->lm75[0])
-		kfree(data->lm75[0]);
-ERROR_SC_0:
-	return err;
-}
-
-static int
-w83781d_detect(struct i2c_adapter *adapter, int address, int kind)
-{
-	int i = 0, val1 = 0, val2;
-	struct i2c_client *new_client;
-	struct w83781d_data *data;
-	int err;
-	const char *client_name = "";
-	int is_isa = i2c_is_isa_adapter(adapter);
-	enum vendor { winbond, asus } vendid;
-
-	if (!is_isa
-	    && !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
-		err = -EINVAL;
-		goto ERROR0;
-	}
-
-	/* Prevent users from forcing a kind for a bus it isn't supposed
-	   to possibly be on */
-	if (is_isa && (kind == as99127f || kind == w83783s)) {
-		dev_err(&adapter->dev,
-			"Cannot force I2C-only chip for ISA address 0x%02x.\n",
-			address);
-		err = -EINVAL;
-		goto ERROR0;
-	}
-	if (!is_isa && kind == w83697hf) {
-		dev_err(&adapter->dev,
-			"Cannot force ISA-only chip for I2C address 0x%02x.\n",
-			address);
-		err = -EINVAL;
-		goto ERROR0;
-	}
-	
-	if (is_isa)
-		if (!request_region(address, W83781D_EXTENT,
-				    w83781d_driver.name)) {
-			dev_dbg(&adapter->dev, "Request of region "
-				"0x%x-0x%x for w83781d failed\n", address,
-				address + W83781D_EXTENT - 1);
-			err = -EBUSY;
-			goto ERROR0;
-		}
-
-	/* Probe whether there is anything available on this address. Already
-	   done for SMBus clients */
-	if (kind < 0) {
-		if (is_isa) {
-
-#define REALLY_SLOW_IO
-			/* We need the timeouts for at least some LM78-like
-			   chips. But only if we read 'undefined' registers. */
-			i = inb_p(address + 1);
-			if (inb_p(address + 2) != i
-			 || inb_p(address + 3) != i
-			 || inb_p(address + 7) != i) {
-				dev_dbg(&adapter->dev, "Detection of w83781d "
-					"chip failed at step 1\n");
-				err = -ENODEV;
-				goto ERROR1;
-			}
-#undef REALLY_SLOW_IO
-
-			/* Let's just hope nothing breaks here */
-			i = inb_p(address + 5) & 0x7f;
-			outb_p(~i & 0x7f, address + 5);
-			val2 = inb_p(address + 5) & 0x7f;
-			if (val2 != (~i & 0x7f)) {
-				outb_p(i, address + 5);
-				dev_dbg(&adapter->dev, "Detection of w83781d "
-					"chip failed at step 2 (0x%x != "
-					"0x%x at 0x%x)\n", val2, ~i & 0x7f,
-					address + 5);
-				err = -ENODEV;
-				goto ERROR1;
-			}
-		}
-	}
-
-	/* OK. For now, we presume we have a valid client. We now create the
-	   client structure, even though we cannot fill it completely yet.
-	   But it allows us to access w83781d_{read,write}_value. */
-
-	if (!(data = kmalloc(sizeof(struct w83781d_data), GFP_KERNEL))) {
-		err = -ENOMEM;
-		goto ERROR1;
-	}
-	memset(data, 0, sizeof(struct w83781d_data));
-
-	new_client = &data->client;
-	i2c_set_clientdata(new_client, data);
-	new_client->addr = address;
-	init_MUTEX(&data->lock);
-	new_client->adapter = adapter;
-	new_client->driver = &w83781d_driver;
-	new_client->flags = 0;
-
-	/* Now, we do the remaining detection. */
-
-	/* The w8378?d may be stuck in some other bank than bank 0. This may
-	   make reading other information impossible. Specify a force=... or
-	   force_*=... parameter, and the Winbond will be reset to the right
-	   bank. */
-	if (kind < 0) {
-		if (w83781d_read_value(new_client, W83781D_REG_CONFIG) & 0x80) {
-			dev_dbg(&new_client->dev, "Detection failed at step "
-				"3\n");
-			err = -ENODEV;
-			goto ERROR2;
-		}
-		val1 = w83781d_read_value(new_client, W83781D_REG_BANK);
-		val2 = w83781d_read_value(new_client, W83781D_REG_CHIPMAN);
-		/* Check for Winbond or Asus ID if in bank 0 */
-		if ((!(val1 & 0x07)) &&
-		    (((!(val1 & 0x80)) && (val2 != 0xa3) && (val2 != 0xc3))
-		     || ((val1 & 0x80) && (val2 != 0x5c) && (val2 != 0x12)))) {
-			dev_dbg(&new_client->dev, "Detection failed at step "
-				"4\n");
-			err = -ENODEV;
-			goto ERROR2;
-		}
-		/* If Winbond SMBus, check address at 0x48.
-		   Asus doesn't support, except for as99127f rev.2 */
-		if ((!is_isa) && (((!(val1 & 0x80)) && (val2 == 0xa3)) ||
-				  ((val1 & 0x80) && (val2 == 0x5c)))) {
-			if (w83781d_read_value
-			    (new_client, W83781D_REG_I2C_ADDR) != address) {
-				dev_dbg(&new_client->dev, "Detection failed "
-					"at step 5\n");
-				err = -ENODEV;
-				goto ERROR2;
-			}
-		}
-	}
-
-	/* We have either had a force parameter, or we have already detected the
-	   Winbond. Put it now into bank 0 and Vendor ID High Byte */
-	w83781d_write_value(new_client, W83781D_REG_BANK,
-			    (w83781d_read_value(new_client,
-						W83781D_REG_BANK) & 0x78) |
-			    0x80);
-
-	/* Determine the chip type. */
-	if (kind <= 0) {
-		/* get vendor ID */
-		val2 = w83781d_read_value(new_client, W83781D_REG_CHIPMAN);
-		if (val2 == 0x5c)
-			vendid = winbond;
-		else if (val2 == 0x12)
-			vendid = asus;
-		else {
-			dev_dbg(&new_client->dev, "Chip was made by neither "
-				"Winbond nor Asus?\n");
-			err = -ENODEV;
-			goto ERROR2;
-		}
-
-		val1 = w83781d_read_value(new_client, W83781D_REG_WCHIPID);
-		if ((val1 == 0x10 || val1 == 0x11) && vendid == winbond)
-			kind = w83781d;
-		else if (val1 == 0x30 && vendid == winbond)
-			kind = w83782d;
-		else if (val1 == 0x40 && vendid == winbond && !is_isa
-				&& address == 0x2d)
-			kind = w83783s;
-		else if ((val1 == 0x21 || val1 == 0x90) && vendid == winbond)
-			kind = w83627hf;
-		else if (val1 == 0x31 && !is_isa && address >= 0x28)
-			kind = as99127f;
-		else if (val1 == 0x60 && vendid == winbond && is_isa)
-			kind = w83697hf;
-		else {
-			if (kind == 0)
-				dev_warn(&new_client->dev, "Ignoring 'force' "
-					 "parameter for unknown chip at "
-					 "adapter %d, address 0x%02x\n",
-					 i2c_adapter_id(adapter), address);
-			err = -EINVAL;
-			goto ERROR2;
-		}
-	}
-
-	if (kind == w83781d) {
-		client_name = "w83781d";
-	} else if (kind == w83782d) {
-		client_name = "w83782d";
-	} else if (kind == w83783s) {
-		client_name = "w83783s";
-	} else if (kind == w83627hf) {
-		if (val1 == 0x90)
-			client_name = "w83627thf";
-		else
-			client_name = "w83627hf";
-	} else if (kind == as99127f) {
-		client_name = "as99127f";
-	} else if (kind == w83697hf) {
-		client_name = "w83697hf";
-	}
-
-	/* Fill in the remaining client fields and put into the global list */
-	strlcpy(new_client->name, client_name, I2C_NAME_SIZE);
-	data->type = kind;
-
-	data->valid = 0;
-	init_MUTEX(&data->update_lock);
-
-	/* Tell the I2C layer a new client has arrived */
-	if ((err = i2c_attach_client(new_client)))
-		goto ERROR2;
-
-	/* attach secondary i2c lm75-like clients */
-	if (!is_isa) {
-		if ((err = w83781d_detect_subclients(adapter, address,
-				kind, new_client)))
-			goto ERROR3;
-	} else {
-		data->lm75[0] = NULL;
-		data->lm75[1] = NULL;
-	}
-
-	/* Initialize the chip */
-	w83781d_init_client(new_client);
-
-	/* A few vars need to be filled upon startup */
-	for (i = 1; i <= 3; i++) {
-		data->fan_min[i - 1] = w83781d_read_value(new_client,
-					W83781D_REG_FAN_MIN(i));
-	}
-	if (kind != w83781d && kind != as99127f)
-		for (i = 0; i < 4; i++)
-			data->pwmenable[i] = 1;
-
-	/* Register sysfs hooks */
-	device_create_file_in(new_client, 0);
-	if (kind != w83783s && kind != w83697hf)
-		device_create_file_in(new_client, 1);
-	device_create_file_in(new_client, 2);
-	device_create_file_in(new_client, 3);
-	device_create_file_in(new_client, 4);
-	device_create_file_in(new_client, 5);
-	device_create_file_in(new_client, 6);
-	if (kind != as99127f && kind != w83781d && kind != w83783s) {
-		device_create_file_in(new_client, 7);
-		device_create_file_in(new_client, 8);
-	}
-
-	device_create_file_fan(new_client, 1);
-	device_create_file_fan(new_client, 2);
-	if (kind != w83697hf)
-		device_create_file_fan(new_client, 3);
-
-	device_create_file_temp(new_client, 1);
-	device_create_file_temp(new_client, 2);
-	if (kind != w83783s && kind != w83697hf)
-		device_create_file_temp(new_client, 3);
-
-	if (kind != w83697hf)
-		device_create_file_vid(new_client);
-
-	if (kind != w83697hf)
-		device_create_file_vrm(new_client);
-
-	device_create_file_fan_div(new_client, 1);
-	device_create_file_fan_div(new_client, 2);
-	if (kind != w83697hf)
-		device_create_file_fan_div(new_client, 3);
-
-	device_create_file_alarms(new_client);
-
-	device_create_file_beep(new_client);
-
-	if (kind != w83781d && kind != as99127f) {
-		device_create_file_pwm(new_client, 1);
-		device_create_file_pwm(new_client, 2);
-		device_create_file_pwmenable(new_client, 2);
-	}
-	if (kind == w83782d && !is_isa) {
-		device_create_file_pwm(new_client, 3);
-		device_create_file_pwm(new_client, 4);
-	}
-
-	if (kind != as99127f && kind != w83781d) {
-		device_create_file_sensor(new_client, 1);
-		device_create_file_sensor(new_client, 2);
-		if (kind != w83783s && kind != w83697hf)
-			device_create_file_sensor(new_client, 3);
-	}
-
-	return 0;
-
-ERROR3:
-	i2c_detach_client(new_client);
-ERROR2:
-	kfree(data);
-ERROR1:
-	if (is_isa)
-		release_region(address, W83781D_EXTENT);
-ERROR0:
-	return err;
-}
-
-static int
-w83781d_detach_client(struct i2c_client *client)
-{
-	int err;
-
-	if (i2c_is_isa_client(client))
-		release_region(client->addr, W83781D_EXTENT);
-
-	if ((err = i2c_detach_client(client))) {
-		dev_err(&client->dev,
-		       "Client deregistration failed, client not detached.\n");
-		return err;
-	}
-
-	if (i2c_get_clientdata(client)==NULL) {
-		/* subclients */
-		kfree(client);
-	} else {
-		/* main client */
-		kfree(i2c_get_clientdata(client));
-	}
-
-	return 0;
-}
-
-/* The SMBus locks itself, usually, but nothing may access the Winbond between
-   bank switches. ISA access must always be locked explicitly! 
-   We ignore the W83781D BUSY flag at this moment - it could lead to deadlocks,
-   would slow down the W83781D access and should not be necessary. 
-   There are some ugly typecasts here, but the good news is - they should
-   nowhere else be necessary! */
-static int
-w83781d_read_value(struct i2c_client *client, u16 reg)
-{
-	struct w83781d_data *data = i2c_get_clientdata(client);
-	int res, word_sized, bank;
-	struct i2c_client *cl;
-
-	down(&data->lock);
-	if (i2c_is_isa_client(client)) {
-		word_sized = (((reg & 0xff00) == 0x100)
-			      || ((reg & 0xff00) == 0x200))
-		    && (((reg & 0x00ff) == 0x50)
-			|| ((reg & 0x00ff) == 0x53)
-			|| ((reg & 0x00ff) == 0x55));
-		if (reg & 0xff00) {
-			outb_p(W83781D_REG_BANK,
-			       client->addr + W83781D_ADDR_REG_OFFSET);
-			outb_p(reg >> 8,
-			       client->addr + W83781D_DATA_REG_OFFSET);
-		}
-		outb_p(reg & 0xff, client->addr + W83781D_ADDR_REG_OFFSET);
-		res = inb_p(client->addr + W83781D_DATA_REG_OFFSET);
-		if (word_sized) {
-			outb_p((reg & 0xff) + 1,
-			       client->addr + W83781D_ADDR_REG_OFFSET);
-			res =
-			    (res << 8) + inb_p(client->addr +
-					       W83781D_DATA_REG_OFFSET);
-		}
-		if (reg & 0xff00) {
-			outb_p(W83781D_REG_BANK,
-			       client->addr + W83781D_ADDR_REG_OFFSET);
-			outb_p(0, client->addr + W83781D_DATA_REG_OFFSET);
-		}
-	} else {
-		bank = (reg >> 8) & 0x0f;
-		if (bank > 2)
-			/* switch banks */
-			i2c_smbus_write_byte_data(client, W83781D_REG_BANK,
-						  bank);
-		if (bank == 0 || bank > 2) {
-			res = i2c_smbus_read_byte_data(client, reg & 0xff);
-		} else {
-			/* switch to subclient */
-			cl = data->lm75[bank - 1];
-			/* convert from ISA to LM75 I2C addresses */
-			switch (reg & 0xff) {
-			case 0x50:	/* TEMP */
-				res = swab16(i2c_smbus_read_word_data(cl, 0));
-				break;
-			case 0x52:	/* CONFIG */
-				res = i2c_smbus_read_byte_data(cl, 1);
-				break;
-			case 0x53:	/* HYST */
-				res = swab16(i2c_smbus_read_word_data(cl, 2));
-				break;
-			case 0x55:	/* OVER */
-			default:
-				res = swab16(i2c_smbus_read_word_data(cl, 3));
-				break;
-			}
-		}
-		if (bank > 2)
-			i2c_smbus_write_byte_data(client, W83781D_REG_BANK, 0);
-	}
-	up(&data->lock);
-	return res;
-}
-
-static int
-w83781d_write_value(struct i2c_client *client, u16 reg, u16 value)
-{
-	struct w83781d_data *data = i2c_get_clientdata(client);
-	int word_sized, bank;
-	struct i2c_client *cl;
-
-	down(&data->lock);
-	if (i2c_is_isa_client(client)) {
-		word_sized = (((reg & 0xff00) == 0x100)
-			      || ((reg & 0xff00) == 0x200))
-		    && (((reg & 0x00ff) == 0x53)
-			|| ((reg & 0x00ff) == 0x55));
-		if (reg & 0xff00) {
-			outb_p(W83781D_REG_BANK,
-			       client->addr + W83781D_ADDR_REG_OFFSET);
-			outb_p(reg >> 8,
-			       client->addr + W83781D_DATA_REG_OFFSET);
-		}
-		outb_p(reg & 0xff, client->addr + W83781D_ADDR_REG_OFFSET);
-		if (word_sized) {
-			outb_p(value >> 8,
-			       client->addr + W83781D_DATA_REG_OFFSET);
-			outb_p((reg & 0xff) + 1,
-			       client->addr + W83781D_ADDR_REG_OFFSET);
-		}
-		outb_p(value & 0xff, client->addr + W83781D_DATA_REG_OFFSET);
-		if (reg & 0xff00) {
-			outb_p(W83781D_REG_BANK,
-			       client->addr + W83781D_ADDR_REG_OFFSET);
-			outb_p(0, client->addr + W83781D_DATA_REG_OFFSET);
-		}
-	} else {
-		bank = (reg >> 8) & 0x0f;
-		if (bank > 2)
-			/* switch banks */
-			i2c_smbus_write_byte_data(client, W83781D_REG_BANK,
-						  bank);
-		if (bank == 0 || bank > 2) {
-			i2c_smbus_write_byte_data(client, reg & 0xff,
-						  value & 0xff);
-		} else {
-			/* switch to subclient */
-			cl = data->lm75[bank - 1];
-			/* convert from ISA to LM75 I2C addresses */
-			switch (reg & 0xff) {
-			case 0x52:	/* CONFIG */
-				i2c_smbus_write_byte_data(cl, 1, value & 0xff);
-				break;
-			case 0x53:	/* HYST */
-				i2c_smbus_write_word_data(cl, 2, swab16(value));
-				break;
-			case 0x55:	/* OVER */
-				i2c_smbus_write_word_data(cl, 3, swab16(value));
-				break;
-			}
-		}
-		if (bank > 2)
-			i2c_smbus_write_byte_data(client, W83781D_REG_BANK, 0);
-	}
-	up(&data->lock);
-	return 0;
-}
-
-/* Called when we have found a new W83781D. It should set limits, etc. */
-static void
-w83781d_init_client(struct i2c_client *client)
-{
-	struct w83781d_data *data = i2c_get_clientdata(client);
-	int i, p;
-	int type = data->type;
-	u8 tmp;
-
-	if (init && type != as99127f) {	/* this resets registers we don't have
-					   documentation for on the as99127f */
-		/* save these registers */
-		i = w83781d_read_value(client, W83781D_REG_BEEP_CONFIG);
-		p = w83781d_read_value(client, W83781D_REG_PWMCLK12);
-		/* Reset all except Watchdog values and last conversion values
-		   This sets fan-divs to 2, among others */
-		w83781d_write_value(client, W83781D_REG_CONFIG, 0x80);
-		/* Restore the registers and disable power-on abnormal beep.
-		   This saves FAN 1/2/3 input/output values set by BIOS. */
-		w83781d_write_value(client, W83781D_REG_BEEP_CONFIG, i | 0x80);
-		w83781d_write_value(client, W83781D_REG_PWMCLK12, p);
-		/* Disable master beep-enable (reset turns it on).
-		   Individual beep_mask should be reset to off but for some reason
-		   disabling this bit helps some people not get beeped */
-		w83781d_write_value(client, W83781D_REG_BEEP_INTS2, 0);
-	}
-
-	data->vrm = i2c_which_vrm();
-
-	if ((type != w83781d) && (type != as99127f)) {
-		tmp = w83781d_read_value(client, W83781D_REG_SCFG1);
-		for (i = 1; i <= 3; i++) {
-			if (!(tmp & BIT_SCFG1[i - 1])) {
-				data->sens[i - 1] = W83781D_DEFAULT_BETA;
-			} else {
-				if (w83781d_read_value
-				    (client,
-				     W83781D_REG_SCFG2) & BIT_SCFG2[i - 1])
-					data->sens[i - 1] = 1;
-				else
-					data->sens[i - 1] = 2;
-			}
-			if ((type == w83783s || type == w83697hf) && (i == 2))
-				break;
-		}
-	}
-
-	if (init && type != as99127f) {
-		/* Enable temp2 */
-		tmp = w83781d_read_value(client, W83781D_REG_TEMP2_CONFIG);
-		if (tmp & 0x01) {
-			dev_warn(&client->dev, "Enabling temp2, readings "
-				 "might not make sense\n");
-			w83781d_write_value(client, W83781D_REG_TEMP2_CONFIG,
-				tmp & 0xfe);
-		}
-
-		/* Enable temp3 */
-		if (type != w83783s && type != w83697hf) {
-			tmp = w83781d_read_value(client,
-				W83781D_REG_TEMP3_CONFIG);
-			if (tmp & 0x01) {
-				dev_warn(&client->dev, "Enabling temp3, "
-					 "readings might not make sense\n");
-				w83781d_write_value(client,
-					W83781D_REG_TEMP3_CONFIG, tmp & 0xfe);
-			}
-		}
-
-		if (type != w83781d) {
-			/* enable comparator mode for temp2 and temp3 so
-			   alarm indication will work correctly */
-			i = w83781d_read_value(client, W83781D_REG_IRQ);
-			if (!(i & 0x40))
-				w83781d_write_value(client, W83781D_REG_IRQ,
-						    i | 0x40);
-		}
-	}
-
-	/* Start monitoring */
-	w83781d_write_value(client, W83781D_REG_CONFIG,
-			    (w83781d_read_value(client,
-						W83781D_REG_CONFIG) & 0xf7)
-			    | 0x01);
-}
-
-static struct w83781d_data *w83781d_update_device(struct device *dev)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct w83781d_data *data = i2c_get_clientdata(client);
-	int i;
-
-	down(&data->update_lock);
-
-	if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
-	    || !data->valid) {
-		dev_dbg(dev, "Starting device update\n");
-
-		for (i = 0; i <= 8; i++) {
-			if ((data->type == w83783s || data->type == w83697hf)
-			    && (i == 1))
-				continue;	/* 783S has no in1 */
-			data->in[i] =
-			    w83781d_read_value(client, W83781D_REG_IN(i));
-			data->in_min[i] =
-			    w83781d_read_value(client, W83781D_REG_IN_MIN(i));
-			data->in_max[i] =
-			    w83781d_read_value(client, W83781D_REG_IN_MAX(i));
-			if ((data->type != w83782d) && (data->type != w83697hf)
-			    && (data->type != w83627hf) && (i == 6))
-				break;
-		}
-		for (i = 1; i <= 3; i++) {
-			data->fan[i - 1] =
-			    w83781d_read_value(client, W83781D_REG_FAN(i));
-			data->fan_min[i - 1] =
-			    w83781d_read_value(client, W83781D_REG_FAN_MIN(i));
-		}
-		if (data->type != w83781d && data->type != as99127f) {
-			for (i = 1; i <= 4; i++) {
-				data->pwm[i - 1] =
-				    w83781d_read_value(client,
-						       W83781D_REG_PWM(i));
-				if ((data->type != w83782d
-				     || i2c_is_isa_client(client))
-				    && i == 2)
-					break;
-			}
-			/* Only PWM2 can be disabled */
-			data->pwmenable[1] = (w83781d_read_value(client,
-					      W83781D_REG_PWMCLK12) & 0x08) >> 3;
-		}
-
-		data->temp = w83781d_read_value(client, W83781D_REG_TEMP(1));
-		data->temp_max =
-		    w83781d_read_value(client, W83781D_REG_TEMP_OVER(1));
-		data->temp_max_hyst =
-		    w83781d_read_value(client, W83781D_REG_TEMP_HYST(1));
-		data->temp_add[0] =
-		    w83781d_read_value(client, W83781D_REG_TEMP(2));
-		data->temp_max_add[0] =
-		    w83781d_read_value(client, W83781D_REG_TEMP_OVER(2));
-		data->temp_max_hyst_add[0] =
-		    w83781d_read_value(client, W83781D_REG_TEMP_HYST(2));
-		if (data->type != w83783s && data->type != w83697hf) {
-			data->temp_add[1] =
-			    w83781d_read_value(client, W83781D_REG_TEMP(3));
-			data->temp_max_add[1] =
-			    w83781d_read_value(client,
-					       W83781D_REG_TEMP_OVER(3));
-			data->temp_max_hyst_add[1] =
-			    w83781d_read_value(client,
-					       W83781D_REG_TEMP_HYST(3));
-		}
-		i = w83781d_read_value(client, W83781D_REG_VID_FANDIV);
-		if (data->type != w83697hf) {
-			data->vid = i & 0x0f;
-			data->vid |=
-			    (w83781d_read_value(client, W83781D_REG_CHIPID) &
-			     0x01)
-			    << 4;
-		}
-		data->fan_div[0] = (i >> 4) & 0x03;
-		data->fan_div[1] = (i >> 6) & 0x03;
-		if (data->type != w83697hf) {
-			data->fan_div[2] = (w83781d_read_value(client,
-							       W83781D_REG_PIN)
-					    >> 6) & 0x03;
-		}
-		if ((data->type != w83781d) && (data->type != as99127f)) {
-			i = w83781d_read_value(client, W83781D_REG_VBAT);
-			data->fan_div[0] |= (i >> 3) & 0x04;
-			data->fan_div[1] |= (i >> 4) & 0x04;
-			if (data->type != w83697hf)
-				data->fan_div[2] |= (i >> 5) & 0x04;
-		}
-		data->alarms =
-		    w83781d_read_value(client,
-				       W83781D_REG_ALARM1) +
-		    (w83781d_read_value(client, W83781D_REG_ALARM2) << 8);
-		if ((data->type == w83782d) || (data->type == w83627hf)) {
-			data->alarms |=
-			    w83781d_read_value(client,
-					       W83781D_REG_ALARM3) << 16;
-		}
-		i = w83781d_read_value(client, W83781D_REG_BEEP_INTS2);
-		data->beep_enable = i >> 7;
-		data->beep_mask = ((i & 0x7f) << 8) +
-		    w83781d_read_value(client, W83781D_REG_BEEP_INTS1);
-		if ((data->type != w83781d) && (data->type != as99127f)) {
-			data->beep_mask |=
-			    w83781d_read_value(client,
-					       W83781D_REG_BEEP_INTS3) << 16;
-		}
-		data->last_updated = jiffies;
-		data->valid = 1;
-	}
-
-	up(&data->update_lock);
-
-	return data;
-}
-
-static int __init
-sensors_w83781d_init(void)
-{
-	return i2c_add_driver(&w83781d_driver);
-}
-
-static void __exit
-sensors_w83781d_exit(void)
-{
-	i2c_del_driver(&w83781d_driver);
-}
-
-MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>, "
-	      "Philip Edelbrock <phil@netroedge.com>, "
-	      "and Mark Studebaker <mdsxyz123@yahoo.com>");
-MODULE_DESCRIPTION("W83781D driver");
-MODULE_LICENSE("GPL");
-
-module_init(sensors_w83781d_init);
-module_exit(sensors_w83781d_exit);
diff --git a/drivers/i2c/chips/w83l785ts.c b/drivers/i2c/chips/w83l785ts.c
deleted file mode 100644
--- a/drivers/i2c/chips/w83l785ts.c
+++ /dev/null
@@ -1,329 +0,0 @@
-/*
- * w83l785ts.c - Part of lm_sensors, Linux kernel modules for hardware
- *               monitoring
- * Copyright (C) 2003-2004  Jean Delvare <khali@linux-fr.org>
- *
- * Inspired from the lm83 driver. The W83L785TS-S is a sensor chip made
- * by Winbond. It reports a single external temperature with a 1 deg
- * resolution and a 3 deg accuracy. Datasheet can be obtained from
- * Winbond's website at:
- *   http://www.winbond-usa.com/products/winbond_products/pdfs/PCIC/W83L785TS-S.pdf
- *
- * Ported to Linux 2.6 by Wolfgang Ziegler <nuppla@gmx.at> and Jean Delvare
- * <khali@linux-fr.org>.
- *
- * Thanks to James Bolt <james@evilpenguin.com> for benchmarking the read
- * error handling mechanism.
- *
- * 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 <linux/config.h>
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/jiffies.h>
-#include <linux/i2c.h>
-#include <linux/i2c-sensor.h>
-
-/* How many retries on register read error */
-#define MAX_RETRIES	5
-
-/*
- * Address to scan
- * Address is fully defined internally and cannot be changed.
- */
-
-static unsigned short normal_i2c[] = { 0x2e, I2C_CLIENT_END };
-static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
-
-/*
- * Insmod parameters
- */
-
-SENSORS_INSMOD_1(w83l785ts);
-
-/*
- * The W83L785TS-S registers
- * Manufacturer ID is 0x5CA3 for Winbond.
- */
-
-#define W83L785TS_REG_MAN_ID1		0x4D
-#define W83L785TS_REG_MAN_ID2		0x4C
-#define W83L785TS_REG_CHIP_ID		0x4E
-#define W83L785TS_REG_CONFIG		0x40
-#define W83L785TS_REG_TYPE		0x52
-#define W83L785TS_REG_TEMP		0x27
-#define W83L785TS_REG_TEMP_OVER		0x53 /* not sure about this one */
-
-/*
- * Conversions
- * The W83L785TS-S uses signed 8-bit values.
- */
-
-#define TEMP_FROM_REG(val)	((val & 0x80 ? val-0x100 : val) * 1000)
-
-/*
- * Functions declaration
- */
-
-static int w83l785ts_attach_adapter(struct i2c_adapter *adapter);
-static int w83l785ts_detect(struct i2c_adapter *adapter, int address,
-	int kind);
-static int w83l785ts_detach_client(struct i2c_client *client);
-static u8 w83l785ts_read_value(struct i2c_client *client, u8 reg, u8 defval);
-static struct w83l785ts_data *w83l785ts_update_device(struct device *dev);
-
-/*
- * Driver data (common to all clients)
- */
- 
-static struct i2c_driver w83l785ts_driver = {
-	.owner		= THIS_MODULE,
-	.name		= "w83l785ts",
-	.id		= I2C_DRIVERID_W83L785TS,
-	.flags		= I2C_DF_NOTIFY,
-	.attach_adapter	= w83l785ts_attach_adapter,
-	.detach_client	= w83l785ts_detach_client,
-};
-
-/*
- * Client data (each client gets its own)
- */
-
-struct w83l785ts_data {
-	struct i2c_client client;
-	struct semaphore update_lock;
-	char valid; /* zero until following fields are valid */
-	unsigned long last_updated; /* in jiffies */
-
-	/* registers values */
-	u8 temp, temp_over;
-};
-
-/*
- * Sysfs stuff
- */
-
-static ssize_t show_temp(struct device *dev, char *buf)
-{
-	struct w83l785ts_data *data = w83l785ts_update_device(dev);
-	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp));
-}
-
-static ssize_t show_temp_over(struct device *dev, char *buf)
-{
-	struct w83l785ts_data *data = w83l785ts_update_device(dev);
-	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_over));
-}
-
-static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL);
-static DEVICE_ATTR(temp1_max, S_IRUGO, show_temp_over, NULL);
-
-/*
- * Real code
- */
-
-static int w83l785ts_attach_adapter(struct i2c_adapter *adapter)
-{
-	if (!(adapter->class & I2C_CLASS_HWMON))
-		return 0;
-	return i2c_detect(adapter, &addr_data, w83l785ts_detect);
-}
-
-/*
- * The following function does more than just detection. If detection
- * succeeds, it also registers the new chip.
- */
-static int w83l785ts_detect(struct i2c_adapter *adapter, int address, int kind)
-{
-	struct i2c_client *new_client;
-	struct w83l785ts_data *data;
-	int err = 0;
-
-
-	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
-		goto exit;
-
-	if (!(data = kmalloc(sizeof(struct w83l785ts_data), GFP_KERNEL))) {
-		err = -ENOMEM;
-		goto exit;
-	}
-	memset(data, 0, sizeof(struct w83l785ts_data));
-
-
-	/* The common I2C client data is placed right before the
-	 * W83L785TS-specific data. */
-	new_client = &data->client;
-	i2c_set_clientdata(new_client, data);
-	new_client->addr = address;
-	new_client->adapter = adapter;
-	new_client->driver = &w83l785ts_driver;
-	new_client->flags = 0;
-
-	/*
-	 * Now we do the remaining detection. A negative kind means that
-	 * the driver was loaded with no force parameter (default), so we
-	 * must both detect and identify the chip (actually there is only
-	 * one possible kind of chip for now, W83L785TS-S). A zero kind means
-	 * that the driver was loaded with the force parameter, the detection
-	 * step shall be skipped. A positive kind means that the driver
-	 * was loaded with the force parameter and a given kind of chip is
-	 * requested, so both the detection and the identification steps
-	 * are skipped.
-	 */
-	if (kind < 0) { /* detection */
-		if (((w83l785ts_read_value(new_client,
-		      W83L785TS_REG_CONFIG, 0) & 0x80) != 0x00)
-		 || ((w83l785ts_read_value(new_client,
-		      W83L785TS_REG_TYPE, 0) & 0xFC) != 0x00)) {
-			dev_dbg(&adapter->dev,
-				"W83L785TS-S detection failed at 0x%02x.\n",
-				address);
-			goto exit_free;
-		}
-	}
-
-	if (kind <= 0) { /* identification */
-		u16 man_id;
-		u8 chip_id;
-
-		man_id = (w83l785ts_read_value(new_client,
-			 W83L785TS_REG_MAN_ID1, 0) << 8) +
-			 w83l785ts_read_value(new_client,
-			 W83L785TS_REG_MAN_ID2, 0);
-		chip_id = w83l785ts_read_value(new_client,
-			  W83L785TS_REG_CHIP_ID, 0);
-
-		if (man_id == 0x5CA3) { /* Winbond */
-			if (chip_id == 0x70) { /* W83L785TS-S */
-				kind = w83l785ts;			
-			}
-		}
-	
-		if (kind <= 0) { /* identification failed */
-			dev_info(&adapter->dev,
-				 "Unsupported chip (man_id=0x%04X, "
-				 "chip_id=0x%02X).\n", man_id, chip_id);
-			goto exit_free;
-		}
-	}
-
-	/* We can fill in the remaining client fields. */
-	strlcpy(new_client->name, "w83l785ts", I2C_NAME_SIZE);
-	data->valid = 0;
-	init_MUTEX(&data->update_lock);
-
-	/* Default values in case the first read fails (unlikely). */
-	data->temp_over = data->temp = 0;
-
-	/* Tell the I2C layer a new client has arrived. */
-	if ((err = i2c_attach_client(new_client))) 
-		goto exit_free;
-
-	/*
-	 * Initialize the W83L785TS chip
-	 * Nothing yet, assume it is already started.
-	 */
-
-	/* Register sysfs hooks */
-	device_create_file(&new_client->dev, &dev_attr_temp1_input);
-	device_create_file(&new_client->dev, &dev_attr_temp1_max);
-
-	return 0;
-
-exit_free:
-	kfree(data);
-exit:
-	return err;
-}
-
-static int w83l785ts_detach_client(struct i2c_client *client)
-{
-	int err;
-
-	if ((err = i2c_detach_client(client))) {
-		dev_err(&client->dev, "Client deregistration failed, "
-			"client not detached.\n");
-		return err;
-	}
-
-	kfree(i2c_get_clientdata(client));
-	return 0;
-}
-
-static u8 w83l785ts_read_value(struct i2c_client *client, u8 reg, u8 defval)
-{
-	int value, i;
-
-	/* Frequent read errors have been reported on Asus boards, so we
-	 * retry on read errors. If it still fails (unlikely), return the
-	 * default value requested by the caller. */
-	for (i = 1; i <= MAX_RETRIES; i++) {
-		value = i2c_smbus_read_byte_data(client, reg);
-		if (value >= 0) {
-			dev_dbg(&client->dev, "Read 0x%02x from register "
-				"0x%02x.\n", value, reg);
-			return value;
-		}
-		dev_dbg(&client->dev, "Read failed, will retry in %d.\n", i);
-		msleep(i);
-	}
-
-	dev_err(&client->dev, "Couldn't read value from register 0x%02x. "
-		"Please report.\n", reg);
-	return defval;
-}
-
-static struct w83l785ts_data *w83l785ts_update_device(struct device *dev)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct w83l785ts_data *data = i2c_get_clientdata(client);
-
-	down(&data->update_lock);
-
-	if (!data->valid || time_after(jiffies, data->last_updated + HZ * 2)) {
-		dev_dbg(&client->dev, "Updating w83l785ts data.\n");
-		data->temp = w83l785ts_read_value(client,
-			     W83L785TS_REG_TEMP, data->temp);
-		data->temp_over = w83l785ts_read_value(client,
-				  W83L785TS_REG_TEMP_OVER, data->temp_over);
-
-		data->last_updated = jiffies;
-		data->valid = 1;
-	}
-
-	up(&data->update_lock);
-
-	return data;
-}
-
-static int __init sensors_w83l785ts_init(void)
-{
-	return i2c_add_driver(&w83l785ts_driver);
-}
-
-static void __exit sensors_w83l785ts_exit(void)
-{
-	i2c_del_driver(&w83l785ts_driver);
-}
-
-MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>");
-MODULE_DESCRIPTION("W83L785TS-S driver");
-MODULE_LICENSE("GPL");
-
-module_init(sensors_w83l785ts_init);
-module_exit(sensors_w83l785ts_exit);
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -21,7 +21,6 @@
    All SMBus-related things are written by Frodo Looijaard <frodol@dds.nl>
    SMBus 2.0 support by Mark Studebaker <mdsxyz123@yahoo.com>                */
 
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
@@ -103,7 +102,7 @@ static struct class i2c_adapter_class = 
 	.release =	&i2c_adapter_class_dev_release,
 };
 
-static ssize_t show_adapter_name(struct device *dev, char *buf)
+static ssize_t show_adapter_name(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct i2c_adapter *adap = dev_to_i2c_adapter(dev);
 	return sprintf(buf, "%s\n", adap->name);
@@ -117,7 +116,7 @@ static void i2c_client_release(struct de
 	complete(&client->released);
 }
 
-static ssize_t show_client_name(struct device *dev, char *buf)
+static ssize_t show_client_name(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	return sprintf(buf, "%s\n", client->name);
@@ -157,7 +156,7 @@ int i2c_add_adapter(struct i2c_adapter *
 		goto out_unlock;
 	}
 
-	res = idr_get_new(&i2c_adapter_idr, NULL, &id);
+	res = idr_get_new(&i2c_adapter_idr, adap, &id);
 	if (res < 0) {
 		if (res == -EAGAIN)
 			res = -ENOMEM;
@@ -232,14 +231,14 @@ int i2c_del_adapter(struct i2c_adapter *
 		if (driver->detach_adapter)
 			if ((res = driver->detach_adapter(adap))) {
 				dev_warn(&adap->dev, "can't detach adapter "
-					 "while detaching driver %s: driver not "
-					 "detached!", driver->name);
+					 "while detaching driver %s: driver "
+					 "not detached!\n", driver->name);
 				goto out_unlock;
 			}
 	}
 
 	/* detach any active clients. This must be done first, because
-	 * it can fail; in which case we give upp. */
+	 * it can fail; in which case we give up. */
 	list_for_each_safe(item, _n, &adap->clients) {
 		client = list_entry(item, struct i2c_client, list);
 
@@ -457,8 +456,8 @@ int i2c_detach_client(struct i2c_client 
 		res = adapter->client_unregister(client);
 		if (res) {
 			dev_err(&client->dev,
-			       "client_unregister [%s] failed, "
-			       "client not detached", client->name);
+				"client_unregister [%s] failed, "
+				"client not detached\n", client->name);
 			goto out;
 		}
 	}
@@ -612,27 +611,16 @@ int i2c_master_send(struct i2c_client *c
 	struct i2c_adapter *adap=client->adapter;
 	struct i2c_msg msg;
 
-	if (client->adapter->algo->master_xfer) {
-		msg.addr   = client->addr;
-		msg.flags = client->flags & I2C_M_TEN;
-		msg.len = count;
-		msg.buf = (char *)buf;
+	msg.addr = client->addr;
+	msg.flags = client->flags & I2C_M_TEN;
+	msg.len = count;
+	msg.buf = (char *)buf;
 	
-		dev_dbg(&client->adapter->dev, "master_send: writing %d bytes.\n",
-			count);
-	
-		down(&adap->bus_lock);
-		ret = adap->algo->master_xfer(adap,&msg,1);
-		up(&adap->bus_lock);
+	ret = i2c_transfer(adap, &msg, 1);
 
-		/* if everything went ok (i.e. 1 msg transmitted), return #bytes
-		 * transmitted, else error code.
-		 */
-		return (ret == 1 )? count : ret;
-	} else {
-		dev_err(&client->adapter->dev, "I2C level transfers not supported\n");
-		return -ENOSYS;
-	}
+	/* If everything went ok (i.e. 1 msg transmitted), return #bytes
+	   transmitted, else error code. */
+	return (ret == 1) ? count : ret;
 }
 
 int i2c_master_recv(struct i2c_client *client, char *buf ,int count)
@@ -640,31 +628,18 @@ int i2c_master_recv(struct i2c_client *c
 	struct i2c_adapter *adap=client->adapter;
 	struct i2c_msg msg;
 	int ret;
-	if (client->adapter->algo->master_xfer) {
-		msg.addr   = client->addr;
-		msg.flags = client->flags & I2C_M_TEN;
-		msg.flags |= I2C_M_RD;
-		msg.len = count;
-		msg.buf = buf;
 
-		dev_dbg(&client->adapter->dev, "master_recv: reading %d bytes.\n",
-			count);
-	
-		down(&adap->bus_lock);
-		ret = adap->algo->master_xfer(adap,&msg,1);
-		up(&adap->bus_lock);
-	
-		dev_dbg(&client->adapter->dev, "master_recv: return:%d (count:%d, addr:0x%02x)\n",
-			ret, count, client->addr);
-	
-		/* if everything went ok (i.e. 1 msg transmitted), return #bytes
-	 	* transmitted, else error code.
-	 	*/
-		return (ret == 1 )? count : ret;
-	} else {
-		dev_err(&client->adapter->dev, "I2C level transfers not supported\n");
-		return -ENOSYS;
-	}
+	msg.addr = client->addr;
+	msg.flags = client->flags & I2C_M_TEN;
+	msg.flags |= I2C_M_RD;
+	msg.len = count;
+	msg.buf = buf;
+
+	ret = i2c_transfer(adap, &msg, 1);
+
+	/* If everything went ok (i.e. 1 msg transmitted), return #bytes
+	   transmitted, else error code. */
+	return (ret == 1) ? count : ret;
 }
 
 
@@ -742,18 +717,6 @@ int i2c_probe(struct i2c_adapter *adapte
 				found = 1;
 			}
 		}
-		for (i = 0;
-		     !found && (address_data->ignore_range[i] != I2C_CLIENT_END);
-		     i += 3) {
-			if (((adap_id == address_data->ignore_range[i]) ||
-			    ((address_data->ignore_range[i]==ANY_I2C_BUS))) &&
-			    (addr >= address_data->ignore_range[i+1]) &&
-			    (addr <= address_data->ignore_range[i+2])) {
-				dev_dbg(&adapter->dev, "found ignore_range parameter for adapter %d, "
-					"addr %04x\n", adap_id,addr);
-				found = 1;
-			}
-		}
 		if (found) 
 			continue;
 
@@ -770,17 +733,6 @@ int i2c_probe(struct i2c_adapter *adapte
 		}
 
 		for (i = 0;
-		     !found && (address_data->normal_i2c_range[i] != I2C_CLIENT_END);
-		     i += 2) {
-			if ((addr >= address_data->normal_i2c_range[i]) &&
-			    (addr <= address_data->normal_i2c_range[i+1])) {
-				found = 1;
-				dev_dbg(&adapter->dev, "found normal i2c_range entry for adapter %d, "
-					"addr %04x\n", adap_id,addr);
-			}
-		}
-
-		for (i = 0;
 		     !found && (address_data->probe[i] != I2C_CLIENT_END);
 		     i += 2) {
 			if (((adap_id == address_data->probe[i]) ||
@@ -791,18 +743,6 @@ int i2c_probe(struct i2c_adapter *adapte
 					"addr %04x\n", adap_id,addr);
 			}
 		}
-		for (i = 0;
-		     !found && (address_data->probe_range[i] != I2C_CLIENT_END);
-		     i += 3) {
-			if (((adap_id == address_data->probe_range[i]) ||
-			   (address_data->probe_range[i] == ANY_I2C_BUS)) &&
-			   (addr >= address_data->probe_range[i+1]) &&
-			   (addr <= address_data->probe_range[i+2])) {
-				found = 1;
-				dev_dbg(&adapter->dev, "found probe_range parameter for adapter %d, "
-					"addr %04x\n", adap_id,addr);
-			}
-		}
 		if (!found) 
 			continue;
 
@@ -825,20 +765,15 @@ int i2c_adapter_id(struct i2c_adapter *a
 
 struct i2c_adapter* i2c_get_adapter(int id)
 {
-	struct list_head   *item;
 	struct i2c_adapter *adapter;
 	
 	down(&core_lists);
-	list_for_each(item,&adapters) {
-		adapter = list_entry(item, struct i2c_adapter, list);
-		if (id == adapter->nr &&
-		    try_module_get(adapter->owner)) {
-			up(&core_lists);
-			return adapter;
-		}
-	}
+	adapter = (struct i2c_adapter *)idr_find(&i2c_adapter_idr, id);
+	if (adapter && !try_module_get(adapter->owner))
+		adapter = NULL;
+
 	up(&core_lists);
-	return NULL;
+	return adapter;
 }
 
 void i2c_put_adapter(struct i2c_adapter *adap)
diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c
--- a/drivers/i2c/i2c-dev.c
+++ b/drivers/i2c/i2c-dev.c
@@ -29,7 +29,6 @@
 /* The devfs code is contributed by Philipp Matthias Hahn 
    <pmhahn@titan.lahn.de> */
 
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/fs.h>
@@ -214,7 +213,7 @@ static int i2cdev_ioctl(struct inode *in
 				   sizeof(rdwr_arg)))
 			return -EFAULT;
 
-		/* Put an arbritrary limit on the number of messages that can
+		/* Put an arbitrary limit on the number of messages that can
 		 * be sent at once */
 		if (rdwr_arg.nmsgs > I2C_RDRW_IOCTL_MAX_MSGS)
 			return -EINVAL;
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig
--- a/drivers/ide/Kconfig
+++ b/drivers/ide/Kconfig
@@ -606,6 +606,12 @@ config BLK_DEV_IT8172
 	  <http://www.ite.com.tw/ia/brief_it8172bsp.htm>; picture of the
 	  board at <http://www.mvista.com/partners/semiconductor/ite.html>.
 
+config BLK_DEV_IT821X
+	tristate "IT821X IDE support"
+	help
+	  This driver adds support for the ITE 8211 IDE controller and the
+	  IT 8212 IDE RAID controller in both RAID and pass-through mode.
+
 config BLK_DEV_NS87415
 	tristate "NS87415 chipset support"
 	help
@@ -672,8 +678,8 @@ config BLK_DEV_SVWKS
 	  chipsets.
 
 config BLK_DEV_SGIIOC4
-	tristate "Silicon Graphics IOC4 chipset support"
-	depends on IA64_SGI_SN2 || IA64_GENERIC
+	tristate "Silicon Graphics IOC4 chipset ATA/ATAPI support"
+	depends on (IA64_SGI_SN2 || IA64_GENERIC) && SGI_IOC4
 	help
 	  This driver adds PIO & MultiMode DMA-2 support for the SGI IOC4
 	  chipset, which has one channel and can support two devices.
@@ -758,6 +764,7 @@ config BLK_DEV_IDE_PMAC_ATA100FIRST
 config BLK_DEV_IDEDMA_PMAC
 	bool "PowerMac IDE DMA support"
 	depends on BLK_DEV_IDE_PMAC
+	select BLK_DEV_IDEDMA_PCI
 	help
 	  This option allows the driver for the built-in IDE controller on
 	  Power Macintoshes and PowerBooks to use DMA (direct memory access)
diff --git a/drivers/ide/Makefile b/drivers/ide/Makefile
--- a/drivers/ide/Makefile
+++ b/drivers/ide/Makefile
@@ -20,7 +20,6 @@ ide-core-$(CONFIG_BLK_DEV_CMD640)	+= pci
 # Core IDE code - must come before legacy
 ide-core-$(CONFIG_BLK_DEV_IDEPCI)	+= setup-pci.o
 ide-core-$(CONFIG_BLK_DEV_IDEDMA)	+= ide-dma.o
-ide-core-$(CONFIG_BLK_DEV_IDE_TCQ)	+= ide-tcq.o
 ide-core-$(CONFIG_PROC_FS)		+= ide-proc.o
 ide-core-$(CONFIG_BLK_DEV_IDEPNP)	+= ide-pnp.o
 
diff --git a/drivers/ide/cris/Makefile b/drivers/ide/cris/Makefile
--- a/drivers/ide/cris/Makefile
+++ b/drivers/ide/cris/Makefile
@@ -1,3 +1,3 @@
 EXTRA_CFLAGS				+= -Idrivers/ide
 
-obj-$(CONFIG_ETRAX_ARCH_V10)		+= ide-v10.o
+obj-y					+= ide-cris.o
diff --git a/drivers/ide/cris/ide-cris.c b/drivers/ide/cris/ide-cris.c
new file mode 100644
--- /dev/null
+++ b/drivers/ide/cris/ide-cris.c
@@ -0,0 +1,1107 @@
+/* $Id: cris-ide-driver.patch,v 1.1 2005/06/29 21:39:07 akpm Exp $
+ *
+ * Etrax specific IDE functions, like init and PIO-mode setting etc.
+ * Almost the entire ide.c is used for the rest of the Etrax ATA driver.
+ * Copyright (c) 2000-2005 Axis Communications AB
+ *
+ * Authors:    Bjorn Wesen        (initial version)
+ *             Mikael Starvik     (crisv32 port)
+ */
+
+/* Regarding DMA:
+ *
+ * There are two forms of DMA - "DMA handshaking" between the interface and the drive,
+ * and DMA between the memory and the interface. We can ALWAYS use the latter, since it's
+ * something built-in in the Etrax. However only some drives support the DMA-mode handshaking
+ * on the ATA-bus. The normal PC driver and Triton interface disables memory-if DMA when the
+ * device can't do DMA handshaking for some stupid reason. We don't need to do that.
+ */
+
+#undef REALLY_SLOW_IO           /* most systems can safely undef this */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/timer.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/blkdev.h>
+#include <linux/hdreg.h>
+#include <linux/ide.h>
+#include <linux/init.h>
+
+#include <asm/io.h>
+#include <asm/dma.h>
+
+/* number of DMA descriptors */
+#define MAX_DMA_DESCRS 64
+
+/* number of times to retry busy-flags when reading/writing IDE-registers
+ * this can't be too high because a hung harddisk might cause the watchdog
+ * to trigger (sometimes INB and OUTB are called with irq's disabled)
+ */
+
+#define IDE_REGISTER_TIMEOUT 300
+
+#define LOWDB(x)
+#define D(x)
+
+enum /* Transfer types */
+{
+	TYPE_PIO,
+	TYPE_DMA,
+	TYPE_UDMA
+};
+
+/* CRISv32 specifics */
+#ifdef CONFIG_ETRAX_ARCH_V32
+#include <asm/arch/hwregs/ata_defs.h>
+#include <asm/arch/hwregs/dma_defs.h>
+#include <asm/arch/hwregs/dma.h>
+#include <asm/arch/pinmux.h>
+
+#define ATA_UDMA2_CYC    2
+#define ATA_UDMA2_DVS    3
+#define ATA_UDMA1_CYC    2
+#define ATA_UDMA1_DVS    4
+#define ATA_UDMA0_CYC    4
+#define ATA_UDMA0_DVS    6
+#define ATA_DMA2_STROBE  7
+#define ATA_DMA2_HOLD    1
+#define ATA_DMA1_STROBE  8
+#define ATA_DMA1_HOLD    3
+#define ATA_DMA0_STROBE 25
+#define ATA_DMA0_HOLD   19
+#define ATA_PIO4_SETUP   3
+#define ATA_PIO4_STROBE  7
+#define ATA_PIO4_HOLD    1
+#define ATA_PIO3_SETUP   3
+#define ATA_PIO3_STROBE  9
+#define ATA_PIO3_HOLD    3
+#define ATA_PIO2_SETUP   3
+#define ATA_PIO2_STROBE 13
+#define ATA_PIO2_HOLD    5
+#define ATA_PIO1_SETUP   5
+#define ATA_PIO1_STROBE 23
+#define ATA_PIO1_HOLD    9
+#define ATA_PIO0_SETUP   9
+#define ATA_PIO0_STROBE 39
+#define ATA_PIO0_HOLD    9
+
+int
+cris_ide_ack_intr(ide_hwif_t* hwif)
+{
+	reg_ata_rw_ctrl2 ctrl2 = REG_TYPE_CONV(reg_ata_rw_ctrl2,
+	                         int, hwif->io_ports[0]);
+	REG_WR_INT(ata, regi_ata, rw_ack_intr, 1 << ctrl2.sel);
+	return 1;
+}
+
+static inline int
+cris_ide_busy(void)
+{
+	reg_ata_rs_stat_data stat_data;
+	stat_data = REG_RD(ata, regi_ata, rs_stat_data);
+	return stat_data.busy;
+}
+
+static inline int
+cris_ide_ready(void)
+{
+	return !cris_ide_busy();
+}
+
+static inline int
+cris_ide_data_available(unsigned short* data)
+{
+	reg_ata_rs_stat_data stat_data;
+	stat_data = REG_RD(ata, regi_ata, rs_stat_data);
+	*data = stat_data.data;
+	return stat_data.dav;
+}
+
+static void
+cris_ide_write_command(unsigned long command)
+{
+	REG_WR_INT(ata, regi_ata, rw_ctrl2, command); /* write data to the drive's register */
+}
+
+static void
+cris_ide_set_speed(int type, int setup, int strobe, int hold)
+{
+	reg_ata_rw_ctrl0 ctrl0 = REG_RD(ata, regi_ata, rw_ctrl0);
+	reg_ata_rw_ctrl1 ctrl1 = REG_RD(ata, regi_ata, rw_ctrl1);
+
+	if (type == TYPE_PIO) {
+		ctrl0.pio_setup = setup;
+		ctrl0.pio_strb = strobe;
+		ctrl0.pio_hold = hold;
+	} else if (type == TYPE_DMA) {
+		ctrl0.dma_strb = strobe;
+		ctrl0.dma_hold = hold;
+	} else if (type == TYPE_UDMA) {
+		ctrl1.udma_tcyc = setup;
+		ctrl1.udma_tdvs = strobe;
+	}
+	REG_WR(ata, regi_ata, rw_ctrl0, ctrl0);
+	REG_WR(ata, regi_ata, rw_ctrl1, ctrl1);
+}
+
+static unsigned long
+cris_ide_base_address(int bus)
+{
+	reg_ata_rw_ctrl2 ctrl2 = {0};
+	ctrl2.sel = bus;
+	return REG_TYPE_CONV(int, reg_ata_rw_ctrl2, ctrl2);
+}
+
+static unsigned long
+cris_ide_reg_addr(unsigned long addr, int cs0, int cs1)
+{
+	reg_ata_rw_ctrl2 ctrl2 = {0};
+	ctrl2.addr = addr;
+	ctrl2.cs1 = cs1;
+	ctrl2.cs0 = cs0;
+	return REG_TYPE_CONV(int, reg_ata_rw_ctrl2, ctrl2);
+}
+
+static __init void
+cris_ide_reset(unsigned val)
+{
+	reg_ata_rw_ctrl0 ctrl0 = {0};
+	ctrl0.rst = val ? regk_ata_active : regk_ata_inactive;
+	REG_WR(ata, regi_ata, rw_ctrl0, ctrl0);
+}
+
+static __init void
+cris_ide_init(void)
+{
+	reg_ata_rw_ctrl0 ctrl0 = {0};
+	reg_ata_rw_intr_mask intr_mask = {0};
+
+	ctrl0.en = regk_ata_yes;
+	REG_WR(ata, regi_ata, rw_ctrl0, ctrl0);
+
+	intr_mask.bus0 = regk_ata_yes;
+	intr_mask.bus1 = regk_ata_yes;
+	intr_mask.bus2 = regk_ata_yes;
+	intr_mask.bus3 = regk_ata_yes;
+
+	REG_WR(ata, regi_ata, rw_intr_mask, intr_mask);
+
+	crisv32_request_dma(2, "ETRAX FS built-in ATA", DMA_VERBOSE_ON_ERROR, 0, dma_ata);
+	crisv32_request_dma(3, "ETRAX FS built-in ATA", DMA_VERBOSE_ON_ERROR, 0, dma_ata);
+
+	crisv32_pinmux_alloc_fixed(pinmux_ata);
+	crisv32_pinmux_alloc_fixed(pinmux_ata0);
+	crisv32_pinmux_alloc_fixed(pinmux_ata1);
+	crisv32_pinmux_alloc_fixed(pinmux_ata2);
+	crisv32_pinmux_alloc_fixed(pinmux_ata3);
+
+	DMA_RESET(regi_dma2);
+	DMA_ENABLE(regi_dma2);
+	DMA_RESET(regi_dma3);
+	DMA_ENABLE(regi_dma3);
+
+	DMA_WR_CMD (regi_dma2, regk_dma_set_w_size2);
+	DMA_WR_CMD (regi_dma3, regk_dma_set_w_size2);
+}
+
+static dma_descr_context mycontext __attribute__ ((__aligned__(32)));
+
+#define cris_dma_descr_type dma_descr_data
+#define cris_pio_read regk_ata_rd
+#define cris_ultra_mask 0x7
+#define MAX_DESCR_SIZE 0xffffffffUL
+
+static unsigned long
+cris_ide_get_reg(unsigned long reg)
+{
+	return (reg & 0x0e000000) >> 25;
+}
+
+static void
+cris_ide_fill_descriptor(cris_dma_descr_type *d, void* buf, unsigned int len, int last)
+{
+	d->buf = (char*)virt_to_phys(buf);
+	d->after = d->buf + len;
+	d->eol = last;
+}
+
+static void
+cris_ide_start_dma(ide_drive_t *drive, cris_dma_descr_type *d, int dir,int type,int len)
+{
+	reg_ata_rw_ctrl2 ctrl2 = REG_TYPE_CONV(reg_ata_rw_ctrl2, int, IDE_DATA_REG);
+	reg_ata_rw_trf_cnt trf_cnt = {0};
+
+	mycontext.saved_data = (dma_descr_data*)virt_to_phys(d);
+	mycontext.saved_data_buf = d->buf;
+	/* start the dma channel */
+	DMA_START_CONTEXT(dir ? regi_dma3 : regi_dma2, virt_to_phys(&mycontext));
+
+	/* initiate a multi word dma read using PIO handshaking */
+	trf_cnt.cnt = len >> 1;
+	/* Due to a "feature" the transfer count has to be one extra word for UDMA. */
+	if (type == TYPE_UDMA)
+		trf_cnt.cnt++;
+	REG_WR(ata, regi_ata, rw_trf_cnt, trf_cnt);
+
+	ctrl2.rw = dir ? regk_ata_rd : regk_ata_wr;
+	ctrl2.trf_mode = regk_ata_dma;
+	ctrl2.hsh = type == TYPE_PIO ? regk_ata_pio :
+	            type == TYPE_DMA ? regk_ata_dma : regk_ata_udma;
+	ctrl2.multi = regk_ata_yes;
+	ctrl2.dma_size = regk_ata_word;
+	REG_WR(ata, regi_ata, rw_ctrl2, ctrl2);
+}
+
+static void
+cris_ide_wait_dma(int dir)
+{
+	reg_dma_rw_stat status;
+	do
+	{
+		status = REG_RD(dma, dir ? regi_dma3 : regi_dma2, rw_stat);
+	} while(status.list_state != regk_dma_data_at_eol);
+}
+
+static int cris_dma_test_irq(ide_drive_t *drive)
+{
+	int intr = REG_RD_INT(ata, regi_ata, r_intr);
+	reg_ata_rw_ctrl2 ctrl2 = REG_TYPE_CONV(reg_ata_rw_ctrl2, int, IDE_DATA_REG);
+	return intr & (1 << ctrl2.sel) ? 1 : 0;
+}
+
+static void cris_ide_initialize_dma(int dir)
+{
+}
+
+#else
+/* CRISv10 specifics */
+#include <asm/arch/svinto.h>
+#include <asm/arch/io_interface_mux.h>
+
+/* PIO timing (in R_ATA_CONFIG)
+ *
+ *                        _____________________________
+ * ADDRESS :     ________/
+ *
+ *                            _______________
+ * DIOR    :     ____________/               \__________
+ *
+ *                               _______________
+ * DATA    :     XXXXXXXXXXXXXXXX_______________XXXXXXXX
+ *
+ *
+ * DIOR is unbuffered while address and data is buffered.
+ * This creates two problems:
+ * 1. The DIOR pulse is to early (because it is unbuffered)
+ * 2. The rise time of DIOR is long
+ *
+ * There are at least three different plausible solutions
+ * 1. Use a pad capable of larger currents in Etrax
+ * 2. Use an external buffer
+ * 3. Make the strobe pulse longer
+ *
+ * Some of the strobe timings below are modified to compensate
+ * for this. This implies a slight performance decrease.
+ *
+ * THIS SHOULD NEVER BE CHANGED!
+ *
+ * TODO: Is this true for the latest LX boards still ?
+ */
+
+#define ATA_UDMA2_CYC    0 /* No UDMA supported, just to make it compile. */
+#define ATA_UDMA2_DVS    0
+#define ATA_UDMA1_CYC    0
+#define ATA_UDMA1_DVS    0
+#define ATA_UDMA0_CYC    0
+#define ATA_UDMA0_DVS    0
+#define ATA_DMA2_STROBE  4
+#define ATA_DMA2_HOLD    0
+#define ATA_DMA1_STROBE  4
+#define ATA_DMA1_HOLD    1
+#define ATA_DMA0_STROBE 12
+#define ATA_DMA0_HOLD    9
+#define ATA_PIO4_SETUP   1
+#define ATA_PIO4_STROBE  5
+#define ATA_PIO4_HOLD    0
+#define ATA_PIO3_SETUP   1
+#define ATA_PIO3_STROBE  5
+#define ATA_PIO3_HOLD    1
+#define ATA_PIO2_SETUP   1
+#define ATA_PIO2_STROBE  6
+#define ATA_PIO2_HOLD    2
+#define ATA_PIO1_SETUP   2
+#define ATA_PIO1_STROBE 11
+#define ATA_PIO1_HOLD    4
+#define ATA_PIO0_SETUP   4
+#define ATA_PIO0_STROBE 19
+#define ATA_PIO0_HOLD    4
+
+int
+cris_ide_ack_intr(ide_hwif_t* hwif)
+{
+	return 1;
+}
+
+static inline int
+cris_ide_busy(void)
+{
+	return *R_ATA_STATUS_DATA & IO_MASK(R_ATA_STATUS_DATA, busy) ;
+}
+
+static inline int
+cris_ide_ready(void)
+{
+	return *R_ATA_STATUS_DATA & IO_MASK(R_ATA_STATUS_DATA, tr_rdy) ;
+}
+
+static inline int
+cris_ide_data_available(unsigned short* data)
+{
+	unsigned long status = *R_ATA_STATUS_DATA;
+	*data = (unsigned short)status;
+	return status & IO_MASK(R_ATA_STATUS_DATA, dav);
+}
+
+static void
+cris_ide_write_command(unsigned long command)
+{
+	*R_ATA_CTRL_DATA = command;
+}
+
+static void
+cris_ide_set_speed(int type, int setup, int strobe, int hold)
+{
+	static int pio_setup = ATA_PIO4_SETUP;
+	static int pio_strobe = ATA_PIO4_STROBE;
+	static int pio_hold = ATA_PIO4_HOLD;
+	static int dma_strobe = ATA_DMA2_STROBE;
+	static int dma_hold = ATA_DMA2_HOLD;
+
+	if (type == TYPE_PIO) {
+		pio_setup = setup;
+		pio_strobe = strobe;
+		pio_hold = hold;
+	} else if (type == TYPE_DMA) {
+		dma_strobe = strobe;
+	  dma_hold = hold;
+	}
+	*R_ATA_CONFIG = ( IO_FIELD( R_ATA_CONFIG, enable, 1 ) |
+	  IO_FIELD( R_ATA_CONFIG, dma_strobe, dma_strobe ) |
+		IO_FIELD( R_ATA_CONFIG, dma_hold,   dma_hold ) |
+		IO_FIELD( R_ATA_CONFIG, pio_setup,  pio_setup ) |
+		IO_FIELD( R_ATA_CONFIG, pio_strobe, pio_strobe ) |
+		IO_FIELD( R_ATA_CONFIG, pio_hold,   pio_hold ) );
+}
+
+static unsigned long
+cris_ide_base_address(int bus)
+{
+	return IO_FIELD(R_ATA_CTRL_DATA, sel, bus);
+}
+
+static unsigned long
+cris_ide_reg_addr(unsigned long addr, int cs0, int cs1)
+{
+	return IO_FIELD(R_ATA_CTRL_DATA, addr, addr) |
+	       IO_FIELD(R_ATA_CTRL_DATA, cs0, cs0) |
+	       IO_FIELD(R_ATA_CTRL_DATA, cs1, cs1);
+}
+
+static __init void
+cris_ide_reset(unsigned val)
+{
+#ifdef CONFIG_ETRAX_IDE_G27_RESET
+	REG_SHADOW_SET(R_PORT_G_DATA, port_g_data_shadow, 27, val);
+#endif
+#ifdef CONFIG_ETRAX_IDE_CSE1_16_RESET
+	REG_SHADOW_SET(port_cse1_addr, port_cse1_shadow, 16, val);
+#endif
+#ifdef CONFIG_ETRAX_IDE_CSP0_8_RESET
+	REG_SHADOW_SET(port_csp0_addr, port_csp0_shadow, 8, val);
+#endif
+#ifdef CONFIG_ETRAX_IDE_PB7_RESET
+	port_pb_dir_shadow = port_pb_dir_shadow |
+		IO_STATE(R_PORT_PB_DIR, dir7, output);
+	*R_PORT_PB_DIR = port_pb_dir_shadow;
+	REG_SHADOW_SET(R_PORT_PB_DATA, port_pb_data_shadow, 7, val);
+#endif
+}
+
+static __init void
+cris_ide_init(void)
+{
+	volatile unsigned int dummy;
+
+	*R_ATA_CTRL_DATA = 0;
+	*R_ATA_TRANSFER_CNT = 0;
+	*R_ATA_CONFIG = 0;
+
+	if (cris_request_io_interface(if_ata, "ETRAX100LX IDE")) {
+		printk(KERN_CRIT "ide: Failed to get IO interface\n");
+		return;
+	} else if (cris_request_dma(ATA_TX_DMA_NBR,
+		                          "ETRAX100LX IDE TX",
+		                          DMA_VERBOSE_ON_ERROR,
+		                          dma_ata)) {
+		cris_free_io_interface(if_ata);
+		printk(KERN_CRIT "ide: Failed to get Tx DMA channel\n");
+		return;
+	} else if (cris_request_dma(ATA_RX_DMA_NBR,
+		                          "ETRAX100LX IDE RX",
+		                          DMA_VERBOSE_ON_ERROR,
+		                          dma_ata)) {
+		cris_free_dma(ATA_TX_DMA_NBR, "ETRAX100LX IDE Tx");
+		cris_free_io_interface(if_ata);
+		printk(KERN_CRIT "ide: Failed to get Rx DMA channel\n");
+		return;
+	}
+
+	/* make a dummy read to set the ata controller in a proper state */
+	dummy = *R_ATA_STATUS_DATA;
+
+	*R_ATA_CONFIG = ( IO_FIELD( R_ATA_CONFIG, enable, 1 ));
+	*R_ATA_CTRL_DATA = ( IO_STATE( R_ATA_CTRL_DATA, rw,   read) |
+	                     IO_FIELD( R_ATA_CTRL_DATA, addr, 1   ) );
+
+	while(*R_ATA_STATUS_DATA & IO_MASK(R_ATA_STATUS_DATA, busy)); /* wait for busy flag*/
+
+	*R_IRQ_MASK0_SET = ( IO_STATE( R_IRQ_MASK0_SET, ata_irq0, set ) |
+	                     IO_STATE( R_IRQ_MASK0_SET, ata_irq1, set ) |
+	                     IO_STATE( R_IRQ_MASK0_SET, ata_irq2, set ) |
+	                     IO_STATE( R_IRQ_MASK0_SET, ata_irq3, set ) );
+
+	/* reset the dma channels we will use */
+
+	RESET_DMA(ATA_TX_DMA_NBR);
+	RESET_DMA(ATA_RX_DMA_NBR);
+	WAIT_DMA(ATA_TX_DMA_NBR);
+	WAIT_DMA(ATA_RX_DMA_NBR);
+}
+
+#define cris_dma_descr_type etrax_dma_descr
+#define cris_pio_read IO_STATE(R_ATA_CTRL_DATA, rw, read)
+#define cris_ultra_mask 0x0
+#define MAX_DESCR_SIZE 0x10000UL
+
+static unsigned long
+cris_ide_get_reg(unsigned long reg)
+{
+	return (reg & 0x0e000000) >> 25;
+}
+
+static void
+cris_ide_fill_descriptor(cris_dma_descr_type *d, void* buf, unsigned int len, int last)
+{
+	d->buf = virt_to_phys(buf);
+	d->sw_len = len == MAX_DESCR_SIZE ? 0 : len;
+	if (last)
+		d->ctrl |= d_eol;
+}
+
+static void cris_ide_start_dma(ide_drive_t *drive, cris_dma_descr_type *d, int dir, int type, int len)
+{
+	unsigned long cmd;
+
+	if (dir) {
+		/* need to do this before RX DMA due to a chip bug
+		 * it is enough to just flush the part of the cache that
+		 * corresponds to the buffers we start, but since HD transfers
+		 * usually are more than 8 kB, it is easier to optimize for the
+		 * normal case and just flush the entire cache. its the only
+		 * way to be sure! (OB movie quote)
+		 */
+		flush_etrax_cache();
+		*R_DMA_CH3_FIRST = virt_to_phys(d);
+		*R_DMA_CH3_CMD   = IO_STATE(R_DMA_CH3_CMD, cmd, start);
+
+	} else {
+		*R_DMA_CH2_FIRST = virt_to_phys(d);
+		*R_DMA_CH2_CMD   = IO_STATE(R_DMA_CH2_CMD, cmd, start);
+	}
+
+	/* initiate a multi word dma read using DMA handshaking */
+
+	*R_ATA_TRANSFER_CNT =
+		IO_FIELD(R_ATA_TRANSFER_CNT, count, len >> 1);
+
+	cmd = dir ? IO_STATE(R_ATA_CTRL_DATA, rw, read) : IO_STATE(R_ATA_CTRL_DATA, rw, write);
+	cmd |= type == TYPE_PIO ? IO_STATE(R_ATA_CTRL_DATA, handsh, pio) :
+	                          IO_STATE(R_ATA_CTRL_DATA, handsh, dma);
+	*R_ATA_CTRL_DATA =
+		cmd |
+		IO_FIELD(R_ATA_CTRL_DATA, data, IDE_DATA_REG) |
+		IO_STATE(R_ATA_CTRL_DATA, src_dst,  dma)  |
+		IO_STATE(R_ATA_CTRL_DATA, multi,    on)   |
+		IO_STATE(R_ATA_CTRL_DATA, dma_size, word);
+}
+
+static void
+cris_ide_wait_dma(int dir)
+{
+	if (dir)
+		WAIT_DMA(ATA_RX_DMA_NBR);
+	else
+		WAIT_DMA(ATA_TX_DMA_NBR);
+}
+
+static int cris_dma_test_irq(ide_drive_t *drive)
+{
+	int intr = *R_IRQ_MASK0_RD;
+	int bus = IO_EXTRACT(R_ATA_CTRL_DATA, sel, IDE_DATA_REG);
+	return intr & (1 << (bus + IO_BITNR(R_IRQ_MASK0_RD, ata_irq0))) ? 1 : 0;
+}
+
+
+static void cris_ide_initialize_dma(int dir)
+{
+	if (dir)
+	{
+		RESET_DMA(ATA_RX_DMA_NBR); /* sometimes the DMA channel get stuck so we need to do this */
+		WAIT_DMA(ATA_RX_DMA_NBR);
+	}
+	else
+	{
+		RESET_DMA(ATA_TX_DMA_NBR); /* sometimes the DMA channel get stuck so we need to do this */
+		WAIT_DMA(ATA_TX_DMA_NBR);
+	}
+}
+
+#endif
+
+void
+cris_ide_outw(unsigned short data, unsigned long reg) {
+	int timeleft;
+
+	LOWDB(printk("ow: data 0x%x, reg 0x%x\n", data, reg));
+
+	/* note the lack of handling any timeouts. we stop waiting, but we don't
+	 * really notify anybody.
+	 */
+
+	timeleft = IDE_REGISTER_TIMEOUT;
+	/* wait for busy flag */
+	do {
+		timeleft--;
+	} while(timeleft && cris_ide_busy());
+
+	/*
+	 * Fall through at a timeout, so the ongoing command will be
+	 * aborted by the write below, which is expected to be a dummy
+	 * command to the command register.  This happens when a faulty
+	 * drive times out on a command.  See comment on timeout in
+	 * INB.
+	 */
+	if(!timeleft)
+		printk("ATA timeout reg 0x%lx := 0x%x\n", reg, data);
+
+	cris_ide_write_command(reg|data); /* write data to the drive's register */
+
+	timeleft = IDE_REGISTER_TIMEOUT;
+	/* wait for transmitter ready */
+	do {
+		timeleft--;
+	} while(timeleft && !cris_ide_ready());
+}
+
+void
+cris_ide_outb(unsigned char data, unsigned long reg)
+{
+	cris_ide_outw(data, reg);
+}
+
+void
+cris_ide_outbsync(ide_drive_t *drive, u8 addr, unsigned long port)
+{
+	cris_ide_outw(addr, port);
+}
+
+unsigned short
+cris_ide_inw(unsigned long reg) {
+	int timeleft;
+	unsigned short val;
+
+	timeleft = IDE_REGISTER_TIMEOUT;
+	/* wait for busy flag */
+	do {
+		timeleft--;
+	} while(timeleft && cris_ide_busy());
+
+	if(!timeleft) {
+		/*
+		 * If we're asked to read the status register, like for
+		 * example when a command does not complete for an
+		 * extended time, but the ATA interface is stuck in a
+		 * busy state at the *ETRAX* ATA interface level (as has
+		 * happened repeatedly with at least one bad disk), then
+		 * the best thing to do is to pretend that we read
+		 * "busy" in the status register, so the IDE driver will
+		 * time-out, abort the ongoing command and perform a
+		 * reset sequence.  Note that the subsequent OUT_BYTE
+		 * call will also timeout on busy, but as long as the
+		 * write is still performed, everything will be fine.
+		 */
+		if (cris_ide_get_reg(reg) == IDE_STATUS_OFFSET)
+			return BUSY_STAT;
+		else
+			/* For other rare cases we assume 0 is good enough.  */
+			return 0;
+	}
+
+	cris_ide_write_command(reg | cris_pio_read);
+
+	timeleft = IDE_REGISTER_TIMEOUT;
+	/* wait for available */
+	do {
+		timeleft--;
+	} while(timeleft && !cris_ide_data_available(&val));
+
+	if(!timeleft)
+		return 0;
+
+	LOWDB(printk("inb: 0x%x from reg 0x%x\n", val & 0xff, reg));
+
+	return val;
+}
+
+unsigned char
+cris_ide_inb(unsigned long reg)
+{
+	return (unsigned char)cris_ide_inw(reg);
+}
+
+static int cris_dma_check (ide_drive_t *drive);
+static int cris_dma_end (ide_drive_t *drive);
+static int cris_dma_setup (ide_drive_t *drive);
+static void cris_dma_exec_cmd (ide_drive_t *drive, u8 command);
+static int cris_dma_test_irq(ide_drive_t *drive);
+static void cris_dma_start(ide_drive_t *drive);
+static void cris_ide_input_data (ide_drive_t *drive, void *, unsigned int);
+static void cris_ide_output_data (ide_drive_t *drive, void *, unsigned int);
+static void cris_atapi_input_bytes(ide_drive_t *drive, void *, unsigned int);
+static void cris_atapi_output_bytes(ide_drive_t *drive, void *, unsigned int);
+static int cris_dma_off (ide_drive_t *drive);
+static int cris_dma_on (ide_drive_t *drive);
+
+static void tune_cris_ide(ide_drive_t *drive, u8 pio)
+{
+	int setup, strobe, hold;
+
+	switch(pio)
+	{
+		case 0:
+			setup = ATA_PIO0_SETUP;
+			strobe = ATA_PIO0_STROBE;
+			hold = ATA_PIO0_HOLD;
+			break;
+		case 1:
+			setup = ATA_PIO1_SETUP;
+			strobe = ATA_PIO1_STROBE;
+			hold = ATA_PIO1_HOLD;
+			break;
+		case 2:
+			setup = ATA_PIO2_SETUP;
+			strobe = ATA_PIO2_STROBE;
+			hold = ATA_PIO2_HOLD;
+			break;
+		case 3:
+			setup = ATA_PIO3_SETUP;
+			strobe = ATA_PIO3_STROBE;
+			hold = ATA_PIO3_HOLD;
+			break;
+		case 4:
+			setup = ATA_PIO4_SETUP;
+			strobe = ATA_PIO4_STROBE;
+			hold = ATA_PIO4_HOLD;
+			break;
+		default:
+			return;
+	}
+
+	cris_ide_set_speed(TYPE_PIO, setup, strobe, hold);
+}
+
+static int speed_cris_ide(ide_drive_t *drive, u8 speed)
+{
+	int cyc = 0, dvs = 0, strobe = 0, hold = 0;
+
+	if (speed >= XFER_PIO_0 && speed <= XFER_PIO_4) {
+		tune_cris_ide(drive, speed - XFER_PIO_0);
+		return 0;
+	}
+
+	switch(speed)
+	{
+		case XFER_UDMA_0:
+			cyc = ATA_UDMA0_CYC;
+			dvs = ATA_UDMA0_DVS;
+			break;
+		case XFER_UDMA_1:
+			cyc = ATA_UDMA1_CYC;
+			dvs = ATA_UDMA1_DVS;
+			break;
+		case XFER_UDMA_2:
+			cyc = ATA_UDMA2_CYC;
+			dvs = ATA_UDMA2_DVS;
+			break;
+		case XFER_MW_DMA_0:
+			strobe = ATA_DMA0_STROBE;
+			hold = ATA_DMA0_HOLD;
+			break;
+		case XFER_MW_DMA_1:
+			strobe = ATA_DMA1_STROBE;
+			hold = ATA_DMA1_HOLD;
+			break;
+		case XFER_MW_DMA_2:
+			strobe = ATA_DMA2_STROBE;
+			hold = ATA_DMA2_HOLD;
+			break;
+		default:
+			return 0;
+	}
+
+	if (speed >= XFER_UDMA_0)
+		cris_ide_set_speed(TYPE_UDMA, cyc, dvs, 0);
+	else
+		cris_ide_set_speed(TYPE_DMA, 0, strobe, hold);
+
+	return 0;
+}
+
+void __init
+init_e100_ide (void)
+{
+	hw_regs_t hw;
+	int ide_offsets[IDE_NR_PORTS];
+	int h;
+	int i;
+
+	printk("ide: ETRAX FS built-in ATA DMA controller\n");
+
+	for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++)
+		ide_offsets[i] = cris_ide_reg_addr(i, 0, 1);
+
+	/* the IDE control register is at ATA address 6, with CS1 active instead of CS0 */
+	ide_offsets[IDE_CONTROL_OFFSET] = cris_ide_reg_addr(6, 1, 0);
+
+	/* first fill in some stuff in the ide_hwifs fields */
+
+	for(h = 0; h < MAX_HWIFS; h++) {
+		ide_hwif_t *hwif = &ide_hwifs[h];
+		ide_setup_ports(&hw, cris_ide_base_address(h),
+		                ide_offsets,
+		                0, 0, cris_ide_ack_intr,
+		                ide_default_irq(0));
+		ide_register_hw(&hw, &hwif);
+		hwif->mmio = 2;
+		hwif->chipset = ide_etrax100;
+		hwif->tuneproc = &tune_cris_ide;
+		hwif->speedproc = &speed_cris_ide;
+		hwif->ata_input_data = &cris_ide_input_data;
+		hwif->ata_output_data = &cris_ide_output_data;
+		hwif->atapi_input_bytes = &cris_atapi_input_bytes;
+		hwif->atapi_output_bytes = &cris_atapi_output_bytes;
+		hwif->ide_dma_check = &cris_dma_check;
+		hwif->ide_dma_end = &cris_dma_end;
+		hwif->dma_setup = &cris_dma_setup;
+		hwif->dma_exec_cmd = &cris_dma_exec_cmd;
+		hwif->ide_dma_test_irq = &cris_dma_test_irq;
+		hwif->dma_start = &cris_dma_start;
+		hwif->OUTB = &cris_ide_outb;
+		hwif->OUTW = &cris_ide_outw;
+		hwif->OUTBSYNC = &cris_ide_outbsync;
+		hwif->INB = &cris_ide_inb;
+		hwif->INW = &cris_ide_inw;
+		hwif->ide_dma_host_off = &cris_dma_off;
+		hwif->ide_dma_host_on = &cris_dma_on;
+		hwif->ide_dma_off_quietly = &cris_dma_off;
+		hwif->udma_four = 0;
+		hwif->ultra_mask = cris_ultra_mask;
+		hwif->mwdma_mask = 0x07; /* Multiword DMA 0-2 */
+		hwif->swdma_mask = 0x07; /* Singleword DMA 0-2 */
+	}
+
+	/* Reset pulse */
+	cris_ide_reset(0);
+	udelay(25);
+	cris_ide_reset(1);
+
+	cris_ide_init();
+
+	cris_ide_set_speed(TYPE_PIO, ATA_PIO4_SETUP, ATA_PIO4_STROBE, ATA_PIO4_HOLD);
+	cris_ide_set_speed(TYPE_DMA, 0, ATA_DMA2_STROBE, ATA_DMA2_HOLD);
+	cris_ide_set_speed(TYPE_UDMA, ATA_UDMA2_CYC, ATA_UDMA2_DVS, 0);
+}
+
+static int cris_dma_off (ide_drive_t *drive)
+{
+	return 0;
+}
+
+static int cris_dma_on (ide_drive_t *drive)
+{
+	return 0;
+}
+
+
+static cris_dma_descr_type mydescr __attribute__ ((__aligned__(16)));
+
+/*
+ * 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.
+ */
+static void
+cris_atapi_input_bytes (ide_drive_t *drive, void *buffer, unsigned int bytecount)
+{
+	D(printk("atapi_input_bytes, buffer 0x%x, count %d\n",
+	         buffer, bytecount));
+
+	if(bytecount & 1) {
+		printk("warning, odd bytecount in cdrom_in_bytes = %d.\n", bytecount);
+		bytecount++; /* to round off */
+	}
+
+	/* setup DMA and start transfer */
+
+	cris_ide_fill_descriptor(&mydescr, buffer, bytecount, 1);
+	cris_ide_start_dma(drive, &mydescr, 1, TYPE_PIO, bytecount);
+
+	/* wait for completion */
+	LED_DISK_READ(1);
+	cris_ide_wait_dma(1);
+	LED_DISK_READ(0);
+}
+
+static void
+cris_atapi_output_bytes (ide_drive_t *drive, void *buffer, unsigned int bytecount)
+{
+	D(printk("atapi_output_bytes, buffer 0x%x, count %d\n",
+	         buffer, bytecount));
+
+	if(bytecount & 1) {
+		printk("odd bytecount %d in atapi_out_bytes!\n", bytecount);
+		bytecount++;
+	}
+
+	cris_ide_fill_descriptor(&mydescr, buffer, bytecount, 1);
+	cris_ide_start_dma(drive, &mydescr, 0, TYPE_PIO, bytecount);
+
+	/* wait for completion */
+
+	LED_DISK_WRITE(1);
+	LED_DISK_READ(1);
+	cris_ide_wait_dma(0);
+	LED_DISK_WRITE(0);
+}
+
+/*
+ * This is used for most PIO data transfers *from* the IDE interface
+ */
+static void
+cris_ide_input_data (ide_drive_t *drive, void *buffer, unsigned int wcount)
+{
+	cris_atapi_input_bytes(drive, buffer, wcount << 2);
+}
+
+/*
+ * This is used for most PIO data transfers *to* the IDE interface
+ */
+static void
+cris_ide_output_data (ide_drive_t *drive, void *buffer, unsigned int wcount)
+{
+	cris_atapi_output_bytes(drive, buffer, wcount << 2);
+}
+
+/* we only have one DMA channel on the chip for ATA, so we can keep these statically */
+static cris_dma_descr_type ata_descrs[MAX_DMA_DESCRS] __attribute__ ((__aligned__(16)));
+static unsigned int ata_tot_size;
+
+/*
+ * cris_ide_build_dmatable() prepares a dma request.
+ * Returns 0 if all went okay, returns 1 otherwise.
+ */
+static int cris_ide_build_dmatable (ide_drive_t *drive)
+{
+	ide_hwif_t *hwif = drive->hwif;
+	struct scatterlist* sg;
+	struct request *rq  = drive->hwif->hwgroup->rq;
+	unsigned long size, addr;
+	unsigned int count = 0;
+	int i = 0;
+
+	sg = hwif->sg_table;
+
+	ata_tot_size = 0;
+
+	ide_map_sg(drive, rq);
+	i = hwif->sg_nents;
+
+	while(i) {
+		/*
+		 * Determine addr and size of next buffer area.  We assume that
+		 * individual virtual buffers are always composed linearly in
+		 * physical memory.  For example, we assume that any 8kB buffer
+		 * is always composed of two adjacent physical 4kB pages rather
+		 * than two possibly non-adjacent physical 4kB pages.
+		 */
+		/* group sequential buffers into one large buffer */
+		addr = page_to_phys(sg->page) + sg->offset;
+		size = sg_dma_len(sg);
+		while (sg++, --i) {
+			if ((addr + size) != page_to_phys(sg->page) + sg->offset)
+				break;
+			size += sg_dma_len(sg);
+		}
+
+		/* did we run out of descriptors? */
+
+		if(count >= MAX_DMA_DESCRS) {
+			printk("%s: too few DMA descriptors\n", drive->name);
+			return 1;
+		}
+
+		/* however, this case is more difficult - rw_trf_cnt cannot be more
+		   than 65536 words per transfer, so in that case we need to either
+		   1) use a DMA interrupt to re-trigger rw_trf_cnt and continue with
+		      the descriptors, or
+		   2) simply do the request here, and get dma_intr to only ide_end_request on
+		      those blocks that were actually set-up for transfer.
+		*/
+
+		if(ata_tot_size + size > 131072) {
+			printk("too large total ATA DMA request, %d + %d!\n", ata_tot_size, (int)size);
+			return 1;
+		}
+
+		/* If size > MAX_DESCR_SIZE it has to be splitted into new descriptors. Since we
+                   don't handle size > 131072 only one split is necessary */
+
+		if(size > MAX_DESCR_SIZE) {
+			cris_ide_fill_descriptor(&ata_descrs[count], (void*)addr, MAX_DESCR_SIZE, 0);
+			count++;
+			ata_tot_size += MAX_DESCR_SIZE;
+			size -= MAX_DESCR_SIZE;
+			addr += MAX_DESCR_SIZE;
+		}
+
+		cris_ide_fill_descriptor(&ata_descrs[count], (void*)addr, size,i ? 0 : 1);
+		count++;
+		ata_tot_size += size;
+	}
+
+	if (count) {
+		/* return and say all is ok */
+		return 0;
+	}
+
+	printk("%s: empty DMA table?\n", drive->name);
+	return 1;	/* let the PIO routines handle this weirdness */
+}
+
+static int cris_config_drive_for_dma (ide_drive_t *drive)
+{
+	u8 speed = ide_dma_speed(drive, 1);
+
+	if (!speed)
+		return 0;
+
+	speed_cris_ide(drive, speed);
+	ide_config_drive_speed(drive, speed);
+
+	return ide_dma_enable(drive);
+}
+
+/*
+ * cris_dma_intr() is the handler for disk read/write DMA interrupts
+ */
+static ide_startstop_t cris_dma_intr (ide_drive_t *drive)
+{
+	LED_DISK_READ(0);
+	LED_DISK_WRITE(0);
+
+	return ide_dma_intr(drive);
+}
+
+/*
+ * Functions below initiates/aborts DMA read/write operations on a drive.
+ *
+ * The caller is assumed to have selected the drive and programmed the drive's
+ * sector address using CHS or LBA.  All that remains is to prepare for DMA
+ * and then issue the actual read/write DMA/PIO command to the drive.
+ *
+ * For ATAPI devices, we just prepare for DMA and return. The caller should
+ * then issue the packet command to the drive and call us again with
+ * cris_dma_start afterwards.
+ *
+ * Returns 0 if all went well.
+ * Returns 1 if DMA read/write could not be started, in which case
+ * the caller should revert to PIO for the current request.
+ */
+
+static int cris_dma_check(ide_drive_t *drive)
+{
+	ide_hwif_t *hwif = drive->hwif;
+	struct hd_driveid* id = drive->id;
+
+	if (id && (id->capability & 1)) {
+		if (ide_use_dma(drive)) {
+			if (cris_config_drive_for_dma(drive))
+				return hwif->ide_dma_on(drive);
+		}
+	}
+
+	return hwif->ide_dma_off_quietly(drive);
+}
+
+static int cris_dma_end(ide_drive_t *drive)
+{
+	drive->waiting_for_dma = 0;
+	return 0;
+}
+
+static int cris_dma_setup(ide_drive_t *drive)
+{
+	struct request *rq = drive->hwif->hwgroup->rq;
+
+	cris_ide_initialize_dma(!rq_data_dir(rq));
+	if (cris_ide_build_dmatable (drive)) {
+		ide_map_sg(drive, rq);
+		return 1;
+	}
+
+	drive->waiting_for_dma = 1;
+	return 0;
+}
+
+static void cris_dma_exec_cmd(ide_drive_t *drive, u8 command)
+{
+	/* set the irq handler which will finish the request when DMA is done */
+	ide_set_handler(drive, &cris_dma_intr, WAIT_CMD, NULL);
+
+	/* issue cmd to drive */
+	cris_ide_outb(command, IDE_COMMAND_REG);
+}
+
+static void cris_dma_start(ide_drive_t *drive)
+{
+	struct request *rq = drive->hwif->hwgroup->rq;
+	int writing = rq_data_dir(rq);
+	int type = TYPE_DMA;
+
+	if (drive->current_speed >= XFER_UDMA_0)
+		type = TYPE_UDMA;
+
+	cris_ide_start_dma(drive, &ata_descrs[0], writing ? 0 : 1, type, ata_tot_size);
+
+	if (writing) {
+		LED_DISK_WRITE(1);
+	} else {
+		LED_DISK_READ(1);
+	}
+}
diff --git a/drivers/ide/cris/ide-v10.c b/drivers/ide/cris/ide-v10.c
deleted file mode 100644
--- a/drivers/ide/cris/ide-v10.c
+++ /dev/null
@@ -1,842 +0,0 @@
-/* $Id: ide.c,v 1.4 2004/10/12 07:55:48 starvik Exp $
- *
- * Etrax specific IDE functions, like init and PIO-mode setting etc.
- * Almost the entire ide.c is used for the rest of the Etrax ATA driver.
- * Copyright (c) 2000-2004 Axis Communications AB
- *
- * Authors:    Bjorn Wesen        (initial version)
- *             Mikael Starvik     (pio setup stuff, Linux 2.6 port)
- */
-
-/* Regarding DMA:
- *
- * There are two forms of DMA - "DMA handshaking" between the interface and the drive,
- * and DMA between the memory and the interface. We can ALWAYS use the latter, since it's
- * something built-in in the Etrax. However only some drives support the DMA-mode handshaking
- * on the ATA-bus. The normal PC driver and Triton interface disables memory-if DMA when the
- * device can't do DMA handshaking for some stupid reason. We don't need to do that.
- */
-
-#undef REALLY_SLOW_IO           /* most systems can safely undef this */
-
-#include <linux/config.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/timer.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/blkdev.h>
-#include <linux/hdreg.h>
-#include <linux/ide.h>
-#include <linux/init.h>
-#include <linux/scatterlist.h>
-
-#include <asm/io.h>
-#include <asm/arch/svinto.h>
-#include <asm/dma.h>
-
-/* number of Etrax DMA descriptors */
-#define MAX_DMA_DESCRS 64
-
-/* number of times to retry busy-flags when reading/writing IDE-registers
- * this can't be too high because a hung harddisk might cause the watchdog
- * to trigger (sometimes INB and OUTB are called with irq's disabled)
- */
-
-#define IDE_REGISTER_TIMEOUT 300
-
-static int e100_read_command = 0;
-
-#define LOWDB(x)
-#define D(x)
-
-static int e100_ide_build_dmatable (ide_drive_t *drive);
-static ide_startstop_t etrax_dma_intr (ide_drive_t *drive);
-
-void
-etrax100_ide_outw(unsigned short data, unsigned long reg) {
-	int timeleft;
-	LOWDB(printk("ow: data 0x%x, reg 0x%x\n", data, reg));
-
-	/* note the lack of handling any timeouts. we stop waiting, but we don't
-	 * really notify anybody.
-	 */
-
-	timeleft = IDE_REGISTER_TIMEOUT;
-	/* wait for busy flag */
-	while(timeleft && (*R_ATA_STATUS_DATA & IO_MASK(R_ATA_STATUS_DATA, busy)))
-		timeleft--;
-
-	/*
-	 * Fall through at a timeout, so the ongoing command will be
-	 * aborted by the write below, which is expected to be a dummy
-	 * command to the command register.  This happens when a faulty
-	 * drive times out on a command.  See comment on timeout in
-	 * INB.
-	 */
-	if(!timeleft)
-		printk("ATA timeout reg 0x%lx := 0x%x\n", reg, data);
-
-	*R_ATA_CTRL_DATA = reg | data; /* write data to the drive's register */
-
-	timeleft = IDE_REGISTER_TIMEOUT;
-	/* wait for transmitter ready */
-	while(timeleft && !(*R_ATA_STATUS_DATA &
-			    IO_MASK(R_ATA_STATUS_DATA, tr_rdy)))
-		timeleft--;
-}
-
-void
-etrax100_ide_outb(unsigned char data, unsigned long reg)
-{
-	etrax100_ide_outw(data, reg);
-}
-
-void
-etrax100_ide_outbsync(ide_drive_t *drive, u8 addr, unsigned long port)
-{
-	etrax100_ide_outw(addr, port);
-}
-
-unsigned short
-etrax100_ide_inw(unsigned long reg) {
-	int status;
-	int timeleft;
-
-	timeleft = IDE_REGISTER_TIMEOUT;
-	/* wait for busy flag */
-	while(timeleft && (*R_ATA_STATUS_DATA & IO_MASK(R_ATA_STATUS_DATA, busy)))
-		timeleft--;
-
-	if(!timeleft) {
-		/*
-		 * If we're asked to read the status register, like for
-		 * example when a command does not complete for an
-		 * extended time, but the ATA interface is stuck in a
-		 * busy state at the *ETRAX* ATA interface level (as has
-		 * happened repeatedly with at least one bad disk), then
-		 * the best thing to do is to pretend that we read
-		 * "busy" in the status register, so the IDE driver will
-		 * time-out, abort the ongoing command and perform a
-		 * reset sequence.  Note that the subsequent OUT_BYTE
-		 * call will also timeout on busy, but as long as the
-		 * write is still performed, everything will be fine.
-		 */
-		if ((reg & IO_MASK (R_ATA_CTRL_DATA, addr))
-		    == IO_FIELD (R_ATA_CTRL_DATA, addr, IDE_STATUS_OFFSET))
-			return BUSY_STAT;
-		else
-			/* For other rare cases we assume 0 is good enough.  */
-			return 0;
-	}
-
-	*R_ATA_CTRL_DATA = reg | IO_STATE(R_ATA_CTRL_DATA, rw, read); /* read data */
-
-	timeleft = IDE_REGISTER_TIMEOUT;
-	/* wait for available */
-	while(timeleft && !((status = *R_ATA_STATUS_DATA) &
-			    IO_MASK(R_ATA_STATUS_DATA, dav)))
-		timeleft--;
-
-	if(!timeleft)
-		return 0;
-
-	LOWDB(printk("inb: 0x%x from reg 0x%x\n", status & 0xff, reg));
-
-        return (unsigned short)status;
-}
-
-unsigned char
-etrax100_ide_inb(unsigned long reg)
-{
-	return (unsigned char)etrax100_ide_inw(reg);
-}
-
-/* PIO timing (in R_ATA_CONFIG)
- *
- *                        _____________________________
- * ADDRESS :     ________/
- *
- *                            _______________
- * DIOR    :     ____________/               \__________
- *
- *                               _______________
- * DATA    :     XXXXXXXXXXXXXXXX_______________XXXXXXXX
- *
- *
- * DIOR is unbuffered while address and data is buffered.
- * This creates two problems:
- * 1. The DIOR pulse is to early (because it is unbuffered)
- * 2. The rise time of DIOR is long
- *
- * There are at least three different plausible solutions
- * 1. Use a pad capable of larger currents in Etrax
- * 2. Use an external buffer
- * 3. Make the strobe pulse longer
- *
- * Some of the strobe timings below are modified to compensate
- * for this. This implies a slight performance decrease.
- *
- * THIS SHOULD NEVER BE CHANGED!
- *
- * TODO: Is this true for the latest LX boards still ?
- */
-
-#define ATA_DMA2_STROBE  4
-#define ATA_DMA2_HOLD    0
-#define ATA_DMA1_STROBE  4
-#define ATA_DMA1_HOLD    1
-#define ATA_DMA0_STROBE 12
-#define ATA_DMA0_HOLD    9
-#define ATA_PIO4_SETUP   1
-#define ATA_PIO4_STROBE  5
-#define ATA_PIO4_HOLD    0
-#define ATA_PIO3_SETUP   1
-#define ATA_PIO3_STROBE  5
-#define ATA_PIO3_HOLD    1
-#define ATA_PIO2_SETUP   1
-#define ATA_PIO2_STROBE  6
-#define ATA_PIO2_HOLD    2
-#define ATA_PIO1_SETUP   2
-#define ATA_PIO1_STROBE 11
-#define ATA_PIO1_HOLD    4
-#define ATA_PIO0_SETUP   4
-#define ATA_PIO0_STROBE 19
-#define ATA_PIO0_HOLD    4
-
-static int e100_dma_check (ide_drive_t *drive);
-static void e100_dma_start(ide_drive_t *drive);
-static int e100_dma_end (ide_drive_t *drive);
-static void e100_ide_input_data (ide_drive_t *drive, void *, unsigned int);
-static void e100_ide_output_data (ide_drive_t *drive, void *, unsigned int);
-static void e100_atapi_input_bytes(ide_drive_t *drive, void *, unsigned int);
-static void e100_atapi_output_bytes(ide_drive_t *drive, void *, unsigned int);
-static int e100_dma_off (ide_drive_t *drive);
-
-
-/*
- * good_dma_drives() lists the model names (from "hdparm -i")
- * of drives which do not support mword2 DMA but which are
- * known to work fine with this interface under Linux.
- */
-
-const char *good_dma_drives[] = {"Micropolis 2112A",
-				 "CONNER CTMA 4000",
-				 "CONNER CTT8000-A",
-				 NULL};
-
-static void tune_e100_ide(ide_drive_t *drive, byte pio)
-{
-	pio = 4;
-	/* pio = ide_get_best_pio_mode(drive, pio, 4, NULL); */
-
-	/* set pio mode! */
-
-	switch(pio) {
-		case 0:
-			*R_ATA_CONFIG = ( IO_FIELD( R_ATA_CONFIG, enable,     1 ) |
-					  IO_FIELD( R_ATA_CONFIG, dma_strobe, ATA_DMA2_STROBE ) |
-					  IO_FIELD( R_ATA_CONFIG, dma_hold,   ATA_DMA2_HOLD ) |
-					  IO_FIELD( R_ATA_CONFIG, pio_setup,  ATA_PIO0_SETUP ) |
-					  IO_FIELD( R_ATA_CONFIG, pio_strobe, ATA_PIO0_STROBE ) |
-					  IO_FIELD( R_ATA_CONFIG, pio_hold,   ATA_PIO0_HOLD ) );
-			break;
-		case 1:
-			*R_ATA_CONFIG = ( IO_FIELD( R_ATA_CONFIG, enable,     1 ) |
-					  IO_FIELD( R_ATA_CONFIG, dma_strobe, ATA_DMA2_STROBE ) |
-					  IO_FIELD( R_ATA_CONFIG, dma_hold,   ATA_DMA2_HOLD ) |
-					  IO_FIELD( R_ATA_CONFIG, pio_setup,  ATA_PIO1_SETUP ) |
-					  IO_FIELD( R_ATA_CONFIG, pio_strobe, ATA_PIO1_STROBE ) |
-					  IO_FIELD( R_ATA_CONFIG, pio_hold,   ATA_PIO1_HOLD ) );
-			break;
-		case 2:
-			*R_ATA_CONFIG = ( IO_FIELD( R_ATA_CONFIG, enable,     1 ) |
-					  IO_FIELD( R_ATA_CONFIG, dma_strobe, ATA_DMA2_STROBE ) |
-					  IO_FIELD( R_ATA_CONFIG, dma_hold,   ATA_DMA2_HOLD ) |
-					  IO_FIELD( R_ATA_CONFIG, pio_setup,  ATA_PIO2_SETUP ) |
-					  IO_FIELD( R_ATA_CONFIG, pio_strobe, ATA_PIO2_STROBE ) |
-					  IO_FIELD( R_ATA_CONFIG, pio_hold,   ATA_PIO2_HOLD ) );
-			break;
-		case 3:
-			*R_ATA_CONFIG = ( IO_FIELD( R_ATA_CONFIG, enable,     1 ) |
-					  IO_FIELD( R_ATA_CONFIG, dma_strobe, ATA_DMA2_STROBE ) |
-					  IO_FIELD( R_ATA_CONFIG, dma_hold,   ATA_DMA2_HOLD ) |
-					  IO_FIELD( R_ATA_CONFIG, pio_setup,  ATA_PIO3_SETUP ) |
-					  IO_FIELD( R_ATA_CONFIG, pio_strobe, ATA_PIO3_STROBE ) |
-					  IO_FIELD( R_ATA_CONFIG, pio_hold,   ATA_PIO3_HOLD ) );
-			break;
-		case 4:
-			*R_ATA_CONFIG = ( IO_FIELD( R_ATA_CONFIG, enable,     1 ) |
-					  IO_FIELD( R_ATA_CONFIG, dma_strobe, ATA_DMA2_STROBE ) |
-					  IO_FIELD( R_ATA_CONFIG, dma_hold,   ATA_DMA2_HOLD ) |
-					  IO_FIELD( R_ATA_CONFIG, pio_setup,  ATA_PIO4_SETUP ) |
-					  IO_FIELD( R_ATA_CONFIG, pio_strobe, ATA_PIO4_STROBE ) |
-					  IO_FIELD( R_ATA_CONFIG, pio_hold,   ATA_PIO4_HOLD ) );
-			break;
-	}
-}
-
-static int e100_dma_setup(ide_drive_t *drive)
-{
-	struct request *rq = drive->hwif->hwgroup->rq;
-
-	if (rq_data_dir(rq)) {
-		e100_read_command = 0;
-
-		RESET_DMA(ATA_TX_DMA_NBR); /* sometimes the DMA channel get stuck so we need to do this */
-		WAIT_DMA(ATA_TX_DMA_NBR);
-	} else {
-		e100_read_command = 1;
-
-		RESET_DMA(ATA_RX_DMA_NBR); /* sometimes the DMA channel get stuck so we need to do this */
-		WAIT_DMA(ATA_RX_DMA_NBR);
-	}
-
-	/* set up the Etrax DMA descriptors */
-	if (e100_ide_build_dmatable(drive)) {
-		ide_map_sg(drive, rq);
-		return 1;
-	}
-
-	return 0;
-}
-
-static void e100_dma_exec_cmd(ide_drive_t *drive, u8 command)
-{
-	/* set the irq handler which will finish the request when DMA is done */
-	ide_set_handler(drive, &etrax_dma_intr, WAIT_CMD, NULL);
-
-	/* issue cmd to drive */
-	etrax100_ide_outb(command, IDE_COMMAND_REG);
-}
-
-void __init
-init_e100_ide (void)
-{
-	volatile unsigned int dummy;
-	int h;
-
-	printk("ide: ETRAX 100LX built-in ATA DMA controller\n");
-
-	/* first fill in some stuff in the ide_hwifs fields */
-
-	for(h = 0; h < MAX_HWIFS; h++) {
-		ide_hwif_t *hwif = &ide_hwifs[h];
-		hwif->mmio = 2;
-		hwif->chipset = ide_etrax100;
-		hwif->tuneproc = &tune_e100_ide;
-                hwif->ata_input_data = &e100_ide_input_data;
-                hwif->ata_output_data = &e100_ide_output_data;
-                hwif->atapi_input_bytes = &e100_atapi_input_bytes;
-                hwif->atapi_output_bytes = &e100_atapi_output_bytes;
-                hwif->ide_dma_check = &e100_dma_check;
-                hwif->ide_dma_end = &e100_dma_end;
-		hwif->dma_setup = &e100_dma_setup;
-		hwif->dma_exec_cmd = &e100_dma_exec_cmd;
-		hwif->dma_start = &e100_dma_start;
-		hwif->OUTB = &etrax100_ide_outb;
-		hwif->OUTW = &etrax100_ide_outw;
-		hwif->OUTBSYNC = &etrax100_ide_outbsync;
-		hwif->INB = &etrax100_ide_inb;
-		hwif->INW = &etrax100_ide_inw;
-		hwif->ide_dma_off_quietly = &e100_dma_off;
-	}
-
-	/* actually reset and configure the etrax100 ide/ata interface */
-
-	*R_ATA_CTRL_DATA = 0;
-	*R_ATA_TRANSFER_CNT = 0;
-	*R_ATA_CONFIG = 0;
-
-	genconfig_shadow = (genconfig_shadow &
-			    ~IO_MASK(R_GEN_CONFIG, dma2) &
-			    ~IO_MASK(R_GEN_CONFIG, dma3) &
-			    ~IO_MASK(R_GEN_CONFIG, ata)) |
-		( IO_STATE( R_GEN_CONFIG, dma3, ata    ) |
-		  IO_STATE( R_GEN_CONFIG, dma2, ata    ) |
-		  IO_STATE( R_GEN_CONFIG, ata,  select ) );
-
-	*R_GEN_CONFIG = genconfig_shadow;
-
-        /* pull the chosen /reset-line low */
-
-#ifdef CONFIG_ETRAX_IDE_G27_RESET
-        REG_SHADOW_SET(R_PORT_G_DATA, port_g_data_shadow, 27, 0);
-#endif
-#ifdef CONFIG_ETRAX_IDE_CSE1_16_RESET
-        REG_SHADOW_SET(port_cse1_addr, port_cse1_shadow, 16, 0);
-#endif
-#ifdef CONFIG_ETRAX_IDE_CSP0_8_RESET
-        REG_SHADOW_SET(port_csp0_addr, port_csp0_shadow, 8, 0);
-#endif
-#ifdef CONFIG_ETRAX_IDE_PB7_RESET
-	port_pb_dir_shadow = port_pb_dir_shadow |
-		IO_STATE(R_PORT_PB_DIR, dir7, output);
-	*R_PORT_PB_DIR = port_pb_dir_shadow;
-	REG_SHADOW_SET(R_PORT_PB_DATA, port_pb_data_shadow, 7, 1);
-#endif
-
-	/* wait some */
-
-	udelay(25);
-
-	/* de-assert bus-reset */
-
-#ifdef CONFIG_ETRAX_IDE_CSE1_16_RESET
-	REG_SHADOW_SET(port_cse1_addr, port_cse1_shadow, 16, 1);
-#endif
-#ifdef CONFIG_ETRAX_IDE_CSP0_8_RESET
-	REG_SHADOW_SET(port_csp0_addr, port_csp0_shadow, 8, 1);
-#endif
-#ifdef CONFIG_ETRAX_IDE_G27_RESET
-	REG_SHADOW_SET(R_PORT_G_DATA, port_g_data_shadow, 27, 1);
-#endif
-
-	/* make a dummy read to set the ata controller in a proper state */
-	dummy = *R_ATA_STATUS_DATA;
-
-	*R_ATA_CONFIG = ( IO_FIELD( R_ATA_CONFIG, enable,     1 ) |
-			  IO_FIELD( R_ATA_CONFIG, dma_strobe, ATA_DMA2_STROBE ) |
-			  IO_FIELD( R_ATA_CONFIG, dma_hold,   ATA_DMA2_HOLD ) |
-			  IO_FIELD( R_ATA_CONFIG, pio_setup,  ATA_PIO4_SETUP ) |
-			  IO_FIELD( R_ATA_CONFIG, pio_strobe, ATA_PIO4_STROBE ) |
-			  IO_FIELD( R_ATA_CONFIG, pio_hold,   ATA_PIO4_HOLD ) );
-
-	*R_ATA_CTRL_DATA = ( IO_STATE( R_ATA_CTRL_DATA, rw,   read) |
-			     IO_FIELD( R_ATA_CTRL_DATA, addr, 1   ) );
-
-	while(*R_ATA_STATUS_DATA & IO_MASK(R_ATA_STATUS_DATA, busy)); /* wait for busy flag*/
-
-	*R_IRQ_MASK0_SET = ( IO_STATE( R_IRQ_MASK0_SET, ata_irq0, set ) |
-			     IO_STATE( R_IRQ_MASK0_SET, ata_irq1, set ) |
-			     IO_STATE( R_IRQ_MASK0_SET, ata_irq2, set ) |
-			     IO_STATE( R_IRQ_MASK0_SET, ata_irq3, set ) );
-
-	printk("ide: waiting %d seconds for drives to regain consciousness\n",
-	       CONFIG_ETRAX_IDE_DELAY);
-
-	h = jiffies + (CONFIG_ETRAX_IDE_DELAY * HZ);
-	while(time_before(jiffies, h)) /* nothing */ ;
-
-	/* reset the dma channels we will use */
-
-	RESET_DMA(ATA_TX_DMA_NBR);
-	RESET_DMA(ATA_RX_DMA_NBR);
-	WAIT_DMA(ATA_TX_DMA_NBR);
-	WAIT_DMA(ATA_RX_DMA_NBR);
-
-}
-
-static int e100_dma_off (ide_drive_t *drive)
-{
-	return 0;
-}
-
-static etrax_dma_descr mydescr;
-
-/*
- * 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.
- */
-static void
-e100_atapi_input_bytes (ide_drive_t *drive, void *buffer, unsigned int bytecount)
-{
-	unsigned long data_reg = IDE_DATA_REG;
-
-	D(printk("atapi_input_bytes, dreg 0x%x, buffer 0x%x, count %d\n",
-		 data_reg, buffer, bytecount));
-
-	if(bytecount & 1) {
-		printk("warning, odd bytecount in cdrom_in_bytes = %d.\n", bytecount);
-		bytecount++; /* to round off */
-	}
-
-	/* make sure the DMA channel is available */
-	RESET_DMA(ATA_RX_DMA_NBR);
-	WAIT_DMA(ATA_RX_DMA_NBR);
-
-	/* setup DMA descriptor */
-
-	mydescr.sw_len = bytecount;
-	mydescr.ctrl   = d_eol;
-	mydescr.buf    = virt_to_phys(buffer);
-
-	/* start the dma channel */
-
-	*R_DMA_CH3_FIRST = virt_to_phys(&mydescr);
-	*R_DMA_CH3_CMD   = IO_STATE(R_DMA_CH3_CMD, cmd, start);
-
-	/* initiate a multi word dma read using PIO handshaking */
-
-	*R_ATA_TRANSFER_CNT = IO_FIELD(R_ATA_TRANSFER_CNT, count, bytecount >> 1);
-
-	*R_ATA_CTRL_DATA = data_reg |
-		IO_STATE(R_ATA_CTRL_DATA, rw,       read) |
-		IO_STATE(R_ATA_CTRL_DATA, src_dst,  dma) |
-		IO_STATE(R_ATA_CTRL_DATA, handsh,   pio) |
-		IO_STATE(R_ATA_CTRL_DATA, multi,    on) |
-		IO_STATE(R_ATA_CTRL_DATA, dma_size, word);
-
-	/* wait for completion */
-
-	LED_DISK_READ(1);
-	WAIT_DMA(ATA_RX_DMA_NBR);
-	LED_DISK_READ(0);
-
-#if 0
-        /* old polled transfer code
-	 * this should be moved into a new function that can do polled
-	 * transfers if DMA is not available
-	 */
-
-        /* initiate a multi word read */
-
-        *R_ATA_TRANSFER_CNT = wcount << 1;
-
-        *R_ATA_CTRL_DATA = data_reg |
-                IO_STATE(R_ATA_CTRL_DATA, rw,       read) |
-                IO_STATE(R_ATA_CTRL_DATA, src_dst,  register) |
-                IO_STATE(R_ATA_CTRL_DATA, handsh,   pio) |
-                IO_STATE(R_ATA_CTRL_DATA, multi,    on) |
-                IO_STATE(R_ATA_CTRL_DATA, dma_size, word);
-
-        /* svinto has a latency until the busy bit actually is set */
-
-        nop(); nop();
-        nop(); nop();
-        nop(); nop();
-        nop(); nop();
-        nop(); nop();
-
-        /* unit should be busy during multi transfer */
-        while((status = *R_ATA_STATUS_DATA) & IO_MASK(R_ATA_STATUS_DATA, busy)) {
-                while(!(status & IO_MASK(R_ATA_STATUS_DATA, dav)))
-                        status = *R_ATA_STATUS_DATA;
-                *ptr++ = (unsigned short)(status & 0xffff);
-        }
-#endif
-}
-
-static void
-e100_atapi_output_bytes (ide_drive_t *drive, void *buffer, unsigned int bytecount)
-{
-	unsigned long data_reg = IDE_DATA_REG;
-
-	D(printk("atapi_output_bytes, dreg 0x%x, buffer 0x%x, count %d\n",
-		 data_reg, buffer, bytecount));
-
-	if(bytecount & 1) {
-		printk("odd bytecount %d in atapi_out_bytes!\n", bytecount);
-		bytecount++;
-	}
-
-	/* make sure the DMA channel is available */
-	RESET_DMA(ATA_TX_DMA_NBR);
-	WAIT_DMA(ATA_TX_DMA_NBR);
-
-	/* setup DMA descriptor */
-
-	mydescr.sw_len = bytecount;
-	mydescr.ctrl   = d_eol;
-	mydescr.buf    = virt_to_phys(buffer);
-
-	/* start the dma channel */
-
-	*R_DMA_CH2_FIRST = virt_to_phys(&mydescr);
-	*R_DMA_CH2_CMD   = IO_STATE(R_DMA_CH2_CMD, cmd, start);
-
-	/* initiate a multi word dma write using PIO handshaking */
-
-	*R_ATA_TRANSFER_CNT = IO_FIELD(R_ATA_TRANSFER_CNT, count, bytecount >> 1);
-
-	*R_ATA_CTRL_DATA = data_reg |
-		IO_STATE(R_ATA_CTRL_DATA, rw,       write) |
-		IO_STATE(R_ATA_CTRL_DATA, src_dst,  dma) |
-		IO_STATE(R_ATA_CTRL_DATA, handsh,   pio) |
-		IO_STATE(R_ATA_CTRL_DATA, multi,    on) |
-		IO_STATE(R_ATA_CTRL_DATA, dma_size, word);
-
-	/* wait for completion */
-
-	LED_DISK_WRITE(1);
-	WAIT_DMA(ATA_TX_DMA_NBR);
-	LED_DISK_WRITE(0);
-
-#if 0
-        /* old polled write code - see comment in input_bytes */
-
-	/* wait for busy flag */
-        while(*R_ATA_STATUS_DATA & IO_MASK(R_ATA_STATUS_DATA, busy));
-
-        /* initiate a multi word write */
-
-        *R_ATA_TRANSFER_CNT = bytecount >> 1;
-
-        ctrl = data_reg |
-                IO_STATE(R_ATA_CTRL_DATA, rw,       write) |
-                IO_STATE(R_ATA_CTRL_DATA, src_dst,  register) |
-                IO_STATE(R_ATA_CTRL_DATA, handsh,   pio) |
-                IO_STATE(R_ATA_CTRL_DATA, multi,    on) |
-                IO_STATE(R_ATA_CTRL_DATA, dma_size, word);
-
-        LED_DISK_WRITE(1);
-
-        /* Etrax will set busy = 1 until the multi pio transfer has finished
-         * and tr_rdy = 1 after each successful word transfer.
-         * When the last byte has been transferred Etrax will first set tr_tdy = 1
-         * and then busy = 0 (not in the same cycle). If we read busy before it
-         * has been set to 0 we will think that we should transfer more bytes
-         * and then tr_rdy would be 0 forever. This is solved by checking busy
-         * in the inner loop.
-         */
-
-        do {
-                *R_ATA_CTRL_DATA = ctrl | *ptr++;
-                while(!(*R_ATA_STATUS_DATA & IO_MASK(R_ATA_STATUS_DATA, tr_rdy)) &&
-                      (*R_ATA_STATUS_DATA & IO_MASK(R_ATA_STATUS_DATA, busy)));
-        } while(*R_ATA_STATUS_DATA & IO_MASK(R_ATA_STATUS_DATA, busy));
-
-        LED_DISK_WRITE(0);
-#endif
-
-}
-
-/*
- * This is used for most PIO data transfers *from* the IDE interface
- */
-static void
-e100_ide_input_data (ide_drive_t *drive, void *buffer, unsigned int wcount)
-{
-	e100_atapi_input_bytes(drive, buffer, wcount << 2);
-}
-
-/*
- * This is used for most PIO data transfers *to* the IDE interface
- */
-static void
-e100_ide_output_data (ide_drive_t *drive, void *buffer, unsigned int wcount)
-{
-	e100_atapi_output_bytes(drive, buffer, wcount << 2);
-}
-
-/* we only have one DMA channel on the chip for ATA, so we can keep these statically */
-static etrax_dma_descr ata_descrs[MAX_DMA_DESCRS];
-static unsigned int ata_tot_size;
-
-/*
- * e100_ide_build_dmatable() prepares a dma request.
- * Returns 0 if all went okay, returns 1 otherwise.
- */
-static int e100_ide_build_dmatable (ide_drive_t *drive)
-{
-	ide_hwif_t *hwif = HWIF(drive);
-	struct scatterlist* sg;
-	struct request *rq  = HWGROUP(drive)->rq;
-	unsigned long size, addr;
-	unsigned int count = 0;
-	int i = 0;
-
-	sg = hwif->sg_table;
-
-	ata_tot_size = 0;
-
-	ide_map_sg(drive, rq);
-
-	i = hwif->sg_nents;
-
-	while(i) {
-		/*
-		 * Determine addr and size of next buffer area.  We assume that
-		 * individual virtual buffers are always composed linearly in
-		 * physical memory.  For example, we assume that any 8kB buffer
-		 * is always composed of two adjacent physical 4kB pages rather
-		 * than two possibly non-adjacent physical 4kB pages.
-		 */
-		/* group sequential buffers into one large buffer */
-		addr = page_to_phys(sg->page) + sg->offset;
-		size = sg_dma_len(sg);
-		while (sg++, --i) {
-			if ((addr + size) != page_to_phys(sg->page) + sg->offset)
-				break;
-			size += sg_dma_len(sg);
-		}
-
-		/* did we run out of descriptors? */
-
-		if(count >= MAX_DMA_DESCRS) {
-			printk("%s: too few DMA descriptors\n", drive->name);
-			return 1;
-		}
-
-		/* however, this case is more difficult - R_ATA_TRANSFER_CNT cannot be more
-		   than 65536 words per transfer, so in that case we need to either
-		   1) use a DMA interrupt to re-trigger R_ATA_TRANSFER_CNT and continue with
-		      the descriptors, or
-		   2) simply do the request here, and get dma_intr to only ide_end_request on
-		      those blocks that were actually set-up for transfer.
-		*/
-
-		if(ata_tot_size + size > 131072) {
-			printk("too large total ATA DMA request, %d + %d!\n", ata_tot_size, (int)size);
-			return 1;
-		}
-
-		/* If size > 65536 it has to be splitted into new descriptors. Since we don't handle
-                   size > 131072 only one split is necessary */
-
-		if(size > 65536) {
- 		        /* ok we want to do IO at addr, size bytes. set up a new descriptor entry */
-                        ata_descrs[count].sw_len = 0;  /* 0 means 65536, this is a 16-bit field */
-                        ata_descrs[count].ctrl = 0;
-                        ata_descrs[count].buf = addr;
-                        ata_descrs[count].next = virt_to_phys(&ata_descrs[count + 1]);
-                        count++;
-                        ata_tot_size += 65536;
-                        /* size and addr should refere to not handled data */
-                        size -= 65536;
-                        addr += 65536;
-                }
-		/* ok we want to do IO at addr, size bytes. set up a new descriptor entry */
-                if(size == 65536) {
-			ata_descrs[count].sw_len = 0;  /* 0 means 65536, this is a 16-bit field */
-                } else {
-			ata_descrs[count].sw_len = size;
-                }
-		ata_descrs[count].ctrl = 0;
-		ata_descrs[count].buf = addr;
-		ata_descrs[count].next = virt_to_phys(&ata_descrs[count + 1]);
-		count++;
-		ata_tot_size += size;
-	}
-
-	if (count) {
-		/* set the end-of-list flag on the last descriptor */
-		ata_descrs[count - 1].ctrl |= d_eol;
-		/* return and say all is ok */
-		return 0;
-	}
-
-	printk("%s: empty DMA table?\n", drive->name);
-	return 1;	/* let the PIO routines handle this weirdness */
-}
-
-static int config_drive_for_dma (ide_drive_t *drive)
-{
-        const char **list;
-        struct hd_driveid *id = drive->id;
-
-        if (id && (id->capability & 1)) {
-                /* Enable DMA on any drive that supports mword2 DMA */
-                if ((id->field_valid & 2) && (id->dma_mword & 0x404) == 0x404) {
-                        drive->using_dma = 1;
-                        return 0;               /* DMA enabled */
-                }
-
-                /* Consult the list of known "good" drives */
-                list = good_dma_drives;
-                while (*list) {
-                        if (!strcmp(*list++,id->model)) {
-                                drive->using_dma = 1;
-                                return 0;       /* DMA enabled */
-                        }
-                }
-        }
-        return 1;       /* DMA not enabled */
-}
-
-/*
- * etrax_dma_intr() is the handler for disk read/write DMA interrupts
- */
-static ide_startstop_t etrax_dma_intr (ide_drive_t *drive)
-{
-	LED_DISK_READ(0);
-	LED_DISK_WRITE(0);
-
-	return ide_dma_intr(drive);
-}
-
-/*
- * Functions below initiates/aborts DMA read/write operations on a drive.
- *
- * The caller is assumed to have selected the drive and programmed the drive's
- * sector address using CHS or LBA.  All that remains is to prepare for DMA
- * and then issue the actual read/write DMA/PIO command to the drive.
- *
- * Returns 0 if all went well.
- * Returns 1 if DMA read/write could not be started, in which case
- * the caller should revert to PIO for the current request.
- */
-
-static int e100_dma_check(ide_drive_t *drive)
-{
-	return config_drive_for_dma (drive);
-}
-
-static int e100_dma_end(ide_drive_t *drive)
-{
-	/* TODO: check if something went wrong with the DMA */
-	return 0;
-}
-
-static void e100_dma_start(ide_drive_t *drive)
-{
-	if (e100_read_command) {
-		/* begin DMA */
-
-		/* need to do this before RX DMA due to a chip bug
-		 * it is enough to just flush the part of the cache that
-		 * corresponds to the buffers we start, but since HD transfers
-		 * usually are more than 8 kB, it is easier to optimize for the
-		 * normal case and just flush the entire cache. its the only
-		 * way to be sure! (OB movie quote)
-		 */
-		flush_etrax_cache();
-		*R_DMA_CH3_FIRST = virt_to_phys(ata_descrs);
-		*R_DMA_CH3_CMD   = IO_STATE(R_DMA_CH3_CMD, cmd, start);
-
-		/* initiate a multi word dma read using DMA handshaking */
-
-		*R_ATA_TRANSFER_CNT =
-			IO_FIELD(R_ATA_TRANSFER_CNT, count, ata_tot_size >> 1);
-
-		*R_ATA_CTRL_DATA =
-			IO_FIELD(R_ATA_CTRL_DATA, data, IDE_DATA_REG) |
-			IO_STATE(R_ATA_CTRL_DATA, rw,       read) |
-			IO_STATE(R_ATA_CTRL_DATA, src_dst,  dma)  |
-			IO_STATE(R_ATA_CTRL_DATA, handsh,   dma)  |
-			IO_STATE(R_ATA_CTRL_DATA, multi,    on)   |
-			IO_STATE(R_ATA_CTRL_DATA, dma_size, word);
-
-		LED_DISK_READ(1);
-
-		D(printk("dma read of %d bytes.\n", ata_tot_size));
-
-	} else {
-		/* writing */
-		/* begin DMA */
-
-		*R_DMA_CH2_FIRST = virt_to_phys(ata_descrs);
-		*R_DMA_CH2_CMD   = IO_STATE(R_DMA_CH2_CMD, cmd, start);
-
-		/* initiate a multi word dma write using DMA handshaking */
-
-		*R_ATA_TRANSFER_CNT =
-			IO_FIELD(R_ATA_TRANSFER_CNT, count, ata_tot_size >> 1);
-
-		*R_ATA_CTRL_DATA =
-			IO_FIELD(R_ATA_CTRL_DATA, data,     IDE_DATA_REG) |
-			IO_STATE(R_ATA_CTRL_DATA, rw,       write) |
-			IO_STATE(R_ATA_CTRL_DATA, src_dst,  dma) |
-			IO_STATE(R_ATA_CTRL_DATA, handsh,   dma) |
-			IO_STATE(R_ATA_CTRL_DATA, multi,    on) |
-			IO_STATE(R_ATA_CTRL_DATA, dma_size, word);
-
-		LED_DISK_WRITE(1);
-
-		D(printk("dma write of %d bytes.\n", ata_tot_size));
-	}
-}
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -431,7 +431,7 @@ void cdrom_analyze_sense_data(ide_drive_
 #if VERBOSE_IDE_CD_ERRORS
 	{
 		int i;
-		const char *s;
+		const char *s = "bad sense key!";
 		char buf[80];
 
 		printk ("ATAPI device %s:\n", drive->name);
@@ -446,8 +446,6 @@ void cdrom_analyze_sense_data(ide_drive_
 
 		if (sense->sense_key < ARY_LEN(sense_key_texts))
 			s = sense_key_texts[sense->sense_key];
-		else
-			s = "bad sense key!";
 
 		printk("%s -- (Sense key=0x%02x)\n", s, sense->sense_key);
 
@@ -2657,16 +2655,63 @@ int ide_cdrom_lock_door (struct cdrom_de
 }
 
 static
+int ide_cdrom_get_capabilities(ide_drive_t *drive, struct atapi_capabilities_page *cap)
+{
+	struct cdrom_info *info = drive->driver_data;
+	struct cdrom_device_info *cdi = &info->devinfo;
+	struct packet_command cgc;
+	int stat, attempts = 3, size = sizeof(*cap);
+
+	/*
+	 * ACER50 (and others?) require the full spec length mode sense
+	 * page capabilities size, but older drives break.
+	 */
+	if (!(!strcmp(drive->id->model, "ATAPI CD ROM DRIVE 50X MAX") ||
+	    !strcmp(drive->id->model, "WPI CDS-32X")))
+		size -= sizeof(cap->pad);
+
+	init_cdrom_command(&cgc, cap, size, CGC_DATA_UNKNOWN);
+	do { /* we seem to get stat=0x01,err=0x00 the first time (??) */
+		stat = cdrom_mode_sense(cdi, &cgc, GPMODE_CAPABILITIES_PAGE, 0);
+		if (!stat)
+			break;
+	} while (--attempts);
+	return stat;
+}
+
+static
+void ide_cdrom_update_speed (ide_drive_t *drive, struct atapi_capabilities_page *cap)
+{
+	/* The ACER/AOpen 24X cdrom has the speed fields byte-swapped */
+	if (!drive->id->model[0] &&
+	    !strncmp(drive->id->fw_rev, "241N", 4)) {
+		CDROM_STATE_FLAGS(drive)->current_speed  =
+			(((unsigned int)cap->curspeed) + (176/2)) / 176;
+		CDROM_CONFIG_FLAGS(drive)->max_speed =
+			(((unsigned int)cap->maxspeed) + (176/2)) / 176;
+	} else {
+		CDROM_STATE_FLAGS(drive)->current_speed  =
+			(ntohs(cap->curspeed) + (176/2)) / 176;
+		CDROM_CONFIG_FLAGS(drive)->max_speed =
+			(ntohs(cap->maxspeed) + (176/2)) / 176;
+	}
+}
+
+static
 int ide_cdrom_select_speed (struct cdrom_device_info *cdi, int speed)
 {
 	ide_drive_t *drive = (ide_drive_t*) cdi->handle;
 	struct request_sense sense;
+	struct atapi_capabilities_page cap;
 	int stat;
 
 	if ((stat = cdrom_select_speed(drive, speed, &sense)) < 0)
 		return stat;
 
-        cdi->speed = CDROM_STATE_FLAGS(drive)->current_speed;
+	if (!ide_cdrom_get_capabilities(drive, &cap)) {
+		ide_cdrom_update_speed(drive, &cap);
+		cdi->speed = CDROM_STATE_FLAGS(drive)->current_speed;
+	}
         return 0;
 }
 
@@ -2869,31 +2914,6 @@ static int ide_cdrom_register (ide_drive
 }
 
 static
-int ide_cdrom_get_capabilities(ide_drive_t *drive, struct atapi_capabilities_page *cap)
-{
-	struct cdrom_info *info = drive->driver_data;
-	struct cdrom_device_info *cdi = &info->devinfo;
-	struct packet_command cgc;
-	int stat, attempts = 3, size = sizeof(*cap);
-
-	/*
-	 * ACER50 (and others?) require the full spec length mode sense
-	 * page capabilities size, but older drives break.
-	 */
-	if (!(!strcmp(drive->id->model, "ATAPI CD ROM DRIVE 50X MAX") ||
-	    !strcmp(drive->id->model, "WPI CDS-32X")))
-		size -= sizeof(cap->pad);
-
-	init_cdrom_command(&cgc, cap, size, CGC_DATA_UNKNOWN);
-	do { /* we seem to get stat=0x01,err=0x00 the first time (??) */
-		stat = cdrom_mode_sense(cdi, &cgc, GPMODE_CAPABILITIES_PAGE, 0);
-		if (!stat)
-			break;
-	} while (--attempts);
-	return stat;
-}
-
-static
 int ide_cdrom_probe_capabilities (ide_drive_t *drive)
 {
 	struct cdrom_info *info = drive->driver_data;
@@ -2978,20 +2998,7 @@ int ide_cdrom_probe_capabilities (ide_dr
 		}
 	}
 
-	/* The ACER/AOpen 24X cdrom has the speed fields byte-swapped */
-	if (!drive->id->model[0] &&
-	    !strncmp(drive->id->fw_rev, "241N", 4)) {
-		CDROM_STATE_FLAGS(drive)->current_speed  = 
-			(((unsigned int)cap.curspeed) + (176/2)) / 176;
-		CDROM_CONFIG_FLAGS(drive)->max_speed = 
-			(((unsigned int)cap.maxspeed) + (176/2)) / 176;
-	} else {
-		CDROM_STATE_FLAGS(drive)->current_speed  = 
-			(ntohs(cap.curspeed) + (176/2)) / 176;
-		CDROM_CONFIG_FLAGS(drive)->max_speed = 
-			(ntohs(cap.maxspeed) + (176/2)) / 176;
-	}
-
+	ide_cdrom_update_speed(drive, &cap);
 	/* don't print speed if the drive reported 0.
 	 */
 	printk(KERN_INFO "%s: ATAPI", drive->name);
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -119,6 +119,10 @@ static int lba_capacity_is_ok (struct hd
 {
 	unsigned long lba_sects, chs_sects, head, tail;
 
+	/* No non-LBA info .. so valid! */
+	if (id->cyls == 0)
+		return 1;
+
 	/*
 	 * The ATA spec tells large drives to return
 	 * C/H/S = 16383/16/63 independent of their size.
@@ -1215,7 +1219,8 @@ static int ide_disk_probe(struct device 
 	if (!idkp)
 		goto failed;
 
-	g = alloc_disk(1 << PARTN_BITS);
+	g = alloc_disk_node(1 << PARTN_BITS,
+			hwif_to_node(drive->hwif));
 	if (!g)
 		goto out_free_idkp;
 
diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c
--- a/drivers/ide/ide-dma.c
+++ b/drivers/ide/ide-dma.c
@@ -132,7 +132,6 @@ static const struct drive_list_entry dri
 	{ "SAMSUNG CD-ROM SC-148C",	"ALL"		},
 	{ "SAMSUNG CD-ROM SC",	"ALL"		},
 	{ "SanDisk SDP3B-64"	,	"ALL"		},
-	{ "SAMSUNG CD-ROM SN-124",	"ALL"		},
 	{ "ATAPI CD-ROM DRIVE 40X MAXIMUM",	"ALL"		},
 	{ "_NEC DV5800A",               "ALL"           },  
 	{ NULL			,	NULL		}
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -317,7 +317,7 @@ typedef struct ide_floppy_obj {
 	unsigned long flags;
 } idefloppy_floppy_t;
 
-#define IDEFLOPPY_TICKS_DELAY	3	/* default delay for ZIP 100 */
+#define IDEFLOPPY_TICKS_DELAY	HZ/20	/* default delay for ZIP 100 (50ms) */
 
 /*
  *	Floppy flag bits values.
@@ -661,10 +661,12 @@ static void idefloppy_output_buffers (id
 
 	idefloppy_do_end_request(drive, 1, done >> 9);
 
+#if IDEFLOPPY_DEBUG_BUGS
 	if (bcount) {
 		printk(KERN_ERR "%s: leftover data in idefloppy_output_buffers, bcount == %d\n", drive->name, bcount);
 		idefloppy_write_zeros(drive, bcount);
 	}
+#endif
 }
 
 static void idefloppy_update_buffers (ide_drive_t *drive, idefloppy_pc_t *pc)
@@ -1048,6 +1050,9 @@ static ide_startstop_t idefloppy_issue_p
 	atapi_bcount_t bcount;
 	ide_handler_t *pkt_xfer_routine;
 
+#if 0 /* Accessing floppy->pc is not valid here, the previous pc may be gone
+         and have lived on another thread's stack; that stack may have become
+         unmapped meanwhile (CONFIG_DEBUG_PAGEALLOC). */
 #if IDEFLOPPY_DEBUG_BUGS
 	if (floppy->pc->c[0] == IDEFLOPPY_REQUEST_SENSE_CMD &&
 	    pc->c[0] == IDEFLOPPY_REQUEST_SENSE_CMD) {
@@ -1055,6 +1060,7 @@ static ide_startstop_t idefloppy_issue_p
 			"Two request sense in serial were issued\n");
 	}
 #endif /* IDEFLOPPY_DEBUG_BUGS */
+#endif
 
 	if (floppy->failed_pc == NULL &&
 	    pc->c[0] != IDEFLOPPY_REQUEST_SENSE_CMD)
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c
--- a/drivers/ide/ide-iops.c
+++ b/drivers/ide/ide-iops.c
@@ -1181,7 +1181,8 @@ static ide_startstop_t do_reset1 (ide_dr
 		pre_reset(drive);
 		SELECT_DRIVE(drive);
 		udelay (20);
-		hwif->OUTB(WIN_SRST, IDE_COMMAND_REG);
+		hwif->OUTBSYNC(drive, WIN_SRST, IDE_COMMAND_REG);
+		ndelay(400);
 		hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE;
 		hwgroup->polling = 1;
 		__ide_set_handler(drive, &atapi_reset_pollfunc, HZ/20, NULL);
diff --git a/drivers/ide/ide-lib.c b/drivers/ide/ide-lib.c
--- a/drivers/ide/ide-lib.c
+++ b/drivers/ide/ide-lib.c
@@ -487,8 +487,7 @@ static u8 ide_dump_ata_status(ide_drive_
 	u8 err = 0;
 
 	local_irq_set(flags);
-	printk("%s: %s: status=0x%02x", drive->name, msg, stat);
-	printk(" { ");
+	printk("%s: %s: status=0x%02x { ", drive->name, msg, stat);
 	if (stat & BUSY_STAT)
 		printk("Busy ");
 	else {
@@ -500,15 +499,13 @@ static u8 ide_dump_ata_status(ide_drive_
 		if (stat & INDEX_STAT)	printk("Index ");
 		if (stat & ERR_STAT)	printk("Error ");
 	}
-	printk("}");
-	printk("\n");
+	printk("}\n");
 	if ((stat & (BUSY_STAT|ERR_STAT)) == ERR_STAT) {
 		err = hwif->INB(IDE_ERROR_REG);
-		printk("%s: %s: error=0x%02x", drive->name, msg, err);
-		printk(" { ");
+		printk("%s: %s: error=0x%02x { ", drive->name, msg, err);
 		if (err & ABRT_ERR)	printk("DriveStatusError ");
 		if (err & ICRC_ERR)
-			printk("Bad%s ", (err & ABRT_ERR) ? "CRC" : "Sector");
+			printk((err & ABRT_ERR) ? "BadCRC " : "BadSector ");
 		if (err & ECC_ERR)	printk("UncorrectableError ");
 		if (err & ID_ERR)	printk("SectorIdNotFound ");
 		if (err & TRK0_ERR)	printk("TrackZeroNotFound ");
@@ -546,8 +543,8 @@ static u8 ide_dump_ata_status(ide_drive_
 				printk(", sector=%llu",
 					(unsigned long long)HWGROUP(drive)->rq->sector);
 		}
+		printk("\n");
 	}
-	printk("\n");
 	ide_dump_opcode(drive);
 	local_irq_restore(flags);
 	return err;
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -977,8 +977,8 @@ static int ide_init_queue(ide_drive_t *d
 	 *	limits and LBA48 we could raise it but as yet
 	 *	do not.
 	 */
-	 
-	q = blk_init_queue(do_ide_request, &ide_lock);
+
+	q = blk_init_queue_node(do_ide_request, &ide_lock, hwif_to_node(hwif));
 	if (!q)
 		return 1;
 
@@ -1047,6 +1047,8 @@ static int init_irq (ide_hwif_t *hwif)
 
 	BUG_ON(in_interrupt());
 	BUG_ON(irqs_disabled());	
+	BUG_ON(hwif == NULL);
+
 	down(&ide_cfg_sem);
 	hwif->hwgroup = NULL;
 #if MAX_HWIFS > 1
@@ -1095,7 +1097,8 @@ static int init_irq (ide_hwif_t *hwif)
 		hwgroup->hwif->next = hwif;
 		spin_unlock_irq(&ide_lock);
 	} else {
-		hwgroup = kmalloc(sizeof(ide_hwgroup_t),GFP_KERNEL);
+		hwgroup = kmalloc_node(sizeof(ide_hwgroup_t), GFP_KERNEL,
+					hwif_to_node(hwif->drives[0].hwif));
 		if (!hwgroup)
 	       		goto out_up;
 
diff --git a/drivers/ide/legacy/hd.c b/drivers/ide/legacy/hd.c
--- a/drivers/ide/legacy/hd.c
+++ b/drivers/ide/legacy/hd.c
@@ -156,11 +156,13 @@ else \
 
 
 #if (HD_DELAY > 0)
+
+#include <asm/i8253.h>
+
 unsigned long last_req;
 
 unsigned long read_timer(void)
 {
-        extern spinlock_t i8253_lock;
 	unsigned long t, flags;
 	int i;
 
diff --git a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c
--- a/drivers/ide/legacy/ide-cs.c
+++ b/drivers/ide/legacy/ide-cs.c
@@ -46,7 +46,6 @@
 #include <asm/io.h>
 #include <asm/system.h>
 
-#include <pcmcia/version.h>
 #include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
@@ -134,11 +133,6 @@ static dev_link_t *ide_attach(void)
     link->next = dev_list;
     dev_list = link;
     client_reg.dev_info = &dev_info;
-    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 = &ide_event;
     client_reg.Version = 0x0210;
     client_reg.event_callback_args.client_data = link;
     ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -457,13 +451,50 @@ int ide_event(event_t event, int priorit
     return 0;
 } /* ide_event */
 
+static struct pcmcia_device_id ide_ids[] = {
+	PCMCIA_DEVICE_FUNC_ID(4),
+	PCMCIA_DEVICE_MANF_CARD(0x0032, 0x0704),
+	PCMCIA_DEVICE_MANF_CARD(0x00a4, 0x002d),
+	PCMCIA_DEVICE_MANF_CARD(0x2080, 0x0001),
+	PCMCIA_DEVICE_MANF_CARD(0x0045, 0x0401),
+	PCMCIA_DEVICE_PROD_ID123("Caravelle", "PSC-IDE ", "PSC000", 0x8c36137c, 0xd0693ab8, 0x2768a9f0),
+	PCMCIA_DEVICE_PROD_ID123("CDROM", "IDE", "MCD-601p", 0x1b9179ca, 0xede88951, 0x0d902f74),
+	PCMCIA_DEVICE_PROD_ID123("PCMCIA", "IDE CARD", "F1", 0x281f1c5d, 0x1907960c, 0xf7fde8b9),
+	PCMCIA_DEVICE_PROD_ID12("ARGOSY", "CD-ROM", 0x78f308dc, 0x66536591),
+	PCMCIA_DEVICE_PROD_ID12("ARGOSY", "PnPIDE", 0x78f308dc, 0x0c694728),
+	PCMCIA_DEVICE_PROD_ID12("CNF CD-M", "CD-ROM", 0x7d93b852, 0x66536591),
+	PCMCIA_DEVICE_PROD_ID12("Creative Technology Ltd.", "PCMCIA CD-ROM Interface Card", 0xff8c8a45, 0xfe8020c4),
+	PCMCIA_DEVICE_PROD_ID12("Digital Equipment Corporation.", "Digital Mobile Media CD-ROM", 0x17692a66, 0xef1dcbde),
+	PCMCIA_DEVICE_PROD_ID12("EXP", "CD+GAME", 0x6f58c983, 0x63c13aaf),
+	PCMCIA_DEVICE_PROD_ID12("EXP   ", "CD-ROM", 0x0a5c52fd, 0x66536591),
+	PCMCIA_DEVICE_PROD_ID12("EXP   ", "PnPIDE", 0x0a5c52fd, 0x0c694728),
+	PCMCIA_DEVICE_PROD_ID12("FREECOM", "PCCARD-IDE", 0x5714cbf7, 0x48e0ab8e),
+	PCMCIA_DEVICE_PROD_ID12("IBM", "IBM17JSSFP20", 0xb569a6e5, 0xf2508753),
+	PCMCIA_DEVICE_PROD_ID12("IO DATA", "CBIDE2      ", 0x547e66dc, 0x8671043b),
+	PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCIDE", 0x547e66dc, 0x5c5ab149),
+	PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCIDEII", 0x547e66dc, 0xb3662674),
+	PCMCIA_DEVICE_PROD_ID12("LOOKMEET", "CBIDE2      ", 0xe37be2b5, 0x8671043b),
+	PCMCIA_DEVICE_PROD_ID12(" ", "NinjaATA-", 0x3b6e20c8, 0xebe0bd79),
+	PCMCIA_DEVICE_PROD_ID12("PCMCIA", "CD-ROM", 0x281f1c5d, 0x66536591),
+	PCMCIA_DEVICE_PROD_ID12("PCMCIA", "PnPIDE", 0x281f1c5d, 0x0c694728),
+	PCMCIA_DEVICE_PROD_ID12("SHUTTLE TECHNOLOGY LTD.", "PCCARD-IDE/ATAPI Adapter", 0x4a3f0ba0, 0x322560e1),
+	PCMCIA_DEVICE_PROD_ID12("TOSHIBA", "MK2001MPL", 0xb4585a1a, 0x3489e003),
+	PCMCIA_DEVICE_PROD_ID12("WIT", "IDE16", 0x244e5994, 0x3e232852),
+	PCMCIA_DEVICE_PROD_ID1("STI Flash", 0xe4a13209),
+	PCMCIA_MFC_DEVICE_PROD_ID12(1, "SanDisk", "ConnectPlus", 0x7a954bd9, 0x74be00c6),
+	PCMCIA_DEVICE_NULL,
+};
+MODULE_DEVICE_TABLE(pcmcia, ide_ids);
+
 static struct pcmcia_driver ide_cs_driver = {
 	.owner		= THIS_MODULE,
 	.drv		= {
 		.name	= "ide-cs",
 	},
 	.attach		= ide_attach,
+	.event		= ide_event,
 	.detach		= ide_detach,
+	.id_table       = ide_ids,
 };
 
 static int __init init_ide_cs(void)
@@ -477,5 +508,5 @@ static void __exit exit_ide_cs(void)
 	BUG_ON(dev_list != NULL);
 }
 
-module_init(init_ide_cs);
+late_initcall(init_ide_cs);
 module_exit(exit_ide_cs);
diff --git a/drivers/ide/pci/Makefile b/drivers/ide/pci/Makefile
--- a/drivers/ide/pci/Makefile
+++ b/drivers/ide/pci/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_BLK_DEV_HPT34X)		+= hpt34x.
 obj-$(CONFIG_BLK_DEV_HPT366)		+= hpt366.o
 #obj-$(CONFIG_BLK_DEV_HPT37X)		+= hpt37x.o
 obj-$(CONFIG_BLK_DEV_IT8172)		+= it8172.o
+obj-$(CONFIG_BLK_DEV_IT821X)		+= it821x.o
 obj-$(CONFIG_BLK_DEV_NS87415)		+= ns87415.o
 obj-$(CONFIG_BLK_DEV_OPTI621)		+= opti621.o
 obj-$(CONFIG_BLK_DEV_PDC202XX_OLD)	+= pdc202xx_old.o
diff --git a/drivers/ide/pci/alim15x3.c b/drivers/ide/pci/alim15x3.c
--- a/drivers/ide/pci/alim15x3.c
+++ b/drivers/ide/pci/alim15x3.c
@@ -583,7 +583,7 @@ static int ali15x3_dma_setup(ide_drive_t
  *	appropriate also sets up the 1533 southbridge.
  */
   
-static unsigned int __init init_chipset_ali15x3 (struct pci_dev *dev, const char *name)
+static unsigned int __devinit init_chipset_ali15x3 (struct pci_dev *dev, const char *name)
 {
 	unsigned long flags;
 	u8 tmpbyte;
@@ -677,7 +677,7 @@ static unsigned int __init init_chipset_
  *	FIXME: frobs bits that are not defined on newer ALi devicea
  */
 
-static unsigned int __init ata66_ali15x3 (ide_hwif_t *hwif)
+static unsigned int __devinit ata66_ali15x3 (ide_hwif_t *hwif)
 {
 	struct pci_dev *dev	= hwif->pci_dev;
 	unsigned int ata66	= 0;
@@ -748,7 +748,7 @@ static unsigned int __init ata66_ali15x3
  *	Initialize the IDE structure side of the ALi 15x3 driver.
  */
  
-static void __init init_hwif_common_ali15x3 (ide_hwif_t *hwif)
+static void __devinit init_hwif_common_ali15x3 (ide_hwif_t *hwif)
 {
 	hwif->autodma = 0;
 	hwif->tuneproc = &ali15x3_tune_drive;
@@ -794,7 +794,7 @@ static void __init init_hwif_common_ali1
  *	Sparc systems
  */
 
-static void __init init_hwif_ali15x3 (ide_hwif_t *hwif)
+static void __devinit init_hwif_ali15x3 (ide_hwif_t *hwif)
 {
 	u8 ideic, inmir;
 	s8 irq_routing_table[] = { -1,  9, 3, 10, 4,  5, 7,  6,
@@ -847,7 +847,7 @@ static void __init init_hwif_ali15x3 (id
  *	the actual work.
  */
 
-static void __init init_dma_ali15x3 (ide_hwif_t *hwif, unsigned long dmabase)
+static void __devinit init_dma_ali15x3 (ide_hwif_t *hwif, unsigned long dmabase)
 {
 	if (m5229_revision < 0x20)
 		return;
diff --git a/drivers/ide/pci/amd74xx.c b/drivers/ide/pci/amd74xx.c
--- a/drivers/ide/pci/amd74xx.c
+++ b/drivers/ide/pci/amd74xx.c
@@ -73,6 +73,7 @@ static struct amd_ide_chip {
 	{ PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_IDE,	0x50, AMD_UDMA_133 },
 	{ PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE,	0x50, AMD_UDMA_133 },
 	{ PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE,	0x50, AMD_UDMA_133 },
+	{ PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE,	0x50, AMD_UDMA_133 },
 	{ 0 }
 };
 
@@ -309,7 +310,7 @@ static int amd74xx_ide_dma_check(ide_dri
  * and initialize its drive independent registers.
  */
 
-static unsigned int __init init_chipset_amd74xx(struct pci_dev *dev, const char *name)
+static unsigned int __devinit init_chipset_amd74xx(struct pci_dev *dev, const char *name)
 {
 	unsigned char t;
 	unsigned int u;
@@ -413,7 +414,7 @@ static unsigned int __init init_chipset_
 	return dev->irq;
 }
 
-static void __init init_hwif_amd74xx(ide_hwif_t *hwif)
+static void __devinit init_hwif_amd74xx(ide_hwif_t *hwif)
 {
 	int i;
 
@@ -489,6 +490,7 @@ static ide_pci_device_t amd74xx_chipsets
 	/* 13 */ DECLARE_NV_DEV("NFORCE-CK804"),
 	/* 14 */ DECLARE_NV_DEV("NFORCE-MCP04"),
 	/* 15 */ DECLARE_NV_DEV("NFORCE-MCP51"),
+	/* 16 */ DECLARE_NV_DEV("NFORCE-MCP55"),
 };
 
 static int __devinit amd74xx_probe(struct pci_dev *dev, const struct pci_device_id *id)
@@ -524,6 +526,7 @@ static struct pci_device_id amd74xx_pci_
 	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_IDE,	PCI_ANY_ID, PCI_ANY_ID, 0, 0, 13 },
 	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE,	PCI_ANY_ID, PCI_ANY_ID, 0, 0, 14 },
 	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE,	PCI_ANY_ID, PCI_ANY_ID, 0, 0, 15 },
+	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE,	PCI_ANY_ID, PCI_ANY_ID, 0, 0, 16 },
 	{ 0, },
 };
 MODULE_DEVICE_TABLE(pci, amd74xx_pci_tbl);
diff --git a/drivers/ide/pci/cmd640.c b/drivers/ide/pci/cmd640.c
--- a/drivers/ide/pci/cmd640.c
+++ b/drivers/ide/pci/cmd640.c
@@ -487,7 +487,7 @@ static void display_clocks (unsigned int
  * Pack active and recovery counts into single byte representation
  * used by controller
  */
-inline static u8 pack_nibbles (u8 upper, u8 lower)
+static inline u8 pack_nibbles (u8 upper, u8 lower)
 {
 	return ((upper & 0x0f) << 4) | (lower & 0x0f);
 }
diff --git a/drivers/ide/pci/cs5530.c b/drivers/ide/pci/cs5530.c
--- a/drivers/ide/pci/cs5530.c
+++ b/drivers/ide/pci/cs5530.c
@@ -217,7 +217,7 @@ static int cs5530_config_dma (ide_drive_
  *	Initialize the cs5530 bridge for reliable IDE DMA operation.
  */
 
-static unsigned int __init init_chipset_cs5530 (struct pci_dev *dev, const char *name)
+static unsigned int __devinit init_chipset_cs5530 (struct pci_dev *dev, const char *name)
 {
 	struct pci_dev *master_0 = NULL, *cs5530_0 = NULL;
 	unsigned long flags;
@@ -308,7 +308,7 @@ static unsigned int __init init_chipset_
  *	performs channel-specific pre-initialization before drive probing.
  */
 
-static void __init init_hwif_cs5530 (ide_hwif_t *hwif)
+static void __devinit init_hwif_cs5530 (ide_hwif_t *hwif)
 {
 	unsigned long basereg;
 	u32 d0_timings;
diff --git a/drivers/ide/pci/cy82c693.c b/drivers/ide/pci/cy82c693.c
--- a/drivers/ide/pci/cy82c693.c
+++ b/drivers/ide/pci/cy82c693.c
@@ -391,7 +391,7 @@ static void cy82c693_tune_drive (ide_dri
 /*
  * this function is called during init and is used to setup the cy82c693 chip
  */
-static unsigned int __init init_chipset_cy82c693(struct pci_dev *dev, const char *name)
+static unsigned int __devinit init_chipset_cy82c693(struct pci_dev *dev, const char *name)
 {
 	if (PCI_FUNC(dev->devfn) != 1)
 		return 0;
@@ -443,7 +443,7 @@ static unsigned int __init init_chipset_
 /*
  * the init function - called for each ide channel once
  */
-static void __init init_hwif_cy82c693(ide_hwif_t *hwif)
+static void __devinit init_hwif_cy82c693(ide_hwif_t *hwif)
 {
 	hwif->autodma = 0;
 
@@ -467,9 +467,9 @@ static void __init init_hwif_cy82c693(id
 	hwif->drives[1].autodma = hwif->autodma;
 }
 
-static __initdata ide_hwif_t *primary;
+static __devinitdata ide_hwif_t *primary;
 
-void __init init_iops_cy82c693(ide_hwif_t *hwif)
+void __devinit init_iops_cy82c693(ide_hwif_t *hwif)
 {
 	if (PCI_FUNC(hwif->pci_dev->devfn) == 1)
 		primary = hwif;
diff --git a/drivers/ide/pci/generic.c b/drivers/ide/pci/generic.c
--- a/drivers/ide/pci/generic.c
+++ b/drivers/ide/pci/generic.c
@@ -39,6 +39,17 @@
 
 #include <asm/io.h>
 
+static int ide_generic_all;		/* Set to claim all devices */
+
+static int __init ide_generic_all_on(char *unused)
+{
+	ide_generic_all = 1;
+	printk(KERN_INFO "IDE generic will claim all unknown PCI IDE storage controllers.\n");
+	return 1;
+}
+
+__setup("all-generic-ide", ide_generic_all_on);
+
 static void __devinit init_hwif_generic (ide_hwif_t *hwif)
 {
 	switch(hwif->pci_dev->device) {
@@ -78,84 +89,96 @@ static void __devinit init_hwif_generic 
 
 static ide_pci_device_t generic_chipsets[] __devinitdata = {
 	{	/* 0 */
+		.name		= "Unknown",
+		.init_hwif	= init_hwif_generic,
+		.channels	= 2,
+		.autodma	= AUTODMA,
+		.bootable	= ON_BOARD,
+	},{	/* 1 */
 		.name		= "NS87410",
 		.init_hwif	= init_hwif_generic,
 		.channels	= 2,
 		.autodma	= AUTODMA,
 		.enablebits	= {{0x43,0x08,0x08}, {0x47,0x08,0x08}},
 		.bootable	= ON_BOARD,
-        },{	/* 1 */
+        },{	/* 2 */
 		.name		= "SAMURAI",
 		.init_hwif	= init_hwif_generic,
 		.channels	= 2,
 		.autodma	= AUTODMA,
 		.bootable	= ON_BOARD,
-	},{	/* 2 */
+	},{	/* 3 */
 		.name		= "HT6565",
 		.init_hwif	= init_hwif_generic,
 		.channels	= 2,
 		.autodma	= AUTODMA,
 		.bootable	= ON_BOARD,
-	},{	/* 3 */
+	},{	/* 4 */
 		.name		= "UM8673F",
 		.init_hwif	= init_hwif_generic,
 		.channels	= 2,
 		.autodma	= NODMA,
 		.bootable	= ON_BOARD,
-	},{	/* 4 */
+	},{	/* 5 */
 		.name		= "UM8886A",
 		.init_hwif	= init_hwif_generic,
 		.channels	= 2,
 		.autodma	= NODMA,
 		.bootable	= ON_BOARD,
-	},{	/* 5 */
+	},{	/* 6 */
 		.name		= "UM8886BF",
 		.init_hwif	= init_hwif_generic,
 		.channels	= 2,
 		.autodma	= NODMA,
 		.bootable	= ON_BOARD,
-	},{	/* 6 */
+	},{	/* 7 */
 		.name		= "HINT_IDE",
 		.init_hwif	= init_hwif_generic,
 		.channels	= 2,
 		.autodma	= AUTODMA,
 		.bootable	= ON_BOARD,
-	},{	/* 7 */
+	},{	/* 8 */
 		.name		= "VIA_IDE",
 		.init_hwif	= init_hwif_generic,
 		.channels	= 2,
 		.autodma	= NOAUTODMA,
 		.bootable	= ON_BOARD,
-	},{	/* 8 */
+	},{	/* 9 */
 		.name		= "OPTI621V",
 		.init_hwif	= init_hwif_generic,
 		.channels	= 2,
 		.autodma	= NOAUTODMA,
 		.bootable	= ON_BOARD,
-	},{	/* 9 */
+	},{	/* 10 */
 		.name		= "VIA8237SATA",
 		.init_hwif	= init_hwif_generic,
 		.channels	= 2,
 		.autodma	= AUTODMA,
 		.bootable	= OFF_BOARD,
-	},{	/* 10 */
+	},{	/* 11 */
 		.name 		= "Piccolo0102",
 		.init_hwif	= init_hwif_generic,
 		.channels	= 2,
 		.autodma	= NOAUTODMA,
 		.bootable	= ON_BOARD,
-	},{	/* 11 */
+	},{	/* 12 */
 		.name 		= "Piccolo0103",
 		.init_hwif	= init_hwif_generic,
 		.channels	= 2,
 		.autodma	= NOAUTODMA,
 		.bootable	= ON_BOARD,
-	},{	/* 12 */
+	},{	/* 13 */
 		.name 		= "Piccolo0105",
 		.init_hwif	= init_hwif_generic,
 		.channels	= 2,
 		.autodma	= NOAUTODMA,
 		.bootable	= ON_BOARD,
+	},{	/* 14 */
+		.name		= "Revolution",
+		.init_hwif	= init_hwif_generic,
+		.channels	= 2,
+		.autodma	= AUTODMA,
+		.bootable	= OFF_BOARD,
 	}
 };
 
@@ -174,6 +197,10 @@ static int __devinit generic_init_one(st
 	u16 command;
 	int ret = -ENODEV;
 
+	/* Don't use the generic entry unless instructed to do so */
+	if (id->driver_data == 0 && ide_generic_all == 0)
+			goto out;
+
 	if (dev->vendor == PCI_VENDOR_ID_UMC &&
 	    dev->device == PCI_DEVICE_ID_UMC_UM8886A &&
 	    (!(PCI_FUNC(dev->devfn) & 1)))
@@ -195,21 +222,24 @@ out:
 }
 
 static struct pci_device_id generic_pci_tbl[] = {
-	{ PCI_VENDOR_ID_NS,     PCI_DEVICE_ID_NS_87410,            PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{ PCI_VENDOR_ID_PCTECH, PCI_DEVICE_ID_PCTECH_SAMURAI_IDE,  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
-	{ PCI_VENDOR_ID_HOLTEK, PCI_DEVICE_ID_HOLTEK_6565,         PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2},
-	{ PCI_VENDOR_ID_UMC,    PCI_DEVICE_ID_UMC_UM8673F,         PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3},
-	{ PCI_VENDOR_ID_UMC,    PCI_DEVICE_ID_UMC_UM8886A,         PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4},
-	{ PCI_VENDOR_ID_UMC,    PCI_DEVICE_ID_UMC_UM8886BF,        PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5},
-	{ PCI_VENDOR_ID_HINT,   PCI_DEVICE_ID_HINT_VXPROII_IDE,    PCI_ANY_ID, PCI_ANY_ID, 0, 0, 6},
-	{ PCI_VENDOR_ID_VIA,    PCI_DEVICE_ID_VIA_82C561,          PCI_ANY_ID, PCI_ANY_ID, 0, 0, 7},
-	{ PCI_VENDOR_ID_OPTI,   PCI_DEVICE_ID_OPTI_82C558,         PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8},
+	{ PCI_VENDOR_ID_NS,     PCI_DEVICE_ID_NS_87410,            PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
+	{ PCI_VENDOR_ID_PCTECH, PCI_DEVICE_ID_PCTECH_SAMURAI_IDE,  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2},
+	{ PCI_VENDOR_ID_HOLTEK, PCI_DEVICE_ID_HOLTEK_6565,         PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3},
+	{ PCI_VENDOR_ID_UMC,    PCI_DEVICE_ID_UMC_UM8673F,         PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4},
+	{ PCI_VENDOR_ID_UMC,    PCI_DEVICE_ID_UMC_UM8886A,         PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5},
+	{ PCI_VENDOR_ID_UMC,    PCI_DEVICE_ID_UMC_UM8886BF,        PCI_ANY_ID, PCI_ANY_ID, 0, 0, 6},
+	{ PCI_VENDOR_ID_HINT,   PCI_DEVICE_ID_HINT_VXPROII_IDE,    PCI_ANY_ID, PCI_ANY_ID, 0, 0, 7},
+	{ PCI_VENDOR_ID_VIA,    PCI_DEVICE_ID_VIA_82C561,          PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8},
+	{ PCI_VENDOR_ID_OPTI,   PCI_DEVICE_ID_OPTI_82C558,         PCI_ANY_ID, PCI_ANY_ID, 0, 0, 9},
 #ifdef CONFIG_BLK_DEV_IDE_SATA
-	{ PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_8237_SATA,	   PCI_ANY_ID, PCI_ANY_ID, 0, 0, 9},
+	{ PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_8237_SATA,	   PCI_ANY_ID, PCI_ANY_ID, 0, 0, 10},
 #endif
-	{ PCI_VENDOR_ID_TOSHIBA,PCI_DEVICE_ID_TOSHIBA_PICCOLO,     PCI_ANY_ID, PCI_ANY_ID, 0, 0, 10},
-	{ PCI_VENDOR_ID_TOSHIBA,PCI_DEVICE_ID_TOSHIBA_PICCOLO_1,   PCI_ANY_ID, PCI_ANY_ID, 0, 0, 11},
-	{ PCI_VENDOR_ID_TOSHIBA,PCI_DEVICE_ID_TOSHIBA_PICCOLO_2,   PCI_ANY_ID, PCI_ANY_ID, 0, 0, 12},
+	{ PCI_VENDOR_ID_TOSHIBA,PCI_DEVICE_ID_TOSHIBA_PICCOLO,     PCI_ANY_ID, PCI_ANY_ID, 0, 0, 11},
+	{ PCI_VENDOR_ID_TOSHIBA,PCI_DEVICE_ID_TOSHIBA_PICCOLO_1,   PCI_ANY_ID, PCI_ANY_ID, 0, 0, 12},
+	{ PCI_VENDOR_ID_TOSHIBA,PCI_DEVICE_ID_TOSHIBA_PICCOLO_2,   PCI_ANY_ID, PCI_ANY_ID, 0, 0, 13},
+	{ PCI_VENDOR_ID_NETCELL,PCI_DEVICE_ID_REVOLUTION,          PCI_ANY_ID, PCI_ANY_ID, 0, 0, 14},
+	/* Must come last. If you add entries adjust this table appropriately and the init_one code */
+	{ PCI_ANY_ID,		PCI_ANY_ID,			   PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_IDE << 8, 0xFFFFFF00UL, 0},
 	{ 0, },
 };
 MODULE_DEVICE_TABLE(pci, generic_pci_tbl);
diff --git a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c
--- a/drivers/ide/pci/hpt366.c
+++ b/drivers/ide/pci/hpt366.c
@@ -10,6 +10,11 @@
  * donation of an ABit BP6 mainboard, processor, and memory acellerated
  * development and support.
  *
+ *
+ * Highpoint have their own driver (source except for the raid part)
+ * available from http://www.highpoint-tech.com/hpt3xx-opensource-v131.tgz
+ * This may be useful to anyone wanting to work on the mainstream hpt IDE.
+ *
  * Note that final HPT370 support was done by force extraction of GPL.
  *
  * - add function for getting/setting power status of drive
@@ -446,44 +451,29 @@ static struct chipset_bus_clock_list_ent
 #define F_LOW_PCI_50	0x2d
 #define F_LOW_PCI_66	0x42
 
-/* FIXME: compare with driver's code before removing */
-#if 0
-		if (hpt_minimum_revision(dev, 3)) {
-			u8 cbl;
-			cbl = inb(iobase + 0x7b);
-			outb(cbl | 1, iobase + 0x7b);
-			outb(cbl & ~1, iobase + 0x7b);
-			cbl = inb(iobase + 0x7a);
-			p += sprintf(p, "Cable:          ATA-%d"
-					"                          ATA-%d\n",
-				(cbl & 0x02) ? 33 : 66,
-				(cbl & 0x01) ? 33 : 66);
-			p += sprintf(p, "\n");
-		}
-		{
-			u8 c2, c3;
-			/* older revs don't have these registers mapped 
-			 * into io space */
-			pci_read_config_byte(dev, 0x43, &c0);
-			pci_read_config_byte(dev, 0x47, &c1);
-			pci_read_config_byte(dev, 0x4b, &c2);
-			pci_read_config_byte(dev, 0x4f, &c3);
-
-			p += sprintf(p, "Mode:           %s             %s"
-					"           %s              %s\n",
-				(c0 & 0x10) ? "UDMA" : (c0 & 0x20) ? "DMA " : 
-					(c0 & 0x80) ? "PIO " : "off ",
-				(c1 & 0x10) ? "UDMA" : (c1 & 0x20) ? "DMA " :
-					(c1 & 0x80) ? "PIO " : "off ",
-				(c2 & 0x10) ? "UDMA" : (c2 & 0x20) ? "DMA " :
-					(c2 & 0x80) ? "PIO " : "off ",
-				(c3 & 0x10) ? "UDMA" : (c3 & 0x20) ? "DMA " :
-					(c3 & 0x80) ? "PIO " : "off ");
-		}
-	}
-#endif
+/*
+ *	Hold all the highpoint quirks and revision information in one
+ *	place.
+ */
 
-static u32 hpt_revision (struct pci_dev *dev)
+struct hpt_info
+{
+	u8 max_mode;		/* Speeds allowed */
+	int revision;		/* Chipset revision */
+	int flags;		/* Chipset properties */
+#define PLL_MODE	1
+#define IS_372N		2
+				/* Speed table */
+	struct chipset_bus_clock_list_entry *speed;
+};
+
+/*
+ *	This wants fixing so that we do everything not by classrev
+ *	(which breaks on the newest chips) but by creating an
+ *	enumeration of chip variants and using that
+ */
+
+static __devinit u32 hpt_revision (struct pci_dev *dev)
 {
 	u32 class_rev;
 	pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
@@ -507,37 +497,33 @@ static u32 hpt_revision (struct pci_dev 
 	return class_rev;
 }
 
-static u32 hpt_minimum_revision (struct pci_dev *dev, int revision)
-{
-	unsigned int class_rev = hpt_revision(dev);
-	revision--;
-	return ((int) (class_rev > revision) ? 1 : 0);
-}
-
 static int check_in_drive_lists(ide_drive_t *drive, const char **list);
 
 static u8 hpt3xx_ratemask (ide_drive_t *drive)
 {
-	struct pci_dev *dev	= HWIF(drive)->pci_dev;
+	ide_hwif_t *hwif	= drive->hwif;
+	struct hpt_info *info	= ide_get_hwifdata(hwif);
 	u8 mode			= 0;
 
-	if (hpt_minimum_revision(dev, 8)) {		/* HPT374 */
+	/* FIXME: TODO - move this to set info->mode once at boot */
+
+	if (info->revision >= 8) {		/* HPT374 */
 		mode = (HPT374_ALLOW_ATA133_6) ? 4 : 3;
-	} else if (hpt_minimum_revision(dev, 7)) {	/* HPT371 */
+	} else if (info->revision >= 7) {	/* HPT371 */
 		mode = (HPT371_ALLOW_ATA133_6) ? 4 : 3;
-	} else if (hpt_minimum_revision(dev, 6)) {	/* HPT302 */
+	} else if (info->revision >= 6) {	/* HPT302 */
 		mode = (HPT302_ALLOW_ATA133_6) ? 4 : 3;
-	} else if (hpt_minimum_revision(dev, 5)) {	/* HPT372 */
+	} else if (info->revision >= 5) {	/* HPT372 */
 		mode = (HPT372_ALLOW_ATA133_6) ? 4 : 3;
-	} else if (hpt_minimum_revision(dev, 4)) {	/* HPT370A */
+	} else if (info->revision >= 4) {	/* HPT370A */
 		mode = (HPT370_ALLOW_ATA100_5) ? 3 : 2;
-	} else if (hpt_minimum_revision(dev, 3)) {	/* HPT370 */
+	} else if (info->revision >= 3) {	/* HPT370 */
 		mode = (HPT370_ALLOW_ATA100_5) ? 3 : 2;
 		mode = (check_in_drive_lists(drive, bad_ata33)) ? 0 : mode;
 	} else {				/* HPT366 and HPT368 */
 		mode = (check_in_drive_lists(drive, bad_ata33)) ? 0 : 2;
 	}
-	if (!eighty_ninty_three(drive) && (mode))
+	if (!eighty_ninty_three(drive) && mode)
 		mode = min(mode, (u8)1);
 	return mode;
 }
@@ -549,7 +535,8 @@ static u8 hpt3xx_ratemask (ide_drive_t *
  
 static u8 hpt3xx_ratefilter (ide_drive_t *drive, u8 speed)
 {
-	struct pci_dev *dev	= HWIF(drive)->pci_dev;
+	ide_hwif_t *hwif	= drive->hwif;
+	struct hpt_info *info	= ide_get_hwifdata(hwif);
 	u8 mode			= hpt3xx_ratemask(drive);
 
 	if (drive->media != ide_disk)
@@ -561,7 +548,7 @@ static u8 hpt3xx_ratefilter (ide_drive_t
 			break;
 		case 0x03:
 			speed = min(speed, (u8)XFER_UDMA_5);
-			if (hpt_minimum_revision(dev, 5))
+			if (info->revision >= 5)
 				break;
 			if (check_in_drive_lists(drive, bad_ata100_5))
 				speed = min(speed, (u8)XFER_UDMA_4);
@@ -571,7 +558,7 @@ static u8 hpt3xx_ratefilter (ide_drive_t
 	/*
 	 * CHECK ME, Does this need to be set to 5 ??
 	 */
-			if (hpt_minimum_revision(dev, 3))
+			if (info->revision >= 3)
 				break;
 			if ((check_in_drive_lists(drive, bad_ata66_4)) ||
 			    (!(HPT366_ALLOW_ATA66_4)))
@@ -585,7 +572,7 @@ static u8 hpt3xx_ratefilter (ide_drive_t
 	/*
 	 * CHECK ME, Does this need to be set to 5 ??
 	 */
-			if (hpt_minimum_revision(dev, 3))
+			if (info->revision >= 3)
 				break;
 			if (check_in_drive_lists(drive, bad_ata33))
 				speed = min(speed, (u8)XFER_MW_DMA_2);
@@ -624,11 +611,12 @@ static unsigned int pci_bus_clock_list (
 
 static int hpt36x_tune_chipset(ide_drive_t *drive, u8 xferspeed)
 {
-	struct pci_dev *dev	= HWIF(drive)->pci_dev;
+	ide_hwif_t *hwif	= drive->hwif;
+	struct pci_dev *dev	= hwif->pci_dev;
+	struct hpt_info	*info	= ide_get_hwifdata(hwif);
 	u8 speed		= hpt3xx_ratefilter(drive, xferspeed);
-//	u8 speed		= ide_rate_filter(hpt3xx_ratemask(drive), xferspeed);
 	u8 regtime		= (drive->select.b.unit & 0x01) ? 0x44 : 0x40;
-	u8 regfast		= (HWIF(drive)->channel) ? 0x55 : 0x51;
+	u8 regfast		= (hwif->channel) ? 0x55 : 0x51;
 	u8 drive_fast		= 0;
 	u32 reg1 = 0, reg2	= 0;
 
@@ -636,16 +624,11 @@ static int hpt36x_tune_chipset(ide_drive
 	 * Disable the "fast interrupt" prediction.
 	 */
 	pci_read_config_byte(dev, regfast, &drive_fast);
-#if 0
-	if (drive_fast & 0x02)
-		pci_write_config_byte(dev, regfast, drive_fast & ~0x20);
-#else
 	if (drive_fast & 0x80)
 		pci_write_config_byte(dev, regfast, drive_fast & ~0x80);
-#endif
 
-	reg2 = pci_bus_clock_list(speed,
-		(struct chipset_bus_clock_list_entry *) pci_get_drvdata(dev));
+	reg2 = pci_bus_clock_list(speed, info->speed);
+
 	/*
 	 * Disable on-chip PIO FIFO/buffer
 	 *  (to avoid problems handling I/O errors later)
@@ -665,10 +648,11 @@ static int hpt36x_tune_chipset(ide_drive
 
 static int hpt370_tune_chipset(ide_drive_t *drive, u8 xferspeed)
 {
-	struct pci_dev *dev = HWIF(drive)->pci_dev;
+	ide_hwif_t *hwif	= drive->hwif;
+	struct pci_dev *dev = hwif->pci_dev;
+	struct hpt_info	*info	= ide_get_hwifdata(hwif);
 	u8 speed	= hpt3xx_ratefilter(drive, xferspeed);
-//	u8 speed	= ide_rate_filter(hpt3xx_ratemask(drive), xferspeed);
-	u8 regfast	= (HWIF(drive)->channel) ? 0x55 : 0x51;
+	u8 regfast	= (drive->hwif->channel) ? 0x55 : 0x51;
 	u8 drive_pci	= 0x40 + (drive->dn * 4);
 	u8 new_fast	= 0, drive_fast = 0;
 	u32 list_conf	= 0, drive_conf = 0;
@@ -693,17 +677,13 @@ static int hpt370_tune_chipset(ide_drive
 	if (new_fast != drive_fast)
 		pci_write_config_byte(dev, regfast, new_fast);
 
-	list_conf = pci_bus_clock_list(speed, 
-				       (struct chipset_bus_clock_list_entry *)
-				       pci_get_drvdata(dev));
+	list_conf = pci_bus_clock_list(speed, info->speed);
 
 	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) {
+	if (speed < XFER_MW_DMA_0)
 		list_conf &= ~0x80000000; /* Disable on-chip PIO FIFO/buffer */
-	}
-
 	pci_write_config_dword(dev, drive_pci, list_conf);
 
 	return ide_config_drive_speed(drive, speed);
@@ -711,10 +691,11 @@ static int hpt370_tune_chipset(ide_drive
 
 static int hpt372_tune_chipset(ide_drive_t *drive, u8 xferspeed)
 {
-	struct pci_dev *dev	= HWIF(drive)->pci_dev;
+	ide_hwif_t *hwif	= drive->hwif;
+	struct pci_dev *dev	= hwif->pci_dev;
+	struct hpt_info	*info	= ide_get_hwifdata(hwif);
 	u8 speed	= hpt3xx_ratefilter(drive, xferspeed);
-//	u8 speed	= ide_rate_filter(hpt3xx_ratemask(drive), xferspeed);
-	u8 regfast	= (HWIF(drive)->channel) ? 0x55 : 0x51;
+	u8 regfast	= (drive->hwif->channel) ? 0x55 : 0x51;
 	u8 drive_fast	= 0, drive_pci = 0x40 + (drive->dn * 4);
 	u32 list_conf	= 0, drive_conf = 0;
 	u32 conf_mask	= (speed >= XFER_MW_DMA_0) ? 0xc0000000 : 0x30070000;
@@ -726,10 +707,8 @@ static int hpt372_tune_chipset(ide_drive
 	pci_read_config_byte(dev, regfast, &drive_fast);
 	drive_fast &= ~0x07;
 	pci_write_config_byte(dev, regfast, drive_fast);
-					
-	list_conf = pci_bus_clock_list(speed,
-			(struct chipset_bus_clock_list_entry *)
-					pci_get_drvdata(dev));
+
+	list_conf = pci_bus_clock_list(speed, info->speed);
 	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)
@@ -741,19 +720,14 @@ static int hpt372_tune_chipset(ide_drive
 
 static int hpt3xx_tune_chipset (ide_drive_t *drive, u8 speed)
 {
-	struct pci_dev *dev	= HWIF(drive)->pci_dev;
+	ide_hwif_t *hwif	= drive->hwif;
+	struct hpt_info	*info	= ide_get_hwifdata(hwif);
 
-	if (hpt_minimum_revision(dev, 8))
+	if (info->revision >= 8)
 		return hpt372_tune_chipset(drive, speed); /* not a typo */
-#if 0
-	else if (hpt_minimum_revision(dev, 7))
-		hpt371_tune_chipset(drive, speed);
-	else if (hpt_minimum_revision(dev, 6))
-		hpt302_tune_chipset(drive, speed);
-#endif
-	else if (hpt_minimum_revision(dev, 5))
+	else if (info->revision >= 5)
 		return hpt372_tune_chipset(drive, speed);
-	else if (hpt_minimum_revision(dev, 3))
+	else if (info->revision >= 3)
 		return hpt370_tune_chipset(drive, speed);
 	else	/* hpt368: hpt_minimum_revision(dev, 2) */
 		return hpt36x_tune_chipset(drive, speed);
@@ -779,8 +753,14 @@ static void hpt3xx_tune_drive (ide_drive
 static int config_chipset_for_dma (ide_drive_t *drive)
 {
 	u8 speed = ide_dma_speed(drive, hpt3xx_ratemask(drive));
+	ide_hwif_t *hwif = drive->hwif;
+	struct hpt_info	*info	= ide_get_hwifdata(hwif);
+
+	if (!speed)
+		return 0;
 
-	if (!(speed))
+	/* If we don't have any timings we can't do a lot */
+	if (info->speed == NULL)
 		return 0;
 
 	(void) hpt3xx_tune_chipset(drive, speed);
@@ -794,7 +774,7 @@ static int hpt3xx_quirkproc (ide_drive_t
 
 static void hpt3xx_intrproc (ide_drive_t *drive)
 {
-	ide_hwif_t *hwif = HWIF(drive);
+	ide_hwif_t *hwif = drive->hwif;
 
 	if (drive->quirk_list)
 		return;
@@ -804,24 +784,26 @@ static void hpt3xx_intrproc (ide_drive_t
 
 static void hpt3xx_maskproc (ide_drive_t *drive, int mask)
 {
-	struct pci_dev *dev = HWIF(drive)->pci_dev;
+	ide_hwif_t *hwif = drive->hwif;
+	struct hpt_info *info = ide_get_hwifdata(hwif);
+	struct pci_dev *dev = hwif->pci_dev;
 
 	if (drive->quirk_list) {
-		if (hpt_minimum_revision(dev,3)) {
+		if (info->revision >= 3) {
 			u8 reg5a = 0;
 			pci_read_config_byte(dev, 0x5a, &reg5a);
 			if (((reg5a & 0x10) >> 4) != mask)
 				pci_write_config_byte(dev, 0x5a, mask ? (reg5a | 0x10) : (reg5a & ~0x10));
 		} else {
 			if (mask) {
-				disable_irq(HWIF(drive)->irq);
+				disable_irq(hwif->irq);
 			} else {
-				enable_irq(HWIF(drive)->irq);
+				enable_irq(hwif->irq);
 			}
 		}
 	} else {
 		if (IDE_CONTROL_REG)
-			HWIF(drive)->OUTB(mask ? (drive->ctl | 2) :
+			hwif->OUTB(mask ? (drive->ctl | 2) :
 						 (drive->ctl & ~2),
 						 IDE_CONTROL_REG);
 	}
@@ -829,12 +811,12 @@ static void hpt3xx_maskproc (ide_drive_t
 
 static int hpt366_config_drive_xfer_rate (ide_drive_t *drive)
 {
-	ide_hwif_t *hwif	= HWIF(drive);
+	ide_hwif_t *hwif	= drive->hwif;
 	struct hd_driveid *id	= drive->id;
 
 	drive->init_speed = 0;
 
-	if (id && (id->capability & 1) && drive->autodma) {
+	if ((id->capability & 1) && drive->autodma) {
 
 		if (ide_use_dma(drive)) {
 			if (config_chipset_for_dma(drive))
@@ -868,15 +850,6 @@ static int hpt366_ide_dma_lostirq (ide_d
 		drive->name, __FUNCTION__, reg50h, reg52h, reg5ah);
 	if (reg5ah & 0x10)
 		pci_write_config_byte(dev, 0x5a, reg5ah & ~0x10);
-#if 0
-	/* how about we flush and reset, mmmkay? */
-	pci_write_config_byte(dev, 0x51, 0x1F);
-	/* fall through to a reset */
-	case dma_start:
-	case ide_dma_end:
-	/* reset the chips state over and over.. */
-	pci_write_config_byte(dev, 0x51, 0x13);
-#endif
 	return __ide_dma_lostirq(drive);
 }
 
@@ -919,7 +892,7 @@ static void hpt370_lostirq_timeout (ide_
 	u8 dma_stat = 0, dma_cmd = 0;
 
 	pci_read_config_byte(HWIF(drive)->pci_dev, reginfo, &bfifo);
-	printk("%s: %d bytes in FIFO\n", drive->name, bfifo);
+	printk(KERN_DEBUG "%s: %d bytes in FIFO\n", drive->name, bfifo);
 	hpt370_clear_engine(drive);
 	/* get dma command mode */
 	dma_cmd = hwif->INB(hwif->dma_command);
@@ -1047,15 +1020,6 @@ static void hpt372n_rw_disk(ide_drive_t 
 
 static void hpt3xx_reset (ide_drive_t *drive)
 {
-#if 0
-	unsigned long high_16	= pci_resource_start(HWIF(drive)->pci_dev, 4);
-	u8 reset	= (HWIF(drive)->channel) ? 0x80 : 0x40;
-	u8 reg59h	= 0;
-
-	pci_read_config_byte(HWIF(drive)->pci_dev, 0x59, &reg59h);
-	pci_write_config_byte(HWIF(drive)->pci_dev, 0x59, reg59h|reset);
-	pci_write_config_byte(HWIF(drive)->pci_dev, 0x59, reg59h);
-#endif
 }
 
 static int hpt3xx_tristate (ide_drive_t * drive, int state)
@@ -1065,8 +1029,6 @@ static int hpt3xx_tristate (ide_drive_t 
 	u8 reg59h = 0, reset	= (hwif->channel) ? 0x80 : 0x40;
 	u8 regXXh = 0, state_reg= (hwif->channel) ? 0x57 : 0x53;
 
-//	hwif->bus_state = state;
-
 	pci_read_config_byte(dev, 0x59, &reg59h);
 	pci_read_config_byte(dev, state_reg, &regXXh);
 
@@ -1093,7 +1055,7 @@ static int hpt3xx_tristate (ide_drive_t 
 #define TRISTATE_BIT  0x8000
 static int hpt370_busproc(ide_drive_t * drive, int state)
 {
-	ide_hwif_t *hwif	= HWIF(drive);
+	ide_hwif_t *hwif	= drive->hwif;
 	struct pci_dev *dev	= hwif->pci_dev;
 	u8 tristate = 0, resetmask = 0, bus_reg = 0;
 	u16 tri_reg;
@@ -1148,33 +1110,44 @@ static int hpt370_busproc(ide_drive_t * 
 	return 0;
 }
 
-static int __devinit init_hpt37x(struct pci_dev *dev)
+static void __devinit hpt366_clocking(ide_hwif_t *hwif)
+{
+	u32 reg1	= 0;
+	struct hpt_info *info = ide_get_hwifdata(hwif);
+
+	pci_read_config_dword(hwif->pci_dev, 0x40, &reg1);
+
+	/* detect bus speed by looking at control reg timing: */
+	switch((reg1 >> 8) & 7) {
+		case 5:
+			info->speed = forty_base_hpt366;
+			break;
+		case 9:
+			info->speed = twenty_five_base_hpt366;
+			break;
+		case 7:
+		default:
+			info->speed = thirty_three_base_hpt366;
+			break;
+	}
+}
+
+static void __devinit hpt37x_clocking(ide_hwif_t *hwif)
 {
+	struct hpt_info *info = ide_get_hwifdata(hwif);
+	struct pci_dev *dev = hwif->pci_dev;
 	int adjust, i;
 	u16 freq;
 	u32 pll;
 	u8 reg5bh;
-	u8 reg5ah = 0;
-	unsigned long dmabase = pci_resource_start(dev, 4);
-	u8 did, rid;	
-	int is_372n = 0;
 	
-	pci_read_config_byte(dev, 0x5a, &reg5ah);
-	/* interrupt force enable */
-	pci_write_config_byte(dev, 0x5a, (reg5ah & ~0x10));
-
-	if(dmabase)
-	{
-		did = inb(dmabase + 0x22);
-		rid = inb(dmabase + 0x28);
-	
-		if((did == 4 && rid == 6) || (did == 5 && rid > 1))
-			is_372n = 1;
-	}
-
 	/*
 	 * default to pci clock. make sure MA15/16 are set to output
-	 * to prevent drives having problems with 40-pin cables.
+	 * to prevent drives having problems with 40-pin cables. Needed
+	 * for some drives such as IBM-DTLA which will not enter ready
+	 * state on reset when PDIAG is a input.
+	 *
+	 * ToDo: should we set 0x21 when using PLL mode ?
 	 */
 	pci_write_config_byte(dev, 0x5b, 0x23);
 
@@ -1197,9 +1170,7 @@ static int __devinit init_hpt37x(struct 
 	 * Currently we always set up the PLL for the 372N
 	 */
 	 
-	pci_set_drvdata(dev, NULL);
-	
-	if(is_372n)
+	if(info->flags & IS_372N)
 	{
 		printk(KERN_INFO "hpt: HPT372N detected, using 372N timing.\n");
 		if(freq < 0x55)
@@ -1227,39 +1198,38 @@ static int __devinit init_hpt37x(struct 
 			pll = F_LOW_PCI_66;
 	
 		if (pll == F_LOW_PCI_33) {
-			if (hpt_minimum_revision(dev,8))
-				pci_set_drvdata(dev, (void *) thirty_three_base_hpt374);
-			else if (hpt_minimum_revision(dev,5))
-				pci_set_drvdata(dev, (void *) thirty_three_base_hpt372);
-			else if (hpt_minimum_revision(dev,4))
-				pci_set_drvdata(dev, (void *) thirty_three_base_hpt370a);
+			if (info->revision >= 8)
+				info->speed = thirty_three_base_hpt374;
+			else if (info->revision >= 5)
+				info->speed = thirty_three_base_hpt372;
+			else if (info->revision >= 4)
+				info->speed = thirty_three_base_hpt370a;
 			else
-				pci_set_drvdata(dev, (void *) thirty_three_base_hpt370);
-			printk("HPT37X: using 33MHz PCI clock\n");
+				info->speed = thirty_three_base_hpt370;
+			printk(KERN_DEBUG "HPT37X: using 33MHz PCI clock\n");
 		} else if (pll == F_LOW_PCI_40) {
 			/* Unsupported */
 		} else if (pll == F_LOW_PCI_50) {
-			if (hpt_minimum_revision(dev,8))
-				pci_set_drvdata(dev, (void *) fifty_base_hpt370a);
-			else if (hpt_minimum_revision(dev,5))
-				pci_set_drvdata(dev, (void *) fifty_base_hpt372);
-			else if (hpt_minimum_revision(dev,4))
-				pci_set_drvdata(dev, (void *) fifty_base_hpt370a);
+			if (info->revision >= 8)
+				info->speed = fifty_base_hpt370a;
+			else if (info->revision >= 5)
+				info->speed = fifty_base_hpt372;
+			else if (info->revision >= 4)
+				info->speed = fifty_base_hpt370a;
 			else
-				pci_set_drvdata(dev, (void *) fifty_base_hpt370a);
-			printk("HPT37X: using 50MHz PCI clock\n");
+				info->speed = fifty_base_hpt370a;
+			printk(KERN_DEBUG "HPT37X: using 50MHz PCI clock\n");
 		} else {
-			if (hpt_minimum_revision(dev,8))
-			{
+			if (info->revision >= 8) {
 				printk(KERN_ERR "HPT37x: 66MHz timings are not supported.\n");
 			}
-			else if (hpt_minimum_revision(dev,5))
-				pci_set_drvdata(dev, (void *) sixty_six_base_hpt372);
-			else if (hpt_minimum_revision(dev,4))
-				pci_set_drvdata(dev, (void *) sixty_six_base_hpt370a);
+			else if (info->revision >= 5)
+				info->speed = sixty_six_base_hpt372;
+			else if (info->revision >= 4)
+				info->speed = sixty_six_base_hpt370a;
 			else
-				pci_set_drvdata(dev, (void *) sixty_six_base_hpt370);
-			printk("HPT37X: using 66MHz PCI clock\n");
+				info->speed = sixty_six_base_hpt370;
+			printk(KERN_DEBUG "HPT37X: using 66MHz PCI clock\n");
 		}
 	}
 	
@@ -1269,11 +1239,19 @@ static int __devinit init_hpt37x(struct 
 	 * 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.
+	 *
+	 * ToDo: Use 66MHz PLL when ATA133 devices are present on a
+	 * 372 device so we can get ATA133 support
 	 */
-	if (pci_get_drvdata(dev)) 
+	if (info->speed)
 		goto init_hpt37X_done;
+
+	info->flags |= PLL_MODE;
 	
 	/*
+	 * FIXME: make this work correctly, esp with 372N as per
+	 * reference driver code.
+	 *
 	 * adjust PLL based upon PCI clock, enable it, and wait for
 	 * stabilization.
 	 */
@@ -1298,14 +1276,14 @@ static int __devinit init_hpt37x(struct 
 				pci_write_config_dword(dev, 0x5c, 
 						       pll & ~0x100);
 				pci_write_config_byte(dev, 0x5b, 0x21);
-				if (hpt_minimum_revision(dev,8))
-					pci_set_drvdata(dev, (void *) fifty_base_hpt370a);
-				else if (hpt_minimum_revision(dev,5))
-					pci_set_drvdata(dev, (void *) fifty_base_hpt372);
-				else if (hpt_minimum_revision(dev,4))
-					pci_set_drvdata(dev, (void *) fifty_base_hpt370a);
+				if (info->revision >= 8)
+					info->speed = fifty_base_hpt370a;
+				else if (info->revision >= 5)
+					info->speed = fifty_base_hpt372;
+				else if (info->revision >= 4)
+					info->speed = fifty_base_hpt370a;
 				else
-					pci_set_drvdata(dev, (void *) fifty_base_hpt370a);
+					info->speed = fifty_base_hpt370a;
 				printk("HPT37X: using 50MHz internal PLL\n");
 				goto init_hpt37X_done;
 			}
@@ -1318,10 +1296,22 @@ pll_recal:
 	} 
 
 init_hpt37X_done:
+	if (!info->speed)
+		printk(KERN_ERR "HPT37X%s: unknown bus timing [%d %d].\n",
+			(info->flags & IS_372N)?"N":"", pll, freq);
 	/* reset state engine */
 	pci_write_config_byte(dev, 0x50, 0x37); 
 	pci_write_config_byte(dev, 0x54, 0x37); 
 	udelay(100);
+}
+
+static int __devinit init_hpt37x(struct pci_dev *dev)
+{
+	u8 reg5ah;
+
+	pci_read_config_byte(dev, 0x5a, &reg5ah);
+	/* interrupt force enable */
+	pci_write_config_byte(dev, 0x5a, (reg5ah & ~0x10));
 	return 0;
 }
 
@@ -1338,59 +1328,27 @@ static int __devinit init_hpt366(struct 
 		pci_write_config_byte(dev, 0x51, drive_fast & ~0x80);
 	pci_read_config_dword(dev, 0x40, &reg1);
 									
-	/* detect bus speed by looking at control reg timing: */
-	switch((reg1 >> 8) & 7) {
-		case 5:
-			pci_set_drvdata(dev, (void *) forty_base_hpt366);
-			break;
-		case 9:
-			pci_set_drvdata(dev, (void *) twenty_five_base_hpt366);
-			break;
-		case 7:
-		default:
-			pci_set_drvdata(dev, (void *) thirty_three_base_hpt366);
-			break;
-	}
-
-	if (!pci_get_drvdata(dev))
-	{
-		printk(KERN_ERR "hpt366: unknown bus timing.\n");
-		pci_set_drvdata(dev, NULL);
-	}
 	return 0;
 }
 
 static unsigned int __devinit init_chipset_hpt366(struct pci_dev *dev, const char *name)
 {
 	int ret = 0;
-	u8 test = 0;
-
+	/* FIXME: Not portable */
 	if (dev->resource[PCI_ROM_RESOURCE].start)
 		pci_write_config_byte(dev, PCI_ROM_ADDRESS,
 			dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE);
 
-	pci_read_config_byte(dev, PCI_CACHE_LINE_SIZE, &test);
-	if (test != (L1_CACHE_BYTES / 4))
-		pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE,
-			(L1_CACHE_BYTES / 4));
-
-	pci_read_config_byte(dev, PCI_LATENCY_TIMER, &test);
-	if (test != 0x78)
-		pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x78);
-
-	pci_read_config_byte(dev, PCI_MIN_GNT, &test);
-	if (test != 0x08)
-		pci_write_config_byte(dev, PCI_MIN_GNT, 0x08);
-
-	pci_read_config_byte(dev, PCI_MAX_LAT, &test);
-	if (test != 0x08)
-		pci_write_config_byte(dev, PCI_MAX_LAT, 0x08);
+	pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, (L1_CACHE_BYTES / 4));
+	pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x78);
+	pci_write_config_byte(dev, PCI_MIN_GNT, 0x08);
+	pci_write_config_byte(dev, PCI_MAX_LAT, 0x08);
 
-	if (hpt_minimum_revision(dev, 3)) {
+	if (hpt_revision(dev) >= 3)
 		ret = init_hpt37x(dev);
-	} else {
-		ret =init_hpt366(dev);
-	}
+	else
+		ret = init_hpt366(dev);
+
 	if (ret)
 		return ret;
 
@@ -1400,27 +1358,16 @@ static unsigned int __devinit init_chips
 static void __devinit init_hwif_hpt366(ide_hwif_t *hwif)
 {
 	struct pci_dev *dev		= hwif->pci_dev;
+	struct hpt_info *info		= ide_get_hwifdata(hwif);
 	u8 ata66 = 0, regmask		= (hwif->channel) ? 0x01 : 0x02;
-	u8 did, rid;
-	unsigned long dmabase		= hwif->dma_base;
-	int is_372n = 0;
 	
-	if(dmabase)
-	{
-		did = inb(dmabase + 0x22);
-		rid = inb(dmabase + 0x28);
-	
-		if((did == 4 && rid == 6) || (did == 5 && rid > 1))
-			is_372n = 1;
-	}
-		
 	hwif->tuneproc			= &hpt3xx_tune_drive;
 	hwif->speedproc			= &hpt3xx_tune_chipset;
 	hwif->quirkproc			= &hpt3xx_quirkproc;
 	hwif->intrproc			= &hpt3xx_intrproc;
 	hwif->maskproc			= &hpt3xx_maskproc;
 	
-	if(is_372n)
+	if(info->flags & IS_372N)
 		hwif->rw_disk = &hpt372n_rw_disk;
 
 	/*
@@ -1428,7 +1375,7 @@ static void __devinit init_hwif_hpt366(i
 	 * address lines to access an external eeprom.  To read valid
 	 * cable detect state the pins must be enabled as inputs.
 	 */
-	if (hpt_minimum_revision(dev, 8) && PCI_FUNC(dev->devfn) & 1) {
+	if (info->revision >= 8 && (PCI_FUNC(dev->devfn) & 1)) {
 		/*
 		 * HPT374 PCI function 1
 		 * - set bit 15 of reg 0x52 to enable TCBLID as input
@@ -1443,7 +1390,7 @@ static void __devinit init_hwif_hpt366(i
 		pci_read_config_byte(dev, 0x5a, &ata66);
 		pci_write_config_word(dev, 0x52, mcr3);
 		pci_write_config_word(dev, 0x56, mcr6);
-	} else if (hpt_minimum_revision(dev, 3)) {
+	} else if (info->revision >= 3) {
 		/*
 		 * HPT370/372 and 374 pcifn 0
 		 * - clear bit 0 of 0x5b to enable P/SCBLID as inputs
@@ -1470,7 +1417,7 @@ static void __devinit init_hwif_hpt366(i
 		hwif->serialized = hwif->mate->serialized = 1;
 #endif
 
-	if (hpt_minimum_revision(dev,3)) {
+	if (info->revision >= 3) {
 		u8 reg5ah = 0;
 			pci_write_config_byte(dev, 0x5a, reg5ah & ~0x10);
 		/*
@@ -1480,8 +1427,7 @@ static void __devinit init_hwif_hpt366(i
 		 */
 		hwif->resetproc	= &hpt3xx_reset;
 		hwif->busproc	= &hpt370_busproc;
-//		hwif->drives[0].autotune = hwif->drives[1].autotune = 1;
-	} else if (hpt_minimum_revision(dev,2)) {
+	} else if (info->revision >= 2) {
 		hwif->resetproc	= &hpt3xx_reset;
 		hwif->busproc	= &hpt3xx_tristate;
 	} else {
@@ -1502,18 +1448,18 @@ static void __devinit init_hwif_hpt366(i
 		hwif->udma_four = ((ata66 & regmask) ? 0 : 1);
 	hwif->ide_dma_check = &hpt366_config_drive_xfer_rate;
 
-	if (hpt_minimum_revision(dev,8)) {
+	if (info->revision >= 8) {
 		hwif->ide_dma_test_irq = &hpt374_ide_dma_test_irq;
 		hwif->ide_dma_end = &hpt374_ide_dma_end;
-	} else if (hpt_minimum_revision(dev,5)) {
+	} else if (info->revision >= 5) {
 		hwif->ide_dma_test_irq = &hpt374_ide_dma_test_irq;
 		hwif->ide_dma_end = &hpt374_ide_dma_end;
-	} else if (hpt_minimum_revision(dev,3)) {
+	} else if (info->revision >= 3) {
 		hwif->dma_start = &hpt370_ide_dma_start;
 		hwif->ide_dma_end = &hpt370_ide_dma_end;
 		hwif->ide_dma_timeout = &hpt370_ide_dma_timeout;
 		hwif->ide_dma_lostirq = &hpt370_ide_dma_lostirq;
-	} else if (hpt_minimum_revision(dev,2))
+	} else if (info->revision >= 2)
 		hwif->ide_dma_lostirq = &hpt366_ide_dma_lostirq;
 	else
 		hwif->ide_dma_lostirq = &hpt366_ide_dma_lostirq;
@@ -1526,6 +1472,7 @@ static void __devinit init_hwif_hpt366(i
 
 static void __devinit init_dma_hpt366(ide_hwif_t *hwif, unsigned long dmabase)
 {
+	struct hpt_info	*info	= ide_get_hwifdata(hwif);
 	u8 masterdma	= 0, slavedma = 0;
 	u8 dma_new	= 0, dma_old = 0;
 	u8 primary	= hwif->channel ? 0x4b : 0x43;
@@ -1535,8 +1482,7 @@ static void __devinit init_dma_hpt366(id
 	if (!dmabase)
 		return;
 		
-	if(pci_get_drvdata(hwif->pci_dev) == NULL)
-	{
+	if(info->speed == NULL) {
 		printk(KERN_WARNING "hpt: no known IDE timings, disabling DMA.\n");
 		return;
 	}
@@ -1559,6 +1505,40 @@ static void __devinit init_dma_hpt366(id
 	ide_setup_dma(hwif, dmabase, 8);
 }
 
+/*
+ *	We "borrow" this hook in order to set the data structures
+ *	up early enough before dma or init_hwif calls are made.
+ */
+
+static void __devinit init_iops_hpt366(ide_hwif_t *hwif)
+{
+	struct hpt_info *info = kmalloc(sizeof(struct hpt_info), GFP_KERNEL);
+	unsigned long dmabase = pci_resource_start(hwif->pci_dev, 4);
+	u8 did, rid;
+
+	if(info == NULL) {
+		printk(KERN_WARNING "hpt366: out of memory.\n");
+		return;
+	}
+	memset(info, 0, sizeof(struct hpt_info));
+	ide_set_hwifdata(hwif, info);
+
+	if(dmabase) {
+		did = inb(dmabase + 0x22);
+		rid = inb(dmabase + 0x28);
+
+		if((did == 4 && rid == 6) || (did == 5 && rid > 1))
+			info->flags |= IS_372N;
+	}
+
+	info->revision = hpt_revision(hwif->pci_dev);
+
+	if (info->revision >= 3)
+		hpt37x_clocking(hwif);
+	else
+		hpt366_clocking(hwif);
+}
+
 static int __devinit init_setup_hpt374(struct pci_dev *dev, ide_pci_device_t *d)
 {
 	struct pci_dev *findev = NULL;
@@ -1646,6 +1626,7 @@ static ide_pci_device_t hpt366_chipsets[
 		.name		= "HPT366",
 		.init_setup	= init_setup_hpt366,
 		.init_chipset	= init_chipset_hpt366,
+		.init_iops	= init_iops_hpt366,
 		.init_hwif	= init_hwif_hpt366,
 		.init_dma	= init_dma_hpt366,
 		.channels	= 2,
@@ -1656,6 +1637,7 @@ static ide_pci_device_t hpt366_chipsets[
 		.name		= "HPT372A",
 		.init_setup	= init_setup_hpt37x,
 		.init_chipset	= init_chipset_hpt366,
+		.init_iops	= init_iops_hpt366,
 		.init_hwif	= init_hwif_hpt366,
 		.init_dma	= init_dma_hpt366,
 		.channels	= 2,
@@ -1665,6 +1647,7 @@ static ide_pci_device_t hpt366_chipsets[
 		.name		= "HPT302",
 		.init_setup	= init_setup_hpt37x,
 		.init_chipset	= init_chipset_hpt366,
+		.init_iops	= init_iops_hpt366,
 		.init_hwif	= init_hwif_hpt366,
 		.init_dma	= init_dma_hpt366,
 		.channels	= 2,
@@ -1674,6 +1657,7 @@ static ide_pci_device_t hpt366_chipsets[
 		.name		= "HPT371",
 		.init_setup	= init_setup_hpt37x,
 		.init_chipset	= init_chipset_hpt366,
+		.init_iops	= init_iops_hpt366,
 		.init_hwif	= init_hwif_hpt366,
 		.init_dma	= init_dma_hpt366,
 		.channels	= 2,
@@ -1683,6 +1667,7 @@ static ide_pci_device_t hpt366_chipsets[
 		.name		= "HPT374",
 		.init_setup	= init_setup_hpt374,
 		.init_chipset	= init_chipset_hpt366,
+		.init_iops	= init_iops_hpt366,
 		.init_hwif	= init_hwif_hpt366,
 		.init_dma	= init_dma_hpt366,
 		.channels	= 2,	/* 4 */
@@ -1692,6 +1677,7 @@ static ide_pci_device_t hpt366_chipsets[
 		.name		= "HPT372N",
 		.init_setup	= init_setup_hpt37x,
 		.init_chipset	= init_chipset_hpt366,
+		.init_iops	= init_iops_hpt366,
 		.init_hwif	= init_hwif_hpt366,
 		.init_dma	= init_dma_hpt366,
 		.channels	= 2,	/* 4 */
diff --git a/drivers/ide/pci/it8172.c b/drivers/ide/pci/it8172.c
--- a/drivers/ide/pci/it8172.c
+++ b/drivers/ide/pci/it8172.c
@@ -216,7 +216,7 @@ fast_ata_pio:
 	return 0;
 }
 
-static unsigned int __init init_chipset_it8172 (struct pci_dev *dev, const char *name)
+static unsigned int __devinit init_chipset_it8172 (struct pci_dev *dev, const char *name)
 {
 	unsigned char progif;
     
@@ -230,7 +230,7 @@ static unsigned int __init init_chipset_
 }
 
 
-static void __init init_hwif_it8172 (ide_hwif_t *hwif)
+static void __devinit init_hwif_it8172 (ide_hwif_t *hwif)
 {
 	struct pci_dev* dev = hwif->pci_dev;
 	unsigned long cmdBase, ctrlBase;
diff --git a/drivers/ide/pci/it821x.c b/drivers/ide/pci/it821x.c
new file mode 100644
--- /dev/null
+++ b/drivers/ide/pci/it821x.c
@@ -0,0 +1,812 @@
+
+/*
+ * linux/drivers/ide/pci/it821x.c		Version 0.09	December 2004
+ *
+ * Copyright (C) 2004		Red Hat <alan@redhat.com>
+ *
+ *  May be copied or modified under the terms of the GNU General Public License
+ *  Based in part on the ITE vendor provided SCSI driver.
+ *
+ *  Documentation available from
+ * 	http://www.ite.com.tw/pc/IT8212F_V04.pdf
+ *  Some other documents are NDA.
+ *
+ *  The ITE8212 isn't exactly a standard IDE controller. It has two
+ *  modes. In pass through mode then it is an IDE controller. In its smart
+ *  mode its actually quite a capable hardware raid controller disguised
+ *  as an IDE controller. Smart mode only understands DMA read/write and
+ *  identify, none of the fancier commands apply. The IT8211 is identical
+ *  in other respects but lacks the raid mode.
+ *
+ *  Errata:
+ *  o	Rev 0x10 also requires master/slave hold the same DMA timings and
+ *	cannot do ATAPI MWDMA.
+ *  o	The identify data for raid volumes lacks CHS info (technically ok)
+ *	but also fails to set the LBA28 and other bits. We fix these in
+ *	the IDE probe quirk code.
+ *  o	If you write LBA48 sized I/O's (ie > 256 sector) in smart mode
+ *	raid then the controller firmware dies
+ *  o	Smart mode without RAID doesn't clear all the necessary identify
+ *	bits to reduce the command set to the one used
+ *
+ *  This has a few impacts on the driver
+ *  - In pass through mode we do all the work you would expect
+ *  - In smart mode the clocking set up is done by the controller generally
+ *    but we must watch the other limits and filter.
+ *  - There are a few extra vendor commands that actually talk to the
+ *    controller but only work PIO with no IRQ.
+ *
+ *  Vendor areas of the identify block in smart mode are used for the
+ *  timing and policy set up. Each HDD in raid mode also has a serial
+ *  block on the disk. The hardware extra commands are get/set chip status,
+ *  rebuild, get rebuild status.
+ *
+ *  In Linux the driver supports pass through mode as if the device was
+ *  just another IDE controller. If the smart mode is running then
+ *  volumes are managed by the controller firmware and each IDE "disk"
+ *  is a raid volume. Even more cute - the controller can do automated
+ *  hotplug and rebuild.
+ *
+ *  The pass through controller itself is a little demented. It has a
+ *  flaw that it has a single set of PIO/MWDMA timings per channel so
+ *  non UDMA devices restrict each others performance. It also has a
+ *  single clock source per channel so mixed UDMA100/133 performance
+ *  isn't perfect and we have to pick a clock. Thankfully none of this
+ *  matters in smart mode. ATAPI DMA is not currently supported.
+ *
+ *  It seems the smart mode is a win for RAID1/RAID10 but otherwise not.
+ *
+ *  TODO
+ *	-	ATAPI UDMA is ok but not MWDMA it seems
+ *	-	RAID configuration ioctls
+ *	-	Move to libata once it grows up
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/hdreg.h>
+#include <linux/ide.h>
+#include <linux/init.h>
+
+#include <asm/io.h>
+
+struct it821x_dev
+{
+	unsigned int smart:1,		/* Are we in smart raid mode */
+		timing10:1;		/* Rev 0x10 */
+	u8	clock_mode;		/* 0, ATA_50 or ATA_66 */
+	u8	want[2][2];		/* Mode/Pri log for master slave */
+	/* We need these for switching the clock when DMA goes on/off
+	   The high byte is the 66Mhz timing */
+	u16	pio[2];			/* Cached PIO values */
+	u16	mwdma[2];		/* Cached MWDMA values */
+	u16	udma[2];		/* Cached UDMA values (per drive) */
+};
+
+#define ATA_66		0
+#define ATA_50		1
+#define ATA_ANY		2
+
+#define UDMA_OFF	0
+#define MWDMA_OFF	0
+
+/*
+ *	We allow users to force the card into non raid mode without
+ *	flashing the alternative BIOS. This is also neccessary right now
+ *	for embedded platforms that cannot run a PC BIOS but are using this
+ *	device.
+ */
+
+static int it8212_noraid;
+
+/**
+ *	it821x_program	-	program the PIO/MWDMA registers
+ *	@drive: drive to tune
+ *
+ *	Program the PIO/MWDMA timing for this channel according to the
+ *	current clock.
+ */
+
+static void it821x_program(ide_drive_t *drive, u16 timing)
+{
+	ide_hwif_t *hwif	= drive->hwif;
+	struct it821x_dev *itdev = ide_get_hwifdata(hwif);
+	int channel = hwif->channel;
+	u8 conf;
+
+	/* Program PIO/MWDMA timing bits */
+	if(itdev->clock_mode == ATA_66)
+		conf = timing >> 8;
+	else
+		conf = timing & 0xFF;
+	pci_write_config_byte(hwif->pci_dev, 0x54 + 4 * channel, conf);
+}
+
+/**
+ *	it821x_program_udma	-	program the UDMA registers
+ *	@drive: drive to tune
+ *
+ *	Program the UDMA timing for this drive according to the
+ *	current clock.
+ */
+
+static void it821x_program_udma(ide_drive_t *drive, u16 timing)
+{
+	ide_hwif_t *hwif	= drive->hwif;
+	struct it821x_dev *itdev = ide_get_hwifdata(hwif);
+	int channel = hwif->channel;
+	int unit = drive->select.b.unit;
+	u8 conf;
+
+	/* Program UDMA timing bits */
+	if(itdev->clock_mode == ATA_66)
+		conf = timing >> 8;
+	else
+		conf = timing & 0xFF;
+	if(itdev->timing10 == 0)
+		pci_write_config_byte(hwif->pci_dev, 0x56 + 4 * channel + unit, conf);
+	else {
+		pci_write_config_byte(hwif->pci_dev, 0x56 + 4 * channel, conf);
+		pci_write_config_byte(hwif->pci_dev, 0x56 + 4 * channel + 1, conf);
+	}
+}
+
+
+/**
+ *	it821x_clock_strategy
+ *	@hwif: hardware interface
+ *
+ *	Select between the 50 and 66Mhz base clocks to get the best
+ *	results for this interface.
+ */
+
+static void it821x_clock_strategy(ide_drive_t *drive)
+{
+	ide_hwif_t *hwif = drive->hwif;
+	struct it821x_dev *itdev = ide_get_hwifdata(hwif);
+
+	u8 unit = drive->select.b.unit;
+	ide_drive_t *pair = &hwif->drives[1-unit];
+
+	int clock, altclock;
+	u8 v;
+	int sel = 0;
+
+	if(itdev->want[0][0] > itdev->want[1][0]) {
+		clock = itdev->want[0][1];
+		altclock = itdev->want[1][1];
+	} else {
+		clock = itdev->want[1][1];
+		altclock = itdev->want[0][1];
+	}
+
+	/* Master doesn't care does the slave ? */
+	if(clock == ATA_ANY)
+		clock = altclock;
+
+	/* Nobody cares - keep the same clock */
+	if(clock == ATA_ANY)
+		return;
+	/* No change */
+	if(clock == itdev->clock_mode)
+		return;
+
+	/* Load this into the controller ? */
+	if(clock == ATA_66)
+		itdev->clock_mode = ATA_66;
+	else {
+		itdev->clock_mode = ATA_50;
+		sel = 1;
+	}
+	pci_read_config_byte(hwif->pci_dev, 0x50, &v);
+	v &= ~(1 << (1 + hwif->channel));
+	v |= sel << (1 + hwif->channel);
+	pci_write_config_byte(hwif->pci_dev, 0x50, v);
+
+	/*
+	 *	Reprogram the UDMA/PIO of the pair drive for the switch
+	 *	MWDMA will be dealt with by the dma switcher
+	 */
+	if(pair && itdev->udma[1-unit] != UDMA_OFF) {
+		it821x_program_udma(pair, itdev->udma[1-unit]);
+		it821x_program(pair, itdev->pio[1-unit]);
+	}
+	/*
+	 *	Reprogram the UDMA/PIO of our drive for the switch.
+	 *	MWDMA will be dealt with by the dma switcher
+	 */
+	if(itdev->udma[unit] != UDMA_OFF) {
+		it821x_program_udma(drive, itdev->udma[unit]);
+		it821x_program(drive, itdev->pio[unit]);
+	}
+}
+
+/**
+ *	it821x_ratemask	-	Compute available modes
+ *	@drive: IDE drive
+ *
+ *	Compute the available speeds for the devices on the interface. This
+ *	is all modes to ATA133 clipped by drive cable setup.
+ */
+
+static u8 it821x_ratemask (ide_drive_t *drive)
+{
+	u8 mode	= 4;
+	if (!eighty_ninty_three(drive))
+		mode = min(mode, (u8)1);
+	return mode;
+}
+
+/**
+ *	it821x_tuneproc	-	tune a drive
+ *	@drive: drive to tune
+ *	@mode_wanted: the target operating mode
+ *
+ *	Load the timing settings for this device mode into the
+ *	controller. By the time we are called the mode has been
+ *	modified as neccessary to handle the absence of seperate
+ *	master/slave timers for MWDMA/PIO.
+ *
+ *	This code is only used in pass through mode.
+ */
+
+static void it821x_tuneproc (ide_drive_t *drive, byte mode_wanted)
+{
+	ide_hwif_t *hwif	= drive->hwif;
+	struct it821x_dev *itdev = ide_get_hwifdata(hwif);
+	int unit = drive->select.b.unit;
+
+	/* Spec says 89 ref driver uses 88 */
+	static u16 pio[]	= { 0xAA88, 0xA382, 0xA181, 0x3332, 0x3121 };
+	static u8 pio_want[]    = { ATA_66, ATA_66, ATA_66, ATA_66, ATA_ANY };
+
+	if(itdev->smart)
+		return;
+
+	/* We prefer 66Mhz clock for PIO 0-3, don't care for PIO4 */
+	itdev->want[unit][1] = pio_want[mode_wanted];
+	itdev->want[unit][0] = 1;	/* PIO is lowest priority */
+	itdev->pio[unit] = pio[mode_wanted];
+	it821x_clock_strategy(drive);
+	it821x_program(drive, itdev->pio[unit]);
+}
+
+/**
+ *	it821x_tune_mwdma	-	tune a channel for MWDMA
+ *	@drive: drive to set up
+ *	@mode_wanted: the target operating mode
+ *
+ *	Load the timing settings for this device mode into the
+ *	controller when doing MWDMA in pass through mode. The caller
+ *	must manage the whole lack of per device MWDMA/PIO timings and
+ *	the shared MWDMA/PIO timing register.
+ */
+
+static void it821x_tune_mwdma (ide_drive_t *drive, byte mode_wanted)
+{
+	ide_hwif_t *hwif	= drive->hwif;
+	struct it821x_dev *itdev = (void *)ide_get_hwifdata(hwif);
+	int unit = drive->select.b.unit;
+	int channel = hwif->channel;
+	u8 conf;
+
+	static u16 dma[]	= { 0x8866, 0x3222, 0x3121 };
+	static u8 mwdma_want[]	= { ATA_ANY, ATA_66, ATA_ANY };
+
+	itdev->want[unit][1] = mwdma_want[mode_wanted];
+	itdev->want[unit][0] = 2;	/* MWDMA is low priority */
+	itdev->mwdma[unit] = dma[mode_wanted];
+	itdev->udma[unit] = UDMA_OFF;
+
+	/* UDMA bits off - Revision 0x10 do them in pairs */
+	pci_read_config_byte(hwif->pci_dev, 0x50, &conf);
+	if(itdev->timing10)
+		conf |= channel ? 0x60: 0x18;
+	else
+		conf |= 1 << (3 + 2 * channel + unit);
+	pci_write_config_byte(hwif->pci_dev, 0x50, conf);
+
+	it821x_clock_strategy(drive);
+	/* FIXME: do we need to program this ? */
+	/* it821x_program(drive, itdev->mwdma[unit]); */
+}
+
+/**
+ *	it821x_tune_udma	-	tune a channel for UDMA
+ *	@drive: drive to set up
+ *	@mode_wanted: the target operating mode
+ *
+ *	Load the timing settings for this device mode into the
+ *	controller when doing UDMA modes in pass through.
+ */
+
+static void it821x_tune_udma (ide_drive_t *drive, byte mode_wanted)
+{
+	ide_hwif_t *hwif	= drive->hwif;
+	struct it821x_dev *itdev = ide_get_hwifdata(hwif);
+	int unit = drive->select.b.unit;
+	int channel = hwif->channel;
+	u8 conf;
+
+	static u16 udma[]	= { 0x4433, 0x4231, 0x3121, 0x2121, 0x1111, 0x2211, 0x1111 };
+	static u8 udma_want[]	= { ATA_ANY, ATA_50, ATA_ANY, ATA_66, ATA_66, ATA_50, ATA_66 };
+
+	itdev->want[unit][1] = udma_want[mode_wanted];
+	itdev->want[unit][0] = 3;	/* UDMA is high priority */
+	itdev->mwdma[unit] = MWDMA_OFF;
+	itdev->udma[unit] = udma[mode_wanted];
+	if(mode_wanted >= 5)
+		itdev->udma[unit] |= 0x8080;	/* UDMA 5/6 select on */
+
+	/* UDMA on. Again revision 0x10 must do the pair */
+	pci_read_config_byte(hwif->pci_dev, 0x50, &conf);
+	if(itdev->timing10)
+		conf &= channel ? 0x9F: 0xE7;
+	else
+		conf &= ~ (1 << (3 + 2 * channel + unit));
+	pci_write_config_byte(hwif->pci_dev, 0x50, conf);
+
+	it821x_clock_strategy(drive);
+	it821x_program_udma(drive, itdev->udma[unit]);
+
+}
+
+/**
+ *	config_it821x_chipset_for_pio	-	set drive timings
+ *	@drive: drive to tune
+ *	@speed we want
+ *
+ *	Compute the best pio mode we can for a given device. We must
+ *	pick a speed that does not cause problems with the other device
+ *	on the cable.
+ */
+
+static void config_it821x_chipset_for_pio (ide_drive_t *drive, byte set_speed)
+{
+	u8 unit = drive->select.b.unit;
+	ide_hwif_t *hwif = drive->hwif;
+	ide_drive_t *pair = &hwif->drives[1-unit];
+	u8 speed = 0, set_pio	= ide_get_best_pio_mode(drive, 255, 5, NULL);
+	u8 pair_pio;
+
+	/* We have to deal with this mess in pairs */
+	if(pair != NULL) {
+		pair_pio = ide_get_best_pio_mode(pair, 255, 5, NULL);
+		/* Trim PIO to the slowest of the master/slave */
+		if(pair_pio < set_pio)
+			set_pio = pair_pio;
+	}
+	it821x_tuneproc(drive, set_pio);
+	speed = XFER_PIO_0 + set_pio;
+	/* XXX - We trim to the lowest of the pair so the other drive
+	   will always be fine at this point until we do hotplug passthru */
+
+	if (set_speed)
+		(void) ide_config_drive_speed(drive, speed);
+}
+
+/**
+ *	it821x_dma_read	-	DMA hook
+ *	@drive: drive for DMA
+ *
+ *	The IT821x has a single timing register for MWDMA and for PIO
+ *	operations. As we flip back and forth we have to reload the
+ *	clock. In addition the rev 0x10 device only works if the same
+ *	timing value is loaded into the master and slave UDMA clock
+ * 	so we must also reload that.
+ *
+ *	FIXME: we could figure out in advance if we need to do reloads
+ */
+
+static void it821x_dma_start(ide_drive_t *drive)
+{
+	ide_hwif_t *hwif = drive->hwif;
+	struct it821x_dev *itdev = ide_get_hwifdata(hwif);
+	int unit = drive->select.b.unit;
+	if(itdev->mwdma[unit] != MWDMA_OFF)
+		it821x_program(drive, itdev->mwdma[unit]);
+	else if(itdev->udma[unit] != UDMA_OFF && itdev->timing10)
+		it821x_program_udma(drive, itdev->udma[unit]);
+	ide_dma_start(drive);
+}
+
+/**
+ *	it821x_dma_write	-	DMA hook
+ *	@drive: drive for DMA stop
+ *
+ *	The IT821x has a single timing register for MWDMA and for PIO
+ *	operations. As we flip back and forth we have to reload the
+ *	clock.
+ */
+
+static int it821x_dma_end(ide_drive_t *drive)
+{
+	ide_hwif_t *hwif = drive->hwif;
+	int unit = drive->select.b.unit;
+	struct it821x_dev *itdev = ide_get_hwifdata(hwif);
+	int ret = __ide_dma_end(drive);
+	if(itdev->mwdma[unit] != MWDMA_OFF)
+		it821x_program(drive, itdev->pio[unit]);
+	return ret;
+}
+
+
+/**
+ *	it821x_tune_chipset	-	set controller timings
+ *	@drive: Drive to set up
+ *	@xferspeed: speed we want to achieve
+ *
+ *	Tune the ITE chipset for the desired mode. If we can't achieve
+ *	the desired mode then tune for a lower one, but ultimately
+ *	make the thing work.
+ */
+
+static int it821x_tune_chipset (ide_drive_t *drive, byte xferspeed)
+{
+
+	ide_hwif_t *hwif	= drive->hwif;
+	struct it821x_dev *itdev = ide_get_hwifdata(hwif);
+	u8 speed		= ide_rate_filter(it821x_ratemask(drive), xferspeed);
+
+	if(!itdev->smart) {
+		switch(speed) {
+			case XFER_PIO_4:
+			case XFER_PIO_3:
+			case XFER_PIO_2:
+			case XFER_PIO_1:
+			case XFER_PIO_0:
+				it821x_tuneproc(drive, (speed - XFER_PIO_0));
+				break;
+			/* MWDMA tuning is really hard because our MWDMA and PIO
+			   timings are kept in the same place. We can switch in the
+			   host dma on/off callbacks */
+			case XFER_MW_DMA_2:
+			case XFER_MW_DMA_1:
+			case XFER_MW_DMA_0:
+				it821x_tune_mwdma(drive, (speed - XFER_MW_DMA_0));
+				break;
+			case XFER_UDMA_6:
+			case XFER_UDMA_5:
+			case XFER_UDMA_4:
+			case XFER_UDMA_3:
+			case XFER_UDMA_2:
+			case XFER_UDMA_1:
+			case XFER_UDMA_0:
+				it821x_tune_udma(drive, (speed - XFER_UDMA_0));
+				break;
+			default:
+				return 1;
+		}
+	}
+	/*
+	 *	In smart mode the clocking is done by the host controller
+	 * 	snooping the mode we picked. The rest of it is not our problem
+	 */
+	return ide_config_drive_speed(drive, speed);
+}
+
+/**
+ *	config_chipset_for_dma	-	configure for DMA
+ *	@drive: drive to configure
+ *
+ *	Called by the IDE layer when it wants the timings set up.
+ */
+
+static int config_chipset_for_dma (ide_drive_t *drive)
+{
+	u8 speed	= ide_dma_speed(drive, it821x_ratemask(drive));
+
+	config_it821x_chipset_for_pio(drive, !speed);
+	it821x_tune_chipset(drive, speed);
+	return ide_dma_enable(drive);
+}
+
+/**
+ *	it821x_configure_drive_for_dma	-	set up for DMA transfers
+ *	@drive: drive we are going to set up
+ *
+ *	Set up the drive for DMA, tune the controller and drive as
+ *	required. If the drive isn't suitable for DMA or we hit
+ *	other problems then we will drop down to PIO and set up
+ *	PIO appropriately
+ */
+
+static int it821x_config_drive_for_dma (ide_drive_t *drive)
+{
+	ide_hwif_t *hwif	= drive->hwif;
+
+	if (ide_use_dma(drive)) {
+		if (config_chipset_for_dma(drive))
+			return hwif->ide_dma_on(drive);
+	}
+	config_it821x_chipset_for_pio(drive, 1);
+	return hwif->ide_dma_off_quietly(drive);
+}
+
+/**
+ *	ata66_it821x	-	check for 80 pin cable
+ *	@hwif: interface to check
+ *
+ *	Check for the presence of an ATA66 capable cable on the
+ *	interface. Problematic as it seems some cards don't have
+ *	the needed logic onboard.
+ */
+
+static unsigned int __devinit ata66_it821x(ide_hwif_t *hwif)
+{
+	/* The reference driver also only does disk side */
+	return 1;
+}
+
+/**
+ *	it821x_fixup	-	post init callback
+ *	@hwif: interface
+ *
+ *	This callback is run after the drives have been probed but
+ *	before anything gets attached. It allows drivers to do any
+ *	final tuning that is needed, or fixups to work around bugs.
+ */
+
+static void __devinit it821x_fixups(ide_hwif_t *hwif)
+{
+	struct it821x_dev *itdev = ide_get_hwifdata(hwif);
+	int i;
+
+	if(!itdev->smart) {
+		/*
+		 *	If we are in pass through mode then not much
+		 *	needs to be done, but we do bother to clear the
+		 *	IRQ mask as we may well be in PIO (eg rev 0x10)
+		 *	for now and we know unmasking is safe on this chipset.
+		 */
+		for (i = 0; i < 2; i++) {
+			ide_drive_t *drive = &hwif->drives[i];
+			if(drive->present)
+				drive->unmask = 1;
+		}
+		return;
+	}
+	/*
+	 *	Perform fixups on smart mode. We need to "lose" some
+	 *	capabilities the firmware lacks but does not filter, and
+	 *	also patch up some capability bits that it forgets to set
+	 *	in RAID mode.
+	 */
+
+	for(i = 0; i < 2; i++) {
+		ide_drive_t *drive = &hwif->drives[i];
+		struct hd_driveid *id;
+		u16 *idbits;
+
+		if(!drive->present)
+			continue;
+		id = drive->id;
+		idbits = (u16 *)drive->id;
+
+		/* Check for RAID v native */
+		if(strstr(id->model, "Integrated Technology Express")) {
+			/* In raid mode the ident block is slightly buggy
+			   We need to set the bits so that the IDE layer knows
+			   LBA28. LBA48 and DMA ar valid */
+			id->capability |= 3;		/* LBA28, DMA */
+			id->command_set_2 |= 0x0400;	/* LBA48 valid */
+			id->cfs_enable_2 |= 0x0400;	/* LBA48 on */
+			/* Reporting logic */
+			printk(KERN_INFO "%s: IT8212 %sRAID %d volume",
+				drive->name,
+				idbits[147] ? "Bootable ":"",
+				idbits[129]);
+				if(idbits[129] != 1)
+					printk("(%dK stripe)", idbits[146]);
+				printk(".\n");
+			/* Now the core code will have wrongly decided no DMA
+			   so we need to fix this */
+			hwif->ide_dma_off_quietly(drive);
+#ifdef CONFIG_IDEDMA_ONLYDISK
+			if (drive->media == ide_disk)
+#endif
+				hwif->ide_dma_check(drive);
+		} else {
+			/* Non RAID volume. Fixups to stop the core code
+			   doing unsupported things */
+			id->field_valid &= 1;
+			id->queue_depth = 0;
+			id->command_set_1 = 0;
+			id->command_set_2 &= 0xC400;
+			id->cfsse &= 0xC000;
+			id->cfs_enable_1 = 0;
+			id->cfs_enable_2 &= 0xC400;
+			id->csf_default &= 0xC000;
+			id->word127 = 0;
+			id->dlf = 0;
+			id->csfo = 0;
+			id->cfa_power = 0;
+			printk(KERN_INFO "%s: Performing identify fixups.\n",
+				drive->name);
+		}
+	}
+
+}
+
+/**
+ *	init_hwif_it821x	-	set up hwif structs
+ *	@hwif: interface to set up
+ *
+ *	We do the basic set up of the interface structure. The IT8212
+ *	requires several custom handlers so we override the default
+ *	ide DMA handlers appropriately
+ */
+
+static void __devinit init_hwif_it821x(ide_hwif_t *hwif)
+{
+	struct it821x_dev *idev = kmalloc(sizeof(struct it821x_dev), GFP_KERNEL);
+	u8 conf;
+
+	if(idev == NULL) {
+		printk(KERN_ERR "it821x: out of memory, falling back to legacy behaviour.\n");
+		goto fallback;
+	}
+	memset(idev, 0, sizeof(struct it821x_dev));
+	ide_set_hwifdata(hwif, idev);
+
+	pci_read_config_byte(hwif->pci_dev, 0x50, &conf);
+	if(conf & 1) {
+		idev->smart = 1;
+		hwif->atapi_dma = 0;
+		/* Long I/O's although allowed in LBA48 space cause the
+		   onboard firmware to enter the twighlight zone */
+		hwif->rqsize = 256;
+	}
+
+	/* Pull the current clocks from 0x50 also */
+	if (conf & (1 << (1 + hwif->channel)))
+		idev->clock_mode = ATA_50;
+	else
+		idev->clock_mode = ATA_66;
+
+	idev->want[0][1] = ATA_ANY;
+	idev->want[1][1] = ATA_ANY;
+
+	/*
+	 *	Not in the docs but according to the reference driver
+	 *	this is neccessary.
+	 */
+
+	pci_read_config_byte(hwif->pci_dev, 0x08, &conf);
+	if(conf == 0x10) {
+		idev->timing10 = 1;
+		hwif->atapi_dma = 0;
+		if(!idev->smart)
+			printk(KERN_WARNING "it821x: Revision 0x10, workarounds activated.\n");
+	}
+
+	hwif->speedproc = &it821x_tune_chipset;
+	hwif->tuneproc	= &it821x_tuneproc;
+
+	/* MWDMA/PIO clock switching for pass through mode */
+	if(!idev->smart) {
+		hwif->dma_start = &it821x_dma_start;
+		hwif->ide_dma_end = &it821x_dma_end;
+	}
+
+	hwif->drives[0].autotune = 1;
+	hwif->drives[1].autotune = 1;
+
+	if (!hwif->dma_base)
+		goto fallback;
+
+	hwif->ultra_mask = 0x7f;
+	hwif->mwdma_mask = 0x07;
+	hwif->swdma_mask = 0x07;
+
+	hwif->ide_dma_check = &it821x_config_drive_for_dma;
+	if (!(hwif->udma_four))
+		hwif->udma_four = ata66_it821x(hwif);
+
+	/*
+	 *	The BIOS often doesn't set up DMA on this controller
+	 *	so we always do it.
+	 */
+
+	hwif->autodma = 1;
+	hwif->drives[0].autodma = hwif->autodma;
+	hwif->drives[1].autodma = hwif->autodma;
+	return;
+fallback:
+	hwif->autodma = 0;
+	return;
+}
+
+static void __devinit it8212_disable_raid(struct pci_dev *dev)
+{
+	/* Reset local CPU, and set BIOS not ready */
+	pci_write_config_byte(dev, 0x5E, 0x01);
+
+	/* Set to bypass mode, and reset PCI bus */
+	pci_write_config_byte(dev, 0x50, 0x00);
+	pci_write_config_word(dev, PCI_COMMAND,
+			      PCI_COMMAND_PARITY | PCI_COMMAND_IO |
+			      PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
+	pci_write_config_word(dev, 0x40, 0xA0F3);
+
+	pci_write_config_dword(dev,0x4C, 0x02040204);
+	pci_write_config_byte(dev, 0x42, 0x36);
+	pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0);
+}
+
+static unsigned int __devinit init_chipset_it821x(struct pci_dev *dev, const char *name)
+{
+	u8 conf;
+	static char *mode[2] = { "pass through", "smart" };
+
+	/* Force the card into bypass mode if so requested */
+	if (it8212_noraid) {
+		printk(KERN_INFO "it8212: forcing bypass mode.\n");
+		it8212_disable_raid(dev);
+	}
+	pci_read_config_byte(dev, 0x50, &conf);
+	printk(KERN_INFO "it821x: controller in %s mode.\n", mode[conf & 1]);
+	return 0;
+}
+
+
+#define DECLARE_ITE_DEV(name_str)			\
+	{						\
+		.name		= name_str,		\
+		.init_chipset	= init_chipset_it821x,	\
+		.init_hwif	= init_hwif_it821x,	\
+		.channels	= 2,			\
+		.autodma	= AUTODMA,		\
+		.bootable	= ON_BOARD,		\
+		.fixup	 	= it821x_fixups		\
+	}
+
+static ide_pci_device_t it821x_chipsets[] __devinitdata = {
+	/* 0 */ DECLARE_ITE_DEV("IT8212"),
+};
+
+/**
+ *	it821x_init_one	-	pci layer discovery entry
+ *	@dev: PCI device
+ *	@id: ident table entry
+ *
+ *	Called by the PCI code when it finds an ITE821x controller.
+ *	We then use the IDE PCI generic helper to do most of the work.
+ */
+
+static int __devinit it821x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
+{
+	ide_setup_pci_device(dev, &it821x_chipsets[id->driver_data]);
+	return 0;
+}
+
+static struct pci_device_id it821x_pci_tbl[] = {
+	{ PCI_VENDOR_ID_ITE, PCI_DEVICE_ID_ITE_8211,  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{ PCI_VENDOR_ID_ITE, PCI_DEVICE_ID_ITE_8212,  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{ 0, },
+};
+
+MODULE_DEVICE_TABLE(pci, it821x_pci_tbl);
+
+static struct pci_driver driver = {
+	.name		= "ITE821x IDE",
+	.id_table	= it821x_pci_tbl,
+	.probe		= it821x_init_one,
+};
+
+static int __init it821x_ide_init(void)
+{
+	return ide_pci_register_driver(&driver);
+}
+
+module_init(it821x_ide_init);
+
+module_param_named(noraid, it8212_noraid, int, S_IRUGO);
+MODULE_PARM_DESC(it8212_noraid, "Force card into bypass mode");
+
+MODULE_AUTHOR("Alan Cox");
+MODULE_DESCRIPTION("PCI driver module for the ITE 821x");
+MODULE_LICENSE("GPL");
diff --git a/drivers/ide/pci/ns87415.c b/drivers/ide/pci/ns87415.c
--- a/drivers/ide/pci/ns87415.c
+++ b/drivers/ide/pci/ns87415.c
@@ -195,7 +195,7 @@ static int ns87415_ide_dma_check (ide_dr
 	return __ide_dma_check(drive);
 }
 
-static void __init init_hwif_ns87415 (ide_hwif_t *hwif)
+static void __devinit init_hwif_ns87415 (ide_hwif_t *hwif)
 {
 	struct pci_dev *dev = hwif->pci_dev;
 	unsigned int ctrl, using_inta;
diff --git a/drivers/ide/pci/opti621.c b/drivers/ide/pci/opti621.c
--- a/drivers/ide/pci/opti621.c
+++ b/drivers/ide/pci/opti621.c
@@ -326,7 +326,7 @@ static void opti621_tune_drive (ide_driv
 /*
  * init_hwif_opti621() is called once for each hwif found at boot.
  */
-static void __init init_hwif_opti621 (ide_hwif_t *hwif)
+static void __devinit init_hwif_opti621 (ide_hwif_t *hwif)
 {
 	hwif->autodma = 0;
 	hwif->drives[0].drive_data = PIO_DONT_KNOW;
diff --git a/drivers/ide/pci/sc1200.c b/drivers/ide/pci/sc1200.c
--- a/drivers/ide/pci/sc1200.c
+++ b/drivers/ide/pci/sc1200.c
@@ -459,7 +459,7 @@ printk("%s: SC1200: resume\n", hwif->nam
  * This gets invoked by the IDE driver once for each channel,
  * and performs channel-specific pre-initialization before drive probing.
  */
-static void __init init_hwif_sc1200 (ide_hwif_t *hwif)
+static void __devinit init_hwif_sc1200 (ide_hwif_t *hwif)
 {
 	if (hwif->mate)
 		hwif->serialized = hwif->mate->serialized = 1;
diff --git a/drivers/ide/pci/serverworks.c b/drivers/ide/pci/serverworks.c
--- a/drivers/ide/pci/serverworks.c
+++ b/drivers/ide/pci/serverworks.c
@@ -21,6 +21,9 @@
  *
  *   CSB6: `Champion South Bridge' IDE Interface (optional: third channel)
  *
+ *   HT1000: AKA BCM5785 - Hypertransport Southbridge for Opteron systems. IDE
+ *   controller same as the CSB6. Single channel ATA100 only.
+ *
  * Documentation:
  *	Available under NDA only. Errata info very hard to get.
  *
@@ -71,6 +74,8 @@ static u8 svwks_ratemask (ide_drive_t *d
 	if (!svwks_revision)
 		pci_read_config_byte(dev, PCI_REVISION_ID, &svwks_revision);
 
+	if (dev->device == PCI_DEVICE_ID_SERVERWORKS_HT1000IDE)
+		return 2;
 	if (dev->device == PCI_DEVICE_ID_SERVERWORKS_OSB4IDE) {
 		u32 reg = 0;
 		if (isa_dev)
@@ -109,6 +114,7 @@ static u8 svwks_csb_check (struct pci_de
 		case PCI_DEVICE_ID_SERVERWORKS_CSB5IDE:
 		case PCI_DEVICE_ID_SERVERWORKS_CSB6IDE:
 		case PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2:
+		case PCI_DEVICE_ID_SERVERWORKS_HT1000IDE:
 			return 1;
 		default:
 			break;
@@ -438,11 +444,18 @@ static unsigned int __devinit init_chips
 			btr |= (svwks_revision >= SVWKS_CSB5_REVISION_NEW) ? 0x3 : 0x2;
 		pci_write_config_byte(dev, 0x5A, btr);
 	}
+	/* Setup HT1000 SouthBridge Controller - Single Channel Only */
+	else if (dev->device == PCI_DEVICE_ID_SERVERWORKS_HT1000IDE) {
+		pci_read_config_byte(dev, 0x5A, &btr);
+		btr &= ~0x40;
+		btr |= 0x3;
+		pci_write_config_byte(dev, 0x5A, btr);
+	}
 
 	return (dev->irq) ? dev->irq : 0;
 }
 
-static unsigned int __init ata66_svwks_svwks (ide_hwif_t *hwif)
+static unsigned int __devinit ata66_svwks_svwks (ide_hwif_t *hwif)
 {
 	return 1;
 }
@@ -454,7 +467,7 @@ static unsigned int __init ata66_svwks_s
  * Bit 14 clear = primary IDE channel does not have 80-pin cable.
  * Bit 14 set   = primary IDE channel has 80-pin cable.
  */
-static unsigned int __init ata66_svwks_dell (ide_hwif_t *hwif)
+static unsigned int __devinit ata66_svwks_dell (ide_hwif_t *hwif)
 {
 	struct pci_dev *dev = hwif->pci_dev;
 	if (dev->subsystem_vendor == PCI_VENDOR_ID_DELL &&
@@ -472,7 +485,7 @@ static unsigned int __init ata66_svwks_d
  *
  * WARNING: this only works on Alpine hardware!
  */
-static unsigned int __init ata66_svwks_cobalt (ide_hwif_t *hwif)
+static unsigned int __devinit ata66_svwks_cobalt (ide_hwif_t *hwif)
 {
 	struct pci_dev *dev = hwif->pci_dev;
 	if (dev->subsystem_vendor == PCI_VENDOR_ID_SUN &&
@@ -483,7 +496,7 @@ static unsigned int __init ata66_svwks_c
 	return 0;
 }
 
-static unsigned int __init ata66_svwks (ide_hwif_t *hwif)
+static unsigned int __devinit ata66_svwks (ide_hwif_t *hwif)
 {
 	struct pci_dev *dev = hwif->pci_dev;
 
@@ -573,7 +586,7 @@ static int __devinit init_setup_svwks (s
 	return ide_setup_pci_device(dev, d);
 }
 
-static int __init init_setup_csb6 (struct pci_dev *dev, ide_pci_device_t *d)
+static int __devinit init_setup_csb6 (struct pci_dev *dev, ide_pci_device_t *d)
 {
 	if (!(PCI_FUNC(dev->devfn) & 1)) {
 		d->bootable = NEVER_BOARD;
@@ -629,6 +642,15 @@ static ide_pci_device_t serverworks_chip
 		.channels	= 1,	/* 2 */
 		.autodma	= AUTODMA,
 		.bootable	= ON_BOARD,
+	},{	/* 4 */
+		.name		= "SvrWks HT1000",
+		.init_setup	= init_setup_svwks,
+		.init_chipset	= init_chipset_svwks,
+		.init_hwif	= init_hwif_svwks,
+		.init_dma	= init_dma_svwks,
+		.channels	= 1,	/* 2 */
+		.autodma	= AUTODMA,
+		.bootable	= ON_BOARD,
 	}
 };
 
@@ -653,6 +675,7 @@ static struct pci_device_id svwks_pci_tb
 	{ PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB5IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
 	{ PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB6IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2},
 	{ PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3},
+	{ PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT1000IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4},
 	{ 0, },
 };
 MODULE_DEVICE_TABLE(pci, svwks_pci_tbl);
diff --git a/drivers/ide/pci/sgiioc4.c b/drivers/ide/pci/sgiioc4.c
--- a/drivers/ide/pci/sgiioc4.c
+++ b/drivers/ide/pci/sgiioc4.c
@@ -34,7 +34,7 @@
 #include <linux/mm.h>
 #include <linux/ioport.h>
 #include <linux/blkdev.h>
-#include <linux/ioc4_common.h>
+#include <linux/ioc4.h>
 #include <asm/io.h>
 
 #include <linux/ide.h>
@@ -715,14 +715,34 @@ static ide_pci_device_t sgiioc4_chipsets
 };
 
 int
-ioc4_ide_attach_one(struct pci_dev *dev, const struct pci_device_id *id)
+ioc4_ide_attach_one(struct ioc4_driver_data *idd)
 {
-	return pci_init_sgiioc4(dev, &sgiioc4_chipsets[id->driver_data]);
+	return pci_init_sgiioc4(idd->idd_pdev,
+				&sgiioc4_chipsets[idd->idd_pci_id->driver_data]);
 }
 
+static struct ioc4_submodule ioc4_ide_submodule = {
+	.is_name = "IOC4_ide",
+	.is_owner = THIS_MODULE,
+	.is_probe = ioc4_ide_attach_one,
+/*	.is_remove = ioc4_ide_remove_one,	*/
+};
+
+static int __devinit
+ioc4_ide_init(void)
+{
+	return ioc4_register_submodule(&ioc4_ide_submodule);
+}
+
+static void __devexit
+ioc4_ide_exit(void)
+{
+	ioc4_unregister_submodule(&ioc4_ide_submodule);
+}
+
+module_init(ioc4_ide_init);
+module_exit(ioc4_ide_exit);
 
 MODULE_AUTHOR("Aniket Malatpure - Silicon Graphics Inc. (SGI)");
 MODULE_DESCRIPTION("IDE PCI driver module for SGI IOC4 Base-IO Card");
 MODULE_LICENSE("GPL");
-
-EXPORT_SYMBOL(ioc4_ide_attach_one);
diff --git a/drivers/ide/pci/sl82c105.c b/drivers/ide/pci/sl82c105.c
--- a/drivers/ide/pci/sl82c105.c
+++ b/drivers/ide/pci/sl82c105.c
@@ -386,7 +386,7 @@ static unsigned int sl82c105_bridge_revi
  * channel 0 here at least, but channel 1 has to be enabled by
  * firmware or arch code. We still set both to 16 bits mode.
  */
-static unsigned int __init init_chipset_sl82c105(struct pci_dev *dev, const char *msg)
+static unsigned int __devinit init_chipset_sl82c105(struct pci_dev *dev, const char *msg)
 {
 	u32 val;
 
@@ -399,7 +399,7 @@ static unsigned int __init init_chipset_
 	return dev->irq;
 }
 
-static void __init init_dma_sl82c105(ide_hwif_t *hwif, unsigned long dma_base)
+static void __devinit init_dma_sl82c105(ide_hwif_t *hwif, unsigned long dma_base)
 {
 	unsigned int rev;
 	u8 dma_state;
@@ -431,7 +431,7 @@ static void __init init_dma_sl82c105(ide
  * Initialise the chip
  */
 
-static void __init init_hwif_sl82c105(ide_hwif_t *hwif)
+static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif)
 {
 	struct pci_dev *dev = hwif->pci_dev;
 	u32 val;
diff --git a/drivers/ide/pci/slc90e66.c b/drivers/ide/pci/slc90e66.c
--- a/drivers/ide/pci/slc90e66.c
+++ b/drivers/ide/pci/slc90e66.c
@@ -196,7 +196,7 @@ fast_ata_pio:
 }
 #endif /* CONFIG_BLK_DEV_IDEDMA */
 
-static void __init init_hwif_slc90e66 (ide_hwif_t *hwif)
+static void __devinit init_hwif_slc90e66 (ide_hwif_t *hwif)
 {
 	u8 reg47 = 0;
 	u8 mask = hwif->channel ? 0x01 : 0x02;  /* bit0:Primary */
diff --git a/drivers/ide/pci/triflex.c b/drivers/ide/pci/triflex.c
--- a/drivers/ide/pci/triflex.c
+++ b/drivers/ide/pci/triflex.c
@@ -130,7 +130,7 @@ static int triflex_config_drive_xfer_rat
 	return hwif->ide_dma_off_quietly(drive);
 }
 
-static void __init init_hwif_triflex(ide_hwif_t *hwif)
+static void __devinit init_hwif_triflex(ide_hwif_t *hwif)
 {
 	hwif->tuneproc = &triflex_tune_drive;
 	hwif->speedproc = &triflex_tune_chipset;
diff --git a/drivers/ide/pci/trm290.c b/drivers/ide/pci/trm290.c
--- a/drivers/ide/pci/trm290.c
+++ b/drivers/ide/pci/trm290.c
@@ -5,7 +5,7 @@
  *  May be copied or modified under the terms of the GNU General Public License
  *
  *  June 22, 2004 - get rid of check_region
- *                  Jesper Juhl <juhl-lkml@dif.dk>
+ *                   - Jesper Juhl
  *
  */
 
diff --git a/drivers/ide/pci/via82cxxx.c b/drivers/ide/pci/via82cxxx.c
--- a/drivers/ide/pci/via82cxxx.c
+++ b/drivers/ide/pci/via82cxxx.c
@@ -415,7 +415,7 @@ static int via82cxxx_ide_dma_check (ide_
  *	and initialize its drive independent registers.
  */
 
-static unsigned int __init init_chipset_via82cxxx(struct pci_dev *dev, const char *name)
+static unsigned int __devinit init_chipset_via82cxxx(struct pci_dev *dev, const char *name)
 {
 	struct pci_dev *isa = NULL;
 	u8 t, v;
@@ -576,7 +576,7 @@ static unsigned int __init init_chipset_
 	return 0;
 }
 
-static void __init init_hwif_via82cxxx(ide_hwif_t *hwif)
+static void __devinit init_hwif_via82cxxx(ide_hwif_t *hwif)
 {
 	int i;
 
diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c
--- a/drivers/ide/ppc/pmac.c
+++ b/drivers/ide/ppc/pmac.c
@@ -1324,9 +1324,9 @@ pmac_ide_setup_device(pmac_ide_hwif_t *p
 	/* XXX FIXME: Media bay stuff need re-organizing */
 	if (np->parent && np->parent->name
 	    && strcasecmp(np->parent->name, "media-bay") == 0) {
-#ifdef CONFIG_PMAC_PBOOK
+#ifdef CONFIG_PMAC_MEDIABAY
 		media_bay_set_ide_infos(np->parent, pmif->regbase, pmif->irq, hwif->index);
-#endif /* CONFIG_PMAC_PBOOK */
+#endif /* CONFIG_PMAC_MEDIABAY */
 		pmif->mediabay = 1;
 		if (!bidp)
 			pmif->aapl_bus_id = 1;
@@ -1382,10 +1382,10 @@ pmac_ide_setup_device(pmac_ide_hwif_t *p
 	       hwif->index, model_name[pmif->kind], pmif->aapl_bus_id,
 	       pmif->mediabay ? " (mediabay)" : "", hwif->irq);
 			
-#ifdef CONFIG_PMAC_PBOOK
+#ifdef CONFIG_PMAC_MEDIABAY
 	if (pmif->mediabay && check_media_bay_by_base(pmif->regbase, MB_CD) == 0)
 		hwif->noprobe = 0;
-#endif /* CONFIG_PMAC_PBOOK */
+#endif /* CONFIG_PMAC_MEDIABAY */
 
 	hwif->sg_max_nents = MAX_DCMDS;
 
@@ -1419,7 +1419,7 @@ pmac_ide_setup_device(pmac_ide_hwif_t *p
  * Attach to a macio probed interface
  */
 static int __devinit
-pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_match *match)
+pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match)
 {
 	void __iomem *base;
 	unsigned long regbase;
@@ -1637,27 +1637,19 @@ pmac_ide_pci_resume(struct pci_dev *pdev
 	return rc;
 }
 
-static struct of_match pmac_ide_macio_match[] = 
+static struct of_device_id pmac_ide_macio_match[] = 
 {
 	{
 	.name 		= "IDE",
-	.type		= OF_ANY_MATCH,
-	.compatible	= OF_ANY_MATCH
 	},
 	{
 	.name 		= "ATA",
-	.type		= OF_ANY_MATCH,
-	.compatible	= OF_ANY_MATCH
 	},
 	{
-	.name 		= OF_ANY_MATCH,
 	.type		= "ide",
-	.compatible	= OF_ANY_MATCH
 	},
 	{
-	.name 		= OF_ANY_MATCH,
 	.type		= "ata",
-	.compatible	= OF_ANY_MATCH
 	},
 	{},
 };
@@ -1672,7 +1664,7 @@ static struct macio_driver pmac_ide_maci
 };
 
 static struct pci_device_id pmac_ide_pci_match[] = {
-	{ PCI_VENDOR_ID_APPLE, PCI_DEVIEC_ID_APPLE_UNI_N_ATA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{ PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_UNI_N_ATA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
 	{ PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_IPID_ATA100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
 	{ PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_K2_ATA100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
 	{ PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_SH_ATA,
diff --git a/drivers/ide/setup-pci.c b/drivers/ide/setup-pci.c
--- a/drivers/ide/setup-pci.c
+++ b/drivers/ide/setup-pci.c
@@ -229,6 +229,7 @@ second_chance_to_dma:
 			case PCI_DEVICE_ID_AMD_VIPER_7409:
 			case PCI_DEVICE_ID_CMD_643:
 			case PCI_DEVICE_ID_SERVERWORKS_CSB5IDE:
+			case PCI_DEVICE_ID_REVOLUTION:
 				simplex_stat = hwif->INB(dma_base + 2);
 				hwif->OUTB((simplex_stat&0x60),(dma_base + 2));
 				simplex_stat = hwif->INB(dma_base + 2);
@@ -847,7 +848,7 @@ static int __init ide_scan_pcidev(struct
 		d = list_entry(l, struct pci_driver, node);
 		if(d->id_table)
 		{
-			const struct pci_device_id *id = pci_match_device(d->id_table, dev);
+			const struct pci_device_id *id = pci_match_id(d->id_table, dev);
 			if(id != NULL)
 			{
 				if(d->probe(dev, id) >= 0)
diff --git a/drivers/ieee1394/Kconfig b/drivers/ieee1394/Kconfig
--- a/drivers/ieee1394/Kconfig
+++ b/drivers/ieee1394/Kconfig
@@ -66,6 +66,18 @@ config IEEE1394_CONFIG_ROM_IP1394
 	  with MacOSX and WinXP IP-over-1394), enable this option and the
 	  eth1394 option below.
 
+config IEEE1394_EXPORT_FULL_API
+	bool "Export all symbols of ieee1394's API"
+	depends on IEEE1394
+	default n
+	help
+	  Export all symbols of ieee1394's driver programming interface, even
+	  those that are not currently used by the standard IEEE 1394 drivers.
+
+	  This option does not affect the interface to userspace applications.
+	  Say Y here if you want to compile externally developed drivers that
+	  make extended use of ieee1394's API. It is otherwise safe to say N.
+
 comment "Device Drivers"
 	depends on IEEE1394
 
diff --git a/drivers/ieee1394/csr.c b/drivers/ieee1394/csr.c
--- a/drivers/ieee1394/csr.c
+++ b/drivers/ieee1394/csr.c
@@ -28,6 +28,7 @@
 #include "hosts.h"
 #include "ieee1394.h"
 #include "highlevel.h"
+#include "ieee1394_core.h"
 
 /* Module Parameters */
 /* this module parameter can be used to disable mapping of the FCP registers */
@@ -232,7 +233,7 @@ static void add_host(struct hpsb_host *h
 	host->csr.generation = 2;
 
 	bus_info[1] = __constant_cpu_to_be32(0x31333934);
-	bus_info[2] = cpu_to_be32((1 << CSR_IRMC_SHIFT) |
+	bus_info[2] = cpu_to_be32((hpsb_disable_irm ? 0 : 1 << CSR_IRMC_SHIFT) |
 				  (1 << CSR_CMC_SHIFT) |
 				  (1 << CSR_ISC_SHIFT) |
 				  (0 << CSR_BMC_SHIFT) |
diff --git a/drivers/ieee1394/csr1212.c b/drivers/ieee1394/csr1212.c
--- a/drivers/ieee1394/csr1212.c
+++ b/drivers/ieee1394/csr1212.c
@@ -209,7 +209,15 @@ void csr1212_init_local_csr(struct csr12
 {
 	static const int mr_map[] = { 4, 64, 1024, 0 };
 
+#ifdef __KERNEL__
+	BUG_ON(max_rom & ~0x3);
 	csr->max_rom = mr_map[max_rom];
+#else
+	if (max_rom & ~0x3) /* caller supplied invalid argument */
+		csr->max_rom = 0;
+	else
+		csr->max_rom = mr_map[max_rom];
+#endif
 	memcpy(csr->bus_info_data, bus_info_data, csr->bus_info_len);
 }
 
@@ -533,12 +541,15 @@ struct csr1212_keyval *csr1212_new_icon_
 	static const int pd[4] = { 0, 4, 16, 256 };
 	static const int cs[16] = { 4, 2 };
 	struct csr1212_keyval *kv;
-	int palette_size = pd[palette_depth] * cs[color_space];
+	int palette_size;
 	int pixel_size = (hscan * vscan + 3) & ~0x3;
 
-	if ((palette_depth && !palette) || !pixels)
+	if (!pixels || (!palette && palette_depth) ||
+	    (palette_depth & ~0x3) || (color_space & ~0xf))
 		return NULL;
 
+	palette_size = pd[palette_depth] * cs[color_space];
+
 	kv = csr1212_new_descriptor_leaf(1, 0, NULL,
 					 palette_size + pixel_size +
 					 CSR1212_ICON_DESCRIPTOR_LEAF_OVERHEAD);
@@ -760,9 +771,9 @@ static int csr1212_append_new_cache(stru
 	struct csr1212_csr_rom_cache *cache;
 	u_int64_t csr_addr;
 
-	if (!csr || !csr->ops->allocate_addr_range ||
-	    !csr->ops->release_addr)
-		return CSR1212_ENOMEM;
+	if (!csr || !csr->ops || !csr->ops->allocate_addr_range ||
+	    !csr->ops->release_addr || csr->max_rom < 1)
+		return CSR1212_EINVAL;
 
 	/* ROM size must be a multiple of csr->max_rom */
 	romsize = (romsize + (csr->max_rom - 1)) & ~(csr->max_rom - 1);
@@ -1145,6 +1156,8 @@ int csr1212_generate_csr_image(struct cs
 
 			/* Make sure the Extended ROM leaf is a multiple of
 			 * max_rom in size. */
+			if (csr->max_rom < 1)
+				return CSR1212_EINVAL;
 			leaf_size = (cache->len + (csr->max_rom - 1)) &
 				~(csr->max_rom - 1);
 
@@ -1409,7 +1422,7 @@ int _csr1212_read_keyval(struct csr1212_
 	u_int32_t *cache_ptr;
 	u_int16_t kv_len = 0;
 
-	if (!csr || !kv)
+	if (!csr || !kv || csr->max_rom < 1)
 		return CSR1212_EINVAL;
 
 	/* First find which cache the data should be in (or go in if not read
@@ -1572,7 +1585,7 @@ int csr1212_parse_csr(struct csr1212_csr
 	struct csr1212_dentry *dentry;
 	int ret;
 
-	if (!csr || !csr->ops->bus_read)
+	if (!csr || !csr->ops || !csr->ops->bus_read)
 		return CSR1212_EINVAL;
 
 	ret = csr1212_parse_bus_info_block(csr);
@@ -1581,9 +1594,13 @@ int csr1212_parse_csr(struct csr1212_csr
 
 	if (!csr->ops->get_max_rom)
 		csr->max_rom = mr_map[0];	/* default value */
-	else
-		csr->max_rom = mr_map[csr->ops->get_max_rom(csr->bus_info_data,
-							    csr->private)];
+	else {
+		int i = csr->ops->get_max_rom(csr->bus_info_data,
+					      csr->private);
+		if (i & ~0x3)
+			return CSR1212_EINVAL;
+		csr->max_rom = mr_map[i];
+	}
 
 	csr->cache_head->layout_head = csr->root_kv;
 	csr->cache_head->layout_tail = csr->root_kv;
diff --git a/drivers/ieee1394/dma.c b/drivers/ieee1394/dma.c
--- a/drivers/ieee1394/dma.c
+++ b/drivers/ieee1394/dma.c
@@ -158,7 +158,7 @@ static inline int dma_region_find(struct
 
 dma_addr_t dma_region_offset_to_bus(struct dma_region *dma, unsigned long offset)
 {
-	unsigned long rem;
+	unsigned long rem = 0;
 
 	struct scatterlist *sg = &dma->sglist[dma_region_find(dma, offset, &rem)];
 	return sg_dma_address(sg) + rem;
diff --git a/drivers/ieee1394/dv1394.c b/drivers/ieee1394/dv1394.c
--- a/drivers/ieee1394/dv1394.c
+++ b/drivers/ieee1394/dv1394.c
@@ -2343,8 +2343,8 @@ static void dv1394_remove_host (struct h
 			dv1394_un_init(video);
 	} while (video != NULL);
 
-	class_simple_device_remove(MKDEV(
-		IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_DV1394 * 16 + (id<<2)));
+	class_device_destroy(hpsb_protocol_class,
+		MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_DV1394 * 16 + (id<<2)));
 	devfs_remove("ieee1394/dv/host%d/NTSC", id);
 	devfs_remove("ieee1394/dv/host%d/PAL", id);
 	devfs_remove("ieee1394/dv/host%d", id);
@@ -2361,7 +2361,7 @@ static void dv1394_add_host (struct hpsb
 
 	ohci = (struct ti_ohci *)host->hostdata;
 
-	class_simple_device_add(hpsb_protocol_class, MKDEV(
+	class_device_create(hpsb_protocol_class, MKDEV(
 		IEEE1394_MAJOR,	IEEE1394_MINOR_BLOCK_DV1394 * 16 + (id<<2)), 
 		NULL, "dv1394-%d", id);
 	devfs_mk_dir("ieee1394/dv/host%d", id);
diff --git a/drivers/ieee1394/eth1394.c b/drivers/ieee1394/eth1394.c
--- a/drivers/ieee1394/eth1394.c
+++ b/drivers/ieee1394/eth1394.c
@@ -89,7 +89,7 @@
 #define TRACE() printk(KERN_ERR "%s:%s[%d] ---- TRACE\n", driver_name, __FUNCTION__, __LINE__)
 
 static char version[] __devinitdata =
-	"$Rev: 1247 $ Ben Collins <bcollins@debian.org>";
+	"$Rev: 1264 $ Ben Collins <bcollins@debian.org>";
 
 struct fragment_info {
 	struct list_head list;
@@ -706,7 +706,7 @@ static void ether1394_host_reset (struct
 		return;
 
 	dev = hi->dev;
-	priv = netdev_priv(dev);
+	priv = (struct eth1394_priv *)netdev_priv(dev);
 
 	/* Reset our private host data, but not our mtu */
 	netif_stop_queue (dev);
@@ -1770,7 +1770,7 @@ fail:
 static void ether1394_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
 {
 	strcpy (info->driver, driver_name);
-	strcpy (info->version, "$Rev: 1247 $");
+	strcpy (info->version, "$Rev: 1264 $");
 	/* FIXME XXX provide sane businfo */
 	strcpy (info->bus_info, "ieee1394");
 }
diff --git a/drivers/ieee1394/ieee1394_core.c b/drivers/ieee1394/ieee1394_core.c
--- a/drivers/ieee1394/ieee1394_core.c
+++ b/drivers/ieee1394/ieee1394_core.c
@@ -52,7 +52,7 @@
 /*
  * Disable the nodemgr detection and config rom reading functionality.
  */
-static int disable_nodemgr = 0;
+static int disable_nodemgr;
 module_param(disable_nodemgr, int, 0444);
 MODULE_PARM_DESC(disable_nodemgr, "Disable nodemgr functionality.");
 
@@ -67,7 +67,7 @@ MODULE_LICENSE("GPL");
 
 /* Some globals used */
 const char *hpsb_speedto_str[] = { "S100", "S200", "S400", "S800", "S1600", "S3200" };
-struct class_simple *hpsb_protocol_class;
+struct class *hpsb_protocol_class;
 
 #ifdef CONFIG_IEEE1394_VERBOSEDEBUG
 static void dump_packet(const char *text, quadlet_t *data, int size)
@@ -520,6 +520,9 @@ int hpsb_send_packet(struct hpsb_packet 
 
 	if (!packet->no_waiter || packet->expect_response) {
 		atomic_inc(&packet->refcnt);
+		/* Set the initial "sendtime" to 10 seconds from now, to
+		   prevent premature expiry.  If a packet takes more than
+		   10 seconds to hit the wire, we have bigger problems :) */
 		packet->sendtime = jiffies + 10 * HZ;
 		skb_queue_tail(&host->pending_packet_queue, packet->skb);
 	}
@@ -1041,10 +1044,8 @@ static int hpsbpkt_thread(void *__hi)
 
 	while (1) {
 		if (down_interruptible(&khpsbpkt_sig)) {
-			if (current->flags & PF_FREEZE) {
-				refrigerator(0);
+			if (try_to_freeze())
 				continue;
-			}
 			printk("khpsbpkt: received unexpected signal?!\n" );
 			break;
 		}
@@ -1121,7 +1122,7 @@ static int __init ieee1394_init(void)
 	if (ret < 0)
 		goto release_all_bus;
 
-	hpsb_protocol_class = class_simple_create(THIS_MODULE, "ieee1394_protocol");
+	hpsb_protocol_class = class_create(THIS_MODULE, "ieee1394_protocol");
 	if (IS_ERR(hpsb_protocol_class)) {
 		ret = PTR_ERR(hpsb_protocol_class);
 		goto release_class_host;
@@ -1159,7 +1160,7 @@ static int __init ieee1394_init(void)
 cleanup_csr:
 	cleanup_csr();
 release_class_protocol:
-	class_simple_destroy(hpsb_protocol_class);
+	class_destroy(hpsb_protocol_class);
 release_class_host:
 	class_unregister(&hpsb_host_class);
 release_all_bus:
@@ -1189,7 +1190,7 @@ static void __exit ieee1394_cleanup(void
 
 	cleanup_csr();
 
-	class_simple_destroy(hpsb_protocol_class);
+	class_destroy(hpsb_protocol_class);
 	class_unregister(&hpsb_host_class);
 	for (i = 0; fw_bus_attrs[i]; i++)
 		bus_remove_file(&ieee1394_bus_type, fw_bus_attrs[i]);
@@ -1225,9 +1226,7 @@ EXPORT_SYMBOL(hpsb_protocol_class);
 EXPORT_SYMBOL(hpsb_set_packet_complete_task);
 EXPORT_SYMBOL(hpsb_alloc_packet);
 EXPORT_SYMBOL(hpsb_free_packet);
-EXPORT_SYMBOL(hpsb_send_phy_config);
 EXPORT_SYMBOL(hpsb_send_packet);
-EXPORT_SYMBOL(hpsb_send_packet_and_wait);
 EXPORT_SYMBOL(hpsb_reset_bus);
 EXPORT_SYMBOL(hpsb_bus_reset);
 EXPORT_SYMBOL(hpsb_selfid_received);
@@ -1235,6 +1234,10 @@ EXPORT_SYMBOL(hpsb_selfid_complete);
 EXPORT_SYMBOL(hpsb_packet_sent);
 EXPORT_SYMBOL(hpsb_packet_received);
 EXPORT_SYMBOL_GPL(hpsb_disable_irm);
+#ifdef CONFIG_IEEE1394_EXPORT_FULL_API
+EXPORT_SYMBOL(hpsb_send_phy_config);
+EXPORT_SYMBOL(hpsb_send_packet_and_wait);
+#endif
 
 /** ieee1394_transactions.c **/
 EXPORT_SYMBOL(hpsb_get_tlabel);
@@ -1264,9 +1267,11 @@ EXPORT_SYMBOL(hpsb_destroy_hostinfo);
 EXPORT_SYMBOL(hpsb_set_hostinfo_key);
 EXPORT_SYMBOL(hpsb_get_hostinfo_bykey);
 EXPORT_SYMBOL(hpsb_set_hostinfo);
+EXPORT_SYMBOL(highlevel_host_reset);
+#ifdef CONFIG_IEEE1394_EXPORT_FULL_API
 EXPORT_SYMBOL(highlevel_add_host);
 EXPORT_SYMBOL(highlevel_remove_host);
-EXPORT_SYMBOL(highlevel_host_reset);
+#endif
 
 /** nodemgr.c **/
 EXPORT_SYMBOL(hpsb_node_fill_packet);
@@ -1274,7 +1279,9 @@ EXPORT_SYMBOL(hpsb_node_write);
 EXPORT_SYMBOL(hpsb_register_protocol);
 EXPORT_SYMBOL(hpsb_unregister_protocol);
 EXPORT_SYMBOL(ieee1394_bus_type);
+#ifdef CONFIG_IEEE1394_EXPORT_FULL_API
 EXPORT_SYMBOL(nodemgr_for_each_host);
+#endif
 
 /** csr.c **/
 EXPORT_SYMBOL(hpsb_update_config_rom);
@@ -1311,19 +1318,21 @@ EXPORT_SYMBOL(hpsb_iso_wake);
 EXPORT_SYMBOL(hpsb_iso_recv_flush);
 
 /** csr1212.c **/
-EXPORT_SYMBOL(csr1212_create_csr);
-EXPORT_SYMBOL(csr1212_init_local_csr);
-EXPORT_SYMBOL(csr1212_new_immediate);
 EXPORT_SYMBOL(csr1212_new_directory);
-EXPORT_SYMBOL(csr1212_associate_keyval);
 EXPORT_SYMBOL(csr1212_attach_keyval_to_directory);
-EXPORT_SYMBOL(csr1212_new_string_descriptor_leaf);
 EXPORT_SYMBOL(csr1212_detach_keyval_from_directory);
 EXPORT_SYMBOL(csr1212_release_keyval);
-EXPORT_SYMBOL(csr1212_destroy_csr);
 EXPORT_SYMBOL(csr1212_read);
-EXPORT_SYMBOL(csr1212_generate_csr_image);
 EXPORT_SYMBOL(csr1212_parse_keyval);
-EXPORT_SYMBOL(csr1212_parse_csr);
 EXPORT_SYMBOL(_csr1212_read_keyval);
 EXPORT_SYMBOL(_csr1212_destroy_keyval);
+#ifdef CONFIG_IEEE1394_EXPORT_FULL_API
+EXPORT_SYMBOL(csr1212_create_csr);
+EXPORT_SYMBOL(csr1212_init_local_csr);
+EXPORT_SYMBOL(csr1212_new_immediate);
+EXPORT_SYMBOL(csr1212_associate_keyval);
+EXPORT_SYMBOL(csr1212_new_string_descriptor_leaf);
+EXPORT_SYMBOL(csr1212_destroy_csr);
+EXPORT_SYMBOL(csr1212_generate_csr_image);
+EXPORT_SYMBOL(csr1212_parse_csr);
+#endif
diff --git a/drivers/ieee1394/ieee1394_core.h b/drivers/ieee1394/ieee1394_core.h
--- a/drivers/ieee1394/ieee1394_core.h
+++ b/drivers/ieee1394/ieee1394_core.h
@@ -38,8 +38,8 @@ struct hpsb_packet {
 
         /* These are core internal. */
         signed char tlabel;
-        char ack_code;
-        char tcode;
+	signed char ack_code;
+	unsigned char tcode;
 
         unsigned expect_response:1;
         unsigned no_waiter:1;
@@ -223,6 +223,7 @@ extern int hpsb_disable_irm;
 /* Our sysfs bus entry */
 extern struct bus_type ieee1394_bus_type;
 extern struct class hpsb_host_class;
-extern struct class_simple *hpsb_protocol_class;
+extern struct class *hpsb_protocol_class;
 
 #endif /* _IEEE1394_CORE_H */
+
diff --git a/drivers/ieee1394/iso.c b/drivers/ieee1394/iso.c
--- a/drivers/ieee1394/iso.c
+++ b/drivers/ieee1394/iso.c
@@ -62,10 +62,10 @@ static struct hpsb_iso* hpsb_iso_common_
 	if ((dma_mode < HPSB_ISO_DMA_DEFAULT) || (dma_mode > HPSB_ISO_DMA_PACKET_PER_BUFFER))
 		dma_mode=HPSB_ISO_DMA_DEFAULT;
 
+	if ((irq_interval < 0) || (irq_interval > buf_packets / 4))
+ 		irq_interval = buf_packets / 4;
 	if (irq_interval == 0)     /* really interrupt for each packet*/
 		irq_interval = 1;
-	else if ((irq_interval < 0) || (irq_interval > buf_packets / 4))
- 		irq_interval = buf_packets / 4;
 
 	if (channel < -1 || channel >= 64)
 		return NULL;
@@ -106,6 +106,7 @@ static struct hpsb_iso* hpsb_iso_common_
 	}
 
 	atomic_set(&iso->overflows, 0);
+	iso->bytes_discarded = 0;
 	iso->flags = 0;
 	iso->prebuffer = 0;
 
@@ -241,12 +242,12 @@ int hpsb_iso_xmit_start(struct hpsb_iso 
 	iso->xmit_cycle = cycle;
 
 	if (prebuffer < 0)
-		prebuffer = iso->buf_packets;
+		prebuffer = iso->buf_packets - 1;
 	else if (prebuffer == 0)
 		prebuffer = 1;
 
-	if (prebuffer > iso->buf_packets)
-		prebuffer = iso->buf_packets;
+	if (prebuffer >= iso->buf_packets)
+		prebuffer = iso->buf_packets - 1;
 
 	iso->prebuffer = prebuffer;
 
@@ -395,7 +396,7 @@ void hpsb_iso_packet_sent(struct hpsb_is
 }
 
 void hpsb_iso_packet_received(struct hpsb_iso *iso, u32 offset, u16 len,
-			      u16 cycle, u8 channel, u8 tag, u8 sy)
+			      u16 total_len, u16 cycle, u8 channel, u8 tag, u8 sy)
 {
 	unsigned long flags;
 	spin_lock_irqsave(&iso->lock, flags);
@@ -403,10 +404,13 @@ void hpsb_iso_packet_received(struct hps
 	if (iso->n_ready_packets == iso->buf_packets) {
 		/* overflow! */
 		atomic_inc(&iso->overflows);
+		/* Record size of this discarded packet */
+		iso->bytes_discarded += total_len;
 	} else {
 		struct hpsb_iso_packet_info *info = &iso->infos[iso->pkt_dma];
 		info->offset = offset;
 		info->len = len;
+		info->total_len = total_len;
 		info->cycle = cycle;
 		info->channel = channel;
 		info->tag = tag;
@@ -437,6 +441,17 @@ int hpsb_iso_recv_release_packets(struct
 
 		iso->first_packet = (iso->first_packet+1) % iso->buf_packets;
 		iso->n_ready_packets--;
+
+		/* release memory from packets discarded when queue was full  */
+		if (iso->n_ready_packets == 0) { /* Release only after all prior packets handled */
+			if (iso->bytes_discarded != 0) {
+				struct hpsb_iso_packet_info inf;
+				inf.total_len = iso->bytes_discarded;
+				iso->host->driver->isoctl(iso, RECV_RELEASE,
+							(unsigned long) &inf);
+				iso->bytes_discarded = 0;
+			}
+		}
 	}
 	spin_unlock_irqrestore(&iso->lock, flags);
 	return rv;
diff --git a/drivers/ieee1394/iso.h b/drivers/ieee1394/iso.h
--- a/drivers/ieee1394/iso.h
+++ b/drivers/ieee1394/iso.h
@@ -47,6 +47,14 @@ struct hpsb_iso_packet_info {
 	/* 2-bit 'tag' and 4-bit 'sy' fields of the isochronous header */
 	__u8 tag;
 	__u8 sy;
+
+	/*
+	 * length in bytes of the packet including header/trailer.
+	 * MUST be at structure end, since the first part of this structure is also 
+	 * defined in raw1394.h (i.e. struct raw1394_iso_packet_info), is copied to 
+	 * userspace and is accessed there through libraw1394. 
+	 */
+	__u16 total_len;
 };
 
 enum hpsb_iso_type { HPSB_ISO_RECV = 0, HPSB_ISO_XMIT = 1 };
@@ -111,6 +119,9 @@ struct hpsb_iso {
 	/* how many times the buffer has overflowed or underflowed */
 	atomic_t overflows;
 
+	/* Current number of bytes lost in discarded packets */
+	int bytes_discarded;
+
 	/* private flags to track initialization progress */
 #define HPSB_ISO_DRIVER_INIT     (1<<0)
 #define HPSB_ISO_DRIVER_STARTED  (1<<1)
@@ -193,7 +204,7 @@ void hpsb_iso_packet_sent(struct hpsb_is
 
 /* call after a packet has been received (interrupt context OK) */
 void hpsb_iso_packet_received(struct hpsb_iso *iso, u32 offset, u16 len,
-			      u16 cycle, u8 channel, u8 tag, u8 sy);
+			      u16 total_len, u16 cycle, u8 channel, u8 tag, u8 sy);
 
 /* call to wake waiting processes after buffer space has opened up. */
 void hpsb_iso_wake(struct hpsb_iso *iso);
diff --git a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c
--- a/drivers/ieee1394/nodemgr.c
+++ b/drivers/ieee1394/nodemgr.c
@@ -30,7 +30,7 @@
 #include "csr.h"
 #include "nodemgr.h"
 
-static int ignore_drivers = 0;
+static int ignore_drivers;
 module_param(ignore_drivers, int, 0444);
 MODULE_PARM_DESC(ignore_drivers, "Disable automatic probing for drivers.");
 
@@ -220,7 +220,7 @@ struct device nodemgr_dev_template_host 
 
 
 #define fw_attr(class, class_type, field, type, format_string)		\
-static ssize_t fw_show_##class##_##field (struct device *dev, char *buf)\
+static ssize_t fw_show_##class##_##field (struct device *dev, struct device_attribute *attr, char *buf)\
 {									\
 	class_type *class;						\
 	class = container_of(dev, class_type, device);			\
@@ -232,7 +232,7 @@ static struct device_attribute dev_attr_
 };
 
 #define fw_attr_td(class, class_type, td_kv)				\
-static ssize_t fw_show_##class##_##td_kv (struct device *dev, char *buf)\
+static ssize_t fw_show_##class##_##td_kv (struct device *dev, struct device_attribute *attr, char *buf)\
 {									\
 	int len;							\
 	class_type *class = container_of(dev, class_type, device);	\
@@ -265,7 +265,7 @@ static struct driver_attribute driver_at
 };
 
 
-static ssize_t fw_show_ne_bus_options(struct device *dev, char *buf)
+static ssize_t fw_show_ne_bus_options(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct node_entry *ne = container_of(dev, struct node_entry, device);
 
@@ -281,7 +281,7 @@ static ssize_t fw_show_ne_bus_options(st
 static DEVICE_ATTR(bus_options,S_IRUGO,fw_show_ne_bus_options,NULL);
 
 
-static ssize_t fw_show_ne_tlabels_free(struct device *dev, char *buf)
+static ssize_t fw_show_ne_tlabels_free(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct node_entry *ne = container_of(dev, struct node_entry, device);
 	return sprintf(buf, "%d\n", atomic_read(&ne->tpool->count.count) + 1);
@@ -289,7 +289,7 @@ static ssize_t fw_show_ne_tlabels_free(s
 static DEVICE_ATTR(tlabels_free,S_IRUGO,fw_show_ne_tlabels_free,NULL);
 
 
-static ssize_t fw_show_ne_tlabels_allocations(struct device *dev, char *buf)
+static ssize_t fw_show_ne_tlabels_allocations(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct node_entry *ne = container_of(dev, struct node_entry, device);
 	return sprintf(buf, "%u\n", ne->tpool->allocations);
@@ -297,7 +297,7 @@ static ssize_t fw_show_ne_tlabels_alloca
 static DEVICE_ATTR(tlabels_allocations,S_IRUGO,fw_show_ne_tlabels_allocations,NULL);
 
 
-static ssize_t fw_show_ne_tlabels_mask(struct device *dev, char *buf)
+static ssize_t fw_show_ne_tlabels_mask(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct node_entry *ne = container_of(dev, struct node_entry, device);
 #if (BITS_PER_LONG <= 32)
@@ -309,7 +309,7 @@ static ssize_t fw_show_ne_tlabels_mask(s
 static DEVICE_ATTR(tlabels_mask, S_IRUGO, fw_show_ne_tlabels_mask, NULL);
 
 
-static ssize_t fw_set_ignore_driver(struct device *dev, const char *buf, size_t count)
+static ssize_t fw_set_ignore_driver(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct unit_directory *ud = container_of(dev, struct unit_directory, device);
 	int state = simple_strtoul(buf, NULL, 10);
@@ -324,7 +324,7 @@ static ssize_t fw_set_ignore_driver(stru
 
 	return count;
 }
-static ssize_t fw_get_ignore_driver(struct device *dev, char *buf)
+static ssize_t fw_get_ignore_driver(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct unit_directory *ud = container_of(dev, struct unit_directory, device);
 
@@ -695,14 +695,15 @@ static void nodemgr_remove_ne(struct nod
 	put_device(dev);
 }
 
+static int __nodemgr_remove_host_dev(struct device *dev, void *data)
+{
+	nodemgr_remove_ne(container_of(dev, struct node_entry, device));
+	return 0;
+}
 
 static void nodemgr_remove_host_dev(struct device *dev)
 {
-	struct device *ne_dev, *next;
-
-	list_for_each_entry_safe(ne_dev, next, &dev->children, node)
-		nodemgr_remove_ne(container_of(ne_dev, struct node_entry, device));
-
+	device_for_each_child(dev, NULL, __nodemgr_remove_host_dev);
 	sysfs_remove_link(&dev->kobj, "irm_id");
 	sysfs_remove_link(&dev->kobj, "busmgr_id");
 	sysfs_remove_link(&dev->kobj, "host_id");
@@ -1509,7 +1510,7 @@ static int nodemgr_host_thread(void *__h
 
 		if (down_interruptible(&hi->reset_sem) ||
 		    down_interruptible(&nodemgr_serialize)) {
-			if (try_to_freeze(PF_FREEZE))
+			if (try_to_freeze())
 				continue;
 			printk("NodeMgr: received unexpected signal?!\n" );
 			break;
diff --git a/drivers/ieee1394/ohci1394.c b/drivers/ieee1394/ohci1394.c
--- a/drivers/ieee1394/ohci1394.c
+++ b/drivers/ieee1394/ohci1394.c
@@ -162,7 +162,7 @@ printk(level "%s: " fmt "\n" , OHCI1394_
 printk(level "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, ohci->host->id , ## args)
 
 static char version[] __devinitdata =
-	"$Rev: 1250 $ Ben Collins <bcollins@debian.org>";
+	"$Rev: 1299 $ Ben Collins <bcollins@debian.org>";
 
 /* Module Parameters */
 static int phys_dma = 1;
@@ -478,12 +478,13 @@ static void ohci_initialize(struct ti_oh
 	int num_ports, i;
 
 	spin_lock_init(&ohci->phy_reg_lock);
-	spin_lock_init(&ohci->event_lock);
 
 	/* Put some defaults to these undefined bus options */
 	buf = reg_read(ohci, OHCI1394_BusOptions);
 	buf |=  0x60000000; /* Enable CMC and ISC */
-	if (!hpsb_disable_irm)
+	if (hpsb_disable_irm)
+		buf &= ~0x80000000;
+	else
 		buf |=  0x80000000; /* Enable IRMC */
 	buf &= ~0x00ff0000; /* XXX: Set cyc_clk_acc to zero for now */
 	buf &= ~0x18000000; /* Disable PMC and BMC */
@@ -503,8 +504,12 @@ static void ohci_initialize(struct ti_oh
 	reg_write(ohci, OHCI1394_LinkControlSet,
 		  OHCI1394_LinkControl_CycleTimerEnable |
 		  OHCI1394_LinkControl_CycleMaster);
-	set_phy_reg_mask(ohci, 4, PHY_04_LCTRL |
-			 (hpsb_disable_irm ? 0 : PHY_04_CONTENDER));
+	i = get_phy_reg(ohci, 4) | PHY_04_LCTRL;
+	if (hpsb_disable_irm)
+		i &= ~PHY_04_CONTENDER;
+	else
+		i |= PHY_04_CONTENDER;
+	set_phy_reg(ohci, 4, i);
 
 	/* Set up self-id dma buffer */
 	reg_write(ohci, OHCI1394_SelfIDBuffer, ohci->selfid_buf_bus);
@@ -1078,7 +1083,8 @@ static int ohci_devctl(struct hpsb_host 
 
 			initialize_dma_rcv_ctx(&ohci->ir_legacy_context, 1);
 
-			PRINT(KERN_ERR, "IR legacy activated");
+			if (printk_ratelimit())
+				PRINT(KERN_ERR, "IR legacy activated");
 		}
 
                 spin_lock_irqsave(&ohci->IR_channel_lock, flags);
@@ -1566,6 +1572,10 @@ static void ohci_iso_recv_release_block(
 
 	struct dma_cmd *next = &recv->block[next_i];
 	struct dma_cmd *prev = &recv->block[prev_i];
+	
+	/* ignore out-of-range requests */
+	if ((block < 0) || (block > recv->nblocks))
+		return;
 
 	/* 'next' becomes the new end of the DMA chain,
 	   so disable branch and enable interrupt */
@@ -1593,19 +1603,8 @@ static void ohci_iso_recv_release_block(
 static void ohci_iso_recv_bufferfill_release(struct ohci_iso_recv *recv,
 					     struct hpsb_iso_packet_info *info)
 {
-	int len;
-
 	/* release the memory where the packet was */
-	len = info->len;
-
-	/* add the wasted space for padding to 4 bytes */
-	if (len % 4)
-		len += 4 - (len % 4);
-
-	/* add 8 bytes for the OHCI DMA data format overhead */
-	len += 8;
-
-	recv->released_bytes += len;
+	recv->released_bytes += info->total_len;
 
 	/* have we released enough memory for one block? */
 	while (recv->released_bytes > recv->buf_stride) {
@@ -1637,7 +1636,7 @@ static void ohci_iso_recv_bufferfill_par
 		/* note: packet layout is as shown in section 10.6.1.1 of the OHCI spec */
 
 		unsigned int offset;
-		unsigned short len, cycle;
+		unsigned short len, cycle, total_len;
 		unsigned char channel, tag, sy;
 
 		unsigned char *p = iso->data_buf.kvirt;
@@ -1688,9 +1687,11 @@ static void ohci_iso_recv_bufferfill_par
 		/* advance to xferStatus/timeStamp */
 		recv->dma_offset += len;
 
+		total_len = len + 8; /* 8 bytes header+trailer in OHCI packet */
 		/* payload is padded to 4 bytes */
 		if (len % 4) {
 			recv->dma_offset += 4 - (len%4);
+			total_len += 4 - (len%4);
 		}
 
 		/* check for wrap-around */
@@ -1724,7 +1725,7 @@ static void ohci_iso_recv_bufferfill_par
 			recv->dma_offset -= recv->buf_stride*recv->nblocks;
 		}
 
-		hpsb_iso_packet_received(iso, offset, len, cycle, channel, tag, sy);
+		hpsb_iso_packet_received(iso, offset, len, total_len, cycle, channel, tag, sy);
 	}
 
 	if (wake)
@@ -1850,7 +1851,8 @@ static void ohci_iso_recv_packetperbuf_t
 			tag = hdr[5] >> 6;
 			sy = hdr[4] & 0xF;
 
-			hpsb_iso_packet_received(iso, offset, packet_len, cycle, channel, tag, sy);
+			hpsb_iso_packet_received(iso, offset, packet_len,
+					recv->buf_stride, cycle, channel, tag, sy);
 		}
 
 		/* reset the DMA descriptor */
@@ -3399,7 +3401,14 @@ static int __devinit ohci1394_pci_probe(
 	/* We hopefully don't have to pre-allocate IT DMA like we did
 	 * for IR DMA above. Allocate it on-demand and mark inactive. */
 	ohci->it_legacy_context.ohci = NULL;
+	spin_lock_init(&ohci->event_lock);
 
+	/*
+	 * interrupts are disabled, all right, but... due to SA_SHIRQ we
+	 * might get called anyway.  We'll see no event, of course, but
+	 * we need to get to that "no event", so enough should be initialized
+	 * by that point.
+	 */
 	if (request_irq(dev->irq, ohci_irq_handler, SA_SHIRQ,
 			 OHCI1394_DRIVER_NAME, ohci))
 		FAIL(-ENOMEM, "Failed to allocate shared interrupt %d", dev->irq);
@@ -3538,8 +3547,8 @@ static void ohci1394_pci_remove(struct p
 
 static int ohci1394_pci_resume (struct pci_dev *pdev)
 {
-#ifdef CONFIG_PMAC_PBOOK
-	{
+#ifdef CONFIG_PPC_PMAC
+	if (_machine == _MACH_Pmac) {
 		struct device_node *of_node;
 
 		/* Re-enable 1394 */
@@ -3547,7 +3556,7 @@ static int ohci1394_pci_resume (struct p
 		if (of_node)
 			pmac_call_feature (PMAC_FTR_1394_ENABLE, of_node, 0, 1);
 	}
-#endif
+#endif /* CONFIG_PPC_PMAC */
 
 	pci_enable_device(pdev);
 
@@ -3557,8 +3566,8 @@ static int ohci1394_pci_resume (struct p
 
 static int ohci1394_pci_suspend (struct pci_dev *pdev, pm_message_t state)
 {
-#ifdef CONFIG_PMAC_PBOOK
-	{
+#ifdef CONFIG_PPC_PMAC
+	if (_machine == _MACH_Pmac) {
 		struct device_node *of_node;
 
 		/* Disable 1394 */
diff --git a/drivers/ieee1394/pcilynx.c b/drivers/ieee1394/pcilynx.c
--- a/drivers/ieee1394/pcilynx.c
+++ b/drivers/ieee1394/pcilynx.c
@@ -76,7 +76,7 @@
 
 
 /* Module Parameters */
-static int skip_eeprom = 0;
+static int skip_eeprom;
 module_param(skip_eeprom, int, 0444);
 MODULE_PARM_DESC(skip_eeprom, "Use generic bus info block instead of serial eeprom (default = 0).");
 
@@ -1422,7 +1422,7 @@ static int __devinit add_card(struct pci
 		i = get_phy_reg(lynx, 4);
 		i |= PHY_04_LCTRL;
 		if (hpsb_disable_irm)
-			i &= !PHY_04_CONTENDER;
+			i &= ~PHY_04_CONTENDER;
 		else
 			i |= PHY_04_CONTENDER;
 		if (i != -1) set_phy_reg(lynx, 4, i);
diff --git a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c
--- a/drivers/ieee1394/raw1394.c
+++ b/drivers/ieee1394/raw1394.c
@@ -98,7 +98,7 @@ static struct hpsb_address_ops arm_ops =
 
 static void queue_complete_cb(struct pending_request *req);
 
-static struct pending_request *__alloc_pending_request(int flags)
+static struct pending_request *__alloc_pending_request(unsigned int __nocast flags)
 {
 	struct pending_request *req;
 
@@ -2506,9 +2506,12 @@ static int raw1394_iso_send_packets(stru
 	if (copy_from_user(&upackets, uaddr, sizeof(upackets)))
 		return -EFAULT;
 
-	if (upackets.n_packets > hpsb_iso_n_ready(fi->iso_handle))
+	if (upackets.n_packets >= fi->iso_handle->buf_packets)
 		return -EINVAL;
 
+	if (upackets.n_packets >= hpsb_iso_n_ready(fi->iso_handle))
+		return -EAGAIN;
+
 	/* ensure user-supplied buffer is accessible and big enough */
 	if (!access_ok(VERIFY_READ, upackets.infos,
 			upackets.n_packets *
@@ -2901,7 +2904,7 @@ static int __init init_raw1394(void)
 
 	hpsb_register_highlevel(&raw1394_highlevel);
 
-	if (IS_ERR(class_simple_device_add(hpsb_protocol_class, MKDEV(
+	if (IS_ERR(class_device_create(hpsb_protocol_class, MKDEV(
 		IEEE1394_MAJOR,	IEEE1394_MINOR_BLOCK_RAW1394 * 16), 
 		NULL, RAW1394_DEVICE_NAME))) {
 		ret = -EFAULT;
@@ -2934,8 +2937,8 @@ static int __init init_raw1394(void)
 
 out_dev:
 	devfs_remove(RAW1394_DEVICE_NAME);
-	class_simple_device_remove(MKDEV(
-		IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16));
+	class_device_destroy(hpsb_protocol_class,
+		MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16));
 out_unreg:
 	hpsb_unregister_highlevel(&raw1394_highlevel);
 out:
@@ -2944,8 +2947,8 @@ out:
 
 static void __exit cleanup_raw1394(void)
 {
-	class_simple_device_remove(MKDEV(
-		IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16));
+	class_device_destroy(hpsb_protocol_class,
+		MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16));
 	cdev_del(&raw1394_cdev);
 	devfs_remove(RAW1394_DEVICE_NAME);
 	hpsb_unregister_highlevel(&raw1394_highlevel);
diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c
--- a/drivers/ieee1394/sbp2.c
+++ b/drivers/ieee1394/sbp2.c
@@ -81,7 +81,7 @@
 #include "sbp2.h"
 
 static char version[] __devinitdata =
-	"$Rev: 1219 $ Ben Collins <bcollins@debian.org>";
+	"$Rev: 1306 $ Ben Collins <bcollins@debian.org>";
 
 /*
  * Module load parameter definitions
@@ -104,7 +104,7 @@ MODULE_PARM_DESC(max_speed, "Force max s
  * down to us at a time (debugging). This might be necessary for very
  * badly behaved sbp2 devices.
  */
-static int serialize_io = 0;
+static int serialize_io;
 module_param(serialize_io, int, 0444);
 MODULE_PARM_DESC(serialize_io, "Serialize all I/O coming down from the scsi drivers (default = 0)");
 
@@ -145,7 +145,7 @@ MODULE_PARM_DESC(exclusive_login, "Exclu
  * please submit the logged sbp2_firmware_revision value of this device to
  * the linux1394-devel mailing list.
  */
-static int force_inquiry_hack = 0;
+static int force_inquiry_hack;
 module_param(force_inquiry_hack, int, 0444);
 MODULE_PARM_DESC(force_inquiry_hack, "Force SCSI inquiry hack (default = 0)");
 
@@ -169,6 +169,7 @@ MODULE_DEVICE_TABLE(ieee1394, sbp2_id_ta
  * Debug levels, configured via kernel config, or enable here.
  */
 
+#define CONFIG_IEEE1394_SBP2_DEBUG 0
 /* #define CONFIG_IEEE1394_SBP2_DEBUG_ORBS */
 /* #define CONFIG_IEEE1394_SBP2_DEBUG_DMA */
 /* #define CONFIG_IEEE1394_SBP2_DEBUG 1 */
@@ -1071,7 +1072,7 @@ static int sbp2_handle_physdma_read(stru
 static __inline__ int sbp2_command_conversion_device_type(u8 device_type)
 {
 	return (((device_type == TYPE_DISK) ||
-		 (device_type == TYPE_SDAD) ||
+		 (device_type == TYPE_RBC) ||
 		 (device_type == TYPE_ROM)) ? 1:0);
 }
 
@@ -2275,8 +2276,8 @@ static void sbp2_check_sbp2_response(str
 			/*
 			 * Check for Simple Direct Access Device and change it to TYPE_DISK
 			 */
-			if ((scsi_buf[0] & 0x1f) == TYPE_SDAD) {
-				SBP2_DEBUG("Changing TYPE_SDAD to TYPE_DISK");
+			if ((scsi_buf[0] & 0x1f) == TYPE_RBC) {
+				SBP2_DEBUG("Changing TYPE_RBC to TYPE_DISK");
 				scsi_buf[0] &= 0xe0;
 			}
 
@@ -2580,8 +2581,6 @@ static void sbp2scsi_complete_command(st
 				      u32 scsi_status, struct scsi_cmnd *SCpnt,
 				      void (*done)(struct scsi_cmnd *))
 {
-	unsigned long flags;
-
 	SBP2_DEBUG("sbp2scsi_complete_command");
 
 	/*
@@ -2680,11 +2679,7 @@ static void sbp2scsi_complete_command(st
 	/*
 	 * Tell scsi stack that we're done with this command
 	 */
-	spin_lock_irqsave(scsi_id->scsi_host->host_lock,flags);
 	done (SCpnt);
-	spin_unlock_irqrestore(scsi_id->scsi_host->host_lock,flags);
-
-	return;
 }
 
 
@@ -2747,7 +2742,7 @@ static int sbp2scsi_abort(struct scsi_cm
 /*
  * Called by scsi stack when something has really gone wrong.
  */
-static int sbp2scsi_reset(struct scsi_cmnd *SCpnt)
+static int __sbp2scsi_reset(struct scsi_cmnd *SCpnt)
 {
 	struct scsi_id_instance_data *scsi_id =
 		(struct scsi_id_instance_data *)SCpnt->device->host->hostdata[0];
@@ -2762,12 +2757,24 @@ static int sbp2scsi_reset(struct scsi_cm
 	return(SUCCESS);
 }
 
+static int sbp2scsi_reset(struct scsi_cmnd *SCpnt)
+{
+	unsigned long flags;
+	int rc;
+
+	spin_lock_irqsave(SCpnt->device->host->host_lock, flags);
+	rc = __sbp2scsi_reset(SCpnt);
+	spin_unlock_irqrestore(SCpnt->device->host->host_lock, flags);
+
+	return rc;
+}
+
 static const char *sbp2scsi_info (struct Scsi_Host *host)
 {
         return "SCSI emulation for IEEE-1394 SBP-2 Devices";
 }
 
-static ssize_t sbp2_sysfs_ieee1394_id_show(struct device *dev, char *buf)
+static ssize_t sbp2_sysfs_ieee1394_id_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct scsi_device *sdev;
 	struct scsi_id_instance_data *scsi_id;
diff --git a/drivers/ieee1394/sbp2.h b/drivers/ieee1394/sbp2.h
--- a/drivers/ieee1394/sbp2.h
+++ b/drivers/ieee1394/sbp2.h
@@ -266,10 +266,6 @@ struct sbp2_status_block {
 #define SBP2_MAX_UDS_PER_NODE		16	/* Maximum scsi devices per node */
 #define SBP2_MAX_SECTORS		255	/* Max sectors supported */
 
-#ifndef TYPE_SDAD
-#define TYPE_SDAD			0x0e	/* simplified direct access device */
-#endif
-
 /*
  * SCSI direction table...
  * (now used as a back-up in case the direction passed down from above is "unknown")
diff --git a/drivers/ieee1394/video1394.c b/drivers/ieee1394/video1394.c
--- a/drivers/ieee1394/video1394.c
+++ b/drivers/ieee1394/video1394.c
@@ -1370,7 +1370,7 @@ static void video1394_add_host (struct h
 	hpsb_set_hostinfo_key(&video1394_highlevel, host, ohci->host->id);
 
 	minor = IEEE1394_MINOR_BLOCK_VIDEO1394 * 16 + ohci->host->id;
-	class_simple_device_add(hpsb_protocol_class, MKDEV(
+	class_device_create(hpsb_protocol_class, MKDEV(
 		IEEE1394_MAJOR,	minor), 
 		NULL, "%s-%d", VIDEO1394_DRIVER_NAME, ohci->host->id);
 	devfs_mk_cdev(MKDEV(IEEE1394_MAJOR, minor),
@@ -1384,7 +1384,7 @@ static void video1394_remove_host (struc
 	struct ti_ohci *ohci = hpsb_get_hostinfo(&video1394_highlevel, host);
 
 	if (ohci) {
-		class_simple_device_remove(MKDEV(IEEE1394_MAJOR, 
+		class_device_destroy(hpsb_protocol_class, MKDEV(IEEE1394_MAJOR,
 			IEEE1394_MINOR_BLOCK_VIDEO1394 * 16 + ohci->host->id));
 		devfs_remove("%s/%d", VIDEO1394_DRIVER_NAME, ohci->host->id);
 	}
diff --git a/drivers/infiniband/Kconfig b/drivers/infiniband/Kconfig
--- a/drivers/infiniband/Kconfig
+++ b/drivers/infiniband/Kconfig
@@ -1,12 +1,23 @@
 menu "InfiniBand support"
 
 config INFINIBAND
+	depends on PCI || BROKEN
 	tristate "InfiniBand support"
 	---help---
 	  Core support for InfiniBand (IB).  Make sure to also select
 	  any protocols you wish to use as well as drivers for your
 	  InfiniBand hardware.
 
+config INFINIBAND_USER_VERBS
+	tristate "InfiniBand userspace verbs support"
+	depends on INFINIBAND
+	---help---
+	  Userspace InfiniBand verbs support.  This is the kernel side
+	  of userspace verbs, which allows userspace processes to
+	  directly access InfiniBand hardware for fast-path
+	  operations.  You will also need libibverbs and a hardware
+	  driver library from <http://www.openib.org>.
+
 source "drivers/infiniband/hw/mthca/Kconfig"
 
 source "drivers/infiniband/ulp/ipoib/Kconfig"
diff --git a/drivers/infiniband/core/Makefile b/drivers/infiniband/core/Makefile
--- a/drivers/infiniband/core/Makefile
+++ b/drivers/infiniband/core/Makefile
@@ -1,12 +1,20 @@
 EXTRA_CFLAGS += -Idrivers/infiniband/include
 
-obj-$(CONFIG_INFINIBAND) +=	ib_core.o ib_mad.o ib_sa.o ib_umad.o
+obj-$(CONFIG_INFINIBAND) +=		ib_core.o ib_mad.o ib_sa.o \
+					ib_cm.o ib_umad.o ib_ucm.o
+obj-$(CONFIG_INFINIBAND_USER_VERBS) +=	ib_uverbs.o
 
 ib_core-y :=			packer.o ud_header.o verbs.o sysfs.o \
 				device.o fmr_pool.o cache.o
 
-ib_mad-y :=			mad.o smi.o agent.o
+ib_mad-y :=			mad.o smi.o agent.o mad_rmpp.o
 
 ib_sa-y :=			sa_query.o
 
+ib_cm-y :=			cm.o
+
 ib_umad-y :=			user_mad.o
+
+ib_ucm-y :=			ucm.o
+
+ib_uverbs-y :=			uverbs_main.o uverbs_cmd.o uverbs_mem.o
diff --git a/drivers/infiniband/core/agent.c b/drivers/infiniband/core/agent.c
--- a/drivers/infiniband/core/agent.c
+++ b/drivers/infiniband/core/agent.c
@@ -134,7 +134,7 @@ static int agent_mad_send(struct ib_mad_
 					  sizeof(mad_priv->mad),
 					  DMA_TO_DEVICE);
 	gather_list.length = sizeof(mad_priv->mad);
-	gather_list.lkey = (*port_priv->mr).lkey;
+	gather_list.lkey = mad_agent->mr->lkey;
 
 	send_wr.next = NULL;
 	send_wr.opcode = IB_WR_SEND;
@@ -156,10 +156,10 @@ static int agent_mad_send(struct ib_mad_
 			/* Should sgid be looked up ? */
 			ah_attr.grh.sgid_index = 0;
 			ah_attr.grh.hop_limit = grh->hop_limit;
-			ah_attr.grh.flow_label = be32_to_cpup(
-				&grh->version_tclass_flow)  & 0xfffff;
-			ah_attr.grh.traffic_class = (be32_to_cpup(
-				&grh->version_tclass_flow) >> 20) & 0xff;
+			ah_attr.grh.flow_label = be32_to_cpu(
+				grh->version_tclass_flow)  & 0xfffff;
+			ah_attr.grh.traffic_class = (be32_to_cpu(
+				grh->version_tclass_flow) >> 20) & 0xff;
 			memcpy(ah_attr.grh.dgid.raw,
 			       grh->sgid.raw,
 			       sizeof(ah_attr.grh.dgid));
@@ -322,22 +322,12 @@ int ib_agent_port_open(struct ib_device 
 		goto error3;
 	}
 
-	port_priv->mr = ib_get_dma_mr(port_priv->smp_agent->qp->pd,
-				      IB_ACCESS_LOCAL_WRITE);
-	if (IS_ERR(port_priv->mr)) {
-		printk(KERN_ERR SPFX "Couldn't get DMA MR\n");
-		ret = PTR_ERR(port_priv->mr);
-		goto error4;
-	}
-
 	spin_lock_irqsave(&ib_agent_port_list_lock, flags);
 	list_add_tail(&port_priv->port_list, &ib_agent_port_list);
 	spin_unlock_irqrestore(&ib_agent_port_list_lock, flags);
 
 	return 0;
 
-error4:
-	ib_unregister_mad_agent(port_priv->perf_mgmt_agent);
 error3:
 	ib_unregister_mad_agent(port_priv->smp_agent);
 error2:
@@ -361,8 +351,6 @@ int ib_agent_port_close(struct ib_device
 	list_del(&port_priv->port_list);
 	spin_unlock_irqrestore(&ib_agent_port_list_lock, flags);
 
-	ib_dereg_mr(port_priv->mr);
-
 	ib_unregister_mad_agent(port_priv->perf_mgmt_agent);
 	ib_unregister_mad_agent(port_priv->smp_agent);
 	kfree(port_priv);
diff --git a/drivers/infiniband/core/agent_priv.h b/drivers/infiniband/core/agent_priv.h
--- a/drivers/infiniband/core/agent_priv.h
+++ b/drivers/infiniband/core/agent_priv.h
@@ -33,7 +33,7 @@
  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  *
- * $Id: agent_priv.h 1389 2004-12-27 22:56:47Z roland $
+ * $Id: agent_priv.h 1640 2005-01-24 22:39:02Z halr $
  */
 
 #ifndef __IB_AGENT_PRIV_H__
@@ -57,7 +57,6 @@ struct ib_agent_port_private {
 	int port_num;
 	struct ib_mad_agent *smp_agent;	      /* SM class */
 	struct ib_mad_agent *perf_mgmt_agent; /* PerfMgmt class */
-	struct ib_mr *mr;
 };
 
 #endif	/* __IB_AGENT_PRIV_H__ */
diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c
new file mode 100644
--- /dev/null
+++ b/drivers/infiniband/core/cm.c
@@ -0,0 +1,3324 @@
+/*
+ * Copyright (c) 2004, 2005 Intel Corporation.  All rights reserved.
+ * Copyright (c) 2004 Topspin Corporation.  All rights reserved.
+ * Copyright (c) 2004, 2005 Voltaire Corporation.  All rights reserved.
+ * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * 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 THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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.
+ *
+ * $Id: cm.c 2821 2005-07-08 17:07:28Z sean.hefty $
+ */
+#include <linux/dma-mapping.h>
+#include <linux/err.h>
+#include <linux/idr.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/rbtree.h>
+#include <linux/spinlock.h>
+#include <linux/workqueue.h>
+
+#include <ib_cache.h>
+#include <ib_cm.h>
+#include "cm_msgs.h"
+
+MODULE_AUTHOR("Sean Hefty");
+MODULE_DESCRIPTION("InfiniBand CM");
+MODULE_LICENSE("Dual BSD/GPL");
+
+static void cm_add_one(struct ib_device *device);
+static void cm_remove_one(struct ib_device *device);
+
+static struct ib_client cm_client = {
+	.name   = "cm",
+	.add    = cm_add_one,
+	.remove = cm_remove_one
+};
+
+static struct ib_cm {
+	spinlock_t lock;
+	struct list_head device_list;
+	rwlock_t device_lock;
+	struct rb_root listen_service_table;
+	u64 listen_service_id;
+	/* struct rb_root peer_service_table; todo: fix peer to peer */
+	struct rb_root remote_qp_table;
+	struct rb_root remote_id_table;
+	struct rb_root remote_sidr_table;
+	struct idr local_id_table;
+	struct workqueue_struct *wq;
+} cm;
+
+struct cm_port {
+	struct cm_device *cm_dev;
+	struct ib_mad_agent *mad_agent;
+	u8 port_num;
+};
+
+struct cm_device {
+	struct list_head list;
+	struct ib_device *device;
+	u64 ca_guid;
+	struct cm_port port[0];
+};
+
+struct cm_av {
+	struct cm_port *port;
+	union ib_gid dgid;
+	struct ib_ah_attr ah_attr;
+	u16 pkey_index;
+	u8 packet_life_time;
+};
+
+struct cm_work {
+	struct work_struct work;
+	struct list_head list;
+	struct cm_port *port;
+	struct ib_mad_recv_wc *mad_recv_wc;	/* Received MADs */
+	u32 local_id;				/* Established / timewait */
+	u32 remote_id;
+	struct ib_cm_event cm_event;
+	struct ib_sa_path_rec path[0];
+};
+
+struct cm_timewait_info {
+	struct cm_work work;			/* Must be first. */
+	struct rb_node remote_qp_node;
+	struct rb_node remote_id_node;
+	u64 remote_ca_guid;
+	u32 remote_qpn;
+	u8 inserted_remote_qp;
+	u8 inserted_remote_id;
+};
+
+struct cm_id_private {
+	struct ib_cm_id	id;
+
+	struct rb_node service_node;
+	struct rb_node sidr_id_node;
+	spinlock_t lock;
+	wait_queue_head_t wait;
+	atomic_t refcount;
+
+	struct ib_mad_send_buf *msg;
+	struct cm_timewait_info *timewait_info;
+	/* todo: use alternate port on send failure */
+	struct cm_av av;
+	struct cm_av alt_av;
+
+	void *private_data;
+	u64 tid;
+	u32 local_qpn;
+	u32 remote_qpn;
+	u32 sq_psn;
+	u32 rq_psn;
+	int timeout_ms;
+	enum ib_mtu path_mtu;
+	u8 private_data_len;
+	u8 max_cm_retries;
+	u8 peer_to_peer;
+	u8 responder_resources;
+	u8 initiator_depth;
+	u8 local_ack_timeout;
+	u8 retry_count;
+	u8 rnr_retry_count;
+	u8 service_timeout;
+
+	struct list_head work_list;
+	atomic_t work_count;
+};
+
+static void cm_work_handler(void *data);
+
+static inline void cm_deref_id(struct cm_id_private *cm_id_priv)
+{
+	if (atomic_dec_and_test(&cm_id_priv->refcount))
+		wake_up(&cm_id_priv->wait);
+}
+
+static int cm_alloc_msg(struct cm_id_private *cm_id_priv,
+			struct ib_mad_send_buf **msg)
+{
+	struct ib_mad_agent *mad_agent;
+	struct ib_mad_send_buf *m;
+	struct ib_ah *ah;
+
+	mad_agent = cm_id_priv->av.port->mad_agent;
+	ah = ib_create_ah(mad_agent->qp->pd, &cm_id_priv->av.ah_attr);
+	if (IS_ERR(ah))
+		return PTR_ERR(ah);
+
+	m = ib_create_send_mad(mad_agent, 1, cm_id_priv->av.pkey_index,
+			       ah, 0, sizeof(struct ib_mad_hdr),
+			       sizeof(struct ib_mad)-sizeof(struct ib_mad_hdr),
+			       GFP_ATOMIC);
+	if (IS_ERR(m)) {
+		ib_destroy_ah(ah);
+		return PTR_ERR(m);
+	}
+
+	/* Timeout set by caller if response is expected. */
+	m->send_wr.wr.ud.retries = cm_id_priv->max_cm_retries;
+
+	atomic_inc(&cm_id_priv->refcount);
+	m->context[0] = cm_id_priv;
+	*msg = m;
+	return 0;
+}
+
+static int cm_alloc_response_msg(struct cm_port *port,
+				 struct ib_mad_recv_wc *mad_recv_wc,
+				 struct ib_mad_send_buf **msg)
+{
+	struct ib_mad_send_buf *m;
+	struct ib_ah *ah;
+
+	ah = ib_create_ah_from_wc(port->mad_agent->qp->pd, mad_recv_wc->wc,
+				  mad_recv_wc->recv_buf.grh, port->port_num);
+	if (IS_ERR(ah))
+		return PTR_ERR(ah);
+
+	m = ib_create_send_mad(port->mad_agent, 1, mad_recv_wc->wc->pkey_index,
+			       ah, 0, sizeof(struct ib_mad_hdr),
+			       sizeof(struct ib_mad)-sizeof(struct ib_mad_hdr),
+			       GFP_ATOMIC);
+	if (IS_ERR(m)) {
+		ib_destroy_ah(ah);
+		return PTR_ERR(m);
+	}
+	*msg = m;
+	return 0;
+}
+
+static void cm_free_msg(struct ib_mad_send_buf *msg)
+{
+	ib_destroy_ah(msg->send_wr.wr.ud.ah);
+	if (msg->context[0])
+		cm_deref_id(msg->context[0]);
+	ib_free_send_mad(msg);
+}
+
+static void * cm_copy_private_data(const void *private_data,
+				   u8 private_data_len)
+{
+	void *data;
+
+	if (!private_data || !private_data_len)
+		return NULL;
+
+	data = kmalloc(private_data_len, GFP_KERNEL);
+	if (!data)
+		return ERR_PTR(-ENOMEM);
+
+	memcpy(data, private_data, private_data_len);
+	return data;
+}
+
+static void cm_set_private_data(struct cm_id_private *cm_id_priv,
+				 void *private_data, u8 private_data_len)
+{
+	if (cm_id_priv->private_data && cm_id_priv->private_data_len)
+		kfree(cm_id_priv->private_data);
+
+	cm_id_priv->private_data = private_data;
+	cm_id_priv->private_data_len = private_data_len;
+}
+
+static void cm_set_ah_attr(struct ib_ah_attr *ah_attr, u8 port_num,
+			   u16 dlid, u8 sl, u16 src_path_bits)
+{
+	memset(ah_attr, 0, sizeof ah_attr);
+	ah_attr->dlid = be16_to_cpu(dlid);
+	ah_attr->sl = sl;
+	ah_attr->src_path_bits = src_path_bits;
+	ah_attr->port_num = port_num;
+}
+
+static void cm_init_av_for_response(struct cm_port *port,
+				    struct ib_wc *wc, struct cm_av *av)
+{
+	av->port = port;
+	av->pkey_index = wc->pkey_index;
+	cm_set_ah_attr(&av->ah_attr, port->port_num, cpu_to_be16(wc->slid),
+		       wc->sl, wc->dlid_path_bits);
+}
+
+static int cm_init_av_by_path(struct ib_sa_path_rec *path, struct cm_av *av)
+{
+	struct cm_device *cm_dev;
+	struct cm_port *port = NULL;
+	unsigned long flags;
+	int ret;
+	u8 p;
+
+	read_lock_irqsave(&cm.device_lock, flags);
+	list_for_each_entry(cm_dev, &cm.device_list, list) {
+		if (!ib_find_cached_gid(cm_dev->device, &path->sgid,
+					&p, NULL)) {
+			port = &cm_dev->port[p-1];
+			break;
+		}
+	}
+	read_unlock_irqrestore(&cm.device_lock, flags);
+
+	if (!port)
+		return -EINVAL;
+
+	ret = ib_find_cached_pkey(cm_dev->device, port->port_num,
+				  be16_to_cpu(path->pkey), &av->pkey_index);
+	if (ret)
+		return ret;
+
+	av->port = port;
+	cm_set_ah_attr(&av->ah_attr, av->port->port_num, path->dlid,
+		       path->sl, path->slid & 0x7F);
+	av->packet_life_time = path->packet_life_time;
+	return 0;
+}
+
+static int cm_alloc_id(struct cm_id_private *cm_id_priv)
+{
+	unsigned long flags;
+	int ret;
+
+	do {
+		spin_lock_irqsave(&cm.lock, flags);
+		ret = idr_get_new_above(&cm.local_id_table, cm_id_priv, 1,
+					(int *) &cm_id_priv->id.local_id);
+		spin_unlock_irqrestore(&cm.lock, flags);
+	} while( (ret == -EAGAIN) && idr_pre_get(&cm.local_id_table, GFP_KERNEL) );
+	return ret;
+}
+
+static void cm_free_id(u32 local_id)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&cm.lock, flags);
+	idr_remove(&cm.local_id_table, (int) local_id);
+	spin_unlock_irqrestore(&cm.lock, flags);
+}
+
+static struct cm_id_private * cm_get_id(u32 local_id, u32 remote_id)
+{
+	struct cm_id_private *cm_id_priv;
+
+	cm_id_priv = idr_find(&cm.local_id_table, (int) local_id);
+	if (cm_id_priv) {
+		if (cm_id_priv->id.remote_id == remote_id)
+			atomic_inc(&cm_id_priv->refcount);
+		else
+			cm_id_priv = NULL;
+	}
+
+	return cm_id_priv;
+}
+
+static struct cm_id_private * cm_acquire_id(u32 local_id, u32 remote_id)
+{
+	struct cm_id_private *cm_id_priv;
+	unsigned long flags;
+
+	spin_lock_irqsave(&cm.lock, flags);
+	cm_id_priv = cm_get_id(local_id, remote_id);
+	spin_unlock_irqrestore(&cm.lock, flags);
+
+	return cm_id_priv;
+}
+
+static struct cm_id_private * cm_insert_listen(struct cm_id_private *cm_id_priv)
+{
+	struct rb_node **link = &cm.listen_service_table.rb_node;
+	struct rb_node *parent = NULL;
+	struct cm_id_private *cur_cm_id_priv;
+	u64 service_id = cm_id_priv->id.service_id;
+	u64 service_mask = cm_id_priv->id.service_mask;
+
+	while (*link) {
+		parent = *link;
+		cur_cm_id_priv = rb_entry(parent, struct cm_id_private,
+					  service_node);
+		if ((cur_cm_id_priv->id.service_mask & service_id) ==
+		    (service_mask & cur_cm_id_priv->id.service_id))
+			return cm_id_priv;
+		if (service_id < cur_cm_id_priv->id.service_id)
+			link = &(*link)->rb_left;
+		else
+			link = &(*link)->rb_right;
+	}
+	rb_link_node(&cm_id_priv->service_node, parent, link);
+	rb_insert_color(&cm_id_priv->service_node, &cm.listen_service_table);
+	return NULL;
+}
+
+static struct cm_id_private * cm_find_listen(u64 service_id)
+{
+	struct rb_node *node = cm.listen_service_table.rb_node;
+	struct cm_id_private *cm_id_priv;
+
+	while (node) {
+		cm_id_priv = rb_entry(node, struct cm_id_private, service_node);
+		if ((cm_id_priv->id.service_mask & service_id) ==
+		    (cm_id_priv->id.service_mask & cm_id_priv->id.service_id))
+			return cm_id_priv;
+		if (service_id < cm_id_priv->id.service_id)
+			node = node->rb_left;
+		else
+			node = node->rb_right;
+	}
+	return NULL;
+}
+
+static struct cm_timewait_info * cm_insert_remote_id(struct cm_timewait_info
+						     *timewait_info)
+{
+	struct rb_node **link = &cm.remote_id_table.rb_node;
+	struct rb_node *parent = NULL;
+	struct cm_timewait_info *cur_timewait_info;
+	u64 remote_ca_guid = timewait_info->remote_ca_guid;
+	u32 remote_id = timewait_info->work.remote_id;
+
+	while (*link) {
+		parent = *link;
+		cur_timewait_info = rb_entry(parent, struct cm_timewait_info,
+					     remote_id_node);
+		if (remote_id < cur_timewait_info->work.remote_id)
+			link = &(*link)->rb_left;
+		else if (remote_id > cur_timewait_info->work.remote_id)
+			link = &(*link)->rb_right;
+		else if (remote_ca_guid < cur_timewait_info->remote_ca_guid)
+			link = &(*link)->rb_left;
+		else if (remote_ca_guid > cur_timewait_info->remote_ca_guid)
+			link = &(*link)->rb_right;
+		else
+			return cur_timewait_info;
+	}
+	timewait_info->inserted_remote_id = 1;
+	rb_link_node(&timewait_info->remote_id_node, parent, link);
+	rb_insert_color(&timewait_info->remote_id_node, &cm.remote_id_table);
+	return NULL;
+}
+
+static struct cm_timewait_info * cm_find_remote_id(u64 remote_ca_guid,
+						   u32 remote_id)
+{
+	struct rb_node *node = cm.remote_id_table.rb_node;
+	struct cm_timewait_info *timewait_info;
+
+	while (node) {
+		timewait_info = rb_entry(node, struct cm_timewait_info,
+					 remote_id_node);
+		if (remote_id < timewait_info->work.remote_id)
+			node = node->rb_left;
+		else if (remote_id > timewait_info->work.remote_id)
+			node = node->rb_right;
+		else if (remote_ca_guid < timewait_info->remote_ca_guid)
+			node = node->rb_left;
+		else if (remote_ca_guid > timewait_info->remote_ca_guid)
+			node = node->rb_right;
+		else
+			return timewait_info;
+	}
+	return NULL;
+}
+
+static struct cm_timewait_info * cm_insert_remote_qpn(struct cm_timewait_info
+						      *timewait_info)
+{
+	struct rb_node **link = &cm.remote_qp_table.rb_node;
+	struct rb_node *parent = NULL;
+	struct cm_timewait_info *cur_timewait_info;
+	u64 remote_ca_guid = timewait_info->remote_ca_guid;
+	u32 remote_qpn = timewait_info->remote_qpn;
+
+	while (*link) {
+		parent = *link;
+		cur_timewait_info = rb_entry(parent, struct cm_timewait_info,
+					     remote_qp_node);
+		if (remote_qpn < cur_timewait_info->remote_qpn)
+			link = &(*link)->rb_left;
+		else if (remote_qpn > cur_timewait_info->remote_qpn)
+			link = &(*link)->rb_right;
+		else if (remote_ca_guid < cur_timewait_info->remote_ca_guid)
+			link = &(*link)->rb_left;
+		else if (remote_ca_guid > cur_timewait_info->remote_ca_guid)
+			link = &(*link)->rb_right;
+		else
+			return cur_timewait_info;
+	}
+	timewait_info->inserted_remote_qp = 1;
+	rb_link_node(&timewait_info->remote_qp_node, parent, link);
+	rb_insert_color(&timewait_info->remote_qp_node, &cm.remote_qp_table);
+	return NULL;
+}
+
+static struct cm_id_private * cm_insert_remote_sidr(struct cm_id_private
+						    *cm_id_priv)
+{
+	struct rb_node **link = &cm.remote_sidr_table.rb_node;
+	struct rb_node *parent = NULL;
+	struct cm_id_private *cur_cm_id_priv;
+	union ib_gid *port_gid = &cm_id_priv->av.dgid;
+	u32 remote_id = cm_id_priv->id.remote_id;
+
+	while (*link) {
+		parent = *link;
+		cur_cm_id_priv = rb_entry(parent, struct cm_id_private,
+					  sidr_id_node);
+		if (remote_id < cur_cm_id_priv->id.remote_id)
+			link = &(*link)->rb_left;
+		else if (remote_id > cur_cm_id_priv->id.remote_id)
+			link = &(*link)->rb_right;
+		else {
+			int cmp;
+			cmp = memcmp(port_gid, &cur_cm_id_priv->av.dgid,
+				     sizeof *port_gid);
+			if (cmp < 0)
+				link = &(*link)->rb_left;
+			else if (cmp > 0)
+				link = &(*link)->rb_right;
+			else
+				return cur_cm_id_priv;
+		}
+	}
+	rb_link_node(&cm_id_priv->sidr_id_node, parent, link);
+	rb_insert_color(&cm_id_priv->sidr_id_node, &cm.remote_sidr_table);
+	return NULL;
+}
+
+static void cm_reject_sidr_req(struct cm_id_private *cm_id_priv,
+			       enum ib_cm_sidr_status status)
+{
+	struct ib_cm_sidr_rep_param param;
+
+	memset(&param, 0, sizeof param);
+	param.status = status;
+	ib_send_cm_sidr_rep(&cm_id_priv->id, &param);
+}
+
+struct ib_cm_id *ib_create_cm_id(ib_cm_handler cm_handler,
+				 void *context)
+{
+	struct cm_id_private *cm_id_priv;
+	int ret;
+
+	cm_id_priv = kmalloc(sizeof *cm_id_priv, GFP_KERNEL);
+	if (!cm_id_priv)
+		return ERR_PTR(-ENOMEM);
+
+	memset(cm_id_priv, 0, sizeof *cm_id_priv);
+	cm_id_priv->id.state = IB_CM_IDLE;
+	cm_id_priv->id.cm_handler = cm_handler;
+	cm_id_priv->id.context = context;
+	ret = cm_alloc_id(cm_id_priv);
+	if (ret)
+		goto error;
+
+	spin_lock_init(&cm_id_priv->lock);
+	init_waitqueue_head(&cm_id_priv->wait);
+	INIT_LIST_HEAD(&cm_id_priv->work_list);
+	atomic_set(&cm_id_priv->work_count, -1);
+	atomic_set(&cm_id_priv->refcount, 1);
+	return &cm_id_priv->id;
+
+error:
+	kfree(cm_id_priv);
+	return ERR_PTR(-ENOMEM);
+}
+EXPORT_SYMBOL(ib_create_cm_id);
+
+static struct cm_work * cm_dequeue_work(struct cm_id_private *cm_id_priv)
+{
+	struct cm_work *work;
+
+	if (list_empty(&cm_id_priv->work_list))
+		return NULL;
+
+	work = list_entry(cm_id_priv->work_list.next, struct cm_work, list);
+	list_del(&work->list);
+	return work;
+}
+
+static void cm_free_work(struct cm_work *work)
+{
+	if (work->mad_recv_wc)
+		ib_free_recv_mad(work->mad_recv_wc);
+	kfree(work);
+}
+
+static inline int cm_convert_to_ms(int iba_time)
+{
+	/* approximate conversion to ms from 4.096us x 2^iba_time */
+	return 1 << max(iba_time - 8, 0);
+}
+
+static void cm_cleanup_timewait(struct cm_timewait_info *timewait_info)
+{
+	unsigned long flags;
+
+	if (!timewait_info->inserted_remote_id &&
+	    !timewait_info->inserted_remote_qp)
+	    return;
+
+	spin_lock_irqsave(&cm.lock, flags);
+	if (timewait_info->inserted_remote_id) {
+		rb_erase(&timewait_info->remote_id_node, &cm.remote_id_table);
+		timewait_info->inserted_remote_id = 0;
+	}
+
+	if (timewait_info->inserted_remote_qp) {
+		rb_erase(&timewait_info->remote_qp_node, &cm.remote_qp_table);
+		timewait_info->inserted_remote_qp = 0;
+	}
+	spin_unlock_irqrestore(&cm.lock, flags);
+}
+
+static struct cm_timewait_info * cm_create_timewait_info(u32 local_id)
+{
+	struct cm_timewait_info *timewait_info;
+
+	timewait_info = kmalloc(sizeof *timewait_info, GFP_KERNEL);
+	if (!timewait_info)
+		return ERR_PTR(-ENOMEM);
+	memset(timewait_info, 0, sizeof *timewait_info);
+
+	timewait_info->work.local_id = local_id;
+	INIT_WORK(&timewait_info->work.work, cm_work_handler,
+		  &timewait_info->work);
+	timewait_info->work.cm_event.event = IB_CM_TIMEWAIT_EXIT;
+	return timewait_info;
+}
+
+static void cm_enter_timewait(struct cm_id_private *cm_id_priv)
+{
+	int wait_time;
+
+	/*
+	 * The cm_id could be destroyed by the user before we exit timewait.
+	 * To protect against this, we search for the cm_id after exiting
+	 * timewait before notifying the user that we've exited timewait.
+	 */
+	cm_id_priv->id.state = IB_CM_TIMEWAIT;
+	wait_time = cm_convert_to_ms(cm_id_priv->local_ack_timeout);
+	queue_delayed_work(cm.wq, &cm_id_priv->timewait_info->work.work,
+			   msecs_to_jiffies(wait_time));
+	cm_id_priv->timewait_info = NULL;
+}
+
+static void cm_reset_to_idle(struct cm_id_private *cm_id_priv)
+{
+	cm_id_priv->id.state = IB_CM_IDLE;
+	if (cm_id_priv->timewait_info) {
+		cm_cleanup_timewait(cm_id_priv->timewait_info);
+		kfree(cm_id_priv->timewait_info);
+		cm_id_priv->timewait_info = NULL;
+	}
+}
+
+void ib_destroy_cm_id(struct ib_cm_id *cm_id)
+{
+	struct cm_id_private *cm_id_priv;
+	struct cm_work *work;
+	unsigned long flags;
+
+	cm_id_priv = container_of(cm_id, struct cm_id_private, id);
+retest:
+	spin_lock_irqsave(&cm_id_priv->lock, flags);
+	switch (cm_id->state) {
+	case IB_CM_LISTEN:
+		cm_id->state = IB_CM_IDLE;
+		spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+		spin_lock_irqsave(&cm.lock, flags);
+		rb_erase(&cm_id_priv->service_node, &cm.listen_service_table);
+		spin_unlock_irqrestore(&cm.lock, flags);
+		break;
+	case IB_CM_SIDR_REQ_SENT:
+		cm_id->state = IB_CM_IDLE;
+		ib_cancel_mad(cm_id_priv->av.port->mad_agent,
+			      (unsigned long) cm_id_priv->msg);
+		spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+		break;
+	case IB_CM_SIDR_REQ_RCVD:
+		spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+		cm_reject_sidr_req(cm_id_priv, IB_SIDR_REJECT);
+		break;
+	case IB_CM_REQ_SENT:
+	case IB_CM_MRA_REQ_RCVD:
+	case IB_CM_REP_SENT:
+	case IB_CM_MRA_REP_RCVD:
+		ib_cancel_mad(cm_id_priv->av.port->mad_agent,
+			      (unsigned long) cm_id_priv->msg);
+		/* Fall through */
+	case IB_CM_REQ_RCVD:
+	case IB_CM_MRA_REQ_SENT:
+	case IB_CM_REP_RCVD:
+	case IB_CM_MRA_REP_SENT:
+		spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+		ib_send_cm_rej(cm_id, IB_CM_REJ_TIMEOUT,
+			       &cm_id_priv->av.port->cm_dev->ca_guid,
+			       sizeof cm_id_priv->av.port->cm_dev->ca_guid,
+			       NULL, 0);
+		break;
+	case IB_CM_ESTABLISHED:
+		spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+		ib_send_cm_dreq(cm_id, NULL, 0);
+		goto retest;
+	case IB_CM_DREQ_SENT:
+		ib_cancel_mad(cm_id_priv->av.port->mad_agent,
+			      (unsigned long) cm_id_priv->msg);
+		cm_enter_timewait(cm_id_priv);
+		spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+		break;
+	case IB_CM_DREQ_RCVD:
+		spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+		ib_send_cm_drep(cm_id, NULL, 0);
+		break;
+	default:
+		spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+		break;
+	}
+
+	cm_free_id(cm_id->local_id);
+	atomic_dec(&cm_id_priv->refcount);
+	wait_event(cm_id_priv->wait, !atomic_read(&cm_id_priv->refcount));
+	while ((work = cm_dequeue_work(cm_id_priv)) != NULL)
+		cm_free_work(work);
+	if (cm_id_priv->private_data && cm_id_priv->private_data_len)
+		kfree(cm_id_priv->private_data);
+	kfree(cm_id_priv);
+}
+EXPORT_SYMBOL(ib_destroy_cm_id);
+
+int ib_cm_listen(struct ib_cm_id *cm_id,
+		 u64 service_id,
+		 u64 service_mask)
+{
+	struct cm_id_private *cm_id_priv, *cur_cm_id_priv;
+	unsigned long flags;
+	int ret = 0;
+
+	service_mask = service_mask ? service_mask : ~0ULL;
+	service_id &= service_mask;
+	if ((service_id & IB_SERVICE_ID_AGN_MASK) == IB_CM_ASSIGN_SERVICE_ID &&
+	    (service_id != IB_CM_ASSIGN_SERVICE_ID))
+		return -EINVAL;
+
+	cm_id_priv = container_of(cm_id, struct cm_id_private, id);
+	BUG_ON(cm_id->state != IB_CM_IDLE);
+
+	cm_id->state = IB_CM_LISTEN;
+
+	spin_lock_irqsave(&cm.lock, flags);
+	if (service_id == IB_CM_ASSIGN_SERVICE_ID) {
+		cm_id->service_id = __cpu_to_be64(cm.listen_service_id++);
+		cm_id->service_mask = ~0ULL;
+	} else {
+		cm_id->service_id = service_id;
+		cm_id->service_mask = service_mask;
+	}
+	cur_cm_id_priv = cm_insert_listen(cm_id_priv);
+	spin_unlock_irqrestore(&cm.lock, flags);
+
+	if (cur_cm_id_priv) {
+		cm_id->state = IB_CM_IDLE;
+		ret = -EBUSY;
+	}
+	return ret;
+}
+EXPORT_SYMBOL(ib_cm_listen);
+
+static u64 cm_form_tid(struct cm_id_private *cm_id_priv,
+		       enum cm_msg_sequence msg_seq)
+{
+	u64 hi_tid, low_tid;
+
+	hi_tid   = ((u64) cm_id_priv->av.port->mad_agent->hi_tid) << 32;
+	low_tid  = (u64) (cm_id_priv->id.local_id | (msg_seq << 30));
+	return cpu_to_be64(hi_tid | low_tid);
+}
+
+static void cm_format_mad_hdr(struct ib_mad_hdr *hdr,
+			      enum cm_msg_attr_id attr_id, u64 tid)
+{
+	hdr->base_version  = IB_MGMT_BASE_VERSION;
+	hdr->mgmt_class	   = IB_MGMT_CLASS_CM;
+	hdr->class_version = IB_CM_CLASS_VERSION;
+	hdr->method	   = IB_MGMT_METHOD_SEND;
+	hdr->attr_id	   = attr_id;
+	hdr->tid	   = tid;
+}
+
+static void cm_format_req(struct cm_req_msg *req_msg,
+			  struct cm_id_private *cm_id_priv,
+			  struct ib_cm_req_param *param)
+{
+	cm_format_mad_hdr(&req_msg->hdr, CM_REQ_ATTR_ID,
+			  cm_form_tid(cm_id_priv, CM_MSG_SEQUENCE_REQ));
+
+	req_msg->local_comm_id = cm_id_priv->id.local_id;
+	req_msg->service_id = param->service_id;
+	req_msg->local_ca_guid = cm_id_priv->av.port->cm_dev->ca_guid;
+	cm_req_set_local_qpn(req_msg, cpu_to_be32(param->qp_num));
+	cm_req_set_resp_res(req_msg, param->responder_resources);
+	cm_req_set_init_depth(req_msg, param->initiator_depth);
+	cm_req_set_remote_resp_timeout(req_msg,
+				       param->remote_cm_response_timeout);
+	cm_req_set_qp_type(req_msg, param->qp_type);
+	cm_req_set_flow_ctrl(req_msg, param->flow_control);
+	cm_req_set_starting_psn(req_msg, cpu_to_be32(param->starting_psn));
+	cm_req_set_local_resp_timeout(req_msg,
+				      param->local_cm_response_timeout);
+	cm_req_set_retry_count(req_msg, param->retry_count);
+	req_msg->pkey = param->primary_path->pkey;
+	cm_req_set_path_mtu(req_msg, param->primary_path->mtu);
+	cm_req_set_rnr_retry_count(req_msg, param->rnr_retry_count);
+	cm_req_set_max_cm_retries(req_msg, param->max_cm_retries);
+	cm_req_set_srq(req_msg, param->srq);
+
+	req_msg->primary_local_lid = param->primary_path->slid;
+	req_msg->primary_remote_lid = param->primary_path->dlid;
+	req_msg->primary_local_gid = param->primary_path->sgid;
+	req_msg->primary_remote_gid = param->primary_path->dgid;
+	cm_req_set_primary_flow_label(req_msg, param->primary_path->flow_label);
+	cm_req_set_primary_packet_rate(req_msg, param->primary_path->rate);
+	req_msg->primary_traffic_class = param->primary_path->traffic_class;
+	req_msg->primary_hop_limit = param->primary_path->hop_limit;
+	cm_req_set_primary_sl(req_msg, param->primary_path->sl);
+	cm_req_set_primary_subnet_local(req_msg, 1); /* local only... */
+	cm_req_set_primary_local_ack_timeout(req_msg,
+		min(31, param->primary_path->packet_life_time + 1));
+
+	if (param->alternate_path) {
+		req_msg->alt_local_lid = param->alternate_path->slid;
+		req_msg->alt_remote_lid = param->alternate_path->dlid;
+		req_msg->alt_local_gid = param->alternate_path->sgid;
+		req_msg->alt_remote_gid = param->alternate_path->dgid;
+		cm_req_set_alt_flow_label(req_msg,
+					  param->alternate_path->flow_label);
+		cm_req_set_alt_packet_rate(req_msg, param->alternate_path->rate);
+		req_msg->alt_traffic_class = param->alternate_path->traffic_class;
+		req_msg->alt_hop_limit = param->alternate_path->hop_limit;
+		cm_req_set_alt_sl(req_msg, param->alternate_path->sl);
+		cm_req_set_alt_subnet_local(req_msg, 1); /* local only... */
+		cm_req_set_alt_local_ack_timeout(req_msg,
+			min(31, param->alternate_path->packet_life_time + 1));
+	}
+
+	if (param->private_data && param->private_data_len)
+		memcpy(req_msg->private_data, param->private_data,
+		       param->private_data_len);
+}
+
+static inline int cm_validate_req_param(struct ib_cm_req_param *param)
+{
+	/* peer-to-peer not supported */
+	if (param->peer_to_peer)
+		return -EINVAL;
+
+	if (!param->primary_path)
+		return -EINVAL;
+
+	if (param->qp_type != IB_QPT_RC && param->qp_type != IB_QPT_UC)
+		return -EINVAL;
+
+	if (param->private_data &&
+	    param->private_data_len > IB_CM_REQ_PRIVATE_DATA_SIZE)
+		return -EINVAL;
+
+	if (param->alternate_path &&
+	    (param->alternate_path->pkey != param->primary_path->pkey ||
+	     param->alternate_path->mtu != param->primary_path->mtu))
+		return -EINVAL;
+
+	return 0;
+}
+
+int ib_send_cm_req(struct ib_cm_id *cm_id,
+		   struct ib_cm_req_param *param)
+{
+	struct cm_id_private *cm_id_priv;
+	struct ib_send_wr *bad_send_wr;
+	struct cm_req_msg *req_msg;
+	unsigned long flags;
+	int ret;
+
+	ret = cm_validate_req_param(param);
+	if (ret)
+		return ret;
+
+	/* Verify that we're not in timewait. */
+	cm_id_priv = container_of(cm_id, struct cm_id_private, id);
+	spin_lock_irqsave(&cm_id_priv->lock, flags);
+	if (cm_id->state != IB_CM_IDLE) {
+		spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+		ret = -EINVAL;
+		goto out;
+	}
+	spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+
+	cm_id_priv->timewait_info = cm_create_timewait_info(cm_id_priv->
+							    id.local_id);
+	if (IS_ERR(cm_id_priv->timewait_info))
+		goto out;
+
+	ret = cm_init_av_by_path(param->primary_path, &cm_id_priv->av);
+	if (ret)
+		goto error1;
+	if (param->alternate_path) {
+		ret = cm_init_av_by_path(param->alternate_path,
+					 &cm_id_priv->alt_av);
+		if (ret)
+			goto error1;
+	}
+	cm_id->service_id = param->service_id;
+	cm_id->service_mask = ~0ULL;
+	cm_id_priv->timeout_ms = cm_convert_to_ms(
+				    param->primary_path->packet_life_time) * 2 +
+				 cm_convert_to_ms(
+				    param->remote_cm_response_timeout);
+	cm_id_priv->max_cm_retries = param->max_cm_retries;
+	cm_id_priv->initiator_depth = param->initiator_depth;
+	cm_id_priv->responder_resources = param->responder_resources;
+	cm_id_priv->retry_count = param->retry_count;
+	cm_id_priv->path_mtu = param->primary_path->mtu;
+
+	ret = cm_alloc_msg(cm_id_priv, &cm_id_priv->msg);
+	if (ret)
+		goto error1;
+
+	req_msg = (struct cm_req_msg *) cm_id_priv->msg->mad;
+	cm_format_req(req_msg, cm_id_priv, param);
+	cm_id_priv->tid = req_msg->hdr.tid;
+	cm_id_priv->msg->send_wr.wr.ud.timeout_ms = cm_id_priv->timeout_ms;
+	cm_id_priv->msg->context[1] = (void *) (unsigned long) IB_CM_REQ_SENT;
+
+	cm_id_priv->local_qpn = cm_req_get_local_qpn(req_msg);
+	cm_id_priv->rq_psn = cm_req_get_starting_psn(req_msg);
+	cm_id_priv->local_ack_timeout =
+				cm_req_get_primary_local_ack_timeout(req_msg);
+
+	spin_lock_irqsave(&cm_id_priv->lock, flags);
+	ret = ib_post_send_mad(cm_id_priv->av.port->mad_agent,
+				&cm_id_priv->msg->send_wr, &bad_send_wr);
+	if (ret) {
+		spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+		goto error2;
+	}
+	BUG_ON(cm_id->state != IB_CM_IDLE);
+	cm_id->state = IB_CM_REQ_SENT;
+	spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+	return 0;
+
+error2:	cm_free_msg(cm_id_priv->msg);
+error1:	kfree(cm_id_priv->timewait_info);
+out:	return ret;
+}
+EXPORT_SYMBOL(ib_send_cm_req);
+
+static int cm_issue_rej(struct cm_port *port,
+			struct ib_mad_recv_wc *mad_recv_wc,
+			enum ib_cm_rej_reason reason,
+			enum cm_msg_response msg_rejected,
+			void *ari, u8 ari_length)
+{
+	struct ib_mad_send_buf *msg = NULL;
+	struct ib_send_wr *bad_send_wr;
+	struct cm_rej_msg *rej_msg, *rcv_msg;
+	int ret;
+
+	ret = cm_alloc_response_msg(port, mad_recv_wc, &msg);
+	if (ret)
+		return ret;
+
+	/* We just need common CM header information.  Cast to any message. */
+	rcv_msg = (struct cm_rej_msg *) mad_recv_wc->recv_buf.mad;
+	rej_msg = (struct cm_rej_msg *) msg->mad;
+
+	cm_format_mad_hdr(&rej_msg->hdr, CM_REJ_ATTR_ID, rcv_msg->hdr.tid);
+	rej_msg->remote_comm_id = rcv_msg->local_comm_id;
+	rej_msg->local_comm_id = rcv_msg->remote_comm_id;
+	cm_rej_set_msg_rejected(rej_msg, msg_rejected);
+	rej_msg->reason = reason;
+
+	if (ari && ari_length) {
+		cm_rej_set_reject_info_len(rej_msg, ari_length);
+		memcpy(rej_msg->ari, ari, ari_length);
+	}
+
+	ret = ib_post_send_mad(port->mad_agent, &msg->send_wr, &bad_send_wr);
+	if (ret)
+		cm_free_msg(msg);
+
+	return ret;
+}
+
+static inline int cm_is_active_peer(u64 local_ca_guid, u64 remote_ca_guid,
+				    u32 local_qpn, u32 remote_qpn)
+{
+	return (be64_to_cpu(local_ca_guid) > be64_to_cpu(remote_ca_guid) ||
+		((local_ca_guid == remote_ca_guid) &&
+		 (be32_to_cpu(local_qpn) > be32_to_cpu(remote_qpn))));
+}
+
+static inline void cm_format_paths_from_req(struct cm_req_msg *req_msg,
+					    struct ib_sa_path_rec *primary_path,
+					    struct ib_sa_path_rec *alt_path)
+{
+	memset(primary_path, 0, sizeof *primary_path);
+	primary_path->dgid = req_msg->primary_local_gid;
+	primary_path->sgid = req_msg->primary_remote_gid;
+	primary_path->dlid = req_msg->primary_local_lid;
+	primary_path->slid = req_msg->primary_remote_lid;
+	primary_path->flow_label = cm_req_get_primary_flow_label(req_msg);
+	primary_path->hop_limit = req_msg->primary_hop_limit;
+	primary_path->traffic_class = req_msg->primary_traffic_class;
+	primary_path->reversible = 1;
+	primary_path->pkey = req_msg->pkey;
+	primary_path->sl = cm_req_get_primary_sl(req_msg);
+	primary_path->mtu_selector = IB_SA_EQ;
+	primary_path->mtu = cm_req_get_path_mtu(req_msg);
+	primary_path->rate_selector = IB_SA_EQ;
+	primary_path->rate = cm_req_get_primary_packet_rate(req_msg);
+	primary_path->packet_life_time_selector = IB_SA_EQ;
+	primary_path->packet_life_time =
+		cm_req_get_primary_local_ack_timeout(req_msg);
+	primary_path->packet_life_time -= (primary_path->packet_life_time > 0);
+
+	if (req_msg->alt_local_lid) {
+		memset(alt_path, 0, sizeof *alt_path);
+		alt_path->dgid = req_msg->alt_local_gid;
+		alt_path->sgid = req_msg->alt_remote_gid;
+		alt_path->dlid = req_msg->alt_local_lid;
+		alt_path->slid = req_msg->alt_remote_lid;
+		alt_path->flow_label = cm_req_get_alt_flow_label(req_msg);
+		alt_path->hop_limit = req_msg->alt_hop_limit;
+		alt_path->traffic_class = req_msg->alt_traffic_class;
+		alt_path->reversible = 1;
+		alt_path->pkey = req_msg->pkey;
+		alt_path->sl = cm_req_get_alt_sl(req_msg);
+		alt_path->mtu_selector = IB_SA_EQ;
+		alt_path->mtu = cm_req_get_path_mtu(req_msg);
+		alt_path->rate_selector = IB_SA_EQ;
+		alt_path->rate = cm_req_get_alt_packet_rate(req_msg);
+		alt_path->packet_life_time_selector = IB_SA_EQ;
+		alt_path->packet_life_time =
+			cm_req_get_alt_local_ack_timeout(req_msg);
+		alt_path->packet_life_time -= (alt_path->packet_life_time > 0);
+	}
+}
+
+static void cm_format_req_event(struct cm_work *work,
+				struct cm_id_private *cm_id_priv,
+				struct ib_cm_id *listen_id)
+{
+	struct cm_req_msg *req_msg;
+	struct ib_cm_req_event_param *param;
+
+	req_msg = (struct cm_req_msg *)work->mad_recv_wc->recv_buf.mad;
+	param = &work->cm_event.param.req_rcvd;
+	param->listen_id = listen_id;
+	param->device = cm_id_priv->av.port->mad_agent->device;
+	param->port = cm_id_priv->av.port->port_num;
+	param->primary_path = &work->path[0];
+	if (req_msg->alt_local_lid)
+		param->alternate_path = &work->path[1];
+	else
+		param->alternate_path = NULL;
+	param->remote_ca_guid = req_msg->local_ca_guid;
+	param->remote_qkey = be32_to_cpu(req_msg->local_qkey);
+	param->remote_qpn = be32_to_cpu(cm_req_get_local_qpn(req_msg));
+	param->qp_type = cm_req_get_qp_type(req_msg);
+	param->starting_psn = be32_to_cpu(cm_req_get_starting_psn(req_msg));
+	param->responder_resources = cm_req_get_init_depth(req_msg);
+	param->initiator_depth = cm_req_get_resp_res(req_msg);
+	param->local_cm_response_timeout =
+					cm_req_get_remote_resp_timeout(req_msg);
+	param->flow_control = cm_req_get_flow_ctrl(req_msg);
+	param->remote_cm_response_timeout =
+					cm_req_get_local_resp_timeout(req_msg);
+	param->retry_count = cm_req_get_retry_count(req_msg);
+	param->rnr_retry_count = cm_req_get_rnr_retry_count(req_msg);
+	param->srq = cm_req_get_srq(req_msg);
+	work->cm_event.private_data = &req_msg->private_data;
+}
+
+static void cm_process_work(struct cm_id_private *cm_id_priv,
+			    struct cm_work *work)
+{
+	unsigned long flags;
+	int ret;
+
+	/* We will typically only have the current event to report. */
+	ret = cm_id_priv->id.cm_handler(&cm_id_priv->id, &work->cm_event);
+	cm_free_work(work);
+
+	while (!ret && !atomic_add_negative(-1, &cm_id_priv->work_count)) {
+		spin_lock_irqsave(&cm_id_priv->lock, flags);
+		work = cm_dequeue_work(cm_id_priv);
+		spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+		BUG_ON(!work);
+		ret = cm_id_priv->id.cm_handler(&cm_id_priv->id,
+						&work->cm_event);
+		cm_free_work(work);
+	}
+	cm_deref_id(cm_id_priv);
+	if (ret)
+		ib_destroy_cm_id(&cm_id_priv->id);
+}
+
+static void cm_format_mra(struct cm_mra_msg *mra_msg,
+			  struct cm_id_private *cm_id_priv,
+			  enum cm_msg_response msg_mraed, u8 service_timeout,
+			  const void *private_data, u8 private_data_len)
+{
+	cm_format_mad_hdr(&mra_msg->hdr, CM_MRA_ATTR_ID, cm_id_priv->tid);
+	cm_mra_set_msg_mraed(mra_msg, msg_mraed);
+	mra_msg->local_comm_id = cm_id_priv->id.local_id;
+	mra_msg->remote_comm_id = cm_id_priv->id.remote_id;
+	cm_mra_set_service_timeout(mra_msg, service_timeout);
+
+	if (private_data && private_data_len)
+		memcpy(mra_msg->private_data, private_data, private_data_len);
+}
+
+static void cm_format_rej(struct cm_rej_msg *rej_msg,
+			  struct cm_id_private *cm_id_priv,
+			  enum ib_cm_rej_reason reason,
+			  void *ari,
+			  u8 ari_length,
+			  const void *private_data,
+			  u8 private_data_len)
+{
+	cm_format_mad_hdr(&rej_msg->hdr, CM_REJ_ATTR_ID, cm_id_priv->tid);
+	rej_msg->remote_comm_id = cm_id_priv->id.remote_id;
+
+	switch(cm_id_priv->id.state) {
+	case IB_CM_REQ_RCVD:
+		rej_msg->local_comm_id = 0;
+		cm_rej_set_msg_rejected(rej_msg, CM_MSG_RESPONSE_REQ);
+		break;
+	case IB_CM_MRA_REQ_SENT:
+		rej_msg->local_comm_id = cm_id_priv->id.local_id;
+		cm_rej_set_msg_rejected(rej_msg, CM_MSG_RESPONSE_REQ);
+		break;
+	case IB_CM_REP_RCVD:
+	case IB_CM_MRA_REP_SENT:
+		rej_msg->local_comm_id = cm_id_priv->id.local_id;
+		cm_rej_set_msg_rejected(rej_msg, CM_MSG_RESPONSE_REP);
+		break;
+	default:
+		rej_msg->local_comm_id = cm_id_priv->id.local_id;
+		cm_rej_set_msg_rejected(rej_msg, CM_MSG_RESPONSE_OTHER);
+		break;
+	}
+
+	rej_msg->reason = reason;
+	if (ari && ari_length) {
+		cm_rej_set_reject_info_len(rej_msg, ari_length);
+		memcpy(rej_msg->ari, ari, ari_length);
+	}
+
+	if (private_data && private_data_len)
+		memcpy(rej_msg->private_data, private_data, private_data_len);
+}
+
+static void cm_dup_req_handler(struct cm_work *work,
+			       struct cm_id_private *cm_id_priv)
+{
+	struct ib_mad_send_buf *msg = NULL;
+	struct ib_send_wr *bad_send_wr;
+	unsigned long flags;
+	int ret;
+
+	/* Quick state check to discard duplicate REQs. */
+	if (cm_id_priv->id.state == IB_CM_REQ_RCVD)
+		return;
+
+	ret = cm_alloc_response_msg(work->port, work->mad_recv_wc, &msg);
+	if (ret)
+		return;
+
+	spin_lock_irqsave(&cm_id_priv->lock, flags);
+	switch (cm_id_priv->id.state) {
+	case IB_CM_MRA_REQ_SENT:
+		cm_format_mra((struct cm_mra_msg *) msg->mad, cm_id_priv,
+			      CM_MSG_RESPONSE_REQ, cm_id_priv->service_timeout,
+			      cm_id_priv->private_data,
+			      cm_id_priv->private_data_len);
+		break;
+	case IB_CM_TIMEWAIT:
+		cm_format_rej((struct cm_rej_msg *) msg->mad, cm_id_priv,
+			      IB_CM_REJ_STALE_CONN, NULL, 0, NULL, 0);
+		break;
+	default:
+		goto unlock;
+	}
+	spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+
+	ret = ib_post_send_mad(cm_id_priv->av.port->mad_agent, &msg->send_wr,
+			       &bad_send_wr);
+	if (ret)
+		goto free;
+	return;
+
+unlock:	spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+free:	cm_free_msg(msg);
+}
+
+static struct cm_id_private * cm_match_req(struct cm_work *work,
+					   struct cm_id_private *cm_id_priv)
+{
+	struct cm_id_private *listen_cm_id_priv, *cur_cm_id_priv;
+	struct cm_timewait_info *timewait_info;
+	struct cm_req_msg *req_msg;
+	unsigned long flags;
+
+	req_msg = (struct cm_req_msg *)work->mad_recv_wc->recv_buf.mad;
+
+	/* Check for duplicate REQ and stale connections. */
+	spin_lock_irqsave(&cm.lock, flags);
+	timewait_info = cm_insert_remote_id(cm_id_priv->timewait_info);
+	if (!timewait_info)
+		timewait_info = cm_insert_remote_qpn(cm_id_priv->timewait_info);
+
+	if (timewait_info) {
+		cur_cm_id_priv = cm_get_id(timewait_info->work.local_id,
+					   timewait_info->work.remote_id);
+		spin_unlock_irqrestore(&cm.lock, flags);
+		if (cur_cm_id_priv) {
+			cm_dup_req_handler(work, cur_cm_id_priv);
+			cm_deref_id(cur_cm_id_priv);
+		} else
+			cm_issue_rej(work->port, work->mad_recv_wc,
+				     IB_CM_REJ_STALE_CONN, CM_MSG_RESPONSE_REQ,
+				     NULL, 0);
+		goto error;
+	}
+
+	/* Find matching listen request. */
+	listen_cm_id_priv = cm_find_listen(req_msg->service_id);
+	if (!listen_cm_id_priv) {
+		spin_unlock_irqrestore(&cm.lock, flags);
+		cm_issue_rej(work->port, work->mad_recv_wc,
+			     IB_CM_REJ_INVALID_SERVICE_ID, CM_MSG_RESPONSE_REQ,
+			     NULL, 0);
+		goto error;
+	}
+	atomic_inc(&listen_cm_id_priv->refcount);
+	atomic_inc(&cm_id_priv->refcount);
+	cm_id_priv->id.state = IB_CM_REQ_RCVD;
+	atomic_inc(&cm_id_priv->work_count);
+	spin_unlock_irqrestore(&cm.lock, flags);
+	return listen_cm_id_priv;
+
+error:	cm_cleanup_timewait(cm_id_priv->timewait_info);
+	return NULL;
+}
+
+static int cm_req_handler(struct cm_work *work)
+{
+	struct ib_cm_id *cm_id;
+	struct cm_id_private *cm_id_priv, *listen_cm_id_priv;
+	struct cm_req_msg *req_msg;
+	int ret;
+
+	req_msg = (struct cm_req_msg *)work->mad_recv_wc->recv_buf.mad;
+
+	cm_id = ib_create_cm_id(NULL, NULL);
+	if (IS_ERR(cm_id))
+		return PTR_ERR(cm_id);
+
+	cm_id_priv = container_of(cm_id, struct cm_id_private, id);
+	cm_id_priv->id.remote_id = req_msg->local_comm_id;
+	cm_init_av_for_response(work->port, work->mad_recv_wc->wc,
+				&cm_id_priv->av);
+	cm_id_priv->timewait_info = cm_create_timewait_info(cm_id_priv->
+							    id.local_id);
+	if (IS_ERR(cm_id_priv->timewait_info)) {
+		ret = PTR_ERR(cm_id_priv->timewait_info);
+		goto error1;
+	}
+	cm_id_priv->timewait_info->work.remote_id = req_msg->local_comm_id;
+	cm_id_priv->timewait_info->remote_ca_guid = req_msg->local_ca_guid;
+	cm_id_priv->timewait_info->remote_qpn = cm_req_get_local_qpn(req_msg);
+
+	listen_cm_id_priv = cm_match_req(work, cm_id_priv);
+	if (!listen_cm_id_priv) {
+		ret = -EINVAL;
+		goto error2;
+	}
+
+	cm_id_priv->id.cm_handler = listen_cm_id_priv->id.cm_handler;
+	cm_id_priv->id.context = listen_cm_id_priv->id.context;
+	cm_id_priv->id.service_id = req_msg->service_id;
+	cm_id_priv->id.service_mask = ~0ULL;
+
+	cm_format_paths_from_req(req_msg, &work->path[0], &work->path[1]);
+	ret = cm_init_av_by_path(&work->path[0], &cm_id_priv->av);
+	if (ret)
+		goto error3;
+	if (req_msg->alt_local_lid) {
+		ret = cm_init_av_by_path(&work->path[1], &cm_id_priv->alt_av);
+		if (ret)
+			goto error3;
+	}
+	cm_id_priv->tid = req_msg->hdr.tid;
+	cm_id_priv->timeout_ms = cm_convert_to_ms(
+					cm_req_get_local_resp_timeout(req_msg));
+	cm_id_priv->max_cm_retries = cm_req_get_max_cm_retries(req_msg);
+	cm_id_priv->remote_qpn = cm_req_get_local_qpn(req_msg);
+	cm_id_priv->initiator_depth = cm_req_get_resp_res(req_msg);
+	cm_id_priv->responder_resources = cm_req_get_init_depth(req_msg);
+	cm_id_priv->path_mtu = cm_req_get_path_mtu(req_msg);
+	cm_id_priv->sq_psn = cm_req_get_starting_psn(req_msg);
+	cm_id_priv->local_ack_timeout =
+				cm_req_get_primary_local_ack_timeout(req_msg);
+	cm_id_priv->retry_count = cm_req_get_retry_count(req_msg);
+	cm_id_priv->rnr_retry_count = cm_req_get_rnr_retry_count(req_msg);
+
+	cm_format_req_event(work, cm_id_priv, &listen_cm_id_priv->id);
+	cm_process_work(cm_id_priv, work);
+	cm_deref_id(listen_cm_id_priv);
+	return 0;
+
+error3:	atomic_dec(&cm_id_priv->refcount);
+	cm_deref_id(listen_cm_id_priv);
+	cm_cleanup_timewait(cm_id_priv->timewait_info);
+error2:	kfree(cm_id_priv->timewait_info);
+error1:	ib_destroy_cm_id(&cm_id_priv->id);
+	return ret;
+}
+
+static void cm_format_rep(struct cm_rep_msg *rep_msg,
+			  struct cm_id_private *cm_id_priv,
+			  struct ib_cm_rep_param *param)
+{
+	cm_format_mad_hdr(&rep_msg->hdr, CM_REP_ATTR_ID, cm_id_priv->tid);
+	rep_msg->local_comm_id = cm_id_priv->id.local_id;
+	rep_msg->remote_comm_id = cm_id_priv->id.remote_id;
+	cm_rep_set_local_qpn(rep_msg, cpu_to_be32(param->qp_num));
+	cm_rep_set_starting_psn(rep_msg, cpu_to_be32(param->starting_psn));
+	rep_msg->resp_resources = param->responder_resources;
+	rep_msg->initiator_depth = param->initiator_depth;
+	cm_rep_set_target_ack_delay(rep_msg, param->target_ack_delay);
+	cm_rep_set_failover(rep_msg, param->failover_accepted);
+	cm_rep_set_flow_ctrl(rep_msg, param->flow_control);
+	cm_rep_set_rnr_retry_count(rep_msg, param->rnr_retry_count);
+	cm_rep_set_srq(rep_msg, param->srq);
+	rep_msg->local_ca_guid = cm_id_priv->av.port->cm_dev->ca_guid;
+
+	if (param->private_data && param->private_data_len)
+		memcpy(rep_msg->private_data, param->private_data,
+		       param->private_data_len);
+}
+
+int ib_send_cm_rep(struct ib_cm_id *cm_id,
+		   struct ib_cm_rep_param *param)
+{
+	struct cm_id_private *cm_id_priv;
+	struct ib_mad_send_buf *msg;
+	struct cm_rep_msg *rep_msg;
+	struct ib_send_wr *bad_send_wr;
+	unsigned long flags;
+	int ret;
+
+	if (param->private_data &&
+	    param->private_data_len > IB_CM_REP_PRIVATE_DATA_SIZE)
+		return -EINVAL;
+
+	cm_id_priv = container_of(cm_id, struct cm_id_private, id);
+	spin_lock_irqsave(&cm_id_priv->lock, flags);
+	if (cm_id->state != IB_CM_REQ_RCVD &&
+	    cm_id->state != IB_CM_MRA_REQ_SENT) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	ret = cm_alloc_msg(cm_id_priv, &msg);
+	if (ret)
+		goto out;
+
+	rep_msg = (struct cm_rep_msg *) msg->mad;
+	cm_format_rep(rep_msg, cm_id_priv, param);
+	msg->send_wr.wr.ud.timeout_ms = cm_id_priv->timeout_ms;
+	msg->context[1] = (void *) (unsigned long) IB_CM_REP_SENT;
+
+	ret = ib_post_send_mad(cm_id_priv->av.port->mad_agent,
+			       &msg->send_wr, &bad_send_wr);
+	if (ret) {
+		spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+		cm_free_msg(msg);
+		return ret;
+	}
+
+	cm_id->state = IB_CM_REP_SENT;
+	cm_id_priv->msg = msg;
+	cm_id_priv->initiator_depth = param->initiator_depth;
+	cm_id_priv->responder_resources = param->responder_resources;
+	cm_id_priv->rq_psn = cm_rep_get_starting_psn(rep_msg);
+	cm_id_priv->local_qpn = cm_rep_get_local_qpn(rep_msg);
+
+out:	spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+	return ret;
+}
+EXPORT_SYMBOL(ib_send_cm_rep);
+
+static void cm_format_rtu(struct cm_rtu_msg *rtu_msg,
+			  struct cm_id_private *cm_id_priv,
+			  const void *private_data,
+			  u8 private_data_len)
+{
+	cm_format_mad_hdr(&rtu_msg->hdr, CM_RTU_ATTR_ID, cm_id_priv->tid);
+	rtu_msg->local_comm_id = cm_id_priv->id.local_id;
+	rtu_msg->remote_comm_id = cm_id_priv->id.remote_id;
+
+	if (private_data && private_data_len)
+		memcpy(rtu_msg->private_data, private_data, private_data_len);
+}
+
+int ib_send_cm_rtu(struct ib_cm_id *cm_id,
+		   const void *private_data,
+		   u8 private_data_len)
+{
+	struct cm_id_private *cm_id_priv;
+	struct ib_mad_send_buf *msg;
+	struct ib_send_wr *bad_send_wr;
+	unsigned long flags;
+	void *data;
+	int ret;
+
+	if (private_data && private_data_len > IB_CM_RTU_PRIVATE_DATA_SIZE)
+		return -EINVAL;
+
+	data = cm_copy_private_data(private_data, private_data_len);
+	if (IS_ERR(data))
+		return PTR_ERR(data);
+
+	cm_id_priv = container_of(cm_id, struct cm_id_private, id);
+	spin_lock_irqsave(&cm_id_priv->lock, flags);
+	if (cm_id->state != IB_CM_REP_RCVD &&
+	    cm_id->state != IB_CM_MRA_REP_SENT) {
+		ret = -EINVAL;
+		goto error;
+	}
+
+	ret = cm_alloc_msg(cm_id_priv, &msg);
+	if (ret)
+		goto error;
+
+	cm_format_rtu((struct cm_rtu_msg *) msg->mad, cm_id_priv,
+		      private_data, private_data_len);
+
+	ret = ib_post_send_mad(cm_id_priv->av.port->mad_agent,
+			       &msg->send_wr, &bad_send_wr);
+	if (ret) {
+		spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+		cm_free_msg(msg);
+		kfree(data);
+		return ret;
+	}
+
+	cm_id->state = IB_CM_ESTABLISHED;
+	cm_set_private_data(cm_id_priv, data, private_data_len);
+	spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+	return 0;
+
+error:	spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+	kfree(data);
+	return ret;
+}
+EXPORT_SYMBOL(ib_send_cm_rtu);
+
+static void cm_format_rep_event(struct cm_work *work)
+{
+	struct cm_rep_msg *rep_msg;
+	struct ib_cm_rep_event_param *param;
+
+	rep_msg = (struct cm_rep_msg *)work->mad_recv_wc->recv_buf.mad;
+	param = &work->cm_event.param.rep_rcvd;
+	param->remote_ca_guid = rep_msg->local_ca_guid;
+	param->remote_qkey = be32_to_cpu(rep_msg->local_qkey);
+	param->remote_qpn = be32_to_cpu(cm_rep_get_local_qpn(rep_msg));
+	param->starting_psn = be32_to_cpu(cm_rep_get_starting_psn(rep_msg));
+	param->responder_resources = rep_msg->initiator_depth;
+	param->initiator_depth = rep_msg->resp_resources;
+	param->target_ack_delay = cm_rep_get_target_ack_delay(rep_msg);
+	param->failover_accepted = cm_rep_get_failover(rep_msg);
+	param->flow_control = cm_rep_get_flow_ctrl(rep_msg);
+	param->rnr_retry_count = cm_rep_get_rnr_retry_count(rep_msg);
+	param->srq = cm_rep_get_srq(rep_msg);
+	work->cm_event.private_data = &rep_msg->private_data;
+}
+
+static void cm_dup_rep_handler(struct cm_work *work)
+{
+	struct cm_id_private *cm_id_priv;
+	struct cm_rep_msg *rep_msg;
+	struct ib_mad_send_buf *msg = NULL;
+	struct ib_send_wr *bad_send_wr;
+	unsigned long flags;
+	int ret;
+
+	rep_msg = (struct cm_rep_msg *) work->mad_recv_wc->recv_buf.mad;
+	cm_id_priv = cm_acquire_id(rep_msg->remote_comm_id,
+				   rep_msg->local_comm_id);
+	if (!cm_id_priv)
+		return;
+
+	ret = cm_alloc_response_msg(work->port, work->mad_recv_wc, &msg);
+	if (ret)
+		goto deref;
+
+	spin_lock_irqsave(&cm_id_priv->lock, flags);
+	if (cm_id_priv->id.state == IB_CM_ESTABLISHED)
+		cm_format_rtu((struct cm_rtu_msg *) msg->mad, cm_id_priv,
+			      cm_id_priv->private_data,
+			      cm_id_priv->private_data_len);
+	else if (cm_id_priv->id.state == IB_CM_MRA_REP_SENT)
+		cm_format_mra((struct cm_mra_msg *) msg->mad, cm_id_priv,
+			      CM_MSG_RESPONSE_REP, cm_id_priv->service_timeout,
+			      cm_id_priv->private_data,
+			      cm_id_priv->private_data_len);
+	else
+		goto unlock;
+	spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+
+	ret = ib_post_send_mad(cm_id_priv->av.port->mad_agent, &msg->send_wr,
+			       &bad_send_wr);
+	if (ret)
+		goto free;
+	goto deref;
+
+unlock:	spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+free:	cm_free_msg(msg);
+deref:	cm_deref_id(cm_id_priv);
+}
+
+static int cm_rep_handler(struct cm_work *work)
+{
+	struct cm_id_private *cm_id_priv;
+	struct cm_rep_msg *rep_msg;
+	unsigned long flags;
+	int ret;
+
+	rep_msg = (struct cm_rep_msg *)work->mad_recv_wc->recv_buf.mad;
+	cm_id_priv = cm_acquire_id(rep_msg->remote_comm_id, 0);
+	if (!cm_id_priv) {
+		cm_dup_rep_handler(work);
+		return -EINVAL;
+	}
+
+	cm_id_priv->timewait_info->work.remote_id = rep_msg->local_comm_id;
+	cm_id_priv->timewait_info->remote_ca_guid = rep_msg->local_ca_guid;
+	cm_id_priv->timewait_info->remote_qpn = cm_rep_get_local_qpn(rep_msg);
+
+	spin_lock_irqsave(&cm.lock, flags);
+	/* Check for duplicate REP. */
+	if (cm_insert_remote_id(cm_id_priv->timewait_info)) {
+		spin_unlock_irqrestore(&cm.lock, flags);
+		ret = -EINVAL;
+		goto error;
+	}
+	/* Check for a stale connection. */
+	if (cm_insert_remote_qpn(cm_id_priv->timewait_info)) {
+		spin_unlock_irqrestore(&cm.lock, flags);
+		cm_issue_rej(work->port, work->mad_recv_wc,
+			     IB_CM_REJ_STALE_CONN, CM_MSG_RESPONSE_REP,
+			     NULL, 0);
+		ret = -EINVAL;
+		goto error;
+	}
+	spin_unlock_irqrestore(&cm.lock, flags);
+
+	cm_format_rep_event(work);
+
+	spin_lock_irqsave(&cm_id_priv->lock, flags);
+	switch (cm_id_priv->id.state) {
+	case IB_CM_REQ_SENT:
+	case IB_CM_MRA_REQ_RCVD:
+		break;
+	default:
+		spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+		ret = -EINVAL;
+		goto error;
+	}
+	cm_id_priv->id.state = IB_CM_REP_RCVD;
+	cm_id_priv->id.remote_id = rep_msg->local_comm_id;
+	cm_id_priv->remote_qpn = cm_rep_get_local_qpn(rep_msg);
+	cm_id_priv->initiator_depth = rep_msg->resp_resources;
+	cm_id_priv->responder_resources = rep_msg->initiator_depth;
+	cm_id_priv->sq_psn = cm_rep_get_starting_psn(rep_msg);
+	cm_id_priv->rnr_retry_count = cm_rep_get_rnr_retry_count(rep_msg);
+
+	/* todo: handle peer_to_peer */
+
+	ib_cancel_mad(cm_id_priv->av.port->mad_agent,
+		      (unsigned long) cm_id_priv->msg);
+	ret = atomic_inc_and_test(&cm_id_priv->work_count);
+	if (!ret)
+		list_add_tail(&work->list, &cm_id_priv->work_list);
+	spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+
+	if (ret)
+		cm_process_work(cm_id_priv, work);
+	else
+		cm_deref_id(cm_id_priv);
+	return 0;
+
+error:	cm_cleanup_timewait(cm_id_priv->timewait_info);
+	cm_deref_id(cm_id_priv);
+	return ret;
+}
+
+static int cm_establish_handler(struct cm_work *work)
+{
+	struct cm_id_private *cm_id_priv;
+	unsigned long flags;
+	int ret;
+
+	/* See comment in ib_cm_establish about lookup. */
+	cm_id_priv = cm_acquire_id(work->local_id, work->remote_id);
+	if (!cm_id_priv)
+		return -EINVAL;
+
+	spin_lock_irqsave(&cm_id_priv->lock, flags);
+	if (cm_id_priv->id.state != IB_CM_ESTABLISHED) {
+		spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+		goto out;
+	}
+
+	ib_cancel_mad(cm_id_priv->av.port->mad_agent,
+		      (unsigned long) cm_id_priv->msg);
+	ret = atomic_inc_and_test(&cm_id_priv->work_count);
+	if (!ret)
+		list_add_tail(&work->list, &cm_id_priv->work_list);
+	spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+
+	if (ret)
+		cm_process_work(cm_id_priv, work);
+	else
+		cm_deref_id(cm_id_priv);
+	return 0;
+out:
+	cm_deref_id(cm_id_priv);
+	return -EINVAL;
+}
+
+static int cm_rtu_handler(struct cm_work *work)
+{
+	struct cm_id_private *cm_id_priv;
+	struct cm_rtu_msg *rtu_msg;
+	unsigned long flags;
+	int ret;
+
+	rtu_msg = (struct cm_rtu_msg *)work->mad_recv_wc->recv_buf.mad;
+	cm_id_priv = cm_acquire_id(rtu_msg->remote_comm_id,
+				   rtu_msg->local_comm_id);
+	if (!cm_id_priv)
+		return -EINVAL;
+
+	work->cm_event.private_data = &rtu_msg->private_data;
+
+	spin_lock_irqsave(&cm_id_priv->lock, flags);
+	if (cm_id_priv->id.state != IB_CM_REP_SENT &&
+	    cm_id_priv->id.state != IB_CM_MRA_REP_RCVD) {
+		spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+		goto out;
+	}
+	cm_id_priv->id.state = IB_CM_ESTABLISHED;
+
+	ib_cancel_mad(cm_id_priv->av.port->mad_agent,
+		      (unsigned long) cm_id_priv->msg);
+	ret = atomic_inc_and_test(&cm_id_priv->work_count);
+	if (!ret)
+		list_add_tail(&work->list, &cm_id_priv->work_list);
+	spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+
+	if (ret)
+		cm_process_work(cm_id_priv, work);
+	else
+		cm_deref_id(cm_id_priv);
+	return 0;
+out:
+	cm_deref_id(cm_id_priv);
+	return -EINVAL;
+}
+
+static void cm_format_dreq(struct cm_dreq_msg *dreq_msg,
+			  struct cm_id_private *cm_id_priv,
+			  const void *private_data,
+			  u8 private_data_len)
+{
+	cm_format_mad_hdr(&dreq_msg->hdr, CM_DREQ_ATTR_ID,
+			  cm_form_tid(cm_id_priv, CM_MSG_SEQUENCE_DREQ));
+	dreq_msg->local_comm_id = cm_id_priv->id.local_id;
+	dreq_msg->remote_comm_id = cm_id_priv->id.remote_id;
+	cm_dreq_set_remote_qpn(dreq_msg, cm_id_priv->remote_qpn);
+
+	if (private_data && private_data_len)
+		memcpy(dreq_msg->private_data, private_data, private_data_len);
+}
+
+int ib_send_cm_dreq(struct ib_cm_id *cm_id,
+		    const void *private_data,
+		    u8 private_data_len)
+{
+	struct cm_id_private *cm_id_priv;
+	struct ib_mad_send_buf *msg;
+	struct ib_send_wr *bad_send_wr;
+	unsigned long flags;
+	int ret;
+
+	if (private_data && private_data_len > IB_CM_DREQ_PRIVATE_DATA_SIZE)
+		return -EINVAL;
+
+	cm_id_priv = container_of(cm_id, struct cm_id_private, id);
+	spin_lock_irqsave(&cm_id_priv->lock, flags);
+	if (cm_id->state != IB_CM_ESTABLISHED) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	ret = cm_alloc_msg(cm_id_priv, &msg);
+	if (ret) {
+		cm_enter_timewait(cm_id_priv);
+		goto out;
+	}
+
+	cm_format_dreq((struct cm_dreq_msg *) msg->mad, cm_id_priv,
+		       private_data, private_data_len);
+	msg->send_wr.wr.ud.timeout_ms = cm_id_priv->timeout_ms;
+	msg->context[1] = (void *) (unsigned long) IB_CM_DREQ_SENT;
+
+	ret = ib_post_send_mad(cm_id_priv->av.port->mad_agent,
+			       &msg->send_wr, &bad_send_wr);
+	if (ret) {
+		cm_enter_timewait(cm_id_priv);
+		spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+		cm_free_msg(msg);
+		return ret;
+	}
+
+	cm_id->state = IB_CM_DREQ_SENT;
+	cm_id_priv->msg = msg;
+out:	spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+	return ret;
+}
+EXPORT_SYMBOL(ib_send_cm_dreq);
+
+static void cm_format_drep(struct cm_drep_msg *drep_msg,
+			  struct cm_id_private *cm_id_priv,
+			  const void *private_data,
+			  u8 private_data_len)
+{
+	cm_format_mad_hdr(&drep_msg->hdr, CM_DREP_ATTR_ID, cm_id_priv->tid);
+	drep_msg->local_comm_id = cm_id_priv->id.local_id;
+	drep_msg->remote_comm_id = cm_id_priv->id.remote_id;
+
+	if (private_data && private_data_len)
+		memcpy(drep_msg->private_data, private_data, private_data_len);
+}
+
+int ib_send_cm_drep(struct ib_cm_id *cm_id,
+		    const void *private_data,
+		    u8 private_data_len)
+{
+	struct cm_id_private *cm_id_priv;
+	struct ib_mad_send_buf *msg;
+	struct ib_send_wr *bad_send_wr;
+	unsigned long flags;
+	void *data;
+	int ret;
+
+	if (private_data && private_data_len > IB_CM_DREP_PRIVATE_DATA_SIZE)
+		return -EINVAL;
+
+	data = cm_copy_private_data(private_data, private_data_len);
+	if (IS_ERR(data))
+		return PTR_ERR(data);
+
+	cm_id_priv = container_of(cm_id, struct cm_id_private, id);
+	spin_lock_irqsave(&cm_id_priv->lock, flags);
+	if (cm_id->state != IB_CM_DREQ_RCVD) {
+		spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+		kfree(data);
+		return -EINVAL;
+	}
+
+	cm_set_private_data(cm_id_priv, data, private_data_len);
+	cm_enter_timewait(cm_id_priv);
+
+	ret = cm_alloc_msg(cm_id_priv, &msg);
+	if (ret)
+		goto out;
+
+	cm_format_drep((struct cm_drep_msg *) msg->mad, cm_id_priv,
+		       private_data, private_data_len);
+
+	ret = ib_post_send_mad(cm_id_priv->av.port->mad_agent, &msg->send_wr,
+			       &bad_send_wr);
+	if (ret) {
+		spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+		cm_free_msg(msg);
+		return ret;
+	}
+
+out:	spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+	return ret;
+}
+EXPORT_SYMBOL(ib_send_cm_drep);
+
+static int cm_dreq_handler(struct cm_work *work)
+{
+	struct cm_id_private *cm_id_priv;
+	struct cm_dreq_msg *dreq_msg;
+	struct ib_mad_send_buf *msg = NULL;
+	struct ib_send_wr *bad_send_wr;
+	unsigned long flags;
+	int ret;
+
+	dreq_msg = (struct cm_dreq_msg *)work->mad_recv_wc->recv_buf.mad;
+	cm_id_priv = cm_acquire_id(dreq_msg->remote_comm_id,
+				   dreq_msg->local_comm_id);
+	if (!cm_id_priv)
+		return -EINVAL;
+
+	work->cm_event.private_data = &dreq_msg->private_data;
+
+	spin_lock_irqsave(&cm_id_priv->lock, flags);
+	if (cm_id_priv->local_qpn != cm_dreq_get_remote_qpn(dreq_msg))
+		goto unlock;
+
+	switch (cm_id_priv->id.state) {
+	case IB_CM_REP_SENT:
+	case IB_CM_DREQ_SENT:
+		ib_cancel_mad(cm_id_priv->av.port->mad_agent,
+			      (unsigned long) cm_id_priv->msg);
+		break;
+	case IB_CM_ESTABLISHED:
+	case IB_CM_MRA_REP_RCVD:
+		break;
+	case IB_CM_TIMEWAIT:
+		if (cm_alloc_response_msg(work->port, work->mad_recv_wc, &msg))
+			goto unlock;
+
+		cm_format_drep((struct cm_drep_msg *) msg->mad, cm_id_priv,
+			       cm_id_priv->private_data,
+			       cm_id_priv->private_data_len);
+		spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+
+		if (ib_post_send_mad(cm_id_priv->av.port->mad_agent,
+				     &msg->send_wr, &bad_send_wr))
+			cm_free_msg(msg);
+		goto deref;
+	default:
+		goto unlock;
+	}
+	cm_id_priv->id.state = IB_CM_DREQ_RCVD;
+	cm_id_priv->tid = dreq_msg->hdr.tid;
+	ret = atomic_inc_and_test(&cm_id_priv->work_count);
+	if (!ret)
+		list_add_tail(&work->list, &cm_id_priv->work_list);
+	spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+
+	if (ret)
+		cm_process_work(cm_id_priv, work);
+	else
+		cm_deref_id(cm_id_priv);
+	return 0;
+
+unlock:	spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+deref:	cm_deref_id(cm_id_priv);
+	return -EINVAL;
+}
+
+static int cm_drep_handler(struct cm_work *work)
+{
+	struct cm_id_private *cm_id_priv;
+	struct cm_drep_msg *drep_msg;
+	unsigned long flags;
+	int ret;
+
+	drep_msg = (struct cm_drep_msg *)work->mad_recv_wc->recv_buf.mad;
+	cm_id_priv = cm_acquire_id(drep_msg->remote_comm_id,
+				   drep_msg->local_comm_id);
+	if (!cm_id_priv)
+		return -EINVAL;
+
+	work->cm_event.private_data = &drep_msg->private_data;
+
+	spin_lock_irqsave(&cm_id_priv->lock, flags);
+	if (cm_id_priv->id.state != IB_CM_DREQ_SENT &&
+	    cm_id_priv->id.state != IB_CM_DREQ_RCVD) {
+		spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+		goto out;
+	}
+	cm_enter_timewait(cm_id_priv);
+
+	ib_cancel_mad(cm_id_priv->av.port->mad_agent,
+		      (unsigned long) cm_id_priv->msg);
+	ret = atomic_inc_and_test(&cm_id_priv->work_count);
+	if (!ret)
+		list_add_tail(&work->list, &cm_id_priv->work_list);
+	spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+
+	if (ret)
+		cm_process_work(cm_id_priv, work);
+	else
+		cm_deref_id(cm_id_priv);
+	return 0;
+out:
+	cm_deref_id(cm_id_priv);
+	return -EINVAL;
+}
+
+int ib_send_cm_rej(struct ib_cm_id *cm_id,
+		   enum ib_cm_rej_reason reason,
+		   void *ari,
+		   u8 ari_length,
+		   const void *private_data,
+		   u8 private_data_len)
+{
+	struct cm_id_private *cm_id_priv;
+	struct ib_mad_send_buf *msg;
+	struct ib_send_wr *bad_send_wr;
+	unsigned long flags;
+	int ret;
+
+	if ((private_data && private_data_len > IB_CM_REJ_PRIVATE_DATA_SIZE) ||
+	    (ari && ari_length > IB_CM_REJ_ARI_LENGTH))
+		return -EINVAL;
+
+	cm_id_priv = container_of(cm_id, struct cm_id_private, id);
+
+	spin_lock_irqsave(&cm_id_priv->lock, flags);
+	switch (cm_id->state) {
+	case IB_CM_REQ_SENT:
+	case IB_CM_MRA_REQ_RCVD:
+	case IB_CM_REQ_RCVD:
+	case IB_CM_MRA_REQ_SENT:
+	case IB_CM_REP_RCVD:
+	case IB_CM_MRA_REP_SENT:
+		ret = cm_alloc_msg(cm_id_priv, &msg);
+		if (!ret)
+			cm_format_rej((struct cm_rej_msg *) msg->mad,
+				      cm_id_priv, reason, ari, ari_length,
+				      private_data, private_data_len);
+
+		cm_reset_to_idle(cm_id_priv);
+		break;
+	case IB_CM_REP_SENT:
+	case IB_CM_MRA_REP_RCVD:
+		ret = cm_alloc_msg(cm_id_priv, &msg);
+		if (!ret)
+			cm_format_rej((struct cm_rej_msg *) msg->mad,
+				      cm_id_priv, reason, ari, ari_length,
+				      private_data, private_data_len);
+
+		cm_enter_timewait(cm_id_priv);
+		break;
+	default:
+		ret = -EINVAL;
+		goto out;
+	}
+
+	if (ret)
+		goto out;
+
+	ret = ib_post_send_mad(cm_id_priv->av.port->mad_agent,
+			       &msg->send_wr, &bad_send_wr);
+	if (ret)
+		cm_free_msg(msg);
+
+out:	spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+	return ret;
+}
+EXPORT_SYMBOL(ib_send_cm_rej);
+
+static void cm_format_rej_event(struct cm_work *work)
+{
+	struct cm_rej_msg *rej_msg;
+	struct ib_cm_rej_event_param *param;
+
+	rej_msg = (struct cm_rej_msg *)work->mad_recv_wc->recv_buf.mad;
+	param = &work->cm_event.param.rej_rcvd;
+	param->ari = rej_msg->ari;
+	param->ari_length = cm_rej_get_reject_info_len(rej_msg);
+	param->reason = rej_msg->reason;
+	work->cm_event.private_data = &rej_msg->private_data;
+}
+
+static struct cm_id_private * cm_acquire_rejected_id(struct cm_rej_msg *rej_msg)
+{
+	struct cm_timewait_info *timewait_info;
+	struct cm_id_private *cm_id_priv;
+	unsigned long flags;
+	u32 remote_id;
+
+	remote_id = rej_msg->local_comm_id;
+
+	if (rej_msg->reason == IB_CM_REJ_TIMEOUT) {
+		spin_lock_irqsave(&cm.lock, flags);
+		timewait_info = cm_find_remote_id( *((u64 *) rej_msg->ari),
+						  remote_id);
+		if (!timewait_info) {
+			spin_unlock_irqrestore(&cm.lock, flags);
+			return NULL;
+		}
+		cm_id_priv = idr_find(&cm.local_id_table,
+				      (int) timewait_info->work.local_id);
+		if (cm_id_priv) {
+			if (cm_id_priv->id.remote_id == remote_id)
+				atomic_inc(&cm_id_priv->refcount);
+			else
+				cm_id_priv = NULL;
+		}
+		spin_unlock_irqrestore(&cm.lock, flags);
+	} else if (cm_rej_get_msg_rejected(rej_msg) == CM_MSG_RESPONSE_REQ)
+		cm_id_priv = cm_acquire_id(rej_msg->remote_comm_id, 0);
+	else
+		cm_id_priv = cm_acquire_id(rej_msg->remote_comm_id, remote_id);
+
+	return cm_id_priv;
+}
+
+static int cm_rej_handler(struct cm_work *work)
+{
+	struct cm_id_private *cm_id_priv;
+	struct cm_rej_msg *rej_msg;
+	unsigned long flags;
+	int ret;
+
+	rej_msg = (struct cm_rej_msg *)work->mad_recv_wc->recv_buf.mad;
+	cm_id_priv = cm_acquire_rejected_id(rej_msg);
+	if (!cm_id_priv)
+		return -EINVAL;
+
+	cm_format_rej_event(work);
+
+	spin_lock_irqsave(&cm_id_priv->lock, flags);
+	switch (cm_id_priv->id.state) {
+	case IB_CM_REQ_SENT:
+	case IB_CM_MRA_REQ_RCVD:
+	case IB_CM_REP_SENT:
+	case IB_CM_MRA_REP_RCVD:
+		ib_cancel_mad(cm_id_priv->av.port->mad_agent,
+			      (unsigned long) cm_id_priv->msg);
+		/* fall through */
+	case IB_CM_REQ_RCVD:
+	case IB_CM_MRA_REQ_SENT:
+		if (rej_msg->reason == IB_CM_REJ_STALE_CONN)
+			cm_enter_timewait(cm_id_priv);
+		else
+			cm_reset_to_idle(cm_id_priv);
+		break;
+	case IB_CM_DREQ_SENT:
+		ib_cancel_mad(cm_id_priv->av.port->mad_agent,
+			      (unsigned long) cm_id_priv->msg);
+		/* fall through */
+	case IB_CM_REP_RCVD:
+	case IB_CM_MRA_REP_SENT:
+	case IB_CM_ESTABLISHED:
+		cm_enter_timewait(cm_id_priv);
+		break;
+	default:
+		spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+		ret = -EINVAL;
+		goto out;
+	}
+
+	ret = atomic_inc_and_test(&cm_id_priv->work_count);
+	if (!ret)
+		list_add_tail(&work->list, &cm_id_priv->work_list);
+	spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+
+	if (ret)
+		cm_process_work(cm_id_priv, work);
+	else
+		cm_deref_id(cm_id_priv);
+	return 0;
+out:
+	cm_deref_id(cm_id_priv);
+	return -EINVAL;
+}
+
+int ib_send_cm_mra(struct ib_cm_id *cm_id,
+		   u8 service_timeout,
+		   const void *private_data,
+		   u8 private_data_len)
+{
+	struct cm_id_private *cm_id_priv;
+	struct ib_mad_send_buf *msg;
+	struct ib_send_wr *bad_send_wr;
+	void *data;
+	unsigned long flags;
+	int ret;
+
+	if (private_data && private_data_len > IB_CM_MRA_PRIVATE_DATA_SIZE)
+		return -EINVAL;
+
+	data = cm_copy_private_data(private_data, private_data_len);
+	if (IS_ERR(data))
+		return PTR_ERR(data);
+
+	cm_id_priv = container_of(cm_id, struct cm_id_private, id);
+
+	spin_lock_irqsave(&cm_id_priv->lock, flags);
+	switch(cm_id_priv->id.state) {
+	case IB_CM_REQ_RCVD:
+		ret = cm_alloc_msg(cm_id_priv, &msg);
+		if (ret)
+			goto error1;
+
+		cm_format_mra((struct cm_mra_msg *) msg->mad, cm_id_priv,
+			      CM_MSG_RESPONSE_REQ, service_timeout,
+			      private_data, private_data_len);
+		ret = ib_post_send_mad(cm_id_priv->av.port->mad_agent,
+				       &msg->send_wr, &bad_send_wr);
+		if (ret)
+			goto error2;
+		cm_id->state = IB_CM_MRA_REQ_SENT;
+		break;
+	case IB_CM_REP_RCVD:
+		ret = cm_alloc_msg(cm_id_priv, &msg);
+		if (ret)
+			goto error1;
+
+		cm_format_mra((struct cm_mra_msg *) msg->mad, cm_id_priv,
+			      CM_MSG_RESPONSE_REP, service_timeout,
+			      private_data, private_data_len);
+		ret = ib_post_send_mad(cm_id_priv->av.port->mad_agent,
+				       &msg->send_wr, &bad_send_wr);
+		if (ret)
+			goto error2;
+		cm_id->state = IB_CM_MRA_REP_SENT;
+		break;
+	case IB_CM_ESTABLISHED:
+		ret = cm_alloc_msg(cm_id_priv, &msg);
+		if (ret)
+			goto error1;
+
+		cm_format_mra((struct cm_mra_msg *) msg->mad, cm_id_priv,
+			      CM_MSG_RESPONSE_OTHER, service_timeout,
+			      private_data, private_data_len);
+		ret = ib_post_send_mad(cm_id_priv->av.port->mad_agent,
+				       &msg->send_wr, &bad_send_wr);
+		if (ret)
+			goto error2;
+		cm_id->lap_state = IB_CM_MRA_LAP_SENT;
+		break;
+	default:
+		ret = -EINVAL;
+		goto error1;
+	}
+	cm_id_priv->service_timeout = service_timeout;
+	cm_set_private_data(cm_id_priv, data, private_data_len);
+	spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+	return 0;
+
+error1:	spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+	kfree(data);
+	return ret;
+
+error2:	spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+	kfree(data);
+	cm_free_msg(msg);
+	return ret;
+}
+EXPORT_SYMBOL(ib_send_cm_mra);
+
+static struct cm_id_private * cm_acquire_mraed_id(struct cm_mra_msg *mra_msg)
+{
+	switch (cm_mra_get_msg_mraed(mra_msg)) {
+	case CM_MSG_RESPONSE_REQ:
+		return cm_acquire_id(mra_msg->remote_comm_id, 0);
+	case CM_MSG_RESPONSE_REP:
+	case CM_MSG_RESPONSE_OTHER:
+		return cm_acquire_id(mra_msg->remote_comm_id,
+				     mra_msg->local_comm_id);
+	default:
+		return NULL;
+	}
+}
+
+static int cm_mra_handler(struct cm_work *work)
+{
+	struct cm_id_private *cm_id_priv;
+	struct cm_mra_msg *mra_msg;
+	unsigned long flags;
+	int timeout, ret;
+
+	mra_msg = (struct cm_mra_msg *)work->mad_recv_wc->recv_buf.mad;
+	cm_id_priv = cm_acquire_mraed_id(mra_msg);
+	if (!cm_id_priv)
+		return -EINVAL;
+
+	work->cm_event.private_data = &mra_msg->private_data;
+	work->cm_event.param.mra_rcvd.service_timeout =
+					cm_mra_get_service_timeout(mra_msg);
+	timeout = cm_convert_to_ms(cm_mra_get_service_timeout(mra_msg)) +
+		  cm_convert_to_ms(cm_id_priv->av.packet_life_time);
+
+	spin_lock_irqsave(&cm_id_priv->lock, flags);
+	switch (cm_id_priv->id.state) {
+	case IB_CM_REQ_SENT:
+		if (cm_mra_get_msg_mraed(mra_msg) != CM_MSG_RESPONSE_REQ ||
+		    ib_modify_mad(cm_id_priv->av.port->mad_agent,
+				  (unsigned long) cm_id_priv->msg, timeout))
+			goto out;
+		cm_id_priv->id.state = IB_CM_MRA_REQ_RCVD;
+		break;
+	case IB_CM_REP_SENT:
+		if (cm_mra_get_msg_mraed(mra_msg) != CM_MSG_RESPONSE_REP ||
+		    ib_modify_mad(cm_id_priv->av.port->mad_agent,
+				  (unsigned long) cm_id_priv->msg, timeout))
+			goto out;
+		cm_id_priv->id.state = IB_CM_MRA_REP_RCVD;
+		break;
+	case IB_CM_ESTABLISHED:
+		if (cm_mra_get_msg_mraed(mra_msg) != CM_MSG_RESPONSE_OTHER ||
+		    cm_id_priv->id.lap_state != IB_CM_LAP_SENT ||
+		    ib_modify_mad(cm_id_priv->av.port->mad_agent,
+				  (unsigned long) cm_id_priv->msg, timeout))
+			goto out;
+		cm_id_priv->id.lap_state = IB_CM_MRA_LAP_RCVD;
+		break;
+	default:
+		goto out;
+	}
+
+	cm_id_priv->msg->context[1] = (void *) (unsigned long)
+				      cm_id_priv->id.state;
+	ret = atomic_inc_and_test(&cm_id_priv->work_count);
+	if (!ret)
+		list_add_tail(&work->list, &cm_id_priv->work_list);
+	spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+
+	if (ret)
+		cm_process_work(cm_id_priv, work);
+	else
+		cm_deref_id(cm_id_priv);
+	return 0;
+out:
+	spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+	cm_deref_id(cm_id_priv);
+	return -EINVAL;
+}
+
+static void cm_format_lap(struct cm_lap_msg *lap_msg,
+			  struct cm_id_private *cm_id_priv,
+			  struct ib_sa_path_rec *alternate_path,
+			  const void *private_data,
+			  u8 private_data_len)
+{
+	cm_format_mad_hdr(&lap_msg->hdr, CM_LAP_ATTR_ID,
+			  cm_form_tid(cm_id_priv, CM_MSG_SEQUENCE_LAP));
+	lap_msg->local_comm_id = cm_id_priv->id.local_id;
+	lap_msg->remote_comm_id = cm_id_priv->id.remote_id;
+	cm_lap_set_remote_qpn(lap_msg, cm_id_priv->remote_qpn);
+	/* todo: need remote CM response timeout */
+	cm_lap_set_remote_resp_timeout(lap_msg, 0x1F);
+	lap_msg->alt_local_lid = alternate_path->slid;
+	lap_msg->alt_remote_lid = alternate_path->dlid;
+	lap_msg->alt_local_gid = alternate_path->sgid;
+	lap_msg->alt_remote_gid = alternate_path->dgid;
+	cm_lap_set_flow_label(lap_msg, alternate_path->flow_label);
+	cm_lap_set_traffic_class(lap_msg, alternate_path->traffic_class);
+	lap_msg->alt_hop_limit = alternate_path->hop_limit;
+	cm_lap_set_packet_rate(lap_msg, alternate_path->rate);
+	cm_lap_set_sl(lap_msg, alternate_path->sl);
+	cm_lap_set_subnet_local(lap_msg, 1); /* local only... */
+	cm_lap_set_local_ack_timeout(lap_msg,
+		min(31, alternate_path->packet_life_time + 1));
+
+	if (private_data && private_data_len)
+		memcpy(lap_msg->private_data, private_data, private_data_len);
+}
+
+int ib_send_cm_lap(struct ib_cm_id *cm_id,
+		   struct ib_sa_path_rec *alternate_path,
+		   const void *private_data,
+		   u8 private_data_len)
+{
+	struct cm_id_private *cm_id_priv;
+	struct ib_mad_send_buf *msg;
+	struct ib_send_wr *bad_send_wr;
+	unsigned long flags;
+	int ret;
+
+	if (private_data && private_data_len > IB_CM_LAP_PRIVATE_DATA_SIZE)
+		return -EINVAL;
+
+	cm_id_priv = container_of(cm_id, struct cm_id_private, id);
+	spin_lock_irqsave(&cm_id_priv->lock, flags);
+	if (cm_id->state != IB_CM_ESTABLISHED ||
+	    cm_id->lap_state != IB_CM_LAP_IDLE) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	ret = cm_alloc_msg(cm_id_priv, &msg);
+	if (ret)
+		goto out;
+
+	cm_format_lap((struct cm_lap_msg *) msg->mad, cm_id_priv,
+		      alternate_path, private_data, private_data_len);
+	msg->send_wr.wr.ud.timeout_ms = cm_id_priv->timeout_ms;
+	msg->context[1] = (void *) (unsigned long) IB_CM_ESTABLISHED;
+
+	ret = ib_post_send_mad(cm_id_priv->av.port->mad_agent,
+			       &msg->send_wr, &bad_send_wr);
+	if (ret) {
+		spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+		cm_free_msg(msg);
+		return ret;
+	}
+
+	cm_id->lap_state = IB_CM_LAP_SENT;
+	cm_id_priv->msg = msg;
+
+out:	spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+	return ret;
+}
+EXPORT_SYMBOL(ib_send_cm_lap);
+
+static void cm_format_path_from_lap(struct ib_sa_path_rec *path,
+				    struct cm_lap_msg *lap_msg)
+{
+	memset(path, 0, sizeof *path);
+	path->dgid = lap_msg->alt_local_gid;
+	path->sgid = lap_msg->alt_remote_gid;
+	path->dlid = lap_msg->alt_local_lid;
+	path->slid = lap_msg->alt_remote_lid;
+	path->flow_label = cm_lap_get_flow_label(lap_msg);
+	path->hop_limit = lap_msg->alt_hop_limit;
+	path->traffic_class = cm_lap_get_traffic_class(lap_msg);
+	path->reversible = 1;
+	/* pkey is same as in REQ */
+	path->sl = cm_lap_get_sl(lap_msg);
+	path->mtu_selector = IB_SA_EQ;
+	/* mtu is same as in REQ */
+	path->rate_selector = IB_SA_EQ;
+	path->rate = cm_lap_get_packet_rate(lap_msg);
+	path->packet_life_time_selector = IB_SA_EQ;
+	path->packet_life_time = cm_lap_get_local_ack_timeout(lap_msg);
+	path->packet_life_time -= (path->packet_life_time > 0);
+}
+
+static int cm_lap_handler(struct cm_work *work)
+{
+	struct cm_id_private *cm_id_priv;
+	struct cm_lap_msg *lap_msg;
+	struct ib_cm_lap_event_param *param;
+	struct ib_mad_send_buf *msg = NULL;
+	struct ib_send_wr *bad_send_wr;
+	unsigned long flags;
+	int ret;
+
+	/* todo: verify LAP request and send reject APR if invalid. */
+	lap_msg = (struct cm_lap_msg *)work->mad_recv_wc->recv_buf.mad;
+	cm_id_priv = cm_acquire_id(lap_msg->remote_comm_id,
+				   lap_msg->local_comm_id);
+	if (!cm_id_priv)
+		return -EINVAL;
+
+	param = &work->cm_event.param.lap_rcvd;
+	param->alternate_path = &work->path[0];
+	cm_format_path_from_lap(param->alternate_path, lap_msg);
+	work->cm_event.private_data = &lap_msg->private_data;
+
+	spin_lock_irqsave(&cm_id_priv->lock, flags);
+	if (cm_id_priv->id.state != IB_CM_ESTABLISHED)
+		goto unlock;
+
+	switch (cm_id_priv->id.lap_state) {
+	case IB_CM_LAP_IDLE:
+		break;
+	case IB_CM_MRA_LAP_SENT:
+		if (cm_alloc_response_msg(work->port, work->mad_recv_wc, &msg))
+			goto unlock;
+
+		cm_format_mra((struct cm_mra_msg *) msg->mad, cm_id_priv,
+			      CM_MSG_RESPONSE_OTHER,
+			      cm_id_priv->service_timeout,
+			      cm_id_priv->private_data,
+			      cm_id_priv->private_data_len);
+		spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+
+		if (ib_post_send_mad(cm_id_priv->av.port->mad_agent,
+				     &msg->send_wr, &bad_send_wr))
+			cm_free_msg(msg);
+		goto deref;
+	default:
+		goto unlock;
+	}
+
+	cm_id_priv->id.lap_state = IB_CM_LAP_RCVD;
+	cm_id_priv->tid = lap_msg->hdr.tid;
+	ret = atomic_inc_and_test(&cm_id_priv->work_count);
+	if (!ret)
+		list_add_tail(&work->list, &cm_id_priv->work_list);
+	spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+
+	if (ret)
+		cm_process_work(cm_id_priv, work);
+	else
+		cm_deref_id(cm_id_priv);
+	return 0;
+
+unlock:	spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+deref:	cm_deref_id(cm_id_priv);
+	return -EINVAL;
+}
+
+static void cm_format_apr(struct cm_apr_msg *apr_msg,
+			  struct cm_id_private *cm_id_priv,
+			  enum ib_cm_apr_status status,
+			  void *info,
+			  u8 info_length,
+			  const void *private_data,
+			  u8 private_data_len)
+{
+	cm_format_mad_hdr(&apr_msg->hdr, CM_APR_ATTR_ID, cm_id_priv->tid);
+	apr_msg->local_comm_id = cm_id_priv->id.local_id;
+	apr_msg->remote_comm_id = cm_id_priv->id.remote_id;
+	apr_msg->ap_status = (u8) status;
+
+	if (info && info_length) {
+		apr_msg->info_length = info_length;
+		memcpy(apr_msg->info, info, info_length);
+	}
+
+	if (private_data && private_data_len)
+		memcpy(apr_msg->private_data, private_data, private_data_len);
+}
+
+int ib_send_cm_apr(struct ib_cm_id *cm_id,
+		   enum ib_cm_apr_status status,
+		   void *info,
+		   u8 info_length,
+		   const void *private_data,
+		   u8 private_data_len)
+{
+	struct cm_id_private *cm_id_priv;
+	struct ib_mad_send_buf *msg;
+	struct ib_send_wr *bad_send_wr;
+	unsigned long flags;
+	int ret;
+
+	if ((private_data && private_data_len > IB_CM_APR_PRIVATE_DATA_SIZE) ||
+	    (info && info_length > IB_CM_APR_INFO_LENGTH))
+		return -EINVAL;
+
+	cm_id_priv = container_of(cm_id, struct cm_id_private, id);
+	spin_lock_irqsave(&cm_id_priv->lock, flags);
+	if (cm_id->state != IB_CM_ESTABLISHED ||
+	    (cm_id->lap_state != IB_CM_LAP_RCVD &&
+	     cm_id->lap_state != IB_CM_MRA_LAP_SENT)) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	ret = cm_alloc_msg(cm_id_priv, &msg);
+	if (ret)
+		goto out;
+
+	cm_format_apr((struct cm_apr_msg *) msg->mad, cm_id_priv, status,
+		      info, info_length, private_data, private_data_len);
+	ret = ib_post_send_mad(cm_id_priv->av.port->mad_agent,
+			       &msg->send_wr, &bad_send_wr);
+	if (ret) {
+		spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+		cm_free_msg(msg);
+		return ret;
+	}
+
+	cm_id->lap_state = IB_CM_LAP_IDLE;
+out:	spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+	return ret;
+}
+EXPORT_SYMBOL(ib_send_cm_apr);
+
+static int cm_apr_handler(struct cm_work *work)
+{
+	struct cm_id_private *cm_id_priv;
+	struct cm_apr_msg *apr_msg;
+	unsigned long flags;
+	int ret;
+
+	apr_msg = (struct cm_apr_msg *)work->mad_recv_wc->recv_buf.mad;
+	cm_id_priv = cm_acquire_id(apr_msg->remote_comm_id,
+				   apr_msg->local_comm_id);
+	if (!cm_id_priv)
+		return -EINVAL; /* Unmatched reply. */
+
+	work->cm_event.param.apr_rcvd.ap_status = apr_msg->ap_status;
+	work->cm_event.param.apr_rcvd.apr_info = &apr_msg->info;
+	work->cm_event.param.apr_rcvd.info_len = apr_msg->info_length;
+	work->cm_event.private_data = &apr_msg->private_data;
+
+	spin_lock_irqsave(&cm_id_priv->lock, flags);
+	if (cm_id_priv->id.state != IB_CM_ESTABLISHED ||
+	    (cm_id_priv->id.lap_state != IB_CM_LAP_SENT &&
+	     cm_id_priv->id.lap_state != IB_CM_MRA_LAP_RCVD)) {
+		spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+		goto out;
+	}
+	cm_id_priv->id.lap_state = IB_CM_LAP_IDLE;
+	ib_cancel_mad(cm_id_priv->av.port->mad_agent,
+		      (unsigned long) cm_id_priv->msg);
+	cm_id_priv->msg = NULL;
+
+	ret = atomic_inc_and_test(&cm_id_priv->work_count);
+	if (!ret)
+		list_add_tail(&work->list, &cm_id_priv->work_list);
+	spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+
+	if (ret)
+		cm_process_work(cm_id_priv, work);
+	else
+		cm_deref_id(cm_id_priv);
+	return 0;
+out:
+	cm_deref_id(cm_id_priv);
+	return -EINVAL;
+}
+
+static int cm_timewait_handler(struct cm_work *work)
+{
+	struct cm_timewait_info *timewait_info;
+	struct cm_id_private *cm_id_priv;
+	unsigned long flags;
+	int ret;
+
+	timewait_info = (struct cm_timewait_info *)work;
+	cm_cleanup_timewait(timewait_info);
+
+	cm_id_priv = cm_acquire_id(timewait_info->work.local_id,
+				   timewait_info->work.remote_id);
+	if (!cm_id_priv)
+		return -EINVAL;
+
+	spin_lock_irqsave(&cm_id_priv->lock, flags);
+	if (cm_id_priv->id.state != IB_CM_TIMEWAIT ||
+	    cm_id_priv->remote_qpn != timewait_info->remote_qpn) {
+		spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+		goto out;
+	}
+	cm_id_priv->id.state = IB_CM_IDLE;
+	ret = atomic_inc_and_test(&cm_id_priv->work_count);
+	if (!ret)
+		list_add_tail(&work->list, &cm_id_priv->work_list);
+	spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+
+	if (ret)
+		cm_process_work(cm_id_priv, work);
+	else
+		cm_deref_id(cm_id_priv);
+	return 0;
+out:
+	cm_deref_id(cm_id_priv);
+	return -EINVAL;
+}
+
+static void cm_format_sidr_req(struct cm_sidr_req_msg *sidr_req_msg,
+			       struct cm_id_private *cm_id_priv,
+			       struct ib_cm_sidr_req_param *param)
+{
+	cm_format_mad_hdr(&sidr_req_msg->hdr, CM_SIDR_REQ_ATTR_ID,
+			  cm_form_tid(cm_id_priv, CM_MSG_SEQUENCE_SIDR));
+	sidr_req_msg->request_id = cm_id_priv->id.local_id;
+	sidr_req_msg->pkey = param->pkey;
+	sidr_req_msg->service_id = param->service_id;
+
+	if (param->private_data && param->private_data_len)
+		memcpy(sidr_req_msg->private_data, param->private_data,
+		       param->private_data_len);
+}
+
+int ib_send_cm_sidr_req(struct ib_cm_id *cm_id,
+			struct ib_cm_sidr_req_param *param)
+{
+	struct cm_id_private *cm_id_priv;
+	struct ib_mad_send_buf *msg;
+	struct ib_send_wr *bad_send_wr;
+	unsigned long flags;
+	int ret;
+
+	if (!param->path || (param->private_data &&
+	     param->private_data_len > IB_CM_SIDR_REQ_PRIVATE_DATA_SIZE))
+		return -EINVAL;
+
+	cm_id_priv = container_of(cm_id, struct cm_id_private, id);
+	ret = cm_init_av_by_path(param->path, &cm_id_priv->av);
+	if (ret)
+		goto out;
+
+	cm_id->service_id = param->service_id;
+	cm_id->service_mask = ~0ULL;
+	cm_id_priv->timeout_ms = param->timeout_ms;
+	cm_id_priv->max_cm_retries = param->max_cm_retries;
+	ret = cm_alloc_msg(cm_id_priv, &msg);
+	if (ret)
+		goto out;
+
+	cm_format_sidr_req((struct cm_sidr_req_msg *) msg->mad, cm_id_priv,
+			   param);
+	msg->send_wr.wr.ud.timeout_ms = cm_id_priv->timeout_ms;
+	msg->context[1] = (void *) (unsigned long) IB_CM_SIDR_REQ_SENT;
+
+	spin_lock_irqsave(&cm_id_priv->lock, flags);
+	if (cm_id->state == IB_CM_IDLE)
+		ret = ib_post_send_mad(cm_id_priv->av.port->mad_agent,
+				       &msg->send_wr, &bad_send_wr);
+	else
+		ret = -EINVAL;
+
+	if (ret) {
+		spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+		cm_free_msg(msg);
+		goto out;
+	}
+	cm_id->state = IB_CM_SIDR_REQ_SENT;
+	cm_id_priv->msg = msg;
+	spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+out:
+	return ret;
+}
+EXPORT_SYMBOL(ib_send_cm_sidr_req);
+
+static void cm_format_sidr_req_event(struct cm_work *work,
+				     struct ib_cm_id *listen_id)
+{
+	struct cm_sidr_req_msg *sidr_req_msg;
+	struct ib_cm_sidr_req_event_param *param;
+
+	sidr_req_msg = (struct cm_sidr_req_msg *)
+				work->mad_recv_wc->recv_buf.mad;
+	param = &work->cm_event.param.sidr_req_rcvd;
+	param->pkey = sidr_req_msg->pkey;
+	param->listen_id = listen_id;
+	param->device = work->port->mad_agent->device;
+	param->port = work->port->port_num;
+	work->cm_event.private_data = &sidr_req_msg->private_data;
+}
+
+static int cm_sidr_req_handler(struct cm_work *work)
+{
+	struct ib_cm_id *cm_id;
+	struct cm_id_private *cm_id_priv, *cur_cm_id_priv;
+	struct cm_sidr_req_msg *sidr_req_msg;
+	struct ib_wc *wc;
+	unsigned long flags;
+
+	cm_id = ib_create_cm_id(NULL, NULL);
+	if (IS_ERR(cm_id))
+		return PTR_ERR(cm_id);
+	cm_id_priv = container_of(cm_id, struct cm_id_private, id);
+
+	/* Record SGID/SLID and request ID for lookup. */
+	sidr_req_msg = (struct cm_sidr_req_msg *)
+				work->mad_recv_wc->recv_buf.mad;
+	wc = work->mad_recv_wc->wc;
+	cm_id_priv->av.dgid.global.subnet_prefix = wc->slid;
+	cm_id_priv->av.dgid.global.interface_id = 0;
+	cm_init_av_for_response(work->port, work->mad_recv_wc->wc,
+				&cm_id_priv->av);
+	cm_id_priv->id.remote_id = sidr_req_msg->request_id;
+	cm_id_priv->id.state = IB_CM_SIDR_REQ_RCVD;
+	cm_id_priv->tid = sidr_req_msg->hdr.tid;
+	atomic_inc(&cm_id_priv->work_count);
+
+	spin_lock_irqsave(&cm.lock, flags);
+	cur_cm_id_priv = cm_insert_remote_sidr(cm_id_priv);
+	if (cur_cm_id_priv) {
+		spin_unlock_irqrestore(&cm.lock, flags);
+		goto out; /* Duplicate message. */
+	}
+	cur_cm_id_priv = cm_find_listen(sidr_req_msg->service_id);
+	if (!cur_cm_id_priv) {
+		rb_erase(&cm_id_priv->sidr_id_node, &cm.remote_sidr_table);
+		spin_unlock_irqrestore(&cm.lock, flags);
+		/* todo: reply with no match */
+		goto out; /* No match. */
+	}
+	atomic_inc(&cur_cm_id_priv->refcount);
+	spin_unlock_irqrestore(&cm.lock, flags);
+
+	cm_id_priv->id.cm_handler = cur_cm_id_priv->id.cm_handler;
+	cm_id_priv->id.context = cur_cm_id_priv->id.context;
+	cm_id_priv->id.service_id = sidr_req_msg->service_id;
+	cm_id_priv->id.service_mask = ~0ULL;
+
+	cm_format_sidr_req_event(work, &cur_cm_id_priv->id);
+	cm_process_work(cm_id_priv, work);
+	cm_deref_id(cur_cm_id_priv);
+	return 0;
+out:
+	ib_destroy_cm_id(&cm_id_priv->id);
+	return -EINVAL;
+}
+
+static void cm_format_sidr_rep(struct cm_sidr_rep_msg *sidr_rep_msg,
+			       struct cm_id_private *cm_id_priv,
+			       struct ib_cm_sidr_rep_param *param)
+{
+	cm_format_mad_hdr(&sidr_rep_msg->hdr, CM_SIDR_REP_ATTR_ID,
+			  cm_id_priv->tid);
+	sidr_rep_msg->request_id = cm_id_priv->id.remote_id;
+	sidr_rep_msg->status = param->status;
+	cm_sidr_rep_set_qpn(sidr_rep_msg, cpu_to_be32(param->qp_num));
+	sidr_rep_msg->service_id = cm_id_priv->id.service_id;
+	sidr_rep_msg->qkey = cpu_to_be32(param->qkey);
+
+	if (param->info && param->info_length)
+		memcpy(sidr_rep_msg->info, param->info, param->info_length);
+
+	if (param->private_data && param->private_data_len)
+		memcpy(sidr_rep_msg->private_data, param->private_data,
+		       param->private_data_len);
+}
+
+int ib_send_cm_sidr_rep(struct ib_cm_id *cm_id,
+			struct ib_cm_sidr_rep_param *param)
+{
+	struct cm_id_private *cm_id_priv;
+	struct ib_mad_send_buf *msg;
+	struct ib_send_wr *bad_send_wr;
+	unsigned long flags;
+	int ret;
+
+	if ((param->info && param->info_length > IB_CM_SIDR_REP_INFO_LENGTH) ||
+	    (param->private_data &&
+	     param->private_data_len > IB_CM_SIDR_REP_PRIVATE_DATA_SIZE))
+		return -EINVAL;
+
+	cm_id_priv = container_of(cm_id, struct cm_id_private, id);
+	spin_lock_irqsave(&cm_id_priv->lock, flags);
+	if (cm_id->state != IB_CM_SIDR_REQ_RCVD) {
+		ret = -EINVAL;
+		goto error;
+	}
+
+	ret = cm_alloc_msg(cm_id_priv, &msg);
+	if (ret)
+		goto error;
+
+	cm_format_sidr_rep((struct cm_sidr_rep_msg *) msg->mad, cm_id_priv,
+			   param);
+	ret = ib_post_send_mad(cm_id_priv->av.port->mad_agent,
+			       &msg->send_wr, &bad_send_wr);
+	if (ret) {
+		spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+		cm_free_msg(msg);
+		return ret;
+	}
+	cm_id->state = IB_CM_IDLE;
+	spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+
+	spin_lock_irqsave(&cm.lock, flags);
+	rb_erase(&cm_id_priv->sidr_id_node, &cm.remote_sidr_table);
+	spin_unlock_irqrestore(&cm.lock, flags);
+	return 0;
+
+error:	spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+	return ret;
+}
+EXPORT_SYMBOL(ib_send_cm_sidr_rep);
+
+static void cm_format_sidr_rep_event(struct cm_work *work)
+{
+	struct cm_sidr_rep_msg *sidr_rep_msg;
+	struct ib_cm_sidr_rep_event_param *param;
+
+	sidr_rep_msg = (struct cm_sidr_rep_msg *)
+				work->mad_recv_wc->recv_buf.mad;
+	param = &work->cm_event.param.sidr_rep_rcvd;
+	param->status = sidr_rep_msg->status;
+	param->qkey = be32_to_cpu(sidr_rep_msg->qkey);
+	param->qpn = be32_to_cpu(cm_sidr_rep_get_qpn(sidr_rep_msg));
+	param->info = &sidr_rep_msg->info;
+	param->info_len = sidr_rep_msg->info_length;
+	work->cm_event.private_data = &sidr_rep_msg->private_data;
+}
+
+static int cm_sidr_rep_handler(struct cm_work *work)
+{
+	struct cm_sidr_rep_msg *sidr_rep_msg;
+	struct cm_id_private *cm_id_priv;
+	unsigned long flags;
+
+	sidr_rep_msg = (struct cm_sidr_rep_msg *)
+				work->mad_recv_wc->recv_buf.mad;
+	cm_id_priv = cm_acquire_id(sidr_rep_msg->request_id, 0);
+	if (!cm_id_priv)
+		return -EINVAL; /* Unmatched reply. */
+
+	spin_lock_irqsave(&cm_id_priv->lock, flags);
+	if (cm_id_priv->id.state != IB_CM_SIDR_REQ_SENT) {
+		spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+		goto out;
+	}
+	cm_id_priv->id.state = IB_CM_IDLE;
+	ib_cancel_mad(cm_id_priv->av.port->mad_agent,
+		      (unsigned long) cm_id_priv->msg);
+	spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+
+	cm_format_sidr_rep_event(work);
+	cm_process_work(cm_id_priv, work);
+	return 0;
+out:
+	cm_deref_id(cm_id_priv);
+	return -EINVAL;
+}
+
+static void cm_process_send_error(struct ib_mad_send_buf *msg,
+				  enum ib_wc_status wc_status)
+{
+	struct cm_id_private *cm_id_priv;
+	struct ib_cm_event cm_event;
+	enum ib_cm_state state;
+	unsigned long flags;
+	int ret;
+
+	memset(&cm_event, 0, sizeof cm_event);
+	cm_id_priv = msg->context[0];
+
+	/* Discard old sends or ones without a response. */
+	spin_lock_irqsave(&cm_id_priv->lock, flags);
+	state = (enum ib_cm_state) (unsigned long) msg->context[1];
+	if (msg != cm_id_priv->msg || state != cm_id_priv->id.state)
+		goto discard;
+
+	switch (state) {
+	case IB_CM_REQ_SENT:
+	case IB_CM_MRA_REQ_RCVD:
+		cm_reset_to_idle(cm_id_priv);
+		cm_event.event = IB_CM_REQ_ERROR;
+		break;
+	case IB_CM_REP_SENT:
+	case IB_CM_MRA_REP_RCVD:
+		cm_reset_to_idle(cm_id_priv);
+		cm_event.event = IB_CM_REP_ERROR;
+		break;
+	case IB_CM_DREQ_SENT:
+		cm_enter_timewait(cm_id_priv);
+		cm_event.event = IB_CM_DREQ_ERROR;
+		break;
+	case IB_CM_SIDR_REQ_SENT:
+		cm_id_priv->id.state = IB_CM_IDLE;
+		cm_event.event = IB_CM_SIDR_REQ_ERROR;
+		break;
+	default:
+		goto discard;
+	}
+	spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+	cm_event.param.send_status = wc_status;
+
+	/* No other events can occur on the cm_id at this point. */
+	ret = cm_id_priv->id.cm_handler(&cm_id_priv->id, &cm_event);
+	cm_free_msg(msg);
+	if (ret)
+		ib_destroy_cm_id(&cm_id_priv->id);
+	return;
+discard:
+	spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+	cm_free_msg(msg);
+}
+
+static void cm_send_handler(struct ib_mad_agent *mad_agent,
+			    struct ib_mad_send_wc *mad_send_wc)
+{
+	struct ib_mad_send_buf *msg;
+
+	msg = (struct ib_mad_send_buf *)(unsigned long)mad_send_wc->wr_id;
+
+	switch (mad_send_wc->status) {
+	case IB_WC_SUCCESS:
+	case IB_WC_WR_FLUSH_ERR:
+		cm_free_msg(msg);
+		break;
+	default:
+		if (msg->context[0] && msg->context[1])
+			cm_process_send_error(msg, mad_send_wc->status);
+		else
+			cm_free_msg(msg);
+		break;
+	}
+}
+
+static void cm_work_handler(void *data)
+{
+	struct cm_work *work = data;
+	int ret;
+
+	switch (work->cm_event.event) {
+	case IB_CM_REQ_RECEIVED:
+		ret = cm_req_handler(work);
+		break;
+	case IB_CM_MRA_RECEIVED:
+		ret = cm_mra_handler(work);
+		break;
+	case IB_CM_REJ_RECEIVED:
+		ret = cm_rej_handler(work);
+		break;
+	case IB_CM_REP_RECEIVED:
+		ret = cm_rep_handler(work);
+		break;
+	case IB_CM_RTU_RECEIVED:
+		ret = cm_rtu_handler(work);
+		break;
+	case IB_CM_USER_ESTABLISHED:
+		ret = cm_establish_handler(work);
+		break;
+	case IB_CM_DREQ_RECEIVED:
+		ret = cm_dreq_handler(work);
+		break;
+	case IB_CM_DREP_RECEIVED:
+		ret = cm_drep_handler(work);
+		break;
+	case IB_CM_SIDR_REQ_RECEIVED:
+		ret = cm_sidr_req_handler(work);
+		break;
+	case IB_CM_SIDR_REP_RECEIVED:
+		ret = cm_sidr_rep_handler(work);
+		break;
+	case IB_CM_LAP_RECEIVED:
+		ret = cm_lap_handler(work);
+		break;
+	case IB_CM_APR_RECEIVED:
+		ret = cm_apr_handler(work);
+		break;
+	case IB_CM_TIMEWAIT_EXIT:
+		ret = cm_timewait_handler(work);
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+	if (ret)
+		cm_free_work(work);
+}
+
+int ib_cm_establish(struct ib_cm_id *cm_id)
+{
+	struct cm_id_private *cm_id_priv;
+	struct cm_work *work;
+	unsigned long flags;
+	int ret = 0;
+
+	work = kmalloc(sizeof *work, GFP_ATOMIC);
+	if (!work)
+		return -ENOMEM;
+
+	cm_id_priv = container_of(cm_id, struct cm_id_private, id);
+	spin_lock_irqsave(&cm_id_priv->lock, flags);
+	switch (cm_id->state)
+	{
+	case IB_CM_REP_SENT:
+	case IB_CM_MRA_REP_RCVD:
+		cm_id->state = IB_CM_ESTABLISHED;
+		break;
+	case IB_CM_ESTABLISHED:
+		ret = -EISCONN;
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+	spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+
+	if (ret) {
+		kfree(work);
+		goto out;
+	}
+
+	/*
+	 * The CM worker thread may try to destroy the cm_id before it
+	 * can execute this work item.  To prevent potential deadlock,
+	 * we need to find the cm_id once we're in the context of the
+	 * worker thread, rather than holding a reference on it.
+	 */
+	INIT_WORK(&work->work, cm_work_handler, work);
+	work->local_id = cm_id->local_id;
+	work->remote_id = cm_id->remote_id;
+	work->mad_recv_wc = NULL;
+	work->cm_event.event = IB_CM_USER_ESTABLISHED;
+	queue_work(cm.wq, &work->work);
+out:
+	return ret;
+}
+EXPORT_SYMBOL(ib_cm_establish);
+
+static void cm_recv_handler(struct ib_mad_agent *mad_agent,
+			    struct ib_mad_recv_wc *mad_recv_wc)
+{
+	struct cm_work *work;
+	enum ib_cm_event_type event;
+	int paths = 0;
+
+	switch (mad_recv_wc->recv_buf.mad->mad_hdr.attr_id) {
+	case CM_REQ_ATTR_ID:
+		paths = 1 + (((struct cm_req_msg *) mad_recv_wc->recv_buf.mad)->
+						    alt_local_lid != 0);
+		event = IB_CM_REQ_RECEIVED;
+		break;
+	case CM_MRA_ATTR_ID:
+		event = IB_CM_MRA_RECEIVED;
+		break;
+	case CM_REJ_ATTR_ID:
+		event = IB_CM_REJ_RECEIVED;
+		break;
+	case CM_REP_ATTR_ID:
+		event = IB_CM_REP_RECEIVED;
+		break;
+	case CM_RTU_ATTR_ID:
+		event = IB_CM_RTU_RECEIVED;
+		break;
+	case CM_DREQ_ATTR_ID:
+		event = IB_CM_DREQ_RECEIVED;
+		break;
+	case CM_DREP_ATTR_ID:
+		event = IB_CM_DREP_RECEIVED;
+		break;
+	case CM_SIDR_REQ_ATTR_ID:
+		event = IB_CM_SIDR_REQ_RECEIVED;
+		break;
+	case CM_SIDR_REP_ATTR_ID:
+		event = IB_CM_SIDR_REP_RECEIVED;
+		break;
+	case CM_LAP_ATTR_ID:
+		paths = 1;
+		event = IB_CM_LAP_RECEIVED;
+		break;
+	case CM_APR_ATTR_ID:
+		event = IB_CM_APR_RECEIVED;
+		break;
+	default:
+		ib_free_recv_mad(mad_recv_wc);
+		return;
+	}
+
+	work = kmalloc(sizeof *work + sizeof(struct ib_sa_path_rec) * paths,
+		       GFP_KERNEL);
+	if (!work) {
+		ib_free_recv_mad(mad_recv_wc);
+		return;
+	}
+
+	INIT_WORK(&work->work, cm_work_handler, work);
+	work->cm_event.event = event;
+	work->mad_recv_wc = mad_recv_wc;
+	work->port = (struct cm_port *)mad_agent->context;
+	queue_work(cm.wq, &work->work);
+}
+
+static int cm_init_qp_init_attr(struct cm_id_private *cm_id_priv,
+				struct ib_qp_attr *qp_attr,
+				int *qp_attr_mask)
+{
+	unsigned long flags;
+	int ret;
+
+	spin_lock_irqsave(&cm_id_priv->lock, flags);
+	switch (cm_id_priv->id.state) {
+	case IB_CM_REQ_SENT:
+	case IB_CM_MRA_REQ_RCVD:
+	case IB_CM_REQ_RCVD:
+	case IB_CM_MRA_REQ_SENT:
+	case IB_CM_REP_RCVD:
+	case IB_CM_MRA_REP_SENT:
+	case IB_CM_REP_SENT:
+	case IB_CM_MRA_REP_RCVD:
+	case IB_CM_ESTABLISHED:
+		*qp_attr_mask = IB_QP_STATE | IB_QP_ACCESS_FLAGS |
+				IB_QP_PKEY_INDEX | IB_QP_PORT;
+		qp_attr->qp_access_flags = IB_ACCESS_LOCAL_WRITE;
+		if (cm_id_priv->responder_resources)
+			qp_attr->qp_access_flags |= IB_ACCESS_REMOTE_WRITE |
+						    IB_ACCESS_REMOTE_READ;
+		qp_attr->pkey_index = cm_id_priv->av.pkey_index;
+		qp_attr->port_num = cm_id_priv->av.port->port_num;
+		ret = 0;
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+	spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+	return ret;
+}
+
+static int cm_init_qp_rtr_attr(struct cm_id_private *cm_id_priv,
+			       struct ib_qp_attr *qp_attr,
+			       int *qp_attr_mask)
+{
+	unsigned long flags;
+	int ret;
+
+	spin_lock_irqsave(&cm_id_priv->lock, flags);
+	switch (cm_id_priv->id.state) {
+	case IB_CM_REQ_RCVD:
+	case IB_CM_MRA_REQ_SENT:
+	case IB_CM_REP_RCVD:
+	case IB_CM_MRA_REP_SENT:
+	case IB_CM_REP_SENT:
+	case IB_CM_MRA_REP_RCVD:
+	case IB_CM_ESTABLISHED:
+		*qp_attr_mask = IB_QP_STATE | IB_QP_AV | IB_QP_PATH_MTU |
+				IB_QP_DEST_QPN | IB_QP_RQ_PSN |
+				IB_QP_MAX_DEST_RD_ATOMIC | IB_QP_MIN_RNR_TIMER;
+		qp_attr->ah_attr = cm_id_priv->av.ah_attr;
+		qp_attr->path_mtu = cm_id_priv->path_mtu;
+		qp_attr->dest_qp_num = be32_to_cpu(cm_id_priv->remote_qpn);
+		qp_attr->rq_psn = be32_to_cpu(cm_id_priv->rq_psn);
+		qp_attr->max_dest_rd_atomic = cm_id_priv->responder_resources;
+		qp_attr->min_rnr_timer = 0;
+		if (cm_id_priv->alt_av.ah_attr.dlid) {
+			*qp_attr_mask |= IB_QP_ALT_PATH;
+			qp_attr->alt_ah_attr = cm_id_priv->alt_av.ah_attr;
+		}
+		ret = 0;
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+	spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+	return ret;
+}
+
+static int cm_init_qp_rts_attr(struct cm_id_private *cm_id_priv,
+			       struct ib_qp_attr *qp_attr,
+			       int *qp_attr_mask)
+{
+	unsigned long flags;
+	int ret;
+
+	spin_lock_irqsave(&cm_id_priv->lock, flags);
+	switch (cm_id_priv->id.state) {
+	case IB_CM_REP_RCVD:
+	case IB_CM_MRA_REP_SENT:
+	case IB_CM_REP_SENT:
+	case IB_CM_MRA_REP_RCVD:
+	case IB_CM_ESTABLISHED:
+		*qp_attr_mask = IB_QP_STATE | IB_QP_TIMEOUT | IB_QP_RETRY_CNT |
+				IB_QP_RNR_RETRY | IB_QP_SQ_PSN |
+				IB_QP_MAX_QP_RD_ATOMIC;
+		qp_attr->timeout = cm_id_priv->local_ack_timeout;
+		qp_attr->retry_cnt = cm_id_priv->retry_count;
+		qp_attr->rnr_retry = cm_id_priv->rnr_retry_count;
+		qp_attr->sq_psn = be32_to_cpu(cm_id_priv->sq_psn);
+		qp_attr->max_rd_atomic = cm_id_priv->initiator_depth;
+		if (cm_id_priv->alt_av.ah_attr.dlid) {
+			*qp_attr_mask |= IB_QP_PATH_MIG_STATE;
+			qp_attr->path_mig_state = IB_MIG_REARM;
+		}
+		ret = 0;
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+	spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+	return ret;
+}
+
+int ib_cm_init_qp_attr(struct ib_cm_id *cm_id,
+		       struct ib_qp_attr *qp_attr,
+		       int *qp_attr_mask)
+{
+	struct cm_id_private *cm_id_priv;
+	int ret;
+
+	cm_id_priv = container_of(cm_id, struct cm_id_private, id);
+	switch (qp_attr->qp_state) {
+	case IB_QPS_INIT:
+		ret = cm_init_qp_init_attr(cm_id_priv, qp_attr, qp_attr_mask);
+		break;
+	case IB_QPS_RTR:
+		ret = cm_init_qp_rtr_attr(cm_id_priv, qp_attr, qp_attr_mask);
+		break;
+	case IB_QPS_RTS:
+		ret = cm_init_qp_rts_attr(cm_id_priv, qp_attr, qp_attr_mask);
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+	return ret;
+}
+EXPORT_SYMBOL(ib_cm_init_qp_attr);
+
+static u64 cm_get_ca_guid(struct ib_device *device)
+{
+	struct ib_device_attr *device_attr;
+	u64 guid;
+	int ret;
+
+	device_attr = kmalloc(sizeof *device_attr, GFP_KERNEL);
+	if (!device_attr)
+		return 0;
+
+	ret = ib_query_device(device, device_attr);
+	guid = ret ? 0 : device_attr->node_guid;
+	kfree(device_attr);
+	return guid;
+}
+
+static void cm_add_one(struct ib_device *device)
+{
+	struct cm_device *cm_dev;
+	struct cm_port *port;
+	struct ib_mad_reg_req reg_req = {
+		.mgmt_class = IB_MGMT_CLASS_CM,
+		.mgmt_class_version = IB_CM_CLASS_VERSION
+	};
+	struct ib_port_modify port_modify = {
+		.set_port_cap_mask = IB_PORT_CM_SUP
+	};
+	unsigned long flags;
+	int ret;
+	u8 i;
+
+	cm_dev = kmalloc(sizeof(*cm_dev) + sizeof(*port) *
+			 device->phys_port_cnt, GFP_KERNEL);
+	if (!cm_dev)
+		return;
+
+	cm_dev->device = device;
+	cm_dev->ca_guid = cm_get_ca_guid(device);
+	if (!cm_dev->ca_guid)
+		goto error1;
+
+	set_bit(IB_MGMT_METHOD_SEND, reg_req.method_mask);
+	for (i = 1; i <= device->phys_port_cnt; i++) {
+		port = &cm_dev->port[i-1];
+		port->cm_dev = cm_dev;
+		port->port_num = i;
+		port->mad_agent = ib_register_mad_agent(device, i,
+							IB_QPT_GSI,
+							&reg_req,
+							0,
+							cm_send_handler,
+							cm_recv_handler,
+							port);
+		if (IS_ERR(port->mad_agent))
+			goto error2;
+
+		ret = ib_modify_port(device, i, 0, &port_modify);
+		if (ret)
+			goto error3;
+	}
+	ib_set_client_data(device, &cm_client, cm_dev);
+
+	write_lock_irqsave(&cm.device_lock, flags);
+	list_add_tail(&cm_dev->list, &cm.device_list);
+	write_unlock_irqrestore(&cm.device_lock, flags);
+	return;
+
+error3:
+	ib_unregister_mad_agent(port->mad_agent);
+error2:
+	port_modify.set_port_cap_mask = 0;
+	port_modify.clr_port_cap_mask = IB_PORT_CM_SUP;
+	while (--i) {
+		port = &cm_dev->port[i-1];
+		ib_modify_port(device, port->port_num, 0, &port_modify);
+		ib_unregister_mad_agent(port->mad_agent);
+	}
+error1:
+	kfree(cm_dev);
+}
+
+static void cm_remove_one(struct ib_device *device)
+{
+	struct cm_device *cm_dev;
+	struct cm_port *port;
+	struct ib_port_modify port_modify = {
+		.clr_port_cap_mask = IB_PORT_CM_SUP
+	};
+	unsigned long flags;
+	int i;
+
+	cm_dev = ib_get_client_data(device, &cm_client);
+	if (!cm_dev)
+		return;
+
+	write_lock_irqsave(&cm.device_lock, flags);
+	list_del(&cm_dev->list);
+	write_unlock_irqrestore(&cm.device_lock, flags);
+
+	for (i = 1; i <= device->phys_port_cnt; i++) {
+		port = &cm_dev->port[i-1];
+		ib_modify_port(device, port->port_num, 0, &port_modify);
+		ib_unregister_mad_agent(port->mad_agent);
+	}
+	kfree(cm_dev);
+}
+
+static int __init ib_cm_init(void)
+{
+	int ret;
+
+	memset(&cm, 0, sizeof cm);
+	INIT_LIST_HEAD(&cm.device_list);
+	rwlock_init(&cm.device_lock);
+	spin_lock_init(&cm.lock);
+	cm.listen_service_table = RB_ROOT;
+	cm.listen_service_id = __constant_be64_to_cpu(IB_CM_ASSIGN_SERVICE_ID);
+	cm.remote_id_table = RB_ROOT;
+	cm.remote_qp_table = RB_ROOT;
+	cm.remote_sidr_table = RB_ROOT;
+	idr_init(&cm.local_id_table);
+	idr_pre_get(&cm.local_id_table, GFP_KERNEL);
+
+	cm.wq = create_workqueue("ib_cm");
+	if (!cm.wq)
+		return -ENOMEM;
+
+	ret = ib_register_client(&cm_client);
+	if (ret)
+		goto error;
+
+	return 0;
+error:
+	destroy_workqueue(cm.wq);
+	return ret;
+}
+
+static void __exit ib_cm_cleanup(void)
+{
+	flush_workqueue(cm.wq);
+	destroy_workqueue(cm.wq);
+	ib_unregister_client(&cm_client);
+}
+
+module_init(ib_cm_init);
+module_exit(ib_cm_cleanup);
+
diff --git a/drivers/infiniband/core/cm_msgs.h b/drivers/infiniband/core/cm_msgs.h
new file mode 100644
--- /dev/null
+++ b/drivers/infiniband/core/cm_msgs.h
@@ -0,0 +1,819 @@
+/*
+ * Copyright (c) 2004 Intel Corporation.  All rights reserved.
+ * Copyright (c) 2004 Topspin Corporation.  All rights reserved.
+ * Copyright (c) 2004 Voltaire Corporation.  All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING the madirectory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use source and binary forms, with or
+ *     withmodification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retathe above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHWARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS THE
+ * SOFTWARE.
+ */
+#if !defined(CM_MSGS_H)
+#define CM_MSGS_H
+
+#include <ib_mad.h>
+
+/*
+ * Parameters to routines below should be in network-byte order, and values
+ * are returned in network-byte order.
+ */
+
+#define IB_CM_CLASS_VERSION	2 /* IB specification 1.2 */
+
+enum cm_msg_attr_id {
+	CM_REQ_ATTR_ID	    = __constant_htons(0x0010),
+	CM_MRA_ATTR_ID	    = __constant_htons(0x0011),
+	CM_REJ_ATTR_ID	    = __constant_htons(0x0012),
+	CM_REP_ATTR_ID	    = __constant_htons(0x0013),
+	CM_RTU_ATTR_ID	    = __constant_htons(0x0014),
+	CM_DREQ_ATTR_ID	    = __constant_htons(0x0015),
+	CM_DREP_ATTR_ID	    = __constant_htons(0x0016),
+	CM_SIDR_REQ_ATTR_ID = __constant_htons(0x0017),
+	CM_SIDR_REP_ATTR_ID = __constant_htons(0x0018),
+	CM_LAP_ATTR_ID      = __constant_htons(0x0019),
+	CM_APR_ATTR_ID      = __constant_htons(0x001A)
+};
+
+enum cm_msg_sequence {
+	CM_MSG_SEQUENCE_REQ,
+	CM_MSG_SEQUENCE_LAP,
+	CM_MSG_SEQUENCE_DREQ,
+	CM_MSG_SEQUENCE_SIDR
+};
+
+struct cm_req_msg {
+	struct ib_mad_hdr hdr;
+
+	u32 local_comm_id;
+	u32 rsvd4;
+	u64 service_id;
+	u64 local_ca_guid;
+	u32 rsvd24;
+	u32 local_qkey;
+	/* local QPN:24, responder resources:8 */
+	u32 offset32;
+	/* local EECN:24, initiator depth:8 */
+	u32 offset36;
+	/*
+	 * remote EECN:24, remote CM response timeout:5,
+	 * transport service type:2, end-to-end flow control:1
+	 */
+	u32 offset40;
+	/* starting PSN:24, local CM response timeout:5, retry count:3 */
+	u32 offset44;
+	u16 pkey;
+	/* path MTU:4, RDC exists:1, RNR retry count:3. */
+	u8 offset50;
+	/* max CM Retries:4, SRQ:1, rsvd:3 */
+	u8 offset51;
+
+	u16 primary_local_lid;
+	u16 primary_remote_lid;
+	union ib_gid primary_local_gid;
+	union ib_gid primary_remote_gid;
+	/* flow label:20, rsvd:6, packet rate:6 */
+	u32 primary_offset88;
+	u8 primary_traffic_class;
+	u8 primary_hop_limit;
+	/* SL:4, subnet local:1, rsvd:3 */
+	u8 primary_offset94;
+	/* local ACK timeout:5, rsvd:3 */
+	u8 primary_offset95;
+
+	u16 alt_local_lid;
+	u16 alt_remote_lid;
+	union ib_gid alt_local_gid;
+	union ib_gid alt_remote_gid;
+	/* flow label:20, rsvd:6, packet rate:6 */
+	u32 alt_offset132;
+	u8 alt_traffic_class;
+	u8 alt_hop_limit;
+	/* SL:4, subnet local:1, rsvd:3 */
+	u8 alt_offset138;
+	/* local ACK timeout:5, rsvd:3 */
+	u8 alt_offset139;
+
+	u8 private_data[IB_CM_REQ_PRIVATE_DATA_SIZE];
+
+} __attribute__ ((packed));
+
+static inline u32 cm_req_get_local_qpn(struct cm_req_msg *req_msg)
+{
+	return cpu_to_be32(be32_to_cpu(req_msg->offset32) >> 8);
+}
+
+static inline void cm_req_set_local_qpn(struct cm_req_msg *req_msg, u32 qpn)
+{
+	req_msg->offset32 = cpu_to_be32((be32_to_cpu(qpn) << 8) |
+					 (be32_to_cpu(req_msg->offset32) &
+					  0x000000FF));
+}
+
+static inline u8 cm_req_get_resp_res(struct cm_req_msg *req_msg)
+{
+	return (u8) be32_to_cpu(req_msg->offset32);
+}
+
+static inline void cm_req_set_resp_res(struct cm_req_msg *req_msg, u8 resp_res)
+{
+	req_msg->offset32 = cpu_to_be32(resp_res |
+					(be32_to_cpu(req_msg->offset32) &
+					 0xFFFFFF00));
+}
+
+static inline u8 cm_req_get_init_depth(struct cm_req_msg *req_msg)
+{
+	return (u8) be32_to_cpu(req_msg->offset36);
+}
+
+static inline void cm_req_set_init_depth(struct cm_req_msg *req_msg,
+					 u8 init_depth)
+{
+	req_msg->offset36 = cpu_to_be32(init_depth |
+					(be32_to_cpu(req_msg->offset36) &
+					 0xFFFFFF00));
+}
+
+static inline u8 cm_req_get_remote_resp_timeout(struct cm_req_msg *req_msg)
+{
+	return (u8) ((be32_to_cpu(req_msg->offset40) & 0xF8) >> 3);
+}
+
+static inline void cm_req_set_remote_resp_timeout(struct cm_req_msg *req_msg,
+						  u8 resp_timeout)
+{
+	req_msg->offset40 = cpu_to_be32((resp_timeout << 3) |
+					 (be32_to_cpu(req_msg->offset40) &
+					  0xFFFFFF07));
+}
+
+static inline enum ib_qp_type cm_req_get_qp_type(struct cm_req_msg *req_msg)
+{
+	u8 transport_type = (u8) (be32_to_cpu(req_msg->offset40) & 0x06) >> 1;
+	switch(transport_type) {
+	case 0: return IB_QPT_RC;
+	case 1: return IB_QPT_UC;
+	default: return 0;
+	}
+}
+
+static inline void cm_req_set_qp_type(struct cm_req_msg *req_msg,
+				      enum ib_qp_type qp_type)
+{
+	switch(qp_type) {
+	case IB_QPT_UC:
+		req_msg->offset40 = cpu_to_be32((be32_to_cpu(
+						  req_msg->offset40) &
+						   0xFFFFFFF9) | 0x2);
+	default:
+		req_msg->offset40 = cpu_to_be32(be32_to_cpu(
+						 req_msg->offset40) &
+						  0xFFFFFFF9);
+	}
+}
+
+static inline u8 cm_req_get_flow_ctrl(struct cm_req_msg *req_msg)
+{
+	return be32_to_cpu(req_msg->offset40) & 0x1;
+}
+
+static inline void cm_req_set_flow_ctrl(struct cm_req_msg *req_msg,
+					u8 flow_ctrl)
+{
+	req_msg->offset40 = cpu_to_be32((flow_ctrl & 0x1) |
+					 (be32_to_cpu(req_msg->offset40) &
+					  0xFFFFFFFE));
+}
+
+static inline u32 cm_req_get_starting_psn(struct cm_req_msg *req_msg)
+{
+	return cpu_to_be32(be32_to_cpu(req_msg->offset44) >> 8);
+}
+
+static inline void cm_req_set_starting_psn(struct cm_req_msg *req_msg,
+					   u32 starting_psn)
+{
+	req_msg->offset44 = cpu_to_be32((be32_to_cpu(starting_psn) << 8) |
+			    (be32_to_cpu(req_msg->offset44) & 0x000000FF));
+}
+
+static inline u8 cm_req_get_local_resp_timeout(struct cm_req_msg *req_msg)
+{
+	return (u8) ((be32_to_cpu(req_msg->offset44) & 0xF8) >> 3);
+}
+
+static inline void cm_req_set_local_resp_timeout(struct cm_req_msg *req_msg,
+						 u8 resp_timeout)
+{
+	req_msg->offset44 = cpu_to_be32((resp_timeout << 3) |
+			    (be32_to_cpu(req_msg->offset44) & 0xFFFFFF07));
+}
+
+static inline u8 cm_req_get_retry_count(struct cm_req_msg *req_msg)
+{
+	return (u8) (be32_to_cpu(req_msg->offset44) & 0x7);
+}
+
+static inline void cm_req_set_retry_count(struct cm_req_msg *req_msg,
+					  u8 retry_count)
+{
+	req_msg->offset44 = cpu_to_be32((retry_count & 0x7) |
+			    (be32_to_cpu(req_msg->offset44) & 0xFFFFFFF8));
+}
+
+static inline u8 cm_req_get_path_mtu(struct cm_req_msg *req_msg)
+{
+	return req_msg->offset50 >> 4;
+}
+
+static inline void cm_req_set_path_mtu(struct cm_req_msg *req_msg, u8 path_mtu)
+{
+	req_msg->offset50 = (u8) ((req_msg->offset50 & 0xF) | (path_mtu << 4));
+}
+
+static inline u8 cm_req_get_rnr_retry_count(struct cm_req_msg *req_msg)
+{
+	return req_msg->offset50 & 0x7;
+}
+
+static inline void cm_req_set_rnr_retry_count(struct cm_req_msg *req_msg,
+					      u8 rnr_retry_count)
+{
+	req_msg->offset50 = (u8) ((req_msg->offset50 & 0xF8) |
+				  (rnr_retry_count & 0x7));
+}
+
+static inline u8 cm_req_get_max_cm_retries(struct cm_req_msg *req_msg)
+{
+	return req_msg->offset51 >> 4;
+}
+
+static inline void cm_req_set_max_cm_retries(struct cm_req_msg *req_msg,
+					     u8 retries)
+{
+	req_msg->offset51 = (u8) ((req_msg->offset51 & 0xF) | (retries << 4));
+}
+
+static inline u8 cm_req_get_srq(struct cm_req_msg *req_msg)
+{
+	return (req_msg->offset51 & 0x8) >> 3;
+}
+
+static inline void cm_req_set_srq(struct cm_req_msg *req_msg, u8 srq)
+{
+	req_msg->offset51 = (u8) ((req_msg->offset51 & 0xF7) |
+				  ((srq & 0x1) << 3));
+}
+
+static inline u32 cm_req_get_primary_flow_label(struct cm_req_msg *req_msg)
+{
+	return cpu_to_be32((be32_to_cpu(req_msg->primary_offset88) >> 12));
+}
+
+static inline void cm_req_set_primary_flow_label(struct cm_req_msg *req_msg,
+						 u32 flow_label)
+{
+	req_msg->primary_offset88 = cpu_to_be32(
+				    (be32_to_cpu(req_msg->primary_offset88) &
+				     0x00000FFF) |
+				     (be32_to_cpu(flow_label) << 12));
+}
+
+static inline u8 cm_req_get_primary_packet_rate(struct cm_req_msg *req_msg)
+{
+	return (u8) (be32_to_cpu(req_msg->primary_offset88) & 0x3F);
+}
+
+static inline void cm_req_set_primary_packet_rate(struct cm_req_msg *req_msg,
+						  u8 rate)
+{
+	req_msg->primary_offset88 = cpu_to_be32(
+				    (be32_to_cpu(req_msg->primary_offset88) &
+				     0xFFFFFFC0) | (rate & 0x3F));
+}
+
+static inline u8 cm_req_get_primary_sl(struct cm_req_msg *req_msg)
+{
+	return (u8) (req_msg->primary_offset94 >> 4);
+}
+
+static inline void cm_req_set_primary_sl(struct cm_req_msg *req_msg, u8 sl)
+{
+	req_msg->primary_offset94 = (u8) ((req_msg->primary_offset94 & 0x0F) |
+					  (sl << 4));
+}
+
+static inline u8 cm_req_get_primary_subnet_local(struct cm_req_msg *req_msg)
+{
+	return (u8) ((req_msg->primary_offset94 & 0x08) >> 3);
+}
+
+static inline void cm_req_set_primary_subnet_local(struct cm_req_msg *req_msg,
+						   u8 subnet_local)
+{
+	req_msg->primary_offset94 = (u8) ((req_msg->primary_offset94 & 0xF7) |
+					  ((subnet_local & 0x1) << 3));
+}
+
+static inline u8 cm_req_get_primary_local_ack_timeout(struct cm_req_msg *req_msg)
+{
+	return (u8) (req_msg->primary_offset95 >> 3);
+}
+
+static inline void cm_req_set_primary_local_ack_timeout(struct cm_req_msg *req_msg,
+							u8 local_ack_timeout)
+{
+	req_msg->primary_offset95 = (u8) ((req_msg->primary_offset95 & 0x07) |
+					  (local_ack_timeout << 3));
+}
+
+static inline u32 cm_req_get_alt_flow_label(struct cm_req_msg *req_msg)
+{
+	return cpu_to_be32((be32_to_cpu(req_msg->alt_offset132) >> 12));
+}
+
+static inline void cm_req_set_alt_flow_label(struct cm_req_msg *req_msg,
+					     u32 flow_label)
+{
+	req_msg->alt_offset132 = cpu_to_be32(
+				 (be32_to_cpu(req_msg->alt_offset132) &
+				  0x00000FFF) |
+				  (be32_to_cpu(flow_label) << 12));
+}
+
+static inline u8 cm_req_get_alt_packet_rate(struct cm_req_msg *req_msg)
+{
+	return (u8) (be32_to_cpu(req_msg->alt_offset132) & 0x3F);
+}
+
+static inline void cm_req_set_alt_packet_rate(struct cm_req_msg *req_msg,
+					      u8 rate)
+{
+	req_msg->alt_offset132 = cpu_to_be32(
+				 (be32_to_cpu(req_msg->alt_offset132) &
+				  0xFFFFFFC0) | (rate & 0x3F));
+}
+
+static inline u8 cm_req_get_alt_sl(struct cm_req_msg *req_msg)
+{
+	return (u8) (req_msg->alt_offset138 >> 4);
+}
+
+static inline void cm_req_set_alt_sl(struct cm_req_msg *req_msg, u8 sl)
+{
+	req_msg->alt_offset138 = (u8) ((req_msg->alt_offset138 & 0x0F) |
+				       (sl << 4));
+}
+
+static inline u8 cm_req_get_alt_subnet_local(struct cm_req_msg *req_msg)
+{
+	return (u8) ((req_msg->alt_offset138 & 0x08) >> 3);
+}
+
+static inline void cm_req_set_alt_subnet_local(struct cm_req_msg *req_msg,
+					       u8 subnet_local)
+{
+	req_msg->alt_offset138 = (u8) ((req_msg->alt_offset138 & 0xF7) |
+				       ((subnet_local & 0x1) << 3));
+}
+
+static inline u8 cm_req_get_alt_local_ack_timeout(struct cm_req_msg *req_msg)
+{
+	return (u8) (req_msg->alt_offset139 >> 3);
+}
+
+static inline void cm_req_set_alt_local_ack_timeout(struct cm_req_msg *req_msg,
+						    u8 local_ack_timeout)
+{
+	req_msg->alt_offset139 = (u8) ((req_msg->alt_offset139 & 0x07) |
+				       (local_ack_timeout << 3));
+}
+
+/* Message REJected or MRAed */
+enum cm_msg_response {
+	CM_MSG_RESPONSE_REQ = 0x0,
+	CM_MSG_RESPONSE_REP = 0x1,
+	CM_MSG_RESPONSE_OTHER = 0x2
+};
+
+ struct cm_mra_msg {
+	struct ib_mad_hdr hdr;
+
+	u32 local_comm_id;
+	u32 remote_comm_id;
+	/* message MRAed:2, rsvd:6 */
+	u8 offset8;
+	/* service timeout:5, rsvd:3 */
+	u8 offset9;
+
+	u8 private_data[IB_CM_MRA_PRIVATE_DATA_SIZE];
+
+} __attribute__ ((packed));
+
+static inline u8 cm_mra_get_msg_mraed(struct cm_mra_msg *mra_msg)
+{
+	return (u8) (mra_msg->offset8 >> 6);
+}
+
+static inline void cm_mra_set_msg_mraed(struct cm_mra_msg *mra_msg, u8 msg)
+{
+	mra_msg->offset8 = (u8) ((mra_msg->offset8 & 0x3F) | (msg << 6));
+}
+
+static inline u8 cm_mra_get_service_timeout(struct cm_mra_msg *mra_msg)
+{
+	return (u8) (mra_msg->offset9 >> 3);
+}
+
+static inline void cm_mra_set_service_timeout(struct cm_mra_msg *mra_msg,
+					      u8 service_timeout)
+{
+	mra_msg->offset9 = (u8) ((mra_msg->offset9 & 0x07) |
+				 (service_timeout << 3));
+}
+
+struct cm_rej_msg {
+	struct ib_mad_hdr hdr;
+
+	u32 local_comm_id;
+	u32 remote_comm_id;
+	/* message REJected:2, rsvd:6 */
+	u8 offset8;
+	/* reject info length:7, rsvd:1. */
+	u8 offset9;
+	u16 reason;
+	u8 ari[IB_CM_REJ_ARI_LENGTH];
+
+	u8 private_data[IB_CM_REJ_PRIVATE_DATA_SIZE];
+
+} __attribute__ ((packed));
+
+static inline u8 cm_rej_get_msg_rejected(struct cm_rej_msg *rej_msg)
+{
+	return (u8) (rej_msg->offset8 >> 6);
+}
+
+static inline void cm_rej_set_msg_rejected(struct cm_rej_msg *rej_msg, u8 msg)
+{
+	rej_msg->offset8 = (u8) ((rej_msg->offset8 & 0x3F) | (msg << 6));
+}
+
+static inline u8 cm_rej_get_reject_info_len(struct cm_rej_msg *rej_msg)
+{
+	return (u8) (rej_msg->offset9 >> 1);
+}
+
+static inline void cm_rej_set_reject_info_len(struct cm_rej_msg *rej_msg,
+					      u8 len)
+{
+	rej_msg->offset9 = (u8) ((rej_msg->offset9 & 0x1) | (len << 1));
+}
+
+struct cm_rep_msg {
+	struct ib_mad_hdr hdr;
+
+	u32 local_comm_id;
+	u32 remote_comm_id;
+	u32 local_qkey;
+	/* local QPN:24, rsvd:8 */
+	u32 offset12;
+	/* local EECN:24, rsvd:8 */
+	u32 offset16;
+	/* starting PSN:24 rsvd:8 */
+	u32 offset20;
+	u8 resp_resources;
+	u8 initiator_depth;
+	/* target ACK delay:5, failover accepted:2, end-to-end flow control:1 */
+	u8 offset26;
+	/* RNR retry count:3, SRQ:1, rsvd:5 */
+	u8 offset27;
+	u64 local_ca_guid;
+
+	u8 private_data[IB_CM_REP_PRIVATE_DATA_SIZE];
+
+} __attribute__ ((packed));
+
+static inline u32 cm_rep_get_local_qpn(struct cm_rep_msg *rep_msg)
+{
+	return cpu_to_be32(be32_to_cpu(rep_msg->offset12) >> 8);
+}
+
+static inline void cm_rep_set_local_qpn(struct cm_rep_msg *rep_msg, u32 qpn)
+{
+	rep_msg->offset12 = cpu_to_be32((be32_to_cpu(qpn) << 8) |
+			    (be32_to_cpu(rep_msg->offset12) & 0x000000FF));
+}
+
+static inline u32 cm_rep_get_starting_psn(struct cm_rep_msg *rep_msg)
+{
+	return cpu_to_be32(be32_to_cpu(rep_msg->offset20) >> 8);
+}
+
+static inline void cm_rep_set_starting_psn(struct cm_rep_msg *rep_msg,
+					   u32 starting_psn)
+{
+	rep_msg->offset20 = cpu_to_be32((be32_to_cpu(starting_psn) << 8) |
+			    (be32_to_cpu(rep_msg->offset20) & 0x000000FF));
+}
+
+static inline u8 cm_rep_get_target_ack_delay(struct cm_rep_msg *rep_msg)
+{
+	return (u8) (rep_msg->offset26 >> 3);
+}
+
+static inline void cm_rep_set_target_ack_delay(struct cm_rep_msg *rep_msg,
+					       u8 target_ack_delay)
+{
+	rep_msg->offset26 = (u8) ((rep_msg->offset26 & 0x07) |
+				  (target_ack_delay << 3));
+}
+
+static inline u8 cm_rep_get_failover(struct cm_rep_msg *rep_msg)
+{
+	return (u8) ((rep_msg->offset26 & 0x06) >> 1);
+}
+
+static inline void cm_rep_set_failover(struct cm_rep_msg *rep_msg, u8 failover)
+{
+	rep_msg->offset26 = (u8) ((rep_msg->offset26 & 0xF9) |
+				  ((failover & 0x3) << 1));
+}
+
+static inline u8 cm_rep_get_flow_ctrl(struct cm_rep_msg *rep_msg)
+{
+	return (u8) (rep_msg->offset26 & 0x01);
+}
+
+static inline void cm_rep_set_flow_ctrl(struct cm_rep_msg *rep_msg,
+					    u8 flow_ctrl)
+{
+	rep_msg->offset26 = (u8) ((rep_msg->offset26 & 0xFE) |
+				  (flow_ctrl & 0x1));
+}
+
+static inline u8 cm_rep_get_rnr_retry_count(struct cm_rep_msg *rep_msg)
+{
+	return (u8) (rep_msg->offset27 >> 5);
+}
+
+static inline void cm_rep_set_rnr_retry_count(struct cm_rep_msg *rep_msg,
+					      u8 rnr_retry_count)
+{
+	rep_msg->offset27 = (u8) ((rep_msg->offset27 & 0x1F) |
+				  (rnr_retry_count << 5));
+}
+
+static inline u8 cm_rep_get_srq(struct cm_rep_msg *rep_msg)
+{
+	return (u8) ((rep_msg->offset27 >> 4) & 0x1);
+}
+
+static inline void cm_rep_set_srq(struct cm_rep_msg *rep_msg, u8 srq)
+{
+	rep_msg->offset27 = (u8) ((rep_msg->offset27 & 0xEF) |
+				  ((srq & 0x1) << 4));
+}
+
+struct cm_rtu_msg {
+	struct ib_mad_hdr hdr;
+
+	u32 local_comm_id;
+	u32 remote_comm_id;
+
+	u8 private_data[IB_CM_RTU_PRIVATE_DATA_SIZE];
+
+} __attribute__ ((packed));
+
+struct cm_dreq_msg {
+	struct ib_mad_hdr hdr;
+
+	u32 local_comm_id;
+	u32 remote_comm_id;
+	/* remote QPN/EECN:24, rsvd:8 */
+	u32 offset8;
+
+	u8 private_data[IB_CM_DREQ_PRIVATE_DATA_SIZE];
+
+} __attribute__ ((packed));
+
+static inline u32 cm_dreq_get_remote_qpn(struct cm_dreq_msg *dreq_msg)
+{
+	return cpu_to_be32(be32_to_cpu(dreq_msg->offset8) >> 8);
+}
+
+static inline void cm_dreq_set_remote_qpn(struct cm_dreq_msg *dreq_msg, u32 qpn)
+{
+	dreq_msg->offset8 = cpu_to_be32((be32_to_cpu(qpn) << 8) |
+			    (be32_to_cpu(dreq_msg->offset8) & 0x000000FF));
+}
+
+struct cm_drep_msg {
+	struct ib_mad_hdr hdr;
+
+	u32 local_comm_id;
+	u32 remote_comm_id;
+
+	u8 private_data[IB_CM_DREP_PRIVATE_DATA_SIZE];
+
+} __attribute__ ((packed));
+
+struct cm_lap_msg {
+	struct ib_mad_hdr hdr;
+
+	u32 local_comm_id;
+	u32 remote_comm_id;
+
+	u32 rsvd8;
+	/* remote QPN/EECN:24, remote CM response timeout:5, rsvd:3 */
+	u32 offset12;
+	u32 rsvd16;
+
+	u16 alt_local_lid;
+	u16 alt_remote_lid;
+	union ib_gid alt_local_gid;
+	union ib_gid alt_remote_gid;
+	/* flow label:20, rsvd:4, traffic class:8 */
+	u32 offset56;
+	u8 alt_hop_limit;
+	/* rsvd:2, packet rate:6 */
+	uint8_t offset61;
+	/* SL:4, subnet local:1, rsvd:3 */
+	uint8_t offset62;
+	/* local ACK timeout:5, rsvd:3 */
+	uint8_t offset63;
+
+	u8 private_data[IB_CM_LAP_PRIVATE_DATA_SIZE];
+} __attribute__  ((packed));
+
+static inline u32 cm_lap_get_remote_qpn(struct cm_lap_msg *lap_msg)
+{
+	return cpu_to_be32(be32_to_cpu(lap_msg->offset12) >> 8);
+}
+
+static inline void cm_lap_set_remote_qpn(struct cm_lap_msg *lap_msg, u32 qpn)
+{
+	lap_msg->offset12 = cpu_to_be32((be32_to_cpu(qpn) << 8) |
+					 (be32_to_cpu(lap_msg->offset12) &
+					  0x000000FF));
+}
+
+static inline u8 cm_lap_get_remote_resp_timeout(struct cm_lap_msg *lap_msg)
+{
+	return (u8) ((be32_to_cpu(lap_msg->offset12) & 0xF8) >> 3);
+}
+
+static inline void cm_lap_set_remote_resp_timeout(struct cm_lap_msg *lap_msg,
+						  u8 resp_timeout)
+{
+	lap_msg->offset12 = cpu_to_be32((resp_timeout << 3) |
+					 (be32_to_cpu(lap_msg->offset12) &
+					  0xFFFFFF07));
+}
+
+static inline u32 cm_lap_get_flow_label(struct cm_lap_msg *lap_msg)
+{
+	return be32_to_cpu(lap_msg->offset56) >> 12;
+}
+
+static inline void cm_lap_set_flow_label(struct cm_lap_msg *lap_msg,
+					 u32 flow_label)
+{
+	lap_msg->offset56 = cpu_to_be32((flow_label << 12) |
+					 (be32_to_cpu(lap_msg->offset56) &
+					  0x00000FFF));
+}
+
+static inline u8 cm_lap_get_traffic_class(struct cm_lap_msg *lap_msg)
+{
+	return (u8) be32_to_cpu(lap_msg->offset56);
+}
+
+static inline void cm_lap_set_traffic_class(struct cm_lap_msg *lap_msg,
+					    u8 traffic_class)
+{
+	lap_msg->offset56 = cpu_to_be32(traffic_class |
+					 (be32_to_cpu(lap_msg->offset56) &
+					  0xFFFFFF00));
+}
+
+static inline u8 cm_lap_get_packet_rate(struct cm_lap_msg *lap_msg)
+{
+	return lap_msg->offset61 & 0x3F;
+}
+
+static inline void cm_lap_set_packet_rate(struct cm_lap_msg *lap_msg,
+					  u8 packet_rate)
+{
+	lap_msg->offset61 = (packet_rate & 0x3F) | (lap_msg->offset61 & 0xC0);
+}
+
+static inline u8 cm_lap_get_sl(struct cm_lap_msg *lap_msg)
+{
+	return lap_msg->offset62 >> 4;
+}
+
+static inline void cm_lap_set_sl(struct cm_lap_msg *lap_msg, u8 sl)
+{
+	lap_msg->offset62 = (sl << 4) | (lap_msg->offset62 & 0x0F);
+}
+
+static inline u8 cm_lap_get_subnet_local(struct cm_lap_msg *lap_msg)
+{
+	return (lap_msg->offset62 >> 3) & 0x1;
+}
+
+static inline void cm_lap_set_subnet_local(struct cm_lap_msg *lap_msg,
+					   u8 subnet_local)
+{
+	lap_msg->offset62 = ((subnet_local & 0x1) << 3) |
+			     (lap_msg->offset61 & 0xF7);
+}
+static inline u8 cm_lap_get_local_ack_timeout(struct cm_lap_msg *lap_msg)
+{
+	return lap_msg->offset63 >> 3;
+}
+
+static inline void cm_lap_set_local_ack_timeout(struct cm_lap_msg *lap_msg,
+						u8 local_ack_timeout)
+{
+	lap_msg->offset63 = (local_ack_timeout << 3) |
+			    (lap_msg->offset63 & 0x07);
+}
+
+struct cm_apr_msg {
+	struct ib_mad_hdr hdr;
+
+	u32 local_comm_id;
+	u32 remote_comm_id;
+
+	u8 info_length;
+	u8 ap_status;
+	u8 info[IB_CM_APR_INFO_LENGTH];
+
+	u8 private_data[IB_CM_APR_PRIVATE_DATA_SIZE];
+} __attribute__ ((packed));
+
+struct cm_sidr_req_msg {
+	struct ib_mad_hdr hdr;
+
+	u32 request_id;
+	u16 pkey;
+	u16 rsvd;
+	u64 service_id;
+
+	u8 private_data[IB_CM_SIDR_REQ_PRIVATE_DATA_SIZE];
+} __attribute__ ((packed));
+
+struct cm_sidr_rep_msg {
+	struct ib_mad_hdr hdr;
+
+	u32 request_id;
+	u8 status;
+	u8 info_length;
+	u16 rsvd;
+	/* QPN:24, rsvd:8 */
+	u32 offset8;
+	u64 service_id;
+	u32 qkey;
+	u8 info[IB_CM_SIDR_REP_INFO_LENGTH];
+
+	u8 private_data[IB_CM_SIDR_REP_PRIVATE_DATA_SIZE];
+} __attribute__ ((packed));
+
+static inline u32 cm_sidr_rep_get_qpn(struct cm_sidr_rep_msg *sidr_rep_msg)
+{
+	return cpu_to_be32(be32_to_cpu(sidr_rep_msg->offset8) >> 8);
+}
+
+static inline void cm_sidr_rep_set_qpn(struct cm_sidr_rep_msg *sidr_rep_msg,
+				       u32 qpn)
+{
+	sidr_rep_msg->offset8 = cpu_to_be32((be32_to_cpu(qpn) << 8) |
+					(be32_to_cpu(sidr_rep_msg->offset8) &
+					 0x000000FF));
+}
+
+#endif /* CM_MSGS_H */
diff --git a/drivers/infiniband/core/fmr_pool.c b/drivers/infiniband/core/fmr_pool.c
--- a/drivers/infiniband/core/fmr_pool.c
+++ b/drivers/infiniband/core/fmr_pool.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2004 Topspin Communications.  All rights reserved.
+ * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
@@ -29,7 +30,7 @@
  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  *
- * $Id: fmr_pool.c 1349 2004-12-16 21:09:43Z roland $
+ * $Id: fmr_pool.c 2730 2005-06-28 16:43:03Z sean.hefty $
  */
 
 #include <linux/errno.h>
@@ -329,7 +330,7 @@ EXPORT_SYMBOL(ib_create_fmr_pool);
  *
  * Destroy an FMR pool and free all associated resources.
  */
-int ib_destroy_fmr_pool(struct ib_fmr_pool *pool)
+void ib_destroy_fmr_pool(struct ib_fmr_pool *pool)
 {
 	struct ib_pool_fmr *fmr;
 	struct ib_pool_fmr *tmp;
@@ -352,8 +353,6 @@ int ib_destroy_fmr_pool(struct ib_fmr_po
 
 	kfree(pool->cache_bucket);
 	kfree(pool);
-
-	return 0;
 }
 EXPORT_SYMBOL(ib_destroy_fmr_pool);
 
diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c
--- a/drivers/infiniband/core/mad.c
+++ b/drivers/infiniband/core/mad.c
@@ -1,5 +1,7 @@
 /*
  * Copyright (c) 2004, 2005 Voltaire, Inc. All rights reserved.
+ * Copyright (c) 2005 Intel Corporation.  All rights reserved.
+ * Copyright (c) 2005 Mellanox Technologies Ltd.  All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
@@ -29,12 +31,12 @@
  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  *
- * $Id: mad.c 1389 2004-12-27 22:56:47Z roland $
+ * $Id: mad.c 2817 2005-07-07 11:29:26Z halr $
  */
-
 #include <linux/dma-mapping.h>
 
 #include "mad_priv.h"
+#include "mad_rmpp.h"
 #include "smi.h"
 #include "agent.h"
 
@@ -45,6 +47,7 @@ MODULE_AUTHOR("Sean Hefty");
 
 
 kmem_cache_t *ib_mad_cache;
+
 static struct list_head ib_mad_port_list;
 static u32 ib_mad_client_id = 0;
 
@@ -58,16 +61,12 @@ static int method_in_use(struct ib_mad_m
 static void remove_mad_reg_req(struct ib_mad_agent_private *priv);
 static struct ib_mad_agent_private *find_mad_agent(
 					struct ib_mad_port_private *port_priv,
-					struct ib_mad *mad, int solicited);
+					struct ib_mad *mad);
 static int ib_mad_post_receive_mads(struct ib_mad_qp_info *qp_info,
 				    struct ib_mad_private *mad);
 static void cancel_mads(struct ib_mad_agent_private *mad_agent_priv);
-static void ib_mad_complete_send_wr(struct ib_mad_send_wr_private *mad_send_wr,
-				    struct ib_mad_send_wc *mad_send_wc);
 static void timeout_sends(void *data);
-static void cancel_sends(void *data);
 static void local_completions(void *data);
-static int solicited_mad(struct ib_mad *mad);
 static int add_nonoui_reg_req(struct ib_mad_reg_req *mad_reg_req,
 			      struct ib_mad_agent_private *agent_priv,
 			      u8 mgmt_class);
@@ -197,8 +196,8 @@ struct ib_mad_agent *ib_register_mad_age
 	if (qpn == -1)
 		goto error1;
 
-	if (rmpp_version)
-		goto error1;	/* XXX: until RMPP implemented */
+	if (rmpp_version && rmpp_version != IB_MGMT_RMPP_VERSION)
+		goto error1;
 
 	/* Validate MAD registration request if supplied */
 	if (mad_reg_req) {
@@ -261,22 +260,29 @@ struct ib_mad_agent *ib_register_mad_age
 		ret = ERR_PTR(-ENOMEM);
 		goto error1;
 	}
+	memset(mad_agent_priv, 0, sizeof *mad_agent_priv);
+
+	mad_agent_priv->agent.mr = ib_get_dma_mr(port_priv->qp_info[qpn].qp->pd,
+						 IB_ACCESS_LOCAL_WRITE);
+	if (IS_ERR(mad_agent_priv->agent.mr)) {
+		ret = ERR_PTR(-ENOMEM);
+		goto error2;
+	}
 
 	if (mad_reg_req) {
 		reg_req = kmalloc(sizeof *reg_req, GFP_KERNEL);
 		if (!reg_req) {
 			ret = ERR_PTR(-ENOMEM);
-			goto error2;
+			goto error3;
 		}
 		/* Make a copy of the MAD registration request */
 		memcpy(reg_req, mad_reg_req, sizeof *reg_req);
 	}
 
 	/* Now, fill in the various structures */
-	memset(mad_agent_priv, 0, sizeof *mad_agent_priv);
 	mad_agent_priv->qp_info = &port_priv->qp_info[qpn];
 	mad_agent_priv->reg_req = reg_req;
-	mad_agent_priv->rmpp_version = rmpp_version;
+	mad_agent_priv->agent.rmpp_version = rmpp_version;
 	mad_agent_priv->agent.device = device;
 	mad_agent_priv->agent.recv_handler = recv_handler;
 	mad_agent_priv->agent.send_handler = send_handler;
@@ -301,7 +307,7 @@ struct ib_mad_agent *ib_register_mad_age
 				if (method) {
 					if (method_in_use(&method,
 							   mad_reg_req))
-						goto error3;
+						goto error4;
 				}
 			}
 			ret2 = add_nonoui_reg_req(mad_reg_req, mad_agent_priv,
@@ -317,14 +323,14 @@ struct ib_mad_agent *ib_register_mad_age
 					if (is_vendor_method_in_use(
 							vendor_class,
 							mad_reg_req))
-						goto error3;
+						goto error4;
 				}
 			}
 			ret2 = add_oui_reg_req(mad_reg_req, mad_agent_priv);
 		}
 		if (ret2) {
 			ret = ERR_PTR(ret2);
-			goto error3;
+			goto error4;
 		}
 	}
 
@@ -335,22 +341,24 @@ struct ib_mad_agent *ib_register_mad_age
 	spin_lock_init(&mad_agent_priv->lock);
 	INIT_LIST_HEAD(&mad_agent_priv->send_list);
 	INIT_LIST_HEAD(&mad_agent_priv->wait_list);
+	INIT_LIST_HEAD(&mad_agent_priv->done_list);
+	INIT_LIST_HEAD(&mad_agent_priv->rmpp_list);
 	INIT_WORK(&mad_agent_priv->timed_work, timeout_sends, mad_agent_priv);
 	INIT_LIST_HEAD(&mad_agent_priv->local_list);
 	INIT_WORK(&mad_agent_priv->local_work, local_completions,
 		   mad_agent_priv);
-	INIT_LIST_HEAD(&mad_agent_priv->canceled_list);
-	INIT_WORK(&mad_agent_priv->canceled_work, cancel_sends, mad_agent_priv);
 	atomic_set(&mad_agent_priv->refcount, 1);
 	init_waitqueue_head(&mad_agent_priv->wait);
 
 	return &mad_agent_priv->agent;
 
-error3:
+error4:
 	spin_unlock_irqrestore(&port_priv->reg_lock, flags);
 	kfree(reg_req);
-error2:
+error3:
 	kfree(mad_agent_priv);
+error2:
+	ib_dereg_mr(mad_agent_priv->agent.mr);
 error1:
 	return ret;
 }
@@ -487,18 +495,16 @@ static void unregister_mad_agent(struct 
 	 * MADs, preventing us from queuing additional work
 	 */
 	cancel_mads(mad_agent_priv);
-
 	port_priv = mad_agent_priv->qp_info->port_priv;
-
 	cancel_delayed_work(&mad_agent_priv->timed_work);
-	flush_workqueue(port_priv->wq);
 
 	spin_lock_irqsave(&port_priv->reg_lock, flags);
 	remove_mad_reg_req(mad_agent_priv);
 	list_del(&mad_agent_priv->agent_list);
 	spin_unlock_irqrestore(&port_priv->reg_lock, flags);
 
-	/* XXX: Cleanup pending RMPP receives for this agent */
+	flush_workqueue(port_priv->wq);
+	ib_cancel_rmpp_recvs(mad_agent_priv);
 
 	atomic_dec(&mad_agent_priv->refcount);
 	wait_event(mad_agent_priv->wait,
@@ -506,6 +512,7 @@ static void unregister_mad_agent(struct 
 
 	if (mad_agent_priv->reg_req)
 		kfree(mad_agent_priv->reg_req);
+	ib_dereg_mr(mad_agent_priv->agent.mr);
 	kfree(mad_agent_priv);
 }
 
@@ -551,6 +558,13 @@ int ib_unregister_mad_agent(struct ib_ma
 }
 EXPORT_SYMBOL(ib_unregister_mad_agent);
 
+static inline int response_mad(struct ib_mad *mad)
+{
+	/* Trap represses are responses although response bit is reset */
+	return ((mad->mad_hdr.method == IB_MGMT_METHOD_TRAP_REPRESS) ||
+		(mad->mad_hdr.method & IB_MGMT_METHOD_RESP));
+}
+
 static void dequeue_mad(struct ib_mad_list_head *mad_list)
 {
 	struct ib_mad_queue *mad_queue;
@@ -643,7 +657,7 @@ static int handle_outgoing_dr_smp(struct
 				  struct ib_smp *smp,
 				  struct ib_send_wr *send_wr)
 {
-	int ret, solicited;
+	int ret;
 	unsigned long flags;
 	struct ib_mad_local_private *local;
 	struct ib_mad_private *mad_priv;
@@ -689,11 +703,7 @@ static int handle_outgoing_dr_smp(struct
 	switch (ret)
 	{
 	case IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_REPLY:
-		/*
-		 * See if response is solicited and
-		 * there is a recv handler
-		 */
-		if (solicited_mad(&mad_priv->mad.mad) &&
+		if (response_mad(&mad_priv->mad.mad) &&
 		    mad_agent_priv->agent.recv_handler) {
 			local->mad_priv = mad_priv;
 			local->recv_mad_agent = mad_agent_priv;
@@ -710,15 +720,13 @@ static int handle_outgoing_dr_smp(struct
 		break;
 	case IB_MAD_RESULT_SUCCESS:
 		/* Treat like an incoming receive MAD */
-		solicited = solicited_mad(&mad_priv->mad.mad);
 		port_priv = ib_get_mad_port(mad_agent_priv->agent.device,
 					    mad_agent_priv->agent.port_num);
 		if (port_priv) {
 			mad_priv->mad.mad.mad_hdr.tid =
 				((struct ib_mad *)smp)->mad_hdr.tid;
 			recv_mad_agent = find_mad_agent(port_priv,
-						       &mad_priv->mad.mad,
-							solicited);
+						        &mad_priv->mad.mad);
 		}
 		if (!port_priv || !recv_mad_agent) {
 			kmem_cache_free(ib_mad_cache, mad_priv);
@@ -750,43 +758,133 @@ static int handle_outgoing_dr_smp(struct
 	list_add_tail(&local->completion_list, &mad_agent_priv->local_list);
 	spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
 	queue_work(mad_agent_priv->qp_info->port_priv->wq,
-		  &mad_agent_priv->local_work);
+		   &mad_agent_priv->local_work);
 	ret = 1;
 out:
 	return ret;
 }
 
-static int ib_send_mad(struct ib_mad_agent_private *mad_agent_priv,
-		       struct ib_mad_send_wr_private *mad_send_wr)
+static int get_buf_length(int hdr_len, int data_len)
+{
+	int seg_size, pad;
+
+	seg_size = sizeof(struct ib_mad) - hdr_len;
+	if (data_len && seg_size) {
+		pad = seg_size - data_len % seg_size;
+		if (pad == seg_size)
+			pad = 0;
+	} else
+		pad = seg_size;
+	return hdr_len + data_len + pad;
+}
+
+struct ib_mad_send_buf * ib_create_send_mad(struct ib_mad_agent *mad_agent,
+					    u32 remote_qpn, u16 pkey_index,
+					    struct ib_ah *ah, int rmpp_active,
+					    int hdr_len, int data_len,
+					    unsigned int __nocast gfp_mask)
+{
+	struct ib_mad_agent_private *mad_agent_priv;
+	struct ib_mad_send_buf *send_buf;
+	int buf_size;
+	void *buf;
+
+	mad_agent_priv = container_of(mad_agent,
+				      struct ib_mad_agent_private, agent);
+	buf_size = get_buf_length(hdr_len, data_len);
+
+	if ((!mad_agent->rmpp_version &&
+	     (rmpp_active || buf_size > sizeof(struct ib_mad))) ||
+	    (!rmpp_active && buf_size > sizeof(struct ib_mad)))
+		return ERR_PTR(-EINVAL);
+
+	buf = kmalloc(sizeof *send_buf + buf_size, gfp_mask);
+	if (!buf)
+		return ERR_PTR(-ENOMEM);
+	memset(buf, 0, sizeof *send_buf + buf_size);
+
+	send_buf = buf + buf_size;
+	send_buf->mad = buf;
+
+	send_buf->sge.addr = dma_map_single(mad_agent->device->dma_device,
+					    buf, buf_size, DMA_TO_DEVICE);
+	pci_unmap_addr_set(send_buf, mapping, send_buf->sge.addr);
+	send_buf->sge.length = buf_size;
+	send_buf->sge.lkey = mad_agent->mr->lkey;
+
+	send_buf->send_wr.wr_id = (unsigned long) send_buf;
+	send_buf->send_wr.sg_list = &send_buf->sge;
+	send_buf->send_wr.num_sge = 1;
+	send_buf->send_wr.opcode = IB_WR_SEND;
+	send_buf->send_wr.send_flags = IB_SEND_SIGNALED;
+	send_buf->send_wr.wr.ud.ah = ah;
+	send_buf->send_wr.wr.ud.mad_hdr = &send_buf->mad->mad_hdr;
+	send_buf->send_wr.wr.ud.remote_qpn = remote_qpn;
+	send_buf->send_wr.wr.ud.remote_qkey = IB_QP_SET_QKEY;
+	send_buf->send_wr.wr.ud.pkey_index = pkey_index;
+
+	if (rmpp_active) {
+		struct ib_rmpp_mad *rmpp_mad;
+		rmpp_mad = (struct ib_rmpp_mad *)send_buf->mad;
+		rmpp_mad->rmpp_hdr.paylen_newwin = cpu_to_be32(hdr_len -
+			offsetof(struct ib_rmpp_mad, data) + data_len);
+		rmpp_mad->rmpp_hdr.rmpp_version = mad_agent->rmpp_version;
+		rmpp_mad->rmpp_hdr.rmpp_type = IB_MGMT_RMPP_TYPE_DATA;
+		ib_set_rmpp_flags(&rmpp_mad->rmpp_hdr,
+				  IB_MGMT_RMPP_FLAG_ACTIVE);
+	}
+
+	send_buf->mad_agent = mad_agent;
+	atomic_inc(&mad_agent_priv->refcount);
+	return send_buf;
+}
+EXPORT_SYMBOL(ib_create_send_mad);
+
+void ib_free_send_mad(struct ib_mad_send_buf *send_buf)
+{
+	struct ib_mad_agent_private *mad_agent_priv;
+
+	mad_agent_priv = container_of(send_buf->mad_agent,
+				      struct ib_mad_agent_private, agent);
+
+	dma_unmap_single(send_buf->mad_agent->device->dma_device,
+			 pci_unmap_addr(send_buf, mapping),
+			 send_buf->sge.length, DMA_TO_DEVICE);
+	kfree(send_buf->mad);
+
+	if (atomic_dec_and_test(&mad_agent_priv->refcount))
+		wake_up(&mad_agent_priv->wait);
+}
+EXPORT_SYMBOL(ib_free_send_mad);
+
+int ib_send_mad(struct ib_mad_send_wr_private *mad_send_wr)
 {
 	struct ib_mad_qp_info *qp_info;
 	struct ib_send_wr *bad_send_wr;
+	struct list_head *list;
 	unsigned long flags;
 	int ret;
 
-	/* Replace user's WR ID with our own to find WR upon completion */
-	qp_info = mad_agent_priv->qp_info;
-	mad_send_wr->wr_id = mad_send_wr->send_wr.wr_id;
+	/* Set WR ID to find mad_send_wr upon completion */
+	qp_info = mad_send_wr->mad_agent_priv->qp_info;
 	mad_send_wr->send_wr.wr_id = (unsigned long)&mad_send_wr->mad_list;
 	mad_send_wr->mad_list.mad_queue = &qp_info->send_queue;
 
 	spin_lock_irqsave(&qp_info->send_queue.lock, flags);
-	if (qp_info->send_queue.count++ < qp_info->send_queue.max_active) {
-		list_add_tail(&mad_send_wr->mad_list.list,
-			      &qp_info->send_queue.list);
-		spin_unlock_irqrestore(&qp_info->send_queue.lock, flags);
-		ret = ib_post_send(mad_agent_priv->agent.qp,
+	if (qp_info->send_queue.count < qp_info->send_queue.max_active) {
+		ret = ib_post_send(mad_send_wr->mad_agent_priv->agent.qp,
 				   &mad_send_wr->send_wr, &bad_send_wr);
-		if (ret) {
-			printk(KERN_ERR PFX "ib_post_send failed: %d\n", ret);
-			dequeue_mad(&mad_send_wr->mad_list);
-		}
+		list = &qp_info->send_queue.list;
 	} else {
-		list_add_tail(&mad_send_wr->mad_list.list,
-			      &qp_info->overflow_list);
-		spin_unlock_irqrestore(&qp_info->send_queue.lock, flags);
 		ret = 0;
+		list = &qp_info->overflow_list;
 	}
+
+	if (!ret) {
+		qp_info->send_queue.count++;
+		list_add_tail(&mad_send_wr->mad_list.list, list);
+	}
+	spin_unlock_irqrestore(&qp_info->send_queue.lock, flags);
 	return ret;
 }
 
@@ -860,18 +958,19 @@ int ib_post_send_mad(struct ib_mad_agent
 			ret = -ENOMEM;
 			goto error2;
 		}
+		memset(mad_send_wr, 0, sizeof *mad_send_wr);
 
 		mad_send_wr->send_wr = *send_wr;
 		mad_send_wr->send_wr.sg_list = mad_send_wr->sg_list;
 		memcpy(mad_send_wr->sg_list, send_wr->sg_list,
 		       sizeof *send_wr->sg_list * send_wr->num_sge);
-		mad_send_wr->send_wr.next = NULL;
+		mad_send_wr->wr_id = send_wr->wr_id;
 		mad_send_wr->tid = send_wr->wr.ud.mad_hdr->tid;
-		mad_send_wr->agent = mad_agent;
+		mad_send_wr->mad_agent_priv = mad_agent_priv;
 		/* Timeout will be updated after send completes */
 		mad_send_wr->timeout = msecs_to_jiffies(send_wr->wr.
 							ud.timeout_ms);
-		mad_send_wr->retry = 0;
+		mad_send_wr->retries = mad_send_wr->send_wr.wr.ud.retries;
 		/* One reference for each work request to QP + response */
 		mad_send_wr->refcount = 1 + (mad_send_wr->timeout > 0);
 		mad_send_wr->status = IB_WC_SUCCESS;
@@ -883,8 +982,13 @@ int ib_post_send_mad(struct ib_mad_agent
 			      &mad_agent_priv->send_list);
 		spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
 
-		ret = ib_send_mad(mad_agent_priv, mad_send_wr);
-		if (ret) {
+		if (mad_agent_priv->agent.rmpp_version) {
+			ret = ib_send_rmpp_mad(mad_send_wr);
+			if (ret >= 0 && ret != IB_RMPP_RESULT_CONSUMED)
+				ret = ib_send_mad(mad_send_wr);
+		} else
+			ret = ib_send_mad(mad_send_wr);
+		if (ret < 0) {
 			/* Fail send request */
 			spin_lock_irqsave(&mad_agent_priv->lock, flags);
 			list_del(&mad_send_wr->agent_list);
@@ -910,41 +1014,28 @@ EXPORT_SYMBOL(ib_post_send_mad);
  */
 void ib_free_recv_mad(struct ib_mad_recv_wc *mad_recv_wc)
 {
-	struct ib_mad_recv_buf *entry;
+	struct ib_mad_recv_buf *mad_recv_buf, *temp_recv_buf;
 	struct ib_mad_private_header *mad_priv_hdr;
 	struct ib_mad_private *priv;
+	struct list_head free_list;
 
-	mad_priv_hdr = container_of(mad_recv_wc,
-				    struct ib_mad_private_header,
-				    recv_wc);
-	priv = container_of(mad_priv_hdr, struct ib_mad_private, header);
+	INIT_LIST_HEAD(&free_list);
+	list_splice_init(&mad_recv_wc->rmpp_list, &free_list);
 
-	/*
-	 * Walk receive buffer list associated with this WC
-	 * No need to remove them from list of receive buffers
-	 */
-	list_for_each_entry(entry, &mad_recv_wc->recv_buf.list, list) {
-		/* Free previous receive buffer */
-		kmem_cache_free(ib_mad_cache, priv);
+	list_for_each_entry_safe(mad_recv_buf, temp_recv_buf,
+					&free_list, list) {
+		mad_recv_wc = container_of(mad_recv_buf, struct ib_mad_recv_wc,
+					   recv_buf);
 		mad_priv_hdr = container_of(mad_recv_wc,
 					    struct ib_mad_private_header,
 					    recv_wc);
 		priv = container_of(mad_priv_hdr, struct ib_mad_private,
 				    header);
+		kmem_cache_free(ib_mad_cache, priv);
 	}
-
-	/* Free last buffer */
-	kmem_cache_free(ib_mad_cache, priv);
 }
 EXPORT_SYMBOL(ib_free_recv_mad);
 
-void ib_coalesce_recv_mad(struct ib_mad_recv_wc *mad_recv_wc,
-			  void *buf)
-{
-	printk(KERN_ERR PFX "ib_coalesce_recv_mad() not implemented yet\n");
-}
-EXPORT_SYMBOL(ib_coalesce_recv_mad);
-
 struct ib_mad_agent *ib_redirect_mad_qp(struct ib_qp *qp,
 					u8 rmpp_version,
 					ib_mad_send_handler send_handler,
@@ -1338,42 +1429,15 @@ out:
 	return;
 }
 
-static int response_mad(struct ib_mad *mad)
-{
-	/* Trap represses are responses although response bit is reset */
-	return ((mad->mad_hdr.method == IB_MGMT_METHOD_TRAP_REPRESS) ||
-		(mad->mad_hdr.method & IB_MGMT_METHOD_RESP));
-}
-
-static int solicited_mad(struct ib_mad *mad)
-{
-	/* CM MADs are never solicited */
-	if (mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_CM) {
-		return 0;
-	}
-
-	/* XXX: Determine whether MAD is using RMPP */
-
-	/* Not using RMPP */
-	/* Is this MAD a response to a previous MAD ? */
-	return response_mad(mad);
-}
-
 static struct ib_mad_agent_private *
 find_mad_agent(struct ib_mad_port_private *port_priv,
-	       struct ib_mad *mad,
-	       int solicited)
+	       struct ib_mad *mad)
 {
 	struct ib_mad_agent_private *mad_agent = NULL;
 	unsigned long flags;
 
 	spin_lock_irqsave(&port_priv->reg_lock, flags);
-
-	/*
-	 * Whether MAD was solicited determines type of routing to
-	 * MAD client.
-	 */
-	if (solicited) {
+	if (response_mad(mad)) {
 		u32 hi_tid;
 		struct ib_mad_agent_private *entry;
 
@@ -1477,21 +1541,20 @@ out:
 	return valid;
 }
 
-/*
- * Return start of fully reassembled MAD, or NULL, if MAD isn't assembled yet
- */
-static struct ib_mad_private *
-reassemble_recv(struct ib_mad_agent_private *mad_agent_priv,
-		struct ib_mad_private *recv)
-{
-	/* Until we have RMPP, all receives are reassembled!... */
-	INIT_LIST_HEAD(&recv->header.recv_wc.recv_buf.list);
-	return recv;
+static int is_data_mad(struct ib_mad_agent_private *mad_agent_priv,
+		       struct ib_mad_hdr *mad_hdr)
+{
+	struct ib_rmpp_mad *rmpp_mad;
+
+	rmpp_mad = (struct ib_rmpp_mad *)mad_hdr;
+	return !mad_agent_priv->agent.rmpp_version ||
+		!(ib_get_rmpp_flags(&rmpp_mad->rmpp_hdr) &
+				    IB_MGMT_RMPP_FLAG_ACTIVE) ||
+		(rmpp_mad->rmpp_hdr.rmpp_type == IB_MGMT_RMPP_TYPE_DATA);
 }
 
-static struct ib_mad_send_wr_private*
-find_send_req(struct ib_mad_agent_private *mad_agent_priv,
-	      u64 tid)
+struct ib_mad_send_wr_private*
+ib_find_send_mad(struct ib_mad_agent_private *mad_agent_priv, u64 tid)
 {
 	struct ib_mad_send_wr_private *mad_send_wr;
 
@@ -1507,7 +1570,9 @@ find_send_req(struct ib_mad_agent_privat
 	 */
 	list_for_each_entry(mad_send_wr, &mad_agent_priv->send_list,
 			    agent_list) {
-		if (mad_send_wr->tid == tid && mad_send_wr->timeout) {
+		if (is_data_mad(mad_agent_priv,
+				mad_send_wr->send_wr.wr.ud.mad_hdr) &&
+		    mad_send_wr->tid == tid && mad_send_wr->timeout) {
 			/* Verify request has not been canceled */
 			return (mad_send_wr->status == IB_WC_SUCCESS) ?
 				mad_send_wr : NULL;
@@ -1516,43 +1581,55 @@ find_send_req(struct ib_mad_agent_privat
 	return NULL;
 }
 
+void ib_mark_mad_done(struct ib_mad_send_wr_private *mad_send_wr)
+{
+	mad_send_wr->timeout = 0;
+	if (mad_send_wr->refcount == 1) {
+		list_del(&mad_send_wr->agent_list);
+		list_add_tail(&mad_send_wr->agent_list,
+			      &mad_send_wr->mad_agent_priv->done_list);
+	}
+}
+
 static void ib_mad_complete_recv(struct ib_mad_agent_private *mad_agent_priv,
-				 struct ib_mad_private *recv,
-				 int solicited)
+				 struct ib_mad_recv_wc *mad_recv_wc)
 {
 	struct ib_mad_send_wr_private *mad_send_wr;
 	struct ib_mad_send_wc mad_send_wc;
 	unsigned long flags;
+	u64 tid;
 
-	/* Fully reassemble receive before processing */
-	recv = reassemble_recv(mad_agent_priv, recv);
-	if (!recv) {
-		if (atomic_dec_and_test(&mad_agent_priv->refcount))
-			wake_up(&mad_agent_priv->wait);
-		return;
+	INIT_LIST_HEAD(&mad_recv_wc->rmpp_list);
+	list_add(&mad_recv_wc->recv_buf.list, &mad_recv_wc->rmpp_list);
+	if (mad_agent_priv->agent.rmpp_version) {
+		mad_recv_wc = ib_process_rmpp_recv_wc(mad_agent_priv,
+						      mad_recv_wc);
+		if (!mad_recv_wc) {
+			if (atomic_dec_and_test(&mad_agent_priv->refcount))
+				wake_up(&mad_agent_priv->wait);
+			return;
+		}
 	}
 
 	/* Complete corresponding request */
-	if (solicited) {
+	if (response_mad(mad_recv_wc->recv_buf.mad)) {
+		tid = mad_recv_wc->recv_buf.mad->mad_hdr.tid;
 		spin_lock_irqsave(&mad_agent_priv->lock, flags);
-		mad_send_wr = find_send_req(mad_agent_priv,
-					    recv->mad.mad.mad_hdr.tid);
+		mad_send_wr = ib_find_send_mad(mad_agent_priv, tid);
 		if (!mad_send_wr) {
 			spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
-			ib_free_recv_mad(&recv->header.recv_wc);
+			ib_free_recv_mad(mad_recv_wc);
 			if (atomic_dec_and_test(&mad_agent_priv->refcount))
 				wake_up(&mad_agent_priv->wait);
 			return;
 		}
-		/* Timeout = 0 means that we won't wait for a response */
-		mad_send_wr->timeout = 0;
+		ib_mark_mad_done(mad_send_wr);
 		spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
 
 		/* Defined behavior is to complete response before request */
-		recv->header.recv_wc.wc->wr_id = mad_send_wr->wr_id;
-		mad_agent_priv->agent.recv_handler(
-						&mad_agent_priv->agent,
-						&recv->header.recv_wc);
+		mad_recv_wc->wc->wr_id = mad_send_wr->wr_id;
+		mad_agent_priv->agent.recv_handler(&mad_agent_priv->agent,
+						   mad_recv_wc);
 		atomic_dec(&mad_agent_priv->refcount);
 
 		mad_send_wc.status = IB_WC_SUCCESS;
@@ -1560,9 +1637,8 @@ static void ib_mad_complete_recv(struct 
 		mad_send_wc.wr_id = mad_send_wr->wr_id;
 		ib_mad_complete_send_wr(mad_send_wr, &mad_send_wc);
 	} else {
-		mad_agent_priv->agent.recv_handler(
-						&mad_agent_priv->agent,
-						&recv->header.recv_wc);
+		mad_agent_priv->agent.recv_handler(&mad_agent_priv->agent,
+						   mad_recv_wc);
 		if (atomic_dec_and_test(&mad_agent_priv->refcount))
 			wake_up(&mad_agent_priv->wait);
 	}
@@ -1576,7 +1652,6 @@ static void ib_mad_recv_done_handler(str
 	struct ib_mad_private *recv, *response;
 	struct ib_mad_list_head *mad_list;
 	struct ib_mad_agent_private *mad_agent;
-	int solicited;
 
 	response = kmem_cache_alloc(ib_mad_cache, GFP_KERNEL);
 	if (!response)
@@ -1662,11 +1737,9 @@ local:
 		}
 	}
 
-	/* Determine corresponding MAD agent for incoming receive MAD */
-	solicited = solicited_mad(&recv->mad.mad);
-	mad_agent = find_mad_agent(port_priv, &recv->mad.mad, solicited);
+	mad_agent = find_mad_agent(port_priv, &recv->mad.mad);
 	if (mad_agent) {
-		ib_mad_complete_recv(mad_agent, recv, solicited);
+		ib_mad_complete_recv(mad_agent, &recv->header.recv_wc);
 		/*
 		 * recv is freed up in error cases in ib_mad_complete_recv
 		 * or via recv_handler in ib_mad_complete_recv()
@@ -1710,26 +1783,31 @@ static void adjust_timeout(struct ib_mad
 	}
 }
 
-static void wait_for_response(struct ib_mad_agent_private *mad_agent_priv,
-			      struct ib_mad_send_wr_private *mad_send_wr )
+static void wait_for_response(struct ib_mad_send_wr_private *mad_send_wr)
 {
+	struct ib_mad_agent_private *mad_agent_priv;
 	struct ib_mad_send_wr_private *temp_mad_send_wr;
 	struct list_head *list_item;
 	unsigned long delay;
 
+	mad_agent_priv = mad_send_wr->mad_agent_priv;
 	list_del(&mad_send_wr->agent_list);
 
 	delay = mad_send_wr->timeout;
 	mad_send_wr->timeout += jiffies;
 
-	list_for_each_prev(list_item, &mad_agent_priv->wait_list) {
-		temp_mad_send_wr = list_entry(list_item,
-					      struct ib_mad_send_wr_private,
-					      agent_list);
-		if (time_after(mad_send_wr->timeout,
-			       temp_mad_send_wr->timeout))
-			break;
+	if (delay) {
+		list_for_each_prev(list_item, &mad_agent_priv->wait_list) {
+			temp_mad_send_wr = list_entry(list_item,
+						struct ib_mad_send_wr_private,
+						agent_list);
+			if (time_after(mad_send_wr->timeout,
+				       temp_mad_send_wr->timeout))
+				break;
+		}
 	}
+	else
+		list_item = &mad_agent_priv->wait_list;
 	list_add(&mad_send_wr->agent_list, list_item);
 
 	/* Reschedule a work item if we have a shorter timeout */
@@ -1740,19 +1818,32 @@ static void wait_for_response(struct ib_
 	}
 }
 
+void ib_reset_mad_timeout(struct ib_mad_send_wr_private *mad_send_wr,
+			  int timeout_ms)
+{
+	mad_send_wr->timeout = msecs_to_jiffies(timeout_ms);
+	wait_for_response(mad_send_wr);
+}
+
 /*
  * Process a send work completion
  */
-static void ib_mad_complete_send_wr(struct ib_mad_send_wr_private *mad_send_wr,
-				    struct ib_mad_send_wc *mad_send_wc)
+void ib_mad_complete_send_wr(struct ib_mad_send_wr_private *mad_send_wr,
+			     struct ib_mad_send_wc *mad_send_wc)
 {
 	struct ib_mad_agent_private	*mad_agent_priv;
 	unsigned long			flags;
+	int				ret;
 
-	mad_agent_priv = container_of(mad_send_wr->agent,
-				      struct ib_mad_agent_private, agent);
-
+	mad_agent_priv = mad_send_wr->mad_agent_priv;
 	spin_lock_irqsave(&mad_agent_priv->lock, flags);
+	if (mad_agent_priv->agent.rmpp_version) {
+		ret = ib_process_rmpp_send_wc(mad_send_wr, mad_send_wc);
+		if (ret == IB_RMPP_RESULT_CONSUMED)
+			goto done;
+	} else
+		ret = IB_RMPP_RESULT_UNHANDLED;
+
 	if (mad_send_wc->status != IB_WC_SUCCESS &&
 	    mad_send_wr->status == IB_WC_SUCCESS) {
 		mad_send_wr->status = mad_send_wc->status;
@@ -1762,10 +1853,9 @@ static void ib_mad_complete_send_wr(stru
 	if (--mad_send_wr->refcount > 0) {
 		if (mad_send_wr->refcount == 1 && mad_send_wr->timeout &&
 		    mad_send_wr->status == IB_WC_SUCCESS) {
-			wait_for_response(mad_agent_priv, mad_send_wr);
+			wait_for_response(mad_send_wr);
 		}
-		spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
-		return;
+		goto done;
 	}
 
 	/* Remove send from MAD agent and notify client of completion */
@@ -1775,14 +1865,18 @@ static void ib_mad_complete_send_wr(stru
 
 	if (mad_send_wr->status != IB_WC_SUCCESS )
 		mad_send_wc->status = mad_send_wr->status;
-	mad_agent_priv->agent.send_handler(&mad_agent_priv->agent,
-					    mad_send_wc);
+	if (ret != IB_RMPP_RESULT_INTERNAL)
+		mad_agent_priv->agent.send_handler(&mad_agent_priv->agent,
+						   mad_send_wc);
 
 	/* Release reference on agent taken when sending */
 	if (atomic_dec_and_test(&mad_agent_priv->refcount))
 		wake_up(&mad_agent_priv->wait);
 
 	kfree(mad_send_wr);
+	return;
+done:
+	spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
 }
 
 static void ib_mad_send_done_handler(struct ib_mad_port_private *port_priv,
@@ -1961,6 +2055,8 @@ static void cancel_mads(struct ib_mad_ag
 
 	/* Empty wait list to prevent receives from finding a request */
 	list_splice_init(&mad_agent_priv->wait_list, &cancel_list);
+	/* Empty local completion list as well */
+	list_splice_init(&mad_agent_priv->local_list, &cancel_list);
 	spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
 
 	/* Report all cancelled requests */
@@ -1980,8 +2076,7 @@ static void cancel_mads(struct ib_mad_ag
 }
 
 static struct ib_mad_send_wr_private*
-find_send_by_wr_id(struct ib_mad_agent_private *mad_agent_priv,
-		   u64 wr_id)
+find_send_by_wr_id(struct ib_mad_agent_private *mad_agent_priv, u64 wr_id)
 {
 	struct ib_mad_send_wr_private *mad_send_wr;
 
@@ -1993,79 +2088,50 @@ find_send_by_wr_id(struct ib_mad_agent_p
 
 	list_for_each_entry(mad_send_wr, &mad_agent_priv->send_list,
 			    agent_list) {
-		if (mad_send_wr->wr_id == wr_id)
+		if (is_data_mad(mad_agent_priv,
+				mad_send_wr->send_wr.wr.ud.mad_hdr) &&
+		    mad_send_wr->wr_id == wr_id)
 			return mad_send_wr;
 	}
 	return NULL;
 }
 
-void cancel_sends(void *data)
-{
-	struct ib_mad_agent_private *mad_agent_priv;
-	struct ib_mad_send_wr_private *mad_send_wr;
-	struct ib_mad_send_wc mad_send_wc;
-	unsigned long flags;
-
-	mad_agent_priv = data;
-
-	mad_send_wc.status = IB_WC_WR_FLUSH_ERR;
-	mad_send_wc.vendor_err = 0;
-
-	spin_lock_irqsave(&mad_agent_priv->lock, flags);
-	while (!list_empty(&mad_agent_priv->canceled_list)) {
-		mad_send_wr = list_entry(mad_agent_priv->canceled_list.next,
-					 struct ib_mad_send_wr_private,
-					 agent_list);
-
-		list_del(&mad_send_wr->agent_list);
-		spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
-
-		mad_send_wc.wr_id = mad_send_wr->wr_id;
-		mad_agent_priv->agent.send_handler(&mad_agent_priv->agent,
-						   &mad_send_wc);
-
-		kfree(mad_send_wr);
-		if (atomic_dec_and_test(&mad_agent_priv->refcount))
-			wake_up(&mad_agent_priv->wait);
-		spin_lock_irqsave(&mad_agent_priv->lock, flags);
-	}
-	spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
-}
-
-void ib_cancel_mad(struct ib_mad_agent *mad_agent,
-		  u64 wr_id)
+int ib_modify_mad(struct ib_mad_agent *mad_agent, u64 wr_id, u32 timeout_ms)
 {
 	struct ib_mad_agent_private *mad_agent_priv;
 	struct ib_mad_send_wr_private *mad_send_wr;
 	unsigned long flags;
+	int active;
 
 	mad_agent_priv = container_of(mad_agent, struct ib_mad_agent_private,
 				      agent);
 	spin_lock_irqsave(&mad_agent_priv->lock, flags);
 	mad_send_wr = find_send_by_wr_id(mad_agent_priv, wr_id);
-	if (!mad_send_wr) {
+	if (!mad_send_wr || mad_send_wr->status != IB_WC_SUCCESS) {
 		spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
-		goto out;
+		return -EINVAL;
 	}
 
-	if (mad_send_wr->status == IB_WC_SUCCESS)
-		mad_send_wr->refcount -= (mad_send_wr->timeout > 0);
-
-	if (mad_send_wr->refcount != 0) {
+	active = (!mad_send_wr->timeout || mad_send_wr->refcount > 1);
+	if (!timeout_ms) {
 		mad_send_wr->status = IB_WC_WR_FLUSH_ERR;
-		spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
-		goto out;
+		mad_send_wr->refcount -= (mad_send_wr->timeout > 0);
 	}
 
-	list_del(&mad_send_wr->agent_list);
-	list_add_tail(&mad_send_wr->agent_list, &mad_agent_priv->canceled_list);
-	adjust_timeout(mad_agent_priv);
+	mad_send_wr->send_wr.wr.ud.timeout_ms = timeout_ms;
+	if (active)
+		mad_send_wr->timeout = msecs_to_jiffies(timeout_ms);
+	else
+		ib_reset_mad_timeout(mad_send_wr, timeout_ms);
+
 	spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
+	return 0;
+}
+EXPORT_SYMBOL(ib_modify_mad);
 
-	queue_work(mad_agent_priv->qp_info->port_priv->wq,
-		   &mad_agent_priv->canceled_work);
-out:
-	return;
+void ib_cancel_mad(struct ib_mad_agent *mad_agent, u64 wr_id)
+{
+	ib_modify_mad(mad_agent, wr_id, 0);
 }
 EXPORT_SYMBOL(ib_cancel_mad);
 
@@ -2075,6 +2141,7 @@ static void local_completions(void *data
 	struct ib_mad_local_private *local;
 	struct ib_mad_agent_private *recv_mad_agent;
 	unsigned long flags;
+	int recv = 0;
 	struct ib_wc wc;
 	struct ib_mad_send_wc mad_send_wc;
 
@@ -2090,10 +2157,10 @@ static void local_completions(void *data
 			recv_mad_agent = local->recv_mad_agent;
 			if (!recv_mad_agent) {
 				printk(KERN_ERR PFX "No receive MAD agent for local completion\n");
-				kmem_cache_free(ib_mad_cache, local->mad_priv);
 				goto local_send_completion;
 			}
 
+			recv = 1;
 			/*
 			 * Defined behavior is to complete response
 			 * before request
@@ -2105,7 +2172,9 @@ static void local_completions(void *data
 			local->mad_priv->header.recv_wc.wc = &wc;
 			local->mad_priv->header.recv_wc.mad_len =
 						sizeof(struct ib_mad);
-			INIT_LIST_HEAD(&local->mad_priv->header.recv_wc.recv_buf.list);
+			INIT_LIST_HEAD(&local->mad_priv->header.recv_wc.rmpp_list);
+			list_add(&local->mad_priv->header.recv_wc.recv_buf.list,
+				 &local->mad_priv->header.recv_wc.rmpp_list);
 			local->mad_priv->header.recv_wc.recv_buf.grh = NULL;
 			local->mad_priv->header.recv_wc.recv_buf.mad =
 						&local->mad_priv->mad.mad;
@@ -2136,11 +2205,47 @@ local_send_completion:
 		spin_lock_irqsave(&mad_agent_priv->lock, flags);
 		list_del(&local->completion_list);
 		atomic_dec(&mad_agent_priv->refcount);
+		if (!recv)
+			kmem_cache_free(ib_mad_cache, local->mad_priv);
 		kfree(local);
 	}
 	spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
 }
 
+static int retry_send(struct ib_mad_send_wr_private *mad_send_wr)
+{
+	int ret;
+
+	if (!mad_send_wr->retries--)
+		return -ETIMEDOUT;
+
+	mad_send_wr->timeout = msecs_to_jiffies(mad_send_wr->send_wr.
+						wr.ud.timeout_ms);
+
+	if (mad_send_wr->mad_agent_priv->agent.rmpp_version) {
+		ret = ib_retry_rmpp(mad_send_wr);
+		switch (ret) {
+		case IB_RMPP_RESULT_UNHANDLED:
+			ret = ib_send_mad(mad_send_wr);
+			break;
+		case IB_RMPP_RESULT_CONSUMED:
+			ret = 0;
+			break;
+		default:
+			ret = -ECOMM;
+			break;
+		}
+	} else
+		ret = ib_send_mad(mad_send_wr);
+
+	if (!ret) {
+		mad_send_wr->refcount++;
+		list_add_tail(&mad_send_wr->agent_list,
+			      &mad_send_wr->mad_agent_priv->send_list);
+	}
+	return ret;
+}
+
 static void timeout_sends(void *data)
 {
 	struct ib_mad_agent_private *mad_agent_priv;
@@ -2149,8 +2254,6 @@ static void timeout_sends(void *data)
 	unsigned long flags, delay;
 
 	mad_agent_priv = (struct ib_mad_agent_private *)data;
-
-	mad_send_wc.status = IB_WC_RESP_TIMEOUT_ERR;
 	mad_send_wc.vendor_err = 0;
 
 	spin_lock_irqsave(&mad_agent_priv->lock, flags);
@@ -2170,8 +2273,16 @@ static void timeout_sends(void *data)
 		}
 
 		list_del(&mad_send_wr->agent_list);
+		if (mad_send_wr->status == IB_WC_SUCCESS &&
+		    !retry_send(mad_send_wr))
+			continue;
+
 		spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
 
+		if (mad_send_wr->status == IB_WC_SUCCESS)
+			mad_send_wc.status = IB_WC_RESP_TIMEOUT_ERR;
+		else
+			mad_send_wc.status = mad_send_wr->status;
 		mad_send_wc.wr_id = mad_send_wr->wr_id;
 		mad_agent_priv->agent.send_handler(&mad_agent_priv->agent,
 						   &mad_send_wc);
@@ -2447,14 +2558,6 @@ static int ib_mad_port_open(struct ib_de
 	unsigned long flags;
 	char name[sizeof "ib_mad123"];
 
-	/* First, check if port already open at MAD layer */
-	port_priv = ib_get_mad_port(device, port_num);
-	if (port_priv) {
-		printk(KERN_DEBUG PFX "%s port %d already open\n",
-		       device->name, port_num);
-		return 0;
-	}
-
 	/* Create new device info */
 	port_priv = kmalloc(sizeof *port_priv, GFP_KERNEL);
 	if (!port_priv) {
@@ -2579,7 +2682,7 @@ static int ib_mad_port_close(struct ib_d
 
 static void ib_mad_init_device(struct ib_device *device)
 {
-	int ret, num_ports, cur_port, i, ret2;
+	int num_ports, cur_port, i;
 
 	if (device->node_type == IB_NODE_SWITCH) {
 		num_ports = 1;
@@ -2589,47 +2692,37 @@ static void ib_mad_init_device(struct ib
 		cur_port = 1;
 	}
 	for (i = 0; i < num_ports; i++, cur_port++) {
-		ret = ib_mad_port_open(device, cur_port);
-		if (ret) {
+		if (ib_mad_port_open(device, cur_port)) {
 			printk(KERN_ERR PFX "Couldn't open %s port %d\n",
 			       device->name, cur_port);
 			goto error_device_open;
 		}
-		ret = ib_agent_port_open(device, cur_port);
-		if (ret) {
+		if (ib_agent_port_open(device, cur_port)) {
 			printk(KERN_ERR PFX "Couldn't open %s port %d "
 			       "for agents\n",
 			       device->name, cur_port);
 			goto error_device_open;
 		}
 	}
-
-	goto error_device_query;
+	return;
 
 error_device_open:
 	while (i > 0) {
 		cur_port--;
-		ret2 = ib_agent_port_close(device, cur_port);
-		if (ret2) {
+		if (ib_agent_port_close(device, cur_port))
 			printk(KERN_ERR PFX "Couldn't close %s port %d "
 			       "for agents\n",
 			       device->name, cur_port);
-		}
-		ret2 = ib_mad_port_close(device, cur_port);
-		if (ret2) {
+		if (ib_mad_port_close(device, cur_port))
 			printk(KERN_ERR PFX "Couldn't close %s port %d\n",
 			       device->name, cur_port);
-		}
 		i--;
 	}
-
-error_device_query:
-	return;
 }
 
 static void ib_mad_remove_device(struct ib_device *device)
 {
-	int ret = 0, i, num_ports, cur_port, ret2;
+	int i, num_ports, cur_port;
 
 	if (device->node_type == IB_NODE_SWITCH) {
 		num_ports = 1;
@@ -2639,21 +2732,13 @@ static void ib_mad_remove_device(struct 
 		cur_port = 1;
 	}
 	for (i = 0; i < num_ports; i++, cur_port++) {
-		ret2 = ib_agent_port_close(device, cur_port);
-		if (ret2) {
+		if (ib_agent_port_close(device, cur_port))
 			printk(KERN_ERR PFX "Couldn't close %s port %d "
 			       "for agents\n",
 			       device->name, cur_port);
-			if (!ret)
-				ret = ret2;
-		}
-		ret2 = ib_mad_port_close(device, cur_port);
-		if (ret2) {
+		if (ib_mad_port_close(device, cur_port))
 			printk(KERN_ERR PFX "Couldn't close %s port %d\n",
 			       device->name, cur_port);
-			if (!ret)
-				ret = ret2;
-		}
 	}
 }
 
@@ -2709,3 +2794,4 @@ static void __exit ib_mad_cleanup_module
 
 module_init(ib_mad_init_module);
 module_exit(ib_mad_cleanup_module);
+
diff --git a/drivers/infiniband/core/mad_priv.h b/drivers/infiniband/core/mad_priv.h
--- a/drivers/infiniband/core/mad_priv.h
+++ b/drivers/infiniband/core/mad_priv.h
@@ -1,5 +1,7 @@
 /*
  * Copyright (c) 2004, 2005, Voltaire, Inc. All rights reserved.
+ * Copyright (c) 2005 Intel Corporation. All rights reserved.
+ * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
@@ -29,7 +31,7 @@
  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  *
- * $Id: mad_priv.h 1389 2004-12-27 22:56:47Z roland $
+ * $Id: mad_priv.h 2730 2005-06-28 16:43:03Z sean.hefty $
  */
 
 #ifndef __IB_MAD_PRIV_H__
@@ -92,16 +94,15 @@ struct ib_mad_agent_private {
 	spinlock_t lock;
 	struct list_head send_list;
 	struct list_head wait_list;
+	struct list_head done_list;
 	struct work_struct timed_work;
 	unsigned long timeout;
 	struct list_head local_list;
 	struct work_struct local_work;
-	struct list_head canceled_list;
-	struct work_struct canceled_work;
+	struct list_head rmpp_list;
 
 	atomic_t refcount;
 	wait_queue_head_t wait;
-	u8 rmpp_version;
 };
 
 struct ib_mad_snoop_private {
@@ -116,15 +117,24 @@ struct ib_mad_snoop_private {
 struct ib_mad_send_wr_private {
 	struct ib_mad_list_head mad_list;
 	struct list_head agent_list;
-	struct ib_mad_agent *agent;
+	struct ib_mad_agent_private *mad_agent_priv;
 	struct ib_send_wr send_wr;
 	struct ib_sge sg_list[IB_MAD_SEND_REQ_MAX_SG];
 	u64 wr_id;			/* client WR ID */
 	u64 tid;
 	unsigned long timeout;
+	int retries;
 	int retry;
 	int refcount;
 	enum ib_wc_status status;
+
+	/* RMPP control */
+	int last_ack;
+	int seg_num;
+	int newwin;
+	int total_seg;
+	int data_offset;
+	int pad;
 };
 
 struct ib_mad_local_private {
@@ -197,4 +207,17 @@ struct ib_mad_port_private {
 
 extern kmem_cache_t *ib_mad_cache;
 
+int ib_send_mad(struct ib_mad_send_wr_private *mad_send_wr);
+
+struct ib_mad_send_wr_private *
+ib_find_send_mad(struct ib_mad_agent_private *mad_agent_priv, u64 tid);
+
+void ib_mad_complete_send_wr(struct ib_mad_send_wr_private *mad_send_wr,
+			     struct ib_mad_send_wc *mad_send_wc);
+
+void ib_mark_mad_done(struct ib_mad_send_wr_private *mad_send_wr);
+
+void ib_reset_mad_timeout(struct ib_mad_send_wr_private *mad_send_wr,
+			  int timeout_ms);
+
 #endif	/* __IB_MAD_PRIV_H__ */
diff --git a/drivers/infiniband/core/mad_rmpp.c b/drivers/infiniband/core/mad_rmpp.c
new file mode 100644
--- /dev/null
+++ b/drivers/infiniband/core/mad_rmpp.c
@@ -0,0 +1,765 @@
+/*
+ * Copyright (c) 2005 Intel Inc. All rights reserved.
+ * Copyright (c) 2005 Voltaire, Inc. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * 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 THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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.
+ *
+ * $Id: mad_rmpp.c 1921 2005-03-02 22:58:44Z sean.hefty $
+ */
+
+#include <linux/dma-mapping.h>
+
+#include "mad_priv.h"
+#include "mad_rmpp.h"
+
+enum rmpp_state {
+	RMPP_STATE_ACTIVE,
+	RMPP_STATE_TIMEOUT,
+	RMPP_STATE_COMPLETE
+};
+
+struct mad_rmpp_recv {
+	struct ib_mad_agent_private *agent;
+	struct list_head list;
+	struct work_struct timeout_work;
+	struct work_struct cleanup_work;
+	wait_queue_head_t wait;
+	enum rmpp_state state;
+	spinlock_t lock;
+	atomic_t refcount;
+
+	struct ib_ah *ah;
+	struct ib_mad_recv_wc *rmpp_wc;
+	struct ib_mad_recv_buf *cur_seg_buf;
+	int last_ack;
+	int seg_num;
+	int newwin;
+
+	u64 tid;
+	u32 src_qp;
+	u16 slid;
+	u8 mgmt_class;
+	u8 class_version;
+	u8 method;
+};
+
+static void destroy_rmpp_recv(struct mad_rmpp_recv *rmpp_recv)
+{
+	atomic_dec(&rmpp_recv->refcount);
+	wait_event(rmpp_recv->wait, !atomic_read(&rmpp_recv->refcount));
+	ib_destroy_ah(rmpp_recv->ah);
+	kfree(rmpp_recv);
+}
+
+void ib_cancel_rmpp_recvs(struct ib_mad_agent_private *agent)
+{
+	struct mad_rmpp_recv *rmpp_recv, *temp_rmpp_recv;
+	unsigned long flags;
+
+	spin_lock_irqsave(&agent->lock, flags);
+	list_for_each_entry(rmpp_recv, &agent->rmpp_list, list) {
+		cancel_delayed_work(&rmpp_recv->timeout_work);
+		cancel_delayed_work(&rmpp_recv->cleanup_work);
+	}
+	spin_unlock_irqrestore(&agent->lock, flags);
+
+	flush_workqueue(agent->qp_info->port_priv->wq);
+
+	list_for_each_entry_safe(rmpp_recv, temp_rmpp_recv,
+				 &agent->rmpp_list, list) {
+		list_del(&rmpp_recv->list);
+		if (rmpp_recv->state != RMPP_STATE_COMPLETE)
+			ib_free_recv_mad(rmpp_recv->rmpp_wc);
+		destroy_rmpp_recv(rmpp_recv);
+	}
+}
+
+static void recv_timeout_handler(void *data)
+{
+	struct mad_rmpp_recv *rmpp_recv = data;
+	struct ib_mad_recv_wc *rmpp_wc;
+	unsigned long flags;
+
+	spin_lock_irqsave(&rmpp_recv->agent->lock, flags);
+	if (rmpp_recv->state != RMPP_STATE_ACTIVE) {
+		spin_unlock_irqrestore(&rmpp_recv->agent->lock, flags);
+		return;
+	}
+	rmpp_recv->state = RMPP_STATE_TIMEOUT;
+	list_del(&rmpp_recv->list);
+	spin_unlock_irqrestore(&rmpp_recv->agent->lock, flags);
+
+	/* TODO: send abort. */
+	rmpp_wc = rmpp_recv->rmpp_wc;
+	destroy_rmpp_recv(rmpp_recv);
+	ib_free_recv_mad(rmpp_wc);
+}
+
+static void recv_cleanup_handler(void *data)
+{
+	struct mad_rmpp_recv *rmpp_recv = data;
+	unsigned long flags;
+
+	spin_lock_irqsave(&rmpp_recv->agent->lock, flags);
+	list_del(&rmpp_recv->list);
+	spin_unlock_irqrestore(&rmpp_recv->agent->lock, flags);
+	destroy_rmpp_recv(rmpp_recv);
+}
+
+static struct mad_rmpp_recv *
+create_rmpp_recv(struct ib_mad_agent_private *agent,
+		 struct ib_mad_recv_wc *mad_recv_wc)
+{
+	struct mad_rmpp_recv *rmpp_recv;
+	struct ib_mad_hdr *mad_hdr;
+
+	rmpp_recv = kmalloc(sizeof *rmpp_recv, GFP_KERNEL);
+	if (!rmpp_recv)
+		return NULL;
+
+	rmpp_recv->ah = ib_create_ah_from_wc(agent->agent.qp->pd,
+					     mad_recv_wc->wc,
+					     mad_recv_wc->recv_buf.grh,
+					     agent->agent.port_num);
+	if (IS_ERR(rmpp_recv->ah))
+		goto error;
+
+	rmpp_recv->agent = agent;
+	init_waitqueue_head(&rmpp_recv->wait);
+	INIT_WORK(&rmpp_recv->timeout_work, recv_timeout_handler, rmpp_recv);
+	INIT_WORK(&rmpp_recv->cleanup_work, recv_cleanup_handler, rmpp_recv);
+	spin_lock_init(&rmpp_recv->lock);
+	rmpp_recv->state = RMPP_STATE_ACTIVE;
+	atomic_set(&rmpp_recv->refcount, 1);
+
+	rmpp_recv->rmpp_wc = mad_recv_wc;
+	rmpp_recv->cur_seg_buf = &mad_recv_wc->recv_buf;
+	rmpp_recv->newwin = 1;
+	rmpp_recv->seg_num = 1;
+	rmpp_recv->last_ack = 0;
+
+	mad_hdr = &mad_recv_wc->recv_buf.mad->mad_hdr;
+	rmpp_recv->tid = mad_hdr->tid;
+	rmpp_recv->src_qp = mad_recv_wc->wc->src_qp;
+	rmpp_recv->slid = mad_recv_wc->wc->slid;
+	rmpp_recv->mgmt_class = mad_hdr->mgmt_class;
+	rmpp_recv->class_version = mad_hdr->class_version;
+	rmpp_recv->method  = mad_hdr->method;
+	return rmpp_recv;
+
+error:	kfree(rmpp_recv);
+	return NULL;
+}
+
+static inline void deref_rmpp_recv(struct mad_rmpp_recv *rmpp_recv)
+{
+	if (atomic_dec_and_test(&rmpp_recv->refcount))
+		wake_up(&rmpp_recv->wait);
+}
+
+static struct mad_rmpp_recv *
+find_rmpp_recv(struct ib_mad_agent_private *agent,
+	       struct ib_mad_recv_wc *mad_recv_wc)
+{
+	struct mad_rmpp_recv *rmpp_recv;
+	struct ib_mad_hdr *mad_hdr = &mad_recv_wc->recv_buf.mad->mad_hdr;
+
+	list_for_each_entry(rmpp_recv, &agent->rmpp_list, list) {
+		if (rmpp_recv->tid == mad_hdr->tid &&
+		    rmpp_recv->src_qp == mad_recv_wc->wc->src_qp &&
+		    rmpp_recv->slid == mad_recv_wc->wc->slid &&
+		    rmpp_recv->mgmt_class == mad_hdr->mgmt_class &&
+		    rmpp_recv->class_version == mad_hdr->class_version &&
+		    rmpp_recv->method == mad_hdr->method)
+			return rmpp_recv;
+	}
+	return NULL;
+}
+
+static struct mad_rmpp_recv *
+acquire_rmpp_recv(struct ib_mad_agent_private *agent,
+		  struct ib_mad_recv_wc *mad_recv_wc)
+{
+	struct mad_rmpp_recv *rmpp_recv;
+	unsigned long flags;
+
+	spin_lock_irqsave(&agent->lock, flags);
+	rmpp_recv = find_rmpp_recv(agent, mad_recv_wc);
+	if (rmpp_recv)
+		atomic_inc(&rmpp_recv->refcount);
+	spin_unlock_irqrestore(&agent->lock, flags);
+	return rmpp_recv;
+}
+
+static struct mad_rmpp_recv *
+insert_rmpp_recv(struct ib_mad_agent_private *agent,
+		 struct mad_rmpp_recv *rmpp_recv)
+{
+	struct mad_rmpp_recv *cur_rmpp_recv;
+
+	cur_rmpp_recv = find_rmpp_recv(agent, rmpp_recv->rmpp_wc);
+	if (!cur_rmpp_recv)
+		list_add_tail(&rmpp_recv->list, &agent->rmpp_list);
+
+	return cur_rmpp_recv;
+}
+
+static int data_offset(u8 mgmt_class)
+{
+	if (mgmt_class == IB_MGMT_CLASS_SUBN_ADM)
+		return offsetof(struct ib_sa_mad, data);
+	else if ((mgmt_class >= IB_MGMT_CLASS_VENDOR_RANGE2_START) &&
+		 (mgmt_class <= IB_MGMT_CLASS_VENDOR_RANGE2_END))
+		return offsetof(struct ib_vendor_mad, data);
+	else
+		return offsetof(struct ib_rmpp_mad, data);
+}
+
+static void format_ack(struct ib_rmpp_mad *ack,
+		       struct ib_rmpp_mad *data,
+		       struct mad_rmpp_recv *rmpp_recv)
+{
+	unsigned long flags;
+
+	memcpy(&ack->mad_hdr, &data->mad_hdr,
+	       data_offset(data->mad_hdr.mgmt_class));
+
+	ack->mad_hdr.method ^= IB_MGMT_METHOD_RESP;
+	ack->rmpp_hdr.rmpp_type = IB_MGMT_RMPP_TYPE_ACK;
+	ib_set_rmpp_flags(&ack->rmpp_hdr, IB_MGMT_RMPP_FLAG_ACTIVE);
+
+	spin_lock_irqsave(&rmpp_recv->lock, flags);
+	rmpp_recv->last_ack = rmpp_recv->seg_num;
+	ack->rmpp_hdr.seg_num = cpu_to_be32(rmpp_recv->seg_num);
+	ack->rmpp_hdr.paylen_newwin = cpu_to_be32(rmpp_recv->newwin);
+	spin_unlock_irqrestore(&rmpp_recv->lock, flags);
+}
+
+static void ack_recv(struct mad_rmpp_recv *rmpp_recv,
+		     struct ib_mad_recv_wc *recv_wc)
+{
+	struct ib_mad_send_buf *msg;
+	struct ib_send_wr *bad_send_wr;
+	int hdr_len, ret;
+
+	hdr_len = sizeof(struct ib_mad_hdr) + sizeof(struct ib_rmpp_hdr);
+	msg = ib_create_send_mad(&rmpp_recv->agent->agent, recv_wc->wc->src_qp,
+				 recv_wc->wc->pkey_index, rmpp_recv->ah, 1,
+				 hdr_len, sizeof(struct ib_rmpp_mad) - hdr_len,
+				 GFP_KERNEL);
+	if (!msg)
+		return;
+
+	format_ack((struct ib_rmpp_mad *) msg->mad,
+		   (struct ib_rmpp_mad *) recv_wc->recv_buf.mad, rmpp_recv);
+	ret = ib_post_send_mad(&rmpp_recv->agent->agent, &msg->send_wr,
+			       &bad_send_wr);
+	if (ret)
+		ib_free_send_mad(msg);
+}
+
+static inline int get_last_flag(struct ib_mad_recv_buf *seg)
+{
+	struct ib_rmpp_mad *rmpp_mad;
+
+	rmpp_mad = (struct ib_rmpp_mad *) seg->mad;
+	return ib_get_rmpp_flags(&rmpp_mad->rmpp_hdr) & IB_MGMT_RMPP_FLAG_LAST;
+}
+
+static inline int get_seg_num(struct ib_mad_recv_buf *seg)
+{
+	struct ib_rmpp_mad *rmpp_mad;
+
+	rmpp_mad = (struct ib_rmpp_mad *) seg->mad;
+	return be32_to_cpu(rmpp_mad->rmpp_hdr.seg_num);
+}
+
+static inline struct ib_mad_recv_buf * get_next_seg(struct list_head *rmpp_list,
+						    struct ib_mad_recv_buf *seg)
+{
+	if (seg->list.next == rmpp_list)
+		return NULL;
+
+	return container_of(seg->list.next, struct ib_mad_recv_buf, list);
+}
+
+static inline int window_size(struct ib_mad_agent_private *agent)
+{
+	return max(agent->qp_info->recv_queue.max_active >> 3, 1);
+}
+
+static struct ib_mad_recv_buf * find_seg_location(struct list_head *rmpp_list,
+						  int seg_num)
+{
+        struct ib_mad_recv_buf *seg_buf;
+	int cur_seg_num;
+
+	list_for_each_entry_reverse(seg_buf, rmpp_list, list) {
+		cur_seg_num = get_seg_num(seg_buf);
+		if (seg_num > cur_seg_num)
+			return seg_buf;
+		if (seg_num == cur_seg_num)
+			break;
+	}
+	return NULL;
+}
+
+static void update_seg_num(struct mad_rmpp_recv *rmpp_recv,
+			   struct ib_mad_recv_buf *new_buf)
+{
+	struct list_head *rmpp_list = &rmpp_recv->rmpp_wc->rmpp_list;
+
+	while (new_buf && (get_seg_num(new_buf) == rmpp_recv->seg_num + 1)) {
+		rmpp_recv->cur_seg_buf = new_buf;
+		rmpp_recv->seg_num++;
+		new_buf = get_next_seg(rmpp_list, new_buf);
+	}
+}
+
+static inline int get_mad_len(struct mad_rmpp_recv *rmpp_recv)
+{
+	struct ib_rmpp_mad *rmpp_mad;
+	int hdr_size, data_size, pad;
+
+	rmpp_mad = (struct ib_rmpp_mad *)rmpp_recv->cur_seg_buf->mad;
+
+	hdr_size = data_offset(rmpp_mad->mad_hdr.mgmt_class);
+	data_size = sizeof(struct ib_rmpp_mad) - hdr_size;
+	pad = data_size - be32_to_cpu(rmpp_mad->rmpp_hdr.paylen_newwin);
+	if (pad > data_size || pad < 0)
+		pad = 0;
+
+	return hdr_size + rmpp_recv->seg_num * data_size - pad;
+}
+
+static struct ib_mad_recv_wc * complete_rmpp(struct mad_rmpp_recv *rmpp_recv)
+{
+	struct ib_mad_recv_wc *rmpp_wc;
+
+	ack_recv(rmpp_recv, rmpp_recv->rmpp_wc);
+	if (rmpp_recv->seg_num > 1)
+		cancel_delayed_work(&rmpp_recv->timeout_work);
+
+	rmpp_wc = rmpp_recv->rmpp_wc;
+	rmpp_wc->mad_len = get_mad_len(rmpp_recv);
+	/* 10 seconds until we can find the packet lifetime */
+	queue_delayed_work(rmpp_recv->agent->qp_info->port_priv->wq,
+			   &rmpp_recv->cleanup_work, msecs_to_jiffies(10000));
+	return rmpp_wc;
+}
+
+void ib_coalesce_recv_mad(struct ib_mad_recv_wc *mad_recv_wc, void *buf)
+{
+	struct ib_mad_recv_buf *seg_buf;
+	struct ib_rmpp_mad *rmpp_mad;
+	void *data;
+	int size, len, offset;
+	u8 flags;
+
+	len = mad_recv_wc->mad_len;
+	if (len <= sizeof(struct ib_mad)) {
+		memcpy(buf, mad_recv_wc->recv_buf.mad, len);
+		return;
+	}
+
+	offset = data_offset(mad_recv_wc->recv_buf.mad->mad_hdr.mgmt_class);
+
+	list_for_each_entry(seg_buf, &mad_recv_wc->rmpp_list, list) {
+		rmpp_mad = (struct ib_rmpp_mad *)seg_buf->mad;
+		flags = ib_get_rmpp_flags(&rmpp_mad->rmpp_hdr);
+
+		if (flags & IB_MGMT_RMPP_FLAG_FIRST) {
+			data = rmpp_mad;
+			size = sizeof(*rmpp_mad);
+		} else {
+			data = (void *) rmpp_mad + offset;
+			if (flags & IB_MGMT_RMPP_FLAG_LAST)
+				size = len;
+			else
+				size = sizeof(*rmpp_mad) - offset;
+		}
+
+		memcpy(buf, data, size);
+		len -= size;
+		buf += size;
+	}
+}
+EXPORT_SYMBOL(ib_coalesce_recv_mad);
+
+static struct ib_mad_recv_wc *
+continue_rmpp(struct ib_mad_agent_private *agent,
+	      struct ib_mad_recv_wc *mad_recv_wc)
+{
+	struct mad_rmpp_recv *rmpp_recv;
+	struct ib_mad_recv_buf *prev_buf;
+	struct ib_mad_recv_wc *done_wc;
+	int seg_num;
+	unsigned long flags;
+
+	rmpp_recv = acquire_rmpp_recv(agent, mad_recv_wc);
+	if (!rmpp_recv)
+		goto drop1;
+
+	seg_num = get_seg_num(&mad_recv_wc->recv_buf);
+
+	spin_lock_irqsave(&rmpp_recv->lock, flags);
+	if ((rmpp_recv->state == RMPP_STATE_TIMEOUT) ||
+	    (seg_num > rmpp_recv->newwin))
+		goto drop3;
+
+	if ((seg_num <= rmpp_recv->last_ack) ||
+	    (rmpp_recv->state == RMPP_STATE_COMPLETE)) {
+		spin_unlock_irqrestore(&rmpp_recv->lock, flags);
+		ack_recv(rmpp_recv, mad_recv_wc);
+		goto drop2;
+	}
+
+	prev_buf = find_seg_location(&rmpp_recv->rmpp_wc->rmpp_list, seg_num);
+	if (!prev_buf)
+		goto drop3;
+
+	done_wc = NULL;
+	list_add(&mad_recv_wc->recv_buf.list, &prev_buf->list);
+	if (rmpp_recv->cur_seg_buf == prev_buf) {
+		update_seg_num(rmpp_recv, &mad_recv_wc->recv_buf);
+		if (get_last_flag(rmpp_recv->cur_seg_buf)) {
+			rmpp_recv->state = RMPP_STATE_COMPLETE;
+			spin_unlock_irqrestore(&rmpp_recv->lock, flags);
+			done_wc = complete_rmpp(rmpp_recv);
+			goto out;
+		} else if (rmpp_recv->seg_num == rmpp_recv->newwin) {
+			rmpp_recv->newwin += window_size(agent);
+			spin_unlock_irqrestore(&rmpp_recv->lock, flags);
+			ack_recv(rmpp_recv, mad_recv_wc);
+			goto out;
+		}
+	}
+	spin_unlock_irqrestore(&rmpp_recv->lock, flags);
+out:
+	deref_rmpp_recv(rmpp_recv);
+	return done_wc;
+
+drop3:	spin_unlock_irqrestore(&rmpp_recv->lock, flags);
+drop2:	deref_rmpp_recv(rmpp_recv);
+drop1:	ib_free_recv_mad(mad_recv_wc);
+	return NULL;
+}
+
+static struct ib_mad_recv_wc *
+start_rmpp(struct ib_mad_agent_private *agent,
+	   struct ib_mad_recv_wc *mad_recv_wc)
+{
+	struct mad_rmpp_recv *rmpp_recv;
+	unsigned long flags;
+
+	rmpp_recv = create_rmpp_recv(agent, mad_recv_wc);
+	if (!rmpp_recv) {
+		ib_free_recv_mad(mad_recv_wc);
+		return NULL;
+	}
+
+	spin_lock_irqsave(&agent->lock, flags);
+	if (insert_rmpp_recv(agent, rmpp_recv)) {
+		spin_unlock_irqrestore(&agent->lock, flags);
+		/* duplicate first MAD */
+		destroy_rmpp_recv(rmpp_recv);
+		return continue_rmpp(agent, mad_recv_wc);
+	}
+	atomic_inc(&rmpp_recv->refcount);
+
+	if (get_last_flag(&mad_recv_wc->recv_buf)) {
+		rmpp_recv->state = RMPP_STATE_COMPLETE;
+		spin_unlock_irqrestore(&agent->lock, flags);
+		complete_rmpp(rmpp_recv);
+	} else {
+		spin_unlock_irqrestore(&agent->lock, flags);
+		/* 40 seconds until we can find the packet lifetimes */
+		queue_delayed_work(agent->qp_info->port_priv->wq,
+				   &rmpp_recv->timeout_work,
+				   msecs_to_jiffies(40000));
+		rmpp_recv->newwin += window_size(agent);
+		ack_recv(rmpp_recv, mad_recv_wc);
+		mad_recv_wc = NULL;
+	}
+	deref_rmpp_recv(rmpp_recv);
+	return mad_recv_wc;
+}
+
+static inline u64 get_seg_addr(struct ib_mad_send_wr_private *mad_send_wr)
+{
+	return mad_send_wr->sg_list[0].addr + mad_send_wr->data_offset +
+	       (sizeof(struct ib_rmpp_mad) - mad_send_wr->data_offset) *
+	       (mad_send_wr->seg_num - 1);
+}
+
+static int send_next_seg(struct ib_mad_send_wr_private *mad_send_wr)
+{
+	struct ib_rmpp_mad *rmpp_mad;
+	int timeout;
+
+	rmpp_mad = (struct ib_rmpp_mad *)mad_send_wr->send_wr.wr.ud.mad_hdr;
+	ib_set_rmpp_flags(&rmpp_mad->rmpp_hdr, IB_MGMT_RMPP_FLAG_ACTIVE);
+	rmpp_mad->rmpp_hdr.seg_num = cpu_to_be32(mad_send_wr->seg_num);
+
+	if (mad_send_wr->seg_num == 1) {
+		rmpp_mad->rmpp_hdr.rmpp_rtime_flags |= IB_MGMT_RMPP_FLAG_FIRST;
+		rmpp_mad->rmpp_hdr.paylen_newwin =
+			cpu_to_be32(mad_send_wr->total_seg *
+				    (sizeof(struct ib_rmpp_mad) -
+				       offsetof(struct ib_rmpp_mad, data)));
+		mad_send_wr->sg_list[0].length = sizeof(struct ib_rmpp_mad);
+	} else {
+		mad_send_wr->send_wr.num_sge = 2;
+		mad_send_wr->sg_list[0].length = mad_send_wr->data_offset;
+		mad_send_wr->sg_list[1].addr = get_seg_addr(mad_send_wr);
+		mad_send_wr->sg_list[1].length = sizeof(struct ib_rmpp_mad) -
+						 mad_send_wr->data_offset;
+		mad_send_wr->sg_list[1].lkey = mad_send_wr->sg_list[0].lkey;
+	}
+
+	if (mad_send_wr->seg_num == mad_send_wr->total_seg) {
+		rmpp_mad->rmpp_hdr.rmpp_rtime_flags |= IB_MGMT_RMPP_FLAG_LAST;
+		rmpp_mad->rmpp_hdr.paylen_newwin =
+			cpu_to_be32(sizeof(struct ib_rmpp_mad) -
+				    offsetof(struct ib_rmpp_mad, data) -
+				    mad_send_wr->pad);
+	}
+
+	/* 2 seconds for an ACK until we can find the packet lifetime */
+	timeout = mad_send_wr->send_wr.wr.ud.timeout_ms;
+	if (!timeout || timeout > 2000)
+		mad_send_wr->timeout = msecs_to_jiffies(2000);
+	mad_send_wr->seg_num++;
+	return ib_send_mad(mad_send_wr);
+}
+
+static void process_rmpp_ack(struct ib_mad_agent_private *agent,
+			     struct ib_mad_recv_wc *mad_recv_wc)
+{
+	struct ib_mad_send_wr_private *mad_send_wr;
+	struct ib_rmpp_mad *rmpp_mad;
+	unsigned long flags;
+	int seg_num, newwin, ret;
+
+	rmpp_mad = (struct ib_rmpp_mad *)mad_recv_wc->recv_buf.mad;
+	if (rmpp_mad->rmpp_hdr.rmpp_status)
+		return;
+
+	seg_num = be32_to_cpu(rmpp_mad->rmpp_hdr.seg_num);
+	newwin = be32_to_cpu(rmpp_mad->rmpp_hdr.paylen_newwin);
+
+	spin_lock_irqsave(&agent->lock, flags);
+	mad_send_wr = ib_find_send_mad(agent, rmpp_mad->mad_hdr.tid);
+	if (!mad_send_wr)
+		goto out;	/* Unmatched ACK */
+
+	if ((mad_send_wr->last_ack == mad_send_wr->total_seg) ||
+	    (!mad_send_wr->timeout) || (mad_send_wr->status != IB_WC_SUCCESS))
+		goto out;	/* Send is already done */
+
+	if (seg_num > mad_send_wr->total_seg)
+		goto out;	/* Bad ACK */
+
+	if (newwin < mad_send_wr->newwin || seg_num < mad_send_wr->last_ack)
+		goto out;	/* Old ACK */
+
+	if (seg_num > mad_send_wr->last_ack) {
+		mad_send_wr->last_ack = seg_num;
+		mad_send_wr->retries = mad_send_wr->send_wr.wr.ud.retries;
+	}
+	mad_send_wr->newwin = newwin;
+	if (mad_send_wr->last_ack == mad_send_wr->total_seg) {
+		/* If no response is expected, the ACK completes the send */
+		if (!mad_send_wr->send_wr.wr.ud.timeout_ms) {
+			struct ib_mad_send_wc wc;
+
+			ib_mark_mad_done(mad_send_wr);
+			spin_unlock_irqrestore(&agent->lock, flags);
+
+			wc.status = IB_WC_SUCCESS;
+			wc.vendor_err = 0;
+			wc.wr_id = mad_send_wr->wr_id;
+			ib_mad_complete_send_wr(mad_send_wr, &wc);
+			return;
+		}
+		if (mad_send_wr->refcount == 1)
+			ib_reset_mad_timeout(mad_send_wr, mad_send_wr->
+					     send_wr.wr.ud.timeout_ms);
+	} else if (mad_send_wr->refcount == 1 &&
+		   mad_send_wr->seg_num < mad_send_wr->newwin &&
+		   mad_send_wr->seg_num <= mad_send_wr->total_seg) {
+		/* Send failure will just result in a timeout/retry */
+		ret = send_next_seg(mad_send_wr);
+		if (ret)
+			goto out;
+
+		mad_send_wr->refcount++;
+		list_del(&mad_send_wr->agent_list);
+		list_add_tail(&mad_send_wr->agent_list,
+			      &mad_send_wr->mad_agent_priv->send_list);
+	}
+out:
+	spin_unlock_irqrestore(&agent->lock, flags);
+}
+
+struct ib_mad_recv_wc *
+ib_process_rmpp_recv_wc(struct ib_mad_agent_private *agent,
+			struct ib_mad_recv_wc *mad_recv_wc)
+{
+	struct ib_rmpp_mad *rmpp_mad;
+
+	rmpp_mad = (struct ib_rmpp_mad *)mad_recv_wc->recv_buf.mad;
+	if (!(rmpp_mad->rmpp_hdr.rmpp_rtime_flags & IB_MGMT_RMPP_FLAG_ACTIVE))
+		return mad_recv_wc;
+
+	if (rmpp_mad->rmpp_hdr.rmpp_version != IB_MGMT_RMPP_VERSION)
+		goto out;
+
+	switch (rmpp_mad->rmpp_hdr.rmpp_type) {
+	case IB_MGMT_RMPP_TYPE_DATA:
+		if (rmpp_mad->rmpp_hdr.seg_num == __constant_htonl(1))
+			return start_rmpp(agent, mad_recv_wc);
+		else
+			return continue_rmpp(agent, mad_recv_wc);
+	case IB_MGMT_RMPP_TYPE_ACK:
+		process_rmpp_ack(agent, mad_recv_wc);
+		break;
+	case IB_MGMT_RMPP_TYPE_STOP:
+	case IB_MGMT_RMPP_TYPE_ABORT:
+		/* TODO: process_rmpp_nack(agent, mad_recv_wc); */
+		break;
+	default:
+		break;
+	}
+out:
+	ib_free_recv_mad(mad_recv_wc);
+	return NULL;
+}
+
+int ib_send_rmpp_mad(struct ib_mad_send_wr_private *mad_send_wr)
+{
+	struct ib_rmpp_mad *rmpp_mad;
+	int i, total_len, ret;
+
+	rmpp_mad = (struct ib_rmpp_mad *)mad_send_wr->send_wr.wr.ud.mad_hdr;
+	if (!(ib_get_rmpp_flags(&rmpp_mad->rmpp_hdr) &
+	      IB_MGMT_RMPP_FLAG_ACTIVE))
+		return IB_RMPP_RESULT_UNHANDLED;
+
+	if (rmpp_mad->rmpp_hdr.rmpp_type != IB_MGMT_RMPP_TYPE_DATA)
+		return IB_RMPP_RESULT_INTERNAL;
+
+	if (mad_send_wr->send_wr.num_sge > 1)
+		return -EINVAL;		/* TODO: support num_sge > 1 */
+
+	mad_send_wr->seg_num = 1;
+	mad_send_wr->newwin = 1;
+	mad_send_wr->data_offset = data_offset(rmpp_mad->mad_hdr.mgmt_class);
+
+	total_len = 0;
+	for (i = 0; i < mad_send_wr->send_wr.num_sge; i++)
+		total_len += mad_send_wr->send_wr.sg_list[i].length;
+
+        mad_send_wr->total_seg = (total_len - mad_send_wr->data_offset) /
+			(sizeof(struct ib_rmpp_mad) - mad_send_wr->data_offset);
+	mad_send_wr->pad = total_len - offsetof(struct ib_rmpp_mad, data) -
+			   be32_to_cpu(rmpp_mad->rmpp_hdr.paylen_newwin);
+
+	/* We need to wait for the final ACK even if there isn't a response */
+	mad_send_wr->refcount += (mad_send_wr->timeout == 0);
+	ret = send_next_seg(mad_send_wr);
+	if (!ret)
+		return IB_RMPP_RESULT_CONSUMED;
+	return ret;
+}
+
+int ib_process_rmpp_send_wc(struct ib_mad_send_wr_private *mad_send_wr,
+			    struct ib_mad_send_wc *mad_send_wc)
+{
+	struct ib_rmpp_mad *rmpp_mad;
+	struct ib_mad_send_buf *msg;
+	int ret;
+
+	rmpp_mad = (struct ib_rmpp_mad *)mad_send_wr->send_wr.wr.ud.mad_hdr;
+	if (!(ib_get_rmpp_flags(&rmpp_mad->rmpp_hdr) &
+	      IB_MGMT_RMPP_FLAG_ACTIVE))
+		return IB_RMPP_RESULT_UNHANDLED; /* RMPP not active */
+
+	if (rmpp_mad->rmpp_hdr.rmpp_type != IB_MGMT_RMPP_TYPE_DATA) {
+		msg = (struct ib_mad_send_buf *) (unsigned long)
+		      mad_send_wc->wr_id;
+		ib_free_send_mad(msg);
+		return IB_RMPP_RESULT_INTERNAL;	 /* ACK, STOP, or ABORT */
+	}
+
+	if (mad_send_wc->status != IB_WC_SUCCESS ||
+	    mad_send_wr->status != IB_WC_SUCCESS)
+		return IB_RMPP_RESULT_PROCESSED; /* Canceled or send error */
+
+	if (!mad_send_wr->timeout)
+		return IB_RMPP_RESULT_PROCESSED; /* Response received */
+
+	if (mad_send_wr->last_ack == mad_send_wr->total_seg) {
+		mad_send_wr->timeout =
+			msecs_to_jiffies(mad_send_wr->send_wr.wr.ud.timeout_ms);
+		return IB_RMPP_RESULT_PROCESSED; /* Send done */
+	}
+
+	if (mad_send_wr->seg_num > mad_send_wr->newwin ||
+	    mad_send_wr->seg_num > mad_send_wr->total_seg)
+		return IB_RMPP_RESULT_PROCESSED; /* Wait for ACK */
+
+	ret = send_next_seg(mad_send_wr);
+	if (ret) {
+		mad_send_wc->status = IB_WC_GENERAL_ERR;
+		return IB_RMPP_RESULT_PROCESSED;
+	}
+	return IB_RMPP_RESULT_CONSUMED;
+}
+
+int ib_retry_rmpp(struct ib_mad_send_wr_private *mad_send_wr)
+{
+	struct ib_rmpp_mad *rmpp_mad;
+	int ret;
+
+	rmpp_mad = (struct ib_rmpp_mad *)mad_send_wr->send_wr.wr.ud.mad_hdr;
+	if (!(ib_get_rmpp_flags(&rmpp_mad->rmpp_hdr) &
+	      IB_MGMT_RMPP_FLAG_ACTIVE))
+		return IB_RMPP_RESULT_UNHANDLED; /* RMPP not active */
+
+	if (mad_send_wr->last_ack == mad_send_wr->total_seg)
+		return IB_RMPP_RESULT_PROCESSED;
+
+	mad_send_wr->seg_num = mad_send_wr->last_ack + 1;
+	ret = send_next_seg(mad_send_wr);
+	if (ret)
+		return IB_RMPP_RESULT_PROCESSED;
+
+	return IB_RMPP_RESULT_CONSUMED;
+}
diff --git a/drivers/infiniband/core/mad_rmpp.h b/drivers/infiniband/core/mad_rmpp.h
new file mode 100644
--- /dev/null
+++ b/drivers/infiniband/core/mad_rmpp.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2005 Intel Inc. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * 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 THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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.
+ *
+ * $Id: mad_rmpp.h 1921 2005-02-25 22:58:44Z sean.hefty $
+ */
+
+#ifndef __MAD_RMPP_H__
+#define __MAD_RMPP_H__
+
+enum {
+	IB_RMPP_RESULT_PROCESSED,
+	IB_RMPP_RESULT_CONSUMED,
+	IB_RMPP_RESULT_INTERNAL,
+	IB_RMPP_RESULT_UNHANDLED
+};
+
+int ib_send_rmpp_mad(struct ib_mad_send_wr_private *mad_send_wr);
+
+struct ib_mad_recv_wc *
+ib_process_rmpp_recv_wc(struct ib_mad_agent_private *agent,
+			struct ib_mad_recv_wc *mad_recv_wc);
+
+int ib_process_rmpp_send_wc(struct ib_mad_send_wr_private *mad_send_wr,
+			    struct ib_mad_send_wc *mad_send_wc);
+
+void ib_cancel_rmpp_recvs(struct ib_mad_agent_private *agent);
+
+int ib_retry_rmpp(struct ib_mad_send_wr_private *mad_send_wr);
+
+#endif	/* __MAD_RMPP_H__ */
diff --git a/drivers/infiniband/core/packer.c b/drivers/infiniband/core/packer.c
--- a/drivers/infiniband/core/packer.c
+++ b/drivers/infiniband/core/packer.c
@@ -96,7 +96,7 @@ void ib_pack(const struct ib_field      
 			else
 				val = 0;
 
-			mask = cpu_to_be64(((1ull << desc[i].size_bits) - 1) << shift);
+			mask = cpu_to_be64((~0ull >> (64 - desc[i].size_bits)) << shift);
 			addr = (__be64 *) ((__be32 *) buf + desc[i].offset_words);
 			*addr = (*addr & ~mask) | (cpu_to_be64(val) & mask);
 		} else {
@@ -176,7 +176,7 @@ void ib_unpack(const struct ib_field    
 			__be64 *addr;
 
 			shift = 64 - desc[i].offset_bits - desc[i].size_bits;
-			mask = ((1ull << desc[i].size_bits) - 1) << shift;
+			mask = (~0ull >> (64 - desc[i].size_bits)) << shift;
 			addr = (__be64 *) buf + desc[i].offset_words;
 			val = (be64_to_cpup(addr) & mask) >> shift;
 			value_write(desc[i].struct_offset_bytes,
diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c
--- a/drivers/infiniband/core/sa_query.c
+++ b/drivers/infiniband/core/sa_query.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2004 Topspin Communications.  All rights reserved.
+ * Copyright (c) 2005 Voltaire, Inc.  All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
@@ -29,7 +30,7 @@
  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  *
- * $Id: sa_query.c 1389 2004-12-27 22:56:47Z roland $
+ * $Id: sa_query.c 2811 2005-07-06 18:11:43Z halr $
  */
 
 #include <linux/module.h>
@@ -50,26 +51,6 @@ MODULE_AUTHOR("Roland Dreier");
 MODULE_DESCRIPTION("InfiniBand subnet administration query support");
 MODULE_LICENSE("Dual BSD/GPL");
 
-/*
- * These two structures must be packed because they have 64-bit fields
- * that are only 32-bit aligned.  64-bit architectures will lay them
- * out wrong otherwise.  (And unfortunately they are sent on the wire
- * so we can't change the layout)
- */
-struct ib_sa_hdr {
-	u64			sm_key;
-	u16			attr_offset;
-	u16			reserved;
-	ib_sa_comp_mask		comp_mask;
-} __attribute__ ((packed));
-
-struct ib_sa_mad {
-	struct ib_mad_hdr	mad_hdr;
-	struct ib_rmpp_hdr	rmpp_hdr;
-	struct ib_sa_hdr	sa_hdr;
-	u8			data[200];
-} __attribute__ ((packed));
-
 struct ib_sa_sm_ah {
 	struct ib_ah        *ah;
 	struct kref          ref;
@@ -77,7 +58,6 @@ struct ib_sa_sm_ah {
 
 struct ib_sa_port {
 	struct ib_mad_agent *agent;
-	struct ib_mr        *mr;
 	struct ib_sa_sm_ah  *sm_ah;
 	struct work_struct   update_task;
 	spinlock_t           ah_lock;
@@ -100,6 +80,12 @@ struct ib_sa_query {
 	int                 id;
 };
 
+struct ib_sa_service_query {
+	void (*callback)(int, struct ib_sa_service_rec *, void *);
+	void *context;
+	struct ib_sa_query sa_query;
+};
+
 struct ib_sa_path_query {
 	void (*callback)(int, struct ib_sa_path_rec *, void *);
 	void *context;
@@ -341,6 +327,54 @@ static const struct ib_field mcmember_re
 	  .size_bits    = 23 },
 };
 
+#define SERVICE_REC_FIELD(field) \
+	.struct_offset_bytes = offsetof(struct ib_sa_service_rec, field),	\
+	.struct_size_bytes   = sizeof ((struct ib_sa_service_rec *) 0)->field,	\
+	.field_name          = "sa_service_rec:" #field
+
+static const struct ib_field service_rec_table[] = {
+	{ SERVICE_REC_FIELD(id),
+	  .offset_words = 0,
+	  .offset_bits  = 0,
+	  .size_bits    = 64 },
+	{ SERVICE_REC_FIELD(gid),
+	  .offset_words = 2,
+	  .offset_bits  = 0,
+	  .size_bits    = 128 },
+	{ SERVICE_REC_FIELD(pkey),
+	  .offset_words = 6,
+	  .offset_bits  = 0,
+	  .size_bits    = 16 },
+	{ SERVICE_REC_FIELD(lease),
+	  .offset_words = 7,
+	  .offset_bits  = 0,
+	  .size_bits    = 32 },
+	{ SERVICE_REC_FIELD(key),
+	  .offset_words = 8,
+	  .offset_bits  = 0,
+	  .size_bits    = 128 },
+	{ SERVICE_REC_FIELD(name),
+	  .offset_words = 12,
+	  .offset_bits  = 0,
+	  .size_bits    = 64*8 },
+	{ SERVICE_REC_FIELD(data8),
+	  .offset_words = 28,
+	  .offset_bits  = 0,
+	  .size_bits    = 16*8 },
+	{ SERVICE_REC_FIELD(data16),
+	  .offset_words = 32,
+	  .offset_bits  = 0,
+	  .size_bits    = 8*16 },
+	{ SERVICE_REC_FIELD(data32),
+	  .offset_words = 36,
+	  .offset_bits  = 0,
+	  .size_bits    = 4*32 },
+	{ SERVICE_REC_FIELD(data64),
+	  .offset_words = 40,
+	  .offset_bits  = 0,
+	  .size_bits    = 2*64 },
+};
+
 static void free_sm_ah(struct kref *kref)
 {
 	struct ib_sa_sm_ah *sm_ah = container_of(kref, struct ib_sa_sm_ah, ref);
@@ -463,7 +497,7 @@ static int send_mad(struct ib_sa_query *
 				 .mad_hdr     = &query->mad->mad_hdr,
 				 .remote_qpn  = 1,
 				 .remote_qkey = IB_QP1_QKEY,
-				 .timeout_ms  = timeout_ms
+				 .timeout_ms  = timeout_ms,
 			 }
 		 }
 	};
@@ -492,7 +526,7 @@ retry:
 					    sizeof (struct ib_sa_mad),
 					    DMA_TO_DEVICE);
 	gather_list.length = sizeof (struct ib_sa_mad);
-	gather_list.lkey   = port->mr->lkey;
+	gather_list.lkey   = port->agent->mr->lkey;
 	pci_unmap_addr_set(query, mapping, gather_list.addr);
 
 	ret = ib_post_send_mad(port->agent, &wr, &bad_wr);
@@ -507,7 +541,13 @@ retry:
 		spin_unlock_irqrestore(&idr_lock, flags);
 	}
 
-	return ret;
+	/*
+	 * It's not safe to dereference query any more, because the
+	 * send may already have completed and freed the query in
+	 * another context.  So use wr.wr_id, which has a copy of the
+	 * query's id.
+	 */
+	return ret ? ret : wr.wr_id;
 }
 
 static void ib_sa_path_rec_callback(struct ib_sa_query *sa_query,
@@ -560,7 +600,7 @@ static void ib_sa_path_rec_release(struc
 int ib_sa_path_rec_get(struct ib_device *device, u8 port_num,
 		       struct ib_sa_path_rec *rec,
 		       ib_sa_comp_mask comp_mask,
-		       int timeout_ms, int gfp_mask,
+		       int timeout_ms, unsigned int __nocast gfp_mask,
 		       void (*callback)(int status,
 					struct ib_sa_path_rec *resp,
 					void *context),
@@ -598,17 +638,126 @@ int ib_sa_path_rec_get(struct ib_device 
 		rec, query->sa_query.mad->data);
 
 	*sa_query = &query->sa_query;
+
 	ret = send_mad(&query->sa_query, timeout_ms);
-	if (ret) {
+	if (ret < 0) {
 		*sa_query = NULL;
 		kfree(query->sa_query.mad);
 		kfree(query);
 	}
 
-	return ret ? ret : query->sa_query.id;
+	return ret;
 }
 EXPORT_SYMBOL(ib_sa_path_rec_get);
 
+static void ib_sa_service_rec_callback(struct ib_sa_query *sa_query,
+				    int status,
+				    struct ib_sa_mad *mad)
+{
+	struct ib_sa_service_query *query =
+		container_of(sa_query, struct ib_sa_service_query, sa_query);
+
+	if (mad) {
+		struct ib_sa_service_rec rec;
+
+		ib_unpack(service_rec_table, ARRAY_SIZE(service_rec_table),
+			  mad->data, &rec);
+		query->callback(status, &rec, query->context);
+	} else
+		query->callback(status, NULL, query->context);
+}
+
+static void ib_sa_service_rec_release(struct ib_sa_query *sa_query)
+{
+	kfree(sa_query->mad);
+	kfree(container_of(sa_query, struct ib_sa_service_query, sa_query));
+}
+
+/**
+ * ib_sa_service_rec_query - Start Service Record operation
+ * @device:device to send request on
+ * @port_num: port number to send request on
+ * @method:SA method - should be get, set, or delete
+ * @rec:Service Record to send in request
+ * @comp_mask:component mask to send in request
+ * @timeout_ms:time to wait for response
+ * @gfp_mask:GFP mask to use for internal allocations
+ * @callback:function called when request completes, times out or is
+ * canceled
+ * @context:opaque user context passed to callback
+ * @sa_query:request context, used to cancel request
+ *
+ * Send a Service Record set/get/delete to the SA to register,
+ * unregister or query a service record.
+ * The callback function will be called when the request completes (or
+ * fails); status is 0 for a successful response, -EINTR if the query
+ * is canceled, -ETIMEDOUT is the query timed out, or -EIO if an error
+ * occurred sending the query.  The resp parameter of the callback is
+ * only valid if status is 0.
+ *
+ * If the return value of ib_sa_service_rec_query() is negative, it is an
+ * error code.  Otherwise it is a request ID that can be used to cancel
+ * the query.
+ */
+int ib_sa_service_rec_query(struct ib_device *device, u8 port_num, u8 method,
+			    struct ib_sa_service_rec *rec,
+			    ib_sa_comp_mask comp_mask,
+			    int timeout_ms, unsigned int __nocast gfp_mask,
+			    void (*callback)(int status,
+					     struct ib_sa_service_rec *resp,
+					     void *context),
+			    void *context,
+			    struct ib_sa_query **sa_query)
+{
+	struct ib_sa_service_query *query;
+	struct ib_sa_device *sa_dev = ib_get_client_data(device, &sa_client);
+	struct ib_sa_port   *port   = &sa_dev->port[port_num - sa_dev->start_port];
+	struct ib_mad_agent *agent  = port->agent;
+	int ret;
+
+	if (method != IB_MGMT_METHOD_GET &&
+	    method != IB_MGMT_METHOD_SET &&
+	    method != IB_SA_METHOD_DELETE)
+		return -EINVAL;
+
+	query = kmalloc(sizeof *query, gfp_mask);
+	if (!query)
+		return -ENOMEM;
+	query->sa_query.mad = kmalloc(sizeof *query->sa_query.mad, gfp_mask);
+	if (!query->sa_query.mad) {
+		kfree(query);
+		return -ENOMEM;
+	}
+
+	query->callback = callback;
+	query->context  = context;
+
+	init_mad(query->sa_query.mad, agent);
+
+	query->sa_query.callback              = callback ? ib_sa_service_rec_callback : NULL;
+	query->sa_query.release               = ib_sa_service_rec_release;
+	query->sa_query.port                  = port;
+	query->sa_query.mad->mad_hdr.method   = method;
+	query->sa_query.mad->mad_hdr.attr_id  =
+				cpu_to_be16(IB_SA_ATTR_SERVICE_REC);
+	query->sa_query.mad->sa_hdr.comp_mask = comp_mask;
+
+	ib_pack(service_rec_table, ARRAY_SIZE(service_rec_table),
+		rec, query->sa_query.mad->data);
+
+	*sa_query = &query->sa_query;
+
+	ret = send_mad(&query->sa_query, timeout_ms);
+	if (ret < 0) {
+		*sa_query = NULL;
+		kfree(query->sa_query.mad);
+		kfree(query);
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL(ib_sa_service_rec_query);
+
 static void ib_sa_mcmember_rec_callback(struct ib_sa_query *sa_query,
 					int status,
 					struct ib_sa_mad *mad)
@@ -636,7 +785,7 @@ int ib_sa_mcmember_rec_query(struct ib_d
 			     u8 method,
 			     struct ib_sa_mcmember_rec *rec,
 			     ib_sa_comp_mask comp_mask,
-			     int timeout_ms, int gfp_mask,
+			     int timeout_ms, unsigned int __nocast gfp_mask,
 			     void (*callback)(int status,
 					      struct ib_sa_mcmember_rec *resp,
 					      void *context),
@@ -674,14 +823,15 @@ int ib_sa_mcmember_rec_query(struct ib_d
 		rec, query->sa_query.mad->data);
 
 	*sa_query = &query->sa_query;
+
 	ret = send_mad(&query->sa_query, timeout_ms);
-	if (ret) {
+	if (ret < 0) {
 		*sa_query = NULL;
 		kfree(query->sa_query.mad);
 		kfree(query);
 	}
 
-	return ret ? ret : query->sa_query.id;
+	return ret;
 }
 EXPORT_SYMBOL(ib_sa_mcmember_rec_query);
 
@@ -772,7 +922,6 @@ static void ib_sa_add_one(struct ib_devi
 	sa_dev->end_port   = e;
 
 	for (i = 0; i <= e - s; ++i) {
-		sa_dev->port[i].mr       = NULL;
 		sa_dev->port[i].sm_ah    = NULL;
 		sa_dev->port[i].port_num = i + s;
 		spin_lock_init(&sa_dev->port[i].ah_lock);
@@ -784,13 +933,6 @@ static void ib_sa_add_one(struct ib_devi
 		if (IS_ERR(sa_dev->port[i].agent))
 			goto err;
 
-		sa_dev->port[i].mr = ib_get_dma_mr(sa_dev->port[i].agent->qp->pd,
-						   IB_ACCESS_LOCAL_WRITE);
-		if (IS_ERR(sa_dev->port[i].mr)) {
-			ib_unregister_mad_agent(sa_dev->port[i].agent);
-			goto err;
-		}
-
 		INIT_WORK(&sa_dev->port[i].update_task,
 			  update_sm_ah, &sa_dev->port[i]);
 	}
@@ -814,10 +956,8 @@ static void ib_sa_add_one(struct ib_devi
 	return;
 
 err:
-	while (--i >= 0) {
-		ib_dereg_mr(sa_dev->port[i].mr);
+	while (--i >= 0)
 		ib_unregister_mad_agent(sa_dev->port[i].agent);
-	}
 
 	kfree(sa_dev);
 
diff --git a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c
--- a/drivers/infiniband/core/sysfs.c
+++ b/drivers/infiniband/core/sysfs.c
@@ -40,9 +40,7 @@ struct ib_port {
 	struct kobject         kobj;
 	struct ib_device      *ibdev;
 	struct attribute_group gid_group;
-	struct attribute     **gid_attr;
 	struct attribute_group pkey_group;
-	struct attribute     **pkey_attr;
 	u8                     port_num;
 };
 
@@ -60,8 +58,9 @@ struct port_attribute port_attr_##_name 
 struct port_attribute port_attr_##_name = __ATTR_RO(_name)
 
 struct port_table_attribute {
-	struct port_attribute attr;
-	int                   index;
+	struct port_attribute	attr;
+	char			name[8];
+	int			index;
 };
 
 static ssize_t port_attr_show(struct kobject *kobj,
@@ -72,7 +71,7 @@ static ssize_t port_attr_show(struct kob
 	struct ib_port *p = container_of(kobj, struct ib_port, kobj);
 
 	if (!port_attr->show)
-		return 0;
+		return -EIO;
 
 	return port_attr->show(p, port_attr, buf);
 }
@@ -398,17 +397,16 @@ static void ib_port_release(struct kobje
 	struct attribute *a;
 	int i;
 
-	for (i = 0; (a = p->gid_attr[i]); ++i) {
-		kfree(a->name);
+	for (i = 0; (a = p->gid_group.attrs[i]); ++i)
 		kfree(a);
-	}
 
-	for (i = 0; (a = p->pkey_attr[i]); ++i) {
-		kfree(a->name);
+	kfree(p->gid_group.attrs);
+
+	for (i = 0; (a = p->pkey_group.attrs[i]); ++i)
 		kfree(a);
-	}
 
-	kfree(p->gid_attr);
+	kfree(p->pkey_group.attrs);
+
 	kfree(p);
 }
 
@@ -449,58 +447,45 @@ static int ib_device_hotplug(struct clas
 	return 0;
 }
 
-static int alloc_group(struct attribute ***attr,
-		       ssize_t (*show)(struct ib_port *,
-				       struct port_attribute *, char *buf),
-		       int len)
+static struct attribute **
+alloc_group_attrs(ssize_t (*show)(struct ib_port *,
+				  struct port_attribute *, char *buf),
+		  int len)
 {
-	struct port_table_attribute ***tab_attr =
-		(struct port_table_attribute ***) attr;
+	struct attribute **tab_attr;
+	struct port_table_attribute *element;
 	int i;
-	int ret;
-
-	*tab_attr = kmalloc((1 + len) * sizeof *tab_attr, GFP_KERNEL);
-	if (!*tab_attr)
-		return -ENOMEM;
 
-	memset(*tab_attr, 0, (1 + len) * sizeof *tab_attr);
-
-	for (i = 0; i < len; ++i) {
-		(*tab_attr)[i] = kmalloc(sizeof *(*tab_attr)[i], GFP_KERNEL);
-		if (!(*tab_attr)[i]) {
-			ret = -ENOMEM;
-			goto err;
-		}
-		memset((*tab_attr)[i], 0, sizeof *(*tab_attr)[i]);
-		(*tab_attr)[i]->attr.attr.name = kmalloc(8, GFP_KERNEL);
-		if (!(*tab_attr)[i]->attr.attr.name) {
-			ret = -ENOMEM;
+	tab_attr = kcalloc(1 + len, sizeof(struct attribute *), GFP_KERNEL);
+	if (!tab_attr)
+		return NULL;
+
+	for (i = 0; i < len; i++) {
+		element = kcalloc(1, sizeof(struct port_table_attribute),
+				  GFP_KERNEL);
+		if (!element)
 			goto err;
-		}
 
-		if (snprintf((*tab_attr)[i]->attr.attr.name, 8, "%d", i) >= 8) {
-			ret = -ENOMEM;
+		if (snprintf(element->name, sizeof(element->name),
+			     "%d", i) >= sizeof(element->name))
 			goto err;
-		}
-
-		(*tab_attr)[i]->attr.attr.mode  = S_IRUGO;
-		(*tab_attr)[i]->attr.attr.owner = THIS_MODULE;
-		(*tab_attr)[i]->attr.show       = show;
-		(*tab_attr)[i]->index           = i;
-	}
 
-	return 0;
+		element->attr.attr.name  = element->name;
+		element->attr.attr.mode  = S_IRUGO;
+		element->attr.attr.owner = THIS_MODULE;
+		element->attr.show       = show;
+		element->index		 = i;
 
-err:
-	for (i = 0; i < len; ++i) {
-		if ((*tab_attr)[i])
-			kfree((*tab_attr)[i]->attr.attr.name);
-		kfree((*tab_attr)[i]);
+		tab_attr[i] = &element->attr.attr;
 	}
 
-	kfree(*tab_attr);
+	return tab_attr;
 
-	return ret;
+err:
+	while (--i >= 0)
+		kfree(tab_attr[i]);
+	kfree(tab_attr);
+	return NULL;
 }
 
 static int add_port(struct ib_device *device, int port_num)
@@ -541,23 +526,20 @@ static int add_port(struct ib_device *de
 	if (ret)
 		goto err_put;
 
-	ret = alloc_group(&p->gid_attr, show_port_gid, attr.gid_tbl_len);
-	if (ret)
-		goto err_remove_pma;
-
 	p->gid_group.name  = "gids";
-	p->gid_group.attrs = p->gid_attr;
+	p->gid_group.attrs = alloc_group_attrs(show_port_gid, attr.gid_tbl_len);
+	if (!p->gid_group.attrs)
+		goto err_remove_pma;
 
 	ret = sysfs_create_group(&p->kobj, &p->gid_group);
 	if (ret)
 		goto err_free_gid;
 
-	ret = alloc_group(&p->pkey_attr, show_port_pkey, attr.pkey_tbl_len);
-	if (ret)
-		goto err_remove_gid;
-
 	p->pkey_group.name  = "pkeys";
-	p->pkey_group.attrs = p->pkey_attr;
+	p->pkey_group.attrs = alloc_group_attrs(show_port_pkey,
+						attr.pkey_tbl_len);
+	if (!p->pkey_group.attrs)
+		goto err_remove_gid;
 
 	ret = sysfs_create_group(&p->kobj, &p->pkey_group);
 	if (ret)
@@ -568,23 +550,19 @@ static int add_port(struct ib_device *de
 	return 0;
 
 err_free_pkey:
-	for (i = 0; i < attr.pkey_tbl_len; ++i) {
-		kfree(p->pkey_attr[i]->name);
-		kfree(p->pkey_attr[i]);
-	}
+	for (i = 0; i < attr.pkey_tbl_len; ++i)
+		kfree(p->pkey_group.attrs[i]);
 
-	kfree(p->pkey_attr);
+	kfree(p->pkey_group.attrs);
 
 err_remove_gid:
 	sysfs_remove_group(&p->kobj, &p->gid_group);
 
 err_free_gid:
-	for (i = 0; i < attr.gid_tbl_len; ++i) {
-		kfree(p->gid_attr[i]->name);
-		kfree(p->gid_attr[i]);
-	}
+	for (i = 0; i < attr.gid_tbl_len; ++i)
+		kfree(p->gid_group.attrs[i]);
 
-	kfree(p->gid_attr);
+	kfree(p->gid_group.attrs);
 
 err_remove_pma:
 	sysfs_remove_group(&p->kobj, &pma_group);
diff --git a/drivers/infiniband/core/ucm.c b/drivers/infiniband/core/ucm.c
new file mode 100644
--- /dev/null
+++ b/drivers/infiniband/core/ucm.c
@@ -0,0 +1,1387 @@
+/*
+ * Copyright (c) 2005 Topspin Communications.  All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *	copyright notice, this list of conditions and the following
+ *	disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *	copyright notice, this list of conditions and the following
+ *	disclaimer in the documentation and/or other materials
+ *	provided with the distribution.
+ *
+ * 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 THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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.
+ *
+ * $Id: ucm.c 2594 2005-06-13 19:46:02Z libor $
+ */
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/poll.h>
+#include <linux/file.h>
+#include <linux/mount.h>
+#include <linux/cdev.h>
+
+#include <asm/uaccess.h>
+
+#include "ucm.h"
+
+MODULE_AUTHOR("Libor Michalek");
+MODULE_DESCRIPTION("InfiniBand userspace Connection Manager access");
+MODULE_LICENSE("Dual BSD/GPL");
+
+static int ucm_debug_level;
+
+module_param_named(debug_level, ucm_debug_level, int, 0644);
+MODULE_PARM_DESC(debug_level, "Enable debug tracing if > 0");
+
+enum {
+	IB_UCM_MAJOR = 231,
+	IB_UCM_MINOR = 255
+};
+
+#define IB_UCM_DEV MKDEV(IB_UCM_MAJOR, IB_UCM_MINOR)
+
+#define PFX "UCM: "
+
+#define ucm_dbg(format, arg...)			\
+	do {					\
+		if (ucm_debug_level > 0)	\
+			printk(KERN_DEBUG PFX format, ## arg); \
+	} while (0)
+
+static struct semaphore ctx_id_mutex;
+static struct idr       ctx_id_table;
+static int              ctx_id_rover = 0;
+
+static struct ib_ucm_context *ib_ucm_ctx_get(int id)
+{
+	struct ib_ucm_context *ctx;
+
+	down(&ctx_id_mutex);
+	ctx = idr_find(&ctx_id_table, id);
+	if (ctx)
+		ctx->ref++;
+	up(&ctx_id_mutex);
+
+	return ctx;
+}
+
+static void ib_ucm_ctx_put(struct ib_ucm_context *ctx)
+{
+	struct ib_ucm_event *uevent;
+
+	down(&ctx_id_mutex);
+
+	ctx->ref--;
+	if (!ctx->ref)
+		idr_remove(&ctx_id_table, ctx->id);
+
+	up(&ctx_id_mutex);
+
+	if (ctx->ref)
+		return;
+
+	down(&ctx->file->mutex);
+
+	list_del(&ctx->file_list);
+	while (!list_empty(&ctx->events)) {
+
+		uevent = list_entry(ctx->events.next,
+				    struct ib_ucm_event, ctx_list);
+		list_del(&uevent->file_list);
+		list_del(&uevent->ctx_list);
+
+		/* clear incoming connections. */
+		if (uevent->cm_id)
+			ib_destroy_cm_id(uevent->cm_id);
+
+		kfree(uevent);
+	}
+
+	up(&ctx->file->mutex);
+
+	ucm_dbg("Destroyed CM ID <%d>\n", ctx->id);
+
+	ib_destroy_cm_id(ctx->cm_id);
+	kfree(ctx);
+}
+
+static struct ib_ucm_context *ib_ucm_ctx_alloc(struct ib_ucm_file *file)
+{
+	struct ib_ucm_context *ctx;
+	int result;
+
+	ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
+	if (!ctx)
+		return NULL;
+
+	ctx->ref  = 1; /* user reference */
+	ctx->file = file;
+
+	INIT_LIST_HEAD(&ctx->events);
+	init_MUTEX(&ctx->mutex);
+
+	list_add_tail(&ctx->file_list, &file->ctxs);
+
+	ctx_id_rover = (ctx_id_rover + 1) & INT_MAX;
+retry:
+	result = idr_pre_get(&ctx_id_table, GFP_KERNEL);
+	if (!result)
+		goto error;
+
+	down(&ctx_id_mutex);
+	result = idr_get_new_above(&ctx_id_table, ctx, ctx_id_rover, &ctx->id);
+	up(&ctx_id_mutex);
+
+	if (result == -EAGAIN)
+		goto retry;
+	if (result)
+		goto error;
+
+	ucm_dbg("Allocated CM ID <%d>\n", ctx->id);
+
+	return ctx;
+error:
+	list_del(&ctx->file_list);
+	kfree(ctx);
+
+	return NULL;
+}
+/*
+ * Event portion of the API, handle CM events
+ * and allow event polling.
+ */
+static void ib_ucm_event_path_get(struct ib_ucm_path_rec *upath,
+				  struct ib_sa_path_rec	 *kpath)
+{
+	if (!kpath || !upath)
+		return;
+
+	memcpy(upath->dgid, kpath->dgid.raw, sizeof(union ib_gid));
+	memcpy(upath->sgid, kpath->sgid.raw, sizeof(union ib_gid));
+
+	upath->dlid             = kpath->dlid;
+	upath->slid             = kpath->slid;
+	upath->raw_traffic      = kpath->raw_traffic;
+	upath->flow_label       = kpath->flow_label;
+	upath->hop_limit        = kpath->hop_limit;
+	upath->traffic_class    = kpath->traffic_class;
+	upath->reversible       = kpath->reversible;
+	upath->numb_path        = kpath->numb_path;
+	upath->pkey             = kpath->pkey;
+	upath->sl	        = kpath->sl;
+	upath->mtu_selector     = kpath->mtu_selector;
+	upath->mtu              = kpath->mtu;
+	upath->rate_selector    = kpath->rate_selector;
+	upath->rate             = kpath->rate;
+	upath->packet_life_time = kpath->packet_life_time;
+	upath->preference       = kpath->preference;
+
+	upath->packet_life_time_selector =
+		kpath->packet_life_time_selector;
+}
+
+static void ib_ucm_event_req_get(struct ib_ucm_req_event_resp *ureq,
+				 struct ib_cm_req_event_param *kreq)
+{
+	ureq->listen_id = (long)kreq->listen_id->context;
+
+	ureq->remote_ca_guid             = kreq->remote_ca_guid;
+	ureq->remote_qkey                = kreq->remote_qkey;
+	ureq->remote_qpn                 = kreq->remote_qpn;
+	ureq->qp_type                    = kreq->qp_type;
+	ureq->starting_psn               = kreq->starting_psn;
+	ureq->responder_resources        = kreq->responder_resources;
+	ureq->initiator_depth            = kreq->initiator_depth;
+	ureq->local_cm_response_timeout  = kreq->local_cm_response_timeout;
+	ureq->flow_control               = kreq->flow_control;
+	ureq->remote_cm_response_timeout = kreq->remote_cm_response_timeout;
+	ureq->retry_count                = kreq->retry_count;
+	ureq->rnr_retry_count            = kreq->rnr_retry_count;
+	ureq->srq                        = kreq->srq;
+
+	ib_ucm_event_path_get(&ureq->primary_path, kreq->primary_path);
+	ib_ucm_event_path_get(&ureq->alternate_path, kreq->alternate_path);
+}
+
+static void ib_ucm_event_rep_get(struct ib_ucm_rep_event_resp *urep,
+				 struct ib_cm_rep_event_param *krep)
+{
+	urep->remote_ca_guid      = krep->remote_ca_guid;
+	urep->remote_qkey         = krep->remote_qkey;
+	urep->remote_qpn          = krep->remote_qpn;
+	urep->starting_psn        = krep->starting_psn;
+	urep->responder_resources = krep->responder_resources;
+	urep->initiator_depth     = krep->initiator_depth;
+	urep->target_ack_delay    = krep->target_ack_delay;
+	urep->failover_accepted   = krep->failover_accepted;
+	urep->flow_control        = krep->flow_control;
+	urep->rnr_retry_count     = krep->rnr_retry_count;
+	urep->srq                 = krep->srq;
+}
+
+static void ib_ucm_event_rej_get(struct ib_ucm_rej_event_resp *urej,
+				 struct ib_cm_rej_event_param *krej)
+{
+	urej->reason = krej->reason;
+}
+
+static void ib_ucm_event_mra_get(struct ib_ucm_mra_event_resp *umra,
+				 struct ib_cm_mra_event_param *kmra)
+{
+	umra->timeout = kmra->service_timeout;
+}
+
+static void ib_ucm_event_lap_get(struct ib_ucm_lap_event_resp *ulap,
+				 struct ib_cm_lap_event_param *klap)
+{
+	ib_ucm_event_path_get(&ulap->path, klap->alternate_path);
+}
+
+static void ib_ucm_event_apr_get(struct ib_ucm_apr_event_resp *uapr,
+				 struct ib_cm_apr_event_param *kapr)
+{
+	uapr->status = kapr->ap_status;
+}
+
+static void ib_ucm_event_sidr_req_get(struct ib_ucm_sidr_req_event_resp *ureq,
+				      struct ib_cm_sidr_req_event_param *kreq)
+{
+	ureq->listen_id = (long)kreq->listen_id->context;
+	ureq->pkey      = kreq->pkey;
+}
+
+static void ib_ucm_event_sidr_rep_get(struct ib_ucm_sidr_rep_event_resp *urep,
+				      struct ib_cm_sidr_rep_event_param *krep)
+{
+	urep->status = krep->status;
+	urep->qkey   = krep->qkey;
+	urep->qpn    = krep->qpn;
+};
+
+static int ib_ucm_event_process(struct ib_cm_event *evt,
+				struct ib_ucm_event *uvt)
+{
+	void *info = NULL;
+	int result;
+
+	switch (evt->event) {
+	case IB_CM_REQ_RECEIVED:
+		ib_ucm_event_req_get(&uvt->resp.u.req_resp,
+				     &evt->param.req_rcvd);
+		uvt->data_len      = IB_CM_REQ_PRIVATE_DATA_SIZE;
+		uvt->resp.present |= (evt->param.req_rcvd.primary_path ?
+				      IB_UCM_PRES_PRIMARY : 0);
+		uvt->resp.present |= (evt->param.req_rcvd.alternate_path ?
+				      IB_UCM_PRES_ALTERNATE : 0);
+		break;
+	case IB_CM_REP_RECEIVED:
+		ib_ucm_event_rep_get(&uvt->resp.u.rep_resp,
+				     &evt->param.rep_rcvd);
+		uvt->data_len = IB_CM_REP_PRIVATE_DATA_SIZE;
+
+		break;
+	case IB_CM_RTU_RECEIVED:
+		uvt->data_len = IB_CM_RTU_PRIVATE_DATA_SIZE;
+		uvt->resp.u.send_status = evt->param.send_status;
+
+		break;
+	case IB_CM_DREQ_RECEIVED:
+		uvt->data_len = IB_CM_DREQ_PRIVATE_DATA_SIZE;
+		uvt->resp.u.send_status = evt->param.send_status;
+
+		break;
+	case IB_CM_DREP_RECEIVED:
+		uvt->data_len = IB_CM_DREP_PRIVATE_DATA_SIZE;
+		uvt->resp.u.send_status = evt->param.send_status;
+
+		break;
+	case IB_CM_MRA_RECEIVED:
+		ib_ucm_event_mra_get(&uvt->resp.u.mra_resp,
+				     &evt->param.mra_rcvd);
+		uvt->data_len = IB_CM_MRA_PRIVATE_DATA_SIZE;
+
+		break;
+	case IB_CM_REJ_RECEIVED:
+		ib_ucm_event_rej_get(&uvt->resp.u.rej_resp,
+				     &evt->param.rej_rcvd);
+		uvt->data_len = IB_CM_REJ_PRIVATE_DATA_SIZE;
+		uvt->info_len = evt->param.rej_rcvd.ari_length;
+		info	      = evt->param.rej_rcvd.ari;
+
+		break;
+	case IB_CM_LAP_RECEIVED:
+		ib_ucm_event_lap_get(&uvt->resp.u.lap_resp,
+				     &evt->param.lap_rcvd);
+		uvt->data_len = IB_CM_LAP_PRIVATE_DATA_SIZE;
+		uvt->resp.present |= (evt->param.lap_rcvd.alternate_path ?
+				      IB_UCM_PRES_ALTERNATE : 0);
+		break;
+	case IB_CM_APR_RECEIVED:
+		ib_ucm_event_apr_get(&uvt->resp.u.apr_resp,
+				     &evt->param.apr_rcvd);
+		uvt->data_len = IB_CM_APR_PRIVATE_DATA_SIZE;
+		uvt->info_len = evt->param.apr_rcvd.info_len;
+		info	      = evt->param.apr_rcvd.apr_info;
+
+		break;
+	case IB_CM_SIDR_REQ_RECEIVED:
+		ib_ucm_event_sidr_req_get(&uvt->resp.u.sidr_req_resp,
+					  &evt->param.sidr_req_rcvd);
+		uvt->data_len = IB_CM_SIDR_REQ_PRIVATE_DATA_SIZE;
+
+		break;
+	case IB_CM_SIDR_REP_RECEIVED:
+		ib_ucm_event_sidr_rep_get(&uvt->resp.u.sidr_rep_resp,
+					  &evt->param.sidr_rep_rcvd);
+		uvt->data_len = IB_CM_SIDR_REP_PRIVATE_DATA_SIZE;
+		uvt->info_len = evt->param.sidr_rep_rcvd.info_len;
+		info	      = evt->param.sidr_rep_rcvd.info;
+
+		break;
+	default:
+		uvt->resp.u.send_status = evt->param.send_status;
+
+		break;
+	}
+
+	if (uvt->data_len && evt->private_data) {
+
+		uvt->data = kmalloc(uvt->data_len, GFP_KERNEL);
+		if (!uvt->data) {
+			result = -ENOMEM;
+			goto error;
+		}
+
+		memcpy(uvt->data, evt->private_data, uvt->data_len);
+		uvt->resp.present |= IB_UCM_PRES_DATA;
+	}
+
+	if (uvt->info_len && info) {
+
+		uvt->info = kmalloc(uvt->info_len, GFP_KERNEL);
+		if (!uvt->info) {
+			result = -ENOMEM;
+			goto error;
+		}
+
+		memcpy(uvt->info, info, uvt->info_len);
+		uvt->resp.present |= IB_UCM_PRES_INFO;
+	}
+
+	return 0;
+error:
+	kfree(uvt->info);
+	kfree(uvt->data);
+	return result;
+}
+
+static int ib_ucm_event_handler(struct ib_cm_id *cm_id,
+				struct ib_cm_event *event)
+{
+	struct ib_ucm_event *uevent;
+	struct ib_ucm_context *ctx;
+	int result = 0;
+	int id;
+	/*
+	 * lookup correct context based on event type.
+	 */
+	switch (event->event) {
+	case IB_CM_REQ_RECEIVED:
+		id = (long)event->param.req_rcvd.listen_id->context;
+		break;
+	case IB_CM_SIDR_REQ_RECEIVED:
+		id = (long)event->param.sidr_req_rcvd.listen_id->context;
+		break;
+	default:
+		id = (long)cm_id->context;
+		break;
+	}
+
+	ucm_dbg("Event. CM ID <%d> event <%d>\n", id, event->event);
+
+	ctx = ib_ucm_ctx_get(id);
+	if (!ctx)
+		return -ENOENT;
+
+	if (event->event == IB_CM_REQ_RECEIVED ||
+	    event->event == IB_CM_SIDR_REQ_RECEIVED)
+		id = IB_UCM_CM_ID_INVALID;
+
+	uevent = kmalloc(sizeof(*uevent), GFP_KERNEL);
+	if (!uevent) {
+		result = -ENOMEM;
+		goto done;
+	}
+
+	memset(uevent, 0, sizeof(*uevent));
+
+	uevent->resp.id    = id;
+	uevent->resp.event = event->event;
+
+	result = ib_ucm_event_process(event, uevent);
+	if (result)
+		goto done;
+
+	uevent->ctx   = ctx;
+	uevent->cm_id = ((event->event == IB_CM_REQ_RECEIVED ||
+			  event->event == IB_CM_SIDR_REQ_RECEIVED ) ?
+			 cm_id : NULL);
+
+	down(&ctx->file->mutex);
+
+	list_add_tail(&uevent->file_list, &ctx->file->events);
+	list_add_tail(&uevent->ctx_list, &ctx->events);
+
+	wake_up_interruptible(&ctx->file->poll_wait);
+
+	up(&ctx->file->mutex);
+done:
+	ctx->error = result;
+	ib_ucm_ctx_put(ctx); /* func reference */
+	return result;
+}
+
+static ssize_t ib_ucm_event(struct ib_ucm_file *file,
+			    const char __user *inbuf,
+			    int in_len, int out_len)
+{
+	struct ib_ucm_context *ctx;
+	struct ib_ucm_event_get cmd;
+	struct ib_ucm_event *uevent = NULL;
+	int result = 0;
+	DEFINE_WAIT(wait);
+
+	if (out_len < sizeof(struct ib_ucm_event_resp))
+		return -ENOSPC;
+
+	if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
+		return -EFAULT;
+	/*
+	 * wait
+	 */
+	down(&file->mutex);
+
+	while (list_empty(&file->events)) {
+
+		if (file->filp->f_flags & O_NONBLOCK) {
+			result = -EAGAIN;
+			break;
+		}
+
+		if (signal_pending(current)) {
+			result = -ERESTARTSYS;
+			break;
+		}
+
+		prepare_to_wait(&file->poll_wait, &wait, TASK_INTERRUPTIBLE);
+
+		up(&file->mutex);
+		schedule();
+		down(&file->mutex);
+
+		finish_wait(&file->poll_wait, &wait);
+	}
+
+	if (result)
+		goto done;
+
+	uevent = list_entry(file->events.next, struct ib_ucm_event, file_list);
+
+	if (!uevent->cm_id)
+		goto user;
+
+	ctx = ib_ucm_ctx_alloc(file);
+	if (!ctx) {
+		result = -ENOMEM;
+		goto done;
+	}
+
+	ctx->cm_id             = uevent->cm_id;
+	ctx->cm_id->cm_handler = ib_ucm_event_handler;
+	ctx->cm_id->context    = (void *)(unsigned long)ctx->id;
+
+	uevent->resp.id = ctx->id;
+
+user:
+	if (copy_to_user((void __user *)(unsigned long)cmd.response,
+			 &uevent->resp, sizeof(uevent->resp))) {
+		result = -EFAULT;
+		goto done;
+	}
+
+	if (uevent->data) {
+
+		if (cmd.data_len < uevent->data_len) {
+			result = -ENOMEM;
+			goto done;
+		}
+
+		if (copy_to_user((void __user *)(unsigned long)cmd.data,
+				 uevent->data, uevent->data_len)) {
+			result = -EFAULT;
+			goto done;
+		}
+	}
+
+	if (uevent->info) {
+
+		if (cmd.info_len < uevent->info_len) {
+			result = -ENOMEM;
+			goto done;
+		}
+
+		if (copy_to_user((void __user *)(unsigned long)cmd.info,
+				 uevent->info, uevent->info_len)) {
+			result = -EFAULT;
+			goto done;
+		}
+	}
+
+	list_del(&uevent->file_list);
+	list_del(&uevent->ctx_list);
+
+	kfree(uevent->data);
+	kfree(uevent->info);
+	kfree(uevent);
+done:
+	up(&file->mutex);
+	return result;
+}
+
+
+static ssize_t ib_ucm_create_id(struct ib_ucm_file *file,
+				const char __user *inbuf,
+				int in_len, int out_len)
+{
+	struct ib_ucm_create_id cmd;
+	struct ib_ucm_create_id_resp resp;
+	struct ib_ucm_context *ctx;
+	int result;
+
+	if (out_len < sizeof(resp))
+		return -ENOSPC;
+
+	if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
+		return -EFAULT;
+
+	ctx = ib_ucm_ctx_alloc(file);
+	if (!ctx)
+		return -ENOMEM;
+
+	ctx->cm_id = ib_create_cm_id(ib_ucm_event_handler,
+				     (void *)(unsigned long)ctx->id);
+	if (!ctx->cm_id) {
+		result = -ENOMEM;
+		goto err_cm;
+	}
+
+	resp.id = ctx->id;
+	if (copy_to_user((void __user *)(unsigned long)cmd.response,
+			 &resp, sizeof(resp))) {
+		result = -EFAULT;
+		goto err_ret;
+	}
+
+	return 0;
+err_ret:
+	ib_destroy_cm_id(ctx->cm_id);
+err_cm:
+	ib_ucm_ctx_put(ctx); /* user reference */
+
+	return result;
+}
+
+static ssize_t ib_ucm_destroy_id(struct ib_ucm_file *file,
+				 const char __user *inbuf,
+				 int in_len, int out_len)
+{
+	struct ib_ucm_destroy_id cmd;
+	struct ib_ucm_context *ctx;
+
+	if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
+		return -EFAULT;
+
+	ctx = ib_ucm_ctx_get(cmd.id);
+	if (!ctx)
+		return -ENOENT;
+
+	ib_ucm_ctx_put(ctx); /* user reference */
+	ib_ucm_ctx_put(ctx); /* func reference */
+
+	return 0;
+}
+
+static ssize_t ib_ucm_attr_id(struct ib_ucm_file *file,
+			      const char __user *inbuf,
+			      int in_len, int out_len)
+{
+	struct ib_ucm_attr_id_resp resp;
+	struct ib_ucm_attr_id cmd;
+	struct ib_ucm_context *ctx;
+	int result = 0;
+
+	if (out_len < sizeof(resp))
+		return -ENOSPC;
+
+	if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
+		return -EFAULT;
+
+	ctx = ib_ucm_ctx_get(cmd.id);
+	if (!ctx)
+		return -ENOENT;
+
+ 	down(&ctx->file->mutex);
+	if (ctx->file != file) {
+		result = -EINVAL;
+		goto done;
+	}
+
+	resp.service_id   = ctx->cm_id->service_id;
+	resp.service_mask = ctx->cm_id->service_mask;
+	resp.local_id     = ctx->cm_id->local_id;
+	resp.remote_id    = ctx->cm_id->remote_id;
+
+	if (copy_to_user((void __user *)(unsigned long)cmd.response,
+			 &resp, sizeof(resp)))
+		result = -EFAULT;
+
+done:
+	up(&ctx->file->mutex);
+	ib_ucm_ctx_put(ctx); /* func reference */
+	return result;
+}
+
+static ssize_t ib_ucm_listen(struct ib_ucm_file *file,
+			     const char __user *inbuf,
+			     int in_len, int out_len)
+{
+	struct ib_ucm_listen cmd;
+	struct ib_ucm_context *ctx;
+	int result;
+
+	if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
+		return -EFAULT;
+
+	ctx = ib_ucm_ctx_get(cmd.id);
+	if (!ctx)
+		return -ENOENT;
+
+ 	down(&ctx->file->mutex);
+	if (ctx->file != file)
+		result = -EINVAL;
+	else
+		result = ib_cm_listen(ctx->cm_id, cmd.service_id,
+				      cmd.service_mask);
+
+	up(&ctx->file->mutex);
+	ib_ucm_ctx_put(ctx); /* func reference */
+	return result;
+}
+
+static ssize_t ib_ucm_establish(struct ib_ucm_file *file,
+				const char __user *inbuf,
+				int in_len, int out_len)
+{
+	struct ib_ucm_establish cmd;
+	struct ib_ucm_context *ctx;
+	int result;
+
+	if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
+		return -EFAULT;
+
+	ctx = ib_ucm_ctx_get(cmd.id);
+	if (!ctx)
+		return -ENOENT;
+
+ 	down(&ctx->file->mutex);
+	if (ctx->file != file)
+		result = -EINVAL;
+	else
+		result = ib_cm_establish(ctx->cm_id);
+
+	up(&ctx->file->mutex);
+	ib_ucm_ctx_put(ctx); /* func reference */
+	return result;
+}
+
+static int ib_ucm_alloc_data(const void **dest, u64 src, u32 len)
+{
+	void *data;
+
+	*dest = NULL;
+
+	if (!len)
+		return 0;
+
+	data = kmalloc(len, GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	if (copy_from_user(data, (void __user *)(unsigned long)src, len)) {
+		kfree(data);
+		return -EFAULT;
+	}
+
+	*dest = data;
+	return 0;
+}
+
+static int ib_ucm_path_get(struct ib_sa_path_rec **path, u64 src)
+{
+	struct ib_ucm_path_rec ucm_path;
+	struct ib_sa_path_rec  *sa_path;
+
+	*path = NULL;
+
+	if (!src)
+		return 0;
+
+	sa_path = kmalloc(sizeof(*sa_path), GFP_KERNEL);
+	if (!sa_path)
+		return -ENOMEM;
+
+	if (copy_from_user(&ucm_path, (void __user *)(unsigned long)src,
+			   sizeof(ucm_path))) {
+
+		kfree(sa_path);
+		return -EFAULT;
+	}
+
+	memcpy(sa_path->dgid.raw, ucm_path.dgid, sizeof(union ib_gid));
+	memcpy(sa_path->sgid.raw, ucm_path.sgid, sizeof(union ib_gid));
+
+	sa_path->dlid	          = ucm_path.dlid;
+	sa_path->slid	          = ucm_path.slid;
+	sa_path->raw_traffic      = ucm_path.raw_traffic;
+	sa_path->flow_label       = ucm_path.flow_label;
+	sa_path->hop_limit        = ucm_path.hop_limit;
+	sa_path->traffic_class    = ucm_path.traffic_class;
+	sa_path->reversible       = ucm_path.reversible;
+	sa_path->numb_path        = ucm_path.numb_path;
+	sa_path->pkey             = ucm_path.pkey;
+	sa_path->sl               = ucm_path.sl;
+	sa_path->mtu_selector     = ucm_path.mtu_selector;
+	sa_path->mtu              = ucm_path.mtu;
+	sa_path->rate_selector    = ucm_path.rate_selector;
+	sa_path->rate             = ucm_path.rate;
+	sa_path->packet_life_time = ucm_path.packet_life_time;
+	sa_path->preference       = ucm_path.preference;
+
+	sa_path->packet_life_time_selector =
+		ucm_path.packet_life_time_selector;
+
+	*path = sa_path;
+	return 0;
+}
+
+static ssize_t ib_ucm_send_req(struct ib_ucm_file *file,
+			       const char __user *inbuf,
+			       int in_len, int out_len)
+{
+	struct ib_cm_req_param param;
+	struct ib_ucm_context *ctx;
+	struct ib_ucm_req cmd;
+	int result;
+
+	param.private_data   = NULL;
+	param.primary_path   = NULL;
+	param.alternate_path = NULL;
+
+	if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
+		return -EFAULT;
+
+	result = ib_ucm_alloc_data(&param.private_data, cmd.data, cmd.len);
+	if (result)
+		goto done;
+
+	result = ib_ucm_path_get(&param.primary_path, cmd.primary_path);
+	if (result)
+		goto done;
+
+	result = ib_ucm_path_get(&param.alternate_path, cmd.alternate_path);
+	if (result)
+		goto done;
+
+	param.private_data_len           = cmd.len;
+	param.service_id                 = cmd.sid;
+	param.qp_num                     = cmd.qpn;
+	param.qp_type                    = cmd.qp_type;
+	param.starting_psn               = cmd.psn;
+	param.peer_to_peer               = cmd.peer_to_peer;
+	param.responder_resources        = cmd.responder_resources;
+	param.initiator_depth            = cmd.initiator_depth;
+	param.remote_cm_response_timeout = cmd.remote_cm_response_timeout;
+	param.flow_control               = cmd.flow_control;
+	param.local_cm_response_timeout  = cmd.local_cm_response_timeout;
+	param.retry_count                = cmd.retry_count;
+	param.rnr_retry_count            = cmd.rnr_retry_count;
+	param.max_cm_retries             = cmd.max_cm_retries;
+	param.srq                        = cmd.srq;
+
+	ctx = ib_ucm_ctx_get(cmd.id);
+	if (!ctx) {
+		result = -ENOENT;
+		goto done;
+	}
+
+ 	down(&ctx->file->mutex);
+	if (ctx->file != file)
+		result = -EINVAL;
+	else
+		result = ib_send_cm_req(ctx->cm_id, &param);
+
+	up(&ctx->file->mutex);
+	ib_ucm_ctx_put(ctx); /* func reference */
+done:
+	kfree(param.private_data);
+	kfree(param.primary_path);
+	kfree(param.alternate_path);
+
+	return result;
+}
+
+static ssize_t ib_ucm_send_rep(struct ib_ucm_file *file,
+			       const char __user *inbuf,
+			       int in_len, int out_len)
+{
+	struct ib_cm_rep_param param;
+	struct ib_ucm_context *ctx;
+	struct ib_ucm_rep cmd;
+	int result;
+
+	param.private_data = NULL;
+
+	if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
+		return -EFAULT;
+
+	result = ib_ucm_alloc_data(&param.private_data, cmd.data, cmd.len);
+	if (result)
+		return result;
+
+	param.qp_num              = cmd.qpn;
+	param.starting_psn        = cmd.psn;
+	param.private_data_len    = cmd.len;
+	param.responder_resources = cmd.responder_resources;
+	param.initiator_depth     = cmd.initiator_depth;
+	param.target_ack_delay    = cmd.target_ack_delay;
+	param.failover_accepted   = cmd.failover_accepted;
+	param.flow_control        = cmd.flow_control;
+	param.rnr_retry_count     = cmd.rnr_retry_count;
+	param.srq                 = cmd.srq;
+
+	ctx = ib_ucm_ctx_get(cmd.id);
+	if (!ctx) {
+		result = -ENOENT;
+		goto done;
+	}
+
+ 	down(&ctx->file->mutex);
+	if (ctx->file != file)
+		result = -EINVAL;
+	else
+		result = ib_send_cm_rep(ctx->cm_id, &param);
+
+	up(&ctx->file->mutex);
+	ib_ucm_ctx_put(ctx); /* func reference */
+done:
+	kfree(param.private_data);
+
+	return result;
+}
+
+static ssize_t ib_ucm_send_private_data(struct ib_ucm_file *file,
+					const char __user *inbuf, int in_len,
+					int (*func)(struct ib_cm_id *cm_id,
+						    const void *private_data,
+						    u8 private_data_len))
+{
+	struct ib_ucm_private_data cmd;
+	struct ib_ucm_context *ctx;
+	const void *private_data = NULL;
+	int result;
+
+	if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
+		return -EFAULT;
+
+	result = ib_ucm_alloc_data(&private_data, cmd.data, cmd.len);
+	if (result)
+		return result;
+
+	ctx = ib_ucm_ctx_get(cmd.id);
+	if (!ctx) {
+		result = -ENOENT;
+		goto done;
+	}
+
+ 	down(&ctx->file->mutex);
+	if (ctx->file != file)
+		result = -EINVAL;
+	else
+		result = func(ctx->cm_id, private_data, cmd.len);
+
+	up(&ctx->file->mutex);
+	ib_ucm_ctx_put(ctx); /* func reference */
+done:
+	kfree(private_data);
+
+	return result;
+}
+
+static ssize_t ib_ucm_send_rtu(struct ib_ucm_file *file,
+			       const char __user *inbuf,
+			       int in_len, int out_len)
+{
+	return ib_ucm_send_private_data(file, inbuf, in_len, ib_send_cm_rtu);
+}
+
+static ssize_t ib_ucm_send_dreq(struct ib_ucm_file *file,
+				const char __user *inbuf,
+				int in_len, int out_len)
+{
+	return ib_ucm_send_private_data(file, inbuf, in_len, ib_send_cm_dreq);
+}
+
+static ssize_t ib_ucm_send_drep(struct ib_ucm_file *file,
+				const char __user *inbuf,
+				int in_len, int out_len)
+{
+	return ib_ucm_send_private_data(file, inbuf, in_len, ib_send_cm_drep);
+}
+
+static ssize_t ib_ucm_send_info(struct ib_ucm_file *file,
+				const char __user *inbuf, int in_len,
+				int (*func)(struct ib_cm_id *cm_id,
+					    int status,
+					    const void *info,
+					    u8 info_len,
+					    const void *data,
+					    u8 data_len))
+{
+	struct ib_ucm_context *ctx;
+	struct ib_ucm_info cmd;
+	const void *data = NULL;
+	const void *info = NULL;
+	int result;
+
+	if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
+		return -EFAULT;
+
+	result = ib_ucm_alloc_data(&data, cmd.data, cmd.data_len);
+	if (result)
+		goto done;
+
+	result = ib_ucm_alloc_data(&info, cmd.info, cmd.info_len);
+	if (result)
+		goto done;
+
+	ctx = ib_ucm_ctx_get(cmd.id);
+	if (!ctx) {
+		result = -ENOENT;
+		goto done;
+	}
+
+ 	down(&ctx->file->mutex);
+	if (ctx->file != file)
+		result = -EINVAL;
+	else
+		result = func(ctx->cm_id, cmd.status,
+			      info, cmd.info_len,
+			      data, cmd.data_len);
+
+	up(&ctx->file->mutex);
+	ib_ucm_ctx_put(ctx); /* func reference */
+done:
+	kfree(data);
+	kfree(info);
+
+	return result;
+}
+
+static ssize_t ib_ucm_send_rej(struct ib_ucm_file *file,
+			       const char __user *inbuf,
+			       int in_len, int out_len)
+{
+	return ib_ucm_send_info(file, inbuf, in_len, (void *)ib_send_cm_rej);
+}
+
+static ssize_t ib_ucm_send_apr(struct ib_ucm_file *file,
+			       const char __user *inbuf,
+			       int in_len, int out_len)
+{
+	return ib_ucm_send_info(file, inbuf, in_len, (void *)ib_send_cm_apr);
+}
+
+static ssize_t ib_ucm_send_mra(struct ib_ucm_file *file,
+			       const char __user *inbuf,
+			       int in_len, int out_len)
+{
+	struct ib_ucm_context *ctx;
+	struct ib_ucm_mra cmd;
+	const void *data = NULL;
+	int result;
+
+	if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
+		return -EFAULT;
+
+	result = ib_ucm_alloc_data(&data, cmd.data, cmd.len);
+	if (result)
+		return result;
+
+	ctx = ib_ucm_ctx_get(cmd.id);
+	if (!ctx) {
+		result = -ENOENT;
+		goto done;
+	}
+
+ 	down(&ctx->file->mutex);
+	if (ctx->file != file)
+		result = -EINVAL;
+	else
+		result = ib_send_cm_mra(ctx->cm_id, cmd.timeout,
+					data, cmd.len);
+
+	up(&ctx->file->mutex);
+	ib_ucm_ctx_put(ctx); /* func reference */
+done:
+	kfree(data);
+
+	return result;
+}
+
+static ssize_t ib_ucm_send_lap(struct ib_ucm_file *file,
+			       const char __user *inbuf,
+			       int in_len, int out_len)
+{
+	struct ib_ucm_context *ctx;
+	struct ib_sa_path_rec *path = NULL;
+	struct ib_ucm_lap cmd;
+	const void *data = NULL;
+	int result;
+
+	if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
+		return -EFAULT;
+
+	result = ib_ucm_alloc_data(&data, cmd.data, cmd.len);
+	if (result)
+		goto done;
+
+	result = ib_ucm_path_get(&path, cmd.path);
+	if (result)
+		goto done;
+
+	ctx = ib_ucm_ctx_get(cmd.id);
+	if (!ctx) {
+		result = -ENOENT;
+		goto done;
+	}
+
+ 	down(&ctx->file->mutex);
+	if (ctx->file != file)
+		result = -EINVAL;
+	else
+		result = ib_send_cm_lap(ctx->cm_id, path, data, cmd.len);
+
+	up(&ctx->file->mutex);
+	ib_ucm_ctx_put(ctx); /* func reference */
+done:
+	kfree(data);
+	kfree(path);
+
+	return result;
+}
+
+static ssize_t ib_ucm_send_sidr_req(struct ib_ucm_file *file,
+				    const char __user *inbuf,
+				    int in_len, int out_len)
+{
+	struct ib_cm_sidr_req_param param;
+	struct ib_ucm_context *ctx;
+	struct ib_ucm_sidr_req cmd;
+	int result;
+
+	param.private_data = NULL;
+	param.path = NULL;
+
+	if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
+		return -EFAULT;
+
+	result = ib_ucm_alloc_data(&param.private_data, cmd.data, cmd.len);
+	if (result)
+		goto done;
+
+	result = ib_ucm_path_get(&param.path, cmd.path);
+	if (result)
+		goto done;
+
+	param.private_data_len = cmd.len;
+	param.service_id       = cmd.sid;
+	param.timeout_ms       = cmd.timeout;
+	param.max_cm_retries   = cmd.max_cm_retries;
+	param.pkey             = cmd.pkey;
+
+	ctx = ib_ucm_ctx_get(cmd.id);
+	if (!ctx) {
+		result = -ENOENT;
+		goto done;
+	}
+
+ 	down(&ctx->file->mutex);
+	if (ctx->file != file)
+		result = -EINVAL;
+	else
+		result = ib_send_cm_sidr_req(ctx->cm_id, &param);
+
+	up(&ctx->file->mutex);
+	ib_ucm_ctx_put(ctx); /* func reference */
+done:
+	kfree(param.private_data);
+	kfree(param.path);
+
+	return result;
+}
+
+static ssize_t ib_ucm_send_sidr_rep(struct ib_ucm_file *file,
+				    const char __user *inbuf,
+				    int in_len, int out_len)
+{
+	struct ib_cm_sidr_rep_param param;
+	struct ib_ucm_sidr_rep cmd;
+	struct ib_ucm_context *ctx;
+	int result;
+
+	param.info = NULL;
+
+	if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
+		return -EFAULT;
+
+	result = ib_ucm_alloc_data(&param.private_data,
+				   cmd.data, cmd.data_len);
+	if (result)
+		goto done;
+
+	result = ib_ucm_alloc_data(&param.info, cmd.info, cmd.info_len);
+	if (result)
+		goto done;
+
+	param.qp_num	   = cmd.qpn;
+	param.qkey	     = cmd.qkey;
+	param.status	   = cmd.status;
+	param.info_length      = cmd.info_len;
+	param.private_data_len = cmd.data_len;
+
+	ctx = ib_ucm_ctx_get(cmd.id);
+	if (!ctx) {
+		result = -ENOENT;
+		goto done;
+	}
+
+ 	down(&ctx->file->mutex);
+	if (ctx->file != file)
+		result = -EINVAL;
+	else
+		result = ib_send_cm_sidr_rep(ctx->cm_id, &param);
+
+	up(&ctx->file->mutex);
+	ib_ucm_ctx_put(ctx); /* func reference */
+done:
+	kfree(param.private_data);
+	kfree(param.info);
+
+	return result;
+}
+
+static ssize_t (*ucm_cmd_table[])(struct ib_ucm_file *file,
+				  const char __user *inbuf,
+				  int in_len, int out_len) = {
+	[IB_USER_CM_CMD_CREATE_ID]     = ib_ucm_create_id,
+	[IB_USER_CM_CMD_DESTROY_ID]    = ib_ucm_destroy_id,
+	[IB_USER_CM_CMD_ATTR_ID]       = ib_ucm_attr_id,
+	[IB_USER_CM_CMD_LISTEN]        = ib_ucm_listen,
+	[IB_USER_CM_CMD_ESTABLISH]     = ib_ucm_establish,
+	[IB_USER_CM_CMD_SEND_REQ]      = ib_ucm_send_req,
+	[IB_USER_CM_CMD_SEND_REP]      = ib_ucm_send_rep,
+	[IB_USER_CM_CMD_SEND_RTU]      = ib_ucm_send_rtu,
+	[IB_USER_CM_CMD_SEND_DREQ]     = ib_ucm_send_dreq,
+	[IB_USER_CM_CMD_SEND_DREP]     = ib_ucm_send_drep,
+	[IB_USER_CM_CMD_SEND_REJ]      = ib_ucm_send_rej,
+	[IB_USER_CM_CMD_SEND_MRA]      = ib_ucm_send_mra,
+	[IB_USER_CM_CMD_SEND_LAP]      = ib_ucm_send_lap,
+	[IB_USER_CM_CMD_SEND_APR]      = ib_ucm_send_apr,
+	[IB_USER_CM_CMD_SEND_SIDR_REQ] = ib_ucm_send_sidr_req,
+	[IB_USER_CM_CMD_SEND_SIDR_REP] = ib_ucm_send_sidr_rep,
+	[IB_USER_CM_CMD_EVENT]	       = ib_ucm_event,
+};
+
+static ssize_t ib_ucm_write(struct file *filp, const char __user *buf,
+			    size_t len, loff_t *pos)
+{
+	struct ib_ucm_file *file = filp->private_data;
+	struct ib_ucm_cmd_hdr hdr;
+	ssize_t result;
+
+	if (len < sizeof(hdr))
+		return -EINVAL;
+
+	if (copy_from_user(&hdr, buf, sizeof(hdr)))
+		return -EFAULT;
+
+	ucm_dbg("Write. cmd <%d> in <%d> out <%d> len <%Zu>\n",
+		hdr.cmd, hdr.in, hdr.out, len);
+
+	if (hdr.cmd < 0 || hdr.cmd >= ARRAY_SIZE(ucm_cmd_table))
+		return -EINVAL;
+
+	if (hdr.in + sizeof(hdr) > len)
+		return -EINVAL;
+
+	result = ucm_cmd_table[hdr.cmd](file, buf + sizeof(hdr),
+					hdr.in, hdr.out);
+	if (!result)
+		result = len;
+
+	return result;
+}
+
+static unsigned int ib_ucm_poll(struct file *filp,
+				struct poll_table_struct *wait)
+{
+	struct ib_ucm_file *file = filp->private_data;
+	unsigned int mask = 0;
+
+	poll_wait(filp, &file->poll_wait, wait);
+
+	if (!list_empty(&file->events))
+		mask = POLLIN | POLLRDNORM;
+
+	return mask;
+}
+
+static int ib_ucm_open(struct inode *inode, struct file *filp)
+{
+	struct ib_ucm_file *file;
+
+	file = kmalloc(sizeof(*file), GFP_KERNEL);
+	if (!file)
+		return -ENOMEM;
+
+	INIT_LIST_HEAD(&file->events);
+	INIT_LIST_HEAD(&file->ctxs);
+	init_waitqueue_head(&file->poll_wait);
+
+	init_MUTEX(&file->mutex);
+
+	filp->private_data = file;
+	file->filp = filp;
+
+	ucm_dbg("Created struct\n");
+
+	return 0;
+}
+
+static int ib_ucm_close(struct inode *inode, struct file *filp)
+{
+	struct ib_ucm_file *file = filp->private_data;
+	struct ib_ucm_context *ctx;
+
+	down(&file->mutex);
+
+	while (!list_empty(&file->ctxs)) {
+
+		ctx = list_entry(file->ctxs.next,
+				 struct ib_ucm_context, file_list);
+
+		up(&ctx->file->mutex);
+		ib_ucm_ctx_put(ctx); /* user reference */
+		down(&file->mutex);
+	}
+
+	up(&file->mutex);
+
+	kfree(file);
+
+	ucm_dbg("Deleted struct\n");
+	return 0;
+}
+
+static struct file_operations ib_ucm_fops = {
+	.owner 	 = THIS_MODULE,
+	.open 	 = ib_ucm_open,
+	.release = ib_ucm_close,
+	.write 	 = ib_ucm_write,
+	.poll    = ib_ucm_poll,
+};
+
+
+static struct class *ib_ucm_class;
+static struct cdev	  ib_ucm_cdev;
+
+static int __init ib_ucm_init(void)
+{
+	int result;
+
+	result = register_chrdev_region(IB_UCM_DEV, 1, "infiniband_cm");
+	if (result) {
+		ucm_dbg("Error <%d> registering dev\n", result);
+		goto err_chr;
+	}
+
+	cdev_init(&ib_ucm_cdev, &ib_ucm_fops);
+
+	result = cdev_add(&ib_ucm_cdev, IB_UCM_DEV, 1);
+	if (result) {
+ 		ucm_dbg("Error <%d> adding cdev\n", result);
+		goto err_cdev;
+	}
+
+	ib_ucm_class = class_create(THIS_MODULE, "infiniband_cm");
+	if (IS_ERR(ib_ucm_class)) {
+		result = PTR_ERR(ib_ucm_class);
+ 		ucm_dbg("Error <%d> creating class\n", result);
+		goto err_class;
+	}
+
+	class_device_create(ib_ucm_class, IB_UCM_DEV, NULL, "ucm");
+
+	idr_init(&ctx_id_table);
+	init_MUTEX(&ctx_id_mutex);
+
+	return 0;
+err_class:
+	cdev_del(&ib_ucm_cdev);
+err_cdev:
+	unregister_chrdev_region(IB_UCM_DEV, 1);
+err_chr:
+	return result;
+}
+
+static void __exit ib_ucm_cleanup(void)
+{
+	class_device_destroy(ib_ucm_class, IB_UCM_DEV);
+	class_destroy(ib_ucm_class);
+	cdev_del(&ib_ucm_cdev);
+	unregister_chrdev_region(IB_UCM_DEV, 1);
+}
+
+module_init(ib_ucm_init);
+module_exit(ib_ucm_cleanup);
diff --git a/drivers/infiniband/core/ucm.h b/drivers/infiniband/core/ucm.h
new file mode 100644
--- /dev/null
+++ b/drivers/infiniband/core/ucm.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2005 Topspin Communications.  All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * 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 THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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.
+ *
+ * $Id: ucm.h 2208 2005-04-22 23:24:31Z libor $
+ */
+
+#ifndef UCM_H
+#define UCM_H
+
+#include <linux/fs.h>
+#include <linux/device.h>
+#include <linux/cdev.h>
+#include <linux/idr.h>
+
+#include <ib_cm.h>
+#include <ib_user_cm.h>
+
+#define IB_UCM_CM_ID_INVALID 0xffffffff
+
+struct ib_ucm_file {
+	struct semaphore mutex;
+	struct file *filp;
+	/*
+	 * list of pending events
+	 */
+	struct list_head  ctxs;   /* list of active connections */
+	struct list_head  events; /* list of pending events */
+	wait_queue_head_t poll_wait;
+};
+
+struct ib_ucm_context {
+	int                 id;
+	int                 ref;
+	int                 error;
+
+	struct ib_ucm_file *file;
+	struct ib_cm_id    *cm_id;
+	struct semaphore    mutex;
+
+	struct list_head    events;    /* list of pending events. */
+	struct list_head    file_list; /* member in file ctx list */
+};
+
+struct ib_ucm_event {
+	struct ib_ucm_context *ctx;
+	struct list_head file_list; /* member in file event list */
+	struct list_head ctx_list;  /* member in ctx event list */
+
+	struct ib_ucm_event_resp resp;
+	void *data;
+	void *info;
+	int data_len;
+	int info_len;
+	/*
+	 * new connection identifiers needs to be saved until
+	 * userspace can get a handle on them.
+	 */
+	struct ib_cm_id *cm_id;
+};
+
+#endif /* UCM_H */
diff --git a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c
--- a/drivers/infiniband/core/user_mad.c
+++ b/drivers/infiniband/core/user_mad.c
@@ -1,5 +1,7 @@
 /*
  * Copyright (c) 2004 Topspin Communications.  All rights reserved.
+ * Copyright (c) 2005 Voltaire, Inc. All rights reserved.
+ * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
@@ -29,7 +31,7 @@
  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  *
- * $Id: user_mad.c 1389 2004-12-27 22:56:47Z roland $
+ * $Id: user_mad.c 2814 2005-07-06 19:14:09Z halr $
  */
 
 #include <linux/module.h>
@@ -94,10 +96,12 @@ struct ib_umad_file {
 };
 
 struct ib_umad_packet {
-	struct ib_user_mad mad;
 	struct ib_ah      *ah;
+	struct ib_mad_send_buf *msg;
 	struct list_head   list;
+	int		   length;
 	DECLARE_PCI_UNMAP_ADDR(mapping)
+	struct ib_user_mad mad;
 };
 
 static const dev_t base_dev = MKDEV(IB_UMAD_MAJOR, IB_UMAD_MINOR_BASE);
@@ -114,10 +118,10 @@ static int queue_packet(struct ib_umad_f
 	int ret = 1;
 
 	down_read(&file->agent_mutex);
-	for (packet->mad.id = 0;
-	     packet->mad.id < IB_UMAD_MAX_AGENTS;
-	     packet->mad.id++)
-		if (agent == file->agent[packet->mad.id]) {
+	for (packet->mad.hdr.id = 0;
+	     packet->mad.hdr.id < IB_UMAD_MAX_AGENTS;
+	     packet->mad.hdr.id++)
+		if (agent == file->agent[packet->mad.hdr.id]) {
 			spin_lock_irq(&file->recv_lock);
 			list_add_tail(&packet->list, &file->recv_list);
 			spin_unlock_irq(&file->recv_lock);
@@ -135,22 +139,30 @@ static void send_handler(struct ib_mad_a
 			 struct ib_mad_send_wc *send_wc)
 {
 	struct ib_umad_file *file = agent->context;
-	struct ib_umad_packet *packet =
+	struct ib_umad_packet *timeout, *packet =
 		(void *) (unsigned long) send_wc->wr_id;
 
-	dma_unmap_single(agent->device->dma_device,
-			 pci_unmap_addr(packet, mapping),
-			 sizeof packet->mad.data,
-			 DMA_TO_DEVICE);
-	ib_destroy_ah(packet->ah);
+	ib_destroy_ah(packet->msg->send_wr.wr.ud.ah);
+	ib_free_send_mad(packet->msg);
 
 	if (send_wc->status == IB_WC_RESP_TIMEOUT_ERR) {
-		packet->mad.status = ETIMEDOUT;
+		timeout = kmalloc(sizeof *timeout + sizeof (struct ib_mad_hdr),
+				  GFP_KERNEL);
+		if (!timeout)
+			goto out;
+
+		memset(timeout, 0, sizeof *timeout + sizeof (struct ib_mad_hdr));
+
+		timeout->length = sizeof (struct ib_mad_hdr);
+		timeout->mad.hdr.id = packet->mad.hdr.id;
+		timeout->mad.hdr.status = ETIMEDOUT;
+		memcpy(timeout->mad.data, packet->mad.data,
+		       sizeof (struct ib_mad_hdr));
 
-		if (!queue_packet(file, agent, packet))
-			return;
+		if (!queue_packet(file, agent, timeout))
+				return;
 	}
-
+out:
 	kfree(packet);
 }
 
@@ -159,30 +171,35 @@ static void recv_handler(struct ib_mad_a
 {
 	struct ib_umad_file *file = agent->context;
 	struct ib_umad_packet *packet;
+	int length;
 
 	if (mad_recv_wc->wc->status != IB_WC_SUCCESS)
 		goto out;
 
-	packet = kmalloc(sizeof *packet, GFP_KERNEL);
+	length = mad_recv_wc->mad_len;
+	packet = kmalloc(sizeof *packet + length, GFP_KERNEL);
 	if (!packet)
 		goto out;
 
-	memset(packet, 0, sizeof *packet);
+	memset(packet, 0, sizeof *packet + length);
+	packet->length = length;
+
+	ib_coalesce_recv_mad(mad_recv_wc, packet->mad.data);
 
-	memcpy(packet->mad.data, mad_recv_wc->recv_buf.mad, sizeof packet->mad.data);
-	packet->mad.status        = 0;
-	packet->mad.qpn 	  = cpu_to_be32(mad_recv_wc->wc->src_qp);
-	packet->mad.lid 	  = cpu_to_be16(mad_recv_wc->wc->slid);
-	packet->mad.sl  	  = mad_recv_wc->wc->sl;
-	packet->mad.path_bits 	  = mad_recv_wc->wc->dlid_path_bits;
-	packet->mad.grh_present   = !!(mad_recv_wc->wc->wc_flags & IB_WC_GRH);
-	if (packet->mad.grh_present) {
+	packet->mad.hdr.status    = 0;
+	packet->mad.hdr.length    = length + sizeof (struct ib_user_mad);
+	packet->mad.hdr.qpn 	  = cpu_to_be32(mad_recv_wc->wc->src_qp);
+	packet->mad.hdr.lid 	  = cpu_to_be16(mad_recv_wc->wc->slid);
+	packet->mad.hdr.sl  	  = mad_recv_wc->wc->sl;
+	packet->mad.hdr.path_bits = mad_recv_wc->wc->dlid_path_bits;
+	packet->mad.hdr.grh_present = !!(mad_recv_wc->wc->wc_flags & IB_WC_GRH);
+	if (packet->mad.hdr.grh_present) {
 		/* XXX parse GRH */
-		packet->mad.gid_index 	  = 0;
-		packet->mad.hop_limit 	  = 0;
-		packet->mad.traffic_class = 0;
-		memset(packet->mad.gid, 0, 16);
-		packet->mad.flow_label 	  = 0;
+		packet->mad.hdr.gid_index 	= 0;
+		packet->mad.hdr.hop_limit 	= 0;
+		packet->mad.hdr.traffic_class	= 0;
+		memset(packet->mad.hdr.gid, 0, 16);
+		packet->mad.hdr.flow_label	= 0;
 	}
 
 	if (queue_packet(file, agent, packet))
@@ -199,7 +216,7 @@ static ssize_t ib_umad_read(struct file 
 	struct ib_umad_packet *packet;
 	ssize_t ret;
 
-	if (count < sizeof (struct ib_user_mad))
+	if (count < sizeof (struct ib_user_mad) + sizeof (struct ib_mad))
 		return -EINVAL;
 
 	spin_lock_irq(&file->recv_lock);
@@ -222,12 +239,25 @@ static ssize_t ib_umad_read(struct file 
 
 	spin_unlock_irq(&file->recv_lock);
 
-	if (copy_to_user(buf, &packet->mad, sizeof packet->mad))
+	if (count < packet->length + sizeof (struct ib_user_mad)) {
+		/* Return length needed (and first RMPP segment) if too small */
+		if (copy_to_user(buf, &packet->mad,
+				 sizeof (struct ib_user_mad) + sizeof (struct ib_mad)))
+			ret = -EFAULT;
+		else
+			ret = -ENOSPC;
+	} else if (copy_to_user(buf, &packet->mad,
+			      packet->length + sizeof (struct ib_user_mad)))
 		ret = -EFAULT;
 	else
-		ret = sizeof packet->mad;
-
-	kfree(packet);
+		ret = packet->length + sizeof (struct ib_user_mad);
+	if (ret < 0) {
+		/* Requeue packet */
+		spin_lock_irq(&file->recv_lock);
+		list_add(&packet->list, &file->recv_list);
+		spin_unlock_irq(&file->recv_lock);
+	} else
+		kfree(packet);
 	return ret;
 }
 
@@ -238,105 +268,163 @@ static ssize_t ib_umad_write(struct file
 	struct ib_umad_packet *packet;
 	struct ib_mad_agent *agent;
 	struct ib_ah_attr ah_attr;
-	struct ib_sge      gather_list;
-	struct ib_send_wr *bad_wr, wr = {
-		.opcode      = IB_WR_SEND,
-		.sg_list     = &gather_list,
-		.num_sge     = 1,
-		.send_flags  = IB_SEND_SIGNALED,
-	};
+	struct ib_send_wr *bad_wr;
+	struct ib_rmpp_mad *rmpp_mad;
 	u8 method;
 	u64 *tid;
-	int ret;
+	int ret, length, hdr_len, data_len, rmpp_hdr_size;
+	int rmpp_active = 0;
 
 	if (count < sizeof (struct ib_user_mad))
 		return -EINVAL;
 
-	packet = kmalloc(sizeof *packet, GFP_KERNEL);
+	length = count - sizeof (struct ib_user_mad);
+	packet = kmalloc(sizeof *packet + sizeof(struct ib_mad_hdr) +
+			 sizeof(struct ib_rmpp_hdr), GFP_KERNEL);
 	if (!packet)
 		return -ENOMEM;
 
-	if (copy_from_user(&packet->mad, buf, sizeof packet->mad)) {
-		kfree(packet);
-		return -EFAULT;
+	if (copy_from_user(&packet->mad, buf,
+			    sizeof (struct ib_user_mad) +
+			    sizeof(struct ib_mad_hdr) +
+			    sizeof(struct ib_rmpp_hdr))) {
+		ret = -EFAULT;
+		goto err;
 	}
 
-	if (packet->mad.id < 0 || packet->mad.id >= IB_UMAD_MAX_AGENTS) {
+	if (packet->mad.hdr.id < 0 ||
+	    packet->mad.hdr.id >= IB_UMAD_MAX_AGENTS) {
 		ret = -EINVAL;
 		goto err;
 	}
 
+	packet->length = length;
+
 	down_read(&file->agent_mutex);
 
-	agent = file->agent[packet->mad.id];
+	agent = file->agent[packet->mad.hdr.id];
 	if (!agent) {
 		ret = -EINVAL;
 		goto err_up;
 	}
 
+	memset(&ah_attr, 0, sizeof ah_attr);
+	ah_attr.dlid          = be16_to_cpu(packet->mad.hdr.lid);
+	ah_attr.sl            = packet->mad.hdr.sl;
+	ah_attr.src_path_bits = packet->mad.hdr.path_bits;
+	ah_attr.port_num      = file->port->port_num;
+	if (packet->mad.hdr.grh_present) {
+		ah_attr.ah_flags = IB_AH_GRH;
+		memcpy(ah_attr.grh.dgid.raw, packet->mad.hdr.gid, 16);
+		ah_attr.grh.flow_label 	   = packet->mad.hdr.flow_label;
+		ah_attr.grh.hop_limit  	   = packet->mad.hdr.hop_limit;
+		ah_attr.grh.traffic_class  = packet->mad.hdr.traffic_class;
+	}
+
+	packet->ah = ib_create_ah(agent->qp->pd, &ah_attr);
+	if (IS_ERR(packet->ah)) {
+		ret = PTR_ERR(packet->ah);
+		goto err_up;
+	}
+
+	rmpp_mad = (struct ib_rmpp_mad *) packet->mad.data;
+	if (ib_get_rmpp_flags(&rmpp_mad->rmpp_hdr) & IB_MGMT_RMPP_FLAG_ACTIVE) {
+		/* RMPP active */
+		if (!agent->rmpp_version) {
+			ret = -EINVAL;
+			goto err_ah;
+		}
+		/* Validate that management class can support RMPP */
+		if (rmpp_mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_ADM) {
+			hdr_len = offsetof(struct ib_sa_mad, data);
+			data_len = length;
+		} else if ((rmpp_mad->mad_hdr.mgmt_class >= IB_MGMT_CLASS_VENDOR_RANGE2_START) &&
+			    (rmpp_mad->mad_hdr.mgmt_class <= IB_MGMT_CLASS_VENDOR_RANGE2_END)) {
+				hdr_len = offsetof(struct ib_vendor_mad, data);
+				data_len = length - hdr_len;
+		} else {
+			ret = -EINVAL;
+			goto err_ah;
+		}
+		rmpp_active = 1;
+	} else {
+		if (length > sizeof(struct ib_mad)) {
+			ret = -EINVAL;
+			goto err_ah;
+		}
+		hdr_len = offsetof(struct ib_mad, data);
+		data_len = length - hdr_len;
+	}
+
+	packet->msg = ib_create_send_mad(agent,
+					 be32_to_cpu(packet->mad.hdr.qpn),
+					 0, packet->ah, rmpp_active,
+					 hdr_len, data_len,
+					 GFP_KERNEL);
+	if (IS_ERR(packet->msg)) {
+		ret = PTR_ERR(packet->msg);
+		goto err_ah;
+	}
+
+	packet->msg->send_wr.wr.ud.timeout_ms  = packet->mad.hdr.timeout_ms;
+	packet->msg->send_wr.wr.ud.retries = packet->mad.hdr.retries;
+
+	/* Override send WR WRID initialized in ib_create_send_mad */
+	packet->msg->send_wr.wr_id = (unsigned long) packet;
+
+	if (!rmpp_active) {
+		/* Copy message from user into send buffer */
+		if (copy_from_user(packet->msg->mad,
+				   buf + sizeof(struct ib_user_mad), length)) {
+			ret = -EFAULT;
+			goto err_msg;
+		}
+	} else {
+		rmpp_hdr_size = sizeof(struct ib_mad_hdr) +
+				sizeof(struct ib_rmpp_hdr);
+
+		/* Only copy MAD headers (RMPP header in place) */
+		memcpy(packet->msg->mad, packet->mad.data,
+		       sizeof(struct ib_mad_hdr));
+
+		/* Now, copy rest of message from user into send buffer */
+		if (copy_from_user(((struct ib_rmpp_mad *) packet->msg->mad)->data,
+				   buf + sizeof (struct ib_user_mad) + rmpp_hdr_size,
+				   length - rmpp_hdr_size)) {
+			ret = -EFAULT;
+			goto err_msg;
+		}
+	}
+
 	/*
 	 * If userspace is generating a request that will generate a
 	 * response, we need to make sure the high-order part of the
 	 * transaction ID matches the agent being used to send the
 	 * MAD.
 	 */
-	method = ((struct ib_mad_hdr *) packet->mad.data)->method;
+	method = packet->msg->mad->mad_hdr.method;
 
 	if (!(method & IB_MGMT_METHOD_RESP)       &&
 	    method != IB_MGMT_METHOD_TRAP_REPRESS &&
 	    method != IB_MGMT_METHOD_SEND) {
-		tid = &((struct ib_mad_hdr *) packet->mad.data)->tid;
+		tid = &packet->msg->mad->mad_hdr.tid;
 		*tid = cpu_to_be64(((u64) agent->hi_tid) << 32 |
 				   (be64_to_cpup(tid) & 0xffffffff));
 	}
 
-	memset(&ah_attr, 0, sizeof ah_attr);
-	ah_attr.dlid          = be16_to_cpu(packet->mad.lid);
-	ah_attr.sl            = packet->mad.sl;
-	ah_attr.src_path_bits = packet->mad.path_bits;
-	ah_attr.port_num      = file->port->port_num;
-	if (packet->mad.grh_present) {
-		ah_attr.ah_flags = IB_AH_GRH;
-		memcpy(ah_attr.grh.dgid.raw, packet->mad.gid, 16);
-		ah_attr.grh.flow_label 	   = packet->mad.flow_label;
-		ah_attr.grh.hop_limit  	   = packet->mad.hop_limit;
-		ah_attr.grh.traffic_class  = packet->mad.traffic_class;
-	}
-
-	packet->ah = ib_create_ah(agent->qp->pd, &ah_attr);
-	if (IS_ERR(packet->ah)) {
-		ret = PTR_ERR(packet->ah);
-		goto err_up;
-	}
+	ret = ib_post_send_mad(agent, &packet->msg->send_wr, &bad_wr);
+	if (ret)
+		goto err_msg;
 
-	gather_list.addr = dma_map_single(agent->device->dma_device,
-					  packet->mad.data,
-					  sizeof packet->mad.data,
-					  DMA_TO_DEVICE);
-	gather_list.length = sizeof packet->mad.data;
-	gather_list.lkey   = file->mr[packet->mad.id]->lkey;
-	pci_unmap_addr_set(packet, mapping, gather_list.addr);
-
-	wr.wr.ud.mad_hdr     = (struct ib_mad_hdr *) packet->mad.data;
-	wr.wr.ud.ah          = packet->ah;
-	wr.wr.ud.remote_qpn  = be32_to_cpu(packet->mad.qpn);
-	wr.wr.ud.remote_qkey = be32_to_cpu(packet->mad.qkey);
-	wr.wr.ud.timeout_ms  = packet->mad.timeout_ms;
+	up_read(&file->agent_mutex);
 
-	wr.wr_id            = (unsigned long) packet;
+	return sizeof (struct ib_user_mad_hdr) + packet->length;
 
-	ret = ib_post_send_mad(agent, &wr, &bad_wr);
-	if (ret) {
-		dma_unmap_single(agent->device->dma_device,
-				 pci_unmap_addr(packet, mapping),
-				 sizeof packet->mad.data,
-				 DMA_TO_DEVICE);
-		goto err_up;
-	}
+err_msg:
+	ib_free_send_mad(packet->msg);
 
-	up_read(&file->agent_mutex);
-
-	return sizeof packet->mad;
+err_ah:
+	ib_destroy_ah(packet->ah);
 
 err_up:
 	up_read(&file->agent_mutex);
@@ -399,7 +487,8 @@ found:
 	agent = ib_register_mad_agent(file->port->ib_dev, file->port->port_num,
 				      ureq.qpn ? IB_QPT_GSI : IB_QPT_SMI,
 				      ureq.mgmt_class ? &req : NULL,
-				      0, send_handler, recv_handler, file);
+				      ureq.rmpp_version,
+				      send_handler, recv_handler, file);
 	if (IS_ERR(agent)) {
 		ret = PTR_ERR(agent);
 		goto out;
@@ -460,8 +549,8 @@ out:
 	return ret;
 }
 
-static long ib_umad_ioctl(struct file *filp,
-			 unsigned int cmd, unsigned long arg)
+static long ib_umad_ioctl(struct file *filp, unsigned int cmd,
+			  unsigned long arg)
 {
 	switch (cmd) {
 	case IB_USER_MAD_REGISTER_AGENT:
@@ -517,14 +606,14 @@ static int ib_umad_close(struct inode *i
 }
 
 static struct file_operations umad_fops = {
-	.owner 	        = THIS_MODULE,
-	.read 	        = ib_umad_read,
-	.write 	        = ib_umad_write,
-	.poll 	        = ib_umad_poll,
+	.owner 	 	= THIS_MODULE,
+	.read 	 	= ib_umad_read,
+	.write 	 	= ib_umad_write,
+	.poll 	 	= ib_umad_poll,
 	.unlocked_ioctl = ib_umad_ioctl,
-	.compat_ioctl   = ib_umad_ioctl,
-	.open 	        = ib_umad_open,
-	.release        = ib_umad_close
+	.compat_ioctl 	= ib_umad_ioctl,
+	.open 	 	= ib_umad_open,
+	.release 	= ib_umad_close
 };
 
 static int ib_umad_sm_open(struct inode *inode, struct file *filp)
diff --git a/drivers/infiniband/core/uverbs.h b/drivers/infiniband/core/uverbs.h
new file mode 100644
--- /dev/null
+++ b/drivers/infiniband/core/uverbs.h
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2005 Topspin Communications.  All rights reserved.
+ * Copyright (c) 2005 Cisco Systems.  All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * 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 THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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.
+ *
+ * $Id: uverbs.h 2559 2005-06-06 19:43:16Z roland $
+ */
+
+#ifndef UVERBS_H
+#define UVERBS_H
+
+/* Include device.h and fs.h until cdev.h is self-sufficient */
+#include <linux/fs.h>
+#include <linux/device.h>
+#include <linux/cdev.h>
+#include <linux/kref.h>
+#include <linux/idr.h>
+
+#include <ib_verbs.h>
+#include <ib_user_verbs.h>
+
+struct ib_uverbs_device {
+	int					devnum;
+	struct cdev				dev;
+	struct class_device			class_dev;
+	struct ib_device		       *ib_dev;
+	int					num_comp;
+};
+
+struct ib_uverbs_event_file {
+	struct kref				ref;
+	struct ib_uverbs_file		       *uverbs_file;
+	spinlock_t				lock;
+	int					fd;
+	int					is_async;
+	wait_queue_head_t			poll_wait;
+	struct fasync_struct		       *async_queue;
+	struct list_head			event_list;
+};
+
+struct ib_uverbs_file {
+	struct kref				ref;
+	struct ib_uverbs_device		       *device;
+	struct ib_ucontext		       *ucontext;
+	struct ib_event_handler			event_handler;
+	struct ib_uverbs_event_file	        async_file;
+	struct ib_uverbs_event_file	        comp_file[1];
+};
+
+struct ib_uverbs_async_event {
+	struct ib_uverbs_async_event_desc	desc;
+	struct list_head			list;
+};
+
+struct ib_uverbs_comp_event {
+	struct ib_uverbs_comp_event_desc	desc;
+	struct list_head			list;
+};
+
+struct ib_uobject_mr {
+	struct ib_uobject			uobj;
+	struct page			       *page_list;
+	struct scatterlist		       *sg_list;
+};
+
+extern struct semaphore ib_uverbs_idr_mutex;
+extern struct idr ib_uverbs_pd_idr;
+extern struct idr ib_uverbs_mr_idr;
+extern struct idr ib_uverbs_mw_idr;
+extern struct idr ib_uverbs_ah_idr;
+extern struct idr ib_uverbs_cq_idr;
+extern struct idr ib_uverbs_qp_idr;
+
+void ib_uverbs_comp_handler(struct ib_cq *cq, void *cq_context);
+void ib_uverbs_cq_event_handler(struct ib_event *event, void *context_ptr);
+void ib_uverbs_qp_event_handler(struct ib_event *event, void *context_ptr);
+
+int ib_umem_get(struct ib_device *dev, struct ib_umem *mem,
+		void *addr, size_t size, int write);
+void ib_umem_release(struct ib_device *dev, struct ib_umem *umem);
+void ib_umem_release_on_close(struct ib_device *dev, struct ib_umem *umem);
+
+#define IB_UVERBS_DECLARE_CMD(name)					\
+	ssize_t ib_uverbs_##name(struct ib_uverbs_file *file,		\
+				 const char __user *buf, int in_len,	\
+				 int out_len)
+
+IB_UVERBS_DECLARE_CMD(query_params);
+IB_UVERBS_DECLARE_CMD(get_context);
+IB_UVERBS_DECLARE_CMD(query_device);
+IB_UVERBS_DECLARE_CMD(query_port);
+IB_UVERBS_DECLARE_CMD(query_gid);
+IB_UVERBS_DECLARE_CMD(query_pkey);
+IB_UVERBS_DECLARE_CMD(alloc_pd);
+IB_UVERBS_DECLARE_CMD(dealloc_pd);
+IB_UVERBS_DECLARE_CMD(reg_mr);
+IB_UVERBS_DECLARE_CMD(dereg_mr);
+IB_UVERBS_DECLARE_CMD(create_cq);
+IB_UVERBS_DECLARE_CMD(destroy_cq);
+IB_UVERBS_DECLARE_CMD(create_qp);
+IB_UVERBS_DECLARE_CMD(modify_qp);
+IB_UVERBS_DECLARE_CMD(destroy_qp);
+IB_UVERBS_DECLARE_CMD(attach_mcast);
+IB_UVERBS_DECLARE_CMD(detach_mcast);
+
+#endif /* UVERBS_H */
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c
new file mode 100644
--- /dev/null
+++ b/drivers/infiniband/core/uverbs_cmd.c
@@ -0,0 +1,1006 @@
+/*
+ * Copyright (c) 2005 Topspin Communications.  All rights reserved.
+ * Copyright (c) 2005 Cisco Systems.  All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * 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 THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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.
+ *
+ * $Id: uverbs_cmd.c 2708 2005-06-24 17:27:21Z roland $
+ */
+
+#include <asm/uaccess.h>
+
+#include "uverbs.h"
+
+#define INIT_UDATA(udata, ibuf, obuf, ilen, olen)			\
+	do {								\
+		(udata)->inbuf  = (void __user *) (ibuf);		\
+		(udata)->outbuf = (void __user *) (obuf);		\
+		(udata)->inlen  = (ilen);				\
+		(udata)->outlen = (olen);				\
+	} while (0)
+
+ssize_t ib_uverbs_query_params(struct ib_uverbs_file *file,
+			       const char __user *buf,
+			       int in_len, int out_len)
+{
+	struct ib_uverbs_query_params      cmd;
+	struct ib_uverbs_query_params_resp resp;
+
+	if (out_len < sizeof resp)
+		return -ENOSPC;
+
+	if (copy_from_user(&cmd, buf, sizeof cmd))
+		return -EFAULT;
+
+	memset(&resp, 0, sizeof resp);
+
+	resp.num_cq_events = file->device->num_comp;
+
+	if (copy_to_user((void __user *) (unsigned long) cmd.response, &resp, sizeof resp))
+	    return -EFAULT;
+
+	return in_len;
+}
+
+ssize_t ib_uverbs_get_context(struct ib_uverbs_file *file,
+			      const char __user *buf,
+			      int in_len, int out_len)
+{
+	struct ib_uverbs_get_context      cmd;
+	struct ib_uverbs_get_context_resp resp;
+	struct ib_udata                   udata;
+	struct ib_device                 *ibdev = file->device->ib_dev;
+	int i;
+	int ret = in_len;
+
+	if (out_len < sizeof resp)
+		return -ENOSPC;
+
+	if (copy_from_user(&cmd, buf, sizeof cmd))
+		return -EFAULT;
+
+	INIT_UDATA(&udata, buf + sizeof cmd,
+		   (unsigned long) cmd.response + sizeof resp,
+		   in_len - sizeof cmd, out_len - sizeof resp);
+
+	file->ucontext = ibdev->alloc_ucontext(ibdev, &udata);
+	if (IS_ERR(file->ucontext)) {
+		ret = PTR_ERR(file->ucontext);
+		file->ucontext = NULL;
+		return ret;
+	}
+
+	file->ucontext->device = ibdev;
+	INIT_LIST_HEAD(&file->ucontext->pd_list);
+	INIT_LIST_HEAD(&file->ucontext->mr_list);
+	INIT_LIST_HEAD(&file->ucontext->mw_list);
+	INIT_LIST_HEAD(&file->ucontext->cq_list);
+	INIT_LIST_HEAD(&file->ucontext->qp_list);
+	INIT_LIST_HEAD(&file->ucontext->srq_list);
+	INIT_LIST_HEAD(&file->ucontext->ah_list);
+	spin_lock_init(&file->ucontext->lock);
+
+	resp.async_fd = file->async_file.fd;
+	for (i = 0; i < file->device->num_comp; ++i)
+		if (copy_to_user((void __user *) (unsigned long) cmd.cq_fd_tab +
+				 i * sizeof (__u32),
+				 &file->comp_file[i].fd, sizeof (__u32)))
+			goto err;
+
+	if (copy_to_user((void __user *) (unsigned long) cmd.response,
+			 &resp, sizeof resp))
+		goto err;
+
+	return in_len;
+
+err:
+	ibdev->dealloc_ucontext(file->ucontext);
+	file->ucontext = NULL;
+
+	return -EFAULT;
+}
+
+ssize_t ib_uverbs_query_device(struct ib_uverbs_file *file,
+			       const char __user *buf,
+			       int in_len, int out_len)
+{
+	struct ib_uverbs_query_device      cmd;
+	struct ib_uverbs_query_device_resp resp;
+	struct ib_device_attr              attr;
+	int                                ret;
+
+	if (out_len < sizeof resp)
+		return -ENOSPC;
+
+	if (copy_from_user(&cmd, buf, sizeof cmd))
+		return -EFAULT;
+
+	ret = ib_query_device(file->device->ib_dev, &attr);
+	if (ret)
+		return ret;
+
+	memset(&resp, 0, sizeof resp);
+
+	resp.fw_ver 		       = attr.fw_ver;
+	resp.node_guid 		       = attr.node_guid;
+	resp.sys_image_guid 	       = attr.sys_image_guid;
+	resp.max_mr_size 	       = attr.max_mr_size;
+	resp.page_size_cap 	       = attr.page_size_cap;
+	resp.vendor_id 		       = attr.vendor_id;
+	resp.vendor_part_id 	       = attr.vendor_part_id;
+	resp.hw_ver 		       = attr.hw_ver;
+	resp.max_qp 		       = attr.max_qp;
+	resp.max_qp_wr 		       = attr.max_qp_wr;
+	resp.device_cap_flags 	       = attr.device_cap_flags;
+	resp.max_sge 		       = attr.max_sge;
+	resp.max_sge_rd 	       = attr.max_sge_rd;
+	resp.max_cq 		       = attr.max_cq;
+	resp.max_cqe 		       = attr.max_cqe;
+	resp.max_mr 		       = attr.max_mr;
+	resp.max_pd 		       = attr.max_pd;
+	resp.max_qp_rd_atom 	       = attr.max_qp_rd_atom;
+	resp.max_ee_rd_atom 	       = attr.max_ee_rd_atom;
+	resp.max_res_rd_atom 	       = attr.max_res_rd_atom;
+	resp.max_qp_init_rd_atom       = attr.max_qp_init_rd_atom;
+	resp.max_ee_init_rd_atom       = attr.max_ee_init_rd_atom;
+	resp.atomic_cap 	       = attr.atomic_cap;
+	resp.max_ee 		       = attr.max_ee;
+	resp.max_rdd 		       = attr.max_rdd;
+	resp.max_mw 		       = attr.max_mw;
+	resp.max_raw_ipv6_qp 	       = attr.max_raw_ipv6_qp;
+	resp.max_raw_ethy_qp 	       = attr.max_raw_ethy_qp;
+	resp.max_mcast_grp 	       = attr.max_mcast_grp;
+	resp.max_mcast_qp_attach       = attr.max_mcast_qp_attach;
+	resp.max_total_mcast_qp_attach = attr.max_total_mcast_qp_attach;
+	resp.max_ah 		       = attr.max_ah;
+	resp.max_fmr 		       = attr.max_fmr;
+	resp.max_map_per_fmr 	       = attr.max_map_per_fmr;
+	resp.max_srq 		       = attr.max_srq;
+	resp.max_srq_wr 	       = attr.max_srq_wr;
+	resp.max_srq_sge 	       = attr.max_srq_sge;
+	resp.max_pkeys 		       = attr.max_pkeys;
+	resp.local_ca_ack_delay        = attr.local_ca_ack_delay;
+	resp.phys_port_cnt	       = file->device->ib_dev->phys_port_cnt;
+
+	if (copy_to_user((void __user *) (unsigned long) cmd.response,
+			 &resp, sizeof resp))
+		return -EFAULT;
+
+	return in_len;
+}
+
+ssize_t ib_uverbs_query_port(struct ib_uverbs_file *file,
+			     const char __user *buf,
+			     int in_len, int out_len)
+{
+	struct ib_uverbs_query_port      cmd;
+	struct ib_uverbs_query_port_resp resp;
+	struct ib_port_attr              attr;
+	int                              ret;
+
+	if (out_len < sizeof resp)
+		return -ENOSPC;
+
+	if (copy_from_user(&cmd, buf, sizeof cmd))
+		return -EFAULT;
+
+	ret = ib_query_port(file->device->ib_dev, cmd.port_num, &attr);
+	if (ret)
+		return ret;
+
+	memset(&resp, 0, sizeof resp);
+
+	resp.state 	     = attr.state;
+	resp.max_mtu 	     = attr.max_mtu;
+	resp.active_mtu      = attr.active_mtu;
+	resp.gid_tbl_len     = attr.gid_tbl_len;
+	resp.port_cap_flags  = attr.port_cap_flags;
+	resp.max_msg_sz      = attr.max_msg_sz;
+	resp.bad_pkey_cntr   = attr.bad_pkey_cntr;
+	resp.qkey_viol_cntr  = attr.qkey_viol_cntr;
+	resp.pkey_tbl_len    = attr.pkey_tbl_len;
+	resp.lid 	     = attr.lid;
+	resp.sm_lid 	     = attr.sm_lid;
+	resp.lmc 	     = attr.lmc;
+	resp.max_vl_num      = attr.max_vl_num;
+	resp.sm_sl 	     = attr.sm_sl;
+	resp.subnet_timeout  = attr.subnet_timeout;
+	resp.init_type_reply = attr.init_type_reply;
+	resp.active_width    = attr.active_width;
+	resp.active_speed    = attr.active_speed;
+	resp.phys_state      = attr.phys_state;
+
+	if (copy_to_user((void __user *) (unsigned long) cmd.response,
+			 &resp, sizeof resp))
+		return -EFAULT;
+
+	return in_len;
+}
+
+ssize_t ib_uverbs_query_gid(struct ib_uverbs_file *file,
+			    const char __user *buf,
+			    int in_len, int out_len)
+{
+	struct ib_uverbs_query_gid      cmd;
+	struct ib_uverbs_query_gid_resp resp;
+	int                             ret;
+
+	if (out_len < sizeof resp)
+		return -ENOSPC;
+
+	if (copy_from_user(&cmd, buf, sizeof cmd))
+		return -EFAULT;
+
+	memset(&resp, 0, sizeof resp);
+
+	ret = ib_query_gid(file->device->ib_dev, cmd.port_num, cmd.index,
+			   (union ib_gid *) resp.gid);
+	if (ret)
+		return ret;
+
+	if (copy_to_user((void __user *) (unsigned long) cmd.response,
+			 &resp, sizeof resp))
+		return -EFAULT;
+
+	return in_len;
+}
+
+ssize_t ib_uverbs_query_pkey(struct ib_uverbs_file *file,
+			     const char __user *buf,
+			     int in_len, int out_len)
+{
+	struct ib_uverbs_query_pkey      cmd;
+	struct ib_uverbs_query_pkey_resp resp;
+	int                              ret;
+
+	if (out_len < sizeof resp)
+		return -ENOSPC;
+
+	if (copy_from_user(&cmd, buf, sizeof cmd))
+		return -EFAULT;
+
+	memset(&resp, 0, sizeof resp);
+
+	ret = ib_query_pkey(file->device->ib_dev, cmd.port_num, cmd.index,
+			    &resp.pkey);
+	if (ret)
+		return ret;
+
+	if (copy_to_user((void __user *) (unsigned long) cmd.response,
+			 &resp, sizeof resp))
+		return -EFAULT;
+
+	return in_len;
+}
+
+ssize_t ib_uverbs_alloc_pd(struct ib_uverbs_file *file,
+			   const char __user *buf,
+			   int in_len, int out_len)
+{
+	struct ib_uverbs_alloc_pd      cmd;
+	struct ib_uverbs_alloc_pd_resp resp;
+	struct ib_udata                udata;
+	struct ib_uobject             *uobj;
+	struct ib_pd                  *pd;
+	int                            ret;
+
+	if (out_len < sizeof resp)
+		return -ENOSPC;
+
+	if (copy_from_user(&cmd, buf, sizeof cmd))
+		return -EFAULT;
+
+	INIT_UDATA(&udata, buf + sizeof cmd,
+		   (unsigned long) cmd.response + sizeof resp,
+		   in_len - sizeof cmd, out_len - sizeof resp);
+
+	uobj = kmalloc(sizeof *uobj, GFP_KERNEL);
+	if (!uobj)
+		return -ENOMEM;
+
+	uobj->context = file->ucontext;
+
+	pd = file->device->ib_dev->alloc_pd(file->device->ib_dev,
+					    file->ucontext, &udata);
+	if (IS_ERR(pd)) {
+		ret = PTR_ERR(pd);
+		goto err;
+	}
+
+	pd->device  = file->device->ib_dev;
+	pd->uobject = uobj;
+	atomic_set(&pd->usecnt, 0);
+
+retry:
+	if (!idr_pre_get(&ib_uverbs_pd_idr, GFP_KERNEL)) {
+		ret = -ENOMEM;
+		goto err_pd;
+	}
+
+	down(&ib_uverbs_idr_mutex);
+	ret = idr_get_new(&ib_uverbs_pd_idr, pd, &uobj->id);
+	up(&ib_uverbs_idr_mutex);
+
+	if (ret == -EAGAIN)
+		goto retry;
+	if (ret)
+		goto err_pd;
+
+	spin_lock_irq(&file->ucontext->lock);
+	list_add_tail(&uobj->list, &file->ucontext->pd_list);
+	spin_unlock_irq(&file->ucontext->lock);
+
+	memset(&resp, 0, sizeof resp);
+	resp.pd_handle = uobj->id;
+
+	if (copy_to_user((void __user *) (unsigned long) cmd.response,
+			 &resp, sizeof resp)) {
+		ret = -EFAULT;
+		goto err_list;
+	}
+
+	return in_len;
+
+err_list:
+ 	spin_lock_irq(&file->ucontext->lock);
+	list_del(&uobj->list);
+	spin_unlock_irq(&file->ucontext->lock);
+
+	down(&ib_uverbs_idr_mutex);
+	idr_remove(&ib_uverbs_pd_idr, uobj->id);
+	up(&ib_uverbs_idr_mutex);
+
+err_pd:
+	ib_dealloc_pd(pd);
+
+err:
+	kfree(uobj);
+	return ret;
+}
+
+ssize_t ib_uverbs_dealloc_pd(struct ib_uverbs_file *file,
+			     const char __user *buf,
+			     int in_len, int out_len)
+{
+	struct ib_uverbs_dealloc_pd cmd;
+	struct ib_pd               *pd;
+	struct ib_uobject          *uobj;
+	int                         ret = -EINVAL;
+
+	if (copy_from_user(&cmd, buf, sizeof cmd))
+		return -EFAULT;
+
+	down(&ib_uverbs_idr_mutex);
+
+	pd = idr_find(&ib_uverbs_pd_idr, cmd.pd_handle);
+	if (!pd || pd->uobject->context != file->ucontext)
+		goto out;
+
+	uobj = pd->uobject;
+
+	ret = ib_dealloc_pd(pd);
+	if (ret)
+		goto out;
+
+	idr_remove(&ib_uverbs_pd_idr, cmd.pd_handle);
+
+	spin_lock_irq(&file->ucontext->lock);
+	list_del(&uobj->list);
+	spin_unlock_irq(&file->ucontext->lock);
+
+	kfree(uobj);
+
+out:
+	up(&ib_uverbs_idr_mutex);
+
+	return ret ? ret : in_len;
+}
+
+ssize_t ib_uverbs_reg_mr(struct ib_uverbs_file *file,
+			 const char __user *buf, int in_len,
+			 int out_len)
+{
+	struct ib_uverbs_reg_mr      cmd;
+	struct ib_uverbs_reg_mr_resp resp;
+	struct ib_udata              udata;
+	struct ib_umem_object       *obj;
+	struct ib_pd                *pd;
+	struct ib_mr                *mr;
+	int                          ret;
+
+	if (out_len < sizeof resp)
+		return -ENOSPC;
+
+	if (copy_from_user(&cmd, buf, sizeof cmd))
+		return -EFAULT;
+
+	INIT_UDATA(&udata, buf + sizeof cmd,
+		   (unsigned long) cmd.response + sizeof resp,
+		   in_len - sizeof cmd, out_len - sizeof resp);
+
+	if ((cmd.start & ~PAGE_MASK) != (cmd.hca_va & ~PAGE_MASK))
+		return -EINVAL;
+
+	obj = kmalloc(sizeof *obj, GFP_KERNEL);
+	if (!obj)
+		return -ENOMEM;
+
+	obj->uobject.context = file->ucontext;
+
+	/*
+	 * We ask for writable memory if any access flags other than
+	 * "remote read" are set.  "Local write" and "remote write"
+	 * obviously require write access.  "Remote atomic" can do
+	 * things like fetch and add, which will modify memory, and
+	 * "MW bind" can change permissions by binding a window.
+	 */
+	ret = ib_umem_get(file->device->ib_dev, &obj->umem,
+			  (void *) (unsigned long) cmd.start, cmd.length,
+			  !!(cmd.access_flags & ~IB_ACCESS_REMOTE_READ));
+	if (ret)
+		goto err_free;
+
+	obj->umem.virt_base = cmd.hca_va;
+
+	down(&ib_uverbs_idr_mutex);
+
+	pd = idr_find(&ib_uverbs_pd_idr, cmd.pd_handle);
+	if (!pd || pd->uobject->context != file->ucontext) {
+		ret = -EINVAL;
+		goto err_up;
+	}
+
+	if (!pd->device->reg_user_mr) {
+		ret = -ENOSYS;
+		goto err_up;
+	}
+
+	mr = pd->device->reg_user_mr(pd, &obj->umem, cmd.access_flags, &udata);
+	if (IS_ERR(mr)) {
+		ret = PTR_ERR(mr);
+		goto err_up;
+	}
+
+	mr->device  = pd->device;
+	mr->pd      = pd;
+	mr->uobject = &obj->uobject;
+	atomic_inc(&pd->usecnt);
+	atomic_set(&mr->usecnt, 0);
+
+	memset(&resp, 0, sizeof resp);
+	resp.lkey = mr->lkey;
+	resp.rkey = mr->rkey;
+
+retry:
+	if (!idr_pre_get(&ib_uverbs_mr_idr, GFP_KERNEL)) {
+		ret = -ENOMEM;
+		goto err_unreg;
+	}
+
+	ret = idr_get_new(&ib_uverbs_mr_idr, mr, &obj->uobject.id);
+
+	if (ret == -EAGAIN)
+		goto retry;
+	if (ret)
+		goto err_unreg;
+
+	resp.mr_handle = obj->uobject.id;
+
+	spin_lock_irq(&file->ucontext->lock);
+	list_add_tail(&obj->uobject.list, &file->ucontext->mr_list);
+	spin_unlock_irq(&file->ucontext->lock);
+
+	if (copy_to_user((void __user *) (unsigned long) cmd.response,
+			 &resp, sizeof resp)) {
+		ret = -EFAULT;
+		goto err_list;
+	}
+
+	up(&ib_uverbs_idr_mutex);
+
+	return in_len;
+
+err_list:
+	spin_lock_irq(&file->ucontext->lock);
+	list_del(&obj->uobject.list);
+	spin_unlock_irq(&file->ucontext->lock);
+
+err_unreg:
+	ib_dereg_mr(mr);
+
+err_up:
+	up(&ib_uverbs_idr_mutex);
+
+	ib_umem_release(file->device->ib_dev, &obj->umem);
+
+err_free:
+	kfree(obj);
+	return ret;
+}
+
+ssize_t ib_uverbs_dereg_mr(struct ib_uverbs_file *file,
+			   const char __user *buf, int in_len,
+			   int out_len)
+{
+	struct ib_uverbs_dereg_mr cmd;
+	struct ib_mr             *mr;
+	struct ib_umem_object    *memobj;
+	int                       ret = -EINVAL;
+
+	if (copy_from_user(&cmd, buf, sizeof cmd))
+		return -EFAULT;
+
+	down(&ib_uverbs_idr_mutex);
+
+	mr = idr_find(&ib_uverbs_mr_idr, cmd.mr_handle);
+	if (!mr || mr->uobject->context != file->ucontext)
+		goto out;
+
+	memobj = container_of(mr->uobject, struct ib_umem_object, uobject);
+
+	ret = ib_dereg_mr(mr);
+	if (ret)
+		goto out;
+
+	idr_remove(&ib_uverbs_mr_idr, cmd.mr_handle);
+
+	spin_lock_irq(&file->ucontext->lock);
+	list_del(&memobj->uobject.list);
+	spin_unlock_irq(&file->ucontext->lock);
+
+	ib_umem_release(file->device->ib_dev, &memobj->umem);
+	kfree(memobj);
+
+out:
+	up(&ib_uverbs_idr_mutex);
+
+	return ret ? ret : in_len;
+}
+
+ssize_t ib_uverbs_create_cq(struct ib_uverbs_file *file,
+			    const char __user *buf, int in_len,
+			    int out_len)
+{
+	struct ib_uverbs_create_cq      cmd;
+	struct ib_uverbs_create_cq_resp resp;
+	struct ib_udata                 udata;
+	struct ib_uobject              *uobj;
+	struct ib_cq                   *cq;
+	int                             ret;
+
+	if (out_len < sizeof resp)
+		return -ENOSPC;
+
+	if (copy_from_user(&cmd, buf, sizeof cmd))
+		return -EFAULT;
+
+	INIT_UDATA(&udata, buf + sizeof cmd,
+		   (unsigned long) cmd.response + sizeof resp,
+		   in_len - sizeof cmd, out_len - sizeof resp);
+
+	if (cmd.event_handler >= file->device->num_comp)
+		return -EINVAL;
+
+	uobj = kmalloc(sizeof *uobj, GFP_KERNEL);
+	if (!uobj)
+		return -ENOMEM;
+
+	uobj->user_handle = cmd.user_handle;
+	uobj->context     = file->ucontext;
+
+	cq = file->device->ib_dev->create_cq(file->device->ib_dev, cmd.cqe,
+					     file->ucontext, &udata);
+	if (IS_ERR(cq)) {
+		ret = PTR_ERR(cq);
+		goto err;
+	}
+
+	cq->device        = file->device->ib_dev;
+	cq->uobject       = uobj;
+	cq->comp_handler  = ib_uverbs_comp_handler;
+	cq->event_handler = ib_uverbs_cq_event_handler;
+	cq->cq_context    = file;
+	atomic_set(&cq->usecnt, 0);
+
+retry:
+	if (!idr_pre_get(&ib_uverbs_cq_idr, GFP_KERNEL)) {
+		ret = -ENOMEM;
+		goto err_cq;
+	}
+
+	down(&ib_uverbs_idr_mutex);
+	ret = idr_get_new(&ib_uverbs_cq_idr, cq, &uobj->id);
+	up(&ib_uverbs_idr_mutex);
+
+	if (ret == -EAGAIN)
+		goto retry;
+	if (ret)
+		goto err_cq;
+
+	spin_lock_irq(&file->ucontext->lock);
+	list_add_tail(&uobj->list, &file->ucontext->cq_list);
+	spin_unlock_irq(&file->ucontext->lock);
+
+	memset(&resp, 0, sizeof resp);
+	resp.cq_handle = uobj->id;
+	resp.cqe       = cq->cqe;
+
+	if (copy_to_user((void __user *) (unsigned long) cmd.response,
+			 &resp, sizeof resp)) {
+		ret = -EFAULT;
+		goto err_list;
+	}
+
+	return in_len;
+
+err_list:
+ 	spin_lock_irq(&file->ucontext->lock);
+	list_del(&uobj->list);
+	spin_unlock_irq(&file->ucontext->lock);
+
+	down(&ib_uverbs_idr_mutex);
+	idr_remove(&ib_uverbs_cq_idr, uobj->id);
+	up(&ib_uverbs_idr_mutex);
+
+err_cq:
+	ib_destroy_cq(cq);
+
+err:
+	kfree(uobj);
+	return ret;
+}
+
+ssize_t ib_uverbs_destroy_cq(struct ib_uverbs_file *file,
+			     const char __user *buf, int in_len,
+			     int out_len)
+{
+	struct ib_uverbs_destroy_cq cmd;
+	struct ib_cq               *cq;
+	struct ib_uobject          *uobj;
+	int                         ret = -EINVAL;
+
+	if (copy_from_user(&cmd, buf, sizeof cmd))
+		return -EFAULT;
+
+	down(&ib_uverbs_idr_mutex);
+
+	cq = idr_find(&ib_uverbs_cq_idr, cmd.cq_handle);
+	if (!cq || cq->uobject->context != file->ucontext)
+		goto out;
+
+	uobj = cq->uobject;
+
+	ret = ib_destroy_cq(cq);
+	if (ret)
+		goto out;
+
+	idr_remove(&ib_uverbs_cq_idr, cmd.cq_handle);
+
+	spin_lock_irq(&file->ucontext->lock);
+	list_del(&uobj->list);
+	spin_unlock_irq(&file->ucontext->lock);
+
+	kfree(uobj);
+
+out:
+	up(&ib_uverbs_idr_mutex);
+
+	return ret ? ret : in_len;
+}
+
+ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file,
+			    const char __user *buf, int in_len,
+			    int out_len)
+{
+	struct ib_uverbs_create_qp      cmd;
+	struct ib_uverbs_create_qp_resp resp;
+	struct ib_udata                 udata;
+	struct ib_uobject              *uobj;
+	struct ib_pd                   *pd;
+	struct ib_cq                   *scq, *rcq;
+	struct ib_qp                   *qp;
+	struct ib_qp_init_attr          attr;
+	int ret;
+
+	if (out_len < sizeof resp)
+		return -ENOSPC;
+
+	if (copy_from_user(&cmd, buf, sizeof cmd))
+		return -EFAULT;
+
+	INIT_UDATA(&udata, buf + sizeof cmd,
+		   (unsigned long) cmd.response + sizeof resp,
+		   in_len - sizeof cmd, out_len - sizeof resp);
+
+	uobj = kmalloc(sizeof *uobj, GFP_KERNEL);
+	if (!uobj)
+		return -ENOMEM;
+
+	down(&ib_uverbs_idr_mutex);
+
+	pd  = idr_find(&ib_uverbs_pd_idr, cmd.pd_handle);
+	scq = idr_find(&ib_uverbs_cq_idr, cmd.send_cq_handle);
+	rcq = idr_find(&ib_uverbs_cq_idr, cmd.recv_cq_handle);
+
+	if (!pd  || pd->uobject->context  != file->ucontext ||
+	    !scq || scq->uobject->context != file->ucontext ||
+	    !rcq || rcq->uobject->context != file->ucontext) {
+		ret = -EINVAL;
+		goto err_up;
+	}
+
+	attr.event_handler = ib_uverbs_qp_event_handler;
+	attr.qp_context    = file;
+	attr.send_cq       = scq;
+	attr.recv_cq       = rcq;
+	attr.srq           = NULL;
+	attr.sq_sig_type   = cmd.sq_sig_all ? IB_SIGNAL_ALL_WR : IB_SIGNAL_REQ_WR;
+	attr.qp_type       = cmd.qp_type;
+
+	attr.cap.max_send_wr     = cmd.max_send_wr;
+	attr.cap.max_recv_wr     = cmd.max_recv_wr;
+	attr.cap.max_send_sge    = cmd.max_send_sge;
+	attr.cap.max_recv_sge    = cmd.max_recv_sge;
+	attr.cap.max_inline_data = cmd.max_inline_data;
+
+	uobj->user_handle = cmd.user_handle;
+	uobj->context     = file->ucontext;
+
+	qp = pd->device->create_qp(pd, &attr, &udata);
+	if (IS_ERR(qp)) {
+		ret = PTR_ERR(qp);
+		goto err_up;
+	}
+
+	qp->device     	  = pd->device;
+	qp->pd         	  = pd;
+	qp->send_cq    	  = attr.send_cq;
+	qp->recv_cq    	  = attr.recv_cq;
+	qp->srq	       	  = attr.srq;
+	qp->uobject       = uobj;
+	qp->event_handler = attr.event_handler;
+	qp->qp_context    = attr.qp_context;
+	qp->qp_type	  = attr.qp_type;
+	atomic_inc(&pd->usecnt);
+	atomic_inc(&attr.send_cq->usecnt);
+	atomic_inc(&attr.recv_cq->usecnt);
+	if (attr.srq)
+		atomic_inc(&attr.srq->usecnt);
+
+	memset(&resp, 0, sizeof resp);
+	resp.qpn = qp->qp_num;
+
+retry:
+	if (!idr_pre_get(&ib_uverbs_qp_idr, GFP_KERNEL)) {
+		ret = -ENOMEM;
+		goto err_destroy;
+	}
+
+	ret = idr_get_new(&ib_uverbs_qp_idr, qp, &uobj->id);
+
+	if (ret == -EAGAIN)
+		goto retry;
+	if (ret)
+		goto err_destroy;
+
+	resp.qp_handle = uobj->id;
+
+	spin_lock_irq(&file->ucontext->lock);
+	list_add_tail(&uobj->list, &file->ucontext->qp_list);
+	spin_unlock_irq(&file->ucontext->lock);
+
+	if (copy_to_user((void __user *) (unsigned long) cmd.response,
+			 &resp, sizeof resp)) {
+		ret = -EFAULT;
+		goto err_list;
+	}
+
+	up(&ib_uverbs_idr_mutex);
+
+	return in_len;
+
+err_list:
+	spin_lock_irq(&file->ucontext->lock);
+	list_del(&uobj->list);
+	spin_unlock_irq(&file->ucontext->lock);
+
+err_destroy:
+	ib_destroy_qp(qp);
+
+err_up:
+	up(&ib_uverbs_idr_mutex);
+
+	kfree(uobj);
+	return ret;
+}
+
+ssize_t ib_uverbs_modify_qp(struct ib_uverbs_file *file,
+			    const char __user *buf, int in_len,
+			    int out_len)
+{
+	struct ib_uverbs_modify_qp cmd;
+	struct ib_qp              *qp;
+	struct ib_qp_attr         *attr;
+	int                        ret;
+
+	if (copy_from_user(&cmd, buf, sizeof cmd))
+		return -EFAULT;
+
+	attr = kmalloc(sizeof *attr, GFP_KERNEL);
+	if (!attr)
+		return -ENOMEM;
+
+	down(&ib_uverbs_idr_mutex);
+
+	qp = idr_find(&ib_uverbs_qp_idr, cmd.qp_handle);
+	if (!qp || qp->uobject->context != file->ucontext) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	attr->qp_state 		  = cmd.qp_state;
+	attr->cur_qp_state 	  = cmd.cur_qp_state;
+	attr->path_mtu 		  = cmd.path_mtu;
+	attr->path_mig_state 	  = cmd.path_mig_state;
+	attr->qkey 		  = cmd.qkey;
+	attr->rq_psn 		  = cmd.rq_psn;
+	attr->sq_psn 		  = cmd.sq_psn;
+	attr->dest_qp_num 	  = cmd.dest_qp_num;
+	attr->qp_access_flags 	  = cmd.qp_access_flags;
+	attr->pkey_index 	  = cmd.pkey_index;
+	attr->alt_pkey_index 	  = cmd.pkey_index;
+	attr->en_sqd_async_notify = cmd.en_sqd_async_notify;
+	attr->max_rd_atomic 	  = cmd.max_rd_atomic;
+	attr->max_dest_rd_atomic  = cmd.max_dest_rd_atomic;
+	attr->min_rnr_timer 	  = cmd.min_rnr_timer;
+	attr->port_num 		  = cmd.port_num;
+	attr->timeout 		  = cmd.timeout;
+	attr->retry_cnt 	  = cmd.retry_cnt;
+	attr->rnr_retry 	  = cmd.rnr_retry;
+	attr->alt_port_num 	  = cmd.alt_port_num;
+	attr->alt_timeout 	  = cmd.alt_timeout;
+
+	memcpy(attr->ah_attr.grh.dgid.raw, cmd.dest.dgid, 16);
+	attr->ah_attr.grh.flow_label        = cmd.dest.flow_label;
+	attr->ah_attr.grh.sgid_index        = cmd.dest.sgid_index;
+	attr->ah_attr.grh.hop_limit         = cmd.dest.hop_limit;
+	attr->ah_attr.grh.traffic_class     = cmd.dest.traffic_class;
+	attr->ah_attr.dlid 	    	    = cmd.dest.dlid;
+	attr->ah_attr.sl   	    	    = cmd.dest.sl;
+	attr->ah_attr.src_path_bits 	    = cmd.dest.src_path_bits;
+	attr->ah_attr.static_rate   	    = cmd.dest.static_rate;
+	attr->ah_attr.ah_flags 	    	    = cmd.dest.is_global ? IB_AH_GRH : 0;
+	attr->ah_attr.port_num 	    	    = cmd.dest.port_num;
+
+	memcpy(attr->alt_ah_attr.grh.dgid.raw, cmd.alt_dest.dgid, 16);
+	attr->alt_ah_attr.grh.flow_label    = cmd.alt_dest.flow_label;
+	attr->alt_ah_attr.grh.sgid_index    = cmd.alt_dest.sgid_index;
+	attr->alt_ah_attr.grh.hop_limit     = cmd.alt_dest.hop_limit;
+	attr->alt_ah_attr.grh.traffic_class = cmd.alt_dest.traffic_class;
+	attr->alt_ah_attr.dlid 	    	    = cmd.alt_dest.dlid;
+	attr->alt_ah_attr.sl   	    	    = cmd.alt_dest.sl;
+	attr->alt_ah_attr.src_path_bits     = cmd.alt_dest.src_path_bits;
+	attr->alt_ah_attr.static_rate       = cmd.alt_dest.static_rate;
+	attr->alt_ah_attr.ah_flags 	    = cmd.alt_dest.is_global ? IB_AH_GRH : 0;
+	attr->alt_ah_attr.port_num 	    = cmd.alt_dest.port_num;
+
+	ret = ib_modify_qp(qp, attr, cmd.attr_mask);
+	if (ret)
+		goto out;
+
+	ret = in_len;
+
+out:
+	up(&ib_uverbs_idr_mutex);
+	kfree(attr);
+
+	return ret;
+}
+
+ssize_t ib_uverbs_destroy_qp(struct ib_uverbs_file *file,
+			     const char __user *buf, int in_len,
+			     int out_len)
+{
+	struct ib_uverbs_destroy_qp cmd;
+	struct ib_qp               *qp;
+	struct ib_uobject          *uobj;
+	int                         ret = -EINVAL;
+
+	if (copy_from_user(&cmd, buf, sizeof cmd))
+		return -EFAULT;
+
+	down(&ib_uverbs_idr_mutex);
+
+	qp = idr_find(&ib_uverbs_qp_idr, cmd.qp_handle);
+	if (!qp || qp->uobject->context != file->ucontext)
+		goto out;
+
+	uobj = qp->uobject;
+
+	ret = ib_destroy_qp(qp);
+	if (ret)
+		goto out;
+
+	idr_remove(&ib_uverbs_qp_idr, cmd.qp_handle);
+
+	spin_lock_irq(&file->ucontext->lock);
+	list_del(&uobj->list);
+	spin_unlock_irq(&file->ucontext->lock);
+
+	kfree(uobj);
+
+out:
+	up(&ib_uverbs_idr_mutex);
+
+	return ret ? ret : in_len;
+}
+
+ssize_t ib_uverbs_attach_mcast(struct ib_uverbs_file *file,
+			       const char __user *buf, int in_len,
+			       int out_len)
+{
+	struct ib_uverbs_attach_mcast cmd;
+	struct ib_qp                 *qp;
+	int                           ret = -EINVAL;
+
+	if (copy_from_user(&cmd, buf, sizeof cmd))
+		return -EFAULT;
+
+	down(&ib_uverbs_idr_mutex);
+
+	qp = idr_find(&ib_uverbs_qp_idr, cmd.qp_handle);
+	if (qp && qp->uobject->context == file->ucontext)
+		ret = ib_attach_mcast(qp, (union ib_gid *) cmd.gid, cmd.mlid);
+
+	up(&ib_uverbs_idr_mutex);
+
+	return ret ? ret : in_len;
+}
+
+ssize_t ib_uverbs_detach_mcast(struct ib_uverbs_file *file,
+			       const char __user *buf, int in_len,
+			       int out_len)
+{
+	struct ib_uverbs_detach_mcast cmd;
+	struct ib_qp                 *qp;
+	int                           ret = -EINVAL;
+
+	if (copy_from_user(&cmd, buf, sizeof cmd))
+		return -EFAULT;
+
+	down(&ib_uverbs_idr_mutex);
+
+	qp = idr_find(&ib_uverbs_qp_idr, cmd.qp_handle);
+	if (qp && qp->uobject->context == file->ucontext)
+		ret = ib_detach_mcast(qp, (union ib_gid *) cmd.gid, cmd.mlid);
+
+	up(&ib_uverbs_idr_mutex);
+
+	return ret ? ret : in_len;
+}
diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c
new file mode 100644
--- /dev/null
+++ b/drivers/infiniband/core/uverbs_main.c
@@ -0,0 +1,711 @@
+/*
+ * Copyright (c) 2005 Topspin Communications.  All rights reserved.
+ * Copyright (c) 2005 Cisco Systems.  All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * 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 THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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.
+ *
+ * $Id: uverbs_main.c 2733 2005-06-28 19:14:34Z roland $
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/fs.h>
+#include <linux/poll.h>
+#include <linux/file.h>
+#include <linux/mount.h>
+
+#include <asm/uaccess.h>
+
+#include "uverbs.h"
+
+MODULE_AUTHOR("Roland Dreier");
+MODULE_DESCRIPTION("InfiniBand userspace verbs access");
+MODULE_LICENSE("Dual BSD/GPL");
+
+#define INFINIBANDEVENTFS_MAGIC	0x49426576	/* "IBev" */
+
+enum {
+	IB_UVERBS_MAJOR       = 231,
+	IB_UVERBS_BASE_MINOR  = 192,
+	IB_UVERBS_MAX_DEVICES = 32
+};
+
+#define IB_UVERBS_BASE_DEV	MKDEV(IB_UVERBS_MAJOR, IB_UVERBS_BASE_MINOR)
+
+DECLARE_MUTEX(ib_uverbs_idr_mutex);
+DEFINE_IDR(ib_uverbs_pd_idr);
+DEFINE_IDR(ib_uverbs_mr_idr);
+DEFINE_IDR(ib_uverbs_mw_idr);
+DEFINE_IDR(ib_uverbs_ah_idr);
+DEFINE_IDR(ib_uverbs_cq_idr);
+DEFINE_IDR(ib_uverbs_qp_idr);
+
+static spinlock_t map_lock;
+static DECLARE_BITMAP(dev_map, IB_UVERBS_MAX_DEVICES);
+
+static ssize_t (*uverbs_cmd_table[])(struct ib_uverbs_file *file,
+				     const char __user *buf, int in_len,
+				     int out_len) = {
+	[IB_USER_VERBS_CMD_QUERY_PARAMS]  = ib_uverbs_query_params,
+	[IB_USER_VERBS_CMD_GET_CONTEXT]   = ib_uverbs_get_context,
+	[IB_USER_VERBS_CMD_QUERY_DEVICE]  = ib_uverbs_query_device,
+	[IB_USER_VERBS_CMD_QUERY_PORT]    = ib_uverbs_query_port,
+	[IB_USER_VERBS_CMD_QUERY_GID]     = ib_uverbs_query_gid,
+	[IB_USER_VERBS_CMD_QUERY_PKEY]    = ib_uverbs_query_pkey,
+	[IB_USER_VERBS_CMD_ALLOC_PD]      = ib_uverbs_alloc_pd,
+	[IB_USER_VERBS_CMD_DEALLOC_PD]    = ib_uverbs_dealloc_pd,
+	[IB_USER_VERBS_CMD_REG_MR]        = ib_uverbs_reg_mr,
+	[IB_USER_VERBS_CMD_DEREG_MR]      = ib_uverbs_dereg_mr,
+	[IB_USER_VERBS_CMD_CREATE_CQ]     = ib_uverbs_create_cq,
+	[IB_USER_VERBS_CMD_DESTROY_CQ]    = ib_uverbs_destroy_cq,
+	[IB_USER_VERBS_CMD_CREATE_QP]     = ib_uverbs_create_qp,
+	[IB_USER_VERBS_CMD_MODIFY_QP]     = ib_uverbs_modify_qp,
+	[IB_USER_VERBS_CMD_DESTROY_QP]    = ib_uverbs_destroy_qp,
+	[IB_USER_VERBS_CMD_ATTACH_MCAST]  = ib_uverbs_attach_mcast,
+	[IB_USER_VERBS_CMD_DETACH_MCAST]  = ib_uverbs_detach_mcast,
+};
+
+static struct vfsmount *uverbs_event_mnt;
+
+static void ib_uverbs_add_one(struct ib_device *device);
+static void ib_uverbs_remove_one(struct ib_device *device);
+
+static int ib_dealloc_ucontext(struct ib_ucontext *context)
+{
+	struct ib_uobject *uobj, *tmp;
+
+	if (!context)
+		return 0;
+
+	down(&ib_uverbs_idr_mutex);
+
+	/* XXX Free AHs */
+
+	list_for_each_entry_safe(uobj, tmp, &context->qp_list, list) {
+		struct ib_qp *qp = idr_find(&ib_uverbs_qp_idr, uobj->id);
+		idr_remove(&ib_uverbs_qp_idr, uobj->id);
+		ib_destroy_qp(qp);
+		list_del(&uobj->list);
+		kfree(uobj);
+	}
+
+	list_for_each_entry_safe(uobj, tmp, &context->cq_list, list) {
+		struct ib_cq *cq = idr_find(&ib_uverbs_cq_idr, uobj->id);
+		idr_remove(&ib_uverbs_cq_idr, uobj->id);
+		ib_destroy_cq(cq);
+		list_del(&uobj->list);
+		kfree(uobj);
+	}
+
+	/* XXX Free SRQs */
+	/* XXX Free MWs */
+
+	list_for_each_entry_safe(uobj, tmp, &context->mr_list, list) {
+		struct ib_mr *mr = idr_find(&ib_uverbs_mr_idr, uobj->id);
+		struct ib_device *mrdev = mr->device;
+		struct ib_umem_object *memobj;
+
+		idr_remove(&ib_uverbs_mr_idr, uobj->id);
+		ib_dereg_mr(mr);
+
+		memobj = container_of(uobj, struct ib_umem_object, uobject);
+		ib_umem_release_on_close(mrdev, &memobj->umem);
+
+		list_del(&uobj->list);
+		kfree(memobj);
+	}
+
+	list_for_each_entry_safe(uobj, tmp, &context->pd_list, list) {
+		struct ib_pd *pd = idr_find(&ib_uverbs_pd_idr, uobj->id);
+		idr_remove(&ib_uverbs_pd_idr, uobj->id);
+		ib_dealloc_pd(pd);
+		list_del(&uobj->list);
+		kfree(uobj);
+	}
+
+	up(&ib_uverbs_idr_mutex);
+
+	return context->device->dealloc_ucontext(context);
+}
+
+static void ib_uverbs_release_file(struct kref *ref)
+{
+	struct ib_uverbs_file *file =
+		container_of(ref, struct ib_uverbs_file, ref);
+
+	module_put(file->device->ib_dev->owner);
+	kfree(file);
+}
+
+static ssize_t ib_uverbs_event_read(struct file *filp, char __user *buf,
+				    size_t count, loff_t *pos)
+{
+	struct ib_uverbs_event_file *file = filp->private_data;
+	void *event;
+	int eventsz;
+	int ret = 0;
+
+	spin_lock_irq(&file->lock);
+
+	while (list_empty(&file->event_list) && file->fd >= 0) {
+		spin_unlock_irq(&file->lock);
+
+		if (filp->f_flags & O_NONBLOCK)
+			return -EAGAIN;
+
+		if (wait_event_interruptible(file->poll_wait,
+					     !list_empty(&file->event_list) ||
+					     file->fd < 0))
+			return -ERESTARTSYS;
+
+		spin_lock_irq(&file->lock);
+	}
+
+	if (file->fd < 0) {
+		spin_unlock_irq(&file->lock);
+		return -ENODEV;
+	}
+
+	if (file->is_async) {
+		event   = list_entry(file->event_list.next,
+				     struct ib_uverbs_async_event, list);
+		eventsz = sizeof (struct ib_uverbs_async_event_desc);
+	} else {
+		event   = list_entry(file->event_list.next,
+				     struct ib_uverbs_comp_event, list);
+		eventsz = sizeof (struct ib_uverbs_comp_event_desc);
+	}
+
+	if (eventsz > count) {
+		ret   = -EINVAL;
+		event = NULL;
+	} else
+		list_del(file->event_list.next);
+
+	spin_unlock_irq(&file->lock);
+
+	if (event) {
+		if (copy_to_user(buf, event, eventsz))
+			ret = -EFAULT;
+		else
+			ret = eventsz;
+	}
+
+	kfree(event);
+
+	return ret;
+}
+
+static unsigned int ib_uverbs_event_poll(struct file *filp,
+					 struct poll_table_struct *wait)
+{
+	unsigned int pollflags = 0;
+	struct ib_uverbs_event_file *file = filp->private_data;
+
+	poll_wait(filp, &file->poll_wait, wait);
+
+	spin_lock_irq(&file->lock);
+	if (file->fd < 0)
+		pollflags = POLLERR;
+	else if (!list_empty(&file->event_list))
+		pollflags = POLLIN | POLLRDNORM;
+	spin_unlock_irq(&file->lock);
+
+	return pollflags;
+}
+
+static void ib_uverbs_event_release(struct ib_uverbs_event_file *file)
+{
+	struct list_head *entry, *tmp;
+
+	spin_lock_irq(&file->lock);
+	if (file->fd != -1) {
+		file->fd = -1;
+		list_for_each_safe(entry, tmp, &file->event_list)
+			if (file->is_async)
+				kfree(list_entry(entry, struct ib_uverbs_async_event, list));
+			else
+				kfree(list_entry(entry, struct ib_uverbs_comp_event, list));
+	}
+	spin_unlock_irq(&file->lock);
+}
+
+static int ib_uverbs_event_fasync(int fd, struct file *filp, int on)
+{
+	struct ib_uverbs_event_file *file = filp->private_data;
+
+	return fasync_helper(fd, filp, on, &file->async_queue);
+}
+
+static int ib_uverbs_event_close(struct inode *inode, struct file *filp)
+{
+	struct ib_uverbs_event_file *file = filp->private_data;
+
+	ib_uverbs_event_release(file);
+	ib_uverbs_event_fasync(-1, filp, 0);
+	kref_put(&file->uverbs_file->ref, ib_uverbs_release_file);
+
+	return 0;
+}
+
+static struct file_operations uverbs_event_fops = {
+	/*
+	 * No .owner field since we artificially create event files,
+	 * so there is no increment to the module reference count in
+	 * the open path.  All event files come from a uverbs command
+	 * file, which already takes a module reference, so this is OK.
+	 */
+	.read 	 = ib_uverbs_event_read,
+	.poll    = ib_uverbs_event_poll,
+	.release = ib_uverbs_event_close,
+	.fasync  = ib_uverbs_event_fasync
+};
+
+void ib_uverbs_comp_handler(struct ib_cq *cq, void *cq_context)
+{
+	struct ib_uverbs_file       *file = cq_context;
+	struct ib_uverbs_comp_event *entry;
+	unsigned long                flags;
+
+	entry = kmalloc(sizeof *entry, GFP_ATOMIC);
+	if (!entry)
+		return;
+
+	entry->desc.cq_handle = cq->uobject->user_handle;
+
+	spin_lock_irqsave(&file->comp_file[0].lock, flags);
+	list_add_tail(&entry->list, &file->comp_file[0].event_list);
+	spin_unlock_irqrestore(&file->comp_file[0].lock, flags);
+
+	wake_up_interruptible(&file->comp_file[0].poll_wait);
+	kill_fasync(&file->comp_file[0].async_queue, SIGIO, POLL_IN);
+}
+
+static void ib_uverbs_async_handler(struct ib_uverbs_file *file,
+				    __u64 element, __u64 event)
+{
+	struct ib_uverbs_async_event *entry;
+	unsigned long flags;
+
+	entry = kmalloc(sizeof *entry, GFP_ATOMIC);
+	if (!entry)
+		return;
+
+	entry->desc.element    = element;
+	entry->desc.event_type = event;
+
+	spin_lock_irqsave(&file->async_file.lock, flags);
+	list_add_tail(&entry->list, &file->async_file.event_list);
+	spin_unlock_irqrestore(&file->async_file.lock, flags);
+
+	wake_up_interruptible(&file->async_file.poll_wait);
+	kill_fasync(&file->async_file.async_queue, SIGIO, POLL_IN);
+}
+
+void ib_uverbs_cq_event_handler(struct ib_event *event, void *context_ptr)
+{
+	ib_uverbs_async_handler(context_ptr,
+				event->element.cq->uobject->user_handle,
+				event->event);
+}
+
+void ib_uverbs_qp_event_handler(struct ib_event *event, void *context_ptr)
+{
+	ib_uverbs_async_handler(context_ptr,
+				event->element.qp->uobject->user_handle,
+				event->event);
+}
+
+static void ib_uverbs_event_handler(struct ib_event_handler *handler,
+				    struct ib_event *event)
+{
+	struct ib_uverbs_file *file =
+		container_of(handler, struct ib_uverbs_file, event_handler);
+
+	ib_uverbs_async_handler(file, event->element.port_num, event->event);
+}
+
+static int ib_uverbs_event_init(struct ib_uverbs_event_file *file,
+				struct ib_uverbs_file *uverbs_file)
+{
+	struct file *filp;
+
+	spin_lock_init(&file->lock);
+	INIT_LIST_HEAD(&file->event_list);
+	init_waitqueue_head(&file->poll_wait);
+	file->uverbs_file = uverbs_file;
+	file->async_queue = NULL;
+
+	file->fd = get_unused_fd();
+	if (file->fd < 0)
+		return file->fd;
+
+	filp = get_empty_filp();
+	if (!filp) {
+		put_unused_fd(file->fd);
+		return -ENFILE;
+	}
+
+	filp->f_op 	   = &uverbs_event_fops;
+	filp->f_vfsmnt 	   = mntget(uverbs_event_mnt);
+	filp->f_dentry 	   = dget(uverbs_event_mnt->mnt_root);
+	filp->f_mapping    = filp->f_dentry->d_inode->i_mapping;
+	filp->f_flags      = O_RDONLY;
+	filp->f_mode       = FMODE_READ;
+	filp->private_data = file;
+
+	fd_install(file->fd, filp);
+
+	return 0;
+}
+
+static ssize_t ib_uverbs_write(struct file *filp, const char __user *buf,
+			     size_t count, loff_t *pos)
+{
+	struct ib_uverbs_file *file = filp->private_data;
+	struct ib_uverbs_cmd_hdr hdr;
+
+	if (count < sizeof hdr)
+		return -EINVAL;
+
+	if (copy_from_user(&hdr, buf, sizeof hdr))
+		return -EFAULT;
+
+	if (hdr.in_words * 4 != count)
+		return -EINVAL;
+
+	if (hdr.command < 0 || hdr.command >= ARRAY_SIZE(uverbs_cmd_table))
+		return -EINVAL;
+
+	if (!file->ucontext                               &&
+	    hdr.command != IB_USER_VERBS_CMD_QUERY_PARAMS &&
+	    hdr.command != IB_USER_VERBS_CMD_GET_CONTEXT)
+		return -EINVAL;
+
+	return uverbs_cmd_table[hdr.command](file, buf + sizeof hdr,
+					     hdr.in_words * 4, hdr.out_words * 4);
+}
+
+static int ib_uverbs_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+	struct ib_uverbs_file *file = filp->private_data;
+
+	if (!file->ucontext)
+		return -ENODEV;
+	else
+		return file->device->ib_dev->mmap(file->ucontext, vma);
+}
+
+static int ib_uverbs_open(struct inode *inode, struct file *filp)
+{
+	struct ib_uverbs_device *dev =
+		container_of(inode->i_cdev, struct ib_uverbs_device, dev);
+	struct ib_uverbs_file *file;
+	int i = 0;
+	int ret;
+
+	if (!try_module_get(dev->ib_dev->owner))
+		return -ENODEV;
+
+	file = kmalloc(sizeof *file +
+		       (dev->num_comp - 1) * sizeof (struct ib_uverbs_event_file),
+		       GFP_KERNEL);
+	if (!file)
+		return -ENOMEM;
+
+	file->device = dev;
+	kref_init(&file->ref);
+
+	file->ucontext = NULL;
+
+	ret = ib_uverbs_event_init(&file->async_file, file);
+	if (ret)
+		goto err;
+
+	file->async_file.is_async = 1;
+
+	kref_get(&file->ref);
+
+	for (i = 0; i < dev->num_comp; ++i) {
+		ret = ib_uverbs_event_init(&file->comp_file[i], file);
+		if (ret)
+			goto err_async;
+		kref_get(&file->ref);
+		file->comp_file[i].is_async = 0;
+	}
+
+
+	filp->private_data = file;
+
+	INIT_IB_EVENT_HANDLER(&file->event_handler, dev->ib_dev,
+			      ib_uverbs_event_handler);
+	if (ib_register_event_handler(&file->event_handler))
+		goto err_async;
+
+	return 0;
+
+err_async:
+	while (i--)
+		ib_uverbs_event_release(&file->comp_file[i]);
+
+	ib_uverbs_event_release(&file->async_file);
+
+err:
+	kref_put(&file->ref, ib_uverbs_release_file);
+
+	return ret;
+}
+
+static int ib_uverbs_close(struct inode *inode, struct file *filp)
+{
+	struct ib_uverbs_file *file = filp->private_data;
+	int i;
+
+	ib_unregister_event_handler(&file->event_handler);
+	ib_uverbs_event_release(&file->async_file);
+	ib_dealloc_ucontext(file->ucontext);
+
+	for (i = 0; i < file->device->num_comp; ++i)
+		ib_uverbs_event_release(&file->comp_file[i]);
+
+	kref_put(&file->ref, ib_uverbs_release_file);
+
+	return 0;
+}
+
+static struct file_operations uverbs_fops = {
+	.owner 	 = THIS_MODULE,
+	.write 	 = ib_uverbs_write,
+	.open 	 = ib_uverbs_open,
+	.release = ib_uverbs_close
+};
+
+static struct file_operations uverbs_mmap_fops = {
+	.owner 	 = THIS_MODULE,
+	.write 	 = ib_uverbs_write,
+	.mmap    = ib_uverbs_mmap,
+	.open 	 = ib_uverbs_open,
+	.release = ib_uverbs_close
+};
+
+static struct ib_client uverbs_client = {
+	.name   = "uverbs",
+	.add    = ib_uverbs_add_one,
+	.remove = ib_uverbs_remove_one
+};
+
+static ssize_t show_ibdev(struct class_device *class_dev, char *buf)
+{
+	struct ib_uverbs_device *dev =
+		container_of(class_dev, struct ib_uverbs_device, class_dev);
+
+	return sprintf(buf, "%s\n", dev->ib_dev->name);
+}
+static CLASS_DEVICE_ATTR(ibdev, S_IRUGO, show_ibdev, NULL);
+
+static void ib_uverbs_release_class_dev(struct class_device *class_dev)
+{
+	struct ib_uverbs_device *dev =
+		container_of(class_dev, struct ib_uverbs_device, class_dev);
+
+	cdev_del(&dev->dev);
+	clear_bit(dev->devnum, dev_map);
+	kfree(dev);
+}
+
+static struct class uverbs_class = {
+	.name    = "infiniband_verbs",
+	.release = ib_uverbs_release_class_dev
+};
+
+static ssize_t show_abi_version(struct class *class, char *buf)
+{
+	return sprintf(buf, "%d\n", IB_USER_VERBS_ABI_VERSION);
+}
+static CLASS_ATTR(abi_version, S_IRUGO, show_abi_version, NULL);
+
+static void ib_uverbs_add_one(struct ib_device *device)
+{
+	struct ib_uverbs_device *uverbs_dev;
+
+	if (!device->alloc_ucontext)
+		return;
+
+	uverbs_dev = kmalloc(sizeof *uverbs_dev, GFP_KERNEL);
+	if (!uverbs_dev)
+		return;
+
+	memset(uverbs_dev, 0, sizeof *uverbs_dev);
+
+	spin_lock(&map_lock);
+	uverbs_dev->devnum = find_first_zero_bit(dev_map, IB_UVERBS_MAX_DEVICES);
+	if (uverbs_dev->devnum >= IB_UVERBS_MAX_DEVICES) {
+		spin_unlock(&map_lock);
+		goto err;
+	}
+	set_bit(uverbs_dev->devnum, dev_map);
+	spin_unlock(&map_lock);
+
+	uverbs_dev->ib_dev   = device;
+	uverbs_dev->num_comp = 1;
+
+	if (device->mmap)
+		cdev_init(&uverbs_dev->dev, &uverbs_mmap_fops);
+	else
+		cdev_init(&uverbs_dev->dev, &uverbs_fops);
+	uverbs_dev->dev.owner = THIS_MODULE;
+	kobject_set_name(&uverbs_dev->dev.kobj, "uverbs%d", uverbs_dev->devnum);
+	if (cdev_add(&uverbs_dev->dev, IB_UVERBS_BASE_DEV + uverbs_dev->devnum, 1))
+		goto err;
+
+	uverbs_dev->class_dev.class = &uverbs_class;
+	uverbs_dev->class_dev.dev   = device->dma_device;
+	uverbs_dev->class_dev.devt  = uverbs_dev->dev.dev;
+	snprintf(uverbs_dev->class_dev.class_id, BUS_ID_SIZE, "uverbs%d", uverbs_dev->devnum);
+	if (class_device_register(&uverbs_dev->class_dev))
+		goto err_cdev;
+
+	if (class_device_create_file(&uverbs_dev->class_dev, &class_device_attr_ibdev))
+		goto err_class;
+
+	ib_set_client_data(device, &uverbs_client, uverbs_dev);
+
+	return;
+
+err_class:
+	class_device_unregister(&uverbs_dev->class_dev);
+
+err_cdev:
+	cdev_del(&uverbs_dev->dev);
+	clear_bit(uverbs_dev->devnum, dev_map);
+
+err:
+	kfree(uverbs_dev);
+	return;
+}
+
+static void ib_uverbs_remove_one(struct ib_device *device)
+{
+	struct ib_uverbs_device *uverbs_dev = ib_get_client_data(device, &uverbs_client);
+
+	if (!uverbs_dev)
+		return;
+
+	class_device_unregister(&uverbs_dev->class_dev);
+}
+
+static struct super_block *uverbs_event_get_sb(struct file_system_type *fs_type, int flags,
+					       const char *dev_name, void *data)
+{
+	return get_sb_pseudo(fs_type, "infinibandevent:", NULL,
+			     INFINIBANDEVENTFS_MAGIC);
+}
+
+static struct file_system_type uverbs_event_fs = {
+	/* No owner field so module can be unloaded */
+	.name    = "infinibandeventfs",
+	.get_sb  = uverbs_event_get_sb,
+	.kill_sb = kill_litter_super
+};
+
+static int __init ib_uverbs_init(void)
+{
+	int ret;
+
+	spin_lock_init(&map_lock);
+
+	ret = register_chrdev_region(IB_UVERBS_BASE_DEV, IB_UVERBS_MAX_DEVICES,
+				     "infiniband_verbs");
+	if (ret) {
+		printk(KERN_ERR "user_verbs: couldn't register device number\n");
+		goto out;
+	}
+
+	ret = class_register(&uverbs_class);
+	if (ret) {
+		printk(KERN_ERR "user_verbs: couldn't create class infiniband_verbs\n");
+		goto out_chrdev;
+	}
+
+	ret = class_create_file(&uverbs_class, &class_attr_abi_version);
+	if (ret) {
+		printk(KERN_ERR "user_verbs: couldn't create abi_version attribute\n");
+		goto out_class;
+	}
+
+	ret = register_filesystem(&uverbs_event_fs);
+	if (ret) {
+		printk(KERN_ERR "user_verbs: couldn't register infinibandeventfs\n");
+		goto out_class;
+	}
+
+	uverbs_event_mnt = kern_mount(&uverbs_event_fs);
+	if (IS_ERR(uverbs_event_mnt)) {
+		ret = PTR_ERR(uverbs_event_mnt);
+		printk(KERN_ERR "user_verbs: couldn't mount infinibandeventfs\n");
+		goto out_fs;
+	}
+
+	ret = ib_register_client(&uverbs_client);
+	if (ret) {
+		printk(KERN_ERR "user_verbs: couldn't register client\n");
+		goto out_mnt;
+	}
+
+	return 0;
+
+out_mnt:
+	mntput(uverbs_event_mnt);
+
+out_fs:
+	unregister_filesystem(&uverbs_event_fs);
+
+out_class:
+	class_unregister(&uverbs_class);
+
+out_chrdev:
+	unregister_chrdev_region(IB_UVERBS_BASE_DEV, IB_UVERBS_MAX_DEVICES);
+
+out:
+	return ret;
+}
+
+static void __exit ib_uverbs_cleanup(void)
+{
+	ib_unregister_client(&uverbs_client);
+	mntput(uverbs_event_mnt);
+	unregister_filesystem(&uverbs_event_fs);
+	class_unregister(&uverbs_class);
+	unregister_chrdev_region(IB_UVERBS_BASE_DEV, IB_UVERBS_MAX_DEVICES);
+}
+
+module_init(ib_uverbs_init);
+module_exit(ib_uverbs_cleanup);
diff --git a/drivers/infiniband/core/uverbs_mem.c b/drivers/infiniband/core/uverbs_mem.c
new file mode 100644
--- /dev/null
+++ b/drivers/infiniband/core/uverbs_mem.c
@@ -0,0 +1,221 @@
+/*
+ * Copyright (c) 2005 Topspin Communications.  All rights reserved.
+ * Copyright (c) 2005 Cisco Systems.  All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * 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 THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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.
+ *
+ * $Id: uverbs_mem.c 2743 2005-06-28 22:27:59Z roland $
+ */
+
+#include <linux/mm.h>
+#include <linux/dma-mapping.h>
+
+#include "uverbs.h"
+
+struct ib_umem_account_work {
+	struct work_struct work;
+	struct mm_struct  *mm;
+	unsigned long      diff;
+};
+
+
+static void __ib_umem_release(struct ib_device *dev, struct ib_umem *umem, int dirty)
+{
+	struct ib_umem_chunk *chunk, *tmp;
+	int i;
+
+	list_for_each_entry_safe(chunk, tmp, &umem->chunk_list, list) {
+		dma_unmap_sg(dev->dma_device, chunk->page_list,
+			     chunk->nents, DMA_BIDIRECTIONAL);
+		for (i = 0; i < chunk->nents; ++i) {
+			if (umem->writable && dirty)
+				set_page_dirty_lock(chunk->page_list[i].page);
+			put_page(chunk->page_list[i].page);
+		}
+
+		kfree(chunk);
+	}
+}
+
+int ib_umem_get(struct ib_device *dev, struct ib_umem *mem,
+		void *addr, size_t size, int write)
+{
+	struct page **page_list;
+	struct ib_umem_chunk *chunk;
+	unsigned long locked;
+	unsigned long lock_limit;
+	unsigned long cur_base;
+	unsigned long npages;
+	int ret = 0;
+	int off;
+	int i;
+
+	if (!can_do_mlock())
+		return -EPERM;
+
+	page_list = (struct page **) __get_free_page(GFP_KERNEL);
+	if (!page_list)
+		return -ENOMEM;
+
+	mem->user_base = (unsigned long) addr;
+	mem->length    = size;
+	mem->offset    = (unsigned long) addr & ~PAGE_MASK;
+	mem->page_size = PAGE_SIZE;
+	mem->writable  = write;
+
+	INIT_LIST_HEAD(&mem->chunk_list);
+
+	npages = PAGE_ALIGN(size + mem->offset) >> PAGE_SHIFT;
+
+	down_write(&current->mm->mmap_sem);
+
+	locked     = npages + current->mm->locked_vm;
+	lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur >> PAGE_SHIFT;
+
+	if ((locked > lock_limit) && !capable(CAP_IPC_LOCK)) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	cur_base = (unsigned long) addr & PAGE_MASK;
+
+	while (npages) {
+		ret = get_user_pages(current, current->mm, cur_base,
+				     min_t(int, npages,
+					   PAGE_SIZE / sizeof (struct page *)),
+				     1, !write, page_list, NULL);
+
+		if (ret < 0)
+			goto out;
+
+		cur_base += ret * PAGE_SIZE;
+		npages   -= ret;
+
+		off = 0;
+
+		while (ret) {
+			chunk = kmalloc(sizeof *chunk + sizeof (struct scatterlist) *
+					min_t(int, ret, IB_UMEM_MAX_PAGE_CHUNK),
+					GFP_KERNEL);
+			if (!chunk) {
+				ret = -ENOMEM;
+				goto out;
+			}
+
+			chunk->nents = min_t(int, ret, IB_UMEM_MAX_PAGE_CHUNK);
+			for (i = 0; i < chunk->nents; ++i) {
+				chunk->page_list[i].page   = page_list[i + off];
+				chunk->page_list[i].offset = 0;
+				chunk->page_list[i].length = PAGE_SIZE;
+			}
+
+			chunk->nmap = dma_map_sg(dev->dma_device,
+						 &chunk->page_list[0],
+						 chunk->nents,
+						 DMA_BIDIRECTIONAL);
+			if (chunk->nmap <= 0) {
+				for (i = 0; i < chunk->nents; ++i)
+					put_page(chunk->page_list[i].page);
+				kfree(chunk);
+
+				ret = -ENOMEM;
+				goto out;
+			}
+
+			ret -= chunk->nents;
+			off += chunk->nents;
+			list_add_tail(&chunk->list, &mem->chunk_list);
+		}
+
+		ret = 0;
+	}
+
+out:
+	if (ret < 0)
+		__ib_umem_release(dev, mem, 0);
+	else
+		current->mm->locked_vm = locked;
+
+	up_write(&current->mm->mmap_sem);
+	free_page((unsigned long) page_list);
+
+	return ret;
+}
+
+void ib_umem_release(struct ib_device *dev, struct ib_umem *umem)
+{
+	__ib_umem_release(dev, umem, 1);
+
+	down_write(&current->mm->mmap_sem);
+	current->mm->locked_vm -=
+		PAGE_ALIGN(umem->length + umem->offset) >> PAGE_SHIFT;
+	up_write(&current->mm->mmap_sem);
+}
+
+static void ib_umem_account(void *work_ptr)
+{
+	struct ib_umem_account_work *work = work_ptr;
+
+	down_write(&work->mm->mmap_sem);
+	work->mm->locked_vm -= work->diff;
+	up_write(&work->mm->mmap_sem);
+	mmput(work->mm);
+	kfree(work);
+}
+
+void ib_umem_release_on_close(struct ib_device *dev, struct ib_umem *umem)
+{
+	struct ib_umem_account_work *work;
+	struct mm_struct *mm;
+
+	__ib_umem_release(dev, umem, 1);
+
+	mm = get_task_mm(current);
+	if (!mm)
+		return;
+
+	/*
+	 * We may be called with the mm's mmap_sem already held.  This
+	 * can happen when a userspace munmap() is the call that drops
+	 * the last reference to our file and calls our release
+	 * method.  If there are memory regions to destroy, we'll end
+	 * up here and not be able to take the mmap_sem.  Therefore we
+	 * defer the vm_locked accounting to the system workqueue.
+	 */
+
+	work = kmalloc(sizeof *work, GFP_KERNEL);
+	if (!work)
+		return;
+
+	INIT_WORK(&work->work, ib_umem_account, work);
+	work->mm   = mm;
+	work->diff = PAGE_ALIGN(umem->length + umem->offset) >> PAGE_SHIFT;
+
+	schedule_work(&work->work);
+}
diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c
--- a/drivers/infiniband/core/verbs.c
+++ b/drivers/infiniband/core/verbs.c
@@ -4,6 +4,7 @@
  * Copyright (c) 2004 Intel Corporation.  All rights reserved.
  * Copyright (c) 2004 Topspin Corporation.  All rights reserved.
  * Copyright (c) 2004 Voltaire Corporation.  All rights reserved.
+ * Copyright (c) 2005 Cisco Systems.  All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
@@ -40,6 +41,7 @@
 #include <linux/err.h>
 
 #include <ib_verbs.h>
+#include <ib_cache.h>
 
 /* Protection domains */
 
@@ -47,10 +49,11 @@ struct ib_pd *ib_alloc_pd(struct ib_devi
 {
 	struct ib_pd *pd;
 
-	pd = device->alloc_pd(device);
+	pd = device->alloc_pd(device, NULL, NULL);
 
 	if (!IS_ERR(pd)) {
-		pd->device = device;
+		pd->device  = device;
+		pd->uobject = NULL;
 		atomic_set(&pd->usecnt, 0);
 	}
 
@@ -76,8 +79,9 @@ struct ib_ah *ib_create_ah(struct ib_pd 
 	ah = pd->device->create_ah(pd, ah_attr);
 
 	if (!IS_ERR(ah)) {
-		ah->device = pd->device;
-		ah->pd     = pd;
+		ah->device  = pd->device;
+		ah->pd      = pd;
+		ah->uobject = NULL;
 		atomic_inc(&pd->usecnt);
 	}
 
@@ -85,6 +89,40 @@ struct ib_ah *ib_create_ah(struct ib_pd 
 }
 EXPORT_SYMBOL(ib_create_ah);
 
+struct ib_ah *ib_create_ah_from_wc(struct ib_pd *pd, struct ib_wc *wc,
+				   struct ib_grh *grh, u8 port_num)
+{
+	struct ib_ah_attr ah_attr;
+	u32 flow_class;
+	u16 gid_index;
+	int ret;
+
+	memset(&ah_attr, 0, sizeof ah_attr);
+	ah_attr.dlid = wc->slid;
+	ah_attr.sl = wc->sl;
+	ah_attr.src_path_bits = wc->dlid_path_bits;
+	ah_attr.port_num = port_num;
+
+	if (wc->wc_flags & IB_WC_GRH) {
+		ah_attr.ah_flags = IB_AH_GRH;
+		ah_attr.grh.dgid = grh->dgid;
+
+		ret = ib_find_cached_gid(pd->device, &grh->sgid, &port_num,
+					 &gid_index);
+		if (ret)
+			return ERR_PTR(ret);
+
+		ah_attr.grh.sgid_index = (u8) gid_index;
+		flow_class = be32_to_cpu(grh->version_tclass_flow);
+		ah_attr.grh.flow_label = flow_class & 0xFFFFF;
+		ah_attr.grh.traffic_class = (flow_class >> 20) & 0xFF;
+		ah_attr.grh.hop_limit = grh->hop_limit;
+	}
+
+	return ib_create_ah(pd, &ah_attr);
+}
+EXPORT_SYMBOL(ib_create_ah_from_wc);
+
 int ib_modify_ah(struct ib_ah *ah, struct ib_ah_attr *ah_attr)
 {
 	return ah->device->modify_ah ?
@@ -122,7 +160,7 @@ struct ib_qp *ib_create_qp(struct ib_pd 
 {
 	struct ib_qp *qp;
 
-	qp = pd->device->create_qp(pd, qp_init_attr);
+	qp = pd->device->create_qp(pd, qp_init_attr, NULL);
 
 	if (!IS_ERR(qp)) {
 		qp->device     	  = pd->device;
@@ -130,6 +168,7 @@ struct ib_qp *ib_create_qp(struct ib_pd 
 		qp->send_cq    	  = qp_init_attr->send_cq;
 		qp->recv_cq    	  = qp_init_attr->recv_cq;
 		qp->srq	       	  = qp_init_attr->srq;
+		qp->uobject       = NULL;
 		qp->event_handler = qp_init_attr->event_handler;
 		qp->qp_context    = qp_init_attr->qp_context;
 		qp->qp_type	  = qp_init_attr->qp_type;
@@ -197,10 +236,11 @@ struct ib_cq *ib_create_cq(struct ib_dev
 {
 	struct ib_cq *cq;
 
-	cq = device->create_cq(device, cqe);
+	cq = device->create_cq(device, cqe, NULL, NULL);
 
 	if (!IS_ERR(cq)) {
 		cq->device        = device;
+		cq->uobject       = NULL;
 		cq->comp_handler  = comp_handler;
 		cq->event_handler = event_handler;
 		cq->cq_context    = cq_context;
@@ -245,8 +285,9 @@ struct ib_mr *ib_get_dma_mr(struct ib_pd
 	mr = pd->device->get_dma_mr(pd, mr_access_flags);
 
 	if (!IS_ERR(mr)) {
-		mr->device = pd->device;
-		mr->pd     = pd;
+		mr->device  = pd->device;
+		mr->pd      = pd;
+		mr->uobject = NULL;
 		atomic_inc(&pd->usecnt);
 		atomic_set(&mr->usecnt, 0);
 	}
@@ -267,8 +308,9 @@ struct ib_mr *ib_reg_phys_mr(struct ib_p
 				     mr_access_flags, iova_start);
 
 	if (!IS_ERR(mr)) {
-		mr->device = pd->device;
-		mr->pd     = pd;
+		mr->device  = pd->device;
+		mr->pd      = pd;
+		mr->uobject = NULL;
 		atomic_inc(&pd->usecnt);
 		atomic_set(&mr->usecnt, 0);
 	}
@@ -344,8 +386,9 @@ struct ib_mw *ib_alloc_mw(struct ib_pd *
 
 	mw = pd->device->alloc_mw(pd);
 	if (!IS_ERR(mw)) {
-		mw->device = pd->device;
-		mw->pd     = pd;
+		mw->device  = pd->device;
+		mw->pd      = pd;
+		mw->uobject = NULL;
 		atomic_inc(&pd->usecnt);
 	}
 
diff --git a/drivers/infiniband/hw/mthca/mthca_av.c b/drivers/infiniband/hw/mthca/mthca_av.c
--- a/drivers/infiniband/hw/mthca/mthca_av.c
+++ b/drivers/infiniband/hw/mthca/mthca_av.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2004 Topspin Communications.  All rights reserved.
+ * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.c b/drivers/infiniband/hw/mthca/mthca_cmd.c
--- a/drivers/infiniband/hw/mthca/mthca_cmd.c
+++ b/drivers/infiniband/hw/mthca/mthca_cmd.c
@@ -431,6 +431,36 @@ static int mthca_cmd_imm(struct mthca_de
 				      timeout, status);
 }
 
+int mthca_cmd_init(struct mthca_dev *dev)
+{
+	sema_init(&dev->cmd.hcr_sem, 1);
+	sema_init(&dev->cmd.poll_sem, 1);
+	dev->cmd.use_events = 0;
+
+	dev->hcr = ioremap(pci_resource_start(dev->pdev, 0) + MTHCA_HCR_BASE,
+			   MTHCA_HCR_SIZE);
+	if (!dev->hcr) {
+		mthca_err(dev, "Couldn't map command register.");
+		return -ENOMEM;
+	}
+
+	dev->cmd.pool = pci_pool_create("mthca_cmd", dev->pdev,
+					MTHCA_MAILBOX_SIZE,
+					MTHCA_MAILBOX_SIZE, 0);
+	if (!dev->cmd.pool) {
+		iounmap(dev->hcr);
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+void mthca_cmd_cleanup(struct mthca_dev *dev)
+{
+	pci_pool_destroy(dev->cmd.pool);
+	iounmap(dev->hcr);
+}
+
 /*
  * Switch to using events to issue FW commands (should be called after
  * event queue to command events has been initialized).
@@ -489,6 +519,33 @@ void mthca_cmd_use_polling(struct mthca_
 	up(&dev->cmd.poll_sem);
 }
 
+struct mthca_mailbox *mthca_alloc_mailbox(struct mthca_dev *dev,
+					  unsigned int gfp_mask)
+{
+	struct mthca_mailbox *mailbox;
+
+	mailbox = kmalloc(sizeof *mailbox, gfp_mask);
+	if (!mailbox)
+		return ERR_PTR(-ENOMEM);
+
+	mailbox->buf = pci_pool_alloc(dev->cmd.pool, gfp_mask, &mailbox->dma);
+	if (!mailbox->buf) {
+		kfree(mailbox);
+		return ERR_PTR(-ENOMEM);
+	}
+
+	return mailbox;
+}
+
+void mthca_free_mailbox(struct mthca_dev *dev, struct mthca_mailbox *mailbox)
+{
+	if (!mailbox)
+		return;
+
+	pci_pool_free(dev->cmd.pool, mailbox->buf, mailbox->dma);
+	kfree(mailbox);
+}
+
 int mthca_SYS_EN(struct mthca_dev *dev, u8 *status)
 {
 	u64 out;
@@ -513,20 +570,20 @@ int mthca_SYS_DIS(struct mthca_dev *dev,
 static int mthca_map_cmd(struct mthca_dev *dev, u16 op, struct mthca_icm *icm,
 			 u64 virt, u8 *status)
 {
-	u32 *inbox;
-	dma_addr_t indma;
+	struct mthca_mailbox *mailbox;
 	struct mthca_icm_iter iter;
+	__be64 *pages;
 	int lg;
 	int nent = 0;
 	int i;
 	int err = 0;
 	int ts = 0, tc = 0;
 
-	inbox = pci_alloc_consistent(dev->pdev, PAGE_SIZE, &indma);
-	if (!inbox)
-		return -ENOMEM;
-
-	memset(inbox, 0, PAGE_SIZE);
+	mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL);
+	if (IS_ERR(mailbox))
+		return PTR_ERR(mailbox);
+	memset(mailbox->buf, 0, MTHCA_MAILBOX_SIZE);
+	pages = mailbox->buf;
 
 	for (mthca_icm_first(icm, &iter);
 	     !mthca_icm_last(&iter);
@@ -546,19 +603,17 @@ static int mthca_map_cmd(struct mthca_de
 		}
 		for (i = 0; i < mthca_icm_size(&iter) / (1 << lg); ++i, ++nent) {
 			if (virt != -1) {
-				*((__be64 *) (inbox + nent * 4)) =
-					cpu_to_be64(virt);
+				pages[nent * 2] = cpu_to_be64(virt);
 				virt += 1 << lg;
 			}
 
-			*((__be64 *) (inbox + nent * 4 + 2)) =
-				cpu_to_be64((mthca_icm_addr(&iter) +
-					     (i << lg)) | (lg - 12));
+			pages[nent * 2 + 1] = cpu_to_be64((mthca_icm_addr(&iter) +
+							   (i << lg)) | (lg - 12));
 			ts += 1 << (lg - 10);
 			++tc;
 
-			if (nent == PAGE_SIZE / 16) {
-				err = mthca_cmd(dev, indma, nent, 0, op,
+			if (nent == MTHCA_MAILBOX_SIZE / 16) {
+				err = mthca_cmd(dev, mailbox->dma, nent, 0, op,
 						CMD_TIME_CLASS_B, status);
 				if (err || *status)
 					goto out;
@@ -568,7 +623,7 @@ static int mthca_map_cmd(struct mthca_de
 	}
 
 	if (nent)
-		err = mthca_cmd(dev, indma, nent, 0, op,
+		err = mthca_cmd(dev, mailbox->dma, nent, 0, op,
 				CMD_TIME_CLASS_B, status);
 
 	switch (op) {
@@ -585,7 +640,7 @@ static int mthca_map_cmd(struct mthca_de
 	}
 
 out:
-	pci_free_consistent(dev->pdev, PAGE_SIZE, inbox, indma);
+	mthca_free_mailbox(dev, mailbox);
 	return err;
 }
 
@@ -606,8 +661,8 @@ int mthca_RUN_FW(struct mthca_dev *dev, 
 
 int mthca_QUERY_FW(struct mthca_dev *dev, u8 *status)
 {
+	struct mthca_mailbox *mailbox;
 	u32 *outbox;
-	dma_addr_t outdma;
 	int err = 0;
 	u8 lg;
 
@@ -625,12 +680,12 @@ int mthca_QUERY_FW(struct mthca_dev *dev
 #define QUERY_FW_EQ_ARM_BASE_OFFSET    0x40
 #define QUERY_FW_EQ_SET_CI_BASE_OFFSET 0x48
 
-	outbox = pci_alloc_consistent(dev->pdev, QUERY_FW_OUT_SIZE, &outdma);
-	if (!outbox) {
-		return -ENOMEM;
-	}
+	mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL);
+	if (IS_ERR(mailbox))
+		return PTR_ERR(mailbox);
+	outbox = mailbox->buf;
 
-	err = mthca_cmd_box(dev, 0, outdma, 0, 0, CMD_QUERY_FW,
+	err = mthca_cmd_box(dev, 0, mailbox->dma, 0, 0, CMD_QUERY_FW,
 			    CMD_TIME_CLASS_A, status);
 
 	if (err)
@@ -681,15 +736,15 @@ int mthca_QUERY_FW(struct mthca_dev *dev
 	}
 
 out:
-	pci_free_consistent(dev->pdev, QUERY_FW_OUT_SIZE, outbox, outdma);
+	mthca_free_mailbox(dev, mailbox);
 	return err;
 }
 
 int mthca_ENABLE_LAM(struct mthca_dev *dev, u8 *status)
 {
+	struct mthca_mailbox *mailbox;
 	u8 info;
 	u32 *outbox;
-	dma_addr_t outdma;
 	int err = 0;
 
 #define ENABLE_LAM_OUT_SIZE         0x100
@@ -700,11 +755,12 @@ int mthca_ENABLE_LAM(struct mthca_dev *d
 #define ENABLE_LAM_INFO_HIDDEN_FLAG (1 << 4)
 #define ENABLE_LAM_INFO_ECC_MASK    0x3
 
-	outbox = pci_alloc_consistent(dev->pdev, ENABLE_LAM_OUT_SIZE, &outdma);
-	if (!outbox)
-		return -ENOMEM;
+	mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL);
+	if (IS_ERR(mailbox))
+		return PTR_ERR(mailbox);
+	outbox = mailbox->buf;
 
-	err = mthca_cmd_box(dev, 0, outdma, 0, 0, CMD_ENABLE_LAM,
+	err = mthca_cmd_box(dev, 0, mailbox->dma, 0, 0, CMD_ENABLE_LAM,
 			    CMD_TIME_CLASS_C, status);
 
 	if (err)
@@ -733,7 +789,7 @@ int mthca_ENABLE_LAM(struct mthca_dev *d
 		  (unsigned long long) dev->ddr_end);
 
 out:
-	pci_free_consistent(dev->pdev, ENABLE_LAM_OUT_SIZE, outbox, outdma);
+	mthca_free_mailbox(dev, mailbox);
 	return err;
 }
 
@@ -744,9 +800,9 @@ int mthca_DISABLE_LAM(struct mthca_dev *
 
 int mthca_QUERY_DDR(struct mthca_dev *dev, u8 *status)
 {
+	struct mthca_mailbox *mailbox;
 	u8 info;
 	u32 *outbox;
-	dma_addr_t outdma;
 	int err = 0;
 
 #define QUERY_DDR_OUT_SIZE         0x100
@@ -757,11 +813,12 @@ int mthca_QUERY_DDR(struct mthca_dev *de
 #define QUERY_DDR_INFO_HIDDEN_FLAG (1 << 4)
 #define QUERY_DDR_INFO_ECC_MASK    0x3
 
-	outbox = pci_alloc_consistent(dev->pdev, QUERY_DDR_OUT_SIZE, &outdma);
-	if (!outbox)
-		return -ENOMEM;
+	mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL);
+	if (IS_ERR(mailbox))
+		return PTR_ERR(mailbox);
+	outbox = mailbox->buf;
 
-	err = mthca_cmd_box(dev, 0, outdma, 0, 0, CMD_QUERY_DDR,
+	err = mthca_cmd_box(dev, 0, mailbox->dma, 0, 0, CMD_QUERY_DDR,
 			    CMD_TIME_CLASS_A, status);
 
 	if (err)
@@ -787,15 +844,15 @@ int mthca_QUERY_DDR(struct mthca_dev *de
 		  (unsigned long long) dev->ddr_end);
 
 out:
-	pci_free_consistent(dev->pdev, QUERY_DDR_OUT_SIZE, outbox, outdma);
+	mthca_free_mailbox(dev, mailbox);
 	return err;
 }
 
 int mthca_QUERY_DEV_LIM(struct mthca_dev *dev,
 			struct mthca_dev_lim *dev_lim, u8 *status)
 {
+	struct mthca_mailbox *mailbox;
 	u32 *outbox;
-	dma_addr_t outdma;
 	u8 field;
 	u16 size;
 	int err;
@@ -860,11 +917,12 @@ int mthca_QUERY_DEV_LIM(struct mthca_dev
 #define QUERY_DEV_LIM_LAMR_OFFSET           0x9f
 #define QUERY_DEV_LIM_MAX_ICM_SZ_OFFSET     0xa0
 
-	outbox = pci_alloc_consistent(dev->pdev, QUERY_DEV_LIM_OUT_SIZE, &outdma);
-	if (!outbox)
-		return -ENOMEM;
+	mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL);
+	if (IS_ERR(mailbox))
+		return PTR_ERR(mailbox);
+	outbox = mailbox->buf;
 
-	err = mthca_cmd_box(dev, 0, outdma, 0, 0, CMD_QUERY_DEV_LIM,
+	err = mthca_cmd_box(dev, 0, mailbox->dma, 0, 0, CMD_QUERY_DEV_LIM,
 			    CMD_TIME_CLASS_A, status);
 
 	if (err)
@@ -1020,15 +1078,15 @@ int mthca_QUERY_DEV_LIM(struct mthca_dev
 	}
 
 out:
-	pci_free_consistent(dev->pdev, QUERY_DEV_LIM_OUT_SIZE, outbox, outdma);
+	mthca_free_mailbox(dev, mailbox);
 	return err;
 }
 
 int mthca_QUERY_ADAPTER(struct mthca_dev *dev,
 			struct mthca_adapter *adapter, u8 *status)
 {
+	struct mthca_mailbox *mailbox;
 	u32 *outbox;
-	dma_addr_t outdma;
 	int err;
 
 #define QUERY_ADAPTER_OUT_SIZE             0x100
@@ -1037,23 +1095,24 @@ int mthca_QUERY_ADAPTER(struct mthca_dev
 #define QUERY_ADAPTER_REVISION_ID_OFFSET   0x08
 #define QUERY_ADAPTER_INTA_PIN_OFFSET      0x10
 
-	outbox = pci_alloc_consistent(dev->pdev, QUERY_ADAPTER_OUT_SIZE, &outdma);
-	if (!outbox)
-		return -ENOMEM;
+	mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL);
+	if (IS_ERR(mailbox))
+		return PTR_ERR(mailbox);
+	outbox = mailbox->buf;
 
-	err = mthca_cmd_box(dev, 0, outdma, 0, 0, CMD_QUERY_ADAPTER,
+	err = mthca_cmd_box(dev, 0, mailbox->dma, 0, 0, CMD_QUERY_ADAPTER,
 			    CMD_TIME_CLASS_A, status);
 
 	if (err)
 		goto out;
 
-	MTHCA_GET(adapter->vendor_id, outbox, QUERY_ADAPTER_VENDOR_ID_OFFSET);
-	MTHCA_GET(adapter->device_id, outbox, QUERY_ADAPTER_DEVICE_ID_OFFSET);
+	MTHCA_GET(adapter->vendor_id, outbox,   QUERY_ADAPTER_VENDOR_ID_OFFSET);
+	MTHCA_GET(adapter->device_id, outbox,   QUERY_ADAPTER_DEVICE_ID_OFFSET);
 	MTHCA_GET(adapter->revision_id, outbox, QUERY_ADAPTER_REVISION_ID_OFFSET);
-	MTHCA_GET(adapter->inta_pin, outbox, QUERY_ADAPTER_INTA_PIN_OFFSET);
+	MTHCA_GET(adapter->inta_pin, outbox,    QUERY_ADAPTER_INTA_PIN_OFFSET);
 
 out:
-	pci_free_consistent(dev->pdev, QUERY_DEV_LIM_OUT_SIZE, outbox, outdma);
+	mthca_free_mailbox(dev, mailbox);
 	return err;
 }
 
@@ -1061,8 +1120,8 @@ int mthca_INIT_HCA(struct mthca_dev *dev
 		   struct mthca_init_hca_param *param,
 		   u8 *status)
 {
+	struct mthca_mailbox *mailbox;
 	u32 *inbox;
-	dma_addr_t indma;
 	int err;
 
 #define INIT_HCA_IN_SIZE             	 0x200
@@ -1102,9 +1161,10 @@ int mthca_INIT_HCA(struct mthca_dev *dev
 #define  INIT_HCA_UAR_SCATCH_BASE_OFFSET (INIT_HCA_UAR_OFFSET + 0x10)
 #define  INIT_HCA_UAR_CTX_BASE_OFFSET    (INIT_HCA_UAR_OFFSET + 0x18)
 
-	inbox = pci_alloc_consistent(dev->pdev, INIT_HCA_IN_SIZE, &indma);
-	if (!inbox)
-		return -ENOMEM;
+	mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL);
+	if (IS_ERR(mailbox))
+		return PTR_ERR(mailbox);
+	inbox = mailbox->buf;
 
 	memset(inbox, 0, INIT_HCA_IN_SIZE);
 
@@ -1167,10 +1227,9 @@ int mthca_INIT_HCA(struct mthca_dev *dev
 		MTHCA_PUT(inbox, param->uarc_base,   INIT_HCA_UAR_CTX_BASE_OFFSET);
 	}
 
-	err = mthca_cmd(dev, indma, 0, 0, CMD_INIT_HCA,
-			HZ, status);
+	err = mthca_cmd(dev, mailbox->dma, 0, 0, CMD_INIT_HCA, HZ, status);
 
-	pci_free_consistent(dev->pdev, INIT_HCA_IN_SIZE, inbox, indma);
+	mthca_free_mailbox(dev, mailbox);
 	return err;
 }
 
@@ -1178,8 +1237,8 @@ int mthca_INIT_IB(struct mthca_dev *dev,
 		  struct mthca_init_ib_param *param,
 		  int port, u8 *status)
 {
+	struct mthca_mailbox *mailbox;
 	u32 *inbox;
-	dma_addr_t indma;
 	int err;
 	u32 flags;
 
@@ -1199,9 +1258,10 @@ int mthca_INIT_IB(struct mthca_dev *dev,
 #define INIT_IB_NODE_GUID_OFFSET 0x18
 #define INIT_IB_SI_GUID_OFFSET   0x20
 
-	inbox = pci_alloc_consistent(dev->pdev, INIT_IB_IN_SIZE, &indma);
-	if (!inbox)
-		return -ENOMEM;
+	mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL);
+	if (IS_ERR(mailbox))
+		return PTR_ERR(mailbox);
+	inbox = mailbox->buf;
 
 	memset(inbox, 0, INIT_IB_IN_SIZE);
 
@@ -1221,10 +1281,10 @@ int mthca_INIT_IB(struct mthca_dev *dev,
 	MTHCA_PUT(inbox, param->node_guid, INIT_IB_NODE_GUID_OFFSET);
 	MTHCA_PUT(inbox, param->si_guid,   INIT_IB_SI_GUID_OFFSET);
 
-	err = mthca_cmd(dev, indma, port, 0, CMD_INIT_IB,
+	err = mthca_cmd(dev, mailbox->dma, port, 0, CMD_INIT_IB,
 			CMD_TIME_CLASS_A, status);
 
-	pci_free_consistent(dev->pdev, INIT_HCA_IN_SIZE, inbox, indma);
+	mthca_free_mailbox(dev, mailbox);
 	return err;
 }
 
@@ -1241,8 +1301,8 @@ int mthca_CLOSE_HCA(struct mthca_dev *de
 int mthca_SET_IB(struct mthca_dev *dev, struct mthca_set_ib_param *param,
 		 int port, u8 *status)
 {
+	struct mthca_mailbox *mailbox;
 	u32 *inbox;
-	dma_addr_t indma;
 	int err;
 	u32 flags = 0;
 
@@ -1253,9 +1313,10 @@ int mthca_SET_IB(struct mthca_dev *dev, 
 #define SET_IB_CAP_MASK_OFFSET 0x04
 #define SET_IB_SI_GUID_OFFSET  0x08
 
-	inbox = pci_alloc_consistent(dev->pdev, SET_IB_IN_SIZE, &indma);
-	if (!inbox)
-		return -ENOMEM;
+	mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL);
+	if (IS_ERR(mailbox))
+		return PTR_ERR(mailbox);
+	inbox = mailbox->buf;
 
 	memset(inbox, 0, SET_IB_IN_SIZE);
 
@@ -1266,10 +1327,10 @@ int mthca_SET_IB(struct mthca_dev *dev, 
 	MTHCA_PUT(inbox, param->cap_mask, SET_IB_CAP_MASK_OFFSET);
 	MTHCA_PUT(inbox, param->si_guid,  SET_IB_SI_GUID_OFFSET);
 
-	err = mthca_cmd(dev, indma, port, 0, CMD_SET_IB,
+	err = mthca_cmd(dev, mailbox->dma, port, 0, CMD_SET_IB,
 			CMD_TIME_CLASS_B, status);
 
-	pci_free_consistent(dev->pdev, INIT_HCA_IN_SIZE, inbox, indma);
+	mthca_free_mailbox(dev, mailbox);
 	return err;
 }
 
@@ -1280,20 +1341,22 @@ int mthca_MAP_ICM(struct mthca_dev *dev,
 
 int mthca_MAP_ICM_page(struct mthca_dev *dev, u64 dma_addr, u64 virt, u8 *status)
 {
+	struct mthca_mailbox *mailbox;
 	u64 *inbox;
-	dma_addr_t indma;
 	int err;
 
-	inbox = pci_alloc_consistent(dev->pdev, 16, &indma);
-	if (!inbox)
-		return -ENOMEM;
+	mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL);
+	if (IS_ERR(mailbox))
+		return PTR_ERR(mailbox);
+	inbox = mailbox->buf;
 
 	inbox[0] = cpu_to_be64(virt);
 	inbox[1] = cpu_to_be64(dma_addr);
 
-	err = mthca_cmd(dev, indma, 1, 0, CMD_MAP_ICM, CMD_TIME_CLASS_B, status);
+	err = mthca_cmd(dev, mailbox->dma, 1, 0, CMD_MAP_ICM,
+			CMD_TIME_CLASS_B, status);
 
-	pci_free_consistent(dev->pdev, 16, inbox, indma);
+	mthca_free_mailbox(dev, mailbox);
 
 	if (!err)
 		mthca_dbg(dev, "Mapped page at %llx to %llx for ICM.\n",
@@ -1338,69 +1401,26 @@ int mthca_SET_ICM_SIZE(struct mthca_dev 
 	return 0;
 }
 
-int mthca_SW2HW_MPT(struct mthca_dev *dev, void *mpt_entry,
+int mthca_SW2HW_MPT(struct mthca_dev *dev, struct mthca_mailbox *mailbox,
 		    int mpt_index, u8 *status)
 {
-	dma_addr_t indma;
-	int err;
-
-	indma = pci_map_single(dev->pdev, mpt_entry,
-			       MTHCA_MPT_ENTRY_SIZE,
-			       PCI_DMA_TODEVICE);
-	if (pci_dma_mapping_error(indma))
-		return -ENOMEM;
-
-	err = mthca_cmd(dev, indma, mpt_index, 0, CMD_SW2HW_MPT,
-			CMD_TIME_CLASS_B, status);
-
-	pci_unmap_single(dev->pdev, indma,
-			 MTHCA_MPT_ENTRY_SIZE, PCI_DMA_TODEVICE);
-	return err;
+	return mthca_cmd(dev, mailbox->dma, mpt_index, 0, CMD_SW2HW_MPT,
+			 CMD_TIME_CLASS_B, status);
 }
 
-int mthca_HW2SW_MPT(struct mthca_dev *dev, void *mpt_entry,
+int mthca_HW2SW_MPT(struct mthca_dev *dev, struct mthca_mailbox *mailbox,
 		    int mpt_index, u8 *status)
 {
-	dma_addr_t outdma = 0;
-	int err;
-
-	if (mpt_entry) {
-		outdma = pci_map_single(dev->pdev, mpt_entry,
-					MTHCA_MPT_ENTRY_SIZE,
-					PCI_DMA_FROMDEVICE);
-		if (pci_dma_mapping_error(outdma))
-			return -ENOMEM;
-	}
-
-	err = mthca_cmd_box(dev, 0, outdma, mpt_index, !mpt_entry,
-			    CMD_HW2SW_MPT,
-			    CMD_TIME_CLASS_B, status);
-
-	if (mpt_entry)
-		pci_unmap_single(dev->pdev, outdma,
-				 MTHCA_MPT_ENTRY_SIZE,
-				 PCI_DMA_FROMDEVICE);
-	return err;
+	return mthca_cmd_box(dev, 0, mailbox ? mailbox->dma : 0, mpt_index,
+			     !mailbox, CMD_HW2SW_MPT,
+			     CMD_TIME_CLASS_B, status);
 }
 
-int mthca_WRITE_MTT(struct mthca_dev *dev, u64 *mtt_entry,
+int mthca_WRITE_MTT(struct mthca_dev *dev, struct mthca_mailbox *mailbox,
 		    int num_mtt, u8 *status)
 {
-	dma_addr_t indma;
-	int err;
-
-	indma = pci_map_single(dev->pdev, mtt_entry,
-			       (num_mtt + 2) * 8,
-			       PCI_DMA_TODEVICE);
-	if (pci_dma_mapping_error(indma))
-		return -ENOMEM;
-
-	err = mthca_cmd(dev, indma, num_mtt, 0, CMD_WRITE_MTT,
-			CMD_TIME_CLASS_B, status);
-
-	pci_unmap_single(dev->pdev, indma,
-			 (num_mtt + 2) * 8, PCI_DMA_TODEVICE);
-	return err;
+	return mthca_cmd(dev, mailbox->dma, num_mtt, 0, CMD_WRITE_MTT,
+			 CMD_TIME_CLASS_B, status);
 }
 
 int mthca_SYNC_TPT(struct mthca_dev *dev, u8 *status)
@@ -1418,92 +1438,38 @@ int mthca_MAP_EQ(struct mthca_dev *dev, 
 			 0, CMD_MAP_EQ, CMD_TIME_CLASS_B, status);
 }
 
-int mthca_SW2HW_EQ(struct mthca_dev *dev, void *eq_context,
+int mthca_SW2HW_EQ(struct mthca_dev *dev, struct mthca_mailbox *mailbox,
 		   int eq_num, u8 *status)
 {
-	dma_addr_t indma;
-	int err;
-
-	indma = pci_map_single(dev->pdev, eq_context,
-			       MTHCA_EQ_CONTEXT_SIZE,
-			       PCI_DMA_TODEVICE);
-	if (pci_dma_mapping_error(indma))
-		return -ENOMEM;
-
-	err = mthca_cmd(dev, indma, eq_num, 0, CMD_SW2HW_EQ,
-			CMD_TIME_CLASS_A, status);
-
-	pci_unmap_single(dev->pdev, indma,
-			 MTHCA_EQ_CONTEXT_SIZE, PCI_DMA_TODEVICE);
-	return err;
+	return mthca_cmd(dev, mailbox->dma, eq_num, 0, CMD_SW2HW_EQ,
+			 CMD_TIME_CLASS_A, status);
 }
 
-int mthca_HW2SW_EQ(struct mthca_dev *dev, void *eq_context,
+int mthca_HW2SW_EQ(struct mthca_dev *dev, struct mthca_mailbox *mailbox,
 		   int eq_num, u8 *status)
 {
-	dma_addr_t outdma = 0;
-	int err;
-
-	outdma = pci_map_single(dev->pdev, eq_context,
-				MTHCA_EQ_CONTEXT_SIZE,
-				PCI_DMA_FROMDEVICE);
-	if (pci_dma_mapping_error(outdma))
-		return -ENOMEM;
-
-	err = mthca_cmd_box(dev, 0, outdma, eq_num, 0,
-			    CMD_HW2SW_EQ,
-			    CMD_TIME_CLASS_A, status);
-
-	pci_unmap_single(dev->pdev, outdma,
-			 MTHCA_EQ_CONTEXT_SIZE,
-			 PCI_DMA_FROMDEVICE);
-	return err;
+	return mthca_cmd_box(dev, 0, mailbox->dma, eq_num, 0,
+			     CMD_HW2SW_EQ,
+			     CMD_TIME_CLASS_A, status);
 }
 
-int mthca_SW2HW_CQ(struct mthca_dev *dev, void *cq_context,
+int mthca_SW2HW_CQ(struct mthca_dev *dev, struct mthca_mailbox *mailbox,
 		   int cq_num, u8 *status)
 {
-	dma_addr_t indma;
-	int err;
-
-	indma = pci_map_single(dev->pdev, cq_context,
-			       MTHCA_CQ_CONTEXT_SIZE,
-			       PCI_DMA_TODEVICE);
-	if (pci_dma_mapping_error(indma))
-		return -ENOMEM;
-
-	err = mthca_cmd(dev, indma, cq_num, 0, CMD_SW2HW_CQ,
+	return mthca_cmd(dev, mailbox->dma, cq_num, 0, CMD_SW2HW_CQ,
 			CMD_TIME_CLASS_A, status);
-
-	pci_unmap_single(dev->pdev, indma,
-			 MTHCA_CQ_CONTEXT_SIZE, PCI_DMA_TODEVICE);
-	return err;
 }
 
-int mthca_HW2SW_CQ(struct mthca_dev *dev, void *cq_context,
+int mthca_HW2SW_CQ(struct mthca_dev *dev, struct mthca_mailbox *mailbox,
 		   int cq_num, u8 *status)
 {
-	dma_addr_t outdma = 0;
-	int err;
-
-	outdma = pci_map_single(dev->pdev, cq_context,
-				MTHCA_CQ_CONTEXT_SIZE,
-				PCI_DMA_FROMDEVICE);
-	if (pci_dma_mapping_error(outdma))
-		return -ENOMEM;
-
-	err = mthca_cmd_box(dev, 0, outdma, cq_num, 0,
-			    CMD_HW2SW_CQ,
-			    CMD_TIME_CLASS_A, status);
-
-	pci_unmap_single(dev->pdev, outdma,
-			 MTHCA_CQ_CONTEXT_SIZE,
-			 PCI_DMA_FROMDEVICE);
-	return err;
+	return mthca_cmd_box(dev, 0, mailbox->dma, cq_num, 0,
+			     CMD_HW2SW_CQ,
+			     CMD_TIME_CLASS_A, status);
 }
 
 int mthca_MODIFY_QP(struct mthca_dev *dev, int trans, u32 num,
-		    int is_ee, void *qp_context, u32 optmask,
+		    int is_ee, struct mthca_mailbox *mailbox, u32 optmask,
 		    u8 *status)
 {
 	static const u16 op[] = {
@@ -1520,36 +1486,34 @@ int mthca_MODIFY_QP(struct mthca_dev *de
 		[MTHCA_TRANS_ANY2RST]   = CMD_ERR2RST_QPEE
 	};
 	u8 op_mod = 0;
-
-	dma_addr_t indma;
+	int my_mailbox = 0;
 	int err;
 
 	if (trans < 0 || trans >= ARRAY_SIZE(op))
 		return -EINVAL;
 
 	if (trans == MTHCA_TRANS_ANY2RST) {
-		indma  = 0;
 		op_mod = 3;	/* don't write outbox, any->reset */
 
 		/* For debugging */
-		qp_context = pci_alloc_consistent(dev->pdev, MTHCA_QP_CONTEXT_SIZE,
-						  &indma);
-		op_mod = 2;	/* write outbox, any->reset */
+		if (!mailbox) {
+			mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL);
+			if (!IS_ERR(mailbox)) {
+				my_mailbox = 1;
+				op_mod     = 2;	/* write outbox, any->reset */
+			} else
+				mailbox = NULL;
+		}
 	} else {
-		indma = pci_map_single(dev->pdev, qp_context,
-				       MTHCA_QP_CONTEXT_SIZE,
-				       PCI_DMA_TODEVICE);
-		if (pci_dma_mapping_error(indma))
-			return -ENOMEM;
-
 		if (0) {
 			int i;
 			mthca_dbg(dev, "Dumping QP context:\n");
-			printk("  opt param mask: %08x\n", be32_to_cpup(qp_context));
+			printk("  opt param mask: %08x\n", be32_to_cpup(mailbox->buf));
 			for (i = 0; i < 0x100 / 4; ++i) {
 				if (i % 8 == 0)
 					printk("  [%02x] ", i * 4);
-				printk(" %08x", be32_to_cpu(((u32 *) qp_context)[i + 2]));
+				printk(" %08x",
+				       be32_to_cpu(((u32 *) mailbox->buf)[i + 2]));
 				if ((i + 1) % 8 == 0)
 					printk("\n");
 			}
@@ -1557,55 +1521,39 @@ int mthca_MODIFY_QP(struct mthca_dev *de
 	}
 
 	if (trans == MTHCA_TRANS_ANY2RST) {
-		err = mthca_cmd_box(dev, 0, indma, (!!is_ee << 24) | num,
-				    op_mod, op[trans], CMD_TIME_CLASS_C, status);
+		err = mthca_cmd_box(dev, 0, mailbox ? mailbox->dma : 0,
+				    (!!is_ee << 24) | num, op_mod,
+				    op[trans], CMD_TIME_CLASS_C, status);
 
-		if (0) {
+		if (0 && mailbox) {
 			int i;
 			mthca_dbg(dev, "Dumping QP context:\n");
-			printk(" %08x\n", be32_to_cpup(qp_context));
+			printk(" %08x\n", be32_to_cpup(mailbox->buf));
 			for (i = 0; i < 0x100 / 4; ++i) {
 				if (i % 8 == 0)
 					printk("[%02x] ", i * 4);
-				printk(" %08x", be32_to_cpu(((u32 *) qp_context)[i + 2]));
+				printk(" %08x",
+				       be32_to_cpu(((u32 *) mailbox->buf)[i + 2]));
 				if ((i + 1) % 8 == 0)
 					printk("\n");
 			}
 		}
 
 	} else
-		err = mthca_cmd(dev, indma, (!!is_ee << 24) | num,
+		err = mthca_cmd(dev, mailbox->dma, (!!is_ee << 24) | num,
 				op_mod, op[trans], CMD_TIME_CLASS_C, status);
 
-	if (trans != MTHCA_TRANS_ANY2RST)
-		pci_unmap_single(dev->pdev, indma,
-				 MTHCA_QP_CONTEXT_SIZE, PCI_DMA_TODEVICE);
-	else
-		pci_free_consistent(dev->pdev, MTHCA_QP_CONTEXT_SIZE,
-				    qp_context, indma);
+	if (my_mailbox)
+		mthca_free_mailbox(dev, mailbox);
+
 	return err;
 }
 
 int mthca_QUERY_QP(struct mthca_dev *dev, u32 num, int is_ee,
-		   void *qp_context, u8 *status)
+		   struct mthca_mailbox *mailbox, u8 *status)
 {
-	dma_addr_t outdma = 0;
-	int err;
-
-	outdma = pci_map_single(dev->pdev, qp_context,
-				MTHCA_QP_CONTEXT_SIZE,
-				PCI_DMA_FROMDEVICE);
-	if (pci_dma_mapping_error(outdma))
-		return -ENOMEM;
-
-	err = mthca_cmd_box(dev, 0, outdma, (!!is_ee << 24) | num, 0,
-			    CMD_QUERY_QPEE,
-			    CMD_TIME_CLASS_A, status);
-
-	pci_unmap_single(dev->pdev, outdma,
-			 MTHCA_QP_CONTEXT_SIZE,
-			 PCI_DMA_FROMDEVICE);
-	return err;
+	return mthca_cmd_box(dev, 0, mailbox->dma, (!!is_ee << 24) | num, 0,
+			     CMD_QUERY_QPEE, CMD_TIME_CLASS_A, status);
 }
 
 int mthca_CONF_SPECIAL_QP(struct mthca_dev *dev, int type, u32 qpn,
@@ -1635,11 +1583,11 @@ int mthca_CONF_SPECIAL_QP(struct mthca_d
 }
 
 int mthca_MAD_IFC(struct mthca_dev *dev, int ignore_mkey, int ignore_bkey,
-		  int port, struct ib_wc* in_wc, struct ib_grh* in_grh,
+		  int port, struct ib_wc *in_wc, struct ib_grh *in_grh,
 		  void *in_mad, void *response_mad, u8 *status)
 {
-	void *box;
-	dma_addr_t dma;
+	struct mthca_mailbox *inmailbox, *outmailbox;
+	void *inbox;
 	int err;
 	u32 in_modifier = port;
 	u8 op_modifier = 0;
@@ -1653,11 +1601,18 @@ int mthca_MAD_IFC(struct mthca_dev *dev,
 #define MAD_IFC_PKEY_OFFSET   0x10e
 #define MAD_IFC_GRH_OFFSET    0x140
 
-	box = pci_alloc_consistent(dev->pdev, MAD_IFC_BOX_SIZE, &dma);
-	if (!box)
-		return -ENOMEM;
+	inmailbox = mthca_alloc_mailbox(dev, GFP_KERNEL);
+	if (IS_ERR(inmailbox))
+		return PTR_ERR(inmailbox);
+	inbox = inmailbox->buf;
+
+	outmailbox = mthca_alloc_mailbox(dev, GFP_KERNEL);
+	if (IS_ERR(outmailbox)) {
+		mthca_free_mailbox(dev, inmailbox);
+		return PTR_ERR(outmailbox);
+	}
 
-	memcpy(box, in_mad, 256);
+	memcpy(inbox, in_mad, 256);
 
 	/*
 	 * Key check traps can't be generated unless we have in_wc to
@@ -1671,97 +1626,65 @@ int mthca_MAD_IFC(struct mthca_dev *dev,
 	if (in_wc) {
 		u8 val;
 
-		memset(box + 256, 0, 256);
+		memset(inbox + 256, 0, 256);
 
-		MTHCA_PUT(box, in_wc->qp_num, 	  MAD_IFC_MY_QPN_OFFSET);
-		MTHCA_PUT(box, in_wc->src_qp, 	  MAD_IFC_RQPN_OFFSET);
+		MTHCA_PUT(inbox, in_wc->qp_num,     MAD_IFC_MY_QPN_OFFSET);
+		MTHCA_PUT(inbox, in_wc->src_qp,     MAD_IFC_RQPN_OFFSET);
 
 		val = in_wc->sl << 4;
-		MTHCA_PUT(box, val,               MAD_IFC_SL_OFFSET);
+		MTHCA_PUT(inbox, val,               MAD_IFC_SL_OFFSET);
 
 		val = in_wc->dlid_path_bits |
 			(in_wc->wc_flags & IB_WC_GRH ? 0x80 : 0);
-		MTHCA_PUT(box, val,               MAD_IFC_GRH_OFFSET);
+		MTHCA_PUT(inbox, val,               MAD_IFC_GRH_OFFSET);
 
-		MTHCA_PUT(box, in_wc->slid,       MAD_IFC_RLID_OFFSET);
-		MTHCA_PUT(box, in_wc->pkey_index, MAD_IFC_PKEY_OFFSET);
+		MTHCA_PUT(inbox, in_wc->slid,       MAD_IFC_RLID_OFFSET);
+		MTHCA_PUT(inbox, in_wc->pkey_index, MAD_IFC_PKEY_OFFSET);
 
 		if (in_grh)
-			memcpy((u8 *) box + MAD_IFC_GRH_OFFSET, in_grh, 40);
+			memcpy(inbox + MAD_IFC_GRH_OFFSET, in_grh, 40);
 
 		op_modifier |= 0x10;
 
 		in_modifier |= in_wc->slid << 16;
 	}
 
-	err = mthca_cmd_box(dev, dma, dma + 512, in_modifier, op_modifier,
+	err = mthca_cmd_box(dev, inmailbox->dma, outmailbox->dma,
+			    in_modifier, op_modifier,
 			    CMD_MAD_IFC, CMD_TIME_CLASS_C, status);
 
 	if (!err && !*status)
-		memcpy(response_mad, box + 512, 256);
+		memcpy(response_mad, outmailbox->buf, 256);
 
-	pci_free_consistent(dev->pdev, MAD_IFC_BOX_SIZE, box, dma);
+	mthca_free_mailbox(dev, inmailbox);
+	mthca_free_mailbox(dev, outmailbox);
 	return err;
 }
 
-int mthca_READ_MGM(struct mthca_dev *dev, int index, void *mgm,
-		   u8 *status)
+int mthca_READ_MGM(struct mthca_dev *dev, int index,
+		   struct mthca_mailbox *mailbox, u8 *status)
 {
-	dma_addr_t outdma = 0;
-	int err;
-
-	outdma = pci_map_single(dev->pdev, mgm,
-				MTHCA_MGM_ENTRY_SIZE,
-				PCI_DMA_FROMDEVICE);
-	if (pci_dma_mapping_error(outdma))
-		return -ENOMEM;
-
-	err = mthca_cmd_box(dev, 0, outdma, index, 0,
-			    CMD_READ_MGM,
-			    CMD_TIME_CLASS_A, status);
-
-	pci_unmap_single(dev->pdev, outdma,
-			 MTHCA_MGM_ENTRY_SIZE,
-			 PCI_DMA_FROMDEVICE);
-	return err;
+	return mthca_cmd_box(dev, 0, mailbox->dma, index, 0,
+			     CMD_READ_MGM, CMD_TIME_CLASS_A, status);
 }
 
-int mthca_WRITE_MGM(struct mthca_dev *dev, int index, void *mgm,
-		    u8 *status)
+int mthca_WRITE_MGM(struct mthca_dev *dev, int index,
+		    struct mthca_mailbox *mailbox, u8 *status)
 {
-	dma_addr_t indma;
-	int err;
-
-	indma = pci_map_single(dev->pdev, mgm,
-			       MTHCA_MGM_ENTRY_SIZE,
-			       PCI_DMA_TODEVICE);
-	if (pci_dma_mapping_error(indma))
-		return -ENOMEM;
-
-	err = mthca_cmd(dev, indma, index, 0, CMD_WRITE_MGM,
-			CMD_TIME_CLASS_A, status);
-
-	pci_unmap_single(dev->pdev, indma,
-			 MTHCA_MGM_ENTRY_SIZE, PCI_DMA_TODEVICE);
-	return err;
+	return mthca_cmd(dev, mailbox->dma, index, 0, CMD_WRITE_MGM,
+			 CMD_TIME_CLASS_A, status);
 }
 
-int mthca_MGID_HASH(struct mthca_dev *dev, void *gid, u16 *hash,
-		    u8 *status)
+int mthca_MGID_HASH(struct mthca_dev *dev, struct mthca_mailbox *mailbox,
+		    u16 *hash, u8 *status)
 {
-	dma_addr_t indma;
 	u64 imm;
 	int err;
 
-	indma = pci_map_single(dev->pdev, gid, 16, PCI_DMA_TODEVICE);
-	if (pci_dma_mapping_error(indma))
-		return -ENOMEM;
-
-	err = mthca_cmd_imm(dev, indma, &imm, 0, 0, CMD_MGID_HASH,
+	err = mthca_cmd_imm(dev, mailbox->dma, &imm, 0, 0, CMD_MGID_HASH,
 			    CMD_TIME_CLASS_A, status);
-	*hash = imm;
 
-	pci_unmap_single(dev->pdev, indma, 16, PCI_DMA_TODEVICE);
+	*hash = imm;
 	return err;
 }
 
diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.h b/drivers/infiniband/hw/mthca/mthca_cmd.h
--- a/drivers/infiniband/hw/mthca/mthca_cmd.h
+++ b/drivers/infiniband/hw/mthca/mthca_cmd.h
@@ -37,8 +37,7 @@
 
 #include <ib_verbs.h>
 
-#define MTHCA_CMD_MAILBOX_ALIGN 16UL
-#define MTHCA_CMD_MAILBOX_EXTRA (MTHCA_CMD_MAILBOX_ALIGN - 1)
+#define MTHCA_MAILBOX_SIZE 4096
 
 enum {
 	/* command completed successfully: */
@@ -112,6 +111,11 @@ enum {
 	DEV_LIM_FLAG_UD_MULTI           = 1 << 21,
 };
 
+struct mthca_mailbox {
+	dma_addr_t dma;
+	void      *buf;
+};
+
 struct mthca_dev_lim {
 	int max_srq_sz;
 	int max_qp_sz;
@@ -235,11 +239,17 @@ struct mthca_set_ib_param {
 	u32 cap_mask;
 };
 
+int mthca_cmd_init(struct mthca_dev *dev);
+void mthca_cmd_cleanup(struct mthca_dev *dev);
 int mthca_cmd_use_events(struct mthca_dev *dev);
 void mthca_cmd_use_polling(struct mthca_dev *dev);
 void mthca_cmd_event(struct mthca_dev *dev, u16 token,
 		     u8  status, u64 out_param);
 
+struct mthca_mailbox *mthca_alloc_mailbox(struct mthca_dev *dev,
+					  unsigned int gfp_mask);
+void mthca_free_mailbox(struct mthca_dev *dev, struct mthca_mailbox *mailbox);
+
 int mthca_SYS_EN(struct mthca_dev *dev, u8 *status);
 int mthca_SYS_DIS(struct mthca_dev *dev, u8 *status);
 int mthca_MAP_FA(struct mthca_dev *dev, struct mthca_icm *icm, u8 *status);
@@ -270,41 +280,39 @@ int mthca_MAP_ICM_AUX(struct mthca_dev *
 int mthca_UNMAP_ICM_AUX(struct mthca_dev *dev, u8 *status);
 int mthca_SET_ICM_SIZE(struct mthca_dev *dev, u64 icm_size, u64 *aux_pages,
 		       u8 *status);
-int mthca_SW2HW_MPT(struct mthca_dev *dev, void *mpt_entry,
+int mthca_SW2HW_MPT(struct mthca_dev *dev, struct mthca_mailbox *mailbox,
 		    int mpt_index, u8 *status);
-int mthca_HW2SW_MPT(struct mthca_dev *dev, void *mpt_entry,
+int mthca_HW2SW_MPT(struct mthca_dev *dev, struct mthca_mailbox *mailbox,
 		    int mpt_index, u8 *status);
-int mthca_WRITE_MTT(struct mthca_dev *dev, u64 *mtt_entry,
+int mthca_WRITE_MTT(struct mthca_dev *dev, struct mthca_mailbox *mailbox,
 		    int num_mtt, u8 *status);
 int mthca_SYNC_TPT(struct mthca_dev *dev, u8 *status);
 int mthca_MAP_EQ(struct mthca_dev *dev, u64 event_mask, int unmap,
 		 int eq_num, u8 *status);
-int mthca_SW2HW_EQ(struct mthca_dev *dev, void *eq_context,
+int mthca_SW2HW_EQ(struct mthca_dev *dev, struct mthca_mailbox *mailbox,
 		   int eq_num, u8 *status);
-int mthca_HW2SW_EQ(struct mthca_dev *dev, void *eq_context,
+int mthca_HW2SW_EQ(struct mthca_dev *dev, struct mthca_mailbox *mailbox,
 		   int eq_num, u8 *status);
-int mthca_SW2HW_CQ(struct mthca_dev *dev, void *cq_context,
+int mthca_SW2HW_CQ(struct mthca_dev *dev, struct mthca_mailbox *mailbox,
 		   int cq_num, u8 *status);
-int mthca_HW2SW_CQ(struct mthca_dev *dev, void *cq_context,
+int mthca_HW2SW_CQ(struct mthca_dev *dev, struct mthca_mailbox *mailbox,
 		   int cq_num, u8 *status);
 int mthca_MODIFY_QP(struct mthca_dev *dev, int trans, u32 num,
-		    int is_ee, void *qp_context, u32 optmask,
+		    int is_ee, struct mthca_mailbox *mailbox, u32 optmask,
 		    u8 *status);
 int mthca_QUERY_QP(struct mthca_dev *dev, u32 num, int is_ee,
-		   void *qp_context, u8 *status);
+		   struct mthca_mailbox *mailbox, u8 *status);
 int mthca_CONF_SPECIAL_QP(struct mthca_dev *dev, int type, u32 qpn,
 			  u8 *status);
 int mthca_MAD_IFC(struct mthca_dev *dev, int ignore_mkey, int ignore_bkey,
-		  int port, struct ib_wc* in_wc, struct ib_grh* in_grh,
+		  int port, struct ib_wc *in_wc, struct ib_grh *in_grh,
 		  void *in_mad, void *response_mad, u8 *status);
-int mthca_READ_MGM(struct mthca_dev *dev, int index, void *mgm,
-		   u8 *status);
-int mthca_WRITE_MGM(struct mthca_dev *dev, int index, void *mgm,
-		    u8 *status);
-int mthca_MGID_HASH(struct mthca_dev *dev, void *gid, u16 *hash,
-		    u8 *status);
+int mthca_READ_MGM(struct mthca_dev *dev, int index,
+		   struct mthca_mailbox *mailbox, u8 *status);
+int mthca_WRITE_MGM(struct mthca_dev *dev, int index,
+		    struct mthca_mailbox *mailbox, u8 *status);
+int mthca_MGID_HASH(struct mthca_dev *dev, struct mthca_mailbox *mailbox,
+		    u16 *hash, u8 *status);
 int mthca_NOP(struct mthca_dev *dev, u8 *status);
 
-#define MAILBOX_ALIGN(x) ((void *) ALIGN((unsigned long) (x), MTHCA_CMD_MAILBOX_ALIGN))
-
 #endif /* MTHCA_CMD_H */
diff --git a/drivers/infiniband/hw/mthca/mthca_cq.c b/drivers/infiniband/hw/mthca/mthca_cq.c
--- a/drivers/infiniband/hw/mthca/mthca_cq.c
+++ b/drivers/infiniband/hw/mthca/mthca_cq.c
@@ -1,5 +1,7 @@
 /*
  * Copyright (c) 2004, 2005 Topspin Communications.  All rights reserved.
+ * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright (c) 2005 Cisco Systems, Inc. All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
@@ -171,6 +173,17 @@ static inline void set_cqe_hw(struct mth
 	cqe->owner = MTHCA_CQ_ENTRY_OWNER_HW;
 }
 
+static void dump_cqe(struct mthca_dev *dev, void *cqe_ptr)
+{
+	__be32 *cqe = cqe_ptr;
+
+	(void) cqe;	/* avoid warning if mthca_dbg compiled away... */
+	mthca_dbg(dev, "CQE contents %08x %08x %08x %08x %08x %08x %08x %08x\n",
+		  be32_to_cpu(cqe[0]), be32_to_cpu(cqe[1]), be32_to_cpu(cqe[2]),
+		  be32_to_cpu(cqe[3]), be32_to_cpu(cqe[4]), be32_to_cpu(cqe[5]),
+		  be32_to_cpu(cqe[6]), be32_to_cpu(cqe[7]));
+}
+
 /*
  * incr is ignored in native Arbel (mem-free) mode, so cq->cons_index
  * should be correct before calling update_cons_index().
@@ -280,16 +293,12 @@ static int handle_error_cqe(struct mthca
 	int dbd;
 	u32 new_wqe;
 
-	if (1 && cqe->syndrome != SYNDROME_WR_FLUSH_ERR) {
-		int j;
-
-		mthca_dbg(dev, "%x/%d: error CQE -> QPN %06x, WQE @ %08x\n",
-			  cq->cqn, cq->cons_index, be32_to_cpu(cqe->my_qpn),
-			  be32_to_cpu(cqe->wqe));
-
-		for (j = 0; j < 8; ++j)
-			printk(KERN_DEBUG "  [%2x] %08x\n",
-			       j * 4, be32_to_cpu(((u32 *) cqe)[j]));
+	if (cqe->syndrome == SYNDROME_LOCAL_QP_OP_ERR) {
+		mthca_dbg(dev, "local QP operation err "
+			  "(QPN %06x, WQE @ %08x, CQN %06x, index %d)\n",
+			  be32_to_cpu(cqe->my_qpn), be32_to_cpu(cqe->wqe),
+			  cq->cqn, cq->cons_index);
+		dump_cqe(dev, cqe);
 	}
 
 	/*
@@ -364,8 +373,12 @@ static int handle_error_cqe(struct mthca
 	 * If we're at the end of the WQE chain, or we've used up our
 	 * doorbell count, free the CQE.  Otherwise just update it for
 	 * the next poll operation.
+	 *
+	 * This does not apply to mem-free HCAs: they don't use the
+	 * doorbell count field, and so we should always free the CQE.
 	 */
-	if (!(new_wqe & cpu_to_be32(0x3f)) || (!cqe->db_cnt && dbd))
+	if (mthca_is_memfree(dev) ||
+	    !(new_wqe & cpu_to_be32(0x3f)) || (!cqe->db_cnt && dbd))
 		return 0;
 
 	cqe->db_cnt   = cpu_to_be16(be16_to_cpu(cqe->db_cnt) - dbd);
@@ -377,15 +390,6 @@ static int handle_error_cqe(struct mthca
 	return 0;
 }
 
-static void dump_cqe(struct mthca_cqe *cqe)
-{
-	int j;
-
-	for (j = 0; j < 8; ++j)
-		printk(KERN_DEBUG "  [%2x] %08x\n",
-		       j * 4, be32_to_cpu(((u32 *) cqe)[j]));
-}
-
 static inline int mthca_poll_one(struct mthca_dev *dev,
 				 struct mthca_cq *cq,
 				 struct mthca_qp **cur_qp,
@@ -414,8 +418,7 @@ static inline int mthca_poll_one(struct 
 		mthca_dbg(dev, "%x/%d: CQE -> QPN %06x, WQE @ %08x\n",
 			  cq->cqn, cq->cons_index, be32_to_cpu(cqe->my_qpn),
 			  be32_to_cpu(cqe->wqe));
-
-		dump_cqe(cqe);
+		dump_cqe(dev, cqe);
 	}
 
 	is_error = (cqe->opcode & MTHCA_ERROR_CQE_OPCODE_MASK) ==
@@ -638,19 +641,19 @@ static void mthca_free_cq_buf(struct mth
 	int size;
 
 	if (cq->is_direct)
-		pci_free_consistent(dev->pdev,
-				    (cq->ibcq.cqe + 1) * MTHCA_CQ_ENTRY_SIZE,
-				    cq->queue.direct.buf,
-				    pci_unmap_addr(&cq->queue.direct,
-						   mapping));
+		dma_free_coherent(&dev->pdev->dev,
+				  (cq->ibcq.cqe + 1) * MTHCA_CQ_ENTRY_SIZE,
+				  cq->queue.direct.buf,
+				  pci_unmap_addr(&cq->queue.direct,
+						 mapping));
 	else {
 		size = (cq->ibcq.cqe + 1) * MTHCA_CQ_ENTRY_SIZE;
 		for (i = 0; i < (size + PAGE_SIZE - 1) / PAGE_SIZE; ++i)
 			if (cq->queue.page_list[i].buf)
-				pci_free_consistent(dev->pdev, PAGE_SIZE,
-						    cq->queue.page_list[i].buf,
-						    pci_unmap_addr(&cq->queue.page_list[i],
-								   mapping));
+				dma_free_coherent(&dev->pdev->dev, PAGE_SIZE,
+						  cq->queue.page_list[i].buf,
+						  pci_unmap_addr(&cq->queue.page_list[i],
+								 mapping));
 
 		kfree(cq->queue.page_list);
 	}
@@ -670,8 +673,8 @@ static int mthca_alloc_cq_buf(struct mth
 		npages        = 1;
 		shift         = get_order(size) + PAGE_SHIFT;
 
-		cq->queue.direct.buf = pci_alloc_consistent(dev->pdev,
-							    size, &t);
+		cq->queue.direct.buf = dma_alloc_coherent(&dev->pdev->dev,
+							  size, &t, GFP_KERNEL);
 		if (!cq->queue.direct.buf)
 			return -ENOMEM;
 
@@ -709,7 +712,8 @@ static int mthca_alloc_cq_buf(struct mth
 
 		for (i = 0; i < npages; ++i) {
 			cq->queue.page_list[i].buf =
-				pci_alloc_consistent(dev->pdev, PAGE_SIZE, &t);
+				dma_alloc_coherent(&dev->pdev->dev, PAGE_SIZE,
+						   &t, GFP_KERNEL);
 			if (!cq->queue.page_list[i].buf)
 				goto err_free;
 
@@ -743,10 +747,11 @@ err_out:
 }
 
 int mthca_init_cq(struct mthca_dev *dev, int nent,
+		  struct mthca_ucontext *ctx, u32 pdn,
 		  struct mthca_cq *cq)
 {
 	int size = nent * MTHCA_CQ_ENTRY_SIZE;
-	void *mailbox = NULL;
+	struct mthca_mailbox *mailbox;
 	struct mthca_cq_context *cq_context;
 	int err = -ENOMEM;
 	u8 status;
@@ -754,45 +759,49 @@ int mthca_init_cq(struct mthca_dev *dev,
 
 	might_sleep();
 
-	cq->ibcq.cqe = nent - 1;
+	cq->ibcq.cqe  = nent - 1;
+	cq->is_kernel = !ctx;
 
 	cq->cqn = mthca_alloc(&dev->cq_table.alloc);
 	if (cq->cqn == -1)
 		return -ENOMEM;
 
 	if (mthca_is_memfree(dev)) {
-		cq->arm_sn = 1;
-
 		err = mthca_table_get(dev, dev->cq_table.table, cq->cqn);
 		if (err)
 			goto err_out;
 
-		err = -ENOMEM;
+		if (cq->is_kernel) {
+			cq->arm_sn = 1;
 
-		cq->set_ci_db_index = mthca_alloc_db(dev, MTHCA_DB_TYPE_CQ_SET_CI,
-						     cq->cqn, &cq->set_ci_db);
-		if (cq->set_ci_db_index < 0)
-			goto err_out_icm;
+			err = -ENOMEM;
 
-		cq->arm_db_index = mthca_alloc_db(dev, MTHCA_DB_TYPE_CQ_ARM,
-						  cq->cqn, &cq->arm_db);
-		if (cq->arm_db_index < 0)
-			goto err_out_ci;
+			cq->set_ci_db_index = mthca_alloc_db(dev, MTHCA_DB_TYPE_CQ_SET_CI,
+							     cq->cqn, &cq->set_ci_db);
+			if (cq->set_ci_db_index < 0)
+				goto err_out_icm;
+
+			cq->arm_db_index = mthca_alloc_db(dev, MTHCA_DB_TYPE_CQ_ARM,
+							  cq->cqn, &cq->arm_db);
+			if (cq->arm_db_index < 0)
+				goto err_out_ci;
+		}
 	}
 
-	mailbox = kmalloc(sizeof (struct mthca_cq_context) + MTHCA_CMD_MAILBOX_EXTRA,
-			  GFP_KERNEL);
-	if (!mailbox)
-		goto err_out_mailbox;
+	mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL);
+	if (IS_ERR(mailbox))
+		goto err_out_arm;
 
-	cq_context = MAILBOX_ALIGN(mailbox);
+	cq_context = mailbox->buf;
 
-	err = mthca_alloc_cq_buf(dev, size, cq);
-	if (err)
-		goto err_out_mailbox;
+	if (cq->is_kernel) {
+		err = mthca_alloc_cq_buf(dev, size, cq);
+		if (err)
+			goto err_out_mailbox;
 
-	for (i = 0; i < nent; ++i)
-		set_cqe_hw(get_cqe(cq, i));
+		for (i = 0; i < nent; ++i)
+			set_cqe_hw(get_cqe(cq, i));
+	}
 
 	spin_lock_init(&cq->lock);
 	atomic_set(&cq->refcount, 1);
@@ -803,11 +812,14 @@ int mthca_init_cq(struct mthca_dev *dev,
 						  MTHCA_CQ_STATE_DISARMED |
 						  MTHCA_CQ_FLAG_TR);
 	cq_context->start           = cpu_to_be64(0);
-	cq_context->logsize_usrpage = cpu_to_be32((ffs(nent) - 1) << 24 |
-						  dev->driver_uar.index);
+	cq_context->logsize_usrpage = cpu_to_be32((ffs(nent) - 1) << 24);
+	if (ctx)
+		cq_context->logsize_usrpage |= cpu_to_be32(ctx->uar.index);
+	else
+		cq_context->logsize_usrpage |= cpu_to_be32(dev->driver_uar.index);
 	cq_context->error_eqn       = cpu_to_be32(dev->eq_table.eq[MTHCA_EQ_ASYNC].eqn);
 	cq_context->comp_eqn        = cpu_to_be32(dev->eq_table.eq[MTHCA_EQ_COMP].eqn);
-	cq_context->pd              = cpu_to_be32(dev->driver_pd.pd_num);
+	cq_context->pd              = cpu_to_be32(pdn);
 	cq_context->lkey            = cpu_to_be32(cq->mr.ibmr.lkey);
 	cq_context->cqn             = cpu_to_be32(cq->cqn);
 
@@ -816,7 +828,7 @@ int mthca_init_cq(struct mthca_dev *dev,
 		cq_context->state_db = cpu_to_be32(cq->arm_db_index);
 	}
 
-	err = mthca_SW2HW_CQ(dev, cq_context, cq->cqn, &status);
+	err = mthca_SW2HW_CQ(dev, mailbox, cq->cqn, &status);
 	if (err) {
 		mthca_warn(dev, "SW2HW_CQ failed (%d)\n", err);
 		goto err_out_free_mr;
@@ -840,22 +852,25 @@ int mthca_init_cq(struct mthca_dev *dev,
 
 	cq->cons_index = 0;
 
-	kfree(mailbox);
+	mthca_free_mailbox(dev, mailbox);
 
 	return 0;
 
 err_out_free_mr:
-	mthca_free_mr(dev, &cq->mr);
-	mthca_free_cq_buf(dev, cq);
+	if (cq->is_kernel) {
+		mthca_free_mr(dev, &cq->mr);
+		mthca_free_cq_buf(dev, cq);
+	}
 
 err_out_mailbox:
-	kfree(mailbox);
+	mthca_free_mailbox(dev, mailbox);
 
-	if (mthca_is_memfree(dev))
+err_out_arm:
+	if (cq->is_kernel && mthca_is_memfree(dev))
 		mthca_free_db(dev, MTHCA_DB_TYPE_CQ_ARM, cq->arm_db_index);
 
 err_out_ci:
-	if (mthca_is_memfree(dev))
+	if (cq->is_kernel && mthca_is_memfree(dev))
 		mthca_free_db(dev, MTHCA_DB_TYPE_CQ_SET_CI, cq->set_ci_db_index);
 
 err_out_icm:
@@ -870,32 +885,31 @@ err_out:
 void mthca_free_cq(struct mthca_dev *dev,
 		   struct mthca_cq *cq)
 {
-	void *mailbox;
+	struct mthca_mailbox *mailbox;
 	int err;
 	u8 status;
 
 	might_sleep();
 
-	mailbox = kmalloc(sizeof (struct mthca_cq_context) + MTHCA_CMD_MAILBOX_EXTRA,
-			  GFP_KERNEL);
-	if (!mailbox) {
+	mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL);
+	if (IS_ERR(mailbox)) {
 		mthca_warn(dev, "No memory for mailbox to free CQ.\n");
 		return;
 	}
 
-	err = mthca_HW2SW_CQ(dev, MAILBOX_ALIGN(mailbox), cq->cqn, &status);
+	err = mthca_HW2SW_CQ(dev, mailbox, cq->cqn, &status);
 	if (err)
 		mthca_warn(dev, "HW2SW_CQ failed (%d)\n", err);
 	else if (status)
-		mthca_warn(dev, "HW2SW_CQ returned status 0x%02x\n",
-			   status);
+		mthca_warn(dev, "HW2SW_CQ returned status 0x%02x\n", status);
 
 	if (0) {
-		u32 *ctx = MAILBOX_ALIGN(mailbox);
+		u32 *ctx = mailbox->buf;
 		int j;
 
 		printk(KERN_ERR "context for CQN %x (cons index %x, next sw %d)\n",
-		       cq->cqn, cq->cons_index, !!next_cqe_sw(cq));
+		       cq->cqn, cq->cons_index,
+		       cq->is_kernel ? !!next_cqe_sw(cq) : 0);
 		for (j = 0; j < 16; ++j)
 			printk(KERN_ERR "[%2x] %08x\n", j * 4, be32_to_cpu(ctx[j]));
 	}
@@ -913,17 +927,18 @@ void mthca_free_cq(struct mthca_dev *dev
 	atomic_dec(&cq->refcount);
 	wait_event(cq->wait, !atomic_read(&cq->refcount));
 
-	mthca_free_mr(dev, &cq->mr);
-	mthca_free_cq_buf(dev, cq);
-
-	if (mthca_is_memfree(dev)) {
-		mthca_free_db(dev, MTHCA_DB_TYPE_CQ_ARM,    cq->arm_db_index);
-		mthca_free_db(dev, MTHCA_DB_TYPE_CQ_SET_CI, cq->set_ci_db_index);
-		mthca_table_put(dev, dev->cq_table.table, cq->cqn);
+	if (cq->is_kernel) {
+		mthca_free_mr(dev, &cq->mr);
+		mthca_free_cq_buf(dev, cq);
+		if (mthca_is_memfree(dev)) {
+			mthca_free_db(dev, MTHCA_DB_TYPE_CQ_ARM,    cq->arm_db_index);
+			mthca_free_db(dev, MTHCA_DB_TYPE_CQ_SET_CI, cq->set_ci_db_index);
+		}
 	}
 
+	mthca_table_put(dev, dev->cq_table.table, cq->cqn);
 	mthca_free(&dev->cq_table.alloc, cq->cqn);
-	kfree(mailbox);
+	mthca_free_mailbox(dev, mailbox);
 }
 
 int __devinit mthca_init_cq_table(struct mthca_dev *dev)
diff --git a/drivers/infiniband/hw/mthca/mthca_dev.h b/drivers/infiniband/hw/mthca/mthca_dev.h
--- a/drivers/infiniband/hw/mthca/mthca_dev.h
+++ b/drivers/infiniband/hw/mthca/mthca_dev.h
@@ -1,5 +1,7 @@
 /*
  * Copyright (c) 2004, 2005 Topspin Communications.  All rights reserved.
+ * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright (c) 2005 Cisco Systems.  All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
@@ -46,8 +48,8 @@
 
 #define DRV_NAME	"ib_mthca"
 #define PFX		DRV_NAME ": "
-#define DRV_VERSION	"0.06-pre"
-#define DRV_RELDATE	"November 8, 2004"
+#define DRV_VERSION	"0.06"
+#define DRV_RELDATE	"June 23, 2005"
 
 enum {
 	MTHCA_FLAG_DDR_HIDDEN = 1 << 1,
@@ -98,6 +100,7 @@ enum {
 };
 
 struct mthca_cmd {
+	struct pci_pool          *pool;
 	int                       use_events;
 	struct semaphore          hcr_sem;
 	struct semaphore 	  poll_sem;
@@ -376,9 +379,15 @@ void mthca_unregister_device(struct mthc
 int mthca_uar_alloc(struct mthca_dev *dev, struct mthca_uar *uar);
 void mthca_uar_free(struct mthca_dev *dev, struct mthca_uar *uar);
 
-int mthca_pd_alloc(struct mthca_dev *dev, struct mthca_pd *pd);
+int mthca_pd_alloc(struct mthca_dev *dev, int privileged, struct mthca_pd *pd);
 void mthca_pd_free(struct mthca_dev *dev, struct mthca_pd *pd);
 
+struct mthca_mtt *mthca_alloc_mtt(struct mthca_dev *dev, int size);
+void mthca_free_mtt(struct mthca_dev *dev, struct mthca_mtt *mtt);
+int mthca_write_mtt(struct mthca_dev *dev, struct mthca_mtt *mtt,
+		    int start_index, u64 *buffer_list, int list_len);
+int mthca_mr_alloc(struct mthca_dev *dev, u32 pd, int buffer_size_shift,
+		   u64 iova, u64 total_size, u32 access, struct mthca_mr *mr);
 int mthca_mr_alloc_notrans(struct mthca_dev *dev, u32 pd,
 			   u32 access, struct mthca_mr *mr);
 int mthca_mr_alloc_phys(struct mthca_dev *dev, u32 pd,
@@ -405,6 +414,7 @@ int mthca_poll_cq(struct ib_cq *ibcq, in
 int mthca_tavor_arm_cq(struct ib_cq *cq, enum ib_cq_notify notify);
 int mthca_arbel_arm_cq(struct ib_cq *cq, enum ib_cq_notify notify);
 int mthca_init_cq(struct mthca_dev *dev, int nent,
+		  struct mthca_ucontext *ctx, u32 pdn,
 		  struct mthca_cq *cq);
 void mthca_free_cq(struct mthca_dev *dev,
 		   struct mthca_cq *cq);
@@ -430,12 +440,14 @@ int mthca_alloc_qp(struct mthca_dev *dev
 		   struct mthca_cq *recv_cq,
 		   enum ib_qp_type type,
 		   enum ib_sig_type send_policy,
+		   struct ib_qp_cap *cap,
 		   struct mthca_qp *qp);
 int mthca_alloc_sqp(struct mthca_dev *dev,
 		    struct mthca_pd *pd,
 		    struct mthca_cq *send_cq,
 		    struct mthca_cq *recv_cq,
 		    enum ib_sig_type send_policy,
+		    struct ib_qp_cap *cap,
 		    int qpn,
 		    int port,
 		    struct mthca_sqp *sqp);
diff --git a/drivers/infiniband/hw/mthca/mthca_doorbell.h b/drivers/infiniband/hw/mthca/mthca_doorbell.h
--- a/drivers/infiniband/hw/mthca/mthca_doorbell.h
+++ b/drivers/infiniband/hw/mthca/mthca_doorbell.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2004 Topspin Communications.  All rights reserved.
+ * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
diff --git a/drivers/infiniband/hw/mthca/mthca_eq.c b/drivers/infiniband/hw/mthca/mthca_eq.c
--- a/drivers/infiniband/hw/mthca/mthca_eq.c
+++ b/drivers/infiniband/hw/mthca/mthca_eq.c
@@ -469,7 +469,7 @@ static int __devinit mthca_create_eq(str
 		PAGE_SIZE;
 	u64 *dma_list = NULL;
 	dma_addr_t t;
-	void *mailbox = NULL;
+	struct mthca_mailbox *mailbox;
 	struct mthca_eq_context *eq_context;
 	int err = -ENOMEM;
 	int i;
@@ -494,17 +494,16 @@ static int __devinit mthca_create_eq(str
 	if (!dma_list)
 		goto err_out_free;
 
-	mailbox = kmalloc(sizeof *eq_context + MTHCA_CMD_MAILBOX_EXTRA,
-			  GFP_KERNEL);
-	if (!mailbox)
+	mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL);
+	if (IS_ERR(mailbox))
 		goto err_out_free;
-	eq_context = MAILBOX_ALIGN(mailbox);
+	eq_context = mailbox->buf;
 
 	for (i = 0; i < npages; ++i) {
-		eq->page_list[i].buf = pci_alloc_consistent(dev->pdev,
-							    PAGE_SIZE, &t);
+		eq->page_list[i].buf = dma_alloc_coherent(&dev->pdev->dev,
+							  PAGE_SIZE, &t, GFP_KERNEL);
 		if (!eq->page_list[i].buf)
-			goto err_out_free;
+			goto err_out_free_pages;
 
 		dma_list[i] = t;
 		pci_unmap_addr_set(&eq->page_list[i], mapping, t);
@@ -517,7 +516,7 @@ static int __devinit mthca_create_eq(str
 
 	eq->eqn = mthca_alloc(&dev->eq_table.alloc);
 	if (eq->eqn == -1)
-		goto err_out_free;
+		goto err_out_free_pages;
 
 	err = mthca_mr_alloc_phys(dev, dev->driver_pd.pd_num,
 				  dma_list, PAGE_SHIFT, npages,
@@ -548,7 +547,7 @@ static int __devinit mthca_create_eq(str
 	eq_context->intr            = intr;
 	eq_context->lkey            = cpu_to_be32(eq->mr.ibmr.lkey);
 
-	err = mthca_SW2HW_EQ(dev, eq_context, eq->eqn, &status);
+	err = mthca_SW2HW_EQ(dev, mailbox, eq->eqn, &status);
 	if (err) {
 		mthca_warn(dev, "SW2HW_EQ failed (%d)\n", err);
 		goto err_out_free_mr;
@@ -561,7 +560,7 @@ static int __devinit mthca_create_eq(str
 	}
 
 	kfree(dma_list);
-	kfree(mailbox);
+	mthca_free_mailbox(dev, mailbox);
 
 	eq->eqn_mask   = swab32(1 << eq->eqn);
 	eq->cons_index = 0;
@@ -579,17 +578,19 @@ static int __devinit mthca_create_eq(str
  err_out_free_eq:
 	mthca_free(&dev->eq_table.alloc, eq->eqn);
 
- err_out_free:
+ err_out_free_pages:
 	for (i = 0; i < npages; ++i)
 		if (eq->page_list[i].buf)
-			pci_free_consistent(dev->pdev, PAGE_SIZE,
-					    eq->page_list[i].buf,
-					    pci_unmap_addr(&eq->page_list[i],
-							   mapping));
+			dma_free_coherent(&dev->pdev->dev, PAGE_SIZE,
+					  eq->page_list[i].buf,
+					  pci_unmap_addr(&eq->page_list[i],
+							 mapping));
+
+	mthca_free_mailbox(dev, mailbox);
 
+ err_out_free:
 	kfree(eq->page_list);
 	kfree(dma_list);
-	kfree(mailbox);
 
  err_out:
 	return err;
@@ -598,25 +599,22 @@ static int __devinit mthca_create_eq(str
 static void mthca_free_eq(struct mthca_dev *dev,
 			  struct mthca_eq *eq)
 {
-	void *mailbox = NULL;
+	struct mthca_mailbox *mailbox;
 	int err;
 	u8 status;
 	int npages = (eq->nent * MTHCA_EQ_ENTRY_SIZE + PAGE_SIZE - 1) /
 		PAGE_SIZE;
 	int i;
 
-	mailbox = kmalloc(sizeof (struct mthca_eq_context) + MTHCA_CMD_MAILBOX_EXTRA,
-			  GFP_KERNEL);
-	if (!mailbox)
+	mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL);
+	if (IS_ERR(mailbox))
 		return;
 
-	err = mthca_HW2SW_EQ(dev, MAILBOX_ALIGN(mailbox),
-			     eq->eqn, &status);
+	err = mthca_HW2SW_EQ(dev, mailbox, eq->eqn, &status);
 	if (err)
 		mthca_warn(dev, "HW2SW_EQ failed (%d)\n", err);
 	if (status)
-		mthca_warn(dev, "HW2SW_EQ returned status 0x%02x\n",
-			   status);
+		mthca_warn(dev, "HW2SW_EQ returned status 0x%02x\n", status);
 
 	dev->eq_table.arm_mask &= ~eq->eqn_mask;
 
@@ -625,7 +623,7 @@ static void mthca_free_eq(struct mthca_d
 		for (i = 0; i < sizeof (struct mthca_eq_context) / 4; ++i) {
 			if (i % 4 == 0)
 				printk("[%02x] ", i * 4);
-			printk(" %08x", be32_to_cpup(MAILBOX_ALIGN(mailbox) + i * 4));
+			printk(" %08x", be32_to_cpup(mailbox->buf + i * 4));
 			if ((i + 1) % 4 == 0)
 				printk("\n");
 		}
@@ -638,7 +636,7 @@ static void mthca_free_eq(struct mthca_d
 				    pci_unmap_addr(&eq->page_list[i], mapping));
 
 	kfree(eq->page_list);
-	kfree(mailbox);
+	mthca_free_mailbox(dev, mailbox);
 }
 
 static void mthca_free_irqs(struct mthca_dev *dev)
@@ -709,8 +707,7 @@ static int __devinit mthca_map_eq_regs(s
 		if (mthca_map_reg(dev, ((pci_resource_len(dev->pdev, 0) - 1) &
 					dev->fw.arbel.eq_arm_base) + 4, 4,
 				  &dev->eq_regs.arbel.eq_arm)) {
-			mthca_err(dev, "Couldn't map interrupt clear register, "
-				  "aborting.\n");
+			mthca_err(dev, "Couldn't map EQ arm register, aborting.\n");
 			mthca_unmap_reg(dev, (pci_resource_len(dev->pdev, 0) - 1) &
 					dev->fw.arbel.clr_int_base, MTHCA_CLR_INT_SIZE,
 					dev->clr_base);
@@ -721,8 +718,7 @@ static int __devinit mthca_map_eq_regs(s
 				  dev->fw.arbel.eq_set_ci_base,
 				  MTHCA_EQ_SET_CI_SIZE,
 				  &dev->eq_regs.arbel.eq_set_ci_base)) {
-			mthca_err(dev, "Couldn't map interrupt clear register, "
-				  "aborting.\n");
+			mthca_err(dev, "Couldn't map EQ CI register, aborting.\n");
 			mthca_unmap_reg(dev, ((pci_resource_len(dev->pdev, 0) - 1) &
 					      dev->fw.arbel.eq_arm_base) + 4, 4,
 					dev->eq_regs.arbel.eq_arm);
diff --git a/drivers/infiniband/hw/mthca/mthca_main.c b/drivers/infiniband/hw/mthca/mthca_main.c
--- a/drivers/infiniband/hw/mthca/mthca_main.c
+++ b/drivers/infiniband/hw/mthca/mthca_main.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2004, 2005 Topspin Communications.  All rights reserved.
+ * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
@@ -69,7 +70,7 @@ MODULE_PARM_DESC(msi, "attempt to use MS
 #endif /* CONFIG_PCI_MSI */
 
 static const char mthca_version[] __devinitdata =
-	"ib_mthca: Mellanox InfiniBand HCA driver v"
+	DRV_NAME ": Mellanox InfiniBand HCA driver v"
 	DRV_VERSION " (" DRV_RELDATE ")\n";
 
 static struct mthca_profile default_profile = {
@@ -664,7 +665,7 @@ static int __devinit mthca_setup_hca(str
 		goto err_pd_table_free;
 	}
 
-	err = mthca_pd_alloc(dev, &dev->driver_pd);
+	err = mthca_pd_alloc(dev, 1, &dev->driver_pd);
 	if (err) {
 		mthca_err(dev, "Failed to create driver PD, "
 			  "aborting.\n");
@@ -927,13 +928,13 @@ static int __devinit mthca_init_one(stru
 	 */
 	if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM) ||
 	    pci_resource_len(pdev, 0) != 1 << 20) {
-		dev_err(&pdev->dev, "Missing DCS, aborting.");
+		dev_err(&pdev->dev, "Missing DCS, aborting.\n");
 		err = -ENODEV;
 		goto err_disable_pdev;
 	}
 	if (!(pci_resource_flags(pdev, 2) & IORESOURCE_MEM) ||
 	    pci_resource_len(pdev, 2) != 1 << 23) {
-		dev_err(&pdev->dev, "Missing UAR, aborting.");
+		dev_err(&pdev->dev, "Missing UAR, aborting.\n");
 		err = -ENODEV;
 		goto err_disable_pdev;
 	}
@@ -1004,25 +1005,18 @@ static int __devinit mthca_init_one(stru
 	    !pci_enable_msi(pdev))
 		mdev->mthca_flags |= MTHCA_FLAG_MSI;
 
-	sema_init(&mdev->cmd.hcr_sem, 1);
-	sema_init(&mdev->cmd.poll_sem, 1);
-	mdev->cmd.use_events = 0;
-
-	mdev->hcr = ioremap(pci_resource_start(pdev, 0) + MTHCA_HCR_BASE, MTHCA_HCR_SIZE);
-	if (!mdev->hcr) {
-		mthca_err(mdev, "Couldn't map command register, "
-			  "aborting.\n");
-		err = -ENOMEM;
+	if (mthca_cmd_init(mdev)) {
+		mthca_err(mdev, "Failed to init command interface, aborting.\n");
 		goto err_free_dev;
 	}
 
 	err = mthca_tune_pci(mdev);
 	if (err)
-		goto err_iounmap;
+		goto err_cmd;
 
 	err = mthca_init_hca(mdev);
 	if (err)
-		goto err_iounmap;
+		goto err_cmd;
 
 	if (mdev->fw_ver < mthca_hca_table[id->driver_data].latest_fw) {
 		mthca_warn(mdev, "HCA FW version %x.%x.%x is old (%x.%x.%x is current).\n",
@@ -1070,8 +1064,8 @@ err_cleanup:
 err_close:
 	mthca_close_hca(mdev);
 
-err_iounmap:
-	iounmap(mdev->hcr);
+err_cmd:
+	mthca_cmd_cleanup(mdev);
 
 err_free_dev:
 	if (mdev->mthca_flags & MTHCA_FLAG_MSI_X)
@@ -1118,10 +1112,8 @@ static void __devexit mthca_remove_one(s
 		iounmap(mdev->kar);
 		mthca_uar_free(mdev, &mdev->driver_uar);
 		mthca_cleanup_uar_table(mdev);
-
 		mthca_close_hca(mdev);
-
-		iounmap(mdev->hcr);
+		mthca_cmd_cleanup(mdev);
 
 		if (mdev->mthca_flags & MTHCA_FLAG_MSI_X)
 			pci_disable_msix(pdev);
@@ -1163,7 +1155,7 @@ static struct pci_device_id mthca_pci_ta
 MODULE_DEVICE_TABLE(pci, mthca_pci_table);
 
 static struct pci_driver mthca_driver = {
-	.name		= "ib_mthca",
+	.name		= DRV_NAME,
 	.id_table	= mthca_pci_table,
 	.probe		= mthca_init_one,
 	.remove		= __devexit_p(mthca_remove_one)
diff --git a/drivers/infiniband/hw/mthca/mthca_mcg.c b/drivers/infiniband/hw/mthca/mthca_mcg.c
--- a/drivers/infiniband/hw/mthca/mthca_mcg.c
+++ b/drivers/infiniband/hw/mthca/mthca_mcg.c
@@ -66,22 +66,23 @@ static const u8 zero_gid[16];	/* automat
  * entry in hash chain and *mgm holds end of hash chain.
  */
 static int find_mgm(struct mthca_dev *dev,
-		    u8 *gid, struct mthca_mgm *mgm,
+		    u8 *gid, struct mthca_mailbox *mgm_mailbox,
 		    u16 *hash, int *prev, int *index)
 {
-	void *mailbox;
+	struct mthca_mailbox *mailbox;
+	struct mthca_mgm *mgm = mgm_mailbox->buf;
 	u8 *mgid;
 	int err;
 	u8 status;
 
-	mailbox = kmalloc(16 + MTHCA_CMD_MAILBOX_EXTRA, GFP_KERNEL);
-	if (!mailbox)
+	mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL);
+	if (IS_ERR(mailbox))
 		return -ENOMEM;
-	mgid = MAILBOX_ALIGN(mailbox);
+	mgid = mailbox->buf;
 
 	memcpy(mgid, gid, 16);
 
-	err = mthca_MGID_HASH(dev, mgid, hash, &status);
+	err = mthca_MGID_HASH(dev, mailbox, hash, &status);
 	if (err)
 		goto out;
 	if (status) {
@@ -103,7 +104,7 @@ static int find_mgm(struct mthca_dev *de
 	*prev  = -1;
 
 	do {
-		err = mthca_READ_MGM(dev, *index, mgm, &status);
+		err = mthca_READ_MGM(dev, *index, mgm_mailbox, &status);
 		if (err)
 			goto out;
 		if (status) {
@@ -129,14 +130,14 @@ static int find_mgm(struct mthca_dev *de
 	*index = -1;
 
  out:
-	kfree(mailbox);
+	mthca_free_mailbox(dev, mailbox);
 	return err;
 }
 
 int mthca_multicast_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
 {
 	struct mthca_dev *dev = to_mdev(ibqp->device);
-	void *mailbox;
+	struct mthca_mailbox *mailbox;
 	struct mthca_mgm *mgm;
 	u16 hash;
 	int index, prev;
@@ -145,15 +146,15 @@ int mthca_multicast_attach(struct ib_qp 
 	int err;
 	u8 status;
 
-	mailbox = kmalloc(sizeof *mgm + MTHCA_CMD_MAILBOX_EXTRA, GFP_KERNEL);
-	if (!mailbox)
-		return -ENOMEM;
-	mgm = MAILBOX_ALIGN(mailbox);
+	mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL);
+	if (IS_ERR(mailbox))
+		return PTR_ERR(mailbox);
+	mgm = mailbox->buf;
 
 	if (down_interruptible(&dev->mcg_table.sem))
 		return -EINTR;
 
-	err = find_mgm(dev, gid->raw, mgm, &hash, &prev, &index);
+	err = find_mgm(dev, gid->raw, mailbox, &hash, &prev, &index);
 	if (err)
 		goto out;
 
@@ -170,7 +171,7 @@ int mthca_multicast_attach(struct ib_qp 
 			goto out;
 		}
 
-		err = mthca_READ_MGM(dev, index, mgm, &status);
+		err = mthca_READ_MGM(dev, index, mailbox, &status);
 		if (err)
 			goto out;
 		if (status) {
@@ -195,7 +196,7 @@ int mthca_multicast_attach(struct ib_qp 
 		goto out;
 	}
 
-	err = mthca_WRITE_MGM(dev, index, mgm, &status);
+	err = mthca_WRITE_MGM(dev, index, mailbox, &status);
 	if (err)
 		goto out;
 	if (status) {
@@ -206,7 +207,7 @@ int mthca_multicast_attach(struct ib_qp 
 	if (!link)
 		goto out;
 
-	err = mthca_READ_MGM(dev, prev, mgm, &status);
+	err = mthca_READ_MGM(dev, prev, mailbox, &status);
 	if (err)
 		goto out;
 	if (status) {
@@ -217,7 +218,7 @@ int mthca_multicast_attach(struct ib_qp 
 
 	mgm->next_gid_index = cpu_to_be32(index << 5);
 
-	err = mthca_WRITE_MGM(dev, prev, mgm, &status);
+	err = mthca_WRITE_MGM(dev, prev, mailbox, &status);
 	if (err)
 		goto out;
 	if (status) {
@@ -227,14 +228,14 @@ int mthca_multicast_attach(struct ib_qp 
 
  out:
 	up(&dev->mcg_table.sem);
-	kfree(mailbox);
+	mthca_free_mailbox(dev, mailbox);
 	return err;
 }
 
 int mthca_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
 {
 	struct mthca_dev *dev = to_mdev(ibqp->device);
-	void *mailbox;
+	struct mthca_mailbox *mailbox;
 	struct mthca_mgm *mgm;
 	u16 hash;
 	int prev, index;
@@ -242,15 +243,15 @@ int mthca_multicast_detach(struct ib_qp 
 	int err;
 	u8 status;
 
-	mailbox = kmalloc(sizeof *mgm + MTHCA_CMD_MAILBOX_EXTRA, GFP_KERNEL);
-	if (!mailbox)
-		return -ENOMEM;
-	mgm = MAILBOX_ALIGN(mailbox);
+	mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL);
+	if (IS_ERR(mailbox))
+		return PTR_ERR(mailbox);
+	mgm = mailbox->buf;
 
 	if (down_interruptible(&dev->mcg_table.sem))
 		return -EINTR;
 
-	err = find_mgm(dev, gid->raw, mgm, &hash, &prev, &index);
+	err = find_mgm(dev, gid->raw, mailbox, &hash, &prev, &index);
 	if (err)
 		goto out;
 
@@ -285,7 +286,7 @@ int mthca_multicast_detach(struct ib_qp 
 	mgm->qp[loc]   = mgm->qp[i - 1];
 	mgm->qp[i - 1] = 0;
 
-	err = mthca_WRITE_MGM(dev, index, mgm, &status);
+	err = mthca_WRITE_MGM(dev, index, mailbox, &status);
 	if (err)
 		goto out;
 	if (status) {
@@ -304,7 +305,7 @@ int mthca_multicast_detach(struct ib_qp 
 		if (be32_to_cpu(mgm->next_gid_index) >> 5) {
 			err = mthca_READ_MGM(dev,
 					     be32_to_cpu(mgm->next_gid_index) >> 5,
-					     mgm, &status);
+					     mailbox, &status);
 			if (err)
 				goto out;
 			if (status) {
@@ -316,7 +317,7 @@ int mthca_multicast_detach(struct ib_qp 
 		} else
 			memset(mgm->gid, 0, 16);
 
-		err = mthca_WRITE_MGM(dev, index, mgm, &status);
+		err = mthca_WRITE_MGM(dev, index, mailbox, &status);
 		if (err)
 			goto out;
 		if (status) {
@@ -327,7 +328,7 @@ int mthca_multicast_detach(struct ib_qp 
 	} else {
 		/* Remove entry from AMGM */
 		index = be32_to_cpu(mgm->next_gid_index) >> 5;
-		err = mthca_READ_MGM(dev, prev, mgm, &status);
+		err = mthca_READ_MGM(dev, prev, mailbox, &status);
 		if (err)
 			goto out;
 		if (status) {
@@ -338,7 +339,7 @@ int mthca_multicast_detach(struct ib_qp 
 
 		mgm->next_gid_index = cpu_to_be32(index << 5);
 
-		err = mthca_WRITE_MGM(dev, prev, mgm, &status);
+		err = mthca_WRITE_MGM(dev, prev, mailbox, &status);
 		if (err)
 			goto out;
 		if (status) {
@@ -350,7 +351,7 @@ int mthca_multicast_detach(struct ib_qp 
 
  out:
 	up(&dev->mcg_table.sem);
-	kfree(mailbox);
+	mthca_free_mailbox(dev, mailbox);
 	return err;
 }
 
diff --git a/drivers/infiniband/hw/mthca/mthca_memfree.c b/drivers/infiniband/hw/mthca/mthca_memfree.c
--- a/drivers/infiniband/hw/mthca/mthca_memfree.c
+++ b/drivers/infiniband/hw/mthca/mthca_memfree.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2004, 2005 Topspin Communications.  All rights reserved.
+ * Copyright (c) 2005 Cisco Systems.  All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
@@ -47,6 +48,15 @@ enum {
 	MTHCA_TABLE_CHUNK_SIZE = 1 << 18
 };
 
+struct mthca_user_db_table {
+	struct semaphore mutex;
+	struct {
+		u64                uvirt;
+		struct scatterlist mem;
+		int                refcount;
+	}                page[0];
+};
+
 void mthca_free_icm(struct mthca_dev *dev, struct mthca_icm *icm)
 {
 	struct mthca_icm_chunk *chunk, *tmp;
@@ -179,9 +189,14 @@ out:
 
 void mthca_table_put(struct mthca_dev *dev, struct mthca_icm_table *table, int obj)
 {
-	int i = (obj & (table->num_obj - 1)) * table->obj_size / MTHCA_TABLE_CHUNK_SIZE;
+	int i;
 	u8 status;
 
+	if (!mthca_is_memfree(dev))
+		return;
+
+	i = (obj & (table->num_obj - 1)) * table->obj_size / MTHCA_TABLE_CHUNK_SIZE;
+
 	down(&table->mutex);
 
 	if (--table->icm[i]->refcount == 0) {
@@ -256,6 +271,9 @@ void mthca_table_put_range(struct mthca_
 {
 	int i;
 
+	if (!mthca_is_memfree(dev))
+		return;
+
 	for (i = start; i <= end; i += MTHCA_TABLE_CHUNK_SIZE / table->obj_size)
 		mthca_table_put(dev, table, i);
 }
@@ -336,13 +354,133 @@ void mthca_free_icm_table(struct mthca_d
 	kfree(table);
 }
 
-static u64 mthca_uarc_virt(struct mthca_dev *dev, int page)
+static u64 mthca_uarc_virt(struct mthca_dev *dev, struct mthca_uar *uar, int page)
 {
 	return dev->uar_table.uarc_base +
-		dev->driver_uar.index * dev->uar_table.uarc_size +
+		uar->index * dev->uar_table.uarc_size +
 		page * 4096;
 }
 
+int mthca_map_user_db(struct mthca_dev *dev, struct mthca_uar *uar,
+		      struct mthca_user_db_table *db_tab, int index, u64 uaddr)
+{
+	int ret = 0;
+	u8 status;
+	int i;
+
+	if (!mthca_is_memfree(dev))
+		return 0;
+
+	if (index < 0 || index > dev->uar_table.uarc_size / 8)
+		return -EINVAL;
+
+	down(&db_tab->mutex);
+
+	i = index / MTHCA_DB_REC_PER_PAGE;
+
+	if ((db_tab->page[i].refcount >= MTHCA_DB_REC_PER_PAGE)       ||
+	    (db_tab->page[i].uvirt && db_tab->page[i].uvirt != uaddr) ||
+	    (uaddr & 4095)) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	if (db_tab->page[i].refcount) {
+		++db_tab->page[i].refcount;
+		goto out;
+	}
+
+	ret = get_user_pages(current, current->mm, uaddr & PAGE_MASK, 1, 1, 0,
+			     &db_tab->page[i].mem.page, NULL);
+	if (ret < 0)
+		goto out;
+
+	db_tab->page[i].mem.length = 4096;
+	db_tab->page[i].mem.offset = uaddr & ~PAGE_MASK;
+
+	ret = pci_map_sg(dev->pdev, &db_tab->page[i].mem, 1, PCI_DMA_TODEVICE);
+	if (ret < 0) {
+		put_page(db_tab->page[i].mem.page);
+		goto out;
+	}
+
+	ret = mthca_MAP_ICM_page(dev, sg_dma_address(&db_tab->page[i].mem),
+				 mthca_uarc_virt(dev, uar, i), &status);
+	if (!ret && status)
+		ret = -EINVAL;
+	if (ret) {
+		pci_unmap_sg(dev->pdev, &db_tab->page[i].mem, 1, PCI_DMA_TODEVICE);
+		put_page(db_tab->page[i].mem.page);
+		goto out;
+	}
+
+	db_tab->page[i].uvirt    = uaddr;
+	db_tab->page[i].refcount = 1;
+
+out:
+	up(&db_tab->mutex);
+	return ret;
+}
+
+void mthca_unmap_user_db(struct mthca_dev *dev, struct mthca_uar *uar,
+			 struct mthca_user_db_table *db_tab, int index)
+{
+	if (!mthca_is_memfree(dev))
+		return;
+
+	/*
+	 * To make our bookkeeping simpler, we don't unmap DB
+	 * pages until we clean up the whole db table.
+	 */
+
+	down(&db_tab->mutex);
+
+	--db_tab->page[index / MTHCA_DB_REC_PER_PAGE].refcount;
+
+	up(&db_tab->mutex);
+}
+
+struct mthca_user_db_table *mthca_init_user_db_tab(struct mthca_dev *dev)
+{
+	struct mthca_user_db_table *db_tab;
+	int npages;
+	int i;
+
+	if (!mthca_is_memfree(dev))
+		return NULL;
+
+	npages = dev->uar_table.uarc_size / 4096;
+	db_tab = kmalloc(sizeof *db_tab + npages * sizeof *db_tab->page, GFP_KERNEL);
+	if (!db_tab)
+		return ERR_PTR(-ENOMEM);
+
+	init_MUTEX(&db_tab->mutex);
+	for (i = 0; i < npages; ++i) {
+		db_tab->page[i].refcount = 0;
+		db_tab->page[i].uvirt    = 0;
+	}
+
+	return db_tab;
+}
+
+void mthca_cleanup_user_db_tab(struct mthca_dev *dev, struct mthca_uar *uar,
+			       struct mthca_user_db_table *db_tab)
+{
+	int i;
+	u8 status;
+
+	if (!mthca_is_memfree(dev))
+		return;
+
+	for (i = 0; i < dev->uar_table.uarc_size / 4096; ++i) {
+		if (db_tab->page[i].uvirt) {
+			mthca_UNMAP_ICM(dev, mthca_uarc_virt(dev, uar, i), 1, &status);
+			pci_unmap_sg(dev->pdev, &db_tab->page[i].mem, 1, PCI_DMA_TODEVICE);
+			put_page(db_tab->page[i].mem.page);
+		}
+	}
+}
+
 int mthca_alloc_db(struct mthca_dev *dev, int type, u32 qn, u32 **db)
 {
 	int group;
@@ -399,7 +537,8 @@ int mthca_alloc_db(struct mthca_dev *dev
 	}
 	memset(page->db_rec, 0, 4096);
 
-	ret = mthca_MAP_ICM_page(dev, page->mapping, mthca_uarc_virt(dev, i), &status);
+	ret = mthca_MAP_ICM_page(dev, page->mapping,
+				 mthca_uarc_virt(dev, &dev->driver_uar, i), &status);
 	if (!ret && status)
 		ret = -EINVAL;
 	if (ret) {
@@ -453,7 +592,7 @@ void mthca_free_db(struct mthca_dev *dev
 
 	if (bitmap_empty(page->used, MTHCA_DB_REC_PER_PAGE) &&
 	    i >= dev->db_tab->max_group1 - 1) {
-		mthca_UNMAP_ICM(dev, mthca_uarc_virt(dev, i), 1, &status);
+		mthca_UNMAP_ICM(dev, mthca_uarc_virt(dev, &dev->driver_uar, i), 1, &status);
 
 		dma_free_coherent(&dev->pdev->dev, 4096,
 				  page->db_rec, page->mapping);
@@ -522,7 +661,7 @@ void mthca_cleanup_db_tab(struct mthca_d
 		if (!bitmap_empty(dev->db_tab->page[i].used, MTHCA_DB_REC_PER_PAGE))
 			mthca_warn(dev, "Kernel UARC page %d not empty\n", i);
 
-		mthca_UNMAP_ICM(dev, mthca_uarc_virt(dev, i), 1, &status);
+		mthca_UNMAP_ICM(dev, mthca_uarc_virt(dev, &dev->driver_uar, i), 1, &status);
 
 		dma_free_coherent(&dev->pdev->dev, 4096,
 				  dev->db_tab->page[i].db_rec,
diff --git a/drivers/infiniband/hw/mthca/mthca_memfree.h b/drivers/infiniband/hw/mthca/mthca_memfree.h
--- a/drivers/infiniband/hw/mthca/mthca_memfree.h
+++ b/drivers/infiniband/hw/mthca/mthca_memfree.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2004, 2005 Topspin Communications.  All rights reserved.
+ * Copyright (c) 2005 Cisco Systems.  All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
@@ -148,7 +149,7 @@ struct mthca_db_table {
 	struct semaphore      mutex;
 };
 
-enum {
+enum mthca_db_type {
 	MTHCA_DB_TYPE_INVALID   = 0x0,
 	MTHCA_DB_TYPE_CQ_SET_CI = 0x1,
 	MTHCA_DB_TYPE_CQ_ARM    = 0x2,
@@ -158,6 +159,17 @@ enum {
 	MTHCA_DB_TYPE_GROUP_SEP = 0x7
 };
 
+struct mthca_user_db_table;
+struct mthca_uar;
+
+int mthca_map_user_db(struct mthca_dev *dev, struct mthca_uar *uar,
+		      struct mthca_user_db_table *db_tab, int index, u64 uaddr);
+void mthca_unmap_user_db(struct mthca_dev *dev, struct mthca_uar *uar,
+			 struct mthca_user_db_table *db_tab, int index);
+struct mthca_user_db_table *mthca_init_user_db_tab(struct mthca_dev *dev);
+void mthca_cleanup_user_db_tab(struct mthca_dev *dev, struct mthca_uar *uar,
+			       struct mthca_user_db_table *db_tab);
+
 int mthca_init_db_tab(struct mthca_dev *dev);
 void mthca_cleanup_db_tab(struct mthca_dev *dev);
 int mthca_alloc_db(struct mthca_dev *dev, int type, u32 qn, u32 **db);
diff --git a/drivers/infiniband/hw/mthca/mthca_mr.c b/drivers/infiniband/hw/mthca/mthca_mr.c
--- a/drivers/infiniband/hw/mthca/mthca_mr.c
+++ b/drivers/infiniband/hw/mthca/mthca_mr.c
@@ -40,6 +40,12 @@
 #include "mthca_cmd.h"
 #include "mthca_memfree.h"
 
+struct mthca_mtt {
+	struct mthca_buddy *buddy;
+	int                 order;
+	u32                 first_seg;
+};
+
 /*
  * Must be packed because mtt_seg is 64 bits but only aligned to 32 bits.
  */
@@ -173,8 +179,8 @@ static void __devexit mthca_buddy_cleanu
 	kfree(buddy->bits);
 }
 
-static u32 mthca_alloc_mtt(struct mthca_dev *dev, int order,
-			   struct mthca_buddy *buddy)
+static u32 mthca_alloc_mtt_range(struct mthca_dev *dev, int order,
+				 struct mthca_buddy *buddy)
 {
 	u32 seg = mthca_buddy_alloc(buddy, order);
 
@@ -191,14 +197,102 @@ static u32 mthca_alloc_mtt(struct mthca_
 	return seg;
 }
 
-static void mthca_free_mtt(struct mthca_dev *dev, u32 seg, int order,
-			   struct mthca_buddy* buddy)
+static struct mthca_mtt *__mthca_alloc_mtt(struct mthca_dev *dev, int size,
+					   struct mthca_buddy *buddy)
 {
-	mthca_buddy_free(buddy, seg, order);
+	struct mthca_mtt *mtt;
+	int i;
 
-	if (mthca_is_memfree(dev))
-		mthca_table_put_range(dev, dev->mr_table.mtt_table, seg,
-				      seg + (1 << order) - 1);
+	if (size <= 0)
+		return ERR_PTR(-EINVAL);
+
+	mtt = kmalloc(sizeof *mtt, GFP_KERNEL);
+	if (!mtt)
+		return ERR_PTR(-ENOMEM);
+
+	mtt->buddy = buddy;
+	mtt->order = 0;
+	for (i = MTHCA_MTT_SEG_SIZE / 8; i < size; i <<= 1)
+		++mtt->order;
+
+	mtt->first_seg = mthca_alloc_mtt_range(dev, mtt->order, buddy);
+	if (mtt->first_seg == -1) {
+		kfree(mtt);
+		return ERR_PTR(-ENOMEM);
+	}
+
+	return mtt;
+}
+
+struct mthca_mtt *mthca_alloc_mtt(struct mthca_dev *dev, int size)
+{
+	return __mthca_alloc_mtt(dev, size, &dev->mr_table.mtt_buddy);
+}
+
+void mthca_free_mtt(struct mthca_dev *dev, struct mthca_mtt *mtt)
+{
+	if (!mtt)
+		return;
+
+	mthca_buddy_free(mtt->buddy, mtt->first_seg, mtt->order);
+
+	mthca_table_put_range(dev, dev->mr_table.mtt_table,
+			      mtt->first_seg,
+			      mtt->first_seg + (1 << mtt->order) - 1);
+
+	kfree(mtt);
+}
+
+int mthca_write_mtt(struct mthca_dev *dev, struct mthca_mtt *mtt,
+		    int start_index, u64 *buffer_list, int list_len)
+{
+	struct mthca_mailbox *mailbox;
+	u64 *mtt_entry;
+	int err = 0;
+	u8 status;
+	int i;
+
+	mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL);
+	if (IS_ERR(mailbox))
+		return PTR_ERR(mailbox);
+	mtt_entry = mailbox->buf;
+
+	while (list_len > 0) {
+		mtt_entry[0] = cpu_to_be64(dev->mr_table.mtt_base +
+					   mtt->first_seg * MTHCA_MTT_SEG_SIZE +
+					   start_index * 8);
+		mtt_entry[1] = 0;
+		for (i = 0; i < list_len && i < MTHCA_MAILBOX_SIZE / 8 - 2; ++i)
+			mtt_entry[i + 2] = cpu_to_be64(buffer_list[i] |
+						       MTHCA_MTT_FLAG_PRESENT);
+
+		/*
+		 * If we have an odd number of entries to write, add
+		 * one more dummy entry for firmware efficiency.
+		 */
+		if (i & 1)
+			mtt_entry[i + 2] = 0;
+
+		err = mthca_WRITE_MTT(dev, mailbox, (i + 1) & ~1, &status);
+		if (err) {
+			mthca_warn(dev, "WRITE_MTT failed (%d)\n", err);
+			goto out;
+		}
+		if (status) {
+			mthca_warn(dev, "WRITE_MTT returned status 0x%02x\n",
+				   status);
+			err = -EINVAL;
+			goto out;
+		}
+
+		list_len    -= i;
+		start_index += i;
+		buffer_list += i;
+	}
+
+out:
+	mthca_free_mailbox(dev, mailbox);
+	return err;
 }
 
 static inline u32 tavor_hw_index_to_key(u32 ind)
@@ -237,91 +331,18 @@ static inline u32 key_to_hw_index(struct
 		return tavor_key_to_hw_index(key);
 }
 
-int mthca_mr_alloc_notrans(struct mthca_dev *dev, u32 pd,
-			   u32 access, struct mthca_mr *mr)
+int mthca_mr_alloc(struct mthca_dev *dev, u32 pd, int buffer_size_shift,
+		   u64 iova, u64 total_size, u32 access, struct mthca_mr *mr)
 {
-	void *mailbox = NULL;
+	struct mthca_mailbox *mailbox;
 	struct mthca_mpt_entry *mpt_entry;
 	u32 key;
+	int i;
 	int err;
 	u8 status;
 
 	might_sleep();
 
-	mr->order = -1;
-	key = mthca_alloc(&dev->mr_table.mpt_alloc);
-	if (key == -1)
-		return -ENOMEM;
-	mr->ibmr.rkey = mr->ibmr.lkey = hw_index_to_key(dev, key);
-
-	if (mthca_is_memfree(dev)) {
-		err = mthca_table_get(dev, dev->mr_table.mpt_table, key);
-		if (err)
-			goto err_out_mpt_free;
-	}
-
-	mailbox = kmalloc(sizeof *mpt_entry + MTHCA_CMD_MAILBOX_EXTRA,
-			  GFP_KERNEL);
-	if (!mailbox) {
-		err = -ENOMEM;
-		goto err_out_table;
-	}
-	mpt_entry = MAILBOX_ALIGN(mailbox);
-
-	mpt_entry->flags = cpu_to_be32(MTHCA_MPT_FLAG_SW_OWNS     |
-				       MTHCA_MPT_FLAG_MIO         |
-				       MTHCA_MPT_FLAG_PHYSICAL    |
-				       MTHCA_MPT_FLAG_REGION      |
-				       access);
-	mpt_entry->page_size = 0;
-	mpt_entry->key       = cpu_to_be32(key);
-	mpt_entry->pd        = cpu_to_be32(pd);
-	mpt_entry->start     = 0;
-	mpt_entry->length    = ~0ULL;
-
-	memset(&mpt_entry->lkey, 0,
-	       sizeof *mpt_entry - offsetof(struct mthca_mpt_entry, lkey));
-
-	err = mthca_SW2HW_MPT(dev, mpt_entry,
-			      key & (dev->limits.num_mpts - 1),
-			      &status);
-	if (err) {
-		mthca_warn(dev, "SW2HW_MPT failed (%d)\n", err);
-		goto err_out_table;
-	} else if (status) {
-		mthca_warn(dev, "SW2HW_MPT returned status 0x%02x\n",
-			   status);
-		err = -EINVAL;
-		goto err_out_table;
-	}
-
-	kfree(mailbox);
-	return err;
-
-err_out_table:
-	if (mthca_is_memfree(dev))
-		mthca_table_put(dev, dev->mr_table.mpt_table, key);
-
-err_out_mpt_free:
-	mthca_free(&dev->mr_table.mpt_alloc, key);
-	kfree(mailbox);
-	return err;
-}
-
-int mthca_mr_alloc_phys(struct mthca_dev *dev, u32 pd,
-			u64 *buffer_list, int buffer_size_shift,
-			int list_len, u64 iova, u64 total_size,
-			u32 access, struct mthca_mr *mr)
-{
-	void *mailbox;
-	u64 *mtt_entry;
-	struct mthca_mpt_entry *mpt_entry;
-	u32 key;
-	int err = -ENOMEM;
-	u8 status;
-	int i;
-
-	might_sleep();
 	WARN_ON(buffer_size_shift >= 32);
 
 	key = mthca_alloc(&dev->mr_table.mpt_alloc);
@@ -335,75 +356,33 @@ int mthca_mr_alloc_phys(struct mthca_dev
 			goto err_out_mpt_free;
 	}
 
-	for (i = MTHCA_MTT_SEG_SIZE / 8, mr->order = 0;
-	     i < list_len;
-	     i <<= 1, ++mr->order)
-		; /* nothing */
-
-	mr->first_seg = mthca_alloc_mtt(dev, mr->order,
-				       	&dev->mr_table.mtt_buddy);
-	if (mr->first_seg == -1)
+	mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL);
+	if (IS_ERR(mailbox)) {
+		err = PTR_ERR(mailbox);
 		goto err_out_table;
-
-	/*
-	 * If list_len is odd, we add one more dummy entry for
-	 * firmware efficiency.
-	 */
-	mailbox = kmalloc(max(sizeof *mpt_entry,
-			      (size_t) 8 * (list_len + (list_len & 1) + 2)) +
-			  MTHCA_CMD_MAILBOX_EXTRA,
-			  GFP_KERNEL);
-	if (!mailbox)
-		goto err_out_free_mtt;
-
-	mtt_entry = MAILBOX_ALIGN(mailbox);
-
-	mtt_entry[0] = cpu_to_be64(dev->mr_table.mtt_base +
-				   mr->first_seg * MTHCA_MTT_SEG_SIZE);
-	mtt_entry[1] = 0;
-	for (i = 0; i < list_len; ++i)
-		mtt_entry[i + 2] = cpu_to_be64(buffer_list[i] |
-					       MTHCA_MTT_FLAG_PRESENT);
-	if (list_len & 1) {
-		mtt_entry[i + 2] = 0;
-		++list_len;
-	}
-
-	if (0) {
-		mthca_dbg(dev, "Dumping MPT entry\n");
-		for (i = 0; i < list_len + 2; ++i)
-			printk(KERN_ERR "[%2d] %016llx\n",
-			       i, (unsigned long long) be64_to_cpu(mtt_entry[i]));
-	}
-
-	err = mthca_WRITE_MTT(dev, mtt_entry, list_len, &status);
-	if (err) {
-		mthca_warn(dev, "WRITE_MTT failed (%d)\n", err);
-		goto err_out_mailbox_free;
-	}
-	if (status) {
-		mthca_warn(dev, "WRITE_MTT returned status 0x%02x\n",
-			   status);
-		err = -EINVAL;
-		goto err_out_mailbox_free;
 	}
-
-	mpt_entry = MAILBOX_ALIGN(mailbox);
+	mpt_entry = mailbox->buf;
 
 	mpt_entry->flags = cpu_to_be32(MTHCA_MPT_FLAG_SW_OWNS     |
 				       MTHCA_MPT_FLAG_MIO         |
 				       MTHCA_MPT_FLAG_REGION      |
 				       access);
+	if (!mr->mtt)
+		mpt_entry->flags |= cpu_to_be32(MTHCA_MPT_FLAG_PHYSICAL);
 
 	mpt_entry->page_size = cpu_to_be32(buffer_size_shift - 12);
 	mpt_entry->key       = cpu_to_be32(key);
 	mpt_entry->pd        = cpu_to_be32(pd);
 	mpt_entry->start     = cpu_to_be64(iova);
 	mpt_entry->length    = cpu_to_be64(total_size);
+
 	memset(&mpt_entry->lkey, 0,
 	       sizeof *mpt_entry - offsetof(struct mthca_mpt_entry, lkey));
-	mpt_entry->mtt_seg   = cpu_to_be64(dev->mr_table.mtt_base +
-					   mr->first_seg * MTHCA_MTT_SEG_SIZE);
+
+	if (mr->mtt)
+		mpt_entry->mtt_seg =
+			cpu_to_be64(dev->mr_table.mtt_base +
+				    mr->mtt->first_seg * MTHCA_MTT_SEG_SIZE);
 
 	if (0) {
 		mthca_dbg(dev, "Dumping MPT entry %08x:\n", mr->ibmr.lkey);
@@ -416,45 +395,70 @@ int mthca_mr_alloc_phys(struct mthca_dev
 		}
 	}
 
-	err = mthca_SW2HW_MPT(dev, mpt_entry,
+	err = mthca_SW2HW_MPT(dev, mailbox,
 			      key & (dev->limits.num_mpts - 1),
 			      &status);
-	if (err)
+	if (err) {
 		mthca_warn(dev, "SW2HW_MPT failed (%d)\n", err);
-	else if (status) {
+		goto err_out_mailbox;
+	} else if (status) {
 		mthca_warn(dev, "SW2HW_MPT returned status 0x%02x\n",
 			   status);
 		err = -EINVAL;
+		goto err_out_mailbox;
 	}
 
-	kfree(mailbox);
+	mthca_free_mailbox(dev, mailbox);
 	return err;
 
-err_out_mailbox_free:
-	kfree(mailbox);
-
-err_out_free_mtt:
-	mthca_free_mtt(dev, mr->first_seg, mr->order, &dev->mr_table.mtt_buddy);
+err_out_mailbox:
+	mthca_free_mailbox(dev, mailbox);
 
 err_out_table:
-	if (mthca_is_memfree(dev))
-		mthca_table_put(dev, dev->mr_table.mpt_table, key);
+	mthca_table_put(dev, dev->mr_table.mpt_table, key);
 
 err_out_mpt_free:
 	mthca_free(&dev->mr_table.mpt_alloc, key);
 	return err;
 }
 
-/* Free mr or fmr */
-static void mthca_free_region(struct mthca_dev *dev, u32 lkey, int order,
-			      u32 first_seg, struct mthca_buddy *buddy)
+int mthca_mr_alloc_notrans(struct mthca_dev *dev, u32 pd,
+			   u32 access, struct mthca_mr *mr)
 {
-	if (order >= 0)
-		mthca_free_mtt(dev, first_seg, order, buddy);
+	mr->mtt = NULL;
+	return mthca_mr_alloc(dev, pd, 12, 0, ~0ULL, access, mr);
+}
 
-	if (mthca_is_memfree(dev))
-		mthca_table_put(dev, dev->mr_table.mpt_table,
-				arbel_key_to_hw_index(lkey));
+int mthca_mr_alloc_phys(struct mthca_dev *dev, u32 pd,
+			u64 *buffer_list, int buffer_size_shift,
+			int list_len, u64 iova, u64 total_size,
+			u32 access, struct mthca_mr *mr)
+{
+	int err;
+
+	mr->mtt = mthca_alloc_mtt(dev, list_len);
+	if (IS_ERR(mr->mtt))
+		return PTR_ERR(mr->mtt);
+
+	err = mthca_write_mtt(dev, mr->mtt, 0, buffer_list, list_len);
+	if (err) {
+		mthca_free_mtt(dev, mr->mtt);
+		return err;
+	}
+
+	err = mthca_mr_alloc(dev, pd, buffer_size_shift, iova,
+			     total_size, access, mr);
+	if (err)
+		mthca_free_mtt(dev, mr->mtt);
+
+	return err;
+}
+
+/* Free mr or fmr */
+static void mthca_free_region(struct mthca_dev *dev, u32 lkey)
+{
+	mthca_table_put(dev, dev->mr_table.mpt_table,
+			arbel_key_to_hw_index(lkey));
 
 	mthca_free(&dev->mr_table.mpt_alloc, key_to_hw_index(dev, lkey));
 }
@@ -476,15 +480,15 @@ void mthca_free_mr(struct mthca_dev *dev
 		mthca_warn(dev, "HW2SW_MPT returned status 0x%02x\n",
 			   status);
 
-	mthca_free_region(dev, mr->ibmr.lkey, mr->order, mr->first_seg,
-			  &dev->mr_table.mtt_buddy);
+	mthca_free_region(dev, mr->ibmr.lkey);
+	mthca_free_mtt(dev, mr->mtt);
 }
 
 int mthca_fmr_alloc(struct mthca_dev *dev, u32 pd,
 		    u32 access, struct mthca_fmr *mr)
 {
 	struct mthca_mpt_entry *mpt_entry;
-	void *mailbox;
+	struct mthca_mailbox *mailbox;
 	u64 mtt_seg;
 	u32 key, idx;
 	u8 status;
@@ -522,31 +526,24 @@ int mthca_fmr_alloc(struct mthca_dev *de
 		mr->mem.tavor.mpt = dev->mr_table.tavor_fmr.mpt_base +
 		       	sizeof *(mr->mem.tavor.mpt) * idx;
 
-	for (i = MTHCA_MTT_SEG_SIZE / 8, mr->order = 0;
-	     i < list_len;
-	     i <<= 1, ++mr->order)
-		; /* nothing */
-
-	mr->first_seg = mthca_alloc_mtt(dev, mr->order,
-				       	dev->mr_table.fmr_mtt_buddy);
-	if (mr->first_seg == -1)
+	mr->mtt = __mthca_alloc_mtt(dev, list_len, dev->mr_table.fmr_mtt_buddy);
+	if (IS_ERR(mr->mtt))
 		goto err_out_table;
 
-	mtt_seg = mr->first_seg * MTHCA_MTT_SEG_SIZE;
+	mtt_seg = mr->mtt->first_seg * MTHCA_MTT_SEG_SIZE;
 
 	if (mthca_is_memfree(dev)) {
 		mr->mem.arbel.mtts = mthca_table_find(dev->mr_table.mtt_table,
-						      mr->first_seg);
+						      mr->mtt->first_seg);
 		BUG_ON(!mr->mem.arbel.mtts);
 	} else
 		mr->mem.tavor.mtts = dev->mr_table.tavor_fmr.mtt_base + mtt_seg;
 
-	mailbox = kmalloc(sizeof *mpt_entry + MTHCA_CMD_MAILBOX_EXTRA,
-			  GFP_KERNEL);
-	if (!mailbox)
+	mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL);
+	if (IS_ERR(mailbox))
 		goto err_out_free_mtt;
 
-	mpt_entry = MAILBOX_ALIGN(mailbox);
+	mpt_entry = mailbox->buf;
 
 	mpt_entry->flags = cpu_to_be32(MTHCA_MPT_FLAG_SW_OWNS     |
 				       MTHCA_MPT_FLAG_MIO         |
@@ -571,7 +568,7 @@ int mthca_fmr_alloc(struct mthca_dev *de
 		}
 	}
 
-	err = mthca_SW2HW_MPT(dev, mpt_entry,
+	err = mthca_SW2HW_MPT(dev, mailbox,
 			      key & (dev->limits.num_mpts - 1),
 			      &status);
 	if (err) {
@@ -585,19 +582,17 @@ int mthca_fmr_alloc(struct mthca_dev *de
 		goto err_out_mailbox_free;
 	}
 
-	kfree(mailbox);
+	mthca_free_mailbox(dev, mailbox);
 	return 0;
 
 err_out_mailbox_free:
-	kfree(mailbox);
+	mthca_free_mailbox(dev, mailbox);
 
 err_out_free_mtt:
-	mthca_free_mtt(dev, mr->first_seg, mr->order,
-		       dev->mr_table.fmr_mtt_buddy);
+	mthca_free_mtt(dev, mr->mtt);
 
 err_out_table:
-	if (mthca_is_memfree(dev))
-		mthca_table_put(dev, dev->mr_table.mpt_table, key);
+	mthca_table_put(dev, dev->mr_table.mpt_table, key);
 
 err_out_mpt_free:
 	mthca_free(&dev->mr_table.mpt_alloc, mr->ibmr.lkey);
@@ -609,8 +604,9 @@ int mthca_free_fmr(struct mthca_dev *dev
 	if (fmr->maps)
 		return -EBUSY;
 
-	mthca_free_region(dev, fmr->ibmr.lkey, fmr->order, fmr->first_seg,
-			  dev->mr_table.fmr_mtt_buddy);
+	mthca_free_region(dev, fmr->ibmr.lkey);
+	mthca_free_mtt(dev, fmr->mtt);
+
 	return 0;
 }
 
@@ -826,7 +822,8 @@ int __devinit mthca_init_mr_table(struct
 	if (dev->limits.reserved_mtts) {
 		i = fls(dev->limits.reserved_mtts - 1);
 
-		if (mthca_alloc_mtt(dev, i, dev->mr_table.fmr_mtt_buddy) == -1) {
+		if (mthca_alloc_mtt_range(dev, i,
+					  dev->mr_table.fmr_mtt_buddy) == -1) {
 			mthca_warn(dev, "MTT table of order %d is too small.\n",
 				  dev->mr_table.fmr_mtt_buddy->max_order);
 			err = -ENOMEM;
diff --git a/drivers/infiniband/hw/mthca/mthca_pd.c b/drivers/infiniband/hw/mthca/mthca_pd.c
--- a/drivers/infiniband/hw/mthca/mthca_pd.c
+++ b/drivers/infiniband/hw/mthca/mthca_pd.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2004 Topspin Communications.  All rights reserved.
+ * Copyright (c) 2005 Cisco Systems.  All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
@@ -37,23 +38,27 @@
 
 #include "mthca_dev.h"
 
-int mthca_pd_alloc(struct mthca_dev *dev, struct mthca_pd *pd)
+int mthca_pd_alloc(struct mthca_dev *dev, int privileged, struct mthca_pd *pd)
 {
-	int err;
+	int err = 0;
 
 	might_sleep();
 
+	pd->privileged = privileged;
+
 	atomic_set(&pd->sqp_count, 0);
 	pd->pd_num = mthca_alloc(&dev->pd_table.alloc);
 	if (pd->pd_num == -1)
 		return -ENOMEM;
 
-	err = mthca_mr_alloc_notrans(dev, pd->pd_num,
-				     MTHCA_MPT_FLAG_LOCAL_READ |
-				     MTHCA_MPT_FLAG_LOCAL_WRITE,
-				     &pd->ntmr);
-	if (err)
-		mthca_free(&dev->pd_table.alloc, pd->pd_num);
+	if (privileged) {
+		err = mthca_mr_alloc_notrans(dev, pd->pd_num,
+					     MTHCA_MPT_FLAG_LOCAL_READ |
+					     MTHCA_MPT_FLAG_LOCAL_WRITE,
+					     &pd->ntmr);
+		if (err)
+			mthca_free(&dev->pd_table.alloc, pd->pd_num);
+	}
 
 	return err;
 }
@@ -61,7 +66,8 @@ int mthca_pd_alloc(struct mthca_dev *dev
 void mthca_pd_free(struct mthca_dev *dev, struct mthca_pd *pd)
 {
 	might_sleep();
-	mthca_free_mr(dev, &pd->ntmr);
+	if (pd->privileged)
+		mthca_free_mr(dev, &pd->ntmr);
 	mthca_free(&dev->pd_table.alloc, pd->pd_num);
 }
 
diff --git a/drivers/infiniband/hw/mthca/mthca_provider.c b/drivers/infiniband/hw/mthca/mthca_provider.c
--- a/drivers/infiniband/hw/mthca/mthca_provider.c
+++ b/drivers/infiniband/hw/mthca/mthca_provider.c
@@ -1,5 +1,7 @@
 /*
  * Copyright (c) 2004, 2005 Topspin Communications.  All rights reserved.
+ * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright (c) 2005 Cisco Systems. All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
@@ -33,9 +35,12 @@
  */
 
 #include <ib_smi.h>
+#include <linux/mm.h>
 
 #include "mthca_dev.h"
 #include "mthca_cmd.h"
+#include "mthca_user.h"
+#include "mthca_memfree.h"
 
 static int mthca_query_device(struct ib_device *ibdev,
 			      struct ib_device_attr *props)
@@ -52,7 +57,7 @@ static int mthca_query_device(struct ib_
 	if (!in_mad || !out_mad)
 		goto out;
 
-	memset(props, 0, sizeof props);
+	memset(props, 0, sizeof *props);
 
 	props->fw_ver              = mdev->fw_ver;
 
@@ -283,7 +288,78 @@ static int mthca_query_gid(struct ib_dev
 	return err;
 }
 
-static struct ib_pd *mthca_alloc_pd(struct ib_device *ibdev)
+static struct ib_ucontext *mthca_alloc_ucontext(struct ib_device *ibdev,
+						struct ib_udata *udata)
+{
+	struct mthca_alloc_ucontext_resp uresp;
+	struct mthca_ucontext           *context;
+	int                              err;
+
+	memset(&uresp, 0, sizeof uresp);
+
+	uresp.qp_tab_size = to_mdev(ibdev)->limits.num_qps;
+	if (mthca_is_memfree(to_mdev(ibdev)))
+		uresp.uarc_size = to_mdev(ibdev)->uar_table.uarc_size;
+	else
+		uresp.uarc_size = 0;
+
+	context = kmalloc(sizeof *context, GFP_KERNEL);
+	if (!context)
+		return ERR_PTR(-ENOMEM);
+
+	err = mthca_uar_alloc(to_mdev(ibdev), &context->uar);
+	if (err) {
+		kfree(context);
+		return ERR_PTR(err);
+	}
+
+	context->db_tab = mthca_init_user_db_tab(to_mdev(ibdev));
+	if (IS_ERR(context->db_tab)) {
+		err = PTR_ERR(context->db_tab);
+		mthca_uar_free(to_mdev(ibdev), &context->uar);
+		kfree(context);
+		return ERR_PTR(err);
+	}
+
+	if (ib_copy_to_udata(udata, &uresp, sizeof uresp)) {
+		mthca_cleanup_user_db_tab(to_mdev(ibdev), &context->uar, context->db_tab);
+		mthca_uar_free(to_mdev(ibdev), &context->uar);
+		kfree(context);
+		return ERR_PTR(-EFAULT);
+	}
+
+	return &context->ibucontext;
+}
+
+static int mthca_dealloc_ucontext(struct ib_ucontext *context)
+{
+	mthca_cleanup_user_db_tab(to_mdev(context->device), &to_mucontext(context)->uar,
+				  to_mucontext(context)->db_tab);
+	mthca_uar_free(to_mdev(context->device), &to_mucontext(context)->uar);
+	kfree(to_mucontext(context));
+
+	return 0;
+}
+
+static int mthca_mmap_uar(struct ib_ucontext *context,
+			  struct vm_area_struct *vma)
+{
+	if (vma->vm_end - vma->vm_start != PAGE_SIZE)
+		return -EINVAL;
+
+	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+
+	if (io_remap_pfn_range(vma, vma->vm_start,
+			       to_mucontext(context)->uar.pfn,
+			       PAGE_SIZE, vma->vm_page_prot))
+		return -EAGAIN;
+
+	return 0;
+}
+
+static struct ib_pd *mthca_alloc_pd(struct ib_device *ibdev,
+				    struct ib_ucontext *context,
+				    struct ib_udata *udata)
 {
 	struct mthca_pd *pd;
 	int err;
@@ -292,12 +368,20 @@ static struct ib_pd *mthca_alloc_pd(stru
 	if (!pd)
 		return ERR_PTR(-ENOMEM);
 
-	err = mthca_pd_alloc(to_mdev(ibdev), pd);
+	err = mthca_pd_alloc(to_mdev(ibdev), !context, pd);
 	if (err) {
 		kfree(pd);
 		return ERR_PTR(err);
 	}
 
+	if (context) {
+		if (ib_copy_to_udata(udata, &pd->pd_num, sizeof (__u32))) {
+			mthca_pd_free(to_mdev(ibdev), pd);
+			kfree(pd);
+			return ERR_PTR(-EFAULT);
+		}
+	}
+
 	return &pd->ibpd;
 }
 
@@ -337,8 +421,10 @@ static int mthca_ah_destroy(struct ib_ah
 }
 
 static struct ib_qp *mthca_create_qp(struct ib_pd *pd,
-				     struct ib_qp_init_attr *init_attr)
+				     struct ib_qp_init_attr *init_attr,
+				     struct ib_udata *udata)
 {
+	struct mthca_create_qp ucmd;
 	struct mthca_qp *qp;
 	int err;
 
@@ -347,41 +433,82 @@ static struct ib_qp *mthca_create_qp(str
 	case IB_QPT_UC:
 	case IB_QPT_UD:
 	{
+		struct mthca_ucontext *context;
+
 		qp = kmalloc(sizeof *qp, GFP_KERNEL);
 		if (!qp)
 			return ERR_PTR(-ENOMEM);
 
-		qp->sq.max    = init_attr->cap.max_send_wr;
-		qp->rq.max    = init_attr->cap.max_recv_wr;
-		qp->sq.max_gs = init_attr->cap.max_send_sge;
-		qp->rq.max_gs = init_attr->cap.max_recv_sge;
+		if (pd->uobject) {
+			context = to_mucontext(pd->uobject->context);
+
+			if (ib_copy_from_udata(&ucmd, udata, sizeof ucmd))
+				return ERR_PTR(-EFAULT);
+
+			err = mthca_map_user_db(to_mdev(pd->device), &context->uar,
+						context->db_tab,
+						ucmd.sq_db_index, ucmd.sq_db_page);
+			if (err) {
+				kfree(qp);
+				return ERR_PTR(err);
+			}
+
+			err = mthca_map_user_db(to_mdev(pd->device), &context->uar,
+						context->db_tab,
+						ucmd.rq_db_index, ucmd.rq_db_page);
+			if (err) {
+				mthca_unmap_user_db(to_mdev(pd->device),
+						    &context->uar,
+						    context->db_tab,
+						    ucmd.sq_db_index);
+				kfree(qp);
+				return ERR_PTR(err);
+			}
+
+			qp->mr.ibmr.lkey = ucmd.lkey;
+			qp->sq.db_index  = ucmd.sq_db_index;
+			qp->rq.db_index  = ucmd.rq_db_index;
+		}
 
 		err = mthca_alloc_qp(to_mdev(pd->device), to_mpd(pd),
 				     to_mcq(init_attr->send_cq),
 				     to_mcq(init_attr->recv_cq),
 				     init_attr->qp_type, init_attr->sq_sig_type,
-				     qp);
+				     &init_attr->cap, qp);
+
+		if (err && pd->uobject) {
+			context = to_mucontext(pd->uobject->context);
+
+			mthca_unmap_user_db(to_mdev(pd->device),
+					    &context->uar,
+					    context->db_tab,
+					    ucmd.sq_db_index);
+			mthca_unmap_user_db(to_mdev(pd->device),
+					    &context->uar,
+					    context->db_tab,
+					    ucmd.rq_db_index);
+		}
+
 		qp->ibqp.qp_num = qp->qpn;
 		break;
 	}
 	case IB_QPT_SMI:
 	case IB_QPT_GSI:
 	{
+		/* Don't allow userspace to create special QPs */
+		if (pd->uobject)
+			return ERR_PTR(-EINVAL);
+
 		qp = kmalloc(sizeof (struct mthca_sqp), GFP_KERNEL);
 		if (!qp)
 			return ERR_PTR(-ENOMEM);
 
-		qp->sq.max    = init_attr->cap.max_send_wr;
-		qp->rq.max    = init_attr->cap.max_recv_wr;
-		qp->sq.max_gs = init_attr->cap.max_send_sge;
-		qp->rq.max_gs = init_attr->cap.max_recv_sge;
-
 		qp->ibqp.qp_num = init_attr->qp_type == IB_QPT_SMI ? 0 : 1;
 
 		err = mthca_alloc_sqp(to_mdev(pd->device), to_mpd(pd),
 				      to_mcq(init_attr->send_cq),
 				      to_mcq(init_attr->recv_cq),
-				      init_attr->sq_sig_type,
+				      init_attr->sq_sig_type, &init_attr->cap,
 				      qp->ibqp.qp_num, init_attr->port_num,
 				      to_msqp(qp));
 		break;
@@ -396,42 +523,115 @@ static struct ib_qp *mthca_create_qp(str
 		return ERR_PTR(err);
 	}
 
-        init_attr->cap.max_inline_data = 0;
+	init_attr->cap.max_inline_data = 0;
+	init_attr->cap.max_send_wr     = qp->sq.max;
+	init_attr->cap.max_recv_wr     = qp->rq.max;
+	init_attr->cap.max_send_sge    = qp->sq.max_gs;
+	init_attr->cap.max_recv_sge    = qp->rq.max_gs;
 
 	return &qp->ibqp;
 }
 
 static int mthca_destroy_qp(struct ib_qp *qp)
 {
+	if (qp->uobject) {
+		mthca_unmap_user_db(to_mdev(qp->device),
+				    &to_mucontext(qp->uobject->context)->uar,
+				    to_mucontext(qp->uobject->context)->db_tab,
+				    to_mqp(qp)->sq.db_index);
+		mthca_unmap_user_db(to_mdev(qp->device),
+				    &to_mucontext(qp->uobject->context)->uar,
+				    to_mucontext(qp->uobject->context)->db_tab,
+				    to_mqp(qp)->rq.db_index);
+	}
 	mthca_free_qp(to_mdev(qp->device), to_mqp(qp));
 	kfree(qp);
 	return 0;
 }
 
-static struct ib_cq *mthca_create_cq(struct ib_device *ibdev, int entries)
+static struct ib_cq *mthca_create_cq(struct ib_device *ibdev, int entries,
+				     struct ib_ucontext *context,
+				     struct ib_udata *udata)
 {
+	struct mthca_create_cq ucmd;
 	struct mthca_cq *cq;
 	int nent;
 	int err;
 
+	if (context) {
+		if (ib_copy_from_udata(&ucmd, udata, sizeof ucmd))
+			return ERR_PTR(-EFAULT);
+
+		err = mthca_map_user_db(to_mdev(ibdev), &to_mucontext(context)->uar,
+					to_mucontext(context)->db_tab,
+					ucmd.set_db_index, ucmd.set_db_page);
+		if (err)
+			return ERR_PTR(err);
+
+		err = mthca_map_user_db(to_mdev(ibdev), &to_mucontext(context)->uar,
+					to_mucontext(context)->db_tab,
+					ucmd.arm_db_index, ucmd.arm_db_page);
+		if (err)
+			goto err_unmap_set;
+	}
+
 	cq = kmalloc(sizeof *cq, GFP_KERNEL);
-	if (!cq)
-		return ERR_PTR(-ENOMEM);
+	if (!cq) {
+		err = -ENOMEM;
+		goto err_unmap_arm;
+	}
+
+	if (context) {
+		cq->mr.ibmr.lkey    = ucmd.lkey;
+		cq->set_ci_db_index = ucmd.set_db_index;
+		cq->arm_db_index    = ucmd.arm_db_index;
+	}
 
 	for (nent = 1; nent <= entries; nent <<= 1)
 		; /* nothing */
 
-	err = mthca_init_cq(to_mdev(ibdev), nent, cq);
-	if (err) {
-		kfree(cq);
-		cq = ERR_PTR(err);
+	err = mthca_init_cq(to_mdev(ibdev), nent,
+			    context ? to_mucontext(context) : NULL,
+			    context ? ucmd.pdn : to_mdev(ibdev)->driver_pd.pd_num,
+			    cq);
+	if (err)
+		goto err_free;
+
+	if (context && ib_copy_to_udata(udata, &cq->cqn, sizeof (__u32))) {
+		mthca_free_cq(to_mdev(ibdev), cq);
+		goto err_free;
 	}
 
 	return &cq->ibcq;
+
+err_free:
+	kfree(cq);
+
+err_unmap_arm:
+	if (context)
+		mthca_unmap_user_db(to_mdev(ibdev), &to_mucontext(context)->uar,
+				    to_mucontext(context)->db_tab, ucmd.arm_db_index);
+
+err_unmap_set:
+	if (context)
+		mthca_unmap_user_db(to_mdev(ibdev), &to_mucontext(context)->uar,
+				    to_mucontext(context)->db_tab, ucmd.set_db_index);
+
+	return ERR_PTR(err);
 }
 
 static int mthca_destroy_cq(struct ib_cq *cq)
 {
+	if (cq->uobject) {
+		mthca_unmap_user_db(to_mdev(cq->device),
+				    &to_mucontext(cq->uobject->context)->uar,
+				    to_mucontext(cq->uobject->context)->db_tab,
+				    to_mcq(cq)->arm_db_index);
+		mthca_unmap_user_db(to_mdev(cq->device),
+				    &to_mucontext(cq->uobject->context)->uar,
+				    to_mucontext(cq->uobject->context)->db_tab,
+				    to_mcq(cq)->set_ci_db_index);
+	}
 	mthca_free_cq(to_mdev(cq->device), to_mcq(cq));
 	kfree(cq);
 
@@ -558,6 +758,7 @@ static struct ib_mr *mthca_reg_phys_mr(s
 				  convert_access(acc), mr);
 
 	if (err) {
+		kfree(page_list);
 		kfree(mr);
 		return ERR_PTR(err);
 	}
@@ -566,6 +767,87 @@ static struct ib_mr *mthca_reg_phys_mr(s
 	return &mr->ibmr;
 }
 
+static struct ib_mr *mthca_reg_user_mr(struct ib_pd *pd, struct ib_umem *region,
+				       int acc, struct ib_udata *udata)
+{
+	struct mthca_dev *dev = to_mdev(pd->device);
+	struct ib_umem_chunk *chunk;
+	struct mthca_mr *mr;
+	u64 *pages;
+	int shift, n, len;
+	int i, j, k;
+	int err = 0;
+
+	shift = ffs(region->page_size) - 1;
+
+	mr = kmalloc(sizeof *mr, GFP_KERNEL);
+	if (!mr)
+		return ERR_PTR(-ENOMEM);
+
+	n = 0;
+	list_for_each_entry(chunk, &region->chunk_list, list)
+		n += chunk->nents;
+
+	mr->mtt = mthca_alloc_mtt(dev, n);
+	if (IS_ERR(mr->mtt)) {
+		err = PTR_ERR(mr->mtt);
+		goto err;
+	}
+
+	pages = (u64 *) __get_free_page(GFP_KERNEL);
+	if (!pages) {
+		err = -ENOMEM;
+		goto err_mtt;
+	}
+
+	i = n = 0;
+
+	list_for_each_entry(chunk, &region->chunk_list, list)
+		for (j = 0; j < chunk->nmap; ++j) {
+			len = sg_dma_len(&chunk->page_list[j]) >> shift;
+			for (k = 0; k < len; ++k) {
+				pages[i++] = sg_dma_address(&chunk->page_list[j]) +
+					region->page_size * k;
+				/*
+				 * Be friendly to WRITE_MTT command
+				 * and leave two empty slots for the
+				 * index and reserved fields of the
+				 * mailbox.
+				 */
+				if (i == PAGE_SIZE / sizeof (u64) - 2) {
+					err = mthca_write_mtt(dev, mr->mtt,
+							      n, pages, i);
+					if (err)
+						goto mtt_done;
+					n += i;
+					i = 0;
+				}
+			}
+		}
+
+	if (i)
+		err = mthca_write_mtt(dev, mr->mtt, n, pages, i);
+mtt_done:
+	free_page((unsigned long) pages);
+	if (err)
+		goto err_mtt;
+
+	err = mthca_mr_alloc(dev, to_mpd(pd)->pd_num, shift, region->virt_base,
+			     region->length, convert_access(acc), mr);
+
+	if (err)
+		goto err_mtt;
+
+	return &mr->ibmr;
+
+err_mtt:
+	mthca_free_mtt(dev, mr->mtt);
+
+err:
+	kfree(mr);
+	return ERR_PTR(err);
+}
+
 static int mthca_dereg_mr(struct ib_mr *mr)
 {
 	struct mthca_mr *mmr = to_mmr(mr);
@@ -690,6 +972,8 @@ int mthca_register_device(struct mthca_d
 	int i;
 
 	strlcpy(dev->ib_dev.name, "mthca%d", IB_DEVICE_NAME_MAX);
+	dev->ib_dev.owner                = THIS_MODULE;
+
 	dev->ib_dev.node_type            = IB_NODE_CA;
 	dev->ib_dev.phys_port_cnt        = dev->limits.num_ports;
 	dev->ib_dev.dma_device           = &dev->pdev->dev;
@@ -699,6 +983,9 @@ int mthca_register_device(struct mthca_d
 	dev->ib_dev.modify_port          = mthca_modify_port;
 	dev->ib_dev.query_pkey           = mthca_query_pkey;
 	dev->ib_dev.query_gid            = mthca_query_gid;
+	dev->ib_dev.alloc_ucontext       = mthca_alloc_ucontext;
+	dev->ib_dev.dealloc_ucontext     = mthca_dealloc_ucontext;
+	dev->ib_dev.mmap                 = mthca_mmap_uar;
 	dev->ib_dev.alloc_pd             = mthca_alloc_pd;
 	dev->ib_dev.dealloc_pd           = mthca_dealloc_pd;
 	dev->ib_dev.create_ah            = mthca_ah_create;
@@ -711,6 +998,7 @@ int mthca_register_device(struct mthca_d
 	dev->ib_dev.poll_cq              = mthca_poll_cq;
 	dev->ib_dev.get_dma_mr           = mthca_get_dma_mr;
 	dev->ib_dev.reg_phys_mr          = mthca_reg_phys_mr;
+	dev->ib_dev.reg_user_mr          = mthca_reg_user_mr;
 	dev->ib_dev.dereg_mr             = mthca_dereg_mr;
 
 	if (dev->mthca_flags & MTHCA_FLAG_FMR) {
diff --git a/drivers/infiniband/hw/mthca/mthca_provider.h b/drivers/infiniband/hw/mthca/mthca_provider.h
--- a/drivers/infiniband/hw/mthca/mthca_provider.h
+++ b/drivers/infiniband/hw/mthca/mthca_provider.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2004 Topspin Communications.  All rights reserved.
+ * Copyright (c) 2005 Cisco Systems.  All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
@@ -54,18 +55,26 @@ struct mthca_uar {
 	int           index;
 };
 
+struct mthca_user_db_table;
+
+struct mthca_ucontext {
+	struct ib_ucontext          ibucontext;
+	struct mthca_uar            uar;
+	struct mthca_user_db_table *db_tab;
+};
+
+struct mthca_mtt;
+
 struct mthca_mr {
-	struct ib_mr ibmr;
-	int order;
-	u32 first_seg;
+	struct ib_mr      ibmr;
+	struct mthca_mtt *mtt;
 };
 
 struct mthca_fmr {
-	struct ib_fmr ibmr;
+	struct ib_fmr      ibmr;
 	struct ib_fmr_attr attr;
-	int order;
-	u32 first_seg;
-	int maps;
+	struct mthca_mtt  *mtt;
+	int                maps;
 	union {
 		struct {
 			struct mthca_mpt_entry __iomem *mpt;
@@ -83,6 +92,7 @@ struct mthca_pd {
 	u32             pd_num;
 	atomic_t        sqp_count;
 	struct mthca_mr ntmr;
+	int             privileged;
 };
 
 struct mthca_eq {
@@ -167,6 +177,7 @@ struct mthca_cq {
 	int                    cqn;
 	u32                    cons_index;
 	int                    is_direct;
+	int                    is_kernel;
 
 	/* Next fields are Arbel only */
 	int                    set_ci_db_index;
@@ -236,6 +247,11 @@ struct mthca_sqp {
 	dma_addr_t      header_dma;
 };
 
+static inline struct mthca_ucontext *to_mucontext(struct ib_ucontext *ibucontext)
+{
+	return container_of(ibucontext, struct mthca_ucontext, ibucontext);
+}
+
 static inline struct mthca_fmr *to_mfmr(struct ib_fmr *ibmr)
 {
 	return container_of(ibmr, struct mthca_fmr, ibmr);
diff --git a/drivers/infiniband/hw/mthca/mthca_qp.c b/drivers/infiniband/hw/mthca/mthca_qp.c
--- a/drivers/infiniband/hw/mthca/mthca_qp.c
+++ b/drivers/infiniband/hw/mthca/mthca_qp.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2004 Topspin Communications.  All rights reserved.
+ * Copyright (c) 2005 Cisco Systems. All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
@@ -46,7 +47,9 @@ enum {
 	MTHCA_MAX_DIRECT_QP_SIZE = 4 * PAGE_SIZE,
 	MTHCA_ACK_REQ_FREQ       = 10,
 	MTHCA_FLIGHT_LIMIT       = 9,
-	MTHCA_UD_HEADER_SIZE     = 72 /* largest UD header possible */
+	MTHCA_UD_HEADER_SIZE     = 72, /* largest UD header possible */
+	MTHCA_INLINE_HEADER_SIZE = 4,  /* data segment overhead for inline */
+	MTHCA_INLINE_CHUNK_SIZE  = 16  /* inline data segment chunk */
 };
 
 enum {
@@ -357,6 +360,9 @@ static const struct {
 				[UD]  = (IB_QP_PKEY_INDEX |
 					 IB_QP_PORT       |
 					 IB_QP_QKEY),
+				[UC]  = (IB_QP_PKEY_INDEX |
+					 IB_QP_PORT       |
+					 IB_QP_ACCESS_FLAGS),
 				[RC]  = (IB_QP_PKEY_INDEX |
 					 IB_QP_PORT       |
 					 IB_QP_ACCESS_FLAGS),
@@ -378,6 +384,9 @@ static const struct {
 				[UD]  = (IB_QP_PKEY_INDEX |
 					 IB_QP_PORT       |
 					 IB_QP_QKEY),
+				[UC]  = (IB_QP_PKEY_INDEX |
+					 IB_QP_PORT       |
+					 IB_QP_ACCESS_FLAGS),
 				[RC]  = (IB_QP_PKEY_INDEX |
 					 IB_QP_PORT       |
 					 IB_QP_ACCESS_FLAGS),
@@ -388,6 +397,11 @@ static const struct {
 		[IB_QPS_RTR]   = {
 			.trans = MTHCA_TRANS_INIT2RTR,
 			.req_param = {
+				[UC]  = (IB_QP_AV                  |
+					 IB_QP_PATH_MTU            |
+					 IB_QP_DEST_QPN            |
+					 IB_QP_RQ_PSN              |
+					 IB_QP_MAX_DEST_RD_ATOMIC),
 				[RC]  = (IB_QP_AV                  |
 					 IB_QP_PATH_MTU            |
 					 IB_QP_DEST_QPN            |
@@ -398,6 +412,9 @@ static const struct {
 			.opt_param = {
 				[UD]  = (IB_QP_PKEY_INDEX |
 					 IB_QP_QKEY),
+				[UC]  = (IB_QP_ALT_PATH     |
+					 IB_QP_ACCESS_FLAGS |
+					 IB_QP_PKEY_INDEX),
 				[RC]  = (IB_QP_ALT_PATH     |
 					 IB_QP_ACCESS_FLAGS |
 					 IB_QP_PKEY_INDEX),
@@ -413,6 +430,8 @@ static const struct {
 			.trans = MTHCA_TRANS_RTR2RTS,
 			.req_param = {
 				[UD]  = IB_QP_SQ_PSN,
+				[UC]  = (IB_QP_SQ_PSN            |
+					 IB_QP_MAX_QP_RD_ATOMIC),
 				[RC]  = (IB_QP_TIMEOUT           |
 					 IB_QP_RETRY_CNT         |
 					 IB_QP_RNR_RETRY         |
@@ -423,6 +442,11 @@ static const struct {
 			.opt_param = {
 				[UD]  = (IB_QP_CUR_STATE             |
 					 IB_QP_QKEY),
+				[UC]  = (IB_QP_CUR_STATE             |
+					 IB_QP_ALT_PATH              |
+					 IB_QP_ACCESS_FLAGS          |
+					 IB_QP_PKEY_INDEX            |
+					 IB_QP_PATH_MIG_STATE),
 				[RC]  = (IB_QP_CUR_STATE             |
 					 IB_QP_ALT_PATH              |
 					 IB_QP_ACCESS_FLAGS          |
@@ -442,6 +466,9 @@ static const struct {
 			.opt_param = {
 				[UD]  = (IB_QP_CUR_STATE             |
 					 IB_QP_QKEY),
+				[UC]  = (IB_QP_ACCESS_FLAGS          |
+					 IB_QP_ALT_PATH              |
+					 IB_QP_PATH_MIG_STATE),
 				[RC]  = (IB_QP_ACCESS_FLAGS          |
 					 IB_QP_ALT_PATH              |
 					 IB_QP_PATH_MIG_STATE        |
@@ -462,6 +489,10 @@ static const struct {
 			.opt_param = {
 				[UD]  = (IB_QP_CUR_STATE             |
 					 IB_QP_QKEY),
+				[UC]  = (IB_QP_CUR_STATE             |
+					 IB_QP_ALT_PATH              |
+					 IB_QP_ACCESS_FLAGS          |
+					 IB_QP_PATH_MIG_STATE),
 				[RC]  = (IB_QP_CUR_STATE             |
 					 IB_QP_ALT_PATH              |
 					 IB_QP_ACCESS_FLAGS          |
@@ -476,6 +507,14 @@ static const struct {
 			.opt_param = {
 				[UD]  = (IB_QP_PKEY_INDEX            |
 					 IB_QP_QKEY),
+				[UC]  = (IB_QP_AV                    |
+					 IB_QP_MAX_QP_RD_ATOMIC      |
+					 IB_QP_MAX_DEST_RD_ATOMIC    |
+					 IB_QP_CUR_STATE             |
+					 IB_QP_ALT_PATH              |
+					 IB_QP_ACCESS_FLAGS          |
+					 IB_QP_PKEY_INDEX            |
+					 IB_QP_PATH_MIG_STATE),
 				[RC]  = (IB_QP_AV                    |
 					 IB_QP_TIMEOUT               |
 					 IB_QP_RETRY_CNT             |
@@ -501,6 +540,7 @@ static const struct {
 			.opt_param = {
 				[UD]  = (IB_QP_CUR_STATE             |
 					 IB_QP_QKEY),
+				[UC]  = (IB_QP_CUR_STATE),
 				[RC]  = (IB_QP_CUR_STATE             |
 					 IB_QP_MIN_RNR_TIMER),
 				[MLX] = (IB_QP_CUR_STATE             |
@@ -552,7 +592,7 @@ int mthca_modify_qp(struct ib_qp *ibqp, 
 	struct mthca_dev *dev = to_mdev(ibqp->device);
 	struct mthca_qp *qp = to_mqp(ibqp);
 	enum ib_qp_state cur_state, new_state;
-	void *mailbox = NULL;
+	struct mthca_mailbox *mailbox;
 	struct mthca_qp_param *qp_param;
 	struct mthca_qp_context *qp_context;
 	u32 req_param, opt_param;
@@ -609,10 +649,10 @@ int mthca_modify_qp(struct ib_qp *ibqp, 
 		return -EINVAL;
 	}
 
-	mailbox = kmalloc(sizeof (*qp_param) + MTHCA_CMD_MAILBOX_EXTRA, GFP_KERNEL);
-	if (!mailbox)
-		return -ENOMEM;
-	qp_param = MAILBOX_ALIGN(mailbox);
+	mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL);
+	if (IS_ERR(mailbox))
+		return PTR_ERR(mailbox);
+	qp_param = mailbox->buf;
 	qp_context = &qp_param->context;
 	memset(qp_param, 0, sizeof *qp_param);
 
@@ -652,7 +692,11 @@ int mthca_modify_qp(struct ib_qp *ibqp, 
 
 	/* leave arbel_sched_queue as 0 */
 
-	qp_context->usr_page   = cpu_to_be32(dev->driver_uar.index);
+	if (qp->ibqp.uobject)
+		qp_context->usr_page =
+			cpu_to_be32(to_mucontext(qp->ibqp.uobject->context)->uar.index);
+	else
+		qp_context->usr_page = cpu_to_be32(dev->driver_uar.index);
 	qp_context->local_qpn  = cpu_to_be32(qp->qpn);
 	if (attr_mask & IB_QP_DEST_QPN) {
 		qp_context->remote_qpn = cpu_to_be32(attr->dest_qp_num);
@@ -683,7 +727,7 @@ int mthca_modify_qp(struct ib_qp *ibqp, 
 	if (attr_mask & IB_QP_AV) {
 		qp_context->pri_path.g_mylmc     = attr->ah_attr.src_path_bits & 0x7f;
 		qp_context->pri_path.rlid        = cpu_to_be16(attr->ah_attr.dlid);
-		qp_context->pri_path.static_rate = (!!attr->ah_attr.static_rate) << 3;
+		qp_context->pri_path.static_rate = !!attr->ah_attr.static_rate;
 		if (attr->ah_attr.ah_flags & IB_AH_GRH) {
 			qp_context->pri_path.g_mylmc |= 1 << 7;
 			qp_context->pri_path.mgid_index = attr->ah_attr.grh.sgid_index;
@@ -724,9 +768,9 @@ int mthca_modify_qp(struct ib_qp *ibqp, 
 		qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RETRY_COUNT);
 	}
 
-	if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC) {
-		qp_context->params1 |= cpu_to_be32(min(attr->max_dest_rd_atomic ?
-						       ffs(attr->max_dest_rd_atomic) - 1 : 0,
+	if (attr_mask & IB_QP_MAX_QP_RD_ATOMIC) {
+		qp_context->params1 |= cpu_to_be32(min(attr->max_rd_atomic ?
+						       ffs(attr->max_rd_atomic) - 1 : 0,
 						       7) << 21);
 		qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_SRA_MAX);
 	}
@@ -764,10 +808,10 @@ int mthca_modify_qp(struct ib_qp *ibqp, 
 		qp->atomic_rd_en = attr->qp_access_flags;
 	}
 
-	if (attr_mask & IB_QP_MAX_QP_RD_ATOMIC) {
+	if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC) {
 		u8 rra_max;
 
-		if (qp->resp_depth && !attr->max_rd_atomic) {
+		if (qp->resp_depth && !attr->max_dest_rd_atomic) {
 			/*
 			 * Lowering our responder resources to zero.
 			 * Turn off RDMA/atomics as responder.
@@ -778,7 +822,7 @@ int mthca_modify_qp(struct ib_qp *ibqp, 
 								MTHCA_QP_OPTPAR_RAE);
 		}
 
-		if (!qp->resp_depth && attr->max_rd_atomic) {
+		if (!qp->resp_depth && attr->max_dest_rd_atomic) {
 			/*
 			 * Increasing our responder resources from
 			 * zero.  Turn on RDMA/atomics as appropriate.
@@ -799,7 +843,7 @@ int mthca_modify_qp(struct ib_qp *ibqp, 
 		}
 
 		for (rra_max = 0;
-		     1 << rra_max < attr->max_rd_atomic &&
+		     1 << rra_max < attr->max_dest_rd_atomic &&
 			     rra_max < dev->qp_table.rdb_shift;
 		     ++rra_max)
 			; /* nothing */
@@ -807,7 +851,7 @@ int mthca_modify_qp(struct ib_qp *ibqp, 
 		qp_context->params2      |= cpu_to_be32(rra_max << 21);
 		qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RRA_MAX);
 
-		qp->resp_depth = attr->max_rd_atomic;
+		qp->resp_depth = attr->max_dest_rd_atomic;
 	}
 
 	qp_context->params2 |= cpu_to_be32(MTHCA_QP_BIT_RSC);
@@ -835,7 +879,7 @@ int mthca_modify_qp(struct ib_qp *ibqp, 
 	}
 
 	err = mthca_MODIFY_QP(dev, state_table[cur_state][new_state].trans,
-			      qp->qpn, 0, qp_param, 0, &status);
+			      qp->qpn, 0, mailbox, 0, &status);
 	if (status) {
 		mthca_warn(dev, "modify QP %d returned status %02x.\n",
 			   state_table[cur_state][new_state].trans, status);
@@ -845,7 +889,7 @@ int mthca_modify_qp(struct ib_qp *ibqp, 
 	if (!err)
 		qp->state = new_state;
 
-	kfree(mailbox);
+	mthca_free_mailbox(dev, mailbox);
 
 	if (is_sqp(dev, qp))
 		store_attrs(to_msqp(qp), attr, attr_mask);
@@ -917,6 +961,15 @@ static int mthca_alloc_wqe_buf(struct mt
 
 	qp->send_wqe_offset = ALIGN(qp->rq.max << qp->rq.wqe_shift,
 				    1 << qp->sq.wqe_shift);
+
+	/*
+	 * If this is a userspace QP, we don't actually have to
+	 * allocate anything.  All we need is to calculate the WQE
+	 * sizes and the send_wqe_offset, so we're done now.
+	 */
+	if (pd->ibpd.uobject)
+		return 0;
+
 	size = PAGE_ALIGN(qp->send_wqe_offset +
 			  (qp->sq.max << qp->sq.wqe_shift));
 
@@ -934,7 +987,8 @@ static int mthca_alloc_wqe_buf(struct mt
 			mthca_dbg(dev, "Creating direct QP of size %d (shift %d)\n",
 				  size, shift);
 
-		qp->queue.direct.buf = pci_alloc_consistent(dev->pdev, size, &t);
+		qp->queue.direct.buf = dma_alloc_coherent(&dev->pdev->dev, size,
+							  &t, GFP_KERNEL);
 		if (!qp->queue.direct.buf)
 			goto err_out;
 
@@ -973,7 +1027,8 @@ static int mthca_alloc_wqe_buf(struct mt
 
 		for (i = 0; i < npages; ++i) {
 			qp->queue.page_list[i].buf =
-				pci_alloc_consistent(dev->pdev, PAGE_SIZE, &t);
+				dma_alloc_coherent(&dev->pdev->dev, PAGE_SIZE,
+						   &t, GFP_KERNEL);
 			if (!qp->queue.page_list[i].buf)
 				goto err_out_free;
 
@@ -996,16 +1051,15 @@ static int mthca_alloc_wqe_buf(struct mt
 
  err_out_free:
 	if (qp->is_direct) {
-		pci_free_consistent(dev->pdev, size,
-				    qp->queue.direct.buf,
-				    pci_unmap_addr(&qp->queue.direct, mapping));
+		dma_free_coherent(&dev->pdev->dev, size, qp->queue.direct.buf,
+				  pci_unmap_addr(&qp->queue.direct, mapping));
 	} else
 		for (i = 0; i < npages; ++i) {
 			if (qp->queue.page_list[i].buf)
-				pci_free_consistent(dev->pdev, PAGE_SIZE,
-						    qp->queue.page_list[i].buf,
-						    pci_unmap_addr(&qp->queue.page_list[i],
-								   mapping));
+				dma_free_coherent(&dev->pdev->dev, PAGE_SIZE,
+						  qp->queue.page_list[i].buf,
+						  pci_unmap_addr(&qp->queue.page_list[i],
+								 mapping));
 
 		}
 
@@ -1015,10 +1069,32 @@ static int mthca_alloc_wqe_buf(struct mt
 	return err;
 }
 
-static int mthca_alloc_memfree(struct mthca_dev *dev,
+static void mthca_free_wqe_buf(struct mthca_dev *dev,
 			       struct mthca_qp *qp)
 {
-	int ret = 0;
+	int i;
+	int size = PAGE_ALIGN(qp->send_wqe_offset +
+			      (qp->sq.max << qp->sq.wqe_shift));
+
+	if (qp->is_direct) {
+		dma_free_coherent(&dev->pdev->dev, size, qp->queue.direct.buf,
+				  pci_unmap_addr(&qp->queue.direct, mapping));
+	} else {
+		for (i = 0; i < size / PAGE_SIZE; ++i) {
+			dma_free_coherent(&dev->pdev->dev, PAGE_SIZE,
+					  qp->queue.page_list[i].buf,
+					  pci_unmap_addr(&qp->queue.page_list[i],
+							 mapping));
+		}
+	}
+
+	kfree(qp->wrid);
+}
+
+static int mthca_map_memfree(struct mthca_dev *dev,
+			     struct mthca_qp *qp)
+{
+	int ret;
 
 	if (mthca_is_memfree(dev)) {
 		ret = mthca_table_get(dev, dev->qp_table.qp_table, qp->qpn);
@@ -1029,35 +1105,15 @@ static int mthca_alloc_memfree(struct mt
 		if (ret)
 			goto err_qpc;
 
-		ret = mthca_table_get(dev, dev->qp_table.rdb_table,
-				      qp->qpn << dev->qp_table.rdb_shift);
-		if (ret)
-			goto err_eqpc;
-
-		qp->rq.db_index = mthca_alloc_db(dev, MTHCA_DB_TYPE_RQ,
-						 qp->qpn, &qp->rq.db);
-		if (qp->rq.db_index < 0) {
-			ret = -ENOMEM;
-			goto err_rdb;
-		}
+ 		ret = mthca_table_get(dev, dev->qp_table.rdb_table,
+ 				      qp->qpn << dev->qp_table.rdb_shift);
+ 		if (ret)
+ 			goto err_eqpc;
 
-		qp->sq.db_index = mthca_alloc_db(dev, MTHCA_DB_TYPE_SQ,
-						 qp->qpn, &qp->sq.db);
-		if (qp->sq.db_index < 0) {
-			ret = -ENOMEM;
-			goto err_rq_db;
-		}
 	}
 
 	return 0;
 
-err_rq_db:
-	mthca_free_db(dev, MTHCA_DB_TYPE_RQ, qp->rq.db_index);
-
-err_rdb:
-	mthca_table_put(dev, dev->qp_table.rdb_table,
-			qp->qpn << dev->qp_table.rdb_shift);
-
 err_eqpc:
 	mthca_table_put(dev, dev->qp_table.eqp_table, qp->qpn);
 
@@ -1067,16 +1123,41 @@ err_qpc:
 	return ret;
 }
 
+static void mthca_unmap_memfree(struct mthca_dev *dev,
+				struct mthca_qp *qp)
+{
+	mthca_table_put(dev, dev->qp_table.rdb_table,
+			qp->qpn << dev->qp_table.rdb_shift);
+	mthca_table_put(dev, dev->qp_table.eqp_table, qp->qpn);
+	mthca_table_put(dev, dev->qp_table.qp_table, qp->qpn);
+}
+
+static int mthca_alloc_memfree(struct mthca_dev *dev,
+			       struct mthca_qp *qp)
+{
+	int ret = 0;
+
+	if (mthca_is_memfree(dev)) {
+		qp->rq.db_index = mthca_alloc_db(dev, MTHCA_DB_TYPE_RQ,
+						 qp->qpn, &qp->rq.db);
+		if (qp->rq.db_index < 0)
+			return ret;
+
+		qp->sq.db_index = mthca_alloc_db(dev, MTHCA_DB_TYPE_SQ,
+						 qp->qpn, &qp->sq.db);
+		if (qp->sq.db_index < 0)
+			mthca_free_db(dev, MTHCA_DB_TYPE_RQ, qp->rq.db_index);
+	}
+
+	return ret;
+}
+
 static void mthca_free_memfree(struct mthca_dev *dev,
 			       struct mthca_qp *qp)
 {
 	if (mthca_is_memfree(dev)) {
 		mthca_free_db(dev, MTHCA_DB_TYPE_SQ, qp->sq.db_index);
 		mthca_free_db(dev, MTHCA_DB_TYPE_RQ, qp->rq.db_index);
-		mthca_table_put(dev, dev->qp_table.rdb_table,
-				qp->qpn << dev->qp_table.rdb_shift);
-		mthca_table_put(dev, dev->qp_table.eqp_table, qp->qpn);
-		mthca_table_put(dev, dev->qp_table.qp_table, qp->qpn);
 	}
 }
 
@@ -1108,13 +1189,28 @@ static int mthca_alloc_qp_common(struct 
 	mthca_wq_init(&qp->sq);
 	mthca_wq_init(&qp->rq);
 
-	ret = mthca_alloc_memfree(dev, qp);
+	ret = mthca_map_memfree(dev, qp);
 	if (ret)
 		return ret;
 
 	ret = mthca_alloc_wqe_buf(dev, pd, qp);
 	if (ret) {
-		mthca_free_memfree(dev, qp);
+		mthca_unmap_memfree(dev, qp);
+		return ret;
+	}
+
+	/*
+	 * If this is a userspace QP, we're done now.  The doorbells
+	 * will be allocated and buffers will be initialized in
+	 * userspace.
+	 */
+	if (pd->ibpd.uobject)
+		return 0;
+
+	ret = mthca_alloc_memfree(dev, qp);
+	if (ret) {
+		mthca_free_wqe_buf(dev, qp);
+		mthca_unmap_memfree(dev, qp);
 		return ret;
 	}
 
@@ -1147,22 +1243,39 @@ static int mthca_alloc_qp_common(struct 
 	return 0;
 }
 
-static void mthca_align_qp_size(struct mthca_dev *dev, struct mthca_qp *qp)
+static int mthca_set_qp_size(struct mthca_dev *dev, struct ib_qp_cap *cap,
+			     struct mthca_qp *qp)
 {
-	int i;
-
-	if (!mthca_is_memfree(dev))
-		return;
+	/* Sanity check QP size before proceeding */
+	if (cap->max_send_wr  > 65536 || cap->max_recv_wr  > 65536 ||
+	    cap->max_send_sge > 64    || cap->max_recv_sge > 64)
+		return -EINVAL;
 
-	for (i = 0; 1 << i < qp->rq.max; ++i)
-		; /* nothing */
+	if (mthca_is_memfree(dev)) {
+		qp->rq.max = cap->max_recv_wr ?
+			roundup_pow_of_two(cap->max_recv_wr) : 0;
+		qp->sq.max = cap->max_send_wr ?
+			roundup_pow_of_two(cap->max_send_wr) : 0;
+	} else {
+		qp->rq.max = cap->max_recv_wr;
+		qp->sq.max = cap->max_send_wr;
+	}
 
-	qp->rq.max = 1 << i;
+	qp->rq.max_gs = cap->max_recv_sge;
+	qp->sq.max_gs = max_t(int, cap->max_send_sge,
+			      ALIGN(cap->max_inline_data + MTHCA_INLINE_HEADER_SIZE,
+				    MTHCA_INLINE_CHUNK_SIZE) /
+			      sizeof (struct mthca_data_seg));
 
-	for (i = 0; 1 << i < qp->sq.max; ++i)
-		; /* nothing */
+	/*
+	 * For MLX transport we need 2 extra S/G entries:
+	 * one for the header and one for the checksum at the end
+	 */
+	if ((qp->transport == MLX && qp->sq.max_gs + 2 > dev->limits.max_sg) ||
+	    qp->sq.max_gs > dev->limits.max_sg || qp->rq.max_gs > dev->limits.max_sg)
+		return -EINVAL;
 
-	qp->sq.max = 1 << i;
+	return 0;
 }
 
 int mthca_alloc_qp(struct mthca_dev *dev,
@@ -1171,11 +1284,14 @@ int mthca_alloc_qp(struct mthca_dev *dev
 		   struct mthca_cq *recv_cq,
 		   enum ib_qp_type type,
 		   enum ib_sig_type send_policy,
+		   struct ib_qp_cap *cap,
 		   struct mthca_qp *qp)
 {
 	int err;
 
-	mthca_align_qp_size(dev, qp);
+	err = mthca_set_qp_size(dev, cap, qp);
+	if (err)
+		return err;
 
 	switch (type) {
 	case IB_QPT_RC: qp->transport = RC; break;
@@ -1208,14 +1324,17 @@ int mthca_alloc_sqp(struct mthca_dev *de
 		    struct mthca_cq *send_cq,
 		    struct mthca_cq *recv_cq,
 		    enum ib_sig_type send_policy,
+		    struct ib_qp_cap *cap,
 		    int qpn,
 		    int port,
 		    struct mthca_sqp *sqp)
 {
-	int err = 0;
 	u32 mqpn = qpn * 2 + dev->qp_table.sqp_start + port - 1;
+	int err;
 
-	mthca_align_qp_size(dev, &sqp->qp);
+	err = mthca_set_qp_size(dev, cap, &sqp->qp);
+	if (err)
+		return err;
 
 	sqp->header_buf_size = sqp->qp.sq.max * MTHCA_UD_HEADER_SIZE;
 	sqp->header_buf = dma_alloc_coherent(&dev->pdev->dev, sqp->header_buf_size,
@@ -1274,8 +1393,6 @@ void mthca_free_qp(struct mthca_dev *dev
 		   struct mthca_qp *qp)
 {
 	u8 status;
-	int size;
-	int i;
 	struct mthca_cq *send_cq;
 	struct mthca_cq *recv_cq;
 
@@ -1305,31 +1422,22 @@ void mthca_free_qp(struct mthca_dev *dev
 	if (qp->state != IB_QPS_RESET)
 		mthca_MODIFY_QP(dev, MTHCA_TRANS_ANY2RST, qp->qpn, 0, NULL, 0, &status);
 
-	mthca_cq_clean(dev, to_mcq(qp->ibqp.send_cq)->cqn, qp->qpn);
-	if (qp->ibqp.send_cq != qp->ibqp.recv_cq)
-		mthca_cq_clean(dev, to_mcq(qp->ibqp.recv_cq)->cqn, qp->qpn);
-
-	mthca_free_mr(dev, &qp->mr);
-
-	size = PAGE_ALIGN(qp->send_wqe_offset +
-			  (qp->sq.max << qp->sq.wqe_shift));
+	/*
+	 * If this is a userspace QP, the buffers, MR, CQs and so on
+	 * will be cleaned up in userspace, so all we have to do is
+	 * unref the mem-free tables and free the QPN in our table.
+	 */
+	if (!qp->ibqp.uobject) {
+		mthca_cq_clean(dev, to_mcq(qp->ibqp.send_cq)->cqn, qp->qpn);
+		if (qp->ibqp.send_cq != qp->ibqp.recv_cq)
+			mthca_cq_clean(dev, to_mcq(qp->ibqp.recv_cq)->cqn, qp->qpn);
 
-	if (qp->is_direct) {
-		pci_free_consistent(dev->pdev, size,
-				    qp->queue.direct.buf,
-				    pci_unmap_addr(&qp->queue.direct, mapping));
-	} else {
-		for (i = 0; i < size / PAGE_SIZE; ++i) {
-			pci_free_consistent(dev->pdev, PAGE_SIZE,
-					    qp->queue.page_list[i].buf,
-					    pci_unmap_addr(&qp->queue.page_list[i],
-							   mapping));
-		}
+		mthca_free_mr(dev, &qp->mr);
+		mthca_free_memfree(dev, qp);
+		mthca_free_wqe_buf(dev, qp);
 	}
 
-	kfree(qp->wrid);
-
-	mthca_free_memfree(dev, qp);
+	mthca_unmap_memfree(dev, qp);
 
 	if (is_sqp(dev, qp)) {
 		atomic_dec(&(to_mpd(qp->ibqp.pd)->sqp_count));
@@ -1529,6 +1637,26 @@ int mthca_tavor_post_send(struct ib_qp *
 
 			break;
 
+		case UC:
+			switch (wr->opcode) {
+			case IB_WR_RDMA_WRITE:
+			case IB_WR_RDMA_WRITE_WITH_IMM:
+				((struct mthca_raddr_seg *) wqe)->raddr =
+					cpu_to_be64(wr->wr.rdma.remote_addr);
+				((struct mthca_raddr_seg *) wqe)->rkey =
+					cpu_to_be32(wr->wr.rdma.rkey);
+				((struct mthca_raddr_seg *) wqe)->reserved = 0;
+				wqe += sizeof (struct mthca_raddr_seg);
+				size += sizeof (struct mthca_raddr_seg) / 16;
+				break;
+
+			default:
+				/* No extra segments required for sends */
+				break;
+			}
+
+			break;
+
 		case UD:
 			((struct mthca_tavor_ud_seg *) wqe)->lkey =
 				cpu_to_be32(to_mah(wr->wr.ud.ah)->key);
@@ -1814,9 +1942,29 @@ int mthca_arbel_post_send(struct ib_qp *
 					sizeof (struct mthca_atomic_seg);
 				break;
 
+			case IB_WR_RDMA_READ:
+			case IB_WR_RDMA_WRITE:
+			case IB_WR_RDMA_WRITE_WITH_IMM:
+				((struct mthca_raddr_seg *) wqe)->raddr =
+					cpu_to_be64(wr->wr.rdma.remote_addr);
+				((struct mthca_raddr_seg *) wqe)->rkey =
+					cpu_to_be32(wr->wr.rdma.rkey);
+				((struct mthca_raddr_seg *) wqe)->reserved = 0;
+				wqe += sizeof (struct mthca_raddr_seg);
+				size += sizeof (struct mthca_raddr_seg) / 16;
+				break;
+
+			default:
+				/* No extra segments required for sends */
+				break;
+			}
+
+			break;
+
+		case UC:
+			switch (wr->opcode) {
 			case IB_WR_RDMA_WRITE:
 			case IB_WR_RDMA_WRITE_WITH_IMM:
-			case IB_WR_RDMA_READ:
 				((struct mthca_raddr_seg *) wqe)->raddr =
 					cpu_to_be64(wr->wr.rdma.remote_addr);
 				((struct mthca_raddr_seg *) wqe)->rkey =
diff --git a/drivers/infiniband/hw/mthca/mthca_user.h b/drivers/infiniband/hw/mthca/mthca_user.h
new file mode 100644
--- /dev/null
+++ b/drivers/infiniband/hw/mthca/mthca_user.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2005 Topspin Communications.  All rights reserved.
+ * Copyright (c) 2005 Cisco Systems.  All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * 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 THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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.
+ *
+ */
+
+#ifndef MTHCA_USER_H
+#define MTHCA_USER_H
+
+#include <linux/types.h>
+
+/*
+ * Make sure that all structs defined in this file remain laid out so
+ * that they pack the same way on 32-bit and 64-bit architectures (to
+ * avoid incompatibility between 32-bit userspace and 64-bit kernels).
+ * In particular do not use pointer types -- pass pointers in __u64
+ * instead.
+ */
+
+struct mthca_alloc_ucontext_resp {
+	__u32 qp_tab_size;
+	__u32 uarc_size;
+};
+
+struct mthca_alloc_pd_resp {
+	__u32 pdn;
+	__u32 reserved;
+};
+
+struct mthca_create_cq {
+	__u32 lkey;
+	__u32 pdn;
+	__u64 arm_db_page;
+	__u64 set_db_page;
+	__u32 arm_db_index;
+	__u32 set_db_index;
+};
+
+struct mthca_create_cq_resp {
+	__u32 cqn;
+	__u32 reserved;
+};
+
+struct mthca_create_qp {
+	__u32 lkey;
+	__u32 reserved;
+	__u64 sq_db_page;
+	__u64 rq_db_page;
+	__u32 sq_db_index;
+	__u32 rq_db_index;
+};
+
+#endif /* MTHCA_USER_H */
diff --git a/drivers/infiniband/include/ib_cm.h b/drivers/infiniband/include/ib_cm.h
new file mode 100644
--- /dev/null
+++ b/drivers/infiniband/include/ib_cm.h
@@ -0,0 +1,569 @@
+/*
+ * Copyright (c) 2004 Intel Corporation.  All rights reserved.
+ * Copyright (c) 2004 Topspin Corporation.  All rights reserved.
+ * Copyright (c) 2004 Voltaire Corporation.  All rights reserved.
+ * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * 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 THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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.
+ *
+ * $Id: ib_cm.h 2730 2005-06-28 16:43:03Z sean.hefty $
+ */
+#if !defined(IB_CM_H)
+#define IB_CM_H
+
+#include <ib_mad.h>
+#include <ib_sa.h>
+
+enum ib_cm_state {
+	IB_CM_IDLE,
+	IB_CM_LISTEN,
+	IB_CM_REQ_SENT,
+	IB_CM_REQ_RCVD,
+	IB_CM_MRA_REQ_SENT,
+	IB_CM_MRA_REQ_RCVD,
+	IB_CM_REP_SENT,
+	IB_CM_REP_RCVD,
+	IB_CM_MRA_REP_SENT,
+	IB_CM_MRA_REP_RCVD,
+	IB_CM_ESTABLISHED,
+	IB_CM_DREQ_SENT,
+	IB_CM_DREQ_RCVD,
+	IB_CM_TIMEWAIT,
+	IB_CM_SIDR_REQ_SENT,
+	IB_CM_SIDR_REQ_RCVD
+};
+
+enum ib_cm_lap_state {
+	IB_CM_LAP_IDLE,
+	IB_CM_LAP_SENT,
+	IB_CM_LAP_RCVD,
+	IB_CM_MRA_LAP_SENT,
+	IB_CM_MRA_LAP_RCVD,
+};
+
+enum ib_cm_event_type {
+	IB_CM_REQ_ERROR,
+	IB_CM_REQ_RECEIVED,
+	IB_CM_REP_ERROR,
+	IB_CM_REP_RECEIVED,
+	IB_CM_RTU_RECEIVED,
+	IB_CM_USER_ESTABLISHED,
+	IB_CM_DREQ_ERROR,
+	IB_CM_DREQ_RECEIVED,
+	IB_CM_DREP_RECEIVED,
+	IB_CM_TIMEWAIT_EXIT,
+	IB_CM_MRA_RECEIVED,
+	IB_CM_REJ_RECEIVED,
+	IB_CM_LAP_ERROR,
+	IB_CM_LAP_RECEIVED,
+	IB_CM_APR_RECEIVED,
+	IB_CM_SIDR_REQ_ERROR,
+	IB_CM_SIDR_REQ_RECEIVED,
+	IB_CM_SIDR_REP_RECEIVED
+};
+
+enum ib_cm_data_size {
+	IB_CM_REQ_PRIVATE_DATA_SIZE	 = 92,
+	IB_CM_MRA_PRIVATE_DATA_SIZE	 = 222,
+	IB_CM_REJ_PRIVATE_DATA_SIZE	 = 148,
+	IB_CM_REP_PRIVATE_DATA_SIZE	 = 196,
+	IB_CM_RTU_PRIVATE_DATA_SIZE	 = 224,
+	IB_CM_DREQ_PRIVATE_DATA_SIZE	 = 220,
+	IB_CM_DREP_PRIVATE_DATA_SIZE	 = 224,
+	IB_CM_REJ_ARI_LENGTH		 = 72,
+	IB_CM_LAP_PRIVATE_DATA_SIZE	 = 168,
+	IB_CM_APR_PRIVATE_DATA_SIZE	 = 148,
+	IB_CM_APR_INFO_LENGTH		 = 72,
+	IB_CM_SIDR_REQ_PRIVATE_DATA_SIZE = 216,
+	IB_CM_SIDR_REP_PRIVATE_DATA_SIZE = 136,
+	IB_CM_SIDR_REP_INFO_LENGTH	 = 72
+};
+
+struct ib_cm_id;
+
+struct ib_cm_req_event_param {
+	struct ib_cm_id		*listen_id;
+	struct ib_device	*device;
+	u8			port;
+
+	struct ib_sa_path_rec	*primary_path;
+	struct ib_sa_path_rec	*alternate_path;
+
+	u64			remote_ca_guid;
+	u32			remote_qkey;
+	u32			remote_qpn;
+	enum ib_qp_type		qp_type;
+
+	u32			starting_psn;
+	u8			responder_resources;
+	u8			initiator_depth;
+	unsigned int		local_cm_response_timeout:5;
+	unsigned int		flow_control:1;
+	unsigned int		remote_cm_response_timeout:5;
+	unsigned int		retry_count:3;
+	unsigned int		rnr_retry_count:3;
+	unsigned int		srq:1;
+};
+
+struct ib_cm_rep_event_param {
+	u64			remote_ca_guid;
+	u32			remote_qkey;
+	u32			remote_qpn;
+	u32			starting_psn;
+	u8			responder_resources;
+	u8			initiator_depth;
+	unsigned int		target_ack_delay:5;
+	unsigned int		failover_accepted:2;
+	unsigned int		flow_control:1;
+	unsigned int		rnr_retry_count:3;
+	unsigned int		srq:1;
+};
+
+enum ib_cm_rej_reason {
+	IB_CM_REJ_NO_QP				= __constant_htons(1),
+	IB_CM_REJ_NO_EEC			= __constant_htons(2),
+	IB_CM_REJ_NO_RESOURCES			= __constant_htons(3),
+	IB_CM_REJ_TIMEOUT			= __constant_htons(4),
+	IB_CM_REJ_UNSUPPORTED			= __constant_htons(5),
+	IB_CM_REJ_INVALID_COMM_ID		= __constant_htons(6),
+	IB_CM_REJ_INVALID_COMM_INSTANCE		= __constant_htons(7),
+	IB_CM_REJ_INVALID_SERVICE_ID		= __constant_htons(8),
+	IB_CM_REJ_INVALID_TRANSPORT_TYPE	= __constant_htons(9),
+	IB_CM_REJ_STALE_CONN			= __constant_htons(10),
+	IB_CM_REJ_RDC_NOT_EXIST			= __constant_htons(11),
+	IB_CM_REJ_INVALID_GID			= __constant_htons(12),
+	IB_CM_REJ_INVALID_LID			= __constant_htons(13),
+	IB_CM_REJ_INVALID_SL			= __constant_htons(14),
+	IB_CM_REJ_INVALID_TRAFFIC_CLASS		= __constant_htons(15),
+	IB_CM_REJ_INVALID_HOP_LIMIT		= __constant_htons(16),
+	IB_CM_REJ_INVALID_PACKET_RATE		= __constant_htons(17),
+	IB_CM_REJ_INVALID_ALT_GID		= __constant_htons(18),
+	IB_CM_REJ_INVALID_ALT_LID		= __constant_htons(19),
+	IB_CM_REJ_INVALID_ALT_SL		= __constant_htons(20),
+	IB_CM_REJ_INVALID_ALT_TRAFFIC_CLASS	= __constant_htons(21),
+	IB_CM_REJ_INVALID_ALT_HOP_LIMIT		= __constant_htons(22),
+	IB_CM_REJ_INVALID_ALT_PACKET_RATE	= __constant_htons(23),
+	IB_CM_REJ_PORT_CM_REDIRECT		= __constant_htons(24),
+	IB_CM_REJ_PORT_REDIRECT			= __constant_htons(25),
+	IB_CM_REJ_INVALID_MTU			= __constant_htons(26),
+	IB_CM_REJ_INSUFFICIENT_RESP_RESOURCES	= __constant_htons(27),
+	IB_CM_REJ_CONSUMER_DEFINED		= __constant_htons(28),
+	IB_CM_REJ_INVALID_RNR_RETRY		= __constant_htons(29),
+	IB_CM_REJ_DUPLICATE_LOCAL_COMM_ID	= __constant_htons(30),
+	IB_CM_REJ_INVALID_CLASS_VERSION		= __constant_htons(31),
+	IB_CM_REJ_INVALID_FLOW_LABEL		= __constant_htons(32),
+	IB_CM_REJ_INVALID_ALT_FLOW_LABEL	= __constant_htons(33)
+};
+
+struct ib_cm_rej_event_param {
+	enum ib_cm_rej_reason	reason;
+	void			*ari;
+	u8			ari_length;
+};
+
+struct ib_cm_mra_event_param {
+	u8	service_timeout;
+};
+
+struct ib_cm_lap_event_param {
+	struct ib_sa_path_rec	*alternate_path;
+};
+
+enum ib_cm_apr_status {
+	IB_CM_APR_SUCCESS,
+	IB_CM_APR_INVALID_COMM_ID,
+	IB_CM_APR_UNSUPPORTED,
+	IB_CM_APR_REJECT,
+	IB_CM_APR_REDIRECT,
+	IB_CM_APR_IS_CURRENT,
+	IB_CM_APR_INVALID_QPN_EECN,
+	IB_CM_APR_INVALID_LID,
+	IB_CM_APR_INVALID_GID,
+	IB_CM_APR_INVALID_FLOW_LABEL,
+	IB_CM_APR_INVALID_TCLASS,
+	IB_CM_APR_INVALID_HOP_LIMIT,
+	IB_CM_APR_INVALID_PACKET_RATE,
+	IB_CM_APR_INVALID_SL
+};
+
+struct ib_cm_apr_event_param {
+	enum ib_cm_apr_status	ap_status;
+	void			*apr_info;
+	u8			info_len;
+};
+
+struct ib_cm_sidr_req_event_param {
+	struct ib_cm_id		*listen_id;
+	struct ib_device	*device;
+	u8			port;
+
+	u16	pkey;
+};
+
+enum ib_cm_sidr_status {
+	IB_SIDR_SUCCESS,
+	IB_SIDR_UNSUPPORTED,
+	IB_SIDR_REJECT,
+	IB_SIDR_NO_QP,
+	IB_SIDR_REDIRECT,
+	IB_SIDR_UNSUPPORTED_VERSION
+};
+
+struct ib_cm_sidr_rep_event_param {
+	enum ib_cm_sidr_status	status;
+	u32			qkey;
+	u32			qpn;
+	void			*info;
+	u8			info_len;
+
+};
+
+struct ib_cm_event {
+	enum ib_cm_event_type	event;
+	union {
+		struct ib_cm_req_event_param	req_rcvd;
+		struct ib_cm_rep_event_param	rep_rcvd;
+		/* No data for RTU received events. */
+		struct ib_cm_rej_event_param	rej_rcvd;
+		struct ib_cm_mra_event_param	mra_rcvd;
+		struct ib_cm_lap_event_param	lap_rcvd;
+		struct ib_cm_apr_event_param	apr_rcvd;
+		/* No data for DREQ/DREP received events. */
+		struct ib_cm_sidr_req_event_param sidr_req_rcvd;
+		struct ib_cm_sidr_rep_event_param sidr_rep_rcvd;
+		enum ib_wc_status		send_status;
+	} param;
+
+	void			*private_data;
+};
+
+/**
+ * ib_cm_handler - User-defined callback to process communication events.
+ * @cm_id: Communication identifier associated with the reported event.
+ * @event: Information about the communication event.
+ *
+ * IB_CM_REQ_RECEIVED and IB_CM_SIDR_REQ_RECEIVED communication events
+ * generated as a result of listen requests result in the allocation of a
+ * new @cm_id.  The new @cm_id is returned to the user through this callback.
+ * Clients are responsible for destroying the new @cm_id.  For peer-to-peer
+ * IB_CM_REQ_RECEIVED and all other events, the returned @cm_id corresponds
+ * to a user's existing communication identifier.
+ *
+ * Users may not call ib_destroy_cm_id while in the context of this callback;
+ * however, returning a non-zero value instructs the communication manager to
+ * destroy the @cm_id after the callback completes.
+ */
+typedef int (*ib_cm_handler)(struct ib_cm_id *cm_id,
+			     struct ib_cm_event *event);
+
+struct ib_cm_id {
+	ib_cm_handler		cm_handler;
+	void			*context;
+	u64			service_id;
+	u64			service_mask;
+	enum ib_cm_state	state;		/* internal CM/debug use */
+	enum ib_cm_lap_state	lap_state;	/* internal CM/debug use */
+	u32			local_id;
+	u32			remote_id;
+};
+
+/**
+ * ib_create_cm_id - Allocate a communication identifier.
+ * @cm_handler: Callback invoked to notify the user of CM events.
+ * @context: User specified context associated with the communication
+ *   identifier.
+ *
+ * Communication identifiers are used to track connection states, service
+ * ID resolution requests, and listen requests.
+ */
+struct ib_cm_id *ib_create_cm_id(ib_cm_handler cm_handler,
+				 void *context);
+
+/**
+ * ib_destroy_cm_id - Destroy a connection identifier.
+ * @cm_id: Connection identifier to destroy.
+ *
+ * This call blocks until the connection identifier is destroyed.
+ */
+void ib_destroy_cm_id(struct ib_cm_id *cm_id);
+
+#define IB_SERVICE_ID_AGN_MASK	__constant_cpu_to_be64(0xFF00000000000000ULL)
+#define IB_CM_ASSIGN_SERVICE_ID __constant_cpu_to_be64(0x0200000000000000ULL)
+
+/**
+ * ib_cm_listen - Initiates listening on the specified service ID for
+ *   connection and service ID resolution requests.
+ * @cm_id: Connection identifier associated with the listen request.
+ * @service_id: Service identifier matched against incoming connection
+ *   and service ID resolution requests.  The service ID should be specified
+ *   network-byte order.  If set to IB_CM_ASSIGN_SERVICE_ID, the CM will
+ *   assign a service ID to the caller.
+ * @service_mask: Mask applied to service ID used to listen across a
+ *   range of service IDs.  If set to 0, the service ID is matched
+ *   exactly.  This parameter is ignored if %service_id is set to
+ *   IB_CM_ASSIGN_SERVICE_ID.
+ */
+int ib_cm_listen(struct ib_cm_id *cm_id,
+		 u64 service_id,
+		 u64 service_mask);
+
+struct ib_cm_req_param {
+	struct ib_sa_path_rec	*primary_path;
+	struct ib_sa_path_rec	*alternate_path;
+	u64			service_id;
+	u32			qp_num;
+	enum ib_qp_type		qp_type;
+	u32			starting_psn;
+	const void		*private_data;
+	u8			private_data_len;
+	u8			peer_to_peer;
+	u8			responder_resources;
+	u8			initiator_depth;
+	u8			remote_cm_response_timeout;
+	u8			flow_control;
+	u8			local_cm_response_timeout;
+	u8			retry_count;
+	u8			rnr_retry_count;
+	u8			max_cm_retries;
+	u8			srq;
+};
+
+/**
+ * ib_send_cm_req - Sends a connection request to the remote node.
+ * @cm_id: Connection identifier that will be associated with the
+ *   connection request.
+ * @param: Connection request information needed to establish the
+ *   connection.
+ */
+int ib_send_cm_req(struct ib_cm_id *cm_id,
+		   struct ib_cm_req_param *param);
+
+struct ib_cm_rep_param {
+	u32		qp_num;
+	u32		starting_psn;
+	const void	*private_data;
+	u8		private_data_len;
+	u8		responder_resources;
+	u8		initiator_depth;
+	u8		target_ack_delay;
+	u8		failover_accepted;
+	u8		flow_control;
+	u8		rnr_retry_count;
+	u8		srq;
+};
+
+/**
+ * ib_send_cm_rep - Sends a connection reply in response to a connection
+ *   request.
+ * @cm_id: Connection identifier that will be associated with the
+ *   connection request.
+ * @param: Connection reply information needed to establish the
+ *   connection.
+ */
+int ib_send_cm_rep(struct ib_cm_id *cm_id,
+		   struct ib_cm_rep_param *param);
+
+/**
+ * ib_send_cm_rtu - Sends a connection ready to use message in response
+ *   to a connection reply message.
+ * @cm_id: Connection identifier associated with the connection request.
+ * @private_data: Optional user-defined private data sent with the
+ *   ready to use message.
+ * @private_data_len: Size of the private data buffer, in bytes.
+ */
+int ib_send_cm_rtu(struct ib_cm_id *cm_id,
+		   const void *private_data,
+		   u8 private_data_len);
+
+/**
+ * ib_send_cm_dreq - Sends a disconnection request for an existing
+ *   connection.
+ * @cm_id: Connection identifier associated with the connection being
+ *   released.
+ * @private_data: Optional user-defined private data sent with the
+ *   disconnection request message.
+ * @private_data_len: Size of the private data buffer, in bytes.
+ */
+int ib_send_cm_dreq(struct ib_cm_id *cm_id,
+		    const void *private_data,
+		    u8 private_data_len);
+
+/**
+ * ib_send_cm_drep - Sends a disconnection reply to a disconnection request.
+ * @cm_id: Connection identifier associated with the connection being
+ *   released.
+ * @private_data: Optional user-defined private data sent with the
+ *   disconnection reply message.
+ * @private_data_len: Size of the private data buffer, in bytes.
+ *
+ * If the cm_id is in the correct state, the CM will transition the connection
+ * to the timewait state, even if an error occurs sending the DREP message.
+ */
+int ib_send_cm_drep(struct ib_cm_id *cm_id,
+		    const void *private_data,
+		    u8 private_data_len);
+
+/**
+ * ib_cm_establish - Forces a connection state to established.
+ * @cm_id: Connection identifier to transition to established.
+ *
+ * This routine should be invoked by users who receive messages on a
+ * connected QP before an RTU has been received.
+ */
+int ib_cm_establish(struct ib_cm_id *cm_id);
+
+/**
+ * ib_send_cm_rej - Sends a connection rejection message to the
+ *   remote node.
+ * @cm_id: Connection identifier associated with the connection being
+ *   rejected.
+ * @reason: Reason for the connection request rejection.
+ * @ari: Optional additional rejection information.
+ * @ari_length: Size of the additional rejection information, in bytes.
+ * @private_data: Optional user-defined private data sent with the
+ *   rejection message.
+ * @private_data_len: Size of the private data buffer, in bytes.
+ */
+int ib_send_cm_rej(struct ib_cm_id *cm_id,
+		   enum ib_cm_rej_reason reason,
+		   void *ari,
+		   u8 ari_length,
+		   const void *private_data,
+		   u8 private_data_len);
+
+/**
+ * ib_send_cm_mra - Sends a message receipt acknowledgement to a connection
+ *   message.
+ * @cm_id: Connection identifier associated with the connection message.
+ * @service_timeout: The maximum time required for the sender to reply to
+ *   to the connection message.
+ * @private_data: Optional user-defined private data sent with the
+ *   message receipt acknowledgement.
+ * @private_data_len: Size of the private data buffer, in bytes.
+ */
+int ib_send_cm_mra(struct ib_cm_id *cm_id,
+		   u8 service_timeout,
+		   const void *private_data,
+		   u8 private_data_len);
+
+/**
+ * ib_send_cm_lap - Sends a load alternate path request.
+ * @cm_id: Connection identifier associated with the load alternate path
+ *   message.
+ * @alternate_path: A path record that identifies the alternate path to
+ *   load.
+ * @private_data: Optional user-defined private data sent with the
+ *   load alternate path message.
+ * @private_data_len: Size of the private data buffer, in bytes.
+ */
+int ib_send_cm_lap(struct ib_cm_id *cm_id,
+		   struct ib_sa_path_rec *alternate_path,
+		   const void *private_data,
+		   u8 private_data_len);
+
+/**
+ * ib_cm_init_qp_attr - Initializes the QP attributes for use in transitioning
+ *   to a specified QP state.
+ * @cm_id: Communication identifier associated with the QP attributes to
+ *   initialize.
+ * @qp_attr: On input, specifies the desired QP state.  On output, the
+ *   mandatory and desired optional attributes will be set in order to
+ *   modify the QP to the specified state.
+ * @qp_attr_mask: The QP attribute mask that may be used to transition the
+ *   QP to the specified state.
+ *
+ * Users must set the @qp_attr->qp_state to the desired QP state.  This call
+ * will set all required attributes for the given transition, along with
+ * known optional attributes.  Users may override the attributes returned from
+ * this call before calling ib_modify_qp.
+ */
+int ib_cm_init_qp_attr(struct ib_cm_id *cm_id,
+		       struct ib_qp_attr *qp_attr,
+		       int *qp_attr_mask);
+
+/**
+ * ib_send_cm_apr - Sends an alternate path response message in response to
+ *   a load alternate path request.
+ * @cm_id: Connection identifier associated with the alternate path response.
+ * @status: Reply status sent with the alternate path response.
+ * @info: Optional additional information sent with the alternate path
+ *   response.
+ * @info_length: Size of the additional information, in bytes.
+ * @private_data: Optional user-defined private data sent with the
+ *   alternate path response message.
+ * @private_data_len: Size of the private data buffer, in bytes.
+ */
+int ib_send_cm_apr(struct ib_cm_id *cm_id,
+		   enum ib_cm_apr_status status,
+		   void *info,
+		   u8 info_length,
+		   const void *private_data,
+		   u8 private_data_len);
+
+struct ib_cm_sidr_req_param {
+	struct ib_sa_path_rec	*path;
+	u64			service_id;
+	int			timeout_ms;
+	const void		*private_data;
+	u8			private_data_len;
+	u8			max_cm_retries;
+	u16			pkey;
+};
+
+/**
+ * ib_send_cm_sidr_req - Sends a service ID resolution request to the
+ *   remote node.
+ * @cm_id: Communication identifier that will be associated with the
+ *   service ID resolution request.
+ * @param: Service ID resolution request information.
+ */
+int ib_send_cm_sidr_req(struct ib_cm_id *cm_id,
+			struct ib_cm_sidr_req_param *param);
+
+struct ib_cm_sidr_rep_param {
+	u32			qp_num;
+	u32			qkey;
+	enum ib_cm_sidr_status	status;
+	const void		*info;
+	u8			info_length;
+	const void		*private_data;
+	u8			private_data_len;
+};
+
+/**
+ * ib_send_cm_sidr_rep - Sends a service ID resolution request to the
+ *   remote node.
+ * @cm_id: Communication identifier associated with the received service ID
+ *   resolution request.
+ * @param: Service ID resolution reply information.
+ */
+int ib_send_cm_sidr_rep(struct ib_cm_id *cm_id,
+			struct ib_cm_sidr_rep_param *param);
+
+#endif /* IB_CM_H */
diff --git a/drivers/infiniband/include/ib_fmr_pool.h b/drivers/infiniband/include/ib_fmr_pool.h
--- a/drivers/infiniband/include/ib_fmr_pool.h
+++ b/drivers/infiniband/include/ib_fmr_pool.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2004 Topspin Corporation.  All rights reserved.
+ * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
@@ -29,7 +30,7 @@
  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  *
- * $Id: ib_fmr_pool.h 1349 2004-12-16 21:09:43Z roland $
+ * $Id: ib_fmr_pool.h 2730 2005-06-28 16:43:03Z sean.hefty $
  */
 
 #if !defined(IB_FMR_POOL_H)
@@ -78,7 +79,7 @@ struct ib_pool_fmr {
 struct ib_fmr_pool *ib_create_fmr_pool(struct ib_pd             *pd,
 				       struct ib_fmr_pool_param *params);
 
-int ib_destroy_fmr_pool(struct ib_fmr_pool *pool);
+void ib_destroy_fmr_pool(struct ib_fmr_pool *pool);
 
 int ib_flush_fmr_pool(struct ib_fmr_pool *pool);
 
diff --git a/drivers/infiniband/include/ib_mad.h b/drivers/infiniband/include/ib_mad.h
--- a/drivers/infiniband/include/ib_mad.h
+++ b/drivers/infiniband/include/ib_mad.h
@@ -33,12 +33,14 @@
  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  *
- * $Id: ib_mad.h 1389 2004-12-27 22:56:47Z roland $
+ * $Id: ib_mad.h 2775 2005-07-02 13:42:12Z halr $
  */
 
 #if !defined( IB_MAD_H )
 #define IB_MAD_H
 
+#include <linux/pci.h>
+
 #include <ib_verbs.h>
 
 /* Management base version */
@@ -56,6 +58,8 @@
 #define IB_MGMT_CLASS_VENDOR_RANGE2_START	0x30
 #define IB_MGMT_CLASS_VENDOR_RANGE2_END		0x4F
 
+#define	IB_OPENIB_OUI				(0x001405)
+
 /* Management methods */
 #define IB_MGMT_METHOD_GET			0x01
 #define IB_MGMT_METHOD_SET			0x02
@@ -70,18 +74,37 @@
 
 #define IB_MGMT_MAX_METHODS			128
 
+/* RMPP information */
+#define IB_MGMT_RMPP_VERSION			1
+
+#define IB_MGMT_RMPP_TYPE_DATA			1
+#define IB_MGMT_RMPP_TYPE_ACK			2
+#define IB_MGMT_RMPP_TYPE_STOP			3
+#define IB_MGMT_RMPP_TYPE_ABORT			4
+
+#define IB_MGMT_RMPP_FLAG_ACTIVE		1
+#define IB_MGMT_RMPP_FLAG_FIRST			(1<<1)
+#define IB_MGMT_RMPP_FLAG_LAST			(1<<2)
+
+#define IB_MGMT_RMPP_NO_RESPTIME		0x1F
+
+#define	IB_MGMT_RMPP_STATUS_SUCCESS		0
+#define	IB_MGMT_RMPP_STATUS_RESX		1
+#define	IB_MGMT_RMPP_STATUS_T2L			118
+#define	IB_MGMT_RMPP_STATUS_BAD_LEN		119
+#define	IB_MGMT_RMPP_STATUS_BAD_SEG		120
+#define	IB_MGMT_RMPP_STATUS_BADT		121
+#define	IB_MGMT_RMPP_STATUS_W2S			122
+#define	IB_MGMT_RMPP_STATUS_S2B			123
+#define	IB_MGMT_RMPP_STATUS_BAD_STATUS		124
+#define	IB_MGMT_RMPP_STATUS_UNV			125
+#define	IB_MGMT_RMPP_STATUS_TMR			126
+#define	IB_MGMT_RMPP_STATUS_UNSPEC		127
+
 #define IB_QP0		0
 #define IB_QP1		__constant_htonl(1)
 #define IB_QP1_QKEY	0x80010000
-
-struct ib_grh {
-	u32		version_tclass_flow;
-	u16		paylen;
-	u8		next_hdr;
-	u8		hop_limit;
-	union ib_gid	sgid;
-	union ib_gid	dgid;
-} __attribute__ ((packed));
+#define IB_QP_SET_QKEY	0x80000000
 
 struct ib_mad_hdr {
 	u8	base_version;
@@ -94,7 +117,7 @@ struct ib_mad_hdr {
 	u16	attr_id;
 	u16	resv;
 	u32	attr_mod;
-} __attribute__ ((packed));
+};
 
 struct ib_rmpp_hdr {
 	u8	rmpp_version;
@@ -103,17 +126,41 @@ struct ib_rmpp_hdr {
 	u8	rmpp_status;
 	u32	seg_num;
 	u32	paylen_newwin;
+};
+
+typedef u64 __bitwise ib_sa_comp_mask;
+
+#define IB_SA_COMP_MASK(n) ((__force ib_sa_comp_mask) cpu_to_be64(1ull << n))
+
+/*
+ * ib_sa_hdr and ib_sa_mad structures must be packed because they have
+ * 64-bit fields that are only 32-bit aligned. 64-bit architectures will
+ * lay them out wrong otherwise.  (And unfortunately they are sent on
+ * the wire so we can't change the layout)
+ */
+struct ib_sa_hdr {
+	u64			sm_key;
+	u16			attr_offset;
+	u16			reserved;
+	ib_sa_comp_mask		comp_mask;
 } __attribute__ ((packed));
 
 struct ib_mad {
 	struct ib_mad_hdr	mad_hdr;
 	u8			data[232];
-} __attribute__ ((packed));
+};
 
 struct ib_rmpp_mad {
 	struct ib_mad_hdr	mad_hdr;
 	struct ib_rmpp_hdr	rmpp_hdr;
 	u8			data[220];
+};
+
+struct ib_sa_mad {
+	struct ib_mad_hdr	mad_hdr;
+	struct ib_rmpp_hdr	rmpp_hdr;
+	struct ib_sa_hdr	sa_hdr;
+	u8			data[200];
 } __attribute__ ((packed));
 
 struct ib_vendor_mad {
@@ -122,7 +169,70 @@ struct ib_vendor_mad {
 	u8			reserved;
 	u8			oui[3];
 	u8			data[216];
-} __attribute__ ((packed));
+};
+
+/**
+ * ib_mad_send_buf - MAD data buffer and work request for sends.
+ * @mad: References an allocated MAD data buffer.  The size of the data
+ *   buffer is specified in the @send_wr.length field.
+ * @mapping: DMA mapping information.
+ * @mad_agent: MAD agent that allocated the buffer.
+ * @context: User-controlled context fields.
+ * @send_wr: An initialized work request structure used when sending the MAD.
+ *   The wr_id field of the work request is initialized to reference this
+ *   data structure.
+ * @sge: A scatter-gather list referenced by the work request.
+ *
+ * Users are responsible for initializing the MAD buffer itself, with the
+ * exception of specifying the payload length field in any RMPP MAD.
+ */
+struct ib_mad_send_buf {
+	struct ib_mad		*mad;
+	DECLARE_PCI_UNMAP_ADDR(mapping)
+	struct ib_mad_agent	*mad_agent;
+	void			*context[2];
+	struct ib_send_wr	send_wr;
+	struct ib_sge		sge;
+};
+
+/**
+ * ib_get_rmpp_resptime - Returns the RMPP response time.
+ * @rmpp_hdr: An RMPP header.
+ */
+static inline u8 ib_get_rmpp_resptime(struct ib_rmpp_hdr *rmpp_hdr)
+{
+	return rmpp_hdr->rmpp_rtime_flags >> 3;
+}
+
+/**
+ * ib_get_rmpp_flags - Returns the RMPP flags.
+ * @rmpp_hdr: An RMPP header.
+ */
+static inline u8 ib_get_rmpp_flags(struct ib_rmpp_hdr *rmpp_hdr)
+{
+	return rmpp_hdr->rmpp_rtime_flags & 0x7;
+}
+
+/**
+ * ib_set_rmpp_resptime - Sets the response time in an RMPP header.
+ * @rmpp_hdr: An RMPP header.
+ * @rtime: The response time to set.
+ */
+static inline void ib_set_rmpp_resptime(struct ib_rmpp_hdr *rmpp_hdr, u8 rtime)
+{
+	rmpp_hdr->rmpp_rtime_flags = ib_get_rmpp_flags(rmpp_hdr) | (rtime << 3);
+}
+
+/**
+ * ib_set_rmpp_flags - Sets the flags in an RMPP header.
+ * @rmpp_hdr: An RMPP header.
+ * @flags: The flags to set.
+ */
+static inline void ib_set_rmpp_flags(struct ib_rmpp_hdr *rmpp_hdr, u8 flags)
+{
+	rmpp_hdr->rmpp_rtime_flags = (rmpp_hdr->rmpp_rtime_flags & 0xF1) |
+				     (flags & 0x7);
+}
 
 struct ib_mad_agent;
 struct ib_mad_send_wc;
@@ -168,6 +278,7 @@ typedef void (*ib_mad_recv_handler)(stru
  * ib_mad_agent - Used to track MAD registration with the access layer.
  * @device: Reference to device registration is on.
  * @qp: Reference to QP used for sending and receiving MADs.
+ * @mr: Memory region for system memory usable for DMA.
  * @recv_handler: Callback handler for a received MAD.
  * @send_handler: Callback handler for a sent MAD.
  * @snoop_handler: Callback handler for snooped sent MADs.
@@ -176,16 +287,19 @@ typedef void (*ib_mad_recv_handler)(stru
  *   Unsolicited MADs sent by this client will have the upper 32-bits
  *   of their TID set to this value.
  * @port_num: Port number on which QP is registered
+ * @rmpp_version: If set, indicates the RMPP version used by this agent.
  */
 struct ib_mad_agent {
 	struct ib_device	*device;
 	struct ib_qp		*qp;
+	struct ib_mr		*mr;
 	ib_mad_recv_handler	recv_handler;
 	ib_mad_send_handler	send_handler;
 	ib_mad_snoop_handler	snoop_handler;
 	void			*context;
 	u32			hi_tid;
 	u8			port_num;
+	u8			rmpp_version;
 };
 
 /**
@@ -219,6 +333,7 @@ struct ib_mad_recv_buf {
  * ib_mad_recv_wc - received MAD information.
  * @wc: Completion information for the received data.
  * @recv_buf: Specifies the location of the received data buffer(s).
+ * @rmpp_list: Specifies a list of RMPP reassembled received MAD buffers.
  * @mad_len: The length of the received MAD, without duplicated headers.
  *
  * For received response, the wr_id field of the wc is set to the wr_id
@@ -227,6 +342,7 @@ struct ib_mad_recv_buf {
 struct ib_mad_recv_wc {
 	struct ib_wc		*wc;
 	struct ib_mad_recv_buf	recv_buf;
+	struct list_head	rmpp_list;
 	int			mad_len;
 };
 
@@ -322,6 +438,16 @@ int ib_unregister_mad_agent(struct ib_ma
  * @bad_send_wr: Specifies the MAD on which an error was encountered.
  *
  * Sent MADs are not guaranteed to complete in the order that they were posted.
+ *
+ * If the MAD requires RMPP, the data buffer should contain a single copy
+ * of the common MAD, RMPP, and class specific headers, followed by the class
+ * defined data.  If the class defined data would not divide evenly into
+ * RMPP segments, then space must be allocated at the end of the referenced
+ * buffer for any required padding.  To indicate the amount of class defined
+ * data being transferred, the paylen_newwin field in the RMPP header should
+ * be set to the size of the class specific header plus the amount of class
+ * defined data being transferred.  The paylen_newwin field should be
+ * specified in network-byte order.
  */
 int ib_post_send_mad(struct ib_mad_agent *mad_agent,
 		     struct ib_send_wr *send_wr,
@@ -334,15 +460,13 @@ int ib_post_send_mad(struct ib_mad_agent
  *   referenced buffer should be at least the size of the mad_len specified
  *   by @mad_recv_wc.
  *
- * This call copies a chain of received RMPP MADs into a single data buffer,
+ * This call copies a chain of received MAD segments into a single data buffer,
  * removing duplicated headers.
  */
-void ib_coalesce_recv_mad(struct ib_mad_recv_wc *mad_recv_wc,
-			  void *buf);
+void ib_coalesce_recv_mad(struct ib_mad_recv_wc *mad_recv_wc, void *buf);
 
 /**
- * ib_free_recv_mad - Returns data buffers used to receive a MAD to the
- *   access layer.
+ * ib_free_recv_mad - Returns data buffers used to receive a MAD.
  * @mad_recv_wc: Work completion information for a received MAD.
  *
  * Clients receiving MADs through their ib_mad_recv_handler must call this
@@ -358,8 +482,18 @@ void ib_free_recv_mad(struct ib_mad_recv
  * MADs will be returned to the user through the corresponding
  * ib_mad_send_handler.
  */
-void ib_cancel_mad(struct ib_mad_agent *mad_agent,
-		   u64 wr_id);
+void ib_cancel_mad(struct ib_mad_agent *mad_agent, u64 wr_id);
+
+/**
+ * ib_modify_mad - Modifies an outstanding send MAD operation.
+ * @mad_agent: Specifies the registration associated with sent MAD.
+ * @wr_id: Indicates the work request identifier of the MAD to modify.
+ * @timeout_ms: New timeout value for sent MAD.
+ *
+ * This call will reset the timeout value for a sent MAD to the specified
+ * value.
+ */
+int ib_modify_mad(struct ib_mad_agent *mad_agent, u64 wr_id, u32 timeout_ms);
 
 /**
  * ib_redirect_mad_qp - Registers a QP for MAD services.
@@ -401,4 +535,43 @@ struct ib_mad_agent *ib_redirect_mad_qp(
 int ib_process_mad_wc(struct ib_mad_agent *mad_agent,
 		      struct ib_wc *wc);
 
+/**
+ * ib_create_send_mad - Allocate and initialize a data buffer and work request
+ *   for sending a MAD.
+ * @mad_agent: Specifies the registered MAD service to associate with the MAD.
+ * @remote_qpn: Specifies the QPN of the receiving node.
+ * @pkey_index: Specifies which PKey the MAD will be sent using.  This field
+ *   is valid only if the remote_qpn is QP 1.
+ * @ah: References the address handle used to transfer to the remote node.
+ * @rmpp_active: Indicates if the send will enable RMPP.
+ * @hdr_len: Indicates the size of the data header of the MAD.  This length
+ *   should include the common MAD header, RMPP header, plus any class
+ *   specific header.
+ * @data_len: Indicates the size of any user-transferred data.  The call will
+ *   automatically adjust the allocated buffer size to account for any
+ *   additional padding that may be necessary.
+ * @gfp_mask: GFP mask used for the memory allocation.
+ *
+ * This is a helper routine that may be used to allocate a MAD.  Users are
+ * not required to allocate outbound MADs using this call.  The returned
+ * MAD send buffer will reference a data buffer usable for sending a MAD, along
+ * with an initialized work request structure.  Users may modify the returned
+ * MAD data buffer or work request before posting the send.
+ *
+ * The returned data buffer will be cleared.  Users are responsible for
+ * initializing the common MAD and any class specific headers.  If @rmpp_active
+ * is set, the RMPP header will be initialized for sending.
+ */
+struct ib_mad_send_buf * ib_create_send_mad(struct ib_mad_agent *mad_agent,
+					    u32 remote_qpn, u16 pkey_index,
+					    struct ib_ah *ah, int rmpp_active,
+					    int hdr_len, int data_len,
+					    unsigned int __nocast gfp_mask);
+
+/**
+ * ib_free_send_mad - Returns data buffers used to send a MAD.
+ * @send_buf: Previously allocated send data buffer.
+ */
+void ib_free_send_mad(struct ib_mad_send_buf *send_buf);
+
 #endif /* IB_MAD_H */
diff --git a/drivers/infiniband/include/ib_sa.h b/drivers/infiniband/include/ib_sa.h
--- a/drivers/infiniband/include/ib_sa.h
+++ b/drivers/infiniband/include/ib_sa.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2004 Topspin Communications.  All rights reserved.
+ * Copyright (c) 2005 Voltaire, Inc.  All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
@@ -29,7 +30,7 @@
  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  *
- * $Id: ib_sa.h 1389 2004-12-27 22:56:47Z roland $
+ * $Id: ib_sa.h 2811 2005-07-06 18:11:43Z halr $
  */
 
 #ifndef IB_SA_H
@@ -41,9 +42,11 @@
 #include <ib_mad.h>
 
 enum {
-	IB_SA_CLASS_VERSION	= 2,	/* IB spec version 1.1/1.2 */
+	IB_SA_CLASS_VERSION		= 2,	/* IB spec version 1.1/1.2 */
 
-	IB_SA_METHOD_DELETE	= 0x15
+	IB_SA_METHOD_GET_TABLE		= 0x12,
+	IB_SA_METHOD_GET_TABLE_RESP	= 0x92,
+	IB_SA_METHOD_DELETE		= 0x15
 };
 
 enum ib_sa_selector {
@@ -87,10 +90,6 @@ static inline int ib_sa_rate_enum_to_int
 	}
 }
 
-typedef u64 __bitwise ib_sa_comp_mask;
-
-#define IB_SA_COMP_MASK(n)	((__force ib_sa_comp_mask) cpu_to_be64(1ull << n))
-
 /*
  * Structures for SA records are named "struct ib_sa_xxx_rec."  No
  * attempt is made to pack structures to match the physical layout of
@@ -195,6 +194,61 @@ struct ib_sa_mcmember_rec {
 	int          proxy_join;
 };
 
+/* Service Record Component Mask Sec 15.2.5.14 Ver 1.1	*/
+#define IB_SA_SERVICE_REC_SERVICE_ID			IB_SA_COMP_MASK( 0)
+#define IB_SA_SERVICE_REC_SERVICE_GID			IB_SA_COMP_MASK( 1)
+#define IB_SA_SERVICE_REC_SERVICE_PKEY			IB_SA_COMP_MASK( 2)
+/* reserved:								 3 */
+#define IB_SA_SERVICE_REC_SERVICE_LEASE			IB_SA_COMP_MASK( 4)
+#define IB_SA_SERVICE_REC_SERVICE_KEY			IB_SA_COMP_MASK( 5)
+#define IB_SA_SERVICE_REC_SERVICE_NAME			IB_SA_COMP_MASK( 6)
+#define IB_SA_SERVICE_REC_SERVICE_DATA8_0		IB_SA_COMP_MASK( 7)
+#define IB_SA_SERVICE_REC_SERVICE_DATA8_1		IB_SA_COMP_MASK( 8)
+#define IB_SA_SERVICE_REC_SERVICE_DATA8_2		IB_SA_COMP_MASK( 9)
+#define IB_SA_SERVICE_REC_SERVICE_DATA8_3		IB_SA_COMP_MASK(10)
+#define IB_SA_SERVICE_REC_SERVICE_DATA8_4		IB_SA_COMP_MASK(11)
+#define IB_SA_SERVICE_REC_SERVICE_DATA8_5		IB_SA_COMP_MASK(12)
+#define IB_SA_SERVICE_REC_SERVICE_DATA8_6		IB_SA_COMP_MASK(13)
+#define IB_SA_SERVICE_REC_SERVICE_DATA8_7		IB_SA_COMP_MASK(14)
+#define IB_SA_SERVICE_REC_SERVICE_DATA8_8		IB_SA_COMP_MASK(15)
+#define IB_SA_SERVICE_REC_SERVICE_DATA8_9		IB_SA_COMP_MASK(16)
+#define IB_SA_SERVICE_REC_SERVICE_DATA8_10		IB_SA_COMP_MASK(17)
+#define IB_SA_SERVICE_REC_SERVICE_DATA8_11		IB_SA_COMP_MASK(18)
+#define IB_SA_SERVICE_REC_SERVICE_DATA8_12		IB_SA_COMP_MASK(19)
+#define IB_SA_SERVICE_REC_SERVICE_DATA8_13		IB_SA_COMP_MASK(20)
+#define IB_SA_SERVICE_REC_SERVICE_DATA8_14		IB_SA_COMP_MASK(21)
+#define IB_SA_SERVICE_REC_SERVICE_DATA8_15		IB_SA_COMP_MASK(22)
+#define IB_SA_SERVICE_REC_SERVICE_DATA16_0		IB_SA_COMP_MASK(23)
+#define IB_SA_SERVICE_REC_SERVICE_DATA16_1		IB_SA_COMP_MASK(24)
+#define IB_SA_SERVICE_REC_SERVICE_DATA16_2		IB_SA_COMP_MASK(25)
+#define IB_SA_SERVICE_REC_SERVICE_DATA16_3		IB_SA_COMP_MASK(26)
+#define IB_SA_SERVICE_REC_SERVICE_DATA16_4		IB_SA_COMP_MASK(27)
+#define IB_SA_SERVICE_REC_SERVICE_DATA16_5		IB_SA_COMP_MASK(28)
+#define IB_SA_SERVICE_REC_SERVICE_DATA16_6		IB_SA_COMP_MASK(29)
+#define IB_SA_SERVICE_REC_SERVICE_DATA16_7		IB_SA_COMP_MASK(30)
+#define IB_SA_SERVICE_REC_SERVICE_DATA32_0		IB_SA_COMP_MASK(31)
+#define IB_SA_SERVICE_REC_SERVICE_DATA32_1		IB_SA_COMP_MASK(32)
+#define IB_SA_SERVICE_REC_SERVICE_DATA32_2		IB_SA_COMP_MASK(33)
+#define IB_SA_SERVICE_REC_SERVICE_DATA32_3		IB_SA_COMP_MASK(34)
+#define IB_SA_SERVICE_REC_SERVICE_DATA64_0		IB_SA_COMP_MASK(35)
+#define IB_SA_SERVICE_REC_SERVICE_DATA64_1		IB_SA_COMP_MASK(36)
+
+#define IB_DEFAULT_SERVICE_LEASE 	0xFFFFFFFF
+
+struct ib_sa_service_rec {
+	u64		id;
+	union ib_gid	gid;
+	u16 		pkey;
+	/* reserved */
+	u32		lease;
+	u8		key[16];
+	u8		name[64];
+	u8		data8[16];
+	u16		data16[8];
+	u32		data32[4];
+	u64		data64[2];
+};
+
 struct ib_sa_query;
 
 void ib_sa_cancel_query(int id, struct ib_sa_query *query);
@@ -202,7 +256,7 @@ void ib_sa_cancel_query(int id, struct i
 int ib_sa_path_rec_get(struct ib_device *device, u8 port_num,
 		       struct ib_sa_path_rec *rec,
 		       ib_sa_comp_mask comp_mask,
-		       int timeout_ms, int gfp_mask,
+		       int timeout_ms, unsigned int __nocast gfp_mask,
 		       void (*callback)(int status,
 					struct ib_sa_path_rec *resp,
 					void *context),
@@ -213,13 +267,24 @@ int ib_sa_mcmember_rec_query(struct ib_d
 			     u8 method,
 			     struct ib_sa_mcmember_rec *rec,
 			     ib_sa_comp_mask comp_mask,
-			     int timeout_ms, int gfp_mask,
+			     int timeout_ms, unsigned int __nocast gfp_mask,
 			     void (*callback)(int status,
 					      struct ib_sa_mcmember_rec *resp,
 					      void *context),
 			     void *context,
 			     struct ib_sa_query **query);
 
+int ib_sa_service_rec_query(struct ib_device *device, u8 port_num,
+			 u8 method,
+			 struct ib_sa_service_rec *rec,
+			 ib_sa_comp_mask comp_mask,
+			 int timeout_ms, unsigned int __nocast gfp_mask,
+			 void (*callback)(int status,
+					  struct ib_sa_service_rec *resp,
+					  void *context),
+			 void *context,
+			 struct ib_sa_query **sa_query);
+
 /**
  * ib_sa_mcmember_rec_set - Start an MCMember set query
  * @device:device to send query on
@@ -248,7 +313,7 @@ static inline int
 ib_sa_mcmember_rec_set(struct ib_device *device, u8 port_num,
 		       struct ib_sa_mcmember_rec *rec,
 		       ib_sa_comp_mask comp_mask,
-		       int timeout_ms, int gfp_mask,
+		       int timeout_ms, unsigned int __nocast gfp_mask,
 		       void (*callback)(int status,
 					struct ib_sa_mcmember_rec *resp,
 					void *context),
@@ -290,7 +355,7 @@ static inline int
 ib_sa_mcmember_rec_delete(struct ib_device *device, u8 port_num,
 			  struct ib_sa_mcmember_rec *rec,
 			  ib_sa_comp_mask comp_mask,
-			  int timeout_ms, int gfp_mask,
+			  int timeout_ms, unsigned int __nocast gfp_mask,
 			  void (*callback)(int status,
 					   struct ib_sa_mcmember_rec *resp,
 					   void *context),
diff --git a/drivers/infiniband/include/ib_user_cm.h b/drivers/infiniband/include/ib_user_cm.h
new file mode 100644
--- /dev/null
+++ b/drivers/infiniband/include/ib_user_cm.h
@@ -0,0 +1,328 @@
+/*
+ * Copyright (c) 2005 Topspin Communications.  All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * 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 THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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.
+ *
+ * $Id: ib_user_cm.h 2576 2005-06-09 17:00:30Z libor $
+ */
+
+#ifndef IB_USER_CM_H
+#define IB_USER_CM_H
+
+#include <linux/types.h>
+
+#define IB_USER_CM_ABI_VERSION 1
+
+enum {
+	IB_USER_CM_CMD_CREATE_ID,
+	IB_USER_CM_CMD_DESTROY_ID,
+	IB_USER_CM_CMD_ATTR_ID,
+
+	IB_USER_CM_CMD_LISTEN,
+	IB_USER_CM_CMD_ESTABLISH,
+
+	IB_USER_CM_CMD_SEND_REQ,
+	IB_USER_CM_CMD_SEND_REP,
+	IB_USER_CM_CMD_SEND_RTU,
+	IB_USER_CM_CMD_SEND_DREQ,
+	IB_USER_CM_CMD_SEND_DREP,
+	IB_USER_CM_CMD_SEND_REJ,
+	IB_USER_CM_CMD_SEND_MRA,
+	IB_USER_CM_CMD_SEND_LAP,
+	IB_USER_CM_CMD_SEND_APR,
+	IB_USER_CM_CMD_SEND_SIDR_REQ,
+	IB_USER_CM_CMD_SEND_SIDR_REP,
+
+	IB_USER_CM_CMD_EVENT,
+};
+/*
+ * command ABI structures.
+ */
+struct ib_ucm_cmd_hdr {
+	__u32 cmd;
+	__u16 in;
+	__u16 out;
+};
+
+struct ib_ucm_create_id {
+	__u64 response;
+};
+
+struct ib_ucm_create_id_resp {
+	__u32 id;
+};
+
+struct ib_ucm_destroy_id {
+	__u32 id;
+};
+
+struct ib_ucm_attr_id {
+	__u64 response;
+	__u32 id;
+};
+
+struct ib_ucm_attr_id_resp {
+	__u64 service_id;
+	__u64 service_mask;
+	__u32 local_id;
+	__u32 remote_id;
+};
+
+struct ib_ucm_listen {
+	__u64 service_id;
+	__u64 service_mask;
+	__u32 id;
+};
+
+struct ib_ucm_establish {
+	__u32 id;
+};
+
+struct ib_ucm_private_data {
+	__u64 data;
+	__u32 id;
+	__u8  len;
+	__u8  reserved[3];
+};
+
+struct ib_ucm_path_rec {
+	__u8  dgid[16];
+	__u8  sgid[16];
+	__u16 dlid;
+	__u16 slid;
+	__u32 raw_traffic;
+	__u32 flow_label;
+	__u32 reversible;
+	__u32 mtu;
+	__u16 pkey;
+	__u8  hop_limit;
+	__u8  traffic_class;
+	__u8  numb_path;
+	__u8  sl;
+	__u8  mtu_selector;
+	__u8  rate_selector;
+	__u8  rate;
+	__u8  packet_life_time_selector;
+	__u8  packet_life_time;
+	__u8  preference;
+};
+
+struct ib_ucm_req {
+	__u32 id;
+	__u32 qpn;
+	__u32 qp_type;
+	__u32 psn;
+	__u64 sid;
+	__u64 data;
+	__u64 primary_path;
+	__u64 alternate_path;
+	__u8  len;
+	__u8  peer_to_peer;
+	__u8  responder_resources;
+	__u8  initiator_depth;
+	__u8  remote_cm_response_timeout;
+	__u8  flow_control;
+	__u8  local_cm_response_timeout;
+	__u8  retry_count;
+	__u8  rnr_retry_count;
+	__u8  max_cm_retries;
+	__u8  srq;
+	__u8  reserved[1];
+};
+
+struct ib_ucm_rep {
+	__u64 data;
+	__u32 id;
+	__u32 qpn;
+	__u32 psn;
+	__u8  len;
+	__u8  responder_resources;
+	__u8  initiator_depth;
+	__u8  target_ack_delay;
+	__u8  failover_accepted;
+	__u8  flow_control;
+	__u8  rnr_retry_count;
+	__u8  srq;
+};
+
+struct ib_ucm_info {
+	__u32 id;
+	__u32 status;
+	__u64 info;
+	__u64 data;
+	__u8  info_len;
+	__u8  data_len;
+	__u8  reserved[2];
+};
+
+struct ib_ucm_mra {
+	__u64 data;
+	__u32 id;
+	__u8  len;
+	__u8  timeout;
+	__u8  reserved[2];
+};
+
+struct ib_ucm_lap {
+	__u64 path;
+	__u64 data;
+	__u32 id;
+	__u8  len;
+	__u8  reserved[3];
+};
+
+struct ib_ucm_sidr_req {
+	__u32 id;
+	__u32 timeout;
+	__u64 sid;
+	__u64 data;
+	__u64 path;
+	__u16 pkey;
+	__u8  len;
+	__u8  max_cm_retries;
+};
+
+struct ib_ucm_sidr_rep {
+	__u32 id;
+	__u32 qpn;
+	__u32 qkey;
+	__u32 status;
+	__u64 info;
+	__u64 data;
+	__u8  info_len;
+	__u8  data_len;
+	__u8  reserved[2];
+};
+/*
+ * event notification ABI structures.
+ */
+struct ib_ucm_event_get {
+	__u64 response;
+	__u64 data;
+	__u64 info;
+	__u8  data_len;
+	__u8  info_len;
+	__u8  reserved[2];
+};
+
+struct ib_ucm_req_event_resp {
+	__u32                  listen_id;
+	/* device */
+	/* port */
+	struct ib_ucm_path_rec primary_path;
+	struct ib_ucm_path_rec alternate_path;
+	__u64                  remote_ca_guid;
+	__u32                  remote_qkey;
+	__u32                  remote_qpn;
+	__u32                  qp_type;
+	__u32                  starting_psn;
+	__u8  responder_resources;
+	__u8  initiator_depth;
+	__u8  local_cm_response_timeout;
+	__u8  flow_control;
+	__u8  remote_cm_response_timeout;
+	__u8  retry_count;
+	__u8  rnr_retry_count;
+	__u8  srq;
+};
+
+struct ib_ucm_rep_event_resp {
+	__u64 remote_ca_guid;
+	__u32 remote_qkey;
+	__u32 remote_qpn;
+	__u32 starting_psn;
+	__u8  responder_resources;
+	__u8  initiator_depth;
+	__u8  target_ack_delay;
+	__u8  failover_accepted;
+	__u8  flow_control;
+	__u8  rnr_retry_count;
+	__u8  srq;
+	__u8  reserved[1];
+};
+
+struct ib_ucm_rej_event_resp {
+	__u32 reason;
+	/* ari in ib_ucm_event_get info field. */
+};
+
+struct ib_ucm_mra_event_resp {
+	__u8  timeout;
+	__u8  reserved[3];
+};
+
+struct ib_ucm_lap_event_resp {
+	struct ib_ucm_path_rec path;
+};
+
+struct ib_ucm_apr_event_resp {
+	__u32 status;
+	/* apr info in ib_ucm_event_get info field. */
+};
+
+struct ib_ucm_sidr_req_event_resp {
+	__u32 listen_id;
+	/* device */
+	/* port */
+	__u16 pkey;
+	__u8  reserved[2];
+};
+
+struct ib_ucm_sidr_rep_event_resp {
+	__u32 status;
+	__u32 qkey;
+	__u32 qpn;
+	/* info in ib_ucm_event_get info field. */
+};
+
+#define IB_UCM_PRES_DATA      0x01
+#define IB_UCM_PRES_INFO      0x02
+#define IB_UCM_PRES_PRIMARY   0x04
+#define IB_UCM_PRES_ALTERNATE 0x08
+
+struct ib_ucm_event_resp {
+	__u32 id;
+	__u32 event;
+	__u32 present;
+	union {
+		struct ib_ucm_req_event_resp req_resp;
+		struct ib_ucm_rep_event_resp rep_resp;
+		struct ib_ucm_rej_event_resp rej_resp;
+		struct ib_ucm_mra_event_resp mra_resp;
+		struct ib_ucm_lap_event_resp lap_resp;
+		struct ib_ucm_apr_event_resp apr_resp;
+
+		struct ib_ucm_sidr_req_event_resp sidr_req_resp;
+		struct ib_ucm_sidr_rep_event_resp sidr_rep_resp;
+
+		__u32                             send_status;
+	} u;
+};
+
+#endif /* IB_USER_CM_H */
diff --git a/drivers/infiniband/include/ib_user_mad.h b/drivers/infiniband/include/ib_user_mad.h
--- a/drivers/infiniband/include/ib_user_mad.h
+++ b/drivers/infiniband/include/ib_user_mad.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2004 Topspin Communications.  All rights reserved.
+ * Copyright (c) 2005 Voltaire, Inc. All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
@@ -29,7 +30,7 @@
  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  *
- * $Id: ib_user_mad.h 1389 2004-12-27 22:56:47Z roland $
+ * $Id: ib_user_mad.h 2814 2005-07-06 19:14:09Z halr $
  */
 
 #ifndef IB_USER_MAD_H
@@ -42,7 +43,7 @@
  * Increment this value if any changes that break userspace ABI
  * compatibility are made.
  */
-#define IB_USER_MAD_ABI_VERSION	2
+#define IB_USER_MAD_ABI_VERSION	5
 
 /*
  * Make sure that all structs defined in this file remain laid out so
@@ -51,13 +52,13 @@
  */
 
 /**
- * ib_user_mad - MAD packet
- * @data - Contents of MAD
+ * ib_user_mad_hdr - MAD packet header
  * @id - ID of agent MAD received with/to be sent with
  * @status - 0 on successful receive, ETIMEDOUT if no response
  *   received (transaction ID in data[] will be set to TID of original
  *   request) (ignored on send)
  * @timeout_ms - Milliseconds to wait for response (unset on receive)
+ * @retries - Number of automatic retries to attempt
  * @qpn - Remote QP number received from/to be sent to
  * @qkey - Remote Q_Key to be sent with (unset on receive)
  * @lid - Remote lid received from/to be sent to
@@ -72,11 +73,12 @@
  *
  * All multi-byte quantities are stored in network (big endian) byte order.
  */
-struct ib_user_mad {
-	__u8	data[256];
+struct ib_user_mad_hdr {
 	__u32	id;
 	__u32	status;
 	__u32	timeout_ms;
+	__u32	retries;
+	__u32	length;
 	__u32	qpn;
 	__u32   qkey;
 	__u16	lid;
@@ -91,6 +93,17 @@ struct ib_user_mad {
 };
 
 /**
+ * ib_user_mad - MAD packet
+ * @hdr - MAD packet header
+ * @data - Contents of MAD
+ *
+ */
+struct ib_user_mad {
+	struct ib_user_mad_hdr hdr;
+	__u8	data[0];
+};
+
+/**
  * ib_user_mad_reg_req - MAD registration request
  * @id - Set by the kernel; used to identify agent in future requests.
  * @qpn - Queue pair number; must be 0 or 1.
@@ -103,6 +116,8 @@ struct ib_user_mad {
  *   management class to receive.
  * @oui: Indicates IEEE OUI when mgmt_class is a vendor class
  *   in the range from 0x30 to 0x4f. Otherwise not used.
+ * @rmpp_version: If set, indicates the RMPP version used.
+ *
  */
 struct ib_user_mad_reg_req {
 	__u32	id;
@@ -111,6 +126,7 @@ struct ib_user_mad_reg_req {
 	__u8	mgmt_class;
 	__u8	mgmt_class_version;
 	__u8    oui[3];
+	__u8	rmpp_version;
 };
 
 #define IB_IOCTL_MAGIC		0x1b
diff --git a/drivers/infiniband/include/ib_user_verbs.h b/drivers/infiniband/include/ib_user_verbs.h
new file mode 100644
--- /dev/null
+++ b/drivers/infiniband/include/ib_user_verbs.h
@@ -0,0 +1,389 @@
+/*
+ * Copyright (c) 2005 Topspin Communications.  All rights reserved.
+ * Copyright (c) 2005 Cisco Systems.  All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * 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 THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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.
+ *
+ * $Id: ib_user_verbs.h 2708 2005-06-24 17:27:21Z roland $
+ */
+
+#ifndef IB_USER_VERBS_H
+#define IB_USER_VERBS_H
+
+#include <linux/types.h>
+
+/*
+ * Increment this value if any changes that break userspace ABI
+ * compatibility are made.
+ */
+#define IB_USER_VERBS_ABI_VERSION	1
+
+enum {
+	IB_USER_VERBS_CMD_QUERY_PARAMS,
+	IB_USER_VERBS_CMD_GET_CONTEXT,
+	IB_USER_VERBS_CMD_QUERY_DEVICE,
+	IB_USER_VERBS_CMD_QUERY_PORT,
+	IB_USER_VERBS_CMD_QUERY_GID,
+	IB_USER_VERBS_CMD_QUERY_PKEY,
+	IB_USER_VERBS_CMD_ALLOC_PD,
+	IB_USER_VERBS_CMD_DEALLOC_PD,
+	IB_USER_VERBS_CMD_CREATE_AH,
+	IB_USER_VERBS_CMD_MODIFY_AH,
+	IB_USER_VERBS_CMD_QUERY_AH,
+	IB_USER_VERBS_CMD_DESTROY_AH,
+	IB_USER_VERBS_CMD_REG_MR,
+	IB_USER_VERBS_CMD_REG_SMR,
+	IB_USER_VERBS_CMD_REREG_MR,
+	IB_USER_VERBS_CMD_QUERY_MR,
+	IB_USER_VERBS_CMD_DEREG_MR,
+	IB_USER_VERBS_CMD_ALLOC_MW,
+	IB_USER_VERBS_CMD_BIND_MW,
+	IB_USER_VERBS_CMD_DEALLOC_MW,
+	IB_USER_VERBS_CMD_CREATE_CQ,
+	IB_USER_VERBS_CMD_RESIZE_CQ,
+	IB_USER_VERBS_CMD_DESTROY_CQ,
+	IB_USER_VERBS_CMD_POLL_CQ,
+	IB_USER_VERBS_CMD_PEEK_CQ,
+	IB_USER_VERBS_CMD_REQ_NOTIFY_CQ,
+	IB_USER_VERBS_CMD_CREATE_QP,
+	IB_USER_VERBS_CMD_QUERY_QP,
+	IB_USER_VERBS_CMD_MODIFY_QP,
+	IB_USER_VERBS_CMD_DESTROY_QP,
+	IB_USER_VERBS_CMD_POST_SEND,
+	IB_USER_VERBS_CMD_POST_RECV,
+	IB_USER_VERBS_CMD_ATTACH_MCAST,
+	IB_USER_VERBS_CMD_DETACH_MCAST
+};
+
+/*
+ * Make sure that all structs defined in this file remain laid out so
+ * that they pack the same way on 32-bit and 64-bit architectures (to
+ * avoid incompatibility between 32-bit userspace and 64-bit kernels).
+ * In particular do not use pointer types -- pass pointers in __u64
+ * instead.
+ */
+
+struct ib_uverbs_async_event_desc {
+	__u64 element;
+	__u32 event_type;	/* enum ib_event_type */
+	__u32 reserved;
+};
+
+struct ib_uverbs_comp_event_desc {
+	__u64 cq_handle;
+};
+
+/*
+ * All commands from userspace should start with a __u32 command field
+ * followed by __u16 in_words and out_words fields (which give the
+ * length of the command block and response buffer if any in 32-bit
+ * words).  The kernel driver will read these fields first and read
+ * the rest of the command struct based on these value.
+ */
+
+struct ib_uverbs_cmd_hdr {
+	__u32 command;
+	__u16 in_words;
+	__u16 out_words;
+};
+
+/*
+ * No driver_data for "query params" command, since this is intended
+ * to be a core function with no possible device dependence.
+ */
+struct ib_uverbs_query_params {
+	__u64 response;
+};
+
+struct ib_uverbs_query_params_resp {
+	__u32 num_cq_events;
+};
+
+struct ib_uverbs_get_context {
+	__u64 response;
+	__u64 cq_fd_tab;
+	__u64 driver_data[0];
+};
+
+struct ib_uverbs_get_context_resp {
+	__u32 async_fd;
+	__u32 reserved;
+};
+
+struct ib_uverbs_query_device {
+	__u64 response;
+	__u64 driver_data[0];
+};
+
+struct ib_uverbs_query_device_resp {
+	__u64 fw_ver;
+	__u64 node_guid;
+	__u64 sys_image_guid;
+	__u64 max_mr_size;
+	__u64 page_size_cap;
+	__u32 vendor_id;
+	__u32 vendor_part_id;
+	__u32 hw_ver;
+	__u32 max_qp;
+	__u32 max_qp_wr;
+	__u32 device_cap_flags;
+	__u32 max_sge;
+	__u32 max_sge_rd;
+	__u32 max_cq;
+	__u32 max_cqe;
+	__u32 max_mr;
+	__u32 max_pd;
+	__u32 max_qp_rd_atom;
+	__u32 max_ee_rd_atom;
+	__u32 max_res_rd_atom;
+	__u32 max_qp_init_rd_atom;
+	__u32 max_ee_init_rd_atom;
+	__u32 atomic_cap;
+	__u32 max_ee;
+	__u32 max_rdd;
+	__u32 max_mw;
+	__u32 max_raw_ipv6_qp;
+	__u32 max_raw_ethy_qp;
+	__u32 max_mcast_grp;
+	__u32 max_mcast_qp_attach;
+	__u32 max_total_mcast_qp_attach;
+	__u32 max_ah;
+	__u32 max_fmr;
+	__u32 max_map_per_fmr;
+	__u32 max_srq;
+	__u32 max_srq_wr;
+	__u32 max_srq_sge;
+	__u16 max_pkeys;
+	__u8  local_ca_ack_delay;
+	__u8  phys_port_cnt;
+	__u8  reserved[4];
+};
+
+struct ib_uverbs_query_port {
+	__u64 response;
+	__u8  port_num;
+	__u8  reserved[7];
+	__u64 driver_data[0];
+};
+
+struct ib_uverbs_query_port_resp {
+	__u32 port_cap_flags;
+	__u32 max_msg_sz;
+	__u32 bad_pkey_cntr;
+	__u32 qkey_viol_cntr;
+	__u32 gid_tbl_len;
+	__u16 pkey_tbl_len;
+	__u16 lid;
+	__u16 sm_lid;
+	__u8  state;
+	__u8  max_mtu;
+	__u8  active_mtu;
+	__u8  lmc;
+	__u8  max_vl_num;
+	__u8  sm_sl;
+	__u8  subnet_timeout;
+	__u8  init_type_reply;
+	__u8  active_width;
+	__u8  active_speed;
+	__u8  phys_state;
+	__u8  reserved[3];
+};
+
+struct ib_uverbs_query_gid {
+	__u64 response;
+	__u8  port_num;
+	__u8  index;
+	__u8  reserved[6];
+	__u64 driver_data[0];
+};
+
+struct ib_uverbs_query_gid_resp {
+	__u8  gid[16];
+};
+
+struct ib_uverbs_query_pkey {
+	__u64 response;
+	__u8  port_num;
+	__u8  index;
+	__u8  reserved[6];
+	__u64 driver_data[0];
+};
+
+struct ib_uverbs_query_pkey_resp {
+	__u16 pkey;
+	__u16 reserved;
+};
+
+struct ib_uverbs_alloc_pd {
+	__u64 response;
+	__u64 driver_data[0];
+};
+
+struct ib_uverbs_alloc_pd_resp {
+	__u32 pd_handle;
+};
+
+struct ib_uverbs_dealloc_pd {
+	__u32 pd_handle;
+};
+
+struct ib_uverbs_reg_mr {
+	__u64 response;
+	__u64 start;
+	__u64 length;
+	__u64 hca_va;
+	__u32 pd_handle;
+	__u32 access_flags;
+	__u64 driver_data[0];
+};
+
+struct ib_uverbs_reg_mr_resp {
+	__u32 mr_handle;
+	__u32 lkey;
+	__u32 rkey;
+};
+
+struct ib_uverbs_dereg_mr {
+	__u32 mr_handle;
+};
+
+struct ib_uverbs_create_cq {
+	__u64 response;
+	__u64 user_handle;
+	__u32 cqe;
+	__u32 event_handler;
+	__u64 driver_data[0];
+};
+
+struct ib_uverbs_create_cq_resp {
+	__u32 cq_handle;
+	__u32 cqe;
+};
+
+struct ib_uverbs_destroy_cq {
+	__u32 cq_handle;
+};
+
+struct ib_uverbs_create_qp {
+	__u64 response;
+	__u64 user_handle;
+	__u32 pd_handle;
+	__u32 send_cq_handle;
+	__u32 recv_cq_handle;
+	__u32 srq_handle;
+	__u32 max_send_wr;
+	__u32 max_recv_wr;
+	__u32 max_send_sge;
+	__u32 max_recv_sge;
+	__u32 max_inline_data;
+	__u8  sq_sig_all;
+	__u8  qp_type;
+	__u8  is_srq;
+	__u8  reserved;
+	__u64 driver_data[0];
+};
+
+struct ib_uverbs_create_qp_resp {
+	__u32 qp_handle;
+	__u32 qpn;
+};
+
+/*
+ * This struct needs to remain a multiple of 8 bytes to keep the
+ * alignment of the modify QP parameters.
+ */
+struct ib_uverbs_qp_dest {
+	__u8  dgid[16];
+	__u32 flow_label;
+	__u16 dlid;
+	__u16 reserved;
+	__u8  sgid_index;
+	__u8  hop_limit;
+	__u8  traffic_class;
+	__u8  sl;
+	__u8  src_path_bits;
+	__u8  static_rate;
+	__u8  is_global;
+	__u8  port_num;
+};
+
+struct ib_uverbs_modify_qp {
+	struct ib_uverbs_qp_dest dest;
+	struct ib_uverbs_qp_dest alt_dest;
+	__u32 qp_handle;
+	__u32 attr_mask;
+	__u32 qkey;
+	__u32 rq_psn;
+	__u32 sq_psn;
+	__u32 dest_qp_num;
+	__u32 qp_access_flags;
+	__u16 pkey_index;
+	__u16 alt_pkey_index;
+	__u8  qp_state;
+	__u8  cur_qp_state;
+	__u8  path_mtu;
+	__u8  path_mig_state;
+	__u8  en_sqd_async_notify;
+	__u8  max_rd_atomic;
+	__u8  max_dest_rd_atomic;
+	__u8  min_rnr_timer;
+	__u8  port_num;
+	__u8  timeout;
+	__u8  retry_cnt;
+	__u8  rnr_retry;
+	__u8  alt_port_num;
+	__u8  alt_timeout;
+	__u8  reserved[2];
+	__u64 driver_data[0];
+};
+
+struct ib_uverbs_modify_qp_resp {
+};
+
+struct ib_uverbs_destroy_qp {
+	__u32 qp_handle;
+};
+
+struct ib_uverbs_attach_mcast {
+	__u8  gid[16];
+	__u32 qp_handle;
+	__u16 mlid;
+	__u16 reserved;
+	__u64 driver_data[0];
+};
+
+struct ib_uverbs_detach_mcast {
+	__u8  gid[16];
+	__u32 qp_handle;
+	__u16 mlid;
+	__u16 reserved;
+	__u64 driver_data[0];
+};
+
+#endif /* IB_USER_VERBS_H */
diff --git a/drivers/infiniband/include/ib_verbs.h b/drivers/infiniband/include/ib_verbs.h
--- a/drivers/infiniband/include/ib_verbs.h
+++ b/drivers/infiniband/include/ib_verbs.h
@@ -4,6 +4,7 @@
  * Copyright (c) 2004 Intel Corporation.  All rights reserved.
  * Copyright (c) 2004 Topspin Corporation.  All rights reserved.
  * Copyright (c) 2004 Voltaire Corporation.  All rights reserved.
+ * Copyright (c) 2005 Cisco Systems.  All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
@@ -41,7 +42,10 @@
 
 #include <linux/types.h>
 #include <linux/device.h>
+
 #include <asm/atomic.h>
+#include <asm/scatterlist.h>
+#include <asm/uaccess.h>
 
 union ib_gid {
 	u8	raw[16];
@@ -285,6 +289,15 @@ struct ib_global_route {
 	u8		traffic_class;
 };
 
+struct ib_grh {
+	u32		version_tclass_flow;
+	u16		paylen;
+	u8		next_hdr;
+	u8		hop_limit;
+	union ib_gid	sgid;
+	union ib_gid	dgid;
+};
+
 enum {
 	IB_MULTICAST_QPN = 0xffffff
 };
@@ -544,7 +557,7 @@ struct ib_send_wr {
 	int			num_sge;
 	enum ib_wr_opcode	opcode;
 	int			send_flags;
-	u32			imm_data;
+	__be32			imm_data;
 	union {
 		struct {
 			u64	remote_addr;
@@ -562,6 +575,7 @@ struct ib_send_wr {
 			u32	remote_qpn;
 			u32	remote_qkey;
 			int	timeout_ms; /* valid for MADs only */
+			int	retries;    /* valid for MADs only */
 			u16	pkey_index; /* valid for GSI only */
 			u8	port_num;   /* valid for DR SMPs on switch only */
 		} ud;
@@ -618,29 +632,86 @@ struct ib_fmr_attr {
 	u8	page_size;
 };
 
+struct ib_ucontext {
+	struct ib_device       *device;
+	struct list_head	pd_list;
+	struct list_head	mr_list;
+	struct list_head	mw_list;
+	struct list_head	cq_list;
+	struct list_head	qp_list;
+	struct list_head	srq_list;
+	struct list_head	ah_list;
+	spinlock_t              lock;
+};
+
+struct ib_uobject {
+	u64			user_handle;	/* handle given to us by userspace */
+	struct ib_ucontext     *context;	/* associated user context */
+	struct list_head	list;		/* link to context's list */
+	u32			id;		/* index into kernel idr */
+};
+
+struct ib_umem {
+	unsigned long		user_base;
+	unsigned long		virt_base;
+	size_t			length;
+	int			offset;
+	int			page_size;
+	int                     writable;
+	struct list_head	chunk_list;
+};
+
+struct ib_umem_chunk {
+	struct list_head	list;
+	int                     nents;
+	int                     nmap;
+	struct scatterlist      page_list[0];
+};
+
+struct ib_udata {
+	void __user *inbuf;
+	void __user *outbuf;
+	size_t       inlen;
+	size_t       outlen;
+};
+
+#define IB_UMEM_MAX_PAGE_CHUNK						\
+	((PAGE_SIZE - offsetof(struct ib_umem_chunk, page_list)) /	\
+	 ((void *) &((struct ib_umem_chunk *) 0)->page_list[1] -	\
+	  (void *) &((struct ib_umem_chunk *) 0)->page_list[0]))
+
+struct ib_umem_object {
+	struct ib_uobject	uobject;
+	struct ib_umem		umem;
+};
+
 struct ib_pd {
-	struct ib_device *device;
-	atomic_t          usecnt; /* count all resources */
+	struct ib_device       *device;
+	struct ib_uobject      *uobject;
+	atomic_t          	usecnt; /* count all resources */
 };
 
 struct ib_ah {
 	struct ib_device	*device;
 	struct ib_pd		*pd;
+	struct ib_uobject	*uobject;
 };
 
 typedef void (*ib_comp_handler)(struct ib_cq *cq, void *cq_context);
 
 struct ib_cq {
-	struct ib_device *device;
-	ib_comp_handler   comp_handler;
-	void             (*event_handler)(struct ib_event *, void *);
-	void *            cq_context;
-	int               cqe;
-	atomic_t          usecnt; /* count number of work queues */
+	struct ib_device       *device;
+	struct ib_uobject      *uobject;
+	ib_comp_handler   	comp_handler;
+	void                  (*event_handler)(struct ib_event *, void *);
+	void *            	cq_context;
+	int               	cqe;
+	atomic_t          	usecnt; /* count number of work queues */
 };
 
 struct ib_srq {
 	struct ib_device	*device;
+	struct ib_uobject	*uobject;
 	struct ib_pd		*pd;
 	void			*srq_context;
 	atomic_t		usecnt;
@@ -652,6 +723,7 @@ struct ib_qp {
 	struct ib_cq	       *send_cq;
 	struct ib_cq	       *recv_cq;
 	struct ib_srq	       *srq;
+	struct ib_uobject      *uobject;
 	void                  (*event_handler)(struct ib_event *, void *);
 	void		       *qp_context;
 	u32			qp_num;
@@ -659,16 +731,18 @@ struct ib_qp {
 };
 
 struct ib_mr {
-	struct ib_device *device;
-	struct ib_pd     *pd;
-	u32		  lkey;
-	u32		  rkey;
-	atomic_t          usecnt; /* count number of MWs */
+	struct ib_device  *device;
+	struct ib_pd	  *pd;
+	struct ib_uobject *uobject;
+	u32		   lkey;
+	u32		   rkey;
+	atomic_t	   usecnt; /* count number of MWs */
 };
 
 struct ib_mw {
 	struct ib_device	*device;
 	struct ib_pd		*pd;
+	struct ib_uobject	*uobject;
 	u32			rkey;
 };
 
@@ -737,7 +811,14 @@ struct ib_device {
 	int		           (*modify_port)(struct ib_device *device,
 						  u8 port_num, int port_modify_mask,
 						  struct ib_port_modify *port_modify);
-	struct ib_pd *             (*alloc_pd)(struct ib_device *device);
+	struct ib_ucontext *       (*alloc_ucontext)(struct ib_device *device,
+						     struct ib_udata *udata);
+	int                        (*dealloc_ucontext)(struct ib_ucontext *context);
+	int                        (*mmap)(struct ib_ucontext *context,
+					   struct vm_area_struct *vma);
+	struct ib_pd *             (*alloc_pd)(struct ib_device *device,
+					       struct ib_ucontext *context,
+					       struct ib_udata *udata);
 	int                        (*dealloc_pd)(struct ib_pd *pd);
 	struct ib_ah *             (*create_ah)(struct ib_pd *pd,
 						struct ib_ah_attr *ah_attr);
@@ -747,7 +828,8 @@ struct ib_device {
 					       struct ib_ah_attr *ah_attr);
 	int                        (*destroy_ah)(struct ib_ah *ah);
 	struct ib_qp *             (*create_qp)(struct ib_pd *pd,
-						struct ib_qp_init_attr *qp_init_attr);
+						struct ib_qp_init_attr *qp_init_attr,
+						struct ib_udata *udata);
 	int                        (*modify_qp)(struct ib_qp *qp,
 						struct ib_qp_attr *qp_attr,
 						int qp_attr_mask);
@@ -762,8 +844,9 @@ struct ib_device {
 	int                        (*post_recv)(struct ib_qp *qp,
 						struct ib_recv_wr *recv_wr,
 						struct ib_recv_wr **bad_recv_wr);
-	struct ib_cq *             (*create_cq)(struct ib_device *device,
-						int cqe);
+	struct ib_cq *             (*create_cq)(struct ib_device *device, int cqe,
+						struct ib_ucontext *context,
+						struct ib_udata *udata);
 	int                        (*destroy_cq)(struct ib_cq *cq);
 	int                        (*resize_cq)(struct ib_cq *cq, int *cqe);
 	int                        (*poll_cq)(struct ib_cq *cq, int num_entries,
@@ -780,6 +863,10 @@ struct ib_device {
 						  int num_phys_buf,
 						  int mr_access_flags,
 						  u64 *iova_start);
+	struct ib_mr *             (*reg_user_mr)(struct ib_pd *pd,
+						  struct ib_umem *region,
+						  int mr_access_flags,
+						  struct ib_udata *udata);
 	int                        (*query_mr)(struct ib_mr *mr,
 					       struct ib_mr_attr *mr_attr);
 	int                        (*dereg_mr)(struct ib_mr *mr);
@@ -817,6 +904,7 @@ struct ib_device {
 						  struct ib_mad *in_mad,
 						  struct ib_mad *out_mad);
 
+	struct module               *owner;
 	struct class_device          class_dev;
 	struct kobject               ports_parent;
 	struct list_head             port_list;
@@ -852,6 +940,16 @@ void *ib_get_client_data(struct ib_devic
 void  ib_set_client_data(struct ib_device *device, struct ib_client *client,
 			 void *data);
 
+static inline int ib_copy_from_udata(void *dest, struct ib_udata *udata, size_t len)
+{
+	return copy_from_user(dest, udata->inbuf, len) ? -EFAULT : 0;
+}
+
+static inline int ib_copy_to_udata(struct ib_udata *udata, void *src, size_t len)
+{
+	return copy_to_user(udata->outbuf, src, len) ? -EFAULT : 0;
+}
+
 int ib_register_event_handler  (struct ib_event_handler *event_handler);
 int ib_unregister_event_handler(struct ib_event_handler *event_handler);
 void ib_dispatch_event(struct ib_event *event);
@@ -902,6 +1000,21 @@ int ib_dealloc_pd(struct ib_pd *pd);
 struct ib_ah *ib_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr);
 
 /**
+ * ib_create_ah_from_wc - Creates an address handle associated with the
+ *   sender of the specified work completion.
+ * @pd: The protection domain associated with the address handle.
+ * @wc: Work completion information associated with a received message.
+ * @grh: References the received global route header.  This parameter is
+ *   ignored unless the work completion indicates that the GRH is valid.
+ * @port_num: The outbound port number to associate with the address.
+ *
+ * The address handle is used to reference a local or global destination
+ * in all UD QP post sends.
+ */
+struct ib_ah *ib_create_ah_from_wc(struct ib_pd *pd, struct ib_wc *wc,
+				   struct ib_grh *grh, u8 port_num);
+
+/**
  * ib_modify_ah - Modifies the address vector associated with an address
  *   handle.
  * @ah: The address handle to modify.
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
--- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
@@ -81,7 +81,7 @@ void ipoib_free_ah(struct kref *kref)
 
 	unsigned long flags;
 
-	if (ah->last_send <= priv->tx_tail) {
+	if ((int) priv->tx_tail - (int) ah->last_send >= 0) {
 		ipoib_dbg(priv, "Freeing ah %p\n", ah->ah);
 		ib_destroy_ah(ah->ah);
 		kfree(ah);
@@ -355,7 +355,7 @@ static void __ipoib_reap_ah(struct net_d
 
 	spin_lock_irq(&priv->lock);
 	list_for_each_entry_safe(ah, tah, &priv->dead_ahs, list)
-		if (ah->last_send <= priv->tx_tail) {
+		if ((int) priv->tx_tail - (int) ah->last_send >= 0) {
 			list_del(&ah->list);
 			list_add_tail(&ah->list, &remove_list);
 		}
@@ -486,7 +486,7 @@ int ipoib_ib_dev_stop(struct net_device 
 			 * assume the HW is wedged and just free up
 			 * all our pending work requests.
 			 */
-			while (priv->tx_tail < priv->tx_head) {
+			while ((int) priv->tx_tail - (int) priv->tx_head < 0) {
 				tx_req = &priv->tx_ring[priv->tx_tail &
 							(IPOIB_TX_RING_SIZE - 1)];
 				dma_unmap_single(priv->ca->dma_device,
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -600,9 +600,10 @@ static int ipoib_start_xmit(struct sk_bu
 
 			ipoib_mcast_send(dev, (union ib_gid *) (phdr->hwaddr + 4), skb);
 		} else {
-			/* unicast GID -- should be ARP reply */
+			/* unicast GID -- should be ARP or RARP reply */
 
-			if (be16_to_cpup((u16 *) skb->data) != ETH_P_ARP) {
+			if ((be16_to_cpup((__be16 *) skb->data) != ETH_P_ARP) &&
+			    (be16_to_cpup((__be16 *) skb->data) != ETH_P_RARP)) {
 				ipoib_warn(priv, "Unicast, no %s: type %04x, QPN %06x "
 					   IPOIB_GID_FMT "\n",
 					   skb->dst ? "neigh" : "dst",
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -21,6 +21,7 @@
 #include <linux/smp_lock.h>
 #include <linux/device.h>
 #include <linux/devfs_fs_kernel.h>
+#include <linux/compat.h>
 
 struct evdev {
 	int exist;
@@ -145,6 +146,41 @@ static int evdev_open(struct inode * ino
 	return 0;
 }
 
+#ifdef CONFIG_COMPAT
+struct input_event_compat {
+	struct compat_timeval time;
+	__u16 type;
+	__u16 code;
+	__s32 value;
+};
+
+#ifdef CONFIG_X86_64
+#  define COMPAT_TEST test_thread_flag(TIF_IA32)
+#elif defined(CONFIG_IA64)
+#  define COMPAT_TEST IS_IA32_PROCESS(ia64_task_regs(current))
+#elif defined(CONFIG_ARCH_S390)
+#  define COMPAT_TEST test_thread_flag(TIF_31BIT)
+#else
+#  define COMPAT_TEST test_thread_flag(TIF_32BIT)
+#endif
+
+static ssize_t evdev_write_compat(struct file * file, const char __user * buffer, size_t count, loff_t *ppos)
+{
+	struct evdev_list *list = file->private_data;
+	struct input_event_compat event;
+	int retval = 0;
+
+	while (retval < count) {
+		if (copy_from_user(&event, buffer + retval, sizeof(struct input_event_compat)))
+			return -EFAULT;
+		input_event(list->evdev->handle.dev, event.type, event.code, event.value);
+		retval += sizeof(struct input_event_compat);
+	}
+
+	return retval;
+}
+#endif
+
 static ssize_t evdev_write(struct file * file, const char __user * buffer, size_t count, loff_t *ppos)
 {
 	struct evdev_list *list = file->private_data;
@@ -153,6 +189,11 @@ static ssize_t evdev_write(struct file *
 
 	if (!list->evdev->exist) return -ENODEV;
 
+#ifdef CONFIG_COMPAT
+	if (COMPAT_TEST)
+		return evdev_write_compat(file, buffer, count, ppos);
+#endif
+
 	while (retval < count) {
 
 		if (copy_from_user(&event, buffer + retval, sizeof(struct input_event)))
@@ -164,11 +205,56 @@ static ssize_t evdev_write(struct file *
 	return retval;
 }
 
+#ifdef CONFIG_COMPAT
+static ssize_t evdev_read_compat(struct file * file, char __user * buffer, size_t count, loff_t *ppos)
+{
+	struct evdev_list *list = file->private_data;
+	int retval;
+
+	if (count < sizeof(struct input_event_compat))
+		return -EINVAL;
+
+	if (list->head == list->tail && list->evdev->exist && (file->f_flags & O_NONBLOCK))
+		return -EAGAIN;
+
+	retval = wait_event_interruptible(list->evdev->wait,
+		list->head != list->tail || (!list->evdev->exist));
+
+	if (retval)
+		return retval;
+
+	if (!list->evdev->exist)
+		return -ENODEV;
+
+	while (list->head != list->tail && retval + sizeof(struct input_event_compat) <= count) {
+		struct input_event *event = (struct input_event *) list->buffer + list->tail;
+		struct input_event_compat event_compat;
+		event_compat.time.tv_sec = event->time.tv_sec;
+		event_compat.time.tv_usec = event->time.tv_usec;
+		event_compat.type = event->type;
+		event_compat.code = event->code;
+		event_compat.value = event->value;
+
+		if (copy_to_user(buffer + retval, &event_compat,
+			sizeof(struct input_event_compat))) return -EFAULT;
+		list->tail = (list->tail + 1) & (EVDEV_BUFFER_SIZE - 1);
+		retval += sizeof(struct input_event_compat);
+	}
+
+	return retval;
+}
+#endif
+
 static ssize_t evdev_read(struct file * file, char __user * buffer, size_t count, loff_t *ppos)
 {
 	struct evdev_list *list = file->private_data;
 	int retval;
 
+#ifdef CONFIG_COMPAT
+	if (COMPAT_TEST)
+		return evdev_read_compat(file, buffer, count, ppos);
+#endif
+
 	if (count < sizeof(struct input_event))
 		return -EINVAL;
 
@@ -186,7 +272,7 @@ static ssize_t evdev_read(struct file * 
 
 	while (list->head != list->tail && retval + sizeof(struct input_event) <= count) {
 		if (copy_to_user(buffer + retval, list->buffer + list->tail,
-			 sizeof(struct input_event))) return -EFAULT;
+			sizeof(struct input_event))) return -EFAULT;
 		list->tail = (list->tail + 1) & (EVDEV_BUFFER_SIZE - 1);
 		retval += sizeof(struct input_event);
 	}
@@ -203,7 +289,7 @@ static unsigned int evdev_poll(struct fi
 		(list->evdev->exist ? 0 : (POLLHUP | POLLERR));
 }
 
-static int evdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+static long evdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
 	struct evdev_list *list = file->private_data;
 	struct evdev *evdev = list->evdev;
@@ -234,6 +320,7 @@ static int evdev_ioctl(struct inode *ino
 			if (t < 0 || t >= dev->keycodemax || !dev->keycodesize) return -EINVAL;
 			if (get_user(v, ip + 1)) return -EFAULT;
 			if (v < 0 || v > KEY_MAX) return -EINVAL;
+			if (v >> (dev->keycodesize * 8)) return -EINVAL;
 			u = SET_INPUT_KEYCODE(dev, t, v);
 			clear_bit(u, dev->keybit);
 			set_bit(v, dev->keybit);
@@ -285,109 +372,267 @@ static int evdev_ioctl(struct inode *ino
 
 		default:
 
-			if (_IOC_TYPE(cmd) != 'E' || _IOC_DIR(cmd) != _IOC_READ)
+			if (_IOC_TYPE(cmd) != 'E')
 				return -EINVAL;
 
-			if ((_IOC_NR(cmd) & ~EV_MAX) == _IOC_NR(EVIOCGBIT(0,0))) {
+			if (_IOC_DIR(cmd) == _IOC_READ) {
 
-				long *bits;
-				int len;
+				if ((_IOC_NR(cmd) & ~EV_MAX) == _IOC_NR(EVIOCGBIT(0,0))) {
 
-				switch (_IOC_NR(cmd) & EV_MAX) {
-					case      0: bits = dev->evbit;  len = EV_MAX;  break;
-					case EV_KEY: bits = dev->keybit; len = KEY_MAX; break;
-					case EV_REL: bits = dev->relbit; len = REL_MAX; break;
-					case EV_ABS: bits = dev->absbit; len = ABS_MAX; break;
-					case EV_MSC: bits = dev->mscbit; len = MSC_MAX; break;
-					case EV_LED: bits = dev->ledbit; len = LED_MAX; break;
-					case EV_SND: bits = dev->sndbit; len = SND_MAX; break;
-					case EV_FF:  bits = dev->ffbit;  len = FF_MAX;  break;
-					default: return -EINVAL;
-				}
-				len = NBITS(len) * sizeof(long);
-				if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
-				return copy_to_user(p, bits, len) ? -EFAULT : len;
-			}
+					long *bits;
+					int len;
 
-			if (_IOC_NR(cmd) == _IOC_NR(EVIOCGKEY(0))) {
-				int len;
-				len = NBITS(KEY_MAX) * sizeof(long);
-				if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
-				return copy_to_user(p, dev->key, len) ? -EFAULT : len;
-			}
+					switch (_IOC_NR(cmd) & EV_MAX) {
+						case      0: bits = dev->evbit;  len = EV_MAX;  break;
+						case EV_KEY: bits = dev->keybit; len = KEY_MAX; break;
+						case EV_REL: bits = dev->relbit; len = REL_MAX; break;
+						case EV_ABS: bits = dev->absbit; len = ABS_MAX; break;
+						case EV_MSC: bits = dev->mscbit; len = MSC_MAX; break;
+						case EV_LED: bits = dev->ledbit; len = LED_MAX; break;
+						case EV_SND: bits = dev->sndbit; len = SND_MAX; break;
+						case EV_FF:  bits = dev->ffbit;  len = FF_MAX;  break;
+						default: return -EINVAL;
+					}
+					len = NBITS(len) * sizeof(long);
+					if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
+					return copy_to_user(p, bits, len) ? -EFAULT : len;
+				}
 
-			if (_IOC_NR(cmd) == _IOC_NR(EVIOCGLED(0))) {
-				int len;
-				len = NBITS(LED_MAX) * sizeof(long);
-				if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
-				return copy_to_user(p, dev->led, len) ? -EFAULT : len;
-			}
+				if (_IOC_NR(cmd) == _IOC_NR(EVIOCGKEY(0))) {
+					int len;
+					len = NBITS(KEY_MAX) * sizeof(long);
+					if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
+					return copy_to_user(p, dev->key, len) ? -EFAULT : len;
+				}
 
-			if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSND(0))) {
-				int len;
-				len = NBITS(SND_MAX) * sizeof(long);
-				if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
-				return copy_to_user(p, dev->snd, len) ? -EFAULT : len;
-			}
+				if (_IOC_NR(cmd) == _IOC_NR(EVIOCGLED(0))) {
+					int len;
+					len = NBITS(LED_MAX) * sizeof(long);
+					if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
+					return copy_to_user(p, dev->led, len) ? -EFAULT : len;
+				}
 
-			if (_IOC_NR(cmd) == _IOC_NR(EVIOCGNAME(0))) {
-				int len;
-				if (!dev->name) return -ENOENT;
-				len = strlen(dev->name) + 1;
-				if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
-				return copy_to_user(p, dev->name, len) ? -EFAULT : len;
-			}
+				if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSND(0))) {
+					int len;
+					len = NBITS(SND_MAX) * sizeof(long);
+					if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
+					return copy_to_user(p, dev->snd, len) ? -EFAULT : len;
+				}
+
+				if (_IOC_NR(cmd) == _IOC_NR(EVIOCGNAME(0))) {
+					int len;
+					if (!dev->name) return -ENOENT;
+					len = strlen(dev->name) + 1;
+					if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
+					return copy_to_user(p, dev->name, len) ? -EFAULT : len;
+				}
+
+				if (_IOC_NR(cmd) == _IOC_NR(EVIOCGPHYS(0))) {
+					int len;
+					if (!dev->phys) return -ENOENT;
+					len = strlen(dev->phys) + 1;
+					if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
+					return copy_to_user(p, dev->phys, len) ? -EFAULT : len;
+				}
+
+				if (_IOC_NR(cmd) == _IOC_NR(EVIOCGUNIQ(0))) {
+					int len;
+					if (!dev->uniq) return -ENOENT;
+					len = strlen(dev->uniq) + 1;
+					if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
+					return copy_to_user(p, dev->uniq, len) ? -EFAULT : len;
+				}
+
+				if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCGABS(0))) {
+
+					int t = _IOC_NR(cmd) & ABS_MAX;
+
+					abs.value = dev->abs[t];
+					abs.minimum = dev->absmin[t];
+					abs.maximum = dev->absmax[t];
+					abs.fuzz = dev->absfuzz[t];
+					abs.flat = dev->absflat[t];
+
+					if (copy_to_user(p, &abs, sizeof(struct input_absinfo)))
+						return -EFAULT;
+
+					return 0;
+				}
 
-			if (_IOC_NR(cmd) == _IOC_NR(EVIOCGPHYS(0))) {
-				int len;
-				if (!dev->phys) return -ENOENT;
-				len = strlen(dev->phys) + 1;
-				if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
-				return copy_to_user(p, dev->phys, len) ? -EFAULT : len;
 			}
 
-			if (_IOC_NR(cmd) == _IOC_NR(EVIOCGUNIQ(0))) {
-				int len;
-				if (!dev->uniq) return -ENOENT;
-				len = strlen(dev->uniq) + 1;
-				if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
-				return copy_to_user(p, dev->uniq, len) ? -EFAULT : len;
+			if (_IOC_DIR(cmd) == _IOC_WRITE) {
+
+				if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCSABS(0))) {
+
+					int t = _IOC_NR(cmd) & ABS_MAX;
+
+					if (copy_from_user(&abs, p, sizeof(struct input_absinfo)))
+						return -EFAULT;
+
+					dev->abs[t] = abs.value;
+					dev->absmin[t] = abs.minimum;
+					dev->absmax[t] = abs.maximum;
+					dev->absfuzz[t] = abs.fuzz;
+					dev->absflat[t] = abs.flat;
+
+					return 0;
+				}
 			}
+	}
+	return -EINVAL;
+}
 
-			if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCGABS(0))) {
+#ifdef CONFIG_COMPAT
 
-				int t = _IOC_NR(cmd) & ABS_MAX;
+#define BITS_PER_LONG_COMPAT (sizeof(compat_long_t) * 8)
+#define NBITS_COMPAT(x) ((((x)-1)/BITS_PER_LONG_COMPAT)+1)
+#define OFF_COMPAT(x)  ((x)%BITS_PER_LONG_COMPAT)
+#define BIT_COMPAT(x)  (1UL<<OFF_COMPAT(x))
+#define LONG_COMPAT(x) ((x)/BITS_PER_LONG_COMPAT)
+#define test_bit_compat(bit, array) ((array[LONG_COMPAT(bit)] >> OFF_COMPAT(bit)) & 1)
+
+#ifdef __BIG_ENDIAN
+#define bit_to_user(bit, max) \
+do { \
+	int i; \
+	int len = NBITS_COMPAT((max)) * sizeof(compat_long_t); \
+	if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd); \
+	for (i = 0; i < len / sizeof(compat_long_t); i++) \
+		if (copy_to_user((compat_long_t*) p + i, \
+				 (compat_long_t*) (bit) + i + 1 - ((i % 2) << 1), \
+				 sizeof(compat_long_t))) \
+			return -EFAULT; \
+	return len; \
+} while (0)
+#else
+#define bit_to_user(bit, max) \
+do { \
+	int len = NBITS_COMPAT((max)) * sizeof(compat_long_t); \
+	if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd); \
+	return copy_to_user(p, (bit), len) ? -EFAULT : len; \
+} while (0)
+#endif
 
-				abs.value = dev->abs[t];
-				abs.minimum = dev->absmin[t];
-				abs.maximum = dev->absmax[t];
-				abs.fuzz = dev->absfuzz[t];
-				abs.flat = dev->absflat[t];
+static long evdev_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg)
+{
+	struct evdev_list *list = file->private_data;
+	struct evdev *evdev = list->evdev;
+	struct input_dev *dev = evdev->handle.dev;
+	struct input_absinfo abs;
+	void __user *p = compat_ptr(arg);
 
-				if (copy_to_user(p, &abs, sizeof(struct input_absinfo)))
-					return -EFAULT;
+	if (!evdev->exist) return -ENODEV;
 
-				return 0;
+	switch (cmd) {
+
+		case EVIOCGVERSION:
+		case EVIOCGID:
+		case EVIOCGKEYCODE:
+		case EVIOCSKEYCODE:
+		case EVIOCSFF:
+		case EVIOCRMFF:
+		case EVIOCGEFFECTS:
+		case EVIOCGRAB:
+			return evdev_ioctl(file, cmd, (unsigned long) p);
+
+		default:
+
+			if (_IOC_TYPE(cmd) != 'E')
+				return -EINVAL;
+
+			if (_IOC_DIR(cmd) == _IOC_READ) {
+
+				if ((_IOC_NR(cmd) & ~EV_MAX) == _IOC_NR(EVIOCGBIT(0,0))) {
+					long *bits;
+					int max;
+
+					switch (_IOC_NR(cmd) & EV_MAX) {
+						case      0: bits = dev->evbit;  max = EV_MAX;  break;
+						case EV_KEY: bits = dev->keybit; max = KEY_MAX; break;
+						case EV_REL: bits = dev->relbit; max = REL_MAX; break;
+						case EV_ABS: bits = dev->absbit; max = ABS_MAX; break;
+						case EV_MSC: bits = dev->mscbit; max = MSC_MAX; break;
+						case EV_LED: bits = dev->ledbit; max = LED_MAX; break;
+						case EV_SND: bits = dev->sndbit; max = SND_MAX; break;
+						case EV_FF:  bits = dev->ffbit;  max = FF_MAX;  break;
+						default: return -EINVAL;
+					}
+					bit_to_user(bits, max);
+				}
+
+				if (_IOC_NR(cmd) == _IOC_NR(EVIOCGKEY(0)))
+					bit_to_user(dev->key, KEY_MAX);
+
+				if (_IOC_NR(cmd) == _IOC_NR(EVIOCGLED(0)))
+					bit_to_user(dev->led, LED_MAX);
+
+				if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSND(0)))
+					bit_to_user(dev->snd, SND_MAX);
+
+				if (_IOC_NR(cmd) == _IOC_NR(EVIOCGNAME(0))) {
+					int len;
+					if (!dev->name) return -ENOENT;
+					len = strlen(dev->name) + 1;
+					if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
+					return copy_to_user(p, dev->name, len) ? -EFAULT : len;
+				}
+
+				if (_IOC_NR(cmd) == _IOC_NR(EVIOCGPHYS(0))) {
+					int len;
+					if (!dev->phys) return -ENOENT;
+					len = strlen(dev->phys) + 1;
+					if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
+					return copy_to_user(p, dev->phys, len) ? -EFAULT : len;
+				}
+
+				if (_IOC_NR(cmd) == _IOC_NR(EVIOCGUNIQ(0))) {
+					int len;
+					if (!dev->uniq) return -ENOENT;
+					len = strlen(dev->uniq) + 1;
+					if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
+					return copy_to_user(p, dev->uniq, len) ? -EFAULT : len;
+				}
+
+				if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCGABS(0))) {
+
+					int t = _IOC_NR(cmd) & ABS_MAX;
+
+					abs.value = dev->abs[t];
+					abs.minimum = dev->absmin[t];
+					abs.maximum = dev->absmax[t];
+					abs.fuzz = dev->absfuzz[t];
+					abs.flat = dev->absflat[t];
+
+					if (copy_to_user(p, &abs, sizeof(struct input_absinfo)))
+						return -EFAULT;
+
+					return 0;
+				}
 			}
 
-			if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCSABS(0))) {
+			if (_IOC_DIR(cmd) == _IOC_WRITE) {
 
-				int t = _IOC_NR(cmd) & ABS_MAX;
+				if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCSABS(0))) {
 
-				if (copy_from_user(&abs, p, sizeof(struct input_absinfo)))
-					return -EFAULT;
+					int t = _IOC_NR(cmd) & ABS_MAX;
 
-				dev->abs[t] = abs.value;
-				dev->absmin[t] = abs.minimum;
-				dev->absmax[t] = abs.maximum;
-				dev->absfuzz[t] = abs.fuzz;
-				dev->absflat[t] = abs.flat;
+					if (copy_from_user(&abs, p, sizeof(struct input_absinfo)))
+						return -EFAULT;
 
-				return 0;
+					dev->abs[t] = abs.value;
+					dev->absmin[t] = abs.minimum;
+					dev->absmax[t] = abs.maximum;
+					dev->absfuzz[t] = abs.fuzz;
+					dev->absflat[t] = abs.flat;
+
+					return 0;
+				}
 			}
 	}
 	return -EINVAL;
 }
+#endif
 
 static struct file_operations evdev_fops = {
 	.owner =	THIS_MODULE,
@@ -396,7 +641,10 @@ static struct file_operations evdev_fops
 	.poll =		evdev_poll,
 	.open =		evdev_open,
 	.release =	evdev_release,
-	.ioctl =	evdev_ioctl,
+	.unlocked_ioctl = evdev_ioctl,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl =	evdev_ioctl_compat,
+#endif
 	.fasync =	evdev_fasync,
 	.flush =	evdev_flush
 };
@@ -431,9 +679,9 @@ static struct input_handle *evdev_connec
 
 	devfs_mk_cdev(MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor),
 			S_IFCHR|S_IRUGO|S_IWUSR, "input/event%d", minor);
-	class_simple_device_add(input_class,
-				MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor),
-				dev->dev, "event%d", minor);
+	class_device_create(input_class,
+			MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor),
+			dev->dev, "event%d", minor);
 
 	return &evdev->handle;
 }
@@ -443,7 +691,8 @@ static void evdev_disconnect(struct inpu
 	struct evdev *evdev = handle->private;
 	struct evdev_list *list;
 
-	class_simple_device_remove(MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + evdev->minor));
+	class_device_destroy(input_class,
+			MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + evdev->minor));
 	devfs_remove("input/event%d", evdev->minor);
 	evdev->exist = 0;
 
diff --git a/drivers/input/gameport/Kconfig b/drivers/input/gameport/Kconfig
--- a/drivers/input/gameport/Kconfig
+++ b/drivers/input/gameport/Kconfig
@@ -49,22 +49,8 @@ config GAMEPORT_EMU10K1
 	  To compile this driver as a module, choose M here: the
 	  module will be called emu10k1-gp.
 
-config GAMEPORT_VORTEX
-	tristate "Aureal Vortex, Vortex 2 gameport support"
-	depends on PCI
-	help
-	  Say Y here if you have an Aureal Vortex 1 or 2  card and want
-	  to use its gameport.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called vortex.
-
 config GAMEPORT_FM801
 	tristate "ForteMedia FM801 gameport support"
 	depends on PCI
 
-config GAMEPORT_CS461X
-	tristate "Crystal SoundFusion gameport support"
-	depends on PCI
-
 endif
diff --git a/drivers/input/gameport/Makefile b/drivers/input/gameport/Makefile
--- a/drivers/input/gameport/Makefile
+++ b/drivers/input/gameport/Makefile
@@ -5,9 +5,7 @@
 # Each configuration option enables a list of files.
 
 obj-$(CONFIG_GAMEPORT)		+= gameport.o
-obj-$(CONFIG_GAMEPORT_CS461X)	+= cs461x.o
 obj-$(CONFIG_GAMEPORT_EMU10K1)	+= emu10k1-gp.o
 obj-$(CONFIG_GAMEPORT_FM801)	+= fm801-gp.o
 obj-$(CONFIG_GAMEPORT_L4)	+= lightning.o
 obj-$(CONFIG_GAMEPORT_NS558)	+= ns558.o
-obj-$(CONFIG_GAMEPORT_VORTEX)	+= vortex.o
diff --git a/drivers/input/gameport/cs461x.c b/drivers/input/gameport/cs461x.c
deleted file mode 100644
--- a/drivers/input/gameport/cs461x.c
+++ /dev/null
@@ -1,322 +0,0 @@
-/*
-	The all defines and part of code (such as cs461x_*) are
-	contributed from ALSA 0.5.8 sources.
-	See http://www.alsa-project.org/ for sources
-
-	Tested on Linux 686 2.4.0-test9, ALSA 0.5.8a and CS4610
-*/
-
-#include <asm/io.h>
-
-#include <linux/module.h>
-#include <linux/ioport.h>
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/gameport.h>
-#include <linux/slab.h>
-#include <linux/pci.h>
-
-MODULE_AUTHOR("Victor Krapivin");
-MODULE_LICENSE("GPL");
-
-/*
-	These options are experimental
-
-#define CS461X_FULL_MAP
-*/
-
-
-#ifndef PCI_VENDOR_ID_CIRRUS
-#define PCI_VENDOR_ID_CIRRUS            0x1013
-#endif
-#ifndef PCI_DEVICE_ID_CIRRUS_4610
-#define PCI_DEVICE_ID_CIRRUS_4610       0x6001
-#endif
-#ifndef PCI_DEVICE_ID_CIRRUS_4612
-#define PCI_DEVICE_ID_CIRRUS_4612       0x6003
-#endif
-#ifndef PCI_DEVICE_ID_CIRRUS_4615
-#define PCI_DEVICE_ID_CIRRUS_4615       0x6004
-#endif
-
-/* Registers */
-
-#define BA0_JSPT                                0x00000480
-#define BA0_JSCTL                               0x00000484
-#define BA0_JSC1                                0x00000488
-#define BA0_JSC2                                0x0000048C
-#define BA0_JSIO                                0x000004A0
-
-/* Bits for JSPT */
-
-#define JSPT_CAX                                0x00000001
-#define JSPT_CAY                                0x00000002
-#define JSPT_CBX                                0x00000004
-#define JSPT_CBY                                0x00000008
-#define JSPT_BA1                                0x00000010
-#define JSPT_BA2                                0x00000020
-#define JSPT_BB1                                0x00000040
-#define JSPT_BB2                                0x00000080
-
-/* Bits for JSCTL */
-
-#define JSCTL_SP_MASK                           0x00000003
-#define JSCTL_SP_SLOW                           0x00000000
-#define JSCTL_SP_MEDIUM_SLOW                    0x00000001
-#define JSCTL_SP_MEDIUM_FAST                    0x00000002
-#define JSCTL_SP_FAST                           0x00000003
-#define JSCTL_ARE                               0x00000004
-
-/* Data register pairs masks */
-
-#define JSC1_Y1V_MASK                           0x0000FFFF
-#define JSC1_X1V_MASK                           0xFFFF0000
-#define JSC1_Y1V_SHIFT                          0
-#define JSC1_X1V_SHIFT                          16
-#define JSC2_Y2V_MASK                           0x0000FFFF
-#define JSC2_X2V_MASK                           0xFFFF0000
-#define JSC2_Y2V_SHIFT                          0
-#define JSC2_X2V_SHIFT                          16
-
-/* JS GPIO */
-
-#define JSIO_DAX                                0x00000001
-#define JSIO_DAY                                0x00000002
-#define JSIO_DBX                                0x00000004
-#define JSIO_DBY                                0x00000008
-#define JSIO_AXOE                               0x00000010
-#define JSIO_AYOE                               0x00000020
-#define JSIO_BXOE                               0x00000040
-#define JSIO_BYOE                               0x00000080
-
-/*
-   The card initialization code is obfuscated; the module cs461x
-   need to be loaded after ALSA modules initialized and something
-   played on the CS 4610 chip (see sources for details of CS4610
-   initialization code from ALSA)
-*/
-
-/* Card specific definitions */
-
-#define CS461X_BA0_SIZE         0x2000
-#define CS461X_BA1_DATA0_SIZE   0x3000
-#define CS461X_BA1_DATA1_SIZE   0x3800
-#define CS461X_BA1_PRG_SIZE     0x7000
-#define CS461X_BA1_REG_SIZE     0x0100
-
-#define BA1_SP_DMEM0                            0x00000000
-#define BA1_SP_DMEM1                            0x00010000
-#define BA1_SP_PMEM                             0x00020000
-#define BA1_SP_REG                              0x00030000
-
-#define BA1_DWORD_SIZE          (13 * 1024 + 512)
-#define BA1_MEMORY_COUNT        3
-
-/*
-   Only one CS461x card is still suppoted; the code requires
-   redesign to avoid this limitatuion.
-*/
-
-static unsigned long ba0_addr;
-static unsigned int __iomem *ba0;
-
-#ifdef CS461X_FULL_MAP
-static unsigned long ba1_addr;
-static union ba1_t {
-        struct {
-                unsigned int __iomem *data0;
-                unsigned int __iomem *data1;
-                unsigned int __iomem *pmem;
-                unsigned int __iomem *reg;
-        } name;
-        unsigned int __iomem *idx[4];
-} ba1;
-
-static void cs461x_poke(unsigned long reg, unsigned int val)
-{
-        writel(val, &ba1.idx[(reg >> 16) & 3][(reg >> 2) & 0x3fff]);
-}
-
-static unsigned int cs461x_peek(unsigned long reg)
-{
-        return readl(&ba1.idx[(reg >> 16) & 3][(reg >> 2) & 0x3fff]);
-}
-
-#endif
-
-static void cs461x_pokeBA0(unsigned long reg, unsigned int val)
-{
-        writel(val, &ba0[reg >> 2]);
-}
-
-static unsigned int cs461x_peekBA0(unsigned long reg)
-{
-        return readl(&ba0[reg >> 2]);
-}
-
-static int cs461x_free(struct pci_dev *pdev)
-{
-	struct gameport *port = pci_get_drvdata(pdev);
-
-	if (port)
-	    gameport_unregister_port(port);
-
-	if (ba0) iounmap(ba0);
-#ifdef CS461X_FULL_MAP
-	if (ba1.name.data0) iounmap(ba1.name.data0);
-	if (ba1.name.data1) iounmap(ba1.name.data1);
-	if (ba1.name.pmem)  iounmap(ba1.name.pmem);
-	if (ba1.name.reg)   iounmap(ba1.name.reg);
-#endif
-	return 0;
-}
-
-static void cs461x_gameport_trigger(struct gameport *gameport)
-{
-	cs461x_pokeBA0(BA0_JSPT, 0xFF);  //outb(gameport->io, 0xFF);
-}
-
-static unsigned char cs461x_gameport_read(struct gameport *gameport)
-{
-	return cs461x_peekBA0(BA0_JSPT); //inb(gameport->io);
-}
-
-static int cs461x_gameport_cooked_read(struct gameport *gameport, int *axes, int *buttons)
-{
-	unsigned js1, js2, jst;
-
-	js1 = cs461x_peekBA0(BA0_JSC1);
-	js2 = cs461x_peekBA0(BA0_JSC2);
-	jst = cs461x_peekBA0(BA0_JSPT);
-
-	*buttons = (~jst >> 4) & 0x0F;
-
-	axes[0] = ((js1 & JSC1_Y1V_MASK) >> JSC1_Y1V_SHIFT) & 0xFFFF;
-	axes[1] = ((js1 & JSC1_X1V_MASK) >> JSC1_X1V_SHIFT) & 0xFFFF;
-	axes[2] = ((js2 & JSC2_Y2V_MASK) >> JSC2_Y2V_SHIFT) & 0xFFFF;
-	axes[3] = ((js2 & JSC2_X2V_MASK) >> JSC2_X2V_SHIFT) & 0xFFFF;
-
-	for(jst=0;jst<4;++jst)
-		if(axes[jst]==0xFFFF) axes[jst] = -1;
-	return 0;
-}
-
-static int cs461x_gameport_open(struct gameport *gameport, int mode)
-{
-	switch (mode) {
-		case GAMEPORT_MODE_COOKED:
-		case GAMEPORT_MODE_RAW:
-			return 0;
-		default:
-			return -1;
-	}
-	return 0;
-}
-
-static struct pci_device_id cs461x_pci_tbl[] = {
-	{ PCI_VENDOR_ID_CIRRUS, 0x6001, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* Cirrus CS4610 */
-	{ PCI_VENDOR_ID_CIRRUS, 0x6003, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* Cirrus CS4612 */
-	{ PCI_VENDOR_ID_CIRRUS, 0x6005, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* Cirrus CS4615 */
-	{ 0, }
-};
-MODULE_DEVICE_TABLE(pci, cs461x_pci_tbl);
-
-static int __devinit cs461x_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
-{
-	int rc;
-	struct gameport* port;
-
-	rc = pci_enable_device(pdev);
-	if (rc) {
-		printk(KERN_ERR "cs461x: Cannot enable PCI gameport (bus %d, devfn %d) error=%d\n",
-			pdev->bus->number, pdev->devfn, rc);
-		return rc;
-	}
-
-	ba0_addr = pci_resource_start(pdev, 0);
-#ifdef CS461X_FULL_MAP
-	ba1_addr = pci_resource_start(pdev, 1);
-#endif
-	if (ba0_addr == 0 || ba0_addr == ~0
-#ifdef CS461X_FULL_MAP
-            || ba1_addr == 0 || ba1_addr == ~0
-#endif
-	    ) {
-                printk(KERN_ERR "cs461x: wrong address - ba0 = 0x%lx\n", ba0_addr);
-#ifdef CS461X_FULL_MAP
-                printk(KERN_ERR "cs461x: wrong address - ba1 = 0x%lx\n", ba1_addr);
-#endif
-		cs461x_free(pdev);
-                return -ENOMEM;
-        }
-
-	ba0 = ioremap(ba0_addr, CS461X_BA0_SIZE);
-#ifdef CS461X_FULL_MAP
-	ba1.name.data0 = ioremap(ba1_addr + BA1_SP_DMEM0, CS461X_BA1_DATA0_SIZE);
-	ba1.name.data1 = ioremap(ba1_addr + BA1_SP_DMEM1, CS461X_BA1_DATA1_SIZE);
-	ba1.name.pmem  = ioremap(ba1_addr + BA1_SP_PMEM, CS461X_BA1_PRG_SIZE);
-	ba1.name.reg   = ioremap(ba1_addr + BA1_SP_REG, CS461X_BA1_REG_SIZE);
-
-	if (ba0 == NULL || ba1.name.data0 == NULL ||
-            ba1.name.data1 == NULL || ba1.name.pmem == NULL ||
-            ba1.name.reg == NULL) {
-		cs461x_free(pdev);
-                return -ENOMEM;
-        }
-#else
-	if (ba0 == NULL) {
-		cs461x_free(pdev);
-		return -ENOMEM;
-	}
-#endif
-
-	if (!(port = gameport_allocate_port())) {
-		printk(KERN_ERR "cs461x: Memory allocation failed\n");
-		cs461x_free(pdev);
-		return -ENOMEM;
-	}
-
-	pci_set_drvdata(pdev, port);
-
-	port->open = cs461x_gameport_open;
-	port->trigger = cs461x_gameport_trigger;
-	port->read = cs461x_gameport_read;
-	port->cooked_read = cs461x_gameport_cooked_read;
-
-	gameport_set_name(port, "CS416x");
-	gameport_set_phys(port, "pci%s/gameport0", pci_name(pdev));
-	port->dev.parent = &pdev->dev;
-
-	cs461x_pokeBA0(BA0_JSIO, 0xFF); // ?
-	cs461x_pokeBA0(BA0_JSCTL, JSCTL_SP_MEDIUM_SLOW);
-
-	gameport_register_port(port);
-
-	return 0;
-}
-
-static void __devexit cs461x_pci_remove(struct pci_dev *pdev)
-{
-	cs461x_free(pdev);
-}
-
-static struct pci_driver cs461x_pci_driver = {
-        .name =         "CS461x_gameport",
-        .id_table =     cs461x_pci_tbl,
-        .probe =        cs461x_pci_probe,
-        .remove =       __devexit_p(cs461x_pci_remove),
-};
-
-static int __init cs461x_init(void)
-{
-        return pci_register_driver(&cs461x_pci_driver);
-}
-
-static void __exit cs461x_exit(void)
-{
-        pci_unregister_driver(&cs461x_pci_driver);
-}
-
-module_init(cs461x_init);
-module_exit(cs461x_exit);
-
diff --git a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c
--- a/drivers/input/gameport/gameport.c
+++ b/drivers/input/gameport/gameport.c
@@ -17,11 +17,10 @@
 #include <linux/init.h>
 #include <linux/gameport.h>
 #include <linux/wait.h>
-#include <linux/completion.h>
 #include <linux/sched.h>
-#include <linux/smp_lock.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
+#include <linux/kthread.h>
 
 /*#include <asm/io.h>*/
 
@@ -61,12 +60,13 @@ static void gameport_disconnect_port(str
 
 #if defined(__i386__)
 
+#include <asm/i8253.h>
+
 #define DELTA(x,y)      ((y)-(x)+((y)<(x)?1193182/HZ:0))
 #define GET_TIME(x)     do { x = get_time_pit(); } while (0)
 
 static unsigned int get_time_pit(void)
 {
-	extern spinlock_t i8253_lock;
 	unsigned long flags;
 	unsigned int count;
 
@@ -134,7 +134,7 @@ static int gameport_measure_speed(struct
 	}
 
 	gameport_close(gameport);
-	return (cpu_data[_smp_processor_id()].loops_per_jiffy * (unsigned long)HZ / (1000 / 50)) / (tx < 1 ? 1 : tx);
+	return (cpu_data[raw_smp_processor_id()].loops_per_jiffy * (unsigned long)HZ / (1000 / 50)) / (tx < 1 ? 1 : tx);
 
 #else
 
@@ -238,8 +238,7 @@ struct gameport_event {
 static DEFINE_SPINLOCK(gameport_event_lock);	/* protects gameport_event_list */
 static LIST_HEAD(gameport_event_list);
 static DECLARE_WAIT_QUEUE_HEAD(gameport_wait);
-static DECLARE_COMPLETION(gameport_exited);
-static int gameport_pid;
+static struct task_struct *gameport_task;
 
 static void gameport_queue_event(void *object, struct module *owner,
 			      enum gameport_event_type event_type)
@@ -250,12 +249,12 @@ static void gameport_queue_event(void *o
 	spin_lock_irqsave(&gameport_event_lock, flags);
 
 	/*
- 	 * Scan event list for the other events for the same gameport port,
+	 * Scan event list for the other events for the same gameport port,
 	 * starting with the most recent one. If event is the same we
 	 * do not need add new one. If event is of different type we
 	 * need to add this event and should not look further because
 	 * we need to preseve sequence of distinct events.
- 	 */
+	 */
 	list_for_each_entry_reverse(event, &gameport_event_list, node) {
 		if (event->object == object) {
 			if (event->type == event_type)
@@ -432,20 +431,15 @@ static struct gameport *gameport_get_pen
 
 static int gameport_thread(void *nothing)
 {
-	lock_kernel();
-	daemonize("kgameportd");
-	allow_signal(SIGTERM);
-
 	do {
 		gameport_handle_events();
-		wait_event_interruptible(gameport_wait, !list_empty(&gameport_event_list));
-		try_to_freeze(PF_FREEZE);
-	} while (!signal_pending(current));
+		wait_event_interruptible(gameport_wait,
+			kthread_should_stop() || !list_empty(&gameport_event_list));
+		try_to_freeze();
+	} while (!kthread_should_stop());
 
 	printk(KERN_DEBUG "gameport: kgameportd exiting\n");
-
-	unlock_kernel();
-	complete_and_exit(&gameport_exited, 0);
+	return 0;
 }
 
 
@@ -453,13 +447,13 @@ static int gameport_thread(void *nothing
  * Gameport port operations
  */
 
-static ssize_t gameport_show_description(struct device *dev, char *buf)
+static ssize_t gameport_show_description(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct gameport *gameport = to_gameport_port(dev);
 	return sprintf(buf, "%s\n", gameport->name);
 }
 
-static ssize_t gameport_rebind_driver(struct device *dev, const char *buf, size_t count)
+static ssize_t gameport_rebind_driver(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct gameport *gameport = to_gameport_port(dev);
 	struct device_driver *drv;
@@ -773,9 +767,10 @@ void gameport_close(struct gameport *gam
 
 static int __init gameport_init(void)
 {
-	if (!(gameport_pid = kernel_thread(gameport_thread, NULL, CLONE_KERNEL))) {
+	gameport_task = kthread_run(gameport_thread, NULL, "kgameportd");
+	if (IS_ERR(gameport_task)) {
 		printk(KERN_ERR "gameport: Failed to start kgameportd\n");
-		return -1;
+		return PTR_ERR(gameport_task);
 	}
 
 	gameport_bus.dev_attrs = gameport_device_attrs;
@@ -789,8 +784,7 @@ static int __init gameport_init(void)
 static void __exit gameport_exit(void)
 {
 	bus_unregister(&gameport_bus);
-	kill_proc(gameport_pid, SIGTERM, 1);
-	wait_for_completion(&gameport_exited);
+	kthread_stop(gameport_task);
 }
 
 module_init(gameport_init);
diff --git a/drivers/input/gameport/ns558.c b/drivers/input/gameport/ns558.c
--- a/drivers/input/gameport/ns558.c
+++ b/drivers/input/gameport/ns558.c
@@ -258,26 +258,26 @@ static int __init ns558_init(void)
 {
 	int i = 0;
 
+	if (pnp_register_driver(&ns558_pnp_driver) >= 0)
+		pnp_registered = 1;
+
 /*
- * Probe ISA ports first so that PnP gets to choose free port addresses
- * not occupied by the ISA ports.
+ * Probe ISA ports after PnP, so that PnP ports that are already
+ * enabled get detected as PnP. This may be suboptimal in multi-device
+ * configurations, but saves hassle with simple setups.
  */
 
 	while (ns558_isa_portlist[i])
 		ns558_isa_probe(ns558_isa_portlist[i++]);
 
-	if (pnp_register_driver(&ns558_pnp_driver) >= 0)
-		pnp_registered = 1;
-
-
 	return (list_empty(&ns558_list) && !pnp_registered) ? -ENODEV : 0;
 }
 
 static void __exit ns558_exit(void)
 {
-	struct ns558 *ns558;
+	struct ns558 *ns558, *safe;
 
-	list_for_each_entry(ns558, &ns558_list, node) {
+	list_for_each_entry_safe(ns558, safe, &ns558_list, node) {
 		gameport_unregister_port(ns558->gameport);
 		release_region(ns558->io & ~(ns558->size - 1), ns558->size);
 		kfree(ns558);
diff --git a/drivers/input/gameport/vortex.c b/drivers/input/gameport/vortex.c
deleted file mode 100644
--- a/drivers/input/gameport/vortex.c
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * $Id: vortex.c,v 1.5 2002/07/01 15:39:30 vojtech Exp $
- *
- *  Copyright (c) 2000-2001 Vojtech Pavlik
- *
- *  Based on the work of:
- *	Raymond Ingles
- */
-
-/*
- * Trident 4DWave and Aureal Vortex gameport driver for Linux
- */
-
-/*
- * 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
- *
- * Should you need to contact me, the author, you can do so either by
- * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
- * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
- */
-
-#include <asm/io.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/ioport.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/gameport.h>
-
-MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
-MODULE_DESCRIPTION("Aureal Vortex and Vortex2 gameport driver");
-MODULE_LICENSE("GPL");
-
-#define VORTEX_GCR		0x0c	/* Gameport control register */
-#define VORTEX_LEG		0x08	/* Legacy port location */
-#define VORTEX_AXD		0x10	/* Axes start */
-#define VORTEX_DATA_WAIT	20	/* 20 ms */
-
-struct vortex {
-	struct gameport *gameport;
-	struct pci_dev *dev;
-	unsigned char __iomem *base;
-	unsigned char __iomem *io;
-};
-
-static unsigned char vortex_read(struct gameport *gameport)
-{
-	struct vortex *vortex = gameport->port_data;
-	return readb(vortex->io + VORTEX_LEG);
-}
-
-static void vortex_trigger(struct gameport *gameport)
-{
-	struct vortex *vortex = gameport->port_data;
-	writeb(0xff, vortex->io + VORTEX_LEG);
-}
-
-static int vortex_cooked_read(struct gameport *gameport, int *axes, int *buttons)
-{
-	struct vortex *vortex = gameport->port_data;
-	int i;
-
-	*buttons = (~readb(vortex->base + VORTEX_LEG) >> 4) & 0xf;
-
-	for (i = 0; i < 4; i++) {
-		axes[i] = readw(vortex->io + VORTEX_AXD + i * sizeof(u32));
-		if (axes[i] == 0x1fff) axes[i] = -1;
-	}
-
-        return 0;
-}
-
-static int vortex_open(struct gameport *gameport, int mode)
-{
-	struct vortex *vortex = gameport->port_data;
-
-	switch (mode) {
-		case GAMEPORT_MODE_COOKED:
-			writeb(0x40, vortex->io + VORTEX_GCR);
-			msleep(VORTEX_DATA_WAIT);
-			return 0;
-		case GAMEPORT_MODE_RAW:
-			writeb(0x00, vortex->io + VORTEX_GCR);
-			return 0;
-		default:
-			return -1;
-	}
-
-	return 0;
-}
-
-static int __devinit vortex_probe(struct pci_dev *dev, const struct pci_device_id *id)
-{
-	struct vortex *vortex;
-	struct gameport *port;
-	int i;
-
-	vortex = kcalloc(1, sizeof(struct vortex), GFP_KERNEL);
-	port = gameport_allocate_port();
-	if (!vortex || !port) {
-		printk(KERN_ERR "vortex: Memory allocation failed.\n");
-		kfree(vortex);
-		gameport_free_port(port);
-		return -ENOMEM;
-	}
-
-	for (i = 0; i < 6; i++)
-		if (~pci_resource_flags(dev, i) & IORESOURCE_IO)
-			break;
-
-	pci_enable_device(dev);
-
-	vortex->dev = dev;
-	vortex->gameport = port;
-	vortex->base = ioremap(pci_resource_start(vortex->dev, i),
-				pci_resource_len(vortex->dev, i));
-	vortex->io = vortex->base + id->driver_data;
-
-	pci_set_drvdata(dev, vortex);
-
-	port->port_data = vortex;
-	port->fuzz = 64;
-
-	gameport_set_name(port, "AU88x0");
-	gameport_set_phys(port, "pci%s/gameport0", pci_name(dev));
-	port->dev.parent = &dev->dev;
-	port->read = vortex_read;
-	port->trigger = vortex_trigger;
-	port->cooked_read = vortex_cooked_read;
-	port->open = vortex_open;
-
-	gameport_register_port(port);
-
-	return 0;
-}
-
-static void __devexit vortex_remove(struct pci_dev *dev)
-{
-	struct vortex *vortex = pci_get_drvdata(dev);
-
-	gameport_unregister_port(vortex->gameport);
-	iounmap(vortex->base);
-	kfree(vortex);
-}
-
-static struct pci_device_id vortex_id_table[] = {
-	{ 0x12eb, 0x0001, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0x11000 },
-	{ 0x12eb, 0x0002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0x28800 },
-	{ 0 }
-};
-
-static struct pci_driver vortex_driver = {
-	.name =		"vortex_gameport",
-	.id_table =	vortex_id_table,
-	.probe =	vortex_probe,
-	.remove =	__devexit_p(vortex_remove),
-};
-
-static int __init vortex_init(void)
-{
-	return pci_register_driver(&vortex_driver);
-}
-
-static void __exit vortex_exit(void)
-{
-	pci_unregister_driver(&vortex_driver);
-}
-
-module_init(vortex_init);
-module_exit(vortex_exit);
diff --git a/drivers/input/input.c b/drivers/input/input.c
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -48,12 +48,6 @@ static LIST_HEAD(input_handler_list);
 
 static struct input_handler *input_table[8];
 
-#ifdef CONFIG_PROC_FS
-static struct proc_dir_entry *proc_bus_input_dir;
-static DECLARE_WAIT_QUEUE_HEAD(input_devices_poll_wait);
-static int input_devices_state;
-#endif
-
 void input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
 {
 	struct input_handle *handle;
@@ -219,10 +213,24 @@ void input_release_device(struct input_h
 
 int input_open_device(struct input_handle *handle)
 {
+	struct input_dev *dev = handle->dev;
+	int err;
+
+	err = down_interruptible(&dev->sem);
+	if (err)
+		return err;
+
 	handle->open++;
-	if (handle->dev->open)
-		return handle->dev->open(handle->dev);
-	return 0;
+
+	if (!dev->users++ && dev->open)
+		err = dev->open(dev);
+
+	if (err)
+		handle->open--;
+
+	up(&dev->sem);
+
+	return err;
 }
 
 int input_flush_device(struct input_handle* handle, struct file* file)
@@ -235,10 +243,17 @@ int input_flush_device(struct input_hand
 
 void input_close_device(struct input_handle *handle)
 {
+	struct input_dev *dev = handle->dev;
+
 	input_release_device(handle);
-	if (handle->dev->close)
-		handle->dev->close(handle->dev);
+
+	down(&dev->sem);
+
+	if (!--dev->users && dev->close)
+		dev->close(dev);
 	handle->open--;
+
+	up(&dev->sem);
 }
 
 static void input_link_handle(struct input_handle *handle)
@@ -291,6 +306,7 @@ static struct input_device_id *input_mat
 	return NULL;
 }
 
+
 /*
  * Input hotplugging interface - loading event handlers based on
  * device bitfields.
@@ -407,6 +423,177 @@ static void input_call_hotplug(char *ver
 
 #endif
 
+#ifdef CONFIG_PROC_FS
+
+static struct proc_dir_entry *proc_bus_input_dir;
+static DECLARE_WAIT_QUEUE_HEAD(input_devices_poll_wait);
+static int input_devices_state;
+
+static inline void input_wakeup_procfs_readers(void)
+{
+	input_devices_state++;
+	wake_up(&input_devices_poll_wait);
+}
+
+static unsigned int input_devices_poll(struct file *file, poll_table *wait)
+{
+	int state = input_devices_state;
+	poll_wait(file, &input_devices_poll_wait, wait);
+	if (state != input_devices_state)
+		return POLLIN | POLLRDNORM;
+	return 0;
+}
+
+#define SPRINTF_BIT_B(bit, name, max) \
+	do { \
+		len += sprintf(buf + len, "B: %s", name); \
+		for (i = NBITS(max) - 1; i >= 0; i--) \
+			if (dev->bit[i]) break; \
+		for (; i >= 0; i--) \
+			len += sprintf(buf + len, "%lx ", dev->bit[i]); \
+		len += sprintf(buf + len, "\n"); \
+	} while (0)
+
+#define SPRINTF_BIT_B2(bit, name, max, ev) \
+	do { \
+		if (test_bit(ev, dev->evbit)) \
+			SPRINTF_BIT_B(bit, name, max); \
+	} while (0)
+
+static int input_devices_read(char *buf, char **start, off_t pos, int count, int *eof, void *data)
+{
+	struct input_dev *dev;
+	struct input_handle *handle;
+
+	off_t at = 0;
+	int i, len, cnt = 0;
+
+	list_for_each_entry(dev, &input_dev_list, node) {
+
+		len = sprintf(buf, "I: Bus=%04x Vendor=%04x Product=%04x Version=%04x\n",
+			dev->id.bustype, dev->id.vendor, dev->id.product, dev->id.version);
+
+		len += sprintf(buf + len, "N: Name=\"%s\"\n", dev->name ? dev->name : "");
+		len += sprintf(buf + len, "P: Phys=%s\n", dev->phys ? dev->phys : "");
+		len += sprintf(buf + len, "H: Handlers=");
+
+		list_for_each_entry(handle, &dev->h_list, d_node)
+			len += sprintf(buf + len, "%s ", handle->name);
+
+		len += sprintf(buf + len, "\n");
+
+		SPRINTF_BIT_B(evbit, "EV=", EV_MAX);
+		SPRINTF_BIT_B2(keybit, "KEY=", KEY_MAX, EV_KEY);
+		SPRINTF_BIT_B2(relbit, "REL=", REL_MAX, EV_REL);
+		SPRINTF_BIT_B2(absbit, "ABS=", ABS_MAX, EV_ABS);
+		SPRINTF_BIT_B2(mscbit, "MSC=", MSC_MAX, EV_MSC);
+		SPRINTF_BIT_B2(ledbit, "LED=", LED_MAX, EV_LED);
+		SPRINTF_BIT_B2(sndbit, "SND=", SND_MAX, EV_SND);
+		SPRINTF_BIT_B2(ffbit,  "FF=",  FF_MAX, EV_FF);
+
+		len += sprintf(buf + len, "\n");
+
+		at += len;
+
+		if (at >= pos) {
+			if (!*start) {
+				*start = buf + (pos - (at - len));
+				cnt = at - pos;
+			} else  cnt += len;
+			buf += len;
+			if (cnt >= count)
+				break;
+		}
+	}
+
+	if (&dev->node == &input_dev_list)
+		*eof = 1;
+
+	return (count > cnt) ? cnt : count;
+}
+
+static int input_handlers_read(char *buf, char **start, off_t pos, int count, int *eof, void *data)
+{
+	struct input_handler *handler;
+
+	off_t at = 0;
+	int len = 0, cnt = 0;
+	int i = 0;
+
+	list_for_each_entry(handler, &input_handler_list, node) {
+
+		if (handler->fops)
+			len = sprintf(buf, "N: Number=%d Name=%s Minor=%d\n",
+				i++, handler->name, handler->minor);
+		else
+			len = sprintf(buf, "N: Number=%d Name=%s\n",
+				i++, handler->name);
+
+		at += len;
+
+		if (at >= pos) {
+			if (!*start) {
+				*start = buf + (pos - (at - len));
+				cnt = at - pos;
+			} else  cnt += len;
+			buf += len;
+			if (cnt >= count)
+				break;
+		}
+	}
+	if (&handler->node == &input_handler_list)
+		*eof = 1;
+
+	return (count > cnt) ? cnt : count;
+}
+
+static struct file_operations input_fileops;
+
+static int __init input_proc_init(void)
+{
+	struct proc_dir_entry *entry;
+
+	proc_bus_input_dir = proc_mkdir("input", proc_bus);
+	if (!proc_bus_input_dir)
+		return -ENOMEM;
+
+	proc_bus_input_dir->owner = THIS_MODULE;
+
+	entry = create_proc_read_entry("devices", 0, proc_bus_input_dir, input_devices_read, NULL);
+	if (!entry)
+		goto fail1;
+
+	entry->owner = THIS_MODULE;
+	input_fileops = *entry->proc_fops;
+	entry->proc_fops = &input_fileops;
+	entry->proc_fops->poll = input_devices_poll;
+
+	entry = create_proc_read_entry("handlers", 0, proc_bus_input_dir, input_handlers_read, NULL);
+	if (!entry)
+		goto fail2;
+
+	entry->owner = THIS_MODULE;
+
+	return 0;
+
+ fail2:	remove_proc_entry("devices", proc_bus_input_dir);
+ fail1: remove_proc_entry("input", proc_bus);
+	return -ENOMEM;
+}
+
+static void input_proc_exit(void)
+{
+	remove_proc_entry("devices", proc_bus_input_dir);
+	remove_proc_entry("handlers", proc_bus_input_dir);
+	remove_proc_entry("input", proc_bus);
+}
+
+#else /* !CONFIG_PROC_FS */
+static inline void input_wakeup_procfs_readers(void) { }
+static inline int input_proc_init(void) { return 0; }
+static inline void input_proc_exit(void) { }
+#endif
+
 void input_register_device(struct input_dev *dev)
 {
 	struct input_handle *handle;
@@ -415,6 +602,8 @@ void input_register_device(struct input_
 
 	set_bit(EV_SYN, dev->evbit);
 
+	init_MUTEX(&dev->sem);
+
 	/*
 	 * If delay and period are pre-set by the driver, then autorepeating
 	 * is handled by the driver itself and we don't do it in input.c.
@@ -441,10 +630,7 @@ void input_register_device(struct input_
 	input_call_hotplug("add", dev);
 #endif
 
-#ifdef CONFIG_PROC_FS
-	input_devices_state++;
-	wake_up(&input_devices_poll_wait);
-#endif
+	input_wakeup_procfs_readers();
 }
 
 void input_unregister_device(struct input_dev *dev)
@@ -468,10 +654,7 @@ void input_unregister_device(struct inpu
 
 	list_del_init(&dev->node);
 
-#ifdef CONFIG_PROC_FS
-	input_devices_state++;
-	wake_up(&input_devices_poll_wait);
-#endif
+	input_wakeup_procfs_readers();
 }
 
 void input_register_handler(struct input_handler *handler)
@@ -495,10 +678,7 @@ void input_register_handler(struct input
 				if ((handle = handler->connect(handler, dev, id)))
 					input_link_handle(handle);
 
-#ifdef CONFIG_PROC_FS
-	input_devices_state++;
-	wake_up(&input_devices_poll_wait);
-#endif
+	input_wakeup_procfs_readers();
 }
 
 void input_unregister_handler(struct input_handler *handler)
@@ -517,10 +697,7 @@ void input_unregister_handler(struct inp
 	if (handler->fops != NULL)
 		input_table[handler->minor >> 5] = NULL;
 
-#ifdef CONFIG_PROC_FS
-	input_devices_state++;
-	wake_up(&input_devices_poll_wait);
-#endif
+	input_wakeup_procfs_readers();
 }
 
 static int input_open_file(struct inode *inode, struct file *file)
@@ -559,189 +736,46 @@ static struct file_operations input_fops
 	.open = input_open_file,
 };
 
-#ifdef CONFIG_PROC_FS
-
-#define SPRINTF_BIT_B(bit, name, max) \
-	do { \
-		len += sprintf(buf + len, "B: %s", name); \
-		for (i = NBITS(max) - 1; i >= 0; i--) \
-			if (dev->bit[i]) break; \
-		for (; i >= 0; i--) \
-			len += sprintf(buf + len, "%lx ", dev->bit[i]); \
-		len += sprintf(buf + len, "\n"); \
-	} while (0)
-
-#define SPRINTF_BIT_B2(bit, name, max, ev) \
-	do { \
-		if (test_bit(ev, dev->evbit)) \
-			SPRINTF_BIT_B(bit, name, max); \
-	} while (0)
-
+struct class *input_class;
 
-static unsigned int input_devices_poll(struct file *file, poll_table *wait)
-{
-	int state = input_devices_state;
-	poll_wait(file, &input_devices_poll_wait, wait);
-	if (state != input_devices_state)
-		return POLLIN | POLLRDNORM;
-	return 0;
-}
-
-static int input_devices_read(char *buf, char **start, off_t pos, int count, int *eof, void *data)
+static int __init input_init(void)
 {
-	struct input_dev *dev;
-	struct input_handle *handle;
-
-	off_t at = 0;
-	int i, len, cnt = 0;
-
-	list_for_each_entry(dev, &input_dev_list, node) {
-
-		len = sprintf(buf, "I: Bus=%04x Vendor=%04x Product=%04x Version=%04x\n",
-			dev->id.bustype, dev->id.vendor, dev->id.product, dev->id.version);
-
-		len += sprintf(buf + len, "N: Name=\"%s\"\n", dev->name ? dev->name : "");
-		len += sprintf(buf + len, "P: Phys=%s\n", dev->phys ? dev->phys : "");
-		len += sprintf(buf + len, "H: Handlers=");
-
-		list_for_each_entry(handle, &dev->h_list, d_node)
-			len += sprintf(buf + len, "%s ", handle->name);
-
-		len += sprintf(buf + len, "\n");
-
-		SPRINTF_BIT_B(evbit, "EV=", EV_MAX);
-		SPRINTF_BIT_B2(keybit, "KEY=", KEY_MAX, EV_KEY);
-		SPRINTF_BIT_B2(relbit, "REL=", REL_MAX, EV_REL);
-		SPRINTF_BIT_B2(absbit, "ABS=", ABS_MAX, EV_ABS);
-		SPRINTF_BIT_B2(mscbit, "MSC=", MSC_MAX, EV_MSC);
-		SPRINTF_BIT_B2(ledbit, "LED=", LED_MAX, EV_LED);
-		SPRINTF_BIT_B2(sndbit, "SND=", SND_MAX, EV_SND);
-		SPRINTF_BIT_B2(ffbit,  "FF=",  FF_MAX, EV_FF);
-
-		len += sprintf(buf + len, "\n");
-
-		at += len;
+	int err;
 
-		if (at >= pos) {
-			if (!*start) {
-				*start = buf + (pos - (at - len));
-				cnt = at - pos;
-			} else  cnt += len;
-			buf += len;
-			if (cnt >= count)
-				break;
-		}
+	input_class = class_create(THIS_MODULE, "input");
+	if (IS_ERR(input_class)) {
+		printk(KERN_ERR "input: unable to register input class\n");
+		return PTR_ERR(input_class);
 	}
 
-	if (&dev->node == &input_dev_list)
-		*eof = 1;
-
-	return (count > cnt) ? cnt : count;
-}
-
-static int input_handlers_read(char *buf, char **start, off_t pos, int count, int *eof, void *data)
-{
-	struct input_handler *handler;
-
-	off_t at = 0;
-	int len = 0, cnt = 0;
-	int i = 0;
+	err = input_proc_init();
+	if (err)
+		goto fail1;
 
-	list_for_each_entry(handler, &input_handler_list, node) {
-
-		if (handler->fops)
-			len = sprintf(buf, "N: Number=%d Name=%s Minor=%d\n",
-				i++, handler->name, handler->minor);
-		else
-			len = sprintf(buf, "N: Number=%d Name=%s\n",
-				i++, handler->name);
-
-		at += len;
-
-		if (at >= pos) {
-			if (!*start) {
-				*start = buf + (pos - (at - len));
-				cnt = at - pos;
-			} else  cnt += len;
-			buf += len;
-			if (cnt >= count)
-				break;
-		}
+	err = register_chrdev(INPUT_MAJOR, "input", &input_fops);
+	if (err) {
+		printk(KERN_ERR "input: unable to register char major %d", INPUT_MAJOR);
+		goto fail2;
 	}
-	if (&handler->node == &input_handler_list)
-		*eof = 1;
 
-	return (count > cnt) ? cnt : count;
-}
+	err = devfs_mk_dir("input");
+	if (err)
+		goto fail3;
 
-static int __init input_proc_init(void)
-{
-	struct proc_dir_entry *entry;
-
-	proc_bus_input_dir = proc_mkdir("input", proc_bus);
-	if (proc_bus_input_dir == NULL)
-		return -ENOMEM;
-	proc_bus_input_dir->owner = THIS_MODULE;
-	entry = create_proc_read_entry("devices", 0, proc_bus_input_dir, input_devices_read, NULL);
-	if (entry == NULL) {
-		remove_proc_entry("input", proc_bus);
-		return -ENOMEM;
-	}
-	entry->owner = THIS_MODULE;
-	entry->proc_fops->poll = input_devices_poll;
-	entry = create_proc_read_entry("handlers", 0, proc_bus_input_dir, input_handlers_read, NULL);
-	if (entry == NULL) {
-		remove_proc_entry("devices", proc_bus_input_dir);
-		remove_proc_entry("input", proc_bus);
-		return -ENOMEM;
-	}
-	entry->owner = THIS_MODULE;
 	return 0;
-}
-#else /* !CONFIG_PROC_FS */
-static inline int input_proc_init(void) { return 0; }
-#endif
 
-struct class_simple *input_class;
-
-static int __init input_init(void)
-{
-	int retval = -ENOMEM;
-
-	input_class = class_simple_create(THIS_MODULE, "input");
-	if (IS_ERR(input_class))
-		return PTR_ERR(input_class);
-	input_proc_init();
-	retval = register_chrdev(INPUT_MAJOR, "input", &input_fops);
-	if (retval) {
-		printk(KERN_ERR "input: unable to register char major %d", INPUT_MAJOR);
-		remove_proc_entry("devices", proc_bus_input_dir);
-		remove_proc_entry("handlers", proc_bus_input_dir);
-		remove_proc_entry("input", proc_bus);
-		class_simple_destroy(input_class);
-		return retval;
-	}
-
-	retval = devfs_mk_dir("input");
-	if (retval) {
-		remove_proc_entry("devices", proc_bus_input_dir);
-		remove_proc_entry("handlers", proc_bus_input_dir);
-		remove_proc_entry("input", proc_bus);
-		unregister_chrdev(INPUT_MAJOR, "input");
-		class_simple_destroy(input_class);
-	}
-	return retval;
+ fail3:	unregister_chrdev(INPUT_MAJOR, "input");
+ fail2:	input_proc_exit();
+ fail1:	class_destroy(input_class);
+	return err;
 }
 
 static void __exit input_exit(void)
 {
-	remove_proc_entry("devices", proc_bus_input_dir);
-	remove_proc_entry("handlers", proc_bus_input_dir);
-	remove_proc_entry("input", proc_bus);
-
+	input_proc_exit();
 	devfs_remove("input");
 	unregister_chrdev(INPUT_MAJOR, "input");
-	class_simple_destroy(input_class);
+	class_destroy(input_class);
 }
 
 subsys_initcall(input_init);
diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c
--- a/drivers/input/joydev.c
+++ b/drivers/input/joydev.c
@@ -37,8 +37,6 @@ MODULE_LICENSE("GPL");
 #define JOYDEV_MINORS		16
 #define JOYDEV_BUFFER_SIZE	64
 
-#define MSECS(t)	(1000 * ((t) / HZ) + 1000 * ((t) % HZ) / HZ)
-
 struct joydev {
 	int exist;
 	int open;
@@ -117,7 +115,7 @@ static void joydev_event(struct input_ha
 			return;
 	}
 
-	event.time = MSECS(jiffies);
+	event.time = jiffies_to_msecs(jiffies);
 
 	list_for_each_entry(list, &joydev->list, node) {
 
@@ -245,7 +243,7 @@ static ssize_t joydev_read(struct file *
 
 		struct js_event event;
 
-		event.time = MSECS(jiffies);
+		event.time = jiffies_to_msecs(jiffies);
 
 		if (list->startup < joydev->nkey) {
 			event.type = JS_EVENT_BUTTON | JS_EVENT_INIT;
@@ -285,48 +283,33 @@ static unsigned int joydev_poll(struct f
 		(POLLIN | POLLRDNORM) : 0) | (list->joydev->exist ? 0 : (POLLHUP | POLLERR));
 }
 
-static int joydev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+static int joydev_ioctl_common(struct joydev *joydev, unsigned int cmd, void __user *argp)
 {
-	struct joydev_list *list = file->private_data;
-	struct joydev *joydev = list->joydev;
 	struct input_dev *dev = joydev->handle.dev;
-	void __user *argp = (void __user *)arg;
 	int i, j;
 
-	if (!joydev->exist) return -ENODEV;
-
 	switch (cmd) {
 
 		case JS_SET_CAL:
 			return copy_from_user(&joydev->glue.JS_CORR, argp,
-				sizeof(struct JS_DATA_TYPE)) ? -EFAULT : 0;
+				sizeof(joydev->glue.JS_CORR)) ? -EFAULT : 0;
 		case JS_GET_CAL:
 			return copy_to_user(argp, &joydev->glue.JS_CORR,
-				sizeof(struct JS_DATA_TYPE)) ? -EFAULT : 0;
+				sizeof(joydev->glue.JS_CORR)) ? -EFAULT : 0;
 		case JS_SET_TIMEOUT:
-			return get_user(joydev->glue.JS_TIMEOUT, (int __user *) arg);
+			return get_user(joydev->glue.JS_TIMEOUT, (s32 __user *) argp);
 		case JS_GET_TIMEOUT:
-			return put_user(joydev->glue.JS_TIMEOUT, (int __user *) arg);
-		case JS_SET_TIMELIMIT:
-			return get_user(joydev->glue.JS_TIMELIMIT, (long __user *) arg);
-		case JS_GET_TIMELIMIT:
-			return put_user(joydev->glue.JS_TIMELIMIT, (long __user *) arg);
-		case JS_SET_ALL:
-			return copy_from_user(&joydev->glue, argp,
-						sizeof(struct JS_DATA_SAVE_TYPE)) ? -EFAULT : 0;
-		case JS_GET_ALL:
-			return copy_to_user(argp, &joydev->glue,
-						sizeof(struct JS_DATA_SAVE_TYPE)) ? -EFAULT : 0;
+			return put_user(joydev->glue.JS_TIMEOUT, (s32 __user *) argp);
 
 		case JSIOCGVERSION:
-			return put_user(JS_VERSION, (__u32 __user *) arg);
+			return put_user(JS_VERSION, (__u32 __user *) argp);
 		case JSIOCGAXES:
-			return put_user(joydev->nabs, (__u8 __user *) arg);
+			return put_user(joydev->nabs, (__u8 __user *) argp);
 		case JSIOCGBUTTONS:
-			return put_user(joydev->nkey, (__u8 __user *) arg);
+			return put_user(joydev->nkey, (__u8 __user *) argp);
 		case JSIOCSCORR:
 			if (copy_from_user(joydev->corr, argp,
-				      sizeof(struct js_corr) * joydev->nabs))
+				      sizeof(joydev->corr[0]) * joydev->nabs))
 			    return -EFAULT;
 			for (i = 0; i < joydev->nabs; i++) {
 				j = joydev->abspam[i];
@@ -335,7 +318,7 @@ static int joydev_ioctl(struct inode *in
 			return 0;
 		case JSIOCGCORR:
 			return copy_to_user(argp, joydev->corr,
-						sizeof(struct js_corr) * joydev->nabs) ? -EFAULT : 0;
+						sizeof(joydev->corr[0]) * joydev->nabs) ? -EFAULT : 0;
 		case JSIOCSAXMAP:
 			if (copy_from_user(joydev->abspam, argp, sizeof(__u8) * (ABS_MAX + 1)))
 				return -EFAULT;
@@ -371,6 +354,84 @@ static int joydev_ioctl(struct inode *in
 	return -EINVAL;
 }
 
+#ifdef CONFIG_COMPAT
+static long joydev_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+	struct joydev_list *list = file->private_data;
+	struct joydev *joydev = list->joydev;
+	void __user *argp = (void __user *)arg;
+	s32 tmp32;
+	struct JS_DATA_SAVE_TYPE_32 ds32;
+	int err;
+
+	if (!joydev->exist) return -ENODEV;
+	switch(cmd) {
+	case JS_SET_TIMELIMIT:
+		err = get_user(tmp32, (s32 __user *) arg);
+		if (err == 0)
+			joydev->glue.JS_TIMELIMIT = tmp32;
+		break;
+	case JS_GET_TIMELIMIT:
+		tmp32 = joydev->glue.JS_TIMELIMIT;
+		err = put_user(tmp32, (s32 __user *) arg);
+		break;
+
+	case JS_SET_ALL:
+		err = copy_from_user(&ds32, argp,
+				     sizeof(ds32)) ? -EFAULT : 0;
+		if (err == 0) {
+			joydev->glue.JS_TIMEOUT    = ds32.JS_TIMEOUT;
+			joydev->glue.BUSY          = ds32.BUSY;
+			joydev->glue.JS_EXPIRETIME = ds32.JS_EXPIRETIME;
+			joydev->glue.JS_TIMELIMIT  = ds32.JS_TIMELIMIT;
+			joydev->glue.JS_SAVE       = ds32.JS_SAVE;
+			joydev->glue.JS_CORR       = ds32.JS_CORR;
+		}
+		break;
+
+	case JS_GET_ALL:
+		ds32.JS_TIMEOUT    = joydev->glue.JS_TIMEOUT;
+		ds32.BUSY          = joydev->glue.BUSY;
+		ds32.JS_EXPIRETIME = joydev->glue.JS_EXPIRETIME;
+		ds32.JS_TIMELIMIT  = joydev->glue.JS_TIMELIMIT;
+		ds32.JS_SAVE       = joydev->glue.JS_SAVE;
+		ds32.JS_CORR       = joydev->glue.JS_CORR;
+
+		err = copy_to_user(argp, &ds32,
+					  sizeof(ds32)) ? -EFAULT : 0;
+		break;
+
+	default:
+		err = joydev_ioctl_common(joydev, cmd, argp);
+	}
+	return err;
+}
+#endif /* CONFIG_COMPAT */
+
+static int joydev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+{
+	struct joydev_list *list = file->private_data;
+	struct joydev *joydev = list->joydev;
+	void __user *argp = (void __user *)arg;
+
+	if (!joydev->exist) return -ENODEV;
+
+	switch(cmd) {
+		case JS_SET_TIMELIMIT:
+			return get_user(joydev->glue.JS_TIMELIMIT, (long __user *) arg);
+		case JS_GET_TIMELIMIT:
+			return put_user(joydev->glue.JS_TIMELIMIT, (long __user *) arg);
+		case JS_SET_ALL:
+			return copy_from_user(&joydev->glue, argp,
+						sizeof(joydev->glue)) ? -EFAULT : 0;
+		case JS_GET_ALL:
+			return copy_to_user(argp, &joydev->glue,
+						sizeof(joydev->glue)) ? -EFAULT : 0;
+		default:
+			return joydev_ioctl_common(joydev, cmd, argp);
+	}
+}
+
 static struct file_operations joydev_fops = {
 	.owner =	THIS_MODULE,
 	.read =		joydev_read,
@@ -379,6 +440,9 @@ static struct file_operations joydev_fop
 	.open =		joydev_open,
 	.release =	joydev_release,
 	.ioctl =	joydev_ioctl,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl =	joydev_compat_ioctl,
+#endif
 	.fasync =	joydev_fasync,
 };
 
@@ -452,9 +516,9 @@ static struct input_handle *joydev_conne
 
 	devfs_mk_cdev(MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + minor),
 			S_IFCHR|S_IRUGO|S_IWUSR, "input/js%d", minor);
-	class_simple_device_add(input_class,
-				MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + minor),
-				dev->dev, "js%d", minor);
+	class_device_create(input_class,
+			MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + minor),
+			dev->dev, "js%d", minor);
 
 	return &joydev->handle;
 }
@@ -464,7 +528,7 @@ static void joydev_disconnect(struct inp
 	struct joydev *joydev = handle->private;
 	struct joydev_list *list;
 
-	class_simple_device_remove(MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + joydev->minor));
+	class_device_destroy(input_class, MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + joydev->minor));
 	devfs_remove("input/js%d", joydev->minor);
 	joydev->exist = 0;
 
diff --git a/drivers/input/joystick/a3d.c b/drivers/input/joystick/a3d.c
--- a/drivers/input/joystick/a3d.c
+++ b/drivers/input/joystick/a3d.c
@@ -185,7 +185,7 @@ static void a3d_poll(struct gameport *ga
 	a3d->reads++;
 	if (a3d_read_packet(a3d->gameport, a3d->length, data) != a3d->length ||
 	    data[0] != a3d->mode || a3d_csum(data, a3d->length))
-	 	a3d->bads++;
+		a3d->bads++;
 	else
 		a3d_read(a3d, data);
 }
diff --git a/drivers/input/joystick/adi.c b/drivers/input/joystick/adi.c
--- a/drivers/input/joystick/adi.c
+++ b/drivers/input/joystick/adi.c
@@ -82,7 +82,7 @@ static char adi_cm2_abs[] =	{ ABS_X, ABS
 static char adi_wmf_abs[] =	{ ABS_WHEEL, ABS_GAS, ABS_BRAKE, ABS_HAT0X, ABS_HAT0Y, ABS_HAT1X, ABS_HAT1Y, ABS_HAT2X, ABS_HAT2Y };
 
 static short adi_wmgpe_key[] =	{ BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z,  BTN_TL, BTN_TR, BTN_START, BTN_MODE, BTN_SELECT };
-static short adi_wmi_key[] = 	{ BTN_TRIGGER,  BTN_TOP, BTN_THUMB, BTN_TOP2, BTN_BASE, BTN_BASE2, BTN_BASE3, BTN_BASE4, BTN_EXTRA };
+static short adi_wmi_key[] =	{ BTN_TRIGGER,  BTN_TOP, BTN_THUMB, BTN_TOP2, BTN_BASE, BTN_BASE2, BTN_BASE3, BTN_BASE4, BTN_EXTRA };
 static short adi_wmed3d_key[] =	{ BTN_TRIGGER, BTN_THUMB, BTN_THUMB2, BTN_TOP, BTN_TOP2, BTN_BASE, BTN_BASE2 };
 static short adi_cm2_key[] =	{ BTN_1, BTN_2, BTN_3, BTN_4, BTN_5, BTN_6, BTN_7, BTN_8 };
 
@@ -183,7 +183,7 @@ static void adi_move_bits(struct adi_por
 	int i;
 	struct adi *adi = port->adi;
 
- 	adi[0].idx = adi[1].idx = 0;
+	adi[0].idx = adi[1].idx = 0;
 
 	if (adi[0].ret <= 0 || adi[1].ret <= 0) return;
 	if (adi[0].data[0] & 0x20 || ~adi[1].data[0] & 0x20) return;
diff --git a/drivers/input/joystick/amijoy.c b/drivers/input/joystick/amijoy.c
--- a/drivers/input/joystick/amijoy.c
+++ b/drivers/input/joystick/amijoy.c
@@ -51,7 +51,8 @@ MODULE_PARM_DESC(map, "Map of attached j
 
 __obsolete_setup("amijoy=");
 
-static int amijoy_used[2] = { 0, 0 };
+static int amijoy_used;
+static DECLARE_MUTEX(amijoy_sem);
 static struct input_dev amijoy_dev[2];
 static char *amijoy_phys[2] = { "amijoy/input0", "amijoy/input1" };
 
@@ -84,26 +85,30 @@ static irqreturn_t amijoy_interrupt(int 
 
 static int amijoy_open(struct input_dev *dev)
 {
-	int *used = dev->private;
+	int err;
 
-	if ((*used)++)
-		return 0;
+	err = down_interruptible(&amijoy_sem);
+	if (err)
+		return err;
 
-	if (request_irq(IRQ_AMIGA_VERTB, amijoy_interrupt, 0, "amijoy", amijoy_interrupt)) {
-		(*used)--;
+	if (!amijoy_used && request_irq(IRQ_AMIGA_VERTB, amijoy_interrupt, 0, "amijoy", amijoy_interrupt)) {
 		printk(KERN_ERR "amijoy.c: Can't allocate irq %d\n", IRQ_AMIGA_VERTB);
-		return -EBUSY;
+		err = -EBUSY;
+		goto out;
 	}
 
-	return 0;
+	amijoy_used++;
+out:
+	up(&amijoy_sem);
+	return err;
 }
 
 static void amijoy_close(struct input_dev *dev)
 {
-	int *used = dev->private;
-
-	if (!--(*used))
+	down(&amijoy_sem);
+	if (!--amijoy_used)
 		free_irq(IRQ_AMIGA_VERTB, amijoy_interrupt);
+	up(&amijoy_sem);
 }
 
 static int __init amijoy_init(void)
@@ -138,8 +143,6 @@ static int __init amijoy_init(void)
 			amijoy_dev[i].id.product = 0x0003;
 			amijoy_dev[i].id.version = 0x0100;
 
-			amijoy_dev[i].private = amijoy_used + i;
-
 			input_register_device(amijoy_dev + i);
 			printk(KERN_INFO "input: %s at joy%ddat\n", amijoy_name, i);
 		}
diff --git a/drivers/input/joystick/analog.c b/drivers/input/joystick/analog.c
--- a/drivers/input/joystick/analog.c
+++ b/drivers/input/joystick/analog.c
@@ -140,12 +140,14 @@ struct analog_port {
  */
 
 #ifdef __i386__
+
+#include <asm/i8253.h>
+
 #define GET_TIME(x)	do { if (cpu_has_tsc) rdtscl(x); else x = get_time_pit(); } while (0)
 #define DELTA(x,y)	(cpu_has_tsc ? ((y) - (x)) : ((x) - (y) + ((x) < (y) ? CLOCK_TICK_RATE / HZ : 0)))
 #define TIME_NAME	(cpu_has_tsc?"TSC":"PIT")
 static unsigned int get_time_pit(void)
 {
-        extern spinlock_t i8253_lock;
         unsigned long flags;
         unsigned int count;
 
diff --git a/drivers/input/joystick/db9.c b/drivers/input/joystick/db9.c
--- a/drivers/input/joystick/db9.c
+++ b/drivers/input/joystick/db9.c
@@ -87,7 +87,7 @@ __obsolete_setup("db9_3=");
 #define DB9_NORMAL		0x0a
 #define DB9_NOSELECT		0x08
 
-#define DB9_MAX_DEVICES 2
+#define DB9_MAX_DEVICES		2
 
 #define DB9_GENESIS6_DELAY	14
 #define DB9_REFRESH_TIME	HZ/100
@@ -98,6 +98,7 @@ struct db9 {
 	struct pardevice *pd;
 	int mode;
 	int used;
+	struct semaphore sem;
 	char phys[2][32];
 };
 
@@ -503,6 +504,11 @@ static int db9_open(struct input_dev *de
 {
 	struct db9 *db9 = dev->private;
 	struct parport *port = db9->pd->port;
+	int err;
+
+	err = down_interruptible(&db9->sem);
+	if (err)
+		return err;
 
 	if (!db9->used++) {
 		parport_claim(db9->pd);
@@ -514,6 +520,7 @@ static int db9_open(struct input_dev *de
 		mod_timer(&db9->timer, jiffies + DB9_REFRESH_TIME);
 	}
 
+	up(&db9->sem);
 	return 0;
 }
 
@@ -522,12 +529,14 @@ static void db9_close(struct input_dev *
 	struct db9 *db9 = dev->private;
 	struct parport *port = db9->pd->port;
 
+	down(&db9->sem);
 	if (!--db9->used) {
-		del_timer(&db9->timer);
+		del_timer_sync(&db9->timer);
 		parport_write_control(port, 0x00);
 		parport_data_forward(port);
 		parport_release(db9->pd);
 	}
+	up(&db9->sem);
 }
 
 static struct db9 __init *db9_probe(int *config, int nargs)
@@ -563,12 +572,12 @@ static struct db9 __init *db9_probe(int 
 		}
 	}
 
-	if (!(db9 = kmalloc(sizeof(struct db9), GFP_KERNEL))) {
+	if (!(db9 = kcalloc(1, sizeof(struct db9), GFP_KERNEL))) {
 		parport_put_port(pp);
 		return NULL;
 	}
-	memset(db9, 0, sizeof(struct db9));
 
+	init_MUTEX(&db9->sem);
 	db9->mode = config[1];
 	init_timer(&db9->timer);
 	db9->timer.data = (long) db9;
diff --git a/drivers/input/joystick/gamecon.c b/drivers/input/joystick/gamecon.c
--- a/drivers/input/joystick/gamecon.c
+++ b/drivers/input/joystick/gamecon.c
@@ -1,12 +1,12 @@
 /*
  * NES, SNES, N64, MultiSystem, PSX gamepad driver for Linux
  *
- *  Copyright (c) 1999-2004 	Vojtech Pavlik <vojtech@suse.cz>
- *  Copyright (c) 2004 		Peter Nelson <rufus-kernel@hackish.org>
+ *  Copyright (c) 1999-2004	Vojtech Pavlik <vojtech@suse.cz>
+ *  Copyright (c) 2004		Peter Nelson <rufus-kernel@hackish.org>
  *
  *  Based on the work of:
- *  	Andree Borrmann		John Dahlstrom
- *  	David Kuder		Nathan Hand
+ *	Andree Borrmann		John Dahlstrom
+ *	David Kuder		Nathan Hand
  */
 
 /*
@@ -81,6 +81,7 @@ struct gc {
 	struct timer_list timer;
 	unsigned char pads[GC_MAX + 1];
 	int used;
+	struct semaphore sem;
 	char phys[5][32];
 };
 
@@ -433,7 +434,7 @@ static void gc_timer(unsigned long priva
 		gc_psx_read_packet(gc, data_psx, data);
 
 		for (i = 0; i < 5; i++) {
-	 		switch (data[i]) {
+			switch (data[i]) {
 
 				case GC_PSX_RUMBLE:
 
@@ -503,22 +504,33 @@ static void gc_timer(unsigned long priva
 static int gc_open(struct input_dev *dev)
 {
 	struct gc *gc = dev->private;
+	int err;
+
+	err = down_interruptible(&gc->sem);
+	if (err)
+		return err;
+
 	if (!gc->used++) {
 		parport_claim(gc->pd);
 		parport_write_control(gc->pd->port, 0x04);
 		mod_timer(&gc->timer, jiffies + GC_REFRESH_TIME);
 	}
+
+	up(&gc->sem);
 	return 0;
 }
 
 static void gc_close(struct input_dev *dev)
 {
 	struct gc *gc = dev->private;
+
+	down(&gc->sem);
 	if (!--gc->used) {
-		del_timer(&gc->timer);
+		del_timer_sync(&gc->timer);
 		parport_write_control(gc->pd->port, 0x00);
 		parport_release(gc->pd);
 	}
+	up(&gc->sem);
 }
 
 static struct gc __init *gc_probe(int *config, int nargs)
@@ -542,11 +554,12 @@ static struct gc __init *gc_probe(int *c
 		return NULL;
 	}
 
-	if (!(gc = kmalloc(sizeof(struct gc), GFP_KERNEL))) {
+	if (!(gc = kcalloc(1, sizeof(struct gc), GFP_KERNEL))) {
 		parport_put_port(pp);
 		return NULL;
 	}
-	memset(gc, 0, sizeof(struct gc));
+
+	init_MUTEX(&gc->sem);
 
 	gc->pd = parport_register_device(pp, "gamecon", NULL, NULL, NULL, PARPORT_DEV_EXCL, NULL);
 
diff --git a/drivers/input/joystick/gf2k.c b/drivers/input/joystick/gf2k.c
--- a/drivers/input/joystick/gf2k.c
+++ b/drivers/input/joystick/gf2k.c
@@ -329,7 +329,7 @@ static int gf2k_connect(struct gameport 
 
 	for (i = 0; i < gf2k_axes[gf2k->id]; i++) {
 		gf2k->dev.absmax[gf2k_abs[i]] = (i < 2) ? gf2k->dev.abs[gf2k_abs[i]] * 2 - 32 :
-	      		  gf2k->dev.abs[gf2k_abs[0]] + gf2k->dev.abs[gf2k_abs[1]] - 32;
+			  gf2k->dev.abs[gf2k_abs[0]] + gf2k->dev.abs[gf2k_abs[1]] - 32;
 		gf2k->dev.absmin[gf2k_abs[i]] = 32;
 		gf2k->dev.absfuzz[gf2k_abs[i]] = 8;
 		gf2k->dev.absflat[gf2k_abs[i]] = (i < 2) ? 24 : 0;
diff --git a/drivers/input/joystick/grip_mp.c b/drivers/input/joystick/grip_mp.c
--- a/drivers/input/joystick/grip_mp.c
+++ b/drivers/input/joystick/grip_mp.c
@@ -171,7 +171,7 @@ static int mp_io(struct gameport* gamepo
 	*packet = 0;
 	raw_data = gameport_read(gameport);
 	if (raw_data & 1)
- 		return IO_RETRY;
+		return IO_RETRY;
 
 	for (i = 0; i < 64; i++) {
 		raw_data = gameport_read(gameport);
diff --git a/drivers/input/joystick/iforce/iforce-main.c b/drivers/input/joystick/iforce/iforce-main.c
--- a/drivers/input/joystick/iforce/iforce-main.c
+++ b/drivers/input/joystick/iforce/iforce-main.c
@@ -78,6 +78,7 @@ static struct iforce_device iforce_devic
 	{ 0x061c, 0xc0a4, "ACT LABS Force RS",                          btn_wheel, abs_wheel, ff_iforce }, //?
 	{ 0x06f8, 0x0001, "Guillemot Race Leader Force Feedback",	btn_wheel, abs_wheel, ff_iforce }, //?
 	{ 0x06f8, 0x0004, "Guillemot Force Feedback Racing Wheel",	btn_wheel, abs_wheel, ff_iforce }, //?
+	{ 0x06f8, 0x0004, "Gullemot Jet Leader 3D",			btn_joystick, abs_joystick, ff_iforce }, //?
 	{ 0x0000, 0x0000, "Unknown I-Force Device [%04x:%04x]",		btn_joystick, abs_joystick, ff_iforce }
 };
 
diff --git a/drivers/input/joystick/iforce/iforce-usb.c b/drivers/input/joystick/iforce/iforce-usb.c
--- a/drivers/input/joystick/iforce/iforce-usb.c
+++ b/drivers/input/joystick/iforce/iforce-usb.c
@@ -229,6 +229,7 @@ static struct usb_device_id iforce_usb_i
 	{ USB_DEVICE(0x061c, 0xc0a4) },         /* ACT LABS Force RS */
 	{ USB_DEVICE(0x06f8, 0x0001) },		/* Guillemot Race Leader Force Feedback */
 	{ USB_DEVICE(0x06f8, 0x0004) },		/* Guillemot Force Feedback Racing Wheel */
+	{ USB_DEVICE(0x06f8, 0xa302) },		/* Guillemot Jet Leader 3D */
 	{ }					/* Terminating entry */
 };
 
diff --git a/drivers/input/joystick/spaceball.c b/drivers/input/joystick/spaceball.c
--- a/drivers/input/joystick/spaceball.c
+++ b/drivers/input/joystick/spaceball.c
@@ -4,8 +4,8 @@
  *  Copyright (c) 1999-2001 Vojtech Pavlik
  *
  *  Based on the work of:
- *  	David Thompson
- *  	Joseph Krahn
+ *	David Thompson
+ *	Joseph Krahn
  */
 
 /*
diff --git a/drivers/input/joystick/spaceorb.c b/drivers/input/joystick/spaceorb.c
--- a/drivers/input/joystick/spaceorb.c
+++ b/drivers/input/joystick/spaceorb.c
@@ -4,7 +4,7 @@
  *  Copyright (c) 1999-2001 Vojtech Pavlik
  *
  *  Based on the work of:
- *  	David Thompson
+ *	David Thompson
  */
 
 /*
diff --git a/drivers/input/joystick/tmdc.c b/drivers/input/joystick/tmdc.c
--- a/drivers/input/joystick/tmdc.c
+++ b/drivers/input/joystick/tmdc.c
@@ -79,7 +79,7 @@ static short tmdc_btn_pad[TMDC_BTN] =
 	{ BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, BTN_START, BTN_SELECT, BTN_TL, BTN_TR };
 static short tmdc_btn_joy[TMDC_BTN] =
 	{ BTN_TRIGGER, BTN_THUMB, BTN_TOP, BTN_TOP2, BTN_BASE, BTN_BASE2, BTN_THUMB2, BTN_PINKIE,
- 	  BTN_BASE3, BTN_BASE4, BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z };
+	  BTN_BASE3, BTN_BASE4, BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z };
 static short tmdc_btn_fm[TMDC_BTN] =
         { BTN_TRIGGER, BTN_C, BTN_B, BTN_A, BTN_THUMB, BTN_X, BTN_Y, BTN_Z, BTN_TOP, BTN_TOP2 };
 static short tmdc_btn_at[TMDC_BTN] =
diff --git a/drivers/input/joystick/turbografx.c b/drivers/input/joystick/turbografx.c
--- a/drivers/input/joystick/turbografx.c
+++ b/drivers/input/joystick/turbografx.c
@@ -84,6 +84,7 @@ static struct tgfx {
 	char phys[7][32];
 	int sticks;
 	int used;
+	struct semaphore sem;
 } *tgfx_base[3];
 
 /*
@@ -99,7 +100,7 @@ static void tgfx_timer(unsigned long pri
 	for (i = 0; i < 7; i++)
 		if (tgfx->sticks & (1 << i)) {
 
- 			dev = tgfx->dev + i;
+			dev = tgfx->dev + i;
 
 			parport_write_data(tgfx->pd->port, ~(1 << i));
 			data1 = parport_read_status(tgfx->pd->port) ^ 0x7f;
@@ -122,23 +123,34 @@ static void tgfx_timer(unsigned long pri
 
 static int tgfx_open(struct input_dev *dev)
 {
-        struct tgfx *tgfx = dev->private;
-        if (!tgfx->used++) {
+	struct tgfx *tgfx = dev->private;
+	int err;
+
+	err = down_interruptible(&tgfx->sem);
+	if (err)
+		return err;
+
+	if (!tgfx->used++) {
 		parport_claim(tgfx->pd);
 		parport_write_control(tgfx->pd->port, 0x04);
-                mod_timer(&tgfx->timer, jiffies + TGFX_REFRESH_TIME);
+		mod_timer(&tgfx->timer, jiffies + TGFX_REFRESH_TIME);
 	}
-        return 0;
+
+	up(&tgfx->sem);
+	return 0;
 }
 
 static void tgfx_close(struct input_dev *dev)
 {
-        struct tgfx *tgfx = dev->private;
-        if (!--tgfx->used) {
-                del_timer(&tgfx->timer);
+	struct tgfx *tgfx = dev->private;
+
+	down(&tgfx->sem);
+	if (!--tgfx->used) {
+		del_timer_sync(&tgfx->timer);
 		parport_write_control(tgfx->pd->port, 0x00);
-        	parport_release(tgfx->pd);
+		parport_release(tgfx->pd);
 	}
+	up(&tgfx->sem);
 }
 
 /*
@@ -166,11 +178,12 @@ static struct tgfx __init *tgfx_probe(in
 		return NULL;
 	}
 
-	if (!(tgfx = kmalloc(sizeof(struct tgfx), GFP_KERNEL))) {
+	if (!(tgfx = kcalloc(1, sizeof(struct tgfx), GFP_KERNEL))) {
 		parport_put_port(pp);
 		return NULL;
 	}
-	memset(tgfx, 0, sizeof(struct tgfx));
+
+	init_MUTEX(&tgfx->sem);
 
 	tgfx->pd = parport_register_device(pp, "turbografx", NULL, NULL, NULL, PARPORT_DEV_EXCL, NULL);
 
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
--- a/drivers/input/keyboard/atkbd.c
+++ b/drivers/input/keyboard/atkbd.c
@@ -219,15 +219,15 @@ static ssize_t atkbd_attr_set_helper(str
 #define ATKBD_DEFINE_ATTR(_name)						\
 static ssize_t atkbd_show_##_name(struct atkbd *, char *);			\
 static ssize_t atkbd_set_##_name(struct atkbd *, const char *, size_t);		\
-static ssize_t atkbd_do_show_##_name(struct device *d, char *b)			\
+static ssize_t atkbd_do_show_##_name(struct device *d, struct device_attribute *attr, char *b)			\
 {										\
 	return atkbd_attr_show_helper(d, b, atkbd_show_##_name);		\
 }										\
-static ssize_t atkbd_do_set_##_name(struct device *d, const char *b, size_t s)	\
+static ssize_t atkbd_do_set_##_name(struct device *d, struct device_attribute *attr, const char *b, size_t s)	\
 {										\
 	return atkbd_attr_set_helper(d, b, s, atkbd_set_##_name);		\
 }										\
-static struct device_attribute atkbd_attr_##_name = 				\
+static struct device_attribute atkbd_attr_##_name =				\
 	__ATTR(_name, S_IWUSR | S_IRUGO, atkbd_do_show_##_name, atkbd_do_set_##_name);
 
 ATKBD_DEFINE_ATTR(extra);
@@ -388,7 +388,7 @@ static irqreturn_t atkbd_interrupt(struc
 			value = atkbd->release ? 0 :
 				(1 + (!atkbd->softrepeat && test_bit(atkbd->keycode[code], atkbd->dev.key)));
 
-			switch (value) { 	/* Workaround Toshiba laptop multiple keypress */
+			switch (value) {	/* Workaround Toshiba laptop multiple keypress */
 				case 0:
 					atkbd->last = 0;
 					break;
@@ -894,7 +894,7 @@ static int atkbd_reconnect(struct serio 
 	if (atkbd->write) {
 		param[0] = (test_bit(LED_SCROLLL, atkbd->dev.led) ? 1 : 0)
 		         | (test_bit(LED_NUML,    atkbd->dev.led) ? 2 : 0)
- 		         | (test_bit(LED_CAPSL,   atkbd->dev.led) ? 4 : 0);
+		         | (test_bit(LED_CAPSL,   atkbd->dev.led) ? 4 : 0);
 
 		if (atkbd_probe(atkbd))
 			return -1;
diff --git a/drivers/input/keyboard/corgikbd.c b/drivers/input/keyboard/corgikbd.c
--- a/drivers/input/keyboard/corgikbd.c
+++ b/drivers/input/keyboard/corgikbd.c
@@ -39,6 +39,7 @@
 #define CORGI_KEY_CALENDER	KEY_F1
 #define CORGI_KEY_ADDRESS	KEY_F2
 #define CORGI_KEY_FN		KEY_F3
+#define CORGI_KEY_CANCEL	KEY_F4
 #define CORGI_KEY_OFF		KEY_SUSPEND
 #define CORGI_KEY_EXOK		KEY_F5
 #define CORGI_KEY_EXCANCEL	KEY_F6
@@ -46,6 +47,7 @@
 #define CORGI_KEY_EXJOGUP	KEY_F8
 #define CORGI_KEY_JAP1		KEY_LEFTCTRL
 #define CORGI_KEY_JAP2		KEY_LEFTALT
+#define CORGI_KEY_MAIL		KEY_F10
 #define CORGI_KEY_OK		KEY_F11
 #define CORGI_KEY_MENU		KEY_F12
 #define CORGI_HINGE_0		KEY_KP0
@@ -59,8 +61,8 @@ static unsigned char corgikbd_keycode[NR
 	KEY_TAB, KEY_Q, KEY_E, KEY_T, KEY_G, KEY_U, KEY_J, KEY_K, 0, 0, 0, 0, 0, 0, 0, 0,                                 /* 33-48 */
 	CORGI_KEY_CALENDER, KEY_W, KEY_S, KEY_F, KEY_V, KEY_H, KEY_M, KEY_L, 0, KEY_RIGHTSHIFT, 0, 0, 0, 0, 0, 0,         /* 49-64 */
 	CORGI_KEY_ADDRESS, KEY_A, KEY_D, KEY_C, KEY_B, KEY_N, KEY_DOT, 0, KEY_ENTER, 0, KEY_LEFTSHIFT, 0, 0, 0, 0, 0, 	  /* 65-80 */
-	KEY_MAIL, KEY_Z, KEY_X, KEY_MINUS, KEY_SPACE, KEY_COMMA, 0, KEY_UP, 0, 0, 0, CORGI_KEY_FN, 0, 0, 0, 0,            /* 81-96 */
-	KEY_SYSRQ, CORGI_KEY_JAP1, CORGI_KEY_JAP2, KEY_CANCEL, CORGI_KEY_OK, CORGI_KEY_MENU, KEY_LEFT, KEY_DOWN, KEY_RIGHT, 0, 0, 0, 0, 0, 0, 0,  /* 97-112 */
+	CORGI_KEY_MAIL, KEY_Z, KEY_X, KEY_MINUS, KEY_SPACE, KEY_COMMA, 0, KEY_UP, 0, 0, 0, CORGI_KEY_FN, 0, 0, 0, 0,            /* 81-96 */
+	KEY_SYSRQ, CORGI_KEY_JAP1, CORGI_KEY_JAP2, CORGI_KEY_CANCEL, CORGI_KEY_OK, CORGI_KEY_MENU, KEY_LEFT, KEY_DOWN, KEY_RIGHT, 0, 0, 0, 0, 0, 0, 0,  /* 97-112 */
 	CORGI_KEY_OFF, CORGI_KEY_EXOK, CORGI_KEY_EXCANCEL, CORGI_KEY_EXJOGDOWN, CORGI_KEY_EXJOGUP, 0, 0, 0, 0, 0, 0, 0,   /* 113-124 */
 	CORGI_HINGE_0, CORGI_HINGE_1, CORGI_HINGE_2	  /* 125-127 */
 };
diff --git a/drivers/input/keyboard/lkkbd.c b/drivers/input/keyboard/lkkbd.c
--- a/drivers/input/keyboard/lkkbd.c
+++ b/drivers/input/keyboard/lkkbd.c
@@ -15,10 +15,10 @@
  * information given below, I will _not_ be liable!
  *
  * RJ10 pinout:		To DE9:		Or DB25:
- * 	1 - RxD <---->	Pin 3 (TxD) <->	Pin 2 (TxD)
- * 	2 - GND <---->	Pin 5 (GND) <->	Pin 7 (GND)
- * 	4 - TxD <---->	Pin 2 (RxD) <->	Pin 3 (RxD)
- * 	3 - +12V (from HDD drive connector), DON'T connect to DE9 or DB25!!!
+ *	1 - RxD <---->	Pin 3 (TxD) <->	Pin 2 (TxD)
+ *	2 - GND <---->	Pin 5 (GND) <->	Pin 7 (GND)
+ *	4 - TxD <---->	Pin 2 (RxD) <->	Pin 3 (RxD)
+ *	3 - +12V (from HDD drive connector), DON'T connect to DE9 or DB25!!!
  *
  * Pin numbers for DE9 and DB25 are noted on the plug (quite small:). For
  * RJ10, it's like this:
diff --git a/drivers/input/keyboard/locomokbd.c b/drivers/input/keyboard/locomokbd.c
--- a/drivers/input/keyboard/locomokbd.c
+++ b/drivers/input/keyboard/locomokbd.c
@@ -42,7 +42,7 @@ MODULE_AUTHOR("John Lenz <lenz@cs.wisc.e
 MODULE_DESCRIPTION("LoCoMo keyboard driver");
 MODULE_LICENSE("GPL");
 
-#define LOCOMOKBD_NUMKEYS 	128
+#define LOCOMOKBD_NUMKEYS	128
 
 #define KEY_ACTIVITY		KEY_F16
 #define KEY_CONTACT		KEY_F18
@@ -61,7 +61,7 @@ static unsigned char locomokbd_keycode[L
 	KEY_G, KEY_F, KEY_X, KEY_S, 0, 0, 0, 0, 0, 0,				/* 90 - 99 */
 	0, 0, KEY_DOT, 0, KEY_COMMA, KEY_N, KEY_B, KEY_C, KEY_Z, KEY_A,		/* 100 - 109 */
 	KEY_LEFTSHIFT, KEY_TAB, KEY_LEFTCTRL, 0, 0, 0, 0, 0, 0, 0,		/* 110 - 119 */
-	KEY_M, KEY_SPACE, KEY_V, KEY_APOSTROPHE, KEY_SLASH, 0, 0, 0 		/* 120 - 128 */
+	KEY_M, KEY_SPACE, KEY_V, KEY_APOSTROPHE, KEY_SLASH, 0, 0, 0		/* 120 - 128 */
 };
 
 #define KB_ROWS			16
@@ -82,7 +82,7 @@ struct locomokbd {
 	struct locomo_dev *ldev;
 	unsigned long base;
 	spinlock_t lock;
-	
+
 	struct timer_list timer;
 };
 
@@ -95,7 +95,7 @@ static inline void locomokbd_charge_all(
 static inline void locomokbd_activate_all(unsigned long membase)
 {
 	unsigned long r;
-	
+
 	locomo_writel(0, membase + LOCOMO_KSC);
 	r = locomo_readl(membase + LOCOMO_KIC);
 	r &= 0xFEFF;
@@ -127,7 +127,7 @@ static inline void locomokbd_reset_col(u
  */
 
 /* Scan the hardware keyboard and push any changes up through the input layer */
-static void locomokbd_scankeyboard(struct locomokbd *locomokbd, struct pt_regs *regs) 
+static void locomokbd_scankeyboard(struct locomokbd *locomokbd, struct pt_regs *regs)
 {
 	unsigned int row, col, rowd, scancode;
 	unsigned long flags;
@@ -138,7 +138,7 @@ static void locomokbd_scankeyboard(struc
 
 	if (regs)
 		input_regs(&locomokbd->input, regs);
-	
+
 	locomokbd_charge_all(membase);
 
 	num_pressed = 0;
@@ -146,9 +146,9 @@ static void locomokbd_scankeyboard(struc
 
 		locomokbd_activate_col(membase, col);
 		udelay(KB_DELAY);
-		 
+
 		rowd = ~locomo_readl(membase + LOCOMO_KIB);
-		for (row = 0; row < KB_ROWS; row++ ) {
+		for (row = 0; row < KB_ROWS; row++) {
 			scancode = SCANCODE(col, row);
 			if (rowd & KB_ROWMASK(row)) {
 				num_pressed += 1;
@@ -170,7 +170,7 @@ static void locomokbd_scankeyboard(struc
 	spin_unlock_irqrestore(&locomokbd->lock, flags);
 }
 
-/* 
+/*
  * LoCoMo keyboard interrupt handler.
  */
 static irqreturn_t locomokbd_interrupt(int irq, void *dev_id, struct pt_regs *regs)
@@ -205,8 +205,8 @@ static int locomokbd_probe(struct locomo
 	memset(locomokbd, 0, sizeof(struct locomokbd));
 
 	/* try and claim memory region */
-	if (!request_mem_region((unsigned long) dev->mapbase, 
-				dev->length, 
+	if (!request_mem_region((unsigned long) dev->mapbase,
+				dev->length,
 				LOCOMO_DRIVER_NAME(dev))) {
 		ret = -EBUSY;
 		printk(KERN_ERR "locomokbd: Can't acquire access to io memory for keyboard\n");
@@ -225,7 +225,7 @@ static int locomokbd_probe(struct locomo
 	locomokbd->timer.data = (unsigned long) locomokbd;
 
 	locomokbd->input.evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
-	
+
 	init_input_dev(&locomokbd->input);
 	locomokbd->input.keycode = locomokbd->keycode;
 	locomokbd->input.keycodesize = sizeof(unsigned char);
@@ -271,11 +271,11 @@ free:
 static int locomokbd_remove(struct locomo_dev *dev)
 {
 	struct locomokbd *locomokbd = locomo_get_drvdata(dev);
-	
+
 	free_irq(dev->irq[0], locomokbd);
 
 	del_timer_sync(&locomokbd->timer);
-	
+
 	input_unregister_device(&locomokbd->input);
 	locomo_set_drvdata(dev, NULL);
 
diff --git a/drivers/input/keyboard/maple_keyb.c b/drivers/input/keyboard/maple_keyb.c
--- a/drivers/input/keyboard/maple_keyb.c
+++ b/drivers/input/keyboard/maple_keyb.c
@@ -1,6 +1,6 @@
 /*
  *	$Id: maple_keyb.c,v 1.4 2004/03/22 01:18:15 lethal Exp $
- * 	SEGA Dreamcast keyboard driver
+ *	SEGA Dreamcast keyboard driver
  *	Based on drivers/usb/usbkbd.c
  */
 
@@ -40,7 +40,6 @@ struct dc_kbd {
 	struct input_dev dev;
 	unsigned char new[8];
 	unsigned char old[8];
-	int open;
 };
 
 
@@ -95,22 +94,6 @@ static void dc_kbd_callback(struct maple
 	}
 }
 
-
-static int dc_kbd_open(struct input_dev *dev)
-{
-	struct dc_kbd *kbd = dev->private;
-	kbd->open++;
-	return 0;
-}
-
-
-static void dc_kbd_close(struct input_dev *dev)
-{
-	struct dc_kbd *kbd = dev->private;
-	kbd->open--;
-}
-
-
 static int dc_kbd_connect(struct maple_device *dev)
 {
 	int i;
@@ -133,9 +116,6 @@ static int dc_kbd_connect(struct maple_d
 	clear_bit(0, kbd->dev.keybit);
 
 	kbd->dev.private = kbd;
-	kbd->dev.open = dc_kbd_open;
-	kbd->dev.close = dc_kbd_close;
-	kbd->dev.event = NULL;
 
 	kbd->dev.name = dev->product_name;
 	kbd->dev.id.bustype = BUS_MAPLE;
diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c
--- a/drivers/input/misc/uinput.c
+++ b/drivers/input/misc/uinput.c
@@ -36,16 +36,6 @@
 #include <linux/miscdevice.h>
 #include <linux/uinput.h>
 
-static int uinput_dev_open(struct input_dev *dev)
-{
-	return 0;
-}
-
-static void uinput_dev_close(struct input_dev *dev)
-{
-
-}
-
 static int uinput_dev_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
 {
 	struct uinput_device	*udev;
@@ -63,22 +53,24 @@ static int uinput_dev_event(struct input
 	return 0;
 }
 
-static int uinput_request_alloc_id(struct input_dev *dev, struct uinput_request *request)
+static int uinput_request_alloc_id(struct uinput_device *udev, struct uinput_request *request)
 {
 	/* Atomically allocate an ID for the given request. Returns 0 on success. */
-	struct uinput_device *udev = dev->private;
 	int id;
+	int err = -1;
 
-	down(&udev->requests_sem);
-	for (id=0; id<UINPUT_NUM_REQUESTS; id++)
+	spin_lock(&udev->requests_lock);
+
+	for (id = 0; id < UINPUT_NUM_REQUESTS; id++)
 		if (!udev->requests[id]) {
-			udev->requests[id] = request;
 			request->id = id;
-			up(&udev->requests_sem);
-			return 0;
+			udev->requests[id] = request;
+			err = 0;
+			break;
 		}
-	up(&udev->requests_sem);
-	return -1;
+
+	spin_unlock(&udev->requests_lock);
+	return err;
 }
 
 static struct uinput_request* uinput_request_find(struct uinput_device *udev, int id)
@@ -86,70 +78,78 @@ static struct uinput_request* uinput_req
 	/* Find an input request, by ID. Returns NULL if the ID isn't valid. */
 	if (id >= UINPUT_NUM_REQUESTS || id < 0)
 		return NULL;
-	if (udev->requests[id]->completed)
-		return NULL;
 	return udev->requests[id];
 }
 
-static void uinput_request_init(struct input_dev *dev, struct uinput_request *request, int code)
+static inline int uinput_request_reserve_slot(struct uinput_device *udev, struct uinput_request *request)
 {
-	struct uinput_device *udev = dev->private;
+	/* Allocate slot. If none are available right away, wait. */
+	return wait_event_interruptible(udev->requests_waitq,
+					!uinput_request_alloc_id(udev, request));
+}
 
-	memset(request, 0, sizeof(struct uinput_request));
-	request->code = code;
-	init_waitqueue_head(&request->waitq);
+static void uinput_request_done(struct uinput_device *udev, struct uinput_request *request)
+{
+	complete(&request->done);
 
-	/* Allocate an ID. If none are available right away, wait. */
-	request->retval = wait_event_interruptible(udev->requests_waitq,
-				       !uinput_request_alloc_id(dev, request));
+	/* Mark slot as available */
+	udev->requests[request->id] = NULL;
+	wake_up_interruptible(&udev->requests_waitq);
 }
 
-static void uinput_request_submit(struct input_dev *dev, struct uinput_request *request)
+static int uinput_request_submit(struct input_dev *dev, struct uinput_request *request)
 {
-	struct uinput_device *udev = dev->private;
 	int retval;
 
 	/* Tell our userspace app about this new request by queueing an input event */
 	uinput_dev_event(dev, EV_UINPUT, request->code, request->id);
 
 	/* Wait for the request to complete */
-	retval = wait_event_interruptible(request->waitq, request->completed);
-	if (retval)
-		request->retval = retval;
+	retval = wait_for_completion_interruptible(&request->done);
+	if (!retval)
+		retval = request->retval;
 
-	/* Release this request's ID, let others know it's available */
-	udev->requests[request->id] = NULL;
-	wake_up_interruptible(&udev->requests_waitq);
+	return retval;
 }
 
 static int uinput_dev_upload_effect(struct input_dev *dev, struct ff_effect *effect)
 {
 	struct uinput_request request;
+	int retval;
 
 	if (!test_bit(EV_FF, dev->evbit))
 		return -ENOSYS;
 
-	uinput_request_init(dev, &request, UI_FF_UPLOAD);
-	if (request.retval)
-		return request.retval;
+	request.id = -1;
+	init_completion(&request.done);
+	request.code = UI_FF_UPLOAD;
 	request.u.effect = effect;
-	uinput_request_submit(dev, &request);
-	return request.retval;
+
+	retval = uinput_request_reserve_slot(dev->private, &request);
+	if (!retval)
+		retval = uinput_request_submit(dev, &request);
+
+	return retval;
 }
 
 static int uinput_dev_erase_effect(struct input_dev *dev, int effect_id)
 {
 	struct uinput_request request;
+	int retval;
 
 	if (!test_bit(EV_FF, dev->evbit))
 		return -ENOSYS;
 
-	uinput_request_init(dev, &request, UI_FF_ERASE);
-	if (request.retval)
-		return request.retval;
+	request.id = -1;
+	init_completion(&request.done);
+	request.code = UI_FF_ERASE;
 	request.u.effect_id = effect_id;
-	uinput_request_submit(dev, &request);
-	return request.retval;
+
+	retval = uinput_request_reserve_slot(dev->private, &request);
+	if (!retval)
+		retval = uinput_request_submit(dev, &request);
+
+	return retval;
 }
 
 static int uinput_create_device(struct uinput_device *udev)
@@ -159,32 +159,30 @@ static int uinput_create_device(struct u
 		return -EINVAL;
 	}
 
-	udev->dev->open = uinput_dev_open;
-	udev->dev->close = uinput_dev_close;
 	udev->dev->event = uinput_dev_event;
 	udev->dev->upload_effect = uinput_dev_upload_effect;
 	udev->dev->erase_effect = uinput_dev_erase_effect;
 	udev->dev->private = udev;
 
-	init_waitqueue_head(&(udev->waitq));
+	init_waitqueue_head(&udev->waitq);
 
 	input_register_device(udev->dev);
 
-	set_bit(UIST_CREATED, &(udev->state));
+	set_bit(UIST_CREATED, &udev->state);
 
 	return 0;
 }
 
 static int uinput_destroy_device(struct uinput_device *udev)
 {
-	if (!test_bit(UIST_CREATED, &(udev->state))) {
+	if (!test_bit(UIST_CREATED, &udev->state)) {
 		printk(KERN_WARNING "%s: create the device first\n", UINPUT_NAME);
 		return -EINVAL;
 	}
 
 	input_unregister_device(udev->dev);
 
-	clear_bit(UIST_CREATED, &(udev->state));
+	clear_bit(UIST_CREATED, &udev->state);
 
 	return 0;
 }
@@ -198,7 +196,7 @@ static int uinput_open(struct inode *ino
 	if (!newdev)
 		goto error;
 	memset(newdev, 0, sizeof(struct uinput_device));
-	init_MUTEX(&newdev->requests_sem);
+	spin_lock_init(&newdev->requests_lock);
 	init_waitqueue_head(&newdev->requests_waitq);
 
 	newinput = kmalloc(sizeof(struct input_dev), GFP_KERNEL);
@@ -253,15 +251,16 @@ static int uinput_alloc_device(struct fi
 	struct uinput_user_dev	*user_dev;
 	struct input_dev	*dev;
 	struct uinput_device	*udev;
-	int			size,
-				retval;
+	char			*name;
+	int			size;
+	int			retval;
 
 	retval = count;
 
 	udev = file->private_data;
 	dev = udev->dev;
 
-	user_dev = kmalloc(sizeof(*user_dev), GFP_KERNEL);
+	user_dev = kmalloc(sizeof(struct uinput_user_dev), GFP_KERNEL);
 	if (!user_dev) {
 		retval = -ENOMEM;
 		goto exit;
@@ -272,17 +271,17 @@ static int uinput_alloc_device(struct fi
 		goto exit;
 	}
 
-	if (NULL != dev->name)
+	if (dev->name)
 		kfree(dev->name);
 
 	size = strnlen(user_dev->name, UINPUT_MAX_NAME_SIZE) + 1;
-	dev->name = kmalloc(size, GFP_KERNEL);
-	if (!dev->name) {
+	dev->name = name = kmalloc(size, GFP_KERNEL);
+	if (!name) {
 		retval = -ENOMEM;
 		goto exit;
 	}
+	strlcpy(name, user_dev->name, size);
 
-	strlcpy(dev->name, user_dev->name, size);
 	dev->id.bustype	= user_dev->id.bustype;
 	dev->id.vendor	= user_dev->id.vendor;
 	dev->id.product	= user_dev->id.product;
@@ -298,9 +297,11 @@ static int uinput_alloc_device(struct fi
 	/* check if absmin/absmax/absfuzz/absflat are filled as
 	 * told in Documentation/input/input-programming.txt */
 	if (test_bit(EV_ABS, dev->evbit)) {
-		retval = uinput_validate_absbits(dev);
-		if (retval < 0)
+		int err = uinput_validate_absbits(dev);
+		if (err < 0) {
+			retval = err;
 			kfree(dev->name);
+		}
 	}
 
 exit:
@@ -312,14 +313,13 @@ static ssize_t uinput_write(struct file 
 {
 	struct uinput_device *udev = file->private_data;
 
-	if (test_bit(UIST_CREATED, &(udev->state))) {
+	if (test_bit(UIST_CREATED, &udev->state)) {
 		struct input_event	ev;
 
 		if (copy_from_user(&ev, buffer, sizeof(struct input_event)))
 			return -EFAULT;
 		input_event(udev->dev, ev.type, ev.code, ev.value);
-	}
-	else
+	} else
 		count = uinput_alloc_device(file, buffer, count);
 
 	return count;
@@ -330,26 +330,24 @@ static ssize_t uinput_read(struct file *
 	struct uinput_device *udev = file->private_data;
 	int retval = 0;
 
-	if (!test_bit(UIST_CREATED, &(udev->state)))
+	if (!test_bit(UIST_CREATED, &udev->state))
 		return -ENODEV;
 
-	if ((udev->head == udev->tail) && (file->f_flags & O_NONBLOCK))
+	if (udev->head == udev->tail && (file->f_flags & O_NONBLOCK))
 		return -EAGAIN;
 
 	retval = wait_event_interruptible(udev->waitq,
-			(udev->head != udev->tail) ||
-			!test_bit(UIST_CREATED, &(udev->state)));
-
+			udev->head != udev->tail || !test_bit(UIST_CREATED, &udev->state));
 	if (retval)
 		return retval;
 
-	if (!test_bit(UIST_CREATED, &(udev->state)))
+	if (!test_bit(UIST_CREATED, &udev->state))
 		return -ENODEV;
 
 	while ((udev->head != udev->tail) &&
 	    (retval + sizeof(struct input_event) <= count)) {
-		if (copy_to_user(buffer + retval, &(udev->buff[udev->tail]),
-		    sizeof(struct input_event))) return -EFAULT;
+		if (copy_to_user(buffer + retval, &udev->buff[udev->tail], sizeof(struct input_event)))
+			return -EFAULT;
 		udev->tail = (udev->tail + 1) % UINPUT_BUFFER_SIZE;
 		retval += sizeof(struct input_event);
 	}
@@ -371,12 +369,12 @@ static unsigned int uinput_poll(struct f
 
 static int uinput_burn_device(struct uinput_device *udev)
 {
-	if (test_bit(UIST_CREATED, &(udev->state)))
+	if (test_bit(UIST_CREATED, &udev->state))
 		uinput_destroy_device(udev);
 
-	if (NULL != udev->dev->name)
+	if (udev->dev->name)
 		kfree(udev->dev->name);
-	if (NULL != udev->dev->phys)
+	if (udev->dev->phys)
 		kfree(udev->dev->phys);
 
 	kfree(udev->dev);
@@ -387,7 +385,8 @@ static int uinput_burn_device(struct uin
 
 static int uinput_close(struct inode *inode, struct file *file)
 {
-	return uinput_burn_device(file->private_data);
+	uinput_burn_device(file->private_data);
+	return 0;
 }
 
 static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
@@ -399,6 +398,7 @@ static int uinput_ioctl(struct inode *in
 	struct uinput_ff_erase  ff_erase;
 	struct uinput_request   *req;
 	int                     length;
+	char			*phys;
 
 	udev = file->private_data;
 
@@ -413,7 +413,7 @@ static int uinput_ioctl(struct inode *in
 		case UI_SET_SNDBIT:
 		case UI_SET_FFBIT:
 		case UI_SET_PHYS:
-			if (test_bit(UIST_CREATED, &(udev->state)))
+			if (test_bit(UIST_CREATED, &udev->state))
 				return -EINVAL;
 	}
 
@@ -496,20 +496,19 @@ static int uinput_ioctl(struct inode *in
 				retval = -EFAULT;
 				break;
 			}
-			if (NULL != udev->dev->phys)
-				kfree(udev->dev->phys);
-			udev->dev->phys = kmalloc(length, GFP_KERNEL);
-			if (!udev->dev->phys) {
+			kfree(udev->dev->phys);
+			udev->dev->phys = phys = kmalloc(length, GFP_KERNEL);
+			if (!phys) {
 				retval = -ENOMEM;
 				break;
 			}
-			if (copy_from_user(udev->dev->phys, p, length)) {
-				retval = -EFAULT;
-				kfree(udev->dev->phys);
+			if (copy_from_user(phys, p, length)) {
 				udev->dev->phys = NULL;
+				kfree(phys);
+				retval = -EFAULT;
 				break;
 			}
-			udev->dev->phys[length-1] = '\0';
+			phys[length - 1] = '\0';
 			break;
 
 		case UI_BEGIN_FF_UPLOAD:
@@ -518,7 +517,7 @@ static int uinput_ioctl(struct inode *in
 				break;
 			}
 			req = uinput_request_find(udev, ff_up.request_id);
-			if (!(req && req->code==UI_FF_UPLOAD && req->u.effect)) {
+			if (!(req && req->code == UI_FF_UPLOAD && req->u.effect)) {
 				retval = -EINVAL;
 				break;
 			}
@@ -536,7 +535,7 @@ static int uinput_ioctl(struct inode *in
 				break;
 			}
 			req = uinput_request_find(udev, ff_erase.request_id);
-			if (!(req && req->code==UI_FF_ERASE)) {
+			if (!(req && req->code == UI_FF_ERASE)) {
 				retval = -EINVAL;
 				break;
 			}
@@ -554,14 +553,13 @@ static int uinput_ioctl(struct inode *in
 				break;
 			}
 			req = uinput_request_find(udev, ff_up.request_id);
-			if (!(req && req->code==UI_FF_UPLOAD && req->u.effect)) {
+			if (!(req && req->code == UI_FF_UPLOAD && req->u.effect)) {
 				retval = -EINVAL;
 				break;
 			}
 			req->retval = ff_up.retval;
 			memcpy(req->u.effect, &ff_up.effect, sizeof(struct ff_effect));
-			req->completed = 1;
-			wake_up_interruptible(&req->waitq);
+			uinput_request_done(udev, req);
 			break;
 
 		case UI_END_FF_ERASE:
@@ -570,13 +568,12 @@ static int uinput_ioctl(struct inode *in
 				break;
 			}
 			req = uinput_request_find(udev, ff_erase.request_id);
-			if (!(req && req->code==UI_FF_ERASE)) {
+			if (!(req && req->code == UI_FF_ERASE)) {
 				retval = -EINVAL;
 				break;
 			}
 			req->retval = ff_erase.retval;
-			req->completed = 1;
-			wake_up_interruptible(&req->waitq);
+			uinput_request_done(udev, req);
 			break;
 
 		default:
diff --git a/drivers/input/mouse/Makefile b/drivers/input/mouse/Makefile
--- a/drivers/input/mouse/Makefile
+++ b/drivers/input/mouse/Makefile
@@ -15,4 +15,4 @@ obj-$(CONFIG_MOUSE_SERIAL)	+= sermouse.o
 obj-$(CONFIG_MOUSE_HIL)		+= hil_ptr.o
 obj-$(CONFIG_MOUSE_VSXXXAA)	+= vsxxxaa.o
 
-psmouse-objs  := psmouse-base.o alps.o logips2pp.o synaptics.o
+psmouse-objs  := psmouse-base.o alps.o logips2pp.o synaptics.o lifebook.o
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
--- a/drivers/input/mouse/alps.c
+++ b/drivers/input/mouse/alps.c
@@ -2,7 +2,7 @@
  * ALPS touchpad PS/2 mouse driver
  *
  * Copyright (c) 2003 Neil Brown <neilb@cse.unsw.edu.au>
- * Copyright (c) 2003 Peter Osterlund <petero2@telia.com>
+ * Copyright (c) 2003-2005 Peter Osterlund <petero2@telia.com>
  * Copyright (c) 2004 Dmitry Torokhov <dtor@mail.ru>
  * Copyright (c) 2005 Vojtech Pavlik <vojtech@suse.cz>
  *
@@ -30,10 +30,11 @@
 
 #define ALPS_DUALPOINT	0x01
 #define ALPS_WHEEL	0x02
-#define ALPS_FW_BK	0x04
+#define ALPS_FW_BK_1	0x04
 #define ALPS_4BTN	0x08
 #define ALPS_OLDPROTO	0x10
 #define ALPS_PASS	0x20
+#define ALPS_FW_BK_2	0x40
 
 static struct alps_model_info alps_model_data[] = {
 	{ { 0x33, 0x02, 0x0a },	0x88, 0xf8, ALPS_OLDPROTO },		/* UMAX-530T */
@@ -43,11 +44,11 @@ static struct alps_model_info alps_model
 	{ { 0x63, 0x02, 0x14 },	0xf8, 0xf8, 0 },
 	{ { 0x63, 0x02, 0x28 },	0xf8, 0xf8, 0 },
 	{ { 0x63, 0x02, 0x3c },	0x8f, 0x8f, ALPS_WHEEL },		/* Toshiba Satellite S2400-103 */
-	{ { 0x63, 0x02, 0x50 },	0xef, 0xef, ALPS_FW_BK },		/* NEC Versa L320 */
+	{ { 0x63, 0x02, 0x50 },	0xef, 0xef, ALPS_FW_BK_1 },		/* NEC Versa L320 */
 	{ { 0x63, 0x02, 0x64 },	0xf8, 0xf8, 0 },
 	{ { 0x63, 0x03, 0xc8 }, 0xf8, 0xf8, ALPS_PASS },		/* Dell Latitude D800 */
 	{ { 0x73, 0x02, 0x0a },	0xf8, 0xf8, 0 },
-	{ { 0x73, 0x02, 0x14 },	0xf8, 0xf8, 0 },
+	{ { 0x73, 0x02, 0x14 },	0xf8, 0xf8, ALPS_FW_BK_2 },		/* Ahtec Laptop */
 	{ { 0x20, 0x02, 0x0e },	0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* XXX */
 	{ { 0x22, 0x02, 0x0a },	0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT },
 	{ { 0x22, 0x02, 0x14 }, 0xff, 0xff, ALPS_PASS | ALPS_DUALPOINT }, /* Dell Latitude D600 */
@@ -61,11 +62,11 @@ static struct alps_model_info alps_model
 
 /*
  * ALPS abolute Mode - new format
- * 
- * byte 0:  1    ?    ?    ?    1    ?    ?    ? 
+ *
+ * byte 0:  1    ?    ?    ?    1    ?    ?    ?
  * byte 1:  0   x6   x5   x4   x3   x2   x1   x0
  * byte 2:  0   x10  x9   x8   x7    ?  fin  ges
- * byte 3:  0   y9   y8   y7    1    M    R    L 
+ * byte 3:  0   y9   y8   y7    1    M    R    L
  * byte 4:  0   y6   y5   y4   y3   y2   y1   y0
  * byte 5:  0   z6   z5   z4   z3   z2   z1   z0
  *
@@ -81,11 +82,12 @@ static void alps_process_packet(struct p
 	struct input_dev *dev = &psmouse->dev;
 	struct input_dev *dev2 = &priv->dev2;
 	int x, y, z, ges, fin, left, right, middle;
+	int back = 0, forward = 0;
 
 	input_regs(dev, regs);
 
 	if ((packet[0] & 0xc8) == 0x08) {   /* 3-byte PS/2 packet */
-		input_report_key(dev2, BTN_LEFT,   packet[0] & 1);    
+		input_report_key(dev2, BTN_LEFT,   packet[0] & 1);
 		input_report_key(dev2, BTN_RIGHT,  packet[0] & 2);
 		input_report_key(dev2, BTN_MIDDLE, packet[0] & 4);
 		input_report_rel(dev2, REL_X,
@@ -112,6 +114,18 @@ static void alps_process_packet(struct p
 		z = packet[5];
 	}
 
+	if (priv->i->flags & ALPS_FW_BK_1) {
+		back = packet[2] & 4;
+		forward = packet[0] & 0x10;
+	}
+
+	if (priv->i->flags & ALPS_FW_BK_2) {
+		back = packet[3] & 4;
+		forward = packet[2] & 4;
+		if ((middle = forward && back))
+			forward = back = 0;
+	}
+
 	ges = packet[2] & 1;
 	fin = packet[2] & 2;
 
@@ -155,13 +169,12 @@ static void alps_process_packet(struct p
 	input_report_abs(dev, ABS_PRESSURE, z);
 	input_report_key(dev, BTN_TOOL_FINGER, z > 0);
 
-
 	if (priv->i->flags & ALPS_WHEEL)
 		input_report_rel(dev, REL_WHEEL, ((packet[0] >> 4) & 0x07) | ((packet[2] >> 2) & 0x08));
 
-	if (priv->i->flags & ALPS_FW_BK) {
-		input_report_key(dev, BTN_FORWARD, packet[0] & 0x10);
-		input_report_key(dev, BTN_BACK, packet[2] & 0x04);
+	if (priv->i->flags & (ALPS_FW_BK_1 | ALPS_FW_BK_2)) {
+		input_report_key(dev, BTN_FORWARD, forward);
+		input_report_key(dev, BTN_BACK, back);
 	}
 
 	input_sync(dev);
@@ -257,7 +270,6 @@ static struct alps_model_info *alps_get_
 static int alps_passthrough_mode(struct psmouse *psmouse, int enable)
 {
 	struct ps2dev *ps2dev = &psmouse->ps2dev;
-	unsigned char param[3];
 	int cmd = enable ? PSMOUSE_CMD_SETSCALE21 : PSMOUSE_CMD_SETSCALE11;
 
 	if (ps2_command(ps2dev, NULL, cmd) ||
@@ -267,7 +279,7 @@ static int alps_passthrough_mode(struct 
 		return -1;
 
 	/* we may get 3 more bytes, just ignore them */
-	ps2_command(ps2dev, param, 0x0300);
+	ps2_drain(ps2dev, 3, 100);
 
 	return 0;
 }
@@ -338,7 +350,6 @@ static int alps_tap_mode(struct psmouse 
 static int alps_reconnect(struct psmouse *psmouse)
 {
 	struct alps_data *priv = psmouse->private;
-	unsigned char param[4];
 	int version;
 
 	psmouse_reset(psmouse);
@@ -346,21 +357,20 @@ static int alps_reconnect(struct psmouse
 	if (!(priv->i = alps_get_model(psmouse, &version)))
 		return -1;
 
-	if (priv->i->flags & ALPS_PASS && alps_passthrough_mode(psmouse, 1))
+	if ((priv->i->flags & ALPS_PASS) && alps_passthrough_mode(psmouse, 1))
 		return -1;
 
-	if (alps_get_status(psmouse, param))
+	if (alps_tap_mode(psmouse, 1)) {
+		printk(KERN_WARNING "alps.c: Failed to reenable hardware tapping\n");
 		return -1;
-
-	if (!(param[0] & 0x04))
-		alps_tap_mode(psmouse, 1);
+	}
 
 	if (alps_absolute_mode(psmouse)) {
-		printk(KERN_ERR "alps.c: Failed to enable absolute mode\n");
+		printk(KERN_ERR "alps.c: Failed to reenable absolute mode\n");
 		return -1;
 	}
 
-	if (priv->i->flags == ALPS_PASS && alps_passthrough_mode(psmouse, 0))
+	if ((priv->i->flags & ALPS_PASS) && alps_passthrough_mode(psmouse, 0))
 		return -1;
 
 	return 0;
@@ -377,7 +387,6 @@ static void alps_disconnect(struct psmou
 int alps_init(struct psmouse *psmouse)
 {
 	struct alps_data *priv;
-	unsigned char param[4];
 	int version;
 
 	psmouse->private = priv = kmalloc(sizeof(struct alps_data), GFP_KERNEL);
@@ -391,16 +400,8 @@ int alps_init(struct psmouse *psmouse)
 	if ((priv->i->flags & ALPS_PASS) && alps_passthrough_mode(psmouse, 1))
 		goto init_fail;
 
-	if (alps_get_status(psmouse, param)) {
-		printk(KERN_ERR "alps.c: touchpad status report request failed\n");
-		goto init_fail;
-	}
-
-	if (param[0] & 0x04) {
-		printk(KERN_INFO "alps.c: Enabling hardware tapping\n");
-		if (alps_tap_mode(psmouse, 1))
-			printk(KERN_WARNING "alps.c: Failed to enable hardware tapping\n");
-	}
+	if (alps_tap_mode(psmouse, 1))
+		printk(KERN_WARNING "alps.c: Failed to enable hardware tapping\n");
 
 	if (alps_absolute_mode(psmouse)) {
 		printk(KERN_ERR "alps.c: Failed to enable absolute mode\n");
@@ -425,7 +426,7 @@ int alps_init(struct psmouse *psmouse)
 		psmouse->dev.relbit[LONG(REL_WHEEL)] |= BIT(REL_WHEEL);
 	}
 
-	if (priv->i->flags & ALPS_FW_BK) {
+	if (priv->i->flags & (ALPS_FW_BK_1 | ALPS_FW_BK_2)) {
 		psmouse->dev.keybit[LONG(BTN_FORWARD)] |= BIT(BTN_FORWARD);
 		psmouse->dev.keybit[LONG(BTN_BACK)] |= BIT(BTN_BACK);
 	}
@@ -436,8 +437,8 @@ int alps_init(struct psmouse *psmouse)
 	priv->dev2.id.bustype = BUS_I8042;
 	priv->dev2.id.vendor = 0x0002;
 	priv->dev2.id.product = PSMOUSE_ALPS;
-	priv->dev2.id.version = 0x0000; 
-	
+	priv->dev2.id.version = 0x0000;
+
 	priv->dev2.evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
 	priv->dev2.relbit[LONG(REL_X)] |= BIT(REL_X) | BIT(REL_Y);
 	priv->dev2.keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
@@ -461,17 +462,15 @@ init_fail:
 int alps_detect(struct psmouse *psmouse, int set_properties)
 {
 	int version;
-	struct alps_model_info *model; 
+	struct alps_model_info *model;
 
 	if (!(model = alps_get_model(psmouse, &version)))
 		return -1;
 
 	if (set_properties) {
 		psmouse->vendor = "ALPS";
-		if (model->flags & ALPS_DUALPOINT) 
-			psmouse->name = "DualPoint TouchPad";
-		else
-			psmouse->name = "GlidePoint";
+		psmouse->name = model->flags & ALPS_DUALPOINT ?
+				"DualPoint TouchPad" : "GlidePoint";
 		psmouse->model = version;
 	}
 	return 0;
diff --git a/drivers/input/mouse/amimouse.c b/drivers/input/mouse/amimouse.c
--- a/drivers/input/mouse/amimouse.c
+++ b/drivers/input/mouse/amimouse.c
@@ -33,7 +33,6 @@ MODULE_AUTHOR("Vojtech Pavlik <vojtech@u
 MODULE_DESCRIPTION("Amiga mouse driver");
 MODULE_LICENSE("GPL");
 
-static int amimouse_used = 0;
 static int amimouse_lastx, amimouse_lasty;
 static struct input_dev amimouse_dev;
 
@@ -81,16 +80,12 @@ static int amimouse_open(struct input_de
 {
 	unsigned short joy0dat;
 
-        if (amimouse_used++)
-                return 0;
-
 	joy0dat = custom.joy0dat;
 
 	amimouse_lastx = joy0dat & 0xff;
 	amimouse_lasty = joy0dat >> 8;
 
 	if (request_irq(IRQ_AMIGA_VERTB, amimouse_interrupt, 0, "amimouse", amimouse_interrupt)) {
-                amimouse_used--;
                 printk(KERN_ERR "amimouse.c: Can't allocate irq %d\n", IRQ_AMIGA_VERTB);
                 return -EBUSY;
         }
@@ -100,8 +95,7 @@ static int amimouse_open(struct input_de
 
 static void amimouse_close(struct input_dev *dev)
 {
-        if (!--amimouse_used)
-		free_irq(IRQ_AMIGA_VERTB, amimouse_interrupt);
+	free_irq(IRQ_AMIGA_VERTB, amimouse_interrupt);
 }
 
 static int __init amimouse_init(void)
diff --git a/drivers/input/mouse/inport.c b/drivers/input/mouse/inport.c
--- a/drivers/input/mouse/inport.c
+++ b/drivers/input/mouse/inport.c
@@ -17,18 +17,18 @@
 /*
  * 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 
+ * 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
- * 
+ *
  * Should you need to contact me, the author, you can do so either by
  * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
  * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
@@ -87,29 +87,23 @@ MODULE_PARM_DESC(irq, "IRQ number (5=def
 
 __obsolete_setup("inport_irq=");
 
-static int inport_used;
-
 static irqreturn_t inport_interrupt(int irq, void *dev_id, struct pt_regs *regs);
 
 static int inport_open(struct input_dev *dev)
 {
-	if (!inport_used++) {
-		if (request_irq(inport_irq, inport_interrupt, 0, "inport", NULL))
-			return -EBUSY;
-		outb(INPORT_REG_MODE, INPORT_CONTROL_PORT);
-		outb(INPORT_MODE_IRQ | INPORT_MODE_BASE, INPORT_DATA_PORT);
-	}
+	if (request_irq(inport_irq, inport_interrupt, 0, "inport", NULL))
+		return -EBUSY;
+	outb(INPORT_REG_MODE, INPORT_CONTROL_PORT);
+	outb(INPORT_MODE_IRQ | INPORT_MODE_BASE, INPORT_DATA_PORT);
 
 	return 0;
 }
 
 static void inport_close(struct input_dev *dev)
 {
-	if (!--inport_used) {
-		outb(INPORT_REG_MODE, INPORT_CONTROL_PORT);
-		outb(INPORT_MODE_BASE, INPORT_DATA_PORT);
-		free_irq(inport_irq, NULL);
-	}
+	outb(INPORT_REG_MODE, INPORT_CONTROL_PORT);
+	outb(INPORT_MODE_BASE, INPORT_DATA_PORT);
+	free_irq(inport_irq, NULL);
 }
 
 static struct input_dev inport_dev = {
@@ -120,11 +114,11 @@ static struct input_dev inport_dev = {
 	.close	= inport_close,
 	.name	= INPORT_NAME,
 	.phys	= "isa023c/input0",
-	.id = { 
- 		.bustype = BUS_ISA,
-        	.vendor  = INPORT_VENDOR,
-        	.product = 0x0001,
-        	.version = 0x0100,
+	.id = {
+		.bustype = BUS_ISA,
+		.vendor  = INPORT_VENDOR,
+		.product = 0x0001,
+		.version = 0x0100,
 	},
 };
 
diff --git a/drivers/input/mouse/lifebook.c b/drivers/input/mouse/lifebook.c
new file mode 100644
--- /dev/null
+++ b/drivers/input/mouse/lifebook.c
@@ -0,0 +1,134 @@
+/*
+ * Fujitsu B-series Lifebook PS/2 TouchScreen driver
+ *
+ * Copyright (c) 2005 Vojtech Pavlik <vojtech@suse.cz>
+ * Copyright (c) 2005 Kenan Esau <kenan.esau@conan.de>
+ *
+ * TouchScreen detection, absolute mode setting and packet layout is taken from
+ * Harald Hoyer's description of the device.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+
+#include <linux/input.h>
+#include <linux/serio.h>
+#include <linux/libps2.h>
+#include <linux/dmi.h>
+
+#include "psmouse.h"
+#include "lifebook.h"
+
+static struct dmi_system_id lifebook_dmi_table[] = {
+       {
+               .ident = "Lifebook B",
+               .matches = {
+                       DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK B Series"),
+               },
+       },
+       { }
+};
+
+
+static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse, struct pt_regs *regs)
+{
+	unsigned char *packet = psmouse->packet;
+	struct input_dev *dev = &psmouse->dev;
+
+	if (psmouse->pktcnt != 3)
+		return PSMOUSE_GOOD_DATA;
+
+	input_regs(dev, regs);
+
+	/* calculate X and Y */
+	if ((packet[0] & 0x08) == 0x00) {
+		input_report_abs(dev, ABS_X,
+				 (packet[1] | ((packet[0] & 0x30) << 4)));
+		input_report_abs(dev, ABS_Y,
+				 1024 - (packet[2] | ((packet[0] & 0xC0) << 2)));
+	} else {
+		input_report_rel(dev, REL_X,
+				((packet[0] & 0x10) ? packet[1] - 256 : packet[1]));
+		input_report_rel(dev, REL_Y,
+				 -(int)((packet[0] & 0x20) ? packet[2] - 256 : packet[2]));
+	}
+
+	input_report_key(dev, BTN_LEFT, packet[0] & 0x01);
+	input_report_key(dev, BTN_RIGHT, packet[0] & 0x02);
+	input_report_key(dev, BTN_TOUCH, packet[0] & 0x04);
+
+	input_sync(dev);
+
+	return PSMOUSE_FULL_PACKET;
+}
+
+static int lifebook_absolute_mode(struct psmouse *psmouse)
+{
+	struct ps2dev *ps2dev = &psmouse->ps2dev;
+	unsigned char param;
+
+	if (psmouse_reset(psmouse))
+		return -1;
+
+	/*
+	   Enable absolute output -- ps2_command fails always but if
+	   you leave this call out the touchsreen will never send
+	   absolute coordinates
+	*/
+	param = 0x07;
+	ps2_command(ps2dev, &param, PSMOUSE_CMD_SETRES);
+
+	return 0;
+}
+
+static void lifebook_set_resolution(struct psmouse *psmouse, unsigned int resolution)
+{
+	unsigned char params[] = { 0, 1, 2, 2, 3 };
+
+	if (resolution == 0 || resolution > 400)
+		resolution = 400;
+
+	ps2_command(&psmouse->ps2dev, &params[resolution / 100], PSMOUSE_CMD_SETRES);
+	psmouse->resolution = 50 << params[resolution / 100];
+}
+
+static void lifebook_disconnect(struct psmouse *psmouse)
+{
+	psmouse_reset(psmouse);
+}
+
+int lifebook_detect(struct psmouse *psmouse, int set_properties)
+{
+        if (!dmi_check_system(lifebook_dmi_table))
+                return -1;
+
+	if (set_properties) {
+		psmouse->vendor = "Fujitsu";
+		psmouse->name = "Lifebook TouchScreen";
+	}
+
+        return 0;
+}
+
+int lifebook_init(struct psmouse *psmouse)
+{
+	if (lifebook_absolute_mode(psmouse))
+		return -1;
+
+	psmouse->dev.evbit[0] = BIT(EV_ABS) | BIT(EV_KEY) | BIT(EV_REL);
+	psmouse->dev.keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
+	psmouse->dev.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+	psmouse->dev.relbit[0] = BIT(REL_X) | BIT(REL_Y);
+	input_set_abs_params(&psmouse->dev, ABS_X, 0, 1024, 0, 0);
+	input_set_abs_params(&psmouse->dev, ABS_Y, 0, 1024, 0, 0);
+
+	psmouse->protocol_handler = lifebook_process_byte;
+	psmouse->set_resolution = lifebook_set_resolution;
+	psmouse->disconnect = lifebook_disconnect;
+	psmouse->reconnect  = lifebook_absolute_mode;
+	psmouse->pktsize = 3;
+
+	return 0;
+}
+
diff --git a/drivers/input/mouse/lifebook.h b/drivers/input/mouse/lifebook.h
new file mode 100644
--- /dev/null
+++ b/drivers/input/mouse/lifebook.h
@@ -0,0 +1,17 @@
+/*
+ * Fujitsu B-series Lifebook PS/2 TouchScreen driver
+ *
+ * Copyright (c) 2005 Vojtech Pavlik
+ *
+ * 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.
+ */
+
+#ifndef _LIFEBOOK_H
+#define _LIFEBOOK_H
+
+int lifebook_detect(struct psmouse *psmouse, int set_properties);
+int lifebook_init(struct psmouse *psmouse);
+
+#endif
diff --git a/drivers/input/mouse/logibm.c b/drivers/input/mouse/logibm.c
--- a/drivers/input/mouse/logibm.c
+++ b/drivers/input/mouse/logibm.c
@@ -18,18 +18,18 @@
 /*
  * 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 
+ * 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
- * 
+ *
  * Should you need to contact me, the author, you can do so either by
  * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
  * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
@@ -77,16 +77,11 @@ MODULE_PARM_DESC(irq, "IRQ number (5=def
 
 __obsolete_setup("logibm_irq=");
 
-static int logibm_used = 0;
-
 static irqreturn_t logibm_interrupt(int irq, void *dev_id, struct pt_regs *regs);
 
 static int logibm_open(struct input_dev *dev)
 {
-	if (logibm_used++)
-		return 0;
 	if (request_irq(logibm_irq, logibm_interrupt, 0, "logibm", NULL)) {
-		logibm_used--;
 		printk(KERN_ERR "logibm.c: Can't allocate irq %d\n", logibm_irq);
 		return -EBUSY;
 	}
@@ -96,8 +91,6 @@ static int logibm_open(struct input_dev 
 
 static void logibm_close(struct input_dev *dev)
 {
-	if (--logibm_used)
-		return;
 	outb(LOGIBM_DISABLE_IRQ, LOGIBM_CONTROL_PORT);
 	free_irq(logibm_irq, NULL);
 }
@@ -167,7 +160,7 @@ static int __init logibm_init(void)
 	outb(LOGIBM_DISABLE_IRQ, LOGIBM_CONTROL_PORT);
 
 	input_register_device(&logibm_dev);
-	
+
 	printk(KERN_INFO "input: Logitech bus mouse at %#x irq %d\n", LOGIBM_BASE, logibm_irq);
 
 	return 0;
diff --git a/drivers/input/mouse/logips2pp.c b/drivers/input/mouse/logips2pp.c
--- a/drivers/input/mouse/logips2pp.c
+++ b/drivers/input/mouse/logips2pp.c
@@ -385,8 +385,6 @@ int ps2pp_init(struct psmouse *psmouse, 
 
 		if (buttons < 3)
 			clear_bit(BTN_MIDDLE, psmouse->dev.keybit);
-		if (buttons < 2)
-			clear_bit(BTN_RIGHT, psmouse->dev.keybit);
 
 		if (model_info)
 			ps2pp_set_model_properties(psmouse, model_info, use_ps2pp);
diff --git a/drivers/input/mouse/maplemouse.c b/drivers/input/mouse/maplemouse.c
--- a/drivers/input/mouse/maplemouse.c
+++ b/drivers/input/mouse/maplemouse.c
@@ -1,6 +1,6 @@
 /*
  *	$Id: maplemouse.c,v 1.2 2004/03/22 01:18:15 lethal Exp $
- * 	SEGA Dreamcast mouse driver
+ *	SEGA Dreamcast mouse driver
  *	Based on drivers/usb/usbmouse.c
  */
 
@@ -15,80 +15,51 @@
 MODULE_AUTHOR("YAEGASHI Takeshi <t@keshi.org>");
 MODULE_DESCRIPTION("SEGA Dreamcast mouse driver");
 
-struct dc_mouse {
-	struct input_dev dev;
-	int open;
-};
-
-
 static void dc_mouse_callback(struct mapleq *mq)
 {
 	int buttons, relx, rely, relz;
 	struct maple_device *mapledev = mq->dev;
-	struct dc_mouse *mouse = mapledev->private_data;
-	struct input_dev *dev = &mouse->dev;
+	struct input_dev *dev = mapledev->private_data;
 	unsigned char *res = mq->recvbuf;
 
 	buttons = ~res[8];
-	relx=*(unsigned short *)(res+12)-512;
-	rely=*(unsigned short *)(res+14)-512;
-	relz=*(unsigned short *)(res+16)-512;
-
-	input_report_key(dev, BTN_LEFT,   buttons&4);
-	input_report_key(dev, BTN_MIDDLE, buttons&9);
-	input_report_key(dev, BTN_RIGHT,  buttons&2);
+	relx = *(unsigned short *)(res + 12) - 512;
+	rely = *(unsigned short *)(res + 14) - 512;
+	relz = *(unsigned short *)(res + 16) - 512;
+
+	input_report_key(dev, BTN_LEFT,   buttons & 4);
+	input_report_key(dev, BTN_MIDDLE, buttons & 9);
+	input_report_key(dev, BTN_RIGHT,  buttons & 2);
 	input_report_rel(dev, REL_X,      relx);
 	input_report_rel(dev, REL_Y,      rely);
 	input_report_rel(dev, REL_WHEEL,  relz);
 	input_sync(dev);
 }
 
-
-static int dc_mouse_open(struct input_dev *dev)
-{
-	struct dc_mouse *mouse = dev->private;
-	mouse->open++;
-	return 0;
-}
-
-
-static void dc_mouse_close(struct input_dev *dev)
-{
-	struct dc_mouse *mouse = dev->private;
-	mouse->open--;
-}
-
-
 static int dc_mouse_connect(struct maple_device *dev)
 {
 	unsigned long data = be32_to_cpu(dev->devinfo.function_data[0]);
-	struct dc_mouse *mouse;
+	struct input_dev *input_dev;
 
-	if (!(mouse = kmalloc(sizeof(struct dc_mouse), GFP_KERNEL)))
+	if (!(input_dev = kmalloc(sizeof(struct input_dev), GFP_KERNEL)))
 		return -1;
-	memset(mouse, 0, sizeof(struct dc_mouse));
-
-	dev->private_data = mouse;
 
-	mouse->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
-	mouse->dev.keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
-	mouse->dev.relbit[0] = BIT(REL_X) | BIT(REL_Y) | BIT(REL_WHEEL);
+	dev->private_data = input_dev;
 
-	init_input_dev(&mouse->dev);
+	memset(input_dev, 0, sizeof(struct dc_mouse));
+	init_input_dev(input_dev);
+	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
+	input_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
+	input_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y) | BIT(REL_WHEEL);
 
-	mouse->dev.private = mouse;
-	mouse->dev.open = dc_mouse_open;
-	mouse->dev.close = dc_mouse_close;
-	mouse->dev.event = NULL;
+	input_dev->name = dev->product_name;
+	input_dev->id.bustype = BUS_MAPLE;
 
-	mouse->dev.name = dev->product_name;
-	mouse->dev.id.bustype = BUS_MAPLE;
-	
-	input_register_device(&mouse->dev);
+	input_register_device(input_dev);
 
 	maple_getcond_callback(dev, dc_mouse_callback, 1, MAPLE_FUNC_MOUSE);
 
-	printk(KERN_INFO "input: mouse(0x%lx): %s\n", data, mouse->dev.name);
+	printk(KERN_INFO "input: mouse(0x%lx): %s\n", data, input_dev->name);
 
 	return 0;
 }
@@ -96,10 +67,10 @@ static int dc_mouse_connect(struct maple
 
 static void dc_mouse_disconnect(struct maple_device *dev)
 {
-	struct dc_mouse *mouse = dev->private_data;
+	struct input_dev *input_dev = dev->private_data;
 
-	input_unregister_device(&mouse->dev);
-	kfree(mouse);
+	input_unregister_device(input_dev);
+	kfree(input_dev);
 }
 
 
diff --git a/drivers/input/mouse/pc110pad.c b/drivers/input/mouse/pc110pad.c
--- a/drivers/input/mouse/pc110pad.c
+++ b/drivers/input/mouse/pc110pad.c
@@ -4,7 +4,7 @@
  *  Copyright (c) 2000-2001 Vojtech Pavlik
  *
  *  Based on the work of:
- *	Alan Cox	Robin O'Leary	
+ *	Alan Cox	Robin O'Leary
  */
 
 /*
@@ -56,7 +56,6 @@ static int pc110pad_io = 0x15e0;
 static struct input_dev pc110pad_dev;
 static int pc110pad_data[3];
 static int pc110pad_count;
-static int pc110pad_used;
 
 static char *pc110pad_name = "IBM PC110 TouchPad";
 static char *pc110pad_phys = "isa15e0/input0";
@@ -74,7 +73,7 @@ static irqreturn_t pc110pad_interrupt(in
 
 	if (pc110pad_count < 3)
 		return IRQ_HANDLED;
-	
+
 	input_regs(&pc110pad_dev, regs);
 	input_report_key(&pc110pad_dev, BTN_TOUCH,
 		pc110pad_data[0] & 0x01);
@@ -90,15 +89,11 @@ static irqreturn_t pc110pad_interrupt(in
 
 static void pc110pad_close(struct input_dev *dev)
 {
-	if (!--pc110pad_used)
-		outb(PC110PAD_OFF, pc110pad_io + 2);
+	outb(PC110PAD_OFF, pc110pad_io + 2);
 }
 
 static int pc110pad_open(struct input_dev *dev)
 {
-	if (pc110pad_used++)
-		return 0;
-
 	pc110pad_interrupt(0,NULL,NULL);
 	pc110pad_interrupt(0,NULL,NULL);
 	pc110pad_interrupt(0,NULL,NULL);
@@ -145,7 +140,7 @@ static int __init pc110pad_init(void)
 
 	pc110pad_dev.absmax[ABS_X] = 0x1ff;
 	pc110pad_dev.absmax[ABS_Y] = 0x0ff;
-        
+
 	pc110pad_dev.open = pc110pad_open;
         pc110pad_dev.close = pc110pad_close;
 
@@ -156,17 +151,17 @@ static int __init pc110pad_init(void)
 	pc110pad_dev.id.product = 0x0001;
 	pc110pad_dev.id.version = 0x0100;
 
-	input_register_device(&pc110pad_dev);	
+	input_register_device(&pc110pad_dev);
 
 	printk(KERN_INFO "input: %s at %#x irq %d\n",
 		pc110pad_name, pc110pad_io, pc110pad_irq);
-	
+
 	return 0;
 }
- 
+
 static void __exit pc110pad_exit(void)
 {
-	input_unregister_device(&pc110pad_dev);	
+	input_unregister_device(&pc110pad_dev);
 
 	outb(PC110PAD_OFF, pc110pad_io + 2);
 
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
--- a/drivers/input/mouse/psmouse-base.c
+++ b/drivers/input/mouse/psmouse-base.c
@@ -24,6 +24,7 @@
 #include "synaptics.h"
 #include "logips2pp.h"
 #include "alps.h"
+#include "lifebook.h"
 
 #define DRIVER_DESC	"PS/2 mouse driver"
 
@@ -31,10 +32,9 @@ MODULE_AUTHOR("Vojtech Pavlik <vojtech@s
 MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
 
-static unsigned int psmouse_max_proto = -1U;
+static unsigned int psmouse_max_proto = PSMOUSE_AUTO;
 static int psmouse_set_maxproto(const char *val, struct kernel_param *kp);
 static int psmouse_get_maxproto(char *buffer, struct kernel_param *kp);
-static char *psmouse_proto_abbrev[] = { NULL, "bare", NULL, NULL, NULL, "imps", "exps", NULL, NULL, NULL };
 #define param_check_proto_abbrev(name, p)	__param_check(name, p, unsigned int)
 #define param_set_proto_abbrev			psmouse_set_maxproto
 #define param_get_proto_abbrev			psmouse_get_maxproto
@@ -57,6 +57,7 @@ static unsigned int psmouse_resetafter;
 module_param_named(resetafter, psmouse_resetafter, uint, 0644);
 MODULE_PARM_DESC(resetafter, "Reset device after so many bad packets (0 = never).");
 
+PSMOUSE_DEFINE_ATTR(protocol);
 PSMOUSE_DEFINE_ATTR(rate);
 PSMOUSE_DEFINE_ATTR(resolution);
 PSMOUSE_DEFINE_ATTR(resetafter);
@@ -67,7 +68,23 @@ __obsolete_setup("psmouse_smartscroll=")
 __obsolete_setup("psmouse_resetafter=");
 __obsolete_setup("psmouse_rate=");
 
-static char *psmouse_protocols[] = { "None", "PS/2", "PS2++", "ThinkPS/2", "GenPS/2", "ImPS/2", "ImExPS/2", "SynPS/2", "AlpsPS/2" };
+/*
+ * psmouse_sem protects all operations changing state of mouse
+ * (connecting, disconnecting, changing rate or resolution via
+ * sysfs). We could use a per-device semaphore but since there
+ * rarely more than one PS/2 mouse connected and since semaphore
+ * is taken in "slow" paths it is not worth it.
+ */
+static DECLARE_MUTEX(psmouse_sem);
+
+struct psmouse_protocol {
+	enum psmouse_type type;
+	char *name;
+	char *alias;
+	int maxproto;
+	int (*detect)(struct psmouse *, int);
+	int (*init)(struct psmouse *);
+};
 
 /*
  * psmouse_process_byte() analyzes the PS/2 data stream and reports
@@ -327,6 +344,7 @@ static int intellimouse_detect(struct ps
 		return -1;
 
 	if (set_properties) {
+		set_bit(BTN_MIDDLE, psmouse->dev.keybit);
 		set_bit(REL_WHEEL, psmouse->dev.relbit);
 
 		if (!psmouse->vendor) psmouse->vendor = "Generic";
@@ -359,6 +377,7 @@ static int im_explorer_detect(struct psm
 		return -1;
 
 	if (set_properties) {
+		set_bit(BTN_MIDDLE, psmouse->dev.keybit);
 		set_bit(REL_WHEEL, psmouse->dev.relbit);
 		set_bit(BTN_SIDE, psmouse->dev.keybit);
 		set_bit(BTN_EXTRA, psmouse->dev.keybit);
@@ -407,12 +426,15 @@ static int thinking_detect(struct psmous
  */
 static int ps2bare_detect(struct psmouse *psmouse, int set_properties)
 {
-	if (!psmouse->vendor) psmouse->vendor = "Generic";
-	if (!psmouse->name) psmouse->name = "Mouse";
+	if (set_properties) {
+		if (!psmouse->vendor) psmouse->vendor = "Generic";
+		if (!psmouse->name) psmouse->name = "Mouse";
+	}
 
 	return 0;
 }
 
+
 /*
  * psmouse_extensions() probes for any extensions to the basic PS/2 protocol
  * the mouse may have.
@@ -424,6 +446,17 @@ static int psmouse_extensions(struct psm
 	int synaptics_hardware = 0;
 
 /*
+ * We always check for lifebook because it does not disturb mouse
+ * (it only checks DMI information).
+ */
+	if (lifebook_detect(psmouse, set_properties) == 0) {
+		if (max_proto > PSMOUSE_IMEX) {
+			if (!set_properties || lifebook_init(psmouse) == 0)
+				return PSMOUSE_LIFEBOOK;
+		}
+	}
+
+/*
  * Try Kensington ThinkingMouse (we try first, because synaptics probe
  * upsets the thinkingmouse).
  */
@@ -506,6 +539,103 @@ static int psmouse_extensions(struct psm
 	return PSMOUSE_PS2;
 }
 
+static struct psmouse_protocol psmouse_protocols[] = {
+	{
+		.type		= PSMOUSE_PS2,
+		.name		= "PS/2",
+		.alias		= "bare",
+		.maxproto	= 1,
+		.detect		= ps2bare_detect,
+	},
+	{
+		.type		= PSMOUSE_PS2PP,
+		.name		= "PS2++",
+		.alias		= "logitech",
+		.detect		= ps2pp_init,
+	},
+	{
+		.type		= PSMOUSE_THINKPS,
+		.name		= "ThinkPS/2",
+		.alias		= "thinkps",
+		.detect		= thinking_detect,
+	},
+	{
+		.type		= PSMOUSE_GENPS,
+		.name		= "GenPS/2",
+		.alias		= "genius",
+		.detect		= genius_detect,
+	},
+	{
+		.type		= PSMOUSE_IMPS,
+		.name		= "ImPS/2",
+		.alias		= "imps",
+		.maxproto	= 1,
+		.detect		= intellimouse_detect,
+	},
+	{
+		.type		= PSMOUSE_IMEX,
+		.name		= "ImExPS/2",
+		.alias		= "exps",
+		.maxproto	= 1,
+		.detect		= im_explorer_detect,
+	},
+	{
+		.type		= PSMOUSE_SYNAPTICS,
+		.name		= "SynPS/2",
+		.alias		= "synaptics",
+		.detect		= synaptics_detect,
+		.init		= synaptics_init,
+	},
+	{
+		.type		= PSMOUSE_ALPS,
+		.name		= "AlpsPS/2",
+		.alias		= "alps",
+		.detect		= alps_detect,
+		.init		= alps_init,
+	},
+	{
+		.type		= PSMOUSE_LIFEBOOK,
+		.name		= "LBPS/2",
+		.alias		= "lifebook",
+		.init		= lifebook_init,
+	},
+	{
+		.type		= PSMOUSE_AUTO,
+		.name		= "auto",
+		.alias		= "any",
+		.maxproto	= 1,
+	},
+};
+
+static struct psmouse_protocol *psmouse_protocol_by_type(enum psmouse_type type)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(psmouse_protocols); i++)
+		if (psmouse_protocols[i].type == type)
+			return &psmouse_protocols[i];
+
+	WARN_ON(1);
+	return &psmouse_protocols[0];
+}
+
+static struct psmouse_protocol *psmouse_protocol_by_name(const char *name, size_t len)
+{
+	struct psmouse_protocol *p;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(psmouse_protocols); i++) {
+		p = &psmouse_protocols[i];
+
+		if ((strlen(p->name) == len && !strncmp(p->name, name, len)) ||
+		    (strlen(p->alias) == len && !strncmp(p->alias, name, len)))
+			return &psmouse_protocols[i];
+	}
+
+	return NULL;
+}
+
+
 /*
  * psmouse_probe() probes for a PS/2 mouse.
  */
@@ -653,30 +783,84 @@ static void psmouse_cleanup(struct serio
 
 static void psmouse_disconnect(struct serio *serio)
 {
-	struct psmouse *psmouse, *parent;
+	struct psmouse *psmouse, *parent = NULL;
 
+	psmouse = serio_get_drvdata(serio);
+
+	device_remove_file(&serio->dev, &psmouse_attr_protocol);
 	device_remove_file(&serio->dev, &psmouse_attr_rate);
 	device_remove_file(&serio->dev, &psmouse_attr_resolution);
 	device_remove_file(&serio->dev, &psmouse_attr_resetafter);
 
-	psmouse = serio_get_drvdata(serio);
+	down(&psmouse_sem);
+
 	psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);
 
 	if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) {
 		parent = serio_get_drvdata(serio->parent);
-		if (parent->pt_deactivate)
-			parent->pt_deactivate(parent);
+		psmouse_deactivate(parent);
 	}
 
 	if (psmouse->disconnect)
 		psmouse->disconnect(psmouse);
 
+	if (parent && parent->pt_deactivate)
+		parent->pt_deactivate(parent);
+
 	psmouse_set_state(psmouse, PSMOUSE_IGNORE);
 
 	input_unregister_device(&psmouse->dev);
 	serio_close(serio);
 	serio_set_drvdata(serio, NULL);
 	kfree(psmouse);
+
+	if (parent)
+		psmouse_activate(parent);
+
+	up(&psmouse_sem);
+}
+
+static int psmouse_switch_protocol(struct psmouse *psmouse, struct psmouse_protocol *proto)
+{
+	memset(&psmouse->dev, 0, sizeof(struct input_dev));
+
+	init_input_dev(&psmouse->dev);
+
+	psmouse->dev.private = psmouse;
+	psmouse->dev.dev = &psmouse->ps2dev.serio->dev;
+
+	psmouse->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
+	psmouse->dev.keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
+	psmouse->dev.relbit[0] = BIT(REL_X) | BIT(REL_Y);
+
+	psmouse->set_rate = psmouse_set_rate;
+	psmouse->set_resolution = psmouse_set_resolution;
+	psmouse->protocol_handler = psmouse_process_byte;
+	psmouse->pktsize = 3;
+
+	if (proto && (proto->detect || proto->init)) {
+		if (proto->detect && proto->detect(psmouse, 1) < 0)
+			return -1;
+
+		if (proto->init && proto->init(psmouse) < 0)
+			return -1;
+
+		psmouse->type = proto->type;
+	}
+	else
+		psmouse->type = psmouse_extensions(psmouse, psmouse_max_proto, 1);
+
+	sprintf(psmouse->devname, "%s %s %s",
+		psmouse_protocol_by_type(psmouse->type)->name, psmouse->vendor, psmouse->name);
+
+	psmouse->dev.name = psmouse->devname;
+	psmouse->dev.phys = psmouse->phys;
+	psmouse->dev.id.bustype = BUS_I8042;
+	psmouse->dev.id.vendor = 0x0002;
+	psmouse->dev.id.product = psmouse->type;
+	psmouse->dev.id.version = psmouse->model;
+
+	return 0;
 }
 
 /*
@@ -688,6 +872,8 @@ static int psmouse_connect(struct serio 
 	struct psmouse *psmouse, *parent = NULL;
 	int retval;
 
+	down(&psmouse_sem);
+
 	/*
 	 * If this is a pass-through port deactivate parent so the device
 	 * connected to this port can be successfully identified
@@ -697,20 +883,14 @@ static int psmouse_connect(struct serio 
 		psmouse_deactivate(parent);
 	}
 
-	if (!(psmouse = kmalloc(sizeof(struct psmouse), GFP_KERNEL))) {
+	if (!(psmouse = kcalloc(1, sizeof(struct psmouse), GFP_KERNEL))) {
 		retval = -ENOMEM;
 		goto out;
 	}
 
-	memset(psmouse, 0, sizeof(struct psmouse));
-
 	ps2_init(&psmouse->ps2dev, serio);
 	sprintf(psmouse->phys, "%s/input0", serio->phys);
-	psmouse->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
-	psmouse->dev.keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
-	psmouse->dev.relbit[0] = BIT(REL_X) | BIT(REL_Y);
-	psmouse->dev.private = psmouse;
-	psmouse->dev.dev = &serio->dev;
+
 	psmouse_set_state(psmouse, PSMOUSE_INITIALIZING);
 
 	serio_set_drvdata(serio, psmouse);
@@ -734,25 +914,10 @@ static int psmouse_connect(struct serio 
 	psmouse->resolution = psmouse_resolution;
 	psmouse->resetafter = psmouse_resetafter;
 	psmouse->smartscroll = psmouse_smartscroll;
-	psmouse->set_rate = psmouse_set_rate;
-	psmouse->set_resolution = psmouse_set_resolution;
-	psmouse->protocol_handler = psmouse_process_byte;
-	psmouse->pktsize = 3;
-
-	psmouse->type = psmouse_extensions(psmouse, psmouse_max_proto, 1);
 
-	sprintf(psmouse->devname, "%s %s %s",
-		psmouse_protocols[psmouse->type], psmouse->vendor, psmouse->name);
-
-	psmouse->dev.name = psmouse->devname;
-	psmouse->dev.phys = psmouse->phys;
-	psmouse->dev.id.bustype = BUS_I8042;
-	psmouse->dev.id.vendor = 0x0002;
-	psmouse->dev.id.product = psmouse->type;
-	psmouse->dev.id.version = psmouse->model;
+	psmouse_switch_protocol(psmouse, NULL);
 
 	input_register_device(&psmouse->dev);
-
 	printk(KERN_INFO "input: %s on %s\n", psmouse->devname, serio->phys);
 
 	psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);
@@ -762,6 +927,7 @@ static int psmouse_connect(struct serio 
 	if (parent && parent->pt_activate)
 		parent->pt_activate(parent);
 
+	device_create_file(&serio->dev, &psmouse_attr_protocol);
 	device_create_file(&serio->dev, &psmouse_attr_rate);
 	device_create_file(&serio->dev, &psmouse_attr_resolution);
 	device_create_file(&serio->dev, &psmouse_attr_resetafter);
@@ -771,10 +937,11 @@ static int psmouse_connect(struct serio 
 	retval = 0;
 
 out:
-	/* If this is a pass-through port the parent awaits to be activated */
+	/* If this is a pass-through port the parent needs to be re-activated */
 	if (parent)
 		psmouse_activate(parent);
 
+	up(&psmouse_sem);
 	return retval;
 }
 
@@ -791,6 +958,8 @@ static int psmouse_reconnect(struct seri
 		return -1;
 	}
 
+	down(&psmouse_sem);
+
 	if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) {
 		parent = serio_get_drvdata(serio->parent);
 		psmouse_deactivate(parent);
@@ -823,6 +992,7 @@ out:
 	if (parent)
 		psmouse_activate(parent);
 
+	up(&psmouse_sem);
 	return rc;
 }
 
@@ -893,26 +1063,109 @@ ssize_t psmouse_attr_set_helper(struct d
 
 	if (serio->drv != &psmouse_drv) {
 		retval = -ENODEV;
-		goto out;
+		goto out_unpin;
+	}
+
+	retval = down_interruptible(&psmouse_sem);
+	if (retval)
+		goto out_unpin;
+
+	if (psmouse->state == PSMOUSE_IGNORE) {
+		retval = -ENODEV;
+		goto out_up;
 	}
 
 	if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) {
 		parent = serio_get_drvdata(serio->parent);
 		psmouse_deactivate(parent);
 	}
+
 	psmouse_deactivate(psmouse);
 
 	retval = handler(psmouse, buf, count);
 
-	psmouse_activate(psmouse);
+	if (retval != -ENODEV)
+		psmouse_activate(psmouse);
+
 	if (parent)
 		psmouse_activate(parent);
 
-out:
+ out_up:
+	up(&psmouse_sem);
+ out_unpin:
 	serio_unpin_driver(serio);
 	return retval;
 }
 
+static ssize_t psmouse_attr_show_protocol(struct psmouse *psmouse, char *buf)
+{
+	return sprintf(buf, "%s\n", psmouse_protocol_by_type(psmouse->type)->name);
+}
+
+static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, const char *buf, size_t count)
+{
+	struct serio *serio = psmouse->ps2dev.serio;
+	struct psmouse *parent = NULL;
+	struct psmouse_protocol *proto;
+	int retry = 0;
+
+	if (!(proto = psmouse_protocol_by_name(buf, count)))
+		return -EINVAL;
+
+	if (psmouse->type == proto->type)
+		return count;
+
+	while (serio->child) {
+		if (++retry > 3) {
+			printk(KERN_WARNING "psmouse: failed to destroy child port, protocol change aborted.\n");
+			return -EIO;
+		}
+
+		up(&psmouse_sem);
+		serio_unpin_driver(serio);
+		serio_unregister_child_port(serio);
+		serio_pin_driver_uninterruptible(serio);
+		down(&psmouse_sem);
+
+		if (serio->drv != &psmouse_drv)
+			return -ENODEV;
+
+		if (psmouse->type == proto->type)
+			return count; /* switched by other thread */
+	}
+
+	if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) {
+		parent = serio_get_drvdata(serio->parent);
+		if (parent->pt_deactivate)
+			parent->pt_deactivate(parent);
+	}
+
+	if (psmouse->disconnect)
+		psmouse->disconnect(psmouse);
+
+	psmouse_set_state(psmouse, PSMOUSE_IGNORE);
+	input_unregister_device(&psmouse->dev);
+
+	psmouse_set_state(psmouse, PSMOUSE_INITIALIZING);
+
+	if (psmouse_switch_protocol(psmouse, proto) < 0) {
+		psmouse_reset(psmouse);
+		/* default to PSMOUSE_PS2 */
+		psmouse_switch_protocol(psmouse, &psmouse_protocols[0]);
+	}
+
+	psmouse_initialize(psmouse);
+	psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);
+
+	input_register_device(&psmouse->dev);
+	printk(KERN_INFO "input: %s on %s\n", psmouse->devname, serio->phys);
+
+	if (parent && parent->pt_activate)
+		parent->pt_activate(parent);
+
+	return count;
+}
+
 static ssize_t psmouse_attr_show_rate(struct psmouse *psmouse, char *buf)
 {
 	return sprintf(buf, "%d\n", psmouse->rate);
@@ -969,34 +1222,26 @@ static ssize_t psmouse_attr_set_resetaft
 
 static int psmouse_set_maxproto(const char *val, struct kernel_param *kp)
 {
-	int i;
+	struct psmouse_protocol *proto;
 
 	if (!val)
 		return -EINVAL;
 
-	if (!strncmp(val, "any", 3)) {
-		*((unsigned int *)kp->arg) = -1U;
-		return 0;
-	}
+	proto = psmouse_protocol_by_name(val, strlen(val));
 
-	for (i = 0; i < ARRAY_SIZE(psmouse_proto_abbrev); i++) {
-		if (!psmouse_proto_abbrev[i])
-			continue;
-
-		if (!strncmp(val, psmouse_proto_abbrev[i], strlen(psmouse_proto_abbrev[i]))) {
-			*((unsigned int *)kp->arg) = i;
-			return 0;
-		}
-	}
+	if (!proto || !proto->maxproto)
+		return -EINVAL;
 
-	return -EINVAL;					\
+	*((unsigned int *)kp->arg) = proto->type;
+
+	return 0;					\
 }
 
 static int psmouse_get_maxproto(char *buffer, struct kernel_param *kp)
 {
-	return sprintf(buffer, "%s\n",
-			psmouse_max_proto < ARRAY_SIZE(psmouse_proto_abbrev) ?
-				psmouse_proto_abbrev[psmouse_max_proto] : "any");
+	int type = *((unsigned int *)kp->arg);
+
+	return sprintf(buffer, "%s\n", psmouse_protocol_by_type(type)->name);
 }
 
 static int __init psmouse_init(void)
diff --git a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h
--- a/drivers/input/mouse/psmouse.h
+++ b/drivers/input/mouse/psmouse.h
@@ -77,6 +77,8 @@ enum psmouse_type {
 	PSMOUSE_IMEX,
 	PSMOUSE_SYNAPTICS,
 	PSMOUSE_ALPS,
+	PSMOUSE_LIFEBOOK,
+	PSMOUSE_AUTO		/* This one should always be last */
 };
 
 int psmouse_sliced_command(struct psmouse *psmouse, unsigned char command);
@@ -91,15 +93,15 @@ ssize_t psmouse_attr_set_helper(struct d
 #define PSMOUSE_DEFINE_ATTR(_name)						\
 static ssize_t psmouse_attr_show_##_name(struct psmouse *, char *);		\
 static ssize_t psmouse_attr_set_##_name(struct psmouse *, const char *, size_t);\
-static ssize_t psmouse_do_show_##_name(struct device *d, char *b)		\
+static ssize_t psmouse_do_show_##_name(struct device *d, struct device_attribute *attr, char *b)		\
 {										\
 	return psmouse_attr_show_helper(d, b, psmouse_attr_show_##_name);	\
 }										\
-static ssize_t psmouse_do_set_##_name(struct device *d, const char *b, size_t s)\
+static ssize_t psmouse_do_set_##_name(struct device *d, struct device_attribute *attr, const char *b, size_t s)\
 {										\
 	return psmouse_attr_set_helper(d, b, s, psmouse_attr_set_##_name);	\
 }										\
-static struct device_attribute psmouse_attr_##_name = 				\
+static struct device_attribute psmouse_attr_##_name =				\
 	__ATTR(_name, S_IWUSR | S_IRUGO,					\
 		psmouse_do_show_##_name, psmouse_do_set_##_name);
 
diff --git a/drivers/input/mouse/rpcmouse.c b/drivers/input/mouse/rpcmouse.c
--- a/drivers/input/mouse/rpcmouse.c
+++ b/drivers/input/mouse/rpcmouse.c
@@ -59,7 +59,7 @@ static irqreturn_t rpcmouse_irq(int irq,
 	b = (short) (__raw_readl(0xe0310000) ^ 0x70);
 
 	dx = x - rpcmouse_lastx;
-	dy = y - rpcmouse_lasty; 
+	dy = y - rpcmouse_lasty;
 
 	rpcmouse_lastx = x;
 	rpcmouse_lasty = y;
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
--- a/drivers/input/mouse/synaptics.c
+++ b/drivers/input/mouse/synaptics.c
@@ -219,7 +219,7 @@ static void synaptics_pass_pt_packet(str
 		serio_interrupt(ptport, packet[1], 0, NULL);
 		serio_interrupt(ptport, packet[4], 0, NULL);
 		serio_interrupt(ptport, packet[5], 0, NULL);
-		if (child->type >= PSMOUSE_GENPS)
+		if (child->pktsize == 4)
 			serio_interrupt(ptport, packet[2], 0, NULL);
 	} else
 		serio_interrupt(ptport, packet[1], 0, NULL);
@@ -233,7 +233,7 @@ static void synaptics_pt_activate(struct
 
 	/* adjust the touchpad to child's choice of protocol */
 	if (child) {
-		if (child->type >= PSMOUSE_GENPS)
+		if (child->pktsize == 4)
 			priv->mode |= SYN_BIT_FOUR_BYTE_CLIENT;
 		else
 			priv->mode &= ~SYN_BIT_FOUR_BYTE_CLIENT;
@@ -608,6 +608,13 @@ static struct dmi_system_id toshiba_dmi_
 			DMI_MATCH(DMI_PRODUCT_NAME , "Satellite"),
 		},
 	},
+	{
+		.ident = "Toshiba Dynabook",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+			DMI_MATCH(DMI_PRODUCT_NAME , "dynabook"),
+		},
+	},
 	{ }
 };
 #endif
@@ -656,7 +663,8 @@ int synaptics_init(struct psmouse *psmou
 	 * thye same as rate of standard PS/2 mouse.
 	 */
 	if (psmouse->rate >= 80 && dmi_check_system(toshiba_dmi_table)) {
-		printk(KERN_INFO "synaptics: Toshiba Satellite detected, limiting rate to 40pps.\n");
+		printk(KERN_INFO "synaptics: Toshiba %s detected, limiting rate to 40pps.\n",
+			dmi_get_system_info(DMI_PRODUCT_NAME));
 		psmouse->rate = 40;
 	}
 #endif
diff --git a/drivers/input/mouse/vsxxxaa.c b/drivers/input/mouse/vsxxxaa.c
--- a/drivers/input/mouse/vsxxxaa.c
+++ b/drivers/input/mouse/vsxxxaa.c
@@ -1,7 +1,7 @@
 /*
  * Driver for	DEC VSXXX-AA mouse (hockey-puck mouse, ball or two rollers)
- * 		DEC VSXXX-GA mouse (rectangular mouse, with ball)
- * 		DEC VSXXX-AB tablet (digitizer with hair cross or stylus)
+ *		DEC VSXXX-GA mouse (rectangular mouse, with ball)
+ *		DEC VSXXX-AB tablet (digitizer with hair cross or stylus)
  *
  * Copyright (C) 2003-2004 by Jan-Benedict Glaw <jbglaw@lug-owl.de>
  *
diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c
--- a/drivers/input/mousedev.c
+++ b/drivers/input/mousedev.c
@@ -220,6 +220,7 @@ static void mousedev_notify_readers(stru
 	struct mousedev_list *list;
 	struct mousedev_motion *p;
 	unsigned long flags;
+	int wake_readers = 0;
 
 	list_for_each_entry(list, &mousedev->list, node) {
 		spin_lock_irqsave(&list->packet_lock, flags);
@@ -255,11 +256,14 @@ static void mousedev_notify_readers(stru
 
 		spin_unlock_irqrestore(&list->packet_lock, flags);
 
-		if (list->ready)
+		if (list->ready) {
 			kill_fasync(&list->fasync, SIGIO, POLL_IN);
+			wake_readers = 1;
+		}
 	}
 
-	wake_up_interruptible(&mousedev->wait);
+	if (wake_readers)
+		wake_up_interruptible(&mousedev->wait);
 }
 
 static void mousedev_touchpad_touch(struct mousedev *mousedev, int value)
@@ -647,9 +651,9 @@ static struct input_handle *mousedev_con
 
 	devfs_mk_cdev(MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + minor),
 			S_IFCHR|S_IRUGO|S_IWUSR, "input/mouse%d", minor);
-	class_simple_device_add(input_class,
-				MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + minor),
-				dev->dev, "mouse%d", minor);
+	class_device_create(input_class,
+			MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + minor),
+			dev->dev, "mouse%d", minor);
 
 	return &mousedev->handle;
 }
@@ -659,7 +663,8 @@ static void mousedev_disconnect(struct i
 	struct mousedev *mousedev = handle->private;
 	struct mousedev_list *list;
 
-	class_simple_device_remove(MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + mousedev->minor));
+	class_device_destroy(input_class,
+			MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + mousedev->minor));
 	devfs_remove("input/mouse%d", mousedev->minor);
 	mousedev->exist = 0;
 
@@ -735,8 +740,8 @@ static int __init mousedev_init(void)
 
 	devfs_mk_cdev(MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + MOUSEDEV_MIX),
 			S_IFCHR|S_IRUGO|S_IWUSR, "input/mice");
-	class_simple_device_add(input_class, MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + MOUSEDEV_MIX),
-				NULL, "mice");
+	class_device_create(input_class,
+			MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + MOUSEDEV_MIX), NULL, "mice");
 
 #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
 	if (!(psaux_registered = !misc_register(&psaux_mouse)))
@@ -755,7 +760,8 @@ static void __exit mousedev_exit(void)
 		misc_deregister(&psaux_mouse);
 #endif
 	devfs_remove("input/mice");
-	class_simple_device_remove(MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + MOUSEDEV_MIX));
+	class_device_destroy(input_class,
+			MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + MOUSEDEV_MIX));
 	input_unregister_handler(&mousedev_handler);
 }
 
diff --git a/drivers/input/serio/Kconfig b/drivers/input/serio/Kconfig
--- a/drivers/input/serio/Kconfig
+++ b/drivers/input/serio/Kconfig
@@ -175,7 +175,7 @@ config SERIO_RAW
 	  allocating minor 1 (that historically corresponds to /dev/psaux)
 	  first. To bind this driver to a serio port use sysfs interface:
 
-	      echo -n "serio_raw" > /sys/bus/serio/devices/serioX/driver
+	      echo -n "serio_raw" > /sys/bus/serio/devices/serioX/drvctl
 
 	  To compile this driver as a module, choose M here: the
 	  module will be called serio_raw.
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h
--- a/drivers/input/serio/i8042-x86ia64io.h
+++ b/drivers/input/serio/i8042-x86ia64io.h
@@ -131,12 +131,26 @@ static struct dmi_system_id __initdata i
 		},
 	},
 	{
+		.ident = "Fujitsu-Siemens Lifebook T3010",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK T3010"),
+		},
+	},
+	{
 		.ident = "Toshiba P10",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P10"),
 		},
 	},
+	{
+		.ident = "Alienware Sentia",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "ALIENWARE"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Sentia"),
+		},
+	},
 	{ }
 };
 
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
--- a/drivers/input/serio/i8042.c
+++ b/drivers/input/serio/i8042.c
@@ -100,7 +100,7 @@ struct i8042_port {
 static struct i8042_port i8042_ports[I8042_NUM_PORTS] = {
 	{
 		.disable	= I8042_CTR_KBDDIS,
-		.irqen 		= I8042_CTR_KBDINT,
+		.irqen		= I8042_CTR_KBDINT,
 		.mux		= -1,
 		.name		= "KBD",
 	},
@@ -191,41 +191,45 @@ static int i8042_flush(void)
 static int i8042_command(unsigned char *param, int command)
 {
 	unsigned long flags;
-	int retval = 0, i = 0;
+	int i, retval, auxerr = 0;
 
 	if (i8042_noloop && command == I8042_CMD_AUX_LOOP)
 		return -1;
 
 	spin_lock_irqsave(&i8042_lock, flags);
 
-	retval = i8042_wait_write();
-	if (!retval) {
-		dbg("%02x -> i8042 (command)", command & 0xff);
-		i8042_write_command(command & 0xff);
-	}
+	if ((retval = i8042_wait_write()))
+		goto out;
 
-	if (!retval)
-		for (i = 0; i < ((command >> 12) & 0xf); i++) {
-			if ((retval = i8042_wait_write())) break;
-			dbg("%02x -> i8042 (parameter)", param[i]);
-			i8042_write_data(param[i]);
-		}
+	dbg("%02x -> i8042 (command)", command & 0xff);
+	i8042_write_command(command & 0xff);
 
-	if (!retval)
-		for (i = 0; i < ((command >> 8) & 0xf); i++) {
-			if ((retval = i8042_wait_read())) break;
-			if (i8042_read_status() & I8042_STR_AUXDATA)
-				param[i] = ~i8042_read_data();
-			else
-				param[i] = i8042_read_data();
-			dbg("%02x <- i8042 (return)", param[i]);
+	for (i = 0; i < ((command >> 12) & 0xf); i++) {
+		if ((retval = i8042_wait_write()))
+			goto out;
+		dbg("%02x -> i8042 (parameter)", param[i]);
+		i8042_write_data(param[i]);
+	}
+
+	for (i = 0; i < ((command >> 8) & 0xf); i++) {
+		if ((retval = i8042_wait_read()))
+			goto out;
+
+		if (command == I8042_CMD_AUX_LOOP &&
+		    !(i8042_read_status() & I8042_STR_AUXDATA)) {
+			retval = auxerr = -1;
+			goto out;
 		}
 
-	spin_unlock_irqrestore(&i8042_lock, flags);
+		param[i] = i8042_read_data();
+		dbg("%02x <- i8042 (return)", param[i]);
+	}
 
 	if (retval)
-		dbg("     -- i8042 (timeout)");
+		dbg("     -- i8042 (%s)", auxerr ? "auxerr" : "timeout");
 
+ out:
+	spin_unlock_irqrestore(&i8042_lock, flags);
 	return retval;
 }
 
@@ -396,7 +400,7 @@ static void i8042_stop(struct serio *ser
 	struct i8042_port *port = serio->port_data;
 
 	port->exists = 0;
-	synchronize_kernel();
+	synchronize_sched();
 	port->serio = NULL;
 }
 
@@ -507,17 +511,17 @@ static int i8042_set_mux_mode(unsigned i
  */
 
 	param = 0xf0;
-	if (i8042_command(&param, I8042_CMD_AUX_LOOP) || param != 0x0f)
+	if (i8042_command(&param, I8042_CMD_AUX_LOOP) || param != 0xf0)
 		return -1;
 	param = mode ? 0x56 : 0xf6;
-	if (i8042_command(&param, I8042_CMD_AUX_LOOP) || param != (mode ? 0xa9 : 0x09))
+	if (i8042_command(&param, I8042_CMD_AUX_LOOP) || param != (mode ? 0x56 : 0xf6))
 		return -1;
 	param = mode ? 0xa4 : 0xa5;
-	if (i8042_command(&param, I8042_CMD_AUX_LOOP) || param == (mode ? 0x5b : 0x5a))
+	if (i8042_command(&param, I8042_CMD_AUX_LOOP) || param == (mode ? 0xa4 : 0xa5))
 		return -1;
 
 	if (mux_version)
-		*mux_version = ~param;
+		*mux_version = param;
 
 	return 0;
 }
@@ -619,7 +623,7 @@ static int __init i8042_check_aux(void)
  */
 
 	param = 0x5a;
-	if (i8042_command(&param, I8042_CMD_AUX_LOOP) || param != 0xa5) {
+	if (i8042_command(&param, I8042_CMD_AUX_LOOP) || param != 0x5a) {
 
 /*
  * External connection test - filters out AT-soldered PS/2 i8042's
@@ -630,7 +634,7 @@ static int __init i8042_check_aux(void)
  */
 
 		if (i8042_command(&param, I8042_CMD_AUX_TEST)
-		    	|| (param && param != 0xfa && param != 0xff))
+			|| (param && param != 0xfa && param != 0xff))
 				return -1;
 	}
 
diff --git a/drivers/input/serio/libps2.c b/drivers/input/serio/libps2.c
--- a/drivers/input/serio/libps2.c
+++ b/drivers/input/serio/libps2.c
@@ -29,6 +29,7 @@ MODULE_LICENSE("GPL");
 
 EXPORT_SYMBOL(ps2_init);
 EXPORT_SYMBOL(ps2_sendbyte);
+EXPORT_SYMBOL(ps2_drain);
 EXPORT_SYMBOL(ps2_command);
 EXPORT_SYMBOL(ps2_schedule_command);
 EXPORT_SYMBOL(ps2_handle_ack);
@@ -45,11 +46,11 @@ struct ps2work {
 
 
 /*
- * ps2_sendbyte() sends a byte to the mouse, and waits for acknowledge.
- * It doesn't handle retransmission, though it could - because when there would
- * be need for retransmissions, the mouse has to be replaced anyway.
+ * ps2_sendbyte() sends a byte to the device and waits for acknowledge.
+ * It doesn't handle retransmission, though it could - because if there
+ * is a need for retransmissions device has to be replaced anyway.
  *
- * ps2_sendbyte() can only be called from a process context
+ * ps2_sendbyte() can only be called from a process context.
  */
 
 int ps2_sendbyte(struct ps2dev *ps2dev, unsigned char byte, int timeout)
@@ -72,6 +73,91 @@ int ps2_sendbyte(struct ps2dev *ps2dev, 
 }
 
 /*
+ * ps2_drain() waits for device to transmit requested number of bytes
+ * and discards them.
+ */
+
+void ps2_drain(struct ps2dev *ps2dev, int maxbytes, int timeout)
+{
+	if (maxbytes > sizeof(ps2dev->cmdbuf)) {
+		WARN_ON(1);
+		maxbytes = sizeof(ps2dev->cmdbuf);
+	}
+
+	down(&ps2dev->cmd_sem);
+
+	serio_pause_rx(ps2dev->serio);
+	ps2dev->flags = PS2_FLAG_CMD;
+	ps2dev->cmdcnt = maxbytes;
+	serio_continue_rx(ps2dev->serio);
+
+	wait_event_timeout(ps2dev->wait,
+			   !(ps2dev->flags & PS2_FLAG_CMD),
+			   msecs_to_jiffies(timeout));
+	up(&ps2dev->cmd_sem);
+}
+
+/*
+ * ps2_is_keyboard_id() checks received ID byte against the list of
+ * known keyboard IDs.
+ */
+
+static inline int ps2_is_keyboard_id(char id_byte)
+{
+	static char keyboard_ids[] = {
+		0xab,	/* Regular keyboards		*/
+		0xac,	/* NCD Sun keyboard		*/
+		0x2b,	/* Trust keyboard, translated	*/
+		0x5d,	/* Trust keyboard		*/
+		0x60,	/* NMB SGI keyboard, translated */
+		0x47,	/* NMB SGI keyboard		*/
+	};
+
+	return memchr(keyboard_ids, id_byte, sizeof(keyboard_ids)) != NULL;
+}
+
+/*
+ * ps2_adjust_timeout() is called after receiving 1st byte of command
+ * response and tries to reduce remaining timeout to speed up command
+ * completion.
+ */
+
+static int ps2_adjust_timeout(struct ps2dev *ps2dev, int command, int timeout)
+{
+	switch (command) {
+		case PS2_CMD_RESET_BAT:
+			/*
+			 * Device has sent the first response byte after
+			 * reset command, reset is thus done, so we can
+			 * shorten the timeout.
+			 * The next byte will come soon (keyboard) or not
+			 * at all (mouse).
+			 */
+			if (timeout > msecs_to_jiffies(100))
+				timeout = msecs_to_jiffies(100);
+			break;
+
+		case PS2_CMD_GETID:
+			/*
+			 * If device behind the port is not a keyboard there
+			 * won't be 2nd byte of ID response.
+			 */
+			if (!ps2_is_keyboard_id(ps2dev->cmdbuf[1])) {
+				serio_pause_rx(ps2dev->serio);
+				ps2dev->flags = ps2dev->cmdcnt = 0;
+				serio_continue_rx(ps2dev->serio);
+				timeout = 0;
+			}
+			break;
+
+		default:
+			break;
+	}
+
+	return timeout;
+}
+
+/*
  * ps2_command() sends a command and its parameters to the mouse,
  * then waits for the response and puts it in the param array.
  *
@@ -86,6 +172,11 @@ int ps2_command(struct ps2dev *ps2dev, u
 	int rc = -1;
 	int i;
 
+	if (receive > sizeof(ps2dev->cmdbuf)) {
+		WARN_ON(1);
+		return -1;
+	}
+
 	down(&ps2dev->cmd_sem);
 
 	serio_pause_rx(ps2dev->serio);
@@ -101,10 +192,9 @@ int ps2_command(struct ps2dev *ps2dev, u
 	 * ACKing the reset command, and so it can take a long
 	 * time before the ACK arrrives.
 	 */
-	if (command & 0xff)
-		if (ps2_sendbyte(ps2dev, command & 0xff,
-			command == PS2_CMD_RESET_BAT ? 1000 : 200))
-			goto out;
+	if (ps2_sendbyte(ps2dev, command & 0xff,
+			 command == PS2_CMD_RESET_BAT ? 1000 : 200))
+		goto out;
 
 	for (i = 0; i < send; i++)
 		if (ps2_sendbyte(ps2dev, param[i], 200))
@@ -120,33 +210,7 @@ int ps2_command(struct ps2dev *ps2dev, u
 
 	if (ps2dev->cmdcnt && timeout > 0) {
 
-		if (command == PS2_CMD_RESET_BAT && timeout > msecs_to_jiffies(100)) {
-			/*
-			 * Device has sent the first response byte
-			 * after a reset command, reset is thus done,
-			 * shorten the timeout. The next byte will come
-			 * soon (keyboard) or not at all (mouse).
-			 */
-			timeout = msecs_to_jiffies(100);
-		}
-
-		if (command == PS2_CMD_GETID &&
-		    ps2dev->cmdbuf[receive - 1] != 0xab && /* Regular keyboards */
-		    ps2dev->cmdbuf[receive - 1] != 0xac && /* NCD Sun keyboard */
-		    ps2dev->cmdbuf[receive - 1] != 0x2b && /* Trust keyboard, translated */
-		    ps2dev->cmdbuf[receive - 1] != 0x5d && /* Trust keyboard */
-		    ps2dev->cmdbuf[receive - 1] != 0x60 && /* NMB SGI keyboard, translated */
-		    ps2dev->cmdbuf[receive - 1] != 0x47) { /* NMB SGI keyboard */
-			/*
-			 * Device behind the port is not a keyboard
-			 * so we don't need to wait for the 2nd byte
-			 * of ID response.
-			 */
-			serio_pause_rx(ps2dev->serio);
-			ps2dev->flags = ps2dev->cmdcnt = 0;
-			serio_continue_rx(ps2dev->serio);
-		}
-
+		timeout = ps2_adjust_timeout(ps2dev, command, timeout);
 		wait_event_timeout(ps2dev->wait,
 				   !(ps2dev->flags & PS2_FLAG_CMD), timeout);
 	}
@@ -160,7 +224,7 @@ int ps2_command(struct ps2dev *ps2dev, u
 
 	rc = 0;
 
-out:
+ out:
 	serio_pause_rx(ps2dev->serio);
 	ps2dev->flags = 0;
 	serio_continue_rx(ps2dev->serio);
diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c
--- a/drivers/input/serio/serio.c
+++ b/drivers/input/serio/serio.c
@@ -31,10 +31,9 @@
 #include <linux/serio.h>
 #include <linux/errno.h>
 #include <linux/wait.h>
-#include <linux/completion.h>
 #include <linux/sched.h>
-#include <linux/smp_lock.h>
 #include <linux/slab.h>
+#include <linux/kthread.h>
 
 MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
 MODULE_DESCRIPTION("Serio abstraction core");
@@ -43,6 +42,7 @@ MODULE_LICENSE("GPL");
 EXPORT_SYMBOL(serio_interrupt);
 EXPORT_SYMBOL(__serio_register_port);
 EXPORT_SYMBOL(serio_unregister_port);
+EXPORT_SYMBOL(serio_unregister_child_port);
 EXPORT_SYMBOL(__serio_unregister_port_delayed);
 EXPORT_SYMBOL(__serio_register_driver);
 EXPORT_SYMBOL(serio_unregister_driver);
@@ -68,6 +68,37 @@ static void serio_destroy_port(struct se
 static void serio_reconnect_port(struct serio *serio);
 static void serio_disconnect_port(struct serio *serio);
 
+static int serio_connect_driver(struct serio *serio, struct serio_driver *drv)
+{
+	int retval;
+
+	down(&serio->drv_sem);
+	retval = drv->connect(serio, drv);
+	up(&serio->drv_sem);
+
+	return retval;
+}
+
+static int serio_reconnect_driver(struct serio *serio)
+{
+	int retval = -1;
+
+	down(&serio->drv_sem);
+	if (serio->drv && serio->drv->reconnect)
+		retval = serio->drv->reconnect(serio);
+	up(&serio->drv_sem);
+
+	return retval;
+}
+
+static void serio_disconnect_driver(struct serio *serio)
+{
+	down(&serio->drv_sem);
+	if (serio->drv)
+		serio->drv->disconnect(serio);
+	up(&serio->drv_sem);
+}
+
 static int serio_match_port(const struct serio_device_id *ids, struct serio *serio)
 {
 	while (ids->type || ids->proto) {
@@ -91,7 +122,7 @@ static void serio_bind_driver(struct ser
 
 	if (serio_match_port(drv->id_table, serio)) {
 		serio->dev.driver = &drv->driver;
-		if (drv->connect(serio, drv)) {
+		if (serio_connect_driver(serio, drv)) {
 			serio->dev.driver = NULL;
 			goto out;
 		}
@@ -138,8 +169,7 @@ struct serio_event {
 static DEFINE_SPINLOCK(serio_event_lock);	/* protects serio_event_list */
 static LIST_HEAD(serio_event_list);
 static DECLARE_WAIT_QUEUE_HEAD(serio_wait);
-static DECLARE_COMPLETION(serio_exited);
-static int serio_pid;
+static struct task_struct *serio_task;
 
 static void serio_queue_event(void *object, struct module *owner,
 			      enum serio_event_type event_type)
@@ -150,12 +180,12 @@ static void serio_queue_event(void *obje
 	spin_lock_irqsave(&serio_event_lock, flags);
 
 	/*
- 	 * Scan event list for the other events for the same serio port,
+	 * Scan event list for the other events for the same serio port,
 	 * starting with the most recent one. If event is the same we
 	 * do not need add new one. If event is of different type we
 	 * need to add this event and should not look further because
 	 * we need to preseve sequence of distinct events.
- 	 */
+	 */
 	list_for_each_entry_reverse(event, &serio_event_list, node) {
 		if (event->object == object) {
 			if (event->type == event_type)
@@ -337,20 +367,15 @@ static struct serio *serio_get_pending_c
 
 static int serio_thread(void *nothing)
 {
-	lock_kernel();
-	daemonize("kseriod");
-	allow_signal(SIGTERM);
-
 	do {
 		serio_handle_events();
-		wait_event_interruptible(serio_wait, !list_empty(&serio_event_list));
-		try_to_freeze(PF_FREEZE);
-	} while (!signal_pending(current));
+		wait_event_interruptible(serio_wait,
+			kthread_should_stop() || !list_empty(&serio_event_list));
+		try_to_freeze();
+	} while (!kthread_should_stop());
 
 	printk(KERN_DEBUG "serio: kseriod exiting\n");
-
-	unlock_kernel();
-	complete_and_exit(&serio_exited, 0);
+	return 0;
 }
 
 
@@ -358,31 +383,39 @@ static int serio_thread(void *nothing)
  * Serio port operations
  */
 
-static ssize_t serio_show_description(struct device *dev, char *buf)
+static ssize_t serio_show_description(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct serio *serio = to_serio_port(dev);
 	return sprintf(buf, "%s\n", serio->name);
 }
 
-static ssize_t serio_show_id_type(struct device *dev, char *buf)
+static ssize_t serio_show_modalias(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct serio *serio = to_serio_port(dev);
+
+	return sprintf(buf, "serio:ty%02Xpr%02Xid%02Xex%02X\n",
+			serio->id.type, serio->id.proto, serio->id.id, serio->id.extra);
+}
+
+static ssize_t serio_show_id_type(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct serio *serio = to_serio_port(dev);
 	return sprintf(buf, "%02x\n", serio->id.type);
 }
 
-static ssize_t serio_show_id_proto(struct device *dev, char *buf)
+static ssize_t serio_show_id_proto(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct serio *serio = to_serio_port(dev);
 	return sprintf(buf, "%02x\n", serio->id.proto);
 }
 
-static ssize_t serio_show_id_id(struct device *dev, char *buf)
+static ssize_t serio_show_id_id(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct serio *serio = to_serio_port(dev);
 	return sprintf(buf, "%02x\n", serio->id.id);
 }
 
-static ssize_t serio_show_id_extra(struct device *dev, char *buf)
+static ssize_t serio_show_id_extra(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct serio *serio = to_serio_port(dev);
 	return sprintf(buf, "%02x\n", serio->id.extra);
@@ -406,7 +439,7 @@ static struct attribute_group serio_id_a
 	.attrs	= serio_device_id_attrs,
 };
 
-static ssize_t serio_rebind_driver(struct device *dev, const char *buf, size_t count)
+static ssize_t serio_rebind_driver(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct serio *serio = to_serio_port(dev);
 	struct device_driver *drv;
@@ -437,13 +470,13 @@ static ssize_t serio_rebind_driver(struc
 	return retval;
 }
 
-static ssize_t serio_show_bind_mode(struct device *dev, char *buf)
+static ssize_t serio_show_bind_mode(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct serio *serio = to_serio_port(dev);
 	return sprintf(buf, "%s\n", serio->manual_bind ? "manual" : "auto");
 }
 
-static ssize_t serio_set_bind_mode(struct device *dev, const char *buf, size_t count)
+static ssize_t serio_set_bind_mode(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct serio *serio = to_serio_port(dev);
 	int retval;
@@ -462,6 +495,7 @@ static ssize_t serio_set_bind_mode(struc
 
 static struct device_attribute serio_device_attrs[] = {
 	__ATTR(description, S_IRUGO, serio_show_description, NULL),
+	__ATTR(modalias, S_IRUGO, serio_show_modalias, NULL),
 	__ATTR(drvctl, S_IWUSR, NULL, serio_rebind_driver),
 	__ATTR(bind_mode, S_IWUSR | S_IRUGO, serio_show_bind_mode, serio_set_bind_mode),
 	__ATTR_NULL
@@ -557,7 +591,7 @@ static void serio_destroy_port(struct se
 static void serio_reconnect_port(struct serio *serio)
 {
 	do {
-		if (!serio->drv || !serio->drv->reconnect || serio->drv->reconnect(serio)) {
+		if (serio_reconnect_driver(serio)) {
 			serio_disconnect_port(serio);
 			serio_find_driver(serio);
 			/* Ok, old children are now gone, we are done */
@@ -630,6 +664,19 @@ void serio_unregister_port(struct serio 
 }
 
 /*
+ * Safely unregisters child port if one is present.
+ */
+void serio_unregister_child_port(struct serio *serio)
+{
+	down(&serio_sem);
+	if (serio->child) {
+		serio_disconnect_port(serio->child);
+		serio_destroy_port(serio->child);
+	}
+	up(&serio_sem);
+}
+
+/*
  * Submits register request to kseriod for subsequent execution.
  * Can be used when it is not obvious whether the serio_sem is
  * taken or not and when delayed execution is feasible.
@@ -686,15 +733,14 @@ static int serio_driver_probe(struct dev
 	struct serio *serio = to_serio_port(dev);
 	struct serio_driver *drv = to_serio_driver(dev->driver);
 
-	return drv->connect(serio, drv);
+	return serio_connect_driver(serio, drv);
 }
 
 static int serio_driver_remove(struct device *dev)
 {
 	struct serio *serio = to_serio_port(dev);
-	struct serio_driver *drv = to_serio_driver(dev->driver);
 
-	drv->disconnect(serio);
+	serio_disconnect_driver(serio);
 	return 0;
 }
 
@@ -730,11 +776,9 @@ start_over:
 
 static void serio_set_drv(struct serio *serio, struct serio_driver *drv)
 {
-	down(&serio->drv_sem);
 	serio_pause_rx(serio);
 	serio->drv = drv;
 	serio_continue_rx(serio);
-	up(&serio->drv_sem);
 }
 
 static int serio_bus_match(struct device *dev, struct device_driver *drv)
@@ -750,36 +794,37 @@ static int serio_bus_match(struct device
 
 #ifdef CONFIG_HOTPLUG
 
-#define PUT_ENVP(fmt, val) 						\
-do {									\
-	envp[i++] = buffer;						\
-	length += snprintf(buffer, buffer_size - length, fmt, val);	\
-	if (buffer_size - length <= 0 || i >= num_envp)			\
-		return -ENOMEM;						\
-	length++;							\
-	buffer += length;						\
-} while (0)
+#define SERIO_ADD_HOTPLUG_VAR(fmt, val...)				\
+	do {								\
+		int err = add_hotplug_env_var(envp, num_envp, &i,	\
+					buffer, buffer_size, &len,	\
+					fmt, val);			\
+		if (err)						\
+			return err;					\
+	} while (0)
+
 static int serio_hotplug(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size)
 {
 	struct serio *serio;
 	int i = 0;
-	int length = 0;
+	int len = 0;
 
 	if (!dev)
 		return -ENODEV;
 
 	serio = to_serio_port(dev);
 
-	PUT_ENVP("SERIO_TYPE=%02x", serio->id.type);
-	PUT_ENVP("SERIO_PROTO=%02x", serio->id.proto);
-	PUT_ENVP("SERIO_ID=%02x", serio->id.id);
-	PUT_ENVP("SERIO_EXTRA=%02x", serio->id.extra);
-
+	SERIO_ADD_HOTPLUG_VAR("SERIO_TYPE=%02x", serio->id.type);
+	SERIO_ADD_HOTPLUG_VAR("SERIO_PROTO=%02x", serio->id.proto);
+	SERIO_ADD_HOTPLUG_VAR("SERIO_ID=%02x", serio->id.id);
+	SERIO_ADD_HOTPLUG_VAR("SERIO_EXTRA=%02x", serio->id.extra);
+	SERIO_ADD_HOTPLUG_VAR("MODALIAS=serio:ty%02Xpr%02Xid%02Xex%02X",
+				serio->id.type, serio->id.proto, serio->id.id, serio->id.extra);
 	envp[i] = NULL;
 
 	return 0;
 }
-#undef PUT_ENVP
+#undef SERIO_ADD_HOTPLUG_VAR
 
 #else
 
@@ -794,7 +839,7 @@ static int serio_resume(struct device *d
 {
 	struct serio *serio = to_serio_port(dev);
 
-	if (!serio->drv || !serio->drv->reconnect || serio->drv->reconnect(serio)) {
+	if (serio_reconnect_driver(serio)) {
 		/*
 		 * Driver re-probing can take a while, so better let kseriod
 		 * deal with it.
@@ -848,9 +893,10 @@ irqreturn_t serio_interrupt(struct serio
 
 static int __init serio_init(void)
 {
-	if (!(serio_pid = kernel_thread(serio_thread, NULL, CLONE_KERNEL))) {
+	serio_task = kthread_run(serio_thread, NULL, "kseriod");
+	if (IS_ERR(serio_task)) {
 		printk(KERN_ERR "serio: Failed to start kseriod\n");
-		return -1;
+		return PTR_ERR(serio_task);
 	}
 
 	serio_bus.dev_attrs = serio_device_attrs;
@@ -866,8 +912,7 @@ static int __init serio_init(void)
 static void __exit serio_exit(void)
 {
 	bus_unregister(&serio_bus);
-	kill_proc(serio_pid, SIGTERM, 1);
-	wait_for_completion(&serio_exited);
+	kthread_stop(serio_task);
 }
 
 module_init(serio_init);
diff --git a/drivers/input/serio/serio_raw.c b/drivers/input/serio/serio_raw.c
--- a/drivers/input/serio/serio_raw.c
+++ b/drivers/input/serio/serio_raw.c
@@ -299,6 +299,7 @@ static int serio_raw_connect(struct seri
 
 	serio_raw->dev.minor = PSMOUSE_MINOR;
 	serio_raw->dev.name = serio_raw->name;
+	serio_raw->dev.dev = &serio->dev;
 	serio_raw->dev.fops = &serio_raw_fops;
 
 	err = misc_register(&serio_raw->dev);
diff --git a/drivers/input/serio/serport.c b/drivers/input/serio/serport.c
--- a/drivers/input/serio/serport.c
+++ b/drivers/input/serio/serport.c
@@ -257,7 +257,7 @@ static int __init serport_init(void)
 
 static void __exit serport_exit(void)
 {
-	tty_register_ldisc(N_MOUSE, NULL);
+	tty_unregister_ldisc(N_MOUSE);
 }
 
 module_init(serport_init);
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -58,7 +58,7 @@ config TOUCHSCREEN_ELO
 	  If unsure, say N.
 
 	  To compile this driver as a module, choose M here: the
-	  module will be called gunze.
+	  module will be called elo.
 
 config TOUCHSCREEN_MTOUCH
 	tristate "MicroTouch serial touchscreens"
diff --git a/drivers/input/touchscreen/elo.c b/drivers/input/touchscreen/elo.c
--- a/drivers/input/touchscreen/elo.c
+++ b/drivers/input/touchscreen/elo.c
@@ -226,7 +226,7 @@ static int elo_connect(struct serio *ser
 			input_set_abs_params(&elo->dev, ABS_Y, 96, 4000, 0, 0);
 			input_set_abs_params(&elo->dev, ABS_PRESSURE, 0, 255, 0, 0);
 			break;
-		
+
 		case 1: /* 6-byte protocol */
 			input_set_abs_params(&elo->dev, ABS_PRESSURE, 0, 15, 0, 0);
 
diff --git a/drivers/input/touchscreen/h3600_ts_input.c b/drivers/input/touchscreen/h3600_ts_input.c
--- a/drivers/input/touchscreen/h3600_ts_input.c
+++ b/drivers/input/touchscreen/h3600_ts_input.c
@@ -89,9 +89,9 @@ MODULE_LICENSE("GPL");
 #define H3600_SCANCODE_Q	4	 /* 4 -> Q button */
 #define	H3600_SCANCODE_START	5	 /* 5 -> start menu */
 #define	H3600_SCANCODE_UP	6	 /* 6 -> up */
-#define H3600_SCANCODE_RIGHT	7 	 /* 7 -> right */
-#define H3600_SCANCODE_LEFT 	8	 /* 8 -> left */
-#define H3600_SCANCODE_DOWN 	9	 /* 9 -> down */
+#define H3600_SCANCODE_RIGHT	7	 /* 7 -> right */
+#define H3600_SCANCODE_LEFT	8	 /* 8 -> left */
+#define H3600_SCANCODE_DOWN	9	 /* 9 -> down */
 
 static char *h3600_name = "H3600 TouchScreen";
 
@@ -113,7 +113,7 @@ struct h3600_dev {
 
 static irqreturn_t action_button_handler(int irq, void *dev_id, struct pt_regs *regs)
 {
-        int down = (GPLR & GPIO_BITSY_ACTION_BUTTON) ? 0 : 1;
+	int down = (GPLR & GPIO_BITSY_ACTION_BUTTON) ? 0 : 1;
 	struct input_dev *dev = (struct input_dev *) dev_id;
 
 	input_regs(dev, regs);
@@ -125,7 +125,7 @@ static irqreturn_t action_button_handler
 
 static irqreturn_t npower_button_handler(int irq, void *dev_id, struct pt_regs *regs)
 {
-        int down = (GPLR & GPIO_BITSY_NPOWER_BUTTON) ? 0 : 1;
+	int down = (GPLR & GPIO_BITSY_NPOWER_BUTTON) ? 0 : 1;
 	struct input_dev *dev = (struct input_dev *) dev_id;
 
 	/*
@@ -145,8 +145,8 @@ static irqreturn_t npower_button_handler
 static int flite_brightness = 25;
 
 enum flite_pwr {
-        FLITE_PWR_OFF = 0,
-        FLITE_PWR_ON = 1
+	FLITE_PWR_OFF = 0,
+	FLITE_PWR_ON = 1
 };
 
 /*
@@ -157,9 +157,9 @@ unsigned int h3600_flite_power(struct in
 	struct h3600_dev *ts = dev->private;
 
 	/* Must be in this order */
-       	ts->serio->write(ts->serio, 1);
+	ts->serio->write(ts->serio, 1);
 	ts->serio->write(ts->serio, pwr);
-      	ts->serio->write(ts->serio, brightness);
+	ts->serio->write(ts->serio, brightness);
 	return 0;
 }
 
@@ -169,26 +169,26 @@ static int h3600ts_pm_callback(struct pm
 {
 	struct input_dev *dev = (struct input_dev *) data;
 
-        switch (req) {
-        case PM_SUSPEND: /* enter D1-D3 */
-                suspended = 1;
-                h3600_flite_power(dev, FLITE_PWR_OFF);
-                break;
-        case PM_BLANK:
-                if (!suspended)
-                        h3600_flite_power(dev, FLITE_PWR_OFF);
-                break;
-        case PM_RESUME:  /* enter D0 */
-                /* same as unblank */
-        case PM_UNBLANK:
-                if (suspended) {
-                        //initSerial();
-                        suspended = 0;
-                }
-                h3600_flite_power(dev, FLITE_PWR_ON);
-                break;
-        }
-        return 0;
+	switch (req) {
+	case PM_SUSPEND: /* enter D1-D3 */
+		suspended = 1;
+		h3600_flite_power(dev, FLITE_PWR_OFF);
+		break;
+	case PM_BLANK:
+		if (!suspended)
+			h3600_flite_power(dev, FLITE_PWR_OFF);
+		break;
+	case PM_RESUME:  /* enter D0 */
+		/* same as unblank */
+	case PM_UNBLANK:
+		if (suspended) {
+			//initSerial();
+			suspended = 0;
+		}
+		h3600_flite_power(dev, FLITE_PWR_ON);
+		break;
+	}
+	return 0;
 }
 #endif
 
@@ -199,25 +199,25 @@ static int h3600ts_pm_callback(struct pm
  */
 static void h3600ts_process_packet(struct h3600_dev *ts, struct pt_regs *regs)
 {
-        struct input_dev *dev = &ts->dev;
+	struct input_dev *dev = &ts->dev;
 	static int touched = 0;
 	int key, down = 0;
 
 	input_regs(dev, regs);
 
-        switch (ts->event) {
-                /*
-                   Buttons - returned as a single byte
-                        7 6 5 4 3 2 1 0
-                        S x x x N N N N
-
-                   S       switch state ( 0=pressed 1=released)
-                   x       Unused.
-                   NNNN    switch number 0-15
-
-                Note: This is true for non interrupt generated key events.
-                */
-                case KEYBD_ID:
+	switch (ts->event) {
+		/*
+		   Buttons - returned as a single byte
+			7 6 5 4 3 2 1 0
+			S x x x N N N N
+
+		   S       switch state ( 0=pressed 1=released)
+		   x       Unused.
+		   NNNN    switch number 0-15
+
+		   Note: This is true for non interrupt generated key events.
+		*/
+		case KEYBD_ID:
 			down = (ts->buf[0] & 0x80) ? 0 : 1;
 
 			switch (ts->buf[0] & 0x7f) {
@@ -229,40 +229,40 @@ static void h3600ts_process_packet(struc
                                         break;
 				case H3600_SCANCODE_CONTACTS:
 					key = KEY_PROG2;
-                                        break;
+					break;
 				case H3600_SCANCODE_Q:
 					key = KEY_Q;
-                                        break;
+					break;
 				case H3600_SCANCODE_START:
 					key = KEY_PROG3;
-                                        break;
+					break;
 				case H3600_SCANCODE_UP:
 					key = KEY_UP;
-                                        break;
+					break;
 				case H3600_SCANCODE_RIGHT:
 					key = KEY_RIGHT;
-                                        break;
+					break;
 				case H3600_SCANCODE_LEFT:
 					key = KEY_LEFT;
-                                        break;
+					break;
 				case H3600_SCANCODE_DOWN:
 					key = KEY_DOWN;
-                                        break;
+					break;
 				default:
 					key = 0;
 			}
-                        if (key)
-                        	input_report_key(dev, key, down);
-                        break;
-                /*
-                 * Native touchscreen event data is formatted as shown below:-
-                 *
-                 *      +-------+-------+-------+-------+
-                 *      | Xmsb  | Xlsb  | Ymsb  | Ylsb  |
-                 *      +-------+-------+-------+-------+
-                 *       byte 0    1       2       3
-                 */
-                case TOUCHS_ID:
+			if (key)
+				input_report_key(dev, key, down);
+			break;
+		/*
+		 * Native touchscreen event data is formatted as shown below:-
+		 *
+		 *      +-------+-------+-------+-------+
+		 *      | Xmsb  | Xlsb  | Ymsb  | Ylsb  |
+		 *      +-------+-------+-------+-------+
+		 *       byte 0    1       2       3
+		 */
+		case TOUCHS_ID:
 			if (!touched) {
 				input_report_key(dev, BTN_TOUCH, 1);
 				touched = 1;
@@ -272,19 +272,19 @@ static void h3600ts_process_packet(struc
 				unsigned short x, y;
 
 				x = ts->buf[0]; x <<= 8; x += ts->buf[1];
-                                y = ts->buf[2]; y <<= 8; y += ts->buf[3];
+				y = ts->buf[2]; y <<= 8; y += ts->buf[3];
 
-                       		input_report_abs(dev, ABS_X, x);
-                       		input_report_abs(dev, ABS_Y, y);
+				input_report_abs(dev, ABS_X, x);
+				input_report_abs(dev, ABS_Y, y);
 			} else {
-		               	input_report_key(dev, BTN_TOUCH, 0);
+				input_report_key(dev, BTN_TOUCH, 0);
 				touched = 0;
 			}
-                        break;
+			break;
 		default:
 			/* Send a non input event elsewhere */
 			break;
-        }
+	}
 
 	input_sync(dev);
 }
@@ -293,7 +293,7 @@ static void h3600ts_process_packet(struc
  * h3600ts_event() handles events from the input module.
  */
 static int h3600ts_event(struct input_dev *dev, unsigned int type,
-		 	 unsigned int code, int value)
+			 unsigned int code, int value)
 {
 	struct h3600_dev *ts = dev->private;
 
@@ -332,41 +332,41 @@ static int state;
 static irqreturn_t h3600ts_interrupt(struct serio *serio, unsigned char data,
                                      unsigned int flags, struct pt_regs *regs)
 {
-        struct h3600_dev *ts = serio_get_drvdata(serio);
+	struct h3600_dev *ts = serio_get_drvdata(serio);
 
 	/*
-         * We have a new frame coming in.
-         */
+	 * We have a new frame coming in.
+	 */
 	switch (state) {
 		case STATE_SOF:
-        		if (data == CHAR_SOF)
-                		state = STATE_ID;
+			if (data == CHAR_SOF)
+				state = STATE_ID;
 			break;
-        	case STATE_ID:
+		case STATE_ID:
 			ts->event = (data & 0xf0) >> 4;
 			ts->len = (data & 0xf);
 			ts->idx = 0;
 			if (ts->event >= MAX_ID) {
 				state = STATE_SOF;
-                        	break;
+				break;
 			}
 			ts->chksum = data;
-                	state = (ts->len > 0) ? STATE_DATA : STATE_EOF;
+			state = (ts->len > 0) ? STATE_DATA : STATE_EOF;
 			break;
 		case STATE_DATA:
 			ts->chksum += data;
 			ts->buf[ts->idx]= data;
-			if(++ts->idx == ts->len)
-                        	state = STATE_EOF;
+			if (++ts->idx == ts->len)
+				state = STATE_EOF;
 			break;
 		case STATE_EOF:
-                	state = STATE_SOF;
-                	if (data == CHAR_EOF || data == ts->chksum)
+			state = STATE_SOF;
+			if (data == CHAR_EOF || data == ts->chksum)
 				h3600ts_process_packet(ts, regs);
-                	break;
-        	default:
-                	printk("Error3\n");
-                	break;
+			break;
+		default:
+			printk("Error3\n");
+			break;
 	}
 
 	return IRQ_HANDLED;
@@ -390,10 +390,10 @@ static int h3600ts_connect(struct serio 
 	init_input_dev(&ts->dev);
 
 	/* Device specific stuff */
-        set_GPIO_IRQ_edge(GPIO_BITSY_ACTION_BUTTON, GPIO_BOTH_EDGES);
-        set_GPIO_IRQ_edge(GPIO_BITSY_NPOWER_BUTTON, GPIO_RISING_EDGE);
+	set_GPIO_IRQ_edge(GPIO_BITSY_ACTION_BUTTON, GPIO_BOTH_EDGES);
+	set_GPIO_IRQ_edge(GPIO_BITSY_NPOWER_BUTTON, GPIO_RISING_EDGE);
 
-        if (request_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, action_button_handler,
+	if (request_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, action_button_handler,
 			SA_SHIRQ | SA_INTERRUPT | SA_SAMPLE_RANDOM,
 			"h3600_action", &ts->dev)) {
 		printk(KERN_ERR "h3600ts.c: Could not allocate Action Button IRQ!\n");
@@ -401,7 +401,7 @@ static int h3600ts_connect(struct serio 
 		return -EBUSY;
 	}
 
-        if (request_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, npower_button_handler,
+	if (request_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, npower_button_handler,
 			SA_SHIRQ | SA_INTERRUPT | SA_SAMPLE_RANDOM,
 			"h3600_suspend", &ts->dev)) {
 		free_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, &ts->dev);
@@ -433,7 +433,7 @@ static int h3600ts_connect(struct serio 
 
 	sprintf(ts->phys, "%s/input0", serio->phys);
 
-       	ts->dev.event = h3600ts_event;
+	ts->dev.event = h3600ts_event;
 	ts->dev.private = ts;
 	ts->dev.name = h3600_name;
 	ts->dev.phys = ts->phys;
@@ -446,8 +446,8 @@ static int h3600ts_connect(struct serio 
 
 	err = serio_open(serio, drv);
 	if (err) {
-        	free_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, ts);
-        	free_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, ts);
+		free_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, ts);
+		free_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, ts);
 		serio_set_drvdata(serio, NULL);
 		kfree(ts);
 		return err;
diff --git a/drivers/input/touchscreen/mk712.c b/drivers/input/touchscreen/mk712.c
--- a/drivers/input/touchscreen/mk712.c
+++ b/drivers/input/touchscreen/mk712.c
@@ -17,7 +17,7 @@
  * found in Gateway AOL Connected Touchpad computers.
  *
  * Documentation for ICS MK712 can be found at:
- * 	http://www.icst.com/pdf/mk712.pdf
+ *	http://www.icst.com/pdf/mk712.pdf
  */
 
 /*
@@ -77,7 +77,6 @@ MODULE_PARM_DESC(irq, "IRQ of MK712 touc
 #define MK712_READ_ONE_POINT			0x20
 #define MK712_POWERUP				0x40
 
-static int mk712_used = 0;
 static struct input_dev mk712_dev;
 static DEFINE_SPINLOCK(mk712_lock);
 
@@ -130,17 +129,14 @@ static int mk712_open(struct input_dev *
 
 	spin_lock_irqsave(&mk712_lock, flags);
 
-	if (!mk712_used++) {
+	outb(0, mk712_io + MK712_CONTROL); /* Reset */
 
-		outb(0, mk712_io + MK712_CONTROL); /* Reset */
+	outb(MK712_ENABLE_INT | MK712_INT_ON_CONVERSION_COMPLETE |
+		MK712_INT_ON_CHANGE_IN_TOUCH_STATUS |
+		MK712_ENABLE_PERIODIC_CONVERSIONS |
+		MK712_POWERUP, mk712_io + MK712_CONTROL);
 
-		outb(MK712_ENABLE_INT | MK712_INT_ON_CONVERSION_COMPLETE |
-			MK712_INT_ON_CHANGE_IN_TOUCH_STATUS |
-			MK712_ENABLE_PERIODIC_CONVERSIONS |
-			MK712_POWERUP, mk712_io + MK712_CONTROL);
-
-		outb(10, mk712_io + MK712_RATE); /* 187 points per second */
-	}
+	outb(10, mk712_io + MK712_RATE); /* 187 points per second */
 
 	spin_unlock_irqrestore(&mk712_lock, flags);
 
@@ -153,8 +149,7 @@ static void mk712_close(struct input_dev
 
 	spin_lock_irqsave(&mk712_lock, flags);
 
-	if (!--mk712_used)
-		outb(0, mk712_io + MK712_CONTROL);
+	outb(0, mk712_io + MK712_CONTROL);
 
 	spin_unlock_irqrestore(&mk712_lock, flags);
 }
diff --git a/drivers/input/tsdev.c b/drivers/input/tsdev.c
--- a/drivers/input/tsdev.c
+++ b/drivers/input/tsdev.c
@@ -414,9 +414,9 @@ static struct input_handle *tsdev_connec
 			S_IFCHR|S_IRUGO|S_IWUSR, "input/ts%d", minor);
 	devfs_mk_cdev(MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + minor + TSDEV_MINORS/2),
 			S_IFCHR|S_IRUGO|S_IWUSR, "input/tsraw%d", minor);
-	class_simple_device_add(input_class,
-				MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + minor),
-				dev->dev, "ts%d", minor);
+	class_device_create(input_class,
+			MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + minor),
+			dev->dev, "ts%d", minor);
 
 	return &tsdev->handle;
 }
@@ -426,7 +426,8 @@ static void tsdev_disconnect(struct inpu
 	struct tsdev *tsdev = handle->private;
 	struct tsdev_list *list;
 
-	class_simple_device_remove(MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + tsdev->minor));
+	class_device_destroy(input_class,
+			MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + tsdev->minor));
 	devfs_remove("input/ts%d", tsdev->minor);
 	devfs_remove("input/tsraw%d", tsdev->minor);
 	tsdev->exist = 0;
diff --git a/drivers/isdn/act2000/capi.c b/drivers/isdn/act2000/capi.c
--- a/drivers/isdn/act2000/capi.c
+++ b/drivers/isdn/act2000/capi.c
@@ -224,6 +224,7 @@ actcapi_manufacturer_req_net(act2000_car
 /*
  * Switch V.42 on or off
  */
+#if 0
 int
 actcapi_manufacturer_req_v42(act2000_card *card, ulong arg)
 {
@@ -242,6 +243,7 @@ actcapi_manufacturer_req_v42(act2000_car
 	ACTCAPI_QUEUE_TX;
         return 0;
 }
+#endif  /*  0  */
 
 /*
  * Set error-handler
diff --git a/drivers/isdn/act2000/capi.h b/drivers/isdn/act2000/capi.h
--- a/drivers/isdn/act2000/capi.h
+++ b/drivers/isdn/act2000/capi.h
@@ -350,7 +350,6 @@ actcapi_nextsmsg(act2000_card *card)
 extern int actcapi_chkhdr(act2000_card *, actcapi_msghdr *);
 extern int actcapi_listen_req(act2000_card *);
 extern int actcapi_manufacturer_req_net(act2000_card *);
-extern int actcapi_manufacturer_req_v42(act2000_card *, ulong);
 extern int actcapi_manufacturer_req_errh(act2000_card *);
 extern int actcapi_manufacturer_req_msn(act2000_card *);
 extern int actcapi_connect_req(act2000_card *, act2000_chan *, char *, char, int, int);
diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c
--- a/drivers/isdn/capi/capi.c
+++ b/drivers/isdn/capi/capi.c
@@ -58,7 +58,7 @@ MODULE_LICENSE("GPL");
 
 /* -------- driver information -------------------------------------- */
 
-static struct class_simple *capi_class;
+static struct class *capi_class;
 
 static int capi_major = 68;		/* allocated */
 #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
@@ -1499,20 +1499,20 @@ static int __init capi_init(void)
 		return -EIO;
 	}
 
-	capi_class = class_simple_create(THIS_MODULE, "capi");
+	capi_class = class_create(THIS_MODULE, "capi");
 	if (IS_ERR(capi_class)) {
 		unregister_chrdev(capi_major, "capi20");
 		return PTR_ERR(capi_class);
 	}
 
-	class_simple_device_add(capi_class, MKDEV(capi_major, 0), NULL, "capi");
+	class_device_create(capi_class, MKDEV(capi_major, 0), NULL, "capi");
 	devfs_mk_cdev(MKDEV(capi_major, 0), S_IFCHR | S_IRUSR | S_IWUSR,
 			"isdn/capi20");
 
 #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
 	if (capinc_tty_init() < 0) {
-		class_simple_device_remove(MKDEV(capi_major, 0));
-		class_simple_destroy(capi_class);
+		class_device_destroy(capi_class, MKDEV(capi_major, 0));
+		class_destroy(capi_class);
 		unregister_chrdev(capi_major, "capi20");
 		return -ENOMEM;
 	}
@@ -1539,8 +1539,8 @@ static void __exit capi_exit(void)
 {
 	proc_exit();
 
-	class_simple_device_remove(MKDEV(capi_major, 0));
-	class_simple_destroy(capi_class);
+	class_device_destroy(capi_class, MKDEV(capi_major, 0));
+	class_destroy(capi_class);
 	unregister_chrdev(capi_major, "capi20");
 	devfs_remove("isdn/capi20");
 
diff --git a/drivers/isdn/capi/capifs.c b/drivers/isdn/capi/capifs.c
--- a/drivers/isdn/capi/capifs.c
+++ b/drivers/isdn/capi/capifs.c
@@ -191,8 +191,10 @@ static int __init capifs_init(void)
 	err = register_filesystem(&capifs_fs_type);
 	if (!err) {
 		capifs_mnt = kern_mount(&capifs_fs_type);
-		if (IS_ERR(capifs_mnt))
+		if (IS_ERR(capifs_mnt)) {
 			err = PTR_ERR(capifs_mnt);
+			unregister_filesystem(&capifs_fs_type);
+		}
 	}
 	if (!err)
 		printk(KERN_NOTICE "capifs: Rev %s\n", rev);
diff --git a/drivers/isdn/hardware/avm/avm_cs.c b/drivers/isdn/hardware/avm/avm_cs.c
--- a/drivers/isdn/hardware/avm/avm_cs.c
+++ b/drivers/isdn/hardware/avm/avm_cs.c
@@ -22,7 +22,6 @@
 #include <asm/io.h>
 #include <asm/system.h>
 
-#include <pcmcia/version.h>
 #include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
@@ -161,11 +160,6 @@ static dev_link_t *avmcs_attach(void)
     link->next = dev_list;
     dev_list = link;
     client_reg.dev_info = &dev_info;
-    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 = &avmcs_event;
     client_reg.Version = 0x0210;
     client_reg.event_callback_args.client_data = link;
     ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -486,13 +480,23 @@ static int avmcs_event(event_t event, in
     return 0;
 } /* avmcs_event */
 
+static struct pcmcia_device_id avmcs_ids[] = {
+	PCMCIA_DEVICE_PROD_ID12("AVM", "ISDN-Controller B1", 0x95d42008, 0x845dc335),
+	PCMCIA_DEVICE_PROD_ID12("AVM", "Mobile ISDN-Controller M1", 0x95d42008, 0x81e10430),
+	PCMCIA_DEVICE_PROD_ID12("AVM", "Mobile ISDN-Controller M2", 0x95d42008, 0x18e8558a),
+	PCMCIA_DEVICE_NULL
+};
+MODULE_DEVICE_TABLE(pcmcia, avmcs_ids);
+
 static struct pcmcia_driver avmcs_driver = {
 	.owner	= THIS_MODULE,
 	.drv	= {
 		.name	= "avm_cs",
 	},
 	.attach	= avmcs_attach,
+	.event	= avmcs_event,
 	.detach	= avmcs_detach,
+	.id_table = avmcs_ids,
 };
 
 static int __init avmcs_init(void)
diff --git a/drivers/isdn/hardware/avm/b1dma.c b/drivers/isdn/hardware/avm/b1dma.c
--- a/drivers/isdn/hardware/avm/b1dma.c
+++ b/drivers/isdn/hardware/avm/b1dma.c
@@ -955,7 +955,7 @@ EXPORT_SYMBOL(b1dma_release_appl);
 EXPORT_SYMBOL(b1dma_send_message);
 EXPORT_SYMBOL(b1dmactl_read_proc);
 
-int b1dma_init(void)
+static int __init b1dma_init(void)
 {
 	char *p;
 	char rev[32];
@@ -972,7 +972,7 @@ int b1dma_init(void)
 	return 0;
 }
 
-void b1dma_exit(void)
+static void __exit b1dma_exit(void)
 {
 }
 
diff --git a/drivers/isdn/hardware/avm/c4.c b/drivers/isdn/hardware/avm/c4.c
--- a/drivers/isdn/hardware/avm/c4.c
+++ b/drivers/isdn/hardware/avm/c4.c
@@ -885,7 +885,7 @@ static int c4_load_firmware(struct capi_
 }
 
 
-void c4_reset_ctr(struct capi_ctr *ctrl)
+static void c4_reset_ctr(struct capi_ctr *ctrl)
 {
 	avmcard *card = ((avmctrl_info *)(ctrl->driverdata))->card;
 	avmctrl_info *cinfo;
@@ -933,7 +933,7 @@ static void c4_remove(struct pci_dev *pd
 /* ------------------------------------------------------------- */
 
 
-void c4_register_appl(struct capi_ctr *ctrl,
+static void c4_register_appl(struct capi_ctr *ctrl,
 				u16 appl,
 				capi_register_params *rp)
 {
@@ -978,7 +978,7 @@ void c4_register_appl(struct capi_ctr *c
 
 /* ------------------------------------------------------------- */
 
-void c4_release_appl(struct capi_ctr *ctrl, u16 appl)
+static void c4_release_appl(struct capi_ctr *ctrl, u16 appl)
 {
 	avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
 	avmcard *card = cinfo->card;
diff --git a/drivers/isdn/hardware/avm/t1isa.c b/drivers/isdn/hardware/avm/t1isa.c
--- a/drivers/isdn/hardware/avm/t1isa.c
+++ b/drivers/isdn/hardware/avm/t1isa.c
@@ -328,7 +328,7 @@ static int t1isa_load_firmware(struct ca
 	return 0;
 }
 
-void t1isa_reset_ctr(struct capi_ctr *ctrl)
+static void t1isa_reset_ctr(struct capi_ctr *ctrl)
 {
 	avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
 	avmcard *card = cinfo->card;
diff --git a/drivers/isdn/hardware/eicon/dadapter.c b/drivers/isdn/hardware/eicon/dadapter.c
--- a/drivers/isdn/hardware/eicon/dadapter.c
+++ b/drivers/isdn/hardware/eicon/dadapter.c
@@ -44,7 +44,7 @@ static didd_adapter_change_notification_
   Array to held adapter information
    -------------------------------------------------------------------------- */
 static DESCRIPTOR  HandleTable[NEW_MAX_DESCRIPTORS];
-dword Adapters = 0; /* Number of adapters */
+static dword Adapters = 0; /* Number of adapters */
 /* --------------------------------------------------------------------------
   Shadow IDI_DIMAINT
   and 'shadow' debug stuff
diff --git a/drivers/isdn/hisax/Kconfig b/drivers/isdn/hisax/Kconfig
--- a/drivers/isdn/hisax/Kconfig
+++ b/drivers/isdn/hisax/Kconfig
@@ -134,6 +134,7 @@ config HISAX_AVM_A1
 
 config HISAX_FRITZPCI
 	bool "AVM PnP/PCI (Fritz!PnP/PCI)"
+	depends on BROKEN || !PPC64
 	help
 	  This enables HiSax support for the AVM "Fritz!PnP" and "Fritz!PCI".
 	  See <file:Documentation/isdn/README.HiSax> on how to configure it.
diff --git a/drivers/isdn/hisax/Makefile b/drivers/isdn/hisax/Makefile
--- a/drivers/isdn/hisax/Makefile
+++ b/drivers/isdn/hisax/Makefile
@@ -23,7 +23,7 @@ endif
 # Multipart objects.
 
 hisax_st5481-y 				:= st5481_init.o st5481_usb.o st5481_d.o \
-					   st5481_b.o st5481_hdlc.o
+					   st5481_b.o
 
 hisax-y	  				:= config.o isdnl1.o tei.o isdnl2.o isdnl3.o \
 		     			   lmgr.o q931.o callc.o fsm.o
diff --git a/drivers/isdn/hisax/amd7930_fn.c b/drivers/isdn/hisax/amd7930_fn.c
--- a/drivers/isdn/hisax/amd7930_fn.c
+++ b/drivers/isdn/hisax/amd7930_fn.c
@@ -97,7 +97,7 @@ static WORD initAMD[] = {
 };
 
 
-void /* macro wWordAMD */
+static void /* macro wWordAMD */
 WriteWordAmd7930(struct IsdnCardState *cs, BYTE reg, WORD val)
 {
         wByteAMD(cs, 0x00, reg);
@@ -105,7 +105,7 @@ WriteWordAmd7930(struct IsdnCardState *c
         wByteAMD(cs, 0x01, HIBYTE(val));
 }
 
-WORD /* macro rWordAMD */
+static WORD /* macro rWordAMD */
 ReadWordAmd7930(struct IsdnCardState *cs, BYTE reg)
 {
         WORD res;
@@ -665,7 +665,7 @@ Amd7930_l1hw(struct PStack *st, int pr, 
 	}
 }
 
-void
+static void
 setstack_Amd7930(struct PStack *st, struct IsdnCardState *cs)
 {
 
@@ -676,7 +676,7 @@ setstack_Amd7930(struct PStack *st, stru
 }
 
 
-void
+static void
 DC_Close_Amd7930(struct IsdnCardState *cs) {
         if (cs->debug & L1_DEB_ISAC)
 		debugl1(cs, "Amd7930: DC_Close called");
diff --git a/drivers/isdn/hisax/asuscom.c b/drivers/isdn/hisax/asuscom.c
--- a/drivers/isdn/hisax/asuscom.c
+++ b/drivers/isdn/hisax/asuscom.c
@@ -22,7 +22,7 @@
 
 extern const char *CardType[];
 
-const char *Asuscom_revision = "$Revision: 1.14.2.4 $";
+static const char *Asuscom_revision = "$Revision: 1.14.2.4 $";
 
 #define byteout(addr,val) outb(val,addr)
 #define bytein(addr) inb(addr)
@@ -239,7 +239,7 @@ Start_IPAC:
 	return IRQ_HANDLED;
 }
 
-void
+static void
 release_io_asuscom(struct IsdnCardState *cs)
 {
 	int bytecnt = 8;
diff --git a/drivers/isdn/hisax/avm_a1.c b/drivers/isdn/hisax/avm_a1.c
--- a/drivers/isdn/hisax/avm_a1.c
+++ b/drivers/isdn/hisax/avm_a1.c
@@ -135,7 +135,7 @@ avm_a1_interrupt(int intno, void *dev_id
 	return IRQ_HANDLED;
 }
 
-inline static void
+static inline void
 release_ioregs(struct IsdnCardState *cs, int mask)
 {
 	release_region(cs->hw.avm.cfg_reg, 8);
diff --git a/drivers/isdn/hisax/avm_pci.c b/drivers/isdn/hisax/avm_pci.c
--- a/drivers/isdn/hisax/avm_pci.c
+++ b/drivers/isdn/hisax/avm_pci.c
@@ -172,7 +172,7 @@ struct BCState *Sel_BCS(struct IsdnCardS
 		return(NULL);
 }
 
-void
+static void
 write_ctrl(struct BCState *bcs, int which) {
 
 	if (bcs->cs->debug & L1_DEB_HSCX)
@@ -193,7 +193,7 @@ write_ctrl(struct BCState *bcs, int whic
 	}
 }
 
-void
+static void
 modehdlc(struct BCState *bcs, int mode, int bc)
 {
 	struct IsdnCardState *cs = bcs->cs;
@@ -451,7 +451,7 @@ HDLC_irq(struct BCState *bcs, u_int stat
 	}
 }
 
-inline void
+static inline void
 HDLC_irq_main(struct IsdnCardState *cs)
 {
 	u_int stat;
@@ -487,7 +487,7 @@ HDLC_irq_main(struct IsdnCardState *cs)
 	}
 }
 
-void
+static void
 hdlc_l2l1(struct PStack *st, int pr, void *arg)
 {
 	struct BCState *bcs = st->l1.bcs;
@@ -547,7 +547,7 @@ hdlc_l2l1(struct PStack *st, int pr, voi
 	}
 }
 
-void
+static void
 close_hdlcstate(struct BCState *bcs)
 {
 	modehdlc(bcs, 0, 0);
@@ -570,7 +570,7 @@ close_hdlcstate(struct BCState *bcs)
 	}
 }
 
-int
+static int
 open_hdlcstate(struct IsdnCardState *cs, struct BCState *bcs)
 {
 	if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) {
@@ -598,7 +598,7 @@ open_hdlcstate(struct IsdnCardState *cs,
 	return (0);
 }
 
-int
+static int
 setstack_hdlc(struct PStack *st, struct BCState *bcs)
 {
 	bcs->channel = st->l1.bc;
@@ -612,6 +612,7 @@ setstack_hdlc(struct PStack *st, struct 
 	return (0);
 }
 
+#if 0
 void __init
 clear_pending_hdlc_ints(struct IsdnCardState *cs)
 {
@@ -641,8 +642,9 @@ clear_pending_hdlc_ints(struct IsdnCardS
 		debugl1(cs, "HDLC 2 VIN %x", val);
 	}
 }
+#endif  /*  0  */
 
-void __init
+static void __init
 inithdlc(struct IsdnCardState *cs)
 {
 	cs->bcs[0].BC_SetStack = setstack_hdlc;
diff --git a/drivers/isdn/hisax/avma1_cs.c b/drivers/isdn/hisax/avma1_cs.c
--- a/drivers/isdn/hisax/avma1_cs.c
+++ b/drivers/isdn/hisax/avma1_cs.c
@@ -21,7 +21,6 @@
 #include <asm/io.h>
 #include <asm/system.h>
 
-#include <pcmcia/version.h>
 #include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
@@ -183,11 +182,6 @@ static dev_link_t *avma1cs_attach(void)
     link->next = dev_list;
     dev_list = link;
     client_reg.dev_info = &dev_info;
-    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 = &avma1cs_event;
     client_reg.Version = 0x0210;
     client_reg.event_callback_args.client_data = link;
     ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -501,13 +495,22 @@ static int avma1cs_event(event_t event, 
     return 0;
 } /* avma1cs_event */
 
+static struct pcmcia_device_id avma1cs_ids[] = {
+	PCMCIA_DEVICE_PROD_ID12("AVM", "ISDN A", 0x95d42008, 0xadc9d4bb),
+	PCMCIA_DEVICE_PROD_ID12("ISDN", "CARD", 0x8d9761c8, 0x01c5aa7b),
+	PCMCIA_DEVICE_NULL
+};
+MODULE_DEVICE_TABLE(pcmcia, avma1cs_ids);
+
 static struct pcmcia_driver avma1cs_driver = {
 	.owner		= THIS_MODULE,
 	.drv		= {
 		.name	= "avma1_cs",
 	},
 	.attach		= avma1cs_attach,
+	.event		= avma1cs_event,
 	.detach		= avma1cs_detach,
+	.id_table	= avma1cs_ids,
 };
  
 /*====================================================================*/
diff --git a/drivers/isdn/hisax/bkm_a4t.c b/drivers/isdn/hisax/bkm_a4t.c
--- a/drivers/isdn/hisax/bkm_a4t.c
+++ b/drivers/isdn/hisax/bkm_a4t.c
@@ -23,7 +23,7 @@
 
 extern const char *CardType[];
 
-const char *bkm_a4t_revision = "$Revision: 1.22.2.4 $";
+static const char *bkm_a4t_revision = "$Revision: 1.22.2.4 $";
 
 
 static inline u_char
@@ -167,7 +167,7 @@ bkm_interrupt(int intno, void *dev_id, s
 	}
 }
 
-void
+static void
 release_io_bkm(struct IsdnCardState *cs)
 {
 	if (cs->hw.ax.base) {
diff --git a/drivers/isdn/hisax/bkm_a8.c b/drivers/isdn/hisax/bkm_a8.c
--- a/drivers/isdn/hisax/bkm_a8.c
+++ b/drivers/isdn/hisax/bkm_a8.c
@@ -27,7 +27,7 @@
 
 extern const char *CardType[];
 
-const char sct_quadro_revision[] = "$Revision: 1.22.2.4 $";
+static const char sct_quadro_revision[] = "$Revision: 1.22.2.4 $";
 
 static const char *sct_quadro_subtypes[] =
 {
@@ -193,7 +193,7 @@ bkm_interrupt_ipac(int intno, void *dev_
 	return IRQ_HANDLED;
 }
 
-void
+static void
 release_io_sct_quadro(struct IsdnCardState *cs)
 {
 	release_region(cs->hw.ax.base & 0xffffffc0, 128);
@@ -261,7 +261,7 @@ BKM_card_msg(struct IsdnCardState *cs, i
 	return (0);
 }
 
-int __init
+static int __init
 sct_alloc_io(u_int adr, u_int len)
 {
 	if (!request_region(adr, len, "scitel")) {
diff --git a/drivers/isdn/hisax/callc.c b/drivers/isdn/hisax/callc.c
--- a/drivers/isdn/hisax/callc.c
+++ b/drivers/isdn/hisax/callc.c
@@ -874,7 +874,7 @@ release_b_st(struct Channel *chanp)
 	} 
 }
 
-struct Channel
+static struct Channel
 *selectfreechannel(struct PStack *st, int bch)
 {
 	struct IsdnCardState *cs = st->l1.hardware;
@@ -1429,7 +1429,7 @@ capi_debug(struct Channel *chanp, capi_m
 	HiSax_putstatus(chanp->cs, "Ch", "%d CAPIMSG %s", chanp->chan, tmpbuf);
 }
 
-void
+static void
 lli_got_fac_req(struct Channel *chanp, capi_msg *cm) {
 	if ((cm->para[0] != 3) || (cm->para[1] != 0))
 		return;
@@ -1454,7 +1454,7 @@ lli_got_fac_req(struct Channel *chanp, c
 	}
 }
 
-void
+static void
 lli_got_manufacturer(struct Channel *chanp, struct IsdnCardState *cs, capi_msg *cm) {
 	if ((cs->typ == ISDN_CTYPE_ELSA) || (cs->typ == ISDN_CTYPE_ELSA_PNP) ||
 		(cs->typ == ISDN_CTYPE_ELSA_PCI)) {
diff --git a/drivers/isdn/hisax/config.c b/drivers/isdn/hisax/config.c
--- a/drivers/isdn/hisax/config.c
+++ b/drivers/isdn/hisax/config.c
@@ -332,7 +332,7 @@ struct IsdnCard cards[HISAX_MAX_CARDS] =
 #define HISAX_IDSIZE (HISAX_MAX_CARDS*8)
 static char HiSaxID[HISAX_IDSIZE] = { 0, };
 
-char *HiSax_id = HiSaxID;
+static char *HiSax_id = HiSaxID;
 #ifdef MODULE
 /* Variables for insmod */
 static int type[HISAX_MAX_CARDS] = { 0, };
@@ -391,7 +391,7 @@ char *HiSax_getrev(const char *revision)
 	return rev;
 }
 
-void __init HiSaxVersion(void)
+static void __init HiSaxVersion(void)
 {
 	char tmp[64];
 
@@ -608,6 +608,7 @@ static inline struct IsdnCardState *hisa
 /*
  * Find card with given card number
  */
+#if 0
 struct IsdnCardState *hisax_get_card(int cardnr)
 {
 	if ((cardnr <= nrcards) && (cardnr > 0))
@@ -615,8 +616,9 @@ struct IsdnCardState *hisax_get_card(int
 			return cards[cardnr - 1].cs;
 	return NULL;
 }
+#endif  /*  0  */
 
-int HiSax_readstatus(u_char __user *buf, int len, int id, int channel)
+static int HiSax_readstatus(u_char __user *buf, int len, int id, int channel)
 {
 	int count, cnt;
 	u_char __user *p = buf;
@@ -768,7 +770,7 @@ int ll_run(struct IsdnCardState *cs, int
 	return 0;
 }
 
-void ll_stop(struct IsdnCardState *cs)
+static void ll_stop(struct IsdnCardState *cs)
 {
 	isdn_ctrl ic;
 
@@ -1184,7 +1186,7 @@ static int checkcard(int cardnr, char *i
 	return ret;
 }
 
-void HiSax_shiftcards(int idx)
+static void HiSax_shiftcards(int idx)
 {
 	int i;
 
@@ -1192,7 +1194,7 @@ void HiSax_shiftcards(int idx)
 		memcpy(&cards[i], &cards[i + 1], sizeof(cards[i]));
 }
 
-int HiSax_inithardware(int *busy_flag)
+static int HiSax_inithardware(int *busy_flag)
 {
 	int foundcards = 0;
 	int i = 0;
@@ -1898,6 +1900,7 @@ static struct pci_device_id hisax_pci_tb
 	{PCI_VENDOR_ID_PLX,      PCI_DEVICE_ID_PLX_R685,         PCI_ANY_ID, PCI_ANY_ID},
 	{PCI_VENDOR_ID_PLX,      PCI_DEVICE_ID_PLX_R753,         PCI_ANY_ID, PCI_ANY_ID},
 	{PCI_VENDOR_ID_PLX,      PCI_DEVICE_ID_PLX_DJINN_ITOO,   PCI_ANY_ID, PCI_ANY_ID},
+	{PCI_VENDOR_ID_PLX,      PCI_DEVICE_ID_PLX_OLITEC,       PCI_ANY_ID, PCI_ANY_ID},
 #endif
 #ifdef CONFIG_HISAX_QUADRO
 	{PCI_VENDOR_ID_PLX,      PCI_DEVICE_ID_PLX_9050,         PCI_ANY_ID, PCI_ANY_ID},
diff --git a/drivers/isdn/hisax/diva.c b/drivers/isdn/hisax/diva.c
--- a/drivers/isdn/hisax/diva.c
+++ b/drivers/isdn/hisax/diva.c
@@ -28,7 +28,7 @@
 
 extern const char *CardType[];
 
-const char *Diva_revision = "$Revision: 1.33.2.6 $";
+static const char *Diva_revision = "$Revision: 1.33.2.6 $";
 
 #define byteout(addr,val) outb(val,addr)
 #define bytein(addr) inb(addr)
@@ -706,7 +706,7 @@ diva_irq_ipacx_pci(int intno, void *dev_
 	return IRQ_HANDLED;
 }
 
-void
+static void
 release_io_diva(struct IsdnCardState *cs)
 {
 	int bytecnt;
diff --git a/drivers/isdn/hisax/elsa.c b/drivers/isdn/hisax/elsa.c
--- a/drivers/isdn/hisax/elsa.c
+++ b/drivers/isdn/hisax/elsa.c
@@ -33,13 +33,13 @@
 
 extern const char *CardType[];
 
-const char *Elsa_revision = "$Revision: 2.32.2.4 $";
-const char *Elsa_Types[] =
+static const char *Elsa_revision = "$Revision: 2.32.2.4 $";
+static const char *Elsa_Types[] =
 {"None", "PC", "PCC-8", "PCC-16", "PCF", "PCF-Pro",
  "PCMCIA", "QS 1000", "QS 3000", "Microlink PCI", "QS 3000 PCI", 
  "PCMCIA-IPAC" };
 
-const char *ITACVer[] =
+static const char *ITACVer[] =
 {"?0?", "?1?", "?2?", "?3?", "?4?", "V2.2",
  "B1", "A1"};
 
@@ -425,7 +425,7 @@ Start_IPAC:
 	return IRQ_HANDLED;
 }
 
-void
+static void
 release_io_elsa(struct IsdnCardState *cs)
 {
 	int bytecnt = 8;
diff --git a/drivers/isdn/hisax/elsa_cs.c b/drivers/isdn/hisax/elsa_cs.c
--- a/drivers/isdn/hisax/elsa_cs.c
+++ b/drivers/isdn/hisax/elsa_cs.c
@@ -47,7 +47,6 @@
 #include <asm/io.h>
 #include <asm/system.h>
 
-#include <pcmcia/version.h>
 #include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
@@ -212,11 +211,6 @@ static dev_link_t *elsa_cs_attach(void)
     link->next = dev_list;
     dev_list = link;
     client_reg.dev_info = &dev_info;
-    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 = &elsa_cs_event;
     client_reg.Version = 0x0210;
     client_reg.event_callback_args.client_data = link;
     ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -508,13 +502,22 @@ static int elsa_cs_event(event_t event, 
     return 0;
 } /* elsa_cs_event */
 
+static struct pcmcia_device_id elsa_ids[] = {
+	PCMCIA_DEVICE_PROD_ID12("ELSA AG (Aachen, Germany)", "MicroLink ISDN/MC ", 0x983de2c4, 0x333ba257),
+	PCMCIA_DEVICE_PROD_ID12("ELSA GmbH, Aachen", "MicroLink ISDN/MC ", 0x639e5718, 0x333ba257),
+	PCMCIA_DEVICE_NULL
+};
+MODULE_DEVICE_TABLE(pcmcia, elsa_ids);
+
 static struct pcmcia_driver elsa_cs_driver = {
 	.owner		= THIS_MODULE,
 	.drv		= {
 		.name	= "elsa_cs",
 	},
 	.attach		= elsa_cs_attach,
+	.event		= elsa_cs_event,
 	.detach		= elsa_cs_detach,
+	.id_table	= elsa_ids,
 };
 
 static int __init init_elsa_cs(void)
diff --git a/drivers/isdn/hisax/elsa_ser.c b/drivers/isdn/hisax/elsa_ser.c
--- a/drivers/isdn/hisax/elsa_ser.c
+++ b/drivers/isdn/hisax/elsa_ser.c
@@ -237,7 +237,7 @@ static void mshutdown(struct IsdnCardSta
 #endif
 }
 
-inline int
+static inline int
 write_modem(struct BCState *bcs) {
 	int ret=0;
 	struct IsdnCardState *cs = bcs->cs;
@@ -275,7 +275,7 @@ write_modem(struct BCState *bcs) {
 	return(ret);
 }
 
-inline void
+static inline void
 modem_fill(struct BCState *bcs) {
 		
 	if (bcs->tx_skb) {
@@ -422,7 +422,7 @@ extern int open_hscxstate(struct IsdnCar
 extern void modehscx(struct BCState *bcs, int mode, int bc);
 extern void hscx_l2l1(struct PStack *st, int pr, void *arg);
 
-void
+static void
 close_elsastate(struct BCState *bcs)
 {
 	modehscx(bcs, 0, bcs->channel);
@@ -442,7 +442,7 @@ close_elsastate(struct BCState *bcs)
 	}
 }
 
-void
+static void
 modem_write_cmd(struct IsdnCardState *cs, u_char *buf, int len) {
 	int count, fp;
 	u_char *msg = buf;
@@ -472,7 +472,7 @@ modem_write_cmd(struct IsdnCardState *cs
 	}
 }
 
-void
+static void
 modem_set_init(struct IsdnCardState *cs) {
 	int timeout;
 
@@ -521,7 +521,7 @@ modem_set_init(struct IsdnCardState *cs)
 	udelay(RCV_DELAY);
 }
 
-void
+static void
 modem_set_dial(struct IsdnCardState *cs, int outgoing) {
 	int timeout;
 #define RCV_DELAY 20000	
@@ -543,7 +543,7 @@ modem_set_dial(struct IsdnCardState *cs,
 	udelay(RCV_DELAY);
 }
 
-void
+static void
 modem_l2l1(struct PStack *st, int pr, void *arg)
 {
 	struct BCState *bcs = st->l1.bcs;
@@ -579,7 +579,7 @@ modem_l2l1(struct PStack *st, int pr, vo
 	}
 }
 
-int
+static int
 setstack_elsa(struct PStack *st, struct BCState *bcs)
 {
 
@@ -614,7 +614,7 @@ setstack_elsa(struct PStack *st, struct 
 	return (0);
 }
 
-void
+static void
 init_modem(struct IsdnCardState *cs) {
 
 	cs->bcs[0].BC_SetStack = setstack_elsa;
@@ -641,7 +641,7 @@ init_modem(struct IsdnCardState *cs) {
 	modem_set_init(cs);
 }
 
-void
+static void
 release_modem(struct IsdnCardState *cs) {
 
 	cs->hw.elsa.MFlag = 0;
diff --git a/drivers/isdn/hisax/enternow.h b/drivers/isdn/hisax/enternow.h
deleted file mode 100644
--- a/drivers/isdn/hisax/enternow.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/* 2001/10/02
- *
- * enternow.h   Header-file included by
- *              enternow_pci.c
- *
- * Author       Christoph Ersfeld <info@formula-n.de>
- *              Formula-n Europe AG (www.formula-n.com)
- *              previously Gerdes AG
- *
- *
- *              This file is (c) under GNU PUBLIC LICENSE
- */
-
-
-/* ***************************************************************************************** *
- * ****************************** datatypes and macros ************************************* *
- * ***************************************************************************************** */
-
-#define BYTE							unsigned char
-#define WORD							unsigned int
-#define HIBYTE(w)						((unsigned char)((w & 0xff00) / 256))
-#define LOBYTE(w)						((unsigned char)(w & 0x00ff))
-#define InByte(addr)						inb(addr)
-#define OutByte(addr,val)					outb(val,addr)
-
-
-
-/* ***************************************************************************************** *
- * *********************************** card-specific *************************************** *
- * ***************************************************************************************** */
-
-/* für PowerISDN PCI */
-#define TJ_AMD_IRQ 						0x20
-#define TJ_LED1 						0x40
-#define TJ_LED2 						0x80
-
-
-/* Das Fenster zum AMD...
- * Ab Adresse hw.njet.base + TJ_AMD_PORT werden vom AMD jeweils 8 Bit in
- * den TigerJet i/o-Raum gemappt
- * -> 0x01 des AMD bei hw.njet.base + 0C4 */
-#define TJ_AMD_PORT						0xC0
-
-
-
-/* ***************************************************************************************** *
- * *************************************** Prototypen ************************************** *
- * ***************************************************************************************** */
-
-BYTE ReadByteAmd7930(struct IsdnCardState *cs, BYTE offset);
-void WriteByteAmd7930(struct IsdnCardState *cs, BYTE offset, BYTE value);
diff --git a/drivers/isdn/hisax/enternow_pci.c b/drivers/isdn/hisax/enternow_pci.c
--- a/drivers/isdn/hisax/enternow_pci.c
+++ b/drivers/isdn/hisax/enternow_pci.c
@@ -65,7 +65,6 @@
 #include "isac.h"
 #include "isdnl1.h"
 #include "amd7930_fn.h"
-#include "enternow.h"
 #include <linux/interrupt.h>
 #include <linux/ppp_defs.h>
 #include <linux/pci.h>
@@ -74,58 +73,72 @@
 
 
 
-const char *enternow_pci_rev = "$Revision: 1.1.4.5 $";
+static const char *enternow_pci_rev = "$Revision: 1.1.4.5 $";
+
+
+/* für PowerISDN PCI */
+#define TJ_AMD_IRQ                                              0x20
+#define TJ_LED1                                                 0x40
+#define TJ_LED2                                                 0x80
+
+
+/* Das Fenster zum AMD...
+ * Ab Adresse hw.njet.base + TJ_AMD_PORT werden vom AMD jeweils 8 Bit in
+ * den TigerJet i/o-Raum gemappt
+ * -> 0x01 des AMD bei hw.njet.base + 0C4 */
+#define TJ_AMD_PORT                                             0xC0
+
 
 
 /* *************************** I/O-Interface functions ************************************* */
 
 
 /* cs->readisac, macro rByteAMD */
-BYTE
-ReadByteAmd7930(struct IsdnCardState *cs, BYTE offset)
+static unsigned char
+ReadByteAmd7930(struct IsdnCardState *cs, unsigned char offset)
 {
 	/* direktes Register */
 	if(offset < 8)
-		return (InByte(cs->hw.njet.isac + 4*offset));
+		return (inb(cs->hw.njet.isac + 4*offset));
 
 	/* indirektes Register */
 	else {
-		OutByte(cs->hw.njet.isac + 4*AMD_CR, offset);
-		return(InByte(cs->hw.njet.isac + 4*AMD_DR));
+		outb(offset, cs->hw.njet.isac + 4*AMD_CR);
+		return(inb(cs->hw.njet.isac + 4*AMD_DR));
 	}
 }
 
 /* cs->writeisac, macro wByteAMD */
-void
-WriteByteAmd7930(struct IsdnCardState *cs, BYTE offset, BYTE value)
+static void
+WriteByteAmd7930(struct IsdnCardState *cs, unsigned char offset, unsigned char value)
 {
 	/* direktes Register */
 	if(offset < 8)
-		OutByte(cs->hw.njet.isac + 4*offset, value);
+		outb(value, cs->hw.njet.isac + 4*offset);
 
 	/* indirektes Register */
 	else {
-		OutByte(cs->hw.njet.isac + 4*AMD_CR, offset);
-		OutByte(cs->hw.njet.isac + 4*AMD_DR, value);
+		outb(offset, cs->hw.njet.isac + 4*AMD_CR);
+		outb(value, cs->hw.njet.isac + 4*AMD_DR);
 	}
 }
 
 
-void
-enpci_setIrqMask(struct IsdnCardState *cs, BYTE val) {
+static void
+enpci_setIrqMask(struct IsdnCardState *cs, unsigned char val) {
         if (!val)
-	        OutByte(cs->hw.njet.base+NETJET_IRQMASK1, 0x00);
+	        outb(0x00, cs->hw.njet.base+NETJET_IRQMASK1);
         else
-	        OutByte(cs->hw.njet.base+NETJET_IRQMASK1, TJ_AMD_IRQ);
+	        outb(TJ_AMD_IRQ, cs->hw.njet.base+NETJET_IRQMASK1);
 }
 
 
-static BYTE dummyrr(struct IsdnCardState *cs, int chan, BYTE off)
+static unsigned char dummyrr(struct IsdnCardState *cs, int chan, unsigned char off)
 {
         return(5);
 }
 
-static void dummywr(struct IsdnCardState *cs, int chan, BYTE off, BYTE value)
+static void dummywr(struct IsdnCardState *cs, int chan, unsigned char off, unsigned char value)
 {
 
 }
@@ -142,18 +155,18 @@ reset_enpci(struct IsdnCardState *cs)
 
 	/* Reset on, (also for AMD) */
 	cs->hw.njet.ctrl_reg = 0x07;
-	OutByte(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg);
+	outb(cs->hw.njet.ctrl_reg, cs->hw.njet.base + NETJET_CTRL);
 	mdelay(20);
 	/* Reset off */
 	cs->hw.njet.ctrl_reg = 0x30;
-	OutByte(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg);
+	outb(cs->hw.njet.ctrl_reg, cs->hw.njet.base + NETJET_CTRL);
 	/* 20ms delay */
 	mdelay(20);
 	cs->hw.njet.auxd = 0;  // LED-status
 	cs->hw.njet.dmactrl = 0;
-	OutByte(cs->hw.njet.base + NETJET_AUXCTRL, ~TJ_AMD_IRQ);
-	OutByte(cs->hw.njet.base + NETJET_IRQMASK1, TJ_AMD_IRQ);
-	OutByte(cs->hw.njet.auxa, cs->hw.njet.auxd); // LED off
+	outb(~TJ_AMD_IRQ, cs->hw.njet.base + NETJET_AUXCTRL);
+	outb(TJ_AMD_IRQ, cs->hw.njet.base + NETJET_IRQMASK1);
+	outb(cs->hw.njet.auxd, cs->hw.njet.auxa); // LED off
 }
 
 
@@ -161,7 +174,7 @@ static int
 enpci_card_msg(struct IsdnCardState *cs, int mt, void *arg)
 {
 	u_long flags;
-        BYTE *chan;
+        unsigned char *chan;
 
 	if (cs->debug & L1_DEB_ISAC)
 		debugl1(cs, "enter:now PCI: card_msg: 0x%04X", mt);
@@ -187,16 +200,16 @@ enpci_card_msg(struct IsdnCardState *cs,
                 case MDL_ASSIGN:
                         /* TEI assigned, LED1 on */
                         cs->hw.njet.auxd = TJ_AMD_IRQ << 1;
-                        OutByte(cs->hw.njet.base + NETJET_AUXDATA, cs->hw.njet.auxd);
+                        outb(cs->hw.njet.auxd, cs->hw.njet.base + NETJET_AUXDATA);
                         break;
                 case MDL_REMOVE:
                         /* TEI removed, LEDs off */
 	                cs->hw.njet.auxd = 0;
-                        OutByte(cs->hw.njet.base + NETJET_AUXDATA, 0x00);
+                        outb(0x00, cs->hw.njet.base + NETJET_AUXDATA);
                         break;
                 case MDL_BC_ASSIGN:
                         /* activate B-channel */
-                        chan = (BYTE *)arg;
+                        chan = (unsigned char *)arg;
 
                         if (cs->debug & L1_DEB_ISAC)
 		                debugl1(cs, "enter:now PCI: assign phys. BC %d in AMD LMR1", *chan);
@@ -204,11 +217,11 @@ enpci_card_msg(struct IsdnCardState *cs,
                         cs->dc.amd7930.ph_command(cs, (cs->dc.amd7930.lmr1 | (*chan + 1)), "MDL_BC_ASSIGN");
                         /* at least one b-channel in use, LED 2 on */
                         cs->hw.njet.auxd |= TJ_AMD_IRQ << 2;
-                        OutByte(cs->hw.njet.base + NETJET_AUXDATA, cs->hw.njet.auxd);
+                        outb(cs->hw.njet.auxd, cs->hw.njet.base + NETJET_AUXDATA);
                         break;
                 case MDL_BC_RELEASE:
                         /* deactivate B-channel */
-                        chan = (BYTE *)arg;
+                        chan = (unsigned char *)arg;
 
                         if (cs->debug & L1_DEB_ISAC)
 		                debugl1(cs, "enter:now PCI: release phys. BC %d in Amd LMR1", *chan);
@@ -217,7 +230,7 @@ enpci_card_msg(struct IsdnCardState *cs,
                         /* no b-channel active -> LED2 off */
                         if (!(cs->dc.amd7930.lmr1 & 3)) {
                                 cs->hw.njet.auxd &= ~(TJ_AMD_IRQ << 2);
-                                OutByte(cs->hw.njet.base + NETJET_AUXDATA, cs->hw.njet.auxd);
+                                outb(cs->hw.njet.auxd, cs->hw.njet.base + NETJET_AUXDATA);
                         }
                         break;
                 default:
@@ -231,11 +244,11 @@ static irqreturn_t
 enpci_interrupt(int intno, void *dev_id, struct pt_regs *regs)
 {
 	struct IsdnCardState *cs = dev_id;
-	BYTE s0val, s1val, ir;
+	unsigned char s0val, s1val, ir;
 	u_long flags;
 
 	spin_lock_irqsave(&cs->lock, flags);
-	s1val = InByte(cs->hw.njet.base + NETJET_IRQSTAT1);
+	s1val = inb(cs->hw.njet.base + NETJET_IRQSTAT1);
 
         /* AMD threw an interrupt */
 	if (!(s1val & TJ_AMD_IRQ)) {
@@ -245,13 +258,13 @@ enpci_interrupt(int intno, void *dev_id,
 		s1val = 1;
 	} else
 		s1val = 0;
-	s0val = InByte(cs->hw.njet.base + NETJET_IRQSTAT0);
+	s0val = inb(cs->hw.njet.base + NETJET_IRQSTAT0);
 	if ((s0val | s1val)==0) { // shared IRQ
 		spin_unlock_irqrestore(&cs->lock, flags);
 		return IRQ_NONE;
 	} 
 	if (s0val)
-		OutByte(cs->hw.njet.base + NETJET_IRQSTAT0, s0val);
+		outb(s0val, cs->hw.njet.base + NETJET_IRQSTAT0);
 
 	/* DMA-Interrupt: B-channel-stuff */
 	/* set bits in sval to indicate which page is free */
@@ -342,20 +355,20 @@ setup_enternow_pci(struct IsdnCard *card
 
 		/* Reset an */
 		cs->hw.njet.ctrl_reg = 0x07;  // geändert von 0xff
-		OutByte(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg);
+		outb(cs->hw.njet.ctrl_reg, cs->hw.njet.base + NETJET_CTRL);
 		/* 20 ms Pause */
 		mdelay(20);
 
 		cs->hw.njet.ctrl_reg = 0x30;  /* Reset Off and status read clear */
-		OutByte(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg);
+		outb(cs->hw.njet.ctrl_reg, cs->hw.njet.base + NETJET_CTRL);
 		mdelay(10);
 
 		cs->hw.njet.auxd = 0x00; // war 0xc0
 		cs->hw.njet.dmactrl = 0;
 
-		OutByte(cs->hw.njet.base + NETJET_AUXCTRL, ~TJ_AMD_IRQ);
-		OutByte(cs->hw.njet.base + NETJET_IRQMASK1, TJ_AMD_IRQ);
-		OutByte(cs->hw.njet.auxa, cs->hw.njet.auxd);
+		outb(~TJ_AMD_IRQ, cs->hw.njet.base + NETJET_AUXCTRL);
+		outb(TJ_AMD_IRQ, cs->hw.njet.base + NETJET_IRQMASK1);
+		outb(cs->hw.njet.auxd, cs->hw.njet.auxa);
 
 		break;
 	}
diff --git a/drivers/isdn/hisax/gazel.c b/drivers/isdn/hisax/gazel.c
--- a/drivers/isdn/hisax/gazel.c
+++ b/drivers/isdn/hisax/gazel.c
@@ -21,7 +21,7 @@
 #include <linux/pci.h>
 
 extern const char *CardType[];
-const char *gazel_revision = "$Revision: 2.19.2.4 $";
+static const char *gazel_revision = "$Revision: 2.19.2.4 $";
 
 #define R647      1
 #define R685      2
@@ -317,7 +317,8 @@ gazel_interrupt_ipac(int intno, void *de
 	spin_unlock_irqrestore(&cs->lock, flags);
 	return IRQ_HANDLED;
 }
-void
+
+static void
 release_io_gazel(struct IsdnCardState *cs)
 {
 	unsigned int i;
@@ -545,8 +546,9 @@ setup_gazelpci(struct IsdnCardState *cs)
 
 	found = 0;
 	seekcard = PCI_DEVICE_ID_PLX_R685;
-	for (nbseek = 0; nbseek < 3; nbseek++) {
-		if ((dev_tel = pci_find_device(PCI_VENDOR_ID_PLX, seekcard, dev_tel))) {
+	for (nbseek = 0; nbseek < 4; nbseek++) {
+		if ((dev_tel = pci_find_device(PCI_VENDOR_ID_PLX,
+					seekcard, dev_tel))) {
 			if (pci_enable_device(dev_tel))
 				return 1;
 			pci_irq = dev_tel->irq;
@@ -564,6 +566,9 @@ setup_gazelpci(struct IsdnCardState *cs)
 				case PCI_DEVICE_ID_PLX_R753:
 					seekcard = PCI_DEVICE_ID_PLX_DJINN_ITOO;
 					break;
+				case PCI_DEVICE_ID_PLX_DJINN_ITOO:
+					seekcard = PCI_DEVICE_ID_PLX_OLITEC;
+					break;
 			}
 		}
 	}
@@ -604,6 +609,7 @@ setup_gazelpci(struct IsdnCardState *cs)
 			break;
 		case PCI_DEVICE_ID_PLX_R753:
 		case PCI_DEVICE_ID_PLX_DJINN_ITOO:
+		case PCI_DEVICE_ID_PLX_OLITEC:
 			printk(KERN_INFO "Gazel: Card PCI R753 found\n");
 			cs->subtyp = R753;
 			test_and_set_bit(HW_IPAC, &cs->HW_Flags);
diff --git a/drivers/isdn/hisax/hfc4s8s_l1.c b/drivers/isdn/hisax/hfc4s8s_l1.c
--- a/drivers/isdn/hisax/hfc4s8s_l1.c
+++ b/drivers/isdn/hisax/hfc4s8s_l1.c
@@ -312,7 +312,7 @@ wait_busy(hfc4s8s_hw * a)
 /* function to read critical counter registers that   */
 /* may be udpated by the chip during read             */
 /******************************************************/
-static volatile u_char
+static u_char
 Read_hfc8_stable(hfc4s8s_hw * hw, int reg)
 {
 	u_char ref8;
@@ -324,7 +324,7 @@ Read_hfc8_stable(hfc4s8s_hw * hw, int re
 	return in8;
 }
 
-static volatile int
+static int
 Read_hfc16_stable(hfc4s8s_hw * hw, int reg)
 {
 	int ref16;
@@ -1358,7 +1358,7 @@ chipreset(hfc4s8s_hw * hw)
 /********************************************/
 /* disable/enable hardware in nt or te mode */
 /********************************************/
-void
+static void
 hfc_hardware_enable(hfc4s8s_hw * hw, int enable, int nt_mode)
 {
 	u_long flags;
@@ -1465,7 +1465,7 @@ hfc_hardware_enable(hfc4s8s_hw * hw, int
 /******************************************/
 /* disable memory mapped ports / io ports */
 /******************************************/
-void
+static void
 release_pci_ports(hfc4s8s_hw * hw)
 {
 	pci_write_config_word(hw->pdev, PCI_COMMAND, 0);
@@ -1481,7 +1481,7 @@ release_pci_ports(hfc4s8s_hw * hw)
 /*****************************************/
 /* enable memory mapped ports / io ports */
 /*****************************************/
-void
+static void
 enable_pci_ports(hfc4s8s_hw * hw)
 {
 #ifdef CONFIG_HISAX_HFC4S8S_PCIMEM
diff --git a/drivers/isdn/hisax/hfc_2bds0.c b/drivers/isdn/hisax/hfc_2bds0.c
--- a/drivers/isdn/hisax/hfc_2bds0.c
+++ b/drivers/isdn/hisax/hfc_2bds0.c
@@ -345,7 +345,7 @@ hfc_send_data(struct BCState *bcs)
 		debugl1(cs,"send_data %d blocked", bcs->channel);
 }
 
-void
+static void
 main_rec_2bds0(struct BCState *bcs)
 {
 	struct IsdnCardState *cs = bcs->cs;
@@ -399,7 +399,7 @@ main_rec_2bds0(struct BCState *bcs)
 	return;
 }
 
-void
+static void
 mode_2bs0(struct BCState *bcs, int mode, int bc)
 {
 	struct IsdnCardState *cs = bcs->cs;
@@ -505,7 +505,7 @@ hfc_l2l1(struct PStack *st, int pr, void
 	}
 }
 
-void
+static void
 close_2bs0(struct BCState *bcs)
 {
 	mode_2bs0(bcs, 0, bcs->channel);
@@ -534,7 +534,7 @@ open_hfcstate(struct IsdnCardState *cs, 
 	return (0);
 }
 
-int
+static int
 setstack_2b(struct PStack *st, struct BCState *bcs)
 {
 	bcs->channel = st->l1.bc;
@@ -1004,7 +1004,7 @@ HFCD_l1hw(struct PStack *st, int pr, voi
 	}
 }
 
-void
+static void
 setstack_hfcd(struct PStack *st, struct IsdnCardState *cs)
 {
 	st->l1.l1hw = HFCD_l1hw;
@@ -1015,7 +1015,7 @@ hfc_dbusy_timer(struct IsdnCardState *cs
 {
 }
 
-unsigned int __init
+static unsigned int __init
 *init_send_hfcd(int cnt)
 {
 	int i, *send;
diff --git a/drivers/isdn/hisax/hfc_2bs0.c b/drivers/isdn/hisax/hfc_2bs0.c
--- a/drivers/isdn/hisax/hfc_2bs0.c
+++ b/drivers/isdn/hisax/hfc_2bs0.c
@@ -52,7 +52,7 @@ WaitNoBusy(struct IsdnCardState *cs)
 		return (to);
 }
 
-int
+static int
 GetFreeFifoBytes(struct BCState *bcs)
 {
 	int s;
@@ -66,7 +66,7 @@ GetFreeFifoBytes(struct BCState *bcs)
 	return (s);
 }
 
-int
+static int
 ReadZReg(struct BCState *bcs, u_char reg)
 {
 	int val;
@@ -394,7 +394,7 @@ main_irq_hfc(struct BCState *bcs)
 	return;
 }
 
-void
+static void
 mode_hfc(struct BCState *bcs, int mode, int bc)
 {
 	struct IsdnCardState *cs = bcs->cs;
@@ -507,7 +507,7 @@ hfc_l2l1(struct PStack *st, int pr, void
 }
 
 
-void
+static void
 close_hfcstate(struct BCState *bcs)
 {
 	mode_hfc(bcs, 0, bcs->channel);
@@ -537,7 +537,7 @@ open_hfcstate(struct IsdnCardState *cs, 
 	return (0);
 }
 
-int
+static int
 setstack_hfc(struct PStack *st, struct BCState *bcs)
 {
 	bcs->channel = st->l1.bc;
@@ -551,7 +551,7 @@ setstack_hfc(struct PStack *st, struct B
 	return (0);
 }
 
-void __init
+static void __init
 init_send(struct BCState *bcs)
 {
 	int i;
diff --git a/drivers/isdn/hisax/hfc_pci.c b/drivers/isdn/hisax/hfc_pci.c
--- a/drivers/isdn/hisax/hfc_pci.c
+++ b/drivers/isdn/hisax/hfc_pci.c
@@ -70,7 +70,7 @@ static const PCI_ENTRY id_list[] =
 /******************************************/
 /* free hardware resources used by driver */
 /******************************************/
-void
+static void
 release_io_hfcpci(struct IsdnCardState *cs)
 {
 	printk(KERN_INFO "HiSax: release hfcpci at %p\n",
@@ -394,7 +394,7 @@ receive_dmsg(struct IsdnCardState *cs)
 /*******************************************************************************/
 /* check for transparent receive data and read max one threshold size if avail */
 /*******************************************************************************/
-int
+static int
 hfcpci_empty_fifo_trans(struct BCState *bcs, bzfifo_type * bz, u_char * bdata)
 {
 	unsigned short *z1r, *z2r;
@@ -446,7 +446,7 @@ hfcpci_empty_fifo_trans(struct BCState *
 /**********************************/
 /* B-channel main receive routine */
 /**********************************/
-void
+static void
 main_rec_hfcpci(struct BCState *bcs)
 {
 	struct IsdnCardState *cs = bcs->cs;
@@ -1244,7 +1244,7 @@ HFCPCI_l1hw(struct PStack *st, int pr, v
 /***********************************************/
 /* called during init setting l1 stack pointer */
 /***********************************************/
-void
+static void
 setstack_hfcpci(struct PStack *st, struct IsdnCardState *cs)
 {
 	st->l1.l1hw = HFCPCI_l1hw;
@@ -1268,7 +1268,7 @@ hfcpci_send_data(struct BCState *bcs)
 /***************************************************************/
 /* activate/deactivate hardware for selected channels and mode */
 /***************************************************************/
-void
+static void
 mode_hfcpci(struct BCState *bcs, int mode, int bc)
 {
 	struct IsdnCardState *cs = bcs->cs;
@@ -1579,7 +1579,7 @@ hfcpci_bh(struct IsdnCardState *cs)
 /********************************/
 /* called for card init message */
 /********************************/
-void __init
+static void __init
 inithfcpci(struct IsdnCardState *cs)
 {
 	cs->bcs[0].BC_SetStack = setstack_2b;
diff --git a/drivers/isdn/hisax/hfc_pci.h b/drivers/isdn/hisax/hfc_pci.h
--- a/drivers/isdn/hisax/hfc_pci.h
+++ b/drivers/isdn/hisax/hfc_pci.h
@@ -232,5 +232,4 @@ typedef union {
 #define Read_hfc(a,b) (*(((u_char *)a->hw.hfcpci.pci_io)+b))
 
 extern void main_irq_hcpci(struct BCState *bcs);
-extern void inithfcpci(struct IsdnCardState *cs);
 extern void releasehfcpci(struct IsdnCardState *cs);
diff --git a/drivers/isdn/hisax/hfc_sx.c b/drivers/isdn/hisax/hfc_sx.c
--- a/drivers/isdn/hisax/hfc_sx.c
+++ b/drivers/isdn/hisax/hfc_sx.c
@@ -308,7 +308,7 @@ read_fifo(struct IsdnCardState *cs, u_ch
 /******************************************/
 /* free hardware resources used by driver */
 /******************************************/
-void
+static void
 release_io_hfcsx(struct IsdnCardState *cs)
 {
 	cs->hw.hfcsx.int_m2 = 0;	/* interrupt output off ! */
@@ -472,7 +472,7 @@ receive_dmsg(struct IsdnCardState *cs)
 /**********************************/
 /* B-channel main receive routine */
 /**********************************/
-void
+static void
 main_rec_hfcsx(struct BCState *bcs)
 {
 	struct IsdnCardState *cs = bcs->cs;
@@ -1003,7 +1003,7 @@ HFCSX_l1hw(struct PStack *st, int pr, vo
 /***********************************************/
 /* called during init setting l1 stack pointer */
 /***********************************************/
-void
+static void
 setstack_hfcsx(struct PStack *st, struct IsdnCardState *cs)
 {
 	st->l1.l1hw = HFCSX_l1hw;
@@ -1027,7 +1027,7 @@ hfcsx_send_data(struct BCState *bcs)
 /***************************************************************/
 /* activate/deactivate hardware for selected channels and mode */
 /***************************************************************/
-void
+static void
 mode_hfcsx(struct BCState *bcs, int mode, int bc)
 {
 	struct IsdnCardState *cs = bcs->cs;
@@ -1328,7 +1328,7 @@ hfcsx_bh(struct IsdnCardState *cs)
 /********************************/
 /* called for card init message */
 /********************************/
-void __devinit
+static void __devinit
 inithfcsx(struct IsdnCardState *cs)
 {
 	cs->setstack_d = setstack_hfcsx;
diff --git a/drivers/isdn/hisax/hfc_sx.h b/drivers/isdn/hisax/hfc_sx.h
--- a/drivers/isdn/hisax/hfc_sx.h
+++ b/drivers/isdn/hisax/hfc_sx.h
@@ -193,5 +193,4 @@ struct hfcsx_extra {
 };
 
 extern void main_irq_hfcsx(struct BCState *bcs);
-extern void inithfcsx(struct IsdnCardState *cs);
 extern void releasehfcsx(struct IsdnCardState *cs);
diff --git a/drivers/isdn/hisax/hfc_usb.c b/drivers/isdn/hisax/hfc_usb.c
--- a/drivers/isdn/hisax/hfc_usb.c
+++ b/drivers/isdn/hisax/hfc_usb.c
@@ -60,7 +60,7 @@ static const char *hfcusb_revision =
 #include "hisax_debug.h"
 static u_int debug;
 module_param(debug, uint, 0);
-int hfc_debug;
+static int hfc_debug;
 #endif
 
 
@@ -85,7 +85,7 @@ static struct usb_device_id hfc_usb_idta
 *   VendorID, ProductID, Devicename, LED_SCHEME,
 *   LED's BitMask in HFCUSB_P_DATA Register : LED_USB, LED_S0, LED_B1, LED_B2
 */
-vendor_data vdata[] = {
+static vendor_data vdata[] = {
 	/* CologneChip Eval TA */
 	{0x0959, 0x2bd0, "ISDN USB TA (Cologne Chip HFC-S USB based)",
 	 LED_OFF, {4, 0, 2, 1}
@@ -1137,7 +1137,7 @@ set_hfcmode(hfcusb_data * hfc, int chann
 	}
 }
 
-void
+static void
 hfc_usb_l2l1(struct hisax_if *my_hisax_if, int pr, void *arg)
 {
 	usb_fifo *fifo = my_hisax_if->priv;
diff --git a/drivers/isdn/hisax/hfc_usb.h b/drivers/isdn/hisax/hfc_usb.h
--- a/drivers/isdn/hisax/hfc_usb.h
+++ b/drivers/isdn/hisax/hfc_usb.h
@@ -168,7 +168,7 @@ static struct hfcusb_symbolic_list urb_e
 * 3 entries are the configuration number, the minimum interval for
 * Interrupt endpoints & boolean if E-channel logging possible
 */
-int validconf[][19] = {
+static int validconf[][19] = {
 	// INT in, ISO out config
 	{EP_NUL, EP_INT, EP_NUL, EP_INT, EP_NUL, EP_INT, EP_NOP, EP_INT,
 	 EP_ISO, EP_NUL, EP_ISO, EP_NUL, EP_ISO, EP_NUL, EP_NUL, EP_NUL,
@@ -187,7 +187,7 @@ int validconf[][19] = {
 };
 
 // string description of chosen config
-char *conf_str[] = {
+static char *conf_str[] = {
 	"4 Interrupt IN + 3 Isochron OUT",
 	"3 Interrupt IN + 3 Isochron OUT",
 	"4 Isochron IN + 3 Isochron OUT",
diff --git a/drivers/isdn/hisax/hfcscard.c b/drivers/isdn/hisax/hfcscard.c
--- a/drivers/isdn/hisax/hfcscard.c
+++ b/drivers/isdn/hisax/hfcscard.c
@@ -52,7 +52,7 @@ hfcs_Timer(struct IsdnCardState *cs)
 */
 }
 
-void
+static void
 release_io_hfcs(struct IsdnCardState *cs)
 {
 	release2bds0(cs);
diff --git a/drivers/isdn/hisax/hisax.h b/drivers/isdn/hisax/hisax.h
--- a/drivers/isdn/hisax/hisax.h
+++ b/drivers/isdn/hisax/hisax.h
@@ -1271,7 +1271,6 @@ extern void Logl2Frame(struct IsdnCardSt
 void init_bcstate(struct IsdnCardState *cs, int bc);
 
 void setstack_HiSax(struct PStack *st, struct IsdnCardState *cs);
-unsigned int random_ri(void);
 void HiSax_addlist(struct IsdnCardState *sp, struct PStack *st);
 void HiSax_rmlist(struct IsdnCardState *sp, struct PStack *st);
 
@@ -1315,15 +1314,11 @@ int QuickHex(char *txt, u_char * p, int 
 void LogFrame(struct IsdnCardState *cs, u_char * p, int size);
 void dlogframe(struct IsdnCardState *cs, struct sk_buff *skb, int dir);
 void iecpy(u_char * dest, u_char * iestart, int ieoffset);
-#ifdef ISDN_CHIP_ISAC
-void setstack_isac(struct PStack *st, struct IsdnCardState *cs);
-#endif	/* ISDN_CHIP_ISAC */
 #endif	/* __KERNEL__ */
 
 #define HZDELAY(jiffs) {int tout = jiffs; while (tout--) udelay(1000000/HZ);}
 
 int ll_run(struct IsdnCardState *cs, int addfeatures);
-void ll_stop(struct IsdnCardState *cs);
 int CallcNew(void);
 void CallcFree(void);
 int CallcNewChan(struct IsdnCardState *cs);
diff --git a/drivers/isdn/hisax/hscx.c b/drivers/isdn/hisax/hscx.c
--- a/drivers/isdn/hisax/hscx.c
+++ b/drivers/isdn/hisax/hscx.c
@@ -151,7 +151,7 @@ hscx_l2l1(struct PStack *st, int pr, voi
 	}
 }
 
-void
+static void
 close_hscxstate(struct BCState *bcs)
 {
 	modehscx(bcs, 0, bcs->channel);
@@ -203,7 +203,7 @@ open_hscxstate(struct IsdnCardState *cs,
 	return (0);
 }
 
-int
+static int
 setstack_hscx(struct PStack *st, struct BCState *bcs)
 {
 	bcs->channel = st->l1.bc;
diff --git a/drivers/isdn/hisax/icc.c b/drivers/isdn/hisax/icc.c
--- a/drivers/isdn/hisax/icc.c
+++ b/drivers/isdn/hisax/icc.c
@@ -108,7 +108,7 @@ icc_bh(struct IsdnCardState *cs)
 #endif
 }
 
-void
+static void
 icc_empty_fifo(struct IsdnCardState *cs, int count)
 {
 	u_char *ptr;
@@ -563,13 +563,13 @@ ICC_l1hw(struct PStack *st, int pr, void
 	}
 }
 
-void
+static void
 setstack_icc(struct PStack *st, struct IsdnCardState *cs)
 {
 	st->l1.l1hw = ICC_l1hw;
 }
 
-void 
+static void
 DC_Close_icc(struct IsdnCardState *cs) {
 	if (cs->dc.icc.mon_rx) {
 		kfree(cs->dc.icc.mon_rx);
diff --git a/drivers/isdn/hisax/ipacx.c b/drivers/isdn/hisax/ipacx.c
--- a/drivers/isdn/hisax/ipacx.c
+++ b/drivers/isdn/hisax/ipacx.c
@@ -36,8 +36,6 @@ static void ph_command(struct IsdnCardSt
 static inline void cic_int(struct IsdnCardState *cs);
 static void dch_l2l1(struct PStack *st, int pr, void *arg);
 static void dbusy_timer_handler(struct IsdnCardState *cs);
-static void ipacx_new_ph(struct IsdnCardState *cs);
-static void dch_bh(struct IsdnCardState *cs);
 static void dch_empty_fifo(struct IsdnCardState *cs, int count);
 static void dch_fill_fifo(struct IsdnCardState *cs);
 static inline void dch_int(struct IsdnCardState *cs);
@@ -232,81 +230,6 @@ dbusy_timer_handler(struct IsdnCardState
 }
 
 //----------------------------------------------------------
-// L1 state machine intermediate layer to isdnl1 module
-//----------------------------------------------------------
-static void
-ipacx_new_ph(struct IsdnCardState *cs)
-{
-	switch (cs->dc.isac.ph_state) {
-		case (IPACX_IND_RES):
-			ph_command(cs, IPACX_CMD_DI);
-			l1_msg(cs, HW_RESET | INDICATION, NULL);
-			break;
-      
-		case (IPACX_IND_DC):
-			l1_msg(cs, HW_DEACTIVATE | CONFIRM, NULL);
-			break;
-      
-		case (IPACX_IND_DR):
-			l1_msg(cs, HW_DEACTIVATE | INDICATION, NULL);
-			break;
-      
-		case (IPACX_IND_PU):
-			l1_msg(cs, HW_POWERUP | CONFIRM, NULL);
-			break;
-
-		case (IPACX_IND_RSY):
-			l1_msg(cs, HW_RSYNC | INDICATION, NULL);
-			break;
-
-		case (IPACX_IND_AR):
-			l1_msg(cs, HW_INFO2 | INDICATION, NULL);
-			break;
-      
-		case (IPACX_IND_AI8):
-			l1_msg(cs, HW_INFO4_P8 | INDICATION, NULL);
-			break;
-      
-		case (IPACX_IND_AI10):
-			l1_msg(cs, HW_INFO4_P10 | INDICATION, NULL);
-			break;
-      
-		default:
-			break;
-	}
-}
-
-//----------------------------------------------------------
-// bottom half handler for D channel
-//----------------------------------------------------------
-static void
-dch_bh(struct IsdnCardState *cs)
-{
-	struct PStack *st;
-	
-	if (!cs) return;
-  
-	if (test_and_clear_bit(D_CLEARBUSY, &cs->event)) {
-		if (cs->debug) debugl1(cs, "D-Channel Busy cleared");
-		for (st = cs->stlist; st; st = st->next) {
-			st->l1.l1l2(st, PH_PAUSE | CONFIRM, NULL);
-		}
-	}
-  
-	if (test_and_clear_bit(D_RCVBUFREADY, &cs->event)) {
-		DChannel_proc_rcv(cs);
-  }  
-  
-	if (test_and_clear_bit(D_XMTBUFREADY, &cs->event)) {
-		DChannel_proc_xmt(cs);
-  }  
-  
-	if (test_and_clear_bit(D_L1STATECHANGE, &cs->event)) {
-    ipacx_new_ph(cs);
-  }  
-}
-
-//----------------------------------------------------------
 // Fill buffer from receive FIFO
 //----------------------------------------------------------
 static void 
@@ -991,14 +914,5 @@ init_ipacx(struct IsdnCardState *cs, int
 	}
 }
 
-
-void __devinit
-setup_ipacx(struct IsdnCardState *cs)
-{
-	INIT_WORK(&cs->tqueue, (void *)(void *) dch_bh, cs);
-	cs->dbusytimer.function = (void *) dbusy_timer_handler;
-	cs->dbusytimer.data = (long) cs;
-	init_timer(&cs->dbusytimer);
-}
 //----------------- end of file -----------------------
 
diff --git a/drivers/isdn/hisax/isac.c b/drivers/isdn/hisax/isac.c
--- a/drivers/isdn/hisax/isac.c
+++ b/drivers/isdn/hisax/isac.c
@@ -112,7 +112,7 @@ isac_bh(struct IsdnCardState *cs)
 #endif
 }
 
-void
+static void
 isac_empty_fifo(struct IsdnCardState *cs, int count)
 {
 	u_char *ptr;
@@ -563,13 +563,13 @@ ISAC_l1hw(struct PStack *st, int pr, voi
 	}
 }
 
-void
+static void
 setstack_isac(struct PStack *st, struct IsdnCardState *cs)
 {
 	st->l1.l1hw = ISAC_l1hw;
 }
 
-void 
+static void
 DC_Close_isac(struct IsdnCardState *cs) {
 	if (cs->dc.isac.mon_rx) {
 		kfree(cs->dc.isac.mon_rx);
diff --git a/drivers/isdn/hisax/isar.c b/drivers/isdn/hisax/isar.c
--- a/drivers/isdn/hisax/isar.c
+++ b/drivers/isdn/hisax/isar.c
@@ -21,13 +21,13 @@
 #define ETX	0x03
 
 #define FAXMODCNT	13
-const	u_char	faxmodulation[] = {3,24,48,72,73,74,96,97,98,121,122,145,146};
+static const	u_char	faxmodulation[] = {3,24,48,72,73,74,96,97,98,121,122,145,146};
 static	u_int	modmask = 0x1fff;
 static	int	frm_extra_delay = 2;
 static	int	para_TOA = 6;
-const   u_char  *FC1_CMD[] = {"FAE", "FTS", "FRS", "FTM", "FRM", "FTH", "FRH", "CTRL" };
+static const   u_char  *FC1_CMD[] = {"FAE", "FTS", "FRS", "FTM", "FRM", "FTH", "FRH", "CTRL" };
 
-void isar_setup(struct IsdnCardState *cs);
+static void isar_setup(struct IsdnCardState *cs);
 static void isar_pump_cmd(struct BCState *bcs, u_char cmd, u_char para);
 static void ll_deliver_faxstat(struct BCState *bcs, u_char status);
 
@@ -45,7 +45,7 @@ waitforHIA(struct IsdnCardState *cs, int
 }
 
 
-int
+static int
 sendmsg(struct IsdnCardState *cs, u_char his, u_char creg, u_char len,
 	u_char *msg)
 {
@@ -85,7 +85,7 @@ sendmsg(struct IsdnCardState *cs, u_char
 }
 
 /* Call only with IRQ disabled !!! */
-inline void
+static inline void
 rcv_mbox(struct IsdnCardState *cs, struct isar_reg *ireg, u_char *msg)
 {
 	int i;
@@ -114,7 +114,7 @@ rcv_mbox(struct IsdnCardState *cs, struc
 }
 
 /* Call only with IRQ disabled !!! */
-inline void
+static inline void
 get_irq_infos(struct IsdnCardState *cs, struct isar_reg *ireg)
 {
 	ireg->iis = cs->BC_Read_Reg(cs, 1, ISAR_IIS);
@@ -127,7 +127,7 @@ get_irq_infos(struct IsdnCardState *cs, 
 #endif
 }
 
-int
+static int
 waitrecmsg(struct IsdnCardState *cs, u_char *len,
 	u_char *msg, int maxdelay)
 {
@@ -185,7 +185,7 @@ ISARVersion(struct IsdnCardState *cs, ch
 	return(ver);
 }
 
-int
+static int
 isar_load_firmware(struct IsdnCardState *cs, u_char __user *buf)
 {
 	int ret, size, cnt, debug;
@@ -739,7 +739,7 @@ isar_fill_fifo(struct BCState *bcs)
 	}
 }
 
-inline
+static inline
 struct BCState *sel_bcs_isar(struct IsdnCardState *cs, u_char dpath)
 {
 	if ((!dpath) || (dpath == 3))
@@ -751,7 +751,7 @@ struct BCState *sel_bcs_isar(struct Isdn
 	return(NULL);
 }
 
-void
+static void
 send_frames(struct BCState *bcs)
 {
 	if (bcs->tx_skb) {
@@ -806,7 +806,7 @@ send_frames(struct BCState *bcs)
 	}
 }
 
-inline void
+static inline void
 check_send(struct IsdnCardState *cs, u_char rdm)
 {
 	struct BCState *bcs;
@@ -828,11 +828,13 @@ check_send(struct IsdnCardState *cs, u_c
 	
 }
 
-const char *dmril[] = {"NO SPEED", "1200/75", "NODEF2", "75/1200", "NODEF4",
-			"300", "600", "1200", "2400", "4800", "7200",
-			"9600nt", "9600t", "12000", "14400", "WRONG"};
-const char *dmrim[] = {"NO MOD", "NO DEF", "V32/V32b", "V22", "V21",
-			"Bell103", "V23", "Bell202", "V17", "V29", "V27ter"};
+static const char *dmril[] = {"NO SPEED", "1200/75", "NODEF2", "75/1200",
+				"NODEF4", "300", "600", "1200", "2400",
+				"4800", "7200", "9600nt", "9600t", "12000",
+				"14400", "WRONG"};
+static const char *dmrim[] = {"NO MOD", "NO DEF", "V32/V32b", "V22", "V21",
+				"Bell103", "V23", "Bell202", "V17", "V29",
+				"V27ter"};
 
 static void
 isar_pump_status_rsp(struct BCState *bcs, struct isar_reg *ireg) {
@@ -1388,7 +1390,7 @@ setup_iom2(struct BCState *bcs) {
 	udelay(1000);
 }
 
-int
+static int
 modeisar(struct BCState *bcs, int mode, int bc)
 {
 	struct IsdnCardState *cs = bcs->cs;
@@ -1562,7 +1564,7 @@ isar_pump_cmd(struct BCState *bcs, u_cha
 		sendmsg(cs, dps | ISAR_HIS_PUMPCTRL, ctrl, nom, &p1);
 }
 
-void
+static void
 isar_setup(struct IsdnCardState *cs)
 {
 	u_char msg;
@@ -1582,7 +1584,7 @@ isar_setup(struct IsdnCardState *cs)
 	}
 }
 
-void
+static void
 isar_l2l1(struct PStack *st, int pr, void *arg)
 {
 	struct BCState *bcs = st->l1.bcs;
@@ -1681,7 +1683,7 @@ isar_l2l1(struct PStack *st, int pr, voi
 	}
 }
 
-void
+static void
 close_isarstate(struct BCState *bcs)
 {
 	modeisar(bcs, 0, bcs->channel);
@@ -1703,7 +1705,7 @@ close_isarstate(struct BCState *bcs)
 	del_timer(&bcs->hw.isar.ftimer);
 }
 
-int
+static int
 open_isarstate(struct IsdnCardState *cs, struct BCState *bcs)
 {
 	if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) {
@@ -1725,7 +1727,7 @@ open_isarstate(struct IsdnCardState *cs,
 	return (0);
 }
 
-int
+static int
 setstack_isar(struct PStack *st, struct BCState *bcs)
 {
 	bcs->channel = st->l1.bc;
diff --git a/drivers/isdn/hisax/isdnl1.c b/drivers/isdn/hisax/isdnl1.c
--- a/drivers/isdn/hisax/isdnl1.c
+++ b/drivers/isdn/hisax/isdnl1.c
@@ -151,7 +151,7 @@ l1m_debug(struct FsmInst *fi, char *fmt,
 	va_end(args);
 }
 
-void
+static void
 L1activated(struct IsdnCardState *cs)
 {
 	struct PStack *st;
@@ -166,7 +166,7 @@ L1activated(struct IsdnCardState *cs)
 	}
 }
 
-void
+static void
 L1deactivated(struct IsdnCardState *cs)
 {
 	struct PStack *st;
@@ -279,7 +279,8 @@ BChannel_proc_xmt(struct BCState *bcs)
 	if (test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags))
 		st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
 	if (!test_bit(BC_FLG_ACTIV, &bcs->Flag)) {
-		if (!test_bit(BC_FLG_BUSY, &bcs->Flag) && (!skb_queue_len(&bcs->squeue))) {
+		if (!test_bit(BC_FLG_BUSY, &bcs->Flag) &&
+		    skb_queue_empty(&bcs->squeue)) {
 			st->l2.l2l1(st, PH_DEACTIVATE | CONFIRM, NULL);
 		}
 	}
@@ -370,7 +371,7 @@ init_bcstate(struct IsdnCardState *cs, i
 
 #ifdef L2FRAME_DEBUG		/* psa */
 
-char *
+static char *
 l2cmd(u_char cmd)
 {
 	switch (cmd & ~0x10) {
@@ -404,7 +405,7 @@ l2cmd(u_char cmd)
 
 static char tmpdeb[32];
 
-char *
+static char *
 l2frames(u_char * ptr)
 {
 	switch (ptr[2] & ~0x10) {
diff --git a/drivers/isdn/hisax/isdnl2.c b/drivers/isdn/hisax/isdnl2.c
--- a/drivers/isdn/hisax/isdnl2.c
+++ b/drivers/isdn/hisax/isdnl2.c
@@ -108,7 +108,8 @@ static int l2addrsize(struct Layer2 *l2)
 static void
 set_peer_busy(struct Layer2 *l2) {
 	test_and_set_bit(FLG_PEER_BUSY, &l2->flag);
-	if (skb_queue_len(&l2->i_queue) || skb_queue_len(&l2->ui_queue))
+	if (!skb_queue_empty(&l2->i_queue) ||
+	    !skb_queue_empty(&l2->ui_queue))
 		test_and_set_bit(FLG_L2BLOCK, &l2->flag);
 }
 
@@ -142,7 +143,7 @@ freewin1(struct Layer2 *l2)
 	return cnt;
 }
 
-inline void
+static inline void
 freewin(struct PStack *st)
 {
 	freewin1(&st->l2);
@@ -157,7 +158,7 @@ ReleaseWin(struct Layer2 *l2)
 		printk(KERN_WARNING "isdl2 freed %d skbuffs in release\n", cnt);
 }
 
-inline unsigned int
+static inline unsigned int
 cansend(struct PStack *st)
 {
 	unsigned int p1;
@@ -169,7 +170,7 @@ cansend(struct PStack *st)
 	return ((p1 < st->l2.window) && !test_bit(FLG_PEER_BUSY, &st->l2.flag));
 }
 
-inline void
+static inline void
 clear_exception(struct Layer2 *l2)
 {
 	test_and_clear_bit(FLG_ACK_PEND, &l2->flag);
@@ -178,7 +179,7 @@ clear_exception(struct Layer2 *l2)
 	clear_peer_busy(l2);
 }
 
-inline int
+static inline int
 l2headersize(struct Layer2 *l2, int ui)
 {
 	return (((test_bit(FLG_MOD128, &l2->flag) && (!ui)) ? 2 : 1) +
@@ -212,7 +213,7 @@ sethdraddr(struct Layer2 *l2, u_char * h
 	}
 }
 
-inline static void
+static inline void
 enqueue_super(struct PStack *st,
 	      struct sk_buff *skb)
 {
@@ -223,40 +224,31 @@ enqueue_super(struct PStack *st,
 
 #define enqueue_ui(a, b) enqueue_super(a, b)
 
-inline int
+static inline int
 IsUI(u_char * data)
 {
 	return ((data[0] & 0xef) == UI);
 }
 
-inline int
+static inline int
 IsUA(u_char * data)
 {
 	return ((data[0] & 0xef) == UA);
 }
 
-inline int
+static inline int
 IsDM(u_char * data)
 {
 	return ((data[0] & 0xef) == DM);
 }
 
-inline int
+static inline int
 IsDISC(u_char * data)
 {
 	return ((data[0] & 0xef) == DISC);
 }
 
-inline int
-IsRR(u_char * data, struct PStack *st)
-{
-	if (test_bit(FLG_MOD128, &st->l2.flag))
-		return (data[0] == RR);
-	else
-		return ((data[0] & 0xf) == 1);
-}
-
-inline int
+static inline int
 IsSFrame(u_char * data, struct PStack *st)
 {
 	register u_char d = *data;
@@ -266,7 +258,7 @@ IsSFrame(u_char * data, struct PStack *s
 	return(((d & 0xf3) == 1) && ((d & 0x0c) != 0x0c));
 }
 
-inline int
+static inline int
 IsSABME(u_char * data, struct PStack *st)
 {
 	u_char d = data[0] & ~0x10;
@@ -274,25 +266,25 @@ IsSABME(u_char * data, struct PStack *st
 	return (test_bit(FLG_MOD128, &st->l2.flag) ? d == SABME : d == SABM);
 }
 
-inline int
+static inline int
 IsREJ(u_char * data, struct PStack *st)
 {
 	return (test_bit(FLG_MOD128, &st->l2.flag) ? data[0] == REJ : (data[0] & 0xf) == REJ);
 }
 
-inline int
+static inline int
 IsFRMR(u_char * data)
 {
 	return ((data[0] & 0xef) == FRMR);
 }
 
-inline int
+static inline int
 IsRNR(u_char * data, struct PStack *st)
 {
 	return (test_bit(FLG_MOD128, &st->l2.flag) ? data[0] == RNR : (data[0] & 0xf) == RNR);
 }
 
-int
+static int
 iframe_error(struct PStack *st, struct sk_buff *skb)
 {
 	int i = l2addrsize(&st->l2) + (test_bit(FLG_MOD128, &st->l2.flag) ? 2 : 1);
@@ -315,7 +307,7 @@ iframe_error(struct PStack *st, struct s
 	return 0;
 }
 
-int
+static int
 super_error(struct PStack *st, struct sk_buff *skb)
 {
 	if (skb->len != l2addrsize(&st->l2) +
@@ -325,7 +317,7 @@ super_error(struct PStack *st, struct sk
 	return 0;
 }
 
-int
+static int
 unnum_error(struct PStack *st, struct sk_buff *skb, int wantrsp)
 {
 	int rsp = (*skb->data & 0x2) >> 1;
@@ -341,7 +333,7 @@ unnum_error(struct PStack *st, struct sk
 	return 0;
 }
 
-int
+static int
 UI_error(struct PStack *st, struct sk_buff *skb)
 {
 	int rsp = *skb->data & 0x2;
@@ -357,7 +349,7 @@ UI_error(struct PStack *st, struct sk_bu
 	return 0;
 }
 
-int
+static int
 FRMR_error(struct PStack *st, struct sk_buff *skb)
 {
 	int headers = l2addrsize(&st->l2) + 1;
@@ -444,51 +436,44 @@ send_uframe(struct PStack *st, u_char cm
 	enqueue_super(st, skb);
 }
 
-inline u_char
+static inline u_char
 get_PollFlag(struct PStack * st, struct sk_buff * skb)
 {
 	return (skb->data[l2addrsize(&(st->l2))] & 0x10);
 }
 
-inline void
-FreeSkb(struct sk_buff *skb)
-{
-	dev_kfree_skb(skb);
-}
-
-
-inline u_char
+static inline u_char
 get_PollFlagFree(struct PStack *st, struct sk_buff *skb)
 {
 	u_char PF;
 
 	PF = get_PollFlag(st, skb);
-	FreeSkb(skb);
+	dev_kfree_skb(skb);
 	return (PF);
 }
 
-inline void
+static inline void
 start_t200(struct PStack *st, int i)
 {
 	FsmAddTimer(&st->l2.t200, st->l2.T200, EV_L2_T200, NULL, i);
 	test_and_set_bit(FLG_T200_RUN, &st->l2.flag);
 }
 
-inline void
+static inline void
 restart_t200(struct PStack *st, int i)
 {
 	FsmRestartTimer(&st->l2.t200, st->l2.T200, EV_L2_T200, NULL, i);
 	test_and_set_bit(FLG_T200_RUN, &st->l2.flag);
 }
 
-inline void
+static inline void
 stop_t200(struct PStack *st, int i)
 {
 	if(test_and_clear_bit(FLG_T200_RUN, &st->l2.flag))
 		FsmDelTimer(&st->l2.t200, i);
 }
 
-inline void
+static inline void
 st5_dl_release_l2l3(struct PStack *st)
 {
 		int pr;
@@ -501,7 +486,7 @@ st5_dl_release_l2l3(struct PStack *st)
 		st->l2.l2l3(st, pr, NULL);
 }
 
-inline void
+static inline void
 lapb_dl_release_l2l3(struct PStack *st, int f)
 {
 		if (test_bit(FLG_LAPB, &st->l2.flag))
@@ -770,7 +755,7 @@ l2_restart_multi(struct FsmInst *fi, int
 		st->l2.l2l3(st, DL_ESTABLISH | INDICATION, NULL);
 
 	if ((ST_L2_7==state) || (ST_L2_8 == state))
-		if (skb_queue_len(&st->l2.i_queue) && cansend(st))
+		if (!skb_queue_empty(&st->l2.i_queue) && cansend(st))
 			st->l2.l2l1(st, PH_PULL | REQUEST, NULL);
 }
 
@@ -802,7 +787,7 @@ l2_connected(struct FsmInst *fi, int eve
 		l2_mdl_error_ua(fi, event, arg);
 		return;
 	}
-	FreeSkb(skb);
+	dev_kfree_skb(skb);
 
 	if (test_and_clear_bit(FLG_PEND_REL, &st->l2.flag))
 		l2_disconnect(fi, event, arg);
@@ -826,7 +811,7 @@ l2_connected(struct FsmInst *fi, int eve
 	if (pr != -1)
 		st->l2.l2l3(st, pr, NULL);
 
-	if (skb_queue_len(&st->l2.i_queue) && cansend(st))
+	if (!skb_queue_empty(&st->l2.i_queue) && cansend(st))
 		st->l2.l2l1(st, PH_PULL | REQUEST, NULL);
 }
 
@@ -840,7 +825,7 @@ l2_released(struct FsmInst *fi, int even
 		l2_mdl_error_ua(fi, event, arg);
 		return;
 	}
-	FreeSkb(skb);
+	dev_kfree_skb(skb);
 
 	stop_t200(st, 6);
 	lapb_dl_release_l2l3(st, CONFIRM);
@@ -889,7 +874,7 @@ l2_st6_dm_release(struct FsmInst *fi, in
 	}
 }
 
-inline void
+static inline void
 enquiry_cr(struct PStack *st, u_char typ, u_char cr, u_char pf)
 {
 	struct sk_buff *skb;
@@ -912,7 +897,7 @@ enquiry_cr(struct PStack *st, u_char typ
 	enqueue_super(st, skb);
 }
 
-inline void
+static inline void
 enquiry_response(struct PStack *st)
 {
 	if (test_bit(FLG_OWN_BUSY, &st->l2.flag))
@@ -922,7 +907,7 @@ enquiry_response(struct PStack *st)
 	test_and_clear_bit(FLG_ACK_PEND, &st->l2.flag);
 }
 
-inline void
+static inline void
 transmit_enquiry(struct PStack *st)
 {
 	if (test_bit(FLG_OWN_BUSY, &st->l2.flag))
@@ -1004,7 +989,7 @@ l2_st7_got_super(struct FsmInst *fi, int
 		PollFlag = (skb->data[0] & 0x10);
 		nr = (skb->data[0] >> 5) & 0x7;
 	}
-	FreeSkb(skb);
+	dev_kfree_skb(skb);
 
 	if (PollFlag) {
 		if (rsp)
@@ -1030,7 +1015,7 @@ l2_st7_got_super(struct FsmInst *fi, int
 			if(typ != RR) FsmDelTimer(&st->l2.t203, 9);
 			restart_t200(st, 12);
 		}
-		if (skb_queue_len(&st->l2.i_queue) && (typ == RR))
+		if (!skb_queue_empty(&st->l2.i_queue) && (typ == RR))
 			st->l2.l2l1(st, PH_PULL | REQUEST, NULL);
 	} else
 		nrerrorrecovery(fi);
@@ -1047,7 +1032,7 @@ l2_feed_i_if_reest(struct FsmInst *fi, i
 	if (!test_bit(FLG_L3_INIT, &st->l2.flag))
 		skb_queue_tail(&st->l2.i_queue, skb);
 	else
-		FreeSkb(skb);
+		dev_kfree_skb(skb);
 }
 
 static void
@@ -1093,7 +1078,7 @@ l2_got_iframe(struct FsmInst *fi, int ev
 		nr = (skb->data[i] >> 5) & 0x7;
 	}
 	if (test_bit(FLG_OWN_BUSY, &l2->flag)) {
-		FreeSkb(skb);
+		dev_kfree_skb(skb);
 		if(PollFlag) enquiry_response(st);
 	} else if (l2->vr == ns) {
 		(l2->vr)++;
@@ -1111,7 +1096,7 @@ l2_got_iframe(struct FsmInst *fi, int ev
 		st->l2.l2l3(st, DL_DATA | INDICATION, skb);
 	} else {
 		/* n(s)!=v(r) */
-		FreeSkb(skb);
+		dev_kfree_skb(skb);
 		if (test_and_set_bit(FLG_REJEXC, &l2->flag)) {
 			if (PollFlag)
 				enquiry_response(st);
@@ -1136,7 +1121,7 @@ l2_got_iframe(struct FsmInst *fi, int ev
 		return;
 	}
 
-	if (skb_queue_len(&st->l2.i_queue) && (fi->state == ST_L2_7))
+	if (!skb_queue_empty(&st->l2.i_queue) && (fi->state == ST_L2_7))
 		st->l2.l2l1(st, PH_PULL | REQUEST, NULL);
 	if (test_and_clear_bit(FLG_ACK_PEND, &st->l2.flag))
 		enquiry_cr(st, RR, RSP, 0);
@@ -1154,7 +1139,7 @@ l2_got_tei(struct FsmInst *fi, int event
 		test_and_set_bit(FLG_L3_INIT, &st->l2.flag);
 	} else
 		FsmChangeState(fi, ST_L2_4);
-	if (skb_queue_len(&st->l2.ui_queue))
+	if (!skb_queue_empty(&st->l2.ui_queue))
 		tx_ui(st);
 }
 
@@ -1309,7 +1294,7 @@ l2_pull_iqueue(struct FsmInst *fi, int e
 		skb = alloc_skb(oskb->len + i, GFP_ATOMIC);
 		memcpy(skb_put(skb, i), header, i);
 		memcpy(skb_put(skb, oskb->len), oskb->data, oskb->len);
-		FreeSkb(oskb);
+		dev_kfree_skb(oskb);
 	}
 	st->l2.l2l1(st, PH_PULL | INDICATION, skb);
 	test_and_clear_bit(FLG_ACK_PEND, &st->l2.flag);
@@ -1317,7 +1302,7 @@ l2_pull_iqueue(struct FsmInst *fi, int e
 		FsmDelTimer(&st->l2.t203, 13);
 		FsmAddTimer(&st->l2.t200, st->l2.T200, EV_L2_T200, NULL, 11);
 	}
-	if (skb_queue_len(&l2->i_queue) && cansend(st))
+	if (!skb_queue_empty(&l2->i_queue) && cansend(st))
 		st->l2.l2l1(st, PH_PULL | REQUEST, NULL);
 }
 
@@ -1349,7 +1334,7 @@ l2_st8_got_super(struct FsmInst *fi, int
 		PollFlag = (skb->data[0] & 0x10);
 		nr = (skb->data[0] >> 5) & 0x7;
 	}
-	FreeSkb(skb);
+	dev_kfree_skb(skb);
 
 	if (rsp && PollFlag) {
 		if (legalnr(st, nr)) {
@@ -1363,7 +1348,7 @@ l2_st8_got_super(struct FsmInst *fi, int
 			}
 			invoke_retransmission(st, nr);
 			FsmChangeState(fi, ST_L2_7);
-			if (skb_queue_len(&l2->i_queue) && cansend(st))
+			if (!skb_queue_empty(&l2->i_queue) && cansend(st))
 				st->l2.l2l1(st, PH_PULL | REQUEST, NULL);
 		} else
 			nrerrorrecovery(fi);
@@ -1391,7 +1376,7 @@ l2_got_FRMR(struct FsmInst *fi, int even
 		establishlink(fi);
 		test_and_clear_bit(FLG_L3_INIT, &st->l2.flag);
 	}
-	FreeSkb(skb);
+	dev_kfree_skb(skb);
 }
 
 static void
@@ -1655,7 +1640,7 @@ isdnl2_l1l2(struct PStack *st, int pr, v
 				datap += len;
 			else {
 				FsmEvent(&st->l2.l2m, EV_L2_FRAME_ERROR, (void *) 'N');
-				FreeSkb(skb);
+				dev_kfree_skb(skb);
 				return;
 			}
 			if (!(*datap & 1)) {	/* I-Frame */
@@ -1684,16 +1669,16 @@ isdnl2_l1l2(struct PStack *st, int pr, v
 					ret = FsmEvent(&st->l2.l2m, EV_L2_FRMR, skb);
 			} else {
 				FsmEvent(&st->l2.l2m, EV_L2_FRAME_ERROR, (void *) 'L');
-				FreeSkb(skb);
+				dev_kfree_skb(skb);
 				ret = 0;
 			}
 			if(c) {
-				FreeSkb(skb);
+				dev_kfree_skb(skb);
 				FsmEvent(&st->l2.l2m, EV_L2_FRAME_ERROR, (void *)(long)c);
 				ret = 0;
 			}
 			if (ret)
-				FreeSkb(skb);
+				dev_kfree_skb(skb);
 			break;
 		case (PH_PULL | CONFIRM):
 			FsmEvent(&st->l2.l2m, EV_L2_ACK_PULL, arg);
diff --git a/drivers/isdn/hisax/isdnl3.c b/drivers/isdn/hisax/isdnl3.c
--- a/drivers/isdn/hisax/isdnl3.c
+++ b/drivers/isdn/hisax/isdnl3.c
@@ -302,7 +302,7 @@ release_l3_process(struct l3_process *p)
 				!test_bit(FLG_PTP, &p->st->l2.flag)) {
 				if (p->debug)
 					l3_debug(p->st, "release_l3_process: last process");
-				if (!skb_queue_len(&p->st->l3.squeue)) {
+				if (skb_queue_empty(&p->st->l3.squeue)) {
 					if (p->debug)
 						l3_debug(p->st, "release_l3_process: release link");
 					if (p->st->protocol != ISDN_PTYPE_NI1)
@@ -390,7 +390,7 @@ setstack_l3dc(struct PStack *st, struct 
 	}
 }
 
-void
+static void
 isdnl3_trans(struct PStack *st, int pr, void *arg) {
 	st->l3.l3l2(st, pr, arg);
 }
diff --git a/drivers/isdn/hisax/isurf.c b/drivers/isdn/hisax/isurf.c
--- a/drivers/isdn/hisax/isurf.c
+++ b/drivers/isdn/hisax/isurf.c
@@ -122,7 +122,7 @@ isurf_interrupt(int intno, void *dev_id,
 	return IRQ_HANDLED;
 }
 
-void
+static void
 release_io_isurf(struct IsdnCardState *cs)
 {
 	release_region(cs->hw.isurf.reset, 1);
diff --git a/drivers/isdn/hisax/ix1_micro.c b/drivers/isdn/hisax/ix1_micro.c
--- a/drivers/isdn/hisax/ix1_micro.c
+++ b/drivers/isdn/hisax/ix1_micro.c
@@ -25,7 +25,7 @@
 #include "isdnl1.h"
 
 extern const char *CardType[];
-const char *ix1_revision = "$Revision: 2.12.2.4 $";
+static const char *ix1_revision = "$Revision: 2.12.2.4 $";
 
 #define byteout(addr,val) outb(val,addr)
 #define bytein(addr) inb(addr)
@@ -162,7 +162,7 @@ ix1micro_interrupt(int intno, void *dev_
 	return IRQ_HANDLED;
 }
 
-void
+static void
 release_io_ix1micro(struct IsdnCardState *cs)
 {
 	if (cs->hw.ix1.cfg_reg)
diff --git a/drivers/isdn/hisax/jade.c b/drivers/isdn/hisax/jade.c
--- a/drivers/isdn/hisax/jade.c
+++ b/drivers/isdn/hisax/jade.c
@@ -74,7 +74,7 @@ jade_write_indirect(struct IsdnCardState
 
 
 
-void
+static void
 modejade(struct BCState *bcs, int mode, int bc)
 {
     struct IsdnCardState *cs = bcs->cs;
@@ -190,7 +190,7 @@ jade_l2l1(struct PStack *st, int pr, voi
     }
 }
 
-void
+static void
 close_jadestate(struct BCState *bcs)
 {
     modejade(bcs, 0, bcs->channel);
@@ -243,7 +243,7 @@ open_jadestate(struct IsdnCardState *cs,
 }
 
 
-int
+static int
 setstack_jade(struct PStack *st, struct BCState *bcs)
 {
 	bcs->channel = st->l1.bc;
diff --git a/drivers/isdn/hisax/jade.h b/drivers/isdn/hisax/jade.h
--- a/drivers/isdn/hisax/jade.h
+++ b/drivers/isdn/hisax/jade.h
@@ -128,7 +128,6 @@
 #define	jade_TXAUDIOCH2CFG				0x1A
 
 extern int JadeVersion(struct IsdnCardState *cs, char *s);
-extern void modejade(struct BCState *bcs, int mode, int bc);
 extern void clear_pending_jade_ints(struct IsdnCardState *cs);
 extern void initjade(struct IsdnCardState *cs);
 
diff --git a/drivers/isdn/hisax/l3_1tr6.c b/drivers/isdn/hisax/l3_1tr6.c
--- a/drivers/isdn/hisax/l3_1tr6.c
+++ b/drivers/isdn/hisax/l3_1tr6.c
@@ -19,7 +19,7 @@
 #include <linux/ctype.h>
 
 extern char *HiSax_getrev(const char *revision);
-const char *l3_1tr6_revision = "$Revision: 2.15.2.3 $";
+static const char *l3_1tr6_revision = "$Revision: 2.15.2.3 $";
 
 #define MsgHead(ptr, cref, mty, dis) \
 	*ptr++ = dis; \
diff --git a/drivers/isdn/hisax/l3dss1.c b/drivers/isdn/hisax/l3dss1.c
--- a/drivers/isdn/hisax/l3dss1.c
+++ b/drivers/isdn/hisax/l3dss1.c
@@ -26,7 +26,7 @@
 #include <linux/config.h>
 
 extern char *HiSax_getrev(const char *revision);
-const char *dss1_revision = "$Revision: 2.32.2.3 $";
+static const char *dss1_revision = "$Revision: 2.32.2.3 $";
 
 #define EXT_BEARER_CAPS 1
 
@@ -353,7 +353,7 @@ l3dss1_parse_facility(struct PStack *st,
 			         { l3dss1_dummy_invoke(st, cr, id, ident, p, nlen);
                                    return;
                                  } 
-#if HISAX_DE_AOC
+#ifdef HISAX_DE_AOC
 			{
 
 #define FOO1(s,a,b) \
@@ -977,7 +977,7 @@ l3dss1_release_cmpl(struct l3_process *p
 	dss1_release_l3_process(pc);
 }
 
-#if EXT_BEARER_CAPS
+#ifdef EXT_BEARER_CAPS
 
 static u_char *
 EncodeASyncParams(u_char * p, u_char si2)
@@ -1369,7 +1369,7 @@ l3dss1_setup_req(struct l3_process *pc, 
 				*p++ = *sub++ & 0x7f;
 		}
         }
-#if EXT_BEARER_CAPS
+#ifdef EXT_BEARER_CAPS
 	if ((pc->para.setup.si2 >= 160) && (pc->para.setup.si2 <= 175)) {	// sync. Bitratenadaption, V.110/X.30
 
 		*p++ = IE_LLC;
@@ -1609,7 +1609,7 @@ l3dss1_setup(struct l3_process *pc, u_ch
 				case 0x08: /* Unrestricted digital information */
 					pc->para.setup.si1 = 7;
 /* JIM, 05.11.97 I wanna set service indicator 2 */
-#if EXT_BEARER_CAPS
+#ifdef EXT_BEARER_CAPS
 					pc->para.setup.si2 = DecodeSI2(skb);
 #endif
 					break;
diff --git a/drivers/isdn/hisax/l3ni1.c b/drivers/isdn/hisax/l3ni1.c
--- a/drivers/isdn/hisax/l3ni1.c
+++ b/drivers/isdn/hisax/l3ni1.c
@@ -24,7 +24,7 @@
 #include <linux/ctype.h>
 
 extern char *HiSax_getrev(const char *revision);
-const char *ni1_revision = "$Revision: 2.8.2.3 $";
+static const char *ni1_revision = "$Revision: 2.8.2.3 $";
 
 #define EXT_BEARER_CAPS 1
 
@@ -2665,7 +2665,7 @@ static void l3ni1_spid_send( struct l3_p
 	l3ni1_SendSpid( pc, pr, arg, 20 );
 }
 
-void l3ni1_spid_epid( struct l3_process *pc, u_char pr, void *arg )
+static void l3ni1_spid_epid( struct l3_process *pc, u_char pr, void *arg )
 {
 	struct sk_buff *skb = arg;
 
diff --git a/drivers/isdn/hisax/mic.c b/drivers/isdn/hisax/mic.c
--- a/drivers/isdn/hisax/mic.c
+++ b/drivers/isdn/hisax/mic.c
@@ -18,7 +18,7 @@
 
 extern const char *CardType[];
 
-const char *mic_revision = "$Revision: 1.12.2.4 $";
+static const char *mic_revision = "$Revision: 1.12.2.4 $";
 
 #define byteout(addr,val) outb(val,addr)
 #define bytein(addr) inb(addr)
@@ -157,7 +157,7 @@ mic_interrupt(int intno, void *dev_id, s
 	return IRQ_HANDLED;
 }
 
-void
+static void
 release_io_mic(struct IsdnCardState *cs)
 {
 	int bytecnt = 8;
diff --git a/drivers/isdn/hisax/netjet.c b/drivers/isdn/hisax/netjet.c
--- a/drivers/isdn/hisax/netjet.c
+++ b/drivers/isdn/hisax/netjet.c
@@ -25,8 +25,6 @@
 #include <asm/io.h>
 #include "netjet.h"
 
-const char *NETjet_revision = "$Revision: 1.29.2.4 $";
-
 /* Interface functions */
 
 u_char
@@ -66,7 +64,7 @@ NETjet_WriteICfifo(struct IsdnCardState 
 	outsb(cs->hw.njet.isac, data, size);
 }
 
-void fill_mem(struct BCState *bcs, u_int *pos, u_int cnt, int chan, u_char fill)
+static void fill_mem(struct BCState *bcs, u_int *pos, u_int cnt, int chan, u_char fill)
 {
 	u_int mask=0x000000ff, val = 0, *p=pos;
 	u_int i;
@@ -85,7 +83,7 @@ void fill_mem(struct BCState *bcs, u_int
 	}
 }
 
-void
+static void
 mode_tiger(struct BCState *bcs, int mode, int bc)
 {
 	struct IsdnCardState *cs = bcs->cs;
@@ -852,7 +850,7 @@ tiger_l2l1(struct PStack *st, int pr, vo
 }
 
 
-void
+static void
 close_tigerstate(struct BCState *bcs)
 {
 	mode_tiger(bcs, 0, bcs->channel);
@@ -900,7 +898,7 @@ open_tigerstate(struct IsdnCardState *cs
 	return (0);
 }
 
-int
+static int
 setstack_tiger(struct PStack *st, struct BCState *bcs)
 {
 	bcs->channel = st->l1.bc;
@@ -966,7 +964,7 @@ inittiger(struct IsdnCardState *cs)
 	cs->bcs[1].BC_Close = close_tigerstate;
 }
 
-void
+static void
 releasetiger(struct IsdnCardState *cs)
 {
 	if (cs->bcs[0].hw.tiger.send) {
diff --git a/drivers/isdn/hisax/niccy.c b/drivers/isdn/hisax/niccy.c
--- a/drivers/isdn/hisax/niccy.c
+++ b/drivers/isdn/hisax/niccy.c
@@ -24,7 +24,7 @@
 #include <linux/isapnp.h>
 
 extern const char *CardType[];
-const char *niccy_revision = "$Revision: 1.21.2.4 $";
+static const char *niccy_revision = "$Revision: 1.21.2.4 $";
 
 #define byteout(addr,val) outb(val,addr)
 #define bytein(addr) inb(addr)
@@ -178,7 +178,7 @@ niccy_interrupt(int intno, void *dev_id,
 	return IRQ_HANDLED;
 }
 
-void
+static void
 release_io_niccy(struct IsdnCardState *cs)
 {
 	if (cs->subtyp == NICCY_PCI) {
diff --git a/drivers/isdn/hisax/nj_s.c b/drivers/isdn/hisax/nj_s.c
--- a/drivers/isdn/hisax/nj_s.c
+++ b/drivers/isdn/hisax/nj_s.c
@@ -15,7 +15,7 @@
 #include <linux/ppp_defs.h>
 #include "netjet.h"
 
-const char *NETjet_S_revision = "$Revision: 2.13.2.4 $";
+static const char *NETjet_S_revision = "$Revision: 2.13.2.4 $";
 
 static u_char dummyrr(struct IsdnCardState *cs, int chan, u_char off)
 {
diff --git a/drivers/isdn/hisax/nj_u.c b/drivers/isdn/hisax/nj_u.c
--- a/drivers/isdn/hisax/nj_u.c
+++ b/drivers/isdn/hisax/nj_u.c
@@ -15,7 +15,7 @@
 #include <linux/ppp_defs.h>
 #include "netjet.h"
 
-const char *NETjet_U_revision = "$Revision: 2.14.2.3 $";
+static const char *NETjet_U_revision = "$Revision: 2.14.2.3 $";
 
 static u_char dummyrr(struct IsdnCardState *cs, int chan, u_char off)
 {
diff --git a/drivers/isdn/hisax/q931.c b/drivers/isdn/hisax/q931.c
--- a/drivers/isdn/hisax/q931.c
+++ b/drivers/isdn/hisax/q931.c
@@ -516,7 +516,7 @@ struct MessageType cause_1tr6[] =
 	{CAUSE_UserInfoDiscarded, "User Info Discarded"}
 };
 
-int cause_1tr6_len = (sizeof(cause_1tr6) / sizeof(struct MessageType));
+static int cause_1tr6_len = (sizeof(cause_1tr6) / sizeof(struct MessageType));
 
 static int
 prcause_1tr6(char *dest, u_char * p)
@@ -935,7 +935,7 @@ display(char *dest, u_char * p)
 	return (dp - dest);
 }
 
-int
+static int
 prfacility(char *dest, u_char * p)
 {
 	char *dp = dest;
diff --git a/drivers/isdn/hisax/s0box.c b/drivers/isdn/hisax/s0box.c
--- a/drivers/isdn/hisax/s0box.c
+++ b/drivers/isdn/hisax/s0box.c
@@ -17,7 +17,7 @@
 #include "isdnl1.h"
 
 extern const char *CardType[];
-const char *s0box_revision = "$Revision: 2.6.2.4 $";
+static const char *s0box_revision = "$Revision: 2.6.2.4 $";
 
 static inline void
 writereg(unsigned int padr, signed int addr, u_char off, u_char val) {
@@ -183,7 +183,7 @@ s0box_interrupt(int intno, void *dev_id,
 	return IRQ_HANDLED;
 }
 
-void
+static void
 release_io_s0box(struct IsdnCardState *cs)
 {
 	release_region(cs->hw.teles3.cfg_reg, 8);
diff --git a/drivers/isdn/hisax/saphir.c b/drivers/isdn/hisax/saphir.c
--- a/drivers/isdn/hisax/saphir.c
+++ b/drivers/isdn/hisax/saphir.c
@@ -171,7 +171,7 @@ SaphirWatchDog(struct IsdnCardState *cs)
 	mod_timer(&cs->hw.saphir.timer, jiffies+1*HZ);
 }
 
-void
+static void
 release_io_saphir(struct IsdnCardState *cs)
 {
 	byteout(cs->hw.saphir.cfg_reg + IRQ_REG, 0xff);
diff --git a/drivers/isdn/hisax/sedlbauer.c b/drivers/isdn/hisax/sedlbauer.c
--- a/drivers/isdn/hisax/sedlbauer.c
+++ b/drivers/isdn/hisax/sedlbauer.c
@@ -51,9 +51,9 @@
 
 extern const char *CardType[];
 
-const char *Sedlbauer_revision = "$Revision: 1.34.2.6 $";
+static const char *Sedlbauer_revision = "$Revision: 1.34.2.6 $";
 
-const char *Sedlbauer_Types[] =
+static const char *Sedlbauer_Types[] =
 	{"None", "speed card/win", "speed star", "speed fax+",
 	"speed win II / ISDN PC/104", "speed star II", "speed pci",
 	"speed fax+ pyramid", "speed fax+ pci", "HST Saphir III"};
@@ -394,7 +394,7 @@ sedlbauer_interrupt_isar(int intno, void
 	return IRQ_HANDLED;
 }
 
-void
+static void
 release_io_sedlbauer(struct IsdnCardState *cs)
 {
 	int bytecnt = 8;
diff --git a/drivers/isdn/hisax/sedlbauer_cs.c b/drivers/isdn/hisax/sedlbauer_cs.c
--- a/drivers/isdn/hisax/sedlbauer_cs.c
+++ b/drivers/isdn/hisax/sedlbauer_cs.c
@@ -47,7 +47,6 @@
 #include <asm/io.h>
 #include <asm/system.h>
 
-#include <pcmcia/version.h>
 #include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
@@ -226,11 +225,6 @@ static dev_link_t *sedlbauer_attach(void
     link->next = dev_list;
     dev_list = link;
     client_reg.dev_info = &dev_info;
-    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 = &sedlbauer_event;
     client_reg.Version = 0x0210;
     client_reg.event_callback_args.client_data = link;
     ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -616,13 +610,27 @@ static int sedlbauer_event(event_t event
     return 0;
 } /* sedlbauer_event */
 
+static struct pcmcia_device_id sedlbauer_ids[] = {
+	PCMCIA_DEVICE_PROD_ID1234("SEDLBAUER", "speed star II", "V 3.1", "(c) 93 - 98 cb ", 0x81fb79f5, 0xf3612e1d, 0x6b95c78a, 0x50d4149c),
+	PCMCIA_DEVICE_PROD_ID123("SEDLBAUER", "ISDN-Adapter", "4D67", 0x81fb79f5, 0xe4e9bc12, 0x397b7e90),
+	PCMCIA_DEVICE_PROD_ID123("SEDLBAUER", "ISDN-Adapter", "4D98", 0x81fb79f5, 0xe4e9bc12, 0x2e5c7fce),
+	PCMCIA_DEVICE_PROD_ID123("SEDLBAUER", "ISDN-Adapter", " (C) 93-94 VK", 0x81fb79f5, 0xe4e9bc12, 0x8db143fe),
+	PCMCIA_DEVICE_PROD_ID123("SEDLBAUER", "ISDN-Adapter", " (c) 93-95 VK", 0x81fb79f5, 0xe4e9bc12, 0xb391ab4c),
+	PCMCIA_DEVICE_PROD_ID12("HST High Soft Tech GmbH", "Saphir II B", 0xd79e0b84, 0x21d083ae),
+/*	PCMCIA_DEVICE_PROD_ID1234("SEDLBAUER", 0x81fb79f5), */ /* too generic*/
+	PCMCIA_DEVICE_NULL
+};
+MODULE_DEVICE_TABLE(pcmcia, sedlbauer_ids);
+
 static struct pcmcia_driver sedlbauer_driver = {
 	.owner		= THIS_MODULE,
 	.drv		= {
 		.name	= "sedlbauer_cs",
 	},
 	.attach		= sedlbauer_attach,
+	.event		= sedlbauer_event,
 	.detach		= sedlbauer_detach,
+	.id_table	= sedlbauer_ids,
 };
 
 static int __init init_sedlbauer_cs(void)
diff --git a/drivers/isdn/hisax/sportster.c b/drivers/isdn/hisax/sportster.c
--- a/drivers/isdn/hisax/sportster.c
+++ b/drivers/isdn/hisax/sportster.c
@@ -19,7 +19,7 @@
 #include "isdnl1.h"
 
 extern const char *CardType[];
-const char *sportster_revision = "$Revision: 1.16.2.4 $";
+static const char *sportster_revision = "$Revision: 1.16.2.4 $";
 
 #define byteout(addr,val) outb(val,addr)
 #define bytein(addr) inb(addr)
@@ -132,7 +132,7 @@ sportster_interrupt(int intno, void *dev
 	return IRQ_HANDLED;
 }
 
-void
+static void
 release_io_sportster(struct IsdnCardState *cs)
 {
 	int i, adr;
@@ -144,7 +144,7 @@ release_io_sportster(struct IsdnCardStat
 	}
 }
 
-void
+static void
 reset_sportster(struct IsdnCardState *cs)
 {
 	cs->hw.spt.res_irq |= SPORTSTER_RESET; /* Reset On */
diff --git a/drivers/isdn/hisax/st5481.h b/drivers/isdn/hisax/st5481.h
--- a/drivers/isdn/hisax/st5481.h
+++ b/drivers/isdn/hisax/st5481.h
@@ -450,12 +450,8 @@ int st5481_setup_isocpipes(struct urb* u
 			   usb_complete_t complete, void *context);
 void st5481_release_isocpipes(struct urb* urb[2]);
 
-int  st5481_isoc_flatten(struct urb *urb);
 void st5481_usb_pipe_reset(struct st5481_adapter *adapter,
 		    u_char pipe, ctrl_complete_t complete, void *context);
-void st5481_usb_ctrl_msg(struct st5481_adapter *adapter,
-		  u8 request, u8 requesttype, u16 value, u16 index,
-		  ctrl_complete_t complete, void *context);
 void st5481_usb_device_ctrl_msg(struct st5481_adapter *adapter,
 			 u8 request, u16 value,
 			 ctrl_complete_t complete, void *context);
diff --git a/drivers/isdn/hisax/st5481_hdlc.c b/drivers/isdn/hisax/st5481_hdlc.c
deleted file mode 100644
--- a/drivers/isdn/hisax/st5481_hdlc.c
+++ /dev/null
@@ -1,580 +0,0 @@
-/*
- * Driver for ST5481 USB ISDN modem
- *
- * Author       Frode Isaksen
- * Copyright    2001 by Frode Isaksen      <fisaksen@bewan.com>
- *              2001 by Kai Germaschewski  <kai.germaschewski@gmx.de>
- * 
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- */
-
-#include <linux/crc-ccitt.h>
-#include "st5481_hdlc.h"
-
-
-enum {
-	HDLC_FAST_IDLE,HDLC_GET_FLAG_B0,HDLC_GETFLAG_B1A6,HDLC_GETFLAG_B7,
-	HDLC_GET_DATA,HDLC_FAST_FLAG
-};
-
-enum {
-	HDLC_SEND_DATA,HDLC_SEND_CRC1,HDLC_SEND_FAST_FLAG,
-	HDLC_SEND_FIRST_FLAG,HDLC_SEND_CRC2,HDLC_SEND_CLOSING_FLAG,
-	HDLC_SEND_IDLE1,HDLC_SEND_FAST_IDLE,HDLC_SENDFLAG_B0,
-	HDLC_SENDFLAG_B1A6,HDLC_SENDFLAG_B7,STOPPED
-};
-
-void 
-hdlc_rcv_init(struct hdlc_vars *hdlc, int do_adapt56)
-{
-   	hdlc->bit_shift = 0;
-	hdlc->hdlc_bits1 = 0;
-	hdlc->data_bits = 0;
-	hdlc->ffbit_shift = 0;
-	hdlc->data_received = 0;
-	hdlc->state = HDLC_GET_DATA;
-	hdlc->do_adapt56 = do_adapt56;
-	hdlc->dchannel = 0;
-	hdlc->crc = 0;
-	hdlc->cbin = 0;
-	hdlc->shift_reg = 0;
-	hdlc->ffvalue = 0;
-	hdlc->dstpos = 0;
-}
-
-void 
-hdlc_out_init(struct hdlc_vars *hdlc, int is_d_channel, int do_adapt56)
-{
-   	hdlc->bit_shift = 0;
-	hdlc->hdlc_bits1 = 0;
-	hdlc->data_bits = 0;
-	hdlc->ffbit_shift = 0;
-	hdlc->data_received = 0;
-	hdlc->do_closing = 0;
-	hdlc->ffvalue = 0;
-	if (is_d_channel) {
-		hdlc->dchannel = 1;
-		hdlc->state = HDLC_SEND_FIRST_FLAG;
-	} else {
-		hdlc->dchannel = 0;
-		hdlc->state = HDLC_SEND_FAST_FLAG;
-		hdlc->ffvalue = 0x7e;
-	} 
-	hdlc->cbin = 0x7e;
-	hdlc->bit_shift = 0;
-	if(do_adapt56){
-		hdlc->do_adapt56 = 1;		
-		hdlc->data_bits = 0;
-		hdlc->state = HDLC_SENDFLAG_B0;
-	} else {
-		hdlc->do_adapt56 = 0;		
-		hdlc->data_bits = 8;
-	}
-	hdlc->shift_reg = 0;
-}
-
-/*
-  hdlc_decode - decodes HDLC frames from a transparent bit stream.
-
-  The source buffer is scanned for valid HDLC frames looking for
-  flags (01111110) to indicate the start of a frame. If the start of
-  the frame is found, the bit stuffing is removed (0 after 5 1's).
-  When a new flag is found, the complete frame has been received
-  and the CRC is checked.
-  If a valid frame is found, the function returns the frame length 
-  excluding the CRC with the bit HDLC_END_OF_FRAME set.
-  If the beginning of a valid frame is found, the function returns
-  the length. 
-  If a framing error is found (too many 1s and not a flag) the function 
-  returns the length with the bit HDLC_FRAMING_ERROR set.
-  If a CRC error is found the function returns the length with the
-  bit HDLC_CRC_ERROR set.
-  If the frame length exceeds the destination buffer size, the function
-  returns the length with the bit HDLC_LENGTH_ERROR set.
-
-  src - source buffer
-  slen - source buffer length
-  count - number of bytes removed (decoded) from the source buffer
-  dst _ destination buffer
-  dsize - destination buffer size
-  returns - number of decoded bytes in the destination buffer and status
-  flag.
- */
-int hdlc_decode(struct hdlc_vars *hdlc, const unsigned char *src,
-		int slen, int *count, unsigned char *dst, int dsize)
-{
-	int status=0;
-
-	static const unsigned char fast_flag[]={
-		0x00,0x00,0x00,0x20,0x30,0x38,0x3c,0x3e,0x3f
-	};
-
-	static const unsigned char fast_flag_value[]={
-		0x00,0x7e,0xfc,0xf9,0xf3,0xe7,0xcf,0x9f,0x3f
-	};
-
-	static const unsigned char fast_abort[]={
-		0x00,0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff
-	};
-
-	*count = slen;
-
-	while(slen > 0){
-		if(hdlc->bit_shift==0){
-			hdlc->cbin = *src++;
-			slen--;
-			hdlc->bit_shift = 8;
-			if(hdlc->do_adapt56){
-				hdlc->bit_shift --;
-			}
-		}
-
-		switch(hdlc->state){
-		case STOPPED:
-			return 0;
-		case HDLC_FAST_IDLE:
-			if(hdlc->cbin == 0xff){
-				hdlc->bit_shift = 0;
-				break;
-			}
-			hdlc->state = HDLC_GET_FLAG_B0;
-			hdlc->hdlc_bits1 = 0;
-			hdlc->bit_shift = 8;
-			break;
-		case HDLC_GET_FLAG_B0:
-			if(!(hdlc->cbin & 0x80)) {
-				hdlc->state = HDLC_GETFLAG_B1A6;
-				hdlc->hdlc_bits1 = 0;
-			} else {
-				if(!hdlc->do_adapt56){
-					if(++hdlc->hdlc_bits1 >=8 ) if(hdlc->bit_shift==1)
-						hdlc->state = HDLC_FAST_IDLE;
-				}
-			}
-			hdlc->cbin<<=1;
-			hdlc->bit_shift --;
-			break;
-		case HDLC_GETFLAG_B1A6:
-			if(hdlc->cbin & 0x80){
-				hdlc->hdlc_bits1++;
-				if(hdlc->hdlc_bits1==6){
-					hdlc->state = HDLC_GETFLAG_B7;
-				}
-			} else {
-				hdlc->hdlc_bits1 = 0;
-			}
-			hdlc->cbin<<=1;
-			hdlc->bit_shift --;
-			break;
-		case HDLC_GETFLAG_B7:
-			if(hdlc->cbin & 0x80) {
-				hdlc->state = HDLC_GET_FLAG_B0;
-			} else {
-				hdlc->state = HDLC_GET_DATA;
-				hdlc->crc = 0xffff;
-				hdlc->shift_reg = 0;
-				hdlc->hdlc_bits1 = 0;
-				hdlc->data_bits = 0;
-				hdlc->data_received = 0;
-			}
-			hdlc->cbin<<=1;
-			hdlc->bit_shift --;
-			break;
-		case HDLC_GET_DATA:
-			if(hdlc->cbin & 0x80){
-				hdlc->hdlc_bits1++;
-				switch(hdlc->hdlc_bits1){
-				case 6:
-					break;
-				case 7:
-					if(hdlc->data_received) {
-						// bad frame
-						status = -HDLC_FRAMING_ERROR;
-					}
-					if(!hdlc->do_adapt56){
-						if(hdlc->cbin==fast_abort[hdlc->bit_shift+1]){
-							hdlc->state = HDLC_FAST_IDLE;
-							hdlc->bit_shift=1;
-							break;
-						}
-					} else {
-						hdlc->state = HDLC_GET_FLAG_B0;
-					}
-					break;
-				default:
-					hdlc->shift_reg>>=1;
-					hdlc->shift_reg |= 0x80;
-					hdlc->data_bits++;
-					break;
-				}
-			} else {
-				switch(hdlc->hdlc_bits1){
-				case 5:
-					break;
-				case 6:
-					if(hdlc->data_received){
-						if (hdlc->dstpos < 2) {
-							status = -HDLC_FRAMING_ERROR;
-						} else if (hdlc->crc != 0xf0b8){
-							// crc error
-							status = -HDLC_CRC_ERROR;
-						} else {
-							// remove CRC
-							hdlc->dstpos -= 2;
-							// good frame
-							status = hdlc->dstpos;
-						}
-					}
-					hdlc->crc = 0xffff;
-					hdlc->shift_reg = 0;
-					hdlc->data_bits = 0;
-					if(!hdlc->do_adapt56){
-						if(hdlc->cbin==fast_flag[hdlc->bit_shift]){
-							hdlc->ffvalue = fast_flag_value[hdlc->bit_shift];
-							hdlc->state = HDLC_FAST_FLAG;
-							hdlc->ffbit_shift = hdlc->bit_shift;
-							hdlc->bit_shift = 1;
-						} else {
-							hdlc->state = HDLC_GET_DATA;
-							hdlc->data_received = 0;
-						}
-					} else {
-						hdlc->state = HDLC_GET_DATA;
-						hdlc->data_received = 0;
-					}
-					break;
-				default:
-					hdlc->shift_reg>>=1;
-					hdlc->data_bits++;
-					break;
-				}
-				hdlc->hdlc_bits1 = 0;
-			}
-			if (status) {
-				hdlc->dstpos = 0;
-				*count -= slen;
-				hdlc->cbin <<= 1;
-				hdlc->bit_shift--;
-				return status;
-			}
-			if(hdlc->data_bits==8){
-				hdlc->data_bits = 0;
-				hdlc->data_received = 1;
-				hdlc->crc = crc_ccitt_byte(hdlc->crc, hdlc->shift_reg);
-
-				// good byte received
-				if (dsize--) {
-					dst[hdlc->dstpos++] = hdlc->shift_reg;
-				} else {
-					// frame too long
-					status = -HDLC_LENGTH_ERROR;
-					hdlc->dstpos = 0;
-				}
-			}
-			hdlc->cbin <<= 1;
-			hdlc->bit_shift--;
-			break;
-		case HDLC_FAST_FLAG:
-			if(hdlc->cbin==hdlc->ffvalue){
-				hdlc->bit_shift = 0;
-				break;
-			} else {
-				if(hdlc->cbin == 0xff){
-					hdlc->state = HDLC_FAST_IDLE;
-					hdlc->bit_shift=0;
-				} else if(hdlc->ffbit_shift==8){
-					hdlc->state = HDLC_GETFLAG_B7;
-					break;
-				} else {
-					hdlc->shift_reg = fast_abort[hdlc->ffbit_shift-1];
-					hdlc->hdlc_bits1 = hdlc->ffbit_shift-2;
-					if(hdlc->hdlc_bits1<0)hdlc->hdlc_bits1 = 0;
-					hdlc->data_bits = hdlc->ffbit_shift-1;
-					hdlc->state = HDLC_GET_DATA;
-					hdlc->data_received = 0;
-				}
-			}
-			break;
-		default:
-			break;
-		}
-	}
-	*count -= slen;
-	return 0;
-}
-
-/*
-  hdlc_encode - encodes HDLC frames to a transparent bit stream.
-
-  The bit stream starts with a beginning flag (01111110). After
-  that each byte is added to the bit stream with bit stuffing added
-  (0 after 5 1's).
-  When the last byte has been removed from the source buffer, the
-  CRC (2 bytes is added) and the frame terminates with the ending flag.
-  For the dchannel, the idle character (all 1's) is also added at the end.
-  If this function is called with empty source buffer (slen=0), flags or
-  idle character will be generated.
- 
-  src - source buffer
-  slen - source buffer length
-  count - number of bytes removed (encoded) from source buffer
-  dst _ destination buffer
-  dsize - destination buffer size
-  returns - number of encoded bytes in the destination buffer
-*/
-int hdlc_encode(struct hdlc_vars *hdlc, const unsigned char *src, 
-		unsigned short slen, int *count,
-		unsigned char *dst, int dsize)
-{
-	static const unsigned char xfast_flag_value[] = {
-		0x7e,0x3f,0x9f,0xcf,0xe7,0xf3,0xf9,0xfc,0x7e
-	};
-
-	int len = 0;
-
-	*count = slen;
-
-	while (dsize > 0) {
-		if(hdlc->bit_shift==0){	
-			if(slen && !hdlc->do_closing){
-				hdlc->shift_reg = *src++;
-				slen--;
-				if (slen == 0) 
-					hdlc->do_closing = 1;  /* closing sequence, CRC + flag(s) */
-				hdlc->bit_shift = 8;
-			} else {
-				if(hdlc->state == HDLC_SEND_DATA){
-					if(hdlc->data_received){
-						hdlc->state = HDLC_SEND_CRC1;
-						hdlc->crc ^= 0xffff;
-						hdlc->bit_shift = 8;
-						hdlc->shift_reg = hdlc->crc & 0xff;
-					} else if(!hdlc->do_adapt56){
-						hdlc->state = HDLC_SEND_FAST_FLAG;
-					} else {
-						hdlc->state = HDLC_SENDFLAG_B0;
-					}
-				}
-			  
-			}
-		}
-
-		switch(hdlc->state){
-		case STOPPED:
-			while (dsize--)
-				*dst++ = 0xff;
-		  
-			return dsize;
-		case HDLC_SEND_FAST_FLAG:
-			hdlc->do_closing = 0;
-			if(slen == 0){
-				*dst++ = hdlc->ffvalue;
-				len++;
-				dsize--;
-				break;
-			}
-			if(hdlc->bit_shift==8){
-				hdlc->cbin = hdlc->ffvalue>>(8-hdlc->data_bits);
-				hdlc->state = HDLC_SEND_DATA;
-				hdlc->crc = 0xffff;
-				hdlc->hdlc_bits1 = 0;
-				hdlc->data_received = 1;
-			}
-			break;
-		case HDLC_SENDFLAG_B0:
-			hdlc->do_closing = 0;
-			hdlc->cbin <<= 1;
-			hdlc->data_bits++;
-			hdlc->hdlc_bits1 = 0;
-			hdlc->state = HDLC_SENDFLAG_B1A6;
-			break;
-		case HDLC_SENDFLAG_B1A6:
-			hdlc->cbin <<= 1;
-			hdlc->data_bits++;
-			hdlc->cbin++;
-			if(++hdlc->hdlc_bits1 == 6)
-				hdlc->state = HDLC_SENDFLAG_B7;
-			break;
-		case HDLC_SENDFLAG_B7:
-			hdlc->cbin <<= 1;
-			hdlc->data_bits++;
-			if(slen == 0){
-				hdlc->state = HDLC_SENDFLAG_B0;
-				break;
-			}
-			if(hdlc->bit_shift==8){
-				hdlc->state = HDLC_SEND_DATA;
-				hdlc->crc = 0xffff;
-				hdlc->hdlc_bits1 = 0;
-				hdlc->data_received = 1;
-			}
-			break;
-		case HDLC_SEND_FIRST_FLAG:
-			hdlc->data_received = 1;
-			if(hdlc->data_bits==8){
-				hdlc->state = HDLC_SEND_DATA;
-				hdlc->crc = 0xffff;
-				hdlc->hdlc_bits1 = 0;
-				break;
-			}
-			hdlc->cbin <<= 1;
-			hdlc->data_bits++;
-			if(hdlc->shift_reg & 0x01)
-				hdlc->cbin++;
-			hdlc->shift_reg >>= 1;
-			hdlc->bit_shift--;
-			if(hdlc->bit_shift==0){
-				hdlc->state = HDLC_SEND_DATA;
-				hdlc->crc = 0xffff;
-				hdlc->hdlc_bits1 = 0;
-			}
-			break;
-		case HDLC_SEND_DATA:
-			hdlc->cbin <<= 1;
-			hdlc->data_bits++;
-			if(hdlc->hdlc_bits1 == 5){
-				hdlc->hdlc_bits1 = 0;
-				break;
-			}
-			if(hdlc->bit_shift==8){
-				hdlc->crc = crc_ccitt_byte(hdlc->crc, hdlc->shift_reg);
-			}
-			if(hdlc->shift_reg & 0x01){
-				hdlc->hdlc_bits1++;
-				hdlc->cbin++;
-				hdlc->shift_reg >>= 1;
-				hdlc->bit_shift--;
-			} else {
-				hdlc->hdlc_bits1 = 0;
-				hdlc->shift_reg >>= 1;
-				hdlc->bit_shift--;
-			}
-			break;
-		case HDLC_SEND_CRC1:
-			hdlc->cbin <<= 1;
-			hdlc->data_bits++;
-			if(hdlc->hdlc_bits1 == 5){
-				hdlc->hdlc_bits1 = 0;
-				break;
-			}
-			if(hdlc->shift_reg & 0x01){
-				hdlc->hdlc_bits1++;
-				hdlc->cbin++;
-				hdlc->shift_reg >>= 1;
-				hdlc->bit_shift--;
-			} else {
-				hdlc->hdlc_bits1 = 0;
-				hdlc->shift_reg >>= 1;
-				hdlc->bit_shift--;
-			}
-			if(hdlc->bit_shift==0){
-				hdlc->shift_reg = (hdlc->crc >> 8);
-				hdlc->state = HDLC_SEND_CRC2;
-				hdlc->bit_shift = 8;
-			}
-			break;
-		case HDLC_SEND_CRC2:
-			hdlc->cbin <<= 1;
-			hdlc->data_bits++;
-			if(hdlc->hdlc_bits1 == 5){
-				hdlc->hdlc_bits1 = 0;
-				break;
-			}
-			if(hdlc->shift_reg & 0x01){
-				hdlc->hdlc_bits1++;
-				hdlc->cbin++;
-				hdlc->shift_reg >>= 1;
-				hdlc->bit_shift--;
-			} else {
-				hdlc->hdlc_bits1 = 0;
-				hdlc->shift_reg >>= 1;
-				hdlc->bit_shift--;
-			}
-			if(hdlc->bit_shift==0){
-				hdlc->shift_reg = 0x7e;
-				hdlc->state = HDLC_SEND_CLOSING_FLAG;
-				hdlc->bit_shift = 8;
-			}
-			break;
-		case HDLC_SEND_CLOSING_FLAG:
-			hdlc->cbin <<= 1;
-			hdlc->data_bits++;
-			if(hdlc->hdlc_bits1 == 5){
-				hdlc->hdlc_bits1 = 0;
-				break;
-			}
-			if(hdlc->shift_reg & 0x01){
-				hdlc->cbin++;
-			}
-			hdlc->shift_reg >>= 1;
-			hdlc->bit_shift--;
-			if(hdlc->bit_shift==0){
-				hdlc->ffvalue = xfast_flag_value[hdlc->data_bits];
-				if(hdlc->dchannel){
-					hdlc->ffvalue = 0x7e;
-					hdlc->state = HDLC_SEND_IDLE1;
-					hdlc->bit_shift = 8-hdlc->data_bits;
-					if(hdlc->bit_shift==0)
-						hdlc->state = HDLC_SEND_FAST_IDLE;
-				} else {
-					if(!hdlc->do_adapt56){
-						hdlc->state = HDLC_SEND_FAST_FLAG;
-						hdlc->data_received = 0;
-					} else {
-						hdlc->state = HDLC_SENDFLAG_B0;
-						hdlc->data_received = 0;
-					}
-					// Finished with this frame, send flags
-					if (dsize > 1) dsize = 1; 
-				}
-			}
-			break;
-		case HDLC_SEND_IDLE1:
-			hdlc->do_closing = 0;
-			hdlc->cbin <<= 1;
-			hdlc->cbin++;
-			hdlc->data_bits++;
-			hdlc->bit_shift--;
-			if(hdlc->bit_shift==0){
-				hdlc->state = HDLC_SEND_FAST_IDLE;
-				hdlc->bit_shift = 0;
-			}
-			break;
-		case HDLC_SEND_FAST_IDLE:
-			hdlc->do_closing = 0;
-			hdlc->cbin = 0xff;
-			hdlc->data_bits = 8;
-			if(hdlc->bit_shift == 8){
-				hdlc->cbin = 0x7e;
-				hdlc->state = HDLC_SEND_FIRST_FLAG;
-			} else {
-				*dst++ = hdlc->cbin;
-				hdlc->bit_shift = hdlc->data_bits = 0;
-				len++;
-				dsize = 0;
-			}
-			break;
-		default:
-			break;
-		}
-		if(hdlc->do_adapt56){
-			if(hdlc->data_bits==7){
-				hdlc->cbin <<= 1;
-				hdlc->cbin++;
-				hdlc->data_bits++;
-			}
-		}
-		if(hdlc->data_bits==8){
-			*dst++ = hdlc->cbin;
-			hdlc->data_bits = 0;
-			len++;
-			dsize--;
-		}
-	}
-	*count -= slen;
-
-	return len;
-}
-
diff --git a/drivers/isdn/hisax/st5481_hdlc.h b/drivers/isdn/hisax/st5481_hdlc.h
deleted file mode 100644
--- a/drivers/isdn/hisax/st5481_hdlc.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Driver for ST5481 USB ISDN modem
- *
- * Author       Frode Isaksen
- * Copyright    2001 by Frode Isaksen      <fisaksen@bewan.com>
- *              2001 by Kai Germaschewski  <kai.germaschewski@gmx.de>
- * 
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- */
-
-#ifndef __ST5481_HDLC_H__
-#define __ST5481_HDLC_H__
-
-struct hdlc_vars {
-  	int bit_shift; 
-	int hdlc_bits1;
-	int data_bits;
-	int ffbit_shift; // encoding only
-	int state;
-	int dstpos;
-
-	int data_received:1; // set if transferring data
-	int dchannel:1; // set if D channel (send idle instead of flags)
-	int do_adapt56:1; // set if 56K adaptation
-        int do_closing:1; // set if in closing phase (need to send CRC + flag
-
-	unsigned short crc;
-
-	unsigned char cbin; 
-	unsigned char shift_reg;
-	unsigned char ffvalue;
-	
-};
-
-
-/*
-  The return value from hdlc_decode is
-  the frame length, 0 if no complete frame was decoded,
-  or a negative error number
-*/
-
-#define HDLC_FRAMING_ERROR     1
-#define HDLC_CRC_ERROR         2
-#define HDLC_LENGTH_ERROR      3
-
-void 
-hdlc_rcv_init(struct hdlc_vars *hdlc, int do_adapt56);
-
-int
-hdlc_decode(struct hdlc_vars *hdlc, const unsigned char *src, int slen,int *count, 
-	    unsigned char *dst, int dsize);
-
-void 
-hdlc_out_init(struct hdlc_vars *hdlc,int is_d_channel,int do_adapt56);
-
-int 
-hdlc_encode(struct hdlc_vars *hdlc,const unsigned char *src,unsigned short slen,int *count,
-	    unsigned char *dst,int dsize);
-
-#endif
diff --git a/drivers/isdn/hisax/st5481_usb.c b/drivers/isdn/hisax/st5481_usb.c
--- a/drivers/isdn/hisax/st5481_usb.c
+++ b/drivers/isdn/hisax/st5481_usb.c
@@ -15,6 +15,8 @@
 #include <linux/slab.h>
 #include "st5481.h"
 
+static int st5481_isoc_flatten(struct urb *urb);
+
 /* ======================================================================
  * control pipe
  */
@@ -55,9 +57,9 @@ static void usb_next_ctrl_msg(struct urb
  * Asynchronous endpoint 0 request (async version of usb_control_msg).
  * The request will be queued up in a FIFO if the endpoint is busy.
  */
-void usb_ctrl_msg(struct st5481_adapter *adapter,
-		  u8 request, u8 requesttype, u16 value, u16 index,
-		  ctrl_complete_t complete, void *context)
+static void usb_ctrl_msg(struct st5481_adapter *adapter,
+			 u8 request, u8 requesttype, u16 value, u16 index,
+			 ctrl_complete_t complete, void *context)
 {
 	struct st5481_ctrl *ctrl = &adapter->ctrl;
 	int w_index;
@@ -571,7 +573,7 @@ void st5481_release_in(struct st5481_in 
  * Make the transfer_buffer contiguous by
  * copying from the iso descriptors if necessary. 
  */
-int st5481_isoc_flatten(struct urb *urb)
+static int st5481_isoc_flatten(struct urb *urb)
 {
 	struct usb_iso_packet_descriptor *pipd,*pend;
 	unsigned char *src,*dst;
diff --git a/drivers/isdn/hisax/tei.c b/drivers/isdn/hisax/tei.c
--- a/drivers/isdn/hisax/tei.c
+++ b/drivers/isdn/hisax/tei.c
@@ -74,7 +74,7 @@ static char *strTeiEvent[] =
 	"EV_T202",
 };
 
-unsigned int
+static unsigned int
 random_ri(void)
 {
 	unsigned int x;
diff --git a/drivers/isdn/hisax/teleint.c b/drivers/isdn/hisax/teleint.c
--- a/drivers/isdn/hisax/teleint.c
+++ b/drivers/isdn/hisax/teleint.c
@@ -18,7 +18,7 @@
 
 extern const char *CardType[];
 
-const char *TeleInt_revision = "$Revision: 1.16.2.5 $";
+static const char *TeleInt_revision = "$Revision: 1.16.2.5 $";
 
 #define byteout(addr,val) outb(val,addr)
 #define bytein(addr) inb(addr)
@@ -203,7 +203,7 @@ TeleInt_Timer(struct IsdnCardState *cs)
 	add_timer(&cs->hw.hfc.timer);
 }
 
-void
+static void
 release_io_TeleInt(struct IsdnCardState *cs)
 {
 	del_timer(&cs->hw.hfc.timer);
diff --git a/drivers/isdn/hisax/teles0.c b/drivers/isdn/hisax/teles0.c
--- a/drivers/isdn/hisax/teles0.c
+++ b/drivers/isdn/hisax/teles0.c
@@ -23,7 +23,7 @@
 
 extern const char *CardType[];
 
-const char *teles0_revision = "$Revision: 2.15.2.4 $";
+static const char *teles0_revision = "$Revision: 2.15.2.4 $";
 
 #define TELES_IOMEM_SIZE	0x400
 #define byteout(addr,val) outb(val,addr)
@@ -183,7 +183,7 @@ teles0_interrupt(int intno, void *dev_id
 	return IRQ_HANDLED;
 }
 
-void
+static void
 release_io_teles0(struct IsdnCardState *cs)
 {
 	if (cs->hw.teles0.cfg_reg)
diff --git a/drivers/isdn/hisax/teles3.c b/drivers/isdn/hisax/teles3.c
--- a/drivers/isdn/hisax/teles3.c
+++ b/drivers/isdn/hisax/teles3.c
@@ -21,7 +21,7 @@
 #include "isdnl1.h"
 
 extern const char *CardType[];
-const char *teles3_revision = "$Revision: 2.19.2.4 $";
+static const char *teles3_revision = "$Revision: 2.19.2.4 $";
 
 #define byteout(addr,val) outb(val,addr)
 #define bytein(addr) inb(addr)
@@ -143,7 +143,7 @@ teles3_interrupt(int intno, void *dev_id
 	return IRQ_HANDLED;
 }
 
-inline static void
+static inline void
 release_ioregs(struct IsdnCardState *cs, int mask)
 {
 	if (mask & 1)
@@ -154,7 +154,7 @@ release_ioregs(struct IsdnCardState *cs,
 		release_region(cs->hw.teles3.hscx[1] + 32, 32);
 }
 
-void
+static void
 release_io_teles3(struct IsdnCardState *cs)
 {
 	if (cs->typ == ISDN_CTYPE_TELESPCMCIA) {
diff --git a/drivers/isdn/hisax/teles_cs.c b/drivers/isdn/hisax/teles_cs.c
--- a/drivers/isdn/hisax/teles_cs.c
+++ b/drivers/isdn/hisax/teles_cs.c
@@ -28,7 +28,6 @@
 #include <asm/io.h>
 #include <asm/system.h>
 
-#include <pcmcia/version.h>
 #include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
@@ -193,11 +192,6 @@ static dev_link_t *teles_attach(void)
     link->next = dev_list;
     dev_list = link;
     client_reg.dev_info = &dev_info;
-    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 = &teles_cs_event;
     client_reg.Version = 0x0210;
     client_reg.event_callback_args.client_data = link;
     ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -489,13 +483,21 @@ static int teles_cs_event(event_t event,
     return 0;
 } /* teles_cs_event */
 
+static struct pcmcia_device_id teles_ids[] = {
+	PCMCIA_DEVICE_PROD_ID12("TELES", "S0/PC", 0x67b50eae, 0xe9e70119),
+	PCMCIA_DEVICE_NULL,
+};
+MODULE_DEVICE_TABLE(pcmcia, teles_ids);
+
 static struct pcmcia_driver teles_cs_driver = {
 	.owner		= THIS_MODULE,
 	.drv		= {
 		.name	= "teles_cs",
 	},
 	.attach		= teles_attach,
+	.event		= teles_cs_event,
 	.detach		= teles_detach,
+	.id_table       = teles_ids,
 };
 
 static int __init init_teles_cs(void)
diff --git a/drivers/isdn/hisax/telespci.c b/drivers/isdn/hisax/telespci.c
--- a/drivers/isdn/hisax/telespci.c
+++ b/drivers/isdn/hisax/telespci.c
@@ -21,7 +21,7 @@
 #include <linux/pci.h>
 
 extern const char *CardType[];
-const char *telespci_revision = "$Revision: 2.23.2.3 $";
+static const char *telespci_revision = "$Revision: 2.23.2.3 $";
 
 #define ZORAN_PO_RQ_PEN	0x02000000
 #define ZORAN_PO_WR	0x00800000
@@ -257,7 +257,7 @@ telespci_interrupt(int intno, void *dev_
 	return IRQ_HANDLED;
 }
 
-void
+static void
 release_io_telespci(struct IsdnCardState *cs)
 {
 	iounmap(cs->hw.teles0.membase);
diff --git a/drivers/isdn/hisax/w6692.c b/drivers/isdn/hisax/w6692.c
--- a/drivers/isdn/hisax/w6692.c
+++ b/drivers/isdn/hisax/w6692.c
@@ -41,7 +41,7 @@ static const PCI_ENTRY id_list[] =
 
 extern const char *CardType[];
 
-const char *w6692_revision = "$Revision: 1.18.2.4 $";
+static const char *w6692_revision = "$Revision: 1.18.2.4 $";
 
 #define DBUSY_TIMER_VALUE 80
 
@@ -880,7 +880,7 @@ setstack_w6692(struct PStack *st, struct
 	return (0);
 }
 
-void resetW6692(struct IsdnCardState *cs)
+static void resetW6692(struct IsdnCardState *cs)
 {
 	cs->writeW6692(cs, W_D_CTL, W_D_CTL_SRST);
 	mdelay(10);
@@ -902,7 +902,7 @@ void resetW6692(struct IsdnCardState *cs
 	}
 }
 
-void __init initW6692(struct IsdnCardState *cs, int part)
+static void __init initW6692(struct IsdnCardState *cs, int part)
 {
 	if (part & 1) {
 		cs->setstack_d = setstack_W6692;
diff --git a/drivers/isdn/hysdn/hycapi.c b/drivers/isdn/hysdn/hycapi.c
--- a/drivers/isdn/hysdn/hycapi.c
+++ b/drivers/isdn/hysdn/hycapi.c
@@ -42,6 +42,8 @@ typedef struct _hycapi_appl {
 
 static hycapi_appl hycapi_applications[CAPI_MAXAPPL];
 
+static u16 hycapi_send_message(struct capi_ctr *ctrl, struct sk_buff *skb);
+
 static inline int _hycapi_appCheck(int app_id, int ctrl_no)
 {
 	if((ctrl_no <= 0) || (ctrl_no > CAPI_MAXCONTR) || (app_id <= 0) ||
@@ -57,7 +59,7 @@ static inline int _hycapi_appCheck(int a
 Kernel-Capi callback reset_ctr
 ******************************/     
 
-void 
+static void
 hycapi_reset_ctr(struct capi_ctr *ctrl)
 {
 	hycapictrl_info *cinfo = ctrl->driverdata;
@@ -73,7 +75,7 @@ hycapi_reset_ctr(struct capi_ctr *ctrl)
 Kernel-Capi callback remove_ctr
 ******************************/     
 
-void 
+static void
 hycapi_remove_ctr(struct capi_ctr *ctrl)
 {
 	int i;
@@ -215,7 +217,7 @@ Error-checking is done for CAPI-complian
 The application is recorded in the internal list.
 *************************************************************/
 
-void 
+static void
 hycapi_register_appl(struct capi_ctr *ctrl, __u16 appl, 
 		     capi_register_params *rp)
 {
@@ -291,7 +293,7 @@ Release the application from the interna
 registration at controller-level
 ******************************************************************/
 
-void 
+static void
 hycapi_release_appl(struct capi_ctr *ctrl, __u16 appl)
 {
 	int chk;
@@ -364,7 +366,7 @@ firmware-releases that do not check the 
 
 ***************************************************************/
 
-u16 hycapi_send_message(struct capi_ctr *ctrl, struct sk_buff *skb)
+static u16 hycapi_send_message(struct capi_ctr *ctrl, struct sk_buff *skb)
 {
 	__u16 appl_id;
 	int _len, _len2;
@@ -437,8 +439,8 @@ Informations provided in the /proc/capi-
 
 *********************************************************************/
 
-int hycapi_read_proc(char *page, char **start, off_t off,
-		     int count, int *eof, struct capi_ctr *ctrl)
+static int hycapi_read_proc(char *page, char **start, off_t off,
+			    int count, int *eof, struct capi_ctr *ctrl)
 {
 	hycapictrl_info *cinfo = (hycapictrl_info *)(ctrl->driverdata);
 	hysdn_card *card = cinfo->card;
@@ -485,7 +487,7 @@ on capi-interface registration.
 
 **************************************************************/
 
-int hycapi_load_firmware(struct capi_ctr *ctrl, capiloaddata *data)
+static int hycapi_load_firmware(struct capi_ctr *ctrl, capiloaddata *data)
 {
 #ifdef HYCAPI_PRINTFNAMES
 	printk(KERN_NOTICE "hycapi_load_firmware\n");    
@@ -494,7 +496,7 @@ int hycapi_load_firmware(struct capi_ctr
 }
 
 
-char *hycapi_procinfo(struct capi_ctr *ctrl)
+static char *hycapi_procinfo(struct capi_ctr *ctrl)
 {
 	hycapictrl_info *cinfo = (hycapictrl_info *)(ctrl->driverdata);
 #ifdef HYCAPI_PRINTFNAMES
diff --git a/drivers/isdn/hysdn/hysdn_boot.c b/drivers/isdn/hysdn/hysdn_boot.c
--- a/drivers/isdn/hysdn/hysdn_boot.c
+++ b/drivers/isdn/hysdn/hysdn_boot.c
@@ -53,7 +53,7 @@ struct boot_data {
 /*  to be called at start of POF file reading,       */
 /*  before starting any decryption on any POF record. */
 /*****************************************************/
-void
+static void
 StartDecryption(struct boot_data *boot)
 {
 	boot->Cryptor = CRYPT_STARTTERM;
@@ -66,7 +66,7 @@ StartDecryption(struct boot_data *boot)
 /*       to HI and LO boot loader and (all) seq tags, because  */
 /*       global Cryptor is started for whole POF.              */
 /***************************************************************/
-void
+static void
 DecryptBuf(struct boot_data *boot, int cnt)
 {
 	uchar *bufp = boot->buf.BootBuf;
diff --git a/drivers/isdn/hysdn/hysdn_defs.h b/drivers/isdn/hysdn/hysdn_defs.h
--- a/drivers/isdn/hysdn/hysdn_defs.h
+++ b/drivers/isdn/hysdn/hysdn_defs.h
@@ -227,7 +227,6 @@ typedef struct hycapictrl_info hycapictr
 /*****************/
 /* exported vars */
 /*****************/
-extern int cardmax;		/* number of found cards */
 extern hysdn_card *card_root;	/* pointer to first card */
 
 
@@ -244,7 +243,6 @@ extern void hysdn_procconf_release(void)
 /* hysdn_proclog.c */
 extern int hysdn_proclog_init(hysdn_card *);	/* init proc log entry */
 extern void hysdn_proclog_release(hysdn_card *);	/* deinit proc log entry */
-extern void put_log_buffer(hysdn_card *, char *);	/* output log data */
 extern void hysdn_addlog(hysdn_card *, char *,...);	/* output data to log */
 extern void hysdn_card_errlog(hysdn_card *, tErrLogEntry *, int);	/* output card log */
 
@@ -278,16 +276,6 @@ extern unsigned int hycapi_enable; 
 extern int hycapi_capi_create(hysdn_card *);	/* create a new capi device */
 extern int hycapi_capi_release(hysdn_card *);	/* delete the device */
 extern int hycapi_capi_stop(hysdn_card *card);   /* suspend */
-extern int hycapi_load_firmware(struct capi_ctr *, capiloaddata *);
-extern void hycapi_reset_ctr(struct capi_ctr *);
-extern void hycapi_remove_ctr(struct capi_ctr *);
-extern void hycapi_register_appl(struct capi_ctr *, __u16 appl,
-				 capi_register_params *);
-extern void hycapi_release_appl(struct capi_ctr *, __u16 appl);
-extern u16  hycapi_send_message(struct capi_ctr *, struct sk_buff *skb);
-extern char *hycapi_procinfo(struct capi_ctr *);
-extern int hycapi_read_proc(char *page, char **start, off_t off,
-			    int count, int *eof, struct capi_ctr *card);
 extern void hycapi_rx_capipkt(hysdn_card * card, uchar * buf, word len);
 extern void hycapi_tx_capiack(hysdn_card * card);
 extern struct sk_buff *hycapi_tx_capiget(hysdn_card *card);
diff --git a/drivers/isdn/hysdn/hysdn_init.c b/drivers/isdn/hysdn/hysdn_init.c
--- a/drivers/isdn/hysdn/hysdn_init.c
+++ b/drivers/isdn/hysdn/hysdn_init.c
@@ -34,7 +34,7 @@ MODULE_AUTHOR("Werner Cornelius");
 MODULE_LICENSE("GPL");
 
 static char *hysdn_init_revision = "$Revision: 1.6.6.6 $";
-int cardmax;			/* number of found cards */
+static int cardmax;		/* number of found cards */
 hysdn_card *card_root = NULL;	/* pointer to first card */
 
 /**********************************************/
diff --git a/drivers/isdn/hysdn/hysdn_proclog.c b/drivers/isdn/hysdn/hysdn_proclog.c
--- a/drivers/isdn/hysdn/hysdn_proclog.c
+++ b/drivers/isdn/hysdn/hysdn_proclog.c
@@ -22,6 +22,8 @@
 /* the proc subdir for the interface is defined in the procconf module */
 extern struct proc_dir_entry *hysdn_proc_entry;
 
+static void put_log_buffer(hysdn_card * card, char *cp);
+
 /*************************************************/
 /* structure keeping ascii log for device output */
 /*************************************************/
@@ -93,7 +95,7 @@ hysdn_addlog(hysdn_card * card, char *fm
 /* opened for read got the contents.        */
 /* Flushes buffers not longer in use.       */
 /********************************************/
-void
+static void
 put_log_buffer(hysdn_card * card, char *cp)
 {
 	struct log_data *ib;
diff --git a/drivers/isdn/i4l/isdn_audio.c b/drivers/isdn/i4l/isdn_audio.c
--- a/drivers/isdn/i4l/isdn_audio.c
+++ b/drivers/isdn/i4l/isdn_audio.c
@@ -392,16 +392,6 @@ isdn_audio_adpcm2xlaw(adpcm_state * s, i
 }
 
 int
-isdn_audio_2adpcm_flush(adpcm_state * s, unsigned char *out)
-{
-	int olen = 0;
-
-	if (s->nleft)
-		isdn_audio_put_bits(0, 8 - s->nleft, s, &out, &olen);
-	return olen;
-}
-
-int
 isdn_audio_xlaw2adpcm(adpcm_state * s, int fmt, unsigned char *in,
 		      unsigned char *out, int len)
 {
diff --git a/drivers/isdn/i4l/isdn_audio.h b/drivers/isdn/i4l/isdn_audio.h
--- a/drivers/isdn/i4l/isdn_audio.h
+++ b/drivers/isdn/i4l/isdn_audio.h
@@ -35,7 +35,6 @@ extern void isdn_audio_alaw2ulaw(unsigne
 extern adpcm_state *isdn_audio_adpcm_init(adpcm_state *, int);
 extern int isdn_audio_adpcm2xlaw(adpcm_state *, int, unsigned char *, unsigned char *, int);
 extern int isdn_audio_xlaw2adpcm(adpcm_state *, int, unsigned char *, unsigned char *, int);
-extern int isdn_audio_2adpcm_flush(adpcm_state * s, unsigned char *out);
 extern void isdn_audio_calc_dtmf(modem_info *, unsigned char *, int, int);
 extern void isdn_audio_eval_dtmf(modem_info *);
 dtmf_state *isdn_audio_dtmf_init(dtmf_state *);
diff --git a/drivers/isdn/i4l/isdn_common.c b/drivers/isdn/i4l/isdn_common.c
--- a/drivers/isdn/i4l/isdn_common.c
+++ b/drivers/isdn/i4l/isdn_common.c
@@ -67,7 +67,7 @@ static isdn_divert_if *divert_if; /* = N
 static int isdn_writebuf_stub(int, int, const u_char __user *, int);
 static void set_global_features(void);
 static int isdn_wildmat(char *s, char *p);
-
+static int isdn_add_channels(isdn_driver_t *d, int drvidx, int n, int adding);
 
 static inline void
 isdn_lock_driver(isdn_driver_t *drv)
@@ -388,7 +388,7 @@ isdn_all_eaz(int di, int ch)
  */
 #include <linux/isdn/capicmd.h>
 
-int
+static int
 isdn_capi_rec_hl_msg(capi_msg *cm) {
 	
 	int di;
@@ -1923,7 +1923,7 @@ isdn_writebuf_skb_stub(int drvidx, int c
 	return ret;
 }
 
-int
+static int
 isdn_add_channels(isdn_driver_t *d, int drvidx, int n, int adding)
 {
 	int j, k, m;
diff --git a/drivers/isdn/i4l/isdn_common.h b/drivers/isdn/i4l/isdn_common.h
--- a/drivers/isdn/i4l/isdn_common.h
+++ b/drivers/isdn/i4l/isdn_common.h
@@ -41,7 +41,6 @@ extern int  isdn_get_free_channel(int, i
 extern int  isdn_writebuf_skb_stub(int, int, int, struct sk_buff *);
 extern int  register_isdn(isdn_if * i);
 extern int  isdn_msncmp( const char *,  const char *);
-extern int  isdn_add_channels(isdn_driver_t *, int, int, int);
 #if defined(ISDN_DEBUG_NET_DUMP) || defined(ISDN_DEBUG_MODEM_DUMP)
 extern void isdn_dumppkt(char *, u_char *, int, int);
 #endif
diff --git a/drivers/isdn/i4l/isdn_concap.c b/drivers/isdn/i4l/isdn_concap.c
--- a/drivers/isdn/i4l/isdn_concap.c
+++ b/drivers/isdn/i4l/isdn_concap.c
@@ -39,7 +39,7 @@
    */
 
 
-int isdn_concap_dl_data_req(struct concap_proto *concap, struct sk_buff *skb)
+static int isdn_concap_dl_data_req(struct concap_proto *concap, struct sk_buff *skb)
 {
 	struct net_device *ndev = concap -> net_dev;
 	isdn_net_dev *nd = ((isdn_net_local *) ndev->priv)->netdev;
@@ -58,7 +58,7 @@ int isdn_concap_dl_data_req(struct conca
 }
 
 
-int isdn_concap_dl_connect_req(struct concap_proto *concap)
+static int isdn_concap_dl_connect_req(struct concap_proto *concap)
 {
 	struct net_device *ndev = concap -> net_dev;
 	isdn_net_local *lp = (isdn_net_local *) ndev->priv;
@@ -71,7 +71,7 @@ int isdn_concap_dl_connect_req(struct co
 	return ret;
 }
 
-int isdn_concap_dl_disconn_req(struct concap_proto *concap)
+static int isdn_concap_dl_disconn_req(struct concap_proto *concap)
 {
 	IX25DEBUG( "isdn_concap_dl_disconn_req: %s \n", concap -> net_dev -> name);
 
@@ -85,15 +85,6 @@ struct concap_device_ops isdn_concap_rel
 	&isdn_concap_dl_disconn_req
 };
 
-struct concap_device_ops isdn_concap_demand_dial_dops = {
-	NULL, /* set this first entry to something like &isdn_net_start_xmit,
-		 but the entry part of the current isdn_net_start_xmit must be
-		 separated first. */
-	/* no connection control for demand dial semantics */
-	NULL,
-	NULL,
-};
-
 /* The following should better go into a dedicated source file such that
    this sourcefile does not need to include any protocol specific header
    files. For now:
diff --git a/drivers/isdn/i4l/isdn_concap.h b/drivers/isdn/i4l/isdn_concap.h
--- a/drivers/isdn/i4l/isdn_concap.h
+++ b/drivers/isdn/i4l/isdn_concap.h
@@ -8,7 +8,6 @@
  */
 
 extern struct concap_device_ops isdn_concap_reliable_dl_dops;
-extern struct concap_device_ops isdn_concap_demand_dial_dops;
 extern struct concap_proto * isdn_concap_new( int );
 
 
diff --git a/drivers/isdn/i4l/isdn_net.c b/drivers/isdn/i4l/isdn_net.c
--- a/drivers/isdn/i4l/isdn_net.c
+++ b/drivers/isdn/i4l/isdn_net.c
@@ -176,7 +176,7 @@ static __inline__ void isdn_net_zero_fra
 
 /* Prototypes */
 
-int isdn_net_force_dial_lp(isdn_net_local *);
+static int isdn_net_force_dial_lp(isdn_net_local *);
 static int isdn_net_start_xmit(struct sk_buff *, struct net_device *);
 
 static void isdn_net_ciscohdlck_connected(isdn_net_local *lp);
@@ -312,7 +312,7 @@ isdn_net_unbind_channel(isdn_net_local *
  * Since this function is called every second, simply reset the
  * byte-counter of the interface after copying it to the cps-variable.
  */
-unsigned long last_jiffies = -HZ;
+static unsigned long last_jiffies = -HZ;
 
 void
 isdn_net_autohup(void)
@@ -1131,7 +1131,7 @@ isdn_net_adjust_hdr(struct sk_buff *skb,
 }
 
 
-void isdn_net_tx_timeout(struct net_device * ndev)
+static void isdn_net_tx_timeout(struct net_device * ndev)
 {
 	isdn_net_local *lp = (isdn_net_local *) ndev->priv;
 
@@ -1424,7 +1424,7 @@ isdn_net_ciscohdlck_alloc_skb(isdn_net_l
 }
 
 /* cisco hdlck device private ioctls */
-int
+static int
 isdn_ciscohdlck_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 {
 	isdn_net_local *lp = (isdn_net_local *) dev->priv;
@@ -2461,7 +2461,7 @@ isdn_net_findif(char *name)
  * This is called from the userlevel-routine below or
  * from isdn_net_start_xmit().
  */
-int
+static int
 isdn_net_force_dial_lp(isdn_net_local * lp)
 {
 	if ((!(lp->flags & ISDN_NET_CONNECTED)) && !lp->dialstate) {
diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c
--- a/drivers/isdn/i4l/isdn_tty.c
+++ b/drivers/isdn/i4l/isdn_tty.c
@@ -273,7 +273,7 @@ isdn_tty_rcv_skb(int i, int di, int chan
 	return 1;
 }
 
-void
+static void
 isdn_tty_cleanup_xmit(modem_info * info)
 {
 	skb_queue_purge(&info->xmit_queue);
@@ -560,7 +560,7 @@ isdn_tty_modem_ncarrier(modem_info * inf
 /*
  * return the usage calculated by si and layer 2 protocol
  */
-int
+static int
 isdn_calc_usage(int si, int l2)
 {
 	int usg = ISDN_USAGE_MODEM;
@@ -1223,7 +1223,7 @@ isdn_tty_write(struct tty_struct *tty, c
 		total += c;
 	}
 	atomic_dec(&info->xmit_lock);
-	if ((info->xmit_count) || (skb_queue_len(&info->xmit_queue))) {
+	if ((info->xmit_count) || !skb_queue_empty(&info->xmit_queue)) {
 		if (m->mdmreg[REG_DXMT] & BIT_DXMT) {
 			isdn_tty_senddown(info);
 			isdn_tty_tint(info);
@@ -1284,7 +1284,7 @@ isdn_tty_flush_chars(struct tty_struct *
 
 	if (isdn_tty_paranoia_check(info, tty->name, "isdn_tty_flush_chars"))
 		return;
-	if ((info->xmit_count) || (skb_queue_len(&info->xmit_queue)))
+	if ((info->xmit_count) || !skb_queue_empty(&info->xmit_queue))
 		isdn_timer_ctrl(ISDN_TIMER_MODEMXMIT, 1);
 }
 
diff --git a/drivers/isdn/i4l/isdn_tty.h b/drivers/isdn/i4l/isdn_tty.h
--- a/drivers/isdn/i4l/isdn_tty.h
+++ b/drivers/isdn/i4l/isdn_tty.h
@@ -109,7 +109,6 @@ extern int  isdn_tty_modem_init(void);
 extern void isdn_tty_exit(void);
 extern void isdn_tty_readmodem(void);
 extern int  isdn_tty_find_icall(int, int, setup_parm *);
-extern void isdn_tty_cleanup_xmit(modem_info *);
 extern int  isdn_tty_stat_callback(int, isdn_ctrl *);
 extern int  isdn_tty_rcv_skb(int, int, int, struct sk_buff *);
 extern int  isdn_tty_capi_facility(capi_msg *cm); 
diff --git a/drivers/isdn/i4l/isdn_ttyfax.c b/drivers/isdn/i4l/isdn_ttyfax.c
--- a/drivers/isdn/i4l/isdn_ttyfax.c
+++ b/drivers/isdn/i4l/isdn_ttyfax.c
@@ -148,7 +148,7 @@ isdn_tty_fax_modem_result(int code, mode
 	}
 }
 
-int
+static int
 isdn_tty_fax_command1(modem_info * info, isdn_ctrl * c)
 {
 	static char *msg[] =
@@ -316,7 +316,7 @@ isdn_tty_fax_bitorder(modem_info * info,
  * Parse AT+F.. FAX class 1 commands
  */
 
-int
+static int
 isdn_tty_cmd_FCLASS1(char **p, modem_info * info)
 {
 	static char *cmd[] =
@@ -408,7 +408,7 @@ isdn_tty_cmd_FCLASS1(char **p, modem_inf
  * Parse AT+F.. FAX class 2 commands
  */
 
-int
+static int
 isdn_tty_cmd_FCLASS2(char **p, modem_info * info)
 {
 	atemu *m = &info->emu;
diff --git a/drivers/isdn/i4l/isdn_x25iface.c b/drivers/isdn/i4l/isdn_x25iface.c
--- a/drivers/isdn/i4l/isdn_x25iface.c
+++ b/drivers/isdn/i4l/isdn_x25iface.c
@@ -40,15 +40,15 @@ typedef struct isdn_x25iface_proto_data 
 
 
 /* is now in header file (extern): struct concap_proto * isdn_x25iface_proto_new(void); */
-void isdn_x25iface_proto_del( struct concap_proto * );
-int isdn_x25iface_proto_close( struct concap_proto * );
-int isdn_x25iface_proto_restart( struct concap_proto *,
-				 struct net_device *,
-				 struct concap_device_ops *);
-int isdn_x25iface_xmit( struct concap_proto *, struct sk_buff * );
-int isdn_x25iface_receive( struct concap_proto *, struct sk_buff * );
-int isdn_x25iface_connect_ind( struct concap_proto * );
-int isdn_x25iface_disconn_ind( struct concap_proto * );
+static void isdn_x25iface_proto_del( struct concap_proto * );
+static int isdn_x25iface_proto_close( struct concap_proto * );
+static int isdn_x25iface_proto_restart( struct concap_proto *,
+					struct net_device *,
+					struct concap_device_ops *);
+static int isdn_x25iface_xmit( struct concap_proto *, struct sk_buff * );
+static int isdn_x25iface_receive( struct concap_proto *, struct sk_buff * );
+static int isdn_x25iface_connect_ind( struct concap_proto * );
+static int isdn_x25iface_disconn_ind( struct concap_proto * );
 
 
 static struct concap_proto_ops ix25_pops = {
@@ -102,7 +102,7 @@ struct concap_proto * isdn_x25iface_prot
 
 /* close the x25iface encapsulation protocol 
  */
-int isdn_x25iface_proto_close(struct concap_proto *cprot){
+static int isdn_x25iface_proto_close(struct concap_proto *cprot){
 
 	ix25_pdata_t *tmp;
         int ret = 0;
@@ -129,7 +129,7 @@ int isdn_x25iface_proto_close(struct con
 
 /* Delete the x25iface encapsulation protocol instance
  */
-void isdn_x25iface_proto_del(struct concap_proto *cprot){
+static void isdn_x25iface_proto_del(struct concap_proto *cprot){
 
 	ix25_pdata_t * tmp;
  
@@ -158,9 +158,9 @@ void isdn_x25iface_proto_del(struct conc
 
 /* (re-)initialize the data structures for x25iface encapsulation
  */
-int isdn_x25iface_proto_restart(struct concap_proto *cprot,
-				struct net_device *ndev, 
-				struct concap_device_ops *dops)
+static int isdn_x25iface_proto_restart(struct concap_proto *cprot,
+					struct net_device *ndev,
+					struct concap_device_ops *dops)
 {
 	ix25_pdata_t * pda = cprot -> proto_data ;
 	ulong flags;
@@ -187,7 +187,7 @@ int isdn_x25iface_proto_restart(struct c
 
 /* deliver a dl_data frame received from i4l HL driver to the network layer 
  */
-int isdn_x25iface_receive(struct concap_proto *cprot, struct sk_buff *skb)
+static int isdn_x25iface_receive(struct concap_proto *cprot, struct sk_buff *skb)
 {
   	IX25DEBUG( "isdn_x25iface_receive %s \n", MY_DEVNAME(cprot->net_dev) );
 	if ( ( (ix25_pdata_t*) (cprot->proto_data) ) 
@@ -206,7 +206,7 @@ int isdn_x25iface_receive(struct concap_
 
 /* a connection set up is indicated by lower layer 
  */
-int isdn_x25iface_connect_ind(struct concap_proto *cprot)
+static int isdn_x25iface_connect_ind(struct concap_proto *cprot)
 {
 	struct sk_buff * skb = dev_alloc_skb(1);
 	enum wan_states *state_p 
@@ -235,7 +235,7 @@ int isdn_x25iface_connect_ind(struct con
 	
 /* a disconnect is indicated by lower layer 
  */
-int isdn_x25iface_disconn_ind(struct concap_proto *cprot)
+static int isdn_x25iface_disconn_ind(struct concap_proto *cprot)
 {
 	struct sk_buff *skb;
 	enum wan_states *state_p 
@@ -264,7 +264,7 @@ int isdn_x25iface_disconn_ind(struct con
 /* process a frame handed over to us from linux network layer. First byte
    semantics as defined in Documentation/networking/x25-iface.txt
    */
-int isdn_x25iface_xmit(struct concap_proto *cprot, struct sk_buff *skb)
+static int isdn_x25iface_xmit(struct concap_proto *cprot, struct sk_buff *skb)
 {
 	unsigned char firstbyte = skb->data[0];
 	enum wan_states *state = &((ix25_pdata_t*)cprot->proto_data)->state;
diff --git a/drivers/isdn/icn/icn.c b/drivers/isdn/icn/icn.c
--- a/drivers/isdn/icn/icn.c
+++ b/drivers/isdn/icn/icn.c
@@ -304,12 +304,12 @@ icn_pollbchan_send(int channel, icn_card
 	isdn_ctrl cmd;
 
 	if (!(card->sndcount[channel] || card->xskb[channel] ||
-	      skb_queue_len(&card->spqueue[channel])))
+	      !skb_queue_empty(&card->spqueue[channel])))
 		return;
 	if (icn_trymaplock_channel(card, mch)) {
 		while (sbfree && 
 		       (card->sndcount[channel] ||
-			skb_queue_len(&card->spqueue[channel]) ||
+			!skb_queue_empty(&card->spqueue[channel]) ||
 			card->xskb[channel])) {
 			spin_lock_irqsave(&card->lock, flags);
 			if (card->xmit_lock[channel]) {
@@ -1650,7 +1650,7 @@ static void __exit icn_exit(void)
 {
 	isdn_ctrl cmd;
 	icn_card *card = cards;
-	icn_card *last;
+	icn_card *last, *tmpcard;
 	int i;
 	unsigned long flags;
 
@@ -1670,8 +1670,9 @@ static void __exit icn_exit(void)
 			for (i = 0; i < ICN_BCH; i++)
 				icn_free_queue(card, i);
 		}
-		card = card->next;
+		tmpcard = card->next;
 		spin_unlock_irqrestore(&card->lock, flags);
+		card = tmpcard;
 	}
 	card = cards;
 	cards = NULL;
diff --git a/drivers/isdn/pcbit/callbacks.c b/drivers/isdn/pcbit/callbacks.c
--- a/drivers/isdn/pcbit/callbacks.c
+++ b/drivers/isdn/pcbit/callbacks.c
@@ -125,23 +125,6 @@ void cb_out_2(struct pcbit_dev * dev, st
 
 
 /*
- * Disconnect received (actually RELEASE COMPLETE) 
- * This means we were not able to establish connection with remote
- * Inform the big boss above
- */
-void cb_out_3(struct pcbit_dev * dev, struct pcbit_chan* chan,
-	      struct callb_data *data) 
-{
-        isdn_ctrl ictl;
-
-        ictl.command = ISDN_STAT_DHUP;
-        ictl.driver=dev->id;
-        ictl.arg=chan->id;
-        dev->dev_if->statcallb(&ictl);
-}
-
-
-/*
  * Incoming call received
  * inform user
  */
diff --git a/drivers/isdn/pcbit/callbacks.h b/drivers/isdn/pcbit/callbacks.h
--- a/drivers/isdn/pcbit/callbacks.h
+++ b/drivers/isdn/pcbit/callbacks.h
@@ -19,9 +19,6 @@ extern void cb_out_1(struct pcbit_dev * 
 extern void cb_out_2(struct pcbit_dev * dev, struct pcbit_chan* chan, 
 		     struct callb_data *data);
 
-extern void cb_out_3(struct pcbit_dev * dev, struct pcbit_chan* chan, 
-		     struct callb_data *data);
-
 extern void cb_in_1(struct pcbit_dev * dev, struct pcbit_chan* chan, 
 		    struct callb_data *data);
 extern void cb_in_2(struct pcbit_dev * dev, struct pcbit_chan* chan, 
diff --git a/drivers/isdn/pcbit/capi.c b/drivers/isdn/pcbit/capi.c
--- a/drivers/isdn/pcbit/capi.c
+++ b/drivers/isdn/pcbit/capi.c
@@ -627,16 +627,6 @@ int capi_decode_disc_ind(struct pcbit_ch
         return 0;
 }
 
-int capi_decode_disc_conf(struct pcbit_chan *chan, struct sk_buff *skb)
-{
-        ushort errcode;
-
-        errcode = *((ushort*) skb->data);
-        skb_pull(skb, 2);
-
-        return errcode;                
-}
-
 #ifdef DEBUG
 int capi_decode_debug_188(u_char *hdr, ushort hdrlen)
 {
diff --git a/drivers/isdn/pcbit/capi.h b/drivers/isdn/pcbit/capi.h
--- a/drivers/isdn/pcbit/capi.h
+++ b/drivers/isdn/pcbit/capi.h
@@ -54,7 +54,6 @@ extern int capi_tdata_resp(struct pcbit_
 
 /* Connection Termination */
 extern int capi_disc_req(ushort callref, struct sk_buff **skb, u_char cause);
-extern int capi_decode_disc_conf(struct pcbit_chan *chan, struct sk_buff *skb);
 
 extern int capi_decode_disc_ind(struct pcbit_chan *chan, struct sk_buff *skb);
 extern int capi_disc_resp(struct pcbit_chan *chan, struct sk_buff **skb);
diff --git a/drivers/isdn/pcbit/drv.c b/drivers/isdn/pcbit/drv.c
--- a/drivers/isdn/pcbit/drv.c
+++ b/drivers/isdn/pcbit/drv.c
@@ -56,10 +56,10 @@ static char* pcbit_devname[MAX_PCBIT_CAR
  * prototypes
  */
 
-int pcbit_command(isdn_ctrl* ctl);
-int pcbit_stat(u_char __user * buf, int len, int, int);
-int pcbit_xmit(int driver, int chan, int ack, struct sk_buff *skb);
-int pcbit_writecmd(const u_char __user *, int, int, int);
+static int pcbit_command(isdn_ctrl* ctl);
+static int pcbit_stat(u_char __user * buf, int len, int, int);
+static int pcbit_xmit(int driver, int chan, int ack, struct sk_buff *skb);
+static int pcbit_writecmd(const u_char __user *, int, int, int);
 
 static int set_protocol_running(struct pcbit_dev * dev);
 
@@ -238,7 +238,7 @@ void pcbit_terminate(int board)
 }
 #endif
 
-int pcbit_command(isdn_ctrl* ctl)
+static int pcbit_command(isdn_ctrl* ctl)
 {
 	struct pcbit_dev  *dev;
 	struct pcbit_chan *chan;
@@ -330,7 +330,7 @@ static void pcbit_block_timer(unsigned l
 }
 #endif
 
-int pcbit_xmit(int driver, int chnum, int ack, struct sk_buff *skb)
+static int pcbit_xmit(int driver, int chnum, int ack, struct sk_buff *skb)
 {
 	ushort hdrlen;
 	int refnum, len;
@@ -389,7 +389,7 @@ int pcbit_xmit(int driver, int chnum, in
 	return len;
 }
 
-int pcbit_writecmd(const u_char __user *buf, int len, int driver, int channel)
+static int pcbit_writecmd(const u_char __user *buf, int len, int driver, int channel)
 {
 	struct pcbit_dev * dev;
 	int i, j;
@@ -713,7 +713,7 @@ static char statbuf[STATBUF_LEN];
 static int stat_st = 0;
 static int stat_end = 0;
 
-int pcbit_stat(u_char __user *buf, int len, int driver, int channel)
+static int pcbit_stat(u_char __user *buf, int len, int driver, int channel)
 {
 	int stat_count;
 	stat_count = stat_end - stat_st;
diff --git a/drivers/isdn/sc/Makefile b/drivers/isdn/sc/Makefile
--- a/drivers/isdn/sc/Makefile
+++ b/drivers/isdn/sc/Makefile
@@ -6,5 +6,5 @@ obj-$(CONFIG_ISDN_DRV_SC)	+= sc.o
 
 # Multipart objects.
 
-sc-y				:= shmem.o init.o debug.o packet.o command.o event.o \
+sc-y				:= shmem.o init.o packet.o command.o event.o \
 		   		   ioctl.o interrupt.o message.o timer.o	
diff --git a/drivers/isdn/sc/command.c b/drivers/isdn/sc/command.c
--- a/drivers/isdn/sc/command.c
+++ b/drivers/isdn/sc/command.c
@@ -22,14 +22,14 @@
 #include "card.h"
 #include "scioc.h"
 
-int dial(int card, unsigned long channel, setup_parm setup);
-int hangup(int card, unsigned long channel);
-int answer(int card, unsigned long channel);
-int clreaz(int card, unsigned long channel);
-int seteaz(int card, unsigned long channel, char *);
-int setl2(int card, unsigned long arg);
-int setl3(int card, unsigned long arg);
-int acceptb(int card, unsigned long channel);
+static int dial(int card, unsigned long channel, setup_parm setup);
+static int hangup(int card, unsigned long channel);
+static int answer(int card, unsigned long channel);
+static int clreaz(int card, unsigned long channel);
+static int seteaz(int card, unsigned long channel, char *);
+static int setl2(int card, unsigned long arg);
+static int setl3(int card, unsigned long arg);
+static int acceptb(int card, unsigned long channel);
 
 extern int cinst;
 extern board *sc_adapter[];
@@ -148,56 +148,6 @@ int command(isdn_ctrl *cmd)
 }
 
 /*
- * Confirm our ability to communicate with the board.  This test assumes no
- * other message activity is present
- */
-int loopback(int card) 
-{
-
-	int status;
-	static char testmsg[] = "Test Message";
-	RspMessage rspmsg;
-
-	if(!IS_VALID_CARD(card)) {
-		pr_debug("Invalid param: %d is not a valid card id\n", card);
-		return -ENODEV;
-	}
-
-	pr_debug("%s: Sending loopback message\n",
-		sc_adapter[card]->devicename);
-
-	/*
-	 * Send the loopback message to confirm that memory transfer is
-	 * operational
-	 */
-	status = send_and_receive(card, CMPID, cmReqType1,
-				  cmReqClass0,
-				  cmReqMsgLpbk,
-				  0,
-				  (unsigned char) strlen(testmsg),
-				  (unsigned char *)testmsg,
-				  &rspmsg, SAR_TIMEOUT);
-
-
-	if (!status) {
-		pr_debug("%s: Loopback message successfully sent\n",
-			sc_adapter[card]->devicename);
-		if(strcmp(rspmsg.msg_data.byte_array, testmsg)) {
-			pr_debug("%s: Loopback return != sent\n",
-				sc_adapter[card]->devicename);
-			return -EIO;
-		}
-		return 0;
-	}
-	else {
-		pr_debug("%s: Send loopback message failed\n",
-			sc_adapter[card]->devicename);
-		return -EIO;
-	}
-
-}
-
-/*
  * start the onboard firmware
  */
 int startproc(int card) 
@@ -222,16 +172,10 @@ int startproc(int card) 
 }
 
 
-int loadproc(int card, char *data) 
-{
-	return -1;
-}
-
-
 /*
  * Dials the number passed in 
  */
-int dial(int card, unsigned long channel, setup_parm setup) 
+static int dial(int card, unsigned long channel, setup_parm setup)
 {
 	int status;
 	char Phone[48];
@@ -261,7 +205,7 @@ int dial(int card, unsigned long channel
 /*
  * Answer an incoming call 
  */
-int answer(int card, unsigned long channel) 
+static int answer(int card, unsigned long channel)
 {
 	if(!IS_VALID_CARD(card)) {
 		pr_debug("Invalid param: %d is not a valid card id\n", card);
@@ -282,7 +226,7 @@ int answer(int card, unsigned long chann
 /*
  * Hangup up the call on specified channel
  */
-int hangup(int card, unsigned long channel) 
+static int hangup(int card, unsigned long channel)
 {
 	int status;
 
@@ -305,7 +249,7 @@ int hangup(int card, unsigned long chann
 /*
  * Set the layer 2 protocol (X.25, HDLC, Raw)
  */
-int setl2(int card, unsigned long arg) 
+static int setl2(int card, unsigned long arg)
 {
 	int status =0;
 	int protocol,channel;
@@ -340,7 +284,7 @@ int setl2(int card, unsigned long arg) 
 /*
  * Set the layer 3 protocol
  */
-int setl3(int card, unsigned long channel) 
+static int setl3(int card, unsigned long channel)
 {
 	int protocol = channel >> 8;
 
@@ -355,7 +299,7 @@ int setl3(int card, unsigned long channe
 	return 0;
 }
 
-int acceptb(int card, unsigned long channel)
+static int acceptb(int card, unsigned long channel)
 {
 	if(!IS_VALID_CARD(card)) {
 		pr_debug("Invalid param: %d is not a valid card id\n", card);
@@ -374,7 +318,7 @@ int acceptb(int card, unsigned long chan
 	return 0;
 }
 
-int clreaz(int card, unsigned long arg)
+static int clreaz(int card, unsigned long arg)
 {
 	if(!IS_VALID_CARD(card)) {
 		pr_debug("Invalid param: %d is not a valid card id\n", card);
@@ -388,7 +332,7 @@ int clreaz(int card, unsigned long arg)
 	return 0;
 }
 
-int seteaz(int card, unsigned long arg, char *num)
+static int seteaz(int card, unsigned long arg, char *num)
 {
 	if(!IS_VALID_CARD(card)) {
 		pr_debug("Invalid param: %d is not a valid card id\n", card);
diff --git a/drivers/isdn/sc/debug.c b/drivers/isdn/sc/debug.c
deleted file mode 100644
--- a/drivers/isdn/sc/debug.c
+++ /dev/null
@@ -1,46 +0,0 @@
-/* $Id: debug.c,v 1.5.6.1 2001/09/23 22:24:59 kai Exp $
- *
- * Copyright (C) 1996  SpellCaster Telecommunications Inc.
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- * For more information, please contact gpl-info@spellcast.com or write:
- *
- *     SpellCaster Telecommunications Inc.
- *     5621 Finch Avenue East, Unit #3
- *     Scarborough, Ontario  Canada
- *     M1B 2T9
- *     +1 (416) 297-8565
- *     +1 (416) 297-6433 Facsimile
- */
-
-#include <linux/kernel.h>
-#include <linux/string.h>
-
-int dbg_level = 0;
-static char dbg_funcname[255];
-
-void dbg_endfunc(void)
-{
-	if (dbg_level) {
-		printk("<-- Leaving function %s\n", dbg_funcname);
-		strcpy(dbg_funcname, "");
-	}
-}
-
-void dbg_func(char *func)
-{
-	strcpy(dbg_funcname, func);
-	if(dbg_level)
-		printk("--> Entering function %s\n", dbg_funcname);
-}
-
-inline void pullphone(char *dn, char *str)
-{
-	int i = 0;
-
-	while(dn[i] != ',')
-		str[i] = dn[i], i++;
-	str[i] = 0x0;
-}
diff --git a/drivers/isdn/sc/init.c b/drivers/isdn/sc/init.c
--- a/drivers/isdn/sc/init.c
+++ b/drivers/isdn/sc/init.c
@@ -20,9 +20,9 @@ board *sc_adapter[MAX_CARDS];
 int cinst;
 
 static char devname[] = "scX";
-const char version[] = "2.0b1";
+static const char version[] = "2.0b1";
 
-const char *boardname[] = { "DataCommute/BRI", "DataCommute/PRI", "TeleCommute/BRI" };
+static const char *boardname[] = { "DataCommute/BRI", "DataCommute/PRI", "TeleCommute/BRI" };
 
 /* insmod set parameters */
 static unsigned int io[] = {0,0,0,0};
@@ -35,26 +35,13 @@ module_param_array(irq, int, NULL, 0);
 module_param_array(ram, int, NULL, 0);
 module_param(do_reset, bool, 0);
 
-static int sup_irq[] = { 11, 10, 9, 5, 12, 14, 7, 3, 4, 6 };
-#define MAX_IRQS	10
-
 extern irqreturn_t interrupt_handler(int, void *, struct pt_regs *);
 extern int sndpkt(int, int, int, struct sk_buff *);
 extern int command(isdn_ctrl *);
 extern int indicate_status(int, int, ulong, char*);
 extern int reset(int);
 
-int identify_board(unsigned long, unsigned int);
-
-int irq_supported(int irq_x)
-{
-	int i;
-	for(i=0 ; i < MAX_IRQS ; i++) {
-		if(sup_irq[i] == irq_x)
-			return 1;
-	}
-	return 0;
-}
+static int identify_board(unsigned long, unsigned int);
 
 static int __init sc_init(void)
 {
@@ -454,7 +441,7 @@ static void __exit sc_exit(void)
 	pr_info("SpellCaster ISA ISDN Adapter Driver Unloaded.\n");
 }
 
-int identify_board(unsigned long rambase, unsigned int iobase) 
+static int identify_board(unsigned long rambase, unsigned int iobase)
 {
 	unsigned int pgport;
 	unsigned long sig;
diff --git a/drivers/isdn/sc/interrupt.c b/drivers/isdn/sc/interrupt.c
--- a/drivers/isdn/sc/interrupt.c
+++ b/drivers/isdn/sc/interrupt.c
@@ -31,7 +31,7 @@ extern void rcvpkt(int, RspMessage *);
 extern int cinst;
 extern board *sc_adapter[];
 
-int get_card_from_irq(int irq)
+static int get_card_from_irq(int irq)
 {
 	int i;
 
diff --git a/drivers/isdn/sc/ioctl.c b/drivers/isdn/sc/ioctl.c
--- a/drivers/isdn/sc/ioctl.c
+++ b/drivers/isdn/sc/ioctl.c
@@ -14,7 +14,6 @@
 
 extern int indicate_status(int, int, unsigned long, char *);
 extern int startproc(int);
-extern int loadproc(int, char *record);
 extern int reset(int);
 extern int send_and_receive(int, unsigned int, unsigned char,unsigned char,
 		unsigned char,unsigned char, 
@@ -23,7 +22,7 @@ extern int send_and_receive(int, unsigne
 extern board *sc_adapter[];
 
 
-int GetStatus(int card, boardInfo *);
+static int GetStatus(int card, boardInfo *);
 
 /*
  * Process private IOCTL messages (typically from scctrl)
@@ -428,7 +427,7 @@ int sc_ioctl(int card, scs_ioctl *data)
 	return 0;
 }
 
-int GetStatus(int card, boardInfo *bi)
+static int GetStatus(int card, boardInfo *bi)
 {
 	RspMessage rcvmsg;
 	int i, status;
diff --git a/drivers/isdn/sc/packet.c b/drivers/isdn/sc/packet.c
--- a/drivers/isdn/sc/packet.c
+++ b/drivers/isdn/sc/packet.c
@@ -213,19 +213,3 @@ int setup_buffers(int card, int c)
 	return 0;
 }
 
-int print_skb(int card,char *skb_p, int len){
-	int i,data;
-	pr_debug("%s: data at 0x%x len: 0x%x\n", sc_adapter[card]->devicename,
-			skb_p,len);
-	for(i=1;i<=len;i++,skb_p++){
-		data = (int) (0xff & (*skb_p));
-		pr_debug("%s: data =  0x%x", sc_adapter[card]->devicename,data);
-		if(!(i%4))
-			pr_debug(" ");
-		if(!(i%32))
-			pr_debug("\n");
-	}
-	pr_debug("\n");
-	return 0;
-}		
-
diff --git a/drivers/isdn/sc/shmem.c b/drivers/isdn/sc/shmem.c
--- a/drivers/isdn/sc/shmem.c
+++ b/drivers/isdn/sc/shmem.c
@@ -108,6 +108,7 @@ void memcpy_fromshmem(int card, void *de
 		sc_adapter[card]->rambase + ((unsigned long) src %0x4000), (unsigned long) dest); */
 }
 
+#if 0
 void memset_shmem(int card, void *dest, int c, size_t n)
 {
 	unsigned long flags;
@@ -141,3 +142,4 @@ void memset_shmem(int card, void *dest, 
 		((sc_adapter[card]->shmem_magic + ch * SRAM_PAGESIZE)>>14)|0x80);
 	spin_unlock_irqrestore(&sc_adapter[card]->lock, flags);
 }
+#endif  /*  0  */
diff --git a/drivers/isdn/sc/timer.c b/drivers/isdn/sc/timer.c
--- a/drivers/isdn/sc/timer.c
+++ b/drivers/isdn/sc/timer.c
@@ -32,7 +32,7 @@ extern int  sendmessage(int, unsigned in
 /*
  * Write the proper values into the I/O ports following a reset
  */
-void setup_ports(int card)
+static void setup_ports(int card)
 {
 
 	outb((sc_adapter[card]->rambase >> 12), sc_adapter[card]->ioport[EXP_BASE]);
@@ -129,19 +129,3 @@ void check_phystat(unsigned long data)
 		ceReqPhyStatus,0,0,NULL);
 }
 
-/*
- * When in trace mode, this callback is used to swap the working shared
- * RAM page to the trace page(s) and process all received messages. It
- * must be called often enough to get all of the messages out of RAM before
- * it loops around.
- * Trace messages are \n terminated strings.
- * We output the messages in 64 byte chunks through readstat. Each chunk
- * is scanned for a \n followed by a time stamp. If the timerstamp is older
- * than the current time, scanning stops and the page and offset are recorded
- * as the starting point the next time the trace timer is called. The final
- * step is to restore the working page and reset the timer.
- */
-void trace_timer(unsigned long data)
-{
-	/* not implemented */
-}
diff --git a/drivers/macintosh/Kconfig b/drivers/macintosh/Kconfig
--- a/drivers/macintosh/Kconfig
+++ b/drivers/macintosh/Kconfig
@@ -4,7 +4,7 @@ menu "Macintosh device drivers"
 
 config ADB
 	bool "Apple Desktop Bus (ADB) support"
-	depends on MAC || PPC_PMAC
+	depends on MAC || (PPC_PMAC && PPC32)
 	help
 	  Apple Desktop Bus (ADB) support is for support of devices which
 	  are connected to an ADB port.  ADB devices tend to have 4 pins.
@@ -86,39 +86,24 @@ config PMAC_SMU
 	  on the "SMU" system control chip which replaces the old PMU.
 	  If you don't know, say Y.
 
-config PMAC_PBOOK
-	bool "Power management support for PowerBooks"
-	depends on ADB_PMU
-	---help---
-	  This provides support for putting a PowerBook to sleep; it also
-	  enables media bay support.  Power management works on the
-	  PB2400/3400/3500, Wallstreet, Lombard, and Bronze PowerBook G3 and
-	  the Titanium Powerbook G4, as well as the iBooks.  You should get
-	  the power management daemon, pmud, to make it work and you must have
-	  the /dev/pmu device (see the pmud README).
-
-	  Get pmud from <ftp://ftp.samba.org/pub/ppclinux/pmud/>.
-
-	  If you have a PowerBook, you should say Y here.
-
-	  You may also want to compile the dma sound driver as a module and
-	  have it autoloaded. The act of removing the module shuts down the
-	  sound hardware for more power savings.
-
-config PM
-	bool
-	depends on PPC_PMAC && ADB_PMU && PMAC_PBOOK
-	default y
-
 config PMAC_APM_EMU
 	tristate "APM emulation"
-	depends on PMAC_PBOOK
+	depends on PPC_PMAC && PPC32 && PM
+
+config PMAC_MEDIABAY
+	bool "Support PowerBook hotswap media bay"
+	depends on PPC_PMAC && PPC32
+	help
+	  This option adds support for older PowerBook's hotswap media bay
+	  that can contains batteries, floppy drives, or IDE devices. PCI
+	  devices are not fully supported in the bay as I never had one to
+	  try with
 
 # made a separate option since backlight may end up beeing used
 # on non-powerbook machines (but only on PMU based ones AFAIK)
 config PMAC_BACKLIGHT
 	bool "Backlight control for LCD screens"
-	depends on ADB_PMU
+	depends on ADB_PMU && (BROKEN || !PPC64)
 	help
 	  Say Y here to build in code to manage the LCD backlight on a
 	  Macintosh PowerBook.  With this code, the backlight will be turned
@@ -126,13 +111,6 @@ config PMAC_BACKLIGHT
 	  events; also, the PowerBook button device will be enabled so you can
 	  change the screen brightness.
 
-config MAC_SERIAL
-	tristate "Support for PowerMac serial ports (OBSOLETE DRIVER)"
-	depends on PPC_PMAC && BROKEN
-	help
-	  This driver is obsolete. Use CONFIG_SERIAL_PMACZILOG in
-	  "Character devices --> Serial drivers --> PowerMac z85c30" option.
-
 config ADB_MACIO
 	bool "Include MacIO (CHRP) ADB driver"
 	depends on ADB && PPC_CHRP && !PPC_PMAC64
diff --git a/drivers/macintosh/Makefile b/drivers/macintosh/Makefile
--- a/drivers/macintosh/Makefile
+++ b/drivers/macintosh/Makefile
@@ -4,10 +4,9 @@
 
 # Each configuration option enables a list of files.
 
-obj-$(CONFIG_PPC_PMAC)		+= macio_asic.o
+obj-$(CONFIG_PPC_PMAC)		+= macio_asic.o macio_sysfs.o
 
-obj-$(CONFIG_PMAC_PBOOK)	+= mediabay.o
-obj-$(CONFIG_MAC_SERIAL)	+= macserial.o
+obj-$(CONFIG_PMAC_MEDIABAY)	+= mediabay.o
 obj-$(CONFIG_MAC_EMUMOUSEBTN)	+= mac_hid.o
 obj-$(CONFIG_INPUT_ADBHID)	+= adbhid.o
 obj-$(CONFIG_ANSLCD)		+= ans-lcd.o
diff --git a/drivers/macintosh/adb.c b/drivers/macintosh/adb.c
--- a/drivers/macintosh/adb.c
+++ b/drivers/macintosh/adb.c
@@ -77,7 +77,7 @@ static struct adb_driver *adb_driver_lis
 	NULL
 };
 
-static struct class_simple *adb_dev_class;
+static struct class *adb_dev_class;
 
 struct adb_driver *adb_controller;
 struct notifier_block *adb_client_list = NULL;
@@ -90,7 +90,7 @@ static int sleepy_trackpad;
 static int autopoll_devs;
 int __adb_probe_sync;
 
-#ifdef CONFIG_PMAC_PBOOK
+#ifdef CONFIG_PM
 static int adb_notify_sleep(struct pmu_sleep_notifier *self, int when);
 static struct pmu_sleep_notifier adb_sleep_notifier = {
 	adb_notify_sleep,
@@ -320,9 +320,9 @@ int __init adb_init(void)
 		printk(KERN_WARNING "Warning: no ADB interface detected\n");
 		adb_controller = NULL;
 	} else {
-#ifdef CONFIG_PMAC_PBOOK
+#ifdef CONFIG_PM
 		pmu_register_sleep_notifier(&adb_sleep_notifier);
-#endif /* CONFIG_PMAC_PBOOK */
+#endif /* CONFIG_PM */
 #ifdef CONFIG_PPC
 		if (machine_is_compatible("AAPL,PowerBook1998") ||
 			machine_is_compatible("PowerBook1,1"))
@@ -337,7 +337,7 @@ int __init adb_init(void)
 
 __initcall(adb_init);
 
-#ifdef CONFIG_PMAC_PBOOK
+#ifdef CONFIG_PM
 /*
  * notify clients before sleep and reset bus afterwards
  */
@@ -378,7 +378,7 @@ adb_notify_sleep(struct pmu_sleep_notifi
 	}
 	return PBOOK_SLEEP_OK;
 }
-#endif /* CONFIG_PMAC_PBOOK */
+#endif /* CONFIG_PM */
 
 static int
 do_adb_reset_bus(void)
@@ -902,9 +902,8 @@ adbdev_init(void)
 
 	devfs_mk_cdev(MKDEV(ADB_MAJOR, 0), S_IFCHR | S_IRUSR | S_IWUSR, "adb");
 
-	adb_dev_class = class_simple_create(THIS_MODULE, "adb");
-	if (IS_ERR(adb_dev_class)) {
+	adb_dev_class = class_create(THIS_MODULE, "adb");
+	if (IS_ERR(adb_dev_class))
 		return;
-	}
-	class_simple_device_add(adb_dev_class, MKDEV(ADB_MAJOR, 0), NULL, "adb");
+	class_device_create(adb_dev_class, MKDEV(ADB_MAJOR, 0), NULL, "adb");
 }
diff --git a/drivers/macintosh/macio_asic.c b/drivers/macintosh/macio_asic.c
--- a/drivers/macintosh/macio_asic.c
+++ b/drivers/macintosh/macio_asic.c
@@ -33,7 +33,7 @@ static int macio_bus_match(struct device
 {
 	struct macio_dev * macio_dev = to_macio_device(dev);
 	struct macio_driver * macio_drv = to_macio_driver(drv);
-	const struct of_match * matches = macio_drv->match_table;
+	const struct of_device_id * matches = macio_drv->match_table;
 
 	if (!matches) 
 		return 0;
@@ -66,7 +66,7 @@ static int macio_device_probe(struct dev
 	int error = -ENODEV;
 	struct macio_driver *drv;
 	struct macio_dev *macio_dev;
-	const struct of_match *match;
+	const struct of_device_id *match;
 
 	drv = to_macio_driver(dev->driver);
 	macio_dev = to_macio_device(dev);
@@ -126,11 +126,85 @@ static int macio_device_resume(struct de
 	return 0;
 }
 
+static int macio_hotplug (struct device *dev, char **envp, int num_envp,
+                          char *buffer, int buffer_size)
+{
+	struct macio_dev * macio_dev;
+	struct of_device * of;
+	char *scratch, *compat;
+	int i = 0;
+	int length = 0;
+	int cplen, seen = 0;
+
+	if (!dev)
+		return -ENODEV;
+
+	macio_dev = to_macio_device(dev);
+	if (!macio_dev)
+		return -ENODEV;
+
+	of = &macio_dev->ofdev;
+	scratch = buffer;
+
+	/* stuff we want to pass to /sbin/hotplug */
+	envp[i++] = scratch;
+	length += scnprintf (scratch, buffer_size - length, "OF_NAME=%s",
+	                     of->node->name);
+	if ((buffer_size - length <= 0) || (i >= num_envp))
+		return -ENOMEM;
+	++length;
+	scratch += length;
+
+	envp[i++] = scratch;
+	length += scnprintf (scratch, buffer_size - length, "OF_TYPE=%s",
+	                     of->node->type);
+	if ((buffer_size - length <= 0) || (i >= num_envp))
+		return -ENOMEM;
+	++length;
+	scratch += length;
+
+        /* Since the compatible field can contain pretty much anything
+         * it's not really legal to split it out with commas. We split it
+         * up using a number of environment variables instead. */
+
+	compat = (char *) get_property(of->node, "compatible", &cplen);
+	while (compat && cplen > 0) {
+		int l;
+                envp[i++] = scratch;
+		length += scnprintf (scratch, buffer_size - length,
+		                     "OF_COMPATIBLE_%d=%s", seen, compat);
+		if ((buffer_size - length <= 0) || (i >= num_envp))
+			return -ENOMEM;
+		length++;
+		scratch += length;
+		l = strlen (compat) + 1;
+		compat += l;
+		cplen -= l;
+		seen++;
+	}
+
+	envp[i++] = scratch;
+	length += scnprintf (scratch, buffer_size - length,
+	                     "OF_COMPATIBLE_N=%d", seen);
+	if ((buffer_size - length <= 0) || (i >= num_envp))
+		return -ENOMEM;
+	++length;
+	scratch += length;
+
+	envp[i] = NULL;
+
+	return 0;
+}
+
+extern struct device_attribute macio_dev_attrs[];
+
 struct bus_type macio_bus_type = {
        .name	= "macio",
        .match	= macio_bus_match,
+       .hotplug = macio_hotplug,
        .suspend	= macio_device_suspend,
        .resume	= macio_device_resume,
+       .dev_attrs = macio_dev_attrs,
 };
 
 static int __init macio_bus_driver_init(void)
diff --git a/drivers/macintosh/macio_sysfs.c b/drivers/macintosh/macio_sysfs.c
new file mode 100644
--- /dev/null
+++ b/drivers/macintosh/macio_sysfs.c
@@ -0,0 +1,50 @@
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/stat.h>
+#include <asm/macio.h>
+
+
+#define macio_config_of_attr(field, format_string)			\
+static ssize_t								\
+field##_show (struct device *dev, struct device_attribute *attr,	\
+              char *buf)						\
+{									\
+	struct macio_dev *mdev = to_macio_device (dev);			\
+	return sprintf (buf, format_string, mdev->ofdev.node->field);	\
+}
+
+static ssize_t
+compatible_show (struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct of_device *of;
+	char *compat;
+	int cplen;
+	int length = 0;
+
+	of = &to_macio_device (dev)->ofdev;
+	compat = (char *) get_property(of->node, "compatible", &cplen);
+	if (!compat) {
+		*buf = '\0';
+		return 0;
+	}
+	while (cplen > 0) {
+		int l;
+		length += sprintf (buf, "%s\n", compat);
+		buf += length;
+		l = strlen (compat) + 1;
+		compat += l;
+		cplen -= l;
+	}
+
+	return length;
+}
+
+macio_config_of_attr (name, "%s\n");
+macio_config_of_attr (type, "%s\n");
+
+struct device_attribute macio_dev_attrs[] = {
+	__ATTR_RO(name),
+	__ATTR_RO(type),
+	__ATTR_RO(compatible),
+	__ATTR_NULL
+};
diff --git a/drivers/macintosh/macserial.c b/drivers/macintosh/macserial.c
deleted file mode 100644
--- a/drivers/macintosh/macserial.c
+++ /dev/null
@@ -1,3036 +0,0 @@
-/*
- * macserial.c: Serial port driver for Power Macintoshes.
- *
- * Derived from drivers/sbus/char/sunserial.c by Paul Mackerras.
- *
- * Copyright (C) 1996 Paul Mackerras (Paul.Mackerras@cs.anu.edu.au)
- * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
- *
- * Receive DMA code by Takashi Oe <toe@unlserve.unl.edu>.
- *
- * $Id: macserial.c,v 1.24.2.4 1999/10/19 04:36:42 paulus Exp $
- */
-
-#include <linux/config.h>
-#include <linux/errno.h>
-#include <linux/module.h>
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/timer.h>
-#include <linux/interrupt.h>
-#include <linux/workqueue.h>
-#include <linux/tty.h>
-#include <linux/tty_flip.h>
-#include <linux/major.h>
-#include <linux/string.h>
-#include <linux/fcntl.h>
-#include <linux/mm.h>
-#include <linux/kernel.h>
-#include <linux/delay.h>
-#include <linux/init.h>
-#ifdef CONFIG_SERIAL_CONSOLE
-#include <linux/console.h>
-#endif
-#include <linux/slab.h>
-#include <linux/bitops.h>
-
-#include <asm/sections.h>
-#include <asm/io.h>
-#include <asm/pgtable.h>
-#include <asm/irq.h>
-#include <asm/prom.h>
-#include <asm/system.h>
-#include <asm/segment.h>
-#include <asm/machdep.h>
-#include <asm/pmac_feature.h>
-#include <linux/adb.h>
-#include <linux/pmu.h>
-#ifdef CONFIG_KGDB
-#include <asm/kgdb.h>
-#endif
-#include <asm/dbdma.h>
-
-#include "macserial.h"
-
-#ifdef CONFIG_PMAC_PBOOK
-static int serial_notify_sleep(struct pmu_sleep_notifier *self, int when);
-static struct pmu_sleep_notifier serial_sleep_notifier = {
-	serial_notify_sleep,
-	SLEEP_LEVEL_MISC,
-};
-#endif
-
-#define SUPPORT_SERIAL_DMA
-#define MACSERIAL_VERSION	"2.0"
-
-/*
- * It would be nice to dynamically allocate everything that
- * depends on NUM_SERIAL, so we could support any number of
- * Z8530s, but for now...
- */
-#define NUM_SERIAL	2		/* Max number of ZS chips supported */
-#define NUM_CHANNELS	(NUM_SERIAL * 2)	/* 2 channels per chip */
-
-/* On PowerMacs, the hardware takes care of the SCC recovery time,
-   but we need the eieio to make sure that the accesses occur
-   in the order we want. */
-#define RECOVERY_DELAY	eieio()
-
-static struct tty_driver *serial_driver;
-
-struct mac_zschannel zs_channels[NUM_CHANNELS];
-
-struct mac_serial zs_soft[NUM_CHANNELS];
-int zs_channels_found;
-struct mac_serial *zs_chain;	/* list of all channels */
-
-struct tty_struct zs_ttys[NUM_CHANNELS];
-
-static int is_powerbook;
-
-#ifdef CONFIG_SERIAL_CONSOLE
-static struct console sercons;
-#endif
-
-#ifdef CONFIG_KGDB
-struct mac_zschannel *zs_kgdbchan;
-static unsigned char scc_inittab[] = {
-	9,  0x80,	/* reset A side (CHRA) */
-	13, 0,		/* set baud rate divisor */
-	12, 1,
-	14, 1,		/* baud rate gen enable, src=rtxc (BRENABL) */
-	11, 0x50,	/* clocks = br gen (RCBR | TCBR) */
-	5,  0x6a,	/* tx 8 bits, assert RTS (Tx8 | TxENAB | RTS) */
-	4,  0x44,	/* x16 clock, 1 stop (SB1 | X16CLK)*/
-	3,  0xc1,	/* rx enable, 8 bits (RxENABLE | Rx8)*/
-};
-#endif
-#define ZS_CLOCK         3686400 	/* Z8530 RTxC input clock rate */
-
-/* serial subtype definitions */
-#define SERIAL_TYPE_NORMAL	1
-
-/* number of characters left in xmit buffer before we ask for more */
-#define WAKEUP_CHARS 256
-
-/*
- * Debugging.
- */
-#undef SERIAL_DEBUG_INTR
-#undef SERIAL_DEBUG_OPEN
-#undef SERIAL_DEBUG_FLOW
-#undef SERIAL_DEBUG_POWER
-#undef SERIAL_DEBUG_THROTTLE
-#undef SERIAL_DEBUG_STOP
-#undef SERIAL_DEBUG_BAUDS
-
-#define RS_STROBE_TIME 10
-#define RS_ISR_PASS_LIMIT 256
-
-#define _INLINE_ inline
-
-#ifdef SERIAL_DEBUG_OPEN
-#define OPNDBG(fmt, arg...)	printk(KERN_DEBUG fmt , ## arg)
-#else
-#define OPNDBG(fmt, arg...)	do { } while (0)
-#endif
-#ifdef SERIAL_DEBUG_POWER
-#define PWRDBG(fmt, arg...)	printk(KERN_DEBUG fmt , ## arg)
-#else
-#define PWRDBG(fmt, arg...)	do { } while (0)
-#endif
-#ifdef SERIAL_DEBUG_BAUDS
-#define BAUDBG(fmt, arg...)	printk(fmt , ## arg)
-#else
-#define BAUDBG(fmt, arg...)	do { } while (0)
-#endif
-
-static void probe_sccs(void);
-static void change_speed(struct mac_serial *info, struct termios *old);
-static void rs_wait_until_sent(struct tty_struct *tty, int timeout);
-static int set_scc_power(struct mac_serial * info, int state);
-static int setup_scc(struct mac_serial * info);
-static void dbdma_reset(volatile struct dbdma_regs *dma);
-static void dbdma_flush(volatile struct dbdma_regs *dma);
-static irqreturn_t rs_txdma_irq(int irq, void *dev_id, struct pt_regs *regs);
-static irqreturn_t rs_rxdma_irq(int irq, void *dev_id, struct pt_regs *regs);
-static void dma_init(struct mac_serial * info);
-static void rxdma_start(struct mac_serial * info, int curr);
-static void rxdma_to_tty(struct mac_serial * info);
-
-/*
- * tmp_buf is used as a temporary buffer by serial_write.  We need to
- * lock it in case the copy_from_user blocks while swapping in a page,
- * and some other program tries to do a serial write at the same time.
- * Since the lock will only come under contention when the system is
- * swapping and available memory is low, it makes sense to share one
- * buffer across all the serial ports, since it significantly saves
- * memory if large numbers of serial ports are open.
- */
-static unsigned char *tmp_buf;
-static DECLARE_MUTEX(tmp_buf_sem);
-
-
-static inline int __pmac
-serial_paranoia_check(struct mac_serial *info,
-		      char *name, const char *routine)
-{
-#ifdef SERIAL_PARANOIA_CHECK
-	static const char badmagic[] = KERN_WARNING
-		"Warning: bad magic number for serial struct %s in %s\n";
-	static const char badinfo[] = KERN_WARNING
-		"Warning: null mac_serial for %s in %s\n";
-
-	if (!info) {
-		printk(badinfo, name, routine);
-		return 1;
-	}
-	if (info->magic != SERIAL_MAGIC) {
-		printk(badmagic, name, routine);
-		return 1;
-	}
-#endif
-	return 0;
-}
-
-/* 
- * Reading and writing Z8530 registers.
- */
-static inline unsigned char __pmac read_zsreg(struct mac_zschannel *channel,
-					      unsigned char reg)
-{
-	unsigned char retval;
-	unsigned long flags;
-
-	/*
-	 * We have to make this atomic.
-	 */
-	spin_lock_irqsave(&channel->lock, flags);
-	if (reg != 0) {
-		*channel->control = reg;
-		RECOVERY_DELAY;
-	}
-	retval = *channel->control;
-	RECOVERY_DELAY;
-	spin_unlock_irqrestore(&channel->lock, flags);
-	return retval;
-}
-
-static inline void __pmac write_zsreg(struct mac_zschannel *channel,
-				      unsigned char reg, unsigned char value)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&channel->lock, flags);
-	if (reg != 0) {
-		*channel->control = reg;
-		RECOVERY_DELAY;
-	}
-	*channel->control = value;
-	RECOVERY_DELAY;
-	spin_unlock_irqrestore(&channel->lock, flags);
-	return;
-}
-
-static inline unsigned char __pmac read_zsdata(struct mac_zschannel *channel)
-{
-	unsigned char retval;
-
-	retval = *channel->data;
-	RECOVERY_DELAY;
-	return retval;
-}
-
-static inline void write_zsdata(struct mac_zschannel *channel,
-				unsigned char value)
-{
-	*channel->data = value;
-	RECOVERY_DELAY;
-	return;
-}
-
-static inline void load_zsregs(struct mac_zschannel *channel,
-			       unsigned char *regs)
-{
-	ZS_CLEARERR(channel);
-	ZS_CLEARFIFO(channel);
-	/* Load 'em up */
-	write_zsreg(channel, R4, regs[R4]);
-	write_zsreg(channel, R10, regs[R10]);
-	write_zsreg(channel, R3, regs[R3] & ~RxENABLE);
-	write_zsreg(channel, R5, regs[R5] & ~TxENAB);
-	write_zsreg(channel, R1, regs[R1]);
-	write_zsreg(channel, R9, regs[R9]);
-	write_zsreg(channel, R11, regs[R11]);
-	write_zsreg(channel, R12, regs[R12]);
-	write_zsreg(channel, R13, regs[R13]);
-	write_zsreg(channel, R14, regs[R14]);
-	write_zsreg(channel, R15, regs[R15]);
-	write_zsreg(channel, R3, regs[R3]);
-	write_zsreg(channel, R5, regs[R5]);
-	return;
-}
-
-/* Sets or clears DTR/RTS on the requested line */
-static inline void zs_rtsdtr(struct mac_serial *ss, int set)
-{
-	if (set)
-		ss->curregs[5] |= (RTS | DTR);
-	else
-		ss->curregs[5] &= ~(RTS | DTR);
-	write_zsreg(ss->zs_channel, 5, ss->curregs[5]);
-	return;
-}
-
-/* Utility routines for the Zilog */
-static inline int get_zsbaud(struct mac_serial *ss)
-{
-	struct mac_zschannel *channel = ss->zs_channel;
-	int brg;
-
-	if ((ss->curregs[R11] & TCBR) == 0) {
-		/* higher rates don't use the baud rate generator */
-		return (ss->curregs[R4] & X32CLK)? ZS_CLOCK/32: ZS_CLOCK/16;
-	}
-	/* The baud rate is split up between two 8-bit registers in
-	 * what is termed 'BRG time constant' format in my docs for
-	 * the chip, it is a function of the clk rate the chip is
-	 * receiving which happens to be constant.
-	 */
-	brg = (read_zsreg(channel, 13) << 8);
-	brg |= read_zsreg(channel, 12);
-	return BRG_TO_BPS(brg, (ZS_CLOCK/(ss->clk_divisor)));
-}
-
-/* On receive, this clears errors and the receiver interrupts */
-static inline void rs_recv_clear(struct mac_zschannel *zsc)
-{
-	write_zsreg(zsc, 0, ERR_RES);
-	write_zsreg(zsc, 0, RES_H_IUS); /* XXX this is unnecessary */
-}
-
-/*
- * Reset a Descriptor-Based DMA channel.
- */
-static void dbdma_reset(volatile struct dbdma_regs *dma)
-{
-	int i;
-
-	out_le32(&dma->control, (WAKE|FLUSH|PAUSE|RUN) << 16);
-
-	/*
-	 * Yes this looks peculiar, but apparently it needs to be this
-	 * way on some machines.  (We need to make sure the DBDMA
-	 * engine has actually got the write above and responded
-	 * to it. - paulus)
-	 */
-	for (i = 200; i > 0; --i)
-		if (ld_le32(&dma->status) & RUN)
-			udelay(1);
-}
-
-/*
- * Tells a DBDMA channel to stop and write any buffered data
- * it might have to memory.
- */
-static _INLINE_ void dbdma_flush(volatile struct dbdma_regs *dma)
-{
-	int i = 0;
-
-	out_le32(&dma->control, (FLUSH << 16) | FLUSH);
-	while (((in_le32(&dma->status) & FLUSH) != 0) && (i++ < 100))
-		udelay(1);
-}
-
-/*
- * ----------------------------------------------------------------------
- *
- * Here starts the interrupt handling routines.  All of the following
- * subroutines are declared as inline and are folded into
- * rs_interrupt().  They were separated out for readability's sake.
- *
- * 				- Ted Ts'o (tytso@mit.edu), 7-Mar-93
- * -----------------------------------------------------------------------
- */
-
-/*
- * This routine is used by the interrupt handler to schedule
- * processing in the software interrupt portion of the driver.
- */
-static _INLINE_ void rs_sched_event(struct mac_serial *info,
-				  int event)
-{
-	info->event |= 1 << event;
-	schedule_work(&info->tqueue);
-}
-
-/* Work out the flag value for a z8530 status value. */
-static _INLINE_ int stat_to_flag(int stat)
-{
-	int flag;
-
-	if (stat & Rx_OVR) {
-		flag = TTY_OVERRUN;
-	} else if (stat & FRM_ERR) {
-		flag = TTY_FRAME;
-	} else if (stat & PAR_ERR) {
-		flag = TTY_PARITY;
-	} else
-		flag = 0;
-	return flag;
-}
-
-static _INLINE_ void receive_chars(struct mac_serial *info,
-				   struct pt_regs *regs)
-{
-	struct tty_struct *tty = info->tty;
-	unsigned char ch, stat, flag;
-
-	while ((read_zsreg(info->zs_channel, 0) & Rx_CH_AV) != 0) {
-
-		stat = read_zsreg(info->zs_channel, R1);
-		ch = read_zsdata(info->zs_channel);
-
-#ifdef CONFIG_KGDB
-		if (info->kgdb_channel) {
-			if (ch == 0x03 || ch == '$')
-				breakpoint();
-			if (stat & (Rx_OVR|FRM_ERR|PAR_ERR))
-				write_zsreg(info->zs_channel, 0, ERR_RES);
-			return;
-		}
-#endif
-		if (!tty)
-			continue;
-		if (tty->flip.count >= TTY_FLIPBUF_SIZE)
-			tty_flip_buffer_push(tty);
-
-		if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
-			static int flip_buf_ovf;
-			if (++flip_buf_ovf <= 1)
-				printk(KERN_WARNING "FB. overflow: %d\n",
-						    flip_buf_ovf);
-			break;
-		}
-		tty->flip.count++;
-		{
-			static int flip_max_cnt;
-			if (flip_max_cnt < tty->flip.count)
-				flip_max_cnt = tty->flip.count;
-		}
-		flag = stat_to_flag(stat);
-		if (flag)
-			/* reset the error indication */
-			write_zsreg(info->zs_channel, 0, ERR_RES);
-		*tty->flip.flag_buf_ptr++ = flag;
-		*tty->flip.char_buf_ptr++ = ch;
-	}
-	if (tty)
-		tty_flip_buffer_push(tty);
-}
-
-static void transmit_chars(struct mac_serial *info)
-{
-	if ((read_zsreg(info->zs_channel, 0) & Tx_BUF_EMP) == 0)
-		return;
-	info->tx_active = 0;
-
-	if (info->x_char && !info->power_wait) {
-		/* Send next char */
-		write_zsdata(info->zs_channel, info->x_char);
-		info->x_char = 0;
-		info->tx_active = 1;
-		return;
-	}
-
-	if ((info->xmit_cnt <= 0) || info->tty->stopped || info->tx_stopped
-	    || info->power_wait) {
-		write_zsreg(info->zs_channel, 0, RES_Tx_P);
-		return;
-	}
-
-	/* Send char */
-	write_zsdata(info->zs_channel, info->xmit_buf[info->xmit_tail++]);
-	info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE-1);
-	info->xmit_cnt--;
-	info->tx_active = 1;
-
-	if (info->xmit_cnt < WAKEUP_CHARS)
-		rs_sched_event(info, RS_EVENT_WRITE_WAKEUP);
-}
-
-static void powerup_done(unsigned long data)
-{
-	struct mac_serial *info = (struct mac_serial *) data;
-	unsigned long flags;
-
-	spin_lock_irqsave(&info->lock, flags);
-	info->power_wait = 0;
-	transmit_chars(info);
-	spin_unlock_irqrestore(&info->lock, flags);
-}
-
-static _INLINE_ void status_handle(struct mac_serial *info)
-{
-	unsigned char status;
-
-	/* Get status from Read Register 0 */
-	status = read_zsreg(info->zs_channel, 0);
-
-	/* Check for DCD transitions */
-	if (((status ^ info->read_reg_zero) & DCD) != 0
-	    && info->tty && !C_CLOCAL(info->tty)) {
-		if (status & DCD) {
-			wake_up_interruptible(&info->open_wait);
-		} else {
-			if (info->tty)
-				tty_hangup(info->tty);
-		}
-	}
-
-	/* Check for CTS transitions */
-	if (info->tty && C_CRTSCTS(info->tty)) {
-		/*
-		 * For some reason, on the Power Macintosh,
-		 * it seems that the CTS bit is 1 when CTS is
-		 * *negated* and 0 when it is asserted.
-		 * The DCD bit doesn't seem to be inverted
-		 * like this.
-		 */
-		if ((status & CTS) == 0) {
-			if (info->tx_stopped) {
-#ifdef SERIAL_DEBUG_FLOW
-				printk(KERN_DEBUG "CTS up\n");
-#endif
-				info->tx_stopped = 0;
-				if (!info->tx_active)
-					transmit_chars(info);
-			}
-		} else {
-#ifdef SERIAL_DEBUG_FLOW
-			printk(KERN_DEBUG "CTS down\n");
-#endif
-			info->tx_stopped = 1;
-		}
-	}
-
-	/* Clear status condition... */
-	write_zsreg(info->zs_channel, 0, RES_EXT_INT);
-	info->read_reg_zero = status;
-}
-
-static _INLINE_ void receive_special_dma(struct mac_serial *info)
-{
-	unsigned char stat, flag;
-	volatile struct dbdma_regs *rd = &info->rx->dma;
-	int where = RX_BUF_SIZE;
-
-	spin_lock(&info->rx_dma_lock);
-	if ((ld_le32(&rd->status) & ACTIVE) != 0)
-		dbdma_flush(rd);
-	if (in_le32(&rd->cmdptr)
-	    == virt_to_bus(info->rx_cmds[info->rx_cbuf] + 1))
-		where -= in_le16(&info->rx->res_count);
-	where--;
-
-	stat = read_zsreg(info->zs_channel, R1);
-
-	flag = stat_to_flag(stat);
-	if (flag) {
-		info->rx_flag_buf[info->rx_cbuf][where] = flag;
-		/* reset the error indication */
-		write_zsreg(info->zs_channel, 0, ERR_RES);
-	}
-
-	spin_unlock(&info->rx_dma_lock);
-}
-
-/*
- * This is the serial driver's generic interrupt routine
- */
-static irqreturn_t rs_interrupt(int irq, void *dev_id, struct pt_regs * regs)
-{
-	struct mac_serial *info = (struct mac_serial *) dev_id;
-	unsigned char zs_intreg;
-	int shift;
-	unsigned long flags;
-	int handled = 0;
-
-	if (!(info->flags & ZILOG_INITIALIZED)) {
-		printk(KERN_WARNING "rs_interrupt: irq %d, port not "
-				    "initialized\n", irq);
-		disable_irq(irq);
-		return IRQ_NONE;
-	}
-
-	/* NOTE: The read register 3, which holds the irq status,
-	 *       does so for both channels on each chip.  Although
-	 *       the status value itself must be read from the A
-	 *       channel and is only valid when read from channel A.
-	 *       Yes... broken hardware...
-	 */
-#define CHAN_IRQMASK (CHBRxIP | CHBTxIP | CHBEXT)
-
-	if (info->zs_chan_a == info->zs_channel)
-		shift = 3;	/* Channel A */
-	else
-		shift = 0;	/* Channel B */
-
-	spin_lock_irqsave(&info->lock, flags);
-	for (;;) {
-		zs_intreg = read_zsreg(info->zs_chan_a, 3) >> shift;
-#ifdef SERIAL_DEBUG_INTR
-		printk(KERN_DEBUG "rs_interrupt: irq %d, zs_intreg 0x%x\n",
-		       irq, (int)zs_intreg);
-#endif
-
-		if ((zs_intreg & CHAN_IRQMASK) == 0)
-			break;
-		handled = 1;
-
-		if (zs_intreg & CHBRxIP) {
-			/* If we are doing DMA, we only ask for interrupts
-			   on characters with errors or special conditions. */
-			if (info->dma_initted)
-				receive_special_dma(info);
-			else
-				receive_chars(info, regs);
-		}
-		if (zs_intreg & CHBTxIP)
-			transmit_chars(info);
-		if (zs_intreg & CHBEXT)
-			status_handle(info);
-	}
-	spin_unlock_irqrestore(&info->lock, flags);
-	return IRQ_RETVAL(handled);
-}
-
-/* Transmit DMA interrupt - not used at present */
-static irqreturn_t rs_txdma_irq(int irq, void *dev_id, struct pt_regs *regs)
-{
-	return IRQ_HANDLED;
-}
-
-/*
- * Receive DMA interrupt.
- */
-static irqreturn_t rs_rxdma_irq(int irq, void *dev_id, struct pt_regs *regs)
-{
-	struct mac_serial *info = (struct mac_serial *) dev_id;
-	volatile struct dbdma_cmd *cd;
-
-	if (!info->dma_initted)
-		return IRQ_NONE;
-	spin_lock(&info->rx_dma_lock);
-	/* First, confirm that this interrupt is, indeed, coming */
-	/* from Rx DMA */
-	cd = info->rx_cmds[info->rx_cbuf] + 2;
-	if ((in_le16(&cd->xfer_status) & (RUN | ACTIVE)) != (RUN | ACTIVE)) {
-		spin_unlock(&info->rx_dma_lock);
-		return IRQ_NONE;
-	}
-	if (info->rx_fbuf != RX_NO_FBUF) {
-		info->rx_cbuf = info->rx_fbuf;
-		if (++info->rx_fbuf == info->rx_nbuf)
-			info->rx_fbuf = 0;
-		if (info->rx_fbuf == info->rx_ubuf)
-			info->rx_fbuf = RX_NO_FBUF;
-	}
-	spin_unlock(&info->rx_dma_lock);
-	return IRQ_HANDLED;
-}
-
-/*
- * -------------------------------------------------------------------
- * Here ends the serial interrupt routines.
- * -------------------------------------------------------------------
- */
-
-/*
- * ------------------------------------------------------------
- * rs_stop() and rs_start()
- *
- * This routines are called before setting or resetting tty->stopped.
- * ------------------------------------------------------------
- */
-static void rs_stop(struct tty_struct *tty)
-{
-	struct mac_serial *info = (struct mac_serial *)tty->driver_data;
-
-#ifdef SERIAL_DEBUG_STOP
-	printk(KERN_DEBUG "rs_stop %ld....\n",
-	       tty->ldisc.chars_in_buffer(tty));
-#endif
-
-	if (serial_paranoia_check(info, tty->name, "rs_stop"))
-		return;
-
-#if 0
-	spin_lock_irqsave(&info->lock, flags);
-	if (info->curregs[5] & TxENAB) {
-		info->curregs[5] &= ~TxENAB;
-		info->pendregs[5] &= ~TxENAB;
-		write_zsreg(info->zs_channel, 5, info->curregs[5]);
-	}
-	spin_unlock_irqrestore(&info->lock, flags);
-#endif
-}
-
-static void rs_start(struct tty_struct *tty)
-{
-	struct mac_serial *info = (struct mac_serial *)tty->driver_data;
-	unsigned long flags;
-
-#ifdef SERIAL_DEBUG_STOP
-	printk(KERN_DEBUG "rs_start %ld....\n", 
-	       tty->ldisc.chars_in_buffer(tty));
-#endif
-
-	if (serial_paranoia_check(info, tty->name, "rs_start"))
-		return;
-
-	spin_lock_irqsave(&info->lock, flags);
-#if 0
-	if (info->xmit_cnt && info->xmit_buf && !(info->curregs[5] & TxENAB)) {
-		info->curregs[5] |= TxENAB;
-		info->pendregs[5] = info->curregs[5];
-		write_zsreg(info->zs_channel, 5, info->curregs[5]);
-	}
-#else
-	if (info->xmit_cnt && info->xmit_buf && !info->tx_active) {
-		transmit_chars(info);
-	}
-#endif
-	spin_unlock_irqrestore(&info->lock, flags);
-}
-
-static void do_softint(void *private_)
-{
-	struct mac_serial	*info = (struct mac_serial *) private_;
-	struct tty_struct	*tty;
-
-	tty = info->tty;
-	if (!tty)
-		return;
-
-	if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event))
-		tty_wakeup(tty);
-}
-
-static int startup(struct mac_serial * info)
-{
-	int delay;
-
-	OPNDBG("startup() (ttyS%d, irq %d)\n", info->line, info->irq);
- 
-	if (info->flags & ZILOG_INITIALIZED) {
-		OPNDBG(" -> already inited\n");
- 		return 0;
-	}
-
-	if (!info->xmit_buf) {
-		info->xmit_buf = (unsigned char *) get_zeroed_page(GFP_KERNEL);
-		if (!info->xmit_buf)
-			return -ENOMEM;
-	}
-
-	OPNDBG("starting up ttyS%d (irq %d)...\n", info->line, info->irq);
-
-	delay = set_scc_power(info, 1);
-
-	setup_scc(info);
-
-	if (delay) {
-		unsigned long flags;
-
-		/* delay is in ms */
-		spin_lock_irqsave(&info->lock, flags);
-		info->power_wait = 1;
-		mod_timer(&info->powerup_timer,
-			  jiffies + (delay * HZ + 999) / 1000);
-		spin_unlock_irqrestore(&info->lock, flags);
-	}
-
-	OPNDBG("enabling IRQ on ttyS%d (irq %d)...\n", info->line, info->irq);
-
-	info->flags |= ZILOG_INITIALIZED;
-	enable_irq(info->irq);
-	if (info->dma_initted) {
-		enable_irq(info->rx_dma_irq);
-	}
-
-	return 0;
-}
-
-static _INLINE_ void rxdma_start(struct mac_serial * info, int curr)
-{
-	volatile struct dbdma_regs *rd = &info->rx->dma;
-	volatile struct dbdma_cmd *cd = info->rx_cmds[curr];
-
-//printk(KERN_DEBUG "SCC: rxdma_start\n");
-
-	st_le32(&rd->cmdptr, virt_to_bus(cd));
-	out_le32(&rd->control, (RUN << 16) | RUN);
-}
-
-static void rxdma_to_tty(struct mac_serial *info)
-{
-	struct tty_struct	*tty = info->tty;
-	volatile struct dbdma_regs *rd = &info->rx->dma;
-	unsigned long flags;
-	int residue, available, space, do_queue;
-
-	if (!tty)
-		return;
-
-	do_queue = 0;
-	spin_lock_irqsave(&info->rx_dma_lock, flags);
-more:
-	space = TTY_FLIPBUF_SIZE - tty->flip.count;
-	if (!space) {
-		do_queue++;
-		goto out;
-	}
-	residue = 0;
-	if (info->rx_ubuf == info->rx_cbuf) {
-		if ((ld_le32(&rd->status) & ACTIVE) != 0) {
-			dbdma_flush(rd);
-			if (in_le32(&rd->cmdptr)
-			    == virt_to_bus(info->rx_cmds[info->rx_cbuf]+1))
-				residue = in_le16(&info->rx->res_count);
-		}
-	}
-	available = RX_BUF_SIZE - residue - info->rx_done_bytes;
-	if (available > space)
-		available = space;
-	if (available) {
-		memcpy(tty->flip.char_buf_ptr,
-		       info->rx_char_buf[info->rx_ubuf] + info->rx_done_bytes,
-		       available);
-		memcpy(tty->flip.flag_buf_ptr,
-		       info->rx_flag_buf[info->rx_ubuf] + info->rx_done_bytes,
-		       available);
-		tty->flip.char_buf_ptr += available;
-		tty->flip.count += available;
-		tty->flip.flag_buf_ptr += available;
-		memset(info->rx_flag_buf[info->rx_ubuf] + info->rx_done_bytes,
-		       0, available);
-		info->rx_done_bytes += available;
-		do_queue++;
-	}
-	if (info->rx_done_bytes == RX_BUF_SIZE) {
-		volatile struct dbdma_cmd *cd = info->rx_cmds[info->rx_ubuf];
-
-		if (info->rx_ubuf == info->rx_cbuf)
-			goto out;
-		/* mark rx_char_buf[rx_ubuf] free */
-		st_le16(&cd->command, DBDMA_NOP);
-		cd++;
-		st_le32(&cd->cmd_dep, 0);
-		st_le32((unsigned int *)&cd->res_count, 0);
-		cd++;
-		st_le16(&cd->xfer_status, 0);
-
-		if (info->rx_fbuf == RX_NO_FBUF) {
-			info->rx_fbuf = info->rx_ubuf;
-			if (!(ld_le32(&rd->status) & ACTIVE)) {
-				dbdma_reset(&info->rx->dma);
-				rxdma_start(info, info->rx_ubuf);
-				info->rx_cbuf = info->rx_ubuf;
-			}
-		}
-		info->rx_done_bytes = 0;
-		if (++info->rx_ubuf == info->rx_nbuf)
-			info->rx_ubuf = 0;
-		if (info->rx_fbuf == info->rx_ubuf)
-			info->rx_fbuf = RX_NO_FBUF;
-		goto more;
-	}
-out:
-	spin_unlock_irqrestore(&info->rx_dma_lock, flags);
-	if (do_queue)
-		tty_flip_buffer_push(tty);
-}
-
-static void poll_rxdma(unsigned long private_)
-{
-	struct mac_serial	*info = (struct mac_serial *) private_;
-	unsigned long flags;
-
-	rxdma_to_tty(info);
-	spin_lock_irqsave(&info->rx_dma_lock, flags);
-	mod_timer(&info->poll_dma_timer, RX_DMA_TIMER);
-	spin_unlock_irqrestore(&info->rx_dma_lock, flags);
-}
-
-static void dma_init(struct mac_serial * info)
-{
-	int i, size;
-	volatile struct dbdma_cmd *cd;
-	unsigned char *p;
-
-	info->rx_nbuf = 8;
-
-	/* various mem set up */
-	size = sizeof(struct dbdma_cmd) * (3 * info->rx_nbuf + 2)
-		+ (RX_BUF_SIZE * 2 + sizeof(*info->rx_cmds)
-		   + sizeof(*info->rx_char_buf) + sizeof(*info->rx_flag_buf))
-		* info->rx_nbuf;
-	info->dma_priv = kmalloc(size, GFP_KERNEL | GFP_DMA);
-	if (info->dma_priv == NULL)
-		return;
-	memset(info->dma_priv, 0, size);
-
-	info->rx_cmds = (volatile struct dbdma_cmd **)info->dma_priv;
-	info->rx_char_buf = (unsigned char **) (info->rx_cmds + info->rx_nbuf);
-	info->rx_flag_buf = info->rx_char_buf + info->rx_nbuf;
-	p = (unsigned char *) (info->rx_flag_buf + info->rx_nbuf);
-	for (i = 0; i < info->rx_nbuf; i++, p += RX_BUF_SIZE)
-		info->rx_char_buf[i] = p;
-	for (i = 0; i < info->rx_nbuf; i++, p += RX_BUF_SIZE)
-		info->rx_flag_buf[i] = p;
-
-	/* a bit of DMA programming */
-	cd = info->rx_cmds[0] = (volatile struct dbdma_cmd *) DBDMA_ALIGN(p);
-	st_le16(&cd->command, DBDMA_NOP);
-	cd++;
-	st_le16(&cd->req_count, RX_BUF_SIZE);
-	st_le16(&cd->command, INPUT_MORE);
-	st_le32(&cd->phy_addr, virt_to_bus(info->rx_char_buf[0]));
-	cd++;
-	st_le16(&cd->req_count, 4);
-	st_le16(&cd->command, STORE_WORD | INTR_ALWAYS);
-	st_le32(&cd->phy_addr, virt_to_bus(cd-2));
-	st_le32(&cd->cmd_dep, DBDMA_STOP);
-	for (i = 1; i < info->rx_nbuf; i++) {
-		info->rx_cmds[i] = ++cd;
-		st_le16(&cd->command, DBDMA_NOP);
-		cd++;
-		st_le16(&cd->req_count, RX_BUF_SIZE);
-		st_le16(&cd->command, INPUT_MORE);
-		st_le32(&cd->phy_addr, virt_to_bus(info->rx_char_buf[i]));
-		cd++;
-		st_le16(&cd->req_count, 4);
-		st_le16(&cd->command, STORE_WORD | INTR_ALWAYS);
-		st_le32(&cd->phy_addr, virt_to_bus(cd-2));
-		st_le32(&cd->cmd_dep, DBDMA_STOP);
-	}
-	cd++;
-	st_le16(&cd->command, DBDMA_NOP | BR_ALWAYS);
-	st_le32(&cd->cmd_dep, virt_to_bus(info->rx_cmds[0]));
-
-	/* setup DMA to our liking */
-	dbdma_reset(&info->rx->dma);
-	st_le32(&info->rx->dma.intr_sel, 0x10001);
-	st_le32(&info->rx->dma.br_sel, 0x10001);
-	out_le32(&info->rx->dma.wait_sel, 0x10001);
-
-	/* set various flags */
-	info->rx_ubuf = 0;
-	info->rx_cbuf = 0;
-	info->rx_fbuf = info->rx_ubuf + 1;
-	if (info->rx_fbuf == info->rx_nbuf)
-		info->rx_fbuf = RX_NO_FBUF;
-	info->rx_done_bytes = 0;
-
-	/* setup polling */
-	init_timer(&info->poll_dma_timer);
-	info->poll_dma_timer.function = (void *)&poll_rxdma;
-	info->poll_dma_timer.data = (unsigned long)info;
-
-	info->dma_initted = 1;
-}
-
-/*
- * FixZeroBug....Works around a bug in the SCC receving channel.
- * Taken from Darwin code, 15 Sept. 2000  -DanM
- *
- * The following sequence prevents a problem that is seen with O'Hare ASICs
- * (most versions -- also with some Heathrow and Hydra ASICs) where a zero
- * at the input to the receiver becomes 'stuck' and locks up the receiver.
- * This problem can occur as a result of a zero bit at the receiver input
- * coincident with any of the following events:
- *
- *	The SCC is initialized (hardware or software).
- *	A framing error is detected.
- *	The clocking option changes from synchronous or X1 asynchronous
- *		clocking to X16, X32, or X64 asynchronous clocking.
- *	The decoding mode is changed among NRZ, NRZI, FM0, or FM1.
- *
- * This workaround attempts to recover from the lockup condition by placing
- * the SCC in synchronous loopback mode with a fast clock before programming
- * any of the asynchronous modes.
- */
-static void fix_zero_bug_scc(struct mac_serial * info)
-{
-	write_zsreg(info->zs_channel, 9,
-		    (info->zs_channel == info->zs_chan_a? CHRA: CHRB));
-	udelay(10);
-	write_zsreg(info->zs_channel, 9,
-		    ((info->zs_channel == info->zs_chan_a? CHRA: CHRB) | NV));
-
-	write_zsreg(info->zs_channel, 4, (X1CLK | EXTSYNC));
-
-	/* I think this is wrong....but, I just copying code....
-	*/
-	write_zsreg(info->zs_channel, 3, (8 & ~RxENABLE));
-
-	write_zsreg(info->zs_channel, 5, (8 & ~TxENAB));
-	write_zsreg(info->zs_channel, 9, NV);	/* Didn't we already do this? */
-	write_zsreg(info->zs_channel, 11, (RCBR | TCBR));
-	write_zsreg(info->zs_channel, 12, 0);
-	write_zsreg(info->zs_channel, 13, 0);
-	write_zsreg(info->zs_channel, 14, (LOOPBAK | SSBR));
-	write_zsreg(info->zs_channel, 14, (LOOPBAK | SSBR | BRENABL));
-	write_zsreg(info->zs_channel, 3, (8 | RxENABLE));
-	write_zsreg(info->zs_channel, 0, RES_EXT_INT);
-	write_zsreg(info->zs_channel, 0, RES_EXT_INT);	/* to kill some time */
-
-	/* The channel should be OK now, but it is probably receiving
-	 * loopback garbage.
-	 * Switch to asynchronous mode, disable the receiver,
-	 * and discard everything in the receive buffer.
-	 */
-	write_zsreg(info->zs_channel, 9, NV);
-	write_zsreg(info->zs_channel, 4, PAR_ENA);
-	write_zsreg(info->zs_channel, 3, (8 & ~RxENABLE));
-
-	while (read_zsreg(info->zs_channel, 0) & Rx_CH_AV) {
-		(void)read_zsreg(info->zs_channel, 8);
-		write_zsreg(info->zs_channel, 0, RES_EXT_INT);
-		write_zsreg(info->zs_channel, 0, ERR_RES);
-	}
-}
-
-static int setup_scc(struct mac_serial * info)
-{
-	unsigned long flags;
-
-	OPNDBG("setting up ttyS%d SCC...\n", info->line);
-
-	spin_lock_irqsave(&info->lock, flags);
-
-	/* Nice buggy HW ... */
-	fix_zero_bug_scc(info);
-
-	/*
-	 * Reset the chip.
-	 */
-	write_zsreg(info->zs_channel, 9,
-		    (info->zs_channel == info->zs_chan_a? CHRA: CHRB));
-	udelay(10);
-	write_zsreg(info->zs_channel, 9, 0);
-
-	/*
-	 * Clear the receive FIFO.
-	 */
-	ZS_CLEARFIFO(info->zs_channel);
-	info->xmit_fifo_size = 1;
-
-	/*
-	 * Reset DMAs
-	 */
-	if (info->has_dma)
-		dma_init(info);
-
-	/*
-	 * Clear the interrupt registers.
-	 */
-	write_zsreg(info->zs_channel, 0, ERR_RES);
-	write_zsreg(info->zs_channel, 0, RES_H_IUS);
-
-	/*
-	 * Turn on RTS and DTR.
-	 */
-	if (!info->is_irda)
-		zs_rtsdtr(info, 1);
-
-	/*
-	 * Finally, enable sequencing and interrupts
-	 */
-	if (!info->dma_initted) {
-		/* interrupt on ext/status changes, all received chars,
-		   transmit ready */
-		info->curregs[1] = (info->curregs[1] & ~0x18)
-				| (EXT_INT_ENAB | INT_ALL_Rx | TxINT_ENAB);
-	} else {
-		/* interrupt on ext/status changes, W/Req pin is
-		   receive DMA request */
-		info->curregs[1] = (info->curregs[1] & ~(0x18 | TxINT_ENAB))
-				| (EXT_INT_ENAB | WT_RDY_RT | WT_FN_RDYFN);
-		write_zsreg(info->zs_channel, 1, info->curregs[1]);
-		/* enable W/Req pin */
-		info->curregs[1] |= WT_RDY_ENAB;
-		write_zsreg(info->zs_channel, 1, info->curregs[1]);
-		/* enable interrupts on transmit ready and receive errors */
-		info->curregs[1] |= INT_ERR_Rx | TxINT_ENAB;
-	}
-	info->pendregs[1] = info->curregs[1];
-	info->curregs[3] |= (RxENABLE | Rx8);
-	info->pendregs[3] = info->curregs[3];
-	info->curregs[5] |= (TxENAB | Tx8);
-	info->pendregs[5] = info->curregs[5];
-	info->curregs[9] |= (NV | MIE);
-	info->pendregs[9] = info->curregs[9];
-	write_zsreg(info->zs_channel, 3, info->curregs[3]);
-	write_zsreg(info->zs_channel, 5, info->curregs[5]);
-	write_zsreg(info->zs_channel, 9, info->curregs[9]);
-
-	if (info->tty)
-		clear_bit(TTY_IO_ERROR, &info->tty->flags);
-	info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
-
-	spin_unlock_irqrestore(&info->lock, flags);
-
-	/*
-	 * Set the speed of the serial port
-	 */
-	change_speed(info, 0);
-
-	/* Save the current value of RR0 */
-	info->read_reg_zero = read_zsreg(info->zs_channel, 0);
-
-	if (info->dma_initted) {
-		spin_lock_irqsave(&info->rx_dma_lock, flags);
-		rxdma_start(info, 0);
-		info->poll_dma_timer.expires = RX_DMA_TIMER;
-		add_timer(&info->poll_dma_timer);
-		spin_unlock_irqrestore(&info->rx_dma_lock, flags);
-	}
-
-	return 0;
-}
-
-/*
- * This routine will shutdown a serial port; interrupts are disabled, and
- * DTR is dropped if the hangup on close termio flag is on.
- */
-static void shutdown(struct mac_serial * info)
-{
-	OPNDBG("Shutting down serial port %d (irq %d)....\n", info->line,
-	       info->irq);
-
-	if (!(info->flags & ZILOG_INITIALIZED)) {
-		OPNDBG("(already shutdown)\n");
-		return;
-	}
-
-	if (info->has_dma) {
-		del_timer(&info->poll_dma_timer);
-		dbdma_reset(info->tx_dma);
-		dbdma_reset(&info->rx->dma);
-		disable_irq(info->tx_dma_irq);
-		disable_irq(info->rx_dma_irq);
-	}
-	disable_irq(info->irq);
-
-	info->pendregs[1] = info->curregs[1] = 0;
-	write_zsreg(info->zs_channel, 1, 0);	/* no interrupts */
-
-	info->curregs[3] &= ~RxENABLE;
-	info->pendregs[3] = info->curregs[3];
-	write_zsreg(info->zs_channel, 3, info->curregs[3]);
-
-	info->curregs[5] &= ~TxENAB;
-	if (!info->tty || C_HUPCL(info->tty))
-		info->curregs[5] &= ~DTR;
-	info->pendregs[5] = info->curregs[5];
-	write_zsreg(info->zs_channel, 5, info->curregs[5]);
-
-	if (info->tty)
-		set_bit(TTY_IO_ERROR, &info->tty->flags);
-
-	set_scc_power(info, 0);
-
-	if (info->xmit_buf) {
-		free_page((unsigned long) info->xmit_buf);
-		info->xmit_buf = 0;
-	}
-
-	if (info->has_dma && info->dma_priv) {
-		kfree(info->dma_priv);
-		info->dma_priv = NULL;
-		info->dma_initted = 0;
-	}
-
-	memset(info->curregs, 0, sizeof(info->curregs));
-	memset(info->pendregs, 0, sizeof(info->pendregs));
-
-	info->flags &= ~ZILOG_INITIALIZED;
-}
-
-/*
- * Turn power on or off to the SCC and associated stuff
- * (port drivers, modem, IR port, etc.)
- * Returns the number of milliseconds we should wait before
- * trying to use the port.
- */
-static int set_scc_power(struct mac_serial * info, int state)
-{
-	int delay = 0;
-
-	if (state) {
-		PWRDBG("ttyS%d: powering up hardware\n", info->line);
-		pmac_call_feature(
-			PMAC_FTR_SCC_ENABLE,
-			info->dev_node, info->port_type, 1);
-		if (info->is_internal_modem) {
-			pmac_call_feature(
-				PMAC_FTR_MODEM_ENABLE,
-				info->dev_node, 0, 1);
-			delay = 2500;	/* wait for 2.5s before using */
-		} else if (info->is_irda)
-			mdelay(50);	/* Do better here once the problems
-			                 * with blocking have been ironed out
-			                 */
-	} else {
-		/* TODO: Make that depend on a timer, don't power down
-		 * immediately
-		 */
-		PWRDBG("ttyS%d: shutting down hardware\n", info->line);
-		if (info->is_internal_modem) {
-			PWRDBG("ttyS%d: shutting down modem\n", info->line);
-			pmac_call_feature(
-				PMAC_FTR_MODEM_ENABLE,
-				info->dev_node, 0, 0);
-		}
-		pmac_call_feature(
-			PMAC_FTR_SCC_ENABLE,
-			info->dev_node, info->port_type, 0);
-	}
-	return delay;
-}
-
-static void irda_rts_pulses(struct mac_serial *info, int w)
-{
-	udelay(w);
-	write_zsreg(info->zs_channel, 5, Tx8 | TxENAB);
-	udelay(2);
-	write_zsreg(info->zs_channel, 5, Tx8 | TxENAB | RTS);
-	udelay(8);
-	write_zsreg(info->zs_channel, 5, Tx8 | TxENAB);
-	udelay(4);
-	write_zsreg(info->zs_channel, 5, Tx8 | TxENAB | RTS);
-}
-
-/*
- * Set the irda codec on the imac to the specified baud rate.
- */
-static void irda_setup(struct mac_serial *info)
-{
-	int code, speed, t;
-
-	speed = info->tty->termios->c_cflag & CBAUD;
-	if (speed < B2400 || speed > B115200)
-		return;
-	code = 0x4d + B115200 - speed;
-
-	/* disable serial interrupts and receive DMA */
-	write_zsreg(info->zs_channel, 1, info->curregs[1] & ~0x9f);
-
-	/* wait for transmitter to drain */
-	t = 10000;
-	while ((read_zsreg(info->zs_channel, 0) & Tx_BUF_EMP) == 0
-	       || (read_zsreg(info->zs_channel, 1) & ALL_SNT) == 0) {
-		if (--t <= 0) {
-			printk(KERN_ERR "transmitter didn't drain\n");
-			return;
-		}
-		udelay(10);
-	}
-	udelay(100);
-
-	/* set to 8 bits, no parity, 19200 baud, RTS on, DTR off */
-	write_zsreg(info->zs_channel, 4, X16CLK | SB1);
-	write_zsreg(info->zs_channel, 11, TCBR | RCBR);
-	t = BPS_TO_BRG(19200, ZS_CLOCK/16);
-	write_zsreg(info->zs_channel, 12, t);
-	write_zsreg(info->zs_channel, 13, t >> 8);
-	write_zsreg(info->zs_channel, 14, BRENABL);
-	write_zsreg(info->zs_channel, 3, Rx8 | RxENABLE);
-	write_zsreg(info->zs_channel, 5, Tx8 | TxENAB | RTS);
-
-	/* set TxD low for ~104us and pulse RTS */
-	udelay(1000);
-	write_zsdata(info->zs_channel, 0xfe);
-	irda_rts_pulses(info, 150);
-	irda_rts_pulses(info, 180);
-	irda_rts_pulses(info, 50);
-	udelay(100);
-
-	/* assert DTR, wait 30ms, talk to the chip */
-	write_zsreg(info->zs_channel, 5, Tx8 | TxENAB | RTS | DTR);
-	mdelay(30);
-	while (read_zsreg(info->zs_channel, 0) & Rx_CH_AV)
-		read_zsdata(info->zs_channel);
-
-	write_zsdata(info->zs_channel, 1);
-	t = 1000;
-	while ((read_zsreg(info->zs_channel, 0) & Rx_CH_AV) == 0) {
-		if (--t <= 0) {
-			printk(KERN_ERR "irda_setup timed out on 1st byte\n");
-			goto out;
-		}
-		udelay(10);
-	}
-	t = read_zsdata(info->zs_channel);
-	if (t != 4)
-		printk(KERN_ERR "irda_setup 1st byte = %x\n", t);
-
-	write_zsdata(info->zs_channel, code);
-	t = 1000;
-	while ((read_zsreg(info->zs_channel, 0) & Rx_CH_AV) == 0) {
-		if (--t <= 0) {
-			printk(KERN_ERR "irda_setup timed out on 2nd byte\n");
-			goto out;
-		}
-		udelay(10);
-	}
-	t = read_zsdata(info->zs_channel);
-	if (t != code)
-		printk(KERN_ERR "irda_setup 2nd byte = %x (%x)\n", t, code);
-
-	/* Drop DTR again and do some more RTS pulses */
- out:
-	udelay(100);
-	write_zsreg(info->zs_channel, 5, Tx8 | TxENAB | RTS);
-	irda_rts_pulses(info, 80);
-
-	/* We should be right to go now.  We assume that load_zsregs
-	   will get called soon to load up the correct baud rate etc. */
-	info->curregs[5] = (info->curregs[5] | RTS) & ~DTR;
-	info->pendregs[5] = info->curregs[5];
-}
-
-/*
- * This routine is called to set the UART divisor registers to match
- * the specified baud rate for a serial port.
- */
-static void change_speed(struct mac_serial *info, struct termios *old_termios)
-{
-	unsigned cflag;
-	int	bits;
-	int	brg, baud;
-	unsigned long flags;
-
-	if (!info->tty || !info->tty->termios)
-		return;
-
-	cflag = info->tty->termios->c_cflag;
-	baud = tty_get_baud_rate(info->tty);
-	if (baud == 0) {
-		if (old_termios) {
-			info->tty->termios->c_cflag &= ~CBAUD;
-			info->tty->termios->c_cflag |= (old_termios->c_cflag & CBAUD);
-			cflag = info->tty->termios->c_cflag;
-			baud = tty_get_baud_rate(info->tty);
-		}
-		else
-			baud = info->zs_baud;
-	}
-	if (baud > 230400)
-		baud = 230400;
-	else if (baud == 0)
-		baud = 38400;
-
-	spin_lock_irqsave(&info->lock, flags);
-	info->zs_baud = baud;
-	info->clk_divisor = 16;
-
-	BAUDBG(KERN_DEBUG "set speed to %d bds, ", baud);
-
-	switch (baud) {
-	case ZS_CLOCK/16:	/* 230400 */
-		info->curregs[4] = X16CLK;
-		info->curregs[11] = 0;
-		break;
-	case ZS_CLOCK/32:	/* 115200 */
-		info->curregs[4] = X32CLK;
-		info->curregs[11] = 0;
-		break;
-	default:
-		info->curregs[4] = X16CLK;
-		info->curregs[11] = TCBR | RCBR;
-		brg = BPS_TO_BRG(baud, ZS_CLOCK/info->clk_divisor);
-		info->curregs[12] = (brg & 255);
-		info->curregs[13] = ((brg >> 8) & 255);
-		info->curregs[14] = BRENABL;
-	}
-
-	/* byte size and parity */
-	info->curregs[3] &= ~RxNBITS_MASK;
-	info->curregs[5] &= ~TxNBITS_MASK;
-	switch (cflag & CSIZE) {
-	case CS5:
-		info->curregs[3] |= Rx5;
-		info->curregs[5] |= Tx5;
-		BAUDBG("5 bits, ");
-		bits = 7;
-		break;
-	case CS6:
-		info->curregs[3] |= Rx6;
-		info->curregs[5] |= Tx6;
-		BAUDBG("6 bits, ");
-		bits = 8;
-		break;
-	case CS7:
-		info->curregs[3] |= Rx7;
-		info->curregs[5] |= Tx7;
-		BAUDBG("7 bits, ");
-		bits = 9;
-		break;
-	case CS8:
-	default: /* defaults to 8 bits */
-		info->curregs[3] |= Rx8;
-		info->curregs[5] |= Tx8;
-		BAUDBG("8 bits, ");
-		bits = 10;
-		break;
-	}
-	info->pendregs[3] = info->curregs[3];
-	info->pendregs[5] = info->curregs[5];
-
-	info->curregs[4] &= ~(SB_MASK | PAR_ENA | PAR_EVEN);
-	if (cflag & CSTOPB) {
-		info->curregs[4] |= SB2;
-		bits++;
-		BAUDBG("2 stop, ");
-	} else {
-		info->curregs[4] |= SB1;
-		BAUDBG("1 stop, ");
-	}
-	if (cflag & PARENB) {
-		bits++;
- 		info->curregs[4] |= PAR_ENA;
-		BAUDBG("parity, ");
-	}
-	if (!(cflag & PARODD)) {
-		info->curregs[4] |= PAR_EVEN;
-	}
-	info->pendregs[4] = info->curregs[4];
-
-	if (!(cflag & CLOCAL)) {
-		if (!(info->curregs[15] & DCDIE))
-			info->read_reg_zero = read_zsreg(info->zs_channel, 0);
-		info->curregs[15] |= DCDIE;
-	} else
-		info->curregs[15] &= ~DCDIE;
-	if (cflag & CRTSCTS) {
-		info->curregs[15] |= CTSIE;
-		if ((read_zsreg(info->zs_channel, 0) & CTS) != 0)
-			info->tx_stopped = 1;
-	} else {
-		info->curregs[15] &= ~CTSIE;
-		info->tx_stopped = 0;
-	}
-	info->pendregs[15] = info->curregs[15];
-
-	/* Calc timeout value. This is pretty broken with high baud rates with HZ=100.
-	   This code would love a larger HZ and a >1 fifo size, but this is not
-	   a priority. The resulting value must be >HZ/2
-	 */
-	info->timeout = ((info->xmit_fifo_size*HZ*bits) / baud);
-	info->timeout += HZ/50+1;	/* Add .02 seconds of slop */
-
-	BAUDBG("timeout=%d/%ds, base:%d\n", (int)info->timeout, (int)HZ,
-	       (int)info->baud_base);
-
-	/* set the irda codec to the right rate */
-	if (info->is_irda)
-		irda_setup(info);
-
-	/* Load up the new values */
-	load_zsregs(info->zs_channel, info->curregs);
-
-	spin_unlock_irqrestore(&info->lock, flags);
-}
-
-static void rs_flush_chars(struct tty_struct *tty)
-{
-	struct mac_serial *info = (struct mac_serial *)tty->driver_data;
-	unsigned long flags;
-
-	if (serial_paranoia_check(info, tty->name, "rs_flush_chars"))
-		return;
-
-	spin_lock_irqsave(&info->lock, flags);
-	if (!(info->xmit_cnt <= 0 || tty->stopped || info->tx_stopped ||
-	      !info->xmit_buf))
-		/* Enable transmitter */
-		transmit_chars(info);
-	spin_unlock_irqrestore(&info->lock, flags);
-}
-
-static int rs_write(struct tty_struct * tty,
-		    const unsigned char *buf, int count)
-{
-	int	c, ret = 0;
-	struct mac_serial *info = (struct mac_serial *)tty->driver_data;
-	unsigned long flags;
-
-	if (serial_paranoia_check(info, tty->name, "rs_write"))
-		return 0;
-
-	if (!tty || !info->xmit_buf || !tmp_buf)
-		return 0;
-
-	while (1) {
-		spin_lock_irqsave(&info->lock, flags);
-		c = min_t(int, count, min(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
-					  SERIAL_XMIT_SIZE - info->xmit_head));
-		if (c <= 0) {
-			spin_unlock_irqrestore(&info->lock, flags);
-			break;
-		}
-		memcpy(info->xmit_buf + info->xmit_head, buf, c);
-		info->xmit_head = ((info->xmit_head + c) &
-				   (SERIAL_XMIT_SIZE-1));
-		info->xmit_cnt += c;
-		spin_unlock_irqrestore(&info->lock, flags);
-		buf += c;
-		count -= c;
-		ret += c;
-	}
-	spin_lock_irqsave(&info->lock, flags);
-	if (info->xmit_cnt && !tty->stopped && !info->tx_stopped
-	    && !info->tx_active)
-		transmit_chars(info);
-	spin_unlock_irqrestore(&info->lock, flags);
-	return ret;
-}
-
-static int rs_write_room(struct tty_struct *tty)
-{
-	struct mac_serial *info = (struct mac_serial *)tty->driver_data;
-	int	ret;
-
-	if (serial_paranoia_check(info, tty->name, "rs_write_room"))
-		return 0;
-	ret = SERIAL_XMIT_SIZE - info->xmit_cnt - 1;
-	if (ret < 0)
-		ret = 0;
-	return ret;
-}
-
-static int rs_chars_in_buffer(struct tty_struct *tty)
-{
-	struct mac_serial *info = (struct mac_serial *)tty->driver_data;
-
-	if (serial_paranoia_check(info, tty->name, "rs_chars_in_buffer"))
-		return 0;
-	return info->xmit_cnt;
-}
-
-static void rs_flush_buffer(struct tty_struct *tty)
-{
-	struct mac_serial *info = (struct mac_serial *)tty->driver_data;
-	unsigned long flags;
-
-	if (serial_paranoia_check(info, tty->name, "rs_flush_buffer"))
-		return;
-	spin_lock_irqsave(&info->lock, flags);
-	info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
-	spin_unlock_irqrestore(&info->lock, flags);
-	tty_wakeup(tty);
-}
-
-/*
- * ------------------------------------------------------------
- * rs_throttle()
- * 
- * This routine is called by the upper-layer tty layer to signal that
- * incoming characters should be throttled.
- * ------------------------------------------------------------
- */
-static void rs_throttle(struct tty_struct * tty)
-{
-	struct mac_serial *info = (struct mac_serial *)tty->driver_data;
-	unsigned long flags;
-#ifdef SERIAL_DEBUG_THROTTLE
-	printk(KERN_DEBUG "throttle %ld....\n",tty->ldisc.chars_in_buffer(tty));
-#endif
-
-	if (serial_paranoia_check(info, tty->name, "rs_throttle"))
-		return;
-
-	if (I_IXOFF(tty)) {
-		spin_lock_irqsave(&info->lock, flags);
-		info->x_char = STOP_CHAR(tty);
-		if (!info->tx_active)
-			transmit_chars(info);
-		spin_unlock_irqrestore(&info->lock, flags);
-	}
-
-	if (C_CRTSCTS(tty)) {
-		/*
-		 * Here we want to turn off the RTS line.  On Macintoshes,
-		 * the external serial ports using a DIN-8 or DIN-9
-		 * connector only have the DTR line (which is usually
-		 * wired to both RTS and DTR on an external modem in
-		 * the cable).  RTS doesn't go out to the serial port
-		 * socket, it acts as an output enable for the transmit
-		 * data line.  So in this case we don't drop RTS.
-		 *
-		 * Macs with internal modems generally do have both RTS
-		 * and DTR wired to the modem, so in that case we do
-		 * drop RTS.
-		 */
-		if (info->is_internal_modem) {
-			spin_lock_irqsave(&info->lock, flags);
-			info->curregs[5] &= ~RTS;
-			info->pendregs[5] &= ~RTS;
-			write_zsreg(info->zs_channel, 5, info->curregs[5]);
-			spin_unlock_irqrestore(&info->lock, flags);
-		}
-	}
-	
-#ifdef CDTRCTS
-	if (tty->termios->c_cflag & CDTRCTS) {
-		spin_lock_irqsave(&info->lock, flags);
-		info->curregs[5] &= ~DTR;
-		info->pendregs[5] &= ~DTR;
-		write_zsreg(info->zs_channel, 5, info->curregs[5]);
-		spin_unlock_irqrestore(&info->lock, flags);
-	}
-#endif /* CDTRCTS */
-}
-
-static void rs_unthrottle(struct tty_struct * tty)
-{
-	struct mac_serial *info = (struct mac_serial *)tty->driver_data;
-	unsigned long flags;
-#ifdef SERIAL_DEBUG_THROTTLE
-	printk(KERN_DEBUG "unthrottle %s: %d....\n",
-			tty->ldisc.chars_in_buffer(tty));
-#endif
-
-	if (serial_paranoia_check(info, tty->name, "rs_unthrottle"))
-		return;
-
-	if (I_IXOFF(tty)) {
-		spin_lock_irqsave(&info->lock, flags);
-		if (info->x_char)
-			info->x_char = 0;
-		else {
-			info->x_char = START_CHAR(tty);
-			if (!info->tx_active)
-				transmit_chars(info);
-		}
-		spin_unlock_irqrestore(&info->lock, flags);
-	}
-
-	if (C_CRTSCTS(tty) && info->is_internal_modem) {
-		/* Assert RTS line */
-		spin_lock_irqsave(&info->lock, flags);
-		info->curregs[5] |= RTS;
-		info->pendregs[5] |= RTS;
-		write_zsreg(info->zs_channel, 5, info->curregs[5]);
-		spin_unlock_irqrestore(&info->lock, flags);
-	}
-
-#ifdef CDTRCTS
-	if (tty->termios->c_cflag & CDTRCTS) {
-		/* Assert DTR line */
-		spin_lock_irqsave(&info->lock, flags);
-		info->curregs[5] |= DTR;
-		info->pendregs[5] |= DTR;
-		write_zsreg(info->zs_channel, 5, info->curregs[5]);
-		spin_unlock_irqrestore(&info->lock, flags);
-	}
-#endif
-}
-
-/*
- * ------------------------------------------------------------
- * rs_ioctl() and friends
- * ------------------------------------------------------------
- */
-
-static int get_serial_info(struct mac_serial * info,
-			   struct serial_struct __user * retinfo)
-{
-	struct serial_struct tmp;
-  
-	if (!retinfo)
-		return -EFAULT;
-	memset(&tmp, 0, sizeof(tmp));
-	tmp.type = info->type;
-	tmp.line = info->line;
-	tmp.port = info->port;
-	tmp.irq = info->irq;
-	tmp.flags = info->flags;
-	tmp.baud_base = info->baud_base;
-	tmp.close_delay = info->close_delay;
-	tmp.closing_wait = info->closing_wait;
-	tmp.custom_divisor = info->custom_divisor;
-	if (copy_to_user(retinfo,&tmp,sizeof(*retinfo)))
-		return -EFAULT;
-	return 0;
-}
-
-static int set_serial_info(struct mac_serial * info,
-			   struct serial_struct __user * new_info)
-{
-	struct serial_struct new_serial;
-	struct mac_serial old_info;
-	int 			retval = 0;
-
-	if (copy_from_user(&new_serial,new_info,sizeof(new_serial)))
-		return -EFAULT;
-	old_info = *info;
-
-	if (!capable(CAP_SYS_ADMIN)) {
-		if ((new_serial.baud_base != info->baud_base) ||
-		    (new_serial.type != info->type) ||
-		    (new_serial.close_delay != info->close_delay) ||
-		    ((new_serial.flags & ~ZILOG_USR_MASK) !=
-		     (info->flags & ~ZILOG_USR_MASK)))
-			return -EPERM;
-		info->flags = ((info->flags & ~ZILOG_USR_MASK) |
-			       (new_serial.flags & ZILOG_USR_MASK));
-		info->custom_divisor = new_serial.custom_divisor;
-		goto check_and_exit;
-	}
-
-	if (info->count > 1)
-		return -EBUSY;
-
-	/*
-	 * OK, past this point, all the error checking has been done.
-	 * At this point, we start making changes.....
-	 */
-
-	info->baud_base = new_serial.baud_base;
-	info->flags = ((info->flags & ~ZILOG_FLAGS) |
-			(new_serial.flags & ZILOG_FLAGS));
-	info->type = new_serial.type;
-	info->close_delay = new_serial.close_delay;
-	info->closing_wait = new_serial.closing_wait;
-
-check_and_exit:
-	if (info->flags & ZILOG_INITIALIZED)
-		retval = setup_scc(info);
-	return retval;
-}
-
-/*
- * 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 get_lsr_info(struct mac_serial * info, unsigned int *value)
-{
-	unsigned char status;
-	unsigned long flags;
-
-	spin_lock_irqsave(&info->lock, flags);
-	status = read_zsreg(info->zs_channel, 0);
-	spin_unlock_irqrestore(&info->lock, flags);
-	status = (status & Tx_BUF_EMP)? TIOCSER_TEMT: 0;
-	return put_user(status,value);
-}
-
-static int rs_tiocmget(struct tty_struct *tty, struct file *file)
-{
-	struct mac_serial * info = (struct mac_serial *)tty->driver_data;
-	unsigned char control, status;
-	unsigned long flags;
-
-#ifdef CONFIG_KGDB
-	if (info->kgdb_channel)
-		return -ENODEV;
-#endif
-	if (serial_paranoia_check(info, tty->name, __FUNCTION__))
-		return -ENODEV;
-
-	if (tty->flags & (1 << TTY_IO_ERROR))
-		return -EIO;
-
-	spin_lock_irqsave(&info->lock, flags);
-	control = info->curregs[5];
-	status = read_zsreg(info->zs_channel, 0);
-	spin_unlock_irqrestore(&info->lock, flags);
-	return    ((control & RTS) ? TIOCM_RTS: 0)
-		| ((control & DTR) ? TIOCM_DTR: 0)
-		| ((status  & DCD) ? TIOCM_CAR: 0)
-		| ((status  & CTS) ? 0: TIOCM_CTS);
-}
-
-static int rs_tiocmset(struct tty_struct *tty, struct file *file,
-		       unsigned int set, unsigned int clear)
-{
-	struct mac_serial * info = (struct mac_serial *)tty->driver_data;
-	unsigned int arg, bits;
-	unsigned long flags;
-
-#ifdef CONFIG_KGDB
-	if (info->kgdb_channel)
-		return -ENODEV;
-#endif
-	if (serial_paranoia_check(info, tty->name, __FUNCTION__))
-		return -ENODEV;
-
-	if (tty->flags & (1 << TTY_IO_ERROR))
-		return -EIO;
-
-	spin_lock_irqsave(&info->lock, flags);
-	if (set & TIOCM_RTS)
-		info->curregs[5] |= RTS;
-	if (set & TIOCM_DTR)
-		info->curregs[5] |= DTR;
-	if (clear & TIOCM_RTS)
-		info->curregs[5] &= ~RTS;
-	if (clear & TIOCM_DTR)
-		info->curregs[5] &= ~DTR;
-
-	info->pendregs[5] = info->curregs[5];
-	write_zsreg(info->zs_channel, 5, info->curregs[5]);
-	spin_unlock_irqrestore(&info->lock, flags);
-	return 0;
-}
-
-/*
- * rs_break - turn transmit break condition on/off
- */
-static void rs_break(struct tty_struct *tty, int break_state)
-{
-	struct mac_serial *info = (struct mac_serial *) tty->driver_data;
-	unsigned long flags;
-
-	if (serial_paranoia_check(info, tty->name, "rs_break"))
-		return;
-
-	spin_lock_irqsave(&info->lock, flags);
-	if (break_state == -1)
-		info->curregs[5] |= SND_BRK;
-	else
-		info->curregs[5] &= ~SND_BRK;
-	write_zsreg(info->zs_channel, 5, info->curregs[5]);
-	spin_unlock_irqrestore(&info->lock, flags);
-}
-
-static int rs_ioctl(struct tty_struct *tty, struct file * file,
-		    unsigned int cmd, unsigned long arg)
-{
-	struct mac_serial * info = (struct mac_serial *)tty->driver_data;
-
-#ifdef CONFIG_KGDB
-	if (info->kgdb_channel)
-		return -ENODEV;
-#endif
-	if (serial_paranoia_check(info, tty->name, "rs_ioctl"))
-		return -ENODEV;
-
-	if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
-	    (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT)) {
-		if (tty->flags & (1 << TTY_IO_ERROR))
-		    return -EIO;
-	}
-
-	switch (cmd) {
-		case TIOCGSERIAL:
-			return get_serial_info(info,
-					(struct serial_struct __user *) arg);
-		case TIOCSSERIAL:
-			return set_serial_info(info,
-					(struct serial_struct __user *) arg);
-		case TIOCSERGETLSR: /* Get line status register */
-			return get_lsr_info(info, (unsigned int *) arg);
-
-		case TIOCSERGSTRUCT:
-			if (copy_to_user((struct mac_serial __user *) arg,
-					 info, sizeof(struct mac_serial)))
-				return -EFAULT;
-			return 0;
-
-		default:
-			return -ENOIOCTLCMD;
-		}
-	return 0;
-}
-
-static void rs_set_termios(struct tty_struct *tty, struct termios *old_termios)
-{
-	struct mac_serial *info = (struct mac_serial *)tty->driver_data;
-	int was_stopped;
-
-	if (tty->termios->c_cflag == old_termios->c_cflag)
-		return;
-	was_stopped = info->tx_stopped;
-
-	change_speed(info, old_termios);
-
-	if (was_stopped && !info->tx_stopped) {
-		tty->hw_stopped = 0;
-		rs_start(tty);
-	}
-}
-
-/*
- * ------------------------------------------------------------
- * rs_close()
- * 
- * This routine is called when the serial port gets closed.
- * Wait for the last remaining data to be sent.
- * ------------------------------------------------------------
- */
-static void rs_close(struct tty_struct *tty, struct file * filp)
-{
-	struct mac_serial * info = (struct mac_serial *)tty->driver_data;
-	unsigned long flags;
-
-	if (!info || serial_paranoia_check(info, tty->name, "rs_close"))
-		return;
-
-	spin_lock_irqsave(&info->lock, flags);
-
-	if (tty_hung_up_p(filp)) {
-		spin_unlock_irqrestore(&info->lock, flags);
-		return;
-	}
-
-	OPNDBG("rs_close ttyS%d, count = %d\n", info->line, info->count);
-	if ((tty->count == 1) && (info->count != 1)) {
-		/*
-		 * Uh, oh.  tty->count is 1, which means that the tty
-		 * structure will be freed.  Info->count should always
-		 * be one in these conditions.  If it's greater than
-		 * one, we've got real problems, since it means the
-		 * serial port won't be shutdown.
-		 */
-		printk(KERN_ERR "rs_close: bad serial port count; tty->count "
-				"is 1, info->count is %d\n", info->count);
-		info->count = 1;
-	}
-	if (--info->count < 0) {
-		printk(KERN_ERR "rs_close: bad serial port count for "
-				"ttyS%d: %d\n", info->line, info->count);
-		info->count = 0;
-	}
-	if (info->count) {
-		spin_unlock_irqrestore(&info->lock, flags);
-		return;
-	}
-	info->flags |= ZILOG_CLOSING;
-	/*
-	 * Now we wait for the transmit buffer to clear; and we notify 
-	 * the line discipline to only process XON/XOFF characters.
-	 */
-	OPNDBG("waiting end of Tx... (timeout:%d)\n", info->closing_wait);
-	tty->closing = 1;
-	if (info->closing_wait != ZILOG_CLOSING_WAIT_NONE) {
-		spin_unlock_irqrestore(&info->lock, flags);
-		tty_wait_until_sent(tty, info->closing_wait);
-		spin_lock_irqsave(&info->lock, flags);
-	}
-
-	/*
-	 * At this point we stop accepting input.  To do this, we
-	 * disable the receiver and receive interrupts.
-	 */
-	info->curregs[3] &= ~RxENABLE;
-	info->pendregs[3] = info->curregs[3];
-	write_zsreg(info->zs_channel, 3, info->curregs[3]);
-	info->curregs[1] &= ~(0x18);	/* disable any rx ints */
-	info->pendregs[1] = info->curregs[1];
-	write_zsreg(info->zs_channel, 1, info->curregs[1]);
-	ZS_CLEARFIFO(info->zs_channel);
-	if (info->flags & ZILOG_INITIALIZED) {
-		/*
-		 * Before we drop DTR, make sure the SCC transmitter
-		 * has completely drained.
-		 */
-		OPNDBG("waiting end of Rx...\n");
-		spin_unlock_irqrestore(&info->lock, flags);
-		rs_wait_until_sent(tty, info->timeout);
-		spin_lock_irqsave(&info->lock, flags);
-	}
-
-	shutdown(info);
-	/* restore flags now since shutdown() will have disabled this port's
-	   specific irqs */
-	spin_unlock_irqrestore(&info->lock, flags);
-
-	if (tty->driver->flush_buffer)
-		tty->driver->flush_buffer(tty);
-	tty_ldisc_flush(tty);
-	tty->closing = 0;
-	info->event = 0;
-	info->tty = 0;
-
-	if (info->blocked_open) {
-		if (info->close_delay) {
-			msleep_interruptible(jiffies_to_msecs(info->close_delay));
-		}
-		wake_up_interruptible(&info->open_wait);
-	}
-	info->flags &= ~(ZILOG_NORMAL_ACTIVE|ZILOG_CLOSING);
-	wake_up_interruptible(&info->close_wait);
-}
-
-/*
- * rs_wait_until_sent() --- wait until the transmitter is empty
- */
-static void rs_wait_until_sent(struct tty_struct *tty, int timeout)
-{
-	struct mac_serial *info = (struct mac_serial *) tty->driver_data;
-	unsigned long orig_jiffies, char_time;
-
-	if (serial_paranoia_check(info, tty->name, "rs_wait_until_sent"))
-		return;
-
-/*	printk("rs_wait_until_sent, timeout:%d, tty_stopped:%d, tx_stopped:%d\n",
-			timeout, tty->stopped, info->tx_stopped);
-*/
-	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.
-	 */
-	if (info->timeout <= HZ/50) {
-		printk(KERN_INFO "macserial: invalid info->timeout=%d\n",
-				    info->timeout);
-		info->timeout = HZ/50+1;
-	}
-
-	char_time = (info->timeout - HZ/50) / info->xmit_fifo_size;
-	char_time = char_time / 5;
-	if (char_time > HZ) {
-		printk(KERN_WARNING "macserial: char_time %ld >HZ !!!\n",
-				    char_time);
-		char_time = 1;
-	} else if (char_time == 0)
-		char_time = 1;
-	if (timeout)
-		char_time = min_t(unsigned long, char_time, timeout);
-	while ((read_zsreg(info->zs_channel, 1) & ALL_SNT) == 0) {
-		msleep_interruptible(jiffies_to_msecs(char_time));
-		if (signal_pending(current))
-			break;
-		if (timeout && time_after(jiffies, orig_jiffies + timeout))
-			break;
-	}
-	current->state = TASK_RUNNING;
-}
-
-/*
- * rs_hangup() --- called by tty_hangup() when a hangup is signaled.
- */
-static void rs_hangup(struct tty_struct *tty)
-{
-	struct mac_serial * info = (struct mac_serial *)tty->driver_data;
-
-	if (serial_paranoia_check(info, tty->name, "rs_hangup"))
-		return;
-
-	rs_flush_buffer(tty);
-	shutdown(info);
-	info->event = 0;
-	info->count = 0;
-	info->flags &= ~ZILOG_NORMAL_ACTIVE;
-	info->tty = 0;
-	wake_up_interruptible(&info->open_wait);
-}
-
-/*
- * ------------------------------------------------------------
- * rs_open() and friends
- * ------------------------------------------------------------
- */
-static int block_til_ready(struct tty_struct *tty, struct file * filp,
-			   struct mac_serial *info)
-{
-	DECLARE_WAITQUEUE(wait,current);
-	int		retval;
-	int		do_clocal = 0;
-
-	/*
-	 * If the device is in the middle of being closed, then block
-	 * until it's done, and then try again.
-	 */
-	if (info->flags & ZILOG_CLOSING) {
-		interruptible_sleep_on(&info->close_wait);
-		return -EAGAIN;
-	}
-
-	/*
-	 * 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))) {
-		info->flags |= ZILOG_NORMAL_ACTIVE;
-		return 0;
-	}
-
-	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, info->count is dropped by one, so that
-	 * rs_close() knows when to free things.  We restore it upon
-	 * exit, either normal or abnormal.
-	 */
-	retval = 0;
-	add_wait_queue(&info->open_wait, &wait);
-	OPNDBG("block_til_ready before block: ttyS%d, count = %d\n",
-	       info->line, info->count);
-	spin_lock_irq(&info->lock);
-	if (!tty_hung_up_p(filp)) 
-		info->count--;
-	spin_unlock_irq(&info->lock);
-	info->blocked_open++;
-	while (1) {
-		spin_lock_irq(&info->lock);
-		if ((tty->termios->c_cflag & CBAUD) &&
-		    !info->is_irda)
-			zs_rtsdtr(info, 1);
-		spin_unlock_irq(&info->lock);
-		set_current_state(TASK_INTERRUPTIBLE);
-		if (tty_hung_up_p(filp) ||
-		    !(info->flags & ZILOG_INITIALIZED)) {
-			retval = -EAGAIN;
-			break;
-		}
-		if (!(info->flags & ZILOG_CLOSING) &&
-		    (do_clocal || (read_zsreg(info->zs_channel, 0) & DCD)))
-			break;
-		if (signal_pending(current)) {
-			retval = -ERESTARTSYS;
-			break;
-		}
-		OPNDBG("block_til_ready blocking: ttyS%d, count = %d\n",
-		       info->line, info->count);
-		schedule();
-	}
-	current->state = TASK_RUNNING;
-	remove_wait_queue(&info->open_wait, &wait);
-	if (!tty_hung_up_p(filp))
-		info->count++;
-	info->blocked_open--;
-	OPNDBG("block_til_ready after blocking: ttyS%d, count = %d\n",
-	       info->line, info->count);
-	if (retval)
-		return retval;
-	info->flags |= ZILOG_NORMAL_ACTIVE;
-	return 0;
-}
-
-/*
- * This routine is called whenever a serial port is opened.  It
- * enables interrupts for a serial port, linking in its ZILOG structure into
- * the IRQ chain.   It also performs the serial-specific
- * initialization for the tty structure.
- */
-static int rs_open(struct tty_struct *tty, struct file * filp)
-{
-	struct mac_serial	*info;
-	int 			retval, line;
-	unsigned long		page;
-
-	line = tty->index;
-	if ((line < 0) || (line >= zs_channels_found)) {
-		return -ENODEV;
-	}
-	info = zs_soft + line;
-
-#ifdef CONFIG_KGDB
-	if (info->kgdb_channel) {
-		return -ENODEV;
-	}
-#endif
-	if (serial_paranoia_check(info, tty->name, "rs_open"))
-		return -ENODEV;
-	OPNDBG("rs_open %s, count = %d, tty=%p\n", tty->name,
-	       info->count, tty);
-
-	info->count++;
-	tty->driver_data = info;
-	info->tty = tty;
-
-	if (!tmp_buf) {
-		page = get_zeroed_page(GFP_KERNEL);
-		if (!page)
-			return -ENOMEM;
-		if (tmp_buf)
-			free_page(page);
-		else
-			tmp_buf = (unsigned char *) page;
-	}
-
-	/*
-	 * If the port is the middle of closing, bail out now
-	 */
-	if (tty_hung_up_p(filp) ||
-	    (info->flags & ZILOG_CLOSING)) {
-		if (info->flags & ZILOG_CLOSING)
-			interruptible_sleep_on(&info->close_wait);
-		return -EAGAIN;
-	}
-
-	/*
-	 * Start up serial port
-	 */
-
-	retval = startup(info);
-	if (retval)
-		return retval;
-
-	retval = block_til_ready(tty, filp, info);
-	if (retval) {
-		OPNDBG("rs_open returning after block_til_ready with %d\n",
-			retval);
-		return retval;
-	}
-
-#ifdef CONFIG_SERIAL_CONSOLE
-	if (sercons.cflag && sercons.index == line) {
-		tty->termios->c_cflag = sercons.cflag;
-		sercons.cflag = 0;
-		change_speed(info, 0);
-	}
-#endif
-
-	OPNDBG("rs_open %s successful...\n", tty->name);
-	return 0;
-}
-
-/* Finally, routines used to initialize the serial driver. */
-
-static void show_serial_version(void)
-{
-	printk(KERN_INFO "PowerMac Z8530 serial driver version " MACSERIAL_VERSION "\n");
-}
-
-/*
- * Initialize one channel, both the mac_serial and mac_zschannel
- * structs.  We use the dev_node field of the mac_serial struct.
- */
-static int
-chan_init(struct mac_serial *zss, struct mac_zschannel *zs_chan,
-	  struct mac_zschannel *zs_chan_a)
-{
-	struct device_node *ch = zss->dev_node;
-	char *conn;
-	int len;
-	struct slot_names_prop {
-		int	count;
-		char	name[1];
-	} *slots;
-
-	zss->irq = ch->intrs[0].line;
-	zss->has_dma = 0;
-#if !defined(CONFIG_KGDB) && defined(SUPPORT_SERIAL_DMA)
-	if (ch->n_addrs >= 3 && ch->n_intrs == 3)
-		zss->has_dma = 1;
-#endif
-	zss->dma_initted = 0;
-
-	zs_chan->control = (volatile unsigned char *)
-		ioremap(ch->addrs[0].address, 0x1000);
-	zs_chan->data = zs_chan->control + 0x10;
-	spin_lock_init(&zs_chan->lock);
-	zs_chan->parent = zss;
-	zss->zs_channel = zs_chan;
-	zss->zs_chan_a = zs_chan_a;
-
-	/* setup misc varariables */
-	zss->kgdb_channel = 0;
-
-	/* For now, we assume you either have a slot-names property
-	 * with "Modem" in it, or your channel is compatible with
-	 * "cobalt". Might need additional fixups
-	 */
-	zss->is_internal_modem = device_is_compatible(ch, "cobalt");
-	conn = get_property(ch, "AAPL,connector", &len);
-	zss->is_irda = conn && (strcmp(conn, "infrared") == 0);
-	zss->port_type = PMAC_SCC_ASYNC;
-	/* 1999 Powerbook G3 has slot-names property instead */
-	slots = (struct slot_names_prop *)get_property(ch, "slot-names", &len);
-	if (slots && slots->count > 0) {
-		if (strcmp(slots->name, "IrDA") == 0)
-			zss->is_irda = 1;
-		else if (strcmp(slots->name, "Modem") == 0)
-			zss->is_internal_modem = 1;
-	}
-	if (zss->is_irda)
-		zss->port_type = PMAC_SCC_IRDA;
-	if (zss->is_internal_modem) {
-		struct device_node* i2c_modem = find_devices("i2c-modem");
-		if (i2c_modem) {
-			char* mid = get_property(i2c_modem, "modem-id", NULL);
-			if (mid) switch(*mid) {
-			case 0x04 :
-			case 0x05 :
-			case 0x07 :
-			case 0x08 :
-			case 0x0b :
-			case 0x0c :
-				zss->port_type = PMAC_SCC_I2S1;
-			}
-			printk(KERN_INFO "macserial: i2c-modem detected, id: %d\n",
-				mid ? (*mid) : 0);
-		} else {
-			printk(KERN_INFO "macserial: serial modem detected\n");
-		}
-	}
-
-	while (zss->has_dma) {
-		zss->dma_priv = NULL;
-		/* it seems that the last two addresses are the
-		   DMA controllers */
-		zss->tx_dma = (volatile struct dbdma_regs *)
-			ioremap(ch->addrs[ch->n_addrs - 2].address, 0x100);
-		zss->rx = (volatile struct mac_dma *)
-			ioremap(ch->addrs[ch->n_addrs - 1].address, 0x100);
-		zss->tx_dma_irq = ch->intrs[1].line;
-		zss->rx_dma_irq = ch->intrs[2].line;
-		spin_lock_init(&zss->rx_dma_lock);
-		break;
-	}
-
-	init_timer(&zss->powerup_timer);
-	zss->powerup_timer.function = powerup_done;
-	zss->powerup_timer.data = (unsigned long) zss;
-	return 0;
-}
-
-/*
- * /proc fs routines. TODO: Add status lines & error stats
- */
-static inline int
-line_info(char *buf, struct mac_serial *info)
-{
-	int		ret=0;
-	unsigned char* connector;
-	int lenp;
-
-	ret += sprintf(buf, "%d: port:0x%X irq:%d", info->line, info->port, info->irq);
-
-	connector = get_property(info->dev_node, "AAPL,connector", &lenp);
-	if (connector)
-		ret+=sprintf(buf+ret," con:%s ", connector);
-	if (info->is_internal_modem) {
-		if (!connector)
-			ret+=sprintf(buf+ret," con:");
-		ret+=sprintf(buf+ret,"%s", " (internal modem)");
-	}
-	if (info->is_irda) {
-		if (!connector)
-			ret+=sprintf(buf+ret," con:");
-		ret+=sprintf(buf+ret,"%s", " (IrDA)");
-	}
-	ret+=sprintf(buf+ret,"\n");
-
-	return ret;
-}
-
-int macserial_read_proc(char *page, char **start, off_t off, int count,
-		 int *eof, void *data)
-{
-	int l, len = 0;
-	off_t	begin = 0;
-	struct mac_serial *info;
-
-	len += sprintf(page, "serinfo:1.0 driver:" MACSERIAL_VERSION "\n");
-	for (info = zs_chain; info && len < 4000; info = info->zs_next) {
-		l = line_info(page + len, info);
-		len += l;
-		if (len+begin > off+count)
-			goto done;
-		if (len+begin < off) {
-			begin += len;
-			len = 0;
-		}
-	}
-	*eof = 1;
-done:
-	if (off >= len+begin)
-		return 0;
-	*start = page + (off-begin);
-	return ((count < begin+len-off) ? count : begin+len-off);
-}
-
-/* Ask the PROM how many Z8530s we have and initialize their zs_channels */
-static void
-probe_sccs(void)
-{
-	struct device_node *dev, *ch;
-	struct mac_serial **pp;
-	int n, chip, nchan;
-	struct mac_zschannel *zs_chan;
-	int chan_a_index;
-
-	n = 0;
-	pp = &zs_chain;
-	zs_chan = zs_channels;
-	for (dev = find_devices("escc"); dev != 0; dev = dev->next) {
-		nchan = 0;
-		chip = n;
-		if (n >= NUM_CHANNELS) {
-			printk(KERN_WARNING "Sorry, can't use %s: no more "
-					    "channels\n", dev->full_name);
-			continue;
-		}
-		chan_a_index = 0;
-		for (ch = dev->child; ch != 0; ch = ch->sibling) {
-			if (nchan >= 2) {
-				printk(KERN_WARNING "SCC: Only 2 channels per "
-					"chip are supported\n");
-				break;
-			}
-			if (ch->n_addrs < 1 || (ch ->n_intrs < 1)) {
-				printk("Can't use %s: %d addrs %d intrs\n",
-				      ch->full_name, ch->n_addrs, ch->n_intrs);
-				continue;
-			}
-
-			/* The channel with the higher address
-			   will be the A side. */
-			if (nchan > 0 &&
-			    ch->addrs[0].address
-			    > zs_soft[n-1].dev_node->addrs[0].address)
-				chan_a_index = 1;
-
-			/* minimal initialization for now */
-			zs_soft[n].dev_node = ch;
-			*pp = &zs_soft[n];
-			pp = &zs_soft[n].zs_next;
-			++nchan;
-			++n;
-		}
-		if (nchan == 0)
-			continue;
-
-		/* set up A side */
-		if (chan_init(&zs_soft[chip + chan_a_index], zs_chan, zs_chan))
-			continue;
-		++zs_chan;
-
-		/* set up B side, if it exists */
-		if (nchan > 1)
-			if (chan_init(&zs_soft[chip + 1 - chan_a_index],
-				  zs_chan, zs_chan - 1))
-				continue;
-		++zs_chan;
-	}
-	*pp = 0;
-
-	zs_channels_found = n;
-#ifdef CONFIG_PMAC_PBOOK
-	if (n)
-		pmu_register_sleep_notifier(&serial_sleep_notifier);
-#endif /* CONFIG_PMAC_PBOOK */
-}
-
-static struct tty_operations serial_ops = {
-	.open = rs_open,
-	.close = rs_close,
-	.write = rs_write,
-	.flush_chars = rs_flush_chars,
-	.write_room = rs_write_room,
-	.chars_in_buffer = rs_chars_in_buffer,
-	.flush_buffer = rs_flush_buffer,
-	.ioctl = rs_ioctl,
-	.throttle = rs_throttle,
-	.unthrottle = rs_unthrottle,
-	.set_termios = rs_set_termios,
-	.stop = rs_stop,
-	.start = rs_start,
-	.hangup = rs_hangup,
-	.break_ctl = rs_break,
-	.wait_until_sent = rs_wait_until_sent,
-	.read_proc = macserial_read_proc,
-	.tiocmget = rs_tiocmget,
-	.tiocmset = rs_tiocmset,
-};
-
-static int macserial_init(void)
-{
-	int channel, i;
-	struct mac_serial *info;
-
-	/* Find out how many Z8530 SCCs we have */
-	if (zs_chain == 0)
-		probe_sccs();
-
-	serial_driver = alloc_tty_driver(zs_channels_found);
-	if (!serial_driver)
-		return -ENOMEM;
-
-	/* XXX assume it's a powerbook if we have a via-pmu
-	 * 
-	 * This is OK for core99 machines as well.
-	 */
-	is_powerbook = find_devices("via-pmu") != 0;
-
-	/* Register the interrupt handler for each one
-	 * We also request the OF resources here as probe_sccs()
-	 * might be called too early for that
-	 */
-	for (i = 0; i < zs_channels_found; ++i) {
-		struct device_node* ch = zs_soft[i].dev_node;
-		if (!request_OF_resource(ch, 0, NULL)) {
-			printk(KERN_ERR "macserial: can't request IO resource !\n");
-			put_tty_driver(serial_driver);
-			return -ENODEV;
-		}
-		if (zs_soft[i].has_dma) {
-			if (!request_OF_resource(ch, ch->n_addrs - 2, " (tx dma)")) {
-				printk(KERN_ERR "macserial: can't request TX DMA resource !\n");
-				zs_soft[i].has_dma = 0;
-				goto no_dma;
-			}
-			if (!request_OF_resource(ch, ch->n_addrs - 1, " (rx dma)")) {
-				release_OF_resource(ch, ch->n_addrs - 2);
-				printk(KERN_ERR "macserial: can't request RX DMA resource !\n");
-				zs_soft[i].has_dma = 0;
-				goto no_dma;
-			}
-			if (request_irq(zs_soft[i].tx_dma_irq, rs_txdma_irq, 0,
-					"SCC-txdma", &zs_soft[i]))
-				printk(KERN_ERR "macserial: can't get irq %d\n",
-				       zs_soft[i].tx_dma_irq);
-			disable_irq(zs_soft[i].tx_dma_irq);
-			if (request_irq(zs_soft[i].rx_dma_irq, rs_rxdma_irq, 0,
-					"SCC-rxdma", &zs_soft[i]))
-				printk(KERN_ERR "macserial: can't get irq %d\n",
-				       zs_soft[i].rx_dma_irq);
-			disable_irq(zs_soft[i].rx_dma_irq);
-		}
-no_dma:		
-		if (request_irq(zs_soft[i].irq, rs_interrupt, 0,
-				"SCC", &zs_soft[i]))
-			printk(KERN_ERR "macserial: can't get irq %d\n",
-			       zs_soft[i].irq);
-		disable_irq(zs_soft[i].irq);
-	}
-
-	show_serial_version();
-
-	/* Initialize the tty_driver structure */
-	/* Not all of this is exactly right for us. */
-
-	serial_driver->owner = THIS_MODULE;
-	serial_driver->driver_name = "macserial";
-	serial_driver->devfs_name = "tts/";
-	serial_driver->name = "ttyS";
-	serial_driver->major = TTY_MAJOR;
-	serial_driver->minor_start = 64;
-	serial_driver->type = TTY_DRIVER_TYPE_SERIAL;
-	serial_driver->subtype = SERIAL_TYPE_NORMAL;
-	serial_driver->init_termios = tty_std_termios;
-	serial_driver->init_termios.c_cflag =
-		B38400 | CS8 | CREAD | HUPCL | CLOCAL;
-	serial_driver->flags = TTY_DRIVER_REAL_RAW;
-	tty_set_operations(serial_driver, &serial_ops);
-
-	if (tty_register_driver(serial_driver))
-		printk(KERN_ERR "Error: couldn't register serial driver\n");
-
-	for (channel = 0; channel < zs_channels_found; ++channel) {
-#ifdef CONFIG_KGDB
-		if (zs_soft[channel].kgdb_channel) {
-			kgdb_interruptible(1);
-			continue;
-		}
-#endif
-		zs_soft[channel].clk_divisor = 16;
-/* -- we are not sure the SCC is powered ON at this point
- 		zs_soft[channel].zs_baud = get_zsbaud(&zs_soft[channel]);
-*/
-		zs_soft[channel].zs_baud = 38400;
-
-		/* If console serial line, then enable interrupts. */
-		if (zs_soft[channel].is_cons) {
-			printk(KERN_INFO "macserial: console line, enabling "
-					"interrupt %d\n", zs_soft[channel].irq);
-			panic("macserial: console not supported yet !");
-			write_zsreg(zs_soft[channel].zs_channel, R1,
-				    (EXT_INT_ENAB | INT_ALL_Rx | TxINT_ENAB));
-			write_zsreg(zs_soft[channel].zs_channel, R9,
-				    (NV | MIE));
-		}
-	}
-
-	for (info = zs_chain, i = 0; info; info = info->zs_next, i++)
-	{
-		unsigned char* connector;
-		int lenp;
-
-#ifdef CONFIG_KGDB
-		if (info->kgdb_channel) {
-			continue;
-		}
-#endif
-		info->magic = SERIAL_MAGIC;
-		info->port = (int) info->zs_channel->control;
-		info->line = i;
-		info->tty = 0;
-		info->custom_divisor = 16;
-		info->timeout = 0;
-		info->close_delay = 50;
-		info->closing_wait = 3000;
-		info->x_char = 0;
-		info->event = 0;
-		info->count = 0;
-		info->blocked_open = 0;
-		INIT_WORK(&info->tqueue, do_softint, info);
-		spin_lock_init(&info->lock);
-		init_waitqueue_head(&info->open_wait);
-		init_waitqueue_head(&info->close_wait);
-		info->timeout = HZ;
-		printk(KERN_INFO "tty%02d at 0x%08x (irq = %d)", info->line, 
-			info->port, info->irq);
-		printk(" is a Z8530 ESCC");
-		connector = get_property(info->dev_node, "AAPL,connector", &lenp);
-		if (connector)
-			printk(", port = %s", connector);
-		if (info->is_internal_modem)
-			printk(" (internal modem)");
-		if (info->is_irda)
-			printk(" (IrDA)");
-		printk("\n");
- 	}
-	tmp_buf = 0;
-
-	return 0;
-}
-
-void macserial_cleanup(void)
-{
-	int i;
-	unsigned long flags;
-	struct mac_serial *info;
-
-	for (info = zs_chain, i = 0; info; info = info->zs_next, i++)
-		set_scc_power(info, 0);
-	spin_lock_irqsave(&info->lock, flags);
-	for (i = 0; i < zs_channels_found; ++i) {
-		free_irq(zs_soft[i].irq, &zs_soft[i]);
-		if (zs_soft[i].has_dma) {
-			free_irq(zs_soft[i].tx_dma_irq, &zs_soft[i]);
-			free_irq(zs_soft[i].rx_dma_irq, &zs_soft[i]);
-		}
-		release_OF_resource(zs_soft[i].dev_node, 0);
-		if (zs_soft[i].has_dma) {
-			struct device_node* ch = zs_soft[i].dev_node;
-			release_OF_resource(ch, ch->n_addrs - 2);
-			release_OF_resource(ch, ch->n_addrs - 1);
-		}
-	}
-	spin_unlock_irqrestore(&info->lock, flags);
-	tty_unregister_driver(serial_driver);
-	put_tty_driver(serial_driver);
-
-	if (tmp_buf) {
-		free_page((unsigned long) tmp_buf);
-		tmp_buf = 0;
-	}
-
-#ifdef CONFIG_PMAC_PBOOK
-	if (zs_channels_found)
-		pmu_unregister_sleep_notifier(&serial_sleep_notifier);
-#endif /* CONFIG_PMAC_PBOOK */
-}
-
-module_init(macserial_init);
-module_exit(macserial_cleanup);
-MODULE_LICENSE("GPL");
-
-#if 0
-/*
- * register_serial and unregister_serial allows for serial ports to be
- * configured at run-time, to support PCMCIA modems.
- */
-/* PowerMac: Unused at this time, just here to make things link. */
-int register_serial(struct serial_struct *req)
-{
-	return -1;
-}
-
-void unregister_serial(int line)
-{
-	return;
-}
-#endif
-
-/*
- * ------------------------------------------------------------
- * Serial console driver
- * ------------------------------------------------------------
- */
-#ifdef CONFIG_SERIAL_CONSOLE
-
-/*
- *	Print a string to the serial port trying not to disturb
- *	any possible real use of the port...
- */
-static void serial_console_write(struct console *co, const char *s,
-				 unsigned count)
-{
-	struct mac_serial *info = zs_soft + co->index;
-	int i;
-
-	/* Turn of interrupts and enable the transmitter. */
-	write_zsreg(info->zs_channel, R1, info->curregs[1] & ~TxINT_ENAB);
-	write_zsreg(info->zs_channel, R5, info->curregs[5] | TxENAB | RTS | DTR);
-
-	for (i=0; i<count; i++) {
-		/* Wait for the transmit buffer to empty. */
-		while ((read_zsreg(info->zs_channel, 0) & Tx_BUF_EMP) == 0) {
-			eieio();
-		}
-
-		write_zsdata(info->zs_channel, s[i]);
-		if (s[i] == 10) {
-			while ((read_zsreg(info->zs_channel, 0) & Tx_BUF_EMP)
-                                == 0)
-				eieio();
-
-			write_zsdata(info->zs_channel, 13);
-		}
-	}
-
-	/* Restore the values in the registers. */
-	write_zsreg(info->zs_channel, R1, info->curregs[1]);
-	/* Don't disable the transmitter. */
-}
-
-static struct tty_driver *serial_driver;
-
-static struct tty_driver *serial_console_device(struct console *c, int *index)
-{
-	*index = c->index;
-	return serial_driver;
-}
-
-/*
- *	Setup initial baud/bits/parity. We do two things here:
- *	- construct a cflag setting for the first rs_open()
- *	- initialize the serial port
- *	Return non-zero if we didn't find a serial port.
- */
-static int __init serial_console_setup(struct console *co, char *options)
-{
-	struct mac_serial *info;
-	int	baud = 38400;
-	int	bits = 8;
-	int	parity = 'n';
-	int	cflag = CREAD | HUPCL | CLOCAL;
-	int	brg;
-	char	*s;
-	long	flags;
-
-	/* Find out how many Z8530 SCCs we have */
-	if (zs_chain == 0)
-		probe_sccs();
-
-	if (zs_chain == 0)
-		return -1;
-
-	/* Do we have the device asked for? */
-	if (co->index >= zs_channels_found)
-		return -1;
-	info = zs_soft + co->index;
-
-	set_scc_power(info, 1);
-
-	/* Reset the channel */
-	write_zsreg(info->zs_channel, R9, CHRA);
-
-	if (options) {
-		baud = simple_strtoul(options, NULL, 10);
-		s = options;
-		while(*s >= '0' && *s <= '9')
-			s++;
-		if (*s)
-			parity = *s++;
-		if (*s)
-			bits   = *s - '0';
-	}
-
-	/*
-	 *	Now construct a cflag setting.
-	 */
-	switch(baud) {
-	case 1200:
-		cflag |= B1200;
-		break;
-	case 2400:
-		cflag |= B2400;
-		break;
-	case 4800:
-		cflag |= B4800;
-		break;
-	case 9600:
-		cflag |= B9600;
-		break;
-	case 19200:
-		cflag |= B19200;
-		break;
-	case 57600:
-		cflag |= B57600;
-		break;
-	case 115200:
-		cflag |= B115200;
-		break;
-	case 38400:
-	default:
-		cflag |= B38400;
-		break;
-	}
-	switch(bits) {
-	case 7:
-		cflag |= CS7;
-		break;
-	default:
-	case 8:
-		cflag |= CS8;
-		break;
-	}
-	switch(parity) {
-	case 'o': case 'O':
-		cflag |= PARENB | PARODD;
-		break;
-	case 'e': case 'E':
-		cflag |= PARENB;
-		break;
-	}
-	co->cflag = cflag;
-
-	spin_lock_irqsave(&info->lock, flags);
-        memset(info->curregs, 0, sizeof(info->curregs));
-
-	info->zs_baud = baud;
-	info->clk_divisor = 16;
-	switch (info->zs_baud) {
-	case ZS_CLOCK/16:	/* 230400 */
-		info->curregs[4] = X16CLK;
-		info->curregs[11] = 0;
-		break;
-	case ZS_CLOCK/32:	/* 115200 */
-		info->curregs[4] = X32CLK;
-		info->curregs[11] = 0;
-		break;
-	default:
-		info->curregs[4] = X16CLK;
-		info->curregs[11] = TCBR | RCBR;
-		brg = BPS_TO_BRG(info->zs_baud, ZS_CLOCK/info->clk_divisor);
-		info->curregs[12] = (brg & 255);
-		info->curregs[13] = ((brg >> 8) & 255);
-		info->curregs[14] = BRENABL;
-	}
-
-	/* byte size and parity */
-	info->curregs[3] &= ~RxNBITS_MASK;
-	info->curregs[5] &= ~TxNBITS_MASK;
-	switch (cflag & CSIZE) {
-	case CS5:
-		info->curregs[3] |= Rx5;
-		info->curregs[5] |= Tx5;
-		break;
-	case CS6:
-		info->curregs[3] |= Rx6;
-		info->curregs[5] |= Tx6;
-		break;
-	case CS7:
-		info->curregs[3] |= Rx7;
-		info->curregs[5] |= Tx7;
-		break;
-	case CS8:
-	default: /* defaults to 8 bits */
-		info->curregs[3] |= Rx8;
-		info->curregs[5] |= Tx8;
-		break;
-	}
-        info->curregs[5] |= TxENAB | RTS | DTR;
-	info->pendregs[3] = info->curregs[3];
-	info->pendregs[5] = info->curregs[5];
-
-	info->curregs[4] &= ~(SB_MASK | PAR_ENA | PAR_EVEN);
-	if (cflag & CSTOPB) {
-		info->curregs[4] |= SB2;
-	} else {
-		info->curregs[4] |= SB1;
-	}
-	if (cflag & PARENB) {
-		info->curregs[4] |= PAR_ENA;
-		if (!(cflag & PARODD)) {
-			info->curregs[4] |= PAR_EVEN;
-		}
-	}
-	info->pendregs[4] = info->curregs[4];
-
-	if (!(cflag & CLOCAL)) {
-		if (!(info->curregs[15] & DCDIE))
-			info->read_reg_zero = read_zsreg(info->zs_channel, 0);
-		info->curregs[15] |= DCDIE;
-	} else
-		info->curregs[15] &= ~DCDIE;
-	if (cflag & CRTSCTS) {
-		info->curregs[15] |= CTSIE;
-		if ((read_zsreg(info->zs_channel, 0) & CTS) != 0)
-			info->tx_stopped = 1;
-	} else {
-		info->curregs[15] &= ~CTSIE;
-		info->tx_stopped = 0;
-	}
-	info->pendregs[15] = info->curregs[15];
-
-	/* Load up the new values */
-	load_zsregs(info->zs_channel, info->curregs);
-
-	spin_unlock_irqrestore(&info->lock, flags);
-
-	return 0;
-}
-
-static struct console sercons = {
-	.name		= "ttyS",
-	.write		= serial_console_write,
-	.device		= serial_console_device,
-	.setup		= serial_console_setup,
-	.flags		= CON_PRINTBUFFER,
-	.index		= -1,
-};
-
-/*
- *	Register console.
- */
-static void __init mac_scc_console_init(void)
-{
-	register_console(&sercons);
-}
-console_initcall(mac_scc_console_init);
-
-#endif /* ifdef CONFIG_SERIAL_CONSOLE */
-
-#ifdef CONFIG_KGDB
-/* These are for receiving and sending characters under the kgdb
- * source level kernel debugger.
- */
-void putDebugChar(char kgdb_char)
-{
-	struct mac_zschannel *chan = zs_kgdbchan;
-	while ((read_zsreg(chan, 0) & Tx_BUF_EMP) == 0)
-		udelay(5);
-	write_zsdata(chan, kgdb_char);
-}
-
-char getDebugChar(void)
-{
-	struct mac_zschannel *chan = zs_kgdbchan;
-	while((read_zsreg(chan, 0) & Rx_CH_AV) == 0)
-		eieio(); /*barrier();*/
-	return read_zsdata(chan);
-}
-
-void kgdb_interruptible(int yes)
-{
-	struct mac_zschannel *chan = zs_kgdbchan;
-	int one, nine;
-	nine = read_zsreg(chan, 9);
-	if (yes == 1) {
-		one = EXT_INT_ENAB|INT_ALL_Rx;
-		nine |= MIE;
-		printk("turning serial ints on\n");
-	} else {
-		one = RxINT_DISAB;
-		nine &= ~MIE;
-		printk("turning serial ints off\n");
-	}
-	write_zsreg(chan, 1, one);
-	write_zsreg(chan, 9, nine);
-}
-
-/* This sets up the serial port we're using, and turns on
- * interrupts for that channel, so kgdb is usable once we're done.
- */
-static inline void kgdb_chaninit(struct mac_zschannel *ms, int intson, int bps)
-{
-	int brg;
-	int i, x;
-	volatile char *sccc = ms->control;
-	brg = BPS_TO_BRG(bps, ZS_CLOCK/16);
-	printk("setting bps on kgdb line to %d [brg=%x]\n", bps, brg);
-	for (i = 20000; i != 0; --i) {
-		x = *sccc; eieio();
-	}
-	for (i = 0; i < sizeof(scc_inittab); ++i) {
-		write_zsreg(ms, scc_inittab[i], scc_inittab[i+1]);
-		i++;
-	}
-}
-
-/* This is called at boot time to prime the kgdb serial debugging
- * serial line.  The 'tty_num' argument is 0 for /dev/ttya and 1
- * for /dev/ttyb which is determined in setup_arch() from the
- * boot command line flags.
- * XXX at the moment probably only channel A will work
- */
-void __init zs_kgdb_hook(int tty_num)
-{
-	/* Find out how many Z8530 SCCs we have */
-	if (zs_chain == 0)
-		probe_sccs();
-
-	set_scc_power(&zs_soft[tty_num], 1);
-
-	zs_kgdbchan = zs_soft[tty_num].zs_channel;
-	zs_soft[tty_num].change_needed = 0;
-	zs_soft[tty_num].clk_divisor = 16;
-	zs_soft[tty_num].zs_baud = 38400;
-	zs_soft[tty_num].kgdb_channel = 1;     /* This runs kgdb */
-
-	/* Turn on transmitter/receiver at 8-bits/char */
-        kgdb_chaninit(zs_soft[tty_num].zs_channel, 1, 38400);
-	printk("KGDB: on channel %d initialized\n", tty_num);
-	set_debug_traps(); /* init stub */
-}
-#endif /* ifdef CONFIG_KGDB */
-
-#ifdef CONFIG_PMAC_PBOOK
-/*
- * notify clients before sleep and reset bus afterwards
- */
-int
-serial_notify_sleep(struct pmu_sleep_notifier *self, int when)
-{
-	int i;
-
-	switch (when) {
-	case PBOOK_SLEEP_REQUEST:
-	case PBOOK_SLEEP_REJECT:
-		break;
-
-	case PBOOK_SLEEP_NOW:
-		for (i=0; i<zs_channels_found; i++) {
-			struct mac_serial *info = &zs_soft[i];
-			if (info->flags & ZILOG_INITIALIZED) {
-				shutdown(info);
-				info->flags |= ZILOG_SLEEPING;
-			}
-		}
-		break;
-	case PBOOK_WAKE:
-		for (i=0; i<zs_channels_found; i++) {
-			struct mac_serial *info = &zs_soft[i];
-			if (info->flags & ZILOG_SLEEPING) {
-				info->flags &= ~ZILOG_SLEEPING;
-				startup(info);
-			}
-		}
-		break;
-	}
-	return PBOOK_SLEEP_OK;
-}
-#endif /* CONFIG_PMAC_PBOOK */
diff --git a/drivers/macintosh/macserial.h b/drivers/macintosh/macserial.h
deleted file mode 100644
--- a/drivers/macintosh/macserial.h
+++ /dev/null
@@ -1,461 +0,0 @@
-/*
- * macserial.h: Definitions for the Macintosh Z8530 serial driver.
- *
- * Adapted from drivers/sbus/char/sunserial.h by Paul Mackerras.
- *
- * Copyright (C) 1996 Paul Mackerras (Paul.Mackerras@cs.anu.edu.au)
- * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
- */
-#ifndef _MACSERIAL_H
-#define _MACSERIAL_H
-
-#include <linux/spinlock.h>
-
-#define NUM_ZSREGS    16
-
-struct serial_struct {
-	int	type;
-	int	line;
-	int	port;
-	int	irq;
-	int	flags;
-	int	xmit_fifo_size;
-	int	custom_divisor;
-	int	baud_base;
-	unsigned short	close_delay;
-	char	reserved_char[2];
-	int	hub6;
-	unsigned short	closing_wait; /* time to wait before closing */
-	unsigned short	closing_wait2; /* no longer used... */
-	int	reserved[4];
-};
-
-/*
- * For the close wait times, 0 means wait forever for serial port to
- * flush its output.  65535 means don't wait at all.
- */
-#define ZILOG_CLOSING_WAIT_INF	0
-#define ZILOG_CLOSING_WAIT_NONE	65535
-
-/*
- * Definitions for ZILOG_struct (and serial_struct) flags field
- */
-#define ZILOG_HUP_NOTIFY	0x0001	/* Notify getty on hangups and closes 
-				   	 * on the callout port */
-#define ZILOG_FOURPORT 		0x0002	/* Set OU1, OUT2 per AST Fourport settings */
-#define ZILOG_SAK		0x0004	/* Secure Attention Key (Orange book) */
-#define ZILOG_SPLIT_TERMIOS	0x0008	/* Separate termios for dialin/callout */
-
-#define ZILOG_SPD_MASK		0x0030
-#define ZILOG_SPD_HI		0x0010	/* Use 56000 instead of 38400 bps */
-
-#define ZILOG_SPD_VHI		0x0020  /* Use 115200 instead of 38400 bps */
-#define ZILOG_SPD_CUST		0x0030  /* Use user-specified divisor */
-
-#define ZILOG_SKIP_TEST		0x0040	/* Skip UART test during autoconfiguration */
-#define ZILOG_AUTO_IRQ 		0x0080	/* Do automatic IRQ during autoconfiguration */
-#define ZILOG_SESSION_LOCKOUT	0x0100	/* Lock out cua opens based on session */
-#define ZILOG_PGRP_LOCKOUT	0x0200	/* Lock out cua opens based on pgrp */
-#define ZILOG_CALLOUT_NOHUP	0x0400	/* Don't do hangups for cua device */
-
-#define ZILOG_FLAGS		0x0FFF	/* Possible legal ZILOG flags */
-#define ZILOG_USR_MASK		0x0430	/* Legal flags that non-privileged
-					 * users can set or reset */
-
-/* Internal flags used only by kernel/chr_drv/serial.c */
-#define ZILOG_INITIALIZED	0x80000000 /* Serial port was initialized */
-#define ZILOG_CALLOUT_ACTIVE	0x40000000 /* Call out device is active */
-#define ZILOG_NORMAL_ACTIVE	0x20000000 /* Normal device is active */
-#define ZILOG_BOOT_AUTOCONF	0x10000000 /* Autoconfigure port on bootup */
-#define ZILOG_CLOSING		0x08000000 /* Serial port is closing */
-#define ZILOG_CTS_FLOW		0x04000000 /* Do CTS flow control */
-#define ZILOG_CHECK_CD		0x02000000 /* i.e., CLOCAL */
-#define ZILOG_SLEEPING		0x01000000 /* have shut it down for sleep */
-
-/* Software state per channel */
-
-#ifdef __KERNEL__
-/*
- * This is our internal structure for each serial port's state.
- * 
- * Many fields are paralleled by the structure used by the serial_struct
- * structure.
- *
- * For definitions of the flags field, see tty.h
- */
-
-struct mac_serial;
-
-struct mac_zschannel {
-	volatile unsigned char*	control;
-	volatile unsigned char*	data;
-	spinlock_t		lock;
-	/* Used for debugging */
-	struct mac_serial*	parent;
-};
-
-struct mac_dma {
-	volatile struct dbdma_regs	dma;
-	volatile unsigned short		res_count;
-	volatile unsigned short		command;
-	volatile unsigned int		buf_addr;
-};
-
-struct mac_serial {
-	struct mac_serial *zs_next;	/* For IRQ servicing chain */
-	struct mac_zschannel *zs_channel; /* Channel registers */
-	struct mac_zschannel *zs_chan_a;	/* A side registers */
-	unsigned char read_reg_zero;
-	struct device_node* dev_node;
-	spinlock_t lock;
-
-	char soft_carrier;  /* Use soft carrier on this channel */
-	char break_abort;   /* Is serial console in, so process brk/abrt */
-	char kgdb_channel;  /* Kgdb is running on this channel */
-	char is_cons;       /* Is this our console. */
-	char is_internal_modem; /* is connected to an internal modem */
-	char is_irda;		/* is connected to an IrDA codec */
-	int port_type;		/* Port type for pmac_feature */
-	unsigned char tx_active; /* character is being xmitted */
-	unsigned char tx_stopped; /* output is suspended */
-	unsigned char power_wait; /* waiting for power-up delay to expire */
-
-	/* We need to know the current clock divisor
-	 * to read the bps rate the chip has currently
-	 * loaded.
-	 */
-	unsigned char clk_divisor;  /* May be 1, 16, 32, or 64 */
-	int zs_baud;
-
-	/* Current write register values */
-	unsigned char curregs[NUM_ZSREGS];
-
-	/* Values we need to set next opportunity */
-	unsigned char pendregs[NUM_ZSREGS];
-
-	char change_needed;
-
-	int			magic;
-	int			baud_base;
-	int			port;
-	int			irq;
-	int			flags; 		/* defined in tty.h */
-	int			type; 		/* UART type */
-	struct tty_struct 	*tty;
-	int			read_status_mask;
-	int			ignore_status_mask;
-	int			timeout;
-	int			xmit_fifo_size;
-	int			custom_divisor;
-	int			x_char;	/* xon/xoff character */
-	int			close_delay;
-	unsigned short		closing_wait;
-	unsigned short		closing_wait2;
-	unsigned long		event;
-	unsigned long		last_active;
-	int			line;
-	int			count;	    /* # of fd on device */
-	int			blocked_open; /* # of blocked opens */
-	unsigned char 		*xmit_buf;
-	int			xmit_head;
-	int			xmit_tail;
-	int			xmit_cnt;
-	struct work_struct	tqueue;
-	wait_queue_head_t	open_wait;
-	wait_queue_head_t	close_wait;
-
-	volatile struct dbdma_regs *tx_dma;
-	int			tx_dma_irq;
-	volatile struct dbdma_cmd *tx_cmds;
-	volatile struct mac_dma *rx;
-	int 			rx_dma_irq;
-	volatile struct dbdma_cmd **rx_cmds;
-	unsigned char		**rx_char_buf;
-	unsigned char		**rx_flag_buf;
-#define	RX_BUF_SIZE	256
-	int			rx_nbuf;
-	int			rx_done_bytes;
-	int			rx_ubuf;
-	int			rx_fbuf;
-#define	RX_NO_FBUF	(-1)
-	int			rx_cbuf;
-	spinlock_t		rx_dma_lock;
-	int			has_dma;
-	int			dma_initted;
-	void			*dma_priv;
-	struct timer_list	poll_dma_timer;
-#define RX_DMA_TIMER	(jiffies + 10*HZ/1000)
-
-	struct timer_list	powerup_timer;
-};
-
-
-#define SERIAL_MAGIC 0x5301
-
-/*
- * The size of the serial xmit buffer is 1 page, or 4096 bytes
- */
-#define SERIAL_XMIT_SIZE 4096
-
-/*
- * Events are used to schedule things to happen at timer-interrupt
- * time, instead of at rs interrupt time.
- */
-#define RS_EVENT_WRITE_WAKEUP	0
-
-#endif /* __KERNEL__ */
-
-/* Conversion routines to/from brg time constants from/to bits
- * per second.
- */
-#define BRG_TO_BPS(brg, freq) ((freq) / 2 / ((brg) + 2))
-#define BPS_TO_BRG(bps, freq) ((((freq) + (bps)) / (2 * (bps))) - 2)
-
-/* The Zilog register set */
-
-#define	FLAG	0x7e
-
-/* Write Register 0 */
-#define	R0	0		/* Register selects */
-#define	R1	1
-#define	R2	2
-#define	R3	3
-#define	R4	4
-#define	R5	5
-#define	R6	6
-#define	R7	7
-#define	R8	8
-#define	R9	9
-#define	R10	10
-#define	R11	11
-#define	R12	12
-#define	R13	13
-#define	R14	14
-#define	R15	15
-
-#define	NULLCODE	0	/* Null Code */
-#define	POINT_HIGH	0x8	/* Select upper half of registers */
-#define	RES_EXT_INT	0x10	/* Reset Ext. Status Interrupts */
-#define	SEND_ABORT	0x18	/* HDLC Abort */
-#define	RES_RxINT_FC	0x20	/* Reset RxINT on First Character */
-#define	RES_Tx_P	0x28	/* Reset TxINT Pending */
-#define	ERR_RES		0x30	/* Error Reset */
-#define	RES_H_IUS	0x38	/* Reset highest IUS */
-
-#define	RES_Rx_CRC	0x40	/* Reset Rx CRC Checker */
-#define	RES_Tx_CRC	0x80	/* Reset Tx CRC Checker */
-#define	RES_EOM_L	0xC0	/* Reset EOM latch */
-
-/* Write Register 1 */
-
-#define	EXT_INT_ENAB	0x1	/* Ext Int Enable */
-#define	TxINT_ENAB	0x2	/* Tx Int Enable */
-#define	PAR_SPEC	0x4	/* Parity is special condition */
-
-#define	RxINT_DISAB	0	/* Rx Int Disable */
-#define	RxINT_FCERR	0x8	/* Rx Int on First Character Only or Error */
-#define	INT_ALL_Rx	0x10	/* Int on all Rx Characters or error */
-#define	INT_ERR_Rx	0x18	/* Int on error only */
-
-#define	WT_RDY_RT	0x20	/* W/Req reflects recv if 1, xmit if 0 */
-#define	WT_FN_RDYFN	0x40	/* W/Req pin is DMA request if 1, wait if 0 */
-#define	WT_RDY_ENAB	0x80	/* Enable W/Req pin */
-
-/* Write Register #2 (Interrupt Vector) */
-
-/* Write Register 3 */
-
-#define	RxENABLE	0x1	/* Rx Enable */
-#define	SYNC_L_INH	0x2	/* Sync Character Load Inhibit */
-#define	ADD_SM		0x4	/* Address Search Mode (SDLC) */
-#define	RxCRC_ENAB	0x8	/* Rx CRC Enable */
-#define	ENT_HM		0x10	/* Enter Hunt Mode */
-#define	AUTO_ENAB	0x20	/* Auto Enables */
-#define	Rx5		0x0	/* Rx 5 Bits/Character */
-#define	Rx7		0x40	/* Rx 7 Bits/Character */
-#define	Rx6		0x80	/* Rx 6 Bits/Character */
-#define	Rx8		0xc0	/* Rx 8 Bits/Character */
-#define RxNBITS_MASK	0xc0
-
-/* Write Register 4 */
-
-#define	PAR_ENA		0x1	/* Parity Enable */
-#define	PAR_EVEN	0x2	/* Parity Even/Odd* */
-
-#define	SYNC_ENAB	0	/* Sync Modes Enable */
-#define	SB1		0x4	/* 1 stop bit/char */
-#define	SB15		0x8	/* 1.5 stop bits/char */
-#define	SB2		0xc	/* 2 stop bits/char */
-#define SB_MASK		0xc
-
-#define	MONSYNC		0	/* 8 Bit Sync character */
-#define	BISYNC		0x10	/* 16 bit sync character */
-#define	SDLC		0x20	/* SDLC Mode (01111110 Sync Flag) */
-#define	EXTSYNC		0x30	/* External Sync Mode */
-
-#define	X1CLK		0x0	/* x1 clock mode */
-#define	X16CLK		0x40	/* x16 clock mode */
-#define	X32CLK		0x80	/* x32 clock mode */
-#define	X64CLK		0xC0	/* x64 clock mode */
-#define XCLK_MASK	0xC0
-
-/* Write Register 5 */
-
-#define	TxCRC_ENAB	0x1	/* Tx CRC Enable */
-#define	RTS		0x2	/* RTS */
-#define	SDLC_CRC	0x4	/* SDLC/CRC-16 */
-#define	TxENAB		0x8	/* Tx Enable */
-#define	SND_BRK		0x10	/* Send Break */
-#define	Tx5		0x0	/* Tx 5 bits (or less)/character */
-#define	Tx7		0x20	/* Tx 7 bits/character */
-#define	Tx6		0x40	/* Tx 6 bits/character */
-#define	Tx8		0x60	/* Tx 8 bits/character */
-#define TxNBITS_MASK	0x60
-#define	DTR		0x80	/* DTR */
-
-/* Write Register 6 (Sync bits 0-7/SDLC Address Field) */
-
-/* Write Register 7 (Sync bits 8-15/SDLC 01111110) */
-
-/* Write Register 7' (Some enhanced feature control) */
-#define	ENEXREAD	0x40	/* Enable read of some write registers */
-
-/* Write Register 8 (transmit buffer) */
-
-/* Write Register 9 (Master interrupt control) */
-#define	VIS	1	/* Vector Includes Status */
-#define	NV	2	/* No Vector */
-#define	DLC	4	/* Disable Lower Chain */
-#define	MIE	8	/* Master Interrupt Enable */
-#define	STATHI	0x10	/* Status high */
-#define	NORESET	0	/* No reset on write to R9 */
-#define	CHRB	0x40	/* Reset channel B */
-#define	CHRA	0x80	/* Reset channel A */
-#define	FHWRES	0xc0	/* Force hardware reset */
-
-/* Write Register 10 (misc control bits) */
-#define	BIT6	1	/* 6 bit/8bit sync */
-#define	LOOPMODE 2	/* SDLC Loop mode */
-#define	ABUNDER	4	/* Abort/flag on SDLC xmit underrun */
-#define	MARKIDLE 8	/* Mark/flag on idle */
-#define	GAOP	0x10	/* Go active on poll */
-#define	NRZ	0	/* NRZ mode */
-#define	NRZI	0x20	/* NRZI mode */
-#define	FM1	0x40	/* FM1 (transition = 1) */
-#define	FM0	0x60	/* FM0 (transition = 0) */
-#define	CRCPS	0x80	/* CRC Preset I/O */
-
-/* Write Register 11 (Clock Mode control) */
-#define	TRxCXT	0	/* TRxC = Xtal output */
-#define	TRxCTC	1	/* TRxC = Transmit clock */
-#define	TRxCBR	2	/* TRxC = BR Generator Output */
-#define	TRxCDP	3	/* TRxC = DPLL output */
-#define	TRxCOI	4	/* TRxC O/I */
-#define	TCRTxCP	0	/* Transmit clock = RTxC pin */
-#define	TCTRxCP	8	/* Transmit clock = TRxC pin */
-#define	TCBR	0x10	/* Transmit clock = BR Generator output */
-#define	TCDPLL	0x18	/* Transmit clock = DPLL output */
-#define	RCRTxCP	0	/* Receive clock = RTxC pin */
-#define	RCTRxCP	0x20	/* Receive clock = TRxC pin */
-#define	RCBR	0x40	/* Receive clock = BR Generator output */
-#define	RCDPLL	0x60	/* Receive clock = DPLL output */
-#define	RTxCX	0x80	/* RTxC Xtal/No Xtal */
-
-/* Write Register 12 (lower byte of baud rate generator time constant) */
-
-/* Write Register 13 (upper byte of baud rate generator time constant) */
-
-/* Write Register 14 (Misc control bits) */
-#define	BRENABL	1	/* Baud rate generator enable */
-#define	BRSRC	2	/* Baud rate generator source */
-#define	DTRREQ	4	/* DTR/Request function */
-#define	AUTOECHO 8	/* Auto Echo */
-#define	LOOPBAK	0x10	/* Local loopback */
-#define	SEARCH	0x20	/* Enter search mode */
-#define	RMC	0x40	/* Reset missing clock */
-#define	DISDPLL	0x60	/* Disable DPLL */
-#define	SSBR	0x80	/* Set DPLL source = BR generator */
-#define	SSRTxC	0xa0	/* Set DPLL source = RTxC */
-#define	SFMM	0xc0	/* Set FM mode */
-#define	SNRZI	0xe0	/* Set NRZI mode */
-
-/* Write Register 15 (external/status interrupt control) */
-#define	EN85C30	1	/* Enable some 85c30-enhanced registers */
-#define	ZCIE	2	/* Zero count IE */
-#define	ENSTFIFO 4	/* Enable status FIFO (SDLC) */
-#define	DCDIE	8	/* DCD IE */
-#define	SYNCIE	0x10	/* Sync/hunt IE */
-#define	CTSIE	0x20	/* CTS IE */
-#define	TxUIE	0x40	/* Tx Underrun/EOM IE */
-#define	BRKIE	0x80	/* Break/Abort IE */
-
-
-/* Read Register 0 */
-#define	Rx_CH_AV	0x1	/* Rx Character Available */
-#define	ZCOUNT		0x2	/* Zero count */
-#define	Tx_BUF_EMP	0x4	/* Tx Buffer empty */
-#define	DCD		0x8	/* DCD */
-#define	SYNC_HUNT	0x10	/* Sync/hunt */
-#define	CTS		0x20	/* CTS */
-#define	TxEOM		0x40	/* Tx underrun */
-#define	BRK_ABRT	0x80	/* Break/Abort */
-
-/* Read Register 1 */
-#define	ALL_SNT		0x1	/* All sent */
-/* Residue Data for 8 Rx bits/char programmed */
-#define	RES3		0x8	/* 0/3 */
-#define	RES4		0x4	/* 0/4 */
-#define	RES5		0xc	/* 0/5 */
-#define	RES6		0x2	/* 0/6 */
-#define	RES7		0xa	/* 0/7 */
-#define	RES8		0x6	/* 0/8 */
-#define	RES18		0xe	/* 1/8 */
-#define	RES28		0x0	/* 2/8 */
-/* Special Rx Condition Interrupts */
-#define	PAR_ERR		0x10	/* Parity error */
-#define	Rx_OVR		0x20	/* Rx Overrun Error */
-#define	FRM_ERR		0x40	/* CRC/Framing Error */
-#define	END_FR		0x80	/* End of Frame (SDLC) */
-
-/* Read Register 2 (channel b only) - Interrupt vector */
-#define	CHB_Tx_EMPTY	0x00
-#define	CHB_EXT_STAT	0x02
-#define	CHB_Rx_AVAIL	0x04
-#define	CHB_SPECIAL	0x06
-#define	CHA_Tx_EMPTY	0x08
-#define	CHA_EXT_STAT	0x0a
-#define	CHA_Rx_AVAIL	0x0c
-#define	CHA_SPECIAL	0x0e
-#define	STATUS_MASK	0x06
-
-/* Read Register 3 (interrupt pending register) ch a only */
-#define	CHBEXT	0x1		/* Channel B Ext/Stat IP */
-#define	CHBTxIP	0x2		/* Channel B Tx IP */
-#define	CHBRxIP	0x4		/* Channel B Rx IP */
-#define	CHAEXT	0x8		/* Channel A Ext/Stat IP */
-#define	CHATxIP	0x10		/* Channel A Tx IP */
-#define	CHARxIP	0x20		/* Channel A Rx IP */
-
-/* Read Register 8 (receive data register) */
-
-/* Read Register 10  (misc status bits) */
-#define	ONLOOP	2		/* On loop */
-#define	LOOPSEND 0x10		/* Loop sending */
-#define	CLK2MIS	0x40		/* Two clocks missing */
-#define	CLK1MIS	0x80		/* One clock missing */
-
-/* Read Register 12 (lower byte of baud rate generator constant) */
-
-/* Read Register 13 (upper byte of baud rate generator constant) */
-
-/* Read Register 15 (value of WR 15) */
-
-/* Misc macros */
-#define ZS_CLEARERR(channel)    (write_zsreg(channel, 0, ERR_RES))
-#define ZS_CLEARFIFO(channel)   do { volatile unsigned char garbage; \
-				     garbage = read_zsdata(channel); \
-				     garbage = read_zsdata(channel); \
-				     garbage = read_zsdata(channel); \
-				} while(0)
-
-#endif /* !(_MACSERIAL_H) */
diff --git a/drivers/macintosh/mediabay.c b/drivers/macintosh/mediabay.c
--- a/drivers/macintosh/mediabay.c
+++ b/drivers/macintosh/mediabay.c
@@ -642,7 +642,7 @@ static int __pmac media_bay_task(void *x
 	}
 }
 
-static int __devinit media_bay_attach(struct macio_dev *mdev, const struct of_match *match)
+static int __devinit media_bay_attach(struct macio_dev *mdev, const struct of_device_id *match)
 {
 	struct media_bay_info* bay;
 	u32 __iomem *regbase;
@@ -797,23 +797,20 @@ static struct mb_ops keylargo_mb_ops __p
  * Therefore we do it all by polling the media bay once each tick.
  */
 
-static struct of_match media_bay_match[] =
+static struct of_device_id media_bay_match[] =
 {
 	{
 	.name		= "media-bay",
-	.type		= OF_ANY_MATCH,
 	.compatible	= "keylargo-media-bay",
 	.data		= &keylargo_mb_ops,
 	},
 	{
 	.name		= "media-bay",
-	.type		= OF_ANY_MATCH,
 	.compatible	= "heathrow-media-bay",
 	.data		= &heathrow_mb_ops,
 	},
 	{
 	.name		= "media-bay",
-	.type		= OF_ANY_MATCH,
 	.compatible	= "ohare-media-bay",
 	.data		= &ohare_mb_ops,
 	},
diff --git a/drivers/macintosh/therm_adt746x.c b/drivers/macintosh/therm_adt746x.c
--- a/drivers/macintosh/therm_adt746x.c
+++ b/drivers/macintosh/therm_adt746x.c
@@ -328,9 +328,7 @@ static int monitor_task(void *arg)
 	struct thermostat* th = arg;
 
 	while(!kthread_should_stop()) {
-		if (current->flags & PF_FREEZE)
-			refrigerator(PF_FREEZE);
-
+		try_to_freeze();
 		msleep_interruptible(2000);
 
 #ifndef DEBUG
@@ -455,21 +453,22 @@ static int attach_one_thermostat(struct 
  * pass around to the attribute functions, so we don't really have
  * choice but implement a bunch of them...
  *
+ * FIXME, it does now...
  */
 #define BUILD_SHOW_FUNC_INT(name, data)				\
-static ssize_t show_##name(struct device *dev, char *buf)	\
+static ssize_t show_##name(struct device *dev, struct device_attribute *attr, char *buf)	\
 {								\
 	return sprintf(buf, "%d\n", data);			\
 }
 
 #define BUILD_SHOW_FUNC_STR(name, data)				\
-static ssize_t show_##name(struct device *dev, char *buf)	\
+static ssize_t show_##name(struct device *dev, struct device_attribute *attr, char *buf)       \
 {								\
 	return sprintf(buf, "%s\n", data);			\
 }
 
 #define BUILD_SHOW_FUNC_FAN(name, data)				\
-static ssize_t show_##name(struct device *dev, char *buf)       \
+static ssize_t show_##name(struct device *dev, struct device_attribute *attr, char *buf)       \
 {								\
 	return sprintf(buf, "%d (%d rpm)\n", 			\
 		thermostat->last_speed[data],			\
@@ -478,7 +477,7 @@ static ssize_t show_##name(struct device
 }
 
 #define BUILD_STORE_FUNC_DEG(name, data)			\
-static ssize_t store_##name(struct device *dev, const char *buf, size_t n) \
+static ssize_t store_##name(struct device *dev, struct device_attribute *attr, const char *buf, size_t n) \
 {								\
 	int val;						\
 	int i;							\
@@ -491,7 +490,7 @@ static ssize_t store_##name(struct devic
 }
 
 #define BUILD_STORE_FUNC_INT(name, data)			\
-static ssize_t store_##name(struct device *dev, const char *buf, size_t n) \
+static ssize_t store_##name(struct device *dev, struct device_attribute *attr, const char *buf, size_t n) \
 {								\
 	u32 val;						\
 	val = simple_strtoul(buf, NULL, 10);			\
diff --git a/drivers/macintosh/therm_pm72.c b/drivers/macintosh/therm_pm72.c
--- a/drivers/macintosh/therm_pm72.c
+++ b/drivers/macintosh/therm_pm72.c
@@ -120,6 +120,7 @@
 #include <asm/system.h>
 #include <asm/sections.h>
 #include <asm/of_device.h>
+#include <asm/macio.h>
 
 #include "therm_pm72.h"
 
@@ -685,7 +686,7 @@ static void fetch_cpu_pumps_minmax(void)
  * the input twice... I accept patches :)
  */
 #define BUILD_SHOW_FUNC_FIX(name, data)				\
-static ssize_t show_##name(struct device *dev, char *buf)	\
+static ssize_t show_##name(struct device *dev, struct device_attribute *attr, char *buf)	\
 {								\
 	ssize_t r;						\
 	down(&driver_lock);					\
@@ -694,7 +695,7 @@ static ssize_t show_##name(struct device
 	return r;						\
 }
 #define BUILD_SHOW_FUNC_INT(name, data)				\
-static ssize_t show_##name(struct device *dev, char *buf)	\
+static ssize_t show_##name(struct device *dev, struct device_attribute *attr, char *buf)	\
 {								\
 	return sprintf(buf, "%d", data);			\
 }
@@ -1986,7 +1987,7 @@ static void fcu_lookup_fans(struct devic
 	}
 }
 
-static int fcu_of_probe(struct of_device* dev, const struct of_match *match)
+static int fcu_of_probe(struct of_device* dev, const struct of_device_id *match)
 {
 	int rc;
 
@@ -2009,12 +2010,10 @@ static int fcu_of_remove(struct of_devic
 	return 0;
 }
 
-static struct of_match fcu_of_match[] = 
+static struct of_device_id fcu_match[] = 
 {
 	{
-	.name 		= OF_ANY_MATCH,
 	.type		= "fcu",
-	.compatible	= OF_ANY_MATCH
 	},
 	{},
 };
@@ -2022,7 +2021,7 @@ static struct of_match fcu_of_match[] = 
 static struct of_platform_driver fcu_of_platform_driver = 
 {
 	.name 		= "temperature",
-	.match_table	= fcu_of_match,
+	.match_table	= fcu_match,
 	.probe		= fcu_of_probe,
 	.remove		= fcu_of_remove
 };
diff --git a/drivers/macintosh/therm_windtunnel.c b/drivers/macintosh/therm_windtunnel.c
--- a/drivers/macintosh/therm_windtunnel.c
+++ b/drivers/macintosh/therm_windtunnel.c
@@ -43,6 +43,7 @@
 #include <asm/system.h>
 #include <asm/sections.h>
 #include <asm/of_device.h>
+#include <asm/macio.h>
 
 #define LOG_TEMP		0			/* continously log temperature */
 
@@ -51,8 +52,10 @@
 static int 			do_probe( struct i2c_adapter *adapter, int addr, int kind);
 
 /* scan 0x48-0x4f (DS1775) and 0x2c-2x2f (ADM1030) */
-static unsigned short		normal_i2c[] = { 0x49, 0x2c, I2C_CLIENT_END };
-static unsigned short		normal_i2c_range[] = { 0x48, 0x4f, 0x2c, 0x2f, I2C_CLIENT_END };
+static unsigned short		normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b,
+						 0x4c, 0x4d, 0x4e, 0x4f,
+						 0x2c, 0x2d, 0x2e, 0x2f,
+						 I2C_CLIENT_END };
 
 I2C_CLIENT_INSMOD;
 
@@ -107,13 +110,13 @@ print_temp( const char *s, int temp )
 }
 
 static ssize_t
-show_cpu_temperature( struct device *dev, char *buf )
+show_cpu_temperature( struct device *dev, struct device_attribute *attr, char *buf )
 {
 	return sprintf(buf, "%d.%d\n", x.temp>>8, (x.temp & 255)*10/256 );
 }
 
 static ssize_t
-show_case_temperature( struct device *dev, char *buf )
+show_case_temperature( struct device *dev, struct device_attribute *attr, char *buf )
 {
 	return sprintf(buf, "%d.%d\n", x.casetemp>>8, (x.casetemp & 255)*10/256 );
 }
@@ -448,7 +451,7 @@ do_probe( struct i2c_adapter *adapter, i
 /************************************************************************/
 
 static int
-therm_of_probe( struct of_device *dev, const struct of_match *match )
+therm_of_probe( struct of_device *dev, const struct of_device_id *match )
 {
 	return i2c_add_driver( &g4fan_driver );
 }
@@ -459,9 +462,8 @@ therm_of_remove( struct of_device *dev )
 	return i2c_del_driver( &g4fan_driver );
 }
 
-static struct of_match therm_of_match[] = {{
+static struct of_device_id therm_of_match[] = {{
 	.name		= "fan",
-	.type		= OF_ANY_MATCH,
 	.compatible	= "adm1030"
     }, {}
 };
diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c
--- a/drivers/macintosh/via-pmu.c
+++ b/drivers/macintosh/via-pmu.c
@@ -63,6 +63,10 @@
 #include <asm/backlight.h>
 #endif
 
+#ifdef CONFIG_PPC32
+#include <asm/open_pic.h>
+#endif
+
 /* Some compile options */
 #undef SUSPEND_USES_PMU
 #define DEBUG_SLEEP
@@ -151,10 +155,10 @@ static spinlock_t pmu_lock;
 static u8 pmu_intr_mask;
 static int pmu_version;
 static int drop_interrupts;
-#ifdef CONFIG_PMAC_PBOOK
+#ifdef CONFIG_PM
 static int option_lid_wakeup = 1;
 static int sleep_in_progress;
-#endif /* CONFIG_PMAC_PBOOK */
+#endif /* CONFIG_PM */
 static unsigned long async_req_locks;
 static unsigned int pmu_irq_stats[11];
 
@@ -164,7 +168,6 @@ static struct proc_dir_entry *proc_pmu_i
 static struct proc_dir_entry *proc_pmu_options;
 static int option_server_mode;
 
-#ifdef CONFIG_PMAC_PBOOK
 int pmu_battery_count;
 int pmu_cur_battery;
 unsigned int pmu_power_flags;
@@ -172,7 +175,6 @@ struct pmu_battery_info pmu_batteries[PM
 static int query_batt_timer = BATTERY_POLLING_COUNT;
 static struct adb_request batt_req;
 static struct proc_dir_entry *proc_pmu_batt[PMU_MAX_BATTERIES];
-#endif /* CONFIG_PMAC_PBOOK */
 
 #if defined(CONFIG_INPUT_ADBHID) && defined(CONFIG_PMAC_BACKLIGHT)
 extern int disable_kernel_backlight;
@@ -206,11 +208,9 @@ static int proc_get_irqstats(char *page,
 static int pmu_set_backlight_level(int level, void* data);
 static int pmu_set_backlight_enable(int on, int level, void* data);
 #endif /* CONFIG_PMAC_BACKLIGHT */
-#ifdef CONFIG_PMAC_PBOOK
 static void pmu_pass_intr(unsigned char *data, int len);
 static int proc_get_batt(char *page, char **start, off_t off,
 			int count, int *eof, void *data);
-#endif /* CONFIG_PMAC_PBOOK */
 static int proc_read_options(char *page, char **start, off_t off,
 			int count, int *eof, void *data);
 static int proc_write_options(struct file *file, const char __user *buffer,
@@ -403,8 +403,12 @@ static int __init via_pmu_start(void)
 
 	bright_req_1.complete = 1;
 	bright_req_2.complete = 1;
-#ifdef CONFIG_PMAC_PBOOK
 	batt_req.complete = 1;
+
+#ifdef CONFIG_PPC32
+	if (pmu_kind == PMU_KEYLARGO_BASED)
+		openpic_set_irq_priority(vias->intrs[0].line,
+					 OPENPIC_PRIORITY_DEFAULT + 1);
 #endif
 
 	if (request_irq(vias->intrs[0].line, via_pmu_interrupt, 0, "VIA-PMU",
@@ -458,7 +462,7 @@ static int __init via_pmu_dev_init(void)
 	register_backlight_controller(&pmu_backlight_controller, NULL, "pmu");
 #endif /* CONFIG_PMAC_BACKLIGHT */
 
-#ifdef CONFIG_PMAC_PBOOK
+#ifdef CONFIG_PPC32
   	if (machine_is_compatible("AAPL,3400/2400") ||
   		machine_is_compatible("AAPL,3500")) {
 		int mb = pmac_call_feature(PMAC_FTR_GET_MB_INFO,
@@ -486,20 +490,19 @@ static int __init via_pmu_dev_init(void)
 				pmu_batteries[1].flags |= PMU_BATT_TYPE_SMART;
 		}
 	}
-#endif /* CONFIG_PMAC_PBOOK */
+#endif /* CONFIG_PPC32 */
+
 	/* Create /proc/pmu */
 	proc_pmu_root = proc_mkdir("pmu", NULL);
 	if (proc_pmu_root) {
-#ifdef CONFIG_PMAC_PBOOK
-		int i;
+		long i;
 
 		for (i=0; i<pmu_battery_count; i++) {
 			char title[16];
-			sprintf(title, "battery_%d", i);
+			sprintf(title, "battery_%ld", i);
 			proc_pmu_batt[i] = create_proc_read_entry(title, 0, proc_pmu_root,
 						proc_get_batt, (void *)i);
 		}
-#endif /* CONFIG_PMAC_PBOOK */
 
 		proc_pmu_info = create_proc_read_entry("info", 0, proc_pmu_root,
 					proc_get_info, NULL);
@@ -619,8 +622,6 @@ static void pmu_set_server_mode(int serv
 	pmu_wait_complete(&req);
 }
 
-#ifdef CONFIG_PMAC_PBOOK
-
 /* This new version of the code for 2400/3400/3500 powerbooks
  * is inspired from the implementation in gkrellm-pmu
  */
@@ -803,8 +804,6 @@ query_battery_state(void)
 			2, PMU_SMART_BATTERY_STATE, pmu_cur_battery+1);
 }
 
-#endif /* CONFIG_PMAC_PBOOK */
-
 static int __pmac
 proc_get_info(char *page, char **start, off_t off,
 		int count, int *eof, void *data)
@@ -813,11 +812,9 @@ proc_get_info(char *page, char **start, 
 
 	p += sprintf(p, "PMU driver version     : %d\n", PMU_DRIVER_VERSION);
 	p += sprintf(p, "PMU firmware version   : %02x\n", pmu_version);
-#ifdef CONFIG_PMAC_PBOOK
 	p += sprintf(p, "AC Power               : %d\n",
 		((pmu_power_flags & PMU_PWR_AC_PRESENT) != 0));
 	p += sprintf(p, "Battery count          : %d\n", pmu_battery_count);
-#endif /* CONFIG_PMAC_PBOOK */
 
 	return p - page;
 }
@@ -849,12 +846,11 @@ proc_get_irqstats(char *page, char **sta
 	return p - page;
 }
 
-#ifdef CONFIG_PMAC_PBOOK
 static int __pmac
 proc_get_batt(char *page, char **start, off_t off,
 		int count, int *eof, void *data)
 {
-	int batnum = (int)data;
+	long batnum = (long)data;
 	char *p = page;
 	
 	p += sprintf(p, "\n");
@@ -873,7 +869,6 @@ proc_get_batt(char *page, char **start, 
 
 	return p - page;
 }
-#endif /* CONFIG_PMAC_PBOOK */
 
 static int __pmac
 proc_read_options(char *page, char **start, off_t off,
@@ -881,11 +876,11 @@ proc_read_options(char *page, char **sta
 {
 	char *p = page;
 
-#ifdef CONFIG_PMAC_PBOOK
+#ifdef CONFIG_PM
 	if (pmu_kind == PMU_KEYLARGO_BASED &&
 	    pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,0,-1) >= 0)
 		p += sprintf(p, "lid_wakeup=%d\n", option_lid_wakeup);
-#endif /* CONFIG_PMAC_PBOOK */
+#endif
 	if (pmu_kind == PMU_KEYLARGO_BASED)
 		p += sprintf(p, "server_mode=%d\n", option_server_mode);
 
@@ -922,12 +917,12 @@ proc_write_options(struct file *file, co
 	*(val++) = 0;
 	while(*val == ' ')
 		val++;
-#ifdef CONFIG_PMAC_PBOOK
+#ifdef CONFIG_PM
 	if (pmu_kind == PMU_KEYLARGO_BASED &&
 	    pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,0,-1) >= 0)
 		if (!strcmp(label, "lid_wakeup"))
 			option_lid_wakeup = ((*val) == '1');
-#endif /* CONFIG_PMAC_PBOOK */
+#endif
 	if (pmu_kind == PMU_KEYLARGO_BASED && !strcmp(label, "server_mode")) {
 		int new_value;
 		new_value = ((*val) == '1');
@@ -1422,7 +1417,6 @@ next:
 	}
 	/* Tick interrupt */
 	else if ((1 << pirq) & PMU_INT_TICK) {
-#ifdef CONFIG_PMAC_PBOOK
 		/* Environement or tick interrupt, query batteries */
 		if (pmu_battery_count) {
 			if ((--query_batt_timer) == 0) {
@@ -1437,7 +1431,6 @@ next:
 		pmu_pass_intr(data, len);
 	} else {
 	       pmu_pass_intr(data, len);
-#endif /* CONFIG_PMAC_PBOOK */
 	}
 	goto next;
 }
@@ -2052,7 +2045,7 @@ pmu_i2c_simple_write(int bus, int addr, 
 	return -1;
 }
 
-#ifdef CONFIG_PMAC_PBOOK
+#ifdef CONFIG_PM
 
 static LIST_HEAD(sleep_notifiers);
 
@@ -2705,6 +2698,8 @@ powerbook_sleep_3400(void)
 	return 0;
 }
 
+#endif /* CONFIG_PM */
+
 /*
  * Support for /dev/pmu device
  */
@@ -2884,11 +2879,11 @@ static int __pmac
 pmu_ioctl(struct inode * inode, struct file *filp,
 		     u_int cmd, u_long arg)
 {
-	struct pmu_private *pp = filp->private_data;
 	__u32 __user *argp = (__u32 __user *)arg;
-	int error;
+	int error = -EINVAL;
 
 	switch (cmd) {
+#ifdef CONFIG_PM
 	case PMU_IOC_SLEEP:
 		if (!capable(CAP_SYS_ADMIN))
 			return -EACCES;
@@ -2910,12 +2905,13 @@ pmu_ioctl(struct inode * inode, struct f
 			error = -ENOSYS;
 		}
 		sleep_in_progress = 0;
-		return error;
+		break;
 	case PMU_IOC_CAN_SLEEP:
 		if (pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,0,-1) < 0)
 			return put_user(0, argp);
 		else
 			return put_user(1, argp);
+#endif /* CONFIG_PM */
 
 #ifdef CONFIG_PMAC_BACKLIGHT
 	/* Backlight should have its own device or go via
@@ -2936,11 +2932,13 @@ pmu_ioctl(struct inode * inode, struct f
 		error = get_user(value, argp);
 		if (!error)
 			error = set_backlight_level(value);
-		return error;
+		break;
 	}
 #ifdef CONFIG_INPUT_ADBHID
 	case PMU_IOC_GRAB_BACKLIGHT: {
+		struct pmu_private *pp = filp->private_data;
 		unsigned long flags;
+
 		if (pp->backlight_locker)
 			return 0;
 		pp->backlight_locker = 1;
@@ -2956,7 +2954,7 @@ pmu_ioctl(struct inode * inode, struct f
 	case PMU_IOC_HAS_ADB:
 		return put_user(pmu_has_adb, argp);
 	}
-	return -EINVAL;
+	return error;
 }
 
 static struct file_operations pmu_device_fops __pmacdata = {
@@ -2972,14 +2970,16 @@ static struct miscdevice pmu_device __pm
 	PMU_MINOR, "pmu", &pmu_device_fops
 };
 
-void pmu_device_init(void)
+static int pmu_device_init(void)
 {
 	if (!via)
-		return;
+		return 0;
 	if (misc_register(&pmu_device) < 0)
 		printk(KERN_ERR "via-pmu: cannot register misc device.\n");
+	return 0;
 }
-#endif /* CONFIG_PMAC_PBOOK */
+device_initcall(pmu_device_init);
+
 
 #ifdef DEBUG_SLEEP
 static inline void  __pmac
@@ -3147,12 +3147,12 @@ EXPORT_SYMBOL(pmu_i2c_combined_read);
 EXPORT_SYMBOL(pmu_i2c_stdsub_write);
 EXPORT_SYMBOL(pmu_i2c_simple_read);
 EXPORT_SYMBOL(pmu_i2c_simple_write);
-#ifdef CONFIG_PMAC_PBOOK
+#ifdef CONFIG_PM
 EXPORT_SYMBOL(pmu_register_sleep_notifier);
 EXPORT_SYMBOL(pmu_unregister_sleep_notifier);
 EXPORT_SYMBOL(pmu_enable_irled);
 EXPORT_SYMBOL(pmu_battery_count);
 EXPORT_SYMBOL(pmu_batteries);
 EXPORT_SYMBOL(pmu_power_flags);
-#endif /* CONFIG_PMAC_PBOOK */
+#endif /* CONFIG_PM */
 
diff --git a/drivers/mca/mca-bus.c b/drivers/mca/mca-bus.c
--- a/drivers/mca/mca-bus.c
+++ b/drivers/mca/mca-bus.c
@@ -69,7 +69,7 @@ struct bus_type mca_bus_type = {
 };
 EXPORT_SYMBOL (mca_bus_type);
 
-static ssize_t mca_show_pos_id(struct device *dev, char *buf)
+static ssize_t mca_show_pos_id(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	/* four digits, \n and trailing \0 */
 	struct mca_device *mca_dev = to_mca_device(dev);
@@ -81,7 +81,7 @@ static ssize_t mca_show_pos_id(struct de
 		len = sprintf(buf, "none\n");
 	return len;
 }
-static ssize_t mca_show_pos(struct device *dev, char *buf)
+static ssize_t mca_show_pos(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	/* enough for 8 two byte hex chars plus space and new line */
 	int j, len=0;
diff --git a/drivers/mca/mca-legacy.c b/drivers/mca/mca-legacy.c
--- a/drivers/mca/mca-legacy.c
+++ b/drivers/mca/mca-legacy.c
@@ -180,7 +180,6 @@ struct mca_device *mca_find_device_by_sl
 
 	return info.mca_dev;
 }
-EXPORT_SYMBOL(mca_find_device_by_slot);
 
 /**
  *	mca_read_stored_pos - read POS register from boot data
diff --git a/drivers/md/Makefile b/drivers/md/Makefile
--- a/drivers/md/Makefile
+++ b/drivers/md/Makefile
@@ -7,6 +7,7 @@ dm-mod-objs	:= dm.o dm-table.o dm-target
 dm-multipath-objs := dm-hw-handler.o dm-path-selector.o dm-mpath.o
 dm-snapshot-objs := dm-snap.o dm-exception-store.o
 dm-mirror-objs	:= dm-log.o dm-raid1.o
+md-mod-objs     := md.o bitmap.o
 raid6-objs	:= raid6main.o raid6algos.o raid6recov.o raid6tables.o \
 		   raid6int1.o raid6int2.o raid6int4.o \
 		   raid6int8.o raid6int16.o raid6int32.o \
@@ -28,7 +29,7 @@ obj-$(CONFIG_MD_RAID5)		+= raid5.o xor.o
 obj-$(CONFIG_MD_RAID6)		+= raid6.o xor.o
 obj-$(CONFIG_MD_MULTIPATH)	+= multipath.o
 obj-$(CONFIG_MD_FAULTY)		+= faulty.o
-obj-$(CONFIG_BLK_DEV_MD)	+= md.o
+obj-$(CONFIG_BLK_DEV_MD)	+= md-mod.o
 obj-$(CONFIG_BLK_DEV_DM)	+= dm-mod.o
 obj-$(CONFIG_DM_CRYPT)		+= dm-crypt.o
 obj-$(CONFIG_DM_MULTIPATH)	+= dm-multipath.o dm-round-robin.o
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c
new file mode 100644
--- /dev/null
+++ b/drivers/md/bitmap.c
@@ -0,0 +1,1606 @@
+/*
+ * bitmap.c two-level bitmap (C) Peter T. Breuer (ptb@ot.uc3m.es) 2003
+ *
+ * bitmap_create  - sets up the bitmap structure
+ * bitmap_destroy - destroys the bitmap structure
+ *
+ * additions, Copyright (C) 2003-2004, Paul Clements, SteelEye Technology, Inc.:
+ * - added disk storage for bitmap
+ * - changes to allow various bitmap chunk sizes
+ * - added bitmap daemon (to asynchronously clear bitmap bits from disk)
+ */
+
+/*
+ * Still to do:
+ *
+ * flush after percent set rather than just time based. (maybe both).
+ * wait if count gets too high, wake when it drops to half.
+ * allow bitmap to be mirrored with superblock (before or after...)
+ * allow hot-add to re-instate a current device.
+ * allow hot-add of bitmap after quiessing device
+ */
+
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/config.h>
+#include <linux/timer.h>
+#include <linux/sched.h>
+#include <linux/list.h>
+#include <linux/file.h>
+#include <linux/mount.h>
+#include <linux/buffer_head.h>
+#include <linux/raid/md.h>
+#include <linux/raid/bitmap.h>
+
+/* debug macros */
+
+#define DEBUG 0
+
+#if DEBUG
+/* these are for debugging purposes only! */
+
+/* define one and only one of these */
+#define INJECT_FAULTS_1 0 /* cause bitmap_alloc_page to fail always */
+#define INJECT_FAULTS_2 0 /* cause bitmap file to be kicked when first bit set*/
+#define INJECT_FAULTS_3 0 /* treat bitmap file as kicked at init time */
+#define INJECT_FAULTS_4 0 /* undef */
+#define INJECT_FAULTS_5 0 /* undef */
+#define INJECT_FAULTS_6 0
+
+/* if these are defined, the driver will fail! debug only */
+#define INJECT_FATAL_FAULT_1 0 /* fail kmalloc, causing bitmap_create to fail */
+#define INJECT_FATAL_FAULT_2 0 /* undef */
+#define INJECT_FATAL_FAULT_3 0 /* undef */
+#endif
+
+//#define DPRINTK PRINTK /* set this NULL to avoid verbose debug output */
+#define DPRINTK(x...) do { } while(0)
+
+#ifndef PRINTK
+#  if DEBUG > 0
+#    define PRINTK(x...) printk(KERN_DEBUG x)
+#  else
+#    define PRINTK(x...)
+#  endif
+#endif
+
+static inline char * bmname(struct bitmap *bitmap)
+{
+	return bitmap->mddev ? mdname(bitmap->mddev) : "mdX";
+}
+
+
+/*
+ * test if the bitmap is active
+ */
+int bitmap_active(struct bitmap *bitmap)
+{
+	unsigned long flags;
+	int res = 0;
+
+	if (!bitmap)
+		return res;
+	spin_lock_irqsave(&bitmap->lock, flags);
+	res = bitmap->flags & BITMAP_ACTIVE;
+	spin_unlock_irqrestore(&bitmap->lock, flags);
+	return res;
+}
+
+#define WRITE_POOL_SIZE 256
+/* mempool for queueing pending writes on the bitmap file */
+static void *write_pool_alloc(unsigned int gfp_flags, void *data)
+{
+	return kmalloc(sizeof(struct page_list), gfp_flags);
+}
+
+static void write_pool_free(void *ptr, void *data)
+{
+	kfree(ptr);
+}
+
+/*
+ * just a placeholder - calls kmalloc for bitmap pages
+ */
+static unsigned char *bitmap_alloc_page(struct bitmap *bitmap)
+{
+	unsigned char *page;
+
+#ifdef INJECT_FAULTS_1
+	page = NULL;
+#else
+	page = kmalloc(PAGE_SIZE, GFP_NOIO);
+#endif
+	if (!page)
+		printk("%s: bitmap_alloc_page FAILED\n", bmname(bitmap));
+	else
+		PRINTK("%s: bitmap_alloc_page: allocated page at %p\n",
+			bmname(bitmap), page);
+	return page;
+}
+
+/*
+ * for now just a placeholder -- just calls kfree for bitmap pages
+ */
+static void bitmap_free_page(struct bitmap *bitmap, unsigned char *page)
+{
+	PRINTK("%s: bitmap_free_page: free page %p\n", bmname(bitmap), page);
+	kfree(page);
+}
+
+/*
+ * check a page and, if necessary, allocate it (or hijack it if the alloc fails)
+ *
+ * 1) check to see if this page is allocated, if it's not then try to alloc
+ * 2) if the alloc fails, set the page's hijacked flag so we'll use the
+ *    page pointer directly as a counter
+ *
+ * if we find our page, we increment the page's refcount so that it stays
+ * allocated while we're using it
+ */
+static int bitmap_checkpage(struct bitmap *bitmap, unsigned long page, int create)
+{
+	unsigned char *mappage;
+
+	if (page >= bitmap->pages) {
+		printk(KERN_ALERT
+			"%s: invalid bitmap page request: %lu (> %lu)\n",
+			bmname(bitmap), page, bitmap->pages-1);
+		return -EINVAL;
+	}
+
+
+	if (bitmap->bp[page].hijacked) /* it's hijacked, don't try to alloc */
+		return 0;
+
+	if (bitmap->bp[page].map) /* page is already allocated, just return */
+		return 0;
+
+	if (!create)
+		return -ENOENT;
+
+	spin_unlock_irq(&bitmap->lock);
+
+	/* this page has not been allocated yet */
+
+	if ((mappage = bitmap_alloc_page(bitmap)) == NULL) {
+		PRINTK("%s: bitmap map page allocation failed, hijacking\n",
+			bmname(bitmap));
+		/* failed - set the hijacked flag so that we can use the
+		 * pointer as a counter */
+		spin_lock_irq(&bitmap->lock);
+		if (!bitmap->bp[page].map)
+			bitmap->bp[page].hijacked = 1;
+		goto out;
+	}
+
+	/* got a page */
+
+	spin_lock_irq(&bitmap->lock);
+
+	/* recheck the page */
+
+	if (bitmap->bp[page].map || bitmap->bp[page].hijacked) {
+		/* somebody beat us to getting the page */
+		bitmap_free_page(bitmap, mappage);
+		return 0;
+	}
+
+	/* no page was in place and we have one, so install it */
+
+	memset(mappage, 0, PAGE_SIZE);
+	bitmap->bp[page].map = mappage;
+	bitmap->missing_pages--;
+out:
+	return 0;
+}
+
+
+/* if page is completely empty, put it back on the free list, or dealloc it */
+/* if page was hijacked, unmark the flag so it might get alloced next time */
+/* Note: lock should be held when calling this */
+static inline void bitmap_checkfree(struct bitmap *bitmap, unsigned long page)
+{
+	char *ptr;
+
+	if (bitmap->bp[page].count) /* page is still busy */
+		return;
+
+	/* page is no longer in use, it can be released */
+
+	if (bitmap->bp[page].hijacked) { /* page was hijacked, undo this now */
+		bitmap->bp[page].hijacked = 0;
+		bitmap->bp[page].map = NULL;
+		return;
+	}
+
+	/* normal case, free the page */
+
+#if 0
+/* actually ... let's not.  We will probably need the page again exactly when
+ * memory is tight and we are flusing to disk
+ */
+	return;
+#else
+	ptr = bitmap->bp[page].map;
+	bitmap->bp[page].map = NULL;
+	bitmap->missing_pages++;
+	bitmap_free_page(bitmap, ptr);
+	return;
+#endif
+}
+
+
+/*
+ * bitmap file handling - read and write the bitmap file and its superblock
+ */
+
+/* copy the pathname of a file to a buffer */
+char *file_path(struct file *file, char *buf, int count)
+{
+	struct dentry *d;
+	struct vfsmount *v;
+
+	if (!buf)
+		return NULL;
+
+	d = file->f_dentry;
+	v = file->f_vfsmnt;
+
+	buf = d_path(d, v, buf, count);
+
+	return IS_ERR(buf) ? NULL : buf;
+}
+
+/*
+ * basic page I/O operations
+ */
+
+/* IO operations when bitmap is stored near all superblocks */
+static struct page *read_sb_page(mddev_t *mddev, long offset, unsigned long index)
+{
+	/* choose a good rdev and read the page from there */
+
+	mdk_rdev_t *rdev;
+	struct list_head *tmp;
+	struct page *page = alloc_page(GFP_KERNEL);
+	sector_t target;
+
+	if (!page)
+		return ERR_PTR(-ENOMEM);
+	do {
+		ITERATE_RDEV(mddev, rdev, tmp)
+			if (rdev->in_sync && !rdev->faulty)
+				goto found;
+		return ERR_PTR(-EIO);
+
+	found:
+		target = (rdev->sb_offset << 1) + offset + index * (PAGE_SIZE/512);
+
+	} while (!sync_page_io(rdev->bdev, target, PAGE_SIZE, page, READ));
+
+	page->index = index;
+	return page;
+}
+
+static int write_sb_page(mddev_t *mddev, long offset, struct page *page, int wait)
+{
+	mdk_rdev_t *rdev;
+	struct list_head *tmp;
+
+	ITERATE_RDEV(mddev, rdev, tmp)
+		if (rdev->in_sync && !rdev->faulty)
+			md_super_write(mddev, rdev,
+				       (rdev->sb_offset<<1) + offset
+				       + page->index * (PAGE_SIZE/512),
+				       PAGE_SIZE,
+				       page);
+
+	if (wait)
+		wait_event(mddev->sb_wait, atomic_read(&mddev->pending_writes)==0);
+	return 0;
+}
+
+/*
+ * write out a page to a file
+ */
+static int write_page(struct bitmap *bitmap, struct page *page, int wait)
+{
+	int ret = -ENOMEM;
+
+	if (bitmap->file == NULL)
+		return write_sb_page(bitmap->mddev, bitmap->offset, page, wait);
+
+	if (wait)
+		lock_page(page);
+	else {
+		if (TestSetPageLocked(page))
+			return -EAGAIN; /* already locked */
+		if (PageWriteback(page)) {
+			unlock_page(page);
+			return -EAGAIN;
+		}
+	}
+
+	ret = page->mapping->a_ops->prepare_write(NULL, page, 0, PAGE_SIZE);
+	if (!ret)
+		ret = page->mapping->a_ops->commit_write(NULL, page, 0,
+			PAGE_SIZE);
+	if (ret) {
+		unlock_page(page);
+		return ret;
+	}
+
+	set_page_dirty(page); /* force it to be written out */
+
+	if (!wait) {
+		/* add to list to be waited for by daemon */
+		struct page_list *item = mempool_alloc(bitmap->write_pool, GFP_NOIO);
+		item->page = page;
+		page_cache_get(page);
+		spin_lock(&bitmap->write_lock);
+		list_add(&item->list, &bitmap->complete_pages);
+		spin_unlock(&bitmap->write_lock);
+		md_wakeup_thread(bitmap->writeback_daemon);
+	}
+	return write_one_page(page, wait);
+}
+
+/* read a page from a file, pinning it into cache, and return bytes_read */
+static struct page *read_page(struct file *file, unsigned long index,
+					unsigned long *bytes_read)
+{
+	struct inode *inode = file->f_mapping->host;
+	struct page *page = NULL;
+	loff_t isize = i_size_read(inode);
+	unsigned long end_index = isize >> PAGE_CACHE_SHIFT;
+
+	PRINTK("read bitmap file (%dB @ %Lu)\n", (int)PAGE_CACHE_SIZE,
+			(unsigned long long)index << PAGE_CACHE_SHIFT);
+
+	page = read_cache_page(inode->i_mapping, index,
+			(filler_t *)inode->i_mapping->a_ops->readpage, file);
+	if (IS_ERR(page))
+		goto out;
+	wait_on_page_locked(page);
+	if (!PageUptodate(page) || PageError(page)) {
+		page_cache_release(page);
+		page = ERR_PTR(-EIO);
+		goto out;
+	}
+
+	if (index > end_index) /* we have read beyond EOF */
+		*bytes_read = 0;
+	else if (index == end_index) /* possible short read */
+		*bytes_read = isize & ~PAGE_CACHE_MASK;
+	else
+		*bytes_read = PAGE_CACHE_SIZE; /* got a full page */
+out:
+	if (IS_ERR(page))
+		printk(KERN_ALERT "md: bitmap read error: (%dB @ %Lu): %ld\n",
+			(int)PAGE_CACHE_SIZE,
+			(unsigned long long)index << PAGE_CACHE_SHIFT,
+			PTR_ERR(page));
+	return page;
+}
+
+/*
+ * bitmap file superblock operations
+ */
+
+/* update the event counter and sync the superblock to disk */
+int bitmap_update_sb(struct bitmap *bitmap)
+{
+	bitmap_super_t *sb;
+	unsigned long flags;
+
+	if (!bitmap || !bitmap->mddev) /* no bitmap for this array */
+		return 0;
+	spin_lock_irqsave(&bitmap->lock, flags);
+	if (!bitmap->sb_page) { /* no superblock */
+		spin_unlock_irqrestore(&bitmap->lock, flags);
+		return 0;
+	}
+	spin_unlock_irqrestore(&bitmap->lock, flags);
+	sb = (bitmap_super_t *)kmap(bitmap->sb_page);
+	sb->events = cpu_to_le64(bitmap->mddev->events);
+	if (!bitmap->mddev->degraded)
+		sb->events_cleared = cpu_to_le64(bitmap->mddev->events);
+	kunmap(bitmap->sb_page);
+	return write_page(bitmap, bitmap->sb_page, 1);
+}
+
+/* print out the bitmap file superblock */
+void bitmap_print_sb(struct bitmap *bitmap)
+{
+	bitmap_super_t *sb;
+
+	if (!bitmap || !bitmap->sb_page)
+		return;
+	sb = (bitmap_super_t *)kmap(bitmap->sb_page);
+	printk(KERN_DEBUG "%s: bitmap file superblock:\n", bmname(bitmap));
+	printk(KERN_DEBUG "         magic: %08x\n", le32_to_cpu(sb->magic));
+	printk(KERN_DEBUG "       version: %d\n", le32_to_cpu(sb->version));
+	printk(KERN_DEBUG "          uuid: %08x.%08x.%08x.%08x\n",
+					*(__u32 *)(sb->uuid+0),
+					*(__u32 *)(sb->uuid+4),
+					*(__u32 *)(sb->uuid+8),
+					*(__u32 *)(sb->uuid+12));
+	printk(KERN_DEBUG "        events: %llu\n",
+			(unsigned long long) le64_to_cpu(sb->events));
+	printk(KERN_DEBUG "events cleared: %llu\n",
+			(unsigned long long) le64_to_cpu(sb->events_cleared));
+	printk(KERN_DEBUG "         state: %08x\n", le32_to_cpu(sb->state));
+	printk(KERN_DEBUG "     chunksize: %d B\n", le32_to_cpu(sb->chunksize));
+	printk(KERN_DEBUG "  daemon sleep: %ds\n", le32_to_cpu(sb->daemon_sleep));
+	printk(KERN_DEBUG "     sync size: %llu KB\n",
+			(unsigned long long)le64_to_cpu(sb->sync_size)/2);
+	kunmap(bitmap->sb_page);
+}
+
+/* read the superblock from the bitmap file and initialize some bitmap fields */
+static int bitmap_read_sb(struct bitmap *bitmap)
+{
+	char *reason = NULL;
+	bitmap_super_t *sb;
+	unsigned long chunksize, daemon_sleep;
+	unsigned long bytes_read;
+	unsigned long long events;
+	int err = -EINVAL;
+
+	/* page 0 is the superblock, read it... */
+	if (bitmap->file)
+		bitmap->sb_page = read_page(bitmap->file, 0, &bytes_read);
+	else {
+		bitmap->sb_page = read_sb_page(bitmap->mddev, bitmap->offset, 0);
+		bytes_read = PAGE_SIZE;
+	}
+	if (IS_ERR(bitmap->sb_page)) {
+		err = PTR_ERR(bitmap->sb_page);
+		bitmap->sb_page = NULL;
+		return err;
+	}
+
+	sb = (bitmap_super_t *)kmap(bitmap->sb_page);
+
+	if (bytes_read < sizeof(*sb)) { /* short read */
+		printk(KERN_INFO "%s: bitmap file superblock truncated\n",
+			bmname(bitmap));
+		err = -ENOSPC;
+		goto out;
+	}
+
+	chunksize = le32_to_cpu(sb->chunksize);
+	daemon_sleep = le32_to_cpu(sb->daemon_sleep);
+
+	/* verify that the bitmap-specific fields are valid */
+	if (sb->magic != cpu_to_le32(BITMAP_MAGIC))
+		reason = "bad magic";
+	else if (sb->version != cpu_to_le32(BITMAP_MAJOR))
+		reason = "unrecognized superblock version";
+	else if (chunksize < 512 || chunksize > (1024 * 1024 * 4))
+		reason = "bitmap chunksize out of range (512B - 4MB)";
+	else if ((1 << ffz(~chunksize)) != chunksize)
+		reason = "bitmap chunksize not a power of 2";
+	else if (daemon_sleep < 1 || daemon_sleep > 15)
+		reason = "daemon sleep period out of range";
+	if (reason) {
+		printk(KERN_INFO "%s: invalid bitmap file superblock: %s\n",
+			bmname(bitmap), reason);
+		goto out;
+	}
+
+	/* keep the array size field of the bitmap superblock up to date */
+	sb->sync_size = cpu_to_le64(bitmap->mddev->resync_max_sectors);
+
+	if (!bitmap->mddev->persistent)
+		goto success;
+
+	/*
+	 * if we have a persistent array superblock, compare the
+	 * bitmap's UUID and event counter to the mddev's
+	 */
+	if (memcmp(sb->uuid, bitmap->mddev->uuid, 16)) {
+		printk(KERN_INFO "%s: bitmap superblock UUID mismatch\n",
+			bmname(bitmap));
+		goto out;
+	}
+	events = le64_to_cpu(sb->events);
+	if (events < bitmap->mddev->events) {
+		printk(KERN_INFO "%s: bitmap file is out of date (%llu < %llu) "
+			"-- forcing full recovery\n", bmname(bitmap), events,
+			(unsigned long long) bitmap->mddev->events);
+		sb->state |= BITMAP_STALE;
+	}
+success:
+	/* assign fields using values from superblock */
+	bitmap->chunksize = chunksize;
+	bitmap->daemon_sleep = daemon_sleep;
+	bitmap->flags |= sb->state;
+	bitmap->events_cleared = le64_to_cpu(sb->events_cleared);
+	err = 0;
+out:
+	kunmap(bitmap->sb_page);
+	if (err)
+		bitmap_print_sb(bitmap);
+	return err;
+}
+
+enum bitmap_mask_op {
+	MASK_SET,
+	MASK_UNSET
+};
+
+/* record the state of the bitmap in the superblock */
+static void bitmap_mask_state(struct bitmap *bitmap, enum bitmap_state bits,
+				enum bitmap_mask_op op)
+{
+	bitmap_super_t *sb;
+	unsigned long flags;
+
+	spin_lock_irqsave(&bitmap->lock, flags);
+	if (!bitmap || !bitmap->sb_page) { /* can't set the state */
+		spin_unlock_irqrestore(&bitmap->lock, flags);
+		return;
+	}
+	page_cache_get(bitmap->sb_page);
+	spin_unlock_irqrestore(&bitmap->lock, flags);
+	sb = (bitmap_super_t *)kmap(bitmap->sb_page);
+	switch (op) {
+		case MASK_SET: sb->state |= bits;
+				break;
+		case MASK_UNSET: sb->state &= ~bits;
+				break;
+		default: BUG();
+	}
+	kunmap(bitmap->sb_page);
+	page_cache_release(bitmap->sb_page);
+}
+
+/*
+ * general bitmap file operations
+ */
+
+/* calculate the index of the page that contains this bit */
+static inline unsigned long file_page_index(unsigned long chunk)
+{
+	return CHUNK_BIT_OFFSET(chunk) >> PAGE_BIT_SHIFT;
+}
+
+/* calculate the (bit) offset of this bit within a page */
+static inline unsigned long file_page_offset(unsigned long chunk)
+{
+	return CHUNK_BIT_OFFSET(chunk) & (PAGE_BITS - 1);
+}
+
+/*
+ * return a pointer to the page in the filemap that contains the given bit
+ *
+ * this lookup is complicated by the fact that the bitmap sb might be exactly
+ * 1 page (e.g., x86) or less than 1 page -- so the bitmap might start on page
+ * 0 or page 1
+ */
+static inline struct page *filemap_get_page(struct bitmap *bitmap,
+					unsigned long chunk)
+{
+	return bitmap->filemap[file_page_index(chunk) - file_page_index(0)];
+}
+
+
+static void bitmap_file_unmap(struct bitmap *bitmap)
+{
+	struct page **map, *sb_page;
+	unsigned long *attr;
+	int pages;
+	unsigned long flags;
+
+	spin_lock_irqsave(&bitmap->lock, flags);
+	map = bitmap->filemap;
+	bitmap->filemap = NULL;
+	attr = bitmap->filemap_attr;
+	bitmap->filemap_attr = NULL;
+	pages = bitmap->file_pages;
+	bitmap->file_pages = 0;
+	sb_page = bitmap->sb_page;
+	bitmap->sb_page = NULL;
+	spin_unlock_irqrestore(&bitmap->lock, flags);
+
+	while (pages--)
+		if (map[pages]->index != 0) /* 0 is sb_page, release it below */
+			page_cache_release(map[pages]);
+	kfree(map);
+	kfree(attr);
+
+	if (sb_page)
+		page_cache_release(sb_page);
+}
+
+static void bitmap_stop_daemons(struct bitmap *bitmap);
+
+/* dequeue the next item in a page list -- don't call from irq context */
+static struct page_list *dequeue_page(struct bitmap *bitmap)
+{
+	struct page_list *item = NULL;
+	struct list_head *head = &bitmap->complete_pages;
+
+	spin_lock(&bitmap->write_lock);
+	if (list_empty(head))
+		goto out;
+	item = list_entry(head->prev, struct page_list, list);
+	list_del(head->prev);
+out:
+	spin_unlock(&bitmap->write_lock);
+	return item;
+}
+
+static void drain_write_queues(struct bitmap *bitmap)
+{
+	struct page_list *item;
+
+	while ((item = dequeue_page(bitmap))) {
+		/* don't bother to wait */
+		page_cache_release(item->page);
+		mempool_free(item, bitmap->write_pool);
+	}
+
+	wake_up(&bitmap->write_wait);
+}
+
+static void bitmap_file_put(struct bitmap *bitmap)
+{
+	struct file *file;
+	struct inode *inode;
+	unsigned long flags;
+
+	spin_lock_irqsave(&bitmap->lock, flags);
+	file = bitmap->file;
+	bitmap->file = NULL;
+	spin_unlock_irqrestore(&bitmap->lock, flags);
+
+	bitmap_stop_daemons(bitmap);
+
+	drain_write_queues(bitmap);
+
+	bitmap_file_unmap(bitmap);
+
+	if (file) {
+		inode = file->f_mapping->host;
+		spin_lock(&inode->i_lock);
+		atomic_set(&inode->i_writecount, 1); /* allow writes again */
+		spin_unlock(&inode->i_lock);
+		fput(file);
+	}
+}
+
+
+/*
+ * bitmap_file_kick - if an error occurs while manipulating the bitmap file
+ * then it is no longer reliable, so we stop using it and we mark the file
+ * as failed in the superblock
+ */
+static void bitmap_file_kick(struct bitmap *bitmap)
+{
+	char *path, *ptr = NULL;
+
+	bitmap_mask_state(bitmap, BITMAP_STALE, MASK_SET);
+	bitmap_update_sb(bitmap);
+
+	if (bitmap->file) {
+		path = kmalloc(PAGE_SIZE, GFP_KERNEL);
+		if (path)
+			ptr = file_path(bitmap->file, path, PAGE_SIZE);
+
+		printk(KERN_ALERT "%s: kicking failed bitmap file %s from array!\n",
+		       bmname(bitmap), ptr ? ptr : "");
+
+		kfree(path);
+	}
+
+	bitmap_file_put(bitmap);
+
+	return;
+}
+
+enum bitmap_page_attr {
+	BITMAP_PAGE_DIRTY = 1, // there are set bits that need to be synced
+	BITMAP_PAGE_CLEAN = 2, // there are bits that might need to be cleared
+	BITMAP_PAGE_NEEDWRITE=4, // there are cleared bits that need to be synced
+};
+
+static inline void set_page_attr(struct bitmap *bitmap, struct page *page,
+				enum bitmap_page_attr attr)
+{
+	bitmap->filemap_attr[page->index] |= attr;
+}
+
+static inline void clear_page_attr(struct bitmap *bitmap, struct page *page,
+				enum bitmap_page_attr attr)
+{
+	bitmap->filemap_attr[page->index] &= ~attr;
+}
+
+static inline unsigned long get_page_attr(struct bitmap *bitmap, struct page *page)
+{
+	return bitmap->filemap_attr[page->index];
+}
+
+/*
+ * bitmap_file_set_bit -- called before performing a write to the md device
+ * to set (and eventually sync) a particular bit in the bitmap file
+ *
+ * we set the bit immediately, then we record the page number so that
+ * when an unplug occurs, we can flush the dirty pages out to disk
+ */
+static void bitmap_file_set_bit(struct bitmap *bitmap, sector_t block)
+{
+	unsigned long bit;
+	struct page *page;
+	void *kaddr;
+	unsigned long chunk = block >> CHUNK_BLOCK_SHIFT(bitmap);
+
+	if (!bitmap->filemap) {
+		return;
+	}
+
+	page = filemap_get_page(bitmap, chunk);
+	bit = file_page_offset(chunk);
+
+
+	/* make sure the page stays cached until it gets written out */
+	if (! (get_page_attr(bitmap, page) & BITMAP_PAGE_DIRTY))
+		page_cache_get(page);
+
+ 	/* set the bit */
+	kaddr = kmap_atomic(page, KM_USER0);
+	set_bit(bit, kaddr);
+	kunmap_atomic(kaddr, KM_USER0);
+	PRINTK("set file bit %lu page %lu\n", bit, page->index);
+
+	/* record page number so it gets flushed to disk when unplug occurs */
+	set_page_attr(bitmap, page, BITMAP_PAGE_DIRTY);
+
+}
+
+/* this gets called when the md device is ready to unplug its underlying
+ * (slave) device queues -- before we let any writes go down, we need to
+ * sync the dirty pages of the bitmap file to disk */
+int bitmap_unplug(struct bitmap *bitmap)
+{
+	unsigned long i, attr, flags;
+	struct page *page;
+	int wait = 0;
+	int err;
+
+	if (!bitmap)
+		return 0;
+
+	/* look at each page to see if there are any set bits that need to be
+	 * flushed out to disk */
+	for (i = 0; i < bitmap->file_pages; i++) {
+		spin_lock_irqsave(&bitmap->lock, flags);
+		if (!bitmap->filemap) {
+			spin_unlock_irqrestore(&bitmap->lock, flags);
+			return 0;
+		}
+		page = bitmap->filemap[i];
+		attr = get_page_attr(bitmap, page);
+		clear_page_attr(bitmap, page, BITMAP_PAGE_DIRTY);
+		clear_page_attr(bitmap, page, BITMAP_PAGE_NEEDWRITE);
+		if ((attr & BITMAP_PAGE_DIRTY))
+			wait = 1;
+		spin_unlock_irqrestore(&bitmap->lock, flags);
+
+		if (attr & (BITMAP_PAGE_DIRTY | BITMAP_PAGE_NEEDWRITE)) {
+			err = write_page(bitmap, page, 0);
+			if (err == -EAGAIN) {
+				if (attr & BITMAP_PAGE_DIRTY)
+					err = write_page(bitmap, page, 1);
+				else
+					err = 0;
+			}
+			if (err)
+				return 1;
+		}
+	}
+	if (wait) { /* if any writes were performed, we need to wait on them */
+		if (bitmap->file) {
+			spin_lock_irq(&bitmap->write_lock);
+			wait_event_lock_irq(bitmap->write_wait,
+					    list_empty(&bitmap->complete_pages), bitmap->write_lock,
+					    wake_up_process(bitmap->writeback_daemon->tsk));
+			spin_unlock_irq(&bitmap->write_lock);
+		} else
+			wait_event(bitmap->mddev->sb_wait,
+				   atomic_read(&bitmap->mddev->pending_writes)==0);
+	}
+	return 0;
+}
+
+static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset);
+/* * bitmap_init_from_disk -- called at bitmap_create time to initialize
+ * the in-memory bitmap from the on-disk bitmap -- also, sets up the
+ * memory mapping of the bitmap file
+ * Special cases:
+ *   if there's no bitmap file, or if the bitmap file had been
+ *   previously kicked from the array, we mark all the bits as
+ *   1's in order to cause a full resync.
+ */
+static int bitmap_init_from_disk(struct bitmap *bitmap)
+{
+	unsigned long i, chunks, index, oldindex, bit;
+	struct page *page = NULL, *oldpage = NULL;
+	unsigned long num_pages, bit_cnt = 0;
+	struct file *file;
+	unsigned long bytes, offset, dummy;
+	int outofdate;
+	int ret = -ENOSPC;
+
+	chunks = bitmap->chunks;
+	file = bitmap->file;
+
+	BUG_ON(!file && !bitmap->offset);
+
+#ifdef INJECT_FAULTS_3
+	outofdate = 1;
+#else
+	outofdate = bitmap->flags & BITMAP_STALE;
+#endif
+	if (outofdate)
+		printk(KERN_INFO "%s: bitmap file is out of date, doing full "
+			"recovery\n", bmname(bitmap));
+
+	bytes = (chunks + 7) / 8;
+
+	num_pages = (bytes + sizeof(bitmap_super_t) + PAGE_SIZE - 1) / PAGE_SIZE;
+
+	if (file && i_size_read(file->f_mapping->host) < bytes + sizeof(bitmap_super_t)) {
+		printk(KERN_INFO "%s: bitmap file too short %lu < %lu\n",
+			bmname(bitmap),
+			(unsigned long) i_size_read(file->f_mapping->host),
+			bytes + sizeof(bitmap_super_t));
+		goto out;
+	}
+
+	ret = -ENOMEM;
+
+	bitmap->filemap = kmalloc(sizeof(struct page *) * num_pages, GFP_KERNEL);
+	if (!bitmap->filemap)
+		goto out;
+
+	bitmap->filemap_attr = kmalloc(sizeof(long) * num_pages, GFP_KERNEL);
+	if (!bitmap->filemap_attr)
+		goto out;
+
+	memset(bitmap->filemap_attr, 0, sizeof(long) * num_pages);
+
+	oldindex = ~0L;
+
+	for (i = 0; i < chunks; i++) {
+		index = file_page_index(i);
+		bit = file_page_offset(i);
+		if (index != oldindex) { /* this is a new page, read it in */
+			/* unmap the old page, we're done with it */
+			if (oldpage != NULL)
+				kunmap(oldpage);
+			if (index == 0) {
+				/*
+				 * if we're here then the superblock page
+				 * contains some bits (PAGE_SIZE != sizeof sb)
+				 * we've already read it in, so just use it
+				 */
+				page = bitmap->sb_page;
+				offset = sizeof(bitmap_super_t);
+			} else if (file) {
+				page = read_page(file, index, &dummy);
+				offset = 0;
+			} else {
+				page = read_sb_page(bitmap->mddev, bitmap->offset, index);
+				offset = 0;
+			}
+			if (IS_ERR(page)) { /* read error */
+				ret = PTR_ERR(page);
+				goto out;
+			}
+
+			oldindex = index;
+			oldpage = page;
+			kmap(page);
+
+			if (outofdate) {
+				/*
+				 * if bitmap is out of date, dirty the
+			 	 * whole page and write it out
+				 */
+				memset(page_address(page) + offset, 0xff,
+					PAGE_SIZE - offset);
+				ret = write_page(bitmap, page, 1);
+				if (ret) {
+					kunmap(page);
+					/* release, page not in filemap yet */
+					page_cache_release(page);
+					goto out;
+				}
+			}
+
+			bitmap->filemap[bitmap->file_pages++] = page;
+		}
+		if (test_bit(bit, page_address(page))) {
+			/* if the disk bit is set, set the memory bit */
+			bitmap_set_memory_bits(bitmap, i << CHUNK_BLOCK_SHIFT(bitmap));
+			bit_cnt++;
+		}
+	}
+
+ 	/* everything went OK */
+	ret = 0;
+	bitmap_mask_state(bitmap, BITMAP_STALE, MASK_UNSET);
+
+	if (page) /* unmap the last page */
+		kunmap(page);
+
+	if (bit_cnt) { /* Kick recovery if any bits were set */
+		set_bit(MD_RECOVERY_NEEDED, &bitmap->mddev->recovery);
+		md_wakeup_thread(bitmap->mddev->thread);
+	}
+
+out:
+	printk(KERN_INFO "%s: bitmap initialized from disk: "
+		"read %lu/%lu pages, set %lu bits, status: %d\n",
+		bmname(bitmap), bitmap->file_pages, num_pages, bit_cnt, ret);
+
+	return ret;
+}
+
+void bitmap_write_all(struct bitmap *bitmap)
+{
+	/* We don't actually write all bitmap blocks here,
+	 * just flag them as needing to be written
+	 */
+
+	unsigned long chunks = bitmap->chunks;
+	unsigned long bytes = (chunks+7)/8 + sizeof(bitmap_super_t);
+	unsigned long num_pages = (bytes + PAGE_SIZE-1) / PAGE_SIZE;
+	while (num_pages--)
+		bitmap->filemap_attr[num_pages] |= BITMAP_PAGE_NEEDWRITE;
+}
+
+
+static void bitmap_count_page(struct bitmap *bitmap, sector_t offset, int inc)
+{
+	sector_t chunk = offset >> CHUNK_BLOCK_SHIFT(bitmap);
+	unsigned long page = chunk >> PAGE_COUNTER_SHIFT;
+	bitmap->bp[page].count += inc;
+/*
+	if (page == 0) printk("count page 0, offset %llu: %d gives %d\n",
+			      (unsigned long long)offset, inc, bitmap->bp[page].count);
+*/
+	bitmap_checkfree(bitmap, page);
+}
+static bitmap_counter_t *bitmap_get_counter(struct bitmap *bitmap,
+					    sector_t offset, int *blocks,
+					    int create);
+
+/*
+ * bitmap daemon -- periodically wakes up to clean bits and flush pages
+ *			out to disk
+ */
+
+int bitmap_daemon_work(struct bitmap *bitmap)
+{
+	unsigned long j;
+	unsigned long flags;
+	struct page *page = NULL, *lastpage = NULL;
+	int err = 0;
+	int blocks;
+	int attr;
+
+	if (bitmap == NULL)
+		return 0;
+	if (time_before(jiffies, bitmap->daemon_lastrun + bitmap->daemon_sleep*HZ))
+		return 0;
+	bitmap->daemon_lastrun = jiffies;
+
+	for (j = 0; j < bitmap->chunks; j++) {
+		bitmap_counter_t *bmc;
+		spin_lock_irqsave(&bitmap->lock, flags);
+		if (!bitmap->filemap) {
+			/* error or shutdown */
+			spin_unlock_irqrestore(&bitmap->lock, flags);
+			break;
+		}
+
+		page = filemap_get_page(bitmap, j);
+
+		if (page != lastpage) {
+			/* skip this page unless it's marked as needing cleaning */
+			if (!((attr=get_page_attr(bitmap, page)) & BITMAP_PAGE_CLEAN)) {
+				if (attr & BITMAP_PAGE_NEEDWRITE) {
+					page_cache_get(page);
+					clear_page_attr(bitmap, page, BITMAP_PAGE_NEEDWRITE);
+				}
+				spin_unlock_irqrestore(&bitmap->lock, flags);
+				if (attr & BITMAP_PAGE_NEEDWRITE) {
+					switch (write_page(bitmap, page, 0)) {
+					case -EAGAIN:
+						set_page_attr(bitmap, page, BITMAP_PAGE_NEEDWRITE);
+						break;
+					case 0:
+						break;
+					default:
+						bitmap_file_kick(bitmap);
+					}
+					page_cache_release(page);
+				}
+				continue;
+			}
+
+			/* grab the new page, sync and release the old */
+			page_cache_get(page);
+			if (lastpage != NULL) {
+				if (get_page_attr(bitmap, lastpage) & BITMAP_PAGE_NEEDWRITE) {
+					clear_page_attr(bitmap, lastpage, BITMAP_PAGE_NEEDWRITE);
+					spin_unlock_irqrestore(&bitmap->lock, flags);
+					err = write_page(bitmap, lastpage, 0);
+					if (err == -EAGAIN) {
+						err = 0;
+						set_page_attr(bitmap, lastpage, BITMAP_PAGE_NEEDWRITE);
+					}
+				} else {
+					set_page_attr(bitmap, lastpage, BITMAP_PAGE_NEEDWRITE);
+					spin_unlock_irqrestore(&bitmap->lock, flags);
+				}
+				kunmap(lastpage);
+				page_cache_release(lastpage);
+				if (err)
+					bitmap_file_kick(bitmap);
+			} else
+				spin_unlock_irqrestore(&bitmap->lock, flags);
+			lastpage = page;
+			kmap(page);
+/*
+			printk("bitmap clean at page %lu\n", j);
+*/
+			spin_lock_irqsave(&bitmap->lock, flags);
+			clear_page_attr(bitmap, page, BITMAP_PAGE_CLEAN);
+		}
+		bmc = bitmap_get_counter(bitmap, j << CHUNK_BLOCK_SHIFT(bitmap),
+					&blocks, 0);
+		if (bmc) {
+/*
+  if (j < 100) printk("bitmap: j=%lu, *bmc = 0x%x\n", j, *bmc);
+*/
+			if (*bmc == 2) {
+				*bmc=1; /* maybe clear the bit next time */
+				set_page_attr(bitmap, page, BITMAP_PAGE_CLEAN);
+			} else if (*bmc == 1) {
+				/* we can clear the bit */
+				*bmc = 0;
+				bitmap_count_page(bitmap, j << CHUNK_BLOCK_SHIFT(bitmap),
+						  -1);
+
+				/* clear the bit */
+				clear_bit(file_page_offset(j), page_address(page));
+			}
+		}
+		spin_unlock_irqrestore(&bitmap->lock, flags);
+	}
+
+	/* now sync the final page */
+	if (lastpage != NULL) {
+		kunmap(lastpage);
+		spin_lock_irqsave(&bitmap->lock, flags);
+		if (get_page_attr(bitmap, lastpage) &BITMAP_PAGE_NEEDWRITE) {
+			clear_page_attr(bitmap, lastpage, BITMAP_PAGE_NEEDWRITE);
+			spin_unlock_irqrestore(&bitmap->lock, flags);
+			err = write_page(bitmap, lastpage, 0);
+			if (err == -EAGAIN) {
+				set_page_attr(bitmap, lastpage, BITMAP_PAGE_NEEDWRITE);
+				err = 0;
+			}
+		} else {
+			set_page_attr(bitmap, lastpage, BITMAP_PAGE_NEEDWRITE);
+			spin_unlock_irqrestore(&bitmap->lock, flags);
+		}
+
+		page_cache_release(lastpage);
+	}
+
+	return err;
+}
+
+static void daemon_exit(struct bitmap *bitmap, mdk_thread_t **daemon)
+{
+	mdk_thread_t *dmn;
+	unsigned long flags;
+
+	/* if no one is waiting on us, we'll free the md thread struct
+	 * and exit, otherwise we let the waiter clean things up */
+	spin_lock_irqsave(&bitmap->lock, flags);
+	if ((dmn = *daemon)) { /* no one is waiting, cleanup and exit */
+		*daemon = NULL;
+		spin_unlock_irqrestore(&bitmap->lock, flags);
+		kfree(dmn);
+		complete_and_exit(NULL, 0); /* do_exit not exported */
+	}
+	spin_unlock_irqrestore(&bitmap->lock, flags);
+}
+
+static void bitmap_writeback_daemon(mddev_t *mddev)
+{
+	struct bitmap *bitmap = mddev->bitmap;
+	struct page *page;
+	struct page_list *item;
+	int err = 0;
+
+	if (signal_pending(current)) {
+		printk(KERN_INFO
+		       "%s: bitmap writeback daemon got signal, exiting...\n",
+		       bmname(bitmap));
+		err = -EINTR;
+		goto out;
+	}
+
+	PRINTK("%s: bitmap writeback daemon woke up...\n", bmname(bitmap));
+	/* wait on bitmap page writebacks */
+	while ((item = dequeue_page(bitmap))) {
+		page = item->page;
+		mempool_free(item, bitmap->write_pool);
+		PRINTK("wait on page writeback: %p\n", page);
+		wait_on_page_writeback(page);
+		PRINTK("finished page writeback: %p\n", page);
+
+		err = PageError(page);
+		page_cache_release(page);
+		if (err) {
+			printk(KERN_WARNING "%s: bitmap file writeback "
+			       "failed (page %lu): %d\n",
+			       bmname(bitmap), page->index, err);
+			bitmap_file_kick(bitmap);
+			goto out;
+		}
+	}
+ out:
+	wake_up(&bitmap->write_wait);
+	if (err) {
+		printk(KERN_INFO "%s: bitmap writeback daemon exiting (%d)\n",
+		       bmname(bitmap), err);
+		daemon_exit(bitmap, &bitmap->writeback_daemon);
+	}
+}
+
+static int bitmap_start_daemon(struct bitmap *bitmap, mdk_thread_t **ptr,
+				void (*func)(mddev_t *), char *name)
+{
+	mdk_thread_t *daemon;
+	unsigned long flags;
+	char namebuf[32];
+
+	spin_lock_irqsave(&bitmap->lock, flags);
+	*ptr = NULL;
+
+	if (!bitmap->file) /* no need for daemon if there's no backing file */
+		goto out_unlock;
+
+	spin_unlock_irqrestore(&bitmap->lock, flags);
+
+#ifdef INJECT_FATAL_FAULT_2
+	daemon = NULL;
+#else
+	sprintf(namebuf, "%%s_%s", name);
+	daemon = md_register_thread(func, bitmap->mddev, namebuf);
+#endif
+	if (!daemon) {
+		printk(KERN_ERR "%s: failed to start bitmap daemon\n",
+			bmname(bitmap));
+		return -ECHILD;
+	}
+
+	spin_lock_irqsave(&bitmap->lock, flags);
+	*ptr = daemon;
+
+	md_wakeup_thread(daemon); /* start it running */
+
+	PRINTK("%s: %s daemon (pid %d) started...\n",
+		bmname(bitmap), name, daemon->tsk->pid);
+out_unlock:
+	spin_unlock_irqrestore(&bitmap->lock, flags);
+	return 0;
+}
+
+static int bitmap_start_daemons(struct bitmap *bitmap)
+{
+	int err = bitmap_start_daemon(bitmap, &bitmap->writeback_daemon,
+					bitmap_writeback_daemon, "bitmap_wb");
+	return err;
+}
+
+static void bitmap_stop_daemon(struct bitmap *bitmap, mdk_thread_t **ptr)
+{
+	mdk_thread_t *daemon;
+	unsigned long flags;
+
+	spin_lock_irqsave(&bitmap->lock, flags);
+	daemon = *ptr;
+	*ptr = NULL;
+	spin_unlock_irqrestore(&bitmap->lock, flags);
+	if (daemon)
+		md_unregister_thread(daemon); /* destroy the thread */
+}
+
+static void bitmap_stop_daemons(struct bitmap *bitmap)
+{
+	/* the daemons can't stop themselves... they'll just exit instead... */
+	if (bitmap->writeback_daemon &&
+	    current->pid != bitmap->writeback_daemon->tsk->pid)
+		bitmap_stop_daemon(bitmap, &bitmap->writeback_daemon);
+}
+
+static bitmap_counter_t *bitmap_get_counter(struct bitmap *bitmap,
+					    sector_t offset, int *blocks,
+					    int create)
+{
+	/* If 'create', we might release the lock and reclaim it.
+	 * The lock must have been taken with interrupts enabled.
+	 * If !create, we don't release the lock.
+	 */
+	sector_t chunk = offset >> CHUNK_BLOCK_SHIFT(bitmap);
+	unsigned long page = chunk >> PAGE_COUNTER_SHIFT;
+	unsigned long pageoff = (chunk & PAGE_COUNTER_MASK) << COUNTER_BYTE_SHIFT;
+	sector_t csize;
+
+	if (bitmap_checkpage(bitmap, page, create) < 0) {
+		csize = ((sector_t)1) << (CHUNK_BLOCK_SHIFT(bitmap));
+		*blocks = csize - (offset & (csize- 1));
+		return NULL;
+	}
+	/* now locked ... */
+
+	if (bitmap->bp[page].hijacked) { /* hijacked pointer */
+		/* should we use the first or second counter field
+		 * of the hijacked pointer? */
+		int hi = (pageoff > PAGE_COUNTER_MASK);
+		csize = ((sector_t)1) << (CHUNK_BLOCK_SHIFT(bitmap) +
+					  PAGE_COUNTER_SHIFT - 1);
+		*blocks = csize - (offset & (csize- 1));
+		return  &((bitmap_counter_t *)
+			  &bitmap->bp[page].map)[hi];
+	} else { /* page is allocated */
+		csize = ((sector_t)1) << (CHUNK_BLOCK_SHIFT(bitmap));
+		*blocks = csize - (offset & (csize- 1));
+		return (bitmap_counter_t *)
+			&(bitmap->bp[page].map[pageoff]);
+	}
+}
+
+int bitmap_startwrite(struct bitmap *bitmap, sector_t offset, unsigned long sectors)
+{
+	if (!bitmap) return 0;
+	while (sectors) {
+		int blocks;
+		bitmap_counter_t *bmc;
+
+		spin_lock_irq(&bitmap->lock);
+		bmc = bitmap_get_counter(bitmap, offset, &blocks, 1);
+		if (!bmc) {
+			spin_unlock_irq(&bitmap->lock);
+			return 0;
+		}
+
+		switch(*bmc) {
+		case 0:
+			bitmap_file_set_bit(bitmap, offset);
+			bitmap_count_page(bitmap,offset, 1);
+			blk_plug_device(bitmap->mddev->queue);
+			/* fall through */
+		case 1:
+			*bmc = 2;
+		}
+		if ((*bmc & COUNTER_MAX) == COUNTER_MAX) BUG();
+		(*bmc)++;
+
+		spin_unlock_irq(&bitmap->lock);
+
+		offset += blocks;
+		if (sectors > blocks)
+			sectors -= blocks;
+		else sectors = 0;
+	}
+	return 0;
+}
+
+void bitmap_endwrite(struct bitmap *bitmap, sector_t offset, unsigned long sectors,
+		     int success)
+{
+	if (!bitmap) return;
+	while (sectors) {
+		int blocks;
+		unsigned long flags;
+		bitmap_counter_t *bmc;
+
+		spin_lock_irqsave(&bitmap->lock, flags);
+		bmc = bitmap_get_counter(bitmap, offset, &blocks, 0);
+		if (!bmc) {
+			spin_unlock_irqrestore(&bitmap->lock, flags);
+			return;
+		}
+
+		if (!success && ! (*bmc & NEEDED_MASK))
+			*bmc |= NEEDED_MASK;
+
+		(*bmc)--;
+		if (*bmc <= 2) {
+			set_page_attr(bitmap,
+				      filemap_get_page(bitmap, offset >> CHUNK_BLOCK_SHIFT(bitmap)),
+				      BITMAP_PAGE_CLEAN);
+		}
+		spin_unlock_irqrestore(&bitmap->lock, flags);
+		offset += blocks;
+		if (sectors > blocks)
+			sectors -= blocks;
+		else sectors = 0;
+	}
+}
+
+int bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *blocks,
+			int degraded)
+{
+	bitmap_counter_t *bmc;
+	int rv;
+	if (bitmap == NULL) {/* FIXME or bitmap set as 'failed' */
+		*blocks = 1024;
+		return 1; /* always resync if no bitmap */
+	}
+	spin_lock_irq(&bitmap->lock);
+	bmc = bitmap_get_counter(bitmap, offset, blocks, 0);
+	rv = 0;
+	if (bmc) {
+		/* locked */
+		if (RESYNC(*bmc))
+			rv = 1;
+		else if (NEEDED(*bmc)) {
+			rv = 1;
+			if (!degraded) { /* don't set/clear bits if degraded */
+				*bmc |= RESYNC_MASK;
+				*bmc &= ~NEEDED_MASK;
+			}
+		}
+	}
+	spin_unlock_irq(&bitmap->lock);
+	return rv;
+}
+
+void bitmap_end_sync(struct bitmap *bitmap, sector_t offset, int *blocks, int aborted)
+{
+	bitmap_counter_t *bmc;
+	unsigned long flags;
+/*
+	if (offset == 0) printk("bitmap_end_sync 0 (%d)\n", aborted);
+*/	if (bitmap == NULL) {
+		*blocks = 1024;
+		return;
+	}
+	spin_lock_irqsave(&bitmap->lock, flags);
+	bmc = bitmap_get_counter(bitmap, offset, blocks, 0);
+	if (bmc == NULL)
+		goto unlock;
+	/* locked */
+/*
+	if (offset == 0) printk("bitmap_end sync found 0x%x, blocks %d\n", *bmc, *blocks);
+*/
+	if (RESYNC(*bmc)) {
+		*bmc &= ~RESYNC_MASK;
+
+		if (!NEEDED(*bmc) && aborted)
+			*bmc |= NEEDED_MASK;
+		else {
+			if (*bmc <= 2) {
+				set_page_attr(bitmap,
+					      filemap_get_page(bitmap, offset >> CHUNK_BLOCK_SHIFT(bitmap)),
+					      BITMAP_PAGE_CLEAN);
+			}
+		}
+	}
+ unlock:
+	spin_unlock_irqrestore(&bitmap->lock, flags);
+}
+
+void bitmap_close_sync(struct bitmap *bitmap)
+{
+	/* Sync has finished, and any bitmap chunks that weren't synced
+	 * properly have been aborted.  It remains to us to clear the
+	 * RESYNC bit wherever it is still on
+	 */
+	sector_t sector = 0;
+	int blocks;
+	if (!bitmap) return;
+	while (sector < bitmap->mddev->resync_max_sectors) {
+		bitmap_end_sync(bitmap, sector, &blocks, 0);
+/*
+		if (sector < 500) printk("bitmap_close_sync: sec %llu blks %d\n",
+					 (unsigned long long)sector, blocks);
+*/		sector += blocks;
+	}
+}
+
+static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset)
+{
+	/* For each chunk covered by any of these sectors, set the
+	 * counter to 1 and set resync_needed.  They should all
+	 * be 0 at this point
+	 */
+
+	int secs;
+	bitmap_counter_t *bmc;
+	spin_lock_irq(&bitmap->lock);
+	bmc = bitmap_get_counter(bitmap, offset, &secs, 1);
+	if (!bmc) {
+		spin_unlock_irq(&bitmap->lock);
+		return;
+	}
+	if (! *bmc) {
+		struct page *page;
+		*bmc = 1 | NEEDED_MASK;
+		bitmap_count_page(bitmap, offset, 1);
+		page = filemap_get_page(bitmap, offset >> CHUNK_BLOCK_SHIFT(bitmap));
+		set_page_attr(bitmap, page, BITMAP_PAGE_CLEAN);
+	}
+	spin_unlock_irq(&bitmap->lock);
+
+}
+
+/*
+ * flush out any pending updates
+ */
+void bitmap_flush(mddev_t *mddev)
+{
+	struct bitmap *bitmap = mddev->bitmap;
+	int sleep;
+
+	if (!bitmap) /* there was no bitmap */
+		return;
+
+	/* run the daemon_work three time to ensure everything is flushed
+	 * that can be
+	 */
+	sleep = bitmap->daemon_sleep;
+	bitmap->daemon_sleep = 0;
+	bitmap_daemon_work(bitmap);
+	bitmap_daemon_work(bitmap);
+	bitmap_daemon_work(bitmap);
+	bitmap->daemon_sleep = sleep;
+	bitmap_update_sb(bitmap);
+}
+
+/*
+ * free memory that was allocated
+ */
+void bitmap_destroy(mddev_t *mddev)
+{
+	unsigned long k, pages;
+	struct bitmap_page *bp;
+	struct bitmap *bitmap = mddev->bitmap;
+
+	if (!bitmap) /* there was no bitmap */
+		return;
+
+	mddev->bitmap = NULL; /* disconnect from the md device */
+
+	/* release the bitmap file and kill the daemon */
+	bitmap_file_put(bitmap);
+
+	bp = bitmap->bp;
+	pages = bitmap->pages;
+
+	/* free all allocated memory */
+
+	mempool_destroy(bitmap->write_pool);
+
+	if (bp) /* deallocate the page memory */
+		for (k = 0; k < pages; k++)
+			if (bp[k].map && !bp[k].hijacked)
+				kfree(bp[k].map);
+	kfree(bp);
+	kfree(bitmap);
+}
+
+/*
+ * initialize the bitmap structure
+ * if this returns an error, bitmap_destroy must be called to do clean up
+ */
+int bitmap_create(mddev_t *mddev)
+{
+	struct bitmap *bitmap;
+	unsigned long blocks = mddev->resync_max_sectors;
+	unsigned long chunks;
+	unsigned long pages;
+	struct file *file = mddev->bitmap_file;
+	int err;
+
+	BUG_ON(sizeof(bitmap_super_t) != 256);
+
+	if (!file && !mddev->bitmap_offset) /* bitmap disabled, nothing to do */
+		return 0;
+
+	BUG_ON(file && mddev->bitmap_offset);
+
+	bitmap = kmalloc(sizeof(*bitmap), GFP_KERNEL);
+	if (!bitmap)
+		return -ENOMEM;
+
+	memset(bitmap, 0, sizeof(*bitmap));
+
+	spin_lock_init(&bitmap->lock);
+	bitmap->mddev = mddev;
+	mddev->bitmap = bitmap;
+
+	spin_lock_init(&bitmap->write_lock);
+	INIT_LIST_HEAD(&bitmap->complete_pages);
+	init_waitqueue_head(&bitmap->write_wait);
+	bitmap->write_pool = mempool_create(WRITE_POOL_SIZE, write_pool_alloc,
+				write_pool_free, NULL);
+	if (!bitmap->write_pool)
+		return -ENOMEM;
+
+	bitmap->file = file;
+	bitmap->offset = mddev->bitmap_offset;
+	if (file) get_file(file);
+	/* read superblock from bitmap file (this sets bitmap->chunksize) */
+	err = bitmap_read_sb(bitmap);
+	if (err)
+		return err;
+
+	bitmap->chunkshift = find_first_bit(&bitmap->chunksize,
+					sizeof(bitmap->chunksize));
+
+	/* now that chunksize and chunkshift are set, we can use these macros */
+ 	chunks = (blocks + CHUNK_BLOCK_RATIO(bitmap) - 1) /
+			CHUNK_BLOCK_RATIO(bitmap);
+ 	pages = (chunks + PAGE_COUNTER_RATIO - 1) / PAGE_COUNTER_RATIO;
+
+	BUG_ON(!pages);
+
+	bitmap->chunks = chunks;
+	bitmap->pages = pages;
+	bitmap->missing_pages = pages;
+	bitmap->counter_bits = COUNTER_BITS;
+
+	bitmap->syncchunk = ~0UL;
+
+#ifdef INJECT_FATAL_FAULT_1
+	bitmap->bp = NULL;
+#else
+	bitmap->bp = kmalloc(pages * sizeof(*bitmap->bp), GFP_KERNEL);
+#endif
+	if (!bitmap->bp)
+		return -ENOMEM;
+	memset(bitmap->bp, 0, pages * sizeof(*bitmap->bp));
+
+	bitmap->flags |= BITMAP_ACTIVE;
+
+	/* now that we have some pages available, initialize the in-memory
+	 * bitmap from the on-disk bitmap */
+	err = bitmap_init_from_disk(bitmap);
+
+	if (err)
+		return err;
+
+	printk(KERN_INFO "created bitmap (%lu pages) for device %s\n",
+		pages, bmname(bitmap));
+
+	/* kick off the bitmap daemons */
+	err = bitmap_start_daemons(bitmap);
+	if (err)
+		return err;
+	return bitmap_update_sb(bitmap);
+}
+
+/* the bitmap API -- for raid personalities */
+EXPORT_SYMBOL(bitmap_startwrite);
+EXPORT_SYMBOL(bitmap_endwrite);
+EXPORT_SYMBOL(bitmap_start_sync);
+EXPORT_SYMBOL(bitmap_end_sync);
+EXPORT_SYMBOL(bitmap_unplug);
+EXPORT_SYMBOL(bitmap_close_sync);
+EXPORT_SYMBOL(bitmap_daemon_work);
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -704,8 +704,7 @@ static void crypt_dtr(struct dm_target *
 	mempool_destroy(cc->page_pool);
 	mempool_destroy(cc->io_pool);
 
-	if (cc->iv_mode)
-		kfree(cc->iv_mode);
+	kfree(cc->iv_mode);
 	if (cc->iv_gen_ops && cc->iv_gen_ops->dtr)
 		cc->iv_gen_ops->dtr(cc);
 	crypto_free_tfm(cc->tfm);
diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c
--- a/drivers/md/dm-ioctl.c
+++ b/drivers/md/dm-ioctl.c
@@ -122,14 +122,6 @@ static struct hash_cell *__get_uuid_cell
 /*-----------------------------------------------------------------
  * Inserting, removing and renaming a device.
  *---------------------------------------------------------------*/
-static inline char *kstrdup(const char *str)
-{
-	char *r = kmalloc(strlen(str) + 1, GFP_KERNEL);
-	if (r)
-		strcpy(r, str);
-	return r;
-}
-
 static struct hash_cell *alloc_cell(const char *name, const char *uuid,
 				    struct mapped_device *md)
 {
@@ -139,7 +131,7 @@ static struct hash_cell *alloc_cell(cons
 	if (!hc)
 		return NULL;
 
-	hc->name = kstrdup(name);
+	hc->name = kstrdup(name, GFP_KERNEL);
 	if (!hc->name) {
 		kfree(hc);
 		return NULL;
@@ -149,7 +141,7 @@ static struct hash_cell *alloc_cell(cons
 		hc->uuid = NULL;
 
 	else {
-		hc->uuid = kstrdup(uuid);
+		hc->uuid = kstrdup(uuid, GFP_KERNEL);
 		if (!hc->uuid) {
 			kfree(hc->name);
 			kfree(hc);
@@ -273,7 +265,7 @@ static int dm_hash_rename(const char *ol
 	/*
 	 * duplicate new.
 	 */
-	new_name = kstrdup(new);
+	new_name = kstrdup(new, GFP_KERNEL);
 	if (!new_name)
 		return -ENOMEM;
 
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c
--- a/drivers/md/dm-mpath.c
+++ b/drivers/md/dm-mpath.c
@@ -63,6 +63,7 @@ struct multipath {
 	unsigned nr_priority_groups;
 	struct list_head priority_groups;
 	unsigned pg_init_required;	/* pg_init needs calling? */
+	unsigned pg_init_in_progress;	/* Only one pg_init allowed at once */
 
 	unsigned nr_valid_paths;	/* Total number of usable paths */
 	struct pgpath *current_pgpath;
@@ -72,7 +73,7 @@ struct multipath {
 
 	unsigned queue_io;		/* Must we queue all I/O? */
 	unsigned queue_if_no_path;	/* Queue I/O if last path fails? */
-	unsigned suspended;		/* Has dm core suspended our I/O? */
+	unsigned saved_queue_if_no_path;/* Saved state during suspension */
 
 	struct work_struct process_queued_ios;
 	struct bio_list queued_ios;
@@ -304,11 +305,12 @@ static int map_io(struct multipath *m, s
 		m->queue_size--;
 
 	if ((pgpath && m->queue_io) ||
-	    (!pgpath && m->queue_if_no_path && !m->suspended)) {
+	    (!pgpath && m->queue_if_no_path)) {
 		/* Queue for the daemon to resubmit */
 		bio_list_add(&m->queued_ios, bio);
 		m->queue_size++;
-		if (m->pg_init_required || !m->queue_io)
+		if ((m->pg_init_required && !m->pg_init_in_progress) ||
+		    !m->queue_io)
 			queue_work(kmultipathd, &m->process_queued_ios);
 		pgpath = NULL;
 		r = 0;
@@ -333,8 +335,9 @@ static int queue_if_no_path(struct multi
 
 	spin_lock_irqsave(&m->lock, flags);
 
+	m->saved_queue_if_no_path = m->queue_if_no_path;
 	m->queue_if_no_path = queue_if_no_path;
-	if (!m->queue_if_no_path)
+	if (!m->queue_if_no_path && m->queue_size)
 		queue_work(kmultipathd, &m->process_queued_ios);
 
 	spin_unlock_irqrestore(&m->lock, flags);
@@ -379,25 +382,31 @@ static void process_queued_ios(void *dat
 {
 	struct multipath *m = (struct multipath *) data;
 	struct hw_handler *hwh = &m->hw_handler;
-	struct pgpath *pgpath;
-	unsigned init_required, must_queue = 0;
+	struct pgpath *pgpath = NULL;
+	unsigned init_required = 0, must_queue = 1;
 	unsigned long flags;
 
 	spin_lock_irqsave(&m->lock, flags);
 
+	if (!m->queue_size)
+		goto out;
+
 	if (!m->current_pgpath)
 		__choose_pgpath(m);
 
 	pgpath = m->current_pgpath;
 
-	if ((pgpath && m->queue_io) ||
-	    (!pgpath && m->queue_if_no_path && !m->suspended))
-		must_queue = 1;
+	if ((pgpath && !m->queue_io) ||
+	    (!pgpath && !m->queue_if_no_path))
+		must_queue = 0;
 
-	init_required = m->pg_init_required;
-	if (init_required)
+	if (m->pg_init_required && !m->pg_init_in_progress) {
 		m->pg_init_required = 0;
+		m->pg_init_in_progress = 1;
+		init_required = 1;
+	}
 
+out:
 	spin_unlock_irqrestore(&m->lock, flags);
 
 	if (init_required)
@@ -752,6 +761,8 @@ static int multipath_ctr(struct dm_targe
 static void multipath_dtr(struct dm_target *ti)
 {
 	struct multipath *m = (struct multipath *) ti->private;
+
+	flush_workqueue(kmultipathd);
 	free_multipath(m);
 }
 
@@ -765,6 +776,9 @@ static int multipath_map(struct dm_targe
 	struct mpath_io *mpio;
 	struct multipath *m = (struct multipath *) ti->private;
 
+	if (bio_barrier(bio))
+		return -EOPNOTSUPP;
+
 	mpio = mempool_alloc(m->mpio_pool, GFP_NOIO);
 	dm_bio_record(&mpio->details, bio);
 
@@ -837,7 +851,7 @@ static int reinstate_path(struct pgpath 
 	pgpath->path.is_active = 1;
 
 	m->current_pgpath = NULL;
-	if (!m->nr_valid_paths++)
+	if (!m->nr_valid_paths++ && m->queue_size)
 		queue_work(kmultipathd, &m->process_queued_ios);
 
 	queue_work(kmultipathd, &m->trigger_event);
@@ -963,12 +977,13 @@ void dm_pg_init_complete(struct path *pa
 		bypass_pg(m, pg, 1);
 
 	spin_lock_irqsave(&m->lock, flags);
-	if (!err_flags)
-		m->queue_io = 0;
-	else {
+	if (err_flags) {
 		m->current_pgpath = NULL;
 		m->current_pg = NULL;
-	}
+	} else if (!m->pg_init_required)
+		m->queue_io = 0;
+
+	m->pg_init_in_progress = 0;
 	queue_work(kmultipathd, &m->process_queued_ios);
 	spin_unlock_irqrestore(&m->lock, flags);
 }
@@ -988,9 +1003,12 @@ static int do_end_io(struct multipath *m
 	if ((error == -EWOULDBLOCK) && bio_rw_ahead(bio))
 		return error;
 
+	if (error == -EOPNOTSUPP)
+		return error;
+
 	spin_lock(&m->lock);
 	if (!m->nr_valid_paths) {
-		if (!m->queue_if_no_path || m->suspended) {
+		if (!m->queue_if_no_path) {
 			spin_unlock(&m->lock);
 			return -EIO;
 		} else {
@@ -1051,27 +1069,27 @@ static int multipath_end_io(struct dm_ta
 
 /*
  * Suspend can't complete until all the I/O is processed so if
- * the last path failed we will now error any queued I/O.
+ * the last path fails we must error any remaining I/O.
+ * Note that if the freeze_bdev fails while suspending, the
+ * queue_if_no_path state is lost - userspace should reset it.
  */
 static void multipath_presuspend(struct dm_target *ti)
 {
 	struct multipath *m = (struct multipath *) ti->private;
-	unsigned long flags;
 
-	spin_lock_irqsave(&m->lock, flags);
-	m->suspended = 1;
-	if (m->queue_if_no_path)
-		queue_work(kmultipathd, &m->process_queued_ios);
-	spin_unlock_irqrestore(&m->lock, flags);
+	queue_if_no_path(m, 0);
 }
 
+/*
+ * Restore the queue_if_no_path setting.
+ */
 static void multipath_resume(struct dm_target *ti)
 {
 	struct multipath *m = (struct multipath *) ti->private;
 	unsigned long flags;
 
 	spin_lock_irqsave(&m->lock, flags);
-	m->suspended = 0;
+	m->queue_if_no_path = m->saved_queue_if_no_path;
 	spin_unlock_irqrestore(&m->lock, flags);
 }
 
diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c
--- a/drivers/md/dm-raid1.c
+++ b/drivers/md/dm-raid1.c
@@ -1060,6 +1060,7 @@ static int mirror_ctr(struct dm_target *
 	}
 
 	ti->private = ms;
+ 	ti->split_io = ms->rh.region_size;
 
 	r = kcopyd_client_create(DM_IO_PAGES, &ms->kcopyd_client);
 	if (r) {
@@ -1229,7 +1230,7 @@ static int __init dm_mirror_init(void)
 	if (r)
 		return r;
 
-	_kmirrord_wq = create_workqueue("kmirrord");
+	_kmirrord_wq = create_singlethread_workqueue("kmirrord");
 	if (!_kmirrord_wq) {
 		DMERR("couldn't start kmirrord");
 		dm_dirty_log_exit();
diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c
--- a/drivers/md/dm-snap.c
+++ b/drivers/md/dm-snap.c
@@ -777,7 +777,7 @@ static int snapshot_map(struct dm_target
 
 	/* Full snapshots are not usable */
 	if (!s->valid)
-		return -1;
+		return -EIO;
 
 	/*
 	 * Write to snapshot - higher level takes care of RW/RO
@@ -931,6 +931,10 @@ static int __origin_write(struct list_he
 		if (!snap->valid)
 			continue;
 
+		/* Nothing to do if writing beyond end of snapshot */
+		if (bio->bi_sector >= dm_table_get_size(snap->table))
+			continue;
+
 		down_write(&snap->lock);
 
 		/*
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c
--- a/drivers/md/dm-table.c
+++ b/drivers/md/dm-table.c
@@ -869,11 +869,17 @@ static void suspend_targets(struct dm_ta
 
 void dm_table_presuspend_targets(struct dm_table *t)
 {
+	if (!t)
+		return;
+
 	return suspend_targets(t, 0);
 }
 
 void dm_table_postsuspend_targets(struct dm_table *t)
 {
+	if (!t)
+		return;
+
 	return suspend_targets(t, 1);
 }
 
@@ -943,6 +949,7 @@ EXPORT_SYMBOL(dm_vcalloc);
 EXPORT_SYMBOL(dm_get_device);
 EXPORT_SYMBOL(dm_put_device);
 EXPORT_SYMBOL(dm_table_event);
+EXPORT_SYMBOL(dm_table_get_size);
 EXPORT_SYMBOL(dm_table_get_mode);
 EXPORT_SYMBOL(dm_table_put);
 EXPORT_SYMBOL(dm_table_get);
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -55,10 +55,10 @@ union map_info *dm_get_mapinfo(struct bi
  */
 #define DMF_BLOCK_IO 0
 #define DMF_SUSPENDED 1
-#define DMF_FS_LOCKED 2
 
 struct mapped_device {
-	struct rw_semaphore lock;
+	struct rw_semaphore io_lock;
+	struct semaphore suspend_lock;
 	rwlock_t map_lock;
 	atomic_t holders;
 
@@ -248,16 +248,16 @@ static inline void free_tio(struct mappe
  */
 static int queue_io(struct mapped_device *md, struct bio *bio)
 {
-	down_write(&md->lock);
+	down_write(&md->io_lock);
 
 	if (!test_bit(DMF_BLOCK_IO, &md->flags)) {
-		up_write(&md->lock);
+		up_write(&md->io_lock);
 		return 1;
 	}
 
 	bio_list_add(&md->deferred, bio);
 
-	up_write(&md->lock);
+	up_write(&md->io_lock);
 	return 0;		/* deferred successfully */
 }
 
@@ -384,7 +384,7 @@ static void __map_bio(struct dm_target *
 		/* error the io and bail out */
 		struct dm_io *io = tio->io;
 		free_tio(tio->io->md, tio);
-		dec_pending(io, -EIO);
+		dec_pending(io, r);
 		bio_put(clone);
 	}
 }
@@ -568,14 +568,14 @@ static int dm_request(request_queue_t *q
 	int r;
 	struct mapped_device *md = q->queuedata;
 
-	down_read(&md->lock);
+	down_read(&md->io_lock);
 
 	/*
 	 * If we're suspended we have to queue
 	 * this io for later.
 	 */
 	while (test_bit(DMF_BLOCK_IO, &md->flags)) {
-		up_read(&md->lock);
+		up_read(&md->io_lock);
 
 		if (bio_rw(bio) == READA) {
 			bio_io_error(bio, bio->bi_size);
@@ -594,11 +594,11 @@ static int dm_request(request_queue_t *q
 		 * We're in a while loop, because someone could suspend
 		 * before we get to the following read lock.
 		 */
-		down_read(&md->lock);
+		down_read(&md->io_lock);
 	}
 
 	__split_bio(md, bio);
-	up_read(&md->lock);
+	up_read(&md->io_lock);
 	return 0;
 }
 
@@ -610,7 +610,7 @@ static int dm_flush_all(request_queue_t 
 	int ret = -ENXIO;
 
 	if (map) {
-		ret = dm_table_flush_all(md->map);
+		ret = dm_table_flush_all(map);
 		dm_table_put(map);
 	}
 
@@ -747,7 +747,8 @@ static struct mapped_device *alloc_dev(u
 		goto bad1;
 
 	memset(md, 0, sizeof(*md));
-	init_rwsem(&md->lock);
+	init_rwsem(&md->io_lock);
+	init_MUTEX(&md->suspend_lock);
 	rwlock_init(&md->map_lock);
 	atomic_set(&md->holders, 1);
 	atomic_set(&md->event_nr, 0);
@@ -825,18 +826,13 @@ static void event_callback(void *context
 	wake_up(&md->eventq);
 }
 
-static void __set_size(struct gendisk *disk, sector_t size)
+static void __set_size(struct mapped_device *md, sector_t size)
 {
-	struct block_device *bdev;
+	set_capacity(md->disk, size);
 
-	set_capacity(disk, size);
-	bdev = bdget_disk(disk, 0);
-	if (bdev) {
-		down(&bdev->bd_inode->i_sem);
-		i_size_write(bdev->bd_inode, (loff_t)size << SECTOR_SHIFT);
-		up(&bdev->bd_inode->i_sem);
-		bdput(bdev);
-	}
+	down(&md->frozen_bdev->bd_inode->i_sem);
+	i_size_write(md->frozen_bdev->bd_inode, (loff_t)size << SECTOR_SHIFT);
+	up(&md->frozen_bdev->bd_inode->i_sem);
 }
 
 static int __bind(struct mapped_device *md, struct dm_table *t)
@@ -845,17 +841,18 @@ static int __bind(struct mapped_device *
 	sector_t size;
 
 	size = dm_table_get_size(t);
-	__set_size(md->disk, size);
+	__set_size(md, size);
 	if (size == 0)
 		return 0;
 
+	dm_table_get(t);
+	dm_table_event_callback(t, event_callback, md);
+
 	write_lock(&md->map_lock);
 	md->map = t;
+	dm_table_set_restrictions(t, q);
 	write_unlock(&md->map_lock);
 
-	dm_table_get(t);
-	dm_table_event_callback(md->map, event_callback, md);
-	dm_table_set_restrictions(t, q);
 	return 0;
 }
 
@@ -935,7 +932,7 @@ void dm_put(struct mapped_device *md)
 	struct dm_table *map = dm_get_table(md);
 
 	if (atomic_dec_and_test(&md->holders)) {
-		if (!test_bit(DMF_SUSPENDED, &md->flags) && map) {
+		if (!dm_suspended(md)) {
 			dm_table_presuspend_targets(map);
 			dm_table_postsuspend_targets(map);
 		}
@@ -966,39 +963,33 @@ static void __flush_deferred_io(struct m
  */
 int dm_swap_table(struct mapped_device *md, struct dm_table *table)
 {
-	int r;
+	int r = -EINVAL;
 
-	down_write(&md->lock);
+	down(&md->suspend_lock);
 
 	/* device must be suspended */
-	if (!test_bit(DMF_SUSPENDED, &md->flags)) {
-		up_write(&md->lock);
-		return -EPERM;
-	}
+	if (!dm_suspended(md))
+		goto out;
 
 	__unbind(md);
 	r = __bind(md, table);
-	if (r)
-		return r;
 
-	up_write(&md->lock);
-	return 0;
+out:
+	up(&md->suspend_lock);
+	return r;
 }
 
 /*
  * Functions to lock and unlock any filesystem running on the
  * device.
  */
-static int __lock_fs(struct mapped_device *md)
+static int lock_fs(struct mapped_device *md)
 {
-	int error = -ENOMEM;
-
-	if (test_and_set_bit(DMF_FS_LOCKED, &md->flags))
-		return 0;
+	int r = -ENOMEM;
 
 	md->frozen_bdev = bdget_disk(md->disk, 0);
 	if (!md->frozen_bdev) {
-		DMWARN("bdget failed in __lock_fs");
+		DMWARN("bdget failed in lock_fs");
 		goto out;
 	}
 
@@ -1006,13 +997,13 @@ static int __lock_fs(struct mapped_devic
 
 	md->frozen_sb = freeze_bdev(md->frozen_bdev);
 	if (IS_ERR(md->frozen_sb)) {
-		error = PTR_ERR(md->frozen_sb);
+		r = PTR_ERR(md->frozen_sb);
 		goto out_bdput;
 	}
 
 	/* don't bdput right now, we don't want the bdev
 	 * to go away while it is locked.  We'll bdput
-	 * in __unlock_fs
+	 * in unlock_fs
 	 */
 	return 0;
 
@@ -1021,15 +1012,11 @@ out_bdput:
 	md->frozen_sb = NULL;
 	md->frozen_bdev = NULL;
 out:
-	clear_bit(DMF_FS_LOCKED, &md->flags);
-	return error;
+	return r;
 }
 
-static void __unlock_fs(struct mapped_device *md)
+static void unlock_fs(struct mapped_device *md)
 {
-	if (!test_and_clear_bit(DMF_FS_LOCKED, &md->flags))
-		return;
-
 	thaw_bdev(md->frozen_bdev, md->frozen_sb);
 	bdput(md->frozen_bdev);
 
@@ -1046,47 +1033,37 @@ static void __unlock_fs(struct mapped_de
  */
 int dm_suspend(struct mapped_device *md)
 {
-	struct dm_table *map;
+	struct dm_table *map = NULL;
 	DECLARE_WAITQUEUE(wait, current);
-	int error = -EINVAL;
+	int r = -EINVAL;
 
-	/* Flush I/O to the device. */
-	down_read(&md->lock);
-	if (test_bit(DMF_BLOCK_IO, &md->flags))
-		goto out_read_unlock;
+	down(&md->suspend_lock);
 
-	error = __lock_fs(md);
-	if (error)
-		goto out_read_unlock;
+	if (dm_suspended(md))
+		goto out;
 
 	map = dm_get_table(md);
-	if (map)
-		dm_table_presuspend_targets(map);
 
-	up_read(&md->lock);
+	/* This does not get reverted if there's an error later. */
+	dm_table_presuspend_targets(map);
+
+	/* Flush I/O to the device. */
+	r = lock_fs(md);
+	if (r)
+		goto out;
 
 	/*
 	 * First we set the BLOCK_IO flag so no more ios will be mapped.
-	 *
-	 * If the flag is already set we know another thread is trying to
-	 * suspend as well, so we leave the fs locked for this thread.
 	 */
-	error = -EINVAL;
-	down_write(&md->lock);
-	if (test_and_set_bit(DMF_BLOCK_IO, &md->flags)) {
-		if (map)
-			dm_table_put(map);
-		goto out_write_unlock;
-	}
+	down_write(&md->io_lock);
+	set_bit(DMF_BLOCK_IO, &md->flags);
 
 	add_wait_queue(&md->wait, &wait);
-	up_write(&md->lock);
+	up_write(&md->io_lock);
 
 	/* unplug */
-	if (map) {
+	if (map)
 		dm_table_unplug_all(map);
-		dm_table_put(map);
-	}
 
 	/*
 	 * Then we wait for the already mapped ios to
@@ -1102,63 +1079,67 @@ int dm_suspend(struct mapped_device *md)
 	}
 	set_current_state(TASK_RUNNING);
 
-	down_write(&md->lock);
+	down_write(&md->io_lock);
 	remove_wait_queue(&md->wait, &wait);
 
 	/* were we interrupted ? */
-	error = -EINTR;
-	if (atomic_read(&md->pending))
-		goto out_unfreeze;
+	r = -EINTR;
+	if (atomic_read(&md->pending)) {
+		up_write(&md->io_lock);
+		unlock_fs(md);
+		clear_bit(DMF_BLOCK_IO, &md->flags);
+		goto out;
+	}
+	up_write(&md->io_lock);
 
-	set_bit(DMF_SUSPENDED, &md->flags);
+	dm_table_postsuspend_targets(map);
 
-	map = dm_get_table(md);
-	if (map)
-		dm_table_postsuspend_targets(map);
-	dm_table_put(map);
-	up_write(&md->lock);
+	set_bit(DMF_SUSPENDED, &md->flags);
 
-	return 0;
+	r = 0;
 
-out_unfreeze:
-	/* FIXME Undo dm_table_presuspend_targets */
-	__unlock_fs(md);
-	clear_bit(DMF_BLOCK_IO, &md->flags);
-out_write_unlock:
-	up_write(&md->lock);
-	return error;
-
-out_read_unlock:
-	up_read(&md->lock);
-	return error;
+out:
+	dm_table_put(map);
+	up(&md->suspend_lock);
+	return r;
 }
 
 int dm_resume(struct mapped_device *md)
 {
+	int r = -EINVAL;
 	struct bio *def;
-	struct dm_table *map = dm_get_table(md);
+	struct dm_table *map = NULL;
 
-	down_write(&md->lock);
-	if (!map ||
-	    !test_bit(DMF_SUSPENDED, &md->flags) ||
-	    !dm_table_get_size(map)) {
-		up_write(&md->lock);
-		dm_table_put(map);
-		return -EINVAL;
-	}
+	down(&md->suspend_lock);
+	if (!dm_suspended(md))
+		goto out;
+
+	map = dm_get_table(md);
+	if (!map || !dm_table_get_size(map))
+		goto out;
 
 	dm_table_resume_targets(map);
-	clear_bit(DMF_SUSPENDED, &md->flags);
+
+	down_write(&md->io_lock);
 	clear_bit(DMF_BLOCK_IO, &md->flags);
 
 	def = bio_list_get(&md->deferred);
 	__flush_deferred_io(md, def);
-	up_write(&md->lock);
-	__unlock_fs(md);
+	up_write(&md->io_lock);
+
+	unlock_fs(md);
+
+	clear_bit(DMF_SUSPENDED, &md->flags);
+
 	dm_table_unplug_all(map);
+
+	r = 0;
+
+out:
 	dm_table_put(map);
+	up(&md->suspend_lock);
 
-	return 0;
+	return r;
 }
 
 /*-----------------------------------------------------------------
diff --git a/drivers/md/linear.c b/drivers/md/linear.c
--- a/drivers/md/linear.c
+++ b/drivers/md/linear.c
@@ -217,8 +217,7 @@ static int linear_run (mddev_t *mddev)
 	return 0;
 
 out:
-	if (conf)
-		kfree(conf);
+	kfree(conf);
 	return 1;
 }
 
diff --git a/drivers/md/md.c b/drivers/md/md.c
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -19,6 +19,9 @@
 
      Neil Brown <neilb@cse.unsw.edu.au>.
 
+   - persistent bitmap code
+     Copyright (C) 2003-2004, Paul Clements, SteelEye Technology, 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, or (at your option)
@@ -33,6 +36,7 @@
 #include <linux/config.h>
 #include <linux/linkage.h>
 #include <linux/raid/md.h>
+#include <linux/raid/bitmap.h>
 #include <linux/sysctl.h>
 #include <linux/devfs_fs_kernel.h>
 #include <linux/buffer_head.h> /* for invalidate_bdev */
@@ -40,6 +44,8 @@
 
 #include <linux/init.h>
 
+#include <linux/file.h>
+
 #ifdef CONFIG_KMOD
 #include <linux/kmod.h>
 #endif
@@ -189,8 +195,7 @@ static mddev_t * mddev_find(dev_t unit)
 		if (mddev->unit == unit) {
 			mddev_get(mddev);
 			spin_unlock(&all_mddevs_lock);
-			if (new)
-				kfree(new);
+			kfree(new);
 			return mddev;
 		}
 
@@ -218,6 +223,8 @@ static mddev_t * mddev_find(dev_t unit)
 	INIT_LIST_HEAD(&new->all_mddevs);
 	init_timer(&new->safemode_timer);
 	atomic_set(&new->active, 1);
+	spin_lock_init(&new->write_lock);
+	init_waitqueue_head(&new->sb_wait);
 
 	new->queue = blk_alloc_queue(GFP_KERNEL);
 	if (!new->queue) {
@@ -249,8 +256,7 @@ static inline void mddev_unlock(mddev_t 
 {
 	up(&mddev->reconfig_sem);
 
-	if (mddev->thread)
-		md_wakeup_thread(mddev->thread);
+	md_wakeup_thread(mddev->thread);
 }
 
 mdk_rdev_t * find_rdev_nr(mddev_t *mddev, int nr)
@@ -277,7 +283,7 @@ static mdk_rdev_t * find_rdev(mddev_t * 
 	return NULL;
 }
 
-inline static sector_t calc_dev_sboffset(struct block_device *bdev)
+static inline sector_t calc_dev_sboffset(struct block_device *bdev)
 {
 	sector_t size = bdev->bd_inode->i_size >> BLOCK_SIZE_BITS;
 	return MD_NEW_SIZE_BLOCKS(size);
@@ -320,6 +326,41 @@ static void free_disk_sb(mdk_rdev_t * rd
 }
 
 
+static int super_written(struct bio *bio, unsigned int bytes_done, int error)
+{
+	mdk_rdev_t *rdev = bio->bi_private;
+	if (bio->bi_size)
+		return 1;
+
+	if (error || !test_bit(BIO_UPTODATE, &bio->bi_flags))
+		md_error(rdev->mddev, rdev);
+
+	if (atomic_dec_and_test(&rdev->mddev->pending_writes))
+		wake_up(&rdev->mddev->sb_wait);
+	bio_put(bio);
+	return 0;
+}
+
+void md_super_write(mddev_t *mddev, mdk_rdev_t *rdev,
+		   sector_t sector, int size, struct page *page)
+{
+	/* write first size bytes of page to sector of rdev
+	 * Increment mddev->pending_writes before returning
+	 * and decrement it on completion, waking up sb_wait
+	 * if zero is reached.
+	 * If an error occurred, call md_error
+	 */
+	struct bio *bio = bio_alloc(GFP_NOIO, 1);
+
+	bio->bi_bdev = rdev->bdev;
+	bio->bi_sector = sector;
+	bio_add_page(bio, page, size, 0);
+	bio->bi_private = rdev;
+	bio->bi_end_io = super_written;
+	atomic_inc(&mddev->pending_writes);
+	submit_bio((1<<BIO_RW)|(1<<BIO_RW_SYNC), bio);
+}
+
 static int bi_complete(struct bio *bio, unsigned int bytes_done, int error)
 {
 	if (bio->bi_size)
@@ -329,7 +370,7 @@ static int bi_complete(struct bio *bio, 
 	return 0;
 }
 
-static int sync_page_io(struct block_device *bdev, sector_t sector, int size,
+int sync_page_io(struct block_device *bdev, sector_t sector, int size,
 		   struct page *page, int rw)
 {
 	struct bio *bio = bio_alloc(GFP_NOIO, 1);
@@ -416,11 +457,8 @@ static int sb_equal(mdp_super_t *sb1, md
 		ret = 1;
 
 abort:
-	if (tmp1)
-		kfree(tmp1);
-	if (tmp2)
-		kfree(tmp2);
-
+	kfree(tmp1);
+	kfree(tmp2);
 	return ret;
 }
 
@@ -569,6 +607,8 @@ static int super_90_validate(mddev_t *md
 	mdp_disk_t *desc;
 	mdp_super_t *sb = (mdp_super_t *)page_address(rdev->sb_page);
 
+	rdev->raid_disk = -1;
+	rdev->in_sync = 0;
 	if (mddev->raid_disks == 0) {
 		mddev->major_version = 0;
 		mddev->minor_version = sb->minor_version;
@@ -582,6 +622,7 @@ static int super_90_validate(mddev_t *md
 		mddev->raid_disks = sb->raid_disks;
 		mddev->size = sb->size;
 		mddev->events = md_event(sb);
+		mddev->bitmap_offset = 0;
 
 		if (sb->state & (1<<MD_SB_CLEAN))
 			mddev->recovery_cp = MaxSector;
@@ -599,16 +640,35 @@ static int super_90_validate(mddev_t *md
 		memcpy(mddev->uuid+12,&sb->set_uuid3, 4);
 
 		mddev->max_disks = MD_SB_DISKS;
-	} else {
-		__u64 ev1;
-		ev1 = md_event(sb);
+
+		if (sb->state & (1<<MD_SB_BITMAP_PRESENT) &&
+		    mddev->bitmap_file == NULL) {
+			if (mddev->level != 1) {
+				/* FIXME use a better test */
+				printk(KERN_WARNING "md: bitmaps only support for raid1\n");
+				return -EINVAL;
+			}
+			mddev->bitmap_offset = (MD_SB_BYTES >> 9);
+		}
+
+	} else if (mddev->pers == NULL) {
+		/* Insist on good event counter while assembling */
+		__u64 ev1 = md_event(sb);
 		++ev1;
 		if (ev1 < mddev->events) 
 			return -EINVAL;
-	}
+	} else if (mddev->bitmap) {
+		/* if adding to array with a bitmap, then we can accept an
+		 * older device ... but not too old.
+		 */
+		__u64 ev1 = md_event(sb);
+		if (ev1 < mddev->bitmap->events_cleared)
+			return 0;
+	} else /* just a hot-add of a new device, leave raid_disk at -1 */
+		return 0;
+
 	if (mddev->level != LEVEL_MULTIPATH) {
-		rdev->raid_disk = -1;
-		rdev->in_sync = rdev->faulty = 0;
+		rdev->faulty = 0;
 		desc = sb->disks + rdev->desc_nr;
 
 		if (desc->state & (1<<MD_DISK_FAULTY))
@@ -618,7 +678,8 @@ static int super_90_validate(mddev_t *md
 			rdev->in_sync = 1;
 			rdev->raid_disk = desc->raid_disk;
 		}
-	}
+	} else /* MULTIPATH are always insync */
+		rdev->in_sync = 1;
 	return 0;
 }
 
@@ -683,6 +744,9 @@ static void super_90_sync(mddev_t *mddev
 	sb->layout = mddev->layout;
 	sb->chunk_size = mddev->chunk_size;
 
+	if (mddev->bitmap && mddev->bitmap_file == NULL)
+		sb->state |= (1<<MD_SB_BITMAP_PRESENT);
+
 	sb->disks[0].state = (1<<MD_DISK_REMOVED);
 	ITERATE_RDEV(mddev,rdev2,tmp) {
 		mdp_disk_t *d;
@@ -780,7 +844,7 @@ static int super_1_load(mdk_rdev_t *rdev
 	case 0:
 		sb_offset = rdev->bdev->bd_inode->i_size >> 9;
 		sb_offset -= 8*2;
-		sb_offset &= ~(4*2-1);
+		sb_offset &= ~(sector_t)(4*2-1);
 		/* convert from sectors to K */
 		sb_offset /= 2;
 		break;
@@ -860,6 +924,8 @@ static int super_1_validate(mddev_t *mdd
 {
 	struct mdp_superblock_1 *sb = (struct mdp_superblock_1*)page_address(rdev->sb_page);
 
+	rdev->raid_disk = -1;
+	rdev->in_sync = 0;
 	if (mddev->raid_disks == 0) {
 		mddev->major_version = 1;
 		mddev->patch_version = 0;
@@ -872,18 +938,36 @@ static int super_1_validate(mddev_t *mdd
 		mddev->raid_disks = le32_to_cpu(sb->raid_disks);
 		mddev->size = le64_to_cpu(sb->size)/2;
 		mddev->events = le64_to_cpu(sb->events);
+		mddev->bitmap_offset = 0;
 		
 		mddev->recovery_cp = le64_to_cpu(sb->resync_offset);
 		memcpy(mddev->uuid, sb->set_uuid, 16);
 
 		mddev->max_disks =  (4096-256)/2;
-	} else {
-		__u64 ev1;
-		ev1 = le64_to_cpu(sb->events);
+
+		if ((le32_to_cpu(sb->feature_map) & 1) &&
+		    mddev->bitmap_file == NULL ) {
+			if (mddev->level != 1) {
+				printk(KERN_WARNING "md: bitmaps only supported for raid1\n");
+				return -EINVAL;
+			}
+			mddev->bitmap_offset = (__s32)le32_to_cpu(sb->bitmap_offset);
+		}
+	} else if (mddev->pers == NULL) {
+		/* Insist of good event counter while assembling */
+		__u64 ev1 = le64_to_cpu(sb->events);
 		++ev1;
 		if (ev1 < mddev->events)
 			return -EINVAL;
-	}
+	} else if (mddev->bitmap) {
+		/* If adding to array with a bitmap, then we can accept an
+		 * older device, but not too old.
+		 */
+		__u64 ev1 = le64_to_cpu(sb->events);
+		if (ev1 < mddev->bitmap->events_cleared)
+			return 0;
+	} else /* just a hot-add of a new device, leave raid_disk at -1 */
+		return 0;
 
 	if (mddev->level != LEVEL_MULTIPATH) {
 		int role;
@@ -891,14 +975,10 @@ static int super_1_validate(mddev_t *mdd
 		role = le16_to_cpu(sb->dev_roles[rdev->desc_nr]);
 		switch(role) {
 		case 0xffff: /* spare */
-			rdev->in_sync = 0;
 			rdev->faulty = 0;
-			rdev->raid_disk = -1;
 			break;
 		case 0xfffe: /* faulty */
-			rdev->in_sync = 0;
 			rdev->faulty = 1;
-			rdev->raid_disk = -1;
 			break;
 		default:
 			rdev->in_sync = 1;
@@ -906,7 +986,9 @@ static int super_1_validate(mddev_t *mdd
 			rdev->raid_disk = role;
 			break;
 		}
-	}
+	} else /* MULTIPATH are always insync */
+		rdev->in_sync = 1;
+
 	return 0;
 }
 
@@ -933,6 +1015,11 @@ static void super_1_sync(mddev_t *mddev,
 	else
 		sb->resync_offset = cpu_to_le64(0);
 
+	if (mddev->bitmap && mddev->bitmap_file == NULL) {
+		sb->bitmap_offset = cpu_to_le32((__u32)mddev->bitmap_offset);
+		sb->feature_map = cpu_to_le32(1);
+	}
+
 	max_dev = 0;
 	ITERATE_RDEV(mddev,rdev2,tmp)
 		if (rdev2->desc_nr+1 > max_dev)
@@ -1196,8 +1283,11 @@ void md_print_devices(void)
 	printk("md:	* <COMPLETE RAID STATE PRINTOUT> *\n");
 	printk("md:	**********************************\n");
 	ITERATE_MDDEV(mddev,tmp) {
-		printk("%s: ", mdname(mddev));
 
+		if (mddev->bitmap)
+			bitmap_print_sb(mddev->bitmap);
+		else
+			printk("%s: ", mdname(mddev));
 		ITERATE_RDEV(mddev,rdev,tmp2)
 			printk("<%s>", bdevname(rdev->bdev,b));
 		printk("\n");
@@ -1210,30 +1300,6 @@ void md_print_devices(void)
 }
 
 
-static int write_disk_sb(mdk_rdev_t * rdev)
-{
-	char b[BDEVNAME_SIZE];
-	if (!rdev->sb_loaded) {
-		MD_BUG();
-		return 1;
-	}
-	if (rdev->faulty) {
-		MD_BUG();
-		return 1;
-	}
-
-	dprintk(KERN_INFO "(write) %s's sb offset: %llu\n",
-		bdevname(rdev->bdev,b),
-	       (unsigned long long)rdev->sb_offset);
-  
-	if (sync_page_io(rdev->bdev, rdev->sb_offset<<1, MD_SB_BYTES, rdev->sb_page, WRITE))
-		return 0;
-
-	printk("md: write_disk_sb failed for device %s\n", 
-		bdevname(rdev->bdev,b));
-	return 1;
-}
-
 static void sync_sbs(mddev_t * mddev)
 {
 	mdk_rdev_t *rdev;
@@ -1248,12 +1314,14 @@ static void sync_sbs(mddev_t * mddev)
 
 static void md_update_sb(mddev_t * mddev)
 {
-	int err, count = 100;
+	int err;
 	struct list_head *tmp;
 	mdk_rdev_t *rdev;
+	int sync_req;
 
-	mddev->sb_dirty = 0;
 repeat:
+	spin_lock(&mddev->write_lock);
+	sync_req = mddev->in_sync;
 	mddev->utime = get_seconds();
 	mddev->events ++;
 
@@ -1266,20 +1334,26 @@ repeat:
 		MD_BUG();
 		mddev->events --;
 	}
+	mddev->sb_dirty = 2;
 	sync_sbs(mddev);
 
 	/*
 	 * do not write anything to disk if using
 	 * nonpersistent superblocks
 	 */
-	if (!mddev->persistent)
+	if (!mddev->persistent) {
+		mddev->sb_dirty = 0;
+		spin_unlock(&mddev->write_lock);
+		wake_up(&mddev->sb_wait);
 		return;
+	}
+	spin_unlock(&mddev->write_lock);
 
 	dprintk(KERN_INFO 
 		"md: updating %s RAID superblock on device (in sync %d)\n",
 		mdname(mddev),mddev->in_sync);
 
-	err = 0;
+	err = bitmap_update_sb(mddev->bitmap);
 	ITERATE_RDEV(mddev,rdev,tmp) {
 		char b[BDEVNAME_SIZE];
 		dprintk(KERN_INFO "md: ");
@@ -1288,22 +1362,32 @@ repeat:
 
 		dprintk("%s ", bdevname(rdev->bdev,b));
 		if (!rdev->faulty) {
-			err += write_disk_sb(rdev);
+			md_super_write(mddev,rdev,
+				       rdev->sb_offset<<1, MD_SB_BYTES,
+				       rdev->sb_page);
+			dprintk(KERN_INFO "(write) %s's sb offset: %llu\n",
+				bdevname(rdev->bdev,b),
+				(unsigned long long)rdev->sb_offset);
+
 		} else
 			dprintk(")\n");
-		if (!err && mddev->level == LEVEL_MULTIPATH)
+		if (mddev->level == LEVEL_MULTIPATH)
 			/* only need to write one superblock... */
 			break;
 	}
-	if (err) {
-		if (--count) {
-			printk(KERN_ERR "md: errors occurred during superblock"
-				" update, repeating\n");
-			goto repeat;
-		}
-		printk(KERN_ERR \
-			"md: excessive errors occurred during superblock update, exiting\n");
+	wait_event(mddev->sb_wait, atomic_read(&mddev->pending_writes)==0);
+	/* if there was a failure, sb_dirty was set to 1, and we re-write super */
+
+	spin_lock(&mddev->write_lock);
+	if (mddev->in_sync != sync_req|| mddev->sb_dirty == 1) {
+		/* have to write it out again */
+		spin_unlock(&mddev->write_lock);
+		goto repeat;
 	}
+	mddev->sb_dirty = 0;
+	spin_unlock(&mddev->write_lock);
+	wake_up(&mddev->sb_wait);
+
 }
 
 /*
@@ -1605,14 +1689,22 @@ static int do_md_run(mddev_t * mddev)
 	mddev->pers = pers[pnum];
 	spin_unlock(&pers_lock);
 
+	mddev->recovery = 0;
 	mddev->resync_max_sectors = mddev->size << 1; /* may be over-ridden by personality */
 
-	err = mddev->pers->run(mddev);
+	/* before we start the array running, initialise the bitmap */
+	err = bitmap_create(mddev);
+	if (err)
+		printk(KERN_ERR "%s: failed to create bitmap (%d)\n",
+			mdname(mddev), err);
+	else
+		err = mddev->pers->run(mddev);
 	if (err) {
 		printk(KERN_ERR "md: pers->run() failed ...\n");
 		module_put(mddev->pers->owner);
 		mddev->pers = NULL;
-		return -EINVAL;
+		bitmap_destroy(mddev);
+		return err;
 	}
  	atomic_set(&mddev->writes_pending,0);
 	mddev->safemode = 0;
@@ -1622,6 +1714,7 @@ static int do_md_run(mddev_t * mddev)
 	mddev->in_sync = 1;
 	
 	set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
+	md_wakeup_thread(mddev->thread);
 	
 	if (mddev->sb_dirty)
 		md_update_sb(mddev);
@@ -1708,6 +1801,8 @@ static int do_md_stop(mddev_t * mddev, i
 				goto out;
 			mddev->ro = 1;
 		} else {
+			bitmap_flush(mddev);
+			wait_event(mddev->sb_wait, atomic_read(&mddev->pending_writes)==0);
 			if (mddev->ro)
 				set_disk_ro(disk, 0);
 			blk_queue_make_request(mddev->queue, md_fail_request);
@@ -1725,6 +1820,15 @@ static int do_md_stop(mddev_t * mddev, i
 		if (ro)
 			set_disk_ro(disk, 1);
 	}
+
+	bitmap_destroy(mddev);
+	if (mddev->bitmap_file) {
+		atomic_set(&mddev->bitmap_file->f_dentry->d_inode->i_writecount, 1);
+		fput(mddev->bitmap_file);
+		mddev->bitmap_file = NULL;
+	}
+	mddev->bitmap_offset = 0;
+
 	/*
 	 * Free resources if final stop
 	 */
@@ -1983,6 +2087,42 @@ static int get_array_info(mddev_t * mdde
 	return 0;
 }
 
+static int get_bitmap_file(mddev_t * mddev, void * arg)
+{
+	mdu_bitmap_file_t *file = NULL; /* too big for stack allocation */
+	char *ptr, *buf = NULL;
+	int err = -ENOMEM;
+
+	file = kmalloc(sizeof(*file), GFP_KERNEL);
+	if (!file)
+		goto out;
+
+	/* bitmap disabled, zero the first byte and copy out */
+	if (!mddev->bitmap || !mddev->bitmap->file) {
+		file->pathname[0] = '\0';
+		goto copy_out;
+	}
+
+	buf = kmalloc(sizeof(file->pathname), GFP_KERNEL);
+	if (!buf)
+		goto out;
+
+	ptr = file_path(mddev->bitmap->file, buf, sizeof(file->pathname));
+	if (!ptr)
+		goto out;
+
+	strcpy(file->pathname, ptr);
+
+copy_out:
+	err = 0;
+	if (copy_to_user(arg, file, sizeof(*file)))
+		err = -EFAULT;
+out:
+	kfree(buf);
+	kfree(file);
+	return err;
+}
+
 static int get_disk_info(mddev_t * mddev, void __user * arg)
 {
 	mdu_disk_info_t info;
@@ -2078,13 +2218,26 @@ static int add_new_disk(mddev_t * mddev,
 				PTR_ERR(rdev));
 			return PTR_ERR(rdev);
 		}
+		/* set save_raid_disk if appropriate */
+		if (!mddev->persistent) {
+			if (info->state & (1<<MD_DISK_SYNC)  &&
+			    info->raid_disk < mddev->raid_disks)
+				rdev->raid_disk = info->raid_disk;
+			else
+				rdev->raid_disk = -1;
+		} else
+			super_types[mddev->major_version].
+				validate_super(mddev, rdev);
+		rdev->saved_raid_disk = rdev->raid_disk;
+
 		rdev->in_sync = 0; /* just to be sure */
 		rdev->raid_disk = -1;
 		err = bind_rdev_to_array(rdev, mddev);
 		if (err)
 			export_rdev(rdev);
-		if (mddev->thread)
-			md_wakeup_thread(mddev->thread);
+
+		set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
+		md_wakeup_thread(mddev->thread);
 		return err;
 	}
 
@@ -2256,6 +2409,49 @@ abort_export:
 	return err;
 }
 
+/* similar to deny_write_access, but accounts for our holding a reference
+ * to the file ourselves */
+static int deny_bitmap_write_access(struct file * file)
+{
+	struct inode *inode = file->f_mapping->host;
+
+	spin_lock(&inode->i_lock);
+	if (atomic_read(&inode->i_writecount) > 1) {
+		spin_unlock(&inode->i_lock);
+		return -ETXTBSY;
+	}
+	atomic_set(&inode->i_writecount, -1);
+	spin_unlock(&inode->i_lock);
+
+	return 0;
+}
+
+static int set_bitmap_file(mddev_t *mddev, int fd)
+{
+	int err;
+
+	if (mddev->pers)
+		return -EBUSY;
+
+	mddev->bitmap_file = fget(fd);
+
+	if (mddev->bitmap_file == NULL) {
+		printk(KERN_ERR "%s: error: failed to get bitmap file\n",
+			mdname(mddev));
+		return -EBADF;
+	}
+
+	err = deny_bitmap_write_access(mddev->bitmap_file);
+	if (err) {
+		printk(KERN_ERR "%s: error: bitmap file is already in use\n",
+			mdname(mddev));
+		fput(mddev->bitmap_file);
+		mddev->bitmap_file = NULL;
+	} else
+		mddev->bitmap_offset = 0; /* file overrides offset */
+	return err;
+}
+
 /*
  * set_array_info is used two different ways
  * The original usage is when creating a new array.
@@ -2567,8 +2763,10 @@ static int md_ioctl(struct inode *inode,
 	/*
 	 * Commands querying/configuring an existing array:
 	 */
-	/* if we are initialised yet, only ADD_NEW_DISK or STOP_ARRAY is allowed */
-	if (!mddev->raid_disks && cmd != ADD_NEW_DISK && cmd != STOP_ARRAY && cmd != RUN_ARRAY) {
+	/* if we are not initialised yet, only ADD_NEW_DISK, STOP_ARRAY,
+	 * RUN_ARRAY, and SET_BITMAP_FILE are allowed */
+	if (!mddev->raid_disks && cmd != ADD_NEW_DISK && cmd != STOP_ARRAY
+			&& cmd != RUN_ARRAY && cmd != SET_BITMAP_FILE) {
 		err = -ENODEV;
 		goto abort_unlock;
 	}
@@ -2582,6 +2780,10 @@ static int md_ioctl(struct inode *inode,
 			err = get_array_info(mddev, argp);
 			goto done_unlock;
 
+		case GET_BITMAP_FILE:
+			err = get_bitmap_file(mddev, (void *)arg);
+			goto done_unlock;
+
 		case GET_DISK_INFO:
 			err = get_disk_info(mddev, argp);
 			goto done_unlock;
@@ -2662,6 +2864,10 @@ static int md_ioctl(struct inode *inode,
 			err = do_md_run (mddev);
 			goto done_unlock;
 
+		case SET_BITMAP_FILE:
+			err = set_bitmap_file(mddev, (int)arg);
+			goto done_unlock;
+
 		default:
 			if (_IOC_TYPE(cmd) == MD_MAJOR)
 				printk(KERN_WARNING "md: %s(pid %d) used"
@@ -2773,10 +2979,10 @@ static int md_thread(void * arg)
 	while (thread->run) {
 		void (*run)(mddev_t *);
 
-		wait_event_interruptible(thread->wqueue,
-					 test_bit(THREAD_WAKEUP, &thread->flags));
-		if (current->flags & PF_FREEZE)
-			refrigerator(PF_FREEZE);
+		wait_event_interruptible_timeout(thread->wqueue,
+						 test_bit(THREAD_WAKEUP, &thread->flags),
+						 thread->timeout);
+		try_to_freeze();
 
 		clear_bit(THREAD_WAKEUP, &thread->flags);
 
@@ -2820,6 +3026,7 @@ mdk_thread_t *md_register_thread(void (*
 	thread->run = run;
 	thread->mddev = mddev;
 	thread->name = name;
+	thread->timeout = MAX_SCHEDULE_TIMEOUT;
 	ret = kernel_thread(md_thread, thread, 0);
 	if (ret < 0) {
 		kfree(thread);
@@ -2858,13 +3065,13 @@ void md_error(mddev_t *mddev, mdk_rdev_t
 
 	if (!rdev || rdev->faulty)
 		return;
-
+/*
 	dprintk("md_error dev:%s, rdev:(%d:%d), (caller: %p,%p,%p,%p).\n",
 		mdname(mddev),
 		MAJOR(rdev->bdev->bd_dev), MINOR(rdev->bdev->bd_dev),
 		__builtin_return_address(0),__builtin_return_address(1),
 		__builtin_return_address(2),__builtin_return_address(3));
-
+*/
 	if (!mddev->pers->error_handler)
 		return;
 	mddev->pers->error_handler(mddev,rdev);
@@ -3018,6 +3225,7 @@ static int md_seq_show(struct seq_file *
 	struct list_head *tmp2;
 	mdk_rdev_t *rdev;
 	int i;
+	struct bitmap *bitmap;
 
 	if (v == (void*)1) {
 		seq_printf(seq, "Personalities : ");
@@ -3070,10 +3278,35 @@ static int md_seq_show(struct seq_file *
 		if (mddev->pers) {
 			mddev->pers->status (seq, mddev);
 	 		seq_printf(seq, "\n      ");
-			if (mddev->curr_resync > 2)
+			if (mddev->curr_resync > 2) {
 				status_resync (seq, mddev);
-			else if (mddev->curr_resync == 1 || mddev->curr_resync == 2)
-				seq_printf(seq, "	resync=DELAYED");
+				seq_printf(seq, "\n      ");
+			} else if (mddev->curr_resync == 1 || mddev->curr_resync == 2)
+				seq_printf(seq, "	resync=DELAYED\n      ");
+		} else
+			seq_printf(seq, "\n       ");
+
+		if ((bitmap = mddev->bitmap)) {
+			unsigned long chunk_kb;
+			unsigned long flags;
+			spin_lock_irqsave(&bitmap->lock, flags);
+			chunk_kb = bitmap->chunksize >> 10;
+			seq_printf(seq, "bitmap: %lu/%lu pages [%luKB], "
+				"%lu%s chunk",
+				bitmap->pages - bitmap->missing_pages,
+				bitmap->pages,
+				(bitmap->pages - bitmap->missing_pages)
+					<< (PAGE_SHIFT - 10),
+				chunk_kb ? chunk_kb : bitmap->chunksize,
+				chunk_kb ? "KB" : "B");
+			if (bitmap->file) {
+				seq_printf(seq, ", file: ");
+				seq_path(seq, bitmap->file->f_vfsmnt,
+					 bitmap->file->f_dentry," \t\n");
+			}
+
+			seq_printf(seq, "\n");
+			spin_unlock_irqrestore(&bitmap->lock, flags);
 		}
 
 		seq_printf(seq, "\n");
@@ -3176,19 +3409,28 @@ void md_done_sync(mddev_t *mddev, int bl
 }
 
 
-void md_write_start(mddev_t *mddev)
+/* md_write_start(mddev, bi)
+ * If we need to update some array metadata (e.g. 'active' flag
+ * in superblock) before writing, schedule a superblock update
+ * and wait for it to complete.
+ */
+void md_write_start(mddev_t *mddev, struct bio *bi)
 {
-	if (!atomic_read(&mddev->writes_pending)) {
-		mddev_lock_uninterruptible(mddev);
+	DEFINE_WAIT(w);
+	if (bio_data_dir(bi) != WRITE)
+		return;
+
+	atomic_inc(&mddev->writes_pending);
+	if (mddev->in_sync) {
+		spin_lock(&mddev->write_lock);
 		if (mddev->in_sync) {
 			mddev->in_sync = 0;
- 			del_timer(&mddev->safemode_timer);
-			md_update_sb(mddev);
+			mddev->sb_dirty = 1;
+			md_wakeup_thread(mddev->thread);
 		}
-		atomic_inc(&mddev->writes_pending);
-		mddev_unlock(mddev);
-	} else
-		atomic_inc(&mddev->writes_pending);
+		spin_unlock(&mddev->write_lock);
+	}
+	wait_event(mddev->sb_wait, mddev->sb_dirty==0);
 }
 
 void md_write_end(mddev_t *mddev)
@@ -3201,37 +3443,6 @@ void md_write_end(mddev_t *mddev)
 	}
 }
 
-static inline void md_enter_safemode(mddev_t *mddev)
-{
-	if (!mddev->safemode) return;
-	if (mddev->safemode == 2 &&
-	    (atomic_read(&mddev->writes_pending) || mddev->in_sync ||
-		    mddev->recovery_cp != MaxSector))
-		return; /* avoid the lock */
-	mddev_lock_uninterruptible(mddev);
-	if (mddev->safemode && !atomic_read(&mddev->writes_pending) &&
-	    !mddev->in_sync && mddev->recovery_cp == MaxSector) {
-		mddev->in_sync = 1;
-		md_update_sb(mddev);
-	}
-	mddev_unlock(mddev);
-
-	if (mddev->safemode == 1)
-		mddev->safemode = 0;
-}
-
-void md_handle_safemode(mddev_t *mddev)
-{
-	if (signal_pending(current)) {
-		printk(KERN_INFO "md: %s in immediate safe mode\n",
-			mdname(mddev));
-		mddev->safemode = 2;
-		flush_signals(current);
-	}
-	md_enter_safemode(mddev);
-}
-
-
 static DECLARE_WAIT_QUEUE_HEAD(resync_wait);
 
 #define SYNC_MARKS	10
@@ -3241,12 +3452,13 @@ static void md_do_sync(mddev_t *mddev)
 	mddev_t *mddev2;
 	unsigned int currspeed = 0,
 		 window;
-	sector_t max_sectors,j;
+	sector_t max_sectors,j, io_sectors;
 	unsigned long mark[SYNC_MARKS];
 	sector_t mark_cnt[SYNC_MARKS];
 	int last_mark,m;
 	struct list_head *tmp;
 	sector_t last_check;
+	int skipped = 0;
 
 	/* just incase thread restarts... */
 	if (test_bit(MD_RECOVERY_DONE, &mddev->recovery))
@@ -3277,7 +3489,6 @@ static void md_do_sync(mddev_t *mddev)
 			goto skip;
 		}
 		ITERATE_MDDEV(mddev2,tmp) {
-			printk(".");
 			if (mddev2 == mddev)
 				continue;
 			if (mddev2->curr_resync && 
@@ -3312,7 +3523,7 @@ static void md_do_sync(mddev_t *mddev)
 
 	if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery))
 		/* resync follows the size requested by the personality,
-		 * which default to physical size, but can be virtual size
+		 * which defaults to physical size, but can be virtual size
 		 */
 		max_sectors = mddev->resync_max_sectors;
 	else
@@ -3327,13 +3538,15 @@ static void md_do_sync(mddev_t *mddev)
 	       sysctl_speed_limit_max);
 
 	is_mddev_idle(mddev); /* this also initializes IO event counters */
-	if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery))
+	/* we don't use the checkpoint if there's a bitmap */
+	if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery) && !mddev->bitmap)
 		j = mddev->recovery_cp;
 	else
 		j = 0;
+	io_sectors = 0;
 	for (m = 0; m < SYNC_MARKS; m++) {
 		mark[m] = jiffies;
-		mark_cnt[m] = j;
+		mark_cnt[m] = io_sectors;
 	}
 	last_mark = 0;
 	mddev->resync_mark = mark[last_mark];
@@ -3358,21 +3571,29 @@ static void md_do_sync(mddev_t *mddev)
 	}
 
 	while (j < max_sectors) {
-		int sectors;
+		sector_t sectors;
 
-		sectors = mddev->pers->sync_request(mddev, j, currspeed < sysctl_speed_limit_min);
-		if (sectors < 0) {
+		skipped = 0;
+		sectors = mddev->pers->sync_request(mddev, j, &skipped,
+					    currspeed < sysctl_speed_limit_min);
+		if (sectors == 0) {
 			set_bit(MD_RECOVERY_ERR, &mddev->recovery);
 			goto out;
 		}
-		atomic_add(sectors, &mddev->recovery_active);
+
+		if (!skipped) { /* actual IO requested */
+			io_sectors += sectors;
+			atomic_add(sectors, &mddev->recovery_active);
+		}
+
 		j += sectors;
 		if (j>1) mddev->curr_resync = j;
 
-		if (last_check + window > j || j == max_sectors)
+
+		if (last_check + window > io_sectors || j == max_sectors)
 			continue;
 
-		last_check = j;
+		last_check = io_sectors;
 
 		if (test_bit(MD_RECOVERY_INTR, &mddev->recovery) ||
 		    test_bit(MD_RECOVERY_ERR, &mddev->recovery))
@@ -3386,7 +3607,7 @@ static void md_do_sync(mddev_t *mddev)
 			mddev->resync_mark = mark[next];
 			mddev->resync_mark_cnt = mark_cnt[next];
 			mark[next] = jiffies;
-			mark_cnt[next] = j - atomic_read(&mddev->recovery_active);
+			mark_cnt[next] = io_sectors - atomic_read(&mddev->recovery_active);
 			last_mark = next;
 		}
 
@@ -3413,7 +3634,8 @@ static void md_do_sync(mddev_t *mddev)
 		mddev->queue->unplug_fn(mddev->queue);
 		cond_resched();
 
-		currspeed = ((unsigned long)(j-mddev->resync_mark_cnt))/2/((jiffies-mddev->resync_mark)/HZ +1) +1;
+		currspeed = ((unsigned long)(io_sectors-mddev->resync_mark_cnt))/2
+			/((jiffies-mddev->resync_mark)/HZ +1) +1;
 
 		if (currspeed > sysctl_speed_limit_min) {
 			if ((currspeed > sysctl_speed_limit_max) ||
@@ -3433,7 +3655,7 @@ static void md_do_sync(mddev_t *mddev)
 	wait_event(mddev->recovery_wait, !atomic_read(&mddev->recovery_active));
 
 	/* tell personality that we are finished */
-	mddev->pers->sync_request(mddev, max_sectors, 1);
+	mddev->pers->sync_request(mddev, max_sectors, &skipped, 1);
 
 	if (!test_bit(MD_RECOVERY_ERR, &mddev->recovery) &&
 	    mddev->curr_resync > 2 &&
@@ -3447,7 +3669,6 @@ static void md_do_sync(mddev_t *mddev)
 			mddev->recovery_cp = MaxSector;
 	}
 
-	md_enter_safemode(mddev);
  skip:
 	mddev->curr_resync = 0;
 	wake_up(&resync_wait);
@@ -3484,20 +3705,48 @@ void md_check_recovery(mddev_t *mddev)
 	struct list_head *rtmp;
 
 
-	dprintk(KERN_INFO "md: recovery thread got woken up ...\n");
+	if (mddev->bitmap)
+		bitmap_daemon_work(mddev->bitmap);
 
 	if (mddev->ro)
 		return;
+
+	if (signal_pending(current)) {
+		if (mddev->pers->sync_request) {
+			printk(KERN_INFO "md: %s in immediate safe mode\n",
+			       mdname(mddev));
+			mddev->safemode = 2;
+		}
+		flush_signals(current);
+	}
+
 	if ( ! (
 		mddev->sb_dirty ||
 		test_bit(MD_RECOVERY_NEEDED, &mddev->recovery) ||
-		test_bit(MD_RECOVERY_DONE, &mddev->recovery)
+		test_bit(MD_RECOVERY_DONE, &mddev->recovery) ||
+		(mddev->safemode == 1) ||
+		(mddev->safemode == 2 && ! atomic_read(&mddev->writes_pending)
+		 && !mddev->in_sync && mddev->recovery_cp == MaxSector)
 		))
 		return;
+
 	if (mddev_trylock(mddev)==0) {
 		int spares =0;
+
+		spin_lock(&mddev->write_lock);
+		if (mddev->safemode && !atomic_read(&mddev->writes_pending) &&
+		    !mddev->in_sync && mddev->recovery_cp == MaxSector) {
+			mddev->in_sync = 1;
+			mddev->sb_dirty = 1;
+		}
+		if (mddev->safemode == 1)
+			mddev->safemode = 0;
+		spin_unlock(&mddev->write_lock);
+
 		if (mddev->sb_dirty)
 			md_update_sb(mddev);
+
+
 		if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) &&
 		    !test_bit(MD_RECOVERY_DONE, &mddev->recovery)) {
 			/* resync/recovery still happening */
@@ -3515,6 +3764,14 @@ void md_check_recovery(mddev_t *mddev)
 				mddev->pers->spare_active(mddev);
 			}
 			md_update_sb(mddev);
+
+			/* if array is no-longer degraded, then any saved_raid_disk
+			 * information must be scrapped
+			 */
+			if (!mddev->degraded)
+				ITERATE_RDEV(mddev,rdev,rtmp)
+					rdev->saved_raid_disk = -1;
+
 			mddev->recovery = 0;
 			/* flag recovery needed just to double check */
 			set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
@@ -3557,6 +3814,13 @@ void md_check_recovery(mddev_t *mddev)
 			set_bit(MD_RECOVERY_RUNNING, &mddev->recovery);
 			if (!spares)
 				set_bit(MD_RECOVERY_SYNC, &mddev->recovery);
+			if (spares && mddev->bitmap && ! mddev->bitmap->file) {
+				/* We are adding a device or devices to an array
+				 * which has the bitmap stored on all devices.
+				 * So make sure all bitmap pages get written
+				 */
+				bitmap_write_all(mddev->bitmap);
+			}
 			mddev->sync_thread = md_register_thread(md_do_sync,
 								mddev,
 								"%s_resync");
@@ -3624,6 +3888,8 @@ static int __init md_init(void)
 			" MD_SB_DISKS=%d\n",
 			MD_MAJOR_VERSION, MD_MINOR_VERSION,
 			MD_PATCHLEVEL_VERSION, MAX_MD_DEVS, MD_SB_DISKS);
+	printk(KERN_INFO "md: bitmap version %d.%d\n", BITMAP_MAJOR,
+			BITMAP_MINOR);
 
 	if (register_blkdev(MAJOR_NR, "md"))
 		return -1;
@@ -3739,10 +4005,11 @@ EXPORT_SYMBOL(md_error);
 EXPORT_SYMBOL(md_done_sync);
 EXPORT_SYMBOL(md_write_start);
 EXPORT_SYMBOL(md_write_end);
-EXPORT_SYMBOL(md_handle_safemode);
 EXPORT_SYMBOL(md_register_thread);
 EXPORT_SYMBOL(md_unregister_thread);
 EXPORT_SYMBOL(md_wakeup_thread);
 EXPORT_SYMBOL(md_print_devices);
 EXPORT_SYMBOL(md_check_recovery);
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("md");
+MODULE_ALIAS_BLOCKDEV_MAJOR(MD_MAJOR);
diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c
--- a/drivers/md/multipath.c
+++ b/drivers/md/multipath.c
@@ -533,8 +533,7 @@ static int multipath_run (mddev_t *mddev
 out_free_conf:
 	if (conf->pool)
 		mempool_destroy(conf->pool);
-	if (conf->multipaths)
-		kfree(conf->multipaths);
+	kfree(conf->multipaths);
 	kfree(conf);
 	mddev->private = NULL;
 out:
diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c
--- a/drivers/md/raid0.c
+++ b/drivers/md/raid0.c
@@ -314,16 +314,16 @@ static int raid0_run (mddev_t *mddev)
 		sector_t space = conf->hash_spacing;
 		int round;
 		conf->preshift = 0;
-		if (sizeof(sector_t) > sizeof(unsigned long)) {
+		if (sizeof(sector_t) > sizeof(u32)) {
 			/*shift down space and s so that sector_div will work */
-			while (space > (sector_t) (~(unsigned long)0)) {
+			while (space > (sector_t) (~(u32)0)) {
 				s >>= 1;
 				space >>= 1;
 				s += 1; /* force round-up */
 				conf->preshift++;
 			}
 		}
-		round = sector_div(s, (unsigned long)space) ? 1 : 0;
+		round = sector_div(s, (u32)space) ? 1 : 0;
 		nb_zone = s + round;
 	}
 	printk("raid0 : nb_zone is %d.\n", nb_zone);
@@ -371,10 +371,8 @@ static int raid0_run (mddev_t *mddev)
 	return 0;
 
 out_free_conf:
-	if (conf->strip_zone)
-		kfree(conf->strip_zone);
-	if (conf->devlist)
-		kfree (conf->devlist);
+	kfree(conf->strip_zone);
+	kfree(conf->devlist);
 	kfree(conf);
 	mddev->private = NULL;
 out:
@@ -386,11 +384,11 @@ static int raid0_stop (mddev_t *mddev)
 	raid0_conf_t *conf = mddev_to_conf(mddev);
 
 	blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/
-	kfree (conf->hash_table);
+	kfree(conf->hash_table);
 	conf->hash_table = NULL;
-	kfree (conf->strip_zone);
+	kfree(conf->strip_zone);
 	conf->strip_zone = NULL;
-	kfree (conf);
+	kfree(conf);
 	mddev->private = NULL;
 
 	return 0;
@@ -445,7 +443,7 @@ static int raid0_make_request (request_q
 		volatile
 #endif
 		sector_t x = block >> conf->preshift;
-		sector_div(x, (unsigned long)conf->hash_spacing);
+		sector_div(x, (u32)conf->hash_spacing);
 		zone = conf->hash_table[x];
 	}
  
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -12,6 +12,15 @@
  * Fixes to reconstruction by Jakob Østergaard" <jakob@ostenfeld.dk>
  * Various fixes by Neil Brown <neilb@cse.unsw.edu.au>
  *
+ * Changes by Peter T. Breuer <ptb@it.uc3m.es> 31/1/2003 to support
+ * bitmapped intelligence in resync:
+ *
+ *      - bitmap marked during normal i/o
+ *      - bitmap used to skip nondirty blocks during sync
+ *
+ * Additions to bitmap code, (C) 2003-2004 Paul Clements, SteelEye Technology:
+ * - persistent bitmap code
+ *
  * 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)
@@ -22,7 +31,16 @@
  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#include "dm-bio-list.h"
 #include <linux/raid/raid1.h>
+#include <linux/raid/bitmap.h>
+
+#define DEBUG 0
+#if DEBUG
+#define PRINTK(x...) printk(x)
+#else
+#define PRINTK(x...)
+#endif
 
 /*
  * Number of guaranteed r1bios in case of extreme VM load:
@@ -287,9 +305,11 @@ static int raid1_end_write_request(struc
 	/*
 	 * this branch is our 'one mirror IO has finished' event handler:
 	 */
-	if (!uptodate)
+	if (!uptodate) {
 		md_error(r1_bio->mddev, conf->mirrors[mirror].rdev);
-	else
+		/* an I/O failed, we can't clear the bitmap */
+		set_bit(R1BIO_Degraded, &r1_bio->state);
+	} else
 		/*
 		 * Set R1BIO_Uptodate in our master bio, so that
 		 * we will return a good error code for to the higher
@@ -309,6 +329,10 @@ static int raid1_end_write_request(struc
 	 * already.
 	 */
 	if (atomic_dec_and_test(&r1_bio->remaining)) {
+		/* clear the bitmap if all writes complete successfully */
+		bitmap_endwrite(r1_bio->mddev->bitmap, r1_bio->sector,
+				r1_bio->sectors,
+				!test_bit(R1BIO_Degraded, &r1_bio->state));
 		md_write_end(r1_bio->mddev);
 		raid_end_bio_io(r1_bio);
 	}
@@ -458,7 +482,10 @@ static void unplug_slaves(mddev_t *mddev
 
 static void raid1_unplug(request_queue_t *q)
 {
-	unplug_slaves(q->queuedata);
+	mddev_t *mddev = q->queuedata;
+
+	unplug_slaves(mddev);
+	md_wakeup_thread(mddev->thread);
 }
 
 static int raid1_issue_flush(request_queue_t *q, struct gendisk *disk,
@@ -501,16 +528,16 @@ static void device_barrier(conf_t *conf,
 {
 	spin_lock_irq(&conf->resync_lock);
 	wait_event_lock_irq(conf->wait_idle, !waitqueue_active(&conf->wait_resume),
-			    conf->resync_lock, unplug_slaves(conf->mddev));
+			    conf->resync_lock, raid1_unplug(conf->mddev->queue));
 	
 	if (!conf->barrier++) {
 		wait_event_lock_irq(conf->wait_idle, !conf->nr_pending,
-				    conf->resync_lock, unplug_slaves(conf->mddev));
+				    conf->resync_lock, raid1_unplug(conf->mddev->queue));
 		if (conf->nr_pending)
 			BUG();
 	}
 	wait_event_lock_irq(conf->wait_resume, conf->barrier < RESYNC_DEPTH,
-			    conf->resync_lock, unplug_slaves(conf->mddev));
+			    conf->resync_lock, raid1_unplug(conf->mddev->queue));
 	conf->next_resync = sect;
 	spin_unlock_irq(&conf->resync_lock);
 }
@@ -522,14 +549,20 @@ static int make_request(request_queue_t 
 	mirror_info_t *mirror;
 	r1bio_t *r1_bio;
 	struct bio *read_bio;
-	int i, disks;
+	int i, targets = 0, disks;
 	mdk_rdev_t *rdev;
+	struct bitmap *bitmap = mddev->bitmap;
+	unsigned long flags;
+	struct bio_list bl;
+
 
 	/*
 	 * Register the new request and wait if the reconstruction
 	 * thread has put up a bar for new requests.
 	 * Continue immediately if no resync is active currently.
 	 */
+	md_write_start(mddev, bio); /* wait on superblock update early */
+
 	spin_lock_irq(&conf->resync_lock);
 	wait_event_lock_irq(conf->wait_resume, !conf->barrier, conf->resync_lock, );
 	conf->nr_pending++;
@@ -552,7 +585,7 @@ static int make_request(request_queue_t 
 
 	r1_bio->master_bio = bio;
 	r1_bio->sectors = bio->bi_size >> 9;
-
+	r1_bio->state = 0;
 	r1_bio->mddev = mddev;
 	r1_bio->sector = bio->bi_sector;
 
@@ -595,6 +628,13 @@ static int make_request(request_queue_t 
 	 * bios[x] to bio
 	 */
 	disks = conf->raid_disks;
+#if 0
+	{ static int first=1;
+	if (first) printk("First Write sector %llu disks %d\n",
+			  (unsigned long long)r1_bio->sector, disks);
+	first = 0;
+	}
+#endif
 	rcu_read_lock();
 	for (i = 0;  i < disks; i++) {
 		if ((rdev=conf->mirrors[i].rdev) != NULL &&
@@ -605,13 +645,21 @@ static int make_request(request_queue_t 
 				r1_bio->bios[i] = NULL;
 			} else
 				r1_bio->bios[i] = bio;
+			targets++;
 		} else
 			r1_bio->bios[i] = NULL;
 	}
 	rcu_read_unlock();
 
-	atomic_set(&r1_bio->remaining, 1);
-	md_write_start(mddev);
+	if (targets < conf->raid_disks) {
+		/* array is degraded, we will not clear the bitmap
+		 * on I/O completion (see raid1_end_write_request) */
+		set_bit(R1BIO_Degraded, &r1_bio->state);
+	}
+
+	atomic_set(&r1_bio->remaining, 0);
+
+	bio_list_init(&bl);
 	for (i = 0; i < disks; i++) {
 		struct bio *mbio;
 		if (!r1_bio->bios[i])
@@ -627,14 +675,23 @@ static int make_request(request_queue_t 
 		mbio->bi_private = r1_bio;
 
 		atomic_inc(&r1_bio->remaining);
-		generic_make_request(mbio);
-	}
 
-	if (atomic_dec_and_test(&r1_bio->remaining)) {
-		md_write_end(mddev);
-		raid_end_bio_io(r1_bio);
+		bio_list_add(&bl, mbio);
 	}
 
+	bitmap_startwrite(bitmap, bio->bi_sector, r1_bio->sectors);
+	spin_lock_irqsave(&conf->device_lock, flags);
+	bio_list_merge(&conf->pending_bio_list, &bl);
+	bio_list_init(&bl);
+
+	blk_plug_device(mddev->queue);
+	spin_unlock_irqrestore(&conf->device_lock, flags);
+
+#if 0
+	while ((bio = bio_list_pop(&bl)) != NULL)
+		generic_make_request(bio);
+#endif
+
 	return 0;
 }
 
@@ -714,7 +771,7 @@ static void close_sync(conf_t *conf)
 {
 	spin_lock_irq(&conf->resync_lock);
 	wait_event_lock_irq(conf->wait_resume, !conf->barrier,
-			    conf->resync_lock, 	unplug_slaves(conf->mddev));
+			    conf->resync_lock, 	raid1_unplug(conf->mddev->queue));
 	spin_unlock_irq(&conf->resync_lock);
 
 	if (conf->barrier) BUG();
@@ -754,9 +811,12 @@ static int raid1_add_disk(mddev_t *mddev
 {
 	conf_t *conf = mddev->private;
 	int found = 0;
-	int mirror;
+	int mirror = 0;
 	mirror_info_t *p;
 
+	if (rdev->saved_raid_disk >= 0 &&
+	    conf->mirrors[rdev->saved_raid_disk].rdev == NULL)
+		mirror = rdev->saved_raid_disk;
 	for (mirror=0; mirror < mddev->raid_disks; mirror++)
 		if ( !(p=conf->mirrors+mirror)->rdev) {
 
@@ -773,6 +833,8 @@ static int raid1_add_disk(mddev_t *mddev
 			p->head_position = 0;
 			rdev->raid_disk = mirror;
 			found = 1;
+			if (rdev->saved_raid_disk != mirror)
+				conf->fullsync = 1;
 			p->rdev = rdev;
 			break;
 		}
@@ -828,10 +890,10 @@ static int end_sync_read(struct bio *bio
 	 * or re-read if the read failed.
 	 * We don't do much here, just schedule handling by raid1d
 	 */
-	if (!uptodate)
+	if (!uptodate) {
 		md_error(r1_bio->mddev,
 			 conf->mirrors[r1_bio->read_disk].rdev);
-	else
+	} else
 		set_bit(R1BIO_Uptodate, &r1_bio->state);
 	rdev_dec_pending(conf->mirrors[r1_bio->read_disk].rdev, conf->mddev);
 	reschedule_retry(r1_bio);
@@ -857,6 +919,7 @@ static int end_sync_write(struct bio *bi
 		}
 	if (!uptodate)
 		md_error(mddev, conf->mirrors[mirror].rdev);
+
 	update_head_pos(mirror, r1_bio);
 
 	if (atomic_dec_and_test(&r1_bio->remaining)) {
@@ -876,6 +939,9 @@ static void sync_request_write(mddev_t *
 
 	bio = r1_bio->bios[r1_bio->read_disk];
 
+/*
+	if (r1_bio->sector == 0) printk("First sync write startss\n");
+*/
 	/*
 	 * schedule writes
 	 */
@@ -903,10 +969,12 @@ static void sync_request_write(mddev_t *
 		atomic_inc(&conf->mirrors[i].rdev->nr_pending);
 		atomic_inc(&r1_bio->remaining);
 		md_sync_acct(conf->mirrors[i].rdev->bdev, wbio->bi_size >> 9);
+
 		generic_make_request(wbio);
 	}
 
 	if (atomic_dec_and_test(&r1_bio->remaining)) {
+		/* if we're here, all write(s) have completed, so clean up */
 		md_done_sync(mddev, r1_bio->sectors, 1);
 		put_buf(r1_bio);
 	}
@@ -931,11 +999,30 @@ static void raid1d(mddev_t *mddev)
 	mdk_rdev_t *rdev;
 
 	md_check_recovery(mddev);
-	md_handle_safemode(mddev);
 	
 	for (;;) {
 		char b[BDEVNAME_SIZE];
 		spin_lock_irqsave(&conf->device_lock, flags);
+
+		if (conf->pending_bio_list.head) {
+			bio = bio_list_get(&conf->pending_bio_list);
+			blk_remove_plug(mddev->queue);
+			spin_unlock_irqrestore(&conf->device_lock, flags);
+			/* flush any pending bitmap writes to disk before proceeding w/ I/O */
+			if (bitmap_unplug(mddev->bitmap) != 0)
+				printk("%s: bitmap file write failed!\n", mdname(mddev));
+
+			while (bio) { /* submit pending writes */
+				struct bio *next = bio->bi_next;
+				bio->bi_next = NULL;
+				generic_make_request(bio);
+				bio = next;
+			}
+			unplug = 1;
+
+			continue;
+		}
+
 		if (list_empty(head))
 			break;
 		r1_bio = list_entry(head->prev, r1bio_t, retry_list);
@@ -1009,7 +1096,7 @@ static int init_resync(conf_t *conf)
  * that can be installed to exclude normal IO requests.
  */
 
-static int sync_request(mddev_t *mddev, sector_t sector_nr, int go_faster)
+static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, int go_faster)
 {
 	conf_t *conf = mddev_to_conf(mddev);
 	mirror_info_t *mirror;
@@ -1019,17 +1106,45 @@ static int sync_request(mddev_t *mddev, 
 	int disk;
 	int i;
 	int write_targets = 0;
+	int sync_blocks;
+	int still_degraded = 0;
 
 	if (!conf->r1buf_pool)
+	{
+/*
+		printk("sync start - bitmap %p\n", mddev->bitmap);
+*/
 		if (init_resync(conf))
-			return -ENOMEM;
+			return 0;
+	}
 
 	max_sector = mddev->size << 1;
 	if (sector_nr >= max_sector) {
+		/* If we aborted, we need to abort the
+		 * sync on the 'current' bitmap chunk (there will
+		 * only be one in raid1 resync.
+		 * We can find the current addess in mddev->curr_resync
+		 */
+		if (mddev->curr_resync < max_sector) /* aborted */
+			bitmap_end_sync(mddev->bitmap, mddev->curr_resync,
+						&sync_blocks, 1);
+		else /* completed sync */
+			conf->fullsync = 0;
+
+		bitmap_close_sync(mddev->bitmap);
 		close_sync(conf);
 		return 0;
 	}
 
+	/* before building a request, check if we can skip these blocks..
+	 * This call the bitmap_start_sync doesn't actually record anything
+	 */
+	if (!bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, 1) &&
+	    !conf->fullsync) {
+		/* We can skip this block, and probably several more */
+		*skipped = 1;
+		return sync_blocks;
+	}
 	/*
 	 * If there is non-resync activity waiting for us then
 	 * put in a delay to throttle resync.
@@ -1068,6 +1183,7 @@ static int sync_request(mddev_t *mddev, 
 
 	r1_bio->mddev = mddev;
 	r1_bio->sector = sector_nr;
+	r1_bio->state = 0;
 	set_bit(R1BIO_IsSync, &r1_bio->state);
 	r1_bio->read_disk = disk;
 
@@ -1089,31 +1205,36 @@ static int sync_request(mddev_t *mddev, 
 		if (i == disk) {
 			bio->bi_rw = READ;
 			bio->bi_end_io = end_sync_read;
-		} else if (conf->mirrors[i].rdev &&
-			   !conf->mirrors[i].rdev->faulty &&
-			   (!conf->mirrors[i].rdev->in_sync ||
-			    sector_nr + RESYNC_SECTORS > mddev->recovery_cp)) {
+		} else if (conf->mirrors[i].rdev == NULL ||
+			   conf->mirrors[i].rdev->faulty) {
+			still_degraded = 1;
+			continue;
+		} else if (!conf->mirrors[i].rdev->in_sync ||
+			   sector_nr + RESYNC_SECTORS > mddev->recovery_cp) {
 			bio->bi_rw = WRITE;
 			bio->bi_end_io = end_sync_write;
 			write_targets ++;
 		} else
+			/* no need to read or write here */
 			continue;
 		bio->bi_sector = sector_nr + conf->mirrors[i].rdev->data_offset;
 		bio->bi_bdev = conf->mirrors[i].rdev->bdev;
 		bio->bi_private = r1_bio;
 	}
+
 	if (write_targets == 0) {
 		/* There is nowhere to write, so all non-sync
 		 * drives must be failed - so we are finished
 		 */
-		int rv = max_sector - sector_nr;
-		md_done_sync(mddev, rv, 1);
+		sector_t rv = max_sector - sector_nr;
+		*skipped = 1;
 		put_buf(r1_bio);
 		rdev_dec_pending(conf->mirrors[disk].rdev, mddev);
 		return rv;
 	}
 
 	nr_sectors = 0;
+	sync_blocks = 0;
 	do {
 		struct page *page;
 		int len = PAGE_SIZE;
@@ -1121,6 +1242,17 @@ static int sync_request(mddev_t *mddev, 
 			len = (max_sector - sector_nr) << 9;
 		if (len == 0)
 			break;
+		if (sync_blocks == 0) {
+			if (!bitmap_start_sync(mddev->bitmap, sector_nr,
+					&sync_blocks, still_degraded) &&
+					!conf->fullsync)
+				break;
+			if (sync_blocks < (PAGE_SIZE>>9))
+				BUG();
+			if (len > (sync_blocks<<9))
+				len = sync_blocks<<9;
+		}
+
 		for (i=0 ; i < conf->raid_disks; i++) {
 			bio = r1_bio->bios[i];
 			if (bio->bi_end_io) {
@@ -1131,7 +1263,8 @@ static int sync_request(mddev_t *mddev, 
 					while (i > 0) {
 						i--;
 						bio = r1_bio->bios[i];
-						if (bio->bi_end_io==NULL) continue;
+						if (bio->bi_end_io==NULL)
+							continue;
 						/* remove last page from this bio */
 						bio->bi_vcnt--;
 						bio->bi_size -= len;
@@ -1143,6 +1276,7 @@ static int sync_request(mddev_t *mddev, 
 		}
 		nr_sectors += len>>9;
 		sector_nr += len>>9;
+		sync_blocks -= (len>>9);
 	} while (r1_bio->bios[disk]->bi_vcnt < RESYNC_PAGES);
  bio_full:
 	bio = r1_bio->bios[disk];
@@ -1231,6 +1365,9 @@ static int run(mddev_t *mddev)
 	init_waitqueue_head(&conf->wait_idle);
 	init_waitqueue_head(&conf->wait_resume);
 
+	bio_list_init(&conf->pending_bio_list);
+	bio_list_init(&conf->flushing_bio_list);
+
 	if (!conf->working_disks) {
 		printk(KERN_ERR "raid1: no operational mirrors for %s\n",
 			mdname(mddev));
@@ -1259,16 +1396,15 @@ static int run(mddev_t *mddev)
 	conf->last_used = j;
 
 
-
-	{
-		mddev->thread = md_register_thread(raid1d, mddev, "%s_raid1");
-		if (!mddev->thread) {
-			printk(KERN_ERR 
-				"raid1: couldn't allocate thread for %s\n", 
-				mdname(mddev));
-			goto out_free_conf;
-		}
+	mddev->thread = md_register_thread(raid1d, mddev, "%s_raid1");
+	if (!mddev->thread) {
+		printk(KERN_ERR
+		       "raid1: couldn't allocate thread for %s\n",
+		       mdname(mddev));
+		goto out_free_conf;
 	}
+	if (mddev->bitmap) mddev->thread->timeout = mddev->bitmap->daemon_sleep * HZ;
+
 	printk(KERN_INFO 
 		"raid1: raid set %s active with %d out of %d mirrors\n",
 		mdname(mddev), mddev->raid_disks - mddev->degraded, 
@@ -1291,10 +1427,8 @@ out_free_conf:
 	if (conf) {
 		if (conf->r1bio_pool)
 			mempool_destroy(conf->r1bio_pool);
-		if (conf->mirrors)
-			kfree(conf->mirrors);
-		if (conf->poolinfo)
-			kfree(conf->poolinfo);
+		kfree(conf->mirrors);
+		kfree(conf->poolinfo);
 		kfree(conf);
 		mddev->private = NULL;
 	}
@@ -1311,10 +1445,8 @@ static int stop(mddev_t *mddev)
 	blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/
 	if (conf->r1bio_pool)
 		mempool_destroy(conf->r1bio_pool);
-	if (conf->mirrors)
-		kfree(conf->mirrors);
-	if (conf->poolinfo)
-		kfree(conf->poolinfo);
+	kfree(conf->mirrors);
+	kfree(conf->poolinfo);
 	kfree(conf);
 	mddev->private = NULL;
 	return 0;
@@ -1337,6 +1469,7 @@ static int raid1_resize(mddev_t *mddev, 
 		set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
 	}
 	mddev->size = mddev->array_size;
+	mddev->resync_max_sectors = sectors;
 	return 0;
 }
 
@@ -1349,17 +1482,26 @@ static int raid1_reshape(mddev_t *mddev,
 	 * We allocate a new r1bio_pool if we can.
 	 * Then raise a device barrier and wait until all IO stops.
 	 * Then resize conf->mirrors and swap in the new r1bio pool.
+	 *
+	 * At the same time, we "pack" the devices so that all the missing
+	 * devices have the higher raid_disk numbers.
 	 */
 	mempool_t *newpool, *oldpool;
 	struct pool_info *newpoolinfo;
 	mirror_info_t *newmirrors;
 	conf_t *conf = mddev_to_conf(mddev);
+	int cnt;
 
-	int d;
+	int d, d2;
 
-	for (d= raid_disks; d < conf->raid_disks; d++)
-		if (conf->mirrors[d].rdev)
+	if (raid_disks < conf->raid_disks) {
+		cnt=0;
+		for (d= 0; d < conf->raid_disks; d++)
+			if (conf->mirrors[d].rdev)
+				cnt++;
+		if (cnt > raid_disks)
 			return -EBUSY;
+	}
 
 	newpoolinfo = kmalloc(sizeof(*newpoolinfo), GFP_KERNEL);
 	if (!newpoolinfo)
@@ -1384,14 +1526,18 @@ static int raid1_reshape(mddev_t *mddev,
 	spin_lock_irq(&conf->resync_lock);
 	conf->barrier++;
 	wait_event_lock_irq(conf->wait_idle, !conf->nr_pending,
-			    conf->resync_lock, unplug_slaves(mddev));
+			    conf->resync_lock, raid1_unplug(mddev->queue));
 	spin_unlock_irq(&conf->resync_lock);
 
 	/* ok, everything is stopped */
 	oldpool = conf->r1bio_pool;
 	conf->r1bio_pool = newpool;
-	for (d=0; d < raid_disks && d < conf->raid_disks; d++)
-		newmirrors[d] = conf->mirrors[d];
+
+	for (d=d2=0; d < conf->raid_disks; d++)
+		if (conf->mirrors[d].rdev) {
+			conf->mirrors[d].rdev->raid_disk = d2;
+			newmirrors[d2++].rdev = conf->mirrors[d].rdev;
+		}
 	kfree(conf->mirrors);
 	conf->mirrors = newmirrors;
 	kfree(conf->poolinfo);
@@ -1400,6 +1546,7 @@ static int raid1_reshape(mddev_t *mddev,
 	mddev->degraded += (raid_disks - conf->raid_disks);
 	conf->raid_disks = mddev->raid_disks = raid_disks;
 
+	conf->last_used = 0; /* just make sure it is in-range */
 	spin_lock_irq(&conf->resync_lock);
 	conf->barrier--;
 	spin_unlock_irq(&conf->resync_lock);
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -700,6 +700,8 @@ static int make_request(request_queue_t 
 		return 0;
 	}
 
+	md_write_start(mddev, bio);
+
 	/*
 	 * Register the new request and wait if the reconstruction
 	 * thread has put up a bar for new requests.
@@ -774,7 +776,7 @@ static int make_request(request_queue_t 
 	rcu_read_unlock();
 
 	atomic_set(&r10_bio->remaining, 1);
-	md_write_start(mddev);
+
 	for (i = 0; i < conf->copies; i++) {
 		struct bio *mbio;
 		int d = r10_bio->devs[i].devnum;
@@ -1216,7 +1218,6 @@ static void raid10d(mddev_t *mddev)
 	mdk_rdev_t *rdev;
 
 	md_check_recovery(mddev);
-	md_handle_safemode(mddev);
 
 	for (;;) {
 		char b[BDEVNAME_SIZE];
@@ -1319,7 +1320,7 @@ static int init_resync(conf_t *conf)
  *
  */
 
-static int sync_request(mddev_t *mddev, sector_t sector_nr, int go_faster)
+static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, int go_faster)
 {
 	conf_t *conf = mddev_to_conf(mddev);
 	r10bio_t *r10_bio;
@@ -1333,7 +1334,7 @@ static int sync_request(mddev_t *mddev, 
 
 	if (!conf->r10buf_pool)
 		if (init_resync(conf))
-			return -ENOMEM;
+			return 0;
 
  skipped:
 	max_sector = mddev->size << 1;
@@ -1341,15 +1342,15 @@ static int sync_request(mddev_t *mddev, 
 		max_sector = mddev->resync_max_sectors;
 	if (sector_nr >= max_sector) {
 		close_sync(conf);
+		*skipped = 1;
 		return sectors_skipped;
 	}
 	if (chunks_skipped >= conf->raid_disks) {
 		/* if there has been nothing to do on any drive,
 		 * then there is nothing to do at all..
 		 */
-		sector_t sec = max_sector - sector_nr;
-		md_done_sync(mddev, sec, 1);
-		return sec + sectors_skipped;
+		*skipped = 1;
+		return (max_sector - sector_nr) + sectors_skipped;
 	}
 
 	/* make sure whole request will fit in a chunk - if chunks
@@ -1563,17 +1564,22 @@ static int sync_request(mddev_t *mddev, 
 		}
 	}
 
+	if (sectors_skipped)
+		/* pretend they weren't skipped, it makes
+		 * no important difference in this case
+		 */
+		md_done_sync(mddev, sectors_skipped, 1);
+
 	return sectors_skipped + nr_sectors;
  giveup:
 	/* There is nowhere to write, so all non-sync
 	 * drives must be failed, so try the next chunk...
 	 */
 	{
-	int sec = max_sector - sector_nr;
+	sector_t sec = max_sector - sector_nr;
 	sectors_skipped += sec;
 	chunks_skipped ++;
 	sector_nr = max_sector;
-	md_done_sync(mddev, sec, 1);
 	goto skipped;
 	}
 }
@@ -1731,8 +1737,7 @@ static int run(mddev_t *mddev)
 out_free_conf:
 	if (conf->r10bio_pool)
 		mempool_destroy(conf->r10bio_pool);
-	if (conf->mirrors)
-		kfree(conf->mirrors);
+	kfree(conf->mirrors);
 	kfree(conf);
 	mddev->private = NULL;
 out:
@@ -1748,8 +1753,7 @@ static int stop(mddev_t *mddev)
 	blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/
 	if (conf->r10bio_pool)
 		mempool_destroy(conf->r10bio_pool);
-	if (conf->mirrors)
-		kfree(conf->mirrors);
+	kfree(conf->mirrors);
 	kfree(conf);
 	mddev->private = NULL;
 	return 0;
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -1411,6 +1411,8 @@ static int make_request (request_queue_t
 	sector_t logical_sector, last_sector;
 	struct stripe_head *sh;
 
+	md_write_start(mddev, bi);
+
 	if (bio_data_dir(bi)==WRITE) {
 		disk_stat_inc(mddev->gendisk, writes);
 		disk_stat_add(mddev->gendisk, write_sectors, bio_sectors(bi));
@@ -1423,8 +1425,7 @@ static int make_request (request_queue_t
 	last_sector = bi->bi_sector + (bi->bi_size>>9);
 	bi->bi_next = NULL;
 	bi->bi_phys_segments = 1;	/* over-loaded to count active stripes */
-	if ( bio_data_dir(bi) == WRITE )
-		md_write_start(mddev);
+
 	for (;logical_sector < last_sector; logical_sector += STRIPE_SECTORS) {
 		DEFINE_WAIT(w);
 		
@@ -1475,7 +1476,7 @@ static int make_request (request_queue_t
 }
 
 /* FIXME go_faster isn't used */
-static int sync_request (mddev_t *mddev, sector_t sector_nr, int go_faster)
+static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, int go_faster)
 {
 	raid5_conf_t *conf = (raid5_conf_t *) mddev->private;
 	struct stripe_head *sh;
@@ -1498,8 +1499,8 @@ static int sync_request (mddev_t *mddev,
 	 * nothing we can do.
 	 */
 	if (mddev->degraded >= 1 && test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) {
-		int rv = (mddev->size << 1) - sector_nr;
-		md_done_sync(mddev, rv, 1);
+		sector_t rv = (mddev->size << 1) - sector_nr;
+		*skipped = 1;
 		return rv;
 	}
 
@@ -1546,7 +1547,6 @@ static void raid5d (mddev_t *mddev)
 	PRINTK("+++ raid5d active\n");
 
 	md_check_recovery(mddev);
-	md_handle_safemode(mddev);
 
 	handled = 0;
 	spin_lock_irq(&conf->device_lock);
@@ -1653,6 +1653,7 @@ static int run (mddev_t *mddev)
 
 	/* device size must be a multiple of chunk size */
 	mddev->size &= ~(mddev->chunk_size/1024 -1);
+	mddev->resync_max_sectors = mddev->size << 1;
 
 	if (!conf->chunk_size || conf->chunk_size % 4) {
 		printk(KERN_ERR "raid5: invalid chunk size %d for %s\n",
@@ -1931,6 +1932,7 @@ static int raid5_resize(mddev_t *mddev, 
 		set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
 	}
 	mddev->size = sectors /2;
+	mddev->resync_max_sectors = sectors;
 	return 0;
 }
 
diff --git a/drivers/md/raid6main.c b/drivers/md/raid6main.c
--- a/drivers/md/raid6main.c
+++ b/drivers/md/raid6main.c
@@ -1570,6 +1570,8 @@ static int make_request (request_queue_t
 	sector_t logical_sector, last_sector;
 	struct stripe_head *sh;
 
+	md_write_start(mddev, bi);
+
 	if (bio_data_dir(bi)==WRITE) {
 		disk_stat_inc(mddev->gendisk, writes);
 		disk_stat_add(mddev->gendisk, write_sectors, bio_sectors(bi));
@@ -1583,8 +1585,7 @@ static int make_request (request_queue_t
 
 	bi->bi_next = NULL;
 	bi->bi_phys_segments = 1;	/* over-loaded to count active stripes */
-	if ( bio_data_dir(bi) == WRITE )
-		md_write_start(mddev);
+
 	for (;logical_sector < last_sector; logical_sector += STRIPE_SECTORS) {
 		DEFINE_WAIT(w);
 
@@ -1634,7 +1635,7 @@ static int make_request (request_queue_t
 }
 
 /* FIXME go_faster isn't used */
-static int sync_request (mddev_t *mddev, sector_t sector_nr, int go_faster)
+static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, int go_faster)
 {
 	raid6_conf_t *conf = (raid6_conf_t *) mddev->private;
 	struct stripe_head *sh;
@@ -1657,8 +1658,8 @@ static int sync_request (mddev_t *mddev,
 	 * nothing we can do.
 	 */
 	if (mddev->degraded >= 2 && test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) {
-		int rv = (mddev->size << 1) - sector_nr;
-		md_done_sync(mddev, rv, 1);
+		sector_t rv = (mddev->size << 1) - sector_nr;
+		*skipped = 1;
 		return rv;
 	}
 
@@ -1705,7 +1706,6 @@ static void raid6d (mddev_t *mddev)
 	PRINTK("+++ raid6d active\n");
 
 	md_check_recovery(mddev);
-	md_handle_safemode(mddev);
 
 	handled = 0;
 	spin_lock_irq(&conf->device_lock);
@@ -1813,6 +1813,7 @@ static int run (mddev_t *mddev)
 
 	/* device size must be a multiple of chunk size */
 	mddev->size &= ~(mddev->chunk_size/1024 -1);
+	mddev->resync_max_sectors = mddev->size << 1;
 
 	if (conf->raid_disks < 4) {
 		printk(KERN_ERR "raid6: not enough configured devices for %s (%d, minimum 4)\n",
@@ -2095,6 +2096,7 @@ static int raid6_resize(mddev_t *mddev, 
 		set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
 	}
 	mddev->size = sectors /2;
+	mddev->resync_max_sectors = sectors;
 	return 0;
 }
 
diff --git a/drivers/media/common/ir-common.c b/drivers/media/common/ir-common.c
--- a/drivers/media/common/ir-common.c
+++ b/drivers/media/common/ir-common.c
@@ -1,5 +1,5 @@
 /*
- * $Id: ir-common.c,v 1.8 2005/02/22 12:28:40 kraxel Exp $
+ * $Id: ir-common.c,v 1.11 2005/07/07 14:44:43 mchehab Exp $
  *
  * some common structs and functions to handle infrared remotes via
  * input layer ...
@@ -46,79 +46,49 @@ module_param(debug, int, 0644);
 /* see http://users.pandora.be/nenya/electronics/rc5/codes00.htm */
 /* used by old (black) Hauppauge remotes                         */
 IR_KEYTAB_TYPE ir_codes_rc5_tv[IR_KEYTAB_SIZE] = {
-	[ 0x00 ] = KEY_KP0,             // 0
-	[ 0x01 ] = KEY_KP1,             // 1
-	[ 0x02 ] = KEY_KP2,             // 2
-	[ 0x03 ] = KEY_KP3,             // 3
-	[ 0x04 ] = KEY_KP4,             // 4
-	[ 0x05 ] = KEY_KP5,             // 5
-	[ 0x06 ] = KEY_KP6,             // 6
-	[ 0x07 ] = KEY_KP7,             // 7
-	[ 0x08 ] = KEY_KP8,             // 8
-	[ 0x09 ] = KEY_KP9,             // 9
-
-	[ 0x0b ] = KEY_CHANNEL,         // channel / program (japan: 11)
-	[ 0x0c ] = KEY_POWER,           // standby
-	[ 0x0d ] = KEY_MUTE,            // mute / demute
-	[ 0x0f ] = KEY_TV,              // display
-	[ 0x10 ] = KEY_VOLUMEUP,        // volume +
-	[ 0x11 ] = KEY_VOLUMEDOWN,      // volume -
-	[ 0x12 ] = KEY_BRIGHTNESSUP,    // brightness +
-	[ 0x13 ] = KEY_BRIGHTNESSDOWN,  // brightness -
-	[ 0x1e ] = KEY_SEARCH,          // search +
-	[ 0x20 ] = KEY_CHANNELUP,       // channel / program +
-	[ 0x21 ] = KEY_CHANNELDOWN,     // channel / program -
-	[ 0x22 ] = KEY_CHANNEL,         // alt / channel
-	[ 0x23 ] = KEY_LANGUAGE,        // 1st / 2nd language
-	[ 0x26 ] = KEY_SLEEP,           // sleeptimer
-	[ 0x2e ] = KEY_MENU,            // 2nd controls (USA: menu)
-	[ 0x30 ] = KEY_PAUSE,           // pause
-	[ 0x32 ] = KEY_REWIND,          // rewind
-	[ 0x33 ] = KEY_GOTO,            // go to
-	[ 0x35 ] = KEY_PLAY,            // play
-	[ 0x36 ] = KEY_STOP,            // stop
-	[ 0x37 ] = KEY_RECORD,          // recording
-	[ 0x3c ] = KEY_TEXT,            // teletext submode (Japan: 12)
-	[ 0x3d ] = KEY_SUSPEND,         // system standby
-
-#if 0 /* FIXME */
-	[ 0x0a ] = KEY_RESERVED,        // 1/2/3 digits (japan: 10)
-	[ 0x0e ] = KEY_RESERVED,        // P.P. (personal preference)
-	[ 0x14 ] = KEY_RESERVED,        // colour saturation +
-	[ 0x15 ] = KEY_RESERVED,        // colour saturation -
-	[ 0x16 ] = KEY_RESERVED,        // bass +
-	[ 0x17 ] = KEY_RESERVED,        // bass -
-	[ 0x18 ] = KEY_RESERVED,        // treble +
-	[ 0x19 ] = KEY_RESERVED,        // treble -
-	[ 0x1a ] = KEY_RESERVED,        // balance right
-	[ 0x1b ] = KEY_RESERVED,        // balance left
-	[ 0x1c ] = KEY_RESERVED,        // contrast +
-	[ 0x1d ] = KEY_RESERVED,        // contrast -
-	[ 0x1f ] = KEY_RESERVED,        // tint/hue +
-	[ 0x24 ] = KEY_RESERVED,        // spacial stereo on/off
-	[ 0x25 ] = KEY_RESERVED,        // mono / stereo (USA)
-	[ 0x27 ] = KEY_RESERVED,        // tint / hue -
-	[ 0x28 ] = KEY_RESERVED,        // RF switch/PIP select
-	[ 0x29 ] = KEY_RESERVED,        // vote
-	[ 0x2a ] = KEY_RESERVED,        // timed page/channel clck
-	[ 0x2b ] = KEY_RESERVED,        // increment (USA)
-	[ 0x2c ] = KEY_RESERVED,        // decrement (USA)
-	[ 0x2d ] = KEY_RESERVED,        //
-	[ 0x2f ] = KEY_RESERVED,        // PIP shift
-	[ 0x31 ] = KEY_RESERVED,        // erase
-	[ 0x34 ] = KEY_RESERVED,        // wind
-	[ 0x38 ] = KEY_RESERVED,        // external 1
-	[ 0x39 ] = KEY_RESERVED,        // external 2
-	[ 0x3a ] = KEY_RESERVED,        // PIP display mode
-	[ 0x3b ] = KEY_RESERVED,        // view data mode / advance
-	[ 0x3e ] = KEY_RESERVED,        // crispener on/off
-	[ 0x3f ] = KEY_RESERVED,        // system select
-#endif
+	/* Keys 0 to 9 */
+	[ 0x00 ] = KEY_KP0,
+	[ 0x01 ] = KEY_KP1,
+	[ 0x02 ] = KEY_KP2,
+	[ 0x03 ] = KEY_KP3,
+	[ 0x04 ] = KEY_KP4,
+	[ 0x05 ] = KEY_KP5,
+	[ 0x06 ] = KEY_KP6,
+	[ 0x07 ] = KEY_KP7,
+	[ 0x08 ] = KEY_KP8,
+	[ 0x09 ] = KEY_KP9,
+
+	[ 0x0b ] = KEY_CHANNEL,		/* channel / program (japan: 11) */
+	[ 0x0c ] = KEY_POWER,		/* standby */
+	[ 0x0d ] = KEY_MUTE,		/* mute / demute */
+	[ 0x0f ] = KEY_TV,		/* display */
+	[ 0x10 ] = KEY_VOLUMEUP,
+	[ 0x11 ] = KEY_VOLUMEDOWN,
+	[ 0x12 ] = KEY_BRIGHTNESSUP,
+	[ 0x13 ] = KEY_BRIGHTNESSDOWN,
+	[ 0x1e ] = KEY_SEARCH,		/* search + */
+	[ 0x20 ] = KEY_CHANNELUP,	/* channel / program + */
+	[ 0x21 ] = KEY_CHANNELDOWN,	/* channel / program - */
+	[ 0x22 ] = KEY_CHANNEL,		/* alt / channel */
+	[ 0x23 ] = KEY_LANGUAGE,	/* 1st / 2nd language */
+	[ 0x26 ] = KEY_SLEEP,		/* sleeptimer */
+	[ 0x2e ] = KEY_MENU,		/* 2nd controls (USA: menu) */
+	[ 0x30 ] = KEY_PAUSE,
+	[ 0x32 ] = KEY_REWIND,
+	[ 0x33 ] = KEY_GOTO,
+	[ 0x35 ] = KEY_PLAY,
+	[ 0x36 ] = KEY_STOP,
+	[ 0x37 ] = KEY_RECORD,		/* recording */
+	[ 0x3c ] = KEY_TEXT,    	/* teletext submode (Japan: 12) */
+	[ 0x3d ] = KEY_SUSPEND,		/* system standby */
+
 };
 EXPORT_SYMBOL_GPL(ir_codes_rc5_tv);
 
 /* Table for Leadtek Winfast Remote Controls - used by both bttv and cx88 */
 IR_KEYTAB_TYPE ir_codes_winfast[IR_KEYTAB_SIZE] = {
+	/* Keys 0 to 9 */
+	[ 18 ] = KEY_KP0,
 	[  5 ] = KEY_KP1,
 	[  6 ] = KEY_KP2,
 	[  7 ] = KEY_KP3,
@@ -128,39 +98,31 @@ IR_KEYTAB_TYPE ir_codes_winfast[IR_KEYTA
 	[ 13 ] = KEY_KP7,
 	[ 14 ] = KEY_KP8,
 	[ 15 ] = KEY_KP9,
-	[ 18 ] = KEY_KP0,
 
 	[  0 ] = KEY_POWER,
-	[ 27 ] = KEY_LANGUAGE,  //MTS button
-	[  2 ] = KEY_TUNER,     // TV/FM
+	[  2 ] = KEY_TUNER,		/* TV/FM */
 	[ 30 ] = KEY_VIDEO,
-	[ 22 ] = KEY_INFO,      //display button
 	[  4 ] = KEY_VOLUMEUP,
 	[  8 ] = KEY_VOLUMEDOWN,
 	[ 12 ] = KEY_CHANNELUP,
 	[ 16 ] = KEY_CHANNELDOWN,
-	[  3 ] = KEY_ZOOM,      // fullscreen
-	[ 31 ] = KEY_SUBTITLE,  // closed caption/teletext
+	[  3 ] = KEY_ZOOM,		/* fullscreen */
+	[ 31 ] = KEY_SUBTITLE,		/* closed caption/teletext */
 	[ 32 ] = KEY_SLEEP,
-	[ 41 ] = KEY_SEARCH,    //boss key
 	[ 20 ] = KEY_MUTE,
 	[ 43 ] = KEY_RED,
 	[ 44 ] = KEY_GREEN,
 	[ 45 ] = KEY_YELLOW,
 	[ 46 ] = KEY_BLUE,
-	[ 24 ] = KEY_KPPLUS,    //fine tune +
-	[ 25 ] = KEY_KPMINUS,   //fine tune -
-	[ 42 ] = KEY_ANGLE,     //picture in picture
-	[ 33 ] = KEY_KPDOT,
+	[ 24 ] = KEY_KPPLUS,		/* fine tune + */
+	[ 25 ] = KEY_KPMINUS,		/* fine tune - */
+        [ 33 ] = KEY_KPDOT,
 	[ 19 ] = KEY_KPENTER,
-	[ 17 ] = KEY_AGAIN,     //recall
 	[ 34 ] = KEY_BACK,
 	[ 35 ] = KEY_PLAYPAUSE,
 	[ 36 ] = KEY_NEXT,
-	[ 37 ] = KEY_T,         //time shifting
 	[ 38 ] = KEY_STOP,
-	[ 39 ] = KEY_RECORD,
-	[ 40 ] = KEY_SHUFFLE    //snapshot
+	[ 39 ] = KEY_RECORD
 };
 EXPORT_SYMBOL_GPL(ir_codes_winfast);
 
@@ -174,45 +136,97 @@ EXPORT_SYMBOL_GPL(ir_codes_empty);
  * slightly different versions), shipped with cx88+ivtv cards.
  * almost rc5 coding, but some non-standard keys */
 IR_KEYTAB_TYPE ir_codes_hauppauge_new[IR_KEYTAB_SIZE] = {
-	[ 0x00 ] = KEY_KP0,             // 0
-	[ 0x01 ] = KEY_KP1,             // 1
-	[ 0x02 ] = KEY_KP2,             // 2
-	[ 0x03 ] = KEY_KP3,             // 3
-	[ 0x04 ] = KEY_KP4,             // 4
-	[ 0x05 ] = KEY_KP5,             // 5
-	[ 0x06 ] = KEY_KP6,             // 6
-	[ 0x07 ] = KEY_KP7,             // 7
-	[ 0x08 ] = KEY_KP8,             // 8
-	[ 0x09 ] = KEY_KP9,             // 9
-	[ 0x0b ] = KEY_RED,             // red button
-	[ 0x0c ] = KEY_OPTION,          // black key without text
-	[ 0x0d ] = KEY_MENU,            // menu
-	[ 0x0f ] = KEY_MUTE,            // mute
-	[ 0x10 ] = KEY_VOLUMEUP,        // volume +
-	[ 0x11 ] = KEY_VOLUMEDOWN,      // volume -
-	[ 0x1e ] = KEY_NEXT,            // skip >|
-	[ 0x1f ] = KEY_EXIT,            // back/exit
-	[ 0x20 ] = KEY_CHANNELUP,       // channel / program +
-	[ 0x21 ] = KEY_CHANNELDOWN,     // channel / program -
-	[ 0x22 ] = KEY_CHANNEL,         // source (old black remote)
-	[ 0x24 ] = KEY_PREVIOUS,        // replay |<
-	[ 0x25 ] = KEY_ENTER,           // OK
-	[ 0x26 ] = KEY_SLEEP,           // minimize (old black remote)
-	[ 0x29 ] = KEY_BLUE,            // blue key
-	[ 0x2e ] = KEY_GREEN,           // green button
-	[ 0x30 ] = KEY_PAUSE,           // pause
-	[ 0x32 ] = KEY_REWIND,          // backward <<
-	[ 0x34 ] = KEY_FASTFORWARD,     // forward >>
-	[ 0x35 ] = KEY_PLAY,            // play
-	[ 0x36 ] = KEY_STOP,            // stop
-	[ 0x37 ] = KEY_RECORD,          // recording
-	[ 0x38 ] = KEY_YELLOW,          // yellow key
-	[ 0x3b ] = KEY_SELECT,          // top right button
-	[ 0x3c ] = KEY_ZOOM,            // full
-	[ 0x3d ] = KEY_POWER,           // system power (green button)
+	/* Keys 0 to 9 */
+	[ 0x00 ] = KEY_KP0,
+	[ 0x01 ] = KEY_KP1,
+	[ 0x02 ] = KEY_KP2,
+	[ 0x03 ] = KEY_KP3,
+	[ 0x04 ] = KEY_KP4,
+	[ 0x05 ] = KEY_KP5,
+	[ 0x06 ] = KEY_KP6,
+	[ 0x07 ] = KEY_KP7,
+	[ 0x08 ] = KEY_KP8,
+	[ 0x09 ] = KEY_KP9,
+
+	[ 0x0a ] = KEY_TEXT,      	/* keypad asterisk as well */
+	[ 0x0b ] = KEY_RED,		/* red button */
+	[ 0x0c ] = KEY_RADIO,
+	[ 0x0d ] = KEY_MENU,
+	[ 0x0e ] = KEY_SUBTITLE,	/* also the # key */
+	[ 0x0f ] = KEY_MUTE,
+	[ 0x10 ] = KEY_VOLUMEUP,
+	[ 0x11 ] = KEY_VOLUMEDOWN,
+	[ 0x12 ] = KEY_PREVIOUS,	/* previous channel */
+	[ 0x14 ] = KEY_UP,
+	[ 0x15 ] = KEY_DOWN,
+	[ 0x16 ] = KEY_LEFT,
+	[ 0x17 ] = KEY_RIGHT,
+	[ 0x18 ] = KEY_VIDEO,		/* Videos */
+	[ 0x19 ] = KEY_AUDIO,		/* Music */
+	/* 0x1a: Pictures - presume this means
+	   "Multimedia Home Platform" -
+	   no "PICTURES" key in input.h
+	 */
+	[ 0x1a ] = KEY_MHP,
+
+	[ 0x1b ] = KEY_EPG,		/* Guide */
+	[ 0x1c ] = KEY_TV,
+	[ 0x1e ] = KEY_NEXTSONG,	/* skip >| */
+	[ 0x1f ] = KEY_EXIT,		/* back/exit */
+	[ 0x20 ] = KEY_CHANNELUP,	/* channel / program + */
+	[ 0x21 ] = KEY_CHANNELDOWN,	/* channel / program - */
+	[ 0x22 ] = KEY_CHANNEL,		/* source (old black remote) */
+	[ 0x24 ] = KEY_PREVIOUSSONG,	/* replay |< */
+	[ 0x25 ] = KEY_ENTER,		/* OK */
+	[ 0x26 ] = KEY_SLEEP,		/* minimize (old black remote) */
+	[ 0x29 ] = KEY_BLUE,		/* blue key */
+	[ 0x2e ] = KEY_GREEN,		/* green button */
+	[ 0x30 ] = KEY_PAUSE,		/* pause */
+	[ 0x32 ] = KEY_REWIND,		/* backward << */
+	[ 0x34 ] = KEY_FASTFORWARD,	/* forward >> */
+	[ 0x35 ] = KEY_PLAY,
+	[ 0x36 ] = KEY_STOP,
+	[ 0x37 ] = KEY_RECORD,		/* recording */
+	[ 0x38 ] = KEY_YELLOW,		/* yellow key */
+	[ 0x3b ] = KEY_SELECT,		/* top right button */
+	[ 0x3c ] = KEY_ZOOM,		/* full */
+	[ 0x3d ] = KEY_POWER,		/* system power (green button) */
 };
 EXPORT_SYMBOL(ir_codes_hauppauge_new);
 
+IR_KEYTAB_TYPE ir_codes_pixelview[IR_KEYTAB_SIZE] = {
+	[  2 ] = KEY_KP0,
+	[  1 ] = KEY_KP1,
+	[ 11 ] = KEY_KP2,
+	[ 27 ] = KEY_KP3,
+	[  5 ] = KEY_KP4,
+	[  9 ] = KEY_KP5,
+	[ 21 ] = KEY_KP6,
+	[  6 ] = KEY_KP7,
+	[ 10 ] = KEY_KP8,
+	[ 18 ] = KEY_KP9,
+
+	[  3 ] = KEY_TUNER,		/* TV/FM */
+	[  7 ] = KEY_SEARCH,		/* scan */
+	[ 28 ] = KEY_ZOOM,		/* full screen */
+	[ 30 ] = KEY_POWER,
+	[ 23 ] = KEY_VOLUMEDOWN,
+	[ 31 ] = KEY_VOLUMEUP,
+	[ 20 ] = KEY_CHANNELDOWN,
+	[ 22 ] = KEY_CHANNELUP,
+	[ 24 ] = KEY_MUTE,
+
+	[  0 ] = KEY_LIST,		/* source */
+	[ 19 ] = KEY_INFO,		/* loop */
+	[ 16 ] = KEY_LAST,		/* +100 */
+	[ 13 ] = KEY_CLEAR,		/* reset */
+	[ 12 ] = BTN_RIGHT,		/* fun++ */
+	[  4 ] = BTN_LEFT,		/* fun-- */
+	[ 14 ] = KEY_GOTO,		/* function */
+	[ 15 ] = KEY_STOP,		/* freeze */
+};
+EXPORT_SYMBOL(ir_codes_pixelview);
+
 /* -------------------------------------------------------------------------- */
 
 static void ir_input_key_event(struct input_dev *dev, struct ir_input_state *ir)
@@ -276,10 +290,6 @@ void ir_input_keydown(struct input_dev *
 		ir->keypressed = 1;
 		ir_input_key_event(dev,ir);
 	}
-#if 0
-	/* maybe do something like this ??? */
-	input_event(a, EV_IR, ir->ir_type, ir->ir_raw);
-#endif
 }
 
 /* -------------------------------------------------------------------------- */
@@ -379,3 +389,4 @@ EXPORT_SYMBOL_GPL(ir_decode_biphase);
  * c-basic-offset: 8
  * End:
  */
+
diff --git a/drivers/media/common/saa7146_core.c b/drivers/media/common/saa7146_core.c
--- a/drivers/media/common/saa7146_core.c
+++ b/drivers/media/common/saa7146_core.c
@@ -62,13 +62,15 @@ void saa7146_setgpio(struct saa7146_dev 
 int saa7146_wait_for_debi_done(struct saa7146_dev *dev, int nobusyloop)
 {
 	unsigned long start;
+	int err;
 
 	/* wait for registers to be programmed */
 	start = jiffies;
 	while (1) {
-                if (saa7146_read(dev, MC2) & 2)
-                        break;
-		if (time_after(jiffies, start + HZ/20)) {
+		err = time_after(jiffies, start + HZ/20);
+		if (saa7146_read(dev, MC2) & 2)
+			break;
+		if (err) {
 			DEB_S(("timed out while waiting for registers getting programmed\n"));
 			return -ETIMEDOUT;
 		}
@@ -79,10 +81,11 @@ int saa7146_wait_for_debi_done(struct sa
 	/* wait for transfer to complete */
 	start = jiffies;
 	while (1) {
+		err = time_after(jiffies, start + HZ/4);
 		if (!(saa7146_read(dev, PSR) & SPCI_DEBI_S))
 			break;
 		saa7146_read(dev, MC2);
-		if (time_after(jiffies, start + HZ/4)) {
+		if (err) {
 			DEB_S(("timed out while waiting for transfer completion\n"));
 			return -ETIMEDOUT;
 		}
@@ -512,7 +515,7 @@ int saa7146_register_extension(struct sa
 	ext->driver.remove = saa7146_remove_one;
 
 	printk("saa7146: register extension '%s'.\n",ext->name);
-	return pci_module_init(&ext->driver);
+	return pci_register_driver(&ext->driver);
 }
 
 int saa7146_unregister_extension(struct saa7146_extension* ext)
diff --git a/drivers/media/common/saa7146_fops.c b/drivers/media/common/saa7146_fops.c
--- a/drivers/media/common/saa7146_fops.c
+++ b/drivers/media/common/saa7146_fops.c
@@ -403,7 +403,7 @@ static struct file_operations video_fops
 	.llseek		= no_llseek,
 };
 
-void vv_callback(struct saa7146_dev *dev, unsigned long status)
+static void vv_callback(struct saa7146_dev *dev, unsigned long status)
 {
 	u32 isr = status;
 	
diff --git a/drivers/media/dvb/Kconfig b/drivers/media/dvb/Kconfig
--- a/drivers/media/dvb/Kconfig
+++ b/drivers/media/dvb/Kconfig
@@ -27,9 +27,9 @@ source "drivers/media/dvb/ttpci/Kconfig"
 
 comment "Supported USB Adapters"
 	depends on DVB_CORE && USB
+source "drivers/media/dvb/dvb-usb/Kconfig"
 source "drivers/media/dvb/ttusb-budget/Kconfig"
 source "drivers/media/dvb/ttusb-dec/Kconfig"
-source "drivers/media/dvb/dibusb/Kconfig"
 source "drivers/media/dvb/cinergyT2/Kconfig"
 
 comment "Supported FlexCopII (B2C2) Adapters"
@@ -40,6 +40,10 @@ comment "Supported BT878 Adapters"
 	depends on DVB_CORE && PCI
 source "drivers/media/dvb/bt8xx/Kconfig"
 
+comment "Supported Pluto2 Adapters"
+	depends on DVB_CORE && PCI
+source "drivers/media/dvb/pluto2/Kconfig"
+
 comment "Supported DVB Frontends"
 	depends on DVB_CORE
 source "drivers/media/dvb/frontends/Kconfig"
diff --git a/drivers/media/dvb/Makefile b/drivers/media/dvb/Makefile
--- a/drivers/media/dvb/Makefile
+++ b/drivers/media/dvb/Makefile
@@ -2,4 +2,4 @@
 # Makefile for the kernel multimedia device drivers.
 #
 
-obj-y        := dvb-core/ frontends/ ttpci/ ttusb-dec/ ttusb-budget/ b2c2/ bt8xx/ dibusb/ cinergyT2/
+obj-y        := dvb-core/ frontends/ ttpci/ ttusb-dec/ ttusb-budget/ b2c2/ bt8xx/ cinergyT2/ dvb-usb/ pluto2/
diff --git a/drivers/media/dvb/b2c2/Kconfig b/drivers/media/dvb/b2c2/Kconfig
--- a/drivers/media/dvb/b2c2/Kconfig
+++ b/drivers/media/dvb/b2c2/Kconfig
@@ -6,6 +6,7 @@ config DVB_B2C2_FLEXCOP
 	select DVB_MT312
 	select DVB_NXT2002
 	select DVB_STV0297
+	select DVB_BCM3510
 	help
 	  Support for the digital TV receiver chip made by B2C2 Inc. included in
 	  Technisats PCI cards and USB boxes.
@@ -34,17 +35,3 @@ config DVB_B2C2_FLEXCOP_DEBUG
 	help
 	  Say Y if you want to enable the module option to control debug messages
 	  of all B2C2 FlexCop drivers.
-
-config DVB_B2C2_SKYSTAR
-	tristate "B2C2/Technisat Air/Sky/CableStar 2 PCI"
-	depends on DVB_CORE && PCI
-	select DVB_STV0299
-	select DVB_MT352
-	select DVB_MT312
-	select DVB_NXT2002
-	help
-	  Support for the Skystar2 PCI DVB card by Technisat, which
-	  is equipped with the FlexCopII chipset by B2C2, and
-	  for the B2C2/BBTI Air2PC-ATSC card.
-
-	  Say Y if you own such a device and want to use it.
diff --git a/drivers/media/dvb/b2c2/Makefile b/drivers/media/dvb/b2c2/Makefile
--- a/drivers/media/dvb/b2c2/Makefile
+++ b/drivers/media/dvb/b2c2/Makefile
@@ -9,6 +9,4 @@ obj-$(CONFIG_DVB_B2C2_FLEXCOP_PCI) += b2
 b2c2-flexcop-usb-objs = flexcop-usb.o
 obj-$(CONFIG_DVB_B2C2_FLEXCOP_USB) += b2c2-flexcop-usb.o
 
-obj-$(CONFIG_DVB_B2C2_SKYSTAR) += skystar2.o
-
 EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
diff --git a/drivers/media/dvb/b2c2/flexcop-common.h b/drivers/media/dvb/b2c2/flexcop-common.h
--- a/drivers/media/dvb/b2c2/flexcop-common.h
+++ b/drivers/media/dvb/b2c2/flexcop-common.h
@@ -108,6 +108,8 @@ void flexcop_device_kfree(struct flexcop
 int  flexcop_device_initialize(struct flexcop_device*);
 void flexcop_device_exit(struct flexcop_device *fc);
 
+void flexcop_reset_block_300(struct flexcop_device *fc);
+
 /* from flexcop-dma.c */
 int flexcop_dma_allocate(struct pci_dev *pdev, struct flexcop_dma *dma, u32 size);
 void flexcop_dma_free(struct flexcop_dma *dma);
@@ -115,7 +117,8 @@ void flexcop_dma_free(struct flexcop_dma
 int flexcop_dma_control_timer_irq(struct flexcop_device *fc, flexcop_dma_index_t no, int onoff);
 int flexcop_dma_control_size_irq(struct flexcop_device *fc, flexcop_dma_index_t no, int onoff);
 int flexcop_dma_control_packet_irq(struct flexcop_device *fc, flexcop_dma_index_t no, int onoff);
-int flexcop_dma_config(struct flexcop_device *fc, struct flexcop_dma *dma, flexcop_dma_index_t dma_idx,flexcop_dma_addr_index_t index);
+int flexcop_dma_config(struct flexcop_device *fc, struct flexcop_dma *dma, flexcop_dma_index_t dma_idx);
+int flexcop_dma_xfer_control(struct flexcop_device *fc, flexcop_dma_index_t dma_idx, flexcop_dma_addr_index_t index, int onoff);
 int flexcop_dma_config_timer(struct flexcop_device *fc, flexcop_dma_index_t dma_idx, u8 cycles);
 int flexcop_dma_config_packet_count(struct flexcop_device *fc, flexcop_dma_index_t dma_idx, u8 packets);
 
@@ -151,6 +154,7 @@ int flexcop_sram_init(struct flexcop_dev
 /* from flexcop-misc.c */
 void flexcop_determine_revision(struct flexcop_device *fc);
 void flexcop_device_name(struct flexcop_device *fc,const char *prefix,const char *suffix);
+void flexcop_dump_reg(struct flexcop_device *fc, flexcop_ibi_register reg, int num);
 
 /* from flexcop-hw-filter.c */
 int flexcop_pid_feed_control(struct flexcop_device *fc, struct dvb_demux_feed *dvbdmxfeed, int onoff);
diff --git a/drivers/media/dvb/b2c2/flexcop-dma.c b/drivers/media/dvb/b2c2/flexcop-dma.c
--- a/drivers/media/dvb/b2c2/flexcop-dma.c
+++ b/drivers/media/dvb/b2c2/flexcop-dma.c
@@ -37,22 +37,90 @@ void flexcop_dma_free(struct flexcop_dma
 }
 EXPORT_SYMBOL(flexcop_dma_free);
 
-int flexcop_dma_control_timer_irq(struct flexcop_device *fc, flexcop_dma_index_t no, int onoff)
+int flexcop_dma_config(struct flexcop_device *fc,
+		struct flexcop_dma *dma,
+		flexcop_dma_index_t dma_idx)
 {
-	flexcop_ibi_value v = fc->read_ibi_reg(fc,ctrl_208);
+	flexcop_ibi_value v0x0,v0x4,v0xc;
+	v0x0.raw = v0x4.raw = v0xc.raw = 0;
 
-	if (no & FC_DMA_1)
-		v.ctrl_208.DMA1_Timer_Enable_sig = onoff;
+	v0x0.dma_0x0.dma_address0        = dma->dma_addr0 >> 2;
+	v0xc.dma_0xc.dma_address1        = dma->dma_addr1 >> 2;
+	v0x4.dma_0x4_write.dma_addr_size = dma->size / 4;
 
-	if (no & FC_DMA_2)
-		v.ctrl_208.DMA2_Timer_Enable_sig = onoff;
+	if ((dma_idx & FC_DMA_1) == dma_idx) {
+		fc->write_ibi_reg(fc,dma1_000,v0x0);
+		fc->write_ibi_reg(fc,dma1_004,v0x4);
+		fc->write_ibi_reg(fc,dma1_00c,v0xc);
+	} else if ((dma_idx & FC_DMA_2) == dma_idx) {
+		fc->write_ibi_reg(fc,dma2_010,v0x0);
+		fc->write_ibi_reg(fc,dma2_014,v0x4);
+		fc->write_ibi_reg(fc,dma2_01c,v0xc);
+	} else {
+		err("either DMA1 or DMA2 can be configured at the within one flexcop_dma_config call.");
+		return -EINVAL;
+	}
 
-	fc->write_ibi_reg(fc,ctrl_208,v);
 	return 0;
 }
-EXPORT_SYMBOL(flexcop_dma_control_timer_irq);
+EXPORT_SYMBOL(flexcop_dma_config);
+
+/* start the DMA transfers, but not the DMA IRQs */
+int flexcop_dma_xfer_control(struct flexcop_device *fc,
+		flexcop_dma_index_t dma_idx,
+		flexcop_dma_addr_index_t index,
+		int onoff)
+{
+	flexcop_ibi_value v0x0,v0xc;
+	flexcop_ibi_register r0x0,r0xc;
+
+	if ((dma_idx & FC_DMA_1) == dma_idx) {
+		r0x0 = dma1_000;
+		r0xc = dma1_00c;
+	} else if ((dma_idx & FC_DMA_2) == dma_idx) {
+		r0x0 = dma2_010;
+		r0xc = dma2_01c;
+	} else {
+		err("either transfer DMA1 or DMA2 can be started within one flexcop_dma_xfer_control call.");
+		return -EINVAL;
+	}
+
+	v0x0 = fc->read_ibi_reg(fc,r0x0);
+	v0xc = fc->read_ibi_reg(fc,r0xc);
 
-int flexcop_dma_control_size_irq(struct flexcop_device *fc, flexcop_dma_index_t no, int onoff)
+	deb_rdump("reg: %03x: %x\n",r0x0,v0x0.raw);
+	deb_rdump("reg: %03x: %x\n",r0xc,v0xc.raw);
+
+	if (index & FC_DMA_SUBADDR_0)
+		v0x0.dma_0x0.dma_0start = onoff;
+
+	if (index & FC_DMA_SUBADDR_1)
+		v0xc.dma_0xc.dma_1start = onoff;
+
+	fc->write_ibi_reg(fc,r0x0,v0x0);
+	fc->write_ibi_reg(fc,r0xc,v0xc);
+
+	deb_rdump("reg: %03x: %x\n",r0x0,v0x0.raw);
+	deb_rdump("reg: %03x: %x\n",r0xc,v0xc.raw);
+	return 0;
+}
+EXPORT_SYMBOL(flexcop_dma_xfer_control);
+
+static int flexcop_dma_remap(struct flexcop_device *fc,
+		flexcop_dma_index_t dma_idx,
+		int onoff)
+{
+	flexcop_ibi_register r = (dma_idx & FC_DMA_1) ? dma1_00c : dma2_01c;
+	flexcop_ibi_value v = fc->read_ibi_reg(fc,r);
+	deb_info("%s\n",__FUNCTION__);
+	v.dma_0xc.remap_enable = onoff;
+	fc->write_ibi_reg(fc,r,v);
+	return 0;
+}
+
+int flexcop_dma_control_size_irq(struct flexcop_device *fc,
+		flexcop_dma_index_t no,
+		int onoff)
 {
 	flexcop_ibi_value v = fc->read_ibi_reg(fc,ctrl_208);
 
@@ -67,75 +135,64 @@ int flexcop_dma_control_size_irq(struct 
 }
 EXPORT_SYMBOL(flexcop_dma_control_size_irq);
 
-int flexcop_dma_control_packet_irq(struct flexcop_device *fc, flexcop_dma_index_t no, int onoff)
+int flexcop_dma_control_timer_irq(struct flexcop_device *fc,
+		flexcop_dma_index_t no,
+		int onoff)
 {
 	flexcop_ibi_value v = fc->read_ibi_reg(fc,ctrl_208);
 
 	if (no & FC_DMA_1)
-		v.ctrl_208.DMA1_Size_IRQ_Enable_sig = onoff;
+		v.ctrl_208.DMA1_Timer_Enable_sig = onoff;
 
 	if (no & FC_DMA_2)
-		v.ctrl_208.DMA2_Size_IRQ_Enable_sig = onoff;
+		v.ctrl_208.DMA2_Timer_Enable_sig = onoff;
 
 	fc->write_ibi_reg(fc,ctrl_208,v);
 	return 0;
 }
-EXPORT_SYMBOL(flexcop_dma_control_packet_irq);
+EXPORT_SYMBOL(flexcop_dma_control_timer_irq);
 
-int flexcop_dma_config(struct flexcop_device *fc, struct flexcop_dma *dma, flexcop_dma_index_t dma_idx,flexcop_dma_addr_index_t index)
+/* 1 cycles = 1.97 msec */
+int flexcop_dma_config_timer(struct flexcop_device *fc,
+		flexcop_dma_index_t dma_idx,
+		u8 cycles)
 {
+	flexcop_ibi_register r = (dma_idx & FC_DMA_1) ? dma1_004 : dma2_014;
+	flexcop_ibi_value v = fc->read_ibi_reg(fc,r);
 
-	flexcop_ibi_value v0x0,v0x4,v0xc;
-	v0x0.raw = v0x4.raw = v0xc.raw = 0;
-
-	v0x0.dma_0x0.dma_address0        = dma->dma_addr0 >> 2;
-	v0xc.dma_0xc.dma_address1        = dma->dma_addr1 >> 2;
-	v0x4.dma_0x4_write.dma_addr_size = dma->size / 4;
-
-	if (index & FC_DMA_SUBADDR_0)
-		v0x0.dma_0x0.dma_0start = 1;
-
-	if (index & FC_DMA_SUBADDR_1)
-		v0xc.dma_0xc.dma_1start = 1;
-
-	if (dma_idx & FC_DMA_1) {
-		fc->write_ibi_reg(fc,dma1_000,v0x0);
-		fc->write_ibi_reg(fc,dma1_004,v0x4);
-		fc->write_ibi_reg(fc,dma1_00c,v0xc);
-	} else { /* (dma_idx & FC_DMA_2) */
-		fc->write_ibi_reg(fc,dma2_010,v0x0);
-		fc->write_ibi_reg(fc,dma2_014,v0x4);
-		fc->write_ibi_reg(fc,dma2_01c,v0xc);
-	}
-
-	return 0;
-}
-EXPORT_SYMBOL(flexcop_dma_config);
+	flexcop_dma_remap(fc,dma_idx,0);
 
-static int flexcop_dma_remap(struct flexcop_device *fc, flexcop_dma_index_t dma_idx, int onoff)
-{
-	flexcop_ibi_register r = (dma_idx & FC_DMA_1) ? dma1_00c : dma2_01c;
-	flexcop_ibi_value v = fc->read_ibi_reg(fc,r);
-	v.dma_0xc.remap_enable = onoff;
+	deb_info("%s\n",__FUNCTION__);
+	v.dma_0x4_write.dmatimer = cycles;
 	fc->write_ibi_reg(fc,r,v);
 	return 0;
 }
+EXPORT_SYMBOL(flexcop_dma_config_timer);
 
-/* 1 cycles = 1.97 msec */
-int flexcop_dma_config_timer(struct flexcop_device *fc, flexcop_dma_index_t dma_idx, u8 cycles)
+/* packet IRQ does not exist in FCII or FCIIb - according to data book and tests */
+int flexcop_dma_control_packet_irq(struct flexcop_device *fc,
+		flexcop_dma_index_t no,
+		int onoff)
 {
-	flexcop_ibi_register r = (dma_idx & FC_DMA_1) ? dma1_004 : dma2_014;
-	flexcop_ibi_value v = fc->read_ibi_reg(fc,r);
+	flexcop_ibi_value v = fc->read_ibi_reg(fc,ctrl_208);
 
-	flexcop_dma_remap(fc,dma_idx,0);
+	deb_rdump("reg: %03x: %x\n",ctrl_208,v.raw);
+	if (no & FC_DMA_1)
+		v.ctrl_208.DMA1_Size_IRQ_Enable_sig = onoff;
+
+	if (no & FC_DMA_2)
+		v.ctrl_208.DMA2_Size_IRQ_Enable_sig = onoff;
+
+	fc->write_ibi_reg(fc,ctrl_208,v);
+	deb_rdump("reg: %03x: %x\n",ctrl_208,v.raw);
 
-	v.dma_0x4_write.dmatimer = cycles >> 1;
-	fc->write_ibi_reg(fc,r,v);
 	return 0;
 }
-EXPORT_SYMBOL(flexcop_dma_config_timer);
+EXPORT_SYMBOL(flexcop_dma_control_packet_irq);
 
-int flexcop_dma_config_packet_count(struct flexcop_device *fc, flexcop_dma_index_t dma_idx, u8 packets)
+int flexcop_dma_config_packet_count(struct flexcop_device *fc,
+		flexcop_dma_index_t dma_idx,
+		u8 packets)
 {
 	flexcop_ibi_register r = (dma_idx & FC_DMA_1) ? dma1_004 : dma2_014;
 	flexcop_ibi_value v = fc->read_ibi_reg(fc,r);
diff --git a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
--- a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
+++ b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
@@ -10,6 +10,7 @@
 #include "stv0299.h"
 #include "mt352.h"
 #include "nxt2002.h"
+#include "bcm3510.h"
 #include "stv0297.h"
 #include "mt312.h"
 
@@ -285,21 +286,25 @@ static int samsung_tdtc9251dh0_pll_set(s
 }
 
 static struct mt352_config samsung_tdtc9251dh0_config = {
-
 	.demod_address = 0x0f,
-	.demod_init = samsung_tdtc9251dh0_demod_init,
-	.pll_set = samsung_tdtc9251dh0_pll_set,
+	.demod_init    = samsung_tdtc9251dh0_demod_init,
+	.pll_set       = samsung_tdtc9251dh0_pll_set,
 };
 
-static int nxt2002_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name)
+static int flexcop_fe_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name)
 {
 	struct flexcop_device *fc = fe->dvb->priv;
 	return request_firmware(fw, name, fc->dev);
 }
 
 static struct nxt2002_config samsung_tbmv_config = {
-	.demod_address = 0x0a,
-	.request_firmware = nxt2002_request_firmware,
+	.demod_address    = 0x0a,
+	.request_firmware = flexcop_fe_request_firmware,
+};
+
+static struct bcm3510_config air2pc_atsc_first_gen_config = {
+	.demod_address    = 0x0f,
+	.request_firmware = flexcop_fe_request_firmware,
 };
 
 static int skystar23_samsung_tbdu18132_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
@@ -354,11 +359,16 @@ int flexcop_frontend_init(struct flexcop
 		fc->dev_type          = FC_AIR_DVB;
 		info("found the mt352 at i2c address: 0x%02x",samsung_tdtc9251dh0_config.demod_address);
 	} else
-	/* try the air atsc (nxt2002) */
+	/* try the air atsc 2nd generation (nxt2002) */
 	if ((fc->fe = nxt2002_attach(&samsung_tbmv_config, &fc->i2c_adap)) != NULL) {
-		fc->dev_type          = FC_AIR_ATSC;
+		fc->dev_type          = FC_AIR_ATSC2;
 		info("found the nxt2002 at i2c address: 0x%02x",samsung_tbmv_config.demod_address);
 	} else
+	/* try the air atsc 1nd generation (bcm3510)/panasonic ct10s */
+	if ((fc->fe = bcm3510_attach(&air2pc_atsc_first_gen_config, &fc->i2c_adap)) != NULL) {
+		fc->dev_type          = FC_AIR_ATSC1;
+		info("found the bcm3510 at i2c address: 0x%02x",air2pc_atsc_first_gen_config.demod_address);
+	} else
 	/* try the cable dvb (stv0297) */
 	if ((fc->fe = stv0297_attach(&alps_tdee4_stv0297_config, &fc->i2c_adap, 0xf8)) != NULL) {
 		fc->dev_type                        = FC_CABLE;
diff --git a/drivers/media/dvb/b2c2/flexcop-hw-filter.c b/drivers/media/dvb/b2c2/flexcop-hw-filter.c
--- a/drivers/media/dvb/b2c2/flexcop-hw-filter.c
+++ b/drivers/media/dvb/b2c2/flexcop-hw-filter.c
@@ -10,6 +10,8 @@
 static void flexcop_rcv_data_ctrl(struct flexcop_device *fc, int onoff)
 {
 	flexcop_set_ibi_value(ctrl_208,Rcv_Data_sig,onoff);
+
+	deb_ts("rcv_data is now: '%s'\n",onoff ? "on" : "off");
 }
 
 void flexcop_smc_ctrl(struct flexcop_device *fc, int onoff)
@@ -151,7 +153,7 @@ int flexcop_pid_feed_control(struct flex
 {
 	int max_pid_filter = 6 + fc->has_32_hw_pid_filter*32;
 
-	fc->feedcount += onoff ? 1 : -1;
+	fc->feedcount += onoff ? 1 : -1; /* the number of PIDs/Feed currently requested */
 	if (dvbdmxfeed->index >= max_pid_filter)
 		fc->extra_feedcount += onoff ? 1 : -1;
 
@@ -178,8 +180,14 @@ int flexcop_pid_feed_control(struct flex
 	/* if it was the first or last feed request change the stream-status */
 	if (fc->feedcount == onoff) {
 		flexcop_rcv_data_ctrl(fc,onoff);
-		if (fc->stream_control)
+		if (fc->stream_control) /* device specific stream control */
 			fc->stream_control(fc,onoff);
+
+		/* feeding stopped -> reset the flexcop filter*/
+		if (onoff == 0) {
+			flexcop_reset_block_300(fc);
+			flexcop_hw_filter_init(fc);
+		}
 	}
 
 	return 0;
diff --git a/drivers/media/dvb/b2c2/flexcop-misc.c b/drivers/media/dvb/b2c2/flexcop-misc.c
--- a/drivers/media/dvb/b2c2/flexcop-misc.c
+++ b/drivers/media/dvb/b2c2/flexcop-misc.c
@@ -45,11 +45,12 @@ const char *flexcop_revision_names[] = {
 
 const char *flexcop_device_names[] = {
 	"Unkown device",
-	"AirStar 2 DVB-T",
-	"AirStar 2 ATSC",
-	"SkyStar 2 DVB-S",
-	"SkyStar 2 DVB-S (old version)",
-	"CableStar 2 DVB-C",
+	"Air2PC/AirStar 2 DVB-T",
+	"Air2PC/AirStar 2 ATSC 1st generation",
+	"Air2PC/AirStar 2 ATSC 2nd generation",
+	"Sky2PC/SkyStar 2 DVB-S",
+	"Sky2PC/SkyStar 2 DVB-S (old version)",
+	"Cable2PC/CableStar 2 DVB-C",
 };
 
 const char *flexcop_bus_names[] = {
@@ -64,3 +65,15 @@ void flexcop_device_name(struct flexcop_
 			flexcop_device_names[fc->dev_type],flexcop_bus_names[fc->bus_type],
 			flexcop_revision_names[fc->rev],suffix);
 }
+
+void flexcop_dump_reg(struct flexcop_device *fc, flexcop_ibi_register reg, int num)
+{
+	flexcop_ibi_value v;
+	int i;
+	for (i = 0; i < num; i++) {
+		v = fc->read_ibi_reg(fc,reg+4*i);
+		deb_rdump("0x%03x: %08x, ",reg+4*i, v.raw);
+	}
+	deb_rdump("\n");
+}
+EXPORT_SYMBOL(flexcop_dump_reg);
diff --git a/drivers/media/dvb/b2c2/flexcop-pci.c b/drivers/media/dvb/b2c2/flexcop-pci.c
--- a/drivers/media/dvb/b2c2/flexcop-pci.c
+++ b/drivers/media/dvb/b2c2/flexcop-pci.c
@@ -13,6 +13,10 @@ static int enable_pid_filtering = 1;
 module_param(enable_pid_filtering, int, 0444);
 MODULE_PARM_DESC(enable_pid_filtering, "enable hardware pid filtering: supported values: 0 (fullts), 1");
 
+static int irq_chk_intv;
+module_param(irq_chk_intv, int, 0644);
+MODULE_PARM_DESC(irq_chk_intv, "set the interval for IRQ watchdog (currently just debugging).");
+
 #ifdef CONFIG_DVB_B2C2_FLEXCOP_DEBUG
 #define dprintk(level,args...) \
 	do { if ((debug & level)) printk(args); } while (0)
@@ -26,6 +30,7 @@ MODULE_PARM_DESC(enable_pid_filtering, "
 #define deb_reg(args...)   dprintk(0x02,args)
 #define deb_ts(args...)    dprintk(0x04,args)
 #define deb_irq(args...)   dprintk(0x08,args)
+#define deb_chk(args...)   dprintk(0x10,args)
 
 static int debug = 0;
 module_param(debug, int, 0644);
@@ -56,6 +61,10 @@ struct flexcop_pci {
 
 	spinlock_t irq_lock;
 
+	unsigned long last_irq;
+
+	struct work_struct irq_check_work;
+
 	struct flexcop_device *fc_dev;
 };
 
@@ -88,18 +97,55 @@ static int flexcop_pci_write_ibi_reg(str
 	return 0;
 }
 
+static void flexcop_pci_irq_check_work(void *data)
+{
+	struct flexcop_pci *fc_pci = data;
+	struct flexcop_device *fc = fc_pci->fc_dev;
+
+	flexcop_ibi_value v = fc->read_ibi_reg(fc,sram_dest_reg_714);
+
+	flexcop_dump_reg(fc_pci->fc_dev,dma1_000,4);
+
+	if (v.sram_dest_reg_714.net_ovflow_error)
+		deb_chk("sram net_ovflow_error\n");
+	if (v.sram_dest_reg_714.media_ovflow_error)
+		deb_chk("sram media_ovflow_error\n");
+	if (v.sram_dest_reg_714.cai_ovflow_error)
+		deb_chk("sram cai_ovflow_error\n");
+	if (v.sram_dest_reg_714.cai_ovflow_error)
+		deb_chk("sram cai_ovflow_error\n");
+
+	schedule_delayed_work(&fc_pci->irq_check_work,
+			msecs_to_jiffies(irq_chk_intv < 100 ? 100 : irq_chk_intv));
+}
+
 /* When PID filtering is turned on, we use the timer IRQ, because small amounts
  * of data need to be passed to the user space instantly as well. When PID
  * filtering is turned off, we use the page-change-IRQ */
-static irqreturn_t flexcop_pci_irq(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t flexcop_pci_isr(int irq, void *dev_id, struct pt_regs *regs)
 {
 	struct flexcop_pci *fc_pci = dev_id;
 	struct flexcop_device *fc = fc_pci->fc_dev;
-	flexcop_ibi_value v = fc->read_ibi_reg(fc,irq_20c);
+	flexcop_ibi_value v;
 	irqreturn_t ret = IRQ_HANDLED;
 
 	spin_lock_irq(&fc_pci->irq_lock);
 
+	v = fc->read_ibi_reg(fc,irq_20c);
+
+   /* errors */
+	if (v.irq_20c.Data_receiver_error)
+		deb_chk("data receiver error\n");
+	if (v.irq_20c.Continuity_error_flag)
+		deb_chk("Contunuity error flag is set\n");
+	if (v.irq_20c.LLC_SNAP_FLAG_set)
+		deb_chk("LLC_SNAP_FLAG_set is set\n");
+	if (v.irq_20c.Transport_Error)
+		deb_chk("Transport error\n");
+
+	if ((fc_pci->count % 1000) == 0)
+		deb_chk("%d valid irq took place so far\n",fc_pci->count);
+
 	if (v.irq_20c.DMA1_IRQ_Status == 1) {
 		if (fc_pci->active_dma1_addr == 0)
 			flexcop_pass_dmx_packets(fc_pci->fc_dev,fc_pci->dma[0].cpu_addr0,fc_pci->dma[0].size / 188);
@@ -115,8 +161,9 @@ static irqreturn_t flexcop_pci_irq(int i
 			fc->read_ibi_reg(fc,dma1_008).dma_0x8.dma_cur_addr << 2;
 		u32 cur_pos = cur_addr - fc_pci->dma[0].dma_addr0;
 
-		deb_irq("irq: %08x cur_addr: %08x: cur_pos: %08x, last_cur_pos: %08x ",
-				v.raw,cur_addr,cur_pos,fc_pci->last_dma1_cur_pos);
+		deb_irq("%u irq: %08x cur_addr: %08x: cur_pos: %08x, last_cur_pos: %08x ",
+				jiffies_to_usecs(jiffies - fc_pci->last_irq),v.raw,cur_addr,cur_pos,fc_pci->last_dma1_cur_pos);
+		fc_pci->last_irq = jiffies;
 
 		/* buffer end was reached, restarted from the beginning
 		 * pass the data from last_cur_pos to the buffer end to the demux
@@ -127,7 +174,6 @@ static irqreturn_t flexcop_pci_irq(int i
 					fc_pci->dma[0].cpu_addr0 + fc_pci->last_dma1_cur_pos,
 					(fc_pci->dma[0].size*2) - fc_pci->last_dma1_cur_pos);
 			fc_pci->last_dma1_cur_pos = 0;
-			fc_pci->count = 0;
 		}
 
 		if (cur_pos > fc_pci->last_dma1_cur_pos) {
@@ -139,16 +185,14 @@ static irqreturn_t flexcop_pci_irq(int i
 		deb_irq("\n");
 
 		fc_pci->last_dma1_cur_pos = cur_pos;
-	} else
+		fc_pci->count++;
+	} else {
+		deb_irq("isr for flexcop called, apparently without reason (%08x)\n",v.raw);
 		ret = IRQ_NONE;
+	}
 
 	spin_unlock_irq(&fc_pci->irq_lock);
 
-/* packet count would be ideal for hw filtering, but it isn't working. Either
- * the data book is wrong, or I'm unable to read it correctly */
-
-/*	if (v.irq_20c.DMA1_Size_IRQ_Status == 1) { packet counter */
-
 	return ret;
 }
 
@@ -156,30 +200,35 @@ static int flexcop_pci_stream_control(st
 {
 	struct flexcop_pci *fc_pci = fc->bus_specific;
 	if (onoff) {
-		flexcop_dma_config(fc,&fc_pci->dma[0],FC_DMA_1,FC_DMA_SUBADDR_0 | FC_DMA_SUBADDR_1);
-		flexcop_dma_config(fc,&fc_pci->dma[1],FC_DMA_2,FC_DMA_SUBADDR_0 | FC_DMA_SUBADDR_1);
-		flexcop_dma_config_timer(fc,FC_DMA_1,1);
+		flexcop_dma_config(fc,&fc_pci->dma[0],FC_DMA_1);
+		flexcop_dma_config(fc,&fc_pci->dma[1],FC_DMA_2);
 
-		if (fc_pci->fc_dev->pid_filtering) {
-			fc_pci->last_dma1_cur_pos = 0;
-			flexcop_dma_control_timer_irq(fc,FC_DMA_1,1);
-		} else {
-			fc_pci->active_dma1_addr = 0;
-			flexcop_dma_control_size_irq(fc,FC_DMA_1,1);
-		}
+		flexcop_dma_config_timer(fc,FC_DMA_1,0);
 
-/*		flexcop_dma_config_packet_count(fc,FC_DMA_1,0xc0);
-		flexcop_dma_control_packet_irq(fc,FC_DMA_1,1); */
+		flexcop_dma_xfer_control(fc,FC_DMA_1,FC_DMA_SUBADDR_0 | FC_DMA_SUBADDR_1,1);
+		deb_irq("DMA xfer enabled\n");
 
-		deb_irq("irqs enabled\n");
+		fc_pci->last_dma1_cur_pos = 0;
+		flexcop_dma_control_timer_irq(fc,FC_DMA_1,1);
+		deb_irq("IRQ enabled\n");
+
+//		fc_pci->active_dma1_addr = 0;
+//		flexcop_dma_control_size_irq(fc,FC_DMA_1,1);
+
+		if (irq_chk_intv > 0)
+			schedule_delayed_work(&fc_pci->irq_check_work,
+					msecs_to_jiffies(irq_chk_intv < 100 ? 100 : irq_chk_intv));
 	} else {
-		if (fc_pci->fc_dev->pid_filtering)
-			flexcop_dma_control_timer_irq(fc,FC_DMA_1,0);
-		else
-			flexcop_dma_control_size_irq(fc,FC_DMA_1,0);
+		if (irq_chk_intv > 0)
+			cancel_delayed_work(&fc_pci->irq_check_work);
+
+		flexcop_dma_control_timer_irq(fc,FC_DMA_1,0);
+		deb_irq("IRQ disabled\n");
 
-//		flexcop_dma_control_packet_irq(fc,FC_DMA_1,0);
-		deb_irq("irqs disabled\n");
+//		flexcop_dma_control_size_irq(fc,FC_DMA_1,0);
+
+		flexcop_dma_xfer_control(fc,FC_DMA_1,FC_DMA_SUBADDR_0 | FC_DMA_SUBADDR_1,0);
+		deb_irq("DMA xfer disabled\n");
 	}
 
 	return 0;
@@ -198,6 +247,7 @@ static int flexcop_pci_dma_init(struct f
 	flexcop_sram_set_dest(fc_pci->fc_dev,FC_SRAM_DEST_CAO   | FC_SRAM_DEST_CAI, FC_SRAM_DEST_TARGET_DMA2);
 
 	fc_pci->init_state |= FC_PCI_DMA_INIT;
+
 	goto success;
 dma1_free:
 	flexcop_dma_free(&fc_pci->dma[0]);
@@ -244,7 +294,7 @@ static int flexcop_pci_init(struct flexc
 
 	pci_set_drvdata(fc_pci->pdev, fc_pci);
 
-	if ((ret = request_irq(fc_pci->pdev->irq, flexcop_pci_irq,
+	if ((ret = request_irq(fc_pci->pdev->irq, flexcop_pci_isr,
 					SA_SHIRQ, DRIVER_NAME, fc_pci)) != 0)
 		goto err_pci_iounmap;
 
@@ -324,6 +374,8 @@ static int flexcop_pci_probe(struct pci_
 	if ((ret = flexcop_pci_dma_init(fc_pci)) != 0)
 		goto err_fc_exit;
 
+	INIT_WORK(&fc_pci->irq_check_work, flexcop_pci_irq_check_work, fc_pci);
+
 	goto success;
 err_fc_exit:
 	flexcop_device_exit(fc);
@@ -350,17 +402,17 @@ static void flexcop_pci_remove(struct pc
 
 static struct pci_device_id flexcop_pci_tbl[] = {
 	{ PCI_DEVICE(0x13d0, 0x2103) },
-/*	{ PCI_DEVICE(0x13d0, 0x2200) }, PCI FlexCopIII ? */
+/*	{ PCI_DEVICE(0x13d0, 0x2200) }, ? */
 	{ },
 };
 
 MODULE_DEVICE_TABLE(pci, flexcop_pci_tbl);
 
 static struct pci_driver flexcop_pci_driver = {
-	.name = "Technisat/B2C2 FlexCop II/IIb/III PCI",
+	.name     = "b2c2_flexcop_pci",
 	.id_table = flexcop_pci_tbl,
-	.probe = flexcop_pci_probe,
-	.remove = flexcop_pci_remove,
+	.probe    = flexcop_pci_probe,
+	.remove   = flexcop_pci_remove,
 };
 
 static int __init flexcop_pci_module_init(void)
diff --git a/drivers/media/dvb/b2c2/flexcop-reg.h b/drivers/media/dvb/b2c2/flexcop-reg.h
--- a/drivers/media/dvb/b2c2/flexcop-reg.h
+++ b/drivers/media/dvb/b2c2/flexcop-reg.h
@@ -21,7 +21,8 @@ extern const char *flexcop_revision_name
 typedef enum {
 	FC_UNK = 0,
 	FC_AIR_DVB,
-	FC_AIR_ATSC,
+	FC_AIR_ATSC1,
+	FC_AIR_ATSC2,
 	FC_SKY,
 	FC_SKY_OLD,
 	FC_CABLE,
@@ -35,555 +36,21 @@ typedef enum {
 extern const char *flexcop_device_names[];
 
 /* FlexCop IBI Registers */
+#if defined(__LITTLE_ENDIAN)
+	#include "flexcop_ibi_value_le.h"
+#elif defined(__BIG_ENDIAN)
+	#include "flexcop_ibi_value_be.h"
+#else
+	#error no endian defined
+#endif
 
-/* flexcop_ibi_reg - a huge union representing the register structure */
-typedef union {
-	u32 raw;
-
-/* DMA 0x000 to 0x01c
- * DMA1 0x000 to 0x00c
- * DMA2 0x010 to 0x01c
- */
-	struct {
-		u32 dma_0start        : 1;   /* set: data will be delivered to dma1_address0 */
-        u32 dma_0No_update    : 1;   /* set: dma1_cur_address will be updated, unset: no update */
-        u32 dma_address0      :30;   /* physical/virtual host memory address0 DMA */
-	} dma_0x0;
-
-	struct {
-		u32 DMA_maxpackets    : 8;   /* (remapped) PCI DMA1 Packet Count Interrupt. This variable
-										is able to be read and written while bit(1) of register
-										0x00c (remap_enable) is set. This variable represents
-										the number of packets that will be transmitted to the PCI
-										host using PCI DMA1 before an interrupt to the PCI is
-										asserted. This functionality may be enabled using bit(20)
-										of register 0x208. N=0 disables the IRQ. */
-		u32 dma_addr_size     :24;   /* size of memory buffer in DWORDs (bytesize / 4) for DMA */
-	} dma_0x4_remap;
-
-	struct {
-		u32 dma1timer         : 7;   /* reading PCI DMA1 timer ... when remap_enable is 0 */
-		u32 unused            : 1;
-		u32 dma_addr_size     :24;
-	} dma_0x4_read;
-
-	struct {
-		u32 unused            : 1;
-		u32 dmatimer          : 7;   /* writing PCI DMA1 timer ... when remap_enable is 0 */
-		u32 dma_addr_size     :24;
-	} dma_0x4_write;
-
-	struct {
-		u32 unused            : 2;
-		u32 dma_cur_addr      :30;   /* current physical host memory address pointer for DMA */
-	} dma_0x8;
-
-	struct {
-		u32 dma_1start        : 1;   /* set: data will be delivered to dma_address1, when dma_address0 is full */
-		u32 remap_enable      : 1;   /* remap enable for 0x0x4(7:0) */
-		u32 dma_address1      :30;   /* Physical/virtual address 1 on DMA */
-	} dma_0xc;
-
-/* Two-wire Serial Master and Clock 0x100-0x110 */
-	struct {
-//		u32 slave_transmitter : 1;   /* ???*/
-		u32 chipaddr          : 7;   /* two-line serial address of the target slave */
-		u32 reserved1         : 1;
-		u32 baseaddr          : 8;   /* address of the location of the read/write operation */
-		u32 data1_reg         : 8;   /* first byte in two-line serial read/write operation */
-		u32 working_start     : 1;  /* when doing a write operation this indicator is 0 when ready
-									  * set to 1 when doing a write operation */
-		u32 twoWS_rw          : 1;   /* read/write indicator (1 = read, 0 write) */
-		u32 total_bytes       : 2;   /* number of data bytes in each two-line serial transaction (0 = 1 byte, 11 = 4byte)*/
-		u32 twoWS_port_reg    : 2;   /* port selection: 01 - Front End/Demod, 10 - EEPROM, 11 - Tuner */
-		u32 no_base_addr_ack_error : 1;   /* writing: write-req: frame is produced w/o baseaddr, read-req: read-cycles w/o
-									  * preceding address assignment write frame
-									  * ACK_ERROR = 1 when no ACK from slave in the last transaction */
-		u32 st_done           : 1;   /* indicator for transaction is done */
-	} tw_sm_c_100;
-
-	struct {
-		u32 data2_reg         : 8;   /* 2nd data byte */
-		u32 data3_reg         : 8;   /* 3rd data byte */
-		u32 data4_reg         : 8;   /* 4th data byte */
-		u32 exlicit_stops     : 1;   /* when set, transactions are produced w/o trailing STOP flag, then send isolated STOP flags */
-		u32 force_stop        : 1;   /* isolated stop flag */
-		u32 unused            : 6;
-	} tw_sm_c_104;
-
-/* Clock. The register allows the FCIII to convert an incoming Master clock
- * (MCLK) signal into a lower frequency clock through the use of a LowCounter
- * (TLO) and a High- Counter (THI). The time counts for THI and TLO are
- * measured in MCLK; each count represents 4 MCLK input clock cycles.
- *
- * The default output for port #1 is set for Front End Demod communication. (0x108)
- * The default output for port #2 is set for EEPROM communication. (0x10c)
- * The default output for port #3 is set for Tuner communication. (0x110)
- */
-	struct {
-		u32 thi1              : 6;   /* Thi for port #1 (def: 100110b; 38) */
-		u32 reserved1         : 2;
-		u32 tlo1              : 5;   /* Tlo for port #1 (def: 11100b; 28) */
-		u32 reserved2         :19;
-	} tw_sm_c_108;
-
-	struct {
-		u32 thi1              : 6;   /* Thi for port #2 (def: 111001b; 57) */
-		u32 reserved1         : 2;
-		u32 tlo1              : 5;   /* Tlo for port #2 (def: 11100b; 28) */
-		u32 reserved2         :19;
-	} tw_sm_c_10c;
-
-	struct {
-		u32 thi1              : 6;   /* Thi for port #3 (def: 111001b; 57) */
-		u32 reserved1         : 2;
-		u32 tlo1              : 5;   /* Tlo for port #3 (def: 11100b; 28) */
-		u32 reserved2         :19;
-	} tw_sm_c_110;
-
-/* LNB Switch Frequency 0x200
- * Clock that creates the LNB switch tone. The default is set to have a fixed
- * low output (not oscillating) to the LNB_CTL line.
- */
-	struct {
-		u32 LNB_CTLHighCount_sig :15; /* It is the number of pre-scaled clock cycles that will be low. */
-		u32 LNB_CTLLowCount_sig  :15; /* For example, to obtain a 22KHz output given a 45 Mhz Master
-										Clock signal (MCLK), set PreScalar=01 and LowCounter value to 0x1ff. */
-		u32 LNB_CTLPrescaler_sig : 2; /* pre-scaler divides MCLK: 00 (no division), 01 by 2, 10 by 4, 11 by 12 */
-	} lnb_switch_freq_200;
-
-/* ACPI, Peripheral Reset, LNB Polarity
- * ACPI power conservation mode, LNB polarity selection (low or high voltage),
- * and peripheral reset.
- */
-	struct {
-		u32 ACPI1_sig         : 1;   /* turn of the power of tuner and LNB, not implemented in FCIII */
-		u32 ACPI3_sig         : 1;   /* turn of power of the complete satelite receiver board (except FCIII) */
-		u32 LNB_L_H_sig       : 1;   /* low or high voltage for LNB. (0 = low, 1 = high) */
-		u32 Per_reset_sig     : 1;   /* misc. init reset (default: 1), to reset set to low and back to high */
-		u32 reserved          :20;
-		u32 Rev_N_sig_revision_hi : 4;/* 0xc in case of FCIII */
-		u32 Rev_N_sig_reserved1 : 2;
-		u32 Rev_N_sig_caps    : 1;   /* if 1, FCIII has 32 PID- and MAC-filters and is capable of IP multicast */
-		u32 Rev_N_sig_reserved2 : 1;
-	} misc_204;
-
-/* Control and Status 0x208 to 0x21c */
-/* Gross enable and disable control */
-	struct {
-		u32 Stream1_filter_sig : 1;  /* Stream1 PID filtering */
-		u32 Stream2_filter_sig : 1;  /* Stream2 PID filtering */
-		u32 PCR_filter_sig    : 1;   /* PCR PID filter */
-		u32 PMT_filter_sig    : 1;   /* PMT PID filter */
-
-		u32 EMM_filter_sig    : 1;   /* EMM PID filter */
-		u32 ECM_filter_sig    : 1;   /* ECM PID filter */
-		u32 Null_filter_sig   : 1;   /* Filters null packets, PID=0x1fff. */
-		u32 Mask_filter_sig   : 1;   /* mask PID filter */
-
-		u32 WAN_Enable_sig    : 1;   /* WAN output line through V8 memory space is activated. */
-		u32 WAN_CA_Enable_sig : 1;   /* not in FCIII */
-		u32 CA_Enable_sig     : 1;   /* not in FCIII */
-		u32 SMC_Enable_sig    : 1;   /* CI stream data (CAI) goes directly to the smart card intf (opposed IBI 0x600 or SC-cmd buf). */
-
-		u32 Per_CA_Enable_sig : 1;   /* not in FCIII */
-		u32 Multi2_Enable_sig : 1;   /* ? */
-		u32 MAC_filter_Mode_sig : 1; /* (MAC_filter_enable) Globally enables MAC filters for Net PID filteres. */
-		u32 Rcv_Data_sig      : 1;   /* PID filtering module enable. When this bit is a one, the PID filter will
-										examine and process packets according to all other (individual) PID
-										filtering controls. If it a zero, no packet processing of any kind will
-										take place. All data from the tuner will be thrown away. */
-
-		u32 DMA1_IRQ_Enable_sig : 1; /* When set, a DWORD counter is enabled on PCI DMA1 that asserts the PCI
-									  * interrupt after the specified count for filling the buffer. */
-		u32 DMA1_Timer_Enable_sig : 1; /* When set, a timer is enabled on PCI DMA1 that asserts the PCI interrupt
-											after a specified amount of time. */
-		u32 DMA2_IRQ_Enable_sig : 1;   /* same as DMA1_IRQ_Enable_sig but for DMA2 */
-		u32 DMA2_Timer_Enable_sig : 1;   /* same as DMA1_Timer_Enable_sig but for DMA2 */
-
-		u32 DMA1_Size_IRQ_Enable_sig : 1; /* When set, a packet count detector is enabled on PCI DMA1 that asserts the PCI interrupt. */
-		u32 DMA2_Size_IRQ_Enable_sig : 1; /* When set, a packet	count detector is enabled on PCI DMA2 that asserts the PCI interrupt. */
-		u32 Mailbox_from_V8_Enable_sig: 1; /* When set, writes to the mailbox register produce an interrupt to the
-											PCI host to indicate that mailbox data is available. */
-
-		u32 unused            : 9;
-	} ctrl_208;
-
-/* General status. When a PCI interrupt occurs, this register is read to
- * discover the reason for the interrupt.
- */
-	struct {
-		u32 DMA1_IRQ_Status   : 1;   /* When set(1) the DMA1 counter had generated an IRQ. Read Only. */
-		u32 DMA1_Timer_Status : 1;   /* When set(1) the DMA1 timer had generated an IRQ. Read Only. */
-		u32 DMA2_IRQ_Status   : 1;   /* When set(1) the DMA2 counter had generated an IRQ. Read Only. */
-		u32 DMA2_Timer_Status : 1;   /* When set(1) the DMA2 timer had generated an IRQ. Read Only. */
-		u32 DMA1_Size_IRQ_Status : 1; /* (Read only). This register is read after an interrupt to */
-		u32 DMA2_Size_IRQ_Status : 1; /* find out why we had an IRQ. Reading this register will clear this bit. Packet count*/
-		u32 Mailbox_from_V8_Status_sig: 1; /* Same as above. Reading this register will clear this bit. */
-		u32 Data_receiver_error : 1; /* 1 indicate an error in the receiver Front End (Tuner module) */
-		u32 Continuity_error_flag : 1;   /* 1 indicates a continuity error in the TS stream. */
-		u32 LLC_SNAP_FLAG_set : 1;   /* 1 indicates that the LCC_SNAP_FLAG was set. */
-		u32 Transport_Error   : 1;   /*  When set indicates that an unexpected packet was received. */
-		u32 reserved          :21;
-	} irq_20c;
-
-
-/* Software reset register */
-	struct {
-		u32 reset_blocks      : 8;   /* Enabled when Block_reset_enable = 0xB2 and 0x208 bits 15:8 = 0x00.
-										Each bit location represents a 0x100 block of registers. Writing
-										a one in a bit location resets that block of registers and the logic
-										that it controls. */
-		u32 Block_reset_enable : 8;  /* This variable is set to 0xB2 when the register is written. */
-		u32 Special_controls  :16;   /* Asserts Reset_V8 => 0xC258; Turns on pci encryption => 0xC25A;
-										Turns off pci encryption => 0xC259 Note: pci_encryption default
-										at power-up is ON. */
-	} sw_reset_210;
-
-	struct {
-		u32 vuart_oe_sig      : 1;   /* When clear, the V8 processor has sole control of the serial UART
-										(RS-232 Smart Card interface). When set, the IBI interface
-										defined by register 0x600 controls the serial UART. */
-		u32 v2WS_oe_sig       : 1;   /* When clear, the V8 processor has direct control of the Two-line
-										Serial Master EEPROM target. When set, the Two-line Serial Master
-										EEPROM target interface is controlled by IBI register 0x100. */
-		u32 halt_V8_sig       : 1;   /* When set, contiguous wait states are applied to the V8-space
-										bus masters. Once this signal is cleared, normal V8-space
-										operations resume. */
-		u32 section_pkg_enable_sig: 1; /* When set, this signal enables the front end translation circuitry
-										  to process section packed transport streams. */
-		u32 s2p_sel_sig       : 1;   /* Serial to parallel conversion. When set, polarized transport data
-										within the FlexCop3 front end circuitry is converted from a serial
-										stream into parallel data before downstream processing otherwise
-										interprets the data. */
-		u32 unused1           : 3;
-		u32 polarity_PS_CLK_sig: 1;  /* This signal is used to invert the input polarity of the tranport
-										stream CLOCK signal before any processing occurs on the transport
-										stream within FlexCop3. */
-		u32 polarity_PS_VALID_sig: 1; /* This signal is used to invert the input polarity of the tranport
-										stream VALID signal before any processing occurs on the transport
-										stream within FlexCop3. */
-		u32 polarity_PS_SYNC_sig: 1; /* This signal is used to invert the input polarity of the tranport
-										stream SYNC signal before any processing occurs on the transport
-										stream within FlexCop3. */
-		u32 polarity_PS_ERR_sig: 1;  /* This signal is used to invert the input polarity of the tranport
-										stream ERROR signal before any processing occurs on the transport
-										stream within FlexCop3. */
-		u32 unused2           :20;
-	} misc_214;
-
-/* Mailbox from V8 to host */
-	struct {
-		u32 Mailbox_from_V8   :32;   /* When this register is written by either the V8 processor or by an
-										end host, an interrupt is generated to the PCI host to indicate
-										that mailbox data is available. Reading register 20c will clear
-										the IRQ. */
-	} mbox_v8_to_host_218;
-
-/* Mailbox from host to v8 Mailbox_to_V8
- * Mailbox_to_V8 mailbox storage register
- * used to send messages from PCI to V8. Writing to this register will send an
- * IRQ to the V8. Then it can read the data from here. Reading this register
- * will clear the IRQ. If the V8 is halted and bit 31 of this register is set,
- * then this register is used instead as a direct interface to access the
- * V8space memory.
- */
-	struct {
-		u32 sysramaccess_data : 8;   /* Data byte written or read from the specified address in V8 SysRAM. */
-		u32 sysramaccess_addr :15;   /* 15 bit address used to access V8 Sys-RAM. */
-		u32 unused            : 7;
-		u32 sysramaccess_write: 1;   /* Write flag used to latch data into the V8 SysRAM. */
-		u32 sysramaccess_busmuster: 1; /* Setting this bit when the V8 is halted at 0x214 Bit(2) allows
-										  this IBI register interface to directly drive the V8-space memory. */
-	} mbox_host_to_v8_21c;
-
-
-/* PIDs, Translation Bit, SMC Filter Select 0x300 to 0x31c */
-	struct {
-		u32 Stream1_PID       :13;   /* Primary use is receiving Net data, so these 13 bits normally
-										hold the PID value for the desired network stream. */
-		u32 Stream1_trans     : 1;   /* When set, Net translation will take place for Net data ferried in TS packets. */
-		u32 MAC_Multicast_filter : 1;   /* When clear, multicast MAC filtering is not allowed for Stream1 and PID_n filters. */
-		u32 debug_flag_pid_saved : 1;
-		u32 Stream2_PID       :13;   /* 13 bits for Stream 2 PID filter value. General use. */
-		u32 Stream2_trans     : 1;   /* When set Tables/CAI translation will take place for the data ferried in
-										Stream2_PID TS packets. */
-		u32 debug_flag_write_status00 : 1;
-		u32 debug_fifo_problem : 1;
-	} pid_filter_300;
-
-	struct {
-		u32 PCR_PID           :13;   /* PCR stream PID filter value. Primary use is Program Clock Reference stream filtering. */
-		u32 PCR_trans         : 1;   /* When set, Tables/CAI translation will take place for these packets. */
-		u32 debug_overrun3    : 1;
-		u32 debug_overrun2    : 1;
-		u32 PMT_PID           :13;   /* stream PID filter value. Primary use is Program Management Table segment filtering. */
-		u32 PMT_trans         : 1;   /* When set, Tables/CAI translation will take place for these packets. */
-		u32 reserved          : 2;
-	} pid_filter_304;
-
-	struct {
-		u32 EMM_PID           :13;   /* EMM PID filter value. Primary use is Entitlement Management Messaging for
-										conditional access-related data. */
-		u32 EMM_trans         : 1;   /* When set, Tables/CAI translation will take place for these packets. */
-		u32 EMM_filter_4      : 1;   /* When set will pass only EMM data possessing the same ID code as the
-										first four bytes (32 bits) of the end-user s 6-byte Smart Card ID number Select */
-		u32 EMM_filter_6      : 1;   /* When set will pass only EMM data possessing the same 6-byte code as the end-users
-										complete 6-byte Smart Card ID number. */
-		u32 ECM_PID           :13;   /* ECM PID filter value. Primary use is Entitlement Control Messaging for conditional
-										access-related data. */
-		u32 ECM_trans         : 1;   /* When set, Tables/CAI translation will take place for these packets. */
-		u32 reserved          : 2;
-	} pid_filter_308;
-
-	struct {
-		u32 Group_PID     :13;   /* PID value for group filtering. */
-		u32 Group_trans   : 1;   /* When set, Tables/CAI translation will take place for these packets. */
-		u32 unused1       : 2;
-		u32 Group_mask    :13;   /* Mask value used in logical "and" equation that defines group filtering */
-		u32 unused2       : 3;
-	} pid_filter_30c_ext_ind_0_7;
-
-	struct {
-		u32 net_master_read :17;
-		u32 unused        :15;
-	} pid_filter_30c_ext_ind_1;
-
-	struct {
-		u32 net_master_write :17;
-		u32 unused        :15;
-	} pid_filter_30c_ext_ind_2;
-
-	struct {
-		u32 next_net_master_write :17;
-		u32 unused        :15;
-	} pid_filter_30c_ext_ind_3;
-
-	struct {
-		u32 unused1       : 1;
-		u32 state_write   :10;
-		u32 reserved1     : 6;   /* default: 000100 */
-		u32 stack_read    :10;
-		u32 reserved2     : 5;   /* default: 00100 */
-	} pid_filter_30c_ext_ind_4;
-
-	struct {
-		u32 stack_cnt     :10;
-		u32 unused        :22;
-	} pid_filter_30c_ext_ind_5;
-
-	struct {
-		u32 pid_fsm_save_reg0 : 2;
-		u32 pid_fsm_save_reg1 : 2;
-		u32 pid_fsm_save_reg2 : 2;
-		u32 pid_fsm_save_reg3 : 2;
-		u32 pid_fsm_save_reg4 : 2;
-		u32 pid_fsm_save_reg300 : 2;
-		u32 write_status1 : 2;
-		u32 write_status4 : 2;
-		u32 data_size_reg :12;
-		u32 unused        : 4;
-	} pid_filter_30c_ext_ind_6;
-
-	struct {
-		u32 index_reg         : 5;   /* (Index pointer) Points at an internal PIDn register. A binary code
-										representing one of 32 internal PIDn registers as well as its
-										corresponding internal MAC_lown register. */
-		u32 extra_index_reg   : 3;   /* This vector is used to select between sets of debug signals routed to register 0x30c. */
-		u32 AB_select         : 1;   /* Used in conjunction with 0x31c. read/write to the MAC_highA or MAC_highB register
-										0=MAC_highB register, 1=MAC_highA */
-		u32 pass_alltables    : 1;   /* 1=Net packets are not filtered against the Network Table ID found in register 0x400.
-										All types of networks (DVB, ATSC, ISDB) are passed. */
-		u32 unused            :22;
-	} index_reg_310;
-
-	struct {
-		u32 PID               :13;   /* PID value */
-		u32 PID_trans         : 1;   /* translation will take place for packets filtered */
-		u32 PID_enable_bit    : 1;   /* When set this PID filter is enabled */
-		u32 reserved          :17;
-	} pid_n_reg_314;
-
-	struct {
-		u32 A4_byte           : 8;
-		u32 A5_byte           : 8;
-		u32 A6_byte           : 8;
-		u32 Enable_bit        : 1;   /* enabled (1) or disabled (1) */
-		u32 HighAB_bit        : 1;   /* use MAC_highA (1) or MAC_highB (0) as MSB */
-		u32 reserved          : 6;
-	} mac_low_reg_318;
-
-	struct {
-		u32 A1_byte           : 8;
-		u32 A2_byte           : 8;
-		u32 A3_byte           : 8;
-		u32 reserved          : 8;
-	} mac_high_reg_31c;
-
-/* Table, SMCID,MACDestination Filters 0x400 to 0x41c */
-	struct {
-		u32 reserved          :16;
 #define fc_data_Tag_ID_DVB  0x3e
 #define fc_data_Tag_ID_ATSC 0x3f
 #define fc_data_Tag_ID_IDSB 0x8b
-		u32 data_Tag_ID       :16;
-	} data_tag_400;
 
-	struct {
-		u32 Card_IDbyte6      : 8;
-		u32 Card_IDbyte5      : 8;
-		u32 Card_IDbyte4      : 8;
-		u32 Card_IDbyte3      : 8;
-	} card_id_408;
-
-	struct {
-		u32 Card_IDbyte2      : 8;
-		u32 Card_IDbyte1      : 8;
-	} card_id_40c;
-
-	/* holding the unique mac address of the receiver which houses the FlexCopIII */
-	struct {
-		u32 MAC1              : 8;
-		u32 MAC2              : 8;
-		u32 MAC3              : 8;
-		u32 MAC6              : 8;
-	} mac_address_418;
-
-	struct {
-		u32 MAC7              : 8;
-		u32 MAC8              : 8;
-		u32 reserved          : 16;
-	} mac_address_41c;
-
-	struct {
-		u32 transmitter_data_byte : 8;
-		u32 ReceiveDataReady  : 1;
-		u32 ReceiveByteFrameError: 1;
-		u32 txbuffempty       : 1;
-		u32 reserved          :21;
-	} ci_600;
-
-	struct {
-		u32 pi_d              : 8;
-		u32 pi_ha             :20;
-		u32 pi_rw             : 1;
-		u32 pi_component_reg  : 3;
-	} pi_604;
-
-	struct {
-		u32 serialReset       : 1;
-		u32 oncecycle_read    : 1;
-		u32 Timer_Read_req    : 1;
-		u32 Timer_Load_req    : 1;
-		u32 timer_data        : 7;
-		u32 unused            : 1; /* ??? not mentioned in data book */
-		u32 Timer_addr        : 5;
-		u32 reserved          : 3;
-		u32 pcmcia_a_mod_pwr_n : 1;
-		u32 pcmcia_b_mod_pwr_n : 1;
-		u32 config_Done_stat  : 1;
-		u32 config_Init_stat  : 1;
-		u32 config_Prog_n     : 1;
-		u32 config_wr_n       : 1;
-		u32 config_cs_n       : 1;
-		u32 config_cclk       : 1;
-		u32 pi_CiMax_IRQ_n    : 1;
-		u32 pi_timeout_status : 1;
-		u32 pi_wait_n         : 1;
-		u32 pi_busy_n         : 1;
-	} pi_608;
-
-	struct {
-		u32 PID               :13;
-		u32 key_enable        : 1;
 #define fc_key_code_default 0x1
 #define fc_key_code_even    0x2
 #define fc_key_code_odd     0x3
-		u32 key_code          : 2;
-		u32 key_array_col     : 3;
-		u32 key_array_row     : 5;
-		u32 dvb_en            : 1; /* 0=TS bypasses the Descrambler */
-		u32 rw_flag           : 1;
-		u32 reserved          : 6;
-	} dvb_reg_60c;
-
-/* SRAM and Output Destination 0x700 to 0x714 */
-	struct {
-		u32 sram_addr         :15;
-		u32 sram_rw           : 1;   /* 0=write, 1=read */
-		u32 sram_data         : 8;
-		u32 sc_xfer_bit       : 1;
-		u32 reserved1         : 3;
-		u32 oe_pin_reg        : 1;
-		u32 ce_pin_reg        : 1;
-		u32 reserved2         : 1;
-		u32 start_sram_ibi    : 1;
-	} sram_ctrl_reg_700;
-
-	struct {
-		u32 net_addr_read     :16;
-		u32 net_addr_write    :16;
-	} net_buf_reg_704;
-
-	struct {
-		u32 cai_read          :11;
-		u32 reserved1         : 5;
-		u32 cai_write         :11;
-		u32 reserved2         : 6;
-		u32 cai_cnt           : 4;
-	} cai_buf_reg_708;
-
-	struct {
-		u32 cao_read          :11;
-		u32 reserved1         : 5;
-		u32 cap_write         :11;
-		u32 reserved2         : 6;
-		u32 cao_cnt           : 4;
-	} cao_buf_reg_70c;
-
-	struct {
-		u32 media_read        :11;
-		u32 reserved1         : 5;
-		u32 media_write       :11;
-		u32 reserved2         : 6;
-		u32 media_cnt         : 4;
-	} media_buf_reg_710;
-
-	struct {
-		u32 NET_Dest          : 2;
-		u32 CAI_Dest          : 2;
-		u32 CAO_Dest          : 2;
-		u32 MEDIA_Dest        : 2;
-		u32 net_ovflow_error  : 1;
-		u32 media_ovflow_error : 1;
-		u32 cai_ovflow_error  : 1;
-		u32 cao_ovflow_error  : 1;
-		u32 ctrl_usb_wan      : 1;
-		u32 ctrl_sramdma      : 1;
-		u32 ctrl_maximumfill  : 1;
-		u32 reserved          :17;
-	} sram_dest_reg_714;
-
-	struct {
-		u32 net_cnt           :12;
-		u32 reserved1         : 4;
-		u32 net_addr_read     : 1;
-		u32 reserved2         : 3;
-		u32 net_addr_write    : 1;
-		u32 reserved3         :11;
-	} net_buf_reg_718;
-
-	struct {
-		u32 wan_speed_sig     : 2;
-		u32 reserved1         : 6;
-		u32 wan_wait_state    : 8;
-		u32 sram_chip         : 2;
-		u32 sram_memmap       : 2;
-		u32 reserved2         : 4;
-		u32 wan_pkt_frame     : 4;
-		u32 reserved3         : 4;
-	} wan_ctrl_reg_71c;
-} flexcop_ibi_value;
 
 extern flexcop_ibi_value ibi_zero;
 
diff --git a/drivers/media/dvb/b2c2/flexcop-usb.c b/drivers/media/dvb/b2c2/flexcop-usb.c
--- a/drivers/media/dvb/b2c2/flexcop-usb.c
+++ b/drivers/media/dvb/b2c2/flexcop-usb.c
@@ -545,7 +545,7 @@ static struct usb_device_id flexcop_usb_
 /* usb specific object needed to register this driver with the usb subsystem */
 static struct usb_driver flexcop_usb_driver = {
 	.owner		= THIS_MODULE,
-	.name		= "Technisat/B2C2 FlexCop II/IIb/III USB",
+	.name		= "b2c2_flexcop_usb",
 	.probe		= flexcop_usb_probe,
 	.disconnect = flexcop_usb_disconnect,
 	.id_table	= flexcop_usb_table,
diff --git a/drivers/media/dvb/b2c2/flexcop.c b/drivers/media/dvb/b2c2/flexcop.c
--- a/drivers/media/dvb/b2c2/flexcop.c
+++ b/drivers/media/dvb/b2c2/flexcop.c
@@ -46,7 +46,7 @@
 
 int b2c2_flexcop_debug;
 module_param_named(debug, b2c2_flexcop_debug,  int, 0644);
-MODULE_PARM_DESC(debug, "set debug level (1=info,2=tuner,4=i2c,8=ts,16=sram (|-able))." DEBSTATUS);
+MODULE_PARM_DESC(debug, "set debug level (1=info,2=tuner,4=i2c,8=ts,16=sram,32=reg (|-able))." DEBSTATUS);
 #undef DEBSTATUS
 
 /* global zero for ibi values */
@@ -173,9 +173,20 @@ static void flexcop_reset(struct flexcop
 	fc->write_ibi_reg(fc,ctrl_208,ibi_zero);
 
 	v210.raw = 0;
-	v210.sw_reset_210.reset_blocks = 0xff;
+	v210.sw_reset_210.reset_block_000 = 1;
+	v210.sw_reset_210.reset_block_100 = 1;
+	v210.sw_reset_210.reset_block_200 = 1;
+	v210.sw_reset_210.reset_block_300 = 1;
+	v210.sw_reset_210.reset_block_400 = 1;
+	v210.sw_reset_210.reset_block_500 = 1;
+	v210.sw_reset_210.reset_block_600 = 1;
+	v210.sw_reset_210.reset_block_700 = 1;
 	v210.sw_reset_210.Block_reset_enable = 0xb2;
+
+	v210.sw_reset_210.Special_controls = 0xc259;
+
 	fc->write_ibi_reg(fc,sw_reset_210,v210);
+	msleep(1);
 
 /* reset the periphical devices */
 
@@ -186,6 +197,25 @@ static void flexcop_reset(struct flexcop
 	fc->write_ibi_reg(fc,misc_204,v204);
 }
 
+void flexcop_reset_block_300(struct flexcop_device *fc)
+{
+	flexcop_ibi_value v208_save = fc->read_ibi_reg(fc,ctrl_208),
+					  v210 = fc->read_ibi_reg(fc,sw_reset_210);
+
+	deb_rdump("208: %08x, 210: %08x\n",v208_save.raw,v210.raw);
+
+	fc->write_ibi_reg(fc,ctrl_208,ibi_zero);
+
+	v210.sw_reset_210.reset_block_300 = 1;
+	v210.sw_reset_210.Block_reset_enable = 0xb2;
+
+	fc->write_ibi_reg(fc,sw_reset_210,v210);
+	msleep(1);
+
+	fc->write_ibi_reg(fc,ctrl_208,v208_save);
+}
+EXPORT_SYMBOL(flexcop_reset_block_300);
+
 struct flexcop_device *flexcop_device_kmalloc(size_t bus_specific_len)
 {
 	void *bus;
diff --git a/drivers/media/dvb/b2c2/flexcop.h b/drivers/media/dvb/b2c2/flexcop.h
--- a/drivers/media/dvb/b2c2/flexcop.h
+++ b/drivers/media/dvb/b2c2/flexcop.h
@@ -26,5 +26,6 @@ extern int b2c2_flexcop_debug;
 #define deb_i2c(args...)   dprintk(0x04,args)
 #define deb_ts(args...)    dprintk(0x08,args)
 #define deb_sram(args...)  dprintk(0x10,args)
+#define deb_rdump(args...)  dprintk(0x20,args)
 
 #endif
diff --git a/drivers/media/dvb/b2c2/flexcop_ibi_value_be.h b/drivers/media/dvb/b2c2/flexcop_ibi_value_be.h
new file mode 100644
--- /dev/null
+++ b/drivers/media/dvb/b2c2/flexcop_ibi_value_be.h
@@ -0,0 +1,458 @@
+/* This file is part of linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
+ *
+ * register descriptions
+ *
+ * see flexcop.c for copyright information.
+ */
+
+/* This file is automatically generated, do not edit things here. */
+#ifndef __FLEXCOP_IBI_VALUE_INCLUDED__
+#define __FLEXCOP_IBI_VALUE_INCLUDED__
+
+typedef union {
+	u32 raw;
+
+	struct {
+		u32 dma_address0                   :30;
+		u32 dma_0No_update                 : 1;
+		u32 dma_0start                     : 1;
+	} dma_0x0;
+
+	struct {
+		u32 dma_addr_size                  :24;
+		u32 DMA_maxpackets                 : 8;
+	} dma_0x4_remap;
+
+	struct {
+		u32 dma_addr_size                  :24;
+		u32 unused                         : 1;
+		u32 dma1timer                      : 7;
+	} dma_0x4_read;
+
+	struct {
+		u32 dma_addr_size                  :24;
+		u32 dmatimer                       : 7;
+		u32 unused                         : 1;
+	} dma_0x4_write;
+
+	struct {
+		u32 dma_cur_addr                   :30;
+		u32 unused                         : 2;
+	} dma_0x8;
+
+	struct {
+		u32 dma_address1                   :30;
+		u32 remap_enable                   : 1;
+		u32 dma_1start                     : 1;
+	} dma_0xc;
+
+	struct {
+		u32 st_done                        : 1;
+		u32 no_base_addr_ack_error         : 1;
+		u32 twoWS_port_reg                 : 2;
+		u32 total_bytes                    : 2;
+		u32 twoWS_rw                       : 1;
+		u32 working_start                  : 1;
+		u32 data1_reg                      : 8;
+		u32 baseaddr                       : 8;
+		u32 reserved1                      : 1;
+		u32 chipaddr                       : 7;
+	} tw_sm_c_100;
+
+	struct {
+		u32 unused                         : 6;
+		u32 force_stop                     : 1;
+		u32 exlicit_stops                  : 1;
+		u32 data4_reg                      : 8;
+		u32 data3_reg                      : 8;
+		u32 data2_reg                      : 8;
+	} tw_sm_c_104;
+
+	struct {
+		u32 reserved2                      :19;
+		u32 tlo1                           : 5;
+		u32 reserved1                      : 2;
+		u32 thi1                           : 6;
+	} tw_sm_c_108;
+
+	struct {
+		u32 reserved2                      :19;
+		u32 tlo1                           : 5;
+		u32 reserved1                      : 2;
+		u32 thi1                           : 6;
+	} tw_sm_c_10c;
+
+	struct {
+		u32 reserved2                      :19;
+		u32 tlo1                           : 5;
+		u32 reserved1                      : 2;
+		u32 thi1                           : 6;
+	} tw_sm_c_110;
+
+	struct {
+		u32 LNB_CTLPrescaler_sig           : 2;
+		u32 LNB_CTLLowCount_sig            :15;
+		u32 LNB_CTLHighCount_sig           :15;
+	} lnb_switch_freq_200;
+
+	struct {
+		u32 Rev_N_sig_reserved2            : 1;
+		u32 Rev_N_sig_caps                 : 1;
+		u32 Rev_N_sig_reserved1            : 2;
+		u32 Rev_N_sig_revision_hi          : 4;
+		u32 reserved                       :20;
+		u32 Per_reset_sig                  : 1;
+		u32 LNB_L_H_sig                    : 1;
+		u32 ACPI3_sig                      : 1;
+		u32 ACPI1_sig                      : 1;
+	} misc_204;
+
+	struct {
+		u32 unused                         : 9;
+		u32 Mailbox_from_V8_Enable_sig     : 1;
+		u32 DMA2_Size_IRQ_Enable_sig       : 1;
+		u32 DMA1_Size_IRQ_Enable_sig       : 1;
+		u32 DMA2_Timer_Enable_sig          : 1;
+		u32 DMA2_IRQ_Enable_sig            : 1;
+		u32 DMA1_Timer_Enable_sig          : 1;
+		u32 DMA1_IRQ_Enable_sig            : 1;
+		u32 Rcv_Data_sig                   : 1;
+		u32 MAC_filter_Mode_sig            : 1;
+		u32 Multi2_Enable_sig              : 1;
+		u32 Per_CA_Enable_sig              : 1;
+		u32 SMC_Enable_sig                 : 1;
+		u32 CA_Enable_sig                  : 1;
+		u32 WAN_CA_Enable_sig              : 1;
+		u32 WAN_Enable_sig                 : 1;
+		u32 Mask_filter_sig                : 1;
+		u32 Null_filter_sig                : 1;
+		u32 ECM_filter_sig                 : 1;
+		u32 EMM_filter_sig                 : 1;
+		u32 PMT_filter_sig                 : 1;
+		u32 PCR_filter_sig                 : 1;
+		u32 Stream2_filter_sig             : 1;
+		u32 Stream1_filter_sig             : 1;
+	} ctrl_208;
+
+	struct {
+		u32 reserved                       :21;
+		u32 Transport_Error                : 1;
+		u32 LLC_SNAP_FLAG_set              : 1;
+		u32 Continuity_error_flag          : 1;
+		u32 Data_receiver_error            : 1;
+		u32 Mailbox_from_V8_Status_sig     : 1;
+		u32 DMA2_Size_IRQ_Status           : 1;
+		u32 DMA1_Size_IRQ_Status           : 1;
+		u32 DMA2_Timer_Status              : 1;
+		u32 DMA2_IRQ_Status                : 1;
+		u32 DMA1_Timer_Status              : 1;
+		u32 DMA1_IRQ_Status                : 1;
+	} irq_20c;
+
+	struct {
+		u32 Special_controls               :16;
+		u32 Block_reset_enable             : 8;
+		u32 reset_block_700                : 1;
+		u32 reset_block_600                : 1;
+		u32 reset_block_500                : 1;
+		u32 reset_block_400                : 1;
+		u32 reset_block_300                : 1;
+		u32 reset_block_200                : 1;
+		u32 reset_block_100                : 1;
+		u32 reset_block_000                : 1;
+	} sw_reset_210;
+
+	struct {
+		u32 unused2                        :20;
+		u32 polarity_PS_ERR_sig            : 1;
+		u32 polarity_PS_SYNC_sig           : 1;
+		u32 polarity_PS_VALID_sig          : 1;
+		u32 polarity_PS_CLK_sig            : 1;
+		u32 unused1                        : 3;
+		u32 s2p_sel_sig                    : 1;
+		u32 section_pkg_enable_sig         : 1;
+		u32 halt_V8_sig                    : 1;
+		u32 v2WS_oe_sig                    : 1;
+		u32 vuart_oe_sig                   : 1;
+	} misc_214;
+
+	struct {
+		u32 Mailbox_from_V8                :32;
+	} mbox_v8_to_host_218;
+
+	struct {
+		u32 sysramaccess_busmuster         : 1;
+		u32 sysramaccess_write             : 1;
+		u32 unused                         : 7;
+		u32 sysramaccess_addr              :15;
+		u32 sysramaccess_data              : 8;
+	} mbox_host_to_v8_21c;
+
+	struct {
+		u32 debug_fifo_problem             : 1;
+		u32 debug_flag_write_status00      : 1;
+		u32 Stream2_trans                  : 1;
+		u32 Stream2_PID                    :13;
+		u32 debug_flag_pid_saved           : 1;
+		u32 MAC_Multicast_filter           : 1;
+		u32 Stream1_trans                  : 1;
+		u32 Stream1_PID                    :13;
+	} pid_filter_300;
+
+	struct {
+		u32 reserved                       : 2;
+		u32 PMT_trans                      : 1;
+		u32 PMT_PID                        :13;
+		u32 debug_overrun2                 : 1;
+		u32 debug_overrun3                 : 1;
+		u32 PCR_trans                      : 1;
+		u32 PCR_PID                        :13;
+	} pid_filter_304;
+
+	struct {
+		u32 reserved                       : 2;
+		u32 ECM_trans                      : 1;
+		u32 ECM_PID                        :13;
+		u32 EMM_filter_6                   : 1;
+		u32 EMM_filter_4                   : 1;
+		u32 EMM_trans                      : 1;
+		u32 EMM_PID                        :13;
+	} pid_filter_308;
+
+	struct {
+		u32 unused2                        : 3;
+		u32 Group_mask                     :13;
+		u32 unused1                        : 2;
+		u32 Group_trans                    : 1;
+		u32 Group_PID                      :13;
+	} pid_filter_30c_ext_ind_0_7;
+
+	struct {
+		u32 unused                         :15;
+		u32 net_master_read                :17;
+	} pid_filter_30c_ext_ind_1;
+
+	struct {
+		u32 unused                         :15;
+		u32 net_master_write               :17;
+	} pid_filter_30c_ext_ind_2;
+
+	struct {
+		u32 unused                         :15;
+		u32 next_net_master_write          :17;
+	} pid_filter_30c_ext_ind_3;
+
+	struct {
+		u32 reserved2                      : 5;
+		u32 stack_read                     :10;
+		u32 reserved1                      : 6;
+		u32 state_write                    :10;
+		u32 unused1                        : 1;
+	} pid_filter_30c_ext_ind_4;
+
+	struct {
+		u32 unused                         :22;
+		u32 stack_cnt                      :10;
+	} pid_filter_30c_ext_ind_5;
+
+	struct {
+		u32 unused                         : 4;
+		u32 data_size_reg                  :12;
+		u32 write_status4                  : 2;
+		u32 write_status1                  : 2;
+		u32 pid_fsm_save_reg300            : 2;
+		u32 pid_fsm_save_reg4              : 2;
+		u32 pid_fsm_save_reg3              : 2;
+		u32 pid_fsm_save_reg2              : 2;
+		u32 pid_fsm_save_reg1              : 2;
+		u32 pid_fsm_save_reg0              : 2;
+	} pid_filter_30c_ext_ind_6;
+
+	struct {
+		u32 unused                         :22;
+		u32 pass_alltables                 : 1;
+		u32 AB_select                      : 1;
+		u32 extra_index_reg                : 3;
+		u32 index_reg                      : 5;
+	} index_reg_310;
+
+	struct {
+		u32 reserved                       :17;
+		u32 PID_enable_bit                 : 1;
+		u32 PID_trans                      : 1;
+		u32 PID                            :13;
+	} pid_n_reg_314;
+
+	struct {
+		u32 reserved                       : 6;
+		u32 HighAB_bit                     : 1;
+		u32 Enable_bit                     : 1;
+		u32 A6_byte                        : 8;
+		u32 A5_byte                        : 8;
+		u32 A4_byte                        : 8;
+	} mac_low_reg_318;
+
+	struct {
+		u32 reserved                       : 8;
+		u32 A3_byte                        : 8;
+		u32 A2_byte                        : 8;
+		u32 A1_byte                        : 8;
+	} mac_high_reg_31c;
+
+	struct {
+		u32 data_Tag_ID                    :16;
+		u32 reserved                       :16;
+	} data_tag_400;
+
+	struct {
+		u32 Card_IDbyte3                   : 8;
+		u32 Card_IDbyte4                   : 8;
+		u32 Card_IDbyte5                   : 8;
+		u32 Card_IDbyte6                   : 8;
+	} card_id_408;
+
+	struct {
+		u32 Card_IDbyte1                   : 8;
+		u32 Card_IDbyte2                   : 8;
+	} card_id_40c;
+
+	struct {
+		u32 MAC6                           : 8;
+		u32 MAC3                           : 8;
+		u32 MAC2                           : 8;
+		u32 MAC1                           : 8;
+	} mac_address_418;
+
+	struct {
+		u32 reserved                       :16;
+		u32 MAC8                           : 8;
+		u32 MAC7                           : 8;
+	} mac_address_41c;
+
+	struct {
+		u32 reserved                       :21;
+		u32 txbuffempty                    : 1;
+		u32 ReceiveByteFrameError          : 1;
+		u32 ReceiveDataReady               : 1;
+		u32 transmitter_data_byte          : 8;
+	} ci_600;
+
+	struct {
+		u32 pi_component_reg               : 3;
+		u32 pi_rw                          : 1;
+		u32 pi_ha                          :20;
+		u32 pi_d                           : 8;
+	} pi_604;
+
+	struct {
+		u32 pi_busy_n                      : 1;
+		u32 pi_wait_n                      : 1;
+		u32 pi_timeout_status              : 1;
+		u32 pi_CiMax_IRQ_n                 : 1;
+		u32 config_cclk                    : 1;
+		u32 config_cs_n                    : 1;
+		u32 config_wr_n                    : 1;
+		u32 config_Prog_n                  : 1;
+		u32 config_Init_stat               : 1;
+		u32 config_Done_stat               : 1;
+		u32 pcmcia_b_mod_pwr_n             : 1;
+		u32 pcmcia_a_mod_pwr_n             : 1;
+		u32 reserved                       : 3;
+		u32 Timer_addr                     : 5;
+		u32 unused                         : 1;
+		u32 timer_data                     : 7;
+		u32 Timer_Load_req                 : 1;
+		u32 Timer_Read_req                 : 1;
+		u32 oncecycle_read                 : 1;
+		u32 serialReset                    : 1;
+	} pi_608;
+
+	struct {
+		u32 reserved                       : 6;
+		u32 rw_flag                        : 1;
+		u32 dvb_en                         : 1;
+		u32 key_array_row                  : 5;
+		u32 key_array_col                  : 3;
+		u32 key_code                       : 2;
+		u32 key_enable                     : 1;
+		u32 PID                            :13;
+	} dvb_reg_60c;
+
+	struct {
+		u32 start_sram_ibi                 : 1;
+		u32 reserved2                      : 1;
+		u32 ce_pin_reg                     : 1;
+		u32 oe_pin_reg                     : 1;
+		u32 reserved1                      : 3;
+		u32 sc_xfer_bit                    : 1;
+		u32 sram_data                      : 8;
+		u32 sram_rw                        : 1;
+		u32 sram_addr                      :15;
+	} sram_ctrl_reg_700;
+
+	struct {
+		u32 net_addr_write                 :16;
+		u32 net_addr_read                  :16;
+	} net_buf_reg_704;
+
+	struct {
+		u32 cai_cnt                        : 4;
+		u32 reserved2                      : 6;
+		u32 cai_write                      :11;
+		u32 reserved1                      : 5;
+		u32 cai_read                       :11;
+	} cai_buf_reg_708;
+
+	struct {
+		u32 cao_cnt                        : 4;
+		u32 reserved2                      : 6;
+		u32 cap_write                      :11;
+		u32 reserved1                      : 5;
+		u32 cao_read                       :11;
+	} cao_buf_reg_70c;
+
+	struct {
+		u32 media_cnt                      : 4;
+		u32 reserved2                      : 6;
+		u32 media_write                    :11;
+		u32 reserved1                      : 5;
+		u32 media_read                     :11;
+	} media_buf_reg_710;
+
+	struct {
+		u32 reserved                       :17;
+		u32 ctrl_maximumfill               : 1;
+		u32 ctrl_sramdma                   : 1;
+		u32 ctrl_usb_wan                   : 1;
+		u32 cao_ovflow_error               : 1;
+		u32 cai_ovflow_error               : 1;
+		u32 media_ovflow_error             : 1;
+		u32 net_ovflow_error               : 1;
+		u32 MEDIA_Dest                     : 2;
+		u32 CAO_Dest                       : 2;
+		u32 CAI_Dest                       : 2;
+		u32 NET_Dest                       : 2;
+	} sram_dest_reg_714;
+
+	struct {
+		u32 reserved3                      :11;
+		u32 net_addr_write                 : 1;
+		u32 reserved2                      : 3;
+		u32 net_addr_read                  : 1;
+		u32 reserved1                      : 4;
+		u32 net_cnt                        :12;
+	} net_buf_reg_718;
+
+	struct {
+		u32 reserved3                      : 4;
+		u32 wan_pkt_frame                  : 4;
+		u32 reserved2                      : 4;
+		u32 sram_memmap                    : 2;
+		u32 sram_chip                      : 2;
+		u32 wan_wait_state                 : 8;
+		u32 reserved1                      : 6;
+		u32 wan_speed_sig                  : 2;
+	} wan_ctrl_reg_71c;
+} flexcop_ibi_value;
+
+#endif
diff --git a/drivers/media/dvb/b2c2/flexcop_ibi_value_le.h b/drivers/media/dvb/b2c2/flexcop_ibi_value_le.h
new file mode 100644
--- /dev/null
+++ b/drivers/media/dvb/b2c2/flexcop_ibi_value_le.h
@@ -0,0 +1,458 @@
+/* This file is part of linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
+ *
+ * register descriptions
+ *
+ * see flexcop.c for copyright information.
+ */
+
+/* This file is automatically generated, do not edit things here. */
+#ifndef __FLEXCOP_IBI_VALUE_INCLUDED__
+#define __FLEXCOP_IBI_VALUE_INCLUDED__
+
+typedef union {
+	u32 raw;
+
+	struct {
+		u32 dma_0start                     : 1;
+		u32 dma_0No_update                 : 1;
+		u32 dma_address0                   :30;
+	} dma_0x0;
+
+	struct {
+		u32 DMA_maxpackets                 : 8;
+		u32 dma_addr_size                  :24;
+	} dma_0x4_remap;
+
+	struct {
+		u32 dma1timer                      : 7;
+		u32 unused                         : 1;
+		u32 dma_addr_size                  :24;
+	} dma_0x4_read;
+
+	struct {
+		u32 unused                         : 1;
+		u32 dmatimer                       : 7;
+		u32 dma_addr_size                  :24;
+	} dma_0x4_write;
+
+	struct {
+		u32 unused                         : 2;
+		u32 dma_cur_addr                   :30;
+	} dma_0x8;
+
+	struct {
+		u32 dma_1start                     : 1;
+		u32 remap_enable                   : 1;
+		u32 dma_address1                   :30;
+	} dma_0xc;
+
+	struct {
+		u32 chipaddr                       : 7;
+		u32 reserved1                      : 1;
+		u32 baseaddr                       : 8;
+		u32 data1_reg                      : 8;
+		u32 working_start                  : 1;
+		u32 twoWS_rw                       : 1;
+		u32 total_bytes                    : 2;
+		u32 twoWS_port_reg                 : 2;
+		u32 no_base_addr_ack_error         : 1;
+		u32 st_done                        : 1;
+	} tw_sm_c_100;
+
+	struct {
+		u32 data2_reg                      : 8;
+		u32 data3_reg                      : 8;
+		u32 data4_reg                      : 8;
+		u32 exlicit_stops                  : 1;
+		u32 force_stop                     : 1;
+		u32 unused                         : 6;
+	} tw_sm_c_104;
+
+	struct {
+		u32 thi1                           : 6;
+		u32 reserved1                      : 2;
+		u32 tlo1                           : 5;
+		u32 reserved2                      :19;
+	} tw_sm_c_108;
+
+	struct {
+		u32 thi1                           : 6;
+		u32 reserved1                      : 2;
+		u32 tlo1                           : 5;
+		u32 reserved2                      :19;
+	} tw_sm_c_10c;
+
+	struct {
+		u32 thi1                           : 6;
+		u32 reserved1                      : 2;
+		u32 tlo1                           : 5;
+		u32 reserved2                      :19;
+	} tw_sm_c_110;
+
+	struct {
+		u32 LNB_CTLHighCount_sig           :15;
+		u32 LNB_CTLLowCount_sig            :15;
+		u32 LNB_CTLPrescaler_sig           : 2;
+	} lnb_switch_freq_200;
+
+	struct {
+		u32 ACPI1_sig                      : 1;
+		u32 ACPI3_sig                      : 1;
+		u32 LNB_L_H_sig                    : 1;
+		u32 Per_reset_sig                  : 1;
+		u32 reserved                       :20;
+		u32 Rev_N_sig_revision_hi          : 4;
+		u32 Rev_N_sig_reserved1            : 2;
+		u32 Rev_N_sig_caps                 : 1;
+		u32 Rev_N_sig_reserved2            : 1;
+	} misc_204;
+
+	struct {
+		u32 Stream1_filter_sig             : 1;
+		u32 Stream2_filter_sig             : 1;
+		u32 PCR_filter_sig                 : 1;
+		u32 PMT_filter_sig                 : 1;
+		u32 EMM_filter_sig                 : 1;
+		u32 ECM_filter_sig                 : 1;
+		u32 Null_filter_sig                : 1;
+		u32 Mask_filter_sig                : 1;
+		u32 WAN_Enable_sig                 : 1;
+		u32 WAN_CA_Enable_sig              : 1;
+		u32 CA_Enable_sig                  : 1;
+		u32 SMC_Enable_sig                 : 1;
+		u32 Per_CA_Enable_sig              : 1;
+		u32 Multi2_Enable_sig              : 1;
+		u32 MAC_filter_Mode_sig            : 1;
+		u32 Rcv_Data_sig                   : 1;
+		u32 DMA1_IRQ_Enable_sig            : 1;
+		u32 DMA1_Timer_Enable_sig          : 1;
+		u32 DMA2_IRQ_Enable_sig            : 1;
+		u32 DMA2_Timer_Enable_sig          : 1;
+		u32 DMA1_Size_IRQ_Enable_sig       : 1;
+		u32 DMA2_Size_IRQ_Enable_sig       : 1;
+		u32 Mailbox_from_V8_Enable_sig     : 1;
+		u32 unused                         : 9;
+	} ctrl_208;
+
+	struct {
+		u32 DMA1_IRQ_Status                : 1;
+		u32 DMA1_Timer_Status              : 1;
+		u32 DMA2_IRQ_Status                : 1;
+		u32 DMA2_Timer_Status              : 1;
+		u32 DMA1_Size_IRQ_Status           : 1;
+		u32 DMA2_Size_IRQ_Status           : 1;
+		u32 Mailbox_from_V8_Status_sig     : 1;
+		u32 Data_receiver_error            : 1;
+		u32 Continuity_error_flag          : 1;
+		u32 LLC_SNAP_FLAG_set              : 1;
+		u32 Transport_Error                : 1;
+		u32 reserved                       :21;
+	} irq_20c;
+
+	struct {
+		u32 reset_block_000                : 1;
+		u32 reset_block_100                : 1;
+		u32 reset_block_200                : 1;
+		u32 reset_block_300                : 1;
+		u32 reset_block_400                : 1;
+		u32 reset_block_500                : 1;
+		u32 reset_block_600                : 1;
+		u32 reset_block_700                : 1;
+		u32 Block_reset_enable             : 8;
+		u32 Special_controls               :16;
+	} sw_reset_210;
+
+	struct {
+		u32 vuart_oe_sig                   : 1;
+		u32 v2WS_oe_sig                    : 1;
+		u32 halt_V8_sig                    : 1;
+		u32 section_pkg_enable_sig         : 1;
+		u32 s2p_sel_sig                    : 1;
+		u32 unused1                        : 3;
+		u32 polarity_PS_CLK_sig            : 1;
+		u32 polarity_PS_VALID_sig          : 1;
+		u32 polarity_PS_SYNC_sig           : 1;
+		u32 polarity_PS_ERR_sig            : 1;
+		u32 unused2                        :20;
+	} misc_214;
+
+	struct {
+		u32 Mailbox_from_V8                :32;
+	} mbox_v8_to_host_218;
+
+	struct {
+		u32 sysramaccess_data              : 8;
+		u32 sysramaccess_addr              :15;
+		u32 unused                         : 7;
+		u32 sysramaccess_write             : 1;
+		u32 sysramaccess_busmuster         : 1;
+	} mbox_host_to_v8_21c;
+
+	struct {
+		u32 Stream1_PID                    :13;
+		u32 Stream1_trans                  : 1;
+		u32 MAC_Multicast_filter           : 1;
+		u32 debug_flag_pid_saved           : 1;
+		u32 Stream2_PID                    :13;
+		u32 Stream2_trans                  : 1;
+		u32 debug_flag_write_status00      : 1;
+		u32 debug_fifo_problem             : 1;
+	} pid_filter_300;
+
+	struct {
+		u32 PCR_PID                        :13;
+		u32 PCR_trans                      : 1;
+		u32 debug_overrun3                 : 1;
+		u32 debug_overrun2                 : 1;
+		u32 PMT_PID                        :13;
+		u32 PMT_trans                      : 1;
+		u32 reserved                       : 2;
+	} pid_filter_304;
+
+	struct {
+		u32 EMM_PID                        :13;
+		u32 EMM_trans                      : 1;
+		u32 EMM_filter_4                   : 1;
+		u32 EMM_filter_6                   : 1;
+		u32 ECM_PID                        :13;
+		u32 ECM_trans                      : 1;
+		u32 reserved                       : 2;
+	} pid_filter_308;
+
+	struct {
+		u32 Group_PID                      :13;
+		u32 Group_trans                    : 1;
+		u32 unused1                        : 2;
+		u32 Group_mask                     :13;
+		u32 unused2                        : 3;
+	} pid_filter_30c_ext_ind_0_7;
+
+	struct {
+		u32 net_master_read                :17;
+		u32 unused                         :15;
+	} pid_filter_30c_ext_ind_1;
+
+	struct {
+		u32 net_master_write               :17;
+		u32 unused                         :15;
+	} pid_filter_30c_ext_ind_2;
+
+	struct {
+		u32 next_net_master_write          :17;
+		u32 unused                         :15;
+	} pid_filter_30c_ext_ind_3;
+
+	struct {
+		u32 unused1                        : 1;
+		u32 state_write                    :10;
+		u32 reserved1                      : 6;
+		u32 stack_read                     :10;
+		u32 reserved2                      : 5;
+	} pid_filter_30c_ext_ind_4;
+
+	struct {
+		u32 stack_cnt                      :10;
+		u32 unused                         :22;
+	} pid_filter_30c_ext_ind_5;
+
+	struct {
+		u32 pid_fsm_save_reg0              : 2;
+		u32 pid_fsm_save_reg1              : 2;
+		u32 pid_fsm_save_reg2              : 2;
+		u32 pid_fsm_save_reg3              : 2;
+		u32 pid_fsm_save_reg4              : 2;
+		u32 pid_fsm_save_reg300            : 2;
+		u32 write_status1                  : 2;
+		u32 write_status4                  : 2;
+		u32 data_size_reg                  :12;
+		u32 unused                         : 4;
+	} pid_filter_30c_ext_ind_6;
+
+	struct {
+		u32 index_reg                      : 5;
+		u32 extra_index_reg                : 3;
+		u32 AB_select                      : 1;
+		u32 pass_alltables                 : 1;
+		u32 unused                         :22;
+	} index_reg_310;
+
+	struct {
+		u32 PID                            :13;
+		u32 PID_trans                      : 1;
+		u32 PID_enable_bit                 : 1;
+		u32 reserved                       :17;
+	} pid_n_reg_314;
+
+	struct {
+		u32 A4_byte                        : 8;
+		u32 A5_byte                        : 8;
+		u32 A6_byte                        : 8;
+		u32 Enable_bit                     : 1;
+		u32 HighAB_bit                     : 1;
+		u32 reserved                       : 6;
+	} mac_low_reg_318;
+
+	struct {
+		u32 A1_byte                        : 8;
+		u32 A2_byte                        : 8;
+		u32 A3_byte                        : 8;
+		u32 reserved                       : 8;
+	} mac_high_reg_31c;
+
+	struct {
+		u32 reserved                       :16;
+		u32 data_Tag_ID                    :16;
+	} data_tag_400;
+
+	struct {
+		u32 Card_IDbyte6                   : 8;
+		u32 Card_IDbyte5                   : 8;
+		u32 Card_IDbyte4                   : 8;
+		u32 Card_IDbyte3                   : 8;
+	} card_id_408;
+
+	struct {
+		u32 Card_IDbyte2                   : 8;
+		u32 Card_IDbyte1                   : 8;
+	} card_id_40c;
+
+	struct {
+		u32 MAC1                           : 8;
+		u32 MAC2                           : 8;
+		u32 MAC3                           : 8;
+		u32 MAC6                           : 8;
+	} mac_address_418;
+
+	struct {
+		u32 MAC7                           : 8;
+		u32 MAC8                           : 8;
+		u32 reserved                       :16;
+	} mac_address_41c;
+
+	struct {
+		u32 transmitter_data_byte          : 8;
+		u32 ReceiveDataReady               : 1;
+		u32 ReceiveByteFrameError          : 1;
+		u32 txbuffempty                    : 1;
+		u32 reserved                       :21;
+	} ci_600;
+
+	struct {
+		u32 pi_d                           : 8;
+		u32 pi_ha                          :20;
+		u32 pi_rw                          : 1;
+		u32 pi_component_reg               : 3;
+	} pi_604;
+
+	struct {
+		u32 serialReset                    : 1;
+		u32 oncecycle_read                 : 1;
+		u32 Timer_Read_req                 : 1;
+		u32 Timer_Load_req                 : 1;
+		u32 timer_data                     : 7;
+		u32 unused                         : 1;
+		u32 Timer_addr                     : 5;
+		u32 reserved                       : 3;
+		u32 pcmcia_a_mod_pwr_n             : 1;
+		u32 pcmcia_b_mod_pwr_n             : 1;
+		u32 config_Done_stat               : 1;
+		u32 config_Init_stat               : 1;
+		u32 config_Prog_n                  : 1;
+		u32 config_wr_n                    : 1;
+		u32 config_cs_n                    : 1;
+		u32 config_cclk                    : 1;
+		u32 pi_CiMax_IRQ_n                 : 1;
+		u32 pi_timeout_status              : 1;
+		u32 pi_wait_n                      : 1;
+		u32 pi_busy_n                      : 1;
+	} pi_608;
+
+	struct {
+		u32 PID                            :13;
+		u32 key_enable                     : 1;
+		u32 key_code                       : 2;
+		u32 key_array_col                  : 3;
+		u32 key_array_row                  : 5;
+		u32 dvb_en                         : 1;
+		u32 rw_flag                        : 1;
+		u32 reserved                       : 6;
+	} dvb_reg_60c;
+
+	struct {
+		u32 sram_addr                      :15;
+		u32 sram_rw                        : 1;
+		u32 sram_data                      : 8;
+		u32 sc_xfer_bit                    : 1;
+		u32 reserved1                      : 3;
+		u32 oe_pin_reg                     : 1;
+		u32 ce_pin_reg                     : 1;
+		u32 reserved2                      : 1;
+		u32 start_sram_ibi                 : 1;
+	} sram_ctrl_reg_700;
+
+	struct {
+		u32 net_addr_read                  :16;
+		u32 net_addr_write                 :16;
+	} net_buf_reg_704;
+
+	struct {
+		u32 cai_read                       :11;
+		u32 reserved1                      : 5;
+		u32 cai_write                      :11;
+		u32 reserved2                      : 6;
+		u32 cai_cnt                        : 4;
+	} cai_buf_reg_708;
+
+	struct {
+		u32 cao_read                       :11;
+		u32 reserved1                      : 5;
+		u32 cap_write                      :11;
+		u32 reserved2                      : 6;
+		u32 cao_cnt                        : 4;
+	} cao_buf_reg_70c;
+
+	struct {
+		u32 media_read                     :11;
+		u32 reserved1                      : 5;
+		u32 media_write                    :11;
+		u32 reserved2                      : 6;
+		u32 media_cnt                      : 4;
+	} media_buf_reg_710;
+
+	struct {
+		u32 NET_Dest                       : 2;
+		u32 CAI_Dest                       : 2;
+		u32 CAO_Dest                       : 2;
+		u32 MEDIA_Dest                     : 2;
+		u32 net_ovflow_error               : 1;
+		u32 media_ovflow_error             : 1;
+		u32 cai_ovflow_error               : 1;
+		u32 cao_ovflow_error               : 1;
+		u32 ctrl_usb_wan                   : 1;
+		u32 ctrl_sramdma                   : 1;
+		u32 ctrl_maximumfill               : 1;
+		u32 reserved                       :17;
+	} sram_dest_reg_714;
+
+	struct {
+		u32 net_cnt                        :12;
+		u32 reserved1                      : 4;
+		u32 net_addr_read                  : 1;
+		u32 reserved2                      : 3;
+		u32 net_addr_write                 : 1;
+		u32 reserved3                      :11;
+	} net_buf_reg_718;
+
+	struct {
+		u32 wan_speed_sig                  : 2;
+		u32 reserved1                      : 6;
+		u32 wan_wait_state                 : 8;
+		u32 sram_chip                      : 2;
+		u32 sram_memmap                    : 2;
+		u32 reserved2                      : 4;
+		u32 wan_pkt_frame                  : 4;
+		u32 reserved3                      : 4;
+	} wan_ctrl_reg_71c;
+} flexcop_ibi_value;
+
+#endif
diff --git a/drivers/media/dvb/b2c2/skystar2.c b/drivers/media/dvb/b2c2/skystar2.c
deleted file mode 100644
--- a/drivers/media/dvb/b2c2/skystar2.c
+++ /dev/null
@@ -1,2644 +0,0 @@
-/*
- * skystar2.c - driver for the Technisat SkyStar2 PCI DVB card
- *              based on the FlexCopII by B2C2,Inc.
- *
- * Copyright (C) 2003  Vadim Catana, skystar@moldova.cc
- *
- * FIX: DISEQC Tone Burst in flexcop_diseqc_ioctl()
- * FIX: FULL soft DiSEqC for skystar2 (FlexCopII rev 130) VP310 equipped
- *     Vincenzo Di Massa, hawk.it at tiscalinet.it
- *
- * Converted to Linux coding style
- * Misc reorganization, polishing, restyling
- *     Roberto Ragusa, skystar2-c5b8 at robertoragusa dot it
- *
- * Added hardware filtering support,
- *     Niklas Peinecke, peinecke at gdv.uni-hannover.de
- *
- *
- * 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/module.h>
-#include <linux/moduleparam.h>
-#include <linux/delay.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/version.h>
-
-#include <asm/io.h>
-
-#include "dvb_frontend.h"
-
-#include <linux/dvb/frontend.h>
-#include <linux/dvb/dmx.h>
-#include "dvb_demux.h"
-#include "dmxdev.h"
-#include "dvb_filter.h"
-#include "dvbdev.h"
-#include "demux.h"
-#include "dvb_net.h"
-#include "stv0299.h"
-#include "mt352.h"
-#include "mt312.h"
-#include "nxt2002.h"
-
-static int debug;
-static int enable_hw_filters = 2;
-
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Set debugging level (0 = default, 1 = most messages, 2 = all messages).");
-module_param(enable_hw_filters, int, 0444);
-MODULE_PARM_DESC(enable_hw_filters, "enable hardware filters: supported values: 0 (none), 1, 2");
-
-#define dprintk(x...)	do { if (debug>=1) printk(x); } while (0)
-#define ddprintk(x...)	do { if (debug>=2) printk(x); } while (0)
-
-#define SIZE_OF_BUF_DMA1	0x3ac00
-#define SIZE_OF_BUF_DMA2	0x758
-
-#define MAX_N_HW_FILTERS	(6+32)
-#define N_PID_SLOTS		256
-
-struct dmaq {
-	u32 bus_addr;
-	u32 head;
-	u32 tail;
-	u32 buffer_size;
-	u8 *buffer;
-};
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9)
-#define __iomem
-#endif
-
-struct adapter {
-	struct pci_dev *pdev;
-
-	u8 card_revision;
-	u32 b2c2_revision;
-	u32 pid_filter_max;
-	u32 mac_filter_max;
-	u32 irq;
-	void __iomem *io_mem;
-	unsigned long io_port;
-	u8 mac_addr[8];
-	u32 dw_sram_type;
-
-	struct dvb_adapter dvb_adapter;
-	struct dvb_demux demux;
-	struct dmxdev dmxdev;
-	struct dmx_frontend hw_frontend;
-	struct dmx_frontend mem_frontend;
-	struct i2c_adapter i2c_adap;
-	struct dvb_net dvbnet;
-
-	struct semaphore i2c_sem;
-
-	struct dmaq dmaq1;
-	struct dmaq dmaq2;
-
-	u32 dma_ctrl;
-	u32 dma_status;
-
-	int capturing;
-
-	spinlock_t lock;
-
-	int useable_hw_filters;
-	u16 hw_pids[MAX_N_HW_FILTERS];
-	u16 pid_list[N_PID_SLOTS];
-	int pid_rc[N_PID_SLOTS];	// ref counters for the pids
-	int pid_count;
-	int whole_bandwidth_count;
-	u32 mac_filter;
-
-	struct dvb_frontend* fe;
-	int (*fe_sleep)(struct dvb_frontend* fe);
-};
-
-#define write_reg_dw(adapter,reg,value) writel(value, adapter->io_mem + reg)
-#define read_reg_dw(adapter,reg) readl(adapter->io_mem + reg)
-
-static void write_reg_bitfield(struct adapter *adapter, u32 reg, u32 zeromask, u32 orvalue)
-{
-	u32 tmp;
-
-	tmp = read_reg_dw(adapter, reg);
-	tmp = (tmp & ~zeromask) | orvalue;
-	write_reg_dw(adapter, reg, tmp);
-}
-
-/* i2c functions */
-static int i2c_main_write_for_flex2(struct adapter *adapter, u32 command, u8 *buf, int retries)
-{
-	int i;
-	u32 value;
-
-	write_reg_dw(adapter, 0x100, 0);
-	write_reg_dw(adapter, 0x100, command);
-
-	for (i = 0; i < retries; i++) {
-		value = read_reg_dw(adapter, 0x100);
-
-		if ((value & 0x40000000) == 0) {
-			if ((value & 0x81000000) == 0x80000000) {
-				if (buf != 0)
-					*buf = (value >> 0x10) & 0xff;
-
-				return 1;
-			}
-		} else {
-			write_reg_dw(adapter, 0x100, 0);
-			write_reg_dw(adapter, 0x100, command);
-		}
-	}
-
-	return 0;
-}
-
-/* device = 0x10000000 for tuner, 0x20000000 for eeprom */
-static void i2c_main_setup(u32 device, u32 chip_addr, u8 op, u8 addr, u32 value, u32 len, u32 *command)
-{
-	*command = device | ((len - 1) << 26) | (value << 16) | (addr << 8) | chip_addr;
-
-	if (op != 0)
-		*command = *command | 0x03000000;
-	else
-		*command = *command | 0x01000000;
-}
-
-static int flex_i2c_read4(struct adapter *adapter, u32 device, u32 chip_addr, u16 addr, u8 *buf, u8 len)
-{
-	u32 command;
-	u32 value;
-
-	int result, i;
-
-	i2c_main_setup(device, chip_addr, 1, addr, 0, len, &command);
-
-	result = i2c_main_write_for_flex2(adapter, command, buf, 100000);
-
-	if ((result & 0xff) != 0) {
-		if (len > 1) {
-			value = read_reg_dw(adapter, 0x104);
-
-			for (i = 1; i < len; i++) {
-				buf[i] = value & 0xff;
-				value = value >> 8;
-			}
-		}
-	}
-
-	return result;
-}
-
-static int flex_i2c_write4(struct adapter *adapter, u32 device, u32 chip_addr, u32 addr, u8 *buf, u8 len)
-{
-	u32 command;
-	u32 value;
-	int i;
-
-	if (len > 1) {
-		value = 0;
-
-		for (i = len; i > 1; i--) {
-			value = value << 8;
-			value = value | buf[i - 1];
-		}
-
-		write_reg_dw(adapter, 0x104, value);
-	}
-
-	i2c_main_setup(device, chip_addr, 0, addr, buf[0], len, &command);
-
-	return i2c_main_write_for_flex2(adapter, command, NULL, 100000);
-}
-
-static void fixchipaddr(u32 device, u32 bus, u32 addr, u32 *ret)
-{
-	if (device == 0x20000000)
-		*ret = bus | ((addr >> 8) & 3);
-	else
-		*ret = bus;
-}
-
-static u32 flex_i2c_read(struct adapter *adapter, u32 device, u32 bus, u32 addr, u8 *buf, u32 len)
-{
-	u32 chipaddr;
-	u32 bytes_to_transfer;
-	u8 *start;
-
-	ddprintk("%s:\n", __FUNCTION__);
-
-	start = buf;
-
-	while (len != 0) {
-		bytes_to_transfer = len;
-
-		if (bytes_to_transfer > 4)
-			bytes_to_transfer = 4;
-
-		fixchipaddr(device, bus, addr, &chipaddr);
-
-		if (flex_i2c_read4(adapter, device, chipaddr, addr, buf, bytes_to_transfer) == 0)
-			return buf - start;
-
-		buf = buf + bytes_to_transfer;
-		addr = addr + bytes_to_transfer;
-		len = len - bytes_to_transfer;
-	};
-
-	return buf - start;
-}
-
-static u32 flex_i2c_write(struct adapter *adapter, u32 device, u32 bus, u32 addr, u8 *buf, u32 len)
-{
-	u32 chipaddr;
-	u32 bytes_to_transfer;
-	u8 *start;
-
-	ddprintk("%s:\n", __FUNCTION__);
-
-	start = buf;
-
-	while (len != 0) {
-		bytes_to_transfer = len;
-
-		if (bytes_to_transfer > 4)
-			bytes_to_transfer = 4;
-
-		fixchipaddr(device, bus, addr, &chipaddr);
-
-		if (flex_i2c_write4(adapter, device, chipaddr, addr, buf, bytes_to_transfer) == 0)
-			return buf - start;
-
-		buf = buf + bytes_to_transfer;
-		addr = addr + bytes_to_transfer;
-		len = len - bytes_to_transfer;
-	}
-
-	return buf - start;
-}
-
-static int master_xfer(struct i2c_adapter* adapter, struct i2c_msg *msgs, int num)
-{
-	struct adapter *tmp = i2c_get_adapdata(adapter);
-	int i, ret = 0;
-
-	if (down_interruptible(&tmp->i2c_sem))
-		return -ERESTARTSYS;
-
-	ddprintk("%s: %d messages to transfer\n", __FUNCTION__, num);
-
-		for (i = 0; i < num; i++) {
-		ddprintk("message %d: flags=0x%x, addr=0x%x, buf=0x%x, len=%d \n", i,
-			 msgs[i].flags, msgs[i].addr, msgs[i].buf[0], msgs[i].len);
-	}
-
-	// read command
-	if ((num == 2) && (msgs[0].flags == 0) && (msgs[1].flags == I2C_M_RD) && (msgs[0].buf != NULL) && (msgs[1].buf != NULL)) {
-
-		ret = flex_i2c_read(tmp, 0x10000000, msgs[0].addr, msgs[0].buf[0], msgs[1].buf, msgs[1].len);
-
-		up(&tmp->i2c_sem);
-
-		if (ret != msgs[1].len) {
-			dprintk("%s: read error !\n", __FUNCTION__);
-
-			for (i = 0; i < 2; i++) {
-				dprintk("message %d: flags=0x%x, addr=0x%x, buf=0x%x, len=%d \n", i,
-				       msgs[i].flags, msgs[i].addr, msgs[i].buf[0], msgs[i].len);
-		}
-
-			return -EREMOTEIO;
-		}
-
-		return num;
-	}
-	// write command
-	for (i = 0; i < num; i++) {
-
-		if ((msgs[i].flags != 0) || (msgs[i].buf == NULL) || (msgs[i].len < 2))
-			return -EINVAL;
-
-		ret = flex_i2c_write(tmp, 0x10000000, msgs[i].addr, msgs[i].buf[0], &msgs[i].buf[1], msgs[i].len - 1);
-
-		up(&tmp->i2c_sem);
-
-		if (ret != msgs[0].len - 1) {
-			dprintk("%s: write error %i !\n", __FUNCTION__, ret);
-
-			dprintk("message %d: flags=0x%x, addr=0x%x, buf[0]=0x%x, len=%d \n", i,
-			       msgs[i].flags, msgs[i].addr, msgs[i].buf[0], msgs[i].len);
-
-			return -EREMOTEIO;
-		}
-
-		return num;
-	}
-
-	printk("%s: unknown command format !\n", __FUNCTION__);
-
-	return -EINVAL;
-}
-
-/* SRAM (Skystar2 rev2.3 has one "ISSI IS61LV256" chip on board,
-   but it seems that FlexCopII can work with more than one chip) */
-static void sram_set_net_dest(struct adapter *adapter, u8 dest)
-{
-	u32 tmp;
-
-	udelay(1000);
-
-	tmp = (read_reg_dw(adapter, 0x714) & 0xfffffffc) | (dest & 3);
-
-	udelay(1000);
-
-	write_reg_dw(adapter, 0x714, tmp);
-	write_reg_dw(adapter, 0x714, tmp);
-
-	udelay(1000);
-
-	/* return value is never used? */
-/*	return tmp; */
-}
-
-static void sram_set_cai_dest(struct adapter *adapter, u8 dest)
-{
-	u32 tmp;
-
-	udelay(1000);
-
-	tmp = (read_reg_dw(adapter, 0x714) & 0xfffffff3) | ((dest & 3) << 2);
-
-	udelay(1000);
-	udelay(1000);
-
-	write_reg_dw(adapter, 0x714, tmp);
-	write_reg_dw(adapter, 0x714, tmp);
-
-	udelay(1000);
-
-	/* return value is never used? */
-/*	return tmp; */
-}
-
-static void sram_set_cao_dest(struct adapter *adapter, u8 dest)
-{
-	u32 tmp;
-
-	udelay(1000);
-
-	tmp = (read_reg_dw(adapter, 0x714) & 0xffffffcf) | ((dest & 3) << 4);
-
-	udelay(1000);
-	udelay(1000);
-
-	write_reg_dw(adapter, 0x714, tmp);
-	write_reg_dw(adapter, 0x714, tmp);
-
-	udelay(1000);
-
-	/* return value is never used? */
-/*	return tmp; */
-}
-
-static void sram_set_media_dest(struct adapter *adapter, u8 dest)
-{
-	u32 tmp;
-
-	udelay(1000);
-
-	tmp = (read_reg_dw(adapter, 0x714) & 0xffffff3f) | ((dest & 3) << 6);
-
-	udelay(1000);
-	udelay(1000);
-
-	write_reg_dw(adapter, 0x714, tmp);
-	write_reg_dw(adapter, 0x714, tmp);
-
-	udelay(1000);
-
-	/* return value is never used? */
-/*	return tmp; */
-}
-
-/* SRAM memory is accessed through a buffer register in the FlexCop
-   chip (0x700). This register has the following structure:
-    bits 0-14  : address
-    bit  15    : read/write flag
-    bits 16-23 : 8-bit word to write
-    bits 24-27 : = 4
-    bits 28-29 : memory bank selector
-    bit  31    : busy flag
-*/
-static void flex_sram_write(struct adapter *adapter, u32 bank, u32 addr, u8 *buf, u32 len)
-{
-	int i, retries;
-	u32 command;
-
-	for (i = 0; i < len; i++) {
-		command = bank | addr | 0x04000000 | (*buf << 0x10);
-
-		retries = 2;
-
-		while (((read_reg_dw(adapter, 0x700) & 0x80000000) != 0) && (retries > 0)) {
-			mdelay(1);
-			retries--;
-		};
-
-		if (retries == 0)
-			printk("%s: SRAM timeout\n", __FUNCTION__);
-
-		write_reg_dw(adapter, 0x700, command);
-
-		buf++;
-		addr++;
-	}
-}
-
-static void flex_sram_read(struct adapter *adapter, u32 bank, u32 addr, u8 *buf, u32 len)
-{
-	int i, retries;
-	u32 command, value;
-
-	for (i = 0; i < len; i++) {
-		command = bank | addr | 0x04008000;
-
-		retries = 10000;
-
-		while (((read_reg_dw(adapter, 0x700) & 0x80000000) != 0) && (retries > 0)) {
-			mdelay(1);
-			retries--;
-		};
-
-		if (retries == 0)
-			printk("%s: SRAM timeout\n", __FUNCTION__);
-
-		write_reg_dw(adapter, 0x700, command);
-
-		retries = 10000;
-
-		while (((read_reg_dw(adapter, 0x700) & 0x80000000) != 0) && (retries > 0)) {
-			mdelay(1);
-			retries--;
-		};
-
-		if (retries == 0)
-			printk("%s: SRAM timeout\n", __FUNCTION__);
-
-		value = read_reg_dw(adapter, 0x700) >> 0x10;
-
-		*buf = (value & 0xff);
-
-		addr++;
-		buf++;
-	}
-}
-
-static void sram_write_chunk(struct adapter *adapter, u32 addr, u8 *buf, u16 len)
-{
-	u32 bank;
-
-	bank = 0;
-
-	if (adapter->dw_sram_type == 0x20000) {
-		bank = (addr & 0x18000) << 0x0d;
-	}
-
-	if (adapter->dw_sram_type == 0x00000) {
-		if ((addr >> 0x0f) == 0)
-			bank = 0x20000000;
-		else
-			bank = 0x10000000;
-	}
-
-	flex_sram_write(adapter, bank, addr & 0x7fff, buf, len);
-}
-
-static void sram_read_chunk(struct adapter *adapter, u32 addr, u8 *buf, u16 len)
-{
-	u32 bank;
-
-	bank = 0;
-
-	if (adapter->dw_sram_type == 0x20000) {
-		bank = (addr & 0x18000) << 0x0d;
-	}
-
-	if (adapter->dw_sram_type == 0x00000) {
-		if ((addr >> 0x0f) == 0)
-			bank = 0x20000000;
-		else
-			bank = 0x10000000;
-	}
-
-	flex_sram_read(adapter, bank, addr & 0x7fff, buf, len);
-}
-
-static void sram_read(struct adapter *adapter, u32 addr, u8 *buf, u32 len)
-{
-	u32 length;
-
-	while (len != 0) {
-		length = len;
-
-		// check if the address range belongs to the same 
-		// 32K memory chip. If not, the data is read from 
-		// one chip at a time.
-		if ((addr >> 0x0f) != ((addr + len - 1) >> 0x0f)) {
-			length = (((addr >> 0x0f) + 1) << 0x0f) - addr;
-		}
-
-		sram_read_chunk(adapter, addr, buf, length);
-
-		addr = addr + length;
-		buf = buf + length;
-		len = len - length;
-	}
-}
-
-static void sram_write(struct adapter *adapter, u32 addr, u8 *buf, u32 len)
-{
-	u32 length;
-
-	while (len != 0) {
-		length = len;
-
-		// check if the address range belongs to the same 
-		// 32K memory chip. If not, the data is written to
-		// one chip at a time.
-		if ((addr >> 0x0f) != ((addr + len - 1) >> 0x0f)) {
-			length = (((addr >> 0x0f) + 1) << 0x0f) - addr;
-		}
-
-		sram_write_chunk(adapter, addr, buf, length);
-
-		addr = addr + length;
-		buf = buf + length;
-		len = len - length;
-	}
-}
-
-static void sram_set_size(struct adapter *adapter, u32 mask)
-{
-	write_reg_dw(adapter, 0x71c, (mask | (~0x30000 & read_reg_dw(adapter, 0x71c))));
-}
-
-static void sram_init(struct adapter *adapter)
-{
-	u32 tmp;
-
-	tmp = read_reg_dw(adapter, 0x71c);
-
-	write_reg_dw(adapter, 0x71c, 1);
-
-	if (read_reg_dw(adapter, 0x71c) != 0) {
-		write_reg_dw(adapter, 0x71c, tmp);
-
-		adapter->dw_sram_type = tmp & 0x30000;
-
-		ddprintk("%s: dw_sram_type = %x\n", __FUNCTION__, adapter->dw_sram_type);
-
-	} else {
-
-		adapter->dw_sram_type = 0x10000;
-
-		ddprintk("%s: dw_sram_type = %x\n", __FUNCTION__, adapter->dw_sram_type);
-	}
-
-	/* return value is never used? */
-/*	return adapter->dw_sram_type; */
-}
-
-static int sram_test_location(struct adapter *adapter, u32 mask, u32 addr)
-{
-	u8 tmp1, tmp2;
-
-	dprintk("%s: mask = %x, addr = %x\n", __FUNCTION__, mask, addr);
-
-	sram_set_size(adapter, mask);
-	sram_init(adapter);
-
-	tmp2 = 0xa5;
-	tmp1 = 0x4f;
-
-	sram_write(adapter, addr, &tmp2, 1);
-	sram_write(adapter, addr + 4, &tmp1, 1);
-
-	tmp2 = 0;
-
-	mdelay(20);
-
-	sram_read(adapter, addr, &tmp2, 1);
-	sram_read(adapter, addr, &tmp2, 1);
-
-	dprintk("%s: wrote 0xa5, read 0x%2x\n", __FUNCTION__, tmp2);
-
-	if (tmp2 != 0xa5)
-		return 0;
-
-	tmp2 = 0x5a;
-	tmp1 = 0xf4;
-
-	sram_write(adapter, addr, &tmp2, 1);
-	sram_write(adapter, addr + 4, &tmp1, 1);
-
-	tmp2 = 0;
-
-	mdelay(20);
-
-	sram_read(adapter, addr, &tmp2, 1);
-	sram_read(adapter, addr, &tmp2, 1);
-
-	dprintk("%s: wrote 0x5a, read 0x%2x\n", __FUNCTION__, tmp2);
-
-	if (tmp2 != 0x5a)
-		return 0;
-
-	return 1;
-}
-
-static u32 sram_length(struct adapter *adapter)
-{
-	if (adapter->dw_sram_type == 0x10000)
-		return 32768;	//  32K
-	if (adapter->dw_sram_type == 0x00000)
-		return 65536;	//  64K        
-	if (adapter->dw_sram_type == 0x20000)
-		return 131072;	// 128K
-
-	return 32768;		// 32K
-}
-
-/* FlexcopII can work with 32K, 64K or 128K of external SRAM memory.
-    - for 128K there are 4x32K chips at bank 0,1,2,3.
-    - for  64K there are 2x32K chips at bank 1,2.
-    - for  32K there is one 32K chip at bank 0.
-
-   FlexCop works only with one bank at a time. The bank is selected
-   by bits 28-29 of the 0x700 register.
-  
-   bank 0 covers addresses 0x00000-0x07fff
-   bank 1 covers addresses 0x08000-0x0ffff
-   bank 2 covers addresses 0x10000-0x17fff
-   bank 3 covers addresses 0x18000-0x1ffff
-*/
-static int sram_detect_for_flex2(struct adapter *adapter)
-{
-	u32 tmp, tmp2, tmp3;
-
-	dprintk("%s:\n", __FUNCTION__);
-
-	tmp = read_reg_dw(adapter, 0x208);
-	write_reg_dw(adapter, 0x208, 0);
-
-	tmp2 = read_reg_dw(adapter, 0x71c);
-
-	dprintk("%s: tmp2 = %x\n", __FUNCTION__, tmp2);
-
-	write_reg_dw(adapter, 0x71c, 1);
-
-	tmp3 = read_reg_dw(adapter, 0x71c);
-
-	dprintk("%s: tmp3 = %x\n", __FUNCTION__, tmp3);
-
-	write_reg_dw(adapter, 0x71c, tmp2);
-
-	// check for internal SRAM ???
-	tmp3--;
-	if (tmp3 != 0) {
-		sram_set_size(adapter, 0x10000);
-		sram_init(adapter);
-		write_reg_dw(adapter, 0x208, tmp);
-
-		dprintk("%s: sram size = 32K\n", __FUNCTION__);
-
-		return 32;
-	}
-
-	if (sram_test_location(adapter, 0x20000, 0x18000) != 0) {
-		sram_set_size(adapter, 0x20000);
-		sram_init(adapter);
-		write_reg_dw(adapter, 0x208, tmp);
-
-		dprintk("%s: sram size = 128K\n", __FUNCTION__);
-
-		return 128;
-	}
-
-	if (sram_test_location(adapter, 0x00000, 0x10000) != 0) {
-		sram_set_size(adapter, 0x00000);
-		sram_init(adapter);
-		write_reg_dw(adapter, 0x208, tmp);
-
-		dprintk("%s: sram size = 64K\n", __FUNCTION__);
-
-		return 64;
-	}
-
-	if (sram_test_location(adapter, 0x10000, 0x00000) != 0) {
-		sram_set_size(adapter, 0x10000);
-		sram_init(adapter);
-		write_reg_dw(adapter, 0x208, tmp);
-
-		dprintk("%s: sram size = 32K\n", __FUNCTION__);
-
-		return 32;
-	}
-
-	sram_set_size(adapter, 0x10000);
-	sram_init(adapter);
-	write_reg_dw(adapter, 0x208, tmp);
-
-	dprintk("%s: SRAM detection failed. Set to 32K \n", __FUNCTION__);
-
-	return 0;
-}
-
-static void sll_detect_sram_size(struct adapter *adapter)
-{
-	sram_detect_for_flex2(adapter);
-}
-
-/* EEPROM (Skystar2 has one "24LC08B" chip on board) */
-/*
-static int eeprom_write(struct adapter *adapter, u16 addr, u8 *buf, u16 len)
-{
-	return flex_i2c_write(adapter, 0x20000000, 0x50, addr, buf, len);
-}
-*/
-
-static int eeprom_read(struct adapter *adapter, u16 addr, u8 *buf, u16 len)
-{
-	return flex_i2c_read(adapter, 0x20000000, 0x50, addr, buf, len);
-}
-
-static u8 calc_lrc(u8 *buf, int len)
-{
-	int i;
-	u8 sum;
-
-	sum = 0;
-
-	for (i = 0; i < len; i++)
-		sum = sum ^ buf[i];
-
-	return sum;
-}
-
-static int eeprom_lrc_read(struct adapter *adapter, u32 addr, u32 len, u8 *buf, int retries)
-{
-	int i;
-
-	for (i = 0; i < retries; i++) {
-		if (eeprom_read(adapter, addr, buf, len) == len) {
-			if (calc_lrc(buf, len - 1) == buf[len - 1])
-				return 1;
-		}
-	}
-
-	return 0;
-}
-
-/*
-static int eeprom_lrc_write(struct adapter *adapter, u32 addr, u32 len, u8 *wbuf, u8 *rbuf, int retries)
-{
-	int i;
-
-	for (i = 0; i < retries; i++) {
-		if (eeprom_write(adapter, addr, wbuf, len) == len) {
-			if (eeprom_lrc_read(adapter, addr, len, rbuf, retries) == 1)
-				return 1;
-		}
-	}
-
-	return 0;
-}
-*/
-
-
-/* These functions could be used to unlock SkyStar2 cards. */
-
-/*
-static int eeprom_writeKey(struct adapter *adapter, u8 *key, u32 len)
-{
-	u8 rbuf[20];
-	u8 wbuf[20];
-
-	if (len != 16)
-		return 0;
-
-	memcpy(wbuf, key, len);
-
-	wbuf[16] = 0;
-	wbuf[17] = 0;
-	wbuf[18] = 0;
-	wbuf[19] = calc_lrc(wbuf, 19);
-
-	return eeprom_lrc_write(adapter, 0x3e4, 20, wbuf, rbuf, 4);
-}
-
-static int eeprom_readKey(struct adapter *adapter, u8 *key, u32 len)
-{
-	u8 buf[20];
-
-	if (len != 16)
-		return 0;
-
-	if (eeprom_lrc_read(adapter, 0x3e4, 20, buf, 4) == 0)
-		return 0;
-
-	memcpy(key, buf, len);
-
-	return 1;
-}
-*/
-
-static int eeprom_get_mac_addr(struct adapter *adapter, char type, u8 *mac)
-{
-	u8 tmp[8];
-
-	if (eeprom_lrc_read(adapter, 0x3f8, 8, tmp, 4) != 0) {
-		if (type != 0) {
-			mac[0] = tmp[0];
-			mac[1] = tmp[1];
-			mac[2] = tmp[2];
-			mac[3] = 0xfe;
-			mac[4] = 0xff;
-			mac[5] = tmp[3];
-			mac[6] = tmp[4];
-			mac[7] = tmp[5];
-
-		} else {
-
-			mac[0] = tmp[0];
-			mac[1] = tmp[1];
-			mac[2] = tmp[2];
-			mac[3] = tmp[3];
-			mac[4] = tmp[4];
-			mac[5] = tmp[5];
-		}
-
-		return 1;
-
-	} else {
-
-		if (type == 0) {
-			memset(mac, 0, 6);
-
-		} else {
-
-			memset(mac, 0, 8);
-		}
-
-		return 0;
-	}
-}
-
-/*
-static char eeprom_set_mac_addr(struct adapter *adapter, char type, u8 *mac)
-{
-	u8 tmp[8];
-
-	if (type != 0) {
-		tmp[0] = mac[0];
-		tmp[1] = mac[1];
-		tmp[2] = mac[2];
-		tmp[3] = mac[5];
-		tmp[4] = mac[6];
-		tmp[5] = mac[7];
-
-	} else {
-
-		tmp[0] = mac[0];
-		tmp[1] = mac[1];
-		tmp[2] = mac[2];
-		tmp[3] = mac[3];
-		tmp[4] = mac[4];
-		tmp[5] = mac[5];
-	}
-
-	tmp[6] = 0;
-	tmp[7] = calc_lrc(tmp, 7);
-
-	if (eeprom_write(adapter, 0x3f8, tmp, 8) == 8)
-		return 1;
-
-	return 0;
-}
-*/
-
-/* PID filter */
-
-/* every flexcop has 6 "lower" hw PID filters     */
-/* these are enabled by setting bits 0-5 of 0x208 */
-/* for the 32 additional filters we have to select one */
-/* of them through 0x310 and modify through 0x314 */
-/* op: 0=disable, 1=enable */
-static void filter_enable_hw_filter(struct adapter *adapter, int id, u8 op)
-{
-	dprintk("%s: id=%d op=%d\n", __FUNCTION__, id, op);
-	if (id <= 5) {
-		u32 mask = (0x00000001 << id);
-		write_reg_bitfield(adapter, 0x208, mask, op ? mask : 0);
-	} else {
-		/* select */
-		write_reg_bitfield(adapter, 0x310, 0x1f, (id - 6) & 0x1f);
-		/* modify */
-		write_reg_bitfield(adapter, 0x314, 0x00006000, op ? 0x00004000 : 0);
-	}
-}
-
-/* this sets the PID that should pass the specified filter */
-static void pid_set_hw_pid(struct adapter *adapter, int id, u16 pid)
-{
-	dprintk("%s: id=%d  pid=%d\n", __FUNCTION__, id, pid);
-	if (id <= 5) {
-		u32 adr = 0x300 + ((id & 6) << 1);
-		int shift = (id & 1) ? 16 : 0;
-		dprintk("%s: id=%d  addr=%x %c  pid=%d\n", __FUNCTION__, id, adr, (id & 1) ? 'h' : 'l', pid);
-		write_reg_bitfield(adapter, adr, (0x7fff) << shift, (pid & 0x1fff) << shift);
-	} else {
-		/* select */
-		write_reg_bitfield(adapter, 0x310, 0x1f, (id - 6) & 0x1f);
-		/* modify */
-		write_reg_bitfield(adapter, 0x314, 0x1fff, pid & 0x1fff);
-	}
-}
-
-
-/*
-static void filter_enable_null_filter(struct adapter *adapter, u32 op)
-{
-	dprintk("%s: op=%x\n", __FUNCTION__, op);
-
-	write_reg_bitfield(adapter, 0x208, 0x00000040, op?0x00000040:0);
-}
-*/
-
-static void filter_enable_mask_filter(struct adapter *adapter, u32 op)
-{
-	dprintk("%s: op=%x\n", __FUNCTION__, op);
-
-	write_reg_bitfield(adapter, 0x208, 0x00000080, op ? 0x00000080 : 0);
-}
-
-
-static void ctrl_enable_mac(struct adapter *adapter, u32 op)
-{
-	write_reg_bitfield(adapter, 0x208, 0x00004000, op ? 0x00004000 : 0);
-}
-
-static int ca_set_mac_dst_addr_filter(struct adapter *adapter, u8 *mac)
-{
-	u32 tmp1, tmp2;
-
-	tmp1 = (mac[3] << 0x18) | (mac[2] << 0x10) | (mac[1] << 0x08) | mac[0];
-	tmp2 = (mac[5] << 0x08) | mac[4];
-
-	write_reg_dw(adapter, 0x418, tmp1);
-	write_reg_dw(adapter, 0x41c, tmp2);
-
-	return 0;
-}
-
-/*
-static void set_ignore_mac_filter(struct adapter *adapter, u8 op)
-{
-	if (op != 0) {
-		write_reg_bitfield(adapter, 0x208, 0x00004000, 0);
-		adapter->mac_filter = 1;
-	} else {
-		if (adapter->mac_filter != 0) {
-			adapter->mac_filter = 0;
-			write_reg_bitfield(adapter, 0x208, 0x00004000, 0x00004000);
-		}
-	}
-}
-*/
-
-/*
-static void check_null_filter_enable(struct adapter *adapter)
-{
-	filter_enable_null_filter(adapter, 1);
-	filter_enable_mask_filter(adapter, 1);
-}
-*/
-
-static void pid_set_group_pid(struct adapter *adapter, u16 pid)
-{
-	u32 value;
-
-	dprintk("%s: pid=%x\n", __FUNCTION__, pid);
-	value = (pid & 0x3fff) | (read_reg_dw(adapter, 0x30c) & 0xffff0000);
-	write_reg_dw(adapter, 0x30c, value);
-}
-
-static void pid_set_group_mask(struct adapter *adapter, u16 pid)
-{
-	u32 value;
-
-	dprintk("%s: pid=%x\n", __FUNCTION__, pid);
-	value = ((pid & 0x3fff) << 0x10) | (read_reg_dw(adapter, 0x30c) & 0xffff);
-	write_reg_dw(adapter, 0x30c, value);
-}
-
-/*
-static int pid_get_group_pid(struct adapter *adapter)
-{
-	return read_reg_dw(adapter, 0x30c) & 0x00001fff;
-}
-
-static int pid_get_group_mask(struct adapter *adapter)
-{
-	return (read_reg_dw(adapter, 0x30c) >> 0x10)& 0x00001fff;
-}
-*/
-
-/*
-static void reset_hardware_pid_filter(struct adapter *adapter)
-{
-	pid_set_stream1_pid(adapter, 0x1fff);
-
-	pid_set_stream2_pid(adapter, 0x1fff);
-	filter_enable_stream2_filter(adapter, 0);
-
-	pid_set_pcr_pid(adapter, 0x1fff);
-	filter_enable_pcr_filter(adapter, 0);
-
-	pid_set_pmt_pid(adapter, 0x1fff);
-	filter_enable_pmt_filter(adapter, 0);
-
-	pid_set_ecm_pid(adapter, 0x1fff);
-	filter_enable_ecm_filter(adapter, 0);
-
-	pid_set_emm_pid(adapter, 0x1fff);
-	filter_enable_emm_filter(adapter, 0);
-}
-*/
-
-static void init_pids(struct adapter *adapter)
-{
-	int i;
-
-	adapter->pid_count = 0;
-	adapter->whole_bandwidth_count = 0;
-	for (i = 0; i < adapter->useable_hw_filters; i++) {
-		dprintk("%s: setting filter %d to 0x1fff\n", __FUNCTION__, i);
-		adapter->hw_pids[i] = 0x1fff;
-		pid_set_hw_pid(adapter, i, 0x1fff);
-}
-
-	pid_set_group_pid(adapter, 0);
-	pid_set_group_mask(adapter, 0x1fe0);
-}
-
-static void open_whole_bandwidth(struct adapter *adapter)
-{
-	dprintk("%s:\n", __FUNCTION__);
-	pid_set_group_pid(adapter, 0);
-	pid_set_group_mask(adapter, 0);
-/*
-	filter_enable_mask_filter(adapter, 1);
-*/
-}
-
-static void close_whole_bandwidth(struct adapter *adapter)
-{
-	dprintk("%s:\n", __FUNCTION__);
-	pid_set_group_pid(adapter, 0);
-	pid_set_group_mask(adapter, 0x1fe0);
-/*
-	filter_enable_mask_filter(adapter, 1);
-*/
-}
-
-static void whole_bandwidth_inc(struct adapter *adapter)
-{
-	if (adapter->whole_bandwidth_count++ == 0)
-		open_whole_bandwidth(adapter);
-}
-
-static void whole_bandwidth_dec(struct adapter *adapter)
-{
-	if (--adapter->whole_bandwidth_count <= 0)
-		close_whole_bandwidth(adapter);
-}
-
-/* The specified PID has to be let through the
-   hw filters.
-   We try to allocate an hardware filter and open whole
-   bandwidth when allocation is impossible.
-   All pids<=0x1f pass through the group filter.
-   Returns 1 on success, -1 on error */
-static int add_hw_pid(struct adapter *adapter, u16 pid)
-{
-	int i;
-
-	dprintk("%s: pid=%d\n", __FUNCTION__, pid);
-
-	if (pid <= 0x1f)
-		return 1;
-
-	/* we can't use a filter for 0x2000, so no search */
-	if (pid != 0x2000) {
-		/* find an unused hardware filter */
-		for (i = 0; i < adapter->useable_hw_filters; i++) {
-			dprintk("%s: pid=%d searching slot=%d\n", __FUNCTION__, pid, i);
-			if (adapter->hw_pids[i] == 0x1fff) {
-				dprintk("%s: pid=%d slot=%d\n", __FUNCTION__, pid, i);
-				adapter->hw_pids[i] = pid;
-				pid_set_hw_pid(adapter, i, pid);
-				filter_enable_hw_filter(adapter, i, 1);
-		return 1;
-	}
-	}
-	}
-	/* if we have not used a filter, this pid depends on whole bandwidth */
-	dprintk("%s: pid=%d whole_bandwidth\n", __FUNCTION__, pid);
-	whole_bandwidth_inc(adapter);
-		return 1;
-	}
-
-/* returns -1 if the pid was not present in the filters */
-static int remove_hw_pid(struct adapter *adapter, u16 pid)
-{
-	int i;
-
-	dprintk("%s: pid=%d\n", __FUNCTION__, pid);
-
-	if (pid <= 0x1f)
-		return 1;
-
-	/* we can't use a filter for 0x2000, so no search */
-	if (pid != 0x2000) {
-		for (i = 0; i < adapter->useable_hw_filters; i++) {
-			dprintk("%s: pid=%d searching slot=%d\n", __FUNCTION__, pid, i);
-			if (adapter->hw_pids[i] == pid) {	// find the pid slot
-				dprintk("%s: pid=%d slot=%d\n", __FUNCTION__, pid, i);
-				adapter->hw_pids[i] = 0x1fff;
-				pid_set_hw_pid(adapter, i, 0x1fff);
-				filter_enable_hw_filter(adapter, i, 0);
-		return 1;
-	}
-	}
-	}
-	/* if we have not used a filter, this pid depended on whole bandwith */
-	dprintk("%s: pid=%d whole_bandwidth\n", __FUNCTION__, pid);
-	whole_bandwidth_dec(adapter);
-		return 1;
-	}
-
-/* Adds a PID to the filters.
-   Adding a pid more than once is possible, we keep reference counts.
-   Whole stream available through pid==0x2000.
-   Returns 1 on success, -1 on error */
-static int add_pid(struct adapter *adapter, u16 pid)
-{
-	int i;
-
-	dprintk("%s: pid=%d\n", __FUNCTION__, pid);
-
-	if (pid > 0x1ffe && pid != 0x2000)
-		return -1;
-
-	// check if the pid is already present
-	for (i = 0; i < adapter->pid_count; i++)
-		if (adapter->pid_list[i] == pid) {
-			adapter->pid_rc[i]++;	// increment ref counter
-		return 1;
-		}
-
-	if (adapter->pid_count == N_PID_SLOTS)
-		return -1;	// no more pids can be added
-	adapter->pid_list[adapter->pid_count] = pid;	// register pid
-	adapter->pid_rc[adapter->pid_count] = 1;
-	adapter->pid_count++;
-	// hardware setting
-	add_hw_pid(adapter, pid);
-
-			return 1;
-		}
-
-/* Removes a PID from the filters. */
-static int remove_pid(struct adapter *adapter, u16 pid)
-{
-	int i;
-
-	dprintk("%s: pid=%d\n", __FUNCTION__, pid);
-
-	if (pid > 0x1ffe && pid != 0x2000)
-		return -1;
-
-	// check if the pid is present (it must be!)
-	for (i = 0; i < adapter->pid_count; i++) {
-		if (adapter->pid_list[i] == pid) {
-			adapter->pid_rc[i]--;
-			if (adapter->pid_rc[i] <= 0) {
-				// remove from the list
-				adapter->pid_count--;
-				adapter->pid_list[i]=adapter->pid_list[adapter->pid_count];
-				adapter->pid_rc[i] = adapter->pid_rc[adapter->pid_count];
-				// hardware setting
-				remove_hw_pid(adapter, pid);
-			}
-			return 1;
-		}
-	}
-
-	return -1;
-}
-
-
-/* dma & irq */
-static void ctrl_enable_smc(struct adapter *adapter, u32 op)
-{
-	write_reg_bitfield(adapter, 0x208, 0x00000800, op ? 0x00000800 : 0);
-}
-
-static void dma_enable_disable_irq(struct adapter *adapter, u32 flag1, u32 flag2, u32 flag3)
-{
-	adapter->dma_ctrl = adapter->dma_ctrl & 0x000f0000;
-
-	if (flag1 == 0) {
-		if (flag2 == 0)
-			adapter->dma_ctrl = adapter->dma_ctrl & ~0x00010000;
-		else
-			adapter->dma_ctrl = adapter->dma_ctrl | 0x00010000;
-
-		if (flag3 == 0)
-			adapter->dma_ctrl = adapter->dma_ctrl & ~0x00020000;
-		else
-			adapter->dma_ctrl = adapter->dma_ctrl | 0x00020000;
-
-	} else {
-
-		if (flag2 == 0)
-			adapter->dma_ctrl = adapter->dma_ctrl & ~0x00040000;
-		else
-			adapter->dma_ctrl = adapter->dma_ctrl | 0x00040000;
-
-		if (flag3 == 0)
-			adapter->dma_ctrl = adapter->dma_ctrl & ~0x00080000;
-		else
-			adapter->dma_ctrl = adapter->dma_ctrl | 0x00080000;
-	}
-}
-
-static void irq_dma_enable_disable_irq(struct adapter *adapter, u32 op)
-{
-	u32 value;
-
-	value = read_reg_dw(adapter, 0x208) & 0xfff0ffff;
-
-	if (op != 0)
-		value = value | (adapter->dma_ctrl & 0x000f0000);
-
-	write_reg_dw(adapter, 0x208, value);
-}
-
-/* FlexCopII has 2 dma channels. DMA1 is used to transfer TS data to
-   system memory.
-
-   The DMA1 buffer is divided in 2 subbuffers of equal size.
-   FlexCopII will transfer TS data to one subbuffer, signal an interrupt
-   when the subbuffer is full and continue fillig the second subbuffer.
-
-   For DMA1:
-       subbuffer size in 32-bit words is stored in the first 24 bits of
-       register 0x004. The last 8 bits of register 0x004 contain the number
-       of subbuffers.
-       
-       the first 30 bits of register 0x000 contain the address of the first
-       subbuffer. The last 2 bits contain 0, when dma1 is disabled and 1,
-       when dma1 is enabled.
-
-       the first 30 bits of register 0x00c contain the address of the second
-       subbuffer. the last 2 bits contain 1.
-
-       register 0x008 will contain the address of the subbuffer that was filled
-       with TS data, when FlexCopII will generate an interrupt.
-
-   For DMA2:
-       subbuffer size in 32-bit words is stored in the first 24 bits of
-       register 0x014. The last 8 bits of register 0x014 contain the number
-       of subbuffers.
-       
-       the first 30 bits of register 0x010 contain the address of the first
-       subbuffer.  The last 2 bits contain 0, when dma1 is disabled and 1,
-       when dma1 is enabled.
-
-       the first 30 bits of register 0x01c contain the address of the second
-       subbuffer. the last 2 bits contain 1.
-
-       register 0x018 contains the address of the subbuffer that was filled
-       with TS data, when FlexCopII generates an interrupt.
-*/
-static int dma_init_dma(struct adapter *adapter, u32 dma_channel)
-{
-	u32 subbuffers, subbufsize, subbuf0, subbuf1;
-
-	if (dma_channel == 0) {
-		dprintk("%s: Initializing DMA1 channel\n", __FUNCTION__);
-
-		subbuffers = 2;
-
-		subbufsize = (((adapter->dmaq1.buffer_size / 2) / 4) << 8) | subbuffers;
-
-		subbuf0 = adapter->dmaq1.bus_addr & 0xfffffffc;
-
-		subbuf1 = ((adapter->dmaq1.bus_addr + adapter->dmaq1.buffer_size / 2) & 0xfffffffc) | 1;
-
-		dprintk("%s: first subbuffer address = 0x%x\n", __FUNCTION__, subbuf0);
-		udelay(1000);
-		write_reg_dw(adapter, 0x000, subbuf0);
-
-		dprintk("%s: subbuffer size = 0x%x\n", __FUNCTION__, (subbufsize >> 8) * 4);
-		udelay(1000);
-		write_reg_dw(adapter, 0x004, subbufsize);
-
-		dprintk("%s: second subbuffer address = 0x%x\n", __FUNCTION__, subbuf1);
-		udelay(1000);
-		write_reg_dw(adapter, 0x00c, subbuf1);
-
-		dprintk("%s: counter = 0x%x\n", __FUNCTION__, adapter->dmaq1.bus_addr & 0xfffffffc);
-		write_reg_dw(adapter, 0x008, adapter->dmaq1.bus_addr & 0xfffffffc);
-		udelay(1000);
-
-		dma_enable_disable_irq(adapter, 0, 1, subbuffers ? 1 : 0);
-
-		irq_dma_enable_disable_irq(adapter, 1);
-
-		sram_set_media_dest(adapter, 1);
-		sram_set_net_dest(adapter, 1);
-		sram_set_cai_dest(adapter, 2);
-		sram_set_cao_dest(adapter, 2);
-	}
-
-	if (dma_channel == 1) {
-		dprintk("%s: Initializing DMA2 channel\n", __FUNCTION__);
-
-		subbuffers = 2;
-
-		subbufsize = (((adapter->dmaq2.buffer_size / 2) / 4) << 8) | subbuffers;
-
-		subbuf0 = adapter->dmaq2.bus_addr & 0xfffffffc;
-
-		subbuf1 = ((adapter->dmaq2.bus_addr + adapter->dmaq2.buffer_size / 2) & 0xfffffffc) | 1;
-
-		dprintk("%s: first subbuffer address = 0x%x\n", __FUNCTION__, subbuf0);
-		udelay(1000);
-		write_reg_dw(adapter, 0x010, subbuf0);
-
-		dprintk("%s: subbuffer size = 0x%x\n", __FUNCTION__, (subbufsize >> 8) * 4);
-		udelay(1000);
-		write_reg_dw(adapter, 0x014, subbufsize);
-
-		dprintk("%s: second buffer address = 0x%x\n", __FUNCTION__, subbuf1);
-		udelay(1000);
-		write_reg_dw(adapter, 0x01c, subbuf1);
-
-		sram_set_cai_dest(adapter, 2);
-	}
-
-	return 0;
-}
-
-static void ctrl_enable_receive_data(struct adapter *adapter, u32 op)
-{
-	if (op == 0) {
-		write_reg_bitfield(adapter, 0x208, 0x00008000, 0);
-		adapter->dma_status = adapter->dma_status & ~0x00000004;
-	} else {
-		write_reg_bitfield(adapter, 0x208, 0x00008000, 0x00008000);
-		adapter->dma_status = adapter->dma_status | 0x00000004;
-	}
-}
-
-/* bit 0 of dma_mask is set to 1 if dma1 channel has to be enabled/disabled
-   bit 1 of dma_mask is set to 1 if dma2 channel has to be enabled/disabled
-*/
-static void dma_start_stop(struct adapter *adapter, u32 dma_mask, int start_stop)
-{
-	u32 dma_enable, dma1_enable, dma2_enable;
-
-	dprintk("%s: dma_mask=%x\n", __FUNCTION__, dma_mask);
-
-	if (start_stop == 1) {
-		dprintk("%s: starting dma\n", __FUNCTION__);
-
-		dma1_enable = 0;
-		dma2_enable = 0;
-
-		if (((dma_mask & 1) != 0) && ((adapter->dma_status & 1) == 0) && (adapter->dmaq1.bus_addr != 0)) {
-			adapter->dma_status = adapter->dma_status | 1;
-			dma1_enable = 1;
-		}
-
-		if (((dma_mask & 2) != 0) && ((adapter->dma_status & 2) == 0) && (adapter->dmaq2.bus_addr != 0)) {
-			adapter->dma_status = adapter->dma_status | 2;
-			dma2_enable = 1;
-		}
-		// enable dma1 and dma2
-		if ((dma1_enable == 1) && (dma2_enable == 1)) {
-			write_reg_dw(adapter, 0x000, adapter->dmaq1.bus_addr | 1);
-			write_reg_dw(adapter, 0x00c, (adapter->dmaq1.bus_addr + adapter->dmaq1.buffer_size / 2) | 1);
-			write_reg_dw(adapter, 0x010, adapter->dmaq2.bus_addr | 1);
-
-			ctrl_enable_receive_data(adapter, 1);
-
-			return;
-		}
-		// enable dma1
-		if ((dma1_enable == 1) && (dma2_enable == 0)) {
-			write_reg_dw(adapter, 0x000, adapter->dmaq1.bus_addr | 1);
-			write_reg_dw(adapter, 0x00c, (adapter->dmaq1.bus_addr + adapter->dmaq1.buffer_size / 2) | 1);
-
-			ctrl_enable_receive_data(adapter, 1);
-
-			return;
-		}
-		// enable dma2
-		if ((dma1_enable == 0) && (dma2_enable == 1)) {
-			write_reg_dw(adapter, 0x010, adapter->dmaq2.bus_addr | 1);
-
-			ctrl_enable_receive_data(adapter, 1);
-
-			return;
-		}
-		// start dma
-		if ((dma1_enable == 0) && (dma2_enable == 0)) {
-			ctrl_enable_receive_data(adapter, 1);
-
-			return;
-		}
-
-	} else {
-
-		dprintk("%s: stopping dma\n", __FUNCTION__);
-
-		dma_enable = adapter->dma_status & 0x00000003;
-
-		if (((dma_mask & 1) != 0) && ((adapter->dma_status & 1) != 0)) {
-			dma_enable = dma_enable & 0xfffffffe;
-		}
-
-		if (((dma_mask & 2) != 0) && ((adapter->dma_status & 2) != 0)) {
-			dma_enable = dma_enable & 0xfffffffd;
-		}
-		//stop dma
-		if ((dma_enable == 0) && ((adapter->dma_status & 4) != 0)) {
-			ctrl_enable_receive_data(adapter, 0);
-
-			udelay(3000);
-		}
-		//disable dma1
-		if (((dma_mask & 1) != 0) && ((adapter->dma_status & 1) != 0) && (adapter->dmaq1.bus_addr != 0)) {
-			write_reg_dw(adapter, 0x000, adapter->dmaq1.bus_addr);
-			write_reg_dw(adapter, 0x00c, (adapter->dmaq1.bus_addr + adapter->dmaq1.buffer_size / 2) | 1);
-
-			adapter->dma_status = adapter->dma_status & ~0x00000001;
-		}
-		//disable dma2
-		if (((dma_mask & 2) != 0) && ((adapter->dma_status & 2) != 0) && (adapter->dmaq2.bus_addr != 0)) {
-			write_reg_dw(adapter, 0x010, adapter->dmaq2.bus_addr);
-
-			adapter->dma_status = adapter->dma_status & ~0x00000002;
-		}
-	}
-}
-
-static void open_stream(struct adapter *adapter, u16 pid)
-{
-	u32 dma_mask;
-
-	++adapter->capturing;
-
-	filter_enable_mask_filter(adapter, 1);
-
-	add_pid(adapter, pid);
-
-	dprintk("%s: adapter->dma_status=%x\n", __FUNCTION__, adapter->dma_status);
-
-	if ((adapter->dma_status & 7) != 7) {
-		dma_mask = 0;
-
-		if (((adapter->dma_status & 0x10000000) != 0) && ((adapter->dma_status & 1) == 0)) {
-			dma_mask = dma_mask | 1;
-
-			adapter->dmaq1.head = 0;
-			adapter->dmaq1.tail = 0;
-
-			memset(adapter->dmaq1.buffer, 0, adapter->dmaq1.buffer_size);
-		}
-
-		if (((adapter->dma_status & 0x20000000) != 0) && ((adapter->dma_status & 2) == 0)) {
-			dma_mask = dma_mask | 2;
-
-			adapter->dmaq2.head = 0;
-			adapter->dmaq2.tail = 0;
-		}
-
-		if (dma_mask != 0) {
-			irq_dma_enable_disable_irq(adapter, 1);
-
-			dma_start_stop(adapter, dma_mask, 1);
-		}
-	}
-}
-
-static void close_stream(struct adapter *adapter, u16 pid)
-{
-	if (adapter->capturing > 0)
-		--adapter->capturing;
-
-	dprintk("%s: dma_status=%x\n", __FUNCTION__, adapter->dma_status);
-
-	if (adapter->capturing == 0) {
-		u32 dma_mask = 0;
-
-	if ((adapter->dma_status & 1) != 0)
-		dma_mask = dma_mask | 0x00000001;
-	if ((adapter->dma_status & 2) != 0)
-		dma_mask = dma_mask | 0x00000002;
-
-	if (dma_mask != 0) {
-			dma_start_stop(adapter, dma_mask, 0);
-	}
-	}
-	remove_pid(adapter, pid);
-}
-
-static void interrupt_service_dma1(struct adapter *adapter)
-{
-	struct dvb_demux *dvbdmx = &adapter->demux;
-
-	int n_cur_dma_counter;
-	u32 n_num_bytes_parsed;
-	u32 n_num_new_bytes_transferred;
-	u32 dw_default_packet_size = 188;
-	u8 gb_tmp_buffer[188];
-	u8 *pb_dma_buf_cur_pos;
-
-	n_cur_dma_counter = readl(adapter->io_mem + 0x008) - adapter->dmaq1.bus_addr;
-	n_cur_dma_counter = (n_cur_dma_counter / dw_default_packet_size) * dw_default_packet_size;
-
-	if ((n_cur_dma_counter < 0) || (n_cur_dma_counter > adapter->dmaq1.buffer_size)) {
-		dprintk("%s: dma counter outside dma buffer\n", __FUNCTION__);
-		return;
-	}
-
-	adapter->dmaq1.head = n_cur_dma_counter;
-
-	if (adapter->dmaq1.tail <= n_cur_dma_counter) {
-		n_num_new_bytes_transferred = n_cur_dma_counter - adapter->dmaq1.tail;
-
-	} else {
-
-		n_num_new_bytes_transferred = (adapter->dmaq1.buffer_size - adapter->dmaq1.tail) + n_cur_dma_counter;
-	}
-
-	ddprintk("%s: n_cur_dma_counter = %d\n", __FUNCTION__, n_cur_dma_counter);
-	ddprintk("%s: dmaq1.tail        = %d\n", __FUNCTION__, adapter->dmaq1.tail);
-	ddprintk("%s: bytes_transferred = %d\n", __FUNCTION__, n_num_new_bytes_transferred);
-
-	if (n_num_new_bytes_transferred < dw_default_packet_size)
-		return;
-
-	n_num_bytes_parsed = 0;
-
-	while (n_num_bytes_parsed < n_num_new_bytes_transferred) {
-		pb_dma_buf_cur_pos = adapter->dmaq1.buffer + adapter->dmaq1.tail;
-
-		if (adapter->dmaq1.buffer + adapter->dmaq1.buffer_size < adapter->dmaq1.buffer + adapter->dmaq1.tail + 188) {
-			memcpy(gb_tmp_buffer, adapter->dmaq1.buffer + adapter->dmaq1.tail,
-			       adapter->dmaq1.buffer_size - adapter->dmaq1.tail);
-			memcpy(gb_tmp_buffer + (adapter->dmaq1.buffer_size - adapter->dmaq1.tail), adapter->dmaq1.buffer,
-			       (188 - (adapter->dmaq1.buffer_size - adapter->dmaq1.tail)));
-
-			pb_dma_buf_cur_pos = gb_tmp_buffer;
-		}
-
-		if (adapter->capturing != 0) {
-			dvb_dmx_swfilter_packets(dvbdmx, pb_dma_buf_cur_pos, dw_default_packet_size / 188);
-		}
-
-		n_num_bytes_parsed = n_num_bytes_parsed + dw_default_packet_size;
-
-		adapter->dmaq1.tail = adapter->dmaq1.tail + dw_default_packet_size;
-
-		if (adapter->dmaq1.tail >= adapter->dmaq1.buffer_size)
-			adapter->dmaq1.tail = adapter->dmaq1.tail - adapter->dmaq1.buffer_size;
-	};
-}
-
-static void interrupt_service_dma2(struct adapter *adapter)
-{
-	printk("%s:\n", __FUNCTION__);
-}
-
-static irqreturn_t isr(int irq, void *dev_id, struct pt_regs *regs)
-{
-	struct adapter *tmp = dev_id;
-
-	u32 value;
-
-	ddprintk("%s:\n", __FUNCTION__);
-
-	spin_lock_irq(&tmp->lock);
-
-	if (0 == ((value = read_reg_dw(tmp, 0x20c)) & 0x0f)) {
-		spin_unlock_irq(&tmp->lock);
-		return IRQ_NONE;
-	}
-	
-	while (value != 0) {
-		if ((value & 0x03) != 0)
-			interrupt_service_dma1(tmp);
-		if ((value & 0x0c) != 0)
-			interrupt_service_dma2(tmp);
-		value = read_reg_dw(tmp, 0x20c) & 0x0f;
-	}
-
-	spin_unlock_irq(&tmp->lock);
-	return IRQ_HANDLED;
-}
-
-static int init_dma_queue_one(struct adapter *adapter, struct dmaq *dmaq,
-			      int size, int dmaq_offset)
-{
-	struct pci_dev *pdev = adapter->pdev;
-	dma_addr_t dma_addr;
-
-	dmaq->head = 0;
-	dmaq->tail = 0;
-
-	dmaq->buffer = pci_alloc_consistent(pdev, size + 0x80, &dma_addr);
-	if (!dmaq->buffer)
-		return -ENOMEM;
-
-	dmaq->bus_addr = dma_addr;
-	dmaq->buffer_size = size;
-
-	dma_init_dma(adapter, dmaq_offset);
-
-	ddprintk("%s: allocated dma buffer at 0x%p, length=%d\n",
-		 __FUNCTION__, dmaq->buffer, size);
-
-	return 0;
-	}
-
-static int init_dma_queue(struct adapter *adapter)
-{
-	struct {
-		struct dmaq *dmaq;
-		u32 dma_status;
-		int size;
-	} dmaq_desc[] = {
-		{ &adapter->dmaq1, 0x10000000, SIZE_OF_BUF_DMA1 },
-		{ &adapter->dmaq2, 0x20000000, SIZE_OF_BUF_DMA2 }
-	}, *p = dmaq_desc;
-	int i;
-
-	for (i = 0; i < 2; i++, p++) {
-		if (init_dma_queue_one(adapter, p->dmaq, p->size, i) < 0)
-			adapter->dma_status &= ~p->dma_status;
-		else
-			adapter->dma_status |= p->dma_status;
-	}
-	return (adapter->dma_status & 0x30000000) ? 0 : -ENOMEM;
-}
-
-static void free_dma_queue_one(struct adapter *adapter, struct dmaq *dmaq)
-{
-	if (dmaq->buffer) {
-		pci_free_consistent(adapter->pdev, dmaq->buffer_size + 0x80,
-				    dmaq->buffer, dmaq->bus_addr);
-		memset(dmaq, 0, sizeof(*dmaq));
-	}
-}
-
-static void free_dma_queue(struct adapter *adapter)
-{
-	struct dmaq *dmaq[] = {
-		&adapter->dmaq1,
-		&adapter->dmaq2,
-		NULL
-	}, **p;
-
-	for (p = dmaq; *p; p++)
-		free_dma_queue_one(adapter, *p);
-	}
-
-static void release_adapter(struct adapter *adapter)
-{
-	struct pci_dev *pdev = adapter->pdev;
-
-	iounmap(adapter->io_mem);
-	pci_disable_device(pdev);
-	pci_release_region(pdev, 0);
-	pci_release_region(pdev, 1);
-}
-
-static void free_adapter_object(struct adapter *adapter)
-{
-	dprintk("%s:\n", __FUNCTION__);
-
-	close_stream(adapter, 0);
-		free_irq(adapter->irq, adapter);
-	free_dma_queue(adapter);
-	release_adapter(adapter);
-	kfree(adapter);
-}
-
-static struct pci_driver skystar2_pci_driver;
-
-static int claim_adapter(struct adapter *adapter)
-{
-	struct pci_dev *pdev = adapter->pdev;
-	u16 var;
-	int ret;
-
-	ret = pci_request_region(pdev, 1, skystar2_pci_driver.name);
-	if (ret < 0)
-		goto out;
-
-	ret = pci_request_region(pdev, 0, skystar2_pci_driver.name);
-	if (ret < 0)
-		goto err_pci_release_1;
-
-	pci_read_config_byte(pdev, PCI_CLASS_REVISION, &adapter->card_revision);
-
-	dprintk("%s: card revision %x \n", __FUNCTION__, adapter->card_revision);
-
-	ret = pci_enable_device(pdev);
-	if (ret < 0)
-		goto err_pci_release_0;
-
-	pci_read_config_word(pdev, 4, &var);
-
-	if ((var & 4) == 0)
-		pci_set_master(pdev);
-
-	adapter->io_port = pdev->resource[1].start;
-
-	adapter->io_mem = ioremap(pdev->resource[0].start, 0x800);
-
-	if (!adapter->io_mem) {
-		dprintk("%s: can not map io memory\n", __FUNCTION__);
-		ret = -EIO;
-		goto err_pci_disable;
-	}
-
-	dprintk("%s: io memory maped at %p\n", __FUNCTION__, adapter->io_mem);
-
-	ret = 1;
-out:
-	return ret;
-
-err_pci_disable:
-	pci_disable_device(pdev);
-err_pci_release_0:
-	pci_release_region(pdev, 0);
-err_pci_release_1:
-	pci_release_region(pdev, 1);
-	goto out;
-}
-
-/*
-static int sll_reset_flexcop(struct adapter *adapter)
-{
-	write_reg_dw(adapter, 0x208, 0);
-	write_reg_dw(adapter, 0x210, 0xb2ff);
-
-	return 0;
-}
-*/
-
-static void decide_how_many_hw_filters(struct adapter *adapter)
-{
-	int hw_filters;
-	int mod_option_hw_filters;
-
-	// FlexCop IIb & III have 6+32 hw filters    
-	// FlexCop II has 6 hw filters, every other should have at least 6
-	switch (adapter->b2c2_revision) {
-	case 0x82:		/* II */
-		hw_filters = 6;
-		break;
-	case 0xc3:		/* IIB */
-		hw_filters = 6 + 32;
-		break;
-	case 0xc0:		/* III */
-		hw_filters = 6 + 32;
-		break;
-	default:
-		hw_filters = 6;
-		break;
-	}
-	printk("%s: the chip has %i hardware filters", __FILE__, hw_filters);
-
-	mod_option_hw_filters = 0;
-	if (enable_hw_filters >= 1)
-		mod_option_hw_filters += 6;
-	if (enable_hw_filters >= 2)
-		mod_option_hw_filters += 32;
-
-	if (mod_option_hw_filters >= hw_filters) {
-		adapter->useable_hw_filters = hw_filters;
-	} else {
-		adapter->useable_hw_filters = mod_option_hw_filters;
-		printk(", but only %d will be used because of module option", mod_option_hw_filters);
-	}
-	printk("\n");
-	dprintk("%s: useable_hardware_filters set to %i\n", __FILE__, adapter->useable_hw_filters);
-}
-
-static int driver_initialize(struct pci_dev *pdev)
-{
-	struct adapter *adapter;
-	u32 tmp;
-	int ret = -ENOMEM;
-
-	adapter = kmalloc(sizeof(struct adapter), GFP_KERNEL);
-	if (!adapter) {
-		dprintk("%s: out of memory!\n", __FUNCTION__);
-		goto out;
-	}
-
-	memset(adapter, 0, sizeof(struct adapter));
-
-	pci_set_drvdata(pdev,adapter);
-
-	adapter->pdev = pdev;
-	adapter->irq = pdev->irq;
-
-	ret = claim_adapter(adapter);
-	if (ret < 0)
-		goto err_kfree;
-
-	irq_dma_enable_disable_irq(adapter, 0);
-
-	ret = request_irq(pdev->irq, isr, 0x4000000, "Skystar2", adapter);
-	if (ret < 0) {
-		dprintk("%s: unable to allocate irq=%d !\n", __FUNCTION__, pdev->irq);
-		goto err_release_adapter;
-	}
-
-	read_reg_dw(adapter, 0x208);
-	write_reg_dw(adapter, 0x208, 0);
-	write_reg_dw(adapter, 0x210, 0xb2ff);
-	write_reg_dw(adapter, 0x208, 0x40);
-
-	ret = init_dma_queue(adapter);
-	if (ret < 0)
-		goto err_free_irq;
-
-	adapter->b2c2_revision = (read_reg_dw(adapter, 0x204) >> 0x18);
-
-	switch (adapter->b2c2_revision) {
-	case 0x82:
-		printk("%s: FlexCopII(rev.130) chip found\n", __FILE__);
-		break;
-	case 0xc3:
-		printk("%s: FlexCopIIB(rev.195) chip found\n", __FILE__);
-		break;
-	case 0xc0:
-		printk("%s: FlexCopIII(rev.192) chip found\n", __FILE__);
-		break;
-	default:
-		printk("%s: The revision of the FlexCop chip on your card is %d\n", __FILE__, adapter->b2c2_revision);
-		printk("%s: This driver works only with FlexCopII(rev.130), FlexCopIIB(rev.195) and FlexCopIII(rev.192).\n", __FILE__);
-		ret = -ENODEV;
-		goto err_free_dma_queue;
-		}
-
-	decide_how_many_hw_filters(adapter);
-
-	init_pids(adapter);
-
-	tmp = read_reg_dw(adapter, 0x204);
-
-	write_reg_dw(adapter, 0x204, 0);
-	mdelay(20);
-
-	write_reg_dw(adapter, 0x204, tmp);
-	mdelay(10);
-
-	tmp = read_reg_dw(adapter, 0x308);
-	write_reg_dw(adapter, 0x308, 0x4000 | tmp);
-
-	adapter->dw_sram_type = 0x10000;
-
-	sll_detect_sram_size(adapter);
-
-	dprintk("%s sram length = %d, sram type= %x\n", __FUNCTION__, sram_length(adapter), adapter->dw_sram_type);
-
-	sram_set_media_dest(adapter, 1);
-	sram_set_net_dest(adapter, 1);
-
-	ctrl_enable_smc(adapter, 0);
-
-	sram_set_cai_dest(adapter, 2);
-	sram_set_cao_dest(adapter, 2);
-
-	dma_enable_disable_irq(adapter, 1, 0, 0);
-
-	if (eeprom_get_mac_addr(adapter, 0, adapter->mac_addr) != 0) {
-		printk("%s MAC address = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x \n", __FUNCTION__, adapter->mac_addr[0],
-		       adapter->mac_addr[1], adapter->mac_addr[2], adapter->mac_addr[3], adapter->mac_addr[4], adapter->mac_addr[5],
-		       adapter->mac_addr[6], adapter->mac_addr[7]
-		    );
-
-		ca_set_mac_dst_addr_filter(adapter, adapter->mac_addr);
-		ctrl_enable_mac(adapter, 1);
-	}
-
-	spin_lock_init(&adapter->lock);
-
-out:
-	return ret;
-
-err_free_dma_queue:
-	free_dma_queue(adapter);
-err_free_irq:
-	free_irq(pdev->irq, adapter);
-err_release_adapter:
-	release_adapter(adapter);
-err_kfree:
-	pci_set_drvdata(pdev, NULL);
-	kfree(adapter);
-	goto out;
-}
-
-static void driver_halt(struct pci_dev *pdev)
-{
-	struct adapter *adapter = pci_get_drvdata(pdev);
-
-	irq_dma_enable_disable_irq(adapter, 0);
-
-	ctrl_enable_receive_data(adapter, 0);
-
-	free_adapter_object(adapter);
-
-	pci_set_drvdata(pdev, NULL);
-}
-
-static int dvb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
-{
-	struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
-	struct adapter *adapter = (struct adapter *) dvbdmx->priv;
-
-	dprintk("%s: PID=%d, type=%d\n", __FUNCTION__, dvbdmxfeed->pid, dvbdmxfeed->type);
-
-	open_stream(adapter, dvbdmxfeed->pid);
-
-	return 0;
-}
-
-static int dvb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
-{
-	struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
-	struct adapter *adapter = (struct adapter *) dvbdmx->priv;
-
-	dprintk("%s: PID=%d, type=%d\n", __FUNCTION__, dvbdmxfeed->pid, dvbdmxfeed->type);
-
-	close_stream(adapter, dvbdmxfeed->pid);
-
-	return 0;
-}
-
-/* lnb control */
-static void set_tuner_tone(struct adapter *adapter, u8 tone)
-{
-	u16 wz_half_period_for_45_mhz[] = { 0x01ff, 0x0154, 0x00ff, 0x00cc };
-	u16 ax;
-
-	dprintk("%s: %u\n", __FUNCTION__, tone);
-
-	switch (tone) {
-	case 1:
-		ax = wz_half_period_for_45_mhz[0];
-		break;
-	case 2:
-		ax = wz_half_period_for_45_mhz[1];
-		break;
-	case 3:
-		ax = wz_half_period_for_45_mhz[2];
-		break;
-	case 4:
-		ax = wz_half_period_for_45_mhz[3];
-		break;
-
-	default:
-		ax = 0;
-	}
-
-	if (ax != 0) {
-		write_reg_dw(adapter, 0x200, ((ax << 0x0f) + (ax & 0x7fff)) | 0x40000000);
-
-	} else {
-
-		write_reg_dw(adapter, 0x200, 0x40ff8000);
-	}
-}
-
-static void set_tuner_polarity(struct adapter *adapter, u8 polarity)
-{
-	u32 var;
-
-	dprintk("%s : polarity = %u \n", __FUNCTION__, polarity);
-
-	var = read_reg_dw(adapter, 0x204);
-
-	if (polarity == 0) {
-		dprintk("%s: LNB power off\n", __FUNCTION__);
-		var = var | 1;
-	};
-
-	if (polarity == 1) {
-		var = var & ~1;
-		var = var & ~4;
-	};
-
-	if (polarity == 2) {
-		var = var & ~1;
-		var = var | 4;
-	}
-
-	write_reg_dw(adapter, 0x204, var);
-}
-
-static void diseqc_send_bit(struct adapter *adapter, int data)
-{
-	set_tuner_tone(adapter, 1);
-	udelay(data ? 500 : 1000);
-	set_tuner_tone(adapter, 0);
-	udelay(data ? 1000 : 500);
-}
-
-
-static void diseqc_send_byte(struct adapter *adapter, int data)
-		{
-	int i, par = 1, d;
-
-	for (i = 7; i >= 0; i--) {
-		d = (data >> i) & 1;
-		par ^= d;
-		diseqc_send_bit(adapter, d);
-	}
-
-	diseqc_send_bit(adapter, par);
-		}
-
-
-static int send_diseqc_msg(struct adapter *adapter, int len, u8 *msg, unsigned long burst)
-{
-	int i;
-
-	set_tuner_tone(adapter, 0);
-	mdelay(16);
-
-	for (i = 0; i < len; i++)
-		diseqc_send_byte(adapter, msg[i]);
-
-	mdelay(16);
-
-	if (burst != -1) {
-		if (burst)
-			diseqc_send_byte(adapter, 0xff);
-		else {
-			set_tuner_tone(adapter, 1);
-			udelay(12500);
-			set_tuner_tone(adapter, 0);
-		}
-		msleep(20);
-	}
-
-	return 0;
-}
-
-static int flexcop_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
-{
-	struct adapter* adapter = (struct adapter*) fe->dvb->priv;
-
-	switch(tone) {
-		case SEC_TONE_ON:
-			set_tuner_tone(adapter, 1);
-			break;
-		case SEC_TONE_OFF:
-			set_tuner_tone(adapter, 0);
-				break;
-			default:
-				return -EINVAL;
-			};
-
-	return 0;
-}
-
-static int flexcop_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd)
-		{
-	struct adapter* adapter = (struct adapter*) fe->dvb->priv;
-
-			send_diseqc_msg(adapter, cmd->msg_len, cmd->msg, 0);
-
-	return 0;
-		}
-
-static int flexcop_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd)
-{
-	struct adapter* adapter = (struct adapter*) fe->dvb->priv;
-
-	send_diseqc_msg(adapter, 0, NULL, minicmd);
-
-	return 0;
-}
-
-static int flexcop_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
-		{
-	struct adapter* adapter = (struct adapter*) fe->dvb->priv;
-
-	dprintk("%s: FE_SET_VOLTAGE\n", __FUNCTION__);
-
-	switch (voltage) {
-	case SEC_VOLTAGE_13:
-		dprintk("%s: SEC_VOLTAGE_13, %x\n", __FUNCTION__, SEC_VOLTAGE_13);
-		set_tuner_polarity(adapter, 1);
-		return 0;
-
-	case SEC_VOLTAGE_18:
-		dprintk("%s: SEC_VOLTAGE_18, %x\n", __FUNCTION__, SEC_VOLTAGE_18);
-		set_tuner_polarity(adapter, 2);
-			return 0;
-
-	default:
-		return -EINVAL;
-	}
-	}
-
-static int flexcop_sleep(struct dvb_frontend* fe)
-		{
-	struct adapter* adapter = (struct adapter*) fe->dvb->priv;
-
-	dprintk("%s: FE_SLEEP\n", __FUNCTION__);
-			set_tuner_polarity(adapter, 0);
-
-	if (adapter->fe_sleep) return adapter->fe_sleep(fe);
-	return 0;
-		}
-
-static u32 flexcop_i2c_func(struct i2c_adapter *adapter)
-		{
-	printk("flexcop_i2c_func\n");
-
-	return I2C_FUNC_I2C;
-}
-
-static struct i2c_algorithm    flexcop_algo = {
-	.name		= "flexcop i2c algorithm",
-	.id		= I2C_ALGO_BIT,
-	.master_xfer	= master_xfer,
-	.functionality	= flexcop_i2c_func,
-};
-
-
-
-
-static int samsung_tbmu24112_set_symbol_rate(struct dvb_frontend* fe, u32 srate, u32 ratio)
-{
-	u8 aclk = 0;
-	u8 bclk = 0;
-
-	if (srate < 1500000) { aclk = 0xb7; bclk = 0x47; }
-	else if (srate < 3000000) { aclk = 0xb7; bclk = 0x4b; }
-	else if (srate < 7000000) { aclk = 0xb7; bclk = 0x4f; }
-	else if (srate < 14000000) { aclk = 0xb7; bclk = 0x53; }
-	else if (srate < 30000000) { aclk = 0xb6; bclk = 0x53; }
-	else if (srate < 45000000) { aclk = 0xb4; bclk = 0x51; }
-
-	stv0299_writereg (fe, 0x13, aclk);
-	stv0299_writereg (fe, 0x14, bclk);
-	stv0299_writereg (fe, 0x1f, (ratio >> 16) & 0xff);
-	stv0299_writereg (fe, 0x20, (ratio >>  8) & 0xff);
-	stv0299_writereg (fe, 0x21, (ratio      ) & 0xf0);
-
-	return 0;
-}
-
-static int samsung_tbmu24112_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
-{
-	u8 buf[4];
-	u32 div;
-	struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
-	struct adapter* adapter = (struct adapter*) fe->dvb->priv;
-
-	div = params->frequency / 125;
-
-	buf[0] = (div >> 8) & 0x7f;
-	buf[1] = div & 0xff;
-	buf[2] = 0x84;  // 0xC4
-	buf[3] = 0x08;
-
-	if (params->frequency < 1500000) buf[3] |= 0x10;
-
-	if (i2c_transfer (&adapter->i2c_adap, &msg, 1) != 1) return -EIO;
-	return 0;
-}
-
-static u8 samsung_tbmu24112_inittab[] = {
-	     0x01, 0x15,
-	     0x02, 0x30,
-	     0x03, 0x00,
-	     0x04, 0x7D,
-	     0x05, 0x35,
-	     0x06, 0x02,
-	     0x07, 0x00,
-	     0x08, 0xC3,
-	     0x0C, 0x00,
-	     0x0D, 0x81,
-	     0x0E, 0x23,
-	     0x0F, 0x12,
-	     0x10, 0x7E,
-	     0x11, 0x84,
-	     0x12, 0xB9,
-	     0x13, 0x88,
-	     0x14, 0x89,
-	     0x15, 0xC9,
-	     0x16, 0x00,
-	     0x17, 0x5C,
-	     0x18, 0x00,
-	     0x19, 0x00,
-	     0x1A, 0x00,
-	     0x1C, 0x00,
-	     0x1D, 0x00,
-	     0x1E, 0x00,
-	     0x1F, 0x3A,
-	     0x20, 0x2E,
-	     0x21, 0x80,
-	     0x22, 0xFF,
-	     0x23, 0xC1,
-	     0x28, 0x00,
-	     0x29, 0x1E,
-	     0x2A, 0x14,
-	     0x2B, 0x0F,
-	     0x2C, 0x09,
-	     0x2D, 0x05,
-	     0x31, 0x1F,
-	     0x32, 0x19,
-	     0x33, 0xFE,
-	     0x34, 0x93,
-	     0xff, 0xff,
-			};
-
-static struct stv0299_config samsung_tbmu24112_config = {
-	.demod_address = 0x68,
-	.inittab = samsung_tbmu24112_inittab,
-	.mclk = 88000000UL,
-	.invert = 0,
-	.enhanced_tuning = 0,
-	.skip_reinit = 0,
-	.lock_output = STV0229_LOCKOUTPUT_LK,
-	.volt13_op0_op1 = STV0299_VOLT13_OP1,
-	.min_delay_ms = 100,
-	.set_symbol_rate = samsung_tbmu24112_set_symbol_rate,
-   	.pll_set = samsung_tbmu24112_pll_set,
-};
-
-
-
-static int nxt2002_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name)
-{
-	struct adapter* adapter = (struct adapter*) fe->dvb->priv;
-
-	return request_firmware(fw, name, &adapter->pdev->dev);
-}
-
-
-static struct nxt2002_config samsung_tbmv_config = {
-	.demod_address = 0x0A,
-	.request_firmware = nxt2002_request_firmware,
-};
-
-static int samsung_tdtc9251dh0_demod_init(struct dvb_frontend* fe)
-{
-	static u8 mt352_clock_config [] = { 0x89, 0x18, 0x2d };
-	static u8 mt352_reset [] = { 0x50, 0x80 };
-	static u8 mt352_adc_ctl_1_cfg [] = { 0x8E, 0x40 };
-	static u8 mt352_agc_cfg [] = { 0x67, 0x28, 0xa1 };
-	static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 };
-
-	mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config));
-	udelay(2000);
-	mt352_write(fe, mt352_reset, sizeof(mt352_reset));
-	mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg));
-
-	mt352_write(fe, mt352_agc_cfg, sizeof(mt352_agc_cfg));
-	mt352_write(fe, mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg));
-
-	return 0;
-}
-
-static int samsung_tdtc9251dh0_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u8* pllbuf)
-{
-	u32 div;
-	unsigned char bs = 0;
-
-	#define IF_FREQUENCYx6 217    /* 6 * 36.16666666667MHz */
-	div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6;
-
-	if (params->frequency >= 48000000 && params->frequency <= 154000000) bs = 0x09;
-	if (params->frequency >= 161000000 && params->frequency <= 439000000) bs = 0x0a;
-	if (params->frequency >= 447000000 && params->frequency <= 863000000) bs = 0x08;
-
-	pllbuf[0] = 0xc2; // Note: non-linux standard PLL i2c address
-	pllbuf[1] = div >> 8;
-   	pllbuf[2] = div & 0xff;
-   	pllbuf[3] = 0xcc;
-   	pllbuf[4] = bs;
-
-	return 0;
-}
-
-static struct mt352_config samsung_tdtc9251dh0_config = {
-
-	.demod_address = 0x0f,
-	.demod_init = samsung_tdtc9251dh0_demod_init,
-   	.pll_set = samsung_tdtc9251dh0_pll_set,
-};
-
-static int skystar23_samsung_tbdu18132_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
-{
-	u8 buf[4];
-	u32 div;
-	struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
-	struct adapter* adapter = (struct adapter*) fe->dvb->priv;
-
-	div = (params->frequency + (125/2)) / 125;
-
-	buf[0] = (div >> 8) & 0x7f;
-	buf[1] = (div >> 0) & 0xff;
-	buf[2] = 0x84 | ((div >> 10) & 0x60);
-	buf[3] = 0x80;
-
-	if (params->frequency < 1550000)
-		buf[3] |= 0x02;
-
-	if (i2c_transfer (&adapter->i2c_adap, &msg, 1) != 1) return -EIO;
-	return 0;
-}
-
-static struct mt312_config skystar23_samsung_tbdu18132_config = {
-
-	.demod_address = 0x0e,
-   	.pll_set = skystar23_samsung_tbdu18132_pll_set,
-};
-
-
-
-
-static void frontend_init(struct adapter *skystar2)
-{
-	switch(skystar2->pdev->device) {
-	case 0x2103: // Technisat Skystar2 OR Technisat Airstar2 (DVB-T or ATSC)
-
-		// Attempt to load the Nextwave nxt2002 for ATSC support 
-		skystar2->fe = nxt2002_attach(&samsung_tbmv_config, &skystar2->i2c_adap);
-		if (skystar2->fe != NULL) {
-			skystar2->fe_sleep = skystar2->fe->ops->sleep;
-			skystar2->fe->ops->sleep = flexcop_sleep;
-			break;
-		}
-
-		// try the skystar2 v2.6 first (stv0299/Samsung tbmu24112(sl1935))
-		skystar2->fe = stv0299_attach(&samsung_tbmu24112_config, &skystar2->i2c_adap);
-		if (skystar2->fe != NULL) {
-			skystar2->fe->ops->set_voltage = flexcop_set_voltage;
-			skystar2->fe_sleep = skystar2->fe->ops->sleep;
-			skystar2->fe->ops->sleep = flexcop_sleep;
-			break;
-}
-
-		// try the airstar2 (mt352/Samsung tdtc9251dh0(??))
-		skystar2->fe = mt352_attach(&samsung_tdtc9251dh0_config, &skystar2->i2c_adap);
-		if (skystar2->fe != NULL) {
-			skystar2->fe->ops->info.frequency_min = 474000000;
-			skystar2->fe->ops->info.frequency_max = 858000000;
-			break;
-		}
-
-		// try the skystar2 v2.3 (vp310/Samsung tbdu18132(tsa5059))
-		skystar2->fe = vp310_attach(&skystar23_samsung_tbdu18132_config, &skystar2->i2c_adap);
-		if (skystar2->fe != NULL) {
-			skystar2->fe->ops->diseqc_send_master_cmd = flexcop_diseqc_send_master_cmd;
-			skystar2->fe->ops->diseqc_send_burst = flexcop_diseqc_send_burst;
-			skystar2->fe->ops->set_tone = flexcop_set_tone;
-			skystar2->fe->ops->set_voltage = flexcop_set_voltage;
-			skystar2->fe_sleep = skystar2->fe->ops->sleep;
-			skystar2->fe->ops->sleep = flexcop_sleep;
-			break;
-		}
-		break;
-	}
-
-	if (skystar2->fe == NULL) {
-		printk("skystar2: A frontend driver was not found for device %04x/%04x subsystem %04x/%04x\n",
-		       skystar2->pdev->vendor,
-		       skystar2->pdev->device,
-		       skystar2->pdev->subsystem_vendor,
-		       skystar2->pdev->subsystem_device);
-	} else {
-		if (dvb_register_frontend(&skystar2->dvb_adapter, skystar2->fe)) {
-			printk("skystar2: Frontend registration failed!\n");
-			if (skystar2->fe->ops->release)
-				skystar2->fe->ops->release(skystar2->fe);
-			skystar2->fe = NULL;
-		}
-	}
-}
-
-
-static int skystar2_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
-{
-	struct adapter *adapter;
-	struct dvb_adapter *dvb_adapter;
-	struct dvb_demux *dvbdemux;
-	struct dmx_demux *dmx;
-	int ret = -ENODEV;
-
-	if (!pdev)
-		goto out;
-
-	ret = driver_initialize(pdev);
-	if (ret < 0)
-		goto out;
-
-	adapter = pci_get_drvdata(pdev);
-	dvb_adapter = &adapter->dvb_adapter;
-
-	ret = dvb_register_adapter(dvb_adapter, skystar2_pci_driver.name,
-				   THIS_MODULE);
-	if (ret < 0) {
-		printk("%s: Error registering DVB adapter\n", __FUNCTION__);
-		goto err_halt;
-	}
-
-	dvb_adapter->priv = adapter;
-
-
-	init_MUTEX(&adapter->i2c_sem);
-
-
-	memset(&adapter->i2c_adap, 0, sizeof(struct i2c_adapter));
-	strcpy(adapter->i2c_adap.name, "SkyStar2");
-
-	i2c_set_adapdata(&adapter->i2c_adap, adapter);
-
-#ifdef I2C_ADAP_CLASS_TV_DIGITAL
-	adapter->i2c_adap.class 	    = I2C_ADAP_CLASS_TV_DIGITAL;
-#else
-	adapter->i2c_adap.class 	    = I2C_CLASS_TV_DIGITAL;
-#endif
-	adapter->i2c_adap.algo              = &flexcop_algo;
-	adapter->i2c_adap.algo_data         = NULL;
-	adapter->i2c_adap.id                = I2C_ALGO_BIT;
-
-	ret = i2c_add_adapter(&adapter->i2c_adap);
-	if (ret < 0)
-		goto err_dvb_unregister;
-
-	dvbdemux = &adapter->demux;
-
-	dvbdemux->priv = adapter;
-	dvbdemux->filternum = N_PID_SLOTS;
-	dvbdemux->feednum = N_PID_SLOTS;
-	dvbdemux->start_feed = dvb_start_feed;
-	dvbdemux->stop_feed = dvb_stop_feed;
-	dvbdemux->write_to_decoder = NULL;
-	dvbdemux->dmx.capabilities = (DMX_TS_FILTERING | DMX_SECTION_FILTERING | DMX_MEMORY_BASED_FILTERING);
-
-	ret = dvb_dmx_init(&adapter->demux);
-	if (ret < 0)
-		goto err_i2c_del;
-
-	dmx = &dvbdemux->dmx;
-
-	adapter->hw_frontend.source = DMX_FRONTEND_0;
-	adapter->dmxdev.filternum = N_PID_SLOTS;
-	adapter->dmxdev.demux = dmx;
-	adapter->dmxdev.capabilities = 0;
-
-	ret = dvb_dmxdev_init(&adapter->dmxdev, &adapter->dvb_adapter);
-	if (ret < 0)
-		goto err_dmx_release;
-
-	ret = dmx->add_frontend(dmx, &adapter->hw_frontend);
-	if (ret < 0)
-		goto err_dmxdev_release;
-
-	adapter->mem_frontend.source = DMX_MEMORY_FE;
-
-	ret = dmx->add_frontend(dmx, &adapter->mem_frontend);
-	if (ret < 0)
-		goto err_remove_hw_frontend;
-
-	ret = dmx->connect_frontend(dmx, &adapter->hw_frontend);
-	if (ret < 0)
-		goto err_remove_mem_frontend;
-
-	dvb_net_init(&adapter->dvb_adapter, &adapter->dvbnet, &dvbdemux->dmx);
-
-	frontend_init(adapter);
-out:
-	return ret;
-
-err_remove_mem_frontend:
-	dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &adapter->mem_frontend);
-err_remove_hw_frontend:
-	dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &adapter->hw_frontend);
-err_dmxdev_release:
-	dvb_dmxdev_release(&adapter->dmxdev);
-err_dmx_release:
-	dvb_dmx_release(&adapter->demux);
-err_i2c_del:
-	i2c_del_adapter(&adapter->i2c_adap);
-err_dvb_unregister:
-	dvb_unregister_adapter(&adapter->dvb_adapter);
-err_halt:
-	driver_halt(pdev);
-	goto out;
-}
-
-static void skystar2_remove(struct pci_dev *pdev)
-{
-	struct adapter *adapter = pci_get_drvdata(pdev);
-	struct dvb_demux *dvbdemux;
-	struct dmx_demux *dmx;
-
-	if (!adapter)
-		return;
-
-		dvb_net_release(&adapter->dvbnet);
-		dvbdemux = &adapter->demux;
-	dmx = &dvbdemux->dmx;
-
-	dmx->close(dmx);
-	dmx->remove_frontend(dmx, &adapter->hw_frontend);
-	dmx->remove_frontend(dmx, &adapter->mem_frontend);
-
-		dvb_dmxdev_release(&adapter->dmxdev);
-	dvb_dmx_release(dvbdemux);
-
-	if (adapter->fe != NULL)
-		dvb_unregister_frontend(adapter->fe);
-
-	dvb_unregister_adapter(&adapter->dvb_adapter);
-
-			i2c_del_adapter(&adapter->i2c_adap);
-
-		driver_halt(pdev);
-	}
-
-static struct pci_device_id skystar2_pci_tbl[] = {
-	{0x000013d0, 0x00002103, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000},
-/*	{0x000013d0, 0x00002200, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000}, UNDEFINED HARDWARE - mail linuxtv.org list */	//FCIII
-	{0,},
-};
-
-MODULE_DEVICE_TABLE(pci, skystar2_pci_tbl);
-
-static struct pci_driver skystar2_pci_driver = {
-	.name = "SkyStar2",
-	.id_table = skystar2_pci_tbl,
-	.probe = skystar2_probe,
-	.remove = skystar2_remove,
-};
-
-static int skystar2_init(void)
-{
-	return pci_register_driver(&skystar2_pci_driver);
-}
-
-static void skystar2_cleanup(void)
-{
-	pci_unregister_driver(&skystar2_pci_driver);
-}
-
-module_init(skystar2_init);
-module_exit(skystar2_cleanup);
-
-MODULE_DESCRIPTION("Technisat SkyStar2 DVB PCI Driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/bt8xx/dst.c b/drivers/media/dvb/bt8xx/dst.c
--- a/drivers/media/dvb/bt8xx/dst.c
+++ b/drivers/media/dvb/bt8xx/dst.c
@@ -258,10 +258,10 @@ int write_dst(struct dst_state *state, u
 	if (debug && (verbose > 4)) {
 		u8 i;
 		if (verbose > 4) {
-			dprintk("%s writing", __FUNCTION__);
+			dprintk("%s writing [ ", __FUNCTION__);
 			for (i = 0; i < len; i++)
-				dprintk(" %02x", data[i]);
-			dprintk("\n");
+				dprintk("%02x ", data[i]);
+			dprintk("]\n");
 		}
 	}
 	for (cnt = 0; cnt < 2; cnt++) {
@@ -320,10 +320,29 @@ int read_dst(struct dst_state *state, u8
 }
 EXPORT_SYMBOL(read_dst);
 
-static int dst_set_freq(struct dst_state *state, u32 freq)
+static int dst_set_polarization(struct dst_state *state)
 {
-	u8 *val;
+	switch (state->voltage) {
+		case SEC_VOLTAGE_13:	// vertical
+			printk("%s: Polarization=[Vertical]\n", __FUNCTION__);
+			state->tx_tuna[8] &= ~0x40;  //1
+			break;
+
+		case SEC_VOLTAGE_18:	// horizontal
+			printk("%s: Polarization=[Horizontal]\n", __FUNCTION__);
+			state->tx_tuna[8] |= 0x40;  // 0
+			break;
 
+		case SEC_VOLTAGE_OFF:
+
+			break;
+	}
+
+	return 0;
+}
+
+static int dst_set_freq(struct dst_state *state, u32 freq)
+{
 	state->frequency = freq;
 	if (debug > 4)
 		dprintk("%s: set Frequency %u\n", __FUNCTION__, freq);
@@ -332,46 +351,30 @@ static int dst_set_freq(struct dst_state
 		freq = freq / 1000;
 		if (freq < 950 || freq > 2150)
 			return -EINVAL;
-		val = &state->tx_tuna[0];
-		val[2] = (freq >> 8) & 0x7f;
-		val[3] = (u8) freq;
-		val[4] = 1;
-		val[8] &= ~4;
-		if (freq < 1531)
-			val[8] |= 4;
+
+		state->tx_tuna[2] = (freq >> 8);
+		state->tx_tuna[3] = (u8) freq;
+		state->tx_tuna[4] = 0x01;
+		state->tx_tuna[8] &= ~0x04;
+		if (state->type_flags & DST_TYPE_HAS_OBS_REGS) {
+			if (freq < 1531)
+				state->tx_tuna[8] |= 0x04;
+		}
+
 	} else if (state->dst_type == DST_TYPE_IS_TERR) {
 		freq = freq / 1000;
 		if (freq < 137000 || freq > 858000)
 			return -EINVAL;
-		val = &state->tx_tuna[0];
-		val[2] = (freq >> 16) & 0xff;
-		val[3] = (freq >> 8) & 0xff;
-		val[4] = (u8) freq;
-		val[5] = 0;
-		switch (state->bandwidth) {
-		case BANDWIDTH_6_MHZ:
-			val[6] = 6;
-			break;
-
-		case BANDWIDTH_7_MHZ:
-		case BANDWIDTH_AUTO:
-			val[6] = 7;
-			break;
 
-		case BANDWIDTH_8_MHZ:
-			val[6] = 8;
-			break;
-		}
+		state->tx_tuna[2] = (freq >> 16) & 0xff;
+		state->tx_tuna[3] = (freq >> 8) & 0xff;
+		state->tx_tuna[4] = (u8) freq;
 
-		val[7] = 0;
-		val[8] = 0;
 	} else if (state->dst_type == DST_TYPE_IS_CABLE) {
-		/* guess till will get one */
-		freq = freq / 1000;
-		val = &state->tx_tuna[0];
-		val[2] = (freq >> 16) & 0xff;
-		val[3] = (freq >> 8) & 0xff;
-		val[4] = (u8) freq;
+		state->tx_tuna[2] = (freq >> 16) & 0xff;
+		state->tx_tuna[3] = (freq >> 8) & 0xff;
+		state->tx_tuna[4] = (u8) freq;
+
 	} else
 		return -EINVAL;
 	return 0;
@@ -379,51 +382,58 @@ static int dst_set_freq(struct dst_state
 
 static int dst_set_bandwidth(struct dst_state* state, fe_bandwidth_t bandwidth)
 {
-	u8 *val;
-
 	state->bandwidth = bandwidth;
 
 	if (state->dst_type != DST_TYPE_IS_TERR)
 		return 0;
 
-	val = &state->tx_tuna[0];
 	switch (bandwidth) {
-	case BANDWIDTH_6_MHZ:
-		val[6] = 6;
-		break;
+		case BANDWIDTH_6_MHZ:
+			if (state->dst_hw_cap & DST_TYPE_HAS_CA)
+				state->tx_tuna[7] = 0x06;
+			else {
+				state->tx_tuna[6] = 0x06;
+				state->tx_tuna[7] = 0x00;
+			}
+			break;
 
-	case BANDWIDTH_7_MHZ:
-		val[6] = 7;
-		break;
+		case BANDWIDTH_7_MHZ:
+			if (state->dst_hw_cap & DST_TYPE_HAS_CA)
+				state->tx_tuna[7] = 0x07;
+			else {
+				state->tx_tuna[6] = 0x07;
+				state->tx_tuna[7] = 0x00;
+			}
+			break;
 
-	case BANDWIDTH_8_MHZ:
-		val[6] = 8;
-		break;
+		case BANDWIDTH_8_MHZ:
+			if (state->dst_hw_cap & DST_TYPE_HAS_CA)
+				state->tx_tuna[7] = 0x08;
+			else {
+				state->tx_tuna[6] = 0x08;
+				state->tx_tuna[7] = 0x00;
+			}
+			break;
 
-	default:
-		return -EINVAL;
+		default:
+			return -EINVAL;
 	}
 	return 0;
 }
 
 static int dst_set_inversion(struct dst_state* state, fe_spectral_inversion_t inversion)
 {
-	u8 *val;
-
 	state->inversion = inversion;
-
-	val = &state->tx_tuna[0];
-
-	val[8] &= ~0x80;
-
 	switch (inversion) {
-	case INVERSION_OFF:
-		break;
-	case INVERSION_ON:
-		val[8] |= 0x80;
-		break;
-	default:
-		return -EINVAL;
+		case INVERSION_OFF:	// Inversion = Normal
+			state->tx_tuna[8] &= ~0x80;
+			break;
+
+		case INVERSION_ON:
+			state->tx_tuna[8] |= 0x80;
+			break;
+		default:
+			return -EINVAL;
 	}
 	return 0;
 }
@@ -478,6 +488,52 @@ static int dst_set_symbolrate(struct dst
 	return 0;
 }
 
+
+static int dst_set_modulation(struct dst_state *state, fe_modulation_t modulation)
+{
+	if (state->dst_type != DST_TYPE_IS_CABLE)
+		return 0;
+
+	state->modulation = modulation;
+	switch (modulation) {
+		case QAM_16:
+			state->tx_tuna[8] = 0x10;
+			break;
+
+		case QAM_32:
+			state->tx_tuna[8] = 0x20;
+			break;
+
+		case QAM_64:
+			state->tx_tuna[8] = 0x40;
+			break;
+
+		case QAM_128:
+			state->tx_tuna[8] = 0x80;
+			break;
+
+		case QAM_256:
+			state->tx_tuna[8] = 0x00;
+			break;
+
+		case QPSK:
+		case QAM_AUTO:
+		case VSB_8:
+		case VSB_16:
+		default:
+			return -EINVAL;
+
+	}
+
+	return 0;
+}
+
+static fe_modulation_t dst_get_modulation(struct dst_state *state)
+{
+	return state->modulation;
+}
+
+
 u8 dst_check_sum(u8 * buf, u32 len)
 {
 	u32 i;
@@ -577,7 +633,7 @@ struct dst_types dst_tlist[] = {
 		.device_id = "200103A",
 		.offset = 0,
 		.dst_type =  DST_TYPE_IS_SAT,
-		.type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1,
+		.type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1 | DST_TYPE_HAS_OBS_REGS,
 		.dst_feature = 0
 	},	/*	obsolete	*/
 
@@ -626,7 +682,7 @@ struct dst_types dst_tlist[] = {
 		.device_id = "DSTMCI",
 		.offset = 1,
 		.dst_type = DST_TYPE_IS_SAT,
-		.type_flags = DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_FW_BUILD,
+		.type_flags = DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_FW_BUILD | DST_TYPE_HAS_INC_COUNT,
 		.dst_feature = DST_TYPE_HAS_CA | DST_TYPE_HAS_DISEQC3 | DST_TYPE_HAS_DISEQC4
 							| DST_TYPE_HAS_MOTO | DST_TYPE_HAS_MAC
 	},
@@ -872,7 +928,7 @@ static int dst_get_signal(struct dst_sta
 {
 	int retval;
 	u8 get_signal[] = { 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb };
-
+	dprintk("%s: Getting Signal strength and other parameters\n", __FUNCTION__);
 	if ((state->diseq_flags & ATTEMPT_TUNE) == 0) {
 		state->decode_lock = state->decode_strength = state->decode_snr = 0;
 		return 0;
@@ -954,15 +1010,8 @@ static int dst_get_tuna(struct dst_state
 	state->decode_freq = ((state->rx_tuna[2] & 0x7f) << 8) + state->rx_tuna[3];
 
 	state->decode_lock = 1;
-	/*
-	   dst->decode_n1 = (dst->rx_tuna[4] << 8) +
-	   (dst->rx_tuna[5]);
-
-	   dst->decode_n2 = (dst->rx_tuna[8] << 8) +
-	   (dst->rx_tuna[7]);
-	 */
 	state->diseq_flags |= HAS_LOCK;
-	/* dst->cur_jiff = jiffies; */
+
 	return 1;
 }
 
@@ -1098,7 +1147,11 @@ static int dst_set_tone(struct dvb_front
 
 	switch (tone) {
 		case SEC_TONE_OFF:
-			state->tx_tuna[2] = 0xff;
+			if (state->type_flags & DST_TYPE_HAS_OBS_REGS)
+			    state->tx_tuna[2] = 0x00;
+			else
+			    state->tx_tuna[2] = 0xff;
+
 			break;
 
 		case SEC_TONE_ON:
@@ -1145,7 +1198,8 @@ static int dst_init(struct dvb_frontend*
 	static u8 ini_tvci_tuna[] = { 9, 0, 3, 0xb6, 1, 7, 0x0, 0x0, 0, 0 };
 	static u8 ini_cabfta_tuna[] = { 0, 0, 3, 0xb6, 1, 7, 0x0, 0x0, 0, 0 };
 	static u8 ini_cabci_tuna[] = { 9, 0, 3, 0xb6, 1, 7, 0x0, 0x0, 0, 0 };
-	state->inversion = INVERSION_ON;
+//	state->inversion = INVERSION_ON;
+	state->inversion = INVERSION_OFF;
 	state->voltage = SEC_VOLTAGE_13;
 	state->tone = SEC_TONE_OFF;
 	state->symbol_rate = 29473000;
@@ -1174,7 +1228,7 @@ static int dst_read_status(struct dvb_fr
 
 	*status = 0;
 	if (state->diseq_flags & HAS_LOCK) {
-		dst_get_signal(state);
+//		dst_get_signal(state);	// don't require(?) to ask MCU
 		if (state->decode_lock)
 			*status |= FE_HAS_LOCK | FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_SYNC | FE_HAS_VITERBI;
 	}
@@ -1208,20 +1262,25 @@ static int dst_set_frontend(struct dvb_f
 
 	dst_set_freq(state, p->frequency);
 	if (verbose > 4)
-		dprintk("Set Frequency = [%d]\n", p->frequency);
+		dprintk("Set Frequency=[%d]\n", p->frequency);
 
-	dst_set_inversion(state, p->inversion);
+//	dst_set_inversion(state, p->inversion);
 	if (state->dst_type == DST_TYPE_IS_SAT) {
+		if (state->type_flags & DST_TYPE_HAS_OBS_REGS)
+			dst_set_inversion(state, p->inversion);
+
 		dst_set_fec(state, p->u.qpsk.fec_inner);
 		dst_set_symbolrate(state, p->u.qpsk.symbol_rate);
+		dst_set_polarization(state);
 		if (verbose > 4)
-			dprintk("Set Symbolrate = [%d]\n", p->u.qpsk.symbol_rate);
+			dprintk("Set Symbolrate=[%d]\n", p->u.qpsk.symbol_rate);
 
 	} else if (state->dst_type == DST_TYPE_IS_TERR) {
 		dst_set_bandwidth(state, p->u.ofdm.bandwidth);
 	} else if (state->dst_type == DST_TYPE_IS_CABLE) {
 		dst_set_fec(state, p->u.qam.fec_inner);
 		dst_set_symbolrate(state, p->u.qam.symbol_rate);
+		dst_set_modulation(state, p->u.qam.modulation);
 	}
 	dst_write_tuna(fe);
 
@@ -1233,8 +1292,11 @@ static int dst_get_frontend(struct dvb_f
 	struct dst_state* state = fe->demodulator_priv;
 
 	p->frequency = state->decode_freq;
-	p->inversion = state->inversion;
+//	p->inversion = state->inversion;
 	if (state->dst_type == DST_TYPE_IS_SAT) {
+		if (state->type_flags & DST_TYPE_HAS_OBS_REGS)
+			p->inversion = state->inversion;
+
 		p->u.qpsk.symbol_rate = state->symbol_rate;
 		p->u.qpsk.fec_inner = dst_get_fec(state);
 	} else if (state->dst_type == DST_TYPE_IS_TERR) {
@@ -1242,7 +1304,8 @@ static int dst_get_frontend(struct dvb_f
 	} else if (state->dst_type == DST_TYPE_IS_CABLE) {
 		p->u.qam.symbol_rate = state->symbol_rate;
 		p->u.qam.fec_inner = dst_get_fec(state);
-		p->u.qam.modulation = QAM_AUTO;
+//		p->u.qam.modulation = QAM_AUTO;
+		p->u.qam.modulation = dst_get_modulation(state);
 	}
 
 	return 0;
diff --git a/drivers/media/dvb/bt8xx/dst_ca.c b/drivers/media/dvb/bt8xx/dst_ca.c
--- a/drivers/media/dvb/bt8xx/dst_ca.c
+++ b/drivers/media/dvb/bt8xx/dst_ca.c
@@ -32,7 +32,7 @@
 #include "dst_ca.h"
 #include "dst_common.h"
 
-static unsigned int verbose = 1;
+static unsigned int verbose = 5;
 module_param(verbose, int, 0644);
 MODULE_PARM_DESC(verbose, "verbose startup messages, default is 1 (yes)");
 
@@ -295,34 +295,28 @@ static int ca_get_message(struct dst_sta
 	return 0;
 }
 
-static int handle_en50221_tag(struct dst_state *state, struct ca_msg *p_ca_message, struct ca_msg *hw_buffer)
+static int handle_dst_tag(struct dst_state *state, struct ca_msg *p_ca_message, struct ca_msg *hw_buffer, u32 length)
 {
 	if (state->dst_hw_cap & DST_TYPE_HAS_SESSION) {
 		hw_buffer->msg[2] = p_ca_message->msg[1];		/*		MSB			*/
 		hw_buffer->msg[3] = p_ca_message->msg[2];		/*		LSB			*/
 	}
 	else {
+		hw_buffer->msg[0] = (length & 0xff) + 7;
+		hw_buffer->msg[1] = 0x40;
 		hw_buffer->msg[2] = 0x03;
 		hw_buffer->msg[3] = 0x00;
+		hw_buffer->msg[4] = 0x03;
+		hw_buffer->msg[5] = length & 0xff;
+		hw_buffer->msg[6] = 0x00;
 	}
 	return 0;
 }
 
-static int debug_8820_buffer(struct ca_msg *hw_buffer)
-{
-	unsigned int i;
-
-	dprintk("%s:Debug=[", __FUNCTION__);
-	for (i = 0; i < (hw_buffer->msg[0] + 1); i++)
-		dprintk(" %02x", hw_buffer->msg[i]);
-	dprintk("]\n");
 
-	return 0;
-}
-
-static int write_to_8820(struct dst_state *state, struct ca_msg *hw_buffer, u8 reply)
+static int write_to_8820(struct dst_state *state, struct ca_msg *hw_buffer, u8 length, u8 reply)
 {
-	if ((dst_put_ci(state, hw_buffer->msg, (hw_buffer->length + 1), hw_buffer->msg, reply)) < 0) {
+	if ((dst_put_ci(state, hw_buffer->msg, length, hw_buffer->msg, reply)) < 0) {
 		dprintk("%s: DST-CI Command failed.\n", __FUNCTION__);
 		dprintk("%s: Resetting DST.\n", __FUNCTION__);
 		rdc_reset_state(state);
@@ -334,234 +328,141 @@ static int write_to_8820(struct dst_stat
 	return 0;
 }
 
-
-static int ca_set_pmt(struct dst_state *state, struct ca_msg *p_ca_message, struct ca_msg *hw_buffer, u8 reply, u8 query)
+u32 asn_1_decode(u8 *asn_1_array)
 {
-	u32 hw_offset, buf_offset, i, k;
-	u32 program_info_length = 0, es_info_length = 0, length = 0, words = 0;
-	u8 found_prog_ca_desc = 0, found_stream_ca_desc = 0, error_condition = 0, hw_buffer_length = 0;
-
-	if (verbose > 3)
-		dprintk("%s, p_ca_message length %d (0x%x)\n", __FUNCTION__,p_ca_message->length,p_ca_message->length );
-
-	handle_en50221_tag(state, p_ca_message, hw_buffer);			/*	EN50221 tag		*/
+	u8 length_field = 0, word_count = 0, count = 0;
+	u32 length = 0;
 
-	/*	Handle the length field (variable)	*/
-	if (!(p_ca_message->msg[3] & 0x80)) {				/*	Length = 1		*/
-		length = p_ca_message->msg[3] & 0x7f;
-		words = 0;						/*	domi's suggestion	*/
-	}
-	else {								/*	Length = words		*/
-		words = p_ca_message->msg[3] & 0x7f;
-		for (i = 0; i < words; i++) {
-			length = length << 8;
-			length = length | p_ca_message->msg[4 + i];
+	length_field = asn_1_array[0];
+	dprintk("%s: Length field=[%02x]\n", __FUNCTION__, length_field);
+	if (length_field < 0x80) {
+		length = length_field & 0x7f;
+		dprintk("%s: Length=[%02x]\n", __FUNCTION__, length);
+	} else {
+		word_count = length_field & 0x7f;
+		for (count = 0; count < word_count; count++) {
+			length = (length | asn_1_array[count + 1]) << 8;
+			dprintk("%s: Length=[%04x]\n", __FUNCTION__, length);
 		}
 	}
-	if (verbose > 4) {
-		dprintk("%s:Length=[%d (0x%x)], Words=[%d]\n", __FUNCTION__, length,length, words);
+	return length;
+}
 
-		/*	Debug Input string		*/
-		for (i = 0; i < length; i++)
-			dprintk(" %02x", p_ca_message->msg[i]);
-		dprintk("]\n");
-	}
+static int init_buffer(u8 *buffer, u32 length)
+{
+	u32 i;
+	for (i = 0; i < length; i++)
+		buffer[i] = 0;
 
-	hw_offset = 7;
-	buf_offset = words + 4;
+	return 0;
+}
 
-	/*		Program Header			*/
-	if (verbose > 4)
-		dprintk("\n%s:Program Header=[", __FUNCTION__);
-	for (i = 0; i < 6; i++) {
-		hw_buffer->msg[hw_offset] = p_ca_message->msg[buf_offset];
-		if (verbose > 4)
-			dprintk(" %02x", p_ca_message->msg[buf_offset]);
-		hw_offset++, buf_offset++, hw_buffer_length++;
-	}
-	if (verbose > 4)
-		dprintk("]\n");
+static int debug_string(u8 *msg, u32 length, u32 offset)
+{
+	u32 i;
 
-	program_info_length = 0;
-	program_info_length = (((program_info_length | p_ca_message->msg[words + 8]) & 0x0f) << 8) | p_ca_message->msg[words + 9];
-	if (verbose > 4)
-		dprintk("%s:Program info Length=[%d][%02x], hw_offset=[%d], buf_offset=[%d] \n",
-			__FUNCTION__, program_info_length, program_info_length, hw_offset, buf_offset);
+	dprintk(" String=[ ");
+	for (i = offset; i < length; i++)
+		dprintk("%02x ", msg[i]);
+	dprintk("]\n");
 
-	if (program_info_length && (program_info_length < 256)) {	/*	If program_info_length		*/
-		hw_buffer->msg[11] = hw_buffer->msg[11] & 0x0f;		/*	req only 4 bits			*/
-		hw_buffer->msg[12] = hw_buffer->msg[12] + 1;		/*	increment! ASIC bug!		*/
-
-		if (p_ca_message->msg[buf_offset + 1] == 0x09) {	/*	Check CA descriptor		*/
-			found_prog_ca_desc = 1;
-			if (verbose > 4)
-				dprintk("%s: Found CA descriptor @ Program level\n", __FUNCTION__);
-		}
-
-		if (found_prog_ca_desc) {				/*	Command only if CA descriptor	*/
-			hw_buffer->msg[13] = p_ca_message->msg[buf_offset];	/*	CA PMT command ID	*/
-			hw_offset++, buf_offset++, hw_buffer_length++;
-		}
-
-		/*			Program descriptors				*/
-		if (verbose > 4) {
-			dprintk("%s:**********>buf_offset=[%d], hw_offset=[%d]\n", __FUNCTION__, buf_offset, hw_offset);
-			dprintk("%s:Program descriptors=[", __FUNCTION__);
-		}
-		while (program_info_length && !error_condition) {		/*	Copy prog descriptors	*/
-			if (program_info_length > p_ca_message->length) {	/*	Error situation		*/
-				dprintk ("%s:\"WARNING\" Length error, line=[%d], prog_info_length=[%d]\n",
-								__FUNCTION__, __LINE__, program_info_length);
-				dprintk("%s:\"WARNING\" Bailing out of possible loop\n", __FUNCTION__);
-				error_condition = 1;
-				break;
-			}
+	return 0;
+}
 
-			hw_buffer->msg[hw_offset] = p_ca_message->msg[buf_offset];
-			dprintk(" %02x", p_ca_message->msg[buf_offset]);
-			hw_offset++, buf_offset++, hw_buffer_length++, program_info_length--;
-		}
-		if (verbose > 4) {
-			dprintk("]\n");
-			dprintk("%s:**********>buf_offset=[%d], hw_offset=[%d]\n", __FUNCTION__, buf_offset, hw_offset);
-		}
-		if (found_prog_ca_desc) {
-			if (!reply) {
-				hw_buffer->msg[13] = 0x01;		/*	OK descrambling			*/
-				if (verbose > 1)
-					dprintk("CA PMT Command = OK Descrambling\n");
-			}
-			else {
-				hw_buffer->msg[13] = 0x02;		/*	Ok MMI				*/
-				if (verbose > 1)
-					dprintk("CA PMT Command = Ok MMI\n");
-			}
-			if (query) {
-				hw_buffer->msg[13] = 0x03;		/*	Query				*/
-				if (verbose > 1)
-					dprintk("CA PMT Command = CA PMT query\n");
-			}
-		}
-	}
-	else {
-		hw_buffer->msg[11] = hw_buffer->msg[11] & 0xf0;		/*	Don't write to ASIC		*/
-		hw_buffer->msg[12] = hw_buffer->msg[12] = 0x00;
+static int copy_string(u8 *destination, u8 *source, u32 dest_offset, u32 source_offset, u32 length)
+{
+	u32 i;
+	dprintk("%s: Copying [", __FUNCTION__);
+	for (i = 0; i < length; i++) {
+		destination[i + dest_offset] = source[i + source_offset];
+		dprintk(" %02x", source[i + source_offset]);
 	}
-	if (verbose > 4)
-		dprintk("%s:**********>p_ca_message->length=[%d], buf_offset=[%d], hw_offset=[%d]\n",
-					__FUNCTION__, p_ca_message->length, buf_offset, hw_offset);
-
-	while ((buf_offset  < p_ca_message->length)  && !error_condition) {
-		/*	Bail out in case of an indefinite loop		*/
-		if ((es_info_length > p_ca_message->length) || (buf_offset > p_ca_message->length)) {
-			dprintk("%s:\"WARNING\" Length error, line=[%d], prog_info_length=[%d], buf_offset=[%d]\n",
-							__FUNCTION__, __LINE__, program_info_length, buf_offset);
-
-			dprintk("%s:\"WARNING\" Bailing out of possible loop\n", __FUNCTION__);
-			error_condition = 1;
-			break;
-		}
-
-		/*		Stream Header				*/
-
-		for (k = 0; k < 5; k++) {
-			hw_buffer->msg[hw_offset + k] = p_ca_message->msg[buf_offset + k];
-		}
-
-		es_info_length = 0;
-		es_info_length = (es_info_length | (p_ca_message->msg[buf_offset + 3] & 0x0f)) << 8 | p_ca_message->msg[buf_offset + 4];
-
-		if (verbose > 4) {
-			dprintk("\n%s:----->Stream header=[%02x %02x %02x %02x %02x]\n", __FUNCTION__,
-				p_ca_message->msg[buf_offset + 0], p_ca_message->msg[buf_offset + 1],
-				p_ca_message->msg[buf_offset + 2], p_ca_message->msg[buf_offset + 3],
-				p_ca_message->msg[buf_offset + 4]);
-
-			dprintk("%s:----->Stream type=[%02x], es length=[%d (0x%x)], Chars=[%02x] [%02x], buf_offset=[%d]\n", __FUNCTION__,
-				p_ca_message->msg[buf_offset + 0], es_info_length, es_info_length,
-				p_ca_message->msg[buf_offset + 3], p_ca_message->msg[buf_offset + 4], buf_offset);
-		}
-
-		hw_buffer->msg[hw_offset + 3] &= 0x0f;			/*	req only 4 bits			*/
+	dprintk("]\n");
 
-		if (found_prog_ca_desc) {
-			hw_buffer->msg[hw_offset + 3] = 0x00;
-			hw_buffer->msg[hw_offset + 4] = 0x00;
-		}
+	return i;
+}
 
-		hw_offset += 5, buf_offset += 5, hw_buffer_length += 5;
+static int modify_4_bits(u8 *message, u32 pos)
+{
+	message[pos] &= 0x0f;
 
-		/*		Check for CA descriptor			*/
-		if (p_ca_message->msg[buf_offset + 1] == 0x09) {
-			if (verbose > 4)
-				dprintk("%s:Found CA descriptor @ Stream level\n", __FUNCTION__);
-			found_stream_ca_desc = 1;
-		}
+	return 0;
+}
 
-		/*		ES descriptors				*/
 
-		if (es_info_length && !error_condition && !found_prog_ca_desc && found_stream_ca_desc) {
-//			if (!ca_pmt_done) {
-				hw_buffer->msg[hw_offset] = p_ca_message->msg[buf_offset];	/*	CA PMT cmd(es)	*/
-				if (verbose > 4)
-					printk("%s:----->CA PMT Command ID=[%02x]\n", __FUNCTION__, p_ca_message->msg[buf_offset]);
-//				hw_offset++, buf_offset++, hw_buffer_length++, es_info_length--, ca_pmt_done = 1;
-				hw_offset++, buf_offset++, hw_buffer_length++, es_info_length--;
-//			}
-			if (verbose > 4)
-				dprintk("%s:----->ES descriptors=[", __FUNCTION__);
 
-			while (es_info_length && !error_condition) {	/*	ES descriptors			*/
-				if ((es_info_length > p_ca_message->length) || (buf_offset > p_ca_message->length)) {
-					if (verbose > 4) {
-						dprintk("%s:\"WARNING\" ES Length error, line=[%d], es_info_length=[%d], buf_offset=[%d]\n",
-										__FUNCTION__, __LINE__, es_info_length, buf_offset);
+static int ca_set_pmt(struct dst_state *state, struct ca_msg *p_ca_message, struct ca_msg *hw_buffer, u8 reply, u8 query)
+{
+	u32 length = 0, count = 0;
+	u8 asn_1_words, program_header_length;
+	u16 program_info_length = 0, es_info_length = 0;
+	u32 hw_offset = 0, buf_offset = 0, i;
+	u8 dst_tag_length;
+
+	length = asn_1_decode(&p_ca_message->msg[3]);
+	dprintk("%s: CA Message length=[%d]\n", __FUNCTION__, length);
+	dprintk("%s: ASN.1 ", __FUNCTION__);
+	debug_string(&p_ca_message->msg[4], length, 0); // length does not include tag and length
 
-						dprintk("%s:\"WARNING\" Bailing out of possible loop\n", __FUNCTION__);
-					}
-					error_condition = 1;
-					break;
-				}
+	init_buffer(hw_buffer->msg, length);
+	handle_dst_tag(state, p_ca_message, hw_buffer, length);
 
-				hw_buffer->msg[hw_offset] = p_ca_message->msg[buf_offset];
-				if (verbose > 3)
-					dprintk("%02x ", hw_buffer->msg[hw_offset]);
-				hw_offset++, buf_offset++, hw_buffer_length++, es_info_length--;
-			}
-			found_stream_ca_desc = 0;			/*	unset for new streams		*/
-			dprintk("]\n");
+	hw_offset = 7;
+	asn_1_words = 1; // just a hack to test, should compute this one
+	buf_offset = 3;
+	program_header_length = 6;
+	dst_tag_length = 7;
+
+//	debug_twinhan_ca_params(state, p_ca_message, hw_buffer, reply, query, length, hw_offset, buf_offset);
+//	dprintk("%s: Program Header(BUF)", __FUNCTION__);
+//	debug_string(&p_ca_message->msg[4], program_header_length, 0);
+//	dprintk("%s: Copying Program header\n", __FUNCTION__);
+	copy_string(hw_buffer->msg, p_ca_message->msg, hw_offset, (buf_offset + asn_1_words), program_header_length);
+	buf_offset += program_header_length, hw_offset += program_header_length;
+	modify_4_bits(hw_buffer->msg, (hw_offset - 2));
+	if (state->type_flags & DST_TYPE_HAS_INC_COUNT) {	// workaround
+		dprintk("%s: Probably an ASIC bug !!!\n", __FUNCTION__);
+		debug_string(hw_buffer->msg, (hw_offset + program_header_length), 0);
+		hw_buffer->msg[hw_offset - 1] += 1;
+	}
+
+//	dprintk("%s: Program Header(HW), Count=[%d]", __FUNCTION__, count);
+//	debug_string(hw_buffer->msg, hw_offset, 0);
+
+	program_info_length =  ((program_info_length | (p_ca_message->msg[buf_offset - 1] & 0x0f)) << 8) | p_ca_message->msg[buf_offset];
+	dprintk("%s: Program info length=[%02x]\n", __FUNCTION__, program_info_length);
+	if (program_info_length) {
+		count = copy_string(hw_buffer->msg, p_ca_message->msg, hw_offset, (buf_offset + 1), (program_info_length + 1) ); // copy next elem, not current
+		buf_offset += count, hw_offset += count;
+//		dprintk("%s: Program level ", __FUNCTION__);
+//		debug_string(hw_buffer->msg, hw_offset, 0);
+	}
+
+	buf_offset += 1;// hw_offset += 1;
+	for (i = buf_offset; i < length; i++) {
+//		dprintk("%s: Stream Header ", __FUNCTION__);
+		count = copy_string(hw_buffer->msg, p_ca_message->msg, hw_offset, buf_offset, 5);
+		modify_4_bits(hw_buffer->msg, (hw_offset + 3));
+
+		hw_offset += 5, buf_offset += 5, i += 4;
+//		debug_string(hw_buffer->msg, hw_offset, (hw_offset - 5));
+		es_info_length = ((es_info_length | (p_ca_message->msg[buf_offset - 1] & 0x0f)) << 8) | p_ca_message->msg[buf_offset];
+		dprintk("%s: ES info length=[%02x]\n", __FUNCTION__, es_info_length);
+		if (es_info_length) {
+			// copy descriptors @ STREAM level
+			dprintk("%s: Descriptors @ STREAM level...!!! \n", __FUNCTION__);
 		}
-	}
-
-	/*		MCU Magic words					*/
-
-	hw_buffer_length += 7;
-	hw_buffer->msg[0] = hw_buffer_length;
-	hw_buffer->msg[1] = 64;
-	hw_buffer->msg[4] = 3;
-	hw_buffer->msg[5] = hw_buffer->msg[0] - 7;
-	hw_buffer->msg[6] = 0;
-
 
-	/*      Fix length      */
-	hw_buffer->length = hw_buffer->msg[0];
-
-	put_checksum(&hw_buffer->msg[0], hw_buffer->msg[0]);
-	/*      Do the actual write     */
-	if (verbose > 4) {
-		dprintk("%s:======================DEBUGGING================================\n", __FUNCTION__);
-		dprintk("%s: Actual Length=[%d]\n", __FUNCTION__, hw_buffer_length);
 	}
-	/*      Only for debugging!     */
-	if (verbose > 2)
-		debug_8820_buffer(hw_buffer);
-	if (verbose > 3)
-		dprintk("%s: Reply = [%d]\n", __FUNCTION__, reply);
-	write_to_8820(state, hw_buffer, reply);
+	hw_buffer->msg[length + dst_tag_length] = dst_check_sum(hw_buffer->msg, (length + dst_tag_length));
+//	dprintk("%s: Total length=[%d], Checksum=[%02x]\n", __FUNCTION__, (length + dst_tag_length), hw_buffer->msg[length + dst_tag_length]);
+	debug_string(hw_buffer->msg, (length + dst_tag_length + 1), 0);	// dst tags also
+	write_to_8820(state, hw_buffer, (length + dst_tag_length + 1), reply);	// checksum
 
 	return 0;
 }
 
+
 /*	Board supports CA PMT reply ?		*/
 static int dst_check_ca_pmt(struct dst_state *state, struct ca_msg *p_ca_message, struct ca_msg *hw_buffer)
 {
@@ -605,7 +506,7 @@ static int ca_send_message(struct dst_st
 	struct ca_msg *hw_buffer;
 
 	if ((hw_buffer = (struct ca_msg *) kmalloc(sizeof (struct ca_msg), GFP_KERNEL)) == NULL) {
-		printk("%s: Memory allocation failure\n", __FUNCTION__);
+		dprintk("%s: Memory allocation failure\n", __FUNCTION__);
 		return -ENOMEM;
 	}
 	if (verbose > 3)
@@ -630,8 +531,10 @@ static int ca_send_message(struct dst_st
 		switch (command) {
 			case CA_PMT:
 				if (verbose > 3)
+//					dprintk("Command = SEND_CA_PMT\n");
 					dprintk("Command = SEND_CA_PMT\n");
-				if ((ca_set_pmt(state, p_ca_message, hw_buffer, 0, 0)) < 0) {
+//				if ((ca_set_pmt(state, p_ca_message, hw_buffer, 0, 0)) < 0) {
+				if ((ca_set_pmt(state, p_ca_message, hw_buffer, 0, 0)) < 0) {	// code simplification started
 					dprintk("%s: -->CA_PMT Failed !\n", __FUNCTION__);
 					return -1;
 				}
@@ -664,7 +567,7 @@ static int ca_send_message(struct dst_st
 					return -1;
 				}
 				if (verbose > 3)
-					printk("%s: -->CA_APP_INFO_ENQUIRY Success !\n", __FUNCTION__);
+					dprintk("%s: -->CA_APP_INFO_ENQUIRY Success !\n", __FUNCTION__);
 
 				break;
 		}
@@ -681,17 +584,17 @@ static int dst_ca_ioctl(struct inode *in
 	struct ca_msg *p_ca_message;
 
 	if ((p_ca_message = (struct ca_msg *) kmalloc(sizeof (struct ca_msg), GFP_KERNEL)) == NULL) {
-		printk("%s: Memory allocation failure\n", __FUNCTION__);
+		dprintk("%s: Memory allocation failure\n", __FUNCTION__);
 		return -ENOMEM;
 	}
 
 	if ((p_ca_slot_info = (struct ca_slot_info *) kmalloc(sizeof (struct ca_slot_info), GFP_KERNEL)) == NULL) {
-		printk("%s: Memory allocation failure\n", __FUNCTION__);
+		dprintk("%s: Memory allocation failure\n", __FUNCTION__);
 		return -ENOMEM;
 	}
 
 	if ((p_ca_caps = (struct ca_caps *) kmalloc(sizeof (struct ca_caps), GFP_KERNEL)) == NULL) {
-		printk("%s: Memory allocation failure\n", __FUNCTION__);
+		dprintk("%s: Memory allocation failure\n", __FUNCTION__);
 		return -ENOMEM;
 	}
 
diff --git a/drivers/media/dvb/bt8xx/dst_common.h b/drivers/media/dvb/bt8xx/dst_common.h
--- a/drivers/media/dvb/bt8xx/dst_common.h
+++ b/drivers/media/dvb/bt8xx/dst_common.h
@@ -47,6 +47,8 @@
 #define DST_TYPE_HAS_FW_2	16
 #define DST_TYPE_HAS_FW_3	32
 #define DST_TYPE_HAS_FW_BUILD	64
+#define DST_TYPE_HAS_OBS_REGS	128
+#define DST_TYPE_HAS_INC_COUNT	256
 
 /*	Card capability list	*/
 
@@ -110,6 +112,7 @@ struct dst_state {
 	u32 dst_hw_cap;
 	u8 dst_fw_version;
 	fe_sec_mini_cmd_t minicmd;
+	fe_modulation_t modulation;
 	u8 messages[256];
 };
 
diff --git a/drivers/media/dvb/cinergyT2/cinergyT2.c b/drivers/media/dvb/cinergyT2/cinergyT2.c
--- a/drivers/media/dvb/cinergyT2/cinergyT2.c
+++ b/drivers/media/dvb/cinergyT2/cinergyT2.c
@@ -699,6 +699,8 @@ static void cinergyt2_query_rc (void *da
 	for (n=0; len>0 && n<(len/sizeof(rc_events[0])); n++) {
 		int i;
 
+/*		dprintk(1,"rc_events[%d].value = %x, type=%x\n",n,le32_to_cpu(rc_events[n].value),rc_events[n].type);*/
+
 		if (rc_events[n].type == CINERGYT2_RC_EVENT_TYPE_NEC &&
 		    rc_events[n].value == ~0)
 		{
@@ -714,7 +716,7 @@ static void cinergyt2_query_rc (void *da
 			cinergyt2->rc_input_event = KEY_MAX;
 			for (i=0; i<sizeof(rc_keys)/sizeof(rc_keys[0]); i+=3) {
 				if (rc_keys[i+0] == rc_events[n].type &&
-				    rc_keys[i+1] == rc_events[n].value)
+				    rc_keys[i+1] == le32_to_cpu(rc_events[n].value))
 				{
 					cinergyt2->rc_input_event = rc_keys[i+2];
 					break;
diff --git a/drivers/media/dvb/dibusb/Kconfig b/drivers/media/dvb/dibusb/Kconfig
deleted file mode 100644
--- a/drivers/media/dvb/dibusb/Kconfig
+++ /dev/null
@@ -1,62 +0,0 @@
-config DVB_DIBUSB
-	tristate "DiBcom USB DVB-T devices (see help for a complete device list)"
-	depends on DVB_CORE && USB
-	select FW_LOADER
-	select DVB_DIB3000MB
-	select DVB_DIB3000MC
-	select DVB_MT352
-	help
-	  Support for USB 1.1 and 2.0 DVB-T devices based on reference designs made by
-	  DiBcom (http://www.dibcom.fr) and C&E.
-
-	  Devices supported by this driver:
-
-	    TwinhanDTV USB-Ter (VP7041)
-		TwinhanDTV Magic Box (VP7041e)
-	    KWorld/JetWay/ADSTech V-Stream XPERT DTV - DVB-T USB1.1 and USB2.0
-	    Hama DVB-T USB-Box
-	    DiBcom reference devices (non-public)
-	    Ultima Electronic/Artec T1 USB TVBOX
-	    Compro Videomate DVB-U2000 - DVB-T USB
-	    Grandtec DVB-T USB
-	    Avermedia AverTV DVBT USB
-	    Artec T1 USB1.1 and USB2.0 boxes
-	    Yakumo/Typhoon DVB-T USB2.0
-	    Hanftek UMT-010 USB2.0
-	    Hauppauge WinTV NOVA-T USB2
-
-	  The VP7041 seems to be identical to "CTS Portable" (Chinese
-	  Television System).
-
-	  These devices can be understood as budget ones, they "only" deliver
-	  (a part of) the MPEG2 transport stream.
-
-	  A firmware is needed to get the device working. See Documentation/dvb/README.dibusb
-	  details.
-
-	  Say Y if you own such a device and want to use it. You should build it as
-	  a module.
-
-config DVB_DIBUSB_MISDESIGNED_DEVICES
-	bool "Enable support for some misdesigned (see help) devices, which identify with wrong IDs"
-	depends on DVB_DIBUSB
-	help
-	  Somehow Artec/Ultima Electronic forgot to program the eeprom of some of their
-	  USB1.1/USB2.0 devices.
-	  So comes that they identify with the default Vendor and Product ID of the Cypress
-	  CY7C64613 (AN2235) or Cypress FX2.
-
-	  Affected device IDs:
-	    0x0574:0x2235 (Artec T1 USB1.1, cold)
-	    0x04b4:0x8613 (Artec T1 USB2.0, cold)
-	    0x0574:0x1002 (Artec T1 USB2.0, warm)
-	    0x0574:0x2131 (aged DiBcom USB1.1 test device)
-
-	  Say Y if your device has one of the mentioned IDs.
-
-config DVB_DIBCOM_DEBUG
-	bool "Enable extended debug support for DiBcom USB device"
-	depends on DVB_DIBUSB
-	help
-	  Say Y if you want to enable debuging. See modinfo dvb-dibusb for
-	  debug levels.
diff --git a/drivers/media/dvb/dibusb/Makefile b/drivers/media/dvb/dibusb/Makefile
deleted file mode 100644
--- a/drivers/media/dvb/dibusb/Makefile
+++ /dev/null
@@ -1,11 +0,0 @@
-dvb-dibusb-objs = dvb-dibusb-core.o \
-	dvb-dibusb-dvb.o \
-	dvb-dibusb-fe-i2c.o \
-	dvb-dibusb-firmware.o \
-	dvb-dibusb-remote.o \
-	dvb-dibusb-usb.o \
-	dvb-fe-dtt200u.o
-
-obj-$(CONFIG_DVB_DIBUSB) += dvb-dibusb.o
-
-EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
diff --git a/drivers/media/dvb/dibusb/dvb-dibusb-core.c b/drivers/media/dvb/dibusb/dvb-dibusb-core.c
deleted file mode 100644
--- a/drivers/media/dvb/dibusb/dvb-dibusb-core.c
+++ /dev/null
@@ -1,558 +0,0 @@
-/*
- * Driver for mobile USB Budget DVB-T devices based on reference 
- * design made by DiBcom (http://www.dibcom.fr/)
- * 
- * dvb-dibusb-core.c
- * 
- * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
- * 
- * based on GPL code from DiBcom, which has
- * Copyright (C) 2004 Amaury Demol for DiBcom (ademol@dibcom.fr)
- *
- * Remote control code added by David Matthews (dm@prolingua.co.uk)
- * 
- *	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, version 2.
- *
- * Acknowledgements
- * 
- *  Amaury Demol (ademol@dibcom.fr) from DiBcom for providing specs and driver
- *  sources, on which this driver (and the dib3000mb/mc/p frontends) are based.
- * 
- * see Documentation/dvb/README.dibusb for more information
- */
-#include "dvb-dibusb.h"
-
-#include <linux/moduleparam.h>
-
-/* debug */
-int dvb_dibusb_debug;
-module_param_named(debug, dvb_dibusb_debug,  int, 0644);
-
-#ifdef CONFIG_DVB_DIBCOM_DEBUG
-#define DBSTATUS ""
-#else
-#define DBSTATUS " (debugging is not enabled)"
-#endif
-MODULE_PARM_DESC(debug, "set debugging level (1=info,2=xfer,4=alotmore,8=ts,16=err,32=rc (|-able))." DBSTATUS);
-#undef DBSTATUS
-
-static int pid_parse;
-module_param(pid_parse, int, 0644);
-MODULE_PARM_DESC(pid_parse, "enable pid parsing (filtering) when running at USB2.0");
-
-static int rc_query_interval = 100;
-module_param(rc_query_interval, int, 0644);
-MODULE_PARM_DESC(rc_query_interval, "interval in msecs for remote control query (default: 100; min: 40)");
-
-static int rc_key_repeat_count = 2;
-module_param(rc_key_repeat_count, int, 0644);
-MODULE_PARM_DESC(rc_key_repeat_count, "how many key repeats will be dropped before passing the key event again (default: 2)");
-
-/* Vendor IDs */
-#define USB_VID_ADSTECH						0x06e1
-#define USB_VID_ANCHOR						0x0547
-#define USB_VID_AVERMEDIA					0x14aa
-#define USB_VID_COMPRO						0x185b
-#define USB_VID_COMPRO_UNK					0x145f
-#define USB_VID_CYPRESS						0x04b4
-#define USB_VID_DIBCOM						0x10b8
-#define USB_VID_EMPIA						0xeb1a
-#define USB_VID_GRANDTEC					0x5032
-#define USB_VID_HANFTEK						0x15f4
-#define USB_VID_HAUPPAUGE					0x2040
-#define USB_VID_HYPER_PALTEK				0x1025
-#define USB_VID_IMC_NETWORKS				0x13d3
-#define USB_VID_TWINHAN						0x1822
-#define USB_VID_ULTIMA_ELECTRONIC			0x05d8
-
-/* Product IDs */
-#define USB_PID_ADSTECH_USB2_COLD			0xa333
-#define USB_PID_ADSTECH_USB2_WARM			0xa334
-#define USB_PID_AVERMEDIA_DVBT_USB_COLD		0x0001
-#define USB_PID_AVERMEDIA_DVBT_USB_WARM		0x0002
-#define USB_PID_COMPRO_DVBU2000_COLD		0xd000
-#define USB_PID_COMPRO_DVBU2000_WARM		0xd001
-#define USB_PID_COMPRO_DVBU2000_UNK_COLD	0x010c
-#define USB_PID_COMPRO_DVBU2000_UNK_WARM	0x010d
-#define USB_PID_DIBCOM_MOD3000_COLD			0x0bb8
-#define USB_PID_DIBCOM_MOD3000_WARM			0x0bb9
-#define USB_PID_DIBCOM_MOD3001_COLD			0x0bc6
-#define USB_PID_DIBCOM_MOD3001_WARM			0x0bc7
-#define USB_PID_DIBCOM_ANCHOR_2135_COLD		0x2131
-#define USB_PID_GRANDTEC_DVBT_USB_COLD		0x0fa0
-#define USB_PID_GRANDTEC_DVBT_USB_WARM		0x0fa1
-#define USB_PID_KWORLD_VSTREAM_COLD			0x17de
-#define USB_PID_KWORLD_VSTREAM_WARM			0x17df
-#define USB_PID_TWINHAN_VP7041_COLD			0x3201
-#define USB_PID_TWINHAN_VP7041_WARM			0x3202
-#define USB_PID_ULTIMA_TVBOX_COLD			0x8105
-#define USB_PID_ULTIMA_TVBOX_WARM			0x8106
-#define USB_PID_ULTIMA_TVBOX_AN2235_COLD	0x8107
-#define USB_PID_ULTIMA_TVBOX_AN2235_WARM	0x8108
-#define USB_PID_ULTIMA_TVBOX_ANCHOR_COLD	0x2235
-#define USB_PID_ULTIMA_TVBOX_USB2_COLD		0x8109
-#define USB_PID_ULTIMA_TVBOX_USB2_FX_COLD	0x8613
-#define USB_PID_ULTIMA_TVBOX_USB2_FX_WARM	0x1002
-#define USB_PID_UNK_HYPER_PALTEK_COLD		0x005e
-#define USB_PID_UNK_HYPER_PALTEK_WARM		0x005f
-#define USB_PID_HANFTEK_UMT_010_COLD		0x0001
-#define USB_PID_HANFTEK_UMT_010_WARM		0x0015
-#define USB_PID_YAKUMO_DTT200U_COLD			0x0201
-#define USB_PID_YAKUMO_DTT200U_WARM			0x0301
-#define USB_PID_WINTV_NOVA_T_USB2_COLD		0x9300
-#define USB_PID_WINTV_NOVA_T_USB2_WARM		0x9301
-
-/* USB Driver stuff
- * table of devices that this driver is working with
- *
- * ATTENTION: Never ever change the order of this table, the particular 
- * devices depend on this order 
- *
- * Each entry is used as a reference in the device_struct. Currently this is 
- * the only non-redundant way of assigning USB ids to actual devices I'm aware 
- * of, because there is only one place in the code where the assignment of 
- * vendor and product id is done, here.
- */
-static struct usb_device_id dib_table [] = {
-/* 00 */	{ USB_DEVICE(USB_VID_AVERMEDIA,		USB_PID_AVERMEDIA_DVBT_USB_COLD)},
-/* 01 */	{ USB_DEVICE(USB_VID_AVERMEDIA,		USB_PID_AVERMEDIA_DVBT_USB_WARM)},
-/* 02 */	{ USB_DEVICE(USB_VID_AVERMEDIA,		USB_PID_YAKUMO_DTT200U_COLD) },
-/* 03 */	{ USB_DEVICE(USB_VID_AVERMEDIA,		USB_PID_YAKUMO_DTT200U_WARM) },
-
-/* 04 */	{ USB_DEVICE(USB_VID_COMPRO,		USB_PID_COMPRO_DVBU2000_COLD) },
-/* 05 */	{ USB_DEVICE(USB_VID_COMPRO,		USB_PID_COMPRO_DVBU2000_WARM) },
-/* 06 */	{ USB_DEVICE(USB_VID_COMPRO_UNK,	USB_PID_COMPRO_DVBU2000_UNK_COLD) },
-/* 07 */	{ USB_DEVICE(USB_VID_DIBCOM,		USB_PID_DIBCOM_MOD3000_COLD) },
-/* 08 */	{ USB_DEVICE(USB_VID_DIBCOM,		USB_PID_DIBCOM_MOD3000_WARM) },
-/* 09 */	{ USB_DEVICE(USB_VID_DIBCOM,		USB_PID_DIBCOM_MOD3001_COLD) },
-/* 10 */	{ USB_DEVICE(USB_VID_DIBCOM,		USB_PID_DIBCOM_MOD3001_WARM) },
-/* 11 */	{ USB_DEVICE(USB_VID_EMPIA,			USB_PID_KWORLD_VSTREAM_COLD) },
-/* 12 */	{ USB_DEVICE(USB_VID_EMPIA,			USB_PID_KWORLD_VSTREAM_WARM) },
-/* 13 */	{ USB_DEVICE(USB_VID_GRANDTEC,		USB_PID_GRANDTEC_DVBT_USB_COLD) },
-/* 14 */	{ USB_DEVICE(USB_VID_GRANDTEC,		USB_PID_GRANDTEC_DVBT_USB_WARM) },
-/* 15 */	{ USB_DEVICE(USB_VID_GRANDTEC,		USB_PID_DIBCOM_MOD3000_COLD) },
-/* 16 */	{ USB_DEVICE(USB_VID_GRANDTEC,		USB_PID_DIBCOM_MOD3000_WARM) },
-/* 17 */	{ USB_DEVICE(USB_VID_HYPER_PALTEK,	USB_PID_UNK_HYPER_PALTEK_COLD) },
-/* 18 */	{ USB_DEVICE(USB_VID_HYPER_PALTEK,	USB_PID_UNK_HYPER_PALTEK_WARM) },
-/* 19 */	{ USB_DEVICE(USB_VID_IMC_NETWORKS,	USB_PID_TWINHAN_VP7041_COLD) },
-/* 20 */	{ USB_DEVICE(USB_VID_IMC_NETWORKS,	USB_PID_TWINHAN_VP7041_WARM) },
-/* 21 */	{ USB_DEVICE(USB_VID_TWINHAN, 		USB_PID_TWINHAN_VP7041_COLD) },
-/* 22 */	{ USB_DEVICE(USB_VID_TWINHAN, 		USB_PID_TWINHAN_VP7041_WARM) },
-/* 23 */	{ USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_COLD) },
-/* 24 */	{ USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_WARM) },
-/* 25 */	{ USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_AN2235_COLD) },
-/* 26 */	{ USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_AN2235_WARM) },
-/* 27 */	{ USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC,	USB_PID_ULTIMA_TVBOX_USB2_COLD) },
-	
-/* 28 */	{ USB_DEVICE(USB_VID_HANFTEK,		USB_PID_HANFTEK_UMT_010_COLD) },
-/* 29 */	{ USB_DEVICE(USB_VID_HANFTEK,		USB_PID_HANFTEK_UMT_010_WARM) },
-
-/* 30 */	{ USB_DEVICE(USB_VID_HAUPPAUGE,		USB_PID_WINTV_NOVA_T_USB2_COLD) },
-/* 31 */	{ USB_DEVICE(USB_VID_HAUPPAUGE,		USB_PID_WINTV_NOVA_T_USB2_WARM) },
-/* 32 */	{ USB_DEVICE(USB_VID_ADSTECH,		USB_PID_ADSTECH_USB2_COLD) },
-/* 33 */	{ USB_DEVICE(USB_VID_ADSTECH,		USB_PID_ADSTECH_USB2_WARM) },
-/* 
- * activate the following define when you have one of the devices and want to 
- * build it from build-2.6 in dvb-kernel
- */
-// #define CONFIG_DVB_DIBUSB_MISDESIGNED_DEVICES
-#ifdef CONFIG_DVB_DIBUSB_MISDESIGNED_DEVICES
-/* 34 */	{ USB_DEVICE(USB_VID_ANCHOR,		USB_PID_ULTIMA_TVBOX_ANCHOR_COLD) },
-/* 35 */	{ USB_DEVICE(USB_VID_CYPRESS,		USB_PID_ULTIMA_TVBOX_USB2_FX_COLD) },
-/* 36 */	{ USB_DEVICE(USB_VID_ANCHOR,		USB_PID_ULTIMA_TVBOX_USB2_FX_WARM) },
-/* 37 */	{ USB_DEVICE(USB_VID_ANCHOR,		USB_PID_DIBCOM_ANCHOR_2135_COLD) },
-#endif
-			{ }		/* Terminating entry */
-};
-
-MODULE_DEVICE_TABLE (usb, dib_table);
-
-static struct dibusb_usb_controller dibusb_usb_ctrl[] = {
-	{ .name = "Cypress AN2135", .cpu_cs_register = 0x7f92 },
-	{ .name = "Cypress AN2235", .cpu_cs_register = 0x7f92 },
-	{ .name = "Cypress FX2",    .cpu_cs_register = 0xe600 },
-};
-
-struct dibusb_tuner dibusb_tuner[] = {
-	{ DIBUSB_TUNER_CABLE_THOMSON, 
-	  0x61 
-	},
-	{ DIBUSB_TUNER_COFDM_PANASONIC_ENV57H1XD5,
-	  0x60 
-	},
-	{ DIBUSB_TUNER_CABLE_LG_TDTP_E102P,
-	  0x61
-	},
-	{ DIBUSB_TUNER_COFDM_PANASONIC_ENV77H11D5,
-	  0x60
-	},
-};
-
-static struct dibusb_demod dibusb_demod[] = {
-	{ DIBUSB_DIB3000MB,
-	  16,
-	  { 0x8, 0 },
-	},
-	{ DIBUSB_DIB3000MC,
-	  32,
-	  { 0x9, 0xa, 0xb, 0xc }, 
-	},
-	{ DIBUSB_MT352,
-	  254,
-	  { 0xf, 0 }, 
-	},
-	{ DTT200U_FE,
-	  8,
-	  { 0xff,0 }, /* there is no i2c bus in this device */
-	}
-};
-
-static struct dibusb_device_class dibusb_device_classes[] = {
-	{ .id = DIBUSB1_1, .usb_ctrl = &dibusb_usb_ctrl[0],
-	  .firmware = "dvb-dibusb-5.0.0.11.fw",
-	  .pipe_cmd = 0x01, .pipe_data = 0x02, 
-	  .urb_count = 7, .urb_buffer_size = 4096,
-	  DIBUSB_RC_NEC_PROTOCOL,
-	  &dibusb_demod[DIBUSB_DIB3000MB],
-	  &dibusb_tuner[DIBUSB_TUNER_CABLE_THOMSON],
-	},
-	{ DIBUSB1_1_AN2235, &dibusb_usb_ctrl[1],
-	  "dvb-dibusb-an2235-1.fw",
-	  0x01, 0x02, 
-	  7, 4096,
-	  DIBUSB_RC_NEC_PROTOCOL,
-	  &dibusb_demod[DIBUSB_DIB3000MB],
-	  &dibusb_tuner[DIBUSB_TUNER_CABLE_THOMSON],
-	},
-	{ DIBUSB2_0,&dibusb_usb_ctrl[2],
-	  "dvb-dibusb-6.0.0.5.fw",
-	  0x01, 0x06, 
-	  7, 4096,
-	  DIBUSB_RC_NEC_PROTOCOL,
-	  &dibusb_demod[DIBUSB_DIB3000MC],
-	  &dibusb_tuner[DIBUSB_TUNER_COFDM_PANASONIC_ENV57H1XD5],
-	},
-	{ UMT2_0, &dibusb_usb_ctrl[2],
-	  "dvb-dibusb-umt-2.fw",
-	  0x01, 0x06,
-	  20, 512,
-	  DIBUSB_RC_NO,
-	  &dibusb_demod[DIBUSB_MT352],
-	  &dibusb_tuner[DIBUSB_TUNER_CABLE_LG_TDTP_E102P],
-	},
-	{ DIBUSB2_0B,&dibusb_usb_ctrl[2],
-	  "dvb-dibusb-adstech-usb2-1.fw",
-	  0x01, 0x06,
-	  7, 4096,
-	  DIBUSB_RC_NEC_PROTOCOL,
-	  &dibusb_demod[DIBUSB_DIB3000MB],
-	  &dibusb_tuner[DIBUSB_TUNER_CABLE_THOMSON],
-	},
-	{ NOVAT_USB2,&dibusb_usb_ctrl[2],
-	  "dvb-dibusb-nova-t-1.fw",
-	  0x01, 0x06,
-	  7, 4096,
-	  DIBUSB_RC_HAUPPAUGE_PROTO,
-	  &dibusb_demod[DIBUSB_DIB3000MC],
-	  &dibusb_tuner[DIBUSB_TUNER_COFDM_PANASONIC_ENV57H1XD5],
-	},
-	{ DTT200U,&dibusb_usb_ctrl[2],
-	  "dvb-dtt200u-1.fw",
-	  0x01, 0x02,
-	  7, 4096,
-	  DIBUSB_RC_NO,
-	  &dibusb_demod[DTT200U_FE],
-	  NULL, /* no explicit tuner/pll-programming necessary (it has the ENV57H1XD5) */
-	},
-};
-
-static struct dibusb_usb_device dibusb_devices[] = {
-	{	"TwinhanDTV USB1.1 / Magic Box / HAMA USB1.1 DVB-T device",
-		&dibusb_device_classes[DIBUSB1_1],
-		{ &dib_table[19], &dib_table[21], NULL},
-		{ &dib_table[20], &dib_table[22], NULL},
-	},
-	{	"KWorld V-Stream XPERT DTV - DVB-T USB1.1",
-		&dibusb_device_classes[DIBUSB1_1],
-		{ &dib_table[11], NULL },
-		{ &dib_table[12], NULL },
-	},
-	{	"Grandtec USB1.1 DVB-T",
-		&dibusb_device_classes[DIBUSB1_1],
-		{ &dib_table[13], &dib_table[15], NULL },
-		{ &dib_table[14], &dib_table[16], NULL },
-	},
-	{	"DiBcom USB1.1 DVB-T reference design (MOD3000)",
-		&dibusb_device_classes[DIBUSB1_1],
-		{ &dib_table[7],  NULL },
-		{ &dib_table[8],  NULL },
-	},
-	{	"Artec T1 USB1.1 TVBOX with AN2135",
-		&dibusb_device_classes[DIBUSB1_1],
-		{ &dib_table[23], NULL },
-		{ &dib_table[24], NULL },
-	},
-	{	"Artec T1 USB1.1 TVBOX with AN2235",
-		&dibusb_device_classes[DIBUSB1_1_AN2235],
-		{ &dib_table[25], NULL },
-		{ &dib_table[26], NULL },
-	},
-	{	"Avermedia AverTV DVBT USB1.1",
-		&dibusb_device_classes[DIBUSB1_1],
-		{ &dib_table[0],  NULL },
-		{ &dib_table[1],  NULL },
-	},
-	{	"Compro Videomate DVB-U2000 - DVB-T USB1.1 (please confirm to linux-dvb)",
-		&dibusb_device_classes[DIBUSB1_1],
-		{ &dib_table[4], &dib_table[6], NULL},
-		{ &dib_table[5], NULL },
-	},
-	{	"Unkown USB1.1 DVB-T device ???? please report the name to the author",
-		&dibusb_device_classes[DIBUSB1_1],
-		{ &dib_table[17], NULL },
-		{ &dib_table[18], NULL },
-	},
-	{	"DiBcom USB2.0 DVB-T reference design (MOD3000P)",
-		&dibusb_device_classes[DIBUSB2_0],
-		{ &dib_table[9],  NULL },
-		{ &dib_table[10], NULL },
-	},
-	{	"Artec T1 USB2.0 TVBOX (please report the warm ID)",
-		&dibusb_device_classes[DIBUSB2_0],
-		{ &dib_table[27], NULL },
-		{ NULL },
-	},
-	{	"Hauppauge WinTV NOVA-T USB2",
-		&dibusb_device_classes[NOVAT_USB2],
-		{ &dib_table[30], NULL },
-		{ &dib_table[31], NULL },
-	},
-	{	"DTT200U (Yakumo/Hama/Typhoon) DVB-T USB2.0",
-		&dibusb_device_classes[DTT200U],
-		{ &dib_table[2], NULL },
-		{ &dib_table[3], NULL },
-	},	
-	{	"Hanftek UMT-010 DVB-T USB2.0",
-		&dibusb_device_classes[UMT2_0],
-		{ &dib_table[28], NULL },
-		{ &dib_table[29], NULL },
-	},	
-	{	"KWorld/ADSTech Instant DVB-T USB 2.0",
-		&dibusb_device_classes[DIBUSB2_0B],
-		{ &dib_table[32], NULL },
-		{ &dib_table[33], NULL }, /* device ID with default DIBUSB2_0-firmware */
-	},
-#ifdef CONFIG_DVB_DIBUSB_MISDESIGNED_DEVICES
-	{	"Artec T1 USB1.1 TVBOX with AN2235 (misdesigned)",
-		&dibusb_device_classes[DIBUSB1_1_AN2235],
-		{ &dib_table[34], NULL },
-		{ NULL },
-	},
-	{	"Artec T1 USB2.0 TVBOX with FX2 IDs (misdesigned, please report the warm ID)",
-		&dibusb_device_classes[DTT200U],
-		{ &dib_table[35], NULL },
-		{ &dib_table[36], NULL }, /* undefined, it could be that the device will get another USB ID in warm state */
-	},
-	{	"DiBcom USB1.1 DVB-T reference design (MOD3000) with AN2135 default IDs",
-		&dibusb_device_classes[DIBUSB1_1],
-		{ &dib_table[37], NULL },
-		{ NULL },
-	},
-#endif
-};
-
-static int dibusb_exit(struct usb_dibusb *dib)
-{
-	deb_info("init_state before exiting everything: %x\n",dib->init_state);
-	dibusb_remote_exit(dib);
-	dibusb_fe_exit(dib);
-	dibusb_i2c_exit(dib);
-	dibusb_dvb_exit(dib);
-	dibusb_urb_exit(dib);
-	deb_info("init_state should be zero now: %x\n",dib->init_state);
-	dib->init_state = DIBUSB_STATE_INIT;
-	kfree(dib);
-	return 0;
-}
-
-static int dibusb_init(struct usb_dibusb *dib)
-{
-	int ret = 0;
-	sema_init(&dib->usb_sem, 1);
-	sema_init(&dib->i2c_sem, 1);
-
-	dib->init_state = DIBUSB_STATE_INIT;
-	
-	if ((ret = dibusb_urb_init(dib)) ||
-		(ret = dibusb_dvb_init(dib)) || 
-		(ret = dibusb_i2c_init(dib))) {
-		dibusb_exit(dib);
-		return ret;
-	}
-
-	if ((ret = dibusb_fe_init(dib)))
-		err("could not initialize a frontend.");
-	
-	if ((ret = dibusb_remote_init(dib)))
-		err("could not initialize remote control.");
-	
-	return 0;
-}
-
-static struct dibusb_usb_device * dibusb_device_class_quirk(struct usb_device *udev, struct dibusb_usb_device *dev)
-{
-	int i;
-
-	/* Quirk for the Kworld/ADSTech Instant USB2.0 device. It has the same USB
-	 * IDs like the USB1.1 KWorld after loading the firmware. Which is a bad
-	 * idea and make this quirk necessary.
-	 */
-	if (dev->dev_cl->id == DIBUSB1_1 && udev->speed == USB_SPEED_HIGH) {
-		info("this seems to be the Kworld/ADSTech Instant USB2.0 device or equal.");
-		for (i = 0; i < sizeof(dibusb_devices)/sizeof(struct dibusb_usb_device); i++) {
-			if (dibusb_devices[i].dev_cl->id == DIBUSB2_0B) {
-				dev = &dibusb_devices[i];
-				break;
-			}
-		}
-	}
-
-	return dev;
-}
-
-static struct dibusb_usb_device * dibusb_find_device (struct usb_device *udev,int *cold)
-{
-	int i,j;
-	struct dibusb_usb_device *dev = NULL;
-	*cold = -1;
-
-	for (i = 0; i < sizeof(dibusb_devices)/sizeof(struct dibusb_usb_device); i++) {
-		for (j = 0; j < DIBUSB_ID_MAX_NUM && dibusb_devices[i].cold_ids[j] != NULL; j++) {
-			deb_info("check for cold %x %x\n",dibusb_devices[i].cold_ids[j]->idVendor, dibusb_devices[i].cold_ids[j]->idProduct);
-			if (dibusb_devices[i].cold_ids[j]->idVendor == le16_to_cpu(udev->descriptor.idVendor) &&
-				dibusb_devices[i].cold_ids[j]->idProduct == le16_to_cpu(udev->descriptor.idProduct)) {
-				*cold = 1;
-				dev = &dibusb_devices[i];
-				break;
-			}
-		}
-
-		if (dev != NULL)
-			break;
-
-		for (j = 0; j < DIBUSB_ID_MAX_NUM && dibusb_devices[i].warm_ids[j] != NULL; j++) {
-			deb_info("check for warm %x %x\n",dibusb_devices[i].warm_ids[j]->idVendor, dibusb_devices[i].warm_ids[j]->idProduct);
-			if (dibusb_devices[i].warm_ids[j]->idVendor == le16_to_cpu(udev->descriptor.idVendor) &&
-				dibusb_devices[i].warm_ids[j]->idProduct == le16_to_cpu(udev->descriptor.idProduct)) {
-				*cold = 0;
-				dev = &dibusb_devices[i];
-				break;
-			}
-		}
-	}
-
-	if (dev != NULL)
-		dev = dibusb_device_class_quirk(udev,dev);
-
-	return dev;
-}
-
-/*
- * USB 
- */
-static int dibusb_probe(struct usb_interface *intf, 
-		const struct usb_device_id *id)
-{
-	struct usb_device *udev = interface_to_usbdev(intf);
-	struct usb_dibusb *dib = NULL;
-	struct dibusb_usb_device *dibdev = NULL;
-	
-	int ret = -ENOMEM,cold=0;
-
-	if ((dibdev = dibusb_find_device(udev,&cold)) == NULL) {
-		err("something went very wrong, "
-				"unknown product ID: %.4x",le16_to_cpu(udev->descriptor.idProduct));
-		return -ENODEV;
-	}
-	
-	if (cold == 1) {
-		info("found a '%s' in cold state, will try to load a firmware",dibdev->name);
-		ret = dibusb_loadfirmware(udev,dibdev);
-	} else {
-		info("found a '%s' in warm state.",dibdev->name);
-		dib = kmalloc(sizeof(struct usb_dibusb),GFP_KERNEL);
-		if (dib == NULL) {
-			err("no memory");
-			return ret;
-		}
-		memset(dib,0,sizeof(struct usb_dibusb));
-		
-		dib->udev = udev;
-		dib->dibdev = dibdev;
-
-		/* store parameters to structures */
-		dib->rc_query_interval = rc_query_interval;
-		dib->pid_parse = pid_parse;
-		dib->rc_key_repeat_count = rc_key_repeat_count;
-
-		usb_set_intfdata(intf, dib);
-		
-		ret = dibusb_init(dib);
-	}
-	
-	if (ret == 0)
-		info("%s successfully initialized and connected.",dibdev->name);
-	else 
-		info("%s error while loading driver (%d)",dibdev->name,ret);
-	return ret;
-}
-
-static void dibusb_disconnect(struct usb_interface *intf)
-{
-	struct usb_dibusb *dib = usb_get_intfdata(intf);
-	const char *name = DRIVER_DESC;
-	
-	usb_set_intfdata(intf,NULL);
-	if (dib != NULL && dib->dibdev != NULL) {
-		name = dib->dibdev->name;
-		dibusb_exit(dib);
-	}
-	info("%s successfully deinitialized and disconnected.",name);
-	
-}
-
-/* usb specific object needed to register this driver with the usb subsystem */
-static struct usb_driver dibusb_driver = {
-	.owner		= THIS_MODULE,
-	.name		= DRIVER_DESC,
-	.probe 		= dibusb_probe,
-	.disconnect = dibusb_disconnect,
-	.id_table 	= dib_table,
-};
-
-/* module stuff */
-static int __init usb_dibusb_init(void)
-{
-	int result;
-	if ((result = usb_register(&dibusb_driver))) {
-		err("usb_register failed. Error number %d",result);
-		return result;
-	}
-	
-	return 0;
-}
-
-static void __exit usb_dibusb_exit(void)
-{
-	/* deregister this driver from the USB subsystem */
-	usb_deregister(&dibusb_driver);
-}
-
-module_init (usb_dibusb_init);
-module_exit (usb_dibusb_exit);
-
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dibusb/dvb-dibusb-dvb.c b/drivers/media/dvb/dibusb/dvb-dibusb-dvb.c
deleted file mode 100644
--- a/drivers/media/dvb/dibusb/dvb-dibusb-dvb.c
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * dvb-dibusb-dvb.c is part of the driver for mobile USB Budget DVB-T devices 
- * based on reference design made by DiBcom (http://www.dibcom.fr/)
- *
- * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
- *
- * see dvb-dibusb-core.c for more copyright details.
- *
- * This file contains functions for initializing and handling the 
- * linux-dvb API.
- */
-#include "dvb-dibusb.h"
-
-#include <linux/usb.h>
-#include <linux/version.h>
-
-static u32 urb_compl_count;
-
-/*
- * MPEG2 TS DVB stuff 
- */
-void dibusb_urb_complete(struct urb *urb, struct pt_regs *ptregs)
-{
-	struct usb_dibusb *dib = urb->context;
-
-	deb_ts("urb complete feedcount: %d, status: %d, length: %d\n",dib->feedcount,urb->status,
-			urb->actual_length);
-
-	urb_compl_count++;
-	if (urb_compl_count % 1000 == 0)
-		deb_info("%d urbs completed so far.\n",urb_compl_count);
-
-	switch (urb->status) {
-		case 0:         /* success */
-		case -ETIMEDOUT:    /* NAK */
-			break;
-		case -ECONNRESET:   /* kill */
-		case -ENOENT:
-		case -ESHUTDOWN:
-			return;
-		default:        /* error */
-			deb_ts("urb completition error %d.", urb->status);
-			break;
-	}
-
-	if (dib->feedcount > 0 && urb->actual_length > 0) {
-		if (dib->init_state & DIBUSB_STATE_DVB)
-			dvb_dmx_swfilter(&dib->demux, (u8*) urb->transfer_buffer,urb->actual_length);
-	} else 
-		deb_ts("URB dropped because of feedcount.\n");
-
-	usb_submit_urb(urb,GFP_ATOMIC);
-}
-
-static int dibusb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, int onoff) 
-{
-	struct usb_dibusb *dib = dvbdmxfeed->demux->priv;
-	int newfeedcount;
-	
-	if (dib == NULL)
-		return -ENODEV;
-
-	newfeedcount = dib->feedcount + (onoff ? 1 : -1);
-
-	/* 
-	 * stop feed before setting a new pid if there will be no pid anymore 
-	 */
-	if (newfeedcount == 0) {
-		deb_ts("stop feeding\n");
-		if (dib->xfer_ops.fifo_ctrl != NULL) {
-			if (dib->xfer_ops.fifo_ctrl(dib->fe,0)) {
-				err("error while inhibiting fifo.");
-				return -ENODEV;
-			}
-		}
-		dibusb_streaming(dib,0);
-	}
-	
-	dib->feedcount = newfeedcount;
-
-	/* activate the pid on the device specific pid_filter */
-	deb_ts("setting pid: %5d %04x at index %d '%s'\n",dvbdmxfeed->pid,dvbdmxfeed->pid,dvbdmxfeed->index,onoff ? "on" : "off");
-	if (dib->pid_parse && dib->xfer_ops.pid_ctrl != NULL)
-		dib->xfer_ops.pid_ctrl(dib->fe,dvbdmxfeed->index,dvbdmxfeed->pid,onoff);
-
-	/* 
-	 * start the feed if this was the first pid to set and there is still a pid
-	 * for reception.
-	 */
-	if (dib->feedcount == onoff && dib->feedcount > 0) {
-
-		deb_ts("controlling pid parser\n");
-		if (dib->xfer_ops.pid_parse != NULL) {
-			if (dib->xfer_ops.pid_parse(dib->fe,dib->pid_parse) < 0) {
-				err("could not handle pid_parser");
-			}
-		}
-		
-		deb_ts("start feeding\n");
-		if (dib->xfer_ops.fifo_ctrl != NULL) {
-			if (dib->xfer_ops.fifo_ctrl(dib->fe,1)) {
-				err("error while enabling fifo.");
-				return -ENODEV;
-			}
-		}
-		dibusb_streaming(dib,1);
-	}
-	return 0;
-}
-
-static int dibusb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
-{
-	deb_ts("start pid: 0x%04x, feedtype: %d\n", dvbdmxfeed->pid,dvbdmxfeed->type);
-	return dibusb_ctrl_feed(dvbdmxfeed,1);
-}
-
-static int dibusb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
-{
-	deb_ts("stop pid: 0x%04x, feedtype: %d\n", dvbdmxfeed->pid, dvbdmxfeed->type);
-	return dibusb_ctrl_feed(dvbdmxfeed,0);
-}
-
-int dibusb_dvb_init(struct usb_dibusb *dib)
-{
-	int ret;
-
-	urb_compl_count = 0;
-
-	if ((ret = dvb_register_adapter(&dib->adapter, DRIVER_DESC,
-			THIS_MODULE)) < 0) {
-		deb_info("dvb_register_adapter failed: error %d", ret);
-		goto err;
-	}
-	dib->adapter.priv = dib;
-	
-/* i2c is done in dibusb_i2c_init */
-	
-	dib->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING;
-
-	dib->demux.priv = (void *)dib;
-	/* get pidcount from demod */
-	dib->demux.feednum = dib->demux.filternum = 255;
-	dib->demux.start_feed = dibusb_start_feed;
-	dib->demux.stop_feed = dibusb_stop_feed;
-	dib->demux.write_to_decoder = NULL;
-	if ((ret = dvb_dmx_init(&dib->demux)) < 0) {
-		err("dvb_dmx_init failed: error %d",ret);
-		goto err_dmx;
-	}
-
-	dib->dmxdev.filternum = dib->demux.filternum;
-	dib->dmxdev.demux = &dib->demux.dmx;
-	dib->dmxdev.capabilities = 0;
-	if ((ret = dvb_dmxdev_init(&dib->dmxdev, &dib->adapter)) < 0) {
-		err("dvb_dmxdev_init failed: error %d",ret);
-		goto err_dmx_dev;
-	}
-
-	dvb_net_init(&dib->adapter, &dib->dvb_net, &dib->demux.dmx);
-
-	goto success;
-err_dmx_dev:
-	dvb_dmx_release(&dib->demux);
-err_dmx:
-	dvb_unregister_adapter(&dib->adapter);
-err:
-	return ret;
-success:
-	dib->init_state |= DIBUSB_STATE_DVB;
-	return 0;
-}
-
-int dibusb_dvb_exit(struct usb_dibusb *dib)
-{
-	if (dib->init_state & DIBUSB_STATE_DVB) {
-		dib->init_state &= ~DIBUSB_STATE_DVB;
-		deb_info("unregistering DVB part\n");
-		dvb_net_release(&dib->dvb_net);
-		dib->demux.dmx.close(&dib->demux.dmx);
-		dvb_dmxdev_release(&dib->dmxdev);
-		dvb_dmx_release(&dib->demux);
-		dvb_unregister_adapter(&dib->adapter);
-	}
-	return 0;
-}
diff --git a/drivers/media/dvb/dibusb/dvb-dibusb-fe-i2c.c b/drivers/media/dvb/dibusb/dvb-dibusb-fe-i2c.c
deleted file mode 100644
--- a/drivers/media/dvb/dibusb/dvb-dibusb-fe-i2c.c
+++ /dev/null
@@ -1,582 +0,0 @@
-/*
- * dvb-dibusb-fe-i2c.c is part of the driver for mobile USB Budget DVB-T devices
- * based on reference design made by DiBcom (http://www.dibcom.fr/)
- *
- * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
- *
- * see dvb-dibusb-core.c for more copyright details.
- *
- * This file contains functions for attaching, initializing of an appropriate
- * demodulator/frontend. I2C-stuff is also located here.
- *
- */
-#include "dvb-dibusb.h"
-
-#include <linux/usb.h>
-
-static int dibusb_i2c_msg(struct usb_dibusb *dib, u8 addr,
-			  u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen)
-{
-	u8 sndbuf[wlen+4]; /* lead(1) devaddr,direction(1) addr(2) data(wlen) (len(2) (when reading)) */
-	/* write only ? */
-	int wo = (rbuf == NULL || rlen == 0),
-		len = 2 + wlen + (wo ? 0 : 2);
-
-	sndbuf[0] = wo ? DIBUSB_REQ_I2C_WRITE : DIBUSB_REQ_I2C_READ;
-	sndbuf[1] = (addr << 1) | (wo ? 0 : 1);
-
-	memcpy(&sndbuf[2],wbuf,wlen);
-
-	if (!wo) {
-		sndbuf[wlen+2] = (rlen >> 8) & 0xff;
-		sndbuf[wlen+3] = rlen & 0xff;
-	}
-
-	return dibusb_readwrite_usb(dib,sndbuf,len,rbuf,rlen);
-}
-
-/*
- * I2C master xfer function
- */
-static int dibusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg *msg,int num)
-{
-	struct usb_dibusb *dib = i2c_get_adapdata(adap);
-	int i;
-
-	if (down_interruptible(&dib->i2c_sem) < 0)
-		return -EAGAIN;
-
-	if (num > 2)
-		warn("more than 2 i2c messages at a time is not handled yet. TODO.");
-
-	for (i = 0; i < num; i++) {
-		/* write/read request */
-		if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) {
-			if (dibusb_i2c_msg(dib, msg[i].addr, msg[i].buf,msg[i].len,
-						msg[i+1].buf,msg[i+1].len) < 0)
-				break;
-			i++;
-		} else
-			if (dibusb_i2c_msg(dib, msg[i].addr, msg[i].buf,msg[i].len,NULL,0) < 0)
-				break;
-	}
-
-	up(&dib->i2c_sem);
-	return i;
-}
-
-static u32 dibusb_i2c_func(struct i2c_adapter *adapter)
-{
-	return I2C_FUNC_I2C;
-}
-
-static struct i2c_algorithm dibusb_algo = {
-	.name			= "DiBcom USB i2c algorithm",
-	.id				= I2C_ALGO_BIT,
-	.master_xfer	= dibusb_i2c_xfer,
-	.functionality	= dibusb_i2c_func,
-};
-
-static int dibusb_general_demod_init(struct dvb_frontend *fe);
-static u8 dibusb_general_pll_addr(struct dvb_frontend *fe);
-static int dibusb_general_pll_init(struct dvb_frontend *fe, u8 pll_buf[5]);
-static int dibusb_general_pll_set(struct dvb_frontend *fe,
-		struct dvb_frontend_parameters* params, u8 pll_buf[5]);
-
-static struct mt352_config mt352_hanftek_umt_010_config = {
-	.demod_address = 0x1e,
-	.demod_init = dibusb_general_demod_init,
-	.pll_set = dibusb_general_pll_set,
-};
-
-static int dibusb_tuner_quirk(struct usb_dibusb *dib)
-{
-	switch (dib->dibdev->dev_cl->id) {
-		case DIBUSB1_1: /* some these device have the ENV77H11D5 and some the THOMSON CABLE */
-		case DIBUSB1_1_AN2235: { /* actually its this device, but in warm state they are indistinguishable */
-			struct dibusb_tuner *t;
-			u8 b[2] = { 0,0 } ,b2[1];
-			struct i2c_msg msg[2] = {
-				{ .flags = 0, .buf = b, .len = 2 },
-				{ .flags = I2C_M_RD, .buf = b2, .len = 1},
-			};
-
-			t = &dibusb_tuner[DIBUSB_TUNER_COFDM_PANASONIC_ENV77H11D5];
-
-			msg[0].addr = msg[1].addr = t->pll_addr;
-
-			if (dib->xfer_ops.tuner_pass_ctrl != NULL)
-				dib->xfer_ops.tuner_pass_ctrl(dib->fe,1,t->pll_addr);
-			dibusb_i2c_xfer(&dib->i2c_adap,msg,2);
-			if (dib->xfer_ops.tuner_pass_ctrl != NULL)
-				dib->xfer_ops.tuner_pass_ctrl(dib->fe,0,t->pll_addr);
-
-			if (b2[0] == 0xfe)
-				info("this device has the Thomson Cable onboard. Which is default.");
-			else {
-				dib->tuner = t;
-				info("this device has the Panasonic ENV77H11D5 onboard.");
-			}
-			break;
-		}
-		default:
-			break;
-	}
-	return 0;
-}
-
-int dibusb_fe_init(struct usb_dibusb* dib)
-{
-	struct dib3000_config demod_cfg;
-	int i;
-
-	if (dib->init_state & DIBUSB_STATE_I2C) {
-		for (i = 0; i < sizeof(dib->dibdev->dev_cl->demod->i2c_addrs) / sizeof(unsigned char) &&
-				dib->dibdev->dev_cl->demod->i2c_addrs[i] != 0; i++) {
-
-			demod_cfg.demod_address = dib->dibdev->dev_cl->demod->i2c_addrs[i];
-			demod_cfg.pll_addr = dibusb_general_pll_addr;
-			demod_cfg.pll_set = dibusb_general_pll_set;
-			demod_cfg.pll_init = dibusb_general_pll_init;
-
-			deb_info("demod id: %d %d\n",dib->dibdev->dev_cl->demod->id,DTT200U_FE);
-
-			switch (dib->dibdev->dev_cl->demod->id) {
-				case DIBUSB_DIB3000MB:
-					dib->fe = dib3000mb_attach(&demod_cfg,&dib->i2c_adap,&dib->xfer_ops);
-				break;
-				case DIBUSB_DIB3000MC:
-					dib->fe = dib3000mc_attach(&demod_cfg,&dib->i2c_adap,&dib->xfer_ops);
-				break;
-				case DIBUSB_MT352:
-					mt352_hanftek_umt_010_config.demod_address = dib->dibdev->dev_cl->demod->i2c_addrs[i];
-					dib->fe = mt352_attach(&mt352_hanftek_umt_010_config, &dib->i2c_adap);
-				break;
-				case DTT200U_FE:
-					dib->fe = dtt200u_fe_attach(dib,&dib->xfer_ops);
-				break;
-			}
-			if (dib->fe != NULL) {
-				info("found demodulator at i2c address 0x%x",dib->dibdev->dev_cl->demod->i2c_addrs[i]);
-				break;
-			}
-		}
-		/* if a frontend was found */
-		if (dib->fe != NULL) {
-			if (dib->fe->ops->sleep != NULL)
-				dib->fe_sleep = dib->fe->ops->sleep;
-			dib->fe->ops->sleep = dibusb_hw_sleep;
-
-			if (dib->fe->ops->init != NULL )
-				dib->fe_init = dib->fe->ops->init;
-			dib->fe->ops->init = dibusb_hw_wakeup;
-
-			/* setting the default tuner */
-			dib->tuner = dib->dibdev->dev_cl->tuner;
-
-			/* check which tuner is mounted on this device, in case this is unsure */
-			dibusb_tuner_quirk(dib);
-		}
-	}
-	if (dib->fe == NULL) {
-		err("A frontend driver was not found for device '%s'.",
-		       dib->dibdev->name);
-		return -ENODEV;
-	} else {
-		if (dvb_register_frontend(&dib->adapter, dib->fe)) {
-			err("Frontend registration failed.");
-			if (dib->fe->ops->release)
-				dib->fe->ops->release(dib->fe);
-			dib->fe = NULL;
-			return -ENODEV;
-		}
-	}
-
-	return 0;
-}
-
-int dibusb_fe_exit(struct usb_dibusb *dib)
-{
-	if (dib->fe != NULL)
-		dvb_unregister_frontend(dib->fe);
-	return 0;
-}
-
-int dibusb_i2c_init(struct usb_dibusb *dib)
-{
-	int ret = 0;
-
-	dib->adapter.priv = dib;
-
-	strncpy(dib->i2c_adap.name,dib->dibdev->name,I2C_NAME_SIZE);
-#ifdef I2C_ADAP_CLASS_TV_DIGITAL
-	dib->i2c_adap.class = I2C_ADAP_CLASS_TV_DIGITAL,
-#else
-	dib->i2c_adap.class = I2C_CLASS_TV_DIGITAL,
-#endif
-	dib->i2c_adap.algo		= &dibusb_algo;
-	dib->i2c_adap.algo_data = NULL;
-	dib->i2c_adap.id		= I2C_ALGO_BIT;
-
-	i2c_set_adapdata(&dib->i2c_adap, dib);
-
-	if ((ret = i2c_add_adapter(&dib->i2c_adap)) < 0)
-		err("could not add i2c adapter");
-
-	dib->init_state |= DIBUSB_STATE_I2C;
-
-	return ret;
-}
-
-int dibusb_i2c_exit(struct usb_dibusb *dib)
-{
-	if (dib->init_state & DIBUSB_STATE_I2C)
-		i2c_del_adapter(&dib->i2c_adap);
-	dib->init_state &= ~DIBUSB_STATE_I2C;
-	return 0;
-}
-
-
-/* pll stuff, maybe removed soon (thx to Gerd/Andrew in advance) */
-static int thomson_cable_eu_pll_set(struct dvb_frontend_parameters *fep, u8 pllbuf[4])
-{
-	u32 tfreq = (fep->frequency + 36125000) / 62500;
-	int vu,p0,p1,p2;
-
-	if (fep->frequency > 403250000)
-		vu = 1, p2 = 1, p1 = 0, p0 = 1;
-	else if (fep->frequency > 115750000)
-		vu = 0, p2 = 1, p1 = 1, p0 = 0;
-	else if (fep->frequency > 44250000)
-		vu = 0, p2 = 0, p1 = 1, p0 = 1;
-	else
-		return -EINVAL;
-
-	pllbuf[0] = (tfreq >> 8) & 0x7f;
-	pllbuf[1] = tfreq & 0xff;
-	pllbuf[2] = 0x8e;
-	pllbuf[3] = (vu << 7) | (p2 << 2) | (p1 << 1) | p0;
-	return 0;
-}
-
-static int panasonic_cofdm_env57h1xd5_pll_set(struct dvb_frontend_parameters *fep, u8 pllbuf[4])
-{
-	u32 freq_khz = fep->frequency / 1000;
-	u32 tfreq = ((freq_khz + 36125)*6 + 500) / 1000;
-	u8 TA, T210, R210, ctrl1, cp210, p4321;
-	if (freq_khz > 858000) {
-		err("frequency cannot be larger than 858 MHz.");
-		return -EINVAL;
-	}
-
-	// contol data 1 : 1 | T/A=1 | T2,T1,T0 = 0,0,0 | R2,R1,R0 = 0,1,0
-	TA = 1;
-	T210 = 0;
-	R210 = 0x2;
-	ctrl1 = (1 << 7) | (TA << 6) | (T210 << 3) | R210;
-
-// ********    CHARGE PUMP CONFIG vs RF FREQUENCIES     *****************
-	if (freq_khz < 470000)
-		cp210 = 2;  // VHF Low and High band ch E12 to E4 to E12
-	else if (freq_khz < 526000)
-		cp210 = 4;  // UHF band Ch E21 to E27
-	else // if (freq < 862000000)
-		cp210 = 5;  // UHF band ch E28 to E69
-
-//*********************    BW select  *******************************
-	if (freq_khz < 153000)
-		p4321  = 1; // BW selected for VHF low
-	else if (freq_khz < 470000)
-		p4321  = 2; // BW selected for VHF high E5 to E12
-	else // if (freq < 862000000)
-		p4321  = 4; // BW selection for UHF E21 to E69
-
-	pllbuf[0] = (tfreq >> 8) & 0xff;
-	pllbuf[1] = (tfreq >> 0) & 0xff;
-	pllbuf[2] = 0xff & ctrl1;
-	pllbuf[3] =  (cp210 << 5) | (p4321);
-
-	return 0;
-}
-
-/*
- *			    7	6		5	4	3	2	1	0
- * Address Byte             1	1		0	0	0	MA1	MA0	R/~W=0
- *
- * Program divider byte 1   0	n14		n13	n12	n11	n10	n9	n8
- * Program divider byte 2	n7	n6		n5	n4	n3	n2	n1	n0
- *
- * Control byte 1           1	T/A=1	T2	T1	T0	R2	R1	R0
- *                          1	T/A=0	0	0	ATC	AL2	AL1	AL0
- *
- * Control byte 2           CP2	CP1		CP0	BS5	BS4	BS3	BS2	BS1
- *
- * MA0/1 = programmable address bits
- * R/~W  = read/write bit (0 for writing)
- * N14-0 = programmable LO frequency
- *
- * T/A   = test AGC bit (0 = next 6 bits AGC setting,
- *                       1 = next 6 bits test and reference divider ratio settings)
- * T2-0  = test bits
- * R2-0  = reference divider ratio and programmable frequency step
- * ATC   = AGC current setting and time constant
- *         ATC = 0: AGC current = 220nA, AGC time constant = 2s
- *         ATC = 1: AGC current = 9uA, AGC time constant = 50ms
- * AL2-0 = AGC take-over point bits
- * CP2-0 = charge pump current
- * BS5-1 = PMOS ports control bits;
- *             BSn = 0 corresponding port is off, high-impedance state (at power-on)
- *             BSn = 1 corresponding port is on
- */
-static int panasonic_cofdm_env77h11d5_tda6650_init(struct dvb_frontend *fe, u8 pllbuf[4])
-{
-	pllbuf[0] = 0x0b;
-	pllbuf[1] = 0xf5;
-	pllbuf[2] = 0x85;
-	pllbuf[3] = 0xab;
-	return 0;
-}
-
-static int panasonic_cofdm_env77h11d5_tda6650_set (struct dvb_frontend_parameters *fep,u8 pllbuf[4])
-{
-	int tuner_frequency = 0;
-	u8 band, cp, filter;
-
-	// determine charge pump
-	tuner_frequency = fep->frequency + 36166000;
-	if (tuner_frequency < 87000000)
-		return -EINVAL;
-	else if (tuner_frequency < 130000000)
-		cp = 3;
-	else if (tuner_frequency < 160000000)
-		cp = 5;
-	else if (tuner_frequency < 200000000)
-		cp = 6;
-	else if (tuner_frequency < 290000000)
-		cp = 3;
-	else if (tuner_frequency < 420000000)
-		cp = 5;
-	else if (tuner_frequency < 480000000)
-		cp = 6;
-	else if (tuner_frequency < 620000000)
-		cp = 3;
-	else if (tuner_frequency < 830000000)
-		cp = 5;
-	else if (tuner_frequency < 895000000)
-		cp = 7;
-	else
-		return -EINVAL;
-
-	// determine band
-	if (fep->frequency < 49000000)
-		return -EINVAL;
-	else if (fep->frequency < 161000000)
-		band = 1;
-	else if (fep->frequency < 444000000)
-		band = 2;
-	else if (fep->frequency < 861000000)
-		band = 4;
-	else
-		return -EINVAL;
-
-	// setup PLL filter
-	switch (fep->u.ofdm.bandwidth) {
-		case BANDWIDTH_6_MHZ:
-		case BANDWIDTH_7_MHZ:
-			filter = 0;
-			break;
-		case BANDWIDTH_8_MHZ:
-			filter = 1;
-			break;
-		default:
-			return -EINVAL;
-	}
-
-	// calculate divisor
-	// ((36166000+((1000000/6)/2)) + Finput)/(1000000/6)
-	tuner_frequency = (((fep->frequency / 1000) * 6) + 217496) / 1000;
-
-	// setup tuner buffer
-	pllbuf[0] = (tuner_frequency >> 8) & 0x7f;
-	pllbuf[1] = tuner_frequency & 0xff;
-	pllbuf[2] = 0xca;
-	pllbuf[3] = (cp << 5) | (filter << 3) | band;
-	return 0;
-}
-
-/*
- *			    7	6	5	4	3	2	1	0
- * Address Byte             1	1	0	0	0	MA1	MA0	R/~W=0
- *
- * Program divider byte 1   0	n14	n13	n12	n11	n10	n9	n8
- * Program divider byte 2	n7	n6	n5	n4	n3	n2	n1	n0
- *
- * Control byte             1	CP	T2	T1	T0	RSA	RSB	OS
- *
- * Band Switch byte         X	X	X	P4	P3	P2	P1	P0
- *
- * Auxiliary byte           ATC	AL2	AL1	AL0	0	0	0	0
- *
- * Address: MA1	MA0	Address
- *          0	0	c0
- *          0	1	c2 (always valid)
- *          1	0	c4
- *          1	1	c6
- */
-static int lg_tdtp_e102p_tua6034(struct dvb_frontend_parameters* fep, u8 pllbuf[4])
-{
-	u32 div;
-	u8 p210, p3;
-
-#define TUNER_MUL 62500
-
-	div = (fep->frequency + 36125000 + TUNER_MUL / 2) / TUNER_MUL;
-//	div = ((fep->frequency/1000 + 36166) * 6) / 1000;
-
-	if (fep->frequency < 174500000)
-		p210 = 1; // not supported by the tdtp_e102p
-	else if (fep->frequency < 230000000) // VHF
-		p210 = 2;
-	else
-		p210 = 4;
-
-	if (fep->u.ofdm.bandwidth == BANDWIDTH_7_MHZ)
-		p3 = 0;
-	else
-		p3 = 1;
-
-	pllbuf[0] = (div >> 8) & 0x7f;
-	pllbuf[1] = div & 0xff;
-	pllbuf[2] = 0xce;
-//	pllbuf[2] = 0xcc;
-	pllbuf[3] = (p3 << 3) | p210;
-
-	return 0;
-}
-
-static int lg_tdtp_e102p_mt352_demod_init(struct dvb_frontend *fe)
-{
-	static u8 mt352_clock_config[] = { 0x89, 0xb8, 0x2d };
-	static u8 mt352_reset[] = { 0x50, 0x80 };
-	static u8 mt352_mclk_ratio[] = { 0x8b, 0x00 };
-	static u8 mt352_adc_ctl_1_cfg[] = { 0x8E, 0x40 };
-	static u8 mt352_agc_cfg[] = { 0x67, 0x10, 0xa0 };
-
-	static u8 mt352_sec_agc_cfg1[] = { 0x6a, 0xff };
-	static u8 mt352_sec_agc_cfg2[] = { 0x6d, 0xff };
-	static u8 mt352_sec_agc_cfg3[] = { 0x70, 0x40 };
-	static u8 mt352_sec_agc_cfg4[] = { 0x7b, 0x03 };
-	static u8 mt352_sec_agc_cfg5[] = { 0x7d, 0x0f };
-
-	static u8 mt352_acq_ctl[] = { 0x53, 0x50 };
-	static u8 mt352_input_freq_1[] = { 0x56, 0x31, 0x06 };
-
-	mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config));
-	udelay(2000);
-	mt352_write(fe, mt352_reset, sizeof(mt352_reset));
-	mt352_write(fe, mt352_mclk_ratio, sizeof(mt352_mclk_ratio));
-
-	mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg));
-	mt352_write(fe, mt352_agc_cfg, sizeof(mt352_agc_cfg));
-
-	mt352_write(fe, mt352_sec_agc_cfg1, sizeof(mt352_sec_agc_cfg1));
-	mt352_write(fe, mt352_sec_agc_cfg2, sizeof(mt352_sec_agc_cfg2));
-	mt352_write(fe, mt352_sec_agc_cfg3, sizeof(mt352_sec_agc_cfg3));
-	mt352_write(fe, mt352_sec_agc_cfg4, sizeof(mt352_sec_agc_cfg4));
-	mt352_write(fe, mt352_sec_agc_cfg5, sizeof(mt352_sec_agc_cfg5));
-
-	mt352_write(fe, mt352_acq_ctl, sizeof(mt352_acq_ctl));
-	mt352_write(fe, mt352_input_freq_1, sizeof(mt352_input_freq_1));
-
-	return 0;
-}
-
-static int dibusb_general_demod_init(struct dvb_frontend *fe)
-{
-	struct usb_dibusb* dib = (struct usb_dibusb*) fe->dvb->priv;
-	switch (dib->dibdev->dev_cl->id) {
-		case UMT2_0:
-			return lg_tdtp_e102p_mt352_demod_init(fe);
-		default: /* other device classes do not have device specific demod inits */
-			break;
-	}
-	return 0;
-}
-
-static u8 dibusb_general_pll_addr(struct dvb_frontend *fe)
-{
-	struct usb_dibusb* dib = (struct usb_dibusb*) fe->dvb->priv;
-	return dib->tuner->pll_addr;
-}
-
-static int dibusb_pll_i2c_helper(struct usb_dibusb *dib, u8 pll_buf[5], u8 buf[4])
-{
-	if (pll_buf == NULL) {
-		struct i2c_msg msg = {
-			.addr = dib->tuner->pll_addr,
-			.flags = 0,
-			.buf = buf,
-			.len = sizeof(buf)
-		};
-		if (i2c_transfer (&dib->i2c_adap, &msg, 1) != 1)
-			return -EIO;
-		msleep(1);
-	} else {
-		pll_buf[0] = dib->tuner->pll_addr << 1;
-		memcpy(&pll_buf[1],buf,4);
-	}
-
-	return 0;
-}
-
-static int dibusb_general_pll_init(struct dvb_frontend *fe,
-		u8 pll_buf[5])
-{
-	struct usb_dibusb* dib = (struct usb_dibusb*) fe->dvb->priv;
-	u8 buf[4];
-	int ret=0;
-	switch (dib->tuner->id) {
-		case DIBUSB_TUNER_COFDM_PANASONIC_ENV77H11D5:
-			ret = panasonic_cofdm_env77h11d5_tda6650_init(fe,buf);
-			break;
-		default:
-			break;
-	}
-
-	if (ret)
-		return ret;
-
-	return dibusb_pll_i2c_helper(dib,pll_buf,buf);
-}
-
-static int dibusb_general_pll_set(struct dvb_frontend *fe,
-		struct dvb_frontend_parameters *fep, u8 pll_buf[5])
-{
-	struct usb_dibusb* dib = (struct usb_dibusb*) fe->dvb->priv;
-	u8 buf[4];
-	int ret=0;
-
-	switch (dib->tuner->id) {
-		case DIBUSB_TUNER_CABLE_THOMSON:
-			ret = thomson_cable_eu_pll_set(fep, buf);
-			break;
-		case DIBUSB_TUNER_COFDM_PANASONIC_ENV57H1XD5:
-			ret = panasonic_cofdm_env57h1xd5_pll_set(fep, buf);
-			break;
-		case DIBUSB_TUNER_CABLE_LG_TDTP_E102P:
-			ret = lg_tdtp_e102p_tua6034(fep, buf);
-			break;
-		case DIBUSB_TUNER_COFDM_PANASONIC_ENV77H11D5:
-			ret = panasonic_cofdm_env77h11d5_tda6650_set(fep,buf);
-			break;
-		default:
-			warn("no pll programming routine found for tuner %d.\n",dib->tuner->id);
-			ret = -ENODEV;
-			break;
-	}
-
-	if (ret)
-		return ret;
-
-	return dibusb_pll_i2c_helper(dib,pll_buf,buf);
-}
diff --git a/drivers/media/dvb/dibusb/dvb-dibusb-firmware.c b/drivers/media/dvb/dibusb/dvb-dibusb-firmware.c
deleted file mode 100644
--- a/drivers/media/dvb/dibusb/dvb-dibusb-firmware.c
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * dvb-dibusb-firmware.c is part of the driver for mobile USB Budget DVB-T devices 
- * based on reference design made by DiBcom (http://www.dibcom.fr/)
- *
- * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
- *
- * see dvb-dibusb-core.c for more copyright details.
- *
- * This file contains functions for downloading the firmware to the device.
- */
-#include "dvb-dibusb.h"
-
-#include <linux/firmware.h>
-#include <linux/usb.h>
-
-/*
- * load a firmware packet to the device 
- */
-static int dibusb_writemem(struct usb_device *udev,u16 addr,u8 *data, u8 len)
-{
-	return usb_control_msg(udev, usb_sndctrlpipe(udev,0),
-			0xa0, USB_TYPE_VENDOR, addr, 0x00, data, len, 5000);
-}
-
-int dibusb_loadfirmware(struct usb_device *udev, struct dibusb_usb_device *dibdev)
-{
-	const struct firmware *fw = NULL;
-	u16 addr;
-	u8 *b,*p;
-	int ret = 0,i;
-	
-	if ((ret = request_firmware(&fw, dibdev->dev_cl->firmware, &udev->dev)) != 0) {
-		err("did not find the firmware file. (%s) "
-			"Please see linux/Documentation/dvb/ for more details on firmware-problems.",
-			dibdev->dev_cl->firmware);
-		return ret;
-	}
-
-	info("downloading firmware from file '%s'.",dibdev->dev_cl->firmware);
-	
-	p = kmalloc(fw->size,GFP_KERNEL);	
-	if (p != NULL) {
-		u8 reset;
-		/*
-		 * you cannot use the fw->data as buffer for 
-		 * usb_control_msg, a new buffer has to be
-		 * created
-		 */
-		memcpy(p,fw->data,fw->size);
-
-		/* stop the CPU */
-		reset = 1;
-		if ((ret = dibusb_writemem(udev,dibdev->dev_cl->usb_ctrl->cpu_cs_register,&reset,1)) != 1) 
-			err("could not stop the USB controller CPU.");
-		for(i = 0; p[i+3] == 0 && i < fw->size; ) { 
-			b = (u8 *) &p[i];
-			addr = *((u16 *) &b[1]);
-
-			ret = dibusb_writemem(udev,addr,&b[4],b[0]);
-		
-			if (ret != b[0]) {
-				err("error while transferring firmware "
-					"(transferred size: %d, block size: %d)",
-					ret,b[0]);
-				ret = -EINVAL;
-				break;
-			}
-			i += 5 + b[0];
-		}
-		/* length in ret */
-		if (ret > 0)
-			ret = 0;
-		/* restart the CPU */
-		reset = 0;
-		if (ret || dibusb_writemem(udev,dibdev->dev_cl->usb_ctrl->cpu_cs_register,&reset,1) != 1) {
-			err("could not restart the USB controller CPU.");
-			ret = -EINVAL;
-		}
-
-		kfree(p);
-	} else { 
-		ret = -ENOMEM;
-	}
-	release_firmware(fw);
-
-	return ret;
-}
diff --git a/drivers/media/dvb/dibusb/dvb-dibusb-remote.c b/drivers/media/dvb/dibusb/dvb-dibusb-remote.c
deleted file mode 100644
--- a/drivers/media/dvb/dibusb/dvb-dibusb-remote.c
+++ /dev/null
@@ -1,316 +0,0 @@
-/*
- * dvb-dibusb-remote.c is part of the driver for mobile USB Budget DVB-T devices
- * based on reference design made by DiBcom (http://www.dibcom.fr/)
- *
- * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
- *
- * see dvb-dibusb-core.c for more copyright details.
- *
- * This file contains functions for handling the event device on the software
- * side and the remote control on the hardware side.
- */
-#include "dvb-dibusb.h"
-
-/* Table to map raw key codes to key events.  This should not be hard-wired
-   into the kernel.  */
-static const struct { u8 c0, c1, c2; uint32_t key; } nec_rc_keys [] =
-{
-	/* Key codes for the little Artec T1/Twinhan/HAMA/ remote. */
-	{ 0x00, 0xff, 0x16, KEY_POWER },
-	{ 0x00, 0xff, 0x10, KEY_MUTE },
-	{ 0x00, 0xff, 0x03, KEY_1 },
-	{ 0x00, 0xff, 0x01, KEY_2 },
-	{ 0x00, 0xff, 0x06, KEY_3 },
-	{ 0x00, 0xff, 0x09, KEY_4 },
-	{ 0x00, 0xff, 0x1d, KEY_5 },
-	{ 0x00, 0xff, 0x1f, KEY_6 },
-	{ 0x00, 0xff, 0x0d, KEY_7 },
-	{ 0x00, 0xff, 0x19, KEY_8 },
-	{ 0x00, 0xff, 0x1b, KEY_9 },
-	{ 0x00, 0xff, 0x15, KEY_0 },
-	{ 0x00, 0xff, 0x05, KEY_CHANNELUP },
-	{ 0x00, 0xff, 0x02, KEY_CHANNELDOWN },
-	{ 0x00, 0xff, 0x1e, KEY_VOLUMEUP },
-	{ 0x00, 0xff, 0x0a, KEY_VOLUMEDOWN },
-	{ 0x00, 0xff, 0x11, KEY_RECORD },
-	{ 0x00, 0xff, 0x17, KEY_FAVORITES }, /* Heart symbol - Channel list. */
-	{ 0x00, 0xff, 0x14, KEY_PLAY },
-	{ 0x00, 0xff, 0x1a, KEY_STOP },
-	{ 0x00, 0xff, 0x40, KEY_REWIND },
-	{ 0x00, 0xff, 0x12, KEY_FASTFORWARD },
-	{ 0x00, 0xff, 0x0e, KEY_PREVIOUS }, /* Recall - Previous channel. */
-	{ 0x00, 0xff, 0x4c, KEY_PAUSE },
-	{ 0x00, 0xff, 0x4d, KEY_SCREEN }, /* Full screen mode. */
-	{ 0x00, 0xff, 0x54, KEY_AUDIO }, /* MTS - Switch to secondary audio. */
-	/* additional keys TwinHan VisionPlus, the Artec seemingly not have */
-	{ 0x00, 0xff, 0x0c, KEY_CANCEL }, /* Cancel */
-	{ 0x00, 0xff, 0x1c, KEY_EPG }, /* EPG */
-	{ 0x00, 0xff, 0x00, KEY_TAB }, /* Tab */
-	{ 0x00, 0xff, 0x48, KEY_INFO }, /* Preview */
-	{ 0x00, 0xff, 0x04, KEY_LIST }, /* RecordList */
-	{ 0x00, 0xff, 0x0f, KEY_TEXT }, /* Teletext */
-	/* Key codes for the KWorld/ADSTech/JetWay remote. */
-	{ 0x86, 0x6b, 0x12, KEY_POWER },
-	{ 0x86, 0x6b, 0x0f, KEY_SELECT }, /* source */
-	{ 0x86, 0x6b, 0x0c, KEY_UNKNOWN }, /* scan */
-	{ 0x86, 0x6b, 0x0b, KEY_EPG },
-	{ 0x86, 0x6b, 0x10, KEY_MUTE },
-	{ 0x86, 0x6b, 0x01, KEY_1 },
-	{ 0x86, 0x6b, 0x02, KEY_2 },
-	{ 0x86, 0x6b, 0x03, KEY_3 },
-	{ 0x86, 0x6b, 0x04, KEY_4 },
-	{ 0x86, 0x6b, 0x05, KEY_5 },
-	{ 0x86, 0x6b, 0x06, KEY_6 },
-	{ 0x86, 0x6b, 0x07, KEY_7 },
-	{ 0x86, 0x6b, 0x08, KEY_8 },
-	{ 0x86, 0x6b, 0x09, KEY_9 },
-	{ 0x86, 0x6b, 0x0a, KEY_0 },
-	{ 0x86, 0x6b, 0x18, KEY_ZOOM },
-	{ 0x86, 0x6b, 0x1c, KEY_UNKNOWN }, /* preview */
-	{ 0x86, 0x6b, 0x13, KEY_UNKNOWN }, /* snap */
-	{ 0x86, 0x6b, 0x00, KEY_UNDO },
-	{ 0x86, 0x6b, 0x1d, KEY_RECORD },
-	{ 0x86, 0x6b, 0x0d, KEY_STOP },
-	{ 0x86, 0x6b, 0x0e, KEY_PAUSE },
-	{ 0x86, 0x6b, 0x16, KEY_PLAY },
-	{ 0x86, 0x6b, 0x11, KEY_BACK },
-	{ 0x86, 0x6b, 0x19, KEY_FORWARD },
-	{ 0x86, 0x6b, 0x14, KEY_UNKNOWN }, /* pip */
-	{ 0x86, 0x6b, 0x15, KEY_ESC },
-	{ 0x86, 0x6b, 0x1a, KEY_UP },
-	{ 0x86, 0x6b, 0x1e, KEY_DOWN },
-	{ 0x86, 0x6b, 0x1f, KEY_LEFT },
-	{ 0x86, 0x6b, 0x1b, KEY_RIGHT },
-};
-
-/* Hauppauge NOVA-T USB2 keys */
-static const struct { u16 raw; uint32_t key; } haupp_rc_keys [] = {
-	{ 0xddf, KEY_GOTO },
-	{ 0xdef, KEY_POWER },
-	{ 0xce7, KEY_TV },
-	{ 0xcc7, KEY_VIDEO },
-	{ 0xccf, KEY_AUDIO },
-	{ 0xcd7, KEY_MEDIA },
-	{ 0xcdf, KEY_EPG },
-	{ 0xca7, KEY_UP },
-	{ 0xc67, KEY_RADIO },
-	{ 0xcb7, KEY_LEFT },
-	{ 0xd2f, KEY_OK },
-	{ 0xcbf, KEY_RIGHT },
-	{ 0xcff, KEY_BACK },
-	{ 0xcaf, KEY_DOWN },
-	{ 0xc6f, KEY_MENU },
-	{ 0xc87, KEY_VOLUMEUP },
-	{ 0xc8f, KEY_VOLUMEDOWN },
-	{ 0xc97, KEY_CHANNEL },
-	{ 0xc7f, KEY_MUTE },
-	{ 0xd07, KEY_CHANNELUP },
-	{ 0xd0f, KEY_CHANNELDOWN },
-	{ 0xdbf, KEY_RECORD },
-	{ 0xdb7, KEY_STOP },
-	{ 0xd97, KEY_REWIND },
-	{ 0xdaf, KEY_PLAY },
-	{ 0xda7, KEY_FASTFORWARD },
-	{ 0xd27, KEY_LAST }, /* Skip backwards */
-	{ 0xd87, KEY_PAUSE },
-	{ 0xcf7, KEY_NEXT },
-	{ 0xc07, KEY_0 },
-	{ 0xc0f, KEY_1 },
-	{ 0xc17, KEY_2 },
-	{ 0xc1f, KEY_3 },
-	{ 0xc27, KEY_4 },
-	{ 0xc2f, KEY_5 },
-	{ 0xc37, KEY_6 },
-	{ 0xc3f, KEY_7 },
-	{ 0xc47, KEY_8 },
-	{ 0xc4f, KEY_9 },
-	{ 0xc57, KEY_KPASTERISK },
-	{ 0xc77, KEY_GRAVE }, /* # */
-	{ 0xc5f, KEY_RED },
-	{ 0xd77, KEY_GREEN },
-	{ 0xdc7, KEY_YELLOW },
-	{ 0xd4f, KEY_BLUE},
-};
-
-static int dibusb_key2event_nec(struct usb_dibusb *dib,u8 rb[5])
-{
-	int i;
-	switch (rb[0]) {
-		case DIBUSB_RC_NEC_KEY_PRESSED:
-			/* rb[1-3] is the actual key, rb[4] is a checksum */
-			deb_rc("raw key code 0x%02x, 0x%02x, 0x%02x, 0x%02x\n",
-				rb[1], rb[2], rb[3], rb[4]);
-
-			if ((0xff - rb[3]) != rb[4]) {
-				deb_rc("remote control checksum failed.\n");
-				break;
-			}
-
-			/* See if we can match the raw key code. */
-			for (i = 0; i < sizeof(nec_rc_keys)/sizeof(nec_rc_keys[0]); i++) {
-				if (nec_rc_keys[i].c0 == rb[1] &&
-					nec_rc_keys[i].c1 == rb[2] &&
-					nec_rc_keys[i].c2 == rb[3]) {
-
-					dib->last_event = nec_rc_keys[i].key;
-					return 1;
-				}
-			}
-			break;
-		case DIBUSB_RC_NEC_KEY_REPEATED:
-			/* rb[1]..rb[4] are always zero.*/
-			/* Repeats often seem to occur so for the moment just ignore this. */
-			return 0;
-		case DIBUSB_RC_NEC_EMPTY: /* No (more) remote control keys. */
-		default:
-			break;
-	}
-	return -1;
-}
-
-static int dibusb_key2event_hauppauge(struct usb_dibusb *dib,u8 rb[4])
-{
-	u16 raw;
-	int i,state;
-	switch (rb[0]) {
-		case DIBUSB_RC_HAUPPAUGE_KEY_PRESSED:
-			raw = ((rb[1] & 0x0f) << 8) | rb[2];
-
-			state = !!(rb[1] & 0x40);
-
-			deb_rc("raw key code 0x%02x, 0x%02x, 0x%02x to %04x state: %d\n",rb[1],rb[2],rb[3],raw,state);
-			for (i = 0; i < sizeof(haupp_rc_keys)/sizeof(haupp_rc_keys[0]); i++) {
-				if (haupp_rc_keys[i].raw == raw) {
-					if (dib->last_event == haupp_rc_keys[i].key &&
-						dib->last_state == state) {
-						deb_rc("key repeat\n");
-						return 0;
-					} else {
-						dib->last_event = haupp_rc_keys[i].key;
-						dib->last_state = state;
-						return 1;
-					}
-				}
-			}
-
-			break;
-		case DIBUSB_RC_HAUPPAUGE_KEY_EMPTY:
-		default:
-			break;
-	}
-	return -1;
-}
-
-/*
- * Read the remote control and feed the appropriate event.
- * NEC protocol is used for remote controls
- */
-static int dibusb_read_remote_control(struct usb_dibusb *dib)
-{
-	u8 b[1] = { DIBUSB_REQ_POLL_REMOTE }, rb[5];
-	int ret,event = 0;
-
-	if ((ret = dibusb_readwrite_usb(dib,b,1,rb,5)))
-		return ret;
-
-	switch (dib->dibdev->dev_cl->remote_type) {
-		case DIBUSB_RC_NEC_PROTOCOL:
-			event = dibusb_key2event_nec(dib,rb);
-			break;
-		case DIBUSB_RC_HAUPPAUGE_PROTO:
-			event = dibusb_key2event_hauppauge(dib,rb);
-		default:
-			break;
-	}
-
-	/* key repeat */
-	if (event == 0)
-		if (++dib->repeat_key_count < dib->rc_key_repeat_count) {
-			deb_rc("key repeat dropped. (%d)\n",dib->repeat_key_count);
-			event = -1; /* skip this key repeat */
-		}
-
-	if (event == 1 || event == 0) {
-		deb_rc("Translated key 0x%04x\n",event);
-
-		/* Signal down and up events for this key. */
-		input_report_key(&dib->rc_input_dev, dib->last_event, 1);
-		input_report_key(&dib->rc_input_dev, dib->last_event, 0);
-		input_sync(&dib->rc_input_dev);
-
-		if (event == 1)
-			dib->repeat_key_count = 0;
-	}
-	return 0;
-}
-
-/* Remote-control poll function - called every dib->rc_query_interval ms to see
-   whether the remote control has received anything. */
-static void dibusb_remote_query(void *data)
-{
-	struct usb_dibusb *dib = (struct usb_dibusb *) data;
-	/* TODO: need a lock here.  We can simply skip checking for the remote control
-	   if we're busy. */
-	dibusb_read_remote_control(dib);
-	schedule_delayed_work(&dib->rc_query_work,
-			      msecs_to_jiffies(dib->rc_query_interval));
-}
-
-int dibusb_remote_init(struct usb_dibusb *dib)
-{
-	int i;
-
-	if (dib->dibdev->dev_cl->remote_type == DIBUSB_RC_NO)
-		return 0;
-	
-	/* Initialise the remote-control structures.*/
-	init_input_dev(&dib->rc_input_dev);
-
-	dib->rc_input_dev.evbit[0] = BIT(EV_KEY);
-	dib->rc_input_dev.keycodesize = sizeof(unsigned char);
-	dib->rc_input_dev.keycodemax = KEY_MAX;
-	dib->rc_input_dev.name = DRIVER_DESC " remote control";
-
-	switch (dib->dibdev->dev_cl->remote_type) {
-		case DIBUSB_RC_NEC_PROTOCOL:
-			for (i=0; i<sizeof(nec_rc_keys)/sizeof(nec_rc_keys[0]); i++)
-				set_bit(nec_rc_keys[i].key, dib->rc_input_dev.keybit);
-			break;
-		case DIBUSB_RC_HAUPPAUGE_PROTO:
-			for (i=0; i<sizeof(haupp_rc_keys)/sizeof(haupp_rc_keys[0]); i++)
-				set_bit(haupp_rc_keys[i].key, dib->rc_input_dev.keybit);
-			break;
-		default:
-			break;
-	}
-
-
-	input_register_device(&dib->rc_input_dev);
-
-	INIT_WORK(&dib->rc_query_work, dibusb_remote_query, dib);
-
-	/* Start the remote-control polling. */
-	if (dib->rc_query_interval < 40)
-		dib->rc_query_interval = 100; /* default */
-
-	info("schedule remote query interval to %d msecs.",dib->rc_query_interval);
-	schedule_delayed_work(&dib->rc_query_work,msecs_to_jiffies(dib->rc_query_interval));
-
-	dib->init_state |= DIBUSB_STATE_REMOTE;
-	
-	return 0;
-}
-
-int dibusb_remote_exit(struct usb_dibusb *dib)
-{
-	if (dib->dibdev->dev_cl->remote_type == DIBUSB_RC_NO)
-		return 0;
-
-	if (dib->init_state & DIBUSB_STATE_REMOTE) {
-		cancel_delayed_work(&dib->rc_query_work);
-		flush_scheduled_work();
-		input_unregister_device(&dib->rc_input_dev);
-	}
-	dib->init_state &= ~DIBUSB_STATE_REMOTE;
-	return 0;
-}
diff --git a/drivers/media/dvb/dibusb/dvb-dibusb-usb.c b/drivers/media/dvb/dibusb/dvb-dibusb-usb.c
deleted file mode 100644
--- a/drivers/media/dvb/dibusb/dvb-dibusb-usb.c
+++ /dev/null
@@ -1,303 +0,0 @@
-/*
- * dvb-dibusb-usb.c is part of the driver for mobile USB Budget DVB-T devices
- * based on reference design made by DiBcom (http://www.dibcom.fr/)
- *
- * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
- *
- * see dvb-dibusb-core.c for more copyright details.
- *
- * This file contains functions for initializing and handling the
- * usb specific stuff.
- */
-#include "dvb-dibusb.h"
-
-#include <linux/version.h>
-#include <linux/pci.h>
-
-int dibusb_readwrite_usb(struct usb_dibusb *dib, u8 *wbuf, u16 wlen, u8 *rbuf,
-		u16 rlen)
-{
-	int actlen,ret = -ENOMEM;
-
-	if (wbuf == NULL || wlen == 0)
-		return -EINVAL;
-
-	if ((ret = down_interruptible(&dib->usb_sem)))
-		return ret;
-
-	debug_dump(wbuf,wlen);
-
-	ret = usb_bulk_msg(dib->udev,usb_sndbulkpipe(dib->udev,
-			dib->dibdev->dev_cl->pipe_cmd), wbuf,wlen,&actlen,
-			DIBUSB_I2C_TIMEOUT);
-
-	if (ret)
-		err("bulk message failed: %d (%d/%d)",ret,wlen,actlen);
-	else
-		ret = actlen != wlen ? -1 : 0;
-
-	/* an answer is expected, and no error before */
-	if (!ret && rbuf && rlen) {
-		ret = usb_bulk_msg(dib->udev,usb_rcvbulkpipe(dib->udev,
-				dib->dibdev->dev_cl->pipe_cmd),rbuf,rlen,&actlen,
-				DIBUSB_I2C_TIMEOUT);
-
-		if (ret)
-			err("recv bulk message failed: %d",ret);
-		else {
-			deb_alot("rlen: %d\n",rlen);
-			debug_dump(rbuf,actlen);
-		}
-	}
-
-	up(&dib->usb_sem);
-	return ret;
-}
-
-/*
- * Cypress controls
- */
-int dibusb_write_usb(struct usb_dibusb *dib, u8 *buf, u16 len)
-{
-	return dibusb_readwrite_usb(dib,buf,len,NULL,0);
-}
-
-#if 0
-/*
- * #if 0'ing the following functions as they are not in use _now_,
- * but probably will be sometime.
- */
-/*
- * do not use this, just a workaround for a bug,
- * which will hopefully never occur :).
- */
-int dibusb_interrupt_read_loop(struct usb_dibusb *dib)
-{
-	u8 b[1] = { DIBUSB_REQ_INTR_READ };
-	return dibusb_write_usb(dib,b,1);
-}
-#endif
-
-/*
- * ioctl for the firmware
- */
-static int dibusb_ioctl_cmd(struct usb_dibusb *dib, u8 cmd, u8 *param, int plen)
-{
-	u8 b[34];
-	int size = plen > 32 ? 32 : plen;
-	memset(b,0,34);
-	b[0] = DIBUSB_REQ_SET_IOCTL;
-	b[1] = cmd;
-
-	if (size > 0)
-		memcpy(&b[2],param,size);
-
-	return dibusb_write_usb(dib,b,34); //2+size);
-}
-
-/*
- * ioctl for power control
- */
-int dibusb_hw_wakeup(struct dvb_frontend *fe)
-{
-	struct usb_dibusb *dib = (struct usb_dibusb *) fe->dvb->priv;
-	u8 b[1] = { DIBUSB_IOCTL_POWER_WAKEUP };
-	deb_info("dibusb-device is getting up.\n");
-
-	switch (dib->dibdev->dev_cl->id) {
-		case DTT200U:
-			break;
-		default:
-			dibusb_ioctl_cmd(dib,DIBUSB_IOCTL_CMD_POWER_MODE, b,1);
-			break;
-	}
-
-	if (dib->fe_init)
-		return dib->fe_init(fe);
-
-	return 0;
-}
-
-int dibusb_hw_sleep(struct dvb_frontend *fe)
-{
-	struct usb_dibusb *dib = (struct usb_dibusb *) fe->dvb->priv;
-	u8 b[1] = { DIBUSB_IOCTL_POWER_SLEEP };
-	deb_info("dibusb-device is going to bed.\n");
-	/* workaround, something is wrong, when dibusb 1.1 device are going to bed too late */
-	switch (dib->dibdev->dev_cl->id) {
-		case DIBUSB1_1:
-		case NOVAT_USB2:
-		case DTT200U:
-			break;
-		default:
-			dibusb_ioctl_cmd(dib,DIBUSB_IOCTL_CMD_POWER_MODE, b,1);
-			break;
-	}
-	if (dib->fe_sleep)
-		return dib->fe_sleep(fe);
-
-	return 0;
-}
-
-int dibusb_set_streaming_mode(struct usb_dibusb *dib,u8 mode)
-{
-	u8 b[2] = { DIBUSB_REQ_SET_STREAMING_MODE, mode };
-	return dibusb_readwrite_usb(dib,b,2,NULL,0);
-}
-
-static int dibusb_urb_kill(struct usb_dibusb *dib)
-{
-	int i;
-deb_info("trying to kill urbs\n");
-	if (dib->init_state & DIBUSB_STATE_URB_SUBMIT) {
-		for (i = 0; i < dib->dibdev->dev_cl->urb_count; i++) {
-			deb_info("killing URB no. %d.\n",i);
-
-			/* stop the URB */
-			usb_kill_urb(dib->urb_list[i]);
-		}
-	} else
-	deb_info(" URBs not killed.\n");
-	dib->init_state &= ~DIBUSB_STATE_URB_SUBMIT;
-	return 0;
-}
-
-static int dibusb_urb_submit(struct usb_dibusb *dib)
-{
-	int i,ret;
-	if (dib->init_state & DIBUSB_STATE_URB_INIT) {
-		for (i = 0; i < dib->dibdev->dev_cl->urb_count; i++) {
-			deb_info("submitting URB no. %d\n",i);
-			if ((ret = usb_submit_urb(dib->urb_list[i],GFP_ATOMIC))) {
-				err("could not submit buffer urb no. %d - get them all back\n",i);
-				dibusb_urb_kill(dib);
-				return ret;
-			}
-			dib->init_state |= DIBUSB_STATE_URB_SUBMIT;
-		}
-	}
-	return 0;
-}
-
-int dibusb_streaming(struct usb_dibusb *dib,int onoff)
-{
-	if (onoff)
-		dibusb_urb_submit(dib);
-	else
-		dibusb_urb_kill(dib);
-
-	switch (dib->dibdev->dev_cl->id) {
-		case DIBUSB2_0:
-		case DIBUSB2_0B:
-		case NOVAT_USB2:
-		case UMT2_0:
-			if (onoff)
-				return dibusb_ioctl_cmd(dib,DIBUSB_IOCTL_CMD_ENABLE_STREAM,NULL,0);
-			else
-				return dibusb_ioctl_cmd(dib,DIBUSB_IOCTL_CMD_DISABLE_STREAM,NULL,0);
-			break;
-		default:
-			break;
-	}
-	return 0;
-}
-
-int dibusb_urb_init(struct usb_dibusb *dib)
-{
-	int i,bufsize,def_pid_parse = 1;
-
-	/*
-	 * when reloading the driver w/o replugging the device
-	 * a timeout occures, this helps
-	 */
-	usb_clear_halt(dib->udev,usb_sndbulkpipe(dib->udev,dib->dibdev->dev_cl->pipe_cmd));
-	usb_clear_halt(dib->udev,usb_rcvbulkpipe(dib->udev,dib->dibdev->dev_cl->pipe_cmd));
-	usb_clear_halt(dib->udev,usb_rcvbulkpipe(dib->udev,dib->dibdev->dev_cl->pipe_data));
-
-	/* allocate the array for the data transfer URBs */
-	dib->urb_list = kmalloc(dib->dibdev->dev_cl->urb_count*sizeof(struct urb *),GFP_KERNEL);
-	if (dib->urb_list == NULL)
-		return -ENOMEM;
-	memset(dib->urb_list,0,dib->dibdev->dev_cl->urb_count*sizeof(struct urb *));
-
-	dib->init_state |= DIBUSB_STATE_URB_LIST;
-
-	bufsize = dib->dibdev->dev_cl->urb_count*dib->dibdev->dev_cl->urb_buffer_size;
-	deb_info("allocate %d bytes as buffersize for all URBs\n",bufsize);
-	/* allocate the actual buffer for the URBs */
-	if ((dib->buffer = pci_alloc_consistent(NULL,bufsize,&dib->dma_handle)) == NULL) {
-		deb_info("not enough memory.\n");
-		return -ENOMEM;
-	}
-	deb_info("allocation complete\n");
-	memset(dib->buffer,0,bufsize);
-
-	dib->init_state |= DIBUSB_STATE_URB_BUF;
-
-	/* allocate and submit the URBs */
-	for (i = 0; i < dib->dibdev->dev_cl->urb_count; i++) {
-		if (!(dib->urb_list[i] = usb_alloc_urb(0,GFP_ATOMIC))) {
-			return -ENOMEM;
-		}
-
-		usb_fill_bulk_urb( dib->urb_list[i], dib->udev,
-				usb_rcvbulkpipe(dib->udev,dib->dibdev->dev_cl->pipe_data),
-				&dib->buffer[i*dib->dibdev->dev_cl->urb_buffer_size],
-				dib->dibdev->dev_cl->urb_buffer_size,
-				dibusb_urb_complete, dib);
-
-		dib->urb_list[i]->transfer_flags = 0;
-
-		dib->init_state |= DIBUSB_STATE_URB_INIT;
-	}
-
-	/* dib->pid_parse here contains the value of the module parameter */
-	/* decide if pid parsing can be deactivated:
-	 * is possible (by device type) and wanted (by user)
-	 */
-	switch (dib->dibdev->dev_cl->id) {
-		case DIBUSB2_0:
-		case DIBUSB2_0B:
-			if (dib->udev->speed == USB_SPEED_HIGH && !dib->pid_parse) {
-				def_pid_parse = 0;
-				info("running at HIGH speed, will deliver the complete TS.");
-			} else
-				info("will use pid_parsing.");
-			break;
-		default:
-			break;
-	}
-	/* from here on it contains the device and user decision */
-	dib->pid_parse = def_pid_parse;
-
-	return 0;
-}
-
-int dibusb_urb_exit(struct usb_dibusb *dib)
-{
-	int i;
-
-	dibusb_urb_kill(dib);
-
-	if (dib->init_state & DIBUSB_STATE_URB_LIST) {
-		for (i = 0; i < dib->dibdev->dev_cl->urb_count; i++) {
-			if (dib->urb_list[i] != NULL) {
-				deb_info("freeing URB no. %d.\n",i);
-				/* free the URBs */
-				usb_free_urb(dib->urb_list[i]);
-			}
-		}
-		/* free the urb array */
-		kfree(dib->urb_list);
-		dib->init_state &= ~DIBUSB_STATE_URB_LIST;
-	}
-
-	if (dib->init_state & DIBUSB_STATE_URB_BUF)
-		pci_free_consistent(NULL,
-			dib->dibdev->dev_cl->urb_buffer_size*dib->dibdev->dev_cl->urb_count,
-			dib->buffer,dib->dma_handle);
-
-	dib->init_state &= ~DIBUSB_STATE_URB_BUF;
-	dib->init_state &= ~DIBUSB_STATE_URB_INIT;
-	return 0;
-}
diff --git a/drivers/media/dvb/dibusb/dvb-dibusb.h b/drivers/media/dvb/dibusb/dvb-dibusb.h
deleted file mode 100644
--- a/drivers/media/dvb/dibusb/dvb-dibusb.h
+++ /dev/null
@@ -1,327 +0,0 @@
-/*
- * dvb-dibusb.h
- *
- * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
- *
- *	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, version 2.
- *
- * for more information see dvb-dibusb-core.c .
- */
-#ifndef __DVB_DIBUSB_H__
-#define __DVB_DIBUSB_H__
-
-#include <linux/input.h>
-#include <linux/config.h>
-#include <linux/usb.h>
-
-#include "dvb_frontend.h"
-#include "dvb_demux.h"
-#include "dvb_net.h"
-#include "dmxdev.h"
-
-#include "dib3000.h"
-#include "mt352.h"
-
-/* debug */
-#ifdef CONFIG_DVB_DIBCOM_DEBUG
-#define dprintk(level,args...) \
-	    do { if ((dvb_dibusb_debug & level)) { printk(args); } } while (0)
-
-#define debug_dump(b,l) {\
-	int i; \
-	for (i = 0; i < l; i++) deb_xfer("%02x ", b[i]); \
-	deb_xfer("\n");\
-}
-
-#else
-#define dprintk(args...)
-#define debug_dump(b,l)
-#endif
-
-extern int dvb_dibusb_debug;
-
-/* Version information */
-#define DRIVER_VERSION "0.3"
-#define DRIVER_DESC "DiBcom based USB Budget DVB-T device"
-#define DRIVER_AUTHOR "Patrick Boettcher, patrick.boettcher@desy.de"
-
-#define deb_info(args...) dprintk(0x01,args)
-#define deb_xfer(args...) dprintk(0x02,args)
-#define deb_alot(args...) dprintk(0x04,args)
-#define deb_ts(args...)   dprintk(0x08,args)
-#define deb_err(args...)  dprintk(0x10,args)
-#define deb_rc(args...)   dprintk(0x20,args)
-
-/* generic log methods - taken from usb.h */
-#undef err
-#define err(format, arg...)  printk(KERN_ERR     "dvb-dibusb: " format "\n" , ## arg)
-#undef info
-#define info(format, arg...) printk(KERN_INFO    "dvb-dibusb: " format "\n" , ## arg)
-#undef warn
-#define warn(format, arg...) printk(KERN_WARNING "dvb-dibusb: " format "\n" , ## arg)
-
-struct dibusb_usb_controller {
-	const char *name;       /* name of the usb controller */
-	u16 cpu_cs_register;    /* needs to be restarted, when the firmware has been downloaded. */
-};
-
-typedef enum {
-	DIBUSB1_1 = 0,
-	DIBUSB1_1_AN2235,
-	DIBUSB2_0,
-	UMT2_0,
-	DIBUSB2_0B,
-	NOVAT_USB2,
-	DTT200U,
-} dibusb_class_t;
-
-typedef enum {
-	DIBUSB_TUNER_CABLE_THOMSON = 0,
-	DIBUSB_TUNER_COFDM_PANASONIC_ENV57H1XD5,
-	DIBUSB_TUNER_CABLE_LG_TDTP_E102P,
-	DIBUSB_TUNER_COFDM_PANASONIC_ENV77H11D5,
-} dibusb_tuner_t;
-
-typedef enum {
-	DIBUSB_DIB3000MB = 0,
-	DIBUSB_DIB3000MC,
-	DIBUSB_MT352,
-	DTT200U_FE,
-} dibusb_demodulator_t;
-
-typedef enum {
-	DIBUSB_RC_NO = 0,
-	DIBUSB_RC_NEC_PROTOCOL,
-	DIBUSB_RC_HAUPPAUGE_PROTO,
-} dibusb_remote_t;
-
-struct dibusb_tuner {
-	dibusb_tuner_t id;
-
-	u8 pll_addr;       /* tuner i2c address */
-};
-extern struct dibusb_tuner dibusb_tuner[];
-
-#define DIBUSB_POSSIBLE_I2C_ADDR_NUM 4
-struct dibusb_demod {
-	dibusb_demodulator_t id;
-
-	int pid_filter_count;                       /* counter of the internal pid_filter */
-	u8 i2c_addrs[DIBUSB_POSSIBLE_I2C_ADDR_NUM]; /* list of possible i2c addresses of the demod */
-};
-
-#define DIBUSB_MAX_TUNER_NUM 2
-struct dibusb_device_class {
-	dibusb_class_t id;
-
-	const struct dibusb_usb_controller *usb_ctrl; /* usb controller */
-	const char *firmware;                         /* valid firmware filenames */
-
-	int pipe_cmd;                                 /* command pipe (read/write) */
-	int pipe_data;                                /* data pipe */
-
-	int urb_count;                                /* number of data URBs to be submitted */
-	int urb_buffer_size;                          /* the size of the buffer for each URB */
-
-	dibusb_remote_t remote_type;                  /* does this device have a ir-receiver */
-
-	struct dibusb_demod *demod;                   /* which demodulator is mount */
-	struct dibusb_tuner *tuner;                   /* which tuner can be found here */
-};
-
-#define DIBUSB_ID_MAX_NUM 15
-struct dibusb_usb_device {
-	const char *name;                                 /* real name of the box */
-	struct dibusb_device_class *dev_cl;               /* which dibusb_device_class is this device part of */
-
-	struct usb_device_id *cold_ids[DIBUSB_ID_MAX_NUM]; /* list of USB ids when this device is at pre firmware state */
-	struct usb_device_id *warm_ids[DIBUSB_ID_MAX_NUM]; /* list of USB ids when this device is at post firmware state */
-};
-
-/* a PID for the pid_filter list, when in use */
-struct dibusb_pid
-{
-	int index;
-	u16 pid;
-	int active;
-};
-
-struct usb_dibusb {
-	/* usb */
-	struct usb_device * udev;
-
-	struct dibusb_usb_device * dibdev;
-
-#define DIBUSB_STATE_INIT       0x000
-#define DIBUSB_STATE_URB_LIST   0x001
-#define DIBUSB_STATE_URB_BUF    0x002
-#define DIBUSB_STATE_URB_INIT	0x004
-#define DIBUSB_STATE_DVB        0x008
-#define DIBUSB_STATE_I2C        0x010
-#define DIBUSB_STATE_REMOTE		0x020
-#define DIBUSB_STATE_URB_SUBMIT 0x040
-	int init_state;
-
-	int feedcount;
-	struct dib_fe_xfer_ops xfer_ops;
-
-	struct dibusb_tuner *tuner;
-
-	struct urb **urb_list;
-	u8 *buffer;
-	dma_addr_t dma_handle;
-
-	/* I2C */
-	struct i2c_adapter i2c_adap;
-
-	/* locking */
-	struct semaphore usb_sem;
-	struct semaphore i2c_sem;
-
-	/* dvb */
-	struct dvb_adapter adapter;
-	struct dmxdev dmxdev;
-	struct dvb_demux demux;
-	struct dvb_net dvb_net;
-	struct dvb_frontend* fe;
-
-	int (*fe_sleep) (struct dvb_frontend *);
-	int (*fe_init) (struct dvb_frontend *);
-
-	/* remote control */
-	struct input_dev rc_input_dev;
-	struct work_struct rc_query_work;
-	int last_event;
-	int last_state; /* for Hauppauge RC protocol */
-	int repeat_key_count;
-	int rc_key_repeat_count; /* module parameter */
-
-	/* module parameters */
-	int pid_parse;
-	int rc_query_interval;
-};
-
-/* commonly used functions in the separated files */
-
-/* dvb-dibusb-firmware.c */
-int dibusb_loadfirmware(struct usb_device *udev, struct dibusb_usb_device *dibdev);
-
-/* dvb-dibusb-remote.c */
-int dibusb_remote_exit(struct usb_dibusb *dib);
-int dibusb_remote_init(struct usb_dibusb *dib);
-
-/* dvb-dibusb-fe-i2c.c */
-int dibusb_fe_init(struct usb_dibusb* dib);
-int dibusb_fe_exit(struct usb_dibusb *dib);
-int dibusb_i2c_init(struct usb_dibusb *dib);
-int dibusb_i2c_exit(struct usb_dibusb *dib);
-
-/* dvb-dibusb-dvb.c */
-void dibusb_urb_complete(struct urb *urb, struct pt_regs *ptregs);
-int dibusb_dvb_init(struct usb_dibusb *dib);
-int dibusb_dvb_exit(struct usb_dibusb *dib);
-
-/* dvb-dibusb-usb.c */
-int dibusb_readwrite_usb(struct usb_dibusb *dib, u8 *wbuf, u16 wlen, u8 *rbuf,
-	u16 rlen);
-int dibusb_write_usb(struct usb_dibusb *dib, u8 *buf, u16 len);
-
-int dibusb_hw_wakeup(struct dvb_frontend *);
-int dibusb_hw_sleep(struct dvb_frontend *);
-int dibusb_set_streaming_mode(struct usb_dibusb *,u8);
-int dibusb_streaming(struct usb_dibusb *,int);
-
-int dibusb_urb_init(struct usb_dibusb *);
-int dibusb_urb_exit(struct usb_dibusb *);
-
-/* dvb-fe-dtt200u.c */
-struct dvb_frontend* dtt200u_fe_attach(struct usb_dibusb *,struct dib_fe_xfer_ops *);
-
-/* i2c and transfer stuff */
-#define DIBUSB_I2C_TIMEOUT				5000
-
-/*
- * protocol of all dibusb related devices
- */
-
-/*
- * bulk msg to/from endpoint 0x01
- *
- * general structure:
- * request_byte parameter_bytes
- */
-
-#define DIBUSB_REQ_START_READ			0x00
-#define DIBUSB_REQ_START_DEMOD			0x01
-
-/*
- * i2c read
- * bulk write: 0x02 ((7bit i2c_addr << 1) & 0x01) register_bytes length_word
- * bulk read:  byte_buffer (length_word bytes)
- */
-#define DIBUSB_REQ_I2C_READ			0x02
-
-/*
- * i2c write
- * bulk write: 0x03 (7bit i2c_addr << 1) register_bytes value_bytes
- */
-#define DIBUSB_REQ_I2C_WRITE			0x03
-
-/*
- * polling the value of the remote control
- * bulk write: 0x04
- * bulk read:  byte_buffer (5 bytes)
- *
- * first byte of byte_buffer shows the status (0x00, 0x01, 0x02)
- */
-#define DIBUSB_REQ_POLL_REMOTE			0x04
-
-#define DIBUSB_RC_NEC_EMPTY				0x00
-#define DIBUSB_RC_NEC_KEY_PRESSED		0x01
-#define DIBUSB_RC_NEC_KEY_REPEATED		0x02
-
-/* additional status values for Hauppauge Remote Control Protocol */
-#define DIBUSB_RC_HAUPPAUGE_KEY_PRESSED	0x01
-#define DIBUSB_RC_HAUPPAUGE_KEY_EMPTY	0x03
-
-/* streaming mode:
- * bulk write: 0x05 mode_byte
- *
- * mode_byte is mostly 0x00
- */
-#define DIBUSB_REQ_SET_STREAMING_MODE	0x05
-
-/* interrupt the internal read loop, when blocking */
-#define DIBUSB_REQ_INTR_READ			0x06
-
-/* io control
- * 0x07 cmd_byte param_bytes
- *
- * param_bytes can be up to 32 bytes
- *
- * cmd_byte function    parameter name
- * 0x00     power mode
- *                      0x00      sleep
- *                      0x01      wakeup
- *
- * 0x01     enable streaming
- * 0x02     disable streaming
- *
- *
- */
-#define DIBUSB_REQ_SET_IOCTL			0x07
-
-/* IOCTL commands */
-
-/* change the power mode in firmware */
-#define DIBUSB_IOCTL_CMD_POWER_MODE		0x00
-#define DIBUSB_IOCTL_POWER_SLEEP			0x00
-#define DIBUSB_IOCTL_POWER_WAKEUP			0x01
-
-/* modify streaming of the FX2 */
-#define DIBUSB_IOCTL_CMD_ENABLE_STREAM	0x01
-#define DIBUSB_IOCTL_CMD_DISABLE_STREAM	0x02
-
-#endif
diff --git a/drivers/media/dvb/dibusb/dvb-fe-dtt200u.c b/drivers/media/dvb/dibusb/dvb-fe-dtt200u.c
deleted file mode 100644
--- a/drivers/media/dvb/dibusb/dvb-fe-dtt200u.c
+++ /dev/null
@@ -1,263 +0,0 @@
-/*
- * dvb-dtt200u-fe.c is a driver which implements the frontend-part of the
- * Yakumo/Typhoon/Hama USB2.0 boxes. It is hard-wired to the dibusb-driver as
- * it uses the usb-transfer functions directly (maybe creating a
- * generic-dvb-usb-lib for all usb-drivers will be reduce some more code.)
- *
- * Copyright (C) 2005 Patrick Boettcher <patrick.boettcher@desy.de>
- *
- * see dvb-dibusb-core.c for copyright details.
- */
-
-/* guessed protocol description (reverse engineered):
- * read
- *  00 - USB type 0x02 for usb2.0, 0x01 for usb1.1
- *  81 - <TS_LOCK> <current frequency divided by 250000>
- *  82 - crash - do not touch
- *  83 - crash - do not touch
- *  84 - remote control
- *  85 - crash - do not touch (OK, stop testing here)
- *  88 - locking 2 bytes (0x80 0x40 == no signal, 0x89 0x20 == nice signal)
- *  89 - noise-to-signal
- *	8a - unkown 1 byte - signal_strength
- *  8c - ber ???
- *  8d - ber
- *  8e - unc
- *
- * write
- *  02 - bandwidth
- *  03 - frequency (divided by 250000)
- *  04 - pid table (index pid(7:0) pid(12:8))
- *  05 - reset the pid table
- *  08 - demod transfer enabled or not (FX2 transfer is enabled by default)
- */
-
-#include "dvb-dibusb.h"
-#include "dvb_frontend.h"
-
-struct dtt200u_fe_state {
-	struct usb_dibusb *dib;
-
-	struct dvb_frontend_parameters fep;
-	struct dvb_frontend frontend;
-};
-
-#define moan(which,what) info("unexpected value in '%s' for cmd '%02x' - please report to linux-dvb@linuxtv.org",which,what)
-
-static int dtt200u_fe_read_status(struct dvb_frontend* fe, fe_status_t *stat)
-{
-	struct dtt200u_fe_state *state = fe->demodulator_priv;
-	u8 bw[1] = { 0x81 };
-	u8 br[3] = { 0 };
-//	u8 bdeb[5] = { 0 };
-
-	dibusb_readwrite_usb(state->dib,bw,1,br,3);
-	switch (br[0]) {
-		case 0x01:
-			*stat = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
-			break;
-		case 0x00:
-			*stat = 0;
-			break;
-		default:
-			moan("br[0]",0x81);
-			break;
-	}
-
-//	bw[0] = 0x88;
-//	dibusb_readwrite_usb(state->dib,bw,1,bdeb,5);
-
-//	deb_info("%02x: %02x %02x %02x %02x %02x\n",bw[0],bdeb[0],bdeb[1],bdeb[2],bdeb[3],bdeb[4]);
-
-	return 0;
-}
-static int dtt200u_fe_read_ber(struct dvb_frontend* fe, u32 *ber)
-{
-	struct dtt200u_fe_state *state = fe->demodulator_priv;
-	u8 bw[1] = { 0x8d };
-	*ber = 0;
-	dibusb_readwrite_usb(state->dib,bw,1,(u8*) ber, 3);
-	return 0;
-}
-
-static int dtt200u_fe_read_unc_blocks(struct dvb_frontend* fe, u32 *unc)
-{
-	struct dtt200u_fe_state *state = fe->demodulator_priv;
-	u8 bw[1] = { 0x8c };
-	*unc = 0;
-	dibusb_readwrite_usb(state->dib,bw,1,(u8*) unc, 3);
-	return 0;
-}
-
-static int dtt200u_fe_read_signal_strength(struct dvb_frontend* fe, u16 *strength)
-{
-	struct dtt200u_fe_state *state = fe->demodulator_priv;
-	u8 bw[1] = { 0x8a };
-	u8 b;
-	dibusb_readwrite_usb(state->dib,bw,1,&b, 1);
-	*strength = (b << 8) | b;
-	return 0;
-}
-
-static int dtt200u_fe_read_snr(struct dvb_frontend* fe, u16 *snr)
-{
-	struct dtt200u_fe_state *state = fe->demodulator_priv;
-	u8 bw[1] = { 0x89 };
-	u8 br[1] = { 0 };
-	dibusb_readwrite_usb(state->dib,bw,1,br,1);
-	*snr = ((0xff - br[0]) << 8) | (0xff - br[0]);
-	return 0;
-}
-
-static int dtt200u_fe_init(struct dvb_frontend* fe)
-{
-	struct dtt200u_fe_state *state = fe->demodulator_priv;
-	u8 b[] = { 0x01 };
-	return dibusb_write_usb(state->dib,b,1);
-}
-
-static int dtt200u_fe_sleep(struct dvb_frontend* fe)
-{
-	return dtt200u_fe_init(fe);
-}
-
-static int dtt200u_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
-{
-	tune->min_delay_ms = 1500;
-	tune->step_size = 166667;
-	tune->max_drift = 166667 * 2;
-	return 0;
-}
-
-static int dtt200u_fe_set_frontend(struct dvb_frontend* fe,
-				  struct dvb_frontend_parameters *fep)
-{
-	struct dtt200u_fe_state *state = fe->demodulator_priv;
-	u16 freq = fep->frequency / 250000;
-	u8 bw,bwbuf[2] = { 0x03, 0 }, freqbuf[3] = { 0x02, 0, 0 };
-
-	switch (fep->u.ofdm.bandwidth) {
-		case BANDWIDTH_8_MHZ: bw = 8; break;
-		case BANDWIDTH_7_MHZ: bw = 7; break;
-		case BANDWIDTH_6_MHZ: bw = 6; break;
-		case BANDWIDTH_AUTO: return -EOPNOTSUPP;
-		default:
-			return -EINVAL;
-	}
-	deb_info("set_frontend\n");
-
-	bwbuf[1] = bw;
-	dibusb_write_usb(state->dib,bwbuf,2);
-
-	freqbuf[1] = freq & 0xff;
-	freqbuf[2] = (freq >> 8) & 0xff;
-	dibusb_write_usb(state->dib,freqbuf,3);
-
-	memcpy(&state->fep,fep,sizeof(struct dvb_frontend_parameters));
-
-	return 0;
-}
-
-static int dtt200u_fe_get_frontend(struct dvb_frontend* fe,
-				  struct dvb_frontend_parameters *fep)
-{
-	struct dtt200u_fe_state *state = fe->demodulator_priv;
-	memcpy(fep,&state->fep,sizeof(struct dvb_frontend_parameters));
-	return 0;
-}
-
-static void dtt200u_fe_release(struct dvb_frontend* fe)
-{
-	struct dtt200u_fe_state *state = (struct dtt200u_fe_state*) fe->demodulator_priv;
-	kfree(state);
-}
-
-static int dtt200u_pid_control(struct dvb_frontend *fe,int index, int pid,int onoff)
-{
-	struct dtt200u_fe_state *state = (struct dtt200u_fe_state*) fe->demodulator_priv;
-	u8 b_pid[4];
-	pid = onoff ? pid : 0;
-
-	b_pid[0] = 0x04;
-	b_pid[1] = index;
-	b_pid[2] = pid & 0xff;
-	b_pid[3] = (pid >> 8) & 0xff;
-
-	dibusb_write_usb(state->dib,b_pid,4);
-	return 0;
-}
-
-static int dtt200u_fifo_control(struct dvb_frontend *fe, int onoff)
-{
-	struct dtt200u_fe_state *state = (struct dtt200u_fe_state*) fe->demodulator_priv;
-	u8 b_streaming[2] = { 0x08, onoff };
-	u8 b_rst_pid[1] = { 0x05 };
-
-	dibusb_write_usb(state->dib,b_streaming,2);
-
-	if (!onoff)
-		dibusb_write_usb(state->dib,b_rst_pid,1);
-	return 0;
-}
-
-static struct dvb_frontend_ops dtt200u_fe_ops;
-
-struct dvb_frontend* dtt200u_fe_attach(struct usb_dibusb *dib, struct dib_fe_xfer_ops *xfer_ops)
-{
-	struct dtt200u_fe_state* state = NULL;
-
-	/* allocate memory for the internal state */
-	state = (struct dtt200u_fe_state*) kmalloc(sizeof(struct dtt200u_fe_state), GFP_KERNEL);
-	if (state == NULL)
-		goto error;
-	memset(state,0,sizeof(struct dtt200u_fe_state));
-
-	deb_info("attaching frontend dtt200u\n");
-
-	state->dib = dib;
-
-	state->frontend.ops = &dtt200u_fe_ops;
-	state->frontend.demodulator_priv = state;
-
-	xfer_ops->fifo_ctrl = dtt200u_fifo_control;
-	xfer_ops->pid_ctrl = dtt200u_pid_control;
-
-	goto success;
-error:
-	return NULL;
-success:
-	return &state->frontend;
-}
-
-static struct dvb_frontend_ops dtt200u_fe_ops = {
-	.info = {
-		.name			= "DTT200U (Yakumo/Typhoon/Hama) DVB-T",
-		.type			= FE_OFDM,
-		.frequency_min		= 44250000,
-		.frequency_max		= 867250000,
-		.frequency_stepsize	= 250000,
-		.caps = FE_CAN_INVERSION_AUTO |
-				FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
-				FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
-				FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
-				FE_CAN_TRANSMISSION_MODE_AUTO |
-				FE_CAN_GUARD_INTERVAL_AUTO |
-				FE_CAN_RECOVER |
-				FE_CAN_HIERARCHY_AUTO,
-	},
-
-	.release = dtt200u_fe_release,
-
-	.init = dtt200u_fe_init,
-	.sleep = dtt200u_fe_sleep,
-
-	.set_frontend = dtt200u_fe_set_frontend,
-	.get_frontend = dtt200u_fe_get_frontend,
-	.get_tune_settings = dtt200u_fe_get_tune_settings,
-
-	.read_status = dtt200u_fe_read_status,
-	.read_ber = dtt200u_fe_read_ber,
-	.read_signal_strength = dtt200u_fe_read_signal_strength,
-	.read_snr = dtt200u_fe_read_snr,
-	.read_ucblocks = dtt200u_fe_read_unc_blocks,
-};
diff --git a/drivers/media/dvb/dvb-core/dmxdev.c b/drivers/media/dvb/dvb-core/dmxdev.c
--- a/drivers/media/dvb/dvb-core/dmxdev.c
+++ b/drivers/media/dvb/dvb-core/dmxdev.c
@@ -42,12 +42,6 @@ MODULE_PARM_DESC(debug, "Turn on/off deb
 
 #define dprintk	if (debug) printk
 
-static inline struct dmxdev_filter *
-dvb_dmxdev_file_to_filter(struct file *file)
-{
-	return (struct dmxdev_filter *) file->private_data;
-}
-
 static inline void dvb_dmxdev_buffer_init(struct dmxdev_buffer *buffer)
 {
 	buffer->data=NULL;
@@ -669,8 +663,10 @@ static int dvb_dmxdev_filter_start(struc
 
 		ret = filter->feed.ts->start_filtering(filter->feed.ts);
 
-		if (ret < 0)
+		if (ret < 0) {
+			dmxdev->demux->release_ts_feed(dmxdev->demux, *tsfeed);
 			return ret;
+		}
 
 		break;
 	}
@@ -842,7 +838,7 @@ static ssize_t dvb_dmxdev_read_sec(struc
 static ssize_t
 dvb_demux_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
 {
-	struct dmxdev_filter *dmxdevfilter=dvb_dmxdev_file_to_filter(file);
+	struct dmxdev_filter *dmxdevfilter= file->private_data;
 	int ret=0;
 
 	if (down_interruptible(&dmxdevfilter->mutex))
@@ -863,7 +859,7 @@ dvb_demux_read(struct file *file, char _
 static int dvb_demux_do_ioctl(struct inode *inode, struct file *file,
 			      unsigned int cmd, void *parg)
 {
-	struct dmxdev_filter *dmxdevfilter=dvb_dmxdev_file_to_filter(file);
+	struct dmxdev_filter *dmxdevfilter = file->private_data;
 	struct dmxdev *dmxdev=dmxdevfilter->dev;
 	unsigned long arg=(unsigned long) parg;
 	int ret=0;
@@ -960,7 +956,7 @@ static int dvb_demux_ioctl(struct inode 
 
 static unsigned int dvb_demux_poll (struct file *file, poll_table *wait)
 {
-	struct dmxdev_filter *dmxdevfilter = dvb_dmxdev_file_to_filter(file);
+	struct dmxdev_filter *dmxdevfilter = file->private_data;
 	unsigned int mask = 0;
 
 	if (!dmxdevfilter)
@@ -985,7 +981,7 @@ static unsigned int dvb_demux_poll (stru
 
 static int dvb_demux_release(struct inode *inode, struct file *file)
 {
-	struct dmxdev_filter *dmxdevfilter = dvb_dmxdev_file_to_filter(file);
+	struct dmxdev_filter *dmxdevfilter = file->private_data;
 	struct dmxdev *dmxdev = dmxdevfilter->dev;
 
 	return dvb_dmxdev_filter_free(dmxdev, dmxdevfilter);
@@ -1109,7 +1105,6 @@ dvb_dmxdev_init(struct dmxdev *dmxdev, s
 		dvb_dmxdev_filter_state_set(&dmxdev->filter[i], DMXDEV_STATE_FREE);
 		dmxdev->dvr[i].dev=dmxdev;
 		dmxdev->dvr[i].buffer.data=NULL;
-		dvb_dmxdev_filter_state_set(&dmxdev->filter[i], DMXDEV_STATE_FREE);
 		dvb_dmxdev_dvr_state_set(&dmxdev->dvr[i], DMXDEV_STATE_FREE);
 	}
 
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c
--- a/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -35,12 +35,15 @@
 #include <linux/moduleparam.h>
 #include <linux/list.h>
 #include <linux/suspend.h>
+#include <linux/jiffies.h>
 #include <asm/processor.h>
 #include <asm/semaphore.h>
 
 #include "dvb_frontend.h"
 #include "dvbdev.h"
 
+// #define DEBUG_LOCKLOSS 1
+
 static int dvb_frontend_debug;
 static int dvb_shutdown_timeout = 5;
 static int dvb_force_auto_inversion;
@@ -112,6 +115,7 @@ struct dvb_frontend_private {
 	int exit;
 	int wakeup;
 	fe_status_t status;
+	fe_sec_tone_mode_t tone;
 };
 
 
@@ -327,7 +331,8 @@ static int dvb_frontend_is_exiting(struc
 		return 1;
 
 	if (fepriv->dvbdev->writers == 1)
-		if (jiffies - fepriv->release_jiffies > dvb_shutdown_timeout * HZ)
+		if (time_after(jiffies, fepriv->release_jiffies +
+					dvb_shutdown_timeout * HZ))
 			return 1;
 
 	return 0;
@@ -389,8 +394,7 @@ static int dvb_frontend_thread(void *dat
 			break;
 		}
 
-		if (current->flags & PF_FREEZE)
-			refrigerator(PF_FREEZE);
+		try_to_freeze();
 
 		if (down_interruptible(&fepriv->sem))
 			break;
@@ -433,9 +437,26 @@ static int dvb_frontend_thread(void *dat
 			/* we're tuned, and the lock is still good... */
 			if (s & FE_HAS_LOCK)
 				continue;
-			else {
-				/* if we _WERE_ tuned, but now don't have a lock,
-				 * need to zigzag */
+			else { /* if we _WERE_ tuned, but now don't have a lock */
+#ifdef DEBUG_LOCKLOSS
+				/* first of all try setting the tone again if it was on - this
+				 * sometimes works around problems with noisy power supplies */
+				if (fe->ops->set_tone && (fepriv->tone == SEC_TONE_ON)) {
+					fe->ops->set_tone(fe, fepriv->tone);
+					mdelay(100);
+					s = 0;
+					fe->ops->read_status(fe, &s);
+					if (s & FE_HAS_LOCK) {
+						printk("DVB%i: Lock was lost, but regained by setting "
+						       "the tone. This may indicate your power supply "
+						       "is noisy/slightly incompatable with this DVB-S "
+						       "adapter\n", fe->dvb->num);
+						fepriv->state = FESTATE_TUNED;
+						continue;
+					}
+				}
+#endif
+				/* some other reason for losing the lock - start zigzagging */
 				fepriv->state = FESTATE_ZIGZAG_FAST;
 				fepriv->started_auto_step = fepriv->auto_step;
 				check_wrapped = 0;
@@ -625,11 +646,21 @@ static int dvb_frontend_ioctl(struct ino
 		break;
 	}
 
-	case FE_READ_STATUS:
+	case FE_READ_STATUS: {
+		fe_status_t* status = parg;
+
+		/* if retune was requested but hasn't occured yet, prevent
+		 * that user get signal state from previous tuning */
+		if(fepriv->state == FESTATE_RETUNE) {
+			err=0;
+			*status = 0;
+			break;
+		}
+
 		if (fe->ops->read_status)
-			err = fe->ops->read_status(fe, (fe_status_t*) parg);
+			err = fe->ops->read_status(fe, status);
 		break;
-
+	}
 	case FE_READ_BER:
 		if (fe->ops->read_ber)
 			err = fe->ops->read_ber(fe, (__u32*) parg);
@@ -680,6 +711,7 @@ static int dvb_frontend_ioctl(struct ino
 			err = fe->ops->set_tone(fe, (fe_sec_tone_mode_t) parg);
 			fepriv->state = FESTATE_DISEQC;
 			fepriv->status = 0;
+			fepriv->tone = (fe_sec_tone_mode_t) parg;
 		}
 		break;
 
@@ -882,6 +914,7 @@ int dvb_register_frontend(struct dvb_ada
 	init_MUTEX (&fepriv->events.sem);
 	fe->dvb = dvb;
 	fepriv->inversion = INVERSION_OFF;
+	fepriv->tone = SEC_TONE_OFF;
 
 	printk ("DVB: registering frontend %i (%s)...\n",
 		fe->dvb->num,
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.h b/drivers/media/dvb/dvb-core/dvb_frontend.h
--- a/drivers/media/dvb/dvb-core/dvb_frontend.h
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.h
@@ -40,28 +40,6 @@
 
 #include "dvbdev.h"
 
-/* FIXME: Move to i2c-id.h */
-#define I2C_DRIVERID_DVBFE_SP8870	I2C_DRIVERID_EXP2
-#define I2C_DRIVERID_DVBFE_CX22700	I2C_DRIVERID_EXP2
-#define I2C_DRIVERID_DVBFE_AT76C651	I2C_DRIVERID_EXP2
-#define I2C_DRIVERID_DVBFE_CX24110	I2C_DRIVERID_EXP2
-#define I2C_DRIVERID_DVBFE_CX22702	I2C_DRIVERID_EXP2
-#define I2C_DRIVERID_DVBFE_DIB3000MB	I2C_DRIVERID_EXP2
-#define I2C_DRIVERID_DVBFE_DST		I2C_DRIVERID_EXP2
-#define I2C_DRIVERID_DVBFE_DUMMY	I2C_DRIVERID_EXP2
-#define I2C_DRIVERID_DVBFE_L64781	I2C_DRIVERID_EXP2
-#define I2C_DRIVERID_DVBFE_MT312	I2C_DRIVERID_EXP2
-#define I2C_DRIVERID_DVBFE_MT352	I2C_DRIVERID_EXP2
-#define I2C_DRIVERID_DVBFE_NXT6000	I2C_DRIVERID_EXP2
-#define I2C_DRIVERID_DVBFE_SP887X	I2C_DRIVERID_EXP2
-#define I2C_DRIVERID_DVBFE_STV0299	I2C_DRIVERID_EXP2
-#define I2C_DRIVERID_DVBFE_TDA1004X	I2C_DRIVERID_EXP2
-#define I2C_DRIVERID_DVBFE_TDA8083	I2C_DRIVERID_EXP2
-#define I2C_DRIVERID_DVBFE_VES1820	I2C_DRIVERID_EXP2
-#define I2C_DRIVERID_DVBFE_VES1X93	I2C_DRIVERID_EXP2
-#define I2C_DRIVERID_DVBFE_TDA80XX	I2C_DRIVERID_EXP2
-
-
 struct dvb_frontend_tune_settings {
         int min_delay_ms;
         int step_size;
diff --git a/drivers/media/dvb/dvb-core/dvbdev.c b/drivers/media/dvb/dvb-core/dvbdev.c
--- a/drivers/media/dvb/dvb-core/dvbdev.c
+++ b/drivers/media/dvb/dvb-core/dvbdev.c
@@ -56,8 +56,7 @@ static const char * const dnames[] = {
 #define nums2minor(num,type,id)	((num << 6) | (id << 4) | type)
 #define MAX_DVB_MINORS		(DVB_MAX_ADAPTERS*64)
 
-struct class_simple *dvb_class;
-EXPORT_SYMBOL(dvb_class);
+static struct class *dvb_class;
 
 static struct dvb_device* dvbdev_find_device (int minor)
 {
@@ -236,8 +235,8 @@ int dvb_register_device(struct dvb_adapt
 			S_IFCHR | S_IRUSR | S_IWUSR,
 			"dvb/adapter%d/%s%d", adap->num, dnames[type], id);
 
-	class_simple_device_add(dvb_class, MKDEV(DVB_MAJOR, nums2minor(adap->num, type, id)),
-				NULL, "dvb%d.%s%d", adap->num, dnames[type], id);
+	class_device_create(dvb_class, MKDEV(DVB_MAJOR, nums2minor(adap->num, type, id)),
+			    NULL, "dvb%d.%s%d", adap->num, dnames[type], id);
 
 	dprintk("DVB: register adapter%d/%s%d @ minor: %i (0x%02x)\n",
 		adap->num, dnames[type], id, nums2minor(adap->num, type, id),
@@ -256,7 +255,7 @@ void dvb_unregister_device(struct dvb_de
 	devfs_remove("dvb/adapter%d/%s%d", dvbdev->adapter->num,
 			dnames[dvbdev->type], dvbdev->id);
 
-	class_simple_device_remove(MKDEV(DVB_MAJOR, nums2minor(dvbdev->adapter->num,
+	class_device_destroy(dvb_class, MKDEV(DVB_MAJOR, nums2minor(dvbdev->adapter->num,
 					dvbdev->type, dvbdev->id)));
 
 	list_del (&dvbdev->list_head);
@@ -412,7 +411,7 @@ static int __init init_dvbdev(void)
 
 	devfs_mk_dir("dvb");
 
-	dvb_class = class_simple_create(THIS_MODULE, "dvb");
+	dvb_class = class_create(THIS_MODULE, "dvb");
 	if (IS_ERR(dvb_class)) {
 		retval = PTR_ERR(dvb_class);
 		goto error;
@@ -429,7 +428,7 @@ error:
 static void __exit exit_dvbdev(void)
 {
         devfs_remove("dvb");
-	class_simple_destroy(dvb_class);
+	class_destroy(dvb_class);
 	cdev_del(&dvb_device_cdev);
         unregister_chrdev_region(MKDEV(DVB_MAJOR, 0), MAX_DVB_MINORS);
 }
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig
new file mode 100644
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/Kconfig
@@ -0,0 +1,119 @@
+config DVB_USB
+	tristate "Support for various USB DVB devices"
+	depends on DVB_CORE && USB
+	select FW_LOADER
+	help
+	  By enabling this you will be able to choose the various supported
+	  USB1.1 and USB2.0 DVB devices.
+
+	  Almost every USB device needs a firmware, please look into
+	  <file:Documentation/dvb/README.dvb-usb>.
+
+	  For a complete list of supported USB devices see the LinuxTV DVB Wiki:
+	  <http://www.linuxtv.org/wiki/index.php/DVB_USB>
+
+	  Say Y if you own a USB DVB device.
+
+config DVB_USB_DEBUG
+	bool "Enable extended debug support for all DVB-USB devices"
+	depends on DVB_USB
+	help
+	  Say Y if you want to enable debugging. See modinfo dvb-usb (and the
+	  appropriate drivers) for debug levels.
+
+config DVB_USB_A800
+	tristate "AVerMedia AverTV DVB-T USB 2.0 (A800)"
+	depends on DVB_USB
+	select DVB_DIB3000MC
+	help
+	  Say Y here to support the AVerMedia AverTV DVB-T USB 2.0 (A800) receiver.
+
+config DVB_USB_DIBUSB_MB
+	tristate "DiBcom USB DVB-T devices (based on the DiB3000M-B) (see help for device list)"
+	depends on DVB_USB
+	select DVB_DIB3000MB
+	help
+	  Support for USB 1.1 and 2.0 DVB-T receivers based on reference designs made by
+	  DiBcom (<http://www.dibcom.fr>) equipped with a DiB3000M-B demodulator.
+
+	  Devices supported by this driver:
+	    TwinhanDTV USB-Ter (VP7041)
+	    TwinhanDTV Magic Box (VP7041e)
+	    KWorld/JetWay/ADSTech V-Stream XPERT DTV - DVB-T USB1.1 and USB2.0
+	    Hama DVB-T USB1.1-Box
+	    DiBcom USB1.1 reference devices (non-public)
+	    Ultima Electronic/Artec T1 USB TVBOX
+	    Compro Videomate DVB-U2000 - DVB-T USB
+	    Grandtec DVB-T USB
+	    Avermedia AverTV DVBT USB1.1
+	    Artec T1 USB1.1 boxes
+
+	  The VP7041 seems to be identical to "CTS Portable" (Chinese
+	  Television System).
+
+	  Say Y if you own such a device and want to use it. You should build it as
+	  a module.
+
+config DVB_USB_DIBUSB_MC
+	tristate "DiBcom USB DVB-T devices (based on the DiB3000M-C/P) (see help for device list)"
+	depends on DVB_USB
+	select DVB_DIB3000MC
+	help
+	  Support for 2.0 DVB-T receivers based on reference designs made by
+	  DiBcom (<http://www.dibcom.fr>) equipped with a DiB3000M-C/P demodulator.
+
+	  Devices supported by this driver:
+	    DiBcom USB2.0 reference devices (non-public)
+	    Artec T1 USB2.0 boxes
+
+	  Say Y if you own such a device and want to use it. You should build it as
+	  a module.
+
+config DVB_USB_UMT_010
+	tristate "HanfTek UMT-010 DVB-T USB2.0 support"
+	depends on DVB_USB
+	select DVB_DIB3000MC
+	help
+	  Say Y here to support the HanfTek UMT-010 USB2.0 stick-sized DVB-T receiver.
+
+config DVB_USB_CXUSB
+	tristate "Medion MD95700 hybrid USB2.0 (Conexant) support"
+	depends on DVB_USB
+	select DVB_CX22702
+	help
+	  Say Y here to support the Medion MD95700 hybrid USB2.0 device. Currently
+	  only the DVB-T part is supported.
+
+config DVB_USB_DIGITV
+	tristate "Nebula Electronics uDigiTV DVB-T USB2.0 support"
+	depends on DVB_USB
+	select DVB_NXT6000
+	select DVB_MT352
+	help
+	  Say Y here to support the Nebula Electronics uDigitV USB2.0 DVB-T receiver.
+
+config DVB_USB_VP7045
+	tristate "TwinhanDTV Alpha/MagicBoxII and DNTV tinyUSB2 DVB-T USB2.0 support"
+	depends on DVB_USB
+	help
+	  Say Y here to support the
+	    TwinhanDTV Alpha (stick) (VP-7045),
+		TwinhanDTV MagicBox II (VP-7046) and
+		DigitalNow TinyUSB 2 DVB-t DVB-T USB2.0 receivers.
+
+config DVB_USB_NOVA_T_USB2
+	tristate "Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 support"
+	depends on DVB_USB
+	select DVB_DIB3000MC
+	help
+	  Say Y here to support the Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 receiver.
+
+config DVB_USB_DTT200U
+	tristate "WideView WT-200U and WT-220U (pen) DVB-T USB2.0 support (Yakumo/Hama/Typhoon/Yuan)"
+	depends on DVB_USB
+	help
+	  Say Y here to support the WideView/Yakumo/Hama/Typhoon/Yuan DVB-T USB2.0 receiver.
+
+	  The receivers are also known as DTT200U (Yakumo) and UB300 (Yuan).
+
+	  The WT-220U and its clones are pen-sized.
diff --git a/drivers/media/dvb/dvb-usb/Makefile b/drivers/media/dvb/dvb-usb/Makefile
new file mode 100644
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/Makefile
@@ -0,0 +1,33 @@
+dvb-usb-objs = dvb-usb-firmware.o dvb-usb-init.o dvb-usb-urb.o dvb-usb-i2c.o dvb-usb-dvb.o dvb-usb-remote.o
+obj-$(CONFIG_DVB_USB) += dvb-usb.o
+
+dvb-usb-vp7045-objs = vp7045.o vp7045-fe.o
+obj-$(CONFIG_DVB_USB_VP7045) += dvb-usb-vp7045.o
+
+dvb-usb-dtt200u-objs = dtt200u.o dtt200u-fe.o
+obj-$(CONFIG_DVB_USB_DTT200U) += dvb-usb-dtt200u.o
+
+dvb-usb-dibusb-common-objs = dibusb-common.o
+
+dvb-usb-a800-objs = a800.o
+obj-$(CONFIG_DVB_USB_A800) += dvb-usb-dibusb-common.o dvb-usb-a800.o
+
+dvb-usb-dibusb-mb-objs = dibusb-mb.o
+obj-$(CONFIG_DVB_USB_DIBUSB_MB) += dvb-usb-dibusb-common.o dvb-usb-dibusb-mb.o
+
+dvb-usb-dibusb-mc-objs = dibusb-mc.o
+obj-$(CONFIG_DVB_USB_DIBUSB_MC) += dvb-usb-dibusb-common.o dvb-usb-dibusb-mc.o
+
+dvb-usb-nova-t-usb2-objs = nova-t-usb2.o
+obj-$(CONFIG_DVB_USB_NOVA_T_USB2) += dvb-usb-dibusb-common.o dvb-usb-nova-t-usb2.o
+
+dvb-usb-umt-010-objs = umt-010.o
+obj-$(CONFIG_DVB_USB_UMT_010) += dvb-usb-dibusb-common.o dvb-usb-umt-010.o
+
+dvb-usb-digitv-objs = digitv.o
+obj-$(CONFIG_DVB_USB_DIGITV) += dvb-usb-digitv.o
+
+dvb-usb-cxusb-objs = cxusb.o
+obj-$(CONFIG_DVB_USB_CXUSB) += dvb-usb-cxusb.o
+
+EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
diff --git a/drivers/media/dvb/dvb-usb/a800.c b/drivers/media/dvb/dvb-usb/a800.c
new file mode 100644
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/a800.c
@@ -0,0 +1,182 @@
+/* DVB USB framework compliant Linux driver for the AVerMedia AverTV DVB-T
+ * USB2.0 (A800) DVB-T receiver.
+ *
+ * Copyright (C) 2005 Patrick Boettcher (patrick.boettcher@desy.de)
+ *
+ * Thanks to
+ *   - AVerMedia who kindly provided information and
+ *   - Glen Harris who suffered from my mistakes during development.
+ *
+ *	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, version 2.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+#include "dibusb.h"
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level (rc=1 (or-able))." DVB_USB_DEBUG_STATUS);
+#define deb_rc(args...)   dprintk(debug,0x01,args)
+
+static int a800_power_ctrl(struct dvb_usb_device *d, int onoff)
+{
+	/* do nothing for the AVerMedia */
+	return 0;
+}
+
+static struct dvb_usb_rc_key a800_rc_keys[] = {
+	{ 0x02, 0x01, KEY_PROG1 },       /* SOURCE */
+	{ 0x02, 0x00, KEY_POWER },       /* POWER */
+	{ 0x02, 0x05, KEY_1 },           /* 1 */
+	{ 0x02, 0x06, KEY_2 },           /* 2 */
+	{ 0x02, 0x07, KEY_3 },           /* 3 */
+	{ 0x02, 0x09, KEY_4 },           /* 4 */
+	{ 0x02, 0x0a, KEY_5 },           /* 5 */
+	{ 0x02, 0x0b, KEY_6 },           /* 6 */
+	{ 0x02, 0x0d, KEY_7 },           /* 7 */
+	{ 0x02, 0x0e, KEY_8 },           /* 8 */
+	{ 0x02, 0x0f, KEY_9 },           /* 9 */
+	{ 0x02, 0x12, KEY_LEFT },        /* L / DISPLAY */
+	{ 0x02, 0x11, KEY_0 },           /* 0 */
+	{ 0x02, 0x13, KEY_RIGHT },       /* R / CH RTN */
+	{ 0x02, 0x17, KEY_PROG2 },       /* SNAP SHOT */
+	{ 0x02, 0x10, KEY_PROG3 },       /* 16-CH PREV */
+	{ 0x02, 0x03, KEY_CHANNELUP },   /* CH UP */
+	{ 0x02, 0x1e, KEY_VOLUMEDOWN },  /* VOL DOWN */
+	{ 0x02, 0x0c, KEY_ZOOM },        /* FULL SCREEN */
+	{ 0x02, 0x1f, KEY_VOLUMEUP },    /* VOL UP */
+	{ 0x02, 0x02, KEY_CHANNELDOWN }, /* CH DOWN */
+	{ 0x02, 0x14, KEY_MUTE },        /* MUTE */
+	{ 0x02, 0x08, KEY_AUDIO },       /* AUDIO */
+	{ 0x02, 0x19, KEY_RECORD },      /* RECORD */
+	{ 0x02, 0x18, KEY_PLAY },        /* PLAY */
+	{ 0x02, 0x1b, KEY_STOP },        /* STOP */
+	{ 0x02, 0x1a, KEY_PLAYPAUSE },   /* TIMESHIFT / PAUSE */
+	{ 0x02, 0x1d, KEY_BACK },        /* << / RED */
+	{ 0x02, 0x1c, KEY_FORWARD },     /* >> / YELLOW */
+	{ 0x02, 0x03, KEY_TEXT },        /* TELETEXT */
+	{ 0x02, 0x01, KEY_FIRST },       /* |<< / GREEN */
+	{ 0x02, 0x00, KEY_LAST },        /* >>| / BLUE */
+	{ 0x02, 0x04, KEY_EPG },         /* EPG */
+	{ 0x02, 0x15, KEY_MENU },        /* MENU */
+
+	{ 0x03, 0x03, KEY_CHANNELUP },   /* CH UP */
+	{ 0x03, 0x02, KEY_CHANNELDOWN }, /* CH DOWN */
+	{ 0x03, 0x01, KEY_FIRST },       /* |<< / GREEN */
+	{ 0x03, 0x00, KEY_LAST },        /* >>| / BLUE */
+
+};
+
+int a800_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
+{
+	u8 key[5];
+	if (usb_control_msg(d->udev,usb_rcvctrlpipe(d->udev,0),
+				0x04, USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, key, 5,
+				2000) != 5)
+		return -ENODEV;
+
+	/* call the universal NEC remote processor, to find out the key's state and event */
+	dvb_usb_nec_rc_key_to_event(d,key,event,state);
+	if (key[0] != 0)
+		deb_rc("key: %x %x %x %x %x\n",key[0],key[1],key[2],key[3],key[4]);
+	return 0;
+}
+
+/* USB Driver stuff */
+static struct dvb_usb_properties a800_properties;
+
+static int a800_probe(struct usb_interface *intf,
+		const struct usb_device_id *id)
+{
+	return dvb_usb_device_init(intf,&a800_properties,THIS_MODULE);
+}
+
+/* do not change the order of the ID table */
+static struct usb_device_id a800_table [] = {
+/* 00 */	{ USB_DEVICE(USB_VID_AVERMEDIA,     USB_PID_AVERMEDIA_DVBT_USB2_COLD) },
+/* 01 */	{ USB_DEVICE(USB_VID_AVERMEDIA,     USB_PID_AVERMEDIA_DVBT_USB2_WARM) },
+			{ }		/* Terminating entry */
+};
+MODULE_DEVICE_TABLE (usb, a800_table);
+
+static struct dvb_usb_properties a800_properties = {
+	.caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER,
+	.pid_filter_count = 32,
+
+	.usb_ctrl = CYPRESS_FX2,
+
+	.firmware = "dvb-usb-avertv-a800-02.fw",
+
+	.size_of_priv     = sizeof(struct dibusb_state),
+
+	.streaming_ctrl   = dibusb2_0_streaming_ctrl,
+	.pid_filter       = dibusb_pid_filter,
+	.pid_filter_ctrl  = dibusb_pid_filter_ctrl,
+	.power_ctrl       = a800_power_ctrl,
+	.frontend_attach  = dibusb_dib3000mc_frontend_attach,
+	.tuner_attach     = dibusb_dib3000mc_tuner_attach,
+
+	.rc_interval      = DEFAULT_RC_INTERVAL,
+	.rc_key_map       = a800_rc_keys,
+	.rc_key_map_size  = ARRAY_SIZE(a800_rc_keys),
+	.rc_query         = a800_rc_query,
+
+	.i2c_algo         = &dibusb_i2c_algo,
+
+	.generic_bulk_ctrl_endpoint = 0x01,
+	/* parameter for the MPEG2-data transfer */
+	.urb = {
+		.type = DVB_USB_BULK,
+		.count = 7,
+		.endpoint = 0x06,
+		.u = {
+			.bulk = {
+				.buffersize = 4096,
+			}
+		}
+	},
+
+	.num_device_descs = 1,
+	.devices = {
+		{   "AVerMedia AverTV DVB-T USB 2.0 (A800)",
+			{ &a800_table[0], NULL },
+			{ &a800_table[1], NULL },
+		},
+	}
+};
+
+static struct usb_driver a800_driver = {
+	.owner		= THIS_MODULE,
+	.name		= "dvb_usb_a800",
+	.probe		= a800_probe,
+	.disconnect = dvb_usb_device_exit,
+	.id_table	= a800_table,
+};
+
+/* module stuff */
+static int __init a800_module_init(void)
+{
+	int result;
+	if ((result = usb_register(&a800_driver))) {
+		err("usb_register failed. Error number %d",result);
+		return result;
+	}
+
+	return 0;
+}
+
+static void __exit a800_module_exit(void)
+{
+	/* deregister this driver from the USB subsystem */
+	usb_deregister(&a800_driver);
+}
+
+module_init (a800_module_init);
+module_exit (a800_module_exit);
+
+MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
+MODULE_DESCRIPTION("AVerMedia AverTV DVB-T USB 2.0 (A800)");
+MODULE_VERSION("1.0");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c
new file mode 100644
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/cxusb.c
@@ -0,0 +1,295 @@
+/* DVB USB compliant linux driver for Conexant USB reference design.
+ *
+ * The Conexant reference design I saw on their website was only for analogue
+ * capturing (using the cx25842). The box I took to write this driver (reverse
+ * engineered) is the one labeled Medion MD95700. In addition to the cx25842
+ * for analogue capturing it also has a cx22702 DVB-T demodulator on the main
+ * board. Besides it has a atiremote (X10) and a USB2.0 hub onboard.
+ *
+ * Maybe it is a little bit premature to call this driver cxusb, but I assume
+ * the USB protocol is identical or at least inherited from the reference
+ * design, so it can be reused for the "analogue-only" device (if it will
+ * appear at all).
+ *
+ * TODO: check if the cx25840-driver (from ivtv) can be used for the analogue
+ * part
+ *
+ * Copyright (C) 2005 Patrick Boettcher (patrick.boettcher@desy.de)
+ *
+ *	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, version 2.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+#include "cxusb.h"
+
+#include "cx22702.h"
+
+/* debug */
+int dvb_usb_cxusb_debug;
+module_param_named(debug,dvb_usb_cxusb_debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS);
+
+static int cxusb_ctrl_msg(struct dvb_usb_device *d,
+		u8 cmd, u8 *wbuf, int wlen, u8 *rbuf, int rlen)
+{
+	int wo = (rbuf == NULL || rlen == 0); /* write-only */
+	u8 sndbuf[1+wlen];
+	memset(sndbuf,0,1+wlen);
+
+	sndbuf[0] = cmd;
+	memcpy(&sndbuf[1],wbuf,wlen);
+	if (wo)
+		dvb_usb_generic_write(d,sndbuf,1+wlen);
+	else
+		dvb_usb_generic_rw(d,sndbuf,1+wlen,rbuf,rlen,0);
+
+	return 0;
+}
+
+/* I2C */
+static void cxusb_set_i2c_path(struct dvb_usb_device *d, enum cxusb_i2c_pathes path)
+{
+	struct cxusb_state *st = d->priv;
+	u8 o[2],i;
+
+	if (path == st->cur_i2c_path)
+		return;
+
+	o[0] = IOCTL_SET_I2C_PATH;
+	switch (path) {
+		case PATH_CX22702:
+			o[1] = 0;
+			break;
+		case PATH_TUNER_OTHER:
+			o[1] = 1;
+			break;
+		default:
+			err("unkown i2c path");
+			return;
+	}
+	cxusb_ctrl_msg(d,CMD_IOCTL,o,2,&i,1);
+
+	if (i != 0x01)
+		deb_info("i2c_path setting failed.\n");
+
+	st->cur_i2c_path = path;
+}
+
+static int cxusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num)
+{
+	struct dvb_usb_device *d = i2c_get_adapdata(adap);
+	int i;
+
+	if (down_interruptible(&d->i2c_sem) < 0)
+		return -EAGAIN;
+
+	if (num > 2)
+		warn("more than 2 i2c messages at a time is not handled yet. TODO.");
+
+	for (i = 0; i < num; i++) {
+
+		switch (msg[i].addr) {
+			case 0x63:
+				cxusb_set_i2c_path(d,PATH_CX22702);
+				break;
+			default:
+				cxusb_set_i2c_path(d,PATH_TUNER_OTHER);
+				break;
+		}
+
+		/* read request */
+		if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) {
+			u8 obuf[3+msg[i].len], ibuf[1+msg[i+1].len];
+			obuf[0] = msg[i].len;
+			obuf[1] = msg[i+1].len;
+			obuf[2] = msg[i].addr;
+			memcpy(&obuf[3],msg[i].buf,msg[i].len);
+
+			if (cxusb_ctrl_msg(d, CMD_I2C_READ,
+						obuf, 3+msg[i].len,
+						ibuf, 1+msg[i+1].len) < 0)
+				break;
+
+			if (ibuf[0] != 0x08)
+				deb_info("i2c read could have been failed\n");
+
+			memcpy(msg[i+1].buf,&ibuf[1],msg[i+1].len);
+
+			i++;
+		} else { /* write */
+			u8 obuf[2+msg[i].len], ibuf;
+			obuf[0] = msg[i].addr;
+			obuf[1] = msg[i].len;
+			memcpy(&obuf[2],msg[i].buf,msg[i].len);
+
+			if (cxusb_ctrl_msg(d,CMD_I2C_WRITE, obuf, 2+msg[i].len, &ibuf,1) < 0)
+				break;
+			if (ibuf != 0x08)
+				deb_info("i2c write could have been failed\n");
+		}
+	}
+
+	up(&d->i2c_sem);
+	return i;
+}
+
+static u32 cxusb_i2c_func(struct i2c_adapter *adapter)
+{
+	return I2C_FUNC_I2C;
+}
+
+static struct i2c_algorithm cxusb_i2c_algo = {
+	.name          = "Conexant USB I2C algorithm",
+	.id            = I2C_ALGO_BIT,
+	.master_xfer   = cxusb_i2c_xfer,
+	.functionality = cxusb_i2c_func,
+};
+
+static int cxusb_power_ctrl(struct dvb_usb_device *d, int onoff)
+{
+	return 0;
+}
+
+static int cxusb_streaming_ctrl(struct dvb_usb_device *d, int onoff)
+{
+	u8 buf[2] = { 0x03, 0x00 };
+	if (onoff)
+		cxusb_ctrl_msg(d,0x36, buf, 2, NULL, 0);
+	else
+		cxusb_ctrl_msg(d,0x37, NULL, 0, NULL, 0);
+
+	return 0;
+}
+
+struct cx22702_config cxusb_cx22702_config = {
+	.demod_address = 0x63,
+
+	.output_mode = CX22702_PARALLEL_OUTPUT,
+
+	.pll_init = dvb_usb_pll_init_i2c,
+	.pll_set  = dvb_usb_pll_set_i2c,
+};
+
+/* Callbacks for DVB USB */
+static int cxusb_tuner_attach(struct dvb_usb_device *d)
+{
+	u8 bpll[4] = { 0x0b, 0xdc, 0x9c, 0xa0 };
+	d->pll_addr = 0x61;
+	memcpy(d->pll_init,bpll,4);
+	d->pll_desc = &dvb_pll_fmd1216me;
+	return 0;
+}
+
+static int cxusb_frontend_attach(struct dvb_usb_device *d)
+{
+	u8 buf[2] = { 0x03, 0x00 };
+	u8 b = 0;
+
+	if (usb_set_interface(d->udev,0,0) < 0)
+		err("set interface to alts=0 failed");
+
+	cxusb_ctrl_msg(d,0xde,&b,0,NULL,0);
+	cxusb_set_i2c_path(d,PATH_TUNER_OTHER);
+	cxusb_ctrl_msg(d,CMD_POWER_OFF, NULL, 0, &b, 1);
+
+	if (usb_set_interface(d->udev,0,6) < 0)
+		err("set interface failed");
+
+	cxusb_ctrl_msg(d,0x36, buf, 2, NULL, 0);
+	cxusb_set_i2c_path(d,PATH_CX22702);
+	cxusb_ctrl_msg(d,CMD_POWER_ON, NULL, 0, &b, 1);
+
+	if ((d->fe = cx22702_attach(&cxusb_cx22702_config, &d->i2c_adap)) != NULL)
+		return 0;
+
+	return -EIO;
+}
+
+/* DVB USB Driver stuff */
+static struct dvb_usb_properties cxusb_properties;
+
+static int cxusb_probe(struct usb_interface *intf,
+		const struct usb_device_id *id)
+{
+	return dvb_usb_device_init(intf,&cxusb_properties,THIS_MODULE);
+}
+
+static struct usb_device_id cxusb_table [] = {
+		{ USB_DEVICE(USB_VID_MEDION, USB_PID_MEDION_MD95700) },
+		{}		/* Terminating entry */
+};
+MODULE_DEVICE_TABLE (usb, cxusb_table);
+
+static struct dvb_usb_properties cxusb_properties = {
+	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
+
+	.usb_ctrl = CYPRESS_FX2,
+
+	.size_of_priv     = sizeof(struct cxusb_state),
+
+	.streaming_ctrl   = cxusb_streaming_ctrl,
+	.power_ctrl       = cxusb_power_ctrl,
+	.frontend_attach  = cxusb_frontend_attach,
+	.tuner_attach     = cxusb_tuner_attach,
+
+	.i2c_algo         = &cxusb_i2c_algo,
+
+	.generic_bulk_ctrl_endpoint = 0x01,
+	/* parameter for the MPEG2-data transfer */
+	.urb = {
+		.type = DVB_USB_ISOC,
+		.count = 5,
+		.endpoint = 0x02,
+		.u = {
+			.isoc = {
+				.framesperurb = 32,
+				.framesize = 940,
+				.interval = 5,
+			}
+		}
+	},
+
+	.num_device_descs = 1,
+	.devices = {
+		{   "Medion MD95700 (MDUSBTV-HYBRID)",
+			{ NULL },
+			{ &cxusb_table[0], NULL },
+		},
+	}
+};
+
+static struct usb_driver cxusb_driver = {
+	.owner		= THIS_MODULE,
+	.name		= "dvb_usb_cxusb",
+	.probe		= cxusb_probe,
+	.disconnect = dvb_usb_device_exit,
+	.id_table	= cxusb_table,
+};
+
+/* module stuff */
+static int __init cxusb_module_init(void)
+{
+	int result;
+	if ((result = usb_register(&cxusb_driver))) {
+		err("usb_register failed. Error number %d",result);
+		return result;
+	}
+
+	return 0;
+}
+
+static void __exit cxusb_module_exit(void)
+{
+	/* deregister this driver from the USB subsystem */
+	usb_deregister(&cxusb_driver);
+}
+
+module_init (cxusb_module_init);
+module_exit (cxusb_module_exit);
+
+MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
+MODULE_DESCRIPTION("Driver for Conexant USB2.0 hybrid reference design");
+MODULE_VERSION("1.0-alpha");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/cxusb.h b/drivers/media/dvb/dvb-usb/cxusb.h
new file mode 100644
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/cxusb.h
@@ -0,0 +1,30 @@
+#ifndef _DVB_USB_CXUSB_H_
+#define _DVB_USB_CXUSB_H_
+
+#define DVB_USB_LOG_PREFIX "digitv"
+#include "dvb-usb.h"
+
+extern int dvb_usb_cxusb_debug;
+#define deb_info(args...)   dprintk(dvb_usb_cxusb_debug,0x01,args)
+
+/* usb commands - some of it are guesses, don't have a reference yet */
+#define CMD_I2C_WRITE    0x08
+#define CMD_I2C_READ     0x09
+
+#define CMD_IOCTL        0x0e
+#define    IOCTL_SET_I2C_PATH 0x02
+
+#define CMD_POWER_OFF    0x50
+#define CMD_POWER_ON     0x51
+
+enum cxusb_i2c_pathes {
+	PATH_UNDEF       = 0x00,
+	PATH_CX22702     = 0x01,
+	PATH_TUNER_OTHER = 0x02,
+};
+
+struct cxusb_state {
+	enum cxusb_i2c_pathes cur_i2c_path;
+};
+
+#endif
diff --git a/drivers/media/dvb/dvb-usb/dibusb-common.c b/drivers/media/dvb/dvb-usb/dibusb-common.c
new file mode 100644
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dibusb-common.c
@@ -0,0 +1,281 @@
+/* Common methods for dibusb-based-receivers.
+ *
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ *
+ *	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, version 2.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+#include "dibusb.h"
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level (1=info (|-able))." DVB_USB_DEBUG_STATUS);
+MODULE_LICENSE("GPL");
+
+#define deb_info(args...) dprintk(debug,0x01,args)
+
+/* common stuff used by the different dibusb modules */
+int dibusb_streaming_ctrl(struct dvb_usb_device *d, int onoff)
+{
+	if (d->priv != NULL) {
+		struct dib_fe_xfer_ops *ops = d->priv;
+		if (ops->fifo_ctrl != NULL)
+			if (ops->fifo_ctrl(d->fe,onoff)) {
+				err("error while controlling the fifo of the demod.");
+				return -ENODEV;
+			}
+	}
+	return 0;
+}
+EXPORT_SYMBOL(dibusb_streaming_ctrl);
+
+int dibusb_pid_filter(struct dvb_usb_device *d, int index, u16 pid, int onoff)
+{
+	if (d->priv != NULL) {
+		struct dib_fe_xfer_ops *ops = d->priv;
+		if (d->pid_filtering && ops->pid_ctrl != NULL)
+			ops->pid_ctrl(d->fe,index,pid,onoff);
+	}
+	return 0;
+}
+EXPORT_SYMBOL(dibusb_pid_filter);
+
+int dibusb_pid_filter_ctrl(struct dvb_usb_device *d, int onoff)
+{
+	if (d->priv != NULL) {
+		struct dib_fe_xfer_ops *ops = d->priv;
+		if (ops->pid_parse != NULL)
+			if (ops->pid_parse(d->fe,onoff) < 0)
+				err("could not handle pid_parser");
+	}
+	return 0;
+}
+EXPORT_SYMBOL(dibusb_pid_filter_ctrl);
+
+int dibusb_power_ctrl(struct dvb_usb_device *d, int onoff)
+{
+	u8 b[3];
+	int ret;
+	b[0] = DIBUSB_REQ_SET_IOCTL;
+	b[1] = DIBUSB_IOCTL_CMD_POWER_MODE;
+	b[2] = onoff ? DIBUSB_IOCTL_POWER_WAKEUP : DIBUSB_IOCTL_POWER_SLEEP;
+	ret = dvb_usb_generic_write(d,b,3);
+	msleep(10);
+	return ret;
+}
+EXPORT_SYMBOL(dibusb_power_ctrl);
+
+int dibusb2_0_streaming_ctrl(struct dvb_usb_device *d, int onoff)
+{
+	u8 b[3] = { 0 };
+	int ret;
+
+	if ((ret = dibusb_streaming_ctrl(d,onoff)) < 0)
+		return ret;
+
+	if (onoff) {
+		b[0] = DIBUSB_REQ_SET_STREAMING_MODE;
+		b[1] = 0x00;
+		if ((ret = dvb_usb_generic_write(d,b,2)) < 0)
+			return ret;
+	}
+
+	b[0] = DIBUSB_REQ_SET_IOCTL;
+	b[1] = onoff ? DIBUSB_IOCTL_CMD_ENABLE_STREAM : DIBUSB_IOCTL_CMD_DISABLE_STREAM;
+	return dvb_usb_generic_write(d,b,3);
+}
+EXPORT_SYMBOL(dibusb2_0_streaming_ctrl);
+
+int dibusb2_0_power_ctrl(struct dvb_usb_device *d, int onoff)
+{
+	if (onoff) {
+		u8 b[3] = { DIBUSB_REQ_SET_IOCTL, DIBUSB_IOCTL_CMD_POWER_MODE, DIBUSB_IOCTL_POWER_WAKEUP };
+		return dvb_usb_generic_write(d,b,3);
+	} else
+		return 0;
+}
+EXPORT_SYMBOL(dibusb2_0_power_ctrl);
+
+static int dibusb_i2c_msg(struct dvb_usb_device *d, u8 addr,
+			  u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen)
+{
+	u8 sndbuf[wlen+4]; /* lead(1) devaddr,direction(1) addr(2) data(wlen) (len(2) (when reading)) */
+	/* write only ? */
+	int wo = (rbuf == NULL || rlen == 0),
+		len = 2 + wlen + (wo ? 0 : 2);
+
+	sndbuf[0] = wo ? DIBUSB_REQ_I2C_WRITE : DIBUSB_REQ_I2C_READ;
+	sndbuf[1] = (addr << 1) | (wo ? 0 : 1);
+
+	memcpy(&sndbuf[2],wbuf,wlen);
+
+	if (!wo) {
+		sndbuf[wlen+2] = (rlen >> 8) & 0xff;
+		sndbuf[wlen+3] = rlen & 0xff;
+	}
+
+	return dvb_usb_generic_rw(d,sndbuf,len,rbuf,rlen,0);
+}
+
+/*
+ * I2C master xfer function
+ */
+static int dibusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num)
+{
+	struct dvb_usb_device *d = i2c_get_adapdata(adap);
+	int i;
+
+	if (down_interruptible(&d->i2c_sem) < 0)
+		return -EAGAIN;
+
+	if (num > 2)
+		warn("more than 2 i2c messages at a time is not handled yet. TODO.");
+
+	for (i = 0; i < num; i++) {
+		/* write/read request */
+		if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) {
+			if (dibusb_i2c_msg(d, msg[i].addr, msg[i].buf,msg[i].len,
+						msg[i+1].buf,msg[i+1].len) < 0)
+				break;
+			i++;
+		} else
+			if (dibusb_i2c_msg(d, msg[i].addr, msg[i].buf,msg[i].len,NULL,0) < 0)
+				break;
+	}
+
+	up(&d->i2c_sem);
+	return i;
+}
+
+static u32 dibusb_i2c_func(struct i2c_adapter *adapter)
+{
+	return I2C_FUNC_I2C;
+}
+
+struct i2c_algorithm dibusb_i2c_algo = {
+	.name          = "DiBcom USB I2C algorithm",
+	.id            = I2C_ALGO_BIT,
+	.master_xfer   = dibusb_i2c_xfer,
+	.functionality = dibusb_i2c_func,
+};
+EXPORT_SYMBOL(dibusb_i2c_algo);
+
+int dibusb_read_eeprom_byte(struct dvb_usb_device *d, u8 offs, u8 *val)
+{
+	u8 wbuf[1] = { offs };
+	return dibusb_i2c_msg(d, 0x50, wbuf, 1, val, 1);
+}
+EXPORT_SYMBOL(dibusb_read_eeprom_byte);
+
+int dibusb_dib3000mc_frontend_attach(struct dvb_usb_device *d)
+{
+	struct dib3000_config demod_cfg;
+	struct dibusb_state *st = d->priv;
+
+	demod_cfg.pll_set = dvb_usb_pll_set_i2c;
+	demod_cfg.pll_init = dvb_usb_pll_init_i2c;
+
+	for (demod_cfg.demod_address = 0x8; demod_cfg.demod_address < 0xd; demod_cfg.demod_address++)
+		if ((d->fe = dib3000mc_attach(&demod_cfg,&d->i2c_adap,&st->ops)) != NULL) {
+			d->tuner_pass_ctrl = st->ops.tuner_pass_ctrl;
+			return 0;
+		}
+
+	return -ENODEV;
+}
+EXPORT_SYMBOL(dibusb_dib3000mc_frontend_attach);
+
+int dibusb_dib3000mc_tuner_attach (struct dvb_usb_device *d)
+{
+	d->pll_addr = 0x60;
+	d->pll_desc = &dvb_pll_env57h1xd5;
+	return 0;
+}
+EXPORT_SYMBOL(dibusb_dib3000mc_tuner_attach);
+
+/*
+ * common remote control stuff
+ */
+struct dvb_usb_rc_key dibusb_rc_keys[] = {
+	/* Key codes for the little Artec T1/Twinhan/HAMA/ remote. */
+	{ 0x00, 0x16, KEY_POWER },
+	{ 0x00, 0x10, KEY_MUTE },
+	{ 0x00, 0x03, KEY_1 },
+	{ 0x00, 0x01, KEY_2 },
+	{ 0x00, 0x06, KEY_3 },
+	{ 0x00, 0x09, KEY_4 },
+	{ 0x00, 0x1d, KEY_5 },
+	{ 0x00, 0x1f, KEY_6 },
+	{ 0x00, 0x0d, KEY_7 },
+	{ 0x00, 0x19, KEY_8 },
+	{ 0x00, 0x1b, KEY_9 },
+	{ 0x00, 0x15, KEY_0 },
+	{ 0x00, 0x05, KEY_CHANNELUP },
+	{ 0x00, 0x02, KEY_CHANNELDOWN },
+	{ 0x00, 0x1e, KEY_VOLUMEUP },
+	{ 0x00, 0x0a, KEY_VOLUMEDOWN },
+	{ 0x00, 0x11, KEY_RECORD },
+	{ 0x00, 0x17, KEY_FAVORITES }, /* Heart symbol - Channel list. */
+	{ 0x00, 0x14, KEY_PLAY },
+	{ 0x00, 0x1a, KEY_STOP },
+	{ 0x00, 0x40, KEY_REWIND },
+	{ 0x00, 0x12, KEY_FASTFORWARD },
+	{ 0x00, 0x0e, KEY_PREVIOUS }, /* Recall - Previous channel. */
+	{ 0x00, 0x4c, KEY_PAUSE },
+	{ 0x00, 0x4d, KEY_SCREEN }, /* Full screen mode. */
+	{ 0x00, 0x54, KEY_AUDIO }, /* MTS - Switch to secondary audio. */
+	/* additional keys TwinHan VisionPlus, the Artec seemingly not have */
+	{ 0x00, 0x0c, KEY_CANCEL }, /* Cancel */
+	{ 0x00, 0x1c, KEY_EPG }, /* EPG */
+	{ 0x00, 0x00, KEY_TAB }, /* Tab */
+	{ 0x00, 0x48, KEY_INFO }, /* Preview */
+	{ 0x00, 0x04, KEY_LIST }, /* RecordList */
+	{ 0x00, 0x0f, KEY_TEXT }, /* Teletext */
+	/* Key codes for the KWorld/ADSTech/JetWay remote. */
+	{ 0x86, 0x12, KEY_POWER },
+	{ 0x86, 0x0f, KEY_SELECT }, /* source */
+	{ 0x86, 0x0c, KEY_UNKNOWN }, /* scan */
+	{ 0x86, 0x0b, KEY_EPG },
+	{ 0x86, 0x10, KEY_MUTE },
+	{ 0x86, 0x01, KEY_1 },
+	{ 0x86, 0x02, KEY_2 },
+	{ 0x86, 0x03, KEY_3 },
+	{ 0x86, 0x04, KEY_4 },
+	{ 0x86, 0x05, KEY_5 },
+	{ 0x86, 0x06, KEY_6 },
+	{ 0x86, 0x07, KEY_7 },
+	{ 0x86, 0x08, KEY_8 },
+	{ 0x86, 0x09, KEY_9 },
+	{ 0x86, 0x0a, KEY_0 },
+	{ 0x86, 0x18, KEY_ZOOM },
+	{ 0x86, 0x1c, KEY_UNKNOWN }, /* preview */
+	{ 0x86, 0x13, KEY_UNKNOWN }, /* snap */
+	{ 0x86, 0x00, KEY_UNDO },
+	{ 0x86, 0x1d, KEY_RECORD },
+	{ 0x86, 0x0d, KEY_STOP },
+	{ 0x86, 0x0e, KEY_PAUSE },
+	{ 0x86, 0x16, KEY_PLAY },
+	{ 0x86, 0x11, KEY_BACK },
+	{ 0x86, 0x19, KEY_FORWARD },
+	{ 0x86, 0x14, KEY_UNKNOWN }, /* pip */
+	{ 0x86, 0x15, KEY_ESC },
+	{ 0x86, 0x1a, KEY_UP },
+	{ 0x86, 0x1e, KEY_DOWN },
+	{ 0x86, 0x1f, KEY_LEFT },
+	{ 0x86, 0x1b, KEY_RIGHT },
+};
+EXPORT_SYMBOL(dibusb_rc_keys);
+
+int dibusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
+{
+	u8 key[5],cmd = DIBUSB_REQ_POLL_REMOTE;
+	dvb_usb_generic_rw(d,&cmd,1,key,5,0);
+	dvb_usb_nec_rc_key_to_event(d,key,event,state);
+	if (key[0] != 0)
+		deb_info("key: %x %x %x %x %x\n",key[0],key[1],key[2],key[3],key[4]);
+	return 0;
+}
+EXPORT_SYMBOL(dibusb_rc_query);
diff --git a/drivers/media/dvb/dvb-usb/dibusb-mb.c b/drivers/media/dvb/dvb-usb/dibusb-mb.c
new file mode 100644
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dibusb-mb.c
@@ -0,0 +1,350 @@
+/* DVB USB compliant linux driver for mobile DVB-T USB devices based on
+ * reference designs made by DiBcom (http://www.dibcom.fr/) (DiB3000M-B)
+ *
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ *
+ * based on GPL code from DiBcom, which has
+ * Copyright (C) 2004 Amaury Demol for DiBcom (ademol@dibcom.fr)
+ *
+ *	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, version 2.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+#include "dibusb.h"
+
+static int dibusb_dib3000mb_frontend_attach(struct dvb_usb_device *d)
+{
+	struct dib3000_config demod_cfg;
+	struct dibusb_state *st = d->priv;
+
+	demod_cfg.demod_address = 0x8;
+	demod_cfg.pll_set = dvb_usb_pll_set_i2c;
+	demod_cfg.pll_init = dvb_usb_pll_init_i2c;
+
+	if ((d->fe = dib3000mb_attach(&demod_cfg,&d->i2c_adap,&st->ops)) == NULL)
+		return -ENODEV;
+
+	d->tuner_pass_ctrl = st->ops.tuner_pass_ctrl;
+
+	return 0;
+}
+
+static int dibusb_thomson_tuner_attach(struct dvb_usb_device *d)
+{
+	d->pll_addr = 0x61;
+	d->pll_desc = &dvb_pll_tua6010xs;
+	return 0;
+}
+
+/* Some of the Artec 1.1 device aren't equipped with the default tuner
+ * (Thomson Cable), but with a Panasonic ENV77H11D5.  This function figures
+ * this out. */
+static int dibusb_tuner_probe_and_attach(struct dvb_usb_device *d)
+{
+	u8 b[2] = { 0,0 }, b2[1];
+	int ret = 0;
+	struct i2c_msg msg[2] = {
+		{ .flags = 0,        .buf = b,  .len = 2 },
+		{ .flags = I2C_M_RD, .buf = b2, .len = 1 },
+	};
+
+	/* the Panasonic sits on I2C addrass 0x60, the Thomson on 0x61 */
+	msg[0].addr = msg[1].addr = 0x60;
+
+	if (d->tuner_pass_ctrl)
+		d->tuner_pass_ctrl(d->fe,1,msg[0].addr);
+
+	if (i2c_transfer (&d->i2c_adap, msg, 2) != 2) {
+		err("tuner i2c write failed.");
+		ret = -EREMOTEIO;
+	}
+
+	if (d->tuner_pass_ctrl)
+		d->tuner_pass_ctrl(d->fe,0,msg[0].addr);
+
+	if (b2[0] == 0xfe) {
+		info("this device has the Thomson Cable onboard. Which is default.");
+		dibusb_thomson_tuner_attach(d);
+	} else {
+		u8 bpll[4] = { 0x0b, 0xf5, 0x85, 0xab };
+		info("this device has the Panasonic ENV77H11D5 onboard.");
+		d->pll_addr = 0x60;
+		memcpy(d->pll_init,bpll,4);
+		d->pll_desc = &dvb_pll_tda665x;
+	}
+
+	return ret;
+}
+
+/* USB Driver stuff */
+static struct dvb_usb_properties dibusb1_1_properties;
+static struct dvb_usb_properties dibusb1_1_an2235_properties;
+static struct dvb_usb_properties dibusb2_0b_properties;
+
+static int dibusb_probe(struct usb_interface *intf,
+		const struct usb_device_id *id)
+{
+	if (dvb_usb_device_init(intf,&dibusb1_1_properties,THIS_MODULE) == 0 ||
+		dvb_usb_device_init(intf,&dibusb1_1_an2235_properties,THIS_MODULE) == 0 ||
+		dvb_usb_device_init(intf,&dibusb2_0b_properties,THIS_MODULE) == 0)
+		return 0;
+
+	return -EINVAL;
+}
+
+/* do not change the order of the ID table */
+static struct usb_device_id dibusb_dib3000mb_table [] = {
+/* 00 */	{ USB_DEVICE(USB_VID_WIDEVIEW,		USB_PID_AVERMEDIA_DVBT_USB_COLD)},
+/* 01 */	{ USB_DEVICE(USB_VID_WIDEVIEW,		USB_PID_AVERMEDIA_DVBT_USB_WARM)},
+/* 02 */	{ USB_DEVICE(USB_VID_COMPRO,		USB_PID_COMPRO_DVBU2000_COLD) },
+/* 03 */	{ USB_DEVICE(USB_VID_COMPRO,		USB_PID_COMPRO_DVBU2000_WARM) },
+/* 04 */	{ USB_DEVICE(USB_VID_COMPRO_UNK,	USB_PID_COMPRO_DVBU2000_UNK_COLD) },
+/* 05 */	{ USB_DEVICE(USB_VID_DIBCOM,		USB_PID_DIBCOM_MOD3000_COLD) },
+/* 06 */	{ USB_DEVICE(USB_VID_DIBCOM,		USB_PID_DIBCOM_MOD3000_WARM) },
+/* 07 */	{ USB_DEVICE(USB_VID_EMPIA,			USB_PID_KWORLD_VSTREAM_COLD) },
+/* 08 */	{ USB_DEVICE(USB_VID_EMPIA,			USB_PID_KWORLD_VSTREAM_WARM) },
+/* 09 */	{ USB_DEVICE(USB_VID_GRANDTEC,		USB_PID_GRANDTEC_DVBT_USB_COLD) },
+/* 10 */	{ USB_DEVICE(USB_VID_GRANDTEC,		USB_PID_GRANDTEC_DVBT_USB_WARM) },
+/* 11 */	{ USB_DEVICE(USB_VID_GRANDTEC,		USB_PID_DIBCOM_MOD3000_COLD) },
+/* 12 */	{ USB_DEVICE(USB_VID_GRANDTEC,		USB_PID_DIBCOM_MOD3000_WARM) },
+/* 13 */	{ USB_DEVICE(USB_VID_HYPER_PALTEK,	USB_PID_UNK_HYPER_PALTEK_COLD) },
+/* 14 */	{ USB_DEVICE(USB_VID_HYPER_PALTEK,	USB_PID_UNK_HYPER_PALTEK_WARM) },
+/* 15 */	{ USB_DEVICE(USB_VID_VISIONPLUS,	USB_PID_TWINHAN_VP7041_COLD) },
+/* 16 */	{ USB_DEVICE(USB_VID_VISIONPLUS,	USB_PID_TWINHAN_VP7041_WARM) },
+/* 17 */	{ USB_DEVICE(USB_VID_TWINHAN,		USB_PID_TWINHAN_VP7041_COLD) },
+/* 18 */	{ USB_DEVICE(USB_VID_TWINHAN,		USB_PID_TWINHAN_VP7041_WARM) },
+/* 19 */	{ USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_COLD) },
+/* 20 */	{ USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_WARM) },
+/* 21 */	{ USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_AN2235_COLD) },
+/* 22 */	{ USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_AN2235_WARM) },
+/* 23 */	{ USB_DEVICE(USB_VID_ADSTECH,		USB_PID_ADSTECH_USB2_COLD) },
+
+/* device ID with default DIBUSB2_0-firmware and with the hacked firmware */
+/* 24 */	{ USB_DEVICE(USB_VID_ADSTECH,		USB_PID_ADSTECH_USB2_WARM) },
+/* 25 */	{ USB_DEVICE(USB_VID_KYE,			USB_PID_KYE_DVB_T_COLD) },
+/* 26 */	{ USB_DEVICE(USB_VID_KYE,			USB_PID_KYE_DVB_T_WARM) },
+
+// #define DVB_USB_DIBUSB_MB_FAULTY_USB_IDs
+
+#ifdef DVB_USB_DIBUSB_MB_FAULTY_USB_IDs
+/* 27 */	{ USB_DEVICE(USB_VID_ANCHOR,		USB_PID_ULTIMA_TVBOX_ANCHOR_COLD) },
+#endif
+			{ }		/* Terminating entry */
+};
+MODULE_DEVICE_TABLE (usb, dibusb_dib3000mb_table);
+
+static struct dvb_usb_properties dibusb1_1_properties = {
+	.caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER,
+	.pid_filter_count = 16,
+
+	.usb_ctrl = CYPRESS_AN2135,
+
+	.firmware = "dvb-usb-dibusb-5.0.0.11.fw",
+
+	.size_of_priv     = sizeof(struct dibusb_state),
+
+	.streaming_ctrl   = dibusb_streaming_ctrl,
+	.pid_filter       = dibusb_pid_filter,
+	.pid_filter_ctrl  = dibusb_pid_filter_ctrl,
+	.power_ctrl       = dibusb_power_ctrl,
+	.frontend_attach  = dibusb_dib3000mb_frontend_attach,
+	.tuner_attach     = dibusb_tuner_probe_and_attach,
+
+	.rc_interval      = DEFAULT_RC_INTERVAL,
+	.rc_key_map       = dibusb_rc_keys,
+	.rc_key_map_size  = 63, /* wow, that is ugly ... I want to load it to the driver dynamically */
+	.rc_query         = dibusb_rc_query,
+
+	.i2c_algo         = &dibusb_i2c_algo,
+
+	.generic_bulk_ctrl_endpoint = 0x01,
+	/* parameter for the MPEG2-data transfer */
+	.urb = {
+		.type = DVB_USB_BULK,
+		.count = 7,
+		.endpoint = 0x02,
+		.u = {
+			.bulk = {
+				.buffersize = 4096,
+			}
+		}
+	},
+
+	.num_device_descs = 9,
+	.devices = {
+		{	"AVerMedia AverTV DVBT USB1.1",
+			{ &dibusb_dib3000mb_table[0],  NULL },
+			{ &dibusb_dib3000mb_table[1],  NULL },
+		},
+		{	"Compro Videomate DVB-U2000 - DVB-T USB1.1 (please confirm to linux-dvb)",
+			{ &dibusb_dib3000mb_table[2], &dibusb_dib3000mb_table[4], NULL},
+			{ &dibusb_dib3000mb_table[3], NULL },
+		},
+		{	"DiBcom USB1.1 DVB-T reference design (MOD3000)",
+			{ &dibusb_dib3000mb_table[5],  NULL },
+			{ &dibusb_dib3000mb_table[6],  NULL },
+		},
+		{	"KWorld V-Stream XPERT DTV - DVB-T USB1.1",
+			{ &dibusb_dib3000mb_table[7], NULL },
+			{ &dibusb_dib3000mb_table[8], NULL },
+		},
+		{	"Grandtec USB1.1 DVB-T",
+			{ &dibusb_dib3000mb_table[9],  &dibusb_dib3000mb_table[11], NULL },
+			{ &dibusb_dib3000mb_table[10], &dibusb_dib3000mb_table[12], NULL },
+		},
+		{	"Unkown USB1.1 DVB-T device ???? please report the name to the author",
+			{ &dibusb_dib3000mb_table[13], NULL },
+			{ &dibusb_dib3000mb_table[14], NULL },
+		},
+		{	"TwinhanDTV USB-Ter USB1.1 / Magic Box I / HAMA USB1.1 DVB-T device",
+			{ &dibusb_dib3000mb_table[15], &dibusb_dib3000mb_table[17], NULL},
+			{ &dibusb_dib3000mb_table[16], &dibusb_dib3000mb_table[18], NULL},
+		},
+		{	"Artec T1 USB1.1 TVBOX with AN2135",
+			{ &dibusb_dib3000mb_table[19], NULL },
+			{ &dibusb_dib3000mb_table[20], NULL },
+		},
+		{	"VideoWalker DVB-T USB",
+			{ &dibusb_dib3000mb_table[25], NULL },
+			{ &dibusb_dib3000mb_table[26], NULL },
+		},
+	}
+};
+
+static struct dvb_usb_properties dibusb1_1_an2235_properties = {
+	.caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER,
+	.pid_filter_count = 16,
+
+	.usb_ctrl = CYPRESS_AN2235,
+
+	.firmware = "dvb-usb-dibusb-an2235-01.fw",
+
+	.size_of_priv     = sizeof(struct dibusb_state),
+
+	.streaming_ctrl   = dibusb_streaming_ctrl,
+	.pid_filter       = dibusb_pid_filter,
+	.pid_filter_ctrl  = dibusb_pid_filter_ctrl,
+	.power_ctrl       = dibusb_power_ctrl,
+	.frontend_attach  = dibusb_dib3000mb_frontend_attach,
+	.tuner_attach     = dibusb_tuner_probe_and_attach,
+
+	.rc_interval      = DEFAULT_RC_INTERVAL,
+	.rc_key_map       = dibusb_rc_keys,
+	.rc_key_map_size  = 63, /* wow, that is ugly ... I want to load it to the driver dynamically */
+	.rc_query         = dibusb_rc_query,
+
+	.i2c_algo         = &dibusb_i2c_algo,
+
+	.generic_bulk_ctrl_endpoint = 0x01,
+	/* parameter for the MPEG2-data transfer */
+	.urb = {
+		.type = DVB_USB_BULK,
+		.count = 7,
+		.endpoint = 0x02,
+		.u = {
+			.bulk = {
+				.buffersize = 4096,
+			}
+		}
+	},
+
+#ifdef DVB_USB_DIBUSB_MB_FAULTY_USB_IDs
+	.num_device_descs = 2,
+#else
+	.num_device_descs = 1,
+#endif
+	.devices = {
+		{	"Artec T1 USB1.1 TVBOX with AN2235",
+			{ &dibusb_dib3000mb_table[20], NULL },
+			{ &dibusb_dib3000mb_table[21], NULL },
+		},
+#ifdef DVB_USB_DIBUSB_MB_FAULTY_USB_IDs
+		{	"Artec T1 USB1.1 TVBOX with AN2235 (faulty USB IDs)",
+			{ &dibusb_dib3000mb_table[27], NULL },
+			{ NULL },
+		},
+#endif
+	}
+};
+
+static struct dvb_usb_properties dibusb2_0b_properties = {
+	.caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER,
+	.pid_filter_count = 32,
+
+	.usb_ctrl = CYPRESS_FX2,
+
+	.firmware = "dvb-usb-adstech-usb2-02.fw",
+
+	.size_of_priv     = sizeof(struct dibusb_state),
+
+	.streaming_ctrl   = dibusb2_0_streaming_ctrl,
+	.pid_filter       = dibusb_pid_filter,
+	.pid_filter_ctrl  = dibusb_pid_filter_ctrl,
+	.power_ctrl       = dibusb2_0_power_ctrl,
+	.frontend_attach  = dibusb_dib3000mb_frontend_attach,
+	.tuner_attach     = dibusb_thomson_tuner_attach,
+
+	.rc_interval      = DEFAULT_RC_INTERVAL,
+	.rc_key_map       = dibusb_rc_keys,
+	.rc_key_map_size  = 63, /* wow, that is ugly ... I want to load it to the driver dynamically */
+	.rc_query         = dibusb_rc_query,
+
+	.i2c_algo         = &dibusb_i2c_algo,
+
+	.generic_bulk_ctrl_endpoint = 0x01,
+	/* parameter for the MPEG2-data transfer */
+	.urb = {
+		.type = DVB_USB_BULK,
+		.count = 7,
+		.endpoint = 0x06,
+		.u = {
+			.bulk = {
+				.buffersize = 4096,
+			}
+		}
+	},
+
+	.num_device_descs = 1,
+	.devices = {
+		{	"KWorld/ADSTech Instant DVB-T USB 2.0",
+			{ &dibusb_dib3000mb_table[23], NULL },
+			{ &dibusb_dib3000mb_table[24], NULL },
+		},
+	}
+};
+
+static struct usb_driver dibusb_driver = {
+	.owner		= THIS_MODULE,
+	.name		= "dvb_usb_dibusb_mb",
+	.probe		= dibusb_probe,
+	.disconnect = dvb_usb_device_exit,
+	.id_table	= dibusb_dib3000mb_table,
+};
+
+/* module stuff */
+static int __init dibusb_module_init(void)
+{
+	int result;
+	if ((result = usb_register(&dibusb_driver))) {
+		err("usb_register failed. Error number %d",result);
+		return result;
+	}
+
+	return 0;
+}
+
+static void __exit dibusb_module_exit(void)
+{
+	/* deregister this driver from the USB subsystem */
+	usb_deregister(&dibusb_driver);
+}
+
+module_init (dibusb_module_init);
+module_exit (dibusb_module_exit);
+
+MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
+MODULE_DESCRIPTION("Driver for DiBcom USB DVB-T devices (DiB3000M-B based)");
+MODULE_VERSION("1.0");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/dibusb-mc.c b/drivers/media/dvb/dvb-usb/dibusb-mc.c
new file mode 100644
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dibusb-mc.c
@@ -0,0 +1,116 @@
+/* DVB USB compliant linux driver for mobile DVB-T USB devices based on
+ * reference designs made by DiBcom (http://www.dibcom.fr/) (DiB3000M-C/P)
+ *
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ *
+ * based on GPL code from DiBcom, which has
+ * Copyright (C) 2004 Amaury Demol for DiBcom (ademol@dibcom.fr)
+ *
+ *	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, version 2.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+#include "dibusb.h"
+
+/* USB Driver stuff */
+static struct dvb_usb_properties dibusb_mc_properties;
+
+static int dibusb_mc_probe(struct usb_interface *intf,
+		const struct usb_device_id *id)
+{
+	return dvb_usb_device_init(intf,&dibusb_mc_properties,THIS_MODULE);
+}
+
+/* do not change the order of the ID table */
+static struct usb_device_id dibusb_dib3000mc_table [] = {
+/* 00 */	{ USB_DEVICE(USB_VID_DIBCOM,		USB_PID_DIBCOM_MOD3001_COLD) },
+/* 01 */	{ USB_DEVICE(USB_VID_DIBCOM,		USB_PID_DIBCOM_MOD3001_WARM) },
+/* 02 */	{ USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC,	USB_PID_ULTIMA_TVBOX_USB2_COLD) },
+			{ }		/* Terminating entry */
+};
+MODULE_DEVICE_TABLE (usb, dibusb_dib3000mc_table);
+
+static struct dvb_usb_properties dibusb_mc_properties = {
+	.caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER,
+	.pid_filter_count = 32,
+
+	.usb_ctrl = CYPRESS_FX2,
+	.firmware = "dvb-usb-dibusb-6.0.0.8.fw",
+
+	.size_of_priv     = sizeof(struct dibusb_state),
+
+	.streaming_ctrl   = dibusb2_0_streaming_ctrl,
+	.pid_filter       = dibusb_pid_filter,
+	.pid_filter_ctrl  = dibusb_pid_filter_ctrl,
+	.power_ctrl       = dibusb2_0_power_ctrl,
+	.frontend_attach  = dibusb_dib3000mc_frontend_attach,
+	.tuner_attach     = dibusb_dib3000mc_tuner_attach,
+
+	.rc_interval      = DEFAULT_RC_INTERVAL,
+	.rc_key_map       = dibusb_rc_keys,
+	.rc_key_map_size  = 63, /* FIXME */
+	.rc_query         = dibusb_rc_query,
+
+	.i2c_algo         = &dibusb_i2c_algo,
+
+	.generic_bulk_ctrl_endpoint = 0x01,
+	/* parameter for the MPEG2-data transfer */
+	.urb = {
+		.type = DVB_USB_BULK,
+		.count = 7,
+		.endpoint = 0x06,
+		.u = {
+			.bulk = {
+				.buffersize = 4096,
+			}
+		}
+	},
+
+	.num_device_descs = 2,
+	.devices = {
+		{   "DiBcom USB2.0 DVB-T reference design (MOD3000P)",
+			{ &dibusb_dib3000mc_table[0], NULL },
+			{ &dibusb_dib3000mc_table[1], NULL },
+		},
+		{   "Artec T1 USB2.0 TVBOX (please report the warm ID)",
+			{ &dibusb_dib3000mc_table[2], NULL },
+			{ NULL },
+		},
+	}
+};
+
+static struct usb_driver dibusb_mc_driver = {
+	.owner		= THIS_MODULE,
+	.name		= "dvb_usb_dibusb_mc",
+	.probe		= dibusb_mc_probe,
+	.disconnect = dvb_usb_device_exit,
+	.id_table	= dibusb_dib3000mc_table,
+};
+
+/* module stuff */
+static int __init dibusb_mc_module_init(void)
+{
+	int result;
+	if ((result = usb_register(&dibusb_mc_driver))) {
+		err("usb_register failed. Error number %d",result);
+		return result;
+	}
+
+	return 0;
+}
+
+static void __exit dibusb_mc_module_exit(void)
+{
+	/* deregister this driver from the USB subsystem */
+	usb_deregister(&dibusb_mc_driver);
+}
+
+module_init (dibusb_mc_module_init);
+module_exit (dibusb_mc_module_exit);
+
+MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
+MODULE_DESCRIPTION("Driver for DiBcom USB2.0 DVB-T (DiB3000M-C/P based) devices");
+MODULE_VERSION("1.0");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/dibusb.h b/drivers/media/dvb/dvb-usb/dibusb.h
new file mode 100644
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dibusb.h
@@ -0,0 +1,122 @@
+/* Header file for all dibusb-based-receivers.
+ *
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ *
+ *	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, version 2.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+#ifndef _DVB_USB_DIBUSB_H_
+#define _DVB_USB_DIBUSB_H_
+
+#define DVB_USB_LOG_PREFIX "dibusb"
+#include "dvb-usb.h"
+
+#include "dib3000.h"
+
+/*
+ * protocol of all dibusb related devices
+ */
+
+/*
+ * bulk msg to/from endpoint 0x01
+ *
+ * general structure:
+ * request_byte parameter_bytes
+ */
+
+#define DIBUSB_REQ_START_READ			0x00
+#define DIBUSB_REQ_START_DEMOD			0x01
+
+/*
+ * i2c read
+ * bulk write: 0x02 ((7bit i2c_addr << 1) & 0x01) register_bytes length_word
+ * bulk read:  byte_buffer (length_word bytes)
+ */
+#define DIBUSB_REQ_I2C_READ			0x02
+
+/*
+ * i2c write
+ * bulk write: 0x03 (7bit i2c_addr << 1) register_bytes value_bytes
+ */
+#define DIBUSB_REQ_I2C_WRITE			0x03
+
+/*
+ * polling the value of the remote control
+ * bulk write: 0x04
+ * bulk read:  byte_buffer (5 bytes)
+ */
+#define DIBUSB_REQ_POLL_REMOTE       0x04
+
+/* additional status values for Hauppauge Remote Control Protocol */
+#define DIBUSB_RC_HAUPPAUGE_KEY_PRESSED	0x01
+#define DIBUSB_RC_HAUPPAUGE_KEY_EMPTY	0x03
+
+/* streaming mode:
+ * bulk write: 0x05 mode_byte
+ *
+ * mode_byte is mostly 0x00
+ */
+#define DIBUSB_REQ_SET_STREAMING_MODE	0x05
+
+/* interrupt the internal read loop, when blocking */
+#define DIBUSB_REQ_INTR_READ			0x06
+
+/* io control
+ * 0x07 cmd_byte param_bytes
+ *
+ * param_bytes can be up to 32 bytes
+ *
+ * cmd_byte function    parameter name
+ * 0x00     power mode
+ *                      0x00      sleep
+ *                      0x01      wakeup
+ *
+ * 0x01     enable streaming
+ * 0x02     disable streaming
+ *
+ *
+ */
+#define DIBUSB_REQ_SET_IOCTL			0x07
+
+/* IOCTL commands */
+
+/* change the power mode in firmware */
+#define DIBUSB_IOCTL_CMD_POWER_MODE		0x00
+#define DIBUSB_IOCTL_POWER_SLEEP			0x00
+#define DIBUSB_IOCTL_POWER_WAKEUP			0x01
+
+/* modify streaming of the FX2 */
+#define DIBUSB_IOCTL_CMD_ENABLE_STREAM	0x01
+#define DIBUSB_IOCTL_CMD_DISABLE_STREAM	0x02
+
+struct dibusb_state {
+	struct dib_fe_xfer_ops ops;
+
+	/* for RC5 remote control */
+	int old_toggle;
+	int last_repeat_count;
+};
+
+extern struct i2c_algorithm dibusb_i2c_algo;
+
+extern int dibusb_dib3000mc_frontend_attach(struct dvb_usb_device *);
+extern int dibusb_dib3000mc_tuner_attach (struct dvb_usb_device *);
+
+extern int dibusb_streaming_ctrl(struct dvb_usb_device *, int);
+extern int dibusb_pid_filter(struct dvb_usb_device *, int, u16, int);
+extern int dibusb_pid_filter_ctrl(struct dvb_usb_device *, int);
+extern int dibusb_power_ctrl(struct dvb_usb_device *, int);
+extern int dibusb2_0_streaming_ctrl(struct dvb_usb_device *, int);
+extern int dibusb2_0_power_ctrl(struct dvb_usb_device *, int);
+
+#define DEFAULT_RC_INTERVAL 150
+//#define DEFAULT_RC_INTERVAL 100000
+
+extern struct dvb_usb_rc_key dibusb_rc_keys[];
+extern int dibusb_rc_query(struct dvb_usb_device *, u32 *, int *);
+extern int dibusb_read_eeprom_byte(struct dvb_usb_device *, u8, u8 *);
+
+#endif
diff --git a/drivers/media/dvb/dvb-usb/digitv.c b/drivers/media/dvb/dvb-usb/digitv.c
new file mode 100644
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/digitv.c
@@ -0,0 +1,261 @@
+/* DVB USB compliant linux driver for Nebula Electronics uDigiTV DVB-T USB2.0
+ * receiver
+ *
+ * Copyright (C) 2005 Patrick Boettcher (patrick.boettcher@desy.de)
+ *
+ * partly based on the SDK published by Nebula Electronics
+ *
+ *	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, version 2.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+#include "digitv.h"
+
+#include "mt352.h"
+#include "nxt6000.h"
+
+/* debug */
+int dvb_usb_digitv_debug;
+module_param_named(debug,dvb_usb_digitv_debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS);
+
+static int digitv_ctrl_msg(struct dvb_usb_device *d,
+		u8 cmd, u8 vv, u8 *wbuf, int wlen, u8 *rbuf, int rlen)
+{
+	int wo = (rbuf == NULL || rlen == 0); /* write-only */
+	u8 sndbuf[7],rcvbuf[7];
+	memset(sndbuf,0,7); memset(rcvbuf,0,7);
+
+	sndbuf[0] = cmd;
+	sndbuf[1] = vv;
+	sndbuf[2] = wo ? wlen : rlen;
+
+	if (!wo) {
+		memcpy(&sndbuf[3],wbuf,wlen);
+		dvb_usb_generic_write(d,sndbuf,7);
+	} else {
+		dvb_usb_generic_rw(d,sndbuf,7,rcvbuf,7,10);
+		memcpy(rbuf,&rcvbuf[3],rlen);
+	}
+	return 0;
+}
+
+/* I2C */
+static int digitv_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num)
+{
+	struct dvb_usb_device *d = i2c_get_adapdata(adap);
+	int i;
+
+	if (down_interruptible(&d->i2c_sem) < 0)
+		return -EAGAIN;
+
+	if (num > 2)
+		warn("more than 2 i2c messages at a time is not handled yet. TODO.");
+
+	for (i = 0; i < num; i++) {
+		/* write/read request */
+		if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) {
+			if (digitv_ctrl_msg(d, USB_READ_COFDM, msg[i].buf[0], NULL, 0,
+						msg[i+1].buf,msg[i+1].len) < 0)
+				break;
+			i++;
+		} else
+			if (digitv_ctrl_msg(d,USB_WRITE_COFDM, msg[i].buf[0],
+						&msg[i].buf[1],msg[i].len-1,NULL,0) < 0)
+				break;
+	}
+
+	up(&d->i2c_sem);
+	return i;
+}
+
+static u32 digitv_i2c_func(struct i2c_adapter *adapter)
+{
+	return I2C_FUNC_I2C;
+}
+
+static struct i2c_algorithm digitv_i2c_algo = {
+	.name          = "Nebula DigiTV USB I2C algorithm",
+	.id            = I2C_ALGO_BIT,
+	.master_xfer   = digitv_i2c_xfer,
+	.functionality = digitv_i2c_func,
+};
+
+/* Callbacks for DVB USB */
+static int digitv_identify_state (struct usb_device *udev, struct
+		dvb_usb_properties *props, struct dvb_usb_device_description **desc,
+		int *cold)
+{
+	*cold = udev->descriptor.iManufacturer == 0 && udev->descriptor.iProduct == 0;
+	return 0;
+}
+
+static int digitv_mt352_demod_init(struct dvb_frontend *fe)
+{
+	static u8 reset_buf[] = { 0x89, 0x38,  0x8a, 0x2d, 0x50, 0x80 };
+	static u8 init_buf[] = { 0x68, 0xa0,  0x8e, 0x40,  0x53, 0x50,
+			0x67, 0x20,  0x7d, 0x01,  0x7c, 0x00,  0x7a, 0x00,
+			0x79, 0x20,  0x57, 0x05,  0x56, 0x31,  0x88, 0x0f,
+			0x75, 0x32 };
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(reset_buf); i += 2)
+		mt352_write(fe, &reset_buf[i], 2);
+
+	msleep(1);
+
+	for (i = 0; i < ARRAY_SIZE(init_buf); i += 2)
+		mt352_write(fe, &init_buf[i], 2);
+
+	return 0;
+}
+
+static struct mt352_config digitv_mt352_config = {
+	.demod_address = 0x0, /* ignored by the digitv anyway */
+	.demod_init = digitv_mt352_demod_init,
+	.pll_set = dvb_usb_pll_set,
+};
+
+static struct nxt6000_config digitv_nxt6000_config = {
+	.demod_address = 0x0, /* ignored by the digitv anyway */
+	.clock_inversion = 0x0,
+
+	.pll_init = NULL,
+	.pll_set = NULL,
+};
+
+static int digitv_frontend_attach(struct dvb_usb_device *d)
+{
+	if ((d->fe = mt352_attach(&digitv_mt352_config, &d->i2c_adap)) != NULL)
+		return 0;
+	if ((d->fe = nxt6000_attach(&digitv_nxt6000_config, &d->i2c_adap)) != NULL) {
+
+		warn("nxt6000 support is not done yet, in fact you are one of the first "
+				"person who wants to use this device in Linux. Please report to "
+				"linux-dvb@linuxtv.org");
+
+		return 0;
+	}
+	return -EIO;
+}
+
+static int digitv_tuner_attach(struct dvb_usb_device *d)
+{
+	d->pll_addr = 0x60;
+	d->pll_desc = &dvb_pll_tded4;
+	return 0;
+}
+
+static struct dvb_usb_rc_key digitv_rc_keys[] = {
+	{ 0x00, 0x16, KEY_POWER }, /* dummy key */
+};
+
+/* TODO is it really the NEC protocol ? */
+int digitv_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
+{
+	u8 key[5];
+
+	digitv_ctrl_msg(d,USB_READ_REMOTE,0,NULL,0,&key[1],4);
+	/* TODO state, maybe it is VV ? */
+	if (key[1] != 0)
+		key[0] = 0x01; /* if something is inside the buffer, simulate key press */
+
+	/* call the universal NEC remote processor, to find out the key's state and event */
+	dvb_usb_nec_rc_key_to_event(d,key,event,state);
+	if (key[0] != 0)
+		deb_rc("key: %x %x %x %x %x\n",key[0],key[1],key[2],key[3],key[4]);
+	return 0;
+}
+
+/* DVB USB Driver stuff */
+static struct dvb_usb_properties digitv_properties;
+
+static int digitv_probe(struct usb_interface *intf,
+		const struct usb_device_id *id)
+{
+	return dvb_usb_device_init(intf,&digitv_properties,THIS_MODULE);
+}
+
+static struct usb_device_id digitv_table [] = {
+		{ USB_DEVICE(USB_VID_ANCHOR, USB_PID_NEBULA_DIGITV) },
+		{ }		/* Terminating entry */
+};
+MODULE_DEVICE_TABLE (usb, digitv_table);
+
+static struct dvb_usb_properties digitv_properties = {
+	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
+
+	.usb_ctrl = CYPRESS_FX2,
+	.firmware = "dvb-usb-digitv-01.fw",
+
+	.size_of_priv     = 0,
+
+	.frontend_attach  = digitv_frontend_attach,
+	.tuner_attach     = digitv_tuner_attach,
+
+	.rc_interval      = 1000,
+	.rc_key_map       = digitv_rc_keys,
+	.rc_key_map_size  = ARRAY_SIZE(digitv_rc_keys),
+	.rc_query         = digitv_rc_query,
+
+	.identify_state   = digitv_identify_state,
+
+	.i2c_algo         = &digitv_i2c_algo,
+
+	.generic_bulk_ctrl_endpoint = 0x01,
+	/* parameter for the MPEG2-data transfer */
+	.urb = {
+		.type = DVB_USB_BULK,
+		.count = 7,
+		.endpoint = 0x02,
+		.u = {
+			.bulk = {
+				.buffersize = 4096,
+			}
+		}
+	},
+
+	.num_device_descs = 1,
+	.devices = {
+		{   "Nebula Electronics uDigiTV DVB-T USB2.0)",
+			{ &digitv_table[0], NULL },
+			{ NULL },
+		},
+	}
+};
+
+static struct usb_driver digitv_driver = {
+	.owner		= THIS_MODULE,
+	.name		= "dvb_usb_digitv",
+	.probe		= digitv_probe,
+	.disconnect = dvb_usb_device_exit,
+	.id_table	= digitv_table,
+};
+
+/* module stuff */
+static int __init digitv_module_init(void)
+{
+	int result;
+	if ((result = usb_register(&digitv_driver))) {
+		err("usb_register failed. Error number %d",result);
+		return result;
+	}
+
+	return 0;
+}
+
+static void __exit digitv_module_exit(void)
+{
+	/* deregister this driver from the USB subsystem */
+	usb_deregister(&digitv_driver);
+}
+
+module_init (digitv_module_init);
+module_exit (digitv_module_exit);
+
+MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
+MODULE_DESCRIPTION("Driver for Nebula Electronics uDigiTV DVB-T USB2.0");
+MODULE_VERSION("1.0-alpha");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/digitv.h b/drivers/media/dvb/dvb-usb/digitv.h
new file mode 100644
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/digitv.h
@@ -0,0 +1,65 @@
+#ifndef _DVB_USB_DIGITV_H_
+#define _DVB_USB_DIGITV_H_
+
+#define DVB_USB_LOG_PREFIX "digitv"
+#include "dvb-usb.h"
+
+extern int dvb_usb_digitv_debug;
+#define deb_rc(args...)   dprintk(dvb_usb_digitv_debug,0x01,args)
+
+/* protocol (from usblogging and the SDK:
+ *
+ * Always 7 bytes bulk message(s) for controlling
+ *
+ * First byte describes the command. Reads are 2 consecutive transfer (as always).
+ *
+ * General structure:
+ *
+ * write or first message of a read:
+ * <cmdbyte> VV <len> B0 B1 B2 B3
+ *
+ * second message of a read
+ * <cmdbyte> VV <len> R0 R1 R2 R3
+ *
+ * whereas 0 < len <= 4
+ *
+ * I2C address is stored somewhere inside the device.
+ *
+ * 0x01 read from EEPROM
+ *  VV = offset; B* = 0; R* = value(s)
+ *
+ * 0x02 read register of the COFDM
+ *  VV = register; B* = 0; R* = value(s)
+ *
+ * 0x05 write register of the COFDM
+ *  VV = register; B* = value(s);
+ *
+ * 0x06 write to the tuner (only for NXT6000)
+ *  VV = 0; B* = PLL data; len = 4;
+ *
+ * 0x03 read remote control
+ *  VV = 0; B* = 0; len = 4; R* = key
+ *
+ * 0x07 write to the remote (don't know why one should this, resetting ?)
+ *  VV = 0; B* = key; len = 4;
+ *
+ * 0x08 write remote type
+ *  VV = 0; B[0] = 0x01, len = 4
+ *
+ * 0x09 write device init
+ *  TODO
+ */
+#define USB_READ_EEPROM         1
+
+#define USB_READ_COFDM          2
+#define USB_WRITE_COFDM         5
+
+#define USB_WRITE_TUNER         6
+
+#define USB_READ_REMOTE         3
+#define USB_WRITE_REMOTE        7
+#define USB_WRITE_REMOTE_TYPE   8
+
+#define USB_DEV_INIT            9
+
+#endif
diff --git a/drivers/media/dvb/dvb-usb/dtt200u-fe.c b/drivers/media/dvb/dvb-usb/dtt200u-fe.c
new file mode 100644
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dtt200u-fe.c
@@ -0,0 +1,208 @@
+/* Frontend part of the Linux driver for the WideView/ Yakumo/ Hama/
+ * Typhoon/ Yuan DVB-T USB2.0 receiver.
+ *
+ * Copyright (C) 2005 Patrick Boettcher <patrick.boettcher@desy.de>
+ *
+ *	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, version 2.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+#include "dtt200u.h"
+
+struct dtt200u_fe_state {
+	struct dvb_usb_device *d;
+
+	fe_status_t stat;
+
+	struct dvb_frontend_parameters fep;
+	struct dvb_frontend frontend;
+};
+
+static int dtt200u_fe_read_status(struct dvb_frontend* fe, fe_status_t *stat)
+{
+	struct dtt200u_fe_state *state = fe->demodulator_priv;
+	u8 st = GET_TUNE_STATUS, b[3];
+
+	dvb_usb_generic_rw(state->d,&st,1,b,3,0);
+
+	switch (b[0]) {
+		case 0x01:
+			*stat = FE_HAS_SIGNAL | FE_HAS_CARRIER |
+				FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
+			break;
+		case 0x00: /* pending */
+			*stat = FE_TIMEDOUT; /* during set_frontend */
+			break;
+		default:
+		case 0x02: /* failed */
+			*stat = 0;
+			break;
+	}
+	return 0;
+}
+
+static int dtt200u_fe_read_ber(struct dvb_frontend* fe, u32 *ber)
+{
+	struct dtt200u_fe_state *state = fe->demodulator_priv;
+	u8 bw = GET_VIT_ERR_CNT,b[3];
+	dvb_usb_generic_rw(state->d,&bw,1,b,3,0);
+	*ber = (b[0] << 16) | (b[1] << 8) | b[2];
+	return 0;
+}
+
+static int dtt200u_fe_read_unc_blocks(struct dvb_frontend* fe, u32 *unc)
+{
+	struct dtt200u_fe_state *state = fe->demodulator_priv;
+	u8 bw = GET_RS_UNCOR_BLK_CNT,b[2];
+
+	dvb_usb_generic_rw(state->d,&bw,1,b,2,0);
+	*unc = (b[0] << 8) | b[1];
+	return 0;
+}
+
+static int dtt200u_fe_read_signal_strength(struct dvb_frontend* fe, u16 *strength)
+{
+	struct dtt200u_fe_state *state = fe->demodulator_priv;
+	u8 bw = GET_AGC, b;
+	dvb_usb_generic_rw(state->d,&bw,1,&b,1,0);
+	*strength = (b << 8) | b;
+	return 0;
+}
+
+static int dtt200u_fe_read_snr(struct dvb_frontend* fe, u16 *snr)
+{
+	struct dtt200u_fe_state *state = fe->demodulator_priv;
+	u8 bw = GET_SNR,br;
+	dvb_usb_generic_rw(state->d,&bw,1,&br,1,0);
+	*snr = ~((br << 8) | br);
+	return 0;
+}
+
+static int dtt200u_fe_init(struct dvb_frontend* fe)
+{
+	struct dtt200u_fe_state *state = fe->demodulator_priv;
+	u8 b = SET_INIT;
+	return dvb_usb_generic_write(state->d,&b,1);
+}
+
+static int dtt200u_fe_sleep(struct dvb_frontend* fe)
+{
+	return dtt200u_fe_init(fe);
+}
+
+static int dtt200u_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
+{
+	tune->min_delay_ms = 1500;
+	tune->step_size = 0;
+	tune->max_drift = 0;
+	return 0;
+}
+
+static int dtt200u_fe_set_frontend(struct dvb_frontend* fe,
+				  struct dvb_frontend_parameters *fep)
+{
+	struct dtt200u_fe_state *state = fe->demodulator_priv;
+	int i;
+	fe_status_t st;
+	u16 freq = fep->frequency / 250000;
+	u8 bwbuf[2] = { SET_BANDWIDTH, 0 },freqbuf[3] = { SET_RF_FREQ, 0, 0 };
+
+	switch (fep->u.ofdm.bandwidth) {
+		case BANDWIDTH_8_MHZ: bwbuf[1] = 8; break;
+		case BANDWIDTH_7_MHZ: bwbuf[1] = 7; break;
+		case BANDWIDTH_6_MHZ: bwbuf[1] = 6; break;
+		case BANDWIDTH_AUTO: return -EOPNOTSUPP;
+		default:
+			return -EINVAL;
+	}
+
+	dvb_usb_generic_write(state->d,bwbuf,2);
+
+	freqbuf[1] = freq & 0xff;
+	freqbuf[2] = (freq >> 8) & 0xff;
+	dvb_usb_generic_write(state->d,freqbuf,3);
+
+	for (i = 0; i < 30; i++) {
+		msleep(20);
+		dtt200u_fe_read_status(fe, &st);
+		if (st & FE_TIMEDOUT)
+			continue;
+	}
+
+	return 0;
+}
+
+static int dtt200u_fe_get_frontend(struct dvb_frontend* fe,
+				  struct dvb_frontend_parameters *fep)
+{
+	struct dtt200u_fe_state *state = fe->demodulator_priv;
+	memcpy(fep,&state->fep,sizeof(struct dvb_frontend_parameters));
+	return 0;
+}
+
+static void dtt200u_fe_release(struct dvb_frontend* fe)
+{
+	struct dtt200u_fe_state *state = (struct dtt200u_fe_state*) fe->demodulator_priv;
+	kfree(state);
+}
+
+static struct dvb_frontend_ops dtt200u_fe_ops;
+
+struct dvb_frontend* dtt200u_fe_attach(struct dvb_usb_device *d)
+{
+	struct dtt200u_fe_state* state = NULL;
+
+	/* allocate memory for the internal state */
+	state = (struct dtt200u_fe_state*) kmalloc(sizeof(struct dtt200u_fe_state), GFP_KERNEL);
+	if (state == NULL)
+		goto error;
+	memset(state,0,sizeof(struct dtt200u_fe_state));
+
+	deb_info("attaching frontend dtt200u\n");
+
+	state->d = d;
+
+	state->frontend.ops = &dtt200u_fe_ops;
+	state->frontend.demodulator_priv = state;
+
+	goto success;
+error:
+	return NULL;
+success:
+	return &state->frontend;
+}
+
+static struct dvb_frontend_ops dtt200u_fe_ops = {
+	.info = {
+		.name			= "WideView USB DVB-T",
+		.type			= FE_OFDM,
+		.frequency_min		= 44250000,
+		.frequency_max		= 867250000,
+		.frequency_stepsize	= 250000,
+		.caps = FE_CAN_INVERSION_AUTO |
+				FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+				FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+				FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
+				FE_CAN_TRANSMISSION_MODE_AUTO |
+				FE_CAN_GUARD_INTERVAL_AUTO |
+				FE_CAN_RECOVER |
+				FE_CAN_HIERARCHY_AUTO,
+	},
+
+	.release = dtt200u_fe_release,
+
+	.init = dtt200u_fe_init,
+	.sleep = dtt200u_fe_sleep,
+
+	.set_frontend = dtt200u_fe_set_frontend,
+	.get_frontend = dtt200u_fe_get_frontend,
+	.get_tune_settings = dtt200u_fe_get_tune_settings,
+
+	.read_status = dtt200u_fe_read_status,
+	.read_ber = dtt200u_fe_read_ber,
+	.read_signal_strength = dtt200u_fe_read_signal_strength,
+	.read_snr = dtt200u_fe_read_snr,
+	.read_ucblocks = dtt200u_fe_read_unc_blocks,
+};
diff --git a/drivers/media/dvb/dvb-usb/dtt200u.c b/drivers/media/dvb/dvb-usb/dtt200u.c
new file mode 100644
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dtt200u.c
@@ -0,0 +1,233 @@
+/* DVB USB library compliant Linux driver for the WideView/ Yakumo/ Hama/
+ * Typhoon/ Yuan DVB-T USB2.0 receiver.
+ *
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ *
+ * Thanks to Steve Chang from WideView for providing support for the WT-220U.
+ *
+ *	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, version 2.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+#include "dtt200u.h"
+
+/* debug */
+int dvb_usb_dtt200u_debug;
+module_param_named(debug,dvb_usb_dtt200u_debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2 (or-able))." DVB_USB_DEBUG_STATUS);
+
+static int dtt200u_power_ctrl(struct dvb_usb_device *d, int onoff)
+{
+	u8 b = SET_INIT;
+
+	if (onoff)
+		dvb_usb_generic_write(d,&b,2);
+
+	return 0;
+}
+
+static int dtt200u_streaming_ctrl(struct dvb_usb_device *d, int onoff)
+{
+	u8 b_streaming[2] = { SET_STREAMING, onoff };
+	u8 b_rst_pid = RESET_PID_FILTER;
+
+	dvb_usb_generic_write(d,b_streaming,2);
+
+	if (onoff == 0)
+		dvb_usb_generic_write(d,&b_rst_pid,1);
+	return 0;
+}
+
+static int dtt200u_pid_filter(struct dvb_usb_device *d, int index, u16 pid, int onoff)
+{
+	u8 b_pid[4];
+	pid = onoff ? pid : 0;
+
+	b_pid[0] = SET_PID_FILTER;
+	b_pid[1] = index;
+	b_pid[2] = pid & 0xff;
+	b_pid[3] = (pid >> 8) & 0x1f;
+
+	return dvb_usb_generic_write(d,b_pid,4);
+}
+
+/* remote control */
+/* key list for the tiny remote control (Yakumo, don't know about the others) */
+static struct dvb_usb_rc_key dtt200u_rc_keys[] = {
+	{ 0x80, 0x01, KEY_MUTE },
+	{ 0x80, 0x02, KEY_CHANNELDOWN },
+	{ 0x80, 0x03, KEY_VOLUMEDOWN },
+	{ 0x80, 0x04, KEY_1 },
+	{ 0x80, 0x05, KEY_2 },
+	{ 0x80, 0x06, KEY_3 },
+	{ 0x80, 0x07, KEY_4 },
+	{ 0x80, 0x08, KEY_5 },
+	{ 0x80, 0x09, KEY_6 },
+	{ 0x80, 0x0a, KEY_7 },
+	{ 0x80, 0x0c, KEY_ZOOM },
+	{ 0x80, 0x0d, KEY_0 },
+	{ 0x80, 0x0e, KEY_SELECT },
+	{ 0x80, 0x12, KEY_POWER },
+	{ 0x80, 0x1a, KEY_CHANNELUP },
+	{ 0x80, 0x1b, KEY_8 },
+	{ 0x80, 0x1e, KEY_VOLUMEUP },
+	{ 0x80, 0x1f, KEY_9 },
+};
+
+static int dtt200u_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
+{
+	u8 key[5],cmd = GET_RC_CODE;
+	dvb_usb_generic_rw(d,&cmd,1,key,5,0);
+	dvb_usb_nec_rc_key_to_event(d,key,event,state);
+	if (key[0] != 0)
+		deb_info("key: %x %x %x %x %x\n",key[0],key[1],key[2],key[3],key[4]);
+	return 0;
+}
+
+static int dtt200u_frontend_attach(struct dvb_usb_device *d)
+{
+	d->fe = dtt200u_fe_attach(d);
+	return 0;
+}
+
+static struct dvb_usb_properties dtt200u_properties;
+static struct dvb_usb_properties wt220u_properties;
+
+static int dtt200u_usb_probe(struct usb_interface *intf,
+		const struct usb_device_id *id)
+{
+	if (dvb_usb_device_init(intf,&dtt200u_properties,THIS_MODULE) == 0 ||
+		dvb_usb_device_init(intf,&wt220u_properties,THIS_MODULE) == 0)
+		return 0;
+
+	return -ENODEV;
+}
+
+static struct usb_device_id dtt200u_usb_table [] = {
+//		{ USB_DEVICE(0x04b4,0x8613) },
+	    { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_DTT200U_COLD) },
+	    { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_DTT200U_WARM) },
+		{ USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_COLD)  },
+		{ USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_WARM)  },
+	    { 0 },
+};
+MODULE_DEVICE_TABLE(usb, dtt200u_usb_table);
+
+static struct dvb_usb_properties dtt200u_properties = {
+	.caps = DVB_USB_HAS_PID_FILTER | DVB_USB_NEED_PID_FILTERING,
+	.pid_filter_count = 15,
+
+	.usb_ctrl = CYPRESS_FX2,
+	.firmware = "dvb-usb-dtt200u-01.fw",
+
+	.power_ctrl      = dtt200u_power_ctrl,
+	.streaming_ctrl  = dtt200u_streaming_ctrl,
+	.pid_filter      = dtt200u_pid_filter,
+	.frontend_attach = dtt200u_frontend_attach,
+
+	.rc_interval     = 300,
+	.rc_key_map      = dtt200u_rc_keys,
+	.rc_key_map_size = ARRAY_SIZE(dtt200u_rc_keys),
+	.rc_query        = dtt200u_rc_query,
+
+	.generic_bulk_ctrl_endpoint = 0x01,
+
+	/* parameter for the MPEG2-data transfer */
+	.urb = {
+		.type = DVB_USB_BULK,
+		.count = 7,
+		.endpoint = 0x02,
+		.u = {
+			.bulk = {
+				.buffersize = 4096,
+			}
+		}
+	},
+
+	.num_device_descs = 1,
+	.devices = {
+		{ .name = "WideView/Yuan/Yakumo/Hama/Typhoon DVB-T USB2.0 (WT-200U)",
+		  .cold_ids = { &dtt200u_usb_table[0], NULL },
+		  .warm_ids = { &dtt200u_usb_table[1], NULL },
+		},
+		{ 0 },
+	}
+};
+
+static struct dvb_usb_properties wt220u_properties = {
+	.caps = DVB_USB_HAS_PID_FILTER | DVB_USB_NEED_PID_FILTERING,
+	.pid_filter_count = 15,
+
+	.usb_ctrl = CYPRESS_FX2,
+	.firmware = "dvb-usb-wt220u-01.fw",
+
+	.power_ctrl      = dtt200u_power_ctrl,
+	.streaming_ctrl  = dtt200u_streaming_ctrl,
+	.pid_filter      = dtt200u_pid_filter,
+	.frontend_attach = dtt200u_frontend_attach,
+
+	.rc_interval     = 300,
+	.rc_key_map      = dtt200u_rc_keys,
+	.rc_key_map_size = ARRAY_SIZE(dtt200u_rc_keys),
+	.rc_query        = dtt200u_rc_query,
+
+	.generic_bulk_ctrl_endpoint = 0x01,
+
+	/* parameter for the MPEG2-data transfer */
+	.urb = {
+		.type = DVB_USB_BULK,
+		.count = 7,
+		.endpoint = 0x02,
+		.u = {
+			.bulk = {
+				.buffersize = 4096,
+			}
+		}
+	},
+
+	.num_device_descs = 1,
+	.devices = {
+		{ .name = "WideView WT-220U PenType Receiver (and clones)",
+		  .cold_ids = { &dtt200u_usb_table[2], NULL },
+		  .warm_ids = { &dtt200u_usb_table[3], NULL },
+		},
+		{ 0 },
+	}
+};
+
+/* usb specific object needed to register this driver with the usb subsystem */
+static struct usb_driver dtt200u_usb_driver = {
+	.owner		= THIS_MODULE,
+	.name		= "dvb_usb_dtt200u",
+	.probe 		= dtt200u_usb_probe,
+	.disconnect = dvb_usb_device_exit,
+	.id_table 	= dtt200u_usb_table,
+};
+
+/* module stuff */
+static int __init dtt200u_usb_module_init(void)
+{
+	int result;
+	if ((result = usb_register(&dtt200u_usb_driver))) {
+		err("usb_register failed. (%d)",result);
+		return result;
+	}
+
+	return 0;
+}
+
+static void __exit dtt200u_usb_module_exit(void)
+{
+	/* deregister this driver from the USB subsystem */
+	usb_deregister(&dtt200u_usb_driver);
+}
+
+module_init(dtt200u_usb_module_init);
+module_exit(dtt200u_usb_module_exit);
+
+MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
+MODULE_DESCRIPTION("Driver for the WideView/Yakumo/Hama/Typhoon DVB-T USB2.0 devices");
+MODULE_VERSION("1.0");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/dtt200u.h b/drivers/media/dvb/dvb-usb/dtt200u.h
new file mode 100644
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dtt200u.h
@@ -0,0 +1,56 @@
+/* Common header file of Linux driver for the WideView/ Yakumo/ Hama/
+ * Typhoon/ Yuan DVB-T USB2.0 receiver.
+ *
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ *
+ *	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, version 2.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+#ifndef _DVB_USB_DTT200U_H_
+#define _DVB_USB_DTT200U_H_
+
+#define DVB_USB_LOG_PREFIX "dtt200u"
+#include "dvb-usb.h"
+
+extern int dvb_usb_dtt200u_debug;
+#define deb_info(args...) dprintk(dvb_usb_dtt200u_debug,0x01,args)
+#define deb_xfer(args...) dprintk(dvb_usb_dtt200u_debug,0x02,args)
+
+/* guessed protocol description (reverse engineered):
+ * read
+ *  00 - USB type 0x02 for usb2.0, 0x01 for usb1.1
+ *  88 - locking 2 bytes (0x80 0x40 == no signal, 0x89 0x20 == nice signal)
+ */
+
+#define GET_SPEED            0x00
+#define GET_TUNE_STATUS      0x81
+#define GET_RC_CODE          0x84
+#define GET_CONFIGURATION    0x88
+#define GET_AGC              0x89
+#define GET_SNR              0x8a
+#define GET_VIT_ERR_CNT      0x8c
+#define GET_RS_ERR_CNT       0x8d
+#define GET_RS_UNCOR_BLK_CNT 0x8e
+
+/* write
+ *  01 - init
+ *  02 - frequency (divided by 250000)
+ *  03 - bandwidth
+ *  04 - pid table (index pid(7:0) pid(12:8))
+ *  05 - reset the pid table
+ *  08 - transfer switch
+ */
+
+#define SET_INIT         0x01
+#define SET_RF_FREQ      0x02
+#define SET_BANDWIDTH    0x03
+#define SET_PID_FILTER   0x04
+#define RESET_PID_FILTER 0x05
+#define SET_STREAMING    0x08
+
+extern struct dvb_frontend * dtt200u_fe_attach(struct dvb_usb_device *d);
+
+#endif
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-common.h b/drivers/media/dvb/dvb-usb/dvb-usb-common.h
new file mode 100644
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-common.h
@@ -0,0 +1,46 @@
+/* dvb-usb-common.h is part of the DVB USB library.
+ *
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ * see dvb-usb-init.c for copyright information.
+ *
+ * a header file containing prototypes and types for internal use of the dvb-usb-lib
+ */
+#ifndef _DVB_USB_COMMON_H_
+#define _DVB_USB_COMMON_H_
+
+#define DVB_USB_LOG_PREFIX "dvb-usb"
+#include "dvb-usb.h"
+
+extern int dvb_usb_debug;
+extern int dvb_usb_disable_rc_polling;
+
+#define deb_info(args...) dprintk(dvb_usb_debug,0x01,args)
+#define deb_xfer(args...) dprintk(dvb_usb_debug,0x02,args)
+#define deb_pll(args...)  dprintk(dvb_usb_debug,0x04,args)
+#define deb_ts(args...)   dprintk(dvb_usb_debug,0x08,args)
+#define deb_err(args...)  dprintk(dvb_usb_debug,0x10,args)
+#define deb_rc(args...)   dprintk(dvb_usb_debug,0x20,args)
+#define deb_fw(args...)   dprintk(dvb_usb_debug,0x40,args)
+#define deb_mem(args...)  dprintk(dvb_usb_debug,0x80,args)
+
+/* commonly used  methods */
+extern int usb_cypress_load_firmware(struct usb_device *, const char *, int);
+
+extern int dvb_usb_urb_submit(struct dvb_usb_device *);
+extern int dvb_usb_urb_kill(struct dvb_usb_device *);
+extern int dvb_usb_urb_init(struct dvb_usb_device *);
+extern int dvb_usb_urb_exit(struct dvb_usb_device *);
+
+extern int dvb_usb_i2c_init(struct dvb_usb_device *);
+extern int dvb_usb_i2c_exit(struct dvb_usb_device *);
+
+extern int dvb_usb_dvb_init(struct dvb_usb_device *);
+extern int dvb_usb_dvb_exit(struct dvb_usb_device *);
+
+extern int dvb_usb_fe_init(struct dvb_usb_device *);
+extern int dvb_usb_fe_exit(struct dvb_usb_device *);
+
+extern int dvb_usb_remote_init(struct dvb_usb_device *);
+extern int dvb_usb_remote_exit(struct dvb_usb_device *);
+
+#endif
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c b/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c
new file mode 100644
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c
@@ -0,0 +1,211 @@
+/* dvb-usb-dvb.c is part of the DVB USB library.
+ *
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ * see dvb-usb-init.c for copyright information.
+ *
+ * This file contains functions for initializing and handling the
+ * linux-dvb API.
+ */
+#include "dvb-usb-common.h"
+
+static int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, int onoff)
+{
+	struct dvb_usb_device *d = dvbdmxfeed->demux->priv;
+	int newfeedcount,ret;
+
+	if (d == NULL)
+		return -ENODEV;
+
+	newfeedcount = d->feedcount + (onoff ? 1 : -1);
+
+	/*
+	 * stop feed before setting a new pid if there will be no pid anymore
+	 */
+	if (newfeedcount == 0) {
+		deb_ts("stop feeding\n");
+		dvb_usb_urb_kill(d);
+
+		if (d->props.streaming_ctrl != NULL)
+			if ((ret = d->props.streaming_ctrl(d,0)))
+				err("error while stopping stream.");
+
+	}
+
+	d->feedcount = newfeedcount;
+
+	/* activate the pid on the device specific pid_filter */
+	deb_ts("setting pid: %5d %04x at index %d '%s'\n",dvbdmxfeed->pid,dvbdmxfeed->pid,dvbdmxfeed->index,onoff ? "on" : "off");
+	if (d->props.caps & DVB_USB_HAS_PID_FILTER &&
+		d->pid_filtering &&
+		d->props.pid_filter != NULL)
+		d->props.pid_filter(d,dvbdmxfeed->index,dvbdmxfeed->pid,onoff);
+
+	/* start the feed if this was the first feed and there is still a feed
+	 * for reception.
+	 */
+	if (d->feedcount == onoff && d->feedcount > 0) {
+		deb_ts("submitting all URBs\n");
+		dvb_usb_urb_submit(d);
+
+		deb_ts("controlling pid parser\n");
+		if (d->props.caps & DVB_USB_HAS_PID_FILTER &&
+			d->props.caps & DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF &&
+			d->props.pid_filter_ctrl != NULL)
+			if (d->props.pid_filter_ctrl(d,d->pid_filtering) < 0)
+				err("could not handle pid_parser");
+
+		deb_ts("start feeding\n");
+		if (d->props.streaming_ctrl != NULL)
+			if (d->props.streaming_ctrl(d,1)) {
+				err("error while enabling fifo.");
+				return -ENODEV;
+			}
+
+	}
+	return 0;
+}
+
+static int dvb_usb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
+{
+	deb_ts("start pid: 0x%04x, feedtype: %d\n", dvbdmxfeed->pid,dvbdmxfeed->type);
+	return dvb_usb_ctrl_feed(dvbdmxfeed,1);
+}
+
+static int dvb_usb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
+{
+	deb_ts("stop pid: 0x%04x, feedtype: %d\n", dvbdmxfeed->pid, dvbdmxfeed->type);
+	return dvb_usb_ctrl_feed(dvbdmxfeed,0);
+}
+
+int dvb_usb_dvb_init(struct dvb_usb_device *d)
+{
+	int ret;
+
+	if ((ret = dvb_register_adapter(&d->dvb_adap, d->desc->name,
+			d->owner)) < 0) {
+		deb_info("dvb_register_adapter failed: error %d", ret);
+		goto err;
+	}
+	d->dvb_adap.priv = d;
+
+	if (d->props.read_mac_address) {
+		if (d->props.read_mac_address(d,d->dvb_adap.proposed_mac) == 0)
+			info("MAC address: %02x:%02x:%02x:%02x:%02x:%02x",d->dvb_adap.proposed_mac[0],
+					d->dvb_adap.proposed_mac[1],d->dvb_adap.proposed_mac[2],
+					d->dvb_adap.proposed_mac[3],d->dvb_adap.proposed_mac[4],
+					d->dvb_adap.proposed_mac[5]);
+		else
+			err("MAC address reading failed.");
+	}
+
+
+	d->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING;
+	d->demux.priv = d;
+
+	d->demux.feednum = d->demux.filternum = d->max_feed_count;
+	d->demux.start_feed = dvb_usb_start_feed;
+	d->demux.stop_feed  = dvb_usb_stop_feed;
+	d->demux.write_to_decoder = NULL;
+	if ((ret = dvb_dmx_init(&d->demux)) < 0) {
+		err("dvb_dmx_init failed: error %d",ret);
+		goto err_dmx;
+	}
+
+	d->dmxdev.filternum = d->demux.filternum;
+	d->dmxdev.demux = &d->demux.dmx;
+	d->dmxdev.capabilities = 0;
+	if ((ret = dvb_dmxdev_init(&d->dmxdev, &d->dvb_adap)) < 0) {
+		err("dvb_dmxdev_init failed: error %d",ret);
+		goto err_dmx_dev;
+	}
+
+	dvb_net_init(&d->dvb_adap, &d->dvb_net, &d->demux.dmx);
+
+	goto success;
+err_dmx_dev:
+	dvb_dmx_release(&d->demux);
+err_dmx:
+	dvb_unregister_adapter(&d->dvb_adap);
+err:
+	return ret;
+success:
+	d->state |= DVB_USB_STATE_DVB;
+	return 0;
+}
+
+int dvb_usb_dvb_exit(struct dvb_usb_device *d)
+{
+	if (d->state & DVB_USB_STATE_DVB) {
+		deb_info("unregistering DVB part\n");
+		dvb_net_release(&d->dvb_net);
+		d->demux.dmx.close(&d->demux.dmx);
+		dvb_dmxdev_release(&d->dmxdev);
+		dvb_dmx_release(&d->demux);
+		dvb_unregister_adapter(&d->dvb_adap);
+		d->state &= ~DVB_USB_STATE_DVB;
+	}
+	return 0;
+}
+
+static int dvb_usb_fe_wakeup(struct dvb_frontend *fe)
+{
+	struct dvb_usb_device *d = fe->dvb->priv;
+
+	if (d->props.power_ctrl)
+		d->props.power_ctrl(d,1);
+
+	if (d->fe_init)
+		d->fe_init(fe);
+
+	return 0;
+}
+
+static int dvb_usb_fe_sleep(struct dvb_frontend *fe)
+{
+	struct dvb_usb_device *d = fe->dvb->priv;
+
+	if (d->fe_sleep)
+		d->fe_sleep(fe);
+
+	if (d->props.power_ctrl)
+		d->props.power_ctrl(d,0);
+
+	return 0;
+}
+
+int dvb_usb_fe_init(struct dvb_usb_device* d)
+{
+	if (d->props.frontend_attach == NULL) {
+		err("strange '%s' doesn't want to attach a frontend.",d->desc->name);
+		return 0;
+	}
+
+	d->props.frontend_attach(d);
+
+	/* re-assign sleep and wakeup functions */
+	if (d->fe != NULL) {
+		d->fe_init = d->fe->ops->init;   d->fe->ops->init  = dvb_usb_fe_wakeup;
+		d->fe_sleep = d->fe->ops->sleep; d->fe->ops->sleep = dvb_usb_fe_sleep;
+
+		if (dvb_register_frontend(&d->dvb_adap, d->fe)) {
+			err("Frontend registration failed.");
+			if (d->fe->ops->release)
+				d->fe->ops->release(d->fe);
+			d->fe = NULL;
+			return -ENODEV;
+		}
+	} else
+		err("no frontend was attached by '%s'",d->desc->name);
+
+	if (d->props.tuner_attach != NULL)
+		d->props.tuner_attach(d);
+
+	return 0;
+}
+
+int dvb_usb_fe_exit(struct dvb_usb_device *d)
+{
+	if (d->fe != NULL)
+		dvb_unregister_frontend(d->fe);
+	return 0;
+}
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-firmware.c b/drivers/media/dvb/dvb-usb/dvb-usb-firmware.c
new file mode 100644
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-firmware.c
@@ -0,0 +1,100 @@
+/* dvb-usb-firmware.c is part of the DVB USB library.
+ *
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ * see dvb-usb-init.c for copyright information.
+ *
+ * This file contains functions for downloading the firmware to Cypress FX 1 and 2 based devices.
+ *
+ * FIXME: This part does actually not belong to dvb-usb, but to the usb-subsystem.
+ */
+#include "dvb-usb-common.h"
+
+#include <linux/firmware.h>
+#include <linux/usb.h>
+
+struct usb_cypress_controller {
+	int id;
+	const char *name;       /* name of the usb controller */
+	u16 cpu_cs_register;    /* needs to be restarted, when the firmware has been downloaded. */
+};
+
+static struct usb_cypress_controller cypress[] = {
+	{ .id = CYPRESS_AN2135, .name = "Cypress AN2135", .cpu_cs_register = 0x7f92 },
+	{ .id = CYPRESS_AN2235, .name = "Cypress AN2235", .cpu_cs_register = 0x7f92 },
+	{ .id = CYPRESS_FX2,    .name = "Cypress FX2",    .cpu_cs_register = 0xe600 },
+};
+
+/*
+ * load a firmware packet to the device
+ */
+static int usb_cypress_writemem(struct usb_device *udev,u16 addr,u8 *data, u8 len)
+{
+	return usb_control_msg(udev, usb_sndctrlpipe(udev,0),
+			0xa0, USB_TYPE_VENDOR, addr, 0x00, data, len, 5*HZ);
+}
+
+int usb_cypress_load_firmware(struct usb_device *udev, const char *filename, int type)
+{
+	const struct firmware *fw = NULL;
+	u16 addr;
+	u8 *b,*p;
+	int ret = 0,i;
+
+	if ((ret = request_firmware(&fw, filename, &udev->dev)) != 0) {
+		err("did not find the firmware file. (%s) "
+			"Please see linux/Documentation/dvb/ for more details on firmware-problems.",
+			filename);
+		return ret;
+	}
+
+	info("downloading firmware from file '%s' to the '%s'",filename,cypress[type].name);
+
+	p = kmalloc(fw->size,GFP_KERNEL);
+	if (p != NULL) {
+		u8 reset;
+		/*
+		 * you cannot use the fw->data as buffer for
+		 * usb_control_msg, a new buffer has to be
+		 * created
+		 */
+		memcpy(p,fw->data,fw->size);
+
+		/* stop the CPU */
+		reset = 1;
+		if ((ret = usb_cypress_writemem(udev,cypress[type].cpu_cs_register,&reset,1)) != 1)
+			err("could not stop the USB controller CPU.");
+		for(i = 0; p[i+3] == 0 && i < fw->size; ) {
+			b = (u8 *) &p[i];
+			addr = cpu_to_le16( *((u16 *) &b[1]) );
+
+			deb_fw("writing to address 0x%04x (buffer: 0x%02x%02x)\n",addr,b[1],b[2]);
+
+			ret = usb_cypress_writemem(udev,addr,&b[4],b[0]);
+
+			if (ret != b[0]) {
+				err("error while transferring firmware "
+					"(transferred size: %d, block size: %d)",
+					ret,b[0]);
+				ret = -EINVAL;
+				break;
+			}
+			i += 5 + b[0];
+		}
+		/* length in ret */
+		if (ret > 0)
+			ret = 0;
+		/* restart the CPU */
+		reset = 0;
+		if (ret || usb_cypress_writemem(udev,cypress[type].cpu_cs_register,&reset,1) != 1) {
+			err("could not restart the USB controller CPU.");
+			ret = -EINVAL;
+		}
+
+		kfree(p);
+	} else {
+		ret = -ENOMEM;
+	}
+	release_firmware(fw);
+
+	return ret;
+}
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c b/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c
new file mode 100644
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c
@@ -0,0 +1,118 @@
+/* dvb-usb-i2c.c is part of the DVB USB library.
+ *
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ * see dvb-usb-init.c for copyright information.
+ *
+ * This file contains functions for (de-)initializing an I2C adapter.
+ */
+#include "dvb-usb-common.h"
+
+int dvb_usb_i2c_init(struct dvb_usb_device *d)
+{
+	int ret = 0;
+
+	if (!(d->props.caps & DVB_USB_IS_AN_I2C_ADAPTER))
+		return 0;
+
+	if (d->props.i2c_algo == NULL) {
+		err("no i2c algorithm specified");
+		return -EINVAL;
+	}
+
+	strncpy(d->i2c_adap.name,d->desc->name,I2C_NAME_SIZE);
+#ifdef I2C_ADAP_CLASS_TV_DIGITAL
+	d->i2c_adap.class = I2C_ADAP_CLASS_TV_DIGITAL,
+#else
+	d->i2c_adap.class = I2C_CLASS_TV_DIGITAL,
+#endif
+	d->i2c_adap.algo      = d->props.i2c_algo;
+	d->i2c_adap.algo_data = NULL;
+	d->i2c_adap.id        = I2C_ALGO_BIT;
+
+	i2c_set_adapdata(&d->i2c_adap, d);
+
+	if ((ret = i2c_add_adapter(&d->i2c_adap)) < 0)
+		err("could not add i2c adapter");
+
+	d->state |= DVB_USB_STATE_I2C;
+
+	return ret;
+}
+
+int dvb_usb_i2c_exit(struct dvb_usb_device *d)
+{
+	if (d->state & DVB_USB_STATE_I2C)
+		i2c_del_adapter(&d->i2c_adap);
+	d->state &= ~DVB_USB_STATE_I2C;
+	return 0;
+}
+
+int dvb_usb_pll_init_i2c(struct dvb_frontend *fe)
+{
+	struct dvb_usb_device *d = fe->dvb->priv;
+	struct i2c_msg msg = { .addr = d->pll_addr, .flags = 0, .buf = d->pll_init, .len = 4 };
+	int ret = 0;
+
+	/* if there is nothing to initialize */
+	if (d->pll_init[0] == 0x00 && d->pll_init[1] == 0x00 &&
+		d->pll_init[2] == 0x00 && d->pll_init[3] == 0x00)
+		return 0;
+
+	if (d->tuner_pass_ctrl)
+		d->tuner_pass_ctrl(fe,1,d->pll_addr);
+
+	deb_pll("pll init: %x\n",d->pll_addr);
+	deb_pll("pll-buf: %x %x %x %x\n",d->pll_init[0],d->pll_init[1],
+			d->pll_init[2],d->pll_init[3]);
+
+	if (i2c_transfer (&d->i2c_adap, &msg, 1) != 1) {
+		err("tuner i2c write failed for pll_init.");
+		ret = -EREMOTEIO;
+	}
+	msleep(1);
+
+	if (d->tuner_pass_ctrl)
+		d->tuner_pass_ctrl(fe,0,d->pll_addr);
+	return ret;
+}
+EXPORT_SYMBOL(dvb_usb_pll_init_i2c);
+
+int dvb_usb_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep, u8 b[5])
+{
+	struct dvb_usb_device *d = fe->dvb->priv;
+
+	deb_pll("pll addr: %x, freq: %d %p\n",d->pll_addr,fep->frequency,d->pll_desc);
+
+	b[0] = d->pll_addr << 1;
+	dvb_pll_configure(d->pll_desc,&b[1],fep->frequency,fep->u.ofdm.bandwidth);
+
+	deb_pll("pll-buf: %x %x %x %x %x\n",b[0],b[1],b[2],b[3],b[4]);
+
+	return 0;
+}
+EXPORT_SYMBOL(dvb_usb_pll_set);
+
+int dvb_usb_pll_set_i2c(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
+{
+	struct dvb_usb_device *d = fe->dvb->priv;
+	int ret = 0;
+	u8 b[5];
+	struct i2c_msg msg = { .addr = d->pll_addr, .flags = 0, .buf = &b[1], .len = 4 };
+
+	dvb_usb_pll_set(fe,fep,b);
+
+	if (d->tuner_pass_ctrl)
+		d->tuner_pass_ctrl(fe,1,d->pll_addr);
+
+	if (i2c_transfer (&d->i2c_adap, &msg, 1) != 1) {
+		err("tuner i2c write failed for pll_set.");
+		ret = -EREMOTEIO;
+	}
+	msleep(1);
+
+	if (d->tuner_pass_ctrl)
+		d->tuner_pass_ctrl(fe,0,d->pll_addr);
+
+	return ret;
+}
+EXPORT_SYMBOL(dvb_usb_pll_set_i2c);
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
new file mode 100644
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -0,0 +1,89 @@
+/* dvb-usb-ids.h is part of the DVB USB library.
+ *
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) see
+ * dvb-usb-init.c for copyright information.
+ *
+ * a header file containing define's for the USB device supported by the
+ * various drivers.
+ */
+#ifndef _DVB_USB_IDS_H_
+#define _DVB_USB_IDS_H_
+
+/* Vendor IDs */
+#define USB_VID_ADSTECH						0x06e1
+#define USB_VID_ANCHOR						0x0547
+#define USB_VID_WIDEVIEW					0x14aa
+#define USB_VID_AVERMEDIA					0x07ca
+#define USB_VID_COMPRO						0x185b
+#define USB_VID_COMPRO_UNK					0x145f
+#define USB_VID_CYPRESS						0x04b4
+#define USB_VID_DIBCOM						0x10b8
+#define USB_VID_DVICO						0x0fe9
+#define USB_VID_EMPIA						0xeb1a
+#define USB_VID_GRANDTEC					0x5032
+#define USB_VID_HANFTEK						0x15f4
+#define USB_VID_HAUPPAUGE					0x2040
+#define USB_VID_HYPER_PALTEK				0x1025
+#define USB_VID_KYE							0x0458
+#define USB_VID_MEDION						0x1660
+#define USB_VID_VISIONPLUS					0x13d3
+#define USB_VID_TWINHAN						0x1822
+#define USB_VID_ULTIMA_ELECTRONIC			0x05d8
+
+/* Product IDs */
+#define USB_PID_ADSTECH_USB2_COLD			0xa333
+#define USB_PID_ADSTECH_USB2_WARM			0xa334
+#define USB_PID_AVERMEDIA_DVBT_USB_COLD		0x0001
+#define USB_PID_AVERMEDIA_DVBT_USB_WARM		0x0002
+#define USB_PID_AVERMEDIA_DVBT_USB2_COLD	0xa800
+#define USB_PID_AVERMEDIA_DVBT_USB2_WARM	0xa801
+#define USB_PID_COMPRO_DVBU2000_COLD		0xd000
+#define USB_PID_COMPRO_DVBU2000_WARM		0xd001
+#define USB_PID_COMPRO_DVBU2000_UNK_COLD	0x010c
+#define USB_PID_COMPRO_DVBU2000_UNK_WARM	0x010d
+#define USB_PID_DIBCOM_MOD3000_COLD			0x0bb8
+#define USB_PID_DIBCOM_MOD3000_WARM			0x0bb9
+#define USB_PID_DIBCOM_MOD3001_COLD			0x0bc6
+#define USB_PID_DIBCOM_MOD3001_WARM			0x0bc7
+#define USB_PID_DIBCOM_ANCHOR_2135_COLD		0x2131
+#define USB_PID_GRANDTEC_DVBT_USB_COLD		0x0fa0
+#define USB_PID_GRANDTEC_DVBT_USB_WARM		0x0fa1
+#define USB_PID_KWORLD_VSTREAM_COLD			0x17de
+#define USB_PID_KWORLD_VSTREAM_WARM			0x17df
+#define USB_PID_TWINHAN_VP7041_COLD			0x3201
+#define USB_PID_TWINHAN_VP7041_WARM			0x3202
+#define USB_PID_TWINHAN_VP7045_COLD			0x3205
+#define USB_PID_TWINHAN_VP7045_WARM			0x3206
+#define USB_PID_DNTV_TINYUSB2_COLD			0x3223
+#define USB_PID_DNTV_TINYUSB2_WARM			0x3224
+#define USB_PID_TWINHAN_VP7021_COLD			0x3207
+#define USB_PID_TWINHAN_VP7021_WARM			0x3208
+#define USB_PID_ULTIMA_TVBOX_COLD			0x8105
+#define USB_PID_ULTIMA_TVBOX_WARM			0x8106
+#define USB_PID_ULTIMA_TVBOX_AN2235_COLD	0x8107
+#define USB_PID_ULTIMA_TVBOX_AN2235_WARM	0x8108
+#define USB_PID_ULTIMA_TVBOX_ANCHOR_COLD	0x2235
+#define USB_PID_ULTIMA_TVBOX_USB2_COLD		0x8109
+#define USB_PID_ULTIMA_TVBOX_USB2_FX_COLD	0x8613
+#define USB_PID_ULTIMA_TVBOX_USB2_FX_WARM	0x1002
+#define USB_PID_UNK_HYPER_PALTEK_COLD		0x005e
+#define USB_PID_UNK_HYPER_PALTEK_WARM		0x005f
+#define USB_PID_HANFTEK_UMT_010_COLD		0x0001
+#define USB_PID_HANFTEK_UMT_010_WARM		0x0015
+#define USB_PID_DTT200U_COLD				0x0201
+#define USB_PID_DTT200U_WARM				0x0301
+#define USB_PID_WT220U_COLD					0x0222
+#define USB_PID_WT220U_WARM					0x0221
+#define USB_PID_WINTV_NOVA_T_USB2_COLD		0x9300
+#define USB_PID_WINTV_NOVA_T_USB2_WARM		0x9301
+#define USB_PID_NEBULA_DIGITV				0x0201
+#define USB_PID_DVICO_BLUEBIRD_LGZ201		0xdb00
+#define USB_PID_DVICO_BLUEBIRD_TH7579		0xdb10
+#define USB_PID_DVICO_BLUEBIRD_LGDT			0xd820
+#define USB_PID_DVICO_BLUEBIRD_LGZ201_1		0xdb01
+#define USB_PID_DVICO_BLUEBIRD_TH7579_2		0xdb11
+#define USB_PID_MEDION_MD95700				0x0932
+#define USB_PID_KYE_DVB_T_COLD				0x701e
+#define USB_PID_KYE_DVB_T_WARM				0x701f
+
+#endif
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-init.c b/drivers/media/dvb/dvb-usb/dvb-usb-init.c
new file mode 100644
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-init.c
@@ -0,0 +1,215 @@
+/*
+ * DVB USB library - provides a generic interface for a DVB USB device driver.
+ *
+ * dvb-usb-init.c
+ *
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ *
+ *	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, version 2.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+#include "dvb-usb-common.h"
+
+/* debug */
+int dvb_usb_debug;
+module_param_named(debug,dvb_usb_debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,pll=4,ts=8,err=16,rc=32,fw=64 (or-able))." DVB_USB_DEBUG_STATUS);
+
+int dvb_usb_disable_rc_polling;
+module_param_named(disable_rc_polling, dvb_usb_disable_rc_polling, int, 0644);
+MODULE_PARM_DESC(disable_rc_polling, "disable remote control polling (default: 0).");
+
+/* general initialization functions */
+int dvb_usb_exit(struct dvb_usb_device *d)
+{
+	deb_info("state before exiting everything: %x\n",d->state);
+	dvb_usb_remote_exit(d);
+	dvb_usb_fe_exit(d);
+	dvb_usb_i2c_exit(d);
+	dvb_usb_dvb_exit(d);
+	dvb_usb_urb_exit(d);
+	deb_info("state should be zero now: %x\n",d->state);
+	d->state = DVB_USB_STATE_INIT;
+	kfree(d->priv);
+	kfree(d);
+	return 0;
+}
+
+static int dvb_usb_init(struct dvb_usb_device *d)
+{
+	int ret = 0;
+
+	sema_init(&d->usb_sem, 1);
+	sema_init(&d->i2c_sem, 1);
+
+	d->state = DVB_USB_STATE_INIT;
+
+/* check the capabilites and set appropriate variables */
+
+/* speed - when running at FULL speed we need a HW PID filter */
+	if (d->udev->speed == USB_SPEED_FULL && !(d->props.caps & DVB_USB_HAS_PID_FILTER)) {
+		err("This USB2.0 device cannot be run on a USB1.1 port. (it lacks a hardware PID filter)");
+		return -ENODEV;
+	}
+
+	if ((d->udev->speed == USB_SPEED_FULL && d->props.caps & DVB_USB_HAS_PID_FILTER) ||
+		(d->props.caps & DVB_USB_NEED_PID_FILTERING)) {
+		info("will use the device's hardware PID filter (table count: %d).",d->props.pid_filter_count);
+		d->pid_filtering = 1;
+		d->max_feed_count = d->props.pid_filter_count;
+	} else {
+		info("will pass the complete MPEG2 transport stream to the software demuxer.");
+		d->pid_filtering = 0;
+		d->max_feed_count = 255;
+	}
+
+	if (d->props.power_ctrl)
+		d->props.power_ctrl(d,1);
+
+	if ((ret = dvb_usb_urb_init(d)) ||
+		(ret = dvb_usb_dvb_init(d)) ||
+		(ret = dvb_usb_i2c_init(d)) ||
+		(ret = dvb_usb_fe_init(d))) {
+		dvb_usb_exit(d);
+		return ret;
+	}
+
+	if ((ret = dvb_usb_remote_init(d)))
+		err("could not initialize remote control.");
+
+	if (d->props.power_ctrl)
+		d->props.power_ctrl(d,0);
+
+	return 0;
+}
+
+/* determine the name and the state of the just found USB device */
+static struct dvb_usb_device_description * dvb_usb_find_device(struct usb_device *udev,struct dvb_usb_properties *props, int *cold)
+{
+	int i,j;
+	struct dvb_usb_device_description *desc = NULL;
+	*cold = -1;
+
+	for (i = 0; i < props->num_device_descs; i++) {
+
+		for (j = 0; j < DVB_USB_ID_MAX_NUM && props->devices[i].cold_ids[j] != NULL; j++) {
+			deb_info("check for cold %x %x\n",props->devices[i].cold_ids[j]->idVendor, props->devices[i].cold_ids[j]->idProduct);
+			if (props->devices[i].cold_ids[j]->idVendor  == le16_to_cpu(udev->descriptor.idVendor) &&
+				props->devices[i].cold_ids[j]->idProduct == le16_to_cpu(udev->descriptor.idProduct)) {
+				*cold = 1;
+				desc = &props->devices[i];
+				break;
+			}
+		}
+
+		if (desc != NULL)
+			break;
+
+		for (j = 0; j < DVB_USB_ID_MAX_NUM && props->devices[i].warm_ids[j] != NULL; j++) {
+			deb_info("check for warm %x %x\n",props->devices[i].warm_ids[j]->idVendor, props->devices[i].warm_ids[j]->idProduct);
+			if (props->devices[i].warm_ids[j]->idVendor == le16_to_cpu(udev->descriptor.idVendor) &&
+				props->devices[i].warm_ids[j]->idProduct == le16_to_cpu(udev->descriptor.idProduct)) {
+				*cold = 0;
+				desc = &props->devices[i];
+				break;
+			}
+		}
+	}
+
+	if (desc != NULL && props->identify_state != NULL)
+		props->identify_state(udev,props,&desc,cold);
+
+	return desc;
+}
+
+/*
+ * USB
+ */
+int dvb_usb_device_init(struct usb_interface *intf, struct dvb_usb_properties *props, struct module *owner)
+{
+	struct usb_device *udev = interface_to_usbdev(intf);
+	struct dvb_usb_device *d = NULL;
+	struct dvb_usb_device_description *desc = NULL;
+
+	int ret = -ENOMEM,cold=0;
+
+	if ((desc = dvb_usb_find_device(udev,props,&cold)) == NULL) {
+		deb_err("something went very wrong, device was not found in current device list - let's see what comes next.\n");
+		return -ENODEV;
+	}
+
+	if (cold) {
+		info("found a '%s' in cold state, will try to load a firmware",desc->name);
+		ret = usb_cypress_load_firmware(udev,props->firmware,props->usb_ctrl);
+	} else {
+		info("found a '%s' in warm state.",desc->name);
+		d = kmalloc(sizeof(struct dvb_usb_device),GFP_KERNEL);
+		if (d == NULL) {
+			err("no memory for 'struct dvb_usb_device'");
+			return ret;
+		}
+		memset(d,0,sizeof(struct dvb_usb_device));
+
+		d->udev = udev;
+		memcpy(&d->props,props,sizeof(struct dvb_usb_properties));
+		d->desc = desc;
+		d->owner = owner;
+
+		if (d->props.size_of_priv > 0) {
+			d->priv = kmalloc(d->props.size_of_priv,GFP_KERNEL);
+			if (d->priv == NULL) {
+				err("no memory for priv in 'struct dvb_usb_device'");
+				kfree(d);
+				return -ENOMEM;
+			}
+			memset(d->priv,0,d->props.size_of_priv);
+		}
+
+		usb_set_intfdata(intf, d);
+
+		ret = dvb_usb_init(d);
+	}
+
+	if (ret == 0)
+		info("%s successfully initialized and connected.",desc->name);
+	else
+		info("%s error while loading driver (%d)",desc->name,ret);
+	return ret;
+}
+EXPORT_SYMBOL(dvb_usb_device_init);
+
+void dvb_usb_device_exit(struct usb_interface *intf)
+{
+	struct dvb_usb_device *d = usb_get_intfdata(intf);
+	const char *name = "generic DVB-USB module";
+
+	usb_set_intfdata(intf,NULL);
+	if (d != NULL && d->desc != NULL) {
+		name = d->desc->name;
+		dvb_usb_exit(d);
+	}
+	info("%s successfully deinitialized and disconnected.",name);
+
+}
+EXPORT_SYMBOL(dvb_usb_device_exit);
+
+/* module stuff */
+static int __init dvb_usb_module_init(void)
+{
+	return 0;
+}
+
+static void __exit dvb_usb_module_exit(void)
+{
+}
+
+module_init (dvb_usb_module_init);
+module_exit (dvb_usb_module_exit);
+
+MODULE_VERSION("0.3");
+MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
+MODULE_DESCRIPTION("A library module containing commonly used USB and DVB function USB DVB devices");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
new file mode 100644
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
@@ -0,0 +1,181 @@
+/* dvb-usb-remote.c is part of the DVB USB library.
+ *
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ * see dvb-usb-init.c for copyright information.
+ *
+ * This file contains functions for initializing the the input-device and for handling remote-control-queries.
+ */
+#include "dvb-usb-common.h"
+
+/* Remote-control poll function - called every dib->rc_query_interval ms to see
+ * whether the remote control has received anything.
+ *
+ * TODO: Fix the repeat rate of the input device.
+ */
+static void dvb_usb_read_remote_control(void *data)
+{
+	struct dvb_usb_device *d = data;
+	u32 event;
+	int state;
+
+	/* TODO: need a lock here.  We can simply skip checking for the remote control
+	   if we're busy. */
+
+	/* when the parameter has been set to 1 via sysfs while the driver was running */
+	if (dvb_usb_disable_rc_polling)
+		return;
+
+	if (d->props.rc_query(d,&event,&state)) {
+		err("error while querying for an remote control event.");
+		goto schedule;
+	}
+
+
+	switch (state) {
+		case REMOTE_NO_KEY_PRESSED:
+			break;
+		case REMOTE_KEY_PRESSED:
+			deb_rc("key pressed\n");
+			d->last_event = event;
+		case REMOTE_KEY_REPEAT:
+			deb_rc("key repeated\n");
+			input_event(&d->rc_input_dev, EV_KEY, d->last_event, 1);
+			input_event(&d->rc_input_dev, EV_KEY, d->last_event, 0);
+			input_sync(&d->rc_input_dev);
+			break;
+		default:
+			break;
+	}
+
+/* improved repeat handling ???
+	switch (state) {
+		case REMOTE_NO_KEY_PRESSED:
+			deb_rc("NO KEY PRESSED\n");
+			if (d->last_state != REMOTE_NO_KEY_PRESSED) {
+				deb_rc("releasing event %d\n",d->last_event);
+				input_event(&d->rc_input_dev, EV_KEY, d->last_event, 0);
+				input_sync(&d->rc_input_dev);
+			}
+			d->last_state = REMOTE_NO_KEY_PRESSED;
+			d->last_event = 0;
+			break;
+		case REMOTE_KEY_PRESSED:
+			deb_rc("KEY PRESSED\n");
+			deb_rc("pressing event %d\n",event);
+
+			input_event(&d->rc_input_dev, EV_KEY, event, 1);
+			input_sync(&d->rc_input_dev);
+
+			d->last_event = event;
+			d->last_state = REMOTE_KEY_PRESSED;
+			break;
+		case REMOTE_KEY_REPEAT:
+			deb_rc("KEY_REPEAT\n");
+			if (d->last_state != REMOTE_NO_KEY_PRESSED) {
+				deb_rc("repeating event %d\n",d->last_event);
+				input_event(&d->rc_input_dev, EV_KEY, d->last_event, 2);
+				input_sync(&d->rc_input_dev);
+				d->last_state = REMOTE_KEY_REPEAT;
+			}
+		default:
+			break;
+	}
+*/
+
+schedule:
+	schedule_delayed_work(&d->rc_query_work,msecs_to_jiffies(d->props.rc_interval));
+}
+
+int dvb_usb_remote_init(struct dvb_usb_device *d)
+{
+	int i;
+	if (d->props.rc_key_map == NULL ||
+		d->props.rc_query == NULL ||
+		dvb_usb_disable_rc_polling)
+		return 0;
+
+	/* Initialise the remote-control structures.*/
+	init_input_dev(&d->rc_input_dev);
+
+	d->rc_input_dev.evbit[0] = BIT(EV_KEY);
+	d->rc_input_dev.keycodesize = sizeof(unsigned char);
+	d->rc_input_dev.keycodemax = KEY_MAX;
+	d->rc_input_dev.name = "IR-receiver inside an USB DVB receiver";
+
+	/* set the bits for the keys */
+	deb_rc("key map size: %d\n",d->props.rc_key_map_size);
+	for (i = 0; i < d->props.rc_key_map_size; i++) {
+		deb_rc("setting bit for event %d item %d\n",d->props.rc_key_map[i].event, i);
+		set_bit(d->props.rc_key_map[i].event, d->rc_input_dev.keybit);
+	}
+
+	/* Start the remote-control polling. */
+	if (d->props.rc_interval < 40)
+		d->props.rc_interval = 100; /* default */
+
+	/* setting these two values to non-zero, we have to manage key repeats */
+	d->rc_input_dev.rep[REP_PERIOD] = d->props.rc_interval;
+	d->rc_input_dev.rep[REP_DELAY]  = d->props.rc_interval + 150;
+
+	input_register_device(&d->rc_input_dev);
+
+	INIT_WORK(&d->rc_query_work, dvb_usb_read_remote_control, d);
+
+	info("schedule remote query interval to %d msecs.",d->props.rc_interval);
+	schedule_delayed_work(&d->rc_query_work,msecs_to_jiffies(d->props.rc_interval));
+
+	d->state |= DVB_USB_STATE_REMOTE;
+
+	return 0;
+}
+
+int dvb_usb_remote_exit(struct dvb_usb_device *d)
+{
+	if (d->state & DVB_USB_STATE_REMOTE) {
+		cancel_delayed_work(&d->rc_query_work);
+		flush_scheduled_work();
+		input_unregister_device(&d->rc_input_dev);
+	}
+	d->state &= ~DVB_USB_STATE_REMOTE;
+	return 0;
+}
+
+#define DVB_USB_RC_NEC_EMPTY           0x00
+#define DVB_USB_RC_NEC_KEY_PRESSED     0x01
+#define DVB_USB_RC_NEC_KEY_REPEATED    0x02
+int dvb_usb_nec_rc_key_to_event(struct dvb_usb_device *d,
+		u8 keybuf[5], u32 *event, int *state)
+{
+	int i;
+	struct dvb_usb_rc_key *keymap = d->props.rc_key_map;
+	*event = 0;
+	*state = REMOTE_NO_KEY_PRESSED;
+	switch (keybuf[0]) {
+		case DVB_USB_RC_NEC_EMPTY:
+			break;
+		case DVB_USB_RC_NEC_KEY_PRESSED:
+			if ((u8) ~keybuf[1] != keybuf[2] ||
+				(u8) ~keybuf[3] != keybuf[4]) {
+				deb_err("remote control checksum failed.\n");
+				break;
+			}
+			/* See if we can match the raw key code. */
+			for (i = 0; i < d->props.rc_key_map_size; i++)
+				if (keymap[i].custom == keybuf[1] &&
+					keymap[i].data == keybuf[3]) {
+					*event = keymap[i].event;
+					*state = REMOTE_KEY_PRESSED;
+					return 0;
+				}
+			deb_err("key mapping failed - no appropriate key found in keymapping\n");
+			break;
+		case DVB_USB_RC_NEC_KEY_REPEATED:
+			*state = REMOTE_KEY_REPEAT;
+			break;
+		default:
+			deb_err("unkown type of remote status: %d\n",keybuf[0]);
+			break;
+	}
+	return 0;
+}
+EXPORT_SYMBOL(dvb_usb_nec_rc_key_to_event);
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-urb.c b/drivers/media/dvb/dvb-usb/dvb-usb-urb.c
new file mode 100644
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-urb.c
@@ -0,0 +1,325 @@
+/* dvb-usb-urb.c is part of the DVB USB library.
+ *
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ * see dvb-usb-init.c for copyright information.
+ *
+ * This file contains functions for initializing and handling the
+ * USB and URB stuff.
+ */
+#include "dvb-usb-common.h"
+
+int dvb_usb_generic_rw(struct dvb_usb_device *d, u8 *wbuf, u16 wlen, u8 *rbuf,
+	u16 rlen, int delay_ms)
+{
+	int actlen,ret = -ENOMEM;
+
+	if (d->props.generic_bulk_ctrl_endpoint == 0) {
+		err("endpoint for generic control not specified.");
+		return -EINVAL;
+	}
+
+	if (wbuf == NULL || wlen == 0)
+		return -EINVAL;
+
+	if ((ret = down_interruptible(&d->usb_sem)))
+		return ret;
+
+	deb_xfer(">>> ");
+	debug_dump(wbuf,wlen,deb_xfer);
+
+	ret = usb_bulk_msg(d->udev,usb_sndbulkpipe(d->udev,
+			d->props.generic_bulk_ctrl_endpoint), wbuf,wlen,&actlen,
+			2000);
+
+	if (ret)
+		err("bulk message failed: %d (%d/%d)",ret,wlen,actlen);
+	else
+		ret = actlen != wlen ? -1 : 0;
+
+	/* an answer is expected, and no error before */
+	if (!ret && rbuf && rlen) {
+		if (delay_ms)
+			msleep(delay_ms);
+
+		ret = usb_bulk_msg(d->udev,usb_rcvbulkpipe(d->udev,
+				d->props.generic_bulk_ctrl_endpoint),rbuf,rlen,&actlen,
+				2000);
+
+		if (ret)
+			err("recv bulk message failed: %d",ret);
+		else {
+			deb_xfer("<<< ");
+			debug_dump(rbuf,actlen,deb_xfer);
+		}
+	}
+
+	up(&d->usb_sem);
+	return ret;
+}
+EXPORT_SYMBOL(dvb_usb_generic_rw);
+
+int dvb_usb_generic_write(struct dvb_usb_device *d, u8 *buf, u16 len)
+{
+	return dvb_usb_generic_rw(d,buf,len,NULL,0,0);
+}
+EXPORT_SYMBOL(dvb_usb_generic_write);
+
+
+/* URB stuff for streaming */
+static void dvb_usb_urb_complete(struct urb *urb, struct pt_regs *ptregs)
+{
+	struct dvb_usb_device *d = urb->context;
+	int ptype = usb_pipetype(urb->pipe);
+	int i;
+	u8 *b;
+
+	deb_ts("'%s' urb completed. feedcount: %d, status: %d, length: %d/%d, pack_num: %d, errors: %d\n",
+			ptype == PIPE_ISOCHRONOUS ? "isoc" : "bulk", d->feedcount,
+			urb->status,urb->actual_length,urb->transfer_buffer_length,
+			urb->number_of_packets,urb->error_count);
+
+	switch (urb->status) {
+		case 0:         /* success */
+		case -ETIMEDOUT:    /* NAK */
+			break;
+		case -ECONNRESET:   /* kill */
+		case -ENOENT:
+		case -ESHUTDOWN:
+			return;
+		default:        /* error */
+			deb_ts("urb completition error %d.", urb->status);
+			break;
+	}
+
+	if (d->feedcount > 0) {
+		if (d->state & DVB_USB_STATE_DVB) {
+			switch (ptype) {
+				case PIPE_ISOCHRONOUS:
+					b = (u8 *) urb->transfer_buffer;
+					for (i = 0; i < urb->number_of_packets; i++) {
+						if (urb->iso_frame_desc[i].status != 0)
+							deb_ts("iso frame descriptor has an error: %d\n",urb->iso_frame_desc[i].status);
+						else if (urb->iso_frame_desc[i].actual_length > 0) {
+								dvb_dmx_swfilter(&d->demux,b + urb->iso_frame_desc[i].offset,
+										urb->iso_frame_desc[i].actual_length);
+							}
+						urb->iso_frame_desc[i].status = 0;
+						urb->iso_frame_desc[i].actual_length = 0;
+					}
+					debug_dump(b,20,deb_ts);
+					break;
+				case PIPE_BULK:
+					if (urb->actual_length > 0)
+						dvb_dmx_swfilter(&d->demux, (u8 *) urb->transfer_buffer,urb->actual_length);
+					break;
+				default:
+					err("unkown endpoint type in completition handler.");
+					return;
+			}
+		}
+	}
+
+	usb_submit_urb(urb,GFP_ATOMIC);
+}
+
+int dvb_usb_urb_kill(struct dvb_usb_device *d)
+{
+	int i;
+	for (i = 0; i < d->urbs_submitted; i++) {
+		deb_ts("killing URB no. %d.\n",i);
+
+		/* stop the URB */
+		usb_kill_urb(d->urb_list[i]);
+	}
+	d->urbs_submitted = 0;
+	return 0;
+}
+
+int dvb_usb_urb_submit(struct dvb_usb_device *d)
+{
+	int i,ret;
+	for (i = 0; i < d->urbs_initialized; i++) {
+		deb_ts("submitting URB no. %d\n",i);
+		if ((ret = usb_submit_urb(d->urb_list[i],GFP_ATOMIC))) {
+			err("could not submit URB no. %d - get them all back",i);
+			dvb_usb_urb_kill(d);
+			return ret;
+		}
+		d->urbs_submitted++;
+	}
+	return 0;
+}
+
+static int dvb_usb_free_stream_buffers(struct dvb_usb_device *d)
+{
+	if (d->state & DVB_USB_STATE_URB_BUF) {
+		while (d->buf_num) {
+			d->buf_num--;
+			deb_mem("freeing buffer %d\n",d->buf_num);
+			usb_buffer_free(d->udev, d->buf_size,
+					d->buf_list[d->buf_num], d->dma_addr[d->buf_num]);
+		}
+		kfree(d->buf_list);
+		kfree(d->dma_addr);
+	}
+
+	d->state &= ~DVB_USB_STATE_URB_BUF;
+
+	return 0;
+}
+
+static int dvb_usb_allocate_stream_buffers(struct dvb_usb_device *d, int num, unsigned long size)
+{
+	d->buf_num = 0;
+	d->buf_size = size;
+
+	deb_mem("all in all I will use %lu bytes for streaming\n",num*size);
+
+	if ((d->buf_list = kmalloc(num*sizeof(u8 *), GFP_ATOMIC)) == NULL)
+		return -ENOMEM;
+
+	if ((d->dma_addr = kmalloc(num*sizeof(dma_addr_t), GFP_ATOMIC)) == NULL) {
+		kfree(d->buf_list);
+		return -ENOMEM;
+	}
+	memset(d->buf_list,0,num*sizeof(u8 *));
+	memset(d->dma_addr,0,num*sizeof(dma_addr_t));
+
+	d->state |= DVB_USB_STATE_URB_BUF;
+
+	for (d->buf_num = 0; d->buf_num < num; d->buf_num++) {
+		deb_mem("allocating buffer %d\n",d->buf_num);
+		if (( d->buf_list[d->buf_num] =
+					usb_buffer_alloc(d->udev, size, SLAB_ATOMIC,
+					&d->dma_addr[d->buf_num]) ) == NULL) {
+			deb_mem("not enough memory for urb-buffer allocation.\n");
+			dvb_usb_free_stream_buffers(d);
+			return -ENOMEM;
+		}
+		deb_mem("buffer %d: %p (dma: %d)\n",d->buf_num,d->buf_list[d->buf_num],d->dma_addr[d->buf_num]);
+		memset(d->buf_list[d->buf_num],0,size);
+	}
+	deb_mem("allocation successful\n");
+
+	return 0;
+}
+
+static int dvb_usb_bulk_urb_init(struct dvb_usb_device *d)
+{
+	int i;
+
+	if ((i = dvb_usb_allocate_stream_buffers(d,d->props.urb.count,
+					d->props.urb.u.bulk.buffersize)) < 0)
+		return i;
+
+	/* allocate the URBs */
+	for (i = 0; i < d->props.urb.count; i++) {
+		if ((d->urb_list[i] = usb_alloc_urb(0,GFP_ATOMIC)) == NULL)
+			return -ENOMEM;
+
+		usb_fill_bulk_urb( d->urb_list[i], d->udev,
+				usb_rcvbulkpipe(d->udev,d->props.urb.endpoint),
+				d->buf_list[i],
+				d->props.urb.u.bulk.buffersize,
+				dvb_usb_urb_complete, d);
+
+		d->urb_list[i]->transfer_flags = 0;
+		d->urbs_initialized++;
+	}
+	return 0;
+}
+
+static int dvb_usb_isoc_urb_init(struct dvb_usb_device *d)
+{
+	int i,j;
+
+	if ((i = dvb_usb_allocate_stream_buffers(d,d->props.urb.count,
+					d->props.urb.u.isoc.framesize*d->props.urb.u.isoc.framesperurb)) < 0)
+		return i;
+
+	/* allocate the URBs */
+	for (i = 0; i < d->props.urb.count; i++) {
+		struct urb *urb;
+		int frame_offset = 0;
+		if ((d->urb_list[i] =
+					usb_alloc_urb(d->props.urb.u.isoc.framesperurb,GFP_ATOMIC)) == NULL)
+			return -ENOMEM;
+
+		urb = d->urb_list[i];
+
+		urb->dev = d->udev;
+		urb->context = d;
+		urb->complete = dvb_usb_urb_complete;
+		urb->pipe = usb_rcvisocpipe(d->udev,d->props.urb.endpoint);
+		urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
+		urb->interval = d->props.urb.u.isoc.interval;
+		urb->number_of_packets = d->props.urb.u.isoc.framesperurb;
+		urb->transfer_buffer_length = d->buf_size;
+		urb->transfer_buffer = d->buf_list[i];
+		urb->transfer_dma = d->dma_addr[i];
+
+		for (j = 0; j < d->props.urb.u.isoc.framesperurb; j++) {
+			urb->iso_frame_desc[j].offset = frame_offset;
+			urb->iso_frame_desc[j].length = d->props.urb.u.isoc.framesize;
+			frame_offset += d->props.urb.u.isoc.framesize;
+		}
+
+		d->urbs_initialized++;
+	}
+	return 0;
+
+}
+
+int dvb_usb_urb_init(struct dvb_usb_device *d)
+{
+	/*
+	 * when reloading the driver w/o replugging the device
+	 * sometimes a timeout occures, this helps
+	 */
+	if (d->props.generic_bulk_ctrl_endpoint != 0) {
+		usb_clear_halt(d->udev,usb_sndbulkpipe(d->udev,d->props.generic_bulk_ctrl_endpoint));
+		usb_clear_halt(d->udev,usb_rcvbulkpipe(d->udev,d->props.generic_bulk_ctrl_endpoint));
+	}
+	usb_clear_halt(d->udev,usb_rcvbulkpipe(d->udev,d->props.urb.endpoint));
+
+	/* allocate the array for the data transfer URBs */
+	d->urb_list = kmalloc(d->props.urb.count * sizeof(struct urb *),GFP_KERNEL);
+	if (d->urb_list == NULL)
+		return -ENOMEM;
+	memset(d->urb_list,0,d->props.urb.count * sizeof(struct urb *));
+	d->state |= DVB_USB_STATE_URB_LIST;
+
+	switch (d->props.urb.type) {
+		case DVB_USB_BULK:
+			return dvb_usb_bulk_urb_init(d);
+		case DVB_USB_ISOC:
+			return dvb_usb_isoc_urb_init(d);
+		default:
+			err("unkown URB-type for data transfer.");
+			return -EINVAL;
+	}
+}
+
+int dvb_usb_urb_exit(struct dvb_usb_device *d)
+{
+	int i;
+
+	dvb_usb_urb_kill(d);
+
+	if (d->state & DVB_USB_STATE_URB_LIST) {
+		for (i = 0; i < d->urbs_initialized; i++) {
+			if (d->urb_list[i] != NULL) {
+				deb_mem("freeing URB no. %d.\n",i);
+				/* free the URBs */
+				usb_free_urb(d->urb_list[i]);
+			}
+		}
+		d->urbs_initialized = 0;
+		/* free the urb array */
+		kfree(d->urb_list);
+		d->state &= ~DVB_USB_STATE_URB_LIST;
+	}
+
+	dvb_usb_free_stream_buffers(d);
+	return 0;
+}
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb.h b/drivers/media/dvb/dvb-usb/dvb-usb.h
new file mode 100644
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dvb-usb.h
@@ -0,0 +1,329 @@
+/* dvb-usb.h is part of the DVB USB library.
+ *
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ * see dvb-usb-init.c for copyright information.
+ *
+ * the headerfile, all dvb-usb-drivers have to include.
+ */
+#ifndef __DVB_USB_H__
+#define __DVB_USB_H__
+
+#include <linux/config.h>
+#include <linux/input.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+
+#include "dvb_frontend.h"
+#include "dvb_demux.h"
+#include "dvb_net.h"
+#include "dmxdev.h"
+
+#include "dvb-pll.h"
+
+#include "dvb-usb-ids.h"
+
+/* debug */
+#ifdef CONFIG_DVB_USB_DEBUG
+#define dprintk(var,level,args...) \
+	    do { if ((var & level)) { printk(args); } } while (0)
+
+#define debug_dump(b,l,func) {\
+	int loop_; \
+	for (loop_ = 0; loop_ < l; loop_++) func("%02x ", b[loop_]); \
+	func("\n");\
+}
+#define DVB_USB_DEBUG_STATUS
+#else
+#define dprintk(args...)
+#define debug_dump(b,l,func)
+
+#define DVB_USB_DEBUG_STATUS " (debugging is not enabled)"
+
+#endif
+
+/* generic log methods - taken from usb.h */
+#ifndef DVB_USB_LOG_PREFIX
+ #define DVB_USB_LOG_PREFIX "dvb-usb (please define a log prefix)"
+#endif
+
+#undef err
+#define err(format, arg...)  printk(KERN_ERR     DVB_USB_LOG_PREFIX ": " format "\n" , ## arg)
+#undef info
+#define info(format, arg...) printk(KERN_INFO    DVB_USB_LOG_PREFIX ": " format "\n" , ## arg)
+#undef warn
+#define warn(format, arg...) printk(KERN_WARNING DVB_USB_LOG_PREFIX ": " format "\n" , ## arg)
+
+/**
+ * struct dvb_usb_device_description - name and its according USB IDs
+ * @name: real name of the box, regardless which DVB USB device class is in use
+ * @cold_ids: array of struct usb_device_id which describe the device in
+ *  pre-firmware state
+ * @warm_ids: array of struct usb_device_id which describe the device in
+ *  post-firmware state
+ *
+ * Each DVB USB device class can have one or more actual devices, this struct
+ * assigns a name to it.
+ */
+struct dvb_usb_device_description {
+	const char *name;
+
+#define DVB_USB_ID_MAX_NUM 15
+	struct usb_device_id *cold_ids[DVB_USB_ID_MAX_NUM];
+	struct usb_device_id *warm_ids[DVB_USB_ID_MAX_NUM];
+};
+
+/**
+ * struct dvb_usb_rc_key - a remote control key and its input-event
+ * @custom: the vendor/custom part of the key
+ * @data: the actual key part
+ * @event: the input event assigned to key identified by custom and data
+ */
+struct dvb_usb_rc_key {
+	u8 custom,data;
+	u32 event;
+};
+
+struct dvb_usb_device;
+
+/**
+ * struct dvb_usb_properties - properties of a dvb-usb-device
+ * @caps: capabilites of the DVB USB device.
+ * @pid_filter_count: number of PID filter position in the optional hardware
+ *  PID-filter.
+ *
+ * @usb_ctrl: which USB device-side controller is in use. Needed for firmware
+ *  download.
+ * @firmware: name of the firmware file.
+ *
+ * @size_of_priv: how many bytes shall be allocated for the private field
+ *  of struct dvb_usb_device.
+ *
+ * @power_ctrl: called to enable/disable power of the device.
+ * @streaming_crtl: called to start and stop the MPEG2-TS streaming of the
+ *  device (not URB submitting/killing).
+ * @pid_filter_ctrl: called to en/disable the PID filter, if any.
+ * @pid_filter: called to set/unset a PID for filtering.
+ *
+ * @read_mac_address: called to read the MAC address of the device.
+ *
+ * @frontend_attach: called to attach the possible frontends (fill fe-field
+ *  of struct dvb_usb_device).
+ * @tuner_attach: called to attach the correct tuner and to fill pll_addr,
+ *  pll_desc and pll_init_buf of struct dvb_usb_device).
+ * @identify_state: called to determine the state (cold or warm), when it
+ *  is not distinguishable by the USB IDs.
+ *
+ * @rc_key_map: a hard-wired array of struct dvb_usb_rc_key (NULL to disable
+ *  remote control handling).
+ * @rc_key_map_size: number of items in @rc_key_map.
+ * @rc_query: called to query an event event.
+ * @rc_interval: time in ms between two queries.
+ *
+ * @i2c_algo: i2c_algorithm if the device has I2CoverUSB.
+ *
+ * @generic_bulk_ctrl_endpoint: most of the DVB USB devices have a generic
+ *  endpoint which received control messages with bulk transfers. When this
+ *  is non-zero, one can use dvb_usb_generic_rw and dvb_usb_generic_write-
+ *  helper functions.
+ *
+ * @urb: describes the kind of USB transfer used for MPEG2-TS-streaming.
+ *  Currently only BULK is implemented
+ *
+ * @num_device_descs: number of struct dvb_usb_device_description in @devices
+ * @devices: array of struct dvb_usb_device_description compatibles with these
+ *  properties.
+ */
+struct dvb_usb_properties {
+
+#define DVB_USB_HAS_PID_FILTER               0x01
+#define DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF 0x02
+#define DVB_USB_NEED_PID_FILTERING           0x04
+#define DVB_USB_IS_AN_I2C_ADAPTER            0x08
+	int caps;
+	int pid_filter_count;
+
+#define CYPRESS_AN2135  0
+#define CYPRESS_AN2235  1
+#define CYPRESS_FX2     2
+	int usb_ctrl;
+	const char *firmware;
+
+	int size_of_priv;
+
+	int (*power_ctrl) (struct dvb_usb_device *, int);
+	int (*streaming_ctrl) (struct dvb_usb_device *, int);
+	int (*pid_filter_ctrl) (struct dvb_usb_device *, int);
+	int (*pid_filter) (struct dvb_usb_device *, int, u16, int);
+
+	int (*read_mac_address) (struct dvb_usb_device *, u8 []);
+	int (*frontend_attach) (struct dvb_usb_device *);
+	int (*tuner_attach) (struct dvb_usb_device *);
+
+	int (*identify_state) (struct usb_device *, struct dvb_usb_properties *,
+			struct dvb_usb_device_description **, int *);
+
+/* remote control properties */
+#define REMOTE_NO_KEY_PRESSED      0x00
+#define REMOTE_KEY_PRESSED         0x01
+#define REMOTE_KEY_REPEAT          0x02
+	struct dvb_usb_rc_key *rc_key_map;
+	int rc_key_map_size;
+	int (*rc_query) (struct dvb_usb_device *, u32 *, int *);
+	int rc_interval;
+
+	struct i2c_algorithm *i2c_algo;
+
+	int generic_bulk_ctrl_endpoint;
+
+	struct {
+#define DVB_USB_BULK  1
+#define DVB_USB_ISOC  2
+		int type;
+		int count;
+		int endpoint;
+
+		union {
+			struct {
+				int buffersize; /* per URB */
+			} bulk;
+			struct {
+				int framesperurb;
+				int framesize;
+				int interval;
+			} isoc;
+		} u;
+	} urb;
+
+	int num_device_descs;
+	struct dvb_usb_device_description devices[9];
+};
+
+
+/**
+ * struct dvb_usb_device - object of a DVB USB device
+ * @props: copy of the struct dvb_usb_properties this device belongs to.
+ * @desc: pointer to the device's struct dvb_usb_device_description.
+ * @state: initialization and runtime state of the device.
+ *
+ * @udev: pointer to the device's struct usb_device.
+ * @urb_list: array of dynamically allocated struct urb for the MPEG2-TS-
+ *  streaming.
+ *
+ * @buf_num: number of buffer allocated.
+ * @buf_size: size of each buffer in buf_list.
+ * @buf_list: array containing all allocate buffers for streaming.
+ * @dma_addr: list of dma_addr_t for each buffer in buf_list.
+ *
+ * @urbs_initialized: number of URBs initialized.
+ * @urbs_submitted: number of URBs submitted.
+ *
+ * @feedcount: number of reqested feeds (used for streaming-activation)
+ * @pid_filtering: is hardware pid_filtering used or not.
+ *
+ * @usb_sem: semaphore of USB control messages (reading needs two messages)
+ * @i2c_sem: semaphore for i2c-transfers
+ *
+ * @i2c_adap: device's i2c_adapter if it uses I2CoverUSB
+ * @pll_addr: I2C address of the tuner for programming
+ * @pll_init: array containing the initialization buffer
+ * @pll_desc: pointer to the appropriate struct dvb_pll_desc
+ *
+ * @tuner_pass_ctrl: called to (de)activate tuner passthru of the demod or the board
+ *
+ * @dvb_adap: device's dvb_adapter.
+ * @dmxdev: device's dmxdev.
+ * @demux: device's software demuxer.
+ * @dvb_net: device's dvb_net interfaces.
+ * @dvb_frontend: device's frontend.
+ * @max_feed_count: how many feeds can be handled simultaneously by this
+ *  device
+ * @fe_sleep: rerouted frontend-sleep function.
+ * @fe_init: rerouted frontend-init (wakeup) function.
+ * @rc_input_dev: input device for the remote control.
+ * @rc_query_work: struct work_struct frequent rc queries
+ * @last_event: last triggered event
+ * @last_state: last state (no, pressed, repeat)
+ * @owner: owner of the dvb_adapter
+ * @priv: private data of the actual driver (allocate by dvb-usb, size defined
+ *  in size_of_priv of dvb_usb_properties).
+ */
+struct dvb_usb_device {
+	struct dvb_usb_properties props;
+	struct dvb_usb_device_description *desc;
+
+#define DVB_USB_STATE_INIT        0x000
+#define DVB_USB_STATE_URB_LIST    0x001
+#define DVB_USB_STATE_URB_BUF     0x002
+#define DVB_USB_STATE_DVB         0x004
+#define DVB_USB_STATE_I2C         0x008
+#define DVB_USB_STATE_REMOTE      0x010
+#define DVB_USB_STATE_URB_SUBMIT  0x020
+	int state;
+
+	/* usb */
+	struct usb_device *udev;
+	struct urb **urb_list;
+
+	int buf_num;
+	unsigned long buf_size;
+	u8 **buf_list;
+	dma_addr_t *dma_addr;
+
+	int urbs_initialized;
+	int urbs_submitted;
+
+	int feedcount;
+	int pid_filtering;
+
+	/* locking */
+	struct semaphore usb_sem;
+
+	/* i2c */
+	struct semaphore i2c_sem;
+	struct i2c_adapter i2c_adap;
+
+	/* tuner programming information */
+	u8 pll_addr;
+	u8 pll_init[4];
+	struct dvb_pll_desc *pll_desc;
+	int (*tuner_pass_ctrl)(struct dvb_frontend *, int, u8);
+
+	/* dvb */
+	struct dvb_adapter dvb_adap;
+	struct dmxdev dmxdev;
+	struct dvb_demux demux;
+	struct dvb_net dvb_net;
+	struct dvb_frontend* fe;
+	int max_feed_count;
+
+	int (*fe_sleep) (struct dvb_frontend *);
+	int (*fe_init)  (struct dvb_frontend *);
+
+	/* remote control */
+	struct input_dev rc_input_dev;
+	struct work_struct rc_query_work;
+	u32 last_event;
+	int last_state;
+
+	struct module *owner;
+
+	void *priv;
+};
+
+extern int dvb_usb_device_init(struct usb_interface *, struct dvb_usb_properties *, struct module *);
+extern void dvb_usb_device_exit(struct usb_interface *);
+
+/* the generic read/write method for device control */
+extern int dvb_usb_generic_rw(struct dvb_usb_device *, u8 *, u16, u8 *, u16,int);
+extern int dvb_usb_generic_write(struct dvb_usb_device *, u8 *, u16);
+
+/* commonly used remote control parsing */
+extern int dvb_usb_nec_rc_key_to_event(struct dvb_usb_device *, u8[], u32 *, int *);
+
+/* commonly used pll init and set functions */
+extern int dvb_usb_pll_init_i2c(struct dvb_frontend *);
+extern int dvb_usb_pll_set(struct dvb_frontend *, struct dvb_frontend_parameters *, u8[]);
+extern int dvb_usb_pll_set_i2c(struct dvb_frontend *, struct dvb_frontend_parameters *);
+
+
+#endif
diff --git a/drivers/media/dvb/dvb-usb/nova-t-usb2.c b/drivers/media/dvb/dvb-usb/nova-t-usb2.c
new file mode 100644
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/nova-t-usb2.c
@@ -0,0 +1,236 @@
+/* DVB USB framework compliant Linux driver for the Hauppauge WinTV-NOVA-T usb2
+ * DVB-T receiver.
+ *
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ *
+ *	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, version 2.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+#include "dibusb.h"
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level (1=rc,2=eeprom (|-able))." DVB_USB_DEBUG_STATUS);
+
+#define deb_rc(args...) dprintk(debug,0x01,args)
+#define deb_ee(args...) dprintk(debug,0x02,args)
+
+/* Hauppauge NOVA-T USB2 keys */
+static struct dvb_usb_rc_key haupp_rc_keys [] = {
+	{ 0x1e, 0x00, KEY_0 },
+	{ 0x1e, 0x01, KEY_1 },
+	{ 0x1e, 0x02, KEY_2 },
+	{ 0x1e, 0x03, KEY_3 },
+	{ 0x1e, 0x04, KEY_4 },
+	{ 0x1e, 0x05, KEY_5 },
+	{ 0x1e, 0x06, KEY_6 },
+	{ 0x1e, 0x07, KEY_7 },
+	{ 0x1e, 0x08, KEY_8 },
+	{ 0x1e, 0x09, KEY_9 },
+	{ 0x1e, 0x0a, KEY_KPASTERISK },
+	{ 0x1e, 0x0b, KEY_RED },
+	{ 0x1e, 0x0c, KEY_RADIO },
+	{ 0x1e, 0x0d, KEY_MENU },
+	{ 0x1e, 0x0e, KEY_GRAVE }, /* # */
+	{ 0x1e, 0x0f, KEY_MUTE },
+	{ 0x1e, 0x10, KEY_VOLUMEUP },
+	{ 0x1e, 0x11, KEY_VOLUMEDOWN },
+	{ 0x1e, 0x12, KEY_CHANNEL },
+	{ 0x1e, 0x14, KEY_UP },
+	{ 0x1e, 0x15, KEY_DOWN },
+	{ 0x1e, 0x16, KEY_LEFT },
+	{ 0x1e, 0x17, KEY_RIGHT },
+	{ 0x1e, 0x18, KEY_VIDEO },
+	{ 0x1e, 0x19, KEY_AUDIO },
+	{ 0x1e, 0x1a, KEY_MEDIA },
+	{ 0x1e, 0x1b, KEY_EPG },
+	{ 0x1e, 0x1c, KEY_TV },
+	{ 0x1e, 0x1e, KEY_NEXT },
+	{ 0x1e, 0x1f, KEY_BACK },
+	{ 0x1e, 0x20, KEY_CHANNELUP },
+	{ 0x1e, 0x21, KEY_CHANNELDOWN },
+	{ 0x1e, 0x24, KEY_LAST }, /* Skip backwards */
+	{ 0x1e, 0x25, KEY_OK },
+	{ 0x1e, 0x29, KEY_BLUE},
+	{ 0x1e, 0x2e, KEY_GREEN },
+	{ 0x1e, 0x30, KEY_PAUSE },
+	{ 0x1e, 0x32, KEY_REWIND },
+	{ 0x1e, 0x34, KEY_FASTFORWARD },
+	{ 0x1e, 0x35, KEY_PLAY },
+	{ 0x1e, 0x36, KEY_STOP },
+	{ 0x1e, 0x37, KEY_RECORD },
+	{ 0x1e, 0x38, KEY_YELLOW },
+	{ 0x1e, 0x3b, KEY_GOTO },
+	{ 0x1e, 0x3d, KEY_POWER },
+};
+
+/* Firmware bug? sometimes, when a new key is pressed, the previous pressed key
+ * is delivered. No workaround yet, maybe a new firmware.
+ */
+static int nova_t_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
+{
+	u8 key[5],cmd[2] = { DIBUSB_REQ_POLL_REMOTE, 0x35 }, data,toggle,custom;
+	u16 raw;
+	int i;
+	struct dibusb_state *st = d->priv;
+
+	dvb_usb_generic_rw(d,cmd,2,key,5,0);
+
+	*state = REMOTE_NO_KEY_PRESSED;
+	switch (key[0]) {
+		case DIBUSB_RC_HAUPPAUGE_KEY_PRESSED:
+			raw = ((key[1] << 8) | key[2]) >> 3;
+			toggle = !!(raw & 0x800);
+			data = raw & 0x3f;
+			custom = (raw >> 6) & 0x1f;
+
+			deb_rc("raw key code 0x%02x, 0x%02x, 0x%02x to c: %02x d: %02x toggle: %d\n",key[1],key[2],key[3],custom,data,toggle);
+
+			for (i = 0; i < ARRAY_SIZE(haupp_rc_keys); i++) {
+				deb_rc("c: %x, d: %x\n",haupp_rc_keys[i].data,haupp_rc_keys[i].custom);
+				if (haupp_rc_keys[i].data == data &&
+					haupp_rc_keys[i].custom == custom) {
+					*event = haupp_rc_keys[i].event;
+					*state = REMOTE_KEY_PRESSED;
+					if (st->old_toggle == toggle) {
+						if (st->last_repeat_count++ < 2)
+							*state = REMOTE_NO_KEY_PRESSED;
+					} else {
+						st->last_repeat_count = 0;
+						st->old_toggle = toggle;
+					}
+					break;
+				}
+			}
+
+			break;
+		case DIBUSB_RC_HAUPPAUGE_KEY_EMPTY:
+		default:
+			break;
+	}
+
+	return 0;
+}
+
+static int nova_t_read_mac_address (struct dvb_usb_device *d, u8 mac[6])
+{
+	int i;
+	u8 b;
+
+	mac[0] = 0x00;
+	mac[1] = 0x0d;
+	mac[2] = 0xfe;
+
+	/* this is a complete guess, but works for my box */
+	for (i = 136; i < 139; i++) {
+		dibusb_read_eeprom_byte(d,i, &b);
+
+		mac[5 - (i - 136)] = b;
+
+/*		deb_ee("%02x ",b);
+		if ((i+1) % 16 == 0)
+			deb_ee("\n");*/
+	}
+
+	return 0;
+}
+
+/* USB Driver stuff */
+static struct dvb_usb_properties nova_t_properties;
+
+static int nova_t_probe(struct usb_interface *intf,
+		const struct usb_device_id *id)
+{
+	return dvb_usb_device_init(intf,&nova_t_properties,THIS_MODULE);
+}
+
+/* do not change the order of the ID table */
+static struct usb_device_id nova_t_table [] = {
+/* 00 */	{ USB_DEVICE(USB_VID_HAUPPAUGE,     USB_PID_WINTV_NOVA_T_USB2_COLD) },
+/* 01 */	{ USB_DEVICE(USB_VID_HAUPPAUGE,     USB_PID_WINTV_NOVA_T_USB2_WARM) },
+			{ }		/* Terminating entry */
+};
+MODULE_DEVICE_TABLE (usb, nova_t_table);
+
+static struct dvb_usb_properties nova_t_properties = {
+	.caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER,
+	.pid_filter_count = 32,
+
+	.usb_ctrl = CYPRESS_FX2,
+	.firmware = "dvb-usb-nova-t-usb2-01.fw",
+
+	.size_of_priv     = sizeof(struct dibusb_state),
+
+	.streaming_ctrl   = dibusb2_0_streaming_ctrl,
+	.pid_filter       = dibusb_pid_filter,
+	.pid_filter_ctrl  = dibusb_pid_filter_ctrl,
+	.power_ctrl       = dibusb2_0_power_ctrl,
+	.frontend_attach  = dibusb_dib3000mc_frontend_attach,
+	.tuner_attach     = dibusb_dib3000mc_tuner_attach,
+	.read_mac_address = nova_t_read_mac_address,
+
+	.rc_interval      = 100,
+	.rc_key_map       = haupp_rc_keys,
+	.rc_key_map_size  = ARRAY_SIZE(haupp_rc_keys),
+	.rc_query         = nova_t_rc_query,
+
+	.i2c_algo         = &dibusb_i2c_algo,
+
+	.generic_bulk_ctrl_endpoint = 0x01,
+	/* parameter for the MPEG2-data transfer */
+	.urb = {
+		.type = DVB_USB_BULK,
+		.count = 7,
+		.endpoint = 0x06,
+		.u = {
+			.bulk = {
+				.buffersize = 4096,
+			}
+		}
+	},
+
+	.num_device_descs = 1,
+	.devices = {
+		{   "Hauppauge WinTV-NOVA-T usb2",
+			{ &nova_t_table[0], NULL },
+			{ &nova_t_table[1], NULL },
+		},
+	}
+};
+
+static struct usb_driver nova_t_driver = {
+	.owner		= THIS_MODULE,
+	.name		= "dvb_usb_nova_t_usb2",
+	.probe		= nova_t_probe,
+	.disconnect = dvb_usb_device_exit,
+	.id_table	= nova_t_table,
+};
+
+/* module stuff */
+static int __init nova_t_module_init(void)
+{
+	int result;
+	if ((result = usb_register(&nova_t_driver))) {
+		err("usb_register failed. Error number %d",result);
+		return result;
+	}
+
+	return 0;
+}
+
+static void __exit nova_t_module_exit(void)
+{
+	/* deregister this driver from the USB subsystem */
+	usb_deregister(&nova_t_driver);
+}
+
+module_init (nova_t_module_init);
+module_exit (nova_t_module_exit);
+
+MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
+MODULE_DESCRIPTION("Hauppauge WinTV-NOVA-T usb2");
+MODULE_VERSION("1.0");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/umt-010.c b/drivers/media/dvb/dvb-usb/umt-010.c
new file mode 100644
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/umt-010.c
@@ -0,0 +1,162 @@
+/* DVB USB framework compliant Linux driver for the HanfTek UMT-010 USB2.0
+ * DVB-T receiver.
+ *
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ *
+ *	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, version 2.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+#include "dibusb.h"
+
+#include "mt352.h"
+
+static int umt_mt352_demod_init(struct dvb_frontend *fe)
+{
+	static u8 mt352_clock_config[] = { 0x89, 0xb8, 0x2d };
+	static u8 mt352_reset[] = { 0x50, 0x80 };
+	static u8 mt352_mclk_ratio[] = { 0x8b, 0x00 };
+	static u8 mt352_adc_ctl_1_cfg[] = { 0x8E, 0x40 };
+	static u8 mt352_agc_cfg[] = { 0x67, 0x10, 0xa0 };
+
+	static u8 mt352_sec_agc_cfg1[] = { 0x6a, 0xff };
+	static u8 mt352_sec_agc_cfg2[] = { 0x6d, 0xff };
+	static u8 mt352_sec_agc_cfg3[] = { 0x70, 0x40 };
+	static u8 mt352_sec_agc_cfg4[] = { 0x7b, 0x03 };
+	static u8 mt352_sec_agc_cfg5[] = { 0x7d, 0x0f };
+
+	static u8 mt352_acq_ctl[] = { 0x53, 0x50 };
+	static u8 mt352_input_freq_1[] = { 0x56, 0x31, 0x06 };
+
+	mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config));
+	udelay(2000);
+	mt352_write(fe, mt352_reset, sizeof(mt352_reset));
+	mt352_write(fe, mt352_mclk_ratio, sizeof(mt352_mclk_ratio));
+
+	mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg));
+	mt352_write(fe, mt352_agc_cfg, sizeof(mt352_agc_cfg));
+
+	mt352_write(fe, mt352_sec_agc_cfg1, sizeof(mt352_sec_agc_cfg1));
+	mt352_write(fe, mt352_sec_agc_cfg2, sizeof(mt352_sec_agc_cfg2));
+	mt352_write(fe, mt352_sec_agc_cfg3, sizeof(mt352_sec_agc_cfg3));
+	mt352_write(fe, mt352_sec_agc_cfg4, sizeof(mt352_sec_agc_cfg4));
+	mt352_write(fe, mt352_sec_agc_cfg5, sizeof(mt352_sec_agc_cfg5));
+
+	mt352_write(fe, mt352_acq_ctl, sizeof(mt352_acq_ctl));
+	mt352_write(fe, mt352_input_freq_1, sizeof(mt352_input_freq_1));
+
+	return 0;
+}
+
+static int umt_mt352_frontend_attach(struct dvb_usb_device *d)
+{
+	struct mt352_config umt_config;
+
+	memset(&umt_config,0,sizeof(struct mt352_config));
+	umt_config.demod_init = umt_mt352_demod_init;
+	umt_config.demod_address = 0xf;
+	umt_config.pll_set = dvb_usb_pll_set;
+
+	d->fe = mt352_attach(&umt_config, &d->i2c_adap);
+
+	return 0;
+}
+
+static int umt_tuner_attach (struct dvb_usb_device *d)
+{
+	d->pll_addr = 0x61;
+	d->pll_desc = &dvb_pll_tua6034;
+	return 0;
+}
+
+/* USB Driver stuff */
+static struct dvb_usb_properties umt_properties;
+
+static int umt_probe(struct usb_interface *intf,
+		const struct usb_device_id *id)
+{
+	if (dvb_usb_device_init(intf,&umt_properties,THIS_MODULE) == 0)
+		return 0;
+	return -EINVAL;
+}
+
+/* do not change the order of the ID table */
+static struct usb_device_id umt_table [] = {
+/* 00 */	{ USB_DEVICE(USB_VID_HANFTEK,		USB_PID_HANFTEK_UMT_010_COLD) },
+/* 01 */	{ USB_DEVICE(USB_VID_HANFTEK,		USB_PID_HANFTEK_UMT_010_WARM) },
+			{ }		/* Terminating entry */
+};
+MODULE_DEVICE_TABLE (usb, umt_table);
+
+static struct dvb_usb_properties umt_properties = {
+	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
+
+	.usb_ctrl = CYPRESS_FX2,
+	.firmware = "dvb-usb-umt-010-02.fw",
+
+	.size_of_priv     = sizeof(struct dibusb_state),
+
+	.streaming_ctrl   = dibusb2_0_streaming_ctrl,
+	.power_ctrl       = dibusb_power_ctrl,
+	.frontend_attach  = umt_mt352_frontend_attach,
+	.tuner_attach     = umt_tuner_attach,
+
+	.i2c_algo         = &dibusb_i2c_algo,
+
+	.generic_bulk_ctrl_endpoint = 0x01,
+	/* parameter for the MPEG2-data transfer */
+	.urb = {
+		.type = DVB_USB_BULK,
+		.count = 20,
+		.endpoint = 0x06,
+		.u = {
+			.bulk = {
+				.buffersize = 512,
+			}
+		}
+	},
+
+	.num_device_descs = 1,
+	.devices = {
+		{	"Hanftek UMT-010 DVB-T USB2.0",
+			{ &umt_table[0], NULL },
+			{ &umt_table[1], NULL },
+		},
+	}
+};
+
+static struct usb_driver umt_driver = {
+	.owner		= THIS_MODULE,
+	.name		= "dvb_usb_umt_010",
+	.probe		= umt_probe,
+	.disconnect = dvb_usb_device_exit,
+	.id_table	= umt_table,
+};
+
+/* module stuff */
+static int __init umt_module_init(void)
+{
+	int result;
+	if ((result = usb_register(&umt_driver))) {
+		err("usb_register failed. Error number %d",result);
+		return result;
+	}
+
+	return 0;
+}
+
+static void __exit umt_module_exit(void)
+{
+	/* deregister this driver from the USB subsystem */
+	usb_deregister(&umt_driver);
+}
+
+module_init (umt_module_init);
+module_exit (umt_module_exit);
+
+MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
+MODULE_DESCRIPTION("Driver for HanfTek UMT 010 USB2.0 DVB-T device");
+MODULE_VERSION("1.0");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/vp7045-fe.c b/drivers/media/dvb/dvb-usb/vp7045-fe.c
new file mode 100644
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/vp7045-fe.c
@@ -0,0 +1,196 @@
+/* DVB frontend part of the Linux driver for TwinhanDTV Alpha/MagicBoxII USB2.0
+ * DVB-T receiver.
+ *
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ *
+ * Thanks to Twinhan who kindly provided hardware and information.
+ *
+ *	This program is free software; you can redistribute it and/or modify it
+ *	under the terms of the GNU General Public License as published by the Free
+ *	Software Foundation, version 2.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ *
+ */
+#include "vp7045.h"
+
+/* It is a Zarlink MT352 within a Samsung Tuner (DNOS404ZH102A) - 040929 - AAT
+ *
+ * Programming is hidden inside the firmware, so set_frontend is very easy.
+ * Even though there is a Firmware command that one can use to access the demod
+ * via its registers. This is used for status information.
+ */
+
+struct vp7045_fe_state {
+	struct dvb_frontend fe;
+	struct dvb_usb_device *d;
+};
+
+
+static int vp7045_fe_read_status(struct dvb_frontend* fe, fe_status_t *status)
+{
+	struct vp7045_fe_state *state = fe->demodulator_priv;
+	u8 s0 = vp7045_read_reg(state->d,0x00),
+	   s1 = vp7045_read_reg(state->d,0x01),
+	   s3 = vp7045_read_reg(state->d,0x03);
+
+	*status = 0;
+	if (s0 & (1 << 4))
+		*status |= FE_HAS_CARRIER;
+	if (s0 & (1 << 1))
+		*status |= FE_HAS_VITERBI;
+	if (s0 & (1 << 5))
+		*status |= FE_HAS_LOCK;
+	if (s1 & (1 << 1))
+		*status |= FE_HAS_SYNC;
+	if (s3 & (1 << 6))
+		*status |= FE_HAS_SIGNAL;
+
+	if ((*status & (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC)) !=
+			(FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC))
+		*status &= ~FE_HAS_LOCK;
+
+	return 0;
+}
+
+static int vp7045_fe_read_ber(struct dvb_frontend* fe, u32 *ber)
+{
+	struct vp7045_fe_state *state = fe->demodulator_priv;
+	*ber = (vp7045_read_reg(state->d, 0x0D) << 16) |
+	       (vp7045_read_reg(state->d, 0x0E) << 8) |
+	        vp7045_read_reg(state->d, 0x0F);
+	return 0;
+}
+
+static int vp7045_fe_read_unc_blocks(struct dvb_frontend* fe, u32 *unc)
+{
+	struct vp7045_fe_state *state = fe->demodulator_priv;
+	*unc = (vp7045_read_reg(state->d, 0x10) << 8) |
+		    vp7045_read_reg(state->d, 0x11);
+	return 0;
+}
+
+static int vp7045_fe_read_signal_strength(struct dvb_frontend* fe, u16 *strength)
+{
+	struct vp7045_fe_state *state = fe->demodulator_priv;
+	u16 signal = (vp7045_read_reg(state->d, 0x14) << 8) |
+		vp7045_read_reg(state->d, 0x15);
+
+	*strength = ~signal;
+	return 0;
+}
+
+static int vp7045_fe_read_snr(struct dvb_frontend* fe, u16 *snr)
+{
+	struct vp7045_fe_state *state = fe->demodulator_priv;
+	u8 _snr = vp7045_read_reg(state->d, 0x09);
+	*snr = (_snr << 8) | _snr;
+	return 0;
+}
+
+static int vp7045_fe_init(struct dvb_frontend* fe)
+{
+	return 0;
+}
+
+static int vp7045_fe_sleep(struct dvb_frontend* fe)
+{
+	return 0;
+}
+
+static int vp7045_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
+{
+	tune->min_delay_ms = 800;
+	return 0;
+}
+
+static int vp7045_fe_set_frontend(struct dvb_frontend* fe,
+				  struct dvb_frontend_parameters *fep)
+{
+	struct vp7045_fe_state *state = fe->demodulator_priv;
+	u8 buf[5];
+	u32 freq = fep->frequency / 1000;
+
+	buf[0] = (freq >> 16) & 0xff;
+	buf[1] = (freq >>  8) & 0xff;
+	buf[2] =  freq        & 0xff;
+	buf[3] = 0;
+
+	switch (fep->u.ofdm.bandwidth) {
+		case BANDWIDTH_8_MHZ: buf[4] = 8; break;
+		case BANDWIDTH_7_MHZ: buf[4] = 7; break;
+		case BANDWIDTH_6_MHZ: buf[4] = 6; break;
+		case BANDWIDTH_AUTO: return -EOPNOTSUPP;
+		default:
+			return -EINVAL;
+	}
+
+	vp7045_usb_op(state->d,LOCK_TUNER_COMMAND,buf,5,NULL,0,200);
+	return 0;
+}
+
+static int vp7045_fe_get_frontend(struct dvb_frontend* fe,
+				  struct dvb_frontend_parameters *fep)
+{
+	return 0;
+}
+
+static void vp7045_fe_release(struct dvb_frontend* fe)
+{
+	struct vp7045_fe_state *state = fe->demodulator_priv;
+	kfree(state);
+}
+
+static struct dvb_frontend_ops vp7045_fe_ops;
+
+struct dvb_frontend * vp7045_fe_attach(struct dvb_usb_device *d)
+{
+	struct vp7045_fe_state *s = kmalloc(sizeof(struct vp7045_fe_state), GFP_KERNEL);
+	if (s == NULL)
+		goto error;
+	memset(s,0,sizeof(struct vp7045_fe_state));
+
+	s->d = d;
+	s->fe.ops = &vp7045_fe_ops;
+	s->fe.demodulator_priv = s;
+
+	goto success;
+error:
+	return NULL;
+success:
+	return &s->fe;
+}
+
+
+static struct dvb_frontend_ops vp7045_fe_ops = {
+	.info = {
+		.name			= "Twinhan VP7045/46 USB DVB-T",
+		.type			= FE_OFDM,
+		.frequency_min		= 44250000,
+		.frequency_max		= 867250000,
+		.frequency_stepsize	= 1000,
+		.caps = FE_CAN_INVERSION_AUTO |
+				FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+				FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+				FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
+				FE_CAN_TRANSMISSION_MODE_AUTO |
+				FE_CAN_GUARD_INTERVAL_AUTO |
+				FE_CAN_RECOVER |
+				FE_CAN_HIERARCHY_AUTO,
+	},
+
+	.release = vp7045_fe_release,
+
+	.init = vp7045_fe_init,
+	.sleep = vp7045_fe_sleep,
+
+	.set_frontend = vp7045_fe_set_frontend,
+	.get_frontend = vp7045_fe_get_frontend,
+	.get_tune_settings = vp7045_fe_get_tune_settings,
+
+	.read_status = vp7045_fe_read_status,
+	.read_ber = vp7045_fe_read_ber,
+	.read_signal_strength = vp7045_fe_read_signal_strength,
+	.read_snr = vp7045_fe_read_snr,
+	.read_ucblocks = vp7045_fe_read_unc_blocks,
+};
diff --git a/drivers/media/dvb/dvb-usb/vp7045.c b/drivers/media/dvb/dvb-usb/vp7045.c
new file mode 100644
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/vp7045.c
@@ -0,0 +1,288 @@
+/* DVB USB compliant Linux driver for the
+ *  - TwinhanDTV Alpha/MagicBoxII USB2.0 DVB-T receiver
+ *  - DigitalNow TinyUSB2 DVB-t receiver
+ *
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ *
+ * Thanks to Twinhan who kindly provided hardware and information.
+ *
+ *	This program is free software; you can redistribute it and/or modify it
+ *	under the terms of the GNU General Public License as published by the Free
+ *	Software Foundation, version 2.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+#include "vp7045.h"
+
+/* debug */
+int dvb_usb_vp7045_debug;
+module_param_named(debug,dvb_usb_vp7045_debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))." DVB_USB_DEBUG_STATUS);
+
+int vp7045_usb_op(struct dvb_usb_device *d, u8 cmd, u8 *out, int outlen, u8 *in, int inlen, int msec)
+{
+	int ret = 0;
+	u8 inbuf[12] = { 0 }, outbuf[20] = { 0 };
+
+	outbuf[0] = cmd;
+
+	if (outlen > 19)
+		outlen = 19;
+
+	if (inlen > 11)
+		inlen = 11;
+
+	if (out != NULL && outlen > 0)
+		memcpy(&outbuf[1], out, outlen);
+
+	deb_xfer("out buffer: ");
+	debug_dump(outbuf,outlen+1,deb_xfer);
+
+	if ((ret = down_interruptible(&d->usb_sem)))
+		return ret;
+
+	if (usb_control_msg(d->udev,
+			usb_sndctrlpipe(d->udev,0),
+			TH_COMMAND_OUT, USB_TYPE_VENDOR | USB_DIR_OUT, 0, 0,
+			outbuf, 20, 2000) != 20) {
+		err("USB control message 'out' went wrong.");
+		ret = -EIO;
+		goto unlock;
+	}
+
+	msleep(msec);
+
+	if (usb_control_msg(d->udev,
+			usb_rcvctrlpipe(d->udev,0),
+			TH_COMMAND_IN, USB_TYPE_VENDOR | USB_DIR_IN, 0, 0,
+			inbuf, 12, 2000) != 12) {
+		err("USB control message 'in' went wrong.");
+		ret = -EIO;
+		goto unlock;
+	}
+
+	deb_xfer("in buffer: ");
+	debug_dump(inbuf,12,deb_xfer);
+
+	if (in != NULL && inlen > 0)
+		memcpy(in,&inbuf[1],inlen);
+
+unlock:
+	up(&d->usb_sem);
+
+	return ret;
+}
+
+u8 vp7045_read_reg(struct dvb_usb_device *d, u8 reg)
+{
+	u8 obuf[2] = { 0 },v;
+	obuf[1] = reg;
+
+	vp7045_usb_op(d,TUNER_REG_READ,obuf,2,&v,1,30);
+
+	return v;
+}
+
+static int vp7045_power_ctrl(struct dvb_usb_device *d, int onoff)
+{
+	u8 v = onoff;
+	return vp7045_usb_op(d,SET_TUNER_POWER,&v,1,NULL,0,150);
+}
+
+/* remote control stuff */
+
+/* The keymapping struct. Somehow this should be loaded to the driver, but
+ * currently it is hardcoded. */
+static struct dvb_usb_rc_key vp7045_rc_keys[] = {
+	{ 0x00, 0x16, KEY_POWER },
+	{ 0x00, 0x10, KEY_MUTE },
+	{ 0x00, 0x03, KEY_1 },
+	{ 0x00, 0x01, KEY_2 },
+	{ 0x00, 0x06, KEY_3 },
+	{ 0x00, 0x09, KEY_4 },
+	{ 0x00, 0x1d, KEY_5 },
+	{ 0x00, 0x1f, KEY_6 },
+	{ 0x00, 0x0d, KEY_7 },
+	{ 0x00, 0x19, KEY_8 },
+	{ 0x00, 0x1b, KEY_9 },
+	{ 0x00, 0x15, KEY_0 },
+	{ 0x00, 0x05, KEY_CHANNELUP },
+	{ 0x00, 0x02, KEY_CHANNELDOWN },
+	{ 0x00, 0x1e, KEY_VOLUMEUP },
+	{ 0x00, 0x0a, KEY_VOLUMEDOWN },
+	{ 0x00, 0x11, KEY_RECORD },
+	{ 0x00, 0x17, KEY_FAVORITES }, /* Heart symbol - Channel list. */
+	{ 0x00, 0x14, KEY_PLAY },
+	{ 0x00, 0x1a, KEY_STOP },
+	{ 0x00, 0x40, KEY_REWIND },
+	{ 0x00, 0x12, KEY_FASTFORWARD },
+	{ 0x00, 0x0e, KEY_PREVIOUS }, /* Recall - Previous channel. */
+	{ 0x00, 0x4c, KEY_PAUSE },
+	{ 0x00, 0x4d, KEY_SCREEN }, /* Full screen mode. */
+	{ 0x00, 0x54, KEY_AUDIO }, /* MTS - Switch to secondary audio. */
+	{ 0x00, 0x0c, KEY_CANCEL }, /* Cancel */
+	{ 0x00, 0x1c, KEY_EPG }, /* EPG */
+	{ 0x00, 0x00, KEY_TAB }, /* Tab */
+	{ 0x00, 0x48, KEY_INFO }, /* Preview */
+	{ 0x00, 0x04, KEY_LIST }, /* RecordList */
+	{ 0x00, 0x0f, KEY_TEXT } /* Teletext */
+};
+
+static int vp7045_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
+{
+	u8 key;
+	int i;
+	vp7045_usb_op(d,RC_VAL_READ,NULL,0,&key,1,20);
+
+	deb_rc("remote query key: %x %d\n",key,key);
+
+	if (key == 0x44) {
+		*state = REMOTE_NO_KEY_PRESSED;
+		return 0;
+	}
+
+	for (i = 0; i < sizeof(vp7045_rc_keys)/sizeof(struct dvb_usb_rc_key); i++)
+		if (vp7045_rc_keys[i].data == key) {
+			*state = REMOTE_KEY_PRESSED;
+			*event = vp7045_rc_keys[i].event;
+			break;
+		}
+	return 0;
+}
+
+static int vp7045_read_eeprom(struct dvb_usb_device *d,u8 *buf, int len, int offset)
+{
+	int i = 0;
+	u8 v,br[2];
+	for (i=0; i < len; i++) {
+		v = offset + i;
+		vp7045_usb_op(d,GET_EE_VALUE,&v,1,br,2,5);
+		buf[i] = br[1];
+	}
+	deb_info("VP7045 EEPROM read (offs: %d, len: %d) : ",offset, i);
+	debug_dump(buf,i,deb_info);
+	return 0;
+}
+
+
+static int vp7045_read_mac_addr(struct dvb_usb_device *d,u8 mac[6])
+{
+	return vp7045_read_eeprom(d,mac, 6, MAC_0_ADDR);
+}
+
+static int vp7045_frontend_attach(struct dvb_usb_device *d)
+{
+	u8 buf[255] = { 0 };
+
+	vp7045_usb_op(d,VENDOR_STRING_READ,NULL,0,buf,20,0);
+	buf[10] = '\0';
+	deb_info("firmware says: %s ",buf);
+
+	vp7045_usb_op(d,PRODUCT_STRING_READ,NULL,0,buf,20,0);
+	buf[10] = '\0';
+	deb_info("%s ",buf);
+
+	vp7045_usb_op(d,FW_VERSION_READ,NULL,0,buf,20,0);
+	buf[10] = '\0';
+	deb_info("v%s\n",buf);
+
+/*	Dump the EEPROM */
+/*	vp7045_read_eeprom(d,buf, 255, FX2_ID_ADDR); */
+
+	d->fe = vp7045_fe_attach(d);
+
+	return 0;
+}
+
+static struct dvb_usb_properties vp7045_properties;
+
+static int vp7045_usb_probe(struct usb_interface *intf,
+		const struct usb_device_id *id)
+{
+	return dvb_usb_device_init(intf,&vp7045_properties,THIS_MODULE);
+}
+
+static struct usb_device_id vp7045_usb_table [] = {
+	    { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7045_COLD) },
+	    { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7045_WARM) },
+	    { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_DNTV_TINYUSB2_COLD) },
+	    { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_DNTV_TINYUSB2_WARM) },
+	    { 0 },
+};
+MODULE_DEVICE_TABLE(usb, vp7045_usb_table);
+
+static struct dvb_usb_properties vp7045_properties = {
+	.caps = 0,
+
+	.usb_ctrl = CYPRESS_FX2,
+	.firmware = "dvb-usb-vp7045-01.fw",
+
+	.power_ctrl       = vp7045_power_ctrl,
+	.frontend_attach  = vp7045_frontend_attach,
+	.read_mac_address = vp7045_read_mac_addr,
+
+	.rc_interval      = 400,
+	.rc_key_map       = vp7045_rc_keys,
+	.rc_key_map_size  = ARRAY_SIZE(vp7045_rc_keys),
+	.rc_query         = vp7045_rc_query,
+
+	/* parameter for the MPEG2-data transfer */
+	.urb = {
+		.type = DVB_USB_BULK,
+		.count = 7,
+		.endpoint = 0x02,
+		.u = {
+			.bulk = {
+				.buffersize = 4096,
+			}
+		}
+	},
+
+	.num_device_descs = 2,
+	.devices = {
+		{ .name = "Twinhan USB2.0 DVB-T receiver (TwinhanDTV Alpha/MagicBox II)",
+		  .cold_ids = { &vp7045_usb_table[0], NULL },
+		  .warm_ids = { &vp7045_usb_table[1], NULL },
+		},
+		{ .name = "DigitalNow TinyUSB 2 DVB-t Receiver",
+		  .cold_ids = { &vp7045_usb_table[2], NULL },
+		  .warm_ids = { &vp7045_usb_table[3], NULL },
+		},
+		{ 0 },
+	}
+};
+
+/* usb specific object needed to register this driver with the usb subsystem */
+static struct usb_driver vp7045_usb_driver = {
+	.owner		= THIS_MODULE,
+	.name		= "dvb_usb_vp7045",
+	.probe 		= vp7045_usb_probe,
+	.disconnect = dvb_usb_device_exit,
+	.id_table 	= vp7045_usb_table,
+};
+
+/* module stuff */
+static int __init vp7045_usb_module_init(void)
+{
+	int result;
+	if ((result = usb_register(&vp7045_usb_driver))) {
+		err("usb_register failed. (%d)",result);
+		return result;
+	}
+
+	return 0;
+}
+
+static void __exit vp7045_usb_module_exit(void)
+{
+	/* deregister this driver from the USB subsystem */
+	usb_deregister(&vp7045_usb_driver);
+}
+
+module_init(vp7045_usb_module_init);
+module_exit(vp7045_usb_module_exit);
+
+MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
+MODULE_DESCRIPTION("Driver for Twinhan MagicBox/Alpha and DNTV tinyUSB2 DVB-T USB2.0");
+MODULE_VERSION("1.0");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/vp7045.h b/drivers/media/dvb/dvb-usb/vp7045.h
new file mode 100644
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/vp7045.h
@@ -0,0 +1,78 @@
+/* Common header-file of the Linux driver for the TwinhanDTV Alpha/MagicBoxII
+ * USB2.0 DVB-T receiver.
+ *
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ *
+ * Thanks to Twinhan who kindly provided hardware and information.
+ *
+ *	This program is free software; you can redistribute it and/or modify it
+ *	under the terms of the GNU General Public License as published by the Free
+ *	Software Foundation, version 2.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+#ifndef _DVB_USB_VP7045_H_
+#define _DVB_USB_VP7045_H_
+
+#define DVB_USB_LOG_PREFIX "vp7045"
+#include "dvb-usb.h"
+
+extern int dvb_usb_vp7045_debug;
+#define deb_info(args...) dprintk(dvb_usb_vp7045_debug,0x01,args)
+#define deb_xfer(args...) dprintk(dvb_usb_vp7045_debug,0x02,args)
+#define deb_rc(args...)   dprintk(dvb_usb_vp7045_debug,0x04,args)
+
+/* vp7045 commands */
+
+/* Twinhan Vendor requests */
+#define TH_COMMAND_IN                     0xC0
+#define TH_COMMAND_OUT                    0xC1
+
+/* command bytes */
+#define TUNER_REG_READ                    0x03
+#define TUNER_REG_WRITE                   0x04
+
+#define RC_VAL_READ                       0x05
+ #define RC_NO_KEY                        0x44
+
+#define SET_TUNER_POWER                   0x06
+#define CHECK_TUNER_POWER                 0x12
+ #define Tuner_Power_ON                   1
+ #define Tuner_Power_OFF                  0
+
+#define GET_USB_SPEED                     0x07
+ #define USB_SPEED_LOW                    0
+ #define USB_SPEED_FULL                   1
+ #define USB_SPEED_HIGH                   2
+
+#define LOCK_TUNER_COMMAND                0x09
+
+#define TUNER_SIGNAL_READ                 0x0A
+
+/* FX2 eeprom */
+#define SET_EE_VALUE                      0x10
+#define GET_EE_VALUE                      0x11
+ #define FX2_ID_ADDR                      0x00
+ #define VID_MSB_ADDR                     0x02
+ #define VID_LSB_ADDR                     0x01
+ #define PID_MSB_ADDR                     0x04
+ #define PID_LSB_ADDR                     0x03
+ #define MAC_0_ADDR                       0x07
+ #define MAC_1_ADDR                       0x08
+ #define MAC_2_ADDR                       0x09
+ #define MAC_3_ADDR                       0x0a
+ #define MAC_4_ADDR                       0x0b
+ #define MAC_5_ADDR                       0x0c
+
+#define RESET_FX2                         0x13
+
+#define FW_VERSION_READ                   0x0B
+#define VENDOR_STRING_READ                0x0C
+#define PRODUCT_STRING_READ               0x0D
+#define FW_BCD_VERSION_READ               0x14
+
+extern struct dvb_frontend * vp7045_fe_attach(struct dvb_usb_device *d);
+extern int vp7045_usb_op(struct dvb_usb_device *d, u8 cmd, u8 *out, int outlen, u8 *in, int inlen,int msec);
+extern u8 vp7045_read_reg(struct dvb_usb_device *d, u8 reg);
+
+#endif
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig
--- a/drivers/media/dvb/frontends/Kconfig
+++ b/drivers/media/dvb/frontends/Kconfig
@@ -40,6 +40,12 @@ config DVB_VES1X93
 	help
 	  A DVB-S tuner module. Say Y when you want to support this frontend.
 
+config DVB_S5H1420
+	tristate "Samsung S5H1420 based"
+	depends on DVB_CORE
+	help
+	  A DVB-S tuner module. Say Y when you want to support this frontend.
+
 comment "DVB-T (terrestrial) frontends"
 	depends on DVB_CORE
 
@@ -173,4 +179,19 @@ config DVB_OR51132
 	  An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
 	  to support this frontend.
 
+config DVB_BCM3510
+	tristate "Broadcom BCM3510"
+	depends on DVB_CORE
+	select FW_LOADER
+	help
+	  An ATSC 8VSB/16VSB and QAM64/256 tuner module. Say Y when you want to
+	  support this frontend.
+
+config DVB_LGDT330X
+	tristate "LG Electronics LGDT3302/LGDT3303 based"
+	depends on DVB_CORE
+	help
+	  An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
+	  to support this frontend.
+
 endmenu
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile
--- a/drivers/media/dvb/frontends/Makefile
+++ b/drivers/media/dvb/frontends/Makefile
@@ -28,3 +28,6 @@ obj-$(CONFIG_DVB_STV0297) += stv0297.o
 obj-$(CONFIG_DVB_NXT2002) += nxt2002.o
 obj-$(CONFIG_DVB_OR51211) += or51211.o
 obj-$(CONFIG_DVB_OR51132) += or51132.o
+obj-$(CONFIG_DVB_BCM3510) += bcm3510.o
+obj-$(CONFIG_DVB_S5H1420) += s5h1420.o
+obj-$(CONFIG_DVB_LGDT330X) += lgdt330x.o
diff --git a/drivers/media/dvb/frontends/bcm3510.c b/drivers/media/dvb/frontends/bcm3510.c
new file mode 100644
--- /dev/null
+++ b/drivers/media/dvb/frontends/bcm3510.c
@@ -0,0 +1,853 @@
+/*
+ * Support for the Broadcom BCM3510 ATSC demodulator (1st generation Air2PC)
+ *
+ *  Copyright (C) 2001-5, B2C2 inc.
+ *
+ *  GPL/Linux driver written by Patrick Boettcher <patrick.boettcher@desy.de>
+ *
+ *  This driver is "hard-coded" to be used with the 1st generation of
+ *  Technisat/B2C2's Air2PC ATSC PCI/USB cards/boxes. The pll-programming
+ *  (Panasonic CT10S) is located here, which is actually wrong. Unless there is
+ *  another device with a BCM3510, this is no problem.
+ *
+ *  The driver works also with QAM64 DVB-C, but had an unreasonable high
+ *  UNC. (Tested with the Air2PC ATSC 1st generation)
+ *
+ *  You'll need a firmware for this driver in order to get it running. It is
+ *  called "dvb-fe-bcm3510-01.fw".
+ *
+ * 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 <linux/init.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/device.h>
+#include <linux/firmware.h>
+
+#include "dvb_frontend.h"
+#include "bcm3510.h"
+#include "bcm3510_priv.h"
+
+struct bcm3510_state {
+
+	struct i2c_adapter* i2c;
+	struct dvb_frontend_ops ops;
+	const struct bcm3510_config* config;
+	struct dvb_frontend frontend;
+
+	/* demodulator private data */
+	struct semaphore hab_sem;
+	u8 firmware_loaded:1;
+
+	unsigned long next_status_check;
+	unsigned long status_check_interval;
+	struct bcm3510_hab_cmd_status1 status1;
+	struct bcm3510_hab_cmd_status2 status2;
+};
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level (1=info,2=i2c (|-able)).");
+
+#define dprintk(level,x...) if (level & debug) printk(x)
+#define dbufout(b,l,m) {\
+	    int i; \
+	    for (i = 0; i < l; i++) \
+	        m("%02x ",b[i]); \
+}
+#define deb_info(args...) dprintk(0x01,args)
+#define deb_i2c(args...)  dprintk(0x02,args)
+#define deb_hab(args...)  dprintk(0x04,args)
+
+/* transfer functions */
+static int bcm3510_writebytes (struct bcm3510_state *state, u8 reg, u8 *buf, u8 len)
+{
+	u8 b[256];
+	int err;
+	struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = b, .len = len + 1 };
+
+	b[0] = reg;
+	memcpy(&b[1],buf,len);
+
+	deb_i2c("i2c wr %02x: ",reg);
+	dbufout(buf,len,deb_i2c);
+	deb_i2c("\n");
+
+	if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
+
+		deb_info("%s: i2c write error (addr %02x, reg %02x, err == %i)\n",
+			__FUNCTION__, state->config->demod_address, reg,  err);
+		return -EREMOTEIO;
+	}
+
+	return 0;
+}
+
+static int bcm3510_readbytes (struct bcm3510_state *state, u8 reg, u8 *buf, u8 len)
+{
+	struct i2c_msg msg[] = {
+		{ .addr = state->config->demod_address, .flags = 0,        .buf = &reg, .len = 1 },
+		{ .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = buf,  .len = len }
+	};
+	int err;
+
+	memset(buf,0,len);
+
+	if ((err = i2c_transfer (state->i2c, msg, 2)) != 2) {
+		deb_info("%s: i2c read error (addr %02x, reg %02x, err == %i)\n",
+			__FUNCTION__, state->config->demod_address, reg,  err);
+		return -EREMOTEIO;
+	}
+	deb_i2c("i2c rd %02x: ",reg);
+	dbufout(buf,len,deb_i2c);
+	deb_i2c("\n");
+
+	return 0;
+}
+
+static int bcm3510_writeB(struct bcm3510_state *state, u8 reg, bcm3510_register_value v)
+{
+	return bcm3510_writebytes(state,reg,&v.raw,1);
+}
+
+static int bcm3510_readB(struct bcm3510_state *state, u8 reg, bcm3510_register_value *v)
+{
+	return bcm3510_readbytes(state,reg,&v->raw,1);
+}
+
+/* Host Access Buffer transfers */
+static int bcm3510_hab_get_response(struct bcm3510_state *st, u8 *buf, int len)
+{
+	bcm3510_register_value v;
+	int ret,i;
+
+	v.HABADR_a6.HABADR = 0;
+	if ((ret = bcm3510_writeB(st,0xa6,v)) < 0)
+		return ret;
+
+	for (i = 0; i < len; i++) {
+		if ((ret = bcm3510_readB(st,0xa7,&v)) < 0)
+			return ret;
+		buf[i] = v.HABDATA_a7;
+	}
+	return 0;
+}
+
+static int bcm3510_hab_send_request(struct bcm3510_state *st, u8 *buf, int len)
+{
+	bcm3510_register_value v,hab;
+	int ret,i;
+	unsigned long t;
+
+/* Check if any previous HAB request still needs to be serviced by the
+ * Aquisition Processor before sending new request */
+	if ((ret = bcm3510_readB(st,0xa8,&v)) < 0)
+		return ret;
+	if (v.HABSTAT_a8.HABR) {
+		deb_info("HAB is running already - clearing it.\n");
+		v.HABSTAT_a8.HABR = 0;
+		bcm3510_writeB(st,0xa8,v);
+//		return -EBUSY;
+	}
+
+/* Send the start HAB Address (automatically incremented after write of
+ * HABDATA) and write the HAB Data */
+	hab.HABADR_a6.HABADR = 0;
+	if ((ret = bcm3510_writeB(st,0xa6,hab)) < 0)
+		return ret;
+
+	for (i = 0; i < len; i++) {
+		hab.HABDATA_a7 = buf[i];
+		if ((ret = bcm3510_writeB(st,0xa7,hab)) < 0)
+			return ret;
+	}
+
+/* Set the HABR bit to indicate AP request in progress (LBHABR allows HABR to
+ * be written) */
+	v.raw = 0; v.HABSTAT_a8.HABR = 1; v.HABSTAT_a8.LDHABR = 1;
+	if ((ret = bcm3510_writeB(st,0xa8,v)) < 0)
+		return ret;
+
+/* Polling method: Wait until the AP finishes processing the HAB request */
+	t = jiffies + 1*HZ;
+	while (time_before(jiffies, t)) {
+		deb_info("waiting for HAB to complete\n");
+		msleep(10);
+		if ((ret = bcm3510_readB(st,0xa8,&v)) < 0)
+			return ret;
+
+		if (!v.HABSTAT_a8.HABR)
+			return 0;
+	}
+
+	deb_info("send_request execution timed out.\n");
+	return -ETIMEDOUT;
+}
+
+static int bcm3510_do_hab_cmd(struct bcm3510_state *st, u8 cmd, u8 msgid, u8 *obuf, u8 olen, u8 *ibuf, u8 ilen)
+{
+	u8 ob[olen+2],ib[ilen+2];
+	int ret = 0;
+
+	ob[0] = cmd;
+	ob[1] = msgid;
+	memcpy(&ob[2],obuf,olen);
+
+	deb_hab("hab snd: ");
+	dbufout(ob,olen+2,deb_hab);
+	deb_hab("\n");
+
+	if (down_interruptible(&st->hab_sem) < 0)
+		return -EAGAIN;
+
+	if ((ret = bcm3510_hab_send_request(st, ob, olen+2)) < 0 ||
+		(ret = bcm3510_hab_get_response(st, ib, ilen+2)) < 0)
+		goto error;
+
+	deb_hab("hab get: ");
+	dbufout(ib,ilen+2,deb_hab);
+	deb_hab("\n");
+
+	memcpy(ibuf,&ib[2],ilen);
+error:
+	up(&st->hab_sem);
+	return ret;
+}
+
+#if 0
+/* not needed, we use a semaphore to prevent HAB races */
+static int bcm3510_is_ap_ready(struct bcm3510_state *st)
+{
+	bcm3510_register_value ap,hab;
+	int ret;
+
+	if ((ret = bcm3510_readB(st,0xa8,&hab)) < 0 ||
+		(ret = bcm3510_readB(st,0xa2,&ap) < 0))
+		return ret;
+
+	if (ap.APSTAT1_a2.RESET || ap.APSTAT1_a2.IDLE || ap.APSTAT1_a2.STOP || hab.HABSTAT_a8.HABR) {
+		deb_info("AP is busy\n");
+		return -EBUSY;
+	}
+
+	return 0;
+}
+#endif
+
+static int bcm3510_bert_reset(struct bcm3510_state *st)
+{
+	bcm3510_register_value b;
+	int ret;
+
+	if ((ret < bcm3510_readB(st,0xfa,&b)) < 0)
+		return ret;
+
+	b.BERCTL_fa.RESYNC = 0; bcm3510_writeB(st,0xfa,b);
+	b.BERCTL_fa.RESYNC = 1; bcm3510_writeB(st,0xfa,b);
+	b.BERCTL_fa.RESYNC = 0; bcm3510_writeB(st,0xfa,b);
+	b.BERCTL_fa.CNTCTL = 1; b.BERCTL_fa.BITCNT = 1; bcm3510_writeB(st,0xfa,b);
+
+	/* clear residual bit counter TODO  */
+	return 0;
+}
+
+static int bcm3510_refresh_state(struct bcm3510_state *st)
+{
+	if (time_after(jiffies,st->next_status_check)) {
+		bcm3510_do_hab_cmd(st, CMD_STATUS, MSGID_STATUS1, NULL,0, (u8 *)&st->status1, sizeof(st->status1));
+		bcm3510_do_hab_cmd(st, CMD_STATUS, MSGID_STATUS2, NULL,0, (u8 *)&st->status2, sizeof(st->status2));
+		st->next_status_check = jiffies + (st->status_check_interval*HZ)/1000;
+	}
+	return 0;
+}
+
+static int bcm3510_read_status(struct dvb_frontend *fe, fe_status_t *status)
+{
+	struct bcm3510_state* st = fe->demodulator_priv;
+	bcm3510_refresh_state(st);
+
+	*status = 0;
+	if (st->status1.STATUS1.RECEIVER_LOCK)
+		*status |= FE_HAS_LOCK | FE_HAS_SYNC;
+
+	if (st->status1.STATUS1.FEC_LOCK)
+		*status |= FE_HAS_VITERBI;
+
+	if (st->status1.STATUS1.OUT_PLL_LOCK)
+		*status |= FE_HAS_SIGNAL | FE_HAS_CARRIER;
+
+	if (*status & FE_HAS_LOCK)
+		st->status_check_interval = 1500;
+	else /* more frequently checks if no lock has been achieved yet */
+		st->status_check_interval = 500;
+
+	deb_info("real_status: %02x\n",*status);
+	return 0;
+}
+
+static int bcm3510_read_ber(struct dvb_frontend* fe, u32* ber)
+{
+	struct bcm3510_state* st = fe->demodulator_priv;
+	bcm3510_refresh_state(st);
+
+	*ber = (st->status2.LDBER0 << 16) | (st->status2.LDBER1 << 8) | st->status2.LDBER2;
+	return 0;
+}
+
+static int bcm3510_read_unc(struct dvb_frontend* fe, u32* unc)
+{
+	struct bcm3510_state* st = fe->demodulator_priv;
+	bcm3510_refresh_state(st);
+	*unc = (st->status2.LDUERC0 << 8) | st->status2.LDUERC1;
+	return 0;
+}
+
+static int bcm3510_read_signal_strength(struct dvb_frontend* fe, u16* strength)
+{
+	struct bcm3510_state* st = fe->demodulator_priv;
+	s32 t;
+
+	bcm3510_refresh_state(st);
+	t = st->status2.SIGNAL;
+
+	if (t > 190)
+		t = 190;
+	if (t < 90)
+		t = 90;
+
+	t -= 90;
+	t = t * 0xff / 100;
+	/* normalize if necessary */
+	*strength = (t << 8) | t;
+	return 0;
+}
+
+static int bcm3510_read_snr(struct dvb_frontend* fe, u16* snr)
+{
+	struct bcm3510_state* st = fe->demodulator_priv;
+	bcm3510_refresh_state(st);
+
+	*snr = st->status1.SNR_EST0*1000 + ((st->status1.SNR_EST1*1000) >> 8);
+	return 0;
+}
+
+/* tuner frontend programming */
+static int bcm3510_tuner_cmd(struct bcm3510_state* st,u8 bc, u16 n, u8 a)
+{
+	struct bcm3510_hab_cmd_tune c;
+	memset(&c,0,sizeof(struct bcm3510_hab_cmd_tune));
+
+/* I2C Mode disabled,  set 16 control / Data pairs */
+	c.length = 0x10;
+	c.clock_width = 0;
+/* CS1, CS0, DATA, CLK bits control the tuner RF_AGC_SEL pin is set to
+ * logic high (as Configuration) */
+	c.misc = 0x10;
+/* Set duration of the initial state of TUNCTL = 3.34 micro Sec */
+	c.TUNCTL_state = 0x40;
+
+/* PRESCALER DEVIDE RATIO | BC1_2_3_4; (band switch), 1stosc REFERENCE COUNTER REF_S12 and REF_S11 */
+	c.ctl_dat[0].ctrl.size = BITS_8;
+	c.ctl_dat[0].data      = 0x80 | bc;
+
+/* Control DATA pin, 1stosc REFERENCE COUNTER REF_S10 to REF_S3 */
+	c.ctl_dat[1].ctrl.size = BITS_8;
+	c.ctl_dat[1].data      = 4;
+
+/* set CONTROL BIT 1 to 1, 1stosc REFERENCE COUNTER REF_S2 to REF_S1 */
+	c.ctl_dat[2].ctrl.size = BITS_3;
+	c.ctl_dat[2].data      = 0x20;
+
+/* control CS0 pin, pulse byte ? */
+	c.ctl_dat[3].ctrl.size = BITS_3;
+	c.ctl_dat[3].ctrl.clk_off = 1;
+	c.ctl_dat[3].ctrl.cs0  = 1;
+	c.ctl_dat[3].data      = 0x40;
+
+/* PGM_S18 to PGM_S11 */
+	c.ctl_dat[4].ctrl.size = BITS_8;
+	c.ctl_dat[4].data      = n >> 3;
+
+/* PGM_S10 to PGM_S8, SWL_S7 to SWL_S3 */
+	c.ctl_dat[5].ctrl.size = BITS_8;
+	c.ctl_dat[5].data      = ((n & 0x7) << 5) | (a >> 2);
+
+/* SWL_S2 and SWL_S1, set CONTROL BIT 2 to 0 */
+	c.ctl_dat[6].ctrl.size = BITS_3;
+	c.ctl_dat[6].data      = (a << 6) & 0xdf;
+
+/* control CS0 pin, pulse byte ? */
+	c.ctl_dat[7].ctrl.size = BITS_3;
+	c.ctl_dat[7].ctrl.clk_off = 1;
+	c.ctl_dat[7].ctrl.cs0  = 1;
+	c.ctl_dat[7].data      = 0x40;
+
+/* PRESCALER DEVIDE RATIO, 2ndosc REFERENCE COUNTER REF_S12 and REF_S11 */
+	c.ctl_dat[8].ctrl.size = BITS_8;
+	c.ctl_dat[8].data      = 0x80;
+
+/* 2ndosc REFERENCE COUNTER REF_S10 to REF_S3 */
+	c.ctl_dat[9].ctrl.size = BITS_8;
+	c.ctl_dat[9].data      = 0x10;
+
+/* set CONTROL BIT 1 to 1, 2ndosc REFERENCE COUNTER REF_S2 to REF_S1 */
+	c.ctl_dat[10].ctrl.size = BITS_3;
+	c.ctl_dat[10].data      = 0x20;
+
+/* pulse byte */
+	c.ctl_dat[11].ctrl.size = BITS_3;
+	c.ctl_dat[11].ctrl.clk_off = 1;
+	c.ctl_dat[11].ctrl.cs1  = 1;
+	c.ctl_dat[11].data      = 0x40;
+
+/* PGM_S18 to PGM_S11 */
+	c.ctl_dat[12].ctrl.size = BITS_8;
+	c.ctl_dat[12].data      = 0x2a;
+
+/* PGM_S10 to PGM_S8 and SWL_S7 to SWL_S3 */
+	c.ctl_dat[13].ctrl.size = BITS_8;
+	c.ctl_dat[13].data      = 0x8e;
+
+/* SWL_S2 and SWL_S1 and set CONTROL BIT 2 to 0 */
+	c.ctl_dat[14].ctrl.size = BITS_3;
+	c.ctl_dat[14].data      = 0;
+
+/* Pulse Byte */
+	c.ctl_dat[15].ctrl.size = BITS_3;
+	c.ctl_dat[15].ctrl.clk_off = 1;
+	c.ctl_dat[15].ctrl.cs1  = 1;
+	c.ctl_dat[15].data      = 0x40;
+
+	return bcm3510_do_hab_cmd(st,CMD_TUNE, MSGID_TUNE,(u8 *) &c,sizeof(c), NULL, 0);
+}
+
+static int bcm3510_set_freq(struct bcm3510_state* st,u32 freq)
+{
+	u8 bc,a;
+	u16 n;
+	s32 YIntercept,Tfvco1;
+
+	freq /= 1000;
+
+	deb_info("%dkHz:",freq);
+	/* set Band Switch */
+	if (freq <= 168000)
+		bc = 0x1c;
+	else if (freq <= 378000)
+		bc = 0x2c;
+	else
+		bc = 0x30;
+
+	if (freq >= 470000) {
+		freq -= 470001;
+		YIntercept = 18805;
+	} else if (freq >= 90000) {
+		freq -= 90001;
+		YIntercept = 15005;
+	} else if (freq >= 76000){
+		freq -= 76001;
+		YIntercept = 14865;
+	} else {
+		freq -= 54001;
+		YIntercept = 14645;
+	}
+
+	Tfvco1 = (((freq/6000)*60 + YIntercept)*4)/10;
+
+	n = Tfvco1 >> 6;
+	a = Tfvco1 & 0x3f;
+
+	deb_info(" BC1_2_3_4: %x, N: %x A: %x\n", bc, n, a);
+	if (n >= 16 && n <= 2047)
+		return bcm3510_tuner_cmd(st,bc,n,a);
+
+	return -EINVAL;
+}
+
+static int bcm3510_set_frontend(struct dvb_frontend* fe,
+					     struct dvb_frontend_parameters *p)
+{
+	struct bcm3510_state* st = fe->demodulator_priv;
+	struct bcm3510_hab_cmd_ext_acquire cmd;
+	struct bcm3510_hab_cmd_bert_control bert;
+	int ret;
+
+	memset(&cmd,0,sizeof(cmd));
+	switch (p->u.vsb.modulation) {
+		case QAM_256:
+			cmd.ACQUIRE0.MODE = 0x1;
+			cmd.ACQUIRE1.SYM_RATE = 0x1;
+			cmd.ACQUIRE1.IF_FREQ = 0x1;
+			break;
+		case QAM_64:
+			cmd.ACQUIRE0.MODE = 0x2;
+			cmd.ACQUIRE1.SYM_RATE = 0x2;
+			cmd.ACQUIRE1.IF_FREQ = 0x1;
+			break;
+/*		case QAM_256:
+			cmd.ACQUIRE0.MODE = 0x3;
+			break;
+		case QAM_128:
+			cmd.ACQUIRE0.MODE = 0x4;
+			break;
+		case QAM_64:
+			cmd.ACQUIRE0.MODE = 0x5;
+			break;
+		case QAM_32:
+			cmd.ACQUIRE0.MODE = 0x6;
+			break;
+		case QAM_16:
+			cmd.ACQUIRE0.MODE = 0x7;
+			break;*/
+		case VSB_8:
+			cmd.ACQUIRE0.MODE = 0x8;
+			cmd.ACQUIRE1.SYM_RATE = 0x0;
+			cmd.ACQUIRE1.IF_FREQ = 0x0;
+			break;
+		case VSB_16:
+			cmd.ACQUIRE0.MODE = 0x9;
+			cmd.ACQUIRE1.SYM_RATE = 0x0;
+			cmd.ACQUIRE1.IF_FREQ = 0x0;
+		default:
+			return -EINVAL;
+	};
+	cmd.ACQUIRE0.OFFSET = 0;
+	cmd.ACQUIRE0.NTSCSWEEP = 1;
+	cmd.ACQUIRE0.FA = 1;
+	cmd.ACQUIRE0.BW = 0;
+
+/*	if (enableOffset) {
+		cmd.IF_OFFSET0 = xx;
+		cmd.IF_OFFSET1 = xx;
+
+		cmd.SYM_OFFSET0 = xx;
+		cmd.SYM_OFFSET1 = xx;
+		if (enableNtscSweep) {
+			cmd.NTSC_OFFSET0;
+			cmd.NTSC_OFFSET1;
+		}
+	} */
+	bcm3510_do_hab_cmd(st, CMD_ACQUIRE, MSGID_EXT_TUNER_ACQUIRE, (u8 *) &cmd, sizeof(cmd), NULL, 0);
+
+/* doing it with different MSGIDs, data book and source differs */
+	bert.BE = 0;
+	bert.unused = 0;
+	bcm3510_do_hab_cmd(st, CMD_STATE_CONTROL, MSGID_BERT_CONTROL, (u8 *) &bert, sizeof(bert), NULL, 0);
+	bcm3510_do_hab_cmd(st, CMD_STATE_CONTROL, MSGID_BERT_SET, (u8 *) &bert, sizeof(bert), NULL, 0);
+
+	bcm3510_bert_reset(st);
+
+	if ((ret = bcm3510_set_freq(st,p->frequency)) < 0)
+		return ret;
+
+	memset(&st->status1,0,sizeof(st->status1));
+	memset(&st->status2,0,sizeof(st->status2));
+	st->status_check_interval = 500;
+
+/* Give the AP some time */
+	msleep(200);
+
+	return 0;
+}
+
+static int bcm3510_sleep(struct dvb_frontend* fe)
+{
+	return 0;
+}
+
+static int bcm3510_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *s)
+{
+	s->min_delay_ms = 1000;
+	s->step_size = 0;
+	s->max_drift = 0;
+	return 0;
+}
+
+static void bcm3510_release(struct dvb_frontend* fe)
+{
+	struct bcm3510_state* state = fe->demodulator_priv;
+	kfree(state);
+}
+
+/* firmware download:
+ * firmware file is build up like this:
+ * 16bit addr, 16bit length, 8byte of length
+ */
+#define BCM3510_DEFAULT_FIRMWARE "dvb-fe-bcm3510-01.fw"
+
+static int bcm3510_write_ram(struct bcm3510_state *st, u16 addr, u8 *b, u16 len)
+{
+	int ret = 0,i;
+	bcm3510_register_value vH, vL,vD;
+
+	vH.MADRH_a9 = addr >> 8;
+	vL.MADRL_aa = addr;
+	if ((ret = bcm3510_writeB(st,0xa9,vH)) < 0) return ret;
+	if ((ret = bcm3510_writeB(st,0xaa,vL)) < 0) return ret;
+
+	for (i = 0; i < len; i++) {
+		vD.MDATA_ab = b[i];
+		if ((ret = bcm3510_writeB(st,0xab,vD)) < 0)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int bcm3510_download_firmware(struct dvb_frontend* fe)
+{
+	struct bcm3510_state* st = fe->demodulator_priv;
+	const struct firmware *fw;
+	u16 addr,len;
+	u8  *b;
+	int ret,i;
+
+	deb_info("requesting firmware\n");
+	if ((ret = st->config->request_firmware(fe, &fw, BCM3510_DEFAULT_FIRMWARE)) < 0) {
+		err("could not load firmware (%s): %d",BCM3510_DEFAULT_FIRMWARE,ret);
+		return ret;
+	}
+	deb_info("got firmware: %d\n",fw->size);
+
+	b = fw->data;
+	for (i = 0; i < fw->size;) {
+		addr = le16_to_cpu( *( (u16 *)&b[i] ) );
+		len  = le16_to_cpu( *( (u16 *)&b[i+2] ) );
+		deb_info("firmware chunk, addr: 0x%04x, len: 0x%04x, total length: 0x%04x\n",addr,len,fw->size);
+		if ((ret = bcm3510_write_ram(st,addr,&b[i+4],len)) < 0) {
+			err("firmware download failed: %d\n",ret);
+			return ret;
+		}
+		i += 4 + len;
+	}
+	release_firmware(fw);
+	deb_info("firmware download successfully completed\n");
+	return 0;
+}
+
+static int bcm3510_check_firmware_version(struct bcm3510_state *st)
+{
+	struct bcm3510_hab_cmd_get_version_info ver;
+	bcm3510_do_hab_cmd(st,CMD_GET_VERSION_INFO,MSGID_GET_VERSION_INFO,NULL,0,(u8*)&ver,sizeof(ver));
+
+	deb_info("Version information: 0x%02x 0x%02x 0x%02x 0x%02x\n",
+		ver.microcode_version, ver.script_version, ver.config_version, ver.demod_version);
+
+	if (ver.script_version == BCM3510_DEF_SCRIPT_VERSION &&
+		ver.config_version == BCM3510_DEF_CONFIG_VERSION &&
+		ver.demod_version  == BCM3510_DEF_DEMOD_VERSION)
+		return 0;
+
+	deb_info("version check failed\n");
+	return -ENODEV;
+}
+
+/* (un)resetting the AP */
+static int bcm3510_reset(struct bcm3510_state *st)
+{
+	int ret;
+	unsigned long  t;
+	bcm3510_register_value v;
+
+	bcm3510_readB(st,0xa0,&v); v.HCTL1_a0.RESET = 1;
+	if ((ret = bcm3510_writeB(st,0xa0,v)) < 0)
+		return ret;
+
+    t = jiffies + 3*HZ;
+	while (time_before(jiffies, t)) {
+		msleep(10);
+		if ((ret = bcm3510_readB(st,0xa2,&v)) < 0)
+			return ret;
+
+		if (v.APSTAT1_a2.RESET)
+			return 0;
+	}
+	deb_info("reset timed out\n");
+	return -ETIMEDOUT;
+}
+
+static int bcm3510_clear_reset(struct bcm3510_state *st)
+{
+	bcm3510_register_value v;
+	int ret;
+	unsigned long t;
+
+	v.raw = 0;
+	if ((ret = bcm3510_writeB(st,0xa0,v)) < 0)
+		return ret;
+
+    t = jiffies + 3*HZ;
+	while (time_before(jiffies, t)) {
+		msleep(10);
+		if ((ret = bcm3510_readB(st,0xa2,&v)) < 0)
+			return ret;
+
+		/* verify that reset is cleared */
+		if (!v.APSTAT1_a2.RESET)
+			return 0;
+	}
+	deb_info("reset clear timed out\n");
+	return -ETIMEDOUT;
+}
+
+static int bcm3510_init_cold(struct bcm3510_state *st)
+{
+	int ret;
+	bcm3510_register_value v;
+
+	/* read Acquisation Processor status register and check it is not in RUN mode */
+	if ((ret = bcm3510_readB(st,0xa2,&v)) < 0)
+		return ret;
+	if (v.APSTAT1_a2.RUN) {
+		deb_info("AP is already running - firmware already loaded.\n");
+		return 0;
+	}
+
+	deb_info("reset?\n");
+	if ((ret = bcm3510_reset(st)) < 0)
+		return ret;
+
+	deb_info("tristate?\n");
+	/* tri-state */
+	v.TSTCTL_2e.CTL = 0;
+	if ((ret = bcm3510_writeB(st,0x2e,v)) < 0)
+		return ret;
+
+	deb_info("firmware?\n");
+	if ((ret = bcm3510_download_firmware(&st->frontend)) < 0 ||
+		(ret = bcm3510_clear_reset(st)) < 0)
+		return ret;
+
+	/* anything left here to Let the acquisition processor begin execution at program counter 0000 ??? */
+
+	return 0;
+}
+
+static int bcm3510_init(struct dvb_frontend* fe)
+{
+	struct bcm3510_state* st = fe->demodulator_priv;
+	bcm3510_register_value j;
+	struct bcm3510_hab_cmd_set_agc c;
+	int ret;
+
+	if ((ret = bcm3510_readB(st,0xca,&j)) < 0)
+		return ret;
+
+	deb_info("JDEC: %02x\n",j.raw);
+
+	switch (j.JDEC_ca.JDEC) {
+		case JDEC_WAIT_AT_RAM:
+			deb_info("attempting to download firmware\n");
+			if ((ret = bcm3510_init_cold(st)) < 0)
+				return ret;
+		case JDEC_EEPROM_LOAD_WAIT: /* fall-through is wanted */
+			deb_info("firmware is loaded\n");
+			bcm3510_check_firmware_version(st);
+			break;
+		default:
+			return -ENODEV;
+	}
+
+	memset(&c,0,1);
+	c.SEL = 1;
+	bcm3510_do_hab_cmd(st,CMD_AUTO_PARAM,MSGID_SET_RF_AGC_SEL,(u8 *)&c,sizeof(c),NULL,0);
+
+	return 0;
+}
+
+
+static struct dvb_frontend_ops bcm3510_ops;
+
+struct dvb_frontend* bcm3510_attach(const struct bcm3510_config *config,
+				   struct i2c_adapter *i2c)
+{
+	struct bcm3510_state* state = NULL;
+	int ret;
+	bcm3510_register_value v;
+
+	/* allocate memory for the internal state */
+	state = kmalloc(sizeof(struct bcm3510_state), GFP_KERNEL);
+	if (state == NULL)
+		goto error;
+	memset(state,0,sizeof(struct bcm3510_state));
+
+	/* setup the state */
+
+	state->config = config;
+	state->i2c = i2c;
+	memcpy(&state->ops, &bcm3510_ops, sizeof(struct dvb_frontend_ops));
+
+	/* create dvb_frontend */
+	state->frontend.ops = &state->ops;
+	state->frontend.demodulator_priv = state;
+
+	sema_init(&state->hab_sem, 1);
+
+	if ((ret = bcm3510_readB(state,0xe0,&v)) < 0)
+		goto error;
+
+	deb_info("Revision: 0x%1x, Layer: 0x%1x.\n",v.REVID_e0.REV,v.REVID_e0.LAYER);
+
+	if ((v.REVID_e0.REV != 0x1 && v.REVID_e0.LAYER != 0xb) && /* cold */
+		(v.REVID_e0.REV != 0x8 && v.REVID_e0.LAYER != 0x0))   /* warm */
+		goto error;
+
+	info("Revision: 0x%1x, Layer: 0x%1x.",v.REVID_e0.REV,v.REVID_e0.LAYER);
+
+	bcm3510_reset(state);
+
+	return &state->frontend;
+
+error:
+	kfree(state);
+	return NULL;
+}
+EXPORT_SYMBOL(bcm3510_attach);
+
+static struct dvb_frontend_ops bcm3510_ops = {
+
+	.info = {
+		.name = "Broadcom BCM3510 VSB/QAM frontend",
+		.type = FE_ATSC,
+		.frequency_min =  54000000,
+		.frequency_max = 803000000,
+                /* stepsize is just a guess */
+		.frequency_stepsize = 0,
+		.caps =
+			FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+			FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+			FE_CAN_8VSB | FE_CAN_16VSB |
+			FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_128 | FE_CAN_QAM_256
+	},
+
+	.release = bcm3510_release,
+
+	.init = bcm3510_init,
+	.sleep = bcm3510_sleep,
+
+	.set_frontend = bcm3510_set_frontend,
+	.get_tune_settings = bcm3510_get_tune_settings,
+
+	.read_status = bcm3510_read_status,
+	.read_ber = bcm3510_read_ber,
+	.read_signal_strength = bcm3510_read_signal_strength,
+	.read_snr = bcm3510_read_snr,
+	.read_ucblocks = bcm3510_read_unc,
+};
+
+MODULE_DESCRIPTION("Broadcom BCM3510 ATSC (8VSB/16VSB & ITU J83 AnnexB FEC QAM64/256) demodulator driver");
+MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/bcm3510.h b/drivers/media/dvb/frontends/bcm3510.h
new file mode 100644
--- /dev/null
+++ b/drivers/media/dvb/frontends/bcm3510.h
@@ -0,0 +1,40 @@
+/*
+ * Support for the Broadcom BCM3510 ATSC demodulator (1st generation Air2PC)
+ *
+ *  Copyright (C) 2001-5, B2C2 inc.
+ *
+ *  GPL/Linux driver written by Patrick Boettcher <patrick.boettcher@desy.de>
+ *
+ * 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 BCM3510_H
+#define BCM3510_H
+
+#include <linux/dvb/frontend.h>
+#include <linux/firmware.h>
+
+struct bcm3510_config
+{
+	/* the demodulator's i2c address */
+	u8 demod_address;
+
+	/* request firmware for device */
+	int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name);
+};
+
+extern struct dvb_frontend* bcm3510_attach(const struct bcm3510_config* config,
+					   struct i2c_adapter* i2c);
+
+#endif
diff --git a/drivers/media/dvb/frontends/bcm3510_priv.h b/drivers/media/dvb/frontends/bcm3510_priv.h
new file mode 100644
--- /dev/null
+++ b/drivers/media/dvb/frontends/bcm3510_priv.h
@@ -0,0 +1,460 @@
+/*
+ * Support for the Broadcom BCM3510 ATSC demodulator (1st generation Air2PC)
+ *
+ *  Copyright (C) 2001-5, B2C2 inc.
+ *
+ *  GPL/Linux driver written by Patrick Boettcher <patrick.boettcher@desy.de>
+ *
+ * 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 __BCM3510_PRIV_H__
+#define __BCM3510_PRIV_H__
+
+#define PACKED __attribute__((packed))
+
+#undef err
+#define err(format, arg...)  printk(KERN_ERR     "bcm3510: " format "\n" , ## arg)
+#undef info
+#define info(format, arg...) printk(KERN_INFO    "bcm3510: " format "\n" , ## arg)
+#undef warn
+#define warn(format, arg...) printk(KERN_WARNING "bcm3510: " format "\n" , ## arg)
+
+
+#define PANASONIC_FIRST_IF_BASE_IN_KHz  1407500
+#define BCM3510_SYMBOL_RATE             5381000
+
+typedef union {
+	u8 raw;
+
+	struct {
+		u8 CTL   :8;
+	} TSTCTL_2e;
+
+	u8 LDCERC_4e;
+	u8 LDUERC_4f;
+	u8 LD_BER0_65;
+	u8 LD_BER1_66;
+	u8 LD_BER2_67;
+	u8 LD_BER3_68;
+
+	struct {
+		u8 RESET :1;
+		u8 IDLE  :1;
+		u8 STOP  :1;
+		u8 HIRQ0 :1;
+		u8 HIRQ1 :1;
+		u8 na0   :1;
+		u8 HABAV :1;
+		u8 na1   :1;
+	} HCTL1_a0;
+
+	struct {
+		u8 na0    :1;
+		u8 IDLMSK :1;
+		u8 STMSK  :1;
+		u8 I0MSK  :1;
+		u8 I1MSK  :1;
+		u8 na1    :1;
+		u8 HABMSK :1;
+		u8 na2    :1;
+	} HCTLMSK_a1;
+
+	struct {
+		u8 RESET  :1;
+		u8 IDLE   :1;
+		u8 STOP   :1;
+		u8 RUN    :1;
+		u8 HABAV  :1;
+		u8 MEMAV  :1;
+		u8 ALDONE :1;
+		u8 REIRQ  :1;
+	} APSTAT1_a2;
+
+	struct {
+		u8 RSTMSK :1;
+		u8 IMSK   :1;
+		u8 SMSK   :1;
+		u8 RMSK   :1;
+		u8 HABMSK :1;
+		u8 MAVMSK :1;
+		u8 ALDMSK :1;
+		u8 REMSK  :1;
+	} APMSK1_a3;
+
+	u8 APSTAT2_a4;
+	u8 APMSK2_a5;
+
+	struct {
+		u8 HABADR :7;
+		u8 na     :1;
+	} HABADR_a6;
+
+	u8 HABDATA_a7;
+
+	struct {
+		u8 HABR   :1;
+		u8 LDHABR :1;
+		u8 APMSK  :1;
+		u8 HMSK   :1;
+		u8 LDMSK  :1;
+		u8 na     :3;
+	} HABSTAT_a8;
+
+	u8 MADRH_a9;
+	u8 MADRL_aa;
+	u8 MDATA_ab;
+
+	struct {
+#define JDEC_WAIT_AT_RAM      0x7
+#define JDEC_EEPROM_LOAD_WAIT 0x4
+		u8 JDEC   :3;
+		u8 na     :5;
+	} JDEC_ca;
+
+	struct {
+		u8 REV   :4;
+		u8 LAYER :4;
+	} REVID_e0;
+
+	struct {
+		u8 unk0   :1;
+		u8 CNTCTL :1;
+		u8 BITCNT :1;
+		u8 unk1   :1;
+		u8 RESYNC :1;
+		u8 unk2   :3;
+	} BERCTL_fa;
+
+	struct {
+		u8 CSEL0  :1;
+		u8 CLKED0 :1;
+		u8 CSEL1  :1;
+		u8 CLKED1 :1;
+		u8 CLKLEV :1;
+		u8 SPIVAR :1;
+		u8 na     :2;
+	} TUNSET_fc;
+
+	struct {
+		u8 CLK    :1;
+		u8 DATA   :1;
+		u8 CS0    :1;
+		u8 CS1    :1;
+		u8 AGCSEL :1;
+		u8 na0    :1;
+		u8 TUNSEL :1;
+		u8 na1    :1;
+	} TUNCTL_fd;
+
+	u8 TUNSEL0_fe;
+	u8 TUNSEL1_ff;
+
+} bcm3510_register_value;
+
+/* HAB commands */
+
+/* version */
+#define CMD_GET_VERSION_INFO   0x3D
+#define MSGID_GET_VERSION_INFO 0x15
+struct bcm3510_hab_cmd_get_version_info {
+	u8 microcode_version;
+	u8 script_version;
+	u8 config_version;
+	u8 demod_version;
+} PACKED;
+
+#define BCM3510_DEF_MICROCODE_VERSION 0x0E
+#define BCM3510_DEF_SCRIPT_VERSION    0x06
+#define BCM3510_DEF_CONFIG_VERSION    0x01
+#define BCM3510_DEF_DEMOD_VERSION     0xB1
+
+/* acquire */
+#define CMD_ACQUIRE            0x38
+
+#define MSGID_EXT_TUNER_ACQUIRE 0x0A
+struct bcm3510_hab_cmd_ext_acquire {
+	struct {
+		u8 MODE      :4;
+		u8 BW        :1;
+		u8 FA        :1;
+		u8 NTSCSWEEP :1;
+		u8 OFFSET    :1;
+	} PACKED ACQUIRE0; /* control_byte */
+
+	struct {
+		u8 IF_FREQ  :3;
+		u8 zero0    :1;
+		u8 SYM_RATE :3;
+		u8 zero1    :1;
+	} PACKED ACQUIRE1; /* sym_if */
+
+	u8 IF_OFFSET0;   /* IF_Offset_10hz */
+	u8 IF_OFFSET1;
+	u8 SYM_OFFSET0;  /* SymbolRateOffset */
+	u8 SYM_OFFSET1;
+	u8 NTSC_OFFSET0; /* NTSC_Offset_10hz */
+	u8 NTSC_OFFSET1;
+} PACKED;
+
+#define MSGID_INT_TUNER_ACQUIRE 0x0B
+struct bcm3510_hab_cmd_int_acquire {
+	struct {
+		u8 MODE      :4;
+		u8 BW        :1;
+		u8 FA        :1;
+		u8 NTSCSWEEP :1;
+		u8 OFFSET    :1;
+	} PACKED ACQUIRE0; /* control_byte */
+
+	struct {
+		u8 IF_FREQ  :3;
+		u8 zero0    :1;
+		u8 SYM_RATE :3;
+		u8 zero1    :1;
+	} PACKED ACQUIRE1; /* sym_if */
+
+	u8 TUNER_FREQ0;
+	u8 TUNER_FREQ1;
+	u8 TUNER_FREQ2;
+	u8 TUNER_FREQ3;
+	u8 IF_OFFSET0;   /* IF_Offset_10hz */
+	u8 IF_OFFSET1;
+	u8 SYM_OFFSET0;  /* SymbolRateOffset */
+	u8 SYM_OFFSET1;
+	u8 NTSC_OFFSET0; /* NTSC_Offset_10hz */
+	u8 NTSC_OFFSET1;
+} PACKED;
+
+/* modes */
+#define BCM3510_QAM16           =   0x01
+#define BCM3510_QAM32           =   0x02
+#define BCM3510_QAM64           =   0x03
+#define BCM3510_QAM128          =   0x04
+#define BCM3510_QAM256          =   0x05
+#define BCM3510_8VSB            =   0x0B
+#define BCM3510_16VSB           =   0x0D
+
+/* IF_FREQS */
+#define BCM3510_IF_TERRESTRIAL 0x0
+#define BCM3510_IF_CABLE       0x1
+#define BCM3510_IF_USE_CMD     0x7
+
+/* SYM_RATE */
+#define BCM3510_SR_8VSB        0x0 /* 5381119 s/sec */
+#define BCM3510_SR_256QAM      0x1 /* 5360537 s/sec */
+#define BCM3510_SR_16QAM       0x2 /* 5056971 s/sec */
+#define BCM3510_SR_MISC        0x3 /* 5000000 s/sec */
+#define BCM3510_SR_USE_CMD     0x7
+
+/* special symbol rate */
+#define CMD_SET_VALUE_NOT_LISTED  0x2d
+#define MSGID_SET_SYMBOL_RATE_NOT_LISTED 0x0c
+struct bcm3510_hab_cmd_set_sr_not_listed {
+	u8 HOST_SYM_RATE0;
+	u8 HOST_SYM_RATE1;
+	u8 HOST_SYM_RATE2;
+	u8 HOST_SYM_RATE3;
+} PACKED;
+
+/* special IF */
+#define MSGID_SET_IF_FREQ_NOT_LISTED 0x0d
+struct bcm3510_hab_cmd_set_if_freq_not_listed {
+	u8 HOST_IF_FREQ0;
+	u8 HOST_IF_FREQ1;
+	u8 HOST_IF_FREQ2;
+	u8 HOST_IF_FREQ3;
+} PACKED;
+
+/* auto reacquire */
+#define CMD_AUTO_PARAM       0x2a
+#define MSGID_AUTO_REACQUIRE 0x0e
+struct bcm3510_hab_cmd_auto_reacquire {
+	u8 ACQ    :1; /* on/off*/
+	u8 unused :7;
+} PACKED;
+
+#define MSGID_SET_RF_AGC_SEL 0x12
+struct bcm3510_hab_cmd_set_agc {
+	u8 LVL    :1;
+	u8 unused :6;
+	u8 SEL    :1;
+} PACKED;
+
+#define MSGID_SET_AUTO_INVERSION 0x14
+struct bcm3510_hab_cmd_auto_inversion {
+	u8 AI     :1;
+	u8 unused :7;
+} PACKED;
+
+
+/* bert control */
+#define CMD_STATE_CONTROL  0x12
+#define MSGID_BERT_CONTROL 0x0e
+#define MSGID_BERT_SET     0xfa
+struct bcm3510_hab_cmd_bert_control {
+	u8 BE     :1;
+	u8 unused :7;
+} PACKED;
+
+#define MSGID_TRI_STATE 0x2e
+struct bcm3510_hab_cmd_tri_state {
+	u8 RE :1; /* a/d ram port pins */
+	u8 PE :1; /* baud clock pin */
+	u8 AC :1; /* a/d clock pin */
+	u8 BE :1; /* baud clock pin */
+	u8 unused :4;
+} PACKED;
+
+
+/* tune */
+#define CMD_TUNE   0x38
+#define MSGID_TUNE 0x16
+struct bcm3510_hab_cmd_tune_ctrl_data_pair {
+	struct {
+#define BITS_8 0x07
+#define BITS_7 0x06
+#define BITS_6 0x05
+#define BITS_5 0x04
+#define BITS_4 0x03
+#define BITS_3 0x02
+#define BITS_2 0x01
+#define BITS_1 0x00
+		u8 size    :3;
+		u8 unk     :2;
+		u8 clk_off :1;
+		u8 cs0     :1;
+		u8 cs1     :1;
+
+	} PACKED ctrl;
+
+	u8 data;
+} PACKED;
+
+struct bcm3510_hab_cmd_tune {
+	u8 length;
+	u8 clock_width;
+	u8 misc;
+	u8 TUNCTL_state;
+
+	struct bcm3510_hab_cmd_tune_ctrl_data_pair ctl_dat[16];
+} PACKED;
+
+#define CMD_STATUS    0x38
+#define MSGID_STATUS1 0x08
+struct bcm3510_hab_cmd_status1 {
+	struct {
+		u8 EQ_MODE       :4;
+		u8 reserved      :2;
+		u8 QRE           :1; /* if QSE and the spectrum is inversed */
+		u8 QSE           :1; /* automatic spectral inversion */
+	} PACKED STATUS0;
+
+	struct {
+		u8 RECEIVER_LOCK :1;
+		u8 FEC_LOCK      :1;
+		u8 OUT_PLL_LOCK  :1;
+		u8 reserved      :5;
+	} PACKED STATUS1;
+
+	struct {
+		u8 reserved      :2;
+		u8 BW            :1;
+		u8 NTE           :1; /* NTSC filter sweep enabled */
+		u8 AQI           :1; /* currently acquiring */
+		u8 FA            :1; /* fast acquisition */
+		u8 ARI           :1; /* auto reacquire */
+		u8 TI            :1; /* programming the tuner */
+	} PACKED STATUS2;
+	u8 STATUS3;
+	u8 SNR_EST0;
+	u8 SNR_EST1;
+	u8 TUNER_FREQ0;
+	u8 TUNER_FREQ1;
+	u8 TUNER_FREQ2;
+	u8 TUNER_FREQ3;
+	u8 SYM_RATE0;
+	u8 SYM_RATE1;
+	u8 SYM_RATE2;
+	u8 SYM_RATE3;
+	u8 SYM_OFFSET0;
+	u8 SYM_OFFSET1;
+	u8 SYM_ERROR0;
+	u8 SYM_ERROR1;
+	u8 IF_FREQ0;
+	u8 IF_FREQ1;
+	u8 IF_FREQ2;
+	u8 IF_FREQ3;
+	u8 IF_OFFSET0;
+	u8 IF_OFFSET1;
+	u8 IF_ERROR0;
+	u8 IF_ERROR1;
+	u8 NTSC_FILTER0;
+	u8 NTSC_FILTER1;
+	u8 NTSC_FILTER2;
+	u8 NTSC_FILTER3;
+	u8 NTSC_OFFSET0;
+	u8 NTSC_OFFSET1;
+	u8 NTSC_ERROR0;
+	u8 NTSC_ERROR1;
+	u8 INT_AGC_LEVEL0;
+	u8 INT_AGC_LEVEL1;
+	u8 EXT_AGC_LEVEL0;
+	u8 EXT_AGC_LEVEL1;
+} PACKED;
+
+#define MSGID_STATUS2 0x14
+struct bcm3510_hab_cmd_status2 {
+	struct {
+		u8 EQ_MODE  :4;
+		u8 reserved :2;
+		u8 QRE      :1;
+		u8 QSR      :1;
+	} PACKED STATUS0;
+	struct {
+		u8 RL       :1;
+		u8 FL       :1;
+		u8 OL       :1;
+		u8 reserved :5;
+	} PACKED STATUS1;
+	u8 SYMBOL_RATE0;
+	u8 SYMBOL_RATE1;
+	u8 SYMBOL_RATE2;
+	u8 SYMBOL_RATE3;
+	u8 LDCERC0;
+	u8 LDCERC1;
+	u8 LDCERC2;
+	u8 LDCERC3;
+	u8 LDUERC0;
+	u8 LDUERC1;
+	u8 LDUERC2;
+	u8 LDUERC3;
+	u8 LDBER0;
+	u8 LDBER1;
+	u8 LDBER2;
+	u8 LDBER3;
+	struct {
+		u8 MODE_TYPE :4; /* acquire mode 0 */
+		u8 reservd   :4;
+	} MODE_TYPE;
+	u8 SNR_EST0;
+	u8 SNR_EST1;
+	u8 SIGNAL;
+} PACKED;
+
+#define CMD_SET_RF_BW_NOT_LISTED   0x3f
+#define MSGID_SET_RF_BW_NOT_LISTED 0x11
+/* TODO */
+
+#endif
diff --git a/drivers/media/dvb/frontends/cx22702.c b/drivers/media/dvb/frontends/cx22702.c
--- a/drivers/media/dvb/frontends/cx22702.c
+++ b/drivers/media/dvb/frontends/cx22702.c
@@ -76,7 +76,6 @@ static u8 init_tab [] = {
 	0x49, 0x56,
 	0x6b, 0x1e,
 	0xc8, 0x02,
-	0xf8, 0x02,
 	0xf9, 0x00,
 	0xfa, 0x00,
 	0xfb, 0x00,
@@ -203,7 +202,7 @@ static int cx22702_set_tps (struct dvb_f
 	struct cx22702_state* state = fe->demodulator_priv;
 
 	/* set PLL */
-        cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) &0xfe);
+	cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) &0xfe);
 	if (state->config->pll_set) {
 		state->config->pll_set(fe, p);
 	} else if (state->config->pll_desc) {
@@ -217,7 +216,7 @@ static int cx22702_set_tps (struct dvb_f
 	} else {
 		BUG();
 	}
-        cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) | 1);
+	cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) | 1);
 
 	/* set inversion */
 	cx22702_set_inversion (state, p->inversion);
@@ -256,7 +255,7 @@ static int cx22702_set_tps (struct dvb_f
 		cx22702_writereg(state, 0x0B, cx22702_readreg(state, 0x0B) & 0xfc );
 		cx22702_writereg(state, 0x0C, (cx22702_readreg(state, 0x0C) & 0xBF) | 0x40 );
 		cx22702_writereg(state, 0x00, 0x01); /* Begin aquisition */
-		printk("%s: Autodetecting\n",__FUNCTION__);
+		dprintk("%s: Autodetecting\n",__FUNCTION__);
 		return 0;
 	}
 
@@ -347,10 +346,11 @@ static int cx22702_init (struct dvb_fron
 	for (i=0; i<sizeof(init_tab); i+=2)
 		cx22702_writereg (state, init_tab[i], init_tab[i+1]);
 
+	cx22702_writereg (state, 0xf8, (state->config->output_mode << 1) & 0x02);
 
 	/* init PLL */
 	if (state->config->pll_init) {
-	        cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) &0xfe);
+		cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) & 0xfe);
 		state->config->pll_init(fe);
 		cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) | 1);
 	}
@@ -440,8 +440,10 @@ static int cx22702_read_ucblocks(struct 
 
 	/* RS Uncorrectable Packet Count then reset */
 	_ucblocks = cx22702_readreg (state, 0xE3);
-	if (state->prevUCBlocks < _ucblocks) *ucblocks = (_ucblocks - state->prevUCBlocks);
-	else *ucblocks = state->prevUCBlocks - _ucblocks;
+	if (state->prevUCBlocks < _ucblocks)
+		*ucblocks = (_ucblocks - state->prevUCBlocks);
+	else
+		*ucblocks = state->prevUCBlocks - _ucblocks;
 	state->prevUCBlocks = _ucblocks;
 
 	return 0;
@@ -457,6 +459,12 @@ static int cx22702_get_frontend(struct d
 	return cx22702_get_tps (state, &p->u.ofdm);
 }
 
+static int cx22702_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
+{
+	tune->min_delay_ms = 1000;
+	return 0;
+}
+
 static void cx22702_release(struct dvb_frontend* fe)
 {
 	struct cx22702_state* state = fe->demodulator_priv;
@@ -472,7 +480,8 @@ struct dvb_frontend* cx22702_attach(cons
 
 	/* allocate memory for the internal state */
 	state = kmalloc(sizeof(struct cx22702_state), GFP_KERNEL);
-	if (state == NULL) goto error;
+	if (state == NULL)
+		goto error;
 
 	/* setup the state */
 	state->config = config;
@@ -481,7 +490,8 @@ struct dvb_frontend* cx22702_attach(cons
 	state->prevUCBlocks = 0;
 
 	/* check if the demod is there */
-	if (cx22702_readreg(state, 0x1f) != 0x3) goto error;
+	if (cx22702_readreg(state, 0x1f) != 0x3)
+		goto error;
 
 	/* create dvb_frontend */
 	state->frontend.ops = &state->ops;
@@ -514,6 +524,7 @@ static struct dvb_frontend_ops cx22702_o
 
 	.set_frontend = cx22702_set_tps,
 	.get_frontend = cx22702_get_frontend,
+	.get_tune_settings = cx22702_get_tune_settings,
 
 	.read_status = cx22702_read_status,
 	.read_ber = cx22702_read_ber,
diff --git a/drivers/media/dvb/frontends/cx22702.h b/drivers/media/dvb/frontends/cx22702.h
--- a/drivers/media/dvb/frontends/cx22702.h
+++ b/drivers/media/dvb/frontends/cx22702.h
@@ -35,6 +35,11 @@ struct cx22702_config
 	/* the demodulator's i2c address */
 	u8 demod_address;
 
+	/* serial/parallel output */
+#define CX22702_PARALLEL_OUTPUT 0
+#define CX22702_SERIAL_OUTPUT   1
+	u8 output_mode;
+
 	/* PLL maintenance */
 	u8 pll_address;
 	struct dvb_pll_desc *pll_desc;
diff --git a/drivers/media/dvb/frontends/dib3000-common.c b/drivers/media/dvb/frontends/dib3000-common.c
--- a/drivers/media/dvb/frontends/dib3000-common.c
+++ b/drivers/media/dvb/frontends/dib3000-common.c
@@ -73,7 +73,7 @@ u16 dib3000_seq[2][2][2] =     /* fft,gu
 	};
 
 MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de");
-MODULE_DESCRIPTION("Common functions for the dib3000mb/dib3000mc dvb-frontend drivers");
+MODULE_DESCRIPTION("Common functions for the dib3000mb/dib3000mc dvb frontend drivers");
 MODULE_LICENSE("GPL");
 
 EXPORT_SYMBOL(dib3000_seq);
diff --git a/drivers/media/dvb/frontends/dib3000.h b/drivers/media/dvb/frontends/dib3000.h
--- a/drivers/media/dvb/frontends/dib3000.h
+++ b/drivers/media/dvb/frontends/dib3000.h
@@ -32,9 +32,8 @@ struct dib3000_config
 	u8 demod_address;
 
 	/* PLL maintenance and the i2c address of the PLL */
-	u8 (*pll_addr)(struct dvb_frontend *fe);
-	int (*pll_init)(struct dvb_frontend *fe, u8 pll_buf[5]);
-	int (*pll_set)(struct dvb_frontend *fe, struct dvb_frontend_parameters* params, u8 pll_buf[5]);
+	int (*pll_init)(struct dvb_frontend *fe);
+	int (*pll_set)(struct dvb_frontend *fe, struct dvb_frontend_parameters* params);
 };
 
 struct dib_fe_xfer_ops
diff --git a/drivers/media/dvb/frontends/dib3000mb.c b/drivers/media/dvb/frontends/dib3000mb.c
--- a/drivers/media/dvb/frontends/dib3000mb.c
+++ b/drivers/media/dvb/frontends/dib3000mb.c
@@ -48,8 +48,6 @@ MODULE_PARM_DESC(debug, "set debugging l
 #define deb_setf(args...) dprintk(0x04,args)
 #define deb_getf(args...) dprintk(0x08,args)
 
-static int dib3000mb_tuner_pass_ctrl(struct dvb_frontend *fe, int onoff, u8 pll_addr);
-
 static int dib3000mb_get_frontend(struct dvb_frontend* fe,
 				  struct dvb_frontend_parameters *fep);
 
@@ -61,10 +59,8 @@ static int dib3000mb_set_frontend(struct
 	fe_code_rate_t fe_cr = FEC_NONE;
 	int search_state, seq;
 
-	if (tuner && state->config.pll_addr && state->config.pll_set) {
-		dib3000mb_tuner_pass_ctrl(fe,1,state->config.pll_addr(fe));
-		state->config.pll_set(fe, fep, NULL);
-		dib3000mb_tuner_pass_ctrl(fe,0,state->config.pll_addr(fe));
+	if (tuner && state->config.pll_set) {
+		state->config.pll_set(fe, fep);
 
 		deb_setf("bandwidth: ");
 		switch (ofdm->bandwidth) {
@@ -389,11 +385,8 @@ static int dib3000mb_fe_init(struct dvb_
 
 	wr(DIB3000MB_REG_DATA_IN_DIVERSITY, DIB3000MB_DATA_DIVERSITY_IN_OFF);
 
-	if (state->config.pll_init) {
-		dib3000mb_tuner_pass_ctrl(fe,1,state->config.pll_addr(fe));
-		state->config.pll_init(fe,NULL);
-		dib3000mb_tuner_pass_ctrl(fe,0,state->config.pll_addr(fe));
-	}
+	if (state->config.pll_init)
+		state->config.pll_init(fe);
 
 	return 0;
 }
@@ -623,7 +616,7 @@ static int dib3000mb_read_unc_blocks(str
 {
 	struct dib3000_state* state = fe->demodulator_priv;
 
-	*unc = rd(DIB3000MB_REG_UNC);
+	*unc = rd(DIB3000MB_REG_PACKET_ERROR_RATE);
 	return 0;
 }
 
@@ -638,9 +631,6 @@ static int dib3000mb_sleep(struct dvb_fr
 static int dib3000mb_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
 {
 	tune->min_delay_ms = 800;
-	tune->step_size = 166667;
-	tune->max_drift = 166667 * 2;
-
 	return 0;
 }
 
diff --git a/drivers/media/dvb/frontends/dib3000mb_priv.h b/drivers/media/dvb/frontends/dib3000mb_priv.h
--- a/drivers/media/dvb/frontends/dib3000mb_priv.h
+++ b/drivers/media/dvb/frontends/dib3000mb_priv.h
@@ -294,7 +294,7 @@ static u16 dib3000mb_reg_filter_coeffs[]
 
 static u16 dib3000mb_filter_coeffs[] = {
 	 226,  160,   29,
- 	 979,  998,   19,
+	 979,  998,   19,
 	  22, 1019, 1006,
 	1022,   12,    6,
 	1017, 1017,    3,
diff --git a/drivers/media/dvb/frontends/dib3000mc.c b/drivers/media/dvb/frontends/dib3000mc.c
--- a/drivers/media/dvb/frontends/dib3000mc.c
+++ b/drivers/media/dvb/frontends/dib3000mc.c
@@ -48,8 +48,6 @@ MODULE_PARM_DESC(debug, "set debugging l
 #define deb_getf(args...) dprintk(0x08,args)
 #define deb_stat(args...) dprintk(0x10,args)
 
-static int dib3000mc_tuner_pass_ctrl(struct dvb_frontend *fe, int onoff, u8 pll_addr);
-
 static int dib3000mc_set_impulse_noise(struct dib3000_state * state, int mode,
 	fe_transmit_mode_t transmission_mode, fe_bandwidth_t bandwidth)
 {
@@ -463,10 +461,8 @@ static int dib3000mc_set_frontend(struct
 	int search_state,auto_val;
 	u16 val;
 
-	if (tuner && state->config.pll_addr && state->config.pll_set) { /* initial call from dvb */
-		dib3000mc_tuner_pass_ctrl(fe,1,state->config.pll_addr(fe));
-		state->config.pll_set(fe,fep,NULL);
-		dib3000mc_tuner_pass_ctrl(fe,0,state->config.pll_addr(fe));
+	if (tuner && state->config.pll_set) { /* initial call from dvb */
+		state->config.pll_set(fe,fep);
 
 		state->last_tuned_freq = fep->frequency;
 	//	if (!scanboost) {
@@ -554,19 +550,15 @@ static int dib3000mc_set_frontend(struct
 			dib3000mc_set_adp_cfg(state,ofdm->constellation);
 		wr_foreach(dib3000mc_reg_offset,
 				dib3000mc_offset[(ofdm->transmission_mode == TRANSMISSION_MODE_8K)+1]);
-
-
 	}
 	return 0;
 }
 
 static int dib3000mc_fe_init(struct dvb_frontend* fe, int mobile_mode)
 {
-	struct dib3000_state *state;
-
+	struct dib3000_state *state = fe->demodulator_priv;
 	deb_info("init start\n");
 
-	state = fe->demodulator_priv;
 	state->timing_offset = 0;
 	state->timing_offset_comp_done = 0;
 
@@ -649,11 +641,9 @@ static int dib3000mc_fe_init(struct dvb_
 
 	set_or(DIB3000MC_REG_CLK_CFG_7,DIB3000MC_CLK_CFG_7_DIV_IN_OFF);
 
-/*	if (state->config->pll_init) {
-		dib3000mc_tuner_pass_ctrl(fe,1,state->config.pll_addr(fe));
-		state->config->pll_init(fe,NULL);
-		dib3000mc_tuner_pass_ctrl(fe,0,state->config.pll_addr(fe));
-	}*/
+	if (state->config.pll_init)
+		state->config.pll_init(fe);
+
 	deb_info("init end\n");
 	return 0;
 }
@@ -688,7 +678,7 @@ static int dib3000mc_read_unc_blocks(str
 {
 	struct dib3000_state* state = fe->demodulator_priv;
 
-	*unc = rd(DIB3000MC_REG_PACKET_ERROR_COUNT);
+	*unc = rd(DIB3000MC_REG_PACKET_ERRORS);
 	return 0;
 }
 
@@ -737,10 +727,7 @@ static int dib3000mc_sleep(struct dvb_fr
 
 static int dib3000mc_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
 {
-	tune->min_delay_ms = 2000;
-	tune->step_size = 166667;
-	tune->max_drift = 166667 * 2;
-
+	tune->min_delay_ms = 1000;
 	return 0;
 }
 
diff --git a/drivers/media/dvb/frontends/dvb-pll.c b/drivers/media/dvb/frontends/dvb-pll.c
--- a/drivers/media/dvb/frontends/dvb-pll.c
+++ b/drivers/media/dvb/frontends/dvb-pll.c
@@ -1,6 +1,4 @@
 /*
- * $Id: dvb-pll.c,v 1.7 2005/02/10 11:52:02 kraxel Exp $
- *
  * descriptions + helper functions for simple dvb plls.
  *
  * (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
@@ -57,7 +55,7 @@ struct dvb_pll_desc dvb_pll_thomson_dtt7
 };
 EXPORT_SYMBOL(dvb_pll_thomson_dtt7610);
 
-static void thomson_dtt759x_bw(u8 *buf, int bandwidth)
+static void thomson_dtt759x_bw(u8 *buf, u32 freq, int bandwidth)
 {
 	if (BANDWIDTH_7_MHZ == bandwidth)
 		buf[3] |= 0x10;
@@ -84,17 +82,44 @@ struct dvb_pll_desc dvb_pll_lg_z201 = {
 	.name  = "LG z201",
 	.min   = 174000000,
 	.max   = 862000000,
-	.count = 5,
+	.count = 6,
 	.entries = {
 		{          0, 36166667, 166666, 0xbc, 0x03 },
-		{  443250000, 36166667, 166666, 0xbc, 0x01 },
-		{  542000000, 36166667, 166666, 0xbc, 0x02 },
-		{  830000000, 36166667, 166666, 0xf4, 0x02 },
-		{  999999999, 36166667, 166666, 0xfc, 0x02 },
+		{  157500000, 36166667, 166666, 0xbc, 0x01 },
+		{  443250000, 36166667, 166666, 0xbc, 0x02 },
+		{  542000000, 36166667, 166666, 0xbc, 0x04 },
+		{  830000000, 36166667, 166666, 0xf4, 0x04 },
+		{  999999999, 36166667, 166666, 0xfc, 0x04 },
 	},
 };
 EXPORT_SYMBOL(dvb_pll_lg_z201);
 
+struct dvb_pll_desc dvb_pll_microtune_4042 = {
+	.name  = "Microtune 4042 FI5",
+	.min   =  57000000,
+	.max   = 858000000,
+	.count = 3,
+	.entries = {
+		{ 162000000, 44000000, 62500, 0x8e, 0xa1 },
+		{ 457000000, 44000000, 62500, 0x8e, 0x91 },
+		{ 999999999, 44000000, 62500, 0x8e, 0x31 },
+	},
+};
+EXPORT_SYMBOL(dvb_pll_microtune_4042);
+
+struct dvb_pll_desc dvb_pll_thomson_dtt7611 = {
+	.name  = "Thomson dtt7611",
+	.min   =  44000000,
+	.max   = 958000000,
+	.count = 3,
+	.entries = {
+		{ 157250000, 44000000, 62500, 0x8e, 0x39 },
+		{ 454000000, 44000000, 62500, 0x8e, 0x3a },
+		{ 999999999, 44000000, 62500, 0x8e, 0x3c },
+	},
+};
+EXPORT_SYMBOL(dvb_pll_thomson_dtt7611);
+
 struct dvb_pll_desc dvb_pll_unknown_1 = {
 	.name  = "unknown 1", /* used by dntv live dvb-t */
 	.min   = 174000000,
@@ -114,6 +139,159 @@ struct dvb_pll_desc dvb_pll_unknown_1 = 
 };
 EXPORT_SYMBOL(dvb_pll_unknown_1);
 
+/* Infineon TUA6010XS
+ * used in Thomson Cable Tuner
+ */
+struct dvb_pll_desc dvb_pll_tua6010xs = {
+	.name  = "Infineon TUA6010XS",
+	.min   =  44250000,
+	.max   = 858000000,
+	.count = 3,
+	.entries = {
+		{  115750000, 36125000, 62500, 0x8e, 0x03 },
+		{  403250000, 36125000, 62500, 0x8e, 0x06 },
+		{  999999999, 36125000, 62500, 0x8e, 0x85 },
+	},
+};
+EXPORT_SYMBOL(dvb_pll_tua6010xs);
+
+/* Panasonic env57h1xd5 (some Philips PLL ?) */
+struct dvb_pll_desc dvb_pll_env57h1xd5 = {
+	.name  = "Panasonic ENV57H1XD5",
+	.min   =  44250000,
+	.max   = 858000000,
+	.count = 4,
+	.entries = {
+		{  153000000, 36291666, 166666, 0xc2, 0x41 },
+		{  470000000, 36291666, 166666, 0xc2, 0x42 },
+		{  526000000, 36291666, 166666, 0xc2, 0x84 },
+		{  999999999, 36291666, 166666, 0xc2, 0xa4 },
+	},
+};
+EXPORT_SYMBOL(dvb_pll_env57h1xd5);
+
+/* Philips TDA6650/TDA6651
+ * used in Panasonic ENV77H11D5
+ */
+static void tda665x_bw(u8 *buf, u32 freq, int bandwidth)
+{
+	if (bandwidth == BANDWIDTH_8_MHZ)
+		buf[3] |= 0x08;
+}
+
+struct dvb_pll_desc dvb_pll_tda665x = {
+	.name  = "Philips TDA6650/TDA6651",
+	.min   =  44250000,
+	.max   = 858000000,
+	.setbw = tda665x_bw,
+	.count = 12,
+	.entries = {
+		{   93834000, 36249333, 166667, 0xca, 0x61 /* 011 0 0 0  01 */ },
+		{  123834000, 36249333, 166667, 0xca, 0xa1 /* 101 0 0 0  01 */ },
+		{  161000000, 36249333, 166667, 0xca, 0xa1 /* 101 0 0 0  01 */ },
+		{  163834000, 36249333, 166667, 0xca, 0xc2 /* 110 0 0 0  10 */ },
+		{  253834000, 36249333, 166667, 0xca, 0x62 /* 011 0 0 0  10 */ },
+		{  383834000, 36249333, 166667, 0xca, 0xa2 /* 101 0 0 0  10 */ },
+		{  443834000, 36249333, 166667, 0xca, 0xc2 /* 110 0 0 0  10 */ },
+		{  444000000, 36249333, 166667, 0xca, 0xc3 /* 110 0 0 0  11 */ },
+		{  583834000, 36249333, 166667, 0xca, 0x63 /* 011 0 0 0  11 */ },
+		{  793834000, 36249333, 166667, 0xca, 0xa3 /* 101 0 0 0  11 */ },
+		{  444834000, 36249333, 166667, 0xca, 0xc3 /* 110 0 0 0  11 */ },
+		{  861000000, 36249333, 166667, 0xca, 0xe3 /* 111 0 0 0  11 */ },
+	}
+};
+EXPORT_SYMBOL(dvb_pll_tda665x);
+
+/* Infineon TUA6034
+ * used in LG TDTP E102P
+ */
+static void tua6034_bw(u8 *buf, u32 freq, int bandwidth)
+{
+	if (BANDWIDTH_7_MHZ != bandwidth)
+		buf[3] |= 0x08;
+}
+
+struct dvb_pll_desc dvb_pll_tua6034 = {
+	.name  = "Infineon TUA6034",
+	.min   =  44250000,
+	.max   = 858000000,
+	.count = 3,
+	.setbw = tua6034_bw,
+	.entries = {
+		{  174500000, 36166667, 62500, 0xce, 0x01 },
+		{  230000000, 36166667, 62500, 0xce, 0x02 },
+		{  999999999, 36166667, 62500, 0xce, 0x04 },
+	},
+};
+EXPORT_SYMBOL(dvb_pll_tua6034);
+
+/* Infineon TUA6034
+ * used in LG Innotek TDVS-H062F
+ */
+struct dvb_pll_desc dvb_pll_tdvs_tua6034 = {
+	.name  = "LG/Infineon TUA6034",
+	.min   =  54000000,
+	.max   = 863000000,
+	.count = 3,
+	.entries = {
+		{  160000000, 44000000, 62500, 0xce, 0x01 },
+		{  455000000, 44000000, 62500, 0xce, 0x02 },
+		{  999999999, 44000000, 62500, 0xce, 0x04 },
+	},
+};
+EXPORT_SYMBOL(dvb_pll_tdvs_tua6034);
+
+/* Philips FMD1216ME
+ * used in Medion Hybrid PCMCIA card and USB Box
+ */
+static void fmd1216me_bw(u8 *buf, u32 freq, int bandwidth)
+{
+	if (bandwidth == BANDWIDTH_8_MHZ && freq >= 158870000)
+		buf[3] |= 0x08;
+}
+
+struct dvb_pll_desc dvb_pll_fmd1216me = {
+	.name = "Philips FMD1216ME",
+	.min = 50870000,
+	.max = 858000000,
+	.setbw = fmd1216me_bw,
+	.count = 7,
+	.entries = {
+		{ 143870000, 36213333, 166667, 0xbc, 0x41 },
+		{ 158870000, 36213333, 166667, 0xf4, 0x41 },
+		{ 329870000, 36213333, 166667, 0xbc, 0x42 },
+		{ 441870000, 36213333, 166667, 0xf4, 0x42 },
+		{ 625870000, 36213333, 166667, 0xbc, 0x44 },
+		{ 803870000, 36213333, 166667, 0xf4, 0x44 },
+		{ 999999999, 36213333, 166667, 0xfc, 0x44 },
+	}
+};
+EXPORT_SYMBOL(dvb_pll_fmd1216me);
+
+/* ALPS TDED4
+ * used in Nebula-Cards and USB boxes
+ */
+static void tded4_bw(u8 *buf, u32 freq, int bandwidth)
+{
+	if (bandwidth == BANDWIDTH_8_MHZ)
+		buf[3] |= 0x04;
+}
+
+struct dvb_pll_desc dvb_pll_tded4 = {
+	.name = "ALPS TDED4",
+	.min = 47000000,
+	.max = 863000000,
+	.setbw = tded4_bw,
+	.count = 4,
+	.entries = {
+		{ 153000000, 36166667, 166667, 0x85, 0x01 },
+		{ 470000000, 36166667, 166667, 0x85, 0x02 },
+		{ 823000000, 36166667, 166667, 0x85, 0x08 },
+		{ 999999999, 36166667, 166667, 0x85, 0x88 },
+	}
+};
+EXPORT_SYMBOL(dvb_pll_tded4);
+
 /* ----------------------------------------------------------- */
 /* code                                                        */
 
@@ -147,7 +325,7 @@ int dvb_pll_configure(struct dvb_pll_des
 	buf[3] = desc->entries[i].cb2;
 
 	if (desc->setbw)
-		desc->setbw(buf, bandwidth);
+		desc->setbw(buf, freq, bandwidth);
 
 	if (debug)
 		printk("pll: %s: div=%d | buf=0x%02x,0x%02x,0x%02x,0x%02x\n",
@@ -160,9 +338,3 @@ EXPORT_SYMBOL(dvb_pll_configure);
 MODULE_DESCRIPTION("dvb pll library");
 MODULE_AUTHOR("Gerd Knorr");
 MODULE_LICENSE("GPL");
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/dvb/frontends/dvb-pll.h b/drivers/media/dvb/frontends/dvb-pll.h
--- a/drivers/media/dvb/frontends/dvb-pll.h
+++ b/drivers/media/dvb/frontends/dvb-pll.h
@@ -1,5 +1,5 @@
 /*
- * $Id: dvb-pll.h,v 1.2 2005/02/10 11:43:41 kraxel Exp $
+ * descriptions + helper functions for simple dvb plls.
  */
 
 #ifndef __DVB_PLL_H__
@@ -9,7 +9,7 @@ struct dvb_pll_desc {
 	char *name;
 	u32  min;
 	u32  max;
-	void (*setbw)(u8 *buf, int bandwidth);
+	void (*setbw)(u8 *buf, u32 freq, int bandwidth);
 	int  count;
 	struct {
 		u32 limit;
@@ -17,15 +17,25 @@ struct dvb_pll_desc {
 		u32 stepsize;
 		u8  cb1;
 		u8  cb2;
-	} entries[9];
+	} entries[12];
 };
 
 extern struct dvb_pll_desc dvb_pll_thomson_dtt7579;
 extern struct dvb_pll_desc dvb_pll_thomson_dtt759x;
 extern struct dvb_pll_desc dvb_pll_thomson_dtt7610;
 extern struct dvb_pll_desc dvb_pll_lg_z201;
+extern struct dvb_pll_desc dvb_pll_microtune_4042;
+extern struct dvb_pll_desc dvb_pll_thomson_dtt7611;
 extern struct dvb_pll_desc dvb_pll_unknown_1;
 
+extern struct dvb_pll_desc dvb_pll_tua6010xs;
+extern struct dvb_pll_desc dvb_pll_env57h1xd5;
+extern struct dvb_pll_desc dvb_pll_tua6034;
+extern struct dvb_pll_desc dvb_pll_tdvs_tua6034;
+extern struct dvb_pll_desc dvb_pll_tda665x;
+extern struct dvb_pll_desc dvb_pll_fmd1216me;
+extern struct dvb_pll_desc dvb_pll_tded4;
+
 int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf,
 		      u32 freq, int bandwidth);
 
diff --git a/drivers/media/dvb/frontends/l64781.c b/drivers/media/dvb/frontends/l64781.c
--- a/drivers/media/dvb/frontends/l64781.c
+++ b/drivers/media/dvb/frontends/l64781.c
@@ -474,11 +474,12 @@ static int l64781_init(struct dvb_fronte
 	return 0;
 }
 
-static int l64781_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
+static int l64781_get_tune_settings(struct dvb_frontend* fe,
+				    struct dvb_frontend_tune_settings* fesettings)
 {
-        fesettings->min_delay_ms = 200;
-        fesettings->step_size = 166667;
-        fesettings->max_drift = 166667*2;
+        fesettings->min_delay_ms = 4000;
+        fesettings->step_size = 0;
+        fesettings->max_drift = 0;
         return 0;
 }
 
diff --git a/drivers/media/dvb/frontends/lgdt330x.c b/drivers/media/dvb/frontends/lgdt330x.c
new file mode 100644
--- /dev/null
+++ b/drivers/media/dvb/frontends/lgdt330x.c
@@ -0,0 +1,796 @@
+/*
+ *    Support for LGDT3302 and LGDT3303 - VSB/QAM
+ *
+ *    Copyright (C) 2005 Wilson Michaels <wilsonmichaels@earthlink.net>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This 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.
+ *
+ */
+
+/*
+ *                      NOTES ABOUT THIS DRIVER
+ *
+ * This Linux driver supports:
+ *   DViCO FusionHDTV 3 Gold-Q
+ *   DViCO FusionHDTV 3 Gold-T
+ *   DViCO FusionHDTV 5 Gold
+ *
+ * TODO:
+ * signal strength always returns 0.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <asm/byteorder.h>
+
+#include "dvb_frontend.h"
+#include "lgdt330x_priv.h"
+#include "lgdt330x.h"
+
+static int debug = 0;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug,"Turn on/off lgdt330x frontend debugging (default:off).");
+#define dprintk(args...) \
+do { \
+if (debug) printk(KERN_DEBUG "lgdt330x: " args); \
+} while (0)
+
+struct lgdt330x_state
+{
+	struct i2c_adapter* i2c;
+	struct dvb_frontend_ops ops;
+
+	/* Configuration settings */
+	const struct lgdt330x_config* config;
+
+	struct dvb_frontend frontend;
+
+	/* Demodulator private data */
+	fe_modulation_t current_modulation;
+
+	/* Tuner private data */
+	u32 current_frequency;
+};
+
+static int i2c_write_demod_bytes (struct lgdt330x_state* state,
+			   u8 *buf, /* data bytes to send */
+			   int len  /* number of bytes to send */ )
+{
+	struct i2c_msg msg =
+		{ .addr = state->config->demod_address,
+		  .flags = 0,
+		  .buf = buf,
+		  .len = 2 };
+	int i;
+	int err;
+
+	for (i=0; i<len-1; i+=2){
+		if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
+			printk(KERN_WARNING "lgdt330x: %s error (addr %02x <- %02x, err = %i)\n", __FUNCTION__, msg.buf[0], msg.buf[1], err);
+			if (err < 0)
+				return err;
+			else
+				return -EREMOTEIO;
+		}
+		msg.buf += 2;
+	}
+	return 0;
+}
+
+/*
+ * This routine writes the register (reg) to the demod bus
+ * then reads the data returned for (len) bytes.
+ */
+
+static u8 i2c_read_demod_bytes (struct lgdt330x_state* state,
+			       enum I2C_REG reg, u8* buf, int len)
+{
+	u8 wr [] = { reg };
+	struct i2c_msg msg [] = {
+		{ .addr = state->config->demod_address,
+		  .flags = 0, .buf = wr,  .len = 1 },
+		{ .addr = state->config->demod_address,
+		  .flags = I2C_M_RD, .buf = buf, .len = len },
+	};
+	int ret;
+	ret = i2c_transfer(state->i2c, msg, 2);
+	if (ret != 2) {
+		printk(KERN_WARNING "lgdt330x: %s: addr 0x%02x select 0x%02x error (ret == %i)\n", __FUNCTION__, state->config->demod_address, reg, ret);
+	} else {
+		ret = 0;
+	}
+	return ret;
+}
+
+/* Software reset */
+static int lgdt3302_SwReset(struct lgdt330x_state* state)
+{
+	u8 ret;
+	u8 reset[] = {
+		IRQ_MASK,
+		0x00 /* bit 6 is active low software reset
+		      *	bits 5-0 are 1 to mask interrupts */
+	};
+
+	ret = i2c_write_demod_bytes(state,
+			     reset, sizeof(reset));
+	if (ret == 0) {
+
+		/* force reset high (inactive) and unmask interrupts */
+		reset[1] = 0x7f;
+		ret = i2c_write_demod_bytes(state,
+				     reset, sizeof(reset));
+	}
+	return ret;
+}
+
+static int lgdt3303_SwReset(struct lgdt330x_state* state)
+{
+	u8 ret;
+	u8 reset[] = {
+		0x02,
+		0x00 /* bit 0 is active low software reset */
+	};
+
+	ret = i2c_write_demod_bytes(state,
+			     reset, sizeof(reset));
+	if (ret == 0) {
+
+		/* force reset high (inactive) */
+		reset[1] = 0x01;
+		ret = i2c_write_demod_bytes(state,
+				     reset, sizeof(reset));
+	}
+	return ret;
+}
+
+static int lgdt330x_SwReset(struct lgdt330x_state* state)
+{
+	switch (state->config->demod_chip) {
+	case LGDT3302:
+		return lgdt3302_SwReset(state);
+	case LGDT3303:
+		return lgdt3303_SwReset(state);
+	default:
+		return -ENODEV;
+	}
+}
+
+
+static int lgdt330x_init(struct dvb_frontend* fe)
+{
+	/* Hardware reset is done using gpio[0] of cx23880x chip.
+	 * I'd like to do it here, but don't know how to find chip address.
+	 * cx88-cards.c arranges for the reset bit to be inactive (high).
+	 * Maybe there needs to be a callable function in cx88-core or
+	 * the caller of this function needs to do it. */
+
+	/*
+	 * Array of byte pairs <address, value>
+	 * to initialize each different chip
+	 */
+	static u8 lgdt3302_init_data[] = {
+		/* Use 50MHz parameter values from spec sheet since xtal is 50 */
+		/* Change the value of NCOCTFV[25:0] of carrier
+		   recovery center frequency register */
+		VSB_CARRIER_FREQ0, 0x00,
+		VSB_CARRIER_FREQ1, 0x87,
+		VSB_CARRIER_FREQ2, 0x8e,
+		VSB_CARRIER_FREQ3, 0x01,
+		/* Change the TPCLK pin polarity
+		   data is valid on falling clock */
+		DEMUX_CONTROL, 0xfb,
+		/* Change the value of IFBW[11:0] of
+		   AGC IF/RF loop filter bandwidth register */
+		AGC_RF_BANDWIDTH0, 0x40,
+		AGC_RF_BANDWIDTH1, 0x93,
+		AGC_RF_BANDWIDTH2, 0x00,
+		/* Change the value of bit 6, 'nINAGCBY' and
+		   'NSSEL[1:0] of ACG function control register 2 */
+		AGC_FUNC_CTRL2, 0xc6,
+		/* Change the value of bit 6 'RFFIX'
+		   of AGC function control register 3 */
+		AGC_FUNC_CTRL3, 0x40,
+		/* Set the value of 'INLVTHD' register 0x2a/0x2c
+		   to 0x7fe */
+		AGC_DELAY0, 0x07,
+		AGC_DELAY2, 0xfe,
+		/* Change the value of IAGCBW[15:8]
+		   of inner AGC loop filter bandwith */
+		AGC_LOOP_BANDWIDTH0, 0x08,
+		AGC_LOOP_BANDWIDTH1, 0x9a
+	};
+
+	static u8 lgdt3303_init_data[] = {
+		0x4c, 0x14
+	};
+
+	struct lgdt330x_state* state = fe->demodulator_priv;
+	char  *chip_name;
+	int    err;
+
+	switch (state->config->demod_chip) {
+	case LGDT3302:
+		chip_name = "LGDT3302";
+		err = i2c_write_demod_bytes(state, lgdt3302_init_data,
+									sizeof(lgdt3302_init_data));
+  		break;
+	case LGDT3303:
+		chip_name = "LGDT3303";
+		err = i2c_write_demod_bytes(state, lgdt3303_init_data,
+									sizeof(lgdt3303_init_data));
+  		break;
+	default:
+		chip_name = "undefined";
+		printk (KERN_WARNING "Only LGDT3302 and LGDT3303 are supported chips.\n");
+		err = -ENODEV;
+	}
+	dprintk("%s entered as %s\n", __FUNCTION__, chip_name);
+	if (err < 0)
+		return err;
+	return lgdt330x_SwReset(state);
+}
+
+static int lgdt330x_read_ber(struct dvb_frontend* fe, u32* ber)
+{
+	*ber = 0; /* Not supplied by the demod chips */
+	return 0;
+}
+
+static int lgdt330x_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
+{
+	struct lgdt330x_state* state = fe->demodulator_priv;
+	int err;
+	u8 buf[2];
+
+	switch (state->config->demod_chip) {
+	case LGDT3302:
+		err = i2c_read_demod_bytes(state, LGDT3302_PACKET_ERR_COUNTER1,
+								  buf, sizeof(buf));
+  		break;
+	case LGDT3303:
+		err = i2c_read_demod_bytes(state, LGDT3303_PACKET_ERR_COUNTER1,
+								  buf, sizeof(buf));
+  		break;
+	default:
+		printk(KERN_WARNING
+			   "Only LGDT3302 and LGDT3303 are supported chips.\n");
+		err = -ENODEV;
+	}
+
+	*ucblocks = (buf[0] << 8) | buf[1];
+	return 0;
+}
+
+static int lgdt330x_set_parameters(struct dvb_frontend* fe,
+				   struct dvb_frontend_parameters *param)
+{
+	/*
+	 * Array of byte pairs <address, value>
+	 * to initialize 8VSB for lgdt3303 chip 50 MHz IF
+	 */
+	static u8 lgdt3303_8vsb_44_data[] = {
+		0x04, 0x00,
+		0x0d, 0x40,
+        0x0e, 0x87,
+        0x0f, 0x8e,
+        0x10, 0x01,
+        0x47, 0x8b };
+
+	/*
+	 * Array of byte pairs <address, value>
+	 * to initialize QAM for lgdt3303 chip
+	 */
+	static u8 lgdt3303_qam_data[] = {
+		0x04, 0x00,
+		0x0d, 0x00,
+		0x0e, 0x00,
+		0x0f, 0x00,
+		0x10, 0x00,
+		0x51, 0x63,
+		0x47, 0x66,
+		0x48, 0x66,
+		0x4d, 0x1a,
+		0x49, 0x08,
+		0x4a, 0x9b };
+
+	struct lgdt330x_state* state = fe->demodulator_priv;
+
+	static u8 top_ctrl_cfg[]   = { TOP_CONTROL, 0x03 };
+
+	int err;
+	/* Change only if we are actually changing the modulation */
+	if (state->current_modulation != param->u.vsb.modulation) {
+		switch(param->u.vsb.modulation) {
+		case VSB_8:
+			dprintk("%s: VSB_8 MODE\n", __FUNCTION__);
+
+			/* Select VSB mode */
+			top_ctrl_cfg[1] = 0x03;
+
+			/* Select ANT connector if supported by card */
+			if (state->config->pll_rf_set)
+				state->config->pll_rf_set(fe, 1);
+
+			if (state->config->demod_chip == LGDT3303) {
+				err = i2c_write_demod_bytes(state, lgdt3303_8vsb_44_data,
+											sizeof(lgdt3303_8vsb_44_data));
+			}
+			break;
+
+		case QAM_64:
+			dprintk("%s: QAM_64 MODE\n", __FUNCTION__);
+
+			/* Select QAM_64 mode */
+			top_ctrl_cfg[1] = 0x00;
+
+			/* Select CABLE connector if supported by card */
+			if (state->config->pll_rf_set)
+				state->config->pll_rf_set(fe, 0);
+
+			if (state->config->demod_chip == LGDT3303) {
+				err = i2c_write_demod_bytes(state, lgdt3303_qam_data,
+											sizeof(lgdt3303_qam_data));
+			}
+			break;
+
+		case QAM_256:
+			dprintk("%s: QAM_256 MODE\n", __FUNCTION__);
+
+			/* Select QAM_256 mode */
+			top_ctrl_cfg[1] = 0x01;
+
+			/* Select CABLE connector if supported by card */
+			if (state->config->pll_rf_set)
+				state->config->pll_rf_set(fe, 0);
+
+			if (state->config->demod_chip == LGDT3303) {
+				err = i2c_write_demod_bytes(state, lgdt3303_qam_data,
+											sizeof(lgdt3303_qam_data));
+			}
+			break;
+		default:
+			printk(KERN_WARNING "lgdt330x: %s: Modulation type(%d) UNSUPPORTED\n", __FUNCTION__, param->u.vsb.modulation);
+			return -1;
+		}
+		/*
+		 * select serial or parallel MPEG harware interface
+		 * Serial:   0x04 for LGDT3302 or 0x40 for LGDT3303
+		 * Parallel: 0x00
+		 */
+		top_ctrl_cfg[1] |= state->config->serial_mpeg;
+
+		/* Select the requested mode */
+		i2c_write_demod_bytes(state, top_ctrl_cfg,
+							  sizeof(top_ctrl_cfg));
+		state->config->set_ts_params(fe, 0);
+		state->current_modulation = param->u.vsb.modulation;
+	}
+
+	/* Change only if we are actually changing the channel */
+	if (state->current_frequency != param->frequency) {
+		/* Tune to the new frequency */
+		state->config->pll_set(fe, param);
+		/* Keep track of the new frequency */
+		state->current_frequency = param->frequency;
+	}
+	lgdt330x_SwReset(state);
+	return 0;
+}
+
+static int lgdt330x_get_frontend(struct dvb_frontend* fe,
+				 struct dvb_frontend_parameters* param)
+{
+	struct lgdt330x_state *state = fe->demodulator_priv;
+	param->frequency = state->current_frequency;
+	return 0;
+}
+
+static int lgdt3302_read_status(struct dvb_frontend* fe, fe_status_t* status)
+{
+	struct lgdt330x_state* state = fe->demodulator_priv;
+	u8 buf[3];
+
+	*status = 0; /* Reset status result */
+
+	/* AGC status register */
+	i2c_read_demod_bytes(state, AGC_STATUS, buf, 1);
+	dprintk("%s: AGC_STATUS = 0x%02x\n", __FUNCTION__, buf[0]);
+	if ((buf[0] & 0x0c) == 0x8){
+		/* Test signal does not exist flag */
+		/* as well as the AGC lock flag.   */
+		*status |= FE_HAS_SIGNAL;
+	} else {
+		/* Without a signal all other status bits are meaningless */
+		return 0;
+	}
+
+	/*
+	 * You must set the Mask bits to 1 in the IRQ_MASK in order
+	 * to see that status bit in the IRQ_STATUS register.
+	 * This is done in SwReset();
+	 */
+	/* signal status */
+	i2c_read_demod_bytes(state, TOP_CONTROL, buf, sizeof(buf));
+	dprintk("%s: TOP_CONTROL = 0x%02x, IRO_MASK = 0x%02x, IRQ_STATUS = 0x%02x\n", __FUNCTION__, buf[0], buf[1], buf[2]);
+
+
+	/* sync status */
+	if ((buf[2] & 0x03) == 0x01) {
+		*status |= FE_HAS_SYNC;
+	}
+
+	/* FEC error status */
+	if ((buf[2] & 0x0c) == 0x08) {
+		*status |= FE_HAS_LOCK;
+		*status |= FE_HAS_VITERBI;
+	}
+
+	/* Carrier Recovery Lock Status Register */
+	i2c_read_demod_bytes(state, CARRIER_LOCK, buf, 1);
+	dprintk("%s: CARRIER_LOCK = 0x%02x\n", __FUNCTION__, buf[0]);
+	switch (state->current_modulation) {
+	case QAM_256:
+	case QAM_64:
+		/* Need to undestand why there are 3 lock levels here */
+		if ((buf[0] & 0x07) == 0x07)
+			*status |= FE_HAS_CARRIER;
+		break;
+	case VSB_8:
+		if ((buf[0] & 0x80) == 0x80)
+			*status |= FE_HAS_CARRIER;
+		break;
+	default:
+		printk("KERN_WARNING lgdt330x: %s: Modulation set to unsupported value\n", __FUNCTION__);
+	}
+
+	return 0;
+}
+
+static int lgdt3303_read_status(struct dvb_frontend* fe, fe_status_t* status)
+{
+	struct lgdt330x_state* state = fe->demodulator_priv;
+	int err;
+	u8 buf[3];
+
+	*status = 0; /* Reset status result */
+
+	/* lgdt3303 AGC status register */
+	err = i2c_read_demod_bytes(state, 0x58, buf, 1);
+	if (err < 0)
+		return err;
+
+	dprintk("%s: AGC_STATUS = 0x%02x\n", __FUNCTION__, buf[0]);
+	if ((buf[0] & 0x21) == 0x01){
+		/* Test input signal does not exist flag */
+		/* as well as the AGC lock flag.   */
+		*status |= FE_HAS_SIGNAL;
+	} else {
+		/* Without a signal all other status bits are meaningless */
+		return 0;
+	}
+
+	/* Carrier Recovery Lock Status Register */
+	i2c_read_demod_bytes(state, CARRIER_LOCK, buf, 1);
+	dprintk("%s: CARRIER_LOCK = 0x%02x\n", __FUNCTION__, buf[0]);
+	switch (state->current_modulation) {
+	case QAM_256:
+	case QAM_64:
+		/* Need to undestand why there are 3 lock levels here */
+		if ((buf[0] & 0x07) == 0x07)
+			*status |= FE_HAS_CARRIER;
+		else
+			break;
+		i2c_read_demod_bytes(state, 0x8a, buf, 1);
+		if ((buf[0] & 0x04) == 0x04)
+			*status |= FE_HAS_SYNC;
+		if ((buf[0] & 0x01) == 0x01)
+			*status |= FE_HAS_LOCK;
+		if ((buf[0] & 0x08) == 0x08)
+			*status |= FE_HAS_VITERBI;
+		break;
+	case VSB_8:
+		if ((buf[0] & 0x80) == 0x80)
+			*status |= FE_HAS_CARRIER;
+		else
+			break;
+		i2c_read_demod_bytes(state, 0x38, buf, 1);
+		if ((buf[0] & 0x02) == 0x00)
+			*status |= FE_HAS_SYNC;
+		if ((buf[0] & 0x01) == 0x01) {
+			*status |= FE_HAS_LOCK;
+			*status |= FE_HAS_VITERBI;
+		}
+		break;
+	default:
+		printk("KERN_WARNING lgdt330x: %s: Modulation set to unsupported value\n", __FUNCTION__);
+	}
+	return 0;
+}
+
+static int lgdt330x_read_signal_strength(struct dvb_frontend* fe, u16* strength)
+{
+	/* not directly available. */
+	*strength = 0;
+	return 0;
+}
+
+static int lgdt3302_read_snr(struct dvb_frontend* fe, u16* snr)
+{
+#ifdef SNR_IN_DB
+	/*
+	 * Spec sheet shows formula for SNR_EQ = 10 log10(25 * 24**2 / noise)
+	 * and SNR_PH = 10 log10(25 * 32**2 / noise) for equalizer and phase tracker
+	 * respectively. The following tables are built on these formulas.
+	 * The usual definition is SNR = 20 log10(signal/noise)
+	 * If the specification is wrong the value retuned is 1/2 the actual SNR in db.
+	 *
+	 * This table is a an ordered list of noise values computed by the
+	 * formula from the spec sheet such that the index into the table
+	 * starting at 43 or 45 is the SNR value in db. There are duplicate noise
+	 * value entries at the beginning because the SNR varies more than
+	 * 1 db for a change of 1 digit in noise at very small values of noise.
+	 *
+	 * Examples from SNR_EQ table:
+	 * noise SNR
+	 *   0    43
+	 *   1    42
+	 *   2    39
+	 *   3    37
+	 *   4    36
+	 *   5    35
+	 *   6    34
+	 *   7    33
+	 *   8    33
+	 *   9    32
+	 *   10   32
+	 *   11   31
+	 *   12   31
+	 *   13   30
+	 */
+
+	static const u32 SNR_EQ[] =
+		{ 1,     2,      2,      2, 3,      3,      4,     4,     5,     7,
+		  9,     11,     13,     17, 21,     26,     33,    41,    52,    65,
+		  81,    102,    129,    162, 204,    257,    323,   406,   511,   644,
+		  810,   1020,   1284,   1616, 2035,   2561,   3224,  4059,  5110,  6433,
+		  8098,  10195,  12835,  16158, 20341,  25608,  32238, 40585, 51094, 64323,
+		  80978, 101945, 128341, 161571, 203406, 256073, 0x40000
+		};
+
+	static const u32 SNR_PH[] =
+		{ 1,     2,      2,      2,      3,      3,     4,     5,     6,     8,
+		  10,    12,     15,     19,     23,     29, 37,    46,    58,    73,
+		  91,    115,    144,    182,    229,    288, 362,   456,   574,   722,
+		  909,   1144,   1440,   1813,   2282,   2873, 3617,  4553,  5732,  7216,
+		  9084,  11436,  14396,  18124,  22817,  28724,  36161, 45524, 57312, 72151,
+		  90833, 114351, 143960, 181235, 228161, 0x080000
+		};
+
+	static u8 buf[5];/* read data buffer */
+	static u32 noise;   /* noise value */
+	static u32 snr_db;  /* index into SNR_EQ[] */
+	struct lgdt330x_state* state = (struct lgdt330x_state*) fe->demodulator_priv;
+
+	/* read both equalizer and phase tracker noise data */
+	i2c_read_demod_bytes(state, EQPH_ERR0, buf, sizeof(buf));
+
+	if (state->current_modulation == VSB_8) {
+		/* Equalizer Mean-Square Error Register for VSB */
+		noise = ((buf[0] & 7) << 16) | (buf[1] << 8) | buf[2];
+
+		/*
+		 * Look up noise value in table.
+		 * A better search algorithm could be used...
+		 * watch out there are duplicate entries.
+		 */
+		for (snr_db = 0; snr_db < sizeof(SNR_EQ); snr_db++) {
+			if (noise < SNR_EQ[snr_db]) {
+				*snr = 43 - snr_db;
+				break;
+			}
+		}
+	} else {
+		/* Phase Tracker Mean-Square Error Register for QAM */
+		noise = ((buf[0] & 7<<3) << 13) | (buf[3] << 8) | buf[4];
+
+		/* Look up noise value in table. */
+		for (snr_db = 0; snr_db < sizeof(SNR_PH); snr_db++) {
+			if (noise < SNR_PH[snr_db]) {
+				*snr = 45 - snr_db;
+				break;
+			}
+		}
+	}
+#else
+	/* Return the raw noise value */
+	static u8 buf[5];/* read data buffer */
+	static u32 noise;   /* noise value */
+	struct lgdt330x_state* state = (struct lgdt330x_state*) fe->demodulator_priv;
+
+	/* read both equalizer and pase tracker noise data */
+	i2c_read_demod_bytes(state, EQPH_ERR0, buf, sizeof(buf));
+
+	if (state->current_modulation == VSB_8) {
+		/* Phase Tracker Mean-Square Error Register for VSB */
+		noise = ((buf[0] & 7<<3) << 13) | (buf[3] << 8) | buf[4];
+	} else {
+
+		/* Carrier Recovery Mean-Square Error for QAM */
+		i2c_read_demod_bytes(state, 0x1a, buf, 2);
+		noise = ((buf[0] & 3) << 8) | buf[1];
+	}
+
+	/* Small values for noise mean signal is better so invert noise */
+	*snr = ~noise;
+#endif
+
+	dprintk("%s: noise = 0x%05x, snr = %idb\n",__FUNCTION__, noise, *snr);
+
+	return 0;
+}
+
+static int lgdt3303_read_snr(struct dvb_frontend* fe, u16* snr)
+{
+	/* Return the raw noise value */
+	static u8 buf[5];/* read data buffer */
+	static u32 noise;   /* noise value */
+	struct lgdt330x_state* state = (struct lgdt330x_state*) fe->demodulator_priv;
+
+	if (state->current_modulation == VSB_8) {
+
+		/* Phase Tracker Mean-Square Error Register for VSB */
+		noise = ((buf[0] & 7) << 16) | (buf[3] << 8) | buf[4];
+	} else {
+
+		/* Carrier Recovery Mean-Square Error for QAM */
+		i2c_read_demod_bytes(state, 0x1a, buf, 2);
+		noise = (buf[0] << 8) | buf[1];
+	}
+
+	/* Small values for noise mean signal is better so invert noise */
+	*snr = ~noise;
+
+	dprintk("%s: noise = 0x%05x, snr = %idb\n",__FUNCTION__, noise, *snr);
+
+	return 0;
+}
+
+static int lgdt330x_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fe_tune_settings)
+{
+	/* I have no idea about this - it may not be needed */
+	fe_tune_settings->min_delay_ms = 500;
+	fe_tune_settings->step_size = 0;
+	fe_tune_settings->max_drift = 0;
+	return 0;
+}
+
+static void lgdt330x_release(struct dvb_frontend* fe)
+{
+	struct lgdt330x_state* state = (struct lgdt330x_state*) fe->demodulator_priv;
+	kfree(state);
+}
+
+static struct dvb_frontend_ops lgdt3302_ops;
+static struct dvb_frontend_ops lgdt3303_ops;
+
+struct dvb_frontend* lgdt330x_attach(const struct lgdt330x_config* config,
+				     struct i2c_adapter* i2c)
+{
+	struct lgdt330x_state* state = NULL;
+	u8 buf[1];
+
+	/* Allocate memory for the internal state */
+	state = (struct lgdt330x_state*) kmalloc(sizeof(struct lgdt330x_state), GFP_KERNEL);
+	if (state == NULL)
+		goto error;
+	memset(state,0,sizeof(*state));
+
+	/* Setup the state */
+	state->config = config;
+	state->i2c = i2c;
+	switch (config->demod_chip) {
+	case LGDT3302:
+		memcpy(&state->ops, &lgdt3302_ops, sizeof(struct dvb_frontend_ops));
+		break;
+	case LGDT3303:
+		memcpy(&state->ops, &lgdt3303_ops, sizeof(struct dvb_frontend_ops));
+		break;
+	default:
+		goto error;
+	}
+
+	/* Verify communication with demod chip */
+	if (i2c_read_demod_bytes(state, 2, buf, 1))
+		goto error;
+
+	state->current_frequency = -1;
+	state->current_modulation = -1;
+
+	/* Create dvb_frontend */
+	state->frontend.ops = &state->ops;
+	state->frontend.demodulator_priv = state;
+	return &state->frontend;
+
+error:
+	if (state)
+		kfree(state);
+	dprintk("%s: ERROR\n",__FUNCTION__);
+	return NULL;
+}
+
+static struct dvb_frontend_ops lgdt3302_ops = {
+	.info = {
+		.name= "LG Electronics LGDT3302 VSB/QAM Frontend",
+		.type = FE_ATSC,
+		.frequency_min= 54000000,
+		.frequency_max= 858000000,
+		.frequency_stepsize= 62500,
+		/* Symbol rate is for all VSB modes need to check QAM */
+		.symbol_rate_min    = 10762000,
+		.symbol_rate_max    = 10762000,
+		.caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
+	},
+	.init                 = lgdt330x_init,
+	.set_frontend         = lgdt330x_set_parameters,
+	.get_frontend         = lgdt330x_get_frontend,
+	.get_tune_settings    = lgdt330x_get_tune_settings,
+	.read_status          = lgdt3302_read_status,
+	.read_ber             = lgdt330x_read_ber,
+	.read_signal_strength = lgdt330x_read_signal_strength,
+	.read_snr             = lgdt3302_read_snr,
+	.read_ucblocks        = lgdt330x_read_ucblocks,
+	.release              = lgdt330x_release,
+};
+
+static struct dvb_frontend_ops lgdt3303_ops = {
+	.info = {
+		.name= "LG Electronics LGDT3303 VSB/QAM Frontend",
+		.type = FE_ATSC,
+		.frequency_min= 54000000,
+		.frequency_max= 858000000,
+		.frequency_stepsize= 62500,
+		/* Symbol rate is for all VSB modes need to check QAM */
+		.symbol_rate_min    = 10762000,
+		.symbol_rate_max    = 10762000,
+		.caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
+	},
+	.init                 = lgdt330x_init,
+	.set_frontend         = lgdt330x_set_parameters,
+	.get_frontend         = lgdt330x_get_frontend,
+	.get_tune_settings    = lgdt330x_get_tune_settings,
+	.read_status          = lgdt3303_read_status,
+	.read_ber             = lgdt330x_read_ber,
+	.read_signal_strength = lgdt330x_read_signal_strength,
+	.read_snr             = lgdt3303_read_snr,
+	.read_ucblocks        = lgdt330x_read_ucblocks,
+	.release              = lgdt330x_release,
+};
+
+MODULE_DESCRIPTION("LGDT330X (ATSC 8VSB & ITU-T J.83 AnnexB 64/256 QAM) Demodulator Driver");
+MODULE_AUTHOR("Wilson Michaels");
+MODULE_LICENSE("GPL");
+
+EXPORT_SYMBOL(lgdt330x_attach);
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/drivers/media/dvb/frontends/lgdt330x.h b/drivers/media/dvb/frontends/lgdt330x.h
new file mode 100644
--- /dev/null
+++ b/drivers/media/dvb/frontends/lgdt330x.h
@@ -0,0 +1,61 @@
+/*
+ *    Support for LGDT3302 and LGDT3303 - VSB/QAM
+ *
+ *    Copyright (C) 2005 Wilson Michaels <wilsonmichaels@earthlink.net>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This 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 LGDT330X_H
+#define LGDT330X_H
+
+#include <linux/dvb/frontend.h>
+
+typedef enum lg_chip_t {
+		UNDEFINED,
+		LGDT3302,
+		LGDT3303
+}lg_chip_type;
+
+struct lgdt330x_config
+{
+	/* The demodulator's i2c address */
+	u8 demod_address;
+
+	/* LG demodulator chip LGDT3302 or LGDT3303 */
+	lg_chip_type demod_chip;
+
+	/* MPEG hardware interface - 0:parallel 1:serial */
+	int serial_mpeg;
+
+	/* PLL interface */
+	int (*pll_rf_set) (struct dvb_frontend* fe, int index);
+	int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
+
+	/* Need to set device param for start_dma */
+	int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured);
+};
+
+extern struct dvb_frontend* lgdt330x_attach(const struct lgdt330x_config* config,
+					    struct i2c_adapter* i2c);
+
+#endif /* LGDT330X_H */
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/drivers/media/dvb/frontends/lgdt330x_priv.h b/drivers/media/dvb/frontends/lgdt330x_priv.h
new file mode 100644
--- /dev/null
+++ b/drivers/media/dvb/frontends/lgdt330x_priv.h
@@ -0,0 +1,72 @@
+/*
+ *    Support for LGDT3302 and LGDT3303 - VSB/QAM
+ *
+ *    Copyright (C) 2005 Wilson Michaels <wilsonmichaels@earthlink.net>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This 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 _LGDT330X_PRIV_
+#define _LGDT330X_PRIV_
+
+/* i2c control register addresses */
+enum I2C_REG {
+	TOP_CONTROL= 0x00,
+	IRQ_MASK= 0x01,
+	IRQ_STATUS= 0x02,
+	VSB_CARRIER_FREQ0= 0x16,
+	VSB_CARRIER_FREQ1= 0x17,
+	VSB_CARRIER_FREQ2= 0x18,
+	VSB_CARRIER_FREQ3= 0x19,
+	CARRIER_MSEQAM1= 0x1a,
+	CARRIER_MSEQAM2= 0x1b,
+	CARRIER_LOCK= 0x1c,
+	TIMING_RECOVERY= 0x1d,
+	AGC_DELAY0= 0x2a,
+	AGC_DELAY1= 0x2b,
+	AGC_DELAY2= 0x2c,
+	AGC_RF_BANDWIDTH0= 0x2d,
+	AGC_RF_BANDWIDTH1= 0x2e,
+	AGC_RF_BANDWIDTH2= 0x2f,
+	AGC_LOOP_BANDWIDTH0= 0x30,
+	AGC_LOOP_BANDWIDTH1= 0x31,
+	AGC_FUNC_CTRL1= 0x32,
+	AGC_FUNC_CTRL2= 0x33,
+	AGC_FUNC_CTRL3= 0x34,
+	AGC_RFIF_ACC0= 0x39,
+	AGC_RFIF_ACC1= 0x3a,
+	AGC_RFIF_ACC2= 0x3b,
+	AGC_STATUS= 0x3f,
+	SYNC_STATUS_VSB= 0x43,
+	EQPH_ERR0= 0x47,
+	EQ_ERR1= 0x48,
+	EQ_ERR2= 0x49,
+	PH_ERR1= 0x4a,
+	PH_ERR2= 0x4b,
+	DEMUX_CONTROL= 0x66,
+	LGDT3302_PACKET_ERR_COUNTER1= 0x6a,
+	LGDT3302_PACKET_ERR_COUNTER2= 0x6b,
+	LGDT3303_PACKET_ERR_COUNTER1= 0x8b,
+	LGDT3303_PACKET_ERR_COUNTER2= 0x8c,
+};
+
+#endif /* _LGDT330X_PRIV_ */
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/drivers/media/dvb/frontends/s5h1420.c b/drivers/media/dvb/frontends/s5h1420.c
new file mode 100644
--- /dev/null
+++ b/drivers/media/dvb/frontends/s5h1420.c
@@ -0,0 +1,800 @@
+/*
+Driver for Samsung S5H1420 QPSK Demodulator
+
+Copyright (C) 2005 Andrew de Quincey <adq_dvb@lidskialf.net>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This 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 <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+
+#include "dvb_frontend.h"
+#include "s5h1420.h"
+
+
+
+#define TONE_FREQ 22000
+
+struct s5h1420_state {
+	struct i2c_adapter* i2c;
+	struct dvb_frontend_ops ops;
+	const struct s5h1420_config* config;
+	struct dvb_frontend frontend;
+
+	u8 postlocked:1;
+	u32 fclk;
+	u32 tunedfreq;
+	fe_code_rate_t fec_inner;
+	u32 symbol_rate;
+};
+
+static u32 s5h1420_getsymbolrate(struct s5h1420_state* state);
+static int s5h1420_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings);
+
+
+static int debug = 0;
+#define dprintk if (debug) printk
+
+static int s5h1420_writereg (struct s5h1420_state* state, u8 reg, u8 data)
+{
+	u8 buf [] = { reg, data };
+	struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
+	int err;
+
+	if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
+		dprintk ("%s: writereg error (err == %i, reg == 0x%02x, data == 0x%02x)\n", __FUNCTION__, err, reg, data);
+		return -EREMOTEIO;
+	}
+
+	return 0;
+}
+
+static u8 s5h1420_readreg (struct s5h1420_state* state, u8 reg)
+{
+	int ret;
+	u8 b0 [] = { reg };
+	u8 b1 [] = { 0 };
+	struct i2c_msg msg1 = { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 };
+	struct i2c_msg msg2 = { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 };
+
+	if ((ret = i2c_transfer (state->i2c, &msg1, 1)) != 1)
+		return ret;
+
+	if ((ret = i2c_transfer (state->i2c, &msg2, 1)) != 1)
+		return ret;
+
+	return b1[0];
+}
+
+static int s5h1420_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage)
+{
+	struct s5h1420_state* state = fe->demodulator_priv;
+
+	switch(voltage) {
+	case SEC_VOLTAGE_13:
+		s5h1420_writereg(state, 0x3c, (s5h1420_readreg(state, 0x3c) & 0xfe) | 0x02);
+		break;
+
+	case SEC_VOLTAGE_18:
+		s5h1420_writereg(state, 0x3c, s5h1420_readreg(state, 0x3c) | 0x03);
+		break;
+
+	case SEC_VOLTAGE_OFF:
+		s5h1420_writereg(state, 0x3c, s5h1420_readreg(state, 0x3c) & 0xfd);
+		break;
+	}
+
+	return 0;
+}
+
+static int s5h1420_set_tone (struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
+{
+	struct s5h1420_state* state = fe->demodulator_priv;
+
+	switch(tone) {
+	case SEC_TONE_ON:
+		s5h1420_writereg(state, 0x3b, (s5h1420_readreg(state, 0x3b) & 0x74) | 0x08);
+		break;
+
+	case SEC_TONE_OFF:
+		s5h1420_writereg(state, 0x3b, (s5h1420_readreg(state, 0x3b) & 0x74) | 0x01);
+		break;
+	}
+
+	return 0;
+}
+
+static int s5h1420_send_master_cmd (struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd)
+{
+	struct s5h1420_state* state = fe->demodulator_priv;
+	u8 val;
+	int i;
+	unsigned long timeout;
+	int result = 0;
+
+	/* setup for DISEQC */
+	val = s5h1420_readreg(state, 0x3b);
+	s5h1420_writereg(state, 0x3b, 0x02);
+	msleep(15);
+
+	/* write the DISEQC command bytes */
+	for(i=0; i< cmd->msg_len; i++) {
+		s5h1420_writereg(state, 0x3c + i, cmd->msg[i]);
+	}
+
+	/* kick off transmission */
+	s5h1420_writereg(state, 0x3b, s5h1420_readreg(state, 0x3b) | ((cmd->msg_len-1) << 4) | 0x08);
+
+	/* wait for transmission to complete */
+	timeout = jiffies + ((100*HZ) / 1000);
+	while(time_before(jiffies, timeout)) {
+		if (s5h1420_readreg(state, 0x3b) & 0x08)
+			break;
+
+		msleep(5);
+	}
+	if (time_after(jiffies, timeout))
+		result = -ETIMEDOUT;
+
+	/* restore original settings */
+	s5h1420_writereg(state, 0x3b, val);
+	msleep(15);
+	return result;
+}
+
+static int s5h1420_recv_slave_reply (struct dvb_frontend* fe, struct dvb_diseqc_slave_reply* reply)
+{
+	struct s5h1420_state* state = fe->demodulator_priv;
+	u8 val;
+	int i;
+	int length;
+	unsigned long timeout;
+	int result = 0;
+
+	/* setup for DISEQC recieve */
+	val = s5h1420_readreg(state, 0x3b);
+	s5h1420_writereg(state, 0x3b, 0x82); /* FIXME: guess - do we need to set DIS_RDY(0x08) in receive mode? */
+	msleep(15);
+
+	/* wait for reception to complete */
+	timeout = jiffies + ((reply->timeout*HZ) / 1000);
+	while(time_before(jiffies, timeout)) {
+		if (!(s5h1420_readreg(state, 0x3b) & 0x80)) /* FIXME: do we test DIS_RDY(0x08) or RCV_EN(0x80)? */
+			break;
+
+		msleep(5);
+	}
+	if (time_after(jiffies, timeout)) {
+		result = -ETIMEDOUT;
+		goto exit;
+	}
+
+	/* check error flag - FIXME: not sure what this does - docs do not describe
+	 * beyond "error flag for diseqc receive data :( */
+	if (s5h1420_readreg(state, 0x49)) {
+		result = -EIO;
+		goto exit;
+	}
+
+	/* check length */
+	length = (s5h1420_readreg(state, 0x3b) & 0x70) >> 4;
+	if (length > sizeof(reply->msg)) {
+		result = -EOVERFLOW;
+		goto exit;
+	}
+	reply->msg_len = length;
+
+	/* extract data */
+	for(i=0; i< length; i++) {
+		reply->msg[i] = s5h1420_readreg(state, 0x3c + i);
+	}
+
+exit:
+	/* restore original settings */
+	s5h1420_writereg(state, 0x3b, val);
+	msleep(15);
+	return result;
+}
+
+static int s5h1420_send_burst (struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd)
+{
+	struct s5h1420_state* state = fe->demodulator_priv;
+	u8 val;
+	int result = 0;
+	unsigned long timeout;
+
+	/* setup for tone burst */
+	val = s5h1420_readreg(state, 0x3b);
+	s5h1420_writereg(state, 0x3b, (s5h1420_readreg(state, 0x3b) & 0x70) | 0x01);
+
+	/* set value for B position if requested */
+	if (minicmd == SEC_MINI_B) {
+		s5h1420_writereg(state, 0x3b, s5h1420_readreg(state, 0x3b) | 0x04);
+	}
+	msleep(15);
+
+	/* start transmission */
+	s5h1420_writereg(state, 0x3b, s5h1420_readreg(state, 0x3b) | 0x08);
+
+	/* wait for transmission to complete */
+	timeout = jiffies + ((20*HZ) / 1000);
+	while(time_before(jiffies, timeout)) {
+		if (!(s5h1420_readreg(state, 0x3b) & 0x08))
+			break;
+
+		msleep(5);
+	}
+	if (time_after(jiffies, timeout))
+		result = -ETIMEDOUT;
+
+	/* restore original settings */
+	s5h1420_writereg(state, 0x3b, val);
+	msleep(15);
+	return result;
+}
+
+static fe_status_t s5h1420_get_status_bits(struct s5h1420_state* state)
+{
+	u8 val;
+	fe_status_t status = 0;
+
+	val = s5h1420_readreg(state, 0x14);
+	if (val & 0x02)
+		status |=  FE_HAS_SIGNAL; // FIXME: not sure if this is right
+	if (val & 0x01)
+		status |=  FE_HAS_CARRIER; // FIXME: not sure if this is right
+	val = s5h1420_readreg(state, 0x36);
+	if (val & 0x01)
+		status |=  FE_HAS_VITERBI;
+	if (val & 0x20)
+		status |=  FE_HAS_SYNC;
+	if (status == (FE_HAS_SIGNAL|FE_HAS_CARRIER|FE_HAS_VITERBI|FE_HAS_SYNC))
+		status |=  FE_HAS_LOCK;
+
+	return status;
+}
+
+static int s5h1420_read_status(struct dvb_frontend* fe, fe_status_t* status)
+{
+	struct s5h1420_state* state = fe->demodulator_priv;
+	u8 val;
+
+	if (status == NULL)
+		return -EINVAL;
+
+	/* determine lock state */
+	*status = s5h1420_get_status_bits(state);
+
+	/* fix for FEC 5/6 inversion issue - if it doesn't quite lock, invert the inversion,
+	wait a bit and check again */
+	if (*status == (FE_HAS_SIGNAL|FE_HAS_CARRIER|FE_HAS_VITERBI)) {
+		val = s5h1420_readreg(state, 0x32);
+		if ((val & 0x07) == 0x03) {
+			if (val & 0x08)
+				s5h1420_writereg(state, 0x31, 0x13);
+			else
+				s5h1420_writereg(state, 0x31, 0x1b);
+
+			/* wait a bit then update lock status */
+			mdelay(200);
+			*status = s5h1420_get_status_bits(state);
+		}
+	}
+
+	/* perform post lock setup */
+	if ((*status & FE_HAS_LOCK) && (!state->postlocked)) {
+
+		/* calculate the data rate */
+		u32 tmp = s5h1420_getsymbolrate(state);
+		switch(s5h1420_readreg(state, 0x32) & 0x07) {
+		case 0:
+			tmp = (tmp * 2 * 1) / 2;
+			break;
+
+		case 1:
+			tmp = (tmp * 2 * 2) / 3;
+			break;
+
+		case 2:
+			tmp = (tmp * 2 * 3) / 4;
+			break;
+
+		case 3:
+			tmp = (tmp * 2 * 5) / 6;
+			break;
+
+		case 4:
+			tmp = (tmp * 2 * 6) / 7;
+			break;
+
+		case 5:
+			tmp = (tmp * 2 * 7) / 8;
+			break;
+		}
+		tmp = state->fclk / tmp;
+
+		/* set the MPEG_CLK_INTL for the calculated data rate */
+		if (tmp < 4)
+			val = 0x00;
+		else if (tmp < 8)
+			val = 0x01;
+		else if (tmp < 12)
+			val = 0x02;
+		else if (tmp < 16)
+			val = 0x03;
+		else if (tmp < 24)
+			val = 0x04;
+		else if (tmp < 32)
+			val = 0x05;
+		else
+			val = 0x06;
+		s5h1420_writereg(state, 0x22, val);
+
+		/* DC freeze */
+		s5h1420_writereg(state, 0x1f, s5h1420_readreg(state, 0x1f) | 0x01);
+
+		/* kicker disable + remove DC offset */
+		s5h1420_writereg(state, 0x05, s5h1420_readreg(state, 0x05) & 0x6f);
+
+		/* post-lock processing has been done! */
+		state->postlocked = 1;
+	}
+
+	return 0;
+}
+
+static int s5h1420_read_ber(struct dvb_frontend* fe, u32* ber)
+{
+	struct s5h1420_state* state = fe->demodulator_priv;
+
+	s5h1420_writereg(state, 0x46, 0x1d);
+	mdelay(25);
+	return (s5h1420_readreg(state, 0x48) << 8) | s5h1420_readreg(state, 0x47);
+}
+
+static int s5h1420_read_signal_strength(struct dvb_frontend* fe, u16* strength)
+{
+	struct s5h1420_state* state = fe->demodulator_priv;
+
+	u8 val = 0xff - s5h1420_readreg(state, 0x15);
+
+	return (int) ((val << 8) | val);
+}
+
+static int s5h1420_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
+{
+	struct s5h1420_state* state = fe->demodulator_priv;
+
+	s5h1420_writereg(state, 0x46, 0x1f);
+	mdelay(25);
+	return (s5h1420_readreg(state, 0x48) << 8) | s5h1420_readreg(state, 0x47);
+}
+
+static void s5h1420_reset(struct s5h1420_state* state)
+{
+	s5h1420_writereg (state, 0x01, 0x08);
+	s5h1420_writereg (state, 0x01, 0x00);
+	udelay(10);
+}
+
+static void s5h1420_setsymbolrate(struct s5h1420_state* state, struct dvb_frontend_parameters *p)
+{
+	u64 val;
+
+	val = (p->u.qpsk.symbol_rate / 1000) * (1<<24);
+	if (p->u.qpsk.symbol_rate <= 21000000) {
+		val *= 2;
+	}
+	do_div(val, (state->fclk / 1000));
+
+	s5h1420_writereg(state, 0x09, s5h1420_readreg(state, 0x09) & 0x7f);
+	s5h1420_writereg(state, 0x11, val >> 16);
+	s5h1420_writereg(state, 0x12, val >> 8);
+	s5h1420_writereg(state, 0x13, val & 0xff);
+	s5h1420_writereg(state, 0x09, s5h1420_readreg(state, 0x09) | 0x80);
+}
+
+static u32 s5h1420_getsymbolrate(struct s5h1420_state* state)
+{
+	u64 val;
+	int sampling = 2;
+
+	if (s5h1420_readreg(state, 0x05) & 0x2)
+		sampling = 1;
+
+	s5h1420_writereg(state, 0x06, s5h1420_readreg(state, 0x06) | 0x08);
+	val  = s5h1420_readreg(state, 0x11) << 16;
+	val |= s5h1420_readreg(state, 0x12) << 8;
+	val |= s5h1420_readreg(state, 0x13);
+	s5h1420_writereg(state, 0x06, s5h1420_readreg(state, 0x06) & 0xf7);
+
+	val *= (state->fclk / 1000);
+	do_div(val, ((1<<24) * sampling));
+
+	return (u32) (val * 1000);
+}
+
+static void s5h1420_setfreqoffset(struct s5h1420_state* state, int freqoffset)
+{
+	int val;
+
+	/* remember freqoffset is in kHz, but the chip wants the offset in Hz, so
+	 * divide fclk by 1000000 to get the correct value. */
+	val = -(int) ((freqoffset * (1<<24)) / (state->fclk / 1000000));
+
+	s5h1420_writereg(state, 0x09, s5h1420_readreg(state, 0x09) & 0xbf);
+	s5h1420_writereg(state, 0x0e, val >> 16);
+	s5h1420_writereg(state, 0x0f, val >> 8);
+	s5h1420_writereg(state, 0x10, val & 0xff);
+	s5h1420_writereg(state, 0x09, s5h1420_readreg(state, 0x09) | 0x40);
+}
+
+static int s5h1420_getfreqoffset(struct s5h1420_state* state)
+{
+	int val;
+
+	s5h1420_writereg(state, 0x06, s5h1420_readreg(state, 0x06) | 0x08);
+	val  = s5h1420_readreg(state, 0x0e) << 16;
+	val |= s5h1420_readreg(state, 0x0f) << 8;
+	val |= s5h1420_readreg(state, 0x10);
+	s5h1420_writereg(state, 0x06, s5h1420_readreg(state, 0x06) & 0xf7);
+
+	if (val & 0x800000)
+		val |= 0xff000000;
+
+	/* remember freqoffset is in kHz, but the chip wants the offset in Hz, so
+	 * divide fclk by 1000000 to get the correct value. */
+	val = - ((val * (state->fclk/1000000)) / (1<<24));
+
+	return val;
+}
+
+static void s5h1420_setfec(struct s5h1420_state* state, struct dvb_frontend_parameters *p)
+{
+	if ((p->u.qpsk.fec_inner == FEC_AUTO) || (p->inversion == INVERSION_AUTO)) {
+		s5h1420_writereg(state, 0x31, 0x00);
+		s5h1420_writereg(state, 0x30, 0x3f);
+	} else {
+		switch(p->u.qpsk.fec_inner) {
+		case FEC_1_2:
+			s5h1420_writereg(state, 0x31, 0x10);
+			s5h1420_writereg(state, 0x30, 0x01);
+			break;
+
+		case FEC_2_3:
+			s5h1420_writereg(state, 0x31, 0x11);
+			s5h1420_writereg(state, 0x30, 0x02);
+			break;
+
+		case FEC_3_4:
+			s5h1420_writereg(state, 0x31, 0x12);
+			s5h1420_writereg(state, 0x30, 0x04);
+			break;
+
+		case FEC_5_6:
+			s5h1420_writereg(state, 0x31, 0x13);
+			s5h1420_writereg(state, 0x30, 0x08);
+			break;
+
+		case FEC_6_7:
+			s5h1420_writereg(state, 0x31, 0x14);
+			s5h1420_writereg(state, 0x30, 0x10);
+			break;
+
+		case FEC_7_8:
+			s5h1420_writereg(state, 0x31, 0x15);
+			s5h1420_writereg(state, 0x30, 0x20);
+			break;
+
+		default:
+			return;
+		}
+	}
+}
+
+static fe_code_rate_t s5h1420_getfec(struct s5h1420_state* state)
+{
+	switch(s5h1420_readreg(state, 0x32) & 0x07) {
+	case 0:
+		return FEC_1_2;
+
+	case 1:
+		return FEC_2_3;
+
+	case 2:
+		return FEC_3_4;
+
+	case 3:
+		return FEC_5_6;
+
+	case 4:
+		return FEC_6_7;
+
+	case 5:
+		return FEC_7_8;
+	}
+
+	return FEC_NONE;
+}
+
+static void s5h1420_setinversion(struct s5h1420_state* state, struct dvb_frontend_parameters *p)
+{
+	if ((p->u.qpsk.fec_inner == FEC_AUTO) || (p->inversion == INVERSION_AUTO)) {
+		s5h1420_writereg(state, 0x31, 0x00);
+		s5h1420_writereg(state, 0x30, 0x3f);
+	} else {
+		u8 tmp = s5h1420_readreg(state, 0x31) & 0xf7;
+			tmp |= 0x10;
+
+		if (p->inversion == INVERSION_ON)
+			tmp |= 0x80;
+
+		s5h1420_writereg(state, 0x31, tmp);
+	}
+}
+
+static fe_spectral_inversion_t s5h1420_getinversion(struct s5h1420_state* state)
+{
+	if (s5h1420_readreg(state, 0x32) & 0x08)
+		return INVERSION_ON;
+
+	return INVERSION_OFF;
+}
+
+static int s5h1420_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
+{
+	struct s5h1420_state* state = fe->demodulator_priv;
+	u32 frequency_delta;
+	struct dvb_frontend_tune_settings fesettings;
+
+	/* check if we should do a fast-tune */
+	memcpy(&fesettings.parameters, p, sizeof(struct dvb_frontend_parameters));
+	s5h1420_get_tune_settings(fe, &fesettings);
+	frequency_delta = p->frequency - state->tunedfreq;
+	if ((frequency_delta > -fesettings.max_drift) && (frequency_delta < fesettings.max_drift) &&
+	    (frequency_delta != 0) &&
+	    (state->fec_inner == p->u.qpsk.fec_inner) &&
+	    (state->symbol_rate == p->u.qpsk.symbol_rate)) {
+
+		s5h1420_setfreqoffset(state, frequency_delta);
+		return 0;
+	}
+
+	/* first of all, software reset */
+	s5h1420_reset(state);
+
+	/* set tuner PLL */
+	if (state->config->pll_set) {
+		s5h1420_writereg (state, 0x02, s5h1420_readreg(state,0x02) | 1);
+		state->config->pll_set(fe, p, &state->tunedfreq);
+		s5h1420_writereg (state, 0x02, s5h1420_readreg(state,0x02) & 0xfe);
+	}
+
+	/* set s5h1420 fclk PLL according to desired symbol rate */
+	if (p->u.qpsk.symbol_rate > 28000000) {
+		state->fclk = 88000000;
+		s5h1420_writereg(state, 0x03, 0x50);
+		s5h1420_writereg(state, 0x04, 0x40);
+		s5h1420_writereg(state, 0x05, 0xae);
+	} else if (p->u.qpsk.symbol_rate > 21000000) {
+		state->fclk = 59000000;
+		s5h1420_writereg(state, 0x03, 0x33);
+		s5h1420_writereg(state, 0x04, 0x40);
+		s5h1420_writereg(state, 0x05, 0xae);
+	} else {
+		state->fclk = 88000000;
+		s5h1420_writereg(state, 0x03, 0x50);
+		s5h1420_writereg(state, 0x04, 0x40);
+		s5h1420_writereg(state, 0x05, 0xac);
+	}
+
+	/* set misc registers */
+	s5h1420_writereg(state, 0x02, 0x00);
+	s5h1420_writereg(state, 0x07, 0xb0);
+	s5h1420_writereg(state, 0x0a, 0x67);
+	s5h1420_writereg(state, 0x0b, 0x78);
+	s5h1420_writereg(state, 0x0c, 0x48);
+	s5h1420_writereg(state, 0x0d, 0x6b);
+	s5h1420_writereg(state, 0x2e, 0x8e);
+	s5h1420_writereg(state, 0x35, 0x33);
+	s5h1420_writereg(state, 0x38, 0x01);
+	s5h1420_writereg(state, 0x39, 0x7d);
+	s5h1420_writereg(state, 0x3a, (state->fclk + (TONE_FREQ * 32) - 1) / (TONE_FREQ * 32));
+	s5h1420_writereg(state, 0x3c, 0x00);
+	s5h1420_writereg(state, 0x45, 0x61);
+	s5h1420_writereg(state, 0x46, 0x1d);
+
+	/* start QPSK */
+	s5h1420_writereg(state, 0x05, s5h1420_readreg(state, 0x05) | 1);
+
+	/* set the frequency offset to adjust for PLL inaccuracy */
+	s5h1420_setfreqoffset(state, p->frequency - state->tunedfreq);
+
+	/* set the reset of the parameters */
+	s5h1420_setsymbolrate(state, p);
+	s5h1420_setinversion(state, p);
+	s5h1420_setfec(state, p);
+
+	state->fec_inner = p->u.qpsk.fec_inner;
+	state->symbol_rate = p->u.qpsk.symbol_rate;
+	state->postlocked = 0;
+	return 0;
+}
+
+static int s5h1420_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
+{
+	struct s5h1420_state* state = fe->demodulator_priv;
+
+	p->frequency = state->tunedfreq + s5h1420_getfreqoffset(state);
+	p->inversion = s5h1420_getinversion(state);
+	p->u.qpsk.symbol_rate = s5h1420_getsymbolrate(state);
+	p->u.qpsk.fec_inner = s5h1420_getfec(state);
+
+	return 0;
+}
+
+static int s5h1420_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
+{
+	if (fesettings->parameters.u.qpsk.symbol_rate > 20000000) {
+		fesettings->min_delay_ms = 50;
+		fesettings->step_size = 2000;
+		fesettings->max_drift = 8000;
+	} else if (fesettings->parameters.u.qpsk.symbol_rate > 12000000) {
+		fesettings->min_delay_ms = 100;
+		fesettings->step_size = 1500;
+		fesettings->max_drift = 9000;
+	} else if (fesettings->parameters.u.qpsk.symbol_rate > 8000000) {
+		fesettings->min_delay_ms = 100;
+		fesettings->step_size = 1000;
+		fesettings->max_drift = 8000;
+	} else if (fesettings->parameters.u.qpsk.symbol_rate > 4000000) {
+		fesettings->min_delay_ms = 100;
+		fesettings->step_size = 500;
+		fesettings->max_drift = 7000;
+	} else if (fesettings->parameters.u.qpsk.symbol_rate > 2000000) {
+		fesettings->min_delay_ms = 200;
+		fesettings->step_size = (fesettings->parameters.u.qpsk.symbol_rate / 8000);
+		fesettings->max_drift = 14 * fesettings->step_size;
+	} else {
+		fesettings->min_delay_ms = 200;
+		fesettings->step_size = (fesettings->parameters.u.qpsk.symbol_rate / 8000);
+		fesettings->max_drift = 18 * fesettings->step_size;
+	}
+
+	return 0;
+}
+
+static int s5h1420_init (struct dvb_frontend* fe)
+{
+	struct s5h1420_state* state = fe->demodulator_priv;
+
+	/* disable power down and do reset */
+	s5h1420_writereg(state, 0x02, 0x10);
+	msleep(10);
+	s5h1420_reset(state);
+
+	/* init PLL */
+	if (state->config->pll_init) {
+		s5h1420_writereg (state, 0x02, s5h1420_readreg(state,0x02) | 1);
+		state->config->pll_init(fe);
+		s5h1420_writereg (state, 0x02, s5h1420_readreg(state,0x02) & 0xfe);
+	}
+
+	return 0;
+}
+
+static int s5h1420_sleep(struct dvb_frontend* fe)
+{
+	struct s5h1420_state* state = fe->demodulator_priv;
+
+	return s5h1420_writereg(state, 0x02, 0x12);
+}
+
+static void s5h1420_release(struct dvb_frontend* fe)
+{
+	struct s5h1420_state* state = fe->demodulator_priv;
+	kfree(state);
+}
+
+static struct dvb_frontend_ops s5h1420_ops;
+
+struct dvb_frontend* s5h1420_attach(const struct s5h1420_config* config, struct i2c_adapter* i2c)
+{
+	struct s5h1420_state* state = NULL;
+	u8 identity;
+
+	/* allocate memory for the internal state */
+	state = kmalloc(sizeof(struct s5h1420_state), GFP_KERNEL);
+	if (state == NULL)
+		goto error;
+
+	/* setup the state */
+	state->config = config;
+	state->i2c = i2c;
+	memcpy(&state->ops, &s5h1420_ops, sizeof(struct dvb_frontend_ops));
+	state->postlocked = 0;
+	state->fclk = 88000000;
+	state->tunedfreq = 0;
+	state->fec_inner = FEC_NONE;
+	state->symbol_rate = 0;
+
+	/* check if the demod is there + identify it */
+	identity = s5h1420_readreg(state, 0x00);
+	if (identity != 0x03)
+		goto error;
+
+	/* create dvb_frontend */
+	state->frontend.ops = &state->ops;
+	state->frontend.demodulator_priv = state;
+	return &state->frontend;
+
+error:
+	kfree(state);
+	return NULL;
+}
+
+static struct dvb_frontend_ops s5h1420_ops = {
+
+	.info = {
+		.name     = "Samsung S5H1420 DVB-S",
+		.type     = FE_QPSK,
+		.frequency_min    = 950000,
+		.frequency_max    = 2150000,
+		.frequency_stepsize = 125,     /* kHz for QPSK frontends */
+		.frequency_tolerance  = 29500,
+		.symbol_rate_min  = 1000000,
+		.symbol_rate_max  = 45000000,
+		/*  .symbol_rate_tolerance  = ???,*/
+		.caps = FE_CAN_INVERSION_AUTO |
+		FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+		FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+		FE_CAN_QPSK
+	},
+
+	.release = s5h1420_release,
+
+	.init = s5h1420_init,
+	.sleep = s5h1420_sleep,
+
+	.set_frontend = s5h1420_set_frontend,
+	.get_frontend = s5h1420_get_frontend,
+	.get_tune_settings = s5h1420_get_tune_settings,
+
+	.read_status = s5h1420_read_status,
+	.read_ber = s5h1420_read_ber,
+	.read_signal_strength = s5h1420_read_signal_strength,
+	.read_ucblocks = s5h1420_read_ucblocks,
+
+	.diseqc_send_master_cmd = s5h1420_send_master_cmd,
+	.diseqc_recv_slave_reply = s5h1420_recv_slave_reply,
+	.diseqc_send_burst = s5h1420_send_burst,
+	.set_tone = s5h1420_set_tone,
+	.set_voltage = s5h1420_set_voltage,
+};
+
+module_param(debug, int, 0644);
+
+MODULE_DESCRIPTION("Samsung S5H1420 DVB-S Demodulator driver");
+MODULE_AUTHOR("Andrew de Quincey");
+MODULE_LICENSE("GPL");
+
+EXPORT_SYMBOL(s5h1420_attach);
diff --git a/drivers/media/dvb/frontends/s5h1420.h b/drivers/media/dvb/frontends/s5h1420.h
new file mode 100644
--- /dev/null
+++ b/drivers/media/dvb/frontends/s5h1420.h
@@ -0,0 +1,41 @@
+/*
+    Driver for S5H1420 QPSK Demodulators
+
+    Copyright (C) 2005 Andrew de Quincey <adq_dvb@lidskialf.net>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This 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 S5H1420_H
+#define S5H1420_H
+
+#include <linux/dvb/frontend.h>
+
+struct s5h1420_config
+{
+	/* the demodulator's i2c address */
+	u8 demod_address;
+
+	/* PLL maintenance */
+	int (*pll_init)(struct dvb_frontend* fe);
+	int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u32* freqout);
+};
+
+extern struct dvb_frontend* s5h1420_attach(const struct s5h1420_config* config,
+             struct i2c_adapter* i2c);
+
+#endif // S5H1420_H
diff --git a/drivers/media/dvb/frontends/stv0297.c b/drivers/media/dvb/frontends/stv0297.c
--- a/drivers/media/dvb/frontends/stv0297.c
+++ b/drivers/media/dvb/frontends/stv0297.c
@@ -617,7 +617,7 @@ static int stv0297_set_frontend(struct d
 
 	/* wait for WGAGC lock */
 	starttime = jiffies;
-	timeout = jiffies + (200 * HZ) / 1000;
+	timeout = jiffies + msecs_to_jiffies(2000);
 	while (time_before(jiffies, timeout)) {
 		msleep(10);
 		if (stv0297_readreg(state, 0x43) & 0x08)
@@ -629,7 +629,7 @@ static int stv0297_set_frontend(struct d
 	msleep(20);
 
 	/* wait for equaliser partial convergence */
-	timeout = jiffies + (50 * HZ) / 1000;
+	timeout = jiffies + msecs_to_jiffies(500);
 	while (time_before(jiffies, timeout)) {
 		msleep(10);
 
@@ -642,7 +642,7 @@ static int stv0297_set_frontend(struct d
 	}
 
 	/* wait for equaliser full convergence */
-	timeout = jiffies + (delay * HZ) / 1000;
+	timeout = jiffies + msecs_to_jiffies(delay);
 	while (time_before(jiffies, timeout)) {
 		msleep(10);
 
@@ -659,7 +659,7 @@ static int stv0297_set_frontend(struct d
 	stv0297_writereg_mask(state, 0x88, 8, 0);
 
 	/* wait for main lock */
-	timeout = jiffies + (20 * HZ) / 1000;
+	timeout = jiffies + msecs_to_jiffies(20);
 	while (time_before(jiffies, timeout)) {
 		msleep(10);
 
diff --git a/drivers/media/dvb/frontends/tda1004x.c b/drivers/media/dvb/frontends/tda1004x.c
--- a/drivers/media/dvb/frontends/tda1004x.c
+++ b/drivers/media/dvb/frontends/tda1004x.c
@@ -49,10 +49,8 @@ struct tda1004x_state {
 	/* private demod data */
 	u8 initialised;
 	enum tda1004x_demod demod_type;
-	u8 fw_version;
 };
 
-
 static int debug;
 #define dprintk(args...) \
 	do { \
@@ -122,6 +120,8 @@ static int debug;
 #define TDA10046H_GPIO_OUT_SEL	 0x41
 #define TDA10046H_GPIO_SELECT	 0x42
 #define TDA10046H_AGC_CONF	 0x43
+#define TDA10046H_AGC_THR	 0x44
+#define TDA10046H_AGC_RENORM	 0x45
 #define TDA10046H_AGC_GAINS	 0x46
 #define TDA10046H_AGC_TUN_MIN	 0x47
 #define TDA10046H_AGC_TUN_MAX	 0x48
@@ -274,14 +274,26 @@ static int tda10046h_set_bandwidth(struc
 	switch (bandwidth) {
 	case BANDWIDTH_6_MHZ:
 		tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_6mhz, sizeof(bandwidth_6mhz));
+		if (state->config->if_freq == TDA10046_FREQ_045) {
+			tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x09);
+			tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x4f);
+		}
 		break;
 
 	case BANDWIDTH_7_MHZ:
 		tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_7mhz, sizeof(bandwidth_7mhz));
+		if (state->config->if_freq == TDA10046_FREQ_045) {
+			tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0a);
+			tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x79);
+		}
 		break;
 
 	case BANDWIDTH_8_MHZ:
 		tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_8mhz, sizeof(bandwidth_8mhz));
+		if (state->config->if_freq == TDA10046_FREQ_045) {
+			tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0b);
+			tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0xa3);
+		}
 		break;
 
 	default:
@@ -315,20 +327,35 @@ static int tda1004x_do_upload(struct tda
 		memcpy(buf + 1, mem + pos, tx_size);
 		fw_msg.len = tx_size + 1;
 		if (i2c_transfer(state->i2c, &fw_msg, 1) != 1) {
-			printk("tda1004x: Error during firmware upload\n");
+			printk(KERN_ERR "tda1004x: Error during firmware upload\n");
 			return -EIO;
 		}
 		pos += tx_size;
 
 		dprintk("%s: fw_pos=0x%x\n", __FUNCTION__, pos);
 	}
+	// give the DSP a chance to settle 03/10/05 Hac
+	msleep(100);
 
 	return 0;
 }
 
-static int tda1004x_check_upload_ok(struct tda1004x_state *state, u8 dspVersion)
+static int tda1004x_check_upload_ok(struct tda1004x_state *state)
 {
 	u8 data1, data2;
+	unsigned long timeout;
+
+	if (state->demod_type == TDA1004X_DEMOD_TDA10046) {
+		timeout = jiffies + 2 * HZ;
+		while(!(tda1004x_read_byte(state, TDA1004X_STATUS_CD) & 0x20)) {
+			if (time_after(jiffies, timeout)) {
+				printk(KERN_ERR "tda1004x: timeout waiting for DSP ready\n");
+				break;
+			}
+			msleep(1);
+		}
+	} else
+		msleep(100);
 
 	// check upload was OK
 	tda1004x_write_mask(state, TDA1004X_CONFC4, 0x10, 0); // we want to read from the DSP
@@ -336,9 +363,11 @@ static int tda1004x_check_upload_ok(stru
 
 	data1 = tda1004x_read_byte(state, TDA1004X_DSP_DATA1);
 	data2 = tda1004x_read_byte(state, TDA1004X_DSP_DATA2);
-	if ((data1 != 0x67) || (data2 != dspVersion))
+	if (data1 != 0x67 || data2 < 0x20 || data2 > 0x2e) {
+		printk(KERN_INFO "tda1004x: found firmware revision %x -- invalid\n", data2);
 		return -EIO;
-
+	}
+	printk(KERN_INFO "tda1004x: found firmware revision %x -- ok\n", data2);
 	return 0;
 }
 
@@ -349,14 +378,14 @@ static int tda10045_fwupload(struct dvb_
 	const struct firmware *fw;
 
 	/* don't re-upload unless necessary */
-	if (tda1004x_check_upload_ok(state, 0x2c) == 0)
+	if (tda1004x_check_upload_ok(state) == 0)
 		return 0;
 
 	/* request the firmware, this will block until someone uploads it */
-	printk("tda1004x: waiting for firmware upload (%s)...\n", TDA10045_DEFAULT_FIRMWARE);
+	printk(KERN_INFO "tda1004x: waiting for firmware upload (%s)...\n", TDA10045_DEFAULT_FIRMWARE);
 	ret = state->config->request_firmware(fe, &fw, TDA10045_DEFAULT_FIRMWARE);
 	if (ret) {
-		printk("tda1004x: no firmware upload (timeout or file not found?)\n");
+		printk(KERN_ERR "tda1004x: no firmware upload (timeout or file not found?)\n");
 		return ret;
 	}
 
@@ -370,95 +399,93 @@ static int tda10045_fwupload(struct dvb_
 	tda10045h_set_bandwidth(state, BANDWIDTH_8_MHZ);
 
 	ret = tda1004x_do_upload(state, fw->data, fw->size, TDA10045H_FWPAGE, TDA10045H_CODE_IN);
+	release_firmware(fw);
 	if (ret)
 		return ret;
-	printk("tda1004x: firmware upload complete\n");
+	printk(KERN_INFO "tda1004x: firmware upload complete\n");
 
 	/* wait for DSP to initialise */
 	/* DSPREADY doesn't seem to work on the TDA10045H */
 	msleep(100);
 
-	return tda1004x_check_upload_ok(state, 0x2c);
+	return tda1004x_check_upload_ok(state);
 }
 
-static int tda10046_get_fw_version(struct tda1004x_state *state,
-				   const struct firmware *fw)
+static void tda10046_init_plls(struct dvb_frontend* fe)
 {
-	const unsigned char pattern[] = { 0x67, 0x00, 0x50, 0x62, 0x5e, 0x18, 0x67 };
-	unsigned int i;
+	struct tda1004x_state* state = fe->demodulator_priv;
 
-	/* area guessed from firmware v20, v21 and v25 */
-	for (i = 0x660; i < 0x700; i++) {
-		if (!memcmp(&fw->data[i], pattern, sizeof(pattern))) {
-			state->fw_version = fw->data[i + sizeof(pattern)];
-			printk(KERN_INFO "tda1004x: using firmware v%02x\n",
-					state->fw_version);
-			return 0;
-		}
+	tda1004x_write_byteI(state, TDA10046H_CONFPLL1, 0xf0);
+	tda1004x_write_byteI(state, TDA10046H_CONFPLL2, 10); // PLL M = 10
+	if (state->config->xtal_freq == TDA10046_XTAL_4M ) {
+		dprintk("%s: setting up PLLs for a 4 MHz Xtal\n", __FUNCTION__);
+		tda1004x_write_byteI(state, TDA10046H_CONFPLL3, 0); // PLL P = N = 0
+	} else {
+		dprintk("%s: setting up PLLs for a 16 MHz Xtal\n", __FUNCTION__);
+		tda1004x_write_byteI(state, TDA10046H_CONFPLL3, 3); // PLL P = 0, N = 3
 	}
-
-	return -EINVAL;
+	tda1004x_write_byteI(state, TDA10046H_FREQ_OFFSET, 99);
+	switch (state->config->if_freq) {
+	case TDA10046_FREQ_3617:
+		tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0xd4);
+		tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x2c);
+		break;
+	case TDA10046_FREQ_3613:
+		tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0xd4);
+		tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x13);
+		break;
+	case TDA10046_FREQ_045:
+		tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0b);
+		tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0xa3);
+		break;
+	case TDA10046_FREQ_052:
+		tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0c);
+		tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x06);
+		break;
+	}
+	tda10046h_set_bandwidth(state, BANDWIDTH_8_MHZ); // default bandwidth 8 MHz
 }
 
 static int tda10046_fwupload(struct dvb_frontend* fe)
 {
 	struct tda1004x_state* state = fe->demodulator_priv;
-	unsigned long timeout;
 	int ret;
 	const struct firmware *fw;
 
 	/* reset + wake up chip */
-	tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 0);
+	tda1004x_write_byteI(state, TDA1004X_CONFC4, 0);
 	tda1004x_write_mask(state, TDA10046H_CONF_TRISTATE1, 1, 0);
-	msleep(100);
+	/* let the clocks recover from sleep */
+	msleep(5);
 
 	/* don't re-upload unless necessary */
-	if (tda1004x_check_upload_ok(state, state->fw_version) == 0)
+	if (tda1004x_check_upload_ok(state) == 0)
 		return 0;
 
-	/* request the firmware, this will block until someone uploads it */
-	printk("tda1004x: waiting for firmware upload (%s)...\n", TDA10046_DEFAULT_FIRMWARE);
-	ret = state->config->request_firmware(fe, &fw, TDA10046_DEFAULT_FIRMWARE);
-	if (ret) {
-		printk("tda1004x: no firmware upload (timeout or file not found?)\n");
-		return ret;
-	}
-
-	if (fw->size < 24478) { /* size of firmware v20, which is the smallest of v20, v21 and v25 */
-		printk("tda1004x: firmware file seems to be too small (%d bytes)\n", fw->size);
-		return -EINVAL;
-	}
-
-	ret = tda10046_get_fw_version(state, fw);
-	if (ret < 0) {
-		printk("tda1004x: unable to find firmware version\n");
-		return ret;
-	}
-
 	/* set parameters */
-	tda1004x_write_byteI(state, TDA10046H_CONFPLL2, 10);
-	tda1004x_write_byteI(state, TDA10046H_CONFPLL3, state->config->n_i2c);
-	tda1004x_write_byteI(state, TDA10046H_FREQ_OFFSET, 99);
-	tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0xd4);
-	tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x2c);
-	tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 8); // going to boot from HOST
+	tda10046_init_plls(fe);
 
-	ret = tda1004x_do_upload(state, fw->data, fw->size, TDA10046H_CODE_CPT, TDA10046H_CODE_IN);
-	if (ret)
-		return ret;
-	printk("tda1004x: firmware upload complete\n");
-
-	/* wait for DSP to initialise */
-	timeout = jiffies + HZ;
-	while (!(tda1004x_read_byte(state, TDA1004X_STATUS_CD) & 0x20)) {
-		if (time_after(jiffies, timeout)) {
-			printk("tda1004x: DSP failed to initialised.\n");
-			return -EIO;
+	if (state->config->request_firmware != NULL) {
+		/* request the firmware, this will block until someone uploads it */
+		printk(KERN_INFO "tda1004x: waiting for firmware upload...\n");
+		ret = state->config->request_firmware(fe, &fw, TDA10046_DEFAULT_FIRMWARE);
+		if (ret) {
+			printk(KERN_ERR "tda1004x: no firmware upload (timeout or file not found?)\n");
+   	   		return ret;
 		}
-		msleep(1);
+		tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 8); // going to boot from HOST
+		ret = tda1004x_do_upload(state, fw->data, fw->size, TDA10046H_CODE_CPT, TDA10046H_CODE_IN);
+		release_firmware(fw);
+		if (ret)
+			return ret;
+	} else {
+		/* boot from firmware eeprom */
+		/* Hac Note: we might need to do some GPIO Magic here */
+		printk(KERN_INFO "tda1004x: booting from eeprom\n");
+		tda1004x_write_mask(state, TDA1004X_CONFC4, 4, 4);
+		msleep(300);
 	}
-
-	return tda1004x_check_upload_ok(state, state->fw_version);
+	return tda1004x_check_upload_ok(state);
 }
 
 static int tda1004x_encode_fec(int fec)
@@ -560,12 +587,10 @@ static int tda10046_init(struct dvb_fron
 
 	if (tda10046_fwupload(fe)) {
 		printk("tda1004x: firmware upload failed\n");
-		return -EIO;
+			return -EIO;
 	}
 
-	tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 0); // wake up the chip
-
-	// Init the PLL
+	// Init the tuner PLL
 	if (state->config->pll_init) {
 		tda1004x_enable_tuner_i2c(state);
 		state->config->pll_init(fe);
@@ -574,32 +599,44 @@ static int tda10046_init(struct dvb_fron
 
 	// tda setup
 	tda1004x_write_mask(state, TDA1004X_CONFC4, 0x20, 0); // disable DSP watchdog timer
-	tda1004x_write_mask(state, TDA1004X_CONFC1, 0x40, 0x40);
-	tda1004x_write_mask(state, TDA1004X_AUTO, 8, 0); // select HP stream
-	tda1004x_write_mask(state, TDA1004X_CONFC1, 0x80, 0); // disable pulse killer
-	tda1004x_write_byteI(state, TDA10046H_CONFPLL2, 10); // PLL M = 10
-	tda1004x_write_byteI(state, TDA10046H_CONFPLL3, state->config->n_i2c); // PLL P = N = 0
-	tda1004x_write_byteI(state, TDA10046H_FREQ_OFFSET, 99); // FREQOFFS = 99
-	tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0xd4); // } PHY2 = -11221
-	tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x2c); // }
-	tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0); // AGC setup
-	tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0x60, 0x60); // set AGC polarities
+	tda1004x_write_byteI(state, TDA1004X_AUTO, 7); // select HP stream
+	tda1004x_write_byteI(state, TDA1004X_CONFC1, 8); // disable pulse killer
+
+	tda10046_init_plls(fe);
+	switch (state->config->agc_config) {
+	case TDA10046_AGC_DEFAULT:
+		tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x00); // AGC setup
+		tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x60); // set AGC polarities
+		break;
+	case TDA10046_AGC_IFO_AUTO_NEG:
+		tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x0a); // AGC setup
+		tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x60); // set AGC polarities
+		break;
+	case TDA10046_AGC_IFO_AUTO_POS:
+		tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x0a); // AGC setup
+		tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x00); // set AGC polarities
+		break;
+	case TDA10046_AGC_TDA827X:
+		tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x02);   // AGC setup
+		tda1004x_write_byteI(state, TDA10046H_AGC_THR, 0x70);    // AGC Threshold
+		tda1004x_write_byteI(state, TDA10046H_AGC_RENORM, 0x0E); // Gain Renormalize
+		tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x60); // set AGC polarities
+		break;
+	}
+	tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE1, 0x61); // Turn both AGC outputs on
 	tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MIN, 0);	  // }
 	tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MAX, 0xff); // } AGC min/max values
 	tda1004x_write_byteI(state, TDA10046H_AGC_IF_MIN, 0);	  // }
 	tda1004x_write_byteI(state, TDA10046H_AGC_IF_MAX, 0xff);  // }
-	tda1004x_write_mask(state, TDA10046H_CVBER_CTRL, 0x30, 0x10); // 10^6 VBER measurement bits
 	tda1004x_write_byteI(state, TDA10046H_AGC_GAINS, 1); // IF gain 2, TUN gain 1
-	tda1004x_write_mask(state, TDA1004X_AUTO, 0x80, 0); // crystal is 50ppm
+	tda1004x_write_byteI(state, TDA10046H_CVBER_CTRL, 0x1a); // 10^6 VBER measurement bits
 	tda1004x_write_byteI(state, TDA1004X_CONF_TS1, 7); // MPEG2 interface config
-	tda1004x_write_mask(state, TDA1004X_CONF_TS2, 0x31, 0); // MPEG2 interface config
-	tda1004x_write_mask(state, TDA10046H_CONF_TRISTATE1, 0x9e, 0); // disable AGC_TUN
+	tda1004x_write_byteI(state, TDA1004X_CONF_TS2, 0xc0); // MPEG2 interface config
+	tda1004x_write_mask(state, 0x3a, 0x80, state->config->invert_oclk << 7);
+
 	tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE2, 0xe1); // tristate setup
 	tda1004x_write_byteI(state, TDA10046H_GPIO_OUT_SEL, 0xcc); // GPIO output config
-	tda1004x_write_mask(state, TDA10046H_GPIO_SELECT, 8, 8); // GPIO select
-	tda10046h_set_bandwidth(state, BANDWIDTH_8_MHZ); // default bandwidth 8 MHz
-
-	tda1004x_write_mask(state, 0x3a, 0x80, state->config->invert_oclk << 7);
+	tda1004x_write_byteI(state, TDA10046H_GPIO_SELECT, 8); // GPIO select
 
 	state->initialised = 1;
 	return 0;
@@ -629,9 +666,6 @@ static int tda1004x_set_fe(struct dvb_fr
 	state->config->pll_set(fe, fe_params);
 	tda1004x_disable_tuner_i2c(state);
 
-	if (state->demod_type == TDA1004X_DEMOD_TDA10046)
-		tda1004x_write_mask(state, TDA10046H_AGC_CONF, 4, 4);
-
 	// Hardcoded to use auto as much as possible on the TDA10045 as it
 	// is very unreliable if AUTO mode is _not_ used.
 	if (state->demod_type == TDA1004X_DEMOD_TDA10045) {
@@ -1089,6 +1123,11 @@ static int tda1004x_sleep(struct dvb_fro
 		break;
 
 	case TDA1004X_DEMOD_TDA10046:
+		if (state->config->pll_sleep != NULL) {
+			tda1004x_enable_tuner_i2c(state);
+			state->config->pll_sleep(fe);
+			tda1004x_disable_tuner_i2c(state);
+		}
 		tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 1);
 		break;
 	}
@@ -1100,8 +1139,9 @@ static int tda1004x_sleep(struct dvb_fro
 static int tda1004x_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
 {
 	fesettings->min_delay_ms = 800;
-	fesettings->step_size = 166667;
-	fesettings->max_drift = 166667*2;
+	/* Drift compensation makes no sense for DVB-T */
+	fesettings->step_size = 0;
+	fesettings->max_drift = 0;
 	return 0;
 }
 
@@ -1216,7 +1256,6 @@ struct dvb_frontend* tda10046_attach(con
 	memcpy(&state->ops, &tda10046_ops, sizeof(struct dvb_frontend_ops));
 	state->initialised = 0;
 	state->demod_type = TDA1004X_DEMOD_TDA10046;
-	state->fw_version = 0x20;	/* dummy default value */
 
 	/* check if the demod is there */
 	if (tda1004x_read_byte(state, TDA1004X_CHIPID) != 0x46) {
diff --git a/drivers/media/dvb/frontends/tda1004x.h b/drivers/media/dvb/frontends/tda1004x.h
--- a/drivers/media/dvb/frontends/tda1004x.h
+++ b/drivers/media/dvb/frontends/tda1004x.h
@@ -26,6 +26,25 @@
 #include <linux/dvb/frontend.h>
 #include <linux/firmware.h>
 
+enum tda10046_xtal {
+	TDA10046_XTAL_4M,
+	TDA10046_XTAL_16M,
+};
+
+enum tda10046_agc {
+	TDA10046_AGC_DEFAULT,		/* original configuration */
+	TDA10046_AGC_IFO_AUTO_NEG,	/* IF AGC only, automatic, negtive */
+	TDA10046_AGC_IFO_AUTO_POS,	/* IF AGC only, automatic, positive */
+	TDA10046_AGC_TDA827X,	    /* IF AGC only, special setup for tda827x */
+};
+
+enum tda10046_if {
+	TDA10046_FREQ_3617,		/* original config, 36,166 MHZ */
+	TDA10046_FREQ_3613,		/* 36,13 MHZ */
+	TDA10046_FREQ_045,		/* low IF, 4.0, 4.5, or 5.0 MHZ */
+	TDA10046_FREQ_052,		/* low IF, 5.1667 MHZ for tda9889 */
+};
+
 struct tda1004x_config
 {
 	/* the demodulator's i2c address */
@@ -37,14 +56,22 @@ struct tda1004x_config
 	/* Does the OCLK signal need inverted? */
 	u8 invert_oclk;
 
-	/* value of N_I2C of the CONF_PLL3 register */
-	u8 n_i2c;
+	/* Xtal frequency, 4 or 16MHz*/
+	enum tda10046_xtal xtal_freq;
+
+	/* IF frequency */
+	enum tda10046_if if_freq;
+
+	/* AGC configuration */
+	enum tda10046_agc agc_config;
 
 	/* PLL maintenance */
 	int (*pll_init)(struct dvb_frontend* fe);
+	void (*pll_sleep)(struct dvb_frontend* fe);
 	int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
 
 	/* request firmware for device */
+	/* set this to NULL if the card has a firmware EEPROM */
 	int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name);
 };
 
diff --git a/drivers/media/dvb/frontends/tda80xx.c b/drivers/media/dvb/frontends/tda80xx.c
--- a/drivers/media/dvb/frontends/tda80xx.c
+++ b/drivers/media/dvb/frontends/tda80xx.c
@@ -27,7 +27,6 @@
 #include <linux/spinlock.h>
 #include <linux/threads.h>
 #include <linux/interrupt.h>
-#include <linux/irq.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/slab.h>
diff --git a/drivers/media/dvb/pluto2/Kconfig b/drivers/media/dvb/pluto2/Kconfig
new file mode 100644
--- /dev/null
+++ b/drivers/media/dvb/pluto2/Kconfig
@@ -0,0 +1,16 @@
+config DVB_PLUTO2
+	tristate "Pluto2 cards"
+	depends on DVB_CORE && PCI
+	select I2C
+	select I2C_ALGOBIT
+	select DVB_TDA1004X
+	help
+	  Support for PCI cards based on the Pluto2 FPGA like the Satelco
+	  Easywatch Mobile Terrestrial DVB-T Receiver.
+
+          Since these cards have no MPEG decoder onboard, they transmit
+	  only compressed MPEG data over the PCI bus, so you need
+	  an external software decoder to watch TV on your computer.
+
+	  Say Y or M if you own such a device and want to use it.
+
diff --git a/drivers/media/dvb/pluto2/Makefile b/drivers/media/dvb/pluto2/Makefile
new file mode 100644
--- /dev/null
+++ b/drivers/media/dvb/pluto2/Makefile
@@ -0,0 +1,3 @@
+obj-$(CONFIG_DVB_PLUTO2) = pluto2.o
+
+EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
diff --git a/drivers/media/dvb/pluto2/pluto2.c b/drivers/media/dvb/pluto2/pluto2.c
new file mode 100644
--- /dev/null
+++ b/drivers/media/dvb/pluto2/pluto2.c
@@ -0,0 +1,809 @@
+/*
+ * pluto2.c - Satelco Easywatch Mobile Terrestrial Receiver [DVB-T]
+ *
+ * Copyright (C) 2005 Andreas Oberritter <obi@linuxtv.org>
+ *
+ * based on pluto2.c 1.10 - http://instinct-wp8.no-ip.org/pluto/
+ * 	by Dany Salman <salmandany@yahoo.fr>
+ *	Copyright (c) 2004 TDF
+ *
+ * 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 <linux/i2c.h>
+#include <linux/i2c-algo-bit.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/dma-mapping.h>
+
+#include "demux.h"
+#include "dmxdev.h"
+#include "dvb_demux.h"
+#include "dvb_frontend.h"
+#include "dvb_net.h"
+#include "dvbdev.h"
+#include "tda1004x.h"
+
+#define DRIVER_NAME		"pluto2"
+
+#define REG_PIDn(n)		((n) << 2)	/* PID n pattern registers */
+#define REG_PCAR		0x0020		/* PC address register */
+#define REG_TSCR		0x0024		/* TS ctrl & status */
+#define REG_MISC		0x0028		/* miscellaneous */
+#define REG_MMAC		0x002c		/* MSB MAC address */
+#define REG_IMAC		0x0030		/* ISB MAC address */
+#define REG_LMAC		0x0034		/* LSB MAC address */
+#define REG_SPID		0x0038		/* SPI data */
+#define REG_SLCS		0x003c		/* serial links ctrl/status */
+
+#define PID0_NOFIL		(0x0001 << 16)
+#define PIDn_ENP		(0x0001 << 15)
+#define PID0_END		(0x0001 << 14)
+#define PID0_AFIL		(0x0001 << 13)
+#define PIDn_PID		(0x1fff <<  0)
+
+#define TSCR_NBPACKETS		(0x00ff << 24)
+#define TSCR_DEM		(0x0001 << 17)
+#define TSCR_DE			(0x0001 << 16)
+#define TSCR_RSTN		(0x0001 << 15)
+#define TSCR_MSKO		(0x0001 << 14)
+#define TSCR_MSKA		(0x0001 << 13)
+#define TSCR_MSKL		(0x0001 << 12)
+#define TSCR_OVR		(0x0001 << 11)
+#define TSCR_AFUL		(0x0001 << 10)
+#define TSCR_LOCK		(0x0001 <<  9)
+#define TSCR_IACK		(0x0001 <<  8)
+#define TSCR_ADEF		(0x007f <<  0)
+
+#define MISC_DVR		(0x0fff <<  4)
+#define MISC_ALED		(0x0001 <<  3)
+#define MISC_FRST		(0x0001 <<  2)
+#define MISC_LED1		(0x0001 <<  1)
+#define MISC_LED0		(0x0001 <<  0)
+
+#define SPID_SPIDR		(0x00ff <<  0)
+
+#define SLCS_SCL		(0x0001 <<  7)
+#define SLCS_SDA		(0x0001 <<  6)
+#define SLCS_CSN		(0x0001 <<  2)
+#define SLCS_OVR		(0x0001 <<  1)
+#define SLCS_SWC		(0x0001 <<  0)
+
+#define TS_DMA_PACKETS		(8)
+#define TS_DMA_BYTES		(188 * TS_DMA_PACKETS)
+
+#define I2C_ADDR_TDA10046	0x10
+#define I2C_ADDR_TUA6034	0xc2
+#define NHWFILTERS		8
+
+struct pluto {
+	/* pci */
+	struct pci_dev *pdev;
+	u8 __iomem *io_mem;
+
+	/* dvb */
+	struct dmx_frontend hw_frontend;
+	struct dmx_frontend mem_frontend;
+	struct dmxdev dmxdev;
+	struct dvb_adapter dvb_adapter;
+	struct dvb_demux demux;
+	struct dvb_frontend *fe;
+	struct dvb_net dvbnet;
+	unsigned int full_ts_users;
+	unsigned int users;
+
+	/* i2c */
+	struct i2c_algo_bit_data i2c_bit;
+	struct i2c_adapter i2c_adap;
+	unsigned int i2cbug;
+
+	/* irq */
+	unsigned int overflow;
+
+	/* dma */
+	dma_addr_t dma_addr;
+	u8 dma_buf[TS_DMA_BYTES];
+	u8 dummy[4096];
+};
+
+static inline struct pluto *feed_to_pluto(struct dvb_demux_feed *feed)
+{
+	return container_of(feed->demux, struct pluto, demux);
+}
+
+static inline struct pluto *frontend_to_pluto(struct dvb_frontend *fe)
+{
+	return container_of(fe->dvb, struct pluto, dvb_adapter);
+}
+
+static inline u32 pluto_readreg(struct pluto *pluto, u32 reg)
+{
+	return readl(&pluto->io_mem[reg]);
+}
+
+static inline void pluto_writereg(struct pluto *pluto, u32 reg, u32 val)
+{
+	writel(val, &pluto->io_mem[reg]);
+}
+
+static inline void pluto_rw(struct pluto *pluto, u32 reg, u32 mask, u32 bits)
+{
+	u32 val = readl(&pluto->io_mem[reg]);
+	val &= ~mask;
+	val |= bits;
+	writel(val, &pluto->io_mem[reg]);
+}
+
+static void pluto_setsda(void *data, int state)
+{
+	struct pluto *pluto = data;
+
+	if (state)
+		pluto_rw(pluto, REG_SLCS, SLCS_SDA, SLCS_SDA);
+	else
+		pluto_rw(pluto, REG_SLCS, SLCS_SDA, 0);
+}
+
+static void pluto_setscl(void *data, int state)
+{
+	struct pluto *pluto = data;
+
+	if (state)
+		pluto_rw(pluto, REG_SLCS, SLCS_SCL, SLCS_SCL);
+	else
+		pluto_rw(pluto, REG_SLCS, SLCS_SCL, 0);
+
+	/* try to detect i2c_inb() to workaround hardware bug:
+	 * reset SDA to high after SCL has been set to low */
+	if ((state) && (pluto->i2cbug == 0)) {
+		pluto->i2cbug = 1;
+	} else {
+		if ((!state) && (pluto->i2cbug == 1))
+			pluto_setsda(pluto, 1);
+		pluto->i2cbug = 0;
+	}
+}
+
+static int pluto_getsda(void *data)
+{
+	struct pluto *pluto = data;
+
+	return pluto_readreg(pluto, REG_SLCS) & SLCS_SDA;
+}
+
+static int pluto_getscl(void *data)
+{
+	struct pluto *pluto = data;
+
+	return pluto_readreg(pluto, REG_SLCS) & SLCS_SCL;
+}
+
+static void pluto_reset_frontend(struct pluto *pluto, int reenable)
+{
+	u32 val = pluto_readreg(pluto, REG_MISC);
+
+	if (val & MISC_FRST) {
+		val &= ~MISC_FRST;
+		pluto_writereg(pluto, REG_MISC, val);
+	}
+	if (reenable) {
+		val |= MISC_FRST;
+		pluto_writereg(pluto, REG_MISC, val);
+	}
+}
+
+static void pluto_reset_ts(struct pluto *pluto, int reenable)
+{
+	u32 val = pluto_readreg(pluto, REG_TSCR);
+
+	if (val & TSCR_RSTN) {
+		val &= ~TSCR_RSTN;
+		pluto_writereg(pluto, REG_TSCR, val);
+	}
+	if (reenable) {
+		val |= TSCR_RSTN;
+		pluto_writereg(pluto, REG_TSCR, val);
+	}
+}
+
+static void pluto_set_dma_addr(struct pluto *pluto)
+{
+	pluto_writereg(pluto, REG_PCAR, cpu_to_le32(pluto->dma_addr));
+}
+
+static int __devinit pluto_dma_map(struct pluto *pluto)
+{
+	pluto->dma_addr = pci_map_single(pluto->pdev, pluto->dma_buf,
+			TS_DMA_BYTES, PCI_DMA_FROMDEVICE);
+
+	return pci_dma_mapping_error(pluto->dma_addr);
+}
+
+static void pluto_dma_unmap(struct pluto *pluto)
+{
+	pci_unmap_single(pluto->pdev, pluto->dma_addr,
+			TS_DMA_BYTES, PCI_DMA_FROMDEVICE);
+}
+
+static int pluto_start_feed(struct dvb_demux_feed *f)
+{
+	struct pluto *pluto = feed_to_pluto(f);
+
+	/* enable PID filtering */
+	if (pluto->users++ == 0)
+		pluto_rw(pluto, REG_PIDn(0), PID0_AFIL | PID0_NOFIL, 0);
+
+	if ((f->pid < 0x2000) && (f->index < NHWFILTERS))
+		pluto_rw(pluto, REG_PIDn(f->index), PIDn_ENP | PIDn_PID, PIDn_ENP | f->pid);
+	else if (pluto->full_ts_users++ == 0)
+		pluto_rw(pluto, REG_PIDn(0), PID0_NOFIL, PID0_NOFIL);
+
+	return 0;
+}
+
+static int pluto_stop_feed(struct dvb_demux_feed *f)
+{
+	struct pluto *pluto = feed_to_pluto(f);
+
+	/* disable PID filtering */
+	if (--pluto->users == 0)
+		pluto_rw(pluto, REG_PIDn(0), PID0_AFIL, PID0_AFIL);
+
+	if ((f->pid < 0x2000) && (f->index < NHWFILTERS))
+		pluto_rw(pluto, REG_PIDn(f->index), PIDn_ENP | PIDn_PID, 0x1fff);
+	else if (--pluto->full_ts_users == 0)
+		pluto_rw(pluto, REG_PIDn(0), PID0_NOFIL, 0);
+
+	return 0;
+}
+
+static void pluto_dma_end(struct pluto *pluto, unsigned int nbpackets)
+{
+	/* synchronize the DMA transfer with the CPU
+	 * first so that we see updated contents. */
+	pci_dma_sync_single_for_cpu(pluto->pdev, pluto->dma_addr,
+			TS_DMA_BYTES, PCI_DMA_FROMDEVICE);
+
+	/* Workaround for broken hardware:
+	 * [1] On startup NBPACKETS seems to contain an uninitialized value,
+	 *     but no packets have been transfered.
+	 * [2] Sometimes (actually very often) NBPACKETS stays at zero
+	 *     although one packet has been transfered.
+	 */
+	if ((nbpackets == 0) || (nbpackets > TS_DMA_PACKETS)) {
+		unsigned int i = 0, valid;
+		while (pluto->dma_buf[i] == 0x47)
+			i += 188;
+		valid = i / 188;
+		if (nbpackets != valid) {
+			dev_err(&pluto->pdev->dev, "nbpackets=%u valid=%u\n",
+					nbpackets, valid);
+			nbpackets = valid;
+		}
+	}
+
+	dvb_dmx_swfilter_packets(&pluto->demux, pluto->dma_buf, nbpackets);
+
+	/* clear the dma buffer. this is needed to be able to identify
+	 * new valid ts packets above */
+	memset(pluto->dma_buf, 0, nbpackets * 188);
+
+	/* reset the dma address */
+	pluto_set_dma_addr(pluto);
+
+	/* sync the buffer and give it back to the card */
+	pci_dma_sync_single_for_device(pluto->pdev, pluto->dma_addr,
+			TS_DMA_BYTES, PCI_DMA_FROMDEVICE);
+}
+
+static irqreturn_t pluto_irq(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct pluto *pluto = dev_id;
+	u32 tscr;
+
+	/* check whether an interrupt occured on this device */
+	tscr = pluto_readreg(pluto, REG_TSCR);
+	if (!(tscr & (TSCR_DE | TSCR_OVR)))
+		return IRQ_NONE;
+
+	if (tscr == 0xffffffff) {
+		// FIXME: maybe recover somehow
+		dev_err(&pluto->pdev->dev, "card hung up :(\n");
+		return IRQ_HANDLED;
+	}
+
+	/* dma end interrupt */
+	if (tscr & TSCR_DE) {
+		pluto_dma_end(pluto, (tscr & TSCR_NBPACKETS) >> 24);
+		/* overflow interrupt */
+		if (tscr & TSCR_OVR)
+			pluto->overflow++;
+		if (pluto->overflow) {
+			dev_err(&pluto->pdev->dev, "overflow irq (%d)\n",
+					pluto->overflow);
+			pluto_reset_ts(pluto, 1);
+			pluto->overflow = 0;
+		}
+	} else if (tscr & TSCR_OVR) {
+		pluto->overflow++;
+	}
+
+	/* ACK the interrupt */
+	pluto_writereg(pluto, REG_TSCR, tscr | TSCR_IACK);
+
+	return IRQ_HANDLED;
+}
+
+static void __devinit pluto_enable_irqs(struct pluto *pluto)
+{
+	u32 val = pluto_readreg(pluto, REG_TSCR);
+
+	/* set the number of packets */
+	val &= ~TSCR_ADEF;
+	val |= TS_DMA_PACKETS / 2;
+	/* disable AFUL and LOCK interrupts */
+	val |= (TSCR_MSKA | TSCR_MSKL);
+	/* enable DMA and OVERFLOW interrupts */
+	val &= ~(TSCR_DEM | TSCR_MSKO);
+	/* clear pending interrupts */
+	val |= TSCR_IACK;
+
+	pluto_writereg(pluto, REG_TSCR, val);
+}
+
+static void pluto_disable_irqs(struct pluto *pluto)
+{
+	u32 val = pluto_readreg(pluto, REG_TSCR);
+
+	/* disable all interrupts */
+	val |= (TSCR_DEM | TSCR_MSKO | TSCR_MSKA | TSCR_MSKL);
+	/* clear pending interrupts */
+	val |= TSCR_IACK;
+
+	pluto_writereg(pluto, REG_TSCR, val);
+}
+
+static int __devinit pluto_hw_init(struct pluto *pluto)
+{
+	pluto_reset_frontend(pluto, 1);
+
+	/* set automatic LED control by FPGA */
+	pluto_rw(pluto, REG_MISC, MISC_ALED, MISC_ALED);
+
+	/* set data endianess */
+#ifdef __LITTLE_ENDIAN
+	pluto_rw(pluto, REG_PIDn(0), PID0_END, PID0_END);
+#else
+	pluto_rw(pluto, REG_PIDn(0), PID0_END, 0);
+#endif
+	/* map DMA and set address */
+	pluto_dma_map(pluto);
+	pluto_set_dma_addr(pluto);
+
+	/* enable interrupts */
+	pluto_enable_irqs(pluto);
+
+	/* reset TS logic */
+	pluto_reset_ts(pluto, 1);
+
+	return 0;
+}
+
+static void pluto_hw_exit(struct pluto *pluto)
+{
+	/* disable interrupts */
+	pluto_disable_irqs(pluto);
+
+	pluto_reset_ts(pluto, 0);
+
+	/* LED: disable automatic control, enable yellow, disable green */
+	pluto_rw(pluto, REG_MISC, MISC_ALED | MISC_LED1 | MISC_LED0, MISC_LED1);
+
+	/* unmap DMA */
+	pluto_dma_unmap(pluto);
+
+	pluto_reset_frontend(pluto, 0);
+}
+
+static inline u32 divide(u32 numerator, u32 denominator)
+{
+	if (denominator == 0)
+		return ~0;
+
+	return (numerator + denominator / 2) / denominator;
+}
+
+/* LG Innotek TDTE-E001P (Infineon TUA6034) */
+static int lg_tdtpe001p_pll_set(struct dvb_frontend *fe,
+				struct dvb_frontend_parameters *p)
+{
+	struct pluto *pluto = frontend_to_pluto(fe);
+	struct i2c_msg msg;
+	int ret;
+	u8 buf[4];
+	u32 div;
+
+	// Fref = 166.667 Hz
+	// Fref * 3 = 500.000 Hz
+	// IF = 36166667
+	// IF / Fref = 217
+	//div = divide(p->frequency + 36166667, 166667);
+	div = divide(p->frequency * 3, 500000) + 217;
+	buf[0] = (div >> 8) & 0x7f;
+	buf[1] = (div >> 0) & 0xff;
+
+	if (p->frequency < 611000000)
+		buf[2] = 0xb4;
+	else if (p->frequency < 811000000)
+		buf[2] = 0xbc;
+	else
+		buf[2] = 0xf4;
+
+	// VHF: 174-230 MHz
+	// center: 350 MHz
+	// UHF: 470-862 MHz
+	if (p->frequency < 350000000)
+		buf[3] = 0x02;
+	else
+		buf[3] = 0x04;
+
+	if (p->u.ofdm.bandwidth == BANDWIDTH_8_MHZ)
+		buf[3] |= 0x08;
+
+	if (sizeof(buf) == 6) {
+		buf[4] = buf[2];
+		buf[4] &= ~0x1c;
+		buf[4] |=  0x18;
+
+		buf[5] = (0 << 7) | (2 << 4);
+	}
+
+	msg.addr = I2C_ADDR_TUA6034 >> 1;
+	msg.flags = 0;
+	msg.buf = buf;
+	msg.len = sizeof(buf);
+
+	ret = i2c_transfer(&pluto->i2c_adap, &msg, 1);
+	if (ret < 0)
+		return ret;
+	else if (ret == 0)
+		return -EREMOTEIO;
+
+	return 0;
+}
+
+static int pluto2_request_firmware(struct dvb_frontend *fe,
+				   const struct firmware **fw, char *name)
+{
+	struct pluto *pluto = frontend_to_pluto(fe);
+
+	return request_firmware(fw, name, &pluto->pdev->dev);
+}
+
+static struct tda1004x_config pluto2_fe_config __devinitdata = {
+	.demod_address = I2C_ADDR_TDA10046 >> 1,
+	.invert = 1,
+	.invert_oclk = 0,
+	.xtal_freq = TDA10046_XTAL_16M,
+	.agc_config = TDA10046_AGC_DEFAULT,
+	.if_freq = TDA10046_FREQ_3617,
+	.pll_set = lg_tdtpe001p_pll_set,
+	.pll_sleep = NULL,
+	.request_firmware = pluto2_request_firmware,
+};
+
+static int __devinit frontend_init(struct pluto *pluto)
+{
+	int ret;
+
+	pluto->fe = tda10046_attach(&pluto2_fe_config, &pluto->i2c_adap);
+	if (!pluto->fe) {
+		dev_err(&pluto->pdev->dev, "could not attach frontend\n");
+		return -ENODEV;
+	}
+
+	ret = dvb_register_frontend(&pluto->dvb_adapter, pluto->fe);
+	if (ret < 0) {
+		if (pluto->fe->ops->release)
+			pluto->fe->ops->release(pluto->fe);
+		return ret;
+	}
+
+	return 0;
+}
+
+static void __devinit pluto_read_rev(struct pluto *pluto)
+{
+	u32 val = pluto_readreg(pluto, REG_MISC) & MISC_DVR;
+	dev_info(&pluto->pdev->dev, "board revision %d.%d\n",
+			(val >> 12) & 0x0f, (val >> 4) & 0xff);
+}
+
+static void __devinit pluto_read_mac(struct pluto *pluto, u8 *mac)
+{
+	u32 val = pluto_readreg(pluto, REG_MMAC);
+	mac[0] = (val >> 8) & 0xff;
+	mac[1] = (val >> 0) & 0xff;
+
+	val = pluto_readreg(pluto, REG_IMAC);
+	mac[2] = (val >> 8) & 0xff;
+	mac[3] = (val >> 0) & 0xff;
+
+	val = pluto_readreg(pluto, REG_LMAC);
+	mac[4] = (val >> 8) & 0xff;
+	mac[5] = (val >> 0) & 0xff;
+
+	dev_info(&pluto->pdev->dev, "MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
+			mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+}
+
+static int __devinit pluto_read_serial(struct pluto *pluto)
+{
+	struct pci_dev *pdev = pluto->pdev;
+	unsigned int i, j;
+	u8 __iomem *cis;
+
+	cis = pci_iomap(pdev, 1, 0);
+	if (!cis)
+		return -EIO;
+
+	dev_info(&pdev->dev, "S/N ");
+
+	for (i = 0xe0; i < 0x100; i += 4) {
+		u32 val = readl(&cis[i]);
+		for (j = 0; j < 32; j += 8) {
+			if ((val & 0xff) == 0xff)
+				goto out;
+			printk("%c", val & 0xff);
+			val >>= 8;
+		}
+	}
+out:
+	printk("\n");
+	pci_iounmap(pdev, cis);
+
+	return 0;
+}
+
+static int __devinit pluto2_probe(struct pci_dev *pdev,
+				  const struct pci_device_id *ent)
+{
+	struct pluto *pluto;
+	struct dvb_adapter *dvb_adapter;
+	struct dvb_demux *dvbdemux;
+	struct dmx_demux *dmx;
+	int ret = -ENOMEM;
+
+	pluto = kmalloc(sizeof(struct pluto), GFP_KERNEL);
+	if (!pluto)
+		goto out;
+
+	memset(pluto, 0, sizeof(struct pluto));
+	pluto->pdev = pdev;
+
+	ret = pci_enable_device(pdev);
+	if (ret < 0)
+		goto err_kfree;
+
+	/* enable interrupts */
+	pci_write_config_dword(pdev, 0x6c, 0x8000);
+
+	ret = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+	if (ret < 0)
+		goto err_pci_disable_device;
+
+	pci_set_master(pdev);
+
+	ret = pci_request_regions(pdev, DRIVER_NAME);
+	if (ret < 0)
+		goto err_pci_disable_device;
+
+	pluto->io_mem = pci_iomap(pdev, 0, 0x40);
+	if (!pluto->io_mem) {
+		ret = -EIO;
+		goto err_pci_release_regions;
+	}
+
+	pci_set_drvdata(pdev, pluto);
+
+	ret = request_irq(pdev->irq, pluto_irq, SA_SHIRQ, DRIVER_NAME, pluto);
+	if (ret < 0)
+		goto err_pci_iounmap;
+
+	ret = pluto_hw_init(pluto);
+	if (ret < 0)
+		goto err_free_irq;
+
+	/* i2c */
+	i2c_set_adapdata(&pluto->i2c_adap, pluto);
+	strcpy(pluto->i2c_adap.name, DRIVER_NAME);
+	pluto->i2c_adap.owner = THIS_MODULE;
+	pluto->i2c_adap.id = I2C_ALGO_BIT;
+	pluto->i2c_adap.class = I2C_CLASS_TV_DIGITAL;
+	pluto->i2c_adap.dev.parent = &pdev->dev;
+	pluto->i2c_adap.algo_data = &pluto->i2c_bit;
+	pluto->i2c_bit.data = pluto;
+	pluto->i2c_bit.setsda = pluto_setsda;
+	pluto->i2c_bit.setscl = pluto_setscl;
+	pluto->i2c_bit.getsda = pluto_getsda;
+	pluto->i2c_bit.getscl = pluto_getscl;
+	pluto->i2c_bit.udelay = 10;
+	pluto->i2c_bit.timeout = 10;
+
+	/* Raise SCL and SDA */
+	pluto_setsda(pluto, 1);
+	pluto_setscl(pluto, 1);
+
+	ret = i2c_bit_add_bus(&pluto->i2c_adap);
+	if (ret < 0)
+		goto err_pluto_hw_exit;
+
+	/* dvb */
+	ret = dvb_register_adapter(&pluto->dvb_adapter, DRIVER_NAME, THIS_MODULE);
+	if (ret < 0)
+		goto err_i2c_bit_del_bus;
+
+	dvb_adapter = &pluto->dvb_adapter;
+
+	pluto_read_rev(pluto);
+	pluto_read_serial(pluto);
+	pluto_read_mac(pluto, dvb_adapter->proposed_mac);
+
+	dvbdemux = &pluto->demux;
+	dvbdemux->filternum = 256;
+	dvbdemux->feednum = 256;
+	dvbdemux->start_feed = pluto_start_feed;
+	dvbdemux->stop_feed = pluto_stop_feed;
+	dvbdemux->dmx.capabilities = (DMX_TS_FILTERING |
+			DMX_SECTION_FILTERING | DMX_MEMORY_BASED_FILTERING);
+	ret = dvb_dmx_init(dvbdemux);
+	if (ret < 0)
+		goto err_dvb_unregister_adapter;
+
+	dmx = &dvbdemux->dmx;
+
+	pluto->hw_frontend.source = DMX_FRONTEND_0;
+	pluto->mem_frontend.source = DMX_MEMORY_FE;
+	pluto->dmxdev.filternum = NHWFILTERS;
+	pluto->dmxdev.demux = dmx;
+
+	ret = dvb_dmxdev_init(&pluto->dmxdev, dvb_adapter);
+	if (ret < 0)
+		goto err_dvb_dmx_release;
+
+	ret = dmx->add_frontend(dmx, &pluto->hw_frontend);
+	if (ret < 0)
+		goto err_dvb_dmxdev_release;
+
+	ret = dmx->add_frontend(dmx, &pluto->mem_frontend);
+	if (ret < 0)
+		goto err_remove_hw_frontend;
+
+	ret = dmx->connect_frontend(dmx, &pluto->hw_frontend);
+	if (ret < 0)
+		goto err_remove_mem_frontend;
+
+	ret = frontend_init(pluto);
+	if (ret < 0)
+		goto err_disconnect_frontend;
+
+	dvb_net_init(dvb_adapter, &pluto->dvbnet, dmx);
+out:
+	return ret;
+
+err_disconnect_frontend:
+	dmx->disconnect_frontend(dmx);
+err_remove_mem_frontend:
+	dmx->remove_frontend(dmx, &pluto->mem_frontend);
+err_remove_hw_frontend:
+	dmx->remove_frontend(dmx, &pluto->hw_frontend);
+err_dvb_dmxdev_release:
+	dvb_dmxdev_release(&pluto->dmxdev);
+err_dvb_dmx_release:
+	dvb_dmx_release(dvbdemux);
+err_dvb_unregister_adapter:
+	dvb_unregister_adapter(dvb_adapter);
+err_i2c_bit_del_bus:
+	i2c_bit_del_bus(&pluto->i2c_adap);
+err_pluto_hw_exit:
+	pluto_hw_exit(pluto);
+err_free_irq:
+	free_irq(pdev->irq, pluto);
+err_pci_iounmap:
+	pci_iounmap(pdev, pluto->io_mem);
+err_pci_release_regions:
+	pci_release_regions(pdev);
+err_pci_disable_device:
+	pci_disable_device(pdev);
+err_kfree:
+	pci_set_drvdata(pdev, NULL);
+	kfree(pluto);
+	goto out;
+}
+
+static void __devexit pluto2_remove(struct pci_dev *pdev)
+{
+	struct pluto *pluto = pci_get_drvdata(pdev);
+	struct dvb_adapter *dvb_adapter = &pluto->dvb_adapter;
+	struct dvb_demux *dvbdemux = &pluto->demux;
+	struct dmx_demux *dmx = &dvbdemux->dmx;
+
+	dmx->close(dmx);
+	dvb_net_release(&pluto->dvbnet);
+	if (pluto->fe)
+		dvb_unregister_frontend(pluto->fe);
+
+	dmx->disconnect_frontend(dmx);
+	dmx->remove_frontend(dmx, &pluto->mem_frontend);
+	dmx->remove_frontend(dmx, &pluto->hw_frontend);
+	dvb_dmxdev_release(&pluto->dmxdev);
+	dvb_dmx_release(dvbdemux);
+	dvb_unregister_adapter(dvb_adapter);
+	i2c_bit_del_bus(&pluto->i2c_adap);
+	pluto_hw_exit(pluto);
+	free_irq(pdev->irq, pluto);
+	pci_iounmap(pdev, pluto->io_mem);
+	pci_release_regions(pdev);
+	pci_disable_device(pdev);
+	pci_set_drvdata(pdev, NULL);
+	kfree(pluto);
+}
+
+#ifndef PCI_VENDOR_ID_SCM
+#define PCI_VENDOR_ID_SCM	0x0432
+#endif
+#ifndef PCI_DEVICE_ID_PLUTO2
+#define PCI_DEVICE_ID_PLUTO2	0x0001
+#endif
+
+static struct pci_device_id pluto2_id_table[] __devinitdata = {
+	{
+		.vendor = PCI_VENDOR_ID_SCM,
+		.device = PCI_DEVICE_ID_PLUTO2,
+		.subvendor = PCI_ANY_ID,
+		.subdevice = PCI_ANY_ID,
+	}, {
+		/* empty */
+	},
+};
+
+MODULE_DEVICE_TABLE(pci, pluto2_id_table);
+
+static struct pci_driver pluto2_driver = {
+	.name = DRIVER_NAME,
+	.id_table = pluto2_id_table,
+	.probe = pluto2_probe,
+	.remove = __devexit_p(pluto2_remove),
+};
+
+static int __init pluto2_init(void)
+{
+	return pci_register_driver(&pluto2_driver);
+}
+
+static void __exit pluto2_exit(void)
+{
+	pci_unregister_driver(&pluto2_driver);
+}
+
+module_init(pluto2_init);
+module_exit(pluto2_exit);
+
+MODULE_AUTHOR("Andreas Oberritter <obi@linuxtv.org>");
+MODULE_DESCRIPTION("Pluto2 driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/ttpci/Kconfig b/drivers/media/dvb/ttpci/Kconfig
--- a/drivers/media/dvb/ttpci/Kconfig
+++ b/drivers/media/dvb/ttpci/Kconfig
@@ -12,7 +12,7 @@ config DVB_AV7110
 	select DVB_STV0297
 	select DVB_L64781
 	help
-	  Support for SAA7146 and AV7110 based DVB cards as produced 
+	  Support for SAA7146 and AV7110 based DVB cards as produced
 	  by Fujitsu-Siemens, Technotrend, Hauppauge and others.
 
 	  This driver only supports the fullfeatured cards with
@@ -33,7 +33,7 @@ config DVB_AV7110_FIRMWARE
 	  If you want to compile the firmware into the driver you need to say
 	  Y here and provide the correct path of the firmware. You need this
 	  option if you want to compile the whole driver statically into the
-	  kernel. 
+	  kernel.
 
 	  All other people say N.
 
@@ -66,6 +66,7 @@ config DVB_BUDGET
 	select DVB_L64781
 	select DVB_TDA8083
 	select DVB_TDA10021
+	select DVB_S5H1420
 	help
 	  Support for simple SAA7146 based DVB cards
 	  (so called Budget- or Nova-PCI cards) without onboard
@@ -119,9 +120,9 @@ config DVB_BUDGET_PATCH
 	select DVB_VES1X93
 	select DVB_TDA8083
 	help
-	  Support for Budget Patch (full TS) modification on 
+	  Support for Budget Patch (full TS) modification on
 	  SAA7146+AV7110 based cards (DVB-S cards). This
-	  driver doesn't use onboard MPEG2 decoder. The 
+	  driver doesn't use onboard MPEG2 decoder. The
 	  card is driven in Budget-only mode. Card is
 	  required to have loaded firmware to tune properly.
 	  Firmware can be loaded by insertion and removal of
diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c
--- a/drivers/media/dvb/ttpci/av7110.c
+++ b/drivers/media/dvb/ttpci/av7110.c
@@ -116,13 +116,18 @@ static int av7110_num = 0;
 
 static void init_av7110_av(struct av7110 *av7110)
 {
+	int ret;
 	struct saa7146_dev *dev = av7110->dev;
 
 	/* set internal volume control to maximum */
 	av7110->adac_type = DVB_ADAC_TI;
-	av7110_set_volume(av7110, av7110->mixer.volume_left, av7110->mixer.volume_right);
+	ret = av7110_set_volume(av7110, av7110->mixer.volume_left, av7110->mixer.volume_right);
+	if (ret < 0)
+		printk("dvb-ttpci:cannot set internal volume to maximum:%d\n",ret);
 
-	av7710_set_video_mode(av7110, vidmode);
+	ret = av7710_set_video_mode(av7110, vidmode);
+	if (ret < 0)
+		printk("dvb-ttpci:cannot set video mode:%d\n",ret);
 
 	/* handle different card types */
 	/* remaining inits according to card and frontend type */
@@ -156,8 +161,12 @@ static void init_av7110_av(struct av7110
 
 	if (av7110->adac_type == DVB_ADAC_NONE || av7110->adac_type == DVB_ADAC_MSP) {
 		// switch DVB SCART on
-		av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, MainSwitch, 1, 0);
-		av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, ADSwitch, 1, 1);
+		ret = av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, MainSwitch, 1, 0);
+		if (ret < 0)
+			printk("dvb-ttpci:cannot switch on SCART(Main):%d\n",ret);
+		ret = av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, ADSwitch, 1, 1);
+		if (ret < 0)
+			printk("dvb-ttpci:cannot switch on SCART(AD):%d\n",ret);
 		if (rgb_on &&
 		    (av7110->dev->pci->subsystem_vendor == 0x110a) && (av7110->dev->pci->subsystem_device == 0x0000)) {
 			saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); // RGB on, SCART pin 16
@@ -165,8 +174,12 @@ static void init_av7110_av(struct av7110
 		}
 	}
 
-	av7110_set_volume(av7110, av7110->mixer.volume_left, av7110->mixer.volume_right);
-	av7110_setup_irc_config(av7110, 0);
+	ret = av7110_set_volume(av7110, av7110->mixer.volume_left, av7110->mixer.volume_right);
+	if (ret < 0)
+		printk("dvb-ttpci:cannot set volume :%d\n",ret);
+	ret = av7110_setup_irc_config(av7110, 0);
+	if (ret < 0)
+		printk("dvb-ttpci:cannot setup irc config :%d\n",ret);
 }
 
 static void recover_arm(struct av7110 *av7110)
@@ -258,8 +271,9 @@ static int arm_thread(void *data)
  *
  *  If we want to support multiple controls we would have to do much more...
  */
-void av7110_setup_irc_config(struct av7110 *av7110, u32 ir_config)
+int av7110_setup_irc_config(struct av7110 *av7110, u32 ir_config)
 {
+	int ret = 0;
 	static struct av7110 *last;
 
 	dprintk(4, "%p\n", av7110);
@@ -270,9 +284,10 @@ void av7110_setup_irc_config(struct av71
 		last = av7110;
 
 	if (av7110) {
-		av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, SetIR, 1, ir_config);
+		ret = av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, SetIR, 1, ir_config);
 		av7110->ir_config = ir_config;
 	}
+	return ret;
 }
 
 static void (*irc_handler)(u32);
@@ -765,13 +780,14 @@ static inline int SetPIDs(struct av7110 
 			     pcrpid, vpid, apid, ttpid, subpid);
 }
 
-void ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid,
+int ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid,
 		u16 subpid, u16 pcrpid)
 {
+	int ret = 0;
 	dprintk(4, "%p\n", av7110);
 
 	if (down_interruptible(&av7110->pid_mutex))
-		return;
+		return -ERESTARTSYS;
 
 	if (!(vpid & 0x8000))
 		av7110->pids[DMX_PES_VIDEO] = vpid;
@@ -786,10 +802,11 @@ void ChangePIDs(struct av7110 *av7110, u
 
 	if (av7110->fe_synced) {
 		pcrpid = av7110->pids[DMX_PES_PCR];
-		SetPIDs(av7110, vpid, apid, ttpid, subpid, pcrpid);
+		ret = SetPIDs(av7110, vpid, apid, ttpid, subpid, pcrpid);
 	}
 
 	up(&av7110->pid_mutex);
+	return ret;
 }
 
 
@@ -832,11 +849,13 @@ static int StartHWFilter(struct dvb_demu
 	ret = av7110_fw_request(av7110, buf, 20, &handle, 1);
 	if (ret != 0 || handle >= 32) {
 		printk("dvb-ttpci: %s error  buf %04x %04x %04x %04x  "
-				"ret %x  handle %04x\n",
+				"ret %d  handle %04x\n",
 				__FUNCTION__, buf[0], buf[1], buf[2], buf[3],
 				ret, handle);
 		dvbdmxfilter->hw_handle = 0xffff;
-		return -1;
+		if (!ret)
+			ret = -1;
+		return ret;
 	}
 
 	av7110->handle2filter[handle] = dvbdmxfilter;
@@ -859,7 +878,7 @@ static int StopHWFilter(struct dvb_demux
 	if (handle >= 32) {
 		printk("%s tried to stop invalid filter %04x, filter type = %x\n",
 				__FUNCTION__, handle, dvbdmxfilter->type);
-		return 0;
+		return -EINVAL;
 	}
 
 	av7110->handle2filter[handle] = NULL;
@@ -873,18 +892,20 @@ static int StopHWFilter(struct dvb_demux
 				"resp %04x %04x  pid %d\n",
 				__FUNCTION__, buf[0], buf[1], buf[2], ret,
 				answ[0], answ[1], dvbdmxfilter->feed->pid);
-		ret = -1;
+		if (!ret)
+			ret = -1;
 	}
 	return ret;
 }
 
 
-static void dvb_feed_start_pid(struct dvb_demux_feed *dvbdmxfeed)
+static int dvb_feed_start_pid(struct dvb_demux_feed *dvbdmxfeed)
 {
 	struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
 	struct av7110 *av7110 = (struct av7110 *) dvbdmx->priv;
 	u16 *pid = dvbdmx->pids, npids[5];
 	int i;
+	int ret = 0;
 
 	dprintk(4, "%p\n", av7110);
 
@@ -893,36 +914,49 @@ static void dvb_feed_start_pid(struct dv
 	npids[i] = (pid[i]&0x8000) ? 0 : pid[i];
 	if ((i == 2) && npids[i] && (dvbdmxfeed->ts_type & TS_PACKET)) {
 		npids[i] = 0;
-		ChangePIDs(av7110, npids[1], npids[0], npids[2], npids[3], npids[4]);
-		StartHWFilter(dvbdmxfeed->filter);
-		return;
+		ret = ChangePIDs(av7110, npids[1], npids[0], npids[2], npids[3], npids[4]);
+		if (!ret)
+			ret = StartHWFilter(dvbdmxfeed->filter);
+		return ret;
+	}
+	if (dvbdmxfeed->pes_type <= 2 || dvbdmxfeed->pes_type == 4) {
+		ret = ChangePIDs(av7110, npids[1], npids[0], npids[2], npids[3], npids[4]);
+		if (ret)
+			return ret;
 	}
-	if (dvbdmxfeed->pes_type <= 2 || dvbdmxfeed->pes_type == 4)
-		ChangePIDs(av7110, npids[1], npids[0], npids[2], npids[3], npids[4]);
 
 	if (dvbdmxfeed->pes_type < 2 && npids[0])
 		if (av7110->fe_synced)
-			av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, Scan, 0);
+		{
+			ret = av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, Scan, 0);
+			if (ret)
+				return ret;
+		}
 
 	if ((dvbdmxfeed->ts_type & TS_PACKET)) {
 		if (dvbdmxfeed->pes_type == 0 && !(dvbdmx->pids[0] & 0x8000))
-			av7110_av_start_record(av7110, RP_AUDIO, dvbdmxfeed);
+			ret = av7110_av_start_record(av7110, RP_AUDIO, dvbdmxfeed);
 		if (dvbdmxfeed->pes_type == 1 && !(dvbdmx->pids[1] & 0x8000))
-			av7110_av_start_record(av7110, RP_VIDEO, dvbdmxfeed);
+			ret = av7110_av_start_record(av7110, RP_VIDEO, dvbdmxfeed);
 	}
+	return ret;
 }
 
-static void dvb_feed_stop_pid(struct dvb_demux_feed *dvbdmxfeed)
+static int dvb_feed_stop_pid(struct dvb_demux_feed *dvbdmxfeed)
 {
 	struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
 	struct av7110 *av7110 = (struct av7110 *) dvbdmx->priv;
 	u16 *pid = dvbdmx->pids, npids[5];
 	int i;
 
+	int ret = 0;
+
 	dprintk(4, "%p\n", av7110);
 
 	if (dvbdmxfeed->pes_type <= 1) {
-		av7110_av_stop(av7110, dvbdmxfeed->pes_type ?  RP_VIDEO : RP_AUDIO);
+		ret = av7110_av_stop(av7110, dvbdmxfeed->pes_type ?  RP_VIDEO : RP_AUDIO);
+		if (ret)
+			return ret;
 		if (!av7110->rec_mode)
 			dvbdmx->recording = 0;
 		if (!av7110->playing)
@@ -933,24 +967,27 @@ static void dvb_feed_stop_pid(struct dvb
 	switch (i) {
 	case 2: //teletext
 		if (dvbdmxfeed->ts_type & TS_PACKET)
-			StopHWFilter(dvbdmxfeed->filter);
+			ret = StopHWFilter(dvbdmxfeed->filter);
 		npids[2] = 0;
 		break;
 	case 0:
 	case 1:
 	case 4:
 		if (!pids_off)
-			return;
+			return 0;
 		npids[i] = (pid[i]&0x8000) ? 0 : pid[i];
 		break;
 	}
-	ChangePIDs(av7110, npids[1], npids[0], npids[2], npids[3], npids[4]);
+	if (!ret)
+		ret = ChangePIDs(av7110, npids[1], npids[0], npids[2], npids[3], npids[4]);
+	return ret;
 }
 
 static int av7110_start_feed(struct dvb_demux_feed *feed)
 {
 	struct dvb_demux *demux = feed->demux;
 	struct av7110 *av7110 = demux->priv;
+	int ret = 0;
 
 	dprintk(4, "%p\n", av7110);
 
@@ -971,21 +1008,22 @@ static int av7110_start_feed(struct dvb_
 					   !(demux->pids[1] & 0x8000)) {
 					       dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout);
 					       dvb_ringbuffer_flush_spinlock_wakeup(&av7110->aout);
-					       av7110_av_start_play(av7110,RP_AV);
-					       demux->playing = 1;
+					       ret = av7110_av_start_play(av7110,RP_AV);
+					       if (!ret)
+						       demux->playing = 1;
 					}
 				break;
 			default:
-				dvb_feed_start_pid(feed);
+				ret = dvb_feed_start_pid(feed);
 				break;
 			}
 		} else if ((feed->ts_type & TS_PACKET) &&
 			   (demux->dmx.frontend->source != DMX_MEMORY_FE)) {
-			StartHWFilter(feed->filter);
+			ret = StartHWFilter(feed->filter);
 		}
 	}
 
-	if (feed->type == DMX_TYPE_SEC) {
+	else if (feed->type == DMX_TYPE_SEC) {
 		int i;
 
 		for (i = 0; i < demux->filternum; i++) {
@@ -996,12 +1034,15 @@ static int av7110_start_feed(struct dvb_
 			if (demux->filter[i].filter.parent != &feed->feed.sec)
 				continue;
 			demux->filter[i].state = DMX_STATE_GO;
-			if (demux->dmx.frontend->source != DMX_MEMORY_FE)
-				StartHWFilter(&demux->filter[i]);
+			if (demux->dmx.frontend->source != DMX_MEMORY_FE) {
+				ret = StartHWFilter(&demux->filter[i]);
+				if (ret)
+					break;
+			}
 		}
 	}
 
-	return 0;
+	return ret;
 }
 
 
@@ -1009,7 +1050,7 @@ static int av7110_stop_feed(struct dvb_d
 {
 	struct dvb_demux *demux = feed->demux;
 	struct av7110 *av7110 = demux->priv;
-
+	int i, rc, ret = 0;
 	dprintk(4, "%p\n", av7110);
 
 	if (feed->type == DMX_TYPE_TS) {
@@ -1022,26 +1063,29 @@ static int av7110_stop_feed(struct dvb_d
 		}
 		if (feed->ts_type & TS_DECODER &&
 		    feed->pes_type < DMX_TS_PES_OTHER) {
-			dvb_feed_stop_pid(feed);
+			ret = dvb_feed_stop_pid(feed);
 		} else
 			if ((feed->ts_type & TS_PACKET) &&
 			    (demux->dmx.frontend->source != DMX_MEMORY_FE))
-				StopHWFilter(feed->filter);
+				ret = StopHWFilter(feed->filter);
 	}
 
-	if (feed->type == DMX_TYPE_SEC) {
-		int i;
-
-		for (i = 0; i<demux->filternum; i++)
+	if (!ret && feed->type == DMX_TYPE_SEC) {
+		for (i = 0; i<demux->filternum; i++) {
 			if (demux->filter[i].state == DMX_STATE_GO &&
 			    demux->filter[i].filter.parent == &feed->feed.sec) {
 				demux->filter[i].state = DMX_STATE_READY;
-				if (demux->dmx.frontend->source != DMX_MEMORY_FE)
-					StopHWFilter(&demux->filter[i]);
+				if (demux->dmx.frontend->source != DMX_MEMORY_FE) {
+					rc = StopHWFilter(&demux->filter[i]);
+					if (!ret)
+						ret = rc;
+					/* keep going, stop as many filters as possible */
+				}
+			}
 		}
 	}
 
-	return 0;
+	return ret;
 }
 
 
@@ -1093,7 +1137,7 @@ static int dvb_get_stc(struct dmx_demux 
 	ret = av7110_fw_request(av7110, &tag, 0, fwstc, 4);
 	if (ret) {
 		printk(KERN_ERR "%s: av7110_fw_request error\n", __FUNCTION__);
-		return -EIO;
+		return ret;
 	}
 	dprintk(2, "fwstc = %04hx %04hx %04hx %04hx\n",
 		fwstc[0], fwstc[1], fwstc[2], fwstc[3]);
@@ -1119,18 +1163,14 @@ static int av7110_set_tone(struct dvb_fr
 
 	switch (tone) {
 	case SEC_TONE_ON:
-		Set22K(av7110, 1);
-		break;
+		return Set22K(av7110, 1);
 
 	case SEC_TONE_OFF:
-		Set22K(av7110, 0);
-		break;
+		return Set22K(av7110, 0);
 
 	default:
 		return -EINVAL;
 	}
-
-	return 0;
 }
 
 static int av7110_diseqc_send_master_cmd(struct dvb_frontend* fe,
@@ -1138,9 +1178,7 @@ static int av7110_diseqc_send_master_cmd
 {
 	struct av7110* av7110 = fe->dvb->priv;
 
-	av7110_diseqc_send(av7110, cmd->msg_len, cmd->msg, -1);
-
-	return 0;
+	return av7110_diseqc_send(av7110, cmd->msg_len, cmd->msg, -1);
 }
 
 static int av7110_diseqc_send_burst(struct dvb_frontend* fe,
@@ -1148,9 +1186,7 @@ static int av7110_diseqc_send_burst(stru
 {
 	struct av7110* av7110 = fe->dvb->priv;
 
-	av7110_diseqc_send(av7110, 0, NULL, minicmd);
-
-	return 0;
+	return av7110_diseqc_send(av7110, 0, NULL, minicmd);
 }
 
 /* simplified code from budget-core.c */
@@ -1992,76 +2028,85 @@ static struct l64781_config grundig_2950
 
 
 
-static void av7110_fe_lock_fix(struct av7110* av7110, fe_status_t status)
+static int av7110_fe_lock_fix(struct av7110* av7110, fe_status_t status)
 {
+	int ret = 0;
 	int synced = (status & FE_HAS_LOCK) ? 1 : 0;
 
 	av7110->fe_status = status;
 
 	if (av7110->fe_synced == synced)
-		return;
-
-	av7110->fe_synced = synced;
+		return 0;
 
 	if (av7110->playing)
-		return;
+		return 0;
 
 	if (down_interruptible(&av7110->pid_mutex))
-		return;
+		return -ERESTARTSYS;
 
-	if (av7110->fe_synced) {
-		SetPIDs(av7110, av7110->pids[DMX_PES_VIDEO],
+	if (synced) {
+		ret = SetPIDs(av7110, av7110->pids[DMX_PES_VIDEO],
 			av7110->pids[DMX_PES_AUDIO],
 			av7110->pids[DMX_PES_TELETEXT], 0,
 			av7110->pids[DMX_PES_PCR]);
-		av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, Scan, 0);
+		if (!ret)
+			ret = av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, Scan, 0);
 	} else {
-		SetPIDs(av7110, 0, 0, 0, 0, 0);
-		av7110_fw_cmd(av7110, COMTYPE_PID_FILTER, FlushTSQueue, 0);
-		av7110_wait_msgstate(av7110, GPMQBusy);
+		ret = SetPIDs(av7110, 0, 0, 0, 0, 0);
+		if (!ret) {
+			ret = av7110_fw_cmd(av7110, COMTYPE_PID_FILTER, FlushTSQueue, 0);
+			if (!ret)
+				ret = av7110_wait_msgstate(av7110, GPMQBusy);
+		}
 	}
 
+	if (!ret)
+		av7110->fe_synced = synced;
+
 	up(&av7110->pid_mutex);
+	return ret;
 }
 
 static int av7110_fe_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
 {
 	struct av7110* av7110 = fe->dvb->priv;
-	av7110_fe_lock_fix(av7110, 0);
-	return av7110->fe_set_frontend(fe, params);
+
+	int ret = av7110_fe_lock_fix(av7110, 0);
+	if (!ret)
+		ret = av7110->fe_set_frontend(fe, params);
+	return ret;
 }
 
 static int av7110_fe_init(struct dvb_frontend* fe)
 {
 	struct av7110* av7110 = fe->dvb->priv;
 
-	av7110_fe_lock_fix(av7110, 0);
-	return av7110->fe_init(fe);
+	int ret = av7110_fe_lock_fix(av7110, 0);
+	if (!ret)
+		ret = av7110->fe_init(fe);
+	return ret;
 }
 
 static int av7110_fe_read_status(struct dvb_frontend* fe, fe_status_t* status)
 {
 	struct av7110* av7110 = fe->dvb->priv;
-	int ret;
 
 	/* call the real implementation */
-	ret = av7110->fe_read_status(fe, status);
-	if (ret)
-		return ret;
-
-	if (((*status ^ av7110->fe_status) & FE_HAS_LOCK) && (*status & FE_HAS_LOCK)) {
-		av7110_fe_lock_fix(av7110, *status);
-	}
-
-	return 0;
+	int ret = av7110->fe_read_status(fe, status);
+	if (!ret)
+		if (((*status ^ av7110->fe_status) & FE_HAS_LOCK) && (*status & FE_HAS_LOCK))
+			ret = av7110_fe_lock_fix(av7110, *status);
+	return ret;
 }
 
 static int av7110_fe_diseqc_reset_overload(struct dvb_frontend* fe)
 {
 	struct av7110* av7110 = fe->dvb->priv;
 
-	av7110_fe_lock_fix(av7110, 0);
-	return av7110->fe_diseqc_reset_overload(fe);
+	int ret = av7110_fe_lock_fix(av7110, 0);
+	if (!ret)
+		ret = av7110->fe_diseqc_reset_overload(fe);
+	return ret;
 }
 
 static int av7110_fe_diseqc_send_master_cmd(struct dvb_frontend* fe,
@@ -2069,40 +2114,50 @@ static int av7110_fe_diseqc_send_master_
 {
 	struct av7110* av7110 = fe->dvb->priv;
 
-	av7110_fe_lock_fix(av7110, 0);
-	return av7110->fe_diseqc_send_master_cmd(fe, cmd);
+	int ret = av7110_fe_lock_fix(av7110, 0);
+	if (!ret)
+		ret = av7110->fe_diseqc_send_master_cmd(fe, cmd);
+	return ret;
 }
 
 static int av7110_fe_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd)
 {
 	struct av7110* av7110 = fe->dvb->priv;
 
-	av7110_fe_lock_fix(av7110, 0);
-	return av7110->fe_diseqc_send_burst(fe, minicmd);
+	int ret = av7110_fe_lock_fix(av7110, 0);
+	if (!ret)
+		ret = av7110->fe_diseqc_send_burst(fe, minicmd);
+	return ret;
 }
 
 static int av7110_fe_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
 {
 	struct av7110* av7110 = fe->dvb->priv;
 
-	av7110_fe_lock_fix(av7110, 0);
-	return av7110->fe_set_tone(fe, tone);
+	int ret = av7110_fe_lock_fix(av7110, 0);
+	if (!ret)
+		ret = av7110->fe_set_tone(fe, tone);
+	return ret;
 }
 
 static int av7110_fe_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
 {
 	struct av7110* av7110 = fe->dvb->priv;
 
-	av7110_fe_lock_fix(av7110, 0);
-	return av7110->fe_set_voltage(fe, voltage);
+	int ret = av7110_fe_lock_fix(av7110, 0);
+	if (!ret)
+		ret = av7110->fe_set_voltage(fe, voltage);
+	return ret;
 }
 
 static int av7110_fe_dishnetwork_send_legacy_command(struct dvb_frontend* fe, unsigned int cmd)
 {
 	struct av7110* av7110 = fe->dvb->priv;
 
-	av7110_fe_lock_fix(av7110, 0);
-	return av7110->fe_dishnetwork_send_legacy_command(fe, cmd);
+	int ret = av7110_fe_lock_fix(av7110, 0);
+	if (!ret)
+		ret = av7110->fe_dishnetwork_send_legacy_command(fe, cmd);
+	return ret;
 }
 
 static u8 read_pwm(struct av7110* av7110)
diff --git a/drivers/media/dvb/ttpci/av7110.h b/drivers/media/dvb/ttpci/av7110.h
--- a/drivers/media/dvb/ttpci/av7110.h
+++ b/drivers/media/dvb/ttpci/av7110.h
@@ -119,8 +119,7 @@ struct av7110 {
 	volatile int		bmp_state;
 #define BMP_NONE     0
 #define BMP_LOADING  1
-#define BMP_LOADINGS 2
-#define BMP_LOADED   3
+#define BMP_LOADED   2
 	wait_queue_head_t	bmpq;
 
 
@@ -255,12 +254,12 @@ struct av7110 {
 };
 
 
-extern void ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid,
+extern int ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid,
 		       u16 subpid, u16 pcrpid);
 
 extern void av7110_register_irc_handler(void (*func)(u32));
 extern void av7110_unregister_irc_handler(void (*func)(u32));
-extern void av7110_setup_irc_config (struct av7110 *av7110, u32 ir_config);
+extern int av7110_setup_irc_config (struct av7110 *av7110, u32 ir_config);
 
 extern int av7110_ir_init (void);
 extern void av7110_ir_exit (void);
diff --git a/drivers/media/dvb/ttpci/av7110_av.c b/drivers/media/dvb/ttpci/av7110_av.c
--- a/drivers/media/dvb/ttpci/av7110_av.c
+++ b/drivers/media/dvb/ttpci/av7110_av.c
@@ -121,6 +121,7 @@ static int dvb_filter_pes2ts_cb(void *pr
 int av7110_av_start_record(struct av7110 *av7110, int av,
 			   struct dvb_demux_feed *dvbdmxfeed)
 {
+	int ret = 0;
 	struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
 
 	dprintk(2, "av7110:%p, , dvb_demux_feed:%p\n", av7110, dvbdmxfeed);
@@ -137,7 +138,7 @@ int av7110_av_start_record(struct av7110
 				       dvbdmx->pesfilter[0]->pid,
 				       dvb_filter_pes2ts_cb,
 				       (void *) dvbdmx->pesfilter[0]);
-		av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, AudioPES, 0);
+		ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, AudioPES, 0);
 		break;
 
 	case RP_VIDEO:
@@ -145,7 +146,7 @@ int av7110_av_start_record(struct av7110
 				       dvbdmx->pesfilter[1]->pid,
 				       dvb_filter_pes2ts_cb,
 				       (void *) dvbdmx->pesfilter[1]);
-		av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, VideoPES, 0);
+		ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, VideoPES, 0);
 		break;
 
 	case RP_AV:
@@ -157,14 +158,15 @@ int av7110_av_start_record(struct av7110
 				       dvbdmx->pesfilter[1]->pid,
 				       dvb_filter_pes2ts_cb,
 				       (void *) dvbdmx->pesfilter[1]);
-		av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, AV_PES, 0);
+		ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, AV_PES, 0);
 		break;
 	}
-	return 0;
+	return ret;
 }
 
 int av7110_av_start_play(struct av7110 *av7110, int av)
 {
+	int ret = 0;
 	dprintk(2, "av7110:%p, \n", av7110);
 
 	if (av7110->rec_mode)
@@ -182,54 +184,57 @@ int av7110_av_start_play(struct av7110 *
 	av7110->playing |= av;
 	switch (av7110->playing) {
 	case RP_AUDIO:
-		av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, AudioPES, 0);
+		ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, AudioPES, 0);
 		break;
 	case RP_VIDEO:
-		av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, VideoPES, 0);
+		ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, VideoPES, 0);
 		av7110->sinfo = 0;
 		break;
 	case RP_AV:
 		av7110->sinfo = 0;
-		av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, AV_PES, 0);
+		ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, AV_PES, 0);
 		break;
 	}
-	return av7110->playing;
+	if (!ret)
+		ret = av7110->playing;
+	return ret;
 }
 
-void av7110_av_stop(struct av7110 *av7110, int av)
+int av7110_av_stop(struct av7110 *av7110, int av)
 {
+	int ret = 0;
 	dprintk(2, "av7110:%p, \n", av7110);
 
 	if (!(av7110->playing & av) && !(av7110->rec_mode & av))
-		return;
-
+		return 0;
 	av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Stop, 0);
 	if (av7110->playing) {
 		av7110->playing &= ~av;
 		switch (av7110->playing) {
 		case RP_AUDIO:
-			av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, AudioPES, 0);
+			ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, AudioPES, 0);
 			break;
 		case RP_VIDEO:
-			av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, VideoPES, 0);
+			ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, VideoPES, 0);
 			break;
 		case RP_NONE:
-			av7110_set_vidmode(av7110, av7110->vidmode);
+			ret = av7110_set_vidmode(av7110, av7110->vidmode);
 			break;
 		}
 	} else {
 		av7110->rec_mode &= ~av;
 		switch (av7110->rec_mode) {
 		case RP_AUDIO:
-			av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, AudioPES, 0);
+			ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, AudioPES, 0);
 			break;
 		case RP_VIDEO:
-			av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, VideoPES, 0);
+			ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, VideoPES, 0);
 			break;
 		case RP_NONE:
 			break;
 		}
 	}
+	return ret;
 }
 
 
@@ -317,19 +322,22 @@ int av7110_set_volume(struct av7110 *av7
 	return 0;
 }
 
-void av7110_set_vidmode(struct av7110 *av7110, int mode)
+int av7110_set_vidmode(struct av7110 *av7110, int mode)
 {
+	int ret;
 	dprintk(2, "av7110:%p, \n", av7110);
 
-	av7110_fw_cmd(av7110, COMTYPE_ENCODER, LoadVidCode, 1, mode);
+	ret = av7110_fw_cmd(av7110, COMTYPE_ENCODER, LoadVidCode, 1, mode);
 
-	if (!av7110->playing) {
-		ChangePIDs(av7110, av7110->pids[DMX_PES_VIDEO],
+	if (!ret && !av7110->playing) {
+		ret = ChangePIDs(av7110, av7110->pids[DMX_PES_VIDEO],
 			   av7110->pids[DMX_PES_AUDIO],
 			   av7110->pids[DMX_PES_TELETEXT],
 			   0, av7110->pids[DMX_PES_PCR]);
-		av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, Scan, 0);
+		if (!ret)
+			ret = av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, Scan, 0);
 	}
+	return ret;
 }
 
 
@@ -340,17 +348,18 @@ static int sw2mode[16] = {
 	VIDEO_MODE_PAL, VIDEO_MODE_PAL, VIDEO_MODE_PAL, VIDEO_MODE_PAL,
 };
 
-static void get_video_format(struct av7110 *av7110, u8 *buf, int count)
+static int get_video_format(struct av7110 *av7110, u8 *buf, int count)
 {
 	int i;
 	int hsize, vsize;
 	int sw;
 	u8 *p;
+	int ret = 0;
 
 	dprintk(2, "av7110:%p, \n", av7110);
 
 	if (av7110->sinfo)
-		return;
+		return 0;
 	for (i = 7; i < count - 10; i++) {
 		p = buf + i;
 		if (p[0] || p[1] || p[2] != 0x01 || p[3] != 0xb3)
@@ -359,11 +368,14 @@ static void get_video_format(struct av71
 		hsize = ((p[1] &0xF0) >> 4) | (p[0] << 4);
 		vsize = ((p[1] &0x0F) << 8) | (p[2]);
 		sw = (p[3] & 0x0F);
-		av7110_set_vidmode(av7110, sw2mode[sw]);
-		dprintk(2, "playback %dx%d fr=%d\n", hsize, vsize, sw);
-		av7110->sinfo = 1;
+		ret = av7110_set_vidmode(av7110, sw2mode[sw]);
+		if (!ret) {
+			dprintk(2, "playback %dx%d fr=%d\n", hsize, vsize, sw);
+			av7110->sinfo = 1;
+		}
 		break;
 	}
+	return ret;
 }
 
 
@@ -974,7 +986,7 @@ static int dvb_video_ioctl(struct inode 
 	unsigned long arg = (unsigned long) parg;
 	int ret = 0;
 
-	dprintk(2, "av7110:%p, \n", av7110);
+	dprintk(1, "av7110:%p, cmd=%04x\n", av7110,cmd);
 
 	if ((file->f_flags & O_ACCMODE) == O_RDONLY) {
 		if ( cmd != VIDEO_GET_STATUS && cmd != VIDEO_GET_EVENT &&
@@ -987,49 +999,57 @@ static int dvb_video_ioctl(struct inode 
 	case VIDEO_STOP:
 		av7110->videostate.play_state = VIDEO_STOPPED;
 		if (av7110->videostate.stream_source == VIDEO_SOURCE_MEMORY)
-			av7110_av_stop(av7110, RP_VIDEO);
+			ret = av7110_av_stop(av7110, RP_VIDEO);
 		else
-			vidcom(av7110, VIDEO_CMD_STOP,
+			ret = vidcom(av7110, VIDEO_CMD_STOP,
 			       av7110->videostate.video_blank ? 0 : 1);
-		av7110->trickmode = TRICK_NONE;
+		if (!ret)
+			av7110->trickmode = TRICK_NONE;
 		break;
 
 	case VIDEO_PLAY:
 		av7110->trickmode = TRICK_NONE;
 		if (av7110->videostate.play_state == VIDEO_FREEZED) {
 			av7110->videostate.play_state = VIDEO_PLAYING;
-			vidcom(av7110, VIDEO_CMD_PLAY, 0);
+			ret = vidcom(av7110, VIDEO_CMD_PLAY, 0);
+			if (ret)
+				break;
 		}
 
 		if (av7110->videostate.stream_source == VIDEO_SOURCE_MEMORY) {
 			if (av7110->playing == RP_AV) {
-				av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Stop, 0);
+				ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Stop, 0);
+				if (ret)
+					break;
 				av7110->playing &= ~RP_VIDEO;
 			}
-			av7110_av_start_play(av7110, RP_VIDEO);
-			vidcom(av7110, VIDEO_CMD_PLAY, 0);
-		} else {
-			//av7110_av_stop(av7110, RP_VIDEO);
-			vidcom(av7110, VIDEO_CMD_PLAY, 0);
+			ret = av7110_av_start_play(av7110, RP_VIDEO);
 		}
-		av7110->videostate.play_state = VIDEO_PLAYING;
+		if (!ret)
+			ret = vidcom(av7110, VIDEO_CMD_PLAY, 0);
+		if (!ret)
+			av7110->videostate.play_state = VIDEO_PLAYING;
 		break;
 
 	case VIDEO_FREEZE:
 		av7110->videostate.play_state = VIDEO_FREEZED;
 		if (av7110->playing & RP_VIDEO)
-			av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Pause, 0);
+			ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Pause, 0);
 		else
-			vidcom(av7110, VIDEO_CMD_FREEZE, 1);
-		av7110->trickmode = TRICK_FREEZE;
+			ret = vidcom(av7110, VIDEO_CMD_FREEZE, 1);
+		if (!ret)
+			av7110->trickmode = TRICK_FREEZE;
 		break;
 
 	case VIDEO_CONTINUE:
 		if (av7110->playing & RP_VIDEO)
-			av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Continue, 0);
-		vidcom(av7110, VIDEO_CMD_PLAY, 0);
-		av7110->videostate.play_state = VIDEO_PLAYING;
-		av7110->trickmode = TRICK_NONE;
+			ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Continue, 0);
+		if (!ret)
+			ret = vidcom(av7110, VIDEO_CMD_PLAY, 0);
+		if (!ret) {
+			av7110->videostate.play_state = VIDEO_PLAYING;
+			av7110->trickmode = TRICK_NONE;
+		}
 		break;
 
 	case VIDEO_SELECT_SOURCE:
@@ -1045,7 +1065,7 @@ static int dvb_video_ioctl(struct inode 
 		break;
 
 	case VIDEO_GET_EVENT:
-		ret=dvb_video_get_event(av7110, parg, file->f_flags);
+		ret = dvb_video_get_event(av7110, parg, file->f_flags);
 		break;
 
 	case VIDEO_GET_SIZE:
@@ -1105,25 +1125,32 @@ static int dvb_video_ioctl(struct inode 
 	case VIDEO_FAST_FORWARD:
 		//note: arg is ignored by firmware
 		if (av7110->playing & RP_VIDEO)
-			av7110_fw_cmd(av7110, COMTYPE_REC_PLAY,
-				      __Scan_I, 2, AV_PES, 0);
+			ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY,
+					    __Scan_I, 2, AV_PES, 0);
 		else
-			vidcom(av7110, VIDEO_CMD_FFWD, arg);
-		av7110->trickmode = TRICK_FAST;
-		av7110->videostate.play_state = VIDEO_PLAYING;
+			ret = vidcom(av7110, VIDEO_CMD_FFWD, arg);
+		if (!ret) {
+			av7110->trickmode = TRICK_FAST;
+			av7110->videostate.play_state = VIDEO_PLAYING;
+		}
 		break;
 
 	case VIDEO_SLOWMOTION:
 		if (av7110->playing&RP_VIDEO) {
-			av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Slow, 2, 0, 0);
-			vidcom(av7110, VIDEO_CMD_SLOW, arg);
+			ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Slow, 2, 0, 0);
+			if (!ret)
+				ret = vidcom(av7110, VIDEO_CMD_SLOW, arg);
 		} else {
-			vidcom(av7110, VIDEO_CMD_PLAY, 0);
-			vidcom(av7110, VIDEO_CMD_STOP, 0);
-			vidcom(av7110, VIDEO_CMD_SLOW, arg);
+			ret = vidcom(av7110, VIDEO_CMD_PLAY, 0);
+			if (!ret)
+				ret = vidcom(av7110, VIDEO_CMD_STOP, 0);
+			if (!ret)
+				ret = vidcom(av7110, VIDEO_CMD_SLOW, arg);
+		}
+		if (!ret) {
+			av7110->trickmode = TRICK_SLOW;
+			av7110->videostate.play_state = VIDEO_PLAYING;
 		}
-		av7110->trickmode = TRICK_SLOW;
-		av7110->videostate.play_state = VIDEO_PLAYING;
 		break;
 
 	case VIDEO_GET_CAPABILITIES:
@@ -1136,18 +1163,21 @@ static int dvb_video_ioctl(struct inode 
 		av7110_ipack_reset(&av7110->ipack[1]);
 
 		if (av7110->playing == RP_AV) {
-			av7110_fw_cmd(av7110, COMTYPE_REC_PLAY,
-				      __Play, 2, AV_PES, 0);
+			ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY,
+					    __Play, 2, AV_PES, 0);
+			if (ret)
+				break;
 			if (av7110->trickmode == TRICK_FAST)
-				av7110_fw_cmd(av7110, COMTYPE_REC_PLAY,
-					      __Scan_I, 2, AV_PES, 0);
+				ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY,
+						    __Scan_I, 2, AV_PES, 0);
 			if (av7110->trickmode == TRICK_SLOW) {
-				av7110_fw_cmd(av7110, COMTYPE_REC_PLAY,
-					      __Slow, 2, 0, 0);
-				vidcom(av7110, VIDEO_CMD_SLOW, arg);
+				ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY,
+						    __Slow, 2, 0, 0);
+				if (!ret)
+					ret = vidcom(av7110, VIDEO_CMD_SLOW, arg);
 			}
 			if (av7110->trickmode == TRICK_FREEZE)
-				vidcom(av7110, VIDEO_CMD_STOP, 1);
+				ret = vidcom(av7110, VIDEO_CMD_STOP, 1);
 		}
 		break;
 
@@ -1170,7 +1200,7 @@ static int dvb_audio_ioctl(struct inode 
 	unsigned long arg = (unsigned long) parg;
 	int ret = 0;
 
-	dprintk(2, "av7110:%p, \n", av7110);
+	dprintk(1, "av7110:%p, cmd=%04x\n", av7110,cmd);
 
 	if (((file->f_flags & O_ACCMODE) == O_RDONLY) &&
 	    (cmd != AUDIO_GET_STATUS))
@@ -1179,28 +1209,32 @@ static int dvb_audio_ioctl(struct inode 
 	switch (cmd) {
 	case AUDIO_STOP:
 		if (av7110->audiostate.stream_source == AUDIO_SOURCE_MEMORY)
-			av7110_av_stop(av7110, RP_AUDIO);
+			ret = av7110_av_stop(av7110, RP_AUDIO);
 		else
-			audcom(av7110, AUDIO_CMD_MUTE);
-		av7110->audiostate.play_state = AUDIO_STOPPED;
+			ret = audcom(av7110, AUDIO_CMD_MUTE);
+		if (!ret)
+			av7110->audiostate.play_state = AUDIO_STOPPED;
 		break;
 
 	case AUDIO_PLAY:
 		if (av7110->audiostate.stream_source == AUDIO_SOURCE_MEMORY)
-			av7110_av_start_play(av7110, RP_AUDIO);
-		audcom(av7110, AUDIO_CMD_UNMUTE);
-		av7110->audiostate.play_state = AUDIO_PLAYING;
+			ret = av7110_av_start_play(av7110, RP_AUDIO);
+		if (!ret)
+			ret = audcom(av7110, AUDIO_CMD_UNMUTE);
+		if (!ret)
+			av7110->audiostate.play_state = AUDIO_PLAYING;
 		break;
 
 	case AUDIO_PAUSE:
-		audcom(av7110, AUDIO_CMD_MUTE);
-		av7110->audiostate.play_state = AUDIO_PAUSED;
+		ret = audcom(av7110, AUDIO_CMD_MUTE);
+		if (!ret)
+			av7110->audiostate.play_state = AUDIO_PAUSED;
 		break;
 
 	case AUDIO_CONTINUE:
 		if (av7110->audiostate.play_state == AUDIO_PAUSED) {
 			av7110->audiostate.play_state = AUDIO_PLAYING;
-			audcom(av7110, AUDIO_CMD_MUTE | AUDIO_CMD_PCM16);
+			ret = audcom(av7110, AUDIO_CMD_UNMUTE | AUDIO_CMD_PCM16);
 		}
 		break;
 
@@ -1210,14 +1244,15 @@ static int dvb_audio_ioctl(struct inode 
 
 	case AUDIO_SET_MUTE:
 	{
-		audcom(av7110, arg ? AUDIO_CMD_MUTE : AUDIO_CMD_UNMUTE);
-		av7110->audiostate.mute_state = (int) arg;
+		ret = audcom(av7110, arg ? AUDIO_CMD_MUTE : AUDIO_CMD_UNMUTE);
+		if (!ret)
+			av7110->audiostate.mute_state = (int) arg;
 		break;
 	}
 
 	case AUDIO_SET_AV_SYNC:
 		av7110->audiostate.AV_sync_state = (int) arg;
-		audcom(av7110, arg ? AUDIO_CMD_SYNC_ON : AUDIO_CMD_SYNC_OFF);
+		ret = audcom(av7110, arg ? AUDIO_CMD_SYNC_ON : AUDIO_CMD_SYNC_OFF);
 		break;
 
 	case AUDIO_SET_BYPASS_MODE:
@@ -1229,21 +1264,24 @@ static int dvb_audio_ioctl(struct inode 
 
 		switch(av7110->audiostate.channel_select) {
 		case AUDIO_STEREO:
-			audcom(av7110, AUDIO_CMD_STEREO);
-			if (av7110->adac_type == DVB_ADAC_CRYSTAL)
-				i2c_writereg(av7110, 0x20, 0x02, 0x49);
+			ret = audcom(av7110, AUDIO_CMD_STEREO);
+			if (!ret)
+				if (av7110->adac_type == DVB_ADAC_CRYSTAL)
+					i2c_writereg(av7110, 0x20, 0x02, 0x49);
 			break;
 
 		case AUDIO_MONO_LEFT:
-			audcom(av7110, AUDIO_CMD_MONO_L);
-			if (av7110->adac_type == DVB_ADAC_CRYSTAL)
-				i2c_writereg(av7110, 0x20, 0x02, 0x4a);
+			ret = audcom(av7110, AUDIO_CMD_MONO_L);
+			if (!ret)
+				if (av7110->adac_type == DVB_ADAC_CRYSTAL)
+					i2c_writereg(av7110, 0x20, 0x02, 0x4a);
 			break;
 
 		case AUDIO_MONO_RIGHT:
-			audcom(av7110, AUDIO_CMD_MONO_R);
-			if (av7110->adac_type == DVB_ADAC_CRYSTAL)
-				i2c_writereg(av7110, 0x20, 0x02, 0x45);
+			ret = audcom(av7110, AUDIO_CMD_MONO_R);
+			if (!ret)
+				if (av7110->adac_type == DVB_ADAC_CRYSTAL)
+					i2c_writereg(av7110, 0x20, 0x02, 0x45);
 			break;
 
 		default:
@@ -1264,8 +1302,8 @@ static int dvb_audio_ioctl(struct inode 
 		dvb_ringbuffer_flush_spinlock_wakeup(&av7110->aout);
 		av7110_ipack_reset(&av7110->ipack[0]);
 		if (av7110->playing == RP_AV)
-			av7110_fw_cmd(av7110, COMTYPE_REC_PLAY,
-			       __Play, 2, AV_PES, 0);
+			ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY,
+					    __Play, 2, AV_PES, 0);
 		break;
 	case AUDIO_SET_ID:
 
@@ -1274,7 +1312,7 @@ static int dvb_audio_ioctl(struct inode 
 	{
 		struct audio_mixer *amix = (struct audio_mixer *)parg;
 
-		av7110_set_volume(av7110, amix->volume_left, amix->volume_right);
+		ret = av7110_set_volume(av7110, amix->volume_left, amix->volume_right);
 		break;
 	}
 	case AUDIO_SET_STREAMTYPE:
diff --git a/drivers/media/dvb/ttpci/av7110_av.h b/drivers/media/dvb/ttpci/av7110_av.h
--- a/drivers/media/dvb/ttpci/av7110_av.h
+++ b/drivers/media/dvb/ttpci/av7110_av.h
@@ -3,14 +3,14 @@
 
 struct av7110;
 
-extern void av7110_set_vidmode(struct av7110 *av7110, int mode);
+extern int av7110_set_vidmode(struct av7110 *av7110, int mode);
 
 extern int av7110_record_cb(struct dvb_filter_pes2ts *p2t, u8 *buf, size_t len);
 extern int av7110_pes_play(void *dest, struct dvb_ringbuffer *buf, int dlen);
 extern int av7110_write_to_decoder(struct dvb_demux_feed *feed, const u8 *buf, size_t len);
 
 extern int av7110_set_volume(struct av7110 *av7110, int volleft, int volright);
-extern void av7110_av_stop(struct av7110 *av7110, int av);
+extern int av7110_av_stop(struct av7110 *av7110, int av);
 extern int av7110_av_start_record(struct av7110 *av7110, int av,
 			  struct dvb_demux_feed *dvbdmxfeed);
 extern int av7110_av_start_play(struct av7110 *av7110, int av);
diff --git a/drivers/media/dvb/ttpci/av7110_hw.c b/drivers/media/dvb/ttpci/av7110_hw.c
--- a/drivers/media/dvb/ttpci/av7110_hw.c
+++ b/drivers/media/dvb/ttpci/av7110_hw.c
@@ -137,7 +137,7 @@ static int waitdebi(struct av7110 *av711
 			return 0;
 		udelay(5);
 	}
-	return -1;
+	return -ETIMEDOUT;
 }
 
 static int load_dram(struct av7110 *av7110, u32 *data, int len)
@@ -155,7 +155,7 @@ static int load_dram(struct av7110 *av71
 	for (i = 0; i < blocks; i++) {
 		if (waitdebi(av7110, BOOT_STATE, BOOTSTATE_BUFFER_EMPTY) < 0) {
 			printk(KERN_ERR "dvb-ttpci: load_dram(): timeout at block %d\n", i);
-			return -1;
+			return -ETIMEDOUT;
 		}
 		dprintk(4, "writing DRAM block %d\n", i);
 		mwdebi(av7110, DEBISWAB, bootblock,
@@ -170,7 +170,7 @@ static int load_dram(struct av7110 *av71
 	if (rest > 0) {
 		if (waitdebi(av7110, BOOT_STATE, BOOTSTATE_BUFFER_EMPTY) < 0) {
 			printk(KERN_ERR "dvb-ttpci: load_dram(): timeout at last block\n");
-			return -1;
+			return -ETIMEDOUT;
 		}
 		if (rest > 4)
 			mwdebi(av7110, DEBISWAB, bootblock,
@@ -185,13 +185,13 @@ static int load_dram(struct av7110 *av71
 	}
 	if (waitdebi(av7110, BOOT_STATE, BOOTSTATE_BUFFER_EMPTY) < 0) {
 		printk(KERN_ERR "dvb-ttpci: load_dram(): timeout after last block\n");
-		return -1;
+		return -ETIMEDOUT;
 	}
 	iwdebi(av7110, DEBINOSWAP, BOOT_SIZE, 0, 2);
 	iwdebi(av7110, DEBINOSWAP, BOOT_STATE, BOOTSTATE_BUFFER_FULL, 2);
 	if (waitdebi(av7110, BOOT_STATE, BOOTSTATE_BOOT_COMPLETE) < 0) {
 		printk(KERN_ERR "dvb-ttpci: load_dram(): final handshake timeout\n");
-		return -1;
+		return -ETIMEDOUT;
 	}
 	return 0;
 }
@@ -263,7 +263,7 @@ int av7110_bootarm(struct av7110 *av7110
 	if (saa7146_wait_for_debi_done(av7110->dev, 1)) {
 		printk(KERN_ERR "dvb-ttpci: av7110_bootarm(): "
 		       "saa7146_wait_for_debi_done() timed out\n");
-		return -1;
+		return -ETIMEDOUT;
 	}
 	saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTHI);
 	mdelay(1);
@@ -284,7 +284,7 @@ int av7110_bootarm(struct av7110 *av7110
 	if (saa7146_wait_for_debi_done(av7110->dev, 1)) {
 		printk(KERN_ERR "dvb-ttpci: av7110_bootarm(): "
 		       "saa7146_wait_for_debi_done() timed out after loading DRAM\n");
-		return -1;
+		return -ETIMEDOUT;
 	}
 	saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTHI);
 	msleep(30);	/* the firmware needs some time to initialize */
@@ -308,6 +308,7 @@ int av7110_wait_msgstate(struct av7110 *
 {
 	unsigned long start;
 	u32 stat;
+	int err;
 
 	if (FW_VERSION(av7110->arm_app) <= 0x261c) {
 		/* not supported by old firmware */
@@ -318,17 +319,17 @@ int av7110_wait_msgstate(struct av7110 *
 	/* new firmware */
 	start = jiffies;
 	for (;;) {
+		err = time_after(jiffies, start + ARM_WAIT_FREE);
 		if (down_interruptible(&av7110->dcomlock))
 			return -ERESTARTSYS;
 		stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2);
 		up(&av7110->dcomlock);
-		if ((stat & flags) == 0) {
+		if ((stat & flags) == 0)
 			break;
-		}
-		if (time_after(jiffies, start + ARM_WAIT_FREE)) {
+		if (err) {
 			printk(KERN_ERR "%s: timeout waiting for MSGSTATE %04x\n",
 				__FUNCTION__, stat & flags);
-			return -1;
+			return -ETIMEDOUT;
 		}
 		msleep(1);
 	}
@@ -342,6 +343,7 @@ static int __av7110_send_fw_cmd(struct a
 	char *type = NULL;
 	u16 flags[2] = {0, 0};
 	u32 stat;
+	int err;
 
 //	dprintk(4, "%p\n", av7110);
 
@@ -351,24 +353,30 @@ static int __av7110_send_fw_cmd(struct a
 	}
 
 	start = jiffies;
-	while (rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2 )) {
-		msleep(1);
-		if (time_after(jiffies, start + ARM_WAIT_FREE)) {
+	while (1) {
+		err = time_after(jiffies, start + ARM_WAIT_FREE);
+		if (rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2) == 0)
+			break;
+		if (err) {
 			printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for COMMAND idle\n", __FUNCTION__);
 			return -ETIMEDOUT;
 		}
+		msleep(1);
 	}
 
 	wdebi(av7110, DEBINOSWAP, COM_IF_LOCK, 0xffff, 2);
 
 #ifndef _NOHANDSHAKE
 	start = jiffies;
-	while (rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2 )) {
-		msleep(1);
-		if (time_after(jiffies, start + ARM_WAIT_SHAKE)) {
+	while (1) {
+		err = time_after(jiffies, start + ARM_WAIT_SHAKE);
+		if (rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2) == 0)
+			break;
+		if (err) {
 			printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for HANDSHAKE_REG\n", __FUNCTION__);
 			return -ETIMEDOUT;
 		}
+		msleep(1);
 	}
 #endif
 
@@ -401,6 +409,7 @@ static int __av7110_send_fw_cmd(struct a
 		/* non-immediate COMMAND type */
 		start = jiffies;
 		for (;;) {
+			err = time_after(jiffies, start + ARM_WAIT_FREE);
 			stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2);
 			if (stat & flags[0]) {
 				printk(KERN_ERR "%s: %s QUEUE overflow\n",
@@ -409,10 +418,10 @@ static int __av7110_send_fw_cmd(struct a
 			}
 			if ((stat & flags[1]) == 0)
 				break;
-			if (time_after(jiffies, start + ARM_WAIT_FREE)) {
+			if (err) {
 				printk(KERN_ERR "%s: timeout waiting on busy %s QUEUE\n",
 					__FUNCTION__, type);
-				return -1;
+				return -ETIMEDOUT;
 			}
 			msleep(1);
 		}
@@ -432,13 +441,16 @@ static int __av7110_send_fw_cmd(struct a
 
 #ifdef COM_DEBUG
 	start = jiffies;
-	while (rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2 )) {
-		msleep(1);
-		if (time_after(jiffies, start + ARM_WAIT_FREE)) {
-			printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for COMMAND to complete\n",
-			       __FUNCTION__);
+	while (1) {
+		err = time_after(jiffies, start + ARM_WAIT_FREE);
+		if (rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2) == 0)
+			break;
+		if (err) {
+			printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for COMMAND %d to complete\n",
+			       __FUNCTION__, (buf[0] >> 8) & 0xff);
 			return -ETIMEDOUT;
 		}
+		msleep(1);
 	}
 
 	stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2);
@@ -470,7 +482,7 @@ static int av7110_send_fw_cmd(struct av7
 
 	ret = __av7110_send_fw_cmd(av7110, buf, length);
 	up(&av7110->dcomlock);
-	if (ret)
+	if (ret && ret!=-ERESTARTSYS)
 		printk(KERN_ERR "dvb-ttpci: %s(): av7110_send_fw_cmd error %d\n",
 		       __FUNCTION__, ret);
 	return ret;
@@ -495,7 +507,7 @@ int av7110_fw_cmd(struct av7110 *av7110,
 	}
 
 	ret = av7110_send_fw_cmd(av7110, buf, num + 2);
-	if (ret)
+	if (ret && ret != -ERESTARTSYS)
 		printk(KERN_ERR "dvb-ttpci: av7110_fw_cmd error %d\n", ret);
 	return ret;
 }
@@ -518,7 +530,7 @@ int av7110_send_ci_cmd(struct av7110 *av
 	}
 
 	ret = av7110_send_fw_cmd(av7110, cmd, 18);
-	if (ret)
+	if (ret && ret != -ERESTARTSYS)
 		printk(KERN_ERR "dvb-ttpci: av7110_send_ci_cmd error %d\n", ret);
 	return ret;
 }
@@ -551,26 +563,32 @@ int av7110_fw_request(struct av7110 *av7
 	}
 
 	start = jiffies;
-	while (rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2)) {
-#ifdef _NOHANDSHAKE
-		msleep(1);
-#endif
-		if (time_after(jiffies, start + ARM_WAIT_FREE)) {
+	while (1) {
+		err = time_after(jiffies, start + ARM_WAIT_FREE);
+		if (rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2) == 0)
+			break;
+		if (err) {
 			printk(KERN_ERR "%s: timeout waiting for COMMAND to complete\n", __FUNCTION__);
 			up(&av7110->dcomlock);
-			return -1;
+			return -ETIMEDOUT;
 		}
+#ifdef _NOHANDSHAKE
+		msleep(1);
+#endif
 	}
 
 #ifndef _NOHANDSHAKE
 	start = jiffies;
-	while (rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2 )) {
-		msleep(1);
-		if (time_after(jiffies, start + ARM_WAIT_SHAKE)) {
+	while (1) {
+		err = time_after(jiffies, start + ARM_WAIT_SHAKE);
+		if (rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2) == 0)
+			break;
+		if (err) {
 			printk(KERN_ERR "%s: timeout waiting for HANDSHAKE_REG\n", __FUNCTION__);
 			up(&av7110->dcomlock);
-			return -1;
+			return -ETIMEDOUT;
 		}
+		msleep(1);
 	}
 #endif
 
@@ -667,10 +685,10 @@ int av7110_diseqc_send(struct av7110 *av
 	for (i = 0; i < len; i++)
 		buf[i + 4] = msg[i];
 
-	if ((ret = av7110_send_fw_cmd(av7110, buf, 18)))
+	ret = av7110_send_fw_cmd(av7110, buf, 18);
+	if (ret && ret!=-ERESTARTSYS)
 		printk(KERN_ERR "dvb-ttpci: av7110_diseqc_send error %d\n", ret);
-
-	return 0;
+	return ret;
 }
 
 
@@ -705,18 +723,22 @@ static inline int SetFont(struct av7110 
 static int FlushText(struct av7110 *av7110)
 {
 	unsigned long start;
+	int err;
 
 	if (down_interruptible(&av7110->dcomlock))
 		return -ERESTARTSYS;
 	start = jiffies;
-	while (rdebi(av7110, DEBINOSWAP, BUFF1_BASE, 0, 2)) {
-		msleep(1);
-		if (time_after(jiffies, start + ARM_WAIT_OSD)) {
+	while (1) {
+		err = time_after(jiffies, start + ARM_WAIT_OSD);
+		if (rdebi(av7110, DEBINOSWAP, BUFF1_BASE, 0, 2) == 0)
+			break;
+		if (err) {
 			printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for BUFF1_BASE == 0\n",
 			       __FUNCTION__);
 			up(&av7110->dcomlock);
-			return -1;
+			return -ETIMEDOUT;
 		}
+		msleep(1);
 	}
 	up(&av7110->dcomlock);
 	return 0;
@@ -733,25 +755,31 @@ static int WriteText(struct av7110 *av71
 		return -ERESTARTSYS;
 
 	start = jiffies;
-	while (rdebi(av7110, DEBINOSWAP, BUFF1_BASE, 0, 2)) {
-		msleep(1);
-		if (time_after(jiffies, start + ARM_WAIT_OSD)) {
+	while (1) {
+		ret = time_after(jiffies, start + ARM_WAIT_OSD);
+		if (rdebi(av7110, DEBINOSWAP, BUFF1_BASE, 0, 2) == 0)
+			break;
+		if (ret) {
 			printk(KERN_ERR "dvb-ttpci: %s: timeout waiting for BUFF1_BASE == 0\n",
 			       __FUNCTION__);
 			up(&av7110->dcomlock);
-			return -1;
+			return -ETIMEDOUT;
 		}
+		msleep(1);
 	}
 #ifndef _NOHANDSHAKE
 	start = jiffies;
-	while (rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2)) {
-		msleep(1);
-		if (time_after(jiffies, start + ARM_WAIT_SHAKE)) {
+	while (1) {
+		ret = time_after(jiffies, start + ARM_WAIT_SHAKE);
+		if (rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2) == 0)
+			break;
+		if (ret) {
 			printk(KERN_ERR "dvb-ttpci: %s: timeout waiting for HANDSHAKE_REG\n",
 			       __FUNCTION__);
 			up(&av7110->dcomlock);
-			return -1;
+			return -ETIMEDOUT;
 		}
+		msleep(1);
 	}
 #endif
 	for (i = 0; i < length / 2; i++)
@@ -761,7 +789,7 @@ static int WriteText(struct av7110 *av71
 		wdebi(av7110, DEBINOSWAP, BUFF1_BASE + i * 2, 0, 2);
 	ret = __av7110_send_fw_cmd(av7110, cbuf, 5);
 	up(&av7110->dcomlock);
-	if (ret)
+	if (ret && ret!=-ERESTARTSYS)
 		printk(KERN_ERR "dvb-ttpci: WriteText error %d\n", ret);
 	return ret;
 }
@@ -816,9 +844,25 @@ static osd_raw_window_t bpp2bit[8] = {
 	OSD_BITMAP1, OSD_BITMAP2, 0, OSD_BITMAP4, 0, 0, 0, OSD_BITMAP8
 };
 
-static inline int LoadBitmap(struct av7110 *av7110, u16 format,
+static inline int WaitUntilBmpLoaded(struct av7110 *av7110)
+{
+	int ret = wait_event_interruptible_timeout(av7110->bmpq,
+				av7110->bmp_state != BMP_LOADING, 10*HZ);
+	if (ret == -ERESTARTSYS)
+		return ret;
+	if (ret == 0) {
+		printk("dvb-ttpci: warning: timeout waiting in LoadBitmap: %d, %d\n",
+		       ret, av7110->bmp_state);
+		av7110->bmp_state = BMP_NONE;
+		return -ETIMEDOUT;
+	}
+	return 0;
+}
+
+static inline int LoadBitmap(struct av7110 *av7110,
 			     u16 dx, u16 dy, int inc, u8 __user * data)
 {
+	u16 format;
 	int bpp;
 	int i;
 	int d, delta;
@@ -827,14 +871,7 @@ static inline int LoadBitmap(struct av71
 
 	dprintk(4, "%p\n", av7110);
 
-	ret = wait_event_interruptible_timeout(av7110->bmpq, av7110->bmp_state != BMP_LOADING, HZ);
-	if (ret == -ERESTARTSYS || ret == 0) {
-		printk("dvb-ttpci: warning: timeout waiting in LoadBitmap: %d, %d\n",
-		       ret, av7110->bmp_state);
-		av7110->bmp_state = BMP_NONE;
-		return -1;
-	}
-	BUG_ON (av7110->bmp_state == BMP_LOADING);
+	format = bpp2bit[av7110->osdbpp[av7110->osdwin]];
 
 	av7110->bmp_state = BMP_LOADING;
 	if	(format == OSD_BITMAP8) {
@@ -847,18 +884,18 @@ static inline int LoadBitmap(struct av71
 		bpp=1; delta = 8;
 	} else {
 		av7110->bmp_state = BMP_NONE;
-		return -1;
+		return -EINVAL;
 	}
 	av7110->bmplen = ((dx * dy * bpp + 7) & ~7) / 8;
 	av7110->bmpp = 0;
 	if (av7110->bmplen > 32768) {
 		av7110->bmp_state = BMP_NONE;
-		return -1;
+		return -EINVAL;
 	}
 	for (i = 0; i < dy; i++) {
 		if (copy_from_user(av7110->bmpbuf + 1024 + i * dx, data + i * inc, dx)) {
 			av7110->bmp_state = BMP_NONE;
-			return -1;
+			return -EINVAL;
 		}
 	}
 	if (format != OSD_BITMAP8) {
@@ -873,37 +910,27 @@ static inline int LoadBitmap(struct av71
 	}
 	av7110->bmplen += 1024;
 	dprintk(4, "av7110_fw_cmd: LoadBmp size %d\n", av7110->bmplen);
-	return av7110_fw_cmd(av7110, COMTYPE_OSD, LoadBmp, 3, format, dx, dy);
+	ret = av7110_fw_cmd(av7110, COMTYPE_OSD, LoadBmp, 3, format, dx, dy);
+	if (!ret)
+		ret = WaitUntilBmpLoaded(av7110);
+	return ret;
 }
 
-static int BlitBitmap(struct av7110 *av7110, u16 win, u16 x, u16 y, u16 trans)
+static int BlitBitmap(struct av7110 *av7110, u16 x, u16 y)
 {
-	int ret;
-
 	dprintk(4, "%p\n", av7110);
 
-	BUG_ON (av7110->bmp_state == BMP_NONE);
-
-	ret = wait_event_interruptible_timeout(av7110->bmpq,
-				av7110->bmp_state != BMP_LOADING, 10*HZ);
-	if (ret == -ERESTARTSYS || ret == 0) {
-		printk("dvb-ttpci: warning: timeout waiting in BlitBitmap: %d, %d\n",
-		       ret, av7110->bmp_state);
-		av7110->bmp_state = BMP_NONE;
-		return (ret == 0) ? -ETIMEDOUT : ret;
-	}
-
-	BUG_ON (av7110->bmp_state != BMP_LOADED);
-
-	return av7110_fw_cmd(av7110, COMTYPE_OSD, BlitBmp, 4, win, x, y, trans);
+	return av7110_fw_cmd(av7110, COMTYPE_OSD, BlitBmp, 4, av7110->osdwin, x, y, 0);
 }
 
 static inline int ReleaseBitmap(struct av7110 *av7110)
 {
 	dprintk(4, "%p\n", av7110);
 
-	if (av7110->bmp_state != BMP_LOADED)
+	if (av7110->bmp_state != BMP_LOADED && FW_VERSION(av7110->arm_app) < 0x261e)
 		return -1;
+	if (av7110->bmp_state == BMP_LOADING)
+		dprintk(1,"ReleaseBitmap called while BMP_LOADING\n");
 	av7110->bmp_state = BMP_NONE;
 	return av7110_fw_cmd(av7110, COMTYPE_OSD, ReleaseBmp, 0);
 }
@@ -924,18 +951,22 @@ static u32 RGB2YUV(u16 R, u16 G, u16 B)
 	return Cr | (Cb << 16) | (Y << 8);
 }
 
-static void OSDSetColor(struct av7110 *av7110, u8 color, u8 r, u8 g, u8 b, u8 blend)
+static int OSDSetColor(struct av7110 *av7110, u8 color, u8 r, u8 g, u8 b, u8 blend)
 {
+	int ret;
+
 	u16 ch, cl;
 	u32 yuv;
 
 	yuv = blend ? RGB2YUV(r,g,b) : 0;
 	cl = (yuv & 0xffff);
 	ch = ((yuv >> 16) & 0xffff);
-	SetColor_(av7110, av7110->osdwin, bpp2pal[av7110->osdbpp[av7110->osdwin]],
-		  color, ch, cl);
-	SetBlend_(av7110, av7110->osdwin, bpp2pal[av7110->osdbpp[av7110->osdwin]],
-		  color, ((blend >> 4) & 0x0f));
+	ret = SetColor_(av7110, av7110->osdwin, bpp2pal[av7110->osdbpp[av7110->osdwin]],
+			color, ch, cl);
+	if (!ret)
+		ret = SetBlend_(av7110, av7110->osdwin, bpp2pal[av7110->osdbpp[av7110->osdwin]],
+				color, ((blend >> 4) & 0x0f));
+	return ret;
 }
 
 static int OSDSetPalette(struct av7110 *av7110, u32 __user * colors, u8 first, u8 last)
@@ -968,14 +999,14 @@ static int OSDSetBlock(struct av7110 *av
 {
 	uint w, h, bpp, bpl, size, lpb, bnum, brest;
 	int i;
-	int rc;
+	int rc,release_rc;
 
 	w = x1 - x0 + 1;
 	h = y1 - y0 + 1;
 	if (inc <= 0)
 		inc = w;
 	if (w <= 0 || w > 720 || h <= 0 || h > 576)
-		return -1;
+		return -EINVAL;
 	bpp = av7110->osdbpp[av7110->osdwin] + 1;
 	bpl = ((w * bpp + 7) & ~7) / 8;
 	size = h * bpl;
@@ -983,176 +1014,186 @@ static int OSDSetBlock(struct av7110 *av
 	bnum = size / (lpb * bpl);
 	brest = size - bnum * lpb * bpl;
 
-	for (i = 0; i < bnum; i++) {
-		rc = LoadBitmap(av7110, bpp2bit[av7110->osdbpp[av7110->osdwin]],
-			   w, lpb, inc, data);
-		if (rc)
-			return rc;
-		rc = BlitBitmap(av7110, av7110->osdwin, x0, y0 + i * lpb, 0);
+	if (av7110->bmp_state == BMP_LOADING) {
+		/* possible if syscall is repeated by -ERESTARTSYS and if firmware cannot abort */
+		BUG_ON (FW_VERSION(av7110->arm_app) >= 0x261e);
+		rc = WaitUntilBmpLoaded(av7110);
 		if (rc)
 			return rc;
-		data += lpb * inc;
+		/* just continue. This should work for all fw versions
+		 * if bnum==1 && !brest && LoadBitmap was successful
+		 */
 	}
-	if (brest) {
-		rc = LoadBitmap(av7110, bpp2bit[av7110->osdbpp[av7110->osdwin]],
-			   w, brest / bpl, inc, data);
+
+	rc = 0;
+	for (i = 0; i < bnum; i++) {
+		rc = LoadBitmap(av7110, w, lpb, inc, data);
 		if (rc)
-			return rc;
-		rc = BlitBitmap(av7110, av7110->osdwin, x0, y0 + bnum * lpb, 0);
+			break;
+		rc = BlitBitmap(av7110, x0, y0 + i * lpb);
 		if (rc)
-			return rc;
+			break;
+		data += lpb * inc;
 	}
-	ReleaseBitmap(av7110);
-	return 0;
+	if (!rc && brest) {
+		rc = LoadBitmap(av7110, w, brest / bpl, inc, data);
+		if (!rc)
+			rc = BlitBitmap(av7110, x0, y0 + bnum * lpb);
+	}
+	release_rc = ReleaseBitmap(av7110);
+	if (!rc)
+		rc = release_rc;
+	if (rc)
+		dprintk(1,"returns %d\n",rc);
+	return rc;
 }
 
 int av7110_osd_cmd(struct av7110 *av7110, osd_cmd_t *dc)
 {
 	int ret;
 
-	ret = down_interruptible(&av7110->osd_sema);
-	if (ret)
+	if (down_interruptible(&av7110->osd_sema))
 		return -ERESTARTSYS;
 
-	/* stupid, but OSD functions don't provide a return code anyway */
-	ret = 0;
-
 	switch (dc->cmd) {
 	case OSD_Close:
-		DestroyOSDWindow(av7110, av7110->osdwin);
-		goto out;
+		ret = DestroyOSDWindow(av7110, av7110->osdwin);
+		break;
 	case OSD_Open:
 		av7110->osdbpp[av7110->osdwin] = (dc->color - 1) & 7;
-		CreateOSDWindow(av7110, av7110->osdwin,
+		ret = CreateOSDWindow(av7110, av7110->osdwin,
 				bpp2bit[av7110->osdbpp[av7110->osdwin]],
 				dc->x1 - dc->x0 + 1, dc->y1 - dc->y0 + 1);
+		if (ret)
+			break;
 		if (!dc->data) {
-			MoveWindowAbs(av7110, av7110->osdwin, dc->x0, dc->y0);
-			SetColorBlend(av7110, av7110->osdwin);
+			ret = MoveWindowAbs(av7110, av7110->osdwin, dc->x0, dc->y0);
+			if (ret)
+				break;
+			ret = SetColorBlend(av7110, av7110->osdwin);
 		}
-		goto out;
+		break;
 	case OSD_Show:
-		MoveWindowRel(av7110, av7110->osdwin, 0, 0);
-		goto out;
+		ret = MoveWindowRel(av7110, av7110->osdwin, 0, 0);
+		break;
 	case OSD_Hide:
-		HideWindow(av7110, av7110->osdwin);
-		goto out;
+		ret = HideWindow(av7110, av7110->osdwin);
+		break;
 	case OSD_Clear:
-		DrawBlock(av7110, av7110->osdwin, 0, 0, 720, 576, 0);
-		goto out;
+		ret = DrawBlock(av7110, av7110->osdwin, 0, 0, 720, 576, 0);
+		break;
 	case OSD_Fill:
-		DrawBlock(av7110, av7110->osdwin, 0, 0, 720, 576, dc->color);
-		goto out;
+		ret = DrawBlock(av7110, av7110->osdwin, 0, 0, 720, 576, dc->color);
+		break;
 	case OSD_SetColor:
-		OSDSetColor(av7110, dc->color, dc->x0, dc->y0, dc->x1, dc->y1);
-		goto out;
+		ret = OSDSetColor(av7110, dc->color, dc->x0, dc->y0, dc->x1, dc->y1);
+		break;
 	case OSD_SetPalette:
-	{
-		if (FW_VERSION(av7110->arm_app) >= 0x2618) {
+		if (FW_VERSION(av7110->arm_app) >= 0x2618)
 			ret = OSDSetPalette(av7110, dc->data, dc->color, dc->x0);
-			goto out;
-		} else {
+		else {
 			int i, len = dc->x0-dc->color+1;
 			u8 __user *colors = (u8 __user *)dc->data;
 			u8 r, g, b, blend;
-
+			ret = 0;
 			for (i = 0; i<len; i++) {
 				if (get_user(r, colors + i * 4) ||
 				    get_user(g, colors + i * 4 + 1) ||
 				    get_user(b, colors + i * 4 + 2) ||
 				    get_user(blend, colors + i * 4 + 3)) {
 					ret = -EFAULT;
-					goto out;
+					break;
 				    }
-				OSDSetColor(av7110, dc->color + i, r, g, b, blend);
+				ret = OSDSetColor(av7110, dc->color + i, r, g, b, blend);
+				if (ret)
+					break;
 			}
 		}
-		ret = 0;
-		goto out;
-	}
-	case OSD_SetTrans:
-		goto out;
+		break;
 	case OSD_SetPixel:
-		DrawLine(av7110, av7110->osdwin,
+		ret = DrawLine(av7110, av7110->osdwin,
 			 dc->x0, dc->y0, 0, 0, dc->color);
-		goto out;
-	case OSD_GetPixel:
-		goto out;
+		break;
 	case OSD_SetRow:
 		dc->y1 = dc->y0;
 		/* fall through */
 	case OSD_SetBlock:
 		ret = OSDSetBlock(av7110, dc->x0, dc->y0, dc->x1, dc->y1, dc->color, dc->data);
-		goto out;
+		break;
 	case OSD_FillRow:
-		DrawBlock(av7110, av7110->osdwin, dc->x0, dc->y0,
+		ret = DrawBlock(av7110, av7110->osdwin, dc->x0, dc->y0,
 			  dc->x1-dc->x0+1, dc->y1, dc->color);
-		goto out;
+		break;
 	case OSD_FillBlock:
-		DrawBlock(av7110, av7110->osdwin, dc->x0, dc->y0,
+		ret = DrawBlock(av7110, av7110->osdwin, dc->x0, dc->y0,
 			  dc->x1 - dc->x0 + 1, dc->y1 - dc->y0 + 1, dc->color);
-		goto out;
+		break;
 	case OSD_Line:
-		DrawLine(av7110, av7110->osdwin,
+		ret = DrawLine(av7110, av7110->osdwin,
 			 dc->x0, dc->y0, dc->x1 - dc->x0, dc->y1 - dc->y0, dc->color);
-		goto out;
-	case OSD_Query:
-		goto out;
-	case OSD_Test:
-		goto out;
+		break;
 	case OSD_Text:
 	{
 		char textbuf[240];
 
 		if (strncpy_from_user(textbuf, dc->data, 240) < 0) {
 			ret = -EFAULT;
-			goto out;
+			break;
 		}
 		textbuf[239] = 0;
 		if (dc->x1 > 3)
 			dc->x1 = 3;
-		SetFont(av7110, av7110->osdwin, dc->x1,
+		ret = SetFont(av7110, av7110->osdwin, dc->x1,
 			(u16) (dc->color & 0xffff), (u16) (dc->color >> 16));
-		FlushText(av7110);
-		WriteText(av7110, av7110->osdwin, dc->x0, dc->y0, textbuf);
-		goto out;
+		if (!ret)
+			ret = FlushText(av7110);
+		if (!ret)
+			ret = WriteText(av7110, av7110->osdwin, dc->x0, dc->y0, textbuf);
+		break;
 	}
 	case OSD_SetWindow:
-		if (dc->x0 < 1 || dc->x0 > 7) {
+		if (dc->x0 < 1 || dc->x0 > 7)
 			ret = -EINVAL;
-			goto out;
+		else {
+			av7110->osdwin = dc->x0;
+			ret = 0;
 		}
-		av7110->osdwin = dc->x0;
-		goto out;
+		break;
 	case OSD_MoveWindow:
-		MoveWindowAbs(av7110, av7110->osdwin, dc->x0, dc->y0);
-		SetColorBlend(av7110, av7110->osdwin);
-		goto out;
+		ret = MoveWindowAbs(av7110, av7110->osdwin, dc->x0, dc->y0);
+		if (!ret)
+			ret = SetColorBlend(av7110, av7110->osdwin);
+		break;
 	case OSD_OpenRaw:
 		if (dc->color < OSD_BITMAP1 || dc->color > OSD_CURSOR) {
 			ret = -EINVAL;
-			goto out;
+			break;
 		}
-		if (dc->color >= OSD_BITMAP1 && dc->color <= OSD_BITMAP8HR) {
+		if (dc->color >= OSD_BITMAP1 && dc->color <= OSD_BITMAP8HR)
 			av7110->osdbpp[av7110->osdwin] = (1 << (dc->color & 3)) - 1;
-		}
-		else {
+		else
 			av7110->osdbpp[av7110->osdwin] = 0;
-		}
-		CreateOSDWindow(av7110, av7110->osdwin, (osd_raw_window_t)dc->color,
+		ret = CreateOSDWindow(av7110, av7110->osdwin, (osd_raw_window_t)dc->color,
 				dc->x1 - dc->x0 + 1, dc->y1 - dc->y0 + 1);
+		if (ret)
+			break;
 		if (!dc->data) {
-			MoveWindowAbs(av7110, av7110->osdwin, dc->x0, dc->y0);
-			SetColorBlend(av7110, av7110->osdwin);
+			ret = MoveWindowAbs(av7110, av7110->osdwin, dc->x0, dc->y0);
+			if (!ret)
+				ret = SetColorBlend(av7110, av7110->osdwin);
 		}
-		goto out;
+		break;
 	default:
 		ret = -EINVAL;
-		goto out;
+		break;
 	}
 
-out:
 	up(&av7110->osd_sema);
+	if (ret==-ERESTARTSYS)
+		dprintk(1, "av7110_osd_cmd(%d) returns with -ERESTARTSYS\n",dc->cmd);
+	else if (ret)
+		dprintk(1, "av7110_osd_cmd(%d) returns with %d\n",dc->cmd,ret);
+
 	return ret;
 }
 
diff --git a/drivers/media/dvb/ttpci/av7110_hw.h b/drivers/media/dvb/ttpci/av7110_hw.h
--- a/drivers/media/dvb/ttpci/av7110_hw.h
+++ b/drivers/media/dvb/ttpci/av7110_hw.h
@@ -458,27 +458,27 @@ static inline int SendDAC(struct av7110 
 	return av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, AudioDAC, 2, addr, data);
 }
 
-static inline void av7710_set_video_mode(struct av7110 *av7110, int mode)
+static inline int av7710_set_video_mode(struct av7110 *av7110, int mode)
 {
-	av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetVidMode, 1, mode);
+	return av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetVidMode, 1, mode);
 }
 
-static int inline vidcom(struct av7110 *av7110, u32 com, u32 arg)
+static inline int vidcom(struct av7110 *av7110, u32 com, u32 arg)
 {
 	return av7110_fw_cmd(av7110, COMTYPE_MISC, AV7110_FW_VIDEO_COMMAND, 4,
 			     (com>>16), (com&0xffff),
 			     (arg>>16), (arg&0xffff));
 }
 
-static int inline audcom(struct av7110 *av7110, u32 com)
+static inline int audcom(struct av7110 *av7110, u32 com)
 {
 	return av7110_fw_cmd(av7110, COMTYPE_MISC, AV7110_FW_AUDIO_COMMAND, 2,
 			     (com>>16), (com&0xffff));
 }
 
-static inline void Set22K(struct av7110 *av7110, int state)
+static inline int Set22K(struct av7110 *av7110, int state)
 {
-	av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, (state ? ON22K : OFF22K), 0);
+	return av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, (state ? ON22K : OFF22K), 0);
 }
 
 
diff --git a/drivers/media/dvb/ttpci/av7110_ipack.c b/drivers/media/dvb/ttpci/av7110_ipack.c
--- a/drivers/media/dvb/ttpci/av7110_ipack.c
+++ b/drivers/media/dvb/ttpci/av7110_ipack.c
@@ -24,7 +24,7 @@ int av7110_ipack_init(struct ipack *p, i
 		      void (*func)(u8 *buf, int size, void *priv))
 {
 	if (!(p->buf = vmalloc(size*sizeof(u8)))) {
-		printk ("Couldn't allocate memory for ipack\n");
+		printk(KERN_WARNING "Couldn't allocate memory for ipack\n");
 		return -ENOMEM;
 	}
 	p->size = size;
diff --git a/drivers/media/dvb/ttpci/budget-av.c b/drivers/media/dvb/ttpci/budget-av.c
--- a/drivers/media/dvb/ttpci/budget-av.c
+++ b/drivers/media/dvb/ttpci/budget-av.c
@@ -570,9 +570,9 @@ static int philips_cu1216_pll_set(struct
 
 	buf[0] = (div >> 8) & 0x7f;
 	buf[1] = div & 0xff;
-	buf[2] = 0x8e;
-	buf[3] = (params->frequency < 174500000 ? 0xa1 :
-		  params->frequency < 454000000 ? 0x92 : 0x34);
+	buf[2] = 0x86;
+	buf[3] = (params->frequency < 150000000 ? 0x01 :
+		  params->frequency < 445000000 ? 0x02 : 0x04);
 
 	if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1)
 		return -EIO;
@@ -695,8 +695,12 @@ static struct tda1004x_config philips_tu
 	.demod_address = 0x8,
 	.invert = 1,
 	.invert_oclk = 1,
+	.xtal_freq = TDA10046_XTAL_4M,
+	.agc_config = TDA10046_AGC_DEFAULT,
+	.if_freq = TDA10046_FREQ_3617,
 	.pll_init = philips_tu1216_pll_init,
 	.pll_set = philips_tu1216_pll_set,
+	.pll_sleep = NULL,
 	.request_firmware = philips_tu1216_request_firmware,
 };
 
@@ -1018,7 +1022,7 @@ static struct pci_device_id pci_tbl[] = 
 MODULE_DEVICE_TABLE(pci, pci_tbl);
 
 static struct saa7146_extension budget_extension = {
-	.name = "budget dvb /w video in\0",
+	.name = "budget_av",
 	.pci_tbl = pci_tbl,
 
 	.module = THIS_MODULE,
diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c
--- a/drivers/media/dvb/ttpci/budget-ci.c
+++ b/drivers/media/dvb/ttpci/budget-ci.c
@@ -69,6 +69,7 @@ struct budget_ci {
 	int slot_status;
 	struct dvb_ca_en50221 ca;
 	char ir_dev_name[50];
+	u8 tuner_pll_address; /* used for philips_tdm1316l configs */
 };
 
 /* from reading the following remotes:
@@ -723,7 +724,7 @@ static int philips_tdm1316l_pll_init(str
 	struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
 	static u8 td1316_init[] = { 0x0b, 0xf5, 0x85, 0xab };
 	static u8 disable_mc44BC374c[] = { 0x1d, 0x74, 0xa0, 0x68 };
-	struct i2c_msg tuner_msg = {.addr = 0x63,.flags = 0,.buf = td1316_init,.len =
+	struct i2c_msg tuner_msg = {.addr = budget_ci->tuner_pll_address,.flags = 0,.buf = td1316_init,.len =
 			sizeof(td1316_init) };
 
 	// setup PLL configuration
@@ -746,7 +747,7 @@ static int philips_tdm1316l_pll_set(stru
 {
 	struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
 	u8 tuner_buf[4];
-	struct i2c_msg tuner_msg = {.addr = 0x63,.flags = 0,.buf = tuner_buf,.len = sizeof(tuner_buf) };
+	struct i2c_msg tuner_msg = {.addr = budget_ci->tuner_pll_address,.flags = 0,.buf = tuner_buf,.len = sizeof(tuner_buf) };
 	int tuner_frequency = 0;
 	u8 band, cp, filter;
 
@@ -838,8 +839,12 @@ static struct tda1004x_config philips_td
 	.demod_address = 0x8,
 	.invert = 0,
 	.invert_oclk = 0,
+	.xtal_freq = TDA10046_XTAL_4M,
+	.agc_config = TDA10046_AGC_DEFAULT,
+	.if_freq = TDA10046_FREQ_3617,
 	.pll_init = philips_tdm1316l_pll_init,
 	.pll_set = philips_tdm1316l_pll_set,
+	.pll_sleep = NULL,
 	.request_firmware = philips_tdm1316l_request_firmware,
 };
 
@@ -865,12 +870,22 @@ static void frontend_init(struct budget_
 		break;
 
 	case 0x1011:		// Hauppauge/TT Nova-T budget (tda10045/Philips tdm1316l(tda6651tt) + TDA9889)
+		budget_ci->tuner_pll_address = 0x63;
 		budget_ci->budget.dvb_frontend =
 			tda10045_attach(&philips_tdm1316l_config, &budget_ci->budget.i2c_adap);
 		if (budget_ci->budget.dvb_frontend) {
 			break;
 		}
 		break;
+
+	case 0x1012:		// Hauppauge/TT Nova-T CI budget (tda10045/Philips tdm1316l(tda6651tt) + TDA9889)
+		budget_ci->tuner_pll_address = 0x60;
+		budget_ci->budget.dvb_frontend =
+			tda10046_attach(&philips_tdm1316l_config, &budget_ci->budget.i2c_adap);
+		if (budget_ci->budget.dvb_frontend) {
+			break;
+		}
+		break;
 	}
 
 	if (budget_ci->budget.dvb_frontend == NULL) {
@@ -950,11 +965,13 @@ static struct saa7146_extension budget_e
 
 MAKE_BUDGET_INFO(ttbci, "TT-Budget/WinTV-NOVA-CI PCI", BUDGET_TT_HW_DISEQC);
 MAKE_BUDGET_INFO(ttbt2, "TT-Budget/WinTV-NOVA-T	 PCI", BUDGET_TT);
+MAKE_BUDGET_INFO(ttbtci, "TT-Budget-T-CI PCI", BUDGET_TT);
 
 static struct pci_device_id pci_tbl[] = {
 	MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100c),
 	MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100f),
 	MAKE_EXTENSION_PCI(ttbt2, 0x13c2, 0x1011),
+	MAKE_EXTENSION_PCI(ttbtci, 0x13c2, 0x1012),
 	{
 	 .vendor = 0,
 	 }
diff --git a/drivers/media/dvb/ttpci/budget.c b/drivers/media/dvb/ttpci/budget.c
--- a/drivers/media/dvb/ttpci/budget.c
+++ b/drivers/media/dvb/ttpci/budget.c
@@ -40,6 +40,7 @@
 #include "ves1820.h"
 #include "l64781.h"
 #include "tda8083.h"
+#include "s5h1420.h"
 
 static void Set22K (struct budget *budget, int state)
 {
@@ -177,6 +178,62 @@ static int budget_diseqc_send_burst(stru
 	return 0;
 }
 
+static int lnbp21_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
+{
+	struct budget* budget = (struct budget*) fe->dvb->priv;
+	u8 buf;
+	struct i2c_msg msg = { .addr = 0x08, .flags = I2C_M_RD, .buf = &buf, .len = sizeof(buf) };
+
+	if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO;
+
+	switch(voltage) {
+	case SEC_VOLTAGE_13:
+		buf = (buf & 0xf7) | 0x04;
+		break;
+
+	case SEC_VOLTAGE_18:
+		buf = (buf & 0xf7) | 0x0c;
+		break;
+
+	case SEC_VOLTAGE_OFF:
+		buf = buf & 0xf0;
+		break;
+	}
+
+	msg.flags = 0;
+	if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO;
+
+	return 0;
+}
+
+static int lnbp21_enable_high_lnb_voltage(struct dvb_frontend* fe, int arg)
+{
+	struct budget* budget = (struct budget*) fe->dvb->priv;
+	u8 buf;
+	struct i2c_msg msg = { .addr = 0x08, .flags = I2C_M_RD, .buf = &buf, .len = sizeof(buf) };
+
+	if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO;
+
+	if (arg) {
+		buf = buf | 0x10;
+	} else {
+		buf = buf & 0xef;
+	}
+
+	msg.flags = 0;
+	if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO;
+
+	return 0;
+}
+
+static void lnbp21_init(struct budget* budget)
+{
+	u8 buf = 0x00;
+	struct i2c_msg msg = { .addr = 0x08, .flags = 0, .buf = &buf, .len = sizeof(buf) };
+
+	i2c_transfer (&budget->i2c_adap, &msg, 1);
+}
+
 static int alps_bsrv2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
 {
 	struct budget* budget = (struct budget*) fe->dvb->priv;
@@ -395,6 +452,38 @@ static struct tda8083_config grundig_295
 	.pll_set = grundig_29504_451_pll_set,
 };
 
+static int s5h1420_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u32* freqout)
+{
+	struct budget* budget = (struct budget*) fe->dvb->priv;
+	u32 div;
+	u8 data[4];
+	struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
+
+	div = params->frequency / 1000;
+	data[0] = (div >> 8) & 0x7f;
+	data[1] = div & 0xff;
+	data[2] = 0xc2;
+
+	if (div < 1450)
+		data[3] = 0x00;
+	else if (div < 1850)
+		data[3] = 0x40;
+	else if (div < 2000)
+		data[3] = 0x80;
+	else
+		data[3] = 0xc0;
+
+	if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO;
+
+	*freqout = div * 1000;
+	return 0;
+}
+
+static struct s5h1420_config s5h1420_config = {
+	.demod_address = 0x53,
+	.pll_set = s5h1420_pll_set,
+};
+
 static u8 read_pwm(struct budget* budget)
 {
 	u8 b = 0xff;
@@ -459,6 +548,15 @@ static void frontend_init(struct budget 
 			break;
 		}
 		break;
+
+	case 0x1016: // Hauppauge/TT Nova-S SE (samsung s5h1420/????(tda8260))
+		budget->dvb_frontend = s5h1420_attach(&s5h1420_config, &budget->i2c_adap);
+		if (budget->dvb_frontend) {
+			budget->dvb_frontend->ops->set_voltage = lnbp21_set_voltage;
+			budget->dvb_frontend->ops->enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage;
+			lnbp21_init(budget);
+			break;
+		}
 	}
 
 	if (budget->dvb_frontend == NULL) {
@@ -532,6 +630,7 @@ static struct pci_device_id pci_tbl[] = 
 	MAKE_EXTENSION_PCI(ttbc,  0x13c2, 0x1004),
 	MAKE_EXTENSION_PCI(ttbt,  0x13c2, 0x1005),
 	MAKE_EXTENSION_PCI(satel, 0x13c2, 0x1013),
+	MAKE_EXTENSION_PCI(ttbs,  0x13c2, 0x1016),
 	MAKE_EXTENSION_PCI(fsacs1,0x1131, 0x4f60),
 	MAKE_EXTENSION_PCI(fsacs0,0x1131, 0x4f61),
 	{
diff --git a/drivers/media/dvb/ttusb-budget/Kconfig b/drivers/media/dvb/ttusb-budget/Kconfig
--- a/drivers/media/dvb/ttusb-budget/Kconfig
+++ b/drivers/media/dvb/ttusb-budget/Kconfig
@@ -3,6 +3,7 @@ config DVB_TTUSB_BUDGET
 	depends on DVB_CORE && USB
 	select DVB_CX22700
 	select DVB_TDA1004X
+	select DVB_VES1820
 	select DVB_TDA8083
 	select DVB_STV0299
 	help
diff --git a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
--- a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
+++ b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
@@ -24,6 +24,7 @@
 #include "dmxdev.h"
 #include "dvb_demux.h"
 #include "dvb_net.h"
+#include "ves1820.h"
 #include "cx22700.h"
 #include "tda1004x.h"
 #include "stv0299.h"
@@ -1367,6 +1368,47 @@ static struct tda8083_config ttusb_novas
 	.pll_set = ttusb_novas_grundig_29504_491_pll_set,
 };
 
+static int alps_tdbe2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
+{
+	struct ttusb* ttusb = fe->dvb->priv;
+	u32 div;
+	u8 data[4];
+	struct i2c_msg msg = { .addr = 0x62, .flags = 0, .buf = data, .len = sizeof(data) };
+
+	div = (params->frequency + 35937500 + 31250) / 62500;
+
+	data[0] = (div >> 8) & 0x7f;
+	data[1] = div & 0xff;
+	data[2] = 0x85 | ((div >> 10) & 0x60);
+	data[3] = (params->frequency < 174000000 ? 0x88 : params->frequency < 470000000 ? 0x84 : 0x81);
+
+	if (i2c_transfer (&ttusb->i2c_adap, &msg, 1) != 1)
+		return -EIO;
+
+	return 0;
+}
+
+
+static struct ves1820_config alps_tdbe2_config = {
+	.demod_address = 0x09,
+	.xin = 57840000UL,
+	.invert = 1,
+	.selagc = VES1820_SELAGC_SIGNAMPERR,
+	.pll_set = alps_tdbe2_pll_set,
+};
+
+static u8 read_pwm(struct ttusb* ttusb)
+{
+	u8 b = 0xff;
+	u8 pwm;
+	struct i2c_msg msg[] = { { .addr = 0x50,.flags = 0,.buf = &b,.len = 1 },
+				{ .addr = 0x50,.flags = I2C_M_RD,.buf = &pwm,.len = 1} };
+
+	if ((i2c_transfer(&ttusb->i2c_adap, msg, 2) != 2) || (pwm == 0xff))
+		pwm = 0x48;
+
+	return pwm;
+}
 
 
 static void frontend_init(struct ttusb* ttusb)
@@ -1394,6 +1436,12 @@ static void frontend_init(struct ttusb* 
 
 		break;
 
+	case 0x1004: // Hauppauge/TT DVB-C budget (ves1820/ALPS TDBE2(sp5659))
+		ttusb->fe = ves1820_attach(&alps_tdbe2_config, &ttusb->i2c_adap, read_pwm(ttusb));
+		if (ttusb->fe != NULL)
+			break;
+		break;
+
 	case 0x1005: // Hauppauge/TT Nova-USB-t budget (tda10046/Philips td1316(tda6651tt) OR cx22700/ALPS TDMB7(??))
 		// try the ALPS TDMB7 first
 		ttusb->fe = cx22700_attach(&alps_tdmb7_config, &ttusb->i2c_adap);
@@ -1570,7 +1618,7 @@ static void ttusb_disconnect(struct usb_
 
 static struct usb_device_id ttusb_table[] = {
 	{USB_DEVICE(0xb48, 0x1003)},
-/*	{USB_DEVICE(0xb48, 0x1004)},UNDEFINED HARDWARE - mail linuxtv.org list*/	/* to be confirmed ????  */
+	{USB_DEVICE(0xb48, 0x1004)},
 	{USB_DEVICE(0xb48, 0x1005)},
 	{}
 };
@@ -1578,7 +1626,7 @@ static struct usb_device_id ttusb_table[
 MODULE_DEVICE_TABLE(usb, ttusb_table);
 
 static struct usb_driver ttusb_driver = {
-      .name		= "Technotrend/Hauppauge USB-Nova",
+      .name		= "ttusb",
       .probe		= ttusb_probe,
       .disconnect	= ttusb_disconnect,
       .id_table		= ttusb_table,
diff --git a/drivers/media/dvb/ttusb-dec/ttusb_dec.c b/drivers/media/dvb/ttusb-dec/ttusb_dec.c
--- a/drivers/media/dvb/ttusb-dec/ttusb_dec.c
+++ b/drivers/media/dvb/ttusb-dec/ttusb_dec.c
@@ -1281,6 +1281,7 @@ static int ttusb_dec_boot_dsp(struct ttu
 	if (firmware_size < 60) {
 		printk("%s: firmware size too small for DSP code (%zu < 60).\n",
 			__FUNCTION__, firmware_size);
+		release_firmware(fw_entry);
 		return -1;
 	}
 
@@ -1294,6 +1295,7 @@ static int ttusb_dec_boot_dsp(struct ttu
 		printk("%s: crc32 check of DSP code failed (calculated "
 		       "0x%08x != 0x%08x in file), file invalid.\n",
 			__FUNCTION__, crc32_csum, crc32_check);
+		release_firmware(fw_entry);
 		return -1;
 	}
 	memcpy(idstring, &firmware[36], 20);
@@ -1308,15 +1310,19 @@ static int ttusb_dec_boot_dsp(struct ttu
 
 	result = ttusb_dec_send_command(dec, 0x41, sizeof(b0), b0, NULL, NULL);
 
-	if (result)
+	if (result) {
+		release_firmware(fw_entry);
 		return result;
+	}
 
 	trans_count = 0;
 	j = 0;
 
 	b = kmalloc(ARM_PACKET_SIZE, GFP_KERNEL);
-	if (b == NULL)
+	if (b == NULL) {
+		release_firmware(fw_entry);
 		return -ENOMEM;
+	}
 
 	for (i = 0; i < firmware_size; i += COMMAND_PACKET_SIZE) {
 		size = firmware_size - i;
@@ -1345,6 +1351,7 @@ static int ttusb_dec_boot_dsp(struct ttu
 
 	result = ttusb_dec_send_command(dec, 0x43, sizeof(b1), b1, NULL, NULL);
 
+	release_firmware(fw_entry);
 	kfree(b);
 
 	return result;
diff --git a/drivers/media/dvb/ttusb-dec/ttusbdecfe.c b/drivers/media/dvb/ttusb-dec/ttusbdecfe.c
--- a/drivers/media/dvb/ttusb-dec/ttusbdecfe.c
+++ b/drivers/media/dvb/ttusb-dec/ttusbdecfe.c
@@ -157,7 +157,8 @@ struct dvb_frontend* ttusbdecfe_dvbt_att
 
 	/* allocate memory for the internal state */
 	state = (struct ttusbdecfe_state*) kmalloc(sizeof(struct ttusbdecfe_state), GFP_KERNEL);
-	if (state == NULL) goto error;
+	if (state == NULL)
+		return NULL;
 
 	/* setup the state */
 	state->config = config;
@@ -167,10 +168,6 @@ struct dvb_frontend* ttusbdecfe_dvbt_att
 	state->frontend.ops = &state->ops;
 	state->frontend.demodulator_priv = state;
 	return &state->frontend;
-
-error:
-	kfree(state);
-	return NULL;
 }
 
 static struct dvb_frontend_ops ttusbdecfe_dvbs_ops;
@@ -181,7 +178,8 @@ struct dvb_frontend* ttusbdecfe_dvbs_att
 
 	/* allocate memory for the internal state */
 	state = (struct ttusbdecfe_state*) kmalloc(sizeof(struct ttusbdecfe_state), GFP_KERNEL);
-	if (state == NULL) goto error;
+	if (state == NULL)
+		return NULL;
 
 	/* setup the state */
 	state->config = config;
@@ -193,10 +191,6 @@ struct dvb_frontend* ttusbdecfe_dvbs_att
 	state->frontend.ops = &state->ops;
 	state->frontend.demodulator_priv = state;
 	return &state->frontend;
-
-error:
-	kfree(state);
-	return NULL;
 }
 
 static struct dvb_frontend_ops ttusbdecfe_dvbt_ops = {
diff --git a/drivers/media/radio/radio-maestro.c b/drivers/media/radio/radio-maestro.c
--- a/drivers/media/radio/radio-maestro.c
+++ b/drivers/media/radio/radio-maestro.c
@@ -154,7 +154,7 @@ static void radio_bits_set(struct radio_
 	msleep(125);
 }
 
-inline static int radio_function(struct inode *inode, struct file *file,
+static inline int radio_function(struct inode *inode, struct file *file,
 				 unsigned int cmd, void *arg)
 {
 	struct video_device *dev = video_devdata(file);
@@ -283,7 +283,7 @@ static int __init maestro_radio_init(voi
 module_init(maestro_radio_init);
 module_exit(maestro_radio_exit);
 
-inline static __u16 radio_power_on(struct radio_device *dev)
+static inline __u16 radio_power_on(struct radio_device *dev)
 {
 	register __u16 io=dev->io;
 	register __u32 ofreq;
diff --git a/drivers/media/radio/radio-maxiradio.c b/drivers/media/radio/radio-maxiradio.c
--- a/drivers/media/radio/radio-maxiradio.c
+++ b/drivers/media/radio/radio-maxiradio.c
@@ -166,7 +166,7 @@ static int get_tune(__u16 io)
 }
 
 
-inline static int radio_function(struct inode *inode, struct file *file,
+static inline int radio_function(struct inode *inode, struct file *file,
 				 unsigned int cmd, void *arg)
 {
 	struct video_device *dev = video_devdata(file);
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -236,7 +236,7 @@ config VIDEO_MEYE
 
 config VIDEO_SAA7134
 	tristate "Philips SAA7134 support"
-	depends on VIDEO_DEV && PCI && I2C
+	depends on VIDEO_DEV && PCI && I2C && SOUND
 	select VIDEO_BUF
 	select VIDEO_IR
 	select VIDEO_TUNER
@@ -330,6 +330,8 @@ config VIDEO_CX88_DVB
 	select VIDEO_BUF_DVB
 	select DVB_MT352
 	select DVB_OR51132
+	select DVB_CX22702
+	select DVB_LGDT330X
 	---help---
 	  This adds support for DVB/ATSC cards based on the
 	  Connexant 2388x chip.
@@ -354,7 +356,7 @@ config VIDEO_M32R_AR
 
 config VIDEO_M32R_AR_M64278
 	tristate "Use Colour AR module M64278(VGA)"
-	depends on VIDEO_M32R_AR
+	depends on VIDEO_M32R_AR && PLAT_M32700UT
 	---help---
 	  Say Y here to use the Renesas M64278E-800 camera module,
 	  which supports VGA(640x480 pixcels) size of images.
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -7,8 +7,7 @@ bttv-objs	:=	bttv-driver.o bttv-cards.o 
 zoran-objs      :=	zr36120.o zr36120_i2c.o zr36120_mem.o
 zr36067-objs	:=	zoran_procfs.o zoran_device.o \
 			zoran_driver.o zoran_card.o
-tuner-objs	:=	tuner-core.o tuner-simple.o mt20xx.o tda8290.o
-
+tuner-objs	:=	tuner-core.o tuner-simple.o mt20xx.o tda8290.o tea5767.o
 obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-common.o v4l1-compat.o
 
 obj-$(CONFIG_VIDEO_BT848) += bttv.o msp3400.o tvaudio.o \
diff --git a/drivers/media/video/adv7170.c b/drivers/media/video/adv7170.c
--- a/drivers/media/video/adv7170.c
+++ b/drivers/media/video/adv7170.c
@@ -384,22 +384,14 @@ static unsigned short normal_i2c[] =
 	I2C_ADV7171 >> 1, (I2C_ADV7171 >> 1) + 1,
 	I2C_CLIENT_END
 };
-static unsigned short normal_i2c_range[] = { I2C_CLIENT_END };
 
-static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short probe_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short ignore_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short force[2] = { I2C_CLIENT_END , I2C_CLIENT_END };
+static unsigned short ignore = I2C_CLIENT_END;
                                                                                 
 static struct i2c_client_address_data addr_data = {
 	.normal_i2c		= normal_i2c,
-	.normal_i2c_range	= normal_i2c_range,
-	.probe			= probe,
-	.probe_range		= probe_range,
-	.ignore			= ignore,
-	.ignore_range		= ignore_range,
-	.force			= force
+	.probe			= &ignore,
+	.ignore			= &ignore,
+	.force			= &ignore,
 };
 
 static struct i2c_driver i2c_driver_adv7170;
diff --git a/drivers/media/video/adv7175.c b/drivers/media/video/adv7175.c
--- a/drivers/media/video/adv7175.c
+++ b/drivers/media/video/adv7175.c
@@ -434,22 +434,14 @@ static unsigned short normal_i2c[] =
 	I2C_ADV7176 >> 1, (I2C_ADV7176 >> 1) + 1,
 	I2C_CLIENT_END
 };
-static unsigned short normal_i2c_range[] = { I2C_CLIENT_END };
 
-static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short probe_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short ignore_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short force[2] = { I2C_CLIENT_END , I2C_CLIENT_END };
+static unsigned short ignore = I2C_CLIENT_END;
                                                                                 
 static struct i2c_client_address_data addr_data = {
 	.normal_i2c		= normal_i2c,
-	.normal_i2c_range	= normal_i2c_range,
-	.probe			= probe,
-	.probe_range		= probe_range,
-	.ignore			= ignore,
-	.ignore_range		= ignore_range,
-	.force			= force
+	.probe			= &ignore,
+	.ignore			= &ignore,
+	.force			= &ignore,
 };
 
 static struct i2c_driver i2c_driver_adv7175;
diff --git a/drivers/media/video/bt819.c b/drivers/media/video/bt819.c
--- a/drivers/media/video/bt819.c
+++ b/drivers/media/video/bt819.c
@@ -500,22 +500,14 @@ static unsigned short normal_i2c[] = {
 	I2C_BT819 >> 1,
 	I2C_CLIENT_END,
 };
-static unsigned short normal_i2c_range[] = { I2C_CLIENT_END };
 
-static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short probe_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short ignore_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short force[2] = { I2C_CLIENT_END , I2C_CLIENT_END };
+static unsigned short ignore = I2C_CLIENT_END;
                                                                                 
 static struct i2c_client_address_data addr_data = {
 	.normal_i2c		= normal_i2c,
-	.normal_i2c_range	= normal_i2c_range,
-	.probe			= probe,
-	.probe_range		= probe_range,
-	.ignore			= ignore,
-	.ignore_range		= ignore_range,
-	.force			= force
+	.probe			= &ignore,
+	.ignore			= &ignore,
+	.force			= &ignore,
 };
 
 static struct i2c_driver i2c_driver_bt819;
diff --git a/drivers/media/video/bt832.c b/drivers/media/video/bt832.c
--- a/drivers/media/video/bt832.c
+++ b/drivers/media/video/bt832.c
@@ -6,7 +6,7 @@
   It outputs an 8-bit 4:2:2 YUV or YCrCb video signal which can be directly
   connected to bt848/bt878 GPIO pins on this purpose.
   (see: VLSI Vision Ltd. www.vvl.co.uk for camera datasheets)
-  
+
   Supported Cards:
   -  Pixelview Rev.4E: 0x8a
 		GPIO 0x400000 toggles Bt832 RESET, and the chip changes to i2c 0x88 !
@@ -31,16 +31,16 @@
 #include <linux/errno.h>
 #include <linux/slab.h>
 
-#include "id.h"
-#include "audiochip.h"
+#include <media/audiochip.h>
+#include <media/id.h>
 #include "bttv.h"
 #include "bt832.h"
 
 MODULE_LICENSE("GPL");
 
 /* Addresses to scan */
-static unsigned short normal_i2c[] = {I2C_CLIENT_END};
-static unsigned short normal_i2c_range[] = {I2C_BT832_ALT1>>1,I2C_BT832_ALT2>>1,I2C_CLIENT_END};
+static unsigned short normal_i2c[] = { I2C_BT832_ALT1>>1, I2C_BT832_ALT2>>1,
+				       I2C_CLIENT_END };
 I2C_CLIENT_INSMOD;
 
 /* ---------------------------------------------------------------------- */
@@ -95,7 +95,7 @@ int bt832_init(struct i2c_client *i2c_cl
 
 	buf=kmalloc(65,GFP_KERNEL);
 	bt832_hexdump(i2c_client_s,buf);
-	
+
 	if(buf[0x40] != 0x31) {
 		printk("bt832: this i2c chip is no bt832 (id=%02x). Detaching.\n",buf[0x40]);
 		kfree(buf);
@@ -135,28 +135,16 @@ int bt832_init(struct i2c_client *i2c_cl
 	buf[1]= 0x27 & (~0x01); // Default | !skip
 	if (2 != (rc = i2c_master_send(i2c_client_s,buf,2)))
                 printk("bt832: i2c i/o error EO: rc == %d (should be 2)\n",rc);
-	
-        bt832_hexdump(i2c_client_s,buf);
-
-#if 0
-	// Full 30/25 Frame rate
-	printk("Full 30/25 Frame rate\n");
-	buf[0]=BT832_VP_CONTROL0; // Reg.39
-        buf[1]= 0x00;
-        if (2 != (rc = i2c_master_send(i2c_client_s,buf,2)))
-                printk("bt832: i2c i/o error FFR: rc == %d (should be 2)\n",rc);
 
         bt832_hexdump(i2c_client_s,buf);
-#endif
 
-#if 1
+
 	// for testing (even works when no camera attached)
 	printk("bt832: *** Generate NTSC M Bars *****\n");
 	buf[0]=BT832_VP_TESTCONTROL0; // Reg. 42
 	buf[1]=3; // Generate NTSC System M bars, Generate Frame timing internally
         if (2 != (rc = i2c_master_send(i2c_client_s,buf,2)))
                 printk("bt832: i2c i/o error MBAR: rc == %d (should be 2)\n",rc);
-#endif
 
 	printk("Bt832: Camera Present: %s\n",
 		(buf[1+BT832_CAM_STATUS] & BT832_56_CAMERA_PRESENT) ? "yes":"no");
@@ -168,8 +156,7 @@ int bt832_init(struct i2c_client *i2c_cl
 
 
 
-static int bt832_attach(struct i2c_adapter *adap, int addr,
-			  unsigned short flags, int kind)
+static int bt832_attach(struct i2c_adapter *adap, int addr, int kind)
 {
 	struct bt832 *t;
 
@@ -184,27 +171,32 @@ static int bt832_attach(struct i2c_adapt
                 return -ENOMEM;
 	memset(t,0,sizeof(*t));
 	t->client = client_template;
-        t->client.data = t;
+        i2c_set_clientdata(&t->client, t);
         i2c_attach_client(&t->client);
 
 	if(! bt832_init(&t->client)) {
 		bt832_detach(&t->client);
 		return -1;
 	}
-        
+
 	return 0;
 }
 
 static int bt832_probe(struct i2c_adapter *adap)
 {
+#ifdef I2C_CLASS_TV_ANALOG
 	if (adap->class & I2C_CLASS_TV_ANALOG)
 		return i2c_probe(adap, &addr_data, bt832_attach);
+#else
+	if (adap->id == (I2C_ALGO_BIT | I2C_HW_B_BT848))
+		return i2c_probe(adap, &addr_data, bt832_attach);
+#endif
 	return 0;
 }
 
 static int bt832_detach(struct i2c_client *client)
 {
-	struct bt832 *t = (struct bt832*)client->data;
+	struct bt832 *t = i2c_get_clientdata(client);
 
 	printk("bt832: detach.\n");
 	i2c_detach_client(client);
@@ -215,7 +207,7 @@ static int bt832_detach(struct i2c_clien
 static int
 bt832_command(struct i2c_client *client, unsigned int cmd, void *arg)
 {
-	struct bt832 *t = (struct bt832*)client->data;
+	struct bt832 *t = i2c_get_clientdata(client);
 
 	printk("bt832: command %x\n",cmd);
 
@@ -249,19 +241,18 @@ static struct i2c_driver driver = {
 };
 static struct i2c_client client_template =
 {
-        .name   = "bt832",
-	.flags  = I2C_CLIENT_ALLOW_USE,
-        .driver = &driver,
+	I2C_DEVNAME("bt832"),
+	.flags      = I2C_CLIENT_ALLOW_USE,
+        .driver     = &driver,
 };
 
 
-int bt832_init_module(void)
+static int __init bt832_init_module(void)
 {
-	i2c_add_driver(&driver);
-	return 0;
+	return i2c_add_driver(&driver);
 }
 
-static void bt832_cleanup_module(void)
+static void __exit bt832_cleanup_module(void)
 {
 	i2c_del_driver(&driver);
 }
@@ -269,3 +260,10 @@ static void bt832_cleanup_module(void)
 module_init(bt832_init_module);
 module_exit(bt832_cleanup_module);
 
+/*
+ * Overrides for Emacs so that we follow Linus's tabbing style.
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/drivers/media/video/bt832.h b/drivers/media/video/bt832.h
--- a/drivers/media/video/bt832.h
+++ b/drivers/media/video/bt832.h
@@ -1,6 +1,6 @@
 /* Bt832 CMOS Camera Video Processor (VP)
 
- The Bt832 CMOS Camera Video Processor chip connects a Quartsight CMOS 
+ The Bt832 CMOS Camera Video Processor chip connects a Quartsight CMOS
   color digital camera directly to video capture devices via an 8-bit,
   4:2:2 YUV or YCrCb video interface.
 
@@ -85,7 +85,7 @@
 #define BT832_DEVICE_ID		63
 # define BT832_DEVICE_ID__31		0x31 // Bt832 has ID 0x31
 
-/* STMicroelectronivcs VV5404 camera module 
+/* STMicroelectronivcs VV5404 camera module
    i2c: 0x20: sensor address
    i2c: 0xa0: eeprom for ccd defect map
  */
@@ -256,26 +256,26 @@ For the CCIR-601 standards, the sampling
 //===========================================================================
 // Timing generator SRAM table values for CCIR601 720x480 NTSC
 //===========================================================================
-// For NTSC CCIR656 
+// For NTSC CCIR656
 BYTE BtCard::SRAMTable_NTSC[] =
 {
     // SRAM Timing Table for NTSC
-    0x0c, 0xc0, 0x00, 
-    0x00, 0x90, 0xc2, 
-    0x03, 0x10, 0x03, 
-    0x06, 0x10, 0x34, 
-    0x12, 0x12, 0x65, 
-    0x02, 0x13, 0x24, 
-    0x19, 0x00, 0x24, 
-    0x39, 0x00, 0x96, 
-    0x59, 0x08, 0x93, 
+    0x0c, 0xc0, 0x00,
+    0x00, 0x90, 0xc2,
+    0x03, 0x10, 0x03,
+    0x06, 0x10, 0x34,
+    0x12, 0x12, 0x65,
+    0x02, 0x13, 0x24,
+    0x19, 0x00, 0x24,
+    0x39, 0x00, 0x96,
+    0x59, 0x08, 0x93,
     0x83, 0x08, 0x97,
-    0x03, 0x50, 0x30, 
-    0xc0, 0x40, 0x30, 
-    0x86, 0x01, 0x01, 
-    0xa6, 0x0d, 0x62, 
-    0x03, 0x11, 0x61, 
-    0x05, 0x37, 0x30, 
+    0x03, 0x50, 0x30,
+    0xc0, 0x40, 0x30,
+    0x86, 0x01, 0x01,
+    0xa6, 0x0d, 0x62,
+    0x03, 0x11, 0x61,
+    0x05, 0x37, 0x30,
     0xac, 0x21, 0x50
 };
 
diff --git a/drivers/media/video/bt856.c b/drivers/media/video/bt856.c
--- a/drivers/media/video/bt856.c
+++ b/drivers/media/video/bt856.c
@@ -288,22 +288,14 @@ bt856_command (struct i2c_client *client
  * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
  */
 static unsigned short normal_i2c[] = { I2C_BT856 >> 1, I2C_CLIENT_END };
-static unsigned short normal_i2c_range[] = { I2C_CLIENT_END };
 
-static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short probe_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short ignore_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short force[2] = { I2C_CLIENT_END , I2C_CLIENT_END };
+static unsigned short ignore = I2C_CLIENT_END;
                                                                                 
 static struct i2c_client_address_data addr_data = {
 	.normal_i2c		= normal_i2c,
-	.normal_i2c_range	= normal_i2c_range,
-	.probe			= probe,
-	.probe_range		= probe_range,
-	.ignore			= ignore,
-	.ignore_range		= ignore_range,
-	.force			= force
+	.probe			= &ignore,
+	.ignore			= &ignore,
+	.force			= &ignore,
 };
 
 static struct i2c_driver i2c_driver_bt856;
diff --git a/drivers/media/video/bttv-cards.c b/drivers/media/video/bttv-cards.c
--- a/drivers/media/video/bttv-cards.c
+++ b/drivers/media/video/bttv-cards.c
@@ -1,5 +1,5 @@
 /*
-    $Id: bttv-cards.c,v 1.47 2005/02/22 14:06:32 kraxel Exp $
+    $Id: bttv-cards.c,v 1.54 2005/07/19 18:26:46 mkrufky Exp $
 
     bttv-cards.c
 
@@ -39,9 +39,6 @@
 #include <asm/io.h>
 
 #include "bttvp.h"
-#if 0 /* not working yet */
-#include "bt832.h"
-#endif
 
 /* fwd decl */
 static void boot_msp34xx(struct bttv *btv, int pin);
@@ -51,6 +48,7 @@ static void avermedia_eeprom(struct bttv
 static void osprey_eeprom(struct bttv *btv);
 static void modtec_eeprom(struct bttv *btv);
 static void init_PXC200(struct bttv *btv);
+static void init_RTV24(struct bttv *btv);
 
 static void winview_audio(struct bttv *btv, struct video_audio *v, int set);
 static void lt9415_audio(struct bttv *btv, struct video_audio *v, int set);
@@ -97,7 +95,7 @@ static int __devinit pvr_boot(struct btt
 static unsigned int triton1=0;
 static unsigned int vsfx=0;
 static unsigned int latency = UNSET;
-static unsigned int no_overlay=-1;
+int no_overlay=-1;
 
 static unsigned int card[BTTV_MAX]   = { [ 0 ... (BTTV_MAX-1) ] = UNSET };
 static unsigned int pll[BTTV_MAX]    = { [ 0 ... (BTTV_MAX-1) ] = UNSET };
@@ -512,13 +510,8 @@ struct tvcard bttv_tvcards[] = {
 	.svhs		= 2,
 	.gpiomask	= 0x01fe00,
 	.muxsel		= { 2, 3, 1, 1},
-#if 0
-	// old
-	.audiomux	= { 0x01c000, 0, 0x018000, 0x014000, 0x002000, 0 },
-#else
 	// 2003-10-20 by "Anton A. Arapov" <arapov@mail.ru>
 	.audiomux       = { 0x001e00, 0, 0x018000, 0x014000, 0x002000, 0 },
-#endif
 	.needs_tvaudio	= 1,
 	.pll		= PLL_28,
 	.tuner_type	= -1,
@@ -765,14 +758,9 @@ struct tvcard bttv_tvcards[] = {
 	.tuner		= 0,
 	.svhs		= 2,
 	.muxsel		= { 2, 3, 1, 1, 0}, // TV, CVid, SVid, CVid over SVid connector
-#if 0
-	.gpiomask	= 0xc33000,
-	.audiomux	= { 0x422000,0x1000,0x0000,0x620000,0x800000 },
-#else
 	/* Alexander Varakin <avarakin@hotmail.com> [stereo version] */
 	.gpiomask	= 0xb33000,
 	.audiomux	= { 0x122000,0x1000,0x0000,0x620000,0x800000 },
-#endif
 	/* Audio Routing for "WinFast 2000 XP" (no tv stereo !)
 		gpio23 -- hef4052:nEnable (0x800000)
 		gpio12 -- hef4052:A1
@@ -1602,20 +1590,11 @@ struct tvcard bttv_tvcards[] = {
        .video_inputs   = 4,
        .audio_inputs   = 1,
        .tuner          = -1,
-#if 0 /* TODO ... */
-       .svhs           = OSPREY540_SVID_ANALOG,
-       .muxsel         = {       [OSPREY540_COMP_ANALOG] = 2,
-                               [OSPREY540_SVID_ANALOG] = 3, },
-#endif
        .pll            = PLL_28,
        .tuner_type     = -1,
        .no_msp34xx     = 1,
        .no_tda9875     = 1,
        .no_tda7432     = 1,
-#if 0 /* TODO ... */
-       .muxsel_hook    = osprey_540_muxsel,
-       .picture_hook   = osprey_540_set_picture,
-#endif
 },{
 
 	/* ---- card 0x5C ---------------------------------- */
@@ -2251,6 +2230,20 @@ struct tvcard bttv_tvcards[] = {
 	.no_tda7432	= 1,
 	.no_tda9875	= 1,
 	.muxsel_hook	= kodicom4400r_muxsel,
+},
+{
+        /* ---- card 0x85---------------------------------- */
+        /* Michael Henson <mhenson@clarityvi.com> */
+        /* Adlink RTV24 with special unlock codes */
+        .name           = "Adlink RTV24",
+        .video_inputs   = 4,
+        .audio_inputs   = 1,
+        .tuner          = 0,
+        .svhs           = 2,
+        .muxsel         = { 2, 3, 1, 0},
+        .tuner_type     = -1,
+        .pll            = PLL_28,
+
 }};
 
 static const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards);
@@ -2531,21 +2524,12 @@ static void eagle_muxsel(struct bttv *bt
 	btaor((2)<<5, ~(3<<5), BT848_IFORM);
 	gpio_bits(3,bttv_tvcards[btv->c.type].muxsel[input&7]);
 
-#if 0
-       /* svhs */
-       /* wake chroma ADC */
-       btand(~BT848_ADC_C_SLEEP, BT848_ADC);
-       /* set to YC video */
-       btor(BT848_CONTROL_COMP, BT848_E_CONTROL);
-       btor(BT848_CONTROL_COMP, BT848_O_CONTROL);
-#else
        /* composite */
        /* set chroma ADC to sleep */
        btor(BT848_ADC_C_SLEEP, BT848_ADC);
        /* set to composite video */
        btand(~BT848_CONTROL_COMP, BT848_E_CONTROL);
        btand(~BT848_CONTROL_COMP, BT848_O_CONTROL);
-#endif
 
        /* switch sync drive off */
        gpio_bits(LM1882_SYNC_DRIVE,LM1882_SYNC_DRIVE);
@@ -2636,6 +2620,10 @@ void __devinit bttv_init_card1(struct bt
 	case BTTV_AVDVBT_771:
 		btv->use_i2c_hw = 1;
 		break;
+        case BTTV_ADLINK_RTV24:
+                init_RTV24( btv );
+                break;
+
 	}
 	if (!bttv_tvcards[btv->c.type].has_dvb)
 		bttv_reset_audio(btv);
@@ -2792,10 +2780,18 @@ void __devinit bttv_init_card2(struct bt
 		btv->tuner_type = tuner[btv->c.nr];
 	printk("bttv%d: using tuner=%d\n",btv->c.nr,btv->tuner_type);
 	if (btv->pinnacle_id != UNSET)
-		bttv_call_i2c_clients(btv,AUDC_CONFIG_PINNACLE,
+		bttv_call_i2c_clients(btv, AUDC_CONFIG_PINNACLE,
 				      &btv->pinnacle_id);
-	if (btv->tuner_type != UNSET)
-		bttv_call_i2c_clients(btv,TUNER_SET_TYPE,&btv->tuner_type);
+	if (btv->tuner_type != UNSET) {
+	        struct tuner_setup tun_setup;
+
+	        tun_setup.mode_mask = T_RADIO | T_ANALOG_TV | T_DIGITAL_TV;
+		tun_setup.type = btv->tuner_type;
+		tun_setup.addr = ADDR_UNSET;
+
+		bttv_call_i2c_clients(btv, TUNER_SET_TYPE_ADDR, &tun_setup);
+	}
+
 	btv->svhs = bttv_tvcards[btv->c.type].svhs;
 	if (svhs[btv->c.nr] != UNSET)
 		btv->svhs = svhs[btv->c.nr];
@@ -3104,14 +3100,6 @@ static int tuner_0_table[] = {
         TUNER_PHILIPS_SECAM, TUNER_PHILIPS_SECAM,
         TUNER_PHILIPS_SECAM, TUNER_PHILIPS_PAL,
 	TUNER_PHILIPS_FM1216ME_MK3 };
-#if 0
-int tuner_0_fm_table[] = {
-        PHILIPS_FR1236_NTSC,  PHILIPS_FR1216_PAL,
-        PHILIPS_FR1216_PAL,   PHILIPS_FR1216_PAL,
-        PHILIPS_FR1216_PAL,   PHILIPS_FR1216_PAL,
-        PHILIPS_FR1236_SECAM, PHILIPS_FR1236_SECAM,
-        PHILIPS_FR1236_SECAM, PHILIPS_FR1216_PAL};
-#endif
 
 static int tuner_1_table[] = {
         TUNER_TEMIC_NTSC,  TUNER_TEMIC_PAL,
@@ -3197,36 +3185,6 @@ static void __devinit boot_msp34xx(struc
 
 static void __devinit boot_bt832(struct bttv *btv)
 {
-#if 0 /* not working yet */
-	int resetbit=0;
-
-	switch (btv->c.type) {
-	case BTTV_PXELVWPLTVPAK:
-		resetbit = 0x400000;
-		break;
-	case BTTV_MODTEC_205:
-		resetbit = 1<<9;
-		break;
-	default:
-		BUG();
-	}
-
-	request_module("bt832");
-	bttv_call_i2c_clients(btv, BT832_HEXDUMP, NULL);
-
-	printk("bttv%d: Reset Bt832 [line=0x%x]\n",btv->c.nr,resetbit);
-	gpio_write(0);
-	gpio_inout(resetbit, resetbit);
-	udelay(5);
-	gpio_bits(resetbit, resetbit);
-	udelay(5);
-	gpio_bits(resetbit, 0);
-	udelay(5);
-
-	// bt832 on pixelview changes from i2c 0x8a to 0x88 after
-	// being reset as above. So we must follow by this:
-	bttv_call_i2c_clients(btv, BT832_REATTACH, NULL);
-#endif
 }
 
 /* ----------------------------------------------------------------------- */
@@ -3304,6 +3262,83 @@ static void __devinit init_PXC200(struct
 }
 
 
+
+/* ----------------------------------------------------------------------- */
+/*
+ *  The Adlink RTV-24 (aka Angelo) has some special initialisation to unlock
+ *  it. This apparently involves the following procedure for each 878 chip:
+ *
+ *  1) write 0x00C3FEFF to the GPIO_OUT_EN register
+ *
+ *  2)  write to GPIO_DATA
+ *      - 0x0E
+ *      - sleep 1ms
+ *      - 0x10 + 0x0E
+ *      - sleep 10ms
+ *      - 0x0E
+ *     read from GPIO_DATA into buf (uint_32)
+ *      - if ( data>>18 & 0x01 != 0) || ( buf>>19 & 0x01 != 1 )
+ *                 error. ERROR_CPLD_Check_Failed stop.
+ *
+ *  3) write to GPIO_DATA
+ *      - write 0x4400 + 0x0E
+ *      - sleep 10ms
+ *      - write 0x4410 + 0x0E
+ *      - sleep 1ms
+ *      - write 0x0E
+ *     read from GPIO_DATA into buf (uint_32)
+ *      - if ( buf>>18 & 0x01 ) || ( buf>>19 && 0x01 != 0 )
+ *                error. ERROR_CPLD_Check_Failed.
+ */
+/* ----------------------------------------------------------------------- */
+void
+init_RTV24 (struct bttv *btv)
+{
+	uint32_t dataRead = 0;
+	long watchdog_value = 0x0E;
+
+	printk (KERN_INFO
+		"bttv%d: Adlink RTV-24 initialisation in progress ...\n",
+		btv->c.nr);
+
+	btwrite (0x00c3feff, BT848_GPIO_OUT_EN);
+
+	btwrite (0 + watchdog_value, BT848_GPIO_DATA);
+	msleep (1);
+	btwrite (0x10 + watchdog_value, BT848_GPIO_DATA);
+	msleep (10);
+	btwrite (0 + watchdog_value, BT848_GPIO_DATA);
+
+	dataRead = btread (BT848_GPIO_DATA);
+
+	if ((((dataRead >> 18) & 0x01) != 0) || (((dataRead >> 19) & 0x01) != 1)) {
+		printk (KERN_INFO
+			"bttv%d: Adlink RTV-24 initialisation(1) ERROR_CPLD_Check_Failed (read %d)\n",
+			btv->c.nr, dataRead);
+	}
+
+	btwrite (0x4400 + watchdog_value, BT848_GPIO_DATA);
+	msleep (10);
+	btwrite (0x4410 + watchdog_value, BT848_GPIO_DATA);
+	msleep (1);
+	btwrite (watchdog_value, BT848_GPIO_DATA);
+	msleep (1);
+	dataRead = btread (BT848_GPIO_DATA);
+
+	if ((((dataRead >> 18) & 0x01) != 0) || (((dataRead >> 19) & 0x01) != 0)) {
+		printk (KERN_INFO
+			"bttv%d: Adlink RTV-24 initialisation(2) ERROR_CPLD_Check_Failed (read %d)\n",
+			btv->c.nr, dataRead);
+
+		return;
+	}
+
+	printk (KERN_INFO
+		"bttv%d: Adlink RTV-24 initialisation complete.\n", btv->c.nr);
+}
+
+
+
 /* ----------------------------------------------------------------------- */
 /* Miro Pro radio stuff -- the tea5757 is connected to some GPIO ports     */
 /*
@@ -3474,11 +3509,6 @@ void tea5757_set_freq(struct bttv *btv, 
 {
 	dprintk("tea5757_set_freq %d\n",freq);
 	tea5757_write(btv, 5 * freq + 0x358); /* add 10.7MHz (see docs) */
-#if 0
-	/* breaks Miro PCTV */
-	value = tea5757_read(btv);
-	dprintk("bttv%d: tea5757 readback=0x%x\n",btv->c.nr,value);
-#endif
 }
 
 
@@ -3558,13 +3588,8 @@ gvbctv5pci_audio(struct bttv *btv, struc
 {
 	unsigned int val, con;
 
-#if BTTV_VERSION_CODE > KERNEL_VERSION(0,8,0)
 	if (btv->radio_user)
 		return;
-#else
-	if (btv->radio)
-		return;
-#endif
 
 	val = gpio_read();
 	if (set) {
@@ -3753,13 +3778,8 @@ pvbt878p9b_audio(struct bttv *btv, struc
 {
 	unsigned int val = 0;
 
-#if BTTV_VERSION_CODE > KERNEL_VERSION(0,8,0)
 	if (btv->radio_user)
 		return;
-#else
-	if (btv->radio)
-		return;
-#endif
 
 	if (set) {
 		if (v->mode & VIDEO_SOUND_MONO)	{
@@ -3790,13 +3810,8 @@ fv2000s_audio(struct bttv *btv, struct v
 {
 	unsigned int val = 0xffff;
 
-#if BTTV_VERSION_CODE > KERNEL_VERSION(0,8,0)
 	if (btv->radio_user)
 		return;
-#else
-	if (btv->radio)
-		return;
-#endif
 	if (set) {
 		if (v->mode & VIDEO_SOUND_MONO)	{
 			val = 0x0000;
@@ -4273,11 +4288,6 @@ void __devinit bttv_check_chipset(void)
 		latency = 0x0A;
 #endif
 
-#if 0
-	/* print which chipset we have */
-	while ((dev = pci_find_class(PCI_CLASS_BRIDGE_HOST << 8,dev)))
-		printk(KERN_INFO "bttv: Host bridge is %s\n",pci_name(dev));
-#endif
 
 	/* print warnings about any quirks found */
 	if (triton1)
@@ -4286,9 +4296,11 @@ void __devinit bttv_check_chipset(void)
 		printk(KERN_INFO "bttv: Host bridge needs VSFX enabled.\n");
 	if (pcipci_fail) {
 		printk(KERN_WARNING "bttv: BT848 and your chipset may not work together.\n");
-		if (UNSET == no_overlay) {
-			printk(KERN_WARNING "bttv: going to disable overlay.\n");
+		if (!no_overlay) {
+			printk(KERN_WARNING "bttv: overlay will be disabled.\n");
 			no_overlay = 1;
+		} else {
+			printk(KERN_WARNING "bttv: overlay forced. Use this option at your own risk.\n");
 		}
 	}
 	if (UNSET != latency)
diff --git a/drivers/media/video/bttv-driver.c b/drivers/media/video/bttv-driver.c
--- a/drivers/media/video/bttv-driver.c
+++ b/drivers/media/video/bttv-driver.c
@@ -1,5 +1,5 @@
 /*
-    $Id: bttv-driver.c,v 1.37 2005/02/21 13:57:59 kraxel Exp $
+    $Id: bttv-driver.c,v 1.52 2005/08/04 00:55:16 mchehab Exp $
 
     bttv - Bt848 frame grabber driver
 
@@ -35,6 +35,7 @@
 #include <linux/sched.h>
 #include <linux/interrupt.h>
 #include <linux/kdev_t.h>
+#include <linux/dma-mapping.h>
 
 #include <asm/io.h>
 #include <asm/byteorder.h>
@@ -76,6 +77,10 @@ static unsigned int whitecrush_upper = 0
 static unsigned int whitecrush_lower = 0x7F;
 static unsigned int vcr_hack    = 0;
 static unsigned int irq_iswitch = 0;
+static unsigned int uv_ratio    = 50;
+static unsigned int full_luma_range = 0;
+static unsigned int coring      = 0;
+extern int no_overlay;
 
 /* API features (turn on/off stuff for testing) */
 static unsigned int v4l2        = 1;
@@ -106,6 +111,9 @@ module_param(adc_crush,         int, 044
 module_param(whitecrush_upper,  int, 0444);
 module_param(whitecrush_lower,  int, 0444);
 module_param(vcr_hack,          int, 0444);
+module_param(uv_ratio,          int, 0444);
+module_param(full_luma_range,   int, 0444);
+module_param(coring,            int, 0444);
 
 module_param_array(radio, int, NULL, 0444);
 
@@ -124,6 +132,9 @@ MODULE_PARM_DESC(whitecrush_upper,"sets 
 MODULE_PARM_DESC(whitecrush_lower,"sets the white crush lower value, default is 127");
 MODULE_PARM_DESC(vcr_hack,"enables the VCR hack (improves synch on poor VCR tapes), default is 0 (no)");
 MODULE_PARM_DESC(irq_iswitch,"switch inputs in irq handler");
+MODULE_PARM_DESC(uv_ratio,"ratio between u and v gains, default is 50");
+MODULE_PARM_DESC(full_luma_range,"use the full luma range, default is 0 (no)");
+MODULE_PARM_DESC(coring,"set the luma coring level, default is 0 (no)");
 
 MODULE_DESCRIPTION("bttv - v4l/v4l2 driver module for bt848/878 based cards");
 MODULE_AUTHOR("Ralph Metzler & Marcus Metzler & Gerd Knorr");
@@ -484,7 +495,10 @@ static const unsigned int BTTV_FORMATS =
 #define V4L2_CID_PRIVATE_VCR_HACK    (V4L2_CID_PRIVATE_BASE + 5)
 #define V4L2_CID_PRIVATE_WHITECRUSH_UPPER   (V4L2_CID_PRIVATE_BASE + 6)
 #define V4L2_CID_PRIVATE_WHITECRUSH_LOWER   (V4L2_CID_PRIVATE_BASE + 7)
-#define V4L2_CID_PRIVATE_LASTP1      (V4L2_CID_PRIVATE_BASE + 8)
+#define V4L2_CID_PRIVATE_UV_RATIO    (V4L2_CID_PRIVATE_BASE + 8)
+#define V4L2_CID_PRIVATE_FULL_LUMA_RANGE    (V4L2_CID_PRIVATE_BASE + 9)
+#define V4L2_CID_PRIVATE_CORING      (V4L2_CID_PRIVATE_BASE + 10)
+#define V4L2_CID_PRIVATE_LASTP1      (V4L2_CID_PRIVATE_BASE + 11)
 
 static const struct v4l2_queryctrl no_ctl = {
 	.name  = "42",
@@ -618,8 +632,32 @@ static const struct v4l2_queryctrl bttv_
 		.step          = 1,
 		.default_value = 0x7F,
 		.type          = V4L2_CTRL_TYPE_INTEGER,
+	},{
+		.id            = V4L2_CID_PRIVATE_UV_RATIO,
+		.name          = "uv ratio",
+		.minimum       = 0,
+		.maximum       = 100,
+		.step          = 1,
+		.default_value = 50,
+		.type          = V4L2_CTRL_TYPE_INTEGER,
+	},{
+		.id            = V4L2_CID_PRIVATE_FULL_LUMA_RANGE,
+		.name          = "full luma range",
+		.minimum       = 0,
+		.maximum       = 1,
+		.type          = V4L2_CTRL_TYPE_BOOLEAN,
+	},{
+		.id            = V4L2_CID_PRIVATE_CORING,
+		.name          = "coring",
+		.minimum       = 0,
+		.maximum       = 3,
+		.step          = 1,
+		.default_value = 0,
+		.type          = V4L2_CTRL_TYPE_INTEGER,
 	}
 
+
+
 };
 static const int BTTV_CTLS = ARRAY_SIZE(bttv_ctls);
 
@@ -662,12 +700,10 @@ int locked_btres(struct bttv *btv, int b
 static
 void free_btres(struct bttv *btv, struct bttv_fh *fh, int bits)
 {
-#if 1 /* DEBUG */
 	if ((fh->resources & bits) != bits) {
 		/* trying to free ressources not allocated by us ... */
 		printk("bttv: BUG! (btres)\n");
 	}
-#endif
 	down(&btv->reslock);
 	fh->resources  &= ~bits;
 	btv->resources &= ~bits;
@@ -833,8 +869,8 @@ static void bt848_sat(struct bttv *btv, 
 	btv->saturation = color;
 
 	/* 0-511 for the color */
-	val_u   = color >> 7;
-	val_v   = ((color>>7)*180L)/254;
+	val_u   = ((color * btv->opt_uv_ratio) / 50) >> 7;
+	val_v   = (((color * (100 - btv->opt_uv_ratio) / 50) >>7)*180L)/254;
         hibits  = (val_u >> 7) & 2;
 	hibits |= (val_v >> 8) & 1;
         btwrite(val_u & 0xff, BT848_SAT_U_LO);
@@ -907,11 +943,6 @@ audio_mux(struct bttv *btv, int mode)
 	i2c_mux = mux = (btv->audio & AUDIO_MUTE) ? AUDIO_OFF : btv->audio;
 	if (btv->opt_automute && !signal && !btv->radio_user)
 		mux = AUDIO_OFF;
-#if 0
-	printk("bttv%d: amux: mode=%d audio=%d signal=%s mux=%d/%d irq=%s\n",
-	       btv->c.nr, mode, btv->audio, signal ? "yes" : "no",
-	       mux, i2c_mux, in_interrupt() ? "yes" : "no");
-#endif
 
 	val = bttv_tvcards[btv->c.type].audiomux[mux];
 	gpio_bits(bttv_tvcards[btv->c.type].gpiomask,val);
@@ -958,11 +989,6 @@ set_tvnorm(struct bttv *btv, unsigned in
 	case BTTV_VOODOOTV_FM:
 		bttv_tda9880_setnorm(btv,norm);
 		break;
-#if 0
-	case BTTV_OSPREY540:
-		osprey_540_set_norm(btv,norm);
-		break;
-#endif
 	}
 	return 0;
 }
@@ -1151,6 +1177,15 @@ static int get_control(struct bttv *btv,
 	case V4L2_CID_PRIVATE_WHITECRUSH_LOWER:
 		c->value = btv->opt_whitecrush_lower;
 		break;
+	case V4L2_CID_PRIVATE_UV_RATIO:
+		c->value = btv->opt_uv_ratio;
+		break;
+	case V4L2_CID_PRIVATE_FULL_LUMA_RANGE:
+		c->value = btv->opt_full_luma_range;
+		break;
+	case V4L2_CID_PRIVATE_CORING:
+		c->value = btv->opt_coring;
+		break;
 	default:
 		return -EINVAL;
 	}
@@ -1247,6 +1282,18 @@ static int set_control(struct bttv *btv,
 		btv->opt_whitecrush_lower = c->value;
 		btwrite(c->value, BT848_WC_DOWN);
 		break;
+	case V4L2_CID_PRIVATE_UV_RATIO:
+		btv->opt_uv_ratio = c->value;
+		bt848_sat(btv, btv->saturation);
+		break;
+	case V4L2_CID_PRIVATE_FULL_LUMA_RANGE:
+		btv->opt_full_luma_range = c->value;
+		btaor((c->value<<7), ~BT848_OFORM_RANGE, BT848_OFORM);
+		break;
+	case V4L2_CID_PRIVATE_CORING:
+		btv->opt_coring = c->value;
+		btaor((c->value<<5), ~BT848_OFORM_CORE32, BT848_OFORM);
+		break;
 	default:
 		return -EINVAL;
 	}
@@ -1792,7 +1839,7 @@ static int bttv_common_ioctls(struct btt
 
 		if (unlikely(f->tuner != 0))
 			return -EINVAL;
-		if (unlikely(f->type != V4L2_TUNER_ANALOG_TV))
+		if (unlikely (f->type != V4L2_TUNER_ANALOG_TV))
 			return -EINVAL;
 		down(&btv->lock);
 		btv->freq = f->frequency;
@@ -2105,6 +2152,10 @@ static int bttv_s_fmt(struct bttv_fh *fh
 		return 0;
 	}
 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+		if (no_overlay > 0) {
+			printk ("V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n");
+			return -EINVAL;
+		}
 		return setup_window(fh, btv, &f->fmt.win, 1);
 	case V4L2_BUF_TYPE_VBI_CAPTURE:
 		retval = bttv_switch_type(fh,f->type);
@@ -2178,9 +2229,11 @@ static int bttv_do_ioctl(struct inode *i
 			/* others */
 			cap->type = VID_TYPE_CAPTURE|
 				VID_TYPE_TUNER|
-				VID_TYPE_OVERLAY|
 				VID_TYPE_CLIPPING|
 				VID_TYPE_SCALES;
+			if (no_overlay <= 0)
+				cap->type |= VID_TYPE_OVERLAY;
+
 			cap->maxwidth  = bttv_tvnorms[btv->tvnorm].swidth;
 			cap->maxheight = bttv_tvnorms[btv->tvnorm].sheight;
 			cap->minwidth  = 48;
@@ -2256,6 +2309,11 @@ static int bttv_do_ioctl(struct inode *i
 		struct video_window *win = arg;
 		struct v4l2_window w2;
 
+		if (no_overlay > 0) {
+			printk ("VIDIOCSWIN: no_overlay\n");
+			return -EINVAL;
+		}
+
 		w2.field = V4L2_FIELD_ANY;
 		w2.w.left    = win->x;
 		w2.w.top     = win->y;
@@ -2531,10 +2589,12 @@ static int bttv_do_ioctl(struct inode *i
 		cap->version = BTTV_VERSION_CODE;
 		cap->capabilities =
 			V4L2_CAP_VIDEO_CAPTURE |
-			V4L2_CAP_VIDEO_OVERLAY |
 			V4L2_CAP_VBI_CAPTURE |
 			V4L2_CAP_READWRITE |
 			V4L2_CAP_STREAMING;
+		if (no_overlay <= 0)
+			cap->capabilities |= V4L2_CAP_VIDEO_OVERLAY;
+
 		if (bttv_tvcards[btv->c.type].tuner != UNSET &&
 		    bttv_tvcards[btv->c.type].tuner != TUNER_ABSENT)
 			cap->capabilities |= V4L2_CAP_TUNER;
@@ -3030,7 +3090,7 @@ static struct file_operations bttv_fops 
 static struct video_device bttv_video_template =
 {
 	.name     = "UNSET",
-	.type     = VID_TYPE_CAPTURE|VID_TYPE_TUNER|VID_TYPE_OVERLAY|
+	.type     = VID_TYPE_CAPTURE|VID_TYPE_TUNER|
 	            VID_TYPE_CLIPPING|VID_TYPE_SCALES,
 	.hardware = VID_HARDWARE_BT848,
 	.fops     = &bttv_fops,
@@ -3117,11 +3177,6 @@ static int radio_do_ioctl(struct inode *
                         return -EINVAL;
 		memset(v,0,sizeof(*v));
                 strcpy(v->name, "Radio");
-                /* japan:          76.0 MHz -  89.9 MHz
-                   western europe: 87.5 MHz - 108.0 MHz
-                   russia:         65.0 MHz - 108.0 MHz */
-                v->rangelow=(int)(65*16);
-                v->rangehigh=(int)(108*16);
                 bttv_call_i2c_clients(btv,cmd,v);
                 return 0;
         }
@@ -3715,6 +3770,12 @@ static void bttv_unregister_video(struct
 /* register video4linux devices */
 static int __devinit bttv_register_video(struct bttv *btv)
 {
+	if (no_overlay <= 0) {
+		bttv_video_template.type |= VID_TYPE_OVERLAY;
+	} else {
+		printk("bttv: Overlay support disabled.\n");
+	}
+
 	/* video */
 	btv->video_dev = vdev_init(btv, &bttv_video_template, "video");
         if (NULL == btv->video_dev)
@@ -3813,7 +3874,7 @@ static int __devinit bttv_probe(struct p
 		       btv->c.nr);
 		return -EIO;
 	}
-        if (pci_set_dma_mask(dev, 0xffffffff)) {
+        if (pci_set_dma_mask(dev, DMA_32BIT_MASK)) {
                 printk(KERN_WARNING "bttv%d: No suitable DMA available.\n",
 		       btv->c.nr);
 		return -EIO;
@@ -3828,11 +3889,6 @@ static int __devinit bttv_probe(struct p
         pci_set_master(dev);
 	pci_set_command(dev);
 	pci_set_drvdata(dev,btv);
-	if (!pci_dma_supported(dev,0xffffffff)) {
-		printk("bttv%d: Oops: no 32bit PCI DMA ???\n", btv->c.nr);
-		result = -EIO;
-		goto fail1;
-	}
 
         pci_read_config_byte(dev, PCI_CLASS_REVISION, &btv->revision);
         pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
@@ -3876,6 +3932,9 @@ static int __devinit bttv_probe(struct p
 	btv->opt_vcr_hack   = vcr_hack;
 	btv->opt_whitecrush_upper  = whitecrush_upper;
 	btv->opt_whitecrush_lower  = whitecrush_lower;
+	btv->opt_uv_ratio   = uv_ratio;
+	btv->opt_full_luma_range   = full_luma_range;
+	btv->opt_coring     = coring;
 
 	/* fill struct bttv with some useful defaults */
 	btv->init.btv         = btv;
diff --git a/drivers/media/video/bttv-i2c.c b/drivers/media/video/bttv-i2c.c
--- a/drivers/media/video/bttv-i2c.c
+++ b/drivers/media/video/bttv-i2c.c
@@ -1,5 +1,5 @@
 /*
-    $Id: bttv-i2c.c,v 1.18 2005/02/16 12:14:10 kraxel Exp $
+    $Id: bttv-i2c.c,v 1.25 2005/07/05 17:37:35 nsh Exp $
 
     bttv-i2c.c  --  all the i2c code is here
 
@@ -295,14 +295,26 @@ static int attach_inform(struct i2c_clie
 {
         struct bttv *btv = i2c_get_adapdata(client->adapter);
 
-	if (btv->tuner_type != UNSET)
-		bttv_call_i2c_clients(btv,TUNER_SET_TYPE,&btv->tuner_type);
+	if (bttv_debug)
+		printk(KERN_DEBUG "bttv%d: %s i2c attach [addr=0x%x,client=%s]\n",
+			btv->c.nr,client->driver->name,client->addr,
+			i2c_clientname(client));
+	if (!client->driver->command)
+		return 0;
+
+	if (btv->tuner_type != UNSET) {
+	        struct tuner_setup tun_setup;
+
+	        tun_setup.mode_mask = T_RADIO | T_ANALOG_TV | T_DIGITAL_TV;
+		tun_setup.type = btv->tuner_type;
+		tun_setup.addr = ADDR_UNSET;
+
+		client->driver->command (client, TUNER_SET_TYPE_ADDR, &tun_setup);
+	}
+
 	if (btv->pinnacle_id != UNSET)
-		bttv_call_i2c_clients(btv,AUDC_CONFIG_PINNACLE,
+		client->driver->command(client,AUDC_CONFIG_PINNACLE,
 				      &btv->pinnacle_id);
-        if (bttv_debug)
-		printk("bttv%d: i2c attach [client=%s]\n",
-		       btv->c.nr, i2c_clientname(client));
         return 0;
 }
 
diff --git a/drivers/media/video/bttv-risc.c b/drivers/media/video/bttv-risc.c
--- a/drivers/media/video/bttv-risc.c
+++ b/drivers/media/video/bttv-risc.c
@@ -334,10 +334,6 @@ bttv_calc_geo(struct bttv *btv, struct b
 	}
 
 	vdelay = tvnorm->vdelay;
-#if 0 /* FIXME */
-	if (vdelay < btv->vbi.lines*2)
-		vdelay = btv->vbi.lines*2;
-#endif
 
         xsf = (width*scaledtwidth)/swidth;
         geo->hscale =  ((totalwidth*4096UL)/xsf-4096);
@@ -776,13 +772,8 @@ bttv_overlay_risc(struct bttv *btv,
 		bttv_risc_overlay(btv, &buf->bottom, fmt, ov, 0, 0);
 		break;
 	case V4L2_FIELD_INTERLACED:
-#if 0
-		bttv_risc_overlay(btv, &buf->top,    fmt, ov, 1, 0);
-		bttv_risc_overlay(btv, &buf->bottom, fmt, ov, 0, 1);
-#else
 		bttv_risc_overlay(btv, &buf->top,    fmt, ov, 0, 1);
 		bttv_risc_overlay(btv, &buf->bottom, fmt, ov, 1, 0);
-#endif
 		break;
 	default:
 		BUG();
diff --git a/drivers/media/video/bttv.h b/drivers/media/video/bttv.h
--- a/drivers/media/video/bttv.h
+++ b/drivers/media/video/bttv.h
@@ -1,5 +1,5 @@
 /*
- * $Id: bttv.h,v 1.17 2005/02/22 14:06:32 kraxel Exp $
+ * $Id: bttv.h,v 1.22 2005/07/28 18:41:21 mchehab Exp $
  *
  *  bttv - Bt848 frame grabber driver
  *
@@ -135,6 +135,9 @@
 #define BTTV_DVICO_DVBT_LITE  0x80
 #define BTTV_TIBET_CS16  0x83
 #define BTTV_KODICOM_4400R  0x84
+#define BTTV_ADLINK_RTV24   0x86
+#define BTTV_DVICO_FUSIONHDTV_5_LITE 0x87
+#define BTTV_ACORP_Y878F   0x88
 
 /* i2c address list */
 #define I2C_TSA5522        0xc2
diff --git a/drivers/media/video/bttvp.h b/drivers/media/video/bttvp.h
--- a/drivers/media/video/bttvp.h
+++ b/drivers/media/video/bttvp.h
@@ -1,5 +1,5 @@
 /*
-    $Id: bttvp.h,v 1.17 2005/02/16 12:14:10 kraxel Exp $
+    $Id: bttvp.h,v 1.21 2005/07/15 21:44:14 mchehab Exp $
 
     bttv - Bt848 frame grabber driver
 
@@ -27,7 +27,7 @@
 #define _BTTVP_H_
 
 #include <linux/version.h>
-#define BTTV_VERSION_CODE KERNEL_VERSION(0,9,15)
+#define BTTV_VERSION_CODE KERNEL_VERSION(0,9,16)
 
 #include <linux/types.h>
 #include <linux/wait.h>
@@ -226,10 +226,6 @@ extern int fini_bttv_i2c(struct bttv *bt
 #define dprintk  if (bttv_debug >= 1) printk
 #define d2printk if (bttv_debug >= 2) printk
 
-/* our devices */
-#define BTTV_MAX 16
-extern unsigned int bttv_num;
-
 #define BTTV_MAX_FBUF   0x208000
 #define VBIBUF_SIZE     (2048*VBI_MAXLINES*2)
 #define BTTV_TIMEOUT    (HZ/2) /* 0.5 seconds */
@@ -330,6 +326,9 @@ struct bttv {
 	int opt_vcr_hack;
 	int opt_whitecrush_upper;
 	int opt_whitecrush_lower;
+	int opt_uv_ratio;
+	int opt_full_luma_range;
+	int opt_coring;
 
 	/* radio data/state */
 	int has_radio;
@@ -375,6 +374,10 @@ struct bttv {
 	unsigned int users;
 	struct bttv_fh init;
 };
+
+/* our devices */
+#define BTTV_MAX 16
+extern unsigned int bttv_num;
 extern struct bttv bttvs[BTTV_MAX];
 
 /* private ioctls */
diff --git a/drivers/media/video/cx88/Makefile b/drivers/media/video/cx88/Makefile
--- a/drivers/media/video/cx88/Makefile
+++ b/drivers/media/video/cx88/Makefile
@@ -9,3 +9,15 @@ obj-$(CONFIG_VIDEO_CX88_DVB) += cx88-dvb
 EXTRA_CFLAGS += -I$(src)/..
 EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core
 EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/frontends
+ifneq ($(CONFIG_DVB_CX22702),n)
+ EXTRA_CFLAGS += -DHAVE_CX22702=1
+endif
+ifneq ($(CONFIG_DVB_OR51132),n)
+ EXTRA_CFLAGS += -DHAVE_OR51132=1
+endif
+ifneq ($(CONFIG_DVB_LGDT330X),n)
+ EXTRA_CFLAGS += -DHAVE_LGDT330X=1
+endif
+ifneq ($(CONFIG_DVB_MT352),n)
+ EXTRA_CFLAGS += -DHAVE_MT352=1
+endif
diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c
--- a/drivers/media/video/cx88/cx88-blackbird.c
+++ b/drivers/media/video/cx88/cx88-blackbird.c
@@ -1,5 +1,5 @@
 /*
- * $Id: cx88-blackbird.c,v 1.26 2005/03/07 15:58:05 kraxel Exp $
+ * $Id: cx88-blackbird.c,v 1.27 2005/06/03 13:31:50 mchehab Exp $
  *
  *  Support for a cx23416 mpeg encoder via cx2388x host port.
  *  "blackbird" reference design.
@@ -61,37 +61,304 @@ static LIST_HEAD(cx8802_devlist);
 
 #define IVTV_CMD_HW_BLOCKS_RST 0xFFFFFFFF
 
-/*Firmware API commands*/
-#define IVTV_API_ENC_PING_FW 0x00000080
-#define IVTV_API_ENC_GETVER 0x000000C4
-#define IVTV_API_ENC_HALT_FW 0x000000C3
-#define IVTV_API_STD_TIMEOUT 0x00010000 /*units??*/
-//#define IVTV_API_ASSIGN_PGM_INDEX_INFO 0x000000c7
-#define IVTV_API_ASSIGN_STREAM_TYPE 0x000000b9
-#define IVTV_API_ASSIGN_OUTPUT_PORT 0x000000bb
-#define IVTV_API_ASSIGN_FRAMERATE 0x0000008f
-#define IVTV_API_ASSIGN_FRAME_SIZE 0x00000091
-#define IVTV_API_ASSIGN_ASPECT_RATIO 0x00000099
-#define IVTV_API_ASSIGN_BITRATES 0x00000095
-#define IVTV_API_ASSIGN_GOP_PROPERTIES 0x00000097
-#define IVTV_API_ASSIGN_3_2_PULLDOWN 0x000000b1
-#define IVTV_API_ASSIGN_GOP_CLOSURE 0x000000c5
-#define IVTV_API_ASSIGN_AUDIO_PROPERTIES 0x000000bd
-#define IVTV_API_ASSIGN_DNR_FILTER_MODE 0x0000009b
-#define IVTV_API_ASSIGN_DNR_FILTER_PROPS 0x0000009d
-#define IVTV_API_ASSIGN_CORING_LEVELS 0x0000009f
-#define IVTV_API_ASSIGN_SPATIAL_FILTER_TYPE 0x000000a1
-#define IVTV_API_ASSIGN_FRAME_DROP_RATE 0x000000d0
-#define IVTV_API_ASSIGN_PLACEHOLDER 0x000000d8
-#define IVTV_API_MUTE_VIDEO 0x000000d9
-#define IVTV_API_MUTE_AUDIO 0x000000da
-#define IVTV_API_INITIALIZE_INPUT 0x000000cd
-#define IVTV_API_REFRESH_INPUT 0x000000d3
-#define IVTV_API_ASSIGN_NUM_VSYNC_LINES 0x000000d6
-#define IVTV_API_BEGIN_CAPTURE 0x00000081
-//#define IVTV_API_PAUSE_ENCODER 0x000000d2
-//#define IVTV_API_EVENT_NOTIFICATION 0x000000d5
-#define IVTV_API_END_CAPTURE 0x00000082
+/* Firmware API commands */
+/* #define IVTV_API_STD_TIMEOUT 0x00010000 // 65536, units?? */
+#define IVTV_API_STD_TIMEOUT 500
+
+#define BLACKBIRD_API_PING               0x80
+#define BLACKBIRD_API_BEGIN_CAPTURE      0x81
+enum blackbird_capture_type {
+	BLACKBIRD_MPEG_CAPTURE,
+	BLACKBIRD_RAW_CAPTURE,
+	BLACKBIRD_RAW_PASSTHRU_CAPTURE
+};
+enum blackbird_capture_bits {
+	BLACKBIRD_RAW_BITS_NONE             = 0x00,
+	BLACKBIRD_RAW_BITS_YUV_CAPTURE      = 0x01,
+	BLACKBIRD_RAW_BITS_PCM_CAPTURE      = 0x02,
+	BLACKBIRD_RAW_BITS_VBI_CAPTURE      = 0x04,
+	BLACKBIRD_RAW_BITS_PASSTHRU_CAPTURE = 0x08,
+	BLACKBIRD_RAW_BITS_TO_HOST_CAPTURE  = 0x10
+};
+#define BLACKBIRD_API_END_CAPTURE        0x82
+enum blackbird_capture_end {
+	BLACKBIRD_END_AT_GOP, /* stop at the end of gop, generate irq */
+	BLACKBIRD_END_NOW, /* stop immediately, no irq */
+};
+#define BLACKBIRD_API_SET_AUDIO_ID       0x89
+#define BLACKBIRD_API_SET_VIDEO_ID       0x8B
+#define BLACKBIRD_API_SET_PCR_ID         0x8D
+#define BLACKBIRD_API_SET_FRAMERATE      0x8F
+enum blackbird_framerate {
+	BLACKBIRD_FRAMERATE_NTSC_30, /* NTSC: 30fps */
+	BLACKBIRD_FRAMERATE_PAL_25   /* PAL: 25fps */
+};
+#define BLACKBIRD_API_SET_RESOLUTION     0x91
+#define BLACKBIRD_API_SET_VIDEO_BITRATE  0x95
+enum blackbird_video_bitrate_type {
+	BLACKBIRD_VIDEO_VBR,
+	BLACKBIRD_VIDEO_CBR
+};
+#define BLACKBIRD_PEAK_RATE_DIVISOR 400
+enum blackbird_mux_rate {
+	BLACKBIRD_MUX_RATE_DEFAULT,
+	 /* dvd mux rate: multiply by 400 to get the actual rate */
+	BLACKBIRD_MUX_RATE_DVD = 25200
+};
+#define BLACKBIRD_API_SET_GOP_STRUCTURE  0x97
+#define BLACKBIRD_API_SET_ASPECT_RATIO   0x99
+enum blackbird_aspect_ratio {
+	BLACKBIRD_ASPECT_RATIO_FORBIDDEN,
+	BLACKBIRD_ASPECT_RATIO_1_1_SQUARE,
+	BLACKBIRD_ASPECT_RATIO_4_3,
+	BLACKBIRD_ASPECT_RATIO_16_9,
+	BLACKBIRD_ASPECT_RATIO_221_100,
+	BLACKBIRD_ASPECT_RATIO_RESERVED
+};
+#define BLACKBIRD_API_SET_DNR_MODE       0x9B
+enum blackbird_dnr_bits {
+	BLACKBIRD_DNR_BITS_MANUAL,
+	BLACKBIRD_DNR_BITS_AUTO_SPATIAL,
+	BLACKBIRD_DNR_BITS_AUTO_TEMPORAL,
+	BLACKBIRD_DNR_BITS_AUTO
+};
+enum blackbird_median_filter {
+	BLACKBIRD_MEDIAN_FILTER_DISABLED,
+	BLACKBIRD_MEDIAN_FILTER_HORIZONTAL,
+	BLACKBIRD_MEDIAN_FILTER_VERTICAL,
+	BLACKBIRD_MEDIAN_FILTER_HV,
+	BLACKBIRD_MEDIAN_FILTER_DIAGONAL
+};
+#define BLACKBIRD_API_SET_MANUAL_DNR     0x9D
+#define BLACKBIRD_API_SET_DNR_MEDIAN     0x9F
+#define BLACKBIRD_API_SET_SPATIAL_FILTER 0xA1
+enum blackbird_spatial_filter_luma {
+	BLACKBIRD_SPATIAL_FILTER_LUMA_DISABLED,
+	BLACKBIRD_SPATIAL_FILTER_LUMA_1D_HORIZ,
+	BLACKBIRD_SPATIAL_FILTER_LUMA_1D_VERT,
+	BLACKBIRD_SPATIAL_FILTER_LUMA_2D_HV, /* separable, default */
+	BLACKBIRD_SPATIAL_FILTER_LUMA_2D_SYMM /* symmetric non-separable */
+};
+enum blackbird_spatial_filter_chroma {
+	BLACKBIRD_SPATIAL_FILTER_CHROMA_DISABLED,
+	BLACKBIRD_SPATIAL_FILTER_CHROMA_1D_HORIZ /* default */
+};
+#define BLACKBIRD_API_SET_3_2_PULLDOWN   0xB1
+enum blackbird_pulldown {
+	BLACKBIRD_3_2_PULLDOWN_DISABLED,
+	BLACKBIRD_3_2_PULLDOWN_ENABLED
+};
+#define BLACKBIRD_API_SET_VBI_LINE_NO    0xB7
+enum blackbird_vbi_line_bits {
+	BLACKBIRD_VBI_LINE_BITS_TOP_FIELD,
+	BLACKBIRD_VBI_LINE_BITS_BOT_FIELD = (1 << 31),
+	BLACKBIRD_VBI_LINE_BITS_ALL_LINES = 0xFFFFFFFF
+};
+enum blackbird_vbi_line {
+	BLACKBIRD_VBI_LINE_DISABLED,
+	BLACKBIRD_VBI_LINE_ENABLED
+};
+enum blackbird_vbi_slicing {
+	BLACKBIRD_VBI_SLICING_NONE,
+	BLACKBIRD_VBI_SLICING_CLOSED_CAPTION
+};
+#define BLACKBIRD_API_SET_STREAM_TYPE    0xB9
+enum blackbird_stream_type {
+	BLACKBIRD_STREAM_PROGRAM,
+	BLACKBIRD_STREAM_TRANSPORT,
+	BLACKBIRD_STREAM_MPEG1,
+	BLACKBIRD_STREAM_PES_AV,
+	BLACKBIRD_STREAM_UNKNOWN4,
+	BLACKBIRD_STREAM_PES_VIDEO,
+	BLACKBIRD_STREAM_UNKNOWN6,
+	BLACKBIRD_STREAM_PES_AUDIO,
+	BLACKBIRD_STREAM_UNKNOWN8,
+	BLACKBIRD_STREAM_UNKNOWN9, /* audio/pcm ? */
+	BLACKBIRD_STREAM_DVD,
+	BLACKBIRD_STREAM_VCD,
+	BLACKBIRD_STREAM_UNKNOWN12 /* svcd/xvcd ? */
+};
+#define BLACKBIRD_API_SET_OUTPUT_PORT    0xBB
+enum blackbird_stream_port {
+	BLACKBIRD_OUTPUT_PORT_MEMORY,
+	BLACKBIRD_OUTPUT_PORT_STREAMING,
+	BLACKBIRD_OUTPUT_PORT_SERIAL
+};
+#define BLACKBIRD_API_SET_AUDIO_PARAMS   0xBD
+enum blackbird_audio_bits_sample_rate {
+	BLACKBIRD_AUDIO_BITS_44100HZ,
+	BLACKBIRD_AUDIO_BITS_48000HZ,
+	BLACKBIRD_AUDIO_BITS_32000HZ,
+	BLACKBIRD_AUDIO_BITS_RESERVED_HZ,
+};
+enum blackbird_audio_bits_encoding {
+	BLACKBIRD_AUDIO_BITS_LAYER_1 = 0x1 << 2,
+	BLACKBIRD_AUDIO_BITS_LAYER_2 = 0x2 << 2,
+};
+enum blackbird_audio_bits_bitrate_layer_1 {
+	BLACKBIRD_AUDIO_BITS_LAYER_1_FREE_FORMAT,
+	BLACKBIRD_AUDIO_BITS_LAYER_1_32  = 0x01 << 4,
+	BLACKBIRD_AUDIO_BITS_LAYER_1_64  = 0x02 << 4,
+	BLACKBIRD_AUDIO_BITS_LAYER_1_96  = 0x03 << 4,
+	BLACKBIRD_AUDIO_BITS_LAYER_1_128 = 0x04 << 4,
+	BLACKBIRD_AUDIO_BITS_LAYER_1_160 = 0x05 << 4,
+	BLACKBIRD_AUDIO_BITS_LAYER_1_192 = 0x06 << 4,
+	BLACKBIRD_AUDIO_BITS_LAYER_1_224 = 0x07 << 4,
+	BLACKBIRD_AUDIO_BITS_LAYER_1_256 = 0x08 << 4,
+	BLACKBIRD_AUDIO_BITS_LAYER_1_288 = 0x09 << 4,
+	BLACKBIRD_AUDIO_BITS_LAYER_1_320 = 0x0A << 4,
+	BLACKBIRD_AUDIO_BITS_LAYER_1_352 = 0x0B << 4,
+	BLACKBIRD_AUDIO_BITS_LAYER_1_384 = 0x0C << 4,
+	BLACKBIRD_AUDIO_BITS_LAYER_1_416 = 0x0D << 4,
+	BLACKBIRD_AUDIO_BITS_LAYER_1_448 = 0x0E << 4,
+};
+enum blackbird_audio_bits_bitrate_layer_2 {
+	BLACKBIRD_AUDIO_BITS_LAYER_2_FREE_FORMAT,
+	BLACKBIRD_AUDIO_BITS_LAYER_2_32  = 0x01 << 4,
+	BLACKBIRD_AUDIO_BITS_LAYER_2_48  = 0x02 << 4,
+	BLACKBIRD_AUDIO_BITS_LAYER_2_56  = 0x03 << 4,
+	BLACKBIRD_AUDIO_BITS_LAYER_2_64  = 0x04 << 4,
+	BLACKBIRD_AUDIO_BITS_LAYER_2_80  = 0x05 << 4,
+	BLACKBIRD_AUDIO_BITS_LAYER_2_96  = 0x06 << 4,
+	BLACKBIRD_AUDIO_BITS_LAYER_2_112 = 0x07 << 4,
+	BLACKBIRD_AUDIO_BITS_LAYER_2_128 = 0x08 << 4,
+	BLACKBIRD_AUDIO_BITS_LAYER_2_160 = 0x09 << 4,
+	BLACKBIRD_AUDIO_BITS_LAYER_2_192 = 0x0A << 4,
+	BLACKBIRD_AUDIO_BITS_LAYER_2_224 = 0x0B << 4,
+	BLACKBIRD_AUDIO_BITS_LAYER_2_256 = 0x0C << 4,
+	BLACKBIRD_AUDIO_BITS_LAYER_2_320 = 0x0D << 4,
+	BLACKBIRD_AUDIO_BITS_LAYER_2_384 = 0x0E << 4,
+};
+enum blackbird_audio_bits_mode {
+	BLACKBIRD_AUDIO_BITS_STEREO,
+	BLACKBIRD_AUDIO_BITS_JOINT_STEREO = 0x1 << 8,
+	BLACKBIRD_AUDIO_BITS_DUAL         = 0x2 << 8,
+	BLACKBIRD_AUDIO_BITS_MONO         = 0x3 << 8,
+};
+enum blackbird_audio_bits_mode_extension {
+	BLACKBIRD_AUDIO_BITS_BOUND_4,
+	BLACKBIRD_AUDIO_BITS_BOUND_8  = 0x1 << 10,
+	BLACKBIRD_AUDIO_BITS_BOUND_12 = 0x2 << 10,
+	BLACKBIRD_AUDIO_BITS_BOUND_16 = 0x3 << 10,
+};
+enum blackbird_audio_bits_emphasis {
+	BLACKBIRD_AUDIO_BITS_EMPHASIS_NONE,
+	BLACKBIRD_AUDIO_BITS_EMPHASIS_50_15     = 0x1 << 12,
+	BLACKBIRD_AUDIO_BITS_EMPHASIS_RESERVED  = 0x2 << 12,
+	BLACKBIRD_AUDIO_BITS_EMPHASIS_CCITT_J17 = 0x3 << 12,
+};
+enum blackbird_audio_bits_crc {
+	BLACKBIRD_AUDIO_BITS_CRC_OFF,
+	BLACKBIRD_AUDIO_BITS_CRC_ON = 0x1 << 14,
+};
+enum blackbird_audio_bits_copyright {
+	BLACKBIRD_AUDIO_BITS_COPYRIGHT_OFF,
+	BLACKBIRD_AUDIO_BITS_COPYRIGHT_ON = 0x1 << 15,
+};
+enum blackbird_audio_bits_original {
+	BLACKBIRD_AUDIO_BITS_COPY,
+	BLACKBIRD_AUDIO_BITS_ORIGINAL = 0x1 << 16,
+};
+#define BLACKBIRD_API_HALT               0xC3
+#define BLACKBIRD_API_GET_VERSION        0xC4
+#define BLACKBIRD_API_SET_GOP_CLOSURE    0xC5
+enum blackbird_gop_closure {
+	BLACKBIRD_GOP_CLOSURE_OFF,
+	BLACKBIRD_GOP_CLOSURE_ON,
+};
+#define BLACKBIRD_API_DATA_XFER_STATUS   0xC6
+enum blackbird_data_xfer_status {
+	BLACKBIRD_MORE_BUFFERS_FOLLOW,
+	BLACKBIRD_LAST_BUFFER,
+};
+#define BLACKBIRD_API_PROGRAM_INDEX_INFO 0xC7
+enum blackbird_picture_mask {
+	BLACKBIRD_PICTURE_MASK_NONE,
+	BLACKBIRD_PICTURE_MASK_I_FRAMES,
+	BLACKBIRD_PICTURE_MASK_I_P_FRAMES = 0x3,
+	BLACKBIRD_PICTURE_MASK_ALL_FRAMES = 0x7,
+};
+#define BLACKBIRD_API_SET_VBI_PARAMS     0xC8
+enum blackbird_vbi_mode_bits {
+	BLACKBIRD_VBI_BITS_SLICED,
+	BLACKBIRD_VBI_BITS_RAW,
+};
+enum blackbird_vbi_insertion_bits {
+	BLACKBIRD_VBI_BITS_INSERT_IN_XTENSION_USR_DATA,
+	BLACKBIRD_VBI_BITS_INSERT_IN_PRIVATE_PACKETS = 0x1 << 1,
+	BLACKBIRD_VBI_BITS_SEPARATE_STREAM = 0x2 << 1,
+	BLACKBIRD_VBI_BITS_SEPARATE_STREAM_USR_DATA = 0x4 << 1,
+	BLACKBIRD_VBI_BITS_SEPARATE_STREAM_PRV_DATA = 0x5 << 1,
+};
+#define BLACKBIRD_API_SET_DMA_BLOCK_SIZE 0xC9
+enum blackbird_dma_unit {
+	BLACKBIRD_DMA_BYTES,
+	BLACKBIRD_DMA_FRAMES,
+};
+#define BLACKBIRD_API_DMA_TRANSFER_INFO  0xCA
+#define BLACKBIRD_API_DMA_TRANSFER_STAT  0xCB
+enum blackbird_dma_transfer_status_bits {
+	BLACKBIRD_DMA_TRANSFER_BITS_DONE = 0x01,
+	BLACKBIRD_DMA_TRANSFER_BITS_ERROR = 0x04,
+	BLACKBIRD_DMA_TRANSFER_BITS_LL_ERROR = 0x10,
+};
+#define BLACKBIRD_API_SET_DMA2HOST_ADDR  0xCC
+#define BLACKBIRD_API_INIT_VIDEO_INPUT   0xCD
+#define BLACKBIRD_API_SET_FRAMESKIP      0xD0
+#define BLACKBIRD_API_PAUSE              0xD2
+enum blackbird_pause {
+	BLACKBIRD_PAUSE_ENCODING,
+	BLACKBIRD_RESUME_ENCODING,
+};
+#define BLACKBIRD_API_REFRESH_INPUT      0xD3
+#define BLACKBIRD_API_SET_COPYRIGHT      0xD4
+enum blackbird_copyright {
+	BLACKBIRD_COPYRIGHT_OFF,
+	BLACKBIRD_COPYRIGHT_ON,
+};
+#define BLACKBIRD_API_SET_NOTIFICATION   0xD5
+enum blackbird_notification_type {
+	BLACKBIRD_NOTIFICATION_REFRESH,
+};
+enum blackbird_notification_status {
+	BLACKBIRD_NOTIFICATION_OFF,
+	BLACKBIRD_NOTIFICATION_ON,
+};
+enum blackbird_notification_mailbox {
+	BLACKBIRD_NOTIFICATION_NO_MAILBOX = -1,
+};
+#define BLACKBIRD_API_SET_CAPTURE_LINES  0xD6
+enum blackbird_field1_lines {
+	BLACKBIRD_FIELD1_SAA7114 = 0x00EF, /* 239 */
+	BLACKBIRD_FIELD1_SAA7115 = 0x00F0, /* 240 */
+	BLACKBIRD_FIELD1_MICRONAS = 0x0105, /* 261 */
+};
+enum blackbird_field2_lines {
+	BLACKBIRD_FIELD2_SAA7114 = 0x00EF, /* 239 */
+	BLACKBIRD_FIELD2_SAA7115 = 0x00F0, /* 240 */
+	BLACKBIRD_FIELD2_MICRONAS = 0x0106, /* 262 */
+};
+#define BLACKBIRD_API_SET_CUSTOM_DATA    0xD7
+enum blackbird_custom_data_type {
+	BLACKBIRD_CUSTOM_EXTENSION_USR_DATA,
+	BLACKBIRD_CUSTOM_PRIVATE_PACKET,
+};
+#define BLACKBIRD_API_MUTE_VIDEO         0xD9
+enum blackbird_mute {
+	BLACKBIRD_UNMUTE,
+	BLACKBIRD_MUTE,
+};
+enum blackbird_mute_video_mask {
+	BLACKBIRD_MUTE_VIDEO_V_MASK = 0x0000FF00,
+	BLACKBIRD_MUTE_VIDEO_U_MASK = 0x00FF0000,
+	BLACKBIRD_MUTE_VIDEO_Y_MASK = 0xFF000000,
+};
+enum blackbird_mute_video_shift {
+	BLACKBIRD_MUTE_VIDEO_V_SHIFT = 8,
+	BLACKBIRD_MUTE_VIDEO_U_SHIFT = 16,
+	BLACKBIRD_MUTE_VIDEO_Y_SHIFT = 24,
+};
+#define BLACKBIRD_API_MUTE_AUDIO         0xDA
 
 /* Registers */
 #define IVTV_REG_ENC_SDRAM_REFRESH (0x07F8 /*| IVTV_REG_OFFSET*/)
@@ -405,68 +672,98 @@ static int blackbird_load_firmware(struc
 	return 0;
 }
 
+/**
+ Settings used by the windows tv app for PVR2000:
+=================================================================================================================
+Profile | Codec | Resolution | CBR/VBR | Video Qlty   | V. Bitrate | Frmrate | Audio Codec | A. Bitrate | A. Mode
+-----------------------------------------------------------------------------------------------------------------
+MPEG-1  | MPEG1 | 352x288PAL | (CBR)   | 1000:Optimal | 2000 Kbps  | 25fps   | MPG1 Layer2 | 224kbps    | Stereo
+MPEG-2  | MPEG2 | 720x576PAL | VBR     | 600 :Good    | 4000 Kbps  | 25fps   | MPG1 Layer2 | 224kbps    | Stereo
+VCD     | MPEG1 | 352x288PAL | (CBR)   | 1000:Optimal | 1150 Kbps  | 25fps   | MPG1 Layer2 | 224kbps    | Stereo
+DVD     | MPEG2 | 720x576PAL | VBR     | 600 :Good    | 6000 Kbps  | 25fps   | MPG1 Layer2 | 224kbps    | Stereo
+DB* DVD | MPEG2 | 720x576PAL | CBR     | 600 :Good    | 6000 Kbps  | 25fps   | MPG1 Layer2 | 224kbps    | Stereo
+=================================================================================================================
+*DB: "DirectBurn"
+*/
 static void blackbird_codec_settings(struct cx8802_dev *dev)
 {
 	int bitrate_mode = 1;
 	int bitrate = 7500000;
 	int bitrate_peak = 7500000;
+	bitrate_mode = BLACKBIRD_VIDEO_CBR;
+	bitrate = 4000*1024;
+	bitrate_peak = 4000*1024;
 
 	/* assign stream type */
-        blackbird_api_cmd(dev, IVTV_API_ASSIGN_STREAM_TYPE, 1, 0, 0); /* program stream */
-        //blackbird_api_cmd(dev, IVTV_API_ASSIGN_STREAM_TYPE, 1, 0, 2); /* MPEG1 stream */
-        //blackbird_api_cmd(dev, IVTV_API_ASSIGN_STREAM_TYPE, 1, 0, 3); /* PES A/V */
-        //blackbird_api_cmd(dev, IVTV_API_ASSIGN_STREAM_TYPE, 1, 0, 10); /* DVD stream */
+	blackbird_api_cmd(dev, BLACKBIRD_API_SET_STREAM_TYPE, 1, 0, BLACKBIRD_STREAM_PROGRAM);
+	/* blackbird_api_cmd(dev, BLACKBIRD_API_SET_STREAM_TYPE, 1, 0, BLACKBIRD_STREAM_TRANSPORT); */
 
-        /* assign output port */
-        blackbird_api_cmd(dev, IVTV_API_ASSIGN_OUTPUT_PORT, 1, 0, 1); /* 1 = Host */
+	/* assign output port */
+	blackbird_api_cmd(dev, BLACKBIRD_API_SET_OUTPUT_PORT, 1, 0, BLACKBIRD_OUTPUT_PORT_STREAMING); /* Host */
 
-        /* assign framerate */
-        blackbird_api_cmd(dev, IVTV_API_ASSIGN_FRAMERATE, 1, 0, 0);
+	/* assign framerate */
+	blackbird_api_cmd(dev, BLACKBIRD_API_SET_FRAMERATE, 1, 0, BLACKBIRD_FRAMERATE_PAL_25);
 
-        /* assign frame size */
-        blackbird_api_cmd(dev, IVTV_API_ASSIGN_FRAME_SIZE, 2, 0,
+	/* assign frame size */
+	blackbird_api_cmd(dev, BLACKBIRD_API_SET_RESOLUTION, 2, 0,
 			  dev->height, dev->width);
 
-        /* assign aspect ratio */
-        blackbird_api_cmd(dev, IVTV_API_ASSIGN_ASPECT_RATIO, 1, 0, 2);
+	/* assign aspect ratio */
+	blackbird_api_cmd(dev, BLACKBIRD_API_SET_ASPECT_RATIO, 1, 0, BLACKBIRD_ASPECT_RATIO_4_3);
 
-        /* assign bitrates */
-        blackbird_api_cmd(dev, IVTV_API_ASSIGN_BITRATES, 5, 0,
+	/* assign bitrates */
+	blackbird_api_cmd(dev, BLACKBIRD_API_SET_VIDEO_BITRATE, 5, 0,
 			 bitrate_mode,         /* mode */
 			 bitrate,              /* bps */
-			 bitrate_peak / 400,   /* peak/400 */
-			 0, 0x70);             /* encoding buffer, ckennedy */
+			 bitrate_peak / BLACKBIRD_PEAK_RATE_DIVISOR,   /* peak/400 */
+			 BLACKBIRD_MUX_RATE_DEFAULT /*, 0x70*/);             /* encoding buffer, ckennedy */
 
-        /* assign gop properties */
-        blackbird_api_cmd(dev, IVTV_API_ASSIGN_GOP_PROPERTIES, 2, 0, 15, 3);
-        //blackbird_api_cmd(dev, IVTV_API_ASSIGN_GOP_PROPERTIES, 2, 0, 2, 1);
+	/* assign gop properties */
+	blackbird_api_cmd(dev, BLACKBIRD_API_SET_GOP_STRUCTURE, 2, 0, 15, 3);
 
-        /* assign 3 2 pulldown */
-        blackbird_api_cmd(dev, IVTV_API_ASSIGN_3_2_PULLDOWN, 1, 0, 0);
+	/* assign 3 2 pulldown */
+	blackbird_api_cmd(dev, BLACKBIRD_API_SET_3_2_PULLDOWN, 1, 0, BLACKBIRD_3_2_PULLDOWN_DISABLED);
 
-        /* note: it's not necessary to set the samplerate, the mpeg encoder seems to autodetect/adjust */
-	blackbird_api_cmd(dev, IVTV_API_ASSIGN_AUDIO_PROPERTIES, 1, 0, (2<<2) | (8<<4));
+	/* assign audio properties */
+	/* note: it's not necessary to set the samplerate, the mpeg encoder seems to autodetect/adjust */
+	/* blackbird_api_cmd(dev, IVTV_API_ASSIGN_AUDIO_PROPERTIES, 1, 0, (2<<2) | (8<<4));
+	   blackbird_api_cmd(dev, IVTV_API_ASSIGN_AUDIO_PROPERTIES, 1, 0, 0 | (2 << 2) | (14 << 4)); */
+	blackbird_api_cmd(dev, BLACKBIRD_API_SET_AUDIO_PARAMS, 1, 0,
+			BLACKBIRD_AUDIO_BITS_44100HZ |
+			BLACKBIRD_AUDIO_BITS_LAYER_2 |
+			BLACKBIRD_AUDIO_BITS_LAYER_2_224 |
+			BLACKBIRD_AUDIO_BITS_STEREO |
+			/* BLACKBIRD_AUDIO_BITS_BOUND_4 | */
+			BLACKBIRD_AUDIO_BITS_EMPHASIS_NONE |
+			BLACKBIRD_AUDIO_BITS_CRC_OFF |
+			BLACKBIRD_AUDIO_BITS_COPYRIGHT_OFF |
+			BLACKBIRD_AUDIO_BITS_COPY
+		);
 
 	/* assign gop closure */
-        blackbird_api_cmd(dev, IVTV_API_ASSIGN_GOP_CLOSURE, 1, 0, 0);
+	blackbird_api_cmd(dev, BLACKBIRD_API_SET_GOP_CLOSURE, 1, 0, BLACKBIRD_GOP_CLOSURE_OFF);
 
-        /* assign audio properties */
-        blackbird_api_cmd(dev, IVTV_API_ASSIGN_AUDIO_PROPERTIES, 1, 0, 0 | (2 << 2) | (14 << 4));
 
-        /* assign dnr filter mode */
-        blackbird_api_cmd(dev, IVTV_API_ASSIGN_DNR_FILTER_MODE, 2, 0, 0, 0);
+	/* assign dnr filter mode */
+	blackbird_api_cmd(dev, BLACKBIRD_API_SET_DNR_MODE, 2, 0,
+			BLACKBIRD_DNR_BITS_MANUAL,
+			BLACKBIRD_MEDIAN_FILTER_DISABLED
+		);
 
-        /* assign dnr filter props*/
-        blackbird_api_cmd(dev, IVTV_API_ASSIGN_DNR_FILTER_PROPS, 2, 0, 0, 0);
+	/* assign dnr filter props*/
+	blackbird_api_cmd(dev, BLACKBIRD_API_SET_MANUAL_DNR, 2, 0, 0, 0);
 
-        /* assign coring levels (luma_h, luma_l, chroma_h, chroma_l) */
-        blackbird_api_cmd(dev, IVTV_API_ASSIGN_CORING_LEVELS, 4, 0, 0, 255, 0, 255);
+	/* assign coring levels (luma_h, luma_l, chroma_h, chroma_l) */
+	blackbird_api_cmd(dev, BLACKBIRD_API_SET_DNR_MEDIAN, 4, 0, 0, 255, 0, 255);
 
-	/* assign spatial filter type: luma_t: 1 = horiz_only, chroma_t: 1 = horiz_only */
-        blackbird_api_cmd(dev, IVTV_API_ASSIGN_SPATIAL_FILTER_TYPE, 2, 0, 1, 1);
+	/* assign spatial filter type: luma_t: horiz_only, chroma_t: horiz_only */
+	blackbird_api_cmd(dev, BLACKBIRD_API_SET_SPATIAL_FILTER, 2, 0,
+			BLACKBIRD_SPATIAL_FILTER_LUMA_1D_HORIZ,
+			BLACKBIRD_SPATIAL_FILTER_CHROMA_1D_HORIZ
+		);
 
-        /* assign frame drop rate */
-        blackbird_api_cmd(dev, IVTV_API_ASSIGN_FRAME_DROP_RATE, 1, 0, 0);
+	/* assign frame drop rate */
+	/* blackbird_api_cmd(dev, IVTV_API_ASSIGN_FRAME_DROP_RATE, 1, 0, 0); */
 }
 
 static int blackbird_initialize_codec(struct cx8802_dev *dev)
@@ -476,7 +773,7 @@ static int blackbird_initialize_codec(st
 	int retval;
 
 	dprintk(1,"Initialize codec\n");
-	retval = blackbird_api_cmd(dev, IVTV_API_ENC_PING_FW, 0, 0); /* ping */
+	retval = blackbird_api_cmd(dev, BLACKBIRD_API_PING, 0, 0); /* ping */
 	if (retval < 0) {
 		/* ping was not successful, reset and upload firmware */
 		cx_write(MO_SRST_IO, 0); /* SYS_RSTO=0 */
@@ -491,13 +788,13 @@ static int blackbird_initialize_codec(st
 		if (dev->mailbox < 0)
 			return -1;
 
-		retval = blackbird_api_cmd(dev, IVTV_API_ENC_PING_FW, 0, 0); /* ping */
+		retval = blackbird_api_cmd(dev, BLACKBIRD_API_PING, 0, 0); /* ping */
 		if (retval < 0) {
 			dprintk(0, "ERROR: Firmware ping failed!\n");
 			return -1;
 		}
 
-		retval = blackbird_api_cmd(dev, IVTV_API_ENC_GETVER, 0, 1, &version);
+		retval = blackbird_api_cmd(dev, BLACKBIRD_API_GET_VERSION, 0, 1, &version);
 		if (retval < 0) {
 			dprintk(0, "ERROR: Firmware get encoder version failed!\n");
 			return -1;
@@ -511,31 +808,39 @@ static int blackbird_initialize_codec(st
 	cx_write(MO_VBOS_CONTROL, 0x84A00); /* no 656 mode, 8-bit pixels, disable VBI */
 	cx_clear(MO_OUTPUT_FORMAT, 0x0008); /* Normal Y-limits to let the mpeg encoder sync */
 
-#if 0 /* FIXME */
-	set_scale(dev, 720, 480, V4L2_FIELD_INTERLACED);
-#endif
 	blackbird_codec_settings(dev);
 	msleep(1);
 
-	//blackbird_api_cmd(dev, IVTV_API_ASSIGN_NUM_VSYNC_LINES, 4, 0, 0xef, 0xef);
-	blackbird_api_cmd(dev, IVTV_API_ASSIGN_NUM_VSYNC_LINES, 4, 0, 0xf0, 0xf0);
-	//blackbird_api_cmd(dev, IVTV_API_ASSIGN_NUM_VSYNC_LINES, 4, 0, 0x180, 0x180);
-        blackbird_api_cmd(dev, IVTV_API_ASSIGN_PLACEHOLDER, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+	/* blackbird_api_cmd(dev, IVTV_API_ASSIGN_NUM_VSYNC_LINES, 4, 0, 0xef, 0xef);
+	   blackbird_api_cmd(dev, IVTV_API_ASSIGN_NUM_VSYNC_LINES, 4, 0, 0xf0, 0xf0);
+	   blackbird_api_cmd(dev, IVTV_API_ASSIGN_NUM_VSYNC_LINES, 4, 0, 0x180, 0x180); */
+	blackbird_api_cmd(dev, BLACKBIRD_API_SET_CAPTURE_LINES, 2, 0,
+			BLACKBIRD_FIELD1_SAA7115,
+			BLACKBIRD_FIELD1_SAA7115
+		);
+
+	/* blackbird_api_cmd(dev, IVTV_API_ASSIGN_PLACEHOLDER, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); */
+	blackbird_api_cmd(dev, BLACKBIRD_API_SET_CUSTOM_DATA, 12, 0,
+			BLACKBIRD_CUSTOM_EXTENSION_USR_DATA,
+			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
 
-	blackbird_api_cmd(dev, IVTV_API_INITIALIZE_INPUT, 0, 0); /* initialize the video input */
+	blackbird_api_cmd(dev, BLACKBIRD_API_INIT_VIDEO_INPUT, 0, 0); /* initialize the video input */
 
 	msleep(1);
 
-        blackbird_api_cmd(dev, IVTV_API_MUTE_VIDEO, 1, 0, 0);
+	blackbird_api_cmd(dev, BLACKBIRD_API_MUTE_VIDEO, 1, 0, BLACKBIRD_UNMUTE);
 	msleep(1);
-        blackbird_api_cmd(dev, IVTV_API_MUTE_AUDIO, 1, 0, 0);
+	blackbird_api_cmd(dev, BLACKBIRD_API_MUTE_AUDIO, 1, 0, BLACKBIRD_UNMUTE);
 	msleep(1);
 
-	blackbird_api_cmd(dev, IVTV_API_BEGIN_CAPTURE, 2, 0, 0, 0x13); /* start capturing to the host interface */
-	//blackbird_api_cmd(dev, IVTV_API_BEGIN_CAPTURE, 2, 0, 0, 0); /* start capturing to the host interface */
-	msleep(1);
+	/* blackbird_api_cmd(dev, BLACKBIRD_API_BEGIN_CAPTURE, 2, 0, 0, 0x13); // start capturing to the host interface */
+	blackbird_api_cmd(dev, BLACKBIRD_API_BEGIN_CAPTURE, 2, 0,
+			BLACKBIRD_MPEG_CAPTURE,
+			BLACKBIRD_RAW_BITS_NONE
+		); /* start capturing to the host interface */
+	msleep(10);
 
-	blackbird_api_cmd(dev, IVTV_API_REFRESH_INPUT, 0,0);
+	blackbird_api_cmd(dev, BLACKBIRD_API_REFRESH_INPUT, 0,0);
 	return 0;
 }
 
@@ -709,7 +1014,12 @@ static int mpeg_release(struct inode *in
 {
 	struct cx8802_fh  *fh  = file->private_data;
 
-	blackbird_api_cmd(fh->dev, IVTV_API_END_CAPTURE, 3, 0, 1, 0, 0x13);
+	/* blackbird_api_cmd(fh->dev, BLACKBIRD_API_END_CAPTURE, 3, 0, BLACKBIRD_END_NOW, 0, 0x13); */
+	blackbird_api_cmd(fh->dev, BLACKBIRD_API_END_CAPTURE, 3, 0,
+			BLACKBIRD_END_NOW,
+			BLACKBIRD_MPEG_CAPTURE,
+			BLACKBIRD_RAW_BITS_NONE
+		);
 
 	/* stop mpeg capture */
 	if (fh->mpegq.streaming)
@@ -908,4 +1218,5 @@ module_exit(blackbird_fini);
  * Local variables:
  * c-basic-offset: 8
  * End:
+ * kate: eol "unix"; indent-width 3; remove-trailing-space on; replace-trailing-space-save on; tab-width 8; replace-tabs off; space-indent off; mixed-indent off
  */
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c
--- a/drivers/media/video/cx88/cx88-cards.c
+++ b/drivers/media/video/cx88/cx88-cards.c
@@ -1,5 +1,5 @@
 /*
- * $Id: cx88-cards.c,v 1.66 2005/03/04 09:12:23 kraxel Exp $
+ * $Id: cx88-cards.c,v 1.90 2005/07/28 02:47:42 mkrufky Exp $
  *
  * device driver for Conexant 2388x based TV cards
  * card-specific stuff.
@@ -35,6 +35,9 @@ struct cx88_board cx88_boards[] = {
 	[CX88_BOARD_UNKNOWN] = {
 		.name		= "UNKNOWN/GENERIC",
 		.tuner_type     = UNSET,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
 		.input          = {{
 			.type   = CX88_VMUX_COMPOSITE1,
 			.vmux   = 0,
@@ -52,6 +55,9 @@ struct cx88_board cx88_boards[] = {
 	[CX88_BOARD_HAUPPAUGE] = {
 		.name		= "Hauppauge WinTV 34xxx models",
 		.tuner_type     = UNSET,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
 		.tda9887_conf   = TDA9887_PRESENT,
 		.input          = {{
 			.type   = CX88_VMUX_TELEVISION,
@@ -78,14 +84,23 @@ struct cx88_board cx88_boards[] = {
 	[CX88_BOARD_GDI] = {
 		.name		= "GDI Black Gold",
 		.tuner_type     = UNSET,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
 		.input          = {{
 			.type   = CX88_VMUX_TELEVISION,
 			.vmux   = 0,
+		},{
+			.type   = CX88_VMUX_SVIDEO,
+			.vmux   = 2,
 		}},
 	},
 	[CX88_BOARD_PIXELVIEW] = {
 		.name           = "PixelView",
-		.tuner_type     = 5,
+		.tuner_type     = TUNER_PHILIPS_PAL,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
 		.input          = {{
 			.type   = CX88_VMUX_TELEVISION,
 			.vmux   = 0,
@@ -104,7 +119,10 @@ struct cx88_board cx88_boards[] = {
 	},
 	[CX88_BOARD_ATI_WONDER_PRO] = {
 		.name           = "ATI TV Wonder Pro",
-		.tuner_type     = 44,
+		.tuner_type     = TUNER_PHILIPS_4IN1,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
 		.tda9887_conf   = TDA9887_PRESENT | TDA9887_INTERCARRIER,
 		.input          = {{
 			.type   = CX88_VMUX_TELEVISION,
@@ -122,7 +140,10 @@ struct cx88_board cx88_boards[] = {
 	},
         [CX88_BOARD_WINFAST2000XP_EXPERT] = {
                 .name           = "Leadtek Winfast 2000XP Expert",
-                .tuner_type     = 44,
+                .tuner_type     = TUNER_PHILIPS_4IN1,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
 		.tda9887_conf   = TDA9887_PRESENT,
                 .input          = {{
                         .type   = CX88_VMUX_TELEVISION,
@@ -156,7 +177,10 @@ struct cx88_board cx88_boards[] = {
         },
 	[CX88_BOARD_AVERTV_303] = {
 		.name           = "AverTV Studio 303 (M126)",
-		.tuner_type     = 38,
+		.tuner_type     = TUNER_PHILIPS_FM1216ME_MK3,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
 		.tda9887_conf   = TDA9887_PRESENT,
 		.input          = {{
 			.type   = CX88_VMUX_TELEVISION,
@@ -179,7 +203,10 @@ struct cx88_board cx88_boards[] = {
 		// added gpio values thanks to Michal
 		// values for PAL from DScaler
 		.name           = "MSI TV-@nywhere Master",
-		.tuner_type     = 33,
+		.tuner_type     = TUNER_MT2032,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
 		.tda9887_conf	= TDA9887_PRESENT,
 		.input          = {{
 			.type   = CX88_VMUX_TELEVISION,
@@ -206,7 +233,10 @@ struct cx88_board cx88_boards[] = {
 	},
 	[CX88_BOARD_WINFAST_DV2000] = {
                 .name           = "Leadtek Winfast DV2000",
-                .tuner_type     = 38,
+                .tuner_type     = TUNER_PHILIPS_FM1216ME_MK3,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
 		.tda9887_conf   = TDA9887_PRESENT,
                 .input          = {{
                         .type   = CX88_VMUX_TELEVISION,
@@ -239,34 +269,40 @@ struct cx88_board cx88_boards[] = {
 			.gpio3  = 0x02000000,
 		 },
         },
-        [CX88_BOARD_LEADTEK_PVR2000] = {
+	[CX88_BOARD_LEADTEK_PVR2000] = {
 		// gpio values for PAL version from regspy by DScaler
-                .name           = "Leadtek PVR 2000",
-                .tuner_type     = 38,
+		.name           = "Leadtek PVR 2000",
+		.tuner_type     = TUNER_PHILIPS_FM1216ME_MK3,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
 		.tda9887_conf   = TDA9887_PRESENT,
-                .input          = {{
-                        .type   = CX88_VMUX_TELEVISION,
-                        .vmux   = 0,
-                        .gpio0  = 0x0000bde6,
-                },{
-                        .type   = CX88_VMUX_COMPOSITE1,
-                        .vmux   = 1,
-                        .gpio0  = 0x0000bde6,
-                },{
-                        .type   = CX88_VMUX_SVIDEO,
-                        .vmux   = 2,
-                        .gpio0  = 0x0000bde6,
-                }},
-                .radio = {
-                        .type   = CX88_RADIO,
-                        .gpio0  = 0x0000bd62,
-                },
+		.input          = {{
+			.type   = CX88_VMUX_TELEVISION,
+			.vmux   = 0,
+			.gpio0  = 0x0000bde2,
+		},{
+			.type   = CX88_VMUX_COMPOSITE1,
+			.vmux   = 1,
+			.gpio0  = 0x0000bde6,
+		},{
+			.type   = CX88_VMUX_SVIDEO,
+			.vmux   = 2,
+			.gpio0  = 0x0000bde6,
+		}},
+		.radio = {
+			.type   = CX88_RADIO,
+			.gpio0  = 0x0000bd62,
+		},
 		.blackbird = 1,
-        },
+	},
 	[CX88_BOARD_IODATA_GVVCP3PCI] = {
  		.name		= "IODATA GV-VCP3/PCI",
 		.tuner_type     = TUNER_ABSENT,
- 		.input          = {{
+ 		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
+		.input          = {{
  			.type   = CX88_VMUX_COMPOSITE1,
  			.vmux   = 0,
  		},{
@@ -279,7 +315,10 @@ struct cx88_board cx88_boards[] = {
  	},
 	[CX88_BOARD_PROLINK_PLAYTVPVR] = {
                 .name           = "Prolink PlayTV PVR",
-                .tuner_type     = 43,
+                .tuner_type     = TUNER_PHILIPS_FM1236_MK3,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
 		.tda9887_conf	= TDA9887_PRESENT,
 		.input          = {{
 			.type   = CX88_VMUX_TELEVISION,
@@ -301,8 +340,11 @@ struct cx88_board cx88_boards[] = {
 	},
 	[CX88_BOARD_ASUS_PVR_416] = {
 		.name		= "ASUS PVR-416",
-		.tuner_type     = 43,
-                .tda9887_conf   = TDA9887_PRESENT,
+		.tuner_type     = TUNER_PHILIPS_FM1236_MK3,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
+		.tda9887_conf   = TDA9887_PRESENT,
 		.input          = {{
 			.type   = CX88_VMUX_TELEVISION,
 			.vmux   = 0,
@@ -320,7 +362,10 @@ struct cx88_board cx88_boards[] = {
 	},
 	[CX88_BOARD_MSI_TVANYWHERE] = {
 		.name           = "MSI TV-@nywhere",
-		.tuner_type     = 33,
+		.tuner_type     = TUNER_MT2032,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
 		.tda9887_conf   = TDA9887_PRESENT,
 		.input          = {{
 			.type   = CX88_VMUX_TELEVISION,
@@ -342,6 +387,9 @@ struct cx88_board cx88_boards[] = {
         [CX88_BOARD_KWORLD_DVB_T] = {
                 .name           = "KWorld/VStream XPert DVB-T",
 		.tuner_type     = TUNER_ABSENT,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
                 .input          = {{
                         .type   = CX88_VMUX_COMPOSITE1,
                         .vmux   = 1,
@@ -356,8 +404,11 @@ struct cx88_board cx88_boards[] = {
 		.dvb            = 1,
 	},
 	[CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1] = {
-		.name           = "DVICO FusionHDTV DVB-T1",
+		.name           = "DViCO FusionHDTV DVB-T1",
 		.tuner_type     = TUNER_ABSENT, /* No analog tuner */
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
 		.input          = {{
 			.type   = CX88_VMUX_COMPOSITE1,
 			.vmux   = 1,
@@ -371,7 +422,10 @@ struct cx88_board cx88_boards[] = {
 	},
 	[CX88_BOARD_KWORLD_LTV883] = {
 		.name           = "KWorld LTV883RF",
-                .tuner_type     = 48,
+		.tuner_type     = TUNER_TNF_8831BGFF,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
                 .input          = {{
                         .type   = CX88_VMUX_TELEVISION,
                         .vmux   = 0,
@@ -394,9 +448,12 @@ struct cx88_board cx88_boards[] = {
                         .gpio0  = 0x000007f8,
                 },
 	},
-	[CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD] = {
-		.name		= "DViCO - FusionHDTV 3 Gold",
+	[CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q] = {
+		.name		= "DViCO FusionHDTV 3 Gold-Q",
 		.tuner_type     = TUNER_MICROTUNE_4042FI5,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
 		/*
 		   GPIO[0] resets DT3302 DTV receiver
 		    0 - reset asserted
@@ -410,6 +467,9 @@ struct cx88_board cx88_boards[] = {
 		   GPIO[3] selects RF input connector on tuner module
 		    0 - RF connector labeled CABLE
 		    1 - RF connector labeled ANT
+		   GPIO[4] selects high RF for QAM256 mode
+		    0 - normal RF
+		    1 - high RF
 		*/
 		.input          = {{
 			.type   = CX88_VMUX_TELEVISION,
@@ -428,25 +488,29 @@ struct cx88_board cx88_boards[] = {
 			.vmux   = 2,
 			.gpio0	= 0x0f00,
 		}},
-#if 0
-		.ts             = {
-			 .type   = CX88_TS,
-			 .gpio0  = 0x00000f01,   /* Hooked to tuner reset bit */
-		 }
-#endif
+		.dvb            = 1,
 	},
         [CX88_BOARD_HAUPPAUGE_DVB_T1] = {
-                .name           = "Hauppauge Nova-T DVB-T",
+		.name           = "Hauppauge Nova-T DVB-T",
 		.tuner_type     = TUNER_ABSENT,
-                .input          = {{
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
+		.input          = {{
                         .type   = CX88_VMUX_DVB,
                         .vmux   = 0,
+		},{
+			.type   = CX88_VMUX_SVIDEO,
+			.vmux   = 2,
                 }},
 		.dvb            = 1,
 	},
         [CX88_BOARD_CONEXANT_DVB_T1] = {
 		.name           = "Conexant DVB-T reference design",
 		.tuner_type     = TUNER_ABSENT,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
                 .input          = {{
                         .type   = CX88_VMUX_DVB,
                         .vmux   = 0,
@@ -456,6 +520,9 @@ struct cx88_board cx88_boards[] = {
 	[CX88_BOARD_PROVIDEO_PV259] = {
 		.name		= "Provideo PV259",
 		.tuner_type     = TUNER_PHILIPS_FQ1216ME,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
 		.input          = {{
 			.type   = CX88_VMUX_TELEVISION,
 			.vmux   = 0,
@@ -463,8 +530,11 @@ struct cx88_board cx88_boards[] = {
 		.blackbird = 1,
 	},
 	[CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS] = {
-		.name           = "DVICO FusionHDTV DVB-T Plus",
+		.name           = "DViCO FusionHDTV DVB-T Plus",
 		.tuner_type     = TUNER_ABSENT, /* No analog tuner */
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
 		.input          = {{
 			.type   = CX88_VMUX_COMPOSITE1,
 			.vmux   = 1,
@@ -479,6 +549,9 @@ struct cx88_board cx88_boards[] = {
 	[CX88_BOARD_DNTV_LIVE_DVB_T] = {
 		.name	        = "digitalnow DNTV Live! DVB-T",
 		.tuner_type     = TUNER_ABSENT,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
 		.input	        = {{
 			.type   = CX88_VMUX_COMPOSITE1,
 			.vmux   = 1,
@@ -495,6 +568,9 @@ struct cx88_board cx88_boards[] = {
 	[CX88_BOARD_PCHDTV_HD3000] = {
 		.name           = "pcHDTV HD3000 HDTV",
 		.tuner_type     = TUNER_THOMSON_DTT7610,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
 		.input          = {{
 			.type   = CX88_VMUX_TELEVISION,
 			.vmux   = 0,
@@ -530,8 +606,11 @@ struct cx88_board cx88_boards[] = {
 	[CX88_BOARD_HAUPPAUGE_ROSLYN] = {
 		// entry added by Kaustubh D. Bhalerao <bhalerao.1@osu.edu>
 		// GPIO values obtained from regspy, courtesy Sean Covel
-		.name        = "Hauppauge WinTV 28xxx (Roslyn) models",
-		.tuner_type  = UNSET,
+		.name           = "Hauppauge WinTV 28xxx (Roslyn) models",
+		.tuner_type     = UNSET,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
 		.input          = {{
 			.type   = CX88_VMUX_TELEVISION,
 			.vmux   = 0,
@@ -559,33 +638,37 @@ struct cx88_board cx88_boards[] = {
 		.blackbird = 1,
 	},
 	[CX88_BOARD_DIGITALLOGIC_MEC] = {
-		/* params copied over from Leadtek PVR 2000 */
 		.name           = "Digital-Logic MICROSPACE Entertainment Center (MEC)",
-		/* not sure yet about the tuner type */
-		.tuner_type     = 38,
+		.tuner_type     = TUNER_PHILIPS_FM1216ME_MK3,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
 		.tda9887_conf   = TDA9887_PRESENT,
 		.input          = {{
 			.type   = CX88_VMUX_TELEVISION,
 			.vmux   = 0,
-			.gpio0  = 0x0000bde6,
+			.gpio0  = 0x00009d80,
 		},{
 			.type   = CX88_VMUX_COMPOSITE1,
 			.vmux   = 1,
-			.gpio0  = 0x0000bde6,
+			.gpio0  = 0x00009d76,
 		},{
 			.type   = CX88_VMUX_SVIDEO,
 			.vmux   = 2,
-			.gpio0  = 0x0000bde6,
+			.gpio0  = 0x00009d76,
 		}},
 		.radio = {
 			.type   = CX88_RADIO,
-			.gpio0  = 0x0000bd62,
+			.gpio0  = 0x00009d00,
 		},
 		.blackbird = 1,
 	},
 	[CX88_BOARD_IODATA_GVBCTV7E] = {
 		.name           = "IODATA GV/BCTV7E",
 		.tuner_type     = TUNER_PHILIPS_FQ1286,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
 		.tda9887_conf   = TDA9887_PRESENT,
 		.input          = {{
 			.type   = CX88_VMUX_TELEVISION,
@@ -601,6 +684,102 @@ struct cx88_board cx88_boards[] = {
 			.gpio1  = 0x0000e07f,
 		}}
 	},
+	[CX88_BOARD_PIXELVIEW_PLAYTV_ULTRA_PRO] = {
+		.name           = "PixelView PlayTV Ultra Pro (Stereo)",
+		/* May be also TUNER_YMEC_TVF_5533MF for NTSC/M or PAL/M */
+		.tuner_type     = TUNER_PHILIPS_FM1216ME_MK3,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
+		.input          = {{
+			.type   = CX88_VMUX_TELEVISION,
+			.vmux   = 0,
+			.gpio0  = 0xbf61,  /* internal decoder */
+		},{
+			.type   = CX88_VMUX_COMPOSITE1,
+			.vmux   = 1,
+			.gpio0	= 0xbf63,
+		},{
+			.type   = CX88_VMUX_SVIDEO,
+			.vmux   = 2,
+			.gpio0	= 0xbf63,
+		}},
+		.radio = {
+			 .type  = CX88_RADIO,
+			 .gpio0 = 0xbf60,
+		 },
+	},
+        [CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T] = {
+		.name           = "DViCO FusionHDTV 3 Gold-T",
+		.tuner_type     = TUNER_THOMSON_DTT7611,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
+		/*  See DViCO FusionHDTV 3 Gold-Q for GPIO documentation.  */
+		.input          = {{
+                        .type   = CX88_VMUX_TELEVISION,
+                        .vmux   = 0,
+                        .gpio0  = 0x0f0d,
+                },{
+                        .type   = CX88_VMUX_COMPOSITE1,
+                        .vmux   = 1,
+                        .gpio0  = 0x0f00,
+                },{
+                        .type   = CX88_VMUX_SVIDEO,
+                        .vmux   = 2,
+                        .gpio0  = 0x0f00,
+                }},
+		.dvb            = 1,
+        },
+        [CX88_BOARD_ADSTECH_DVB_T_PCI] = {
+                .name           = "ADS Tech Instant TV DVB-T PCI",
+		.tuner_type     = TUNER_ABSENT,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
+		.input          = {{
+                        .type   = CX88_VMUX_COMPOSITE1,
+                        .vmux   = 1,
+			.gpio0  = 0x0700,
+			.gpio2  = 0x0101,
+                },{
+                        .type   = CX88_VMUX_SVIDEO,
+                        .vmux   = 2,
+			.gpio0  = 0x0700,
+			.gpio2  = 0x0101,
+                }},
+		.dvb            = 1,
+	},
+	[CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1] = {
+		.name           = "TerraTec Cinergy 1400 DVB-T",
+		.tuner_type     = TUNER_ABSENT,
+		.input          = {{
+			.type   = CX88_VMUX_DVB,
+			.vmux   = 0,
+		}},
+		.dvb            = 1,
+	},
+	[CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD] = {
+		.name           = "DViCO FusionHDTV 5 Gold",
+		.tuner_type     = TUNER_LG_TDVS_H062F,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
+		/*  See DViCO FusionHDTV 3 Gold-Q for GPIO documentation.  */
+		.input          = {{
+                        .type   = CX88_VMUX_TELEVISION,
+                        .vmux   = 0,
+                        .gpio0  = 0x0f0d,
+                },{
+                        .type   = CX88_VMUX_COMPOSITE1,
+                        .vmux   = 1,
+                        .gpio0  = 0x0f00,
+                },{
+                        .type   = CX88_VMUX_SVIDEO,
+                        .vmux   = 2,
+                        .gpio0  = 0x0f00,
+                }},
+	},
 };
 const unsigned int cx88_bcount = ARRAY_SIZE(cx88_boards);
 
@@ -671,7 +850,11 @@ struct cx88_subid cx88_subids[] = {
 	},{
 		.subvendor = 0x18ac,
 		.subdevice = 0xd810,
-		.card      = CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD,
+		.card      = CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q,
+	},{
+		.subvendor = 0x18ac,
+		.subdevice = 0xd820,
+		.card      = CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T,
 	},{
 		.subvendor = 0x18AC,
 		.subdevice = 0xDB00,
@@ -716,7 +899,19 @@ struct cx88_subid cx88_subids[] = {
 		.subvendor = 0x10fc,
 		.subdevice = 0xd035,
 		.card      = CX88_BOARD_IODATA_GVBCTV7E,
-	}
+	},{
+		.subvendor = 0x1421,
+		.subdevice = 0x0334,
+		.card      = CX88_BOARD_ADSTECH_DVB_T_PCI,
+ 	},{
+		.subvendor = 0x153b,
+		.subdevice = 0x1166,
+		.card      = CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1,
+ 	},{
+		.subvendor = 0x18ac,
+		.subdevice = 0xd500,
+		.card      = CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD,
+	},
 };
 const unsigned int cx88_idcount = ARRAY_SIZE(cx88_subids);
 
@@ -935,4 +1130,5 @@ EXPORT_SYMBOL(cx88_card_setup);
  * Local variables:
  * c-basic-offset: 8
  * End:
+ * kate: eol "unix"; indent-width 3; remove-trailing-space on; replace-trailing-space-save on; tab-width 8; replace-tabs off; space-indent off; mixed-indent off
  */
diff --git a/drivers/media/video/cx88/cx88-core.c b/drivers/media/video/cx88/cx88-core.c
--- a/drivers/media/video/cx88/cx88-core.c
+++ b/drivers/media/video/cx88/cx88-core.c
@@ -1,5 +1,5 @@
 /*
- * $Id: cx88-core.c,v 1.24 2005/01/19 12:01:55 kraxel Exp $
+ * $Id: cx88-core.c,v 1.33 2005/07/07 14:17:47 mchehab Exp $
  *
  * device driver for Conexant 2388x based TV cards
  * driver core
@@ -51,12 +51,15 @@ module_param(latency,int,0444);
 MODULE_PARM_DESC(latency,"pci latency timer");
 
 static unsigned int tuner[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET };
+static unsigned int radio[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET };
 static unsigned int card[]  = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET };
 
 module_param_array(tuner, int, NULL, 0444);
+module_param_array(radio, int, NULL, 0444);
 module_param_array(card,  int, NULL, 0444);
 
 MODULE_PARM_DESC(tuner,"tuner type");
+MODULE_PARM_DESC(radio,"radio tuner type");
 MODULE_PARM_DESC(card,"card type");
 
 static unsigned int nicam = 0;
@@ -429,7 +432,7 @@ int cx88_sram_channel_setup(struct cx88_
 /* ------------------------------------------------------------------ */
 /* debug helper code                                                  */
 
-static int cx88_risc_decode(u32 risc)
+int cx88_risc_decode(u32 risc)
 {
 	static char *instr[16] = {
 		[ RISC_SYNC    >> 28 ] = "sync",
@@ -467,25 +470,6 @@ static int cx88_risc_decode(u32 risc)
 	return incr[risc >> 28] ? incr[risc >> 28] : 1;
 }
 
-#if 0 /* currently unused, but useful for debugging */
-void cx88_risc_disasm(struct cx88_core *core,
-		      struct btcx_riscmem *risc)
-{
-	unsigned int i,j,n;
-
-	printk("%s: risc disasm: %p [dma=0x%08lx]\n",
-	       core->name, risc->cpu, (unsigned long)risc->dma);
-	for (i = 0; i < (risc->size >> 2); i += n) {
-		printk("%s:   %04d: ", core->name, i);
-		n = cx88_risc_decode(risc->cpu[i]);
-		for (j = 1; j < n; j++)
-			printk("%s:   %04d: 0x%08x [ arg #%d ]\n",
-			       core->name, i+j, risc->cpu[i+j], j);
-		if (risc->cpu[i] == RISC_JUMP)
-			break;
-	}
-}
-#endif
 
 void cx88_sram_channel_dump(struct cx88_core *core,
 			    struct sram_channel *ch)
@@ -548,21 +532,6 @@ static char *cx88_pci_irqs[32] = {
 	"brdg_err", "src_dma_err", "dst_dma_err", "ipb_dma_err",
 	"i2c", "i2c_rack", "ir_smp", "gpio0", "gpio1"
 };
-char *cx88_vid_irqs[32] = {
-	"y_risci1", "u_risci1", "v_risci1", "vbi_risc1",
-	"y_risci2", "u_risci2", "v_risci2", "vbi_risc2",
-	"y_oflow",  "u_oflow",  "v_oflow",  "vbi_oflow",
-	"y_sync",   "u_sync",   "v_sync",   "vbi_sync",
-	"opc_err",  "par_err",  "rip_err",  "pci_abort",
-};
-char *cx88_mpeg_irqs[32] = {
-	"ts_risci1", NULL, NULL, NULL,
-	"ts_risci2", NULL, NULL, NULL,
-	"ts_oflow",  NULL, NULL, NULL,
-	"ts_sync",   NULL, NULL, NULL,
-	"opc_err", "par_err", "rip_err", "pci_abort",
-	"ts_err?",
-};
 
 void cx88_print_irqbits(char *name, char *tag, char **strings,
 			u32 bits, u32 mask)
@@ -612,16 +581,11 @@ void cx88_wakeup(struct cx88_core *core,
 			break;
 		buf = list_entry(q->active.next,
 				 struct cx88_buffer, vb.queue);
-#if 0
-		if (buf->count > count)
-			break;
-#else
 		/* count comes from the hw and is is 16bit wide --
 		 * this trick handles wrap-arounds correctly for
 		 * up to 32767 buffers in flight... */
 		if ((s16) (count - buf->count) < 0)
 			break;
-#endif
 		do_gettimeofday(&buf->vb.ts);
 		dprintk(2,"[%p/%d] wakeup reg=%d buf=%d\n",buf,buf->vb.i,
 			count, buf->count);
@@ -736,6 +700,10 @@ static unsigned int inline norm_fsc8(str
 {
 	static const unsigned int ntsc = 28636360;
 	static const unsigned int pal  = 35468950;
+	static const unsigned int palm  = 28604892;
+
+	if (norm->id & V4L2_STD_PAL_M)
+		return palm;
 
 	return (norm->id & V4L2_STD_625_50) ? pal : ntsc;
 }
@@ -749,6 +717,11 @@ static unsigned int inline norm_notchfil
 
 static unsigned int inline norm_htotal(struct cx88_tvnorm *norm)
 {
+	/* Should always be Line Draw Time / (4*FSC) */
+
+	if (norm->id & V4L2_STD_PAL_M)
+		return 909;
+
 	return (norm->id & V4L2_STD_625_50) ? 1135 : 910;
 }
 
@@ -940,12 +913,10 @@ int cx88_set_tvnorm(struct cx88_core *co
 		norm->cxiformat, cx_read(MO_INPUT_FORMAT) & 0x0f);
 	cx_andor(MO_INPUT_FORMAT, 0xf, norm->cxiformat);
 
-#if 1
 	// FIXME: as-is from DScaler
 	dprintk(1,"set_tvnorm: MO_OUTPUT_FORMAT 0x%08x [old=0x%08x]\n",
 		norm->cxoformat, cx_read(MO_OUTPUT_FORMAT));
 	cx_write(MO_OUTPUT_FORMAT, norm->cxoformat);
-#endif
 
 	// MO_SCONV_REG = adc clock / video dec clock * 2^17
 	tmp64  = adc_clock * (u64)(1 << 17);
@@ -994,21 +965,7 @@ int cx88_set_tvnorm(struct cx88_core *co
 	set_tvaudio(core);
 
 	// tell i2c chips
-#ifdef V4L2_I2C_CLIENTS
 	cx88_call_i2c_clients(core,VIDIOC_S_STD,&norm->id);
-#else
-	{
-		struct video_channel c;
-		memset(&c,0,sizeof(c));
-		c.channel = core->input;
-		c.norm = VIDEO_MODE_PAL;
-		if ((norm->id & (V4L2_STD_NTSC_M|V4L2_STD_NTSC_M_JP)))
-			c.norm = VIDEO_MODE_NTSC;
-		if (norm->id & V4L2_STD_SECAM)
-			c.norm = VIDEO_MODE_SECAM;
-		cx88_call_i2c_clients(core,VIDIOCSCHAN,&c);
-	}
-#endif
 
 	// done
 	return 0;
@@ -1164,8 +1121,20 @@ struct cx88_core* cx88_core_get(struct p
 	       "insmod option" : "autodetected");
 
 	core->tuner_type = tuner[core->nr];
+	core->radio_type = radio[core->nr];
 	if (UNSET == core->tuner_type)
 		core->tuner_type = cx88_boards[core->board].tuner_type;
+	if (UNSET == core->radio_type)
+		core->radio_type = cx88_boards[core->board].radio_type;
+	if (!core->tuner_addr)
+		core->tuner_addr = cx88_boards[core->board].tuner_addr;
+	if (!core->radio_addr)
+		core->radio_addr = cx88_boards[core->board].radio_addr;
+
+        printk(KERN_INFO "TV tuner %d at 0x%02x, Radio tuner %d at 0x%02x\n",
+		core->tuner_type, core->tuner_addr<<1,
+		core->radio_type, core->radio_addr<<1);
+
 	core->tda9887_conf = cx88_boards[core->board].tda9887_conf;
 
 	/* init hardware */
@@ -1206,8 +1175,6 @@ void cx88_core_put(struct cx88_core *cor
 /* ------------------------------------------------------------------ */
 
 EXPORT_SYMBOL(cx88_print_ioctl);
-EXPORT_SYMBOL(cx88_vid_irqs);
-EXPORT_SYMBOL(cx88_mpeg_irqs);
 EXPORT_SYMBOL(cx88_print_irqbits);
 
 EXPORT_SYMBOL(cx88_core_irq);
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c
--- a/drivers/media/video/cx88/cx88-dvb.c
+++ b/drivers/media/video/cx88/cx88-dvb.c
@@ -1,5 +1,5 @@
 /*
- * $Id: cx88-dvb.c,v 1.31 2005/03/07 15:58:05 kraxel Exp $
+ * $Id: cx88-dvb.c,v 1.58 2005/08/07 09:24:08 mkrufky Exp $
  *
  * device driver for Conexant 2388x based TV cards
  * MPEG Transport Stream (DVB) routines
@@ -29,21 +29,24 @@
 #include <linux/kthread.h>
 #include <linux/file.h>
 #include <linux/suspend.h>
-
-/* those two frontends need merging via linuxtv cvs ... */
-#define HAVE_CX22702 1
-#define HAVE_OR51132 1
+#include <linux/config.h>
 
 #include "cx88.h"
 #include "dvb-pll.h"
-#include "mt352.h"
-#include "mt352_priv.h"
-#if HAVE_CX22702
+
+#ifdef HAVE_MT352
+# include "mt352.h"
+# include "mt352_priv.h"
+#endif
+#ifdef HAVE_CX22702
 # include "cx22702.h"
 #endif
-#if HAVE_OR51132
+#ifdef HAVE_OR51132
 # include "or51132.h"
 #endif
+#ifdef HAVE_LGDT330X
+# include "lgdt330x.h"
+#endif
 
 MODULE_DESCRIPTION("driver for cx2388x based DVB cards");
 MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>");
@@ -100,6 +103,7 @@ static struct videobuf_queue_ops dvb_qop
 
 /* ------------------------------------------------------------------ */
 
+#ifdef HAVE_MT352
 static int dvico_fusionhdtv_demod_init(struct dvb_frontend* fe)
 {
 	static u8 clock_config []  = { CLOCK_CTL,  0x38, 0x39 };
@@ -167,22 +171,25 @@ static struct mt352_config dntv_live_dvb
 	.demod_init    = dntv_live_dvbt_demod_init,
 	.pll_set       = mt352_pll_set,
 };
+#endif
 
-#if HAVE_CX22702
+#ifdef HAVE_CX22702
 static struct cx22702_config connexant_refboard_config = {
 	.demod_address = 0x43,
+	.output_mode   = CX22702_SERIAL_OUTPUT,
 	.pll_address   = 0x60,
 	.pll_desc      = &dvb_pll_thomson_dtt7579,
 };
 
 static struct cx22702_config hauppauge_novat_config = {
 	.demod_address = 0x43,
+	.output_mode   = CX22702_SERIAL_OUTPUT,
 	.pll_address   = 0x61,
 	.pll_desc      = &dvb_pll_thomson_dtt759x,
 };
 #endif
 
-#if HAVE_OR51132
+#ifdef HAVE_OR51132
 static int or51132_set_ts_param(struct dvb_frontend* fe,
 				int is_punctured)
 {
@@ -199,6 +206,63 @@ static struct or51132_config pchdtv_hd30
 };
 #endif
 
+#ifdef HAVE_LGDT330X
+static int lgdt330x_pll_set(struct dvb_frontend* fe,
+			    struct dvb_frontend_parameters* params)
+{
+	struct cx8802_dev *dev= fe->dvb->priv;
+	u8 buf[4];
+	struct i2c_msg msg =
+		{ .addr = dev->core->pll_addr, .flags = 0, .buf = buf, .len = 4 };
+	int err;
+
+	dvb_pll_configure(dev->core->pll_desc, buf, params->frequency, 0);
+	dprintk(1, "%s: tuner at 0x%02x bytes: 0x%02x 0x%02x 0x%02x 0x%02x\n",
+			__FUNCTION__, msg.addr, buf[0],buf[1],buf[2],buf[3]);
+	if ((err = i2c_transfer(&dev->core->i2c_adap, &msg, 1)) != 1) {
+		printk(KERN_WARNING "cx88-dvb: %s error "
+			   "(addr %02x <- %02x, err = %i)\n",
+			   __FUNCTION__, buf[0], buf[1], err);
+		if (err < 0)
+			return err;
+		else
+			return -EREMOTEIO;
+	}
+	return 0;
+}
+
+static int lgdt330x_pll_rf_set(struct dvb_frontend* fe, int index)
+{
+	struct cx8802_dev *dev= fe->dvb->priv;
+	struct cx88_core *core = dev->core;
+
+	dprintk(1, "%s: index = %d\n", __FUNCTION__, index);
+	if (index == 0)
+		cx_clear(MO_GP0_IO, 8);
+	else
+		cx_set(MO_GP0_IO, 8);
+	return 0;
+}
+
+static int lgdt330x_set_ts_param(struct dvb_frontend* fe, int is_punctured)
+{
+	struct cx8802_dev *dev= fe->dvb->priv;
+	if (is_punctured)
+		dev->ts_gen_cntrl |= 0x04;
+	else
+		dev->ts_gen_cntrl &= ~0x04;
+	return 0;
+}
+
+static struct lgdt330x_config fusionhdtv_3_gold = {
+	.demod_address    = 0x0e,
+	.demod_chip       = LGDT3302,
+	.serial_mpeg      = 0x04, /* TPSERIAL for 3302 in TOP_CONTROL */
+	.pll_set          = lgdt330x_pll_set,
+	.set_ts_params    = lgdt330x_set_ts_param,
+};
+#endif
+
 static int dvb_register(struct cx8802_dev *dev)
 {
 	/* init struct videobuf_dvb */
@@ -207,16 +271,18 @@ static int dvb_register(struct cx8802_de
 
 	/* init frontend */
 	switch (dev->core->board) {
-#if HAVE_CX22702
+#ifdef HAVE_CX22702
 	case CX88_BOARD_HAUPPAUGE_DVB_T1:
 		dev->dvb.frontend = cx22702_attach(&hauppauge_novat_config,
 						   &dev->core->i2c_adap);
 		break;
+	case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1:
 	case CX88_BOARD_CONEXANT_DVB_T1:
 		dev->dvb.frontend = cx22702_attach(&connexant_refboard_config,
 						   &dev->core->i2c_adap);
 		break;
 #endif
+#ifdef HAVE_MT352
 	case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1:
 		dev->core->pll_addr = 0x61;
 		dev->core->pll_desc = &dvb_pll_lg_z201;
@@ -231,17 +297,56 @@ static int dvb_register(struct cx8802_de
 		break;
 	case CX88_BOARD_KWORLD_DVB_T:
 	case CX88_BOARD_DNTV_LIVE_DVB_T:
+	case CX88_BOARD_ADSTECH_DVB_T_PCI:
 		dev->core->pll_addr = 0x61;
 		dev->core->pll_desc = &dvb_pll_unknown_1;
 		dev->dvb.frontend = mt352_attach(&dntv_live_dvbt_config,
 						 &dev->core->i2c_adap);
 		break;
-#if HAVE_OR51132
+#endif
+#ifdef HAVE_OR51132
 	case CX88_BOARD_PCHDTV_HD3000:
 		dev->dvb.frontend = or51132_attach(&pchdtv_hd3000,
 						 &dev->core->i2c_adap);
 		break;
 #endif
+#ifdef HAVE_LGDT330X
+	case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q:
+		dev->ts_gen_cntrl = 0x08;
+		{
+		/* Do a hardware reset of chip before using it. */
+		struct cx88_core *core = dev->core;
+
+		cx_clear(MO_GP0_IO, 1);
+		mdelay(100);
+		cx_set(MO_GP0_IO, 1);
+		mdelay(200);
+
+		/* Select RF connector callback */
+		fusionhdtv_3_gold.pll_rf_set = lgdt330x_pll_rf_set;
+		dev->core->pll_addr = 0x61;
+		dev->core->pll_desc = &dvb_pll_microtune_4042;
+		dev->dvb.frontend = lgdt330x_attach(&fusionhdtv_3_gold,
+						    &dev->core->i2c_adap);
+		}
+		break;
+	case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T:
+		dev->ts_gen_cntrl = 0x08;
+		{
+		/* Do a hardware reset of chip before using it. */
+		struct cx88_core *core = dev->core;
+
+		cx_clear(MO_GP0_IO, 1);
+		mdelay(100);
+		cx_set(MO_GP0_IO, 9);
+		mdelay(200);
+		dev->core->pll_addr = 0x61;
+		dev->core->pll_desc = &dvb_pll_thomson_dtt7611;
+		dev->dvb.frontend = lgdt330x_attach(&fusionhdtv_3_gold,
+						    &dev->core->i2c_adap);
+		}
+		break;
+#endif
 	default:
 		printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n",
 		       dev->core->name);
diff --git a/drivers/media/video/cx88/cx88-i2c.c b/drivers/media/video/cx88/cx88-i2c.c
--- a/drivers/media/video/cx88/cx88-i2c.c
+++ b/drivers/media/video/cx88/cx88-i2c.c
@@ -1,5 +1,5 @@
 /*
-    $Id: cx88-i2c.c,v 1.20 2005/02/15 15:59:35 kraxel Exp $
+    $Id: cx88-i2c.c,v 1.30 2005/07/25 05:10:13 mkrufky Exp $
 
     cx88-i2c.c  --  all the i2c code is here
 
@@ -91,15 +91,34 @@ static int cx8800_bit_getsda(void *data)
 
 static int attach_inform(struct i2c_client *client)
 {
+        struct tuner_setup tun_setup;
 	struct cx88_core *core = i2c_get_adapdata(client->adapter);
 
-	dprintk(1, "i2c attach [addr=0x%x,client=%s]\n",
-		client->addr, i2c_clientname(client));
+	dprintk(1, "%s i2c attach [addr=0x%x,client=%s]\n",
+		client->driver->name,client->addr,i2c_clientname(client));
 	if (!client->driver->command)
 		return 0;
 
-	if (core->tuner_type != UNSET)
-		client->driver->command(client, TUNER_SET_TYPE, &core->tuner_type);
+        if (core->radio_type != UNSET) {
+		if ((core->radio_addr==ADDR_UNSET)||(core->radio_addr==client->addr)) {
+			tun_setup.mode_mask = T_RADIO;
+			tun_setup.type = core->radio_type;
+			tun_setup.addr = core->radio_addr;
+
+			client->driver->command (client, TUNER_SET_TYPE_ADDR, &tun_setup);
+		}
+        }
+        if (core->tuner_type != UNSET) {
+		if ((core->tuner_addr==ADDR_UNSET)||(core->tuner_addr==client->addr)) {
+
+			tun_setup.mode_mask = T_ANALOG_TV;
+			tun_setup.type = core->tuner_type;
+			tun_setup.addr = core->tuner_addr;
+
+			client->driver->command (client,TUNER_SET_TYPE_ADDR, &tun_setup);
+		}
+        }
+
 	if (core->tda9887_conf)
 		client->driver->command(client, TDA9887_SET_CONFIG, &core->tda9887_conf);
 	return 0;
@@ -145,6 +164,7 @@ static struct i2c_client cx8800_i2c_clie
 };
 
 static char *i2c_devs[128] = {
+	[ 0x1c >> 1 ] = "lgdt330x",
 	[ 0x86 >> 1 ] = "tda9887/cx22702",
 	[ 0xa0 >> 1 ] = "eeprom",
 	[ 0xc0 >> 1 ] = "tuner (analog)",
diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c
--- a/drivers/media/video/cx88/cx88-input.c
+++ b/drivers/media/video/cx88/cx88-input.c
@@ -1,5 +1,5 @@
 /*
- * $Id: cx88-input.c,v 1.9 2005/03/04 09:12:23 kraxel Exp $
+ * $Id: cx88-input.c,v 1.15 2005/07/07 13:58:38 mchehab Exp $
  *
  * Device driver for GPIO attached remote control interfaces
  * on Conexant 2388x based TV/DVB cards.
@@ -38,119 +38,206 @@
 
 /* DigitalNow DNTV Live DVB-T Remote */
 static IR_KEYTAB_TYPE ir_codes_dntv_live_dvb_t[IR_KEYTAB_SIZE] = {
-	[ 0x00 ] = KEY_ESC,         // 'go up a level?'
-	[ 0x01 ] = KEY_KP1,         // '1'
-	[ 0x02 ] = KEY_KP2,         // '2'
-	[ 0x03 ] = KEY_KP3,         // '3'
-	[ 0x04 ] = KEY_KP4,         // '4'
-	[ 0x05 ] = KEY_KP5,         // '5'
-	[ 0x06 ] = KEY_KP6,         // '6'
-	[ 0x07 ] = KEY_KP7,         // '7'
-	[ 0x08 ] = KEY_KP8,         // '8'
-	[ 0x09 ] = KEY_KP9,         // '9'
-	[ 0x0a ] = KEY_KP0,         // '0'
-	[ 0x0b ] = KEY_TUNER,       // 'tv/fm'
-	[ 0x0c ] = KEY_SEARCH,      // 'scan'
-	[ 0x0d ] = KEY_STOP,        // 'stop'
-	[ 0x0e ] = KEY_PAUSE,       // 'pause'
-	[ 0x0f ] = KEY_LIST,        // 'source'
-
-	[ 0x10 ] = KEY_MUTE,        // 'mute'
-	[ 0x11 ] = KEY_REWIND,      // 'backward <<'
-	[ 0x12 ] = KEY_POWER,       // 'power'
-	[ 0x13 ] = KEY_S,           // 'snap'
-	[ 0x14 ] = KEY_AUDIO,       // 'stereo'
-	[ 0x15 ] = KEY_CLEAR,       // 'reset'
-	[ 0x16 ] = KEY_PLAY,        // 'play'
-	[ 0x17 ] = KEY_ENTER,       // 'enter'
-	[ 0x18 ] = KEY_ZOOM,        // 'full screen'
-	[ 0x19 ] = KEY_FASTFORWARD, // 'forward >>'
-	[ 0x1a ] = KEY_CHANNELUP,   // 'channel +'
-	[ 0x1b ] = KEY_VOLUMEUP,    // 'volume +'
-	[ 0x1c ] = KEY_INFO,        // 'preview'
-	[ 0x1d ] = KEY_RECORD,      // 'record'
-	[ 0x1e ] = KEY_CHANNELDOWN, // 'channel -'
-	[ 0x1f ] = KEY_VOLUMEDOWN,  // 'volume -'
+	[0x00] = KEY_ESC,		/* 'go up a level?' */
+	/* Keys 0 to 9 */
+	[0x0a] = KEY_KP0,
+	[0x01] = KEY_KP1,
+	[0x02] = KEY_KP2,
+	[0x03] = KEY_KP3,
+	[0x04] = KEY_KP4,
+	[0x05] = KEY_KP5,
+	[0x06] = KEY_KP6,
+	[0x07] = KEY_KP7,
+	[0x08] = KEY_KP8,
+	[0x09] = KEY_KP9,
+
+	[0x0b] = KEY_TUNER,		/* tv/fm */
+	[0x0c] = KEY_SEARCH,		/* scan */
+	[0x0d] = KEY_STOP,
+	[0x0e] = KEY_PAUSE,
+	[0x0f] = KEY_LIST,		/* source */
+
+	[0x10] = KEY_MUTE,
+	[0x11] = KEY_REWIND,		/* backward << */
+	[0x12] = KEY_POWER,
+	[0x13] = KEY_S,			/* snap */
+	[0x14] = KEY_AUDIO,		/* stereo */
+	[0x15] = KEY_CLEAR,		/* reset */
+	[0x16] = KEY_PLAY,
+	[0x17] = KEY_ENTER,
+	[0x18] = KEY_ZOOM,		/* full screen */
+	[0x19] = KEY_FASTFORWARD,	/* forward >> */
+	[0x1a] = KEY_CHANNELUP,
+	[0x1b] = KEY_VOLUMEUP,
+	[0x1c] = KEY_INFO,		/* preview */
+	[0x1d] = KEY_RECORD,		/* record */
+	[0x1e] = KEY_CHANNELDOWN,
+	[0x1f] = KEY_VOLUMEDOWN,
 };
 
 /* ---------------------------------------------------------------------- */
 
 /* IO-DATA BCTV7E Remote */
 static IR_KEYTAB_TYPE ir_codes_iodata_bctv7e[IR_KEYTAB_SIZE] = {
-	[ 0x40 ] = KEY_TV,              // TV
-	[ 0x20 ] = KEY_RADIO,           // FM
-	[ 0x60 ] = KEY_EPG,             // EPG
-	[ 0x00 ] = KEY_POWER,           // power
-
-	[ 0x50 ] = KEY_KP1,             // 1
-	[ 0x30 ] = KEY_KP2,             // 2
-	[ 0x70 ] = KEY_KP3,             // 3
-	[ 0x10 ] = KEY_L,               // Live
-
-	[ 0x48 ] = KEY_KP4,             // 4
-	[ 0x28 ] = KEY_KP5,             // 5
-	[ 0x68 ] = KEY_KP6,             // 6
-	[ 0x08 ] = KEY_T,               // Time Shift
-
-	[ 0x58 ] = KEY_KP7,             // 7
-	[ 0x38 ] = KEY_KP8,             // 8
-	[ 0x78 ] = KEY_KP9,             // 9
-	[ 0x18 ] = KEY_PLAYPAUSE,       // Play
-
-	[ 0x44 ] = KEY_KP0,             // 10
-	[ 0x24 ] = KEY_ENTER,           // 11
-	[ 0x64 ] = KEY_ESC,             // 12
-	[ 0x04 ] = KEY_M,               // Multi
-
-	[ 0x54 ] = KEY_VIDEO,           // VIDEO
-	[ 0x34 ] = KEY_CHANNELUP,       // channel +
-	[ 0x74 ] = KEY_VOLUMEUP,        // volume +
-	[ 0x14 ] = KEY_MUTE,            // Mute
-
-	[ 0x4c ] = KEY_S,               // SVIDEO
-	[ 0x2c ] = KEY_CHANNELDOWN,     // channel -
-	[ 0x6c ] = KEY_VOLUMEDOWN,      // volume -
-	[ 0x0c ] = KEY_ZOOM,            // Zoom
-
-	[ 0x5c ] = KEY_PAUSE,           // pause
-	[ 0x3c ] = KEY_C,               // || (red)
-	[ 0x7c ] = KEY_RECORD,          // recording
-	[ 0x1c ] = KEY_STOP,            // stop
-
-	[ 0x41 ] = KEY_REWIND,          // backward <<
-	[ 0x21 ] = KEY_PLAY,            // play
-	[ 0x61 ] = KEY_FASTFORWARD,     // forward >>
-	[ 0x01 ] = KEY_NEXT,            // skip >|
+	[0x40] = KEY_TV,
+	[0x20] = KEY_RADIO,		/* FM */
+	[0x60] = KEY_EPG,
+	[0x00] = KEY_POWER,
+
+	/* Keys 0 to 9 */
+	[0x44] = KEY_KP0,		/* 10 */
+	[0x50] = KEY_KP1,
+	[0x30] = KEY_KP2,
+	[0x70] = KEY_KP3,
+	[0x48] = KEY_KP4,
+	[0x28] = KEY_KP5,
+	[0x68] = KEY_KP6,
+	[0x58] = KEY_KP7,
+	[0x38] = KEY_KP8,
+	[0x78] = KEY_KP9,
+
+	[0x10] = KEY_L,			/* Live */
+	[0x08] = KEY_T,			/* Time Shift */
+
+	[0x18] = KEY_PLAYPAUSE,		/* Play */
+
+	[0x24] = KEY_ENTER,		/* 11 */
+	[0x64] = KEY_ESC,		/* 12 */
+	[0x04] = KEY_M,			/* Multi */
+
+	[0x54] = KEY_VIDEO,
+	[0x34] = KEY_CHANNELUP,
+	[0x74] = KEY_VOLUMEUP,
+	[0x14] = KEY_MUTE,
+
+	[0x4c] = KEY_S,			/* SVIDEO */
+	[0x2c] = KEY_CHANNELDOWN,
+	[0x6c] = KEY_VOLUMEDOWN,
+	[0x0c] = KEY_ZOOM,
+
+	[0x5c] = KEY_PAUSE,
+	[0x3c] = KEY_C,			/* || (red) */
+	[0x7c] = KEY_RECORD,		/* recording */
+	[0x1c] = KEY_STOP,
+
+	[0x41] = KEY_REWIND,		/* backward << */
+	[0x21] = KEY_PLAY,
+	[0x61] = KEY_FASTFORWARD,	/* forward >> */
+	[0x01] = KEY_NEXT,		/* skip >| */
+};
+
+/* ---------------------------------------------------------------------- */
+
+/* ADS Tech Instant TV DVB-T PCI Remote */
+static IR_KEYTAB_TYPE ir_codes_adstech_dvb_t_pci[IR_KEYTAB_SIZE] = {
+	/* Keys 0 to 9 */
+	[0x4d] = KEY_0,
+	[0x57] = KEY_1,
+	[0x4f] = KEY_2,
+	[0x53] = KEY_3,
+	[0x56] = KEY_4,
+	[0x4e] = KEY_5,
+	[0x5e] = KEY_6,
+	[0x54] = KEY_7,
+	[0x4c] = KEY_8,
+	[0x5c] = KEY_9,
+
+	[0x5b] = KEY_POWER,
+	[0x5f] = KEY_MUTE,
+	[0x55] = KEY_GOTO,
+	[0x5d] = KEY_SEARCH,
+	[0x17] = KEY_EPG,		/* Guide */
+	[0x1f] = KEY_MENU,
+	[0x0f] = KEY_UP,
+	[0x46] = KEY_DOWN,
+	[0x16] = KEY_LEFT,
+	[0x1e] = KEY_RIGHT,
+	[0x0e] = KEY_SELECT,		/* Enter */
+	[0x5a] = KEY_INFO,
+	[0x52] = KEY_EXIT,
+	[0x59] = KEY_PREVIOUS,
+	[0x51] = KEY_NEXT,
+	[0x58] = KEY_REWIND,
+	[0x50] = KEY_FORWARD,
+	[0x44] = KEY_PLAYPAUSE,
+	[0x07] = KEY_STOP,
+	[0x1b] = KEY_RECORD,
+	[0x13] = KEY_TUNER,		/* Live */
+	[0x0a] = KEY_A,
+	[0x12] = KEY_B,
+	[0x03] = KEY_PROG1,		/* 1 */
+	[0x01] = KEY_PROG2,		/* 2 */
+	[0x00] = KEY_PROG3,		/* 3 */
+	[0x06] = KEY_DVD,
+	[0x48] = KEY_AUX,		/* Photo */
+	[0x40] = KEY_VIDEO,
+	[0x19] = KEY_AUDIO,		/* Music */
+	[0x0b] = KEY_CHANNELUP,
+	[0x08] = KEY_CHANNELDOWN,
+	[0x15] = KEY_VOLUMEUP,
+	[0x1c] = KEY_VOLUMEDOWN,
+};
+
+/* ---------------------------------------------------------------------- */
+
+/* MSI TV@nywhere remote */
+static IR_KEYTAB_TYPE ir_codes_msi_tvanywhere[IR_KEYTAB_SIZE] = {
+	/* Keys 0 to 9 */
+	[0x00] = KEY_0,
+	[0x01] = KEY_1,
+	[0x02] = KEY_2,
+	[0x03] = KEY_3,
+	[0x04] = KEY_4,
+	[0x05] = KEY_5,
+	[0x06] = KEY_6,
+	[0x07] = KEY_7,
+	[0x08] = KEY_8,
+	[0x09] = KEY_9,
+
+	[0x0c] = KEY_MUTE,
+	[0x0f] = KEY_SCREEN,		/* Full Screen */
+	[0x10] = KEY_F,			/* Funtion */
+	[0x11] = KEY_T,			/* Time shift */
+	[0x12] = KEY_POWER,
+	[0x13] = KEY_MEDIA,		/* MTS */
+	[0x14] = KEY_SLOW,
+	[0x16] = KEY_REWIND,		/* backward << */
+	[0x17] = KEY_ENTER,		/* Return */
+	[0x18] = KEY_FASTFORWARD,	/* forward >> */
+	[0x1a] = KEY_CHANNELUP,
+	[0x1b] = KEY_VOLUMEUP,
+	[0x1e] = KEY_CHANNELDOWN,
+	[0x1f] = KEY_VOLUMEDOWN,
 };
 
 /* ---------------------------------------------------------------------- */
 
 struct cx88_IR {
-	struct cx88_core	*core;
-	struct input_dev        input;
-	struct ir_input_state   ir;
-	char                    name[32];
-	char                    phys[32];
+	struct cx88_core *core;
+	struct input_dev input;
+	struct ir_input_state ir;
+	char name[32];
+	char phys[32];
 
 	/* sample from gpio pin 16 */
-	int                     sampling;
-	u32                     samples[16];
-	int                     scount;
-	unsigned long           release;
+	int sampling;
+	u32 samples[16];
+	int scount;
+	unsigned long release;
 
 	/* poll external decoder */
-	int                     polling;
-	struct work_struct      work;
-	struct timer_list       timer;
-	u32			gpio_addr;
-	u32                     last_gpio;
-	u32                     mask_keycode;
-	u32                     mask_keydown;
-	u32                     mask_keyup;
+	int polling;
+	struct work_struct work;
+	struct timer_list timer;
+	u32 gpio_addr;
+	u32 last_gpio;
+	u32 mask_keycode;
+	u32 mask_keydown;
+	u32 mask_keyup;
 };
 
 static int ir_debug = 0;
-module_param(ir_debug, int, 0644);    /* debug level [IR] */
+module_param(ir_debug, int, 0644);	/* debug level [IR] */
 MODULE_PARM_DESC(ir_debug, "enable debug messages [IR]");
 
 #define ir_dprintk(fmt, arg...)	if (ir_debug) \
@@ -174,37 +261,37 @@ static void cx88_ir_handle_key(struct cx
 	/* extract data */
 	data = ir_extract_bits(gpio, ir->mask_keycode);
 	ir_dprintk("irq gpio=0x%x code=%d | %s%s%s\n",
-		gpio, data,
-		ir->polling               ? "poll"  : "irq",
-		(gpio & ir->mask_keydown) ? " down" : "",
-		(gpio & ir->mask_keyup)   ? " up"   : "");
+		   gpio, data,
+		   ir->polling ? "poll" : "irq",
+		   (gpio & ir->mask_keydown) ? " down" : "",
+		   (gpio & ir->mask_keyup) ? " up" : "");
 
 	if (ir->mask_keydown) {
 		/* bit set on keydown */
 		if (gpio & ir->mask_keydown) {
-			ir_input_keydown(&ir->input,&ir->ir,data,data);
+			ir_input_keydown(&ir->input, &ir->ir, data, data);
 		} else {
-			ir_input_nokey(&ir->input,&ir->ir);
+			ir_input_nokey(&ir->input, &ir->ir);
 		}
 
 	} else if (ir->mask_keyup) {
 		/* bit cleared on keydown */
 		if (0 == (gpio & ir->mask_keyup)) {
-			ir_input_keydown(&ir->input,&ir->ir,data,data);
+			ir_input_keydown(&ir->input, &ir->ir, data, data);
 		} else {
-			ir_input_nokey(&ir->input,&ir->ir);
+			ir_input_nokey(&ir->input, &ir->ir);
 		}
 
 	} else {
 		/* can't distinguish keydown/up :-/ */
-		ir_input_keydown(&ir->input,&ir->ir,data,data);
-		ir_input_nokey(&ir->input,&ir->ir);
+		ir_input_keydown(&ir->input, &ir->ir, data, data);
+		ir_input_nokey(&ir->input, &ir->ir);
 	}
 }
 
 static void ir_timer(unsigned long data)
 {
-	struct cx88_IR *ir = (struct cx88_IR*)data;
+	struct cx88_IR *ir = (struct cx88_IR *)data;
 
 	schedule_work(&ir->work);
 }
@@ -227,41 +314,64 @@ int cx88_ir_init(struct cx88_core *core,
 	IR_KEYTAB_TYPE *ir_codes = NULL;
 	int ir_type = IR_TYPE_OTHER;
 
-	ir = kmalloc(sizeof(*ir),GFP_KERNEL);
+	ir = kmalloc(sizeof(*ir), GFP_KERNEL);
 	if (NULL == ir)
 		return -ENOMEM;
-	memset(ir,0,sizeof(*ir));
+	memset(ir, 0, sizeof(*ir));
 
 	/* detect & configure */
 	switch (core->board) {
 	case CX88_BOARD_DNTV_LIVE_DVB_T:
-		ir_codes         = ir_codes_dntv_live_dvb_t;
-		ir->gpio_addr    = MO_GP1_IO;
+	case CX88_BOARD_KWORLD_DVB_T:
+		ir_codes = ir_codes_dntv_live_dvb_t;
+		ir->gpio_addr = MO_GP1_IO;
 		ir->mask_keycode = 0x1f;
-		ir->mask_keyup   = 0x60;
-		ir->polling      = 50; // ms
+		ir->mask_keyup = 0x60;
+		ir->polling = 50; /* ms */
 		break;
 	case CX88_BOARD_HAUPPAUGE:
 	case CX88_BOARD_HAUPPAUGE_DVB_T1:
-		ir_codes         = ir_codes_hauppauge_new;
-		ir_type          = IR_TYPE_RC5;
-		ir->sampling     = 1;
+		ir_codes = ir_codes_hauppauge_new;
+		ir_type = IR_TYPE_RC5;
+		ir->sampling = 1;
 		break;
 	case CX88_BOARD_WINFAST2000XP_EXPERT:
-		ir_codes         = ir_codes_winfast;
-		ir->gpio_addr    = MO_GP0_IO;
+		ir_codes = ir_codes_winfast;
+		ir->gpio_addr = MO_GP0_IO;
 		ir->mask_keycode = 0x8f8;
-		ir->mask_keyup   = 0x100;
-		ir->polling      = 1; // ms
+		ir->mask_keyup = 0x100;
+		ir->polling = 1; /* ms */
 		break;
 	case CX88_BOARD_IODATA_GVBCTV7E:
-		ir_codes         = ir_codes_iodata_bctv7e;
-		ir->gpio_addr    = MO_GP0_IO;
+		ir_codes = ir_codes_iodata_bctv7e;
+		ir->gpio_addr = MO_GP0_IO;
 		ir->mask_keycode = 0xfd;
 		ir->mask_keydown = 0x02;
-		ir->polling      = 5; // ms
+		ir->polling = 5; /* ms */
+		break;
+	case CX88_BOARD_PIXELVIEW_PLAYTV_ULTRA_PRO:
+		ir_codes = ir_codes_pixelview;
+		ir->gpio_addr = MO_GP1_IO;
+		ir->mask_keycode = 0x1f;
+		ir->mask_keyup = 0x80;
+		ir->polling = 1; /* ms */
+		break;
+	case CX88_BOARD_ADSTECH_DVB_T_PCI:
+		ir_codes = ir_codes_adstech_dvb_t_pci;
+		ir->gpio_addr = MO_GP1_IO;
+		ir->mask_keycode = 0xbf;
+		ir->mask_keyup = 0x40;
+		ir->polling = 50; /* ms */
+		break;
+	case CX88_BOARD_MSI_TVANYWHERE_MASTER:
+		ir_codes = ir_codes_msi_tvanywhere;
+		ir->gpio_addr = MO_GP1_IO;
+		ir->mask_keycode = 0x1f;
+		ir->mask_keyup = 0x40;
+		ir->polling = 1; /* ms */
 		break;
 	}
+
 	if (NULL == ir_codes) {
 		kfree(ir);
 		return -ENODEV;
@@ -270,8 +380,7 @@ int cx88_ir_init(struct cx88_core *core,
 	/* init input device */
 	snprintf(ir->name, sizeof(ir->name), "cx88 IR (%s)",
 		 cx88_boards[core->board].name);
-	snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0",
-		 pci_name(pci));
+	snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", pci_name(pci));
 
 	ir_input_init(&ir->input, &ir->ir, ir_type, ir_codes);
 	ir->input.name = ir->name;
@@ -279,10 +388,10 @@ int cx88_ir_init(struct cx88_core *core,
 	ir->input.id.bustype = BUS_PCI;
 	ir->input.id.version = 1;
 	if (pci->subsystem_vendor) {
-		ir->input.id.vendor  = pci->subsystem_vendor;
+		ir->input.id.vendor = pci->subsystem_vendor;
 		ir->input.id.product = pci->subsystem_device;
 	} else {
-		ir->input.id.vendor  = pci->vendor;
+		ir->input.id.vendor = pci->vendor;
 		ir->input.id.product = pci->device;
 	}
 
@@ -294,13 +403,13 @@ int cx88_ir_init(struct cx88_core *core,
 		INIT_WORK(&ir->work, cx88_ir_work, ir);
 		init_timer(&ir->timer);
 		ir->timer.function = ir_timer;
-		ir->timer.data     = (unsigned long)ir;
+		ir->timer.data = (unsigned long)ir;
 		schedule_work(&ir->work);
 	}
 	if (ir->sampling) {
-		core->pci_irqmask |= (1<<18);   // IR_SMP_INT
-		cx_write(MO_DDS_IO, 0xa80a80);  // 4 kHz sample rate
-		cx_write(MO_DDSCFG_IO,   0x5);  // enable
+		core->pci_irqmask |= (1 << 18);	/* IR_SMP_INT */
+		cx_write(MO_DDS_IO, 0xa80a80);	/* 4 kHz sample rate */
+		cx_write(MO_DDSCFG_IO, 0x5);	/* enable */
 	}
 
 	/* all done */
@@ -336,7 +445,7 @@ int cx88_ir_fini(struct cx88_core *core)
 void cx88_ir_irq(struct cx88_core *core)
 {
 	struct cx88_IR *ir = core->ir;
-	u32 samples,rc5;
+	u32 samples, rc5;
 	int i;
 
 	if (NULL == ir)
@@ -345,7 +454,7 @@ void cx88_ir_irq(struct cx88_core *core)
 		return;
 
 	samples = cx_read(MO_SAMPLE_IO);
-	if (0 != samples  &&  0xffffffff != samples) {
+	if (0 != samples && 0xffffffff != samples) {
 		/* record sample data */
 		if (ir->scount < ARRAY_SIZE(ir->samples))
 			ir->samples[ir->scount++] = samples;
@@ -353,8 +462,8 @@ void cx88_ir_irq(struct cx88_core *core)
 	}
 	if (!ir->scount) {
 		/* nothing to sample */
-		if (ir->ir.keypressed && time_after(jiffies,ir->release))
-			ir_input_nokey(&ir->input,&ir->ir);
+		if (ir->ir.keypressed && time_after(jiffies, ir->release))
+			ir_input_nokey(&ir->input, &ir->ir);
 		return;
 	}
 
@@ -364,14 +473,14 @@ void cx88_ir_irq(struct cx88_core *core)
 	for (i = 0; i < ir->scount; i++)
 		ir->samples[i] = ~ir->samples[i];
 	if (ir_debug)
-		ir_dump_samples(ir->samples,ir->scount);
+		ir_dump_samples(ir->samples, ir->scount);
 
 	/* decode it */
 	switch (core->board) {
 	case CX88_BOARD_HAUPPAUGE:
 	case CX88_BOARD_HAUPPAUGE_DVB_T1:
-		rc5 = ir_decode_biphase(ir->samples,ir->scount,5,7);
-		ir_dprintk("biphase decoded: %x\n",rc5);
+		rc5 = ir_decode_biphase(ir->samples, ir->scount, 5, 7);
+		ir_dprintk("biphase decoded: %x\n", rc5);
 		if ((rc5 & 0xfffff000) != 0x3000)
 			break;
 		ir_input_keydown(&ir->input, &ir->ir, rc5 & 0x3f, rc5);
diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c
--- a/drivers/media/video/cx88/cx88-mpeg.c
+++ b/drivers/media/video/cx88/cx88-mpeg.c
@@ -1,5 +1,5 @@
 /*
- * $Id: cx88-mpeg.c,v 1.25 2005/03/07 14:18:00 kraxel Exp $
+ * $Id: cx88-mpeg.c,v 1.31 2005/07/07 14:17:47 mchehab Exp $
  *
  *  Support for the mpeg transport stream transfers
  *  PCI function #2 of the cx2388x.
@@ -55,7 +55,7 @@ static int cx8802_start_dma(struct cx880
 {
 	struct cx88_core *core = dev->core;
 
-	dprintk(1, "cx8802_start_mpegport_dma %d\n", buf->vb.width);
+	dprintk(0, "cx8802_start_dma %d\n", buf->vb.width);
 
 	/* setup fifo + format */
 	cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH28],
@@ -64,17 +64,21 @@ static int cx8802_start_dma(struct cx880
 	/* write TS length to chip */
 	cx_write(MO_TS_LNGTH, buf->vb.width);
 
-#if 1
 	/* FIXME: this needs a review.
 	 * also: move to cx88-blackbird + cx88-dvb source files? */
 
 	if (cx88_boards[core->board].dvb) {
 		/* negedge driven & software reset */
-		cx_write(TS_GEN_CNTRL, 0x40);
+		cx_write(TS_GEN_CNTRL, 0x0040 | dev->ts_gen_cntrl);
 		udelay(100);
 		cx_write(MO_PINMUX_IO, 0x00);
-		cx_write(TS_HW_SOP_CNTRL,47<<16|188<<4|0x00);
-		cx_write(TS_SOP_STAT,0x00);
+		cx_write(TS_HW_SOP_CNTRL,0x47<<16|188<<4|0x01);
+		if ((core->board == CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q) ||
+		    (core->board == CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T)) {
+			cx_write(TS_SOP_STAT, 1<<13);
+		} else {
+			cx_write(TS_SOP_STAT, 0x00);
+		}
 		cx_write(TS_GEN_CNTRL, dev->ts_gen_cntrl);
 		udelay(100);
 	}
@@ -93,25 +97,27 @@ static int cx8802_start_dma(struct cx880
 		cx_write(TS_GEN_CNTRL, 0x06); /* punctured clock TS & posedge driven */
 		udelay(100);
 	}
-#endif
 
 	/* reset counter */
 	cx_write(MO_TS_GPCNTRL, GP_COUNT_CONTROL_RESET);
 	q->count = 1;
 
 	/* enable irqs */
+	dprintk( 0, "setting the interrupt mask\n" );
 	cx_set(MO_PCI_INTMSK, core->pci_irqmask | 0x04);
-	cx_write(MO_TS_INTMSK,  0x1f0011);
+	cx_set(MO_TS_INTMSK,  0x1f0011);
+	//cx_write(MO_TS_INTMSK,  0x0f0011);
 
 	/* start dma */
-	cx_write(MO_DEV_CNTRL2, (1<<5)); /* FIXME: s/write/set/ ??? */
-	cx_write(MO_TS_DMACNTRL, 0x11);
+	cx_set(MO_DEV_CNTRL2, (1<<5));
+	cx_set(MO_TS_DMACNTRL, 0x11);
 	return 0;
 }
 
 static int cx8802_stop_dma(struct cx8802_dev *dev)
 {
 	struct cx88_core *core = dev->core;
+	dprintk( 0, "cx8802_stop_dma\n" );
 
 	/* stop dma */
 	cx_clear(MO_TS_DMACNTRL, 0x11);
@@ -131,8 +137,12 @@ static int cx8802_restart_queue(struct c
 	struct cx88_buffer *buf;
 	struct list_head *item;
 
+	dprintk( 0, "cx8802_restart_queue\n" );
 	if (list_empty(&q->active))
+	{
+		dprintk( 0, "cx8802_restart_queue: queue is empty\n" );
 		return 0;
+	}
 
 	buf = list_entry(q->active.next, struct cx88_buffer, vb.queue);
 	dprintk(2,"restart_queue [%p/%d]: restart dma\n",
@@ -182,27 +192,32 @@ void cx8802_buf_queue(struct cx8802_dev 
 	struct cx88_buffer    *prev;
 	struct cx88_dmaqueue  *q    = &dev->mpegq;
 
+	dprintk( 1, "cx8802_buf_queue\n" );
 	/* add jump to stopper */
 	buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
 	buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
 
 	if (list_empty(&q->active)) {
+		dprintk( 0, "queue is empty - first active\n" );
 		list_add_tail(&buf->vb.queue,&q->active);
 		cx8802_start_dma(dev, q, buf);
 		buf->vb.state = STATE_ACTIVE;
 		buf->count    = q->count++;
 		mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
-		dprintk(2,"[%p/%d] %s - first active\n",
+		dprintk(0,"[%p/%d] %s - first active\n",
 			buf, buf->vb.i, __FUNCTION__);
+		//udelay(100);
 
 	} else {
+		dprintk( 1, "queue is not empty - append to active\n" );
 		prev = list_entry(q->active.prev, struct cx88_buffer, vb.queue);
 		list_add_tail(&buf->vb.queue,&q->active);
 		buf->vb.state = STATE_ACTIVE;
 		buf->count    = q->count++;
 		prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
-		dprintk(2,"[%p/%d] %s - append to active\n",
+		dprintk( 1, "[%p/%d] %s - append to active\n",
 			buf, buf->vb.i, __FUNCTION__);
+		//udelay(100);
 	}
 }
 
@@ -224,7 +239,10 @@ static void do_cancel_buffers(struct cx8
 			buf, buf->vb.i, reason, (unsigned long)buf->risc.dma);
 	}
 	if (restart)
+	{
+		dprintk(0, "restarting queue\n" );
 		cx8802_restart_queue(dev,q);
+	}
 	spin_unlock_irqrestore(&dev->slock,flags);
 }
 
@@ -232,6 +250,7 @@ void cx8802_cancel_buffers(struct cx8802
 {
 	struct cx88_dmaqueue *q = &dev->mpegq;
 
+	dprintk( 1, "cx8802_cancel_buffers" );
 	del_timer_sync(&q->timeout);
 	cx8802_stop_dma(dev);
 	do_cancel_buffers(dev,"cancel",0);
@@ -241,7 +260,7 @@ static void cx8802_timeout(unsigned long
 {
 	struct cx8802_dev *dev = (struct cx8802_dev*)data;
 
-	dprintk(1, "%s\n",__FUNCTION__);
+	dprintk(0, "%s\n",__FUNCTION__);
 
 	if (debug)
 		cx88_sram_channel_dump(dev->core, &cx88_sram_channels[SRAM_CH28]);
@@ -249,17 +268,28 @@ static void cx8802_timeout(unsigned long
 	do_cancel_buffers(dev,"timeout",1);
 }
 
+static char *cx88_mpeg_irqs[32] = {
+	"ts_risci1", NULL, NULL, NULL,
+	"ts_risci2", NULL, NULL, NULL,
+	"ts_oflow",  NULL, NULL, NULL,
+	"ts_sync",   NULL, NULL, NULL,
+	"opc_err", "par_err", "rip_err", "pci_abort",
+	"ts_err?",
+};
+
 static void cx8802_mpeg_irq(struct cx8802_dev *dev)
 {
 	struct cx88_core *core = dev->core;
 	u32 status, mask, count;
 
+	dprintk( 1, "cx8802_mpeg_irq\n" );
 	status = cx_read(MO_TS_INTSTAT);
 	mask   = cx_read(MO_TS_INTMSK);
 	if (0 == (status & mask))
 		return;
 
 	cx_write(MO_TS_INTSTAT, status);
+
 	if (debug || (status & mask & ~0xff))
 		cx88_print_irqbits(core->name, "irq mpeg ",
 				   cx88_mpeg_irqs, status, mask);
@@ -273,6 +303,7 @@ static void cx8802_mpeg_irq(struct cx880
 
 	/* risc1 y */
 	if (status & 0x01) {
+		dprintk( 1, "wake up\n" );
 		spin_lock(&dev->slock);
 		count = cx_read(MO_TS_GPCNT);
 		cx88_wakeup(dev->core, &dev->mpegq, count);
@@ -288,6 +319,7 @@ static void cx8802_mpeg_irq(struct cx880
 
         /* other general errors */
         if (status & 0x1f0100) {
+		dprintk( 0, "general errors: 0x%08x\n", status & 0x1f0100 );
                 spin_lock(&dev->slock);
 		cx8802_stop_dma(dev);
                 cx8802_restart_queue(dev,&dev->mpegq);
@@ -295,6 +327,8 @@ static void cx8802_mpeg_irq(struct cx880
         }
 }
 
+#define MAX_IRQ_LOOP 10
+
 static irqreturn_t cx8802_irq(int irq, void *dev_id, struct pt_regs *regs)
 {
 	struct cx8802_dev *dev = dev_id;
@@ -302,10 +336,13 @@ static irqreturn_t cx8802_irq(int irq, v
 	u32 status;
 	int loop, handled = 0;
 
-	for (loop = 0; loop < 10; loop++) {
+	for (loop = 0; loop < MAX_IRQ_LOOP; loop++) {
 		status = cx_read(MO_PCI_INTSTAT) & (core->pci_irqmask | 0x04);
 		if (0 == status)
 			goto out;
+		dprintk( 1, "cx8802_irq\n" );
+		dprintk( 1, "    loop: %d/%d\n", loop, MAX_IRQ_LOOP );
+		dprintk( 1, "    status: %d\n", status );
 		handled = 1;
 		cx_write(MO_PCI_INTSTAT, status);
 
@@ -314,7 +351,8 @@ static irqreturn_t cx8802_irq(int irq, v
 		if (status & 0x04)
 			cx8802_mpeg_irq(dev);
 	};
-	if (10 == loop) {
+	if (MAX_IRQ_LOOP == loop) {
+		dprintk( 0, "clearing mask\n" );
 		printk(KERN_WARNING "%s/0: irq loop -- clearing mask\n",
 		       core->name);
 		cx_write(MO_PCI_INTMSK,0);
@@ -378,6 +416,7 @@ int cx8802_init_common(struct cx8802_dev
 
 void cx8802_fini_common(struct cx8802_dev *dev)
 {
+	dprintk( 2, "cx8802_fini_common\n" );
 	cx8802_stop_dma(dev);
 	pci_disable_device(dev->pci);
 
@@ -399,16 +438,15 @@ int cx8802_suspend_common(struct pci_dev
 	/* stop mpeg dma */
 	spin_lock(&dev->slock);
 	if (!list_empty(&dev->mpegq.active)) {
+		dprintk( 2, "suspend\n" );
 		printk("%s: suspend mpeg\n", core->name);
 		cx8802_stop_dma(dev);
 		del_timer(&dev->mpegq.timeout);
 	}
 	spin_unlock(&dev->slock);
 
-#if 1
 	/* FIXME -- shutdown device */
 	cx88_shutdown(dev->core);
-#endif
 
 	pci_save_state(pci_dev);
 	if (0 != pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state))) {
@@ -430,10 +468,8 @@ int cx8802_resume_common(struct pci_dev 
 	pci_set_power_state(pci_dev, PCI_D0);
 	pci_restore_state(pci_dev);
 
-#if 1
 	/* FIXME: re-initialize hardware */
 	cx88_reset(dev->core);
-#endif
 
 	/* restart video+vbi capture */
 	spin_lock(&dev->slock);
@@ -463,4 +499,5 @@ EXPORT_SYMBOL(cx8802_resume_common);
  * Local variables:
  * c-basic-offset: 8
  * End:
+ * kate: eol "unix"; indent-width 3; remove-trailing-space on; replace-trailing-space-save on; tab-width 8; replace-tabs off; space-indent off; mixed-indent off
  */
diff --git a/drivers/media/video/cx88/cx88-reg.h b/drivers/media/video/cx88/cx88-reg.h
--- a/drivers/media/video/cx88/cx88-reg.h
+++ b/drivers/media/video/cx88/cx88-reg.h
@@ -1,5 +1,5 @@
 /*
-    $Id: cx88-reg.h,v 1.6 2004/10/13 10:39:00 kraxel Exp $
+    $Id: cx88-reg.h,v 1.8 2005/07/07 13:58:38 mchehab Exp $
 
     cx88x-hw.h - CX2388x register offsets
 
@@ -397,6 +397,7 @@
 #define AUD_RATE_ADJ4            0x3205e4
 #define AUD_RATE_ADJ5            0x3205e8
 #define AUD_APB_IN_RATE_ADJ      0x3205ec
+#define AUD_I2SCNTL              0x3205ec
 #define AUD_PHASE_FIX_CTL        0x3205f0
 #define AUD_PLL_PRESCALE         0x320600
 #define AUD_PLL_DDS              0x320604
@@ -603,20 +604,11 @@
 #define EN_I2SIN_STR2DAC        0x00004000
 #define EN_I2SIN_ENABLE         0x00008000
 
-#if 0
-/* old */
-#define EN_DMTRX_SUMDIFF        0x00000800
-#define EN_DMTRX_SUMR           0x00000880
-#define EN_DMTRX_LR             0x00000900
-#define EN_DMTRX_MONO           0x00000980
-#else
-/* dscaler cvs */
 #define EN_DMTRX_SUMDIFF        (0 << 7)
 #define EN_DMTRX_SUMR           (1 << 7)
 #define EN_DMTRX_LR             (2 << 7)
 #define EN_DMTRX_MONO           (3 << 7)
 #define EN_DMTRX_BYPASS         (1 << 11)
-#endif
 
 // Video
 #define VID_CAPTURE_CONTROL		0x310180
diff --git a/drivers/media/video/cx88/cx88-tvaudio.c b/drivers/media/video/cx88/cx88-tvaudio.c
--- a/drivers/media/video/cx88/cx88-tvaudio.c
+++ b/drivers/media/video/cx88/cx88-tvaudio.c
@@ -1,5 +1,5 @@
 /*
-    $Id: cx88-tvaudio.c,v 1.34 2005/03/07 16:10:51 kraxel Exp $
+    $Id: cx88-tvaudio.c,v 1.37 2005/07/07 13:58:38 mchehab Exp $
 
     cx88x-audio.c - Conexant CX23880/23881 audio downstream driver driver
 
@@ -127,7 +127,8 @@ static void set_audio_start(struct cx88_
 	cx_write(AUD_VOL_CTL,       (1 << 6));
 
 	//  increase level of input by 12dB
-	cx_write(AUD_AFE_12DB_EN,   0x0001);
+//	cx_write(AUD_AFE_12DB_EN,   0x0001);
+	cx_write(AUD_AFE_12DB_EN,   0x0000);
 
 	// start programming
 	cx_write(AUD_CTL,           0x0000);
@@ -143,9 +144,15 @@ static void set_audio_finish(struct cx88
 	u32 volume;
 
 	if (cx88_boards[core->board].blackbird) {
+		// sets sound input from external adc
+		cx_set(AUD_CTL, EN_I2SIN_ENABLE);
+		//cx_write(AUD_I2SINPUTCNTL, 0);
+		cx_write(AUD_I2SINPUTCNTL, 4);
+		cx_write(AUD_BAUDRATE, 1);
 		// 'pass-thru mode': this enables the i2s output to the mpeg encoder
-		cx_set(AUD_CTL, 0x2000);
+		cx_set(AUD_CTL, EN_I2SOUT_ENABLE);
 		cx_write(AUD_I2SOUTPUTCNTL, 1);
+		cx_write(AUD_I2SCNTL, 0);
 		//cx_write(AUD_APB_IN_RATE_ADJ, 0);
 	}
 
@@ -271,80 +278,6 @@ static void set_audio_standard_BTSC(stru
 	set_audio_finish(core);
 }
 
-#if 0
-static void set_audio_standard_NICAM(struct cx88_core *core)
-{
-	static const struct rlist nicam_common[] = {
-		/* from dscaler */
-    		{ AUD_RATE_ADJ1,           0x00000010 },
-    		{ AUD_RATE_ADJ2,           0x00000040 },
-    		{ AUD_RATE_ADJ3,           0x00000100 },
-    		{ AUD_RATE_ADJ4,           0x00000400 },
-    		{ AUD_RATE_ADJ5,           0x00001000 },
-    //		{ AUD_DMD_RA_DDS,          0x00c0d5ce },
-
-		// Deemphasis 1:
-		{ AUD_DEEMPHGAIN_R,        0x000023c2 },
-		{ AUD_DEEMPHNUMER1_R,      0x0002a7bc },
-		{ AUD_DEEMPHNUMER2_R,      0x0003023e },
-		{ AUD_DEEMPHDENOM1_R,      0x0000f3d0 },
-		{ AUD_DEEMPHDENOM2_R,      0x00000000 },
-
-#if 0
-		// Deemphasis 2: (other tv norm?)
-		{ AUD_DEEMPHGAIN_R,        0x0000c600 },
-		{ AUD_DEEMPHNUMER1_R,      0x00066738 },
-		{ AUD_DEEMPHNUMER2_R,      0x00066739 },
-		{ AUD_DEEMPHDENOM1_R,      0x0001e88c },
-		{ AUD_DEEMPHDENOM2_R,      0x0001e88c },
-#endif
-
-		{ AUD_DEEMPHDENOM2_R,      0x00000000 },
-		{ AUD_ERRLOGPERIOD_R,      0x00000fff },
-		{ AUD_ERRINTRPTTHSHLD1_R,  0x000003ff },
-		{ AUD_ERRINTRPTTHSHLD2_R,  0x000000ff },
-		{ AUD_ERRINTRPTTHSHLD3_R,  0x0000003f },
-		{ AUD_POLYPH80SCALEFAC,    0x00000003 },
-
-		// setup QAM registers
-		{ AUD_PDF_DDS_CNST_BYTE2,  0x06 },
-		{ AUD_PDF_DDS_CNST_BYTE1,  0x82 },
-		{ AUD_PDF_DDS_CNST_BYTE0,  0x16 },
-		{ AUD_QAM_MODE,            0x05 },
-
-                { /* end of list */ },
-        };
-	static const struct rlist nicam_pal_i[] = {
-		{ AUD_PDF_DDS_CNST_BYTE0,  0x12 },
-		{ AUD_PHACC_FREQ_8MSB,     0x3a },
-		{ AUD_PHACC_FREQ_8LSB,     0x93 },
-
-                { /* end of list */ },
-	};
-	static const struct rlist nicam_default[] = {
-		{ AUD_PDF_DDS_CNST_BYTE0,  0x16 },
-		{ AUD_PHACC_FREQ_8MSB,     0x34 },
-		{ AUD_PHACC_FREQ_8LSB,     0x4c },
-
-                { /* end of list */ },
-	};
-
-        set_audio_start(core, 0x0010,
-			EN_DMTRX_LR | EN_DMTRX_BYPASS | EN_NICAM_AUTO_STEREO);
-        set_audio_registers(core, nicam_common);
-	switch (core->tvaudio) {
-	case WW_NICAM_I:
-		dprintk("%s PAL-I NICAM (status: unknown)\n",__FUNCTION__);
-		set_audio_registers(core, nicam_pal_i);
-		break;
-	case WW_NICAM_BGDKL:
-		dprintk("%s PAL-BGDK NICAM (status: unknown)\n",__FUNCTION__);
-		set_audio_registers(core, nicam_default);
-		break;
-	};
-        set_audio_finish(core);
-}
-#endif
 
 static void set_audio_standard_NICAM_L(struct cx88_core *core, int stereo)
 {
@@ -707,50 +640,65 @@ static void set_audio_standard_EIAJ(stru
 	set_audio_finish(core);
 }
 
-static void set_audio_standard_FM(struct cx88_core *core)
+static void set_audio_standard_FM(struct cx88_core *core, enum cx88_deemph_type deemph)
 {
-#if 0 /* FIXME */
-	switch (dev->audio_properties.FM_deemphasis)
-	{
-		case WW_FM_DEEMPH_50:
-			//Set De-emphasis filter coefficients for 50 usec
-			cx_write(AUD_DEEMPH0_G0, 0x0C45);
-			cx_write(AUD_DEEMPH0_A0, 0x6262);
-			cx_write(AUD_DEEMPH0_B0, 0x1C29);
-			cx_write(AUD_DEEMPH0_A1, 0x3FC66);
-			cx_write(AUD_DEEMPH0_B1, 0x399A);
-
-			cx_write(AUD_DEEMPH1_G0, 0x0D80);
-			cx_write(AUD_DEEMPH1_A0, 0x6262);
-			cx_write(AUD_DEEMPH1_B0, 0x1C29);
-			cx_write(AUD_DEEMPH1_A1, 0x3FC66);
-			cx_write(AUD_DEEMPH1_B1, 0x399A);
+	static const struct rlist fm_deemph_50[] = {
+		{ AUD_DEEMPH0_G0,	0x0C45 },
+		{ AUD_DEEMPH0_A0,	0x6262 },
+		{ AUD_DEEMPH0_B0,	0x1C29 },
+		{ AUD_DEEMPH0_A1,	0x3FC66},
+		{ AUD_DEEMPH0_B1,	0x399A },
+
+		{ AUD_DEEMPH1_G0,	0x0D80 },
+		{ AUD_DEEMPH1_A0,	0x6262 },
+		{ AUD_DEEMPH1_B0,	0x1C29 },
+		{ AUD_DEEMPH1_A1,	0x3FC66},
+		{ AUD_DEEMPH1_B1,	0x399A},
 
-			break;
+		{ AUD_POLYPH80SCALEFAC,	0x0003},
+		{ /* end of list */ },
+	};
+	static const struct rlist fm_deemph_75[] = {
+		{ AUD_DEEMPH0_G0,	0x091B },
+		{ AUD_DEEMPH0_A0,	0x6B68 },
+		{ AUD_DEEMPH0_B0,	0x11EC },
+		{ AUD_DEEMPH0_A1,	0x3FC66},
+		{ AUD_DEEMPH0_B1,	0x399A },
+
+		{ AUD_DEEMPH1_G0,	0x0AA0 },
+		{ AUD_DEEMPH1_A0,	0x6B68 },
+		{ AUD_DEEMPH1_B0,	0x11EC },
+		{ AUD_DEEMPH1_A1,	0x3FC66},
+		{ AUD_DEEMPH1_B1,	0x399A},
 
-		case WW_FM_DEEMPH_75:
-			//Set De-emphasis filter coefficients for 75 usec
-			cx_write(AUD_DEEMPH0_G0, 0x91B );
-			cx_write(AUD_DEEMPH0_A0, 0x6B68);
-			cx_write(AUD_DEEMPH0_B0, 0x11EC);
-			cx_write(AUD_DEEMPH0_A1, 0x3FC66);
-			cx_write(AUD_DEEMPH0_B1, 0x399A);
-
-			cx_write(AUD_DEEMPH1_G0, 0xAA0 );
-			cx_write(AUD_DEEMPH1_A0, 0x6B68);
-			cx_write(AUD_DEEMPH1_B0, 0x11EC);
-			cx_write(AUD_DEEMPH1_A1, 0x3FC66);
-			cx_write(AUD_DEEMPH1_B1, 0x399A);
+		{ AUD_POLYPH80SCALEFAC,	0x0003},
+		{ /* end of list */ },
+	};
 
-			break;
-	}
-#endif
+	/* It is enough to leave default values? */
+	static const struct rlist fm_no_deemph[] = {
+
+		{ AUD_POLYPH80SCALEFAC,	0x0003},
+		{ /* end of list */ },
+	};
 
 	dprintk("%s (status: unknown)\n",__FUNCTION__);
 	set_audio_start(core, 0x0020, EN_FMRADIO_AUTO_STEREO);
 
-	// AB: 10/2/01: this register is not being reset appropriately on occasion.
-	cx_write(AUD_POLYPH80SCALEFAC,3);
+	switch (deemph)
+	{
+		case FM_NO_DEEMPH:
+			set_audio_registers(core, fm_no_deemph);
+			break;
+
+		case FM_DEEMPH_50:
+			set_audio_registers(core, fm_deemph_50);
+			break;
+
+		case FM_DEEMPH_75:
+			set_audio_registers(core, fm_deemph_75);
+			break;
+	}
 
 	set_audio_finish(core);
 }
@@ -778,7 +726,7 @@ void cx88_set_tvaudio(struct cx88_core *
 		set_audio_standard_EIAJ(core);
 		break;
 	case WW_FM:
-		set_audio_standard_FM(core);
+		set_audio_standard_FM(core,FM_NO_DEEMPH);
 		break;
 	case WW_SYSTEM_L_AM:
 		set_audio_standard_NICAM_L(core, 1);
@@ -1029,4 +977,5 @@ EXPORT_SYMBOL(cx88_audio_thread);
  * Local variables:
  * c-basic-offset: 8
  * End:
+ * kate: eol "unix"; indent-width 3; remove-trailing-space on; replace-trailing-space-save on; tab-width 8; replace-tabs off; space-indent off; mixed-indent off
  */
diff --git a/drivers/media/video/cx88/cx88-vbi.c b/drivers/media/video/cx88/cx88-vbi.c
--- a/drivers/media/video/cx88/cx88-vbi.c
+++ b/drivers/media/video/cx88/cx88-vbi.c
@@ -1,5 +1,5 @@
 /*
- * $Id: cx88-vbi.c,v 1.16 2004/12/10 12:33:39 kraxel Exp $
+ * $Id: cx88-vbi.c,v 1.17 2005/06/12 04:19:19 mchehab Exp $
  */
 #include <linux/kernel.h>
 #include <linux/module.h>
@@ -47,8 +47,8 @@ void cx8800_vbi_fmt(struct cx8800_dev *d
 }
 
 static int cx8800_start_vbi_dma(struct cx8800_dev    *dev,
-				struct cx88_dmaqueue *q,
-				struct cx88_buffer   *buf)
+			 struct cx88_dmaqueue *q,
+			 struct cx88_buffer   *buf)
 {
 	struct cx88_core *core = dev->core;
 
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c
--- a/drivers/media/video/cx88/cx88-video.c
+++ b/drivers/media/video/cx88/cx88-video.c
@@ -1,5 +1,5 @@
 /*
- * $Id: cx88-video.c,v 1.58 2005/03/07 15:58:05 kraxel Exp $
+ * $Id: cx88-video.c,v 1.82 2005/07/22 05:13:34 mkrufky Exp $
  *
  * device driver for Conexant 2388x based TV cards
  * video4linux video interface
@@ -86,13 +86,6 @@ static struct cx88_tvnorm tvnorms[] = {
 		.id        = V4L2_STD_NTSC_M_JP,
 		.cxiformat = VideoFormatNTSCJapan,
 		.cxoformat = 0x181f0008,
-#if 0
-	},{
-		.name      = "NTSC-4.43",
-		.id        = FIXME,
-		.cxiformat = VideoFormatNTSC443,
-		.cxoformat = 0x181f0008,
-#endif
 	},{
 		.name      = "PAL-BG",
 		.id        = V4L2_STD_PAL_BG,
@@ -248,6 +241,7 @@ static struct cx88_ctrl cx8800_ctls[] = 
 			.default_value = 0,
 			.type          = V4L2_CTRL_TYPE_INTEGER,
 		},
+		.off                   = 0,
 		.reg                   = MO_CONTR_BRIGHT,
 		.mask                  = 0xff00,
 		.shift                 = 8,
@@ -261,7 +255,7 @@ static struct cx88_ctrl cx8800_ctls[] = 
 			.default_value = 0,
 			.type          = V4L2_CTRL_TYPE_INTEGER,
 		},
-		.off                   = 0,
+		.off                   = 128,
 		.reg                   = MO_HUE,
 		.mask                  = 0x00ff,
 		.shift                 = 0,
@@ -674,231 +668,6 @@ static struct videobuf_queue_ops cx8800_
 
 /* ------------------------------------------------------------------ */
 
-#if 0 /* overlay support not finished yet */
-static u32* ov_risc_field(struct cx8800_dev *dev, struct cx8800_fh *fh,
-			  u32 *rp, struct btcx_skiplist *skips,
-			  u32 sync_line, int skip_even, int skip_odd)
-{
-	int line,maxy,start,end,skip,nskips;
-	u32 ri,ra;
-	u32 addr;
-
-	/* sync instruction */
-	*(rp++) = cpu_to_le32(RISC_RESYNC | sync_line);
-
-	addr  = (unsigned long)dev->fbuf.base;
-	addr += dev->fbuf.fmt.bytesperline * fh->win.w.top;
-	addr += (fh->fmt->depth >> 3)      * fh->win.w.left;
-
-	/* scan lines */
-	for (maxy = -1, line = 0; line < fh->win.w.height;
-	     line++, addr += dev->fbuf.fmt.bytesperline) {
-		if ((line%2) == 0  &&  skip_even)
-			continue;
-		if ((line%2) == 1  &&  skip_odd)
-			continue;
-
-		/* calculate clipping */
-		if (line > maxy)
-			btcx_calc_skips(line, fh->win.w.width, &maxy,
-					skips, &nskips, fh->clips, fh->nclips);
-
-		/* write out risc code */
-		for (start = 0, skip = 0; start < fh->win.w.width; start = end) {
-			if (skip >= nskips) {
-				ri  = RISC_WRITE;
-				end = fh->win.w.width;
-			} else if (start < skips[skip].start) {
-				ri  = RISC_WRITE;
-				end = skips[skip].start;
-			} else {
-				ri  = RISC_SKIP;
-				end = skips[skip].end;
-				skip++;
-			}
-			if (RISC_WRITE == ri)
-				ra = addr + (fh->fmt->depth>>3)*start;
-			else
-				ra = 0;
-
-			if (0 == start)
-				ri |= RISC_SOL;
-			if (fh->win.w.width == end)
-				ri |= RISC_EOL;
-			ri |= (fh->fmt->depth>>3) * (end-start);
-
-			*(rp++)=cpu_to_le32(ri);
-			if (0 != ra)
-				*(rp++)=cpu_to_le32(ra);
-		}
-	}
-	kfree(skips);
-	return rp;
-}
-
-static int ov_risc_frame(struct cx8800_dev *dev, struct cx8800_fh *fh,
-			 struct cx88_buffer *buf)
-{
-	struct btcx_skiplist *skips;
-	u32 instructions,fields;
-	u32 *rp;
-	int rc;
-
-	/* skip list for window clipping */
-	if (NULL == (skips = kmalloc(sizeof(*skips) * fh->nclips,GFP_KERNEL)))
-		return -ENOMEM;
-
-	fields = 0;
-	if (V4L2_FIELD_HAS_TOP(fh->win.field))
-		fields++;
-	if (V4L2_FIELD_HAS_BOTTOM(fh->win.field))
-		fields++;
-
-        /* estimate risc mem: worst case is (clip+1) * lines instructions
-           + syncs + jump (all 2 dwords) */
-	instructions  = (fh->nclips+1) * fh->win.w.height;
-	instructions += 3 + 4;
-	if ((rc = btcx_riscmem_alloc(dev->pci,&buf->risc,instructions*8)) < 0) {
-		kfree(skips);
-		return rc;
-	}
-
-	/* write risc instructions */
-	rp = buf->risc.cpu;
-	switch (fh->win.field) {
-	case V4L2_FIELD_TOP:
-		rp = ov_risc_field(dev, fh, rp, skips, 0,     0, 0);
-		break;
-	case V4L2_FIELD_BOTTOM:
-		rp = ov_risc_field(dev, fh, rp, skips, 0x200, 0, 0);
-		break;
-	case V4L2_FIELD_INTERLACED:
-		rp = ov_risc_field(dev, fh, rp, skips, 0,     0, 1);
-		rp = ov_risc_field(dev, fh, rp, skips, 0x200, 1, 0);
-		break;
-	default:
-		BUG();
-	}
-
-	/* save pointer to jmp instruction address */
-	buf->risc.jmp = rp;
-	kfree(skips);
-	return 0;
-}
-
-static int verify_window(struct cx8800_dev *dev, struct v4l2_window *win)
-{
-	enum v4l2_field field;
-	int maxw, maxh;
-
-	if (NULL == dev->fbuf.base)
-		return -EINVAL;
-	if (win->w.width < 48 || win->w.height <  32)
-		return -EINVAL;
-	if (win->clipcount > 2048)
-		return -EINVAL;
-
-	field = win->field;
-	maxw  = norm_maxw(core->tvnorm);
-	maxh  = norm_maxh(core->tvnorm);
-
-	if (V4L2_FIELD_ANY == field) {
-                field = (win->w.height > maxh/2)
-                        ? V4L2_FIELD_INTERLACED
-                        : V4L2_FIELD_TOP;
-        }
-        switch (field) {
-        case V4L2_FIELD_TOP:
-        case V4L2_FIELD_BOTTOM:
-                maxh = maxh / 2;
-                break;
-        case V4L2_FIELD_INTERLACED:
-                break;
-        default:
-                return -EINVAL;
-        }
-
-	win->field = field;
-	if (win->w.width > maxw)
-		win->w.width = maxw;
-	if (win->w.height > maxh)
-		win->w.height = maxh;
-	return 0;
-}
-
-static int setup_window(struct cx8800_dev *dev, struct cx8800_fh *fh,
-			struct v4l2_window *win)
-{
-	struct v4l2_clip *clips = NULL;
-	int n,size,retval = 0;
-
-	if (NULL == fh->fmt)
-		return -EINVAL;
-	retval = verify_window(dev,win);
-	if (0 != retval)
-		return retval;
-
-	/* copy clips  --  luckily v4l1 + v4l2 are binary
-	   compatible here ...*/
-	n = win->clipcount;
-	size = sizeof(*clips)*(n+4);
-	clips = kmalloc(size,GFP_KERNEL);
-	if (NULL == clips)
-		return -ENOMEM;
-	if (n > 0) {
-		if (copy_from_user(clips,win->clips,sizeof(struct v4l2_clip)*n)) {
-			kfree(clips);
-			return -EFAULT;
-		}
-	}
-
-	/* clip against screen */
-	if (NULL != dev->fbuf.base)
-		n = btcx_screen_clips(dev->fbuf.fmt.width, dev->fbuf.fmt.height,
-				      &win->w, clips, n);
-	btcx_sort_clips(clips,n);
-
-	/* 4-byte alignments */
-	switch (fh->fmt->depth) {
-	case 8:
-	case 24:
-		btcx_align(&win->w, clips, n, 3);
-		break;
-	case 16:
-		btcx_align(&win->w, clips, n, 1);
-		break;
-	case 32:
-		/* no alignment fixups needed */
-		break;
-	default:
-		BUG();
-	}
-
-	down(&fh->vidq.lock);
-	if (fh->clips)
-		kfree(fh->clips);
-	fh->clips    = clips;
-	fh->nclips   = n;
-	fh->win      = *win;
-#if 0
-	fh->ov.setup_ok = 1;
-#endif
-
-	/* update overlay if needed */
-	retval = 0;
-#if 0
-	if (check_btres(fh, RESOURCE_OVERLAY)) {
-		struct bttv_buffer *new;
-
-		new = videobuf_alloc(sizeof(*new));
-		bttv_overlay_risc(btv, &fh->ov, fh->ovfmt, new);
-		retval = bttv_switch_overlay(btv,fh,new);
-	}
-#endif
-	up(&fh->vidq.lock);
-	return retval;
-}
-#endif
 
 /* ------------------------------------------------------------------ */
 
@@ -989,10 +758,10 @@ static int video_open(struct inode *inod
 		struct cx88_core *core = dev->core;
 		int board = core->board;
 		dprintk(1,"video_open: setting radio device\n");
+		cx_write(MO_GP3_IO, cx88_boards[board].radio.gpio3);
 		cx_write(MO_GP0_IO, cx88_boards[board].radio.gpio0);
 		cx_write(MO_GP1_IO, cx88_boards[board].radio.gpio1);
 		cx_write(MO_GP2_IO, cx88_boards[board].radio.gpio2);
-		cx_write(MO_GP3_IO, cx88_boards[board].radio.gpio3);
 		dev->core->tvaudio = WW_FM;
 		cx88_set_tvaudio(core);
 		cx88_set_stereo(core,V4L2_TUNER_MODE_STEREO,1);
@@ -1187,9 +956,24 @@ static void init_controls(struct cx8800_
 		.id    = V4L2_CID_AUDIO_VOLUME,
 		.value = 0x3f,
 	};
+	static struct v4l2_control hue = {
+		.id    = V4L2_CID_HUE,
+		.value = 0x80,
+	};
+	static struct v4l2_control contrast = {
+		.id    = V4L2_CID_CONTRAST,
+		.value = 0x80,
+	};
+	static struct v4l2_control brightness = {
+		.id    = V4L2_CID_BRIGHTNESS,
+		.value = 0x80,
+	};
 
 	set_control(dev,&mute);
 	set_control(dev,&volume);
+	set_control(dev,&hue);
+	set_control(dev,&contrast);
+	set_control(dev,&brightness);
 }
 
 /* ------------------------------------------------------------------ */
@@ -1312,9 +1096,6 @@ static int video_do_ioctl(struct inode *
 	struct cx8800_fh  *fh   = file->private_data;
 	struct cx8800_dev *dev  = fh->dev;
 	struct cx88_core  *core = dev->core;
-#if 0
-	unsigned long flags;
-#endif
 	int err;
 
 	if (video_debug > 1)
@@ -1335,9 +1116,6 @@ static int video_do_ioctl(struct inode *
 			V4L2_CAP_READWRITE     |
 			V4L2_CAP_STREAMING     |
 			V4L2_CAP_VBI_CAPTURE   |
-#if 0
-			V4L2_CAP_VIDEO_OVERLAY |
-#endif
 			0;
 		if (UNSET != core->tuner_type)
 			cap->capabilities |= V4L2_CAP_TUNER;
@@ -1438,36 +1216,6 @@ static int video_do_ioctl(struct inode *
 	}
 
 
-#if 0
-	/* needs review */
-	case VIDIOC_G_AUDIO:
-	{
-		struct v4l2_audio *a = arg;
-		unsigned int n = a->index;
-
-		memset(a,0,sizeof(*a));
-		a->index = n;
-		switch (n) {
-		case 0:
-			if ((CX88_VMUX_TELEVISION == INPUT(n)->type)
-			    || (CX88_VMUX_CABLE == INPUT(n)->type)) {
-				strcpy(a->name,"Television");
-				// FIXME figure out if stereo received and set V4L2_AUDCAP_STEREO.
-				return 0;
-			}
-			break;
-		case 1:
-			if (CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD == core->board) {
-				strcpy(a->name,"Line In");
-				a->capability = V4L2_AUDCAP_STEREO;
-				return 0;
-			}
-			break;
-		}
-		// Audio input not available.
-		return -EINVAL;
-	}
-#endif
 
 	/* --- capture ioctls ---------------------------------------- */
 	case VIDIOC_ENUM_FMT:
@@ -1570,13 +1318,16 @@ static int video_do_ioctl(struct inode *
 	{
 		struct v4l2_frequency *f = arg;
 
+		memset(f,0,sizeof(*f));
+
 		if (UNSET == core->tuner_type)
 			return -EINVAL;
-		if (f->tuner != 0)
-			return -EINVAL;
-		memset(f,0,sizeof(*f));
+
 		f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
 		f->frequency = dev->freq;
+
+		cx88_call_i2c_clients(dev->core,VIDIOC_G_FREQUENCY,f);
+
 		return 0;
 	}
 	case VIDIOC_S_FREQUENCY:
@@ -1594,11 +1345,12 @@ static int video_do_ioctl(struct inode *
 		down(&dev->lock);
 		dev->freq = f->frequency;
 		cx88_newstation(core);
-#ifdef V4L2_I2C_CLIENTS
 		cx88_call_i2c_clients(dev->core,VIDIOC_S_FREQUENCY,f);
-#else
-		cx88_call_i2c_clients(dev->core,VIDIOCSFREQ,&dev->freq);
-#endif
+
+		/* When changing channels it is required to reset TVAUDIO */
+		msleep (10);
+		cx88_set_tvaudio(core);
+
 		up(&dev->lock);
 		return 0;
 	}
@@ -1708,19 +1460,8 @@ static int radio_do_ioctl(struct inode *
 
 		memset(t,0,sizeof(*t));
 		strcpy(t->name, "Radio");
-                t->rangelow  = (int)(65*16);
-                t->rangehigh = (int)(108*16);
 
-#ifdef V4L2_I2C_CLIENTS
 		cx88_call_i2c_clients(dev->core,VIDIOC_G_TUNER,t);
-#else
-		{
-			struct video_tuner vt;
-			memset(&vt,0,sizeof(vt));
-			cx88_call_i2c_clients(dev,VIDIOCGTUNER,&vt);
-			t->signal = vt.signal;
-		}
-#endif
 		return 0;
 	}
 	case VIDIOC_ENUMINPUT:
@@ -1753,8 +1494,29 @@ static int radio_do_ioctl(struct inode *
 		*id = 0;
 		return 0;
 	}
-	case VIDIOC_S_AUDIO:
+	case VIDIOCSTUNER:
+	{
+		struct video_tuner *v = arg;
+
+		if (v->tuner) /* Only tuner 0 */
+			return -EINVAL;
+
+		cx88_call_i2c_clients(dev->core,VIDIOCSTUNER,v);
+                return 0;
+	}
 	case VIDIOC_S_TUNER:
+	{
+		struct v4l2_tuner *t = arg;
+
+		if (0 != t->index)
+			return -EINVAL;
+
+		cx88_call_i2c_clients(dev->core,VIDIOC_S_TUNER,t);
+
+		return 0;
+	}
+
+	case VIDIOC_S_AUDIO:
 	case VIDIOC_S_INPUT:
 	case VIDIOC_S_STD:
 		return 0;
@@ -1825,6 +1587,14 @@ static void cx8800_vid_timeout(unsigned 
 	spin_unlock_irqrestore(&dev->slock,flags);
 }
 
+static char *cx88_vid_irqs[32] = {
+	"y_risci1", "u_risci1", "v_risci1", "vbi_risc1",
+	"y_risci2", "u_risci2", "v_risci2", "vbi_risc2",
+	"y_oflow",  "u_oflow",  "v_oflow",  "vbi_oflow",
+	"y_sync",   "u_sync",   "v_sync",   "vbi_sync",
+	"opc_err",  "par_err",  "rip_err",  "pci_abort",
+};
+
 static void cx8800_vid_irq(struct cx8800_dev *dev)
 {
 	struct cx88_core *core = dev->core;
@@ -2065,11 +1835,6 @@ static int __devinit cx8800_initdev(stru
 		request_module("tuner");
 	if (core->tda9887_conf)
 		request_module("tda9887");
-	if (core->tuner_type != UNSET)
-		cx88_call_i2c_clients(dev->core,TUNER_SET_TYPE,&core->tuner_type);
-	if (core->tda9887_conf)
-		cx88_call_i2c_clients(dev->core,TDA9887_SET_CONFIG,&core->tda9887_conf);
-
 	/* register v4l devices */
 	dev->video_dev = cx88_vdev_init(core,dev->pci,
 					&cx8800_video_template,"video");
@@ -2162,7 +1927,7 @@ static void __devexit cx8800_finidev(str
 
 static int cx8800_suspend(struct pci_dev *pci_dev, pm_message_t state)
 {
-        struct cx8800_dev *dev = pci_get_drvdata(pci_dev);
+	struct cx8800_dev *dev = pci_get_drvdata(pci_dev);
 	struct cx88_core *core = dev->core;
 
 	/* stop video+vbi capture */
@@ -2179,10 +1944,8 @@ static int cx8800_suspend(struct pci_dev
 	}
 	spin_unlock(&dev->slock);
 
-#if 1
 	/* FIXME -- shutdown device */
 	cx88_shutdown(dev->core);
-#endif
 
 	pci_save_state(pci_dev);
 	if (0 != pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state))) {
@@ -2194,7 +1957,7 @@ static int cx8800_suspend(struct pci_dev
 
 static int cx8800_resume(struct pci_dev *pci_dev)
 {
-        struct cx8800_dev *dev = pci_get_drvdata(pci_dev);
+	struct cx8800_dev *dev = pci_get_drvdata(pci_dev);
 	struct cx88_core *core = dev->core;
 
 	if (dev->state.disabled) {
@@ -2204,10 +1967,8 @@ static int cx8800_resume(struct pci_dev 
 	pci_set_power_state(pci_dev, PCI_D0);
 	pci_restore_state(pci_dev);
 
-#if 1
 	/* FIXME: re-initialize hardware */
 	cx88_reset(dev->core);
-#endif
 
 	/* restart video+vbi capture */
 	spin_lock(&dev->slock);
@@ -2230,8 +1991,8 @@ static struct pci_device_id cx8800_pci_t
 	{
 		.vendor       = 0x14f1,
 		.device       = 0x8800,
-                .subvendor    = PCI_ANY_ID,
-                .subdevice    = PCI_ANY_ID,
+		.subvendor    = PCI_ANY_ID,
+		.subdevice    = PCI_ANY_ID,
 	},{
 		/* --- end of list --- */
 	}
@@ -2239,10 +2000,10 @@ static struct pci_device_id cx8800_pci_t
 MODULE_DEVICE_TABLE(pci, cx8800_pci_tbl);
 
 static struct pci_driver cx8800_pci_driver = {
-        .name     = "cx8800",
-        .id_table = cx8800_pci_tbl,
-        .probe    = cx8800_initdev,
-        .remove   = __devexit_p(cx8800_finidev),
+	.name     = "cx8800",
+	.id_table = cx8800_pci_tbl,
+	.probe    = cx8800_initdev,
+	.remove   = __devexit_p(cx8800_finidev),
 
 	.suspend  = cx8800_suspend,
 	.resume   = cx8800_resume,
@@ -2274,4 +2035,5 @@ module_exit(cx8800_fini);
  * Local variables:
  * c-basic-offset: 8
  * End:
+ * kate: eol "unix"; indent-width 3; remove-trailing-space on; replace-trailing-space-save on; tab-width 8; replace-tabs off; space-indent off; mixed-indent off
  */
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
--- a/drivers/media/video/cx88/cx88.h
+++ b/drivers/media/video/cx88/cx88.h
@@ -1,5 +1,5 @@
 /*
- * $Id: cx88.h,v 1.56 2005/03/04 09:12:23 kraxel Exp $
+ * $Id: cx88.h,v 1.70 2005/07/24 17:44:09 mkrufky Exp $
  *
  * v4l2 device driver for cx2388x based TV cards
  *
@@ -35,8 +35,8 @@
 #include "btcx-risc.h"
 #include "cx88-reg.h"
 
-#include <linux/version.h>
-#define CX88_VERSION_CODE KERNEL_VERSION(0,0,4)
+#include <linux/utsname.h>
+#define CX88_VERSION_CODE KERNEL_VERSION(0,0,5)
 
 #ifndef TRUE
 # define TRUE (1==1)
@@ -51,8 +51,6 @@
 /* ----------------------------------------------------------- */
 /* defines and enums                                           */
 
-#define V4L2_I2C_CLIENTS 1
-
 #define FORMAT_FLAGS_PACKED       0x01
 #define FORMAT_FLAGS_PLANAR       0x02
 
@@ -64,6 +62,13 @@
 #define SHADOW_AUD_BAL_CTL           2
 #define SHADOW_MAX                   2
 
+/* FM Radio deemphasis type */
+enum cx88_deemph_type {
+	FM_NO_DEEMPH = 0,
+	FM_DEEMPH_50,
+	FM_DEEMPH_75
+};
+
 /* ----------------------------------------------------------- */
 /* tv norms                                                    */
 
@@ -77,9 +82,9 @@ struct cx88_tvnorm {
 static unsigned int inline norm_maxw(struct cx88_tvnorm *norm)
 {
 	return (norm->id & V4L2_STD_625_50) ? 768 : 640;
-//	return (norm->id & V4L2_STD_625_50) ? 720 : 640;
 }
 
+
 static unsigned int inline norm_maxh(struct cx88_tvnorm *norm)
 {
 	return (norm->id & V4L2_STD_625_50) ? 576 : 480;
@@ -152,7 +157,7 @@ extern struct sram_channel cx88_sram_cha
 #define CX88_BOARD_KWORLD_DVB_T            14
 #define CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1 15
 #define CX88_BOARD_KWORLD_LTV883           16
-#define CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD 17
+#define CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q  17
 #define CX88_BOARD_HAUPPAUGE_DVB_T1        18
 #define CX88_BOARD_CONEXANT_DVB_T1         19
 #define CX88_BOARD_PROVIDEO_PV259          20
@@ -160,8 +165,13 @@ extern struct sram_channel cx88_sram_cha
 #define CX88_BOARD_PCHDTV_HD3000           22
 #define CX88_BOARD_DNTV_LIVE_DVB_T         23
 #define CX88_BOARD_HAUPPAUGE_ROSLYN        24
-#define CX88_BOARD_DIGITALLOGIC_MEC	       25
+#define CX88_BOARD_DIGITALLOGIC_MEC        25
 #define CX88_BOARD_IODATA_GVBCTV7E         26
+#define CX88_BOARD_PIXELVIEW_PLAYTV_ULTRA_PRO 27
+#define CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T  28
+#define CX88_BOARD_ADSTECH_DVB_T_PCI          29
+#define CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1  30
+#define CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD 31
 
 enum cx88_itype {
 	CX88_VMUX_COMPOSITE1 = 1,
@@ -185,6 +195,9 @@ struct cx88_input {
 struct cx88_board {
 	char                    *name;
 	unsigned int            tuner_type;
+	unsigned int		radio_type;
+	unsigned char		tuner_addr;
+	unsigned char		radio_addr;
 	int                     tda9887_conf;
 	struct cx88_input       input[8];
 	struct cx88_input       radio;
@@ -208,7 +221,6 @@ struct cx88_subid {
 #define RESOURCE_VBI           4
 
 #define BUFFER_TIMEOUT     (HZ/2)  /* 0.5 seconds */
-//#define BUFFER_TIMEOUT     (HZ*2)
 
 /* buffer for one video frame */
 struct cx88_buffer {
@@ -255,6 +267,9 @@ struct cx88_core {
 	/* config info -- analog */
 	unsigned int               board;
 	unsigned int               tuner_type;
+	unsigned int               radio_type;
+	unsigned char              tuner_addr;
+	unsigned char              radio_addr;
 	unsigned int               tda9887_conf;
 	unsigned int               has_radio;
 
@@ -321,11 +336,6 @@ struct cx8800_dev {
 	struct pci_dev             *pci;
 	unsigned char              pci_rev,pci_lat;
 
-#if 0
-	/* video overlay */
-	struct v4l2_framebuffer    fbuf;
-	struct cx88_buffer         *screen;
-#endif
 
 	/* capture queues */
 	struct cx88_dmaqueue       vidq;
@@ -420,8 +430,6 @@ struct cx8802_dev {
 /* ----------------------------------------------------------- */
 /* cx88-core.c                                                 */
 
-extern char *cx88_vid_irqs[32];
-extern char *cx88_mpeg_irqs[32];
 extern void cx88_print_irqbits(char *name, char *tag, char **strings,
 			       u32 bits, u32 mask);
 extern void cx88_print_ioctl(char *name, unsigned int cmd);
@@ -471,6 +479,11 @@ extern void cx88_core_put(struct cx88_co
 /* cx88-vbi.c                                                  */
 
 void cx8800_vbi_fmt(struct cx8800_dev *dev, struct v4l2_format *f);
+/*
+int cx8800_start_vbi_dma(struct cx8800_dev    *dev,
+			 struct cx88_dmaqueue *q,
+			 struct cx88_buffer   *buf);
+*/
 int cx8800_stop_vbi_dma(struct cx8800_dev *dev);
 int cx8800_restart_vbi_queue(struct cx8800_dev    *dev,
 			     struct cx88_dmaqueue *q);
diff --git a/drivers/media/video/ir-kbd-gpio.c b/drivers/media/video/ir-kbd-gpio.c
--- a/drivers/media/video/ir-kbd-gpio.c
+++ b/drivers/media/video/ir-kbd-gpio.c
@@ -1,5 +1,5 @@
 /*
- * $Id: ir-kbd-gpio.c,v 1.12 2005/02/22 12:28:40 kraxel Exp $
+ * $Id: ir-kbd-gpio.c,v 1.13 2005/05/15 19:01:26 mchehab Exp $
  *
  * Copyright (c) 2003 Gerd Knorr
  * Copyright (c) 2003 Pavel Machek
@@ -114,38 +114,6 @@ static IR_KEYTAB_TYPE ir_codes_avermedia
 	[ 0x3e ] = KEY_VOLUMEUP,    // 'volume +'
 };
 
-static IR_KEYTAB_TYPE ir_codes_pixelview[IR_KEYTAB_SIZE] = {
-	[  2 ] = KEY_KP0,
-	[  1 ] = KEY_KP1,
-	[ 11 ] = KEY_KP2,
-	[ 27 ] = KEY_KP3,
-	[  5 ] = KEY_KP4,
-	[  9 ] = KEY_KP5,
-	[ 21 ] = KEY_KP6,
-	[  6 ] = KEY_KP7,
-	[ 10 ] = KEY_KP8,
-	[ 18 ] = KEY_KP9,
-
-	[  3 ] = KEY_TUNER,       // TV/FM
-	[  7 ] = KEY_SEARCH,      // scan
-	[ 28 ] = KEY_ZOOM,        // full screen
-	[ 30 ] = KEY_POWER,
-	[ 23 ] = KEY_VOLUMEDOWN,
-	[ 31 ] = KEY_VOLUMEUP,
-	[ 20 ] = KEY_CHANNELDOWN,
-	[ 22 ] = KEY_CHANNELUP,
-	[ 24 ] = KEY_MUTE,
-
-	[  0 ] = KEY_LIST,        // source
-	[ 19 ] = KEY_INFO,        // loop
-	[ 16 ] = KEY_LAST,        // +100
-	[ 13 ] = KEY_CLEAR,       // reset
-	[ 12 ] = BTN_RIGHT,       // fun++
-	[  4 ] = BTN_LEFT,        // fun--
-	[ 14 ] = KEY_GOTO,        // function
-	[ 15 ] = KEY_STOP,         // freeze
-};
-
 /* Attila Kondoros <attila.kondoros@chello.hu> */
 static IR_KEYTAB_TYPE ir_codes_apac_viewcomp[IR_KEYTAB_SIZE] = {
 
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c
--- a/drivers/media/video/ir-kbd-i2c.c
+++ b/drivers/media/video/ir-kbd-i2c.c
@@ -1,5 +1,5 @@
 /*
- * $Id: ir-kbd-i2c.c,v 1.10 2004/12/09 12:51:35 kraxel Exp $
+ * $Id: ir-kbd-i2c.c,v 1.11 2005/07/07 16:42:11 mchehab Exp $
  *
  * keyboard input driver for i2c IR remote controls
  *
@@ -66,26 +66,26 @@ static IR_KEYTAB_TYPE ir_codes_pv951[IR_
 	[ 29 ] = KEY_PAGEDOWN,
 	[ 19 ] = KEY_SOUND,
 
-	[ 24 ] = KEY_KPPLUSMINUS,	// CH +/-
-	[ 22 ] = KEY_SUBTITLE,		// CC
-	[ 13 ] = KEY_TEXT,		// TTX
-	[ 11 ] = KEY_TV,		// AIR/CBL
-	[ 17 ] = KEY_PC,		// PC/TV
-	[ 23 ] = KEY_OK,		// CH RTN
-	[ 25 ] = KEY_MODE, 		// FUNC
-	[ 12 ] = KEY_SEARCH, 		// AUTOSCAN
+	[ 24 ] = KEY_KPPLUSMINUS,	/* CH +/- */
+	[ 22 ] = KEY_SUBTITLE,		/* CC */
+	[ 13 ] = KEY_TEXT,		/* TTX */
+	[ 11 ] = KEY_TV,		/* AIR/CBL */
+	[ 17 ] = KEY_PC,		/* PC/TV */
+	[ 23 ] = KEY_OK,		/* CH RTN */
+	[ 25 ] = KEY_MODE, 		/* FUNC */
+	[ 12 ] = KEY_SEARCH, 		/* AUTOSCAN */
 
 	/* Not sure what to do with these ones! */
-	[ 15 ] = KEY_SELECT, 		// SOURCE
-	[ 10 ] = KEY_KPPLUS,		// +100
-	[ 20 ] = KEY_KPEQUAL,		// SYNC
-	[ 28 ] = KEY_MEDIA,             // PC/TV
+	[ 15 ] = KEY_SELECT, 		/* SOURCE */
+	[ 10 ] = KEY_KPPLUS,		/* +100 */
+	[ 20 ] = KEY_KPEQUAL,		/* SYNC */
+	[ 28 ] = KEY_MEDIA,             /* PC/TV */
 };
 
 static IR_KEYTAB_TYPE ir_codes_purpletv[IR_KEYTAB_SIZE] = {
 	[ 0x3  ] = KEY_POWER,
 	[ 0x6f ] = KEY_MUTE,
-	[ 0x10 ] = KEY_BACKSPACE,	// Recall
+	[ 0x10 ] = KEY_BACKSPACE,	/* Recall */
 
 	[ 0x11 ] = KEY_KP0,
 	[ 0x4  ] = KEY_KP1,
@@ -97,7 +97,7 @@ static IR_KEYTAB_TYPE ir_codes_purpletv[
 	[ 0xc  ] = KEY_KP7,
 	[ 0xd  ] = KEY_KP8,
 	[ 0xe  ] = KEY_KP9,
-	[ 0x12 ] = KEY_KPDOT,		// 100+
+	[ 0x12 ] = KEY_KPDOT,		/* 100+ */
 
 	[ 0x7  ] = KEY_VOLUMEUP,
 	[ 0xb  ] = KEY_VOLUMEDOWN,
@@ -109,25 +109,16 @@ static IR_KEYTAB_TYPE ir_codes_purpletv[
 	[ 0x13 ] = KEY_CHANNELDOWN,
 	[ 0x48 ] = KEY_ZOOM,
 
-	[ 0x1b ] = KEY_VIDEO,		// Video source
-#if 0
-	[ 0x1f ] = KEY_S,       	// Snapshot
-#endif
-	[ 0x49 ] = KEY_LANGUAGE,	// MTS Select
-	[ 0x19 ] = KEY_SEARCH,		// Auto Scan
+	[ 0x1b ] = KEY_VIDEO,		/* Video source */
+	[ 0x49 ] = KEY_LANGUAGE,	/* MTS Select */
+	[ 0x19 ] = KEY_SEARCH,		/* Auto Scan */
 
 	[ 0x4b ] = KEY_RECORD,
 	[ 0x46 ] = KEY_PLAY,
-	[ 0x45 ] = KEY_PAUSE,   	// Pause
+	[ 0x45 ] = KEY_PAUSE,   	/* Pause */
 	[ 0x44 ] = KEY_STOP,
-#if 0
-	[ 0x43 ] = KEY_T,    		// Time Shift
-	[ 0x47 ] = KEY_Y,    		// Time Shift OFF
-	[ 0x4a ] = KEY_O,    		// TOP
-	[ 0x17 ] = KEY_F,    		// SURF CH
-#endif
-	[ 0x40 ] = KEY_FORWARD,   	// Forward ?
-	[ 0x42 ] = KEY_REWIND,   	// Backward ?
+	[ 0x40 ] = KEY_FORWARD,   	/* Forward ? */
+	[ 0x42 ] = KEY_REWIND,   	/* Backward ? */
 
 };
 
diff --git a/drivers/media/video/msp3400.c b/drivers/media/video/msp3400.c
--- a/drivers/media/video/msp3400.c
+++ b/drivers/media/video/msp3400.c
@@ -147,7 +147,6 @@ static unsigned short normal_i2c[] = {
 	I2C_MSP3400C_ALT  >> 1,
 	I2C_CLIENT_END
 };
-static unsigned short normal_i2c_range[] = {I2C_CLIENT_END,I2C_CLIENT_END};
 I2C_CLIENT_INSMOD;
 
 /* ----------------------------------------------------------------------- */
@@ -568,10 +567,6 @@ static void msp3400c_set_audmode(struct 
 	switch (audmode) {
 	case V4L2_TUNER_MODE_STEREO:
 		src = 0x0020 | nicam;
-#if 0
-		/* spatial effect */
-		msp3400c_write(client,I2C_MSP3400C_DFP, 0x0005,0x4000);
-#endif
 		break;
 	case V4L2_TUNER_MODE_MONO:
 		if (msp->mode == MSP_MODE_AM_NICAM) {
@@ -736,28 +731,19 @@ static int msp34xx_sleep(struct msp3400c
 {
 	DECLARE_WAITQUEUE(wait, current);
 
-again:
 	add_wait_queue(&msp->wq, &wait);
 	if (!kthread_should_stop()) {
 		if (timeout < 0) {
 			set_current_state(TASK_INTERRUPTIBLE);
 			schedule();
 		} else {
-#if 0
-			/* hmm, that one doesn't return on wakeup ... */
-			msleep_interruptible(timeout);
-#else
 			set_current_state(TASK_INTERRUPTIBLE);
 			schedule_timeout(msecs_to_jiffies(timeout));
-#endif
 		}
 	}
 
 	remove_wait_queue(&msp->wq, &wait);
-
-	if (try_to_freeze(PF_FREEZE))
-		goto again;
-
+	try_to_freeze();
 	return msp->restart;
 }
 
@@ -1160,17 +1146,10 @@ static int msp3410d_thread(void *data)
 					    MSP_CARRIER(10.7));
 			/* scart routing */
 			msp3400c_set_scart(client,SCART_IN2,0);
-#if 0
-			/* radio from SCART_IN2 */
-			msp3400c_write(client,I2C_MSP3400C_DFP, 0x08, 0x0220);
-			msp3400c_write(client,I2C_MSP3400C_DFP, 0x09, 0x0220);
-			msp3400c_write(client,I2C_MSP3400C_DFP, 0x0b, 0x0220);
-#else
 			/* msp34xx does radio decoding */
 			msp3400c_write(client,I2C_MSP3400C_DFP, 0x08, 0x0020);
 			msp3400c_write(client,I2C_MSP3400C_DFP, 0x09, 0x0020);
 			msp3400c_write(client,I2C_MSP3400C_DFP, 0x0b, 0x0020);
-#endif
 			break;
 		case 0x0003:
 		case 0x0004:
@@ -1437,7 +1416,7 @@ static int msp_detach(struct i2c_client 
 static int msp_probe(struct i2c_adapter *adap);
 static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg);
 
-static int msp_suspend(struct device * dev, pm_message_t state, u32 level);
+static int msp_suspend(struct device * dev, u32 state, u32 level);
 static int msp_resume(struct device * dev, u32 level);
 
 static void msp_wake_thread(struct i2c_client *client);
@@ -1513,10 +1492,6 @@ static int msp_attach(struct i2c_adapter
 		return -1;
 	}
 
-#if 0
-	/* this will turn on a 1kHz beep - might be useful for debugging... */
-	msp3400c_write(c,I2C_MSP3400C_DFP, 0x0014, 0x1040);
-#endif
 	msp3400c_setvolume(c, msp->muted, msp->volume, msp->balance);
 
 	snprintf(c->name, sizeof(c->name), "MSP34%02d%c-%c%d",
@@ -1842,7 +1817,7 @@ static int msp_command(struct i2c_client
 	return 0;
 }
 
-static int msp_suspend(struct device * dev, pm_message_t state, u32 level)
+static int msp_suspend(struct device * dev, u32 state, u32 level)
 {
 	struct i2c_client *c = container_of(dev, struct i2c_client, dev);
 
diff --git a/drivers/media/video/msp3400.h b/drivers/media/video/msp3400.h
--- a/drivers/media/video/msp3400.h
+++ b/drivers/media/video/msp3400.h
@@ -1,3 +1,7 @@
+/*
+ * $Id: msp3400.h,v 1.3 2005/06/12 04:19:19 mchehab Exp $
+ */
+
 #ifndef MSP3400_H
 #define MSP3400_H
 
diff --git a/drivers/media/video/mt20xx.c b/drivers/media/video/mt20xx.c
--- a/drivers/media/video/mt20xx.c
+++ b/drivers/media/video/mt20xx.c
@@ -1,5 +1,5 @@
 /*
- * $Id: mt20xx.c,v 1.4 2005/03/04 09:24:56 kraxel Exp $
+ * $Id: mt20xx.c,v 1.5 2005/06/16 08:29:49 nsh Exp $
  *
  * i2c tv tuner chip device driver
  * controls microtune tuners, mt2032 + mt2050 at the moment.
@@ -295,8 +295,8 @@ static void mt2032_set_radio_freq(struct
 	int if2 = t->radio_if2;
 
 	// per Manual for FM tuning: first if center freq. 1085 MHz
-        mt2032_set_if_freq(c, freq*62500 /* freq*1000*1000/16 */,
-			   1085*1000*1000,if2,if2,if2);
+        mt2032_set_if_freq(c, freq * 1000 / 16,
+			      1085*1000*1000,if2,if2,if2);
 }
 
 // Initalization as described in "MT203x Programming Procedures", Rev 1.2, Feb.2001
@@ -511,22 +511,6 @@ int microtune_init(struct i2c_client *c)
 	tuner_info("microtune: companycode=%04x part=%02x rev=%02x\n",
 		   company_code,buf[0x13],buf[0x14]);
 
-#if 0
-	/* seems to cause more problems than it solves ... */
-	switch (company_code) {
-	case 0x30bf:
-	case 0x3cbf:
-	case 0x3dbf:
-	case 0x4d54:
-	case 0x8e81:
-	case 0x8e91:
-		/* ok (?) */
-		break;
-	default:
-		tuner_warn("tuner: microtune: unknown companycode\n");
-		return 0;
-	}
-#endif
 
 	if (buf[0x13] < ARRAY_SIZE(microtune_part) &&
 	    NULL != microtune_part[buf[0x13]])
diff --git a/drivers/media/video/mxb.c b/drivers/media/video/mxb.c
--- a/drivers/media/video/mxb.c
+++ b/drivers/media/video/mxb.c
@@ -142,8 +142,8 @@ struct mxb
 
 	int	cur_mode;	/* current audio mode (mono, stereo, ...) */
 	int	cur_input;	/* current input */
-	int	cur_freq;	/* current frequency the tuner is tuned to */
 	int	cur_mute;	/* current mute status */
+	struct v4l2_frequency	cur_freq;	/* current frequency the tuner is tuned to */
 };
 
 static struct saa7146_extension extension;
@@ -326,6 +326,7 @@ static int mxb_init_done(struct saa7146_
 	struct mxb* mxb = (struct mxb*)dev->ext_priv;
 	struct video_decoder_init init;
 	struct i2c_msg msg;
+	struct tuner_setup tun_setup;
 
 	int i = 0, err = 0;
 	struct	tea6415c_multiplex vm;	
@@ -349,9 +350,17 @@ static int mxb_init_done(struct saa7146_
 	mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_VBI_BYPASS, &i);
 
 	/* select a tuner type */
-	i = 5; 
-	mxb->tuner->driver->command(mxb->tuner,TUNER_SET_TYPE, &i);
-	
+	tun_setup.mode_mask = T_ANALOG_TV;
+	tun_setup.addr = ADDR_UNSET;
+	tun_setup.type = TUNER_PHILIPS_PAL;
+	mxb->tuner->driver->command(mxb->tuner,TUNER_SET_TYPE_ADDR, &tun_setup);
+	/* tune in some frequency on tuner */
+	mxb->cur_freq.tuner = 0;
+	mxb->cur_freq.type = V4L2_TUNER_ANALOG_TV;
+	mxb->cur_freq.frequency = freq;
+	mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_FREQUENCY,
+					&mxb->cur_freq);
+
 	/* mute audio on tea6420s */
 	mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[6][0]);
 	mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[6][1]);
@@ -368,12 +377,8 @@ static int mxb_init_done(struct saa7146_
 	vm.out = 13;
 	mxb->tea6415c->driver->command(mxb->tea6415c,TEA6415C_SWITCH, &vm);
 				
-	/* tune in some frequency on tuner */
-	mxb->tuner->driver->command(mxb->tuner, VIDIOCSFREQ, &freq);
-
 	/* the rest for mxb */
 	mxb->cur_input = 0;
-	mxb->cur_freq = freq;
 	mxb->cur_mute = 1;
 
 	mxb->cur_mode = V4L2_TUNER_MODE_STEREO;
@@ -816,18 +821,14 @@ static int mxb_ioctl(struct saa7146_fh *
 			return -EINVAL;
 		}
 
-		memset(f,0,sizeof(*f));
-		f->type = V4L2_TUNER_ANALOG_TV;
-		f->frequency =  mxb->cur_freq;
+		*f = mxb->cur_freq;
 
-		DEB_EE(("VIDIOC_G_FREQ: freq:0x%08x.\n", mxb->cur_freq));
+		DEB_EE(("VIDIOC_G_FREQ: freq:0x%08x.\n", mxb->cur_freq.frequency));
 		return 0;
 	}
 	case VIDIOC_S_FREQUENCY:
 	{
 		struct v4l2_frequency *f = arg;
-		int t_locked = 0;
-		int v_byte = 0;
 
 		if (0 != f->tuner)
 			return -EINVAL;
@@ -840,20 +841,11 @@ static int mxb_ioctl(struct saa7146_fh *
 			return -EINVAL;
 		}
 
-		DEB_EE(("VIDIOC_S_FREQUENCY: freq:0x%08x.\n",f->frequency));
-
-		mxb->cur_freq = f->frequency;
+		mxb->cur_freq = *f;
+		DEB_EE(("VIDIOC_S_FREQUENCY: freq:0x%08x.\n", mxb->cur_freq.frequency));
 
 		/* tune in desired frequency */			
-		mxb->tuner->driver->command(mxb->tuner, VIDIOCSFREQ, &mxb->cur_freq);
-
-		/* check if pll of tuner & saa7111a is locked */
-//		mxb->tuner->driver->command(mxb->tuner,TUNER_IS_LOCKED, &t_locked);
-		mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_GET_STATUS, &v_byte);
-
-		/* not locked -- anything to do here ? */
-		if( 0 == t_locked || 0 == (v_byte & DECODER_STATUS_GOOD)) {
-		}
+		mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_FREQUENCY, &mxb->cur_freq);
 
 		/* hack: changing the frequency should invalidate the vbi-counter (=> alevt) */
 		spin_lock(&dev->slock);
diff --git a/drivers/media/video/saa5246a.c b/drivers/media/video/saa5246a.c
--- a/drivers/media/video/saa5246a.c
+++ b/drivers/media/video/saa5246a.c
@@ -64,7 +64,6 @@ static struct video_device saa_template;
 
 /* Addresses to scan */
 static unsigned short normal_i2c[]	 = { I2C_ADDRESS, I2C_CLIENT_END };
-static unsigned short normal_i2c_range[] = { I2C_CLIENT_END };
 I2C_CLIENT_INSMOD;
 
 static struct i2c_client client_template;
diff --git a/drivers/media/video/saa5249.c b/drivers/media/video/saa5249.c
--- a/drivers/media/video/saa5249.c
+++ b/drivers/media/video/saa5249.c
@@ -132,7 +132,6 @@ static struct video_device saa_template;
 
 /* Addresses to scan */
 static unsigned short normal_i2c[] = {34>>1,I2C_CLIENT_END};
-static unsigned short normal_i2c_range[] = {I2C_CLIENT_END};
 I2C_CLIENT_INSMOD;
 
 static struct i2c_client client_template;
diff --git a/drivers/media/video/saa7110.c b/drivers/media/video/saa7110.c
--- a/drivers/media/video/saa7110.c
+++ b/drivers/media/video/saa7110.c
@@ -463,22 +463,14 @@ static unsigned short normal_i2c[] = {
 	(I2C_SAA7110 >> 1) + 1,
 	I2C_CLIENT_END
 };
-static unsigned short normal_i2c_range[] = { I2C_CLIENT_END };
 
-static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short probe_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short ignore_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short force[2] = { I2C_CLIENT_END , I2C_CLIENT_END };
+static unsigned short ignore = I2C_CLIENT_END;
                                                                                 
 static struct i2c_client_address_data addr_data = {
 	.normal_i2c		= normal_i2c,
-	.normal_i2c_range	= normal_i2c_range,
-	.probe			= probe,
-	.probe_range		= probe_range,
-	.ignore			= ignore,
-	.ignore_range		= ignore_range,
-	.force			= force
+	.probe			= &ignore,
+	.ignore			= &ignore,
+	.force			= &ignore,
 };
 
 static struct i2c_driver i2c_driver_saa7110;
diff --git a/drivers/media/video/saa7111.c b/drivers/media/video/saa7111.c
--- a/drivers/media/video/saa7111.c
+++ b/drivers/media/video/saa7111.c
@@ -482,22 +482,14 @@ saa7111_command (struct i2c_client *clie
  * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
  */
 static unsigned short normal_i2c[] = { I2C_SAA7111 >> 1, I2C_CLIENT_END };
-static unsigned short normal_i2c_range[] = { I2C_CLIENT_END };
 
-static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short probe_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short ignore_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short force[2] = { I2C_CLIENT_END , I2C_CLIENT_END };
+static unsigned short ignore = I2C_CLIENT_END;
                                                                                 
 static struct i2c_client_address_data addr_data = {
 	.normal_i2c		= normal_i2c,
-	.normal_i2c_range	= normal_i2c_range,
-	.probe			= probe,
-	.probe_range		= probe_range,
-	.ignore			= ignore,
-	.ignore_range		= ignore_range,
-	.force			= force
+	.probe			= &ignore,
+	.ignore			= &ignore,
+	.force			= &ignore,
 };
 
 static struct i2c_driver i2c_driver_saa7111;
diff --git a/drivers/media/video/saa7114.c b/drivers/media/video/saa7114.c
--- a/drivers/media/video/saa7114.c
+++ b/drivers/media/video/saa7114.c
@@ -820,22 +820,14 @@ saa7114_command (struct i2c_client *clie
  */
 static unsigned short normal_i2c[] =
     { I2C_SAA7114 >> 1, I2C_SAA7114A >> 1, I2C_CLIENT_END };
-static unsigned short normal_i2c_range[] = { I2C_CLIENT_END };
 
-static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short probe_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short ignore_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short force[2] = { I2C_CLIENT_END , I2C_CLIENT_END };
+static unsigned short ignore = I2C_CLIENT_END;
                                                                                 
 static struct i2c_client_address_data addr_data = {
 	.normal_i2c		= normal_i2c,
-	.normal_i2c_range	= normal_i2c_range,
-	.probe			= probe,
-	.probe_range		= probe_range,
-	.ignore			= ignore,
-	.ignore_range		= ignore_range,
-	.force			= force
+	.probe			= &ignore,
+	.ignore			= &ignore,
+	.force			= &ignore,
 };
 
 static struct i2c_driver i2c_driver_saa7114;
diff --git a/drivers/media/video/saa7134/Makefile b/drivers/media/video/saa7134/Makefile
--- a/drivers/media/video/saa7134/Makefile
+++ b/drivers/media/video/saa7134/Makefile
@@ -9,3 +9,9 @@ obj-$(CONFIG_VIDEO_SAA7134_DVB) += saa71
 EXTRA_CFLAGS += -I$(src)/..
 EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core
 EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/frontends
+ifneq ($(CONFIG_DVB_MT352),n)
+ EXTRA_CFLAGS += -DHAVE_MT352=1
+endif
+ifneq ($(CONFIG_DVB_TDA1004X),n)
+ EXTRA_CFLAGS += -DHAVE_TDA1004X=1
+endif
diff --git a/drivers/media/video/saa7134/saa6752hs.c b/drivers/media/video/saa7134/saa6752hs.c
--- a/drivers/media/video/saa7134/saa6752hs.c
+++ b/drivers/media/video/saa7134/saa6752hs.c
@@ -22,7 +22,6 @@
 
 /* Addresses to scan */
 static unsigned short normal_i2c[] = {0x20, I2C_CLIENT_END};
-static unsigned short normal_i2c_range[] = {I2C_CLIENT_END};
 I2C_CLIENT_INSMOD;
 
 MODULE_DESCRIPTION("device driver for saa6752hs MPEG2 encoder");
@@ -42,16 +41,16 @@ enum saa6752hs_videoformat {
 
 static const struct v4l2_format v4l2_format_table[] =
 {
-	[SAA6752HS_VF_D1] = {
-		.fmt = { .pix = { .width = 720, .height = 576 }, }, },
-	[SAA6752HS_VF_2_3_D1] = {
-		.fmt = { .pix = { .width = 480, .height = 576 }, }, },
-	[SAA6752HS_VF_1_2_D1] = {
-		.fmt = { .pix = { .width = 352, .height = 576 }, }, },
-	[SAA6752HS_VF_SIF] = {
-		.fmt = { .pix = { .width = 352, .height = 288 }, }, },
-	[SAA6752HS_VF_UNKNOWN] = {
-		.fmt = { .pix = { .width = 0, .height = 0 }, }, },
+	[SAA6752HS_VF_D1] =
+		{ .fmt = { .pix = { .width = 720, .height = 576 }}},
+	[SAA6752HS_VF_2_3_D1] =
+		{ .fmt = { .pix = { .width = 480, .height = 576 }}},
+	[SAA6752HS_VF_1_2_D1] =
+		{ .fmt = { .pix = { .width = 352, .height = 576 }}},
+	[SAA6752HS_VF_SIF] =
+		{ .fmt = { .pix = { .width = 352, .height = 288 }}},
+	[SAA6752HS_VF_UNKNOWN] =
+		{ .fmt = { .pix = { .width = 0, .height = 0}}},
 };
 
 struct saa6752hs_state {
@@ -156,10 +155,6 @@ static struct v4l2_mpeg_compression para
 		.target  = 256,
 	},
 
-#if 0
-	/* FIXME: size? via S_FMT? */
-	.video_format = MPEG_VIDEO_FORMAT_D1,
-#endif
 };
 
 /* ---------------------------------------------------------------------- */
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -1,6 +1,5 @@
-
 /*
- * $Id: saa7134-cards.c,v 1.54 2005/03/07 12:01:51 kraxel Exp $
+ * $Id: saa7134-cards.c,v 1.80 2005/07/07 01:49:30 mkrufky Exp $
  *
  * device driver for philips saa7134 based TV cards
  * card-specific stuff.
@@ -47,6 +46,10 @@ struct saa7134_board saa7134_boards[] = 
 		.name		= "UNKNOWN/GENERIC",
 		.audio_clock	= 0x00187de7,
 		.tuner_type	= TUNER_ABSENT,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
+
 		.inputs         = {{
 			.name = "default",
 			.vmux = 0,
@@ -58,6 +61,10 @@ struct saa7134_board saa7134_boards[] = 
 		.name		= "Proteus Pro [philips reference design]",
 		.audio_clock	= 0x00187de7,
 		.tuner_type	= TUNER_PHILIPS_PAL,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
+
 		.inputs         = {{
 			.name = name_comp1,
 			.vmux = 0,
@@ -83,6 +90,10 @@ struct saa7134_board saa7134_boards[] = 
 		.name		= "LifeView FlyVIDEO3000",
 		.audio_clock	= 0x00200000,
 		.tuner_type	= TUNER_PHILIPS_PAL,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
+
 		.gpiomask       = 0xe000,
 		.inputs         = {{
 			.name = name_tv,
@@ -90,7 +101,7 @@ struct saa7134_board saa7134_boards[] = 
 			.amux = TV,
 			.gpio = 0x8000,
 			.tv   = 1,
-                },{
+		},{
 			.name = name_tv_mono,
 			.vmux = 1,
 			.amux = LINE2,
@@ -117,12 +128,21 @@ struct saa7134_board saa7134_boards[] = 
 			.amux = LINE2,
 			.gpio = 0x2000,
 		},
+		.mute = {
+			.name = name_mute,
+			.amux = TV,
+			.gpio = 0x8000,
+		},
 	},
 	[SAA7134_BOARD_FLYVIDEO2000] = {
 		/* "TC Wan" <tcwan@cs.usm.my> */
 		.name           = "LifeView FlyVIDEO2000",
 		.audio_clock    = 0x00200000,
 		.tuner_type     = TUNER_LG_PAL_NEW_TAPC,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
+
 		.gpiomask       = 0xe000,
 		.inputs         = {{
 			.name = name_tv,
@@ -146,14 +166,14 @@ struct saa7134_board saa7134_boards[] = 
 			.amux = LINE2,
 			.gpio = 0x4000,
 		}},
-                .radio = {
-                        .name = name_radio,
-                        .amux = LINE2,
+		.radio = {
+			.name = name_radio,
+			.amux = LINE2,
 			.gpio = 0x2000,
-                },
+		},
 		.mute = {
 			.name = name_mute,
-                        .amux = LINE2,
+			.amux = LINE2,
 			.gpio = 0x8000,
 		},
 	},
@@ -162,10 +182,14 @@ struct saa7134_board saa7134_boards[] = 
 		.name           = "LifeView FlyTV Platinum Mini",
 		.audio_clock    = 0x00200000,
 		.tuner_type     = TUNER_PHILIPS_TDA8290,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
+
 		.inputs         = {{
 			.name = name_tv,
 			.vmux = 1,
-			.amux = LINE2,
+			.amux = TV,
 			.tv   = 1,
 		},{
 			.name = name_comp1,
@@ -183,6 +207,10 @@ struct saa7134_board saa7134_boards[] = 
 		.name           = "LifeView FlyTV Platinum FM",
 		.audio_clock    = 0x00200000,
 		.tuner_type     = TUNER_PHILIPS_TDA8290,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
+
 		.gpiomask       = 0x1E000,	/* Set GP16 and unused 15,14,13 to Output */
 		.inputs         = {{
 			.name = name_tv,
@@ -190,7 +218,7 @@ struct saa7134_board saa7134_boards[] = 
 			.amux = TV,
 			.gpio = 0x10000,	/* GP16=1 selects TV input */
 			.tv   = 1,
-                },{
+		},{
 /*			.name = name_tv_mono,
 			.vmux = 1,
 			.amux = LINE2,
@@ -200,29 +228,38 @@ struct saa7134_board saa7134_boards[] = 
 */			.name = name_comp1,	/* Composite signal on S-Video input */
 			.vmux = 0,
 			.amux = LINE2,
-//			.gpio = 0x4000,
+/*			.gpio = 0x4000,         */
 		},{
 			.name = name_comp2,	/* Composite input */
 			.vmux = 3,
 			.amux = LINE2,
-//			.gpio = 0x4000,
+/*			.gpio = 0x4000,         */
 		},{
 			.name = name_svideo,	/* S-Video signal on S-Video input */
 			.vmux = 8,
 			.amux = LINE2,
-//			.gpio = 0x4000,
+/*			.gpio = 0x4000,         */
 		}},
 		.radio = {
 			.name = name_radio,
 			.amux = TV,
 			.gpio = 0x00000,	/* GP16=0 selects FM radio antenna */
 		},
+		.mute = {
+			.name = name_mute,
+			.amux = TV,
+			.gpio = 0x10000,
+		},
 	},
 	[SAA7134_BOARD_EMPRESS] = {
 		/* "Gert Vervoort" <gert.vervoort@philips.com> */
 		.name		= "EMPRESS",
 		.audio_clock	= 0x00187de7,
 		.tuner_type	= TUNER_PHILIPS_PAL,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
+
 		.inputs         = {{
 			.name = name_comp1,
 			.vmux = 0,
@@ -245,33 +282,40 @@ struct saa7134_board saa7134_boards[] = 
 		.video_out = CCIR656,
 	},
 	[SAA7134_BOARD_MONSTERTV] = {
-               /* "K.Ohta" <alpha292@bremen.or.jp> */
-               .name           = "SKNet Monster TV",
-               .audio_clock    = 0x00187de7,
-               .tuner_type     = TUNER_PHILIPS_NTSC_M,
-               .inputs         = {{
-                       .name = name_tv,
-                       .vmux = 1,
-                       .amux = TV,
-                       .tv   = 1,
-               },{
-                       .name = name_comp1,
-                       .vmux = 0,
-                       .amux = LINE1,
-               },{
-                       .name = name_svideo,
-                       .vmux = 8,
-                       .amux = LINE1,
-               }},
-               .radio = {
-                       .name = name_radio,
-                       .amux = LINE2,
-               },
+		/* "K.Ohta" <alpha292@bremen.or.jp> */
+		.name           = "SKNet Monster TV",
+		.audio_clock    = 0x00187de7,
+		.tuner_type     = TUNER_PHILIPS_NTSC_M,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
+
+		.inputs         = {{
+			.name = name_tv,
+			.vmux = 1,
+			.amux = TV,
+			.tv   = 1,
+		},{
+			.name = name_comp1,
+			.vmux = 0,
+			.amux = LINE1,
+		},{
+			.name = name_svideo,
+			.vmux = 8,
+			.amux = LINE1,
+		}},
+		.radio = {
+			.name = name_radio,
+			.amux = LINE2,
+		},
 	},
 	[SAA7134_BOARD_MD9717] = {
 		.name		= "Tevion MD 9717",
 		.audio_clock	= 0x00200000,
 		.tuner_type	= TUNER_PHILIPS_PAL,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
 		.inputs         = {{
 			.name = name_tv,
 			.vmux = 1,
@@ -302,10 +346,13 @@ struct saa7134_board saa7134_boards[] = 
 		},
 	},
 	[SAA7134_BOARD_TVSTATION_RDS] = {
-                /* Typhoon TV Tuner RDS: Art.Nr. 50694 */
+		/* Typhoon TV Tuner RDS: Art.Nr. 50694 */
 		.name		= "KNC One TV-Station RDS / Typhoon TV Tuner RDS",
 		.audio_clock	= 0x00200000,
 		.tuner_type	= TUNER_PHILIPS_FM1216ME_MK3,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
 		.tda9887_conf   = TDA9887_PRESENT,
 		.inputs         = {{
 			.name = name_tv,
@@ -314,10 +361,10 @@ struct saa7134_board saa7134_boards[] = 
 			.tv   = 1,
 		},{
 			.name = name_tv_mono,
-                        .vmux = 1,
-                        .amux   = LINE2,
-                        .tv   = 1,
-                },{
+			.vmux = 1,
+			.amux   = LINE2,
+			.tv   = 1,
+		},{
 
 			.name = name_svideo,
 			.vmux = 8,
@@ -328,10 +375,10 @@ struct saa7134_board saa7134_boards[] = 
 			.amux = LINE1,
 		},{
 
-                        .name = "CVid over SVid",
-                        .vmux = 0,
-                        .amux = LINE1,
-                }},
+			.name = "CVid over SVid",
+			.vmux = 0,
+			.amux = LINE1,
+		}},
 		.radio = {
 			.name = name_radio,
 			.amux = LINE2,
@@ -341,6 +388,9 @@ struct saa7134_board saa7134_boards[] = 
 		.name		= "KNC One TV-Station DVR",
 		.audio_clock	= 0x00200000,
 		.tuner_type	= TUNER_PHILIPS_FM1216ME_MK3,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
 		.tda9887_conf	= TDA9887_PRESENT,
 		.gpiomask	= 0x820000,
 		.inputs		= {{
@@ -369,32 +419,38 @@ struct saa7134_board saa7134_boards[] = 
 		.video_out	= CCIR656,
 	},
 	[SAA7134_BOARD_CINERGY400] = {
-                .name           = "Terratec Cinergy 400 TV",
-                .audio_clock    = 0x00200000,
-                .tuner_type     = TUNER_PHILIPS_PAL,
-                .inputs         = {{
-                        .name = name_tv,
-                        .vmux = 1,
-                        .amux = TV,
-                        .tv   = 1,
-                },{
-                        .name = name_comp1,
-                        .vmux = 4,
-                        .amux = LINE1,
-                },{
-                        .name = name_svideo,
-                        .vmux = 8,
-                        .amux = LINE1,
-                },{
-                        .name = name_comp2, // CVideo over SVideo Connector
-                        .vmux = 0,
-                        .amux = LINE1,
-                }}
-        },
+		.name           = "Terratec Cinergy 400 TV",
+		.audio_clock    = 0x00200000,
+		.tuner_type     = TUNER_PHILIPS_PAL,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
+		.inputs         = {{
+			.name = name_tv,
+			.vmux = 1,
+			.amux = TV,
+			.tv   = 1,
+		},{
+			.name = name_comp1,
+			.vmux = 4,
+			.amux = LINE1,
+		},{
+			.name = name_svideo,
+			.vmux = 8,
+			.amux = LINE1,
+		},{
+			.name = name_comp2, /* CVideo over SVideo Connector */
+			.vmux = 0,
+			.amux = LINE1,
+		}}
+	},
 	[SAA7134_BOARD_MD5044] = {
 		.name           = "Medion 5044",
-		.audio_clock    = 0x00187de7, // was: 0x00200000,
+		.audio_clock    = 0x00187de7, /* was: 0x00200000, */
 		.tuner_type     = TUNER_PHILIPS_FM1216ME_MK3,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
 		.tda9887_conf   = TDA9887_PRESENT,
 		.inputs         = {{
 			.name = name_tv,
@@ -426,57 +482,65 @@ struct saa7134_board saa7134_boards[] = 
 		},
 	},
 	[SAA7134_BOARD_KWORLD] = {
-                .name           = "Kworld/KuroutoShikou SAA7130-TVPCI",
+		.name           = "Kworld/KuroutoShikou SAA7130-TVPCI",
 		.audio_clock    = 0x00187de7,
 		.tuner_type     = TUNER_PHILIPS_NTSC_M,
-                .inputs         = {{
-                        .name = name_svideo,
-                        .vmux = 8,
-                        .amux = LINE1,
-                },{
-                        .name = name_comp1,
-                        .vmux = 3,
-                        .amux = LINE1,
-                },{
-                        .name = name_tv,
-                        .vmux = 1,
-                        .amux = LINE2,
-                        .tv   = 1,
-                }},
-        },
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
+		.inputs         = {{
+			.name = name_svideo,
+			.vmux = 8,
+			.amux = LINE1,
+		},{
+			.name = name_comp1,
+			.vmux = 3,
+			.amux = LINE1,
+		},{
+			.name = name_tv,
+			.vmux = 1,
+			.amux = LINE2,
+			.tv   = 1,
+		}},
+	},
 	[SAA7134_BOARD_CINERGY600] = {
-                .name           = "Terratec Cinergy 600 TV",
-                .audio_clock    = 0x00200000,
-                .tuner_type     = TUNER_PHILIPS_PAL,
+		.name           = "Terratec Cinergy 600 TV",
+		.audio_clock    = 0x00200000,
+		.tuner_type     = TUNER_PHILIPS_PAL,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
 		.tda9887_conf   = TDA9887_PRESENT,
-                .inputs         = {{
-                        .name = name_tv,
-                        .vmux = 1,
-                        .amux = TV,
-                        .tv   = 1,
-                },{
-                        .name = name_comp1,
-                        .vmux = 4,
-                        .amux = LINE1,
-                },{
-                        .name = name_svideo,
-                        .vmux = 8,
-                        .amux = LINE1,
-                },{
-                        .name = name_comp2, // CVideo over SVideo Connector
-                        .vmux = 0,
-                        .amux = LINE1,
-                }},
+		.inputs         = {{
+			.name = name_tv,
+			.vmux = 1,
+			.amux = TV,
+			.tv   = 1,
+		},{
+			.name = name_comp1,
+			.vmux = 4,
+			.amux = LINE1,
+		},{
+			.name = name_svideo,
+			.vmux = 8,
+			.amux = LINE1,
+		},{
+			.name = name_comp2, /* CVideo over SVideo Connector */
+			.vmux = 0,
+			.amux = LINE1,
+		}},
 		.radio = {
 			.name = name_radio,
 			.amux = LINE2,
-               },
-        },
+	},
+	},
 	[SAA7134_BOARD_MD7134] = {
 		.name           = "Medion 7134",
-		//.audio_clock    = 0x00200000,
 		.audio_clock    = 0x00187de7,
-		.tuner_type     = TUNER_PHILIPS_FM1216ME_MK3,
+		.tuner_type     = TUNER_PHILIPS_FMD1216ME_MK3,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
 		.tda9887_conf   = TDA9887_PRESENT,
 		.mpeg           = SAA7134_MPEG_DVB,
 		.inputs = {{
@@ -504,6 +568,9 @@ struct saa7134_board saa7134_boards[] = 
 		.name           = "Typhoon TV+Radio 90031",
 		.audio_clock    = 0x00200000,
 		.tuner_type     = TUNER_PHILIPS_PAL,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
 		.tda9887_conf   = TDA9887_PRESENT,
 		.inputs         = {{
 			.name   = name_tv,
@@ -523,11 +590,14 @@ struct saa7134_board saa7134_boards[] = 
 			.name   = name_radio,
 			.amux   = LINE2,
 		},
-        },
+	},
 	[SAA7134_BOARD_ELSA] = {
 		.name           = "ELSA EX-VISION 300TV",
 		.audio_clock    = 0x00187de7,
 		.tuner_type     = TUNER_HITACHI_NTSC,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
 		.inputs         = {{
 			.name = name_svideo,
 			.vmux = 8,
@@ -542,11 +612,14 @@ struct saa7134_board saa7134_boards[] = 
 			.amux = LINE2,
 			.tv   = 1,
 		}},
-        },
+	},
 	[SAA7134_BOARD_ELSA_500TV] = {
 		.name           = "ELSA EX-VISION 500TV",
 		.audio_clock    = 0x00187de7,
 		.tuner_type     = TUNER_HITACHI_NTSC,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
 		.inputs         = {{
 			.name = name_svideo,
 			.vmux = 7,
@@ -562,83 +635,100 @@ struct saa7134_board saa7134_boards[] = 
 			.amux = LINE2,
 			.tv   = 1,
 		}},
-        },
+	},
 	[SAA7134_BOARD_ASUSTeK_TVFM7134] = {
-                .name           = "ASUS TV-FM 7134",
-                .audio_clock    = 0x00187de7,
-                .tuner_type     = TUNER_PHILIPS_FM1216ME_MK3,
-                .tda9887_conf   = TDA9887_PRESENT,
-                .inputs         = {{
-                        .name = name_tv,
-                        .vmux = 1,
-                        .amux = TV,
-                        .tv   = 1,
-                },{
-                        .name = name_comp1,
-                        .vmux = 4,
-                        .amux = LINE2,
-                },{
-                        .name = name_svideo,
-                        .vmux = 6,
-                        .amux = LINE2,
-                }},
-                .radio = {
-                        .name = name_radio,
-                        .amux = LINE1,
-                },
-	},
-	[SAA7135_BOARD_ASUSTeK_TVFM7135] = {
-                .name           = "ASUS TV-FM 7135",
-                .audio_clock    = 0x00187de7,
-                .tuner_type     = TUNER_PHILIPS_TDA8290,
+		.name           = "ASUS TV-FM 7134",
+		.audio_clock    = 0x00187de7,
+		.tuner_type     = TUNER_PHILIPS_FM1216ME_MK3,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
+		.tda9887_conf   = TDA9887_PRESENT,
+		.inputs         = {{
+			.name = name_tv,
+			.vmux = 1,
+			.amux = TV,
+			.tv   = 1,
+		},{
+			.name = name_comp1,
+			.vmux = 4,
+			.amux = LINE2,
+		},{
+			.name = name_svideo,
+			.vmux = 6,
+			.amux = LINE2,
+		}},
+		.radio = {
+			.name = name_radio,
+			.amux = LINE1,
+		},
+	},
+	[SAA7134_BOARD_ASUSTeK_TVFM7135] = {
+		.name           = "ASUS TV-FM 7135",
+		.audio_clock    = 0x00187de7,
+		.tuner_type     = TUNER_PHILIPS_TDA8290,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
 		.gpiomask       = 0x200000,
-                .inputs         = {{
-                        .name = name_tv,
-                        .vmux = 1,
-                        .amux = TV,
+		.inputs         = {{
+			.name = name_tv,
+			.vmux = 1,
+			.amux = TV,
 			.gpio = 0x0000,
-                        .tv   = 1,
-                },{
-                        .name = name_comp1,
-                        .vmux = 4,
-                        .amux = LINE2,
+			.tv   = 1,
+		},{
+			.name = name_comp1,
+			.vmux = 4,
+			.amux = LINE2,
 			.gpio = 0x0000,
-                },{
-                        .name = name_svideo,
-                        .vmux = 6,
-                        .amux = LINE2,
+		},{
+			.name = name_svideo,
+			.vmux = 6,
+			.amux = LINE2,
 			.gpio = 0x0000,
-                }},
-                .radio = {
-                        .name = name_radio,
-                        .amux = TV,
+		}},
+		.radio = {
+			.name = name_radio,
+			.amux = TV,
 			.gpio = 0x200000,
-                },
+		},
+		.mute  = {
+			.name = name_mute,
+			.gpio = 0x0000,
+		},
+
 	},
 	[SAA7134_BOARD_VA1000POWER] = {
-                .name           = "AOPEN VA1000 POWER",
+		.name           = "AOPEN VA1000 POWER",
 		.audio_clock    = 0x00187de7,
 		.tuner_type     = TUNER_PHILIPS_NTSC,
-                .inputs         = {{
-                        .name = name_svideo,
-                        .vmux = 8,
-                        .amux = LINE1,
-                },{
-                        .name = name_comp1,
-                        .vmux = 3,
-                        .amux = LINE1,
-                },{
-                        .name = name_tv,
-                        .vmux = 1,
-                        .amux = LINE2,
-                        .tv   = 1,
-                }},
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
+		.inputs         = {{
+			.name = name_svideo,
+			.vmux = 8,
+			.amux = LINE1,
+		},{
+			.name = name_comp1,
+			.vmux = 3,
+			.amux = LINE1,
+		},{
+			.name = name_tv,
+			.vmux = 1,
+			.amux = LINE2,
+			.tv   = 1,
+		}},
 	},
 	[SAA7134_BOARD_10MOONSTVMASTER] = {
 		/* "lilicheng" <llc@linuxfans.org> */
 		.name           = "10MOONS PCI TV CAPTURE CARD",
 		.audio_clock    = 0x00200000,
 		.tuner_type     = TUNER_LG_PAL_NEW_TAPC,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
 		.gpiomask       = 0xe000,
 		.inputs         = {{
 			.name = name_tv,
@@ -662,14 +752,14 @@ struct saa7134_board saa7134_boards[] = 
 			.amux = LINE2,
 			.gpio = 0x4000,
 		}},
-                .radio = {
-                        .name = name_radio,
-                        .amux = LINE2,
+		.radio = {
+			.name = name_radio,
+			.amux = LINE2,
 			.gpio = 0x2000,
-                },
+		},
 		.mute = {
 			.name = name_mute,
-                        .amux = LINE2,
+			.amux = LINE2,
 			.gpio = 0x8000,
 		},
 	},
@@ -678,6 +768,9 @@ struct saa7134_board saa7134_boards[] = 
 		.name		= "BMK MPEX No Tuner",
 		.audio_clock	= 0x200000,
 		.tuner_type	= TUNER_ABSENT,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
 		.inputs         = {{
 			.name = name_comp1,
 			.vmux = 4,
@@ -706,80 +799,94 @@ struct saa7134_board saa7134_boards[] = 
 		.name           = "Compro VideoMate TV",
 		.audio_clock    = 0x00187de7,
 		.tuner_type     = TUNER_PHILIPS_NTSC_M,
-                .inputs         = {{
-                        .name = name_svideo,
-                        .vmux = 8,
-                        .amux = LINE1,
-                },{
-                        .name = name_comp1,
-                        .vmux = 3,
-                        .amux = LINE1,
-                },{
-                        .name = name_tv,
-                        .vmux = 1,
-                        .amux = LINE2,
-                        .tv   = 1,
-                }},
-        },
-    [SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUS] = {
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
+		.inputs         = {{
+			.name = name_svideo,
+			.vmux = 8,
+			.amux = LINE1,
+		},{
+			.name = name_comp1,
+			.vmux = 3,
+			.amux = LINE1,
+		},{
+			.name = name_tv,
+			.vmux = 1,
+			.amux = LINE2,
+			.tv   = 1,
+		}},
+	},
+	[SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUS] = {
 		.name           = "Compro VideoMate TV Gold+",
 		.audio_clock    = 0x00187de7,
 		.tuner_type     = TUNER_PHILIPS_NTSC_M,
 		.gpiomask       = 0x800c0000,
-                .inputs         = {{
-                        .name = name_svideo,
-                        .vmux = 8,
-                        .amux = LINE1,
-                        .gpio = 0x06c00012,
-                },{
-                        .name = name_comp1,
-                        .vmux = 3,
-                        .amux = LINE1,
-                        .gpio = 0x0ac20012,
-                },{
-                        .name = name_tv,
-                        .vmux = 1,
-                        .amux = LINE2,
-                        .gpio = 0x08c20012,
-                        .tv   = 1,
-                }},
-        },
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
+		.inputs         = {{
+			.name = name_svideo,
+			.vmux = 8,
+			.amux = LINE1,
+			.gpio = 0x06c00012,
+		},{
+			.name = name_comp1,
+			.vmux = 3,
+			.amux = LINE1,
+			.gpio = 0x0ac20012,
+		},{
+			.name = name_tv,
+			.vmux = 1,
+			.amux = LINE2,
+			.gpio = 0x08c20012,
+			.tv   = 1,
+		}},				/* radio and probably mute is missing */
+	},
 	[SAA7134_BOARD_CRONOS_PLUS] = {
-		/* gpio pins:
-		   0  .. 3   BASE_ID
-		   4  .. 7   PROTECT_ID
-		   8  .. 11  USER_OUT
-		   12 .. 13  USER_IN
-		   14 .. 15  VIDIN_SEL */
+		/*
+		gpio pins:
+			0  .. 3   BASE_ID
+			4  .. 7   PROTECT_ID
+			8  .. 11  USER_OUT
+			12 .. 13  USER_IN
+			14 .. 15  VIDIN_SEL
+		*/
 		.name           = "Matrox CronosPlus",
 		.tuner_type     = TUNER_ABSENT,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
 		.gpiomask       = 0xcf00,
-                .inputs         = {{
-                        .name = name_comp1,
-                        .vmux = 0,
+		.inputs         = {{
+			.name = name_comp1,
+			.vmux = 0,
 			.gpio = 2 << 14,
 		},{
-                        .name = name_comp2,
-                        .vmux = 0,
+			.name = name_comp2,
+			.vmux = 0,
 			.gpio = 1 << 14,
 		},{
-                        .name = name_comp3,
-                        .vmux = 0,
+			.name = name_comp3,
+			.vmux = 0,
 			.gpio = 0 << 14,
 		},{
-                        .name = name_comp4,
-                        .vmux = 0,
+			.name = name_comp4,
+			.vmux = 0,
 			.gpio = 3 << 14,
 		},{
 			.name = name_svideo,
 			.vmux = 8,
 			.gpio = 2 << 14,
-                }},
-        },
+		}},
+	},
 	[SAA7134_BOARD_MD2819] = {
 		.name           = "AverMedia M156 / Medion 2819",
 		.audio_clock    = 0x00187de7,
 		.tuner_type     = TUNER_PHILIPS_FM1216ME_MK3,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
 		.tda9887_conf   = TDA9887_PRESENT,
 		.inputs         = {{
 			.name = name_tv,
@@ -809,6 +916,9 @@ struct saa7134_board saa7134_boards[] = 
 		.name           = "BMK MPEX Tuner",
 		.audio_clock    = 0x200000,
 		.tuner_type     = TUNER_PHILIPS_PAL,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
 		.inputs         = {{
 			.name = name_comp1,
 			.vmux = 1,
@@ -825,90 +935,99 @@ struct saa7134_board saa7134_boards[] = 
 		}},
 		.mpeg      = SAA7134_MPEG_EMPRESS,
 		.video_out = CCIR656,
-        },
-        [SAA7134_BOARD_ASUSTEK_TVFM7133] = {
-                .name           = "ASUS TV-FM 7133",
-                .audio_clock    = 0x00187de7,
-		// probably wrong, the 7133 one is the NTSC version ...
-		// .tuner_type     = TUNER_PHILIPS_FM1236_MK3
-                .tuner_type     = TUNER_LG_NTSC_NEW_TAPC,
-                .tda9887_conf   = TDA9887_PRESENT,
-                .inputs         = {{
-                        .name = name_tv,
-                        .vmux = 1,
-                        .amux = TV,
-                        .tv   = 1,
-		},{
-                        .name = name_comp1,
-                        .vmux = 4,
-                        .amux = LINE2,
-                },{
-                        .name = name_svideo,
-                        .vmux = 6,
-                        .amux = LINE2,
-                }},
-                .radio = {
-                        .name = name_radio,
-                        .amux = LINE1,
-                },
-        },
-	[SAA7134_BOARD_PINNACLE_PCTV_STEREO] = {
-                .name           = "Pinnacle PCTV Stereo (saa7134)",
-                .audio_clock    = 0x00187de7,
-                .tuner_type     = TUNER_MT2032,
-                .tda9887_conf   = TDA9887_PRESENT | TDA9887_INTERCARRIER,
-                .inputs         = {{
-                        .name = name_tv,
-                        .vmux = 3,
-                        .amux = TV,
-                        .tv   = 1,
-                },{
-                        .name = name_comp1,
-                        .vmux = 0,
-                        .amux = LINE2,
-                },{
-                        .name = name_comp2,
-                        .vmux = 1,
-                        .amux = LINE2,
-                },{
-                        .name = name_svideo,
-                        .vmux = 8,
-                        .amux = LINE2,
-                }},
-        },
-	[SAA7134_BOARD_MANLI_MTV002] = {
-		/* Ognjen Nastic <ognjen@logosoft.ba> */
-		.name           = "Manli MuchTV M-TV002",
-		.audio_clock    = 0x00200000,
-		.tuner_type     = TUNER_PHILIPS_PAL,
+	},
+	[SAA7134_BOARD_ASUSTEK_TVFM7133] = {
+		.name           = "ASUS TV-FM 7133",
+		.audio_clock    = 0x00187de7,
+		/* probably wrong, the 7133 one is the NTSC version ...
+		* .tuner_type  = TUNER_PHILIPS_FM1236_MK3 */
+		.tuner_type     = TUNER_LG_NTSC_NEW_TAPC,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
+		.tda9887_conf   = TDA9887_PRESENT,
 		.inputs         = {{
-			.name = name_svideo,
-			.vmux = 8,
-			.amux = LINE1,
+			.name = name_tv,
+			.vmux = 1,
+			.amux = TV,
+			.tv   = 1,
+
 		},{
-			.name   = name_comp1,
-			.vmux   = 1,
-			.amux   = LINE1,
+			.name = name_comp1,
+			.vmux = 4,
+			.amux = LINE2,
 		},{
-			.name = name_tv,
-			.vmux = 3,
+			.name = name_svideo,
+			.vmux = 6,
 			.amux = LINE2,
-			.tv   = 1,
 		}},
 		.radio = {
 			.name = name_radio,
-			.amux = LINE2,
-		},
-		.mute = {
-			.name = name_mute,
-                        .amux = LINE1,
+			.amux = LINE1,
 		},
 	},
-	[SAA7134_BOARD_MANLI_MTV001] = {
-		/* Ognjen Nastic <ognjen@logosoft.ba> UNTESTED */
-		.name           = "Manli MuchTV M-TV001",
-		.audio_clock    = 0x00200000,
-		.tuner_type     = TUNER_PHILIPS_PAL,
+	[SAA7134_BOARD_PINNACLE_PCTV_STEREO] = {
+		.name           = "Pinnacle PCTV Stereo (saa7134)",
+		.audio_clock    = 0x00187de7,
+		.tuner_type     = TUNER_MT2032,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
+		.tda9887_conf   = TDA9887_PRESENT | TDA9887_INTERCARRIER,
+		.inputs         = {{
+			.name = name_tv,
+			.vmux = 3,
+			.amux = TV,
+			.tv   = 1,
+		},{
+			.name = name_comp1,
+			.vmux = 0,
+			.amux = LINE2,
+		},{
+			.name = name_comp2,
+			.vmux = 1,
+			.amux = LINE2,
+		},{
+			.name = name_svideo,
+			.vmux = 8,
+			.amux = LINE2,
+		}},
+	},
+	[SAA7134_BOARD_MANLI_MTV002] = {
+		/* Ognjen Nastic <ognjen@logosoft.ba> */
+		.name           = "Manli MuchTV M-TV002/Behold TV 403 FM",
+		.audio_clock    = 0x00200000,
+		.tuner_type     = TUNER_PHILIPS_PAL,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
+		.inputs         = {{
+			.name = name_svideo,
+			.vmux = 8,
+			.amux = LINE1,
+		},{
+			.name   = name_comp1,
+			.vmux   = 1,
+			.amux   = LINE1,
+		},{
+			.name = name_tv,
+			.vmux = 3,
+			.amux = LINE2,
+			.tv   = 1,
+		}},
+		.radio = {
+			.name = name_radio,
+			.amux = LINE2,
+		},
+	},
+	[SAA7134_BOARD_MANLI_MTV001] = {
+		/* Ognjen Nastic <ognjen@logosoft.ba> UNTESTED */
+		.name           = "Manli MuchTV M-TV001/Behold TV 401",
+		.audio_clock    = 0x00200000,
+		.tuner_type     = TUNER_PHILIPS_PAL,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
 		.inputs         = {{
 			.name = name_svideo,
 			.vmux = 8,
@@ -923,12 +1042,19 @@ struct saa7134_board saa7134_boards[] = 
 			.amux = LINE2,
 			.tv   = 1,
 		}},
-        },
+		.mute = {
+			.name = name_mute,
+			.amux = LINE1,
+		},
+	},
 	[SAA7134_BOARD_TG3000TV] = {
 		/* TransGear 3000TV */
 		.name           = "Nagase Sangyo TransGear 3000TV",
 		.audio_clock    = 0x00187de7,
 		.tuner_type     = TUNER_PHILIPS_NTSC_M,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
 		.inputs         = {{
 			.name = name_tv,
 			.vmux = 1,
@@ -944,81 +1070,90 @@ struct saa7134_board saa7134_boards[] = 
 			.amux = LINE2,
 		}},
 	},
-        [SAA7134_BOARD_ECS_TVP3XP] = {
-                .name           = "Elitegroup ECS TVP3XP FM1216 Tuner Card(PAL-BG,FM) ",
-                .audio_clock    = 0x187de7,  // xtal 32.1 MHz
-                .tuner_type     = TUNER_PHILIPS_PAL,
-                .inputs         = {{
-                        .name   = name_tv,
-                        .vmux   = 1,
-                        .amux   = TV,
-                        .tv     = 1,
-                },{
-                        .name   = name_tv_mono,
-                        .vmux   = 1,
-                        .amux   = LINE2,
-                        .tv     = 1,
-                },{
-                        .name   = name_comp1,
-                        .vmux   = 3,
-                        .amux   = LINE1,
-                },{
-                        .name   = name_svideo,
-                        .vmux   = 8,
-                        .amux   = LINE1,
+	[SAA7134_BOARD_ECS_TVP3XP] = {
+		.name           = "Elitegroup ECS TVP3XP FM1216 Tuner Card(PAL-BG,FM) ",
+		.audio_clock    = 0x187de7,  /* xtal 32.1 MHz */
+		.tuner_type     = TUNER_PHILIPS_PAL,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
+		.inputs         = {{
+			.name   = name_tv,
+			.vmux   = 1,
+			.amux   = TV,
+			.tv     = 1,
+		},{
+			.name   = name_tv_mono,
+			.vmux   = 1,
+			.amux   = LINE2,
+			.tv     = 1,
+		},{
+			.name   = name_comp1,
+			.vmux   = 3,
+			.amux   = LINE1,
+		},{
+			.name   = name_svideo,
+			.vmux   = 8,
+			.amux   = LINE1,
 		},{
 			.name   = "CVid over SVid",
 			.vmux   = 0,
 			.amux   = LINE1,
 		}},
-                .radio = {
-                        .name   = name_radio,
-                        .amux   = LINE2,
-                },
-        },
-        [SAA7134_BOARD_ECS_TVP3XP_4CB5] = {
-                .name           = "Elitegroup ECS TVP3XP FM1236 Tuner Card (NTSC,FM)",
-                .audio_clock    = 0x187de7,
-                .tuner_type     = TUNER_PHILIPS_NTSC,
-                .inputs         = {{
-                        .name   = name_tv,
-                        .vmux   = 1,
-                        .amux   = TV,
-                        .tv     = 1,
-                },{
-                        .name   = name_tv_mono,
-                        .vmux   = 1,
-                        .amux   = LINE2,
-                        .tv     = 1,
-                },{
-                        .name   = name_comp1,
-                        .vmux   = 3,
-                        .amux   = LINE1,
-                },{
-                        .name   = name_svideo,
-                        .vmux   = 8,
-                        .amux   = LINE1,
-                },{
-                        .name   = "CVid over SVid",
-                        .vmux   = 0,
-                        .amux   = LINE1,
-                }},
-                .radio = {
-                        .name   = name_radio,
-                        .amux   = LINE2,
-                },
-        },
+		.radio = {
+			.name   = name_radio,
+			.amux   = LINE2,
+		},
+	},
+	[SAA7134_BOARD_ECS_TVP3XP_4CB5] = {
+		.name           = "Elitegroup ECS TVP3XP FM1236 Tuner Card (NTSC,FM)",
+		.audio_clock    = 0x187de7,
+		.tuner_type     = TUNER_PHILIPS_NTSC,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
+		.inputs         = {{
+			.name   = name_tv,
+			.vmux   = 1,
+			.amux   = TV,
+			.tv     = 1,
+		},{
+			.name   = name_tv_mono,
+			.vmux   = 1,
+			.amux   = LINE2,
+			.tv     = 1,
+		},{
+			.name   = name_comp1,
+			.vmux   = 3,
+			.amux   = LINE1,
+		},{
+			.name   = name_svideo,
+			.vmux   = 8,
+			.amux   = LINE1,
+		},{
+			.name   = "CVid over SVid",
+			.vmux   = 0,
+			.amux   = LINE1,
+		}},
+		.radio = {
+			.name   = name_radio,
+			.amux   = LINE2,
+		},
+	},
 	[SAA7134_BOARD_AVACSSMARTTV] = {
 		/* Roman Pszonczenko <romka@kolos.math.uni.lodz.pl> */
 		.name           = "AVACS SmartTV",
 		.audio_clock    = 0x00187de7,
 		.tuner_type     = TUNER_PHILIPS_PAL,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
 		.inputs         = {{
 			.name = name_tv,
 			.vmux = 1,
 			.amux = TV,
 			.tv   = 1,
-                },{
+		},{
 			.name = name_tv_mono,
 			.vmux = 1,
 			.amux = LINE2,
@@ -1047,6 +1182,9 @@ struct saa7134_board saa7134_boards[] = 
 		.name           = "AVerMedia DVD EZMaker",
 		.audio_clock    = 0x00187de7,
 		.tuner_type     = TUNER_ABSENT,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
 		.inputs         = {{
 			.name = name_comp1,
 			.vmux = 3,
@@ -1055,30 +1193,35 @@ struct saa7134_board saa7134_boards[] = 
 			.vmux = 8,
 		}},
 	},
-        [SAA7134_BOARD_NOVAC_PRIMETV7133] = {
-                /* toshii@netbsd.org */
-                .name           = "Noval Prime TV 7133",
-                .audio_clock    = 0x00200000,
-                .tuner_type     = TUNER_ALPS_TSBH1_NTSC,
-                .inputs         = {{
-                        .name = name_comp1,
-                        .vmux = 3,
-                },{
-                        .name = name_tv,
-                        .vmux = 1,
-                        .amux = TV,
-                        .tv   = 1,
-                },{
-                        .name = name_svideo,
-                        .vmux = 8,
-                }},
-        },
+	[SAA7134_BOARD_NOVAC_PRIMETV7133] = {
+		/* toshii@netbsd.org */
+		.name           = "Noval Prime TV 7133",
+		.audio_clock    = 0x00200000,
+		.tuner_type     = TUNER_ALPS_TSBH1_NTSC,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
+		.inputs         = {{
+			.name = name_comp1,
+			.vmux = 3,
+		},{
+			.name = name_tv,
+			.vmux = 1,
+			.amux = TV,
+			.tv   = 1,
+		},{
+			.name = name_svideo,
+			.vmux = 8,
+		}},
+	},
 	[SAA7134_BOARD_AVERMEDIA_STUDIO_305] = {
 		.name           = "AverMedia AverTV Studio 305",
 		.audio_clock    = 0x00187de7,
 		.tuner_type     = TUNER_PHILIPS_FM1256_IH3,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
 		.tda9887_conf   = TDA9887_PRESENT,
-		.gpiomask = 0x3,
 		.inputs         = {{
 			.name = name_tv,
 			.vmux = 1,
@@ -1098,35 +1241,41 @@ struct saa7134_board saa7134_boards[] = 
 			.amux = LINE2,
 		}},
 		.radio = {
-			 .name = name_radio,
-			 .amux = LINE2,
-		 },
+			.name = name_radio,
+			.amux = LINE2,
+		},
 		.mute = {
-			 .name = name_mute,
-			 .amux = LINE1,
+			.name = name_mute,
+			.amux = LINE1,
 		},
 	},
-  	[SAA7133_BOARD_UPMOST_PURPLE_TV] = {
-  		.name           = "UPMOST PURPLE TV",
-  		.audio_clock    = 0x00187de7,
-  		.tuner_type     = TUNER_PHILIPS_FM1236_MK3,
-  		.tda9887_conf   = TDA9887_PRESENT,
-  		.inputs         = {{
-  			.name = name_tv,
-  			.vmux = 7,
-  			.amux = TV,
-  			.tv   = 1,
-  		},{
-  			.name = name_svideo,
-  			.vmux = 7,
-  			.amux = LINE1,
-  		}},
+	[SAA7134_BOARD_UPMOST_PURPLE_TV] = {
+		.name           = "UPMOST PURPLE TV",
+		.audio_clock    = 0x00187de7,
+		.tuner_type     = TUNER_PHILIPS_FM1236_MK3,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
+		.tda9887_conf   = TDA9887_PRESENT,
+		.inputs         = {{
+			.name = name_tv,
+			.vmux = 7,
+			.amux = TV,
+			.tv   = 1,
+		},{
+			.name = name_svideo,
+			.vmux = 7,
+			.amux = LINE1,
+		}},
 	},
 	[SAA7134_BOARD_ITEMS_MTV005] = {
 		/* Norman Jonas <normanjonas@arcor.de> */
 		.name           = "Items MuchTV Plus / IT-005",
 		.audio_clock    = 0x00187de7,
 		.tuner_type     = TUNER_PHILIPS_PAL,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
 		.inputs         = {{
 			.name = name_tv,
 			.vmux = 3,
@@ -1150,27 +1299,30 @@ struct saa7134_board saa7134_boards[] = 
 		.name           = "Terratec Cinergy 200 TV",
 		.audio_clock    = 0x00200000,
 		.tuner_type     = TUNER_PHILIPS_PAL,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
 		.inputs         = {{
-       			.name = name_tv,
+			.name = name_tv,
 			.vmux = 1,
 			.amux = LINE2,
 			.tv   = 1,
-                },{
-                        .name = name_comp1,
-                        .vmux = 4,
-                        .amux = LINE1,
-                },{
-                        .name = name_svideo,
-                        .vmux = 8,
-                        .amux = LINE1,
-                },{
-                        .name = name_comp2, // CVideo over SVideo Connector
-                        .vmux = 0,
-                        .amux = LINE1,
+		},{
+			.name = name_comp1,
+			.vmux = 4,
+			.amux = LINE1,
+		},{
+			.name = name_svideo,
+			.vmux = 8,
+			.amux = LINE1,
+		},{
+			.name = name_comp2, /* CVideo over SVideo Connector */
+			.vmux = 0,
+			.amux = LINE1,
 		}},
 		.mute = {
-			 .name = name_mute,
-			 .amux = LINE2,
+			.name = name_mute,
+			.amux = LINE2,
 		},
 	},
 	[SAA7134_BOARD_VIDEOMATE_TV_PVR] = {
@@ -1178,84 +1330,96 @@ struct saa7134_board saa7134_boards[] = 
 		.name           = "Compro VideoMate TV PVR/FM",
 		.audio_clock    = 0x00187de7,
 		.tuner_type     = TUNER_PHILIPS_NTSC_M,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
 		.gpiomask	= 0x808c0080,
-                .inputs         = {{
-                        .name = name_svideo,
-                        .vmux = 8,
-                        .amux = LINE1,
+		.inputs         = {{
+			.name = name_svideo,
+			.vmux = 8,
+			.amux = LINE1,
 			.gpio = 0x00080,
-                },{
-                        .name = name_comp1,
-                        .vmux = 3,
-                        .amux = LINE1,
+		},{
+			.name = name_comp1,
+			.vmux = 3,
+			.amux = LINE1,
 			.gpio = 0x00080,
-                },{
-                        .name = name_tv,
-                        .vmux = 1,
-                        .amux = LINE2_LEFT,
-                        .tv   = 1,
+		},{
+			.name = name_tv,
+			.vmux = 1,
+			.amux = LINE2_LEFT,
+			.tv   = 1,
 			.gpio = 0x00080,
-                }},
+		}},
 		.radio = {
 			.name = name_radio,
 			.amux = LINE2,
 			.gpio = 0x80000,
-		 },
+		},
 		.mute = {
 			.name = name_mute,
-                        .amux = LINE2,
+			.amux = LINE2,
 			.gpio = 0x40000,
 		},
-        },
-        [SAA7134_BOARD_SABRENT_SBTTVFM] = {
+	},
+	[SAA7134_BOARD_SABRENT_SBTTVFM] = {
 		/* Michael Rodriguez-Torrent <mrtorrent@asu.edu> */
-                .name           = "Sabrent SBT-TVFM (saa7130)",
-                .audio_clock    = 0x00187de7,
-                .tuner_type     = TUNER_PHILIPS_NTSC_M,
-                .inputs         = {{
+		.name           = "Sabrent SBT-TVFM (saa7130)",
+		.audio_clock    = 0x00187de7,
+		.tuner_type     = TUNER_PHILIPS_NTSC_M,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
+		.inputs         = {{
 			.name = name_comp1,
 			.vmux = 1,
 			.amux = LINE2,
 		},{
-                        .name = name_tv,
-                        .vmux = 3,
-                        .amux = LINE2,
-                        .tv   = 1,
-                },{
-                        .name = name_svideo,
-                        .vmux = 8,
-                        .amux = LINE2,
-                }},
-                .radio = {
-                        .name   = name_radio,
-                        .amux   = LINE2,
-                },
-        },
+			.name = name_tv,
+			.vmux = 3,
+			.amux = LINE2,
+			.tv   = 1,
+		},{
+			.name = name_svideo,
+			.vmux = 8,
+			.amux = LINE2,
+		}},
+		.radio = {
+			.name   = name_radio,
+			.amux   = LINE2,
+		},
+	},
 	[SAA7134_BOARD_ZOLID_XPERT_TV7134] = {
 		/* Helge Jensen <helge.jensen@slog.dk> */
-                .name           = ":Zolid Xpert TV7134",
+		.name           = ":Zolid Xpert TV7134",
 		.audio_clock    = 0x00187de7,
 		.tuner_type     = TUNER_PHILIPS_NTSC,
-                .inputs         = {{
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
+		.inputs         = {{
 			.name = name_svideo,
-                        .vmux = 8,
-                        .amux = LINE1,
-                },{
-                        .name = name_comp1,
-                        .vmux = 3,
-                        .amux = LINE1,
-                },{
-                        .name = name_tv,
-                        .vmux = 1,
-                        .amux = LINE2,
-                        .tv   = 1,
-                }},
+			.vmux = 8,
+			.amux = LINE1,
+		},{
+			.name = name_comp1,
+			.vmux = 3,
+			.amux = LINE1,
+		},{
+			.name = name_tv,
+			.vmux = 1,
+			.amux = LINE2,
+			.tv   = 1,
+		}},
 	},
 	[SAA7134_BOARD_EMPIRE_PCI_TV_RADIO_LE] = {
 		/* "Matteo Az" <matte.az@nospam.libero.it> ;-) */
 		.name           = "Empire PCI TV-Radio LE",
 		.audio_clock    = 0x00187de7,
 		.tuner_type     = TUNER_PHILIPS_PAL,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
 		.gpiomask       = 0x4000,
 		.inputs         = {{
 			.name = name_tv_mono,
@@ -1274,18 +1438,18 @@ struct saa7134_board saa7134_boards[] = 
 			.amux = LINE1,
 			.gpio = 0x8000,
 		}},
-                .radio = {
-			 .name = name_radio,
-			 .amux = LINE1,
-			 .gpio = 0x8000,
-		 },
+		.radio = {
+			.name = name_radio,
+			.amux = LINE1,
+			.gpio = 0x8000,
+		},
 		.mute = {
-			 .name = name_mute,
-			 .amux = TV,
-			 .gpio =0x8000,
-		 }
+			.name = name_mute,
+			.amux = TV,
+			.gpio =0x8000,
+		}
 	},
-        [SAA7134_BOARD_AVERMEDIA_307] = {
+	[SAA7134_BOARD_AVERMEDIA_STUDIO_307] = {
 		/*
 		Nickolay V. Shmyrev <nshmyrev@yandex.ru>
 		Lots of thanks to Andrey Zolotarev <zolotarev_andrey@mail.ru>
@@ -1293,6 +1457,9 @@ struct saa7134_board saa7134_boards[] = 
 		.name           = "Avermedia AVerTV Studio 307",
 		.audio_clock    = 0x00187de7,
 		.tuner_type     = TUNER_PHILIPS_FM1256_IH3,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
 		.tda9887_conf   = TDA9887_PRESENT,
 		.gpiomask       = 0x03,
 		.inputs         = {{
@@ -1322,16 +1489,61 @@ struct saa7134_board saa7134_boards[] = 
 			.amux = LINE1,
 			.gpio = 0x01,
 		},
-        },
-	[SAA7134_BOARD_AVERMEDIA_CARDBUS] = {
-		/* Jon Westgate <oryn@oryn.fsck.tv> */
-		.name           = "AVerMedia Cardbus TV/Radio",
-		.audio_clock    = 0x00200000,
-		.tuner_type     = TUNER_PHILIPS_PAL,
+		.mute  = {
+			.name = name_mute,
+			.amux = LINE1,
+			.gpio = 0x00,
+		},
+	},
+	[SAA7134_BOARD_AVERMEDIA_GO_007_FM] = {
+		.name           = "Avermedia AVerTV GO 007 FM",
+		.audio_clock    = 0x00187de7,
+		.tuner_type     = TUNER_PHILIPS_TDA8290,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
+		.gpiomask       = 0x00300003,
+		/* .gpiomask       = 0x8c240003, */
 		.inputs         = {{
 			.name = name_tv,
 			.vmux = 1,
+			.amux = TV,
+			.tv   = 1,
+			.gpio = 0x01,
+		},{
+			.name = name_comp1,
+			.vmux = 0,
 			.amux = LINE2,
+			.gpio = 0x02,
+		},{
+			.name = name_svideo,
+			.vmux = 6,
+			.amux = LINE2,
+			.gpio = 0x02,
+		}},
+		.radio = {
+			.name = name_radio,
+			.amux = LINE1,
+			.gpio = 0x00300001,
+		},
+		.mute = {
+			.name = name_mute,
+			.amux = TV,
+			.gpio = 0x01,
+		},
+	},
+	[SAA7134_BOARD_AVERMEDIA_CARDBUS] = {
+		/* Kees.Blom@cwi.nl */
+		.name           = "AVerMedia Cardbus TV/Radio (E500)",
+		.audio_clock    = 0x187de7,
+		.tuner_type     = TUNER_PHILIPS_TDA8290,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
+		.inputs         = {{
+			.name = name_tv,
+			.vmux = 1,
+			.amux = TV,
 			.tv   = 1,
 		},{
 			.name = name_comp1,
@@ -1340,10 +1552,10 @@ struct saa7134_board saa7134_boards[] = 
 		},{
 			.name = name_svideo,
 			.vmux = 8,
-			.amux = LINE2,
+			.amux = LINE1,
 		}},
 		.radio = {
-                	.name = name_radio,
+			.name = name_radio,
 			.amux = LINE1,
 		},
 	},
@@ -1351,159 +1563,279 @@ struct saa7134_board saa7134_boards[] = 
 		.name           = "Terratec Cinergy 400 mobile",
 		.audio_clock    = 0x187de7,
 		.tuner_type     = TUNER_ALPS_TSBE5_PAL,
-  		.tda9887_conf   = TDA9887_PRESENT,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
+		.tda9887_conf   = TDA9887_PRESENT,
 		.inputs         = {{
-       			.name = name_tv,
+			.name = name_tv,
 			.vmux = 1,
 			.amux = TV,
 			.tv   = 1,
-               },{
+		},{
 			.name = name_tv_mono,
 			.vmux = 1,
 			.amux = LINE2,
 			.tv   = 1,
-                },{
-                        .name = name_comp1,
-                        .vmux = 3,
-                        .amux = LINE1,
-                },{
-                        .name = name_svideo,
-                        .vmux = 8,
-                        .amux = LINE1,
+		},{
+			.name = name_comp1,
+			.vmux = 3,
+			.amux = LINE1,
+		},{
+			.name = name_svideo,
+			.vmux = 8,
+			.amux = LINE1,
 		}},
 	},
 	[SAA7134_BOARD_CINERGY600_MK3] = {
-                .name           = "Terratec Cinergy 600 TV MK3",
-                .audio_clock    = 0x00200000,
+		.name           = "Terratec Cinergy 600 TV MK3",
+		.audio_clock    = 0x00200000,
 		.tuner_type	= TUNER_PHILIPS_FM1216ME_MK3,
-  		.tda9887_conf   = TDA9887_PRESENT,
-                .inputs         = {{
-                        .name = name_tv,
-                        .vmux = 1,
-                        .amux = TV,
-                        .tv   = 1,
-                },{
-                        .name = name_comp1,
-                        .vmux = 4,
-                        .amux = LINE1,
-                },{
-                        .name = name_svideo,
-                        .vmux = 8,
-                        .amux = LINE1,
-                },{
-                        .name = name_comp2, // CVideo over SVideo Connector
-                        .vmux = 0,
-                        .amux = LINE1,
-                }},
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
+		.tda9887_conf   = TDA9887_PRESENT,
+		.inputs         = {{
+			.name = name_tv,
+			.vmux = 1,
+			.amux = TV,
+			.tv   = 1,
+		},{
+			.name = name_comp1,
+			.vmux = 4,
+			.amux = LINE1,
+		},{
+			.name = name_svideo,
+			.vmux = 8,
+			.amux = LINE1,
+		},{
+			.name = name_comp2, /* CVideo over SVideo Connector */
+			.vmux = 0,
+			.amux = LINE1,
+		}},
 		.radio = {
 			.name = name_radio,
 			.amux = LINE2,
-               },
-        },
- 	[SAA7134_BOARD_VIDEOMATE_GOLD_PLUS] = {
- 		/* Dylan Walkden <dylan_walkden@hotmail.com> */
- 		.name		= "Compro VideoMate Gold+ Pal",
- 		.audio_clock	= 0x00187de7,
- 		.tuner_type	= TUNER_PHILIPS_PAL,
- 		.gpiomask	= 0x1ce780,
- 		.inputs		= {{
- 			.name = name_svideo,
- 			.vmux = 0,		// CVideo over SVideo Connector - ok?
- 			.amux = LINE1,
- 			.gpio = 0x008080,
- 		},{
- 			.name = name_comp1,
- 			.vmux = 3,
- 			.amux = LINE1,
- 			.gpio = 0x008080,
- 		},{
- 			.name = name_tv,
- 			.vmux = 1,
- 			.amux = TV,
- 			.tv   = 1,
- 			.gpio = 0x008080,
- 		}},
- 		.radio = {
- 			.name = name_radio,
- 			.amux = LINE2,
- 			.gpio = 0x80000,
- 		},
- 		.mute = {
- 			.name = name_mute,
- 			.amux = LINE2,
- 			.gpio = 0x0c8000,
- 		},
- 	},
+		},
+	},
+	[SAA7134_BOARD_VIDEOMATE_GOLD_PLUS] = {
+		/* Dylan Walkden <dylan_walkden@hotmail.com> */
+		.name		= "Compro VideoMate Gold+ Pal",
+		.audio_clock	= 0x00187de7,
+		.tuner_type     = TUNER_PHILIPS_PAL,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
+		.gpiomask	= 0x1ce780,
+		.inputs		= {{
+			.name = name_svideo,
+			.vmux = 0,		/* CVideo over SVideo Connector - ok? */
+			.amux = LINE1,
+			.gpio = 0x008080,
+		},{
+			.name = name_comp1,
+			.vmux = 3,
+			.amux = LINE1,
+			.gpio = 0x008080,
+		},{
+			.name = name_tv,
+			.vmux = 1,
+			.amux = TV,
+			.tv   = 1,
+			.gpio = 0x008080,
+		}},
+		.radio = {
+			.name = name_radio,
+			.amux = LINE2,
+			.gpio = 0x80000,
+		},
+		.mute = {
+			.name = name_mute,
+			.amux = LINE2,
+			.gpio = 0x0c8000,
+		},
+	},
 	[SAA7134_BOARD_PINNACLE_300I_DVBT_PAL] = {
-                .name           = "Pinnacle PCTV 300i DVB-T + PAL",
-                .audio_clock    = 0x00187de7,
-                .tuner_type     = TUNER_MT2032,
-                .tda9887_conf   = TDA9887_PRESENT | TDA9887_INTERCARRIER,
+		.name           = "Pinnacle PCTV 300i DVB-T + PAL",
+		.audio_clock    = 0x00187de7,
+		.tuner_type     = TUNER_MT2032,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
+		.tda9887_conf   = TDA9887_PRESENT | TDA9887_INTERCARRIER,
 		.mpeg           = SAA7134_MPEG_DVB,
-                .inputs         = {{
-                        .name = name_tv,
-                        .vmux = 3,
-                        .amux = TV,
-                        .tv   = 1,
-                },{
-                        .name = name_comp1,
-                        .vmux = 0,
-                        .amux = LINE2,
-                },{
-                        .name = name_comp2,
-                        .vmux = 1,
-                        .amux = LINE2,
-                },{
-                        .name = name_svideo,
-                        .vmux = 8,
-                        .amux = LINE2,
-                }},
-        },
+		.inputs         = {{
+			.name = name_tv,
+			.vmux = 3,
+			.amux = TV,
+			.tv   = 1,
+		},{
+			.name = name_comp1,
+			.vmux = 0,
+			.amux = LINE2,
+		},{
+			.name = name_comp2,
+			.vmux = 1,
+			.amux = LINE2,
+		},{
+			.name = name_svideo,
+			.vmux = 8,
+			.amux = LINE2,
+		}},
+	},
 	[SAA7134_BOARD_PROVIDEO_PV952] = {
 		/* andreas.kretschmer@web.de */
 		.name		= "ProVideo PV952",
 		.audio_clock	= 0x00187de7,
 		.tuner_type	= TUNER_PHILIPS_FM1216ME_MK3,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
+		.tda9887_conf   = TDA9887_PRESENT,
+		.inputs         = {{
+			.name = name_comp1,
+			.vmux = 0,
+			.amux = LINE1,
+		},{
+			.name = name_tv,
+			.vmux = 1,
+			.amux = TV,
+			.tv   = 1,
+		},{
+			.name = name_tv_mono,
+			.vmux = 1,
+			.amux = LINE2,
+			.tv   = 1,
+		}},
+		.radio = {
+			.name = name_radio,
+			.amux = LINE2,
+		},
+	},
+	[SAA7134_BOARD_AVERMEDIA_305] = {
+		/* much like the "studio" version but without radio
+		* and another tuner (sirspiritus@yandex.ru) */
+		.name           = "AverMedia AverTV/305",
+		.audio_clock    = 0x00187de7,
+		.tuner_type     = TUNER_PHILIPS_FQ1216ME,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
+		.tda9887_conf   = TDA9887_PRESENT,
+		.inputs         = {{
+			.name = name_tv,
+			.vmux = 1,
+			.amux = LINE2,
+			.tv   = 1,
+		},{
+			.name = name_comp1,
+			.vmux = 0,
+			.amux = LINE2,
+		},{
+			.name = name_comp2,
+			.vmux = 3,
+			.amux = LINE2,
+		},{
+			.name = name_svideo,
+			.vmux = 8,
+			.amux = LINE2,
+		}},
+		.mute = {
+			.name = name_mute,
+			.amux = LINE1,
+		},
+	},
+	[SAA7134_BOARD_FLYDVBTDUO] = {
+		/* LifeView FlyDVB-T DUO */
+		/* "Nico Sabbi <nsabbi@tiscali.it>  Hartmut Hackmann hartmut.hackmann@t-online.de*/
+		.name           = "LifeView FlyDVB-T DUO",
+		.audio_clock    = 0x00200000,
+		.tuner_type     = TUNER_PHILIPS_TDA8290,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
+		.mpeg           = SAA7134_MPEG_DVB,
+		.inputs         = {{
+			.name = name_tv,
+			.vmux = 1,
+			.amux = TV,
+			.tv   = 1,
+		},{
+			.name = name_comp1,	/* Composite signal on S-Video input */
+			.vmux = 0,
+			.amux = LINE2,
+		},{
+			.name = name_comp2,	/* Composite input */
+			.vmux = 3,
+			.amux = LINE2,
+		},{
+			.name = name_svideo,	/* S-Video signal on S-Video input */
+			.vmux = 8,
+			.amux = LINE2,
+		}},
+	},
+	[SAA7134_BOARD_PHILIPS_TOUGH] = {
+		.name           = "Philips TOUGH DVB-T reference design",
+		.tuner_type	= TUNER_ABSENT,
+		.audio_clock    = 0x00187de7,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
+		.mpeg           = SAA7134_MPEG_DVB,
+		.inputs = {{
+			.name   = name_comp1,
+			.vmux   = 0,
+			.amux   = LINE1,
+		},{
+			.name   = name_svideo,
+			.vmux   = 8,
+			.amux   = LINE1,
+		}},
+	},
+	[SAA7134_BOARD_AVERMEDIA_307] = {
+		/*
+		Davydov Vladimir <vladimir@iqmedia.com>
+		*/
+		.name           = "Avermedia AVerTV 307",
+		.audio_clock    = 0x00187de7,
+		.tuner_type     = TUNER_PHILIPS_FQ1216ME,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
 		.tda9887_conf   = TDA9887_PRESENT,
 		.inputs         = {{
-			.name = name_comp1,
-			.vmux = 0,
-			.amux = LINE1,
-		},{
 			.name = name_tv,
 			.vmux = 1,
 			.amux = TV,
 			.tv   = 1,
 		},{
-			.name = name_tv_mono,
-			.vmux = 1,
-			.amux = LINE2,
-			.tv   = 1,
+			.name = name_comp1,
+			.vmux = 0,
+			.amux = LINE1,
+		},{
+			.name = name_comp2,
+			.vmux = 3,
+			.amux = LINE1,
+		},{
+			.name = name_svideo,
+			.vmux = 8,
+			.amux = LINE1,
 		}},
-		.radio = {
-			.name = name_radio,
-			.amux = LINE2,
-		},
 	},
-	[SAA7134_BOARD_AVERMEDIA_305] = {
-		/* much like the "studio" version but without radio
-		 * and another tuner (sirspiritus@yandex.ru) */
-		.name           = "AverMedia AverTV/305",
+	[SAA7134_BOARD_ADS_INSTANT_TV] = {
+		.name           = "ADS Tech Instant TV (saa7135)",
 		.audio_clock    = 0x00187de7,
-		.tuner_type     = TUNER_PHILIPS_FQ1216ME,
-		.tda9887_conf   = TDA9887_PRESENT,
-		.gpiomask = 0x3,
+		.tuner_type     = TUNER_PHILIPS_TDA8290,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
 		.inputs         = {{
 			.name = name_tv,
 			.vmux = 1,
-			.amux = LINE2,
+			.amux = TV,
 			.tv   = 1,
 		},{
 			.name = name_comp1,
-			.vmux = 0,
-			.amux = LINE2,
-		},{
-			.name = name_comp2,
 			.vmux = 3,
 			.amux = LINE2,
 		},{
@@ -1511,42 +1843,167 @@ struct saa7134_board saa7134_boards[] = 
 			.vmux = 8,
 			.amux = LINE2,
 		}},
-		.mute = {
-			 .name = name_mute,
-			 .amux = LINE1,
+	},
+	[SAA7134_BOARD_KWORLD_VSTREAM_XPERT] = {
+		.name           = "Kworld/Tevion V-Stream Xpert TV PVR7134",
+		.audio_clock    = 0x00187de7,
+		.tuner_type     = TUNER_PHILIPS_PAL_I,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
+		.gpiomask	= 0x0700,
+		.inputs = {{
+			.name   = name_tv,
+			.vmux   = 1,
+			.amux   = TV,
+			.tv     = 1,
+			.gpio   = 0x000,
+		},{
+			.name   = name_comp1,
+			.vmux   = 3,
+			.amux   = LINE1,
+			.gpio   = 0x200,		/* gpio by DScaler */
+		},{
+			.name   = name_svideo,
+			.vmux   = 0,
+			.amux   = LINE1,
+			.gpio   = 0x200,
+		}},
+		.radio = {
+			.name   = name_radio,
+			.amux   = LINE1,
+			.gpio   = 0x100,
+		},
+		.mute  = {
+			.name = name_mute,
+			.amux = TV,
+			.gpio = 0x000,
 		},
 	},
-	[SAA7134_BOARD_FLYDVBTDUO] = {
-		/* LifeView FlyDVB-T DUO */
-		/* "Nico Sabbi <nsabbi@tiscali.it> */
-		.name           = "LifeView FlyDVB-T DUO",
+	[SAA7134_BOARD_THYPHOON_DVBT_DUO_CARDBUS] = {
+		.name		= "Typhoon DVB-T Duo Digital/Analog Cardbus",
 		.audio_clock    = 0x00200000,
 		.tuner_type     = TUNER_PHILIPS_TDA8290,
-//		.gpiomask       = 0xe000,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
+		.mpeg           = SAA7134_MPEG_DVB,
+		/* .gpiomask       = 0xe000, */
 		.inputs         = {{
 			.name = name_tv,
 			.vmux = 1,
 			.amux = TV,
-//			.gpio = 0x0000,
+		/*	.gpio = 0x0000,      */
 			.tv   = 1,
-                },{
+		},{
 			.name = name_comp1,	/* Composite signal on S-Video input */
 			.vmux = 0,
 			.amux = LINE2,
-//			.gpio = 0x4000,
+		/*	.gpio = 0x4000,      */
 		},{
 			.name = name_comp2,	/* Composite input */
 			.vmux = 3,
 			.amux = LINE2,
-//			.gpio = 0x4000,
+		/*	.gpio = 0x4000,      */
 		},{
 			.name = name_svideo,	/* S-Video signal on S-Video input */
 			.vmux = 8,
 			.amux = LINE2,
-//			.gpio = 0x4000,
+		/*	.gpio = 0x4000,      */
+		}},
+		.radio = {
+			.name = name_radio,
+			.amux = LINE2,
+		},
+		.mute = {
+			.name = name_mute,
+			.amux = LINE1,
+		},
+	},
+	[SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII] = {
+		.name           = "Compro VideoMate TV Gold+II",
+		.audio_clock    = 0x002187de7,
+		.tuner_type     = TUNER_LG_PAL_NEW_TAPC,
+		.radio_type     = TUNER_TEA5767,
+		.tuner_addr     = 0x63,
+		.radio_addr     = 0x60,
+		.gpiomask       = 0x8c1880,
+		.inputs         = {{
+			.name = name_svideo,
+			.vmux = 0,
+			.amux = LINE1,
+			.gpio = 0x800800,
+		},{
+			.name = name_comp1,
+			.vmux = 3,
+			.amux = LINE1,
+			.gpio = 0x801000,
+		},{
+			.name = name_tv,
+			.vmux = 1,
+			.amux = TV,
+			.tv   = 1,
+			.gpio = 0x800000,
+		}},
+		.radio = {
+			.name = name_radio,
+			.amux = TV,
+			.gpio = 0x880000,
+		},
+		.mute = {
+			.name = name_mute,
+			.amux = LINE2,
+			.gpio = 0x840000,
+		},
+	},
+	[SAA7134_BOARD_KWORLD_XPERT] = {
+		/*
+		FIXME:
+		- Remote control doesn't initialize properly.
+		- Audio volume starts muted,
+		then gradually increases after channel change.
+		- Overlay scaling problems (application error?)
+		- Composite S-Video untested.
+		From: Konrad Rzepecki <hannibal@megapolis.pl>
+		*/
+		.name           = "Kworld Xpert TV PVR7134",
+		.audio_clock    = 0x00187de7,
+		.tuner_type     = TUNER_TENA_9533_DI,
+		.radio_type     = TUNER_TEA5767,
+		.tuner_addr	= 0x61,
+		.radio_addr	= 0x60,
+		.gpiomask	= 0x0700,
+		.inputs = {{
+			.name   = name_tv,
+			.vmux   = 1,
+			.amux   = TV,
+			.tv     = 1,
+			.gpio   = 0x000,
+		},{
+			.name   = name_comp1,
+			.vmux   = 3,
+			.amux   = LINE1,
+			.gpio   = 0x200,		/* gpio by DScaler */
+		},{
+			.name   = name_svideo,
+			.vmux   = 0,
+			.amux   = LINE1,
+			.gpio   = 0x200,
 		}},
+		.radio = {
+			.name   = name_radio,
+			.amux   = LINE1,
+			.gpio   = 0x100,
+		},
+		.mute = {
+			.name = name_mute,
+			.amux = TV,
+			.gpio = 0x000,
+		},
 	},
 };
+
+
 const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards);
 
 /* ------------------------------------------------------------------ */
@@ -1559,13 +2016,13 @@ struct pci_device_id saa7134_pci_tbl[] =
 		.subvendor    = PCI_VENDOR_ID_PHILIPS,
 		.subdevice    = 0x2001,
 		.driver_data  = SAA7134_BOARD_PROTEUS_PRO,
-        },{
+	},{
 		.vendor       = PCI_VENDOR_ID_PHILIPS,
 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
 		.subvendor    = PCI_VENDOR_ID_PHILIPS,
 		.subdevice    = 0x2001,
 		.driver_data  = SAA7134_BOARD_PROTEUS_PRO,
-        },{
+	},{
 		.vendor       = PCI_VENDOR_ID_PHILIPS,
 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7134,
 		.subvendor    = PCI_VENDOR_ID_PHILIPS,
@@ -1574,70 +2031,70 @@ struct pci_device_id saa7134_pci_tbl[] =
 	},{
 		.vendor       = PCI_VENDOR_ID_PHILIPS,
 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7134,
-                .subvendor    = 0x1131,
-                .subdevice    = 0x4e85,
+		.subvendor    = 0x1131,
+		.subdevice    = 0x4e85,
 		.driver_data  = SAA7134_BOARD_MONSTERTV,
-        },{
-                .vendor       = PCI_VENDOR_ID_PHILIPS,
-                .device       = PCI_DEVICE_ID_PHILIPS_SAA7134,
-                .subvendor    = 0x153B,
-                .subdevice    = 0x1142,
-                .driver_data  = SAA7134_BOARD_CINERGY400,
-        },{
-                .vendor       = PCI_VENDOR_ID_PHILIPS,
-                .device       = PCI_DEVICE_ID_PHILIPS_SAA7134,
-                .subvendor    = 0x153B,
-                .subdevice    = 0x1143,
-                .driver_data  = SAA7134_BOARD_CINERGY600,
-        },{
-                .vendor       = PCI_VENDOR_ID_PHILIPS,
-                .device       = PCI_DEVICE_ID_PHILIPS_SAA7134,
-                .subvendor    = 0x153B,
-                .subdevice    = 0x1158,
-                .driver_data  = SAA7134_BOARD_CINERGY600_MK3,
-        },{
+	},{
+		.vendor       = PCI_VENDOR_ID_PHILIPS,
+		.device       = PCI_DEVICE_ID_PHILIPS_SAA7134,
+		.subvendor    = 0x153B,
+		.subdevice    = 0x1142,
+		.driver_data  = SAA7134_BOARD_CINERGY400,
+	},{
+		.vendor       = PCI_VENDOR_ID_PHILIPS,
+		.device       = PCI_DEVICE_ID_PHILIPS_SAA7134,
+		.subvendor    = 0x153B,
+		.subdevice    = 0x1143,
+		.driver_data  = SAA7134_BOARD_CINERGY600,
+	},{
+		.vendor       = PCI_VENDOR_ID_PHILIPS,
+		.device       = PCI_DEVICE_ID_PHILIPS_SAA7134,
+		.subvendor    = 0x153B,
+		.subdevice    = 0x1158,
+		.driver_data  = SAA7134_BOARD_CINERGY600_MK3,
+	},{
 		.vendor       = PCI_VENDOR_ID_PHILIPS,
 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
 		.subvendor    = 0x153b,
 		.subdevice    = 0x1162,
 		.driver_data  = SAA7134_BOARD_CINERGY400_CARDBUS,
-        },{
+	},{
 		.vendor       = PCI_VENDOR_ID_PHILIPS,
 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7134,
 		.subvendor    = 0x5168,
 		.subdevice    = 0x0138,
 		.driver_data  = SAA7134_BOARD_FLYVIDEO3000,
-        },{
+	},{
 		.vendor       = PCI_VENDOR_ID_PHILIPS,
-                .device       = PCI_DEVICE_ID_PHILIPS_SAA7134,
-                .subvendor    = 0x4e42,				//"Typhoon PCI Capture TV Card" Art.No. 50673
-                .subdevice    = 0x0138,
-                .driver_data  = SAA7134_BOARD_FLYVIDEO3000,
-        },{
+		.device       = PCI_DEVICE_ID_PHILIPS_SAA7134,
+		.subvendor    = 0x4e42,				/* "Typhoon PCI Capture TV Card" Art.No. 50673 */
+		.subdevice    = 0x0138,
+		.driver_data  = SAA7134_BOARD_FLYVIDEO3000,
+	},{
 		.vendor       = PCI_VENDOR_ID_PHILIPS,
 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7130,
 		.subvendor    = 0x5168,
 		.subdevice    = 0x0138,
 		.driver_data  = SAA7134_BOARD_FLYVIDEO2000,
-        },{
+	},{
 		.vendor       = PCI_VENDOR_ID_PHILIPS,
-		.device       = PCI_DEVICE_ID_PHILIPS_SAA7135,
+		.device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
 		.subvendor    = 0x5168,
 		.subdevice    = 0x0212, /* minipci, LR212 */
 		.driver_data  = SAA7134_BOARD_FLYTVPLATINUM_MINI,
-        },{
+	},{
 		.vendor       = PCI_VENDOR_ID_PHILIPS,
 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
 		.subvendor    = 0x5168,	/* Animation Technologies (LifeView) */
 		.subdevice    = 0x0214, /* Standard PCI, LR214WF */
 		.driver_data  = SAA7134_BOARD_FLYTVPLATINUM_FM,
-        },{
+	},{
 		.vendor       = PCI_VENDOR_ID_PHILIPS,
 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
 		.subvendor    = 0x1489, /* KYE */
 		.subdevice    = 0x0214, /* Genius VideoWonder ProTV */
 		.driver_data  = SAA7134_BOARD_FLYTVPLATINUM_FM, /* is an LR214WF actually */
-        },{
+	},{
 		.vendor       = PCI_VENDOR_ID_PHILIPS,
 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7134,
 		.subvendor    = 0x16be,
@@ -1656,36 +2113,36 @@ struct pci_device_id saa7134_pci_tbl[] =
 		.subdevice    = 0x226b,
 		.driver_data  = SAA7134_BOARD_ELSA_500TV,
 	},{
-                .vendor       = PCI_VENDOR_ID_PHILIPS,
-                .device       = PCI_DEVICE_ID_PHILIPS_SAA7134,
-                .subvendor    = PCI_VENDOR_ID_ASUSTEK,
-                .subdevice    = 0x4842,
-                .driver_data  = SAA7134_BOARD_ASUSTeK_TVFM7134,
-	},{
-                .vendor       = PCI_VENDOR_ID_PHILIPS,
-                .device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
-                .subvendor    = PCI_VENDOR_ID_ASUSTEK,
-                .subdevice    = 0x4845,
-                .driver_data  = SAA7135_BOARD_ASUSTeK_TVFM7135,
-	},{
-                .vendor       = PCI_VENDOR_ID_PHILIPS,
-                .device       = PCI_DEVICE_ID_PHILIPS_SAA7134,
-                .subvendor    = PCI_VENDOR_ID_ASUSTEK,
-                .subdevice    = 0x4830,
-                .driver_data  = SAA7134_BOARD_ASUSTeK_TVFM7134,
-        },{
-                .vendor       = PCI_VENDOR_ID_PHILIPS,
-                .device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
-                .subvendor    = PCI_VENDOR_ID_ASUSTEK,
-                .subdevice    = 0x4843,
-                .driver_data  = SAA7134_BOARD_ASUSTEK_TVFM7133,
-	},{
-                .vendor       = PCI_VENDOR_ID_PHILIPS,
-                .device       = PCI_DEVICE_ID_PHILIPS_SAA7134,
-                .subvendor    = PCI_VENDOR_ID_ASUSTEK,
-                .subdevice    = 0x4840,
-                .driver_data  = SAA7134_BOARD_ASUSTeK_TVFM7134,
-        },{
+		.vendor       = PCI_VENDOR_ID_PHILIPS,
+		.device       = PCI_DEVICE_ID_PHILIPS_SAA7134,
+		.subvendor    = PCI_VENDOR_ID_ASUSTEK,
+		.subdevice    = 0x4842,
+		.driver_data  = SAA7134_BOARD_ASUSTeK_TVFM7134,
+	},{
+		.vendor       = PCI_VENDOR_ID_PHILIPS,
+		.device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
+		.subvendor    = PCI_VENDOR_ID_ASUSTEK,
+		.subdevice    = 0x4845,
+		.driver_data  = SAA7134_BOARD_ASUSTeK_TVFM7135,
+	},{
+		.vendor       = PCI_VENDOR_ID_PHILIPS,
+		.device       = PCI_DEVICE_ID_PHILIPS_SAA7134,
+		.subvendor    = PCI_VENDOR_ID_ASUSTEK,
+		.subdevice    = 0x4830,
+		.driver_data  = SAA7134_BOARD_ASUSTeK_TVFM7134,
+	},{
+		.vendor       = PCI_VENDOR_ID_PHILIPS,
+		.device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
+		.subvendor    = PCI_VENDOR_ID_ASUSTEK,
+		.subdevice    = 0x4843,
+		.driver_data  = SAA7134_BOARD_ASUSTEK_TVFM7133,
+	},{
+		.vendor       = PCI_VENDOR_ID_PHILIPS,
+		.device       = PCI_DEVICE_ID_PHILIPS_SAA7134,
+		.subvendor    = PCI_VENDOR_ID_ASUSTEK,
+		.subdevice    = 0x4840,
+		.driver_data  = SAA7134_BOARD_ASUSTeK_TVFM7134,
+	},{
 		.vendor       = PCI_VENDOR_ID_PHILIPS,
 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7134,
 		.subvendor    = PCI_VENDOR_ID_PHILIPS,
@@ -1706,124 +2163,130 @@ struct pci_device_id saa7134_pci_tbl[] =
 	},{
 		.vendor       = PCI_VENDOR_ID_PHILIPS,
 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7134,
-                .subvendor    = 0x1131,
-                .subdevice    = 0x7133,
+		.subvendor    = 0x1131,
+		.subdevice    = 0x7133,
 		.driver_data  = SAA7134_BOARD_VA1000POWER,
-        },{
+	},{
 		.vendor       = PCI_VENDOR_ID_PHILIPS,
 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7130,
-                .subvendor    = PCI_VENDOR_ID_PHILIPS,
-                .subdevice    = 0x2001,
+		.subvendor    = PCI_VENDOR_ID_PHILIPS,
+		.subdevice    = 0x2001,
 		.driver_data  = SAA7134_BOARD_10MOONSTVMASTER,
-        },{
+	},{
 		.vendor       = PCI_VENDOR_ID_PHILIPS,
 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
-                .subvendor    = 0x185b,
-                .subdevice    = 0xc100,
+		.subvendor    = 0x185b,
+		.subdevice    = 0xc100,
 		.driver_data  = SAA7134_BOARD_VIDEOMATE_TV,
-        },{
+	},{
 		.vendor       = PCI_VENDOR_ID_PHILIPS,
 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
-                .subvendor    = 0x185b,
-                .subdevice    = 0xc100,
+		.subvendor    = 0x185b,
+		.subdevice    = 0xc100,
 		.driver_data  = SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUS,
-        },{
+	},{
 		.vendor       = PCI_VENDOR_ID_PHILIPS,
 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7130,
-                .subvendor    = PCI_VENDOR_ID_MATROX,
-                .subdevice    = 0x48d0,
+		.subvendor    = PCI_VENDOR_ID_MATROX,
+		.subdevice    = 0x48d0,
 		.driver_data  = SAA7134_BOARD_CRONOS_PLUS,
 	},{
 		.vendor       = PCI_VENDOR_ID_PHILIPS,
 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7134,
-                .subvendor    = 0x1461, /* Avermedia Technologies Inc */
-                .subdevice    = 0xa70b,
+		.subvendor    = 0x1461, /* Avermedia Technologies Inc */
+		.subdevice    = 0xa70b,
 		.driver_data  = SAA7134_BOARD_MD2819,
 	},{
 		.vendor       = PCI_VENDOR_ID_PHILIPS,
 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7130,
-                .subvendor    = 0x1461, /* Avermedia Technologies Inc */
-                .subdevice    = 0x2115,
+		.subvendor    = 0x1461, /* Avermedia Technologies Inc */
+		.subdevice    = 0x2115,
 		.driver_data  = SAA7134_BOARD_AVERMEDIA_STUDIO_305,
 	},{
 		.vendor       = PCI_VENDOR_ID_PHILIPS,
 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7130,
-                .subvendor    = 0x1461, /* Avermedia Technologies Inc */
-                .subdevice    = 0x2108,
+		.subvendor    = 0x1461, /* Avermedia Technologies Inc */
+		.subdevice    = 0x2108,
 		.driver_data  = SAA7134_BOARD_AVERMEDIA_305,
 	},{
 		.vendor       = PCI_VENDOR_ID_PHILIPS,
 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7130,
-                .subvendor    = 0x1461, /* Avermedia Technologies Inc */
-                .subdevice    = 0x10ff,
+		.subvendor    = 0x1461, /* Avermedia Technologies Inc */
+		.subdevice    = 0x10ff,
 		.driver_data  = SAA7134_BOARD_AVERMEDIA_DVD_EZMAKER,
-        },{
+	},{
 		/* AVerMedia CardBus */
 		.vendor       = PCI_VENDOR_ID_PHILIPS,
 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7134,
-                .subvendor    = 0x1461, /* Avermedia Technologies Inc */
-                .subdevice    = 0xd6ee,
+		.subvendor    = 0x1461, /* Avermedia Technologies Inc */
+		.subdevice    = 0xd6ee,
 		.driver_data  = SAA7134_BOARD_AVERMEDIA_CARDBUS,
 	},{
 		/* TransGear 3000TV */
 		.vendor       = PCI_VENDOR_ID_PHILIPS,
 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7130,
-                .subvendor    = 0x1461, /* Avermedia Technologies Inc */
-                .subdevice    = 0x050c,
+		.subvendor    = 0x1461, /* Avermedia Technologies Inc */
+		.subdevice    = 0x050c,
 		.driver_data  = SAA7134_BOARD_TG3000TV,
 	},{
-                .vendor       = PCI_VENDOR_ID_PHILIPS,
-                .device       = PCI_DEVICE_ID_PHILIPS_SAA7134,
-                .subvendor    = 0x11bd,
-                .subdevice    = 0x002b,
-                .driver_data  = SAA7134_BOARD_PINNACLE_PCTV_STEREO,
-        },{
-                .vendor       = PCI_VENDOR_ID_PHILIPS,
-                .device       = PCI_DEVICE_ID_PHILIPS_SAA7134,
-                .subvendor    = 0x11bd,
-                .subdevice    = 0x002d,
-                .driver_data  = SAA7134_BOARD_PINNACLE_300I_DVBT_PAL,
-        },{
-                .vendor       = PCI_VENDOR_ID_PHILIPS,
-                .device       = PCI_DEVICE_ID_PHILIPS_SAA7134,
-                .subvendor    = 0x1019,
-                .subdevice    = 0x4cb4,
-                .driver_data  = SAA7134_BOARD_ECS_TVP3XP,
-        },{
-                .vendor       = PCI_VENDOR_ID_PHILIPS,
-                .device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
-                .subvendor    = 0x1019,
-                .subdevice    = 0x4cb5,
-                .driver_data  = SAA7134_BOARD_ECS_TVP3XP_4CB5,
-        },{
-		.vendor       = PCI_VENDOR_ID_PHILIPS,
- 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
-                .subvendor    = 0x12ab,
-                .subdevice    = 0x0800,
- 		.driver_data  = SAA7133_BOARD_UPMOST_PURPLE_TV,
+		.vendor       = PCI_VENDOR_ID_PHILIPS,
+		.device       = PCI_DEVICE_ID_PHILIPS_SAA7134,
+		.subvendor    = 0x11bd,
+		.subdevice    = 0x002b,
+		.driver_data  = SAA7134_BOARD_PINNACLE_PCTV_STEREO,
+	},{
+		.vendor       = PCI_VENDOR_ID_PHILIPS,
+		.device       = PCI_DEVICE_ID_PHILIPS_SAA7134,
+		.subvendor    = 0x11bd,
+		.subdevice    = 0x002d,
+		.driver_data  = SAA7134_BOARD_PINNACLE_300I_DVBT_PAL,
+	},{
+		.vendor       = PCI_VENDOR_ID_PHILIPS,
+		.device       = PCI_DEVICE_ID_PHILIPS_SAA7134,
+		.subvendor    = 0x1019,
+		.subdevice    = 0x4cb4,
+		.driver_data  = SAA7134_BOARD_ECS_TVP3XP,
+	},{
+		.vendor       = PCI_VENDOR_ID_PHILIPS,
+		.device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
+		.subvendor    = 0x1019,
+		.subdevice    = 0x4cb5,
+		.driver_data  = SAA7134_BOARD_ECS_TVP3XP_4CB5,
+	},{
+		.vendor       = PCI_VENDOR_ID_PHILIPS,
+		.device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
+		.subvendor    = 0x12ab,
+		.subdevice    = 0x0800,
+		.driver_data  = SAA7134_BOARD_UPMOST_PURPLE_TV,
 	},{
 		.vendor       = PCI_VENDOR_ID_PHILIPS,
 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7130,
 		.subvendor    = 0x153B,
 		.subdevice    = 0x1152,
 		.driver_data  = SAA7134_BOARD_CINERGY200,
- 	},{
+	},{
 		.vendor       = PCI_VENDOR_ID_PHILIPS,
 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7130,
-                .subvendor    = 0x185b,
-                .subdevice    = 0xc100,
+		.subvendor    = 0x185b,
+		.subdevice    = 0xc100,
 		.driver_data  = SAA7134_BOARD_VIDEOMATE_TV_PVR,
- 	},{
+	},{
 		.vendor       = PCI_VENDOR_ID_PHILIPS,
 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7130,
-                .subvendor    = 0x1131,
-                .subdevice    = 0,
+		.subvendor    = 0x1131,
+		.subdevice    = 0,
 		.driver_data  = SAA7134_BOARD_SABRENT_SBTTVFM,
 	},{
 		.vendor       = PCI_VENDOR_ID_PHILIPS,
 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7134,
 		.subvendor    = 0x1461, /* Avermedia Technologies Inc */
 		.subdevice    = 0x9715,
+		.driver_data  = SAA7134_BOARD_AVERMEDIA_STUDIO_307,
+	},{
+		.vendor       = PCI_VENDOR_ID_PHILIPS,
+		.device       = PCI_DEVICE_ID_PHILIPS_SAA7134,
+		.subvendor    = 0x1461, /* Avermedia Technologies Inc */
+		.subdevice    = 0xa70a,
 		.driver_data  = SAA7134_BOARD_AVERMEDIA_307,
 	},{
 		.vendor       = PCI_VENDOR_ID_PHILIPS,
@@ -1831,31 +2294,70 @@ struct pci_device_id saa7134_pci_tbl[] =
 		.subvendor    = 0x185b,
 		.subdevice    = 0xc200,
 		.driver_data  = SAA7134_BOARD_VIDEOMATE_GOLD_PLUS,
-        },{
+	},{
 		.vendor       = PCI_VENDOR_ID_PHILIPS,
 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7134,
 		.subvendor    = 0x1540,
 		.subdevice    = 0x9524,
 		.driver_data  = SAA7134_BOARD_PROVIDEO_PV952,
 
- 	},{
+	},{
 		.vendor       = PCI_VENDOR_ID_PHILIPS,
 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
 		.subvendor    = 0x5168,
-		.subdevice    = 0x0306,
+		.subdevice    = 0x0502,                /* Cardbus version */
 		.driver_data  = SAA7134_BOARD_FLYDVBTDUO,
+	},{
+		.vendor       = PCI_VENDOR_ID_PHILIPS,
+		.device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
+		.subvendor    = 0x5168,
+		.subdevice    = 0x0306,                /* PCI version */
+		.driver_data  = SAA7134_BOARD_FLYDVBTDUO,
+	},{
+		.vendor       = PCI_VENDOR_ID_PHILIPS,
+		.device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
+		.subvendor    = 0x1461, /* Avermedia Technologies Inc */
+		.subdevice    = 0xf31f,
+		.driver_data  = SAA7134_BOARD_AVERMEDIA_GO_007_FM,
+
+	},{
+		.vendor       = PCI_VENDOR_ID_PHILIPS,
+		.device       = PCI_DEVICE_ID_PHILIPS_SAA7130,
+		.subvendor    = PCI_VENDOR_ID_PHILIPS,
+		.subdevice    = 0x2004,
+		.driver_data  = SAA7134_BOARD_PHILIPS_TOUGH,
+	},{
+		.vendor       = PCI_VENDOR_ID_PHILIPS,
+		.device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
+		.subvendor    = 0x1421,
+		.subdevice    = 0x0350,		/* PCI version */
+		.driver_data  = SAA7134_BOARD_ADS_INSTANT_TV,
+
+	},{
+		.vendor       = PCI_VENDOR_ID_PHILIPS,
+		.device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
+		.subvendor    = 0x1421,
+		.subdevice    = 0x0370,		/* cardbus version */
+		.driver_data  = SAA7134_BOARD_ADS_INSTANT_TV,
+
+	},{     /* Typhoon DVB-T Duo Digital/Analog Cardbus */
+		.vendor       = PCI_VENDOR_ID_PHILIPS,
+		.device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
+		.subvendor    = 0x4e42,
+		.subdevice    = 0x0502,
+		.driver_data  = SAA7134_BOARD_THYPHOON_DVBT_DUO_CARDBUS,
 
- 	},{
+	},{
 		/* --- boards without eeprom + subsystem ID --- */
-                .vendor       = PCI_VENDOR_ID_PHILIPS,
-                .device       = PCI_DEVICE_ID_PHILIPS_SAA7134,
-                .subvendor    = PCI_VENDOR_ID_PHILIPS,
+		.vendor       = PCI_VENDOR_ID_PHILIPS,
+		.device       = PCI_DEVICE_ID_PHILIPS_SAA7134,
+		.subvendor    = PCI_VENDOR_ID_PHILIPS,
 		.subdevice    = 0,
 		.driver_data  = SAA7134_BOARD_NOAUTO,
-        },{
-                .vendor       = PCI_VENDOR_ID_PHILIPS,
-                .device       = PCI_DEVICE_ID_PHILIPS_SAA7130,
-                .subvendor    = PCI_VENDOR_ID_PHILIPS,
+	},{
+		.vendor       = PCI_VENDOR_ID_PHILIPS,
+		.device       = PCI_DEVICE_ID_PHILIPS_SAA7130,
+		.subvendor    = PCI_VENDOR_ID_PHILIPS,
 		.subdevice    = 0,
 		.driver_data  = SAA7134_BOARD_NOAUTO,
 	},{
@@ -1863,26 +2365,26 @@ struct pci_device_id saa7134_pci_tbl[] =
 		/* --- default catch --- */
 		.vendor       = PCI_VENDOR_ID_PHILIPS,
 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7130,
-                .subvendor    = PCI_ANY_ID,
-                .subdevice    = PCI_ANY_ID,
+		.subvendor    = PCI_ANY_ID,
+		.subdevice    = PCI_ANY_ID,
 		.driver_data  = SAA7134_BOARD_UNKNOWN,
-        },{
+	},{
 		.vendor       = PCI_VENDOR_ID_PHILIPS,
 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
-                .subvendor    = PCI_ANY_ID,
-                .subdevice    = PCI_ANY_ID,
+		.subvendor    = PCI_ANY_ID,
+		.subdevice    = PCI_ANY_ID,
 		.driver_data  = SAA7134_BOARD_UNKNOWN,
-        },{
+	},{
 		.vendor       = PCI_VENDOR_ID_PHILIPS,
 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7134,
-                .subvendor    = PCI_ANY_ID,
-                .subdevice    = PCI_ANY_ID,
+		.subvendor    = PCI_ANY_ID,
+		.subdevice    = PCI_ANY_ID,
 		.driver_data  = SAA7134_BOARD_UNKNOWN,
-        },{
+	},{
 		.vendor       = PCI_VENDOR_ID_PHILIPS,
 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7135,
-                .subvendor    = PCI_ANY_ID,
-                .subdevice    = PCI_ANY_ID,
+		.subvendor    = PCI_ANY_ID,
+		.subdevice    = PCI_ANY_ID,
 		.driver_data  = SAA7134_BOARD_UNKNOWN,
 	},{
 		/* --- end of list --- */
@@ -1893,46 +2395,9 @@ MODULE_DEVICE_TABLE(pci, saa7134_pci_tbl
 /* ----------------------------------------------------------- */
 /* flyvideo tweaks                                             */
 
-#if 0
-static struct {
-	char  *model;
-	int   tuner_type;
-} fly_list[0x20] = {
-	/* default catch ... */
-	[ 0 ... 0x1f ] = {
-		.model      = "UNKNOWN",
-		.tuner_type = TUNER_ABSENT,
-	},
-	/* ... the ones known so far */
-	[ 0x05 ] = {
-		.model      = "PAL-BG",
-		.tuner_type = TUNER_LG_PAL_NEW_TAPC,
-	},
-	[ 0x10 ] = {
-		.model      = "PAL-BG / PAL-DK",
-		.tuner_type = TUNER_PHILIPS_PAL,
-	},
-	[ 0x15 ] = {
-		.model      = "NTSC",
-		.tuner_type = TUNER_ABSENT /* FIXME */,
-	},
-};
-#endif
 
 static void board_flyvideo(struct saa7134_dev *dev)
 {
-#if 0
-	/* non-working attempt to detect the correct tuner type ... */
-	u32 value;
-	int index;
-
-	value = dev->gpio_value;
-	index = (value & 0x1f00) >> 8;
-	printk(KERN_INFO "%s: flyvideo: gpio is 0x%x [model=%s,tuner=%d]\n",
-	       dev->name, value, fly_list[index].model,
-	       fly_list[index].tuner_type);
-	dev->tuner_type = fly_list[index].tuner_type;
-#endif
 	printk("%s: there are different flyvideo cards with different tuners\n"
 	       "%s: out there, you might have to use the tuner=<nr> insmod\n"
 	       "%s: option to override the default value.\n",
@@ -1943,7 +2408,7 @@ static void board_flyvideo(struct saa713
 
 int saa7134_board_init1(struct saa7134_dev *dev)
 {
-	// Always print gpio, often manufacturers encode tuner type and other info.
+	/* Always print gpio, often manufacturers encode tuner type and other info. */
 	saa_writel(SAA7134_GPIO_GPMODE0 >> 2, 0);
 	dev->gpio_value = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2);
 	printk(KERN_INFO "%s: board init: gpio is %x\n", dev->name, dev->gpio_value);
@@ -1961,21 +2426,26 @@ int saa7134_board_init1(struct saa7134_d
 	case SAA7134_BOARD_ECS_TVP3XP:
 	case SAA7134_BOARD_ECS_TVP3XP_4CB5:
 	case SAA7134_BOARD_MD2819:
+	case SAA7134_BOARD_KWORLD_VSTREAM_XPERT:
+	case SAA7134_BOARD_KWORLD_XPERT:
 	case SAA7134_BOARD_AVERMEDIA_STUDIO_305:
 	case SAA7134_BOARD_AVERMEDIA_305:
+	case SAA7134_BOARD_AVERMEDIA_STUDIO_307:
 	case SAA7134_BOARD_AVERMEDIA_307:
-//	case SAA7134_BOARD_SABRENT_SBTTVFM:  /* not finished yet */
+	case SAA7134_BOARD_AVERMEDIA_GO_007_FM:
+/*      case SAA7134_BOARD_SABRENT_SBTTVFM:  */ /* not finished yet */
 	case SAA7134_BOARD_VIDEOMATE_TV_PVR:
-		dev->has_remote = 1;
-		break;
+	case SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII:
+	case SAA7134_BOARD_MANLI_MTV001:
+	case SAA7134_BOARD_MANLI_MTV002:
 	case SAA7134_BOARD_AVACSSMARTTV:
 		dev->has_remote = 1;
 		break;
 	case SAA7134_BOARD_MD5044:
 		printk("%s: seems there are two different versions of the MD5044\n"
-		       "%s: (with the same ID) out there.  If sound doesn't work for\n"
-		       "%s: you try the audio_clock_override=0x200000 insmod option.\n",
-		       dev->name,dev->name,dev->name);
+		"%s: (with the same ID) out there.  If sound doesn't work for\n"
+		"%s: you try the audio_clock_override=0x200000 insmod option.\n",
+		dev->name,dev->name,dev->name);
 		break;
 	case SAA7134_BOARD_CINERGY400_CARDBUS:
 		/* power-up tuner chip */
@@ -1983,11 +2453,19 @@ int saa7134_board_init1(struct saa7134_d
 		saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x00040000, 0x00000000);
 		msleep(1);
 		break;
+	case SAA7134_BOARD_FLYDVBTDUO:
+	case SAA7134_BOARD_THYPHOON_DVBT_DUO_CARDBUS:
+	/* turn the fan on Hac: static for the time being */
+		saa_writeb(SAA7134_GPIO_GPMODE3, 0x08);
+		saa_writeb(SAA7134_GPIO_GPSTATUS3, 0x06);
+		break;
+	case SAA7134_BOARD_AVERMEDIA_CARDBUS:
+		/* power-up tuner chip */
+		saa_andorl(SAA7134_GPIO_GPMODE0 >> 2,   0xffffffff, 0xffffffff);
+		saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0xffffffff, 0xffffffff);
+		msleep(1);
+		break;
 	}
-	if (dev->has_remote)
-		dev->irq2_mask |= (SAA7134_IRQ2_INTE_GPIO18  |
-				   SAA7134_IRQ2_INTE_GPIO18A |
-				   SAA7134_IRQ2_INTE_GPIO16  );
 	return 0;
 }
 
@@ -2008,10 +2486,85 @@ int saa7134_board_init2(struct saa7134_d
 			break;
 		dev->board = board;
 		printk("%s: board type fixup: %s\n", dev->name,
-		       saa7134_boards[dev->board].name);
+		saa7134_boards[dev->board].name);
 		dev->tuner_type = saa7134_boards[dev->board].tuner_type;
-		if (TUNER_ABSENT != dev->tuner_type)
-			saa7134_i2c_call_clients(dev,TUNER_SET_TYPE,&dev->tuner_type);
+
+		if (TUNER_ABSENT != dev->tuner_type) {
+				struct tuner_setup tun_setup;
+
+				tun_setup.mode_mask = T_RADIO | T_ANALOG_TV | T_DIGITAL_TV;
+				tun_setup.type = dev->tuner_type;
+				tun_setup.addr = ADDR_UNSET;
+
+				saa7134_i2c_call_clients (dev, TUNER_SET_TYPE_ADDR, &tun_setup);
+		}
+		break;
+case SAA7134_BOARD_MD7134:
+		{
+		struct tuner_setup tun_setup;
+		u8 subaddr;
+		u8 data[3];
+		int ret, tuner_t;
+
+		struct i2c_msg msg[] = {{.addr=0x50, .flags=0, .buf=&subaddr, .len = 1},
+					{.addr=0x50, .flags=I2C_M_RD, .buf=data, .len = 3}};
+		subaddr= 0x14;
+		tuner_t = 0;
+		ret = i2c_transfer(&dev->i2c_adap, msg, 2);
+		if (ret != 2) {
+			printk(KERN_ERR "EEPROM read failure\n");
+		} else if ((data[0] != 0) && (data[0] != 0xff)) {
+			/* old config structure */
+			subaddr = data[0] + 2;
+			msg[1].len = 2;
+			i2c_transfer(&dev->i2c_adap, msg, 2);
+			tuner_t = (data[0] << 8) + data[1];
+			switch (tuner_t){
+			case 0x0103:
+				dev->tuner_type = TUNER_PHILIPS_PAL;
+				break;
+			case 0x010C:
+				dev->tuner_type = TUNER_PHILIPS_FM1216ME_MK3;
+				break;
+			default:
+				printk(KERN_ERR "%s Cant determine tuner type %x from EEPROM\n", dev->name, tuner_t);
+			}
+		} else if ((data[1] != 0) && (data[1] != 0xff)) {
+			/* new config structure */
+			subaddr = data[1] + 1;
+			msg[1].len = 1;
+			i2c_transfer(&dev->i2c_adap, msg, 2);
+			subaddr = data[0] + 1;
+			msg[1].len = 2;
+			i2c_transfer(&dev->i2c_adap, msg, 2);
+			tuner_t = (data[1] << 8) + data[0];
+			switch (tuner_t) {
+			case 0x0005:
+				dev->tuner_type = TUNER_PHILIPS_FM1216ME_MK3;
+				break;
+			case 0x001d:
+				dev->tuner_type = TUNER_PHILIPS_FMD1216ME_MK3;
+					printk(KERN_INFO "%s Board has DVB-T\n", dev->name);
+				break;
+			default:
+				printk(KERN_ERR "%s Cant determine tuner type %x from EEPROM\n", dev->name, tuner_t);
+			}
+		} else {
+			printk(KERN_ERR "%s unexpected config structure\n", dev->name);
+		}
+
+		printk(KERN_INFO "%s Tuner type is %d\n", dev->name, dev->tuner_type);
+		if (dev->tuner_type == TUNER_PHILIPS_FMD1216ME_MK3) {
+			dev->tda9887_conf = TDA9887_PRESENT | TDA9887_PORT1_ACTIVE | TDA9887_PORT2_ACTIVE;
+			saa7134_i2c_call_clients(dev,TDA9887_SET_CONFIG, &dev->tda9887_conf);
+		}
+
+		tun_setup.mode_mask = T_RADIO | T_ANALOG_TV | T_DIGITAL_TV;
+		tun_setup.type = dev->tuner_type;
+		tun_setup.addr = ADDR_UNSET;
+
+		saa7134_i2c_call_clients (dev, TUNER_SET_TYPE_ADDR,&tun_setup);
+		}
 		break;
 	}
 	return 0;
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c
--- a/drivers/media/video/saa7134/saa7134-core.c
+++ b/drivers/media/video/saa7134/saa7134-core.c
@@ -1,5 +1,5 @@
 /*
- * $Id: saa7134-core.c,v 1.28 2005/02/22 09:56:29 kraxel Exp $
+ * $Id: saa7134-core.c,v 1.39 2005/07/05 17:37:35 nsh Exp $
  *
  * device driver for philips saa7134 based TV cards
  * driver core
@@ -183,46 +183,6 @@ void saa7134_track_gpio(struct saa7134_d
 
 /* ------------------------------------------------------------------ */
 
-#if 0
-static char *dec1_bits[8] = {
-	"DCSTD0", "DCSCT1", "WIPA", "GLIMB",
-	"GLIMT", "SLTCA", "HLCK"
-};
-static char *dec2_bits[8] = {
-	"RDCAP", "COPRO", "COLSTR", "TYPE3",
-	NULL, "FIDT", "HLVLN", "INTL"
-};
-static char *scale1_bits[8] = {
-	"VID_A", "VBI_A", NULL, NULL, "VID_B", "VBI_B"
-};
-static char *scale2_bits[8] = {
-	"TRERR", "CFERR", "LDERR", "WASRST",
-	"FIDSCI", "FIDSCO", "D6^D5", "TASK"
-};
-
-static void dump_statusreg(struct saa7134_dev *dev, int reg,
-			   char *regname, char **bits)
-{
-	int value,i;
-
-	value = saa_readb(reg);
-	printk(KERN_DEBUG "%s: %s:", dev->name, regname);
-	for (i = 7; i >= 0; i--) {
-		if (NULL == bits[i])
-			continue;
-		printk(" %s=%d", bits[i], (value & (1 << i)) ? 1 : 0);
-	}
-	printk("\n");
-}
-
-static void dump_statusregs(struct saa7134_dev *dev)
-{
-	dump_statusreg(dev,SAA7134_STATUS_VIDEO1,"dec1",dec1_bits);
-	dump_statusreg(dev,SAA7134_STATUS_VIDEO2,"dec2",dec2_bits);
-	dump_statusreg(dev,SAA7134_SCALER_STATUS0,"scale0",scale1_bits);
-	dump_statusreg(dev,SAA7134_SCALER_STATUS1,"scale1",scale2_bits);
-}
-#endif
 
 /* ----------------------------------------------------------- */
 /* delayed request_module                                      */
@@ -316,7 +276,7 @@ unsigned long saa7134_buffer_base(struct
 
 int saa7134_pgtable_alloc(struct pci_dev *pci, struct saa7134_pgtable *pt)
 {
-        u32          *cpu;
+        __le32       *cpu;
         dma_addr_t   dma_addr;
 
 	cpu = pci_alloc_consistent(pci, SAA7134_PGTABLE_SIZE, &dma_addr);
@@ -332,7 +292,7 @@ int saa7134_pgtable_build(struct pci_dev
 			  struct scatterlist *list, unsigned int length,
 			  unsigned int startpage)
 {
-	u32           *ptr;
+	__le32        *ptr;
 	unsigned int  i,p;
 
 	BUG_ON(NULL == pt || NULL == pt->cpu);
@@ -340,7 +300,7 @@ int saa7134_pgtable_build(struct pci_dev
 	ptr = pt->cpu + startpage;
 	for (i = 0; i < length; i++, list++)
 		for (p = 0; p * 4096 < list->length; p++, ptr++)
-			*ptr = sg_dma_address(list) - list->offset;
+			*ptr = cpu_to_le32(sg_dma_address(list) - list->offset);
 	return 0;
 }
 
@@ -616,10 +576,6 @@ static irqreturn_t saa7134_irq(int irq, 
 		if (irq_debug)
 			print_irqstatus(dev,loop,report,status);
 
-#if 0
-		if (report & SAA7134_IRQ_REPORT_CONF_ERR)
-			dump_statusregs(dev);
-#endif
 
 		if (report & SAA7134_IRQ_REPORT_RDCAP /* _INTL */)
 			saa7134_irq_video_intl(dev);
@@ -711,7 +667,6 @@ static int saa7134_hwinit1(struct saa713
 		   SAA7134_MAIN_CTRL_EVFE1 |
 		   SAA7134_MAIN_CTRL_EVFE2 |
 		   SAA7134_MAIN_CTRL_ESFE  |
-		   SAA7134_MAIN_CTRL_EBADC |
 		   SAA7134_MAIN_CTRL_EBDAC);
 
 	/* enable peripheral devices */
@@ -726,14 +681,28 @@ static int saa7134_hwinit1(struct saa713
 /* late init (with i2c + irq) */
 static int saa7134_hwinit2(struct saa7134_dev *dev)
 {
+	unsigned int irq2_mask;
 	dprintk("hwinit2\n");
 
 	saa7134_video_init2(dev);
 	saa7134_tvaudio_init2(dev);
 
 	/* enable IRQ's */
+   	irq2_mask =
+		SAA7134_IRQ2_INTE_DEC3    |
+		SAA7134_IRQ2_INTE_DEC2    |
+		SAA7134_IRQ2_INTE_DEC1    |
+		SAA7134_IRQ2_INTE_DEC0    |
+		SAA7134_IRQ2_INTE_PE      |
+		SAA7134_IRQ2_INTE_AR;
+
+	if (dev->has_remote)
+		irq2_mask |= (SAA7134_IRQ2_INTE_GPIO18  |
+			      SAA7134_IRQ2_INTE_GPIO18A |
+			      SAA7134_IRQ2_INTE_GPIO16  );
+
 	saa_writel(SAA7134_IRQ1, 0);
-	saa_writel(SAA7134_IRQ2, dev->irq2_mask);
+	saa_writel(SAA7134_IRQ2, irq2_mask);
 
 	return 0;
 }
@@ -954,13 +923,6 @@ static int __devinit saa7134_initdev(str
 	}
 
 	/* initialize hardware #1 */
-   	dev->irq2_mask =
-		SAA7134_IRQ2_INTE_DEC3    |
-		SAA7134_IRQ2_INTE_DEC2    |
-		SAA7134_IRQ2_INTE_DEC1    |
-		SAA7134_IRQ2_INTE_DEC0    |
-		SAA7134_IRQ2_INTE_PE      |
-		SAA7134_IRQ2_INTE_AR;
 	saa7134_board_init1(dev);
 	saa7134_hwinit1(dev);
 
@@ -990,6 +952,7 @@ static int __devinit saa7134_initdev(str
 		request_module("saa6752hs");
 		request_module_depend("saa7134-empress",&need_empress);
 	}
+
   	if (card_is_dvb(dev))
 		request_module_depend("saa7134-dvb",&need_dvb);
 
@@ -1144,9 +1107,6 @@ static void __devexit saa7134_finidev(st
 	release_mem_region(pci_resource_start(pci_dev,0),
 			   pci_resource_len(pci_dev,0));
 
-#if 0  /* causes some trouble when reinserting the driver ... */
-	pci_disable_device(pci_dev);
-#endif
 	pci_set_drvdata(pci_dev, NULL);
 
 	/* free memory */
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c
--- a/drivers/media/video/saa7134/saa7134-dvb.c
+++ b/drivers/media/video/saa7134/saa7134-dvb.c
@@ -1,8 +1,11 @@
 /*
- * $Id: saa7134-dvb.c,v 1.12 2005/02/18 12:28:29 kraxel Exp $
+ * $Id: saa7134-dvb.c,v 1.23 2005/07/24 22:12:47 mkrufky Exp $
  *
  * (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
  *
+ *  Extended 3 / 2005 by Hartmut Hackmann to support various
+ *  cards with the tda10046 DVB-T channel decoder
+ *
  *  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
@@ -26,24 +29,31 @@
 #include <linux/delay.h>
 #include <linux/kthread.h>
 #include <linux/suspend.h>
+#include <linux/config.h>
+
 
 #include "saa7134-reg.h"
 #include "saa7134.h"
 
-#include "dvb-pll.h"
-#include "mt352.h"
-#include "mt352_priv.h" /* FIXME */
-#include "tda1004x.h"
+#ifdef HAVE_MT352
+# include "mt352.h"
+# include "mt352_priv.h" /* FIXME */
+#endif
+#ifdef HAVE_TDA1004X
+# include "tda1004x.h"
+#endif
 
 MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
 MODULE_LICENSE("GPL");
 
 static unsigned int antenna_pwr = 0;
+
 module_param(antenna_pwr, int, 0444);
 MODULE_PARM_DESC(antenna_pwr,"enable antenna power (Pinnacle 300i)");
 
 /* ------------------------------------------------------------------ */
 
+#ifdef HAVE_MT352
 static int pinnacle_antenna_pwr(struct saa7134_dev *dev, int on)
 {
 	u32 ok;
@@ -138,48 +148,388 @@ static struct mt352_config pinnacle_300i
 	.demod_init    = mt352_pinnacle_init,
 	.pll_set       = mt352_pinnacle_pll_set,
 };
+#endif
 
 /* ------------------------------------------------------------------ */
 
-static int medion_cardbus_init(struct dvb_frontend* fe)
+#ifdef HAVE_TDA1004X
+static int philips_tu1216_pll_init(struct dvb_frontend *fe)
 {
-	/* anything to do here ??? */
+	struct saa7134_dev *dev = fe->dvb->priv;
+	static u8 tu1216_init[] = { 0x0b, 0xf5, 0x85, 0xab };
+	struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tu1216_init,.len = sizeof(tu1216_init) };
+
+	/* setup PLL configuration */
+	if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1)
+		return -EIO;
+	msleep(1);
+
 	return 0;
 }
 
-static int medion_cardbus_pll_set(struct dvb_frontend* fe,
-				  struct dvb_frontend_parameters* params)
+static int philips_tu1216_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
 {
 	struct saa7134_dev *dev = fe->dvb->priv;
-	struct v4l2_frequency f;
+	u8 tuner_buf[4];
+	struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tuner_buf,.len =
+			sizeof(tuner_buf) };
+	int tuner_frequency = 0;
+	u8 band, cp, filter;
+
+	/* determine charge pump */
+	tuner_frequency = params->frequency + 36166000;
+	if (tuner_frequency < 87000000)
+		return -EINVAL;
+	else if (tuner_frequency < 130000000)
+		cp = 3;
+	else if (tuner_frequency < 160000000)
+		cp = 5;
+	else if (tuner_frequency < 200000000)
+		cp = 6;
+	else if (tuner_frequency < 290000000)
+		cp = 3;
+	else if (tuner_frequency < 420000000)
+		cp = 5;
+	else if (tuner_frequency < 480000000)
+		cp = 6;
+	else if (tuner_frequency < 620000000)
+		cp = 3;
+	else if (tuner_frequency < 830000000)
+		cp = 5;
+	else if (tuner_frequency < 895000000)
+		cp = 7;
+	else
+		return -EINVAL;
+
+	/* determine band */
+	if (params->frequency < 49000000)
+		return -EINVAL;
+	else if (params->frequency < 161000000)
+		band = 1;
+	else if (params->frequency < 444000000)
+		band = 2;
+	else if (params->frequency < 861000000)
+		band = 4;
+	else
+		return -EINVAL;
+
+	/* setup PLL filter */
+	switch (params->u.ofdm.bandwidth) {
+	case BANDWIDTH_6_MHZ:
+		filter = 0;
+		break;
 
-	/*
-	 * this instructs tuner.o to set the frequency, the call will
-	 * end up in tuner_command(), VIDIOC_S_FREQUENCY switch.
-	 * tda9887.o will see that as well.
+	case BANDWIDTH_7_MHZ:
+		filter = 0;
+		break;
+
+	case BANDWIDTH_8_MHZ:
+		filter = 1;
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	/* calculate divisor
+	 * ((36166000+((1000000/6)/2)) + Finput)/(1000000/6)
 	 */
-	f.tuner     = 0;
-	f.type      = V4L2_TUNER_DIGITAL_TV;
-	f.frequency = params->frequency / 1000 * 16 / 1000;
-	saa7134_i2c_call_clients(dev,VIDIOC_S_FREQUENCY,&f);
+	tuner_frequency = (((params->frequency / 1000) * 6) + 217496) / 1000;
+
+	/* setup tuner buffer */
+	tuner_buf[0] = (tuner_frequency >> 8) & 0x7f;
+	tuner_buf[1] = tuner_frequency & 0xff;
+	tuner_buf[2] = 0xca;
+	tuner_buf[3] = (cp << 5) | (filter << 3) | band;
+
+	if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1)
+		return -EIO;
+
+	msleep(1);
 	return 0;
 }
 
-static int fe_request_firmware(struct dvb_frontend* fe,
-			       const struct firmware **fw, char* name)
+static int philips_tu1216_request_firmware(struct dvb_frontend *fe,
+					   const struct firmware **fw, char *name)
 {
 	struct saa7134_dev *dev = fe->dvb->priv;
 	return request_firmware(fw, name, &dev->pci->dev);
 }
 
+static struct tda1004x_config philips_tu1216_config = {
+
+	.demod_address = 0x8,
+	.invert        = 1,
+	.invert_oclk   = 1,
+	.xtal_freq     = TDA10046_XTAL_4M,
+	.agc_config    = TDA10046_AGC_DEFAULT,
+	.if_freq       = TDA10046_FREQ_3617,
+	.pll_init      = philips_tu1216_pll_init,
+	.pll_set       = philips_tu1216_pll_set,
+	.pll_sleep     = NULL,
+	.request_firmware = philips_tu1216_request_firmware,
+};
+
+/* ------------------------------------------------------------------ */
+
+
+static int philips_fmd1216_pll_init(struct dvb_frontend *fe)
+{
+	struct saa7134_dev *dev = fe->dvb->priv;
+	/* this message is to set up ATC and ALC */
+	static u8 fmd1216_init[] = { 0x0b, 0xdc, 0x9c, 0xa0 };
+	struct i2c_msg tuner_msg = {.addr = 0x61,.flags = 0,.buf = fmd1216_init,.len = sizeof(fmd1216_init) };
+
+	if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1)
+		return -EIO;
+	msleep(1);
+
+	return 0;
+}
+
+static void philips_fmd1216_analog(struct dvb_frontend *fe)
+{
+	struct saa7134_dev *dev = fe->dvb->priv;
+	/* this message actually turns the tuner back to analog mode */
+	static u8 fmd1216_init[] = { 0x0b, 0xdc, 0x9c, 0x60 };
+	struct i2c_msg tuner_msg = {.addr = 0x61,.flags = 0,.buf = fmd1216_init,.len = sizeof(fmd1216_init) };
+
+	i2c_transfer(&dev->i2c_adap, &tuner_msg, 1);
+	msleep(1);
+	fmd1216_init[2] = 0x86;
+	fmd1216_init[3] = 0x54;
+	i2c_transfer(&dev->i2c_adap, &tuner_msg, 1);
+	msleep(1);
+}
+
+static int philips_fmd1216_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
+{
+	struct saa7134_dev *dev = fe->dvb->priv;
+	u8 tuner_buf[4];
+	struct i2c_msg tuner_msg = {.addr = 0x61,.flags = 0,.buf = tuner_buf,.len =
+			sizeof(tuner_buf) };
+	int tuner_frequency = 0;
+	int divider = 0;
+	u8 band, mode, cp;
+
+	/* determine charge pump */
+	tuner_frequency = params->frequency + 36130000;
+	if (tuner_frequency < 87000000)
+		return -EINVAL;
+	/* low band */
+	else if (tuner_frequency < 180000000) {
+		band = 1;
+		mode = 7;
+		cp   = 0;
+	} else if (tuner_frequency < 195000000) {
+		band = 1;
+		mode = 6;
+		cp   = 1;
+	/* mid band	*/
+	} else if (tuner_frequency < 366000000) {
+		if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ) {
+			band = 10;
+		} else {
+			band = 2;
+		}
+		mode = 7;
+		cp   = 0;
+	} else if (tuner_frequency < 478000000) {
+		if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ) {
+			band = 10;
+		} else {
+			band = 2;
+		}
+		mode = 6;
+		cp   = 1;
+	/* high band */
+	} else if (tuner_frequency < 662000000) {
+		if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ) {
+			band = 12;
+		} else {
+			band = 4;
+		}
+		mode = 7;
+		cp   = 0;
+	} else if (tuner_frequency < 840000000) {
+		if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ) {
+			band = 12;
+		} else {
+			band = 4;
+		}
+		mode = 6;
+		cp   = 1;
+	} else {
+		if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ) {
+			band = 12;
+		} else {
+			band = 4;
+		}
+		mode = 7;
+		cp   = 1;
+
+	}
+	/* calculate divisor */
+	/* ((36166000 + Finput) / 166666) rounded! */
+	divider = (tuner_frequency + 83333) / 166667;
+
+	/* setup tuner buffer */
+	tuner_buf[0] = (divider >> 8) & 0x7f;
+	tuner_buf[1] = divider & 0xff;
+	tuner_buf[2] = 0x80 | (cp << 6) | (mode  << 3) | 4;
+	tuner_buf[3] = 0x40 | band;
+
+	if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1)
+		return -EIO;
+	return 0;
+}
+
+#ifdef HAVE_TDA1004X
 static struct tda1004x_config medion_cardbus = {
-	.demod_address = 0x08,  /* not sure this is correct */
-	.invert        = 0,
-        .invert_oclk   = 0,
-        .pll_init      = medion_cardbus_init,
-        .pll_set       = medion_cardbus_pll_set,
-        .request_firmware = fe_request_firmware,
+	.demod_address = 0x08,
+	.invert        = 1,
+	.invert_oclk   = 0,
+	.xtal_freq     = TDA10046_XTAL_16M,
+	.agc_config    = TDA10046_AGC_IFO_AUTO_NEG,
+	.if_freq       = TDA10046_FREQ_3613,
+	.pll_init      = philips_fmd1216_pll_init,
+	.pll_set       = philips_fmd1216_pll_set,
+	.pll_sleep	   = philips_fmd1216_analog,
+	.request_firmware = NULL,
 };
+#endif
+
+/* ------------------------------------------------------------------ */
+
+struct tda827x_data {
+	u32 lomax;
+	u8  spd;
+	u8  bs;
+	u8  bp;
+	u8  cp;
+	u8  gc3;
+	u8 div1p5;
+};
+
+static struct tda827x_data tda827x_dvbt[] = {
+	{ .lomax =  62000000, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 1},
+	{ .lomax =  66000000, .spd = 3, .bs = 3, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 1},
+	{ .lomax =  76000000, .spd = 3, .bs = 1, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 0},
+	{ .lomax =  84000000, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 0},
+	{ .lomax =  93000000, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 1, .div1p5 = 0},
+	{ .lomax =  98000000, .spd = 3, .bs = 3, .bp = 0, .cp = 0, .gc3 = 1, .div1p5 = 0},
+	{ .lomax = 109000000, .spd = 3, .bs = 3, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0},
+	{ .lomax = 123000000, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 1},
+	{ .lomax = 133000000, .spd = 2, .bs = 3, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 1},
+	{ .lomax = 151000000, .spd = 2, .bs = 1, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0},
+	{ .lomax = 154000000, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0},
+	{ .lomax = 181000000, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 0, .div1p5 = 0},
+	{ .lomax = 185000000, .spd = 2, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0},
+	{ .lomax = 217000000, .spd = 2, .bs = 3, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0},
+	{ .lomax = 244000000, .spd = 1, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 1},
+	{ .lomax = 265000000, .spd = 1, .bs = 3, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 1},
+	{ .lomax = 302000000, .spd = 1, .bs = 1, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0},
+	{ .lomax = 324000000, .spd = 1, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0},
+	{ .lomax = 370000000, .spd = 1, .bs = 2, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0},
+	{ .lomax = 454000000, .spd = 1, .bs = 3, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0},
+	{ .lomax = 493000000, .spd = 0, .bs = 2, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 1},
+	{ .lomax = 530000000, .spd = 0, .bs = 3, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 1},
+	{ .lomax = 554000000, .spd = 0, .bs = 1, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0},
+	{ .lomax = 604000000, .spd = 0, .bs = 1, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0},
+	{ .lomax = 696000000, .spd = 0, .bs = 2, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0},
+	{ .lomax = 740000000, .spd = 0, .bs = 2, .bp = 4, .cp = 1, .gc3 = 0, .div1p5 = 0},
+	{ .lomax = 820000000, .spd = 0, .bs = 3, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0},
+	{ .lomax = 865000000, .spd = 0, .bs = 3, .bp = 4, .cp = 1, .gc3 = 0, .div1p5 = 0},
+	{ .lomax =         0, .spd = 0, .bs = 0, .bp = 0, .cp = 0, .gc3 = 0, .div1p5 = 0}
+};
+
+static int philips_tda827x_pll_init(struct dvb_frontend *fe)
+{
+	return 0;
+}
+
+static int philips_tda827x_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
+{
+	struct saa7134_dev *dev = fe->dvb->priv;
+	u8 tuner_buf[14];
+
+	struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tuner_buf,
+		                        .len = sizeof(tuner_buf) };
+	int i, tuner_freq, if_freq;
+	u32 N;
+	switch (params->u.ofdm.bandwidth) {
+	case BANDWIDTH_6_MHZ:
+		if_freq = 4000000;
+		break;
+	case BANDWIDTH_7_MHZ:
+		if_freq = 4500000;
+		break;
+	default:		   /* 8 MHz or Auto */
+		if_freq = 5000000;
+		break;
+	}
+	tuner_freq = params->frequency + if_freq;
+
+	i = 0;
+	while (tda827x_dvbt[i].lomax < tuner_freq) {
+		if(tda827x_dvbt[i + 1].lomax == 0)
+			break;
+		i++;
+	}
+
+	N = ((tuner_freq + 125000) / 250000) << (tda827x_dvbt[i].spd + 2);
+	tuner_buf[0] = 0;
+	tuner_buf[1] = (N>>8) | 0x40;
+	tuner_buf[2] = N & 0xff;
+	tuner_buf[3] = 0;
+	tuner_buf[4] = 0x52;
+	tuner_buf[5] = (tda827x_dvbt[i].spd << 6) + (tda827x_dvbt[i].div1p5 << 5) +
+				   (tda827x_dvbt[i].bs << 3) + tda827x_dvbt[i].bp;
+	tuner_buf[6] = (tda827x_dvbt[i].gc3 << 4) + 0x8f;
+	tuner_buf[7] = 0xbf;
+	tuner_buf[8] = 0x2a;
+	tuner_buf[9] = 0x05;
+	tuner_buf[10] = 0xff;
+	tuner_buf[11] = 0x00;
+	tuner_buf[12] = 0x00;
+	tuner_buf[13] = 0x40;
+
+	tuner_msg.len = 14;
+	if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1)
+		return -EIO;
+
+	msleep(500);
+	/* correct CP value */
+	tuner_buf[0] = 0x30;
+	tuner_buf[1] = 0x50 + tda827x_dvbt[i].cp;
+	tuner_msg.len = 2;
+	i2c_transfer(&dev->i2c_adap, &tuner_msg, 1);
+
+	return 0;
+}
+
+static void philips_tda827x_pll_sleep(struct dvb_frontend *fe)
+{
+	struct saa7134_dev *dev = fe->dvb->priv;
+	static u8 tda827x_sleep[] = { 0x30, 0xd0};
+	struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tda827x_sleep,
+	                            .len = sizeof(tda827x_sleep) };
+	i2c_transfer(&dev->i2c_adap, &tuner_msg, 1);
+}
+
+static struct tda1004x_config tda827x_lifeview_config = {
+	.demod_address = 0x08,
+	.invert        = 1,
+	.invert_oclk   = 0,
+	.xtal_freq     = TDA10046_XTAL_16M,
+	.agc_config    = TDA10046_AGC_TDA827X,
+	.if_freq       = TDA10046_FREQ_045,
+	.pll_init      = philips_tda827x_pll_init,
+	.pll_set       = philips_tda827x_pll_set,
+	.pll_sleep	   = philips_tda827x_pll_sleep,
+	.request_firmware = NULL,
+};
+#endif
 
 /* ------------------------------------------------------------------ */
 
@@ -197,18 +547,31 @@ static int dvb_init(struct saa7134_dev *
 			    dev);
 
 	switch (dev->board) {
+#ifdef HAVE_MT352
 	case SAA7134_BOARD_PINNACLE_300I_DVBT_PAL:
 		printk("%s: pinnacle 300i dvb setup\n",dev->name);
 		dev->dvb.frontend = mt352_attach(&pinnacle_300i,
 						 &dev->i2c_adap);
 		break;
+#endif
+#ifdef HAVE_TDA1004X
 	case SAA7134_BOARD_MD7134:
 		dev->dvb.frontend = tda10046_attach(&medion_cardbus,
 						    &dev->i2c_adap);
-		if (NULL == dev->dvb.frontend)
-			printk("%s: Hmm, looks like this is the old MD7134 "
-			       "version without DVB-T support\n",dev->name);
 		break;
+	case SAA7134_BOARD_PHILIPS_TOUGH:
+		dev->dvb.frontend = tda10046_attach(&philips_tu1216_config,
+						    &dev->i2c_adap);
+		break;
+	case SAA7134_BOARD_FLYDVBTDUO:
+		dev->dvb.frontend = tda10046_attach(&tda827x_lifeview_config,
+						    &dev->i2c_adap);
+		break;
+	case SAA7134_BOARD_THYPHOON_DVBT_DUO_CARDBUS:
+		dev->dvb.frontend = tda10046_attach(&tda827x_lifeview_config,
+						    &dev->i2c_adap);
+		break;
+#endif
 	default:
 		printk("%s: Huh? unknown DVB card?\n",dev->name);
 		break;
@@ -227,8 +590,6 @@ static int dvb_fini(struct saa7134_dev *
 {
 	static int on  = TDA9887_PRESENT | TDA9887_PORT2_INACTIVE;
 
-	printk("%s: %s\n",dev->name,__FUNCTION__);
-
 	switch (dev->board) {
 	case SAA7134_BOARD_PINNACLE_300I_DVBT_PAL:
 		/* otherwise we don't detect the tuner on next insmod */
diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c
--- a/drivers/media/video/saa7134/saa7134-empress.c
+++ b/drivers/media/video/saa7134/saa7134-empress.c
@@ -1,5 +1,5 @@
 /*
- * $Id: saa7134-empress.c,v 1.10 2005/02/03 10:24:33 kraxel Exp $
+ * $Id: saa7134-empress.c,v 1.11 2005/05/22 19:23:39 nsh Exp $
  *
  * (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
  *
diff --git a/drivers/media/video/saa7134/saa7134-i2c.c b/drivers/media/video/saa7134/saa7134-i2c.c
--- a/drivers/media/video/saa7134/saa7134-i2c.c
+++ b/drivers/media/video/saa7134/saa7134-i2c.c
@@ -1,5 +1,5 @@
 /*
- * $Id: saa7134-i2c.c,v 1.10 2005/01/24 17:37:23 kraxel Exp $
+ * $Id: saa7134-i2c.c,v 1.22 2005/07/22 04:09:41 mkrufky Exp $
  *
  * device driver for philips saa7134 based TV cards
  * i2c interface support
@@ -197,10 +197,6 @@ static inline int i2c_send_byte(struct s
 	enum i2c_status status;
 	__u32 dword;
 
-#if 0
-	i2c_set_attr(dev,attr);
-	saa_writeb(SAA7134_I2C_DATA, data);
-#else
 	/* have to write both attr + data in one 32bit word */
 	dword  = saa_readl(SAA7134_I2C_ATTR_STATUS >> 2);
 	dword &= 0x0f;
@@ -210,7 +206,6 @@ static inline int i2c_send_byte(struct s
 //	dword |= 0x40 << 16;  /* 400 kHz */
 	dword |= 0xf0 << 24;
 	saa_writel(SAA7134_I2C_ATTR_STATUS >> 2, dword);
-#endif
 	d2printk(KERN_DEBUG "%s: i2c data => 0x%x\n",dev->name,data);
 
 	if (!i2c_is_busy_wait(dev))
@@ -305,6 +300,8 @@ static int saa7134_i2c_xfer(struct i2c_a
   	status = i2c_get_status(dev);
 	if (i2c_is_error(status))
 		goto err;
+	/* ensure that the bus is idle for at least one bit slot */
+	msleep(1);
 
 	d1printk("\n");
 	return num;
@@ -331,12 +328,44 @@ static u32 functionality(struct i2c_adap
 
 static int attach_inform(struct i2c_client *client)
 {
-        struct saa7134_dev *dev = client->adapter->algo_data;
+	struct saa7134_dev *dev = client->adapter->algo_data;
 	int tuner = dev->tuner_type;
 	int conf  = dev->tda9887_conf;
+	struct tuner_setup tun_setup;
+
+	d1printk( "%s i2c attach [addr=0x%x,client=%s]\n",
+		client->driver->name,client->addr,i2c_clientname(client));
+
+	if (!client->driver->command)
+		return 0;
+
+	if (saa7134_boards[dev->board].radio_type != UNSET) {
+
+		tun_setup.type = saa7134_boards[dev->board].radio_type;
+		tun_setup.addr = saa7134_boards[dev->board].radio_addr;
+
+		if ((tun_setup.addr == ADDR_UNSET) || (tun_setup.addr == client->addr)) {
+			tun_setup.mode_mask = T_RADIO;
+
+			client->driver->command(client, TUNER_SET_TYPE_ADDR, &tun_setup);
+		}
+        }
+
+	if (tuner != UNSET) {
+
+	        tun_setup.type = tuner;
+	        tun_setup.addr = saa7134_boards[dev->board].tuner_addr;
+
+		if ((tun_setup.addr == ADDR_UNSET)||(tun_setup.addr == client->addr)) {
+
+			tun_setup.mode_mask = T_ANALOG_TV;
+
+			client->driver->command(client,TUNER_SET_TYPE_ADDR, &tun_setup);
+		}
+        }
+
+	client->driver->command(client, TDA9887_SET_CONFIG, &conf);
 
-	saa7134_i2c_call_clients(dev,TUNER_SET_TYPE,&tuner);
-	saa7134_i2c_call_clients(dev,TDA9887_SET_CONFIG,&conf);
         return 0;
 }
 
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c
--- a/drivers/media/video/saa7134/saa7134-input.c
+++ b/drivers/media/video/saa7134/saa7134-input.c
@@ -1,5 +1,5 @@
 /*
- * $Id: saa7134-input.c,v 1.16 2004/12/10 12:33:39 kraxel Exp $
+ * $Id: saa7134-input.c,v 1.21 2005/06/22 23:37:34 nsh Exp $
  *
  * handle saa7134 IR remotes via linux kernel input layer.
  *
@@ -68,10 +68,8 @@ static IR_KEYTAB_TYPE flyvideo_codes[IR_
 	[    6 ] = KEY_AGAIN,        // Recal
 	[   16 ] = KEY_KPENTER,      // Enter
 
-#if 1 /* FIXME */
 	[   26 ] = KEY_F22,          // Stereo
 	[   24 ] = KEY_EDIT,         // AV Source
-#endif
 };
 
 static IR_KEYTAB_TYPE cinergy_codes[IR_KEYTAB_SIZE] = {
@@ -172,45 +170,45 @@ static IR_KEYTAB_TYPE eztv_codes[IR_KEYT
 };
 
 static IR_KEYTAB_TYPE avacssmart_codes[IR_KEYTAB_SIZE] = {
-        [ 30 ] = KEY_POWER,		// power
+	[ 30 ] = KEY_POWER,		// power
 	[ 28 ] = KEY_SEARCH,		// scan
-        [  7 ] = KEY_SELECT,		// source
+	[  7 ] = KEY_SELECT,		// source
 
 	[ 22 ] = KEY_VOLUMEUP,
 	[ 20 ] = KEY_VOLUMEDOWN,
-        [ 31 ] = KEY_CHANNELUP,
+	[ 31 ] = KEY_CHANNELUP,
 	[ 23 ] = KEY_CHANNELDOWN,
 	[ 24 ] = KEY_MUTE,
 
 	[  2 ] = KEY_KP0,
-        [  1 ] = KEY_KP1,
-        [ 11 ] = KEY_KP2,
-        [ 27 ] = KEY_KP3,
-        [  5 ] = KEY_KP4,
-        [  9 ] = KEY_KP5,
-        [ 21 ] = KEY_KP6,
+	[  1 ] = KEY_KP1,
+	[ 11 ] = KEY_KP2,
+	[ 27 ] = KEY_KP3,
+	[  5 ] = KEY_KP4,
+	[  9 ] = KEY_KP5,
+	[ 21 ] = KEY_KP6,
 	[  6 ] = KEY_KP7,
-        [ 10 ] = KEY_KP8,
+	[ 10 ] = KEY_KP8,
 	[ 18 ] = KEY_KP9,
 	[ 16 ] = KEY_KPDOT,
 
 	[  3 ] = KEY_TUNER,		// tv/fm
-        [  4 ] = KEY_REWIND,		// fm tuning left or function left
-        [ 12 ] = KEY_FORWARD,		// fm tuning right or function right
+	[  4 ] = KEY_REWIND,		// fm tuning left or function left
+	[ 12 ] = KEY_FORWARD,		// fm tuning right or function right
 
 	[  0 ] = KEY_RECORD,
-        [  8 ] = KEY_STOP,
-        [ 17 ] = KEY_PLAY,
+	[  8 ] = KEY_STOP,
+	[ 17 ] = KEY_PLAY,
 
 	[ 25 ] = KEY_ZOOM,
 	[ 14 ] = KEY_MENU,		// function
 	[ 19 ] = KEY_AGAIN,		// recall
 	[ 29 ] = KEY_RESTART,		// reset
+	[ 26 ] = KEY_SHUFFLE,		// snapshot/shuffle
 
 // FIXME
 	[ 13 ] = KEY_F21,		// mts
-        [ 15 ] = KEY_F22,		// min
-	[ 26 ] = KEY_F23,		// freeze
+	[ 15 ] = KEY_F22,		// min
 };
 
 /* Alex Hermann <gaaf@gmx.net> */
@@ -308,6 +306,102 @@ static IR_KEYTAB_TYPE videomate_tv_pvr_c
 	[ 32 ] = KEY_LANGUAGE,
 	[ 33 ] = KEY_SLEEP,
 };
+
+/* Michael Tokarev <mjt@tls.msk.ru>
+   http://www.corpit.ru/mjt/beholdTV/remote_control.jpg
+   keytable is used by MANLI MTV00[12] and BeholdTV 40[13] at
+   least, and probably other cards too.
+   The "ascii-art picture" below (in comments, first row
+   is the keycode in hex, and subsequent row(s) shows
+   the button labels (several variants when appropriate)
+   helps to descide which keycodes to assign to the buttons.
+ */
+static IR_KEYTAB_TYPE manli_codes[IR_KEYTAB_SIZE] = {
+
+	/*  0x1c            0x12  *
+	 * FUNCTION         POWER *
+	 *   FM              (|)  *
+	 *                        */
+	[ 0x1c ] = KEY_RADIO,	/*XXX*/
+	[ 0x12 ] = KEY_POWER,
+
+	/*  0x01    0x02    0x03  *
+	 *   1       2       3    *
+	 *                        *
+	 *  0x04    0x05    0x06  *
+	 *   4       5       6    *
+	 *                        *
+	 *  0x07    0x08    0x09  *
+	 *   7       8       9    *
+	 *                        */
+	[ 0x01 ] = KEY_KP1,
+	[ 0x02 ] = KEY_KP2,
+	[ 0x03 ] = KEY_KP3,
+	[ 0x04 ] = KEY_KP4,
+	[ 0x05 ] = KEY_KP5,
+	[ 0x06 ] = KEY_KP6,
+	[ 0x07 ] = KEY_KP7,
+	[ 0x08 ] = KEY_KP8,
+	[ 0x09 ] = KEY_KP9,
+
+	/*  0x0a    0x00    0x17  *
+	 * RECALL    0      +100  *
+	 *                  PLUS  *
+	 *                        */
+	[ 0x0a ] = KEY_AGAIN,	/*XXX KEY_REWIND? */
+	[ 0x00 ] = KEY_KP0,
+	[ 0x17 ] = KEY_DIGITS,	/*XXX*/
+
+	/*  0x14            0x10  *
+	 *  MENU            INFO  *
+	 *  OSD                   */
+	[ 0x14 ] = KEY_MENU,
+	[ 0x10 ] = KEY_INFO,
+
+	/*          0x0b          *
+	 *           Up           *
+	 *                        *
+	 *  0x18    0x16    0x0c  *
+	 *  Left     Ok     Right *
+	 *                        *
+	 *         0x015          *
+	 *         Down           *
+	 *                        */
+	[ 0x0b ] = KEY_UP,	/*XXX KEY_SCROLLUP? */
+	[ 0x18 ] = KEY_LEFT,	/*XXX KEY_BACK? */
+	[ 0x16 ] = KEY_OK,	/*XXX KEY_SELECT? KEY_ENTER? */
+	[ 0x0c ] = KEY_RIGHT,	/*XXX KEY_FORWARD? */
+	[ 0x15 ] = KEY_DOWN,	/*XXX KEY_SCROLLDOWN? */
+
+	/*  0x11            0x0d  *
+	 *  TV/AV           MODE  *
+	 *  SOURCE         STEREO *
+	 *                        */
+	[ 0x11 ] = KEY_TV,	/*XXX*/
+	[ 0x0d ] = KEY_MODE,	/*XXX there's no KEY_STEREO */
+
+	/*  0x0f    0x1b    0x1a  *
+	 *  AUDIO   Vol+    Chan+ *
+	 *        TIMESHIFT???    *
+	 *                        *
+	 *  0x0e    0x1f    0x1e  *
+	 *  SLEEP   Vol-    Chan- *
+	 *                        */
+	[ 0x0f ] = KEY_AUDIO,
+	[ 0x1b ] = KEY_VOLUMEUP,
+	[ 0x1a ] = KEY_CHANNELUP,
+	[ 0x0e ] = KEY_SLEEP,	/*XXX maybe KEY_PAUSE */
+	[ 0x1f ] = KEY_VOLUMEDOWN,
+	[ 0x1e ] = KEY_CHANNELDOWN,
+
+	/*         0x13     0x19  *
+	 *         MUTE   SNAPSHOT*
+	 *                        */
+	[ 0x13 ] = KEY_MUTE,
+	[ 0x19 ] = KEY_RECORD,	/*XXX*/
+
+	// 0x1d unused ?
+};
 /* ---------------------------------------------------------------------- */
 
 static int build_key(struct saa7134_dev *dev)
@@ -379,7 +473,7 @@ int saa7134_input_init1(struct saa7134_d
 	switch (dev->board) {
 	case SAA7134_BOARD_FLYVIDEO2000:
 	case SAA7134_BOARD_FLYVIDEO3000:
-	case SAA7134_BOARD_FLYTVPLATINUM_FM:
+        case SAA7134_BOARD_FLYTVPLATINUM_FM:
 		ir_codes     = flyvideo_codes;
 		mask_keycode = 0xEC00000;
 		mask_keydown = 0x0040000;
@@ -393,20 +487,25 @@ int saa7134_input_init1(struct saa7134_d
 		break;
 	case SAA7134_BOARD_ECS_TVP3XP:
 	case SAA7134_BOARD_ECS_TVP3XP_4CB5:
-                ir_codes     = eztv_codes;
-                mask_keycode = 0x00017c;
-                mask_keyup   = 0x000002;
+		ir_codes     = eztv_codes;
+		mask_keycode = 0x00017c;
+		mask_keyup   = 0x000002;
 		polling      = 50; // ms
-                break;
+		break;
+	case SAA7134_BOARD_KWORLD_XPERT:
 	case SAA7134_BOARD_AVACSSMARTTV:
-	        ir_codes     = avacssmart_codes;
+		ir_codes     = avacssmart_codes;
 		mask_keycode = 0x00001F;
 		mask_keyup   = 0x000020;
 		polling      = 50; // ms
 		break;
 	case SAA7134_BOARD_MD2819:
+	case SAA7134_BOARD_KWORLD_VSTREAM_XPERT:
 	case SAA7134_BOARD_AVERMEDIA_305:
 	case SAA7134_BOARD_AVERMEDIA_307:
+	case SAA7134_BOARD_AVERMEDIA_STUDIO_305:
+	case SAA7134_BOARD_AVERMEDIA_STUDIO_307:
+	case SAA7134_BOARD_AVERMEDIA_GO_007_FM:
 		ir_codes     = md2819_codes;
 		mask_keycode = 0x0007C8;
 		mask_keydown = 0x000010;
@@ -415,7 +514,16 @@ int saa7134_input_init1(struct saa7134_d
 		saa_setb(SAA7134_GPIO_GPMODE0, 0x4);
 		saa_setb(SAA7134_GPIO_GPSTATUS0, 0x4);
 		break;
+	case SAA7134_BOARD_MANLI_MTV001:
+	case SAA7134_BOARD_MANLI_MTV002:
+		ir_codes     = manli_codes;
+		mask_keycode = 0x001f00;
+		mask_keyup   = 0x004000;
+		mask_keydown = 0x002000;
+		polling      = 50; // ms
+		break;
 	case SAA7134_BOARD_VIDEOMATE_TV_PVR:
+	case SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII:
 		ir_codes     = videomate_tv_pvr_codes;
 		mask_keycode = 0x00003F;
 		mask_keyup   = 0x400000;
diff --git a/drivers/media/video/saa7134/saa7134-oss.c b/drivers/media/video/saa7134/saa7134-oss.c
--- a/drivers/media/video/saa7134/saa7134-oss.c
+++ b/drivers/media/video/saa7134/saa7134-oss.c
@@ -1,5 +1,5 @@
 /*
- * $Id: saa7134-oss.c,v 1.13 2004/12/10 12:33:39 kraxel Exp $
+ * $Id: saa7134-oss.c,v 1.17 2005/06/28 23:41:47 mkrufky Exp $
  *
  * device driver for philips saa7134 based TV cards
  * oss dsp interface
@@ -49,7 +49,6 @@ MODULE_PARM_DESC(oss_rate,"sample rate (
 
 static int dsp_buffer_conf(struct saa7134_dev *dev, int blksize, int blocks)
 {
-	blksize &= ~0xff;
 	if (blksize < 0x100)
 		blksize = 0x100;
 	if (blksize > 0x10000)
@@ -57,8 +56,6 @@ static int dsp_buffer_conf(struct saa713
 
 	if (blocks < 2)
 		blocks = 2;
-        while ((blksize * blocks) & ~PAGE_MASK)
-		blocks++;
 	if ((blksize * blocks) > 1024*1024)
 		blocks = 1024*1024 / blksize;
 
@@ -79,7 +76,7 @@ static int dsp_buffer_init(struct saa713
 		BUG();
 	videobuf_dma_init(&dev->oss.dma);
 	err = videobuf_dma_init_kernel(&dev->oss.dma, PCI_DMA_FROMDEVICE,
-				       dev->oss.bufsize >> PAGE_SHIFT);
+				       (dev->oss.bufsize + PAGE_SIZE) >> PAGE_SHIFT);
 	if (0 != err)
 		return err;
 	return 0;
@@ -163,10 +160,11 @@ static int dsp_rec_start(struct saa7134_
 			fmt |= 0x04;
 		fmt |= (TV == dev->oss.input) ? 0xc0 : 0x80;
 
-		saa_writeb(SAA7134_NUM_SAMPLES0, (dev->oss.blksize & 0x0000ff));
-		saa_writeb(SAA7134_NUM_SAMPLES1, (dev->oss.blksize & 0x00ff00) >>  8);
-		saa_writeb(SAA7134_NUM_SAMPLES2, (dev->oss.blksize & 0xff0000) >> 16);
+		saa_writeb(SAA7134_NUM_SAMPLES0, ((dev->oss.blksize - 1) & 0x0000ff));
+		saa_writeb(SAA7134_NUM_SAMPLES1, ((dev->oss.blksize - 1) & 0x00ff00) >>  8);
+		saa_writeb(SAA7134_NUM_SAMPLES2, ((dev->oss.blksize - 1) & 0xff0000) >> 16);
 		saa_writeb(SAA7134_AUDIO_FORMAT_CTRL, fmt);
+
 		break;
 	case PCI_DEVICE_ID_PHILIPS_SAA7133:
 	case PCI_DEVICE_ID_PHILIPS_SAA7135:
@@ -558,21 +556,28 @@ mixer_recsrc_7134(struct saa7134_dev *de
 static int
 mixer_recsrc_7133(struct saa7134_dev *dev)
 {
-	u32 value = 0xbbbbbb;
+	u32 anabar, xbarin;
 
+	xbarin = 0x03; // adc
+    anabar = 0;
 	switch (dev->oss.input) {
 	case TV:
-		value = 0xbbbb10;  /* MAIN */
+		xbarin = 0; // Demodulator
+        anabar = 2; // DACs
 		break;
 	case LINE1:
-		value = 0xbbbb32;  /* AUX1 */
+		anabar = 0;  // aux1, aux1
 		break;
 	case LINE2:
 	case LINE2_LEFT:
-		value = 0xbbbb54;  /* AUX2 */
+		anabar = 9;  // aux2, aux2
 		break;
 	}
-	saa_dsp_writel(dev, 0x46c >> 2, value);
+    /* output xbar always main channel */
+	saa_dsp_writel(dev, 0x46c >> 2, 0xbbbb10);
+	saa_dsp_writel(dev, 0x464 >> 2, xbarin);
+	saa_writel(0x594 >> 2, anabar);
+
 	return 0;
 }
 
@@ -817,7 +822,7 @@ void saa7134_irq_oss_done(struct saa7134
 			reg = SAA7134_RS_BA1(6);
 	} else {
 		/* even */
-		if (0 == (dev->oss.dma_blk & 0x00))
+		if (1 == (dev->oss.dma_blk & 0x01))
 			reg = SAA7134_RS_BA2(6);
 	}
 	if (0 == reg) {
diff --git a/drivers/media/video/saa7134/saa7134-ts.c b/drivers/media/video/saa7134/saa7134-ts.c
--- a/drivers/media/video/saa7134/saa7134-ts.c
+++ b/drivers/media/video/saa7134/saa7134-ts.c
@@ -1,5 +1,5 @@
 /*
- * $Id: saa7134-ts.c,v 1.14 2005/02/03 10:24:33 kraxel Exp $
+ * $Id: saa7134-ts.c,v 1.15 2005/06/14 22:48:18 hhackmann Exp $
  *
  * device driver for philips saa7134 based TV cards
  * video4linux video interface
@@ -221,10 +221,10 @@ void saa7134_irq_ts_done(struct saa7134_
 	if (dev->ts_q.curr) {
 		field = dev->ts_q.curr->vb.field;
 		if (field == V4L2_FIELD_TOP) {
-			if ((status & 0x100000) != 0x000000)
+			if ((status & 0x100000) != 0x100000)
 				goto done;
 		} else {
-			if ((status & 0x100000) != 0x100000)
+			if ((status & 0x100000) != 0x000000)
 				goto done;
 		}
 		saa7134_buffer_finish(dev,&dev->ts_q,STATE_DONE);
diff --git a/drivers/media/video/saa7134/saa7134-tvaudio.c b/drivers/media/video/saa7134/saa7134-tvaudio.c
--- a/drivers/media/video/saa7134/saa7134-tvaudio.c
+++ b/drivers/media/video/saa7134/saa7134-tvaudio.c
@@ -1,5 +1,5 @@
 /*
- * $Id: saa7134-tvaudio.c,v 1.22 2005/01/07 13:11:19 kraxel Exp $
+ * $Id: saa7134-tvaudio.c,v 1.30 2005/06/28 23:41:47 mkrufky Exp $
  *
  * device driver for philips saa7134 based TV cards
  * tv audio decoder (fm stereo, nicam, ...)
@@ -169,7 +169,7 @@ static void tvaudio_init(struct saa7134_
 	int clock = saa7134_boards[dev->board].audio_clock;
 
 	if (UNSET != audio_clock_override)
-	        clock = audio_clock_override;
+		clock = audio_clock_override;
 
 	/* init all audio registers */
 	saa_writeb(SAA7134_AUDIO_PLL_CTRL,   0x00);
@@ -181,7 +181,8 @@ static void tvaudio_init(struct saa7134_
 	saa_writeb(SAA7134_AUDIO_CLOCK0,      clock        & 0xff);
 	saa_writeb(SAA7134_AUDIO_CLOCK1,     (clock >>  8) & 0xff);
 	saa_writeb(SAA7134_AUDIO_CLOCK2,     (clock >> 16) & 0xff);
-	saa_writeb(SAA7134_AUDIO_PLL_CTRL,   0x01);
+	// frame locked audio was reported not to be reliable
+	saa_writeb(SAA7134_AUDIO_PLL_CTRL,   0x02);
 
 	saa_writeb(SAA7134_NICAM_ERROR_LOW,  0x14);
 	saa_writeb(SAA7134_NICAM_ERROR_HIGH, 0x50);
@@ -218,14 +219,17 @@ static void mute_input_7134(struct saa71
 	in   = dev->input;
 	mute = (dev->ctl_mute ||
 		(dev->automute  &&  (&card(dev).radio) != in));
-	if (PCI_DEVICE_ID_PHILIPS_SAA7130 == dev->pci->device &&
-	    card(dev).mute.name) {
-		/* 7130 - we'll mute using some unconnected audio input */
+	if (card(dev).mute.name) {
+		/*
+		 * 7130 - we'll mute using some unconnected audio input
+		 * 7134 - we'll probably should switch external mux with gpio
+		 */
 		if (mute)
 			in = &card(dev).mute;
 	}
+
 	if (dev->hw_mute  == mute &&
-	    dev->hw_input == in) {
+		dev->hw_input == in) {
 		dprintk("mute/input: nothing to do [mute=%d,input=%s]\n",
 			mute,in->name);
 		return;
@@ -250,10 +254,16 @@ static void mute_input_7134(struct saa71
 	saa_andorb(SAA7134_AUDIO_FORMAT_CTRL, 0xc0, ausel);
 	saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x08, ics);
 	saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x07, ocs);
+	// for oss, we need to change the clock configuration
+	if (in->amux == TV)
+		saa_andorb(SAA7134_SIF_SAMPLE_FREQ,   0x03, 0x00);
+	else
+		saa_andorb(SAA7134_SIF_SAMPLE_FREQ,   0x03, 0x01);
 
 	/* switch gpio-connected external audio mux */
 	if (0 == card(dev).gpiomask)
 		return;
+
 	mask = card(dev).gpiomask;
 	saa_andorl(SAA7134_GPIO_GPMODE0 >> 2,   mask, mask);
 	saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, mask, in->gpio);
@@ -333,13 +343,8 @@ static int tvaudio_sleep(struct saa7134_
 			set_current_state(TASK_INTERRUPTIBLE);
 			schedule();
 		} else {
-#if 0
-			/* hmm, that one doesn't return on wakeup ... */
-			msleep_interruptible(timeout);
-#else
 			set_current_state(TASK_INTERRUPTIBLE);
 			schedule_timeout(msecs_to_jiffies(timeout));
-#endif
 		}
 	}
 	remove_wait_queue(&dev->thread.wq, &wait);
@@ -394,27 +399,10 @@ static int tvaudio_checkcarrier(struct s
 	return value;
 }
 
-#if 0
-static void sifdebug_dump_regs(struct saa7134_dev *dev)
-{
-	print_regb(AUDIO_STATUS);
-	print_regb(IDENT_SIF);
-	print_regb(LEVEL_READOUT1);
-	print_regb(LEVEL_READOUT2);
-	print_regb(DCXO_IDENT_CTRL);
-	print_regb(DEMODULATOR);
-	print_regb(AGC_GAIN_SELECT);
-	print_regb(MONITOR_SELECT);
-	print_regb(FM_DEEMPHASIS);
-	print_regb(FM_DEMATRIX);
-	print_regb(SIF_SAMPLE_FREQ);
-	print_regb(ANALOG_IO_SELECT);
-}
-#endif
 
 static int tvaudio_getstereo(struct saa7134_dev *dev, struct saa7134_tvaudio *audio)
 {
-	__u32 idp,nicam;
+	__u32 idp, nicam, nicam_status;
 	int retval = -1;
 
 	switch (audio->mode) {
@@ -436,19 +424,24 @@ static int tvaudio_getstereo(struct saa7
 		break;
 	case TVAUDIO_NICAM_FM:
 	case TVAUDIO_NICAM_AM:
-		nicam = saa_readb(SAA7134_NICAM_STATUS);
+		nicam = saa_readb(SAA7134_AUDIO_STATUS);
 		dprintk("getstereo: nicam=0x%x\n",nicam);
-		switch (nicam & 0x0b) {
-		case 0x09:
-			retval = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
-			break;
-		case 0x0a:
-			retval = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
-			break;
-		case 0x08:
-		default:
-			retval = V4L2_TUNER_SUB_MONO;
-			break;
+		if (nicam & 0x1) {
+			nicam_status = saa_readb(SAA7134_NICAM_STATUS);
+			dprintk("getstereo: nicam_status=0x%x\n", nicam_status);
+
+			switch (nicam_status & 0x03) {
+			    case 0x01:
+				retval = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
+				break;
+			    case 0x02:
+				retval = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
+				break;
+			    default:
+				retval = V4L2_TUNER_SUB_MONO;
+			}
+		} else {
+			/* No nicam detected */
 		}
 		break;
 	}
@@ -484,15 +477,15 @@ static int tvaudio_setstereo(struct saa7
 		break;
 	case TVAUDIO_FM_K_STEREO:
 	case TVAUDIO_FM_BG_STEREO:
+	case TVAUDIO_NICAM_AM:
+	case TVAUDIO_NICAM_FM:
 		dprintk("setstereo [fm] => %s\n",
 			name[ mode % ARRAY_SIZE(name) ]);
 		reg = fm[ mode % ARRAY_SIZE(fm) ];
 		saa_writeb(SAA7134_FM_DEMATRIX, reg);
 		break;
 	case TVAUDIO_FM_SAT_STEREO:
-	case TVAUDIO_NICAM_AM:
-	case TVAUDIO_NICAM_FM:
-		/* FIXME */
+		/* Not implemented */
 		break;
 	}
 	return 0;
@@ -572,14 +565,14 @@ static int tvaudio_thread(void *data)
 		} else if (0 != dev->last_carrier) {
 			/* no carrier -- try last detected one as fallback */
 			carrier = dev->last_carrier;
-			printk(KERN_WARNING "%s/audio: audio carrier scan failed, "
+			dprintk(KERN_WARNING "%s/audio: audio carrier scan failed, "
 			       "using %d.%03d MHz [last detected]\n",
 			       dev->name, carrier/1000, carrier%1000);
 
 		} else {
 			/* no carrier + no fallback -- use default */
 			carrier = default_carrier;
-			printk(KERN_WARNING "%s/audio: audio carrier scan failed, "
+			dprintk(KERN_WARNING "%s/audio: audio carrier scan failed, "
 			       "using %d.%03d MHz [default]\n",
 			       dev->name, carrier/1000, carrier%1000);
 		}
@@ -591,7 +584,7 @@ static int tvaudio_thread(void *data)
 		/* find the exact tv audio norm */
 		for (audio = UNSET, i = 0; i < TVAUDIO; i++) {
 			if (dev->tvnorm->id != UNSET &&
-			    !(dev->tvnorm->id & tvaudio[i].std))
+				!(dev->tvnorm->id & tvaudio[i].std))
 				continue;
 			if (tvaudio[i].carr1 != carrier)
 				continue;
@@ -698,24 +691,6 @@ static inline int saa_dsp_wait_bit(struc
 	return 0;
 }
 
-#if 0
-static int saa_dsp_readl(struct saa7134_dev *dev, int reg, u32 *value)
-{
-	int err;
-
-	d2printk("dsp read reg 0x%x\n", reg<<2);
-	saa_readl(reg);
-	err = saa_dsp_wait_bit(dev,SAA7135_DSP_RWSTATE_RDB);
-	if (err < 0)
-		return err;
-	*value = saa_readl(reg);
-	d2printk("dsp read   => 0x%06x\n", *value & 0xffffff);
-	err = saa_dsp_wait_bit(dev,SAA7135_DSP_RWSTATE_IDA);
-	if (err < 0)
-		return err;
-	return 0;
-}
-#endif
 
 int saa_dsp_writel(struct saa7134_dev *dev, int reg, u32 value)
 {
@@ -748,31 +723,50 @@ static int getstereo_7133(struct saa7134
 static int mute_input_7133(struct saa7134_dev *dev)
 {
 	u32 reg = 0;
+	u32 xbarin, xbarout;
 	int mask;
+	struct saa7134_input *in;
 
+	/* Hac 0506 route OSS sound simultanously  */
+	xbarin = 0x03;
 	switch (dev->input->amux) {
 	case TV:
 		reg = 0x02;
+		xbarin = 0;
 		break;
 	case LINE1:
 		reg = 0x00;
 		break;
 	case LINE2:
 	case LINE2_LEFT:
-		reg = 0x01;
+		reg = 0x09;
 		break;
 	}
-	if (dev->ctl_mute)
+	saa_dsp_writel(dev, 0x464 >> 2, xbarin);
+	if (dev->ctl_mute) {
 		reg = 0x07;
+		xbarout = 0xbbbbbb;
+	} else
+		xbarout = 0xbbbb10;
+	saa_dsp_writel(dev, 0x46c >> 2, xbarout);
+
 	saa_writel(0x594 >> 2, reg);
 
+
 	/* switch gpio-connected external audio mux */
         if (0 != card(dev).gpiomask) {
         	mask = card(dev).gpiomask;
+
+		if (card(dev).mute.name && dev->ctl_mute)
+			in = &card(dev).mute;
+		else
+			in = dev->input;
+
         	saa_andorl(SAA7134_GPIO_GPMODE0 >> 2,   mask, mask);
-        	saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, mask, dev->input->gpio);
-        	saa7134_track_gpio(dev,dev->input->name);
+        	saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, mask, in->gpio);
+        	saa7134_track_gpio(dev,in->name);
 	}
+
 	return 0;
 }
 
diff --git a/drivers/media/video/saa7134/saa7134-vbi.c b/drivers/media/video/saa7134/saa7134-vbi.c
--- a/drivers/media/video/saa7134/saa7134-vbi.c
+++ b/drivers/media/video/saa7134/saa7134-vbi.c
@@ -1,5 +1,5 @@
 /*
- * $Id: saa7134-vbi.c,v 1.6 2004/12/10 12:33:39 kraxel Exp $
+ * $Id: saa7134-vbi.c,v 1.7 2005/05/24 23:13:06 nsh Exp $
  *
  * device driver for philips saa7134 based TV cards
  * video4linux video interface
@@ -60,10 +60,10 @@ static void task_init(struct saa7134_dev
 	saa_writeb(SAA7134_VBI_H_START2(task), norm->h_start     >> 8);
 	saa_writeb(SAA7134_VBI_H_STOP1(task),  norm->h_stop      &  0xff);
 	saa_writeb(SAA7134_VBI_H_STOP2(task),  norm->h_stop      >> 8);
-	saa_writeb(SAA7134_VBI_V_START1(task), norm->vbi_v_start &  0xff);
-	saa_writeb(SAA7134_VBI_V_START2(task), norm->vbi_v_start >> 8);
-	saa_writeb(SAA7134_VBI_V_STOP1(task),  norm->vbi_v_stop  &  0xff);
-	saa_writeb(SAA7134_VBI_V_STOP2(task),  norm->vbi_v_stop  >> 8);
+	saa_writeb(SAA7134_VBI_V_START1(task), norm->vbi_v_start_0 &  0xff);
+	saa_writeb(SAA7134_VBI_V_START2(task), norm->vbi_v_start_0 >> 8);
+	saa_writeb(SAA7134_VBI_V_STOP1(task),  norm->vbi_v_stop_0  &  0xff);
+	saa_writeb(SAA7134_VBI_V_STOP2(task),  norm->vbi_v_stop_0  >> 8);
 
 	saa_writeb(SAA7134_VBI_H_SCALE_INC1(task),        VBI_SCALE & 0xff);
 	saa_writeb(SAA7134_VBI_H_SCALE_INC2(task),        VBI_SCALE >> 8);
@@ -127,16 +127,10 @@ static int buffer_prepare(struct videobu
 	unsigned int lines, llength, size;
 	int err;
 
-	lines   = norm->vbi_v_stop - norm->vbi_v_start +1;
+	lines   = norm->vbi_v_stop_0 - norm->vbi_v_start_0 +1;
 	if (lines > VBI_LINE_COUNT)
 		lines = VBI_LINE_COUNT;
-#if 1
 	llength = VBI_LINE_LENGTH;
-#else
-	llength = (norm->h_stop - norm->h_start +1) * 2;
-	if (llength > VBI_LINE_LENGTH)
-		llength = VBI_LINE_LENGTH;
-#endif
 	size = lines * llength * 2;
 	if (0 != buf->vb.baddr  &&  buf->vb.bsize < size)
 		return -EINVAL;
@@ -177,14 +171,8 @@ buffer_setup(struct videobuf_queue *q, u
 	struct saa7134_dev *dev = fh->dev;
 	int llength,lines;
 
-	lines   = dev->tvnorm->vbi_v_stop - dev->tvnorm->vbi_v_start +1;
-#if 1
+	lines   = dev->tvnorm->vbi_v_stop_0 - dev->tvnorm->vbi_v_start_0 +1;
 	llength = VBI_LINE_LENGTH;
-#else
-	llength = (norm->h_stop - norm->h_start +1) * 2;
-	if (llength > VBI_LINE_LENGTH)
-		llength = VBI_LINE_LENGTH;
-#endif
 	*size = lines * llength * 2;
 	if (0 == *count)
 		*count = vbibufs;
diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c
--- a/drivers/media/video/saa7134/saa7134-video.c
+++ b/drivers/media/video/saa7134/saa7134-video.c
@@ -1,5 +1,5 @@
 /*
- * $Id: saa7134-video.c,v 1.28 2005/02/15 15:59:35 kraxel Exp $
+ * $Id: saa7134-video.c,v 1.36 2005/06/28 23:41:47 mkrufky Exp $
  *
  * device driver for philips saa7134 based TV cards
  * video4linux video interface
@@ -31,8 +31,6 @@
 #include "saa7134-reg.h"
 #include "saa7134.h"
 
-#define V4L2_I2C_CLIENTS 1
-
 /* ------------------------------------------------------------------ */
 
 static unsigned int video_debug   = 0;
@@ -158,18 +156,20 @@ static struct saa7134_format formats[] =
 		.h_stop        = 719,	\
 		.video_v_start = 24,	\
 		.video_v_stop  = 311,	\
-		.vbi_v_start   = 7,	\
-		.vbi_v_stop    = 22,	\
+		.vbi_v_start_0 = 7,	\
+		.vbi_v_stop_0  = 22,	\
+		.vbi_v_start_1 = 319,   \
 		.src_timing    = 4
 
 #define NORM_525_60			\
 		.h_start       = 0,	\
 		.h_stop        = 703,	\
-		.video_v_start = 22,	\
-		.video_v_stop  = 22+239, \
-		.vbi_v_start   = 10, /* FIXME */ \
-		.vbi_v_stop    = 21, /* FIXME */ \
-		.src_timing    = 1
+		.video_v_start = 23,	\
+		.video_v_stop  = 262,	\
+		.vbi_v_start_0 = 10,	\
+		.vbi_v_stop_0  = 21,	\
+		.vbi_v_start_1 = 273,	\
+		.src_timing    = 7
 
 static struct saa7134_tvnorm tvnorms[] = {
 	{
@@ -274,11 +274,12 @@ static struct saa7134_tvnorm tvnorms[] =
 
 		.h_start       = 0,
 		.h_stop        = 719,
-		.video_v_start = 22,
-		.video_v_stop  = 22+239,
-		.vbi_v_start   = 10, /* FIXME */
-		.vbi_v_stop    = 21, /* FIXME */
-		.src_timing    = 1,
+  		.video_v_start = 23,
+  		.video_v_stop  = 262,
+  		.vbi_v_start_0 = 10,
+  		.vbi_v_stop_0  = 21,
+  		.vbi_v_start_1 = 273,
+  		.src_timing    = 7,
 
 		.sync_control  = 0x18,
 		.luma_control  = 0x40,
@@ -335,8 +336,8 @@ static const struct v4l2_queryctrl video
 		.default_value = 0,
 		.type          = V4L2_CTRL_TYPE_INTEGER,
 	},{
-		.id            = V4L2_CID_VFLIP,
-		.name          = "vertical flip",
+		.id            = V4L2_CID_HFLIP,
+		.name          = "Mirror",
 		.minimum       = 0,
 		.maximum       = 1,
 		.type          = V4L2_CTRL_TYPE_BOOLEAN,
@@ -482,7 +483,7 @@ static void set_tvnorm(struct saa7134_de
 	dev->crop_bounds.width   = norm->h_stop - norm->h_start +1;
 	dev->crop_defrect.width  = norm->h_stop - norm->h_start +1;
 
-	dev->crop_bounds.top     = (norm->vbi_v_stop+1)*2;
+	dev->crop_bounds.top     = (norm->vbi_v_stop_0+1)*2;
 	dev->crop_defrect.top    = norm->video_v_start*2;
 	dev->crop_bounds.height  = ((norm->id & V4L2_STD_525_60) ? 524 : 624)
 		- dev->crop_bounds.top;
@@ -521,22 +522,7 @@ static void set_tvnorm(struct saa7134_de
 	saa_writeb(SAA7134_RAW_DATA_GAIN,         0x40);
 	saa_writeb(SAA7134_RAW_DATA_OFFSET,       0x80);
 
-#ifdef V4L2_I2C_CLIENTS
 	saa7134_i2c_call_clients(dev,VIDIOC_S_STD,&norm->id);
-#else
-	{
-		/* pass down info to the i2c chips (v4l1) */
-		struct video_channel c;
-		memset(&c,0,sizeof(c));
-		c.channel = dev->ctl_input;
-		c.norm = VIDEO_MODE_PAL;
-		if (norm->id & V4L2_STD_NTSC)
-			c.norm = VIDEO_MODE_NTSC;
-		if (norm->id & V4L2_STD_SECAM)
-			c.norm = VIDEO_MODE_SECAM;
-		saa7134_i2c_call_clients(dev,VIDIOCSCHAN,&c);
-	}
-#endif
 }
 
 static void video_mux(struct saa7134_dev *dev, int input)
@@ -1064,7 +1050,7 @@ static int get_control(struct saa7134_de
 	case V4L2_CID_PRIVATE_INVERT:
 		c->value = dev->ctl_invert;
 		break;
-	case V4L2_CID_VFLIP:
+	case V4L2_CID_HFLIP:
 		c->value = dev->ctl_mirror;
 		break;
 	case V4L2_CID_PRIVATE_Y_EVEN:
@@ -1139,7 +1125,7 @@ static int set_control(struct saa7134_de
 		saa_writeb(SAA7134_DEC_CHROMA_SATURATION,
 			   dev->ctl_invert ? -dev->ctl_saturation : dev->ctl_saturation);
 		break;
-	case V4L2_CID_VFLIP:
+	case V4L2_CID_HFLIP:
 		dev->ctl_mirror = c->value;
 		restart_overlay = 1;
 		break;
@@ -1218,7 +1204,6 @@ static int video_open(struct inode *inod
 	struct list_head *list;
 	enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 	int radio = 0;
-
 	list_for_each(list,&saa7134_devlist) {
 		h = list_entry(list, struct saa7134_dev, devlist);
 		if (h->video_dev && (h->video_dev->minor == minor))
@@ -1270,12 +1255,12 @@ static int video_open(struct inode *inod
 	if (fh->radio) {
 		/* switch to radio mode */
 		saa7134_tvaudio_setinput(dev,&card(dev).radio);
-		saa7134_i2c_call_clients(dev,AUDC_SET_RADIO,NULL);
+		saa7134_i2c_call_clients(dev,AUDC_SET_RADIO, NULL);
 	} else {
 		/* switch to video/vbi mode */
 		video_mux(dev,dev->ctl_input);
 	}
-        return 0;
+	return 0;
 }
 
 static ssize_t
@@ -1318,10 +1303,10 @@ video_poll(struct file *file, struct pol
 	} else {
 		down(&fh->cap.lock);
 		if (UNSET == fh->cap.read_off) {
-                        /* need to capture a new frame */
+			/* need to capture a new frame */
 			if (res_locked(fh->dev,RESOURCE_VIDEO)) {
-                                up(&fh->cap.lock);
-                                return POLLERR;
+				up(&fh->cap.lock);
+				return POLLERR;
                         }
                         if (0 != fh->cap.ops->buf_prepare(&fh->cap,fh->cap.read_buf,fh->cap.field)) {
                                 up(&fh->cap.lock);
@@ -1377,6 +1362,36 @@ static int video_release(struct inode *i
 		res_free(dev,fh,RESOURCE_VBI);
 	}
 
+	/* ts-capture will not work in planar mode, so turn it off Hac: 04.05*/
+	saa_andorb(SAA7134_OFMT_VIDEO_A, 0x1f, 0);
+	saa_andorb(SAA7134_OFMT_VIDEO_B, 0x1f, 0);
+	saa_andorb(SAA7134_OFMT_DATA_A, 0x1f, 0);
+	saa_andorb(SAA7134_OFMT_DATA_B, 0x1f, 0);
+
+	if (dev->tuner_type == TUNER_PHILIPS_TDA8290) {
+		u8 data[2];
+		int ret;
+		struct i2c_msg msg = {.addr=I2C_ADDR_TDA8290, .flags=0, .buf=data, .len = 2};
+		data[0] = 0x21;
+		data[1] = 0xc0;
+		ret = i2c_transfer(&dev->i2c_adap, &msg, 1);
+		if (ret != 1)
+			printk(KERN_ERR "TDA8290 access failure\n");
+		msg.addr = I2C_ADDR_TDA8275;
+		data[0] = 0x30;
+		data[1] = 0xd0;
+		ret = i2c_transfer(&dev->i2c_adap, &msg, 1);
+		if (ret != 1)
+			printk(KERN_ERR "TDA8275 access failure\n");
+		msg.addr = I2C_ADDR_TDA8290;
+		data[0] = 0x21;
+		data[1] = 0x80;
+		i2c_transfer(&dev->i2c_adap, &msg, 1);
+		data[0] = 0x00;
+		data[1] = 0x02;
+		i2c_transfer(&dev->i2c_adap, &msg, 1);
+	}
+
 	/* free stuff */
 	videobuf_mmap_free(&fh->cap);
 	videobuf_mmap_free(&fh->vbi);
@@ -1407,19 +1422,12 @@ static void saa7134_vbi_fmt(struct saa71
 	f->fmt.vbi.samples_per_line = 2048 /* VBI_LINE_LENGTH */;
 	f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
 	f->fmt.vbi.offset = 64 * 4;
-	f->fmt.vbi.start[0] = norm->vbi_v_start;
-	f->fmt.vbi.count[0] = norm->vbi_v_stop - norm->vbi_v_start +1;
-	f->fmt.vbi.start[1] = norm->video_v_stop + norm->vbi_v_start +1;
+	f->fmt.vbi.start[0] = norm->vbi_v_start_0;
+	f->fmt.vbi.count[0] = norm->vbi_v_stop_0 - norm->vbi_v_start_0 +1;
+	f->fmt.vbi.start[1] = norm->vbi_v_start_1;
 	f->fmt.vbi.count[1] = f->fmt.vbi.count[0];
 	f->fmt.vbi.flags = 0; /* VBI_UNSYNC VBI_INTERLACED */
 
-#if 0
-	if (V4L2_STD_PAL == norm->id) {
-		/* FIXME */
-		f->fmt.vbi.start[0] += 3;
-		f->fmt.vbi.start[1] += 3*2;
-	}
-#endif
 }
 
 static int saa7134_g_fmt(struct saa7134_dev *dev, struct saa7134_fh *fh,
@@ -1880,11 +1888,9 @@ static int video_do_ioctl(struct inode *
 			return -EINVAL;
 		down(&dev->lock);
 		dev->ctl_freq = f->frequency;
-#ifdef V4L2_I2C_CLIENTS
+
 		saa7134_i2c_call_clients(dev,VIDIOC_S_FREQUENCY,f);
-#else
-		saa7134_i2c_call_clients(dev,VIDIOCSFREQ,&dev->ctl_freq);
-#endif
+
 		saa7134_tvaudio_do_scan(dev);
 		up(&dev->lock);
 		return 0;
@@ -2136,19 +2142,20 @@ static int radio_do_ioctl(struct inode *
 
 		memset(t,0,sizeof(*t));
 		strcpy(t->name, "Radio");
-                t->rangelow  = (int)(65*16);
-                t->rangehigh = (int)(108*16);
 
-#ifdef V4L2_I2C_CLIENTS
-		saa7134_i2c_call_clients(dev,VIDIOC_G_TUNER,t);
-#else
-		{
-			struct video_tuner vt;
-			memset(&vt,0,sizeof(vt));
-			saa7134_i2c_call_clients(dev,VIDIOCGTUNER,&vt);
-			t->signal = vt.signal;
-		}
-#endif
+		saa7134_i2c_call_clients(dev, VIDIOC_G_TUNER, t);
+
+		return 0;
+	}
+	case VIDIOC_S_TUNER:
+	{
+		struct v4l2_tuner *t = arg;
+
+		if (0 != t->index)
+			return -EINVAL;
+
+		saa7134_i2c_call_clients(dev,VIDIOC_S_TUNER,t);
+
 		return 0;
 	}
 	case VIDIOC_ENUMINPUT:
@@ -2182,7 +2189,6 @@ static int radio_do_ioctl(struct inode *
 		return 0;
 	}
 	case VIDIOC_S_AUDIO:
-	case VIDIOC_S_TUNER:
 	case VIDIOC_S_INPUT:
 	case VIDIOC_S_STD:
 		return 0;
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -1,5 +1,5 @@
 /*
- * $Id: saa7134.h,v 1.38 2005/03/07 12:01:51 kraxel Exp $
+ * $Id: saa7134.h,v 1.49 2005/07/13 17:25:25 mchehab Exp $
  *
  * v4l2 device driver for philips saa7134 based TV cards
  *
@@ -21,7 +21,7 @@
  */
 
 #include <linux/version.h>
-#define SAA7134_VERSION_CODE KERNEL_VERSION(0,2,12)
+#define SAA7134_VERSION_CODE KERNEL_VERSION(0,2,14)
 
 #include <linux/pci.h>
 #include <linux/i2c.h>
@@ -46,8 +46,6 @@
 #endif
 #define UNSET (-1U)
 
-/* 2.4 / 2.5 driver compatibility stuff */
-
 /* ----------------------------------------------------------- */
 /* enums                                                       */
 
@@ -91,9 +89,10 @@ struct saa7134_tvnorm {
 	unsigned int  h_stop;
 	unsigned int  video_v_start;
 	unsigned int  video_v_stop;
-	unsigned int  vbi_v_start;
-	unsigned int  vbi_v_stop;
+	unsigned int  vbi_v_start_0;
+	unsigned int  vbi_v_stop_0;
 	unsigned int  src_timing;
+	unsigned int  vbi_v_start_1;
 };
 
 struct saa7134_tvaudio {
@@ -158,7 +157,7 @@ struct saa7134_format {
 #define SAA7134_BOARD_AVERMEDIA_DVD_EZMAKER 33
 #define SAA7134_BOARD_NOVAC_PRIMETV7133 34
 #define SAA7134_BOARD_AVERMEDIA_STUDIO_305 35
-#define SAA7133_BOARD_UPMOST_PURPLE_TV 36
+#define SAA7134_BOARD_UPMOST_PURPLE_TV 36
 #define SAA7134_BOARD_ITEMS_MTV005     37
 #define SAA7134_BOARD_CINERGY200       38
 #define SAA7134_BOARD_FLYTVPLATINUM_MINI 39
@@ -167,7 +166,7 @@ struct saa7134_format {
 #define SAA7134_BOARD_SABRENT_SBTTVFM  42
 #define SAA7134_BOARD_ZOLID_XPERT_TV7134 43
 #define SAA7134_BOARD_EMPIRE_PCI_TV_RADIO_LE 44
-#define SAA7134_BOARD_AVERMEDIA_307    45
+#define SAA7134_BOARD_AVERMEDIA_STUDIO_307    45
 #define SAA7134_BOARD_AVERMEDIA_CARDBUS 46
 #define SAA7134_BOARD_CINERGY400_CARDBUS 47
 #define SAA7134_BOARD_CINERGY600_MK3   48
@@ -175,9 +174,17 @@ struct saa7134_format {
 #define SAA7134_BOARD_PINNACLE_300I_DVBT_PAL 50
 #define SAA7134_BOARD_PROVIDEO_PV952   51
 #define SAA7134_BOARD_AVERMEDIA_305    52
-#define SAA7135_BOARD_ASUSTeK_TVFM7135 53
+#define SAA7134_BOARD_ASUSTeK_TVFM7135 53
 #define SAA7134_BOARD_FLYTVPLATINUM_FM 54
 #define SAA7134_BOARD_FLYDVBTDUO 55
+#define SAA7134_BOARD_AVERMEDIA_307    56
+#define SAA7134_BOARD_AVERMEDIA_GO_007_FM 57
+#define SAA7134_BOARD_ADS_INSTANT_TV 58
+#define SAA7134_BOARD_KWORLD_VSTREAM_XPERT 59
+#define SAA7134_BOARD_THYPHOON_DVBT_DUO_CARDBUS 60
+#define SAA7134_BOARD_PHILIPS_TOUGH 61
+#define SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII 62
+#define SAA7134_BOARD_KWORLD_XPERT 63
 
 #define SAA7134_MAXBOARDS 8
 #define SAA7134_INPUT_MAX 8
@@ -208,6 +215,10 @@ struct saa7134_board {
 
 	/* i2c chip info */
 	unsigned int            tuner_type;
+	unsigned int		radio_type;
+	unsigned char		tuner_addr;
+	unsigned char		radio_addr;
+
 	unsigned int            tda9887_conf;
 
 	/* peripheral I/O */
@@ -241,7 +252,7 @@ struct saa7134_dma;
 /* saa7134 page table */
 struct saa7134_pgtable {
 	unsigned int               size;
-	u32                        *cpu;
+	__le32                     *cpu;
 	dma_addr_t                 dma;
 };
 
@@ -398,9 +409,12 @@ struct saa7134_dev {
 	/* config info */
 	unsigned int               board;
 	unsigned int               tuner_type;
+	unsigned int 		   radio_type;
+	unsigned char		   tuner_addr;
+	unsigned char		   radio_addr;
+
 	unsigned int               tda9887_conf;
 	unsigned int               gpio_value;
-	unsigned int               irq2_mask;
 
 	/* i2c i/o */
 	struct i2c_adapter         i2c_adap;
diff --git a/drivers/media/video/saa7185.c b/drivers/media/video/saa7185.c
--- a/drivers/media/video/saa7185.c
+++ b/drivers/media/video/saa7185.c
@@ -380,22 +380,14 @@ saa7185_command (struct i2c_client *clie
  * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
  */
 static unsigned short normal_i2c[] = { I2C_SAA7185 >> 1, I2C_CLIENT_END };
-static unsigned short normal_i2c_range[] = { I2C_CLIENT_END };
 
-static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short probe_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short ignore_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short force[2] = { I2C_CLIENT_END , I2C_CLIENT_END };
+static unsigned short ignore = I2C_CLIENT_END;
                                                                                 
 static struct i2c_client_address_data addr_data = {
 	.normal_i2c		= normal_i2c,
-	.normal_i2c_range	= normal_i2c_range,
-	.probe			= probe,
-	.probe_range		= probe_range,
-	.ignore			= ignore,
-	.ignore_range		= ignore_range,
-	.force			= force
+	.probe			= &ignore,
+	.ignore			= &ignore,
+	.force			= &ignore,
 };
 
 static struct i2c_driver i2c_driver_saa7185;
diff --git a/drivers/media/video/tda7432.c b/drivers/media/video/tda7432.c
--- a/drivers/media/video/tda7432.c
+++ b/drivers/media/video/tda7432.c
@@ -74,7 +74,6 @@ static unsigned short normal_i2c[] = {
 	I2C_TDA7432 >> 1,
 	I2C_CLIENT_END,
 };
-static unsigned short normal_i2c_range[] = { I2C_CLIENT_END, I2C_CLIENT_END };
 I2C_CLIENT_INSMOD;
 
 /* Structure of address and subaddresses for the tda7432 */
@@ -244,19 +243,6 @@ static int tda7432_write(struct i2c_clie
 }
 
 /* I don't think we ever actually _read_ the chip... */
-#if 0
-static int tda7432_read(struct i2c_client *client)
-{
-	unsigned char buffer;
-	d2printk("tda7432: In tda7432_read\n");
-	if (1 != i2c_master_recv(client,&buffer,1)) {
-		printk(KERN_WARNING "tda7432: I/O error, trying (read)\n");
-		return -1;
-	}
-	dprintk("tda7432: Read 0x%02x\n", buffer);
-	return buffer;
-}
-#endif
 
 static int tda7432_set(struct i2c_client *client)
 {
diff --git a/drivers/media/video/tda8290.c b/drivers/media/video/tda8290.c
--- a/drivers/media/video/tda8290.c
+++ b/drivers/media/video/tda8290.c
@@ -1,5 +1,5 @@
 /*
- * $Id: tda8290.c,v 1.7 2005/03/07 12:01:51 kraxel Exp $
+ * $Id: tda8290.c,v 1.15 2005/07/08 20:21:33 mchehab Exp $
  *
  * i2c tv tuner chip device driver
  * controls the philips tda8290+75 tuner chip combo.
@@ -69,7 +69,7 @@ static __u8 get_freq_entry( struct freq_
 static unsigned char i2c_enable_bridge[2] = 	{ 0x21, 0xC0 };
 static unsigned char i2c_disable_bridge[2] = 	{ 0x21, 0x80 };
 static unsigned char i2c_init_tda8275[14] = 	{ 0x00, 0x00, 0x00, 0x00,
-						  0x7C, 0x04, 0xA3, 0x3F,
+						  0xfC, 0x04, 0xA3, 0x3F,
 						  0x2A, 0x04, 0xFF, 0x00,
 						  0x00, 0x40 };
 static unsigned char i2c_set_VS[2] = 		{ 0x30, 0x6F };
@@ -136,18 +136,23 @@ static int tda8290_tune(struct i2c_clien
 	return 0;
 }
 
-static void set_frequency(struct tuner *t, u16 ifc)
+static void set_frequency(struct tuner *t, u16 ifc, unsigned int freq)
 {
-	u32 N = (((t->freq<<3)+ifc)&0x3fffc);
+	u32 N;
 
-	N = N >> get_freq_entry(div_table, t->freq);
+	if (t->mode == V4L2_TUNER_RADIO)
+		freq = freq / 1000;
+
+	N = (((freq<<3)+ifc)&0x3fffc);
+
+	N = N >> get_freq_entry(div_table, freq);
 	t->i2c_set_freq[0] = 0;
 	t->i2c_set_freq[1] = (unsigned char)(N>>8);
 	t->i2c_set_freq[2] = (unsigned char) N;
 	t->i2c_set_freq[3] = 0x40;
 	t->i2c_set_freq[4] = 0x52;
-	t->i2c_set_freq[5] = get_freq_entry(band_table, t->freq);
-	t->i2c_set_freq[6] = get_freq_entry(agc_table,  t->freq);
+	t->i2c_set_freq[5] = get_freq_entry(band_table, freq);
+	t->i2c_set_freq[6] = get_freq_entry(agc_table,  freq);
 	t->i2c_set_freq[7] = 0x8f;
 }
 
@@ -179,14 +184,14 @@ static void set_tv_freq(struct i2c_clien
 	struct tuner *t = i2c_get_clientdata(c);
 
 	set_audio(t);
-	set_frequency(t, 864);
+	set_frequency(t, 864, freq);
 	tda8290_tune(c);
 }
 
 static void set_radio_freq(struct i2c_client *c, unsigned int freq)
 {
 	struct tuner *t = i2c_get_clientdata(c);
-	set_frequency(t, 704);
+	set_frequency(t, 704, freq);
 	tda8290_tune(c);
 }
 
diff --git a/drivers/media/video/tda9840.c b/drivers/media/video/tda9840.c
--- a/drivers/media/video/tda9840.c
+++ b/drivers/media/video/tda9840.c
@@ -43,7 +43,6 @@ MODULE_PARM_DESC(debug, "Turn on/off dev
 
 /* addresses to scan, found only at 0x42 (7-Bit) */
 static unsigned short normal_i2c[] = { I2C_TDA9840, I2C_CLIENT_END };
-static unsigned short normal_i2c_range[] = { I2C_CLIENT_END };
 
 /* magic definition of all other variables and things */
 I2C_CLIENT_INSMOD;
diff --git a/drivers/media/video/tda9875.c b/drivers/media/video/tda9875.c
--- a/drivers/media/video/tda9875.c
+++ b/drivers/media/video/tda9875.c
@@ -44,7 +44,6 @@ static unsigned short normal_i2c[] =  {
     I2C_TDA9875 >> 1,
     I2C_CLIENT_END
 };
-static unsigned short normal_i2c_range[] = {I2C_CLIENT_END};
 I2C_CLIENT_INSMOD;
 
 /* This is a superset of the TDA9875 */
@@ -124,19 +123,6 @@ static int tda9875_write(struct i2c_clie
 	return 0;
 }
 
-#if 0
-static int tda9875_read(struct i2c_client *client)
-{
-	unsigned char buffer;
-	dprintk("In tda9875_read\n");
-	if (1 != i2c_master_recv(client,&buffer,1)) {
-		printk(KERN_WARNING "tda9875: I/O error, trying (read)\n");
-		return -1;
-	}
-	dprintk("Read 0x%02x\n", buffer);
-	return buffer;
-}
-#endif
 
 static int i2c_read_register(struct i2c_adapter *adap, int addr, int reg)
 {
diff --git a/drivers/media/video/tda9887.c b/drivers/media/video/tda9887.c
--- a/drivers/media/video/tda9887.c
+++ b/drivers/media/video/tda9887.c
@@ -33,7 +33,6 @@ static unsigned short normal_i2c[] = {
 	0x96 >>1,
 	I2C_CLIENT_END,
 };
-static unsigned short normal_i2c_range[] = {I2C_CLIENT_END,I2C_CLIENT_END};
 I2C_CLIENT_INSMOD;
 
 /* insmod options */
@@ -54,6 +53,7 @@ struct tda9887 {
 	unsigned int       config;
 	unsigned int       pinnacle_id;
 	unsigned int       using_v4l2;
+	unsigned int 	   radio_mode;
 };
 
 struct tvnorm {
@@ -213,12 +213,22 @@ static struct tvnorm tvnorms[] = {
 	}
 };
 
-static struct tvnorm radio = {
-	.name = "radio",
+static struct tvnorm radio_stereo = {
+	.name = "Radio Stereo",
+	.b    = ( cFmRadio       |
+		  cQSS           ),
+	.c    = ( cDeemphasisOFF |
+		  cAudioGain6 ),
+	.e    = ( cAudioIF_5_5   |
+		  cRadioIF_38_90 ),
+};
+
+static struct tvnorm radio_mono = {
+	.name = "Radio Mono",
 	.b    = ( cFmRadio       |
 		  cQSS           ),
 	.c    = ( cDeemphasisON  |
-		  cDeemphasis50  ),
+		  cDeemphasis50),
 	.e    = ( cAudioIF_5_5   |
 		  cRadioIF_38_90 ),
 };
@@ -355,7 +365,10 @@ static int tda9887_set_tvnorm(struct tda
 	int i;
 
 	if (t->radio) {
-		norm = &radio;
+		if (t->radio_mode == V4L2_TUNER_MODE_MONO)
+			norm = &radio_mono;
+		else
+			norm = &radio_stereo;
 	} else {
 		for (i = 0; i < ARRAY_SIZE(tvnorms); i++) {
 			if (tvnorms[i].std & t->std) {
@@ -546,23 +559,16 @@ static int tda9887_configure(struct tda9
 
 	memset(buf,0,sizeof(buf));
 	tda9887_set_tvnorm(t,buf);
+
 	buf[1] |= cOutputPort1Inactive;
 	buf[1] |= cOutputPort2Inactive;
+
 	if (UNSET != t->pinnacle_id) {
 		tda9887_set_pinnacle(t,buf);
 	}
 	tda9887_set_config(t,buf);
 	tda9887_set_insmod(t,buf);
 
-#if 0
-	/* This as-is breaks some cards, must be fixed in a
-	 * card-specific way, probably using TDA9887_SET_CONFIG to
-	 * turn on/off port2 */
-	if (t->std & V4L2_STD_SECAM_L) {
-		/* secam fixup (FIXME: move this to tvnorms array?) */
-		buf[1] &= ~cOutputPort2Inactive;
-	}
-#endif
 
 	dprintk(PREFIX "writing: b=0x%02x c=0x%02x e=0x%02x\n",
 		buf[1],buf[2],buf[3]);
@@ -593,11 +599,14 @@ static int tda9887_attach(struct i2c_ada
         if (NULL == (t = kmalloc(sizeof(*t), GFP_KERNEL)))
                 return -ENOMEM;
 	memset(t,0,sizeof(*t));
+
 	t->client      = client_template;
 	t->std         = 0;
 	t->pinnacle_id = UNSET;
-        i2c_set_clientdata(&t->client, t);
-        i2c_attach_client(&t->client);
+	t->radio_mode = V4L2_TUNER_MODE_STEREO;
+
+	i2c_set_clientdata(&t->client, t);
+	i2c_attach_client(&t->client);
 
 	return 0;
 }
@@ -734,6 +743,16 @@ tda9887_command(struct i2c_client *clien
 		}
 		break;
 	}
+	case VIDIOC_S_TUNER:
+	{
+		struct v4l2_tuner* tuner = arg;
+
+		if (t->radio) {
+			t->radio_mode = tuner->audmode;
+			tda9887_configure (t);
+		}
+		break;
+	}
 	default:
 		/* nothing */
 		break;
@@ -741,7 +760,7 @@ tda9887_command(struct i2c_client *clien
 	return 0;
 }
 
-static int tda9887_suspend(struct device * dev, pm_message_t state, u32 level)
+static int tda9887_suspend(struct device * dev, u32 state, u32 level)
 {
 	dprintk("tda9887: suspend\n");
 	return 0;
diff --git a/drivers/media/video/tea5767.c b/drivers/media/video/tea5767.c
new file mode 100644
--- /dev/null
+++ b/drivers/media/video/tea5767.c
@@ -0,0 +1,350 @@
+/*
+ * For Philips TEA5767 FM Chip used on some TV Cards like Prolink Pixelview
+ * I2C address is allways 0xC0.
+ *
+ * $Id: tea5767.c,v 1.27 2005/07/31 12:10:56 mchehab Exp $
+ *
+ * Copyright (c) 2005 Mauro Carvalho Chehab (mchehab@brturbo.com.br)
+ * This code is placed under the terms of the GNU General Public License
+ *
+ * tea5767 autodetection thanks to Torsten Seeboth and Atsushi Nakagawa
+ * from their contributions on DScaler.
+ */
+
+#include <linux/i2c.h>
+#include <linux/videodev.h>
+#include <linux/delay.h>
+#include <media/tuner.h>
+
+#define PREFIX "TEA5767 "
+
+/*****************************************************************************/
+
+/******************************
+ * Write mode register values *
+ ******************************/
+
+/* First register */
+#define TEA5767_MUTE		0x80	/* Mutes output */
+#define TEA5767_SEARCH		0x40	/* Activates station search */
+/* Bits 0-5 for divider MSB */
+
+/* Second register */
+/* Bits 0-7 for divider LSB */
+
+/* Third register */
+
+/* Station search from botton to up */
+#define TEA5767_SEARCH_UP	0x80
+
+/* Searches with ADC output = 10 */
+#define TEA5767_SRCH_HIGH_LVL	0x60
+
+/* Searches with ADC output = 10 */
+#define TEA5767_SRCH_MID_LVL	0x40
+
+/* Searches with ADC output = 5 */
+#define TEA5767_SRCH_LOW_LVL	0x20
+
+/* if on, div=4*(Frf+Fif)/Fref otherwise, div=4*(Frf-Fif)/Freq) */
+#define TEA5767_HIGH_LO_INJECT	0x10
+
+/* Disable stereo */
+#define TEA5767_MONO		0x08
+
+/* Disable right channel and turns to mono */
+#define TEA5767_MUTE_RIGHT	0x04
+
+/* Disable left channel and turns to mono */
+#define TEA5767_MUTE_LEFT	0x02
+
+#define TEA5767_PORT1_HIGH	0x01
+
+/* Forth register */
+#define TEA5767_PORT2_HIGH	0x80
+/* Chips stops working. Only I2C bus remains on */
+#define TEA5767_STDBY		0x40
+
+/* Japan freq (76-108 MHz. If disabled, 87.5-108 MHz */
+#define TEA5767_JAPAN_BAND	0x20
+
+/* Unselected means 32.768 KHz freq as reference. Otherwise Xtal at 13 MHz */
+#define TEA5767_XTAL_32768	0x10
+
+/* Cuts weak signals */
+#define TEA5767_SOFT_MUTE	0x08
+
+/* Activates high cut control */
+#define TEA5767_HIGH_CUT_CTRL	0x04
+
+/* Activates stereo noise control */
+#define TEA5767_ST_NOISE_CTL	0x02
+
+/* If activate PORT 1 indicates SEARCH or else it is used as PORT1 */
+#define TEA5767_SRCH_IND	0x01
+
+/* Fiveth register */
+
+/* By activating, it will use Xtal at 13 MHz as reference for divider */
+#define TEA5767_PLLREF_ENABLE	0x80
+
+/* By activating, deemphasis=50, or else, deemphasis of 50us */
+#define TEA5767_DEEMPH_75	0X40
+
+/*****************************
+ * Read mode register values *
+ *****************************/
+
+/* First register */
+#define TEA5767_READY_FLAG_MASK	0x80
+#define TEA5767_BAND_LIMIT_MASK	0X40
+/* Bits 0-5 for divider MSB after search or preset */
+
+/* Second register */
+/* Bits 0-7 for divider LSB after search or preset */
+
+/* Third register */
+#define TEA5767_STEREO_MASK	0x80
+#define TEA5767_IF_CNTR_MASK	0x7f
+
+/* Four register */
+#define TEA5767_ADC_LEVEL_MASK	0xf0
+
+/* should be 0 */
+#define TEA5767_CHIP_ID_MASK	0x0f
+
+/* Fiveth register */
+/* Reserved for future extensions */
+#define TEA5767_RESERVED_MASK	0xff
+
+enum tea5767_xtal_freq {
+        TEA5767_LOW_LO_32768    = 0,
+        TEA5767_HIGH_LO_32768   = 1,
+        TEA5767_LOW_LO_13MHz    = 2,
+        TEA5767_HIGH_LO_13MHz   = 3,
+};
+
+
+/*****************************************************************************/
+
+static void set_tv_freq(struct i2c_client *c, unsigned int freq)
+{
+	struct tuner *t = i2c_get_clientdata(c);
+
+	tuner_warn("This tuner doesn't support TV freq.\n");
+}
+
+static void tea5767_status_dump(unsigned char *buffer)
+{
+	unsigned int div, frq;
+
+	if (TEA5767_READY_FLAG_MASK & buffer[0])
+		printk(PREFIX "Ready Flag ON\n");
+	else
+		printk(PREFIX "Ready Flag OFF\n");
+
+	if (TEA5767_BAND_LIMIT_MASK & buffer[0])
+		printk(PREFIX "Tuner at band limit\n");
+	else
+		printk(PREFIX "Tuner not at band limit\n");
+
+	div = ((buffer[0] & 0x3f) << 8) | buffer[1];
+
+	switch (TEA5767_HIGH_LO_32768) {
+	case TEA5767_HIGH_LO_13MHz:
+		frq = (div * 50000 - 700000 - 225000) / 4;	/* Freq in KHz */
+		break;
+	case TEA5767_LOW_LO_13MHz:
+		frq = (div * 50000 + 700000 + 225000) / 4;	/* Freq in KHz */
+		break;
+	case TEA5767_LOW_LO_32768:
+		frq = (div * 32768 + 700000 + 225000) / 4;	/* Freq in KHz */
+		break;
+	case TEA5767_HIGH_LO_32768:
+	default:
+		frq = (div * 32768 - 700000 - 225000) / 4;	/* Freq in KHz */
+		break;
+	}
+	buffer[0] = (div >> 8) & 0x3f;
+	buffer[1] = div & 0xff;
+
+	printk(PREFIX "Frequency %d.%03d KHz (divider = 0x%04x)\n",
+	       frq / 1000, frq % 1000, div);
+
+	if (TEA5767_STEREO_MASK & buffer[2])
+		printk(PREFIX "Stereo\n");
+	else
+		printk(PREFIX "Mono\n");
+
+	printk(PREFIX "IF Counter = %d\n", buffer[2] & TEA5767_IF_CNTR_MASK);
+
+	printk(PREFIX "ADC Level = %d\n",
+	       (buffer[3] & TEA5767_ADC_LEVEL_MASK) >> 4);
+
+	printk(PREFIX "Chip ID = %d\n", (buffer[3] & TEA5767_CHIP_ID_MASK));
+
+	printk(PREFIX "Reserved = 0x%02x\n",
+	       (buffer[4] & TEA5767_RESERVED_MASK));
+}
+
+/* Freq should be specifyed at 62.5 Hz */
+static void set_radio_freq(struct i2c_client *c, unsigned int frq)
+{
+	struct tuner *t = i2c_get_clientdata(c);
+	unsigned char buffer[5];
+	unsigned div;
+	int rc;
+
+	tuner_dbg (PREFIX "radio freq = %d.%03d MHz\n", frq/16000,(frq/16)%1000);
+
+	/* Rounds freq to next decimal value - for 62.5 KHz step */
+	/* frq = 20*(frq/16)+radio_frq[frq%16]; */
+
+	buffer[2] = TEA5767_PORT1_HIGH;
+	buffer[3] = TEA5767_PORT2_HIGH | TEA5767_HIGH_CUT_CTRL |
+		    TEA5767_ST_NOISE_CTL | TEA5767_JAPAN_BAND;
+	buffer[4] = 0;
+
+	if (t->mode == T_STANDBY) {
+		tuner_dbg("TEA5767 set to standby mode\n");
+		buffer[3] |= TEA5767_STDBY;
+	}
+
+	if (t->audmode == V4L2_TUNER_MODE_MONO) {
+		tuner_dbg("TEA5767 set to mono\n");
+		buffer[2] |= TEA5767_MONO;
+	} else {
+		tuner_dbg("TEA5767 set to stereo\n");
+	}
+
+	/* Should be replaced */
+	switch (TEA5767_HIGH_LO_32768) {
+	case TEA5767_HIGH_LO_13MHz:
+		tuner_dbg ("TEA5767 radio HIGH LO inject xtal @ 13 MHz\n");
+		buffer[2] |= TEA5767_HIGH_LO_INJECT;
+		buffer[4] |= TEA5767_PLLREF_ENABLE;
+		div = (frq * 4000 / 16 + 700000 + 225000 + 25000) / 50000;
+		break;
+	case TEA5767_LOW_LO_13MHz:
+		tuner_dbg ("TEA5767 radio LOW LO inject xtal @ 13 MHz\n");
+
+		buffer[4] |= TEA5767_PLLREF_ENABLE;
+		div = (frq * 4000 / 16 - 700000 - 225000 + 25000) / 50000;
+		break;
+	case TEA5767_LOW_LO_32768:
+		tuner_dbg ("TEA5767 radio LOW LO inject xtal @ 32,768 MHz\n");
+		buffer[3] |= TEA5767_XTAL_32768;
+		/* const 700=4000*175 Khz - to adjust freq to right value */
+		div = ((frq * 4000 / 16 - 700000 - 225000) + 16384) >> 15;
+		break;
+	case TEA5767_HIGH_LO_32768:
+	default:
+		tuner_dbg ("TEA5767 radio HIGH LO inject xtal @ 32,768 MHz\n");
+
+		buffer[2] |= TEA5767_HIGH_LO_INJECT;
+		buffer[3] |= TEA5767_XTAL_32768;
+		div = ((frq * (4000 / 16) + 700000 + 225000) + 16384) >> 15;
+		break;
+	}
+	buffer[0] = (div >> 8) & 0x3f;
+	buffer[1] = div & 0xff;
+
+	if (5 != (rc = i2c_master_send(c, buffer, 5)))
+		tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc);
+
+	if (tuner_debug) {
+		if (5 != (rc = i2c_master_recv(c, buffer, 5)))
+			tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc);
+		else
+			tea5767_status_dump(buffer);
+	}
+}
+
+static int tea5767_signal(struct i2c_client *c)
+{
+	unsigned char buffer[5];
+	int rc;
+	struct tuner *t = i2c_get_clientdata(c);
+
+	memset(buffer, 0, sizeof(buffer));
+	if (5 != (rc = i2c_master_recv(c, buffer, 5)))
+		tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc);
+
+	return ((buffer[3] & TEA5767_ADC_LEVEL_MASK) << (13 - 4));
+}
+
+static int tea5767_stereo(struct i2c_client *c)
+{
+	unsigned char buffer[5];
+	int rc;
+	struct tuner *t = i2c_get_clientdata(c);
+
+	memset(buffer, 0, sizeof(buffer));
+	if (5 != (rc = i2c_master_recv(c, buffer, 5)))
+		tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc);
+
+	rc = buffer[2] & TEA5767_STEREO_MASK;
+
+	tuner_dbg("TEA5767 radio ST GET = %02x\n", rc);
+
+	return ((buffer[2] & TEA5767_STEREO_MASK) ? V4L2_TUNER_SUB_STEREO : 0);
+}
+
+int tea5767_autodetection(struct i2c_client *c)
+{
+	unsigned char buffer[7] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+	int rc;
+	struct tuner *t = i2c_get_clientdata(c);
+
+	if (7 != (rc = i2c_master_recv(c, buffer, 7))) {
+		tuner_warn("It is not a TEA5767. Received %i bytes.\n", rc);
+		return EINVAL;
+	}
+
+	/* If all bytes are the same then it's a TV tuner and not a tea5767 */
+	if (buffer[0] == buffer[1] && buffer[0] == buffer[2] &&
+	    buffer[0] == buffer[3] && buffer[0] == buffer[4]) {
+		tuner_warn("All bytes are equal. It is not a TEA5767\n");
+		return EINVAL;
+	}
+
+	/*  Status bytes:
+	 *  Byte 4: bit 3:1 : CI (Chip Identification) == 0
+	 *          bit 0   : internally set to 0
+	 *  Byte 5: bit 7:0 : == 0
+	 */
+	if (!((buffer[3] & 0x0f) == 0x00) && (buffer[4] == 0x00)) {
+		tuner_warn("Chip ID is not zero. It is not a TEA5767\n");
+		return EINVAL;
+	}
+	/* It seems that tea5767 returns 0xff after the 5th byte */
+	if ((buffer[5] != 0xff) || (buffer[6] != 0xff)) {
+		tuner_warn("Returned more than 5 bytes. It is not a TEA5767\n");
+		return EINVAL;
+	}
+
+	/* It seems that tea5767 returns 0xff after the 5th byte */
+	if ((buffer[5] != 0xff) || (buffer[6] != 0xff)) {
+		tuner_warn("Returned more than 5 bytes. It is not a TEA5767\n");
+		return EINVAL;
+	}
+
+	tuner_warn("TEA5767 detected.\n");
+	return 0;
+}
+
+int tea5767_tuner_init(struct i2c_client *c)
+{
+	struct tuner *t = i2c_get_clientdata(c);
+
+	tuner_info("type set to %d (%s)\n", t->type,
+			"Philips TEA5767HN FM Radio");
+	strlcpy(c->name, "tea5767", sizeof(c->name));
+
+	t->tv_freq = set_tv_freq;
+	t->radio_freq = set_radio_freq;
+	t->has_signal = tea5767_signal;
+	t->is_stereo = tea5767_stereo;
+
+	return (0);
+}
diff --git a/drivers/media/video/tea6415c.c b/drivers/media/video/tea6415c.c
--- a/drivers/media/video/tea6415c.c
+++ b/drivers/media/video/tea6415c.c
@@ -43,7 +43,6 @@ MODULE_PARM_DESC(debug, "Turn on/off dev
 
 /* addresses to scan, found only at 0x03 and/or 0x43 (7-bit) */
 static unsigned short normal_i2c[] = { I2C_TEA6415C_1, I2C_TEA6415C_2, I2C_CLIENT_END };
-static unsigned short normal_i2c_range[] = { I2C_CLIENT_END };
 
 /* magic definition of all other variables and things */
 I2C_CLIENT_INSMOD;
diff --git a/drivers/media/video/tea6420.c b/drivers/media/video/tea6420.c
--- a/drivers/media/video/tea6420.c
+++ b/drivers/media/video/tea6420.c
@@ -40,7 +40,6 @@ MODULE_PARM_DESC(debug, "Turn on/off dev
 
 /* addresses to scan, found only at 0x4c and/or 0x4d (7-Bit) */
 static unsigned short normal_i2c[] = { I2C_TEA6420_1, I2C_TEA6420_2, I2C_CLIENT_END };
-static unsigned short normal_i2c_range[] = { I2C_CLIENT_END };
 
 /* magic definition of all other variables and things */
 I2C_CLIENT_INSMOD;
diff --git a/drivers/media/video/tuner-3036.c b/drivers/media/video/tuner-3036.c
--- a/drivers/media/video/tuner-3036.c
+++ b/drivers/media/video/tuner-3036.c
@@ -34,19 +34,14 @@ static int this_adap;
 static struct i2c_client client_template;
 
 /* Addresses to scan */
-static unsigned short normal_i2c[] = {I2C_CLIENT_END};
-static unsigned short normal_i2c_range[] = {0x60, 0x61, I2C_CLIENT_END};
-static unsigned short probe[2]        = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short probe_range[2]  = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short ignore[2]       = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short ignore_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short force[2]        = { I2C_CLIENT_END, I2C_CLIENT_END };
+static unsigned short normal_i2c[] = { 0x60, 0x61, I2C_CLIENT_END };
+static unsigned short ignore = I2C_CLIENT_END;
 
 static struct i2c_client_address_data addr_data = {
-	normal_i2c, normal_i2c_range, 
-	probe, probe_range, 
-	ignore, ignore_range, 
-	force
+	.normal_i2c	= normal_i2c,
+	.probe		= &ignore,
+	.ignore		= &ignore,
+	.force		= &ignore,
 };
 
 /* ---------------------------------------------------------------------- */
@@ -157,7 +152,7 @@ tuner_command(struct i2c_client *client,
 
 	switch (cmd) 
 	{
-		case TUNER_SET_TVFREQ:
+		case VIDIOCSFREQ:
 			set_tv_freq(client, *iarg);
 			break;
 	    
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -1,5 +1,5 @@
 /*
- * $Id: tuner-core.c,v 1.5 2005/02/15 15:59:35 kraxel Exp $
+ * $Id: tuner-core.c,v 1.63 2005/07/28 18:19:55 mchehab Exp $
  *
  * i2c tv tuner chip device driver
  * core core, i.e. kernel interfaces, registering and so on
@@ -23,67 +23,68 @@
 #include <media/tuner.h>
 #include <media/audiochip.h>
 
+#include "msp3400.h"
+
 #define UNSET (-1U)
 
 /* standard i2c insmod options */
 static unsigned short normal_i2c[] = {
-	0x4b, /* tda8290 */
-	I2C_CLIENT_END
-};
-static unsigned short normal_i2c_range[] = {
-	0x60, 0x6f,
+	0x4b,			/* tda8290 */
+	0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+	0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
 	I2C_CLIENT_END
 };
+
 I2C_CLIENT_INSMOD;
 
 /* insmod options used at init time => read/only */
-static unsigned int addr  =  0;
+static unsigned int addr = 0;
 module_param(addr, int, 0444);
 
+static unsigned int no_autodetect = 0;
+module_param(no_autodetect, int, 0444);
+
+static unsigned int show_i2c = 0;
+module_param(show_i2c, int, 0444);
+
 /* insmod options used at runtime => read/write */
-unsigned int tuner_debug   = 0;
-module_param(tuner_debug,       int, 0644);
+unsigned int tuner_debug = 0;
+module_param(tuner_debug, int, 0644);
 
-static unsigned int tv_range[2]    = { 44, 958 };
+static unsigned int tv_range[2] = { 44, 958 };
 static unsigned int radio_range[2] = { 65, 108 };
 
-module_param_array(tv_range,    int, NULL, 0644);
+module_param_array(tv_range, int, NULL, 0644);
 module_param_array(radio_range, int, NULL, 0644);
 
 MODULE_DESCRIPTION("device driver for various TV and TV+FM radio tuners");
 MODULE_AUTHOR("Ralph Metzler, Gerd Knorr, Gunther Mayer");
 MODULE_LICENSE("GPL");
 
-static int this_adap;
-
 static struct i2c_driver driver;
 static struct i2c_client client_template;
 
 /* ---------------------------------------------------------------------- */
 
-// Set tuner frequency,  freq in Units of 62.5kHz = 1/16MHz
+/* Set tuner frequency,  freq in Units of 62.5kHz = 1/16MHz */
 static void set_tv_freq(struct i2c_client *c, unsigned int freq)
 {
 	struct tuner *t = i2c_get_clientdata(c);
 
 	if (t->type == UNSET) {
-		tuner_info("tuner type not set\n");
+		tuner_warn ("tuner type not set\n");
 		return;
 	}
 	if (NULL == t->tv_freq) {
-		tuner_info("Huh? tv_set is NULL?\n");
+		tuner_warn ("Tuner has no way to set tv freq\n");
 		return;
 	}
-	if (freq < tv_range[0]*16 || freq > tv_range[1]*16) {
-		/* FIXME: better do that chip-specific, but
-		   right now we don't have that in the config
-		   struct and this way is still better than no
-		   check at all */
-		tuner_info("TV freq (%d.%02d) out of range (%d-%d)\n",
-			   freq/16,freq%16*100/16,tv_range[0],tv_range[1]);
-		return;
+	if (freq < tv_range[0] * 16 || freq > tv_range[1] * 16) {
+		tuner_dbg ("TV freq (%d.%02d) out of range (%d-%d)\n",
+			   freq / 16, freq % 16 * 100 / 16, tv_range[0],
+			   tv_range[1]);
 	}
-	t->tv_freq(c,freq);
+	t->tv_freq(c, freq);
 }
 
 static void set_radio_freq(struct i2c_client *c, unsigned int freq)
@@ -91,20 +92,21 @@ static void set_radio_freq(struct i2c_cl
 	struct tuner *t = i2c_get_clientdata(c);
 
 	if (t->type == UNSET) {
-		tuner_info("tuner type not set\n");
+		tuner_warn ("tuner type not set\n");
 		return;
 	}
 	if (NULL == t->radio_freq) {
-		tuner_info("no radio tuning for this one, sorry.\n");
+		tuner_warn ("tuner has no way to set radio frequency\n");
 		return;
 	}
-	if (freq < radio_range[0]*16 || freq > radio_range[1]*16) {
-		tuner_info("radio freq (%d.%02d) out of range (%d-%d)\n",
-			   freq/16,freq%16*100/16,
-			   radio_range[0],radio_range[1]);
-		return;
+	if (freq <= radio_range[0] * 16000 || freq >= radio_range[1] * 16000) {
+		tuner_dbg ("radio freq (%d.%02d) out of range (%d-%d)\n",
+			   freq / 16000, freq % 16000 * 100 / 16000,
+			   radio_range[0], radio_range[1]);
 	}
-	t->radio_freq(c,freq);
+
+	t->radio_freq(c, freq);
+	return;
 }
 
 static void set_freq(struct i2c_client *c, unsigned long freq)
@@ -114,40 +116,45 @@ static void set_freq(struct i2c_client *
 	switch (t->mode) {
 	case V4L2_TUNER_RADIO:
 		tuner_dbg("radio freq set to %lu.%02lu\n",
-			  freq/16,freq%16*100/16);
-		set_radio_freq(c,freq);
+			  freq / 16000, freq % 16000 * 100 / 16000);
+		set_radio_freq(c, freq);
 		break;
 	case V4L2_TUNER_ANALOG_TV:
 	case V4L2_TUNER_DIGITAL_TV:
 		tuner_dbg("tv freq set to %lu.%02lu\n",
-			  freq/16,freq%16*100/16);
+			  freq / 16, freq % 16 * 100 / 16);
 		set_tv_freq(c, freq);
 		break;
 	}
 	t->freq = freq;
 }
 
-static void set_type(struct i2c_client *c, unsigned int type)
+static void set_type(struct i2c_client *c, unsigned int type,
+		     unsigned int new_mode_mask)
 {
 	struct tuner *t = i2c_get_clientdata(c);
+	unsigned char buffer[4];
 
-	/* sanity check */
-	if (type == UNSET  ||  type == TUNER_ABSENT)
+	if (type == UNSET || type == TUNER_ABSENT) {
+		tuner_dbg ("tuner 0x%02x: Tuner type absent\n",c->addr);
 		return;
-	if (type >= tuner_count)
+	}
+
+	if (type >= tuner_count) {
+		tuner_warn ("tuner 0x%02x: Tuner count greater than %d\n",c->addr,tuner_count);
 		return;
+	}
 
+	/* This code detects calls by card attach_inform */
 	if (NULL == t->i2c.dev.driver) {
-		/* not registered yet */
-		t->type = type;
+		tuner_dbg ("tuner 0x%02x: called during i2c_client register by adapter's attach_inform\n", c->addr);
+
+		t->type=type;
 		return;
 	}
-	if (t->initialized)
-		/* run only once */
-		return;
 
-	t->initialized = 1;
 	t->type = type;
+
 	switch (t->type) {
 	case TUNER_MT2032:
 		microtune_init(c);
@@ -155,81 +162,219 @@ static void set_type(struct i2c_client *
 	case TUNER_PHILIPS_TDA8290:
 		tda8290_init(c);
 		break;
+	case TUNER_TEA5767:
+		if (tea5767_tuner_init(c) == EINVAL) {
+			t->type = TUNER_ABSENT;
+			t->mode_mask = T_UNINITIALIZED;
+			return;
+		}
+		t->mode_mask = T_RADIO;
+		break;
+	case TUNER_PHILIPS_FMD1216ME_MK3:
+		buffer[0] = 0x0b;
+		buffer[1] = 0xdc;
+		buffer[2] = 0x9c;
+		buffer[3] = 0x60;
+		i2c_master_send(c, buffer, 4);
+		mdelay(1);
+		buffer[2] = 0x86;
+		buffer[3] = 0x54;
+		i2c_master_send(c, buffer, 4);
+		default_tuner_init(c);
+		break;
 	default:
 		default_tuner_init(c);
 		break;
 	}
+
+	if (t->mode_mask == T_UNINITIALIZED)
+		t->mode_mask = new_mode_mask;
+
+	set_freq(c, t->freq);
+	tuner_dbg("%s %s I2C addr 0x%02x with type %d used for 0x%02x\n",
+		  c->adapter->name, c->driver->name, c->addr << 1, type,
+		  t->mode_mask);
+}
+
+/*
+ * This function apply tuner config to tuner specified
+ * by tun_setup structure. I addr is unset, then admin status
+ * and tun addr status is more precise then current status,
+ * it's applied. Otherwise status and type are applied only to
+ * tuner with exactly the same addr.
+*/
+
+static void set_addr(struct i2c_client *c, struct tuner_setup *tun_setup)
+{
+	struct tuner *t = i2c_get_clientdata(c);
+
+	if (tun_setup->addr == ADDR_UNSET) {
+		if (t->mode_mask & tun_setup->mode_mask)
+			set_type(c, tun_setup->type, tun_setup->mode_mask);
+	} else if (tun_setup->addr == c->addr) {
+		set_type(c, tun_setup->type, tun_setup->mode_mask);
+	}
+}
+
+static inline int check_mode(struct tuner *t, char *cmd)
+{
+	if (1 << t->mode & t->mode_mask) {
+		switch (t->mode) {
+		case V4L2_TUNER_RADIO:
+			tuner_dbg("Cmd %s accepted for radio\n", cmd);
+			break;
+		case V4L2_TUNER_ANALOG_TV:
+			tuner_dbg("Cmd %s accepted for analog TV\n", cmd);
+			break;
+		case V4L2_TUNER_DIGITAL_TV:
+			tuner_dbg("Cmd %s accepted for digital TV\n", cmd);
+			break;
+		}
+		return 0;
+	}
+	return EINVAL;
 }
 
 static char pal[] = "-";
 module_param_string(pal, pal, sizeof(pal), 0644);
+static char secam[] = "-";
+module_param_string(secam, secam, sizeof(secam), 0644);
 
+/* get more precise norm info from insmod option */
 static int tuner_fixup_std(struct tuner *t)
 {
 	if ((t->std & V4L2_STD_PAL) == V4L2_STD_PAL) {
-		/* get more precise norm info from insmod option */
 		switch (pal[0]) {
 		case 'b':
 		case 'B':
 		case 'g':
 		case 'G':
-			tuner_dbg("insmod fixup: PAL => PAL-BG\n");
+			tuner_dbg ("insmod fixup: PAL => PAL-BG\n");
 			t->std = V4L2_STD_PAL_BG;
 			break;
 		case 'i':
 		case 'I':
-			tuner_dbg("insmod fixup: PAL => PAL-I\n");
+			tuner_dbg ("insmod fixup: PAL => PAL-I\n");
 			t->std = V4L2_STD_PAL_I;
 			break;
 		case 'd':
 		case 'D':
 		case 'k':
 		case 'K':
-			tuner_dbg("insmod fixup: PAL => PAL-DK\n");
+			tuner_dbg ("insmod fixup: PAL => PAL-DK\n");
 			t->std = V4L2_STD_PAL_DK;
 			break;
+		case 'M':
+		case 'm':
+			tuner_dbg ("insmod fixup: PAL => PAL-M\n");
+			t->std = V4L2_STD_PAL_M;
+			break;
+		case 'N':
+		case 'n':
+			tuner_dbg ("insmod fixup: PAL => PAL-N\n");
+			t->std = V4L2_STD_PAL_N;
+			break;
 		}
 	}
+	if ((t->std & V4L2_STD_SECAM) == V4L2_STD_SECAM) {
+		switch (secam[0]) {
+		case 'd':
+		case 'D':
+		case 'k':
+		case 'K':
+			tuner_dbg ("insmod fixup: SECAM => SECAM-DK\n");
+			t->std = V4L2_STD_SECAM_DK;
+			break;
+		case 'l':
+		case 'L':
+			tuner_dbg ("insmod fixup: SECAM => SECAM-L\n");
+			t->std = V4L2_STD_SECAM_L;
+			break;
+		}
+	}
+
 	return 0;
 }
 
 /* ---------------------------------------------------------------------- */
 
+/* static var Used only in tuner_attach and tuner_probe */
+static unsigned default_mode_mask;
+
+/* During client attach, set_type is called by adapter's attach_inform callback.
+   set_type must then be completed by tuner_attach.
+ */
 static int tuner_attach(struct i2c_adapter *adap, int addr, int kind)
 {
 	struct tuner *t;
 
-	if (this_adap > 0)
-		return -1;
-	this_adap++;
-
-        client_template.adapter = adap;
-        client_template.addr = addr;
-
-        t = kmalloc(sizeof(struct tuner),GFP_KERNEL);
-        if (NULL == t)
-                return -ENOMEM;
-        memset(t,0,sizeof(struct tuner));
-        memcpy(&t->i2c,&client_template,sizeof(struct i2c_client));
+	client_template.adapter = adap;
+	client_template.addr = addr;
+
+	t = kmalloc(sizeof(struct tuner), GFP_KERNEL);
+	if (NULL == t)
+		return -ENOMEM;
+	memset(t, 0, sizeof(struct tuner));
+	memcpy(&t->i2c, &client_template, sizeof(struct i2c_client));
 	i2c_set_clientdata(&t->i2c, t);
-	t->type       = UNSET;
-	t->radio_if2  = 10700*1000; // 10.7MHz - FM radio
+	t->type = UNSET;
+	t->radio_if2 = 10700 * 1000;	/* 10.7MHz - FM radio */
+	t->audmode = V4L2_TUNER_MODE_STEREO;
+	t->mode_mask = T_UNINITIALIZED;
+
+
+	tuner_info("chip found @ 0x%x (%s)\n", addr << 1, adap->name);
+
+	if (show_i2c) {
+		unsigned char buffer[16];
+		int i,rc;
+
+		memset(buffer, 0, sizeof(buffer));
+		rc = i2c_master_recv(&t->i2c, buffer, sizeof(buffer));
+		printk("tuner-%04x I2C RECV = ",addr);
+		for (i=0;i<rc;i++)
+			printk("%02x ",buffer[i]);
+		printk("\n");
+	}
+	/* TEA5767 autodetection code - only for addr = 0xc0 */
+	if (!no_autodetect) {
+		if (addr == 0x60) {
+			if (tea5767_autodetection(&t->i2c) != EINVAL) {
+				t->type = TUNER_TEA5767;
+				t->mode_mask = T_RADIO;
+				t->mode = T_STANDBY;
+				t->freq = 87.5 * 16; /* Sets freq to FM range */
+				default_mode_mask &= ~T_RADIO;
+
+				i2c_attach_client (&t->i2c);
+				set_type(&t->i2c,t->type, t->mode_mask);
+				return 0;
+			}
+		}
+	}
 
-        i2c_attach_client(&t->i2c);
-	tuner_info("chip found @ 0x%x (%s)\n",
-		   addr << 1, adap->name);
-	set_type(&t->i2c, t->type);
+	/* Initializes only the first adapter found */
+	if (default_mode_mask != T_UNINITIALIZED) {
+		tuner_dbg ("Setting mode_mask to 0x%02x\n", default_mode_mask);
+		t->mode_mask = default_mode_mask;
+		t->freq = 400 * 16; /* Sets freq to VHF High */
+		default_mode_mask = T_UNINITIALIZED;
+	}
+
+	/* Should be just before return */
+	i2c_attach_client (&t->i2c);
+	set_type (&t->i2c,t->type, t->mode_mask);
 	return 0;
 }
 
 static int tuner_probe(struct i2c_adapter *adap)
 {
 	if (0 != addr) {
-		normal_i2c[0]       = addr;
-		normal_i2c_range[0] = addr;
-		normal_i2c_range[1] = addr;
+		normal_i2c[0] = addr;
+		normal_i2c[1] = I2C_CLIENT_END;
 	}
-	this_adap = 0;
+
+	default_mode_mask = T_RADIO | T_ANALOG_TV | T_DIGITAL_TV;
 
 	if (adap->class & I2C_CLASS_TV_ANALOG)
 		return i2c_probe(adap, &addr_data, tuner_attach);
@@ -239,38 +384,78 @@ static int tuner_probe(struct i2c_adapte
 static int tuner_detach(struct i2c_client *client)
 {
 	struct tuner *t = i2c_get_clientdata(client);
+	int err;
+
+	err = i2c_detach_client(&t->i2c);
+	if (err) {
+		tuner_warn
+		    ("Client deregistration failed, client not detached.\n");
+		return err;
+	}
 
-	i2c_detach_client(&t->i2c);
 	kfree(t);
 	return 0;
 }
 
-#define SWITCH_V4L2	if (!t->using_v4l2 && tuner_debug) \
-		          tuner_info("switching to v4l2\n"); \
-	                  t->using_v4l2 = 1;
-#define CHECK_V4L2	if (t->using_v4l2) { if (tuner_debug) \
-			  tuner_info("ignore v4l1 call\n"); \
-		          return 0; }
+/*
+ * Switch tuner to other mode. If tuner support both tv and radio,
+ * set another frequency to some value (This is needed for some pal
+ * tuners to avoid locking). Otherwise, just put second tuner in
+ * standby mode.
+ */
 
-static int
-tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
+static inline int set_mode(struct i2c_client *client, struct tuner *t, int mode, char *cmd)
 {
-	struct tuner *t = i2c_get_clientdata(client);
-        unsigned int *iarg = (int*)arg;
+	if (mode != t->mode) {
 
-        switch (cmd) {
+		t->mode = mode;
+		if (check_mode(t, cmd) == EINVAL) {
+			t->mode = T_STANDBY;
+			if (V4L2_TUNER_RADIO == mode) {
+				set_tv_freq(client, 400 * 16);
+			} else {
+				set_radio_freq(client, 87.5 * 16000);
+			}
+			return EINVAL;
+		}
+	}
+	return 0;
+}
+
+#define switch_v4l2()	if (!t->using_v4l2) \
+		            tuner_dbg("switching to v4l2\n"); \
+	                t->using_v4l2 = 1;
+
+static inline int check_v4l2(struct tuner *t)
+{
+	if (t->using_v4l2) {
+		tuner_dbg ("ignore v4l1 call\n");
+		return EINVAL;
+	}
+	return 0;
+}
+
+static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
+{
+	struct tuner *t = i2c_get_clientdata(client);
+	unsigned int *iarg = (int *)arg;
 
+	switch (cmd) {
 	/* --- configuration --- */
-	case TUNER_SET_TYPE:
-		set_type(client,*iarg);
+	case TUNER_SET_TYPE_ADDR:
+		tuner_dbg ("Calling set_type_addr for type=%d, addr=0x%02x, mode=0x%02x\n",
+				((struct tuner_setup *)arg)->type,
+				((struct tuner_setup *)arg)->addr,
+				((struct tuner_setup *)arg)->mode_mask);
+
+		set_addr(client, (struct tuner_setup *)arg);
 		break;
 	case AUDC_SET_RADIO:
-		if (V4L2_TUNER_RADIO != t->mode) {
-			set_tv_freq(client,400 * 16);
-			t->mode = V4L2_TUNER_RADIO;
-		}
+		set_mode(client,t,V4L2_TUNER_RADIO, "AUDC_SET_RADIO");
 		break;
 	case AUDC_CONFIG_PINNACLE:
+		if (check_mode(t, "AUDC_CONFIG_PINNACLE") == EINVAL)
+			return 0;
 		switch (*iarg) {
 		case 2:
 			tuner_dbg("pinnacle pal\n");
@@ -281,154 +466,252 @@ tuner_command(struct i2c_client *client,
 			t->radio_if2 = 41300 * 1000;
 			break;
 		}
-                break;
+		break;
+	case VIDIOCSAUDIO:
+		if (check_mode(t, "VIDIOCSAUDIO") == EINVAL)
+			return 0;
+		if (check_v4l2(t) == EINVAL)
+			return 0;
+
+		/* Should be implemented, since bttv calls it */
+		tuner_dbg("VIDIOCSAUDIO not implemented.\n");
 
+		break;
+	case MSP_SET_MATRIX:
+	case TDA9887_SET_CONFIG:
+		break;
 	/* --- v4l ioctls --- */
 	/* take care: bttv does userspace copying, we'll get a
 	   kernel pointer here... */
 	case VIDIOCSCHAN:
-	{
-		static const v4l2_std_id map[] = {
-			[ VIDEO_MODE_PAL   ] = V4L2_STD_PAL,
-			[ VIDEO_MODE_NTSC  ] = V4L2_STD_NTSC_M,
-			[ VIDEO_MODE_SECAM ] = V4L2_STD_SECAM,
-			[ 4 /* bttv */     ] = V4L2_STD_PAL_M,
-			[ 5 /* bttv */     ] = V4L2_STD_PAL_N,
-			[ 6 /* bttv */     ] = V4L2_STD_NTSC_M_JP,
-		};
-		struct video_channel *vc = arg;
-
-		CHECK_V4L2;
-		t->mode = V4L2_TUNER_ANALOG_TV;
-		if (vc->norm < ARRAY_SIZE(map))
-			t->std = map[vc->norm];
-		tuner_fixup_std(t);
-		if (t->freq)
-			set_tv_freq(client,t->freq);
-		return 0;
-	}
+		{
+			static const v4l2_std_id map[] = {
+				[VIDEO_MODE_PAL] = V4L2_STD_PAL,
+				[VIDEO_MODE_NTSC] = V4L2_STD_NTSC_M,
+				[VIDEO_MODE_SECAM] = V4L2_STD_SECAM,
+				[4 /* bttv */ ] = V4L2_STD_PAL_M,
+				[5 /* bttv */ ] = V4L2_STD_PAL_N,
+				[6 /* bttv */ ] = V4L2_STD_NTSC_M_JP,
+			};
+			struct video_channel *vc = arg;
+
+			if (check_v4l2(t) == EINVAL)
+				return 0;
+
+			if (set_mode(client,t,V4L2_TUNER_ANALOG_TV, "VIDIOCSCHAN")==EINVAL)
+				return 0;
+
+			if (vc->norm < ARRAY_SIZE(map))
+				t->std = map[vc->norm];
+			tuner_fixup_std(t);
+			if (t->freq)
+				set_tv_freq(client, t->freq);
+			return 0;
+		}
 	case VIDIOCSFREQ:
-	{
-		unsigned long *v = arg;
+		{
+			unsigned long *v = arg;
 
-		CHECK_V4L2;
-		set_freq(client,*v);
-		return 0;
-	}
+			if (check_mode(t, "VIDIOCSFREQ") == EINVAL)
+				return 0;
+			if (check_v4l2(t) == EINVAL)
+				return 0;
+
+			set_freq(client, *v);
+			return 0;
+		}
 	case VIDIOCGTUNER:
-	{
-		struct video_tuner *vt = arg;
+		{
+			struct video_tuner *vt = arg;
 
-		CHECK_V4L2;
-		if (V4L2_TUNER_RADIO == t->mode  &&  t->has_signal)
-			vt->signal = t->has_signal(client);
-		return 0;
-	}
+			if (check_mode(t, "VIDIOCGTUNER") == EINVAL)
+				return 0;
+			if (check_v4l2(t) == EINVAL)
+				return 0;
+
+			if (V4L2_TUNER_RADIO == t->mode) {
+				if (t->has_signal)
+					vt->signal = t->has_signal(client);
+				if (t->is_stereo) {
+					if (t->is_stereo(client))
+						vt->flags |=
+						    VIDEO_TUNER_STEREO_ON;
+					else
+						vt->flags &=
+						    ~VIDEO_TUNER_STEREO_ON;
+				}
+				vt->flags |= VIDEO_TUNER_LOW;	/* Allow freqs at 62.5 Hz */
+
+				vt->rangelow = radio_range[0] * 16000;
+				vt->rangehigh = radio_range[1] * 16000;
+
+			} else {
+				vt->rangelow = tv_range[0] * 16;
+				vt->rangehigh = tv_range[1] * 16;
+			}
+
+			return 0;
+		}
 	case VIDIOCGAUDIO:
-	{
-		struct video_audio *va = arg;
+		{
+			struct video_audio *va = arg;
 
-		CHECK_V4L2;
-		if (V4L2_TUNER_RADIO == t->mode  &&  t->is_stereo)
-			va->mode = t->is_stereo(client)
-				? VIDEO_SOUND_STEREO
-				: VIDEO_SOUND_MONO;
-		return 0;
-	}
+			if (check_mode(t, "VIDIOCGAUDIO") == EINVAL)
+				return 0;
+			if (check_v4l2(t) == EINVAL)
+				return 0;
+
+			if (V4L2_TUNER_RADIO == t->mode && t->is_stereo)
+				va->mode = t->is_stereo(client)
+				    ? VIDEO_SOUND_STEREO : VIDEO_SOUND_MONO;
+			return 0;
+		}
 
 	case VIDIOC_S_STD:
-	{
-		v4l2_std_id *id = arg;
+		{
+			v4l2_std_id *id = arg;
 
-		SWITCH_V4L2;
-		t->mode = V4L2_TUNER_ANALOG_TV;
-		t->std = *id;
-		tuner_fixup_std(t);
-		if (t->freq)
-			set_freq(client,t->freq);
-		break;
-	}
+			if (set_mode (client, t, V4L2_TUNER_ANALOG_TV, "VIDIOC_S_STD")
+					== EINVAL)
+				return 0;
+
+			switch_v4l2();
+
+			t->std = *id;
+			tuner_fixup_std(t);
+			if (t->freq)
+				set_freq(client, t->freq);
+			break;
+		}
 	case VIDIOC_S_FREQUENCY:
-	{
-		struct v4l2_frequency *f = arg;
+		{
+			struct v4l2_frequency *f = arg;
 
-		SWITCH_V4L2;
-		if (V4L2_TUNER_RADIO == f->type &&
-		    V4L2_TUNER_RADIO != t->mode)
-			set_tv_freq(client,400*16);
-		t->mode  = f->type;
-		set_freq(client,f->frequency);
-		break;
-	}
+			t->freq = f->frequency;
+			switch_v4l2();
+			if (V4L2_TUNER_RADIO == f->type &&
+			    V4L2_TUNER_RADIO != t->mode) {
+			        if (set_mode (client, t, f->type, "VIDIOC_S_FREQUENCY")
+					    == EINVAL)
+					return 0;
+			}
+			set_freq(client,t->freq);
+
+			break;
+		}
 	case VIDIOC_G_FREQUENCY:
-	{
-		struct v4l2_frequency *f = arg;
+		{
+			struct v4l2_frequency *f = arg;
 
-		SWITCH_V4L2;
-		f->type = t->mode;
-		f->frequency = t->freq;
-		break;
-	}
+			if (check_mode(t, "VIDIOC_G_FREQUENCY") == EINVAL)
+				return 0;
+			switch_v4l2();
+			f->type = t->mode;
+			f->frequency = t->freq;
+			break;
+		}
 	case VIDIOC_G_TUNER:
-	{
-		struct v4l2_tuner *tuner = arg;
+		{
+			struct v4l2_tuner *tuner = arg;
 
-		SWITCH_V4L2;
-		if (V4L2_TUNER_RADIO == t->mode  &&  t->has_signal)
-			tuner->signal = t->has_signal(client);
-		tuner->rangelow = tv_range[0] * 16;
-		tuner->rangehigh = tv_range[1] * 16;
-		break;
-	}
+			if (check_mode(t, "VIDIOC_G_TUNER") == EINVAL)
+				return 0;
+			switch_v4l2();
+
+			if (V4L2_TUNER_RADIO == t->mode) {
+
+				if (t->has_signal)
+					tuner->signal = t->has_signal(client);
+
+				if (t->is_stereo) {
+					if (t->is_stereo(client)) {
+						tuner->rxsubchans =
+						    V4L2_TUNER_SUB_STEREO |
+						    V4L2_TUNER_SUB_MONO;
+					} else {
+						tuner->rxsubchans =
+						    V4L2_TUNER_SUB_MONO;
+					}
+				}
+
+				tuner->capability |=
+				    V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO;
+
+				tuner->audmode = t->audmode;
+
+				tuner->rangelow = radio_range[0] * 16000;
+				tuner->rangehigh = radio_range[1] * 16000;
+			} else {
+				tuner->rangelow = tv_range[0] * 16;
+				tuner->rangehigh = tv_range[1] * 16;
+			}
+			break;
+		}
+	case VIDIOC_S_TUNER:
+		{
+			struct v4l2_tuner *tuner = arg;
+
+			if (check_mode(t, "VIDIOC_S_TUNER") == EINVAL)
+				return 0;
+
+			switch_v4l2();
+
+			if (V4L2_TUNER_RADIO == t->mode) {
+				t->audmode = tuner->audmode;
+				set_radio_freq(client, t->freq);
+			}
+			break;
+		}
 	default:
-		/* nothing */
+		tuner_dbg("Unimplemented IOCTL 0x%08x(dir=%d,tp=0x%02x,nr=%d,sz=%d)\n",
+					 cmd, _IOC_DIR(cmd), _IOC_TYPE(cmd),
+					_IOC_NR(cmd), _IOC_SIZE(cmd));
 		break;
 	}
 
 	return 0;
 }
 
-static int tuner_suspend(struct device * dev, pm_message_t state, u32 level)
+static int tuner_suspend(struct device *dev, u32 state, u32 level)
 {
-	struct i2c_client *c = container_of(dev, struct i2c_client, dev);
-	struct tuner *t = i2c_get_clientdata(c);
+	struct i2c_client *c = container_of (dev, struct i2c_client, dev);
+	struct tuner *t = i2c_get_clientdata (c);
 
-	tuner_dbg("suspend\n");
+	tuner_dbg ("suspend\n");
 	/* FIXME: power down ??? */
 	return 0;
 }
 
-static int tuner_resume(struct device * dev, u32 level)
+static int tuner_resume(struct device *dev, u32 level)
 {
-	struct i2c_client *c = container_of(dev, struct i2c_client, dev);
-	struct tuner *t = i2c_get_clientdata(c);
+	struct i2c_client *c = container_of (dev, struct i2c_client, dev);
+	struct tuner *t = i2c_get_clientdata (c);
 
-	tuner_dbg("resume\n");
+	tuner_dbg ("resume\n");
 	if (t->freq)
-		set_freq(c,t->freq);
+		set_freq(c, t->freq);
 	return 0;
 }
 
 /* ----------------------------------------------------------------------- */
 
 static struct i2c_driver driver = {
-	.owner          = THIS_MODULE,
-        .name           = "tuner",
-        .id             = I2C_DRIVERID_TUNER,
-        .flags          = I2C_DF_NOTIFY,
-        .attach_adapter = tuner_probe,
-        .detach_client  = tuner_detach,
-        .command        = tuner_command,
+	.owner = THIS_MODULE,
+	.name = "tuner",
+	.id = I2C_DRIVERID_TUNER,
+	.flags = I2C_DF_NOTIFY,
+	.attach_adapter = tuner_probe,
+	.detach_client = tuner_detach,
+	.command = tuner_command,
 	.driver = {
-		.suspend = tuner_suspend,
-		.resume  = tuner_resume,
-	},
+		   .suspend = tuner_suspend,
+		   .resume = tuner_resume,
+		   },
 };
-static struct i2c_client client_template =
-{
+static struct i2c_client client_template = {
 	I2C_DEVNAME("(tuner unset)"),
-	.flags      = I2C_CLIENT_ALLOW_USE,
-        .driver     = &driver,
+	.flags = I2C_CLIENT_ALLOW_USE,
+	.driver = &driver,
 };
 
 static int __init tuner_init_module(void)
diff --git a/drivers/media/video/tuner-simple.c b/drivers/media/video/tuner-simple.c
--- a/drivers/media/video/tuner-simple.c
+++ b/drivers/media/video/tuner-simple.c
@@ -1,5 +1,5 @@
 /*
- * $Id: tuner-simple.c,v 1.10 2005/03/08 08:38:00 kraxel Exp $
+ * $Id: tuner-simple.c,v 1.43 2005/07/28 18:41:21 mchehab Exp $
  *
  * i2c tv tuner chip device driver
  * controls all those simple 4-control-bytes style tuners.
@@ -54,6 +54,27 @@
 #define PHILIPS_MF_SET_PAL_L	0x03 // France
 #define PHILIPS_MF_SET_PAL_L2	0x02 // L'
 
+/* Control byte */
+
+#define TUNER_RATIO_MASK        0x06 /* Bit cb1:cb2 */
+#define TUNER_RATIO_SELECT_50   0x00
+#define TUNER_RATIO_SELECT_32   0x02
+#define TUNER_RATIO_SELECT_166  0x04
+#define TUNER_RATIO_SELECT_62   0x06
+
+#define TUNER_CHARGE_PUMP       0x40  /* Bit cb6 */
+
+/* Status byte */
+
+#define TUNER_POR	  0x80
+#define TUNER_FL          0x40
+#define TUNER_MODE        0x38
+#define TUNER_AFC         0x07
+#define TUNER_SIGNAL      0x07
+#define TUNER_STEREO      0x10
+
+#define TUNER_PLL_LOCKED   0x40
+#define TUNER_STEREO_MK3   0x04
 
 /* ---------------------------------------------------------------------- */
 
@@ -207,12 +228,31 @@ static struct tunertype tuners[] = {
 	{ "LG PAL (TAPE series)", LGINNOTEK, PAL,
           16*170.00, 16*450.00, 0x01,0x02,0x08,0xce,623},
 
-        { "Philips PAL/SECAM multi (FQ1216AME MK4)", Philips, PAL,
-          16*160.00,16*442.00,0x01,0x02,0x04,0xce,623 },
-        { "Philips FQ1236A MK4", Philips, NTSC,
-          16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732 },
+	{ "Philips PAL/SECAM multi (FQ1216AME MK4)", Philips, PAL,
+	  16*160.00,16*442.00,0x01,0x02,0x04,0xce,623 },
+	{ "Philips FQ1236A MK4", Philips, NTSC,
+	  16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732 },
+	{ "Ymec TVision TVF-8531MF/8831MF/8731MF", Philips, NTSC,
+	  16*160.00,16*454.00,0xa0,0x90,0x30,0x8e,732},
+	{ "Ymec TVision TVF-5533MF", Philips, NTSC,
+	  16*160.00,16*454.00,0x01,0x02,0x04,0x8e,732},
+
+	{ "Thomson DDT 7611 (ATSC/NTSC)", THOMSON, ATSC,
+	  16*157.25,16*454.00,0x39,0x3a,0x3c,0x8e,732},
+	{ "Tena TNF9533-D/IF/TNF9533-B/DF", Philips, PAL,
+          16*160.25,16*464.25,0x01,0x02,0x04,0x8e,623},
+	{ "Philips TEA5767HN FM Radio", Philips, RADIO,
+          /* see tea5767.c for details */},
+	{ "Philips FMD1216ME MK3 Hybrid Tuner", Philips, PAL,
+	  16*160.00,16*442.00,0x51,0x52,0x54,0x86,623 },
+
+	{ "LG TDVS-H062F/TUA6034", LGINNOTEK, NTSC,
+	  16*160.00,16*455.00,0x01,0x02,0x04,0x8e,732},
 
+	{ "Ymec TVF66T5-B/DFF", Philips, PAL,
+          16*160.25,16*464.25,0x01,0x02,0x08,0x8e,623},
 };
+
 unsigned const int tuner_count = ARRAY_SIZE(tuners);
 
 /* ---------------------------------------------------------------------- */
@@ -223,43 +263,35 @@ static int tuner_getstatus(struct i2c_cl
 
 	if (1 != i2c_master_recv(c,&byte,1))
 		return 0;
+
 	return byte;
 }
 
-#define TUNER_POR       0x80
-#define TUNER_FL        0x40
-#define TUNER_MODE      0x38
-#define TUNER_AFC       0x07
-
-#define TUNER_STEREO    0x10 /* radio mode */
-#define TUNER_SIGNAL    0x07 /* radio mode */
-
 static int tuner_signal(struct i2c_client *c)
 {
-	return (tuner_getstatus(c) & TUNER_SIGNAL)<<13;
+	return (tuner_getstatus(c) & TUNER_SIGNAL) << 13;
 }
 
 static int tuner_stereo(struct i2c_client *c)
 {
-	return (tuner_getstatus (c) & TUNER_STEREO);
-}
+	int stereo, status;
+	struct tuner *t = i2c_get_clientdata(c);
 
-#if 0 /* unused */
-static int tuner_islocked (struct i2c_client *c)
-{
-        return (tuner_getstatus (c) & TUNER_FL);
-}
+	status = tuner_getstatus (c);
 
-static int tuner_afcstatus (struct i2c_client *c)
-{
-        return (tuner_getstatus (c) & TUNER_AFC) - 2;
-}
+	switch (t->type) {
+        	case TUNER_PHILIPS_FM1216ME_MK3:
+    		case TUNER_PHILIPS_FM1236_MK3:
+		case TUNER_PHILIPS_FM1256_IH3:
+			stereo = ((status & TUNER_SIGNAL) == TUNER_STEREO_MK3);
+			break;
+		default:
+			stereo = status & TUNER_STEREO;
+	}
 
-static int tuner_mode (struct i2c_client *c)
-{
-        return (tuner_getstatus (c) & TUNER_MODE) >> 3;
+	return stereo;
 }
-#endif
+
 
 /* ---------------------------------------------------------------------- */
 
@@ -342,7 +374,7 @@ static void default_set_tv_freq(struct i
 
 	case TUNER_MICROTUNE_4042FI5:
 		/* Set the charge pump for fast tuning */
-		tun->config |= 0x40;
+		tun->config |= TUNER_CHARGE_PUMP;
 		break;
 	}
 
@@ -391,14 +423,13 @@ static void default_set_tv_freq(struct i
 				tuner_warn("i2c i/o read error: rc == %d (should be 1)\n",rc);
 				break;
 			}
-			/* bit 6 is PLL locked indicator */
-			if (status_byte & 0x40)
+			if (status_byte & TUNER_PLL_LOCKED)
 				break;
 			udelay(10);
 		}
 
 		/* Set the charge pump for optimized phase noise figure */
-		tun->config &= ~0x40;
+		tun->config &= ~TUNER_CHARGE_PUMP;
 		buffer[0] = (div>>8) & 0x7f;
 		buffer[1] = div      & 0xff;
 		buffer[2] = tun->config;
@@ -419,18 +450,22 @@ static void default_set_radio_freq(struc
 	unsigned div;
 	int rc;
 
-	tun=&tuners[t->type];
-	div = freq + (int)(16*10.7);
-	buffer[2] = tun->config;
+	tun = &tuners[t->type];
+	div = (20 * freq / 16000) + (int)(20*10.7); /* IF 10.7 MHz */
+	buffer[2] = (tun->config & ~TUNER_RATIO_MASK) | TUNER_RATIO_SELECT_50; /* 50 kHz step */
 
 	switch (t->type) {
+	case TUNER_TENA_9533_DI:
+	case TUNER_YMEC_TVF_5533MF:
+		tuner_dbg ("This tuner doesn't have FM. Most cards has a TEA5767 for FM\n");
+		return;
 	case TUNER_PHILIPS_FM1216ME_MK3:
 	case TUNER_PHILIPS_FM1236_MK3:
+	case TUNER_PHILIPS_FMD1216ME_MK3:
 		buffer[3] = 0x19;
 		break;
 	case TUNER_PHILIPS_FM1256_IH3:
-		div = (20 * freq)/16 + 333 * 2;
-	        buffer[2] = 0x80;
+		div = (20 * freq) / 16000 + (int)(33.3 * 20);  /* IF 33.3 MHz */
 		buffer[3] = 0x19;
 		break;
 	case TUNER_LG_PAL_FM:
@@ -462,6 +497,7 @@ int default_tuner_init(struct i2c_client
 	t->radio_freq = default_set_radio_freq;
 	t->has_signal = tuner_signal;
 	t->is_stereo  = tuner_stereo;
+
 	return 0;
 }
 
diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c
--- a/drivers/media/video/tvaudio.c
+++ b/drivers/media/video/tvaudio.c
@@ -148,7 +148,6 @@ static unsigned short normal_i2c[] = {
 	I2C_TDA9874   >> 1,
 	I2C_PIC16C54  >> 1,
 	I2C_CLIENT_END };
-static unsigned short normal_i2c_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
 I2C_CLIENT_INSMOD;
 
 static struct i2c_driver driver;
@@ -286,7 +285,7 @@ static int chip_thread(void *data)
 			schedule();
 		}
 		remove_wait_queue(&chip->wq, &wait);
-		try_to_freeze(PF_FREEZE);
+		try_to_freeze();
 		if (chip->done || signal_pending(current))
 			break;
 		dprintk("%s: thread wakeup\n", i2c_clientname(&chip->c));
@@ -866,13 +865,8 @@ static int tda9874a_getmode(struct CHIPS
 		 * But changing the mode to VIDEO_SOUND_MONO would switch
 		 * external 4052 multiplexer in audio_hook().
 		 */
-#if 0
-		if((nsr & 0x02) && !(dsr & 0x10)) /* NSR.S/MB=1 and DSR.AMSTAT=0 */
-			mode |= VIDEO_SOUND_STEREO;
-#else
 		if(nsr & 0x02) /* NSR.S/MB=1 */
 			mode |= VIDEO_SOUND_STEREO;
-#endif
 		if(nsr & 0x01) /* NSR.D/SB=1 */
 			mode |= VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
 	} else {
@@ -1238,17 +1232,17 @@ static int ta8874z_checkit(struct CHIPST
 /* audio chip descriptions - struct CHIPDESC                              */
 
 /* insmod options to enable/disable individual audio chips */
-int tda8425  = 1;
-int tda9840  = 1;
-int tda9850  = 1;
-int tda9855  = 1;
-int tda9873  = 1;
-int tda9874a = 1;
-int tea6300  = 0;  // address clash with msp34xx
-int tea6320  = 0;  // address clash with msp34xx
-int tea6420  = 1;
-int pic16c54 = 1;
-int ta8874z  = 0;  // address clash with tda9840
+static int tda8425  = 1;
+static int tda9840  = 1;
+static int tda9850  = 1;
+static int tda9855  = 1;
+static int tda9873  = 1;
+static int tda9874a = 1;
+static int tea6300  = 0;  // address clash with msp34xx
+static int tea6320  = 0;  // address clash with msp34xx
+static int tea6420  = 1;
+static int pic16c54 = 1;
+static int ta8874z  = 0;  // address clash with tda9840
 
 module_param(tda8425, int, 0444);
 module_param(tda9840, int, 0444);
diff --git a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c
--- a/drivers/media/video/tveeprom.c
+++ b/drivers/media/video/tveeprom.c
@@ -75,7 +75,7 @@ hauppauge_tuner_fmt[] =
 	{ 0x00000007, "PAL(B/G)" },
 	{ 0x00001000, "NTSC(M)" },
 	{ 0x00000010, "PAL(I)" },
-	{ 0x00400000, "SECAM(L/Lï¿½)" },
+	{ 0x00400000, "SECAM(L/L´)" },
 	{ 0x00000e00, "PAL(D/K)" },
 	{ 0x03000000, "ATSC Digital" },
 };
@@ -189,7 +189,7 @@ hauppauge_tuner[] =
 	{ TUNER_ABSENT,        "Philips FQ1236 MK3"},
 	{ TUNER_ABSENT,        "Samsung TCPN 2121P30A"},
 	{ TUNER_ABSENT,        "Samsung TCPE 4121P30A"},
-	{ TUNER_ABSENT,        "TCL MFPE05 2"},
+	{ TUNER_PHILIPS_FM1216ME_MK3, "TCL MFPE05 2"},
 	/* 90-99 */
 	{ TUNER_ABSENT,        "LG TALN H202T"},
 	{ TUNER_PHILIPS_FQ1216AME_MK4, "Philips FQ1216AME MK4"},
@@ -400,14 +400,6 @@ void tveeprom_hauppauge_analog(struct tv
 		}
 	}
 
-#if 0
-	if (t_format < sizeof(hauppauge_tuner_fmt)/sizeof(struct HAUPPAUGE_TUNER_FMT)) {
-		tvee->tuner_formats = hauppauge_tuner_fmt[t_format].id;
-		t_fmt_name = hauppauge_tuner_fmt[t_format].name;
-	} else {
-		t_fmt_name = "<unknown>";
-	}
-#endif
 
 	TVEEPROM_KERN_INFO("Hauppauge: model = %d, rev = %s, serial# = %d\n",
 		   tvee->model,
@@ -453,6 +445,7 @@ int tveeprom_read(struct i2c_client *c, 
 }
 EXPORT_SYMBOL(tveeprom_read);
 
+#if 0
 int tveeprom_dump(unsigned char *eedata, int len)
 {
 	int i;
@@ -468,6 +461,7 @@ int tveeprom_dump(unsigned char *eedata,
 	return 0;
 }
 EXPORT_SYMBOL(tveeprom_dump);
+#endif  /*  0  */
 
 /* ----------------------------------------------------------------------- */
 /* needed for ivtv.sf.net at the moment.  Should go away in the long       */
@@ -482,10 +476,10 @@ static unsigned short normal_i2c[] = {
 	0xa0 >> 1,
 	I2C_CLIENT_END,
 };
-static unsigned short normal_i2c_range[] = { I2C_CLIENT_END };
+
 I2C_CLIENT_INSMOD;
 
-struct i2c_driver i2c_driver_tveeprom;
+static struct i2c_driver i2c_driver_tveeprom;
 
 static int
 tveeprom_command(struct i2c_client *client,
@@ -557,7 +551,7 @@ tveeprom_detach_client (struct i2c_clien
 	return 0;
 }
 
-struct i2c_driver i2c_driver_tveeprom = {
+static struct i2c_driver i2c_driver_tveeprom = {
 	.owner          = THIS_MODULE,
 	.name           = "tveeprom",
 	.id             = I2C_DRIVERID_TVEEPROM,
diff --git a/drivers/media/video/tvmixer.c b/drivers/media/video/tvmixer.c
--- a/drivers/media/video/tvmixer.c
+++ b/drivers/media/video/tvmixer.c
@@ -1,3 +1,7 @@
+/*
+ * $Id: tvmixer.c,v 1.8 2005/06/12 04:19:19 mchehab Exp $
+ */
+
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/kernel.h>
diff --git a/drivers/media/video/v4l1-compat.c b/drivers/media/video/v4l1-compat.c
--- a/drivers/media/video/v4l1-compat.c
+++ b/drivers/media/video/v4l1-compat.c
@@ -1,4 +1,6 @@
 /*
+ * $Id: v4l1-compat.c,v 1.9 2005/06/12 04:19:19 mchehab Exp $
+ *
  *	Video for Linux Two
  *	Backward Compatibility Layer
  *
@@ -15,14 +17,11 @@
  *
  */
 
-#ifndef __KERNEL__
-#define __KERNEL__
-#endif
-
 #include <linux/config.h>
 
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/moduleparam.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
@@ -787,12 +786,15 @@ v4l_compat_translate_ioctl(struct inode 
 		    !(qctrl2.flags & V4L2_CTRL_FLAG_DISABLED))
 			aud->step = qctrl2.step;
 		aud->mode = 0;
+
+		memset(&tun2,0,sizeof(tun2));
 		err = drv(inode, file, VIDIOC_G_TUNER, &tun2);
 		if (err < 0) {
 			dprintk("VIDIOCGAUDIO / VIDIOC_G_TUNER: %d\n",err);
 			err = 0;
 			break;
 		}
+
 		if (tun2.rxsubchans & V4L2_TUNER_SUB_LANG2)
 			aud->mode = VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
 		else if (tun2.rxsubchans & V4L2_TUNER_SUB_STEREO)
diff --git a/drivers/media/video/video-buf-dvb.c b/drivers/media/video/video-buf-dvb.c
--- a/drivers/media/video/video-buf-dvb.c
+++ b/drivers/media/video/video-buf-dvb.c
@@ -62,8 +62,7 @@ static int videobuf_dvb_thread(void *dat
 			break;
 		if (kthread_should_stop())
 			break;
-		if (current->flags & PF_FREEZE)
-			refrigerator(PF_FREEZE);
+		try_to_freeze();
 
 		/* feed buffer data to demux */
 		if (buf->state == STATE_DONE)
diff --git a/drivers/media/video/vpx3220.c b/drivers/media/video/vpx3220.c
--- a/drivers/media/video/vpx3220.c
+++ b/drivers/media/video/vpx3220.c
@@ -569,22 +569,14 @@ static unsigned short normal_i2c[] =
     { I2C_VPX3220 >> 1, (I2C_VPX3220 >> 1) + 4,
 	I2C_CLIENT_END
 };
-static unsigned short normal_i2c_range[] = { I2C_CLIENT_END };
 
-static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short probe_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short ignore_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
-static unsigned short force[2] = { I2C_CLIENT_END , I2C_CLIENT_END };
+static unsigned short ignore = I2C_CLIENT_END;
                                                                                 
 static struct i2c_client_address_data addr_data = {
 	.normal_i2c		= normal_i2c,
-	.normal_i2c_range	= normal_i2c_range,
-	.probe			= probe,
-	.probe_range		= probe_range,
-	.ignore			= ignore,
-	.ignore_range		= ignore_range,
-	.force			= force
+	.probe			= &ignore,
+	.ignore			= &ignore,
+	.force			= &ignore,
 };
 
 static struct i2c_driver vpx3220_i2c_driver;
diff --git a/drivers/message/fusion/Kconfig b/drivers/message/fusion/Kconfig
--- a/drivers/message/fusion/Kconfig
+++ b/drivers/message/fusion/Kconfig
@@ -2,34 +2,54 @@
 menu "Fusion MPT device support"
 
 config FUSION
-	tristate "Fusion MPT (base + ScsiHost) drivers"
+	bool
+	default n
+
+config FUSION_SPI
+	tristate "Fusion MPT ScsiHost drivers for SPI"
+	depends on PCI && SCSI
+	select FUSION
+	---help---
+	  SCSI HOST support for a parallel SCSI host adapters.
+
+	  List of supported controllers:
+
+	  LSI53C1020
+	  LSI53C1020A
+	  LSI53C1030
+	  LSI53C1035
+
+config FUSION_FC
+	tristate "Fusion MPT ScsiHost drivers for FC"
 	depends on PCI && SCSI
+	select FUSION
 	---help---
-	  LSI Logic Fusion(TM) Message Passing Technology (MPT) device support
-	  provides high performance SCSI host initiator, and LAN [1] interface
-	  services to a host system.  The Fusion architecture is capable of
-	  duplexing these protocols on high-speed Fibre Channel
-	  (up to 2 GHz x 2 ports = 4 GHz) and parallel SCSI (up to Ultra-320)
-	  physical medium.
+	  SCSI HOST support for a Fiber Channel host adapters.
 
-	  [1] LAN is not supported on parallel SCSI medium.
+	  List of supported controllers:
+
+	  LSIFC909
+	  LSIFC919
+	  LSIFC919X
+	  LSIFC929
+	  LSIFC929X
+	  LSIFC929XL
 
 config FUSION_MAX_SGE
-	int "Maximum number of scatter gather entries"
+	int "Maximum number of scatter gather entries (16 - 128)"
 	depends on FUSION
-	default "40"
+	default "128"
+	range 16 128
 	help
 	  This option allows you to specify the maximum number of scatter-
-	  gather entries per I/O. The driver defaults to 40, a reasonable number
-	  for most systems. However, the user may increase this up to 128.
-	  Increasing this parameter will require significantly more memory 
-	  on a per controller instance. Increasing the parameter is not
-	  necessary (or recommended) unless the user will be running 
-	  large I/O's via the raw interface.
+	  gather entries per I/O. The driver default is 128, which matches
+	  SCSI_MAX_PHYS_SEGMENTS. However, it may decreased down to 16.
+	  Decreasing this parameter will reduce memory requirements
+	  on a per controller instance.
 
 config FUSION_CTL
 	tristate "Fusion MPT misc device (ioctl) driver"
-	depends on FUSION
+	depends on FUSION_SPI || FUSION_FC
 	---help---
 	  The Fusion MPT misc device driver provides specialized control
 	  of MPT adapters via system ioctl calls.  Use of ioctl calls to
@@ -48,7 +68,7 @@ config FUSION_CTL
 
 config FUSION_LAN
 	tristate "Fusion MPT LAN driver"
-	depends on FUSION && NET_FC
+	depends on FUSION_FC && NET_FC
 	---help---
 	  This module supports LAN IP traffic over Fibre Channel port(s)
 	  on Fusion MPT compatible hardware (LSIFC9xx chips).
diff --git a/drivers/message/fusion/Makefile b/drivers/message/fusion/Makefile
--- a/drivers/message/fusion/Makefile
+++ b/drivers/message/fusion/Makefile
@@ -1,52 +1,38 @@
-#
-# Makefile for the LSI Logic Fusion MPT (Message Passing Technology) drivers.
-#
-# Note! If you want to turn on various debug defines for an extended period of
-# time but don't want them lingering around in the Makefile when you pass it on
-# to someone else, use the MPT_CFLAGS env variable (thanks Steve). -nromer
-
-#=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-{ LSI_LOGIC
-
-#  Architecture-specific...
-#			# intel
-#EXTRA_CFLAGS += -g
-#			# sparc64
-#EXTRA_CFLAGS += -gstabs+
-
-EXTRA_CFLAGS += ${MPT_CFLAGS}
-
 # Fusion MPT drivers; recognized debug defines...
 #  MPT general:
-#EXTRA_CFLAGS += -DMPT_DEBUG_SCSI
 #EXTRA_CFLAGS += -DMPT_DEBUG
 #EXTRA_CFLAGS += -DMPT_DEBUG_MSG_FRAME
 #EXTRA_CFLAGS += -DMPT_DEBUG_SG
+#EXTRA_CFLAGS += -DMPT_DEBUG_EVENTS
+#EXTRA_CFLAGS += -DMPT_DEBUG_INIT
+#EXTRA_CFLAGS += -DMPT_DEBUG_EXIT
+#EXTRA_CFLAGS += -DMPT_DEBUG_FAIL
+
 
 #
 # driver/module specifics...
 #
 #  For mptbase:
 #CFLAGS_mptbase.o += -DMPT_DEBUG_HANDSHAKE
+#CFLAGS_mptbase.o += -DMPT_DEBUG_CONFIG
+#CFLAGS_mptbase.o += -DMPT_DEBUG_DL
 #CFLAGS_mptbase.o += -DMPT_DEBUG_IRQ
+#CFLAGS_mptbase.o += -DMPT_DEBUG_RESET
 #
 #  For mptscsih:
-#CFLAGS_mptscsih.o += -DMPT_DEBUG_SCANDV
-#CFLAGS_mptscsih.o += -DMPT_DEBUG_RESET
-#CFLAGS_mptscsih.o += -DMPT_DEBUG_NEH
+#CFLAGS_mptscsih.o += -DMPT_DEBUG_DV
+#CFLAGS_mptscsih.o += -DMPT_DEBUG_NEGO
+#CFLAGS_mptscsih.o += -DMPT_DEBUG_TM
+#CFLAGS_mptscsih.o += -DMPT_DEBUG_SCSI
+#CFLAGS_mptscsih.o += -DMPT_DEBUG_REPLY
 #
 #  For mptctl:
 #CFLAGS_mptctl.o += -DMPT_DEBUG_IOCTL
 #
-#  For mptlan:
-#CFLAGS_mptlan.o += -DMPT_LAN_IO_DEBUG
-#
-#  For isense:
-
-#  EXP...
-##mptscsih-objs	:= scsihost.o scsiherr.o
 
 #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-} LSI_LOGIC
 
-obj-$(CONFIG_FUSION)		+= mptbase.o mptscsih.o
+obj-$(CONFIG_FUSION_SPI)	+= mptbase.o mptscsih.o mptspi.o
+obj-$(CONFIG_FUSION_FC)		+= mptbase.o mptscsih.o mptfc.o
 obj-$(CONFIG_FUSION_CTL)	+= mptctl.o
 obj-$(CONFIG_FUSION_LAN)	+= mptlan.o
diff --git a/drivers/message/fusion/lsi/mpi.h b/drivers/message/fusion/lsi/mpi.h
--- a/drivers/message/fusion/lsi/mpi.h
+++ b/drivers/message/fusion/lsi/mpi.h
@@ -1,12 +1,12 @@
 /*
- *  Copyright (c) 2000-2003 LSI Logic Corporation.
+ *  Copyright (c) 2000-2005 LSI Logic Corporation.
  *
  *
  *           Name:  mpi.h
  *          Title:  MPI Message independent structures and definitions
  *  Creation Date:  July 27, 2000
  *
- *    mpi.h Version:  01.05.xx
+ *    mpi.h Version:  01.05.07
  *
  *  Version History
  *  ---------------
@@ -52,6 +52,25 @@
  *                      obsoleted define MPI_IOCSTATUS_TARGET_INVALID_IOCINDEX.
  *  04-01-03  01.02.09  New IOCStatus code: MPI_IOCSTATUS_FC_EXCHANGE_CANCELED
  *  06-26-03  01.02.10  Bumped MPI_HEADER_VERSION_UNIT value.
+ *  01-16-04  01.02.11  Added define for MPI_IOCLOGINFO_TYPE_SHIFT.
+ *  04-29-04  01.02.12  Added function codes for MPI_FUNCTION_DIAG_BUFFER_POST
+ *                      and MPI_FUNCTION_DIAG_RELEASE.
+ *                      Added MPI_IOCSTATUS_DIAGNOSTIC_RELEASED define.
+ *                      Bumped MPI_HEADER_VERSION_UNIT value.
+ *  05-11-04  01.03.01  Bumped MPI_VERSION_MINOR for MPI v1.3.
+ *                      Added codes for Inband.
+ *  08-19-04  01.05.01  Added defines for Host Buffer Access Control doorbell.
+ *                      Added define for offset of High Priority Request Queue.
+ *                      Added new function codes and new IOCStatus codes.
+ *                      Added a IOCLogInfo type of SAS.
+ *  12-07-04  01.05.02  Bumped MPI_HEADER_VERSION_UNIT.
+ *  12-09-04  01.05.03  Bumped MPI_HEADER_VERSION_UNIT.
+ *  01-15-05  01.05.04  Bumped MPI_HEADER_VERSION_UNIT.
+ *  02-09-05  01.05.05  Bumped MPI_HEADER_VERSION_UNIT.
+ *  02-22-05  01.05.06  Bumped MPI_HEADER_VERSION_UNIT.
+ *  03-11-05  01.05.07  Removed function codes for SCSI IO 32 and
+ *                      TargetAssistExtended requests.
+ *                      Removed EEDP IOCStatus codes.
  *  --------------------------------------------------------------------------
  */
 
@@ -82,7 +101,7 @@
 /* Note: The major versions of 0xe0 through 0xff are reserved */
 
 /* versioning for this MPI header set */
-#define MPI_HEADER_VERSION_UNIT             (0x00)
+#define MPI_HEADER_VERSION_UNIT             (0x09)
 #define MPI_HEADER_VERSION_DEV              (0x00)
 #define MPI_HEADER_VERSION_UNIT_MASK        (0xFF00)
 #define MPI_HEADER_VERSION_UNIT_SHIFT       (8)
@@ -122,7 +141,11 @@
 *
 *****************************************************************************/
 
-/* S y s t e m    D o o r b e l l */
+/*
+ * Defines for working with the System Doorbell register.
+ * Values for doorbell function codes are included in the section that defines
+ * all the function codes (further on in this file).
+ */
 #define MPI_DOORBELL_OFFSET                 (0x00000000)
 #define MPI_DOORBELL_ACTIVE                 (0x08000000) /* DoorbellUsed */
 #define MPI_DOORBELL_USED                   (MPI_DOORBELL_ACTIVE)
@@ -134,6 +157,13 @@
 #define MPI_DOORBELL_ADD_DWORDS_MASK        (0x00FF0000)
 #define MPI_DOORBELL_ADD_DWORDS_SHIFT       (16)
 #define MPI_DOORBELL_DATA_MASK              (0x0000FFFF)
+#define MPI_DOORBELL_FUNCTION_SPECIFIC_MASK (0x0000FFFF)
+
+/* values for Host Buffer Access Control doorbell function */
+#define MPI_DB_HPBAC_VALUE_MASK             (0x0000F000)
+#define MPI_DB_HPBAC_ENABLE_ACCESS          (0x01)
+#define MPI_DB_HPBAC_DISABLE_ACCESS         (0x02)
+#define MPI_DB_HPBAC_FREE_BUFFER            (0x03)
 
 
 #define MPI_WRITE_SEQUENCE_OFFSET           (0x00000004)
@@ -257,16 +287,18 @@
 
 #define MPI_FUNCTION_SMP_PASSTHROUGH                (0x1A)
 #define MPI_FUNCTION_SAS_IO_UNIT_CONTROL            (0x1B)
+#define MPI_FUNCTION_SATA_PASSTHROUGH               (0x1C)
 
-#define MPI_DIAG_BUFFER_POST                        (0x1D)
-#define MPI_DIAG_RELEASE                            (0x1E)
-
-#define MPI_FUNCTION_SCSI_IO_32                     (0x1F)
+#define MPI_FUNCTION_DIAG_BUFFER_POST               (0x1D)
+#define MPI_FUNCTION_DIAG_RELEASE                   (0x1E)
 
 #define MPI_FUNCTION_LAN_SEND                       (0x20)
 #define MPI_FUNCTION_LAN_RECEIVE                    (0x21)
 #define MPI_FUNCTION_LAN_RESET                      (0x22)
 
+#define MPI_FUNCTION_TARGET_CMD_BUF_BASE_POST       (0x24)
+#define MPI_FUNCTION_TARGET_CMD_BUF_LIST_POST       (0x25)
+
 #define MPI_FUNCTION_INBAND_BUFFER_POST             (0x28)
 #define MPI_FUNCTION_INBAND_SEND                    (0x29)
 #define MPI_FUNCTION_INBAND_RSP                     (0x2A)
@@ -276,6 +308,7 @@
 #define MPI_FUNCTION_IO_UNIT_RESET                  (0x41)
 #define MPI_FUNCTION_HANDSHAKE                      (0x42)
 #define MPI_FUNCTION_REPLY_FRAME_REMOVAL            (0x43)
+#define MPI_FUNCTION_HOST_PAGEBUF_ACCESS_CONTROL    (0x44)
 
 
 /* standard version format */
@@ -328,8 +361,8 @@ typedef struct _SGE_SIMPLE_UNION
         U32                 Address32;
         U64                 Address64;
     }u;
-} SGESimpleUnion_t, MPI_POINTER pSGESimpleUnion_t,
-  SGE_SIMPLE_UNION, MPI_POINTER PTR_SGE_SIMPLE_UNION;
+} SGE_SIMPLE_UNION, MPI_POINTER PTR_SGE_SIMPLE_UNION,
+  SGESimpleUnion_t, MPI_POINTER pSGESimpleUnion_t;
 
 /****************************************************************************/
 /*  Chain element structures                                                */
@@ -648,27 +681,21 @@ typedef struct _MSG_DEFAULT_REPLY
 #define MPI_IOCSTATUS_SCSI_EXT_TERMINATED       (0x004C)
 
 /****************************************************************************/
-/*  For use by SCSI Initiator and SCSI Target end-to-end data protection    */
-/****************************************************************************/
-
-#define MPI_IOCSTATUS_EEDP_CRC_ERROR            (0x004D)
-#define MPI_IOCSTATUS_EEDP_LBA_TAG_ERROR        (0x004E)
-#define MPI_IOCSTATUS_EEDP_APP_TAG_ERROR        (0x004F)
-
-
-/****************************************************************************/
-/*  SCSI (SPI & FCP) target values                                          */
+/*  SCSI Target values                                                      */
 /****************************************************************************/
 
 #define MPI_IOCSTATUS_TARGET_PRIORITY_IO         (0x0060)
 #define MPI_IOCSTATUS_TARGET_INVALID_PORT        (0x0061)
-#define MPI_IOCSTATUS_TARGET_INVALID_IOCINDEX    (0x0062)   /* obsolete */
+#define MPI_IOCSTATUS_TARGET_INVALID_IOCINDEX    (0x0062)   /* obsolete name */
 #define MPI_IOCSTATUS_TARGET_INVALID_IO_INDEX    (0x0062)
 #define MPI_IOCSTATUS_TARGET_ABORTED             (0x0063)
 #define MPI_IOCSTATUS_TARGET_NO_CONN_RETRYABLE   (0x0064)
 #define MPI_IOCSTATUS_TARGET_NO_CONNECTION       (0x0065)
 #define MPI_IOCSTATUS_TARGET_XFER_COUNT_MISMATCH (0x006A)
 #define MPI_IOCSTATUS_TARGET_STS_DATA_NOT_SENT   (0x006B)
+#define MPI_IOCSTATUS_TARGET_DATA_OFFSET_ERROR   (0x006D)
+#define MPI_IOCSTATUS_TARGET_TOO_MUCH_WRITE_DATA (0x006E)
+#define MPI_IOCSTATUS_TARGET_IU_TOO_SHORT        (0x006F)
 
 /****************************************************************************/
 /*  Additional FCP target values (obsolete)                                 */
@@ -707,6 +734,7 @@ typedef struct _MSG_DEFAULT_REPLY
 /****************************************************************************/
 
 #define MPI_IOCSTATUS_SAS_SMP_REQUEST_FAILED    (0x0090)
+#define MPI_IOCSTATUS_SAS_SMP_DATA_OVERRUN      (0x0091)
 
 /****************************************************************************/
 /*  Inband values                                                           */
diff --git a/drivers/message/fusion/lsi/mpi_cnfg.h b/drivers/message/fusion/lsi/mpi_cnfg.h
--- a/drivers/message/fusion/lsi/mpi_cnfg.h
+++ b/drivers/message/fusion/lsi/mpi_cnfg.h
@@ -1,12 +1,12 @@
 /*
- *  Copyright (c) 2000-2003 LSI Logic Corporation.
+ *  Copyright (c) 2000-2005 LSI Logic Corporation.
  *
  *
  *           Name:  mpi_cnfg.h
  *          Title:  MPI Config message, structures, and Pages
  *  Creation Date:  July 27, 2000
  *
- *    mpi_cnfg.h Version:  01.05.xx
+ *    mpi_cnfg.h Version:  01.05.08
  *
  *  Version History
  *  ---------------
@@ -145,6 +145,93 @@
  *                      In CONFIG_PAGE_FC_DEVICE_0, replaced Reserved1 field
  *                      with ADISCHardALPA.
  *                      Added MPI_FC_DEVICE_PAGE0_PROT_FCP_RETRY define.
+ *  01-16-04 01.02.13   Added InitiatorDeviceTimeout and InitiatorIoPendTimeout
+ *                      fields and related defines to CONFIG_PAGE_FC_PORT_1.
+ *                      Added define for
+ *                      MPI_FCPORTPAGE1_FLAGS_SOFT_ALPA_FALLBACK.
+ *                      Added new fields to the substructures of
+ *                      CONFIG_PAGE_FC_PORT_10.
+ *  04-29-04 01.02.14   Added define for IDP bit for CONFIG_PAGE_SCSI_PORT_0,
+ *                      CONFIG_PAGE_SCSI_DEVICE_0, and
+ *                      CONFIG_PAGE_SCSI_DEVICE_1. Also bumped Page Version for
+ *                      these pages.
+ *  05-11-04 01.03.01   Added structure for CONFIG_PAGE_INBAND_0.
+ *  08-19-04 01.05.01   Modified MSG_CONFIG request to support extended config
+ *                      pages.
+ *                      Added a new structure for extended config page header.
+ *                      Added new extended config pages types and structures for
+ *                      SAS IO Unit, SAS Expander, SAS Device, and SAS PHY.
+ *                      Replaced a reserved byte in CONFIG_PAGE_MANUFACTURING_4
+ *                      to add a Flags field.
+ *                      Two new Manufacturing config pages (5 and 6).
+ *                      Two new bits defined for IO Unit Page 1 Flags field.
+ *                      Modified CONFIG_PAGE_IO_UNIT_2 to add three new fields
+ *                      to specify the BIOS boot device.
+ *                      Four new Flags bits defined for IO Unit Page 2.
+ *                      Added IO Unit Page 4.
+ *                      Added EEDP Flags settings to IOC Page 1.
+ *                      Added new BIOS Page 1 config page.
+ *  10-05-04 01.05.02   Added define for
+ *                      MPI_IOCPAGE1_INITIATOR_CONTEXT_REPLY_DISABLE.
+ *                      Added new Flags field to CONFIG_PAGE_MANUFACTURING_5 and
+ *                      associated defines.
+ *                      Added more defines for SAS IO Unit Page 0
+ *                      DiscoveryStatus field.
+ *                      Added define for MPI_SAS_IOUNIT0_DS_SUBTRACTIVE_LINK
+ *                      and MPI_SAS_IOUNIT0_DS_TABLE_LINK.
+ *                      Added defines for Physical Mapping Modes to SAS IO Unit
+ *                      Page 2.
+ *                      Added define for
+ *                      MPI_SAS_DEVICE0_FLAGS_PORT_SELECTOR_ATTACH.
+ *  10-27-04 01.05.03   Added defines for new SAS PHY page addressing mode.
+ *                      Added defines for MaxTargetSpinUp to BIOS Page 1.
+ *                      Added 5 new ControlFlags defines for SAS IO Unit
+ *                      Page 1.
+ *                      Added MaxNumPhysicalMappedIDs field to SAS IO Unit
+ *                      Page 2.
+ *                      Added AccessStatus field to SAS Device Page 0 and added
+ *                      new Flags bits for supported SATA features.
+ *  12-07-04  01.05.04  Added config page structures for BIOS Page 2, RAID
+ *                      Volume Page 1, and RAID Physical Disk Page 1.
+ *                      Replaced IO Unit Page 1 BootTargetID,BootBus, and
+ *                      BootAdapterNum with reserved field.
+ *                      Added DataScrubRate and ResyncRate to RAID Volume
+ *                      Page 0.
+ *                      Added MPI_SAS_IOUNIT2_FLAGS_RESERVE_ID_0_FOR_BOOT
+ *                      define.
+ *  12-09-04  01.05.05  Added Target Mode Large CDB Enable to FC Port Page 1
+ *                      Flags field.
+ *                      Added Auto Port Config flag define for SAS IOUNIT
+ *                      Page 1 ControlFlags.
+ *                      Added Disabled bad Phy define to Expander Page 1
+ *                      Discovery Info field.
+ *                      Added SAS/SATA device support to SAS IOUnit Page 1
+ *                      ControlFlags.
+ *                      Added Unsupported device to SAS Dev Page 0 Flags field
+ *                      Added disable use SATA Hash Address for SAS IOUNIT
+ *                      page 1 in ControlFields.
+ *  01-15-05  01.05.06  Added defaults for data scrub rate and resync rate to
+ *                      Manufacturing Page 4.
+ *                      Added new defines for BIOS Page 1 IOCSettings field.
+ *                      Added ExtDiskIdentifier field to RAID Physical Disk
+ *                      Page 0.
+ *                      Added new defines for SAS IO Unit Page 1 ControlFlags
+ *                      and to SAS Device Page 0 Flags to control SATA devices.
+ *                      Added defines and structures for the new Log Page 0, a
+ *                      new type of configuration page.
+ *  02-09-05  01.05.07  Added InactiveStatus field to RAID Volume Page 0.
+ *                      Added WWID field to RAID Volume Page 1.
+ *                      Added PhysicalPort field to SAS Expander pages 0 and 1.
+ *  03-11-05  01.05.08  Removed the EEDP flags from IOC Page 1.
+ *                      Added Enclosure/Slot boot device format to BIOS Page 2.
+ *                      New status value for RAID Volume Page 0 VolumeStatus
+ *                      (VolumeState subfield).
+ *                      New value for RAID Physical Page 0 InactiveStatus.
+ *                      Added Inactive Volume Member flag RAID Physical Disk
+ *                      Page 0 PhysDiskStatus field.
+ *                      New physical mapping mode in SAS IO Unit Page 2.
+ *                      Added CONFIG_PAGE_SAS_ENCLOSURE_0.
+ *                      Added Slot and Enclosure fields to SAS Device Page 0.
  *  --------------------------------------------------------------------------
  */
 
@@ -164,7 +251,7 @@ typedef struct _CONFIG_PAGE_HEADER
     U8                      PageLength;                 /* 01h */
     U8                      PageNumber;                 /* 02h */
     U8                      PageType;                   /* 03h */
-} fCONFIG_PAGE_HEADER, MPI_POINTER PTR_CONFIG_PAGE_HEADER,
+} CONFIG_PAGE_HEADER, MPI_POINTER PTR_CONFIG_PAGE_HEADER,
   ConfigPageHeader_t, MPI_POINTER pConfigPageHeader_t;
 
 typedef union _CONFIG_PAGE_HEADER_UNION
@@ -174,7 +261,7 @@ typedef union _CONFIG_PAGE_HEADER_UNION
    U16                 Word16[2];
    U32                 Word32;
 } ConfigPageHeaderUnion, MPI_POINTER pConfigPageHeaderUnion,
-  fCONFIG_PAGE_HEADER_UNION, MPI_POINTER PTR_CONFIG_PAGE_HEADER_UNION;
+  CONFIG_PAGE_HEADER_UNION, MPI_POINTER PTR_CONFIG_PAGE_HEADER_UNION;
 
 typedef struct _CONFIG_EXTENDED_PAGE_HEADER
 {
@@ -185,7 +272,7 @@ typedef struct _CONFIG_EXTENDED_PAGE_HEA
     U16                 ExtPageLength;              /* 04h */
     U8                  ExtPageType;                /* 06h */
     U8                  Reserved2;                  /* 07h */
-} fCONFIG_EXTENDED_PAGE_HEADER, MPI_POINTER PTR_CONFIG_EXTENDED_PAGE_HEADER,
+} CONFIG_EXTENDED_PAGE_HEADER, MPI_POINTER PTR_CONFIG_EXTENDED_PAGE_HEADER,
   ConfigExtendedPageHeader_t, MPI_POINTER pConfigExtendedPageHeader_t;
 
 
@@ -224,6 +311,8 @@ typedef struct _CONFIG_EXTENDED_PAGE_HEA
 #define MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER         (0x11)
 #define MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE           (0x12)
 #define MPI_CONFIG_EXTPAGETYPE_SAS_PHY              (0x13)
+#define MPI_CONFIG_EXTPAGETYPE_LOG                  (0x14)
+#define MPI_CONFIG_EXTPAGETYPE_ENCLOSURE            (0x15)
 
 
 /****************************************************************************
@@ -231,10 +320,19 @@ typedef struct _CONFIG_EXTENDED_PAGE_HEA
 ****************************************************************************/
 #define MPI_SCSI_PORT_PGAD_PORT_MASK                (0x000000FF)
 
+#define MPI_SCSI_DEVICE_FORM_MASK                   (0xF0000000)
+#define MPI_SCSI_DEVICE_FORM_BUS_TID                (0x00000000)
 #define MPI_SCSI_DEVICE_TARGET_ID_MASK              (0x000000FF)
 #define MPI_SCSI_DEVICE_TARGET_ID_SHIFT             (0)
 #define MPI_SCSI_DEVICE_BUS_MASK                    (0x0000FF00)
 #define MPI_SCSI_DEVICE_BUS_SHIFT                   (8)
+#define MPI_SCSI_DEVICE_FORM_TARGET_MODE            (0x10000000)
+#define MPI_SCSI_DEVICE_TM_RESPOND_ID_MASK          (0x000000FF)
+#define MPI_SCSI_DEVICE_TM_RESPOND_ID_SHIFT         (0)
+#define MPI_SCSI_DEVICE_TM_BUS_MASK                 (0x0000FF00)
+#define MPI_SCSI_DEVICE_TM_BUS_SHIFT                (8)
+#define MPI_SCSI_DEVICE_TM_INIT_ID_MASK             (0x00FF0000)
+#define MPI_SCSI_DEVICE_TM_INIT_ID_SHIFT            (16)
 
 #define MPI_FC_PORT_PGAD_PORT_MASK                  (0xF0000000)
 #define MPI_FC_PORT_PGAD_PORT_SHIFT                 (28)
@@ -260,6 +358,20 @@ typedef struct _CONFIG_EXTENDED_PAGE_HEA
 #define MPI_PHYSDISK_PGAD_PHYSDISKNUM_MASK          (0x000000FF)
 #define MPI_PHYSDISK_PGAD_PHYSDISKNUM_SHIFT         (0)
 
+#define MPI_SAS_EXPAND_PGAD_FORM_MASK             (0xF0000000)
+#define MPI_SAS_EXPAND_PGAD_FORM_SHIFT            (28)
+#define MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE  (0x00000000)
+#define MPI_SAS_EXPAND_PGAD_FORM_HANDLE_PHY_NUM   (0x00000001)
+#define MPI_SAS_EXPAND_PGAD_FORM_HANDLE           (0x00000002)
+#define MPI_SAS_EXPAND_PGAD_GNH_MASK_HANDLE       (0x0000FFFF)
+#define MPI_SAS_EXPAND_PGAD_GNH_SHIFT_HANDLE      (0)
+#define MPI_SAS_EXPAND_PGAD_HPN_MASK_PHY          (0x00FF0000)
+#define MPI_SAS_EXPAND_PGAD_HPN_SHIFT_PHY         (16)
+#define MPI_SAS_EXPAND_PGAD_HPN_MASK_HANDLE       (0x0000FFFF)
+#define MPI_SAS_EXPAND_PGAD_HPN_SHIFT_HANDLE      (0)
+#define MPI_SAS_EXPAND_PGAD_H_MASK_HANDLE         (0x0000FFFF)
+#define MPI_SAS_EXPAND_PGAD_H_SHIFT_HANDLE        (0)
+
 #define MPI_SAS_DEVICE_PGAD_FORM_MASK               (0xF0000000)
 #define MPI_SAS_DEVICE_PGAD_FORM_SHIFT              (28)
 #define MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE    (0x00000000)
@@ -274,10 +386,24 @@ typedef struct _CONFIG_EXTENDED_PAGE_HEA
 #define MPI_SAS_DEVICE_PGAD_H_HANDLE_MASK           (0x0000FFFF)
 #define MPI_SAS_DEVICE_PGAD_H_HANDLE_SHIFT          (0)
 
-#define MPI_SAS_PHY_PGAD_PHY_NUMBER_MASK            (0x00FF0000)
-#define MPI_SAS_PHY_PGAD_PHY_NUMBER_SHIFT           (16)
-#define MPI_SAS_PHY_PGAD_DEVHANDLE_MASK             (0x0000FFFF)
-#define MPI_SAS_PHY_PGAD_DEVHANDLE_SHIFT            (0)
+#define MPI_SAS_PHY_PGAD_FORM_MASK                  (0xF0000000)
+#define MPI_SAS_PHY_PGAD_FORM_SHIFT                 (28)
+#define MPI_SAS_PHY_PGAD_FORM_PHY_NUMBER            (0x0)
+#define MPI_SAS_PHY_PGAD_FORM_PHY_TBL_INDEX         (0x1)
+#define MPI_SAS_PHY_PGAD_PHY_NUMBER_MASK            (0x000000FF)
+#define MPI_SAS_PHY_PGAD_PHY_NUMBER_SHIFT           (0)
+#define MPI_SAS_PHY_PGAD_PHY_TBL_INDEX_MASK         (0x0000FFFF)
+#define MPI_SAS_PHY_PGAD_PHY_TBL_INDEX_SHIFT        (0)
+
+#define MPI_SAS_ENCLOS_PGAD_FORM_MASK               (0xF0000000)
+#define MPI_SAS_ENCLOS_PGAD_FORM_SHIFT              (28)
+#define MPI_SAS_ENCLOS_PGAD_FORM_GET_NEXT_HANDLE    (0x00000000)
+#define MPI_SAS_ENCLOS_PGAD_FORM_HANDLE             (0x00000001)
+#define MPI_SAS_ENCLOS_PGAD_GNH_HANDLE_MASK         (0x0000FFFF)
+#define MPI_SAS_ENCLOS_PGAD_GNH_HANDLE_SHIFT        (0)
+#define MPI_SAS_ENCLOS_PGAD_H_HANDLE_MASK           (0x0000FFFF)
+#define MPI_SAS_ENCLOS_PGAD_H_HANDLE_SHIFT          (0)
+
 
 
 /****************************************************************************
@@ -294,7 +420,7 @@ typedef struct _MSG_CONFIG
     U8                      MsgFlags;                   /* 07h */
     U32                     MsgContext;                 /* 08h */
     U8                      Reserved2[8];               /* 0Ch */
-    fCONFIG_PAGE_HEADER      Header;                     /* 14h */
+    CONFIG_PAGE_HEADER      Header;                     /* 14h */
     U32                     PageAddress;                /* 18h */
     SGE_IO_UNION            PageBufferSGE;              /* 1Ch */
 } MSG_CONFIG, MPI_POINTER PTR_MSG_CONFIG,
@@ -327,7 +453,7 @@ typedef struct _MSG_CONFIG_REPLY
     U8                      Reserved2[2];               /* 0Ch */
     U16                     IOCStatus;                  /* 0Eh */
     U32                     IOCLogInfo;                 /* 10h */
-    fCONFIG_PAGE_HEADER      Header;                     /* 14h */
+    CONFIG_PAGE_HEADER      Header;                     /* 14h */
 } MSG_CONFIG_REPLY, MPI_POINTER PTR_MSG_CONFIG_REPLY,
   ConfigReply_t, MPI_POINTER pConfigReply_t;
 
@@ -349,6 +475,8 @@ typedef struct _MSG_CONFIG_REPLY
 #define MPI_MANUFACTPAGE_DEVICEID_FC929             (0x0622)
 #define MPI_MANUFACTPAGE_DEVICEID_FC919X            (0x0628)
 #define MPI_MANUFACTPAGE_DEVICEID_FC929X            (0x0626)
+#define MPI_MANUFACTPAGE_DEVICEID_FC939X            (0x0642)
+#define MPI_MANUFACTPAGE_DEVICEID_FC949X            (0x0640)
 /* SCSI */
 #define MPI_MANUFACTPAGE_DEVID_53C1030              (0x0030)
 #define MPI_MANUFACTPAGE_DEVID_53C1030ZC            (0x0031)
@@ -358,18 +486,25 @@ typedef struct _MSG_CONFIG_REPLY
 #define MPI_MANUFACTPAGE_DEVID_53C1035ZC            (0x0041)
 /* SAS */
 #define MPI_MANUFACTPAGE_DEVID_SAS1064              (0x0050)
+#define MPI_MANUFACTPAGE_DEVID_SAS1064A             (0x005C)
+#define MPI_MANUFACTPAGE_DEVID_SAS1064E             (0x0056)
+#define MPI_MANUFACTPAGE_DEVID_SAS1066              (0x005E)
+#define MPI_MANUFACTPAGE_DEVID_SAS1066E             (0x005A)
+#define MPI_MANUFACTPAGE_DEVID_SAS1068              (0x0054)
+#define MPI_MANUFACTPAGE_DEVID_SAS1068E             (0x0058)
+#define MPI_MANUFACTPAGE_DEVID_SAS1078              (0x0060)
 
 
 typedef struct _CONFIG_PAGE_MANUFACTURING_0
 {
-    fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    CONFIG_PAGE_HEADER      Header;                     /* 00h */
     U8                      ChipName[16];               /* 04h */
     U8                      ChipRevision[8];            /* 14h */
     U8                      BoardName[16];              /* 1Ch */
     U8                      BoardAssembly[16];          /* 2Ch */
     U8                      BoardTracerNumber[16];      /* 3Ch */
 
-} fCONFIG_PAGE_MANUFACTURING_0, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_0,
+} CONFIG_PAGE_MANUFACTURING_0, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_0,
   ManufacturingPage0_t, MPI_POINTER pManufacturingPage0_t;
 
 #define MPI_MANUFACTURING0_PAGEVERSION                 (0x00)
@@ -377,9 +512,9 @@ typedef struct _CONFIG_PAGE_MANUFACTURIN
 
 typedef struct _CONFIG_PAGE_MANUFACTURING_1
 {
-    fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    CONFIG_PAGE_HEADER      Header;                     /* 00h */
     U8                      VPD[256];                   /* 04h */
-} fCONFIG_PAGE_MANUFACTURING_1, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_1,
+} CONFIG_PAGE_MANUFACTURING_1, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_1,
   ManufacturingPage1_t, MPI_POINTER pManufacturingPage1_t;
 
 #define MPI_MANUFACTURING1_PAGEVERSION                 (0x00)
@@ -404,10 +539,10 @@ typedef struct _MPI_CHIP_REVISION_ID
 
 typedef struct _CONFIG_PAGE_MANUFACTURING_2
 {
-    fCONFIG_PAGE_HEADER      Header;                                 /* 00h */
+    CONFIG_PAGE_HEADER      Header;                                 /* 00h */
     MPI_CHIP_REVISION_ID    ChipId;                                 /* 04h */
     U32                     HwSettings[MPI_MAN_PAGE_2_HW_SETTINGS_WORDS];/* 08h */
-} fCONFIG_PAGE_MANUFACTURING_2, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_2,
+} CONFIG_PAGE_MANUFACTURING_2, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_2,
   ManufacturingPage2_t, MPI_POINTER pManufacturingPage2_t;
 
 #define MPI_MANUFACTURING2_PAGEVERSION                  (0x00)
@@ -423,10 +558,10 @@ typedef struct _CONFIG_PAGE_MANUFACTURIN
 
 typedef struct _CONFIG_PAGE_MANUFACTURING_3
 {
-    fCONFIG_PAGE_HEADER                  Header;                     /* 00h */
+    CONFIG_PAGE_HEADER                  Header;                     /* 00h */
     MPI_CHIP_REVISION_ID                ChipId;                     /* 04h */
     U32                                 Info[MPI_MAN_PAGE_3_INFO_WORDS];/* 08h */
-} fCONFIG_PAGE_MANUFACTURING_3, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_3,
+} CONFIG_PAGE_MANUFACTURING_3, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_3,
   ManufacturingPage3_t, MPI_POINTER pManufacturingPage3_t;
 
 #define MPI_MANUFACTURING3_PAGEVERSION                  (0x00)
@@ -434,7 +569,7 @@ typedef struct _CONFIG_PAGE_MANUFACTURIN
 
 typedef struct _CONFIG_PAGE_MANUFACTURING_4
 {
-    fCONFIG_PAGE_HEADER              Header;             /* 00h */
+    CONFIG_PAGE_HEADER              Header;             /* 00h */
     U32                             Reserved1;          /* 04h */
     U8                              InfoOffset0;        /* 08h */
     U8                              InfoSize0;          /* 09h */
@@ -447,10 +582,23 @@ typedef struct _CONFIG_PAGE_MANUFACTURIN
     U32                             ISVolumeSettings;   /* 48h */
     U32                             IMEVolumeSettings;  /* 4Ch */
     U32                             IMVolumeSettings;   /* 50h */
-} fCONFIG_PAGE_MANUFACTURING_4, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_4,
+    U32                             Reserved3;          /* 54h */
+    U32                             Reserved4;          /* 58h */
+    U8                              ISDataScrubRate;    /* 5Ch */
+    U8                              ISResyncRate;       /* 5Dh */
+    U16                             Reserved5;          /* 5Eh */
+    U8                              IMEDataScrubRate;   /* 60h */
+    U8                              IMEResyncRate;      /* 61h */
+    U16                             Reserved6;          /* 62h */
+    U8                              IMDataScrubRate;    /* 64h */
+    U8                              IMResyncRate;       /* 65h */
+    U16                             Reserved7;          /* 66h */
+    U32                             Reserved8;          /* 68h */
+    U32                             Reserved9;          /* 6Ch */
+} CONFIG_PAGE_MANUFACTURING_4, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_4,
   ManufacturingPage4_t, MPI_POINTER pManufacturingPage4_t;
 
-#define MPI_MANUFACTURING4_PAGEVERSION                  (0x01)
+#define MPI_MANUFACTURING4_PAGEVERSION                  (0x02)
 
 /* defines for the Flags field */
 #define MPI_MANPAGE4_IR_NO_MIX_SAS_SATA                 (0x01)
@@ -458,19 +606,25 @@ typedef struct _CONFIG_PAGE_MANUFACTURIN
 
 typedef struct _CONFIG_PAGE_MANUFACTURING_5
 {
-    fCONFIG_PAGE_HEADER              Header;             /* 00h */
+    CONFIG_PAGE_HEADER              Header;             /* 00h */
     U64                             BaseWWID;           /* 04h */
-} fCONFIG_PAGE_MANUFACTURING_5, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_5,
+    U8                              Flags;              /* 0Ch */
+    U8                              Reserved1;          /* 0Dh */
+    U16                             Reserved2;          /* 0Eh */
+} CONFIG_PAGE_MANUFACTURING_5, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_5,
   ManufacturingPage5_t, MPI_POINTER pManufacturingPage5_t;
 
-#define MPI_MANUFACTURING5_PAGEVERSION                  (0x00)
+#define MPI_MANUFACTURING5_PAGEVERSION                  (0x01)
+
+/* defines for the Flags field */
+#define MPI_MANPAGE5_TWO_WWID_PER_PHY                   (0x01)
 
 
 typedef struct _CONFIG_PAGE_MANUFACTURING_6
 {
-    fCONFIG_PAGE_HEADER              Header;             /* 00h */
+    CONFIG_PAGE_HEADER              Header;             /* 00h */
     U32                             ProductSpecificInfo;/* 04h */
-} fCONFIG_PAGE_MANUFACTURING_6, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_6,
+} CONFIG_PAGE_MANUFACTURING_6, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_6,
   ManufacturingPage6_t, MPI_POINTER pManufacturingPage6_t;
 
 #define MPI_MANUFACTURING6_PAGEVERSION                  (0x00)
@@ -482,9 +636,9 @@ typedef struct _CONFIG_PAGE_MANUFACTURIN
 
 typedef struct _CONFIG_PAGE_IO_UNIT_0
 {
-    fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    CONFIG_PAGE_HEADER      Header;                     /* 00h */
     U64                     UniqueValue;                /* 04h */
-} fCONFIG_PAGE_IO_UNIT_0, MPI_POINTER PTR_CONFIG_PAGE_IO_UNIT_0,
+} CONFIG_PAGE_IO_UNIT_0, MPI_POINTER PTR_CONFIG_PAGE_IO_UNIT_0,
   IOUnitPage0_t, MPI_POINTER pIOUnitPage0_t;
 
 #define MPI_IOUNITPAGE0_PAGEVERSION                     (0x00)
@@ -492,9 +646,9 @@ typedef struct _CONFIG_PAGE_IO_UNIT_0
 
 typedef struct _CONFIG_PAGE_IO_UNIT_1
 {
-    fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    CONFIG_PAGE_HEADER      Header;                     /* 00h */
     U32                     Flags;                      /* 04h */
-} fCONFIG_PAGE_IO_UNIT_1, MPI_POINTER PTR_CONFIG_PAGE_IO_UNIT_1,
+} CONFIG_PAGE_IO_UNIT_1, MPI_POINTER PTR_CONFIG_PAGE_IO_UNIT_1,
   IOUnitPage1_t, MPI_POINTER pIOUnitPage1_t;
 
 #define MPI_IOUNITPAGE1_PAGEVERSION                     (0x01)
@@ -524,14 +678,15 @@ typedef struct _MPI_ADAPTER_INFO
 
 typedef struct _CONFIG_PAGE_IO_UNIT_2
 {
-    fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    CONFIG_PAGE_HEADER      Header;                     /* 00h */
     U32                     Flags;                      /* 04h */
     U32                     BiosVersion;                /* 08h */
     MPI_ADAPTER_INFO        AdapterOrder[4];            /* 0Ch */
-} fCONFIG_PAGE_IO_UNIT_2, MPI_POINTER PTR_CONFIG_PAGE_IO_UNIT_2,
+    U32                     Reserved1;                  /* 1Ch */
+} CONFIG_PAGE_IO_UNIT_2, MPI_POINTER PTR_CONFIG_PAGE_IO_UNIT_2,
   IOUnitPage2_t, MPI_POINTER pIOUnitPage2_t;
 
-#define MPI_IOUNITPAGE2_PAGEVERSION                     (0x00)
+#define MPI_IOUNITPAGE2_PAGEVERSION                     (0x02)
 
 #define MPI_IOUNITPAGE2_FLAGS_PAUSE_ON_ERROR            (0x00000002)
 #define MPI_IOUNITPAGE2_FLAGS_VERBOSE_ENABLE            (0x00000004)
@@ -554,12 +709,12 @@ typedef struct _CONFIG_PAGE_IO_UNIT_2
 
 typedef struct _CONFIG_PAGE_IO_UNIT_3
 {
-    fCONFIG_PAGE_HEADER      Header;                                   /* 00h */
+    CONFIG_PAGE_HEADER      Header;                                   /* 00h */
     U8                      GPIOCount;                                /* 04h */
     U8                      Reserved1;                                /* 05h */
     U16                     Reserved2;                                /* 06h */
     U16                     GPIOVal[MPI_IO_UNIT_PAGE_3_GPIO_VAL_MAX]; /* 08h */
-} fCONFIG_PAGE_IO_UNIT_3, MPI_POINTER PTR_CONFIG_PAGE_IO_UNIT_3,
+} CONFIG_PAGE_IO_UNIT_3, MPI_POINTER PTR_CONFIG_PAGE_IO_UNIT_3,
   IOUnitPage3_t, MPI_POINTER pIOUnitPage3_t;
 
 #define MPI_IOUNITPAGE3_PAGEVERSION                     (0x01)
@@ -570,13 +725,24 @@ typedef struct _CONFIG_PAGE_IO_UNIT_3
 #define MPI_IOUNITPAGE3_GPIO_SETTING_ON                 (0x01)
 
 
+typedef struct _CONFIG_PAGE_IO_UNIT_4
+{
+    CONFIG_PAGE_HEADER      Header;                                   /* 00h */
+    U32                     Reserved1;                                /* 04h */
+    SGE_SIMPLE_UNION        FWImageSGE;                               /* 08h */
+} CONFIG_PAGE_IO_UNIT_4, MPI_POINTER PTR_CONFIG_PAGE_IO_UNIT_4,
+  IOUnitPage4_t, MPI_POINTER pIOUnitPage4_t;
+
+#define MPI_IOUNITPAGE4_PAGEVERSION                     (0x00)
+
+
 /****************************************************************************
 *   IOC Config Pages
 ****************************************************************************/
 
 typedef struct _CONFIG_PAGE_IOC_0
 {
-    fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    CONFIG_PAGE_HEADER      Header;                     /* 00h */
     U32                     TotalNVStore;               /* 04h */
     U32                     FreeNVStore;                /* 08h */
     U16                     VendorID;                   /* 0Ch */
@@ -586,7 +752,7 @@ typedef struct _CONFIG_PAGE_IOC_0
     U32                     ClassCode;                  /* 14h */
     U16                     SubsystemVendorID;          /* 18h */
     U16                     SubsystemID;                /* 1Ah */
-} fCONFIG_PAGE_IOC_0, MPI_POINTER PTR_CONFIG_PAGE_IOC_0,
+} CONFIG_PAGE_IOC_0, MPI_POINTER PTR_CONFIG_PAGE_IOC_0,
   IOCPage0_t, MPI_POINTER pIOCPage0_t;
 
 #define MPI_IOCPAGE0_PAGEVERSION                        (0x01)
@@ -594,23 +760,19 @@ typedef struct _CONFIG_PAGE_IOC_0
 
 typedef struct _CONFIG_PAGE_IOC_1
 {
-    fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    CONFIG_PAGE_HEADER      Header;                     /* 00h */
     U32                     Flags;                      /* 04h */
     U32                     CoalescingTimeout;          /* 08h */
     U8                      CoalescingDepth;            /* 0Ch */
     U8                      PCISlotNum;                 /* 0Dh */
     U8                      Reserved[2];                /* 0Eh */
-} fCONFIG_PAGE_IOC_1, MPI_POINTER PTR_CONFIG_PAGE_IOC_1,
+} CONFIG_PAGE_IOC_1, MPI_POINTER PTR_CONFIG_PAGE_IOC_1,
   IOCPage1_t, MPI_POINTER pIOCPage1_t;
 
-#define MPI_IOCPAGE1_PAGEVERSION                        (0x01)
+#define MPI_IOCPAGE1_PAGEVERSION                        (0x02)
 
 /* defines for the Flags field */
-#define MPI_IOCPAGE1_EEDP_HOST_SUPPORTS_DIF             (0x08000000)
-#define MPI_IOCPAGE1_EEDP_MODE_MASK                     (0x07000000)
-#define MPI_IOCPAGE1_EEDP_MODE_OFF                      (0x00000000)
-#define MPI_IOCPAGE1_EEDP_MODE_T10                      (0x01000000)
-#define MPI_IOCPAGE1_EEDP_MODE_LSI_1                    (0x02000000)
+#define MPI_IOCPAGE1_INITIATOR_CONTEXT_REPLY_DISABLE    (0x00000010)
 #define MPI_IOCPAGE1_REPLY_COALESCING                   (0x00000001)
 
 #define MPI_IOCPAGE1_PCISLOTNUM_UNKNOWN                 (0xFF)
@@ -625,7 +787,7 @@ typedef struct _CONFIG_PAGE_IOC_2_RAID_V
     U8                          VolumeType;             /* 04h */
     U8                          Flags;                  /* 05h */
     U16                         Reserved3;              /* 06h */
-} fCONFIG_PAGE_IOC_2_RAID_VOL, MPI_POINTER PTR_CONFIG_PAGE_IOC_2_RAID_VOL,
+} CONFIG_PAGE_IOC_2_RAID_VOL, MPI_POINTER PTR_CONFIG_PAGE_IOC_2_RAID_VOL,
   ConfigPageIoc2RaidVol_t, MPI_POINTER pConfigPageIoc2RaidVol_t;
 
 /* IOC Page 2 Volume RAID Type values, also used in RAID Volume pages */
@@ -648,14 +810,14 @@ typedef struct _CONFIG_PAGE_IOC_2_RAID_V
 
 typedef struct _CONFIG_PAGE_IOC_2
 {
-    fCONFIG_PAGE_HEADER          Header;                              /* 00h */
+    CONFIG_PAGE_HEADER          Header;                              /* 00h */
     U32                         CapabilitiesFlags;                   /* 04h */
     U8                          NumActiveVolumes;                    /* 08h */
     U8                          MaxVolumes;                          /* 09h */
     U8                          NumActivePhysDisks;                  /* 0Ah */
     U8                          MaxPhysDisks;                        /* 0Bh */
-    fCONFIG_PAGE_IOC_2_RAID_VOL  RaidVolume[MPI_IOC_PAGE_2_RAID_VOLUME_MAX];/* 0Ch */
-} fCONFIG_PAGE_IOC_2, MPI_POINTER PTR_CONFIG_PAGE_IOC_2,
+    CONFIG_PAGE_IOC_2_RAID_VOL  RaidVolume[MPI_IOC_PAGE_2_RAID_VOLUME_MAX];/* 0Ch */
+} CONFIG_PAGE_IOC_2, MPI_POINTER PTR_CONFIG_PAGE_IOC_2,
   IOCPage2_t, MPI_POINTER pIOCPage2_t;
 
 #define MPI_IOCPAGE2_PAGEVERSION                        (0x02)
@@ -689,12 +851,12 @@ typedef struct _IOC_3_PHYS_DISK
 
 typedef struct _CONFIG_PAGE_IOC_3
 {
-    fCONFIG_PAGE_HEADER          Header;                                /* 00h */
+    CONFIG_PAGE_HEADER          Header;                                /* 00h */
     U8                          NumPhysDisks;                          /* 04h */
     U8                          Reserved1;                             /* 05h */
     U16                         Reserved2;                             /* 06h */
     IOC_3_PHYS_DISK             PhysDisk[MPI_IOC_PAGE_3_PHYSDISK_MAX]; /* 08h */
-} fCONFIG_PAGE_IOC_3, MPI_POINTER PTR_CONFIG_PAGE_IOC_3,
+} CONFIG_PAGE_IOC_3, MPI_POINTER PTR_CONFIG_PAGE_IOC_3,
   IOCPage3_t, MPI_POINTER pIOCPage3_t;
 
 #define MPI_IOCPAGE3_PAGEVERSION                        (0x00)
@@ -718,12 +880,12 @@ typedef struct _IOC_4_SEP
 
 typedef struct _CONFIG_PAGE_IOC_4
 {
-    fCONFIG_PAGE_HEADER          Header;                         /* 00h */
+    CONFIG_PAGE_HEADER          Header;                         /* 00h */
     U8                          ActiveSEP;                      /* 04h */
     U8                          MaxSEP;                         /* 05h */
     U16                         Reserved1;                      /* 06h */
     IOC_4_SEP                   SEP[MPI_IOC_PAGE_4_SEP_MAX];    /* 08h */
-} fCONFIG_PAGE_IOC_4, MPI_POINTER PTR_CONFIG_PAGE_IOC_4,
+} CONFIG_PAGE_IOC_4, MPI_POINTER PTR_CONFIG_PAGE_IOC_4,
   IOCPage4_t, MPI_POINTER pIOCPage4_t;
 
 #define MPI_IOCPAGE4_PAGEVERSION                        (0x00)
@@ -751,25 +913,25 @@ typedef struct _IOC_5_HOT_SPARE
 
 typedef struct _CONFIG_PAGE_IOC_5
 {
-    fCONFIG_PAGE_HEADER          Header;                         /* 00h */
+    CONFIG_PAGE_HEADER          Header;                         /* 00h */
     U32                         Reserved1;                      /* 04h */
     U8                          NumHotSpares;                   /* 08h */
     U8                          Reserved2;                      /* 09h */
     U16                         Reserved3;                      /* 0Ah */
     IOC_5_HOT_SPARE             HotSpare[MPI_IOC_PAGE_5_HOT_SPARE_MAX]; /* 0Ch */
-} fCONFIG_PAGE_IOC_5, MPI_POINTER PTR_CONFIG_PAGE_IOC_5,
+} CONFIG_PAGE_IOC_5, MPI_POINTER PTR_CONFIG_PAGE_IOC_5,
   IOCPage5_t, MPI_POINTER pIOCPage5_t;
 
 #define MPI_IOCPAGE5_PAGEVERSION                        (0x00)
 
 
 /****************************************************************************
-*   BIOS Port Config Pages
+*   BIOS Config Pages
 ****************************************************************************/
 
 typedef struct _CONFIG_PAGE_BIOS_1
 {
-    fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    CONFIG_PAGE_HEADER      Header;                     /* 00h */
     U32                     BiosOptions;                /* 04h */
     U32                     IOCSettings;                /* 08h */
     U32                     Reserved1;                  /* 0Ch */
@@ -780,10 +942,10 @@ typedef struct _CONFIG_PAGE_BIOS_1
     U16                     IOTimeoutSequential;        /* 1Ah */
     U16                     IOTimeoutOther;             /* 1Ch */
     U16                     IOTimeoutBlockDevicesRM;    /* 1Eh */
-} fCONFIG_PAGE_BIOS_1, MPI_POINTER PTR_CONFIG_PAGE_BIOS_1,
+} CONFIG_PAGE_BIOS_1, MPI_POINTER PTR_CONFIG_PAGE_BIOS_1,
   BIOSPage1_t, MPI_POINTER pBIOSPage1_t;
 
-#define MPI_BIOSPAGE1_PAGEVERSION                       (0x00)
+#define MPI_BIOSPAGE1_PAGEVERSION                       (0x01)
 
 /* values for the BiosOptions field */
 #define MPI_BIOSPAGE1_OPTIONS_SPI_ENABLE                (0x00000400)
@@ -792,6 +954,13 @@ typedef struct _CONFIG_PAGE_BIOS_1
 #define MPI_BIOSPAGE1_OPTIONS_DISABLE_BIOS              (0x00000001)
 
 /* values for the IOCSettings field */
+#define MPI_BIOSPAGE1_IOCSET_MASK_BOOT_PREFERENCE       (0x00030000)
+#define MPI_BIOSPAGE1_IOCSET_ENCLOSURE_SLOT_BOOT        (0x00000000)
+#define MPI_BIOSPAGE1_IOCSET_SAS_ADDRESS_BOOT           (0x00010000)
+
+#define MPI_BIOSPAGE1_IOCSET_MASK_MAX_TARGET_SPIN_UP    (0x0000F000)
+#define MPI_BIOSPAGE1_IOCSET_SHIFT_MAX_TARGET_SPIN_UP   (12)
+
 #define MPI_BIOSPAGE1_IOCSET_MASK_SPINUP_DELAY          (0x00000F00)
 #define MPI_BIOSPAGE1_IOCSET_SHIFT_SPINUP_DELAY         (8)
 
@@ -814,6 +983,191 @@ typedef struct _CONFIG_PAGE_BIOS_1
 #define MPI_BIOSPAGE1_DEVSET_DISABLE_NON_RM_LUN         (0x00000002)
 #define MPI_BIOSPAGE1_DEVSET_DISABLE_OTHER_LUN          (0x00000001)
 
+typedef struct _MPI_BOOT_DEVICE_ADAPTER_ORDER
+{
+    U32         Reserved1;                              /* 00h */
+    U32         Reserved2;                              /* 04h */
+    U32         Reserved3;                              /* 08h */
+    U32         Reserved4;                              /* 0Ch */
+    U32         Reserved5;                              /* 10h */
+    U32         Reserved6;                              /* 14h */
+    U32         Reserved7;                              /* 18h */
+    U32         Reserved8;                              /* 1Ch */
+    U32         Reserved9;                              /* 20h */
+    U32         Reserved10;                             /* 24h */
+    U32         Reserved11;                             /* 28h */
+    U32         Reserved12;                             /* 2Ch */
+    U32         Reserved13;                             /* 30h */
+    U32         Reserved14;                             /* 34h */
+    U32         Reserved15;                             /* 38h */
+    U32         Reserved16;                             /* 3Ch */
+    U32         Reserved17;                             /* 40h */
+} MPI_BOOT_DEVICE_ADAPTER_ORDER, MPI_POINTER PTR_MPI_BOOT_DEVICE_ADAPTER_ORDER;
+
+typedef struct _MPI_BOOT_DEVICE_ADAPTER_NUMBER
+{
+    U8          TargetID;                               /* 00h */
+    U8          Bus;                                    /* 01h */
+    U8          AdapterNumber;                          /* 02h */
+    U8          Reserved1;                              /* 03h */
+    U32         Reserved2;                              /* 04h */
+    U32         Reserved3;                              /* 08h */
+    U32         Reserved4;                              /* 0Ch */
+    U8          LUN[8];                                 /* 10h */
+    U32         Reserved5;                              /* 18h */
+    U32         Reserved6;                              /* 1Ch */
+    U32         Reserved7;                              /* 20h */
+    U32         Reserved8;                              /* 24h */
+    U32         Reserved9;                              /* 28h */
+    U32         Reserved10;                             /* 2Ch */
+    U32         Reserved11;                             /* 30h */
+    U32         Reserved12;                             /* 34h */
+    U32         Reserved13;                             /* 38h */
+    U32         Reserved14;                             /* 3Ch */
+    U32         Reserved15;                             /* 40h */
+} MPI_BOOT_DEVICE_ADAPTER_NUMBER, MPI_POINTER PTR_MPI_BOOT_DEVICE_ADAPTER_NUMBER;
+
+typedef struct _MPI_BOOT_DEVICE_PCI_ADDRESS
+{
+    U8          TargetID;                               /* 00h */
+    U8          Bus;                                    /* 01h */
+    U16         PCIAddress;                             /* 02h */
+    U32         Reserved1;                              /* 04h */
+    U32         Reserved2;                              /* 08h */
+    U32         Reserved3;                              /* 0Ch */
+    U8          LUN[8];                                 /* 10h */
+    U32         Reserved4;                              /* 18h */
+    U32         Reserved5;                              /* 1Ch */
+    U32         Reserved6;                              /* 20h */
+    U32         Reserved7;                              /* 24h */
+    U32         Reserved8;                              /* 28h */
+    U32         Reserved9;                              /* 2Ch */
+    U32         Reserved10;                             /* 30h */
+    U32         Reserved11;                             /* 34h */
+    U32         Reserved12;                             /* 38h */
+    U32         Reserved13;                             /* 3Ch */
+    U32         Reserved14;                             /* 40h */
+} MPI_BOOT_DEVICE_PCI_ADDRESS, MPI_POINTER PTR_MPI_BOOT_DEVICE_PCI_ADDRESS;
+
+typedef struct _MPI_BOOT_DEVICE_SLOT_NUMBER
+{
+    U8          TargetID;                               /* 00h */
+    U8          Bus;                                    /* 01h */
+    U8          PCISlotNumber;                          /* 02h */
+    U8          Reserved1;                              /* 03h */
+    U32         Reserved2;                              /* 04h */
+    U32         Reserved3;                              /* 08h */
+    U32         Reserved4;                              /* 0Ch */
+    U8          LUN[8];                                 /* 10h */
+    U32         Reserved5;                              /* 18h */
+    U32         Reserved6;                              /* 1Ch */
+    U32         Reserved7;                              /* 20h */
+    U32         Reserved8;                              /* 24h */
+    U32         Reserved9;                              /* 28h */
+    U32         Reserved10;                             /* 2Ch */
+    U32         Reserved11;                             /* 30h */
+    U32         Reserved12;                             /* 34h */
+    U32         Reserved13;                             /* 38h */
+    U32         Reserved14;                             /* 3Ch */
+    U32         Reserved15;                             /* 40h */
+} MPI_BOOT_DEVICE_PCI_SLOT_NUMBER, MPI_POINTER PTR_MPI_BOOT_DEVICE_PCI_SLOT_NUMBER;
+
+typedef struct _MPI_BOOT_DEVICE_FC_WWN
+{
+    U64         WWPN;                                   /* 00h */
+    U32         Reserved1;                              /* 08h */
+    U32         Reserved2;                              /* 0Ch */
+    U8          LUN[8];                                 /* 10h */
+    U32         Reserved3;                              /* 18h */
+    U32         Reserved4;                              /* 1Ch */
+    U32         Reserved5;                              /* 20h */
+    U32         Reserved6;                              /* 24h */
+    U32         Reserved7;                              /* 28h */
+    U32         Reserved8;                              /* 2Ch */
+    U32         Reserved9;                              /* 30h */
+    U32         Reserved10;                             /* 34h */
+    U32         Reserved11;                             /* 38h */
+    U32         Reserved12;                             /* 3Ch */
+    U32         Reserved13;                             /* 40h */
+} MPI_BOOT_DEVICE_FC_WWN, MPI_POINTER PTR_MPI_BOOT_DEVICE_FC_WWN;
+
+typedef struct _MPI_BOOT_DEVICE_SAS_WWN
+{
+    U64         SASAddress;                             /* 00h */
+    U32         Reserved1;                              /* 08h */
+    U32         Reserved2;                              /* 0Ch */
+    U8          LUN[8];                                 /* 10h */
+    U32         Reserved3;                              /* 18h */
+    U32         Reserved4;                              /* 1Ch */
+    U32         Reserved5;                              /* 20h */
+    U32         Reserved6;                              /* 24h */
+    U32         Reserved7;                              /* 28h */
+    U32         Reserved8;                              /* 2Ch */
+    U32         Reserved9;                              /* 30h */
+    U32         Reserved10;                             /* 34h */
+    U32         Reserved11;                             /* 38h */
+    U32         Reserved12;                             /* 3Ch */
+    U32         Reserved13;                             /* 40h */
+} MPI_BOOT_DEVICE_SAS_WWN, MPI_POINTER PTR_MPI_BOOT_DEVICE_SAS_WWN;
+
+typedef struct _MPI_BOOT_DEVICE_ENCLOSURE_SLOT
+{
+    U64         EnclosureLogicalID;                     /* 00h */
+    U32         Reserved1;                              /* 08h */
+    U32         Reserved2;                              /* 0Ch */
+    U8          LUN[8];                                 /* 10h */
+    U16         SlotNumber;                             /* 18h */
+    U16         Reserved3;                              /* 1Ah */
+    U32         Reserved4;                              /* 1Ch */
+    U32         Reserved5;                              /* 20h */
+    U32         Reserved6;                              /* 24h */
+    U32         Reserved7;                              /* 28h */
+    U32         Reserved8;                              /* 2Ch */
+    U32         Reserved9;                              /* 30h */
+    U32         Reserved10;                             /* 34h */
+    U32         Reserved11;                             /* 38h */
+    U32         Reserved12;                             /* 3Ch */
+    U32         Reserved13;                             /* 40h */
+} MPI_BOOT_DEVICE_ENCLOSURE_SLOT,
+  MPI_POINTER PTR_MPI_BOOT_DEVICE_ENCLOSURE_SLOT;
+
+typedef union _MPI_BIOSPAGE2_BOOT_DEVICE
+{
+    MPI_BOOT_DEVICE_ADAPTER_ORDER   AdapterOrder;
+    MPI_BOOT_DEVICE_ADAPTER_NUMBER  AdapterNumber;
+    MPI_BOOT_DEVICE_PCI_ADDRESS     PCIAddress;
+    MPI_BOOT_DEVICE_PCI_SLOT_NUMBER PCISlotNumber;
+    MPI_BOOT_DEVICE_FC_WWN          FcWwn;
+    MPI_BOOT_DEVICE_SAS_WWN         SasWwn;
+    MPI_BOOT_DEVICE_ENCLOSURE_SLOT  EnclosureSlot;
+} MPI_BIOSPAGE2_BOOT_DEVICE, MPI_POINTER PTR_MPI_BIOSPAGE2_BOOT_DEVICE;
+
+typedef struct _CONFIG_PAGE_BIOS_2
+{
+    CONFIG_PAGE_HEADER          Header;                 /* 00h */
+    U32                         Reserved1;              /* 04h */
+    U32                         Reserved2;              /* 08h */
+    U32                         Reserved3;              /* 0Ch */
+    U32                         Reserved4;              /* 10h */
+    U32                         Reserved5;              /* 14h */
+    U32                         Reserved6;              /* 18h */
+    U8                          BootDeviceForm;         /* 1Ch */
+    U8                          Reserved7;              /* 1Dh */
+    U16                         Reserved8;              /* 1Eh */
+    MPI_BIOSPAGE2_BOOT_DEVICE   BootDevice;             /* 20h */
+} CONFIG_PAGE_BIOS_2, MPI_POINTER PTR_CONFIG_PAGE_BIOS_2,
+  BIOSPage2_t, MPI_POINTER pBIOSPage2_t;
+
+#define MPI_BIOSPAGE2_PAGEVERSION                       (0x01)
+
+#define MPI_BIOSPAGE2_FORM_MASK                         (0x0F)
+#define MPI_BIOSPAGE2_FORM_ADAPTER_ORDER                (0x00)
+#define MPI_BIOSPAGE2_FORM_ADAPTER_NUMBER               (0x01)
+#define MPI_BIOSPAGE2_FORM_PCI_ADDRESS                  (0x02)
+#define MPI_BIOSPAGE2_FORM_PCI_SLOT_NUMBER              (0x03)
+#define MPI_BIOSPAGE2_FORM_FC_WWN                       (0x04)
+#define MPI_BIOSPAGE2_FORM_SAS_WWN                      (0x05)
+
 
 /****************************************************************************
 *   SCSI Port Config Pages
@@ -821,13 +1175,13 @@ typedef struct _CONFIG_PAGE_BIOS_1
 
 typedef struct _CONFIG_PAGE_SCSI_PORT_0
 {
-    fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    CONFIG_PAGE_HEADER      Header;                     /* 00h */
     U32                     Capabilities;               /* 04h */
     U32                     PhysicalInterface;          /* 08h */
-} fCONFIG_PAGE_SCSI_PORT_0, MPI_POINTER PTR_CONFIG_PAGE_SCSI_PORT_0,
+} CONFIG_PAGE_SCSI_PORT_0, MPI_POINTER PTR_CONFIG_PAGE_SCSI_PORT_0,
   SCSIPortPage0_t, MPI_POINTER pSCSIPortPage0_t;
 
-#define MPI_SCSIPORTPAGE0_PAGEVERSION                   (0x01)
+#define MPI_SCSIPORTPAGE0_PAGEVERSION                   (0x02)
 
 #define MPI_SCSIPORTPAGE0_CAP_IU                        (0x00000001)
 #define MPI_SCSIPORTPAGE0_CAP_DT                        (0x00000002)
@@ -854,6 +1208,7 @@ typedef struct _CONFIG_PAGE_SCSI_PORT_0
     (  ((Cap) & MPI_SCSIPORTPAGE0_CAP_MASK_MAX_SYNC_OFFSET) \
     >> MPI_SCSIPORTPAGE0_CAP_SHIFT_MAX_SYNC_OFFSET          \
     )
+#define MPI_SCSIPORTPAGE0_CAP_IDP                       (0x08000000)
 #define MPI_SCSIPORTPAGE0_CAP_WIDE                      (0x20000000)
 #define MPI_SCSIPORTPAGE0_CAP_AIP                       (0x80000000)
 
@@ -869,13 +1224,13 @@ typedef struct _CONFIG_PAGE_SCSI_PORT_0
 
 typedef struct _CONFIG_PAGE_SCSI_PORT_1
 {
-    fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    CONFIG_PAGE_HEADER      Header;                     /* 00h */
     U32                     Configuration;              /* 04h */
     U32                     OnBusTimerValue;            /* 08h */
     U8                      TargetConfig;               /* 0Ch */
     U8                      Reserved1;                  /* 0Dh */
     U16                     IDConfig;                   /* 0Eh */
-} fCONFIG_PAGE_SCSI_PORT_1, MPI_POINTER PTR_CONFIG_PAGE_SCSI_PORT_1,
+} CONFIG_PAGE_SCSI_PORT_1, MPI_POINTER PTR_CONFIG_PAGE_SCSI_PORT_1,
   SCSIPortPage1_t, MPI_POINTER pSCSIPortPage1_t;
 
 #define MPI_SCSIPORTPAGE1_PAGEVERSION                   (0x03)
@@ -900,11 +1255,11 @@ typedef struct _MPI_DEVICE_INFO
 
 typedef struct _CONFIG_PAGE_SCSI_PORT_2
 {
-    fCONFIG_PAGE_HEADER  Header;                         /* 00h */
+    CONFIG_PAGE_HEADER  Header;                         /* 00h */
     U32                 PortFlags;                      /* 04h */
     U32                 PortSettings;                   /* 08h */
     MPI_DEVICE_INFO     DeviceSettings[16];             /* 0Ch */
-} fCONFIG_PAGE_SCSI_PORT_2, MPI_POINTER PTR_CONFIG_PAGE_SCSI_PORT_2,
+} CONFIG_PAGE_SCSI_PORT_2, MPI_POINTER PTR_CONFIG_PAGE_SCSI_PORT_2,
   SCSIPortPage2_t, MPI_POINTER pSCSIPortPage2_t;
 
 #define MPI_SCSIPORTPAGE2_PAGEVERSION                       (0x02)
@@ -953,13 +1308,13 @@ typedef struct _CONFIG_PAGE_SCSI_PORT_2
 
 typedef struct _CONFIG_PAGE_SCSI_DEVICE_0
 {
-    fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    CONFIG_PAGE_HEADER      Header;                     /* 00h */
     U32                     NegotiatedParameters;       /* 04h */
     U32                     Information;                /* 08h */
-} fCONFIG_PAGE_SCSI_DEVICE_0, MPI_POINTER PTR_CONFIG_PAGE_SCSI_DEVICE_0,
+} CONFIG_PAGE_SCSI_DEVICE_0, MPI_POINTER PTR_CONFIG_PAGE_SCSI_DEVICE_0,
   SCSIDevicePage0_t, MPI_POINTER pSCSIDevicePage0_t;
 
-#define MPI_SCSIDEVPAGE0_PAGEVERSION                    (0x03)
+#define MPI_SCSIDEVPAGE0_PAGEVERSION                    (0x04)
 
 #define MPI_SCSIDEVPAGE0_NP_IU                          (0x00000001)
 #define MPI_SCSIDEVPAGE0_NP_DT                          (0x00000002)
@@ -973,6 +1328,7 @@ typedef struct _CONFIG_PAGE_SCSI_DEVICE_
 #define MPI_SCSIDEVPAGE0_NP_SHIFT_SYNC_PERIOD           (8)
 #define MPI_SCSIDEVPAGE0_NP_NEG_SYNC_OFFSET_MASK        (0x00FF0000)
 #define MPI_SCSIDEVPAGE0_NP_SHIFT_SYNC_OFFSET           (16)
+#define MPI_SCSIDEVPAGE0_NP_IDP                         (0x08000000)
 #define MPI_SCSIDEVPAGE0_NP_WIDE                        (0x20000000)
 #define MPI_SCSIDEVPAGE0_NP_AIP                         (0x80000000)
 
@@ -984,14 +1340,14 @@ typedef struct _CONFIG_PAGE_SCSI_DEVICE_
 
 typedef struct _CONFIG_PAGE_SCSI_DEVICE_1
 {
-    fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    CONFIG_PAGE_HEADER      Header;                     /* 00h */
     U32                     RequestedParameters;        /* 04h */
     U32                     Reserved;                   /* 08h */
     U32                     Configuration;              /* 0Ch */
-} fCONFIG_PAGE_SCSI_DEVICE_1, MPI_POINTER PTR_CONFIG_PAGE_SCSI_DEVICE_1,
+} CONFIG_PAGE_SCSI_DEVICE_1, MPI_POINTER PTR_CONFIG_PAGE_SCSI_DEVICE_1,
   SCSIDevicePage1_t, MPI_POINTER pSCSIDevicePage1_t;
 
-#define MPI_SCSIDEVPAGE1_PAGEVERSION                    (0x04)
+#define MPI_SCSIDEVPAGE1_PAGEVERSION                    (0x05)
 
 #define MPI_SCSIDEVPAGE1_RP_IU                          (0x00000001)
 #define MPI_SCSIDEVPAGE1_RP_DT                          (0x00000002)
@@ -1005,6 +1361,7 @@ typedef struct _CONFIG_PAGE_SCSI_DEVICE_
 #define MPI_SCSIDEVPAGE1_RP_SHIFT_MIN_SYNC_PERIOD       (8)
 #define MPI_SCSIDEVPAGE1_RP_MAX_SYNC_OFFSET_MASK        (0x00FF0000)
 #define MPI_SCSIDEVPAGE1_RP_SHIFT_MAX_SYNC_OFFSET       (16)
+#define MPI_SCSIDEVPAGE1_RP_IDP                         (0x08000000)
 #define MPI_SCSIDEVPAGE1_RP_WIDE                        (0x20000000)
 #define MPI_SCSIDEVPAGE1_RP_AIP                         (0x80000000)
 
@@ -1016,11 +1373,11 @@ typedef struct _CONFIG_PAGE_SCSI_DEVICE_
 
 typedef struct _CONFIG_PAGE_SCSI_DEVICE_2
 {
-    fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    CONFIG_PAGE_HEADER      Header;                     /* 00h */
     U32                     DomainValidation;           /* 04h */
     U32                     ParityPipeSelect;           /* 08h */
     U32                     DataPipeSelect;             /* 0Ch */
-} fCONFIG_PAGE_SCSI_DEVICE_2, MPI_POINTER PTR_CONFIG_PAGE_SCSI_DEVICE_2,
+} CONFIG_PAGE_SCSI_DEVICE_2, MPI_POINTER PTR_CONFIG_PAGE_SCSI_DEVICE_2,
   SCSIDevicePage2_t, MPI_POINTER pSCSIDevicePage2_t;
 
 #define MPI_SCSIDEVPAGE2_PAGEVERSION                    (0x01)
@@ -1057,12 +1414,12 @@ typedef struct _CONFIG_PAGE_SCSI_DEVICE_
 
 typedef struct _CONFIG_PAGE_SCSI_DEVICE_3
 {
-    fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    CONFIG_PAGE_HEADER      Header;                     /* 00h */
     U16                     MsgRejectCount;             /* 04h */
     U16                     PhaseErrorCount;            /* 06h */
     U16                     ParityErrorCount;           /* 08h */
     U16                     Reserved;                   /* 0Ah */
-} fCONFIG_PAGE_SCSI_DEVICE_3, MPI_POINTER PTR_CONFIG_PAGE_SCSI_DEVICE_3,
+} CONFIG_PAGE_SCSI_DEVICE_3, MPI_POINTER PTR_CONFIG_PAGE_SCSI_DEVICE_3,
   SCSIDevicePage3_t, MPI_POINTER pSCSIDevicePage3_t;
 
 #define MPI_SCSIDEVPAGE3_PAGEVERSION                    (0x00)
@@ -1077,7 +1434,7 @@ typedef struct _CONFIG_PAGE_SCSI_DEVICE_
 
 typedef struct _CONFIG_PAGE_FC_PORT_0
 {
-    fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    CONFIG_PAGE_HEADER      Header;                     /* 00h */
     U32                     Flags;                      /* 04h */
     U8                      MPIPortNumber;              /* 08h */
     U8                      LinkType;                   /* 09h */
@@ -1098,7 +1455,7 @@ typedef struct _CONFIG_PAGE_FC_PORT_0
     U8                      MaxHardAliasesSupported;    /* 49h */
     U8                      NumCurrentAliases;          /* 4Ah */
     U8                      Reserved1;                  /* 4Bh */
-} fCONFIG_PAGE_FC_PORT_0, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_0,
+} CONFIG_PAGE_FC_PORT_0, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_0,
   FCPortPage0_t, MPI_POINTER pFCPortPage0_t;
 
 #define MPI_FCPORTPAGE0_PAGEVERSION                     (0x02)
@@ -1164,10 +1521,9 @@ typedef struct _CONFIG_PAGE_FC_PORT_0
 #define MPI_FCPORTPAGE0_CURRENT_SPEED_NOT_NEGOTIATED    (0x00008000)        /* (SNIA)HBA_PORTSPEED_NOT_NEGOTIATED (1<<15) Speed not established */
 
 
-
 typedef struct _CONFIG_PAGE_FC_PORT_1
 {
-    fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    CONFIG_PAGE_HEADER      Header;                     /* 00h */
     U32                     Flags;                      /* 04h */
     U64                     NoSEEPROMWWNN;              /* 08h */
     U64                     NoSEEPROMWWPN;              /* 10h */
@@ -1179,7 +1535,7 @@ typedef struct _CONFIG_PAGE_FC_PORT_1
     U8                      RR_TOV;                     /* 1Dh */
     U8                      InitiatorDeviceTimeout;     /* 1Eh */
     U8                      InitiatorIoPendTimeout;     /* 1Fh */
-} fCONFIG_PAGE_FC_PORT_1, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_1,
+} CONFIG_PAGE_FC_PORT_1, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_1,
   FCPortPage1_t, MPI_POINTER pFCPortPage1_t;
 
 #define MPI_FCPORTPAGE1_PAGEVERSION                     (0x06)
@@ -1191,6 +1547,7 @@ typedef struct _CONFIG_PAGE_FC_PORT_1
 #define MPI_FCPORTPAGE1_FLAGS_TARGET_MODE_OXID          (0x00800000)
 #define MPI_FCPORTPAGE1_FLAGS_PORT_OFFLINE              (0x00400000)
 #define MPI_FCPORTPAGE1_FLAGS_SOFT_ALPA_FALLBACK        (0x00200000)
+#define MPI_FCPORTPAGE1_FLAGS_TARGET_LARGE_CDB_ENABLE   (0x00000080)
 #define MPI_FCPORTPAGE1_FLAGS_MASK_RR_TOV_UNITS         (0x00000070)
 #define MPI_FCPORTPAGE1_FLAGS_SUPPRESS_PROT_REG         (0x00000008)
 #define MPI_FCPORTPAGE1_FLAGS_PLOGI_ON_LOGO             (0x00000004)
@@ -1227,14 +1584,15 @@ typedef struct _CONFIG_PAGE_FC_PORT_1
 #define MPI_FCPORTPAGE1_ALT_CONN_UNKNOWN                (0x00)
 
 #define MPI_FCPORTPAGE1_INITIATOR_DEV_TIMEOUT_MASK      (0x7F)
+#define MPI_FCPORTPAGE1_INITIATOR_DEV_UNIT_16           (0x80)
 
 
 typedef struct _CONFIG_PAGE_FC_PORT_2
 {
-    fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    CONFIG_PAGE_HEADER      Header;                     /* 00h */
     U8                      NumberActive;               /* 04h */
     U8                      ALPA[127];                  /* 05h */
-} fCONFIG_PAGE_FC_PORT_2, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_2,
+} CONFIG_PAGE_FC_PORT_2, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_2,
   FCPortPage2_t, MPI_POINTER pFCPortPage2_t;
 
 #define MPI_FCPORTPAGE2_PAGEVERSION                     (0x01)
@@ -1280,9 +1638,9 @@ typedef struct _FC_PORT_PERSISTENT
 
 typedef struct _CONFIG_PAGE_FC_PORT_3
 {
-    fCONFIG_PAGE_HEADER      Header;                                 /* 00h */
+    CONFIG_PAGE_HEADER      Header;                                 /* 00h */
     FC_PORT_PERSISTENT      Entry[MPI_FC_PORT_PAGE_3_ENTRY_MAX];    /* 04h */
-} fCONFIG_PAGE_FC_PORT_3, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_3,
+} CONFIG_PAGE_FC_PORT_3, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_3,
   FCPortPage3_t, MPI_POINTER pFCPortPage3_t;
 
 #define MPI_FCPORTPAGE3_PAGEVERSION                     (0x01)
@@ -1290,10 +1648,10 @@ typedef struct _CONFIG_PAGE_FC_PORT_3
 
 typedef struct _CONFIG_PAGE_FC_PORT_4
 {
-    fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    CONFIG_PAGE_HEADER      Header;                     /* 00h */
     U32                     PortFlags;                  /* 04h */
     U32                     PortSettings;               /* 08h */
-} fCONFIG_PAGE_FC_PORT_4, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_4,
+} CONFIG_PAGE_FC_PORT_4, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_4,
   FCPortPage4_t, MPI_POINTER pFCPortPage4_t;
 
 #define MPI_FCPORTPAGE4_PAGEVERSION                     (0x00)
@@ -1316,15 +1674,15 @@ typedef struct _CONFIG_PAGE_FC_PORT_5_AL
     U16     Reserved;                                   /* 02h */
     U64     AliasWWNN;                                  /* 04h */
     U64     AliasWWPN;                                  /* 0Ch */
-} fCONFIG_PAGE_FC_PORT_5_ALIAS_INFO,
+} CONFIG_PAGE_FC_PORT_5_ALIAS_INFO,
   MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_5_ALIAS_INFO,
   FcPortPage5AliasInfo_t, MPI_POINTER pFcPortPage5AliasInfo_t;
 
 typedef struct _CONFIG_PAGE_FC_PORT_5
 {
-    fCONFIG_PAGE_HEADER                  Header;         /* 00h */
-    fCONFIG_PAGE_FC_PORT_5_ALIAS_INFO    AliasInfo;      /* 04h */
-} fCONFIG_PAGE_FC_PORT_5, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_5,
+    CONFIG_PAGE_HEADER                  Header;         /* 00h */
+    CONFIG_PAGE_FC_PORT_5_ALIAS_INFO    AliasInfo;      /* 04h */
+} CONFIG_PAGE_FC_PORT_5, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_5,
   FCPortPage5_t, MPI_POINTER pFCPortPage5_t;
 
 #define MPI_FCPORTPAGE5_PAGEVERSION                     (0x02)
@@ -1337,7 +1695,7 @@ typedef struct _CONFIG_PAGE_FC_PORT_5
 
 typedef struct _CONFIG_PAGE_FC_PORT_6
 {
-    fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    CONFIG_PAGE_HEADER      Header;                     /* 00h */
     U32                     Reserved;                   /* 04h */
     U64                     TimeSinceReset;             /* 08h */
     U64                     TxFrames;                   /* 10h */
@@ -1355,7 +1713,7 @@ typedef struct _CONFIG_PAGE_FC_PORT_6
     U64                     InvalidTxWordCount;         /* 70h */
     U64                     InvalidCrcCount;            /* 78h */
     U64                     FcpInitiatorIoCount;        /* 80h */
-} fCONFIG_PAGE_FC_PORT_6, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_6,
+} CONFIG_PAGE_FC_PORT_6, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_6,
   FCPortPage6_t, MPI_POINTER pFCPortPage6_t;
 
 #define MPI_FCPORTPAGE6_PAGEVERSION                     (0x00)
@@ -1363,10 +1721,10 @@ typedef struct _CONFIG_PAGE_FC_PORT_6
 
 typedef struct _CONFIG_PAGE_FC_PORT_7
 {
-    fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    CONFIG_PAGE_HEADER      Header;                     /* 00h */
     U32                     Reserved;                   /* 04h */
     U8                      PortSymbolicName[256];      /* 08h */
-} fCONFIG_PAGE_FC_PORT_7, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_7,
+} CONFIG_PAGE_FC_PORT_7, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_7,
   FCPortPage7_t, MPI_POINTER pFCPortPage7_t;
 
 #define MPI_FCPORTPAGE7_PAGEVERSION                     (0x00)
@@ -1374,9 +1732,9 @@ typedef struct _CONFIG_PAGE_FC_PORT_7
 
 typedef struct _CONFIG_PAGE_FC_PORT_8
 {
-    fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    CONFIG_PAGE_HEADER      Header;                     /* 00h */
     U32                     BitVector[8];               /* 04h */
-} fCONFIG_PAGE_FC_PORT_8, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_8,
+} CONFIG_PAGE_FC_PORT_8, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_8,
   FCPortPage8_t, MPI_POINTER pFCPortPage8_t;
 
 #define MPI_FCPORTPAGE8_PAGEVERSION                     (0x00)
@@ -1384,7 +1742,7 @@ typedef struct _CONFIG_PAGE_FC_PORT_8
 
 typedef struct _CONFIG_PAGE_FC_PORT_9
 {
-    fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    CONFIG_PAGE_HEADER      Header;                     /* 00h */
     U32                     Reserved;                   /* 04h */
     U64                     GlobalWWPN;                 /* 08h */
     U64                     GlobalWWNN;                 /* 10h */
@@ -1396,7 +1754,7 @@ typedef struct _CONFIG_PAGE_FC_PORT_9
     U8                      IPAddress[16];              /* 28h */
     U16                     Reserved1;                  /* 38h */
     U16                     TopologyDiscoveryFlags;     /* 3Ah */
-} fCONFIG_PAGE_FC_PORT_9, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_9,
+} CONFIG_PAGE_FC_PORT_9, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_9,
   FCPortPage9_t, MPI_POINTER pFCPortPage9_t;
 
 #define MPI_FCPORTPAGE9_PAGEVERSION                     (0x00)
@@ -1422,10 +1780,10 @@ typedef struct _CONFIG_PAGE_FC_PORT_10_B
     U8                      VendorOUI[3];               /* 35h */
     U8                      VendorPN[16];               /* 38h */
     U8                      VendorRev[4];               /* 48h */
-    U16                     Reserved4;                  /* 4Ch */
-    U8                      Reserved5;                  /* 4Eh */
+    U16                     Wavelength;                 /* 4Ch */
+    U8                      Reserved4;                  /* 4Eh */
     U8                      CC_BASE;                    /* 4Fh */
-} fCONFIG_PAGE_FC_PORT_10_BASE_SFP_DATA,
+} CONFIG_PAGE_FC_PORT_10_BASE_SFP_DATA,
   MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_10_BASE_SFP_DATA,
   FCPortPage10BaseSfpData_t, MPI_POINTER pFCPortPage10BaseSfpData_t;
 
@@ -1481,9 +1839,11 @@ typedef struct _CONFIG_PAGE_FC_PORT_10_E
     U8                      BitRateMin;                 /* 53h */
     U8                      VendorSN[16];               /* 54h */
     U8                      DateCode[8];                /* 64h */
-    U8                      Reserved5[3];               /* 6Ch */
+    U8                      DiagMonitoringType;         /* 6Ch */
+    U8                      EnhancedOptions;            /* 6Dh */
+    U8                      SFF8472Compliance;          /* 6Eh */
     U8                      CC_EXT;                     /* 6Fh */
-} fCONFIG_PAGE_FC_PORT_10_EXTENDED_SFP_DATA,
+} CONFIG_PAGE_FC_PORT_10_EXTENDED_SFP_DATA,
   MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_10_EXTENDED_SFP_DATA,
   FCPortPage10ExtendedSfpData_t, MPI_POINTER pFCPortPage10ExtendedSfpData_t;
 
@@ -1496,19 +1856,19 @@ typedef struct _CONFIG_PAGE_FC_PORT_10_E
 
 typedef struct _CONFIG_PAGE_FC_PORT_10
 {
-    fCONFIG_PAGE_HEADER                          Header;             /* 00h */
+    CONFIG_PAGE_HEADER                          Header;             /* 00h */
     U8                                          Flags;              /* 04h */
     U8                                          Reserved1;          /* 05h */
     U16                                         Reserved2;          /* 06h */
     U32                                         HwConfig1;          /* 08h */
     U32                                         HwConfig2;          /* 0Ch */
-    fCONFIG_PAGE_FC_PORT_10_BASE_SFP_DATA        Base;               /* 10h */
-    fCONFIG_PAGE_FC_PORT_10_EXTENDED_SFP_DATA    Extended;           /* 50h */
+    CONFIG_PAGE_FC_PORT_10_BASE_SFP_DATA        Base;               /* 10h */
+    CONFIG_PAGE_FC_PORT_10_EXTENDED_SFP_DATA    Extended;           /* 50h */
     U8                                          VendorSpecific[32]; /* 70h */
-} fCONFIG_PAGE_FC_PORT_10, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_10,
+} CONFIG_PAGE_FC_PORT_10, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_10,
   FCPortPage10_t, MPI_POINTER pFCPortPage10_t;
 
-#define MPI_FCPORTPAGE10_PAGEVERSION                    (0x00)
+#define MPI_FCPORTPAGE10_PAGEVERSION                    (0x01)
 
 /* standard MODDEF pin definitions (from GBIC spec.) */
 #define MPI_FCPORTPAGE10_FLAGS_MODDEF_MASK              (0x00000007)
@@ -1534,7 +1894,7 @@ typedef struct _CONFIG_PAGE_FC_PORT_10
 
 typedef struct _CONFIG_PAGE_FC_DEVICE_0
 {
-    fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    CONFIG_PAGE_HEADER      Header;                     /* 00h */
     U64                     WWNN;                       /* 04h */
     U64                     WWPN;                       /* 0Ch */
     U32                     PortIdentifier;             /* 14h */
@@ -1548,7 +1908,7 @@ typedef struct _CONFIG_PAGE_FC_DEVICE_0
     U8                      FcPhHighestVersion;         /* 21h */
     U8                      CurrentTargetID;            /* 22h */
     U8                      CurrentBus;                 /* 23h */
-} fCONFIG_PAGE_FC_DEVICE_0, MPI_POINTER PTR_CONFIG_PAGE_FC_DEVICE_0,
+} CONFIG_PAGE_FC_DEVICE_0, MPI_POINTER PTR_CONFIG_PAGE_FC_DEVICE_0,
   FCDevicePage0_t, MPI_POINTER pFCDevicePage0_t;
 
 #define MPI_FC_DEVICE_PAGE0_PAGEVERSION                 (0x03)
@@ -1606,6 +1966,7 @@ typedef struct _RAID_VOL0_STATUS
 #define MPI_RAIDVOL0_STATUS_STATE_OPTIMAL               (0x00)
 #define MPI_RAIDVOL0_STATUS_STATE_DEGRADED              (0x01)
 #define MPI_RAIDVOL0_STATUS_STATE_FAILED                (0x02)
+#define MPI_RAIDVOL0_STATUS_STATE_MISSING               (0x03)
 
 typedef struct _RAID_VOL0_SETTINGS
 {
@@ -1616,11 +1977,11 @@ typedef struct _RAID_VOL0_SETTINGS
   RaidVol0Settings, MPI_POINTER pRaidVol0Settings;
 
 /* RAID Volume Page 0 VolumeSettings defines */
-
 #define MPI_RAIDVOL0_SETTING_WRITE_CACHING_ENABLE       (0x0001)
 #define MPI_RAIDVOL0_SETTING_OFFLINE_ON_SMART           (0x0002)
 #define MPI_RAIDVOL0_SETTING_AUTO_CONFIGURE             (0x0004)
 #define MPI_RAIDVOL0_SETTING_PRIORITY_RESYNC            (0x0008)
+#define MPI_RAIDVOL0_SETTING_FAST_DATA_SCRUBBING_0102   (0x0020) /* obsolete */
 #define MPI_RAIDVOL0_SETTING_USE_PRODUCT_ID_SUFFIX      (0x0010)
 #define MPI_RAIDVOL0_SETTING_USE_DEFAULTS               (0x8000)
 
@@ -1644,7 +2005,7 @@ typedef struct _RAID_VOL0_SETTINGS
 
 typedef struct _CONFIG_PAGE_RAID_VOL_0
 {
-    fCONFIG_PAGE_HEADER      Header;         /* 00h */
+    CONFIG_PAGE_HEADER      Header;         /* 00h */
     U8                      VolumeID;       /* 04h */
     U8                      VolumeBus;      /* 05h */
     U8                      VolumeIOC;      /* 06h */
@@ -1657,13 +2018,41 @@ typedef struct _CONFIG_PAGE_RAID_VOL_0
     U32                     Reserved2;      /* 1Ch */
     U32                     Reserved3;      /* 20h */
     U8                      NumPhysDisks;   /* 24h */
-    U8                      Reserved4;      /* 25h */
-    U16                     Reserved5;      /* 26h */
+    U8                      DataScrubRate;  /* 25h */
+    U8                      ResyncRate;     /* 26h */
+    U8                      InactiveStatus; /* 27h */
     RAID_VOL0_PHYS_DISK     PhysDisk[MPI_RAID_VOL_PAGE_0_PHYSDISK_MAX];/* 28h */
-} fCONFIG_PAGE_RAID_VOL_0, MPI_POINTER PTR_CONFIG_PAGE_RAID_VOL_0,
+} CONFIG_PAGE_RAID_VOL_0, MPI_POINTER PTR_CONFIG_PAGE_RAID_VOL_0,
   RaidVolumePage0_t, MPI_POINTER pRaidVolumePage0_t;
 
-#define MPI_RAIDVOLPAGE0_PAGEVERSION                    (0x01)
+#define MPI_RAIDVOLPAGE0_PAGEVERSION                    (0x04)
+
+/* values for RAID Volume Page 0 InactiveStatus field */
+#define MPI_RAIDVOLPAGE0_UNKNOWN_INACTIVE               (0x00)
+#define MPI_RAIDVOLPAGE0_STALE_METADATA_INACTIVE        (0x01)
+#define MPI_RAIDVOLPAGE0_FOREIGN_VOLUME_INACTIVE        (0x02)
+#define MPI_RAIDVOLPAGE0_INSUFFICIENT_RESOURCE_INACTIVE (0x03)
+#define MPI_RAIDVOLPAGE0_CLONE_VOLUME_INACTIVE          (0x04)
+#define MPI_RAIDVOLPAGE0_INSUFFICIENT_METADATA_INACTIVE (0x05)
+#define MPI_RAIDVOLPAGE0_PREVIOUSLY_DELETED             (0x06)
+
+
+typedef struct _CONFIG_PAGE_RAID_VOL_1
+{
+    CONFIG_PAGE_HEADER      Header;         /* 00h */
+    U8                      VolumeID;       /* 01h */
+    U8                      VolumeBus;      /* 02h */
+    U8                      VolumeIOC;      /* 03h */
+    U8                      Reserved0;      /* 04h */
+    U8                      GUID[24];       /* 05h */
+    U8                      Name[32];       /* 20h */
+    U64                     WWID;           /* 40h */
+    U32                     Reserved1;      /* 48h */
+    U32                     Reserved2;      /* 4Ch */
+} CONFIG_PAGE_RAID_VOL_1, MPI_POINTER PTR_CONFIG_PAGE_RAID_VOL_1,
+  RaidVolumePage1_t, MPI_POINTER pRaidVolumePage1_t;
+
+#define MPI_RAIDVOLPAGE1_PAGEVERSION                    (0x01)
 
 
 /****************************************************************************
@@ -1714,6 +2103,7 @@ typedef struct _RAID_PHYS_DISK0_STATUS
 
 #define MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC           (0x01)
 #define MPI_PHYSDISK0_STATUS_FLAG_QUIESCED              (0x02)
+#define MPI_PHYSDISK0_STATUS_FLAG_INACTIVE_VOLUME       (0x04)
 
 #define MPI_PHYSDISK0_STATUS_ONLINE                     (0x00)
 #define MPI_PHYSDISK0_STATUS_MISSING                    (0x01)
@@ -1726,24 +2116,54 @@ typedef struct _RAID_PHYS_DISK0_STATUS
 
 typedef struct _CONFIG_PAGE_RAID_PHYS_DISK_0
 {
-    fCONFIG_PAGE_HEADER              Header;             /* 00h */
+    CONFIG_PAGE_HEADER              Header;             /* 00h */
     U8                              PhysDiskID;         /* 04h */
     U8                              PhysDiskBus;        /* 05h */
     U8                              PhysDiskIOC;        /* 06h */
     U8                              PhysDiskNum;        /* 07h */
     RAID_PHYS_DISK0_SETTINGS        PhysDiskSettings;   /* 08h */
     U32                             Reserved1;          /* 0Ch */
-    U32                             Reserved2;          /* 10h */
-    U32                             Reserved3;          /* 14h */
+    U8                              ExtDiskIdentifier[8]; /* 10h */
     U8                              DiskIdentifier[16]; /* 18h */
     RAID_PHYS_DISK0_INQUIRY_DATA    InquiryData;        /* 28h */
     RAID_PHYS_DISK0_STATUS          PhysDiskStatus;     /* 64h */
     U32                             MaxLBA;             /* 68h */
     RAID_PHYS_DISK0_ERROR_DATA      ErrorData;          /* 6Ch */
-} fCONFIG_PAGE_RAID_PHYS_DISK_0, MPI_POINTER PTR_CONFIG_PAGE_RAID_PHYS_DISK_0,
+} CONFIG_PAGE_RAID_PHYS_DISK_0, MPI_POINTER PTR_CONFIG_PAGE_RAID_PHYS_DISK_0,
   RaidPhysDiskPage0_t, MPI_POINTER pRaidPhysDiskPage0_t;
 
-#define MPI_RAIDPHYSDISKPAGE0_PAGEVERSION           (0x00)
+#define MPI_RAIDPHYSDISKPAGE0_PAGEVERSION           (0x01)
+
+
+typedef struct _RAID_PHYS_DISK1_PATH
+{
+    U8                              PhysDiskID;         /* 00h */
+    U8                              PhysDiskBus;        /* 01h */
+    U16                             Reserved1;          /* 02h */
+    U64                             WWID;               /* 04h */
+    U64                             OwnerWWID;          /* 0Ch */
+    U8                              OwnerIdentifier;    /* 14h */
+    U8                              Reserved2;          /* 15h */
+    U16                             Flags;              /* 16h */
+} RAID_PHYS_DISK1_PATH, MPI_POINTER PTR_RAID_PHYS_DISK1_PATH,
+  RaidPhysDisk1Path_t, MPI_POINTER pRaidPhysDisk1Path_t;
+
+/* RAID Physical Disk Page 1 Flags field defines */
+#define MPI_RAID_PHYSDISK1_FLAG_BROKEN          (0x0002)
+#define MPI_RAID_PHYSDISK1_FLAG_INVALID         (0x0001)
+
+typedef struct _CONFIG_PAGE_RAID_PHYS_DISK_1
+{
+    CONFIG_PAGE_HEADER              Header;             /* 00h */
+    U8                              NumPhysDiskPaths;   /* 04h */
+    U8                              PhysDiskNum;        /* 05h */
+    U16                             Reserved2;          /* 06h */
+    U32                             Reserved1;          /* 08h */
+    RAID_PHYS_DISK1_PATH            Path[1];            /* 0Ch */
+} CONFIG_PAGE_RAID_PHYS_DISK_1, MPI_POINTER PTR_CONFIG_PAGE_RAID_PHYS_DISK_1,
+  RaidPhysDiskPage1_t, MPI_POINTER pRaidPhysDiskPage1_t;
+
+#define MPI_RAIDPHYSDISKPAGE1_PAGEVERSION       (0x00)
 
 
 /****************************************************************************
@@ -1756,7 +2176,7 @@ typedef struct _CONFIG_PAGE_LAN_0
     U16                     TxRxModes;                  /* 04h */
     U16                     Reserved;                   /* 06h */
     U32                     PacketPrePad;               /* 08h */
-} fCONFIG_PAGE_LAN_0, MPI_POINTER PTR_CONFIG_PAGE_LAN_0,
+} CONFIG_PAGE_LAN_0, MPI_POINTER PTR_CONFIG_PAGE_LAN_0,
   LANPage0_t, MPI_POINTER pLANPage0_t;
 
 #define MPI_LAN_PAGE0_PAGEVERSION                       (0x01)
@@ -1781,7 +2201,7 @@ typedef struct _CONFIG_PAGE_LAN_1
     U32                     MaxReplySize;               /* 24h */
     U32                     NegWireSpeedLow;            /* 28h */
     U32                     NegWireSpeedHigh;           /* 2Ch */
-} fCONFIG_PAGE_LAN_1, MPI_POINTER PTR_CONFIG_PAGE_LAN_1,
+} CONFIG_PAGE_LAN_1, MPI_POINTER PTR_CONFIG_PAGE_LAN_1,
   LANPage1_t, MPI_POINTER pLANPage1_t;
 
 #define MPI_LAN_PAGE1_PAGEVERSION                       (0x03)
@@ -1796,11 +2216,11 @@ typedef struct _CONFIG_PAGE_LAN_1
 
 typedef struct _CONFIG_PAGE_INBAND_0
 {
-    fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    CONFIG_PAGE_HEADER      Header;                     /* 00h */
     MPI_VERSION_FORMAT      InbandVersion;              /* 04h */
     U16                     MaximumBuffers;             /* 08h */
     U16                     Reserved1;                  /* 0Ah */
-} fCONFIG_PAGE_INBAND_0, MPI_POINTER PTR_CONFIG_PAGE_INBAND_0,
+} CONFIG_PAGE_INBAND_0, MPI_POINTER PTR_CONFIG_PAGE_INBAND_0,
   InbandPage0_t, MPI_POINTER pInbandPage0_t;
 
 #define MPI_INBAND_PAGEVERSION          (0x00)
@@ -1820,7 +2240,7 @@ typedef struct _MPI_SAS_IO_UNIT0_PHY_DAT
     U32         ControllerPhyDeviceInfo;/* 04h */
     U16         AttachedDeviceHandle;   /* 08h */
     U16         ControllerDevHandle;    /* 0Ah */
-    U32         Reserved2;              /* 0Ch */
+    U32         DiscoveryStatus;        /* 0Ch */
 } MPI_SAS_IO_UNIT0_PHY_DATA, MPI_POINTER PTR_MPI_SAS_IO_UNIT0_PHY_DATA,
   SasIOUnit0PhyData, MPI_POINTER pSasIOUnit0PhyData;
 
@@ -1834,22 +2254,21 @@ typedef struct _MPI_SAS_IO_UNIT0_PHY_DAT
 
 typedef struct _CONFIG_PAGE_SAS_IO_UNIT_0
 {
-    fCONFIG_EXTENDED_PAGE_HEADER     Header;                             /* 00h */
+    CONFIG_EXTENDED_PAGE_HEADER     Header;                             /* 00h */
     U32                             Reserved1;                          /* 08h */
     U8                              NumPhys;                            /* 0Ch */
     U8                              Reserved2;                          /* 0Dh */
     U16                             Reserved3;                          /* 0Eh */
     MPI_SAS_IO_UNIT0_PHY_DATA       PhyData[MPI_SAS_IOUNIT0_PHY_MAX];   /* 10h */
-} fCONFIG_PAGE_SAS_IO_UNIT_0, MPI_POINTER PTR_CONFIG_PAGE_SAS_IO_UNIT_0,
+} CONFIG_PAGE_SAS_IO_UNIT_0, MPI_POINTER PTR_CONFIG_PAGE_SAS_IO_UNIT_0,
   SasIOUnitPage0_t, MPI_POINTER pSasIOUnitPage0_t;
 
-#define MPI_SASIOUNITPAGE0_PAGEVERSION      (0x00)
+#define MPI_SASIOUNITPAGE0_PAGEVERSION      (0x02)
 
 /* values for SAS IO Unit Page 0 PortFlags */
 #define MPI_SAS_IOUNIT0_PORT_FLAGS_DISCOVERY_IN_PROGRESS    (0x08)
 #define MPI_SAS_IOUNIT0_PORT_FLAGS_0_TARGET_IOC_NUM         (0x00)
 #define MPI_SAS_IOUNIT0_PORT_FLAGS_1_TARGET_IOC_NUM         (0x04)
-#define MPI_SAS_IOUNIT0_PORT_FLAGS_WAIT_FOR_PORTENABLE      (0x02)
 #define MPI_SAS_IOUNIT0_PORT_FLAGS_AUTO_PORT_CONFIG         (0x01)
 
 /* values for SAS IO Unit Page 0 PhyFlags */
@@ -1867,6 +2286,20 @@ typedef struct _CONFIG_PAGE_SAS_IO_UNIT_
 
 /* see mpi_sas.h for values for SAS IO Unit Page 0 ControllerPhyDeviceInfo values */
 
+/* values for SAS IO Unit Page 0 DiscoveryStatus */
+#define MPI_SAS_IOUNIT0_DS_LOOP_DETECTED                    (0x00000001)
+#define MPI_SAS_IOUNIT0_DS_UNADDRESSABLE_DEVICE             (0x00000002)
+#define MPI_SAS_IOUNIT0_DS_MULTIPLE_PORTS                   (0x00000004)
+#define MPI_SAS_IOUNIT0_DS_EXPANDER_ERR                     (0x00000008)
+#define MPI_SAS_IOUNIT0_DS_SMP_TIMEOUT                      (0x00000010)
+#define MPI_SAS_IOUNIT0_DS_OUT_ROUTE_ENTRIES                (0x00000020)
+#define MPI_SAS_IOUNIT0_DS_INDEX_NOT_EXIST                  (0x00000040)
+#define MPI_SAS_IOUNIT0_DS_SMP_FUNCTION_FAILED              (0x00000080)
+#define MPI_SAS_IOUNIT0_DS_SMP_CRC_ERROR                    (0x00000100)
+#define MPI_SAS_IOUNIT0_DS_SUBTRACTIVE_LINK                 (0x00000200)
+#define MPI_SAS_IOUNIT0_DS_TABLE_LINK                       (0x00000400)
+#define MPI_SAS_IOUNIT0_DS_UNSUPPORTED_DEVICE               (0x00000800)
+
 
 typedef struct _MPI_SAS_IO_UNIT1_PHY_DATA
 {
@@ -1889,52 +2322,75 @@ typedef struct _MPI_SAS_IO_UNIT1_PHY_DAT
 
 typedef struct _CONFIG_PAGE_SAS_IO_UNIT_1
 {
-    fCONFIG_EXTENDED_PAGE_HEADER Header;                             /* 00h */
-    U32                         Reserved1;                          /* 08h */
-    U8                          NumPhys;                            /* 0Ch */
-    U8                          Reserved2;                          /* 0Dh */
-    U16                         Reserved3;                          /* 0Eh */
-    MPI_SAS_IO_UNIT1_PHY_DATA   PhyData[MPI_SAS_IOUNIT1_PHY_MAX];   /* 10h */
-} fCONFIG_PAGE_SAS_IO_UNIT_1, MPI_POINTER PTR_CONFIG_PAGE_SAS_IO_UNIT_1,
+    CONFIG_EXTENDED_PAGE_HEADER Header;                             /* 00h */
+    U16                         ControlFlags;                       /* 08h */
+    U16                         MaxNumSATATargets;                  /* 0Ah */
+    U32                         Reserved1;                          /* 0Ch */
+    U8                          NumPhys;                            /* 10h */
+    U8                          SATAMaxQDepth;                      /* 11h */
+    U16                         Reserved2;                          /* 12h */
+    MPI_SAS_IO_UNIT1_PHY_DATA   PhyData[MPI_SAS_IOUNIT1_PHY_MAX];   /* 14h */
+} CONFIG_PAGE_SAS_IO_UNIT_1, MPI_POINTER PTR_CONFIG_PAGE_SAS_IO_UNIT_1,
   SasIOUnitPage1_t, MPI_POINTER pSasIOUnitPage1_t;
 
-#define MPI_SASIOUNITPAGE1_PAGEVERSION      (0x00)
+#define MPI_SASIOUNITPAGE1_PAGEVERSION      (0x04)
 
-/* values for SAS IO Unit Page 0 PortFlags */
-#define MPI_SAS_IOUNIT1_PORT_FLAGS_0_TARGET_IOC_NUM         (0x00)
-#define MPI_SAS_IOUNIT1_PORT_FLAGS_1_TARGET_IOC_NUM         (0x04)
-#define MPI_SAS_IOUNIT1_PORT_FLAGS_WAIT_FOR_PORTENABLE      (0x02)
-#define MPI_SAS_IOUNIT1_PORT_FLAGS_AUTO_PORT_CONFIG         (0x01)
+/* values for SAS IO Unit Page 1 ControlFlags */
+#define MPI_SAS_IOUNIT1_CONTROL_SATA_3_0_MAX            (0x4000)
+#define MPI_SAS_IOUNIT1_CONTROL_SATA_1_5_MAX            (0x2000)
+#define MPI_SAS_IOUNIT1_CONTROL_SATA_SW_PRESERVE        (0x1000)
+#define MPI_SAS_IOUNIT1_CONTROL_DISABLE_SAS_HASH        (0x0800)
+
+#define MPI_SAS_IOUNIT1_CONTROL_MASK_DEV_SUPPORT        (0x0600)
+#define MPI_SAS_IOUNIT1_CONTROL_SHIFT_DEV_SUPPORT       (9)
+#define MPI_SAS_IOUNIT1_CONTROL_DEV_SUPPORT_BOTH        (0x00)
+#define MPI_SAS_IOUNIT1_CONTROL_DEV_SAS_SUPPORT         (0x01)
+#define MPI_SAS_IOUNIT1_CONTROL_DEV_SATA_SUPPORT        (0x10)
+
+#define MPI_SAS_IOUNIT1_CONTROL_AUTO_PORT_SAME_SAS_ADDR (0x0100)
+#define MPI_SAS_IOUNIT1_CONTROL_SATA_48BIT_LBA_REQUIRED (0x0080)
+#define MPI_SAS_IOUNIT1_CONTROL_SATA_SMART_REQUIRED     (0x0040)
+#define MPI_SAS_IOUNIT1_CONTROL_SATA_NCQ_REQUIRED       (0x0020)
+#define MPI_SAS_IOUNIT1_CONTROL_SATA_FUA_REQUIRED       (0x0010)
+#define MPI_SAS_IOUNIT1_CONTROL_PHY_ENABLE_ORDER_HIGH   (0x0008)
+#define MPI_SAS_IOUNIT1_CONTROL_SUBTRACTIVE_ILLEGAL     (0x0004)
+#define MPI_SAS_IOUNIT1_CONTROL_FIRST_LVL_DISC_ONLY     (0x0002)
+#define MPI_SAS_IOUNIT1_CONTROL_CLEAR_AFFILIATION       (0x0001)
+
+/* values for SAS IO Unit Page 1 PortFlags */
+#define MPI_SAS_IOUNIT1_PORT_FLAGS_0_TARGET_IOC_NUM     (0x00)
+#define MPI_SAS_IOUNIT1_PORT_FLAGS_1_TARGET_IOC_NUM     (0x04)
+#define MPI_SAS_IOUNIT1_PORT_FLAGS_AUTO_PORT_CONFIG     (0x01)
 
 /* values for SAS IO Unit Page 0 PhyFlags */
-#define MPI_SAS_IOUNIT1_PHY_FLAGS_PHY_DISABLE               (0x04)
-#define MPI_SAS_IOUNIT1_PHY_FLAGS_TX_INVERT                 (0x02)
-#define MPI_SAS_IOUNIT1_PHY_FLAGS_RX_INVERT                 (0x01)
+#define MPI_SAS_IOUNIT1_PHY_FLAGS_PHY_DISABLE           (0x04)
+#define MPI_SAS_IOUNIT1_PHY_FLAGS_TX_INVERT             (0x02)
+#define MPI_SAS_IOUNIT1_PHY_FLAGS_RX_INVERT             (0x01)
 
 /* values for SAS IO Unit Page 0 MaxMinLinkRate */
-#define MPI_SAS_IOUNIT1_MAX_RATE_MASK                       (0xF0)
-#define MPI_SAS_IOUNIT1_MAX_RATE_1_5                        (0x80)
-#define MPI_SAS_IOUNIT1_MAX_RATE_3_0                        (0x90)
-#define MPI_SAS_IOUNIT1_MIN_RATE_MASK                       (0x0F)
-#define MPI_SAS_IOUNIT1_MIN_RATE_1_5                        (0x08)
-#define MPI_SAS_IOUNIT1_MIN_RATE_3_0                        (0x09)
+#define MPI_SAS_IOUNIT1_MAX_RATE_MASK                   (0xF0)
+#define MPI_SAS_IOUNIT1_MAX_RATE_1_5                    (0x80)
+#define MPI_SAS_IOUNIT1_MAX_RATE_3_0                    (0x90)
+#define MPI_SAS_IOUNIT1_MIN_RATE_MASK                   (0x0F)
+#define MPI_SAS_IOUNIT1_MIN_RATE_1_5                    (0x08)
+#define MPI_SAS_IOUNIT1_MIN_RATE_3_0                    (0x09)
 
 /* see mpi_sas.h for values for SAS IO Unit Page 1 ControllerPhyDeviceInfo values */
 
 
 typedef struct _CONFIG_PAGE_SAS_IO_UNIT_2
 {
-    fCONFIG_EXTENDED_PAGE_HEADER         Header;                 /* 00h */
+    CONFIG_EXTENDED_PAGE_HEADER         Header;                 /* 00h */
     U32                                 Reserved1;              /* 08h */
     U16                                 MaxPersistentIDs;       /* 0Ch */
     U16                                 NumPersistentIDsUsed;   /* 0Eh */
     U8                                  Status;                 /* 10h */
     U8                                  Flags;                  /* 11h */
-    U16                                 Reserved2;              /* 12h */
-} fCONFIG_PAGE_SAS_IO_UNIT_2, MPI_POINTER PTR_CONFIG_PAGE_SAS_IO_UNIT_2,
+    U16                                 MaxNumPhysicalMappedIDs;/* 12h */              /* 12h */
+} CONFIG_PAGE_SAS_IO_UNIT_2, MPI_POINTER PTR_CONFIG_PAGE_SAS_IO_UNIT_2,
   SasIOUnitPage2_t, MPI_POINTER pSasIOUnitPage2_t;
 
-#define MPI_SASIOUNITPAGE2_PAGEVERSION      (0x00)
+#define MPI_SASIOUNITPAGE2_PAGEVERSION      (0x03)
 
 /* values for SAS IO Unit Page 2 Status field */
 #define MPI_SAS_IOUNIT2_STATUS_DISABLED_PERSISTENT_MAPPINGS (0x02)
@@ -1942,11 +2398,19 @@ typedef struct _CONFIG_PAGE_SAS_IO_UNIT_
 
 /* values for SAS IO Unit Page 2 Flags field */
 #define MPI_SAS_IOUNIT2_FLAGS_DISABLE_PERSISTENT_MAPPINGS   (0x01)
+/* Physical Mapping Modes */
+#define MPI_SAS_IOUNIT2_FLAGS_MASK_PHYS_MAP_MODE            (0x0E)
+#define MPI_SAS_IOUNIT2_FLAGS_SHIFT_PHYS_MAP_MODE           (1)
+#define MPI_SAS_IOUNIT2_FLAGS_NO_PHYS_MAP                   (0x00)
+#define MPI_SAS_IOUNIT2_FLAGS_DIRECT_ATTACH_PHYS_MAP        (0x01)
+#define MPI_SAS_IOUNIT2_FLAGS_ENCLOSURE_SLOT_PHYS_MAP       (0x02)
+
+#define MPI_SAS_IOUNIT2_FLAGS_RESERVE_ID_0_FOR_BOOT         (0x10)
 
 
 typedef struct _CONFIG_PAGE_SAS_IO_UNIT_3
 {
-    fCONFIG_EXTENDED_PAGE_HEADER Header;                         /* 00h */
+    CONFIG_EXTENDED_PAGE_HEADER Header;                         /* 00h */
     U32                         Reserved1;                      /* 08h */
     U32                         MaxInvalidDwordCount;           /* 0Ch */
     U32                         InvalidDwordCountTime;          /* 10h */
@@ -1956,18 +2420,24 @@ typedef struct _CONFIG_PAGE_SAS_IO_UNIT_
     U32                         LossDwordSynchCountTime;        /* 20h */
     U32                         MaxPhyResetProblemCount;        /* 24h */
     U32                         PhyResetProblemTime;            /* 28h */
-} fCONFIG_PAGE_SAS_IO_UNIT_3, MPI_POINTER PTR_CONFIG_PAGE_SAS_IO_UNIT_3,
+} CONFIG_PAGE_SAS_IO_UNIT_3, MPI_POINTER PTR_CONFIG_PAGE_SAS_IO_UNIT_3,
   SasIOUnitPage3_t, MPI_POINTER pSasIOUnitPage3_t;
 
 #define MPI_SASIOUNITPAGE3_PAGEVERSION      (0x00)
 
 
+/****************************************************************************
+*   SAS Expander Config Pages
+****************************************************************************/
+
 typedef struct _CONFIG_PAGE_SAS_EXPANDER_0
 {
-    fCONFIG_EXTENDED_PAGE_HEADER         Header;                 /* 00h */
-    U32                                 Reserved1;              /* 08h */
+    CONFIG_EXTENDED_PAGE_HEADER         Header;                 /* 00h */
+    U8                                  PhysicalPort;           /* 08h */
+    U8                                  Reserved1;              /* 09h */
+    U16                                 Reserved2;              /* 0Ah */
     U64                                 SASAddress;             /* 0Ch */
-    U32                                 Reserved2;              /* 14h */
+    U32                                 DiscoveryStatus;        /* 14h */
     U16                                 DevHandle;              /* 18h */
     U16                                 ParentDevHandle;        /* 1Ah */
     U16                                 ExpanderChangeCount;    /* 1Ch */
@@ -1976,45 +2446,127 @@ typedef struct _CONFIG_PAGE_SAS_EXPANDER
     U8                                  SASLevel;               /* 21h */
     U8                                  Flags;                  /* 22h */
     U8                                  Reserved3;              /* 23h */
-} fCONFIG_PAGE_SAS_EXPANDER_0, MPI_POINTER PTR_CONFIG_PAGE_SAS_EXPANDER_0,
+} CONFIG_PAGE_SAS_EXPANDER_0, MPI_POINTER PTR_CONFIG_PAGE_SAS_EXPANDER_0,
   SasExpanderPage0_t, MPI_POINTER pSasExpanderPage0_t;
 
-#define MPI_SASEXPANDER0_PAGEVERSION        (0x00)
+#define MPI_SASEXPANDER0_PAGEVERSION        (0x02)
+
+/* values for SAS Expander Page 0 DiscoveryStatus field */
+#define MPI_SAS_EXPANDER0_DS_LOOP_DETECTED              (0x00000001)
+#define MPI_SAS_EXPANDER0_DS_UNADDRESSABLE_DEVICE       (0x00000002)
+#define MPI_SAS_EXPANDER0_DS_MULTIPLE_PORTS             (0x00000004)
+#define MPI_SAS_EXPANDER0_DS_EXPANDER_ERR               (0x00000008)
+#define MPI_SAS_EXPANDER0_DS_SMP_TIMEOUT                (0x00000010)
+#define MPI_SAS_EXPANDER0_DS_OUT_ROUTE_ENTRIES          (0x00000020)
+#define MPI_SAS_EXPANDER0_DS_INDEX_NOT_EXIST            (0x00000040)
+#define MPI_SAS_EXPANDER0_DS_SMP_FUNCTION_FAILED        (0x00000080)
+#define MPI_SAS_EXPANDER0_DS_SMP_CRC_ERROR              (0x00000100)
+#define MPI_SAS_EXPANDER0_DS_SUBTRACTIVE_LINK           (0x00000200)
+#define MPI_SAS_EXPANDER0_DS_TABLE_LINK                 (0x00000400)
+#define MPI_SAS_EXPANDER0_DS_UNSUPPORTED_DEVICE         (0x00000800)
 
 /* values for SAS Expander Page 0 Flags field */
 #define MPI_SAS_EXPANDER0_FLAGS_ROUTE_TABLE_CONFIG      (0x02)
 #define MPI_SAS_EXPANDER0_FLAGS_CONFIG_IN_PROGRESS      (0x01)
 
 
+typedef struct _CONFIG_PAGE_SAS_EXPANDER_1
+{
+    CONFIG_EXTENDED_PAGE_HEADER Header;                 /* 00h */
+    U8                          PhysicalPort;           /* 08h */
+    U8                          Reserved1;              /* 09h */
+    U16                         Reserved2;              /* 0Ah */
+    U8                          NumPhys;                /* 0Ch */
+    U8                          Phy;                    /* 0Dh */
+    U16                         NumTableEntriesProgrammed; /* 0Eh */
+    U8                          ProgrammedLinkRate;     /* 10h */
+    U8                          HwLinkRate;             /* 11h */
+    U16                         AttachedDevHandle;      /* 12h */
+    U32                         PhyInfo;                /* 14h */
+    U32                         AttachedDeviceInfo;     /* 18h */
+    U16                         OwnerDevHandle;         /* 1Ch */
+    U8                          ChangeCount;            /* 1Eh */
+    U8                          NegotiatedLinkRate;     /* 1Fh */
+    U8                          PhyIdentifier;          /* 20h */
+    U8                          AttachedPhyIdentifier;  /* 21h */
+    U8                          NumTableEntriesProg;    /* 22h */
+    U8                          DiscoveryInfo;          /* 23h */
+    U32                         Reserved3;              /* 24h */
+} CONFIG_PAGE_SAS_EXPANDER_1, MPI_POINTER PTR_CONFIG_PAGE_SAS_EXPANDER_1,
+  SasExpanderPage1_t, MPI_POINTER pSasExpanderPage1_t;
+
+#define MPI_SASEXPANDER1_PAGEVERSION        (0x01)
+
+/* use MPI_SAS_PHY0_PRATE_ defines for ProgrammedLinkRate */
+
+/* use MPI_SAS_PHY0_HWRATE_ defines for HwLinkRate */
+
+/* use MPI_SAS_PHY0_PHYINFO_ defines for PhyInfo */
+
+/* see mpi_sas.h for values for SAS Expander Page 1 AttachedDeviceInfo values */
+
+/* values for SAS Expander Page 1 DiscoveryInfo field */
+#define MPI_SAS_EXPANDER1_DISCINFO_BAD_PHY DISABLED     (0x04)
+#define MPI_SAS_EXPANDER1_DISCINFO_LINK_STATUS_CHANGE   (0x02)
+#define MPI_SAS_EXPANDER1_DISCINFO_NO_ROUTING_ENTRIES   (0x01)
+
+/* values for SAS Expander Page 1 NegotiatedLinkRate field */
+#define MPI_SAS_EXPANDER1_NEG_RATE_UNKNOWN              (0x00)
+#define MPI_SAS_EXPANDER1_NEG_RATE_PHY_DISABLED         (0x01)
+#define MPI_SAS_EXPANDER1_NEG_RATE_FAILED_NEGOTIATION   (0x02)
+#define MPI_SAS_EXPANDER1_NEG_RATE_SATA_OOB_COMPLETE    (0x03)
+#define MPI_SAS_EXPANDER1_NEG_RATE_1_5                  (0x08)
+#define MPI_SAS_EXPANDER1_NEG_RATE_3_0                  (0x09)
+
+
+/****************************************************************************
+*   SAS Device Config Pages
+****************************************************************************/
+
 typedef struct _CONFIG_PAGE_SAS_DEVICE_0
 {
-    fCONFIG_EXTENDED_PAGE_HEADER         Header;                 /* 00h */
-    U32                                 Reserved1;              /* 08h */
+    CONFIG_EXTENDED_PAGE_HEADER         Header;                 /* 00h */
+    U16                                 Slot;                   /* 08h */
+    U16                                 EnclosureHandle;        /* 0Ah */
     U64                                 SASAddress;             /* 0Ch */
-    U32                                 Reserved2;              /* 14h */
+    U16                                 ParentDevHandle;        /* 14h */
+    U8                                  PhyNum;                 /* 16h */
+    U8                                  AccessStatus;           /* 17h */
     U16                                 DevHandle;              /* 18h */
     U8                                  TargetID;               /* 1Ah */
     U8                                  Bus;                    /* 1Bh */
     U32                                 DeviceInfo;             /* 1Ch */
     U16                                 Flags;                  /* 20h */
     U8                                  PhysicalPort;           /* 22h */
-    U8                                  Reserved3;              /* 23h */
-} fCONFIG_PAGE_SAS_DEVICE_0, MPI_POINTER PTR_CONFIG_PAGE_SAS_DEVICE_0,
+    U8                                  Reserved2;              /* 23h */
+} CONFIG_PAGE_SAS_DEVICE_0, MPI_POINTER PTR_CONFIG_PAGE_SAS_DEVICE_0,
   SasDevicePage0_t, MPI_POINTER pSasDevicePage0_t;
 
-#define MPI_SASDEVICE0_PAGEVERSION          (0x00)
+#define MPI_SASDEVICE0_PAGEVERSION          (0x04)
+
+/* values for SAS Device Page 0 AccessStatus field */
+#define MPI_SAS_DEVICE0_ASTATUS_NO_ERRORS               (0x00)
+#define MPI_SAS_DEVICE0_ASTATUS_SATA_INIT_FAILED        (0x01)
+#define MPI_SAS_DEVICE0_ASTATUS_SATA_CAPABILITY_FAILED  (0x02)
 
 /* values for SAS Device Page 0 Flags field */
-#define MPI_SAS_DEVICE0_FLAGS_MAPPING_PERSISTENT    (0x04)
-#define MPI_SAS_DEVICE0_FLAGS_DEVICE_MAPPED         (0x02)
-#define MPI_SAS_DEVICE0_FLAGS_DEVICE_PRESENT        (0x01)
+#define MPI_SAS_DEVICE0_FLAGS_SATA_SW_PRESERVE          (0x0200)
+#define MPI_SAS_DEVICE0_FLAGS_UNSUPPORTED_DEVICE        (0x0100)
+#define MPI_SAS_DEVICE0_FLAGS_SATA_48BIT_LBA_SUPPORTED  (0x0080)
+#define MPI_SAS_DEVICE0_FLAGS_SATA_SMART_SUPPORTED      (0x0040)
+#define MPI_SAS_DEVICE0_FLAGS_SATA_NCQ_SUPPORTED        (0x0020)
+#define MPI_SAS_DEVICE0_FLAGS_SATA_FUA_SUPPORTED        (0x0010)
+#define MPI_SAS_DEVICE0_FLAGS_PORT_SELECTOR_ATTACH      (0x0008)
+#define MPI_SAS_DEVICE0_FLAGS_MAPPING_PERSISTENT        (0x0004)
+#define MPI_SAS_DEVICE0_FLAGS_DEVICE_MAPPED             (0x0002)
+#define MPI_SAS_DEVICE0_FLAGS_DEVICE_PRESENT            (0x0001)
 
 /* see mpi_sas.h for values for SAS Device Page 0 DeviceInfo values */
 
 
 typedef struct _CONFIG_PAGE_SAS_DEVICE_1
 {
-    fCONFIG_EXTENDED_PAGE_HEADER         Header;                 /* 00h */
+    CONFIG_EXTENDED_PAGE_HEADER         Header;                 /* 00h */
     U32                                 Reserved1;              /* 08h */
     U64                                 SASAddress;             /* 0Ch */
     U32                                 Reserved2;              /* 14h */
@@ -2022,15 +2574,30 @@ typedef struct _CONFIG_PAGE_SAS_DEVICE_1
     U8                                  TargetID;               /* 1Ah */
     U8                                  Bus;                    /* 1Bh */
     U8                                  InitialRegDeviceFIS[20];/* 1Ch */
-} fCONFIG_PAGE_SAS_DEVICE_1, MPI_POINTER PTR_CONFIG_PAGE_SAS_DEVICE_1,
+} CONFIG_PAGE_SAS_DEVICE_1, MPI_POINTER PTR_CONFIG_PAGE_SAS_DEVICE_1,
   SasDevicePage1_t, MPI_POINTER pSasDevicePage1_t;
 
 #define MPI_SASDEVICE1_PAGEVERSION          (0x00)
 
 
+typedef struct _CONFIG_PAGE_SAS_DEVICE_2
+{
+    CONFIG_EXTENDED_PAGE_HEADER         Header;                 /* 00h */
+    U64                                 PhysicalIdentifier;     /* 08h */
+    U32                                 Reserved1;              /* 10h */
+} CONFIG_PAGE_SAS_DEVICE_2, MPI_POINTER PTR_CONFIG_PAGE_SAS_DEVICE_2,
+  SasDevicePage2_t, MPI_POINTER pSasDevicePage2_t;
+
+#define MPI_SASDEVICE2_PAGEVERSION          (0x00)
+
+
+/****************************************************************************
+*   SAS PHY Config Pages
+****************************************************************************/
+
 typedef struct _CONFIG_PAGE_SAS_PHY_0
 {
-    fCONFIG_EXTENDED_PAGE_HEADER         Header;                 /* 00h */
+    CONFIG_EXTENDED_PAGE_HEADER         Header;                 /* 00h */
     U32                                 Reserved1;              /* 08h */
     U64                                 SASAddress;             /* 0Ch */
     U16                                 AttachedDevHandle;      /* 14h */
@@ -2042,7 +2609,7 @@ typedef struct _CONFIG_PAGE_SAS_PHY_0
     U8                                  ChangeCount;            /* 22h */
     U8                                  Reserved3;              /* 23h */
     U32                                 PhyInfo;                /* 24h */
-} fCONFIG_PAGE_SAS_PHY_0, MPI_POINTER PTR_CONFIG_PAGE_SAS_PHY_0,
+} CONFIG_PAGE_SAS_PHY_0, MPI_POINTER PTR_CONFIG_PAGE_SAS_PHY_0,
   SasPhyPage0_t, MPI_POINTER pSasPhyPage0_t;
 
 #define MPI_SASPHY0_PAGEVERSION             (0x00)
@@ -2089,17 +2656,95 @@ typedef struct _CONFIG_PAGE_SAS_PHY_0
 
 typedef struct _CONFIG_PAGE_SAS_PHY_1
 {
-    fCONFIG_EXTENDED_PAGE_HEADER Header;                     /* 00h */
+    CONFIG_EXTENDED_PAGE_HEADER Header;                     /* 00h */
     U32                         Reserved1;                  /* 08h */
     U32                         InvalidDwordCount;          /* 0Ch */
     U32                         RunningDisparityErrorCount; /* 10h */
     U32                         LossDwordSynchCount;        /* 14h */
     U32                         PhyResetProblemCount;       /* 18h */
-} fCONFIG_PAGE_SAS_PHY_1, MPI_POINTER PTR_CONFIG_PAGE_SAS_PHY_1,
+} CONFIG_PAGE_SAS_PHY_1, MPI_POINTER PTR_CONFIG_PAGE_SAS_PHY_1,
   SasPhyPage1_t, MPI_POINTER pSasPhyPage1_t;
 
 #define MPI_SASPHY1_PAGEVERSION             (0x00)
 
 
+/****************************************************************************
+*   SAS Enclosure Config Pages
+****************************************************************************/
+
+typedef struct _CONFIG_PAGE_SAS_ENCLOSURE_0
+{
+    CONFIG_EXTENDED_PAGE_HEADER         Header;                 /* 00h */
+    U32                                 Reserved1;              /* 08h */
+    U64                                 EnclosureLogicalID;     /* 0Ch */
+    U16                                 Flags;                  /* 14h */
+    U16                                 EnclosureHandle;        /* 16h */
+    U16                                 NumSlots;               /* 18h */
+    U16                                 StartSlot;              /* 1Ah */
+    U8                                  StartTargetID;          /* 1Ch */
+    U8                                  StartBus;               /* 1Dh */
+    U8                                  SEPTargetID;            /* 1Eh */
+    U8                                  SEPBus;                 /* 1Fh */
+    U32                                 Reserved2;              /* 20h */
+    U32                                 Reserved3;              /* 24h */
+} CONFIG_PAGE_SAS_ENCLOSURE_0, MPI_POINTER PTR_CONFIG_PAGE_SAS_ENCLOSURE_0,
+  SasEnclosurePage0_t, MPI_POINTER pSasEnclosurePage0_t;
+
+#define MPI_SASENCLOSURE0_PAGEVERSION       (0x00)
+
+/* values for SAS Enclosure Page 0 Flags field */
+#define MPI_SAS_ENCLS0_FLAGS_SEP_BUS_ID_VALID       (0x0020)
+#define MPI_SAS_ENCLS0_FLAGS_START_BUS_ID_VALID     (0x0010)
+
+#define MPI_SAS_ENCLS0_FLAGS_MNG_MASK               (0x000F)
+#define MPI_SAS_ENCLS0_FLAGS_MNG_UNKNOWN            (0x0000)
+#define MPI_SAS_ENCLS0_FLAGS_MNG_IOC_SES            (0x0001)
+#define MPI_SAS_ENCLS0_FLAGS_MNG_IOC_SGPIO          (0x0002)
+#define MPI_SAS_ENCLS0_FLAGS_MNG_EXP_SGPIO          (0x0003)
+#define MPI_SAS_ENCLS0_FLAGS_MNG_SES_ENCLOSURE      (0x0004)
+
+
+/****************************************************************************
+*   Log Config Pages
+****************************************************************************/
+/*
+ * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
+ * one and check NumLogEntries at runtime.
+ */
+#ifndef MPI_LOG_0_NUM_LOG_ENTRIES
+#define MPI_LOG_0_NUM_LOG_ENTRIES        (1)
+#endif
+
+#define MPI_LOG_0_LOG_DATA_LENGTH        (20)
+
+typedef struct _MPI_LOG_0_ENTRY
+{
+    U64         WWID;                               /* 00h */
+    U32         TimeStamp;                          /* 08h */
+    U32         Reserved1;                          /* 0Ch */
+    U16         LogSequence;                        /* 10h */
+    U16         LogEntryQualifier;                  /* 12h */
+    U8          LogData[MPI_LOG_0_LOG_DATA_LENGTH]; /* 14h */
+} MPI_LOG_0_ENTRY, MPI_POINTER PTR_MPI_LOG_0_ENTRY,
+  MpiLog0Entry_t, MPI_POINTER pMpiLog0Entry_t;
+
+/* values for Log Page 0 LogEntry LogEntryQualifier field */
+#define MPI_LOG_0_ENTRY_QUAL_ENTRY_UNUSED           (0x0000)
+#define MPI_LOG_0_ENTRY_QUAL_POWER_ON_RESET         (0x0001)
+
+typedef struct _CONFIG_PAGE_LOG_0
+{
+    CONFIG_EXTENDED_PAGE_HEADER Header;                     /* 00h */
+    U32                         Reserved1;                  /* 08h */
+    U32                         Reserved2;                  /* 0Ch */
+    U16                         NumLogEntries;              /* 10h */
+    U16                         Reserved3;                  /* 12h */
+    MPI_LOG_0_ENTRY             LogEntry[MPI_LOG_0_NUM_LOG_ENTRIES]; /* 14h */
+} CONFIG_PAGE_LOG_0, MPI_POINTER PTR_CONFIG_PAGE_LOG_0,
+  LogPage0_t, MPI_POINTER pLogPage0_t;
+
+#define MPI_LOG_0_PAGEVERSION               (0x00)
+
+
 #endif
 
diff --git a/drivers/message/fusion/lsi/mpi_fc.h b/drivers/message/fusion/lsi/mpi_fc.h
--- a/drivers/message/fusion/lsi/mpi_fc.h
+++ b/drivers/message/fusion/lsi/mpi_fc.h
@@ -1,12 +1,12 @@
 /*
- *  Copyright (c) 2000-2003 LSI Logic Corporation.
+ *  Copyright (c) 2000-2004 LSI Logic Corporation.
  *
  *
  *           Name:  mpi_fc.h
  *          Title:  MPI Fibre Channel messages and structures
  *  Creation Date:  June 12, 2000
  *
- *    mpi_fc.h Version:  01.05.xx
+ *    mpi_fc.h Version:  01.05.01
  *
  *  Version History
  *  ---------------
@@ -36,6 +36,9 @@
  *  09-28-01  01.02.02  Change name of reserved field in
  *                      MSG_LINK_SERVICE_RSP_REPLY.
  *  05-31-02  01.02.03  Adding AliasIndex to FC Direct Access requests.
+ *  01-16-04  01.02.04  Added define for MPI_FC_PRIM_SEND_FLAGS_ML_RESET_LINK.
+ *  05-11-04  01.03.01  Original release for MPI v1.3.
+ *  08-19-04  01.05.01  Original release for MPI v1.5.
  *  --------------------------------------------------------------------------
  */
 
diff --git a/drivers/message/fusion/lsi/mpi_history.txt b/drivers/message/fusion/lsi/mpi_history.txt
--- a/drivers/message/fusion/lsi/mpi_history.txt
+++ b/drivers/message/fusion/lsi/mpi_history.txt
@@ -3,25 +3,28 @@
  MPI Header File Change History
  ==============================
 
- Copyright (c) 2000-2001 LSI Logic Corporation.
+ Copyright (c) 2000-2005 LSI Logic Corporation.
 
  ---------------------------------------
- Header Set Release Version:    01.01.10
- Header Set Release Date:       04-09-01
+ Header Set Release Version:    01.05.09
+ Header Set Release Date:       03-11-05
  ---------------------------------------
 
  Filename               Current version     Prior version
  ----------             ---------------     -------------
- mpi.h                  01.01.07            01.01.06
- mpi_ioc.h              01.01.07            01.01.06
- mpi_cnfg.h             01.01.11            01.01.10
- mpi_init.h             01.01.05            01.01.04
- mpi_targ.h             01.01.04            01.01.04
- mpi_fc.h               01.01.07            01.01.06
- mpi_lan.h              01.01.03            01.01.03
- mpi_raid.h             01.01.02            01.01.02
- mpi_type.h             01.01.02            01.01.02
- mpi_history.txt        01.01.09            01.01.09
+ mpi.h                  01.05.07            01.05.06
+ mpi_ioc.h              01.05.08            01.05.07
+ mpi_cnfg.h             01.05.08            01.05.07
+ mpi_init.h             01.05.04            01.05.03
+ mpi_targ.h             01.05.04            01.05.03
+ mpi_fc.h               01.05.01            01.05.01
+ mpi_lan.h              01.05.01            01.05.01
+ mpi_raid.h             01.05.02            01.05.02
+ mpi_tool.h             01.05.03            01.05.03
+ mpi_inb.h              01.05.01            01.05.01
+ mpi_sas.h              01.05.01            01.05.01
+ mpi_type.h             01.05.01            01.05.01
+ mpi_history.txt        01.05.09            01.05.08
 
 
  *  Date      Version   Description
@@ -53,6 +56,38 @@ mpi.h
  *                      Added function codes for RAID.
  *  04-09-01  01.01.07  Added alternate define for MPI_DOORBELL_ACTIVE,
  *                      MPI_DOORBELL_USED, to better match the spec.
+ *  08-08-01  01.02.01  Original release for v1.2 work.
+ *                      Changed MPI_VERSION_MINOR from 0x01 to 0x02.
+ *                      Added define MPI_FUNCTION_TOOLBOX.
+ *  09-28-01  01.02.02  New function code MPI_SCSI_ENCLOSURE_PROCESSOR.
+ *  11-01-01  01.02.03  Changed name to MPI_FUNCTION_SCSI_ENCLOSURE_PROCESSOR.
+ *  03-14-02  01.02.04  Added MPI_HEADER_VERSION_ defines.
+ *  05-31-02  01.02.05  Bumped MPI_HEADER_VERSION_UNIT.
+ *  07-12-02  01.02.06  Added define for MPI_FUNCTION_MAILBOX.
+ *  09-16-02  01.02.07  Bumped value for MPI_HEADER_VERSION_UNIT.
+ *  11-15-02  01.02.08  Added define MPI_IOCSTATUS_TARGET_INVALID_IO_INDEX and
+ *                      obsoleted define MPI_IOCSTATUS_TARGET_INVALID_IOCINDEX.
+ *  04-01-03  01.02.09  New IOCStatus code: MPI_IOCSTATUS_FC_EXCHANGE_CANCELED
+ *  06-26-03  01.02.10  Bumped MPI_HEADER_VERSION_UNIT value.
+ *  01-16-04  01.02.11  Added define for MPI_IOCLOGINFO_TYPE_SHIFT.
+ *  04-29-04  01.02.12  Added function codes for MPI_FUNCTION_DIAG_BUFFER_POST
+ *                      and MPI_FUNCTION_DIAG_RELEASE.
+ *                      Added MPI_IOCSTATUS_DIAGNOSTIC_RELEASED define.
+ *                      Bumped MPI_HEADER_VERSION_UNIT value.
+ *  05-11-04  01.03.01  Bumped MPI_VERSION_MINOR for MPI v1.3.
+ *                      Added codes for Inband.
+ *  08-19-04  01.05.01  Added defines for Host Buffer Access Control doorbell.
+ *                      Added define for offset of High Priority Request Queue.
+ *                      Added new function codes and new IOCStatus codes.
+ *                      Added a IOCLogInfo type of SAS.
+ *  12-07-04  01.05.02  Bumped MPI_HEADER_VERSION_UNIT.
+ *  12-09-04  01.05.03  Bumped MPI_HEADER_VERSION_UNIT.
+ *  01-15-05  01.05.04  Bumped MPI_HEADER_VERSION_UNIT.
+ *  02-09-05  01.05.05  Bumped MPI_HEADER_VERSION_UNIT.
+ *  02-22-05  01.05.06  Bumped MPI_HEADER_VERSION_UNIT.
+ *  03-11-05  01.05.07  Removed function codes for SCSI IO 32 and
+ *                      TargetAssistExtended requests.
+ *                      Removed EEDP IOCStatus codes.
  *  --------------------------------------------------------------------------
 
 mpi_ioc.h
@@ -81,6 +116,49 @@ mpi_ioc.h
  *  03-27-01  01.01.06  Added defines for ProductId field of MPI_FW_HEADER.
  *                      Added structure offset comments.
  *  04-09-01  01.01.07  Added structure EVENT_DATA_EVENT_CHANGE.
+ *  08-08-01  01.02.01  Original release for v1.2 work.
+ *                      New format for FWVersion and ProductId in
+ *                      MSG_IOC_FACTS_REPLY and MPI_FW_HEADER.
+ *  08-31-01  01.02.02  Addded event MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE and
+ *                      related structure and defines.
+ *                      Added event MPI_EVENT_ON_BUS_TIMER_EXPIRED.
+ *                      Added MPI_IOCINIT_FLAGS_DISCARD_FW_IMAGE.
+ *                      Replaced a reserved field in MSG_IOC_FACTS_REPLY with
+ *                      IOCExceptions and changed DataImageSize to reserved.
+ *                      Added MPI_FW_DOWNLOAD_ITYPE_NVSTORE_DATA and
+ *                      MPI_FW_UPLOAD_ITYPE_NVDATA.
+ *  09-28-01  01.02.03  Modified Event Data for Integrated RAID.
+ *  11-01-01  01.02.04  Added defines for MPI_EXT_IMAGE_HEADER ImageType field.
+ *  03-14-02  01.02.05  Added HeaderVersion field to MSG_IOC_FACTS_REPLY.
+ *  05-31-02  01.02.06  Added define for
+ *                      MPI_IOCFACTS_EXCEPT_RAID_CONFIG_INVALID.
+ *                      Added AliasIndex to EVENT_DATA_LOGOUT structure.
+ *  04-01-03  01.02.07  Added defines for MPI_FW_HEADER_SIGNATURE_.
+ *  06-26-03  01.02.08  Added new values to the product family defines.
+ *  04-29-04  01.02.09  Added IOCCapabilities field to MSG_IOC_FACTS_REPLY and
+ *                      added related defines.
+ *  05-11-04  01.03.01  Original release for MPI v1.3.
+ *  08-19-04  01.05.01  Added four new fields to MSG_IOC_INIT.
+ *                      Added three new fields to MSG_IOC_FACTS_REPLY.
+ *                      Defined four new bits for the IOCCapabilities field of
+ *                      the IOCFacts reply.
+ *                      Added two new PortTypes for the PortFacts reply.
+ *                      Added six new events along with their EventData
+ *                      structures.
+ *                      Added a new MsgFlag to the FwDownload request to
+ *                      indicate last segment.
+ *                      Defined a new image type of boot loader.
+ *                      Added FW family codes for SAS product families.
+ *  10-05-04  01.05.02  Added ReplyFifoHostSignalingAddr field to
+ *                      MSG_IOC_FACTS_REPLY.
+ *  12-07-04  01.05.03  Added more defines for SAS Discovery Error event.
+ *  12-09-04  01.05.04  Added Unsupported device to SAS Device event.
+ *  01-15-05  01.05.05  Added event data for SAS SES Event.
+ *  02-09-05  01.05.06  Added MPI_FW_UPLOAD_ITYPE_FW_BACKUP define.
+ *  02-22-05  01.05.07  Added Host Page Buffer Persistent flag to IOC Facts
+ *                      Reply and IOC Init Request.
+ *  03-11-05  01.05.08  Added family code for 1068E family.
+ *                      Removed IOCFacts Reply EEDP Capability bit.
  *  --------------------------------------------------------------------------
 
 mpi_cnfg.h
@@ -142,6 +220,166 @@ mpi_cnfg.h
  *                      Added IO Unit Page 3.
  *                      Modified defines for Scsi Port Page 2.
  *                      Modified RAID Volume Pages.
+ *  08-08-01  01.02.01  Original release for v1.2 work.
+ *                      Added SepID and SepBus to RVP2 IMPhysicalDisk struct.
+ *                      Added defines for the SEP bits in RVP2 VolumeSettings.
+ *                      Modified the DeviceSettings field in RVP2 to use the
+ *                      proper structure.
+ *                      Added defines for SES, SAF-TE, and cross channel for
+ *                      IOCPage2 CapabilitiesFlags.
+ *                      Removed define for MPI_IOUNITPAGE2_FLAGS_RAID_DISABLE.
+ *                      Removed define for
+ *                      MPI_SCSIPORTPAGE2_PORT_FLAGS_PARITY_ENABLE.
+ *                      Added define for MPI_CONFIG_PAGEATTR_RO_PERSISTENT.
+ *  08-29-01 01.02.02   Fixed value for MPI_MANUFACTPAGE_DEVID_53C1035.
+ *                      Added defines for MPI_FCPORTPAGE1_FLAGS_HARD_ALPA_ONLY
+ *                      and MPI_FCPORTPAGE1_FLAGS_IMMEDIATE_ERROR_REPLY.
+ *                      Removed MPI_SCSIPORTPAGE0_CAP_PACING_TRANSFERS,
+ *                      MPI_SCSIDEVPAGE0_NP_PACING_TRANSFERS, and
+ *                      MPI_SCSIDEVPAGE1_RP_PACING_TRANSFERS, and
+ *                      MPI_SCSIDEVPAGE1_CONF_PPR_ALLOWED.
+ *                      Added defines for MPI_SCSIDEVPAGE1_CONF_WDTR_DISALLOWED
+ *                      and MPI_SCSIDEVPAGE1_CONF_SDTR_DISALLOWED.
+ *                      Added OnBusTimerValue to CONFIG_PAGE_SCSI_PORT_1.
+ *                      Added rejected bits to SCSI Device Page 0 Information.
+ *                      Increased size of ALPA array in FC Port Page 2 by one
+ *                      and removed a one byte reserved field.
+ *  09-28-01 01.02.03   Swapped NegWireSpeedLow and NegWireSpeedLow in
+ *                      CONFIG_PAGE_LAN_1 to match preferred 64-bit ordering.
+ *                      Added structures for Manufacturing Page 4, IO Unit
+ *                      Page 3, IOC Page 3, IOC Page 4, RAID Volume Page 0, and
+ *                      RAID PhysDisk Page 0.
+ *  10-04-01 01.02.04   Added define for MPI_CONFIG_PAGETYPE_RAID_PHYSDISK.
+ *                      Modified some of the new defines to make them 32
+ *                      character unique.
+ *                      Modified how variable length pages (arrays) are defined.
+ *                      Added generic defines for hot spare pools and RAID
+ *                      volume types.
+ *  11-01-01 01.02.05   Added define for MPI_IOUNITPAGE1_DISABLE_IR.
+ *  03-14-02 01.02.06   Added PCISlotNum field to CONFIG_PAGE_IOC_1 along with
+ *                      related define, and bumped the page version define.
+ *  05-31-02 01.02.07   Added a Flags field to CONFIG_PAGE_IOC_2_RAID_VOL in a
+ *                      reserved byte and added a define.
+ *                      Added define for
+ *                      MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE.
+ *                      Added new config page: CONFIG_PAGE_IOC_5.
+ *                      Added MaxAliases, MaxHardAliases, and NumCurrentAliases
+ *                      fields to CONFIG_PAGE_FC_PORT_0.
+ *                      Added AltConnector and NumRequestedAliases fields to
+ *                      CONFIG_PAGE_FC_PORT_1.
+ *                      Added new config page: CONFIG_PAGE_FC_PORT_10.
+ *  07-12-02 01.02.08   Added more MPI_MANUFACTPAGE_DEVID_ defines.
+ *                      Added additional MPI_SCSIDEVPAGE0_NP_ defines.
+ *                      Added more MPI_SCSIDEVPAGE1_RP_ defines.
+ *                      Added define for
+ *                      MPI_SCSIDEVPAGE1_CONF_EXTENDED_PARAMS_ENABLE.
+ *                      Added new config page: CONFIG_PAGE_SCSI_DEVICE_3.
+ *                      Modified MPI_FCPORTPAGE5_FLAGS_ defines.
+ *  09-16-02 01.02.09   Added MPI_SCSIDEVPAGE1_CONF_FORCE_PPR_MSG define.
+ *  11-15-02 01.02.10   Added ConnectedID defines for CONFIG_PAGE_SCSI_PORT_0.
+ *                      Added more Flags defines for CONFIG_PAGE_FC_PORT_1.
+ *                      Added more Flags defines for CONFIG_PAGE_FC_DEVICE_0.
+ *  04-01-03 01.02.11   Added RR_TOV field and additional Flags defines for
+ *                      CONFIG_PAGE_FC_PORT_1.
+ *                      Added define MPI_FCPORTPAGE5_FLAGS_DISABLE to disable
+ *                      an alias.
+ *                      Added more device id defines.
+ *  06-26-03 01.02.12   Added MPI_IOUNITPAGE1_IR_USE_STATIC_VOLUME_ID define.
+ *                      Added TargetConfig and IDConfig fields to
+ *                      CONFIG_PAGE_SCSI_PORT_1.
+ *                      Added more PortFlags defines for CONFIG_PAGE_SCSI_PORT_2
+ *                      to control DV.
+ *                      Added more Flags defines for CONFIG_PAGE_FC_PORT_1.
+ *                      In CONFIG_PAGE_FC_DEVICE_0, replaced Reserved1 field
+ *                      with ADISCHardALPA.
+ *                      Added MPI_FC_DEVICE_PAGE0_PROT_FCP_RETRY define.
+ *  01-16-04  01.02.13  Added InitiatorDeviceTimeout and InitiatorIoPendTimeout
+ *                      fields and related defines to CONFIG_PAGE_FC_PORT_1.
+ *                      Added define for
+ *                      MPI_FCPORTPAGE1_FLAGS_SOFT_ALPA_FALLBACK.
+ *                      Added new fields to the substructures of
+ *                      CONFIG_PAGE_FC_PORT_10.
+ *  04-29-04 01.02.14   Added define for IDP bit for CONFIG_PAGE_SCSI_PORT_0,
+ *                      CONFIG_PAGE_SCSI_DEVICE_0, and
+ *                      CONFIG_PAGE_SCSI_DEVICE_1. Also bumped Page Version for
+ *                      these pages.
+ *  05-11-04 01.03.01   Added structure for CONFIG_PAGE_INBAND_0.
+ *  08-19-04 01.05.01   Modified MSG_CONFIG request to support extended config
+ *                      pages.
+ *                      Added a new structure for extended config page header.
+ *                      Added new extended config pages types and structures for
+ *                      SAS IO Unit, SAS Expander, SAS Device, and SAS PHY.
+ *                      Replaced a reserved byte in CONFIG_PAGE_MANUFACTURING_4
+ *                      to add a Flags field.
+ *                      Two new Manufacturing config pages (5 and 6).
+ *                      Two new bits defined for IO Unit Page 1 Flags field.
+ *                      Modified CONFIG_PAGE_IO_UNIT_2 to add three new fields
+ *                      to specify the BIOS boot device.
+ *                      Four new Flags bits defined for IO Unit Page 2.
+ *                      Added IO Unit Page 4.
+ *                      Added EEDP Flags settings to IOC Page 1.
+ *                      Added new BIOS Page 1 config page.
+ *  10-05-04 01.05.02   Added define for
+ *                      MPI_IOCPAGE1_INITIATOR_CONTEXT_REPLY_DISABLE.
+ *                      Added new Flags field to CONFIG_PAGE_MANUFACTURING_5 and
+ *                      associated defines.
+ *                      Added more defines for SAS IO Unit Page 0
+ *                      DiscoveryStatus field.
+ *                      Added define for MPI_SAS_IOUNIT0_DS_SUBTRACTIVE_LINK
+ *                      and MPI_SAS_IOUNIT0_DS_TABLE_LINK.
+ *                      Added defines for Physical Mapping Modes to SAS IO Unit
+ *                      Page 2.
+ *                      Added define for
+ *                      MPI_SAS_DEVICE0_FLAGS_PORT_SELECTOR_ATTACH.
+ *  10-27-04 01.05.03   Added defines for new SAS PHY page addressing mode.
+ *                      Added defines for MaxTargetSpinUp to BIOS Page 1.
+ *                      Added 5 new ControlFlags defines for SAS IO Unit
+ *                      Page 1.
+ *                      Added MaxNumPhysicalMappedIDs field to SAS IO Unit
+ *                      Page 2.
+ *                      Added AccessStatus field to SAS Device Page 0 and added
+ *                      new Flags bits for supported SATA features.
+ *  12-07-04  01.05.04  Added config page structures for BIOS Page 2, RAID
+ *                      Volume Page 1, and RAID Physical Disk Page 1.
+ *                      Replaced IO Unit Page 1 BootTargetID,BootBus, and
+ *                      BootAdapterNum with reserved field.
+ *                      Added DataScrubRate and ResyncRate to RAID Volume
+ *                      Page 0.
+ *                      Added MPI_SAS_IOUNIT2_FLAGS_RESERVE_ID_0_FOR_BOOT
+ *                      define.
+ *  12-09-04  01.05.05  Added Target Mode Large CDB Enable to FC Port Page 1
+ *                      Flags field.
+ *                      Added Auto Port Config flag define for SAS IOUNIT
+ *                      Page 1 ControlFlags.
+ *                      Added Disabled bad Phy define to Expander Page 1
+ *                      Discovery Info field.
+ *                      Added SAS/SATA device support to SAS IOUnit Page 1
+ *                      ControlFlags.
+ *                      Added Unsupported device to SAS Dev Page 0 Flags field
+ *                      Added disable use SATA Hash Address for SAS IOUNIT
+ *                      page 1 in ControlFields.
+ *  01-15-05  01.05.06  Added defaults for data scrub rate and resync rate to
+ *                      Manufacturing Page 4.
+ *                      Added new defines for BIOS Page 1 IOCSettings field.
+ *                      Added ExtDiskIdentifier field to RAID Physical Disk
+ *                      Page 0.
+ *                      Added new defines for SAS IO Unit Page 1 ControlFlags
+ *                      and to SAS Device Page 0 Flags to control SATA devices.
+ *                      Added defines and structures for the new Log Page 0, a
+ *                      new type of configuration page.
+ *  02-09-05  01.05.07  Added InactiveStatus field to RAID Volume Page 0.
+ *                      Added WWID field to RAID Volume Page 1.
+ *                      Added PhysicalPort field to SAS Expander pages 0 and 1.
+ *  03-11-05  01.05.08  Removed the EEDP flags from IOC Page 1.
+ *                      Added Enclosure/Slot boot device format to BIOS Page 2.
+ *                      New status value for RAID Volume Page 0 VolumeStatus
+ *                      (VolumeState subfield).
+ *                      New value for RAID Physical Page 0 InactiveStatus.
+ *                      Added Inactive Volume Member flag RAID Physical Disk
+ *                      Page 0 PhysDiskStatus field.
+ *                      New physical mapping mode in SAS IO Unit Page 2.
+ *                      Added CONFIG_PAGE_SAS_ENCLOSURE_0.
+ *                      Added Slot and Enclosure fields to SAS Device Page 0.
  *  --------------------------------------------------------------------------
 
 mpi_init.h
@@ -154,6 +392,32 @@ mpi_init.h
  *  02-20-01  01.01.03  Started using MPI_POINTER.
  *  03-27-01  01.01.04  Added structure offset comments.
  *  04-10-01  01.01.05  Added new MsgFlag for MSG_SCSI_TASK_MGMT.
+ *  08-08-01  01.02.01  Original release for v1.2 work.
+ *  08-29-01  01.02.02  Added MPI_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET.
+ *                      Added MPI_SCSI_STATE_QUEUE_TAG_REJECTED for
+ *                      MSG_SCSI_IO_REPLY.
+ *  09-28-01  01.02.03  Added structures and defines for SCSI Enclosure
+ *                      Processor messages.
+ *  10-04-01  01.02.04  Added defines for SEP request Action field.
+ *  05-31-02  01.02.05  Added MPI_SCSIIO_MSGFLGS_CMD_DETERMINES_DATA_DIR define
+ *                      for SCSI IO requests.
+ *  11-15-02  01.02.06  Added special extended SCSI Status defines for FCP.
+ *  06-26-03  01.02.07  Added MPI_SCSI_STATUS_FCPEXT_UNASSIGNED define.
+ *  05-11-04  01.03.01  Original release for MPI v1.3.
+ *  08-19-04  01.05.01  Added MsgFlags defines for EEDP to SCSI IO request.
+ *                      Added new word to MSG_SCSI_IO_REPLY to add TaskTag field
+ *                      and a reserved U16.
+ *                      Added new MSG_SCSI_IO32_REQUEST structure.
+ *                      Added a TaskType of Clear Task Set to SCSI
+ *                      Task Management request.
+ *  12-07-04  01.05.02  Added support for Task Management Query Task.
+ *  01-15-05  01.05.03  Modified SCSI Enclosure Processor Request to support
+ *                      WWID addressing.
+ *  03-11-05  01.05.04  Removed EEDP flags from SCSI IO Request.
+ *                      Removed SCSI IO 32 Request.
+ *                      Modified SCSI Enclosure Processor Request and Reply to
+ *                      support Enclosure/Slot addressing rather than WWID
+ *                      addressing.
  *  --------------------------------------------------------------------------
 
 mpi_targ.h
@@ -170,6 +434,33 @@ mpi_targ.h
  *                      Added structures for MPI_TARGET_SCSI_SPI_CMD_BUFFER and
  *                      MPI_TARGET_FCP_CMD_BUFFER.
  *  03-27-01  01.01.04  Added structure offset comments.
+ *  08-08-01  01.02.01  Original release for v1.2 work.
+ *  09-28-01  01.02.02  Added structure for MPI_TARGET_SCSI_SPI_STATUS_IU.
+ *                      Added PriorityReason field to some replies and
+ *                      defined more PriorityReason codes.
+ *                      Added some defines for to support previous version
+ *                      of MPI.
+ *  10-04-01  01.02.03  Added PriorityReason to MSG_TARGET_ERROR_REPLY.
+ *  11-01-01  01.02.04  Added define for TARGET_STATUS_SEND_FLAGS_HIGH_PRIORITY.
+ *  03-14-02  01.02.05  Modified MPI_TARGET_FCP_RSP_BUFFER to get the proper
+ *                      byte ordering.
+ *  05-31-02  01.02.06  Modified TARGET_MODE_REPLY_ALIAS_MASK to only include
+ *                      one bit.
+ *                      Added AliasIndex field to MPI_TARGET_FCP_CMD_BUFFER.
+ *  09-16-02  01.02.07  Added flags for confirmed completion.
+ *                      Added PRIORITY_REASON_TARGET_BUSY.
+ *  11-15-02  01.02.08  Added AliasID field to MPI_TARGET_SCSI_SPI_CMD_BUFFER.
+ *  04-01-03  01.02.09  Added OptionalOxid field to MPI_TARGET_FCP_CMD_BUFFER.
+ *  05-11-04  01.03.01  Original release for MPI v1.3.
+ *  08-19-04  01.05.01  Added new request message structures for
+ *                      MSG_TARGET_CMD_BUF_POST_BASE_REQUEST,
+ *                      MSG_TARGET_CMD_BUF_POST_LIST_REQUEST, and
+ *                      MSG_TARGET_ASSIST_EXT_REQUEST.
+ *                      Added new structures for SAS SSP Command buffer, SSP
+ *                      Task buffer, and SSP Status IU.
+ *  10-05-04  01.05.02  MSG_TARGET_CMD_BUFFER_POST_BASE_LIST_REPLY added.
+ *  02-22-05  01.05.03  Changed a comment.
+ *  03-11-05  01.05.04  Removed TargetAssistExtended Request.
  *  --------------------------------------------------------------------------
 
 mpi_fc.h
@@ -192,6 +483,13 @@ mpi_fc.h
  *                      Added MPI_FC_PRIM_SEND_FLAGS_RESET_LINK define.
  *                      Added structure offset comments.
  *  04-09-01  01.01.07  Added RspLength field to MSG_LINK_SERVICE_RSP_REQUEST.
+ *  08-08-01  01.02.01  Original release for v1.2 work.
+ *  09-28-01  01.02.02  Change name of reserved field in
+ *                      MSG_LINK_SERVICE_RSP_REPLY.
+ *  05-31-02  01.02.03  Adding AliasIndex to FC Direct Access requests.
+ *  01-16-04  01.02.04  Added define for MPI_FC_PRIM_SEND_FLAGS_ML_RESET_LINK.
+ *  05-11-04  01.03.01  Original release for MPI v1.3.
+ *  08-19-04  01.05.01  Original release for MPI v1.5.
  *  --------------------------------------------------------------------------
 
 mpi_lan.h
@@ -209,11 +507,56 @@ mpi_lan.h
  *  11-02-00  01.01.01  Original release for post 1.0 work
  *  02-20-01  01.01.02  Started using MPI_POINTER.
  *  03-27-01  01.01.03  Added structure offset comments.
+ *  08-08-01  01.02.01  Original release for v1.2 work.
+ *  05-11-04  01.03.01  Original release for MPI v1.3.
+ *  08-19-04  01.05.01  Original release for MPI v1.5.
  *  --------------------------------------------------------------------------
 
 mpi_raid.h
  *  02-27-01  01.01.01  Original release for this file.
  *  03-27-01  01.01.02  Added structure offset comments.
+ *  08-08-01  01.02.01  Original release for v1.2 work.
+ *  08-29-01  01.02.02  Added DIAG_DATA_UPLOAD_HEADER and related defines.
+ *  09-28-01  01.02.02  Major rework for MPI v1.2 Integrated RAID changes.
+ *  10-04-01  01.02.03  Added ActionData defines for
+ *                      MPI_RAID_ACTION_DELETE_VOLUME action.
+ *  11-01-01  01.02.04  Added define for MPI_RAID_ACTION_ADATA_DO_NOT_SYNC.
+ *  03-14-02  01.02.05  Added define for MPI_RAID_ACTION_ADATA_LOW_LEVEL_INIT.
+ *  05-07-02  01.02.06  Added define for MPI_RAID_ACTION_ACTIVATE_VOLUME,
+ *                      MPI_RAID_ACTION_INACTIVATE_VOLUME, and
+ *                      MPI_RAID_ACTION_ADATA_INACTIVATE_ALL.
+ *  07-12-02  01.02.07  Added structures for Mailbox request and reply.
+ *  11-15-02  01.02.08  Added missing MsgContext field to MSG_MAILBOX_REQUEST.
+ *  04-01-03  01.02.09  New action data option flag for
+ *                      MPI_RAID_ACTION_DELETE_VOLUME.
+ *  05-11-04  01.03.01  Original release for MPI v1.3.
+ *  08-19-04  01.05.01  Original release for MPI v1.5.
+ *  01-15-05  01.05.02  Added defines for the two new RAID Actions for
+ *                      _SET_RESYNC_RATE and _SET_DATA_SCRUB_RATE.
+ *  --------------------------------------------------------------------------
+
+mpi_tool.h
+ *  08-08-01  01.02.01  Original release.
+ *  08-29-01  01.02.02  Added DIAG_DATA_UPLOAD_HEADER and related defines.
+ *  01-16-04  01.02.03  Added defines and structures for new tools
+ *.                     MPI_TOOLBOX_ISTWI_READ_WRITE_TOOL and
+ *                      MPI_TOOLBOX_FC_MANAGEMENT_TOOL.
+ *  04-29-04  01.02.04  Added message structures for Diagnostic Buffer Post and
+ *                      Diagnostic Release requests and replies.
+ *  05-11-04  01.03.01  Original release for MPI v1.3.
+ *  08-19-04  01.05.01  Original release for MPI v1.5.
+ *  10-06-04  01.05.02  Added define for MPI_DIAG_BUF_TYPE_COUNT.
+ *  02-09-05  01.05.03  Added frame size option to FC management tool.
+ *                      Added Beacon tool to the Toolbox.
+ *  --------------------------------------------------------------------------
+
+mpi_inb.h
+ *  05-11-04  01.03.01  Original release.
+ *  08-19-04  01.05.01  Original release for MPI v1.5.
+ *  --------------------------------------------------------------------------
+
+mpi_sas.h
+ *  08-19-04  01.05.01  Original release.
  *  --------------------------------------------------------------------------
 
 mpi_type.h
@@ -221,21 +564,83 @@ mpi_type.h
  *  06-06-00  01.00.01  Update version number for 1.0 release.
  *  11-02-00  01.01.01  Original release for post 1.0 work
  *  02-20-01  01.01.02  Added define and ifdef for MPI_POINTER.
+ *  08-08-01  01.02.01  Original release for v1.2 work.
+ *  05-11-04  01.03.01  Original release for MPI v1.3.
+ *  08-19-04  01.05.01  Original release for MPI v1.5.
  *  --------------------------------------------------------------------------
 
 mpi_history.txt         Parts list history
 
-Filename    01.01.10
+Filename    01.05.09
 ----------  --------
-mpi.h       01.01.07
-mpi_ioc.h   01.01.07
-mpi_cnfg.h  01.01.11
-mpi_init.h  01.01.05
-mpi_targ.h  01.01.04
-mpi_fc.h    01.01.07
-mpi_lan.h   01.01.03
-mpi_raid.h  01.01.02
-mpi_type.h  01.01.02
+mpi.h       01.05.07
+mpi_ioc.h   01.05.08
+mpi_cnfg.h  01.05.08
+mpi_init.h  01.05.04
+mpi_targ.h  01.05.04
+mpi_fc.h    01.05.01
+mpi_lan.h   01.05.01
+mpi_raid.h  01.05.02
+mpi_tool.h  01.05.03
+mpi_inb.h   01.05.01
+mpi_sas.h   01.05.01
+mpi_type.h  01.05.01
+
+Filename    01.05.08   01.05.07   01.05.06   01.05.05   01.05.04   01.05.03
+----------  --------   --------   --------   --------   --------   --------
+mpi.h       01.05.06   01.05.05   01.05.04   01.05.03   01.05.02   01.05.01
+mpi_ioc.h   01.05.07   01.05.06   01.05.05   01.05.04   01.05.03   01.05.02
+mpi_cnfg.h  01.05.07   01.05.07   01.05.06   01.05.05   01.05.04   01.05.03
+mpi_init.h  01.05.03   01.05.03   01.05.03   01.05.02   01.05.02   01.05.01
+mpi_targ.h  01.05.03   01.05.02   01.05.02   01.05.02   01.05.02   01.05.02
+mpi_fc.h    01.05.01   01.05.01   01.05.01   01.05.01   01.05.01   01.05.01
+mpi_lan.h   01.05.01   01.05.01   01.05.01   01.05.01   01.05.01   01.05.01
+mpi_raid.h  01.05.02   01.05.02   01.05.02   01.05.01   01.05.01   01.05.01
+mpi_tool.h  01.05.03   01.05.03   01.05.02   01.05.02   01.05.02   01.05.02
+mpi_inb.h   01.05.01   01.05.01   01.05.01   01.05.01   01.05.01   01.05.01
+mpi_sas.h   01.05.01   01.05.01   01.05.01   01.05.01   01.05.01   01.05.01
+mpi_type.h  01.05.01   01.05.01   01.05.01   01.05.01   01.05.01   01.05.01
+
+Filename    01.05.02   01.05.01   01.03.01   01.02.14   01.02.13   01.02.12
+----------  --------   --------   --------   --------   --------   --------
+mpi.h       01.05.01   01.05.01   01.03.01   01.02.12   01.02.11   01.02.10
+mpi_ioc.h   01.05.02   01.05.01   01.03.01   01.02.09   01.02.08   01.02.08
+mpi_cnfg.h  01.05.02   01.05.01   01.03.01   01.02.14   01.02.13   01.02.12
+mpi_init.h  01.05.01   01.05.01   01.03.01   01.02.07   01.02.07   01.02.07
+mpi_targ.h  01.05.02   01.05.01   01.03.01   01.02.09   01.02.09   01.02.09
+mpi_fc.h    01.05.01   01.05.01   01.03.01   01.02.04   01.02.04   01.02.03
+mpi_lan.h   01.05.01   01.05.01   01.03.01   01.02.01   01.02.01   01.02.01
+mpi_raid.h  01.05.01   01.05.01   01.03.01   01.02.09   01.02.09   01.02.09
+mpi_tool.h  01.05.02   01.05.01   01.03.01   01.02.01   01.02.01   01.02.01
+mpi_inb.h   01.05.01   01.05.01   01.03.01
+mpi_sas.h   01.05.01   01.05.01
+mpi_type.h  01.05.01   01.05.01   01.03.01   01.02.04   01.02.03   01.02.02
+
+Filename    01.02.11   01.02.10   01.02.09   01.02.08   01.02.07   01.02.06
+----------  --------   --------   --------   --------   --------   --------
+mpi.h       01.02.09   01.02.08   01.02.07   01.02.06   01.02.05   01.02.04
+mpi_ioc.h   01.02.07   01.02.06   01.02.06   01.02.06   01.02.06   01.02.05
+mpi_cnfg.h  01.02.11   01.02.10   01.02.09   01.02.08   01.02.07   01.02.06
+mpi_init.h  01.02.06   01.02.06   01.02.05   01.02.05   01.02.05   01.02.04
+mpi_targ.h  01.02.09   01.02.08   01.02.07   01.02.06   01.02.06   01.02.05
+mpi_fc.h    01.02.03   01.02.03   01.02.03   01.02.03   01.02.03   01.02.02
+mpi_lan.h   01.02.01   01.02.01   01.02.01   01.02.01   01.02.01   01.02.01
+mpi_raid.h  01.02.09   01.02.08   01.02.07   01.02.07   01.02.06   01.02.05
+mpi_tool.h  01.02.01   01.02.01   01.02.01   01.02.01   01.02.01   01.02.01
+mpi_type.h  01.02.02   01.02.02   01.02.02   01.02.02   01.02.02   01.02.02
+
+Filename    01.02.05   01.02.04   01.02.03   01.02.02   01.02.01   01.01.10
+----------  --------   --------   --------   --------   --------   --------
+mpi.h       01.02.03   01.02.02   01.02.02   01.02.01   01.02.01   01.01.07
+mpi_ioc.h   01.02.04   01.02.03   01.02.03   01.02.02   01.02.01   01.01.07
+mpi_cnfg.h  01.02.05   01.02.04   01.02.03   01.02.02   01.02.01   01.01.11
+mpi_init.h  01.02.04   01.02.04   01.02.03   01.02.02   01.02.01   01.01.05
+mpi_targ.h  01.02.04   01.02.03   01.02.02   01.02.01   01.02.01   01.01.04
+mpi_fc.h    01.02.02   01.02.02   01.02.02   01.02.01   01.02.01   01.01.07
+mpi_lan.h   01.02.01   01.02.01   01.02.01   01.02.01   01.02.01   01.01.03
+mpi_raid.h  01.02.04   01.02.03   01.02.02   01.02.01   01.02.01   01.01.02
+mpi_tool.h  01.02.02   01.02.02   01.02.02   01.02.02   01.02.01
+mpi_type.h  01.02.02   01.02.02   01.02.02   01.02.02   01.02.01   01.01.02
 
 Filename    01.01.09   01.01.08   01.01.07   01.01.06   01.01.05   01.01.04
 ----------  --------   --------   --------   --------   --------   --------
diff --git a/drivers/message/fusion/lsi/mpi_inb.h b/drivers/message/fusion/lsi/mpi_inb.h
--- a/drivers/message/fusion/lsi/mpi_inb.h
+++ b/drivers/message/fusion/lsi/mpi_inb.h
@@ -1,19 +1,20 @@
 /*
- *  Copyright (c) 2003 LSI Logic Corporation.
+ *  Copyright (c) 2003-2004 LSI Logic Corporation.
  *
  *
  *           Name:  mpi_inb.h
  *          Title:  MPI Inband structures and definitions
  *  Creation Date:  September 30, 2003
  *
- *    mpi_inb.h Version:  01.03.xx
+ *    mpi_inb.h Version:  01.05.01
  *
  *  Version History
  *  ---------------
  *
  *  Date      Version   Description
  *  --------  --------  ------------------------------------------------------
- *  ??-??-??  01.03.01  Original release.
+ *  05-11-04  01.03.01  Original release.
+ *  08-19-04  01.05.01  Original release for MPI v1.5.
  *  --------------------------------------------------------------------------
  */
 
diff --git a/drivers/message/fusion/lsi/mpi_init.h b/drivers/message/fusion/lsi/mpi_init.h
--- a/drivers/message/fusion/lsi/mpi_init.h
+++ b/drivers/message/fusion/lsi/mpi_init.h
@@ -1,12 +1,12 @@
 /*
- *  Copyright (c) 2000-2003 LSI Logic Corporation.
+ *  Copyright (c) 2000-2005 LSI Logic Corporation.
  *
  *
  *           Name:  mpi_init.h
  *          Title:  MPI initiator mode messages and structures
  *  Creation Date:  June 8, 2000
  *
- *    mpi_init.h Version:  01.05.xx
+ *    mpi_init.h Version:  01.05.04
  *
  *  Version History
  *  ---------------
@@ -33,6 +33,21 @@
  *                      for SCSI IO requests.
  *  11-15-02  01.02.06  Added special extended SCSI Status defines for FCP.
  *  06-26-03  01.02.07  Added MPI_SCSI_STATUS_FCPEXT_UNASSIGNED define.
+ *  05-11-04  01.03.01  Original release for MPI v1.3.
+ *  08-19-04  01.05.01  Added MsgFlags defines for EEDP to SCSI IO request.
+ *                      Added new word to MSG_SCSI_IO_REPLY to add TaskTag field
+ *                      and a reserved U16.
+ *                      Added new MSG_SCSI_IO32_REQUEST structure.
+ *                      Added a TaskType of Clear Task Set to SCSI
+ *                      Task Management request.
+ *  12-07-04  01.05.02  Added support for Task Management Query Task.
+ *  01-15-05  01.05.03  Modified SCSI Enclosure Processor Request to support
+ *                      WWID addressing.
+ *  03-11-05  01.05.04  Removed EEDP flags from SCSI IO Request.
+ *                      Removed SCSI IO 32 Request.
+ *                      Modified SCSI Enclosure Processor Request and Reply to
+ *                      support Enclosure/Slot addressing rather than WWID
+ *                      addressing.
  *  --------------------------------------------------------------------------
  */
 
@@ -76,20 +91,12 @@ typedef struct _MSG_SCSI_IO_REQUEST
 #define MPI_SCSIIO_MSGFLGS_SENSE_WIDTH              (0x01)
 #define MPI_SCSIIO_MSGFLGS_SENSE_WIDTH_32           (0x00)
 #define MPI_SCSIIO_MSGFLGS_SENSE_WIDTH_64           (0x01)
+
 #define MPI_SCSIIO_MSGFLGS_SENSE_LOCATION           (0x02)
 #define MPI_SCSIIO_MSGFLGS_SENSE_LOC_HOST           (0x00)
 #define MPI_SCSIIO_MSGFLGS_SENSE_LOC_IOC            (0x02)
-#define MPI_SCSIIO_MSGFLGS_CMD_DETERMINES_DATA_DIR  (0x04)
-#define MPI_SCSIIO_MSGFLGS_EEDP_TYPE_MASK           (0xE0)
-#define MPI_SCSIIO_MSGFLGS_EEDP_NONE                (0x00)
-#define MPI_SCSIIO_MSGFLGS_EEDP_RDPROTECT_T10       (0x20)
-#define MPI_SCSIIO_MSGFLGS_EEDP_VRPROTECT_T10       (0x40)
-#define MPI_SCSIIO_MSGFLGS_EEDP_WRPROTECT_T10       (0x60)
-#define MPI_SCSIIO_MSGFLGS_EEDP_520_READ_MODE1      (0x20)
-#define MPI_SCSIIO_MSGFLGS_EEDP_520_WRITE_MODE1     (0x40)
-#define MPI_SCSIIO_MSGFLGS_EEDP_8_9_READ_MODE1      (0x60)
-#define MPI_SCSIIO_MSGFLGS_EEDP_8_9_WRITE_MODE1     (0x80)
 
+#define MPI_SCSIIO_MSGFLGS_CMD_DETERMINES_DATA_DIR  (0x04)
 
 /* SCSI IO LUN fields */
 
@@ -148,6 +155,8 @@ typedef struct _MSG_SCSI_IO_REPLY
     U32                     TransferCount;      /* 14h */
     U32                     SenseCount;         /* 18h */
     U32                     ResponseInfo;       /* 1Ch */
+    U16                     TaskTag;            /* 20h */
+    U16                     Reserved1;          /* 22h */
 } MSG_SCSI_IO_REPLY, MPI_POINTER PTR_MSG_SCSI_IO_REPLY,
   SCSIIOReply_t, MPI_POINTER pSCSIIOReply_t;
 
@@ -190,32 +199,7 @@ typedef struct _MSG_SCSI_IO_REPLY
 #define MPI_SCSI_RSP_INFO_TASK_MGMT_FAILED      (0x05000000)
 #define MPI_SCSI_RSP_INFO_SPI_LQ_INVALID_TYPE   (0x06000000)
 
-
-/****************************************************************************/
-/*  SCSI IO 32 Request message structure                                    */
-/****************************************************************************/
-
-typedef struct _MSG_SCSI_IO32_REQUEST
-{
-    U8                      TargetID;           /* 00h */
-    U8                      Bus;                /* 01h */
-    U8                      ChainOffset;        /* 02h */
-    U8                      Function;           /* 03h */
-    U8                      CDBLength;          /* 04h */
-    U8                      SenseBufferLength;  /* 05h */
-    U8                      Reserved;           /* 06h */
-    U8                      MsgFlags;           /* 07h */
-    U32                     MsgContext;         /* 08h */
-    U8                      LUN[8];             /* 0Ch */
-    U32                     Control;            /* 14h */
-    U8                      CDB[32];            /* 18h */
-    U32                     DataLength;         /* 38h */
-    U32                     SenseBufferLowAddr; /* 3Ch */
-    SGE_IO_UNION            SGL;                /* 40h */
-} MSG_SCSI_IO32_REQUEST, MPI_POINTER PTR_MSG_SCSI_IO32_REQUEST,
-  SCSIIO32Request_t, MPI_POINTER pSCSIIO32Request_t;
-
-/* SCSI IO 32 uses the same defines as above for SCSI IO */
+#define MPI_SCSI_TASKTAG_UNKNOWN                (0xFFFF)
 
 
 /****************************************************************************/
@@ -247,6 +231,7 @@ typedef struct _MSG_SCSI_TASK_MGMT
 #define MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS             (0x04)
 #define MPI_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET    (0x05)
 #define MPI_SCSITASKMGMT_TASKTYPE_CLEAR_TASK_SET        (0x06)
+#define MPI_SCSITASKMGMT_TASKTYPE_QUERY_TASK            (0x07)
 
 /* MsgFlags bits */
 #define MPI_SCSITASKMGMT_MSGFLAGS_TARGET_RESET_OPTION   (0x00)
@@ -260,7 +245,7 @@ typedef struct _MSG_SCSI_TASK_MGMT_REPLY
     U8                      Bus;                /* 01h */
     U8                      MsgLength;          /* 02h */
     U8                      Function;           /* 03h */
-    U8                      Reserved;           /* 04h */
+    U8                      ResponseCode;       /* 04h */
     U8                      TaskType;           /* 05h */
     U8                      Reserved1;          /* 06h */
     U8                      MsgFlags;           /* 07h */
@@ -272,6 +257,15 @@ typedef struct _MSG_SCSI_TASK_MGMT_REPLY
 } MSG_SCSI_TASK_MGMT_REPLY, MPI_POINTER PTR_MSG_SCSI_TASK_MGMT_REPLY,
   SCSITaskMgmtReply_t, MPI_POINTER pSCSITaskMgmtReply_t;
 
+/* ResponseCode values */
+#define MPI_SCSITASKMGMT_RSP_TM_COMPLETE                (0x00)
+#define MPI_SCSITASKMGMT_RSP_INVALID_FRAME              (0x02)
+#define MPI_SCSITASKMGMT_RSP_TM_NOT_SUPPORTED           (0x04)
+#define MPI_SCSITASKMGMT_RSP_TM_FAILED                  (0x05)
+#define MPI_SCSITASKMGMT_RSP_TM_SUCCEEDED               (0x08)
+#define MPI_SCSITASKMGMT_RSP_TM_INVALID_LUN             (0x09)
+#define MPI_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC           (0x80)
+
 
 /****************************************************************************/
 /*  SCSI Enclosure Processor messages                                       */
@@ -284,11 +278,16 @@ typedef struct _MSG_SEP_REQUEST
     U8                      ChainOffset;        /* 02h */
     U8                      Function;           /* 03h */
     U8                      Action;             /* 04h */
-    U8                      Reserved1;          /* 05h */
-    U8                      Reserved2;          /* 06h */
+    U8                      Flags;              /* 05h */
+    U8                      Reserved1;          /* 06h */
     U8                      MsgFlags;           /* 07h */
     U32                     MsgContext;         /* 08h */
     U32                     SlotStatus;         /* 0Ch */
+    U32                     Reserved2;          /* 10h */
+    U32                     Reserved3;          /* 14h */
+    U32                     Reserved4;          /* 18h */
+    U16                     Slot;               /* 1Ch */
+    U16                     EnclosureHandle;    /* 1Eh */
 } MSG_SEP_REQUEST, MPI_POINTER PTR_MSG_SEP_REQUEST,
   SEPRequest_t, MPI_POINTER pSEPRequest_t;
 
@@ -296,6 +295,10 @@ typedef struct _MSG_SEP_REQUEST
 #define MPI_SEP_REQ_ACTION_WRITE_STATUS                 (0x00)
 #define MPI_SEP_REQ_ACTION_READ_STATUS                  (0x01)
 
+/* Flags defines */
+#define MPI_SEP_REQ_FLAGS_ENCLOSURE_SLOT_ADDRESS        (0x01)
+#define MPI_SEP_REQ_FLAGS_BUS_TARGETID_ADDRESS          (0x00)
+
 /* SlotStatus bits for MSG_SEP_REQUEST */
 #define MPI_SEP_REQ_SLOTSTATUS_NO_ERROR                 (0x00000001)
 #define MPI_SEP_REQ_SLOTSTATUS_DEV_FAULTY               (0x00000002)
@@ -332,6 +335,9 @@ typedef struct _MSG_SEP_REPLY
     U16                     IOCStatus;          /* 0Eh */
     U32                     IOCLogInfo;         /* 10h */
     U32                     SlotStatus;         /* 14h */
+    U32                     Reserved4;          /* 18h */
+    U16                     Slot;               /* 1Ch */
+    U16                     EnclosureHandle;    /* 1Eh */
 } MSG_SEP_REPLY, MPI_POINTER PTR_MSG_SEP_REPLY,
   SEPReply_t, MPI_POINTER pSEPReply_t;
 
diff --git a/drivers/message/fusion/lsi/mpi_ioc.h b/drivers/message/fusion/lsi/mpi_ioc.h
--- a/drivers/message/fusion/lsi/mpi_ioc.h
+++ b/drivers/message/fusion/lsi/mpi_ioc.h
@@ -1,12 +1,12 @@
 /*
- *  Copyright (c) 2000-2003 LSI Logic Corporation.
+ *  Copyright (c) 2000-2005 LSI Logic Corporation.
  *
  *
  *           Name:  mpi_ioc.h
  *          Title:  MPI IOC, Port, Event, FW Download, and FW Upload messages
  *  Creation Date:  August 11, 2000
  *
- *    mpi_ioc.h Version:  01.05.xx
+ *    mpi_ioc.h Version:  01.05.08
  *
  *  Version History
  *  ---------------
@@ -57,6 +57,30 @@
  *                      Added AliasIndex to EVENT_DATA_LOGOUT structure.
  *  04-01-03  01.02.07  Added defines for MPI_FW_HEADER_SIGNATURE_.
  *  06-26-03  01.02.08  Added new values to the product family defines.
+ *  04-29-04  01.02.09  Added IOCCapabilities field to MSG_IOC_FACTS_REPLY and
+ *                      added related defines.
+ *  05-11-04  01.03.01  Original release for MPI v1.3.
+ *  08-19-04  01.05.01  Added four new fields to MSG_IOC_INIT.
+ *                      Added three new fields to MSG_IOC_FACTS_REPLY.
+ *                      Defined four new bits for the IOCCapabilities field of
+ *                      the IOCFacts reply.
+ *                      Added two new PortTypes for the PortFacts reply.
+ *                      Added six new events along with their EventData
+ *                      structures.
+ *                      Added a new MsgFlag to the FwDownload request to
+ *                      indicate last segment.
+ *                      Defined a new image type of boot loader.
+ *                      Added FW family codes for SAS product families.
+ *  10-05-04  01.05.02  Added ReplyFifoHostSignalingAddr field to
+ *                      MSG_IOC_FACTS_REPLY.
+ *  12-07-04  01.05.03  Added more defines for SAS Discovery Error event.
+ *  12-09-04  01.05.04  Added Unsupported device to SAS Device event.
+ *  01-15-05  01.05.05  Added event data for SAS SES Event.
+ *  02-09-05  01.05.06  Added MPI_FW_UPLOAD_ITYPE_FW_BACKUP define.
+ *  02-22-05  01.05.07  Added Host Page Buffer Persistent flag to IOC Facts
+ *                      Reply and IOC Init Request.
+ *  03-11-05  01.05.08  Added family code for 1068E family.
+ *                      Removed IOCFacts Reply EEDP Capability bit.
  *  --------------------------------------------------------------------------
  */
 
@@ -90,20 +114,37 @@ typedef struct _MSG_IOC_INIT
     U32                     HostMfaHighAddr;            /* 10h */
     U32                     SenseBufferHighAddr;        /* 14h */
     U32                     ReplyFifoHostSignalingAddr; /* 18h */
+    SGE_SIMPLE_UNION        HostPageBufferSGE;          /* 1Ch */
+    U16                     MsgVersion;                 /* 28h */
+    U16                     HeaderVersion;              /* 2Ah */
 } MSG_IOC_INIT, MPI_POINTER PTR_MSG_IOC_INIT,
   IOCInit_t, MPI_POINTER pIOCInit_t;
 
 /* WhoInit values */
-#define MPI_WHOINIT_NO_ONE                          (0x00)
-#define MPI_WHOINIT_SYSTEM_BIOS                     (0x01)
-#define MPI_WHOINIT_ROM_BIOS                        (0x02)
-#define MPI_WHOINIT_PCI_PEER                        (0x03)
-#define MPI_WHOINIT_HOST_DRIVER                     (0x04)
-#define MPI_WHOINIT_MANUFACTURER                    (0x05)
+#define MPI_WHOINIT_NO_ONE                              (0x00)
+#define MPI_WHOINIT_SYSTEM_BIOS                         (0x01)
+#define MPI_WHOINIT_ROM_BIOS                            (0x02)
+#define MPI_WHOINIT_PCI_PEER                            (0x03)
+#define MPI_WHOINIT_HOST_DRIVER                         (0x04)
+#define MPI_WHOINIT_MANUFACTURER                        (0x05)
 
 /* Flags values */
-#define MPI_IOCINIT_FLAGS_DISCARD_FW_IMAGE          (0x01)
-#define MPI_IOCINIT_FLAGS_REPLY_FIFO_HOST_SIGNAL    (0x02)
+#define MPI_IOCINIT_FLAGS_HOST_PAGE_BUFFER_PERSISTENT   (0x04)
+#define MPI_IOCINIT_FLAGS_REPLY_FIFO_HOST_SIGNAL        (0x02)
+#define MPI_IOCINIT_FLAGS_DISCARD_FW_IMAGE              (0x01)
+
+/* MsgVersion */
+#define MPI_IOCINIT_MSGVERSION_MAJOR_MASK               (0xFF00)
+#define MPI_IOCINIT_MSGVERSION_MAJOR_SHIFT              (8)
+#define MPI_IOCINIT_MSGVERSION_MINOR_MASK               (0x00FF)
+#define MPI_IOCINIT_MSGVERSION_MINOR_SHIFT              (0)
+
+/* HeaderVersion */
+#define MPI_IOCINIT_HEADERVERSION_UNIT_MASK             (0xFF00)
+#define MPI_IOCINIT_HEADERVERSION_UNIT_SHIFT            (8)
+#define MPI_IOCINIT_HEADERVERSION_DEV_MASK              (0x00FF)
+#define MPI_IOCINIT_HEADERVERSION_DEV_SHIFT             (0)
+
 
 typedef struct _MSG_IOC_INIT_REPLY
 {
@@ -187,32 +228,39 @@ typedef struct _MSG_IOC_FACTS_REPLY
     MPI_FW_VERSION          FWVersion;                  /* 38h */
     U16                     HighPriorityQueueDepth;     /* 3Ch */
     U16                     Reserved2;                  /* 3Eh */
+    SGE_SIMPLE_UNION        HostPageBufferSGE;          /* 40h */
+    U32                     ReplyFifoHostSignalingAddr; /* 4Ch */
 } MSG_IOC_FACTS_REPLY, MPI_POINTER PTR_MSG_IOC_FACTS_REPLY,
   IOCFactsReply_t, MPI_POINTER pIOCFactsReply_t;
 
-#define MPI_IOCFACTS_MSGVERSION_MAJOR_MASK          (0xFF00)
-#define MPI_IOCFACTS_MSGVERSION_MINOR_MASK          (0x00FF)
-
-#define MPI_IOCFACTS_HEADERVERSION_UNIT_MASK        (0xFF00)
-#define MPI_IOCFACTS_HEADERVERSION_DEV_MASK         (0x00FF)
-
-#define MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL    (0x0001)
-#define MPI_IOCFACTS_EXCEPT_RAID_CONFIG_INVALID     (0x0002)
-#define MPI_IOCFACTS_EXCEPT_FW_CHECKSUM_FAIL        (0x0004)
-#define MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL   (0x0008)
-
-#define MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT         (0x01)
-
-#define MPI_IOCFACTS_EVENTSTATE_DISABLED            (0x00)
-#define MPI_IOCFACTS_EVENTSTATE_ENABLED             (0x01)
-
-#define MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q          (0x00000001)
-#define MPI_IOCFACTS_CAPABILITY_REPLY_HOST_SIGNAL   (0x00000002)
-#define MPI_IOCFACTS_CAPABILITY_QUEUE_FULL_HANDLING (0x00000004)
-#define MPI_IOCFACTS_CAPABILITY_DIAG_TRACE_BUFFER   (0x00000008)
-#define MPI_IOCFACTS_CAPABILITY_SNAPSHOT_BUFFER     (0x00000010)
-#define MPI_IOCFACTS_CAPABILITY_EXTENDED_BUFFER     (0x00000020)
-#define MPI_IOCFACTS_CAPABILITY_EEDP                (0x00000040)
+#define MPI_IOCFACTS_MSGVERSION_MAJOR_MASK              (0xFF00)
+#define MPI_IOCFACTS_MSGVERSION_MAJOR_SHIFT             (8)
+#define MPI_IOCFACTS_MSGVERSION_MINOR_MASK              (0x00FF)
+#define MPI_IOCFACTS_MSGVERSION_MINOR_SHIFT             (0)
+
+#define MPI_IOCFACTS_HDRVERSION_UNIT_MASK               (0xFF00)
+#define MPI_IOCFACTS_HDRVERSION_UNIT_SHIFT              (8)
+#define MPI_IOCFACTS_HDRVERSION_DEV_MASK                (0x00FF)
+#define MPI_IOCFACTS_HDRVERSION_DEV_SHIFT               (0)
+
+#define MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL        (0x0001)
+#define MPI_IOCFACTS_EXCEPT_RAID_CONFIG_INVALID         (0x0002)
+#define MPI_IOCFACTS_EXCEPT_FW_CHECKSUM_FAIL            (0x0004)
+#define MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL       (0x0008)
+
+#define MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT             (0x01)
+#define MPI_IOCFACTS_FLAGS_REPLY_FIFO_HOST_SIGNAL       (0x02)
+#define MPI_IOCFACTS_FLAGS_HOST_PAGE_BUFFER_PERSISTENT  (0x04)
+
+#define MPI_IOCFACTS_EVENTSTATE_DISABLED                (0x00)
+#define MPI_IOCFACTS_EVENTSTATE_ENABLED                 (0x01)
+
+#define MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q              (0x00000001)
+#define MPI_IOCFACTS_CAPABILITY_REPLY_HOST_SIGNAL       (0x00000002)
+#define MPI_IOCFACTS_CAPABILITY_QUEUE_FULL_HANDLING     (0x00000004)
+#define MPI_IOCFACTS_CAPABILITY_DIAG_TRACE_BUFFER       (0x00000008)
+#define MPI_IOCFACTS_CAPABILITY_SNAPSHOT_BUFFER         (0x00000010)
+#define MPI_IOCFACTS_CAPABILITY_EXTENDED_BUFFER         (0x00000020)
 
 
 
@@ -408,6 +456,8 @@ typedef struct _MSG_EVENT_ACK_REPLY
 #define MPI_EVENT_SAS_DEVICE_STATUS_CHANGE  (0x0000000F)
 #define MPI_EVENT_SAS_SES                   (0x00000010)
 #define MPI_EVENT_PERSISTENT_TABLE_FULL     (0x00000011)
+#define MPI_EVENT_SAS_PHY_LINK_STATUS       (0x00000012)
+#define MPI_EVENT_SAS_DISCOVERY_ERROR       (0x00000013)
 
 /* AckRequired field values */
 
@@ -467,6 +517,10 @@ typedef struct _EVENT_DATA_SAS_DEVICE_ST
     U8                      ASCQ;                       /* 05h */
     U16                     DevHandle;                  /* 06h */
     U32                     DeviceInfo;                 /* 08h */
+    U16                     ParentDevHandle;            /* 0Ch */
+    U8                      PhyNum;                     /* 0Eh */
+    U8                      Reserved1;                  /* 0Fh */
+    U64                     SASAddress;                 /* 10h */
 } EVENT_DATA_SAS_DEVICE_STATUS_CHANGE,
   MPI_POINTER PTR_EVENT_DATA_SAS_DEVICE_STATUS_CHANGE,
   MpiEventDataSasDeviceStatusChange_t,
@@ -477,6 +531,8 @@ typedef struct _EVENT_DATA_SAS_DEVICE_ST
 #define MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING        (0x04)
 #define MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA            (0x05)
 #define MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED      (0x06)
+#define MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED           (0x07)
+
 
 /* SCSI Event data for Queue Full event */
 
@@ -488,6 +544,35 @@ typedef struct _EVENT_DATA_QUEUE_FULL
 } EVENT_DATA_QUEUE_FULL, MPI_POINTER PTR_EVENT_DATA_QUEUE_FULL,
   EventDataQueueFull_t, MPI_POINTER pEventDataQueueFull_t;
 
+/* MPI Integrated RAID Event data */
+
+typedef struct _EVENT_DATA_RAID
+{
+    U8                      VolumeID;                   /* 00h */
+    U8                      VolumeBus;                  /* 01h */
+    U8                      ReasonCode;                 /* 02h */
+    U8                      PhysDiskNum;                /* 03h */
+    U8                      ASC;                        /* 04h */
+    U8                      ASCQ;                       /* 05h */
+    U16                     Reserved;                   /* 06h */
+    U32                     SettingsStatus;             /* 08h */
+} EVENT_DATA_RAID, MPI_POINTER PTR_EVENT_DATA_RAID,
+  MpiEventDataRaid_t, MPI_POINTER pMpiEventDataRaid_t;
+
+/* MPI Integrated RAID Event data ReasonCode values */
+#define MPI_EVENT_RAID_RC_VOLUME_CREATED                (0x00)
+#define MPI_EVENT_RAID_RC_VOLUME_DELETED                (0x01)
+#define MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED       (0x02)
+#define MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED         (0x03)
+#define MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED       (0x04)
+#define MPI_EVENT_RAID_RC_PHYSDISK_CREATED              (0x05)
+#define MPI_EVENT_RAID_RC_PHYSDISK_DELETED              (0x06)
+#define MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED     (0x07)
+#define MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED       (0x08)
+#define MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED             (0x09)
+#define MPI_EVENT_RAID_RC_SMART_DATA                    (0x0A)
+#define MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED        (0x0B)
+
 /* MPI Link Status Change Event data */
 
 typedef struct _EVENT_DATA_LINK_STATUS
@@ -535,35 +620,63 @@ typedef struct _EVENT_DATA_LOGOUT
 
 #define MPI_EVENT_LOGOUT_ALL_ALIASES        (0xFF)
 
+/* SAS SES Event data */
 
-/* MPI Integrated RAID Event data */
+typedef struct _EVENT_DATA_SAS_SES
+{
+    U8                      PhyNum;                     /* 00h */
+    U8                      Port;                       /* 01h */
+    U8                      PortWidth;                  /* 02h */
+    U8                      Reserved1;                  /* 04h */
+} EVENT_DATA_SAS_SES, MPI_POINTER PTR_EVENT_DATA_SAS_SES,
+  MpiEventDataSasSes_t, MPI_POINTER pMpiEventDataSasSes_t;
 
-typedef struct _EVENT_DATA_RAID
+/* SAS Phy Link Status Event data */
+
+typedef struct _EVENT_DATA_SAS_PHY_LINK_STATUS
 {
-    U8                      VolumeID;                   /* 00h */
-    U8                      VolumeBus;                  /* 01h */
-    U8                      ReasonCode;                 /* 02h */
-    U8                      PhysDiskNum;                /* 03h */
-    U8                      ASC;                        /* 04h */
-    U8                      ASCQ;                       /* 05h */
-    U16                     Reserved;                   /* 06h */
-    U32                     SettingsStatus;             /* 08h */
-} EVENT_DATA_RAID, MPI_POINTER PTR_EVENT_DATA_RAID,
-  MpiEventDataRaid_t, MPI_POINTER pMpiEventDataRaid_t;
+    U8                      PhyNum;                     /* 00h */
+    U8                      LinkRates;                  /* 01h */
+    U16                     DevHandle;                  /* 02h */
+    U64                     SASAddress;                 /* 04h */
+} EVENT_DATA_SAS_PHY_LINK_STATUS, MPI_POINTER PTR_EVENT_DATA_SAS_PHY_LINK_STATUS,
+  MpiEventDataSasPhyLinkStatus_t, MPI_POINTER pMpiEventDataSasPhyLinkStatus_t;
+
+/* defines for the LinkRates field of the SAS PHY Link Status event */
+#define MPI_EVENT_SAS_PLS_LR_CURRENT_MASK                   (0xF0)
+#define MPI_EVENT_SAS_PLS_LR_CURRENT_SHIFT                  (4)
+#define MPI_EVENT_SAS_PLS_LR_PREVIOUS_MASK                  (0x0F)
+#define MPI_EVENT_SAS_PLS_LR_PREVIOUS_SHIFT                 (0)
+#define MPI_EVENT_SAS_PLS_LR_RATE_UNKNOWN                   (0x00)
+#define MPI_EVENT_SAS_PLS_LR_RATE_PHY_DISABLED              (0x01)
+#define MPI_EVENT_SAS_PLS_LR_RATE_FAILED_SPEED_NEGOTIATION  (0x02)
+#define MPI_EVENT_SAS_PLS_LR_RATE_SATA_OOB_COMPLETE         (0x03)
+#define MPI_EVENT_SAS_PLS_LR_RATE_1_5                       (0x08)
+#define MPI_EVENT_SAS_PLS_LR_RATE_3_0                       (0x09)
+
+/* SAS Discovery Errror Event data */
+
+typedef struct _EVENT_DATA_DISCOVERY_ERROR
+{
+    U32                     DiscoveryStatus;            /* 00h */
+    U8                      Port;                       /* 04h */
+    U8                      Reserved1;                  /* 05h */
+    U16                     Reserved2;                  /* 06h */
+} EVENT_DATA_DISCOVERY_ERROR, MPI_POINTER PTR_EVENT_DATA_DISCOVERY_ERROR,
+  EventDataDiscoveryError_t, MPI_POINTER pEventDataDiscoveryError_t;
 
-/* MPI Integrated RAID Event data ReasonCode values */
-#define MPI_EVENT_RAID_RC_VOLUME_CREATED                (0x00)
-#define MPI_EVENT_RAID_RC_VOLUME_DELETED                (0x01)
-#define MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED       (0x02)
-#define MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED         (0x03)
-#define MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED       (0x04)
-#define MPI_EVENT_RAID_RC_PHYSDISK_CREATED              (0x05)
-#define MPI_EVENT_RAID_RC_PHYSDISK_DELETED              (0x06)
-#define MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED     (0x07)
-#define MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED       (0x08)
-#define MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED             (0x09)
-#define MPI_EVENT_RAID_RC_SMART_DATA                    (0x0A)
-#define MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED        (0x0B)
+#define MPI_EVENT_DSCVRY_ERR_DS_LOOP_DETECTED               (0x00000001)
+#define MPI_EVENT_DSCVRY_ERR_DS_UNADDRESSABLE_DEVICE        (0x00000002)
+#define MPI_EVENT_DSCVRY_ERR_DS_MULTIPLE_PORTS              (0x00000004)
+#define MPI_EVENT_DSCVRY_ERR_DS_EXPANDER_ERR                (0x00000008)
+#define MPI_EVENT_DSCVRY_ERR_DS_SMP_TIMEOUT                 (0x00000010)
+#define MPI_EVENT_DSCVRY_ERR_DS_OUT_ROUTE_ENTRIES           (0x00000020)
+#define MPI_EVENT_DSCVRY_ERR_DS_INDEX_NOT_EXIST             (0x00000040)
+#define MPI_EVENT_DSCVRY_ERR_DS_SMP_FUNCTION_FAILED         (0x00000080)
+#define MPI_EVENT_DSCVRY_ERR_DS_SMP_CRC_ERROR               (0x00000100)
+#define MPI_EVENT_DSCVRY_ERR_DS_MULTPL_SUBTRACTIVE          (0x00000200)
+#define MPI_EVENT_DSCVRY_ERR_DS_TABLE_TO_TABLE              (0x00000400)
+#define MPI_EVENT_DSCVRY_ERR_DS_MULTPL_PATHS                (0x00000800)
 
 
 /*****************************************************************************
@@ -589,11 +702,13 @@ typedef struct _MSG_FW_DOWNLOAD
 } MSG_FW_DOWNLOAD, MPI_POINTER PTR_MSG_FW_DOWNLOAD,
   FWDownload_t, MPI_POINTER pFWDownload_t;
 
-#define MPI_FW_DOWNLOAD_ITYPE_RESERVED      (0x00)
-#define MPI_FW_DOWNLOAD_ITYPE_FW            (0x01)
-#define MPI_FW_DOWNLOAD_ITYPE_BIOS          (0x02)
-#define MPI_FW_DOWNLOAD_ITYPE_NVDATA        (0x03)
-#define MPI_FW_DOWNLOAD_ITYPE_BOOTLOADER    (0x04)
+#define MPI_FW_DOWNLOAD_MSGFLGS_LAST_SEGMENT    (0x01)
+
+#define MPI_FW_DOWNLOAD_ITYPE_RESERVED          (0x00)
+#define MPI_FW_DOWNLOAD_ITYPE_FW                (0x01)
+#define MPI_FW_DOWNLOAD_ITYPE_BIOS              (0x02)
+#define MPI_FW_DOWNLOAD_ITYPE_NVDATA            (0x03)
+#define MPI_FW_DOWNLOAD_ITYPE_BOOTLOADER        (0x04)
 
 
 typedef struct _FWDownloadTCSGE
@@ -647,6 +762,7 @@ typedef struct _MSG_FW_UPLOAD
 #define MPI_FW_UPLOAD_ITYPE_BIOS_FLASH      (0x02)
 #define MPI_FW_UPLOAD_ITYPE_NVDATA          (0x03)
 #define MPI_FW_UPLOAD_ITYPE_BOOTLOADER      (0x04)
+#define MPI_FW_UPLOAD_ITYPE_FW_BACKUP       (0x05)
 
 typedef struct _FWUploadTCSGE
 {
@@ -723,6 +839,7 @@ typedef struct _MPI_FW_HEADER
 #define MPI_FW_HEADER_PID_PROD_IM_SCSI                  (0x0400)
 #define MPI_FW_HEADER_PID_PROD_IS_SCSI                  (0x0500)
 #define MPI_FW_HEADER_PID_PROD_CTX_SCSI                 (0x0600)
+#define MPI_FW_HEADER_PID_PROD_IR_SCSI                  (0x0700)
 
 #define MPI_FW_HEADER_PID_FAMILY_MASK           (0x00FF)
 /* SCSI */
@@ -740,13 +857,16 @@ typedef struct _MPI_FW_HEADER
 #define MPI_FW_HEADER_PID_FAMILY_1020TA0_SCSI   (0x000C)
 /* Fibre Channel */
 #define MPI_FW_HEADER_PID_FAMILY_909_FC         (0x0000)
-#define MPI_FW_HEADER_PID_FAMILY_919_FC         (0x0001)
-#define MPI_FW_HEADER_PID_FAMILY_919X_FC        (0x0002)
-#define MPI_FW_HEADER_PID_FAMILY_919XL_FC       (0x0003)
-#define MPI_FW_HEADER_PID_FAMILY_949_FC         (0x0004)
+#define MPI_FW_HEADER_PID_FAMILY_919_FC         (0x0001) /* 919 and 929     */
+#define MPI_FW_HEADER_PID_FAMILY_919X_FC        (0x0002) /* 919X and 929X   */
+#define MPI_FW_HEADER_PID_FAMILY_919XL_FC       (0x0003) /* 919XL and 929XL */
+#define MPI_FW_HEADER_PID_FAMILY_939X_FC        (0x0004) /* 939X and 949X   */
 #define MPI_FW_HEADER_PID_FAMILY_959_FC         (0x0005)
 /* SAS */
 #define MPI_FW_HEADER_PID_FAMILY_1064_SAS       (0x0001)
+#define MPI_FW_HEADER_PID_FAMILY_1068_SAS       (0x0002)
+#define MPI_FW_HEADER_PID_FAMILY_1078_SAS       (0x0003)
+#define MPI_FW_HEADER_PID_FAMILY_106xE_SAS      (0x0004) /* 1068E, 1066E, and 1064E */
 
 typedef struct _MPI_EXT_IMAGE_HEADER
 {
diff --git a/drivers/message/fusion/lsi/mpi_lan.h b/drivers/message/fusion/lsi/mpi_lan.h
--- a/drivers/message/fusion/lsi/mpi_lan.h
+++ b/drivers/message/fusion/lsi/mpi_lan.h
@@ -1,12 +1,12 @@
 /*
- *  Copyright (c) 2000-2003 LSI Logic Corporation.
+ *  Copyright (c) 2000-2004 LSI Logic Corporation.
  *
  *
  *           Name:  mpi_lan.h
  *          Title:  MPI LAN messages and structures
  *  Creation Date:  June 30, 2000
  *
- *    mpi_lan.h Version:  01.05.xx
+ *    mpi_lan.h Version:  01.05.01
  *
  *  Version History
  *  ---------------
@@ -28,6 +28,8 @@
  *  02-20-01  01.01.02  Started using MPI_POINTER.
  *  03-27-01  01.01.03  Added structure offset comments.
  *  08-08-01  01.02.01  Original release for v1.2 work.
+ *  05-11-04  01.03.01  Original release for MPI v1.3.
+ *  08-19-04  01.05.01  Original release for MPI v1.5.
  *  --------------------------------------------------------------------------
  */
 
diff --git a/drivers/message/fusion/lsi/mpi_raid.h b/drivers/message/fusion/lsi/mpi_raid.h
--- a/drivers/message/fusion/lsi/mpi_raid.h
+++ b/drivers/message/fusion/lsi/mpi_raid.h
@@ -1,12 +1,12 @@
 /*
- *  Copyright (c) 2001-2003 LSI Logic Corporation.
+ *  Copyright (c) 2001-2005 LSI Logic Corporation.
  *
  *
  *           Name:  mpi_raid.h
  *          Title:  MPI RAID message and structures
  *  Creation Date:  February 27, 2001
  *
- *    mpi_raid.h Version:  01.05.xx
+ *    mpi_raid.h Version:  01.05.02
  *
  *  Version History
  *  ---------------
@@ -28,6 +28,10 @@
  *  11-15-02  01.02.08  Added missing MsgContext field to MSG_MAILBOX_REQUEST.
  *  04-01-03  01.02.09  New action data option flag for
  *                      MPI_RAID_ACTION_DELETE_VOLUME.
+ *  05-11-04  01.03.01  Original release for MPI v1.3.
+ *  08-19-04  01.05.01  Original release for MPI v1.5.
+ *  01-15-05  01.05.02  Added defines for the two new RAID Actions for
+ *                      _SET_RESYNC_RATE and _SET_DATA_SCRUB_RATE.
  *  --------------------------------------------------------------------------
  */
 
@@ -84,6 +88,8 @@ typedef struct _MSG_RAID_ACTION
 #define MPI_RAID_ACTION_REPLACE_PHYSDISK            (0x10)
 #define MPI_RAID_ACTION_ACTIVATE_VOLUME             (0x11)
 #define MPI_RAID_ACTION_INACTIVATE_VOLUME           (0x12)
+#define MPI_RAID_ACTION_SET_RESYNC_RATE             (0x13)
+#define MPI_RAID_ACTION_SET_DATA_SCRUB_RATE         (0x14)
 
 /* ActionDataWord defines for use with MPI_RAID_ACTION_CREATE_VOLUME action */
 #define MPI_RAID_ACTION_ADATA_DO_NOT_SYNC           (0x00000001)
@@ -99,6 +105,13 @@ typedef struct _MSG_RAID_ACTION
 /* ActionDataWord defines for use with MPI_RAID_ACTION_ACTIVATE_VOLUME action */
 #define MPI_RAID_ACTION_ADATA_INACTIVATE_ALL        (0x00000001)
 
+/* ActionDataWord defines for use with MPI_RAID_ACTION_SET_RESYNC_RATE action */
+#define MPI_RAID_ACTION_ADATA_RESYNC_RATE_MASK      (0x000000FF)
+
+/* ActionDataWord defines for use with MPI_RAID_ACTION_SET_DATA_SCRUB_RATE action */
+#define MPI_RAID_ACTION_ADATA_DATA_SCRUB_RATE_MASK  (0x000000FF)
+
+
 
 /* RAID Action reply message */
 
diff --git a/drivers/message/fusion/lsi/mpi_sas.h b/drivers/message/fusion/lsi/mpi_sas.h
--- a/drivers/message/fusion/lsi/mpi_sas.h
+++ b/drivers/message/fusion/lsi/mpi_sas.h
@@ -1,25 +1,76 @@
 /*
- *  Copyright (c) 2003 LSI Logic Corporation.
+ *  Copyright (c) 2004 LSI Logic Corporation.
  *
  *
  *           Name:  mpi_sas.h
  *          Title:  MPI Serial Attached SCSI structures and definitions
- *  Creation Date:  April 23, 2003
+ *  Creation Date:  August 19, 2004
  *
- *    mpi_sas.h Version:  01.05.xx
+ *    mpi_sas.h Version:  01.05.01
  *
  *  Version History
  *  ---------------
  *
  *  Date      Version   Description
  *  --------  --------  ------------------------------------------------------
- *  xx-yy-zz  01.05.01  Original release.
+ *  08-19-04  01.05.01  Original release.
  *  --------------------------------------------------------------------------
  */
 
 #ifndef MPI_SAS_H
 #define MPI_SAS_H
 
+
+/*
+ * Values for SASStatus.
+ */
+#define MPI_SASSTATUS_SUCCESS                           (0x00)
+#define MPI_SASSTATUS_UNKNOWN_ERROR                     (0x01)
+#define MPI_SASSTATUS_INVALID_FRAME                     (0x02)
+#define MPI_SASSTATUS_UTC_BAD_DEST                      (0x03)
+#define MPI_SASSTATUS_UTC_BREAK_RECEIVED                (0x04)
+#define MPI_SASSTATUS_UTC_CONNECT_RATE_NOT_SUPPORTED    (0x05)
+#define MPI_SASSTATUS_UTC_PORT_LAYER_REQUEST            (0x06)
+#define MPI_SASSTATUS_UTC_PROTOCOL_NOT_SUPPORTED        (0x07)
+#define MPI_SASSTATUS_UTC_STP_RESOURCES_BUSY            (0x08)
+#define MPI_SASSTATUS_UTC_WRONG_DESTINATION             (0x09)
+#define MPI_SASSTATUS_SHORT_INFORMATION_UNIT            (0x0A)
+#define MPI_SASSTATUS_LONG_INFORMATION_UNIT             (0x0B)
+#define MPI_SASSTATUS_XFER_RDY_INCORRECT_WRITE_DATA     (0x0C)
+#define MPI_SASSTATUS_XFER_RDY_REQUEST_OFFSET_ERROR     (0x0D)
+#define MPI_SASSTATUS_XFER_RDY_NOT_EXPECTED             (0x0E)
+#define MPI_SASSTATUS_DATA_INCORRECT_DATA_LENGTH        (0x0F)
+#define MPI_SASSTATUS_DATA_TOO_MUCH_READ_DATA           (0x10)
+#define MPI_SASSTATUS_DATA_OFFSET_ERROR                 (0x11)
+#define MPI_SASSTATUS_SDSF_NAK_RECEIVED                 (0x12)
+#define MPI_SASSTATUS_SDSF_CONNECTION_FAILED            (0x13)
+#define MPI_SASSTATUS_INITIATOR_RESPONSE_TIMEOUT        (0x14)
+
+
+/*
+ * Values for the SAS DeviceInfo field used in SAS Device Status Change Event
+ * data and SAS IO Unit Configuration pages.
+ */
+#define MPI_SAS_DEVICE_INFO_ATAPI_DEVICE        (0x00002000)
+#define MPI_SAS_DEVICE_INFO_LSI_DEVICE          (0x00001000)
+#define MPI_SAS_DEVICE_INFO_DIRECT_ATTACH       (0x00000800)
+#define MPI_SAS_DEVICE_INFO_SSP_TARGET          (0x00000400)
+#define MPI_SAS_DEVICE_INFO_STP_TARGET          (0x00000200)
+#define MPI_SAS_DEVICE_INFO_SMP_TARGET          (0x00000100)
+#define MPI_SAS_DEVICE_INFO_SATA_DEVICE         (0x00000080)
+#define MPI_SAS_DEVICE_INFO_SSP_INITIATOR       (0x00000040)
+#define MPI_SAS_DEVICE_INFO_STP_INITIATOR       (0x00000020)
+#define MPI_SAS_DEVICE_INFO_SMP_INITIATOR       (0x00000010)
+#define MPI_SAS_DEVICE_INFO_SATA_HOST           (0x00000008)
+
+#define MPI_SAS_DEVICE_INFO_MASK_DEVICE_TYPE    (0x00000007)
+#define MPI_SAS_DEVICE_INFO_NO_DEVICE           (0x00000000)
+#define MPI_SAS_DEVICE_INFO_END_DEVICE          (0x00000001)
+#define MPI_SAS_DEVICE_INFO_EDGE_EXPANDER       (0x00000002)
+#define MPI_SAS_DEVICE_INFO_FANOUT_EXPANDER     (0x00000003)
+
+
+
 /*****************************************************************************
 *
 *        S e r i a l    A t t a c h e d    S C S I     M e s s a g e s
@@ -48,8 +99,10 @@ typedef struct _MSG_SMP_PASSTHROUGH_REQU
 } MSG_SMP_PASSTHROUGH_REQUEST, MPI_POINTER PTR_MSG_SMP_PASSTHROUGH_REQUEST,
   SmpPassthroughRequest_t, MPI_POINTER pSmpPassthroughRequest_t;
 
+/* values for PassthroughFlags field */
 #define MPI_SMP_PT_REQ_PT_FLAGS_IMMEDIATE       (0x80)
 
+/* values for ConnectionRate field */
 #define MPI_SMP_PT_REQ_CONNECT_RATE_NEGOTIATED  (0x00)
 #define MPI_SMP_PT_REQ_CONNECT_RATE_1_5         (0x08)
 #define MPI_SMP_PT_REQ_CONNECT_RATE_3_0         (0x09)
@@ -77,51 +130,69 @@ typedef struct _MSG_SMP_PASSTHROUGH_REPL
 
 #define MPI_SMP_PT_REPLY_PT_FLAGS_IMMEDIATE     (0x80)
 
-/* values for the SASStatus field */
-#define MPI_SASSTATUS_SUCCESS                           (0x00)
-#define MPI_SASSTATUS_UNKNOWN_ERROR                     (0x01)
-#define MPI_SASSTATUS_INVALID_FRAME                     (0x02)
-#define MPI_SASSTATUS_UTC_BAD_DEST                      (0x03)
-#define MPI_SASSTATUS_UTC_BREAK_RECEIVED                (0x04)
-#define MPI_SASSTATUS_UTC_CONNECT_RATE_NOT_SUPPORTED    (0x05)
-#define MPI_SASSTATUS_UTC_PORT_LAYER_REQUEST            (0x06)
-#define MPI_SASSTATUS_UTC_PROTOCOL_NOT_SUPPORTED        (0x07)
-#define MPI_SASSTATUS_UTC_STP_RESOURCES_BUSY            (0x08)
-#define MPI_SASSTATUS_UTC_WRONG_DESTINATION             (0x09)
-#define MPI_SASSTATUS_SHORT_INFORMATION_UNIT            (0x0A)
-#define MPI_SASSTATUS_LONG_INFORMATION_UNIT             (0x0B)
-#define MPI_SASSTATUS_XFER_RDY_INCORRECT_WRITE_DATA     (0x0C)
-#define MPI_SASSTATUS_XFER_RDY_REQUEST_OFFSET_ERROR     (0x0D)
-#define MPI_SASSTATUS_XFER_RDY_NOT_EXPECTED             (0x0E)
-#define MPI_SASSTATUS_DATA_INCORRECT_DATA_LENGTH        (0x0F)
-#define MPI_SASSTATUS_DATA_TOO_MUCH_READ_DATA           (0x10)
-#define MPI_SASSTATUS_DATA_OFFSET_ERROR                 (0x11)
-#define MPI_SASSTATUS_SDSF_NAK_RECEIVED                 (0x12)
-#define MPI_SASSTATUS_SDSF_CONNECTION_FAILED            (0x13)
-#define MPI_SASSTATUS_INITIATOR_RESPONSE_TIMEOUT        (0x14)
 
+/****************************************************************************/
+/* SATA Passthrough Request                                                 */
+/****************************************************************************/
+
+typedef struct _MSG_SATA_PASSTHROUGH_REQUEST
+{
+    U8                      TargetID;           /* 00h */
+    U8                      Bus;                /* 01h */
+    U8                      ChainOffset;        /* 02h */
+    U8                      Function;           /* 03h */
+    U16                     PassthroughFlags;   /* 04h */
+    U8                      ConnectionRate;     /* 06h */
+    U8                      MsgFlags;           /* 07h */
+    U32                     MsgContext;         /* 08h */
+    U32                     Reserved1;          /* 0Ch */
+    U32                     Reserved2;          /* 10h */
+    U32                     Reserved3;          /* 14h */
+    U32                     DataLength;         /* 18h */
+    U8                      CommandFIS[20];     /* 1Ch */
+    SGE_SIMPLE_UNION        SGL;                /* 30h */
+} MSG_SATA_PASSTHROUGH_REQUEST, MPI_POINTER PTR_MSG_SATA_PASSTHROUGH_REQUEST,
+  SataPassthroughRequest_t, MPI_POINTER pSataPassthroughRequest_t;
+
+/* values for PassthroughFlags field */
+#define MPI_SATA_PT_REQ_PT_FLAGS_RESET_DEVICE   (0x0200)
+#define MPI_SATA_PT_REQ_PT_FLAGS_EXECUTE_DIAG   (0x0100)
+#define MPI_SATA_PT_REQ_PT_FLAGS_DMA_QUEUED     (0x0080)
+#define MPI_SATA_PT_REQ_PT_FLAGS_PACKET_COMMAND (0x0040)
+#define MPI_SATA_PT_REQ_PT_FLAGS_DMA            (0x0020)
+#define MPI_SATA_PT_REQ_PT_FLAGS_PIO            (0x0010)
+#define MPI_SATA_PT_REQ_PT_FLAGS_UNSPECIFIED_VU (0x0004)
+#define MPI_SATA_PT_REQ_PT_FLAGS_WRITE          (0x0002)
+#define MPI_SATA_PT_REQ_PT_FLAGS_READ           (0x0001)
+
+/* values for ConnectionRate field */
+#define MPI_SATA_PT_REQ_CONNECT_RATE_NEGOTIATED (0x00)
+#define MPI_SATA_PT_REQ_CONNECT_RATE_1_5        (0x08)
+#define MPI_SATA_PT_REQ_CONNECT_RATE_3_0        (0x09)
+
+
+/* SATA Passthrough Reply */
+typedef struct _MSG_SATA_PASSTHROUGH_REPLY
+{
+    U8                      TargetID;           /* 00h */
+    U8                      Bus;                /* 01h */
+    U8                      MsgLength;          /* 02h */
+    U8                      Function;           /* 03h */
+    U16                     PassthroughFlags;   /* 04h */
+    U8                      Reserved1;          /* 06h */
+    U8                      MsgFlags;           /* 07h */
+    U32                     MsgContext;         /* 08h */
+    U8                      Reserved2;          /* 0Ch */
+    U8                      SASStatus;          /* 0Dh */
+    U16                     IOCStatus;          /* 0Eh */
+    U32                     IOCLogInfo;         /* 10h */
+    U8                      StatusFIS[20];      /* 14h */
+    U32                     StatusControlRegisters; /* 28h */
+    U32                     TransferCount;      /* 2Ch */
+} MSG_SATA_PASSTHROUGH_REPLY, MPI_POINTER PTR_MSG_SATA_PASSTHROUGH_REPLY,
+  SataPassthroughReply_t, MPI_POINTER pSataPassthroughReply_t;
 
-/*
- * Values for the SAS DeviceInfo field used in SAS Device Status Change Event
- * data and SAS IO Unit Configuration pages.
- */
-#define MPI_SAS_DEVICE_INFO_ATAPI_DEVICE        (0x00002000)
-#define MPI_SAS_DEVICE_INFO_LSI_DEVICE          (0x00001000)
-#define MPI_SAS_DEVICE_INFO_DIRECT_ATTACH       (0x00000800)
-#define MPI_SAS_DEVICE_INFO_SSP_TARGET          (0x00000400)
-#define MPI_SAS_DEVICE_INFO_STP_TARGET          (0x00000200)
-#define MPI_SAS_DEVICE_INFO_SMP_TARGET          (0x00000100)
-#define MPI_SAS_DEVICE_INFO_SATA_DEVICE         (0x00000080)
-#define MPI_SAS_DEVICE_INFO_SSP_INITIATOR       (0x00000040)
-#define MPI_SAS_DEVICE_INFO_STP_INITIATOR       (0x00000020)
-#define MPI_SAS_DEVICE_INFO_SMP_INITIATOR       (0x00000010)
-#define MPI_SAS_DEVICE_INFO_SATA_HOST           (0x00000008)
 
-#define MPI_SAS_DEVICE_INFO_MASK_DEVICE_TYPE    (0x00000007)
-#define MPI_SAS_DEVICE_INFO_NO_DEVICE           (0x00000000)
-#define MPI_SAS_DEVICE_INFO_END_DEVICE          (0x00000001)
-#define MPI_SAS_DEVICE_INFO_EDGE_EXPANDER       (0x00000002)
-#define MPI_SAS_DEVICE_INFO_FANOUT_EXPANDER     (0x00000003)
 
 
 /****************************************************************************/
@@ -148,15 +219,13 @@ typedef struct _MSG_SAS_IOUNIT_CONTROL_R
 } MSG_SAS_IOUNIT_CONTROL_REQUEST, MPI_POINTER PTR_MSG_SAS_IOUNIT_CONTROL_REQUEST,
   SasIoUnitControlRequest_t, MPI_POINTER pSasIoUnitControlRequest_t;
 
-/* values for the ... field */
+/* values for the Operation field */
 #define MPI_SAS_OP_CLEAR_NOT_PRESENT             (0x01)
-#define MPI_SAS_OP_CLEAR_ALL                     (0x02)
-#define MPI_SAS_OP_MAP                           (0x03)
-#define MPI_SAS_OP_MOVE                          (0x04)
-#define MPI_SAS_OP_CLEAR                         (0x05)
+#define MPI_SAS_OP_CLEAR_ALL_PERSISTENT          (0x02)
 #define MPI_SAS_OP_PHY_LINK_RESET                (0x06)
 #define MPI_SAS_OP_PHY_HARD_RESET                (0x07)
 #define MPI_SAS_OP_PHY_CLEAR_ERROR_LOG           (0x08)
+#define MPI_SAS_OP_MAP_CURRENT                   (0x09)
 
 
 /* SAS IO Unit Control Reply */
diff --git a/drivers/message/fusion/lsi/mpi_targ.h b/drivers/message/fusion/lsi/mpi_targ.h
--- a/drivers/message/fusion/lsi/mpi_targ.h
+++ b/drivers/message/fusion/lsi/mpi_targ.h
@@ -1,12 +1,12 @@
 /*
- *  Copyright (c) 2000-2003 LSI Logic Corporation.
+ *  Copyright (c) 2000-2004 LSI Logic Corporation.
  *
  *
  *           Name:  mpi_targ.h
  *          Title:  MPI Target mode messages and structures
  *  Creation Date:  June 22, 2000
  *
- *    mpi_targ.h Version:  01.05.xx
+ *    mpi_targ.h Version:  01.05.04
  *
  *  Version History
  *  ---------------
@@ -43,6 +43,16 @@
  *                      Added PRIORITY_REASON_TARGET_BUSY.
  *  11-15-02  01.02.08  Added AliasID field to MPI_TARGET_SCSI_SPI_CMD_BUFFER.
  *  04-01-03  01.02.09  Added OptionalOxid field to MPI_TARGET_FCP_CMD_BUFFER.
+ *  05-11-04  01.03.01  Original release for MPI v1.3.
+ *  08-19-04  01.05.01  Added new request message structures for
+ *                      MSG_TARGET_CMD_BUF_POST_BASE_REQUEST,
+ *                      MSG_TARGET_CMD_BUF_POST_LIST_REQUEST, and
+ *                      MSG_TARGET_ASSIST_EXT_REQUEST.
+ *                      Added new structures for SAS SSP Command buffer, SSP
+ *                      Task buffer, and SSP Status IU.
+ *  10-05-04  01.05.02  MSG_TARGET_CMD_BUFFER_POST_BASE_LIST_REPLY added.
+ *  02-22-05  01.05.03  Changed a comment.
+ *  03-11-05  01.05.04  Removed TargetAssistExtended Request.
  *  --------------------------------------------------------------------------
  */
 
@@ -133,6 +143,25 @@ typedef struct _MSG_PRIORITY_CMD_RECEIVE
 } MSG_PRIORITY_CMD_RECEIVED_REPLY, MPI_POINTER PTR_MSG_PRIORITY_CMD_RECEIVED_REPLY,
   PriorityCommandReceivedReply_t, MPI_POINTER pPriorityCommandReceivedReply_t;
 
+
+typedef struct _MSG_TARGET_CMD_BUFFER_POST_ERROR_REPLY
+{
+    U16                     Reserved;                   /* 00h */
+    U8                      MsgLength;                  /* 02h */
+    U8                      Function;                   /* 03h */
+    U16                     Reserved1;                  /* 04h */
+    U8                      Reserved2;                  /* 06h */
+    U8                      MsgFlags;                   /* 07h */
+    U32                     MsgContext;                 /* 08h */
+    U8                      PriorityReason;             /* 0Ch */
+    U8                      Reserved3;                  /* 0Dh */
+    U16                     IOCStatus;                  /* 0Eh */
+    U32                     IOCLogInfo;                 /* 10h */
+    U32                     ReplyWord;                  /* 14h */
+} MSG_TARGET_CMD_BUFFER_POST_ERROR_REPLY,
+  MPI_POINTER PTR_MSG_TARGET_CMD_BUFFER_POST_ERROR_REPLY,
+  TargetCmdBufferPostErrorReply_t, MPI_POINTER pTargetCmdBufferPostErrorReply_t;
+
 #define PRIORITY_REASON_NO_DISCONNECT           (0x00)
 #define PRIORITY_REASON_SCSI_TASK_MANAGEMENT    (0x01)
 #define PRIORITY_REASON_CMD_PARITY_ERR          (0x02)
@@ -146,7 +175,34 @@ typedef struct _MSG_PRIORITY_CMD_RECEIVE
 #define PRIORITY_REASON_UNKNOWN                 (0xFF)
 
 
-typedef struct _MSG_TARGET_CMD_BUFFER_POST_ERROR_REPLY
+/****************************************************************************/
+/* Target Command Buffer Post Base Request                                  */
+/****************************************************************************/
+
+typedef struct _MSG_TARGET_CMD_BUF_POST_BASE_REQUEST
+{
+    U8                      BufferPostFlags;            /* 00h */
+    U8                      PortNumber;                 /* 01h */
+    U8                      ChainOffset;                /* 02h */
+    U8                      Function;                   /* 03h */
+    U16                     TotalCmdBuffers;            /* 04h */
+    U8                      Reserved;                   /* 06h */
+    U8                      MsgFlags;                   /* 07h */
+    U32                     MsgContext;                 /* 08h */
+    U32                     Reserved1;                  /* 0Ch */
+    U16                     CmdBufferLength;            /* 10h */
+    U16                     NextCmdBufferOffset;        /* 12h */
+    U32                     BaseAddressLow;             /* 14h */
+    U32                     BaseAddressHigh;            /* 18h */
+} MSG_TARGET_CMD_BUF_POST_BASE_REQUEST,
+  MPI_POINTER PTR__MSG_TARGET_CMD_BUF_POST_BASE_REQUEST,
+  TargetCmdBufferPostBaseRequest_t,
+  MPI_POINTER pTargetCmdBufferPostBaseRequest_t;
+
+#define CMD_BUFFER_POST_BASE_FLAGS_AUTO_POST_ALL    (0x01)
+
+
+typedef struct _MSG_TARGET_CMD_BUFFER_POST_BASE_LIST_REPLY
 {
     U16                     Reserved;                   /* 00h */
     U8                      MsgLength;                  /* 02h */
@@ -155,16 +211,41 @@ typedef struct _MSG_TARGET_CMD_BUFFER_PO
     U8                      Reserved2;                  /* 06h */
     U8                      MsgFlags;                   /* 07h */
     U32                     MsgContext;                 /* 08h */
-    U8                      PriorityReason;             /* 0Ch */
-    U8                      Reserved3;                  /* 0Dh */
+    U16                     Reserved3;                  /* 0Ch */
     U16                     IOCStatus;                  /* 0Eh */
     U32                     IOCLogInfo;                 /* 10h */
-    U32                     ReplyWord;                  /* 14h */
-} MSG_TARGET_CMD_BUFFER_POST_ERROR_REPLY,
-  MPI_POINTER PTR_MSG_TARGET_CMD_BUFFER_POST_ERROR_REPLY,
-  TargetCmdBufferPostErrorReply_t, MPI_POINTER pTargetCmdBufferPostErrorReply_t;
+} MSG_TARGET_CMD_BUFFER_POST_BASE_LIST_REPLY,
+  MPI_POINTER PTR_MSG_TARGET_CMD_BUFFER_POST_BASE_LIST_REPLY,
+  TargetCmdBufferPostBaseListReply_t,
+  MPI_POINTER pTargetCmdBufferPostBaseListReply_t;
+
+
+/****************************************************************************/
+/* Target Command Buffer Post List Request                                  */
+/****************************************************************************/
+
+typedef struct _MSG_TARGET_CMD_BUF_POST_LIST_REQUEST
+{
+    U8                      Reserved;                   /* 00h */
+    U8                      PortNumber;                 /* 01h */
+    U8                      ChainOffset;                /* 02h */
+    U8                      Function;                   /* 03h */
+    U16                     CmdBufferCount;             /* 04h */
+    U8                      Reserved1;                  /* 06h */
+    U8                      MsgFlags;                   /* 07h */
+    U32                     MsgContext;                 /* 08h */
+    U32                     Reserved2;                  /* 0Ch */
+    U16                     IoIndex[2];                 /* 10h */
+} MSG_TARGET_CMD_BUF_POST_LIST_REQUEST,
+  MPI_POINTER PTR_MSG_TARGET_CMD_BUF_POST_LIST_REQUEST,
+  TargetCmdBufferPostListRequest_t,
+  MPI_POINTER pTargetCmdBufferPostListRequest_t;
 
 
+/****************************************************************************/
+/* Command Buffer Formats (with 16 byte CDB)                                */
+/****************************************************************************/
+
 typedef struct _MPI_TARGET_FCP_CMD_BUFFER
 {
     U8      FcpLun[8];                                  /* 00h */
@@ -201,6 +282,46 @@ typedef struct _MPI_TARGET_SCSI_SPI_CMD_
   MpiTargetScsiSpiCmdBuffer, MPI_POINTER pMpiTargetScsiSpiCmdBuffer;
 
 
+typedef struct _MPI_TARGET_SSP_CMD_BUFFER
+{
+    U8      FrameType;                                  /* 00h */
+    U8      Reserved1;                                  /* 01h */
+    U16     Reserved2;                                  /* 02h */
+    U16     InitiatorTag;                               /* 04h */
+    U16     DevHandle;                                  /* 06h */
+    /* COMMAND information unit starts here */
+    U8      LogicalUnitNumber[8];                       /* 08h */
+    U8      Reserved3;                                  /* 10h */
+    U8      TaskAttribute; /* lower 3 bits */           /* 11h */
+    U8      Reserved4;                                  /* 12h */
+    U8      AdditionalCDBLength; /* upper 5 bits */     /* 13h */
+    U8      CDB[16];                                    /* 14h */
+    /* Additional CDB bytes extend past the CDB field */
+} MPI_TARGET_SSP_CMD_BUFFER, MPI_POINTER PTR_MPI_TARGET_SSP_CMD_BUFFER,
+  MpiTargetSspCmdBuffer, MPI_POINTER pMpiTargetSspCmdBuffer;
+
+typedef struct _MPI_TARGET_SSP_TASK_BUFFER
+{
+    U8      FrameType;                                  /* 00h */
+    U8      Reserved1;                                  /* 01h */
+    U16     Reserved2;                                  /* 02h */
+    U16     InitiatorTag;                               /* 04h */
+    U16     DevHandle;                                  /* 06h */
+    /* TASK information unit starts here */
+    U8      LogicalUnitNumber[8];                       /* 08h */
+    U8      Reserved3;                                  /* 10h */
+    U8      Reserved4;                                  /* 11h */
+    U8      TaskManagementFunction;                     /* 12h */
+    U8      Reserved5;                                  /* 13h */
+    U16     ManagedTaskTag;                             /* 14h */
+    U16     Reserved6;                                  /* 16h */
+    U32     Reserved7;                                  /* 18h */
+    U32     Reserved8;                                  /* 1Ch */
+    U32     Reserved9;                                  /* 20h */
+} MPI_TARGET_SSP_TASK_BUFFER, MPI_POINTER PTR_MPI_TARGET_SSP_TASK_BUFFER,
+  MpiTargetSspTaskBuffer, MPI_POINTER pMpiTargetSspTaskBuffer;
+
+
 /****************************************************************************/
 /* Target Assist Request                                                    */
 /****************************************************************************/
@@ -308,6 +429,27 @@ typedef struct _MPI_TARGET_SCSI_SPI_STAT
 } MPI_TARGET_SCSI_SPI_STATUS_IU, MPI_POINTER PTR_MPI_TARGET_SCSI_SPI_STATUS_IU,
   TargetScsiSpiStatusIU_t, MPI_POINTER pTargetScsiSpiStatusIU_t;
 
+/*
+ * NOTE: The SSP status IU is big-endian. When used on a little-endian system,
+ * this structure properly orders the bytes.
+ */
+typedef struct _MPI_TARGET_SSP_RSP_IU
+{
+    U32     Reserved0[6]; /* reserved for SSP header */ /* 00h */
+    /* start of RESPONSE information unit */
+    U32     Reserved1;                                  /* 18h */
+    U32     Reserved2;                                  /* 1Ch */
+    U16     Reserved3;                                  /* 20h */
+    U8      DataPres; /* lower 2 bits */                /* 22h */
+    U8      Status;                                     /* 23h */
+    U32     Reserved4;                                  /* 24h */
+    U32     SenseDataLength;                            /* 28h */
+    U32     ResponseDataLength;                         /* 2Ch */
+    U8      ResponseSenseData[4];                       /* 30h */
+} MPI_TARGET_SSP_RSP_IU, MPI_POINTER PTR_MPI_TARGET_SSP_RSP_IU,
+  MpiTargetSspRspIu_t, MPI_POINTER pMpiTargetSspRspIu_t;
+
+
 /****************************************************************************/
 /* Target Mode Abort Request                                                */
 /****************************************************************************/
diff --git a/drivers/message/fusion/lsi/mpi_tool.h b/drivers/message/fusion/lsi/mpi_tool.h
--- a/drivers/message/fusion/lsi/mpi_tool.h
+++ b/drivers/message/fusion/lsi/mpi_tool.h
@@ -1,12 +1,12 @@
 /*
- *  Copyright (c) 2001-2003 LSI Logic Corporation.
+ *  Copyright (c) 2001-2005 LSI Logic Corporation.
  *
  *
  *           Name:  mpi_tool.h
  *          Title:  MPI Toolbox structures and definitions
  *  Creation Date:  July 30, 2001
  *
- *    mpi_tool.h Version:  01.05.xx
+ *    mpi_tool.h Version:  01.05.03
  *
  *  Version History
  *  ---------------
@@ -15,6 +15,16 @@
  *  --------  --------  ------------------------------------------------------
  *  08-08-01  01.02.01  Original release.
  *  08-29-01  01.02.02  Added DIAG_DATA_UPLOAD_HEADER and related defines.
+ *  01-16-04  01.02.03  Added defines and structures for new tools
+ *.                     MPI_TOOLBOX_ISTWI_READ_WRITE_TOOL and
+ *                      MPI_TOOLBOX_FC_MANAGEMENT_TOOL.
+ *  04-29-04  01.02.04  Added message structures for Diagnostic Buffer Post and
+ *                      Diagnostic Release requests and replies.
+ *  05-11-04  01.03.01  Original release for MPI v1.3.
+ *  08-19-04  01.05.01  Original release for MPI v1.5.
+ *  10-06-04  01.05.02  Added define for MPI_DIAG_BUF_TYPE_COUNT.
+ *  02-09-05  01.05.03  Added frame size option to FC management tool.
+ *                      Added Beacon tool to the Toolbox.
  *  --------------------------------------------------------------------------
  */
 
@@ -26,6 +36,7 @@
 #define MPI_TOOLBOX_DIAG_DATA_UPLOAD_TOOL           (0x02)
 #define MPI_TOOLBOX_ISTWI_READ_WRITE_TOOL           (0x03)
 #define MPI_TOOLBOX_FC_MANAGEMENT_TOOL              (0x04)
+#define MPI_TOOLBOX_BEACON_TOOL                     (0x05)
 
 
 /****************************************************************************/
@@ -185,11 +196,21 @@ typedef struct _MPI_TB_FC_MANAGE_PID_AI
 } MPI_TB_FC_MANAGE_PID_AI, MPI_POINTER PTR_MPI_TB_FC_MANAGE_PID_AI,
   MpiTbFcManagePidAi_t, MPI_POINTER pMpiTbFcManagePidAi_t;
 
+/* ActionInfo for set max frame size */
+typedef struct _MPI_TB_FC_MANAGE_FRAME_SIZE_AI
+{
+    U16                     FrameSize;                  /* 00h */
+    U8                      PortNum;                    /* 02h */
+    U8                      Reserved1;                  /* 03h */
+} MPI_TB_FC_MANAGE_FRAME_SIZE_AI, MPI_POINTER PTR_MPI_TB_FC_MANAGE_FRAME_SIZE_AI,
+  MpiTbFcManageFrameSizeAi_t, MPI_POINTER pMpiTbFcManageFrameSizeAi_t;
+
 /* union of ActionInfo */
 typedef union _MPI_TB_FC_MANAGE_AI_UNION
 {
     MPI_TB_FC_MANAGE_BUS_TID_AI     BusTid;
     MPI_TB_FC_MANAGE_PID_AI         Port;
+    MPI_TB_FC_MANAGE_FRAME_SIZE_AI  FrameSize;
 } MPI_TB_FC_MANAGE_AI_UNION, MPI_POINTER PTR_MPI_TB_FC_MANAGE_AI_UNION,
   MpiTbFcManageAiUnion_t, MPI_POINTER pMpiTbFcManageAiUnion_t;
 
@@ -214,6 +235,32 @@ typedef struct _MSG_TOOLBOX_FC_MANAGE_RE
 #define MPI_TB_FC_MANAGE_ACTION_DISC_ALL            (0x00)
 #define MPI_TB_FC_MANAGE_ACTION_DISC_PID            (0x01)
 #define MPI_TB_FC_MANAGE_ACTION_DISC_BUS_TID        (0x02)
+#define MPI_TB_FC_MANAGE_ACTION_SET_MAX_FRAME_SIZE  (0x03)
+
+
+/****************************************************************************/
+/* Toolbox Beacon Tool request                                               */
+/****************************************************************************/
+
+typedef struct _MSG_TOOLBOX_BEACON_REQUEST
+{
+    U8                      Tool;                       /* 00h */
+    U8                      Reserved;                   /* 01h */
+    U8                      ChainOffset;                /* 02h */
+    U8                      Function;                   /* 03h */
+    U16                     Reserved1;                  /* 04h */
+    U8                      Reserved2;                  /* 06h */
+    U8                      MsgFlags;                   /* 07h */
+    U32                     MsgContext;                 /* 08h */
+    U8                      ConnectNum;                 /* 0Ch */
+    U8                      PortNum;                    /* 0Dh */
+    U8                      Reserved3;                  /* 0Eh */
+    U8                      Flags;                      /* 0Fh */
+} MSG_TOOLBOX_BEACON_REQUEST, MPI_POINTER PTR_MSG_TOOLBOX_BEACON_REQUEST,
+  ToolboxBeaconRequest_t, MPI_POINTER pToolboxBeaconRequest_t;
+
+#define MPI_TOOLBOX_FLAGS_BEACON_MODE_OFF       (0x00)
+#define MPI_TOOLBOX_FLAGS_BEACON_MODE_ON        (0x01)
 
 
 /****************************************************************************/
@@ -233,14 +280,16 @@ typedef struct _MSG_DIAG_BUFFER_POST_REQ
     U32                     ExtendedType;               /* 0Ch */
     U32                     BufferLength;               /* 10h */
     U32                     ProductSpecific[4];         /* 14h */
-    U32                     Reserved3;                  /* 18h */
-    SGE_SIMPLE_UNION        SGL;                        /* 28h */
+    U32                     Reserved3;                  /* 24h */
+    U64                     BufferAddress;              /* 28h */
 } MSG_DIAG_BUFFER_POST_REQUEST, MPI_POINTER PTR_MSG_DIAG_BUFFER_POST_REQUEST,
   DiagBufferPostRequest_t, MPI_POINTER pDiagBufferPostRequest_t;
 
 #define MPI_DIAG_BUF_TYPE_TRACE                     (0x00)
 #define MPI_DIAG_BUF_TYPE_SNAPSHOT                  (0x01)
 #define MPI_DIAG_BUF_TYPE_EXTENDED                  (0x02)
+/* count of the number of buffer types */
+#define MPI_DIAG_BUF_TYPE_COUNT                     (0x03)
 
 #define MPI_DIAG_EXTENDED_QTAG                      (0x00000001)
 
diff --git a/drivers/message/fusion/lsi/mpi_type.h b/drivers/message/fusion/lsi/mpi_type.h
--- a/drivers/message/fusion/lsi/mpi_type.h
+++ b/drivers/message/fusion/lsi/mpi_type.h
@@ -1,12 +1,12 @@
 /*
- *  Copyright (c) 2000-2003 LSI Logic Corporation.
+ *  Copyright (c) 2000-2004 LSI Logic Corporation.
  *
  *
  *           Name:  mpi_type.h
  *          Title:  MPI Basic type definitions
  *  Creation Date:  June 6, 2000
  *
- *    mpi_type.h Version:  01.05.xx
+ *    mpi_type.h Version:  01.05.01
  *
  *  Version History
  *  ---------------
@@ -18,6 +18,8 @@
  *  11-02-00  01.01.01  Original release for post 1.0 work
  *  02-20-01  01.01.02  Added define and ifdef for MPI_POINTER.
  *  08-08-01  01.02.01  Original release for v1.2 work.
+ *  05-11-04  01.03.01  Original release for MPI v1.3.
+ *  08-19-04  01.05.01  Original release for MPI v1.5.
  *  --------------------------------------------------------------------------
  */
 
@@ -50,11 +52,6 @@ typedef unsigned short  U16;
 typedef int32_t   S32;
 typedef u_int32_t U32;
 
-/*
- *  The only way crap below could work on big-endian boxen would be if it
- *  wasn't used at all.
- */
-
 typedef struct _S64
 {
     U32          Low;
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c
--- a/drivers/message/fusion/mptbase.c
+++ b/drivers/message/fusion/mptbase.c
@@ -1,55 +1,13 @@
 /*
  *  linux/drivers/message/fusion/mptbase.c
- *      High performance SCSI + LAN / Fibre Channel device drivers.
  *      This is the Fusion MPT base driver which supports multiple
  *      (SCSI + LAN) specialized protocol drivers.
- *      For use with PCI chip/adapter(s):
- *          LSIFC9xx/LSI409xx Fibre Channel
+ *      For use with LSI Logic PCI chip/adapter(s)
  *      running LSI Logic Fusion MPT (Message Passing Technology) firmware.
  *
- *  Credits:
- *      There are lots of people not mentioned below that deserve credit
- *      and thanks but won't get it here - sorry in advance that you
- *      got overlooked.
- *
- *      This driver would not exist if not for Alan Cox's development
- *      of the linux i2o driver.
- *
- *      A special thanks to Noah Romer (LSI Logic) for tons of work
- *      and tough debugging on the LAN driver, especially early on;-)
- *      And to Roger Hickerson (LSI Logic) for tirelessly supporting
- *      this driver project.
- *
- *      A special thanks to Pamela Delaney (LSI Logic) for tons of work
- *      and countless enhancements while adding support for the 1030
- *      chip family.  Pam has been instrumental in the development of
- *      of the 2.xx.xx series fusion drivers, and her contributions are
- *      far too numerous to hope to list in one place.
- *
- *      All manner of help from Stephen Shirron (LSI Logic):
- *      low-level FC analysis, debug + various fixes in FCxx firmware,
- *      initial port to alpha platform, various driver code optimizations,
- *      being a faithful sounding board on all sorts of issues & ideas,
- *      etc.
- *
- *      A huge debt of gratitude is owed to David S. Miller (DaveM)
- *      for fixing much of the stupid and broken stuff in the early
- *      driver while porting to sparc64 platform.  THANK YOU!
- *
- *      Special thanks goes to the I2O LAN driver people at the
- *      University of Helsinki, who, unbeknownst to them, provided
- *      the inspiration and initial structure for this driver.
- *
- *      A really huge debt of gratitude is owed to Eddie C. Dost
- *      for gobs of hard work fixing and optimizing LAN code.
- *      THANK YOU!
- *
- *  Copyright (c) 1999-2004 LSI Logic Corporation
- *  Originally By: Steven J. Ralston
- *  (mailto:sjralston1@netscape.net)
+ *  Copyright (c) 1999-2005 LSI Logic Corporation
  *  (mailto:mpt_linux_developer@lsil.com)
  *
- *  $Id: mptbase.c,v 1.126 2002/12/16 15:28:45 pdelaney Exp $
  */
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
@@ -101,6 +59,7 @@
 #include <linux/blkdev.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>		/* needed for in_interrupt() proto */
+#include <linux/dma-mapping.h>
 #include <asm/io.h>
 #ifdef CONFIG_MTRR
 #include <asm/mtrr.h>
@@ -218,41 +177,35 @@ static void	mpt_fc_log_info(MPT_ADAPTER 
 static void	mpt_sp_log_info(MPT_ADAPTER *ioc, u32 log_info);
 
 /* module entry point */
-static int  __devinit mptbase_probe (struct pci_dev *, const struct pci_device_id *);
-static void __devexit mptbase_remove(struct pci_dev *);
-static void mptbase_shutdown(struct device * );
 static int  __init    fusion_init  (void);
 static void __exit    fusion_exit  (void);
 
-/****************************************************************************
- * Supported hardware
- */
-
-static struct pci_device_id mptbase_pci_table[] = {
-	{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC909,
-		PCI_ANY_ID, PCI_ANY_ID },
-	{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC929,
-		PCI_ANY_ID, PCI_ANY_ID },
-	{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC919,
-		PCI_ANY_ID, PCI_ANY_ID },
-	{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC929X,
-		PCI_ANY_ID, PCI_ANY_ID },
-	{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC919X,
-		PCI_ANY_ID, PCI_ANY_ID },
-	{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_53C1030,
-		PCI_ANY_ID, PCI_ANY_ID },
-	{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_1030_53C1035,
-		PCI_ANY_ID, PCI_ANY_ID },
-	{0}	/* Terminating entry */
-};
-MODULE_DEVICE_TABLE(pci, mptbase_pci_table);
-
 #define CHIPREG_READ32(addr) 		readl_relaxed(addr)
 #define CHIPREG_READ32_dmasync(addr)	readl(addr)
 #define CHIPREG_WRITE32(addr,val) 	writel(val, addr)
 #define CHIPREG_PIO_WRITE32(addr,val)	outl(val, (unsigned long)addr)
 #define CHIPREG_PIO_READ32(addr) 	inl((unsigned long)addr)
 
+static void
+pci_disable_io_access(struct pci_dev *pdev)
+{
+	u16 command_reg;
+
+	pci_read_config_word(pdev, PCI_COMMAND, &command_reg);
+	command_reg &= ~1;
+	pci_write_config_word(pdev, PCI_COMMAND, command_reg);
+}
+
+static void
+pci_enable_io_access(struct pci_dev *pdev)
+{
+	u16 command_reg;
+
+	pci_read_config_word(pdev, PCI_COMMAND, &command_reg);
+	command_reg |= 1;
+	pci_write_config_word(pdev, PCI_COMMAND, command_reg);
+}
+
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
  *	mpt_interrupt - MPT adapter (IOC) specific interrupt handler.
@@ -330,8 +283,7 @@ mpt_interrupt(int irq, void *bus_id, str
 					ioc->name, mr, req_idx));
 			DBG_DUMP_REPLY_FRAME(mr)
 
-			/* NEW!  20010301 -sralston
-			 *  Check/log IOC log info
+			/*  Check/log IOC log info
 			 */
 			ioc_stat = le16_to_cpu(mr->u.reply.IOCStatus);
 			if (ioc_stat & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
@@ -357,9 +309,7 @@ mpt_interrupt(int irq, void *bus_id, str
 				mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
 			} else if (type == MPI_CONTEXT_REPLY_TYPE_LAN) {
 				cb_idx = mpt_lan_index;
-				/*
-				 * BUG FIX!  20001218 -sralston
-				 *  Blind set of mf to NULL here was fatal
+				 /*  Blind set of mf to NULL here was fatal
 				 *  after lan_reply says "freeme"
 				 *  Fix sort of combined with an optimization here;
 				 *  added explicit check for case where lan_reply
@@ -430,15 +380,8 @@ mpt_interrupt(int irq, void *bus_id, str
 		}
 
 		if (freeme) {
-			unsigned long flags;
-
 			/*  Put Request back on FreeQ!  */
-			spin_lock_irqsave(&ioc->FreeQlock, flags);
-			list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
-#ifdef MFCNT
-			ioc->mfcnt--;
-#endif
-			spin_unlock_irqrestore(&ioc->FreeQlock, flags);
+			mpt_free_msg_frame(ioc, mf);
 		}
 
 		mb();
@@ -725,11 +668,9 @@ int
 mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, int cb_idx)
 {
 	MPT_ADAPTER	*ioc;
-	int 		error=0;
 
 	if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS) {
-		error= -EINVAL;
-		return error;
+		return -EINVAL;
 	}
 
 	MptDeviceDriverHandlers[cb_idx] = dd_cbfunc;
@@ -737,14 +678,12 @@ mpt_device_driver_register(struct mpt_pc
 	/* call per pci device probe entry point */
 	list_for_each_entry(ioc, &ioc_list, list) {
 		if(dd_cbfunc->probe) {
-			error = dd_cbfunc->probe(ioc->pcidev,
+			dd_cbfunc->probe(ioc->pcidev,
 			  ioc->pcidev->driver->id_table);
-			if(error != 0)
-				return error;
   		}
 	 }
 
-	return error;
+	return 0;
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -809,8 +748,8 @@ mpt_get_msg_frame(int handle, MPT_ADAPTE
 		mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle;	/* byte */
 		req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
 								/* u16! */
-		req_idx = cpu_to_le16(req_offset / ioc->req_sz);
-		mf->u.frame.hwhdr.msgctxu.fld.req_idx = req_idx;
+		req_idx = req_offset / ioc->req_sz;
+		mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
 		mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
 		ioc->RequestNB[req_idx] = ioc->NB_for_64_byte_frame; /* Default, will be changed if necessary in SG generation */
 #ifdef MFCNT
@@ -856,8 +795,8 @@ mpt_put_msg_frame(int handle, MPT_ADAPTE
 	mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle;		/* byte */
 	req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
 								/* u16! */
-	req_idx = cpu_to_le16(req_offset / ioc->req_sz);
-	mf->u.frame.hwhdr.msgctxu.fld.req_idx = req_idx;
+	req_idx = req_offset / ioc->req_sz;
+	mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
 	mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
 
 #ifdef MPT_DEBUG_MSG_FRAME
@@ -1058,7 +997,7 @@ mpt_verify_adapter(int iocid, MPT_ADAPTE
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
- *	mptbase_probe - Install a PCI intelligent MPT adapter.
+ *	mpt_attach - Install a PCI intelligent MPT adapter.
  *	@pdev: Pointer to pci_dev structure
  *
  *	This routine performs all the steps necessary to bring the IOC of
@@ -1073,8 +1012,8 @@ mpt_verify_adapter(int iocid, MPT_ADAPTE
  *
  *	TODO: Add support for polled controllers
  */
-static int __devinit
-mptbase_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+int
+mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
 {
 	MPT_ADAPTER	*ioc;
 	u8		__iomem *mem;
@@ -1084,7 +1023,6 @@ mptbase_probe(struct pci_dev *pdev, cons
 	u32		 psize;
 	int		 ii;
 	int		 r = -ENODEV;
-	u64		 mask = 0xffffffffffffffffULL;
 	u8		 revision;
 	u8		 pcixcmd;
 	static int	 mpt_ids = 0;
@@ -1097,15 +1035,15 @@ mptbase_probe(struct pci_dev *pdev, cons
 	
 	dinitprintk((KERN_WARNING MYNAM ": mpt_adapter_install\n"));
 	
-	if (!pci_set_dma_mask(pdev, mask)) {
+	if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
 		dprintk((KERN_INFO MYNAM
 			": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n"));
-	} else if (pci_set_dma_mask(pdev, (u64) 0xffffffff)) {
+	} else if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
 		printk(KERN_WARNING MYNAM ": 32 BIT PCI BUS DMA ADDRESSING NOT SUPPORTED\n");
 		return r;
 	}
 
-	if (!pci_set_consistent_dma_mask(pdev, mask))
+	if (!pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK))
 		dprintk((KERN_INFO MYNAM
 			": Using 64 bit consistent mask\n"));
 	else
@@ -1243,6 +1181,16 @@ mptbase_probe(struct pci_dev *pdev, cons
 		pcixcmd &= 0x8F;
 		pci_write_config_byte(pdev, 0x6a, pcixcmd);
 	}
+	else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC939X) {
+		ioc->prod_name = "LSIFC939X";
+		ioc->bus_type = FC;
+		ioc->errata_flag_1064 = 1;
+	}
+	else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC949X) {
+		ioc->prod_name = "LSIFC949X";
+		ioc->bus_type = FC;
+		ioc->errata_flag_1064 = 1;
+	}
 	else if (pdev->device == MPI_MANUFACTPAGE_DEVID_53C1030) {
 		ioc->prod_name = "LSI53C1030";
 		ioc->bus_type = SCSI;
@@ -1261,6 +1209,9 @@ mptbase_probe(struct pci_dev *pdev, cons
 		ioc->bus_type = SCSI;
 	}
 
+	if (ioc->errata_flag_1064)
+		pci_disable_io_access(pdev);
+
 	sprintf(ioc->name, "ioc%d", ioc->id);
 
 	spin_lock_init(&ioc->FreeQlock);
@@ -1303,8 +1254,7 @@ mptbase_probe(struct pci_dev *pdev, cons
 #endif
 	}
 
-	/* NEW!  20010220 -sralston
-	 * Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets.
+	/* Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets.
 	 */
 	mpt_detect_bound_ports(ioc, pdev);
 
@@ -1354,13 +1304,13 @@ mptbase_probe(struct pci_dev *pdev, cons
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
- *	mptbase_remove - Remove a PCI intelligent MPT adapter.
+ *	mpt_detach - Remove a PCI intelligent MPT adapter.
  *	@pdev: Pointer to pci_dev structure
  *
  */
 
-static void __devexit
-mptbase_remove(struct pci_dev *pdev)
+void
+mpt_detach(struct pci_dev *pdev)
 {
 	MPT_ADAPTER 	*ioc = pci_get_drvdata(pdev);
 	char pname[32];
@@ -1397,70 +1347,28 @@ mptbase_remove(struct pci_dev *pdev)
 	pci_set_drvdata(pdev, NULL);
 }
 
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
- *	mptbase_shutdown -
- *
- */
-static void
-mptbase_shutdown(struct device * dev)
-{
-	int ii;
-
-	/* call per device driver shutdown entry point */
-	for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {
-		if(MptDeviceDriverHandlers[ii] &&
-		  MptDeviceDriverHandlers[ii]->shutdown) {
-			MptDeviceDriverHandlers[ii]->shutdown(dev);
-		}
-	}
-
-}
-
-
 /**************************************************************************
  * Power Management
  */
 #ifdef CONFIG_PM
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
- *	mptbase_suspend - Fusion MPT base driver suspend routine.
+ *	mpt_suspend - Fusion MPT base driver suspend routine.
  *
  *
  */
-static int
-mptbase_suspend(struct pci_dev *pdev, pm_message_t state)
+int
+mpt_suspend(struct pci_dev *pdev, pm_message_t state)
 {
 	u32 device_state;
 	MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
-	int ii;
 
-	switch(state)
-	{
-		case 1: /* S1 */
-			device_state=1; /* D1 */;
-			break;
-		case 3: /* S3 */
-		case 4: /* S4 */
-			device_state=3; /* D3 */;
-			break;
-		default:
-			return -EAGAIN /*FIXME*/;
-			break;
-	}
+	device_state=pci_choose_state(pdev, state);
 
 	printk(MYIOC_s_INFO_FMT
 	"pci-suspend: pdev=0x%p, slot=%s, Entering operating state [D%d]\n",
 		ioc->name, pdev, pci_name(pdev), device_state);
 
-	/* call per device driver suspend entry point */
-	for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {
-		if(MptDeviceDriverHandlers[ii] &&
-		  MptDeviceDriverHandlers[ii]->suspend) {
-			MptDeviceDriverHandlers[ii]->suspend(pdev, state);
-		}
-	}
-
 	pci_save_state(pdev);
 
 	/* put ioc into READY_STATE */
@@ -1484,18 +1392,18 @@ mptbase_suspend(struct pci_dev *pdev, pm
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
- *	mptbase_resume - Fusion MPT base driver resume routine.
+ *	mpt_resume - Fusion MPT base driver resume routine.
  *
  *
  */
-static int
-mptbase_resume(struct pci_dev *pdev)
+int
+mpt_resume(struct pci_dev *pdev)
 {
 	MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
 	u32 device_state = pdev->current_state;
 	int recovery_state;
 	int ii;
-
+	
 	printk(MYIOC_s_INFO_FMT
 	"pci-resume: pdev=0x%p, slot=%s, Previous operating state [D%d]\n",
 		ioc->name, pdev, pci_name(pdev), device_state);
@@ -1533,14 +1441,6 @@ mptbase_resume(struct pci_dev *pdev)
 			"pci-resume: success\n", ioc->name);
 	}
 
-	/* call per device driver resume entry point */
-	for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {
-		if(MptDeviceDriverHandlers[ii] &&
-		  MptDeviceDriverHandlers[ii]->resume) {
-			MptDeviceDriverHandlers[ii]->resume(pdev);
-		}
-	}
-
 	return 0;
 }
 #endif
@@ -1719,8 +1619,7 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u3
 		ioc->alt_ioc->active = 1;
 	}
 
-	/* NEW!  20010120 -sralston
-	 *  Enable MPT base driver management of EventNotification
+	/*  Enable MPT base driver management of EventNotification
 	 *  and EventAck handling.
 	 */
 	if ((ret == 0) && (!ioc->facts.EventState))
@@ -1729,9 +1628,7 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u3
 	if (ioc->alt_ioc && alt_ioc_ready && !ioc->alt_ioc->facts.EventState)
 		(void) SendEventNotification(ioc->alt_ioc, 1);	/* 1=Enable EventNotification */
 
-	/* (Bugzilla:fibrebugs, #513)
-	 * Bug fix (part 2)!  20010905 -sralston
-	 *	Add additional "reason" check before call to GetLanConfigPages
+	/*	Add additional "reason" check before call to GetLanConfigPages
 	 *	(combined with GetIoUnitPage2 call).  This prevents a somewhat
 	 *	recursive scenario; GetLanConfigPages times out, timer expired
 	 *	routine calls HardResetHandler, which calls into here again,
@@ -1829,37 +1726,43 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u3
 static void
 mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev)
 {
-	unsigned int match_lo, match_hi;
+	struct pci_dev *peer=NULL;
+	unsigned int slot = PCI_SLOT(pdev->devfn);
+	unsigned int func = PCI_FUNC(pdev->devfn);
 	MPT_ADAPTER *ioc_srch;
 
-	match_lo = pdev->devfn-1;
-	match_hi = pdev->devfn+1;
-	dprintk((MYIOC_s_INFO_FMT "PCI bus/devfn=%x/%x, searching for devfn match on %x or %x\n",
-			ioc->name, pdev->bus->number, pdev->devfn, match_lo, match_hi));
+	dprintk((MYIOC_s_INFO_FMT "PCI device %s devfn=%x/%x,"
+	    " searching for devfn match on %x or %x\n",
+		ioc->name, pci_name(pdev), pdev->devfn,
+		func-1, func+1));
+
+	peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func-1));
+	if (!peer) {
+		peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func+1));
+		if (!peer)
+			return;
+	}
 
 	list_for_each_entry(ioc_srch, &ioc_list, list) {
 		struct pci_dev *_pcidev = ioc_srch->pcidev;
-
-		if ((_pcidev->device == pdev->device) &&
-		    (_pcidev->bus->number == pdev->bus->number) &&
-		    (_pcidev->devfn == match_lo || _pcidev->devfn == match_hi) ) {
+		if (_pcidev == peer) {
 			/* Paranoia checks */
 			if (ioc->alt_ioc != NULL) {
 				printk(KERN_WARNING MYNAM ": Oops, already bound (%s <==> %s)!\n",
-						ioc->name, ioc->alt_ioc->name);
+					ioc->name, ioc->alt_ioc->name);
 				break;
 			} else if (ioc_srch->alt_ioc != NULL) {
 				printk(KERN_WARNING MYNAM ": Oops, already bound (%s <==> %s)!\n",
-						ioc_srch->name, ioc_srch->alt_ioc->name);
+					ioc_srch->name, ioc_srch->alt_ioc->name);
 				break;
 			}
 			dprintk((KERN_INFO MYNAM ": FOUND! binding %s <==> %s\n",
-					ioc->name, ioc_srch->name));
+				ioc->name, ioc_srch->name));
 			ioc_srch->alt_ioc = ioc;
 			ioc->alt_ioc = ioc_srch;
-			break;
 		}
 	}
+	pci_dev_put(peer);
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -1922,15 +1825,10 @@ mpt_adapter_disable(MPT_ADAPTER *ioc)
 		ioc->alloc_total -= sz;
 	}
 
-	if (ioc->spi_data.nvram != NULL) {
-		kfree(ioc->spi_data.nvram);
-		ioc->spi_data.nvram = NULL;
-	}
-
-	if (ioc->spi_data.pIocPg3 != NULL) {
-		kfree(ioc->spi_data.pIocPg3);
-		ioc->spi_data.pIocPg3 = NULL;
-	}
+	kfree(ioc->spi_data.nvram);
+	kfree(ioc->spi_data.pIocPg3);
+	ioc->spi_data.nvram = NULL;
+	ioc->spi_data.pIocPg3 = NULL;
 
 	if (ioc->spi_data.pIocPg4 != NULL) {
 		sz = ioc->spi_data.IocPg4Sz;
@@ -1947,10 +1845,8 @@ mpt_adapter_disable(MPT_ADAPTER *ioc)
 		ioc->ReqToChain = NULL;
 	}
 
-	if (ioc->ChainToChain != NULL) {
-		kfree(ioc->ChainToChain);
-		ioc->ChainToChain = NULL;
-	}
+	kfree(ioc->ChainToChain);
+	ioc->ChainToChain = NULL;
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -2333,7 +2229,7 @@ GetIocFacts(MPT_ADAPTER *ioc, int sleepF
 			return -55;
 		}
 
-		r = sz = le32_to_cpu(facts->BlockSize);
+		r = sz = facts->BlockSize;
 		vv = ((63 / (sz * 4)) + 1) & 0x03;
 		ioc->NB_for_64_byte_frame = vv;
 		while ( sz )
@@ -2785,7 +2681,7 @@ mpt_downloadboot(MPT_ADAPTER *ioc, int s
 	/* prevent a second downloadboot and memory free with alt_ioc */
 	if (ioc->alt_ioc && ioc->alt_ioc->cached_fw)
 		ioc->alt_ioc->cached_fw = NULL;
-	
+
 	CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
 	CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
 	CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
@@ -2843,6 +2739,9 @@ mpt_downloadboot(MPT_ADAPTER *ioc, int s
 	/* Write the LoadStartAddress to the DiagRw Address Register
 	 * using Programmed IO
 	 */
+	if (ioc->errata_flag_1064)
+		pci_enable_io_access(ioc->pcidev);
+
 	CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->LoadStartAddress);
 	ddlprintk((MYIOC_s_INFO_FMT "LoadStart addr written 0x%x \n",
 		ioc->name, pFwHeader->LoadStartAddress));
@@ -2889,6 +2788,9 @@ mpt_downloadboot(MPT_ADAPTER *ioc, int s
 	CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
 	CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData);
 
+	if (ioc->errata_flag_1064)
+		pci_disable_io_access(ioc->pcidev);
+
 	diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
 	ddlprintk((MYIOC_s_INFO_FMT "downloadboot diag0val=%x, turning off PREVENT_IOC_BOOT, DISABLE_ARM\n",
 		ioc->name, diag0val));
@@ -4250,7 +4152,7 @@ mpt_GetScsiPortSettings(MPT_ADAPTER *ioc
 				if ((ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD) ||
 					(ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE))  {
 
-					if (ioc->spi_data.minSyncFactor < MPT_ULTRA)
+				if (ioc->spi_data.minSyncFactor < MPT_ULTRA)
 						ioc->spi_data.minSyncFactor = MPT_ULTRA;
 				}
 			}
@@ -4482,10 +4384,8 @@ mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
 
 	/* Free the old page
 	 */
-	if (ioc->spi_data.pIocPg3) {
-		kfree(ioc->spi_data.pIocPg3);
-		ioc->spi_data.pIocPg3 = NULL;
-	}
+	kfree(ioc->spi_data.pIocPg3);
+	ioc->spi_data.pIocPg3 = NULL;
 
 	/* There is at least one physical disk.
 	 * Read and save IOC Page 3
@@ -4753,9 +4653,7 @@ mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS
 	u32		 flagsLength;
 	int		 in_isr;
 
-	/* (Bugzilla:fibrebugs, #513)
-	 * Bug fix (part 1)!  20010905 -sralston
-	 *	Prevent calling wait_event() (below), if caller happens
+	/*	Prevent calling wait_event() (below), if caller happens
 	 *	to be in ISR context, because that is fatal!
 	 */
 	in_isr = in_interrupt();
@@ -4861,9 +4759,7 @@ mpt_toolbox(MPT_ADAPTER *ioc, CONFIGPARM
 	u32		 flagsLength;
 	int		 in_isr;
 
-	/* (Bugzilla:fibrebugs, #513)
-	 * Bug fix (part 1)!  20010905 -sralston
-	 *	Prevent calling wait_event() (below), if caller happens
+	/*	Prevent calling wait_event() (below), if caller happens
 	 *	to be in ISR context, because that is fatal!
 	 */
 	in_isr = in_interrupt();
@@ -5130,20 +5026,26 @@ static int
 procmpt_version_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
 {
 	int	 ii;
-	int	 scsi, lan, ctl, targ, dmp;
+	int	 scsi, fc, sas, lan, ctl, targ, dmp;
 	char	*drvname;
 	int	 len;
 
 	len = sprintf(buf, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON);
 	len += sprintf(buf+len, "  Fusion MPT base driver\n");
 
-	scsi = lan = ctl = targ = dmp = 0;
+	scsi = fc = sas = lan = ctl = targ = dmp = 0;
 	for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
 		drvname = NULL;
 		if (MptCallbacks[ii]) {
 			switch (MptDriverClass[ii]) {
-			case MPTSCSIH_DRIVER:
-				if (!scsi++) drvname = "SCSI host";
+			case MPTSPI_DRIVER:
+				if (!scsi++) drvname = "SPI host";
+				break;
+			case MPTFC_DRIVER:
+				if (!fc++) drvname = "FC host";
+				break;
+			case MPTSAS_DRIVER:
+				if (!sas++) drvname = "SAS host";
 				break;
 			case MPTLAN_DRIVER:
 				if (!lan++) drvname = "LAN";
@@ -5832,6 +5734,12 @@ mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 io
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+EXPORT_SYMBOL(mpt_attach);
+EXPORT_SYMBOL(mpt_detach);
+#ifdef CONFIG_PM
+EXPORT_SYMBOL(mpt_resume);
+EXPORT_SYMBOL(mpt_suspend);
+#endif
 EXPORT_SYMBOL(ioc_list);
 EXPORT_SYMBOL(mpt_proc_root_dir);
 EXPORT_SYMBOL(mpt_register);
@@ -5860,19 +5768,6 @@ EXPORT_SYMBOL(mpt_read_ioc_pg_3);
 EXPORT_SYMBOL(mpt_alloc_fw_memory);
 EXPORT_SYMBOL(mpt_free_fw_memory);
 
-static struct pci_driver mptbase_driver = {
-	.name		= "mptbase",
-	.id_table	= mptbase_pci_table,
-	.probe		= mptbase_probe,
-	.remove		= __devexit_p(mptbase_remove),
-	.driver         = {
-		.shutdown = mptbase_shutdown,
-        },
-#ifdef CONFIG_PM
-	.suspend	= mptbase_suspend,
-	.resume		= mptbase_resume,
-#endif
-};
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
@@ -5884,7 +5779,6 @@ static int __init
 fusion_init(void)
 {
 	int i;
-	int r;
 
 	show_mptmod_ver(my_NAME, my_VERSION);
 	printk(KERN_INFO COPYRIGHT "\n");
@@ -5896,8 +5790,7 @@ fusion_init(void)
 		MptResetHandlers[i] = NULL;
 	}
 
-	/* NEW!  20010120 -sralston
-	 *  Register ourselves (mptbase) in order to facilitate
+	/*  Register ourselves (mptbase) in order to facilitate
 	 *  EventNotification handling.
 	 */
 	mpt_base_index = mpt_register(mpt_base_reply, MPTBASE_DRIVER);
@@ -5913,11 +5806,7 @@ fusion_init(void)
 #ifdef CONFIG_PROC_FS
 	(void) procmpt_create();
 #endif
-	r = pci_register_driver(&mptbase_driver);
-	if(r)
-		return(r);
-
-	return r;
+	return 0;
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -5933,7 +5822,6 @@ fusion_exit(void)
 
 	dexitprintk((KERN_INFO MYNAM ": fusion_exit() called!\n"));
 
-	pci_unregister_driver(&mptbase_driver);
 	mpt_reset_deregister(mpt_base_index);
 
 #ifdef CONFIG_PROC_FS
@@ -5941,6 +5829,5 @@ fusion_exit(void)
 #endif
 }
 
-
 module_init(fusion_init);
 module_exit(fusion_exit);
diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h
--- a/drivers/message/fusion/mptbase.h
+++ b/drivers/message/fusion/mptbase.h
@@ -5,15 +5,9 @@
  *          LSIFC9xx/LSI409xx Fibre Channel
  *      running LSI Logic Fusion MPT (Message Passing Technology) firmware.
  *
- *  Credits:
- *     (see mptbase.c)
- *
- *  Copyright (c) 1999-2004 LSI Logic Corporation
- *  Originally By: Steven J. Ralston
- *  (mailto:sjralston1@netscape.net)
+ *  Copyright (c) 1999-2005 LSI Logic Corporation
  *  (mailto:mpt_linux_developer@lsil.com)
  *
- *  $Id: mptbase.h,v 1.144 2003/01/28 21:31:56 pdelaney Exp $
  */
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
@@ -71,7 +65,6 @@
 #include "lsi/mpi_fc.h"		/* Fibre Channel (lowlevel) support */
 #include "lsi/mpi_targ.h"	/* SCSI/FCP Target protcol support */
 #include "lsi/mpi_tool.h"	/* Tools support */
-#include "lsi/fc_log.h"
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 
@@ -80,11 +73,11 @@
 #endif
 
 #ifndef COPYRIGHT
-#define COPYRIGHT	"Copyright (c) 1999-2004 " MODULEAUTHOR
+#define COPYRIGHT	"Copyright (c) 1999-2005 " MODULEAUTHOR
 #endif
 
-#define MPT_LINUX_VERSION_COMMON	"3.01.20"
-#define MPT_LINUX_PACKAGE_NAME		"@(#)mptlinux-3.01.20"
+#define MPT_LINUX_VERSION_COMMON	"3.03.02"
+#define MPT_LINUX_PACKAGE_NAME		"@(#)mptlinux-3.03.02"
 #define WHAT_MAGIC_STRING		"@" "(" "#" ")"
 
 #define show_mptmod_ver(s,ver)  \
@@ -203,7 +196,9 @@
 typedef enum {
 	MPTBASE_DRIVER,		/* MPT base class */
 	MPTCTL_DRIVER,		/* MPT ioctl class */
-	MPTSCSIH_DRIVER,	/* MPT SCSI host (initiator) class */
+	MPTSPI_DRIVER,		/* MPT SPI host class */
+	MPTFC_DRIVER,		/* MPT FC host class */
+	MPTSAS_DRIVER,		/* MPT SAS host class */
 	MPTLAN_DRIVER,		/* MPT LAN class */
 	MPTSTM_DRIVER,		/* MPT SCSI target mode class */
 	MPTUNKNOWN_DRIVER
@@ -212,11 +207,6 @@ typedef enum {
 struct mpt_pci_driver{
 	int  (*probe) (struct pci_dev *dev, const struct pci_device_id *id);
 	void (*remove) (struct pci_dev *dev);
-	void (*shutdown) (struct device * dev);
-#ifdef CONFIG_PM
-	int  (*resume) (struct pci_dev *dev);
-	int  (*suspend) (struct pci_dev *dev, pm_message_t state);
-#endif
 };
 
 /*
@@ -483,6 +473,7 @@ typedef	struct _ScsiCfgData {
 	u8		 forceDv;		/* 1 to force DV scheduling */
 	u8		 noQas;			/* Disable QAS for this adapter */
 	u8		 Saf_Te;		/* 1 to force all Processors as SAF-TE if Inquiry data length is too short to check for SAF-TE */
+	u8		 mpt_dv;		/* command line option: enhanced=1, basic=0 */
 	u8		 rsvd[1];
 } ScsiCfgData;
 
@@ -571,11 +562,21 @@ typedef struct _MPT_ADAPTER
 	FCPortPage0_t		 fc_port_page0[2];
 	LANPage0_t		 lan_cnfg_page0;
 	LANPage1_t		 lan_cnfg_page1;
+	/*  
+	 * Description: errata_flag_1064
+	 * If a PCIX read occurs within 1 or 2 cycles after the chip receives
+	 * a split completion for a read data, an internal address pointer incorrectly
+	 * increments by 32 bytes
+	 */
+	int			 errata_flag_1064;	
 	u8			 FirstWhoInit;
 	u8			 upload_fw;	/* If set, do a fw upload */
 	u8			 reload_fw;	/* Force a FW Reload on next reset */
 	u8			 NBShiftFactor;  /* NB Shift Factor based on Block Size (Facts)  */     
 	u8			 pad1[4];
+	int			 DoneCtx;
+	int			 TaskCtx;
+	int			 InternalCtx;
 	struct list_head	 list; 
 	struct net_device	*netdev;
 } MPT_ADAPTER;
@@ -773,12 +774,6 @@ typedef struct _mpt_sge {
 #define DBG_DUMP_TM_REPLY_FRAME(mfp)
 #endif
 
-#ifdef MPT_DEBUG_NEH
-#define nehprintk(x) printk x
-#else
-#define nehprintk(x)
-#endif
-
 #if defined(MPT_DEBUG_CONFIG) || defined(MPT_DEBUG)
 #define dcprintk(x) printk x
 #else
@@ -898,6 +893,11 @@ typedef struct _MPT_SCSI_HOST {
 	unsigned long		  soft_resets;		/* fw/external bus resets count */
 	unsigned long		  timeouts;		/* cmd timeouts */
 	ushort			  sel_timeout[MPT_MAX_FC_DEVICES];
+	char 			  *info_kbuf;
+	wait_queue_head_t	  scandv_waitq;
+	int			  scandv_wait_done;
+	long			  last_queue_full;
+	u8		 	  mpt_pq_filter;
 } MPT_SCSI_HOST;
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -931,6 +931,12 @@ typedef struct _x_config_parms {
 /*
  *  Public entry points...
  */
+extern int	 mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id);
+extern void	 mpt_detach(struct pci_dev *pdev);
+#ifdef CONFIG_PM
+extern int	 mpt_suspend(struct pci_dev *pdev, pm_message_t state);
+extern int	 mpt_resume(struct pci_dev *pdev);
+#endif
 extern int	 mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass);
 extern void	 mpt_deregister(int cb_idx);
 extern int	 mpt_event_register(int cb_idx, MPT_EVHANDLER ev_cbfunc);
diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c
--- a/drivers/message/fusion/mptctl.c
+++ b/drivers/message/fusion/mptctl.c
@@ -1,40 +1,12 @@
 /*
  *  linux/drivers/message/fusion/mptctl.c
- *      Fusion MPT misc device (ioctl) driver.
- *      For use with PCI chip/adapter(s):
- *          LSIFC9xx/LSI409xx Fibre Channel
+ *      mpt Ioctl driver.
+ *      For use with LSI Logic PCI chip/adapters
  *      running LSI Logic Fusion MPT (Message Passing Technology) firmware.
  *
- *  Credits:
- *      This driver would not exist if not for Alan Cox's development
- *      of the linux i2o driver.
- *
- *      A special thanks to Pamela Delaney (LSI Logic) for tons of work
- *      and countless enhancements while adding support for the 1030
- *      chip family.  Pam has been instrumental in the development of
- *      of the 2.xx.xx series fusion drivers, and her contributions are
- *      far too numerous to hope to list in one place.
- *
- *      A huge debt of gratitude is owed to David S. Miller (DaveM)
- *      for fixing much of the stupid and broken stuff in the early
- *      driver while porting to sparc64 platform.  THANK YOU!
- *
- *      A big THANKS to Eddie C. Dost for fixing the ioctl path
- *      and most importantly f/w download on sparc64 platform!
- *      (plus Eddie's other helpful hints and insights)
- *
- *      Thanks to Arnaldo Carvalho de Melo for finding and patching
- *      a potential memory leak in mptctl_do_fw_download(),
- *      and for some kmalloc insight:-)
- *
- *      (see also mptbase.c)
- *
- *  Copyright (c) 1999-2004 LSI Logic Corporation
- *  Originally By: Steven J. Ralston, Noah Romer
- *  (mailto:sjralston1@netscape.net)
+ *  Copyright (c) 1999-2005 LSI Logic Corporation
  *  (mailto:mpt_linux_developer@lsil.com)
  *
- *  $Id: mptctl.c,v 1.63 2002/12/03 21:26:33 pdelaney Exp $
  */
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
@@ -95,8 +67,8 @@
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_tcq.h>
 
-#define COPYRIGHT	"Copyright (c) 1999-2004 LSI Logic Corporation"
-#define MODULEAUTHOR	"Steven J. Ralston, Noah Romer, Pamela Delaney"
+#define COPYRIGHT	"Copyright (c) 1999-2005 LSI Logic Corporation"
+#define MODULEAUTHOR	"LSI Logic Corporation"
 #include "mptbase.h"
 #include "mptctl.h"
 
@@ -127,14 +99,14 @@ struct buflist {
  * arg contents specific to function.
  */
 static int mptctl_fw_download(unsigned long arg);
-static int mptctl_getiocinfo (unsigned long arg, unsigned int cmd);
-static int mptctl_gettargetinfo (unsigned long arg);
-static int mptctl_readtest (unsigned long arg);
-static int mptctl_mpt_command (unsigned long arg);
-static int mptctl_eventquery (unsigned long arg);
-static int mptctl_eventenable (unsigned long arg);
-static int mptctl_eventreport (unsigned long arg);
-static int mptctl_replace_fw (unsigned long arg);
+static int mptctl_getiocinfo(unsigned long arg, unsigned int cmd);
+static int mptctl_gettargetinfo(unsigned long arg);
+static int mptctl_readtest(unsigned long arg);
+static int mptctl_mpt_command(unsigned long arg);
+static int mptctl_eventquery(unsigned long arg);
+static int mptctl_eventenable(unsigned long arg);
+static int mptctl_eventreport(unsigned long arg);
+static int mptctl_replace_fw(unsigned long arg);
 
 static int mptctl_do_reset(unsigned long arg);
 static int mptctl_hp_hostinfo(unsigned long arg, unsigned int cmd);
@@ -149,11 +121,11 @@ static long compat_mpctl_ioctl(struct fi
 /*
  * Private function calls.
  */
-static int mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr);
+static int mptctl_do_mpt_command(struct mpt_ioctl_command karg, void __user *mfPtr);
 static int mptctl_do_fw_download(int ioc, char __user *ufwbuf, size_t fwlen);
-static MptSge_t *kbuf_alloc_2_sgl( int bytes, u32 dir, int sge_offset, int *frags,
+static MptSge_t *kbuf_alloc_2_sgl(int bytes, u32 dir, int sge_offset, int *frags,
 		struct buflist **blp, dma_addr_t *sglbuf_dma, MPT_ADAPTER *ioc);
-static void kfree_sgl( MptSge_t *sgl, dma_addr_t sgl_dma,
+static void kfree_sgl(MptSge_t *sgl, dma_addr_t sgl_dma,
 		struct buflist *buflist, MPT_ADAPTER *ioc);
 static void mptctl_timeout_expired (MPT_IOCTL *ioctl);
 static int  mptctl_bus_reset(MPT_IOCTL *ioctl);
@@ -1119,7 +1091,7 @@ mptctl_getiocinfo (unsigned long arg, un
 	int			numDevices = 0;
 	unsigned int		max_id;
 	int			ii;
-	int			port;
+	unsigned int		port;
 	int			cim_rev;
 	u8			revision;
 
@@ -1162,9 +1134,7 @@ mptctl_getiocinfo (unsigned long arg, un
 		return -ENODEV;
 	}
 
-	/* Verify the data transfer size is correct.
-	 * Ignore the port setting.
-	 */
+	/* Verify the data transfer size is correct. */
 	if (karg->hdr.maxDataSize != data_size) {
 		printk(KERN_ERR "%s@%d::mptctl_getiocinfo - "
 			"Structure size mismatch. Command not completed.\n",
@@ -1181,6 +1151,8 @@ mptctl_getiocinfo (unsigned long arg, un
 	else
 		karg->adapterType = MPT_IOCTL_INTERFACE_SCSI;
 
+	if (karg->hdr.port > 1)
+		return -EINVAL;
 	port = karg->hdr.port;
 
 	karg->port = port;
diff --git a/drivers/message/fusion/mptctl.h b/drivers/message/fusion/mptctl.h
--- a/drivers/message/fusion/mptctl.h
+++ b/drivers/message/fusion/mptctl.h
@@ -5,22 +5,9 @@
  *          LSIFC9xx/LSI409xx Fibre Channel
  *      running LSI Logic Fusion MPT (Message Passing Technology) firmware.
  *
- *  Credits:
- *      This driver would not exist if not for Alan Cox's development
- *      of the linux i2o driver.
- *
- *      A huge debt of gratitude is owed to David S. Miller (DaveM)
- *      for fixing much of the stupid and broken stuff in the early
- *      driver while porting to sparc64 platform.  THANK YOU!
- *
- *      (see also mptbase.c)
- *
- *  Copyright (c) 1999-2004 LSI Logic Corporation
- *  Originally By: Steven J. Ralston
- *  (mailto:sjralston1@netscape.net)
+ *  Copyright (c) 1999-2005 LSI Logic Corporation
  *  (mailto:mpt_linux_developer@lsil.com)
  *
- *  $Id: mptctl.h,v 1.13 2002/12/03 21:26:33 pdelaney Exp $
  */
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c
new file mode 100644
--- /dev/null
+++ b/drivers/message/fusion/mptfc.c
@@ -0,0 +1,412 @@
+/*
+ *  linux/drivers/message/fusion/mptfc.c
+ *      For use with LSI Logic PCI chip/adapter(s)
+ *      running LSI Logic Fusion MPT (Message Passing Technology) firmware.
+ *
+ *  Copyright (c) 1999-2005 LSI Logic Corporation
+ *  (mailto:mpt_linux_developer@lsil.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; version 2 of the License.
+
+    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.
+
+    NO WARRANTY
+    THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
+    CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
+    LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
+    MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
+    solely responsible for determining the appropriateness of using and
+    distributing the Program and assumes all risks associated with its
+    exercise of rights under this Agreement, including but not limited to
+    the risks and costs of program errors, damage to or loss of data,
+    programs or equipment, and unavailability or interruption of operations.
+
+    DISCLAIMER OF LIABILITY
+    NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+    TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+    USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
+    HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
+
+    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_compat.h"	/* linux-2.6 tweaks */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/kdev_t.h>
+#include <linux/blkdev.h>
+#include <linux/delay.h>	/* for mdelay */
+#include <linux/interrupt.h>	/* needed for in_interrupt() proto */
+#include <linux/reboot.h>	/* notifier code */
+#include <linux/sched.h>
+#include <linux/workqueue.h>
+
+#include <scsi/scsi.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_host.h>
+#include <scsi/scsi_tcq.h>
+
+#include "mptbase.h"
+#include "mptscsih.h"
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+#define my_NAME		"Fusion MPT FC Host driver"
+#define my_VERSION	MPT_LINUX_VERSION_COMMON
+#define MYNAM		"mptfc"
+
+MODULE_AUTHOR(MODULEAUTHOR);
+MODULE_DESCRIPTION(my_NAME);
+MODULE_LICENSE("GPL");
+
+/* Command line args */
+static int mpt_pq_filter = 0;
+module_param(mpt_pq_filter, int, 0);
+MODULE_PARM_DESC(mpt_pq_filter, " Enable peripheral qualifier filter: enable=1  (default=0)");
+
+static int	mptfcDoneCtx = -1;
+static int	mptfcTaskCtx = -1;
+static int	mptfcInternalCtx = -1; /* Used only for internal commands */
+
+static struct scsi_host_template mptfc_driver_template = {
+	.proc_name			= "mptfc",
+	.proc_info			= mptscsih_proc_info,
+	.name				= "MPT FC Host",
+	.info				= mptscsih_info,
+	.queuecommand			= mptscsih_qcmd,
+	.slave_alloc			= mptscsih_slave_alloc,
+	.slave_configure		= mptscsih_slave_configure,
+	.slave_destroy			= mptscsih_slave_destroy,
+	.change_queue_depth 		= mptscsih_change_queue_depth,
+	.eh_abort_handler		= mptscsih_abort,
+	.eh_device_reset_handler	= mptscsih_dev_reset,
+	.eh_bus_reset_handler		= mptscsih_bus_reset,
+	.eh_host_reset_handler		= mptscsih_host_reset,
+	.bios_param			= mptscsih_bios_param,
+	.can_queue			= MPT_FC_CAN_QUEUE,
+	.this_id			= -1,
+	.sg_tablesize			= MPT_SCSI_SG_DEPTH,
+	.max_sectors			= 8192,
+	.cmd_per_lun			= 7,
+	.use_clustering			= ENABLE_CLUSTERING,
+};
+
+/****************************************************************************
+ * Supported hardware
+ */
+
+static struct pci_device_id mptfc_pci_table[] = {
+	{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC909,
+		PCI_ANY_ID, PCI_ANY_ID },
+	{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC919,
+		PCI_ANY_ID, PCI_ANY_ID },
+	{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC929,
+		PCI_ANY_ID, PCI_ANY_ID },
+	{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC919X,
+		PCI_ANY_ID, PCI_ANY_ID },
+	{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC929X,
+		PCI_ANY_ID, PCI_ANY_ID },
+	{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC939X,
+		PCI_ANY_ID, PCI_ANY_ID },
+	{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC949X,
+		PCI_ANY_ID, PCI_ANY_ID },
+	{0}	/* Terminating entry */
+};
+MODULE_DEVICE_TABLE(pci, mptfc_pci_table);
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*
+ *	mptfc_probe - Installs scsi devices per bus.
+ *	@pdev: Pointer to pci_dev structure
+ *
+ *	Returns 0 for success, non-zero for failure.
+ *
+ */
+static int
+mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+{
+	struct Scsi_Host	*sh;
+	MPT_SCSI_HOST		*hd;
+	MPT_ADAPTER 		*ioc;
+	unsigned long		 flags;
+	int			 sz, ii;
+	int			 numSGE = 0;
+	int			 scale;
+	int			 ioc_cap;
+	u8			*mem;
+	int			error=0;
+	int			r;
+		
+	if ((r = mpt_attach(pdev,id)) != 0)
+		return r;
+	
+	ioc = pci_get_drvdata(pdev);
+	ioc->DoneCtx = mptfcDoneCtx;
+	ioc->TaskCtx = mptfcTaskCtx;
+	ioc->InternalCtx = mptfcInternalCtx;
+
+	/*  Added sanity check on readiness of the MPT adapter.
+	 */
+	if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
+		printk(MYIOC_s_WARN_FMT
+		  "Skipping because it's not operational!\n",
+		  ioc->name);
+		return -ENODEV;
+	}
+
+	if (!ioc->active) {
+		printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
+		  ioc->name);
+		return -ENODEV;
+	}
+
+	/*  Sanity check - ensure at least 1 port is INITIATOR capable
+	 */
+	ioc_cap = 0;
+	for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
+		if (ioc->pfacts[ii].ProtocolFlags &
+		    MPI_PORTFACTS_PROTOCOL_INITIATOR)
+			ioc_cap ++;
+	}
+
+	if (!ioc_cap) {
+		printk(MYIOC_s_WARN_FMT
+			"Skipping ioc=%p because SCSI Initiator mode is NOT enabled!\n",
+			ioc->name, ioc);
+		return -ENODEV;
+	}
+
+	sh = scsi_host_alloc(&mptfc_driver_template, sizeof(MPT_SCSI_HOST));
+
+	if (!sh) {
+		printk(MYIOC_s_WARN_FMT
+			"Unable to register controller with SCSI subsystem\n",
+			ioc->name);
+                return -1;
+        }
+
+	spin_lock_irqsave(&ioc->FreeQlock, flags);
+
+	/* Attach the SCSI Host to the IOC structure
+	 */
+	ioc->sh = sh;
+
+	sh->io_port = 0;
+	sh->n_io_port = 0;
+	sh->irq = 0;
+
+	/* set 16 byte cdb's */
+	sh->max_cmd_len = 16;
+
+	sh->max_id = MPT_MAX_FC_DEVICES<256 ? MPT_MAX_FC_DEVICES : 255;
+
+	sh->max_lun = MPT_LAST_LUN + 1;
+	sh->max_channel = 0;
+	sh->this_id = ioc->pfacts[0].PortSCSIID;
+
+	/* Required entry.
+	 */
+	sh->unique_id = ioc->id;
+
+	/* Verify that we won't exceed the maximum
+	 * number of chain buffers
+	 * We can optimize:  ZZ = req_sz/sizeof(SGE)
+	 * For 32bit SGE's:
+	 *  numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
+	 *               + (req_sz - 64)/sizeof(SGE)
+	 * A slightly different algorithm is required for
+	 * 64bit SGEs.
+	 */
+	scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
+	if (sizeof(dma_addr_t) == sizeof(u64)) {
+		numSGE = (scale - 1) *
+		  (ioc->facts.MaxChainDepth-1) + scale +
+		  (ioc->req_sz - 60) / (sizeof(dma_addr_t) +
+		  sizeof(u32));
+	} else {
+		numSGE = 1 + (scale - 1) *
+		  (ioc->facts.MaxChainDepth-1) + scale +
+		  (ioc->req_sz - 64) / (sizeof(dma_addr_t) +
+		  sizeof(u32));
+	}
+
+	if (numSGE < sh->sg_tablesize) {
+		/* Reset this value */
+		dprintk((MYIOC_s_INFO_FMT
+		  "Resetting sg_tablesize to %d from %d\n",
+		  ioc->name, numSGE, sh->sg_tablesize));
+		sh->sg_tablesize = numSGE;
+	}
+
+	spin_unlock_irqrestore(&ioc->FreeQlock, flags);
+
+	hd = (MPT_SCSI_HOST *) sh->hostdata;
+	hd->ioc = ioc;
+
+	/* SCSI needs scsi_cmnd lookup table!
+	 * (with size equal to req_depth*PtrSz!)
+	 */
+	sz = ioc->req_depth * sizeof(void *);
+	mem = kmalloc(sz, GFP_ATOMIC);
+	if (mem == NULL) {
+		error = -ENOMEM;
+		goto mptfc_probe_failed;
+	}
+
+	memset(mem, 0, sz);
+	hd->ScsiLookup = (struct scsi_cmnd **) mem;
+
+	dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p, sz=%d\n",
+		 ioc->name, hd->ScsiLookup, sz));
+
+	/* Allocate memory for the device structures.
+	 * A non-Null pointer at an offset
+	 * indicates a device exists.
+	 * max_id = 1 + maximum id (hosts.h)
+	 */
+	sz = sh->max_id * sizeof(void *);
+	mem = kmalloc(sz, GFP_ATOMIC);
+	if (mem == NULL) {
+		error = -ENOMEM;
+		goto mptfc_probe_failed;
+	}
+
+	memset(mem, 0, sz);
+	hd->Targets = (VirtDevice **) mem;
+
+	dprintk((KERN_INFO
+	  "  Targets @ %p, sz=%d\n", hd->Targets, sz));
+
+	/* Clear the TM flags
+	 */
+	hd->tmPending = 0;
+	hd->tmState = TM_STATE_NONE;
+	hd->resetPending = 0;
+	hd->abortSCpnt = NULL;
+
+	/* Clear the pointer used to store
+	 * single-threaded commands, i.e., those
+	 * issued during a bus scan, dv and
+	 * configuration pages.
+	 */
+	hd->cmdPtr = NULL;
+
+	/* Initialize this SCSI Hosts' timers
+	 * To use, set the timer expires field
+	 * and add_timer
+	 */
+	init_timer(&hd->timer);
+	hd->timer.data = (unsigned long) hd;
+	hd->timer.function = mptscsih_timer_expired;
+
+	hd->mpt_pq_filter = mpt_pq_filter;
+
+	ddvprintk((MYIOC_s_INFO_FMT
+		"mpt_pq_filter %x\n",
+		ioc->name, 
+		mpt_pq_filter));
+
+	init_waitqueue_head(&hd->scandv_waitq);
+	hd->scandv_wait_done = 0;
+	hd->last_queue_full = 0;
+
+	error = scsi_add_host (sh, &ioc->pcidev->dev);
+	if(error) {
+		dprintk((KERN_ERR MYNAM
+		  "scsi_add_host failed\n"));
+		goto mptfc_probe_failed;
+	}
+
+	scsi_scan_host(sh);
+	return 0;
+
+mptfc_probe_failed:
+
+	mptscsih_remove(pdev);
+	return error;
+}
+
+static struct pci_driver mptfc_driver = {
+	.name		= "mptfc",
+	.id_table	= mptfc_pci_table,
+	.probe		= mptfc_probe,
+	.remove		= __devexit_p(mptscsih_remove),
+	.shutdown	= mptscsih_shutdown,
+#ifdef CONFIG_PM
+	.suspend	= mptscsih_suspend,
+	.resume		= mptscsih_resume,
+#endif
+};
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/**
+ *	mptfc_init - Register MPT adapter(s) as SCSI host(s) with
+ *	linux scsi mid-layer.
+ *
+ *	Returns 0 for success, non-zero for failure.
+ */
+static int __init
+mptfc_init(void)
+{
+
+	show_mptmod_ver(my_NAME, my_VERSION);
+
+	mptfcDoneCtx = mpt_register(mptscsih_io_done, MPTFC_DRIVER);
+	mptfcTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTFC_DRIVER);
+	mptfcInternalCtx = mpt_register(mptscsih_scandv_complete, MPTFC_DRIVER);
+
+	if (mpt_event_register(mptfcDoneCtx, mptscsih_event_process) == 0) {
+		devtprintk((KERN_INFO MYNAM
+		  ": Registered for IOC event notifications\n"));
+	}
+
+	if (mpt_reset_register(mptfcDoneCtx, mptscsih_ioc_reset) == 0) {
+		dprintk((KERN_INFO MYNAM
+		  ": Registered for IOC reset notifications\n"));
+	}
+
+	return pci_register_driver(&mptfc_driver);
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/**
+ *	mptfc_exit - Unregisters MPT adapter(s)
+ *
+ */
+static void __exit
+mptfc_exit(void)
+{
+	pci_unregister_driver(&mptfc_driver);
+	
+	mpt_reset_deregister(mptfcDoneCtx);
+	dprintk((KERN_INFO MYNAM
+	  ": Deregistered for IOC reset notifications\n"));
+
+	mpt_event_deregister(mptfcDoneCtx);
+	dprintk((KERN_INFO MYNAM
+	  ": Deregistered for IOC event notifications\n"));
+
+	mpt_deregister(mptfcInternalCtx);
+	mpt_deregister(mptfcTaskCtx);
+	mpt_deregister(mptfcDoneCtx);
+}
+
+module_init(mptfc_init);
+module_exit(mptfc_exit);
diff --git a/drivers/message/fusion/mptlan.c b/drivers/message/fusion/mptlan.c
--- a/drivers/message/fusion/mptlan.c
+++ b/drivers/message/fusion/mptlan.c
@@ -1,33 +1,11 @@
 /*
  *  linux/drivers/message/fusion/mptlan.c
  *      IP Over Fibre Channel device driver.
- *      For use with PCI chip/adapter(s):
- *          LSIFC9xx/LSI409xx Fibre Channel
+ *      For use with LSI Logic Fibre Channel PCI chip/adapters
  *      running LSI Logic Fusion MPT (Message Passing Technology) firmware.
  *
- *  Credits:
- *      This driver would not exist if not for Alan Cox's development
- *      of the linux i2o driver.
+ *  Copyright (c) 2000-2005 LSI Logic Corporation
  *
- *      Special thanks goes to the I2O LAN driver people at the
- *      University of Helsinki, who, unbeknownst to them, provided
- *      the inspiration and initial structure for this driver.
- *
- *      A huge debt of gratitude is owed to David S. Miller (DaveM)
- *      for fixing much of the stupid and broken stuff in the early
- *      driver while porting to sparc64 platform.  THANK YOU!
- *
- *      A really huge debt of gratitude is owed to Eddie C. Dost
- *      for gobs of hard work fixing and optimizing LAN code.
- *      THANK YOU!
- *
- *      (see also mptbase.c)
- *
- *  Copyright (c) 2000-2004 LSI Logic Corporation
- *  Originally By: Noah Romer
- *  (mailto:mpt_linux_developer@lsil.com)
- *
- *  $Id: mptlan.c,v 1.53 2002/10/17 20:15:58 pdelaney Exp $
  */
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
@@ -221,7 +199,7 @@ lan_reply (MPT_ADAPTER *ioc, MPT_FRAME_H
 
 		// NOTE!  (Optimization) First case here is now caught in
 		//  mptbase.c::mpt_interrupt() routine and callcack here
-		//  is now skipped for this case!  20001218 -sralston
+		//  is now skipped for this case!
 #if 0
 		case LAN_REPLY_FORM_MESSAGE_CONTEXT:
 //			dioprintk((KERN_INFO MYNAM "/lan_reply: "
@@ -234,7 +212,7 @@ lan_reply (MPT_ADAPTER *ioc, MPT_FRAME_H
 //			dioprintk((MYNAM "/lan_reply: "
 //				  "calling mpt_lan_send_reply (turbo)\n"));
 
-			// Potential BUG here?  -sralston
+			// Potential BUG here?
 			//	FreeReqFrame = mpt_lan_send_turbo(dev, tmsg);
 			//  If/when mpt_lan_send_turbo would return 1 here,
 			//  calling routine (mptbase.c|mpt_interrupt)
@@ -310,8 +288,7 @@ lan_reply (MPT_ADAPTER *ioc, MPT_FRAME_H
 
 	case MPI_FUNCTION_EVENT_NOTIFICATION:
 	case MPI_FUNCTION_EVENT_ACK:
-		/* UPDATE!  20010120 -sralston
-		 *  _EVENT_NOTIFICATION should NOT come down this path any more.
+		/*  _EVENT_NOTIFICATION should NOT come down this path any more.
 		 *  Should be routed to mpt_lan_event_process(), but just in case...
 		 */
 		FreeReqFrame = 1;
@@ -561,8 +538,8 @@ mpt_lan_close(struct net_device *dev)
 		}
 	}
 
-	kfree (priv->RcvCtl);
-	kfree (priv->mpt_rxfidx);
+	kfree(priv->RcvCtl);
+	kfree(priv->mpt_rxfidx);
 
 	for (i = 0; i < priv->tx_max_out; i++) {
 		if (priv->SendCtl[i].skb != NULL) {
diff --git a/drivers/message/fusion/mptlan.h b/drivers/message/fusion/mptlan.h
--- a/drivers/message/fusion/mptlan.h
+++ b/drivers/message/fusion/mptlan.h
@@ -1,3 +1,49 @@
+/*
+ *  linux/drivers/message/fusion/mptlan.h
+ *      IP Over Fibre Channel device driver.
+ *      For use with LSI Logic Fibre Channel PCI chip/adapters
+ *      running LSI Logic Fusion MPT (Message Passing Technology) firmware.
+ *
+ *  Copyright (c) 2000-2005 LSI Logic Corporation
+ *
+ */
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; version 2 of the License.
+
+    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.
+
+    NO WARRANTY
+    THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
+    CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
+    LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
+    MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
+    solely responsible for determining the appropriateness of using and
+    distributing the Program and assumes all risks associated with its
+    exercise of rights under this Agreement, including but not limited to
+    the risks and costs of program errors, damage to or loss of data,
+    programs or equipment, and unavailability or interruption of operations.
+
+    DISCLAIMER OF LIABILITY
+    NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+    TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+    USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
+    HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
+
+    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
+*/
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+
 /* mptlan.h */
 
 #ifndef LINUX_MPTLAN_H_INCLUDED
@@ -29,7 +75,7 @@
 #include <asm/io.h>
 
     /* Override mptbase.h by pre-defining these! */
-    #define MODULEAUTHOR "Noah Romer, Eddie C. Dost"
+#define MODULEAUTHOR	"LSI Logic Corporation"
 
 #include "mptbase.h"
 
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c
--- a/drivers/message/fusion/mptscsih.c
+++ b/drivers/message/fusion/mptscsih.c
@@ -1,32 +1,11 @@
 /*
  *  linux/drivers/message/fusion/mptscsih.c
- *      High performance SCSI / Fibre Channel SCSI Host device driver.
- *      For use with PCI chip/adapter(s):
- *          LSIFC9xx/LSI409xx Fibre Channel
+ *      For use with LSI Logic PCI chip/adapter(s)
  *      running LSI Logic Fusion MPT (Message Passing Technology) firmware.
  *
- *  Credits:
- *      This driver would not exist if not for Alan Cox's development
- *      of the linux i2o driver.
- *
- *      A special thanks to Pamela Delaney (LSI Logic) for tons of work
- *      and countless enhancements while adding support for the 1030
- *      chip family.  Pam has been instrumental in the development of
- *      of the 2.xx.xx series fusion drivers, and her contributions are
- *      far too numerous to hope to list in one place.
- *
- *      A huge debt of gratitude is owed to David S. Miller (DaveM)
- *      for fixing much of the stupid and broken stuff in the early
- *      driver while porting to sparc64 platform.  THANK YOU!
- *
- *      (see mptbase.c)
- *
- *  Copyright (c) 1999-2004 LSI Logic Corporation
- *  Original author: Steven J. Ralston
- *  (mailto:sjralston1@netscape.net)
+ *  Copyright (c) 1999-2005 LSI Logic Corporation
  *  (mailto:mpt_linux_developer@lsil.com)
  *
- *  $Id: mptscsih.c,v 1.104 2002/12/03 21:26:34 pdelaney Exp $
  */
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
@@ -96,27 +75,6 @@ MODULE_AUTHOR(MODULEAUTHOR);
 MODULE_DESCRIPTION(my_NAME);
 MODULE_LICENSE("GPL");
 
-/* Command line args */
-static int mpt_dv = MPTSCSIH_DOMAIN_VALIDATION;
-MODULE_PARM(mpt_dv, "i");
-MODULE_PARM_DESC(mpt_dv, " DV Algorithm: enhanced=1, basic=0 (default=MPTSCSIH_DOMAIN_VALIDATION=1)");
-
-static int mpt_width = MPTSCSIH_MAX_WIDTH;
-MODULE_PARM(mpt_width, "i");
-MODULE_PARM_DESC(mpt_width, " Max Bus Width: wide=1, narrow=0 (default=MPTSCSIH_MAX_WIDTH=1)");
-
-static int mpt_factor = MPTSCSIH_MIN_SYNC;
-MODULE_PARM(mpt_factor, "h");
-MODULE_PARM_DESC(mpt_factor, " Min Sync Factor (default=MPTSCSIH_MIN_SYNC=0x08)");
-
-static int mpt_saf_te = MPTSCSIH_SAF_TE;
-MODULE_PARM(mpt_saf_te, "i");
-MODULE_PARM_DESC(mpt_saf_te, " Force enabling SEP Processor: enable=1  (default=MPTSCSIH_SAF_TE=0)");
-
-static int mpt_pq_filter = 0;
-MODULE_PARM(mpt_pq_filter, "i");
-MODULE_PARM_DESC(mpt_pq_filter, " Enable peripheral qualifier filter: enable=1  (default=0)");
-
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 
 typedef struct _BIG_SENSE_BUF {
@@ -169,18 +127,17 @@ typedef struct _dv_parameters {
 	u16		 pad1;
 } DVPARAMETERS;
 
-
 /*
  *  Other private/forward protos...
  */
-static int	mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
+int		mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
 static void	mptscsih_report_queue_full(struct scsi_cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq);
-static int	mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
+int		mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
 
 static int	mptscsih_AddSGE(MPT_ADAPTER *ioc, struct scsi_cmnd *SCpnt,
 				 SCSIIORequest_t *pReq, int req_idx);
 static void	mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx);
-static void	copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply);
+static void	mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply);
 static int	mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd);
 static int	mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout );
 static u32	SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc);
@@ -188,8 +145,8 @@ static u32	SCPNT_TO_LOOKUP_IDX(struct sc
 static int	mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout);
 static int	mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout);
 
-static int	mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset);
-static int	mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
+int		mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset);
+int		mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
 
 static void	mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char *data, int dlen);
 static void	mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byte56);
@@ -198,8 +155,7 @@ static void	mptscsih_setDevicePage1Flags
 static void	mptscsih_no_negotiate(MPT_SCSI_HOST *hd, int target_id);
 static int	mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target, int flags);
 static int	mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus);
-static int	mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
-static void	mptscsih_timer_expired(unsigned long data);
+int		mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
 static int	mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd);
 static int	mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum);
 
@@ -212,29 +168,14 @@ static int	mptscsih_doDv(MPT_SCSI_HOST *
 static void	mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage);
 static void	mptscsih_fillbuf(char *buffer, int size, int index, int width);
 #endif
-/* module entry point */
-static int  __init   mptscsih_init  (void);
-static void __exit   mptscsih_exit  (void);
-
-static int  mptscsih_probe (struct pci_dev *, const struct pci_device_id *);
-static void mptscsih_remove(struct pci_dev *);
-static void mptscsih_shutdown(struct device *);
+
+void 		mptscsih_remove(struct pci_dev *);
+void 		mptscsih_shutdown(struct pci_dev *);
 #ifdef CONFIG_PM
-static int mptscsih_suspend(struct pci_dev *pdev, pm_message_t state);
-static int mptscsih_resume(struct pci_dev *pdev);
+int 		mptscsih_suspend(struct pci_dev *pdev, pm_message_t state);
+int 		mptscsih_resume(struct pci_dev *pdev);
 #endif
 
-
-/*
- *	Private data...
- */
-
-static int	mpt_scsi_hosts = 0;
-
-static int	ScsiDoneCtx = -1;
-static int	ScsiTaskCtx = -1;
-static int	ScsiScanDvCtx = -1; /* Used only for bus scan and dv */
-
 #define SNS_LEN(scp)	sizeof((scp)->sense_buffer)
 
 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
@@ -244,20 +185,9 @@ static int	ScsiScanDvCtx = -1; /* Used o
 static DEFINE_SPINLOCK(dvtaskQ_lock);
 static int dvtaskQ_active = 0;
 static int dvtaskQ_release = 0;
-static struct work_struct	mptscsih_dvTask;
+static struct work_struct	dvTaskQ_task;
 #endif
 
-/*
- * Wait Queue setup
- */
-static DECLARE_WAIT_QUEUE_HEAD (scandv_waitq);
-static int scandv_wait_done = 1;
-
-
-/* Driver command line structure
- */
-static struct scsi_host_template driver_template;
-
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /**
  *	mptscsih_add_sge - Place a simple SGE at address pAddr.
@@ -619,7 +549,7 @@ nextSGEset:
  *
  *	Returns 1 indicating alloc'd request frame ptr should be freed.
  */
-static int
+int
 mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
 {
 	struct scsi_cmnd	*sc;
@@ -677,8 +607,8 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_F
 			sc->request_bufflen, xfer_cnt));
 
 		if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID)
-			copy_sense_data(sc, hd, mf, pScsiReply);
-                
+			mptscsih_copy_sense_data(sc, hd, mf, pScsiReply);
+
 		/*
 		 *  Look for + dump FCP ResponseInfo[]!
 		 */
@@ -740,7 +670,7 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_F
 			}
 			dreplyprintk((KERN_NOTICE "RESIDUAL_MISMATCH: result=%x on id=%d\n", sc->result, sc->target));
 			break;
-		
+
 		case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN:		/* 0x0045 */
 			/*
 			 *  Do upfront check for valid SenseData and give it
@@ -773,7 +703,7 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_F
 			 */
 			if (scsi_status == MPI_SCSI_STATUS_TASK_SET_FULL)
 				mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
-			
+
 			break;
 
 		case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR:	/* 0x0040 */
@@ -905,18 +835,16 @@ mptscsih_flush_running_cmds(MPT_SCSI_HOS
 			 * Do OS callback
 			 * Free driver resources (chain, msg buffers)
 			 */
-			if (scsi_device_online(SCpnt->device)) {
-				if (SCpnt->use_sg) {
-					pci_unmap_sg(ioc->pcidev,
-						(struct scatterlist *) SCpnt->request_buffer,
-						SCpnt->use_sg,
-						SCpnt->sc_data_direction);
-				} else if (SCpnt->request_bufflen) {
-					pci_unmap_single(ioc->pcidev,
-						SCpnt->SCp.dma_handle,
-						SCpnt->request_bufflen,
-						SCpnt->sc_data_direction);
-				}
+			if (SCpnt->use_sg) {
+				pci_unmap_sg(ioc->pcidev,
+					(struct scatterlist *) SCpnt->request_buffer,
+					SCpnt->use_sg,
+					SCpnt->sc_data_direction);
+			} else if (SCpnt->request_bufflen) {
+				pci_unmap_single(ioc->pcidev,
+					SCpnt->SCp.dma_handle,
+					SCpnt->request_bufflen,
+					SCpnt->sc_data_direction);
 			}
 			SCpnt->result = DID_RESET << 16;
 			SCpnt->host_scribble = NULL;
@@ -981,11 +909,6 @@ mptscsih_search_running_cmds(MPT_SCSI_HO
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
- *  Hack! It might be nice to report if a device is returning QUEUE_FULL
- *  but maybe not each and every time...
- */
-static long last_queue_full = 0;
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
@@ -1003,280 +926,20 @@ static void
 mptscsih_report_queue_full(struct scsi_cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq)
 {
 	long time = jiffies;
-
-	if (time - last_queue_full > 10 * HZ) {
-		char *ioc_str = "ioc?";
-
-		if (sc->device && sc->device->host != NULL && sc->device->host->hostdata != NULL)
-			ioc_str = ((MPT_SCSI_HOST *)sc->device->host->hostdata)->ioc->name;
-		dprintk((MYIOC_s_WARN_FMT "Device (%d:%d:%d) reported QUEUE_FULL!\n",
-				ioc_str, 0, sc->device->id, sc->device->lun));
-		last_queue_full = time;
-	}
-}
-
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-static char *info_kbuf = NULL;
-
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
- *	mptscsih_probe - Installs scsi devices per bus.
- *	@pdev: Pointer to pci_dev structure
- *
- *	Returns 0 for success, non-zero for failure.
- *
- */
-
-static int
-mptscsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
-{
-	struct Scsi_Host	*sh;
 	MPT_SCSI_HOST		*hd;
-	MPT_ADAPTER 		*ioc = pci_get_drvdata(pdev);
-	unsigned long		 flags;
-	int			 sz, ii;
-	int			 numSGE = 0;
-	int			 scale;
-	int			 ioc_cap;
-	u8			*mem;
-	int			error=0;
-
-
-	/* 20010202 -sralston
-	 *  Added sanity check on readiness of the MPT adapter.
-	 */
-	if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
-		printk(MYIOC_s_WARN_FMT
-		  "Skipping because it's not operational!\n",
-		  ioc->name);
-		return -ENODEV;
-	}
-
-	if (!ioc->active) {
-		printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
-		  ioc->name);
-		return -ENODEV;
-	}
-
-	/*  Sanity check - ensure at least 1 port is INITIATOR capable
-	 */
-	ioc_cap = 0;
-	for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
-		if (ioc->pfacts[ii].ProtocolFlags &
-		    MPI_PORTFACTS_PROTOCOL_INITIATOR)
-			ioc_cap ++;
-	}
-
-	if (!ioc_cap) {
-		printk(MYIOC_s_WARN_FMT
-			"Skipping ioc=%p because SCSI Initiator mode is NOT enabled!\n",
-			ioc->name, ioc);
-		return -ENODEV;
-	}
-
-	sh = scsi_host_alloc(&driver_template, sizeof(MPT_SCSI_HOST));
-        
-	if (!sh) {
-		printk(MYIOC_s_WARN_FMT
-			"Unable to register controller with SCSI subsystem\n",
-			ioc->name);
-                return -1;
-        }
-	
-	spin_lock_irqsave(&ioc->FreeQlock, flags);
-
-	/* Attach the SCSI Host to the IOC structure
-	 */
-	ioc->sh = sh;
-
-	sh->io_port = 0;
-	sh->n_io_port = 0;
-	sh->irq = 0;
-
-	/* set 16 byte cdb's */
-	sh->max_cmd_len = 16;
-
-	/* Yikes!  This is important!
-	 * Otherwise, by default, linux
-	 * only scans target IDs 0-7!
-	 * pfactsN->MaxDevices unreliable
-	 * (not supported in early
-	 *	versions of the FW).
-	 * max_id = 1 + actual max id,
-	 * max_lun = 1 + actual last lun,
-	 *	see hosts.h :o(
-	 */
-	if (ioc->bus_type == SCSI) {
-		sh->max_id = MPT_MAX_SCSI_DEVICES;
-	} else {
-	/* For FC, increase the queue depth
-	 * from MPT_SCSI_CAN_QUEUE (31)
-	 * to MPT_FC_CAN_QUEUE (63).
-	 */
-		sh->can_queue = MPT_FC_CAN_QUEUE;
-		sh->max_id =
-		  MPT_MAX_FC_DEVICES<256 ? MPT_MAX_FC_DEVICES : 255;
-	}
-		
-	sh->max_lun = MPT_LAST_LUN + 1;
-	sh->max_channel = 0;
-	sh->this_id = ioc->pfacts[0].PortSCSIID;
-		
-	/* Required entry.
-	 */
-	sh->unique_id = ioc->id;
-
-	/* Verify that we won't exceed the maximum
-	 * number of chain buffers
-	 * We can optimize:  ZZ = req_sz/sizeof(SGE)
-	 * For 32bit SGE's:
-	 *  numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
-	 *               + (req_sz - 64)/sizeof(SGE)
-	 * A slightly different algorithm is required for
-	 * 64bit SGEs.
-	 */
-	scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
-	if (sizeof(dma_addr_t) == sizeof(u64)) {
-		numSGE = (scale - 1) *
-		  (ioc->facts.MaxChainDepth-1) + scale +
-		  (ioc->req_sz - 60) / (sizeof(dma_addr_t) +
-		  sizeof(u32));
-	} else {
-		numSGE = 1 + (scale - 1) *
-		  (ioc->facts.MaxChainDepth-1) + scale +
-		  (ioc->req_sz - 64) / (sizeof(dma_addr_t) +
-		  sizeof(u32));
-	}
-		
-	if (numSGE < sh->sg_tablesize) {
-		/* Reset this value */
-		dprintk((MYIOC_s_INFO_FMT
-		  "Resetting sg_tablesize to %d from %d\n",
-		  ioc->name, numSGE, sh->sg_tablesize));
-		sh->sg_tablesize = numSGE;
-	}
-
-	/* Set the pci device pointer in Scsi_Host structure.
-	 */
-	scsi_set_device(sh, &ioc->pcidev->dev);
-
-	spin_unlock_irqrestore(&ioc->FreeQlock, flags);
-
-	hd = (MPT_SCSI_HOST *) sh->hostdata;
-	hd->ioc = ioc;
-
-	/* SCSI needs scsi_cmnd lookup table!
-	 * (with size equal to req_depth*PtrSz!)
-	 */
-	sz = ioc->req_depth * sizeof(void *);
-	mem = kmalloc(sz, GFP_ATOMIC);
-	if (mem == NULL) {
-		error = -ENOMEM;
-		goto mptscsih_probe_failed;
-	}
-
-	memset(mem, 0, sz);
-	hd->ScsiLookup = (struct scsi_cmnd **) mem;
-
-	dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p, sz=%d\n",
-		 ioc->name, hd->ScsiLookup, sz));
-		
-	/* Allocate memory for the device structures.
-	 * A non-Null pointer at an offset
-	 * indicates a device exists.
-	 * max_id = 1 + maximum id (hosts.h)
-	 */
-	sz = sh->max_id * sizeof(void *);
-	mem = kmalloc(sz, GFP_ATOMIC);
-	if (mem == NULL) {
-		error = -ENOMEM;
-		goto mptscsih_probe_failed;
-	}
-
-	memset(mem, 0, sz);
-	hd->Targets = (VirtDevice **) mem;
-
-	dprintk((KERN_INFO
-	  "  Targets @ %p, sz=%d\n", hd->Targets, sz));
-
-	/* Clear the TM flags
-	 */
-	hd->tmPending = 0;
-	hd->tmState = TM_STATE_NONE;
-	hd->resetPending = 0;
-	hd->abortSCpnt = NULL;
 
-	/* Clear the pointer used to store
-	 * single-threaded commands, i.e., those
-	 * issued during a bus scan, dv and
-	 * configuration pages.
-	 */
-	hd->cmdPtr = NULL;
-
-	/* Initialize this SCSI Hosts' timers
-	 * To use, set the timer expires field
-	 * and add_timer
-	 */
-	init_timer(&hd->timer);
-	hd->timer.data = (unsigned long) hd;
-	hd->timer.function = mptscsih_timer_expired;
-
-	if (ioc->bus_type == SCSI) {
-		/* Update with the driver setup
-		 * values.
-		 */
-		if (ioc->spi_data.maxBusWidth > mpt_width)
-			ioc->spi_data.maxBusWidth = mpt_width;
-		if (ioc->spi_data.minSyncFactor < mpt_factor)
-			ioc->spi_data.minSyncFactor = mpt_factor;
-
-		if (ioc->spi_data.minSyncFactor == MPT_ASYNC) {
-			ioc->spi_data.maxSyncOffset = 0;
-		}
-
-		ioc->spi_data.Saf_Te = mpt_saf_te;
-
-		hd->negoNvram = 0;
-#ifndef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
-		hd->negoNvram = MPT_SCSICFG_USE_NVRAM;
-#endif
-		ioc->spi_data.forceDv = 0;
-		ioc->spi_data.noQas = 0;
-		for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
-			ioc->spi_data.dvStatus[ii] =
-			  MPT_SCSICFG_NEGOTIATE;
-		}
-
-		for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++)
-			ioc->spi_data.dvStatus[ii] |=
-			  MPT_SCSICFG_DV_NOT_DONE;
-
-		dinitprintk((MYIOC_s_INFO_FMT
-			"dv %x width %x factor %x saf_te %x\n",
-			ioc->name, mpt_dv,
-			mpt_width,
-			mpt_factor,
-			mpt_saf_te));
-	}
-
-	mpt_scsi_hosts++;
+	if (sc->device == NULL)
+		return;
+	if (sc->device->host == NULL)
+		return;
+	if ((hd = (MPT_SCSI_HOST *)sc->device->host->hostdata) == NULL)
+		return;
 
-	error = scsi_add_host (sh, &ioc->pcidev->dev);
-	if(error) {
-		dprintk((KERN_ERR MYNAM
-		  "scsi_add_host failed\n"));
-		goto mptscsih_probe_failed;
+	if (time - hd->last_queue_full > 10 * HZ) {
+		dprintk((MYIOC_s_WARN_FMT "Device (%d:%d:%d) reported QUEUE_FULL!\n",
+				hd->ioc->name, 0, sc->device->id, sc->device->lun));
+		hd->last_queue_full = time;
 	}
-
-	scsi_scan_host(sh);
-	return 0;
-
-mptscsih_probe_failed:
-
-	mptscsih_remove(pdev);
-	return error;
-
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -1286,7 +949,7 @@ mptscsih_probe_failed:
  *
  *
  */
-static void
+void
 mptscsih_remove(struct pci_dev *pdev)
 {
 	MPT_ADAPTER 		*ioc = pci_get_drvdata(pdev);
@@ -1294,12 +957,16 @@ mptscsih_remove(struct pci_dev *pdev)
 	MPT_SCSI_HOST		*hd;
 	int 		 	count;
 	unsigned long	 	flags;
+	int sz1;
 
 	if(!host)
 		return;
 
 	scsi_remove_host(host);
 
+	if((hd = (MPT_SCSI_HOST *)host->hostdata) == NULL)
+		return;
+
 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
 	/* Check DV thread active */
 	count = 10 * HZ;
@@ -1321,40 +988,36 @@ mptscsih_remove(struct pci_dev *pdev)
 #endif
 #endif
 
-	hd = (MPT_SCSI_HOST *)host->hostdata;
-	if (hd != NULL) {
-		int sz1;
+	mptscsih_shutdown(pdev);
 
-		mptscsih_shutdown(&pdev->dev);
+	sz1=0;
 
-		sz1=0;
+	if (hd->ScsiLookup != NULL) {
+		sz1 = hd->ioc->req_depth * sizeof(void *);
+		kfree(hd->ScsiLookup);
+		hd->ScsiLookup = NULL;
+	}
 
-		if (hd->ScsiLookup != NULL) {
-			sz1 = hd->ioc->req_depth * sizeof(void *);
-			kfree(hd->ScsiLookup);
-			hd->ScsiLookup = NULL;
-		}
+	/*
+	 * Free pointer array.
+	 */
+	kfree(hd->Targets);
+	hd->Targets = NULL;
 
-		if (hd->Targets != NULL) {
-			/*
-			 * Free pointer array.
-			 */
-			kfree(hd->Targets);
-			hd->Targets = NULL;
-		}
+	dprintk((MYIOC_s_INFO_FMT
+	    "Free'd ScsiLookup (%d) memory\n",
+	    hd->ioc->name, sz1));
 
-		dprintk((MYIOC_s_INFO_FMT 
-		    "Free'd ScsiLookup (%d) memory\n",
-		    hd->ioc->name, sz1));
+	kfree(hd->info_kbuf);
 
-		/* NULL the Scsi_Host pointer
-		 */
-		hd->ioc->sh = NULL;
-	}
+	/* NULL the Scsi_Host pointer
+	 */
+	hd->ioc->sh = NULL;
 
 	scsi_host_put(host);
-	mpt_scsi_hosts--;
 
+	mpt_detach(pdev);
+	
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -1362,10 +1025,10 @@ mptscsih_remove(struct pci_dev *pdev)
  *	mptscsih_shutdown - reboot notifier
  *
  */
-static void
-mptscsih_shutdown(struct device * dev)
+void
+mptscsih_shutdown(struct pci_dev *pdev)
 {
-	MPT_ADAPTER 		*ioc = pci_get_drvdata(to_pci_dev(dev));
+	MPT_ADAPTER 		*ioc = pci_get_drvdata(pdev);
 	struct Scsi_Host 	*host = ioc->sh;
 	MPT_SCSI_HOST		*hd;
 
@@ -1384,15 +1047,15 @@ mptscsih_shutdown(struct device * dev)
 #ifdef CONFIG_PM
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
- *	mptscsih_suspend - Fusion MPT scsie driver suspend routine.
+ *	mptscsih_suspend - Fusion MPT scsi driver suspend routine.
  *
  *
  */
-static int
+int
 mptscsih_suspend(struct pci_dev *pdev, pm_message_t state)
 {
-	mptscsih_shutdown(&pdev->dev);
-	return 0;
+	mptscsih_shutdown(pdev);
+	return mpt_suspend(pdev,state);
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -1401,13 +1064,15 @@ mptscsih_suspend(struct pci_dev *pdev, p
  *
  *
  */
-static int
+int
 mptscsih_resume(struct pci_dev *pdev)
 {
 	MPT_ADAPTER 		*ioc = pci_get_drvdata(pdev);
 	struct Scsi_Host 	*host = ioc->sh;
 	MPT_SCSI_HOST		*hd;
 
+	mpt_resume(pdev);
+	
 	if(!host)
 		return 0;
 
@@ -1422,9 +1087,9 @@ mptscsih_resume(struct pci_dev *pdev)
 	if (!dvtaskQ_active) {
 		dvtaskQ_active = 1;
 		spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
-		INIT_WORK(&mptscsih_dvTask,
+		INIT_WORK(&dvTaskQ_task,
 		  mptscsih_domainValidation, (void *) hd);
-		schedule_work(&mptscsih_dvTask);
+		schedule_work(&dvTaskQ_task);
 	} else {
 		spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
 	}
@@ -1435,82 +1100,6 @@ mptscsih_resume(struct pci_dev *pdev)
 
 #endif
 
-static struct mpt_pci_driver mptscsih_driver = {
-	.probe		= mptscsih_probe,
-	.remove		= mptscsih_remove,
-	.shutdown	= mptscsih_shutdown,
-#ifdef CONFIG_PM
-	.suspend	= mptscsih_suspend,
-	.resume		= mptscsih_resume,
-#endif
-};
-
-/*  SCSI host fops start here...  */
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/**
- *	mptscsih_init - Register MPT adapter(s) as SCSI host(s) with
- *	linux scsi mid-layer.
- *
- *	Returns 0 for success, non-zero for failure.
- */
-static int __init
-mptscsih_init(void)
-{
-
-	show_mptmod_ver(my_NAME, my_VERSION);
-
-	ScsiDoneCtx = mpt_register(mptscsih_io_done, MPTSCSIH_DRIVER);
-	ScsiTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSCSIH_DRIVER);
-	ScsiScanDvCtx = mpt_register(mptscsih_scandv_complete, MPTSCSIH_DRIVER);
-
-	if (mpt_event_register(ScsiDoneCtx, mptscsih_event_process) == 0) {
-		devtprintk((KERN_INFO MYNAM
-		  ": Registered for IOC event notifications\n"));
-	}
-
-	if (mpt_reset_register(ScsiDoneCtx, mptscsih_ioc_reset) == 0) {
-		dprintk((KERN_INFO MYNAM
-		  ": Registered for IOC reset notifications\n"));
-	}
-
-	if(mpt_device_driver_register(&mptscsih_driver,
-	  MPTSCSIH_DRIVER) != 0 ) {
-		dprintk((KERN_INFO MYNAM
-		": failed to register dd callbacks\n"));
-	}
-
-	return 0;
-
-}
-
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/**
- *	mptscsih_exit - Unregisters MPT adapter(s)
- *
- */
-static void __exit
-mptscsih_exit(void)
-{
-	mpt_device_driver_deregister(MPTSCSIH_DRIVER);
-
-	mpt_reset_deregister(ScsiDoneCtx);
-	dprintk((KERN_INFO MYNAM
-	  ": Deregistered for IOC reset notifications\n"));
-
-	mpt_event_deregister(ScsiDoneCtx);
-	dprintk((KERN_INFO MYNAM
-	  ": Deregistered for IOC event notifications\n"));
-
-	mpt_deregister(ScsiScanDvCtx);
-	mpt_deregister(ScsiTaskCtx);
-	mpt_deregister(ScsiDoneCtx);
-
-	if (info_kbuf != NULL)
-		kfree(info_kbuf);
-
-}
-
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /**
  *	mptscsih_info - Return information about MPT adapter
@@ -1520,24 +1109,25 @@ mptscsih_exit(void)
  *
  *	Returns pointer to buffer where information was written.
  */
-static const char *
+const char *
 mptscsih_info(struct Scsi_Host *SChost)
 {
 	MPT_SCSI_HOST *h;
 	int size = 0;
 
-	if (info_kbuf == NULL)
-		if ((info_kbuf = kmalloc(0x1000 /* 4Kb */, GFP_KERNEL)) == NULL)
-			return info_kbuf;
-
 	h = (MPT_SCSI_HOST *)SChost->hostdata;
-	info_kbuf[0] = '\0';
+
 	if (h) {
-		mpt_print_ioc_summary(h->ioc, info_kbuf, &size, 0, 0);
-		info_kbuf[size-1] = '\0';
+		if (h->info_kbuf == NULL)
+			if ((h->info_kbuf = kmalloc(0x1000 /* 4Kb */, GFP_KERNEL)) == NULL)
+				return h->info_kbuf;
+		h->info_kbuf[0] = '\0';
+
+		mpt_print_ioc_summary(h->ioc, h->info_kbuf, &size, 0, 0);
+		h->info_kbuf[size-1] = '\0';
 	}
 
-	return info_kbuf;
+	return h->info_kbuf;
 }
 
 struct info_str {
@@ -1547,7 +1137,8 @@ struct info_str {
 	int   pos;
 };
 
-static void copy_mem_info(struct info_str *info, char *data, int len)
+static void
+mptscsih_copy_mem_info(struct info_str *info, char *data, int len)
 {
 	if (info->pos + len > info->length)
 		len = info->length - info->pos;
@@ -1568,7 +1159,8 @@ static void copy_mem_info(struct info_st
 	}
 }
 
-static int copy_info(struct info_str *info, char *fmt, ...)
+static int
+mptscsih_copy_info(struct info_str *info, char *fmt, ...)
 {
 	va_list args;
 	char buf[81];
@@ -1578,11 +1170,12 @@ static int copy_info(struct info_str *in
 	len = vsprintf(buf, fmt, args);
 	va_end(args);
 
-	copy_mem_info(info, buf, len);
+	mptscsih_copy_mem_info(info, buf, len);
 	return len;
 }
 
-static int mptscsih_host_info(MPT_ADAPTER *ioc, char *pbuf, off_t offset, int len)
+static int
+mptscsih_host_info(MPT_ADAPTER *ioc, char *pbuf, off_t offset, int len)
 {
 	struct info_str info;
 
@@ -1591,10 +1184,10 @@ static int mptscsih_host_info(MPT_ADAPTE
 	info.offset	= offset;
 	info.pos	= 0;
 
-	copy_info(&info, "%s: %s, ", ioc->name, ioc->prod_name);
-	copy_info(&info, "%s%08xh, ", MPT_FW_REV_MAGIC_ID_STRING, ioc->facts.FWVersion.Word);
-	copy_info(&info, "Ports=%d, ", ioc->facts.NumberOfPorts);
-	copy_info(&info, "MaxQ=%d\n", ioc->req_depth);
+	mptscsih_copy_info(&info, "%s: %s, ", ioc->name, ioc->prod_name);
+	mptscsih_copy_info(&info, "%s%08xh, ", MPT_FW_REV_MAGIC_ID_STRING, ioc->facts.FWVersion.Word);
+	mptscsih_copy_info(&info, "Ports=%d, ", ioc->facts.NumberOfPorts);
+	mptscsih_copy_info(&info, "MaxQ=%d\n", ioc->req_depth);
 
 	return ((info.pos > info.offset) ? info.pos - info.offset : 0);
 }
@@ -1612,7 +1205,7 @@ static int mptscsih_host_info(MPT_ADAPTE
  * 	hostno: scsi host number
  *	func:   if write = 1; if read = 0
  */
-static int
+int
 mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
 			int length, int func)
 {
@@ -1649,7 +1242,7 @@ mptscsih_proc_info(struct Scsi_Host *hos
  *
  *	Returns 0. (rtn value discarded by linux scsi mid-layer)
  */
-static int
+int
 mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
 {
 	MPT_SCSI_HOST		*hd;
@@ -1684,7 +1277,7 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, v
 	/*
 	 *  Put together a MPT SCSI request...
 	 */
-	if ((mf = mpt_get_msg_frame(ScsiDoneCtx, hd->ioc)) == NULL) {
+	if ((mf = mpt_get_msg_frame(hd->ioc->DoneCtx, hd->ioc)) == NULL) {
 		dprintk((MYIOC_s_WARN_FMT "QueueCmd, no msg frames!!\n",
 				hd->ioc->name));
 		return SCSI_MLQUEUE_HOST_BUSY;
@@ -1696,8 +1289,7 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, v
 
 	ADD_INDEX_LOG(my_idx);
 
-	/*  BUG FIX!  19991030 -sralston
-	 *    TUR's being issued with scsictl=0x02000000 (DATA_IN)!
+	/*    TUR's being issued with scsictl=0x02000000 (DATA_IN)!
 	 *    Seems we may receive a buffer (datalen>0) even when there
 	 *    will be no data transfer!  GRRRRR...
 	 */
@@ -1791,9 +1383,9 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, v
 				if (!dvtaskQ_active) {
 					dvtaskQ_active = 1;
 					spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
-					INIT_WORK(&mptscsih_dvTask, mptscsih_domainValidation, (void *) hd);
+					INIT_WORK(&dvTaskQ_task, mptscsih_domainValidation, (void *) hd);
 
-					schedule_work(&mptscsih_dvTask);
+					schedule_work(&dvTaskQ_task);
 				} else {
 					spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
 				}
@@ -1819,7 +1411,7 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, v
 	}
 #endif
 
-	mpt_put_msg_frame(ScsiDoneCtx, hd->ioc, mf);
+	mpt_put_msg_frame(hd->ioc->DoneCtx, hd->ioc, mf);
 	dmfprintk((MYIOC_s_INFO_FMT "Issued SCSI cmd (%p) mf=%p idx=%d\n",
 			hd->ioc->name, SCpnt, mf, my_idx));
 	DBG_DUMP_REQUEST_FRAME(mf)
@@ -2036,7 +1628,7 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd
 
 	/* Return Fail to calling function if no message frames available.
 	 */
-	if ((mf = mpt_get_msg_frame(ScsiTaskCtx, hd->ioc)) == NULL) {
+	if ((mf = mpt_get_msg_frame(hd->ioc->TaskCtx, hd->ioc)) == NULL) {
 		dfailprintk((MYIOC_s_ERR_FMT "IssueTaskMgmt, no msg frames!!\n",
 				hd->ioc->name));
 		//return FAILED;
@@ -2075,7 +1667,7 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd
 
 	DBG_DUMP_TM_REQUEST_FRAME((u32 *)pScsiTm);
 
-	if ((retval = mpt_send_handshake_request(ScsiTaskCtx, hd->ioc,
+	if ((retval = mpt_send_handshake_request(hd->ioc->TaskCtx, hd->ioc,
 		sizeof(SCSITaskMgmt_t), (u32*)pScsiTm,
 		CAN_SLEEP)) != 0) {
 		dfailprintk((MYIOC_s_ERR_FMT "_send_handshake FAILED!"
@@ -2107,7 +1699,7 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd
  *
  *	Returns SUCCESS or FAILED.
  */
-static int
+int
 mptscsih_abort(struct scsi_cmnd * SCpnt)
 {
 	MPT_SCSI_HOST	*hd;
@@ -2115,7 +1707,6 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
 	MPT_FRAME_HDR	*mf;
 	u32		 ctx2abort;
 	int		 scpnt_idx;
-	spinlock_t	*host_lock = SCpnt->device->host->host_lock;
 
 	/* If we can't locate our host adapter structure, return FAILED status.
 	 */
@@ -2163,7 +1754,6 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
 
 	hd->abortSCpnt = SCpnt;
 
-	spin_unlock_irq(host_lock);
 	if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
 		SCpnt->device->channel, SCpnt->device->id, SCpnt->device->lun,
 		ctx2abort, 2 /* 2 second timeout */)
@@ -2180,8 +1770,6 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
 		hd->tmPending = 0;
 		hd->tmState = TM_STATE_NONE;
 
-		spin_lock_irq(host_lock);
-
 		/* Unmap the DMA buffers, if any. */
 		if (SCpnt->use_sg) {
 			pci_unmap_sg(ioc->pcidev, (struct scatterlist *) SCpnt->request_buffer,
@@ -2197,7 +1785,6 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
 		mpt_free_msg_frame(ioc, mf);
 		return FAILED;
 	}
-	spin_lock_irq(host_lock);
 	return SUCCESS;
 }
 
@@ -2210,11 +1797,10 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
  *
  *	Returns SUCCESS or FAILED.
  */
-static int
+int
 mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
 {
 	MPT_SCSI_HOST	*hd;
-	spinlock_t	*host_lock = SCpnt->device->host->host_lock;
 
 	/* If we can't locate our host adapter structure, return FAILED status.
 	 */
@@ -2231,7 +1817,6 @@ mptscsih_dev_reset(struct scsi_cmnd * SC
 	printk(KERN_WARNING MYNAM ": %s: >> Attempting target reset! (sc=%p)\n",
 	       hd->ioc->name, SCpnt);
 
-	spin_unlock_irq(host_lock);
 	if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
 		SCpnt->device->channel, SCpnt->device->id,
 		0, 0, 5 /* 5 second timeout */)
@@ -2243,12 +1828,10 @@ mptscsih_dev_reset(struct scsi_cmnd * SC
 		 		hd->ioc->name, SCpnt);
 		hd->tmPending = 0;
 		hd->tmState = TM_STATE_NONE;
-		spin_lock_irq(host_lock);
 		return FAILED;
 	}
-	spin_lock_irq(host_lock);
-	return SUCCESS;
 
+	return SUCCESS;
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -2260,7 +1843,7 @@ mptscsih_dev_reset(struct scsi_cmnd * SC
  *
  *	Returns SUCCESS or FAILED.
  */
-static int
+int
 mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
 {
 	MPT_SCSI_HOST	*hd;
@@ -2282,7 +1865,6 @@ mptscsih_bus_reset(struct scsi_cmnd * SC
 		hd->timeouts++;
 
 	/* We are now ready to execute the task management request. */
-	spin_unlock_irq(host_lock);
 	if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
 		SCpnt->device->channel, 0, 0, 0, 5 /* 5 second timeout */)
 	    < 0){
@@ -2298,7 +1880,7 @@ mptscsih_bus_reset(struct scsi_cmnd * SC
 		spin_lock_irq(host_lock);
 		return FAILED;
 	}
-	spin_lock_irq(host_lock);
+
 	return SUCCESS;
 }
 
@@ -2312,12 +1894,11 @@ mptscsih_bus_reset(struct scsi_cmnd * SC
  *
  *	Returns SUCCESS or FAILED.
  */
-static int
+int
 mptscsih_host_reset(struct scsi_cmnd *SCpnt)
 {
 	MPT_SCSI_HOST *  hd;
 	int              status = SUCCESS;
-	spinlock_t	*host_lock = SCpnt->device->host->host_lock;
 
 	/*  If we can't locate the host to reset, then we failed. */
 	if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
@@ -2333,7 +1914,6 @@ mptscsih_host_reset(struct scsi_cmnd *SC
 	/*  If our attempts to reset the host failed, then return a failed
 	 *  status.  The host will be taken off line by the SCSI mid-layer.
 	 */
-	spin_unlock_irq(host_lock);
 	if (mpt_HardResetHandler(hd->ioc, CAN_SLEEP) < 0){
 		status = FAILED;
 	} else {
@@ -2343,8 +1923,6 @@ mptscsih_host_reset(struct scsi_cmnd *SC
 		hd->tmPending = 0;
 		hd->tmState = TM_STATE_NONE;
 	}
-	spin_lock_irq(host_lock);
-
 
 	dtmprintk( ( KERN_WARNING MYNAM ": mptscsih_host_reset: "
 		     "Status = %s\n",
@@ -2426,7 +2004,7 @@ mptscsih_tm_wait_for_completion(MPT_SCSI
  *
  *	Returns 1 indicating alloc'd request frame ptr should be freed.
  */
-static int
+int
 mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
 {
 	SCSITaskMgmtReply_t	*pScsiTmReply;
@@ -2509,7 +2087,7 @@ mptscsih_taskmgmt_complete(MPT_ADAPTER *
 /*
  *	This is anyones guess quite frankly.
  */
-static int
+int
 mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev,
 		sector_t capacity, int geom[])
 {
@@ -2556,7 +2134,7 @@ mptscsih_bios_param(struct scsi_device *
  *	Return non-zero if allocation fails.
  *	Init memory once per id (not LUN).
  */
-static int
+int
 mptscsih_slave_alloc(struct scsi_device *device)
 {
 	struct Scsi_Host	*host = device->host;
@@ -2599,7 +2177,8 @@ mptscsih_slave_alloc(struct scsi_device 
 	return 0;
 }
 
-static int mptscsih_is_raid_volume(MPT_SCSI_HOST *hd, uint id)
+static int 
+mptscsih_is_raid_volume(MPT_SCSI_HOST *hd, uint id)
 {
 	int i;
 
@@ -2618,7 +2197,7 @@ static int mptscsih_is_raid_volume(MPT_S
  *	OS entry point to allow for host driver to free allocated memory
  *	Called if no device present or device being unloaded
  */
-static void
+void
 mptscsih_slave_destroy(struct scsi_device *device)
 {
 	struct Scsi_Host	*host = device->host;
@@ -2639,7 +2218,7 @@ mptscsih_slave_destroy(struct scsi_devic
 
 	kfree(hd->Targets[target]);
 	hd->Targets[target] = NULL;
-	
+
 	if (hd->ioc->bus_type == SCSI) {
 		if (mptscsih_is_raid_volume(hd, target)) {
 			hd->ioc->spi_data.forceDv |= MPT_SCSICFG_RELOAD_IOC_PG3;
@@ -2655,13 +2234,27 @@ mptscsih_slave_destroy(struct scsi_devic
 	}
 }
 
-static void
-mptscsih_set_queue_depth(struct scsi_device *device, MPT_SCSI_HOST *hd,
-	VirtDevice *pTarget, int qdepth)
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*
+ *	mptscsih_change_queue_depth - This function will set a devices queue depth
+ *	@sdev: per scsi_device pointer
+ *	@qdepth: requested queue depth
+ *
+ *	Adding support for new 'change_queue_depth' api.
+*/
+int
+mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth)
 {
+	MPT_SCSI_HOST	*hd = (MPT_SCSI_HOST *)sdev->host->hostdata;
+	VirtDevice *pTarget;
 	int	max_depth;
 	int	tagged;
 
+	if (hd == NULL)
+		return 0;
+	if (!(pTarget = hd->Targets[sdev->id]))
+		return 0;
+
 	if (hd->ioc->bus_type == SCSI) {
 		if (pTarget->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY) {
 			if (!(pTarget->tflags & MPT_TARGET_FLAGS_Q_YES))
@@ -2685,17 +2278,17 @@ mptscsih_set_queue_depth(struct scsi_dev
 	else
 		tagged = MSG_SIMPLE_TAG;
 
-	scsi_adjust_queue_depth(device, tagged, qdepth);
+	scsi_adjust_queue_depth(sdev, tagged, qdepth);
+	return sdev->queue_depth;
 }
 
-
 /*
  *	OS entry point to adjust the queue_depths on a per-device basis.
  *	Called once per device the bus scan. Use it to force the queue_depth
  *	member to 1 if a device does not support Q tags.
  *	Return non-zero if fails.
  */
-static int
+int
 mptscsih_slave_configure(struct scsi_device *device)
 {
 	struct Scsi_Host	*sh = device->host;
@@ -2738,7 +2331,7 @@ mptscsih_slave_configure(struct scsi_dev
 
 	mptscsih_initTarget(hd, device->channel, device->id, device->lun,
 		device->inquiry, device->inquiry_len );
-	mptscsih_set_queue_depth(device, hd, pTarget, MPT_SCSI_CMD_PER_DEV_HIGH);
+	mptscsih_change_queue_depth(device, MPT_SCSI_CMD_PER_DEV_HIGH);
 
 	dsprintk((MYIOC_s_INFO_FMT
 		"Queue depth=%d, tflags=%x\n",
@@ -2758,25 +2351,6 @@ slave_configure_exit:
 	return 0;
 }
 
-static ssize_t
-mptscsih_store_queue_depth(struct device *dev, const char *buf, size_t count)
-{
-	int			 depth;
-	struct scsi_device	*sdev = to_scsi_device(dev);
-	MPT_SCSI_HOST		*hd = (MPT_SCSI_HOST *) sdev->host->hostdata;
-	VirtDevice		*pTarget;
-
-	depth = simple_strtoul(buf, NULL, 0);
-	if (depth == 0)
-		return -EINVAL;
-	pTarget = hd->Targets[sdev->id];
-	if (pTarget == NULL)
-		return -EINVAL;
-	mptscsih_set_queue_depth(sdev, (MPT_SCSI_HOST *) sdev->host->hostdata,
-		pTarget, depth);
-	return count;
-}
-
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
  *  Private routines...
@@ -2788,7 +2362,7 @@ mptscsih_store_queue_depth(struct device
  *
  */
 static void
-copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply)
+mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply)
 {
 	VirtDevice	*target;
 	SCSIIORequest_t	*pReq;
@@ -2854,7 +2428,7 @@ SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-static int
+int
 mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
 {
 	MPT_SCSI_HOST	*hd;
@@ -2949,8 +2523,8 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int
 			 */
 			hd->pLocal = &hd->localReply;
 			hd->pLocal->completion = MPT_SCANDV_DID_RESET;
-			scandv_wait_done = 1;
-			wake_up(&scandv_waitq);
+			hd->scandv_wait_done = 1;
+			wake_up(&hd->scandv_waitq);
 			hd->cmdPtr = NULL;
 		}
 
@@ -2969,7 +2543,7 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-static int
+int
 mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
 {
 	MPT_SCSI_HOST *hd;
@@ -3085,42 +2659,6 @@ mptscsih_event_process(MPT_ADAPTER *ioc,
 	return 1;		/* currently means nothing really */
 }
 
-static struct device_attribute mptscsih_queue_depth_attr = {
-	.attr = {
-		.name = 	"queue_depth",
-		.mode =		S_IWUSR,
-	},
-	.store = mptscsih_store_queue_depth,
-};
-
-static struct device_attribute *mptscsih_dev_attrs[] = {
-	&mptscsih_queue_depth_attr,
-	NULL,
-};
-
-static struct scsi_host_template driver_template = {
-	.proc_name			= "mptscsih",
-	.proc_info			= mptscsih_proc_info,
-	.name				= "MPT SCSI Host",
-	.info				= mptscsih_info,
-	.queuecommand			= mptscsih_qcmd,
-	.slave_alloc			= mptscsih_slave_alloc,
-	.slave_configure		= mptscsih_slave_configure,
-	.slave_destroy			= mptscsih_slave_destroy,
-	.eh_abort_handler		= mptscsih_abort,
-	.eh_device_reset_handler	= mptscsih_dev_reset,
-	.eh_bus_reset_handler		= mptscsih_bus_reset,
-	.eh_host_reset_handler		= mptscsih_host_reset,
-	.bios_param			= mptscsih_bios_param,
-	.can_queue			= MPT_SCSI_CAN_QUEUE,
-	.this_id			= -1,
-	.sg_tablesize			= MPT_SCSI_SG_DEPTH,
-	.max_sectors			= 8192,
-	.cmd_per_lun			= 7,
-	.use_clustering			= ENABLE_CLUSTERING,
-	.sdev_attrs			= mptscsih_dev_attrs,
-};
-
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
  *	mptscsih_initTarget - Target, LUN alloc/free functionality.
@@ -3158,9 +2696,9 @@ mptscsih_initTarget(MPT_SCSI_HOST *hd, i
 	 * around a bug in th emid-layer in some distributions in which the mid-layer will
 	 * continue to try to communicate to the LUN and evntually create a dummy LUN.
 	*/
-	if (mpt_pq_filter && dlen && (data[0] & 0xE0))
+	if (hd->mpt_pq_filter && dlen && (data[0] & 0xE0))
 		data[0] |= 0x40;
-	
+
 	/* Is LUN supported? If so, upper 2 bits will be 0
 	* in first byte of inquiry data.
 	*/
@@ -3307,7 +2845,7 @@ mptscsih_setTargetNegoParms(MPT_SCSI_HOS
 				ddvtprintk((KERN_INFO "Enabling QAS on id=%d due to ~TARGET_FLAGS_VALID_56!\n", id));
 				noQas = 0;
 			}
-				
+
 			offset = pspi_data->maxSyncOffset;
 
 			/* If RAID, never disable QAS
@@ -3401,7 +2939,7 @@ mptscsih_setTargetNegoParms(MPT_SCSI_HOS
 				if ( (vdev = hd->Targets[ii]) ) {
 					vdev->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
 					mptscsih_writeSDP1(hd, 0, ii, vdev->negoFlags);
-				}	
+				}
 			}
 		}
 	}
@@ -3426,14 +2964,15 @@ mptscsih_setTargetNegoParms(MPT_SCSI_HOS
  * Tapes, initTarget will set this flag on completion of Inquiry command.
  * Called only if DV_NOT_DONE flag is set
  */
-static void mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq)
+static void
+mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq)
 {
 	u8 cmd;
 	ScsiCfgData *pSpi;
 
 	ddvtprintk((" set_dvflags: id=%d lun=%d negoNvram=%x cmd=%x\n", 
 		pReq->TargetID, pReq->LUN[1], hd->negoNvram, pReq->CDB[0]));
-	
+
 	if ((pReq->LUN[1] != 0) || (hd->negoNvram != 0))
 		return;
 
@@ -3464,7 +3003,8 @@ static void mptscsih_set_dvflags(MPT_SCS
  * If no Target, bus reset on 1st I/O. Set the flag to
  * prevent any future negotiations to this device.
  */
-static void mptscsih_no_negotiate(MPT_SCSI_HOST *hd, int target_id)
+static void
+mptscsih_no_negotiate(MPT_SCSI_HOST *hd, int target_id)
 {
 
 	if ((hd->Targets) && (hd->Targets[target_id] == NULL))
@@ -3631,7 +3171,7 @@ mptscsih_writeSDP1(MPT_SCSI_HOST *hd, in
 			offset = pTarget->maxOffset;
 			negoFlags = pTarget->negoFlags;
 		}
-		
+
 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
 		/* Force to async and narrow if DV has not been executed
 		 * for this ID
@@ -3653,7 +3193,7 @@ mptscsih_writeSDP1(MPT_SCSI_HOST *hd, in
 
 		/* Get a MF for this command.
 		 */
-		if ((mf = mpt_get_msg_frame(ScsiDoneCtx, ioc)) == NULL) {
+		if ((mf = mpt_get_msg_frame(ioc->DoneCtx, ioc)) == NULL) {
 			dprintk((MYIOC_s_WARN_FMT "write SDP1: no msg frames!\n",
 						ioc->name));
 			return -EAGAIN;
@@ -3717,7 +3257,7 @@ mptscsih_writeSDP1(MPT_SCSI_HOST *hd, in
 				ioc->name, id, (id | (bus<<8)),
 				requested, configuration));
 
-		mpt_put_msg_frame(ScsiDoneCtx, ioc, mf);
+		mpt_put_msg_frame(ioc->DoneCtx, ioc, mf);
 	}
 
 	return 0;
@@ -3748,7 +3288,7 @@ mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd
 
 	/* Get a MF for this command.
 	 */
-	if ((mf = mpt_get_msg_frame(ScsiDoneCtx, ioc)) == NULL) {
+	if ((mf = mpt_get_msg_frame(ioc->DoneCtx, ioc)) == NULL) {
 		dprintk((MYIOC_s_WARN_FMT "writeIOCPage4 : no msg frames!\n",
 					ioc->name));
 		return -EAGAIN;
@@ -3794,7 +3334,7 @@ mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd
 		"writeIOCPage4: MaxSEP=%d ActiveSEP=%d id=%d bus=%d\n",
 			ioc->name, IOCPage4Ptr->MaxSEP, IOCPage4Ptr->ActiveSEP, target_id, bus));
 
-	mpt_put_msg_frame(ScsiDoneCtx, ioc, mf);
+	mpt_put_msg_frame(ioc->DoneCtx, ioc, mf);
 
 	return 0;
 }
@@ -3824,7 +3364,7 @@ mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd
  *	in the IOC member localReply structure.
  *	Used ONLY for DV and other internal commands.
  */
-static int
+int
 mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
 {
 	MPT_SCSI_HOST	*hd;
@@ -3832,6 +3372,8 @@ mptscsih_scandv_complete(MPT_ADAPTER *io
 	int		 completionCode;
 	u16		 req_idx;
 
+	hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
+
 	if ((mf == NULL) ||
 	    (mf >= MPT_INDEX_2_MFPTR(ioc, ioc->req_depth))) {
 		printk(MYIOC_s_ERR_FMT
@@ -3840,7 +3382,6 @@ mptscsih_scandv_complete(MPT_ADAPTER *io
 		goto wakeup;
 	}
 
-	hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
 	del_timer(&hd->timer);
 	req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
 	hd->ScsiLookup[req_idx] = NULL;
@@ -3972,8 +3513,8 @@ wakeup:
 	/*
 	 * Wake up the original calling thread
 	 */
-	scandv_wait_done = 1;
-	wake_up(&scandv_waitq);
+	hd->scandv_wait_done = 1;
+	wake_up(&hd->scandv_waitq);
 
 	return 1;
 }
@@ -3984,7 +3525,8 @@ wakeup:
  *	@data: Pointer to MPT_SCSI_HOST recast as an unsigned long
  *
  */
-static void mptscsih_timer_expired(unsigned long data)
+void
+mptscsih_timer_expired(unsigned long data)
 {
 	MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *) data;
 
@@ -4051,7 +3593,7 @@ mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 a
 
 	/* Get and Populate a free Frame
 	 */
-	if ((mf = mpt_get_msg_frame(ScsiScanDvCtx, hd->ioc)) == NULL) {
+	if ((mf = mpt_get_msg_frame(hd->ioc->InternalCtx, hd->ioc)) == NULL) {
 		ddvprintk((MYIOC_s_WARN_FMT "_do_raid: no msg frames!\n",
 					hd->ioc->name));
 		return -EAGAIN;
@@ -4077,7 +3619,7 @@ mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 a
 
 	hd->pLocal = NULL;
 	hd->timer.expires = jiffies + HZ*10; /* 10 second timeout */
-	scandv_wait_done = 0;
+	hd->scandv_wait_done = 0;
 
 	/* Save cmd pointer, for resource free if timeout or
 	 * FW reload occurs
@@ -4085,8 +3627,8 @@ mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 a
 	hd->cmdPtr = mf;
 
 	add_timer(&hd->timer);
-	mpt_put_msg_frame(ScsiScanDvCtx, hd->ioc, mf);
-	wait_event(scandv_waitq, scandv_wait_done);
+	mpt_put_msg_frame(hd->ioc->InternalCtx, hd->ioc, mf);
+	wait_event(hd->scandv_waitq, hd->scandv_wait_done);
 
 	if ((hd->pLocal == NULL) || (hd->pLocal->completion != MPT_SCANDV_GOOD))
 		return -1;
@@ -4232,7 +3774,7 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTER
 
 	/* Get and Populate a free Frame
 	 */
-	if ((mf = mpt_get_msg_frame(ScsiScanDvCtx, hd->ioc)) == NULL) {
+	if ((mf = mpt_get_msg_frame(hd->ioc->InternalCtx, hd->ioc)) == NULL) {
 		ddvprintk((MYIOC_s_WARN_FMT "No msg frames!\n",
 					hd->ioc->name));
 		return -EBUSY;
@@ -4314,7 +3856,7 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTER
 	 */
 	hd->pLocal = NULL;
 	hd->timer.expires = jiffies + HZ*cmdTimeout;
-	scandv_wait_done = 0;
+	hd->scandv_wait_done = 0;
 
 	/* Save cmd pointer, for resource free if timeout or
 	 * FW reload occurs
@@ -4322,8 +3864,8 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTER
 	hd->cmdPtr = mf;
 
 	add_timer(&hd->timer);
-	mpt_put_msg_frame(ScsiScanDvCtx, hd->ioc, mf);
-	wait_event(scandv_waitq, scandv_wait_done);
+	mpt_put_msg_frame(hd->ioc->InternalCtx, hd->ioc, mf);
+	wait_event(hd->scandv_waitq, hd->scandv_wait_done);
 
 	if (hd->pLocal) {
 		rc = hd->pLocal->completion;
@@ -4640,7 +4182,8 @@ mptscsih_domainValidation(void *arg)
 
 /* Search IOC page 3 to determine if this is hidden physical disk
  */
-static int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id)
+static int 
+mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id)
 {
 	if (ioc->spi_data.pIocPg3) {
 		Ioc3PhysDisk_t *pPDisk =  ioc->spi_data.pIocPg3->PhysDisk;
@@ -4659,7 +4202,8 @@ static int mptscsih_is_phys_disk(MPT_ADA
 
 /* Write SDP1 if no QAS has been enabled
  */
-static void mptscsih_qas_check(MPT_SCSI_HOST *hd, int id)
+static void
+mptscsih_qas_check(MPT_SCSI_HOST *hd, int id)
 {
 	VirtDevice *pTarget;
 	int ii;
@@ -5157,7 +4701,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus
 	}
 	ddvprintk((MYIOC_s_NOTE_FMT "DV: Basic test on id=%d completed OK.\n", ioc->name, id));
 
-	if (mpt_dv == 0)
+	if (ioc->spi_data.mpt_dv == 0)
 		goto target_done;
 
 	inq0 = (*pbuf1) & 0x1F;
@@ -6015,7 +5559,29 @@ mptscsih_fillbuf(char *buffer, int size,
 }
 #endif /* ~MPTSCSIH_ENABLE_DOMAIN_VALIDATION */
 
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+EXPORT_SYMBOL(mptscsih_remove);
+EXPORT_SYMBOL(mptscsih_shutdown);
+#ifdef CONFIG_PM
+EXPORT_SYMBOL(mptscsih_suspend);
+EXPORT_SYMBOL(mptscsih_resume);
+#endif
+EXPORT_SYMBOL(mptscsih_proc_info);
+EXPORT_SYMBOL(mptscsih_info);
+EXPORT_SYMBOL(mptscsih_qcmd);
+EXPORT_SYMBOL(mptscsih_slave_alloc);
+EXPORT_SYMBOL(mptscsih_slave_destroy);
+EXPORT_SYMBOL(mptscsih_slave_configure);
+EXPORT_SYMBOL(mptscsih_abort);
+EXPORT_SYMBOL(mptscsih_dev_reset);
+EXPORT_SYMBOL(mptscsih_bus_reset);
+EXPORT_SYMBOL(mptscsih_host_reset);
+EXPORT_SYMBOL(mptscsih_bios_param);
+EXPORT_SYMBOL(mptscsih_io_done);
+EXPORT_SYMBOL(mptscsih_taskmgmt_complete);
+EXPORT_SYMBOL(mptscsih_scandv_complete);
+EXPORT_SYMBOL(mptscsih_event_process);
+EXPORT_SYMBOL(mptscsih_ioc_reset);
+EXPORT_SYMBOL(mptscsih_change_queue_depth);
+EXPORT_SYMBOL(mptscsih_timer_expired);
 
-module_init(mptscsih_init);
-module_exit(mptscsih_exit);
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
diff --git a/drivers/message/fusion/mptscsih.h b/drivers/message/fusion/mptscsih.h
--- a/drivers/message/fusion/mptscsih.h
+++ b/drivers/message/fusion/mptscsih.h
@@ -1,26 +1,13 @@
 /*
- *  linux/drivers/message/fusion/mptscsih.h
+ *  linux/drivers/message/fusion/mptscsi.h
  *      High performance SCSI / Fibre Channel SCSI Host device driver.
  *      For use with PCI chip/adapter(s):
  *          LSIFC9xx/LSI409xx Fibre Channel
  *      running LSI Logic Fusion MPT (Message Passing Technology) firmware.
  *
- *  Credits:
- *      This driver would not exist if not for Alan Cox's development
- *      of the linux i2o driver.
- *
- *      A huge debt of gratitude is owed to David S. Miller (DaveM)
- *      for fixing much of the stupid and broken stuff in the early
- *      driver while porting to sparc64 platform.  THANK YOU!
- *
- *      (see also mptbase.c)
- *
- *  Copyright (c) 1999-2004 LSI Logic Corporation
- *  Originally By: Steven J. Ralston
- *  (mailto:netscape.net)
+ *  Copyright (c) 1999-2005 LSI Logic Corporation
  *  (mailto:mpt_linux_developer@lsil.com)
  *
- *  $Id: mptscsih.h,v 1.21 2002/12/03 21:26:35 pdelaney Exp $
  */
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
@@ -91,4 +78,30 @@
 #define MPTSCSIH_MIN_SYNC               0x08
 #define MPTSCSIH_SAF_TE                 0
 
+
+#endif
+
+extern void mptscsih_remove(struct pci_dev *);
+extern void mptscsih_shutdown(struct pci_dev *);
+#ifdef CONFIG_PM
+extern int mptscsih_suspend(struct pci_dev *pdev, pm_message_t state);
+extern int mptscsih_resume(struct pci_dev *pdev);
 #endif
+extern int mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset, int length, int func);
+extern const char * mptscsih_info(struct Scsi_Host *SChost);
+extern int mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *));
+extern int mptscsih_slave_alloc(struct scsi_device *device);
+extern void mptscsih_slave_destroy(struct scsi_device *device);
+extern int mptscsih_slave_configure(struct scsi_device *device);
+extern int mptscsih_abort(struct scsi_cmnd * SCpnt);
+extern int mptscsih_dev_reset(struct scsi_cmnd * SCpnt);
+extern int mptscsih_bus_reset(struct scsi_cmnd * SCpnt);
+extern int mptscsih_host_reset(struct scsi_cmnd *SCpnt);
+extern int mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev, sector_t capacity, int geom[]);
+extern int mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
+extern int mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
+extern int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
+extern int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
+extern int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset);
+extern int mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth);
+extern void mptscsih_timer_expired(unsigned long data);
diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c
new file mode 100644
--- /dev/null
+++ b/drivers/message/fusion/mptspi.c
@@ -0,0 +1,467 @@
+/*
+ *  linux/drivers/message/fusion/mptspi.c
+ *      For use with LSI Logic PCI chip/adapter(s)
+ *      running LSI Logic Fusion MPT (Message Passing Technology) firmware.
+ *
+ *  Copyright (c) 1999-2005 LSI Logic Corporation
+ *  (mailto:mpt_linux_developer@lsil.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; version 2 of the License.
+
+    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.
+
+    NO WARRANTY
+    THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
+    CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
+    LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
+    MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
+    solely responsible for determining the appropriateness of using and
+    distributing the Program and assumes all risks associated with its
+    exercise of rights under this Agreement, including but not limited to
+    the risks and costs of program errors, damage to or loss of data,
+    programs or equipment, and unavailability or interruption of operations.
+
+    DISCLAIMER OF LIABILITY
+    NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
+    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+    TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+    USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
+    HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
+
+    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_compat.h"	/* linux-2.6 tweaks */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/kdev_t.h>
+#include <linux/blkdev.h>
+#include <linux/delay.h>	/* for mdelay */
+#include <linux/interrupt.h>	/* needed for in_interrupt() proto */
+#include <linux/reboot.h>	/* notifier code */
+#include <linux/sched.h>
+#include <linux/workqueue.h>
+
+#include <scsi/scsi.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_host.h>
+#include <scsi/scsi_tcq.h>
+
+#include "mptbase.h"
+#include "mptscsih.h"
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+#define my_NAME		"Fusion MPT SPI Host driver"
+#define my_VERSION	MPT_LINUX_VERSION_COMMON
+#define MYNAM		"mptspi"
+
+MODULE_AUTHOR(MODULEAUTHOR);
+MODULE_DESCRIPTION(my_NAME);
+MODULE_LICENSE("GPL");
+
+/* Command line args */
+#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
+static int mpt_dv = MPTSCSIH_DOMAIN_VALIDATION;
+module_param(mpt_dv, int, 0);
+MODULE_PARM_DESC(mpt_dv, " DV Algorithm: enhanced=1, basic=0 (default=MPTSCSIH_DOMAIN_VALIDATION=1)");
+
+static int mpt_width = MPTSCSIH_MAX_WIDTH;
+module_param(mpt_width, int, 0);
+MODULE_PARM_DESC(mpt_width, " Max Bus Width: wide=1, narrow=0 (default=MPTSCSIH_MAX_WIDTH=1)");
+
+static ushort mpt_factor = MPTSCSIH_MIN_SYNC;
+module_param(mpt_factor, ushort, 0);
+MODULE_PARM_DESC(mpt_factor, " Min Sync Factor (default=MPTSCSIH_MIN_SYNC=0x08)");
+#endif
+
+static int mpt_saf_te = MPTSCSIH_SAF_TE;
+module_param(mpt_saf_te, int, 0);
+MODULE_PARM_DESC(mpt_saf_te, " Force enabling SEP Processor: enable=1  (default=MPTSCSIH_SAF_TE=0)");
+
+static int mpt_pq_filter = 0;
+module_param(mpt_pq_filter, int, 0);
+MODULE_PARM_DESC(mpt_pq_filter, " Enable peripheral qualifier filter: enable=1  (default=0)");
+
+static int	mptspiDoneCtx = -1;
+static int	mptspiTaskCtx = -1;
+static int	mptspiInternalCtx = -1; /* Used only for internal commands */
+
+static struct scsi_host_template mptspi_driver_template = {
+	.proc_name			= "mptspi",
+	.proc_info			= mptscsih_proc_info,
+	.name				= "MPT SPI Host",
+	.info				= mptscsih_info,
+	.queuecommand			= mptscsih_qcmd,
+	.slave_alloc			= mptscsih_slave_alloc,
+	.slave_configure		= mptscsih_slave_configure,
+	.slave_destroy			= mptscsih_slave_destroy,
+	.change_queue_depth 		= mptscsih_change_queue_depth,
+	.eh_abort_handler		= mptscsih_abort,
+	.eh_device_reset_handler	= mptscsih_dev_reset,
+	.eh_bus_reset_handler		= mptscsih_bus_reset,
+	.eh_host_reset_handler		= mptscsih_host_reset,
+	.bios_param			= mptscsih_bios_param,
+	.can_queue			= MPT_SCSI_CAN_QUEUE,
+	.this_id			= -1,
+	.sg_tablesize			= MPT_SCSI_SG_DEPTH,
+	.max_sectors			= 8192,
+	.cmd_per_lun			= 7,
+	.use_clustering			= ENABLE_CLUSTERING,
+};
+
+
+/****************************************************************************
+ * Supported hardware
+ */
+
+static struct pci_device_id mptspi_pci_table[] = {
+	{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_53C1030,
+		PCI_ANY_ID, PCI_ANY_ID },
+	{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_1030_53C1035,
+		PCI_ANY_ID, PCI_ANY_ID },
+	{0}	/* Terminating entry */
+};
+MODULE_DEVICE_TABLE(pci, mptspi_pci_table);
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*
+ *	mptspi_probe - Installs scsi devices per bus.
+ *	@pdev: Pointer to pci_dev structure
+ *
+ *	Returns 0 for success, non-zero for failure.
+ *
+ */
+static int
+mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+{
+	struct Scsi_Host	*sh;
+	MPT_SCSI_HOST		*hd;
+	MPT_ADAPTER 		*ioc;
+	unsigned long		 flags;
+	int			 sz, ii;
+	int			 numSGE = 0;
+	int			 scale;
+	int			 ioc_cap;
+	u8			*mem;
+	int			error=0;
+	int			r;
+	
+	if ((r = mpt_attach(pdev,id)) != 0)
+		return r;
+	
+	ioc = pci_get_drvdata(pdev);
+	ioc->DoneCtx = mptspiDoneCtx;
+	ioc->TaskCtx = mptspiTaskCtx;
+	ioc->InternalCtx = mptspiInternalCtx;
+	
+	/*  Added sanity check on readiness of the MPT adapter.
+	 */
+	if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
+		printk(MYIOC_s_WARN_FMT
+		  "Skipping because it's not operational!\n",
+		  ioc->name);
+		return -ENODEV;
+	}
+
+	if (!ioc->active) {
+		printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
+		  ioc->name);
+		return -ENODEV;
+	}
+
+	/*  Sanity check - ensure at least 1 port is INITIATOR capable
+	 */
+	ioc_cap = 0;
+	for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
+		if (ioc->pfacts[ii].ProtocolFlags &
+		    MPI_PORTFACTS_PROTOCOL_INITIATOR)
+			ioc_cap ++;
+	}
+
+	if (!ioc_cap) {
+		printk(MYIOC_s_WARN_FMT
+			"Skipping ioc=%p because SCSI Initiator mode is NOT enabled!\n",
+			ioc->name, ioc);
+		return -ENODEV;
+	}
+
+	sh = scsi_host_alloc(&mptspi_driver_template, sizeof(MPT_SCSI_HOST));
+
+	if (!sh) {
+		printk(MYIOC_s_WARN_FMT
+			"Unable to register controller with SCSI subsystem\n",
+			ioc->name);
+                return -1;
+        }
+
+	spin_lock_irqsave(&ioc->FreeQlock, flags);
+
+	/* Attach the SCSI Host to the IOC structure
+	 */
+	ioc->sh = sh;
+
+	sh->io_port = 0;
+	sh->n_io_port = 0;
+	sh->irq = 0;
+
+	/* set 16 byte cdb's */
+	sh->max_cmd_len = 16;
+
+	/* Yikes!  This is important!
+	 * Otherwise, by default, linux
+	 * only scans target IDs 0-7!
+	 * pfactsN->MaxDevices unreliable
+	 * (not supported in early
+	 *	versions of the FW).
+	 * max_id = 1 + actual max id,
+	 * max_lun = 1 + actual last lun,
+	 *	see hosts.h :o(
+	 */
+	sh->max_id = MPT_MAX_SCSI_DEVICES;
+
+	sh->max_lun = MPT_LAST_LUN + 1;
+	sh->max_channel = 0;
+	sh->this_id = ioc->pfacts[0].PortSCSIID;
+
+	/* Required entry.
+	 */
+	sh->unique_id = ioc->id;
+
+	/* Verify that we won't exceed the maximum
+	 * number of chain buffers
+	 * We can optimize:  ZZ = req_sz/sizeof(SGE)
+	 * For 32bit SGE's:
+	 *  numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
+	 *               + (req_sz - 64)/sizeof(SGE)
+	 * A slightly different algorithm is required for
+	 * 64bit SGEs.
+	 */
+	scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
+	if (sizeof(dma_addr_t) == sizeof(u64)) {
+		numSGE = (scale - 1) *
+		  (ioc->facts.MaxChainDepth-1) + scale +
+		  (ioc->req_sz - 60) / (sizeof(dma_addr_t) +
+		  sizeof(u32));
+	} else {
+		numSGE = 1 + (scale - 1) *
+		  (ioc->facts.MaxChainDepth-1) + scale +
+		  (ioc->req_sz - 64) / (sizeof(dma_addr_t) +
+		  sizeof(u32));
+	}
+
+	if (numSGE < sh->sg_tablesize) {
+		/* Reset this value */
+		dprintk((MYIOC_s_INFO_FMT
+		  "Resetting sg_tablesize to %d from %d\n",
+		  ioc->name, numSGE, sh->sg_tablesize));
+		sh->sg_tablesize = numSGE;
+	}
+
+	spin_unlock_irqrestore(&ioc->FreeQlock, flags);
+
+	hd = (MPT_SCSI_HOST *) sh->hostdata;
+	hd->ioc = ioc;
+
+	/* SCSI needs scsi_cmnd lookup table!
+	 * (with size equal to req_depth*PtrSz!)
+	 */
+	sz = ioc->req_depth * sizeof(void *);
+	mem = kmalloc(sz, GFP_ATOMIC);
+	if (mem == NULL) {
+		error = -ENOMEM;
+		goto mptspi_probe_failed;
+	}
+
+	memset(mem, 0, sz);
+	hd->ScsiLookup = (struct scsi_cmnd **) mem;
+
+	dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p, sz=%d\n",
+		 ioc->name, hd->ScsiLookup, sz));
+
+	/* Allocate memory for the device structures.
+	 * A non-Null pointer at an offset
+	 * indicates a device exists.
+	 * max_id = 1 + maximum id (hosts.h)
+	 */
+	sz = sh->max_id * sizeof(void *);
+	mem = kmalloc(sz, GFP_ATOMIC);
+	if (mem == NULL) {
+		error = -ENOMEM;
+		goto mptspi_probe_failed;
+	}
+
+	memset(mem, 0, sz);
+	hd->Targets = (VirtDevice **) mem;
+
+	dprintk((KERN_INFO
+	  "  Targets @ %p, sz=%d\n", hd->Targets, sz));
+
+	/* Clear the TM flags
+	 */
+	hd->tmPending = 0;
+	hd->tmState = TM_STATE_NONE;
+	hd->resetPending = 0;
+	hd->abortSCpnt = NULL;
+
+	/* Clear the pointer used to store
+	 * single-threaded commands, i.e., those
+	 * issued during a bus scan, dv and
+	 * configuration pages.
+	 */
+	hd->cmdPtr = NULL;
+
+	/* Initialize this SCSI Hosts' timers
+	 * To use, set the timer expires field
+	 * and add_timer
+	 */
+	init_timer(&hd->timer);
+	hd->timer.data = (unsigned long) hd;
+	hd->timer.function = mptscsih_timer_expired;
+
+	ioc->spi_data.Saf_Te = mpt_saf_te;
+	hd->mpt_pq_filter = mpt_pq_filter;
+
+#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
+	if (ioc->spi_data.maxBusWidth > mpt_width)
+		ioc->spi_data.maxBusWidth = mpt_width;
+	if (ioc->spi_data.minSyncFactor < mpt_factor)
+		ioc->spi_data.minSyncFactor = mpt_factor;
+	if (ioc->spi_data.minSyncFactor == MPT_ASYNC) {
+		ioc->spi_data.maxSyncOffset = 0;
+	}
+	ioc->spi_data.mpt_dv = mpt_dv;
+	hd->negoNvram = 0;
+
+	ddvprintk((MYIOC_s_INFO_FMT
+		"dv %x width %x factor %x saf_te %x mpt_pq_filter %x\n",
+		ioc->name,
+		mpt_dv,
+		mpt_width,
+		mpt_factor,
+		mpt_saf_te,
+		mpt_pq_filter));
+#else
+	hd->negoNvram = MPT_SCSICFG_USE_NVRAM;
+	ddvprintk((MYIOC_s_INFO_FMT
+		"saf_te %x mpt_pq_filter %x\n",
+		ioc->name,
+		mpt_saf_te,
+		mpt_pq_filter));
+#endif
+
+	ioc->spi_data.forceDv = 0;
+	ioc->spi_data.noQas = 0;
+
+	for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++)
+		ioc->spi_data.dvStatus[ii] =
+		  MPT_SCSICFG_NEGOTIATE;
+
+	for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++)
+		ioc->spi_data.dvStatus[ii] |=
+		  MPT_SCSICFG_DV_NOT_DONE;
+
+	init_waitqueue_head(&hd->scandv_waitq);
+	hd->scandv_wait_done = 0;
+	hd->last_queue_full = 0;
+
+	error = scsi_add_host (sh, &ioc->pcidev->dev);
+	if(error) {
+		dprintk((KERN_ERR MYNAM
+		  "scsi_add_host failed\n"));
+		goto mptspi_probe_failed;
+	}
+
+	scsi_scan_host(sh);
+	return 0;
+
+mptspi_probe_failed:
+
+	mptscsih_remove(pdev);
+	return error;
+}
+
+static struct pci_driver mptspi_driver = {
+	.name		= "mptspi",
+	.id_table	= mptspi_pci_table,
+	.probe		= mptspi_probe,
+	.remove		= __devexit_p(mptscsih_remove),
+	.shutdown	= mptscsih_shutdown,
+#ifdef CONFIG_PM
+	.suspend	= mptscsih_suspend,
+	.resume		= mptscsih_resume,
+#endif
+};
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/**
+ *	mptspi_init - Register MPT adapter(s) as SCSI host(s) with
+ *	linux scsi mid-layer.
+ *
+ *	Returns 0 for success, non-zero for failure.
+ */
+static int __init
+mptspi_init(void)
+{
+
+	show_mptmod_ver(my_NAME, my_VERSION);
+
+	mptspiDoneCtx = mpt_register(mptscsih_io_done, MPTSPI_DRIVER);
+	mptspiTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSPI_DRIVER);
+	mptspiInternalCtx = mpt_register(mptscsih_scandv_complete, MPTSPI_DRIVER);
+
+	if (mpt_event_register(mptspiDoneCtx, mptscsih_event_process) == 0) {
+		devtprintk((KERN_INFO MYNAM
+		  ": Registered for IOC event notifications\n"));
+	}
+
+	if (mpt_reset_register(mptspiDoneCtx, mptscsih_ioc_reset) == 0) {
+		dprintk((KERN_INFO MYNAM
+		  ": Registered for IOC reset notifications\n"));
+	}
+
+	return pci_register_driver(&mptspi_driver);
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/**
+ *	mptspi_exit - Unregisters MPT adapter(s)
+ *
+ */
+static void __exit
+mptspi_exit(void)
+{
+	pci_unregister_driver(&mptspi_driver);
+	
+	mpt_reset_deregister(mptspiDoneCtx);
+	dprintk((KERN_INFO MYNAM
+	  ": Deregistered for IOC reset notifications\n"));
+
+	mpt_event_deregister(mptspiDoneCtx);
+	dprintk((KERN_INFO MYNAM
+	  ": Deregistered for IOC event notifications\n"));
+
+	mpt_deregister(mptspiInternalCtx);
+	mpt_deregister(mptspiTaskCtx);
+	mpt_deregister(mptspiDoneCtx);
+}
+
+module_init(mptspi_init);
+module_exit(mptspi_exit);
diff --git a/drivers/message/i2o/Kconfig b/drivers/message/i2o/Kconfig
--- a/drivers/message/i2o/Kconfig
+++ b/drivers/message/i2o/Kconfig
@@ -24,10 +24,28 @@ config I2O
 
 	  If unsure, say N.
 
+config I2O_EXT_ADAPTEC
+	bool "Enable Adaptec extensions"
+	depends on I2O
+	default y
+	---help---
+	  Say Y for support of raidutils for Adaptec I2O controllers. You also
+	  have to say Y to "I2O Configuration support", "I2O SCSI OSM" below
+	  and to "SCSI generic support" under "SCSI device configuration".
+
+config I2O_EXT_ADAPTEC_DMA64
+	bool "Enable 64-bit DMA"
+	depends on I2O_EXT_ADAPTEC && ( 64BIT || HIGHMEM64G )
+	default y
+	---help---
+	  Say Y for support of 64-bit DMA transfer mode on Adaptec I2O
+	  controllers.
+	  Note: You need at least firmware version 3709.
+
 config I2O_CONFIG
 	tristate "I2O Configuration support"
-	depends on PCI && I2O
-	help
+	depends on I2O
+	---help---
 	  Say Y for support of the configuration interface for the I2O adapters.
 	  If you have a RAID controller from Adaptec and you want to use the
 	  raidutils to manage your RAID array, you have to say Y here.
@@ -35,10 +53,31 @@ config I2O_CONFIG
 	  To compile this support as a module, choose M here: the
 	  module will be called i2o_config.
 
+	  Note: If you want to use the new API you have to download the
+	  i2o_config patch from http://i2o.shadowconnect.com/
+
+config I2O_CONFIG_OLD_IOCTL
+	bool "Enable ioctls (OBSOLETE)"
+	depends on I2O_CONFIG
+	default y
+	---help---
+	  Enables old ioctls.
+
+config I2O_BUS
+	tristate "I2O Bus Adapter OSM"
+	depends on I2O
+	---help---
+	  Include support for the I2O Bus Adapter OSM. The Bus Adapter OSM
+	  provides access to the busses on the I2O controller. The main purpose
+	  is to rescan the bus to find new devices.
+
+	  To compile this support as a module, choose M here: the
+	  module will be called i2o_bus.
+
 config I2O_BLOCK
 	tristate "I2O Block OSM"
 	depends on I2O
-	help
+	---help---
 	  Include support for the I2O Block OSM. The Block OSM presents disk
 	  and other structured block devices to the operating system. If you
 	  are using an RAID controller, you could access the array only by
@@ -51,7 +90,7 @@ config I2O_BLOCK
 config I2O_SCSI
 	tristate "I2O SCSI OSM"
 	depends on I2O && SCSI
-	help
+	---help---
 	  Allows direct SCSI access to SCSI devices on a SCSI or FibreChannel
 	  I2O controller. You can use both the SCSI and Block OSM together if
 	  you wish. To access a RAID array, you must use the Block OSM driver.
@@ -63,7 +102,7 @@ config I2O_SCSI
 config I2O_PROC
 	tristate "I2O /proc support"
 	depends on I2O
-	help
+	---help---
 	  If you say Y here and to "/proc file system support", you will be
 	  able to read I2O related information from the virtual directory
 	  /proc/i2o.
diff --git a/drivers/message/i2o/Makefile b/drivers/message/i2o/Makefile
--- a/drivers/message/i2o/Makefile
+++ b/drivers/message/i2o/Makefile
@@ -6,8 +6,11 @@
 #
 
 i2o_core-y		+= iop.o driver.o device.o debug.o pci.o exec-osm.o
+i2o_bus-y		+= bus-osm.o
+i2o_config-y		+= config-osm.o
 obj-$(CONFIG_I2O)	+= i2o_core.o
 obj-$(CONFIG_I2O_CONFIG)+= i2o_config.o
+obj-$(CONFIG_I2O_BUS)	+= i2o_bus.o
 obj-$(CONFIG_I2O_BLOCK)	+= i2o_block.o
 obj-$(CONFIG_I2O_SCSI)	+= i2o_scsi.o
 obj-$(CONFIG_I2O_PROC)	+= i2o_proc.o
diff --git a/drivers/message/i2o/bus-osm.c b/drivers/message/i2o/bus-osm.c
new file mode 100644
--- /dev/null
+++ b/drivers/message/i2o/bus-osm.c
@@ -0,0 +1,164 @@
+/*
+ *	Bus Adapter OSM
+ *
+ *	Copyright (C) 2005	Markus Lidel <Markus.Lidel@shadowconnect.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.
+ *
+ *	Fixes/additions:
+ *		Markus Lidel <Markus.Lidel@shadowconnect.com>
+ *			initial version.
+ */
+
+#include <linux/module.h>
+#include <linux/i2o.h>
+
+#define OSM_NAME	"bus-osm"
+#define OSM_VERSION	"$Rev$"
+#define OSM_DESCRIPTION	"I2O Bus Adapter OSM"
+
+static struct i2o_driver i2o_bus_driver;
+
+/* Bus OSM class handling definition */
+static struct i2o_class_id i2o_bus_class_id[] = {
+	{I2O_CLASS_BUS_ADAPTER},
+	{I2O_CLASS_END}
+};
+
+/**
+ *	i2o_bus_scan - Scan the bus for new devices
+ *	@dev: I2O device of the bus, which should be scanned
+ *
+ *	Scans the bus dev for new / removed devices. After the scan a new LCT
+ *	will be fetched automatically.
+ *
+ *	Returns 0 on success or negative error code on failure.
+ */
+static int i2o_bus_scan(struct i2o_device *dev)
+{
+	struct i2o_message __iomem *msg;
+	u32 m;
+
+	m = i2o_msg_get_wait(dev->iop, &msg, I2O_TIMEOUT_MESSAGE_GET);
+	if (m == I2O_QUEUE_EMPTY)
+		return -ETIMEDOUT;
+
+	writel(FIVE_WORD_MSG_SIZE | SGL_OFFSET_0, &msg->u.head[0]);
+	writel(I2O_CMD_BUS_SCAN << 24 | HOST_TID << 12 | dev->lct_data.tid,
+	       &msg->u.head[1]);
+
+	return i2o_msg_post_wait(dev->iop, m, 60);
+};
+
+/**
+ *	i2o_bus_store_scan - Scan the I2O Bus Adapter
+ *	@d: device which should be scanned
+ *
+ *	Returns count.
+ */
+static ssize_t i2o_bus_store_scan(struct device *d, struct device_attribute *attr, const char *buf,
+				  size_t count)
+{
+	struct i2o_device *i2o_dev = to_i2o_device(d);
+	int rc;
+
+	if ((rc = i2o_bus_scan(i2o_dev)))
+		osm_warn("bus scan failed %d\n", rc);
+
+	return count;
+}
+
+/* Bus Adapter OSM device attributes */
+static DEVICE_ATTR(scan, S_IWUSR, NULL, i2o_bus_store_scan);
+
+/**
+ *	i2o_bus_probe - verify if dev is a I2O Bus Adapter device and install it
+ *	@dev: device to verify if it is a I2O Bus Adapter device
+ *
+ *	Because we want all Bus Adapters always return 0.
+ *
+ *	Returns 0.
+ */
+static int i2o_bus_probe(struct device *dev)
+{
+	struct i2o_device *i2o_dev = to_i2o_device(get_device(dev));
+
+	device_create_file(dev, &dev_attr_scan);
+
+	osm_info("device added (TID: %03x)\n", i2o_dev->lct_data.tid);
+
+	return 0;
+};
+
+/**
+ *	i2o_bus_remove - remove the I2O Bus Adapter device from the system again
+ *	@dev: I2O Bus Adapter device which should be removed
+ *
+ *	Always returns 0.
+ */
+static int i2o_bus_remove(struct device *dev)
+{
+	struct i2o_device *i2o_dev = to_i2o_device(dev);
+
+	device_remove_file(dev, &dev_attr_scan);
+
+	put_device(dev);
+
+	osm_info("device removed (TID: %03x)\n", i2o_dev->lct_data.tid);
+
+	return 0;
+};
+
+/* Bus Adapter OSM driver struct */
+static struct i2o_driver i2o_bus_driver = {
+	.name = OSM_NAME,
+	.classes = i2o_bus_class_id,
+	.driver = {
+		   .probe = i2o_bus_probe,
+		   .remove = i2o_bus_remove,
+		   },
+};
+
+/**
+ *	i2o_bus_init - Bus Adapter OSM initialization function
+ *
+ *	Only register the Bus Adapter OSM in the I2O core.
+ *
+ *	Returns 0 on success or negative error code on failure.
+ */
+static int __init i2o_bus_init(void)
+{
+	int rc;
+
+	printk(KERN_INFO OSM_DESCRIPTION " v" OSM_VERSION "\n");
+
+	/* Register Bus Adapter OSM into I2O core */
+	rc = i2o_driver_register(&i2o_bus_driver);
+	if (rc) {
+		osm_err("Could not register Bus Adapter OSM\n");
+		return rc;
+	}
+
+	return 0;
+};
+
+/**
+ *	i2o_bus_exit - Bus Adapter OSM exit function
+ *
+ *	Unregisters Bus Adapter OSM from I2O core.
+ */
+static void __exit i2o_bus_exit(void)
+{
+	i2o_driver_unregister(&i2o_bus_driver);
+};
+
+MODULE_AUTHOR("Markus Lidel <Markus.Lidel@shadowconnect.com>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION(OSM_DESCRIPTION);
+MODULE_VERSION(OSM_VERSION);
+
+module_init(i2o_bus_init);
+module_exit(i2o_bus_exit);
diff --git a/drivers/message/i2o/config-osm.c b/drivers/message/i2o/config-osm.c
new file mode 100644
--- /dev/null
+++ b/drivers/message/i2o/config-osm.c
@@ -0,0 +1,87 @@
+/*
+ *	Configuration OSM
+ *
+ *	Copyright (C) 2005	Markus Lidel <Markus.Lidel@shadowconnect.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.
+ *
+ *	Fixes/additions:
+ *		Markus Lidel <Markus.Lidel@shadowconnect.com>
+ *			initial version.
+ */
+
+#include <linux/module.h>
+#include <linux/i2o.h>
+#include <linux/dcache.h>
+#include <linux/namei.h>
+#include <linux/fs.h>
+
+#include <asm/uaccess.h>
+
+#define OSM_NAME	"config-osm"
+#define OSM_VERSION	"1.248"
+#define OSM_DESCRIPTION	"I2O Configuration OSM"
+
+/* access mode user rw */
+#define S_IWRSR (S_IRUSR | S_IWUSR)
+
+static struct i2o_driver i2o_config_driver;
+
+/* Config OSM driver struct */
+static struct i2o_driver i2o_config_driver = {
+	.name = OSM_NAME,
+};
+
+#ifdef CONFIG_I2O_CONFIG_OLD_IOCTL
+#include "i2o_config.c"
+#endif
+
+/**
+ *	i2o_config_init - Configuration OSM initialization function
+ *
+ *	Registers Configuration OSM in the I2O core and if old ioctl's are
+ *	compiled in initialize them.
+ *
+ *	Returns 0 on success or negative error code on failure.
+ */
+static int __init i2o_config_init(void)
+{
+	printk(KERN_INFO OSM_DESCRIPTION " v" OSM_VERSION "\n");
+
+	if (i2o_driver_register(&i2o_config_driver)) {
+		osm_err("handler register failed.\n");
+		return -EBUSY;
+	}
+#ifdef CONFIG_I2O_CONFIG_OLD_IOCTL
+	if (i2o_config_old_init())
+		i2o_driver_unregister(&i2o_config_driver);
+#endif
+
+	return 0;
+}
+
+/**
+ *	i2o_config_exit - Configuration OSM exit function
+ *
+ *	If old ioctl's are compiled in exit remove them and unregisters
+ *	Configuration OSM from I2O core.
+ */
+static void i2o_config_exit(void)
+{
+#ifdef CONFIG_I2O_CONFIG_OLD_IOCTL
+	i2o_config_old_exit();
+#endif
+
+	i2o_driver_unregister(&i2o_config_driver);
+}
+
+MODULE_AUTHOR("Markus Lidel <Markus.Lidel@shadowconnect.com>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION(OSM_DESCRIPTION);
+MODULE_VERSION(OSM_VERSION);
+
+module_init(i2o_config_init);
+module_exit(i2o_config_exit);
diff --git a/drivers/message/i2o/core.h b/drivers/message/i2o/core.h
new file mode 100644
--- /dev/null
+++ b/drivers/message/i2o/core.h
@@ -0,0 +1,58 @@
+/*
+ *	I2O core internal declarations
+ *
+ *	Copyright (C) 2005	Markus Lidel <Markus.Lidel@shadowconnect.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.
+ *
+ *	Fixes/additions:
+ *		Markus Lidel <Markus.Lidel@shadowconnect.com>
+ *			initial version.
+ */
+
+/* Exec-OSM */
+extern struct bus_type i2o_bus_type;
+
+extern struct i2o_driver i2o_exec_driver;
+extern int i2o_exec_lct_get(struct i2o_controller *);
+
+extern int __init i2o_exec_init(void);
+extern void __exit i2o_exec_exit(void);
+
+/* driver */
+extern int i2o_driver_dispatch(struct i2o_controller *, u32);
+
+extern int __init i2o_driver_init(void);
+extern void __exit i2o_driver_exit(void);
+
+/* PCI */
+extern int __init i2o_pci_init(void);
+extern void __exit i2o_pci_exit(void);
+
+/* device */
+extern void i2o_device_remove(struct i2o_device *);
+extern int i2o_device_parse_lct(struct i2o_controller *);
+
+extern int i2o_device_init(void);
+extern void i2o_device_exit(void);
+
+/* IOP */
+extern struct i2o_controller *i2o_iop_alloc(void);
+extern void i2o_iop_free(struct i2o_controller *);
+
+extern int i2o_iop_add(struct i2o_controller *);
+extern void i2o_iop_remove(struct i2o_controller *);
+
+/* config */
+extern int i2o_parm_issue(struct i2o_device *, int, void *, int, void *, int);
+
+/* control registers relative to c->base */
+#define I2O_IRQ_STATUS	0x30
+#define I2O_IRQ_MASK	0x34
+#define I2O_IN_PORT	0x40
+#define I2O_OUT_PORT	0x44
+
+#define I2O_IRQ_OUTBOUND_POST	0x00000008
diff --git a/drivers/message/i2o/debug.c b/drivers/message/i2o/debug.c
--- a/drivers/message/i2o/debug.c
+++ b/drivers/message/i2o/debug.c
@@ -4,8 +4,6 @@
 #include <linux/pci.h>
 #include <linux/i2o.h>
 
-extern struct i2o_driver **i2o_drivers;
-extern unsigned int i2o_max_drivers;
 static void i2o_report_util_cmd(u8 cmd);
 static void i2o_report_exec_cmd(u8 cmd);
 static void i2o_report_fail_status(u8 req_status, u32 * msg);
@@ -23,7 +21,6 @@ void i2o_report_status(const char *sever
 	u8 cmd = (msg[1] >> 24) & 0xFF;
 	u8 req_status = (msg[4] >> 24) & 0xFF;
 	u16 detailed_status = msg[4] & 0xFFFF;
-	//struct i2o_driver *h = i2o_drivers[msg[2] & (i2o_max_drivers-1)];
 
 	if (cmd == I2O_CMD_UTIL_EVT_REGISTER)
 		return;		// No status in this reply
diff --git a/drivers/message/i2o/device.c b/drivers/message/i2o/device.c
--- a/drivers/message/i2o/device.c
+++ b/drivers/message/i2o/device.c
@@ -16,9 +16,7 @@
 #include <linux/module.h>
 #include <linux/i2o.h>
 #include <linux/delay.h>
-
-/* Exec OSM functions */
-extern struct bus_type i2o_bus_type;
+#include "core.h"
 
 /**
  *	i2o_device_issue_claim - claim or release a device
@@ -282,8 +280,7 @@ int i2o_device_parse_lct(struct i2o_cont
 
 	down(&c->lct_lock);
 
-	if (c->lct)
-		kfree(c->lct);
+	kfree(c->lct);
 
 	lct = c->dlct.virt;
 
@@ -294,12 +291,12 @@ int i2o_device_parse_lct(struct i2o_cont
 	}
 
 	if (lct->table_size * 4 > c->dlct.len) {
-		memcpy_fromio(c->lct, c->dlct.virt, c->dlct.len);
+		memcpy(c->lct, c->dlct.virt, c->dlct.len);
 		up(&c->lct_lock);
 		return -EAGAIN;
 	}
 
-	memcpy_fromio(c->lct, c->dlct.virt, lct->table_size * 4);
+	memcpy(c->lct, c->dlct.virt, lct->table_size * 4);
 
 	lct = c->lct;
 
@@ -354,7 +351,7 @@ static ssize_t i2o_device_class_show_cla
 {
 	struct i2o_device *dev = to_i2o_device(cd->dev);
 
-	sprintf(buf, "%03x\n", dev->lct_data.class_id);
+	sprintf(buf, "0x%03x\n", dev->lct_data.class_id);
 	return strlen(buf) + 1;
 };
 
@@ -369,7 +366,7 @@ static ssize_t i2o_device_class_show_tid
 {
 	struct i2o_device *dev = to_i2o_device(cd->dev);
 
-	sprintf(buf, "%03x\n", dev->lct_data.tid);
+	sprintf(buf, "0x%03x\n", dev->lct_data.tid);
 	return strlen(buf) + 1;
 };
 
@@ -401,25 +398,27 @@ static int i2o_device_class_add(struct c
 
 	/* create user entries for this device */
 	tmp = i2o_iop_find_device(i2o_dev->iop, i2o_dev->lct_data.user_tid);
-	if (tmp)
+	if (tmp && (tmp != i2o_dev))
 		sysfs_create_link(&i2o_dev->device.kobj, &tmp->device.kobj,
 				  "user");
 
 	/* create user entries refering to this device */
 	list_for_each_entry(tmp, &c->devices, list)
-	    if (tmp->lct_data.user_tid == i2o_dev->lct_data.tid)
+	    if ((tmp->lct_data.user_tid == i2o_dev->lct_data.tid)
+		&& (tmp != i2o_dev))
 		sysfs_create_link(&tmp->device.kobj,
 				  &i2o_dev->device.kobj, "user");
 
 	/* create parent entries for this device */
 	tmp = i2o_iop_find_device(i2o_dev->iop, i2o_dev->lct_data.parent_tid);
-	if (tmp)
+	if (tmp && (tmp != i2o_dev))
 		sysfs_create_link(&i2o_dev->device.kobj, &tmp->device.kobj,
 				  "parent");
 
 	/* create parent entries refering to this device */
 	list_for_each_entry(tmp, &c->devices, list)
-	    if (tmp->lct_data.parent_tid == i2o_dev->lct_data.tid)
+	    if ((tmp->lct_data.parent_tid == i2o_dev->lct_data.tid)
+		&& (tmp != i2o_dev))
 		sysfs_create_link(&tmp->device.kobj,
 				  &i2o_dev->device.kobj, "parent");
 
@@ -444,9 +443,8 @@ static struct class_interface i2o_device
  *	Note that the minimum sized reslist is 8 bytes and contains
  *	ResultCount, ErrorInfoSize, BlockStatus and BlockSize.
  */
-
 int i2o_parm_issue(struct i2o_device *i2o_dev, int cmd, void *oplist,
-		   int oplen, void *reslist, int reslen)
+			  int oplen, void *reslist, int reslen)
 {
 	struct i2o_message __iomem *msg;
 	u32 m;
@@ -489,7 +487,7 @@ int i2o_parm_issue(struct i2o_device *i2
 	if (rc == -ETIMEDOUT)
 		return rc;
 
-	memcpy_fromio(reslist, res.virt, res.len);
+	memcpy(reslist, res.virt, res.len);
 	i2o_dma_free(dev, &res);
 
 	/* Query failed */
@@ -531,17 +529,23 @@ int i2o_parm_field_get(struct i2o_device
 		       void *buf, int buflen)
 {
 	u16 opblk[] = { 1, 0, I2O_PARAMS_FIELD_GET, group, 1, field };
-	u8 resblk[8 + buflen];	/* 8 bytes for header */
+	u8 *resblk;		/* 8 bytes for header */
 	int size;
 
 	if (field == -1)	/* whole group */
 		opblk[4] = -1;
 
+	resblk = kmalloc(buflen + 8, GFP_KERNEL | GFP_ATOMIC);
+	if (!resblk)
+		return -ENOMEM;
+
 	size = i2o_parm_issue(i2o_dev, I2O_CMD_UTIL_PARAMS_GET, opblk,
-			      sizeof(opblk), resblk, sizeof(resblk));
+			      sizeof(opblk), resblk, buflen + 8);
 
 	memcpy(buf, resblk + 8, buflen);	/* cut off header */
 
+	kfree(resblk);
+
 	if (size > buflen)
 		return buflen;
 
diff --git a/drivers/message/i2o/driver.c b/drivers/message/i2o/driver.c
--- a/drivers/message/i2o/driver.c
+++ b/drivers/message/i2o/driver.c
@@ -17,9 +17,12 @@
 #include <linux/module.h>
 #include <linux/rwsem.h>
 #include <linux/i2o.h>
+#include "core.h"
+
+#define OSM_NAME	"i2o"
 
 /* max_drivers - Maximum I2O drivers (OSMs) which could be registered */
-unsigned int i2o_max_drivers = I2O_MAX_DRIVERS;
+static unsigned int i2o_max_drivers = I2O_MAX_DRIVERS;
 module_param_named(max_drivers, i2o_max_drivers, uint, 0);
 MODULE_PARM_DESC(max_drivers, "maximum number of OSM's to support");
 
@@ -76,17 +79,16 @@ int i2o_driver_register(struct i2o_drive
 	int rc = 0;
 	unsigned long flags;
 
-	pr_debug("i2o: Register driver %s\n", drv->name);
+	osm_debug("Register driver %s\n", drv->name);
 
 	if (drv->event) {
 		drv->event_queue = create_workqueue(drv->name);
 		if (!drv->event_queue) {
-			printk(KERN_ERR "i2o: Could not initialize event queue "
-			       "for driver %s\n", drv->name);
+			osm_err("Could not initialize event queue for driver "
+				"%s\n", drv->name);
 			return -EFAULT;
 		}
-		pr_debug("i2o: Event queue initialized for driver %s\n",
-			 drv->name);
+		osm_debug("Event queue initialized for driver %s\n", drv->name);
 	} else
 		drv->event_queue = NULL;
 
@@ -97,8 +99,8 @@ int i2o_driver_register(struct i2o_drive
 
 	for (i = 0; i2o_drivers[i]; i++)
 		if (i >= i2o_max_drivers) {
-			printk(KERN_ERR "i2o: too many drivers registered, "
-			       "increase max_drivers\n");
+			osm_err("too many drivers registered, increase "
+				"max_drivers\n");
 			spin_unlock_irqrestore(&i2o_drivers_lock, flags);
 			return -EFAULT;
 		}
@@ -108,18 +110,16 @@ int i2o_driver_register(struct i2o_drive
 
 	spin_unlock_irqrestore(&i2o_drivers_lock, flags);
 
-	pr_debug("i2o: driver %s gets context id %d\n", drv->name,
-		 drv->context);
+	osm_debug("driver %s gets context id %d\n", drv->name, drv->context);
 
 	list_for_each_entry(c, &i2o_controllers, list) {
 		struct i2o_device *i2o_dev;
 
 		i2o_driver_notify_controller_add(drv, c);
 		list_for_each_entry(i2o_dev, &c->devices, list)
-			i2o_driver_notify_device_add(drv, i2o_dev);
+		    i2o_driver_notify_device_add(drv, i2o_dev);
 	}
 
-
 	rc = driver_register(&drv->driver);
 	if (rc)
 		destroy_workqueue(drv->event_queue);
@@ -139,7 +139,7 @@ void i2o_driver_unregister(struct i2o_dr
 	struct i2o_controller *c;
 	unsigned long flags;
 
-	pr_debug("i2o: unregister driver %s\n", drv->name);
+	osm_debug("unregister driver %s\n", drv->name);
 
 	driver_unregister(&drv->driver);
 
@@ -159,7 +159,7 @@ void i2o_driver_unregister(struct i2o_dr
 	if (drv->event_queue) {
 		destroy_workqueue(drv->event_queue);
 		drv->event_queue = NULL;
-		pr_debug("i2o: event queue removed for %s\n", drv->name);
+		osm_debug("event queue removed for %s\n", drv->name);
 	}
 };
 
@@ -176,68 +176,70 @@ void i2o_driver_unregister(struct i2o_dr
  *	on success and if the message should be flushed afterwords. Returns
  *	negative error code on failure (the message will be flushed too).
  */
-int i2o_driver_dispatch(struct i2o_controller *c, u32 m,
-			struct i2o_message __iomem *msg)
+int i2o_driver_dispatch(struct i2o_controller *c, u32 m)
 {
 	struct i2o_driver *drv;
-	u32 context = readl(&msg->u.s.icntxt);
+	struct i2o_message *msg = i2o_msg_out_to_virt(c, m);
+	u32 context = le32_to_cpu(msg->u.s.icntxt);
+	unsigned long flags;
+
+	if (unlikely(context >= i2o_max_drivers)) {
+		osm_warn("%s: Spurious reply to unknown driver %d\n", c->name,
+			 context);
+		return -EIO;
+	}
+
+	spin_lock_irqsave(&i2o_drivers_lock, flags);
+	drv = i2o_drivers[context];
+	spin_unlock_irqrestore(&i2o_drivers_lock, flags);
+
+	if (unlikely(!drv)) {
+		osm_warn("%s: Spurious reply to unknown driver %d\n", c->name,
+			 context);
+		return -EIO;
+	}
+
+	if ((le32_to_cpu(msg->u.head[1]) >> 24) == I2O_CMD_UTIL_EVT_REGISTER) {
+		struct i2o_device *dev, *tmp;
+		struct i2o_event *evt;
+		u16 size;
+		u16 tid = le32_to_cpu(msg->u.head[1]) & 0xfff;
 
-	if (likely(context < i2o_max_drivers)) {
-		spin_lock(&i2o_drivers_lock);
-		drv = i2o_drivers[context];
-		spin_unlock(&i2o_drivers_lock);
-
-		if (unlikely(!drv)) {
-			printk(KERN_WARNING "%s: Spurious reply to unknown "
-			       "driver %d\n", c->name, context);
+		osm_debug("event received from device %d\n", tid);
+
+		if (!drv->event)
 			return -EIO;
-		}
 
-		if ((readl(&msg->u.head[1]) >> 24) == I2O_CMD_UTIL_EVT_REGISTER) {
-			struct i2o_device *dev, *tmp;
-			struct i2o_event *evt;
-			u16 size;
-			u16 tid;
-
-			tid = readl(&msg->u.head[1]) & 0x1fff;
-
-			pr_debug("%s: event received from device %d\n", c->name,
-				 tid);
-
-			/* cut of header from message size (in 32-bit words) */
-			size = (readl(&msg->u.head[0]) >> 16) - 5;
-
-			evt = kmalloc(size * 4 + sizeof(*evt), GFP_ATOMIC);
-			if (!evt)
-				return -ENOMEM;
-			memset(evt, 0, size * 4 + sizeof(*evt));
-
-			evt->size = size;
-			memcpy_fromio(&evt->tcntxt, &msg->u.s.tcntxt,
-				      (size + 2) * 4);
-
-			list_for_each_entry_safe(dev, tmp, &c->devices, list)
-			    if (dev->lct_data.tid == tid) {
-				evt->i2o_dev = dev;
-				break;
-			}
-
-			INIT_WORK(&evt->work, (void (*)(void *))drv->event,
-				  evt);
-			queue_work(drv->event_queue, &evt->work);
-			return 1;
+		/* cut of header from message size (in 32-bit words) */
+		size = (le32_to_cpu(msg->u.head[0]) >> 16) - 5;
+
+		evt = kmalloc(size * 4 + sizeof(*evt), GFP_ATOMIC | __GFP_ZERO);
+		if (!evt)
+			return -ENOMEM;
+
+		evt->size = size;
+		evt->tcntxt = le32_to_cpu(msg->u.s.tcntxt);
+		evt->event_indicator = le32_to_cpu(msg->body[0]);
+		memcpy(&evt->tcntxt, &msg->u.s.tcntxt, size * 4);
+
+		list_for_each_entry_safe(dev, tmp, &c->devices, list)
+		    if (dev->lct_data.tid == tid) {
+			evt->i2o_dev = dev;
+			break;
 		}
 
-		if (likely(drv->reply))
-			return drv->reply(c, m, msg);
-		else
-			pr_debug("%s: Reply to driver %s, but no reply function"
-				 " defined!\n", c->name, drv->name);
+		INIT_WORK(&evt->work, (void (*)(void *))drv->event, evt);
+		queue_work(drv->event_queue, &evt->work);
+		return 1;
+	}
+
+	if (unlikely(!drv->reply)) {
+		osm_debug("%s: Reply to driver %s, but no reply function"
+			  " defined!\n", c->name, drv->name);
 		return -EIO;
-	} else
-		printk(KERN_WARNING "%s: Spurious reply to unknown driver "
-		       "%d\n", c->name, readl(&msg->u.s.icntxt));
-	return -EIO;
+	}
+
+	return drv->reply(c, m, msg);
 }
 
 /**
@@ -334,11 +336,11 @@ int __init i2o_driver_init(void)
 	if ((i2o_max_drivers < 2) || (i2o_max_drivers > 64) ||
 	    ((i2o_max_drivers ^ (i2o_max_drivers - 1)) !=
 	     (2 * i2o_max_drivers - 1))) {
-		printk(KERN_WARNING "i2o: max_drivers set to %d, but must be "
-		       ">=2 and <= 64 and a power of 2\n", i2o_max_drivers);
+		osm_warn("max_drivers set to %d, but must be >=2 and <= 64 and "
+			 "a power of 2\n", i2o_max_drivers);
 		i2o_max_drivers = I2O_MAX_DRIVERS;
 	}
-	printk(KERN_INFO "i2o: max drivers = %d\n", i2o_max_drivers);
+	osm_info("max drivers = %d\n", i2o_max_drivers);
 
 	i2o_drivers =
 	    kmalloc(i2o_max_drivers * sizeof(*i2o_drivers), GFP_KERNEL);
diff --git a/drivers/message/i2o/exec-osm.c b/drivers/message/i2o/exec-osm.c
--- a/drivers/message/i2o/exec-osm.c
+++ b/drivers/message/i2o/exec-osm.c
@@ -30,6 +30,7 @@
 #include <linux/module.h>
 #include <linux/i2o.h>
 #include <linux/delay.h>
+#include "core.h"
 
 #define OSM_NAME "exec-osm"
 
@@ -37,9 +38,6 @@ struct i2o_driver i2o_exec_driver;
 
 static int i2o_exec_lct_notify(struct i2o_controller *c, u32 change_ind);
 
-/* Module internal functions from other sources */
-extern int i2o_device_parse_lct(struct i2o_controller *);
-
 /* global wait list for POST WAIT */
 static LIST_HEAD(i2o_exec_wait_list);
 
@@ -50,7 +48,7 @@ struct i2o_exec_wait {
 	u32 tcntxt;		/* transaction context from reply */
 	int complete;		/* 1 if reply received otherwise 0 */
 	u32 m;			/* message id */
-	struct i2o_message __iomem *msg;	/* pointer to the reply message */
+	struct i2o_message *msg;	/* pointer to the reply message */
 	struct list_head list;	/* node in global wait list */
 };
 
@@ -108,7 +106,8 @@ static void i2o_exec_wait_free(struct i2
  *	buffer must not be freed. Instead the event completion will free them
  *	for you. In all other cases the buffer are your problem.
  *
- *	Returns 0 on success or negative error code on failure.
+ *	Returns 0 on success, negative error code on timeout or positive error
+ *	code from reply.
  */
 int i2o_msg_post_wait_mem(struct i2o_controller *c, u32 m, unsigned long
 			  timeout, struct i2o_dma *dma)
@@ -116,7 +115,7 @@ int i2o_msg_post_wait_mem(struct i2o_con
 	DECLARE_WAIT_QUEUE_HEAD(wq);
 	struct i2o_exec_wait *wait;
 	static u32 tcntxt = 0x80000000;
-	struct i2o_message __iomem *msg = c->in_queue.virt + m;
+	struct i2o_message __iomem *msg = i2o_msg_in_to_virt(c, m);
 	int rc = 0;
 
 	wait = i2o_exec_wait_alloc();
@@ -153,7 +152,7 @@ int i2o_msg_post_wait_mem(struct i2o_con
 		list_add(&wait->list, &i2o_exec_wait_list);
 
 		wait_event_interruptible_timeout(wq, wait->complete,
-			timeout * HZ);
+						 timeout * HZ);
 
 		wait->wq = NULL;
 	}
@@ -161,8 +160,7 @@ int i2o_msg_post_wait_mem(struct i2o_con
 	barrier();
 
 	if (wait->complete) {
-		if (readl(&wait->msg->body[0]) >> 24)
-			rc = readl(&wait->msg->body[0]) & 0xff;
+		rc = le32_to_cpu(wait->msg->body[0]) >> 24;
 		i2o_flush_reply(c, wait->m);
 		i2o_exec_wait_free(wait);
 	} else {
@@ -187,6 +185,7 @@ int i2o_msg_post_wait_mem(struct i2o_con
  *	@c: I2O controller which answers
  *	@m: message id
  *	@msg: pointer to the I2O reply message
+ *	@context: transaction context of request
  *
  *	This function is called in interrupt context only. If the reply reached
  *	before the timeout, the i2o_exec_wait struct is filled with the message
@@ -201,16 +200,12 @@ int i2o_msg_post_wait_mem(struct i2o_con
  *	message must also be given back to the controller.
  */
 static int i2o_msg_post_wait_complete(struct i2o_controller *c, u32 m,
-				      struct i2o_message __iomem *msg)
+				      struct i2o_message *msg, u32 context)
 {
 	struct i2o_exec_wait *wait, *tmp;
-	static spinlock_t lock;
+	unsigned long flags;
+	static spinlock_t lock = SPIN_LOCK_UNLOCKED;
 	int rc = 1;
-	u32 context;
-
-	spin_lock_init(&lock);
-
-	context = readl(&msg->u.s.tcntxt);
 
 	/*
 	 * We need to search through the i2o_exec_wait_list to see if the given
@@ -219,11 +214,13 @@ static int i2o_msg_post_wait_complete(st
 	 * already expired. Not much we can do about that except log it for
 	 * debug purposes, increase timeout, and recompile.
 	 */
-	spin_lock(&lock);
+	spin_lock_irqsave(&lock, flags);
 	list_for_each_entry_safe(wait, tmp, &i2o_exec_wait_list, list) {
 		if (wait->tcntxt == context) {
 			list_del(&wait->list);
 
+			spin_unlock_irqrestore(&lock, flags);
+
 			wait->m = m;
 			wait->msg = msg;
 			wait->complete = 1;
@@ -245,21 +242,63 @@ static int i2o_msg_post_wait_complete(st
 				rc = -1;
 			}
 
-			spin_unlock(&lock);
-
 			return rc;
 		}
 	}
 
-	spin_unlock(&lock);
+	spin_unlock_irqrestore(&lock, flags);
 
-	pr_debug("%s: Bogus reply in POST WAIT (tr-context: %08x)!\n", c->name,
+	osm_warn("%s: Bogus reply in POST WAIT (tr-context: %08x)!\n", c->name,
 		 context);
 
 	return -1;
 };
 
 /**
+ *	i2o_exec_show_vendor_id - Displays Vendor ID of controller
+ *	@d: device of which the Vendor ID should be displayed
+ *	@buf: buffer into which the Vendor ID should be printed
+ *
+ *	Returns number of bytes printed into buffer.
+ */
+static ssize_t i2o_exec_show_vendor_id(struct device *d, struct device_attribute *attr, char *buf)
+{
+	struct i2o_device *dev = to_i2o_device(d);
+	u16 id;
+
+	if (i2o_parm_field_get(dev, 0x0000, 0, &id, 2)) {
+		sprintf(buf, "0x%04x", id);
+		return strlen(buf) + 1;
+	}
+
+	return 0;
+};
+
+/**
+ *	i2o_exec_show_product_id - Displays Product ID of controller
+ *	@d: device of which the Product ID should be displayed
+ *	@buf: buffer into which the Product ID should be printed
+ *
+ *	Returns number of bytes printed into buffer.
+ */
+static ssize_t i2o_exec_show_product_id(struct device *d, struct device_attribute *attr, char *buf)
+{
+	struct i2o_device *dev = to_i2o_device(d);
+	u16 id;
+
+	if (i2o_parm_field_get(dev, 0x0000, 1, &id, 2)) {
+		sprintf(buf, "0x%04x", id);
+		return strlen(buf) + 1;
+	}
+
+	return 0;
+};
+
+/* Exec-OSM device attributes */
+static DEVICE_ATTR(vendor_id, S_IRUGO, i2o_exec_show_vendor_id, NULL);
+static DEVICE_ATTR(product_id, S_IRUGO, i2o_exec_show_product_id, NULL);
+
+/**
  *	i2o_exec_probe - Called if a new I2O device (executive class) appears
  *	@dev: I2O device which should be probed
  *
@@ -271,10 +310,16 @@ static int i2o_msg_post_wait_complete(st
 static int i2o_exec_probe(struct device *dev)
 {
 	struct i2o_device *i2o_dev = to_i2o_device(dev);
+	struct i2o_controller *c = i2o_dev->iop;
 
 	i2o_event_register(i2o_dev, &i2o_exec_driver, 0, 0xffffffff);
 
-	i2o_dev->iop->exec = i2o_dev;
+	c->exec = i2o_dev;
+
+	i2o_exec_lct_notify(c, c->lct->change_ind + 1);
+
+	device_create_file(dev, &dev_attr_vendor_id);
+	device_create_file(dev, &dev_attr_product_id);
 
 	return 0;
 };
@@ -289,6 +334,9 @@ static int i2o_exec_probe(struct device 
  */
 static int i2o_exec_remove(struct device *dev)
 {
+	device_remove_file(dev, &dev_attr_product_id);
+	device_remove_file(dev, &dev_attr_vendor_id);
+
 	i2o_event_register(to_i2o_device(dev), &i2o_exec_driver, 0, 0);
 
 	return 0;
@@ -300,12 +348,16 @@ static int i2o_exec_remove(struct device
  *
  *	This function handles asynchronus LCT NOTIFY replies. It parses the
  *	new LCT and if the buffer for the LCT was to small sends a LCT NOTIFY
- *	again.
+ *	again, otherwise send LCT NOTIFY to get informed on next LCT change.
  */
 static void i2o_exec_lct_modified(struct i2o_controller *c)
 {
-	if (i2o_device_parse_lct(c) == -EAGAIN)
-		i2o_exec_lct_notify(c, 0);
+	u32 change_ind = 0;
+
+	if (i2o_device_parse_lct(c) != -EAGAIN)
+		change_ind = c->lct->change_ind + 1;
+
+	i2o_exec_lct_notify(c, change_ind);
 };
 
 /**
@@ -325,8 +377,14 @@ static void i2o_exec_lct_modified(struct
 static int i2o_exec_reply(struct i2o_controller *c, u32 m,
 			  struct i2o_message *msg)
 {
-	if (le32_to_cpu(msg->u.head[0]) & MSG_FAIL) {	// Fail bit is set
-		struct i2o_message __iomem *pmsg;	/* preserved message */
+	u32 context;
+
+	if (le32_to_cpu(msg->u.head[0]) & MSG_FAIL) {
+		/*
+		 * If Fail bit is set we must take the transaction context of
+		 * the preserved message to find the right request again.
+		 */
+		struct i2o_message __iomem *pmsg;
 		u32 pm;
 
 		pm = le32_to_cpu(msg->body[3]);
@@ -335,15 +393,15 @@ static int i2o_exec_reply(struct i2o_con
 
 		i2o_report_status(KERN_INFO, "i2o_core", msg);
 
-		/* Release the preserved msg by resubmitting it as a NOP */
-		i2o_msg_nop(c, pm);
+		context = readl(&pmsg->u.s.tcntxt);
 
-		/* If reply to i2o_post_wait failed, return causes a timeout */
-		return -1;
-	}
+		/* Release the preserved msg */
+		i2o_msg_nop(c, pm);
+	} else
+		context = le32_to_cpu(msg->u.s.tcntxt);
 
-	if (le32_to_cpu(msg->u.s.tcntxt) & 0x80000000)
-		return i2o_msg_post_wait_complete(c, m, msg);
+	if (context & 0x80000000)
+		return i2o_msg_post_wait_complete(c, m, msg, context);
 
 	if ((le32_to_cpu(msg->u.head[1]) >> 24) == I2O_CMD_LCT_NOTIFY) {
 		struct work_struct *work;
@@ -381,8 +439,9 @@ static int i2o_exec_reply(struct i2o_con
  */
 static void i2o_exec_event(struct i2o_event *evt)
 {
-	osm_info("Event received from device: %d\n",
-		 evt->i2o_dev->lct_data.tid);
+	if (likely(evt->i2o_dev))
+		osm_debug("Event received from device: %d\n",
+			  evt->i2o_dev->lct_data.tid);
 	kfree(evt);
 };
 
diff --git a/drivers/message/i2o/i2o_block.c b/drivers/message/i2o/i2o_block.c
--- a/drivers/message/i2o/i2o_block.c
+++ b/drivers/message/i2o/i2o_block.c
@@ -62,7 +62,7 @@
 #include "i2o_block.h"
 
 #define OSM_NAME	"block-osm"
-#define OSM_VERSION	"$Rev$"
+#define OSM_VERSION	"1.287"
 #define OSM_DESCRIPTION	"I2O Block Device OSM"
 
 static struct i2o_driver i2o_block_driver;
@@ -104,7 +104,8 @@ static int i2o_block_remove(struct devic
 	struct i2o_device *i2o_dev = to_i2o_device(dev);
 	struct i2o_block_device *i2o_blk_dev = dev_get_drvdata(dev);
 
-	osm_info("Device removed %s\n", i2o_blk_dev->gd->disk_name);
+	osm_info("device removed (TID: %03x): %s\n", i2o_dev->lct_data.tid,
+		 i2o_blk_dev->gd->disk_name);
 
 	i2o_event_register(i2o_dev, &i2o_block_driver, 0, 0);
 
@@ -146,6 +147,29 @@ static int i2o_block_device_flush(struct
 };
 
 /**
+ *	i2o_block_issue_flush - device-flush interface for block-layer
+ *	@queue: the request queue of the device which should be flushed
+ *	@disk: gendisk
+ *	@error_sector: error offset
+ *
+ *	Helper function to provide flush functionality to block-layer.
+ *
+ *	Returns 0 on success or negative error code on failure.
+ */
+
+static int i2o_block_issue_flush(request_queue_t * queue, struct gendisk *disk,
+				 sector_t * error_sector)
+{
+	struct i2o_block_device *i2o_blk_dev = queue->queuedata;
+	int rc = -ENODEV;
+
+	if (likely(i2o_blk_dev))
+		rc = i2o_block_device_flush(i2o_blk_dev->i2o_dev);
+
+	return rc;
+}
+
+/**
  *	i2o_block_device_mount - Mount (load) the media of device dev
  *	@dev: I2O device which should receive the mount request
  *	@media_id: Media Identifier
@@ -298,28 +322,31 @@ static inline void i2o_block_request_fre
 
 /**
  *	i2o_block_sglist_alloc - Allocate the SG list and map it
+ *	@c: I2O controller to which the request belongs
  *	@ireq: I2O block request
  *
- *	Builds the SG list and map it into to be accessable by the controller.
+ *	Builds the SG list and map it to be accessable by the controller.
  *
- *	Returns the number of elements in the SG list or 0 on failure.
+ *	Returns 0 on failure or 1 on success.
  */
-static inline int i2o_block_sglist_alloc(struct i2o_block_request *ireq)
+static inline int i2o_block_sglist_alloc(struct i2o_controller *c,
+					 struct i2o_block_request *ireq,
+					 u32 __iomem ** mptr)
 {
-	struct device *dev = &ireq->i2o_blk_dev->i2o_dev->iop->pdev->dev;
 	int nents;
+	enum dma_data_direction direction;
 
+	ireq->dev = &c->pdev->dev;
 	nents = blk_rq_map_sg(ireq->req->q, ireq->req, ireq->sg_table);
 
 	if (rq_data_dir(ireq->req) == READ)
-		ireq->sg_dma_direction = PCI_DMA_FROMDEVICE;
+		direction = PCI_DMA_FROMDEVICE;
 	else
-		ireq->sg_dma_direction = PCI_DMA_TODEVICE;
+		direction = PCI_DMA_TODEVICE;
 
-	ireq->sg_nents = dma_map_sg(dev, ireq->sg_table, nents,
-				    ireq->sg_dma_direction);
+	ireq->sg_nents = nents;
 
-	return ireq->sg_nents;
+	return i2o_dma_map_sg(c, ireq->sg_table, nents, direction, mptr);
 };
 
 /**
@@ -330,10 +357,14 @@ static inline int i2o_block_sglist_alloc
  */
 static inline void i2o_block_sglist_free(struct i2o_block_request *ireq)
 {
-	struct device *dev = &ireq->i2o_blk_dev->i2o_dev->iop->pdev->dev;
+	enum dma_data_direction direction;
 
-	dma_unmap_sg(dev, ireq->sg_table, ireq->sg_nents,
-		     ireq->sg_dma_direction);
+	if (rq_data_dir(ireq->req) == READ)
+		direction = PCI_DMA_FROMDEVICE;
+	else
+		direction = PCI_DMA_TODEVICE;
+
+	dma_unmap_sg(ireq->dev, ireq->sg_table, ireq->sg_nents, direction);
 };
 
 /**
@@ -351,6 +382,11 @@ static int i2o_block_prep_req_fn(struct 
 	struct i2o_block_device *i2o_blk_dev = q->queuedata;
 	struct i2o_block_request *ireq;
 
+	if (unlikely(!i2o_blk_dev)) {
+		osm_err("block device already removed\n");
+		return BLKPREP_KILL;
+	}
+
 	/* request is already processed by us, so return */
 	if (req->flags & REQ_SPECIAL) {
 		osm_debug("REQ_SPECIAL already set!\n");
@@ -400,71 +436,65 @@ static void i2o_block_delayed_request_fn
 };
 
 /**
- *	i2o_block_reply - Block OSM reply handler.
- *	@c: I2O controller from which the message arrives
- *	@m: message id of reply
- *	qmsg: the actuall I2O message reply
+ *	i2o_block_end_request - Post-processing of completed commands
+ *	@req: request which should be completed
+ *	@uptodate: 1 for success, 0 for I/O error, < 0 for specific error
+ *	@nr_bytes: number of bytes to complete
  *
- *	This function gets all the message replies.
+ *	Mark the request as complete. The lock must not be held when entering.
  *
  */
-static int i2o_block_reply(struct i2o_controller *c, u32 m,
-			   struct i2o_message *msg)
+static void i2o_block_end_request(struct request *req, int uptodate,
+				  int nr_bytes)
 {
-	struct i2o_block_request *ireq;
-	struct request *req;
-	struct i2o_block_device *dev;
-	struct request_queue *q;
-	u8 st;
+	struct i2o_block_request *ireq = req->special;
+	struct i2o_block_device *dev = ireq->i2o_blk_dev;
+	request_queue_t *q = req->q;
 	unsigned long flags;
 
-	/* FAILed message */
-	if (unlikely(le32_to_cpu(msg->u.head[0]) & (1 << 13))) {
-		struct i2o_message *pmsg;
-		u32 pm;
-
-		/*
-		 * FAILed message from controller
-		 * We increment the error count and abort it
-		 *
-		 * In theory this will never happen.  The I2O block class
-		 * 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 :)
-		 */
-		pm = le32_to_cpu(msg->body[3]);
-		pmsg = i2o_msg_in_to_virt(c, pm);
+	if (end_that_request_chunk(req, uptodate, nr_bytes)) {
+		int leftover = (req->hard_nr_sectors << KERNEL_SECTOR_SHIFT);
 
-		req = i2o_cntxt_list_get(c, le32_to_cpu(pmsg->u.s.tcntxt));
-		if (unlikely(!req)) {
-			osm_err("NULL reply received!\n");
-			return -1;
-		}
+		if (blk_pc_request(req))
+			leftover = req->data_len;
 
-		ireq = req->special;
-		dev = ireq->i2o_blk_dev;
-		q = dev->gd->queue;
+		if (end_io_error(uptodate))
+			end_that_request_chunk(req, 0, leftover);
+	}
 
-		req->errors++;
+	add_disk_randomness(req->rq_disk);
 
-		spin_lock_irqsave(q->queue_lock, flags);
+	spin_lock_irqsave(q->queue_lock, flags);
 
-		while (end_that_request_chunk(req, !req->errors,
-					      le32_to_cpu(pmsg->body[1]))) ;
-		end_that_request_last(req);
+	end_that_request_last(req);
 
+	if (likely(dev)) {
 		dev->open_queue_depth--;
 		list_del(&ireq->queue);
-		blk_start_queue(q);
+	}
 
-		spin_unlock_irqrestore(q->queue_lock, flags);
+	blk_start_queue(q);
 
-		/* Now flush the message by making it a NOP */
-		i2o_msg_nop(c, pm);
+	spin_unlock_irqrestore(q->queue_lock, flags);
 
-		return -1;
-	}
+	i2o_block_sglist_free(ireq);
+	i2o_block_request_free(ireq);
+};
+
+/**
+ *	i2o_block_reply - Block OSM reply handler.
+ *	@c: I2O controller from which the message arrives
+ *	@m: message id of reply
+ *	qmsg: the actuall I2O message reply
+ *
+ *	This function gets all the message replies.
+ *
+ */
+static int i2o_block_reply(struct i2o_controller *c, u32 m,
+			   struct i2o_message *msg)
+{
+	struct request *req;
+	int uptodate = 1;
 
 	req = i2o_cntxt_list_get(c, le32_to_cpu(msg->u.s.tcntxt));
 	if (unlikely(!req)) {
@@ -472,61 +502,13 @@ static int i2o_block_reply(struct i2o_co
 		return -1;
 	}
 
-	ireq = req->special;
-	dev = ireq->i2o_blk_dev;
-	q = dev->gd->queue;
-
-	if (unlikely(!dev->i2o_dev)) {
-		/*
-		 * This is HACK, but Intel Integrated RAID allows user
-		 * to delete a volume that is claimed, locked, and in use
-		 * by the OS. We have to check for a reply from a
-		 * non-existent device and flag it as an error or the system
-		 * goes kaput...
-		 */
-		req->errors++;
-		osm_warn("Data transfer to deleted device!\n");
-		spin_lock_irqsave(q->queue_lock, flags);
-		while (end_that_request_chunk
-		       (req, !req->errors, le32_to_cpu(msg->body[1]))) ;
-		end_that_request_last(req);
-
-		dev->open_queue_depth--;
-		list_del(&ireq->queue);
-		blk_start_queue(q);
-
-		spin_unlock_irqrestore(q->queue_lock, flags);
-		return -1;
-	}
-
 	/*
 	 *      Lets see what is cooking. We stuffed the
 	 *      request in the context.
 	 */
 
-	st = le32_to_cpu(msg->body[0]) >> 24;
-
-	if (st != 0) {
-		int err;
-		char *bsa_errors[] = {
-			"Success",
-			"Media Error",
-			"Failure communicating to device",
-			"Device Failure",
-			"Device is not ready",
-			"Media not present",
-			"Media is locked by another user",
-			"Media has failed",
-			"Failure communicating to device",
-			"Device bus failure",
-			"Device is locked by another user",
-			"Device is write protected",
-			"Device has reset",
-			"Volume has changed, waiting for acknowledgement"
-		};
-
-		err = le32_to_cpu(msg->body[0]) & 0xffff;
-
+	if ((le32_to_cpu(msg->body[0]) >> 24) != 0) {
+		u32 status = le32_to_cpu(msg->body[0]);
 		/*
 		 *      Device not ready means two things. One is that the
 		 *      the thing went offline (but not a removal media)
@@ -539,40 +521,23 @@ static int i2o_block_reply(struct i2o_co
 		 *      Don't stick a supertrak100 into cache aggressive modes
 		 */
 
-		osm_err("block-osm: /dev/%s error: %s", dev->gd->disk_name,
-			bsa_errors[le32_to_cpu(msg->body[0]) & 0xffff]);
-		if (le32_to_cpu(msg->body[0]) & 0x00ff0000)
-			printk(KERN_ERR " - DDM attempted %d retries",
-			       (le32_to_cpu(msg->body[0]) >> 16) & 0x00ff);
-		printk(KERN_ERR ".\n");
-		req->errors++;
-	} else
-		req->errors = 0;
-
-	if (!end_that_request_chunk
-	    (req, !req->errors, le32_to_cpu(msg->body[1]))) {
-		add_disk_randomness(req->rq_disk);
-		spin_lock_irqsave(q->queue_lock, flags);
+		osm_err("TID %03x error status: 0x%02x, detailed status: "
+			"0x%04x\n", (le32_to_cpu(msg->u.head[1]) >> 12 & 0xfff),
+			status >> 24, status & 0xffff);
 
-		end_that_request_last(req);
-
-		dev->open_queue_depth--;
-		list_del(&ireq->queue);
-		blk_start_queue(q);
+		req->errors++;
 
-		spin_unlock_irqrestore(q->queue_lock, flags);
+		uptodate = 0;
+	}
 
-		i2o_block_sglist_free(ireq);
-		i2o_block_request_free(ireq);
-	} else
-		osm_err("still remaining chunks\n");
+	i2o_block_end_request(req, uptodate, le32_to_cpu(msg->body[1]));
 
 	return 1;
 };
 
 static void i2o_block_event(struct i2o_event *evt)
 {
-	osm_info("block-osm: event received\n");
+	osm_debug("event received\n");
 	kfree(evt);
 };
 
@@ -778,18 +743,25 @@ static int i2o_block_media_changed(struc
 static int i2o_block_transfer(struct request *req)
 {
 	struct i2o_block_device *dev = req->rq_disk->private_data;
-	struct i2o_controller *c = dev->i2o_dev->iop;
+	struct i2o_controller *c;
 	int tid = dev->i2o_dev->lct_data.tid;
 	struct i2o_message __iomem *msg;
-	void __iomem *mptr;
+	u32 __iomem *mptr;
 	struct i2o_block_request *ireq = req->special;
-	struct scatterlist *sg;
-	int sgnum;
-	int i;
 	u32 m;
 	u32 tcntxt;
-	u32 sg_flags;
+	u32 sgl_offset = SGL_OFFSET_8;
+	u32 ctl_flags = 0x00000000;
 	int rc;
+	u32 cmd;
+
+	if (unlikely(!dev->i2o_dev)) {
+		osm_err("transfer to removed drive\n");
+		rc = -ENODEV;
+		goto exit;
+	}
+
+	c = dev->i2o_dev->iop;
 
 	m = i2o_msg_get(c, &msg);
 	if (m == I2O_QUEUE_EMPTY) {
@@ -803,82 +775,109 @@ static int i2o_block_transfer(struct req
 		goto nop_msg;
 	}
 
-	if ((sgnum = i2o_block_sglist_alloc(ireq)) <= 0) {
-		rc = -ENOMEM;
-		goto context_remove;
-	}
-
-	/* Build the message based on the request. */
 	writel(i2o_block_driver.context, &msg->u.s.icntxt);
 	writel(tcntxt, &msg->u.s.tcntxt);
-	writel(req->nr_sectors << 9, &msg->body[1]);
-
-	writel((((u64) req->sector) << 9) & 0xffffffff, &msg->body[2]);
-	writel(req->sector >> 23, &msg->body[3]);
 
-	mptr = &msg->body[4];
-
-	sg = ireq->sg_table;
+	mptr = &msg->body[0];
 
 	if (rq_data_dir(req) == READ) {
-		writel(I2O_CMD_BLOCK_READ << 24 | HOST_TID << 12 | tid,
-		       &msg->u.head[1]);
-		sg_flags = 0x10000000;
+		cmd = I2O_CMD_BLOCK_READ << 24;
+
 		switch (dev->rcache) {
-		case CACHE_NULL:
-			writel(0, &msg->body[0]);
-			break;
 		case CACHE_PREFETCH:
-			writel(0x201F0008, &msg->body[0]);
+			ctl_flags = 0x201F0008;
 			break;
+
 		case CACHE_SMARTFETCH:
 			if (req->nr_sectors > 16)
-				writel(0x201F0008, &msg->body[0]);
+				ctl_flags = 0x201F0008;
 			else
-				writel(0x001F0000, &msg->body[0]);
+				ctl_flags = 0x001F0000;
+			break;
+
+		default:
 			break;
 		}
 	} else {
-		writel(I2O_CMD_BLOCK_WRITE << 24 | HOST_TID << 12 | tid,
-		       &msg->u.head[1]);
-		sg_flags = 0x14000000;
+		cmd = I2O_CMD_BLOCK_WRITE << 24;
+
 		switch (dev->wcache) {
-		case CACHE_NULL:
-			writel(0, &msg->body[0]);
-			break;
 		case CACHE_WRITETHROUGH:
-			writel(0x001F0008, &msg->body[0]);
+			ctl_flags = 0x001F0008;
 			break;
 		case CACHE_WRITEBACK:
-			writel(0x001F0010, &msg->body[0]);
+			ctl_flags = 0x001F0010;
 			break;
 		case CACHE_SMARTBACK:
 			if (req->nr_sectors > 16)
-				writel(0x001F0004, &msg->body[0]);
+				ctl_flags = 0x001F0004;
 			else
-				writel(0x001F0010, &msg->body[0]);
+				ctl_flags = 0x001F0010;
 			break;
 		case CACHE_SMARTTHROUGH:
 			if (req->nr_sectors > 16)
-				writel(0x001F0004, &msg->body[0]);
+				ctl_flags = 0x001F0004;
 			else
-				writel(0x001F0010, &msg->body[0]);
+				ctl_flags = 0x001F0010;
+		default:
+			break;
+		}
+	}
+
+#ifdef CONFIG_I2O_EXT_ADAPTEC
+	if (c->adaptec) {
+		u8 cmd[10];
+		u32 scsi_flags;
+		u16 hwsec = queue_hardsect_size(req->q) >> KERNEL_SECTOR_SHIFT;
+
+		memset(cmd, 0, 10);
+
+		sgl_offset = SGL_OFFSET_12;
+
+		writel(I2O_CMD_PRIVATE << 24 | HOST_TID << 12 | tid,
+		       &msg->u.head[1]);
+
+		writel(I2O_VENDOR_DPT << 16 | I2O_CMD_SCSI_EXEC, mptr++);
+		writel(tid, mptr++);
+
+		/*
+		 * ENABLE_DISCONNECT
+		 * SIMPLE_TAG
+		 * RETURN_SENSE_DATA_IN_REPLY_MESSAGE_FRAME
+		 */
+		if (rq_data_dir(req) == READ) {
+			cmd[0] = 0x28;
+			scsi_flags = 0x60a0000a;
+		} else {
+			cmd[0] = 0x2A;
+			scsi_flags = 0xa0a0000a;
 		}
+
+		writel(scsi_flags, mptr++);
+
+		*((u32 *) & cmd[2]) = cpu_to_be32(req->sector * hwsec);
+		*((u16 *) & cmd[7]) = cpu_to_be16(req->nr_sectors * hwsec);
+
+		memcpy_toio(mptr, cmd, 10);
+		mptr += 4;
+		writel(req->nr_sectors << KERNEL_SECTOR_SHIFT, mptr++);
+	} else
+#endif
+	{
+		writel(cmd | HOST_TID << 12 | tid, &msg->u.head[1]);
+		writel(ctl_flags, mptr++);
+		writel(req->nr_sectors << KERNEL_SECTOR_SHIFT, mptr++);
+		writel((u32) (req->sector << KERNEL_SECTOR_SHIFT), mptr++);
+		writel(req->sector >> (32 - KERNEL_SECTOR_SHIFT), mptr++);
 	}
 
-	for (i = sgnum; i > 0; i--) {
-		if (i == 1)
-			sg_flags |= 0x80000000;
-		writel(sg_flags | sg_dma_len(sg), mptr);
-		writel(sg_dma_address(sg), mptr + 4);
-		mptr += 8;
-		sg++;
+	if (!i2o_block_sglist_alloc(c, ireq, &mptr)) {
+		rc = -ENOMEM;
+		goto context_remove;
 	}
 
-	writel(I2O_MESSAGE_SIZE
-	       (((unsigned long)mptr -
-		 (unsigned long)&msg->u.head[0]) >> 2) | SGL_OFFSET_8,
-	       &msg->u.head[0]);
+	writel(I2O_MESSAGE_SIZE(mptr - &msg->u.head[0]) |
+	       sgl_offset, &msg->u.head[0]);
 
 	list_add_tail(&ireq->queue, &dev->open_queue);
 	dev->open_queue_depth++;
@@ -921,11 +920,13 @@ static void i2o_block_request_fn(struct 
 
 			queue_depth = ireq->i2o_blk_dev->open_queue_depth;
 
-			if (queue_depth < I2O_BLOCK_MAX_OPEN_REQUESTS)
+			if (queue_depth < I2O_BLOCK_MAX_OPEN_REQUESTS) {
 				if (!i2o_block_transfer(req)) {
 					blkdev_dequeue_request(req);
 					continue;
-				}
+				} else
+					osm_info("transfer error\n");
+			}
 
 			if (queue_depth)
 				break;
@@ -939,7 +940,6 @@ static void i2o_block_request_fn(struct 
 			INIT_WORK(&dreq->work, i2o_block_delayed_request_fn,
 				  dreq);
 
-			osm_info("transfer error\n");
 			if (!queue_delayed_work(i2o_block_driver.event_queue,
 						&dreq->work,
 						I2O_BLOCK_RETRY_TIME))
@@ -1008,6 +1008,7 @@ static struct i2o_block_device *i2o_bloc
 	}
 
 	blk_queue_prep_rq(queue, i2o_block_prep_req_fn);
+	blk_queue_issue_flush_fn(queue, i2o_block_issue_flush);
 
 	gd->major = I2O_MAJOR;
 	gd->queue = queue;
@@ -1040,17 +1041,27 @@ static struct i2o_block_device *i2o_bloc
 static int i2o_block_probe(struct device *dev)
 {
 	struct i2o_device *i2o_dev = to_i2o_device(dev);
-	struct i2o_block_device *i2o_blk_dev;
 	struct i2o_controller *c = i2o_dev->iop;
+	struct i2o_block_device *i2o_blk_dev;
 	struct gendisk *gd;
 	struct request_queue *queue;
 	static int unit = 0;
 	int rc;
 	u64 size;
 	u32 blocksize;
-	u16 power;
 	u32 flags, status;
-	int segments;
+	u16 body_size = 4;
+	unsigned short max_sectors;
+
+#ifdef CONFIG_I2O_EXT_ADAPTEC
+	if (c->adaptec)
+		body_size = 8;
+#endif
+
+	if (c->limit_sectors)
+		max_sectors = I2O_MAX_SECTORS_LIMITED;
+	else
+		max_sectors = I2O_MAX_SECTORS;
 
 	/* skip devices which are used by IOP */
 	if (i2o_dev->lct_data.user_tid != 0xfff) {
@@ -1058,8 +1069,6 @@ static int i2o_block_probe(struct device
 		return -ENODEV;
 	}
 
-	osm_info("New device detected (TID: %03x)\n", i2o_dev->lct_data.tid);
-
 	if (i2o_device_claim(i2o_dev)) {
 		osm_warn("Unable to claim device. Installation aborted\n");
 		rc = -EFAULT;
@@ -1087,50 +1096,44 @@ static int i2o_block_probe(struct device
 	queue = gd->queue;
 	queue->queuedata = i2o_blk_dev;
 
-	blk_queue_max_phys_segments(queue, I2O_MAX_SEGMENTS);
-	blk_queue_max_sectors(queue, I2O_MAX_SECTORS);
-
-	if (c->short_req)
-		segments = 8;
-	else {
-		i2o_status_block *sb;
-
-		sb = c->status_block.virt;
-
-		segments = (sb->inbound_frame_size -
-			    sizeof(struct i2o_message) / 4 - 4) / 2;
-	}
-
-	blk_queue_max_hw_segments(queue, segments);
-
-	osm_debug("max sectors = %d\n", I2O_MAX_SECTORS);
-	osm_debug("phys segments = %d\n", I2O_MAX_SEGMENTS);
-	osm_debug("hw segments = %d\n", segments);
+	blk_queue_max_phys_segments(queue, I2O_MAX_PHYS_SEGMENTS);
+	blk_queue_max_sectors(queue, max_sectors);
+	blk_queue_max_hw_segments(queue, i2o_sg_tablesize(c, body_size));
+
+	osm_debug("max sectors = %d\n", queue->max_phys_segments);
+	osm_debug("phys segments = %d\n", queue->max_sectors);
+	osm_debug("max hw segments = %d\n", queue->max_hw_segments);
 
 	/*
 	 *      Ask for the current media data. If that isn't supported
 	 *      then we ask for the device capacity data
 	 */
-	if (i2o_parm_field_get(i2o_dev, 0x0004, 1, &blocksize, 4) != 0
-	    || i2o_parm_field_get(i2o_dev, 0x0004, 0, &size, 8) != 0) {
-		i2o_parm_field_get(i2o_dev, 0x0000, 3, &blocksize, 4);
-		i2o_parm_field_get(i2o_dev, 0x0000, 4, &size, 8);
-	}
-	osm_debug("blocksize = %d\n", blocksize);
+	if (i2o_parm_field_get(i2o_dev, 0x0004, 1, &blocksize, 4) ||
+	    i2o_parm_field_get(i2o_dev, 0x0000, 3, &blocksize, 4)) {
+		blk_queue_hardsect_size(queue, blocksize);
+	} else
+		osm_warn("unable to get blocksize of %s\n", gd->disk_name);
 
-	if (i2o_parm_field_get(i2o_dev, 0x0000, 2, &power, 2))
-		power = 0;
+	if (i2o_parm_field_get(i2o_dev, 0x0004, 0, &size, 8) ||
+	    i2o_parm_field_get(i2o_dev, 0x0000, 4, &size, 8)) {
+		set_capacity(gd, size >> KERNEL_SECTOR_SHIFT);
+	} else
+		osm_warn("could not get size of %s\n", gd->disk_name);
+
+	if (!i2o_parm_field_get(i2o_dev, 0x0000, 2, &i2o_blk_dev->power, 2))
+		i2o_blk_dev->power = 0;
 	i2o_parm_field_get(i2o_dev, 0x0000, 5, &flags, 4);
 	i2o_parm_field_get(i2o_dev, 0x0000, 6, &status, 4);
 
-	set_capacity(gd, size >> 9);
-
 	i2o_event_register(i2o_dev, &i2o_block_driver, 0, 0xffffffff);
 
 	add_disk(gd);
 
 	unit++;
 
+	osm_info("device added (TID: %03x): %s\n", i2o_dev->lct_data.tid,
+		 i2o_blk_dev->gd->disk_name);
+
 	return 0;
 
       claim_release:
@@ -1178,7 +1181,7 @@ static int __init i2o_block_init(void)
 		goto exit;
 	}
 
-	i2o_blk_req_pool.pool = mempool_create(I2O_REQ_MEMPOOL_SIZE,
+	i2o_blk_req_pool.pool = mempool_create(I2O_BLOCK_REQ_MEMPOOL_SIZE,
 					       mempool_alloc_slab,
 					       mempool_free_slab,
 					       i2o_blk_req_pool.slab);
diff --git a/drivers/message/i2o/i2o_block.h b/drivers/message/i2o/i2o_block.h
--- a/drivers/message/i2o/i2o_block.h
+++ b/drivers/message/i2o/i2o_block.h
@@ -56,42 +56,46 @@
 #define I2O_BLOCK_RETRY_TIME HZ/4
 #define I2O_BLOCK_MAX_OPEN_REQUESTS 50
 
+/* request queue sizes */
+#define I2O_BLOCK_REQ_MEMPOOL_SIZE		32
+
+#define KERNEL_SECTOR_SHIFT 9
+#define KERNEL_SECTOR_SIZE (1 << KERNEL_SECTOR_SHIFT)
+
 /* I2O Block OSM mempool struct */
 struct i2o_block_mempool {
-	kmem_cache_t	*slab;
-	mempool_t	*pool;
+	kmem_cache_t *slab;
+	mempool_t *pool;
 };
 
 /* I2O Block device descriptor */
 struct i2o_block_device {
 	struct i2o_device *i2o_dev;	/* pointer to I2O device */
 	struct gendisk *gd;
-	spinlock_t lock;		/* queue lock */
+	spinlock_t lock;	/* queue lock */
 	struct list_head open_queue;	/* list of transfered, but unfinished
 					   requests */
 	unsigned int open_queue_depth;	/* number of requests in the queue */
 
-	int rcache;			/* read cache flags */
-	int wcache;			/* write cache flags */
+	int rcache;		/* read cache flags */
+	int wcache;		/* write cache flags */
 	int flags;
-	int power;			/* power state */
-	int media_change_flag;		/* media changed flag */
+	u16 power;		/* power state */
+	int media_change_flag;	/* media changed flag */
 };
 
 /* I2O Block device request */
-struct i2o_block_request
-{
+struct i2o_block_request {
 	struct list_head queue;
-	struct request *req;		/* corresponding request */
+	struct request *req;	/* corresponding request */
 	struct i2o_block_device *i2o_blk_dev;	/* I2O block device */
-	int sg_dma_direction;		/* direction of DMA buffer read/write */
-	int sg_nents;			/* number of SG elements */
-	struct scatterlist sg_table[I2O_MAX_SEGMENTS]; /* SG table */
+	struct device *dev;	/* device used for DMA */
+	int sg_nents;		/* number of SG elements */
+	struct scatterlist sg_table[I2O_MAX_PHYS_SEGMENTS];	/* SG table */
 };
 
 /* I2O Block device delayed request */
-struct i2o_block_delayed_request
-{
+struct i2o_block_delayed_request {
 	struct work_struct work;
 	struct request_queue *queue;
 };
diff --git a/drivers/message/i2o/i2o_config.c b/drivers/message/i2o/i2o_config.c
--- a/drivers/message/i2o/i2o_config.c
+++ b/drivers/message/i2o/i2o_config.c
@@ -30,29 +30,15 @@
  * 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/i2o.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/slab.h>
 #include <linux/miscdevice.h>
-#include <linux/mm.h>
-#include <linux/spinlock.h>
 #include <linux/smp_lock.h>
-#include <linux/ioctl32.h>
 #include <linux/compat.h>
-#include <linux/syscalls.h>
 
 #include <asm/uaccess.h>
-#include <asm/io.h>
 
-#define OSM_NAME	"config-osm"
-#define OSM_VERSION	"$Rev$"
-#define OSM_DESCRIPTION	"I2O Configuration OSM"
+#include "core.h"
 
-extern int i2o_parm_issue(struct i2o_device *, int, void *, int, void *, int);
+#define SG_TABLESIZE		30
 
 static int i2o_cfg_ioctl(struct inode *inode, struct file *fp, unsigned int cmd,
 			 unsigned long arg);
@@ -80,15 +66,6 @@ struct i2o_cfg_info {
 static struct i2o_cfg_info *open_files = NULL;
 static ulong i2o_cfg_info_id = 0;
 
-/*
- *	Each of these describes an i2o message handler. They are
- *	multiplexed by the i2o_core code
- */
-
-static struct i2o_driver i2o_config_driver = {
-	.name = OSM_NAME
-};
-
 static int i2o_cfg_getiops(unsigned long arg)
 {
 	struct i2o_controller *c;
@@ -391,9 +368,9 @@ static int i2o_cfg_swul(unsigned long ar
 
 	i2o_dma_free(&c->pdev->dev, &buffer);
 
-return_ret:
+      return_ret:
 	return ret;
-return_fault:
+      return_fault:
 	ret = -EFAULT;
 	goto return_ret;
 };
@@ -540,8 +517,10 @@ static int i2o_cfg_evt_get(unsigned long
 	return 0;
 }
 
+#ifdef CONFIG_I2O_EXT_ADAPTEC
 #ifdef CONFIG_COMPAT
-static int i2o_cfg_passthru32(struct file *file, unsigned cmnd, unsigned long arg)
+static int i2o_cfg_passthru32(struct file *file, unsigned cmnd,
+			      unsigned long arg)
 {
 	struct i2o_cmd_passthru32 __user *cmd;
 	struct i2o_controller *c;
@@ -555,6 +534,7 @@ static int i2o_cfg_passthru32(struct fil
 	u32 sg_offset = 0;
 	u32 sg_count = 0;
 	u32 i = 0;
+	u32 sg_index = 0;
 	i2o_status_block *sb;
 	struct i2o_message *msg;
 	u32 m;
@@ -634,8 +614,8 @@ static int i2o_cfg_passthru32(struct fil
 		if (sg_count > SG_TABLESIZE) {
 			printk(KERN_DEBUG "%s:IOCTL SG List too large (%u)\n",
 			       c->name, sg_count);
-			kfree(reply);
-			return -EINVAL;
+			rcode = -EINVAL;
+			goto cleanup;
 		}
 
 		for (i = 0; i < sg_count; i++) {
@@ -651,7 +631,7 @@ static int i2o_cfg_passthru32(struct fil
 				goto cleanup;
 			}
 			sg_size = sg[i].flag_count & 0xffffff;
-			p = &(sg_list[i]);
+			p = &(sg_list[sg_index++]);
 			/* Allocate memory for the transfer */
 			if (i2o_dma_alloc
 			    (&c->pdev->dev, p, sg_size,
@@ -660,20 +640,21 @@ static int i2o_cfg_passthru32(struct fil
 				       "%s: Could not allocate SG buffer - size = %d buffer number %d of %d\n",
 				       c->name, sg_size, i, sg_count);
 				rcode = -ENOMEM;
-				goto cleanup;
+				goto sg_list_cleanup;
 			}
 			/* Copy in the user's SG buffer if necessary */
 			if (sg[i].
 			    flag_count & 0x04000000 /*I2O_SGL_FLAGS_DIR */ ) {
 				// TODO 64bit fix
 				if (copy_from_user
-				    (p->virt, (void __user *)(unsigned long)sg[i].addr_bus,
-				     sg_size)) {
+				    (p->virt,
+				     (void __user *)(unsigned long)sg[i].
+				     addr_bus, sg_size)) {
 					printk(KERN_DEBUG
 					       "%s: Could not copy SG buf %d FROM user\n",
 					       c->name, i);
 					rcode = -EFAULT;
-					goto cleanup;
+					goto sg_list_cleanup;
 				}
 			}
 			//TODO 64bit fix
@@ -683,10 +664,10 @@ static int i2o_cfg_passthru32(struct fil
 
 	rcode = i2o_msg_post_wait(c, m, 60);
 	if (rcode)
-		goto cleanup;
+		goto sg_list_cleanup;
 
 	if (sg_offset) {
-		u32 msg[128];
+		u32 msg[I2O_OUTBOUND_MSG_FRAME_SIZE];
 		/* Copy back the Scatter Gather buffers back to user space */
 		u32 j;
 		// TODO 64bit fix
@@ -694,18 +675,18 @@ static int i2o_cfg_passthru32(struct fil
 		int sg_size;
 
 		// re-acquire the original message to handle correctly the sg copy operation
-		memset(&msg, 0, MSG_FRAME_SIZE * 4);
+		memset(&msg, 0, I2O_OUTBOUND_MSG_FRAME_SIZE * 4);
 		// get user msg size in u32s
 		if (get_user(size, &user_msg[0])) {
 			rcode = -EFAULT;
-			goto cleanup;
+			goto sg_list_cleanup;
 		}
 		size = size >> 16;
 		size *= 4;
 		/* Copy in the user's I2O command */
 		if (copy_from_user(msg, user_msg, size)) {
 			rcode = -EFAULT;
-			goto cleanup;
+			goto sg_list_cleanup;
 		}
 		sg_count =
 		    (size - sg_offset * 4) / sizeof(struct sg_simple_element);
@@ -727,7 +708,7 @@ static int i2o_cfg_passthru32(struct fil
 					       c->name, sg_list[j].virt,
 					       sg[j].addr_bus);
 					rcode = -EFAULT;
-					goto cleanup;
+					goto sg_list_cleanup;
 				}
 			}
 		}
@@ -741,6 +722,7 @@ static int i2o_cfg_passthru32(struct fil
 			       "%s: Could not copy message context FROM user\n",
 			       c->name);
 			rcode = -EFAULT;
+			goto sg_list_cleanup;
 		}
 		if (copy_to_user(user_reply, reply, reply_size)) {
 			printk(KERN_WARNING
@@ -749,16 +731,21 @@ static int i2o_cfg_passthru32(struct fil
 		}
 	}
 
+      sg_list_cleanup:
+	for (i = 0; i < sg_index; i++)
+		i2o_dma_free(&c->pdev->dev, &sg_list[i]);
+
       cleanup:
 	kfree(reply);
 	return rcode;
 }
 
-static long i2o_cfg_compat_ioctl(struct file *file, unsigned cmd, unsigned long arg)
+static long i2o_cfg_compat_ioctl(struct file *file, unsigned cmd,
+				 unsigned long arg)
 {
 	int ret;
-	lock_kernel();		
-	switch (cmd) { 
+	lock_kernel();
+	switch (cmd) {
 	case I2OGETIOPS:
 		ret = i2o_cfg_ioctl(NULL, file, cmd, arg);
 		break;
@@ -862,8 +849,8 @@ static int i2o_cfg_passthru(unsigned lon
 		if (sg_count > SG_TABLESIZE) {
 			printk(KERN_DEBUG "%s:IOCTL SG List too large (%u)\n",
 			       c->name, sg_count);
-			kfree(reply);
-			return -EINVAL;
+			rcode = -EINVAL;
+			goto cleanup;
 		}
 
 		for (i = 0; i < sg_count; i++) {
@@ -875,7 +862,7 @@ static int i2o_cfg_passthru(unsigned lon
 				       "%s:Bad SG element %d - not simple (%x)\n",
 				       c->name, i, sg[i].flag_count);
 				rcode = -EINVAL;
-				goto cleanup;
+				goto sg_list_cleanup;
 			}
 			sg_size = sg[i].flag_count & 0xffffff;
 			/* Allocate memory for the transfer */
@@ -885,7 +872,7 @@ static int i2o_cfg_passthru(unsigned lon
 				       "%s: Could not allocate SG buffer - size = %d buffer number %d of %d\n",
 				       c->name, sg_size, i, sg_count);
 				rcode = -ENOMEM;
-				goto cleanup;
+				goto sg_list_cleanup;
 			}
 			sg_list[sg_index++] = p;	// sglist indexed with input frame, not our internal frame.
 			/* Copy in the user's SG buffer if necessary */
@@ -899,7 +886,7 @@ static int i2o_cfg_passthru(unsigned lon
 					       "%s: Could not copy SG buf %d FROM user\n",
 					       c->name, i);
 					rcode = -EFAULT;
-					goto cleanup;
+					goto sg_list_cleanup;
 				}
 			}
 			//TODO 64bit fix
@@ -909,7 +896,7 @@ static int i2o_cfg_passthru(unsigned lon
 
 	rcode = i2o_msg_post_wait(c, m, 60);
 	if (rcode)
-		goto cleanup;
+		goto sg_list_cleanup;
 
 	if (sg_offset) {
 		u32 msg[128];
@@ -920,18 +907,18 @@ static int i2o_cfg_passthru(unsigned lon
 		int sg_size;
 
 		// re-acquire the original message to handle correctly the sg copy operation
-		memset(&msg, 0, MSG_FRAME_SIZE * 4);
+		memset(&msg, 0, I2O_OUTBOUND_MSG_FRAME_SIZE * 4);
 		// get user msg size in u32s
 		if (get_user(size, &user_msg[0])) {
 			rcode = -EFAULT;
-			goto cleanup;
+			goto sg_list_cleanup;
 		}
 		size = size >> 16;
 		size *= 4;
 		/* Copy in the user's I2O command */
 		if (copy_from_user(msg, user_msg, size)) {
 			rcode = -EFAULT;
-			goto cleanup;
+			goto sg_list_cleanup;
 		}
 		sg_count =
 		    (size - sg_offset * 4) / sizeof(struct sg_simple_element);
@@ -953,7 +940,7 @@ static int i2o_cfg_passthru(unsigned lon
 					       c->name, sg_list[j],
 					       sg[j].addr_bus);
 					rcode = -EFAULT;
-					goto cleanup;
+					goto sg_list_cleanup;
 				}
 			}
 		}
@@ -975,10 +962,15 @@ static int i2o_cfg_passthru(unsigned lon
 		}
 	}
 
+      sg_list_cleanup:
+	for (i = 0; i < sg_index; i++)
+		kfree(sg_list[i]);
+
       cleanup:
 	kfree(reply);
 	return rcode;
 }
+#endif
 
 /*
  * IOCTL Handler
@@ -1033,9 +1025,11 @@ static int i2o_cfg_ioctl(struct inode *i
 		ret = i2o_cfg_evt_get(arg, fp);
 		break;
 
+#ifdef CONFIG_I2O_EXT_ADAPTEC
 	case I2OPASSTHRU:
 		ret = i2o_cfg_passthru(arg);
 		break;
+#endif
 
 	default:
 		osm_debug("unknown ioctl called!\n");
@@ -1137,37 +1131,21 @@ static struct miscdevice i2o_miscdev = {
 	&config_fops
 };
 
-static int __init i2o_config_init(void)
+static int __init i2o_config_old_init(void)
 {
-	printk(KERN_INFO OSM_DESCRIPTION " v" OSM_VERSION "\n");
-
 	spin_lock_init(&i2o_config_lock);
 
 	if (misc_register(&i2o_miscdev) < 0) {
 		osm_err("can't register device.\n");
 		return -EBUSY;
 	}
-	/*
-	 *      Install our handler
-	 */
-	if (i2o_driver_register(&i2o_config_driver)) {
-		osm_err("handler register failed.\n");
-		misc_deregister(&i2o_miscdev);
-		return -EBUSY;
-	}
+
 	return 0;
 }
 
-static void i2o_config_exit(void)
+static void i2o_config_old_exit(void)
 {
 	misc_deregister(&i2o_miscdev);
-	i2o_driver_unregister(&i2o_config_driver);
 }
 
 MODULE_AUTHOR("Red Hat Software");
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION(OSM_DESCRIPTION);
-MODULE_VERSION(OSM_VERSION);
-
-module_init(i2o_config_init);
-module_exit(i2o_config_exit);
diff --git a/drivers/message/i2o/i2o_proc.c b/drivers/message/i2o/i2o_proc.c
--- a/drivers/message/i2o/i2o_proc.c
+++ b/drivers/message/i2o/i2o_proc.c
@@ -28,7 +28,7 @@
  */
 
 #define OSM_NAME	"proc-osm"
-#define OSM_VERSION	"$Rev$"
+#define OSM_VERSION	"1.145"
 #define OSM_DESCRIPTION	"I2O ProcFS OSM"
 
 #define I2O_MAX_MODULES 4
@@ -228,7 +228,7 @@ static const char *i2o_get_class_name(in
 	case I2O_CLASS_FLOPPY_DEVICE:
 		idx = 12;
 		break;
-	case I2O_CLASS_BUS_ADAPTER_PORT:
+	case I2O_CLASS_BUS_ADAPTER:
 		idx = 13;
 		break;
 	case I2O_CLASS_PEER_TRANSPORT_AGENT:
@@ -490,7 +490,7 @@ static int i2o_seq_show_lct(struct seq_f
 				seq_printf(seq, ", Unknown Device Type");
 			break;
 
-		case I2O_CLASS_BUS_ADAPTER_PORT:
+		case I2O_CLASS_BUS_ADAPTER:
 			if (lct->lct_entry[i].sub_class < BUS_TABLE_SIZE)
 				seq_printf(seq, ", %s",
 					   bus_ports[lct->lct_entry[i].
diff --git a/drivers/message/i2o/i2o_scsi.c b/drivers/message/i2o/i2o_scsi.c
--- a/drivers/message/i2o/i2o_scsi.c
+++ b/drivers/message/i2o/i2o_scsi.c
@@ -54,6 +54,7 @@
 #include <linux/pci.h>
 #include <linux/blkdev.h>
 #include <linux/i2o.h>
+#include <linux/scatterlist.h>
 
 #include <asm/dma.h>
 #include <asm/system.h>
@@ -64,19 +65,23 @@
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_device.h>
 #include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_request.h>
+#include <scsi/sg.h>
+#include <scsi/sg_request.h>
 
 #define OSM_NAME	"scsi-osm"
-#define OSM_VERSION	"$Rev$"
+#define OSM_VERSION	"1.282"
 #define OSM_DESCRIPTION	"I2O SCSI Peripheral OSM"
 
 static struct i2o_driver i2o_scsi_driver;
 
-static int i2o_scsi_max_id = 16;
-static int i2o_scsi_max_lun = 8;
+static unsigned int i2o_scsi_max_id = 16;
+static unsigned int i2o_scsi_max_lun = 255;
 
 struct i2o_scsi_host {
 	struct Scsi_Host *scsi_host;	/* pointer to the SCSI host */
 	struct i2o_controller *iop;	/* pointer to the I2O controller */
+	unsigned int lun;	/* lun's used for block devices */
 	struct i2o_device *channel[0];	/* channel->i2o_dev mapping table */
 };
 
@@ -99,11 +104,17 @@ static struct i2o_scsi_host *i2o_scsi_ho
 	u8 type;
 	int i;
 	size_t size;
-	i2o_status_block *sb;
+	u16 body_size = 6;
+
+#ifdef CONFIG_I2O_EXT_ADAPTEC
+	if (c->adaptec)
+		body_size = 8;
+#endif
 
 	list_for_each_entry(i2o_dev, &c->devices, list)
-	    if (i2o_dev->lct_data.class_id == I2O_CLASS_BUS_ADAPTER_PORT) {
-		if (i2o_parm_field_get(i2o_dev, 0x0000, 0, &type, 1) || (type == 1))	/* SCSI bus */
+	    if (i2o_dev->lct_data.class_id == I2O_CLASS_BUS_ADAPTER) {
+		if (i2o_parm_field_get(i2o_dev, 0x0000, 0, &type, 1)
+		    && (type == 0x01))	/* SCSI bus */
 			max_channel++;
 	}
 
@@ -125,20 +136,18 @@ static struct i2o_scsi_host *i2o_scsi_ho
 	scsi_host->max_id = i2o_scsi_max_id;
 	scsi_host->max_lun = i2o_scsi_max_lun;
 	scsi_host->this_id = c->unit;
-
-	sb = c->status_block.virt;
-
-	scsi_host->sg_tablesize = (sb->inbound_frame_size -
-				   sizeof(struct i2o_message) / 4 - 6) / 2;
+	scsi_host->sg_tablesize = i2o_sg_tablesize(c, body_size);
 
 	i2o_shost = (struct i2o_scsi_host *)scsi_host->hostdata;
 	i2o_shost->scsi_host = scsi_host;
 	i2o_shost->iop = c;
+	i2o_shost->lun = 1;
 
 	i = 0;
 	list_for_each_entry(i2o_dev, &c->devices, list)
-	    if (i2o_dev->lct_data.class_id == I2O_CLASS_BUS_ADAPTER_PORT) {
-		if (i2o_parm_field_get(i2o_dev, 0x0000, 0, &type, 1) || (type == 1))	/* only SCSI bus */
+	    if (i2o_dev->lct_data.class_id == I2O_CLASS_BUS_ADAPTER) {
+		if (i2o_parm_field_get(i2o_dev, 0x0000, 0, &type, 1)
+		    && (type == 0x01))	/* only SCSI bus */
 			i2o_shost->channel[i++] = i2o_dev;
 
 		if (i >= max_channel)
@@ -178,10 +187,13 @@ static int i2o_scsi_remove(struct device
 	struct i2o_scsi_host *i2o_shost;
 	struct scsi_device *scsi_dev;
 
+	osm_info("device removed (TID: %03x)\n", i2o_dev->lct_data.tid);
+
 	i2o_shost = i2o_scsi_get_host(c);
 
 	shost_for_each_device(scsi_dev, i2o_shost->scsi_host)
 	    if (scsi_dev->hostdata == i2o_dev) {
+		sysfs_remove_link(&i2o_dev->device.kobj, "scsi");
 		scsi_remove_device(scsi_dev);
 		scsi_device_put(scsi_dev);
 		break;
@@ -207,8 +219,8 @@ static int i2o_scsi_probe(struct device 
 	struct Scsi_Host *scsi_host;
 	struct i2o_device *parent;
 	struct scsi_device *scsi_dev;
-	u32 id;
-	u64 lun;
+	u32 id = -1;
+	u64 lun = -1;
 	int channel = -1;
 	int i;
 
@@ -218,8 +230,56 @@ static int i2o_scsi_probe(struct device 
 
 	scsi_host = i2o_shost->scsi_host;
 
-	if (i2o_parm_field_get(i2o_dev, 0, 3, &id, 4) < 0)
+	switch (i2o_dev->lct_data.class_id) {
+	case I2O_CLASS_RANDOM_BLOCK_STORAGE:
+	case I2O_CLASS_EXECUTIVE:
+#ifdef CONFIG_I2O_EXT_ADAPTEC
+		if (c->adaptec) {
+			u8 type;
+			struct i2o_device *d = i2o_shost->channel[0];
+
+			if (i2o_parm_field_get(d, 0x0000, 0, &type, 1)
+			    && (type == 0x01))	/* SCSI bus */
+				if (i2o_parm_field_get(d, 0x0200, 4, &id, 4)) {
+					channel = 0;
+					if (i2o_dev->lct_data.class_id ==
+					    I2O_CLASS_RANDOM_BLOCK_STORAGE)
+						lun = i2o_shost->lun++;
+					else
+						lun = 0;
+				}
+		}
+#endif
+		break;
+
+	case I2O_CLASS_SCSI_PERIPHERAL:
+		if (i2o_parm_field_get(i2o_dev, 0x0000, 3, &id, 4) < 0)
+			return -EFAULT;
+
+		if (i2o_parm_field_get(i2o_dev, 0x0000, 4, &lun, 8) < 0)
+			return -EFAULT;
+
+		parent = i2o_iop_find_device(c, i2o_dev->lct_data.parent_tid);
+		if (!parent) {
+			osm_warn("can not find parent of device %03x\n",
+				 i2o_dev->lct_data.tid);
+			return -EFAULT;
+		}
+
+		for (i = 0; i <= i2o_shost->scsi_host->max_channel; i++)
+			if (i2o_shost->channel[i] == parent)
+				channel = i;
+		break;
+
+	default:
+		return -EFAULT;
+	}
+
+	if (channel == -1) {
+		osm_warn("can not find channel of device %03x\n",
+			 i2o_dev->lct_data.tid);
 		return -EFAULT;
+	}
 
 	if (id >= scsi_host->max_id) {
 		osm_warn("SCSI device id (%d) >= max_id of I2O host (%d)", id,
@@ -227,42 +287,26 @@ static int i2o_scsi_probe(struct device 
 		return -EFAULT;
 	}
 
-	if (i2o_parm_field_get(i2o_dev, 0, 4, &lun, 8) < 0)
-		return -EFAULT;
 	if (lun >= scsi_host->max_lun) {
 		osm_warn("SCSI device id (%d) >= max_lun of I2O host (%d)",
 			 (unsigned int)lun, scsi_host->max_lun);
 		return -EFAULT;
 	}
 
-	parent = i2o_iop_find_device(c, i2o_dev->lct_data.parent_tid);
-	if (!parent) {
-		osm_warn("can not find parent of device %03x\n",
-			 i2o_dev->lct_data.tid);
-		return -EFAULT;
-	}
-
-	for (i = 0; i <= i2o_shost->scsi_host->max_channel; i++)
-		if (i2o_shost->channel[i] == parent)
-			channel = i;
-
-	if (channel == -1) {
-		osm_warn("can not find channel of device %03x\n",
-			 i2o_dev->lct_data.tid);
-		return -EFAULT;
-	}
-
 	scsi_dev =
 	    __scsi_add_device(i2o_shost->scsi_host, channel, id, lun, i2o_dev);
 
-	if (!scsi_dev) {
+	if (IS_ERR(scsi_dev)) {
 		osm_warn("can not add SCSI device %03x\n",
 			 i2o_dev->lct_data.tid);
-		return -EFAULT;
+		return PTR_ERR(scsi_dev);
 	}
 
-	osm_debug("added new SCSI device %03x (cannel: %d, id: %d, lun: %d)\n",
-		  i2o_dev->lct_data.tid, channel, id, (unsigned int)lun);
+	sysfs_create_link(&i2o_dev->device.kobj, &scsi_dev->sdev_gendev.kobj,
+			  "scsi");
+
+	osm_info("device added (TID: %03x) channel: %d, id: %d, lun: %d\n",
+		 i2o_dev->lct_data.tid, channel, id, (unsigned int)lun);
 
 	return 0;
 };
@@ -293,162 +337,89 @@ static int i2o_scsi_reply(struct i2o_con
 			  struct i2o_message *msg)
 {
 	struct scsi_cmnd *cmd;
+	u32 error;
 	struct device *dev;
-	u8 as, ds, st;
 
 	cmd = i2o_cntxt_list_get(c, le32_to_cpu(msg->u.s.tcntxt));
-
-	if (msg->u.head[0] & (1 << 13)) {
-		struct i2o_message __iomem *pmsg;	/* preserved message */
-		u32 pm;
-		int err = DID_ERROR;
-
-		pm = le32_to_cpu(msg->body[3]);
-
-		pmsg = i2o_msg_in_to_virt(c, pm);
-
-		osm_err("IOP fail.\n");
-		osm_err("From %d To %d Cmd %d.\n",
-			(msg->u.head[1] >> 12) & 0xFFF,
-			msg->u.head[1] & 0xFFF, msg->u.head[1] >> 24);
-		osm_err("Failure Code %d.\n", msg->body[0] >> 24);
-		if (msg->body[0] & (1 << 16))
-			osm_err("Format error.\n");
-		if (msg->body[0] & (1 << 17))
-			osm_err("Path error.\n");
-		if (msg->body[0] & (1 << 18))
-			osm_err("Path State.\n");
-		if (msg->body[0] & (1 << 18))
-		{
-			osm_err("Congestion.\n");
-			err = DID_BUS_BUSY;
-		}
-
-		osm_debug("Failing message is %p.\n", pmsg);
-
-		cmd = i2o_cntxt_list_get(c, readl(&pmsg->u.s.tcntxt));
-		if (!cmd)
-			return 1;
-
-		cmd->result = err << 16;
-		cmd->scsi_done(cmd);
-
-		/* Now flush the message by making it a NOP */
-		i2o_msg_nop(c, pm);
-
-		return 1;
+	if (unlikely(!cmd)) {
+		osm_err("NULL reply received!\n");
+		return -1;
 	}
 
 	/*
 	 *      Low byte is device status, next is adapter status,
 	 *      (then one byte reserved), then request status.
 	 */
-	ds = (u8) le32_to_cpu(msg->body[0]);
-	as = (u8) (le32_to_cpu(msg->body[0]) >> 8);
-	st = (u8) (le32_to_cpu(msg->body[0]) >> 24);
-
-	/*
-	 *      Is this a control request coming back - eg an abort ?
-	 */
-
-	if (!cmd) {
-		if (st)
-			osm_warn("SCSI abort: %08X", le32_to_cpu(msg->body[0]));
-		osm_info("SCSI abort completed.\n");
-		return -EFAULT;
-	}
+	error = le32_to_cpu(msg->body[0]);
 
 	osm_debug("Completed %ld\n", cmd->serial_number);
 
-	if (st) {
-		u32 count, error;
-		/* An error has occurred */
-
-		switch (st) {
-		case 0x06:
-			count = le32_to_cpu(msg->body[1]);
-			if (count < cmd->underflow) {
-				int i;
-
-				osm_err("SCSI underflow 0x%08X 0x%08X\n", count,
-					cmd->underflow);
-				osm_debug("Cmd: ");
-				for (i = 0; i < 15; i++)
-					pr_debug("%02X ", cmd->cmnd[i]);
-				pr_debug(".\n");
-				cmd->result = (DID_ERROR << 16);
-			}
-			break;
+	cmd->result = error & 0xff;
+	/*
+	 * if DeviceStatus is not SCSI_SUCCESS copy over the sense data and let
+	 * the SCSI layer handle the error
+	 */
+	if (cmd->result)
+		memcpy(cmd->sense_buffer, &msg->body[3],
+		       min(sizeof(cmd->sense_buffer), (size_t) 40));
+
+	/* only output error code if AdapterStatus is not HBA_SUCCESS */
+	if ((error >> 8) & 0xff)
+		osm_err("SCSI error %08x\n", error);
 
-		default:
-			error = le32_to_cpu(msg->body[0]);
+	dev = &c->pdev->dev;
+	if (cmd->use_sg)
+		dma_unmap_sg(dev, cmd->request_buffer, cmd->use_sg,
+			     cmd->sc_data_direction);
+	else if (cmd->SCp.dma_handle)
+		dma_unmap_single(dev, cmd->SCp.dma_handle, cmd->request_bufflen,
+				 cmd->sc_data_direction);
 
-			osm_err("SCSI error %08x\n", error);
+	cmd->scsi_done(cmd);
 
-			if ((error & 0xff) == 0x02 /*CHECK_CONDITION */ ) {
-				int i;
-				u32 len = sizeof(cmd->sense_buffer);
-				len = (len > 40) ? 40 : len;
-				// Copy over the sense data
-				memcpy(cmd->sense_buffer, (void *)&msg->body[3],
-				       len);
-				for (i = 0; i <= len; i++)
-					osm_info("%02x\n",
-						 cmd->sense_buffer[i]);
-				if (cmd->sense_buffer[0] == 0x70
-				    && cmd->sense_buffer[2] == DATA_PROTECT) {
-					/* This is to handle an array failed */
-					cmd->result = (DID_TIME_OUT << 16);
-					printk(KERN_WARNING "%s: SCSI Data "
-					       "Protect-Device (%d,%d,%d) "
-					       "hba_status=0x%x, dev_status="
-					       "0x%x, cmd=0x%x\n", c->name,
-					       (u32) cmd->device->channel,
-					       (u32) cmd->device->id,
-					       (u32) cmd->device->lun,
-					       (error >> 8) & 0xff,
-					       error & 0xff, cmd->cmnd[0]);
-				} else
-					cmd->result = (DID_ERROR << 16);
-
-				break;
-			}
-
-			switch (as) {
-			case 0x0E:
-				/* SCSI Reset */
-				cmd->result = DID_RESET << 16;
-				break;
-
-			case 0x0F:
-				cmd->result = DID_PARITY << 16;
-				break;
-
-			default:
-				cmd->result = DID_ERROR << 16;
-				break;
-			}
+	return 1;
+};
 
-			break;
-		}
+/**
+ *	i2o_scsi_notify_device_add - Retrieve notifications of added devices
+ *	@i2o_dev: the I2O device which was added
+ *
+ *	If a I2O device is added we catch the notification, because I2O classes
+ *	other then SCSI peripheral will not be received through
+ *	i2o_scsi_probe().
+ */
+static void i2o_scsi_notify_device_add(struct i2o_device *i2o_dev)
+{
+	switch (i2o_dev->lct_data.class_id) {
+	case I2O_CLASS_EXECUTIVE:
+	case I2O_CLASS_RANDOM_BLOCK_STORAGE:
+		i2o_scsi_probe(&i2o_dev->device);
+		break;
 
-		cmd->scsi_done(cmd);
-		return 1;
+	default:
+		break;
 	}
+};
 
-	cmd->result = DID_OK << 16 | ds;
-
-	cmd->scsi_done(cmd);
-
-	dev = &c->pdev->dev;
-	if (cmd->use_sg)
-		dma_unmap_sg(dev, (struct scatterlist *)cmd->buffer,
-			     cmd->use_sg, cmd->sc_data_direction);
-	else if (cmd->request_bufflen)
-		dma_unmap_single(dev, (dma_addr_t) ((long)cmd->SCp.ptr),
-				 cmd->request_bufflen, cmd->sc_data_direction);
+/**
+ *	i2o_scsi_notify_device_remove - Retrieve notifications of removed
+ *				        devices
+ *	@i2o_dev: the I2O device which was removed
+ *
+ *	If a I2O device is removed, we catch the notification to remove the
+ *	corresponding SCSI device.
+ */
+static void i2o_scsi_notify_device_remove(struct i2o_device *i2o_dev)
+{
+	switch (i2o_dev->lct_data.class_id) {
+	case I2O_CLASS_EXECUTIVE:
+	case I2O_CLASS_RANDOM_BLOCK_STORAGE:
+		i2o_scsi_remove(&i2o_dev->device);
+		break;
 
-	return 1;
+	default:
+		break;
+	}
 };
 
 /**
@@ -501,7 +472,7 @@ static void i2o_scsi_notify_controller_r
 
 	scsi_remove_host(i2o_shost->scsi_host);
 	scsi_host_put(i2o_shost->scsi_host);
-	pr_info("I2O SCSI host removed\n");
+	osm_debug("I2O SCSI host removed\n");
 };
 
 /* SCSI OSM driver struct */
@@ -509,6 +480,8 @@ static struct i2o_driver i2o_scsi_driver
 	.name = OSM_NAME,
 	.reply = i2o_scsi_reply,
 	.classes = i2o_scsi_class_id,
+	.notify_device_add = i2o_scsi_notify_device_add,
+	.notify_device_remove = i2o_scsi_notify_device_remove,
 	.notify_controller_add = i2o_scsi_notify_controller_add,
 	.notify_controller_remove = i2o_scsi_notify_controller_remove,
 	.driver = {
@@ -535,26 +508,26 @@ static int i2o_scsi_queuecommand(struct 
 				 void (*done) (struct scsi_cmnd *))
 {
 	struct i2o_controller *c;
-	struct Scsi_Host *host;
 	struct i2o_device *i2o_dev;
-	struct device *dev;
 	int tid;
 	struct i2o_message __iomem *msg;
 	u32 m;
-	u32 scsi_flags, sg_flags;
+	/*
+	 * ENABLE_DISCONNECT
+	 * SIMPLE_TAG
+	 * RETURN_SENSE_DATA_IN_REPLY_MESSAGE_FRAME
+	 */
+	u32 scsi_flags = 0x20a00000;
+	u32 sgl_offset;
 	u32 __iomem *mptr;
-	u32 __iomem *lenptr;
-	u32 len, reqlen;
-	int i;
+	u32 cmd = I2O_CMD_SCSI_EXEC << 24;
+	int rc = 0;
 
 	/*
 	 *      Do the incoming paperwork
 	 */
-
 	i2o_dev = SCpnt->device->hostdata;
-	host = SCpnt->device->host;
 	c = i2o_dev->iop;
-	dev = &c->pdev->dev;
 
 	SCpnt->scsi_done = done;
 
@@ -562,7 +535,7 @@ static int i2o_scsi_queuecommand(struct 
 		osm_warn("no I2O device in request\n");
 		SCpnt->result = DID_NO_CONNECT << 16;
 		done(SCpnt);
-		return 0;
+		goto exit;
 	}
 
 	tid = i2o_dev->lct_data.tid;
@@ -571,44 +544,85 @@ static int i2o_scsi_queuecommand(struct 
 	osm_debug("Real scsi messages.\n");
 
 	/*
-	 *      Obtain an I2O message. If there are none free then
-	 *      throw it back to the scsi layer
-	 */
-
-	m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET);
-	if (m == I2O_QUEUE_EMPTY)
-		return SCSI_MLQUEUE_HOST_BUSY;
-
-	/*
 	 *      Put together a scsi execscb message
 	 */
-
-	len = SCpnt->request_bufflen;
-
 	switch (SCpnt->sc_data_direction) {
 	case PCI_DMA_NONE:
-		scsi_flags = 0x00000000;	// DATA NO XFER
-		sg_flags = 0x00000000;
+		/* DATA NO XFER */
+		sgl_offset = SGL_OFFSET_0;
 		break;
 
 	case PCI_DMA_TODEVICE:
-		scsi_flags = 0x80000000;	// DATA OUT (iop-->dev)
-		sg_flags = 0x14000000;
+		/* DATA OUT (iop-->dev) */
+		scsi_flags |= 0x80000000;
+		sgl_offset = SGL_OFFSET_10;
 		break;
 
 	case PCI_DMA_FROMDEVICE:
-		scsi_flags = 0x40000000;	// DATA IN  (iop<--dev)
-		sg_flags = 0x10000000;
+		/* DATA IN  (iop<--dev) */
+		scsi_flags |= 0x40000000;
+		sgl_offset = SGL_OFFSET_10;
 		break;
 
 	default:
 		/* Unknown - kill the command */
 		SCpnt->result = DID_NO_CONNECT << 16;
 		done(SCpnt);
-		return 0;
+		goto exit;
 	}
 
-	writel(I2O_CMD_SCSI_EXEC << 24 | HOST_TID << 12 | tid, &msg->u.head[1]);
+	/*
+	 *      Obtain an I2O message. If there are none free then
+	 *      throw it back to the scsi layer
+	 */
+
+	m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET);
+	if (m == I2O_QUEUE_EMPTY) {
+		rc = SCSI_MLQUEUE_HOST_BUSY;
+		goto exit;
+	}
+
+	mptr = &msg->body[0];
+
+#ifdef CONFIG_I2O_EXT_ADAPTEC
+	if (c->adaptec) {
+		u32 adpt_flags = 0;
+
+		if (SCpnt->sc_request && SCpnt->sc_request->upper_private_data) {
+			i2o_sg_io_hdr_t __user *usr_ptr =
+			    ((Sg_request *) (SCpnt->sc_request->
+					     upper_private_data))->header.
+			    usr_ptr;
+
+			if (usr_ptr)
+				get_user(adpt_flags, &usr_ptr->flags);
+		}
+
+		switch (i2o_dev->lct_data.class_id) {
+		case I2O_CLASS_EXECUTIVE:
+		case I2O_CLASS_RANDOM_BLOCK_STORAGE:
+			/* interpret flag has to be set for executive */
+			adpt_flags ^= I2O_DPT_SG_FLAG_INTERPRET;
+			break;
+
+		default:
+			break;
+		}
+
+		/*
+		 * for Adaptec controllers we use the PRIVATE command, because
+		 * the normal SCSI EXEC doesn't support all SCSI commands on
+		 * all controllers (for example READ CAPACITY).
+		 */
+		if (sgl_offset == SGL_OFFSET_10)
+			sgl_offset = SGL_OFFSET_12;
+		cmd = I2O_CMD_PRIVATE << 24;
+		writel(I2O_VENDOR_DPT << 16 | I2O_CMD_SCSI_EXEC, mptr++);
+		writel(adpt_flags | tid, mptr++);
+	}
+#endif
+
+	writel(cmd | HOST_TID << 12 | tid, &msg->u.head[1]);
 	writel(i2o_scsi_driver.context, &msg->u.s.icntxt);
 
 	/* We want the SCSI control block back */
@@ -626,7 +640,7 @@ static int i2o_scsi_queuecommand(struct 
 	 */
 
 	/* Attach tags to the devices */
-	/*
+	/* FIXME: implement
 	   if(SCpnt->device->tagged_supported) {
 	   if(SCpnt->tag == HEAD_OF_QUEUE_TAG)
 	   scsi_flags |= 0x01000000;
@@ -635,67 +649,35 @@ static int i2o_scsi_queuecommand(struct 
 	   }
 	 */
 
-	/* Direction, disconnect ok, tag, CDBLen */
-	writel(scsi_flags | 0x20200000 | SCpnt->cmd_len, &msg->body[0]);
-
-	mptr = &msg->body[1];
+	writel(scsi_flags | SCpnt->cmd_len, mptr++);
 
 	/* Write SCSI command into the message - always 16 byte block */
 	memcpy_toio(mptr, SCpnt->cmnd, 16);
 	mptr += 4;
-	lenptr = mptr++;	/* Remember me - fill in when we know */
-
-	reqlen = 12;		// SINGLE SGE
 
-	/* Now fill in the SGList and command */
-	if (SCpnt->use_sg) {
-		struct scatterlist *sg;
-		int sg_count;
-
-		sg = SCpnt->request_buffer;
-		len = 0;
-
-		sg_count = dma_map_sg(dev, sg, SCpnt->use_sg,
-				      SCpnt->sc_data_direction);
-
-		if (unlikely(sg_count <= 0))
-			return -ENOMEM;
-
-		for (i = SCpnt->use_sg; i > 0; i--) {
-			if (i == 1)
-				sg_flags |= 0xC0000000;
-			writel(sg_flags | sg_dma_len(sg), mptr++);
-			writel(sg_dma_address(sg), mptr++);
-			len += sg_dma_len(sg);
-			sg++;
+	if (sgl_offset != SGL_OFFSET_0) {
+		/* write size of data addressed by SGL */
+		writel(SCpnt->request_bufflen, mptr++);
+
+		/* Now fill in the SGList and command */
+		if (SCpnt->use_sg) {
+			if (!i2o_dma_map_sg(c, SCpnt->request_buffer,
+					    SCpnt->use_sg,
+					    SCpnt->sc_data_direction, &mptr))
+				goto nomem;
+		} else {
+			SCpnt->SCp.dma_handle =
+			    i2o_dma_map_single(c, SCpnt->request_buffer,
+					       SCpnt->request_bufflen,
+					       SCpnt->sc_data_direction, &mptr);
+			if (dma_mapping_error(SCpnt->SCp.dma_handle))
+				goto nomem;
 		}
-
-		reqlen = mptr - &msg->u.head[0];
-		writel(len, lenptr);
-	} else {
-		len = SCpnt->request_bufflen;
-
-		writel(len, lenptr);
-
-		if (len > 0) {
-			dma_addr_t dma_addr;
-
-			dma_addr = dma_map_single(dev, SCpnt->request_buffer,
-						  SCpnt->request_bufflen,
-						  SCpnt->sc_data_direction);
-			if (!dma_addr)
-				return -ENOMEM;
-
-			SCpnt->SCp.ptr = (void *)(unsigned long)dma_addr;
-			sg_flags |= 0xC0000000;
-			writel(sg_flags | SCpnt->request_bufflen, mptr++);
-			writel(dma_addr, mptr++);
-		} else
-			reqlen = 9;
 	}
 
 	/* Stick the headers on */
-	writel(reqlen << 16 | SGL_OFFSET_10, &msg->u.head[0]);
+	writel(I2O_MESSAGE_SIZE(mptr - &msg->u.head[0]) | sgl_offset,
+	       &msg->u.head[0]);
 
 	/* Queue the message */
 	i2o_msg_post(c, m);
@@ -703,6 +685,13 @@ static int i2o_scsi_queuecommand(struct 
 	osm_debug("Issued %ld\n", SCpnt->serial_number);
 
 	return 0;
+
+      nomem:
+	rc = -ENOMEM;
+	i2o_msg_nop(c, m);
+
+      exit:
+	return rc;
 };
 
 /**
diff --git a/drivers/message/i2o/iop.c b/drivers/message/i2o/iop.c
--- a/drivers/message/i2o/iop.c
+++ b/drivers/message/i2o/iop.c
@@ -28,8 +28,10 @@
 #include <linux/module.h>
 #include <linux/i2o.h>
 #include <linux/delay.h>
+#include "core.h"
 
-#define OSM_VERSION	"$Rev$"
+#define OSM_NAME	"i2o"
+#define OSM_VERSION	"1.288"
 #define OSM_DESCRIPTION	"I2O subsystem"
 
 /* global I2O controller list */
@@ -43,20 +45,6 @@ static struct i2o_dma i2o_systab;
 
 static int i2o_hrt_get(struct i2o_controller *c);
 
-/* Module internal functions from other sources */
-extern struct i2o_driver i2o_exec_driver;
-extern int i2o_exec_lct_get(struct i2o_controller *);
-extern void i2o_device_remove(struct i2o_device *);
-
-extern int __init i2o_driver_init(void);
-extern void __exit i2o_driver_exit(void);
-extern int __init i2o_exec_init(void);
-extern void __exit i2o_exec_exit(void);
-extern int __init i2o_pci_init(void);
-extern void __exit i2o_pci_exit(void);
-extern int i2o_device_init(void);
-extern void i2o_device_exit(void);
-
 /**
  *	i2o_msg_nop - Returns a message which is not used
  *	@c: I2O controller from which the message was created
@@ -68,7 +56,7 @@ extern void i2o_device_exit(void);
  */
 void i2o_msg_nop(struct i2o_controller *c, u32 m)
 {
-	struct i2o_message __iomem *msg = c->in_queue.virt + m;
+	struct i2o_message __iomem *msg = i2o_msg_in_to_virt(c, m);
 
 	writel(THREE_WORD_MSG_SIZE | SGL_OFFSET_0, &msg->u.head[0]);
 	writel(I2O_CMD_UTIL_NOP << 24 | HOST_TID << 12 | ADAPTER_TID,
@@ -92,16 +80,16 @@ void i2o_msg_nop(struct i2o_controller *
  *	address from the read port (see the i2o spec). If no message is
  *	available returns I2O_QUEUE_EMPTY and msg is leaved untouched.
  */
-u32 i2o_msg_get_wait(struct i2o_controller *c, struct i2o_message __iomem **msg,
-		     int wait)
+u32 i2o_msg_get_wait(struct i2o_controller *c,
+		     struct i2o_message __iomem ** msg, int wait)
 {
 	unsigned long timeout = jiffies + wait * HZ;
 	u32 m;
 
 	while ((m = i2o_msg_get(c, msg)) == I2O_QUEUE_EMPTY) {
 		if (time_after(jiffies, timeout)) {
-			pr_debug("%s: Timeout waiting for message frame.\n",
-				 c->name);
+			osm_debug("%s: Timeout waiting for message frame.\n",
+				  c->name);
 			return I2O_QUEUE_EMPTY;
 		}
 		set_current_state(TASK_UNINTERRUPTIBLE);
@@ -129,13 +117,13 @@ u32 i2o_cntxt_list_add(struct i2o_contro
 	unsigned long flags;
 
 	if (!ptr)
-		printk(KERN_ERR "%s: couldn't add NULL pointer to context list!"
-		       "\n", c->name);
+		osm_err("%s: couldn't add NULL pointer to context list!\n",
+			c->name);
 
 	entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
 	if (!entry) {
-		printk(KERN_ERR "%s: Could not allocate memory for context "
-		       "list element\n", c->name);
+		osm_err("%s: Could not allocate memory for context list element"
+			"\n", c->name);
 		return 0;
 	}
 
@@ -154,7 +142,7 @@ u32 i2o_cntxt_list_add(struct i2o_contro
 
 	spin_unlock_irqrestore(&c->context_list_lock, flags);
 
-	pr_debug("%s: Add context to list %p -> %d\n", c->name, ptr, context);
+	osm_debug("%s: Add context to list %p -> %d\n", c->name, ptr, context);
 
 	return entry->context;
 };
@@ -186,11 +174,11 @@ u32 i2o_cntxt_list_remove(struct i2o_con
 	spin_unlock_irqrestore(&c->context_list_lock, flags);
 
 	if (!context)
-		printk(KERN_WARNING "%s: Could not remove nonexistent ptr "
-		       "%p\n", c->name, ptr);
+		osm_warn("%s: Could not remove nonexistent ptr %p\n", c->name,
+			 ptr);
 
-	pr_debug("%s: remove ptr from context list %d -> %p\n", c->name,
-		 context, ptr);
+	osm_debug("%s: remove ptr from context list %d -> %p\n", c->name,
+		  context, ptr);
 
 	return context;
 };
@@ -220,11 +208,10 @@ void *i2o_cntxt_list_get(struct i2o_cont
 	spin_unlock_irqrestore(&c->context_list_lock, flags);
 
 	if (!ptr)
-		printk(KERN_WARNING "%s: context id %d not found\n", c->name,
-		       context);
+		osm_warn("%s: context id %d not found\n", c->name, context);
 
-	pr_debug("%s: get ptr from context list %d -> %p\n", c->name, context,
-		 ptr);
+	osm_debug("%s: get ptr from context list %d -> %p\n", c->name, context,
+		  ptr);
 
 	return ptr;
 };
@@ -252,11 +239,11 @@ u32 i2o_cntxt_list_get_ptr(struct i2o_co
 	spin_unlock_irqrestore(&c->context_list_lock, flags);
 
 	if (!context)
-		printk(KERN_WARNING "%s: Could not find nonexistent ptr "
-		       "%p\n", c->name, ptr);
+		osm_warn("%s: Could not find nonexistent ptr %p\n", c->name,
+			 ptr);
 
-	pr_debug("%s: get context id from context list %p -> %d\n", c->name,
-		 ptr, context);
+	osm_debug("%s: get context id from context list %p -> %d\n", c->name,
+		  ptr, context);
 
 	return context;
 };
@@ -336,10 +323,9 @@ static int i2o_iop_quiesce(struct i2o_co
 
 	/* Long timeout needed for quiesce if lots of devices */
 	if ((rc = i2o_msg_post_wait(c, m, 240)))
-		printk(KERN_INFO "%s: Unable to quiesce (status=%#x).\n",
-		       c->name, -rc);
+		osm_info("%s: Unable to quiesce (status=%#x).\n", c->name, -rc);
 	else
-		pr_debug("%s: Quiesced.\n", c->name);
+		osm_debug("%s: Quiesced.\n", c->name);
 
 	i2o_status_get(c);	// Entered READY state
 
@@ -377,10 +363,9 @@ static int i2o_iop_enable(struct i2o_con
 
 	/* How long of a timeout do we need? */
 	if ((rc = i2o_msg_post_wait(c, m, 240)))
-		printk(KERN_ERR "%s: Could not enable (status=%#x).\n",
-		       c->name, -rc);
+		osm_err("%s: Could not enable (status=%#x).\n", c->name, -rc);
 	else
-		pr_debug("%s: Enabled.\n", c->name);
+		osm_debug("%s: Enabled.\n", c->name);
 
 	i2o_status_get(c);	// entered OPERATIONAL state
 
@@ -444,20 +429,78 @@ static int i2o_iop_clear(struct i2o_cont
 	       &msg->u.head[1]);
 
 	if ((rc = i2o_msg_post_wait(c, m, 30)))
-		printk(KERN_INFO "%s: Unable to clear (status=%#x).\n",
-		       c->name, -rc);
+		osm_info("%s: Unable to clear (status=%#x).\n", c->name, -rc);
 	else
-		pr_debug("%s: Cleared.\n", c->name);
+		osm_debug("%s: Cleared.\n", c->name);
 
 	/* Enable all IOPs */
 	i2o_iop_enable_all();
 
-	i2o_status_get(c);
-
 	return rc;
 }
 
 /**
+ *	i2o_iop_init_outbound_queue - setup the outbound message queue
+ *	@c: I2O controller
+ *
+ *	Clear and (re)initialize IOP's outbound queue and post the message
+ *	frames to the IOP.
+ *
+ *	Returns 0 on success or a negative errno code on failure.
+ */
+static int i2o_iop_init_outbound_queue(struct i2o_controller *c)
+{
+	volatile u8 *status = c->status.virt;
+	u32 m;
+	struct i2o_message __iomem *msg;
+	ulong timeout;
+	int i;
+
+	osm_debug("%s: Initializing Outbound Queue...\n", c->name);
+
+	memset(c->status.virt, 0, 4);
+
+	m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET);
+	if (m == I2O_QUEUE_EMPTY)
+		return -ETIMEDOUT;
+
+	writel(EIGHT_WORD_MSG_SIZE | SGL_OFFSET_6, &msg->u.head[0]);
+	writel(I2O_CMD_OUTBOUND_INIT << 24 | HOST_TID << 12 | ADAPTER_TID,
+	       &msg->u.head[1]);
+	writel(i2o_exec_driver.context, &msg->u.s.icntxt);
+	writel(0x00000000, &msg->u.s.tcntxt);
+	writel(PAGE_SIZE, &msg->body[0]);
+	/* Outbound msg frame size in words and Initcode */
+	writel(I2O_OUTBOUND_MSG_FRAME_SIZE << 16 | 0x80, &msg->body[1]);
+	writel(0xd0000004, &msg->body[2]);
+	writel(i2o_dma_low(c->status.phys), &msg->body[3]);
+	writel(i2o_dma_high(c->status.phys), &msg->body[4]);
+
+	i2o_msg_post(c, m);
+
+	timeout = jiffies + I2O_TIMEOUT_INIT_OUTBOUND_QUEUE * HZ;
+	while (*status <= I2O_CMD_IN_PROGRESS) {
+		if (time_after(jiffies, timeout)) {
+			osm_warn("%s: Timeout Initializing\n", c->name);
+			return -ETIMEDOUT;
+		}
+		set_current_state(TASK_UNINTERRUPTIBLE);
+		schedule_timeout(1);
+	}
+
+	m = c->out_queue.phys;
+
+	/* Post frames */
+	for (i = 0; i < I2O_MAX_OUTBOUND_MSG_FRAMES; i++) {
+		i2o_flush_reply(c, m);
+		udelay(1);	/* Promise */
+		m += I2O_OUTBOUND_MSG_FRAME_SIZE * sizeof(u32);
+	}
+
+	return 0;
+}
+
+/**
  *	i2o_iop_reset - reset an I2O controller
  *	@c: controller to reset
  *
@@ -468,20 +511,20 @@ static int i2o_iop_clear(struct i2o_cont
  */
 static int i2o_iop_reset(struct i2o_controller *c)
 {
-	u8 *status = c->status.virt;
+	volatile u8 *status = c->status.virt;
 	struct i2o_message __iomem *msg;
 	u32 m;
 	unsigned long timeout;
 	i2o_status_block *sb = c->status_block.virt;
 	int rc = 0;
 
-	pr_debug("%s: Resetting controller\n", c->name);
+	osm_debug("%s: Resetting controller\n", c->name);
 
 	m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET);
 	if (m == I2O_QUEUE_EMPTY)
 		return -ETIMEDOUT;
 
-	memset(status, 0, 8);
+	memset(c->status_block.virt, 0, 8);
 
 	/* Quiesce all IOPs first */
 	i2o_iop_quiesce_all();
@@ -493,49 +536,43 @@ static int i2o_iop_reset(struct i2o_cont
 	writel(0, &msg->u.s.tcntxt);	//FIXME: use reasonable transaction context
 	writel(0, &msg->body[0]);
 	writel(0, &msg->body[1]);
-	writel(i2o_ptr_low((void *)c->status.phys), &msg->body[2]);
-	writel(i2o_ptr_high((void *)c->status.phys), &msg->body[3]);
+	writel(i2o_dma_low(c->status.phys), &msg->body[2]);
+	writel(i2o_dma_high(c->status.phys), &msg->body[3]);
 
 	i2o_msg_post(c, m);
 
 	/* Wait for a reply */
 	timeout = jiffies + I2O_TIMEOUT_RESET * HZ;
 	while (!*status) {
-		if (time_after(jiffies, timeout)) {
-			printk(KERN_ERR "%s: IOP reset timeout.\n", c->name);
-			rc = -ETIMEDOUT;
-			goto exit;
-		}
-
-		/* Promise bug */
-		if (status[1] || status[4]) {
-			*status = 0;
+		if (time_after(jiffies, timeout))
 			break;
-		}
 
 		set_current_state(TASK_UNINTERRUPTIBLE);
 		schedule_timeout(1);
-
-		rmb();
 	}
 
-	if (*status == I2O_CMD_IN_PROGRESS) {
+	switch (*status) {
+	case I2O_CMD_REJECTED:
+		osm_warn("%s: IOP reset rejected\n", c->name);
+		rc = -EPERM;
+		break;
+
+	case I2O_CMD_IN_PROGRESS:
 		/*
 		 * Once the reset is sent, the IOP goes into the INIT state
-		 * which is indeterminate.  We need to wait until the IOP
-		 * has rebooted before we can let the system talk to
-		 * it. We read the inbound Free_List until a message is
-		 * available. If we can't read one in the given ammount of
-		 * time, we assume the IOP could not reboot properly.
+		 * which is indeterminate. We need to wait until the IOP has
+		 * rebooted before we can let the system talk to it. We read
+		 * the inbound Free_List until a message is available. If we
+		 * can't read one in the given ammount of time, we assume the
+		 * IOP could not reboot properly.
 		 */
-		pr_debug("%s: Reset in progress, waiting for reboot...\n",
-			 c->name);
+		osm_debug("%s: Reset in progress, waiting for reboot...\n",
+			  c->name);
 
 		m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_RESET);
 		while (m == I2O_QUEUE_EMPTY) {
 			if (time_after(jiffies, timeout)) {
-				printk(KERN_ERR "%s: IOP reset timeout.\n",
-				       c->name);
+				osm_err("%s: IOP reset timeout.\n", c->name);
 				rc = -ETIMEDOUT;
 				goto exit;
 			}
@@ -545,19 +582,26 @@ static int i2o_iop_reset(struct i2o_cont
 			m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_RESET);
 		}
 		i2o_msg_nop(c, m);
-	}
 
-	/* from here all quiesce commands are safe */
-	c->no_quiesce = 0;
+		/* from here all quiesce commands are safe */
+		c->no_quiesce = 0;
 
-	/* If IopReset was rejected or didn't perform reset, try IopClear */
-	i2o_status_get(c);
-	if (*status == I2O_CMD_REJECTED || sb->iop_state != ADAPTER_STATE_RESET) {
-		printk(KERN_WARNING "%s: Reset rejected, trying to clear\n",
-		       c->name);
-		i2o_iop_clear(c);
-	} else
-		pr_debug("%s: Reset completed.\n", c->name);
+		/* verify if controller is in state RESET */
+		i2o_status_get(c);
+
+		if (!c->promise && (sb->iop_state != ADAPTER_STATE_RESET))
+			osm_warn("%s: reset completed, but adapter not in RESET"
+				 " state.\n", c->name);
+		else
+			osm_debug("%s: reset completed.\n", c->name);
+
+		break;
+
+	default:
+		osm_err("%s: IOP reset timeout.\n", c->name);
+		rc = -ETIMEDOUT;
+		break;
+	}
 
       exit:
 	/* Enable all IOPs */
@@ -567,88 +611,6 @@ static int i2o_iop_reset(struct i2o_cont
 };
 
 /**
- *	i2o_iop_init_outbound_queue - setup the outbound message queue
- *	@c: I2O controller
- *
- *	Clear and (re)initialize IOP's outbound queue and post the message
- *	frames to the IOP.
- *
- *	Returns 0 on success or a negative errno code on failure.
- */
-static int i2o_iop_init_outbound_queue(struct i2o_controller *c)
-{
-	u8 *status = c->status.virt;
-	u32 m;
-	struct i2o_message __iomem *msg;
-	ulong timeout;
-	int i;
-
-	pr_debug("%s: Initializing Outbound Queue...\n", c->name);
-
-	memset(status, 0, 4);
-
-	m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET);
-	if (m == I2O_QUEUE_EMPTY)
-		return -ETIMEDOUT;
-
-	writel(EIGHT_WORD_MSG_SIZE | TRL_OFFSET_6, &msg->u.head[0]);
-	writel(I2O_CMD_OUTBOUND_INIT << 24 | HOST_TID << 12 | ADAPTER_TID,
-	       &msg->u.head[1]);
-	writel(i2o_exec_driver.context, &msg->u.s.icntxt);
-	writel(0x0106, &msg->u.s.tcntxt);	/* FIXME: why 0x0106, maybe in
-						   Spec? */
-	writel(PAGE_SIZE, &msg->body[0]);
-	writel(MSG_FRAME_SIZE << 16 | 0x80, &msg->body[1]);	/* Outbound msg frame
-								   size in words and Initcode */
-	writel(0xd0000004, &msg->body[2]);
-	writel(i2o_ptr_low((void *)c->status.phys), &msg->body[3]);
-	writel(i2o_ptr_high((void *)c->status.phys), &msg->body[4]);
-
-	i2o_msg_post(c, m);
-
-	timeout = jiffies + I2O_TIMEOUT_INIT_OUTBOUND_QUEUE * HZ;
-	while (*status <= I2O_CMD_IN_PROGRESS) {
-		if (time_after(jiffies, timeout)) {
-			printk(KERN_WARNING "%s: Timeout Initializing\n",
-			       c->name);
-			return -ETIMEDOUT;
-		}
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(1);
-
-		rmb();
-	}
-
-	m = c->out_queue.phys;
-
-	/* Post frames */
-	for (i = 0; i < NMBR_MSG_FRAMES; i++) {
-		i2o_flush_reply(c, m);
-		udelay(1);	/* Promise */
-		m += MSG_FRAME_SIZE * 4;
-	}
-
-	return 0;
-}
-
-/**
- *	i2o_iop_send_nop - send a core NOP message
- *	@c: controller
- *
- *	Send a no-operation message with a reply set to cause no
- *	action either. Needed for bringing up promise controllers.
- */
-static int i2o_iop_send_nop(struct i2o_controller *c)
-{
-	struct i2o_message __iomem *msg;
-	u32 m = i2o_msg_get_wait(c, &msg, HZ);
-	if (m == I2O_QUEUE_EMPTY)
-		return -ETIMEDOUT;
-	i2o_msg_nop(c, m);
-	return 0;
-}
-
-/**
  *	i2o_iop_activate - Bring controller up to HOLD
  *	@c: controller
  *
@@ -659,78 +621,62 @@ static int i2o_iop_send_nop(struct i2o_c
  */
 static int i2o_iop_activate(struct i2o_controller *c)
 {
-	struct pci_dev *i960 = NULL;
 	i2o_status_block *sb = c->status_block.virt;
 	int rc;
-
-	if (c->promise) {
-		/* Beat up the hardware first of all */
-		i960 =
-		    pci_find_slot(c->pdev->bus->number,
-				  PCI_DEVFN(PCI_SLOT(c->pdev->devfn), 0));
-		if (i960)
-			pci_write_config_word(i960, 0x42, 0);
-
-		/* Follow this sequence precisely or the controller
-		   ceases to perform useful functions until reboot */
-		if ((rc = i2o_iop_send_nop(c)))
-			return rc;
-
-		if ((rc = i2o_iop_reset(c)))
-			return rc;
-	}
+	int state;
 
 	/* In INIT state, Wait Inbound Q to initialize (in i2o_status_get) */
 	/* In READY state, Get status */
 
 	rc = i2o_status_get(c);
 	if (rc) {
-		printk(KERN_INFO "%s: Unable to obtain status, "
-		       "attempting a reset.\n", c->name);
-		if (i2o_iop_reset(c))
+		osm_info("%s: Unable to obtain status, attempting a reset.\n",
+			 c->name);
+		rc = i2o_iop_reset(c);
+		if (rc)
 			return rc;
 	}
 
 	if (sb->i2o_version > I2OVER15) {
-		printk(KERN_ERR "%s: Not running version 1.5 of the I2O "
-		       "Specification.\n", c->name);
+		osm_err("%s: Not running version 1.5 of the I2O Specification."
+			"\n", c->name);
 		return -ENODEV;
 	}
 
 	switch (sb->iop_state) {
 	case ADAPTER_STATE_FAULTED:
-		printk(KERN_CRIT "%s: hardware fault\n", c->name);
-		return -ENODEV;
+		osm_err("%s: hardware fault\n", c->name);
+		return -EFAULT;
 
 	case ADAPTER_STATE_READY:
 	case ADAPTER_STATE_OPERATIONAL:
 	case ADAPTER_STATE_HOLD:
 	case ADAPTER_STATE_FAILED:
-		pr_debug("%s: already running, trying to reset...\n", c->name);
-		if (i2o_iop_reset(c))
-			return -ENODEV;
+		osm_debug("%s: already running, trying to reset...\n", c->name);
+		rc = i2o_iop_reset(c);
+		if (rc)
+			return rc;
 	}
 
+	/* preserve state */
+	state = sb->iop_state;
+
 	rc = i2o_iop_init_outbound_queue(c);
 	if (rc)
 		return rc;
 
-	if (c->promise) {
-		if ((rc = i2o_iop_send_nop(c)))
-			return rc;
+	/* if adapter was not in RESET state clear now */
+	if (state != ADAPTER_STATE_RESET)
+		i2o_iop_clear(c);
 
-		if ((rc = i2o_status_get(c)))
-			return rc;
+	i2o_status_get(c);
 
-		if (i960)
-			pci_write_config_word(i960, 0x42, 0x3FF);
+	if (sb->iop_state != ADAPTER_STATE_HOLD) {
+		osm_err("%s: failed to bring IOP into HOLD state\n", c->name);
+		return -EIO;
 	}
 
-	/* In HOLD state */
-
-	rc = i2o_hrt_get(c);
-
-	return rc;
+	return i2o_hrt_get(c);
 };
 
 /**
@@ -756,20 +702,18 @@ static int i2o_iop_systab_set(struct i2o
 		res->flags = IORESOURCE_MEM;
 		res->start = 0;
 		res->end = 0;
-		printk(KERN_INFO "%s: requires private memory resources.\n",
-		       c->name);
+		osm_info("%s: requires private memory resources.\n", c->name);
 		root = pci_find_parent_resource(c->pdev, res);
 		if (root == NULL)
-			printk(KERN_WARNING "%s: Can't find parent resource!\n",
-			       c->name);
+			osm_warn("%s: Can't find parent resource!\n", c->name);
 		if (root && allocate_resource(root, res, sb->desired_mem_size, sb->desired_mem_size, sb->desired_mem_size, 1 << 20,	/* Unspecified, so use 1Mb and play safe */
 					      NULL, NULL) >= 0) {
 			c->mem_alloc = 1;
 			sb->current_mem_size = 1 + res->end - res->start;
 			sb->current_mem_base = res->start;
-			printk(KERN_INFO "%s: allocated %ld bytes of PCI memory"
-			       " at 0x%08lX.\n", c->name,
-			       1 + res->end - res->start, res->start);
+			osm_info("%s: allocated %ld bytes of PCI memory at "
+				 "0x%08lX.\n", c->name,
+				 1 + res->end - res->start, res->start);
 		}
 	}
 
@@ -779,20 +723,18 @@ static int i2o_iop_systab_set(struct i2o
 		res->flags = IORESOURCE_IO;
 		res->start = 0;
 		res->end = 0;
-		printk(KERN_INFO "%s: requires private memory resources.\n",
-		       c->name);
+		osm_info("%s: requires private memory resources.\n", c->name);
 		root = pci_find_parent_resource(c->pdev, res);
 		if (root == NULL)
-			printk(KERN_WARNING "%s: Can't find parent resource!\n",
-			       c->name);
+			osm_warn("%s: Can't find parent resource!\n", c->name);
 		if (root && allocate_resource(root, res, sb->desired_io_size, sb->desired_io_size, sb->desired_io_size, 1 << 20,	/* Unspecified, so use 1Mb and play safe */
 					      NULL, NULL) >= 0) {
 			c->io_alloc = 1;
 			sb->current_io_size = 1 + res->end - res->start;
 			sb->current_mem_base = res->start;
-			printk(KERN_INFO "%s: allocated %ld bytes of PCI I/O at"
-			       " 0x%08lX.\n", c->name,
-			       1 + res->end - res->start, res->start);
+			osm_info("%s: allocated %ld bytes of PCI I/O at 0x%08lX"
+				 ".\n", c->name, 1 + res->end - res->start,
+				 res->start);
 		}
 	}
 
@@ -836,10 +778,10 @@ static int i2o_iop_systab_set(struct i2o
 			 PCI_DMA_TODEVICE);
 
 	if (rc < 0)
-		printk(KERN_ERR "%s: Unable to set SysTab (status=%#x).\n",
-		       c->name, -rc);
+		osm_err("%s: Unable to set SysTab (status=%#x).\n", c->name,
+			-rc);
 	else
-		pr_debug("%s: SysTab set.\n", c->name);
+		osm_debug("%s: SysTab set.\n", c->name);
 
 	i2o_status_get(c);	// Entered READY state
 
@@ -863,7 +805,7 @@ static int i2o_iop_online(struct i2o_con
 		return rc;
 
 	/* In READY state */
-	pr_debug("%s: Attempting to enable...\n", c->name);
+	osm_debug("%s: Attempting to enable...\n", c->name);
 	rc = i2o_iop_enable(c);
 	if (rc)
 		return rc;
@@ -882,7 +824,7 @@ void i2o_iop_remove(struct i2o_controlle
 {
 	struct i2o_device *dev, *tmp;
 
-	pr_debug("%s: deleting controller\n", c->name);
+	osm_debug("%s: deleting controller\n", c->name);
 
 	i2o_driver_notify_controller_remove_all(c);
 
@@ -891,8 +833,12 @@ void i2o_iop_remove(struct i2o_controlle
 	list_for_each_entry_safe(dev, tmp, &c->devices, list)
 	    i2o_device_remove(dev);
 
+	device_del(&c->device);
+
 	/* Ask the IOP to switch to RESET state */
 	i2o_iop_reset(c);
+
+	put_device(&c->device);
 }
 
 /**
@@ -927,8 +873,7 @@ static int i2o_systab_build(void)
 
 	systab = i2o_systab.virt = kmalloc(i2o_systab.len, GFP_KERNEL);
 	if (!systab) {
-		printk(KERN_ERR "i2o: unable to allocate memory for System "
-		       "Table\n");
+		osm_err("unable to allocate memory for System Table\n");
 		return -ENOMEM;
 	}
 	memset(systab, 0, i2o_systab.len);
@@ -940,8 +885,8 @@ static int i2o_systab_build(void)
 		i2o_status_block *sb;
 
 		if (count >= num_controllers) {
-			printk(KERN_ERR "i2o: controller added while building "
-			       "system table\n");
+			osm_err("controller added while building system table"
+				"\n");
 			break;
 		}
 
@@ -955,9 +900,8 @@ static int i2o_systab_build(void)
 		 * it is techninically not part of the I2O subsystem...
 		 */
 		if (unlikely(i2o_status_get(c))) {
-			printk(KERN_ERR "%s: Deleting b/c could not get status"
-			       " while attempting to build system table\n",
-			       c->name);
+			osm_err("%s: Deleting b/c could not get status while "
+				"attempting to build system table\n", c->name);
 			i2o_iop_remove(c);
 			continue;	// try the next one
 		}
@@ -971,8 +915,10 @@ static int i2o_systab_build(void)
 		systab->iops[count].frame_size = sb->inbound_frame_size;
 		systab->iops[count].last_changed = change_ind;
 		systab->iops[count].iop_capabilities = sb->iop_capabilities;
-		systab->iops[count].inbound_low = i2o_ptr_low(c->post_port);
-		systab->iops[count].inbound_high = i2o_ptr_high(c->post_port);
+		systab->iops[count].inbound_low =
+		    i2o_dma_low(c->base.phys + I2O_IN_PORT);
+		systab->iops[count].inbound_high =
+		    i2o_dma_high(c->base.phys + I2O_IN_PORT);
 
 		count++;
 	}
@@ -1010,11 +956,11 @@ int i2o_status_get(struct i2o_controller
 {
 	struct i2o_message __iomem *msg;
 	u32 m;
-	u8 *status_block;
+	volatile u8 *status_block;
 	unsigned long timeout;
 
 	status_block = (u8 *) c->status_block.virt;
-	memset(status_block, 0, sizeof(i2o_status_block));
+	memset(c->status_block.virt, 0, sizeof(i2o_status_block));
 
 	m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET);
 	if (m == I2O_QUEUE_EMPTY)
@@ -1027,8 +973,8 @@ int i2o_status_get(struct i2o_controller
 	writel(0, &msg->u.s.tcntxt);	// FIXME: use resonable transaction context
 	writel(0, &msg->body[0]);
 	writel(0, &msg->body[1]);
-	writel(i2o_ptr_low((void *)c->status_block.phys), &msg->body[2]);
-	writel(i2o_ptr_high((void *)c->status_block.phys), &msg->body[3]);
+	writel(i2o_dma_low(c->status_block.phys), &msg->body[2]);
+	writel(i2o_dma_high(c->status_block.phys), &msg->body[3]);
 	writel(sizeof(i2o_status_block), &msg->body[4]);	/* always 88 bytes */
 
 	i2o_msg_post(c, m);
@@ -1037,14 +983,12 @@ int i2o_status_get(struct i2o_controller
 	timeout = jiffies + I2O_TIMEOUT_STATUS_GET * HZ;
 	while (status_block[87] != 0xFF) {
 		if (time_after(jiffies, timeout)) {
-			printk(KERN_ERR "%s: Get status timeout.\n", c->name);
+			osm_err("%s: Get status timeout.\n", c->name);
 			return -ETIMEDOUT;
 		}
 
 		set_current_state(TASK_UNINTERRUPTIBLE);
 		schedule_timeout(1);
-
-		rmb();
 	}
 
 #ifdef DEBUG
@@ -1088,8 +1032,8 @@ static int i2o_hrt_get(struct i2o_contro
 		rc = i2o_msg_post_wait_mem(c, m, 20, &c->hrt);
 
 		if (rc < 0) {
-			printk(KERN_ERR "%s: Unable to get HRT (status=%#x)\n",
-			       c->name, -rc);
+			osm_err("%s: Unable to get HRT (status=%#x)\n", c->name,
+				-rc);
 			return rc;
 		}
 
@@ -1103,13 +1047,41 @@ static int i2o_hrt_get(struct i2o_contro
 			return i2o_parse_hrt(c);
 	}
 
-	printk(KERN_ERR "%s: Unable to get HRT after %d tries, giving up\n",
-	       c->name, I2O_HRT_GET_TRIES);
+	osm_err("%s: Unable to get HRT after %d tries, giving up\n", c->name,
+		I2O_HRT_GET_TRIES);
 
 	return -EBUSY;
 }
 
 /**
+ *	i2o_iop_free - Free the i2o_controller struct
+ *	@c: I2O controller to free
+ */
+void i2o_iop_free(struct i2o_controller *c)
+{
+	kfree(c);
+};
+
+/**
+ *	i2o_iop_release - release the memory for a I2O controller
+ *	@dev: I2O controller which should be released
+ *
+ *	Release the allocated memory. This function is called if refcount of
+ *	device reaches 0 automatically.
+ */
+static void i2o_iop_release(struct device *dev)
+{
+	struct i2o_controller *c = to_i2o_controller(dev);
+
+	i2o_iop_free(c);
+};
+
+/* I2O controller class */
+static struct class i2o_controller_class = {
+	.name = "i2o_controller",
+};
+
+/**
  *	i2o_iop_alloc - Allocate and initialize a i2o_controller struct
  *
  *	Allocate the necessary memory for a i2o_controller struct and
@@ -1125,8 +1097,8 @@ struct i2o_controller *i2o_iop_alloc(voi
 
 	c = kmalloc(sizeof(*c), GFP_KERNEL);
 	if (!c) {
-		printk(KERN_ERR "i2o: Insufficient memory to allocate a I2O "
-		       "controller.\n");
+		osm_err("i2o: Insufficient memory to allocate a I2O controller."
+			"\n");
 		return ERR_PTR(-ENOMEM);
 	}
 	memset(c, 0, sizeof(*c));
@@ -1137,6 +1109,16 @@ struct i2o_controller *i2o_iop_alloc(voi
 	c->unit = unit++;
 	sprintf(c->name, "iop%d", c->unit);
 
+	device_initialize(&c->device);
+	class_device_initialize(&c->classdev);
+
+	c->device.release = &i2o_iop_release;
+	c->classdev.class = &i2o_controller_class;
+	c->classdev.dev = &c->device;
+
+	snprintf(c->device.bus_id, BUS_ID_SIZE, "iop%d", c->unit);
+	snprintf(c->classdev.class_id, BUS_ID_SIZE, "iop%d", c->unit);
+
 #if BITS_PER_LONG == 64
 	spin_lock_init(&c->context_list_lock);
 	atomic_set(&c->context_list_counter, 0);
@@ -1147,15 +1129,6 @@ struct i2o_controller *i2o_iop_alloc(voi
 };
 
 /**
- *	i2o_iop_free - Free the i2o_controller struct
- *	@c: I2O controller to free
- */
-void i2o_iop_free(struct i2o_controller *c)
-{
-	kfree(c);
-};
-
-/**
  *	i2o_iop_add - Initialize the I2O controller and add him to the I2O core
  *	@c: controller
  *
@@ -1168,45 +1141,58 @@ int i2o_iop_add(struct i2o_controller *c
 {
 	int rc;
 
-	printk(KERN_INFO "%s: Activating I2O controller...\n", c->name);
-	printk(KERN_INFO "%s: This may take a few minutes if there are many "
-	       "devices\n", c->name);
+	if ((rc = device_add(&c->device))) {
+		osm_err("%s: could not add controller\n", c->name);
+		goto iop_reset;
+	}
 
-	if ((rc = i2o_iop_activate(c))) {
-		printk(KERN_ERR "%s: could not activate controller\n",
-		       c->name);
-		i2o_iop_reset(c);
-		return rc;
+	if ((rc = class_device_add(&c->classdev))) {
+		osm_err("%s: could not add controller class\n", c->name);
+		goto device_del;
 	}
 
-	pr_debug("%s: building sys table...\n", c->name);
+	osm_info("%s: Activating I2O controller...\n", c->name);
+	osm_info("%s: This may take a few minutes if there are many devices\n",
+		 c->name);
 
-	if ((rc = i2o_systab_build())) {
-		i2o_iop_reset(c);
-		return rc;
+	if ((rc = i2o_iop_activate(c))) {
+		osm_err("%s: could not activate controller\n", c->name);
+		goto class_del;
 	}
 
-	pr_debug("%s: online controller...\n", c->name);
+	osm_debug("%s: building sys table...\n", c->name);
 
-	if ((rc = i2o_iop_online(c))) {
-		i2o_iop_reset(c);
-		return rc;
-	}
+	if ((rc = i2o_systab_build()))
+		goto class_del;
 
-	pr_debug("%s: getting LCT...\n", c->name);
+	osm_debug("%s: online controller...\n", c->name);
 
-	if ((rc = i2o_exec_lct_get(c))) {
-		i2o_iop_reset(c);
-		return rc;
-	}
+	if ((rc = i2o_iop_online(c)))
+		goto class_del;
+
+	osm_debug("%s: getting LCT...\n", c->name);
+
+	if ((rc = i2o_exec_lct_get(c)))
+		goto class_del;
 
 	list_add(&c->list, &i2o_controllers);
 
 	i2o_driver_notify_controller_add_all(c);
 
-	printk(KERN_INFO "%s: Controller added\n", c->name);
+	osm_info("%s: Controller added\n", c->name);
 
 	return 0;
+
+      class_del:
+	class_device_del(&c->classdev);
+
+      device_del:
+	device_del(&c->device);
+
+      iop_reset:
+	i2o_iop_reset(c);
+
+	return rc;
 };
 
 /**
@@ -1264,16 +1250,18 @@ static int __init i2o_iop_init(void)
 	if (rc)
 		goto exit;
 
-	rc = i2o_driver_init();
-	if (rc)
+	if ((rc = class_register(&i2o_controller_class))) {
+		osm_err("can't register class i2o_controller\n");
 		goto device_exit;
+	}
 
-	rc = i2o_exec_init();
-	if (rc)
+	if ((rc = i2o_driver_init()))
+		goto class_exit;
+
+	if ((rc = i2o_exec_init()))
 		goto driver_exit;
 
-	rc = i2o_pci_init();
-	if (rc < 0)
+	if ((rc = i2o_pci_init()))
 		goto exec_exit;
 
 	return 0;
@@ -1284,6 +1272,9 @@ static int __init i2o_iop_init(void)
       driver_exit:
 	i2o_driver_exit();
 
+      class_exit:
+	class_unregister(&i2o_controller_class);
+
       device_exit:
 	i2o_device_exit();
 
@@ -1301,6 +1292,7 @@ static void __exit i2o_iop_exit(void)
 	i2o_pci_exit();
 	i2o_exec_exit();
 	i2o_driver_exit();
+	class_unregister(&i2o_controller_class);
 	i2o_device_exit();
 };
 
diff --git a/drivers/message/i2o/pci.c b/drivers/message/i2o/pci.c
--- a/drivers/message/i2o/pci.c
+++ b/drivers/message/i2o/pci.c
@@ -30,53 +30,20 @@
 #include <linux/pci.h>
 #include <linux/interrupt.h>
 #include <linux/i2o.h>
+#include "core.h"
 
-#ifdef CONFIG_MTRR
-#include <asm/mtrr.h>
-#endif				// CONFIG_MTRR
-
-/* Module internal functions from other sources */
-extern struct i2o_controller *i2o_iop_alloc(void);
-extern void i2o_iop_free(struct i2o_controller *);
-
-extern int i2o_iop_add(struct i2o_controller *);
-extern void i2o_iop_remove(struct i2o_controller *);
-
-extern int i2o_driver_dispatch(struct i2o_controller *, u32,
-			       struct i2o_message *);
+#define OSM_DESCRIPTION	"I2O-subsystem"
 
 /* PCI device id table for all I2O controllers */
 static struct pci_device_id __devinitdata i2o_pci_ids[] = {
 	{PCI_DEVICE_CLASS(PCI_CLASS_INTELLIGENT_I2O << 8, 0xffff00)},
 	{PCI_DEVICE(PCI_VENDOR_ID_DPT, 0xa511)},
+	{.vendor = PCI_VENDOR_ID_INTEL,.device = 0x1962,
+	 .subvendor = PCI_VENDOR_ID_PROMISE,.subdevice = PCI_ANY_ID},
 	{0}
 };
 
 /**
- *	i2o_dma_realloc - Realloc DMA memory
- *	@dev: struct device pointer to the PCI device of the I2O controller
- *	@addr: pointer to a i2o_dma struct DMA buffer
- *	@len: new length of memory
- *	@gfp_mask: GFP mask
- *
- *	If there was something allocated in the addr, free it first. If len > 0
- *	than try to allocate it and write the addresses back to the addr
- *	structure. If len == 0 set the virtual address to NULL.
- *
- *	Returns the 0 on success or negative error code on failure.
- */
-int i2o_dma_realloc(struct device *dev, struct i2o_dma *addr, size_t len,
-		    unsigned int gfp_mask)
-{
-	i2o_dma_free(dev, addr);
-
-	if (len)
-		return i2o_dma_alloc(dev, addr, len, gfp_mask);
-
-	return 0;
-};
-
-/**
  *	i2o_pci_free - Frees the DMA memory for the I2O controller
  *	@c: I2O controller to free
  *
@@ -91,24 +58,18 @@ static void i2o_pci_free(struct i2o_cont
 
 	i2o_dma_free(dev, &c->out_queue);
 	i2o_dma_free(dev, &c->status_block);
-	if (c->lct)
-		kfree(c->lct);
+	kfree(c->lct);
 	i2o_dma_free(dev, &c->dlct);
 	i2o_dma_free(dev, &c->hrt);
 	i2o_dma_free(dev, &c->status);
 
-#ifdef CONFIG_MTRR
-	if (c->mtrr_reg0 >= 0)
-		mtrr_del(c->mtrr_reg0, 0, 0);
-	if (c->mtrr_reg1 >= 0)
-		mtrr_del(c->mtrr_reg1, 0, 0);
-#endif
-
 	if (c->raptor && c->in_queue.virt)
 		iounmap(c->in_queue.virt);
 
 	if (c->base.virt)
 		iounmap(c->base.virt);
+
+	pci_release_regions(c->pdev);
 }
 
 /**
@@ -127,6 +88,11 @@ static int __devinit i2o_pci_alloc(struc
 	struct device *dev = &pdev->dev;
 	int i;
 
+	if (pci_request_regions(pdev, OSM_DESCRIPTION)) {
+		printk(KERN_ERR "%s: device already claimed\n", c->name);
+		return -ENODEV;
+	}
+
 	for (i = 0; i < 6; i++) {
 		/* Skip I/O spaces */
 		if (!(pci_resource_flags(pdev, i) & IORESOURCE_IO)) {
@@ -178,14 +144,16 @@ static int __devinit i2o_pci_alloc(struc
 		       c->name, (unsigned long)c->base.phys,
 		       (unsigned long)c->base.len);
 
-	c->base.virt = ioremap(c->base.phys, c->base.len);
+	c->base.virt = ioremap_nocache(c->base.phys, c->base.len);
 	if (!c->base.virt) {
 		printk(KERN_ERR "%s: Unable to map controller.\n", c->name);
+		i2o_pci_free(c);
 		return -ENOMEM;
 	}
 
 	if (c->raptor) {
-		c->in_queue.virt = ioremap(c->in_queue.phys, c->in_queue.len);
+		c->in_queue.virt =
+		    ioremap_nocache(c->in_queue.phys, c->in_queue.len);
 		if (!c->in_queue.virt) {
 			printk(KERN_ERR "%s: Unable to map controller.\n",
 			       c->name);
@@ -195,43 +163,10 @@ static int __devinit i2o_pci_alloc(struc
 	} else
 		c->in_queue = c->base;
 
-	c->irq_mask = c->base.virt + 0x34;
-	c->post_port = c->base.virt + 0x40;
-	c->reply_port = c->base.virt + 0x44;
-
-#ifdef CONFIG_MTRR
-	/* Enable Write Combining MTRR for IOP's memory region */
-	c->mtrr_reg0 = mtrr_add(c->in_queue.phys, c->in_queue.len,
-				MTRR_TYPE_WRCOMB, 1);
-	c->mtrr_reg1 = -1;
-
-	if (c->mtrr_reg0 < 0)
-		printk(KERN_WARNING "%s: could not enable write combining "
-		       "MTRR\n", c->name);
-	else
-		printk(KERN_INFO "%s: using write combining MTRR\n", c->name);
-
-	/*
-	 * 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 ((pdev->vendor == PCI_VENDOR_ID_INTEL ||
-	     pdev->vendor == PCI_VENDOR_ID_DPT) && !c->raptor) {
-		printk(KERN_INFO "%s: MTRR workaround for Intel i960 processor"
-		       "\n", c->name);
-		c->mtrr_reg1 = mtrr_add(c->base.phys, 0x10000,
-					MTRR_TYPE_UNCACHABLE, 1);
-
-		if (c->mtrr_reg1 < 0) {
-			printk(KERN_WARNING "%s: Error in setting "
-			       "MTRR_TYPE_UNCACHABLE\n", c->name);
-			mtrr_del(c->mtrr_reg0, c->in_queue.phys,
-				 c->in_queue.len);
-			c->mtrr_reg0 = -1;
-		}
-	}
-#endif
+	c->irq_status = c->base.virt + I2O_IRQ_STATUS;
+	c->irq_mask = c->base.virt + I2O_IRQ_MASK;
+	c->in_port = c->base.virt + I2O_IN_PORT;
+	c->out_port = c->base.virt + I2O_OUT_PORT;
 
 	if (i2o_dma_alloc(dev, &c->status, 8, GFP_KERNEL)) {
 		i2o_pci_free(c);
@@ -254,7 +189,10 @@ static int __devinit i2o_pci_alloc(struc
 		return -ENOMEM;
 	}
 
-	if (i2o_dma_alloc(dev, &c->out_queue, MSG_POOL_SIZE, GFP_KERNEL)) {
+	if (i2o_dma_alloc
+	    (dev, &c->out_queue,
+	     I2O_MAX_OUTBOUND_MSG_FRAMES * I2O_OUTBOUND_MSG_FRAME_SIZE *
+	     sizeof(u32), GFP_KERNEL)) {
 		i2o_pci_free(c);
 		return -ENOMEM;
 	}
@@ -276,51 +214,30 @@ static int __devinit i2o_pci_alloc(struc
 static irqreturn_t i2o_pci_interrupt(int irq, void *dev_id, struct pt_regs *r)
 {
 	struct i2o_controller *c = dev_id;
-	struct device *dev = &c->pdev->dev;
-	struct i2o_message *m;
-	u32 mv;
-
-	/*
-	 * Old 960 steppings had a bug in the I2O unit that caused
-	 * the queue to appear empty when it wasn't.
-	 */
-	mv = I2O_REPLY_READ32(c);
-	if (mv == I2O_QUEUE_EMPTY) {
-		mv = I2O_REPLY_READ32(c);
-		if (unlikely(mv == I2O_QUEUE_EMPTY)) {
-			return IRQ_NONE;
-		} else
-			pr_debug("%s: 960 bug detected\n", c->name);
-	}
-
-	while (mv != I2O_QUEUE_EMPTY) {
-		/*
-		 * Map the message from the page frame map to kernel virtual.
-		 * Because bus_to_virt is deprecated, we have calculate the
-		 * location by ourself!
-		 */
-		m = i2o_msg_out_to_virt(c, mv);
+	u32 m;
+	irqreturn_t rc = IRQ_NONE;
 
-		/*
-		 *      Ensure this message is seen coherently but cachably by
-		 *      the processor
-		 */
-		dma_sync_single_for_cpu(dev, mv, MSG_FRAME_SIZE * 4,
-					PCI_DMA_FROMDEVICE);
+	while (readl(c->irq_status) & I2O_IRQ_OUTBOUND_POST) {
+		m = readl(c->out_port);
+		if (m == I2O_QUEUE_EMPTY) {
+			/*
+			 * Old 960 steppings had a bug in the I2O unit that
+			 * caused the queue to appear empty when it wasn't.
+			 */
+			m = readl(c->out_port);
+			if (unlikely(m == I2O_QUEUE_EMPTY))
+				break;
+		}
 
 		/* dispatch it */
-		if (i2o_driver_dispatch(c, mv, m))
+		if (i2o_driver_dispatch(c, m))
 			/* flush it if result != 0 */
-			i2o_flush_reply(c, mv);
+			i2o_flush_reply(c, m);
 
-		/*
-		 * That 960 bug again...
-		 */
-		mv = I2O_REPLY_READ32(c);
-		if (mv == I2O_QUEUE_EMPTY)
-			mv = I2O_REPLY_READ32(c);
+		rc = IRQ_HANDLED;
 	}
-	return IRQ_HANDLED;
+
+	return rc;
 }
 
 /**
@@ -336,7 +253,7 @@ static int i2o_pci_irq_enable(struct i2o
 	struct pci_dev *pdev = c->pdev;
 	int rc;
 
-	I2O_IRQ_WRITE32(c, 0xffffffff);
+	writel(0xffffffff, c->irq_mask);
 
 	if (pdev->irq) {
 		rc = request_irq(pdev->irq, i2o_pci_interrupt, SA_SHIRQ,
@@ -348,7 +265,7 @@ static int i2o_pci_irq_enable(struct i2o
 		}
 	}
 
-	I2O_IRQ_WRITE32(c, 0x00000000);
+	writel(0x00000000, c->irq_mask);
 
 	printk(KERN_INFO "%s: Installed at IRQ %d\n", c->name, pdev->irq);
 
@@ -363,7 +280,7 @@ static int i2o_pci_irq_enable(struct i2o
  */
 static void i2o_pci_irq_disable(struct i2o_controller *c)
 {
-	I2O_IRQ_WRITE32(c, 0xffffffff);
+	writel(0xffffffff, c->irq_mask);
 
 	if (c->pdev->irq > 0)
 		free_irq(c->pdev->irq, c);
@@ -385,28 +302,25 @@ static int __devinit i2o_pci_probe(struc
 {
 	struct i2o_controller *c;
 	int rc;
+	struct pci_dev *i960 = NULL;
 
 	printk(KERN_INFO "i2o: Checking for PCI I2O controllers...\n");
 
 	if ((pdev->class & 0xff) > 1) {
-		printk(KERN_WARNING "i2o: I2O controller found but does not "
-		       "support I2O 1.5 (skipping).\n");
+		printk(KERN_WARNING "i2o: %s does not support I2O 1.5 "
+		       "(skipping).\n", pci_name(pdev));
 		return -ENODEV;
 	}
 
 	if ((rc = pci_enable_device(pdev))) {
-		printk(KERN_WARNING "i2o: I2O controller found but could not be"
-		       " enabled.\n");
+		printk(KERN_WARNING "i2o: couldn't enable device %s\n",
+		       pci_name(pdev));
 		return rc;
 	}
 
-	printk(KERN_INFO "i2o: I2O controller found on bus %d at %d.\n",
-	       pdev->bus->number, pdev->devfn);
-
 	if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
-		printk(KERN_WARNING "i2o: I2O controller on bus %d at %d: No "
-		       "suitable DMA available!\n", pdev->bus->number,
-		       pdev->devfn);
+		printk(KERN_WARNING "i2o: no suitable DMA found for %s\n",
+		       pci_name(pdev));
 		rc = -ENODEV;
 		goto disable;
 	}
@@ -415,14 +329,16 @@ static int __devinit i2o_pci_probe(struc
 
 	c = i2o_iop_alloc();
 	if (IS_ERR(c)) {
-		printk(KERN_ERR "i2o: memory for I2O controller could not be "
-		       "allocated\n");
+		printk(KERN_ERR "i2o: couldn't allocate memory for %s\n",
+		       pci_name(pdev));
 		rc = PTR_ERR(c);
 		goto disable;
-	}
+	} else
+		printk(KERN_INFO "%s: controller found (%s)\n", c->name,
+		       pci_name(pdev));
 
 	c->pdev = pdev;
-	c->device = pdev->dev;
+	c->device.parent = get_device(&pdev->dev);
 
 	/* Cards that fall apart if you hit them with large I/O loads... */
 	if (pdev->vendor == PCI_VENDOR_ID_NCR && pdev->device == 0x0630) {
@@ -432,16 +348,48 @@ static int __devinit i2o_pci_probe(struc
 	}
 
 	if (pdev->subsystem_vendor == PCI_VENDOR_ID_PROMISE) {
+		/*
+		 * Expose the ship behind i960 for initialization, or it will
+		 * failed
+		 */
+		i960 =
+		    pci_find_slot(c->pdev->bus->number,
+				  PCI_DEVFN(PCI_SLOT(c->pdev->devfn), 0));
+
+		if (i960)
+			pci_write_config_word(i960, 0x42, 0);
+
 		c->promise = 1;
-		printk(KERN_INFO "%s: Promise workarounds activated.\n",
-		       c->name);
+		c->limit_sectors = 1;
 	}
 
+	if (pdev->subsystem_vendor == PCI_VENDOR_ID_DPT)
+		c->adaptec = 1;
+
 	/* Cards that go bananas if you quiesce them before you reset them. */
 	if (pdev->vendor == PCI_VENDOR_ID_DPT) {
 		c->no_quiesce = 1;
 		if (pdev->device == 0xa511)
 			c->raptor = 1;
+
+		if (pdev->subsystem_device == 0xc05a) {
+			c->limit_sectors = 1;
+			printk(KERN_INFO
+			       "%s: limit sectors per request to %d\n", c->name,
+			       I2O_MAX_SECTORS_LIMITED);
+		}
+#ifdef CONFIG_I2O_EXT_ADAPTEC_DMA64
+		if (sizeof(dma_addr_t) > 4) {
+			if (pci_set_dma_mask(pdev, DMA_64BIT_MASK))
+				printk(KERN_INFO "%s: 64-bit DMA unavailable\n",
+				       c->name);
+			else {
+				c->pae_support = 1;
+				printk(KERN_INFO "%s: using 64-bit DMA\n",
+				       c->name);
+			}
+		}
+#endif
 	}
 
 	if ((rc = i2o_pci_alloc(c))) {
@@ -459,6 +407,11 @@ static int __devinit i2o_pci_probe(struc
 	if ((rc = i2o_iop_add(c)))
 		goto uninstall;
 
+	get_device(&c->device);
+
+	if (i960)
+		pci_write_config_word(i960, 0x42, 0x03ff);
+
 	return 0;
 
       uninstall:
@@ -469,6 +422,7 @@ static int __devinit i2o_pci_probe(struc
 
       free_controller:
 	i2o_iop_free(c);
+	put_device(c->device.parent);
 
       disable:
 	pci_disable_device(pdev);
@@ -492,15 +446,17 @@ static void __devexit i2o_pci_remove(str
 	i2o_pci_irq_disable(c);
 	i2o_pci_free(c);
 
+	pci_disable_device(pdev);
+
 	printk(KERN_INFO "%s: Controller removed.\n", c->name);
 
-	i2o_iop_free(c);
-	pci_disable_device(pdev);
+	put_device(c->device.parent);
+	put_device(&c->device);
 };
 
 /* PCI driver for I2O controller */
 static struct pci_driver i2o_pci_driver = {
-	.name = "I2O controller",
+	.name = "PCI_I2O",
 	.id_table = i2o_pci_ids,
 	.probe = i2o_pci_probe,
 	.remove = __devexit_p(i2o_pci_remove),
@@ -523,6 +479,4 @@ void __exit i2o_pci_exit(void)
 {
 	pci_unregister_driver(&i2o_pci_driver);
 };
-
-EXPORT_SYMBOL(i2o_dma_realloc);
 MODULE_DEVICE_TABLE(pci, i2o_pci_ids);
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -6,8 +6,7 @@ menu "Misc devices"
 
 config IBM_ASM
 	tristate "Device driver for IBM RSA service processor"
-	depends on X86 && EXPERIMENTAL
-	default n
+	depends on X86 && PCI && EXPERIMENTAL
 	---help---
 	  This option enables device driver support for in-band access to the
 	  IBM RSA (Condor) service processor in eServer xSeries systems.
@@ -22,7 +21,7 @@ config IBM_ASM
 	  
 	  WARNING: This software may not be supported or function
 	  correctly on your IBM server. Please consult the IBM ServerProven
-	  website <http://www.pc.ibm/ww/eserver/xseries/serverproven> for
+	  website <http://www.pc.ibm.com/ww/eserver/xseries/serverproven> for
 	  information on the specific driver level and support statement
 	  for your IBM server.
 
diff --git a/drivers/misc/ibmasm/command.c b/drivers/misc/ibmasm/command.c
--- a/drivers/misc/ibmasm/command.c
+++ b/drivers/misc/ibmasm/command.c
@@ -23,6 +23,7 @@
  */
 
 #include "ibmasm.h"
+#include "lowlevel.h"
 
 static void exec_next_command(struct service_processor *sp);
 static void free_command(struct kobject *kobj);
@@ -31,8 +32,9 @@ static struct kobj_type ibmasm_cmd_kobj_
 	.release = free_command,
 };
 
+static atomic_t command_count = ATOMIC_INIT(0);
 
-struct command *ibmasm_new_command(size_t buffer_size)
+struct command *ibmasm_new_command(struct service_processor *sp, size_t buffer_size)
 {
 	struct command *cmd;
 
@@ -55,11 +57,15 @@ struct command *ibmasm_new_command(size_
 
 	kobject_init(&cmd->kobj);
 	cmd->kobj.ktype = &ibmasm_cmd_kobj_type;
+	cmd->lock = &sp->lock;
 
 	cmd->status = IBMASM_CMD_PENDING;
 	init_waitqueue_head(&cmd->wait);
 	INIT_LIST_HEAD(&cmd->queue_node);
 
+	atomic_inc(&command_count);
+	dbg("command count: %d\n", atomic_read(&command_count));
+
 	return cmd;
 }
 
@@ -68,6 +74,8 @@ static void free_command(struct kobject 
 	struct command *cmd = to_command(kobj);
  
 	list_del(&cmd->queue_node);
+	atomic_dec(&command_count);
+	dbg("command count: %d\n", atomic_read(&command_count));
 	kfree(cmd->buffer);
 	kfree(cmd);
 }
@@ -94,8 +102,14 @@ static struct command *dequeue_command(s
 
 static inline void do_exec_command(struct service_processor *sp)
 {
+	char tsbuf[32];
+
+	dbg("%s:%d at %s\n", __FUNCTION__, __LINE__, get_timestamp(tsbuf));
+
 	if (ibmasm_send_i2o_message(sp)) {
 		sp->current_command->status = IBMASM_CMD_FAILED;
+		wake_up(&sp->current_command->wait);
+		command_put(sp->current_command);
 		exec_next_command(sp);
 	}
 }
@@ -111,14 +125,16 @@ static inline void do_exec_command(struc
 void ibmasm_exec_command(struct service_processor *sp, struct command *cmd)
 {
 	unsigned long flags;
+	char tsbuf[32];
+
+	dbg("%s:%d at %s\n", __FUNCTION__, __LINE__, get_timestamp(tsbuf));
 
 	spin_lock_irqsave(&sp->lock, flags);
 
 	if (!sp->current_command) {
-		command_get(cmd);
 		sp->current_command = cmd;
+		command_get(sp->current_command);
 		spin_unlock_irqrestore(&sp->lock, flags);
-
 		do_exec_command(sp);
 	} else {
 		enqueue_command(sp, cmd);
@@ -129,9 +145,9 @@ void ibmasm_exec_command(struct service_
 static void exec_next_command(struct service_processor *sp)
 {
 	unsigned long flags;
+	char tsbuf[32];
 
-	wake_up(&sp->current_command->wait);
-	command_put(sp->current_command);
+	dbg("%s:%d at %s\n", __FUNCTION__, __LINE__, get_timestamp(tsbuf));
 
 	spin_lock_irqsave(&sp->lock, flags);
 	sp->current_command = dequeue_command(sp);
@@ -169,7 +185,9 @@ void ibmasm_receive_command_response(str
 	if (!sp->current_command) 
 		return; 
 
-	memcpy(cmd->buffer, response, min(size, cmd->buffer_size));
+	memcpy_fromio(cmd->buffer, response, min(size, cmd->buffer_size));
 	cmd->status = IBMASM_CMD_COMPLETE;
+	wake_up(&sp->current_command->wait);
+	command_put(sp->current_command);
 	exec_next_command(sp);
 }
diff --git a/drivers/misc/ibmasm/dot_command.c b/drivers/misc/ibmasm/dot_command.c
--- a/drivers/misc/ibmasm/dot_command.c
+++ b/drivers/misc/ibmasm/dot_command.c
@@ -33,7 +33,13 @@ void ibmasm_receive_message(struct servi
 	u32 size;
 	struct dot_command_header *header = (struct dot_command_header *)message;
 
+	if (message_size == 0)
+		return;
+
 	size = get_dot_command_size(message);
+	if (size == 0)
+		return;
+
 	if (size > message_size)
 		size = message_size;
 
@@ -67,7 +73,7 @@ int ibmasm_send_driver_vpd(struct servic
 	u8 *vpd_data;
 	int result = 0;
 
-	command = ibmasm_new_command(INIT_BUFFER_SIZE);
+	command = ibmasm_new_command(sp, INIT_BUFFER_SIZE);
 	if (command == NULL)
 		return -ENOMEM;
 
@@ -121,7 +127,7 @@ int ibmasm_send_os_state(struct service_
 	struct os_state_command *os_state_cmd;
 	int result = 0;
 
-	cmd = ibmasm_new_command(sizeof(struct os_state_command));
+	cmd = ibmasm_new_command(sp, sizeof(struct os_state_command));
 	if (cmd == NULL)
 		return -ENOMEM;
 
diff --git a/drivers/misc/ibmasm/event.c b/drivers/misc/ibmasm/event.c
--- a/drivers/misc/ibmasm/event.c
+++ b/drivers/misc/ibmasm/event.c
@@ -23,6 +23,7 @@
  */
 
 #include "ibmasm.h"
+#include "lowlevel.h"
 
 /*
  * ASM service processor event handling routines.
@@ -34,7 +35,6 @@
  * circular buffer.
  */
 
-
 static void wake_up_event_readers(struct service_processor *sp)
 {
 	struct event_reader *reader;
@@ -63,7 +63,7 @@ void ibmasm_receive_event(struct service
 	spin_lock_irqsave(&sp->lock, flags);
 	/* copy the event into the next slot in the circular buffer */
 	event = &buffer->events[buffer->next_index];
-	memcpy(event->data, data, data_size);
+	memcpy_fromio(event->data, data, data_size);
 	event->data_size = data_size;
 	event->serial_number = buffer->next_serial_number;
 
@@ -93,7 +93,10 @@ int ibmasm_get_next_event(struct service
 	unsigned int index;
 	unsigned long flags;
 
-	if (wait_event_interruptible(reader->wait, event_available(buffer, reader)))
+	reader->cancelled = 0;
+
+	if (wait_event_interruptible(reader->wait,
+			event_available(buffer, reader) || reader->cancelled))
 		return -ERESTARTSYS;
 
 	if (!event_available(buffer, reader))
@@ -116,6 +119,12 @@ int ibmasm_get_next_event(struct service
 	return event->data_size;
 }
 
+void ibmasm_cancel_next_event(struct event_reader *reader)
+{
+        reader->cancelled = 1;
+        wake_up_interruptible(&reader->wait);
+}
+
 void ibmasm_event_reader_register(struct service_processor *sp, struct event_reader *reader)
 {
 	unsigned long flags;
@@ -131,8 +140,6 @@ void ibmasm_event_reader_unregister(stru
 {
 	unsigned long flags;
 
-	wake_up_interruptible(&reader->wait);
-
 	spin_lock_irqsave(&sp->lock, flags);
 	list_del(&reader->node);
 	spin_unlock_irqrestore(&sp->lock, flags);
@@ -164,6 +171,5 @@ int ibmasm_event_buffer_init(struct serv
 
 void ibmasm_event_buffer_exit(struct service_processor *sp)
 {
-	wake_up_event_readers(sp);
 	kfree(sp->event_buffer);
 }
diff --git a/drivers/misc/ibmasm/heartbeat.c b/drivers/misc/ibmasm/heartbeat.c
--- a/drivers/misc/ibmasm/heartbeat.c
+++ b/drivers/misc/ibmasm/heartbeat.c
@@ -25,6 +25,7 @@
 #include <linux/notifier.h>
 #include "ibmasm.h"
 #include "dot_command.h"
+#include "lowlevel.h"
 
 static int suspend_heartbeats = 0;
 
@@ -62,7 +63,7 @@ void ibmasm_unregister_panic_notifier(vo
 
 int ibmasm_heartbeat_init(struct service_processor *sp)
 {
-	sp->heartbeat = ibmasm_new_command(HEARTBEAT_BUFFER_SIZE);
+	sp->heartbeat = ibmasm_new_command(sp, HEARTBEAT_BUFFER_SIZE);
 	if (sp->heartbeat == NULL)
 		return -ENOMEM;
 
@@ -71,6 +72,12 @@ int ibmasm_heartbeat_init(struct service
 
 void ibmasm_heartbeat_exit(struct service_processor *sp)
 {
+	char tsbuf[32];
+
+	dbg("%s:%d at %s\n", __FUNCTION__, __LINE__, get_timestamp(tsbuf));
+	ibmasm_wait_for_response(sp->heartbeat, IBMASM_CMD_TIMEOUT_NORMAL);
+	dbg("%s:%d at %s\n", __FUNCTION__, __LINE__, get_timestamp(tsbuf));
+	suspend_heartbeats = 1;
 	command_put(sp->heartbeat);
 }
 
@@ -78,14 +85,16 @@ void ibmasm_receive_heartbeat(struct ser
 {
 	struct command *cmd = sp->heartbeat;
 	struct dot_command_header *header = (struct dot_command_header *)cmd->buffer;
+	char tsbuf[32];
 
+	dbg("%s:%d at %s\n", __FUNCTION__, __LINE__, get_timestamp(tsbuf));
 	if (suspend_heartbeats)
 		return;
 
 	/* return the received dot command to sender */
 	cmd->status = IBMASM_CMD_PENDING;
 	size = min(size, cmd->buffer_size);
-	memcpy(cmd->buffer, message, size);
+	memcpy_fromio(cmd->buffer, message, size);
 	header->type = sp_write;
 	ibmasm_exec_command(sp, cmd);
 }
diff --git a/drivers/misc/ibmasm/ibmasm.h b/drivers/misc/ibmasm/ibmasm.h
--- a/drivers/misc/ibmasm/ibmasm.h
+++ b/drivers/misc/ibmasm/ibmasm.h
@@ -34,16 +34,31 @@
 #include <linux/version.h>
 #include <linux/interrupt.h>
 #include <linux/device.h>
+#include <linux/input.h>
 
 /* Driver identification */
 #define DRIVER_NAME	"ibmasm"
-#define DRIVER_VERSION  "0.4"
-#define DRIVER_AUTHOR   "Max Asbock"
+#define DRIVER_VERSION  "1.0"
+#define DRIVER_AUTHOR   "Max Asbock <masbock@us.ibm.com>, Vernon Mauery <vernux@us.ibm.com>"
 #define DRIVER_DESC     "IBM ASM Service Processor Driver"
 
 #define err(msg) printk(KERN_ERR "%s: " msg "\n", DRIVER_NAME)
 #define info(msg) printk(KERN_INFO "%s: " msg "\n", DRIVER_NAME)
 
+extern int ibmasm_debug;
+#define dbg(STR, ARGS...)					\
+	do {							\
+		if (ibmasm_debug)				\
+			printk(KERN_DEBUG STR , ##ARGS);	\
+	} while (0)
+
+static inline char *get_timestamp(char *buf)
+{
+	struct timeval now;
+	do_gettimeofday(&now);
+	sprintf(buf, "%lu.%lu", now.tv_sec, now.tv_usec);
+	return buf;
+}
 
 #define IBMASM_CMD_PENDING	0	
 #define IBMASM_CMD_COMPLETE	1	
@@ -52,7 +67,7 @@
 #define IBMASM_CMD_TIMEOUT_NORMAL	45
 #define IBMASM_CMD_TIMEOUT_EXTRA	240
 
-#define IBMASM_CMD_MAX_BUFFER_SIZE	0x4000
+#define IBMASM_CMD_MAX_BUFFER_SIZE	0x8000
 
 #define REVERSE_HEARTBEAT_TIMEOUT	120
 
@@ -80,12 +95,17 @@ struct command {
 	size_t			buffer_size;
 	int			status;
 	struct kobject		kobj;
+	spinlock_t		*lock;
 };
 #define to_command(c) container_of(c, struct command, kobj)
 
 static inline void command_put(struct command *cmd)
 {
+	unsigned long flags;
+
+	spin_lock_irqsave(cmd->lock, flags);
         kobject_put(&cmd->kobj);
+	spin_unlock_irqrestore(cmd->lock, flags);
 }
 
 static inline void command_get(struct command *cmd)
@@ -108,6 +128,7 @@ struct event_buffer {
 };
 
 struct event_reader {
+	int			cancelled;
 	unsigned int		next_serial_number;
 	wait_queue_head_t	wait;
 	struct list_head	node;
@@ -120,41 +141,11 @@ struct reverse_heartbeat {
 	unsigned int		stopped;
 };
 
-
-/* remote console events */
-struct mouse_event {
-	long		x;
-	long		y;
-	unsigned char	buttons;
-	unsigned char	transitions;
-};
-
-struct keyboard_event {
-	unsigned long	key_code;
-	unsigned char	key_down;
-};
-
-struct remote_event {
-	unsigned long	type;
-	union {
-		struct mouse_event	mouse;
-		struct keyboard_event	keyboard;
-	} data;
-};
-
-#define DRIVER_REMOTE_QUEUE_SIZE 240
-
-struct remote_queue {
-	struct remote_event	*start;
-	struct remote_event	*end;
-	struct remote_event	*reader;
-	struct remote_event	*writer;
-	unsigned int		size;
-	int			open;
-	wait_queue_head_t	wait;
+struct ibmasm_remote {
+	struct input_dev keybd_dev;
+	struct input_dev mouse_dev;
 };
 
-
 struct service_processor {
 	struct list_head	node;
 	spinlock_t		lock;
@@ -167,13 +158,13 @@ struct service_processor {
 	char			dirname[IBMASM_NAME_SIZE];
 	char			devname[IBMASM_NAME_SIZE];
 	unsigned int		number;
-	struct remote_queue	remote_queue;
+	struct ibmasm_remote	*remote;
 	int			serial_line;
 	struct device		*dev;
 };
 
 /* command processing */
-extern struct command *ibmasm_new_command(size_t buffer_size);
+extern struct command *ibmasm_new_command(struct service_processor *sp, size_t buffer_size);
 extern void ibmasm_exec_command(struct service_processor *sp, struct command *cmd);
 extern void ibmasm_wait_for_response(struct command *cmd, int timeout);
 extern void ibmasm_receive_command_response(struct service_processor *sp, void *response,  size_t size);
@@ -185,6 +176,7 @@ extern void ibmasm_receive_event(struct 
 extern void ibmasm_event_reader_register(struct service_processor *sp, struct event_reader *reader);
 extern void ibmasm_event_reader_unregister(struct service_processor *sp, struct event_reader *reader);
 extern int ibmasm_get_next_event(struct service_processor *sp, struct event_reader *reader);
+extern void ibmasm_cancel_next_event(struct event_reader *reader);
 
 /* heartbeat - from SP to OS */
 extern void ibmasm_register_panic_notifier(void);
@@ -208,11 +200,9 @@ extern int ibmasm_send_i2o_message(struc
 extern irqreturn_t ibmasm_interrupt_handler(int irq, void * dev_id, struct pt_regs *regs);
 
 /* remote console */
-extern void ibmasm_handle_mouse_interrupt(struct service_processor *sp);
-extern int ibmasm_init_remote_queue(struct service_processor *sp);
-extern void ibmasm_free_remote_queue(struct service_processor *sp);
-extern void ibmasm_advance_reader(struct remote_queue *q, unsigned int n);
-extern size_t ibmasm_events_available(struct remote_queue *q);
+extern void ibmasm_handle_mouse_interrupt(struct service_processor *sp, struct pt_regs *regs);
+extern int ibmasm_init_remote_input_dev(struct service_processor *sp);
+extern void ibmasm_free_remote_input_dev(struct service_processor *sp);
 
 /* file system */
 extern int ibmasmfs_register(void);
diff --git a/drivers/misc/ibmasm/ibmasmfs.c b/drivers/misc/ibmasm/ibmasmfs.c
--- a/drivers/misc/ibmasm/ibmasmfs.c
+++ b/drivers/misc/ibmasm/ibmasmfs.c
@@ -37,9 +37,7 @@
  *    |   |-- event
  *    |   |-- reverse_heartbeat
  *    |   `-- remote_video
- *    |       |-- connected
  *    |       |-- depth
- *    |       |-- events
  *    |       |-- height
  *    |       `-- width
  *    .
@@ -50,9 +48,7 @@
  *        |-- event
  *        |-- reverse_heartbeat
  *        `-- remote_video
- *            |-- connected
  *            |-- depth
- *            |-- events
  *            |-- height
  *            `-- width
  *
@@ -75,14 +71,6 @@
  * remote_video/width: control remote display settings
  * 	write: set value
  * 	read: read value
- *
- * remote_video/connected
- * 	read: return "1" if web browser VNC java applet is connected, 
- * 		"0" otherwise
- *
- * remote_video/events
- * 	read: sleep until a remote mouse or keyboard event occurs, then return
- * 		then event.
  */
 
 #include <linux/fs.h>
@@ -333,7 +321,7 @@ static ssize_t command_file_write(struct
 	if (command_data->command)
 		return -EAGAIN;
 
-	cmd = ibmasm_new_command(count);
+	cmd = ibmasm_new_command(command_data->sp, count);
 	if (!cmd)
 		return -ENOMEM;
 
@@ -374,6 +362,7 @@ static int event_file_open(struct inode 
 	ibmasm_event_reader_register(sp, &event_data->reader);
 
 	event_data->sp = sp;
+	event_data->active = 0;
 	file->private_data = event_data;
 	return 0;
 }
@@ -391,7 +380,9 @@ static ssize_t event_file_read(struct fi
 {
 	struct ibmasmfs_event_data *event_data = file->private_data;
 	struct event_reader *reader = &event_data->reader;
+	struct service_processor *sp = event_data->sp;
 	int ret;
+	unsigned long flags;
 
 	if (*offset < 0)
 		return -EINVAL;
@@ -400,17 +391,32 @@ static ssize_t event_file_read(struct fi
 	if (*offset != 0)
 		return 0;
 
-	ret = ibmasm_get_next_event(event_data->sp, reader);
+	spin_lock_irqsave(&sp->lock, flags);
+	if (event_data->active) {
+		spin_unlock_irqrestore(&sp->lock, flags);
+		return -EBUSY;
+	}
+	event_data->active = 1;
+	spin_unlock_irqrestore(&sp->lock, flags);
+
+	ret = ibmasm_get_next_event(sp, reader);
 	if (ret <= 0)
-		return ret;
+		goto out;
 
-	if (count < reader->data_size)
-		return -EINVAL;
+	if (count < reader->data_size) {
+		ret = -EINVAL;
+		goto out;
+	}
 
-        if (copy_to_user(buf, reader->data, reader->data_size))
-		return -EFAULT;
+        if (copy_to_user(buf, reader->data, reader->data_size)) {
+		ret = -EFAULT;
+		goto out;
+	}
+	ret = reader->data_size;
 
-	return reader->data_size;
+out:
+	event_data->active = 0;
+	return ret;
 }
 
 static ssize_t event_file_write(struct file *file, const char __user *buf, size_t count, loff_t *offset)
@@ -424,7 +430,7 @@ static ssize_t event_file_write(struct f
 	if (*offset != 0)
 		return 0;
 
-	wake_up_interruptible(&event_data->reader.wait);
+	ibmasm_cancel_next_event(&event_data->reader);
 	return 0;
 }
 
@@ -575,75 +581,6 @@ static ssize_t remote_settings_file_writ
 	return count;
 }
 
-static int remote_event_file_open(struct inode *inode, struct file *file)
-{
-	struct service_processor *sp;
-	unsigned long flags;
-	struct remote_queue *q;
-	
-	file->private_data = inode->u.generic_ip;
-	sp = file->private_data;
-	q = &sp->remote_queue;
-
-	/* allow only one event reader */
-	spin_lock_irqsave(&sp->lock, flags);
-	if (q->open) {
-		spin_unlock_irqrestore(&sp->lock, flags);
-		return -EBUSY;
-	}
-	q->open = 1;
-	spin_unlock_irqrestore(&sp->lock, flags);
-
-	enable_mouse_interrupts(sp);
-	
-	return 0;
-}
-
-static int remote_event_file_close(struct inode *inode, struct file *file)
-{
-	struct service_processor *sp = file->private_data;
-
-	disable_mouse_interrupts(sp);
-	wake_up_interruptible(&sp->remote_queue.wait);
-	sp->remote_queue.open = 0;
-
-	return 0;
-}
-
-static ssize_t remote_event_file_read(struct file *file, char __user *buf, size_t count, loff_t *offset)
-{
-	struct service_processor *sp = file->private_data;
-	struct remote_queue *q = &sp->remote_queue;
-	size_t data_size;
-	struct remote_event *reader = q->reader;
-	size_t num_events;
-
-	if (*offset < 0)
-		return -EINVAL;
-	if (count == 0 || count > 1024)
-		return 0;
-	if (*offset != 0)
-		return 0;
-
-	if (wait_event_interruptible(q->wait, q->reader != q->writer))
-		return -ERESTARTSYS;
-
-	/* only get multiples of struct remote_event */
-	num_events = min((count/sizeof(struct remote_event)), ibmasm_events_available(q));
-	if (!num_events)
-		return 0;
-
-	data_size = num_events * sizeof(struct remote_event);
-
-	if (copy_to_user(buf, reader, data_size))
-		return -EFAULT;
-
-	ibmasm_advance_reader(q, num_events);
-
-	return data_size;
-}
-
-
 static struct file_operations command_fops = {
 	.open =		command_file_open,
 	.release =	command_file_close,
@@ -672,12 +609,6 @@ static struct file_operations remote_set
 	.write =	remote_settings_file_write,
 };
 
-static struct file_operations remote_event_fops = {
-	.open =		remote_event_file_open,
-	.release =	remote_event_file_close,
-	.read =		remote_event_file_read,
-};
-
 
 static void ibmasmfs_create_files (struct super_block *sb, struct dentry *root)
 {
@@ -703,7 +634,5 @@ static void ibmasmfs_create_files (struc
 		ibmasmfs_create_file(sb, remote_dir, "width", &remote_settings_fops, (void *)display_width(sp), S_IRUSR|S_IWUSR);
 		ibmasmfs_create_file(sb, remote_dir, "height", &remote_settings_fops, (void *)display_height(sp), S_IRUSR|S_IWUSR);
 		ibmasmfs_create_file(sb, remote_dir, "depth", &remote_settings_fops, (void *)display_depth(sp), S_IRUSR|S_IWUSR);
-		ibmasmfs_create_file(sb, remote_dir, "connected", &remote_settings_fops, (void *)vnc_status(sp), S_IRUSR);
-		ibmasmfs_create_file(sb, remote_dir, "events", &remote_event_fops, (void *)sp, S_IRUSR);
 	}
 }
diff --git a/drivers/misc/ibmasm/lowlevel.c b/drivers/misc/ibmasm/lowlevel.c
--- a/drivers/misc/ibmasm/lowlevel.c
+++ b/drivers/misc/ibmasm/lowlevel.c
@@ -46,8 +46,8 @@ int ibmasm_send_i2o_message(struct servi
 
 	message = get_i2o_message(sp->base_address, mfa);
 
-	memcpy(&message->header, &header, sizeof(struct i2o_header));
-	memcpy(&message->data, command->buffer, command_size);
+	memcpy_toio(&message->header, &header, sizeof(struct i2o_header));
+	memcpy_toio(&message->data, command->buffer, command_size);
 
 	set_mfa_inbound(sp->base_address, mfa);
 
@@ -59,23 +59,27 @@ irqreturn_t ibmasm_interrupt_handler(int
 	u32	mfa;
 	struct service_processor *sp = (struct service_processor *)dev_id;
 	void __iomem *base_address = sp->base_address;
+	char tsbuf[32];
 
 	if (!sp_interrupt_pending(base_address))
 		return IRQ_NONE;
 
+	dbg("respond to interrupt at %s\n", get_timestamp(tsbuf));
+
 	if (mouse_interrupt_pending(sp)) {
-		ibmasm_handle_mouse_interrupt(sp);
-		mfa = get_mfa_outbound(base_address);
+		ibmasm_handle_mouse_interrupt(sp, regs);
 		clear_mouse_interrupt(sp);
-		set_mfa_outbound(base_address, mfa);
-		return IRQ_HANDLED;
 	}
 
 	mfa = get_mfa_outbound(base_address);
 	if (valid_mfa(mfa)) {
 		struct i2o_message *msg = get_i2o_message(base_address, mfa);
 		ibmasm_receive_message(sp, &msg->data, incoming_data_size(msg));
-	}
+	} else
+		dbg("didn't get a valid MFA\n");
+
 	set_mfa_outbound(base_address, mfa);
+	dbg("finished interrupt at   %s\n", get_timestamp(tsbuf));
+
 	return IRQ_HANDLED;
 }
diff --git a/drivers/misc/ibmasm/module.c b/drivers/misc/ibmasm/module.c
--- a/drivers/misc/ibmasm/module.c
+++ b/drivers/misc/ibmasm/module.c
@@ -56,17 +56,26 @@
 #include "lowlevel.h"
 #include "remote.h"
 
+int ibmasm_debug = 0;
+module_param(ibmasm_debug, int , S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(ibmasm_debug, " Set debug mode on or off");
+
 
 static int __devinit ibmasm_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
 {
-	int err, result = -ENOMEM;
+	int result;
 	struct service_processor *sp;
 
-	if ((err = pci_enable_device(pdev))) {
-		printk(KERN_ERR "%s: can't enable PCI device at %s\n",
-			DRIVER_NAME, pci_name(pdev));
-		return err;
+	if ((result = pci_enable_device(pdev))) {
+		dev_err(&pdev->dev, "Failed to enable PCI device\n");
+		return result;
 	}
+	if ((result = pci_request_regions(pdev, DRIVER_NAME))) {
+		dev_err(&pdev->dev, "Failed to allocate PCI resources\n");
+		goto error_resources;
+	}
+	/* vnc client won't work without bus-mastering */
+	pci_set_master(pdev);
 
 	sp = kmalloc(sizeof(struct service_processor), GFP_KERNEL);
 	if (sp == NULL) {
@@ -76,6 +85,9 @@ static int __devinit ibmasm_init_one(str
 	}
 	memset(sp, 0, sizeof(struct service_processor));
 
+	sp->lock = SPIN_LOCK_UNLOCKED;
+	INIT_LIST_HEAD(&sp->command_queue);
+
 	pci_set_drvdata(pdev, (void *)sp);
 	sp->dev = &pdev->dev;
 	sp->number = pdev->bus->number;
@@ -101,15 +113,6 @@ static int __devinit ibmasm_init_one(str
 		goto error_ioremap;
 	}
 
-	result = ibmasm_init_remote_queue(sp);
-	if (result) {
-		dev_err(sp->dev, "Failed to initialize remote queue\n");
-		goto error_remote_queue;
-	}
-
-	spin_lock_init(&sp->lock);
-	INIT_LIST_HEAD(&sp->command_queue);
-
 	result = request_irq(sp->irq, ibmasm_interrupt_handler, SA_SHIRQ, sp->devname, (void*)sp);
 	if (result) {
 		dev_err(sp->dev, "Failed to register interrupt handler\n");
@@ -117,7 +120,12 @@ static int __devinit ibmasm_init_one(str
 	}
 
 	enable_sp_interrupts(sp->base_address);
-	disable_mouse_interrupts(sp);
+
+	result = ibmasm_init_remote_input_dev(sp);
+	if (result) {
+		dev_err(sp->dev, "Failed to initialize remote queue\n");
+		goto error_send_message;
+	}
 
 	result = ibmasm_send_driver_vpd(sp);
 	if (result) {
@@ -133,30 +141,25 @@ static int __devinit ibmasm_init_one(str
 
 	ibmasm_register_uart(sp);
 
-	dev_printk(KERN_DEBUG, &pdev->dev, "WARNING: This software may not be supported or function\n");
-	dev_printk(KERN_DEBUG, &pdev->dev, "correctly on your IBM server. Please consult the IBM\n");
-	dev_printk(KERN_DEBUG, &pdev->dev, "ServerProven website\n");
-	dev_printk(KERN_DEBUG, &pdev->dev, "http://www.pc.ibm.com/ww/eserver/xseries/serverproven\n");
-	dev_printk(KERN_DEBUG, &pdev->dev, "for information on the specific driver level and support\n");
-	dev_printk(KERN_DEBUG, &pdev->dev, "statement for your IBM server.\n");
-
 	return 0;
 
 error_send_message:
 	disable_sp_interrupts(sp->base_address);
+	ibmasm_free_remote_input_dev(sp);
 	free_irq(sp->irq, (void *)sp);
 error_request_irq:
-	ibmasm_free_remote_queue(sp);
-error_remote_queue:
 	iounmap(sp->base_address);
 error_ioremap:
 	ibmasm_heartbeat_exit(sp);
 error_heartbeat:
 	ibmasm_event_buffer_exit(sp);
 error_eventbuffer:
+	pci_set_drvdata(pdev, NULL);
 	kfree(sp);
 error_kmalloc:
-	pci_disable_device(pdev);
+        pci_release_regions(pdev);
+error_resources:
+        pci_disable_device(pdev);
 
 	return result;
 }
@@ -165,16 +168,24 @@ static void __devexit ibmasm_remove_one(
 {
 	struct service_processor *sp = (struct service_processor *)pci_get_drvdata(pdev);
 
+	dbg("Unregistering UART\n");
 	ibmasm_unregister_uart(sp);
-	ibmasm_send_os_state(sp, SYSTEM_STATE_OS_DOWN);
+	dbg("Sending OS down message\n");
+	if (ibmasm_send_os_state(sp, SYSTEM_STATE_OS_DOWN))
+		err("failed to get repsonse to 'Send OS State' command\n");
+	dbg("Disabling heartbeats\n");
+	ibmasm_heartbeat_exit(sp);
+	dbg("Disabling interrupts\n");
 	disable_sp_interrupts(sp->base_address);
-	disable_mouse_interrupts(sp);
+	dbg("Freeing SP irq\n");
 	free_irq(sp->irq, (void *)sp);
-	ibmasm_heartbeat_exit(sp);
-	ibmasm_free_remote_queue(sp);
+	dbg("Cleaning up\n");
+	ibmasm_free_remote_input_dev(sp);
 	iounmap(sp->base_address);
 	ibmasm_event_buffer_exit(sp);
+	pci_set_drvdata(pdev, NULL);
 	kfree(sp);
+	pci_release_regions(pdev);
 	pci_disable_device(pdev);
 }
 
diff --git a/drivers/misc/ibmasm/r_heartbeat.c b/drivers/misc/ibmasm/r_heartbeat.c
--- a/drivers/misc/ibmasm/r_heartbeat.c
+++ b/drivers/misc/ibmasm/r_heartbeat.c
@@ -63,7 +63,7 @@ int ibmasm_start_reverse_heartbeat(struc
 	int times_failed = 0;
 	int result = 1;
 
-	cmd = ibmasm_new_command(sizeof rhb_dot_cmd);
+	cmd = ibmasm_new_command(sp, sizeof rhb_dot_cmd);
 	if (!cmd)
 		return -ENOMEM;
 
diff --git a/drivers/misc/ibmasm/remote.c b/drivers/misc/ibmasm/remote.c
--- a/drivers/misc/ibmasm/remote.c
+++ b/drivers/misc/ibmasm/remote.c
@@ -1,4 +1,3 @@
-
 /*
  * IBM ASM Service Processor Device Driver
  *
@@ -18,135 +17,256 @@
  *
  * Copyright (C) IBM Corporation, 2004
  *
- * Author: Max Asböck <amax@us.ibm.com> 
+ * Authors: Max Asböck <amax@us.ibm.com>
+ *          Vernon Mauery <vernux@us.ibm.com>
  *
  */
 
 /* Remote mouse and keyboard event handling functions */
 
+#include <linux/pci.h>
 #include "ibmasm.h"
 #include "remote.h"
 
-int ibmasm_init_remote_queue(struct service_processor *sp)
-{
-	struct remote_queue *q = &sp->remote_queue;
+static int xmax = 1600;
+static int ymax = 1200;
 
-	disable_mouse_interrupts(sp);
 
-	q->open = 0;
-	q->size = 0;
+static unsigned short xlate_high[XLATE_SIZE] = {
+	[KEY_SYM_ENTER & 0xff] = KEY_ENTER,
+	[KEY_SYM_KPSLASH & 0xff] = KEY_KPSLASH,
+	[KEY_SYM_KPSTAR & 0xff] = KEY_KPASTERISK,
+	[KEY_SYM_KPMINUS & 0xff] = KEY_KPMINUS,
+	[KEY_SYM_KPDOT & 0xff] = KEY_KPDOT,
+	[KEY_SYM_KPPLUS & 0xff] = KEY_KPPLUS,
+	[KEY_SYM_KP0 & 0xff] = KEY_KP0,
+	[KEY_SYM_KP1 & 0xff] = KEY_KP1,
+	[KEY_SYM_KP2 & 0xff] = KEY_KP2, [KEY_SYM_KPDOWN & 0xff] = KEY_KP2,
+	[KEY_SYM_KP3 & 0xff] = KEY_KP3,
+	[KEY_SYM_KP4 & 0xff] = KEY_KP4, [KEY_SYM_KPLEFT & 0xff] = KEY_KP4,
+	[KEY_SYM_KP5 & 0xff] = KEY_KP5,
+	[KEY_SYM_KP6 & 0xff] = KEY_KP6, [KEY_SYM_KPRIGHT & 0xff] = KEY_KP6,
+	[KEY_SYM_KP7 & 0xff] = KEY_KP7,
+	[KEY_SYM_KP8 & 0xff] = KEY_KP8, [KEY_SYM_KPUP & 0xff] = KEY_KP8,
+	[KEY_SYM_KP9 & 0xff] = KEY_KP9,
+	[KEY_SYM_BK_SPC & 0xff] = KEY_BACKSPACE,
+	[KEY_SYM_TAB & 0xff] = KEY_TAB,
+	[KEY_SYM_CTRL & 0xff] = KEY_LEFTCTRL,
+	[KEY_SYM_ALT & 0xff] = KEY_LEFTALT,
+	[KEY_SYM_INSERT & 0xff] = KEY_INSERT,
+	[KEY_SYM_DELETE & 0xff] = KEY_DELETE,
+	[KEY_SYM_SHIFT & 0xff] = KEY_LEFTSHIFT,
+	[KEY_SYM_UARROW & 0xff] = KEY_UP,
+	[KEY_SYM_DARROW & 0xff] = KEY_DOWN,
+	[KEY_SYM_LARROW & 0xff] = KEY_LEFT,
+	[KEY_SYM_RARROW & 0xff] = KEY_RIGHT,
+	[KEY_SYM_ESCAPE & 0xff] = KEY_ESC,
+        [KEY_SYM_PAGEUP & 0xff] = KEY_PAGEUP,
+        [KEY_SYM_PAGEDOWN & 0xff] = KEY_PAGEDOWN,
+        [KEY_SYM_HOME & 0xff] = KEY_HOME,
+        [KEY_SYM_END & 0xff] = KEY_END,
+	[KEY_SYM_F1 & 0xff] = KEY_F1,
+	[KEY_SYM_F2 & 0xff] = KEY_F2,
+	[KEY_SYM_F3 & 0xff] = KEY_F3,
+	[KEY_SYM_F4 & 0xff] = KEY_F4,
+	[KEY_SYM_F5 & 0xff] = KEY_F5,
+	[KEY_SYM_F6 & 0xff] = KEY_F6,
+	[KEY_SYM_F7 & 0xff] = KEY_F7,
+	[KEY_SYM_F8 & 0xff] = KEY_F8,
+	[KEY_SYM_F9 & 0xff] = KEY_F9,
+	[KEY_SYM_F10 & 0xff] = KEY_F10,
+	[KEY_SYM_F11 & 0xff] = KEY_F11,
+	[KEY_SYM_F12 & 0xff] = KEY_F12,
+	[KEY_SYM_CAP_LOCK & 0xff] = KEY_CAPSLOCK,
+	[KEY_SYM_NUM_LOCK & 0xff] = KEY_NUMLOCK,
+	[KEY_SYM_SCR_LOCK & 0xff] = KEY_SCROLLLOCK,
+};
+static unsigned short xlate[XLATE_SIZE] = {
+	[NO_KEYCODE] = KEY_RESERVED,
+	[KEY_SYM_SPACE] = KEY_SPACE,
+	[KEY_SYM_TILDE] = KEY_GRAVE,        [KEY_SYM_BKTIC] = KEY_GRAVE,
+	[KEY_SYM_ONE] = KEY_1,              [KEY_SYM_BANG] = KEY_1,
+	[KEY_SYM_TWO] = KEY_2,              [KEY_SYM_AT] = KEY_2,
+	[KEY_SYM_THREE] = KEY_3,            [KEY_SYM_POUND] = KEY_3,
+	[KEY_SYM_FOUR] = KEY_4,             [KEY_SYM_DOLLAR] = KEY_4,
+	[KEY_SYM_FIVE] = KEY_5,             [KEY_SYM_PERCENT] = KEY_5,
+	[KEY_SYM_SIX] = KEY_6,              [KEY_SYM_CARAT] = KEY_6,
+	[KEY_SYM_SEVEN] = KEY_7,            [KEY_SYM_AMPER] = KEY_7,
+	[KEY_SYM_EIGHT] = KEY_8,            [KEY_SYM_STAR] = KEY_8,
+	[KEY_SYM_NINE] = KEY_9,             [KEY_SYM_LPAREN] = KEY_9,
+	[KEY_SYM_ZERO] = KEY_0,             [KEY_SYM_RPAREN] = KEY_0,
+	[KEY_SYM_MINUS] = KEY_MINUS,        [KEY_SYM_USCORE] = KEY_MINUS,
+	[KEY_SYM_EQUAL] = KEY_EQUAL,        [KEY_SYM_PLUS] = KEY_EQUAL,
+	[KEY_SYM_LBRKT] = KEY_LEFTBRACE,    [KEY_SYM_LCURLY] = KEY_LEFTBRACE,
+	[KEY_SYM_RBRKT] = KEY_RIGHTBRACE,   [KEY_SYM_RCURLY] = KEY_RIGHTBRACE,
+	[KEY_SYM_SLASH] = KEY_BACKSLASH,    [KEY_SYM_PIPE] = KEY_BACKSLASH,
+	[KEY_SYM_TIC] = KEY_APOSTROPHE,     [KEY_SYM_QUOTE] = KEY_APOSTROPHE,
+	[KEY_SYM_SEMIC] = KEY_SEMICOLON,    [KEY_SYM_COLON] = KEY_SEMICOLON,
+	[KEY_SYM_COMMA] = KEY_COMMA,        [KEY_SYM_LT] = KEY_COMMA,
+	[KEY_SYM_PERIOD] = KEY_DOT,         [KEY_SYM_GT] = KEY_DOT,
+	[KEY_SYM_BSLASH] = KEY_SLASH,       [KEY_SYM_QMARK] = KEY_SLASH,
+	[KEY_SYM_A] = KEY_A,                [KEY_SYM_a] = KEY_A,
+	[KEY_SYM_B] = KEY_B,                [KEY_SYM_b] = KEY_B,
+	[KEY_SYM_C] = KEY_C,                [KEY_SYM_c] = KEY_C,
+	[KEY_SYM_D] = KEY_D,                [KEY_SYM_d] = KEY_D,
+	[KEY_SYM_E] = KEY_E,                [KEY_SYM_e] = KEY_E,
+	[KEY_SYM_F] = KEY_F,                [KEY_SYM_f] = KEY_F,
+	[KEY_SYM_G] = KEY_G,                [KEY_SYM_g] = KEY_G,
+	[KEY_SYM_H] = KEY_H,                [KEY_SYM_h] = KEY_H,
+	[KEY_SYM_I] = KEY_I,                [KEY_SYM_i] = KEY_I,
+	[KEY_SYM_J] = KEY_J,                [KEY_SYM_j] = KEY_J,
+	[KEY_SYM_K] = KEY_K,                [KEY_SYM_k] = KEY_K,
+	[KEY_SYM_L] = KEY_L,                [KEY_SYM_l] = KEY_L,
+	[KEY_SYM_M] = KEY_M,                [KEY_SYM_m] = KEY_M,
+	[KEY_SYM_N] = KEY_N,                [KEY_SYM_n] = KEY_N,
+	[KEY_SYM_O] = KEY_O,                [KEY_SYM_o] = KEY_O,
+	[KEY_SYM_P] = KEY_P,                [KEY_SYM_p] = KEY_P,
+	[KEY_SYM_Q] = KEY_Q,                [KEY_SYM_q] = KEY_Q,
+	[KEY_SYM_R] = KEY_R,                [KEY_SYM_r] = KEY_R,
+	[KEY_SYM_S] = KEY_S,                [KEY_SYM_s] = KEY_S,
+	[KEY_SYM_T] = KEY_T,                [KEY_SYM_t] = KEY_T,
+	[KEY_SYM_U] = KEY_U,                [KEY_SYM_u] = KEY_U,
+	[KEY_SYM_V] = KEY_V,                [KEY_SYM_v] = KEY_V,
+	[KEY_SYM_W] = KEY_W,                [KEY_SYM_w] = KEY_W,
+	[KEY_SYM_X] = KEY_X,                [KEY_SYM_x] = KEY_X,
+	[KEY_SYM_Y] = KEY_Y,                [KEY_SYM_y] = KEY_Y,
+	[KEY_SYM_Z] = KEY_Z,                [KEY_SYM_z] = KEY_Z,
+};
 
-	q->start = kmalloc(DRIVER_REMOTE_QUEUE_SIZE * sizeof(struct remote_event), GFP_KERNEL);
-        if (q->start == 0)
-                return -ENOMEM;
-
-	q->end = q->start + DRIVER_REMOTE_QUEUE_SIZE;
-	q->reader = q->start;
-	q->writer = q->start;
-	q->size = DRIVER_REMOTE_QUEUE_SIZE;
-	init_waitqueue_head(&q->wait);
-
-	return 0;
-}
+static char remote_mouse_name[] = "ibmasm RSA I remote mouse";
+static char remote_keybd_name[] = "ibmasm RSA I remote keyboard";
 
-void ibmasm_free_remote_queue(struct service_processor *sp)
+static void print_input(struct remote_input *input)
 {
-	kfree(sp->remote_queue.start);
+	if (input->type == INPUT_TYPE_MOUSE) {
+		unsigned char buttons = input->mouse_buttons;
+		dbg("remote mouse movement: (x,y)=(%d,%d)%s%s%s%s\n",
+			input->data.mouse.x, input->data.mouse.y,
+			(buttons)?" -- buttons:":"",
+			(buttons & REMOTE_BUTTON_LEFT)?"left ":"",
+			(buttons & REMOTE_BUTTON_MIDDLE)?"middle ":"",
+			(buttons & REMOTE_BUTTON_RIGHT)?"right":""
+		      );
+	} else {
+		dbg("remote keypress (code, flag, down):"
+			   "%d (0x%x) [0x%x] [0x%x]\n",
+				input->data.keyboard.key_code,
+				input->data.keyboard.key_code,
+				input->data.keyboard.key_flag,
+				input->data.keyboard.key_down
+		      );
+	}
 }
 
-void ibmasm_advance_reader(struct remote_queue *q, unsigned int n)
+static void send_mouse_event(struct input_dev *dev, struct pt_regs *regs,
+		struct remote_input *input)
 {
-	q->reader += n;
-	if (q->reader >= q->end)
-		q->reader -= q->size;
-}
+	unsigned char buttons = input->mouse_buttons;
 
-size_t ibmasm_events_available(struct remote_queue *q)
-{
-	ssize_t diff = q->writer - q->reader;
- 
-	return (diff >= 0) ? diff : q->end - q->reader;	
+	input_regs(dev, regs);
+	input_report_abs(dev, ABS_X, input->data.mouse.x);
+	input_report_abs(dev, ABS_Y, input->data.mouse.y);
+	input_report_key(dev, BTN_LEFT, buttons & REMOTE_BUTTON_LEFT);
+	input_report_key(dev, BTN_MIDDLE, buttons & REMOTE_BUTTON_MIDDLE);
+	input_report_key(dev, BTN_RIGHT, buttons & REMOTE_BUTTON_RIGHT);
+	input_sync(dev);
 }
-	
 
-static int space_free(struct remote_queue *q)
+static void send_keyboard_event(struct input_dev *dev, struct pt_regs *regs,
+		struct remote_input *input)
 {
-	if (q->reader == q->writer)
-		return q->size - 1;
+	unsigned int key;
+	unsigned short code = input->data.keyboard.key_code;
 
-	return ( (q->reader + q->size - q->writer) % q->size ) - 1;
+	if (code & 0xff00)
+		key = xlate_high[code & 0xff];
+	else
+		key = xlate[code];
+	input_regs(dev, regs);
+	input_report_key(dev, key, (input->data.keyboard.key_down) ? 1 : 0);
+	input_sync(dev);
 }
 
-static void set_mouse_event(struct remote_input *input, struct mouse_event *mouse)
+void ibmasm_handle_mouse_interrupt(struct service_processor *sp,
+		struct pt_regs *regs)
 {
-	static char last_buttons = 0;
+	unsigned long reader;
+	unsigned long writer;
+	struct remote_input input;
 
-	mouse->x = input->data.mouse.x;
-	mouse->y = input->data.mouse.y;
+	reader = get_queue_reader(sp);
+	writer = get_queue_writer(sp);
 
-	if (input->mouse_buttons == REMOTE_MOUSE_DOUBLE_CLICK) {
-		mouse->buttons = REMOTE_MOUSE_DOUBLE_CLICK;
-		last_buttons = 0;
-		return;
-	}
-	mouse->transitions = last_buttons ^ input->mouse_buttons;
-	mouse->buttons = input->mouse_buttons;
+	while (reader != writer) {
+		memcpy_fromio(&input, get_queue_entry(sp, reader),
+				sizeof(struct remote_input));
 
-	last_buttons = input->mouse_buttons;
-}
+		print_input(&input);
+		if (input.type == INPUT_TYPE_MOUSE) {
+			send_mouse_event(&sp->remote->mouse_dev, regs, &input);
+		} else if (input.type == INPUT_TYPE_KEYBOARD) {
+			send_keyboard_event(&sp->remote->keybd_dev, regs, &input);
+		} else
+			break;
 
-static void set_keyboard_event(struct remote_input *input, struct keyboard_event *keyboard)
-{
-	keyboard->key_code = input->data.keyboard.key_code;
-	keyboard->key_down = input->data.keyboard.key_down;
+		reader = advance_queue_reader(sp, reader);
+		writer = get_queue_writer(sp);
+	}
 }
 
-static int add_to_driver_queue(struct remote_queue *q, struct remote_input *input)
+int ibmasm_init_remote_input_dev(struct service_processor *sp)
 {
-	struct remote_event *event = q->writer;
-
-	if (space_free(q) < 1) {
-		return 1;
+	/* set up the mouse input device */
+	struct ibmasm_remote *remote;
+	struct pci_dev *pdev = to_pci_dev(sp->dev);
+	int i;
+
+	sp->remote = remote = kmalloc(sizeof(*remote), GFP_KERNEL);
+	if (!remote)
+		return -ENOMEM;
+
+	memset(remote, 0, sizeof(*remote));
+
+	remote->mouse_dev.private = remote;
+	init_input_dev(&remote->mouse_dev);
+	remote->mouse_dev.id.vendor = pdev->vendor;
+	remote->mouse_dev.id.product = pdev->device;
+	remote->mouse_dev.evbit[0]  = BIT(EV_KEY) | BIT(EV_ABS);
+	remote->mouse_dev.keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) |
+		BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
+	set_bit(BTN_TOUCH, remote->mouse_dev.keybit);
+	remote->mouse_dev.name = remote_mouse_name;
+	input_set_abs_params(&remote->mouse_dev, ABS_X, 0, xmax, 0, 0);
+	input_set_abs_params(&remote->mouse_dev, ABS_Y, 0, ymax, 0, 0);
+
+	remote->keybd_dev.private = remote;
+	init_input_dev(&remote->keybd_dev);
+	remote->keybd_dev.id.vendor = pdev->vendor;
+	remote->keybd_dev.id.product = pdev->device;
+	remote->keybd_dev.evbit[0]  = BIT(EV_KEY);
+	remote->keybd_dev.name = remote_keybd_name;
+
+	for (i=0; i<XLATE_SIZE; i++) {
+		if (xlate_high[i])
+			set_bit(xlate_high[i], remote->keybd_dev.keybit);
+		if (xlate[i])
+			set_bit(xlate[i], remote->keybd_dev.keybit);
 	}
 
-	switch(input->type) {
-	case (INPUT_TYPE_MOUSE):
-		event->type = INPUT_TYPE_MOUSE;
-		set_mouse_event(input, &event->data.mouse);
-		break;
-	case (INPUT_TYPE_KEYBOARD):
-		event->type = INPUT_TYPE_KEYBOARD;
-		set_keyboard_event(input, &event->data.keyboard);
-		break;
-	default:
-		return 0;
-	}
-	event->type = input->type;
+	input_register_device(&remote->mouse_dev);
+	input_register_device(&remote->keybd_dev);
+	enable_mouse_interrupts(sp);
 
-	q->writer++;
-	if (q->writer == q->end)
-		q->writer = q->start;
+	printk(KERN_INFO "ibmasm remote responding to events on RSA card %d\n", sp->number);
 
 	return 0;
 }
-	
 
-void ibmasm_handle_mouse_interrupt(struct service_processor *sp)
+void ibmasm_free_remote_input_dev(struct service_processor *sp)
 {
-	unsigned long reader;
-	unsigned long writer;
-	struct remote_input input;
-
-	reader = get_queue_reader(sp);
-	writer = get_queue_writer(sp);
-
-	while (reader != writer) {
-		memcpy(&input, (void *)get_queue_entry(sp, reader), sizeof(struct remote_input));
-
-		if (add_to_driver_queue(&sp->remote_queue, &input))
-			break;
-
-		reader = advance_queue_reader(sp, reader);
-	}
-	wake_up_interruptible(&sp->remote_queue.wait);
+	disable_mouse_interrupts(sp);
+	input_unregister_device(&sp->remote->keybd_dev);
+	input_unregister_device(&sp->remote->mouse_dev);
+	kfree(sp->remote);
 }
+
diff --git a/drivers/misc/ibmasm/remote.h b/drivers/misc/ibmasm/remote.h
--- a/drivers/misc/ibmasm/remote.h
+++ b/drivers/misc/ibmasm/remote.h
@@ -51,11 +51,13 @@
 
 
 /* mouse button states received from SP */
-#define REMOTE_MOUSE_DOUBLE_CLICK	0xF0
-#define REMOTE_MOUSE_BUTTON_LEFT	0x01
-#define REMOTE_MOUSE_BUTTON_MIDDLE	0x02
-#define REMOTE_MOUSE_BUTTON_RIGHT	0x04
+#define REMOTE_DOUBLE_CLICK	0xF0
+#define REMOTE_BUTTON_LEFT	0x01
+#define REMOTE_BUTTON_MIDDLE	0x02
+#define REMOTE_BUTTON_RIGHT	0x04
 
+/* size of keysym/keycode translation matricies */
+#define XLATE_SIZE 256
 
 struct mouse_input {
 	unsigned short	y;
@@ -83,11 +85,13 @@ struct remote_input { 
 	unsigned char	pad3;
 };
 
-#define mouse_addr(sp) 		sp->base_address + CONDOR_MOUSE_DATA
-#define display_width(sp)	mouse_addr(sp) + CONDOR_INPUT_DISPLAY_RESX
-#define display_height(sp)	mouse_addr(sp) + CONDOR_INPUT_DISPLAY_RESY
-#define display_depth(sp)	mouse_addr(sp) + CONDOR_INPUT_DISPLAY_BITS
-#define vnc_status(sp)		mouse_addr(sp) + CONDOR_OUTPUT_VNC_STATUS
+#define mouse_addr(sp) 		(sp->base_address + CONDOR_MOUSE_DATA)
+#define display_width(sp)	(mouse_addr(sp) + CONDOR_INPUT_DISPLAY_RESX)
+#define display_height(sp)	(mouse_addr(sp) + CONDOR_INPUT_DISPLAY_RESY)
+#define display_depth(sp)	(mouse_addr(sp) + CONDOR_INPUT_DISPLAY_BITS)
+#define desktop_info(sp)	(mouse_addr(sp) + CONDOR_INPUT_DESKTOP_INFO)
+#define vnc_status(sp)		(mouse_addr(sp) + CONDOR_OUTPUT_VNC_STATUS)
+#define isr_control(sp)		(mouse_addr(sp) + CONDOR_MOUSE_ISR_CONTROL)
 
 #define mouse_interrupt_pending(sp) 	readl(mouse_addr(sp) + CONDOR_MOUSE_ISR_STATUS)
 #define clear_mouse_interrupt(sp)	writel(0, mouse_addr(sp) + CONDOR_MOUSE_ISR_STATUS)
@@ -101,10 +105,10 @@ struct remote_input { 
 #define get_queue_reader(sp)	readl(mouse_addr(sp) + CONDOR_MOUSE_Q_READER)
 #define set_queue_reader(sp, reader)	writel(reader, mouse_addr(sp) + CONDOR_MOUSE_Q_READER)
 
-#define queue_begin	mouse_addr(sp) + CONDOR_MOUSE_Q_BEGIN
+#define queue_begin	(mouse_addr(sp) + CONDOR_MOUSE_Q_BEGIN)
 
 #define get_queue_entry(sp, read_index) \
-	queue_begin + read_index * sizeof(struct remote_input)
+	((void*)(queue_begin + read_index * sizeof(struct remote_input)))
 
 static inline int advance_queue_reader(struct service_processor *sp, unsigned long reader)
 {
@@ -116,4 +120,151 @@ static inline int advance_queue_reader(s
 	return reader;
 }
 
+#define NO_KEYCODE 0
+#define KEY_SYM_BK_SPC   0xFF08
+#define KEY_SYM_TAB      0xFF09
+#define KEY_SYM_ENTER    0xFF0D
+#define KEY_SYM_SCR_LOCK 0xFF14
+#define KEY_SYM_ESCAPE   0xFF1B
+#define KEY_SYM_HOME     0xFF50
+#define KEY_SYM_LARROW   0xFF51
+#define KEY_SYM_UARROW   0xFF52
+#define KEY_SYM_RARROW   0xFF53
+#define KEY_SYM_DARROW   0xFF54
+#define KEY_SYM_PAGEUP   0xFF55
+#define KEY_SYM_PAGEDOWN 0xFF56
+#define KEY_SYM_END      0xFF57
+#define KEY_SYM_INSERT   0xFF63
+#define KEY_SYM_NUM_LOCK 0xFF7F
+#define KEY_SYM_KPSTAR   0xFFAA
+#define KEY_SYM_KPPLUS   0xFFAB
+#define KEY_SYM_KPMINUS  0xFFAD
+#define KEY_SYM_KPDOT    0xFFAE
+#define KEY_SYM_KPSLASH  0xFFAF
+#define KEY_SYM_KPRIGHT  0xFF96
+#define KEY_SYM_KPUP     0xFF97
+#define KEY_SYM_KPLEFT   0xFF98
+#define KEY_SYM_KPDOWN   0xFF99
+#define KEY_SYM_KP0      0xFFB0
+#define KEY_SYM_KP1      0xFFB1
+#define KEY_SYM_KP2      0xFFB2
+#define KEY_SYM_KP3      0xFFB3
+#define KEY_SYM_KP4      0xFFB4
+#define KEY_SYM_KP5      0xFFB5
+#define KEY_SYM_KP6      0xFFB6
+#define KEY_SYM_KP7      0xFFB7
+#define KEY_SYM_KP8      0xFFB8
+#define KEY_SYM_KP9      0xFFB9
+#define KEY_SYM_F1       0xFFBE      // 1B 5B 5B 41
+#define KEY_SYM_F2       0xFFBF      // 1B 5B 5B 42
+#define KEY_SYM_F3       0xFFC0      // 1B 5B 5B 43
+#define KEY_SYM_F4       0xFFC1      // 1B 5B 5B 44
+#define KEY_SYM_F5       0xFFC2      // 1B 5B 5B 45
+#define KEY_SYM_F6       0xFFC3      // 1B 5B 31 37 7E
+#define KEY_SYM_F7       0xFFC4      // 1B 5B 31 38 7E
+#define KEY_SYM_F8       0xFFC5      // 1B 5B 31 39 7E
+#define KEY_SYM_F9       0xFFC6      // 1B 5B 32 30 7E
+#define KEY_SYM_F10      0xFFC7      // 1B 5B 32 31 7E
+#define KEY_SYM_F11      0xFFC8      // 1B 5B 32 33 7E
+#define KEY_SYM_F12      0xFFC9      // 1B 5B 32 34 7E
+#define KEY_SYM_SHIFT    0xFFE1
+#define KEY_SYM_CTRL     0xFFE3
+#define KEY_SYM_ALT      0xFFE9
+#define KEY_SYM_CAP_LOCK 0xFFE5
+#define KEY_SYM_DELETE   0xFFFF
+#define KEY_SYM_TILDE    0x60
+#define KEY_SYM_BKTIC    0x7E
+#define KEY_SYM_ONE      0x31
+#define KEY_SYM_BANG     0x21
+#define KEY_SYM_TWO      0x32
+#define KEY_SYM_AT       0x40
+#define KEY_SYM_THREE    0x33
+#define KEY_SYM_POUND    0x23
+#define KEY_SYM_FOUR     0x34
+#define KEY_SYM_DOLLAR   0x24
+#define KEY_SYM_FIVE     0x35
+#define KEY_SYM_PERCENT  0x25
+#define KEY_SYM_SIX      0x36
+#define KEY_SYM_CARAT    0x5E
+#define KEY_SYM_SEVEN    0x37
+#define KEY_SYM_AMPER    0x26
+#define KEY_SYM_EIGHT    0x38
+#define KEY_SYM_STAR     0x2A
+#define KEY_SYM_NINE     0x39
+#define KEY_SYM_LPAREN   0x28
+#define KEY_SYM_ZERO     0x30
+#define KEY_SYM_RPAREN   0x29
+#define KEY_SYM_MINUS    0x2D
+#define KEY_SYM_USCORE   0x5F
+#define KEY_SYM_EQUAL    0x2B
+#define KEY_SYM_PLUS     0x3D
+#define KEY_SYM_LBRKT    0x5B
+#define KEY_SYM_LCURLY   0x7B
+#define KEY_SYM_RBRKT    0x5D
+#define KEY_SYM_RCURLY   0x7D
+#define KEY_SYM_SLASH    0x5C
+#define KEY_SYM_PIPE     0x7C
+#define KEY_SYM_TIC      0x27
+#define KEY_SYM_QUOTE    0x22
+#define KEY_SYM_SEMIC    0x3B
+#define KEY_SYM_COLON    0x3A
+#define KEY_SYM_COMMA    0x2C
+#define KEY_SYM_LT       0x3C
+#define KEY_SYM_PERIOD   0x2E
+#define KEY_SYM_GT       0x3E
+#define KEY_SYM_BSLASH   0x2F
+#define KEY_SYM_QMARK    0x3F
+#define KEY_SYM_A        0x41
+#define KEY_SYM_B        0x42
+#define KEY_SYM_C        0x43
+#define KEY_SYM_D        0x44
+#define KEY_SYM_E        0x45
+#define KEY_SYM_F        0x46
+#define KEY_SYM_G        0x47
+#define KEY_SYM_H        0x48
+#define KEY_SYM_I        0x49
+#define KEY_SYM_J        0x4A
+#define KEY_SYM_K        0x4B
+#define KEY_SYM_L        0x4C
+#define KEY_SYM_M        0x4D
+#define KEY_SYM_N        0x4E
+#define KEY_SYM_O        0x4F
+#define KEY_SYM_P        0x50
+#define KEY_SYM_Q        0x51
+#define KEY_SYM_R        0x52
+#define KEY_SYM_S        0x53
+#define KEY_SYM_T        0x54
+#define KEY_SYM_U        0x55
+#define KEY_SYM_V        0x56
+#define KEY_SYM_W        0x57
+#define KEY_SYM_X        0x58
+#define KEY_SYM_Y        0x59
+#define KEY_SYM_Z        0x5A
+#define KEY_SYM_a        0x61
+#define KEY_SYM_b        0x62
+#define KEY_SYM_c        0x63
+#define KEY_SYM_d        0x64
+#define KEY_SYM_e        0x65
+#define KEY_SYM_f        0x66
+#define KEY_SYM_g        0x67
+#define KEY_SYM_h        0x68
+#define KEY_SYM_i        0x69
+#define KEY_SYM_j        0x6A
+#define KEY_SYM_k        0x6B
+#define KEY_SYM_l        0x6C
+#define KEY_SYM_m        0x6D
+#define KEY_SYM_n        0x6E
+#define KEY_SYM_o        0x6F
+#define KEY_SYM_p        0x70
+#define KEY_SYM_q        0x71
+#define KEY_SYM_r        0x72
+#define KEY_SYM_s        0x73
+#define KEY_SYM_t        0x74
+#define KEY_SYM_u        0x75
+#define KEY_SYM_v        0x76
+#define KEY_SYM_w        0x77
+#define KEY_SYM_x        0x78
+#define KEY_SYM_y        0x79
+#define KEY_SYM_z        0x7A
+#define KEY_SYM_SPACE    0x20
 #endif /* _IBMASM_REMOTE_H_ */
diff --git a/drivers/mmc/mmc_sysfs.c b/drivers/mmc/mmc_sysfs.c
--- a/drivers/mmc/mmc_sysfs.c
+++ b/drivers/mmc/mmc_sysfs.c
@@ -22,7 +22,7 @@
 #define to_mmc_driver(d)	container_of(d, struct mmc_driver, drv)
 
 #define MMC_ATTR(name, fmt, args...)					\
-static ssize_t mmc_##name##_show (struct device *dev, char *buf)	\
+static ssize_t mmc_##name##_show (struct device *dev, struct device_attribute *attr, char *buf)	\
 {									\
 	struct mmc_card *card = dev_to_mmc_card(dev);			\
 	return sprintf(buf, fmt, args);					\
diff --git a/drivers/mmc/mmci.c b/drivers/mmc/mmci.c
--- a/drivers/mmc/mmci.c
+++ b/drivers/mmc/mmci.c
@@ -20,6 +20,7 @@
 #include <linux/mmc/host.h>
 #include <linux/mmc/protocol.h>
 
+#include <asm/div64.h>
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/scatterlist.h>
@@ -70,6 +71,7 @@ static void mmci_stop_data(struct mmci_h
 static void mmci_start_data(struct mmci_host *host, struct mmc_data *data)
 {
 	unsigned int datactrl, timeout, irqmask;
+	unsigned long long clks;
 	void __iomem *base;
 
 	DBG(host, "blksz %04x blks %04x flags %08x\n",
@@ -81,9 +83,10 @@ static void mmci_start_data(struct mmci_
 
 	mmci_init_sg(host, data);
 
-	timeout = data->timeout_clks +
-		  ((unsigned long long)data->timeout_ns * host->cclk) /
-		   1000000000ULL;
+	clks = (unsigned long long)data->timeout_ns * host->cclk;
+	do_div(clks, 1000000000UL);
+
+	timeout = data->timeout_clks + (unsigned int)clks;
 
 	base = host->base;
 	writel(timeout, base + MMCIDATATIMER);
diff --git a/drivers/mmc/wbsd.c b/drivers/mmc/wbsd.c
--- a/drivers/mmc/wbsd.c
+++ b/drivers/mmc/wbsd.c
@@ -42,7 +42,7 @@
 #include "wbsd.h"
 
 #define DRIVER_NAME "wbsd"
-#define DRIVER_VERSION "1.2"
+#define DRIVER_VERSION "1.3"
 
 #ifdef CONFIG_MMC_DEBUG
 #define DBG(x...) \
@@ -54,28 +54,6 @@
 #define DBGF(x...)	do { } while (0)
 #endif
 
-#ifdef CONFIG_MMC_DEBUG
-void DBG_REG(int reg, u8 value)
-{
-	int i;
-	
-	printk(KERN_DEBUG "wbsd: Register %d: 0x%02X %3d '%c' ",
-		reg, (int)value, (int)value, (value < 0x20)?'.':value);
-	
-	for (i = 7;i >= 0;i--)
-	{
-		if (value & (1 << i))
-			printk("x");
-		else
-			printk(".");
-	}
-	
-	printk("\n");
-}
-#else
-#define DBG_REG(r, v) do {}  while (0)
-#endif
-
 /*
  * Device resources
  */
@@ -92,6 +70,13 @@ MODULE_DEVICE_TABLE(pnp, pnp_dev_table);
 
 #endif /* CONFIG_PNP */
 
+static const int config_ports[] = { 0x2E, 0x4E };
+static const int unlock_codes[] = { 0x83, 0x87 };
+
+static const int valid_ids[] = {
+	0x7112,
+	};
+
 #ifdef CONFIG_PNP
 static unsigned int nopnp = 0;
 #else
@@ -1051,10 +1036,24 @@ static struct mmc_host_ops wbsd_ops = {
 \*****************************************************************************/
 
 /*
+ * Helper function for card detection
+ */
+static void wbsd_detect_card(unsigned long data)
+{
+	struct wbsd_host *host = (struct wbsd_host*)data;
+	
+	BUG_ON(host == NULL);
+	
+	DBG("Executing card detection\n");
+	
+	mmc_detect_change(host->mmc);	
+}
+
+/*
  * Tasklets
  */
 
-inline static struct mmc_data* wbsd_get_data(struct wbsd_host* host)
+static inline struct mmc_data* wbsd_get_data(struct wbsd_host* host)
 {
 	WARN_ON(!host->mrq);
 	if (!host->mrq)
@@ -1075,7 +1074,6 @@ static void wbsd_tasklet_card(unsigned l
 {
 	struct wbsd_host* host = (struct wbsd_host*)param;
 	u8 csr;
-	int change = 0;
 	
 	spin_lock(&host->lock);
 	
@@ -1094,14 +1092,20 @@ static void wbsd_tasklet_card(unsigned l
 		{
 			DBG("Card inserted\n");
 			host->flags |= WBSD_FCARD_PRESENT;
-			change = 1;
+			
+			/*
+			 * Delay card detection to allow electrical connections
+			 * to stabilise.
+			 */
+			mod_timer(&host->timer, jiffies + HZ/2);
 		}
+		
+		spin_unlock(&host->lock);
 	}
 	else if (host->flags & WBSD_FCARD_PRESENT)
 	{
 		DBG("Card removed\n");
 		host->flags &= ~WBSD_FCARD_PRESENT;
-		change = 1;
 		
 		if (host->mrq)
 		{
@@ -1112,15 +1116,14 @@ static void wbsd_tasklet_card(unsigned l
 			host->mrq->cmd->error = MMC_ERR_FAILED;
 			tasklet_schedule(&host->finish_tasklet);
 		}
-	}
-	
-	/*
-	 * Unlock first since we might get a call back.
-	 */
-	spin_unlock(&host->lock);
+		
+		/*
+		 * Unlock first since we might get a call back.
+		 */
+		spin_unlock(&host->lock);
 
-	if (change)
 		mmc_detect_change(host->mmc);
+	}
 }
 
 static void wbsd_tasklet_fifo(unsigned long param)
@@ -1325,6 +1328,13 @@ static int __devinit wbsd_alloc_mmc(stru
 	spin_lock_init(&host->lock);
 	
 	/*
+	 * Set up detection timer
+	 */
+	init_timer(&host->timer);
+	host->timer.data = (unsigned long)host;
+	host->timer.function = wbsd_detect_card;
+	
+	/*
 	 * Maximum number of segments. Worst case is one sector per segment
 	 * so this will be 64kB/512.
 	 */
@@ -1351,11 +1361,17 @@ static int __devinit wbsd_alloc_mmc(stru
 static void __devexit wbsd_free_mmc(struct device* dev)
 {
 	struct mmc_host* mmc;
+	struct wbsd_host* host;
 	
 	mmc = dev_get_drvdata(dev);
 	if (!mmc)
 		return;
 	
+	host = mmc_priv(mmc);
+	BUG_ON(host == NULL);
+	
+	del_timer_sync(&host->timer);
+	
 	mmc_free_host(mmc);
 	
 	dev_set_drvdata(dev, NULL);
diff --git a/drivers/mmc/wbsd.h b/drivers/mmc/wbsd.h
--- a/drivers/mmc/wbsd.h
+++ b/drivers/mmc/wbsd.h
@@ -8,13 +8,6 @@
  * published by the Free Software Foundation.
  */
 
-const int config_ports[] = { 0x2E, 0x4E };
-const int unlock_codes[] = { 0x83, 0x87 };
-
-const int valid_ids[] = {
-	0x7112,
-	};
-
 #define LOCK_CODE		0xAA
 
 #define WBSD_CONF_SWRST		0x02
@@ -187,4 +180,6 @@ struct wbsd_host
 	struct tasklet_struct	timeout_tasklet;
 	struct tasklet_struct	finish_tasklet;
 	struct tasklet_struct	block_tasklet;
+	
+	struct timer_list	timer;		/* Card detection timer */
 };
diff --git a/drivers/mtd/afs.c b/drivers/mtd/afs.c
--- a/drivers/mtd/afs.c
+++ b/drivers/mtd/afs.c
@@ -219,7 +219,7 @@ static int parse_afs_partitions(struct m
 	 */
 	for (idx = off = 0; off < mtd->size; off += mtd->erasesize) {
 		struct image_info_struct iis;
-		u_int iis_ptr, img_ptr, size;
+		u_int iis_ptr, img_ptr;
 
 		/* Read the footer. */
 		ret = afs_read_footer(mtd, &img_ptr, &iis_ptr, off, mask);
@@ -236,21 +236,9 @@ static int parse_afs_partitions(struct m
 			continue;
 
 		strcpy(str, iis.name);
-		size = mtd->erasesize + off - img_ptr;
-
-		/*
-		 * In order to support JFFS2 partitions on this layout,
-		 * we must lie to MTD about the real size of JFFS2
-		 * partitions; this ensures that the AFS flash footer
-		 * won't be erased by JFFS2.  Please ensure that your
-		 * JFFS2 partitions are given image numbers between
-		 * 1000 and 2000 inclusive.
-		 */
-		if (iis.imageNumber >= 1000 && iis.imageNumber < 2000)
-			size -= mtd->erasesize;
 
 		parts[idx].name		= str;
-		parts[idx].size		= size;
+		parts[idx].size		= (iis.length + mtd->erasesize - 1) & ~(mtd->erasesize - 1);
 		parts[idx].offset	= img_ptr;
 		parts[idx].mask_flags	= 0;
 
diff --git a/drivers/mtd/chips/Kconfig b/drivers/mtd/chips/Kconfig
--- a/drivers/mtd/chips/Kconfig
+++ b/drivers/mtd/chips/Kconfig
@@ -1,5 +1,5 @@
 # drivers/mtd/chips/Kconfig
-# $Id: Kconfig,v 1.13 2004/12/01 15:49:10 nico Exp $
+# $Id: Kconfig,v 1.15 2005/06/06 23:04:35 tpoynor Exp $
 
 menu "RAM/ROM/Flash chip drivers"
 	depends on MTD!=n
@@ -155,6 +155,31 @@ config MTD_CFI_I8
 	  If your flash chips are interleaved in eights - i.e. you have eight
 	  flash chips addressed by each bus cycle, then say 'Y'.
 
+config MTD_OTP
+	bool "Protection Registers aka one-time programmable (OTP) bits"
+	depends on MTD_CFI_ADV_OPTIONS
+	default n
+	help
+	  This enables support for reading, writing and locking so called
+	  "Protection Registers" present on some flash chips.
+	  A subset of them are pre-programmed at the factory with a
+	  unique set of values. The rest is user-programmable.
+
+	  The user-programmable Protection Registers contain one-time
+	  programmable (OTP) bits; when programmed, register bits cannot be
+	  erased. Each Protection Register can be accessed multiple times to
+	  program individual bits, as long as the register remains unlocked.
+
+	  Each Protection Register has an associated Lock Register bit. When a
+	  Lock Register bit is programmed, the associated Protection Register
+	  can only be read; it can no longer be programmed. Additionally,
+	  because the Lock Register bits themselves are OTP, when programmed,
+	  Lock Register bits cannot be erased. Therefore, when a Protection
+	  Register is locked, it cannot be unlocked.
+
+	  This feature should therefore be used with extreme care. Any mistake
+	  in the programming of OTP bits will waste them.
+
 config MTD_CFI_INTELEXT
 	tristate "Support for Intel/Sharp flash chips"
 	depends on MTD_GEN_PROBE
@@ -275,7 +300,7 @@ config MTD_JEDEC
 
 config MTD_XIP
 	bool "XIP aware MTD support"
-	depends on !SMP && MTD_CFI_INTELEXT && EXPERIMENTAL
+	depends on !SMP && (MTD_CFI_INTELEXT || MTD_CFI_AMDSTD) && EXPERIMENTAL && ARM
 	default y if XIP_KERNEL
 	help
 	  This allows MTD support to work with flash memory which is also
diff --git a/drivers/mtd/chips/amd_flash.c b/drivers/mtd/chips/amd_flash.c
--- a/drivers/mtd/chips/amd_flash.c
+++ b/drivers/mtd/chips/amd_flash.c
@@ -3,7 +3,7 @@
  *
  * Author: Jonas Holmberg <jonas.holmberg@axis.com>
  *
- * $Id: amd_flash.c,v 1.26 2004/11/20 12:49:04 dwmw2 Exp $
+ * $Id: amd_flash.c,v 1.27 2005/02/04 07:43:09 jonashg Exp $
  *
  * Copyright (c) 2001 Axis Communications AB
  *
@@ -67,7 +67,6 @@
 #define AM29LV160DT	0x22C4
 #define AM29LV160DB	0x2249
 #define AM29BDS323D     0x22D1
-#define AM29BDS643D	0x227E
 
 /* Atmel */
 #define AT49xV16x	0x00C0
@@ -618,17 +617,6 @@ static struct mtd_info *amd_flash_probe(
 			{ .offset = 0x3f0000, .erasesize = 0x02000, .numblocks =  8 },
 		}
 	}, {
-		.mfr_id = MANUFACTURER_AMD,
-		.dev_id = AM29BDS643D,
-		.name = "AMD AM29BDS643D",
-		.size = 0x00800000,
-		.numeraseregions = 3,
-		.regions = {
-			{ .offset = 0x000000, .erasesize = 0x10000, .numblocks = 96 },
-			{ .offset = 0x600000, .erasesize = 0x10000, .numblocks = 31 },
-			{ .offset = 0x7f0000, .erasesize = 0x02000, .numblocks =  8 },
-		}
-	}, {
 		.mfr_id = MANUFACTURER_ATMEL,
 		.dev_id = AT49xV16x,
 		.name = "Atmel AT49xV16x",
diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c
--- a/drivers/mtd/chips/cfi_cmdset_0001.c
+++ b/drivers/mtd/chips/cfi_cmdset_0001.c
@@ -4,7 +4,7 @@
  *
  * (C) 2000 Red Hat. GPL'd
  *
- * $Id: cfi_cmdset_0001.c,v 1.164 2004/11/16 18:29:00 dwmw2 Exp $
+ * $Id: cfi_cmdset_0001.c,v 1.178 2005/05/19 17:05:43 nico Exp $
  *
  * 
  * 10/10/2000	Nicolas Pitre <nico@cam.org>
@@ -29,6 +29,7 @@
 #include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
+#include <linux/reboot.h>
 #include <linux/mtd/xip.h>
 #include <linux/mtd/map.h>
 #include <linux/mtd/mtd.h>
@@ -48,16 +49,25 @@
 #define M50LPW080       0x002F
 
 static int cfi_intelext_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
-//static int cfi_intelext_read_user_prot_reg (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
-//static int cfi_intelext_read_fact_prot_reg (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
 static int cfi_intelext_write_words(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
 static int cfi_intelext_write_buffers(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
 static int cfi_intelext_erase_varsize(struct mtd_info *, struct erase_info *);
 static void cfi_intelext_sync (struct mtd_info *);
 static int cfi_intelext_lock(struct mtd_info *mtd, loff_t ofs, size_t len);
 static int cfi_intelext_unlock(struct mtd_info *mtd, loff_t ofs, size_t len);
+#ifdef CONFIG_MTD_OTP
+static int cfi_intelext_read_fact_prot_reg (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
+static int cfi_intelext_read_user_prot_reg (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
+static int cfi_intelext_write_user_prot_reg (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
+static int cfi_intelext_lock_user_prot_reg (struct mtd_info *, loff_t, size_t);
+static int cfi_intelext_get_fact_prot_info (struct mtd_info *,
+					    struct otp_info *, size_t);
+static int cfi_intelext_get_user_prot_info (struct mtd_info *,
+					    struct otp_info *, size_t);
+#endif
 static int cfi_intelext_suspend (struct mtd_info *);
 static void cfi_intelext_resume (struct mtd_info *);
+static int cfi_intelext_reboot (struct notifier_block *, unsigned long, void *);
 
 static void cfi_intelext_destroy(struct mtd_info *);
 
@@ -252,7 +262,8 @@ read_pri_intelext(struct map_info *map, 
 		int nb_parts, i;
 
 		/* Protection Register info */
-		extra_size += (extp->NumProtectionFields - 1) * (4 + 6);
+		extra_size += (extp->NumProtectionFields - 1) *
+			      sizeof(struct cfi_intelext_otpinfo);
 
 		/* Burst Read info */
 		extra_size += 6;
@@ -324,7 +335,9 @@ struct mtd_info *cfi_cmdset_0001(struct 
 	mtd->resume  = cfi_intelext_resume;
 	mtd->flags   = MTD_CAP_NORFLASH;
 	mtd->name    = map->name;
-	
+
+	mtd->reboot_notifier.notifier_call = cfi_intelext_reboot;
+
 	if (cfi->cfi_mode == CFI_MODE_CFI) {
 		/* 
 		 * It's a real CFI chip, not one for which the probe
@@ -422,9 +435,13 @@ static struct mtd_info *cfi_intelext_set
 		       mtd->eraseregions[i].numblocks);
 	}
 
-#if 0
-	mtd->read_user_prot_reg = cfi_intelext_read_user_prot_reg;
+#ifdef CONFIG_MTD_OTP
 	mtd->read_fact_prot_reg = cfi_intelext_read_fact_prot_reg;
+	mtd->read_user_prot_reg = cfi_intelext_read_user_prot_reg;
+	mtd->write_user_prot_reg = cfi_intelext_write_user_prot_reg;
+	mtd->lock_user_prot_reg = cfi_intelext_lock_user_prot_reg;
+	mtd->get_fact_prot_info = cfi_intelext_get_fact_prot_info;
+	mtd->get_user_prot_info = cfi_intelext_get_user_prot_info;
 #endif
 
 	/* This function has the potential to distort the reality
@@ -433,6 +450,7 @@ static struct mtd_info *cfi_intelext_set
 		goto setup_err;
 
 	__module_get(THIS_MODULE);
+	register_reboot_notifier(&mtd->reboot_notifier);
 	return mtd;
 
  setup_err:
@@ -471,7 +489,8 @@ static int cfi_intelext_partition_fixup(
 		int offs, numregions, numparts, partshift, numvirtchips, i, j;
 
 		/* Protection Register info */
-		offs = (extp->NumProtectionFields - 1) * (4 + 6);
+		offs = (extp->NumProtectionFields - 1) *
+		       sizeof(struct cfi_intelext_otpinfo);
 
 		/* Burst Read info */
 		offs += 6;
@@ -563,7 +582,7 @@ static int get_chip(struct map_info *map
  resettime:
 	timeo = jiffies + HZ;
  retry:
-	if (chip->priv && (mode == FL_WRITING || mode == FL_ERASING)) {
+	if (chip->priv && (mode == FL_WRITING || mode == FL_ERASING || mode == FL_OTP_WRITE)) {
 		/*
 		 * OK. We have possibility for contension on the write/erase
 		 * operations which are global to the real chip and not per
@@ -807,10 +826,6 @@ static void put_chip(struct map_info *ma
  * assembly to make sure inline functions were actually inlined and that gcc
  * didn't emit calls to its own support functions). Also configuring MTD CFI
  * support to a single buswidth and a single interleave is also recommended.
- * Note that not only IRQs are disabled but the preemption count is also
- * increased to prevent other locking primitives (namely spin_unlock) from
- * decrementing the preempt count to zero and scheduling the CPU away while
- * not in array mode.
  */
 
 static void xip_disable(struct map_info *map, struct flchip *chip,
@@ -818,7 +833,6 @@ static void xip_disable(struct map_info 
 {
 	/* TODO: chips with no XIP use should ignore and return */
 	(void) map_read(map, adr); /* ensure mmu mapping is up to date */
-	preempt_disable();
 	local_irq_disable();
 }
 
@@ -831,9 +845,8 @@ static void __xipram xip_enable(struct m
 		chip->state = FL_READY;
 	}
 	(void) map_read(map, adr);
-	asm volatile (".rep 8; nop; .endr"); /* fill instruction prefetch */
+	xip_iprefetch();
 	local_irq_enable();
-	preempt_enable();
 }
 
 /*
@@ -909,7 +922,7 @@ static void __xipram xip_udelay(struct m
 			(void) map_read(map, adr);
 			asm volatile (".rep 8; nop; .endr");
 			local_irq_enable();
-			preempt_enable();
+			spin_unlock(chip->mutex);
 			asm volatile (".rep 8; nop; .endr");
 			cond_resched();
 
@@ -919,15 +932,15 @@ static void __xipram xip_udelay(struct m
 			 * a suspended erase state.  If so let's wait
 			 * until it's done.
 			 */
-			preempt_disable();
+			spin_lock(chip->mutex);
 			while (chip->state != newstate) {
 				DECLARE_WAITQUEUE(wait, current);
 				set_current_state(TASK_UNINTERRUPTIBLE);
 				add_wait_queue(&chip->wq, &wait);
-				preempt_enable();
+				spin_unlock(chip->mutex);
 				schedule();
 				remove_wait_queue(&chip->wq, &wait);
-				preempt_disable();
+				spin_lock(chip->mutex);
 			}
 			/* Disallow XIP again */
 			local_irq_disable();
@@ -956,12 +969,14 @@ static void __xipram xip_udelay(struct m
  * The INVALIDATE_CACHED_RANGE() macro is normally used in parallel while
  * the flash is actively programming or erasing since we have to poll for
  * the operation to complete anyway.  We can't do that in a generic way with
- * a XIP setup so do it before the actual flash operation in this case.
+ * a XIP setup so do it before the actual flash operation in this case
+ * and stub it out from INVALIDATE_CACHE_UDELAY.
  */
-#undef INVALIDATE_CACHED_RANGE
-#define INVALIDATE_CACHED_RANGE(x...)
-#define XIP_INVAL_CACHED_RANGE(map, from, size) \
-	do { if(map->inval_cache) map->inval_cache(map, from, size); } while(0)
+#define XIP_INVAL_CACHED_RANGE(map, from, size)  \
+	INVALIDATE_CACHED_RANGE(map, from, size)
+
+#define INVALIDATE_CACHE_UDELAY(map, chip, adr, len, usec)  \
+	UDELAY(map, chip, adr, usec)
 
 /*
  * Extra notes:
@@ -984,11 +999,23 @@ static void __xipram xip_udelay(struct m
 
 #define xip_disable(map, chip, adr)
 #define xip_enable(map, chip, adr)
-
-#define UDELAY(map, chip, adr, usec)  cfi_udelay(usec)
-
 #define XIP_INVAL_CACHED_RANGE(x...)
 
+#define UDELAY(map, chip, adr, usec)  \
+do {  \
+	spin_unlock(chip->mutex);  \
+	cfi_udelay(usec);  \
+	spin_lock(chip->mutex);  \
+} while (0)
+
+#define INVALIDATE_CACHE_UDELAY(map, chip, adr, len, usec)  \
+do {  \
+	spin_unlock(chip->mutex);  \
+	INVALIDATE_CACHED_RANGE(map, adr, len);  \
+	cfi_udelay(usec);  \
+	spin_lock(chip->mutex);  \
+} while (0)
+
 #endif
 
 static int do_point_onechip (struct map_info *map, struct flchip *chip, loff_t adr, size_t len)
@@ -1176,111 +1203,11 @@ static int cfi_intelext_read (struct mtd
 	return ret;
 }
 
-#if 0
-static int __xipram cfi_intelext_read_prot_reg (struct mtd_info *mtd,
-						loff_t from, size_t len,
-						size_t *retlen,
-						u_char *buf,
-						int base_offst, int reg_sz)
-{
-	struct map_info *map = mtd->priv;
-	struct cfi_private *cfi = map->fldrv_priv;
-	struct cfi_pri_intelext *extp = cfi->cmdset_priv;
-	struct flchip *chip;
-	int ofs_factor = cfi->interleave * cfi->device_type;
-	int count = len;
-	int chip_num, offst;
-	int ret;
-
-	chip_num = ((unsigned int)from/reg_sz);
-	offst = from - (reg_sz*chip_num)+base_offst;
-
-	while (count) {
-	/* Calculate which chip & protection register offset we need */
-
-		if (chip_num >= cfi->numchips)
-			goto out;
-
-		chip = &cfi->chips[chip_num];
-		
-		spin_lock(chip->mutex);
-		ret = get_chip(map, chip, chip->start, FL_JEDEC_QUERY);
-		if (ret) {
-			spin_unlock(chip->mutex);
-			return (len-count)?:ret;
-		}
-
-		xip_disable(map, chip, chip->start);
-
-		if (chip->state != FL_JEDEC_QUERY) {
-			map_write(map, CMD(0x90), chip->start);
-			chip->state = FL_JEDEC_QUERY;
-		}
-
-		while (count && ((offst-base_offst) < reg_sz)) {
-			*buf = map_read8(map,(chip->start+((extp->ProtRegAddr+1)*ofs_factor)+offst));
-			buf++;
-			offst++;
-			count--;
-		}
-
-		xip_enable(map, chip, chip->start);
-		put_chip(map, chip, chip->start);
-		spin_unlock(chip->mutex);
-
-		/* Move on to the next chip */
-		chip_num++;
-		offst = base_offst;
-	}
-	
- out:	
-	return len-count;
-}
-	
-static int cfi_intelext_read_user_prot_reg (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf)
-{
-	struct map_info *map = mtd->priv;
-	struct cfi_private *cfi = map->fldrv_priv;
-	struct cfi_pri_intelext *extp=cfi->cmdset_priv;
-	int base_offst,reg_sz;
-	
-	/* Check that we actually have some protection registers */
-	if(!extp || !(extp->FeatureSupport&64)){
-		printk(KERN_WARNING "%s: This flash device has no protection data to read!\n",map->name);
-		return 0;
-	}
-
-	base_offst=(1<<extp->FactProtRegSize);
-	reg_sz=(1<<extp->UserProtRegSize);
-
-	return cfi_intelext_read_prot_reg(mtd, from, len, retlen, buf, base_offst, reg_sz);
-}
-
-static int cfi_intelext_read_fact_prot_reg (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf)
-{
-	struct map_info *map = mtd->priv;
-	struct cfi_private *cfi = map->fldrv_priv;
-	struct cfi_pri_intelext *extp=cfi->cmdset_priv;
-	int base_offst,reg_sz;
-	
-	/* Check that we actually have some protection registers */
-	if(!extp || !(extp->FeatureSupport&64)){
-		printk(KERN_WARNING "%s: This flash device has no protection data to read!\n",map->name);
-		return 0;
-	}
-
-	base_offst=0;
-	reg_sz=(1<<extp->FactProtRegSize);
-
-	return cfi_intelext_read_prot_reg(mtd, from, len, retlen, buf, base_offst, reg_sz);
-}
-#endif
-
 static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip,
-				     unsigned long adr, map_word datum)
+				     unsigned long adr, map_word datum, int mode)
 {
 	struct cfi_private *cfi = map->fldrv_priv;
-	map_word status, status_OK;
+	map_word status, status_OK, write_cmd;
 	unsigned long timeo;
 	int z, ret=0;
 
@@ -1288,9 +1215,14 @@ static int __xipram do_write_oneword(str
 
 	/* Let's determine this according to the interleave only once */
 	status_OK = CMD(0x80);
+	switch (mode) {
+	case FL_WRITING:   write_cmd = CMD(0x40); break;
+	case FL_OTP_WRITE: write_cmd = CMD(0xc0); break;
+	default: return -EINVAL;
+	}
 
 	spin_lock(chip->mutex);
-	ret = get_chip(map, chip, adr, FL_WRITING);
+	ret = get_chip(map, chip, adr, mode);
 	if (ret) {
 		spin_unlock(chip->mutex);
 		return ret;
@@ -1299,19 +1231,18 @@ static int __xipram do_write_oneword(str
 	XIP_INVAL_CACHED_RANGE(map, adr, map_bankwidth(map));
 	ENABLE_VPP(map);
 	xip_disable(map, chip, adr);
-	map_write(map, CMD(0x40), adr);
+	map_write(map, write_cmd, adr);
 	map_write(map, datum, adr);
-	chip->state = FL_WRITING;
+	chip->state = mode;
 
-	spin_unlock(chip->mutex);
-	INVALIDATE_CACHED_RANGE(map, adr, map_bankwidth(map));
-	UDELAY(map, chip, adr, chip->word_write_time);
-	spin_lock(chip->mutex);
+	INVALIDATE_CACHE_UDELAY(map, chip,
+				adr, map_bankwidth(map),
+				chip->word_write_time);
 
 	timeo = jiffies + (HZ/2);
 	z = 0;
 	for (;;) {
-		if (chip->state != FL_WRITING) {
+		if (chip->state != mode) {
 			/* Someone's suspended the write. Sleep */
 			DECLARE_WAITQUEUE(wait, current);
 
@@ -1339,10 +1270,8 @@ static int __xipram do_write_oneword(str
 		}
 
 		/* Latency issues. Drop the lock, wait a while and retry */
-		spin_unlock(chip->mutex);
 		z++;
 		UDELAY(map, chip, adr, 1);
-		spin_lock(chip->mutex);
 	}
 	if (!z) {
 		chip->word_write_time--;
@@ -1399,7 +1328,7 @@ static int cfi_intelext_write_words (str
 		datum = map_word_load_partial(map, datum, buf, gap, n);
 
 		ret = do_write_oneword(map, &cfi->chips[chipnum],
-					       bus_ofs, datum);
+					       bus_ofs, datum, FL_WRITING);
 		if (ret) 
 			return ret;
 
@@ -1420,7 +1349,7 @@ static int cfi_intelext_write_words (str
 		map_word datum = map_word_load(map, buf);
 
 		ret = do_write_oneword(map, &cfi->chips[chipnum],
-				ofs, datum);
+				       ofs, datum, FL_WRITING);
 		if (ret)
 			return ret;
 
@@ -1444,7 +1373,7 @@ static int cfi_intelext_write_words (str
 		datum = map_word_load_partial(map, datum, buf, 0, len);
 
 		ret = do_write_oneword(map, &cfi->chips[chipnum],
-					       ofs, datum);
+				       ofs, datum, FL_WRITING);
 		if (ret) 
 			return ret;
 		
@@ -1506,9 +1435,7 @@ static int __xipram do_write_buffer(stru
 		if (map_word_andequal(map, status, status_OK, status_OK))
 			break;
 
-		spin_unlock(chip->mutex);
 		UDELAY(map, chip, cmd_adr, 1);
-		spin_lock(chip->mutex);
 
 		if (++z > 20) {
 			/* Argh. Not ready for write to buffer */
@@ -1554,10 +1481,9 @@ static int __xipram do_write_buffer(stru
 	map_write(map, CMD(0xd0), cmd_adr);
 	chip->state = FL_WRITING;
 
-	spin_unlock(chip->mutex);
-	INVALIDATE_CACHED_RANGE(map, adr, len);
-	UDELAY(map, chip, cmd_adr, chip->buffer_write_time);
-	spin_lock(chip->mutex);
+	INVALIDATE_CACHE_UDELAY(map, chip, 
+				cmd_adr, len,
+				chip->buffer_write_time);
 
 	timeo = jiffies + (HZ/2);
 	z = 0;
@@ -1589,10 +1515,8 @@ static int __xipram do_write_buffer(stru
 		}
 		
 		/* Latency issues. Drop the lock, wait a while and retry */
-		spin_unlock(chip->mutex);
-		UDELAY(map, chip, cmd_adr, 1);
 		z++;
-		spin_lock(chip->mutex);
+		UDELAY(map, chip, cmd_adr, 1);
 	}
 	if (!z) {
 		chip->buffer_write_time--;
@@ -1720,10 +1644,9 @@ static int __xipram do_erase_oneblock(st
 	chip->state = FL_ERASING;
 	chip->erase_suspended = 0;
 
-	spin_unlock(chip->mutex);
-	INVALIDATE_CACHED_RANGE(map, adr, len);
-	UDELAY(map, chip, adr, chip->erase_time*1000/2);
-	spin_lock(chip->mutex);
+	INVALIDATE_CACHE_UDELAY(map, chip,
+				adr, len,
+				chip->erase_time*1000/2);
 
 	/* FIXME. Use a timer to check this, and return immediately. */
 	/* Once the state machine's known to be working I'll do that */
@@ -1768,9 +1691,7 @@ static int __xipram do_erase_oneblock(st
 		}
 		
 		/* Latency issues. Drop the lock, wait a while and retry */
-		spin_unlock(chip->mutex);
 		UDELAY(map, chip, adr, 1000000/HZ);
-		spin_lock(chip->mutex);
 	}
 
 	/* We've broken this before. It doesn't hurt to be safe */
@@ -1780,44 +1701,34 @@ static int __xipram do_erase_oneblock(st
 
 	/* check for lock bit */
 	if (map_word_bitsset(map, status, CMD(0x3a))) {
-		unsigned char chipstatus;
+		unsigned long chipstatus;
 
 		/* Reset the error bits */
 		map_write(map, CMD(0x50), adr);
 		map_write(map, CMD(0x70), adr);
 		xip_enable(map, chip, adr);
 
-		chipstatus = status.x[0];
-		if (!map_word_equal(map, status, CMD(chipstatus))) {
-			int i, w;
-			for (w=0; w<map_words(map); w++) {
-				for (i = 0; i<cfi_interleave(cfi); i++) {
-					chipstatus |= status.x[w] >> (cfi->device_type * 8);
-				}
-			}
-			printk(KERN_WARNING "Status is not identical for all chips: 0x%lx. Merging to give 0x%02x\n",
-			       status.x[0], chipstatus);
-		}
+		chipstatus = MERGESTATUS(status);
 
 		if ((chipstatus & 0x30) == 0x30) {
-			printk(KERN_NOTICE "Chip reports improper command sequence: status 0x%x\n", chipstatus);
+			printk(KERN_NOTICE "Chip reports improper command sequence: status 0x%lx\n", chipstatus);
 			ret = -EIO;
 		} else if (chipstatus & 0x02) {
 			/* Protection bit set */
 			ret = -EROFS;
 		} else if (chipstatus & 0x8) {
 			/* Voltage */
-			printk(KERN_WARNING "Chip reports voltage low on erase: status 0x%x\n", chipstatus);
+			printk(KERN_WARNING "Chip reports voltage low on erase: status 0x%lx\n", chipstatus);
 			ret = -EIO;
 		} else if (chipstatus & 0x20) {
 			if (retries--) {
-				printk(KERN_DEBUG "Chip erase failed at 0x%08lx: status 0x%x. Retrying...\n", adr, chipstatus);
+				printk(KERN_DEBUG "Chip erase failed at 0x%08lx: status 0x%lx. Retrying...\n", adr, chipstatus);
 				timeo = jiffies + HZ;
 				put_chip(map, chip, adr);
 				spin_unlock(chip->mutex);
 				goto retry;
 			}
-			printk(KERN_DEBUG "Chip erase failed at 0x%08lx: status 0x%x\n", adr, chipstatus);
+			printk(KERN_DEBUG "Chip erase failed at 0x%08lx: status 0x%lx\n", adr, chipstatus);
 			ret = -EIO;
 		}
 	} else {
@@ -1882,6 +1793,7 @@ static void cfi_intelext_sync (struct mt
 		
 		if (chip->state == FL_SYNCING) {
 			chip->state = chip->oldstate;
+			chip->oldstate = FL_READY;
 			wake_up(&chip->wq);
 		}
 		spin_unlock(chip->mutex);
@@ -1897,8 +1809,9 @@ static int __xipram do_printlockstatus_o
 	struct cfi_private *cfi = map->fldrv_priv;
 	int status, ofs_factor = cfi->interleave * cfi->device_type;
 
+	adr += chip->start;
 	xip_disable(map, chip, adr+(2*ofs_factor));
-	cfi_send_gen_cmd(0x90, 0x55, 0, map, cfi, cfi->device_type, NULL);
+	map_write(map, CMD(0x90), adr+(2*ofs_factor));
 	chip->state = FL_JEDEC_QUERY;
 	status = cfi_read_query(map, adr+(2*ofs_factor));
 	xip_enable(map, chip, 0);
@@ -1915,6 +1828,7 @@ static int __xipram do_xxlock_oneblock(s
 				       unsigned long adr, int len, void *thunk)
 {
 	struct cfi_private *cfi = map->fldrv_priv;
+	struct cfi_pri_intelext *extp = cfi->cmdset_priv;
 	map_word status, status_OK;
 	unsigned long timeo = jiffies + HZ;
 	int ret;
@@ -1944,9 +1858,13 @@ static int __xipram do_xxlock_oneblock(s
 	} else
 		BUG();
 
-	spin_unlock(chip->mutex);
-	UDELAY(map, chip, adr, 1000000/HZ);
-	spin_lock(chip->mutex);
+	/*
+	 * If Instant Individual Block Locking supported then no need
+	 * to delay.
+	 */
+
+	if (!extp || !(extp->FeatureSupport & (1 << 5)))
+		UDELAY(map, chip, adr, 1000000/HZ);
 
 	/* FIXME. Use a timer to check this, and return immediately. */
 	/* Once the state machine's known to be working I'll do that */
@@ -1973,9 +1891,7 @@ static int __xipram do_xxlock_oneblock(s
 		}
 		
 		/* Latency issues. Drop the lock, wait a while and retry */
-		spin_unlock(chip->mutex);
 		UDELAY(map, chip, adr, 1);
-		spin_lock(chip->mutex);
 	}
 	
 	/* Done and happy. */
@@ -2034,6 +1950,274 @@ static int cfi_intelext_unlock(struct mt
 	return ret;
 }
 
+#ifdef CONFIG_MTD_OTP
+
+typedef int (*otp_op_t)(struct map_info *map, struct flchip *chip, 
+			u_long data_offset, u_char *buf, u_int size,
+			u_long prot_offset, u_int groupno, u_int groupsize);
+
+static int __xipram
+do_otp_read(struct map_info *map, struct flchip *chip, u_long offset,
+	    u_char *buf, u_int size, u_long prot, u_int grpno, u_int grpsz)
+{
+	struct cfi_private *cfi = map->fldrv_priv;
+	int ret;
+
+	spin_lock(chip->mutex);
+	ret = get_chip(map, chip, chip->start, FL_JEDEC_QUERY);
+	if (ret) {
+		spin_unlock(chip->mutex);
+		return ret;
+	}
+
+	/* let's ensure we're not reading back cached data from array mode */
+	INVALIDATE_CACHED_RANGE(map, chip->start + offset, size);
+
+	xip_disable(map, chip, chip->start);
+	if (chip->state != FL_JEDEC_QUERY) {
+		map_write(map, CMD(0x90), chip->start);
+		chip->state = FL_JEDEC_QUERY;
+	}
+	map_copy_from(map, buf, chip->start + offset, size);
+	xip_enable(map, chip, chip->start);
+
+	/* then ensure we don't keep OTP data in the cache */
+	INVALIDATE_CACHED_RANGE(map, chip->start + offset, size);
+
+	put_chip(map, chip, chip->start);
+	spin_unlock(chip->mutex);
+	return 0;
+}
+
+static int
+do_otp_write(struct map_info *map, struct flchip *chip, u_long offset,
+	     u_char *buf, u_int size, u_long prot, u_int grpno, u_int grpsz)
+{
+	int ret;
+
+	while (size) {
+		unsigned long bus_ofs = offset & ~(map_bankwidth(map)-1);
+		int gap = offset - bus_ofs;
+		int n = min_t(int, size, map_bankwidth(map)-gap);
+		map_word datum = map_word_ff(map);
+
+		datum = map_word_load_partial(map, datum, buf, gap, n);
+		ret = do_write_oneword(map, chip, bus_ofs, datum, FL_OTP_WRITE);
+		if (ret) 
+			return ret;
+
+		offset += n;
+		buf += n;
+		size -= n;
+	}
+
+	return 0;
+}
+
+static int
+do_otp_lock(struct map_info *map, struct flchip *chip, u_long offset,
+	    u_char *buf, u_int size, u_long prot, u_int grpno, u_int grpsz)
+{
+	struct cfi_private *cfi = map->fldrv_priv;
+	map_word datum;
+
+	/* make sure area matches group boundaries */
+	if (size != grpsz)
+		return -EXDEV;
+
+	datum = map_word_ff(map);
+	datum = map_word_clr(map, datum, CMD(1 << grpno));
+	return do_write_oneword(map, chip, prot, datum, FL_OTP_WRITE);
+}
+
+static int cfi_intelext_otp_walk(struct mtd_info *mtd, loff_t from, size_t len,
+				 size_t *retlen, u_char *buf,
+				 otp_op_t action, int user_regs)
+{
+	struct map_info *map = mtd->priv;
+	struct cfi_private *cfi = map->fldrv_priv;
+	struct cfi_pri_intelext *extp = cfi->cmdset_priv;
+	struct flchip *chip;
+	struct cfi_intelext_otpinfo *otp;
+	u_long devsize, reg_prot_offset, data_offset;
+	u_int chip_num, chip_step, field, reg_fact_size, reg_user_size;
+	u_int groups, groupno, groupsize, reg_fact_groups, reg_user_groups;
+	int ret;
+
+	*retlen = 0;
+
+	/* Check that we actually have some OTP registers */
+	if (!extp || !(extp->FeatureSupport & 64) || !extp->NumProtectionFields)
+		return -ENODATA;
+
+	/* we need real chips here not virtual ones */
+	devsize = (1 << cfi->cfiq->DevSize) * cfi->interleave;
+	chip_step = devsize >> cfi->chipshift;
+	chip_num = 0;
+
+	/* Some chips have OTP located in the _top_ partition only.
+	   For example: Intel 28F256L18T (T means top-parameter device) */
+	if (cfi->mfr == MANUFACTURER_INTEL) {
+		switch (cfi->id) {
+		case 0x880b:
+		case 0x880c:
+		case 0x880d:
+			chip_num = chip_step - 1;
+		}
+	}
+
+	for ( ; chip_num < cfi->numchips; chip_num += chip_step) {
+		chip = &cfi->chips[chip_num];
+		otp = (struct cfi_intelext_otpinfo *)&extp->extra[0];
+
+		/* first OTP region */
+		field = 0;
+		reg_prot_offset = extp->ProtRegAddr;
+		reg_fact_groups = 1;
+		reg_fact_size = 1 << extp->FactProtRegSize;
+		reg_user_groups = 1;
+		reg_user_size = 1 << extp->UserProtRegSize;
+
+		while (len > 0) {
+			/* flash geometry fixup */
+			data_offset = reg_prot_offset + 1;
+			data_offset *= cfi->interleave * cfi->device_type;
+			reg_prot_offset *= cfi->interleave * cfi->device_type;
+			reg_fact_size *= cfi->interleave;
+			reg_user_size *= cfi->interleave;
+
+			if (user_regs) {
+				groups = reg_user_groups;
+				groupsize = reg_user_size;
+				/* skip over factory reg area */
+				groupno = reg_fact_groups;
+				data_offset += reg_fact_groups * reg_fact_size;
+			} else {
+				groups = reg_fact_groups;
+				groupsize = reg_fact_size;
+				groupno = 0;
+			}
+
+			while (len > 0 && groups > 0) {
+				if (!action) {
+					/*
+					 * Special case: if action is NULL
+					 * we fill buf with otp_info records.
+					 */
+					struct otp_info *otpinfo;
+					map_word lockword;
+					len -= sizeof(struct otp_info);
+					if (len <= 0)
+						return -ENOSPC;
+					ret = do_otp_read(map, chip,
+							  reg_prot_offset,
+							  (u_char *)&lockword,
+							  map_bankwidth(map),
+							  0, 0,  0);
+					if (ret)
+						return ret;
+					otpinfo = (struct otp_info *)buf;
+					otpinfo->start = from;
+					otpinfo->length = groupsize;
+					otpinfo->locked =
+					   !map_word_bitsset(map, lockword,
+							     CMD(1 << groupno));
+					from += groupsize;
+					buf += sizeof(*otpinfo);
+					*retlen += sizeof(*otpinfo);
+				} else if (from >= groupsize) {
+					from -= groupsize;
+					data_offset += groupsize;
+				} else {
+					int size = groupsize;
+					data_offset += from;
+					size -= from;
+					from = 0;
+					if (size > len)
+						size = len;
+					ret = action(map, chip, data_offset,
+						     buf, size, reg_prot_offset,
+						     groupno, groupsize);
+					if (ret < 0)
+						return ret;
+					buf += size;
+					len -= size;
+					*retlen += size;
+					data_offset += size;
+				}
+				groupno++;
+				groups--;
+			}
+
+			/* next OTP region */
+			if (++field == extp->NumProtectionFields)
+				break;
+			reg_prot_offset = otp->ProtRegAddr;
+			reg_fact_groups = otp->FactGroups;
+			reg_fact_size = 1 << otp->FactProtRegSize;
+			reg_user_groups = otp->UserGroups;
+			reg_user_size = 1 << otp->UserProtRegSize;
+			otp++;
+		}
+	}
+
+	return 0;
+}
+
+static int cfi_intelext_read_fact_prot_reg(struct mtd_info *mtd, loff_t from,
+					   size_t len, size_t *retlen,
+					    u_char *buf)
+{
+	return cfi_intelext_otp_walk(mtd, from, len, retlen,
+				     buf, do_otp_read, 0);
+}
+
+static int cfi_intelext_read_user_prot_reg(struct mtd_info *mtd, loff_t from,
+					   size_t len, size_t *retlen,
+					    u_char *buf)
+{
+	return cfi_intelext_otp_walk(mtd, from, len, retlen,
+				     buf, do_otp_read, 1);
+}
+
+static int cfi_intelext_write_user_prot_reg(struct mtd_info *mtd, loff_t from,
+					    size_t len, size_t *retlen,
+					     u_char *buf)
+{
+	return cfi_intelext_otp_walk(mtd, from, len, retlen,
+				     buf, do_otp_write, 1);
+}
+
+static int cfi_intelext_lock_user_prot_reg(struct mtd_info *mtd,
+					   loff_t from, size_t len)
+{
+	size_t retlen;
+	return cfi_intelext_otp_walk(mtd, from, len, &retlen,
+				     NULL, do_otp_lock, 1);
+}
+
+static int cfi_intelext_get_fact_prot_info(struct mtd_info *mtd, 
+					   struct otp_info *buf, size_t len)
+{
+	size_t retlen;
+	int ret;
+
+	ret = cfi_intelext_otp_walk(mtd, 0, len, &retlen, (u_char *)buf, NULL, 0);
+	return ret ? : retlen;
+}
+
+static int cfi_intelext_get_user_prot_info(struct mtd_info *mtd,
+					   struct otp_info *buf, size_t len)
+{
+	size_t retlen;
+	int ret;
+
+	ret = cfi_intelext_otp_walk(mtd, 0, len, &retlen, (u_char *)buf, NULL, 1);
+	return ret ? : retlen;
+}
+
+#endif
+
 static int cfi_intelext_suspend(struct mtd_info *mtd)
 {
 	struct map_info *map = mtd->priv;
@@ -2125,10 +2309,46 @@ static void cfi_intelext_resume(struct m
 	}
 }
 
+static int cfi_intelext_reset(struct mtd_info *mtd)
+{
+	struct map_info *map = mtd->priv;
+	struct cfi_private *cfi = map->fldrv_priv;
+	int i, ret;
+
+	for (i=0; i < cfi->numchips; i++) {
+		struct flchip *chip = &cfi->chips[i];
+
+		/* force the completion of any ongoing operation
+		   and switch to array mode so any bootloader in 
+		   flash is accessible for soft reboot. */
+		spin_lock(chip->mutex);
+		ret = get_chip(map, chip, chip->start, FL_SYNCING);
+		if (!ret) {
+			map_write(map, CMD(0xff), chip->start);
+			chip->state = FL_READY;
+		}
+		spin_unlock(chip->mutex);
+	}
+
+	return 0;
+}
+
+static int cfi_intelext_reboot(struct notifier_block *nb, unsigned long val,
+			       void *v)
+{
+	struct mtd_info *mtd;
+
+	mtd = container_of(nb, struct mtd_info, reboot_notifier);
+	cfi_intelext_reset(mtd);
+	return NOTIFY_DONE;
+}
+
 static void cfi_intelext_destroy(struct mtd_info *mtd)
 {
 	struct map_info *map = mtd->priv;
 	struct cfi_private *cfi = map->fldrv_priv;
+	cfi_intelext_reset(mtd);
+	unregister_reboot_notifier(&mtd->reboot_notifier);
 	kfree(cfi->cmdset_priv);
 	kfree(cfi->cfiq);
 	kfree(cfi->chips[0].priv);
diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c
--- a/drivers/mtd/chips/cfi_cmdset_0002.c
+++ b/drivers/mtd/chips/cfi_cmdset_0002.c
@@ -4,16 +4,20 @@
  *
  * Copyright (C) 2000 Crossnet Co. <info@crossnet.co.jp>
  * Copyright (C) 2004 Arcom Control Systems Ltd <linux@arcom.com>
+ * Copyright (C) 2005 MontaVista Software Inc. <source@mvista.com>
  *
  * 2_by_8 routines added by Simon Munton
  *
  * 4_by_16 work by Carolyn J. Smith
  *
+ * XIP support hooks by Vitaly Wool (based on code for Intel flash 
+ * by Nicolas Pitre)
+ * 
  * Occasionally maintained by Thayne Harbaugh tharbaugh at lnxi dot com
  *
  * This code is GPL
  *
- * $Id: cfi_cmdset_0002.c,v 1.114 2004/12/11 15:43:53 dedekind Exp $
+ * $Id: cfi_cmdset_0002.c,v 1.118 2005/07/04 22:34:29 gleixner Exp $
  *
  */
 
@@ -34,6 +38,7 @@
 #include <linux/mtd/map.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/cfi.h>
+#include <linux/mtd/xip.h>
 
 #define AMD_BOOTLOC_BUG
 #define FORCE_WORD_WRITE 0
@@ -43,6 +48,7 @@
 #define MANUFACTURER_AMD	0x0001
 #define MANUFACTURER_SST	0x00BF
 #define SST49LF004B	        0x0060
+#define SST49LF008A		0x005a
 
 static int cfi_amdstd_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
 static int cfi_amdstd_write_words(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
@@ -191,6 +197,7 @@ static struct cfi_fixup cfi_fixup_table[
 };
 static struct cfi_fixup jedec_fixup_table[] = {
 	{ MANUFACTURER_SST, SST49LF004B, fixup_use_fwh_lock, NULL, },
+	{ MANUFACTURER_SST, SST49LF008A, fixup_use_fwh_lock, NULL, },
 	{ 0, 0, NULL, NULL }
 };
 
@@ -391,7 +398,7 @@ static struct mtd_info *cfi_amdstd_setup
  * correctly and is therefore not done	(particulary with interleaved chips
  * as each chip must be checked independantly of the others).
  */
-static int chip_ready(struct map_info *map, unsigned long addr)
+static int __xipram chip_ready(struct map_info *map, unsigned long addr)
 {
 	map_word d, t;
 
@@ -401,6 +408,32 @@ static int chip_ready(struct map_info *m
 	return map_word_equal(map, d, t);
 }
 
+/*
+ * Return true if the chip is ready and has the correct value.
+ *
+ * Ready is one of: read mode, query mode, erase-suspend-read mode (in any
+ * non-suspended sector) and it is indicated by no bits toggling.
+ *
+ * Error are indicated by toggling bits or bits held with the wrong value,
+ * or with bits toggling.
+ *
+ * Note that anything more complicated than checking if no bits are toggling
+ * (including checking DQ5 for an error status) is tricky to get working
+ * correctly and is therefore not done	(particulary with interleaved chips
+ * as each chip must be checked independantly of the others).
+ *
+ */
+static int __xipram chip_good(struct map_info *map, unsigned long addr, map_word expected)
+{
+	map_word oldd, curd;
+
+	oldd = map_read(map, addr);
+	curd = map_read(map, addr);
+
+	return	map_word_equal(map, oldd, curd) && 
+		map_word_equal(map, curd, expected);
+}
+
 static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr, int mode)
 {
 	DECLARE_WAITQUEUE(wait, current);
@@ -420,12 +453,12 @@ static int get_chip(struct map_info *map
 
 			if (time_after(jiffies, timeo)) {
 				printk(KERN_ERR "Waiting for chip to be ready timed out.\n");
-				cfi_spin_unlock(chip->mutex);
+				spin_unlock(chip->mutex);
 				return -EIO;
 			}
-			cfi_spin_unlock(chip->mutex);
+			spin_unlock(chip->mutex);
 			cfi_udelay(1);
-			cfi_spin_lock(chip->mutex);
+			spin_lock(chip->mutex);
 			/* Someone else might have been playing with it. */
 			goto retry;
 		}
@@ -473,15 +506,23 @@ static int get_chip(struct map_info *map
 				return -EIO;
 			}
 			
-			cfi_spin_unlock(chip->mutex);
+			spin_unlock(chip->mutex);
 			cfi_udelay(1);
-			cfi_spin_lock(chip->mutex);
+			spin_lock(chip->mutex);
 			/* Nobody will touch it while it's in state FL_ERASE_SUSPENDING.
 			   So we can just loop here. */
 		}
 		chip->state = FL_READY;
 		return 0;
 
+	case FL_XIP_WHILE_ERASING:
+		if (mode != FL_READY && mode != FL_POINT &&
+		    (!cfip || !(cfip->EraseSuspend&2)))
+			goto sleep;
+		chip->oldstate = chip->state;
+		chip->state = FL_READY;
+		return 0;
+
 	case FL_POINT:
 		/* Only if there's no operation suspended... */
 		if (mode == FL_READY && chip->oldstate == FL_READY)
@@ -491,10 +532,10 @@ static int get_chip(struct map_info *map
 	sleep:
 		set_current_state(TASK_UNINTERRUPTIBLE);
 		add_wait_queue(&chip->wq, &wait);
-		cfi_spin_unlock(chip->mutex);
+		spin_unlock(chip->mutex);
 		schedule();
 		remove_wait_queue(&chip->wq, &wait);
-		cfi_spin_lock(chip->mutex);
+		spin_lock(chip->mutex);
 		goto resettime;
 	}
 }
@@ -512,6 +553,11 @@ static void put_chip(struct map_info *ma
 		chip->state = FL_ERASING;
 		break;
 
+	case FL_XIP_WHILE_ERASING:
+		chip->state = chip->oldstate;
+		chip->oldstate = FL_READY;
+		break;
+
 	case FL_READY:
 	case FL_STATUS:
 		/* We should really make set_vpp() count, rather than doing this */
@@ -523,6 +569,198 @@ static void put_chip(struct map_info *ma
 	wake_up(&chip->wq);
 }
 
+#ifdef CONFIG_MTD_XIP
+
+/*
+ * No interrupt what so ever can be serviced while the flash isn't in array
+ * mode.  This is ensured by the xip_disable() and xip_enable() functions
+ * enclosing any code path where the flash is known not to be in array mode.
+ * And within a XIP disabled code path, only functions marked with __xipram
+ * may be called and nothing else (it's a good thing to inspect generated
+ * assembly to make sure inline functions were actually inlined and that gcc
+ * didn't emit calls to its own support functions). Also configuring MTD CFI
+ * support to a single buswidth and a single interleave is also recommended.
+ */
+
+static void xip_disable(struct map_info *map, struct flchip *chip,
+			unsigned long adr)
+{
+	/* TODO: chips with no XIP use should ignore and return */
+	(void) map_read(map, adr); /* ensure mmu mapping is up to date */
+	local_irq_disable();
+}
+
+static void __xipram xip_enable(struct map_info *map, struct flchip *chip,
+				unsigned long adr)
+{
+	struct cfi_private *cfi = map->fldrv_priv;
+
+	if (chip->state != FL_POINT && chip->state != FL_READY) {
+		map_write(map, CMD(0xf0), adr);
+		chip->state = FL_READY;
+	}
+	(void) map_read(map, adr);
+	xip_iprefetch();
+	local_irq_enable();
+}
+
+/*
+ * When a delay is required for the flash operation to complete, the
+ * xip_udelay() function is polling for both the given timeout and pending
+ * (but still masked) hardware interrupts.  Whenever there is an interrupt
+ * pending then the flash erase operation is suspended, array mode restored 
+ * and interrupts unmasked.  Task scheduling might also happen at that
+ * point.  The CPU eventually returns from the interrupt or the call to
+ * schedule() and the suspended flash operation is resumed for the remaining
+ * of the delay period.
+ *
+ * Warning: this function _will_ fool interrupt latency tracing tools.
+ */
+
+static void __xipram xip_udelay(struct map_info *map, struct flchip *chip,
+				unsigned long adr, int usec)
+{
+	struct cfi_private *cfi = map->fldrv_priv;
+	struct cfi_pri_amdstd *extp = cfi->cmdset_priv;
+	map_word status, OK = CMD(0x80);
+	unsigned long suspended, start = xip_currtime();
+	flstate_t oldstate;
+
+	do {
+		cpu_relax();
+		if (xip_irqpending() && extp &&
+		    ((chip->state == FL_ERASING && (extp->EraseSuspend & 2))) &&
+		    (cfi_interleave_is_1(cfi) || chip->oldstate == FL_READY)) {
+			/*
+			 * Let's suspend the erase operation when supported.  
+			 * Note that we currently don't try to suspend 
+			 * interleaved chips if there is already another 
+			 * operation suspended (imagine what happens
+			 * when one chip was already done with the current
+			 * operation while another chip suspended it, then
+			 * we resume the whole thing at once).  Yes, it
+			 * can happen!
+			 */
+			map_write(map, CMD(0xb0), adr);
+			usec -= xip_elapsed_since(start);
+			suspended = xip_currtime();
+			do {
+				if (xip_elapsed_since(suspended) > 100000) {
+					/*
+					 * The chip doesn't want to suspend
+					 * after waiting for 100 msecs.
+					 * This is a critical error but there
+					 * is not much we can do here.
+					 */
+					return;
+				}
+				status = map_read(map, adr);
+			} while (!map_word_andequal(map, status, OK, OK));
+
+			/* Suspend succeeded */
+			oldstate = chip->state;
+			if (!map_word_bitsset(map, status, CMD(0x40)))
+				break;
+			chip->state = FL_XIP_WHILE_ERASING;
+			chip->erase_suspended = 1;
+			map_write(map, CMD(0xf0), adr);
+			(void) map_read(map, adr);
+			asm volatile (".rep 8; nop; .endr");
+			local_irq_enable();
+			spin_unlock(chip->mutex);
+			asm volatile (".rep 8; nop; .endr");
+			cond_resched();
+
+			/*
+			 * We're back.  However someone else might have
+			 * decided to go write to the chip if we are in
+			 * a suspended erase state.  If so let's wait
+			 * until it's done.
+			 */
+			spin_lock(chip->mutex);
+			while (chip->state != FL_XIP_WHILE_ERASING) {
+				DECLARE_WAITQUEUE(wait, current);
+				set_current_state(TASK_UNINTERRUPTIBLE);
+				add_wait_queue(&chip->wq, &wait);
+				spin_unlock(chip->mutex);
+				schedule();
+				remove_wait_queue(&chip->wq, &wait);
+				spin_lock(chip->mutex);
+			}
+			/* Disallow XIP again */
+			local_irq_disable();
+
+			/* Resume the write or erase operation */
+			map_write(map, CMD(0x30), adr);
+			chip->state = oldstate;
+			start = xip_currtime();
+		} else if (usec >= 1000000/HZ) {
+			/*
+			 * Try to save on CPU power when waiting delay
+			 * is at least a system timer tick period.
+			 * No need to be extremely accurate here.
+			 */
+			xip_cpu_idle();
+		}
+		status = map_read(map, adr);
+	} while (!map_word_andequal(map, status, OK, OK)
+		 && xip_elapsed_since(start) < usec);
+}
+
+#define UDELAY(map, chip, adr, usec)  xip_udelay(map, chip, adr, usec)
+
+/*
+ * The INVALIDATE_CACHED_RANGE() macro is normally used in parallel while
+ * the flash is actively programming or erasing since we have to poll for
+ * the operation to complete anyway.  We can't do that in a generic way with
+ * a XIP setup so do it before the actual flash operation in this case
+ * and stub it out from INVALIDATE_CACHE_UDELAY.
+ */
+#define XIP_INVAL_CACHED_RANGE(map, from, size)  \
+	INVALIDATE_CACHED_RANGE(map, from, size)
+
+#define INVALIDATE_CACHE_UDELAY(map, chip, adr, len, usec)  \
+	UDELAY(map, chip, adr, usec)
+
+/*
+ * Extra notes:
+ *
+ * Activating this XIP support changes the way the code works a bit.  For
+ * example the code to suspend the current process when concurrent access
+ * happens is never executed because xip_udelay() will always return with the
+ * same chip state as it was entered with.  This is why there is no care for
+ * the presence of add_wait_queue() or schedule() calls from within a couple
+ * xip_disable()'d  areas of code, like in do_erase_oneblock for example.
+ * The queueing and scheduling are always happening within xip_udelay().
+ *
+ * Similarly, get_chip() and put_chip() just happen to always be executed
+ * with chip->state set to FL_READY (or FL_XIP_WHILE_*) where flash state
+ * is in array mode, therefore never executing many cases therein and not
+ * causing any problem with XIP.
+ */
+
+#else
+
+#define xip_disable(map, chip, adr)
+#define xip_enable(map, chip, adr)
+#define XIP_INVAL_CACHED_RANGE(x...)
+
+#define UDELAY(map, chip, adr, usec)  \
+do {  \
+	spin_unlock(chip->mutex);  \
+	cfi_udelay(usec);  \
+	spin_lock(chip->mutex);  \
+} while (0)
+
+#define INVALIDATE_CACHE_UDELAY(map, chip, adr, len, usec)  \
+do {  \
+	spin_unlock(chip->mutex);  \
+	INVALIDATE_CACHED_RANGE(map, adr, len);  \
+	cfi_udelay(usec);  \
+	spin_lock(chip->mutex);  \
+} while (0)
+
+#endif
 
 static inline int do_read_onechip(struct map_info *map, struct flchip *chip, loff_t adr, size_t len, u_char *buf)
 {
@@ -535,10 +773,10 @@ static inline int do_read_onechip(struct
 	/* Ensure cmd read/writes are aligned. */ 
 	cmd_addr = adr & ~(map_bankwidth(map)-1); 
 
-	cfi_spin_lock(chip->mutex);
+	spin_lock(chip->mutex);
 	ret = get_chip(map, chip, cmd_addr, FL_READY);
 	if (ret) {
-		cfi_spin_unlock(chip->mutex);
+		spin_unlock(chip->mutex);
 		return ret;
 	}
 
@@ -551,7 +789,7 @@ static inline int do_read_onechip(struct
 
 	put_chip(map, chip, cmd_addr);
 
-	cfi_spin_unlock(chip->mutex);
+	spin_unlock(chip->mutex);
 	return 0;
 }
 
@@ -605,7 +843,7 @@ static inline int do_read_secsi_onechip(
 	struct cfi_private *cfi = map->fldrv_priv;
 
  retry:
-	cfi_spin_lock(chip->mutex);
+	spin_lock(chip->mutex);
 
 	if (chip->state != FL_READY){
 #if 0
@@ -614,7 +852,7 @@ static inline int do_read_secsi_onechip(
 		set_current_state(TASK_UNINTERRUPTIBLE);
 		add_wait_queue(&chip->wq, &wait);
 		
-		cfi_spin_unlock(chip->mutex);
+		spin_unlock(chip->mutex);
 
 		schedule();
 		remove_wait_queue(&chip->wq, &wait);
@@ -643,7 +881,7 @@ static inline int do_read_secsi_onechip(
 	cfi_send_gen_cmd(0x00, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
 	
 	wake_up(&chip->wq);
-	cfi_spin_unlock(chip->mutex);
+	spin_unlock(chip->mutex);
 
 	return 0;
 }
@@ -692,7 +930,7 @@ static int cfi_amdstd_secsi_read (struct
 }
 
 
-static int do_write_oneword(struct map_info *map, struct flchip *chip, unsigned long adr, map_word datum)
+static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip, unsigned long adr, map_word datum)
 {
 	struct cfi_private *cfi = map->fldrv_priv;
 	unsigned long timeo = jiffies + HZ;
@@ -712,10 +950,10 @@ static int do_write_oneword(struct map_i
 
 	adr += chip->start;
 
-	cfi_spin_lock(chip->mutex);
+	spin_lock(chip->mutex);
 	ret = get_chip(map, chip, adr, FL_WRITING);
 	if (ret) {
-		cfi_spin_unlock(chip->mutex);
+		spin_unlock(chip->mutex);
 		return ret;
 	}
 
@@ -735,7 +973,9 @@ static int do_write_oneword(struct map_i
 		goto op_done;
 	}
 
+	XIP_INVAL_CACHED_RANGE(map, adr, map_bankwidth(map));
 	ENABLE_VPP(map);
+	xip_disable(map, chip, adr);
  retry:
 	cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
 	cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL);
@@ -743,9 +983,9 @@ static int do_write_oneword(struct map_i
 	map_write(map, datum, adr);
 	chip->state = FL_WRITING;
 
-	cfi_spin_unlock(chip->mutex);
-	cfi_udelay(chip->word_write_time);
-	cfi_spin_lock(chip->mutex);
+	INVALIDATE_CACHE_UDELAY(map, chip,
+				adr, map_bankwidth(map),
+				chip->word_write_time);
 
 	/* See comment above for timeout value. */
 	timeo = jiffies + uWriteTimeout; 
@@ -756,39 +996,43 @@ static int do_write_oneword(struct map_i
 
 			set_current_state(TASK_UNINTERRUPTIBLE);
 			add_wait_queue(&chip->wq, &wait);
-			cfi_spin_unlock(chip->mutex);
+			spin_unlock(chip->mutex);
 			schedule();
 			remove_wait_queue(&chip->wq, &wait);
 			timeo = jiffies + (HZ / 2); /* FIXME */
-			cfi_spin_lock(chip->mutex);
+			spin_lock(chip->mutex);
 			continue;
 		}
 
 		if (chip_ready(map, adr))
-			goto op_done;
+			break;
 
-		if (time_after(jiffies, timeo))
+		if (time_after(jiffies, timeo)) {
+			xip_enable(map, chip, adr);
+			printk(KERN_WARNING "MTD %s(): software timeout\n", __func__);
+			xip_disable(map, chip, adr);
                         break;
+		}
 
 		/* Latency issues. Drop the lock, wait a while and retry */
-		cfi_spin_unlock(chip->mutex);
-		cfi_udelay(1);
-		cfi_spin_lock(chip->mutex);
+		UDELAY(map, chip, adr, 1);
 	}
+	/* Did we succeed? */
+	if (!chip_good(map, adr, datum)) {
+		/* reset on all failures. */
+		map_write( map, CMD(0xF0), chip->start );
+		/* FIXME - should have reset delay before continuing */
 
-	printk(KERN_WARNING "MTD %s(): software timeout\n", __func__);
-
-	/* reset on all failures. */
-	map_write( map, CMD(0xF0), chip->start );
-	/* FIXME - should have reset delay before continuing */
-	if (++retry_cnt <= MAX_WORD_RETRIES) 
-		goto retry;
+		if (++retry_cnt <= MAX_WORD_RETRIES) 
+			goto retry;
 
-	ret = -EIO;
+		ret = -EIO;
+	}
+	xip_enable(map, chip, adr);
  op_done:
 	chip->state = FL_READY;
 	put_chip(map, chip, adr);
-	cfi_spin_unlock(chip->mutex);
+	spin_unlock(chip->mutex);
 
 	return ret;
 }
@@ -820,7 +1064,7 @@ static int cfi_amdstd_write_words(struct
 		map_word tmp_buf;
 
  retry:
-		cfi_spin_lock(cfi->chips[chipnum].mutex);
+		spin_lock(cfi->chips[chipnum].mutex);
 
 		if (cfi->chips[chipnum].state != FL_READY) {
 #if 0
@@ -829,7 +1073,7 @@ static int cfi_amdstd_write_words(struct
 			set_current_state(TASK_UNINTERRUPTIBLE);
 			add_wait_queue(&cfi->chips[chipnum].wq, &wait);
 
-			cfi_spin_unlock(cfi->chips[chipnum].mutex);
+			spin_unlock(cfi->chips[chipnum].mutex);
 
 			schedule();
 			remove_wait_queue(&cfi->chips[chipnum].wq, &wait);
@@ -843,7 +1087,7 @@ static int cfi_amdstd_write_words(struct
 		/* Load 'tmp_buf' with old contents of flash */
 		tmp_buf = map_read(map, bus_ofs+chipstart);
 
-		cfi_spin_unlock(cfi->chips[chipnum].mutex);
+		spin_unlock(cfi->chips[chipnum].mutex);
 
 		/* Number of bytes to copy from buffer */
 		n = min_t(int, len, map_bankwidth(map)-i);
@@ -898,7 +1142,7 @@ static int cfi_amdstd_write_words(struct
 		map_word tmp_buf;
 
  retry1:
-		cfi_spin_lock(cfi->chips[chipnum].mutex);
+		spin_lock(cfi->chips[chipnum].mutex);
 
 		if (cfi->chips[chipnum].state != FL_READY) {
 #if 0
@@ -907,7 +1151,7 @@ static int cfi_amdstd_write_words(struct
 			set_current_state(TASK_UNINTERRUPTIBLE);
 			add_wait_queue(&cfi->chips[chipnum].wq, &wait);
 
-			cfi_spin_unlock(cfi->chips[chipnum].mutex);
+			spin_unlock(cfi->chips[chipnum].mutex);
 
 			schedule();
 			remove_wait_queue(&cfi->chips[chipnum].wq, &wait);
@@ -920,7 +1164,7 @@ static int cfi_amdstd_write_words(struct
 
 		tmp_buf = map_read(map, ofs + chipstart);
 
-		cfi_spin_unlock(cfi->chips[chipnum].mutex);
+		spin_unlock(cfi->chips[chipnum].mutex);
 
 		tmp_buf = map_word_load_partial(map, tmp_buf, buf, 0, len);
 	
@@ -939,8 +1183,9 @@ static int cfi_amdstd_write_words(struct
 /*
  * FIXME: interleaved mode not tested, and probably not supported!
  */
-static inline int do_write_buffer(struct map_info *map, struct flchip *chip, 
-				  unsigned long adr, const u_char *buf, int len)
+static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
+				    unsigned long adr, const u_char *buf, 
+				    int len)
 {
 	struct cfi_private *cfi = map->fldrv_priv;
 	unsigned long timeo = jiffies + HZ;
@@ -954,10 +1199,10 @@ static inline int do_write_buffer(struct
 	adr += chip->start;
 	cmd_adr = adr;
 
-	cfi_spin_lock(chip->mutex);
+	spin_lock(chip->mutex);
 	ret = get_chip(map, chip, adr, FL_WRITING);
 	if (ret) {
-		cfi_spin_unlock(chip->mutex);
+		spin_unlock(chip->mutex);
 		return ret;
 	}
 
@@ -966,7 +1211,10 @@ static inline int do_write_buffer(struct
 	DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): WRITE 0x%.8lx(0x%.8lx)\n",
 	       __func__, adr, datum.x[0] );
 
+	XIP_INVAL_CACHED_RANGE(map, adr, len);
 	ENABLE_VPP(map);
+	xip_disable(map, chip, cmd_adr);
+	
 	cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
 	cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL);
 	//cfi_send_gen_cmd(0xA0, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
@@ -996,9 +1244,9 @@ static inline int do_write_buffer(struct
 	map_write(map, CMD(0x29), cmd_adr);
 	chip->state = FL_WRITING;
 
-	cfi_spin_unlock(chip->mutex);
-	cfi_udelay(chip->buffer_write_time);
-	cfi_spin_lock(chip->mutex);
+	INVALIDATE_CACHE_UDELAY(map, chip,
+				adr, map_bankwidth(map),
+				chip->word_write_time);
 
 	timeo = jiffies + uWriteTimeout; 
 		
@@ -1009,38 +1257,39 @@ static inline int do_write_buffer(struct
 
 			set_current_state(TASK_UNINTERRUPTIBLE);
 			add_wait_queue(&chip->wq, &wait);
-			cfi_spin_unlock(chip->mutex);
+			spin_unlock(chip->mutex);
 			schedule();
 			remove_wait_queue(&chip->wq, &wait);
 			timeo = jiffies + (HZ / 2); /* FIXME */
-			cfi_spin_lock(chip->mutex);
+			spin_lock(chip->mutex);
 			continue;
 		}
 
-		if (chip_ready(map, adr))
+		if (chip_ready(map, adr)) {
+			xip_enable(map, chip, adr);
 			goto op_done;
+		}
 		    
 		if( time_after(jiffies, timeo))
 			break;
 
 		/* Latency issues. Drop the lock, wait a while and retry */
-		cfi_spin_unlock(chip->mutex);
-		cfi_udelay(1);
-		cfi_spin_lock(chip->mutex);
+		UDELAY(map, chip, adr, 1);
 	}
 
-	printk(KERN_WARNING "MTD %s(): software timeout\n",
-	       __func__ );
-
 	/* reset on all failures. */
 	map_write( map, CMD(0xF0), chip->start );
+	xip_enable(map, chip, adr);
 	/* FIXME - should have reset delay before continuing */
 
+	printk(KERN_WARNING "MTD %s(): software timeout\n",
+	       __func__ );
+
 	ret = -EIO;
  op_done:
 	chip->state = FL_READY;
 	put_chip(map, chip, adr);
-	cfi_spin_unlock(chip->mutex);
+	spin_unlock(chip->mutex);
 
 	return ret;
 }
@@ -1130,7 +1379,7 @@ static int cfi_amdstd_write_buffers(stru
  * Handle devices with one erase region, that only implement
  * the chip erase command.
  */
-static inline int do_erase_chip(struct map_info *map, struct flchip *chip)
+static int __xipram do_erase_chip(struct map_info *map, struct flchip *chip)
 {
 	struct cfi_private *cfi = map->fldrv_priv;
 	unsigned long timeo = jiffies + HZ;
@@ -1140,17 +1389,20 @@ static inline int do_erase_chip(struct m
 
 	adr = cfi->addr_unlock1;
 
-	cfi_spin_lock(chip->mutex);
+	spin_lock(chip->mutex);
 	ret = get_chip(map, chip, adr, FL_WRITING);
 	if (ret) {
-		cfi_spin_unlock(chip->mutex);
+		spin_unlock(chip->mutex);
 		return ret;
 	}
 
 	DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): ERASE 0x%.8lx\n",
 	       __func__, chip->start );
 
+	XIP_INVAL_CACHED_RANGE(map, adr, map->size);
 	ENABLE_VPP(map);
+	xip_disable(map, chip, adr);
+
 	cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
 	cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL);
 	cfi_send_gen_cmd(0x80, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
@@ -1162,9 +1414,9 @@ static inline int do_erase_chip(struct m
 	chip->erase_suspended = 0;
 	chip->in_progress_block_addr = adr;
 
-	cfi_spin_unlock(chip->mutex);
-	msleep(chip->erase_time/2);
-	cfi_spin_lock(chip->mutex);
+	INVALIDATE_CACHE_UDELAY(map, chip,
+				adr, map->size,
+				chip->erase_time*500);
 
 	timeo = jiffies + (HZ*20);
 
@@ -1173,10 +1425,10 @@ static inline int do_erase_chip(struct m
 			/* Someone's suspended the erase. Sleep */
 			set_current_state(TASK_UNINTERRUPTIBLE);
 			add_wait_queue(&chip->wq, &wait);
-			cfi_spin_unlock(chip->mutex);
+			spin_unlock(chip->mutex);
 			schedule();
 			remove_wait_queue(&chip->wq, &wait);
-			cfi_spin_lock(chip->mutex);
+			spin_lock(chip->mutex);
 			continue;
 		}
 		if (chip->erase_suspended) {
@@ -1187,36 +1439,36 @@ static inline int do_erase_chip(struct m
 		}
 
 		if (chip_ready(map, adr))
-			goto op_done;
+			break;
 
-		if (time_after(jiffies, timeo))
+		if (time_after(jiffies, timeo)) {
+			printk(KERN_WARNING "MTD %s(): software timeout\n",
+				__func__ );
 			break;
+		}
 
 		/* Latency issues. Drop the lock, wait a while and retry */
-		cfi_spin_unlock(chip->mutex);
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(1);
-		cfi_spin_lock(chip->mutex);
+		UDELAY(map, chip, adr, 1000000/HZ);
 	}
+	/* Did we succeed? */
+	if (!chip_good(map, adr, map_word_ff(map))) {
+		/* reset on all failures. */
+		map_write( map, CMD(0xF0), chip->start );
+		/* FIXME - should have reset delay before continuing */
 
-	printk(KERN_WARNING "MTD %s(): software timeout\n",
-	       __func__ );
-
-	/* reset on all failures. */
-	map_write( map, CMD(0xF0), chip->start );
-	/* FIXME - should have reset delay before continuing */
+		ret = -EIO;
+	}
 
-	ret = -EIO;
- op_done:
 	chip->state = FL_READY;
+	xip_enable(map, chip, adr);
 	put_chip(map, chip, adr);
-	cfi_spin_unlock(chip->mutex);
+	spin_unlock(chip->mutex);
 
 	return ret;
 }
 
 
-static inline int do_erase_oneblock(struct map_info *map, struct flchip *chip, unsigned long adr, int len, void *thunk)
+static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip, unsigned long adr, int len, void *thunk)
 {
 	struct cfi_private *cfi = map->fldrv_priv;
 	unsigned long timeo = jiffies + HZ;
@@ -1225,17 +1477,20 @@ static inline int do_erase_oneblock(stru
 
 	adr += chip->start;
 
-	cfi_spin_lock(chip->mutex);
+	spin_lock(chip->mutex);
 	ret = get_chip(map, chip, adr, FL_ERASING);
 	if (ret) {
-		cfi_spin_unlock(chip->mutex);
+		spin_unlock(chip->mutex);
 		return ret;
 	}
 
 	DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): ERASE 0x%.8lx\n",
 	       __func__, adr );
 
+	XIP_INVAL_CACHED_RANGE(map, adr, len);
 	ENABLE_VPP(map);
+	xip_disable(map, chip, adr);
+
 	cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
 	cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL);
 	cfi_send_gen_cmd(0x80, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
@@ -1246,10 +1501,10 @@ static inline int do_erase_oneblock(stru
 	chip->state = FL_ERASING;
 	chip->erase_suspended = 0;
 	chip->in_progress_block_addr = adr;
-	
-	cfi_spin_unlock(chip->mutex);
-	msleep(chip->erase_time/2);
-	cfi_spin_lock(chip->mutex);
+
+	INVALIDATE_CACHE_UDELAY(map, chip,
+				adr, len,
+				chip->erase_time*500);
 
 	timeo = jiffies + (HZ*20);
 
@@ -1258,10 +1513,10 @@ static inline int do_erase_oneblock(stru
 			/* Someone's suspended the erase. Sleep */
 			set_current_state(TASK_UNINTERRUPTIBLE);
 			add_wait_queue(&chip->wq, &wait);
-			cfi_spin_unlock(chip->mutex);
+			spin_unlock(chip->mutex);
 			schedule();
 			remove_wait_queue(&chip->wq, &wait);
-			cfi_spin_lock(chip->mutex);
+			spin_lock(chip->mutex);
 			continue;
 		}
 		if (chip->erase_suspended) {
@@ -1271,31 +1526,33 @@ static inline int do_erase_oneblock(stru
 			chip->erase_suspended = 0;
 		}
 
-		if (chip_ready(map, adr))
-			goto op_done;
+		if (chip_ready(map, adr)) {
+			xip_enable(map, chip, adr);
+			break;
+		}
 
-		if (time_after(jiffies, timeo))
+		if (time_after(jiffies, timeo)) {
+			xip_enable(map, chip, adr);
+			printk(KERN_WARNING "MTD %s(): software timeout\n",
+				__func__ );
 			break;
+		}
 
 		/* Latency issues. Drop the lock, wait a while and retry */
-		cfi_spin_unlock(chip->mutex);
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(1);
-		cfi_spin_lock(chip->mutex);
+		UDELAY(map, chip, adr, 1000000/HZ);
+	}
+	/* Did we succeed? */
+	if (!chip_good(map, adr, map_word_ff(map))) {
+		/* reset on all failures. */
+		map_write( map, CMD(0xF0), chip->start );
+		/* FIXME - should have reset delay before continuing */
+
+		ret = -EIO;
 	}
-	
-	printk(KERN_WARNING "MTD %s(): software timeout\n",
-	       __func__ );
-	
-	/* reset on all failures. */
-	map_write( map, CMD(0xF0), chip->start );
-	/* FIXME - should have reset delay before continuing */
 
-	ret = -EIO;
- op_done:
 	chip->state = FL_READY;
 	put_chip(map, chip, adr);
-	cfi_spin_unlock(chip->mutex);
+	spin_unlock(chip->mutex);
 	return ret;
 }
 
@@ -1355,7 +1612,7 @@ static void cfi_amdstd_sync (struct mtd_
 		chip = &cfi->chips[i];
 
 	retry:
-		cfi_spin_lock(chip->mutex);
+		spin_lock(chip->mutex);
 
 		switch(chip->state) {
 		case FL_READY:
@@ -1369,14 +1626,14 @@ static void cfi_amdstd_sync (struct mtd_
 			 * with the chip now anyway.
 			 */
 		case FL_SYNCING:
-			cfi_spin_unlock(chip->mutex);
+			spin_unlock(chip->mutex);
 			break;
 
 		default:
 			/* Not an idle state */
 			add_wait_queue(&chip->wq, &wait);
 			
-			cfi_spin_unlock(chip->mutex);
+			spin_unlock(chip->mutex);
 
 			schedule();
 
@@ -1391,13 +1648,13 @@ static void cfi_amdstd_sync (struct mtd_
 	for (i--; i >=0; i--) {
 		chip = &cfi->chips[i];
 
-		cfi_spin_lock(chip->mutex);
+		spin_lock(chip->mutex);
 		
 		if (chip->state == FL_SYNCING) {
 			chip->state = chip->oldstate;
 			wake_up(&chip->wq);
 		}
-		cfi_spin_unlock(chip->mutex);
+		spin_unlock(chip->mutex);
 	}
 }
 
@@ -1413,7 +1670,7 @@ static int cfi_amdstd_suspend(struct mtd
 	for (i=0; !ret && i<cfi->numchips; i++) {
 		chip = &cfi->chips[i];
 
-		cfi_spin_lock(chip->mutex);
+		spin_lock(chip->mutex);
 
 		switch(chip->state) {
 		case FL_READY:
@@ -1433,7 +1690,7 @@ static int cfi_amdstd_suspend(struct mtd
 			ret = -EAGAIN;
 			break;
 		}
-		cfi_spin_unlock(chip->mutex);
+		spin_unlock(chip->mutex);
 	}
 
 	/* Unlock the chips again */
@@ -1442,13 +1699,13 @@ static int cfi_amdstd_suspend(struct mtd
 		for (i--; i >=0; i--) {
 			chip = &cfi->chips[i];
 
-			cfi_spin_lock(chip->mutex);
+			spin_lock(chip->mutex);
 		
 			if (chip->state == FL_PM_SUSPENDED) {
 				chip->state = chip->oldstate;
 				wake_up(&chip->wq);
 			}
-			cfi_spin_unlock(chip->mutex);
+			spin_unlock(chip->mutex);
 		}
 	}
 	
@@ -1467,7 +1724,7 @@ static void cfi_amdstd_resume(struct mtd
 	
 		chip = &cfi->chips[i];
 
-		cfi_spin_lock(chip->mutex);
+		spin_lock(chip->mutex);
 		
 		if (chip->state == FL_PM_SUSPENDED) {
 			chip->state = FL_READY;
@@ -1477,7 +1734,7 @@ static void cfi_amdstd_resume(struct mtd
 		else
 			printk(KERN_ERR "Argh. Chip not in PM_SUSPENDED state upon resume()\n");
 
-		cfi_spin_unlock(chip->mutex);
+		spin_unlock(chip->mutex);
 	}
 }
 
diff --git a/drivers/mtd/chips/cfi_cmdset_0020.c b/drivers/mtd/chips/cfi_cmdset_0020.c
--- a/drivers/mtd/chips/cfi_cmdset_0020.c
+++ b/drivers/mtd/chips/cfi_cmdset_0020.c
@@ -4,7 +4,7 @@
  *
  * (C) 2000 Red Hat. GPL'd
  *
- * $Id: cfi_cmdset_0020.c,v 1.17 2004/11/20 12:49:04 dwmw2 Exp $
+ * $Id: cfi_cmdset_0020.c,v 1.19 2005/07/13 15:52:45 dwmw2 Exp $
  * 
  * 10/10/2000	Nicolas Pitre <nico@cam.org>
  * 	- completely revamped method functions so they are aware and
@@ -16,6 +16,8 @@
  *	- modified Intel Command Set 0x0001 to support ST Advanced Architecture
  *	  (command set 0x0020)
  *	- added a writev function
+ * 07/13/2005	Joern Engel <joern@wh.fh-wedel.de>
+ * 	- Plugged memory leak in cfi_staa_writev().
  */
 
 #include <linux/version.h>
@@ -719,6 +721,7 @@ cfi_staa_writev(struct mtd_info *mtd, co
 write_error:
 	if (retlen)
 		*retlen = totlen;
+	kfree(buffer);
 	return ret;
 }
 
diff --git a/drivers/mtd/chips/fwh_lock.h b/drivers/mtd/chips/fwh_lock.h
--- a/drivers/mtd/chips/fwh_lock.h
+++ b/drivers/mtd/chips/fwh_lock.h
@@ -58,10 +58,10 @@ static int fwh_xxlock_oneblock(struct ma
 	 * to flash memory - that means that we don't have to check status
 	 * and timeout.
 	 */
-	cfi_spin_lock(chip->mutex);
+	spin_lock(chip->mutex);
 	ret = get_chip(map, chip, adr, FL_LOCKING);
 	if (ret) {
-		cfi_spin_unlock(chip->mutex);
+		spin_unlock(chip->mutex);
 		return ret;
 	}
 
@@ -71,7 +71,7 @@ static int fwh_xxlock_oneblock(struct ma
 	/* Done and happy. */
 	chip->state = FL_READY;
 	put_chip(map, chip, adr);
-	cfi_spin_unlock(chip->mutex);
+	spin_unlock(chip->mutex);
 	return 0;
 }
 
diff --git a/drivers/mtd/chips/gen_probe.c b/drivers/mtd/chips/gen_probe.c
--- a/drivers/mtd/chips/gen_probe.c
+++ b/drivers/mtd/chips/gen_probe.c
@@ -2,7 +2,7 @@
  * Routines common to all CFI-type probes.
  * (C) 2001-2003 Red Hat, Inc.
  * GPL'd
- * $Id: gen_probe.c,v 1.21 2004/08/14 15:14:05 dwmw2 Exp $
+ * $Id: gen_probe.c,v 1.22 2005/01/24 23:49:50 rmk Exp $
  */
 
 #include <linux/kernel.h>
@@ -162,7 +162,7 @@ static int genprobe_new_chip(struct map_
 	int max_chips = map_bankwidth(map); /* And minimum 1 */
 	int nr_chips, type;
 
-	for (nr_chips = min_chips; nr_chips <= max_chips; nr_chips <<= 1) {
+	for (nr_chips = max_chips; nr_chips >= min_chips; nr_chips >>= 1) {
 
 		if (!cfi_interleave_supported(nr_chips))
 		    continue;
diff --git a/drivers/mtd/chips/jedec_probe.c b/drivers/mtd/chips/jedec_probe.c
--- a/drivers/mtd/chips/jedec_probe.c
+++ b/drivers/mtd/chips/jedec_probe.c
@@ -1,7 +1,7 @@
 /* 
    Common Flash Interface probe code.
    (C) 2000 Red Hat. GPL'd.
-   $Id: jedec_probe.c,v 1.61 2004/11/19 20:52:16 thayne Exp $
+   $Id: jedec_probe.c,v 1.63 2005/02/14 16:30:32 bjd Exp $
    See JEDEC (http://www.jedec.org/) standard JESD21C (section 3.5)
    for the standard this probe goes back to.
 
@@ -142,6 +142,7 @@
 #define SST29LE512	0x003d
 #define SST39LF800	0x2781
 #define SST39LF160	0x2782
+#define SST39VF1601	0x234b
 #define SST39LF512	0x00D4
 #define SST39LF010	0x00D5
 #define SST39LF020	0x00D6
@@ -1448,6 +1449,21 @@ static const struct amd_flash_info jedec
                        ERASEINFO(0x1000,256),
                        ERASEINFO(0x1000,256)
                }
+	}, {
+               .mfr_id         = MANUFACTURER_SST,     /* should be CFI */
+               .dev_id         = SST39VF1601,
+               .name           = "SST 39VF1601",
+               .uaddr          = {
+                       [0] = MTD_UADDR_0x5555_0x2AAA,  /* x8 */
+                       [1] = MTD_UADDR_0x5555_0x2AAA   /* x16 */
+               },
+               .DevSize        = SIZE_2MiB,
+               .CmdSet         = P_ID_AMD_STD,
+               .NumEraseRegions= 2,
+               .regions        = {
+                       ERASEINFO(0x1000,256),
+                       ERASEINFO(0x1000,256)
+               }
 
        }, {
 		.mfr_id		= MANUFACTURER_ST,	/* FIXME - CFI device? */
@@ -1856,6 +1872,16 @@ static inline int jedec_match( __u32 bas
 	case CFI_DEVICETYPE_X8:
 		mfr = (__u8)finfo->mfr_id;
 		id = (__u8)finfo->dev_id;
+
+		/* bjd: it seems that if we do this, we can end up
+		 * detecting 16bit flashes as an 8bit device, even though
+		 * there aren't.
+		 */
+		if (finfo->dev_id > 0xff) {
+			DEBUG( MTD_DEBUG_LEVEL3, "%s(): ID is not 8bit\n",
+			       __func__);
+			goto match_done;
+		}
 		break;
 	case CFI_DEVICETYPE_X16:
 		mfr = (__u16)finfo->mfr_id;
diff --git a/drivers/mtd/cmdlinepart.c b/drivers/mtd/cmdlinepart.c
--- a/drivers/mtd/cmdlinepart.c
+++ b/drivers/mtd/cmdlinepart.c
@@ -1,5 +1,5 @@
 /*
- * $Id: cmdlinepart.c,v 1.17 2004/11/26 11:18:47 lavinen Exp $
+ * $Id: cmdlinepart.c,v 1.18 2005/06/07 15:04:26 joern Exp $
  *
  * Read flash partition table from command line
  *
@@ -239,7 +239,8 @@ static int mtdpart_setup_real(char *s)
 				&num_parts,	/* out: number of parts */
 				0,		/* first partition */
 				(unsigned char**)&this_mtd, /* out: extra mem */
-				mtd_id_len + 1 + sizeof(*this_mtd));
+				mtd_id_len + 1 + sizeof(*this_mtd) + 
+				sizeof(void*)-1 /*alignment*/);
 		if(!parts)
 		{
 			/*
@@ -252,6 +253,9 @@ static int mtdpart_setup_real(char *s)
 			 return 0;
 		 }
 
+		/* align this_mtd */
+		this_mtd = (struct cmdline_mtd_partition *) 
+			ALIGN((unsigned long)this_mtd, sizeof(void*));
 		/* enter results */	    
 		this_mtd->parts = parts;
 		this_mtd->num_parts = num_parts;
diff --git a/drivers/mtd/devices/block2mtd.c b/drivers/mtd/devices/block2mtd.c
--- a/drivers/mtd/devices/block2mtd.c
+++ b/drivers/mtd/devices/block2mtd.c
@@ -1,10 +1,9 @@
 /*
- * $Id: block2mtd.c,v 1.23 2005/01/05 17:05:46 dwmw2 Exp $
+ * $Id: block2mtd.c,v 1.28 2005/03/19 22:40:44 gleixner Exp $
  *
  * block2mtd.c - create an mtd from a block device
  *
  * Copyright (C) 2001,2002	Simon Evans <spse@secret.org.uk>
- * Copyright (C) 2004		Gareth Bult <Gareth@Encryptec.net>
  * Copyright (C) 2004,2005	Jörn Engel <joern@wh.fh-wedel.de>
  *
  * Licence: GPL
@@ -20,7 +19,7 @@
 #include <linux/mtd/mtd.h>
 #include <linux/buffer_head.h>
 
-#define VERSION "$Revision: 1.23 $"
+#define VERSION "$Revision: 1.28 $"
 
 
 #define ERROR(fmt, args...) printk(KERN_ERR "block2mtd: " fmt "\n" , ## args)
@@ -89,7 +88,6 @@ void cache_readahead(struct address_spac
 static struct page* page_readahead(struct address_space *mapping, int index)
 {
 	filler_t *filler = (filler_t*)mapping->a_ops->readpage;
-	//do_page_cache_readahead(mapping, index, XXX, 64);
 	cache_readahead(mapping, index);
 	return read_cache_page(mapping, index, filler, NULL);
 }
@@ -157,7 +155,7 @@ static int block2mtd_read(struct mtd_inf
 	struct block2mtd_dev *dev = mtd->priv;
 	struct page *page;
 	int index = from >> PAGE_SHIFT;
-	int offset = from & (PAGE_SHIFT-1);
+	int offset = from & (PAGE_SIZE-1);
 	int cpylen;
 
 	if (from > mtd->size)
@@ -370,16 +368,16 @@ static int ustrtoul(const char *cp, char
 }
 
 
-static int parse_num32(u32 *num32, const char *token)
+static int parse_num(size_t *num, const char *token)
 {
 	char *endp;
-	unsigned long n;
+	size_t n;
 
-	n = ustrtoul(token, &endp, 0);
+	n = (size_t) ustrtoul(token, &endp, 0);
 	if (*endp)
 		return -EINVAL;
 
-	*num32 = n;
+	*num = n;
 	return 0;
 }
 
@@ -422,7 +420,7 @@ static int block2mtd_setup(const char *v
 	char buf[80+12], *str=buf; /* 80 for device, 12 for erase size */
 	char *token[2];
 	char *name;
-	u32 erase_size = PAGE_SIZE;
+	size_t erase_size = PAGE_SIZE;
 	int i, ret;
 
 	if (strnlen(val, sizeof(buf)) >= sizeof(buf))
@@ -449,7 +447,7 @@ static int block2mtd_setup(const char *v
 		return 0;
 
 	if (token[1]) {
-		ret = parse_num32(&erase_size, token[1]);
+		ret = parse_num(&erase_size, token[1]);
 		if (ret)
 			parse_err("illegal erase size");
 	}
diff --git a/drivers/mtd/devices/docecc.c b/drivers/mtd/devices/docecc.c
--- a/drivers/mtd/devices/docecc.c
+++ b/drivers/mtd/devices/docecc.c
@@ -40,6 +40,7 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/doc2000.h>
 
+#define DEBUG 0
 /* need to undef it (from asm/termbits.h) */
 #undef B0
 
diff --git a/drivers/mtd/devices/ms02-nv.c b/drivers/mtd/devices/ms02-nv.c
--- a/drivers/mtd/devices/ms02-nv.c
+++ b/drivers/mtd/devices/ms02-nv.c
@@ -6,7 +6,7 @@
  *	as published by the Free Software Foundation; either version
  *	2 of the License, or (at your option) any later version.
  *
- *	$Id: ms02-nv.c,v 1.8 2005/01/05 18:05:12 dwmw2 Exp $
+ *	$Id: ms02-nv.c,v 1.10 2005/06/20 12:24:41 macro Exp $
  */
 
 #include <linux/init.h>
@@ -99,8 +99,8 @@ static inline uint ms02nv_probe_one(ulon
 	 * The firmware writes MS02NV_ID at MS02NV_MAGIC and also
 	 * a diagnostic status at MS02NV_DIAG.
 	 */
-	ms02nv_diagp = (ms02nv_uint *)(KSEG1ADDR(addr + MS02NV_DIAG));
-	ms02nv_magicp = (ms02nv_uint *)(KSEG1ADDR(addr + MS02NV_MAGIC));
+	ms02nv_diagp = (ms02nv_uint *)(CKSEG1ADDR(addr + MS02NV_DIAG));
+	ms02nv_magicp = (ms02nv_uint *)(CKSEG1ADDR(addr + MS02NV_MAGIC));
 	err = get_dbe(ms02nv_magic, ms02nv_magicp);
 	if (err)
 		return 0;
@@ -233,7 +233,7 @@ static int __init ms02nv_init_one(ulong 
 		goto err_out_csr_res;
 	}
 
-	printk(KERN_INFO "mtd%d: %s at 0x%08lx, size %uMiB.\n",
+	printk(KERN_INFO "mtd%d: %s at 0x%08lx, size %zuMiB.\n",
 		mtd->index, ms02nv_name, addr, size >> 20);
 
 	mp->next = root_ms02nv_mtd;
diff --git a/drivers/mtd/devices/mtdram.c b/drivers/mtd/devices/mtdram.c
--- a/drivers/mtd/devices/mtdram.c
+++ b/drivers/mtd/devices/mtdram.c
@@ -1,9 +1,10 @@
 /*
  * mtdram - a test mtd device
- * $Id: mtdram.c,v 1.35 2005/01/05 18:05:12 dwmw2 Exp $
+ * $Id: mtdram.c,v 1.37 2005/04/21 03:42:11 joern Exp $
  * Author: Alexander Larsson <alex@cendio.se>
  *
  * Copyright (c) 1999 Alexander Larsson <alex@cendio.se>
+ * Copyright (c) 2005 Joern Engel <joern@wh.fh-wedel.de>
  *
  * This code is GPL
  *
@@ -18,213 +19,140 @@
 #include <linux/mtd/compatmac.h>
 #include <linux/mtd/mtd.h>
 
-#ifndef CONFIG_MTDRAM_ABS_POS
-  #define CONFIG_MTDRAM_ABS_POS 0
-#endif
-
-#if CONFIG_MTDRAM_ABS_POS > 0
-  #include <asm/io.h>
-#endif
-
-#ifdef MODULE
 static unsigned long total_size = CONFIG_MTDRAM_TOTAL_SIZE;
 static unsigned long erase_size = CONFIG_MTDRAM_ERASE_SIZE;
-module_param(total_size,ulong,0);
-MODULE_PARM_DESC(total_size, "Total device size in KiB");
-module_param(erase_size,ulong,0);
-MODULE_PARM_DESC(erase_size, "Device erase block size in KiB");
 #define MTDRAM_TOTAL_SIZE (total_size * 1024)
 #define MTDRAM_ERASE_SIZE (erase_size * 1024)
-#else
-#define MTDRAM_TOTAL_SIZE (CONFIG_MTDRAM_TOTAL_SIZE * 1024)
-#define MTDRAM_ERASE_SIZE (CONFIG_MTDRAM_ERASE_SIZE * 1024)
-#endif
 
+#ifdef MODULE
+module_param(total_size, ulong, 0);
+MODULE_PARM_DESC(total_size, "Total device size in KiB");
+module_param(erase_size, ulong, 0);
+MODULE_PARM_DESC(erase_size, "Device erase block size in KiB");
+#endif
 
 // We could store these in the mtd structure, but we only support 1 device..
 static struct mtd_info *mtd_info;
 
-
-static int
-ram_erase(struct mtd_info *mtd, struct erase_info *instr)
+static int ram_erase(struct mtd_info *mtd, struct erase_info *instr)
 {
-  DEBUG(MTD_DEBUG_LEVEL2, "ram_erase(pos:%ld, len:%ld)\n", (long)instr->addr, (long)instr->len);
-  if (instr->addr + instr->len > mtd->size) {
-    DEBUG(MTD_DEBUG_LEVEL1, "ram_erase() out of bounds (%ld > %ld)\n", (long)(instr->addr + instr->len), (long)mtd->size);
-    return -EINVAL;
-  }
-	
-  memset((char *)mtd->priv + instr->addr, 0xff, instr->len);
-	
-  instr->state = MTD_ERASE_DONE;
-  mtd_erase_callback(instr);
+	if (instr->addr + instr->len > mtd->size)
+		return -EINVAL;
+
+	memset((char *)mtd->priv + instr->addr, 0xff, instr->len);
+
+	instr->state = MTD_ERASE_DONE;
+	mtd_erase_callback(instr);
 
-  return 0;
+	return 0;
 }
 
-static int ram_point (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char **mtdbuf)
+static int ram_point(struct mtd_info *mtd, loff_t from, size_t len,
+		size_t *retlen, u_char **mtdbuf)
 {
-  if (from + len > mtd->size)
-    return -EINVAL;
-	
-  *mtdbuf = mtd->priv + from;
-  *retlen = len;
-  return 0;
+	if (from + len > mtd->size)
+		return -EINVAL;
+
+	*mtdbuf = mtd->priv + from;
+	*retlen = len;
+	return 0;
 }
 
-static void ram_unpoint (struct mtd_info *mtd, u_char *addr, loff_t from,
-			 size_t len)
+static void ram_unpoint(struct mtd_info *mtd, u_char * addr, loff_t from,
+		size_t len)
 {
-  DEBUG(MTD_DEBUG_LEVEL2, "ram_unpoint\n");
 }
 
 static int ram_read(struct mtd_info *mtd, loff_t from, size_t len,
-	     size_t *retlen, u_char *buf)
+		size_t *retlen, u_char *buf)
 {
-  DEBUG(MTD_DEBUG_LEVEL2, "ram_read(pos:%ld, len:%ld)\n", (long)from, (long)len);
-  if (from + len > mtd->size) {
-    DEBUG(MTD_DEBUG_LEVEL1, "ram_read() out of bounds (%ld > %ld)\n", (long)(from + len), (long)mtd->size);
-    return -EINVAL;
-  }
+	if (from + len > mtd->size)
+		return -EINVAL;
 
-  memcpy(buf, mtd->priv + from, len);
+	memcpy(buf, mtd->priv + from, len);
 
-  *retlen=len;
-  return 0;
+	*retlen = len;
+	return 0;
 }
 
 static int ram_write(struct mtd_info *mtd, loff_t to, size_t len,
-	      size_t *retlen, const u_char *buf)
+		size_t *retlen, const u_char *buf)
 {
-  DEBUG(MTD_DEBUG_LEVEL2, "ram_write(pos:%ld, len:%ld)\n", (long)to, (long)len);
-  if (to + len > mtd->size) {
-    DEBUG(MTD_DEBUG_LEVEL1, "ram_write() out of bounds (%ld > %ld)\n", (long)(to + len), (long)mtd->size);
-    return -EINVAL;
-  }
+	if (to + len > mtd->size)
+		return -EINVAL;
 
-  memcpy ((char *)mtd->priv + to, buf, len);
+	memcpy((char *)mtd->priv + to, buf, len);
 
-  *retlen=len;
-  return 0;
+	*retlen = len;
+	return 0;
 }
 
 static void __exit cleanup_mtdram(void)
 {
-  if (mtd_info) {
-    del_mtd_device(mtd_info);
-#if CONFIG_MTDRAM_TOTAL_SIZE > 0
-    if (mtd_info->priv)
-#if CONFIG_MTDRAM_ABS_POS > 0
-      iounmap(mtd_info->priv);
-#else
-      vfree(mtd_info->priv);
-#endif	
-#endif
-    kfree(mtd_info);
-  }
-}
-
-int mtdram_init_device(struct mtd_info *mtd, void *mapped_address, 
-                       unsigned long size, char *name)
-{
-   memset(mtd, 0, sizeof(*mtd));
-
-   /* Setup the MTD structure */
-   mtd->name = name;
-   mtd->type = MTD_RAM;
-   mtd->flags = MTD_CAP_RAM;
-   mtd->size = size;
-   mtd->erasesize = MTDRAM_ERASE_SIZE;
-   mtd->priv = mapped_address;
-
-   mtd->owner = THIS_MODULE;
-   mtd->erase = ram_erase;
-   mtd->point = ram_point;
-   mtd->unpoint = ram_unpoint;
-   mtd->read = ram_read;
-   mtd->write = ram_write;
-
-   if (add_mtd_device(mtd)) {
-     return -EIO;
-   }
-   
-   return 0;
-}
+	if (mtd_info) {
+		del_mtd_device(mtd_info);
+		if (mtd_info->priv)
+			vfree(mtd_info->priv);
+		kfree(mtd_info);
+	}
+}
+
+int mtdram_init_device(struct mtd_info *mtd, void *mapped_address,
+		unsigned long size, char *name)
+{
+	memset(mtd, 0, sizeof(*mtd));
+
+	/* Setup the MTD structure */
+	mtd->name = name;
+	mtd->type = MTD_RAM;
+	mtd->flags = MTD_CAP_RAM;
+	mtd->size = size;
+	mtd->erasesize = MTDRAM_ERASE_SIZE;
+	mtd->priv = mapped_address;
+
+	mtd->owner = THIS_MODULE;
+	mtd->erase = ram_erase;
+	mtd->point = ram_point;
+	mtd->unpoint = ram_unpoint;
+	mtd->read = ram_read;
+	mtd->write = ram_write;
+
+	if (add_mtd_device(mtd)) {
+		return -EIO;
+	}
 
-#if CONFIG_MTDRAM_TOTAL_SIZE > 0
-#if CONFIG_MTDRAM_ABS_POS > 0
-static int __init init_mtdram(void)
-{
-  void *addr;
-  int err;
-  /* Allocate some memory */
-   mtd_info = kmalloc(sizeof(struct mtd_info), GFP_KERNEL);
-   if (!mtd_info)
-     return -ENOMEM;
-   
-  addr = ioremap(CONFIG_MTDRAM_ABS_POS, MTDRAM_TOTAL_SIZE);
-  if (!addr) {
-    DEBUG(MTD_DEBUG_LEVEL1, 
-          "Failed to ioremap) memory region of size %ld at ABS_POS:%ld\n", 
-          (long)MTDRAM_TOTAL_SIZE, (long)CONFIG_MTDRAM_ABS_POS);
-    kfree(mtd_info);
-    mtd_info = NULL;
-    return -ENOMEM;
-  }
-  err = mtdram_init_device(mtd_info, addr, 
-                           MTDRAM_TOTAL_SIZE, "mtdram test device");
-  if (err) 
-  {
-    iounmap(addr);
-    kfree(mtd_info);
-    mtd_info = NULL;
-    return err;
-  }
-  memset(mtd_info->priv, 0xff, MTDRAM_TOTAL_SIZE);
-  return err;
+	return 0;
 }
 
-#else /* CONFIG_MTDRAM_ABS_POS > 0 */
-
 static int __init init_mtdram(void)
 {
-  void *addr;
-  int err;
-  /* Allocate some memory */
-   mtd_info = kmalloc(sizeof(struct mtd_info), GFP_KERNEL);
-   if (!mtd_info)
-     return -ENOMEM;
-
-  addr = vmalloc(MTDRAM_TOTAL_SIZE);
-  if (!addr) {
-    DEBUG(MTD_DEBUG_LEVEL1, 
-          "Failed to vmalloc memory region of size %ld\n", 
-          (long)MTDRAM_TOTAL_SIZE);
-    kfree(mtd_info);
-    mtd_info = NULL;
-    return -ENOMEM;
-  }
-  err = mtdram_init_device(mtd_info, addr, 
-                           MTDRAM_TOTAL_SIZE, "mtdram test device");
-  if (err) 
-  {
-    vfree(addr);
-    kfree(mtd_info);
-    mtd_info = NULL;
-    return err;
-  }
-  memset(mtd_info->priv, 0xff, MTDRAM_TOTAL_SIZE);
-  return err;
-}
-#endif /* !(CONFIG_MTDRAM_ABS_POS > 0) */
+	void *addr;
+	int err;
 
-#else /* CONFIG_MTDRAM_TOTAL_SIZE > 0 */
+	if (!total_size)
+		return -EINVAL;
 
-static int __init init_mtdram(void)
-{
-  return 0;
+	/* Allocate some memory */
+	mtd_info = kmalloc(sizeof(struct mtd_info), GFP_KERNEL);
+	if (!mtd_info)
+		return -ENOMEM;
+
+	addr = vmalloc(MTDRAM_TOTAL_SIZE);
+	if (!addr) {
+		kfree(mtd_info);
+		mtd_info = NULL;
+		return -ENOMEM;
+	}
+	err = mtdram_init_device(mtd_info, addr, MTDRAM_TOTAL_SIZE, "mtdram test device");
+	if (err) {
+		vfree(addr);
+		kfree(mtd_info);
+		mtd_info = NULL;
+		return err;
+	}
+	memset(mtd_info->priv, 0xff, MTDRAM_TOTAL_SIZE);
+	return err;
 }
-#endif /* !(CONFIG_MTDRAM_TOTAL_SIZE > 0) */
 
 module_init(init_mtdram);
 module_exit(cleanup_mtdram);
@@ -232,4 +160,3 @@ module_exit(cleanup_mtdram);
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Alexander Larsson <alexl@redhat.com>");
 MODULE_DESCRIPTION("Simulated MTD driver for testing");
-
diff --git a/drivers/mtd/devices/phram.c b/drivers/mtd/devices/phram.c
--- a/drivers/mtd/devices/phram.c
+++ b/drivers/mtd/devices/phram.c
@@ -1,5 +1,5 @@
 /**
- * $Id: phram.c,v 1.11 2005/01/05 18:05:13 dwmw2 Exp $
+ * $Id: phram.c,v 1.14 2005/03/07 21:43:38 joern Exp $
  *
  * Copyright (c) ????		Jochen Schäuble <psionic@psionic.de>
  * Copyright (c) 2003-2004	Jörn Engel <joern@wh.fh-wedel.de>
@@ -15,9 +15,7 @@
  *
  * Example:
  *	phram=swap,64Mi,128Mi phram=test,900Mi,1Mi
- *
  */
-
 #include <asm/io.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
@@ -36,7 +34,6 @@ struct phram_mtd_list {
 static LIST_HEAD(phram_list);
 
 
-
 static int phram_erase(struct mtd_info *mtd, struct erase_info *instr)
 {
 	u_char *start = mtd->priv;
@@ -71,7 +68,8 @@ static int phram_point(struct mtd_info *
 	return 0;
 }
 
-static void phram_unpoint(struct mtd_info *mtd, u_char *addr, loff_t from, size_t len)
+static void phram_unpoint(struct mtd_info *mtd, u_char *addr, loff_t from,
+		size_t len)
 {
 }
 
@@ -80,8 +78,11 @@ static int phram_read(struct mtd_info *m
 {
 	u_char *start = mtd->priv;
 
-	if (from + len > mtd->size)
+	if (from >= mtd->size)
 		return -EINVAL;
+
+	if (len > mtd->size - from)
+		len = mtd->size - from;
 	
 	memcpy(buf, start + from, len);
 
@@ -94,8 +95,11 @@ static int phram_write(struct mtd_info *
 {
 	u_char *start = mtd->priv;
 
-	if (to + len > mtd->size)
+	if (to >= mtd->size)
 		return -EINVAL;
+
+	if (len > mtd->size - to)
+		len = mtd->size - to;
 	
 	memcpy(start + to, buf, len);
 
@@ -107,9 +111,9 @@ static int phram_write(struct mtd_info *
 
 static void unregister_devices(void)
 {
-	struct phram_mtd_list *this;
+	struct phram_mtd_list *this, *safe;
 
-	list_for_each_entry(this, &phram_list, list) {
+	list_for_each_entry_safe(this, safe, &phram_list, list) {
 		del_mtd_device(&this->mtd);
 		iounmap(this->mtd.priv);
 		kfree(this);
@@ -145,7 +149,7 @@ static int register_device(char *name, u
 	new->mtd.write = phram_write;
 	new->mtd.owner = THIS_MODULE;
 	new->mtd.type = MTD_RAM;
-	new->mtd.erasesize = 0;
+	new->mtd.erasesize = PAGE_SIZE;
 
 	ret = -EAGAIN;
 	if (add_mtd_device(&new->mtd)) {
@@ -214,6 +218,15 @@ static int parse_name(char **pname, cons
 	return 0;
 }
 
+
+static inline void kill_final_newline(char *str)
+{
+	char *newline = strrchr(str, '\n');
+	if (newline && !newline[1])
+		*newline = 0;
+}
+
+
 #define parse_err(fmt, args...) do {	\
 	ERROR(fmt , ## args);	\
 	return 0;		\
@@ -232,6 +245,7 @@ static int phram_setup(const char *val, 
 		parse_err("parameter too long\n");
 
 	strcpy(str, val);
+	kill_final_newline(str);
 
 	for (i=0; i<3; i++)
 		token[i] = strsep(&str, ",");
diff --git a/drivers/mtd/devices/slram.c b/drivers/mtd/devices/slram.c
--- a/drivers/mtd/devices/slram.c
+++ b/drivers/mtd/devices/slram.c
@@ -1,6 +1,6 @@
 /*======================================================================
 
-  $Id: slram.c,v 1.33 2005/01/05 18:05:13 dwmw2 Exp $
+  $Id: slram.c,v 1.34 2005/01/06 21:16:42 jwboyer Exp $
 
   This driver provides a method to access memory not used by the kernel
   itself (i.e. if the kernel commandline mem=xxx is used). To actually
@@ -50,6 +50,7 @@
 #include <linux/mtd/mtd.h>
 
 #define SLRAM_MAX_DEVICES_PARAMS 6		/* 3 parameters / device */
+#define SLRAM_BLK_SZ 0x4000
 
 #define T(fmt, args...) printk(KERN_DEBUG fmt, ## args)
 #define E(fmt, args...) printk(KERN_NOTICE fmt, ## args)
@@ -108,6 +109,9 @@ static int slram_point(struct mtd_info *
 {
 	slram_priv_t *priv = mtd->priv;
 
+	if (from + len > mtd->size)
+		return -EINVAL;
+
 	*mtdbuf = priv->start + from;
 	*retlen = len;
 	return(0);
@@ -121,7 +125,13 @@ static int slram_read(struct mtd_info *m
 		size_t *retlen, u_char *buf)
 {
 	slram_priv_t *priv = mtd->priv;
-	
+
+	if (from > mtd->size)
+		return -EINVAL;
+
+	if (from + len > mtd->size)
+		len = mtd->size - from;
+
 	memcpy(buf, priv->start + from, len);
 
 	*retlen = len;
@@ -133,6 +143,9 @@ static int slram_write(struct mtd_info *
 {
 	slram_priv_t *priv = mtd->priv;
 
+	if (to + len > mtd->size)
+		return -EINVAL;
+
 	memcpy(priv->start + to, buf, len);
 
 	*retlen = len;
@@ -188,7 +201,7 @@ static int register_device(char *name, u
 	(*curmtd)->mtdinfo->name = name;
 	(*curmtd)->mtdinfo->size = length;
 	(*curmtd)->mtdinfo->flags = MTD_CLEAR_BITS | MTD_SET_BITS |
-					MTD_WRITEB_WRITEABLE | MTD_VOLATILE;
+					MTD_WRITEB_WRITEABLE | MTD_VOLATILE | MTD_CAP_RAM;
         (*curmtd)->mtdinfo->erase = slram_erase;
 	(*curmtd)->mtdinfo->point = slram_point;
 	(*curmtd)->mtdinfo->unpoint = slram_unpoint;
@@ -196,7 +209,7 @@ static int register_device(char *name, u
 	(*curmtd)->mtdinfo->write = slram_write;
 	(*curmtd)->mtdinfo->owner = THIS_MODULE;
 	(*curmtd)->mtdinfo->type = MTD_RAM;
-	(*curmtd)->mtdinfo->erasesize = 0x0;
+	(*curmtd)->mtdinfo->erasesize = SLRAM_BLK_SZ;
 
 	if (add_mtd_device((*curmtd)->mtdinfo))	{
 		E("slram: Failed to register new device\n");
@@ -261,7 +274,7 @@ static int parse_cmdline(char *devname, 
 	}
 	T("slram: devname=%s, devstart=0x%lx, devlength=0x%lx\n",
 			devname, devstart, devlength);
-	if ((devstart < 0) || (devlength < 0)) {
+	if ((devstart < 0) || (devlength < 0) || (devlength % SLRAM_BLK_SZ != 0)) {
 		E("slram: Illegal start / length parameter.\n");
 		return(-EINVAL);
 	}
diff --git a/drivers/mtd/ftl.c b/drivers/mtd/ftl.c
--- a/drivers/mtd/ftl.c
+++ b/drivers/mtd/ftl.c
@@ -1,5 +1,5 @@
 /* This version ported to the Linux-MTD system by dwmw2@infradead.org
- * $Id: ftl.c,v 1.54 2004/11/16 18:33:15 dwmw2 Exp $
+ * $Id: ftl.c,v 1.55 2005/01/17 13:47:21 hvr Exp $
  *
  * Fixes: Arnaldo Carvalho de Melo <acme@conectiva.com.br>
  * - fixes some leaks on failure in build_maps and ftl_notify_add, cleanups
@@ -357,6 +357,7 @@ static int erase_xfer(partition_t *part,
     if (!erase) 
             return -ENOMEM;
 
+    erase->mtd = part->mbd.mtd;
     erase->callback = ftl_erase_callback;
     erase->addr = xfer->Offset;
     erase->len = 1 << part->header.EraseUnitSize;
@@ -1096,7 +1097,7 @@ struct mtd_blktrans_ops ftl_tr = {
 
 int init_ftl(void)
 {
-	DEBUG(0, "$Id: ftl.c,v 1.54 2004/11/16 18:33:15 dwmw2 Exp $\n");
+	DEBUG(0, "$Id: ftl.c,v 1.55 2005/01/17 13:47:21 hvr Exp $\n");
 
 	return register_mtd_blktrans(&ftl_tr);
 }
diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig
--- a/drivers/mtd/maps/Kconfig
+++ b/drivers/mtd/maps/Kconfig
@@ -1,5 +1,5 @@
 # drivers/mtd/maps/Kconfig
-# $Id: Kconfig,v 1.42 2005/01/05 16:59:50 dwmw2 Exp $
+# $Id: Kconfig,v 1.55 2005/07/02 01:53:24 tpoynor Exp $
 
 menu "Mapping drivers for chip access"
 	depends on MTD!=n
@@ -122,16 +122,6 @@ config MTD_SBC_GXX
 	  More info at
 	  <http://www.arcomcontrols.com/products/icp/pc104/processors/SBC_GX1.htm>.
 
-config MTD_ELAN_104NC
-	tristate "CFI Flash device mapped on Arcom ELAN-104NC"
-	depends on X86 && MTD_CFI_INTELEXT && MTD_PARTITIONS && MTD_COMPLEX_MAPPINGS
-	help
-	  This provides a driver for the on-board flash of the Arcom Control
-	  System's ELAN-104NC development board. By default the flash
-	  is split into 3 partitions which are accessed as separate MTD
-	  devices. This board utilizes Intel StrataFlash. More info at
-	  <http://www.arcomcontrols.com/products/icp/pc104/processors/ELAN104NC.htm>.
-
 config MTD_LUBBOCK
 	tristate "CFI Flash device mapped on Intel Lubbock XScale eval board"
 	depends on ARCH_LUBBOCK && MTD_CFI_INTELEXT && MTD_PARTITIONS
@@ -139,6 +129,14 @@ config MTD_LUBBOCK
 	  This provides a driver for the on-board flash of the Intel
 	  'Lubbock' XScale evaluation board.
 
+config MTD_MAINSTONE
+	tristate "CFI Flash device mapped on Intel Mainstone XScale eval board"
+	depends on MACH_MAINSTONE && MTD_CFI_INTELEXT
+	select MTD_PARTITIONS
+	help
+	  This provides a driver for the on-board flash of the Intel
+	  'Mainstone PXA27x evaluation board.
+
 config MTD_OCTAGON
 	tristate "JEDEC Flash device mapped on Octagon 5066 SBC"
 	depends on X86 && MTD_JEDEC && MTD_COMPLEX_MAPPINGS
@@ -213,74 +211,11 @@ config MTD_NETtel
 	help
 	  Support for flash chips on NETtel/SecureEdge/SnapGear boards.
 
-config MTD_PB1XXX
-	tristate "Flash devices on Alchemy PB1xxx boards"
-	depends on MIPS && ( MIPS_PB1000 || MIPS_PB1100 || MIPS_PB1500 )
-	help
-	  Flash memory access on Alchemy Pb1000/Pb1100/Pb1500 boards
-
-config MTD_PB1XXX_BOOT
-	bool "PB1x00 boot flash device"
-	depends on MTD_PB1XXX && ( MIPS_PB1100 || MIPS_PB1500 )
-	help
-	  Use the first of the two 32MiB flash banks on Pb1100/Pb1500 board.
-	  You can say 'Y' to both this and 'MTD_PB1XXX_USER' below, to use
-	  both banks.
-
-config MTD_PB1XXX_USER
-	bool "PB1x00 user flash device"
-	depends on MTD_PB1XXX && ( MIPS_PB1100 || MIPS_PB1500 )
-	default y if MTD_PB1XX_BOOT = n
-	help
-	  Use the second of the two 32MiB flash banks on Pb1100/Pb1500 board.
-	  You can say 'Y' to both this and 'MTD_PB1XXX_BOOT' above, to use
-	  both banks.
-
-config MTD_PB1550
-	tristate "Flash devices on Alchemy PB1550 board"
-	depends on MIPS && MIPS_PB1550
-	help
-	  Flash memory access on Alchemy Pb1550 board
-
-config MTD_PB1550_BOOT
-	bool "PB1550 boot flash device"
-	depends on MTD_PB1550
-	help
-	  Use the first of the two 64MiB flash banks on Pb1550 board.
-	  You can say 'Y' to both this and 'MTD_PB1550_USER' below, to use
-	  both banks.
-
-config MTD_PB1550_USER
-	bool "PB1550 user flash device"
-	depends on MTD_PB1550
-	default y if MTD_PB1550_BOOT = n
-	help
-	  Use the second of the two 64MiB flash banks on Pb1550 board.
-	  You can say 'Y' to both this and 'MTD_PB1550_BOOT' above, to use
-	  both banks.
-
-config MTD_DB1550
-	tristate "Flash devices on Alchemy DB1550 board"
-	depends on MIPS && MIPS_DB1550
-	help
-	  Flash memory access on Alchemy Db1550 board
-
-config MTD_DB1550_BOOT
-	bool "DB1550 boot flash device"
-	depends on MTD_DB1550
-	help
-	  Use the first of the two 64MiB flash banks on Db1550 board.
-	  You can say 'Y' to both this and 'MTD_DB1550_USER' below, to use
-	  both banks.
-
-config MTD_DB1550_USER
-	bool "DB1550 user flash device"
-	depends on MTD_DB1550
-	default y if MTD_DB1550_BOOT = n
-	help
-	  Use the second of the two 64MiB flash banks on Db1550 board.
-	  You can say 'Y' to both this and 'MTD_DB1550_BOOT' above, to use
-	  both banks.
+config MTD_ALCHEMY
+	tristate '  AMD Alchemy Pb1xxx/Db1xxx/RDK MTD support' 
+	depends on MIPS && SOC_AU1X00
+	help
+	  Flash memory access on AMD Alchemy Pb/Db/RDK Reference Boards
 
 config MTD_DILNETPC
 	tristate "CFI Flash device mapped on DIL/Net PC"
@@ -588,6 +523,15 @@ config MTD_MPC1211
 	  This enables access to the flash chips on the Interface MPC-1211(CTP/PCI/MPC-SH02).
 	  If you have such a board, say 'Y'.
 
+config MTD_OMAP_NOR
+	tristate "TI OMAP board mappings"
+	depends on MTD_CFI && ARCH_OMAP
+	help
+	  This enables access to the NOR flash chips on TI OMAP-based
+	  boards defining flash platform devices and flash platform data.
+	  These boards include the Innovator, H2, H3, OSK, Perseus2, and
+	  more.  If you have such a board, say 'Y'.
+
 # This needs CFI or JEDEC, depending on the cards found.
 config MTD_PCI
 	tristate "PCI MTD driver"
@@ -607,6 +551,16 @@ config MTD_PCMCIA
 	  cards are usually around 4-16MiB in size. This does not include
 	  Compact Flash cards which are treated as IDE devices.
 
+config MTD_PCMCIA_ANONYMOUS
+	bool "Use PCMCIA MTD drivers for anonymous PCMCIA cards"
+	depends on MTD_PCMCIA
+	default N
+	help
+	  If this option is enabled, PCMCIA cards which do not report
+	  anything about themselves are assumed to be MTD cards.
+
+	  If unsure, say N.
+
 config MTD_UCLINUX
 	tristate "Generic uClinux RAM/ROM filesystem support"
 	depends on MTD_PARTITIONS && !MMU
@@ -637,13 +591,14 @@ config MTD_DMV182
           Map driver for Dy-4 SVME/DMV-182 board.
 
 config MTD_BAST
-	tristate "Map driver for Simtec BAST (EB2410ITX)"
-	depends on ARCH_BAST
+	tristate "Map driver for Simtec BAST (EB2410ITX) or Thorcom VR1000"
+	depends on ARCH_BAST || MACH_VR1000
 	select MTD_PARTITIONS
 	select MTD_MAP_BANK_WIDTH_16
 	select MTD_JEDECPROBE
 	help
-	  Map driver for NOR flash on the Simtec BAST (EB2410ITX).
+	  Map driver for NOR flash on the Simtec BAST (EB2410ITX), or the
+	  Thorcom VR1000
 
 	  Note, this driver *cannot* over-ride the WP link on the
 	  board, or currently detect the state of the link.
@@ -659,5 +614,15 @@ config MTD_SHARP_SL
 	help
 	  This enables access to the flash chip on the Sharp SL Series of PDAs.
 
+config MTD_PLATRAM
+	tristate "Map driver for platform device RAM (mtd-ram)"
+	depends on MTD
+	select MTD_RAM
+	help
+	  Map driver for RAM areas described via the platform device
+	  system.
+
+	  This selection automatically selects the map_ram driver.
+
 endmenu
 
diff --git a/drivers/mtd/maps/Makefile b/drivers/mtd/maps/Makefile
--- a/drivers/mtd/maps/Makefile
+++ b/drivers/mtd/maps/Makefile
@@ -1,7 +1,7 @@
 #
 # linux/drivers/maps/Makefile
 #
-# $Id: Makefile.common,v 1.23 2005/01/05 17:06:36 dwmw2 Exp $
+# $Id: Makefile.common,v 1.30 2005/07/02 01:53:24 tpoynor Exp $
 
 ifeq ($(CONFIG_MTD_COMPLEX_MAPPINGS),y)
 obj-$(CONFIG_MTD)		+= map_funcs.o
@@ -15,7 +15,6 @@ obj-$(CONFIG_MTD_CFI_FLAGADM)	+= cfi_fla
 obj-$(CONFIG_MTD_CSTM_MIPS_IXX)	+= cstm_mips_ixx.o
 obj-$(CONFIG_MTD_DC21285)	+= dc21285.o
 obj-$(CONFIG_MTD_DILNETPC)	+= dilnetpc.o
-obj-$(CONFIG_MTD_ELAN_104NC)	+= elan-104nc.o
 obj-$(CONFIG_MTD_EPXA10DB)	+= epxa10db-flash.o
 obj-$(CONFIG_MTD_IQ80310)	+= iq80310.o
 obj-$(CONFIG_MTD_L440GX)	+= l440gx.o
@@ -23,6 +22,7 @@ obj-$(CONFIG_MTD_AMD76XROM)	+= amd76xrom
 obj-$(CONFIG_MTD_ICHXROM)	+= ichxrom.o
 obj-$(CONFIG_MTD_TSUNAMI)	+= tsunami_flash.o
 obj-$(CONFIG_MTD_LUBBOCK)	+= lubbock-flash.o
+obj-$(CONFIG_MTD_MAINSTONE)	+= mainstone-flash.o
 obj-$(CONFIG_MTD_MBX860)	+= mbx860.o
 obj-$(CONFIG_MTD_CEIVA)		+= ceiva.o
 obj-$(CONFIG_MTD_OCTAGON)	+= octagon-5066.o
@@ -44,10 +44,7 @@ obj-$(CONFIG_MTD_DBOX2)		+= dbox2-flash.
 obj-$(CONFIG_MTD_OCELOT)	+= ocelot.o
 obj-$(CONFIG_MTD_SOLUTIONENGINE)+= solutionengine.o
 obj-$(CONFIG_MTD_PCI)		+= pci.o
-obj-$(CONFIG_MTD_PB1XXX)	+= pb1xxx-flash.o
-obj-$(CONFIG_MTD_DB1X00)        += db1x00-flash.o
-obj-$(CONFIG_MTD_PB1550)        += pb1550-flash.o
-obj-$(CONFIG_MTD_DB1550)        += db1550-flash.o
+obj-$(CONFIG_MTD_ALCHEMY)       += alchemy-flash.o
 obj-$(CONFIG_MTD_LASAT)		+= lasat.o
 obj-$(CONFIG_MTD_AUTCPU12)	+= autcpu12-nvram.o
 obj-$(CONFIG_MTD_EDB7312)	+= edb7312.o
@@ -71,3 +68,5 @@ obj-$(CONFIG_MTD_IXP2000)	+= ixp2000.o
 obj-$(CONFIG_MTD_WRSBC8260)	+= wr_sbc82xx_flash.o
 obj-$(CONFIG_MTD_DMV182)	+= dmv182.o
 obj-$(CONFIG_MTD_SHARP_SL)	+= sharpsl-flash.o
+obj-$(CONFIG_MTD_PLATRAM)	+= plat-ram.o
+obj-$(CONFIG_MTD_OMAP_NOR)	+= omap_nor.o
diff --git a/drivers/mtd/maps/alchemy-flash.c b/drivers/mtd/maps/alchemy-flash.c
new file mode 100644
--- /dev/null
+++ b/drivers/mtd/maps/alchemy-flash.c
@@ -0,0 +1,192 @@
+/*
+ * Flash memory access on AMD Alchemy evaluation boards
+ * 
+ * $Id: alchemy-flash.c,v 1.1 2005/02/27 21:50:21 ppopov Exp $
+ *
+ * (C) 2003, 2004 Pete Popov <ppopov@embeddedalley.com>
+ * 
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/io.h>
+
+#ifdef 	DEBUG_RW
+#define	DBG(x...)	printk(x)
+#else
+#define	DBG(x...)	
+#endif
+
+#ifdef CONFIG_MIPS_PB1000
+#define BOARD_MAP_NAME "Pb1000 Flash"
+#define BOARD_FLASH_SIZE 0x00800000 /* 8MB */
+#define BOARD_FLASH_WIDTH 4 /* 32-bits */
+#endif
+
+#ifdef CONFIG_MIPS_PB1500
+#define BOARD_MAP_NAME "Pb1500 Flash"
+#define BOARD_FLASH_SIZE 0x04000000 /* 64MB */
+#define BOARD_FLASH_WIDTH 4 /* 32-bits */
+#endif
+
+#ifdef CONFIG_MIPS_PB1100
+#define BOARD_MAP_NAME "Pb1100 Flash"
+#define BOARD_FLASH_SIZE 0x04000000 /* 64MB */
+#define BOARD_FLASH_WIDTH 4 /* 32-bits */
+#endif
+
+#ifdef CONFIG_MIPS_PB1550
+#define BOARD_MAP_NAME "Pb1550 Flash"
+#define BOARD_FLASH_SIZE 0x08000000 /* 128MB */
+#define BOARD_FLASH_WIDTH 4 /* 32-bits */
+#endif
+
+#ifdef CONFIG_MIPS_PB1200
+#define BOARD_MAP_NAME "Pb1200 Flash"
+#define BOARD_FLASH_SIZE 0x08000000 /* 128MB */
+#define BOARD_FLASH_WIDTH 2 /* 16-bits */
+#endif
+
+#ifdef CONFIG_MIPS_DB1000
+#define BOARD_MAP_NAME "Db1000 Flash"
+#define BOARD_FLASH_SIZE 0x02000000 /* 32MB */
+#define BOARD_FLASH_WIDTH 4 /* 32-bits */
+#endif
+
+#ifdef CONFIG_MIPS_DB1500
+#define BOARD_MAP_NAME "Db1500 Flash"
+#define BOARD_FLASH_SIZE 0x02000000 /* 32MB */
+#define BOARD_FLASH_WIDTH 4 /* 32-bits */
+#endif
+
+#ifdef CONFIG_MIPS_DB1100
+#define BOARD_MAP_NAME "Db1100 Flash"
+#define BOARD_FLASH_SIZE 0x02000000 /* 32MB */
+#define BOARD_FLASH_WIDTH 4 /* 32-bits */
+#endif
+
+#ifdef CONFIG_MIPS_DB1550
+#define BOARD_MAP_NAME "Db1550 Flash"
+#define BOARD_FLASH_SIZE 0x08000000 /* 128MB */
+#define BOARD_FLASH_WIDTH 4 /* 32-bits */
+#endif
+
+#ifdef CONFIG_MIPS_DB1200
+#define BOARD_MAP_NAME "Db1200 Flash"
+#define BOARD_FLASH_SIZE 0x04000000 /* 64MB */
+#define BOARD_FLASH_WIDTH 2 /* 16-bits */
+#endif
+
+#ifdef CONFIG_MIPS_HYDROGEN3
+#define BOARD_MAP_NAME "Hydrogen3 Flash"
+#define BOARD_FLASH_SIZE 0x02000000 /* 32MB */
+#define BOARD_FLASH_WIDTH 4 /* 32-bits */
+#define USE_LOCAL_ACCESSORS /* why? */
+#endif
+
+#ifdef CONFIG_MIPS_BOSPORUS
+#define BOARD_MAP_NAME "Bosporus Flash"
+#define BOARD_FLASH_SIZE 0x01000000 /* 16MB */
+#define BOARD_FLASH_WIDTH 2 /* 16-bits */
+#endif
+
+#ifdef CONFIG_MIPS_MIRAGE
+#define BOARD_MAP_NAME "Mirage Flash"
+#define BOARD_FLASH_SIZE 0x04000000 /* 64MB */
+#define BOARD_FLASH_WIDTH 4 /* 32-bits */
+#define USE_LOCAL_ACCESSORS /* why? */
+#endif
+
+static struct map_info alchemy_map = {
+	.name =	BOARD_MAP_NAME,
+};
+
+static struct mtd_partition alchemy_partitions[] = {
+        {
+                .name = "User FS",
+                .size = BOARD_FLASH_SIZE - 0x00400000,
+                .offset = 0x0000000
+        },{
+                .name = "YAMON",
+                .size = 0x0100000,
+		.offset = MTDPART_OFS_APPEND,
+                .mask_flags = MTD_WRITEABLE
+        },{
+                .name = "raw kernel",
+		.size = (0x300000 - 0x40000), /* last 256KB is yamon env */
+		.offset = MTDPART_OFS_APPEND,
+        }
+};
+
+#define NB_OF(x)  (sizeof(x)/sizeof(x[0]))
+
+static struct mtd_info *mymtd;
+
+int __init alchemy_mtd_init(void)
+{
+	struct mtd_partition *parts;
+	int nb_parts = 0;
+	unsigned long window_addr;
+	unsigned long window_size;
+	
+	/* Default flash buswidth */
+	alchemy_map.bankwidth = BOARD_FLASH_WIDTH;
+
+	window_addr = 0x20000000 - BOARD_FLASH_SIZE;
+	window_size = BOARD_FLASH_SIZE;
+#ifdef CONFIG_MIPS_MIRAGE_WHY
+	/* Boot ROM flash bank only; no user bank */
+	window_addr = 0x1C000000;
+	window_size = 0x04000000;
+	/* USERFS from 0x1C00 0000 to 0x1FC00000 */
+	alchemy_partitions[0].size = 0x03C00000;
+#endif
+
+	/*
+	 * Static partition definition selection
+	 */
+	parts = alchemy_partitions;
+	nb_parts = NB_OF(alchemy_partitions);
+	alchemy_map.size = window_size;
+
+	/*
+	 * Now let's probe for the actual flash.  Do it here since
+	 * specific machine settings might have been set above.
+	 */
+	printk(KERN_NOTICE BOARD_MAP_NAME ": probing %d-bit flash bus\n", 
+			alchemy_map.bankwidth*8);
+	alchemy_map.virt = ioremap(window_addr, window_size);
+	mymtd = do_map_probe("cfi_probe", &alchemy_map);
+	if (!mymtd) {
+		iounmap(alchemy_map.virt);
+		return -ENXIO;
+	}
+	mymtd->owner = THIS_MODULE;
+
+	add_mtd_partitions(mymtd, parts, nb_parts);
+	return 0;
+}
+
+static void __exit alchemy_mtd_cleanup(void)
+{
+	if (mymtd) {
+		del_mtd_partitions(mymtd);
+		map_destroy(mymtd);
+		iounmap(alchemy_map.virt);
+	}
+}
+
+module_init(alchemy_mtd_init);
+module_exit(alchemy_mtd_cleanup);
+
+MODULE_AUTHOR("Embedded Alley Solutions, Inc");
+MODULE_DESCRIPTION(BOARD_MAP_NAME " MTD driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/mtd/maps/amd76xrom.c b/drivers/mtd/maps/amd76xrom.c
--- a/drivers/mtd/maps/amd76xrom.c
+++ b/drivers/mtd/maps/amd76xrom.c
@@ -2,7 +2,7 @@
  * amd76xrom.c
  *
  * Normal mappings of chips in physical memory
- * $Id: amd76xrom.c,v 1.19 2004/11/28 09:40:39 dwmw2 Exp $
+ * $Id: amd76xrom.c,v 1.20 2005/03/18 14:04:35 gleixner Exp $
  */
 
 #include <linux/module.h>
@@ -314,7 +314,7 @@ static int __init init_amd76xrom(void)
 	}
 	return -ENXIO;
 #if 0
-	return pci_module_init(&amd76xrom_driver);
+	return pci_register_driver(&amd76xrom_driver);
 #endif
 }
 
diff --git a/drivers/mtd/maps/bast-flash.c b/drivers/mtd/maps/bast-flash.c
--- a/drivers/mtd/maps/bast-flash.c
+++ b/drivers/mtd/maps/bast-flash.c
@@ -1,14 +1,15 @@
 /* linux/drivers/mtd/maps/bast_flash.c
  *
- * Copyright (c) 2004 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
+ * Copyright (c) 2004-2005 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
  *
  * Simtec Bast (EB2410ITX) NOR MTD Mapping driver
  *
  * Changelog:
  *	20-Sep-2004  BJD  Initial version
+ *	17-Jan-2005  BJD  Add whole device if no partitions found
  *
- * $Id: bast-flash.c,v 1.1 2004/09/21 14:29:04 bjd Exp $
+ * $Id: bast-flash.c,v 1.2 2005/01/18 11:13:47 bjd Exp $
  *
  * 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
@@ -46,9 +47,9 @@
 #include <asm/arch/bast-cpld.h>
 
 #ifdef CONFIG_MTD_BAST_MAXSIZE
-#define AREA_MAXSIZE (CONFIG_MTD_BAST_MAXSIZE * (1024*1024))
+#define AREA_MAXSIZE (CONFIG_MTD_BAST_MAXSIZE * SZ_1M)
 #else
-#define AREA_MAXSIZE (32*1024*1024)
+#define AREA_MAXSIZE (32 * SZ_1M)
 #endif
 
 #define PFX "bast-flash: "
@@ -189,6 +190,8 @@ static int bast_flash_probe(struct devic
 		err = add_mtd_partitions(info->mtd, info->partitions, err);
 		if (err) 
 			printk(KERN_ERR PFX "cannot add/parse partitions\n");
+	} else {
+		err = add_mtd_device(info->mtd);
 	}
 
 	if (err == 0)
diff --git a/drivers/mtd/maps/db1550-flash.c b/drivers/mtd/maps/db1550-flash.c
deleted file mode 100644
--- a/drivers/mtd/maps/db1550-flash.c
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * Flash memory access on Alchemy Db1550 board
- * 
- * $Id: db1550-flash.c,v 1.7 2004/11/04 13:24:14 gleixner Exp $
- *
- * (C) 2004 Embedded Edge, LLC, based on db1550-flash.c:
- * (C) 2003, 2004 Pete Popov <ppopov@embeddedalley.com>
- * 
- */
-
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/map.h>
-#include <linux/mtd/partitions.h>
-
-#include <asm/io.h>
-
-#ifdef 	DEBUG_RW
-#define	DBG(x...)	printk(x)
-#else
-#define	DBG(x...)	
-#endif
-
-static unsigned long window_addr;
-static unsigned long window_size;
-
-
-static struct map_info db1550_map = {
-	.name =	"Db1550 flash",
-};
-
-static unsigned char flash_bankwidth = 4;
-
-/* 
- * Support only 64MB NOR Flash parts
- */
-
-#if defined(CONFIG_MTD_DB1550_BOOT) && defined(CONFIG_MTD_DB1550_USER)
-#define DB1550_BOTH_BANKS
-#elif defined(CONFIG_MTD_DB1550_BOOT) && !defined(CONFIG_MTD_DB1550_USER)
-#define DB1550_BOOT_ONLY
-#elif !defined(CONFIG_MTD_DB1550_BOOT) && defined(CONFIG_MTD_DB1550_USER)
-#define DB1550_USER_ONLY
-#endif
-
-#ifdef DB1550_BOTH_BANKS
-/* both banks will be used. Combine the first bank and the first 
- * part of the second bank together into a single jffs/jffs2
- * partition.
- */
-static struct mtd_partition db1550_partitions[] = {
-	/* assume boot[2:0]:swap is '0000' or '1000', which translates to:
-	 * 1C00 0000 1FFF FFFF CE0 64MB Boot NOR Flash
-	 * 1800 0000 1BFF FFFF CE0 64MB Param NOR Flash
-	 */
-        {
-                .name = "User FS",
-                .size =   (0x1FC00000 - 0x18000000),
-                .offset = 0x0000000
-        },{
-                .name = "yamon",
-                .size = 0x0100000,
-		.offset = MTDPART_OFS_APPEND,
-                .mask_flags = MTD_WRITEABLE
-        },{
-                .name = "raw kernel",
-		.size = (0x300000 - 0x40000), /* last 256KB is yamon env */
-		.offset = MTDPART_OFS_APPEND,
-        }
-};
-#elif defined(DB1550_BOOT_ONLY)
-static struct mtd_partition db1550_partitions[] = {
-	/* assume boot[2:0]:swap is '0000' or '1000', which translates to:
-	 * 1C00 0000 1FFF FFFF CE0 64MB Boot NOR Flash
-	 */
-        {
-                .name = "User FS",
-                .size =   0x03c00000,
-                .offset = 0x0000000
-        },{
-                .name = "yamon",
-                .size = 0x0100000,
-		.offset = MTDPART_OFS_APPEND,
-                .mask_flags = MTD_WRITEABLE
-        },{
-                .name = "raw kernel",
-		.size = (0x300000-0x40000), /* last 256KB is yamon env */
-		.offset = MTDPART_OFS_APPEND,
-        }
-};
-#elif defined(DB1550_USER_ONLY)
-static struct mtd_partition db1550_partitions[] = {
-	/* assume boot[2:0]:swap is '0000' or '1000', which translates to:
-	 * 1800 0000 1BFF FFFF CE0 64MB Param NOR Flash
-	 */
-        {
-                .name = "User FS",
-                .size = (0x4000000 - 0x200000), /* reserve 2MB for raw kernel */
-                .offset = 0x0000000
-        },{
-                .name = "raw kernel",
-		.size = MTDPART_SIZ_FULL,
-		.offset = MTDPART_OFS_APPEND,
-        }
-};
-#else
-#error MTD_DB1550 define combo error /* should never happen */
-#endif
-
-#define NB_OF(x)  (sizeof(x)/sizeof(x[0]))
-
-static struct mtd_info *mymtd;
-
-/*
- * Probe the flash density and setup window address and size
- * based on user CONFIG options. There are times when we don't
- * want the MTD driver to be probing the boot or user flash,
- * so having the option to enable only one bank is important.
- */
-int setup_flash_params(void)
-{
-#if defined(DB1550_BOTH_BANKS)
-			window_addr = 0x18000000;
-			window_size = 0x8000000; 
-#elif defined(DB1550_BOOT_ONLY)
-			window_addr = 0x1C000000;
-			window_size = 0x4000000; 
-#else /* USER ONLY */
-			window_addr = 0x18000000;
-			window_size = 0x4000000; 
-#endif
-	return 0;
-}
-
-int __init db1550_mtd_init(void)
-{
-	struct mtd_partition *parts;
-	int nb_parts = 0;
-	
-	/* Default flash bankwidth */
-	db1550_map.bankwidth = flash_bankwidth;
-
-	if (setup_flash_params()) 
-		return -ENXIO;
-
-	/*
-	 * Static partition definition selection
-	 */
-	parts = db1550_partitions;
-	nb_parts = NB_OF(db1550_partitions);
-	db1550_map.size = window_size;
-
-	/*
-	 * Now let's probe for the actual flash.  Do it here since
-	 * specific machine settings might have been set above.
-	 */
-	printk(KERN_NOTICE "Db1550 flash: probing %d-bit flash bus\n", 
-			db1550_map.bankwidth*8);
-	db1550_map.virt = ioremap(window_addr, window_size);
-	mymtd = do_map_probe("cfi_probe", &db1550_map);
-	if (!mymtd) return -ENXIO;
-	mymtd->owner = THIS_MODULE;
-
-	add_mtd_partitions(mymtd, parts, nb_parts);
-	return 0;
-}
-
-static void __exit db1550_mtd_cleanup(void)
-{
-	if (mymtd) {
-		del_mtd_partitions(mymtd);
-		map_destroy(mymtd);
-		iounmap((void *) db1550_map.virt);
-	}
-}
-
-module_init(db1550_mtd_init);
-module_exit(db1550_mtd_cleanup);
-
-MODULE_AUTHOR("Embedded Edge, LLC");
-MODULE_DESCRIPTION("Db1550 mtd map driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/mtd/maps/db1x00-flash.c b/drivers/mtd/maps/db1x00-flash.c
deleted file mode 100644
--- a/drivers/mtd/maps/db1x00-flash.c
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- * Flash memory access on Alchemy Db1xxx boards
- * 
- * $Id: db1x00-flash.c,v 1.6 2004/11/04 13:24:14 gleixner Exp $
- *
- * (C) 2003 Pete Popov <ppopov@embeddedalley.com>
- * 
- */
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/map.h>
-#include <linux/mtd/partitions.h>
-
-#include <asm/io.h>
-
-#ifdef 	DEBUG_RW
-#define	DBG(x...)	printk(x)
-#else
-#define	DBG(x...)	
-#endif
-
-/* MTD CONFIG OPTIONS */
-#if defined(CONFIG_MTD_DB1X00_BOOT) && defined(CONFIG_MTD_DB1X00_USER)
-#define DB1X00_BOTH_BANKS
-#elif defined(CONFIG_MTD_DB1X00_BOOT) && !defined(CONFIG_MTD_DB1X00_USER)
-#define DB1X00_BOOT_ONLY
-#elif !defined(CONFIG_MTD_DB1X00_BOOT) && defined(CONFIG_MTD_DB1X00_USER)
-#define DB1X00_USER_ONLY
-#endif
-
-static unsigned long window_addr;
-static unsigned long window_size;
-static unsigned long flash_size;
-
-static unsigned short *bcsr = (unsigned short *)0xAE000000;
-static unsigned char flash_bankwidth = 4;
-
-/* 
- * The Db1x boards support different flash densities. We setup
- * the mtd_partition structures below for default of 64Mbit 
- * flash densities, and override the partitions sizes, if
- * necessary, after we check the board status register.
- */
-
-#ifdef DB1X00_BOTH_BANKS
-/* both banks will be used. Combine the first bank and the first 
- * part of the second bank together into a single jffs/jffs2
- * partition.
- */
-static struct mtd_partition db1x00_partitions[] = {
-        {
-                .name         =  "User FS",
-                .size         =  0x1c00000,
-                .offset       =  0x0000000
-        },{
-                .name         =  "yamon",
-                .size         =  0x0100000,
-		.offset       =  MTDPART_OFS_APPEND,
-                .mask_flags   =  MTD_WRITEABLE
-        },{
-                .name         =  "raw kernel",
-		.size         =  (0x300000-0x40000), /* last 256KB is env */
-		.offset       =  MTDPART_OFS_APPEND,
-        }
-};
-#elif defined(DB1X00_BOOT_ONLY)
-static struct mtd_partition db1x00_partitions[] = {
-        {
-                .name         =  "User FS",
-                .size         =  0x00c00000,
-                .offset       =  0x0000000
-        },{
-                .name         =  "yamon",
-                .size         =  0x0100000,
-		.offset       =  MTDPART_OFS_APPEND,
-                .mask_flags   =  MTD_WRITEABLE
-        },{
-                .name         =  "raw kernel",
-		.size         =  (0x300000-0x40000), /* last 256KB is env */
-		.offset       =  MTDPART_OFS_APPEND,
-        }
-};
-#elif defined(DB1X00_USER_ONLY)
-static struct mtd_partition db1x00_partitions[] = {
-        {
-                .name         =  "User FS",
-                .size         =  0x0e00000,
-                .offset       =  0x0000000
-        },{
-                .name         =  "raw kernel",
-		.size         =  MTDPART_SIZ_FULL,
-		.offset       =  MTDPART_OFS_APPEND,
-        }
-};
-#else
-#error MTD_DB1X00 define combo error /* should never happen */
-#endif
-#define NB_OF(x)  (sizeof(x)/sizeof(x[0]))
-
-#define NAME     	"Db1x00 Linux Flash"
-
-static struct map_info db1xxx_mtd_map = {
-	.name		= NAME,
-};
-
-static struct mtd_partition *parsed_parts;
-static struct mtd_info *db1xxx_mtd;
-
-/*
- * Probe the flash density and setup window address and size
- * based on user CONFIG options. There are times when we don't
- * want the MTD driver to be probing the boot or user flash,
- * so having the option to enable only one bank is important.
- */
-int setup_flash_params(void)
-{
-	switch ((bcsr[2] >> 14) & 0x3) {
-		case 0: /* 64Mbit devices */
-			flash_size = 0x800000; /* 8MB per part */
-#if defined(DB1X00_BOTH_BANKS)
-			window_addr = 0x1E000000;
-			window_size = 0x2000000; 
-#elif defined(DB1X00_BOOT_ONLY)
-			window_addr = 0x1F000000;
-			window_size = 0x1000000; 
-#else /* USER ONLY */
-			window_addr = 0x1E000000;
-			window_size = 0x1000000; 
-#endif
-			break;
-		case 1:
-			/* 128 Mbit devices */
-			flash_size = 0x1000000; /* 16MB per part */
-#if defined(DB1X00_BOTH_BANKS)
-			window_addr = 0x1C000000;
-			window_size = 0x4000000;
-			/* USERFS from 0x1C00 0000 to 0x1FC0 0000 */
-			db1x00_partitions[0].size = 0x3C00000;
-#elif defined(DB1X00_BOOT_ONLY)
-			window_addr = 0x1E000000;
-			window_size = 0x2000000;
-			/* USERFS from 0x1E00 0000 to 0x1FC0 0000 */
-			db1x00_partitions[0].size = 0x1C00000;
-#else /* USER ONLY */
-			window_addr = 0x1C000000;
-			window_size = 0x2000000;
-			/* USERFS from 0x1C00 0000 to 0x1DE00000 */
-			db1x00_partitions[0].size = 0x1DE0000;
-#endif
-			break;
-		case 2:
-			/* 256 Mbit devices */
-			flash_size = 0x4000000; /* 64MB per part */
-#if defined(DB1X00_BOTH_BANKS)
-			return 1;
-#elif defined(DB1X00_BOOT_ONLY)
-			/* Boot ROM flash bank only; no user bank */
-			window_addr = 0x1C000000;
-			window_size = 0x4000000;
-			/* USERFS from 0x1C00 0000 to 0x1FC00000 */
-			db1x00_partitions[0].size = 0x3C00000;
-#else /* USER ONLY */
-			return 1;
-#endif
-			break;
-		default:
-			return 1;
-	}
-	db1xxx_mtd_map.size = window_size;
-	db1xxx_mtd_map.bankwidth = flash_bankwidth;
-	db1xxx_mtd_map.phys = window_addr;
-	db1xxx_mtd_map.bankwidth = flash_bankwidth;
-	return 0;
-}
-
-int __init db1x00_mtd_init(void)
-{
-	struct mtd_partition *parts;
-	int nb_parts = 0;
-	
-	if (setup_flash_params()) 
-		return -ENXIO;
-
-	/*
-	 * Static partition definition selection
-	 */
-	parts = db1x00_partitions;
-	nb_parts = NB_OF(db1x00_partitions);
-
-	/*
-	 * Now let's probe for the actual flash.  Do it here since
-	 * specific machine settings might have been set above.
-	 */
-	printk(KERN_NOTICE "Db1xxx flash: probing %d-bit flash bus\n", 
-			db1xxx_mtd_map.bankwidth*8);
-	db1xxx_mtd_map.virt = ioremap(window_addr, window_size);
-	db1xxx_mtd = do_map_probe("cfi_probe", &db1xxx_mtd_map);
-	if (!db1xxx_mtd) return -ENXIO;
-	db1xxx_mtd->owner = THIS_MODULE;
-
-	add_mtd_partitions(db1xxx_mtd, parts, nb_parts);
-	return 0;
-}
-
-static void __exit db1x00_mtd_cleanup(void)
-{
-	if (db1xxx_mtd) {
-		del_mtd_partitions(db1xxx_mtd);
-		map_destroy(db1xxx_mtd);
-		if (parsed_parts)
-			kfree(parsed_parts);
-	}
-}
-
-module_init(db1x00_mtd_init);
-module_exit(db1x00_mtd_cleanup);
-
-MODULE_AUTHOR("Pete Popov");
-MODULE_DESCRIPTION("Db1x00 mtd map driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/mtd/maps/elan-104nc.c b/drivers/mtd/maps/elan-104nc.c
deleted file mode 100644
--- a/drivers/mtd/maps/elan-104nc.c
+++ /dev/null
@@ -1,228 +0,0 @@
-/* elan-104nc.c -- MTD map driver for Arcom Control Systems ELAN-104NC
- 
-   Copyright (C) 2000 Arcom Control System Ltd
- 
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
-   (at your option) any later version.
- 
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
- 
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
-
-   $Id: elan-104nc.c,v 1.25 2004/11/28 09:40:39 dwmw2 Exp $
-
-The ELAN-104NC has up to 8 Mibyte of Intel StrataFlash (28F320/28F640) in x16
-mode.  This drivers uses the CFI probe and Intel Extended Command Set drivers.
-
-The flash is accessed as follows:
-
-   32 kbyte memory window at 0xb0000-0xb7fff
-   
-   16 bit I/O port (0x22) for some sort of paging.
-
-The single flash device is divided into 3 partition which appear as separate
-MTD devices.
-
-Linux thinks that the I/O port is used by the PIC and hence check_region() will
-always fail.  So we don't do it.  I just hope it doesn't break anything.
-*/
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/ioport.h>
-#include <linux/init.h>
-#include <asm/io.h>
-
-#include <linux/mtd/map.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/partitions.h>
-
-#define WINDOW_START 0xb0000
-/* Number of bits in offset. */
-#define WINDOW_SHIFT 15
-#define WINDOW_LENGTH (1 << WINDOW_SHIFT)
-/* The bits for the offset into the window. */
-#define WINDOW_MASK (WINDOW_LENGTH-1)
-#define PAGE_IO 0x22
-#define PAGE_IO_SIZE 2
-
-static volatile int page_in_window = -1; // Current page in window.
-static void __iomem *iomapadr;
-static DEFINE_SPINLOCK(elan_104nc_spin);
-
-/* partition_info gives details on the logical partitions that the split the 
- * single flash device into. If the size if zero we use up to the end of the
- * device. */
-static struct mtd_partition partition_info[]={
-    { .name = "ELAN-104NC flash boot partition", 
-      .offset = 0, 
-      .size = 640*1024 },
-    { .name = "ELAN-104NC flash partition 1", 
-      .offset = 640*1024, 
-      .size = 896*1024 },
-    { .name = "ELAN-104NC flash partition 2", 
-      .offset = (640+896)*1024 }
-};
-#define NUM_PARTITIONS (sizeof(partition_info)/sizeof(partition_info[0]))
-
-/*
- * If no idea what is going on here.  This is taken from the FlashFX stuff.
- */
-#define ROMCS 1
-
-static inline void elan_104nc_setup(void)
-{
-    u16 t;
-
-    outw( 0x0023 + ROMCS*2, PAGE_IO );
-    t=inb( PAGE_IO+1 );
-
-    t=(t & 0xf9) | 0x04;
-
-    outw( ((0x0023 + ROMCS*2) | (t << 8)), PAGE_IO );
-}
-
-static inline void elan_104nc_page(struct map_info *map, unsigned long ofs)
-{
-	unsigned long page = ofs >> WINDOW_SHIFT;
-       
-	if( page!=page_in_window ) {
-		int cmd1;
-		int cmd2;
-
-		cmd1=(page & 0x700) + 0x0833 + ROMCS*0x4000;
-		cmd2=((page & 0xff) << 8) + 0x0032;
-
-		outw( cmd1, PAGE_IO );
-		outw( cmd2, PAGE_IO );
-
-		page_in_window = page;
-	}
-}
-
-
-static map_word elan_104nc_read16(struct map_info *map, unsigned long ofs)
-{
-	map_word ret;
-	spin_lock(&elan_104nc_spin);
-	elan_104nc_page(map, ofs);
-	ret.x[0] = readw(iomapadr + (ofs & WINDOW_MASK));
-	spin_unlock(&elan_104nc_spin);
-	return ret;
-}
-
-static void elan_104nc_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
-{
-	while (len) {
-		unsigned long thislen = len;
-		if (len > (WINDOW_LENGTH - (from & WINDOW_MASK)))
-			thislen = WINDOW_LENGTH-(from & WINDOW_MASK);
-		
-		spin_lock(&elan_104nc_spin);
-		elan_104nc_page(map, from);
-		memcpy_fromio(to, iomapadr + (from & WINDOW_MASK), thislen);
-		spin_unlock(&elan_104nc_spin);
-		to += thislen;
-		from += thislen;
-		len -= thislen;
-	}
-}
-
-static void elan_104nc_write16(struct map_info *map, map_word d, unsigned long adr)
-{
-	spin_lock(&elan_104nc_spin);
-	elan_104nc_page(map, adr);
-	writew(d.x[0], iomapadr + (adr & WINDOW_MASK));
-	spin_unlock(&elan_104nc_spin);
-}
-
-static void elan_104nc_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
-{	
-	while(len) {
-		unsigned long thislen = len;
-		if (len > (WINDOW_LENGTH - (to & WINDOW_MASK)))
-			thislen = WINDOW_LENGTH-(to & WINDOW_MASK);
-		
-		spin_lock(&elan_104nc_spin);
-		elan_104nc_page(map, to);
-		memcpy_toio(iomapadr + (to & WINDOW_MASK), from, thislen);
-		spin_unlock(&elan_104nc_spin);
-		to += thislen;
-		from += thislen;
-		len -= thislen;
-	}
-}
-
-static struct map_info elan_104nc_map = {
-	.name = "ELAN-104NC flash",
-	.phys = NO_XIP,
-	.size = 8*1024*1024, /* this must be set to a maximum possible amount
-			of flash so the cfi probe routines find all
-			the chips */
-	.bankwidth = 2,
-	.read = elan_104nc_read16,
-	.copy_from = elan_104nc_copy_from,
-	.write = elan_104nc_write16,
-	.copy_to = elan_104nc_copy_to
-};
-
-/* MTD device for all of the flash. */
-static struct mtd_info *all_mtd;
-
-static void cleanup_elan_104nc(void)
-{
-	if( all_mtd ) {
-		del_mtd_partitions( all_mtd );
-		map_destroy( all_mtd );
-	}
-
-	iounmap(iomapadr);
-}
-
-static int __init init_elan_104nc(void)
-{
-	/* Urg! We use I/O port 0x22 without request_region()ing it,
-	   because it's already allocated to the PIC. */
-
-  	iomapadr = ioremap(WINDOW_START, WINDOW_LENGTH);
-	if (!iomapadr) {
-		printk( KERN_ERR"%s: failed to ioremap memory region\n",
-			elan_104nc_map.name );
-		return -EIO;
-	}
-
-	printk( KERN_INFO"%s: IO:0x%x-0x%x MEM:0x%x-0x%x\n",
-		elan_104nc_map.name,
-		PAGE_IO, PAGE_IO+PAGE_IO_SIZE-1,
-		WINDOW_START, WINDOW_START+WINDOW_LENGTH-1 );
-
-	elan_104nc_setup();
-
-	/* Probe for chip. */
-	all_mtd = do_map_probe("cfi_probe",  &elan_104nc_map );
-	if( !all_mtd ) {
-		cleanup_elan_104nc();
-		return -ENXIO;
-	}
-	
-	all_mtd->owner = THIS_MODULE;
-
-	/* Create MTD devices for each partition. */
-	add_mtd_partitions( all_mtd, partition_info, NUM_PARTITIONS );
-
-	return 0;
-}
-
-module_init(init_elan_104nc);
-module_exit(cleanup_elan_104nc);
-
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Arcom Control Systems Ltd.");
-MODULE_DESCRIPTION("MTD map driver for Arcom Control Systems ELAN-104NC");
diff --git a/drivers/mtd/maps/ichxrom.c b/drivers/mtd/maps/ichxrom.c
--- a/drivers/mtd/maps/ichxrom.c
+++ b/drivers/mtd/maps/ichxrom.c
@@ -2,7 +2,7 @@
  * ichxrom.c
  *
  * Normal mappings of chips in physical memory
- * $Id: ichxrom.c,v 1.16 2004/11/28 09:40:39 dwmw2 Exp $
+ * $Id: ichxrom.c,v 1.18 2005/07/07 10:26:20 dwmw2 Exp $
  */
 
 #include <linux/module.h>
@@ -338,9 +338,9 @@ static struct pci_device_id ichxrom_pci_
 	{ 0, },
 };
 
+#if 0
 MODULE_DEVICE_TABLE(pci, ichxrom_pci_tbl);
 
-#if 0
 static struct pci_driver ichxrom_driver = {
 	.name =		MOD_NAME,
 	.id_table =	ichxrom_pci_tbl,
@@ -366,7 +366,7 @@ static int __init init_ichxrom(void)
 	}
 	return -ENXIO;
 #if 0
-	return pci_module_init(&ichxrom_driver);
+	return pci_register_driver(&ichxrom_driver);
 #endif
 }
 
diff --git a/drivers/mtd/maps/ixp2000.c b/drivers/mtd/maps/ixp2000.c
--- a/drivers/mtd/maps/ixp2000.c
+++ b/drivers/mtd/maps/ixp2000.c
@@ -1,5 +1,5 @@
 /*
- * $Id: ixp2000.c,v 1.5 2004/11/16 17:15:48 dsaxena Exp $
+ * $Id: ixp2000.c,v 1.6 2005/03/18 14:07:46 gleixner Exp $
  *
  * drivers/mtd/maps/ixp2000.c
  *
@@ -216,11 +216,6 @@ static int ixp2000_flash_probe(struct de
 		goto Error;
 	}
 
-	/*
-	 * Setup read mode for FLASH
-	 */
-	*IXP2000_SLOWPORT_FRM = 1;
-
 #if defined(__ARMEB__)
 	/*
 	 * Enable erratum 44 workaround for NPUs with broken slowport
diff --git a/drivers/mtd/maps/mainstone-flash.c b/drivers/mtd/maps/mainstone-flash.c
new file mode 100644
--- /dev/null
+++ b/drivers/mtd/maps/mainstone-flash.c
@@ -0,0 +1,178 @@
+/*
+ * $Id:  $
+ *
+ * Map driver for the Mainstone developer platform.
+ *
+ * Author:	Nicolas Pitre
+ * Copyright:	(C) 2001 MontaVista Software Inc.
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/dma-mapping.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+#include <asm/io.h>
+#include <asm/hardware.h>
+#include <asm/arch/pxa-regs.h>
+#include <asm/arch/mainstone.h>
+
+
+#define ROM_ADDR	0x00000000
+#define FLASH_ADDR	0x04000000
+
+#define WINDOW_SIZE 	0x04000000
+
+static void mainstone_map_inval_cache(struct map_info *map, unsigned long from,
+				      ssize_t len)
+{
+	consistent_sync((char *)map->cached + from, len, DMA_FROM_DEVICE);
+}
+
+static struct map_info mainstone_maps[2] = { {
+	.size =		WINDOW_SIZE,
+	.phys =		PXA_CS0_PHYS,
+	.inval_cache = 	mainstone_map_inval_cache,
+}, {
+	.size =		WINDOW_SIZE,
+	.phys =		PXA_CS1_PHYS,
+	.inval_cache = 	mainstone_map_inval_cache,
+} };
+
+static struct mtd_partition mainstone_partitions[] = {
+	{
+		.name =		"Bootloader",
+		.size =		0x00040000,
+		.offset =	0,
+		.mask_flags =	MTD_WRITEABLE  /* force read-only */
+	},{
+		.name =		"Kernel",
+		.size =		0x00400000,
+		.offset =	0x00040000,
+	},{
+		.name =		"Filesystem",
+		.size =		MTDPART_SIZ_FULL,
+		.offset =	0x00440000
+	}
+};
+
+static struct mtd_info *mymtds[2];
+static struct mtd_partition *parsed_parts[2];
+static int nr_parsed_parts[2];
+
+static const char *probes[] = { "RedBoot", "cmdlinepart", NULL };
+
+static int __init init_mainstone(void)
+{
+	int SW7 = 0;  /* FIXME: get from SCR (Mst doc section 3.2.1.1) */
+	int ret = 0, i;
+
+	mainstone_maps[0].bankwidth = (BOOT_DEF & 1) ? 2 : 4;
+	mainstone_maps[1].bankwidth = 4;
+
+	/* Compensate for SW7 which swaps the flash banks */
+	mainstone_maps[SW7].name = "processor flash";
+	mainstone_maps[SW7 ^ 1].name = "main board flash";
+
+	printk(KERN_NOTICE "Mainstone configured to boot from %s\n",
+	       mainstone_maps[0].name);
+
+	for (i = 0; i < 2; i++) {
+		mainstone_maps[i].virt = ioremap(mainstone_maps[i].phys,
+						 WINDOW_SIZE);
+		if (!mainstone_maps[i].virt) {
+			printk(KERN_WARNING "Failed to ioremap %s\n", 
+			       mainstone_maps[i].name);
+			if (!ret)
+				ret = -ENOMEM;
+			continue;
+		}
+		mainstone_maps[i].cached = 
+			ioremap_cached(mainstone_maps[i].phys, WINDOW_SIZE);
+		if (!mainstone_maps[i].cached)
+			printk(KERN_WARNING "Failed to ioremap cached %s\n",
+			       mainstone_maps[i].name);
+		simple_map_init(&mainstone_maps[i]);
+
+		printk(KERN_NOTICE 
+		       "Probing %s at physical address 0x%08lx"
+		       " (%d-bit bankwidth)\n",
+		       mainstone_maps[i].name, mainstone_maps[i].phys, 
+		       mainstone_maps[i].bankwidth * 8);
+
+		mymtds[i] = do_map_probe("cfi_probe", &mainstone_maps[i]);
+		
+		if (!mymtds[i]) {
+			iounmap((void *)mainstone_maps[i].virt);
+			if (mainstone_maps[i].cached)
+				iounmap(mainstone_maps[i].cached);
+			if (!ret)
+				ret = -EIO;
+			continue;
+		}
+		mymtds[i]->owner = THIS_MODULE;
+
+		ret = parse_mtd_partitions(mymtds[i], probes,
+					   &parsed_parts[i], 0);
+
+		if (ret > 0)
+			nr_parsed_parts[i] = ret;
+	}
+
+	if (!mymtds[0] && !mymtds[1])
+		return ret;
+	
+	for (i = 0; i < 2; i++) {
+		if (!mymtds[i]) {
+			printk(KERN_WARNING "%s is absent. Skipping\n", 
+			       mainstone_maps[i].name);
+		} else if (nr_parsed_parts[i]) {
+			add_mtd_partitions(mymtds[i], parsed_parts[i], 
+					   nr_parsed_parts[i]);
+		} else if (!i) {
+			printk("Using static partitions on %s\n",
+			       mainstone_maps[i].name);
+			add_mtd_partitions(mymtds[i], mainstone_partitions, 
+					   ARRAY_SIZE(mainstone_partitions));
+		} else {
+			printk("Registering %s as whole device\n", 
+			       mainstone_maps[i].name);
+			add_mtd_device(mymtds[i]);
+		}
+	}
+	return 0;
+}
+
+static void __exit cleanup_mainstone(void)
+{
+	int i;
+	for (i = 0; i < 2; i++) {
+		if (!mymtds[i])
+			continue;
+
+		if (nr_parsed_parts[i] || !i)
+			del_mtd_partitions(mymtds[i]);
+		else
+			del_mtd_device(mymtds[i]);
+
+		map_destroy(mymtds[i]);
+		iounmap((void *)mainstone_maps[i].virt);
+		if (mainstone_maps[i].cached)
+			iounmap(mainstone_maps[i].cached);
+		kfree(parsed_parts[i]);
+	}
+}
+
+module_init(init_mainstone);
+module_exit(cleanup_mainstone);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Nicolas Pitre <nico@cam.org>");
+MODULE_DESCRIPTION("MTD map driver for Intel Mainstone");
diff --git a/drivers/mtd/maps/map_funcs.c b/drivers/mtd/maps/map_funcs.c
--- a/drivers/mtd/maps/map_funcs.c
+++ b/drivers/mtd/maps/map_funcs.c
@@ -1,5 +1,5 @@
 /*
- * $Id: map_funcs.c,v 1.9 2004/07/13 22:33:15 dwmw2 Exp $
+ * $Id: map_funcs.c,v 1.10 2005/06/06 23:04:36 tpoynor Exp $
  *
  * Out-of-line map I/O functions for simple maps when CONFIG_COMPLEX_MAPPINGS
  * is enabled.
@@ -9,23 +9,24 @@
 #include <linux/module.h>
 
 #include <linux/mtd/map.h>
+#include <linux/mtd/xip.h>
 
-static map_word simple_map_read(struct map_info *map, unsigned long ofs)
+static map_word __xipram simple_map_read(struct map_info *map, unsigned long ofs)
 {
 	return inline_map_read(map, ofs);
 }
 
-static void simple_map_write(struct map_info *map, const map_word datum, unsigned long ofs)
+static void __xipram simple_map_write(struct map_info *map, const map_word datum, unsigned long ofs)
 {
 	inline_map_write(map, datum, ofs);
 }
 
-static void simple_map_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
+static void __xipram simple_map_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
 {
 	inline_map_copy_from(map, to, from, len);
 }
 
-static void simple_map_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
+static void __xipram simple_map_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
 {
 	inline_map_copy_to(map, to, from, len);
 }
diff --git a/drivers/mtd/maps/omap_nor.c b/drivers/mtd/maps/omap_nor.c
new file mode 100644
--- /dev/null
+++ b/drivers/mtd/maps/omap_nor.c
@@ -0,0 +1,179 @@
+/*
+ * Flash memory support for various TI OMAP boards
+ *
+ * Copyright (C) 2001-2002 MontaVista Software Inc.
+ * Copyright (C) 2003-2004 Texas Instruments
+ * Copyright (C) 2004 Nokia Corporation 
+ *
+ *	Assembled using driver code copyright the companies above
+ *	and written by David Brownell, Jian Zhang <jzhang@ti.com>,
+ * 	Tony Lindgren <tony@atomide.com> and others.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the  GNU General Public License along
+ * with this program; if not, write  to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/io.h>
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/flash.h>
+#include <asm/arch/tc.h>
+
+#ifdef CONFIG_MTD_PARTITIONS
+static const char *part_probes[] = { /* "RedBoot", */ "cmdlinepart", NULL };
+#endif
+
+struct omapflash_info {
+	struct mtd_partition	*parts;
+	struct mtd_info		*mtd;
+	struct map_info		map;
+};
+
+static void omap_set_vpp(struct map_info *map, int enable)
+{
+	static int	count;
+
+	if (enable) {
+		if (count++ == 0)
+			OMAP_EMIFS_CONFIG_REG |= OMAP_EMIFS_CONFIG_WP;
+	} else {
+		if (count && (--count == 0))
+			OMAP_EMIFS_CONFIG_REG &= ~OMAP_EMIFS_CONFIG_WP;
+	}
+}
+
+static int __devinit omapflash_probe(struct device *dev)
+{
+	int err;
+	struct omapflash_info *info;
+	struct platform_device *pdev = to_platform_device(dev);
+	struct flash_platform_data *pdata = pdev->dev.platform_data;
+	struct resource *res = pdev->resource;
+	unsigned long size = res->end - res->start + 1;
+
+	info = kmalloc(sizeof(struct omapflash_info), GFP_KERNEL);
+	if (!info)
+		return -ENOMEM;
+
+	memset(info, 0, sizeof(struct omapflash_info));
+
+	if (!request_mem_region(res->start, size, "flash")) {
+		err = -EBUSY;
+		goto out_free_info;
+	}
+
+	info->map.virt		= ioremap(res->start, size);
+	if (!info->map.virt) {
+		err = -ENOMEM;
+		goto out_release_mem_region;
+	}
+	info->map.name		= pdev->dev.bus_id;
+	info->map.phys		= res->start;
+	info->map.size		= size;
+	info->map.bankwidth	= pdata->width;
+	info->map.set_vpp	= omap_set_vpp;
+
+	simple_map_init(&info->map);
+	info->mtd = do_map_probe(pdata->map_name, &info->map);
+	if (!info->mtd) {
+		err = -EIO;
+		goto out_iounmap;
+	}
+	info->mtd->owner = THIS_MODULE;
+
+#ifdef CONFIG_MTD_PARTITIONS
+	err = parse_mtd_partitions(info->mtd, part_probes, &info->parts, 0);
+	if (err > 0)
+		add_mtd_partitions(info->mtd, info->parts, err);
+	else if (err < 0 && pdata->parts)
+		add_mtd_partitions(info->mtd, pdata->parts, pdata->nr_parts);
+	else
+#endif
+		add_mtd_device(info->mtd);
+
+	dev_set_drvdata(&pdev->dev, info);
+
+	return 0;
+
+out_iounmap:
+	iounmap(info->map.virt);
+out_release_mem_region:
+	release_mem_region(res->start, size);
+out_free_info:
+	kfree(info);
+
+	return err;
+}
+
+static int __devexit omapflash_remove(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct omapflash_info *info = dev_get_drvdata(&pdev->dev);
+
+	dev_set_drvdata(&pdev->dev, NULL);
+
+	if (info) {
+		if (info->parts) {
+			del_mtd_partitions(info->mtd);
+			kfree(info->parts);
+		} else
+			del_mtd_device(info->mtd);
+		map_destroy(info->mtd);
+		release_mem_region(info->map.phys, info->map.size);
+		iounmap((void __iomem *) info->map.virt);
+		kfree(info);
+	}
+
+	return 0;
+}
+
+static struct device_driver omapflash_driver = {
+	.name	= "omapflash",
+	.bus	= &platform_bus_type,
+	.probe	= omapflash_probe,
+	.remove	= __devexit_p(omapflash_remove),
+};
+
+static int __init omapflash_init(void)
+{
+	return driver_register(&omapflash_driver);
+}
+
+static void __exit omapflash_exit(void)
+{
+	driver_unregister(&omapflash_driver);
+}
+
+module_init(omapflash_init);
+module_exit(omapflash_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("MTD NOR map driver for TI OMAP boards");
+
diff --git a/drivers/mtd/maps/pb1550-flash.c b/drivers/mtd/maps/pb1550-flash.c
deleted file mode 100644
--- a/drivers/mtd/maps/pb1550-flash.c
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * Flash memory access on Alchemy Pb1550 board
- * 
- * $Id: pb1550-flash.c,v 1.6 2004/11/04 13:24:15 gleixner Exp $
- *
- * (C) 2004 Embedded Edge, LLC, based on pb1550-flash.c:
- * (C) 2003 Pete Popov <ppopov@pacbell.net>
- * 
- */
-
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/map.h>
-#include <linux/mtd/partitions.h>
-
-#include <asm/io.h>
-#include <asm/au1000.h>
-#include <asm/pb1550.h>
-
-#ifdef 	DEBUG_RW
-#define	DBG(x...)	printk(x)
-#else
-#define	DBG(x...)	
-#endif
-
-static unsigned long window_addr;
-static unsigned long window_size;
-
-
-static struct map_info pb1550_map = {
-	.name =	"Pb1550 flash",
-};
-
-static unsigned char flash_bankwidth = 4;
-
-/* 
- * Support only 64MB NOR Flash parts
- */
-
-#ifdef PB1550_BOTH_BANKS
-/* both banks will be used. Combine the first bank and the first 
- * part of the second bank together into a single jffs/jffs2
- * partition.
- */
-static struct mtd_partition pb1550_partitions[] = {
-	/* assume boot[2:0]:swap is '0000' or '1000', which translates to:
-	 * 1C00 0000 1FFF FFFF CE0 64MB Boot NOR Flash
-	 * 1800 0000 1BFF FFFF CE0 64MB Param NOR Flash
-	 */
-        {
-                .name = "User FS",
-                .size =   (0x1FC00000 - 0x18000000),
-                .offset = 0x0000000
-        },{
-                .name = "yamon",
-                .size = 0x0100000,
-		.offset = MTDPART_OFS_APPEND,
-                .mask_flags = MTD_WRITEABLE
-        },{
-                .name = "raw kernel",
-		.size = (0x300000 - 0x40000), /* last 256KB is yamon env */
-		.offset = MTDPART_OFS_APPEND,
-        }
-};
-#elif defined(PB1550_BOOT_ONLY)
-static struct mtd_partition pb1550_partitions[] = {
-	/* assume boot[2:0]:swap is '0000' or '1000', which translates to:
-	 * 1C00 0000 1FFF FFFF CE0 64MB Boot NOR Flash
-	 */
-        {
-                .name = "User FS",
-                .size =   0x03c00000,
-                .offset = 0x0000000
-        },{
-                .name = "yamon",
-                .size = 0x0100000,
-		.offset = MTDPART_OFS_APPEND,
-                .mask_flags = MTD_WRITEABLE
-        },{
-                .name = "raw kernel",
-		.size = (0x300000-0x40000), /* last 256KB is yamon env */
-		.offset = MTDPART_OFS_APPEND,
-        }
-};
-#elif defined(PB1550_USER_ONLY)
-static struct mtd_partition pb1550_partitions[] = {
-	/* assume boot[2:0]:swap is '0000' or '1000', which translates to:
-	 * 1800 0000 1BFF FFFF CE0 64MB Param NOR Flash
-	 */
-        {
-                .name = "User FS",
-                .size = (0x4000000 - 0x200000), /* reserve 2MB for raw kernel */
-                .offset = 0x0000000
-        },{
-                .name = "raw kernel",
-		.size = MTDPART_SIZ_FULL,
-		.offset = MTDPART_OFS_APPEND,
-        }
-};
-#else
-#error MTD_PB1550 define combo error /* should never happen */
-#endif
-
-#define NB_OF(x)  (sizeof(x)/sizeof(x[0]))
-
-static struct mtd_info *mymtd;
-
-/*
- * Probe the flash density and setup window address and size
- * based on user CONFIG options. There are times when we don't
- * want the MTD driver to be probing the boot or user flash,
- * so having the option to enable only one bank is important.
- */
-int setup_flash_params(void)
-{
-	u16 boot_swapboot;
-	boot_swapboot = (au_readl(MEM_STSTAT) & (0x7<<1)) | 
-		((bcsr->status >> 6)  & 0x1);
-	printk("Pb1550 MTD: boot:swap %d\n", boot_swapboot);
-
-	switch (boot_swapboot) {
-		case 0: /* 512Mbit devices, both enabled */
-		case 1: 
-		case 8:
-		case 9: 
-#if defined(PB1550_BOTH_BANKS)
-			window_addr = 0x18000000;
-			window_size = 0x8000000; 
-#elif defined(PB1550_BOOT_ONLY)
-			window_addr = 0x1C000000;
-			window_size = 0x4000000; 
-#else /* USER ONLY */
-			window_addr = 0x1E000000;
-			window_size = 0x4000000; 
-#endif
-			break;
-		case 0xC:
-		case 0xD:
-		case 0xE:
-		case 0xF: 
-			/* 64 MB Boot NOR Flash is disabled */
-			/* and the start address is moved to 0x0C00000 */
-			window_addr = 0x0C000000;
-			window_size = 0x4000000; 
-		default:
-			printk("Pb1550 MTD: unsupported boot:swap setting\n");
-			return 1;
-	}
-	return 0;
-}
-
-int __init pb1550_mtd_init(void)
-{
-	struct mtd_partition *parts;
-	int nb_parts = 0;
-	
-	/* Default flash bankwidth */
-	pb1550_map.bankwidth = flash_bankwidth;
-
-	if (setup_flash_params()) 
-		return -ENXIO;
-
-	/*
-	 * Static partition definition selection
-	 */
-	parts = pb1550_partitions;
-	nb_parts = NB_OF(pb1550_partitions);
-	pb1550_map.size = window_size;
-
-	/*
-	 * Now let's probe for the actual flash.  Do it here since
-	 * specific machine settings might have been set above.
-	 */
-	printk(KERN_NOTICE "Pb1550 flash: probing %d-bit flash bus\n", 
-			pb1550_map.bankwidth*8);
-	pb1550_map.virt = ioremap(window_addr, window_size);
-	mymtd = do_map_probe("cfi_probe", &pb1550_map);
-	if (!mymtd) return -ENXIO;
-	mymtd->owner = THIS_MODULE;
-
-	add_mtd_partitions(mymtd, parts, nb_parts);
-	return 0;
-}
-
-static void __exit pb1550_mtd_cleanup(void)
-{
-	if (mymtd) {
-		del_mtd_partitions(mymtd);
-		map_destroy(mymtd);
-	}
-}
-
-module_init(pb1550_mtd_init);
-module_exit(pb1550_mtd_cleanup);
-
-MODULE_AUTHOR("Embedded Edge, LLC");
-MODULE_DESCRIPTION("Pb1550 mtd map driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/mtd/maps/pb1xxx-flash.c b/drivers/mtd/maps/pb1xxx-flash.c
deleted file mode 100644
--- a/drivers/mtd/maps/pb1xxx-flash.c
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * Flash memory access on Alchemy Pb1xxx boards
- * 
- * (C) 2001 Pete Popov <ppopov@mvista.com>
- * 
- * $Id: pb1xxx-flash.c,v 1.14 2004/11/04 13:24:15 gleixner Exp $
- */
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/map.h>
-#include <linux/mtd/partitions.h>
-
-#include <asm/io.h>
-
-#ifdef 	DEBUG_RW
-#define	DBG(x...)	printk(x)
-#else
-#define	DBG(x...)	
-#endif
-
-#ifdef CONFIG_MIPS_PB1000
-
-#define WINDOW_ADDR 0x1F800000
-#define WINDOW_SIZE 0x800000
-
-static struct mtd_partition pb1xxx_partitions[] = {
-        {
-                .name         =  "yamon env",
-                .size         =   0x00020000,
-                .offset       =   0,
-                .mask_flags   =   MTD_WRITEABLE},
-	{
-                .name         =   "User FS",
-                .size         =   0x003e0000,
-                .offset       =   0x20000,},
-	{
-                .name         =   "boot code",
-                .size         =   0x100000,
-                .offset       =   0x400000,
-                .mask_flags   =   MTD_WRITEABLE},
-	{
-                .name         =   "raw/kernel",
-                .size         =   0x300000,
-                .offset       =   0x500000}
-};
-
-#elif defined(CONFIG_MIPS_PB1500) || defined(CONFIG_MIPS_PB1100)
-
-#if defined(CONFIG_MTD_PB1500_BOOT) && defined(CONFIG_MTD_PB1500_USER)
-/* both 32MB banks will be used. Combine the first 32MB bank and the
- * first 28MB of the second bank together into a single jffs/jffs2
- * partition.
- */
-#define WINDOW_ADDR 0x1C000000
-#define WINDOW_SIZE 0x4000000
-static struct mtd_partition pb1xxx_partitions[] = {
-        {
-                .name         =   "User FS",
-                .size         =   0x3c00000,
-                .offset       =   0x0000000
-        },{
-                .name         =   "yamon",
-                .size         =   0x0100000,
-                .offset       =   0x3c00000,
-                .mask_flags   =   MTD_WRITEABLE
-        },{
-                .name         =   "raw kernel",
-                .size         =   0x02c0000,
-                .offset       =   0x3d00000
-        }
-};
-#elif defined(CONFIG_MTD_PB1500_BOOT) && !defined(CONFIG_MTD_PB1500_USER)
-#define WINDOW_ADDR 0x1E000000
-#define WINDOW_SIZE 0x2000000
-static struct mtd_partition pb1xxx_partitions[] = {
-        {
-                .name         =   "User FS",
-                .size         =   0x1c00000,
-                .offset       =   0x0000000
-        },{
-                .name         =   "yamon",
-                .size         =   0x0100000,
-                .offset       =   0x1c00000,
-                .mask_flags   =   MTD_WRITEABLE
-        },{
-                .name         =   "raw kernel",
-                .size         =   0x02c0000,
-                .offset       =   0x1d00000
-        }
-};
-#elif !defined(CONFIG_MTD_PB1500_BOOT) && defined(CONFIG_MTD_PB1500_USER)
-#define WINDOW_ADDR 0x1C000000
-#define WINDOW_SIZE 0x2000000
-static struct mtd_partition pb1xxx_partitions[] = {
-        {
-                .name         =   "User FS",
-                .size         =    0x1e00000,
-                .offset       =    0x0000000
-        },{
-                .name         =    "raw kernel",
-                .size         =    0x0200000,
-                .offset       =    0x1e00000,
-        }
-};
-#else
-#error MTD_PB1500 define combo error /* should never happen */
-#endif
-#else
-#error Unsupported board
-#endif
-
-#define NAME     	"Pb1x00 Linux Flash"
-#define PADDR    	WINDOW_ADDR
-#define BUSWIDTH	4
-#define SIZE		WINDOW_SIZE
-#define PARTITIONS	4
-
-static struct map_info pb1xxx_mtd_map = {
-	.name		= NAME,
-	.size		= SIZE,
-	.bankwidth	= BUSWIDTH,
-	.phys		= PADDR,
-};
-
-static struct mtd_info *pb1xxx_mtd;
-
-int __init pb1xxx_mtd_init(void)
-{
-	struct mtd_partition *parts;
-	int nb_parts = 0;
-	char *part_type;
-	
-	/*
-	 * Static partition definition selection
-	 */
-	part_type = "static";
-	parts = pb1xxx_partitions;
-	nb_parts = ARRAY_SIZE(pb1xxx_partitions);
-
-	/*
-	 * Now let's probe for the actual flash.  Do it here since
-	 * specific machine settings might have been set above.
-	 */
-	printk(KERN_NOTICE "Pb1xxx flash: probing %d-bit flash bus\n", 
-			BUSWIDTH*8);
-	pb1xxx_mtd_map.virt = ioremap(WINDOW_ADDR, WINDOW_SIZE);
-
-	simple_map_init(&pb1xxx_mtd_map);
-
-	pb1xxx_mtd = do_map_probe("cfi_probe", &pb1xxx_mtd_map);
-	if (!pb1xxx_mtd) return -ENXIO;
-	pb1xxx_mtd->owner = THIS_MODULE;
-
-	add_mtd_partitions(pb1xxx_mtd, parts, nb_parts);
-	return 0;
-}
-
-static void __exit pb1xxx_mtd_cleanup(void)
-{
-	if (pb1xxx_mtd) {
-		del_mtd_partitions(pb1xxx_mtd);
-		map_destroy(pb1xxx_mtd);
-		iounmap((void *) pb1xxx_mtd_map.virt);
-	}
-}
-
-module_init(pb1xxx_mtd_init);
-module_exit(pb1xxx_mtd_cleanup);
-
-MODULE_AUTHOR("Pete Popov");
-MODULE_DESCRIPTION("Pb1xxx CFI map driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/mtd/maps/pci.c b/drivers/mtd/maps/pci.c
--- a/drivers/mtd/maps/pci.c
+++ b/drivers/mtd/maps/pci.c
@@ -7,7 +7,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  *
- *  $Id: pci.c,v 1.9 2004/11/28 09:40:40 dwmw2 Exp $
+ *  $Id: pci.c,v 1.10 2005/03/18 14:04:35 gleixner Exp $
  * 
  * Generic PCI memory map driver.  We support the following boards:
  *  - Intel IQ80310 ATU.
@@ -370,7 +370,7 @@ static struct pci_driver mtd_pci_driver 
 
 static int __init mtd_pci_maps_init(void)
 {
-	return pci_module_init(&mtd_pci_driver);
+	return pci_register_driver(&mtd_pci_driver);
 }
 
 static void __exit mtd_pci_maps_exit(void)
diff --git a/drivers/mtd/maps/pcmciamtd.c b/drivers/mtd/maps/pcmciamtd.c
--- a/drivers/mtd/maps/pcmciamtd.c
+++ b/drivers/mtd/maps/pcmciamtd.c
@@ -18,7 +18,6 @@
 #include <asm/io.h>
 #include <asm/system.h>
 
-#include <pcmcia/version.h>
 #include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
@@ -800,11 +799,6 @@ static dev_link_t *pcmciamtd_attach(void
 
 	/* Register with Card Services */
 	client_reg.dev_info = &dev_info;
-	client_reg.EventMask =
-		CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
-		CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
-		CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
-	client_reg.event_handler = &pcmciamtd_event;
 	client_reg.Version = 0x0210;
 	client_reg.event_callback_args.client_data = link;
 	DEBUG(2, "Calling RegisterClient");
@@ -818,14 +812,42 @@ static dev_link_t *pcmciamtd_attach(void
 	return link;
 }
 
+static struct pcmcia_device_id pcmciamtd_ids[] = {
+	PCMCIA_DEVICE_FUNC_ID(1),
+	PCMCIA_DEVICE_PROD_ID123("IO DATA", "PCS-2M", "2MB SRAM", 0x547e66dc, 0x1fed36cd, 0x36eadd21),
+	PCMCIA_DEVICE_PROD_ID12("IBM", "2MB SRAM", 0xb569a6e5, 0x36eadd21),
+	PCMCIA_DEVICE_PROD_ID12("IBM", "4MB FLASH", 0xb569a6e5, 0x8bc54d2a),
+	PCMCIA_DEVICE_PROD_ID12("IBM", "8MB FLASH", 0xb569a6e5, 0x6df1be3e),
+	PCMCIA_DEVICE_PROD_ID12("Intel", "S2E20SW", 0x816cc815, 0xd14c9dcf),
+	PCMCIA_DEVICE_PROD_ID12("Intel", "S2E8 SW", 0x816cc815, 0xa2d7dedb),
+	PCMCIA_DEVICE_PROD_ID12("intel", "SERIES2-02 ", 0x40ade711, 0x145cea5c),
+	PCMCIA_DEVICE_PROD_ID12("intel", "SERIES2-04 ", 0x40ade711, 0x42064dda),
+	PCMCIA_DEVICE_PROD_ID12("intel", "SERIES2-20 ", 0x40ade711, 0x25ee5cb0),
+	PCMCIA_DEVICE_PROD_ID12("intel", "VALUE SERIES 100 ", 0x40ade711, 0xdf8506d8),
+	PCMCIA_DEVICE_PROD_ID12("KINGMAX TECHNOLOGY INC.", "SRAM 256K Bytes", 0x54d0c69c, 0xad12c29c),
+	PCMCIA_DEVICE_PROD_ID12("Maxtor", "MAXFL MobileMax Flash Memory Card", 0xb68968c8, 0x2dfb47b0),
+	PCMCIA_DEVICE_PROD_ID12("SEIKO EPSON", "WWB101EN20", 0xf9876baf, 0xad0b207b),
+	PCMCIA_DEVICE_PROD_ID12("SEIKO EPSON", "WWB513EN20", 0xf9876baf, 0xe8d884ad),
+	PCMCIA_DEVICE_PROD_ID12("Starfish, Inc.", "REX-3000", 0x05ddca47, 0xe7d67bca),
+	PCMCIA_DEVICE_PROD_ID12("Starfish, Inc.", "REX-4100", 0x05ddca47, 0x7bc32944),
+	/* the following was commented out in pcmcia-cs-3.2.7 */
+	/* PCMCIA_DEVICE_PROD_ID12("RATOC Systems,Inc.", "SmartMedia ADAPTER PC Card", 0xf4a2fefe, 0x5885b2ae), */
+#ifdef CONFIG_MTD_PCMCIA_ANONYMOUS
+	{ .match_flags = PCMCIA_DEV_ID_MATCH_ANONYMOUS, },
+#endif
+	PCMCIA_DEVICE_NULL
+};
+MODULE_DEVICE_TABLE(pcmcia, pcmciamtd_ids);
 
 static struct pcmcia_driver pcmciamtd_driver = {
 	.drv		= {
 		.name	= "pcmciamtd"
 	},
 	.attach		= pcmciamtd_attach,
+	.event		= pcmciamtd_event,
 	.detach		= pcmciamtd_detach,
-	.owner		= THIS_MODULE
+	.owner		= THIS_MODULE,
+	.id_table	= pcmciamtd_ids,
 };
 
 
diff --git a/drivers/mtd/maps/plat-ram.c b/drivers/mtd/maps/plat-ram.c
new file mode 100644
--- /dev/null
+++ b/drivers/mtd/maps/plat-ram.c
@@ -0,0 +1,278 @@
+/* drivers/mtd/maps/plat-ram.c
+ *
+ * (c) 2004-2005 Simtec Electronics
+ *	http://www.simtec.co.uk/products/SWLINUX/
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * Generic platfrom device based RAM map
+ *
+ * $Id: plat-ram.c,v 1.3 2005/03/19 22:41:27 gleixner Exp $
+ *
+ * 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/module.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/ioport.h>
+#include <linux/device.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/plat-ram.h>
+
+#include <asm/io.h>
+
+/* private structure for each mtd platform ram device created */
+
+struct platram_info {
+	struct device		*dev;
+	struct mtd_info		*mtd;
+	struct map_info		 map;
+	struct mtd_partition	*partitions;
+	struct resource		*area;
+	struct platdata_mtd_ram	*pdata;
+};
+
+/* to_platram_info()
+ *
+ * device private data to struct platram_info conversion
+*/
+
+static inline struct platram_info *to_platram_info(struct device *dev)
+{
+	return (struct platram_info *)dev_get_drvdata(dev);
+}
+
+/* platram_setrw
+ *
+ * call the platform device's set rw/ro control
+ *
+ * to = 0 => read-only
+ *    = 1 => read-write
+*/
+
+static inline void platram_setrw(struct platram_info *info, int to)
+{
+	if (info->pdata == NULL)
+		return;
+
+	if (info->pdata->set_rw != NULL)
+		(info->pdata->set_rw)(info->dev, to);
+}
+
+/* platram_remove
+ *
+ * called to remove the device from the driver's control
+*/
+
+static int platram_remove(struct device *dev)
+{
+	struct platram_info *info = to_platram_info(dev);
+
+	dev_set_drvdata(dev, NULL);
+
+	dev_dbg(dev, "removing device\n");
+
+	if (info == NULL) 
+		return 0;
+
+	if (info->mtd) {
+#ifdef CONFIG_MTD_PARTITIONS
+		if (info->partitions) {
+			del_mtd_partitions(info->mtd);
+			kfree(info->partitions);
+		}
+#endif
+		del_mtd_device(info->mtd);
+		map_destroy(info->mtd);
+	}
+
+	/* ensure ram is left read-only */
+
+	platram_setrw(info, PLATRAM_RO);
+
+	/* release resources */
+
+	if (info->area) {
+		release_resource(info->area);
+		kfree(info->area);
+	}
+
+	if (info->map.virt != NULL)
+		iounmap(info->map.virt);
+	
+	kfree(info);
+
+	return 0;
+}
+
+/* platram_probe
+ *
+ * called from device drive system when a device matching our
+ * driver is found.
+*/
+
+static int platram_probe(struct device *dev)
+{
+	struct platform_device *pd = to_platform_device(dev);
+	struct platdata_mtd_ram	*pdata;
+	struct platram_info *info;
+	struct resource *res;
+	int err = 0;
+
+	dev_dbg(dev, "probe entered\n");
+	
+	if (dev->platform_data == NULL) {
+		dev_err(dev, "no platform data supplied\n");
+		err = -ENOENT;
+		goto exit_error;
+	}
+
+	pdata = dev->platform_data;
+
+	info = kmalloc(sizeof(*info), GFP_KERNEL);
+	if (info == NULL) {
+		dev_err(dev, "no memory for flash info\n");
+		err = -ENOMEM;
+		goto exit_error;
+	}
+
+	memset(info, 0, sizeof(*info));
+	dev_set_drvdata(dev, info);
+
+	info->dev = dev;
+	info->pdata = pdata;
+
+	/* get the resource for the memory mapping */
+
+	res = platform_get_resource(pd, IORESOURCE_MEM, 0);
+
+	if (res == NULL) {
+		dev_err(dev, "no memory resource specified\n");
+		err = -ENOENT;
+		goto exit_free;
+	}
+
+	dev_dbg(dev, "got platform resource %p (0x%lx)\n", res, res->start);
+
+	/* setup map parameters */
+
+	info->map.phys = res->start;
+	info->map.size = (res->end - res->start) + 1;
+	info->map.name = pdata->mapname != NULL ? pdata->mapname : pd->name;
+	info->map.bankwidth = pdata->bankwidth;
+
+	/* register our usage of the memory area */
+
+	info->area = request_mem_region(res->start, info->map.size, pd->name);
+	if (info->area == NULL) {
+		dev_err(dev, "failed to request memory region\n");
+		err = -EIO;
+		goto exit_free;
+	}
+
+	/* remap the memory area */
+
+	info->map.virt = ioremap(res->start, info->map.size);
+	dev_dbg(dev, "virt %p, %lu bytes\n", info->map.virt, info->map.size);
+
+	if (info->map.virt == NULL) {
+		dev_err(dev, "failed to ioremap() region\n");
+		err = -EIO;
+		goto exit_free;
+	}
+
+	simple_map_init(&info->map);
+
+	dev_dbg(dev, "initialised map, probing for mtd\n");
+
+	/* probe for the right mtd map driver */
+
+	info->mtd = do_map_probe("map_ram" , &info->map);
+	if (info->mtd == NULL) {
+		dev_err(dev, "failed to probe for map_ram\n");
+		err = -ENOMEM;
+		goto exit_free;
+	}
+
+	info->mtd->owner = THIS_MODULE;
+
+	platram_setrw(info, PLATRAM_RW);
+
+	/* check to see if there are any available partitions, or wether
+	 * to add this device whole */
+
+#ifdef CONFIG_MTD_PARTITIONS
+	if (pdata->nr_partitions > 0) {
+		const char **probes = { NULL };
+
+		if (pdata->probes)
+			probes = (const char **)pdata->probes;
+
+		err = parse_mtd_partitions(info->mtd, probes,
+					   &info->partitions, 0);
+		if (err > 0) {
+			err = add_mtd_partitions(info->mtd, info->partitions,
+						 err);
+		}
+	}
+#endif /* CONFIG_MTD_PARTITIONS */
+
+	if (add_mtd_device(info->mtd)) {
+		dev_err(dev, "add_mtd_device() failed\n");
+		err = -ENOMEM;
+	}
+	
+	dev_info(dev, "registered mtd device\n");
+	return err;
+
+ exit_free:
+	platram_remove(dev);
+ exit_error:
+	return err;
+}
+
+/* device driver info */
+
+static struct device_driver platram_driver = {
+	.name		= "mtd-ram",
+	.bus		= &platform_bus_type,
+	.probe		= platram_probe,
+	.remove		= platram_remove,
+};
+
+/* module init/exit */
+
+static int __init platram_init(void)
+{
+	printk("Generic platform RAM MTD, (c) 2004 Simtec Electronics\n");
+	return driver_register(&platram_driver);
+}
+
+static void __exit platram_exit(void)
+{
+	driver_unregister(&platram_driver);
+}
+
+module_init(platram_init);
+module_exit(platram_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
+MODULE_DESCRIPTION("MTD platform RAM map driver");
diff --git a/drivers/mtd/maps/scb2_flash.c b/drivers/mtd/maps/scb2_flash.c
--- a/drivers/mtd/maps/scb2_flash.c
+++ b/drivers/mtd/maps/scb2_flash.c
@@ -1,6 +1,6 @@
 /*
  * MTD map driver for BIOS Flash on Intel SCB2 boards
- * $Id: scb2_flash.c,v 1.11 2004/11/28 09:40:40 dwmw2 Exp $
+ * $Id: scb2_flash.c,v 1.12 2005/03/18 14:04:35 gleixner Exp $
  * Copyright (C) 2002 Sun Microsystems, Inc.
  * Tim Hockin <thockin@sun.com>
  *
@@ -238,7 +238,7 @@ static struct pci_driver scb2_flash_driv
 static int __init
 scb2_flash_init(void)
 {
-	return pci_module_init(&scb2_flash_driver);
+	return pci_register_driver(&scb2_flash_driver);
 }
 
 static void __exit
diff --git a/drivers/mtd/maps/sharpsl-flash.c b/drivers/mtd/maps/sharpsl-flash.c
--- a/drivers/mtd/maps/sharpsl-flash.c
+++ b/drivers/mtd/maps/sharpsl-flash.c
@@ -4,7 +4,7 @@
  * Copyright (C) 2001 Lineo Japan, Inc.
  * Copyright (C) 2002  SHARP
  *
- * $Id: sharpsl-flash.c,v 1.2 2004/11/24 20:38:06 rpurdie Exp $
+ * $Id: sharpsl-flash.c,v 1.5 2005/03/21 08:42:11 rpurdie Exp $
  *
  * based on rpxlite.c,v 1.15 2001/10/02 15:05:14 dwmw2 Exp
  *          Handle mapping of the flash on the RPX Lite and CLLF boards
@@ -24,13 +24,14 @@
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
-#include <asm/io.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/map.h>
 #include <linux/mtd/partitions.h>
+#include <asm/io.h>
+#include <asm/mach-types.h>
 
 #define WINDOW_ADDR 0x00000000
-#define WINDOW_SIZE 0x01000000
+#define WINDOW_SIZE 0x00800000
 #define BANK_WIDTH 2
 
 static struct mtd_info *mymtd;
@@ -44,9 +45,7 @@ struct map_info sharpsl_map = {
 
 static struct mtd_partition sharpsl_partitions[1] = {
 	{
-		name:		"Filesystem",
-		size:		0x006d0000,
-		offset:		0x00120000
+		name:		"Boot PROM Filesystem",
 	}
 };
 
@@ -58,12 +57,16 @@ int __init init_sharpsl(void)
 	int nb_parts = 0;
 	char *part_type = "static";
 
-	printk(KERN_NOTICE "Sharp SL series flash device: %x at %x\n", WINDOW_SIZE, WINDOW_ADDR);
+	printk(KERN_NOTICE "Sharp SL series flash device: %x at %x\n", 
+		WINDOW_SIZE, WINDOW_ADDR);
 	sharpsl_map.virt = ioremap(WINDOW_ADDR, WINDOW_SIZE);
 	if (!sharpsl_map.virt) {
 		printk("Failed to ioremap\n");
 		return -EIO;
 	}
+
+	simple_map_init(&sharpsl_map);
+
 	mymtd = do_map_probe("map_rom", &sharpsl_map);
 	if (!mymtd) {
 		iounmap(sharpsl_map.virt);
@@ -72,6 +75,22 @@ int __init init_sharpsl(void)
 
 	mymtd->owner = THIS_MODULE;
 
+	if (machine_is_corgi() || machine_is_shepherd() || machine_is_husky() 
+		|| machine_is_poodle()) {
+		sharpsl_partitions[0].size=0x006d0000;
+		sharpsl_partitions[0].offset=0x00120000;
+	} else if (machine_is_tosa()) {
+		sharpsl_partitions[0].size=0x006a0000;
+		sharpsl_partitions[0].offset=0x00160000;
+	} else if (machine_is_spitz()) {
+		sharpsl_partitions[0].size=0x006b0000;
+		sharpsl_partitions[0].offset=0x00140000;
+	} else {
+		map_destroy(mymtd);
+		iounmap(sharpsl_map.virt);	
+		return -ENODEV;
+	}
+	
 	parts = sharpsl_partitions;
 	nb_parts = NB_OF(sharpsl_partitions);
 
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -1,5 +1,5 @@
 /*
- * $Id: mtdchar.c,v 1.66 2005/01/05 18:05:11 dwmw2 Exp $
+ * $Id: mtdchar.c,v 1.73 2005/07/04 17:36:41 gleixner Exp $
  *
  * Character-device access to raw MTD devices.
  *
@@ -15,27 +15,30 @@
 #include <linux/fs.h>
 #include <asm/uaccess.h>
 
-#ifdef CONFIG_DEVFS_FS
-#include <linux/devfs_fs_kernel.h>
+#include <linux/device.h>
+
+static struct class *mtd_class;
 
 static void mtd_notify_add(struct mtd_info* mtd)
 {
 	if (!mtd)
 		return;
 
-	devfs_mk_cdev(MKDEV(MTD_CHAR_MAJOR, mtd->index*2),
-		      S_IFCHR | S_IRUGO | S_IWUGO, "mtd/%d", mtd->index);
-		
-	devfs_mk_cdev(MKDEV(MTD_CHAR_MAJOR, mtd->index*2+1),
-		      S_IFCHR | S_IRUGO, "mtd/%dro", mtd->index);
+	class_device_create(mtd_class, MKDEV(MTD_CHAR_MAJOR, mtd->index*2),
+			    NULL, "mtd%d", mtd->index);
+	
+	class_device_create(mtd_class, 
+			    MKDEV(MTD_CHAR_MAJOR, mtd->index*2+1),
+			    NULL, "mtd%dro", mtd->index);
 }
 
 static void mtd_notify_remove(struct mtd_info* mtd)
 {
 	if (!mtd)
 		return;
-	devfs_remove("mtd/%d", mtd->index);
-	devfs_remove("mtd/%dro", mtd->index);
+
+	class_device_destroy(mtd_class, MKDEV(MTD_CHAR_MAJOR, mtd->index*2));
+	class_device_destroy(mtd_class, MKDEV(MTD_CHAR_MAJOR, mtd->index*2+1));
 }
 
 static struct mtd_notifier notifier = {
@@ -43,25 +46,25 @@ static struct mtd_notifier notifier = {
 	.remove	= mtd_notify_remove,
 };
 
-static inline void mtdchar_devfs_init(void)
-{
-	devfs_mk_dir("mtd");
-	register_mtd_user(&notifier);
-}
+/*
+ * We use file->private_data to store a pointer to the MTDdevice.
+ * Since alighment is at least 32 bits, we have 2 bits free for OTP
+ * modes as well.
+ */
 
-static inline void mtdchar_devfs_exit(void)
-{
-	unregister_mtd_user(&notifier);
-	devfs_remove("mtd");
-}
-#else /* !DEVFS */
-#define mtdchar_devfs_init() do { } while(0)
-#define mtdchar_devfs_exit() do { } while(0)
-#endif
+#define TO_MTD(file) (struct mtd_info *)((long)((file)->private_data) & ~3L)
+
+#define MTD_MODE_OTP_FACT	1
+#define MTD_MODE_OTP_USER	2
+#define MTD_MODE(file)		((long)((file)->private_data) & 3)
+
+#define SET_MTD_MODE(file, mode) \
+	do { long __p = (long)((file)->private_data); \
+	     (file)->private_data = (void *)((__p & ~3L) | mode); } while (0)
 
 static loff_t mtd_lseek (struct file *file, loff_t offset, int orig)
 {
-	struct mtd_info *mtd = file->private_data;
+	struct mtd_info *mtd = TO_MTD(file);
 
 	switch (orig) {
 	case 0:
@@ -134,7 +137,7 @@ static int mtd_close(struct inode *inode
 
 	DEBUG(MTD_DEBUG_LEVEL0, "MTD_close\n");
 
-	mtd = file->private_data;
+	mtd = TO_MTD(file);
 	
 	if (mtd->sync)
 		mtd->sync(mtd);
@@ -151,7 +154,7 @@ static int mtd_close(struct inode *inode
 
 static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t *ppos)
 {
-	struct mtd_info *mtd = file->private_data;
+	struct mtd_info *mtd = TO_MTD(file);
 	size_t retlen=0;
 	size_t total_retlen=0;
 	int ret=0;
@@ -178,7 +181,16 @@ static ssize_t mtd_read(struct file *fil
 		if (!kbuf)
 			return -ENOMEM;
 		
-		ret = MTD_READ(mtd, *ppos, len, &retlen, kbuf);
+		switch (MTD_MODE(file)) {
+		case MTD_MODE_OTP_FACT:
+			ret = mtd->read_fact_prot_reg(mtd, *ppos, len, &retlen, kbuf);
+			break;
+		case MTD_MODE_OTP_USER:
+			ret = mtd->read_user_prot_reg(mtd, *ppos, len, &retlen, kbuf);
+			break;
+		default:
+			ret = MTD_READ(mtd, *ppos, len, &retlen, kbuf);
+		}
 		/* Nand returns -EBADMSG on ecc errors, but it returns
 		 * the data. For our userspace tools it is important
 		 * to dump areas with ecc errors ! 
@@ -196,6 +208,8 @@ static ssize_t mtd_read(struct file *fil
 
 			count -= retlen;
 			buf += retlen;
+			if (retlen == 0)
+				count = 0;
 		}
 		else {
 			kfree(kbuf);
@@ -210,7 +224,7 @@ static ssize_t mtd_read(struct file *fil
 
 static ssize_t mtd_write(struct file *file, const char __user *buf, size_t count,loff_t *ppos)
 {
-	struct mtd_info *mtd = file->private_data;
+	struct mtd_info *mtd = TO_MTD(file);
 	char *kbuf;
 	size_t retlen;
 	size_t total_retlen=0;
@@ -245,7 +259,20 @@ static ssize_t mtd_write(struct file *fi
 			return -EFAULT;
 		}
 		
-	        ret = (*(mtd->write))(mtd, *ppos, len, &retlen, kbuf);
+		switch (MTD_MODE(file)) {
+		case MTD_MODE_OTP_FACT:
+			ret = -EROFS;
+			break;
+		case MTD_MODE_OTP_USER:
+			if (!mtd->write_user_prot_reg) {
+				ret = -EOPNOTSUPP;
+				break;
+			}
+			ret = mtd->write_user_prot_reg(mtd, *ppos, len, &retlen, kbuf);
+			break;
+		default:
+			ret = (*(mtd->write))(mtd, *ppos, len, &retlen, kbuf);
+		}
 		if (!ret) {
 			*ppos += retlen;
 			total_retlen += retlen;
@@ -276,7 +303,7 @@ static void mtdchar_erase_callback (stru
 static int mtd_ioctl(struct inode *inode, struct file *file,
 		     u_int cmd, u_long arg)
 {
-	struct mtd_info *mtd = file->private_data;
+	struct mtd_info *mtd = TO_MTD(file);
 	void __user *argp = (void __user *)arg;
 	int ret = 0;
 	u_long size;
@@ -518,6 +545,80 @@ static int mtd_ioctl(struct inode *inode
 		break;
 	}
 
+#ifdef CONFIG_MTD_OTP
+	case OTPSELECT:
+	{
+		int mode;
+		if (copy_from_user(&mode, argp, sizeof(int)))
+			return -EFAULT;
+		SET_MTD_MODE(file, 0);
+		switch (mode) {
+		case MTD_OTP_FACTORY:
+			if (!mtd->read_fact_prot_reg)
+				ret = -EOPNOTSUPP;
+			else
+				SET_MTD_MODE(file, MTD_MODE_OTP_FACT);
+			break;
+		case MTD_OTP_USER:
+			if (!mtd->read_fact_prot_reg)
+				ret = -EOPNOTSUPP;
+			else
+				SET_MTD_MODE(file, MTD_MODE_OTP_USER);
+			break;
+		default:
+			ret = -EINVAL;
+		case MTD_OTP_OFF:
+			break;
+		}
+		file->f_pos = 0;
+		break;
+	}
+
+	case OTPGETREGIONCOUNT:
+	case OTPGETREGIONINFO:
+	{
+		struct otp_info *buf = kmalloc(4096, GFP_KERNEL);
+		if (!buf)
+			return -ENOMEM;
+		ret = -EOPNOTSUPP;
+		switch (MTD_MODE(file)) {
+		case MTD_MODE_OTP_FACT:
+			if (mtd->get_fact_prot_info)
+				ret = mtd->get_fact_prot_info(mtd, buf, 4096);
+			break;
+		case MTD_MODE_OTP_USER:
+			if (mtd->get_user_prot_info)
+				ret = mtd->get_user_prot_info(mtd, buf, 4096);
+			break;
+		}
+		if (ret >= 0) {
+			if (cmd == OTPGETREGIONCOUNT) {
+				int nbr = ret / sizeof(struct otp_info);
+				ret = copy_to_user(argp, &nbr, sizeof(int));
+			} else
+				ret = copy_to_user(argp, buf, ret);
+			if (ret)
+				ret = -EFAULT;
+		}
+		kfree(buf);
+		break;
+	}
+
+	case OTPLOCK:
+	{
+		struct otp_info info;
+
+		if (MTD_MODE(file) != MTD_MODE_OTP_USER)
+			return -EINVAL;
+		if (copy_from_user(&info, argp, sizeof(info)))
+			return -EFAULT;
+		if (!mtd->lock_user_prot_reg)
+			return -EOPNOTSUPP;
+		ret = mtd->lock_user_prot_reg(mtd, info.start, info.length);
+		break;
+	}
+#endif
+
 	default:
 		ret = -ENOTTY;
 	}
@@ -543,13 +644,22 @@ static int __init init_mtdchar(void)
 		return -EAGAIN;
 	}
 
-	mtdchar_devfs_init();
+	mtd_class = class_create(THIS_MODULE, "mtd");
+
+	if (IS_ERR(mtd_class)) {
+		printk(KERN_ERR "Error creating mtd class.\n");
+		unregister_chrdev(MTD_CHAR_MAJOR, "mtd");
+		return PTR_ERR(mtd_class);
+	}
+
+	register_mtd_user(&notifier);
 	return 0;
 }
 
 static void __exit cleanup_mtdchar(void)
 {
-	mtdchar_devfs_exit();
+	unregister_mtd_user(&notifier);
+	class_destroy(mtd_class);
 	unregister_chrdev(MTD_CHAR_MAJOR, "mtd");
 }
 
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -1,5 +1,5 @@
 /*
- * $Id: mtdcore.c,v 1.44 2004/11/16 18:28:59 dwmw2 Exp $
+ * $Id: mtdcore.c,v 1.45 2005/02/18 14:34:50 dedekind Exp $
  *
  * Core registration and callback routines for MTD
  * drivers and users.
@@ -149,8 +149,8 @@ void register_mtd_user (struct mtd_notif
 }
 
 /**
- *	register_mtd_user - unregister a 'user' of MTD devices.
- *	@new: pointer to notifier info structure
+ *	unregister_mtd_user - unregister a 'user' of MTD devices.
+ *	@old: pointer to notifier info structure
  *
  *	Removes a callback function pair from the list of 'users' to be
  *	notified upon addition or removal of MTD devices. Causes the
diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -5,7 +5,7 @@
  *
  * This code is GPL
  *
- * $Id: mtdpart.c,v 1.51 2004/11/16 18:28:59 dwmw2 Exp $
+ * $Id: mtdpart.c,v 1.53 2005/02/08 17:11:13 nico Exp $
  *
  * 	02-21-2002	Thomas Gleixner <gleixner@autronix.de>
  *			added support for read_oob, write_oob
@@ -116,6 +116,13 @@ static int part_read_user_prot_reg (stru
 					len, retlen, buf);
 }
 
+static int part_get_user_prot_info (struct mtd_info *mtd,
+				    struct otp_info *buf, size_t len)
+{
+	struct mtd_part *part = PART(mtd);
+	return part->master->get_user_prot_info (part->master, buf, len);
+}
+
 static int part_read_fact_prot_reg (struct mtd_info *mtd, loff_t from, size_t len, 
 			size_t *retlen, u_char *buf)
 {
@@ -124,6 +131,13 @@ static int part_read_fact_prot_reg (stru
 					len, retlen, buf);
 }
 
+static int part_get_fact_prot_info (struct mtd_info *mtd,
+				    struct otp_info *buf, size_t len)
+{
+	struct mtd_part *part = PART(mtd);
+	return part->master->get_fact_prot_info (part->master, buf, len);
+}
+
 static int part_write (struct mtd_info *mtd, loff_t to, size_t len,
 			size_t *retlen, const u_char *buf)
 {
@@ -182,6 +196,12 @@ static int part_write_user_prot_reg (str
 					len, retlen, buf);
 }
 
+static int part_lock_user_prot_reg (struct mtd_info *mtd, loff_t from, size_t len) 
+{
+	struct mtd_part *part = PART(mtd);
+	return part->master->lock_user_prot_reg (part->master, from, len);
+}
+
 static int part_writev (struct mtd_info *mtd,  const struct kvec *vecs,
 			 unsigned long count, loff_t to, size_t *retlen)
 {
@@ -409,6 +429,12 @@ int add_mtd_partitions(struct mtd_info *
 			slave->mtd.read_fact_prot_reg = part_read_fact_prot_reg;
 		if(master->write_user_prot_reg)
 			slave->mtd.write_user_prot_reg = part_write_user_prot_reg;
+		if(master->lock_user_prot_reg)
+			slave->mtd.lock_user_prot_reg = part_lock_user_prot_reg;
+		if(master->get_user_prot_info)
+			slave->mtd.get_user_prot_info = part_get_user_prot_info;
+		if(master->get_fact_prot_info)
+			slave->mtd.get_fact_prot_info = part_get_fact_prot_info;
 		if (master->sync)
 			slave->mtd.sync = part_sync;
 		if (!i && master->suspend && master->resume) {
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -1,5 +1,5 @@
 # drivers/mtd/nand/Kconfig
-# $Id: Kconfig,v 1.26 2005/01/05 12:42:24 dwmw2 Exp $
+# $Id: Kconfig,v 1.31 2005/06/20 12:03:21 bjd Exp $
 
 menu "NAND Flash Device Drivers"
 	depends on MTD!=n
@@ -58,20 +58,6 @@ config MTD_NAND_TOTO
 config MTD_NAND_IDS
 	tristate
 
-config MTD_NAND_TX4925NDFMC
-	tristate "SmartMedia Card on Toshiba RBTX4925 reference board"
-	depends on TOSHIBA_RBTX4925 && MTD_NAND && TOSHIBA_RBTX4925_MPLEX_NAND
-	help
-	  This enables the driver for the NAND flash device found on the
-	  Toshiba RBTX4925 reference board, which is a SmartMediaCard.
-
-config MTD_NAND_TX4938NDFMC
-	tristate "NAND Flash device on Toshiba RBTX4938 reference board"
-	depends on TOSHIBA_RBTX4938 && MTD_NAND && TOSHIBA_RBTX4938_MPLEX_NAND 
-	help
-	  This enables the driver for the NAND flash device found on the
-	  Toshiba RBTX4938 reference board.
-
 config MTD_NAND_AU1550
 	tristate "Au1550 NAND support"
 	depends on SOC_AU1550 && MTD_NAND
@@ -95,10 +81,11 @@ config MTD_NAND_PPCHAMELEONEVB
 	  This enables the NAND flash driver on the PPChameleon EVB Board.
 
 config MTD_NAND_S3C2410
-	tristate "NAND Flash support for S3C2410 SoC"
+	tristate "NAND Flash support for S3C2410/S3C2440 SoC"
 	depends on ARCH_S3C2410 && MTD_NAND
 	help
-	  This enables the NAND flash controller on the S3C2410.
+	  This enables the NAND flash controller on the S3C2410 and S3C2440
+	  SoCs
 
 	  No board specfic support is done by this driver, each board
 	  must advertise a platform_device for the driver to attach. 
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -10,8 +10,6 @@ obj-$(CONFIG_MTD_NAND_SPIA)		+= spia.o
 obj-$(CONFIG_MTD_NAND_TOTO)		+= toto.o
 obj-$(CONFIG_MTD_NAND_AUTCPU12)		+= autcpu12.o
 obj-$(CONFIG_MTD_NAND_EDB7312)		+= edb7312.o
-obj-$(CONFIG_MTD_NAND_TX4925NDFMC)	+= tx4925ndfmc.o
-obj-$(CONFIG_MTD_NAND_TX4938NDFMC)	+= tx4938ndfmc.o
 obj-$(CONFIG_MTD_NAND_AU1550)		+= au1550nd.o
 obj-$(CONFIG_MTD_NAND_PPCHAMELEONEVB)	+= ppchameleonevb.o
 obj-$(CONFIG_MTD_NAND_S3C2410)		+= s3c2410.o
diff --git a/drivers/mtd/nand/diskonchip.c b/drivers/mtd/nand/diskonchip.c
--- a/drivers/mtd/nand/diskonchip.c
+++ b/drivers/mtd/nand/diskonchip.c
@@ -16,7 +16,7 @@
  *  
  * Interface to generic NAND code for M-Systems DiskOnChip devices
  *
- * $Id: diskonchip.c,v 1.45 2005/01/05 18:05:14 dwmw2 Exp $
+ * $Id: diskonchip.c,v 1.54 2005/04/07 14:22:55 dbrown Exp $
  */
 
 #include <linux/kernel.h>
@@ -35,13 +35,13 @@
 #include <linux/mtd/inftl.h>
 
 /* Where to look for the devices? */
-#ifndef CONFIG_MTD_DISKONCHIP_PROBE_ADDRESS
-#define CONFIG_MTD_DISKONCHIP_PROBE_ADDRESS 0
+#ifndef CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS
+#define CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS 0
 #endif
 
 static unsigned long __initdata doc_locations[] = {
 #if defined (__alpha__) || defined(__i386__) || defined(__x86_64__)
-#ifdef CONFIG_MTD_DISKONCHIP_PROBE_HIGH
+#ifdef CONFIG_MTD_NAND_DISKONCHIP_PROBE_HIGH
 	0xfffc8000, 0xfffca000, 0xfffcc000, 0xfffce000, 
 	0xfffd0000, 0xfffd2000, 0xfffd4000, 0xfffd6000,
 	0xfffd8000, 0xfffda000, 0xfffdc000, 0xfffde000, 
@@ -81,11 +81,6 @@ struct doc_priv {
 	struct mtd_info *nextdoc;
 };
 
-/* Max number of eraseblocks to scan (from start of device) for the (I)NFTL
-   MediaHeader.  The spec says to just keep going, I think, but that's just
-   silly. */
-#define MAX_MEDIAHEADER_SCAN 8
-
 /* This is the syndrome computed by the HW ecc generator upon reading an empty
    page, one with all 0xff for data and stored ecc code. */
 static u_char empty_read_syndrome[6] = { 0x26, 0xff, 0x6d, 0x47, 0x73, 0x7a };
@@ -111,10 +106,11 @@ module_param(try_dword, int, 0);
 static int no_ecc_failures=0;
 module_param(no_ecc_failures, int, 0);
 
-#ifdef CONFIG_MTD_PARTITIONS
 static int no_autopart=0;
 module_param(no_autopart, int, 0);
-#endif
+
+static int show_firmware_partition=0;
+module_param(show_firmware_partition, int, 0);
 
 #ifdef MTD_NAND_DISKONCHIP_BBTWRITE
 static int inftl_bbt_write=1;
@@ -123,7 +119,7 @@ static int inftl_bbt_write=0;
 #endif
 module_param(inftl_bbt_write, int, 0);
 
-static unsigned long doc_config_location = CONFIG_MTD_DISKONCHIP_PROBE_ADDRESS;
+static unsigned long doc_config_location = CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS;
 module_param(doc_config_location, ulong, 0);
 MODULE_PARM_DESC(doc_config_location, "Physical memory address at which to probe for DiskOnChip");
 
@@ -410,7 +406,12 @@ static uint16_t __init doc200x_ident_chi
 	doc200x_hwcontrol(mtd, NAND_CTL_SETALE);
 	this->write_byte(mtd, 0);
 	doc200x_hwcontrol(mtd, NAND_CTL_CLRALE);
-
+	
+	/* We cant' use dev_ready here, but at least we wait for the
+	 * command to complete 
+	 */
+	udelay(50);
+	
 	ret = this->read_byte(mtd) << 8;
 	ret |= this->read_byte(mtd);
 
@@ -429,6 +430,8 @@ static uint16_t __init doc200x_ident_chi
 		doc2000_write_byte(mtd, 0);
 		doc200x_hwcontrol(mtd, NAND_CTL_CLRALE);
 
+		udelay(50);
+
 		ident.dword = readl(docptr + DoC_2k_CDSN_IO);
 		if (((ident.byte[0] << 8) | ident.byte[1]) == ret) {
 			printk(KERN_INFO "DiskOnChip 2000 responds to DWORD access\n");
@@ -1046,11 +1049,21 @@ static int doc200x_correct_data(struct m
 		
 //u_char mydatabuf[528];
 
+/* The strange out-of-order .oobfree list below is a (possibly unneeded)
+ * attempt to retain compatibility.  It used to read:
+ * 	.oobfree = { {8, 8} }
+ * Since that leaves two bytes unusable, it was changed.  But the following
+ * scheme might affect existing jffs2 installs by moving the cleanmarker:
+ * 	.oobfree = { {6, 10} }
+ * jffs2 seems to handle the above gracefully, but the current scheme seems
+ * safer.  The only problem with it is that any code that parses oobfree must
+ * be able to handle out-of-order segments.
+ */
 static struct nand_oobinfo doc200x_oobinfo = {
         .useecc = MTD_NANDECC_AUTOPLACE,
         .eccbytes = 6,
         .eccpos = {0, 1, 2, 3, 4, 5},
-        .oobfree = { {8, 8} }
+        .oobfree = { {8, 8}, {6, 2} }
 };
  
 /* Find the (I)NFTL Media Header, and optionally also the mirror media header.
@@ -1064,12 +1077,11 @@ static int __init find_media_headers(str
 {
 	struct nand_chip *this = mtd->priv;
 	struct doc_priv *doc = this->priv;
-	unsigned offs, end = (MAX_MEDIAHEADER_SCAN << this->phys_erase_shift);
+	unsigned offs;
 	int ret;
 	size_t retlen;
 
-	end = min(end, mtd->size); // paranoia
-	for (offs = 0; offs < end; offs += mtd->erasesize) {
+	for (offs = 0; offs < mtd->size; offs += mtd->erasesize) {
 		ret = mtd->read(mtd, offs, mtd->oobblock, &retlen, buf);
 		if (retlen != mtd->oobblock) continue;
 		if (ret) {
@@ -1111,6 +1123,7 @@ static inline int __init nftl_partscan(s
 	u_char *buf;
 	struct NFTLMediaHeader *mh;
 	const unsigned psize = 1 << this->page_shift;
+	int numparts = 0;
 	unsigned blocks, maxblocks;
 	int offs, numheaders;
 
@@ -1122,8 +1135,10 @@ static inline int __init nftl_partscan(s
 	if (!(numheaders=find_media_headers(mtd, buf, "ANAND", 1))) goto out;
 	mh = (struct NFTLMediaHeader *) buf;
 
-//#ifdef CONFIG_MTD_DEBUG_VERBOSE
-//	if (CONFIG_MTD_DEBUG_VERBOSE >= 2)
+	mh->NumEraseUnits = le16_to_cpu(mh->NumEraseUnits);
+	mh->FirstPhysicalEUN = le16_to_cpu(mh->FirstPhysicalEUN);
+	mh->FormattedSize = le32_to_cpu(mh->FormattedSize);
+
 	printk(KERN_INFO "    DataOrgID        = %s\n"
 			 "    NumEraseUnits    = %d\n"
 			 "    FirstPhysicalEUN = %d\n"
@@ -1132,7 +1147,6 @@ static inline int __init nftl_partscan(s
 		mh->DataOrgID, mh->NumEraseUnits,
 		mh->FirstPhysicalEUN, mh->FormattedSize,
 		mh->UnitSizeFactor);
-//#endif
 
 	blocks = mtd->size >> this->phys_erase_shift;
 	maxblocks = min(32768U, mtd->erasesize - psize);
@@ -1175,23 +1189,28 @@ static inline int __init nftl_partscan(s
 	offs <<= this->page_shift;
 	offs += mtd->erasesize;
 
-	//parts[0].name = " DiskOnChip Boot / Media Header partition";
-	//parts[0].offset = 0;
-	//parts[0].size = offs;
-
-	parts[0].name = " DiskOnChip BDTL partition";
-	parts[0].offset = offs;
-	parts[0].size = (mh->NumEraseUnits - numheaders) << this->bbt_erase_shift;
+	if (show_firmware_partition == 1) {
+		parts[0].name = " DiskOnChip Firmware / Media Header partition";
+		parts[0].offset = 0;
+		parts[0].size = offs;
+		numparts = 1;
+	}
+
+	parts[numparts].name = " DiskOnChip BDTL partition";
+	parts[numparts].offset = offs;
+	parts[numparts].size = (mh->NumEraseUnits - numheaders) << this->bbt_erase_shift;
+
+	offs += parts[numparts].size;
+	numparts++;
 
-	offs += parts[0].size;
 	if (offs < mtd->size) {
-		parts[1].name = " DiskOnChip Remainder partition";
-		parts[1].offset = offs;
-		parts[1].size = mtd->size - offs;
-		ret = 2;
-		goto out;
+		parts[numparts].name = " DiskOnChip Remainder partition";
+		parts[numparts].offset = offs;
+		parts[numparts].size = mtd->size - offs;
+		numparts++;
 	}
-	ret = 1;
+
+	ret = numparts;
 out:
 	kfree(buf);
 	return ret;
@@ -1233,8 +1252,6 @@ static inline int __init inftl_partscan(
 	mh->FormatFlags = le32_to_cpu(mh->FormatFlags);
 	mh->PercentUsed = le32_to_cpu(mh->PercentUsed);
  
-//#ifdef CONFIG_MTD_DEBUG_VERBOSE
-//	if (CONFIG_MTD_DEBUG_VERBOSE >= 2)
 	printk(KERN_INFO "    bootRecordID          = %s\n"
 			 "    NoOfBootImageBlocks   = %d\n"
 			 "    NoOfBinaryPartitions  = %d\n"
@@ -1252,7 +1269,6 @@ static inline int __init inftl_partscan(
 		((unsigned char *) &mh->OsakVersion)[2] & 0xf,
 		((unsigned char *) &mh->OsakVersion)[3] & 0xf,
 		mh->PercentUsed);
-//#endif
 
 	vshift = this->phys_erase_shift + mh->BlockMultiplierBits;
 
@@ -1278,8 +1294,6 @@ static inline int __init inftl_partscan(
 		ip->spareUnits = le32_to_cpu(ip->spareUnits);
 		ip->Reserved0 = le32_to_cpu(ip->Reserved0);
 
-//#ifdef CONFIG_MTD_DEBUG_VERBOSE
-//		if (CONFIG_MTD_DEBUG_VERBOSE >= 2)
 		printk(KERN_INFO	"    PARTITION[%d] ->\n"
 			"        virtualUnits    = %d\n"
 			"        firstUnit       = %d\n"
@@ -1289,16 +1303,14 @@ static inline int __init inftl_partscan(
 			i, ip->virtualUnits, ip->firstUnit,
 			ip->lastUnit, ip->flags,
 			ip->spareUnits);
-//#endif
 
-/*
-		if ((i == 0) && (ip->firstUnit > 0)) {
+		if ((show_firmware_partition == 1) &&
+		    (i == 0) && (ip->firstUnit > 0)) {
 			parts[0].name = " DiskOnChip IPL / Media Header partition";
 			parts[0].offset = 0;
 			parts[0].size = mtd->erasesize * ip->firstUnit;
 			numparts = 1;
 		}
-*/
 
 		if (ip->flags & INFTL_BINARY)
 			parts[numparts].name = " DiskOnChip BDK partition";
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -28,6 +28,24 @@
  *		among multiple independend devices. Suggestions and initial patch
  *		from Ben Dooks <ben-mtd@fluff.org>
  *
+ *  12-05-2004	dmarlin: add workaround for Renesas AG-AND chips "disturb" issue.
+ *		Basically, any block not rewritten may lose data when surrounding blocks
+ *		are rewritten many times.  JFFS2 ensures this doesn't happen for blocks 
+ *		it uses, but the Bad Block Table(s) may not be rewritten.  To ensure they
+ *		do not lose data, force them to be rewritten when some of the surrounding
+ *		blocks are erased.  Rather than tracking a specific nearby block (which 
+ *		could itself go bad), use a page address 'mask' to select several blocks 
+ *		in the same area, and rewrite the BBT when any of them are erased.
+ *
+ *  01-03-2005	dmarlin: added support for the device recovery command sequence for Renesas 
+ *		AG-AND chips.  If there was a sudden loss of power during an erase operation,
+ * 		a "device recovery" operation must be performed when power is restored
+ * 		to ensure correct operation.
+ *
+ *  01-20-2005	dmarlin: added support for optional hardware specific callback routine to 
+ *		perform extra error status checks on erase and write failures.  This required
+ *		adding a wrapper function for nand_read_ecc.
+ *
  * Credits:
  *	David Woodhouse for adding multichip support  
  *	
@@ -41,7 +59,7 @@
  *	The AG-AND chips have nice features for speed improvement,
  *	which are not supported yet. Read / program 4 pages in one go.
  *
- * $Id: nand_base.c,v 1.126 2004/12/13 11:22:25 lavinen Exp $
+ * $Id: nand_base.c,v 1.147 2005/07/15 07:18:06 gleixner Exp $
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -149,17 +167,21 @@ static void nand_release_device (struct 
 
 	/* De-select the NAND device */
 	this->select_chip(mtd, -1);
-	/* Do we have a hardware controller ? */
+
 	if (this->controller) {
+		/* Release the controller and the chip */
 		spin_lock(&this->controller->lock);
 		this->controller->active = NULL;
+		this->state = FL_READY;
+		wake_up(&this->controller->wq);
 		spin_unlock(&this->controller->lock);
+	} else {
+		/* Release the chip */
+		spin_lock(&this->chip_lock);
+		this->state = FL_READY;
+		wake_up(&this->wq);
+		spin_unlock(&this->chip_lock);
 	}
-	/* Release the chip */
-	spin_lock (&this->chip_lock);
-	this->state = FL_READY;
-	wake_up (&this->wq);
-	spin_unlock (&this->chip_lock);
 }
 
 /**
@@ -443,7 +465,8 @@ static int nand_default_block_markbad(st
 	
 	/* Get block number */
 	block = ((int) ofs) >> this->bbt_erase_shift;
-	this->bbt[block >> 2] |= 0x01 << ((block & 0x03) << 1);
+	if (this->bbt)
+		this->bbt[block >> 2] |= 0x01 << ((block & 0x03) << 1);
 
 	/* Do we have a flash based bad block table ? */
 	if (this->options & NAND_USE_FLASH_BBT)
@@ -466,7 +489,7 @@ static int nand_check_wp (struct mtd_inf
 	struct nand_chip *this = mtd->priv;
 	/* Check the WP bit */
 	this->cmdfunc (mtd, NAND_CMD_STATUS, -1, -1);
-	return (this->read_byte(mtd) & 0x80) ? 0 : 1; 
+	return (this->read_byte(mtd) & NAND_STATUS_WP) ? 0 : 1; 
 }
 
 /**
@@ -490,6 +513,22 @@ static int nand_block_checkbad (struct m
 	return nand_isbad_bbt (mtd, ofs, allowbbt);
 }
 
+/* 
+ * Wait for the ready pin, after a command
+ * The timeout is catched later.
+ */
+static void nand_wait_ready(struct mtd_info *mtd)
+{
+	struct nand_chip *this = mtd->priv;
+	unsigned long	timeo = jiffies + 2;
+
+	/* wait until command is processed or timeout occures */
+	do {
+		if (this->dev_ready(mtd))
+			return;
+	} while (time_before(jiffies, timeo));	
+}
+
 /**
  * nand_command - [DEFAULT] Send command to NAND device
  * @mtd:	MTD device structure
@@ -571,7 +610,7 @@ static void nand_command (struct mtd_inf
 		this->hwcontrol(mtd, NAND_CTL_SETCLE);
 		this->write_byte(mtd, NAND_CMD_STATUS);
 		this->hwcontrol(mtd, NAND_CTL_CLRCLE);
-		while ( !(this->read_byte(mtd) & 0x40));
+		while ( !(this->read_byte(mtd) & NAND_STATUS_READY));
 		return;
 
 	/* This applies to read commands */	
@@ -585,12 +624,11 @@ static void nand_command (struct mtd_inf
 			return;
 		}	
 	}
-	
 	/* Apply this short delay always to ensure that we do wait tWB in
 	 * any case on any machine. */
 	ndelay (100);
-	/* wait until command is processed */
-	while (!this->dev_ready(mtd));
+
+	nand_wait_ready(mtd);
 }
 
 /**
@@ -619,7 +657,7 @@ static void nand_command_lp (struct mtd_
 	/* Begin command latch cycle */
 	this->hwcontrol(mtd, NAND_CTL_SETCLE);
 	/* Write out the command to the device. */
-	this->write_byte(mtd, command);
+	this->write_byte(mtd, (command & 0xff));
 	/* End command latch cycle */
 	this->hwcontrol(mtd, NAND_CTL_CLRCLE);
 
@@ -647,8 +685,8 @@ static void nand_command_lp (struct mtd_
 	
 	/* 
 	 * program and erase have their own busy handlers 
-	 * status and sequential in needs no delay
-	*/
+	 * status, sequential in, and deplete1 need no delay
+	 */
 	switch (command) {
 			
 	case NAND_CMD_CACHEDPROG:
@@ -657,8 +695,19 @@ static void nand_command_lp (struct mtd_
 	case NAND_CMD_ERASE2:
 	case NAND_CMD_SEQIN:
 	case NAND_CMD_STATUS:
+	case NAND_CMD_DEPLETE1:
 		return;
 
+	/* 
+	 * read error status commands require only a short delay
+	 */
+	case NAND_CMD_STATUS_ERROR:
+	case NAND_CMD_STATUS_ERROR0:
+	case NAND_CMD_STATUS_ERROR1:
+	case NAND_CMD_STATUS_ERROR2:
+	case NAND_CMD_STATUS_ERROR3:
+		udelay(this->chip_delay);
+		return;
 
 	case NAND_CMD_RESET:
 		if (this->dev_ready)	
@@ -667,7 +716,7 @@ static void nand_command_lp (struct mtd_
 		this->hwcontrol(mtd, NAND_CTL_SETCLE);
 		this->write_byte(mtd, NAND_CMD_STATUS);
 		this->hwcontrol(mtd, NAND_CTL_CLRCLE);
-		while ( !(this->read_byte(mtd) & 0x40));
+		while ( !(this->read_byte(mtd) & NAND_STATUS_READY));
 		return;
 
 	case NAND_CMD_READ0:
@@ -690,12 +739,12 @@ static void nand_command_lp (struct mtd_
 			return;
 		}	
 	}
-	
+
 	/* Apply this short delay always to ensure that we do wait tWB in
 	 * any case on any machine. */
 	ndelay (100);
-	/* wait until command is processed */
-	while (!this->dev_ready(mtd));
+
+	nand_wait_ready(mtd);
 }
 
 /**
@@ -708,37 +757,34 @@ static void nand_command_lp (struct mtd_
  */
 static void nand_get_device (struct nand_chip *this, struct mtd_info *mtd, int new_state)
 {
-	struct nand_chip *active = this;
-
+	struct nand_chip *active;
+	spinlock_t *lock;
+	wait_queue_head_t *wq;
 	DECLARE_WAITQUEUE (wait, current);
 
-	/* 
-	 * Grab the lock and see if the device is available 
-	*/
+	lock = (this->controller) ? &this->controller->lock : &this->chip_lock;
+	wq = (this->controller) ? &this->controller->wq : &this->wq;
 retry:
+	active = this;
+	spin_lock(lock);
+
 	/* Hardware controller shared among independend devices */
 	if (this->controller) {
-		spin_lock (&this->controller->lock);
 		if (this->controller->active)
 			active = this->controller->active;
 		else
 			this->controller->active = this;
-		spin_unlock (&this->controller->lock);
 	}
-	
-	if (active == this) {
-		spin_lock (&this->chip_lock);
-		if (this->state == FL_READY) {
-			this->state = new_state;
-			spin_unlock (&this->chip_lock);
-			return;
-		}
-	}	
-	set_current_state (TASK_UNINTERRUPTIBLE);
-	add_wait_queue (&active->wq, &wait);
-	spin_unlock (&active->chip_lock);
-	schedule ();
-	remove_wait_queue (&active->wq, &wait);
+	if (active == this && this->state == FL_READY) {
+		this->state = new_state;
+		spin_unlock(lock);
+		return;
+	}
+	set_current_state(TASK_UNINTERRUPTIBLE);
+	add_wait_queue(wq, &wait);
+	spin_unlock(lock);
+	schedule();
+	remove_wait_queue(wq, &wait);
 	goto retry;
 }
 
@@ -785,7 +831,7 @@ static int nand_wait(struct mtd_info *mt
 			if (this->read_byte(mtd) & NAND_STATUS_READY)
 				break;
 		}
-		yield ();
+		cond_resched();
 	}
 	status = (int) this->read_byte(mtd);
 	return status;
@@ -871,8 +917,14 @@ static int nand_write_page (struct mtd_i
 	if (!cached) {
 		/* call wait ready function */
 		status = this->waitfunc (mtd, this, FL_WRITING);
+
+		/* See if operation failed and additional status checks are available */
+		if ((status & NAND_STATUS_FAIL) && (this->errstat)) {
+			status = this->errstat(mtd, this, FL_WRITING, status, page);
+		}
+
 		/* See if device thinks it succeeded */
-		if (status & 0x01) {
+		if (status & NAND_STATUS_FAIL) {
 			DEBUG (MTD_DEBUG_LEVEL0, "%s: " "Failed write, page 0x%08x, ", __FUNCTION__, page);
 			return -EIO;
 		}
@@ -975,7 +1027,7 @@ static int nand_verify_pages (struct mtd
 		if (!this->dev_ready) 
 			udelay (this->chip_delay);
 		else
-			while (!this->dev_ready(mtd));	
+			nand_wait_ready(mtd);
 
 		/* All done, return happy */
 		if (!numpages)
@@ -997,23 +1049,24 @@ out:	 
 #endif
 
 /**
- * nand_read - [MTD Interface] MTD compability function for nand_read_ecc
+ * nand_read - [MTD Interface] MTD compability function for nand_do_read_ecc
  * @mtd:	MTD device structure
  * @from:	offset to read from
  * @len:	number of bytes to read
  * @retlen:	pointer to variable to store the number of read bytes
  * @buf:	the databuffer to put data
  *
- * This function simply calls nand_read_ecc with oob buffer and oobsel = NULL
-*/
+ * This function simply calls nand_do_read_ecc with oob buffer and oobsel = NULL
+ * and flags = 0xff
+ */
 static int nand_read (struct mtd_info *mtd, loff_t from, size_t len, size_t * retlen, u_char * buf)
 {
-	return nand_read_ecc (mtd, from, len, retlen, buf, NULL, NULL);
-}			   
+	return nand_do_read_ecc (mtd, from, len, retlen, buf, NULL, &mtd->oobinfo, 0xff);
+}
 
 
 /**
- * nand_read_ecc - [MTD Interface] Read data with ECC
+ * nand_read_ecc - [MTD Interface] MTD compability function for nand_do_read_ecc
  * @mtd:	MTD device structure
  * @from:	offset to read from
  * @len:	number of bytes to read
@@ -1022,11 +1075,39 @@ static int nand_read (struct mtd_info *m
  * @oob_buf:	filesystem supplied oob data buffer
  * @oobsel:	oob selection structure
  *
- * NAND read with ECC
+ * This function simply calls nand_do_read_ecc with flags = 0xff
  */
 static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
 			  size_t * retlen, u_char * buf, u_char * oob_buf, struct nand_oobinfo *oobsel)
 {
+	/* use userspace supplied oobinfo, if zero */
+	if (oobsel == NULL)
+		oobsel = &mtd->oobinfo;
+	return nand_do_read_ecc(mtd, from, len, retlen, buf, oob_buf, oobsel, 0xff);
+}
+
+
+/**
+ * nand_do_read_ecc - [MTD Interface] Read data with ECC
+ * @mtd:	MTD device structure
+ * @from:	offset to read from
+ * @len:	number of bytes to read
+ * @retlen:	pointer to variable to store the number of read bytes
+ * @buf:	the databuffer to put data
+ * @oob_buf:	filesystem supplied oob data buffer (can be NULL)
+ * @oobsel:	oob selection structure
+ * @flags:	flag to indicate if nand_get_device/nand_release_device should be preformed
+ *		and how many corrected error bits are acceptable:
+ *		  bits 0..7 - number of tolerable errors
+ *		  bit  8    - 0 == do not get/release chip, 1 == get/release chip
+ *
+ * NAND read with ECC
+ */
+int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
+			     size_t * retlen, u_char * buf, u_char * oob_buf, 
+			     struct nand_oobinfo *oobsel, int flags)
+{
+
 	int i, j, col, realpage, page, end, ecc, chipnr, sndcmd = 1;
 	int read = 0, oob = 0, ecc_status = 0, ecc_failed = 0;
 	struct nand_chip *this = mtd->priv;
@@ -1051,12 +1132,9 @@ static int nand_read_ecc (struct mtd_inf
 	}
 
 	/* Grab the lock and see if the device is available */
-	nand_get_device (this, mtd ,FL_READING);
+	if (flags & NAND_GET_DEVICE)
+		nand_get_device (this, mtd, FL_READING);
 
-	/* use userspace supplied oobinfo, if zero */
-	if (oobsel == NULL)
-		oobsel = &mtd->oobinfo;
-	
 	/* Autoplace of oob data ? Use the default placement scheme */
 	if (oobsel->useecc == MTD_NANDECC_AUTOPLACE)
 		oobsel = this->autooob;
@@ -1118,7 +1196,8 @@ static int nand_read_ecc (struct mtd_inf
 		}	
 
 		/* get oob area, if we have no oob buffer from fs-driver */
-		if (!oob_buf || oobsel->useecc == MTD_NANDECC_AUTOPLACE)
+		if (!oob_buf || oobsel->useecc == MTD_NANDECC_AUTOPLACE ||
+			oobsel->useecc == MTD_NANDECC_AUTOPL_USR)
 			oob_data = &this->data_buf[end];
 
 		eccsteps = this->eccsteps;
@@ -1155,7 +1234,8 @@ static int nand_read_ecc (struct mtd_inf
 					/* We calc error correction directly, it checks the hw
 					 * generator for an error, reads back the syndrome and
 					 * does the error correction on the fly */
-					if (this->correct_data(mtd, &data_poi[datidx], &oob_data[i], &ecc_code[i]) == -1) {
+					ecc_status = this->correct_data(mtd, &data_poi[datidx], &oob_data[i], &ecc_code[i]);
+					if ((ecc_status == -1) || (ecc_status > (flags && 0xff))) {
 						DEBUG (MTD_DEBUG_LEVEL0, "nand_read_ecc: " 
 							"Failed ECC read, page 0x%08x on chip %d\n", page, chipnr);
 						ecc_failed++;
@@ -1194,7 +1274,7 @@ static int nand_read_ecc (struct mtd_inf
 				p[i] = ecc_status;
 			}
 			
-			if (ecc_status == -1) {	
+			if ((ecc_status == -1) || (ecc_status > (flags && 0xff))) {	
 				DEBUG (MTD_DEBUG_LEVEL0, "nand_read_ecc: " "Failed ECC read, page 0x%08x\n", page);
 				ecc_failed++;
 			}
@@ -1206,14 +1286,14 @@ static int nand_read_ecc (struct mtd_inf
 			/* without autoplace. Legacy mode used by YAFFS1 */
 			switch(oobsel->useecc) {
 			case MTD_NANDECC_AUTOPLACE:
+			case MTD_NANDECC_AUTOPL_USR:
 				/* Walk through the autoplace chunks */
-				for (i = 0, j = 0; j < mtd->oobavail; i++) {
+				for (i = 0; oobsel->oobfree[i][1]; i++) {
 					int from = oobsel->oobfree[i][0];
 					int num = oobsel->oobfree[i][1];
 					memcpy(&oob_buf[oob], &oob_data[from], num);
-					j+= num;
+					oob += num;
 				}
-				oob += mtd->oobavail;
 				break;
 			case MTD_NANDECC_PLACE:
 				/* YAFFS1 legacy mode */
@@ -1239,7 +1319,7 @@ static int nand_read_ecc (struct mtd_inf
 		if (!this->dev_ready) 
 			udelay (this->chip_delay);
 		else
-			while (!this->dev_ready(mtd));	
+			nand_wait_ready(mtd);
 			
 		if (read == len)
 			break;	
@@ -1264,7 +1344,8 @@ static int nand_read_ecc (struct mtd_inf
 	}
 
 	/* Deselect and wake up anyone waiting on the device */
-	nand_release_device(mtd);
+	if (flags & NAND_GET_DEVICE)
+		nand_release_device(mtd);
 
 	/*
 	 * Return success, if no ECC failures, else -EBADMSG
@@ -1328,16 +1409,6 @@ static int nand_read_oob (struct mtd_inf
 		thislen = min_t(int, thislen, len);
 		this->read_buf(mtd, &buf[i], thislen);
 		i += thislen;
-		
-		/* Apply delay or wait for ready/busy pin 
-		 * Do this before the AUTOINCR check, so no problems
-		 * arise if a chip which does auto increment
-		 * is marked as NOAUTOINCR by the board driver.
-		*/
-		if (!this->dev_ready) 
-			udelay (this->chip_delay);
-		else
-			while (!this->dev_ready(mtd));	
 
 		/* Read more ? */
 		if (i < len) {
@@ -1351,6 +1422,16 @@ static int nand_read_oob (struct mtd_inf
 				this->select_chip(mtd, chipnr);
 			}
 				
+			/* Apply delay or wait for ready/busy pin 
+			 * Do this before the AUTOINCR check, so no problems
+			 * arise if a chip which does auto increment
+			 * is marked as NOAUTOINCR by the board driver.
+			 */
+			if (!this->dev_ready) 
+				udelay (this->chip_delay);
+			else
+				nand_wait_ready(mtd);
+
 			/* Check, if the chip supports auto page increment 
 			 * or if we have hit a block boundary. 
 			*/ 
@@ -1417,7 +1498,7 @@ int nand_read_raw (struct mtd_info *mtd,
 		if (!this->dev_ready) 
 			udelay (this->chip_delay);
 		else
-			while (!this->dev_ready(mtd));	
+			nand_wait_ready(mtd);
 			
 		/* Check, if the chip supports auto page increment */ 
 		if (!NAND_CANAUTOINCR(this) || !(page & blockcheck))
@@ -1567,6 +1648,8 @@ static int nand_write_ecc (struct mtd_in
 		oobsel = this->autooob;
 		autoplace = 1;
 	}	
+	if (oobsel->useecc == MTD_NANDECC_AUTOPL_USR)
+		autoplace = 1;
 
 	/* Setup variables and oob buffer */
 	totalpages = len >> this->page_shift;
@@ -1733,7 +1816,7 @@ static int nand_write_oob (struct mtd_in
 	status = this->waitfunc (mtd, this, FL_WRITING);
 
 	/* See if device thinks it succeeded */
-	if (status & 0x01) {
+	if (status & NAND_STATUS_FAIL) {
 		DEBUG (MTD_DEBUG_LEVEL0, "nand_write_oob: " "Failed write, page 0x%08x\n", page);
 		ret = -EIO;
 		goto out;
@@ -1841,6 +1924,8 @@ static int nand_writev_ecc (struct mtd_i
 		oobsel = this->autooob;
 		autoplace = 1;
 	}	
+	if (oobsel->useecc == MTD_NANDECC_AUTOPL_USR)
+		autoplace = 1;
 
 	/* Setup start page */
 	page = (int) (to >> this->page_shift);
@@ -1987,6 +2072,7 @@ static int nand_erase (struct mtd_info *
 	return nand_erase_nand (mtd, instr, 0);
 }
  
+#define BBT_PAGE_MASK	0xffffff3f
 /**
  * nand_erase_intern - [NAND Interface] erase block(s)
  * @mtd:	MTD device structure
@@ -1999,6 +2085,10 @@ int nand_erase_nand (struct mtd_info *mt
 {
 	int page, len, status, pages_per_block, ret, chipnr;
 	struct nand_chip *this = mtd->priv;
+	int rewrite_bbt[NAND_MAX_CHIPS]={0};	/* flags to indicate the page, if bbt needs to be rewritten. */
+	unsigned int bbt_masked_page;		/* bbt mask to compare to page being erased. */
+						/* It is used to see if the current page is in the same */
+						/*   256 block group and the same bank as the bbt. */
 
 	DEBUG (MTD_DEBUG_LEVEL3,
 	       "nand_erase: start = 0x%08x, len = %i\n", (unsigned int) instr->addr, (unsigned int) instr->len);
@@ -2044,6 +2134,13 @@ int nand_erase_nand (struct mtd_info *mt
 		goto erase_exit;
 	}
 
+	/* if BBT requires refresh, set the BBT page mask to see if the BBT should be rewritten */
+	if (this->options & BBT_AUTO_REFRESH) {
+		bbt_masked_page = this->bbt_td->pages[chipnr] & BBT_PAGE_MASK;
+	} else {
+		bbt_masked_page = 0xffffffff;	/* should not match anything */
+	}
+
 	/* Loop through the pages */
 	len = instr->len;
 
@@ -2066,13 +2163,26 @@ int nand_erase_nand (struct mtd_info *mt
 		
 		status = this->waitfunc (mtd, this, FL_ERASING);
 
+		/* See if operation failed and additional status checks are available */
+		if ((status & NAND_STATUS_FAIL) && (this->errstat)) {
+			status = this->errstat(mtd, this, FL_ERASING, status, page);
+		}
+
 		/* See if block erase succeeded */
-		if (status & 0x01) {
+		if (status & NAND_STATUS_FAIL) {
 			DEBUG (MTD_DEBUG_LEVEL0, "nand_erase: " "Failed erase, page 0x%08x\n", page);
 			instr->state = MTD_ERASE_FAILED;
 			instr->fail_addr = (page << this->page_shift);
 			goto erase_exit;
 		}
+
+		/* if BBT requires refresh, set the BBT rewrite flag to the page being erased */
+		if (this->options & BBT_AUTO_REFRESH) {
+			if (((page & BBT_PAGE_MASK) == bbt_masked_page) && 
+			     (page != this->bbt_td->pages[chipnr])) {
+				rewrite_bbt[chipnr] = (page << this->page_shift);
+			}
+		}
 		
 		/* Increment page address and decrement length */
 		len -= (1 << this->phys_erase_shift);
@@ -2083,6 +2193,13 @@ int nand_erase_nand (struct mtd_info *mt
 			chipnr++;
 			this->select_chip(mtd, -1);
 			this->select_chip(mtd, chipnr);
+
+			/* if BBT requires refresh and BBT-PERCHIP, 
+			 *   set the BBT page mask to see if this BBT should be rewritten */
+			if ((this->options & BBT_AUTO_REFRESH) && (this->bbt_td->options & NAND_BBT_PERCHIP)) {
+				bbt_masked_page = this->bbt_td->pages[chipnr] & BBT_PAGE_MASK;
+			}
+
 		}
 	}
 	instr->state = MTD_ERASE_DONE;
@@ -2097,6 +2214,18 @@ erase_exit:
 	/* Deselect and wake up anyone waiting on the device */
 	nand_release_device(mtd);
 
+	/* if BBT requires refresh and erase was successful, rewrite any selected bad block tables */
+	if ((this->options & BBT_AUTO_REFRESH) && (!ret)) {
+		for (chipnr = 0; chipnr < this->numchips; chipnr++) {
+			if (rewrite_bbt[chipnr]) {
+				/* update the BBT for chip */
+				DEBUG (MTD_DEBUG_LEVEL0, "nand_erase_nand: nand_update_bbt (%d:0x%0x 0x%0x)\n", 
+					chipnr, rewrite_bbt[chipnr], this->bbt_td->pages[chipnr]);
+				nand_update_bbt (mtd, rewrite_bbt[chipnr]);
+			}
+		}
+	}
+
 	/* Return more or less happy */
 	return ret;
 }
@@ -2168,7 +2297,7 @@ static int nand_block_markbad (struct mt
  */
 int nand_scan (struct mtd_info *mtd, int maxchips)
 {
-	int i, j, nand_maf_id, nand_dev_id, busw;
+	int i, nand_maf_id, nand_dev_id, busw, maf_id;
 	struct nand_chip *this = mtd->priv;
 
 	/* Get buswidth to select the correct functions*/
@@ -2256,12 +2385,18 @@ int nand_scan (struct mtd_info *mtd, int
 			busw = nand_flash_ids[i].options & NAND_BUSWIDTH_16;
 		}
 
+		/* Try to identify manufacturer */
+		for (maf_id = 0; nand_manuf_ids[maf_id].id != 0x0; maf_id++) {
+			if (nand_manuf_ids[maf_id].id == nand_maf_id)
+				break;
+		}
+
 		/* Check, if buswidth is correct. Hardware drivers should set
 		 * this correct ! */
 		if (busw != (this->options & NAND_BUSWIDTH_16)) {
 			printk (KERN_INFO "NAND device: Manufacturer ID:"
 				" 0x%02x, Chip ID: 0x%02x (%s %s)\n", nand_maf_id, nand_dev_id, 
-				nand_manuf_ids[i].name , mtd->name);
+				nand_manuf_ids[maf_id].name , mtd->name);
 			printk (KERN_WARNING 
 				"NAND bus width %d instead %d bit\n", 
 					(this->options & NAND_BUSWIDTH_16) ? 16 : 8,
@@ -2300,14 +2435,9 @@ int nand_scan (struct mtd_info *mtd, int
 		if (mtd->oobblock > 512 && this->cmdfunc == nand_command)
 			this->cmdfunc = nand_command_lp;
 				
-		/* Try to identify manufacturer */
-		for (j = 0; nand_manuf_ids[j].id != 0x0; j++) {
-			if (nand_manuf_ids[j].id == nand_maf_id)
-				break;
-		}
 		printk (KERN_INFO "NAND device: Manufacturer ID:"
 			" 0x%02x, Chip ID: 0x%02x (%s %s)\n", nand_maf_id, nand_dev_id, 
-			nand_manuf_ids[j].name , nand_flash_ids[i].name);
+			nand_manuf_ids[maf_id].name , nand_flash_ids[i].name);
 		break;
 	}
 
@@ -2388,12 +2518,9 @@ int nand_scan (struct mtd_info *mtd, int
 	
 	/* The number of bytes available for the filesystem to place fs dependend
 	 * oob data */
-	if (this->options & NAND_BUSWIDTH_16) {
-		mtd->oobavail = mtd->oobsize - (this->autooob->eccbytes + 2);
-		if (this->autooob->eccbytes & 0x01)
-			mtd->oobavail--;
-	} else
-		mtd->oobavail = mtd->oobsize - (this->autooob->eccbytes + 1);
+	mtd->oobavail = 0;
+	for (i = 0; this->autooob->oobfree[i][1]; i++)
+		mtd->oobavail += this->autooob->oobfree[i][1];
 
 	/* 
 	 * check ECC mode, default to software
@@ -2524,6 +2651,10 @@ int nand_scan (struct mtd_info *mtd, int
 	memcpy(&mtd->oobinfo, this->autooob, sizeof(mtd->oobinfo));
 
 	mtd->owner = THIS_MODULE;
+	
+	/* Check, if we should skip the bad block table scan */
+	if (this->options & NAND_SKIP_BBTSCAN)
+		return 0;
 
 	/* Build bad block table */
 	return this->scan_bbt (mtd);
@@ -2555,8 +2686,8 @@ void nand_release (struct mtd_info *mtd)
 		kfree (this->data_buf);
 }
 
-EXPORT_SYMBOL (nand_scan);
-EXPORT_SYMBOL (nand_release);
+EXPORT_SYMBOL_GPL (nand_scan);
+EXPORT_SYMBOL_GPL (nand_release);
 
 MODULE_LICENSE ("GPL");
 MODULE_AUTHOR ("Steven J. Hill <sjhill@realitydiluted.com>, Thomas Gleixner <tglx@linutronix.de>");
diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c
--- a/drivers/mtd/nand/nand_bbt.c
+++ b/drivers/mtd/nand/nand_bbt.c
@@ -6,7 +6,7 @@
  *   
  *  Copyright (C) 2004 Thomas Gleixner (tglx@linutronix.de)
  *
- * $Id: nand_bbt.c,v 1.28 2004/11/13 10:19:09 gleixner Exp $
+ * $Id: nand_bbt.c,v 1.35 2005/07/15 13:53:47 gleixner Exp $
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -77,7 +77,7 @@
 */
 static int check_pattern (uint8_t *buf, int len, int paglen, struct nand_bbt_descr *td)
 {
-	int i, end;
+	int i, end = 0;
 	uint8_t *p = buf;
 
 	end = paglen + td->offs;
@@ -95,9 +95,9 @@ static int check_pattern (uint8_t *buf, 
 			return -1;
 	}
 
-	p += td->len;
-	end += td->len;
 	if (td->options & NAND_BBT_SCANEMPTY) {
+		p += td->len;
+		end += td->len;
 		for (i = end; i < len; i++) {
 			if (*p++ != 0xff)
 				return -1;
@@ -106,6 +106,29 @@ static int check_pattern (uint8_t *buf, 
 	return 0;
 }
 
+/** 
+ * check_short_pattern - [GENERIC] check if a pattern is in the buffer
+ * @buf:	the buffer to search
+ * @td:		search pattern descriptor
+ *
+ * Check for a pattern at the given place. Used to search bad block
+ * tables and good / bad block identifiers. Same as check_pattern, but 
+ * no optional empty check
+ *
+*/
+static int check_short_pattern (uint8_t *buf, struct nand_bbt_descr *td)
+{
+	int i;
+	uint8_t *p = buf;
+
+	/* Compare the pattern */
+	for (i = 0; i < td->len; i++) {
+		if (p[td->offs + i] != td->pattern[i])
+			return -1;
+	}
+	return 0;
+}
+
 /**
  * read_bbt - [GENERIC] Read the bad block table starting from page
  * @mtd:	MTD device structure
@@ -252,7 +275,7 @@ static int read_abs_bbts (struct mtd_inf
  * Create a bad block table by scanning the device
  * for the given good/bad block identify pattern
  */
-static void create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *bd, int chip)
+static int create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *bd, int chip)
 {
 	struct nand_chip *this = mtd->priv;
 	int i, j, numblocks, len, scanlen;
@@ -270,9 +293,17 @@ static void create_bbt (struct mtd_info 
 		else	
 			len = 1;
 	}
-	scanlen	= mtd->oobblock + mtd->oobsize;
-	readlen = len * mtd->oobblock;
-	ooblen = len * mtd->oobsize;
+
+	if (!(bd->options & NAND_BBT_SCANEMPTY)) {
+		/* We need only read few bytes from the OOB area */
+		scanlen = ooblen = 0;
+		readlen = bd->len;
+	} else {
+		/* Full page content should be read */
+		scanlen	= mtd->oobblock + mtd->oobsize;
+		readlen = len * mtd->oobblock;
+		ooblen = len * mtd->oobsize;
+	}
 
 	if (chip == -1) {
 		/* Note that numblocks is 2 * (real numblocks) here, see i+=2 below as it
@@ -284,7 +315,7 @@ static void create_bbt (struct mtd_info 
 		if (chip >= this->numchips) {
 			printk (KERN_WARNING "create_bbt(): chipnr (%d) > available chips (%d)\n",
 				chip + 1, this->numchips);
-			return;	
+			return -EINVAL;
 		}
 		numblocks = this->chipsize >> (this->bbt_erase_shift - 1);
 		startblock = chip * numblocks;
@@ -293,18 +324,42 @@ static void create_bbt (struct mtd_info 
 	}
 	
 	for (i = startblock; i < numblocks;) {
-		nand_read_raw (mtd, buf, from, readlen, ooblen);
+		int ret;
+		
+		if (bd->options & NAND_BBT_SCANEMPTY)
+			if ((ret = nand_read_raw (mtd, buf, from, readlen, ooblen)))
+				return ret;
+
 		for (j = 0; j < len; j++) {
-			if (check_pattern (&buf[j * scanlen], scanlen, mtd->oobblock, bd)) {
-				this->bbt[i >> 3] |= 0x03 << (i & 0x6);
-				printk (KERN_WARNING "Bad eraseblock %d at 0x%08x\n", 
-					i >> 1, (unsigned int) from);
-				break;
+			if (!(bd->options & NAND_BBT_SCANEMPTY)) {
+				size_t retlen;
+				
+				/* Read the full oob until read_oob is fixed to 
+				 * handle single byte reads for 16 bit buswidth */
+				ret = mtd->read_oob(mtd, from + j * mtd->oobblock,
+							mtd->oobsize, &retlen, buf);
+				if (ret)
+					return ret;
+
+				if (check_short_pattern (buf, bd)) {
+					this->bbt[i >> 3] |= 0x03 << (i & 0x6);
+					printk (KERN_WARNING "Bad eraseblock %d at 0x%08x\n", 
+						i >> 1, (unsigned int) from);
+					break;
+				}
+			} else {
+				if (check_pattern (&buf[j * scanlen], scanlen, mtd->oobblock, bd)) {
+					this->bbt[i >> 3] |= 0x03 << (i & 0x6);
+					printk (KERN_WARNING "Bad eraseblock %d at 0x%08x\n", 
+						i >> 1, (unsigned int) from);
+					break;
+				}
 			}
 		}
 		i += 2;
 		from += (1 << this->bbt_erase_shift);
 	}
+	return 0;
 }
 
 /**
@@ -589,14 +644,12 @@ write:	
  * The function creates a memory based bbt by scanning the device 
  * for manufacturer / software marked good / bad blocks
 */
-static int nand_memory_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd)
+static inline int nand_memory_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd)
 {
 	struct nand_chip *this = mtd->priv;
 
-	/* Ensure that we only scan for the pattern and nothing else */
-	bd->options = 0;
-	create_bbt (mtd, this->data_buf, bd, -1);
-	return 0;
+	bd->options &= ~NAND_BBT_SCANEMPTY;
+	return create_bbt (mtd, this->data_buf, bd, -1);
 }
 
 /**
@@ -808,8 +861,14 @@ int nand_scan_bbt (struct mtd_info *mtd,
 	/* If no primary table decriptor is given, scan the device
 	 * to build a memory based bad block table
 	 */
-	if (!td)
-		return nand_memory_bbt(mtd, bd);
+	if (!td) {
+		if ((res = nand_memory_bbt(mtd, bd))) {
+			printk (KERN_ERR "nand_bbt: Can't scan flash and build the RAM-based BBT\n");
+			kfree (this->bbt);
+			this->bbt = NULL;
+		}
+		return res;
+	}
 
 	/* Allocate a temporary buffer for one eraseblock incl. oob */
 	len = (1 << this->bbt_erase_shift);
@@ -904,14 +963,11 @@ out:	
 }
 
 /* Define some generic bad / good block scan pattern which are used 
- * while scanning a device for factory marked good / bad blocks
- * 
- * The memory based patterns just 
- */
+ * while scanning a device for factory marked good / bad blocks. */
 static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
 
 static struct nand_bbt_descr smallpage_memorybased = {
-	.options = 0,
+	.options = NAND_BBT_SCAN2NDPAGE,
 	.offs = 5,
 	.len = 1,
 	.pattern = scan_ff_pattern
@@ -1042,7 +1098,7 @@ int nand_isbad_bbt (struct mtd_info *mtd
 	res = (this->bbt[block >> 3] >> (block & 0x06)) & 0x03;
 
 	DEBUG (MTD_DEBUG_LEVEL2, "nand_isbad_bbt(): bbt info for offs 0x%08x: (block %d) 0x%02x\n", 
-		(unsigned int)offs, res, block >> 1);
+		(unsigned int)offs, block >> 1, res);
 
 	switch ((int)res) {
 	case 0x00:	return 0;
diff --git a/drivers/mtd/nand/nand_ids.c b/drivers/mtd/nand/nand_ids.c
--- a/drivers/mtd/nand/nand_ids.c
+++ b/drivers/mtd/nand/nand_ids.c
@@ -2,8 +2,8 @@
  *  drivers/mtd/nandids.c
  *
  *  Copyright (C) 2002 Thomas Gleixner (tglx@linutronix.de)
-  *
- * $Id: nand_ids.c,v 1.10 2004/05/26 13:40:12 gleixner Exp $
+ *
+ * $Id: nand_ids.c,v 1.14 2005/06/23 09:38:50 gleixner Exp $
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -56,17 +56,24 @@ struct nand_flash_dev nand_flash_ids[] =
 	{"NAND 64MiB 3,3V 16-bit", 	0x56, 512, 64, 0x4000, NAND_BUSWIDTH_16},
 	
 	{"NAND 128MiB 1,8V 8-bit", 	0x78, 512, 128, 0x4000, 0},
+	{"NAND 128MiB 1,8V 8-bit", 	0x39, 512, 128, 0x4000, 0},
 	{"NAND 128MiB 3,3V 8-bit", 	0x79, 512, 128, 0x4000, 0},
 	{"NAND 128MiB 1,8V 16-bit", 	0x72, 512, 128, 0x4000, NAND_BUSWIDTH_16},
+	{"NAND 128MiB 1,8V 16-bit", 	0x49, 512, 128, 0x4000, NAND_BUSWIDTH_16},
 	{"NAND 128MiB 3,3V 16-bit", 	0x74, 512, 128, 0x4000, NAND_BUSWIDTH_16},
+	{"NAND 128MiB 3,3V 16-bit", 	0x59, 512, 128, 0x4000, NAND_BUSWIDTH_16},
 	
 	{"NAND 256MiB 3,3V 8-bit", 	0x71, 512, 256, 0x4000, 0},
 
-	{"NAND 512MiB 3,3V 8-bit", 	0xDC, 512, 512, 0x4000, 0},
-	
 	/* These are the new chips with large page size. The pagesize
 	* and the erasesize is determined from the extended id bytes
 	*/
+	/*512 Megabit */
+	{"NAND 64MiB 1,8V 8-bit", 	0xA2, 0,  64, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
+	{"NAND 64MiB 3,3V 8-bit", 	0xF2, 0,  64, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
+	{"NAND 64MiB 1,8V 16-bit", 	0xB2, 0,  64, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
+	{"NAND 64MiB 3,3V 16-bit", 	0xC2, 0,  64, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
+	
 	/* 1 Gigabit */
 	{"NAND 128MiB 1,8V 8-bit", 	0xA1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
 	{"NAND 128MiB 3,3V 8-bit", 	0xF1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
@@ -103,7 +110,7 @@ struct nand_flash_dev nand_flash_ids[] =
 	 * Anyway JFFS2 would increase the eraseblock size so we chose a combined one which can be erased in one go
 	 * There are more speed improvements for reads and writes possible, but not implemented now 
 	 */
-	{"AND 128MiB 3,3V 8-bit",	0x01, 2048, 128, 0x4000, NAND_IS_AND | NAND_NO_AUTOINCR | NAND_4PAGE_ARRAY},
+	{"AND 128MiB 3,3V 8-bit",	0x01, 2048, 128, 0x4000, NAND_IS_AND | NAND_NO_AUTOINCR | NAND_4PAGE_ARRAY | BBT_AUTO_REFRESH},
 
 	{NULL,}
 };
@@ -118,6 +125,7 @@ struct nand_manufacturers nand_manuf_ids
 	{NAND_MFR_NATIONAL, "National"},
 	{NAND_MFR_RENESAS, "Renesas"},
 	{NAND_MFR_STMICRO, "ST Micro"},
+        {NAND_MFR_HYNIX, "Hynix"},
 	{0x0, "Unknown"}
 };
 
diff --git a/drivers/mtd/nand/nandsim.c b/drivers/mtd/nand/nandsim.c
--- a/drivers/mtd/nand/nandsim.c
+++ b/drivers/mtd/nand/nandsim.c
@@ -22,7 +22,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
  *
- * $Id: nandsim.c,v 1.7 2004/12/06 11:53:06 dedekind Exp $
+ * $Id: nandsim.c,v 1.8 2005/03/19 15:33:56 dedekind Exp $
  */
 
 #include <linux/config.h>
@@ -1484,33 +1484,6 @@ ns_nand_verify_buf(struct mtd_info *mtd,
 }
 
 /*
- * Having only NAND chip IDs we call nand_scan which detects NAND flash
- * parameters and then calls scan_bbt in order to scan/find/build the
- * NAND flash bad block table. But since at that moment the NAND flash
- * image isn't allocated in the simulator, errors arise. To avoid this
- * we redefine the scan_bbt callback and initialize the nandsim structure
- * before the flash media scanning.
- */
-int ns_scan_bbt(struct mtd_info *mtd)
-{ 
-	struct nand_chip *chip = (struct nand_chip *)mtd->priv;
-	struct nandsim   *ns   = (struct nandsim *)(chip->priv);
-	int retval;
-
-	if (!NS_IS_INITIALIZED(ns))
-		if ((retval = init_nandsim(mtd)) != 0) {
-			NS_ERR("scan_bbt: can't initialize the nandsim structure\n");
-			return retval;
-		}
-	if ((retval = nand_default_bbt(mtd)) != 0) {
-		free_nandsim(ns);
-		return retval;
-	}
-
-	return 0;
-}
-
-/*
  * Module initialization function
  */
 int __init ns_init_module(void)
@@ -1544,7 +1517,6 @@ int __init ns_init_module(void)
 	chip->hwcontrol  = ns_hwcontrol;
 	chip->read_byte  = ns_nand_read_byte;
 	chip->dev_ready  = ns_device_ready;
-	chip->scan_bbt   = ns_scan_bbt;
 	chip->write_byte = ns_nand_write_byte;
 	chip->write_buf  = ns_nand_write_buf;
 	chip->read_buf   = ns_nand_read_buf;
@@ -1552,6 +1524,7 @@ int __init ns_init_module(void)
 	chip->write_word = ns_nand_write_word;
 	chip->read_word  = ns_nand_read_word;
 	chip->eccmode    = NAND_ECC_SOFT;
+	chip->options   |= NAND_SKIP_BBTSCAN;
 
 	/* 
 	 * Perform minimum nandsim structure initialization to handle
@@ -1580,6 +1553,16 @@ int __init ns_init_module(void)
 		goto error;
 	}
 
+	if ((retval = init_nandsim(nsmtd)) != 0) {
+		NS_ERR("scan_bbt: can't initialize the nandsim structure\n");
+		goto error;
+	}
+	
+	if ((retval = nand_default_bbt(nsmtd)) != 0) {
+		free_nandsim(nand);
+		goto error;
+	}
+
 	/* Register NAND as one big partition */
 	add_mtd_partitions(nsmtd, &nand->part, 1);
 
diff --git a/drivers/mtd/nand/rtc_from4.c b/drivers/mtd/nand/rtc_from4.c
--- a/drivers/mtd/nand/rtc_from4.c
+++ b/drivers/mtd/nand/rtc_from4.c
@@ -6,7 +6,7 @@
  *  Derived from drivers/mtd/nand/spia.c
  *       Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com)
  *
- * $Id: rtc_from4.c,v 1.7 2004/11/04 12:53:10 gleixner Exp $
+ * $Id: rtc_from4.c,v 1.9 2005/01/24 20:40:11 dmarlin Exp $
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -83,13 +83,18 @@ static struct mtd_info *rtc_from4_mtd = 
 #define RTC_FROM4_RS_ECC_CHK		(RTC_FROM4_NAND_ADDR_FPGA | 0x00000070)
 #define RTC_FROM4_RS_ECC_CHK_ERROR	(1 << 7)
 
+#define ERR_STAT_ECC_AVAILABLE		0x20
+
 /* Undefine for software ECC */
 #define RTC_FROM4_HWECC	1
 
+/* Define as 1 for no virtual erase blocks (in JFFS2) */
+#define RTC_FROM4_NO_VIRTBLOCKS	0
+
 /*
  * Module stuff
  */
-static void __iomem *rtc_from4_fio_base = P2SEGADDR(RTC_FROM4_FIO_BASE);
+static void __iomem *rtc_from4_fio_base = (void *)P2SEGADDR(RTC_FROM4_FIO_BASE);
 
 const static struct mtd_partition partition_info[] = {
         {
@@ -267,7 +272,6 @@ static void rtc_from4_nand_select_chip(s
 }
 
 
-
 /*
  * rtc_from4_nand_device_ready - hardware specific ready/busy check
  * @mtd:	MTD device structure
@@ -286,6 +290,40 @@ static int rtc_from4_nand_device_ready(s
 
 }
 
+
+/*
+ * deplete - code to perform device recovery in case there was a power loss
+ * @mtd:	MTD device structure
+ * @chip:	Chip to select (0 == slot 3, 1 == slot 4)
+ *
+ * If there was a sudden loss of power during an erase operation, a 
+ * "device recovery" operation must be performed when power is restored
+ * to ensure correct operation.  This routine performs the required steps
+ * for the requested chip.
+ *
+ * See page 86 of the data sheet for details.
+ *
+ */
+static void deplete(struct mtd_info *mtd, int chip)
+{
+        struct nand_chip *this = mtd->priv;
+
+        /* wait until device is ready */
+        while (!this->dev_ready(mtd));
+
+	this->select_chip(mtd, chip);
+                                                                                                                                              
+	/* Send the commands for device recovery, phase 1 */
+	this->cmdfunc (mtd, NAND_CMD_DEPLETE1, 0x0000, 0x0000);
+	this->cmdfunc (mtd, NAND_CMD_DEPLETE2, -1, -1);
+
+	/* Send the commands for device recovery, phase 2 */
+	this->cmdfunc (mtd, NAND_CMD_DEPLETE1, 0x0000, 0x0004);
+	this->cmdfunc (mtd, NAND_CMD_DEPLETE2, -1, -1);
+
+}
+
+
 #ifdef RTC_FROM4_HWECC
 /*
  * rtc_from4_enable_hwecc - hardware specific hardware ECC enable function
@@ -329,6 +367,7 @@ static void rtc_from4_enable_hwecc(struc
 
 }
 
+
 /*
  * rtc_from4_calculate_ecc - hardware specific code to read ECC code
  * @mtd:	MTD device structure
@@ -356,6 +395,7 @@ static void rtc_from4_calculate_ecc(stru
 	ecc_code[7] |= 0x0f;	/* set the last four bits (not used) */
 }
 
+
 /*
  * rtc_from4_correct_data - hardware specific code to correct data using ECC code
  * @mtd:	MTD device structure
@@ -365,16 +405,14 @@ static void rtc_from4_calculate_ecc(stru
  *
  * The FPGA tells us fast, if there's an error or not. If no, we go back happy
  * else we read the ecc results from the fpga and call the rs library to decode
- * and hopefully correct the error
+ * and hopefully correct the error.
  *
- * For now I use the code, which we read from the FLASH to use the RS lib,
- * as the syndrom conversion has a unresolved issue.
  */
 static int rtc_from4_correct_data(struct mtd_info *mtd, const u_char *buf, u_char *ecc1, u_char *ecc2)
 {
 	int i, j, res;
 	unsigned short status; 
-	uint16_t par[6], syn[6], tmp;
+	uint16_t par[6], syn[6];
 	uint8_t ecc[8];
         volatile unsigned short *rs_ecc;
 
@@ -416,15 +454,86 @@ static int rtc_from4_correct_data(struct
 	}
 
 	/* Let the library code do its magic.*/
-	res = decode_rs8(rs_decoder, buf, par, 512, syn, 0, NULL, 0xff, NULL);
+	res = decode_rs8(rs_decoder, (uint8_t *)buf, par, 512, syn, 0, NULL, 0xff, NULL);
 	if (res > 0) {
 		DEBUG (MTD_DEBUG_LEVEL0, "rtc_from4_correct_data: " 
 			"ECC corrected %d errors on read\n", res);
 	}
 	return res;
 }
+
+
+/**
+ * rtc_from4_errstat - perform additional error status checks
+ * @mtd:	MTD device structure
+ * @this:	NAND chip structure
+ * @state:	state or the operation
+ * @status:	status code returned from read status
+ * @page:	startpage inside the chip, must be called with (page & this->pagemask)
+ * 
+ * Perform additional error status checks on erase and write failures 
+ * to determine if errors are correctable.  For this device, correctable 
+ * 1-bit errors on erase and write are considered acceptable.
+ *
+ * note: see pages 34..37 of data sheet for details.
+ *
+ */
+static int rtc_from4_errstat(struct mtd_info *mtd, struct nand_chip *this, int state, int status, int page)
+{
+	int	er_stat=0;
+	int	rtn, retlen;
+	size_t	len;
+	uint8_t *buf;
+	int	i;
+
+	this->cmdfunc (mtd, NAND_CMD_STATUS_CLEAR, -1, -1);
+
+        if (state == FL_ERASING) {
+		for (i=0; i<4; i++) {
+			if (status & 1<<(i+1)) {
+				this->cmdfunc (mtd, (NAND_CMD_STATUS_ERROR + i + 1), -1, -1);
+				rtn = this->read_byte(mtd);
+				this->cmdfunc (mtd, NAND_CMD_STATUS_RESET, -1, -1);
+				if (!(rtn & ERR_STAT_ECC_AVAILABLE)) {
+					er_stat |= 1<<(i+1);	/* err_ecc_not_avail */
+				}
+			}
+		}
+	} else if (state == FL_WRITING) {
+		/* single bank write logic */
+		this->cmdfunc (mtd, NAND_CMD_STATUS_ERROR, -1, -1);
+		rtn = this->read_byte(mtd);
+		this->cmdfunc (mtd, NAND_CMD_STATUS_RESET, -1, -1);
+		if (!(rtn & ERR_STAT_ECC_AVAILABLE)) {
+			er_stat |= 1<<1;	/* err_ecc_not_avail */
+		} else {
+			len = mtd->oobblock;
+			buf = kmalloc (len, GFP_KERNEL);
+			if (!buf) {
+				printk (KERN_ERR "rtc_from4_errstat: Out of memory!\n");
+				er_stat = 1;			/* if we can't check, assume failed */
+			} else {
+				/* recovery read */
+				/* page read */
+				rtn = nand_do_read_ecc (mtd, page, len, &retlen, buf, NULL, this->autooob, 1);
+				if (rtn) {	/* if read failed or > 1-bit error corrected */
+					er_stat |= 1<<1;	/* ECC read failed */
+				}
+				kfree(buf);
+			}
+		}
+	}
+
+	rtn = status;
+	if (er_stat == 0) {				/* if ECC is available   */
+		rtn = (status & ~NAND_STATUS_FAIL);	/*   clear the error bit */
+	}
+
+	return rtn;
+}
 #endif
 
+
 /*
  * Main initialization routine
  */
@@ -432,6 +541,7 @@ int __init rtc_from4_init (void)
 {
 	struct nand_chip *this;
 	unsigned short bcr1, bcr2, wcr2;
+	int i;
 
 	/* Allocate memory for MTD device structure and private data */
 	rtc_from4_mtd = kmalloc(sizeof(struct mtd_info) + sizeof (struct nand_chip),
@@ -483,6 +593,8 @@ int __init rtc_from4_init (void)
 
         this->eccmode = NAND_ECC_HW8_512;
 	this->options |= NAND_HWECC_SYNDROME;
+	/* return the status of extra status and ECC checks */
+	this->errstat = rtc_from4_errstat;
 	/* set the nand_oobinfo to support FPGA H/W error detection */
 	this->autooob = &rtc_from4_nand_oobinfo;
 	this->enable_hwecc = rtc_from4_enable_hwecc;
@@ -504,6 +616,18 @@ int __init rtc_from4_init (void)
 		return -ENXIO;
 	}
 
+	/* Perform 'device recovery' for each chip in case there was a power loss. */
+	for (i=0; i < this->numchips; i++) {
+		deplete(rtc_from4_mtd, i);
+	}
+
+#if RTC_FROM4_NO_VIRTBLOCKS
+	/* use a smaller erase block to minimize wasted space when a block is bad */
+	/* note: this uses eight times as much RAM as using the default and makes */
+	/*       mounts take four times as long. */
+	rtc_from4_mtd->flags |= MTD_NO_VIRTBLOCKS;
+#endif
+
 	/* Register the partitions */
 	add_mtd_partitions(rtc_from4_mtd, partition_info, NUM_PARTITIONS);
 
diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c
--- a/drivers/mtd/nand/s3c2410.c
+++ b/drivers/mtd/nand/s3c2410.c
@@ -1,17 +1,24 @@
 /* linux/drivers/mtd/nand/s3c2410.c
  *
- * Copyright (c) 2004 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
+ * Copyright (c) 2004,2005 Simtec Electronics
+ *	http://www.simtec.co.uk/products/SWLINUX/
+ *	Ben Dooks <ben@simtec.co.uk>
  *
- * Samsung S3C2410 NAND driver
+ * Samsung S3C2410/S3C240 NAND driver
  *
  * Changelog:
  *	21-Sep-2004  BJD  Initial version
  *	23-Sep-2004  BJD  Mulitple device support
  *	28-Sep-2004  BJD  Fixed ECC placement for Hardware mode
  *	12-Oct-2004  BJD  Fixed errors in use of platform data
+ *	18-Feb-2005  BJD  Fix sparse errors
+ *	14-Mar-2005  BJD  Applied tglx's code reduction patch
+ *	02-May-2005  BJD  Fixed s3c2440 support
+ *	02-May-2005  BJD  Reduced hwcontrol decode
+ *	20-Jun-2005  BJD  Updated s3c2440 support, fixed timing bug
+ *	08-Jul-2005  BJD  Fix OOPS when no platform data supplied
  *
- * $Id: s3c2410.c,v 1.7 2005/01/05 18:05:14 dwmw2 Exp $
+ * $Id: s3c2410.c,v 1.14 2005/07/06 20:05:06 bjd Exp $
  *
  * 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
@@ -69,10 +76,10 @@ static int hardware_ecc = 0;
  */
 
 static struct nand_oobinfo nand_hw_eccoob = {
-	.useecc = MTD_NANDECC_AUTOPLACE,
-	.eccbytes = 3,
-	.eccpos = {0, 1, 2 },
-	.oobfree = { {8, 8} }
+	.useecc		= MTD_NANDECC_AUTOPLACE,
+	.eccbytes	= 3,
+	.eccpos		= {0, 1, 2 },
+	.oobfree	= { {8, 8} }
 };
 
 /* controller and mtd information */
@@ -99,8 +106,10 @@ struct s3c2410_nand_info {
 	struct device			*device;
 	struct resource			*area;
 	struct clk			*clk;
-	void				*regs;
+	void __iomem			*regs;
 	int				mtd_count;
+
+	unsigned char			is_s3c2440;
 };
 
 /* conversion functions */
@@ -165,12 +174,12 @@ static int s3c2410_nand_inithw(struct s3
 	/* calculate the timing information for the controller */
 
 	if (plat != NULL) {
-		tacls = s3c2410_nand_calc_rate(plat->tacls, clkrate, 8);
+		tacls  = s3c2410_nand_calc_rate(plat->tacls, clkrate, 4);
 		twrph0 = s3c2410_nand_calc_rate(plat->twrph0, clkrate, 8);
 		twrph1 = s3c2410_nand_calc_rate(plat->twrph1, clkrate, 8);
 	} else {
 		/* default timings */
-		tacls = 8;
+		tacls = 4;
 		twrph0 = 8;
 		twrph1 = 8;
 	}
@@ -185,10 +194,16 @@ static int s3c2410_nand_inithw(struct s3
 	       to_ns(twrph0, clkrate),
 	       to_ns(twrph1, clkrate));
 
-	cfg  = S3C2410_NFCONF_EN;
-	cfg |= S3C2410_NFCONF_TACLS(tacls-1);
-	cfg |= S3C2410_NFCONF_TWRPH0(twrph0-1);
-	cfg |= S3C2410_NFCONF_TWRPH1(twrph1-1);
+	if (!info->is_s3c2440) {
+		cfg  = S3C2410_NFCONF_EN;
+		cfg |= S3C2410_NFCONF_TACLS(tacls-1);
+		cfg |= S3C2410_NFCONF_TWRPH0(twrph0-1);
+		cfg |= S3C2410_NFCONF_TWRPH1(twrph1-1);
+	} else {
+		cfg   = S3C2440_NFCONF_TACLS(tacls-1);
+		cfg  |= S3C2440_NFCONF_TWRPH0(twrph0-1);
+		cfg  |= S3C2440_NFCONF_TWRPH1(twrph1-1);
+	}
 
 	pr_debug(PFX "NF_CONF is 0x%lx\n", cfg);
 
@@ -203,17 +218,22 @@ static void s3c2410_nand_select_chip(str
 	struct s3c2410_nand_info *info;
 	struct s3c2410_nand_mtd *nmtd; 
 	struct nand_chip *this = mtd->priv;
+	void __iomem *reg;
 	unsigned long cur;
+	unsigned long bit;
 
 	nmtd = this->priv;
 	info = nmtd->info;
 
-	cur = readl(info->regs + S3C2410_NFCONF);
+	bit = (info->is_s3c2440) ? S3C2440_NFCONT_nFCE : S3C2410_NFCONF_nFCE;
+	reg = info->regs+((info->is_s3c2440) ? S3C2440_NFCONT:S3C2410_NFCONF);
+
+	cur = readl(reg);
 
 	if (chip == -1) {
-		cur |= S3C2410_NFCONF_nFCE;
+		cur |= bit;
 	} else {
-		if (chip > nmtd->set->nr_chips) {
+		if (nmtd->set != NULL && chip > nmtd->set->nr_chips) {
 			printk(KERN_ERR PFX "chip %d out of range\n", chip);
 			return;
 		}
@@ -223,143 +243,76 @@ static void s3c2410_nand_select_chip(str
 				(info->platform->select_chip)(nmtd->set, chip);
 		}
 
-		cur &= ~S3C2410_NFCONF_nFCE;
+		cur &= ~bit;
 	}
 
-	writel(cur, info->regs + S3C2410_NFCONF);
+	writel(cur, reg);
 }
 
-/* command and control functions */
+/* command and control functions 
+ *
+ * Note, these all use tglx's method of changing the IO_ADDR_W field
+ * to make the code simpler, and use the nand layer's code to issue the
+ * command and address sequences via the proper IO ports.
+ *
+*/
 
 static void s3c2410_nand_hwcontrol(struct mtd_info *mtd, int cmd)
 {
 	struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd);
-	unsigned long cur;
+	struct nand_chip *chip = mtd->priv;
 
 	switch (cmd) {
 	case NAND_CTL_SETNCE:
-		cur = readl(info->regs + S3C2410_NFCONF);
-		cur &= ~S3C2410_NFCONF_nFCE;
-		writel(cur, info->regs + S3C2410_NFCONF);
-		break;
-
 	case NAND_CTL_CLRNCE:
-		cur = readl(info->regs + S3C2410_NFCONF);
-		cur |= S3C2410_NFCONF_nFCE;
-		writel(cur, info->regs + S3C2410_NFCONF);
+		printk(KERN_ERR "%s: called for NCE\n", __FUNCTION__);
 		break;
 
-		/* we don't need to implement these */
 	case NAND_CTL_SETCLE:
-	case NAND_CTL_CLRCLE:
+		chip->IO_ADDR_W = info->regs + S3C2410_NFCMD;
+		break;
+
 	case NAND_CTL_SETALE:
-	case NAND_CTL_CLRALE:
-		pr_debug(PFX "s3c2410_nand_hwcontrol(%d) unusedn", cmd);
+		chip->IO_ADDR_W = info->regs + S3C2410_NFADDR;
+		break;
+
+		/* NAND_CTL_CLRCLE: */
+		/* NAND_CTL_CLRALE: */
+	default:
+		chip->IO_ADDR_W = info->regs + S3C2410_NFDATA;
 		break;
 	}
 }
 
-/* s3c2410_nand_command
- *
- * This function implements sending commands and the relevant address
- * information to the chip, via the hardware controller. Since the
- * S3C2410 generates the correct ALE/CLE signaling automatically, we
- * do not need to use hwcontrol.
-*/
+/* command and control functions */
 
-static void s3c2410_nand_command (struct mtd_info *mtd, unsigned command,
-				  int column, int page_addr)
+static void s3c2440_nand_hwcontrol(struct mtd_info *mtd, int cmd)
 {
-	register struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd);
-	register struct nand_chip *this = mtd->priv;
-
-	/*
-	 * Write out the command to the device.
-	 */
-	if (command == NAND_CMD_SEQIN) {
-		int readcmd;
-
-		if (column >= mtd->oobblock) {
-			/* OOB area */
-			column -= mtd->oobblock;
-			readcmd = NAND_CMD_READOOB;
-		} else if (column < 256) {
-			/* First 256 bytes --> READ0 */
-			readcmd = NAND_CMD_READ0;
-		} else {
-			column -= 256;
-			readcmd = NAND_CMD_READ1;
-		}
-		
-		writeb(readcmd, info->regs + S3C2410_NFCMD);
-	}
-	writeb(command, info->regs + S3C2410_NFCMD);
-
-	/* Set ALE and clear CLE to start address cycle */
-
-	if (column != -1 || page_addr != -1) {
+	struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd);
+	struct nand_chip *chip = mtd->priv;
 
-		/* Serially input address */
-		if (column != -1) {
-			/* Adjust columns for 16 bit buswidth */
-			if (this->options & NAND_BUSWIDTH_16)
-				column >>= 1;
-			writeb(column, info->regs + S3C2410_NFADDR);
-		}
-		if (page_addr != -1) {
-			writeb((unsigned char) (page_addr), info->regs + S3C2410_NFADDR);
-			writeb((unsigned char) (page_addr >> 8), info->regs + S3C2410_NFADDR);
-			/* One more address cycle for higher density devices */
-			if (this->chipsize & 0x0c000000) 
-				writeb((unsigned char) ((page_addr >> 16) & 0x0f),
-				       info->regs + S3C2410_NFADDR);
-		}
-		/* Latch in address */
-	}
-	
-	/* 
-	 * program and erase have their own busy handlers 
-	 * status and sequential in needs no delay
-	*/
-	switch (command) {
-			
-	case NAND_CMD_PAGEPROG:
-	case NAND_CMD_ERASE1:
-	case NAND_CMD_ERASE2:
-	case NAND_CMD_SEQIN:
-	case NAND_CMD_STATUS:
-		return;
-
-	case NAND_CMD_RESET:
-		if (this->dev_ready)	
-			break;
+	switch (cmd) {
+	case NAND_CTL_SETNCE:
+	case NAND_CTL_CLRNCE:
+		printk(KERN_ERR "%s: called for NCE\n", __FUNCTION__);
+		break;
 
-		udelay(this->chip_delay);
-		writeb(NAND_CMD_STATUS, info->regs + S3C2410_NFCMD);
+	case NAND_CTL_SETCLE:
+		chip->IO_ADDR_W = info->regs + S3C2440_NFCMD;
+		break;
 
-		while ( !(this->read_byte(mtd) & 0x40));
-		return;
+	case NAND_CTL_SETALE:
+		chip->IO_ADDR_W = info->regs + S3C2440_NFADDR;
+		break;
 
-	/* This applies to read commands */	
+		/* NAND_CTL_CLRCLE: */
+		/* NAND_CTL_CLRALE: */
 	default:
-		/* 
-		 * If we don't have access to the busy pin, we apply the given
-		 * command delay
-		*/
-		if (!this->dev_ready) {
-			udelay (this->chip_delay);
-			return;
-		}	
+		chip->IO_ADDR_W = info->regs + S3C2440_NFDATA;
+		break;
 	}
-	
-	/* Apply this short delay always to ensure that we do wait tWB in
-	 * any case on any machine. */
-	ndelay (100);
-	/* wait until command is processed */
-	while (!this->dev_ready(mtd));
 }
 
-
 /* s3c2410_nand_devready()
  *
  * returns 0 if the nand is busy, 1 if it is ready
@@ -369,9 +322,12 @@ static int s3c2410_nand_devready(struct 
 {
 	struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd);
 	
+	if (info->is_s3c2440)
+		return readb(info->regs + S3C2440_NFSTAT) & S3C2440_NFSTAT_READY;
 	return readb(info->regs + S3C2410_NFSTAT) & S3C2410_NFSTAT_BUSY;
 }
 
+
 /* ECC handling functions */
 
 static int s3c2410_nand_correct_data(struct mtd_info *mtd, u_char *dat,
@@ -394,6 +350,12 @@ static int s3c2410_nand_correct_data(str
 	return -1;
 }
 
+/* ECC functions
+ *
+ * These allow the s3c2410 and s3c2440 to use the controller's ECC
+ * generator block to ECC the data as it passes through]
+*/
+
 static void s3c2410_nand_enable_hwecc(struct mtd_info *mtd, int mode)
 {
 	struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd);
@@ -404,6 +366,15 @@ static void s3c2410_nand_enable_hwecc(st
 	writel(ctrl, info->regs + S3C2410_NFCONF);
 }
 
+static void s3c2440_nand_enable_hwecc(struct mtd_info *mtd, int mode)
+{
+	struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd);
+	unsigned long ctrl;
+
+	ctrl = readl(info->regs + S3C2440_NFCONT);
+	writel(ctrl | S3C2440_NFCONT_INITECC, info->regs + S3C2440_NFCONT);
+}
+
 static int s3c2410_nand_calculate_ecc(struct mtd_info *mtd,
 				      const u_char *dat, u_char *ecc_code)
 {
@@ -420,7 +391,26 @@ static int s3c2410_nand_calculate_ecc(st
 }
 
 
-/* over-ride the standard functions for a little more speed? */
+static int s3c2440_nand_calculate_ecc(struct mtd_info *mtd,
+				      const u_char *dat, u_char *ecc_code)
+{
+	struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd);
+	unsigned long ecc = readl(info->regs + S3C2440_NFMECC0);
+
+	ecc_code[0] = ecc;
+	ecc_code[1] = ecc >> 8;
+	ecc_code[2] = ecc >> 16;
+
+	pr_debug("calculate_ecc: returning ecc %02x,%02x,%02x\n",
+		 ecc_code[0], ecc_code[1], ecc_code[2]);
+
+	return 0;
+}
+
+
+/* over-ride the standard functions for a little more speed. We can
+ * use read/write block to move the data buffers to/from the controller
+*/
 
 static void s3c2410_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
 {
@@ -523,11 +513,10 @@ static void s3c2410_nand_init_chip(struc
 {
 	struct nand_chip *chip = &nmtd->chip;
 
-	chip->IO_ADDR_R	   = (char *)info->regs + S3C2410_NFDATA;
-	chip->IO_ADDR_W    = (char *)info->regs + S3C2410_NFDATA;
+	chip->IO_ADDR_R	   = info->regs + S3C2410_NFDATA;
+	chip->IO_ADDR_W    = info->regs + S3C2410_NFDATA;
 	chip->hwcontrol    = s3c2410_nand_hwcontrol;
 	chip->dev_ready    = s3c2410_nand_devready;
-	chip->cmdfunc      = s3c2410_nand_command;
 	chip->write_buf    = s3c2410_nand_write_buf;
 	chip->read_buf     = s3c2410_nand_read_buf;
 	chip->select_chip  = s3c2410_nand_select_chip;
@@ -536,6 +525,12 @@ static void s3c2410_nand_init_chip(struc
 	chip->options	   = 0;
 	chip->controller   = &info->controller;
 
+	if (info->is_s3c2440) {
+		chip->IO_ADDR_R	 = info->regs + S3C2440_NFDATA;
+		chip->IO_ADDR_W  = info->regs + S3C2440_NFDATA;
+		chip->hwcontrol  = s3c2440_nand_hwcontrol;
+	}
+
 	nmtd->info	   = info;
 	nmtd->mtd.priv	   = chip;
 	nmtd->set	   = set;
@@ -546,6 +541,11 @@ static void s3c2410_nand_init_chip(struc
 		chip->calculate_ecc = s3c2410_nand_calculate_ecc;
 		chip->eccmode	    = NAND_ECC_HW3_512;
 		chip->autooob       = &nand_hw_eccoob;
+
+		if (info->is_s3c2440) {
+			chip->enable_hwecc  = s3c2440_nand_enable_hwecc;
+			chip->calculate_ecc = s3c2440_nand_calculate_ecc;
+		}
 	} else {
 		chip->eccmode	    = NAND_ECC_SOFT;
 	}
@@ -559,7 +559,7 @@ static void s3c2410_nand_init_chip(struc
  * nand layer to look for devices
 */
 
-static int s3c2410_nand_probe(struct device *dev)
+static int s3c24xx_nand_probe(struct device *dev, int is_s3c2440)
 {
 	struct platform_device *pdev = to_platform_device(dev);
 	struct s3c2410_platform_nand *plat = to_nand_plat(dev);
@@ -585,6 +585,7 @@ static int s3c2410_nand_probe(struct dev
 	dev_set_drvdata(dev, info);
 
 	spin_lock_init(&info->controller.lock);
+	init_waitqueue_head(&info->controller.wq);
 
 	/* get the clock source and enable it */
 
@@ -600,7 +601,8 @@ static int s3c2410_nand_probe(struct dev
 
 	/* allocate and map the resource */
 
-	res = pdev->resource;  /* assume that the flash has one resource */
+	/* currently we assume we have the one resource */
+	res  = pdev->resource;
 	size = res->end - res->start + 1;
 
 	info->area = request_mem_region(res->start, size, pdev->name);
@@ -611,9 +613,10 @@ static int s3c2410_nand_probe(struct dev
 		goto exit_error;
 	}
 
-	info->device = dev;
-	info->platform = plat;
-	info->regs = ioremap(res->start, size);
+	info->device     = dev;
+	info->platform   = plat;
+	info->regs       = ioremap(res->start, size);
+	info->is_s3c2440 = is_s3c2440;
 
 	if (info->regs == NULL) {
 		printk(KERN_ERR PFX "cannot reserve register region\n");
@@ -678,6 +681,18 @@ static int s3c2410_nand_probe(struct dev
 	return err;
 }
 
+/* driver device registration */
+
+static int s3c2410_nand_probe(struct device *dev)
+{
+	return s3c24xx_nand_probe(dev, 0);
+}
+
+static int s3c2440_nand_probe(struct device *dev)
+{
+	return s3c24xx_nand_probe(dev, 1);
+}
+
 static struct device_driver s3c2410_nand_driver = {
 	.name		= "s3c2410-nand",
 	.bus		= &platform_bus_type,
@@ -685,14 +700,24 @@ static struct device_driver s3c2410_nand
 	.remove		= s3c2410_nand_remove,
 };
 
+static struct device_driver s3c2440_nand_driver = {
+	.name		= "s3c2440-nand",
+	.bus		= &platform_bus_type,
+	.probe		= s3c2440_nand_probe,
+	.remove		= s3c2410_nand_remove,
+};
+
 static int __init s3c2410_nand_init(void)
 {
-	printk("S3C2410 NAND Driver, (c) 2004 Simtec Electronics\n");
+	printk("S3C24XX NAND Driver, (c) 2004 Simtec Electronics\n");
+
+	driver_register(&s3c2440_nand_driver);
 	return driver_register(&s3c2410_nand_driver);
 }
 
 static void __exit s3c2410_nand_exit(void)
 {
+	driver_unregister(&s3c2440_nand_driver);
 	driver_unregister(&s3c2410_nand_driver);
 }
 
@@ -701,4 +726,4 @@ module_exit(s3c2410_nand_exit);
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
-MODULE_DESCRIPTION("S3C2410 MTD NAND driver");
+MODULE_DESCRIPTION("S3C24XX MTD NAND driver");
diff --git a/drivers/mtd/nand/sharpsl.c b/drivers/mtd/nand/sharpsl.c
old mode 100755
new mode 100644
--- a/drivers/mtd/nand/sharpsl.c
+++ b/drivers/mtd/nand/sharpsl.c
@@ -3,7 +3,7 @@
  *
  *  Copyright (C) 2004 Richard Purdie
  *
- *  $Id: sharpsl.c,v 1.3 2005/01/03 14:53:50 rpurdie Exp $
+ *  $Id: sharpsl.c,v 1.4 2005/01/23 11:09:19 rpurdie Exp $
  *
  *  Based on Sharp's NAND driver sharp_sl.c
  *
@@ -216,7 +216,7 @@ sharpsl_nand_init(void)
 		nr_partitions = DEFAULT_NUM_PARTITIONS;
 		sharpsl_partition_info = sharpsl_nand_default_partition_info;
 		if (machine_is_poodle()) {
-			sharpsl_partition_info[1].size=22 * 1024 * 1024;
+			sharpsl_partition_info[1].size=30 * 1024 * 1024;
 		} else if (machine_is_corgi() || machine_is_shepherd()) {
 			sharpsl_partition_info[1].size=25 * 1024 * 1024;
 		} else if (machine_is_husky()) {
diff --git a/drivers/mtd/nand/tx4925ndfmc.c b/drivers/mtd/nand/tx4925ndfmc.c
deleted file mode 100644
--- a/drivers/mtd/nand/tx4925ndfmc.c
+++ /dev/null
@@ -1,416 +0,0 @@
-/*
- *  drivers/mtd/tx4925ndfmc.c
- *
- *  Overview:
- *   This is a device driver for the NAND flash device found on the
- *   Toshiba RBTX4925 reference board, which is a SmartMediaCard. It supports 
- *   16MiB, 32MiB and 64MiB cards.
- *
- * Author: MontaVista Software, Inc.  source@mvista.com
- *
- * Derived from drivers/mtd/autcpu12.c
- *       Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de)
- *
- * $Id: tx4925ndfmc.c,v 1.5 2004/10/05 13:50:20 gleixner Exp $
- *
- * Copyright (C) 2001 Toshiba Corporation 
- * 
- * 2003 (c) MontaVista Software, Inc. This file is licensed under
- * the terms of the GNU General Public License version 2. This program
- * is licensed "as is" without any warranty of any kind, whether express
- * or implied.
- *
- */
-
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/nand.h>
-#include <linux/mtd/partitions.h>
-#include <linux/delay.h>
-#include <asm/io.h>
-#include <asm/tx4925/tx4925_nand.h>
-
-extern struct nand_oobinfo jffs2_oobinfo;
-
-/*
- * MTD structure for RBTX4925 board
- */
-static struct mtd_info *tx4925ndfmc_mtd = NULL;
-
-/*
- * Define partitions for flash devices
- */
-
-static struct mtd_partition partition_info16k[] = {
-	{ .name = "RBTX4925 flash partition 1",
-	  .offset =  0,
-	  .size =    8 * 0x00100000 },
-	{ .name = "RBTX4925 flash partition 2",
-	  .offset =  8 * 0x00100000,
-	  .size =    8 * 0x00100000 },
-};
-
-static struct mtd_partition partition_info32k[] = {
-	{ .name = "RBTX4925 flash partition 1",
-	  .offset =  0,
-	  .size =    8 * 0x00100000 },
-	{ .name = "RBTX4925 flash partition 2",
-	  .offset = 8 * 0x00100000,
-	  .size =  24 * 0x00100000 },
-};
-
-static struct mtd_partition partition_info64k[] = {
-	{ .name = "User FS",
-	  .offset =  0,
-	  .size =   16 * 0x00100000 },
-	{ .name = "RBTX4925 flash partition 2",
-	  .offset = 16 * 0x00100000,
-	  .size =   48 * 0x00100000},
-};
-
-static struct mtd_partition partition_info128k[] = {
-	{ .name = "Skip bad section",
-	  .offset =  0,
-	  .size =   16 * 0x00100000 },
-	{ .name = "User FS",
-	  .offset = 16 * 0x00100000,
-	  .size =   112 * 0x00100000 },
-};
-#define NUM_PARTITIONS16K  2
-#define NUM_PARTITIONS32K  2
-#define NUM_PARTITIONS64K  2
-#define NUM_PARTITIONS128K 2
-
-/* 
- *	hardware specific access to control-lines
-*/
-static void tx4925ndfmc_hwcontrol(struct mtd_info *mtd, int cmd)
-{
-
-	switch(cmd){
-
-		case NAND_CTL_SETCLE: 
-			tx4925_ndfmcptr->mcr |= TX4925_NDFMCR_CLE;
-			break;
-		case NAND_CTL_CLRCLE:
-			tx4925_ndfmcptr->mcr &= ~TX4925_NDFMCR_CLE;
-			break;
-		case NAND_CTL_SETALE:
-			tx4925_ndfmcptr->mcr |= TX4925_NDFMCR_ALE;
-			break;
-		case NAND_CTL_CLRALE: 
-			tx4925_ndfmcptr->mcr &= ~TX4925_NDFMCR_ALE;
-			break;
-		case NAND_CTL_SETNCE:
-			tx4925_ndfmcptr->mcr |= TX4925_NDFMCR_CE;
-			break;
-		case NAND_CTL_CLRNCE:
-			tx4925_ndfmcptr->mcr &= ~TX4925_NDFMCR_CE;
-			break;
-		case NAND_CTL_SETWP:
-			tx4925_ndfmcptr->mcr |= TX4925_NDFMCR_WE;
-			break;
-		case NAND_CTL_CLRWP:
-			tx4925_ndfmcptr->mcr &= ~TX4925_NDFMCR_WE;
-			break;
-	}
-}
-
-/*
-*	read device ready pin
-*/
-static int tx4925ndfmc_device_ready(struct mtd_info *mtd)
-{
-	int ready;
-	ready = (tx4925_ndfmcptr->sr & TX4925_NDSFR_BUSY) ? 0 : 1;
-	return ready;
-}
-void tx4925ndfmc_enable_hwecc(struct mtd_info *mtd, int mode)
-{
-	/* reset first */
-	tx4925_ndfmcptr->mcr |= TX4925_NDFMCR_ECC_CNTL_MASK;
-	tx4925_ndfmcptr->mcr &= ~TX4925_NDFMCR_ECC_CNTL_MASK;
-	tx4925_ndfmcptr->mcr |= TX4925_NDFMCR_ECC_CNTL_ENAB;
-}
-static void tx4925ndfmc_disable_ecc(void)
-{
-	tx4925_ndfmcptr->mcr &= ~TX4925_NDFMCR_ECC_CNTL_MASK;
-}
-static void tx4925ndfmc_enable_read_ecc(void)
-{
-	tx4925_ndfmcptr->mcr &= ~TX4925_NDFMCR_ECC_CNTL_MASK;
-	tx4925_ndfmcptr->mcr |= TX4925_NDFMCR_ECC_CNTL_READ;
-}
-void tx4925ndfmc_readecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code){
-	int i;
-	u_char *ecc = ecc_code;
-        tx4925ndfmc_enable_read_ecc();
-	for (i = 0;i < 6;i++,ecc++)
-		*ecc = tx4925_read_nfmc(&(tx4925_ndfmcptr->dtr));
-        tx4925ndfmc_disable_ecc();
-}
-void tx4925ndfmc_device_setup(void)
-{
-
-	*(unsigned char *)0xbb005000 &= ~0x08;
-
-        /* reset NDFMC */
-        tx4925_ndfmcptr->rstr |= TX4925_NDFRSTR_RST;
-	while (tx4925_ndfmcptr->rstr & TX4925_NDFRSTR_RST);       
-
-	/* setup BusSeparete, Hold Time, Strobe Pulse Width */
-	tx4925_ndfmcptr->mcr = TX4925_BSPRT ? TX4925_NDFMCR_BSPRT : 0;
-	tx4925_ndfmcptr->spr = TX4925_HOLD << 4 | TX4925_SPW;             
-}
-static u_char tx4925ndfmc_nand_read_byte(struct mtd_info *mtd)
-{
-        struct nand_chip *this = mtd->priv;
-        return tx4925_read_nfmc(this->IO_ADDR_R);
-}
-
-static void tx4925ndfmc_nand_write_byte(struct mtd_info *mtd, u_char byte)
-{
-        struct nand_chip *this = mtd->priv;
-        tx4925_write_nfmc(byte, this->IO_ADDR_W);
-}
-
-static void tx4925ndfmc_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
-{
-	int i;
-	struct nand_chip *this = mtd->priv;
-
-	for (i=0; i<len; i++)
-		tx4925_write_nfmc(buf[i], this->IO_ADDR_W);
-}
-
-static void tx4925ndfmc_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
-{
-	int i;
-	struct nand_chip *this = mtd->priv;
-
-	for (i=0; i<len; i++)
-		buf[i] = tx4925_read_nfmc(this->IO_ADDR_R);
-}
-
-static int tx4925ndfmc_nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
-{
-	int i;
-	struct nand_chip *this = mtd->priv;
-
-	for (i=0; i<len; i++)
-		if (buf[i] != tx4925_read_nfmc(this->IO_ADDR_R))
-			return -EFAULT;
-
-	return 0;
-}
-
-/*
- * Send command to NAND device
- */
-static void tx4925ndfmc_nand_command (struct mtd_info *mtd, unsigned command, int column, int page_addr)
-{
-	register struct nand_chip *this = mtd->priv;
-
-	/* Begin command latch cycle */
-	this->hwcontrol(mtd, NAND_CTL_SETCLE);
-	/*
-	 * Write out the command to the device.
-	 */
-	if (command == NAND_CMD_SEQIN) {
-		int readcmd;
-
-		if (column >= mtd->oobblock) {
-			/* OOB area */
-			column -= mtd->oobblock;
-			readcmd = NAND_CMD_READOOB;
-		} else if (column < 256) {
-			/* First 256 bytes --> READ0 */
-			readcmd = NAND_CMD_READ0;
-		} else {
-			column -= 256;
-			readcmd = NAND_CMD_READ1;
-		}
-		this->write_byte(mtd, readcmd);
-	}
-	this->write_byte(mtd, command);
-
-	/* Set ALE and clear CLE to start address cycle */
-	this->hwcontrol(mtd, NAND_CTL_CLRCLE);
-
-	if (column != -1 || page_addr != -1) {
-		this->hwcontrol(mtd, NAND_CTL_SETALE);
-
-		/* Serially input address */
-		if (column != -1)
-			this->write_byte(mtd, column);
-		if (page_addr != -1) {
-			this->write_byte(mtd, (unsigned char) (page_addr & 0xff));
-			this->write_byte(mtd, (unsigned char) ((page_addr >> 8) & 0xff));
-			/* One more address cycle for higher density devices */
-			if (mtd->size & 0x0c000000) 
-				this->write_byte(mtd, (unsigned char) ((page_addr >> 16) & 0x0f));
-		}
-		/* Latch in address */
-		this->hwcontrol(mtd, NAND_CTL_CLRALE);
-	}
-	
-	/* 
-	 * program and erase have their own busy handlers 
-	 * status and sequential in needs no delay
-	*/
-	switch (command) {
-			
-	case NAND_CMD_PAGEPROG:
-		/* Turn off WE */
-		this->hwcontrol (mtd, NAND_CTL_CLRWP);
-                return;
-
-	case NAND_CMD_SEQIN:
-		/* Turn on WE */
-		this->hwcontrol (mtd, NAND_CTL_SETWP);
-                return;
-
-	case NAND_CMD_ERASE1:
-	case NAND_CMD_ERASE2:
-	case NAND_CMD_STATUS:
-		return;
-
-	case NAND_CMD_RESET:
-		if (this->dev_ready)	
-			break;
-		this->hwcontrol(mtd, NAND_CTL_SETCLE);
-		this->write_byte(mtd, NAND_CMD_STATUS);
-		this->hwcontrol(mtd, NAND_CTL_CLRCLE);
-		while ( !(this->read_byte(mtd) & 0x40));
-		return;
-
-	/* This applies to read commands */	
-	default:
-		/* 
-		 * If we don't have access to the busy pin, we apply the given
-		 * command delay
-		*/
-		if (!this->dev_ready) {
-			udelay (this->chip_delay);
-			return;
-		}	
-	}
-	
-	/* wait until command is processed */
-	while (!this->dev_ready(mtd));
-}
-
-#ifdef CONFIG_MTD_CMDLINE_PARTS
-extern int parse_cmdline_partitions(struct mtd_info *master, struct mtd_partitio
-n **pparts, char *);
-#endif
-
-/*
- * Main initialization routine
- */
-extern int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc);
-int __init tx4925ndfmc_init (void)
-{
-	struct nand_chip *this;
-	int err = 0;
-
-	/* Allocate memory for MTD device structure and private data */
-	tx4925ndfmc_mtd = kmalloc (sizeof(struct mtd_info) + sizeof (struct nand_chip),
-				GFP_KERNEL);
-	if (!tx4925ndfmc_mtd) {
-		printk ("Unable to allocate RBTX4925 NAND MTD device structure.\n");
-		err = -ENOMEM;
-		goto out;
-	}
-
-        tx4925ndfmc_device_setup();
-
-	/* io is indirect via a register so don't need to ioremap address */
-
-	/* Get pointer to private data */
-	this = (struct nand_chip *) (&tx4925ndfmc_mtd[1]);
-
-	/* Initialize structures */
-	memset((char *) tx4925ndfmc_mtd, 0, sizeof(struct mtd_info));
-	memset((char *) this, 0, sizeof(struct nand_chip));
-
-	/* Link the private data with the MTD structure */
-	tx4925ndfmc_mtd->priv = this;
-
-	/* Set address of NAND IO lines */
-	this->IO_ADDR_R = (void __iomem *)&(tx4925_ndfmcptr->dtr);
-	this->IO_ADDR_W = (void __iomem *)&(tx4925_ndfmcptr->dtr);
-	this->hwcontrol = tx4925ndfmc_hwcontrol;
-	this->enable_hwecc = tx4925ndfmc_enable_hwecc;
-	this->calculate_ecc = tx4925ndfmc_readecc;
-	this->correct_data = nand_correct_data;
-	this->eccmode = NAND_ECC_HW6_512;	
-	this->dev_ready = tx4925ndfmc_device_ready;
-	/* 20 us command delay time */
-	this->chip_delay = 20;		
-        this->read_byte = tx4925ndfmc_nand_read_byte;
-        this->write_byte = tx4925ndfmc_nand_write_byte;
-	this->cmdfunc = tx4925ndfmc_nand_command;
-	this->write_buf = tx4925ndfmc_nand_write_buf;
-	this->read_buf = tx4925ndfmc_nand_read_buf;
-	this->verify_buf = tx4925ndfmc_nand_verify_buf;
-
-	/* Scan to find existance of the device */
-	if (nand_scan (tx4925ndfmc_mtd, 1)) {
-		err = -ENXIO;
-		goto out_ior;
-	}
-
-	/* Register the partitions */
-#ifdef CONFIG_MTD_CMDLINE_PARTS
-        {
-                int mtd_parts_nb = 0;
-                struct mtd_partition *mtd_parts = 0;
-                mtd_parts_nb = parse_cmdline_partitions(tx4925ndfmc_mtd, &mtd_parts, "tx4925ndfmc");
-                if (mtd_parts_nb > 0)
-                        add_mtd_partitions(tx4925ndfmc_mtd, mtd_parts, mtd_parts_nb);
-                else
-                        add_mtd_device(tx4925ndfmc_mtd);
-        }
-#else /* ifdef CONFIG_MTD_CMDLINE_PARTS */
-	switch(tx4925ndfmc_mtd->size){
-		case 0x01000000: add_mtd_partitions(tx4925ndfmc_mtd, partition_info16k, NUM_PARTITIONS16K); break;
-		case 0x02000000: add_mtd_partitions(tx4925ndfmc_mtd, partition_info32k, NUM_PARTITIONS32K); break;
-		case 0x04000000: add_mtd_partitions(tx4925ndfmc_mtd, partition_info64k, NUM_PARTITIONS64K); break; 
-		case 0x08000000: add_mtd_partitions(tx4925ndfmc_mtd, partition_info128k, NUM_PARTITIONS128K); break; 
-		default: {
-			printk ("Unsupported SmartMedia device\n"); 
-			err = -ENXIO;
-			goto out_ior;
-		}
-	}
-#endif /* ifdef CONFIG_MTD_CMDLINE_PARTS */
-	goto out;
-
-out_ior:
-out:
-	return err;
-}
-
-module_init(tx4925ndfmc_init);
-
-/*
- * Clean up routine
- */
-#ifdef MODULE
-static void __exit tx4925ndfmc_cleanup (void)
-{
-	/* Release resources, unregister device */
-	nand_release (tx4925ndfmc_mtd);
-
-	/* Free the MTD device structure */
-	kfree (tx4925ndfmc_mtd);
-}
-module_exit(tx4925ndfmc_cleanup);
-#endif
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Alice Hennessy <ahennessy@mvista.com>");
-MODULE_DESCRIPTION("Glue layer for SmartMediaCard on Toshiba RBTX4925");
diff --git a/drivers/mtd/nand/tx4938ndfmc.c b/drivers/mtd/nand/tx4938ndfmc.c
deleted file mode 100644
--- a/drivers/mtd/nand/tx4938ndfmc.c
+++ /dev/null
@@ -1,406 +0,0 @@
-/*
- * drivers/mtd/nand/tx4938ndfmc.c
- *
- *  Overview:
- *   This is a device driver for the NAND flash device connected to
- *   TX4938 internal NAND Memory Controller.
- *   TX4938 NDFMC is almost same as TX4925 NDFMC, but register size are 64 bit.
- *
- * Author: source@mvista.com
- *
- * Based on spia.c by Steven J. Hill
- *
- * $Id: tx4938ndfmc.c,v 1.4 2004/10/05 13:50:20 gleixner Exp $
- *
- * Copyright (C) 2000-2001 Toshiba Corporation 
- *
- * 2003 (c) MontaVista Software, Inc. This file is licensed under the
- * terms of the GNU General Public License version 2. This program is
- * licensed "as is" without any warranty of any kind, whether express
- * or implied.
- */
-#include <linux/config.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/nand.h>
-#include <linux/mtd/nand_ecc.h>
-#include <linux/mtd/partitions.h>
-#include <asm/io.h>
-#include <asm/bootinfo.h>
-#include <linux/delay.h>
-#include <asm/tx4938/rbtx4938.h>
-
-extern struct nand_oobinfo jffs2_oobinfo;
-
-/*
- * MTD structure for TX4938 NDFMC
- */
-static struct mtd_info *tx4938ndfmc_mtd;
-
-/*
- * Define partitions for flash device
- */
-#define flush_wb()	(void)tx4938_ndfmcptr->mcr;
-
-#define NUM_PARTITIONS  	3
-#define NUMBER_OF_CIS_BLOCKS	24
-#define SIZE_OF_BLOCK		0x00004000
-#define NUMBER_OF_BLOCK_PER_ZONE 1024
-#define SIZE_OF_ZONE		(NUMBER_OF_BLOCK_PER_ZONE * SIZE_OF_BLOCK)
-#ifndef CONFIG_MTD_CMDLINE_PARTS
-/*
- * You can use the following sample of MTD partitions 
- * on the NAND Flash Memory 32MB or more.
- *
- * The following figure shows the image of the sample partition on
- * the 32MB NAND Flash Memory. 
- *
- *   Block No.
- *    0 +-----------------------------+ ------
- *      |             CIS             |   ^
- *   24 +-----------------------------+   |
- *      |         kernel image        |   | Zone 0
- *      |                             |   |
- *      +-----------------------------+   |
- * 1023 |         unused area         |   v
- *      +-----------------------------+ ------
- * 1024 |            JFFS2            |   ^
- *      |                             |   |
- *      |                             |   | Zone 1
- *      |                             |   |
- *      |                             |   |
- *      |                             |   v
- * 2047 +-----------------------------+ ------
- *
- */
-static struct mtd_partition partition_info[NUM_PARTITIONS] = {
-	{
-		.name = "RBTX4938 CIS Area",
- 		.offset =  0,
- 		.size =    (NUMBER_OF_CIS_BLOCKS * SIZE_OF_BLOCK),
- 		.mask_flags  = MTD_WRITEABLE	/* This partition is NOT writable */
- 	},
- 	{
- 		.name = "RBTX4938 kernel image",
- 		.offset =  MTDPART_OFS_APPEND,
- 		.size =    8 * 0x00100000,	/* 8MB (Depends on size of kernel image) */
- 		.mask_flags  = MTD_WRITEABLE	/* This partition is NOT writable */
- 	},
- 	{
- 		.name = "Root FS (JFFS2)",
- 		.offset =  (0 + SIZE_OF_ZONE),    /* start address of next zone */
- 		.size =    MTDPART_SIZ_FULL
- 	},
-};
-#endif
-
-static void tx4938ndfmc_hwcontrol(struct mtd_info *mtd, int cmd)
-{
-	switch (cmd) {
-		case NAND_CTL_SETCLE:
-			tx4938_ndfmcptr->mcr |= TX4938_NDFMCR_CLE;
-			break;
-		case NAND_CTL_CLRCLE:
-			tx4938_ndfmcptr->mcr &= ~TX4938_NDFMCR_CLE;
-			break;
-		case NAND_CTL_SETALE:
-			tx4938_ndfmcptr->mcr |= TX4938_NDFMCR_ALE;
-			break;
-		case NAND_CTL_CLRALE:
-			tx4938_ndfmcptr->mcr &= ~TX4938_NDFMCR_ALE;
-			break;
-		/* TX4938_NDFMCR_CE bit is 0:high 1:low */
-		case NAND_CTL_SETNCE:
-			tx4938_ndfmcptr->mcr |= TX4938_NDFMCR_CE;
-			break;
-		case NAND_CTL_CLRNCE:
-			tx4938_ndfmcptr->mcr &= ~TX4938_NDFMCR_CE;
-			break;
-		case NAND_CTL_SETWP:
-			tx4938_ndfmcptr->mcr |= TX4938_NDFMCR_WE;
-			break;
-		case NAND_CTL_CLRWP:
-			tx4938_ndfmcptr->mcr &= ~TX4938_NDFMCR_WE;
-			break;
-	}
-}
-static int tx4938ndfmc_dev_ready(struct mtd_info *mtd)
-{
-	flush_wb();
-	return !(tx4938_ndfmcptr->sr & TX4938_NDFSR_BUSY);
-}
-static void tx4938ndfmc_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code)
-{
-	u32 mcr = tx4938_ndfmcptr->mcr;
-	mcr &= ~TX4938_NDFMCR_ECC_ALL;
-	tx4938_ndfmcptr->mcr = mcr | TX4938_NDFMCR_ECC_OFF;
-	tx4938_ndfmcptr->mcr = mcr | TX4938_NDFMCR_ECC_READ;
-	ecc_code[1] = tx4938_ndfmcptr->dtr;
-	ecc_code[0] = tx4938_ndfmcptr->dtr;
-	ecc_code[2] = tx4938_ndfmcptr->dtr;
-	tx4938_ndfmcptr->mcr = mcr | TX4938_NDFMCR_ECC_OFF;
-}
-static void tx4938ndfmc_enable_hwecc(struct mtd_info *mtd, int mode)
-{
-	u32 mcr = tx4938_ndfmcptr->mcr;
-	mcr &= ~TX4938_NDFMCR_ECC_ALL;
-	tx4938_ndfmcptr->mcr = mcr | TX4938_NDFMCR_ECC_RESET;
-	tx4938_ndfmcptr->mcr = mcr | TX4938_NDFMCR_ECC_OFF;
-	tx4938_ndfmcptr->mcr = mcr | TX4938_NDFMCR_ECC_ON;
-}
-
-static u_char tx4938ndfmc_nand_read_byte(struct mtd_info *mtd)
-{
-	struct nand_chip *this = mtd->priv;
-	return tx4938_read_nfmc(this->IO_ADDR_R);
-}
-
-static void tx4938ndfmc_nand_write_byte(struct mtd_info *mtd, u_char byte)
-{
-	struct nand_chip *this = mtd->priv;
-	tx4938_write_nfmc(byte, this->IO_ADDR_W);
-}
-
-static void tx4938ndfmc_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
-{
-	int i;
-	struct nand_chip *this = mtd->priv;
-
-	for (i=0; i<len; i++)
-		tx4938_write_nfmc(buf[i], this->IO_ADDR_W);
-}
-
-static void tx4938ndfmc_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
-{
-	int i;
-	struct nand_chip *this = mtd->priv;
-
-	for (i=0; i<len; i++)
-		buf[i] = tx4938_read_nfmc(this->IO_ADDR_R);
-}
-
-static int tx4938ndfmc_nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
-{
-	int i;
-	struct nand_chip *this = mtd->priv;
-
-	for (i=0; i<len; i++)
-		if (buf[i] != tx4938_read_nfmc(this->IO_ADDR_R))
-			return -EFAULT;
-
-	return 0;
-}
-
-/*
- * Send command to NAND device
- */
-static void tx4938ndfmc_nand_command (struct mtd_info *mtd, unsigned command, int column, int page_addr)
-{
-	register struct nand_chip *this = mtd->priv;
-
-	/* Begin command latch cycle */
-	this->hwcontrol(mtd, NAND_CTL_SETCLE);
-	/*
-	 * Write out the command to the device.
-	 */
-	if (command == NAND_CMD_SEQIN) {
-		int readcmd;
-
-		if (column >= mtd->oobblock) {
-			/* OOB area */
-			column -= mtd->oobblock;
-			readcmd = NAND_CMD_READOOB;
-		} else if (column < 256) {
-			/* First 256 bytes --> READ0 */
-			readcmd = NAND_CMD_READ0;
-		} else {
-			column -= 256;
-			readcmd = NAND_CMD_READ1;
-		}
-		this->write_byte(mtd, readcmd);
-	}
-	this->write_byte(mtd, command);
-
-	/* Set ALE and clear CLE to start address cycle */
-	this->hwcontrol(mtd, NAND_CTL_CLRCLE);
-
-	if (column != -1 || page_addr != -1) {
-		this->hwcontrol(mtd, NAND_CTL_SETALE);
-
-		/* Serially input address */
-		if (column != -1)
-			this->write_byte(mtd, column);
-		if (page_addr != -1) {
-			this->write_byte(mtd, (unsigned char) (page_addr & 0xff));
-			this->write_byte(mtd, (unsigned char) ((page_addr >> 8) & 0xff));
-			/* One more address cycle for higher density devices */
-			if (mtd->size & 0x0c000000) 
-				this->write_byte(mtd, (unsigned char) ((page_addr >> 16) & 0x0f));
-		}
-		/* Latch in address */
-		this->hwcontrol(mtd, NAND_CTL_CLRALE);
-	}
-	
-	/* 
-	 * program and erase have their own busy handlers 
-	 * status and sequential in needs no delay
-	*/
-	switch (command) {
-			
-	case NAND_CMD_PAGEPROG:
-		/* Turn off WE */
-		this->hwcontrol (mtd, NAND_CTL_CLRWP);
-                return;
-
-	case NAND_CMD_SEQIN:
-		/* Turn on WE */
-		this->hwcontrol (mtd, NAND_CTL_SETWP);
-                return;
-
-	case NAND_CMD_ERASE1:
-	case NAND_CMD_ERASE2:
-	case NAND_CMD_STATUS:
-		return;
-
-	case NAND_CMD_RESET:
-		if (this->dev_ready)	
-			break;
-		this->hwcontrol(mtd, NAND_CTL_SETCLE);
-		this->write_byte(mtd, NAND_CMD_STATUS);
-		this->hwcontrol(mtd, NAND_CTL_CLRCLE);
-		while ( !(this->read_byte(mtd) & 0x40));
-		return;
-
-	/* This applies to read commands */	
-	default:
-		/* 
-		 * If we don't have access to the busy pin, we apply the given
-		 * command delay
-		*/
-		if (!this->dev_ready) {
-			udelay (this->chip_delay);
-			return;
-		}	
-	}
-	
-	/* wait until command is processed */
-	while (!this->dev_ready(mtd));
-}
-
-#ifdef CONFIG_MTD_CMDLINE_PARTS
-extern int parse_cmdline_partitions(struct mtd_info *master, struct mtd_partition **pparts, char *);
-#endif
-/*
- * Main initialization routine
- */
-int __init tx4938ndfmc_init (void)
-{
-	struct nand_chip *this;
-	int bsprt = 0, hold = 0xf, spw = 0xf;
-	int protected = 0;
-
-	if ((*rbtx4938_piosel_ptr & 0x0c) != 0x08) {
-		printk("TX4938 NDFMC: disabled by IOC PIOSEL\n");
-		return -ENODEV;
-	}
-	bsprt = 1;
-	hold = 2;
-	spw = 9 - 1;	/* 8 GBUSCLK = 80ns (@ GBUSCLK 100MHz) */
-
-	if ((tx4938_ccfgptr->pcfg &
-	     (TX4938_PCFG_ATA_SEL|TX4938_PCFG_ISA_SEL|TX4938_PCFG_NDF_SEL))
-	    != TX4938_PCFG_NDF_SEL) {
-		printk("TX4938 NDFMC: disabled by PCFG.\n");
-		return -ENODEV;
-	}
-
-	/* reset NDFMC */
-	tx4938_ndfmcptr->rstr |= TX4938_NDFRSTR_RST;
-	while (tx4938_ndfmcptr->rstr & TX4938_NDFRSTR_RST)
-		;
-	/* setup BusSeparete, Hold Time, Strobe Pulse Width */
-	tx4938_ndfmcptr->mcr = bsprt ? TX4938_NDFMCR_BSPRT : 0;
-	tx4938_ndfmcptr->spr = hold << 4 | spw;
-
-	/* Allocate memory for MTD device structure and private data */
-	tx4938ndfmc_mtd = kmalloc (sizeof(struct mtd_info) + sizeof (struct nand_chip),
-				      GFP_KERNEL);
-	if (!tx4938ndfmc_mtd) {
-		printk ("Unable to allocate TX4938 NDFMC MTD device structure.\n");
-		return -ENOMEM;
-	}
-
-	/* Get pointer to private data */
-	this = (struct nand_chip *) (&tx4938ndfmc_mtd[1]);
-
-	/* Initialize structures */
-	memset((char *) tx4938ndfmc_mtd, 0, sizeof(struct mtd_info));
-	memset((char *) this, 0, sizeof(struct nand_chip));
-
-	/* Link the private data with the MTD structure */
-	tx4938ndfmc_mtd->priv = this;
-
-	/* Set address of NAND IO lines */
-	this->IO_ADDR_R = (unsigned long)&tx4938_ndfmcptr->dtr;
-	this->IO_ADDR_W = (unsigned long)&tx4938_ndfmcptr->dtr;
-	this->hwcontrol = tx4938ndfmc_hwcontrol;
-	this->dev_ready = tx4938ndfmc_dev_ready;
-	this->calculate_ecc = tx4938ndfmc_calculate_ecc;
-	this->correct_data = nand_correct_data;
-	this->enable_hwecc = tx4938ndfmc_enable_hwecc;
-	this->eccmode = NAND_ECC_HW3_256;
-	this->chip_delay = 100;
-	this->read_byte = tx4938ndfmc_nand_read_byte;
-	this->write_byte = tx4938ndfmc_nand_write_byte;
-	this->cmdfunc = tx4938ndfmc_nand_command;
-	this->write_buf = tx4938ndfmc_nand_write_buf;
-	this->read_buf = tx4938ndfmc_nand_read_buf;
-	this->verify_buf = tx4938ndfmc_nand_verify_buf;
-
-	/* Scan to find existance of the device */
-	if (nand_scan (tx4938ndfmc_mtd, 1)) {
-		kfree (tx4938ndfmc_mtd);
-		return -ENXIO;
-	}
-
-	if (protected) {
-		printk(KERN_INFO "TX4938 NDFMC: write protected.\n");
-		tx4938ndfmc_mtd->flags &= ~(MTD_WRITEABLE | MTD_ERASEABLE);
-	}
-
-#ifdef CONFIG_MTD_CMDLINE_PARTS
-	{
-		int mtd_parts_nb = 0;
-		struct mtd_partition *mtd_parts = 0;
-		mtd_parts_nb = parse_cmdline_partitions(tx4938ndfmc_mtd, &mtd_parts, "tx4938ndfmc");
-		if (mtd_parts_nb > 0)
-			add_mtd_partitions(tx4938ndfmc_mtd, mtd_parts, mtd_parts_nb);
-		else
-			add_mtd_device(tx4938ndfmc_mtd);
-	}
-#else
-	add_mtd_partitions(tx4938ndfmc_mtd, partition_info, NUM_PARTITIONS );
-#endif
-
-	return 0;
-}
-module_init(tx4938ndfmc_init);
-
-/*
- * Clean up routine
- */
-static void __exit tx4938ndfmc_cleanup (void)
-{
-	/* Release resources, unregister device */
-	nand_release (tx4938ndfmc_mtd);
-
-	/* Free the MTD device structure */
-	kfree (tx4938ndfmc_mtd);
-}
-module_exit(tx4938ndfmc_cleanup);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Alice Hennessy <ahennessy@mvista.com>");
-MODULE_DESCRIPTION("Board-specific glue layer for NAND flash on TX4938 NDFMC");
diff --git a/drivers/net/3c503.c b/drivers/net/3c503.c
--- a/drivers/net/3c503.c
+++ b/drivers/net/3c503.c
@@ -171,12 +171,7 @@ struct net_device * __init el2_probe(int
 	err = do_el2_probe(dev);
 	if (err)
 		goto out;
-	err = register_netdev(dev);
-	if (err)
-		goto out1;
 	return dev;
-out1:
-	cleanup_card(dev);
 out:
 	free_netdev(dev);
 	return ERR_PTR(err);
@@ -356,6 +351,10 @@ el2_probe1(struct net_device *dev, int i
     dev->poll_controller = ei_poll;
 #endif
 
+    retval = register_netdev(dev);
+    if (retval)
+	goto out1;
+
     if (dev->mem_start)
 	printk("%s: %s - %dkB RAM, 8kB shared mem window at %#6lx-%#6lx.\n",
 		dev->name, ei_status.name, (wordlength+1)<<3,
@@ -715,11 +714,8 @@ init_module(void)
 		dev->base_addr = io[this_dev];
 		dev->mem_end = xcvr[this_dev];	/* low 4bits = xcvr sel. */
 		if (do_el2_probe(dev) == 0) {
-			if (register_netdev(dev) == 0) {
-				dev_el2[found++] = dev;
-				continue;
-			}
-			cleanup_card(dev);
+			dev_el2[found++] = dev;
+			continue;
 		}
 		free_netdev(dev);
 		printk(KERN_WARNING "3c503.c: No 3c503 card found (i/o = 0x%x).\n", io[this_dev]);
diff --git a/drivers/net/3c505.c b/drivers/net/3c505.c
--- a/drivers/net/3c505.c
+++ b/drivers/net/3c505.c
@@ -272,7 +272,7 @@ static inline void set_hsf(struct net_de
 
 static int start_receive(struct net_device *, pcb_struct *);
 
-inline static void adapter_reset(struct net_device *dev)
+static inline void adapter_reset(struct net_device *dev)
 {
 	unsigned long timeout;
 	elp_device *adapter = dev->priv;
@@ -1317,8 +1317,7 @@ static int __init elp_sense(struct net_d
 	if (orig_HSR & DIR) {
 		/* If HCR.DIR is up, we pull it down. HSR.DIR should follow. */
 		outb(0, dev->base_addr + PORT_CONTROL);
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(30*HZ/100);
+		msleep(300);
 		if (inb_status(addr) & DIR) {
 			if (elp_debug > 0)
 				printk(notfound_msg, 2);
@@ -1327,8 +1326,7 @@ static int __init elp_sense(struct net_d
 	} else {
 		/* If HCR.DIR is down, we pull it up. HSR.DIR should follow. */
 		outb(DIR, dev->base_addr + PORT_CONTROL);
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(30*HZ/100);
+		msleep(300);
 		if (!(inb_status(addr) & DIR)) {
 			if (elp_debug > 0)
 				printk(notfound_msg, 3);
diff --git a/drivers/net/3c509.c b/drivers/net/3c509.c
--- a/drivers/net/3c509.c
+++ b/drivers/net/3c509.c
@@ -217,6 +217,7 @@ static void el3_poll_controller(struct n
 static struct eisa_device_id el3_eisa_ids[] = {
 		{ "TCM5092" },
 		{ "TCM5093" },
+		{ "TCM5095" },
 		{ "" }
 };
 
diff --git a/drivers/net/3c515.c b/drivers/net/3c515.c
--- a/drivers/net/3c515.c
+++ b/drivers/net/3c515.c
@@ -365,7 +365,7 @@ static int nopnp;
 #endif /* __ISAPNP__ */
 
 static struct net_device *corkscrew_scan(int unit);
-static void corkscrew_setup(struct net_device *dev, int ioaddr,
+static int corkscrew_setup(struct net_device *dev, int ioaddr,
 			    struct pnp_dev *idev, int card_number);
 static int corkscrew_open(struct net_device *dev);
 static void corkscrew_timer(unsigned long arg);
@@ -539,10 +539,9 @@ static struct net_device *corkscrew_scan
 			printk(KERN_INFO "3c515 Resource configuration register %#4.4x, DCR %4.4x.\n",
 		     		inl(ioaddr + 0x2002), inw(ioaddr + 0x2000));
 			/* irq = inw(ioaddr + 0x2002) & 15; */ /* Use the irq from isapnp */
-			corkscrew_setup(dev, ioaddr, idev, cards_found++);
 			SET_NETDEV_DEV(dev, &idev->dev);
 			pnp_cards++;
-			err = register_netdev(dev);
+			err = corkscrew_setup(dev, ioaddr, idev, cards_found++);
 			if (!err)
 				return dev;
 			cleanup_card(dev);
@@ -558,8 +557,7 @@ no_pnp:
 
 		printk(KERN_INFO "3c515 Resource configuration register %#4.4x, DCR %4.4x.\n",
 		     inl(ioaddr + 0x2002), inw(ioaddr + 0x2000));
-		corkscrew_setup(dev, ioaddr, NULL, cards_found++);
-		err = register_netdev(dev);
+		err = corkscrew_setup(dev, ioaddr, NULL, cards_found++);
 		if (!err)
 			return dev;
 		cleanup_card(dev);
@@ -568,7 +566,7 @@ no_pnp:
 	return NULL;
 }
 
-static void corkscrew_setup(struct net_device *dev, int ioaddr,
+static int corkscrew_setup(struct net_device *dev, int ioaddr,
 			    struct pnp_dev *idev, int card_number)
 {
 	struct corkscrew_private *vp = netdev_priv(dev);
@@ -691,6 +689,8 @@ static void corkscrew_setup(struct net_d
 	dev->get_stats = &corkscrew_get_stats;
 	dev->set_multicast_list = &set_rx_mode;
 	dev->ethtool_ops = &netdev_ethtool_ops;
+
+	return register_netdev(dev);
 }
 
 
@@ -822,7 +822,7 @@ static int corkscrew_open(struct net_dev
 				break;	/* Bad news!  */
 			skb->dev = dev;	/* Mark as being used by this device. */
 			skb_reserve(skb, 2);	/* Align IP on 16 byte boundaries */
-			vp->rx_ring[i].addr = isa_virt_to_bus(skb->tail);
+			vp->rx_ring[i].addr = isa_virt_to_bus(skb->data);
 		}
 		vp->rx_ring[i - 1].next = isa_virt_to_bus(&vp->rx_ring[0]);	/* Wrap the ring. */
 		outl(isa_virt_to_bus(&vp->rx_ring[0]), ioaddr + UpListPtr);
@@ -1406,7 +1406,7 @@ static int boomerang_rx(struct net_devic
 				break;	/* Bad news!  */
 			skb->dev = dev;	/* Mark as being used by this device. */
 			skb_reserve(skb, 2);	/* Align IP on 16 byte boundaries */
-			vp->rx_ring[entry].addr = isa_virt_to_bus(skb->tail);
+			vp->rx_ring[entry].addr = isa_virt_to_bus(skb->data);
 			vp->rx_skbuff[entry] = skb;
 		}
 		vp->rx_ring[entry].status = 0;	/* Clear complete bit. */
diff --git a/drivers/net/3c523.c b/drivers/net/3c523.c
--- a/drivers/net/3c523.c
+++ b/drivers/net/3c523.c
@@ -572,6 +572,10 @@ static int __init do_elmc_probe(struct n
         dev->flags&=~IFF_MULTICAST;     /* Multicast doesn't work */
 #endif
 
+	retval = register_netdev(dev);
+	if (retval)
+		goto err_out;
+
 	return 0;
 err_out:
 	mca_set_adapter_procfn(slot, NULL, NULL);
@@ -600,12 +604,7 @@ struct net_device * __init elmc_probe(in
 	err = do_elmc_probe(dev);
 	if (err)
 		goto out;
-	err = register_netdev(dev);
-	if (err)
-		goto out1;
 	return dev;
-out1:
-	cleanup_card(dev);
 out:
 	free_netdev(dev);
 	return ERR_PTR(err);
@@ -1275,6 +1274,7 @@ module_param_array(irq, int, NULL, 0);
 module_param_array(io, int, NULL, 0);
 MODULE_PARM_DESC(io, "EtherLink/MC I/O base address(es)");
 MODULE_PARM_DESC(irq, "EtherLink/MC IRQ number(s)");
+MODULE_LICENSE("GPL");
 
 int init_module(void)
 {
@@ -1288,12 +1288,9 @@ int init_module(void)
 		dev->irq=irq[this_dev];
 		dev->base_addr=io[this_dev];
 		if (do_elmc_probe(dev) == 0) {
-			if (register_netdev(dev) == 0) {
-				dev_elmc[this_dev] = dev;
-				found++;
-				continue;
-			}
-			cleanup_card(dev);
+			dev_elmc[this_dev] = dev;
+			found++;
+			continue;
 		}
 		free_netdev(dev);
 		if (io[this_dev]==0)
diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c
--- a/drivers/net/3c59x.c
+++ b/drivers/net/3c59x.c
@@ -1802,7 +1802,7 @@ vortex_open(struct net_device *dev)
 				break;			/* Bad news!  */
 			skb->dev = dev;			/* Mark as being used by this device. */
 			skb_reserve(skb, 2);	/* Align IP on 16 byte boundaries */
-			vp->rx_ring[i].addr = cpu_to_le32(pci_map_single(VORTEX_PCI(vp), skb->tail, PKT_BUF_SZ, PCI_DMA_FROMDEVICE));
+			vp->rx_ring[i].addr = cpu_to_le32(pci_map_single(VORTEX_PCI(vp), skb->data, PKT_BUF_SZ, PCI_DMA_FROMDEVICE));
 		}
 		if (i != RX_RING_SIZE) {
 			int j;
@@ -2202,9 +2202,8 @@ boomerang_start_xmit(struct sk_buff *skb
 
 	if (vortex_debug > 6) {
 		printk(KERN_DEBUG "boomerang_start_xmit()\n");
-		if (vortex_debug > 3)
-			printk(KERN_DEBUG "%s: Trying to send a packet, Tx index %d.\n",
-				   dev->name, vp->cur_tx);
+		printk(KERN_DEBUG "%s: Trying to send a packet, Tx index %d.\n",
+			   dev->name, vp->cur_tx);
 	}
 
 	if (vp->cur_tx - vp->dirty_tx >= TX_RING_SIZE) {
@@ -2633,7 +2632,7 @@ boomerang_rx(struct net_device *dev)
 				pci_dma_sync_single_for_cpu(VORTEX_PCI(vp), dma, PKT_BUF_SZ, PCI_DMA_FROMDEVICE);
 				/* 'skb_put()' points to the start of sk_buff data area. */
 				memcpy(skb_put(skb, pkt_len),
-					   vp->rx_skbuff[entry]->tail,
+					   vp->rx_skbuff[entry]->data,
 					   pkt_len);
 				pci_dma_sync_single_for_device(VORTEX_PCI(vp), dma, PKT_BUF_SZ, PCI_DMA_FROMDEVICE);
 				vp->rx_copy++;
@@ -2679,7 +2678,7 @@ boomerang_rx(struct net_device *dev)
 			}
 			skb->dev = dev;			/* Mark as being used by this device. */
 			skb_reserve(skb, 2);	/* Align IP on 16 byte boundaries */
-			vp->rx_ring[entry].addr = cpu_to_le32(pci_map_single(VORTEX_PCI(vp), skb->tail, PKT_BUF_SZ, PCI_DMA_FROMDEVICE));
+			vp->rx_ring[entry].addr = cpu_to_le32(pci_map_single(VORTEX_PCI(vp), skb->data, PKT_BUF_SZ, PCI_DMA_FROMDEVICE));
 			vp->rx_skbuff[entry] = skb;
 		}
 		vp->rx_ring[entry].status = 0;	/* Clear complete bit. */
diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c
--- a/drivers/net/8139cp.c
+++ b/drivers/net/8139cp.c
@@ -54,12 +54,14 @@
 
 #include <linux/config.h>
 #include <linux/module.h>
+#include <linux/moduleparam.h>
 #include <linux/kernel.h>
 #include <linux/compiler.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/init.h>
 #include <linux/pci.h>
+#include <linux/dma-mapping.h>
 #include <linux/delay.h>
 #include <linux/ethtool.h>
 #include <linux/mii.h>
@@ -91,16 +93,17 @@ KERN_INFO DRV_NAME ": 10/100 PCI Etherne
 
 MODULE_AUTHOR("Jeff Garzik <jgarzik@pobox.com>");
 MODULE_DESCRIPTION("RealTek RTL-8139C+ series 10/100 PCI Ethernet driver");
+MODULE_VERSION(DRV_VERSION);
 MODULE_LICENSE("GPL");
 
 static int debug = -1;
-MODULE_PARM (debug, "i");
+module_param(debug, int, 0);
 MODULE_PARM_DESC (debug, "8139cp: bitmapped message enable number");
 
 /* Maximum number of multicast addresses to filter (vs. Rx-all-multicast).
    The RTL chips use a 64 element hash table based on the Ethernet CRC.  */
 static int multicast_filter_limit = 32;
-MODULE_PARM (multicast_filter_limit, "i");
+module_param(multicast_filter_limit, int, 0);
 MODULE_PARM_DESC (multicast_filter_limit, "8139cp: maximum number of filtered multicast addresses");
 
 #define PFX			DRV_NAME ": "
@@ -186,6 +189,9 @@ enum {
 	RingEnd		= (1 << 30), /* End of descriptor ring */
 	FirstFrag	= (1 << 29), /* First segment of a packet */
 	LastFrag	= (1 << 28), /* Final segment of a packet */
+	LargeSend	= (1 << 27), /* TCP Large Send Offload (TSO) */
+	MSSShift	= 16,	     /* MSS value position */
+	MSSMask		= 0xfff,     /* MSS value: 11 bits */
 	TxError		= (1 << 23), /* Tx error summary */
 	RxError		= (1 << 20), /* Rx error summary */
 	IPCS		= (1 << 18), /* Calculate IP checksum */
@@ -312,7 +318,7 @@ struct cp_desc {
 struct ring_info {
 	struct sk_buff		*skb;
 	dma_addr_t		mapping;
-	unsigned		frag;
+	u32			len;
 };
 
 struct cp_dma_stats {
@@ -394,6 +400,9 @@ struct cp_private {
 static void __cp_set_rx_mode (struct net_device *dev);
 static void cp_tx (struct cp_private *cp);
 static void cp_clean_rings (struct cp_private *cp);
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void cp_poll_controller(struct net_device *dev);
+#endif
 
 static struct pci_device_id cp_pci_tbl[] = {
 	{ PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_8139,
@@ -587,7 +596,7 @@ rx_status_loop:
 
 		mapping =
 		cp->rx_skb[rx_tail].mapping =
-			pci_map_single(cp->pdev, new_skb->tail,
+			pci_map_single(cp->pdev, new_skb->data,
 				       buflen, PCI_DMA_FROMDEVICE);
 		cp->rx_skb[rx_tail].skb = new_skb;
 
@@ -688,6 +697,19 @@ cp_interrupt (int irq, void *dev_instanc
 	return IRQ_HANDLED;
 }
 
+#ifdef CONFIG_NET_POLL_CONTROLLER
+/*
+ * Polling receive - used by netconsole and other diagnostic tools
+ * to allow network i/o with interrupts disabled.
+ */
+static void cp_poll_controller(struct net_device *dev)
+{
+	disable_irq(dev->irq);
+	cp_interrupt(dev->irq, dev, NULL);
+	enable_irq(dev->irq);
+}
+#endif
+
 static void cp_tx (struct cp_private *cp)
 {
 	unsigned tx_head = cp->tx_head;
@@ -707,7 +729,7 @@ static void cp_tx (struct cp_private *cp
 			BUG();
 
 		pci_unmap_single(cp->pdev, cp->tx_skb[tx_tail].mapping,
-					skb->len, PCI_DMA_TODEVICE);
+				 cp->tx_skb[tx_tail].len, PCI_DMA_TODEVICE);
 
 		if (status & LastFrag) {
 			if (status & (TxError | TxFIFOUnder)) {
@@ -749,10 +771,11 @@ static int cp_start_xmit (struct sk_buff
 {
 	struct cp_private *cp = netdev_priv(dev);
 	unsigned entry;
-	u32 eor;
+	u32 eor, flags;
 #if CP_VLAN_TAG_USED
 	u32 vlan_tag = 0;
 #endif
+	int mss = 0;
 
 	spin_lock_irq(&cp->lock);
 
@@ -772,6 +795,9 @@ static int cp_start_xmit (struct sk_buff
 
 	entry = cp->tx_head;
 	eor = (entry == (CP_TX_RING_SIZE - 1)) ? RingEnd : 0;
+	if (dev->features & NETIF_F_TSO)
+		mss = skb_shinfo(skb)->tso_size;
+
 	if (skb_shinfo(skb)->nr_frags == 0) {
 		struct cp_desc *txd = &cp->tx_ring[entry];
 		u32 len;
@@ -783,26 +809,26 @@ static int cp_start_xmit (struct sk_buff
 		txd->addr = cpu_to_le64(mapping);
 		wmb();
 
-		if (skb->ip_summed == CHECKSUM_HW) {
+		flags = eor | len | DescOwn | FirstFrag | LastFrag;
+
+		if (mss)
+			flags |= LargeSend | ((mss & MSSMask) << MSSShift);
+		else if (skb->ip_summed == CHECKSUM_HW) {
 			const struct iphdr *ip = skb->nh.iph;
 			if (ip->protocol == IPPROTO_TCP)
-				txd->opts1 = cpu_to_le32(eor | len | DescOwn |
-							 FirstFrag | LastFrag |
-							 IPCS | TCPCS);
+				flags |= IPCS | TCPCS;
 			else if (ip->protocol == IPPROTO_UDP)
-				txd->opts1 = cpu_to_le32(eor | len | DescOwn |
-							 FirstFrag | LastFrag |
-							 IPCS | UDPCS);
+				flags |= IPCS | UDPCS;
 			else
-				BUG();
-		} else
-			txd->opts1 = cpu_to_le32(eor | len | DescOwn |
-						 FirstFrag | LastFrag);
+				WARN_ON(1);	/* we need a WARN() */
+		}
+
+		txd->opts1 = cpu_to_le32(flags);
 		wmb();
 
 		cp->tx_skb[entry].skb = skb;
 		cp->tx_skb[entry].mapping = mapping;
-		cp->tx_skb[entry].frag = 0;
+		cp->tx_skb[entry].len = len;
 		entry = NEXT_TX(entry);
 	} else {
 		struct cp_desc *txd;
@@ -820,7 +846,7 @@ static int cp_start_xmit (struct sk_buff
 					       first_len, PCI_DMA_TODEVICE);
 		cp->tx_skb[entry].skb = skb;
 		cp->tx_skb[entry].mapping = first_mapping;
-		cp->tx_skb[entry].frag = 1;
+		cp->tx_skb[entry].len = first_len;
 		entry = NEXT_TX(entry);
 
 		for (frag = 0; frag < skb_shinfo(skb)->nr_frags; frag++) {
@@ -836,16 +862,19 @@ static int cp_start_xmit (struct sk_buff
 						 len, PCI_DMA_TODEVICE);
 			eor = (entry == (CP_TX_RING_SIZE - 1)) ? RingEnd : 0;
 
-			if (skb->ip_summed == CHECKSUM_HW) {
-				ctrl = eor | len | DescOwn | IPCS;
+			ctrl = eor | len | DescOwn;
+
+			if (mss)
+				ctrl |= LargeSend |
+					((mss & MSSMask) << MSSShift);
+			else if (skb->ip_summed == CHECKSUM_HW) {
 				if (ip->protocol == IPPROTO_TCP)
-					ctrl |= TCPCS;
+					ctrl |= IPCS | TCPCS;
 				else if (ip->protocol == IPPROTO_UDP)
-					ctrl |= UDPCS;
+					ctrl |= IPCS | UDPCS;
 				else
 					BUG();
-			} else
-				ctrl = eor | len | DescOwn;
+			}
 
 			if (frag == skb_shinfo(skb)->nr_frags - 1)
 				ctrl |= LastFrag;
@@ -860,7 +889,7 @@ static int cp_start_xmit (struct sk_buff
 
 			cp->tx_skb[entry].skb = skb;
 			cp->tx_skb[entry].mapping = mapping;
-			cp->tx_skb[entry].frag = frag + 2;
+			cp->tx_skb[entry].len = len;
 			entry = NEXT_TX(entry);
 		}
 
@@ -1072,9 +1101,8 @@ static int cp_refill_rx (struct cp_priva
 		skb_reserve(skb, RX_OFFSET);
 
 		cp->rx_skb[i].mapping = pci_map_single(cp->pdev,
-			skb->tail, cp->rx_buf_sz, PCI_DMA_FROMDEVICE);
+			skb->data, cp->rx_buf_sz, PCI_DMA_FROMDEVICE);
 		cp->rx_skb[i].skb = skb;
-		cp->rx_skb[i].frag = 0;
 
 		cp->rx_ring[i].opts2 = 0;
 		cp->rx_ring[i].addr = cpu_to_le64(cp->rx_skb[i].mapping);
@@ -1126,9 +1154,6 @@ static void cp_clean_rings (struct cp_pr
 {
 	unsigned i;
 
-	memset(cp->rx_ring, 0, sizeof(struct cp_desc) * CP_RX_RING_SIZE);
-	memset(cp->tx_ring, 0, sizeof(struct cp_desc) * CP_TX_RING_SIZE);
-
 	for (i = 0; i < CP_RX_RING_SIZE; i++) {
 		if (cp->rx_skb[i].skb) {
 			pci_unmap_single(cp->pdev, cp->rx_skb[i].mapping,
@@ -1140,13 +1165,18 @@ static void cp_clean_rings (struct cp_pr
 	for (i = 0; i < CP_TX_RING_SIZE; i++) {
 		if (cp->tx_skb[i].skb) {
 			struct sk_buff *skb = cp->tx_skb[i].skb;
+
 			pci_unmap_single(cp->pdev, cp->tx_skb[i].mapping,
-					 skb->len, PCI_DMA_TODEVICE);
-			dev_kfree_skb(skb);
+				 	 cp->tx_skb[i].len, PCI_DMA_TODEVICE);
+			if (le32_to_cpu(cp->tx_ring[i].opts1) & LastFrag)
+				dev_kfree_skb(skb);
 			cp->net_stats.tx_dropped++;
 		}
 	}
 
+	memset(cp->rx_ring, 0, sizeof(struct cp_desc) * CP_RX_RING_SIZE);
+	memset(cp->tx_ring, 0, sizeof(struct cp_desc) * CP_TX_RING_SIZE);
+
 	memset(&cp->rx_skb, 0, sizeof(struct ring_info) * CP_RX_RING_SIZE);
 	memset(&cp->tx_skb, 0, sizeof(struct ring_info) * CP_TX_RING_SIZE);
 }
@@ -1486,22 +1516,22 @@ static void cp_get_ethtool_stats (struct
 				  struct ethtool_stats *estats, u64 *tmp_stats)
 {
 	struct cp_private *cp = netdev_priv(dev);
-	unsigned int work = 100;
 	int i;
 
+	memset(cp->nic_stats, 0, sizeof(struct cp_dma_stats));
+
 	/* begin NIC statistics dump */
 	cpw32(StatsAddr + 4, (cp->nic_stats_dma >> 16) >> 16);
 	cpw32(StatsAddr, (cp->nic_stats_dma & 0xffffffff) | DumpStats);
 	cpr32(StatsAddr);
 
-	while (work-- > 0) {
+	for (i = 0; i < 1000; i++) {
 		if ((cpr32(StatsAddr) & DumpStats) == 0)
 			break;
-		cpu_relax();
+		udelay(10);
 	}
-
-	if (cpr32(StatsAddr) & DumpStats)
-		return /* -EIO */;
+	cpw32(StatsAddr, 0);
+	cpw32(StatsAddr + 4, 0);
 
 	i = 0;
 	tmp_stats[i++] = le64_to_cpu(cp->nic_stats->tx_ok);
@@ -1538,6 +1568,8 @@ static struct ethtool_ops cp_ethtool_ops
 	.set_tx_csum		= ethtool_op_set_tx_csum, /* local! */
 	.get_sg			= ethtool_op_get_sg,
 	.set_sg			= ethtool_op_set_sg,
+	.get_tso		= ethtool_op_get_tso,
+	.set_tso		= ethtool_op_set_tso,
 	.get_regs		= cp_get_regs,
 	.get_wol		= cp_get_wol,
 	.set_wol		= cp_set_wol,
@@ -1701,19 +1733,19 @@ static int cp_init_one (struct pci_dev *
 
 	/* Configure DMA attributes. */
 	if ((sizeof(dma_addr_t) > 4) &&
-	    !pci_set_consistent_dma_mask(pdev, 0xffffffffffffffffULL) &&
-	    !pci_set_dma_mask(pdev, 0xffffffffffffffffULL)) {
+	    !pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK) &&
+	    !pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
 		pci_using_dac = 1;
 	} else {
 		pci_using_dac = 0;
 
-		rc = pci_set_dma_mask(pdev, 0xffffffffULL);
+		rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
 		if (rc) {
 			printk(KERN_ERR PFX "No usable DMA configuration, "
 			       "aborting.\n");
 			goto err_out_res;
 		}
-		rc = pci_set_consistent_dma_mask(pdev, 0xffffffffULL);
+		rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
 		if (rc) {
 			printk(KERN_ERR PFX "No usable consistent DMA configuration, "
 			       "aborting.\n");
@@ -1749,6 +1781,9 @@ static int cp_init_one (struct pci_dev *
 	dev->get_stats = cp_get_stats;
 	dev->do_ioctl = cp_ioctl;
 	dev->poll = cp_rx_poll;
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	dev->poll_controller = cp_poll_controller;
+#endif
 	dev->weight = 16;	/* arbitrary? from NAPI_HOWTO.txt. */
 #ifdef BROKEN
 	dev->change_mtu = cp_change_mtu;
@@ -1768,6 +1803,10 @@ static int cp_init_one (struct pci_dev *
 	if (pci_using_dac)
 		dev->features |= NETIF_F_HIGHDMA;
 
+#if 0 /* disabled by default until verified */
+	dev->features |= NETIF_F_TSO;
+#endif
+
 	dev->irq = pdev->irq;
 
 	rc = register_netdev(dev);
@@ -1858,6 +1897,7 @@ static int cp_resume (struct pci_dev *pd
 {
 	struct net_device *dev;
 	struct cp_private *cp;
+	unsigned long flags;
 
 	dev = pci_get_drvdata (pdev);
 	cp  = netdev_priv(dev);
@@ -1871,6 +1911,12 @@ static int cp_resume (struct pci_dev *pd
 	
 	cp_init_hw (cp);
 	netif_start_queue (dev);
+
+	spin_lock_irqsave (&cp->lock, flags);
+
+	mii_check_media(&cp->mii_if, netif_msg_link(cp), FALSE);
+
+	spin_unlock_irqrestore (&cp->lock, flags);
 	
 	return 0;
 }
diff --git a/drivers/net/8139too.c b/drivers/net/8139too.c
--- a/drivers/net/8139too.c
+++ b/drivers/net/8139too.c
@@ -126,14 +126,14 @@
 #define USE_IO_OPS 1
 #endif
 
-/* define to 1 to enable copious debugging info */
-#undef RTL8139_DEBUG
+/* define to 1, 2 or 3 to enable copious debugging info */
+#define RTL8139_DEBUG 0
 
 /* define to 1 to disable lightweight runtime debugging checks */
 #undef RTL8139_NDEBUG
 
 
-#ifdef RTL8139_DEBUG
+#if RTL8139_DEBUG
 /* note: prints function name for you */
 #  define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
 #else
@@ -569,7 +569,7 @@ struct rtl_extra_stats {
 };
 
 struct rtl8139_private {
-	void *mmio_addr;
+	void __iomem *mmio_addr;
 	int drv_flags;
 	struct pci_dev *pci_dev;
 	u32 msg_enable;
@@ -614,7 +614,7 @@ MODULE_PARM_DESC (multicast_filter_limit
 MODULE_PARM_DESC (media, "8139too: Bits 4+9: force full duplex, bit 5: 100Mbps");
 MODULE_PARM_DESC (full_duplex, "8139too: Force full duplex for board(s) (1)");
 
-static int read_eeprom (void *ioaddr, int location, int addr_len);
+static int read_eeprom (void __iomem *ioaddr, int location, int addr_len);
 static int rtl8139_open (struct net_device *dev);
 static int mdio_read (struct net_device *dev, int phy_id, int location);
 static void mdio_write (struct net_device *dev, int phy_id, int location,
@@ -638,46 +638,20 @@ static void __set_rx_mode (struct net_de
 static void rtl8139_hw_start (struct net_device *dev);
 static struct ethtool_ops rtl8139_ethtool_ops;
 
-#ifdef USE_IO_OPS
-
-#define RTL_R8(reg)		inb (((unsigned long)ioaddr) + (reg))
-#define RTL_R16(reg)		inw (((unsigned long)ioaddr) + (reg))
-#define RTL_R32(reg)		((unsigned long) inl (((unsigned long)ioaddr) + (reg)))
-#define RTL_W8(reg, val8)	outb ((val8), ((unsigned long)ioaddr) + (reg))
-#define RTL_W16(reg, val16)	outw ((val16), ((unsigned long)ioaddr) + (reg))
-#define RTL_W32(reg, val32)	outl ((val32), ((unsigned long)ioaddr) + (reg))
-#define RTL_W8_F		RTL_W8
-#define RTL_W16_F		RTL_W16
-#define RTL_W32_F		RTL_W32
-#undef readb
-#undef readw
-#undef readl
-#undef writeb
-#undef writew
-#undef writel
-#define readb(addr) inb((unsigned long)(addr))
-#define readw(addr) inw((unsigned long)(addr))
-#define readl(addr) inl((unsigned long)(addr))
-#define writeb(val,addr) outb((val),(unsigned long)(addr))
-#define writew(val,addr) outw((val),(unsigned long)(addr))
-#define writel(val,addr) outl((val),(unsigned long)(addr))
-
-#else
-
 /* write MMIO register, with flush */
 /* Flush avoids rtl8139 bug w/ posted MMIO writes */
-#define RTL_W8_F(reg, val8)	do { writeb ((val8), ioaddr + (reg)); readb (ioaddr + (reg)); } while (0)
-#define RTL_W16_F(reg, val16)	do { writew ((val16), ioaddr + (reg)); readw (ioaddr + (reg)); } while (0)
-#define RTL_W32_F(reg, val32)	do { writel ((val32), ioaddr + (reg)); readl (ioaddr + (reg)); } while (0)
+#define RTL_W8_F(reg, val8)	do { iowrite8 ((val8), ioaddr + (reg)); ioread8 (ioaddr + (reg)); } while (0)
+#define RTL_W16_F(reg, val16)	do { iowrite16 ((val16), ioaddr + (reg)); ioread16 (ioaddr + (reg)); } while (0)
+#define RTL_W32_F(reg, val32)	do { iowrite32 ((val32), ioaddr + (reg)); ioread32 (ioaddr + (reg)); } while (0)
 
 
 #define MMIO_FLUSH_AUDIT_COMPLETE 1
 #if MMIO_FLUSH_AUDIT_COMPLETE
 
 /* write MMIO register */
-#define RTL_W8(reg, val8)	writeb ((val8), ioaddr + (reg))
-#define RTL_W16(reg, val16)	writew ((val16), ioaddr + (reg))
-#define RTL_W32(reg, val32)	writel ((val32), ioaddr + (reg))
+#define RTL_W8(reg, val8)	iowrite8 ((val8), ioaddr + (reg))
+#define RTL_W16(reg, val16)	iowrite16 ((val16), ioaddr + (reg))
+#define RTL_W32(reg, val32)	iowrite32 ((val32), ioaddr + (reg))
 
 #else
 
@@ -689,11 +663,9 @@ static struct ethtool_ops rtl8139_ethtoo
 #endif /* MMIO_FLUSH_AUDIT_COMPLETE */
 
 /* read MMIO register */
-#define RTL_R8(reg)		readb (ioaddr + (reg))
-#define RTL_R16(reg)		readw (ioaddr + (reg))
-#define RTL_R32(reg)		((unsigned long) readl (ioaddr + (reg)))
-
-#endif /* USE_IO_OPS */
+#define RTL_R8(reg)		ioread8 (ioaddr + (reg))
+#define RTL_R16(reg)		ioread16 (ioaddr + (reg))
+#define RTL_R32(reg)		((unsigned long) ioread32 (ioaddr + (reg)))
 
 
 static const u16 rtl8139_intr_mask =
@@ -740,10 +712,13 @@ static void __rtl8139_cleanup_dev (struc
 	assert (tp->pci_dev != NULL);
 	pdev = tp->pci_dev;
 
-#ifndef USE_IO_OPS
+#ifdef USE_IO_OPS
+	if (tp->mmio_addr)
+		ioport_unmap (tp->mmio_addr);
+#else
 	if (tp->mmio_addr)
-		iounmap (tp->mmio_addr);
-#endif /* !USE_IO_OPS */
+		pci_iounmap (pdev, tp->mmio_addr);
+#endif /* USE_IO_OPS */
 
 	/* it's ok to call this even if we have no regions to free */
 	pci_release_regions (pdev);
@@ -753,7 +728,7 @@ static void __rtl8139_cleanup_dev (struc
 }
 
 
-static void rtl8139_chip_reset (void *ioaddr)
+static void rtl8139_chip_reset (void __iomem *ioaddr)
 {
 	int i;
 
@@ -773,7 +748,7 @@ static void rtl8139_chip_reset (void *io
 static int __devinit rtl8139_init_board (struct pci_dev *pdev,
 					 struct net_device **dev_out)
 {
-	void *ioaddr;
+	void __iomem *ioaddr;
 	struct net_device *dev;
 	struct rtl8139_private *tp;
 	u8 tmp8;
@@ -855,13 +830,18 @@ static int __devinit rtl8139_init_board 
 	pci_set_master (pdev);
 
 #ifdef USE_IO_OPS
-	ioaddr = (void *) pio_start;
+	ioaddr = ioport_map(pio_start, pio_len);
+	if (!ioaddr) {
+		printk (KERN_ERR PFX "%s: cannot map PIO, aborting\n", pci_name(pdev));
+		rc = -EIO;
+		goto err_out;
+	}
 	dev->base_addr = pio_start;
 	tp->mmio_addr = ioaddr;
 	tp->regs_len = pio_len;
 #else
 	/* ioremap MMIO region */
-	ioaddr = ioremap (mmio_start, mmio_len);
+	ioaddr = pci_iomap(pdev, 1, 0);
 	if (ioaddr == NULL) {
 		printk (KERN_ERR PFX "%s: cannot remap MMIO, aborting\n", pci_name(pdev));
 		rc = -EIO;
@@ -947,7 +927,7 @@ static int __devinit rtl8139_init_one (s
 	struct net_device *dev = NULL;
 	struct rtl8139_private *tp;
 	int i, addr_len, option;
-	void *ioaddr;
+	void __iomem *ioaddr;
 	static int board_idx = -1;
 	u8 pci_rev;
 
@@ -1147,47 +1127,46 @@ static void __devexit rtl8139_remove_one
    No extra delay is needed with 33Mhz PCI, but 66Mhz may change this.
  */
 
-#define eeprom_delay()	readl(ee_addr)
+#define eeprom_delay()	RTL_R32(Cfg9346)
 
 /* The EEPROM commands include the alway-set leading bit. */
 #define EE_WRITE_CMD	(5)
 #define EE_READ_CMD		(6)
 #define EE_ERASE_CMD	(7)
 
-static int __devinit read_eeprom (void *ioaddr, int location, int addr_len)
+static int __devinit read_eeprom (void __iomem *ioaddr, int location, int addr_len)
 {
 	int i;
 	unsigned retval = 0;
-	void *ee_addr = ioaddr + Cfg9346;
 	int read_cmd = location | (EE_READ_CMD << addr_len);
 
-	writeb (EE_ENB & ~EE_CS, ee_addr);
-	writeb (EE_ENB, ee_addr);
+	RTL_W8 (Cfg9346, EE_ENB & ~EE_CS);
+	RTL_W8 (Cfg9346, EE_ENB);
 	eeprom_delay ();
 
 	/* Shift the read command bits out. */
 	for (i = 4 + addr_len; i >= 0; i--) {
 		int dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
-		writeb (EE_ENB | dataval, ee_addr);
+		RTL_W8 (Cfg9346, EE_ENB | dataval);
 		eeprom_delay ();
-		writeb (EE_ENB | dataval | EE_SHIFT_CLK, ee_addr);
+		RTL_W8 (Cfg9346, EE_ENB | dataval | EE_SHIFT_CLK);
 		eeprom_delay ();
 	}
-	writeb (EE_ENB, ee_addr);
+	RTL_W8 (Cfg9346, EE_ENB);
 	eeprom_delay ();
 
 	for (i = 16; i > 0; i--) {
-		writeb (EE_ENB | EE_SHIFT_CLK, ee_addr);
+		RTL_W8 (Cfg9346, EE_ENB | EE_SHIFT_CLK);
 		eeprom_delay ();
 		retval =
-		    (retval << 1) | ((readb (ee_addr) & EE_DATA_READ) ? 1 :
+		    (retval << 1) | ((RTL_R8 (Cfg9346) & EE_DATA_READ) ? 1 :
 				     0);
-		writeb (EE_ENB, ee_addr);
+		RTL_W8 (Cfg9346, EE_ENB);
 		eeprom_delay ();
 	}
 
 	/* Terminate the EEPROM access. */
-	writeb (~EE_CS, ee_addr);
+	RTL_W8 (Cfg9346, ~EE_CS);
 	eeprom_delay ();
 
 	return retval;
@@ -1206,7 +1185,7 @@ static int __devinit read_eeprom (void *
 #define MDIO_WRITE0 (MDIO_DIR)
 #define MDIO_WRITE1 (MDIO_DIR | MDIO_DATA_OUT)
 
-#define mdio_delay(mdio_addr)	readb(mdio_addr)
+#define mdio_delay()	RTL_R8(Config4)
 
 
 static char mii_2_8139_map[8] = {
@@ -1223,15 +1202,15 @@ static char mii_2_8139_map[8] = {
 
 #ifdef CONFIG_8139TOO_8129
 /* Syncronize the MII management interface by shifting 32 one bits out. */
-static void mdio_sync (void *mdio_addr)
+static void mdio_sync (void __iomem *ioaddr)
 {
 	int i;
 
 	for (i = 32; i >= 0; i--) {
-		writeb (MDIO_WRITE1, mdio_addr);
-		mdio_delay (mdio_addr);
-		writeb (MDIO_WRITE1 | MDIO_CLK, mdio_addr);
-		mdio_delay (mdio_addr);
+		RTL_W8 (Config4, MDIO_WRITE1);
+		mdio_delay ();
+		RTL_W8 (Config4, MDIO_WRITE1 | MDIO_CLK);
+		mdio_delay ();
 	}
 }
 #endif
@@ -1241,35 +1220,36 @@ static int mdio_read (struct net_device 
 	struct rtl8139_private *tp = netdev_priv(dev);
 	int retval = 0;
 #ifdef CONFIG_8139TOO_8129
-	void *mdio_addr = tp->mmio_addr + Config4;
+	void __iomem *ioaddr = tp->mmio_addr;
 	int mii_cmd = (0xf6 << 10) | (phy_id << 5) | location;
 	int i;
 #endif
 
 	if (phy_id > 31) {	/* Really a 8139.  Use internal registers. */
+		void __iomem *ioaddr = tp->mmio_addr;
 		return location < 8 && mii_2_8139_map[location] ?
-		    readw (tp->mmio_addr + mii_2_8139_map[location]) : 0;
+		    RTL_R16 (mii_2_8139_map[location]) : 0;
 	}
 
 #ifdef CONFIG_8139TOO_8129
-	mdio_sync (mdio_addr);
+	mdio_sync (ioaddr);
 	/* Shift the read command bits out. */
 	for (i = 15; i >= 0; i--) {
 		int dataval = (mii_cmd & (1 << i)) ? MDIO_DATA_OUT : 0;
 
-		writeb (MDIO_DIR | dataval, mdio_addr);
-		mdio_delay (mdio_addr);
-		writeb (MDIO_DIR | dataval | MDIO_CLK, mdio_addr);
-		mdio_delay (mdio_addr);
+		RTL_W8 (Config4, MDIO_DIR | dataval);
+		mdio_delay ();
+		RTL_W8 (Config4, MDIO_DIR | dataval | MDIO_CLK);
+		mdio_delay ();
 	}
 
 	/* Read the two transition, 16 data, and wire-idle bits. */
 	for (i = 19; i > 0; i--) {
-		writeb (0, mdio_addr);
-		mdio_delay (mdio_addr);
-		retval = (retval << 1) | ((readb (mdio_addr) & MDIO_DATA_IN) ? 1 : 0);
-		writeb (MDIO_CLK, mdio_addr);
-		mdio_delay (mdio_addr);
+		RTL_W8 (Config4, 0);
+		mdio_delay ();
+		retval = (retval << 1) | ((RTL_R8 (Config4) & MDIO_DATA_IN) ? 1 : 0);
+		RTL_W8 (Config4, MDIO_CLK);
+		mdio_delay ();
 	}
 #endif
 
@@ -1282,13 +1262,13 @@ static void mdio_write (struct net_devic
 {
 	struct rtl8139_private *tp = netdev_priv(dev);
 #ifdef CONFIG_8139TOO_8129
-	void *mdio_addr = tp->mmio_addr + Config4;
+	void __iomem *ioaddr = tp->mmio_addr;
 	int mii_cmd = (0x5002 << 16) | (phy_id << 23) | (location << 18) | value;
 	int i;
 #endif
 
 	if (phy_id > 31) {	/* Really a 8139.  Use internal registers. */
-		void *ioaddr = tp->mmio_addr;
+		void __iomem *ioaddr = tp->mmio_addr;
 		if (location == 0) {
 			RTL_W8 (Cfg9346, Cfg9346_Unlock);
 			RTL_W16 (BasicModeCtrl, value);
@@ -1299,23 +1279,23 @@ static void mdio_write (struct net_devic
 	}
 
 #ifdef CONFIG_8139TOO_8129
-	mdio_sync (mdio_addr);
+	mdio_sync (ioaddr);
 
 	/* Shift the command bits out. */
 	for (i = 31; i >= 0; i--) {
 		int dataval =
 		    (mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0;
-		writeb (dataval, mdio_addr);
-		mdio_delay (mdio_addr);
-		writeb (dataval | MDIO_CLK, mdio_addr);
-		mdio_delay (mdio_addr);
+		RTL_W8 (Config4, dataval);
+		mdio_delay ();
+		RTL_W8 (Config4, dataval | MDIO_CLK);
+		mdio_delay ();
 	}
 	/* Clear out extra bits. */
 	for (i = 2; i > 0; i--) {
-		writeb (0, mdio_addr);
-		mdio_delay (mdio_addr);
-		writeb (MDIO_CLK, mdio_addr);
-		mdio_delay (mdio_addr);
+		RTL_W8 (Config4, 0);
+		mdio_delay ();
+		RTL_W8 (Config4, MDIO_CLK);
+		mdio_delay ();
 	}
 #endif
 }
@@ -1325,7 +1305,7 @@ static int rtl8139_open (struct net_devi
 {
 	struct rtl8139_private *tp = netdev_priv(dev);
 	int retval;
-	void *ioaddr = tp->mmio_addr;
+	void __iomem *ioaddr = tp->mmio_addr;
 
 	retval = request_irq (dev->irq, rtl8139_interrupt, SA_SHIRQ, dev->name, dev);
 	if (retval)
@@ -1382,7 +1362,7 @@ static void rtl_check_media (struct net_
 static void rtl8139_hw_start (struct net_device *dev)
 {
 	struct rtl8139_private *tp = netdev_priv(dev);
-	void *ioaddr = tp->mmio_addr;
+	void __iomem *ioaddr = tp->mmio_addr;
 	u32 i;
 	u8 tmp;
 
@@ -1484,7 +1464,7 @@ static void rtl8139_tune_twister (struct
 				  struct rtl8139_private *tp)
 {
 	int linkcase;
-	void *ioaddr = tp->mmio_addr;
+	void __iomem *ioaddr = tp->mmio_addr;
 
 	/* This is a complicated state machine to configure the "twister" for
 	   impedance/echos based on the cable length.
@@ -1568,7 +1548,7 @@ static void rtl8139_tune_twister (struct
 
 static inline void rtl8139_thread_iter (struct net_device *dev,
 				 struct rtl8139_private *tp,
-				 void *ioaddr)
+				 void __iomem *ioaddr)
 {
 	int mii_lpa;
 
@@ -1626,7 +1606,7 @@ static int rtl8139_thread (void *data)
 		do {
 			timeout = interruptible_sleep_on_timeout (&tp->thr_wait, timeout);
 			/* make swsusp happy with our thread */
-			try_to_freeze(PF_FREEZE);
+			try_to_freeze();
 		} while (!signal_pending (current) && (timeout > 0));
 
 		if (signal_pending (current)) {
@@ -1676,7 +1656,7 @@ static inline void rtl8139_tx_clear (str
 static void rtl8139_tx_timeout (struct net_device *dev)
 {
 	struct rtl8139_private *tp = netdev_priv(dev);
-	void *ioaddr = tp->mmio_addr;
+	void __iomem *ioaddr = tp->mmio_addr;
 	int i;
 	u8 tmp8;
 	unsigned long flags;
@@ -1721,7 +1701,7 @@ static void rtl8139_tx_timeout (struct n
 static int rtl8139_start_xmit (struct sk_buff *skb, struct net_device *dev)
 {
 	struct rtl8139_private *tp = netdev_priv(dev);
-	void *ioaddr = tp->mmio_addr;
+	void __iomem *ioaddr = tp->mmio_addr;
 	unsigned int entry;
 	unsigned int len = skb->len;
 
@@ -1763,7 +1743,7 @@ static int rtl8139_start_xmit (struct sk
 
 static void rtl8139_tx_interrupt (struct net_device *dev,
 				  struct rtl8139_private *tp,
-				  void *ioaddr)
+				  void __iomem *ioaddr)
 {
 	unsigned long dirty_tx, tx_left;
 
@@ -1833,7 +1813,7 @@ static void rtl8139_tx_interrupt (struct
 
 /* TODO: clean this up!  Rx reset need not be this intensive */
 static void rtl8139_rx_err (u32 rx_status, struct net_device *dev,
-			    struct rtl8139_private *tp, void *ioaddr)
+			    struct rtl8139_private *tp, void __iomem *ioaddr)
 {
 	u8 tmp8;
 #ifdef CONFIG_8139_OLD_RX_RESET
@@ -1930,7 +1910,7 @@ static __inline__ void wrap_copy(struct 
 
 static void rtl8139_isr_ack(struct rtl8139_private *tp)
 {
-	void *ioaddr = tp->mmio_addr;
+	void __iomem *ioaddr = tp->mmio_addr;
 	u16 status;
 
 	status = RTL_R16 (IntrStatus) & RxAckBits;
@@ -1949,7 +1929,7 @@ static void rtl8139_isr_ack(struct rtl81
 static int rtl8139_rx(struct net_device *dev, struct rtl8139_private *tp,
 		      int budget)
 {
-	void *ioaddr = tp->mmio_addr;
+	void __iomem *ioaddr = tp->mmio_addr;
 	int received = 0;
 	unsigned char *rx_ring = tp->rx_ring;
 	unsigned int cur_rx = tp->cur_rx;
@@ -2087,7 +2067,7 @@ out:
 
 static void rtl8139_weird_interrupt (struct net_device *dev,
 				     struct rtl8139_private *tp,
-				     void *ioaddr,
+				     void __iomem *ioaddr,
 				     int status, int link_changed)
 {
 	DPRINTK ("%s: Abnormal interrupt, status %8.8x.\n",
@@ -2127,7 +2107,7 @@ static void rtl8139_weird_interrupt (str
 static int rtl8139_poll(struct net_device *dev, int *budget)
 {
 	struct rtl8139_private *tp = netdev_priv(dev);
-	void *ioaddr = tp->mmio_addr;
+	void __iomem *ioaddr = tp->mmio_addr;
 	int orig_budget = min(*budget, dev->quota);
 	int done = 1;
 
@@ -2165,7 +2145,7 @@ static irqreturn_t rtl8139_interrupt (in
 {
 	struct net_device *dev = (struct net_device *) dev_instance;
 	struct rtl8139_private *tp = netdev_priv(dev);
-	void *ioaddr = tp->mmio_addr;
+	void __iomem *ioaddr = tp->mmio_addr;
 	u16 status, ackstat;
 	int link_changed = 0; /* avoid bogus "uninit" warning */
 	int handled = 0;
@@ -2241,7 +2221,7 @@ static void rtl8139_poll_controller(stru
 static int rtl8139_close (struct net_device *dev)
 {
 	struct rtl8139_private *tp = netdev_priv(dev);
-	void *ioaddr = tp->mmio_addr;
+	void __iomem *ioaddr = tp->mmio_addr;
 	int ret = 0;
 	unsigned long flags;
 
@@ -2304,7 +2284,7 @@ static int rtl8139_close (struct net_dev
 static void rtl8139_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
 {
 	struct rtl8139_private *np = netdev_priv(dev);
-	void *ioaddr = np->mmio_addr;
+	void __iomem *ioaddr = np->mmio_addr;
 
 	spin_lock_irq(&np->lock);
 	if (rtl_chip_info[np->chipset].flags & HasLWake) {
@@ -2338,7 +2318,7 @@ static void rtl8139_get_wol(struct net_d
 static int rtl8139_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
 {
 	struct rtl8139_private *np = netdev_priv(dev);
-	void *ioaddr = np->mmio_addr;
+	void __iomem *ioaddr = np->mmio_addr;
 	u32 support;
 	u8 cfg3, cfg5;
 
@@ -2506,7 +2486,7 @@ static int netdev_ioctl(struct net_devic
 static struct net_device_stats *rtl8139_get_stats (struct net_device *dev)
 {
 	struct rtl8139_private *tp = netdev_priv(dev);
-	void *ioaddr = tp->mmio_addr;
+	void __iomem *ioaddr = tp->mmio_addr;
 	unsigned long flags;
 
 	if (netif_running(dev)) {
@@ -2525,7 +2505,7 @@ static struct net_device_stats *rtl8139_
 static void __set_rx_mode (struct net_device *dev)
 {
 	struct rtl8139_private *tp = netdev_priv(dev);
-	void *ioaddr = tp->mmio_addr;
+	void __iomem *ioaddr = tp->mmio_addr;
 	u32 mc_filter[2];	/* Multicast hash filter */
 	int i, rx_mode;
 	u32 tmp;
@@ -2586,7 +2566,7 @@ static int rtl8139_suspend (struct pci_d
 {
 	struct net_device *dev = pci_get_drvdata (pdev);
 	struct rtl8139_private *tp = netdev_priv(dev);
-	void *ioaddr = tp->mmio_addr;
+	void __iomem *ioaddr = tp->mmio_addr;
 	unsigned long flags;
 
 	pci_save_state (pdev);
diff --git a/drivers/net/82596.c b/drivers/net/82596.c
--- a/drivers/net/82596.c
+++ b/drivers/net/82596.c
@@ -546,11 +546,11 @@ static inline void init_rx_bufs(struct n
 		rbd->b_next = WSWAPrbd(virt_to_bus(rbd+1));
 		rbd->b_addr = WSWAPrbd(virt_to_bus(rbd));
 		rbd->skb = skb;
-		rbd->v_data = skb->tail;
-		rbd->b_data = WSWAPchar(virt_to_bus(skb->tail));
+		rbd->v_data = skb->data;
+		rbd->b_data = WSWAPchar(virt_to_bus(skb->data));
 		rbd->size = PKT_BUF_SZ;
 #ifdef __mc68000__
-		cache_clear(virt_to_phys(skb->tail), PKT_BUF_SZ);
+		cache_clear(virt_to_phys(skb->data), PKT_BUF_SZ);
 #endif
 	}
 	lp->rbd_head = lp->rbds;
@@ -816,10 +816,10 @@ static inline int i596_rx(struct net_dev
 				rx_in_place = 1;
 				rbd->skb = newskb;
 				newskb->dev = dev;
-				rbd->v_data = newskb->tail;
-				rbd->b_data = WSWAPchar(virt_to_bus(newskb->tail));
+				rbd->v_data = newskb->data;
+				rbd->b_data = WSWAPchar(virt_to_bus(newskb->data));
 #ifdef __mc68000__
-				cache_clear(virt_to_phys(newskb->tail), PKT_BUF_SZ);
+				cache_clear(virt_to_phys(newskb->data), PKT_BUF_SZ);
 #endif
 			}
 			else
@@ -840,7 +840,7 @@ memory_squeeze:
 				skb->protocol=eth_type_trans(skb,dev);
 				skb->len = pkt_len;
 #ifdef __mc68000__
-				cache_clear(virt_to_phys(rbd->skb->tail),
+				cache_clear(virt_to_phys(rbd->skb->data),
 						pkt_len);
 #endif
 				netif_rx(skb);
diff --git a/drivers/net/8390.c b/drivers/net/8390.c
--- a/drivers/net/8390.c
+++ b/drivers/net/8390.c
@@ -225,9 +225,9 @@ void ei_tx_timeout(struct net_device *de
 	unsigned long icucr;
 
 	local_irq_save(flags);
-	icucr = inl(ICUCR1);
+	icucr = inl(M32R_ICU_CR1_PORTL);
 	icucr |= M32R_ICUCR_ISMOD11;
-	outl(icucr, ICUCR1);
+	outl(icucr, M32R_ICU_CR1_PORTL);
 	local_irq_restore(flags);
 #endif
 	ei_local->stat.tx_errors++;
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -3,6 +3,8 @@
 # Network device configuration
 #
 
+menu "Network device support"
+
 config NETDEVICES
 	depends on NET
 	bool "Network device support"
@@ -21,9 +23,12 @@ config NETDEVICES
 
 	  If unsure, say Y.
 
+# All the following symbols are dependent on NETDEVICES - do not repeat
+# that for each of the symbols.
+if NETDEVICES
+
 config DUMMY
 	tristate "Dummy net driver support"
-	depends on NETDEVICES
 	---help---
 	  This is essentially a bit-bucket device (i.e. traffic you send to
 	  this device is consigned into oblivion) with a configurable IP
@@ -43,7 +48,6 @@ config DUMMY
 
 config BONDING
 	tristate "Bonding driver support"
-	depends on NETDEVICES
 	depends on INET
 	---help---
 	  Say 'Y' or 'M' if you wish to be able to 'bond' multiple Ethernet
@@ -61,7 +65,6 @@ config BONDING
 
 config EQUALIZER
 	tristate "EQL (serial line load balancing) support"
-	depends on NETDEVICES
 	---help---
 	  If you have two serial connections to some other computer (this
 	  usually requires two modems and two telephone lines) and you use
@@ -81,7 +84,6 @@ config EQUALIZER
 
 config TUN
 	tristate "Universal TUN/TAP device driver support"
-	depends on NETDEVICES
 	select CRC32
 	---help---
 	  TUN/TAP provides packet reception and transmission for user space
@@ -105,7 +107,7 @@ config TUN
 
 config NET_SB1000
 	tristate "General Instruments Surfboard 1000"
-	depends on NETDEVICES && PNP
+	depends on PNP
 	---help---
 	  This is a driver for the General Instrument (also known as
 	  NextLevel) SURFboard 1000 internal
@@ -127,16 +129,14 @@ config NET_SB1000
 
 	  If you don't have this card, of course say N.
 
-if NETDEVICES
 	source "drivers/net/arcnet/Kconfig"
-endif
 
 #
 #	Ethernet
 #
 
 menu "Ethernet (10 or 100Mbit)"
-	depends on NETDEVICES && !UML
+	depends on !UML
 
 config NET_ETHERNET
 	bool "Ethernet (10 or 100Mbit)"
@@ -824,6 +824,18 @@ config SMC9194
 	  <file:Documentation/networking/net-modules.txt>. The module
 	  will be called smc9194.
 
+config DM9000
+	tristate "DM9000 support"
+	depends on ARM && NET_ETHERNET
+	select CRC32
+	select MII
+	---help---
+	  Support for DM9000 chipset.
+
+	  To compile this driver as a module, choose M here and read
+	  <file:Documentation/networking/net-modules.txt>.  The module will be
+	  called dm9000.
+
 config NET_VENDOR_RACAL
 	bool "Racal-Interlan (Micom) NI cards"
 	depends on NET_ETHERNET && ISA
@@ -989,21 +1001,6 @@ config EEXPRESS_PRO
 	  <file:Documentation/networking/net-modules.txt>. The module
 	  will be called eepro.
 
-config FMV18X
-	tristate "FMV-181/182/183/184 support (OBSOLETE)"
-	depends on NET_ISA && OBSOLETE
-	---help---
-	  If you have a Fujitsu FMV-181/182/183/184 network (Ethernet) card,
-	  say Y and read the Ethernet-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  If you use an FMV-183 or FMV-184 and it is not working, you may need
-	  to disable Plug & Play mode of the card.
-
-	  To compile this driver as a module, choose M here and read
-	  <file:Documentation/networking/net-modules.txt>. The module
-	  will be called fmv18x.
-
 config HPLAN_PLUS
 	tristate "HP PCLAN+ (27247B and 27252A) support"
 	depends on NET_ISA
@@ -1092,14 +1089,6 @@ config SEEQ8005
 	  <file:Documentation/networking/net-modules.txt>. The module
 	  will be called seeq8005.
 
-config SK_G16
-	tristate "SK_G16 support (OBSOLETE)"
-	depends on NET_ISA && OBSOLETE
-	help
-	  If you have a network (Ethernet) card of this type, say Y and read
-	  the Ethernet-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.
-
 config SKMC
 	tristate "SKnet MCA support"
 	depends on NET_ETHERNET && MCA && BROKEN
@@ -1146,7 +1135,7 @@ config IBMLANA
 
 config IBMVETH
 	tristate "IBM LAN Virtual Ethernet support"
-	depends on NETDEVICES && NET_ETHERNET && PPC_PSERIES
+	depends on NET_ETHERNET && PPC_PSERIES
 	---help---
 	  This driver supports virtual ethernet adapters on newer IBM iSeries
 	  and pSeries systems.
@@ -1156,7 +1145,7 @@ config IBMVETH
 	  be called ibmveth.
 
 config IBM_EMAC
-	tristate "IBM PPC4xx EMAC driver support"
+	bool "IBM PPC4xx EMAC driver support"
 	depends on 4xx
 	select CRC32
 	---help---
@@ -1165,7 +1154,7 @@ config IBM_EMAC
 
 config IBM_EMAC_ERRMSG
 	bool "Verbose error messages"
-	depends on IBM_EMAC
+	depends on IBM_EMAC && BROKEN
 
 config IBM_EMAC_RXB
 	int "Number of receive buffers"
@@ -1331,7 +1320,7 @@ config FORCEDETH
 
 config CS89x0
 	tristate "CS89x0 support"
-	depends on NET_PCI && (ISA || ARCH_IXDP2X01)
+	depends on (NET_PCI && (ISA || ARCH_IXDP2X01)) || ARCH_PNX0105
 	---help---
 	  Support for CS89x0 chipset based Ethernet cards. If you have a
 	  network (Ethernet) card of this type, say Y and read the
@@ -1499,14 +1488,14 @@ config 8139CP
 	  will be called 8139cp.  This is recommended.
 
 config 8139TOO
-	tristate "RealTek RTL-8139 PCI Fast Ethernet Adapter support"
+	tristate "RealTek RTL-8129/8130/8139 PCI Fast Ethernet Adapter support"
 	depends on NET_PCI && PCI
 	select CRC32
 	select MII
 	---help---
 	  This is a driver for the Fast Ethernet PCI network cards based on
-	  the RTL8139 chips. If you have one of those, say Y and read
-	  the Ethernet-HOWTO <http://www.tldp.org/docs.html#howto>.
+	  the RTL 8129/8130/8139 chips. If you have one of those, say Y and
+	  read the Ethernet-HOWTO <http://www.tldp.org/docs.html#howto>.
 
 	  To compile this driver as a module, choose M here: the module
 	  will be called 8139too.  This is recommended.
@@ -1769,7 +1758,7 @@ endmenu
 #
 
 menu "Ethernet (1000 Mbit)"
-	depends on NETDEVICES && !UML
+	depends on !UML
 
 config ACENIC
 	tristate "Alteon AceNIC/3Com 3C985/NetGear GA620 Gigabit support"
@@ -1932,6 +1921,18 @@ config R8169_VLAN
 	  
 	  If in doubt, say Y.
 
+config SKGE
+	tristate "New SysKonnect GigaEthernet support (EXPERIMENTAL)"
+	depends on PCI && EXPERIMENTAL
+	select CRC32
+	---help---
+	  This driver support the Marvell Yukon or SysKonnect SK-98xx/SK-95xx
+	  and related Gigabit Ethernet adapters. It is a new smaller driver
+	  driver with better performance and more complete ethtool support.
+
+	  It does not support the link failover and network management 
+	  features that "portable" vendor supplied sk98lin driver does.
+	
 config SK98LIN
 	tristate "Marvell Yukon Chipset / SysKonnect SK-98xx Support"
 	depends on PCI
@@ -2088,7 +2089,7 @@ endmenu
 #
 
 menu "Ethernet (10000 Mbit)"
-	depends on NETDEVICES && !UML
+	depends on !UML
 
 config IXGB
 	tristate "Intel(R) PRO/10GbE support"
@@ -2183,11 +2184,11 @@ source "drivers/s390/net/Kconfig"
 
 config ISERIES_VETH
 	tristate "iSeries Virtual Ethernet driver support"
-	depends on NETDEVICES && PPC_ISERIES
+	depends on PPC_ISERIES
 
 config FDDI
 	bool "FDDI driver support"
-	depends on NETDEVICES && (PCI || EISA)
+	depends on (PCI || EISA)
 	help
 	  Fiber Distributed Data Interface is a high speed local area network
 	  design; essentially a replacement for high speed Ethernet. FDDI can
@@ -2236,7 +2237,7 @@ config SKFP
 
 config HIPPI
 	bool "HIPPI driver support (EXPERIMENTAL)"
-	depends on NETDEVICES && EXPERIMENTAL && INET && PCI
+	depends on EXPERIMENTAL && INET && PCI
 	help
 	  HIgh Performance Parallel Interface (HIPPI) is a 800Mbit/sec and
 	  1600Mbit/sec dual-simplex switched or point-to-point network. HIPPI
@@ -2268,7 +2269,7 @@ config ROADRUNNER_LARGE_RINGS
 
 config PLIP
 	tristate "PLIP (parallel port) support"
-	depends on NETDEVICES && PARPORT
+	depends on PARPORT
 	---help---
 	  PLIP (Parallel Line Internet Protocol) is used to create a
 	  reasonably fast mini network consisting of two (or, rarely, more)
@@ -2304,7 +2305,6 @@ config PLIP
 
 config PPP
 	tristate "PPP (point-to-point protocol) support"
-	depends on NETDEVICES
 	---help---
 	  PPP (Point to Point Protocol) is a newer and better SLIP.  It serves
 	  the same purpose: sending Internet traffic over telephone (and other
@@ -2440,7 +2440,6 @@ config PPPOATM
 
 config SLIP
 	tristate "SLIP (serial line) support"
-	depends on NETDEVICES
 	---help---
 	  Say Y if you intend to use SLIP or CSLIP (compressed SLIP) to
 	  connect to your Internet service provider or to connect to some
@@ -2507,7 +2506,7 @@ config SLIP_MODE_SLIP6
 
 config NET_FC
 	bool "Fibre Channel driver support"
-	depends on NETDEVICES && SCSI && PCI
+	depends on SCSI && PCI
 	help
 	  Fibre Channel is a high speed serial protocol mainly used to connect
 	  large storage devices to the computer; it is compatible with and
@@ -2520,7 +2519,7 @@ config NET_FC
 
 config SHAPER
 	tristate "Traffic Shaper (EXPERIMENTAL)"
-	depends on NETDEVICES && EXPERIMENTAL
+	depends on EXPERIMENTAL
 	---help---
 	  The traffic shaper is a virtual network device that allows you to
 	  limit the rate of outgoing data flow over some other network device.
@@ -2541,8 +2540,27 @@ config SHAPER
 
 config NETCONSOLE
 	tristate "Network console logging support (EXPERIMENTAL)"
-	depends on NETDEVICES && EXPERIMENTAL
+	depends on EXPERIMENTAL
 	---help---
 	If you want to log kernel messages over the network, enable this.
 	See <file:Documentation/networking/netconsole.txt> for details.
 
+endif #NETDEVICES
+
+config NETPOLL
+	def_bool NETCONSOLE
+
+config NETPOLL_RX
+	bool "Netpoll support for trapping incoming packets"
+	default n
+	depends on NETPOLL
+
+config NETPOLL_TRAP
+	bool "Netpoll traffic trapping"
+	default n
+	depends on NETPOLL
+
+config NET_POLL_CONTROLLER
+	def_bool NETPOLL
+
+endmenu
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -53,6 +53,7 @@ obj-$(CONFIG_FEALNX) += fealnx.o
 obj-$(CONFIG_TIGON3) += tg3.o
 obj-$(CONFIG_BNX2) += bnx2.o
 obj-$(CONFIG_TC35815) += tc35815.o
+obj-$(CONFIG_SKGE) += skge.o
 obj-$(CONFIG_SK98LIN) += sk98lin/
 obj-$(CONFIG_SKFP) += skfp/
 obj-$(CONFIG_VIA_RHINE) += via-rhine.o
@@ -74,7 +75,6 @@ obj-$(CONFIG_MAC8390) += mac8390.o 8390.
 obj-$(CONFIG_APNE) += apne.o 8390.o
 obj-$(CONFIG_PCMCIA_PCNET) += 8390.o
 obj-$(CONFIG_SHAPER) += shaper.o
-obj-$(CONFIG_SK_G16) += sk_g16.o
 obj-$(CONFIG_HP100) += hp100.o
 obj-$(CONFIG_SMC9194) += smc9194.o
 obj-$(CONFIG_FEC) += fec.o
@@ -122,7 +122,6 @@ obj-$(CONFIG_DEFXX) += defxx.o
 obj-$(CONFIG_SGISEEQ) += sgiseeq.o
 obj-$(CONFIG_SGI_O2MACE_ETH) += meth.o
 obj-$(CONFIG_AT1700) += at1700.o
-obj-$(CONFIG_FMV18X) += fmv18x.o
 obj-$(CONFIG_EL1) += 3c501.o
 obj-$(CONFIG_EL16) += 3c507.o
 obj-$(CONFIG_ELMC) += 3c523.o
@@ -180,6 +179,7 @@ obj-$(CONFIG_AMD8111_ETH) += amd8111e.o
 obj-$(CONFIG_IBMVETH) += ibmveth.o
 obj-$(CONFIG_S2IO) += s2io.o
 obj-$(CONFIG_SMC91X) += smc91x.o
+obj-$(CONFIG_DM9000) += dm9000.o
 obj-$(CONFIG_FEC_8XX) += fec_8xx/
 
 obj-$(CONFIG_ARM) += arm/
diff --git a/drivers/net/Space.c b/drivers/net/Space.c
--- a/drivers/net/Space.c
+++ b/drivers/net/Space.c
@@ -210,9 +210,6 @@ static struct devprobe2 isa_probes[] __i
 #ifdef CONFIG_AT1700
 	{at1700_probe, 0},
 #endif
-#ifdef CONFIG_FMV18X		/* Fujitsu FMV-181/182 */
-	{fmv18x_probe, 0},
-#endif
 #ifdef CONFIG_ETH16I
 	{eth16i_probe, 0},	/* ICL EtherTeam 16i/32 */
 #endif
@@ -243,9 +240,6 @@ static struct devprobe2 isa_probes[] __i
 #ifdef CONFIG_ELPLUS		/* 3c505 */
 	{elplus_probe, 0},
 #endif
-#ifdef CONFIG_SK_G16
-	{SK_init, 0},
-#endif
 #ifdef CONFIG_NI5010
 	{ni5010_probe, 0},
 #endif
diff --git a/drivers/net/ac3200.c b/drivers/net/ac3200.c
--- a/drivers/net/ac3200.c
+++ b/drivers/net/ac3200.c
@@ -146,12 +146,7 @@ struct net_device * __init ac3200_probe(
 	err = do_ac3200_probe(dev);
 	if (err)
 		goto out;
-	err = register_netdev(dev);
-	if (err)
-		goto out1;
 	return dev;
-out1:
-	cleanup_card(dev);
 out:
 	free_netdev(dev);
 	return ERR_PTR(err);
@@ -273,7 +268,14 @@ static int __init ac_probe1(int ioaddr, 
 	dev->poll_controller = ei_poll;
 #endif
 	NS8390_init(dev, 0);
+
+	retval = register_netdev(dev);
+	if (retval)
+		goto out2;
 	return 0;
+out2:
+	if (ei_status.reg0)
+		iounmap((void *)dev->mem_start);
 out1:
 	free_irq(dev->irq, dev);
 out:
@@ -392,11 +394,8 @@ init_module(void)
 		dev->base_addr = io[this_dev];
 		dev->mem_start = mem[this_dev];		/* Currently ignored by driver */
 		if (do_ac3200_probe(dev) == 0) {
-			if (register_netdev(dev) == 0) {
-				dev_ac32[found++] = dev;
-				continue;
-			}
-			cleanup_card(dev);
+			dev_ac32[found++] = dev;
+			continue;
 		}
 		free_netdev(dev);
 		printk(KERN_WARNING "ac3200.c: No ac3200 card found (i/o = 0x%x).\n", io[this_dev]);
diff --git a/drivers/net/acenic.c b/drivers/net/acenic.c
--- a/drivers/net/acenic.c
+++ b/drivers/net/acenic.c
@@ -58,6 +58,7 @@
 #include <linux/errno.h>
 #include <linux/ioport.h>
 #include <linux/pci.h>
+#include <linux/dma-mapping.h>
 #include <linux/kernel.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
@@ -1167,9 +1168,9 @@ static int __devinit ace_init(struct net
 	/*
 	 * Configure DMA attributes.
 	 */
-	if (!pci_set_dma_mask(pdev, 0xffffffffffffffffULL)) {
+	if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
 		ap->pci_using_dac = 1;
-	} else if (!pci_set_dma_mask(pdev, 0xffffffffULL)) {
+	} else if (!pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
 		ap->pci_using_dac = 0;
 	} else {
 		ecode = -ENODEV;
diff --git a/drivers/net/amd8111e.c b/drivers/net/amd8111e.c
--- a/drivers/net/amd8111e.c
+++ b/drivers/net/amd8111e.c
@@ -87,6 +87,7 @@ Revision History:
 #include <linux/if_vlan.h>
 #include <linux/ctype.h>	
 #include <linux/crc32.h>
+#include <linux/dma-mapping.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
@@ -1289,7 +1290,7 @@ static irqreturn_t amd8111e_interrupt(in
 	writel(intr0, mmio + INT0);
 
 	/* Check if Receive Interrupt has occurred. */
-#if CONFIG_AMD8111E_NAPI
+#ifdef CONFIG_AMD8111E_NAPI
 	if(intr0 & RINT0){
 		if(netif_rx_schedule_prep(dev)){
 			/* Disable receive interupts */
@@ -2006,12 +2007,11 @@ static int __devinit amd8111e_probe_one(
 	}
 
 	/* Initialize DMA */
-	if(!pci_dma_supported(pdev, 0xffffffff)){
+	if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) < 0) {
 		printk(KERN_ERR "amd8111e: DMA not supported,"
 			"exiting.\n");
-		goto  err_free_reg;
-	} else
-		pdev->dma_mask = 0xffffffff;
+		goto err_free_reg;
+	}
 	
 	reg_addr = pci_resource_start(pdev, 0);
 	reg_len = pci_resource_len(pdev, 0);
diff --git a/drivers/net/appletalk/Kconfig b/drivers/net/appletalk/Kconfig
--- a/drivers/net/appletalk/Kconfig
+++ b/drivers/net/appletalk/Kconfig
@@ -1,6 +1,33 @@
 #
 # Appletalk driver configuration
 #
+config ATALK
+	tristate "Appletalk protocol support"
+	select LLC
+	---help---
+	  AppleTalk is the protocol that Apple computers can use to communicate
+	  on a network.  If your Linux box is connected to such a network and you
+	  wish to connect to it, say Y.  You will need to use the netatalk package
+	  so that your Linux box can act as a print and file server for Macs as
+	  well as access AppleTalk printers.  Check out
+	  <http://www.zettabyte.net/netatalk/> on the WWW for details.
+	  EtherTalk is the name used for AppleTalk over Ethernet and the
+	  cheaper and slower LocalTalk is AppleTalk over a proprietary Apple
+	  network using serial links.  EtherTalk and LocalTalk are fully
+	  supported by Linux.
+
+	  General information about how to connect Linux, Windows machines and
+	  Macs is on the WWW at <http://www.eats.com/linux_mac_win.html>.  The
+	  NET-3-HOWTO, available from
+	  <http://www.tldp.org/docs.html#howto>, contains valuable
+	  information as well.
+
+	  To compile this driver as a module, choose M here: the module will be
+	  called appletalk. You almost certainly want to compile it as a
+	  module so you can restart your AppleTalk stack without rebooting
+	  your machine. I hear that the GNU boycott of Apple is over, so
+	  even politically correct people are allowed to say Y here.
+
 config DEV_APPLETALK
 	bool "Appletalk interfaces support"
 	depends on ATALK
diff --git a/drivers/net/appletalk/ltpc.c b/drivers/net/appletalk/ltpc.c
--- a/drivers/net/appletalk/ltpc.c
+++ b/drivers/net/appletalk/ltpc.c
@@ -1109,8 +1109,7 @@ struct net_device * __init ltpc_probe(vo
 	inb_p(io+1);
 	inb_p(io+3);
 
-	set_current_state(TASK_UNINTERRUPTIBLE);
-	schedule_timeout(2*HZ/100);
+	msleep(20);
 
 	inb_p(io+0);
 	inb_p(io+2);
@@ -1120,8 +1119,7 @@ struct net_device * __init ltpc_probe(vo
 	inb_p(io+5); /* enable dma */
 	inb_p(io+6); /* tri-state interrupt line */
 
-	set_current_state(TASK_UNINTERRUPTIBLE);
-	schedule_timeout(HZ);
+	ssleep(1);
 	
 	/* now, figure out which dma channel we're using, unless it's
 	   already been specified */
diff --git a/drivers/net/at1700.c b/drivers/net/at1700.c
--- a/drivers/net/at1700.c
+++ b/drivers/net/at1700.c
@@ -34,10 +34,6 @@
 	only is it difficult to detect, it also moves around in I/O space in
 	response to inb()s from other device probes!
 */
-/*
-	99/03/03  Allied Telesis RE1000 Plus support by T.Hagawa
-	99/12/30	port to 2.3.35 by K.Takai
-*/
 
 #include <linux/config.h>
 #include <linux/errno.h>
diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c
--- a/drivers/net/au1000_eth.c
+++ b/drivers/net/au1000_eth.c
@@ -1681,10 +1681,6 @@ static int au1000_init(struct net_device
 		control |= MAC_FULL_DUPLEX;
 	}
 
-	/* fix for startup without cable */
-	if (!link) 
-		dev->flags &= ~IFF_RUNNING;
-
 	aup->mac->control = control;
 	aup->mac->vlan1_tag = 0x8100; /* activate vlan support */
 	au_sync();
@@ -1709,16 +1705,14 @@ static void au1000_timer(unsigned long d
 	if_port = dev->if_port;
 	if (aup->phy_ops->phy_status(dev, aup->phy_addr, &link, &speed) == 0) {
 		if (link) {
-			if (!(dev->flags & IFF_RUNNING)) {
+			if (!netif_carrier_ok(dev)) {
 				netif_carrier_on(dev);
-				dev->flags |= IFF_RUNNING;
 				printk(KERN_INFO "%s: link up\n", dev->name);
 			}
 		}
 		else {
-			if (dev->flags & IFF_RUNNING) {
+			if (netif_carrier_ok(dev)) {
 				netif_carrier_off(dev);
-				dev->flags &= ~IFF_RUNNING;
 				dev->if_port = 0;
 				printk(KERN_INFO "%s: link down\n", dev->name);
 			}
diff --git a/drivers/net/b44.c b/drivers/net/b44.c
--- a/drivers/net/b44.c
+++ b/drivers/net/b44.c
@@ -1285,6 +1285,9 @@ static int b44_open(struct net_device *d
 	b44_init_hw(bp);
 	bp->flags |= B44_FLAG_INIT_COMPLETE;
 
+	netif_carrier_off(dev);
+	b44_check_phy(bp);
+
 	spin_unlock_irq(&bp->lock);
 
 	init_timer(&bp->timer);
@@ -1927,6 +1930,7 @@ static int b44_suspend(struct pci_dev *p
 	b44_free_rings(bp);
 
 	spin_unlock_irq(&bp->lock);
+	pci_disable_device(pdev);
 	return 0;
 }
 
@@ -1936,6 +1940,8 @@ static int b44_resume(struct pci_dev *pd
 	struct b44 *bp = netdev_priv(dev);
 
 	pci_restore_state(pdev);
+	pci_enable_device(pdev);
+	pci_set_master(pdev);
 
 	if (!netif_running(dev))
 		return 0;
diff --git a/drivers/net/bmac.c b/drivers/net/bmac.c
--- a/drivers/net/bmac.c
+++ b/drivers/net/bmac.c
@@ -1261,7 +1261,7 @@ static void bmac_reset_and_enable(struct
 	spin_unlock_irqrestore(&bp->lock, flags);
 }
 
-static int __devinit bmac_probe(struct macio_dev *mdev, const struct of_match *match)
+static int __devinit bmac_probe(struct macio_dev *mdev, const struct of_device_id *match)
 {
 	int j, rev, ret;
 	struct bmac_data *bp;
@@ -1412,7 +1412,6 @@ static int bmac_open(struct net_device *
 	bp->opened = 1;
 	bmac_reset_and_enable(dev);
 	enable_irq(dev->irq);
-	dev->flags |= IFF_RUNNING;
 	return 0;
 }
 
@@ -1425,7 +1424,6 @@ static int bmac_close(struct net_device 
 	int i;
 
 	bp->sleeping = 1;
-	dev->flags &= ~(IFF_UP | IFF_RUNNING);
 
 	/* disable rx and tx */
 	config = bmread(dev, RXCFG);
@@ -1647,16 +1645,13 @@ static int __devexit bmac_remove(struct 
 	return 0;
 }
 
-static struct of_match bmac_match[] = 
+static struct of_device_id bmac_match[] = 
 {
 	{
 	.name 		= "bmac",
-	.type		= OF_ANY_MATCH,
-	.compatible	= OF_ANY_MATCH,
 	.data		= (void *)0,
 	},
 	{
-	.name 		= OF_ANY_MATCH,
 	.type		= "network",
 	.compatible	= "bmac+",
 	.data		= (void *)1,
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
--- a/drivers/net/bonding/bond_3ad.c
+++ b/drivers/net/bonding/bond_3ad.c
@@ -2346,7 +2346,6 @@ int bond_3ad_xmit_xor(struct sk_buff *sk
 {
 	struct slave *slave, *start_at;
 	struct bonding *bond = dev->priv;
-	struct ethhdr *data = (struct ethhdr *)skb->data;
 	int slave_agg_no;
 	int slaves_in_agg;
 	int agg_id;
@@ -2377,7 +2376,7 @@ int bond_3ad_xmit_xor(struct sk_buff *sk
 		goto out;
 	}
 
-	slave_agg_no = (data->h_dest[5]^bond->dev->dev_addr[5]) % slaves_in_agg;
+	slave_agg_no = bond->xmit_hash_policy(skb, dev, slaves_in_agg);
 
 	bond_for_each_slave(bond, slave, i) {
 		struct aggregator *agg = SLAVE_AD_INFO(slave).port.aggregator;
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -475,7 +475,18 @@
  *        Solution is to move call to dev_remove_pack outside of the
  *        spinlock.
  *        Set version to 2.6.1.
- *
+ * 2005/06/05 - Jay Vosburgh <fubar@us.ibm.com>
+ * 	- Support for generating gratuitous ARPs in active-backup mode.
+ * 	  Includes support for VLAN tagging all bonding-generated ARPs
+ * 	  as needed.  Set version to 2.6.2.
+ * 2005/06/08 - Jason Gabler <jygabler at lbl dot gov>
+ *	- alternate hashing policy support for mode 2
+ *	  * Added kernel parameter "xmit_hash_policy" to allow the selection
+ *	    of different hashing policies for mode 2.  The original mode 2
+ *	    policy is the default, now found in xmit_hash_policy_layer2().
+ *	  * Added xmit_hash_policy_layer34()
+ *	- Modified by Jay Vosburgh <fubar@us.ibm.com> to also support mode 4.
+ *	  Set version to 2.6.3.
  */
 
 //#define BONDING_DEBUG 1
@@ -490,7 +501,10 @@
 #include <linux/ptrace.h>
 #include <linux/ioport.h>
 #include <linux/in.h>
+#include <net/ip.h>
 #include <linux/ip.h>
+#include <linux/tcp.h>
+#include <linux/udp.h>
 #include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/init.h>
@@ -519,6 +533,7 @@
 #include <linux/ethtool.h>
 #include <linux/if_vlan.h>
 #include <linux/if_bonding.h>
+#include <net/route.h>
 #include "bonding.h"
 #include "bond_3ad.h"
 #include "bond_alb.h"
@@ -537,6 +552,7 @@ static int use_carrier	= 1;
 static char *mode	= NULL;
 static char *primary	= NULL;
 static char *lacp_rate	= NULL;
+static char *xmit_hash_policy = NULL;
 static int arp_interval = BOND_LINK_ARP_INTERV;
 static char *arp_ip_target[BOND_MAX_ARP_TARGETS] = { NULL, };
 
@@ -556,6 +572,8 @@ module_param(primary, charp, 0);
 MODULE_PARM_DESC(primary, "Primary network device to use");
 module_param(lacp_rate, charp, 0);
 MODULE_PARM_DESC(lacp_rate, "LACPDU tx rate to request from 802.3ad partner (slow/fast)");
+module_param(xmit_hash_policy, charp, 0);
+MODULE_PARM_DESC(xmit_hash_policy, "XOR hashing method : 0 for layer 2 (default), 1 for layer 3+4");
 module_param(arp_interval, int, 0);
 MODULE_PARM_DESC(arp_interval, "arp interval in milliseconds");
 module_param_array(arp_ip_target, charp, NULL, 0);
@@ -574,8 +592,8 @@ static struct proc_dir_entry *bond_proc_
 
 static u32 arp_target[BOND_MAX_ARP_TARGETS] = { 0, } ;
 static int arp_ip_count	= 0;
-static u32 my_ip	= 0;
 static int bond_mode	= BOND_MODE_ROUNDROBIN;
+static int xmit_hashtype= BOND_XMIT_POLICY_LAYER2;
 static int lacp_fast	= 0;
 static int app_abi_ver	= 0;
 static int orig_app_abi_ver = -1; /* This is used to save the first ABI version
@@ -585,7 +603,6 @@ static int orig_app_abi_ver = -1; /* Thi
 				   * command comes from an application using
 				   * another ABI version.
 				   */
-
 struct bond_parm_tbl {
 	char *modename;
 	int mode;
@@ -608,9 +625,16 @@ static struct bond_parm_tbl bond_mode_tb
 {	NULL,			-1},
 };
 
+static struct bond_parm_tbl xmit_hashtype_tbl[] = {
+{	"layer2",		BOND_XMIT_POLICY_LAYER2},
+{	"layer3+4",		BOND_XMIT_POLICY_LAYER34},
+{	NULL,			-1},
+};
+
 /*-------------------------- Forward declarations ---------------------------*/
 
-static inline void bond_set_mode_ops(struct net_device *bond_dev, int mode);
+static inline void bond_set_mode_ops(struct bonding *bond, int mode);
+static void bond_send_gratuitous_arp(struct bonding *bond);
 
 /*---------------------------- General routines -----------------------------*/
 
@@ -659,6 +683,7 @@ static int bond_add_vlan(struct bonding 
 
 	INIT_LIST_HEAD(&vlan->vlan_list);
 	vlan->vlan_id = vlan_id;
+	vlan->vlan_ip = 0;
 
 	write_lock_bh(&bond->lock);
 
@@ -1468,16 +1493,6 @@ static void bond_change_active_slave(str
 		}
 	}
 
-	if (bond->params.mode == BOND_MODE_ACTIVEBACKUP) {
-		if (old_active) {
-			bond_set_slave_inactive_flags(old_active);
-		}
-
-		if (new_active) {
-			bond_set_slave_active_flags(new_active);
-		}
-	}
-
 	if (USES_PRIMARY(bond->params.mode)) {
 		bond_mc_swap(bond, new_active, old_active);
 	}
@@ -1488,6 +1503,17 @@ static void bond_change_active_slave(str
 	} else {
 		bond->curr_active_slave = new_active;
 	}
+
+	if (bond->params.mode == BOND_MODE_ACTIVEBACKUP) {
+		if (old_active) {
+			bond_set_slave_inactive_flags(old_active);
+		}
+
+		if (new_active) {
+			bond_set_slave_active_flags(new_active);
+		}
+		bond_send_gratuitous_arp(bond);
+	}
 }
 
 /**
@@ -2694,15 +2720,180 @@ out:
 	read_unlock(&bond->lock);
 }
 
+
+static u32 bond_glean_dev_ip(struct net_device *dev)
+{
+	struct in_device *idev;
+	struct in_ifaddr *ifa;
+	u32 addr = 0;
+
+	if (!dev)
+		return 0;
+
+	rcu_read_lock();
+	idev = __in_dev_get(dev);
+	if (!idev)
+		goto out;
+
+	ifa = idev->ifa_list;
+	if (!ifa)
+		goto out;
+
+	addr = ifa->ifa_local;
+out:
+	rcu_read_unlock();
+	return addr;
+}
+
+static int bond_has_ip(struct bonding *bond)
+{
+	struct vlan_entry *vlan, *vlan_next;
+
+	if (bond->master_ip)
+		return 1;
+
+	if (list_empty(&bond->vlan_list))
+		return 0;
+
+	list_for_each_entry_safe(vlan, vlan_next, &bond->vlan_list,
+				 vlan_list) {
+		if (vlan->vlan_ip)
+			return 1;
+	}
+
+	return 0;
+}
+
+/*
+ * We go to the (large) trouble of VLAN tagging ARP frames because
+ * switches in VLAN mode (especially if ports are configured as
+ * "native" to a VLAN) might not pass non-tagged frames.
+ */
+static void bond_arp_send(struct net_device *slave_dev, int arp_op, u32 dest_ip, u32 src_ip, unsigned short vlan_id)
+{
+	struct sk_buff *skb;
+
+	dprintk("arp %d on slave %s: dst %x src %x vid %d\n", arp_op,
+	       slave_dev->name, dest_ip, src_ip, vlan_id);
+	       
+	skb = arp_create(arp_op, ETH_P_ARP, dest_ip, slave_dev, src_ip,
+			 NULL, slave_dev->dev_addr, NULL);
+
+	if (!skb) {
+		printk(KERN_ERR DRV_NAME ": ARP packet allocation failed\n");
+		return;
+	}
+	if (vlan_id) {
+		skb = vlan_put_tag(skb, vlan_id);
+		if (!skb) {
+			printk(KERN_ERR DRV_NAME ": failed to insert VLAN tag\n");
+			return;
+		}
+	}
+	arp_xmit(skb);
+}
+
+
 static void bond_arp_send_all(struct bonding *bond, struct slave *slave)
 {
-	int i;
+	int i, vlan_id, rv;
 	u32 *targets = bond->params.arp_targets;
+	struct vlan_entry *vlan, *vlan_next;
+	struct net_device *vlan_dev;
+	struct flowi fl;
+	struct rtable *rt;
 
 	for (i = 0; (i < BOND_MAX_ARP_TARGETS) && targets[i]; i++) {
-		arp_send(ARPOP_REQUEST, ETH_P_ARP, targets[i], slave->dev,
-			 my_ip, NULL, slave->dev->dev_addr,
-			 NULL);
+		dprintk("basa: target %x\n", targets[i]);
+		if (list_empty(&bond->vlan_list)) {
+			dprintk("basa: empty vlan: arp_send\n");
+			bond_arp_send(slave->dev, ARPOP_REQUEST, targets[i],
+				      bond->master_ip, 0);
+			continue;
+		}
+
+		/*
+		 * If VLANs are configured, we do a route lookup to
+		 * determine which VLAN interface would be used, so we
+		 * can tag the ARP with the proper VLAN tag.
+		 */
+		memset(&fl, 0, sizeof(fl));
+		fl.fl4_dst = targets[i];
+		fl.fl4_tos = RTO_ONLINK;
+
+		rv = ip_route_output_key(&rt, &fl);
+		if (rv) {
+			if (net_ratelimit()) {
+				printk(KERN_WARNING DRV_NAME
+			     ": %s: no route to arp_ip_target %u.%u.%u.%u\n",
+				       bond->dev->name, NIPQUAD(fl.fl4_dst));
+			}
+			continue;
+		}
+
+		/*
+		 * This target is not on a VLAN
+		 */
+		if (rt->u.dst.dev == bond->dev) {
+			dprintk("basa: rtdev == bond->dev: arp_send\n");
+			bond_arp_send(slave->dev, ARPOP_REQUEST, targets[i],
+				      bond->master_ip, 0);
+			continue;
+		}
+
+		vlan_id = 0;
+		list_for_each_entry_safe(vlan, vlan_next, &bond->vlan_list,
+					 vlan_list) {
+			vlan_dev = bond->vlgrp->vlan_devices[vlan->vlan_id];
+			if (vlan_dev == rt->u.dst.dev) {
+				vlan_id = vlan->vlan_id;
+				dprintk("basa: vlan match on %s %d\n",
+				       vlan_dev->name, vlan_id);
+				break;
+			}
+		}
+
+		if (vlan_id) {
+			bond_arp_send(slave->dev, ARPOP_REQUEST, targets[i],
+				      vlan->vlan_ip, vlan_id);
+			continue;
+		}
+
+		if (net_ratelimit()) {
+			printk(KERN_WARNING DRV_NAME
+	       ": %s: no path to arp_ip_target %u.%u.%u.%u via rt.dev %s\n",
+			       bond->dev->name, NIPQUAD(fl.fl4_dst),
+			       rt->u.dst.dev ? rt->u.dst.dev->name : "NULL");
+		}
+	}
+}
+
+/*
+ * Kick out a gratuitous ARP for an IP on the bonding master plus one
+ * for each VLAN above us.
+ */
+static void bond_send_gratuitous_arp(struct bonding *bond)
+{
+	struct slave *slave = bond->curr_active_slave;
+	struct vlan_entry *vlan;
+	struct net_device *vlan_dev;
+
+	dprintk("bond_send_grat_arp: bond %s slave %s\n", bond->dev->name,
+				slave ? slave->dev->name : "NULL");
+	if (!slave)
+		return;
+
+	if (bond->master_ip) {
+		bond_arp_send(slave->dev, ARPOP_REPLY, bond->master_ip,
+				  bond->master_ip, 0);
+	}
+
+	list_for_each_entry(vlan, &bond->vlan_list, vlan_list) {
+		vlan_dev = bond->vlgrp->vlan_devices[vlan->vlan_id];
+		if (vlan->vlan_ip) {
+			bond_arp_send(slave->dev, ARPOP_REPLY, vlan->vlan_ip,
+				      vlan->vlan_ip, vlan->vlan_id);
+		}
 	}
 }
 
@@ -2781,7 +2972,7 @@ static void bond_loadbalance_arp_mon(str
 			 */
 			if (((jiffies - slave->dev->trans_start) >= (2*delta_in_ticks)) ||
 			    (((jiffies - slave->dev->last_rx) >= (2*delta_in_ticks)) &&
-			     my_ip)) {
+			     bond_has_ip(bond))) {
 
 				slave->link  = BOND_LINK_DOWN;
 				slave->state = BOND_STATE_BACKUP;
@@ -2920,7 +3111,7 @@ static void bond_activebackup_arp_mon(st
 			if ((slave != bond->curr_active_slave) &&
 			    (!bond->current_arp_slave) &&
 			    (((jiffies - slave->dev->last_rx) >= 3*delta_in_ticks) &&
-			     my_ip)) {
+			     bond_has_ip(bond))) {
 				/* a backup slave has gone down; three times
 				 * the delta allows the current slave to be
 				 * taken out before the backup slave.
@@ -2966,8 +3157,8 @@ static void bond_activebackup_arp_mon(st
 		 * if it is up and needs to take over as the curr_active_slave
 		 */
 		if ((((jiffies - slave->dev->trans_start) >= (2*delta_in_ticks)) ||
-		     (((jiffies - slave->dev->last_rx) >= (2*delta_in_ticks)) &&
-		      my_ip)) &&
+	    (((jiffies - slave->dev->last_rx) >= (2*delta_in_ticks)) &&
+	     bond_has_ip(bond))) &&
 		    ((jiffies - slave->jiffies) >= 2*delta_in_ticks)) {
 
 			slave->link  = BOND_LINK_DOWN;
@@ -3019,7 +3210,7 @@ static void bond_activebackup_arp_mon(st
 		/* the current slave must tx an arp to ensure backup slaves
 		 * rx traffic
 		 */
-		if (slave && my_ip) {
+		if (slave && bond_has_ip(bond)) {
 			bond_arp_send_all(bond, slave);
 		}
 	}
@@ -3471,10 +3662,67 @@ static int bond_netdev_event(struct noti
 	return NOTIFY_DONE;
 }
 
+/*
+ * bond_inetaddr_event: handle inetaddr notifier chain events.
+ *
+ * We keep track of device IPs primarily to use as source addresses in
+ * ARP monitor probes (rather than spewing out broadcasts all the time).
+ *
+ * We track one IP for the main device (if it has one), plus one per VLAN.
+ */
+static int bond_inetaddr_event(struct notifier_block *this, unsigned long event, void *ptr)
+{
+	struct in_ifaddr *ifa = ptr;
+	struct net_device *vlan_dev, *event_dev = ifa->ifa_dev->dev;
+	struct bonding *bond, *bond_next;
+	struct vlan_entry *vlan, *vlan_next;
+
+	list_for_each_entry_safe(bond, bond_next, &bond_dev_list, bond_list) {
+		if (bond->dev == event_dev) {
+			switch (event) {
+			case NETDEV_UP:
+				bond->master_ip = ifa->ifa_local;
+				return NOTIFY_OK;
+			case NETDEV_DOWN:
+				bond->master_ip = bond_glean_dev_ip(bond->dev);
+				return NOTIFY_OK;
+			default:
+				return NOTIFY_DONE;
+			}
+		}
+
+		if (list_empty(&bond->vlan_list))
+			continue;
+
+		list_for_each_entry_safe(vlan, vlan_next, &bond->vlan_list,
+					 vlan_list) {
+			vlan_dev = bond->vlgrp->vlan_devices[vlan->vlan_id];
+			if (vlan_dev == event_dev) {
+				switch (event) {
+				case NETDEV_UP:
+					vlan->vlan_ip = ifa->ifa_local;
+					return NOTIFY_OK;
+				case NETDEV_DOWN:
+					vlan->vlan_ip =
+						bond_glean_dev_ip(vlan_dev);
+					return NOTIFY_OK;
+				default:
+					return NOTIFY_DONE;
+				}
+			}
+		}
+	}
+	return NOTIFY_DONE;
+}
+
 static struct notifier_block bond_netdev_notifier = {
 	.notifier_call = bond_netdev_event,
 };
 
+static struct notifier_block bond_inetaddr_notifier = {
+	.notifier_call = bond_inetaddr_event,
+};
+
 /*-------------------------- Packet type handling ---------------------------*/
 
 /* register to receive lacpdus on a bond */
@@ -3496,6 +3744,46 @@ static void bond_unregister_lacpdu(struc
 	dev_remove_pack(&(BOND_AD_INFO(bond).ad_pkt_type));
 }
 
+/*---------------------------- Hashing Policies -----------------------------*/
+
+/*
+ * Hash for the the output device based upon layer 3 and layer 4 data. If
+ * the packet is a frag or not TCP or UDP, just use layer 3 data.  If it is
+ * altogether not IP, mimic bond_xmit_hash_policy_l2()
+ */
+static int bond_xmit_hash_policy_l34(struct sk_buff *skb,
+				    struct net_device *bond_dev, int count)
+{
+	struct ethhdr *data = (struct ethhdr *)skb->data;
+	struct iphdr *iph = skb->nh.iph;
+	u16 *layer4hdr = (u16 *)((u32 *)iph + iph->ihl);
+	int layer4_xor = 0;
+
+	if (skb->protocol == __constant_htons(ETH_P_IP)) {
+		if (!(iph->frag_off & __constant_htons(IP_MF|IP_OFFSET)) &&
+		    (iph->protocol == IPPROTO_TCP ||
+		     iph->protocol == IPPROTO_UDP)) {
+			layer4_xor = htons((*layer4hdr ^ *(layer4hdr + 1)));
+		}
+		return (layer4_xor ^
+			((ntohl(iph->saddr ^ iph->daddr)) & 0xffff)) % count;
+
+	}
+
+	return (data->h_dest[5] ^ bond_dev->dev_addr[5]) % count;
+}
+
+/*
+ * Hash for the output device based upon layer 2 data
+ */
+static int bond_xmit_hash_policy_l2(struct sk_buff *skb,
+				   struct net_device *bond_dev, int count)
+{
+	struct ethhdr *data = (struct ethhdr *)skb->data;
+
+	return (data->h_dest[5] ^ bond_dev->dev_addr[5]) % count;
+}
+
 /*-------------------------- Device entry points ----------------------------*/
 
 static int bond_open(struct net_device *bond_dev)
@@ -4060,17 +4348,6 @@ static int bond_xmit_activebackup(struct
 	struct bonding *bond = bond_dev->priv;
 	int res = 1;
 
-	/* if we are sending arp packets, try to at least
-	   identify our own ip address */
-	if (bond->params.arp_interval && !my_ip &&
-		(skb->protocol == __constant_htons(ETH_P_ARP))) {
-		char *the_ip = (char *)skb->data +
-				sizeof(struct ethhdr) +
-				sizeof(struct arphdr) +
-				ETH_ALEN;
-		memcpy(&my_ip, the_ip, 4);
-	}
-
 	read_lock(&bond->lock);
 	read_lock(&bond->curr_slave_lock);
 
@@ -4093,14 +4370,13 @@ out:
 }
 
 /*
- * in XOR mode, we determine the output device by performing xor on
- * the source and destination hw adresses.  If this device is not
- * enabled, find the next slave following this xor slave.
+ * In bond_xmit_xor() , we determine the output device by using a pre-
+ * determined xmit_hash_policy(), If the selected device is not enabled,
+ * find the next active slave.
  */
 static int bond_xmit_xor(struct sk_buff *skb, struct net_device *bond_dev)
 {
 	struct bonding *bond = bond_dev->priv;
-	struct ethhdr *data = (struct ethhdr *)skb->data;
 	struct slave *slave, *start_at;
 	int slave_no;
 	int i;
@@ -4112,7 +4388,7 @@ static int bond_xmit_xor(struct sk_buff 
 		goto out;
 	}
 
-	slave_no = (data->h_dest[5]^bond_dev->dev_addr[5]) % bond->slave_cnt;
+	slave_no = bond->xmit_hash_policy(skb, bond_dev, bond->slave_cnt);
 
 	bond_for_each_slave(bond, slave, i) {
 		slave_no--;
@@ -4208,8 +4484,10 @@ out:
 /*
  * set bond mode specific net device operations
  */
-static inline void bond_set_mode_ops(struct net_device *bond_dev, int mode)
+static inline void bond_set_mode_ops(struct bonding *bond, int mode)
 {
+	struct net_device *bond_dev = bond->dev;
+
 	switch (mode) {
 	case BOND_MODE_ROUNDROBIN:
 		bond_dev->hard_start_xmit = bond_xmit_roundrobin;
@@ -4219,12 +4497,20 @@ static inline void bond_set_mode_ops(str
 		break;
 	case BOND_MODE_XOR:
 		bond_dev->hard_start_xmit = bond_xmit_xor;
+		if (bond->params.xmit_policy == BOND_XMIT_POLICY_LAYER34)
+			bond->xmit_hash_policy = bond_xmit_hash_policy_l34;
+		else
+			bond->xmit_hash_policy = bond_xmit_hash_policy_l2;
 		break;
 	case BOND_MODE_BROADCAST:
 		bond_dev->hard_start_xmit = bond_xmit_broadcast;
 		break;
 	case BOND_MODE_8023AD:
 		bond_dev->hard_start_xmit = bond_3ad_xmit_xor;
+		if (bond->params.xmit_policy == BOND_XMIT_POLICY_LAYER34)
+			bond->xmit_hash_policy = bond_xmit_hash_policy_l34;
+		else
+			bond->xmit_hash_policy = bond_xmit_hash_policy_l2;
 		break;
 	case BOND_MODE_TLB:
 	case BOND_MODE_ALB:
@@ -4273,7 +4559,7 @@ static int __init bond_init(struct net_d
 	bond_dev->change_mtu = bond_change_mtu;
 	bond_dev->set_mac_address = bond_set_mac_address;
 
-	bond_set_mode_ops(bond_dev, bond->params.mode);
+	bond_set_mode_ops(bond, bond->params.mode);
 
 	bond_dev->destructor = free_netdev;
 
@@ -4384,6 +4670,25 @@ static int bond_check_params(struct bond
 		}
 	}
 
+	if (xmit_hash_policy) {
+		if ((bond_mode != BOND_MODE_XOR) &&
+		    (bond_mode != BOND_MODE_8023AD)) {
+			printk(KERN_INFO DRV_NAME
+			       ": xor_mode param is irrelevant in mode %s\n",
+			       bond_mode_name(bond_mode));
+		} else {
+			xmit_hashtype = bond_parse_parm(xmit_hash_policy,
+							xmit_hashtype_tbl);
+			if (xmit_hashtype == -1) {
+				printk(KERN_ERR DRV_NAME
+			       	": Error: Invalid xmit_hash_policy \"%s\"\n",
+			       	xmit_hash_policy == NULL ? "NULL" :
+				       xmit_hash_policy);
+				return -EINVAL;
+			}
+		}
+	}
+
 	if (lacp_rate) {
 		if (bond_mode != BOND_MODE_8023AD) {
 			printk(KERN_INFO DRV_NAME
@@ -4595,6 +4900,7 @@ static int bond_check_params(struct bond
 
 	/* fill params struct with the proper values */
 	params->mode = bond_mode;
+	params->xmit_policy = xmit_hashtype;
 	params->miimon = miimon;
 	params->arp_interval = arp_interval;
 	params->updelay = updelay;
@@ -4669,6 +4975,7 @@ static int __init bonding_init(void)
 
 	rtnl_unlock();
 	register_netdevice_notifier(&bond_netdev_notifier);
+	register_inetaddr_notifier(&bond_inetaddr_notifier);
 
 	return 0;
 
@@ -4684,6 +4991,7 @@ out_err:
 static void __exit bonding_exit(void)
 {
 	unregister_netdevice_notifier(&bond_netdev_notifier);
+	unregister_inetaddr_notifier(&bond_inetaddr_notifier);
 
 	rtnl_lock();
 	bond_free_all();
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -25,6 +25,10 @@
  *
  * 2003/12/01 - Shmulik Hen <shmulik.hen at intel dot com>
  *	- Code cleanup and style changes
+ *
+ * 2005/05/05 - Jason Gabler <jygabler at lbl dot gov>
+ *      - added "xmit_policy" kernel parameter for alternate hashing policy
+ *	  support for mode 2
  */
 
 #ifndef _LINUX_BONDING_H
@@ -36,8 +40,8 @@
 #include "bond_3ad.h"
 #include "bond_alb.h"
 
-#define DRV_VERSION	"2.6.1"
-#define DRV_RELDATE	"October 29, 2004"
+#define DRV_VERSION	"2.6.3"
+#define DRV_RELDATE	"June 8, 2005"
 #define DRV_NAME	"bonding"
 #define DRV_DESCRIPTION	"Ethernet Channel Bonding Driver"
 
@@ -137,6 +141,7 @@
 
 struct bond_params {
 	int mode;
+	int xmit_policy;
 	int miimon;
 	int arp_interval;
 	int use_carrier;
@@ -149,6 +154,7 @@ struct bond_params {
 
 struct vlan_entry {
 	struct list_head vlan_list;
+	u32 vlan_ip;
 	unsigned short vlan_id;
 };
 
@@ -197,6 +203,8 @@ struct bonding {
 #endif /* CONFIG_PROC_FS */
 	struct   list_head bond_list;
 	struct   dev_mc_list *mc_list;
+	int      (*xmit_hash_policy)(struct sk_buff *, struct net_device *, int);
+	u32      master_ip;
 	u16      flags;
 	struct   ad_bond_info ad_info;
 	struct   alb_bond_info alb_info;
diff --git a/drivers/net/cs89x0.c b/drivers/net/cs89x0.c
--- a/drivers/net/cs89x0.c
+++ b/drivers/net/cs89x0.c
@@ -174,6 +174,13 @@ static unsigned int cs8900_irq_map[] = {
 #include <asm/irq.h>
 static unsigned int netcard_portlist[] __initdata = {IXDP2X01_CS8900_VIRT_BASE, 0};
 static unsigned int cs8900_irq_map[] = {IRQ_IXDP2X01_CS8900, 0, 0, 0};
+#elif defined(CONFIG_ARCH_PNX0105)
+#include <asm/irq.h>
+#include <asm/arch/gpio.h>
+#define CIRRUS_DEFAULT_BASE	IO_ADDRESS(EXT_STATIC2_s0_BASE + 0x200000)	/* = Physical address 0x48200000 */
+#define CIRRUS_DEFAULT_IRQ	VH_INTC_INT_NUM_CASCADED_INTERRUPT_1 /* Event inputs bank 1 - ID 35/bit 3 */
+static unsigned int netcard_portlist[] __initdata = {CIRRUS_DEFAULT_BASE, 0};
+static unsigned int cs8900_irq_map[] = {CIRRUS_DEFAULT_IRQ, 0, 0, 0};
 #else
 static unsigned int netcard_portlist[] __initdata =
    { 0x300, 0x320, 0x340, 0x360, 0x200, 0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x2e0, 0};
@@ -319,13 +326,7 @@ struct net_device * __init cs89x0_probe(
 	}
 	if (err)
 		goto out;
-	err = register_netdev(dev);
-	if (err)
-		goto out1;
 	return dev;
-out1:
-	outw(PP_ChipID, dev->base_addr + ADD_PORT);
-	release_region(dev->base_addr, NETCARD_IO_EXTENT);
 out:
 	free_netdev(dev);
 	printk(KERN_WARNING "cs89x0: no cs8900 or cs8920 detected.  Be sure to disable PnP with SETUP\n");
@@ -416,6 +417,7 @@ cs89x0_probe1(struct net_device *dev, in
 	struct net_local *lp = netdev_priv(dev);
 	static unsigned version_printed;
 	int i;
+	int tmp;
 	unsigned rev_type = 0;
 	int eeprom_buff[CHKSUM_LEN];
 	int retval;
@@ -437,6 +439,30 @@ cs89x0_probe1(struct net_device *dev, in
 #endif
         }
 
+#ifdef CONFIG_ARCH_PNX0105
+	initialize_ebi();
+
+	/* Map GPIO registers for the pins connected to the CS8900a. */
+	if (map_cirrus_gpio() < 0)
+		return -ENODEV;
+
+	reset_cirrus();
+
+	/* Map event-router registers. */
+	if (map_event_router() < 0)
+		return -ENODEV;
+
+	enable_cirrus_irq();
+
+	unmap_cirrus_gpio();
+	unmap_event_router();
+
+	dev->base_addr = ioaddr;
+
+	for (i = 0 ; i < 3 ; i++)
+		readreg(dev, 0);
+#endif
+
 	/* Grab the region so we can find another board if autoIRQ fails. */
 	/* WTF is going on here? */
 	if (!request_region(ioaddr & ~3, NETCARD_IO_EXTENT, DRV_NAME)) {
@@ -467,14 +493,17 @@ cs89x0_probe1(struct net_device *dev, in
 				goto out2;
 			}
 	}
-printk("PP_addr=0x%x\n", inw(ioaddr + ADD_PORT));
+	printk(KERN_DEBUG "PP_addr at %x: 0x%x\n",
+			ioaddr + ADD_PORT, inw(ioaddr + ADD_PORT));
 
 	ioaddr &= ~3;
 	outw(PP_ChipID, ioaddr + ADD_PORT);
 
-	if (inw(ioaddr + DATA_PORT) != CHIP_EISA_ID_SIG) {
-		printk(KERN_ERR "%s: incorrect signature 0x%x\n",
-			dev->name, inw(ioaddr + DATA_PORT));
+	tmp = inw(ioaddr + DATA_PORT);
+	if (tmp != CHIP_EISA_ID_SIG) {
+		printk(KERN_DEBUG "%s: incorrect signature at %x: 0x%x!="
+			CHIP_EISA_ID_SIG_STR "\n",
+			dev->name, ioaddr + DATA_PORT, tmp);
   		retval = -ENODEV;
   		goto out2;
 	}
@@ -678,7 +707,7 @@ printk("PP_addr=0x%x\n", inw(ioaddr + AD
 	} else {
 		i = lp->isa_config & INT_NO_MASK;
 		if (lp->chip_type == CS8900) {
-#ifdef CONFIG_ARCH_IXDP2X01
+#if defined(CONFIG_ARCH_IXDP2X01) || defined(CONFIG_ARCH_PNX0105)
 		        i = cs8900_irq_map[0];
 #else
 			/* Translate the IRQ using the IRQ mapping table. */
@@ -735,7 +764,13 @@ printk("PP_addr=0x%x\n", inw(ioaddr + AD
 	printk("\n");
 	if (net_debug)
 		printk("cs89x0_probe1() successful\n");
+
+	retval = register_netdev(dev);
+	if (retval)
+		goto out3;
 	return 0;
+out3:
+	outw(PP_ChipID, dev->base_addr + ADD_PORT);
 out2:
 	release_region(ioaddr & ~3, NETCARD_IO_EXTENT);
 out1:
@@ -1145,7 +1180,7 @@ net_open(struct net_device *dev)
 	int i;
 	int ret;
 
-#ifndef CONFIG_SH_HICOSH4 /* uses irq#1, so this won't work */
+#if !defined(CONFIG_SH_HICOSH4) && !defined(CONFIG_ARCH_PNX0105) /* uses irq#1, so this won't work */
 	if (dev->irq < 2) {
 		/* Allow interrupts to be generated by the chip */
 /* Cirrus' release had this: */
@@ -1176,7 +1211,7 @@ net_open(struct net_device *dev)
 	else
 #endif
 	{
-#ifndef CONFIG_ARCH_IXDP2X01
+#if !defined(CONFIG_ARCH_IXDP2X01) && !defined(CONFIG_ARCH_PNX0105)
 		if (((1 << dev->irq) & lp->irq_map) == 0) {
 			printk(KERN_ERR "%s: IRQ %d is not in our map of allowable IRQs, which is %x\n",
                                dev->name, dev->irq, lp->irq_map);
@@ -1261,6 +1296,9 @@ net_open(struct net_device *dev)
 	case A_CNF_MEDIA_10B_2: result = lp->adapter_cnf & A_CNF_10B_2; break;
         default: result = lp->adapter_cnf & (A_CNF_10B_T | A_CNF_AUI | A_CNF_10B_2);
         }
+#ifdef CONFIG_ARCH_PNX0105
+	result = A_CNF_10B_T;
+#endif
         if (!result) {
                 printk(KERN_ERR "%s: EEPROM is configured for unavailable media\n", dev->name);
         release_irq:
@@ -1416,6 +1454,7 @@ static int net_send_packet(struct sk_buf
 	/* Write the contents of the packet */
 	outsw(dev->base_addr + TX_FRAME_PORT,skb->data,(skb->len+1) >>1);
 	spin_unlock_irq(&lp->lock);
+	lp->stats.tx_bytes += skb->len;
 	dev->trans_start = jiffies;
 	dev_kfree_skb (skb);
 
@@ -1831,13 +1870,6 @@ init_module(void)
 	if (ret)
 		goto out;
 
-        if (register_netdev(dev) != 0) {
-                printk(KERN_ERR "cs89x0.c: No card found at 0x%x\n", io);
-                ret = -ENXIO;
-		outw(PP_ChipID, dev->base_addr + ADD_PORT);
-		release_region(dev->base_addr, NETCARD_IO_EXTENT);
-		goto out;
-        }
 	dev_cs89x0 = dev;
 	return 0;
 out:
diff --git a/drivers/net/cs89x0.h b/drivers/net/cs89x0.h
--- a/drivers/net/cs89x0.h
+++ b/drivers/net/cs89x0.h
@@ -16,7 +16,7 @@
 
 #include <linux/config.h>
 
-#ifdef CONFIG_ARCH_IXDP2X01
+#if defined(CONFIG_ARCH_IXDP2X01) || defined(CONFIG_ARCH_PNX0105)
 /* IXDP2401/IXDP2801 uses dword-aligned register addressing */
 #define CS89x0_PORT(reg) ((reg) * 2)
 #else
@@ -93,6 +93,7 @@
 #endif
 
 #define CHIP_EISA_ID_SIG 0x630E   /*  Product ID Code for Crystal Chip (CS8900 spec 4.3) */
+#define CHIP_EISA_ID_SIG_STR "0x630E"
 
 #ifdef IBMEIPKT
 #define EISA_ID_SIG 0x4D24	/*  IBM */
diff --git a/drivers/net/defxx.c b/drivers/net/defxx.c
--- a/drivers/net/defxx.c
+++ b/drivers/net/defxx.c
@@ -191,6 +191,7 @@
  *		Feb 2001	davej		PCI enable cleanups.
  *		04 Aug 2003	macro		Converted to the DMA API.
  *		14 Aug 2004	macro		Fix device names reported.
+ *		14 Jun 2005	macro		Use irqreturn_t.
  */
 
 /* Include files */
@@ -217,8 +218,8 @@
 
 /* Version information string should be updated prior to each new release!  */
 #define DRV_NAME "defxx"
-#define DRV_VERSION "v1.07"
-#define DRV_RELDATE "2004/08/14"
+#define DRV_VERSION "v1.08"
+#define DRV_RELDATE "2005/06/14"
 
 static char version[] __devinitdata =
 	DRV_NAME ": " DRV_VERSION " " DRV_RELDATE
@@ -247,7 +248,8 @@ static int		dfx_close(struct net_device 
 static void		dfx_int_pr_halt_id(DFX_board_t *bp);
 static void		dfx_int_type_0_process(DFX_board_t *bp);
 static void		dfx_int_common(struct net_device *dev);
-static void		dfx_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t	dfx_interrupt(int irq, void *dev_id,
+				      struct pt_regs *regs);
 
 static struct		net_device_stats *dfx_ctl_get_stats(struct net_device *dev);
 static void		dfx_ctl_set_multicast_list(struct net_device *dev);
@@ -437,7 +439,8 @@ static int __devinit dfx_init_one_pci_or
 	}
 
 	SET_MODULE_OWNER(dev);
-	SET_NETDEV_DEV(dev, &pdev->dev);
+	if (pdev != NULL)
+		SET_NETDEV_DEV(dev, &pdev->dev);
 
 	bp = dev->priv;
 
@@ -1225,7 +1228,7 @@ static int dfx_open(struct net_device *d
 	
 	/* Register IRQ - support shared interrupts by passing device ptr */
 
-	ret = request_irq(dev->irq, (void *)dfx_interrupt, SA_SHIRQ, dev->name, dev);
+	ret = request_irq(dev->irq, dfx_interrupt, SA_SHIRQ, dev->name, dev);
 	if (ret) {
 		printk(KERN_ERR "%s: Requested IRQ %d is busy\n", dev->name, dev->irq);
 		return ret;
@@ -1680,13 +1683,13 @@ static void dfx_int_common(struct net_de
  * =================
  * = dfx_interrupt =
  * =================
- *   
+ *
  * Overview:
  *   Interrupt processing routine
- *  
+ *
  * Returns:
- *   None
- *       
+ *   Whether a valid interrupt was seen.
+ *
  * Arguments:
  *   irq	- interrupt vector
  *   dev_id	- pointer to device information
@@ -1699,7 +1702,8 @@ static void dfx_int_common(struct net_de
  *   structure context.
  *
  * Return Codes:
- *   None
+ *   IRQ_HANDLED - an IRQ was handled.
+ *   IRQ_NONE    - no IRQ was handled.
  *
  * Assumptions:
  *   The interrupt acknowledgement at the hardware level (eg. ACKing the PIC
@@ -1712,60 +1716,70 @@ static void dfx_int_common(struct net_de
  *   Interrupts are disabled, then reenabled at the adapter.
  */
 
-static void dfx_interrupt(int irq, void *dev_id, struct pt_regs	*regs)
-	{
+static irqreturn_t dfx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
 	struct net_device	*dev = dev_id;
 	DFX_board_t		*bp;	/* private board structure pointer */
-	u8				tmp;	/* used for disabling/enabling ints */
 
 	/* Get board pointer only if device structure is valid */
 
 	bp = dev->priv;
 
-	spin_lock(&bp->lock);
-	
 	/* See if we're already servicing an interrupt */
 
 	/* Service adapter interrupts */
 
-	if (bp->bus_type == DFX_BUS_TYPE_PCI)
-		{
-		/* Disable PDQ-PFI interrupts at PFI */
+	if (bp->bus_type == DFX_BUS_TYPE_PCI) {
+		u32 status;
 
-		dfx_port_write_long(bp, PFI_K_REG_MODE_CTRL, PFI_MODE_M_DMA_ENB);
+		dfx_port_read_long(bp, PFI_K_REG_STATUS, &status);
+		if (!(status & PFI_STATUS_M_PDQ_INT))
+			return IRQ_NONE;
 
-		/* Call interrupt service routine for this adapter */
+		spin_lock(&bp->lock);
+
+		/* Disable PDQ-PFI interrupts at PFI */
+		dfx_port_write_long(bp, PFI_K_REG_MODE_CTRL,
+				    PFI_MODE_M_DMA_ENB);
 
+		/* Call interrupt service routine for this adapter */
 		dfx_int_common(dev);
 
 		/* Clear PDQ interrupt status bit and reenable interrupts */
-
-		dfx_port_write_long(bp, PFI_K_REG_STATUS, PFI_STATUS_M_PDQ_INT);
+		dfx_port_write_long(bp, PFI_K_REG_STATUS,
+				    PFI_STATUS_M_PDQ_INT);
 		dfx_port_write_long(bp, PFI_K_REG_MODE_CTRL,
-					(PFI_MODE_M_PDQ_INT_ENB + PFI_MODE_M_DMA_ENB));
-		}
-	else
-		{
-		/* Disable interrupts at the ESIC */
+				    (PFI_MODE_M_PDQ_INT_ENB |
+				     PFI_MODE_M_DMA_ENB));
 
-		dfx_port_read_byte(bp, PI_ESIC_K_IO_CONFIG_STAT_0, &tmp);
-		tmp &= ~PI_CONFIG_STAT_0_M_INT_ENB;
-		dfx_port_write_byte(bp, PI_ESIC_K_IO_CONFIG_STAT_0, tmp);
+		spin_unlock(&bp->lock);
+	} else {
+		u8 status;
 
-		/* Call interrupt service routine for this adapter */
+		dfx_port_read_byte(bp, PI_ESIC_K_IO_CONFIG_STAT_0, &status);
+		if (!(status & PI_CONFIG_STAT_0_M_PEND))
+			return IRQ_NONE;
 
+		spin_lock(&bp->lock);
+
+		/* Disable interrupts at the ESIC */
+		status &= ~PI_CONFIG_STAT_0_M_INT_ENB;
+		dfx_port_write_byte(bp, PI_ESIC_K_IO_CONFIG_STAT_0, status);
+
+		/* Call interrupt service routine for this adapter */
 		dfx_int_common(dev);
 
 		/* Reenable interrupts at the ESIC */
+		dfx_port_read_byte(bp, PI_ESIC_K_IO_CONFIG_STAT_0, &status);
+		status |= PI_CONFIG_STAT_0_M_INT_ENB;
+		dfx_port_write_byte(bp, PI_ESIC_K_IO_CONFIG_STAT_0, status);
 
-		dfx_port_read_byte(bp, PI_ESIC_K_IO_CONFIG_STAT_0, &tmp);
-		tmp |= PI_CONFIG_STAT_0_M_INT_ENB;
-		dfx_port_write_byte(bp, PI_ESIC_K_IO_CONFIG_STAT_0, tmp);
-		}
-
-	spin_unlock(&bp->lock);
+		spin_unlock(&bp->lock);
 	}
 
+	return IRQ_HANDLED;
+}
+
 
 /*
  * =====================
diff --git a/drivers/net/dl2k.c b/drivers/net/dl2k.c
--- a/drivers/net/dl2k.c
+++ b/drivers/net/dl2k.c
@@ -547,7 +547,7 @@ rio_timer (unsigned long data)
 				skb_reserve (skb, 2);
 				np->rx_ring[entry].fraginfo =
 				    cpu_to_le64 (pci_map_single
-					 (np->pdev, skb->tail, np->rx_buf_sz,
+					 (np->pdev, skb->data, np->rx_buf_sz,
 					  PCI_DMA_FROMDEVICE));
 			}
 			np->rx_ring[entry].fraginfo |=
@@ -618,7 +618,7 @@ alloc_list (struct net_device *dev)
 		/* Rubicon now supports 40 bits of addressing space. */
 		np->rx_ring[i].fraginfo =
 		    cpu_to_le64 ( pci_map_single (
-			 	  np->pdev, skb->tail, np->rx_buf_sz,
+			 	  np->pdev, skb->data, np->rx_buf_sz,
 				  PCI_DMA_FROMDEVICE));
 		np->rx_ring[i].fraginfo |= cpu_to_le64 (np->rx_buf_sz) << 48;
 	}
@@ -906,7 +906,7 @@ receive_packet (struct net_device *dev)
 				/* 16 byte align the IP header */
 				skb_reserve (skb, 2);
 				eth_copy_and_sum (skb,
-						  np->rx_skbuff[entry]->tail,
+						  np->rx_skbuff[entry]->data,
 						  pkt_len, 0);
 				skb_put (skb, pkt_len);
 				pci_dma_sync_single_for_device(np->pdev,
@@ -950,7 +950,7 @@ receive_packet (struct net_device *dev)
 			skb_reserve (skb, 2);
 			np->rx_ring[entry].fraginfo =
 			    cpu_to_le64 (pci_map_single
-					 (np->pdev, skb->tail, np->rx_buf_sz,
+					 (np->pdev, skb->data, np->rx_buf_sz,
 					  PCI_DMA_FROMDEVICE));
 		}
 		np->rx_ring[entry].fraginfo |=
diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c
new file mode 100644
--- /dev/null
+++ b/drivers/net/dm9000.c
@@ -0,0 +1,1219 @@
+/*
+ *   dm9000.c: Version 1.2 03/18/2003
+ *
+ *         A Davicom DM9000 ISA NIC fast Ethernet driver for Linux.
+ * 	Copyright (C) 1997  Sten Wang
+ *
+ * 	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.
+ *
+ *   (C)Copyright 1997-1998 DAVICOM Semiconductor,Inc. All Rights Reserved.
+ *
+ * V0.11	06/20/2001	REG_0A bit3=1, default enable BP with DA match
+ * 	06/22/2001 	Support DM9801 progrmming
+ * 	 	 	E3: R25 = ((R24 + NF) & 0x00ff) | 0xf000
+ * 		 	E4: R25 = ((R24 + NF) & 0x00ff) | 0xc200
+ * 		     		R17 = (R17 & 0xfff0) | NF + 3
+ * 		 	E5: R25 = ((R24 + NF - 3) & 0x00ff) | 0xc200
+ * 		     		R17 = (R17 & 0xfff0) | NF
+ *
+ * v1.00               	modify by simon 2001.9.5
+ *                         change for kernel 2.4.x
+ *
+ * v1.1   11/09/2001      	fix force mode bug
+ *
+ * v1.2   03/18/2003       Weilun Huang <weilun_huang@davicom.com.tw>:
+ * 			Fixed phy reset.
+ * 			Added tx/rx 32 bit mode.
+ * 			Cleaned up for kernel merge.
+ *
+ *        03/03/2004    Sascha Hauer <s.hauer@pengutronix.de>
+ *                      Port to 2.6 kernel
+ *
+ *	  24-Sep-2004   Ben Dooks <ben@simtec.co.uk>
+ *			Cleanup of code to remove ifdefs
+ *			Allowed platform device data to influence access width
+ *			Reformatting areas of code
+ *
+ *        17-Mar-2005   Sascha Hauer <s.hauer@pengutronix.de>
+ *                      * removed 2.4 style module parameters
+ *                      * removed removed unused stat counter and fixed
+ *                        net_device_stats
+ *                      * introduced tx_timeout function
+ *                      * reworked locking
+ *
+ *	  01-Jul-2005   Ben Dooks <ben@simtec.co.uk>
+ *			* fixed spinlock call without pointer
+ *			* ensure spinlock is initialised
+ */
+
+#include <linux/module.h>
+#include <linux/ioport.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/init.h>
+#include <linux/skbuff.h>
+#include <linux/version.h>
+#include <linux/spinlock.h>
+#include <linux/crc32.h>
+#include <linux/mii.h>
+#include <linux/dm9000.h>
+#include <linux/delay.h>
+
+#include <asm/delay.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+
+#include "dm9000.h"
+
+/* Board/System/Debug information/definition ---------------- */
+
+#define DM9000_PHY		0x40	/* PHY address 0x01 */
+
+#define TRUE			1
+#define FALSE			0
+
+#define CARDNAME "dm9000"
+#define PFX CARDNAME ": "
+
+#define DM9000_TIMER_WUT  jiffies+(HZ*2)	/* timer wakeup time : 2 second */
+
+#define DM9000_DEBUG 0
+
+#if DM9000_DEBUG > 2
+#define PRINTK3(args...)  printk(CARDNAME ": " args)
+#else
+#define PRINTK3(args...)  do { } while(0)
+#endif
+
+#if DM9000_DEBUG > 1
+#define PRINTK2(args...)  printk(CARDNAME ": " args)
+#else
+#define PRINTK2(args...)  do { } while(0)
+#endif
+
+#if DM9000_DEBUG > 0
+#define PRINTK1(args...)  printk(CARDNAME ": " args)
+#define PRINTK(args...)   printk(CARDNAME ": " args)
+#else
+#define PRINTK1(args...)  do { } while(0)
+#define PRINTK(args...)   printk(KERN_DEBUG args)
+#endif
+
+/*
+ * Transmit timeout, default 5 seconds.
+ */
+static int watchdog = 5000;
+module_param(watchdog, int, 0400);
+MODULE_PARM_DESC(watchdog, "transmit timeout in milliseconds");
+
+/* Structure/enum declaration ------------------------------- */
+typedef struct board_info {
+
+	void __iomem *io_addr;	/* Register I/O base address */
+	void __iomem *io_data;	/* Data I/O address */
+	u16 irq;		/* IRQ */
+
+	u16 tx_pkt_cnt;
+	u16 queue_pkt_len;
+	u16 queue_start_addr;
+	u16 dbug_cnt;
+	u8 io_mode;		/* 0:word, 2:byte */
+	u8 phy_addr;
+
+	void (*inblk)(void __iomem *port, void *data, int length);
+	void (*outblk)(void __iomem *port, void *data, int length);
+	void (*dumpblk)(void __iomem *port, int length);
+
+	struct resource	*addr_res;   /* resources found */
+	struct resource *data_res;
+	struct resource	*addr_req;   /* resources requested */
+	struct resource *data_req;
+	struct resource *irq_res;
+
+	struct timer_list timer;
+	struct net_device_stats stats;
+	unsigned char srom[128];
+	spinlock_t lock;
+
+	struct mii_if_info mii;
+	u32 msg_enable;
+} board_info_t;
+
+/* function declaration ------------------------------------- */
+static int dm9000_probe(struct device *);
+static int dm9000_open(struct net_device *);
+static int dm9000_start_xmit(struct sk_buff *, struct net_device *);
+static int dm9000_stop(struct net_device *);
+
+
+static void dm9000_timer(unsigned long);
+static void dm9000_init_dm9000(struct net_device *);
+
+static struct net_device_stats *dm9000_get_stats(struct net_device *);
+
+static irqreturn_t dm9000_interrupt(int, void *, struct pt_regs *);
+
+static int dm9000_phy_read(struct net_device *dev, int phyaddr_unsused, int reg);
+static void dm9000_phy_write(struct net_device *dev, int phyaddr_unused, int reg,
+			   int value);
+static u16 read_srom_word(board_info_t *, int);
+static void dm9000_rx(struct net_device *);
+static void dm9000_hash_table(struct net_device *);
+
+//#define DM9000_PROGRAM_EEPROM
+#ifdef DM9000_PROGRAM_EEPROM
+static void program_eeprom(board_info_t * db);
+#endif
+/* DM9000 network board routine ---------------------------- */
+
+static void
+dm9000_reset(board_info_t * db)
+{
+	PRINTK1("dm9000x: resetting\n");
+	/* RESET device */
+	writeb(DM9000_NCR, db->io_addr);
+	udelay(200);
+	writeb(NCR_RST, db->io_data);
+	udelay(200);
+}
+
+/*
+ *   Read a byte from I/O port
+ */
+static u8
+ior(board_info_t * db, int reg)
+{
+	writeb(reg, db->io_addr);
+	return readb(db->io_data);
+}
+
+/*
+ *   Write a byte to I/O port
+ */
+
+static void
+iow(board_info_t * db, int reg, int value)
+{
+	writeb(reg, db->io_addr);
+	writeb(value, db->io_data);
+}
+
+/* routines for sending block to chip */
+
+static void dm9000_outblk_8bit(void __iomem *reg, void *data, int count)
+{
+	writesb(reg, data, count);
+}
+
+static void dm9000_outblk_16bit(void __iomem *reg, void *data, int count)
+{
+	writesw(reg, data, (count+1) >> 1);
+}
+
+static void dm9000_outblk_32bit(void __iomem *reg, void *data, int count)
+{
+	writesl(reg, data, (count+3) >> 2);
+}
+
+/* input block from chip to memory */
+
+static void dm9000_inblk_8bit(void __iomem *reg, void *data, int count)
+{
+	readsb(reg, data, count);
+}
+
+
+static void dm9000_inblk_16bit(void __iomem *reg, void *data, int count)
+{
+	readsw(reg, data, (count+1) >> 1);
+}
+
+static void dm9000_inblk_32bit(void __iomem *reg, void *data, int count)
+{
+	readsl(reg, data, (count+3) >> 2);
+}
+
+/* dump block from chip to null */
+
+static void dm9000_dumpblk_8bit(void __iomem *reg, int count)
+{
+	int i;
+	int tmp;
+
+	for (i = 0; i < count; i++)
+		tmp = readb(reg);
+}
+
+static void dm9000_dumpblk_16bit(void __iomem *reg, int count)
+{
+	int i;
+	int tmp;
+
+	count = (count + 1) >> 1;
+
+	for (i = 0; i < count; i++)
+		tmp = readw(reg);
+}
+
+static void dm9000_dumpblk_32bit(void __iomem *reg, int count)
+{
+	int i;
+	int tmp;
+
+	count = (count + 3) >> 2;
+
+	for (i = 0; i < count; i++)
+		tmp = readl(reg);
+}
+
+/* dm9000_set_io
+ *
+ * select the specified set of io routines to use with the
+ * device
+ */
+
+static void dm9000_set_io(struct board_info *db, int byte_width)
+{
+	/* use the size of the data resource to work out what IO
+	 * routines we want to use
+	 */
+
+	switch (byte_width) {
+	case 1:
+		db->dumpblk = dm9000_dumpblk_8bit;
+		db->outblk  = dm9000_outblk_8bit;
+		db->inblk   = dm9000_inblk_8bit;
+		break;
+
+	case 2:
+		db->dumpblk = dm9000_dumpblk_16bit;
+		db->outblk  = dm9000_outblk_16bit;
+		db->inblk   = dm9000_inblk_16bit;
+		break;
+
+	case 3:
+		printk(KERN_ERR PFX ": 3 byte IO, falling back to 16bit\n");
+		db->dumpblk = dm9000_dumpblk_16bit;
+		db->outblk  = dm9000_outblk_16bit;
+		db->inblk   = dm9000_inblk_16bit;
+		break;
+
+	case 4:
+	default:
+		db->dumpblk = dm9000_dumpblk_32bit;
+		db->outblk  = dm9000_outblk_32bit;
+		db->inblk   = dm9000_inblk_32bit;
+		break;
+	}
+}
+
+
+/* Our watchdog timed out. Called by the networking layer */
+static void dm9000_timeout(struct net_device *dev)
+{
+	board_info_t *db = (board_info_t *) dev->priv;
+	u8 reg_save;
+	unsigned long flags;
+
+	/* Save previous register address */
+	reg_save = readb(db->io_addr);
+	spin_lock_irqsave(&db->lock,flags);
+
+	netif_stop_queue(dev);
+	dm9000_reset(db);
+	dm9000_init_dm9000(dev);
+	/* We can accept TX packets again */
+	dev->trans_start = jiffies;
+	netif_wake_queue(dev);
+
+	/* Restore previous register address */
+	writeb(reg_save, db->io_addr);
+	spin_unlock_irqrestore(&db->lock,flags);
+}
+
+
+/* dm9000_release_board
+ *
+ * release a board, and any mapped resources
+ */
+
+static void
+dm9000_release_board(struct platform_device *pdev, struct board_info *db)
+{
+	if (db->data_res == NULL) {
+		if (db->addr_res != NULL)
+			release_mem_region((unsigned long)db->io_addr, 4);
+		return;
+	}
+
+	/* unmap our resources */
+
+	iounmap(db->io_addr);
+	iounmap(db->io_data);
+
+	/* release the resources */
+
+	if (db->data_req != NULL) {
+		release_resource(db->data_req);
+		kfree(db->data_req);
+	}
+
+	if (db->addr_res != NULL) {
+		release_resource(db->addr_res);
+		kfree(db->addr_req);
+	}
+}
+
+#define res_size(_r) (((_r)->end - (_r)->start) + 1)
+
+/*
+ * Search DM9000 board, allocate space and register it
+ */
+static int
+dm9000_probe(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct dm9000_plat_data *pdata = pdev->dev.platform_data;
+	struct board_info *db;	/* Point a board information structure */
+	struct net_device *ndev;
+	unsigned long base;
+	int ret = 0;
+	int iosize;
+	int i;
+	u32 id_val;
+
+	/* Init network device */
+	ndev = alloc_etherdev(sizeof (struct board_info));
+	if (!ndev) {
+		printk("%s: could not allocate device.\n", CARDNAME);
+		return -ENOMEM;
+	}
+
+	SET_MODULE_OWNER(ndev);
+	SET_NETDEV_DEV(ndev, dev);
+
+	PRINTK2("dm9000_probe()");
+
+	/* setup board info structure */
+	db = (struct board_info *) ndev->priv;
+	memset(db, 0, sizeof (*db));
+
+	spin_lock_init(&db->lock);
+
+	if (pdev->num_resources < 2) {
+		ret = -ENODEV;
+		goto out;
+	}
+
+	switch (pdev->num_resources) {
+	case 2:
+		base = pdev->resource[0].start;
+
+		if (!request_mem_region(base, 4, ndev->name)) {
+			ret = -EBUSY;
+			goto out;
+		}
+
+		ndev->base_addr = base;
+		ndev->irq = pdev->resource[1].start;
+		db->io_addr = (void *)base;
+		db->io_data = (void *)(base + 4);
+
+		break;
+
+	case 3:
+		db->addr_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+		db->data_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+		db->irq_res  = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+
+		if (db->addr_res == NULL || db->data_res == NULL) {
+			printk(KERN_ERR PFX "insufficient resources\n");
+			ret = -ENOENT;
+			goto out;
+		}
+
+		i = res_size(db->addr_res);
+		db->addr_req = request_mem_region(db->addr_res->start, i,
+						  pdev->name);
+
+		if (db->addr_req == NULL) {
+			printk(KERN_ERR PFX "cannot claim address reg area\n");
+			ret = -EIO;
+			goto out;
+		}
+
+		db->io_addr = ioremap(db->addr_res->start, i);
+
+		if (db->io_addr == NULL) {
+			printk(KERN_ERR "failed to ioremap address reg\n");
+			ret = -EINVAL;
+			goto out;
+		}
+
+		iosize = res_size(db->data_res);
+		db->data_req = request_mem_region(db->data_res->start, iosize,
+						  pdev->name);
+
+		if (db->data_req == NULL) {
+			printk(KERN_ERR PFX "cannot claim data reg area\n");
+			ret = -EIO;
+			goto out;
+		}
+
+		db->io_data = ioremap(db->data_res->start, iosize);
+
+		if (db->io_data == NULL) {
+			printk(KERN_ERR "failed to ioremap data reg\n");
+			ret = -EINVAL;
+			goto out;
+		}
+
+		/* fill in parameters for net-dev structure */
+
+		ndev->base_addr = (unsigned long)db->io_addr;
+		ndev->irq	= db->irq_res->start;
+
+		/* ensure at least we have a default set of IO routines */
+		dm9000_set_io(db, iosize);
+
+	}
+
+	/* check to see if anything is being over-ridden */
+	if (pdata != NULL) {
+		/* check to see if the driver wants to over-ride the
+		 * default IO width */
+
+		if (pdata->flags & DM9000_PLATF_8BITONLY)
+			dm9000_set_io(db, 1);
+
+		if (pdata->flags & DM9000_PLATF_16BITONLY)
+			dm9000_set_io(db, 2);
+
+		if (pdata->flags & DM9000_PLATF_32BITONLY)
+			dm9000_set_io(db, 4);
+
+		/* check to see if there are any IO routine
+		 * over-rides */
+
+		if (pdata->inblk != NULL)
+			db->inblk = pdata->inblk;
+
+		if (pdata->outblk != NULL)
+			db->outblk = pdata->outblk;
+
+		if (pdata->dumpblk != NULL)
+			db->dumpblk = pdata->dumpblk;
+	}
+
+	dm9000_reset(db);
+
+	/* try two times, DM9000 sometimes gets the first read wrong */
+	for (i = 0; i < 2; i++) {
+		id_val  = ior(db, DM9000_VIDL);
+		id_val |= (u32)ior(db, DM9000_VIDH) << 8;
+		id_val |= (u32)ior(db, DM9000_PIDL) << 16;
+		id_val |= (u32)ior(db, DM9000_PIDH) << 24;
+
+		if (id_val == DM9000_ID)
+			break;
+		printk("%s: read wrong id 0x%08x\n", CARDNAME, id_val);
+	}
+
+	if (id_val != DM9000_ID) {
+		printk("%s: wrong id: 0x%08x\n", CARDNAME, id_val);
+		goto release;
+	}
+
+	/* from this point we assume that we have found a DM9000 */
+
+	/* driver system function */
+	ether_setup(ndev);
+
+	ndev->open		 = &dm9000_open;
+	ndev->hard_start_xmit    = &dm9000_start_xmit;
+	ndev->tx_timeout         = &dm9000_timeout;
+	ndev->watchdog_timeo = msecs_to_jiffies(watchdog);
+	ndev->stop		 = &dm9000_stop;
+	ndev->get_stats		 = &dm9000_get_stats;
+	ndev->set_multicast_list = &dm9000_hash_table;
+
+#ifdef DM9000_PROGRAM_EEPROM
+	program_eeprom(db);
+#endif
+	db->msg_enable       = NETIF_MSG_LINK;
+	db->mii.phy_id_mask  = 0x1f;
+	db->mii.reg_num_mask = 0x1f;
+	db->mii.force_media  = 0;
+	db->mii.full_duplex  = 0;
+	db->mii.dev	     = ndev;
+	db->mii.mdio_read    = dm9000_phy_read;
+	db->mii.mdio_write   = dm9000_phy_write;
+
+	/* Read SROM content */
+	for (i = 0; i < 64; i++)
+		((u16 *) db->srom)[i] = read_srom_word(db, i);
+
+	/* Set Node Address */
+	for (i = 0; i < 6; i++)
+		ndev->dev_addr[i] = db->srom[i];
+
+	if (!is_valid_ether_addr(ndev->dev_addr))
+		printk("%s: Invalid ethernet MAC address.  Please "
+		       "set using ifconfig\n", ndev->name);
+
+	dev_set_drvdata(dev, ndev);
+	ret = register_netdev(ndev);
+
+	if (ret == 0) {
+		printk("%s: dm9000 at %p,%p IRQ %d MAC: ",
+		       ndev->name,  db->io_addr, db->io_data, ndev->irq);
+		for (i = 0; i < 5; i++)
+			printk("%02x:", ndev->dev_addr[i]);
+		printk("%02x\n", ndev->dev_addr[5]);
+	}
+	return 0;
+
+ release:
+ out:
+	printk("%s: not found (%d).\n", CARDNAME, ret);
+
+	dm9000_release_board(pdev, db);
+	kfree(ndev);
+
+	return ret;
+}
+
+/*
+ *  Open the interface.
+ *  The interface is opened whenever "ifconfig" actives it.
+ */
+static int
+dm9000_open(struct net_device *dev)
+{
+	board_info_t *db = (board_info_t *) dev->priv;
+
+	PRINTK2("entering dm9000_open\n");
+
+	if (request_irq(dev->irq, &dm9000_interrupt, SA_SHIRQ, dev->name, dev))
+		return -EAGAIN;
+
+	/* Initialize DM9000 board */
+	dm9000_reset(db);
+	dm9000_init_dm9000(dev);
+
+	/* Init driver variable */
+	db->dbug_cnt = 0;
+
+	/* set and active a timer process */
+	init_timer(&db->timer);
+	db->timer.expires  = DM9000_TIMER_WUT;
+	db->timer.data     = (unsigned long) dev;
+	db->timer.function = &dm9000_timer;
+	add_timer(&db->timer);
+
+	mii_check_media(&db->mii, netif_msg_link(db), 1);
+	netif_start_queue(dev);
+
+	return 0;
+}
+
+/*
+ * Initilize dm9000 board
+ */
+static void
+dm9000_init_dm9000(struct net_device *dev)
+{
+	board_info_t *db = (board_info_t *) dev->priv;
+
+	PRINTK1("entering %s\n",__FUNCTION__);
+
+	/* I/O mode */
+	db->io_mode = ior(db, DM9000_ISR) >> 6;	/* ISR bit7:6 keeps I/O mode */
+
+	/* GPIO0 on pre-activate PHY */
+	iow(db, DM9000_GPR, 0);	/* REG_1F bit0 activate phyxcer */
+	iow(db, DM9000_GPCR, GPCR_GEP_CNTL);	/* Let GPIO0 output */
+	iow(db, DM9000_GPR, 0);	/* Enable PHY */
+
+	/* Program operating register */
+	iow(db, DM9000_TCR, 0);	        /* TX Polling clear */
+	iow(db, DM9000_BPTR, 0x3f);	/* Less 3Kb, 200us */
+	iow(db, DM9000_FCR, 0xff);	/* Flow Control */
+	iow(db, DM9000_SMCR, 0);        /* Special Mode */
+	/* clear TX status */
+	iow(db, DM9000_NSR, NSR_WAKEST | NSR_TX2END | NSR_TX1END);
+	iow(db, DM9000_ISR, ISR_CLR_STATUS); /* Clear interrupt status */
+
+	/* Set address filter table */
+	dm9000_hash_table(dev);
+
+	/* Activate DM9000 */
+	iow(db, DM9000_RCR, RCR_DIS_LONG | RCR_DIS_CRC | RCR_RXEN);
+	/* Enable TX/RX interrupt mask */
+	iow(db, DM9000_IMR, IMR_PAR | IMR_PTM | IMR_PRM);
+
+	/* Init Driver variable */
+	db->tx_pkt_cnt = 0;
+	db->queue_pkt_len = 0;
+	dev->trans_start = 0;
+	spin_lock_init(&db->lock);
+}
+
+/*
+ *  Hardware start transmission.
+ *  Send a packet to media from the upper layer.
+ */
+static int
+dm9000_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	board_info_t *db = (board_info_t *) dev->priv;
+
+	PRINTK3("dm9000_start_xmit\n");
+
+	if (db->tx_pkt_cnt > 1)
+		return 1;
+
+	netif_stop_queue(dev);
+
+	/* Disable all interrupts */
+	iow(db, DM9000_IMR, IMR_PAR);
+
+	/* Move data to DM9000 TX RAM */
+	writeb(DM9000_MWCMD, db->io_addr);
+
+	(db->outblk)(db->io_data, skb->data, skb->len);
+	db->stats.tx_bytes += skb->len;
+
+	/* TX control: First packet immediately send, second packet queue */
+	if (db->tx_pkt_cnt == 0) {
+
+		/* First Packet */
+		db->tx_pkt_cnt++;
+
+		/* Set TX length to DM9000 */
+		iow(db, DM9000_TXPLL, skb->len & 0xff);
+		iow(db, DM9000_TXPLH, (skb->len >> 8) & 0xff);
+
+		/* Issue TX polling command */
+		iow(db, DM9000_TCR, TCR_TXREQ);	/* Cleared after TX complete */
+
+		dev->trans_start = jiffies;	/* save the time stamp */
+
+	} else {
+		/* Second packet */
+		db->tx_pkt_cnt++;
+		db->queue_pkt_len = skb->len;
+	}
+
+	/* free this SKB */
+	dev_kfree_skb(skb);
+
+	/* Re-enable resource check */
+	if (db->tx_pkt_cnt == 1)
+		netif_wake_queue(dev);
+
+	/* Re-enable interrupt */
+	iow(db, DM9000_IMR, IMR_PAR | IMR_PTM | IMR_PRM);
+
+	return 0;
+}
+
+static void
+dm9000_shutdown(struct net_device *dev)
+{
+	board_info_t *db = (board_info_t *) dev->priv;
+
+	/* RESET device */
+	dm9000_phy_write(dev, 0, MII_BMCR, BMCR_RESET);	/* PHY RESET */
+	iow(db, DM9000_GPR, 0x01);	/* Power-Down PHY */
+	iow(db, DM9000_IMR, IMR_PAR);	/* Disable all interrupt */
+	iow(db, DM9000_RCR, 0x00);	/* Disable RX */
+}
+
+/*
+ * Stop the interface.
+ * The interface is stopped when it is brought.
+ */
+static int
+dm9000_stop(struct net_device *ndev)
+{
+	board_info_t *db = (board_info_t *) ndev->priv;
+
+	PRINTK1("entering %s\n",__FUNCTION__);
+
+	/* deleted timer */
+	del_timer(&db->timer);
+
+	netif_stop_queue(ndev);
+	netif_carrier_off(ndev);
+
+	/* free interrupt */
+	free_irq(ndev->irq, ndev);
+
+	dm9000_shutdown(ndev);
+
+	return 0;
+}
+
+/*
+ * DM9000 interrupt handler
+ * receive the packet to upper layer, free the transmitted packet
+ */
+
+void
+dm9000_tx_done(struct net_device *dev, board_info_t * db)
+{
+	int tx_status = ior(db, DM9000_NSR);	/* Got TX status */
+
+	if (tx_status & (NSR_TX2END | NSR_TX1END)) {
+		/* One packet sent complete */
+		db->tx_pkt_cnt--;
+		db->stats.tx_packets++;
+
+		/* Queue packet check & send */
+		if (db->tx_pkt_cnt > 0) {
+			iow(db, DM9000_TXPLL, db->queue_pkt_len & 0xff);
+			iow(db, DM9000_TXPLH, (db->queue_pkt_len >> 8) & 0xff);
+			iow(db, DM9000_TCR, TCR_TXREQ);
+			dev->trans_start = jiffies;
+		}
+		netif_wake_queue(dev);
+	}
+}
+
+static irqreturn_t
+dm9000_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct net_device *dev = dev_id;
+	board_info_t *db;
+	int int_status;
+	u8 reg_save;
+
+	PRINTK3("entering %s\n",__FUNCTION__);
+
+	if (!dev) {
+		PRINTK1("dm9000_interrupt() without DEVICE arg\n");
+		return IRQ_HANDLED;
+	}
+
+	/* A real interrupt coming */
+	db = (board_info_t *) dev->priv;
+	spin_lock(&db->lock);
+
+	/* Save previous register address */
+	reg_save = readb(db->io_addr);
+
+	/* Disable all interrupts */
+	iow(db, DM9000_IMR, IMR_PAR);
+
+	/* Got DM9000 interrupt status */
+	int_status = ior(db, DM9000_ISR);	/* Got ISR */
+	iow(db, DM9000_ISR, int_status);	/* Clear ISR status */
+
+	/* Received the coming packet */
+	if (int_status & ISR_PRS)
+		dm9000_rx(dev);
+
+	/* Trnasmit Interrupt check */
+	if (int_status & ISR_PTS)
+		dm9000_tx_done(dev, db);
+
+	/* Re-enable interrupt mask */
+	iow(db, DM9000_IMR, IMR_PAR | IMR_PTM | IMR_PRM);
+
+	/* Restore previous register address */
+	writeb(reg_save, db->io_addr);
+
+	spin_unlock(&db->lock);
+
+	return IRQ_HANDLED;
+}
+
+/*
+ *  Get statistics from driver.
+ */
+static struct net_device_stats *
+dm9000_get_stats(struct net_device *dev)
+{
+	board_info_t *db = (board_info_t *) dev->priv;
+	return &db->stats;
+}
+
+
+/*
+ *  A periodic timer routine
+ *  Dynamic media sense, allocated Rx buffer...
+ */
+static void
+dm9000_timer(unsigned long data)
+{
+	struct net_device *dev = (struct net_device *) data;
+	board_info_t *db = (board_info_t *) dev->priv;
+
+	PRINTK3("dm9000_timer()\n");
+
+	mii_check_media(&db->mii, netif_msg_link(db), 0);
+
+	/* Set timer again */
+	db->timer.expires = DM9000_TIMER_WUT;
+	add_timer(&db->timer);
+}
+
+struct dm9000_rxhdr {
+	u16	RxStatus;
+	u16	RxLen;
+} __attribute__((__packed__));
+
+/*
+ *  Received a packet and pass to upper layer
+ */
+static void
+dm9000_rx(struct net_device *dev)
+{
+	board_info_t *db = (board_info_t *) dev->priv;
+	struct dm9000_rxhdr rxhdr;
+	struct sk_buff *skb;
+	u8 rxbyte, *rdptr;
+	int GoodPacket;
+	int RxLen;
+
+	/* Check packet ready or not */
+	do {
+		ior(db, DM9000_MRCMDX);	/* Dummy read */
+
+		/* Get most updated data */
+		rxbyte = readb(db->io_data);
+
+		/* Status check: this byte must be 0 or 1 */
+		if (rxbyte > DM9000_PKT_RDY) {
+			printk("status check failed: %d\n", rxbyte);
+			iow(db, DM9000_RCR, 0x00);	/* Stop Device */
+			iow(db, DM9000_ISR, IMR_PAR);	/* Stop INT request */
+			return;
+		}
+
+		if (rxbyte != DM9000_PKT_RDY)
+			return;
+
+		/* A packet ready now  & Get status/length */
+		GoodPacket = TRUE;
+		writeb(DM9000_MRCMD, db->io_addr);
+
+		(db->inblk)(db->io_data, &rxhdr, sizeof(rxhdr));
+
+		RxLen = rxhdr.RxLen;
+
+		/* Packet Status check */
+		if (RxLen < 0x40) {
+			GoodPacket = FALSE;
+			PRINTK1("Bad Packet received (runt)\n");
+		}
+
+		if (RxLen > DM9000_PKT_MAX) {
+			PRINTK1("RST: RX Len:%x\n", RxLen);
+		}
+
+		if (rxhdr.RxStatus & 0xbf00) {
+			GoodPacket = FALSE;
+			if (rxhdr.RxStatus & 0x100) {
+				PRINTK1("fifo error\n");
+				db->stats.rx_fifo_errors++;
+			}
+			if (rxhdr.RxStatus & 0x200) {
+				PRINTK1("crc error\n");
+				db->stats.rx_crc_errors++;
+			}
+			if (rxhdr.RxStatus & 0x8000) {
+				PRINTK1("length error\n");
+				db->stats.rx_length_errors++;
+			}
+		}
+
+		/* Move data from DM9000 */
+		if (GoodPacket
+		    && ((skb = dev_alloc_skb(RxLen + 4)) != NULL)) {
+			skb->dev = dev;
+			skb_reserve(skb, 2);
+			rdptr = (u8 *) skb_put(skb, RxLen - 4);
+
+			/* Read received packet from RX SRAM */
+
+			(db->inblk)(db->io_data, rdptr, RxLen);
+			db->stats.rx_bytes += RxLen;
+
+			/* Pass to upper layer */
+			skb->protocol = eth_type_trans(skb, dev);
+			netif_rx(skb);
+			db->stats.rx_packets++;
+
+		} else {
+			/* need to dump the packet's data */
+
+			(db->dumpblk)(db->io_data, RxLen);
+		}
+	} while (rxbyte == DM9000_PKT_RDY);
+}
+
+/*
+ *  Read a word data from SROM
+ */
+static u16
+read_srom_word(board_info_t * db, int offset)
+{
+	iow(db, DM9000_EPAR, offset);
+	iow(db, DM9000_EPCR, EPCR_ERPRR);
+	mdelay(8);		/* according to the datasheet 200us should be enough,
+				   but it doesn't work */
+	iow(db, DM9000_EPCR, 0x0);
+	return (ior(db, DM9000_EPDRL) + (ior(db, DM9000_EPDRH) << 8));
+}
+
+#ifdef DM9000_PROGRAM_EEPROM
+/*
+ * Write a word data to SROM
+ */
+static void
+write_srom_word(board_info_t * db, int offset, u16 val)
+{
+	iow(db, DM9000_EPAR, offset);
+	iow(db, DM9000_EPDRH, ((val >> 8) & 0xff));
+	iow(db, DM9000_EPDRL, (val & 0xff));
+	iow(db, DM9000_EPCR, EPCR_WEP | EPCR_ERPRW);
+	mdelay(8);		/* same shit */
+	iow(db, DM9000_EPCR, 0);
+}
+
+/*
+ * Only for development:
+ * Here we write static data to the eeprom in case
+ * we don't have valid content on a new board
+ */
+static void
+program_eeprom(board_info_t * db)
+{
+	u16 eeprom[] = { 0x0c00, 0x007f, 0x1300,	/* MAC Address */
+		0x0000,		/* Autoload: accept nothing */
+		0x0a46, 0x9000,	/* Vendor / Product ID */
+		0x0000,		/* pin control */
+		0x0000,
+	};			/* Wake-up mode control */
+	int i;
+	for (i = 0; i < 8; i++)
+		write_srom_word(db, i, eeprom[i]);
+}
+#endif
+
+
+/*
+ *  Calculate the CRC valude of the Rx packet
+ *  flag = 1 : return the reverse CRC (for the received packet CRC)
+ *         0 : return the normal CRC (for Hash Table index)
+ */
+
+static unsigned long
+cal_CRC(unsigned char *Data, unsigned int Len, u8 flag)
+{
+
+       u32 crc = ether_crc_le(Len, Data);
+
+       if (flag)
+               return ~crc;
+
+       return crc;
+}
+
+/*
+ *  Set DM9000 multicast address
+ */
+static void
+dm9000_hash_table(struct net_device *dev)
+{
+	board_info_t *db = (board_info_t *) dev->priv;
+	struct dev_mc_list *mcptr = dev->mc_list;
+	int mc_cnt = dev->mc_count;
+	u32 hash_val;
+	u16 i, oft, hash_table[4];
+	unsigned long flags;
+
+	PRINTK2("dm9000_hash_table()\n");
+
+	spin_lock_irqsave(&db->lock,flags);
+
+	for (i = 0, oft = 0x10; i < 6; i++, oft++)
+		iow(db, oft, dev->dev_addr[i]);
+
+	/* Clear Hash Table */
+	for (i = 0; i < 4; i++)
+		hash_table[i] = 0x0;
+
+	/* broadcast address */
+	hash_table[3] = 0x8000;
+
+	/* the multicast address in Hash Table : 64 bits */
+	for (i = 0; i < mc_cnt; i++, mcptr = mcptr->next) {
+		hash_val = cal_CRC((char *) mcptr->dmi_addr, 6, 0) & 0x3f;
+		hash_table[hash_val / 16] |= (u16) 1 << (hash_val % 16);
+	}
+
+	/* Write the hash table to MAC MD table */
+	for (i = 0, oft = 0x16; i < 4; i++) {
+		iow(db, oft++, hash_table[i] & 0xff);
+		iow(db, oft++, (hash_table[i] >> 8) & 0xff);
+	}
+
+	spin_unlock_irqrestore(&db->lock,flags);
+}
+
+
+/*
+ *   Read a word from phyxcer
+ */
+static int
+dm9000_phy_read(struct net_device *dev, int phy_reg_unused, int reg)
+{
+	board_info_t *db = (board_info_t *) dev->priv;
+	unsigned long flags;
+	unsigned int reg_save;
+	int ret;
+
+	spin_lock_irqsave(&db->lock,flags);
+
+	/* Save previous register address */
+	reg_save = readb(db->io_addr);
+
+	/* Fill the phyxcer register into REG_0C */
+	iow(db, DM9000_EPAR, DM9000_PHY | reg);
+
+	iow(db, DM9000_EPCR, 0xc);	/* Issue phyxcer read command */
+	udelay(100);		/* Wait read complete */
+	iow(db, DM9000_EPCR, 0x0);	/* Clear phyxcer read command */
+
+	/* The read data keeps on REG_0D & REG_0E */
+	ret = (ior(db, DM9000_EPDRH) << 8) | ior(db, DM9000_EPDRL);
+
+	/* restore the previous address */
+	writeb(reg_save, db->io_addr);
+
+	spin_unlock_irqrestore(&db->lock,flags);
+
+	return ret;
+}
+
+/*
+ *   Write a word to phyxcer
+ */
+static void
+dm9000_phy_write(struct net_device *dev, int phyaddr_unused, int reg, int value)
+{
+	board_info_t *db = (board_info_t *) dev->priv;
+	unsigned long flags;
+	unsigned long reg_save;
+
+	spin_lock_irqsave(&db->lock,flags);
+
+	/* Save previous register address */
+	reg_save = readb(db->io_addr);
+
+	/* Fill the phyxcer register into REG_0C */
+	iow(db, DM9000_EPAR, DM9000_PHY | reg);
+
+	/* Fill the written data into REG_0D & REG_0E */
+	iow(db, DM9000_EPDRL, (value & 0xff));
+	iow(db, DM9000_EPDRH, ((value >> 8) & 0xff));
+
+	iow(db, DM9000_EPCR, 0xa);	/* Issue phyxcer write command */
+	udelay(500);		/* Wait write complete */
+	iow(db, DM9000_EPCR, 0x0);	/* Clear phyxcer write command */
+
+	/* restore the previous address */
+	writeb(reg_save, db->io_addr);
+
+	spin_unlock_irqrestore(&db->lock,flags);
+}
+
+static int
+dm9000_drv_suspend(struct device *dev, u32 state, u32 level)
+{
+	struct net_device *ndev = dev_get_drvdata(dev);
+
+	if (ndev && level == SUSPEND_DISABLE) {
+		if (netif_running(ndev)) {
+			netif_device_detach(ndev);
+			dm9000_shutdown(ndev);
+		}
+	}
+	return 0;
+}
+
+static int
+dm9000_drv_resume(struct device *dev, u32 level)
+{
+	struct net_device *ndev = dev_get_drvdata(dev);
+	board_info_t *db = (board_info_t *) ndev->priv;
+
+	if (ndev && level == RESUME_ENABLE) {
+
+		if (netif_running(ndev)) {
+			dm9000_reset(db);
+			dm9000_init_dm9000(ndev);
+
+			netif_device_attach(ndev);
+		}
+	}
+	return 0;
+}
+
+static int
+dm9000_drv_remove(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct net_device *ndev = dev_get_drvdata(dev);
+
+	dev_set_drvdata(dev, NULL);
+
+	unregister_netdev(ndev);
+	dm9000_release_board(pdev, (board_info_t *) ndev->priv);
+	kfree(ndev);		/* free device structure */
+
+	PRINTK1("clean_module() exit\n");
+
+	return 0;
+}
+
+static struct device_driver dm9000_driver = {
+	.name    = "dm9000",
+	.bus     = &platform_bus_type,
+	.probe   = dm9000_probe,
+	.remove  = dm9000_drv_remove,
+	.suspend = dm9000_drv_suspend,
+	.resume  = dm9000_drv_resume,
+};
+
+static int __init
+dm9000_init(void)
+{
+	printk(KERN_INFO "%s Ethernet Driver\n", CARDNAME);
+
+	return driver_register(&dm9000_driver);	/* search board and register */
+}
+
+static void __exit
+dm9000_cleanup(void)
+{
+	driver_unregister(&dm9000_driver);
+}
+
+module_init(dm9000_init);
+module_exit(dm9000_cleanup);
+
+MODULE_AUTHOR("Sascha Hauer, Ben Dooks");
+MODULE_DESCRIPTION("Davicom DM9000 network driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/dm9000.h b/drivers/net/dm9000.h
new file mode 100644
--- /dev/null
+++ b/drivers/net/dm9000.h
@@ -0,0 +1,135 @@
+/*
+ * dm9000 Ethernet
+ */
+
+#ifndef _DM9000X_H_
+#define _DM9000X_H_
+
+#define DM9000_ID		0x90000A46
+
+/* although the registers are 16 bit, they are 32-bit aligned.
+ */
+
+#define DM9000_NCR             0x00
+#define DM9000_NSR             0x01
+#define DM9000_TCR             0x02
+#define DM9000_TSR1            0x03
+#define DM9000_TSR2            0x04
+#define DM9000_RCR             0x05
+#define DM9000_RSR             0x06
+#define DM9000_ROCR            0x07
+#define DM9000_BPTR            0x08
+#define DM9000_FCTR            0x09
+#define DM9000_FCR             0x0A
+#define DM9000_EPCR            0x0B
+#define DM9000_EPAR            0x0C
+#define DM9000_EPDRL           0x0D
+#define DM9000_EPDRH           0x0E
+#define DM9000_WCR             0x0F
+
+#define DM9000_PAR             0x10
+#define DM9000_MAR             0x16
+
+#define DM9000_GPCR	       0x1e
+#define DM9000_GPR             0x1f
+#define DM9000_TRPAL           0x22
+#define DM9000_TRPAH           0x23
+#define DM9000_RWPAL           0x24
+#define DM9000_RWPAH           0x25
+
+#define DM9000_VIDL            0x28
+#define DM9000_VIDH            0x29
+#define DM9000_PIDL            0x2A
+#define DM9000_PIDH            0x2B
+
+#define DM9000_CHIPR           0x2C
+#define DM9000_SMCR            0x2F
+
+#define DM9000_MRCMDX          0xF0
+#define DM9000_MRCMD           0xF2
+#define DM9000_MRRL            0xF4
+#define DM9000_MRRH            0xF5
+#define DM9000_MWCMDX          0xF6
+#define DM9000_MWCMD           0xF8
+#define DM9000_MWRL            0xFA
+#define DM9000_MWRH            0xFB
+#define DM9000_TXPLL           0xFC
+#define DM9000_TXPLH           0xFD
+#define DM9000_ISR             0xFE
+#define DM9000_IMR             0xFF
+
+#define NCR_EXT_PHY         (1<<7)
+#define NCR_WAKEEN          (1<<6)
+#define NCR_FCOL            (1<<4)
+#define NCR_FDX             (1<<3)
+#define NCR_LBK             (3<<1)
+#define NCR_RST	            (1<<0)
+
+#define NSR_SPEED           (1<<7)
+#define NSR_LINKST          (1<<6)
+#define NSR_WAKEST          (1<<5)
+#define NSR_TX2END          (1<<3)
+#define NSR_TX1END          (1<<2)
+#define NSR_RXOV            (1<<1)
+
+#define TCR_TJDIS           (1<<6)
+#define TCR_EXCECM          (1<<5)
+#define TCR_PAD_DIS2        (1<<4)
+#define TCR_CRC_DIS2        (1<<3)
+#define TCR_PAD_DIS1        (1<<2)
+#define TCR_CRC_DIS1        (1<<1)
+#define TCR_TXREQ           (1<<0)
+
+#define TSR_TJTO            (1<<7)
+#define TSR_LC              (1<<6)
+#define TSR_NC              (1<<5)
+#define TSR_LCOL            (1<<4)
+#define TSR_COL             (1<<3)
+#define TSR_EC              (1<<2)
+
+#define RCR_WTDIS           (1<<6)
+#define RCR_DIS_LONG        (1<<5)
+#define RCR_DIS_CRC         (1<<4)
+#define RCR_ALL	            (1<<3)
+#define RCR_RUNT            (1<<2)
+#define RCR_PRMSC           (1<<1)
+#define RCR_RXEN            (1<<0)
+
+#define RSR_RF              (1<<7)
+#define RSR_MF              (1<<6)
+#define RSR_LCS             (1<<5)
+#define RSR_RWTO            (1<<4)
+#define RSR_PLE             (1<<3)
+#define RSR_AE              (1<<2)
+#define RSR_CE              (1<<1)
+#define RSR_FOE             (1<<0)
+
+#define FCTR_HWOT(ot)	(( ot & 0xf ) << 4 )
+#define FCTR_LWOT(ot)	( ot & 0xf )
+
+#define IMR_PAR             (1<<7)
+#define IMR_ROOM            (1<<3)
+#define IMR_ROM             (1<<2)
+#define IMR_PTM             (1<<1)
+#define IMR_PRM             (1<<0)
+
+#define ISR_ROOS            (1<<3)
+#define ISR_ROS             (1<<2)
+#define ISR_PTS             (1<<1)
+#define ISR_PRS             (1<<0)
+#define ISR_CLR_STATUS      (ISR_ROOS | ISR_ROS | ISR_PTS | ISR_PRS)
+
+#define EPCR_REEP           (1<<5)
+#define EPCR_WEP            (1<<4)
+#define EPCR_EPOS           (1<<3)
+#define EPCR_ERPRR          (1<<2)
+#define EPCR_ERPRW          (1<<1)
+#define EPCR_ERRE           (1<<0)
+
+#define GPCR_GEP_CNTL       (1<<0)
+
+#define DM9000_PKT_RDY		0x01	/* Packet ready to receive */
+#define DM9000_PKT_MAX		1536	/* Received packet max size */
+
+#endif /* _DM9000X_H_ */
+
diff --git a/drivers/net/e100.c b/drivers/net/e100.c
--- a/drivers/net/e100.c
+++ b/drivers/net/e100.c
@@ -143,6 +143,7 @@
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/pci.h>
+#include <linux/dma-mapping.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/mii.h>
@@ -1092,11 +1093,16 @@ static int e100_phy_init(struct nic *nic
 	}
 
 	if((nic->mac >= mac_82550_D102) || ((nic->flags & ich) && 
-		(mdio_read(netdev, nic->mii.phy_id, MII_TPISTATUS) & 0x8000) && 
-		(nic->eeprom[eeprom_cnfg_mdix] & eeprom_mdix_enabled)))
-		/* enable/disable MDI/MDI-X auto-switching */
-		mdio_write(netdev, nic->mii.phy_id, MII_NCONFIG,
-			nic->mii.force_media ? 0 : NCONFIG_AUTO_SWITCH);
+	   (mdio_read(netdev, nic->mii.phy_id, MII_TPISTATUS) & 0x8000))) {
+		/* enable/disable MDI/MDI-X auto-switching.
+		   MDI/MDI-X auto-switching is disabled for 82551ER/QM chips */
+		if((nic->mac == mac_82551_E) || (nic->mac == mac_82551_F) ||
+		   (nic->mac == mac_82551_10) || (nic->mii.force_media) || 
+		   !(nic->eeprom[eeprom_cnfg_mdix] & eeprom_mdix_enabled)) 
+			mdio_write(netdev, nic->mii.phy_id, MII_NCONFIG, 0);
+		else
+			mdio_write(netdev, nic->mii.phy_id, MII_NCONFIG, NCONFIG_AUTO_SWITCH);
+	}
 
 	return 0;
 }
@@ -1665,8 +1671,10 @@ static irqreturn_t e100_intr(int irq, vo
 	if(stat_ack & stat_ack_rnr)
 		nic->ru_running = RU_SUSPENDED;
 
-	e100_disable_irq(nic);
-	netif_rx_schedule(netdev);
+	if(likely(netif_rx_schedule_prep(netdev))) {
+		e100_disable_irq(nic);
+		__netif_rx_schedule(netdev);
+	}
 
 	return IRQ_HANDLED;
 }
@@ -2286,7 +2294,7 @@ static int __devinit e100_probe(struct p
 		goto err_out_disable_pdev;
 	}
 
-	if((err = pci_set_dma_mask(pdev, 0xFFFFFFFFULL))) {
+	if((err = pci_set_dma_mask(pdev, DMA_32BIT_MASK))) {
 		DPRINTK(PROBE, ERR, "No usable DMA configuration, aborting.\n");
 		goto err_out_free_res;
 	}
@@ -2334,11 +2342,11 @@ static int __devinit e100_probe(struct p
 		goto err_out_iounmap;
 	}
 
-	e100_phy_init(nic);
-
 	if((err = e100_eeprom_load(nic)))
 		goto err_out_free;
 
+	e100_phy_init(nic);
+
 	memcpy(netdev->dev_addr, nic->eeprom, ETH_ALEN);
 	if(!is_valid_ether_addr(netdev->dev_addr)) {
 		DPRINTK(PROBE, ERR, "Invalid MAC address from "
@@ -2439,9 +2447,8 @@ static int e100_resume(struct pci_dev *p
 #endif
 
 
-static void e100_shutdown(struct device *dev)
+static void e100_shutdown(struct pci_dev *pdev)
 {
-	struct pci_dev *pdev = container_of(dev, struct pci_dev, dev);
 	struct net_device *netdev = pci_get_drvdata(pdev);
 	struct nic *nic = netdev_priv(netdev);
 
@@ -2462,11 +2469,7 @@ static struct pci_driver e100_driver = {
 	.suspend =      e100_suspend,
 	.resume =       e100_resume,
 #endif
-
-	.driver = {
-		.shutdown = e100_shutdown,
-	}
-
+	.shutdown =	e100_shutdown,
 };
 
 static int __init e100_init_module(void)
diff --git a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h
--- a/drivers/net/e1000/e1000.h
+++ b/drivers/net/e1000/e1000.h
@@ -140,7 +140,7 @@ struct e1000_adapter;
 #define E1000_RX_BUFFER_WRITE	16	/* Must be power of 2 */
 
 #define AUTO_ALL_MODES            0
-#define E1000_EEPROM_82544_APM    0x0400
+#define E1000_EEPROM_82544_APM    0x0004
 #define E1000_EEPROM_APME         0x0400
 
 #ifndef E1000_MASTER_SLAVE
@@ -159,7 +159,7 @@ struct e1000_adapter;
  * so a DMA handle can be stored along with the buffer */
 struct e1000_buffer {
 	struct sk_buff *skb;
-	uint64_t dma;
+	dma_addr_t dma;
 	unsigned long time_stamp;
 	uint16_t length;
 	uint16_t next_to_watch;
diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c
--- a/drivers/net/e1000/e1000_ethtool.c
+++ b/drivers/net/e1000/e1000_ethtool.c
@@ -105,7 +105,7 @@ static const char e1000_gstrings_test[][
 static int
 e1000_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
 {
-	struct e1000_adapter *adapter = netdev->priv;
+	struct e1000_adapter *adapter = netdev_priv(netdev);
 	struct e1000_hw *hw = &adapter->hw;
 
 	if(hw->media_type == e1000_media_type_copper) {
@@ -141,9 +141,9 @@ e1000_get_settings(struct net_device *ne
 				     SUPPORTED_FIBRE |
 				     SUPPORTED_Autoneg);
 
-		ecmd->advertising = (SUPPORTED_1000baseT_Full |
-				     SUPPORTED_FIBRE |
-				     SUPPORTED_Autoneg);
+		ecmd->advertising = (ADVERTISED_1000baseT_Full |
+				     ADVERTISED_FIBRE |
+				     ADVERTISED_Autoneg);
 
 		ecmd->port = PORT_FIBRE;
 
@@ -179,13 +179,24 @@ e1000_get_settings(struct net_device *ne
 static int
 e1000_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
 {
-	struct e1000_adapter *adapter = netdev->priv;
+	struct e1000_adapter *adapter = netdev_priv(netdev);
 	struct e1000_hw *hw = &adapter->hw;
 
 	if(ecmd->autoneg == AUTONEG_ENABLE) {
 		hw->autoneg = 1;
-		hw->autoneg_advertised = 0x002F;
-		ecmd->advertising = 0x002F;
+		if(hw->media_type == e1000_media_type_fiber)
+			hw->autoneg_advertised = ADVERTISED_1000baseT_Full |
+				     ADVERTISED_FIBRE |
+				     ADVERTISED_Autoneg;
+		else 
+			hw->autoneg_advertised = ADVERTISED_10baseT_Half |
+						  ADVERTISED_10baseT_Full |
+						  ADVERTISED_100baseT_Half |
+						  ADVERTISED_100baseT_Full |
+						  ADVERTISED_1000baseT_Full|
+						  ADVERTISED_Autoneg |
+						  ADVERTISED_TP;
+		ecmd->advertising = hw->autoneg_advertised;
 	} else
 		if(e1000_set_spd_dplx(adapter, ecmd->speed + ecmd->duplex))
 			return -EINVAL;
@@ -206,7 +217,7 @@ static void
 e1000_get_pauseparam(struct net_device *netdev,
                      struct ethtool_pauseparam *pause)
 {
-	struct e1000_adapter *adapter = netdev->priv;
+	struct e1000_adapter *adapter = netdev_priv(netdev);
 	struct e1000_hw *hw = &adapter->hw;
 
 	pause->autoneg = 
@@ -226,7 +237,7 @@ static int
 e1000_set_pauseparam(struct net_device *netdev,
                      struct ethtool_pauseparam *pause)
 {
-	struct e1000_adapter *adapter = netdev->priv;
+	struct e1000_adapter *adapter = netdev_priv(netdev);
 	struct e1000_hw *hw = &adapter->hw;
 	
 	adapter->fc_autoneg = pause->autoneg;
@@ -259,14 +270,14 @@ e1000_set_pauseparam(struct net_device *
 static uint32_t
 e1000_get_rx_csum(struct net_device *netdev)
 {
-	struct e1000_adapter *adapter = netdev->priv;
+	struct e1000_adapter *adapter = netdev_priv(netdev);
 	return adapter->rx_csum;
 }
 
 static int
 e1000_set_rx_csum(struct net_device *netdev, uint32_t data)
 {
-	struct e1000_adapter *adapter = netdev->priv;
+	struct e1000_adapter *adapter = netdev_priv(netdev);
 	adapter->rx_csum = data;
 
 	if(netif_running(netdev)) {
@@ -286,7 +297,7 @@ e1000_get_tx_csum(struct net_device *net
 static int
 e1000_set_tx_csum(struct net_device *netdev, uint32_t data)
 {
-	struct e1000_adapter *adapter = netdev->priv;
+	struct e1000_adapter *adapter = netdev_priv(netdev);
 
 	if(adapter->hw.mac_type < e1000_82543) {
 		if (!data)
@@ -306,8 +317,8 @@ e1000_set_tx_csum(struct net_device *net
 static int
 e1000_set_tso(struct net_device *netdev, uint32_t data)
 {
-	struct e1000_adapter *adapter = netdev->priv;
-	if ((adapter->hw.mac_type < e1000_82544) ||
+	struct e1000_adapter *adapter = netdev_priv(netdev);
+	if((adapter->hw.mac_type < e1000_82544) ||
 	    (adapter->hw.mac_type == e1000_82547)) 
 		return data ? -EINVAL : 0;
 
@@ -322,14 +333,14 @@ e1000_set_tso(struct net_device *netdev,
 static uint32_t
 e1000_get_msglevel(struct net_device *netdev)
 {
-	struct e1000_adapter *adapter = netdev->priv;
+	struct e1000_adapter *adapter = netdev_priv(netdev);
 	return adapter->msg_enable;
 }
 
 static void
 e1000_set_msglevel(struct net_device *netdev, uint32_t data)
 {
-	struct e1000_adapter *adapter = netdev->priv;
+	struct e1000_adapter *adapter = netdev_priv(netdev);
 	adapter->msg_enable = data;
 }
 
@@ -344,7 +355,7 @@ static void
 e1000_get_regs(struct net_device *netdev,
 	       struct ethtool_regs *regs, void *p)
 {
-	struct e1000_adapter *adapter = netdev->priv;
+	struct e1000_adapter *adapter = netdev_priv(netdev);
 	struct e1000_hw *hw = &adapter->hw;
 	uint32_t *regs_buff = p;
 	uint16_t phy_data;
@@ -432,7 +443,7 @@ e1000_get_regs(struct net_device *netdev
 static int
 e1000_get_eeprom_len(struct net_device *netdev)
 {
-	struct e1000_adapter *adapter = netdev->priv;
+	struct e1000_adapter *adapter = netdev_priv(netdev);
 	return adapter->hw.eeprom.word_size * 2;
 }
 
@@ -440,7 +451,7 @@ static int
 e1000_get_eeprom(struct net_device *netdev,
                       struct ethtool_eeprom *eeprom, uint8_t *bytes)
 {
-	struct e1000_adapter *adapter = netdev->priv;
+	struct e1000_adapter *adapter = netdev_priv(netdev);
 	struct e1000_hw *hw = &adapter->hw;
 	uint16_t *eeprom_buff;
 	int first_word, last_word;
@@ -486,7 +497,7 @@ static int
 e1000_set_eeprom(struct net_device *netdev,
                       struct ethtool_eeprom *eeprom, uint8_t *bytes)
 {
-	struct e1000_adapter *adapter = netdev->priv;
+	struct e1000_adapter *adapter = netdev_priv(netdev);
 	struct e1000_hw *hw = &adapter->hw;
 	uint16_t *eeprom_buff;
 	void *ptr;
@@ -547,7 +558,7 @@ static void
 e1000_get_drvinfo(struct net_device *netdev,
                        struct ethtool_drvinfo *drvinfo)
 {
-	struct e1000_adapter *adapter = netdev->priv;
+	struct e1000_adapter *adapter = netdev_priv(netdev);
 
 	strncpy(drvinfo->driver,  e1000_driver_name, 32);
 	strncpy(drvinfo->version, e1000_driver_version, 32);
@@ -563,7 +574,7 @@ static void
 e1000_get_ringparam(struct net_device *netdev,
                     struct ethtool_ringparam *ring)
 {
-	struct e1000_adapter *adapter = netdev->priv;
+	struct e1000_adapter *adapter = netdev_priv(netdev);
 	e1000_mac_type mac_type = adapter->hw.mac_type;
 	struct e1000_desc_ring *txdr = &adapter->tx_ring;
 	struct e1000_desc_ring *rxdr = &adapter->rx_ring;
@@ -584,7 +595,7 @@ static int 
 e1000_set_ringparam(struct net_device *netdev,
                     struct ethtool_ringparam *ring)
 {
-	struct e1000_adapter *adapter = netdev->priv;
+	struct e1000_adapter *adapter = netdev_priv(netdev);
 	e1000_mac_type mac_type = adapter->hw.mac_type;
 	struct e1000_desc_ring *txdr = &adapter->tx_ring;
 	struct e1000_desc_ring *rxdr = &adapter->rx_ring;
@@ -651,6 +662,9 @@ err_setup_rx:
 		E1000_WRITE_REG(&adapter->hw, R, (test[pat] & W));             \
 		value = E1000_READ_REG(&adapter->hw, R);                       \
 		if(value != (test[pat] & W & M)) {                             \
+			DPRINTK(DRV, ERR, "pattern test reg %04X failed: got " \
+			        "0x%08X expected 0x%08X\n",                    \
+			        E1000_##R, value, (test[pat] & W & M));        \
 			*data = (adapter->hw.mac_type < e1000_82543) ?         \
 				E1000_82542_##R : E1000_##R;                   \
 			return 1;                                              \
@@ -663,7 +677,9 @@ err_setup_rx:
 	uint32_t value;                                                        \
 	E1000_WRITE_REG(&adapter->hw, R, W & M);                               \
 	value = E1000_READ_REG(&adapter->hw, R);                               \
-	if ((W & M) != (value & M)) {                                          \
+	if((W & M) != (value & M)) {                                          \
+		DPRINTK(DRV, ERR, "set/check reg %04X test failed: got 0x%08X "\
+		        "expected 0x%08X\n", E1000_##R, (value & M), (W & M)); \
 		*data = (adapter->hw.mac_type < e1000_82543) ?                 \
 			E1000_82542_##R : E1000_##R;                           \
 		return 1;                                                      \
@@ -673,18 +689,33 @@ err_setup_rx:
 static int
 e1000_reg_test(struct e1000_adapter *adapter, uint64_t *data)
 {
-	uint32_t value;
-	uint32_t i;
+	uint32_t value, before, after;
+	uint32_t i, toggle;
 
 	/* The status register is Read Only, so a write should fail.
 	 * Some bits that get toggled are ignored.
 	 */
-	value = (E1000_READ_REG(&adapter->hw, STATUS) & (0xFFFFF833));
-	E1000_WRITE_REG(&adapter->hw, STATUS, (0xFFFFFFFF));
-	if(value != (E1000_READ_REG(&adapter->hw, STATUS) & (0xFFFFF833))) {
+        switch (adapter->hw.mac_type) {
+	case e1000_82573:
+		toggle = 0x7FFFF033;
+		break;
+	default:
+		toggle = 0xFFFFF833;
+		break;
+	}
+
+	before = E1000_READ_REG(&adapter->hw, STATUS);
+	value = (E1000_READ_REG(&adapter->hw, STATUS) & toggle);
+	E1000_WRITE_REG(&adapter->hw, STATUS, toggle);
+	after = E1000_READ_REG(&adapter->hw, STATUS) & toggle;
+	if(value != after) {
+		DPRINTK(DRV, ERR, "failed STATUS register test got: "
+		        "0x%08X expected: 0x%08X\n", after, value);
 		*data = 1;
 		return 1;
 	}
+	/* restore previous status */
+	E1000_WRITE_REG(&adapter->hw, STATUS, before);
 
 	REG_PATTERN_TEST(FCAL, 0xFFFFFFFF, 0xFFFFFFFF);
 	REG_PATTERN_TEST(FCAH, 0x0000FFFF, 0xFFFFFFFF);
@@ -766,7 +797,7 @@ e1000_test_intr(int irq,
 		struct pt_regs *regs)
 {
 	struct net_device *netdev = (struct net_device *) data;
-	struct e1000_adapter *adapter = netdev->priv;
+	struct e1000_adapter *adapter = netdev_priv(netdev);
 
 	adapter->test_icr |= E1000_READ_REG(&adapter->hw, ICR);
 
@@ -1214,6 +1245,7 @@ e1000_set_phy_loopback(struct e1000_adap
 	case e1000_82541_rev_2:
 	case e1000_82547:
 	case e1000_82547_rev_2:
+	case e1000_82573:
 		return e1000_integrated_phy_loopback(adapter);
 		break;
 
@@ -1422,7 +1454,7 @@ static void
 e1000_diag_test(struct net_device *netdev,
 		   struct ethtool_test *eth_test, uint64_t *data)
 {
-	struct e1000_adapter *adapter = netdev->priv;
+	struct e1000_adapter *adapter = netdev_priv(netdev);
 	boolean_t if_running = netif_running(netdev);
 
 	if(eth_test->flags == ETH_TEST_FL_OFFLINE) {
@@ -1482,7 +1514,7 @@ e1000_diag_test(struct net_device *netde
 static void
 e1000_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
 {
-	struct e1000_adapter *adapter = netdev->priv;
+	struct e1000_adapter *adapter = netdev_priv(netdev);
 	struct e1000_hw *hw = &adapter->hw;
 
 	switch(adapter->hw.device_id) {
@@ -1527,7 +1559,7 @@ e1000_get_wol(struct net_device *netdev,
 static int
 e1000_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
 {
-	struct e1000_adapter *adapter = netdev->priv;
+	struct e1000_adapter *adapter = netdev_priv(netdev);
 	struct e1000_hw *hw = &adapter->hw;
 
 	switch(adapter->hw.device_id) {
@@ -1588,22 +1620,31 @@ e1000_led_blink_callback(unsigned long d
 static int
 e1000_phys_id(struct net_device *netdev, uint32_t data)
 {
-	struct e1000_adapter *adapter = netdev->priv;
+	struct e1000_adapter *adapter = netdev_priv(netdev);
 
 	if(!data || data > (uint32_t)(MAX_SCHEDULE_TIMEOUT / HZ))
 		data = (uint32_t)(MAX_SCHEDULE_TIMEOUT / HZ);
 
-	if(!adapter->blink_timer.function) {
-		init_timer(&adapter->blink_timer);
-		adapter->blink_timer.function = e1000_led_blink_callback;
-		adapter->blink_timer.data = (unsigned long) adapter;
+	if(adapter->hw.mac_type < e1000_82573) {
+		if(!adapter->blink_timer.function) {
+			init_timer(&adapter->blink_timer);
+			adapter->blink_timer.function = e1000_led_blink_callback;
+			adapter->blink_timer.data = (unsigned long) adapter;
+		}
+		e1000_setup_led(&adapter->hw);
+		mod_timer(&adapter->blink_timer, jiffies);
+		msleep_interruptible(data * 1000);
+		del_timer_sync(&adapter->blink_timer);
+	}
+	else {
+		E1000_WRITE_REG(&adapter->hw, LEDCTL, (E1000_LEDCTL_LED2_BLINK_RATE |
+			E1000_LEDCTL_LED1_BLINK | E1000_LEDCTL_LED2_BLINK | 
+			(E1000_LEDCTL_MODE_LED_ON << E1000_LEDCTL_LED2_MODE_SHIFT) |
+			(E1000_LEDCTL_MODE_LINK_ACTIVITY << E1000_LEDCTL_LED1_MODE_SHIFT) |
+			(E1000_LEDCTL_MODE_LED_OFF << E1000_LEDCTL_LED0_MODE_SHIFT)));
+		msleep_interruptible(data * 1000);
 	}
 
-	e1000_setup_led(&adapter->hw);
-	mod_timer(&adapter->blink_timer, jiffies);
-
-	msleep_interruptible(data * 1000);
-	del_timer_sync(&adapter->blink_timer);
 	e1000_led_off(&adapter->hw);
 	clear_bit(E1000_LED_ON, &adapter->led_status);
 	e1000_cleanup_led(&adapter->hw);
@@ -1614,7 +1655,7 @@ e1000_phys_id(struct net_device *netdev,
 static int
 e1000_nway_reset(struct net_device *netdev)
 {
-	struct e1000_adapter *adapter = netdev->priv;
+	struct e1000_adapter *adapter = netdev_priv(netdev);
 	if(netif_running(netdev)) {
 		e1000_down(adapter);
 		e1000_up(adapter);
@@ -1632,7 +1673,7 @@ static void 
 e1000_get_ethtool_stats(struct net_device *netdev, 
 		struct ethtool_stats *stats, uint64_t *data)
 {
-	struct e1000_adapter *adapter = netdev->priv;
+	struct e1000_adapter *adapter = netdev_priv(netdev);
 	int i;
 
 	e1000_update_stats(adapter);
diff --git a/drivers/net/e1000/e1000_hw.c b/drivers/net/e1000/e1000_hw.c
--- a/drivers/net/e1000/e1000_hw.c
+++ b/drivers/net/e1000/e1000_hw.c
@@ -354,18 +354,27 @@ e1000_set_media_type(struct e1000_hw *hw
         hw->media_type = e1000_media_type_internal_serdes;
         break;
     default:
-        if(hw->mac_type >= e1000_82543) {
+        switch (hw->mac_type) {
+        case e1000_82542_rev2_0:
+        case e1000_82542_rev2_1:
+            hw->media_type = e1000_media_type_fiber;
+            break;
+        case e1000_82573:
+            /* The STATUS_TBIMODE bit is reserved or reused for the this
+             * device.
+             */
+            hw->media_type = e1000_media_type_copper;
+            break;
+        default:
             status = E1000_READ_REG(hw, STATUS);
-            if(status & E1000_STATUS_TBIMODE) {
+            if (status & E1000_STATUS_TBIMODE) {
                 hw->media_type = e1000_media_type_fiber;
                 /* tbi_compatibility not valid on fiber */
                 hw->tbi_compatibility_en = FALSE;
             } else {
                 hw->media_type = e1000_media_type_copper;
             }
-        } else {
-            /* This is an 82542 (fiber only) */
-            hw->media_type = e1000_media_type_fiber;
+            break;
         }
     }
 }
@@ -1189,9 +1198,9 @@ e1000_copper_link_igp_setup(struct e1000
         ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL, phy_data);
         if(ret_val)
             return ret_val;
-        }
+    }
 
-   return E1000_SUCCESS;
+    return E1000_SUCCESS;
 }
 
 
diff --git a/drivers/net/e1000/e1000_hw.h b/drivers/net/e1000/e1000_hw.h
--- a/drivers/net/e1000/e1000_hw.h
+++ b/drivers/net/e1000/e1000_hw.h
@@ -66,6 +66,7 @@ typedef enum {
     e1000_eeprom_spi,
     e1000_eeprom_microwire,
     e1000_eeprom_flash,
+    e1000_eeprom_none, /* No NVM support */
     e1000_num_eeprom_types
 } e1000_eeprom_type;
 
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -29,6 +29,8 @@
 #include "e1000.h"
 
 /* Change Log
+ * 6.0.58       4/20/05
+ *   o Accepted ethtool cleanup patch from Stephen Hemminger 
  * 6.0.44+	2/15/05
  *   o applied Anton's patch to resolve tx hang in hardware
  *   o Applied Andrew Mortons patch - e1000 stops working after resume
@@ -41,9 +43,9 @@ char e1000_driver_string[] = "Intel(R) P
 #else
 #define DRIVERNAPI "-NAPI"
 #endif
-#define DRV_VERSION "6.0.54-k2"DRIVERNAPI
+#define DRV_VERSION		"6.0.60-k2"DRIVERNAPI
 char e1000_driver_version[] = DRV_VERSION;
-char e1000_copyright[] = "Copyright (c) 1999-2004 Intel Corporation.";
+char e1000_copyright[] = "Copyright (c) 1999-2005 Intel Corporation.";
 
 /* e1000_pci_tbl - PCI Device ID Table
  *
@@ -160,7 +162,6 @@ static void e1000_vlan_rx_add_vid(struct
 static void e1000_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid);
 static void e1000_restore_vlan(struct e1000_adapter *adapter);
 
-static int e1000_notify_reboot(struct notifier_block *, unsigned long event, void *ptr);
 static int e1000_suspend(struct pci_dev *pdev, uint32_t state);
 #ifdef CONFIG_PM
 static int e1000_resume(struct pci_dev *pdev);
@@ -171,12 +172,6 @@ static int e1000_resume(struct pci_dev *
 static void e1000_netpoll (struct net_device *netdev);
 #endif
 
-struct notifier_block e1000_notifier_reboot = {
-	.notifier_call	= e1000_notify_reboot,
-	.next		= NULL,
-	.priority	= 0
-};
-
 /* Exported from other modules */
 
 extern void e1000_check_options(struct e1000_adapter *adapter);
@@ -219,9 +214,7 @@ e1000_init_module(void)
 	printk(KERN_INFO "%s\n", e1000_copyright);
 
 	ret = pci_module_init(&e1000_driver);
-	if(ret >= 0) {
-		register_reboot_notifier(&e1000_notifier_reboot);
-	}
+
 	return ret;
 }
 
@@ -237,7 +230,6 @@ module_init(e1000_init_module);
 static void __exit
 e1000_exit_module(void)
 {
-	unregister_reboot_notifier(&e1000_notifier_reboot);
 	pci_unregister_driver(&e1000_driver);
 }
 
@@ -517,7 +509,7 @@ e1000_probe(struct pci_dev *pdev,
 	SET_NETDEV_DEV(netdev, &pdev->dev);
 
 	pci_set_drvdata(pdev, netdev);
-	adapter = netdev->priv;
+	adapter = netdev_priv(netdev);
 	adapter->netdev = netdev;
 	adapter->pdev = pdev;
 	adapter->hw.back = adapter;
@@ -738,7 +730,7 @@ static void __devexit
 e1000_remove(struct pci_dev *pdev)
 {
 	struct net_device *netdev = pci_get_drvdata(pdev);
-	struct e1000_adapter *adapter = netdev->priv;
+	struct e1000_adapter *adapter = netdev_priv(netdev);
 	uint32_t manc, swsm;
 
 	flush_scheduled_work();
@@ -871,7 +863,7 @@ e1000_sw_init(struct e1000_adapter *adap
 static int
 e1000_open(struct net_device *netdev)
 {
-	struct e1000_adapter *adapter = netdev->priv;
+	struct e1000_adapter *adapter = netdev_priv(netdev);
 	int err;
 
 	/* allocate transmit descriptors */
@@ -919,7 +911,7 @@ err_setup_tx:
 static int
 e1000_close(struct net_device *netdev)
 {
-	struct e1000_adapter *adapter = netdev->priv;
+	struct e1000_adapter *adapter = netdev_priv(netdev);
 
 	e1000_down(adapter);
 
@@ -1599,7 +1591,7 @@ e1000_leave_82542_rst(struct e1000_adapt
 static int
 e1000_set_mac(struct net_device *netdev, void *p)
 {
-	struct e1000_adapter *adapter = netdev->priv;
+	struct e1000_adapter *adapter = netdev_priv(netdev);
 	struct sockaddr *addr = p;
 
 	if(!is_valid_ether_addr(addr->sa_data))
@@ -1634,7 +1626,7 @@ e1000_set_mac(struct net_device *netdev,
 static void
 e1000_set_multi(struct net_device *netdev)
 {
-	struct e1000_adapter *adapter = netdev->priv;
+	struct e1000_adapter *adapter = netdev_priv(netdev);
 	struct e1000_hw *hw = &adapter->hw;
 	struct dev_mc_list *mc_ptr;
 	unsigned long flags;
@@ -2213,7 +2205,7 @@ e1000_transfer_dhcp_info(struct e1000_ad
 static int
 e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 {
-	struct e1000_adapter *adapter = netdev->priv;
+	struct e1000_adapter *adapter = netdev_priv(netdev);
 	unsigned int first, max_per_txd = E1000_MAX_DATA_PER_TXD;
 	unsigned int max_txd_pwr = E1000_MAX_TXD_PWR;
 	unsigned int tx_flags = 0;
@@ -2307,6 +2299,7 @@ e1000_xmit_frame(struct sk_buff *skb, st
 	tso = e1000_tso(adapter, skb);
 	if (tso < 0) {
 		dev_kfree_skb_any(skb);
+		spin_unlock_irqrestore(&adapter->tx_lock, flags);
 		return NETDEV_TX_OK;
 	}
 
@@ -2343,7 +2336,7 @@ e1000_xmit_frame(struct sk_buff *skb, st
 static void
 e1000_tx_timeout(struct net_device *netdev)
 {
-	struct e1000_adapter *adapter = netdev->priv;
+	struct e1000_adapter *adapter = netdev_priv(netdev);
 
 	/* Do the reset outside of interrupt context */
 	schedule_work(&adapter->tx_timeout_task);
@@ -2352,7 +2345,7 @@ e1000_tx_timeout(struct net_device *netd
 static void
 e1000_tx_timeout_task(struct net_device *netdev)
 {
-	struct e1000_adapter *adapter = netdev->priv;
+	struct e1000_adapter *adapter = netdev_priv(netdev);
 
 	e1000_down(adapter);
 	e1000_up(adapter);
@@ -2369,7 +2362,7 @@ e1000_tx_timeout_task(struct net_device 
 static struct net_device_stats *
 e1000_get_stats(struct net_device *netdev)
 {
-	struct e1000_adapter *adapter = netdev->priv;
+	struct e1000_adapter *adapter = netdev_priv(netdev);
 
 	e1000_update_stats(adapter);
 	return &adapter->net_stats;
@@ -2386,7 +2379,7 @@ e1000_get_stats(struct net_device *netde
 static int
 e1000_change_mtu(struct net_device *netdev, int new_mtu)
 {
-	struct e1000_adapter *adapter = netdev->priv;
+	struct e1000_adapter *adapter = netdev_priv(netdev);
 	int max_frame = new_mtu + ENET_HEADER_SIZE + ETHERNET_FCS_SIZE;
 
 	if((max_frame < MINIMUM_ETHERNET_FRAME_SIZE) ||
@@ -2597,7 +2590,7 @@ static irqreturn_t
 e1000_intr(int irq, void *data, struct pt_regs *regs)
 {
 	struct net_device *netdev = data;
-	struct e1000_adapter *adapter = netdev->priv;
+	struct e1000_adapter *adapter = netdev_priv(netdev);
 	struct e1000_hw *hw = &adapter->hw;
 	uint32_t icr = E1000_READ_REG(hw, ICR);
 #ifndef CONFIG_E1000_NAPI
@@ -2660,7 +2653,7 @@ e1000_intr(int irq, void *data, struct p
 static int
 e1000_clean(struct net_device *netdev, int *budget)
 {
-	struct e1000_adapter *adapter = netdev->priv;
+	struct e1000_adapter *adapter = netdev_priv(netdev);
 	int work_to_do = min(*budget, netdev->quota);
 	int tx_cleaned;
 	int work_done = 0;
@@ -2671,8 +2664,8 @@ e1000_clean(struct net_device *netdev, i
 	*budget -= work_done;
 	netdev->quota -= work_done;
 	
-	/* If no Tx and no Rx work done, exit the polling mode */
 	if ((!tx_cleaned && (work_done == 0)) || !netif_running(netdev)) {
+	/* If no Tx and not enough Rx work done, exit the polling mode */
 		netif_rx_complete(netdev);
 		e1000_irq_enable(adapter);
 		return 0;
@@ -2768,13 +2761,13 @@ e1000_clean_tx_irq(struct e1000_adapter 
 			i = tx_ring->next_to_clean;
 			eop = tx_ring->buffer_info[i].next_to_watch;
 			eop_desc = E1000_TX_DESC(*tx_ring, eop);
-			DPRINTK(TX_ERR, ERR, "Detected Tx Unit Hang\n"
+			DPRINTK(DRV, ERR, "Detected Tx Unit Hang\n"
 					"  TDH                  <%x>\n"
 					"  TDT                  <%x>\n"
 					"  next_to_use          <%x>\n"
 					"  next_to_clean        <%x>\n"
 					"buffer_info[next_to_clean]\n"
-					"  dma                  <%llx>\n"
+					"  dma                  <%zx>\n"
 					"  time_stamp           <%lx>\n"
 					"  next_to_watch        <%x>\n"
 					"  jiffies              <%lx>\n"
@@ -2993,7 +2986,7 @@ e1000_clean_rx_irq_ps(struct e1000_adapt
 
 	i = rx_ring->next_to_clean;
 	rx_desc = E1000_RX_DESC_PS(*rx_ring, i);
-	staterr = rx_desc->wb.middle.status_error;
+	staterr = le32_to_cpu(rx_desc->wb.middle.status_error);
 
 	while(staterr & E1000_RXD_STAT_DD) {
 		buffer_info = &rx_ring->buffer_info[i];
@@ -3064,16 +3057,16 @@ e1000_clean_rx_irq_ps(struct e1000_adapt
 #ifdef CONFIG_E1000_NAPI
 		if(unlikely(adapter->vlgrp && (staterr & E1000_RXD_STAT_VP))) {
 			vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
-				le16_to_cpu(rx_desc->wb.middle.vlan &
-					E1000_RXD_SPC_VLAN_MASK));
+				le16_to_cpu(rx_desc->wb.middle.vlan) &
+				E1000_RXD_SPC_VLAN_MASK);
 		} else {
 			netif_receive_skb(skb);
 		}
 #else /* CONFIG_E1000_NAPI */
 		if(unlikely(adapter->vlgrp && (staterr & E1000_RXD_STAT_VP))) {
 			vlan_hwaccel_rx(skb, adapter->vlgrp,
-				le16_to_cpu(rx_desc->wb.middle.vlan &
-					E1000_RXD_SPC_VLAN_MASK));
+				le16_to_cpu(rx_desc->wb.middle.vlan) &
+				E1000_RXD_SPC_VLAN_MASK);
 		} else {
 			netif_rx(skb);
 		}
@@ -3086,7 +3079,7 @@ next_desc:
 		if(unlikely(++i == rx_ring->count)) i = 0;
 
 		rx_desc = E1000_RX_DESC_PS(*rx_ring, i);
-		staterr = rx_desc->wb.middle.status_error;
+		staterr = le32_to_cpu(rx_desc->wb.middle.status_error);
 	}
 	rx_ring->next_to_clean = i;
 	adapter->alloc_rx_buf(adapter);
@@ -3370,11 +3363,12 @@ e1000_ioctl(struct net_device *netdev, s
 static int
 e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
 {
-	struct e1000_adapter *adapter = netdev->priv;
+	struct e1000_adapter *adapter = netdev_priv(netdev);
 	struct mii_ioctl_data *data = if_mii(ifr);
 	int retval;
 	uint16_t mii_reg;
 	uint16_t spddplx;
+	unsigned long flags;
 
 	if(adapter->hw.media_type != e1000_media_type_copper)
 		return -EOPNOTSUPP;
@@ -3384,22 +3378,29 @@ e1000_mii_ioctl(struct net_device *netde
 		data->phy_id = adapter->hw.phy_addr;
 		break;
 	case SIOCGMIIREG:
-		if (!capable(CAP_NET_ADMIN))
+		if(!capable(CAP_NET_ADMIN))
 			return -EPERM;
-		if (e1000_read_phy_reg(&adapter->hw, data->reg_num & 0x1F,
-				   &data->val_out))
+		spin_lock_irqsave(&adapter->stats_lock, flags);
+		if(e1000_read_phy_reg(&adapter->hw, data->reg_num & 0x1F,
+				   &data->val_out)) {
+			spin_unlock_irqrestore(&adapter->stats_lock, flags);
 			return -EIO;
+		}
+		spin_unlock_irqrestore(&adapter->stats_lock, flags);
 		break;
 	case SIOCSMIIREG:
-		if (!capable(CAP_NET_ADMIN))
+		if(!capable(CAP_NET_ADMIN))
 			return -EPERM;
-		if (data->reg_num & ~(0x1F))
+		if(data->reg_num & ~(0x1F))
 			return -EFAULT;
 		mii_reg = data->val_in;
-		if (e1000_write_phy_reg(&adapter->hw, data->reg_num,
-					mii_reg))
+		spin_lock_irqsave(&adapter->stats_lock, flags);
+		if(e1000_write_phy_reg(&adapter->hw, data->reg_num,
+					mii_reg)) {
+			spin_unlock_irqrestore(&adapter->stats_lock, flags);
 			return -EIO;
-		if (adapter->hw.phy_type == e1000_phy_m88) {
+		}
+		if(adapter->hw.phy_type == e1000_phy_m88) {
 			switch (data->reg_num) {
 			case PHY_CTRL:
 				if(mii_reg & MII_CR_POWER_DOWN)
@@ -3419,8 +3420,12 @@ e1000_mii_ioctl(struct net_device *netde
 						   HALF_DUPLEX;
 					retval = e1000_set_spd_dplx(adapter,
 								    spddplx);
-					if(retval)
+					if(retval) {
+						spin_unlock_irqrestore(
+							&adapter->stats_lock, 
+							flags);
 						return retval;
+					}
 				}
 				if(netif_running(adapter->netdev)) {
 					e1000_down(adapter);
@@ -3430,8 +3435,11 @@ e1000_mii_ioctl(struct net_device *netde
 				break;
 			case M88E1000_PHY_SPEC_CTRL:
 			case M88E1000_EXT_PHY_SPEC_CTRL:
-				if (e1000_phy_reset(&adapter->hw))
+				if(e1000_phy_reset(&adapter->hw)) {
+					spin_unlock_irqrestore(
+						&adapter->stats_lock, flags);
 					return -EIO;
+				}
 				break;
 			}
 		} else {
@@ -3447,6 +3455,7 @@ e1000_mii_ioctl(struct net_device *netde
 				break;
 			}
 		}
+		spin_unlock_irqrestore(&adapter->stats_lock, flags);
 		break;
 	default:
 		return -EOPNOTSUPP;
@@ -3503,7 +3512,7 @@ e1000_io_write(struct e1000_hw *hw, unsi
 static void
 e1000_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp)
 {
-	struct e1000_adapter *adapter = netdev->priv;
+	struct e1000_adapter *adapter = netdev_priv(netdev);
 	uint32_t ctrl, rctl;
 
 	e1000_irq_disable(adapter);
@@ -3543,7 +3552,7 @@ e1000_vlan_rx_register(struct net_device
 static void
 e1000_vlan_rx_add_vid(struct net_device *netdev, uint16_t vid)
 {
-	struct e1000_adapter *adapter = netdev->priv;
+	struct e1000_adapter *adapter = netdev_priv(netdev);
 	uint32_t vfta, index;
 	if((adapter->hw.mng_cookie.status &
 		E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) &&
@@ -3559,7 +3568,7 @@ e1000_vlan_rx_add_vid(struct net_device 
 static void
 e1000_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid)
 {
-	struct e1000_adapter *adapter = netdev->priv;
+	struct e1000_adapter *adapter = netdev_priv(netdev);
 	uint32_t vfta, index;
 
 	e1000_irq_disable(adapter);
@@ -3600,6 +3609,13 @@ e1000_set_spd_dplx(struct e1000_adapter 
 {
 	adapter->hw.autoneg = 0;
 
+	/* Fiber NICs only allow 1000 gbps Full duplex */
+	if((adapter->hw.media_type == e1000_media_type_fiber) &&
+		spddplx != (SPEED_1000 + DUPLEX_FULL)) {
+		DPRINTK(PROBE, ERR, "Unsupported Speed/Duplex configuration\n");
+		return -EINVAL;
+	}
+
 	switch(spddplx) {
 	case SPEED_10 + DUPLEX_HALF:
 		adapter->hw.forced_speed_duplex = e1000_10_half;
@@ -3626,27 +3642,10 @@ e1000_set_spd_dplx(struct e1000_adapter 
 }
 
 static int
-e1000_notify_reboot(struct notifier_block *nb, unsigned long event, void *p)
-{
-	struct pci_dev *pdev = NULL;
-
-	switch(event) {
-	case SYS_DOWN:
-	case SYS_HALT:
-	case SYS_POWER_OFF:
-		while((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev))) {
-			if(pci_dev_driver(pdev) == &e1000_driver)
-				e1000_suspend(pdev, 3);
-		}
-	}
-	return NOTIFY_DONE;
-}
-
-static int
 e1000_suspend(struct pci_dev *pdev, uint32_t state)
 {
 	struct net_device *netdev = pci_get_drvdata(pdev);
-	struct e1000_adapter *adapter = netdev->priv;
+	struct e1000_adapter *adapter = netdev_priv(netdev);
 	uint32_t ctrl, ctrl_ext, rctl, manc, status, swsm;
 	uint32_t wufc = adapter->wol;
 
@@ -3739,12 +3738,12 @@ static int
 e1000_resume(struct pci_dev *pdev)
 {
 	struct net_device *netdev = pci_get_drvdata(pdev);
-	struct e1000_adapter *adapter = netdev->priv;
-	uint32_t manc, ret, swsm;
+	struct e1000_adapter *adapter = netdev_priv(netdev);
+	uint32_t manc, ret_val, swsm;
 
 	pci_set_power_state(pdev, 0);
 	pci_restore_state(pdev);
-	ret = pci_enable_device(pdev);
+	ret_val = pci_enable_device(pdev);
 	pci_set_master(pdev);
 
 	pci_enable_wake(pdev, 3, 0);
@@ -3787,9 +3786,10 @@ e1000_resume(struct pci_dev *pdev)
 static void
 e1000_netpoll(struct net_device *netdev)
 {
-	struct e1000_adapter *adapter = netdev->priv;
+	struct e1000_adapter *adapter = netdev_priv(netdev);
 	disable_irq(adapter->pdev->irq);
 	e1000_intr(adapter->pdev->irq, netdev, NULL);
+	e1000_clean_tx_irq(adapter);
 	enable_irq(adapter->pdev->irq);
 }
 #endif
diff --git a/drivers/net/e2100.c b/drivers/net/e2100.c
--- a/drivers/net/e2100.c
+++ b/drivers/net/e2100.c
@@ -162,12 +162,7 @@ struct net_device * __init e2100_probe(i
 	err = do_e2100_probe(dev);
 	if (err)
 		goto out;
-	err = register_netdev(dev);
-	if (err)
-		goto out1;
 	return dev;
-out1:
-	cleanup_card(dev);
 out:
 	free_netdev(dev);
 	return ERR_PTR(err);
@@ -286,6 +281,9 @@ static int __init e21_probe1(struct net_
 #endif
 	NS8390_init(dev, 0);
 
+	retval = register_netdev(dev);
+	if (retval)
+		goto out;
 	return 0;
 out:
 	release_region(ioaddr, E21_IO_EXTENT);
@@ -453,11 +451,8 @@ init_module(void)
 		dev->mem_start = mem[this_dev];
 		dev->mem_end = xcvr[this_dev];	/* low 4bits = xcvr sel. */
 		if (do_e2100_probe(dev) == 0) {
-			if (register_netdev(dev) == 0) {
-				dev_e21[found++] = dev;
-				continue;
-			}
-			cleanup_card(dev);
+			dev_e21[found++] = dev;
+			continue;
 		}
 		free_netdev(dev);
 		printk(KERN_WARNING "e2100.c: No E2100 card found (i/o = 0x%x).\n", io[this_dev]);
diff --git a/drivers/net/eepro.c b/drivers/net/eepro.c
--- a/drivers/net/eepro.c
+++ b/drivers/net/eepro.c
@@ -600,12 +600,7 @@ struct net_device * __init eepro_probe(i
 	err = do_eepro_probe(dev);
 	if (err)
 		goto out;
-	err = register_netdev(dev);
-	if (err)
-		goto out1;
 	return dev;
-out1:
-	release_region(dev->base_addr, EEPRO_IO_EXTENT);
 out:
 	free_netdev(dev);
 	return ERR_PTR(err);
@@ -758,6 +753,7 @@ static int __init eepro_probe1(struct ne
 	int i;
 	struct eepro_local *lp;
 	int ioaddr = dev->base_addr;
+	int err;
 
 	/* Grab the region so we can find another board if autoIRQ fails. */
 	if (!request_region(ioaddr, EEPRO_IO_EXTENT, DRV_NAME)) { 
@@ -873,10 +869,16 @@ static int __init eepro_probe1(struct ne
 
 	/* reset 82595 */
 	eepro_reset(ioaddr);
+
+	err = register_netdev(dev);
+	if (err)
+		goto err;
 	return 0;
 exit:
+	err = -ENODEV;
+err:
  	release_region(dev->base_addr, EEPRO_IO_EXTENT);
- 	return -ENODEV;
+ 	return err;
 }
 
 /* Open/initialize the board.  This is called (in the current kernel)
@@ -1834,11 +1836,8 @@ init_module(void)
 		dev->irq = irq[i];
 
 		if (do_eepro_probe(dev) == 0) {
-			if (register_netdev(dev) == 0) {
-				dev_eepro[n_eepro++] = dev;
-				continue;
-			}
-			release_region(dev->base_addr, EEPRO_IO_EXTENT);
+			dev_eepro[n_eepro++] = dev;
+			continue;
 		}
 		free_netdev(dev);
 		break;
diff --git a/drivers/net/eepro100.c b/drivers/net/eepro100.c
--- a/drivers/net/eepro100.c
+++ b/drivers/net/eepro100.c
@@ -1269,7 +1269,7 @@ speedo_init_rx_ring(struct net_device *d
 		if (skb == NULL)
 			break;			/* OK.  Just initially short of Rx bufs. */
 		skb->dev = dev;			/* Mark as being used by this device. */
-		rxf = (struct RxFD *)skb->tail;
+		rxf = (struct RxFD *)skb->data;
 		sp->rx_ringp[i] = rxf;
 		sp->rx_ring_dma[i] =
 			pci_map_single(sp->pdev, rxf,
@@ -1661,7 +1661,7 @@ static inline struct RxFD *speedo_rx_all
 		sp->rx_ringp[entry] = NULL;
 		return NULL;
 	}
-	rxf = sp->rx_ringp[entry] = (struct RxFD *)skb->tail;
+	rxf = sp->rx_ringp[entry] = (struct RxFD *)skb->data;
 	sp->rx_ring_dma[entry] =
 		pci_map_single(sp->pdev, rxf,
 					   PKT_BUF_SZ + sizeof(struct RxFD), PCI_DMA_FROMDEVICE);
@@ -1808,10 +1808,10 @@ speedo_rx(struct net_device *dev)
 
 #if 1 || USE_IP_CSUM
 				/* Packet is in one chunk -- we can copy + cksum. */
-				eth_copy_and_sum(skb, sp->rx_skbuff[entry]->tail, pkt_len, 0);
+				eth_copy_and_sum(skb, sp->rx_skbuff[entry]->data, pkt_len, 0);
 				skb_put(skb, pkt_len);
 #else
-				memcpy(skb_put(skb, pkt_len), sp->rx_skbuff[entry]->tail,
+				memcpy(skb_put(skb, pkt_len), sp->rx_skbuff[entry]->data,
 					   pkt_len);
 #endif
 				pci_dma_sync_single_for_device(sp->pdev, sp->rx_ring_dma[entry],
diff --git a/drivers/net/eexpress.c b/drivers/net/eexpress.c
--- a/drivers/net/eexpress.c
+++ b/drivers/net/eexpress.c
@@ -436,11 +436,8 @@ struct net_device * __init express_probe
 	netdev_boot_setup_check(dev);
 
 	err = do_express_probe(dev);
-	if (!err) {
-		err = register_netdev(dev);
-		if (!err)
-			return dev;
-	}
+	if (!err)
+		return dev;
 	free_netdev(dev);
 	return ERR_PTR(err);
 }
@@ -1205,7 +1202,8 @@ static int __init eexp_hw_probe(struct n
 	dev->set_multicast_list = &eexp_set_multicast;
 	dev->tx_timeout = eexp_timeout;
 	dev->watchdog_timeo = 2*HZ;
-	return 0;
+
+	return register_netdev(dev);
 }
 
 /*
@@ -1716,7 +1714,7 @@ int init_module(void)
 				break;
 			printk(KERN_NOTICE "eexpress.c: Module autoprobe not recommended, give io=xx.\n");
 		}
-		if (do_express_probe(dev) == 0 && register_netdev(dev) == 0) {
+		if (do_express_probe(dev) == 0) {
 			dev_eexp[this_dev] = dev;
 			found++;
 			continue;
diff --git a/drivers/net/epic100.c b/drivers/net/epic100.c
--- a/drivers/net/epic100.c
+++ b/drivers/net/epic100.c
@@ -1003,7 +1003,7 @@ static void epic_init_ring(struct net_de
 		skb->dev = dev;			/* Mark as being used by this device. */
 		skb_reserve(skb, 2);	/* 16 byte align the IP header. */
 		ep->rx_ring[i].bufaddr = pci_map_single(ep->pci_dev, 
-			skb->tail, ep->rx_buf_sz, PCI_DMA_FROMDEVICE);
+			skb->data, ep->rx_buf_sz, PCI_DMA_FROMDEVICE);
 		ep->rx_ring[i].rxstatus = cpu_to_le32(DescOwn);
 	}
 	ep->dirty_rx = (unsigned int)(i - RX_RING_SIZE);
@@ -1274,7 +1274,7 @@ static int epic_rx(struct net_device *de
 							    ep->rx_ring[entry].bufaddr,
 							    ep->rx_buf_sz,
 							    PCI_DMA_FROMDEVICE);
-				eth_copy_and_sum(skb, ep->rx_skbuff[entry]->tail, pkt_len, 0);
+				eth_copy_and_sum(skb, ep->rx_skbuff[entry]->data, pkt_len, 0);
 				skb_put(skb, pkt_len);
 				pci_dma_sync_single_for_device(ep->pci_dev,
 							       ep->rx_ring[entry].bufaddr,
@@ -1308,7 +1308,7 @@ static int epic_rx(struct net_device *de
 			skb->dev = dev;			/* Mark as being used by this device. */
 			skb_reserve(skb, 2);	/* Align IP on 16 byte boundaries */
 			ep->rx_ring[entry].bufaddr = pci_map_single(ep->pci_dev, 
-				skb->tail, ep->rx_buf_sz, PCI_DMA_FROMDEVICE);
+				skb->data, ep->rx_buf_sz, PCI_DMA_FROMDEVICE);
 			work_done++;
 		}
 		ep->rx_ring[entry].rxstatus = cpu_to_le32(DescOwn);
diff --git a/drivers/net/eql.c b/drivers/net/eql.c
--- a/drivers/net/eql.c
+++ b/drivers/net/eql.c
@@ -132,7 +132,7 @@ static struct net_device_stats *eql_get_
 #define eql_is_slave(dev)	((dev->flags & IFF_SLAVE) == IFF_SLAVE)
 #define eql_is_master(dev)	((dev->flags & IFF_MASTER) == IFF_MASTER)
 
-static void eql_kill_one_slave(slave_t *slave);
+static void eql_kill_one_slave(slave_queue_t *queue, slave_t *slave);
 
 static void eql_timer(unsigned long param)
 {
@@ -149,7 +149,7 @@ static void eql_timer(unsigned long para
 			if (slave->bytes_queued < 0)
 				slave->bytes_queued = 0;
 		} else {
-			eql_kill_one_slave(slave);
+			eql_kill_one_slave(&eql->queue, slave);
 		}
 
 	}
@@ -214,9 +214,10 @@ static int eql_open(struct net_device *d
 	return 0;
 }
 
-static void eql_kill_one_slave(slave_t *slave)
+static void eql_kill_one_slave(slave_queue_t *queue, slave_t *slave)
 {
 	list_del(&slave->list);
+	queue->num_slaves--;
 	slave->dev->flags &= ~IFF_SLAVE;
 	dev_put(slave->dev);
 	kfree(slave);
@@ -232,8 +233,7 @@ static void eql_kill_slave_queue(slave_q
 	list_for_each_safe(this, tmp, head) {
 		slave_t *s = list_entry(this, slave_t, list);
 
-		eql_kill_one_slave(s);
-		queue->num_slaves--;
+		eql_kill_one_slave(queue, s);
 	}
 
 	spin_unlock_bh(&queue->lock);
@@ -318,7 +318,7 @@ static slave_t *__eql_schedule_slaves(sl
 			}
 		} else {
 			/* We found a dead slave, kill it. */
-			eql_kill_one_slave(slave);
+			eql_kill_one_slave(queue, slave);
 		}
 	}
 	return best_slave;
@@ -393,7 +393,7 @@ static int __eql_insert_slave(slave_queu
 
 		duplicate_slave = __eql_find_slave_dev(queue, slave->dev);
 		if (duplicate_slave != 0)
-			eql_kill_one_slave(duplicate_slave);
+			eql_kill_one_slave(queue, duplicate_slave);
 
 		list_add(&slave->list, &queue->all_slaves);
 		queue->num_slaves++;
@@ -471,7 +471,7 @@ static int eql_emancipate(struct net_dev
 							      slave_dev);
 
 			if (slave) {
-				eql_kill_one_slave(slave);
+				eql_kill_one_slave(&eql->queue, slave);
 				ret = 0;
 			}
 		}
diff --git a/drivers/net/es3210.c b/drivers/net/es3210.c
--- a/drivers/net/es3210.c
+++ b/drivers/net/es3210.c
@@ -177,12 +177,7 @@ struct net_device * __init es_probe(int 
 	err = do_es_probe(dev);
 	if (err)
 		goto out;
-	err = register_netdev(dev);
-	if (err)
-		goto out1;
 	return dev;
-out1:
-	cleanup_card(dev);
 out:
 	free_netdev(dev);
 	return ERR_PTR(err);
@@ -310,6 +305,10 @@ static int __init es_probe1(struct net_d
 	dev->poll_controller = ei_poll;
 #endif
 	NS8390_init(dev, 0);
+
+	retval = register_netdev(dev);
+	if (retval)
+		goto out1;
 	return 0;
 out1:
 	free_irq(dev->irq, dev);
@@ -445,11 +444,8 @@ init_module(void)
 		dev->base_addr = io[this_dev];
 		dev->mem_start = mem[this_dev];
 		if (do_es_probe(dev) == 0) {
-			if (register_netdev(dev) == 0) {
-				dev_es3210[found++] = dev;
-				continue;
-			}
-			cleanup_card(dev);
+			dev_es3210[found++] = dev;
+			continue;
 		}
 		free_netdev(dev);
 		printk(KERN_WARNING "es3210.c: No es3210 card found (i/o = 0x%x).\n", io[this_dev]);
diff --git a/drivers/net/eth16i.c b/drivers/net/eth16i.c
--- a/drivers/net/eth16i.c
+++ b/drivers/net/eth16i.c
@@ -473,13 +473,7 @@ struct net_device * __init eth16i_probe(
 	err = do_eth16i_probe(dev);
 	if (err)
 		goto out;
-	err = register_netdev(dev);
-	if (err)
-		goto out1;
 	return dev;
-out1:
-	free_irq(dev->irq, dev);
-	release_region(dev->base_addr, ETH16I_IO_EXTENT);
 out:
 	free_netdev(dev);
 	return ERR_PTR(err);
@@ -569,7 +563,13 @@ static int __init eth16i_probe1(struct n
 	dev->tx_timeout 	= eth16i_timeout;
 	dev->watchdog_timeo	= TX_TIMEOUT;
 	spin_lock_init(&lp->lock);
+
+	retval = register_netdev(dev);
+	if (retval)
+		goto out1;
 	return 0;
+out1:
+	free_irq(dev->irq, dev);
 out:
 	release_region(ioaddr, ETH16I_IO_EXTENT);
 	return retval;
@@ -1462,12 +1462,8 @@ int init_module(void)
 		}
 
 		if (do_eth16i_probe(dev) == 0) {
-			if (register_netdev(dev) == 0) {
-				dev_eth16i[found++] = dev;
-				continue;
-			}
-			free_irq(dev->irq, dev);
-			release_region(dev->base_addr, ETH16I_IO_EXTENT);
+			dev_eth16i[found++] = dev;
+			continue;
 		}
 		printk(KERN_WARNING "eth16i.c No Eth16i card found (i/o = 0x%x).\n",
 		       io[this_dev]);
diff --git a/drivers/net/ewrk3.c b/drivers/net/ewrk3.c
--- a/drivers/net/ewrk3.c
+++ b/drivers/net/ewrk3.c
@@ -1308,15 +1308,9 @@ static int __init eisa_probe(struct net_
 	if (ioaddr < 0x1000)
 		goto out;
 
-	if (ioaddr == 0) {	/* Autoprobing */
-		iobase = EISA_SLOT_INC;		/* Get the first slot address */
-		i = 1;
-		maxSlots = MAX_EISA_SLOTS;
-	} else {		/* Probe a specific location */
-		iobase = ioaddr;
-		i = (ioaddr >> 12);
-		maxSlots = i + 1;
-	}
+	iobase = ioaddr;
+	i = (ioaddr >> 12);
+	maxSlots = i + 1;
 
 	for (i = 1; (i < maxSlots) && (dev != NULL); i++, iobase += EISA_SLOT_INC) {
 		if (EISA_signature(name, EISA_ID) == 0) {
diff --git a/drivers/net/fealnx.c b/drivers/net/fealnx.c
--- a/drivers/net/fealnx.c
+++ b/drivers/net/fealnx.c
@@ -1107,7 +1107,7 @@ static void allocate_rx_buffers(struct n
 
 		skb->dev = dev;	/* Mark as being used by this device. */
 		np->lack_rxbuf->skbuff = skb;
-		np->lack_rxbuf->buffer = pci_map_single(np->pci_dev, skb->tail,
+		np->lack_rxbuf->buffer = pci_map_single(np->pci_dev, skb->data,
 			np->rx_buf_sz, PCI_DMA_FROMDEVICE);
 		np->lack_rxbuf->status = RXOWN;
 		++np->really_rx_count;
@@ -1300,7 +1300,7 @@ static void init_ring(struct net_device 
 		++np->really_rx_count;
 		np->rx_ring[i].skbuff = skb;
 		skb->dev = dev;	/* Mark as being used by this device. */
-		np->rx_ring[i].buffer = pci_map_single(np->pci_dev, skb->tail,
+		np->rx_ring[i].buffer = pci_map_single(np->pci_dev, skb->data,
 			np->rx_buf_sz, PCI_DMA_FROMDEVICE);
 		np->rx_ring[i].status = RXOWN;
 		np->rx_ring[i].control |= RXIC;
@@ -1423,8 +1423,7 @@ static void reset_tx_descriptors(struct 
 		if (cur->skbuff) {
 			pci_unmap_single(np->pci_dev, cur->buffer,
 				cur->skbuff->len, PCI_DMA_TODEVICE);
-			dev_kfree_skb(cur->skbuff);
-			/* or dev_kfree_skb_irq(cur->skbuff); ? */
+			dev_kfree_skb_any(cur->skbuff);
 			cur->skbuff = NULL;
 		}
 		cur->status = 0;
@@ -1738,11 +1737,11 @@ static int netdev_rx(struct net_device *
 
 #if ! defined(__alpha__)
 				eth_copy_and_sum(skb, 
-					np->cur_rx->skbuff->tail, pkt_len, 0);
+					np->cur_rx->skbuff->data, pkt_len, 0);
 				skb_put(skb, pkt_len);
 #else
 				memcpy(skb_put(skb, pkt_len),
-					np->cur_rx->skbuff->tail, pkt_len);
+					np->cur_rx->skbuff->data, pkt_len);
 #endif
 				pci_dma_sync_single_for_device(np->pci_dev,
 							       np->cur_rx->buffer,
diff --git a/drivers/net/fmv18x.c b/drivers/net/fmv18x.c
deleted file mode 100644
--- a/drivers/net/fmv18x.c
+++ /dev/null
@@ -1,689 +0,0 @@
-/* fmv18x.c: A network device driver for the Fujitsu FMV-181/182/183/184.
-
-	Original: at1700.c (1993-94 by Donald Becker).
-		Copyright 1993 United States Government as represented by the
-		Director, National Security Agency.
-		The author may be reached as becker@scyld.com, or C/O
-			Scyld Computing Corporation
-			410 Severn Ave., Suite 210
-			Annapolis MD 21403
-
-	Modified by Yutaka TAMIYA (tamy@flab.fujitsu.co.jp)
-		Copyright 1994 Fujitsu Laboratories Ltd.
-	Special thanks to:
-		Masayoshi UTAKA (utaka@ace.yk.fujitsu.co.jp)
-			for testing this driver.
-		H. NEGISHI (agy, negishi@sun45.psd.cs.fujitsu.co.jp)
-			for suggestion of some program modification.
-		Masahiro SEKIGUCHI <seki@sysrap.cs.fujitsu.co.jp>
-			for suggestion of some program modification.
-		Kazutoshi MORIOKA (morioka@aurora.oaks.cs.fujitsu.co.jp)
-			for testing this driver.
-
-	This software may be used and distributed according to the terms
-	of the GNU General Public License, incorporated herein by reference.
-
-	This is a device driver for the Fujitsu FMV-181/182/183/184, which
-	is a straight-forward Fujitsu MB86965 implementation.
-
-  Sources:
-    at1700.c
-    The Fujitsu MB86965 datasheet.
-    The Fujitsu FMV-181/182 user's guide
-*/
-
-static const char version[] =
-	"fmv18x.c:v2.2.0 09/24/98  Yutaka TAMIYA (tamy@flab.fujitsu.co.jp)\n";
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/fcntl.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/in.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/spinlock.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/delay.h>
-#include <linux/bitops.h>
-
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/dma.h>
-
-#define DRV_NAME "fmv18x"
-
-static unsigned fmv18x_probe_list[] __initdata = {
-	0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x300, 0x340, 0
-};
-
-/* use 0 for production, 1 for verification, >2 for debug */
-#ifndef NET_DEBUG
-#define NET_DEBUG 1
-#endif
-static unsigned int net_debug = NET_DEBUG;
-
-typedef unsigned char uchar;
-
-/* Information that need to be kept for each board. */
-struct net_local {
-	struct net_device_stats stats;
-	long open_time;				/* Useless example local info. */
-	uint tx_started:1;			/* Number of packet on the Tx queue. */
-	uint tx_queue_ready:1;		/* Tx queue is ready to be sent. */
-	uint rx_started:1;			/* Packets are Rxing. */
-	uchar tx_queue;				/* Number of packet on the Tx queue. */
-	ushort tx_queue_len;		/* Current length of the Tx queue. */
-	spinlock_t lock;
-};
-
-
-/* Offsets from the base address. */
-#define STATUS			0
-#define TX_STATUS		0
-#define RX_STATUS		1
-#define TX_INTR			2		/* Bit-mapped interrupt enable registers. */
-#define RX_INTR			3
-#define TX_MODE			4
-#define RX_MODE			5
-#define CONFIG_0		6		/* Misc. configuration settings. */
-#define CONFIG_1		7
-/* Run-time register bank 2 definitions. */
-#define DATAPORT		8		/* Word-wide DMA or programmed-I/O dataport. */
-#define TX_START		10
-#define COL16CNTL		11		/* Controll Reg for 16 collisions */
-#define MODE13			13
-/* Fujitsu FMV-18x Card Configuration */
-#define	FJ_STATUS0		0x10
-#define	FJ_STATUS1		0x11
-#define	FJ_CONFIG0		0x12
-#define	FJ_CONFIG1		0x13
-#define	FJ_MACADDR		0x14	/* 0x14 - 0x19 */
-#define	FJ_BUFCNTL		0x1A
-#define	FJ_BUFDATA		0x1C
-#define FMV18X_IO_EXTENT	32
-
-/* Index to functions, as function prototypes. */
-
-static int fmv18x_probe1(struct net_device *dev, short ioaddr);
-static int net_open(struct net_device *dev);
-static int net_send_packet(struct sk_buff *skb, struct net_device *dev);
-static irqreturn_t net_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-static void net_rx(struct net_device *dev);
-static void net_timeout(struct net_device *dev);
-static int net_close(struct net_device *dev);
-static struct net_device_stats *net_get_stats(struct net_device *dev);
-static void set_multicast_list(struct net_device *dev);
-
-
-/* Check for a network adaptor of this type, and return '0' iff one exists.
-   If dev->base_addr == 0, probe all likely locations.
-   If dev->base_addr == 1, always return failure.
-   If dev->base_addr == 2, allocate space for the device and return success
-   (detachable devices only).
-   */
-
-static int io = 0x220;
-static int irq;
-
-struct net_device * __init fmv18x_probe(int unit)
-{
-	struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
-	unsigned *port;
-	int err = 0;
-
-	if (!dev)
-		return ERR_PTR(-ENODEV);
-
-	if (unit >= 0) {
-		sprintf(dev->name, "eth%d", unit);
-		netdev_boot_setup_check(dev);
-		io = dev->base_addr;
-		irq = dev->irq;
-	}
-
-	SET_MODULE_OWNER(dev);
-
-	if (io > 0x1ff) {	/* Check a single specified location. */
-		err = fmv18x_probe1(dev, io);
-	} else if (io != 0) {	/* Don't probe at all. */
-		err = -ENXIO;
-	} else {
-		for (port = fmv18x_probe_list; *port; port++)
-			if (fmv18x_probe1(dev, *port) == 0)
-				break;
-		if (!*port)
-			err = -ENODEV;
-	}
-	if (err)
-		goto out;
-	err = register_netdev(dev);
-	if (err)
-		goto out1;
-	return dev;
-out1:
-	free_irq(dev->irq, dev);
-	release_region(dev->base_addr, FMV18X_IO_EXTENT);
-out:
-	free_netdev(dev);
-	return ERR_PTR(err);
-}
-
-/* The Fujitsu datasheet suggests that the NIC be probed for by checking its
-   "signature", the default bit pattern after a reset.  This *doesn't* work --
-   there is no way to reset the bus interface without a complete power-cycle!
-
-   It turns out that ATI came to the same conclusion I did: the only thing
-   that can be done is checking a few bits and then diving right into MAC
-   address check. */
-
-static int __init fmv18x_probe1(struct net_device *dev, short ioaddr)
-{
-	char irqmap[4] = {3, 7, 10, 15};
-	char irqmap_pnp[8] = {3, 4, 5, 7, 9, 10, 11, 15};
-	unsigned int i, retval;
-	struct net_local *lp;
-
-	/* Resetting the chip doesn't reset the ISA interface, so don't bother.
-	   That means we have to be careful with the register values we probe for.
-	   */
-
-	if (!request_region(ioaddr, FMV18X_IO_EXTENT, DRV_NAME))
-		return -EBUSY;
-
-	dev->irq = irq;
-	dev->base_addr = ioaddr;
-
-	/* Check I/O address configuration and Fujitsu vendor code */
-	if (inb(ioaddr+FJ_MACADDR  ) != 0x00
-	||  inb(ioaddr+FJ_MACADDR+1) != 0x00
-	||  inb(ioaddr+FJ_MACADDR+2) != 0x0e) {
-		retval = -ENODEV;
-		goto out;
-	}
-
-	/* Check PnP mode for FMV-183/184/183A/184A. */
-	/* This PnP routine is very poor. IO and IRQ should be known. */
-	if (inb(ioaddr + FJ_STATUS1) & 0x20) {
-		for (i = 0; i < 8; i++) {
-			if (dev->irq == irqmap_pnp[i])
-				break;
-		}
-		if (i == 8) {
-			retval = -ENODEV;
-			goto out;
-		}
-	} else {
-		if (fmv18x_probe_list[inb(ioaddr + FJ_CONFIG0) & 0x07] != ioaddr)
-			return -ENODEV;
-		dev->irq = irqmap[(inb(ioaddr + FJ_CONFIG0)>>6) & 0x03];
-	}
-
-	/* Snarf the interrupt vector now. */
-	retval = request_irq(dev->irq, &net_interrupt, 0, DRV_NAME, dev);
-	if (retval) {
-		printk ("FMV-18x found at %#3x, but it's unusable due to a conflict on"
-				"IRQ %d.\n", ioaddr, dev->irq);
-		goto out;
-	}
-
-	printk("%s: FMV-18x found at %#3x, IRQ %d, address ", dev->name,
-		   ioaddr, dev->irq);
-
-	for(i = 0; i < 6; i++) {
-		unsigned char val = inb(ioaddr + FJ_MACADDR + i);
-		printk("%02x", val);
-		dev->dev_addr[i] = val;
-	}
-
-	/* "FJ_STATUS0" 12 bit 0x0400 means use regular 100 ohm 10baseT signals,
-	   rather than 150 ohm shielded twisted pair compensation.
-	   0x0000 == auto-sense the interface
-	   0x0800 == use TP interface
-	   0x1800 == use coax interface
-	   */
-	{
-		const char *porttype[] = {"auto-sense", "10baseT", "auto-sense", "10base2/5"};
-		ushort setup_value = inb(ioaddr + FJ_STATUS0);
-
-		switch( setup_value & 0x07 ){
-		case 0x01 /* 10base5 */:
-		case 0x02 /* 10base2 */: dev->if_port = 0x18; break;
-		case 0x04 /* 10baseT */: dev->if_port = 0x08; break;
-		default /* auto-sense*/: dev->if_port = 0x00; break;
-		}
-		printk(" %s interface.\n", porttype[(dev->if_port>>3) & 3]);
-	}
-
-	/* Initialize LAN Controller and LAN Card */
-	outb(0xda, ioaddr + CONFIG_0);	 /* Initialize LAN Controller */
-	outb(0x00, ioaddr + CONFIG_1);	 /* Stand by mode */
-	outb(0x00, ioaddr + FJ_CONFIG1); /* Disable IRQ of LAN Card */
-	outb(0x00, ioaddr + FJ_BUFCNTL); /* Reset ? I'm not sure (TAMIYA) */
-
-	/* wait for a while */
-	udelay(200);
-
-	/* Set the station address in bank zero. */
-	outb(0x00, ioaddr + CONFIG_1);
-	for (i = 0; i < 6; i++)
-		outb(dev->dev_addr[i], ioaddr + 8 + i);
-
-	/* Switch to bank 1 and set the multicast table to accept none. */
-	outb(0x04, ioaddr + CONFIG_1);
-	for (i = 0; i < 8; i++)
-		outb(0x00, ioaddr + 8 + i);
-
-	/* Switch to bank 2 and lock our I/O address. */
-	outb(0x08, ioaddr + CONFIG_1);
-	outb(dev->if_port, ioaddr + MODE13);
-	outb(0x00, ioaddr + COL16CNTL);
-
-	if (net_debug)
-		printk(version);
-
-	/* Initialize the device structure. */
-	dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
-	if (!dev->priv) {
-		retval = -ENOMEM;
-		goto out_irq;
-	}
-	memset(dev->priv, 0, sizeof(struct net_local));
-	lp = dev->priv;
-	spin_lock_init(&lp->lock);
-
-	dev->open		= net_open;
-	dev->stop		= net_close;
-	dev->hard_start_xmit	= net_send_packet;
-	dev->tx_timeout		= net_timeout;
-	dev->watchdog_timeo	= HZ/10;
-	dev->get_stats		= net_get_stats;
-	dev->set_multicast_list = set_multicast_list;
-	return 0;
-
-out_irq:
-	free_irq(dev->irq, dev);
-out:
-	release_region(ioaddr, FMV18X_IO_EXTENT);
-	return retval;
-}
-
-
-static int net_open(struct net_device *dev)
-{
-	struct net_local *lp = dev->priv;
-	int ioaddr = dev->base_addr;
-
-	/* Set the configuration register 0 to 32K 100ns. byte-wide memory,
-	   16 bit bus access, and two 4K Tx, enable the Rx and Tx. */
-	outb(0x5a, ioaddr + CONFIG_0);
-
-	/* Powerup and switch to register bank 2 for the run-time registers. */
-	outb(0xe8, ioaddr + CONFIG_1);
-
-	lp->tx_started = 0;
-	lp->tx_queue_ready = 1;
-	lp->rx_started = 0;
-	lp->tx_queue = 0;
-	lp->tx_queue_len = 0;
-
-	/* Clear Tx and Rx Status */
-	outb(0xff, ioaddr + TX_STATUS);
-	outb(0xff, ioaddr + RX_STATUS);
-	lp->open_time = jiffies;
-
-	netif_start_queue(dev);
-	
-	/* Enable the IRQ of the LAN Card */
-	outb(0x80, ioaddr + FJ_CONFIG1);
-
-	/* Enable both Tx and Rx interrupts */
-	outw(0x8182, ioaddr+TX_INTR);
-
-	return 0;
-}
-
-static void net_timeout(struct net_device *dev)
-{
-	struct net_local *lp = dev->priv;
-	int ioaddr = dev->base_addr;
-	unsigned long flags;
-	
-	
-	printk(KERN_WARNING "%s: transmit timed out with status %04x, %s?\n", dev->name,
-		   htons(inw(ioaddr + TX_STATUS)),
-		   inb(ioaddr + TX_STATUS) & 0x80
-		   ? "IRQ conflict" : "network cable problem");
-	printk(KERN_WARNING "%s: timeout registers: %04x %04x %04x %04x %04x %04x %04x %04x.\n",
-		   dev->name, htons(inw(ioaddr + 0)),
-		   htons(inw(ioaddr + 2)), htons(inw(ioaddr + 4)),
-		   htons(inw(ioaddr + 6)), htons(inw(ioaddr + 8)),
-		   htons(inw(ioaddr +10)), htons(inw(ioaddr +12)),
-		   htons(inw(ioaddr +14)));
-	printk(KERN_WARNING "eth card: %04x %04x\n",
-		htons(inw(ioaddr+FJ_STATUS0)),
-		htons(inw(ioaddr+FJ_CONFIG0)));
-	lp->stats.tx_errors++;
-	/* ToDo: We should try to restart the adaptor... */
-	spin_lock_irqsave(&lp->lock, flags);
-
-	/* Initialize LAN Controller and LAN Card */
-	outb(0xda, ioaddr + CONFIG_0);   /* Initialize LAN Controller */
-	outb(0x00, ioaddr + CONFIG_1);   /* Stand by mode */
-	outb(0x00, ioaddr + FJ_CONFIG1); /* Disable IRQ of LAN Card */
-	outb(0x00, ioaddr + FJ_BUFCNTL); /* Reset ? I'm not sure */
-	net_open(dev);
-	spin_unlock_irqrestore(&lp->lock, flags);
-
-	netif_wake_queue(dev);
-}
-
-static int net_send_packet(struct sk_buff *skb, struct net_device *dev)
-{
-	struct net_local *lp = dev->priv;
-	int ioaddr = dev->base_addr;
-	short length = skb->len;
-	unsigned char *buf;
-	unsigned long flags;
-
-	/* Block a transmit from overlapping.  */
-	
-	if (length > ETH_FRAME_LEN) {
-		if (net_debug)
-			printk("%s: Attempting to send a large packet (%d bytes).\n",
-				dev->name, length);
-		return 1;
-	}
-	
-	if (length < ETH_ZLEN) {
-		skb = skb_padto(skb, ETH_ZLEN);
-		if (skb == NULL)
-			return 0;
-		length = ETH_ZLEN;
-	}
-	buf = skb->data;
-	
-	if (net_debug > 4)
-		printk("%s: Transmitting a packet of length %lu.\n", dev->name,
-			   (unsigned long)skb->len);
-	/* We may not start transmitting unless we finish transferring
-	   a packet into the Tx queue. During executing the following
-	   codes we possibly catch a Tx interrupt. Thus we flag off
-	   tx_queue_ready, so that we prevent the interrupt routine
-	   (net_interrupt) to start transmitting. */
-	spin_lock_irqsave(&lp->lock, flags);
-	lp->tx_queue_ready = 0;
-	{
-		outw(length, ioaddr + DATAPORT);
-		outsw(ioaddr + DATAPORT, buf, (length + 1) >> 1);
-		lp->tx_queue++;
-		lp->tx_queue_len += length + 2;
-	}
-	lp->tx_queue_ready = 1;
-	spin_unlock_irqrestore(&lp->lock, flags);
-
-	if (lp->tx_started == 0) {
-		/* If the Tx is idle, always trigger a transmit. */
-		outb(0x80 | lp->tx_queue, ioaddr + TX_START);
-		lp->tx_queue = 0;
-		lp->tx_queue_len = 0;
-		dev->trans_start = jiffies;
-		lp->tx_started = 1;
-	} else if (lp->tx_queue_len >= 4096 - 1502) /* No room for a packet */
-		netif_stop_queue(dev);
-
-	dev_kfree_skb(skb);
-	return 0;
-}
-
-/* The typical workload of the driver:
-   Handle the network interface interrupts. */
-static irqreturn_t
-net_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
-	struct net_device *dev = dev_id;
-	struct net_local *lp;
-	int ioaddr, status;
-
-	ioaddr = dev->base_addr;
-	lp = dev->priv;
-	status = inw(ioaddr + TX_STATUS);
-	outw(status, ioaddr + TX_STATUS);
-
-	if (net_debug > 4)
-		printk("%s: Interrupt with status %04x.\n", dev->name, status);
-	if (lp->rx_started == 0 &&
-		(status & 0xff00 || (inb(ioaddr + RX_MODE) & 0x40) == 0)) {
-		/* Got a packet(s).
-		   We cannot execute net_rx more than once at the same time for
-		   the same device. During executing net_rx, we possibly catch a
-		   Tx interrupt. Thus we flag on rx_started, so that we prevent
-		   the interrupt routine (net_interrupt) to dive into net_rx
-		   again. */
-		lp->rx_started = 1;
-		outb(0x00, ioaddr + RX_INTR);	/* Disable RX intr. */
-		net_rx(dev);
-		outb(0x81, ioaddr + RX_INTR);	/* Enable  RX intr. */
-		lp->rx_started = 0;
-	}
-	if (status & 0x00ff) {
-		if (status & 0x02) {
-			/* More than 16 collisions occurred */
-			if (net_debug > 4)
-				printk("%s: 16 Collision occur during Txing.\n", dev->name);
-			/* Cancel sending a packet. */
-			outb(0x03, ioaddr + COL16CNTL);
-			lp->stats.collisions++;
-		}
-		if (status & 0x82) {
-			spin_lock(&lp->lock);
-			lp->stats.tx_packets++;
-			if (lp->tx_queue && lp->tx_queue_ready) {
-				outb(0x80 | lp->tx_queue, ioaddr + TX_START);
-				lp->tx_queue = 0;
-				lp->tx_queue_len = 0;
-				dev->trans_start = jiffies;
-				netif_wake_queue(dev);	/* Inform upper layers. */
-			} else {
-				lp->tx_started = 0;
-				netif_wake_queue(dev);	/* Inform upper layers. */
-			}
-			spin_unlock(&lp->lock);
-		}
-	}
-	return IRQ_RETVAL(status);
-}
-
-/* We have a good packet(s), get it/them out of the buffers. */
-static void net_rx(struct net_device *dev)
-{
-	struct net_local *lp = dev->priv;
-	int ioaddr = dev->base_addr;
-	int boguscount = 5;
-
-	while ((inb(ioaddr + RX_MODE) & 0x40) == 0) {
-		/* Clear PKT_RDY bit: by agy 19940922 */
-		/* outb(0x80, ioaddr + RX_STATUS); */
-		ushort status = inw(ioaddr + DATAPORT);
-
-		if (net_debug > 4)
-			printk("%s: Rxing packet mode %02x status %04x.\n",
-				   dev->name, inb(ioaddr + RX_MODE), status);
-#ifndef final_version
-		if (status == 0) {
-			outb(0x05, ioaddr + 14);
-			break;
-		}
-#endif
-
-		if ((status & 0xF0) != 0x20) {	/* There was an error. */
-			lp->stats.rx_errors++;
-			if (status & 0x08) lp->stats.rx_length_errors++;
-			if (status & 0x04) lp->stats.rx_frame_errors++;
-			if (status & 0x02) lp->stats.rx_crc_errors++;
-			if (status & 0x01) lp->stats.rx_over_errors++;
-		} else {
-			ushort pkt_len = inw(ioaddr + DATAPORT);
-			/* Malloc up new buffer. */
-			struct sk_buff *skb;
-
-			if (pkt_len > 1550) {
-				printk("%s: The FMV-18x claimed a very large packet, size %d.\n",
-					   dev->name, pkt_len);
-				outb(0x05, ioaddr + 14);
-				lp->stats.rx_errors++;
-				break;
-			}
-			skb = dev_alloc_skb(pkt_len+3);
-			if (skb == NULL) {
-				printk("%s: Memory squeeze, dropping packet (len %d).\n",
-					   dev->name, pkt_len);
-				outb(0x05, ioaddr + 14);
-				lp->stats.rx_dropped++;
-				break;
-			}
-			skb->dev = dev;
-			skb_reserve(skb,2);
-
-			insw(ioaddr + DATAPORT, skb_put(skb,pkt_len), (pkt_len + 1) >> 1);
-
-			if (net_debug > 5) {
-				int i;
-				printk("%s: Rxed packet of length %d: ", dev->name, pkt_len);
-				for (i = 0; i < 14; i++)
-					printk(" %02x", skb->data[i]);
-				printk(".\n");
-			}
-
-			skb->protocol=eth_type_trans(skb, dev);
-			netif_rx(skb);
-			dev->last_rx = jiffies;
-			lp->stats.rx_packets++;
-			lp->stats.rx_bytes += pkt_len;
-		}
-		if (--boguscount <= 0)
-			break;
-	}
-
-	/* If any worth-while packets have been received, dev_rint()
-	   has done a mark_bh(NET_BH) for us and will work on them
-	   when we get to the bottom-half routine. */
-	{
-		int i;
-		for (i = 0; i < 20; i++) {
-			if ((inb(ioaddr + RX_MODE) & 0x40) == 0x40)
-				break;
-			(void)inw(ioaddr + DATAPORT);				/* dummy status read */
-			outb(0x05, ioaddr + 14);
-		}
-
-		if (net_debug > 5 && i > 0)
-			printk("%s: Exint Rx packet with mode %02x after %d ticks.\n",
-				   dev->name, inb(ioaddr + RX_MODE), i);
-	}
-
-	return;
-}
-
-/* The inverse routine to net_open(). */
-static int net_close(struct net_device *dev)
-{
-	int ioaddr = dev->base_addr;
-
-	((struct net_local *)dev->priv)->open_time = 0;
-
-	netif_stop_queue(dev);
-	
-	/* Set configuration register 0 to disable Tx and Rx. */
-	outb(0xda, ioaddr + CONFIG_0);
-
-	/* Update the statistics -- ToDo. */
-
-	/* Power-down the chip.  Green, green, green! */
-	outb(0x00, ioaddr + CONFIG_1);
-
-	/* Set the ethernet adaptor disable IRQ */
-	outb(0x00, ioaddr + FJ_CONFIG1);
-
-	return 0;
-}
-
-/* Get the current statistics.	This may be called with the card open or
-   closed. */
-static struct net_device_stats *net_get_stats(struct net_device *dev)
-{
-	struct net_local *lp = dev->priv;
-	return &lp->stats;
-}
-
-/* Set or clear the multicast filter for this adaptor.
-   num_addrs == -1	Promiscuous mode, receive all packets
-   num_addrs == 0	Normal mode, clear multicast list
-   num_addrs > 0	Multicast mode, receive normal and MC packets, and do
-			best-effort filtering.
- */
- 
-static void set_multicast_list(struct net_device *dev)
-{
-	short ioaddr = dev->base_addr;
-	if (dev->mc_count || dev->flags&(IFF_PROMISC|IFF_ALLMULTI))
-	{
-		/*
-		 *	We must make the kernel realise we had to move
-		 *	into promisc mode or we start all out war on
-		 *	the cable. - AC
-		 */
-		dev->flags|=IFF_PROMISC;
-
-		outb(3, ioaddr + RX_MODE);	/* Enable promiscuous mode */
-	}
-	else
-		outb(2, ioaddr + RX_MODE);	/* Disable promiscuous, use normal mode */
-}
-
-#ifdef MODULE
-static struct net_device *dev_fmv18x;
-
-MODULE_PARM(io, "i");
-MODULE_PARM(irq, "i");
-MODULE_PARM(net_debug, "i");
-MODULE_PARM_DESC(io, "FMV-18X I/O address");
-MODULE_PARM_DESC(irq, "FMV-18X IRQ number");
-MODULE_PARM_DESC(net_debug, "FMV-18X debug level (0-1,5-6)");
-MODULE_LICENSE("GPL");
-
-int init_module(void)
-{
-	if (io == 0)
-		printk("fmv18x: You should not use auto-probing with insmod!\n");
-	dev_fmv18x = fmv18x_probe(-1);
-	if (IS_ERR(dev_fmv18x))
-		return PTR_ERR(dev_fmv18x);
-	return 0;
-}
-
-void
-cleanup_module(void)
-{
-	unregister_netdev(dev_fmv18x);
-	free_irq(dev_fmv18x->irq, dev_fmv18x);
-	release_region(dev_fmv18x->base_addr, FMV18X_IO_EXTENT);
-	free_netdev(dev_fmv18x);
-}
-#endif /* MODULE */
-
-/*
- * Local variables:
- *  compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c fmv18x.c"
- *  version-control: t
- *  kept-new-versions: 5
- *  tab-width: 4
- *  c-indent-level: 4
- * End:
- */
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -82,6 +82,9 @@
  *	0.31: 14 Nov 2004: ethtool support for getting/setting link
  *	                   capabilities.
  *	0.32: 16 Apr 2005: RX_ERROR4 handling added.
+ *	0.33: 16 May 2005: Support for MCP51 added.
+ *	0.34: 18 Jun 2005: Add DEV_NEED_LINKTIMER to all nForce nics.
+ *	0.35: 26 Jun 2005: Support for MCP55 added.
  *
  * Known bugs:
  * We suspect that on some hardware no TX done interrupts are generated.
@@ -93,7 +96,7 @@
  * DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few
  * superfluous timer interrupts from the nic.
  */
-#define FORCEDETH_VERSION		"0.32"
+#define FORCEDETH_VERSION		"0.35"
 #define DRV_NAME			"forcedeth"
 
 #include <linux/module.h>
@@ -2005,7 +2008,9 @@ static int __devinit nv_probe(struct pci
 	/* handle different descriptor versions */
 	if (pci_dev->device == PCI_DEVICE_ID_NVIDIA_NVENET_1 ||
 		pci_dev->device == PCI_DEVICE_ID_NVIDIA_NVENET_2 ||
-		pci_dev->device == PCI_DEVICE_ID_NVIDIA_NVENET_3)
+		pci_dev->device == PCI_DEVICE_ID_NVIDIA_NVENET_3 ||    
+		pci_dev->device == PCI_DEVICE_ID_NVIDIA_NVENET_12 ||
+		pci_dev->device == PCI_DEVICE_ID_NVIDIA_NVENET_13)
 		np->desc_ver = DESC_VER_1;
 	else
 		np->desc_ver = DESC_VER_2;
@@ -2215,56 +2220,84 @@ static struct pci_device_id pci_tbl[] = 
 		.device = PCI_DEVICE_ID_NVIDIA_NVENET_4,
 		.subvendor = PCI_ANY_ID,
 		.subdevice = PCI_ANY_ID,
-		.driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ,
+		.driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER,
 	},
 	{	/* nForce3 Ethernet Controller */
 		.vendor = PCI_VENDOR_ID_NVIDIA,
 		.device = PCI_DEVICE_ID_NVIDIA_NVENET_5,
 		.subvendor = PCI_ANY_ID,
 		.subdevice = PCI_ANY_ID,
-		.driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ,
+		.driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER,
 	},
 	{	/* nForce3 Ethernet Controller */
 		.vendor = PCI_VENDOR_ID_NVIDIA,
 		.device = PCI_DEVICE_ID_NVIDIA_NVENET_6,
 		.subvendor = PCI_ANY_ID,
 		.subdevice = PCI_ANY_ID,
-		.driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ,
+		.driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER,
 	},
 	{	/* nForce3 Ethernet Controller */
 		.vendor = PCI_VENDOR_ID_NVIDIA,
 		.device = PCI_DEVICE_ID_NVIDIA_NVENET_7,
 		.subvendor = PCI_ANY_ID,
 		.subdevice = PCI_ANY_ID,
-		.driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ,
+		.driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER,
 	},
 	{	/* CK804 Ethernet Controller */
 		.vendor = PCI_VENDOR_ID_NVIDIA,
 		.device = PCI_DEVICE_ID_NVIDIA_NVENET_8,
 		.subvendor = PCI_ANY_ID,
 		.subdevice = PCI_ANY_ID,
-		.driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ,
+		.driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER,
 	},
 	{	/* CK804 Ethernet Controller */
 		.vendor = PCI_VENDOR_ID_NVIDIA,
 		.device = PCI_DEVICE_ID_NVIDIA_NVENET_9,
 		.subvendor = PCI_ANY_ID,
 		.subdevice = PCI_ANY_ID,
-		.driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ,
+		.driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER,
 	},
 	{	/* MCP04 Ethernet Controller */
 		.vendor = PCI_VENDOR_ID_NVIDIA,
 		.device = PCI_DEVICE_ID_NVIDIA_NVENET_10,
 		.subvendor = PCI_ANY_ID,
 		.subdevice = PCI_ANY_ID,
-		.driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ,
+		.driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER,
 	},
 	{	/* MCP04 Ethernet Controller */
 		.vendor = PCI_VENDOR_ID_NVIDIA,
 		.device = PCI_DEVICE_ID_NVIDIA_NVENET_11,
 		.subvendor = PCI_ANY_ID,
 		.subdevice = PCI_ANY_ID,
-		.driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ,
+		.driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER,
+	},
+	{	/* MCP51 Ethernet Controller */
+		.vendor = PCI_VENDOR_ID_NVIDIA,
+		.device = PCI_DEVICE_ID_NVIDIA_NVENET_12,
+		.subvendor = PCI_ANY_ID,
+		.subdevice = PCI_ANY_ID,
+		.driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER,
+	},
+	{	/* MCP51 Ethernet Controller */
+		.vendor = PCI_VENDOR_ID_NVIDIA,
+		.device = PCI_DEVICE_ID_NVIDIA_NVENET_13,
+		.subvendor = PCI_ANY_ID,
+		.subdevice = PCI_ANY_ID,
+		.driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER,
+	},
+	{	/* MCP55 Ethernet Controller */
+		.vendor = PCI_VENDOR_ID_NVIDIA,
+		.device = PCI_DEVICE_ID_NVIDIA_NVENET_14,
+		.subvendor = PCI_ANY_ID,
+		.subdevice = PCI_ANY_ID,
+		.driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER,
+	},
+	{	/* MCP55 Ethernet Controller */
+		.vendor = PCI_VENDOR_ID_NVIDIA,
+		.device = PCI_DEVICE_ID_NVIDIA_NVENET_15,
+		.subvendor = PCI_ANY_ID,
+		.subdevice = PCI_ANY_ID,
+		.driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER,
 	},
 	{0,},
 };
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -1,4 +1,4 @@
-/* 
+/*
  * drivers/net/gianfar.c
  *
  * Gianfar Ethernet Driver
@@ -22,10 +22,9 @@
  *  B-V +1.62
  *
  *  Theory of operation
- *  This driver is designed for the Triple-speed Ethernet
- *  controllers on the Freescale 8540/8560 integrated processors,
- *  as well as the Fast Ethernet Controller on the 8540.  
- *  
+ *  This driver is designed for the non-CPM ethernet controllers
+ *  on the 85xx and 83xx family of integrated processors
+ *
  *  The driver is initialized through platform_device.  Structures which
  *  define the configuration needed by the board are defined in a
  *  board structure in arch/ppc/platforms (though I do not
@@ -39,12 +38,12 @@
  *
  *  The Gianfar Ethernet Controller uses a ring of buffer
  *  descriptors.  The beginning is indicated by a register
- *  pointing to the physical address of the start of the ring. 
- *  The end is determined by a "wrap" bit being set in the 
+ *  pointing to the physical address of the start of the ring.
+ *  The end is determined by a "wrap" bit being set in the
  *  last descriptor of the ring.
  *
  *  When a packet is received, the RXF bit in the
- *  IEVENT register is set, triggering an interrupt when the 
+ *  IEVENT register is set, triggering an interrupt when the
  *  corresponding bit in the IMASK register is also set (if
  *  interrupt coalescing is active, then the interrupt may not
  *  happen immediately, but will wait until either a set number
@@ -52,7 +51,7 @@
  *  interrupt handler will signal there is work to be done, and
  *  exit.  Without NAPI, the packet(s) will be handled
  *  immediately.  Both methods will start at the last known empty
- *  descriptor, and process every subsequent descriptor until there 
+ *  descriptor, and process every subsequent descriptor until there
  *  are none left with data (NAPI will stop after a set number of
  *  packets to give time to other tasks, but will eventually
  *  process all the packets).  The data arrives inside a
@@ -83,9 +82,13 @@
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
+#include <linux/if_vlan.h>
 #include <linux/spinlock.h>
 #include <linux/mm.h>
 #include <linux/device.h>
+#include <linux/ip.h>
+#include <linux/tcp.h>
+#include <linux/udp.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
@@ -123,7 +126,7 @@ static int gfar_set_mac_address(struct n
 static int gfar_change_mtu(struct net_device *dev, int new_mtu);
 static irqreturn_t gfar_error(int irq, void *dev_id, struct pt_regs *regs);
 static irqreturn_t gfar_transmit(int irq, void *dev_id, struct pt_regs *regs);
-irqreturn_t gfar_receive(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t gfar_receive(int irq, void *dev_id, struct pt_regs *regs);
 static irqreturn_t gfar_interrupt(int irq, void *dev_id, struct pt_regs *regs);
 static irqreturn_t phy_interrupt(int irq, void *dev_id, struct pt_regs *regs);
 static void gfar_phy_change(void *data);
@@ -139,9 +142,12 @@ static void gfar_set_hash_for_addr(struc
 #ifdef CONFIG_GFAR_NAPI
 static int gfar_poll(struct net_device *dev, int *budget);
 #endif
-static int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit);
+int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit);
 static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb, int length);
 static void gfar_phy_startup_timer(unsigned long data);
+static void gfar_vlan_rx_register(struct net_device *netdev,
+		                struct vlan_group *grp);
+static void gfar_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid);
 
 extern struct ethtool_ops gfar_ethtool_ops;
 
@@ -149,6 +155,13 @@ MODULE_AUTHOR("Freescale Semiconductor, 
 MODULE_DESCRIPTION("Gianfar Ethernet Driver");
 MODULE_LICENSE("GPL");
 
+int gfar_uses_fcb(struct gfar_private *priv)
+{
+	if (priv->vlan_enable || priv->rx_csum_enable)
+		return 1;
+	else
+		return 0;
+}
 static int gfar_probe(struct device *device)
 {
 	u32 tempval;
@@ -159,7 +172,6 @@ static int gfar_probe(struct device *dev
 	struct resource *r;
 	int idx;
 	int err = 0;
-	int dev_ethtool_ops = 0;
 
 	einfo = (struct gianfar_platform_data *) pdev->dev.platform_data;
 
@@ -265,15 +277,69 @@ static int gfar_probe(struct device *dev
 	dev->mtu = 1500;
 	dev->set_multicast_list = gfar_set_multi;
 
-	/* Index into the array of possible ethtool
-	 * ops to catch all 4 possibilities */
-	if((priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_RMON) == 0)
-		dev_ethtool_ops += 1;
+	dev->ethtool_ops = &gfar_ethtool_ops;
+
+	if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_CSUM) {
+		priv->rx_csum_enable = 1;
+		dev->features |= NETIF_F_IP_CSUM;
+	} else
+		priv->rx_csum_enable = 0;
+
+	priv->vlgrp = NULL;
+
+	if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_VLAN) {
+		dev->vlan_rx_register = gfar_vlan_rx_register;
+		dev->vlan_rx_kill_vid = gfar_vlan_rx_kill_vid;
+
+		dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
+
+		priv->vlan_enable = 1;
+	}
+
+	if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_EXTENDED_HASH) {
+		priv->extended_hash = 1;
+		priv->hash_width = 9;
+
+		priv->hash_regs[0] = &priv->regs->igaddr0;
+		priv->hash_regs[1] = &priv->regs->igaddr1;
+		priv->hash_regs[2] = &priv->regs->igaddr2;
+		priv->hash_regs[3] = &priv->regs->igaddr3;
+		priv->hash_regs[4] = &priv->regs->igaddr4;
+		priv->hash_regs[5] = &priv->regs->igaddr5;
+		priv->hash_regs[6] = &priv->regs->igaddr6;
+		priv->hash_regs[7] = &priv->regs->igaddr7;
+		priv->hash_regs[8] = &priv->regs->gaddr0;
+		priv->hash_regs[9] = &priv->regs->gaddr1;
+		priv->hash_regs[10] = &priv->regs->gaddr2;
+		priv->hash_regs[11] = &priv->regs->gaddr3;
+		priv->hash_regs[12] = &priv->regs->gaddr4;
+		priv->hash_regs[13] = &priv->regs->gaddr5;
+		priv->hash_regs[14] = &priv->regs->gaddr6;
+		priv->hash_regs[15] = &priv->regs->gaddr7;
+
+	} else {
+		priv->extended_hash = 0;
+		priv->hash_width = 8;
+
+		priv->hash_regs[0] = &priv->regs->gaddr0;
+                priv->hash_regs[1] = &priv->regs->gaddr1;
+		priv->hash_regs[2] = &priv->regs->gaddr2;
+		priv->hash_regs[3] = &priv->regs->gaddr3;
+		priv->hash_regs[4] = &priv->regs->gaddr4;
+		priv->hash_regs[5] = &priv->regs->gaddr5;
+		priv->hash_regs[6] = &priv->regs->gaddr6;
+		priv->hash_regs[7] = &priv->regs->gaddr7;
+	}
+
+	if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_PADDING)
+		priv->padding = DEFAULT_PADDING;
+	else
+		priv->padding = 0;
 
-	if((priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_COALESCE) == 0)
-		dev_ethtool_ops += 2;
+	dev->hard_header_len += priv->padding;
 
-	dev->ethtool_ops = gfar_op_array[dev_ethtool_ops];
+	if (dev->features & NETIF_F_IP_CSUM)
+		dev->hard_header_len += GMAC_FCB_LEN;
 
 	priv->rx_buffer_size = DEFAULT_RX_BUFFER_SIZE;
 #ifdef CONFIG_GFAR_BUFSTASH
@@ -289,6 +355,9 @@ static int gfar_probe(struct device *dev
 	priv->rxcount = DEFAULT_RXCOUNT;
 	priv->rxtime = DEFAULT_RXTIME;
 
+	/* Enable most messages by default */
+	priv->msg_enable = (NETIF_MSG_IFUP << 1 ) - 1;
+
 	err = register_netdev(dev);
 
 	if (err) {
@@ -360,8 +429,9 @@ static int init_phy(struct net_device *d
 			GFP_KERNEL);
 
 	if(NULL == mii_info) {
-		printk(KERN_ERR "%s: Could not allocate mii_info\n", 
-				dev->name);
+		if (netif_msg_ifup(priv))
+			printk(KERN_ERR "%s: Could not allocate mii_info\n",
+					dev->name);
 		return -ENOMEM;
 	}
 
@@ -410,7 +480,8 @@ static int init_phy(struct net_device *d
 	curphy = get_phy_info(priv->mii_info);
 
 	if (curphy == NULL) {
-		printk(KERN_ERR "%s: No PHY found\n", dev->name);
+		if (netif_msg_ifup(priv))
+			printk(KERN_ERR "%s: No PHY found\n", dev->name);
 		err = -1;
 		goto no_phy;
 	}
@@ -421,7 +492,7 @@ static int init_phy(struct net_device *d
 	if(curphy->init) {
 		err = curphy->init(priv->mii_info);
 
-		if (err) 
+		if (err)
 			goto phy_init_fail;
 	}
 
@@ -446,14 +517,14 @@ static void init_registers(struct net_de
 	gfar_write(&priv->regs->imask, IMASK_INIT_CLEAR);
 
 	/* Init hash registers to zero */
-	gfar_write(&priv->regs->iaddr0, 0);
-	gfar_write(&priv->regs->iaddr1, 0);
-	gfar_write(&priv->regs->iaddr2, 0);
-	gfar_write(&priv->regs->iaddr3, 0);
-	gfar_write(&priv->regs->iaddr4, 0);
-	gfar_write(&priv->regs->iaddr5, 0);
-	gfar_write(&priv->regs->iaddr6, 0);
-	gfar_write(&priv->regs->iaddr7, 0);
+	gfar_write(&priv->regs->igaddr0, 0);
+	gfar_write(&priv->regs->igaddr1, 0);
+	gfar_write(&priv->regs->igaddr2, 0);
+	gfar_write(&priv->regs->igaddr3, 0);
+	gfar_write(&priv->regs->igaddr4, 0);
+	gfar_write(&priv->regs->igaddr5, 0);
+	gfar_write(&priv->regs->igaddr6, 0);
+	gfar_write(&priv->regs->igaddr7, 0);
 
 	gfar_write(&priv->regs->gaddr0, 0);
 	gfar_write(&priv->regs->gaddr1, 0);
@@ -464,9 +535,6 @@ static void init_registers(struct net_de
 	gfar_write(&priv->regs->gaddr6, 0);
 	gfar_write(&priv->regs->gaddr7, 0);
 
-	/* Zero out rctrl */
-	gfar_write(&priv->regs->rctrl, 0x00000000);
-
 	/* Zero out the rmon mib registers if it has them */
 	if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_RMON) {
 		memset((void *) &(priv->regs->rmon), 0,
@@ -497,20 +565,14 @@ static void init_registers(struct net_de
 	gfar_write(&priv->regs->tbipa, TBIPA_VALUE);
 }
 
-void stop_gfar(struct net_device *dev)
+
+/* Halt the receive and transmit queues */
+void gfar_halt(struct net_device *dev)
 {
 	struct gfar_private *priv = netdev_priv(dev);
 	struct gfar *regs = priv->regs;
-	unsigned long flags;
 	u32 tempval;
 
-	/* Lock it down */
-	spin_lock_irqsave(&priv->lock, flags);
-
-	/* Tell the kernel the link is down */
-	priv->mii_info->link = 0;
-	adjust_link(dev);
-
 	/* Mask all interrupts */
 	gfar_write(&regs->imask, IMASK_INIT_CLEAR);
 
@@ -533,13 +595,29 @@ void stop_gfar(struct net_device *dev)
 	tempval = gfar_read(&regs->maccfg1);
 	tempval &= ~(MACCFG1_RX_EN | MACCFG1_TX_EN);
 	gfar_write(&regs->maccfg1, tempval);
+}
+
+void stop_gfar(struct net_device *dev)
+{
+	struct gfar_private *priv = netdev_priv(dev);
+	struct gfar *regs = priv->regs;
+	unsigned long flags;
+
+	/* Lock it down */
+	spin_lock_irqsave(&priv->lock, flags);
+
+	/* Tell the kernel the link is down */
+	priv->mii_info->link = 0;
+	adjust_link(dev);
+
+	gfar_halt(dev);
 
 	if (priv->einfo->board_flags & FSL_GIANFAR_BRD_HAS_PHY_INTR) {
 		/* Clear any pending interrupts */
 		mii_clear_phy_interrupt(priv->mii_info);
 
 		/* Disable PHY Interrupts */
-		mii_configure_phy_interrupt(priv->mii_info, 
+		mii_configure_phy_interrupt(priv->mii_info,
 				MII_INTERRUPT_DISABLED);
 	}
 
@@ -566,7 +644,7 @@ void stop_gfar(struct net_device *dev)
 			sizeof(struct txbd8)*priv->tx_ring_size
 			+ sizeof(struct rxbd8)*priv->rx_ring_size,
 			priv->tx_bd_base,
-			gfar_read(&regs->tbase));
+			gfar_read(&regs->tbase0));
 }
 
 /* If there are any tx skbs or rx skbs still around, free them.
@@ -620,6 +698,34 @@ void free_skb_resources(struct gfar_priv
 	}
 }
 
+void gfar_start(struct net_device *dev)
+{
+	struct gfar_private *priv = netdev_priv(dev);
+	struct gfar *regs = priv->regs;
+	u32 tempval;
+
+	/* Enable Rx and Tx in MACCFG1 */
+	tempval = gfar_read(&regs->maccfg1);
+	tempval |= (MACCFG1_RX_EN | MACCFG1_TX_EN);
+	gfar_write(&regs->maccfg1, tempval);
+
+	/* Initialize DMACTRL to have WWR and WOP */
+	tempval = gfar_read(&priv->regs->dmactrl);
+	tempval |= DMACTRL_INIT_SETTINGS;
+	gfar_write(&priv->regs->dmactrl, tempval);
+
+	/* Clear THLT, so that the DMA starts polling now */
+	gfar_write(&regs->tstat, TSTAT_CLEAR_THALT);
+
+	/* Make sure we aren't stopped */
+	tempval = gfar_read(&priv->regs->dmactrl);
+	tempval &= ~(DMACTRL_GRS | DMACTRL_GTS);
+	gfar_write(&priv->regs->dmactrl, tempval);
+
+	/* Unmask the interrupts we look for */
+	gfar_write(&regs->imask, IMASK_DEFAULT);
+}
+
 /* Bring the controller up and running */
 int startup_gfar(struct net_device *dev)
 {
@@ -630,33 +736,34 @@ int startup_gfar(struct net_device *dev)
 	int i;
 	struct gfar_private *priv = netdev_priv(dev);
 	struct gfar *regs = priv->regs;
-	u32 tempval;
 	int err = 0;
+	u32 rctrl = 0;
 
 	gfar_write(&regs->imask, IMASK_INIT_CLEAR);
 
 	/* Allocate memory for the buffer descriptors */
-	vaddr = (unsigned long) dma_alloc_coherent(NULL, 
+	vaddr = (unsigned long) dma_alloc_coherent(NULL,
 			sizeof (struct txbd8) * priv->tx_ring_size +
 			sizeof (struct rxbd8) * priv->rx_ring_size,
 			&addr, GFP_KERNEL);
 
 	if (vaddr == 0) {
-		printk(KERN_ERR "%s: Could not allocate buffer descriptors!\n",
-		       dev->name);
+		if (netif_msg_ifup(priv))
+			printk(KERN_ERR "%s: Could not allocate buffer descriptors!\n",
+					dev->name);
 		return -ENOMEM;
 	}
 
 	priv->tx_bd_base = (struct txbd8 *) vaddr;
 
 	/* enet DMA only understands physical addresses */
-	gfar_write(&regs->tbase, addr);
+	gfar_write(&regs->tbase0, addr);
 
 	/* Start the rx descriptor ring where the tx ring leaves off */
 	addr = addr + sizeof (struct txbd8) * priv->tx_ring_size;
 	vaddr = vaddr + sizeof (struct txbd8) * priv->tx_ring_size;
 	priv->rx_bd_base = (struct rxbd8 *) vaddr;
-	gfar_write(&regs->rbase, addr);
+	gfar_write(&regs->rbase0, addr);
 
 	/* Setup the skbuff rings */
 	priv->tx_skbuff =
@@ -664,8 +771,9 @@ int startup_gfar(struct net_device *dev)
 					priv->tx_ring_size, GFP_KERNEL);
 
 	if (priv->tx_skbuff == NULL) {
-		printk(KERN_ERR "%s: Could not allocate tx_skbuff\n",
-		       dev->name);
+		if (netif_msg_ifup(priv))
+			printk(KERN_ERR "%s: Could not allocate tx_skbuff\n",
+					dev->name);
 		err = -ENOMEM;
 		goto tx_skb_fail;
 	}
@@ -678,8 +786,9 @@ int startup_gfar(struct net_device *dev)
 					priv->rx_ring_size, GFP_KERNEL);
 
 	if (priv->rx_skbuff == NULL) {
-		printk(KERN_ERR "%s: Could not allocate rx_skbuff\n",
-		       dev->name);
+		if (netif_msg_ifup(priv))
+			printk(KERN_ERR "%s: Could not allocate rx_skbuff\n",
+					dev->name);
 		err = -ENOMEM;
 		goto rx_skb_fail;
 	}
@@ -726,12 +835,13 @@ int startup_gfar(struct net_device *dev)
 	/* If the device has multiple interrupts, register for
 	 * them.  Otherwise, only register for the one */
 	if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_MULTI_INTR) {
-		/* Install our interrupt handlers for Error, 
+		/* Install our interrupt handlers for Error,
 		 * Transmit, and Receive */
 		if (request_irq(priv->interruptError, gfar_error,
 				0, "enet_error", dev) < 0) {
-			printk(KERN_ERR "%s: Can't get IRQ %d\n",
-			       dev->name, priv->interruptError);
+			if (netif_msg_intr(priv))
+				printk(KERN_ERR "%s: Can't get IRQ %d\n",
+					dev->name, priv->interruptError);
 
 			err = -1;
 			goto err_irq_fail;
@@ -739,8 +849,9 @@ int startup_gfar(struct net_device *dev)
 
 		if (request_irq(priv->interruptTransmit, gfar_transmit,
 				0, "enet_tx", dev) < 0) {
-			printk(KERN_ERR "%s: Can't get IRQ %d\n",
-			       dev->name, priv->interruptTransmit);
+			if (netif_msg_intr(priv))
+				printk(KERN_ERR "%s: Can't get IRQ %d\n",
+					dev->name, priv->interruptTransmit);
 
 			err = -1;
 
@@ -749,8 +860,9 @@ int startup_gfar(struct net_device *dev)
 
 		if (request_irq(priv->interruptReceive, gfar_receive,
 				0, "enet_rx", dev) < 0) {
-			printk(KERN_ERR "%s: Can't get IRQ %d (receive0)\n",
-			       dev->name, priv->interruptReceive);
+			if (netif_msg_intr(priv))
+				printk(KERN_ERR "%s: Can't get IRQ %d (receive0)\n",
+						dev->name, priv->interruptReceive);
 
 			err = -1;
 			goto rx_irq_fail;
@@ -758,8 +870,9 @@ int startup_gfar(struct net_device *dev)
 	} else {
 		if (request_irq(priv->interruptTransmit, gfar_interrupt,
 				0, "gfar_interrupt", dev) < 0) {
-			printk(KERN_ERR "%s: Can't get IRQ %d\n",
-			       dev->name, priv->interruptError);
+			if (netif_msg_intr(priv))
+				printk(KERN_ERR "%s: Can't get IRQ %d\n",
+					dev->name, priv->interruptError);
 
 			err = -1;
 			goto err_irq_fail;
@@ -787,28 +900,22 @@ int startup_gfar(struct net_device *dev)
 	else
 		gfar_write(&regs->rxic, 0);
 
-	init_waitqueue_head(&priv->rxcleanupq);
+	if (priv->rx_csum_enable)
+		rctrl |= RCTRL_CHECKSUMMING;
 
-	/* Enable Rx and Tx in MACCFG1 */
-	tempval = gfar_read(&regs->maccfg1);
-	tempval |= (MACCFG1_RX_EN | MACCFG1_TX_EN);
-	gfar_write(&regs->maccfg1, tempval);
+	if (priv->extended_hash)
+		rctrl |= RCTRL_EXTHASH;
 
-	/* Initialize DMACTRL to have WWR and WOP */
-	tempval = gfar_read(&priv->regs->dmactrl);
-	tempval |= DMACTRL_INIT_SETTINGS;
-	gfar_write(&priv->regs->dmactrl, tempval);
+	if (priv->vlan_enable)
+		rctrl |= RCTRL_VLAN;
 
-	/* Clear THLT, so that the DMA starts polling now */
-	gfar_write(&regs->tstat, TSTAT_CLEAR_THALT);
+	/* Init rctrl based on our settings */
+	gfar_write(&priv->regs->rctrl, rctrl);
 
-	/* Make sure we aren't stopped */
-	tempval = gfar_read(&priv->regs->dmactrl);
-	tempval &= ~(DMACTRL_GRS | DMACTRL_GTS);
-	gfar_write(&priv->regs->dmactrl, tempval);
+	if (dev->features & NETIF_F_IP_CSUM)
+		gfar_write(&priv->regs->tctrl, TCTRL_INIT_CSUM);
 
-	/* Unmask the interrupts we look for */
-	gfar_write(&regs->imask, IMASK_DEFAULT);
+	gfar_start(dev);
 
 	return 0;
 
@@ -824,7 +931,7 @@ tx_skb_fail:
 			sizeof(struct txbd8)*priv->tx_ring_size
 			+ sizeof(struct rxbd8)*priv->rx_ring_size,
 			priv->tx_bd_base,
-			gfar_read(&regs->tbase));
+			gfar_read(&regs->tbase0));
 
 	if (priv->mii_info->phyinfo->close)
 		priv->mii_info->phyinfo->close(priv->mii_info);
@@ -857,11 +964,62 @@ static int gfar_enet_open(struct net_dev
 	return err;
 }
 
+static struct txfcb *gfar_add_fcb(struct sk_buff *skb, struct txbd8 *bdp)
+{
+	struct txfcb *fcb = (struct txfcb *)skb_push (skb, GMAC_FCB_LEN);
+
+	memset(fcb, 0, GMAC_FCB_LEN);
+
+	/* Flag the bd so the controller looks for the FCB */
+	bdp->status |= TXBD_TOE;
+
+	return fcb;
+}
+
+static inline void gfar_tx_checksum(struct sk_buff *skb, struct txfcb *fcb)
+{
+	int len;
+
+	/* If we're here, it's a IP packet with a TCP or UDP
+	 * payload.  We set it to checksum, using a pseudo-header
+	 * we provide
+	 */
+	fcb->ip = 1;
+	fcb->tup = 1;
+	fcb->ctu = 1;
+	fcb->nph = 1;
+
+	/* Notify the controller what the protocol is */
+	if (skb->nh.iph->protocol == IPPROTO_UDP)
+		fcb->udp = 1;
+
+	/* l3os is the distance between the start of the
+	 * frame (skb->data) and the start of the IP hdr.
+	 * l4os is the distance between the start of the
+	 * l3 hdr and the l4 hdr */
+	fcb->l3os = (u16)(skb->nh.raw - skb->data - GMAC_FCB_LEN);
+	fcb->l4os = (u16)(skb->h.raw - skb->nh.raw);
+
+	len = skb->nh.iph->tot_len - fcb->l4os;
+
+	/* Provide the pseudoheader csum */
+	fcb->phcs = ~csum_tcpudp_magic(skb->nh.iph->saddr,
+			skb->nh.iph->daddr, len,
+			skb->nh.iph->protocol, 0);
+}
+
+void gfar_tx_vlan(struct sk_buff *skb, struct txfcb *fcb)
+{
+	fcb->vln = 1;
+	fcb->vlctl = vlan_tx_tag_get(skb);
+}
+
 /* This is called by the kernel when a frame is ready for transmission. */
 /* It is pointed to by the dev->hard_start_xmit function pointer */
 static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct gfar_private *priv = netdev_priv(dev);
+	struct txfcb *fcb = NULL;
 	struct txbd8 *txbdp;
 
 	/* Update transmit stats */
@@ -876,9 +1034,24 @@ static int gfar_start_xmit(struct sk_buf
 	/* Clear all but the WRAP status flags */
 	txbdp->status &= TXBD_WRAP;
 
+	/* Set up checksumming */
+	if ((dev->features & NETIF_F_IP_CSUM) 
+			&& (CHECKSUM_HW == skb->ip_summed)) {
+		fcb = gfar_add_fcb(skb, txbdp);
+		gfar_tx_checksum(skb, fcb);
+	}
+
+	if (priv->vlan_enable &&
+			unlikely(priv->vlgrp && vlan_tx_tag_present(skb))) {
+		if (NULL == fcb)
+			fcb = gfar_add_fcb(skb, txbdp);
+
+		gfar_tx_vlan(skb, fcb);
+	}
+
 	/* Set buffer length and pointer */
 	txbdp->length = skb->len;
-	txbdp->bufPtr = dma_map_single(NULL, skb->data, 
+	txbdp->bufPtr = dma_map_single(NULL, skb->data,
 			skb->len, DMA_TO_DEVICE);
 
 	/* Save the skb pointer so we can free it later */
@@ -972,15 +1145,78 @@ int gfar_set_mac_address(struct net_devi
 }
 
 
+/* Enables and disables VLAN insertion/extraction */
+static void gfar_vlan_rx_register(struct net_device *dev,
+		struct vlan_group *grp)
+{
+	struct gfar_private *priv = netdev_priv(dev);
+	unsigned long flags;
+	u32 tempval;
+
+	spin_lock_irqsave(&priv->lock, flags);
+
+	priv->vlgrp = grp;
+
+	if (grp) {
+		/* Enable VLAN tag insertion */
+		tempval = gfar_read(&priv->regs->tctrl);
+		tempval |= TCTRL_VLINS;
+
+		gfar_write(&priv->regs->tctrl, tempval);
+		
+		/* Enable VLAN tag extraction */
+		tempval = gfar_read(&priv->regs->rctrl);
+		tempval |= RCTRL_VLEX;
+		gfar_write(&priv->regs->rctrl, tempval);
+	} else {
+		/* Disable VLAN tag insertion */
+		tempval = gfar_read(&priv->regs->tctrl);
+		tempval &= ~TCTRL_VLINS;
+		gfar_write(&priv->regs->tctrl, tempval);
+
+		/* Disable VLAN tag extraction */
+		tempval = gfar_read(&priv->regs->rctrl);
+		tempval &= ~RCTRL_VLEX;
+		gfar_write(&priv->regs->rctrl, tempval);
+	}
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+
+static void gfar_vlan_rx_kill_vid(struct net_device *dev, uint16_t vid)
+{
+	struct gfar_private *priv = netdev_priv(dev);
+	unsigned long flags;
+
+	spin_lock_irqsave(&priv->lock, flags);
+
+	if (priv->vlgrp)
+		priv->vlgrp->vlan_devices[vid] = NULL;
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+
 static int gfar_change_mtu(struct net_device *dev, int new_mtu)
 {
 	int tempsize, tempval;
 	struct gfar_private *priv = netdev_priv(dev);
 	int oldsize = priv->rx_buffer_size;
-	int frame_size = new_mtu + 18;
+	int frame_size = new_mtu + ETH_HLEN;
+
+	if (priv->vlan_enable)
+		frame_size += VLAN_ETH_HLEN;
+
+	if (gfar_uses_fcb(priv))
+		frame_size += GMAC_FCB_LEN;
+
+	frame_size += priv->padding;
 
 	if ((frame_size < 64) || (frame_size > JUMBO_FRAME_SIZE)) {
-		printk(KERN_ERR "%s: Invalid MTU setting\n", dev->name);
+		if (netif_msg_drv(priv))
+			printk(KERN_ERR "%s: Invalid MTU setting\n",
+					dev->name);
 		return -EINVAL;
 	}
 
@@ -1120,7 +1356,7 @@ struct sk_buff * gfar_new_skb(struct net
 	skb->dev = dev;
 
 	bdp->bufPtr = dma_map_single(NULL, skb->data,
-			priv->rx_buffer_size + RXBUF_ALIGNMENT, 
+			priv->rx_buffer_size + RXBUF_ALIGNMENT,
 			DMA_FROM_DEVICE);
 
 	bdp->length = 0;
@@ -1190,11 +1426,10 @@ irqreturn_t gfar_receive(int irq, void *
 
 		__netif_rx_schedule(dev);
 	} else {
-#ifdef VERBOSE_GFAR_ERRORS
-		printk(KERN_DEBUG "%s: receive called twice (%x)[%x]\n",
-		       dev->name, gfar_read(&priv->regs->ievent),
-		       gfar_read(&priv->regs->imask));
-#endif
+		if (netif_msg_rx_err(priv))
+			printk(KERN_DEBUG "%s: receive called twice (%x)[%x]\n",
+				dev->name, gfar_read(&priv->regs->ievent),
+				gfar_read(&priv->regs->imask));
 	}
 #else
 
@@ -1209,15 +1444,43 @@ irqreturn_t gfar_receive(int irq, void *
 	else
 		gfar_write(&priv->regs->rxic, 0);
 
-	/* Just in case we need to wake the ring param changer */
-	priv->rxclean = 1;
-
 	spin_unlock(&priv->lock);
 #endif
 
 	return IRQ_HANDLED;
 }
 
+static inline int gfar_rx_vlan(struct sk_buff *skb,
+		struct vlan_group *vlgrp, unsigned short vlctl)
+{
+#ifdef CONFIG_GFAR_NAPI
+	return vlan_hwaccel_receive_skb(skb, vlgrp, vlctl);
+#else
+	return vlan_hwaccel_rx(skb, vlgrp, vlctl);
+#endif
+}
+
+static inline void gfar_rx_checksum(struct sk_buff *skb, struct rxfcb *fcb)
+{
+	/* If valid headers were found, and valid sums
+	 * were verified, then we tell the kernel that no
+	 * checksumming is necessary.  Otherwise, it is */
+	if (fcb->cip && !fcb->eip && fcb->ctu && !fcb->etu)
+		skb->ip_summed = CHECKSUM_UNNECESSARY;
+	else
+		skb->ip_summed = CHECKSUM_NONE;
+}
+
+
+static inline struct rxfcb *gfar_get_fcb(struct sk_buff *skb)
+{
+	struct rxfcb *fcb = (struct rxfcb *)skb->data;
+
+	/* Remove the FCB from the skb */
+	skb_pull(skb, GMAC_FCB_LEN);
+
+	return fcb;
+}
 
 /* gfar_process_frame() -- handle one incoming packet if skb
  * isn't NULL.  */
@@ -1225,35 +1488,51 @@ static int gfar_process_frame(struct net
 		int length)
 {
 	struct gfar_private *priv = netdev_priv(dev);
+	struct rxfcb *fcb = NULL;
 
 	if (skb == NULL) {
-#ifdef BRIEF_GFAR_ERRORS
-		printk(KERN_WARNING "%s: Missing skb!!.\n",
-				dev->name);
-#endif
+		if (netif_msg_rx_err(priv))
+			printk(KERN_WARNING "%s: Missing skb!!.\n", dev->name);
 		priv->stats.rx_dropped++;
 		priv->extra_stats.rx_skbmissing++;
 	} else {
+		int ret;
+
 		/* Prep the skb for the packet */
 		skb_put(skb, length);
 
+		/* Grab the FCB if there is one */
+		if (gfar_uses_fcb(priv))
+			fcb = gfar_get_fcb(skb);
+
+		/* Remove the padded bytes, if there are any */
+		if (priv->padding)
+			skb_pull(skb, priv->padding);
+
+		if (priv->rx_csum_enable)
+			gfar_rx_checksum(skb, fcb);
+
 		/* Tell the skb what kind of packet this is */
 		skb->protocol = eth_type_trans(skb, dev);
 
 		/* Send the packet up the stack */
-		if (RECEIVE(skb) == NET_RX_DROP) {
+		if (unlikely(priv->vlgrp && fcb->vln))
+			ret = gfar_rx_vlan(skb, priv->vlgrp, fcb->vlctl);
+		else
+			ret = RECEIVE(skb);
+
+		if (NET_RX_DROP == ret)
 			priv->extra_stats.kernel_dropped++;
-		}
 	}
 
 	return 0;
 }
 
 /* gfar_clean_rx_ring() -- Processes each frame in the rx ring
- *   until the budget/quota has been reached. Returns the number 
+ *   until the budget/quota has been reached. Returns the number
  *   of frames handled
  */
-static int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit)
+int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit)
 {
 	struct rxbd8 *bdp;
 	struct sk_buff *skb;
@@ -1355,9 +1634,6 @@ static int gfar_poll(struct net_device *
 				   mk_ic_value(priv->rxcount, priv->rxtime));
 		else
 			gfar_write(&priv->regs->rxic, 0);
-
-		/* Signal to the ring size changer that it's safe to go */
-		priv->rxclean = 1;
 	}
 
 	return (rx_work_limit < 0) ? 1 : 0;
@@ -1393,10 +1669,8 @@ static irqreturn_t gfar_interrupt(int ir
 		if (events & IEVENT_CRL)
 			priv->stats.tx_aborted_errors++;
 		if (events & IEVENT_XFUN) {
-#ifdef VERBOSE_GFAR_ERRORS
-			printk(KERN_WARNING "%s: tx underrun. dropped packet\n",
-			       dev->name);
-#endif
+			if (netif_msg_tx_err(priv))
+				printk(KERN_WARNING "%s: tx underrun. dropped packet\n", dev->name);
 			priv->stats.tx_dropped++;
 			priv->extra_stats.tx_underrun++;
 
@@ -1415,36 +1689,30 @@ static irqreturn_t gfar_interrupt(int ir
 		gfar_write(&priv->regs->rstat, RSTAT_CLEAR_RHALT);
 #endif
 
-#ifdef VERBOSE_GFAR_ERRORS
-		printk(KERN_DEBUG "%s: busy error (rhalt: %x)\n", dev->name,
-		       gfar_read(&priv->regs->rstat));
-#endif
+		if (netif_msg_rx_err(priv))
+			printk(KERN_DEBUG "%s: busy error (rhalt: %x)\n",
+					dev->name,
+					gfar_read(&priv->regs->rstat));
 	}
 	if (events & IEVENT_BABR) {
 		priv->stats.rx_errors++;
 		priv->extra_stats.rx_babr++;
 
-#ifdef VERBOSE_GFAR_ERRORS
-		printk(KERN_DEBUG "%s: babbling error\n", dev->name);
-#endif
+		if (netif_msg_rx_err(priv))
+			printk(KERN_DEBUG "%s: babbling error\n", dev->name);
 	}
 	if (events & IEVENT_EBERR) {
 		priv->extra_stats.eberr++;
-#ifdef VERBOSE_GFAR_ERRORS
-		printk(KERN_DEBUG "%s: EBERR\n", dev->name);
-#endif
-	}
-	if (events & IEVENT_RXC) {
-#ifdef VERBOSE_GFAR_ERRORS
-		printk(KERN_DEBUG "%s: control frame\n", dev->name);
-#endif
+		if (netif_msg_rx_err(priv))
+			printk(KERN_DEBUG "%s: EBERR\n", dev->name);
 	}
+	if ((events & IEVENT_RXC) && (netif_msg_rx_err(priv)))
+			printk(KERN_DEBUG "%s: control frame\n", dev->name);
 
 	if (events & IEVENT_BABT) {
 		priv->extra_stats.tx_babt++;
-#ifdef VERBOSE_GFAR_ERRORS
-		printk(KERN_DEBUG "%s: babt error\n", dev->name);
-#endif
+		if (netif_msg_rx_err(priv))
+			printk(KERN_DEBUG "%s: babt error\n", dev->name);
 	}
 
 	return IRQ_HANDLED;
@@ -1510,7 +1778,7 @@ static void gfar_phy_timer(unsigned long
  * If, after GFAR_AN_TIMEOUT seconds, it has not
  * finished, we switch to forced.
  * Either way, once the process has completed, we either
- * request the interrupt, or switch the timer over to 
+ * request the interrupt, or switch the timer over to
  * using gfar_phy_timer to check status */
 static void gfar_phy_startup_timer(unsigned long data)
 {
@@ -1535,8 +1803,9 @@ static void gfar_phy_startup_timer(unsig
 
 		/* Forcing failed!  Give up */
 		if(result) {
-			printk(KERN_ERR "%s: Forcing failed!\n",
-					mii_info->dev->name);
+			if (netif_msg_link(priv))
+				printk(KERN_ERR "%s: Forcing failed!\n",
+						mii_info->dev->name);
 			return;
 		}
 	}
@@ -1546,16 +1815,17 @@ static void gfar_phy_startup_timer(unsig
 
 	/* Grab the PHY interrupt, if necessary/possible */
 	if (priv->einfo->board_flags & FSL_GIANFAR_BRD_HAS_PHY_INTR) {
-		if (request_irq(priv->einfo->interruptPHY, 
+		if (request_irq(priv->einfo->interruptPHY,
 					phy_interrupt,
-					SA_SHIRQ, 
-					"phy_interrupt", 
+					SA_SHIRQ,
+					"phy_interrupt",
 					mii_info->dev) < 0) {
-			printk(KERN_ERR "%s: Can't get IRQ %d (PHY)\n",
-					mii_info->dev->name,
+			if (netif_msg_intr(priv))
+				printk(KERN_ERR "%s: Can't get IRQ %d (PHY)\n",
+						mii_info->dev->name,
 					priv->einfo->interruptPHY);
 		} else {
-			mii_configure_phy_interrupt(priv->mii_info, 
+			mii_configure_phy_interrupt(priv->mii_info,
 					MII_INTERRUPT_ENABLED);
 			return;
 		}
@@ -1592,15 +1862,17 @@ static void adjust_link(struct net_devic
 				tempval &= ~(MACCFG2_FULL_DUPLEX);
 				gfar_write(&regs->maccfg2, tempval);
 
-				printk(KERN_INFO "%s: Half Duplex\n",
-				       dev->name);
+				if (netif_msg_link(priv))
+					printk(KERN_INFO "%s: Half Duplex\n",
+							dev->name);
 			} else {
 				tempval = gfar_read(&regs->maccfg2);
 				tempval |= MACCFG2_FULL_DUPLEX;
 				gfar_write(&regs->maccfg2, tempval);
 
-				printk(KERN_INFO "%s: Full Duplex\n",
-				       dev->name);
+				if (netif_msg_link(priv))
+					printk(KERN_INFO "%s: Full Duplex\n",
+							dev->name);
 			}
 
 			priv->oldduplex = mii_info->duplex;
@@ -1622,27 +1894,32 @@ static void adjust_link(struct net_devic
 				gfar_write(&regs->maccfg2, tempval);
 				break;
 			default:
-				printk(KERN_WARNING
-				       "%s: Ack!  Speed (%d) is not 10/100/1000!\n",
-				       dev->name, mii_info->speed);
+				if (netif_msg_link(priv))
+					printk(KERN_WARNING
+							"%s: Ack!  Speed (%d) is not 10/100/1000!\n",
+							dev->name, mii_info->speed);
 				break;
 			}
 
-			printk(KERN_INFO "%s: Speed %dBT\n", dev->name,
-			       mii_info->speed);
+			if (netif_msg_link(priv))
+				printk(KERN_INFO "%s: Speed %dBT\n", dev->name,
+						mii_info->speed);
 
 			priv->oldspeed = mii_info->speed;
 		}
 
 		if (!priv->oldlink) {
-			printk(KERN_INFO "%s: Link is up\n", dev->name);
+			if (netif_msg_link(priv))
+				printk(KERN_INFO "%s: Link is up\n", dev->name);
 			priv->oldlink = 1;
 			netif_carrier_on(dev);
 			netif_schedule(dev);
 		}
 	} else {
 		if (priv->oldlink) {
-			printk(KERN_INFO "%s: Link is down\n", dev->name);
+			if (netif_msg_link(priv))
+				printk(KERN_INFO "%s: Link is down\n",
+						dev->name);
 			priv->oldlink = 0;
 			priv->oldspeed = 0;
 			priv->oldduplex = -1;
@@ -1664,8 +1941,9 @@ static void gfar_set_multi(struct net_de
 	u32 tempval;
 
 	if(dev->flags & IFF_PROMISC) {
-		printk(KERN_INFO "%s: Entering promiscuous mode.\n",
-				dev->name);
+		if (netif_msg_drv(priv))
+			printk(KERN_INFO "%s: Entering promiscuous mode.\n",
+					dev->name);
 		/* Set RCTRL to PROM */
 		tempval = gfar_read(&regs->rctrl);
 		tempval |= RCTRL_PROM;
@@ -1679,6 +1957,14 @@ static void gfar_set_multi(struct net_de
 	
 	if(dev->flags & IFF_ALLMULTI) {
 		/* Set the hash to rx all multicast frames */
+		gfar_write(&regs->igaddr0, 0xffffffff);
+		gfar_write(&regs->igaddr1, 0xffffffff);
+		gfar_write(&regs->igaddr2, 0xffffffff);
+		gfar_write(&regs->igaddr3, 0xffffffff);
+		gfar_write(&regs->igaddr4, 0xffffffff);
+		gfar_write(&regs->igaddr5, 0xffffffff);
+		gfar_write(&regs->igaddr6, 0xffffffff);
+		gfar_write(&regs->igaddr7, 0xffffffff);
 		gfar_write(&regs->gaddr0, 0xffffffff);
 		gfar_write(&regs->gaddr1, 0xffffffff);
 		gfar_write(&regs->gaddr2, 0xffffffff);
@@ -1689,6 +1975,14 @@ static void gfar_set_multi(struct net_de
 		gfar_write(&regs->gaddr7, 0xffffffff);
 	} else {
 		/* zero out the hash */
+		gfar_write(&regs->igaddr0, 0x0);
+		gfar_write(&regs->igaddr1, 0x0);
+		gfar_write(&regs->igaddr2, 0x0);
+		gfar_write(&regs->igaddr3, 0x0);
+		gfar_write(&regs->igaddr4, 0x0);
+		gfar_write(&regs->igaddr5, 0x0);
+		gfar_write(&regs->igaddr6, 0x0);
+		gfar_write(&regs->igaddr7, 0x0);
 		gfar_write(&regs->gaddr0, 0x0);
 		gfar_write(&regs->gaddr1, 0x0);
 		gfar_write(&regs->gaddr2, 0x0);
@@ -1727,16 +2021,15 @@ static void gfar_set_hash_for_addr(struc
 {
 	u32 tempval;
 	struct gfar_private *priv = netdev_priv(dev);
-	struct gfar *regs = priv->regs;
-	u32 *hash = &regs->gaddr0;
 	u32 result = ether_crc(MAC_ADDR_LEN, addr);
-	u8 whichreg = ((result >> 29) & 0x7);
-	u8 whichbit = ((result >> 24) & 0x1f);
+	int width = priv->hash_width;
+	u8 whichbit = (result >> (32 - width)) & 0x1f;
+	u8 whichreg = result >> (32 - width + 5);
 	u32 value = (1 << (31-whichbit));
 
-	tempval = gfar_read(&hash[whichreg]);
+	tempval = gfar_read(priv->hash_regs[whichreg]);
 	tempval |= value;
-	gfar_write(&hash[whichreg], tempval);
+	gfar_write(priv->hash_regs[whichreg], tempval);
 
 	return;
 }
@@ -1754,10 +2047,9 @@ static irqreturn_t gfar_error(int irq, v
 	gfar_write(&priv->regs->ievent, IEVENT_ERR_MASK);
 
 	/* Hmm... */
-#if defined (BRIEF_GFAR_ERRORS) || defined (VERBOSE_GFAR_ERRORS)
-	printk(KERN_DEBUG "%s: error interrupt (ievent=0x%08x imask=0x%08x)\n",
-	       dev->name, events, gfar_read(&priv->regs->imask));
-#endif
+	if (netif_msg_rx_err(priv) || netif_msg_tx_err(priv))
+		printk(KERN_DEBUG "%s: error interrupt (ievent=0x%08x imask=0x%08x)\n",
+				dev->name, events, gfar_read(&priv->regs->imask));
 
 	/* Update the error counters */
 	if (events & IEVENT_TXE) {
@@ -1768,19 +2060,17 @@ static irqreturn_t gfar_error(int irq, v
 		if (events & IEVENT_CRL)
 			priv->stats.tx_aborted_errors++;
 		if (events & IEVENT_XFUN) {
-#ifdef VERBOSE_GFAR_ERRORS
-			printk(KERN_DEBUG "%s: underrun.  packet dropped.\n",
-			       dev->name);
-#endif
+			if (netif_msg_tx_err(priv))
+				printk(KERN_DEBUG "%s: underrun.  packet dropped.\n",
+						dev->name);
 			priv->stats.tx_dropped++;
 			priv->extra_stats.tx_underrun++;
 
 			/* Reactivate the Tx Queues */
 			gfar_write(&priv->regs->tstat, TSTAT_CLEAR_THALT);
 		}
-#ifdef VERBOSE_GFAR_ERRORS
-		printk(KERN_DEBUG "%s: Transmit Error\n", dev->name);
-#endif
+		if (netif_msg_tx_err(priv))
+			printk(KERN_DEBUG "%s: Transmit Error\n", dev->name);
 	}
 	if (events & IEVENT_BSY) {
 		priv->stats.rx_errors++;
@@ -1793,35 +2083,31 @@ static irqreturn_t gfar_error(int irq, v
 		gfar_write(&priv->regs->rstat, RSTAT_CLEAR_RHALT);
 #endif
 
-#ifdef VERBOSE_GFAR_ERRORS
-		printk(KERN_DEBUG "%s: busy error (rhalt: %x)\n", dev->name,
-		       gfar_read(&priv->regs->rstat));
-#endif
+		if (netif_msg_rx_err(priv))
+			printk(KERN_DEBUG "%s: busy error (rhalt: %x)\n",
+					dev->name,
+					gfar_read(&priv->regs->rstat));
 	}
 	if (events & IEVENT_BABR) {
 		priv->stats.rx_errors++;
 		priv->extra_stats.rx_babr++;
 
-#ifdef VERBOSE_GFAR_ERRORS
-		printk(KERN_DEBUG "%s: babbling error\n", dev->name);
-#endif
+		if (netif_msg_rx_err(priv))
+			printk(KERN_DEBUG "%s: babbling error\n", dev->name);
 	}
 	if (events & IEVENT_EBERR) {
 		priv->extra_stats.eberr++;
-#ifdef VERBOSE_GFAR_ERRORS
-		printk(KERN_DEBUG "%s: EBERR\n", dev->name);
-#endif
+		if (netif_msg_rx_err(priv))
+			printk(KERN_DEBUG "%s: EBERR\n", dev->name);
 	}
-	if (events & IEVENT_RXC)
-#ifdef VERBOSE_GFAR_ERRORS
-		printk(KERN_DEBUG "%s: control frame\n", dev->name);
-#endif
+	if ((events & IEVENT_RXC) && netif_msg_rx_status(priv))
+		if (netif_msg_rx_status(priv))
+			printk(KERN_DEBUG "%s: control frame\n", dev->name);
 
 	if (events & IEVENT_BABT) {
 		priv->extra_stats.tx_babt++;
-#ifdef VERBOSE_GFAR_ERRORS
-		printk(KERN_DEBUG "%s: babt error\n", dev->name);
-#endif
+		if (netif_msg_tx_err(priv))
+			printk(KERN_DEBUG "%s: babt error\n", dev->name);
 	}
 	return IRQ_HANDLED;
 }
diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h
--- a/drivers/net/gianfar.h
+++ b/drivers/net/gianfar.h
@@ -1,4 +1,4 @@
-/* 
+/*
  * drivers/net/gianfar.h
  *
  * Gianfar Ethernet Driver
@@ -53,6 +53,12 @@
 /* The maximum number of packets to be handled in one call of gfar_poll */
 #define GFAR_DEV_WEIGHT 64
 
+/* Length for FCB */
+#define GMAC_FCB_LEN 8
+
+/* Default padding amount */
+#define DEFAULT_PADDING 2
+
 /* Number of bytes to align the rx bufs to */
 #define RXBUF_ALIGNMENT 64
 
@@ -91,7 +97,7 @@ extern const char gfar_driver_version[];
 #define JUMBO_FRAME_SIZE 9600
 
 /* Latency of interface clock in nanoseconds */
-/* Interface clock latency , in this case, means the 
+/* Interface clock latency , in this case, means the
  * time described by a value of 1 in the interrupt
  * coalescing registers' time fields.  Since those fields
  * refer to the time it takes for 64 clocks to pass, the
@@ -166,9 +172,28 @@ extern const char gfar_driver_version[];
 				mk_ic_icft(count) | \
 				mk_ic_ictt(time))
 
+#define RCTRL_PAL_MASK		0x001f0000
+#define RCTRL_VLEX		0x00002000
+#define RCTRL_FILREN		0x00001000
+#define RCTRL_GHTX		0x00000400
+#define RCTRL_IPCSEN		0x00000200
+#define RCTRL_TUCSEN		0x00000100
+#define RCTRL_PRSDEP_MASK	0x000000c0
+#define RCTRL_PRSDEP_INIT	0x000000c0
 #define RCTRL_PROM		0x00000008
+#define RCTRL_CHECKSUMMING	(RCTRL_IPCSEN \
+		| RCTRL_TUCSEN | RCTRL_PRSDEP_INIT)
+#define RCTRL_EXTHASH		(RCTRL_GHTX)
+#define RCTRL_VLAN		(RCTRL_PRSDEP_INIT)
+
+
 #define RSTAT_CLEAR_RHALT       0x00800000
 
+#define TCTRL_IPCSEN		0x00004000
+#define TCTRL_TUCSEN		0x00002000
+#define TCTRL_VLINS		0x00001000
+#define TCTRL_INIT_CSUM		(TCTRL_TUCSEN | TCTRL_IPCSEN)
+
 #define IEVENT_INIT_CLEAR	0xffffffff
 #define IEVENT_BABR		0x80000000
 #define IEVENT_RXC		0x40000000
@@ -187,12 +212,16 @@ extern const char gfar_driver_version[];
 #define IEVENT_RXB0		0x00008000
 #define IEVENT_GRSC		0x00000100
 #define IEVENT_RXF0		0x00000080
+#define IEVENT_FIR		0x00000008
+#define IEVENT_FIQ		0x00000004
+#define IEVENT_DPE		0x00000002
+#define IEVENT_PERR		0x00000001
 #define IEVENT_RX_MASK          (IEVENT_RXB0 | IEVENT_RXF0)
 #define IEVENT_TX_MASK          (IEVENT_TXB | IEVENT_TXF)
 #define IEVENT_ERR_MASK         \
 (IEVENT_RXC | IEVENT_BSY | IEVENT_EBERR | IEVENT_MSRO | \
  IEVENT_BABT | IEVENT_TXC | IEVENT_TXE | IEVENT_LC \
- | IEVENT_CRL | IEVENT_XFUN)
+ | IEVENT_CRL | IEVENT_XFUN | IEVENT_DPE | IEVENT_PERR)
 
 #define IMASK_INIT_CLEAR	0x00000000
 #define IMASK_BABR              0x80000000
@@ -212,10 +241,15 @@ extern const char gfar_driver_version[];
 #define IMASK_RXB0              0x00008000
 #define IMASK_GTSC              0x00000100
 #define IMASK_RXFEN0		0x00000080
+#define IMASK_FIR		0x00000008
+#define IMASK_FIQ		0x00000004
+#define IMASK_DPE		0x00000002
+#define IMASK_PERR		0x00000001
 #define IMASK_RX_DISABLED ~(IMASK_RXFEN0 | IMASK_BSY)
 #define IMASK_DEFAULT  (IMASK_TXEEN | IMASK_TXFEN | IMASK_TXBEN | \
 		IMASK_RXFEN0 | IMASK_BSY | IMASK_EBERR | IMASK_BABR | \
-		IMASK_XFUN | IMASK_RXC | IMASK_BABT)
+		IMASK_XFUN | IMASK_RXC | IMASK_BABT | IMASK_DPE \
+		| IMASK_PERR)
 
 
 /* Attribute fields */
@@ -254,6 +288,18 @@ extern const char gfar_driver_version[];
 #define TXBD_RETRYLIMIT		0x0040
 #define	TXBD_RETRYCOUNTMASK	0x003c
 #define TXBD_UNDERRUN		0x0002
+#define TXBD_TOE		0x0002
+
+/* Tx FCB param bits */
+#define TXFCB_VLN		0x80
+#define TXFCB_IP		0x40
+#define TXFCB_IP6		0x20
+#define TXFCB_TUP		0x10
+#define TXFCB_UDP		0x08
+#define TXFCB_CIP		0x04
+#define TXFCB_CTU		0x02
+#define TXFCB_NPH		0x01
+#define TXFCB_DEFAULT 		(TXFCB_IP|TXFCB_TUP|TXFCB_CTU|TXFCB_NPH)
 
 /* RxBD status field bits */
 #define RXBD_EMPTY		0x8000
@@ -273,6 +319,18 @@ extern const char gfar_driver_version[];
 #define RXBD_TRUNCATED		0x0001
 #define RXBD_STATS		0x01ff
 
+/* Rx FCB status field bits */
+#define RXFCB_VLN		0x8000
+#define RXFCB_IP		0x4000
+#define RXFCB_IP6		0x2000
+#define RXFCB_TUP		0x1000
+#define RXFCB_CIP		0x0800
+#define RXFCB_CTU		0x0400
+#define RXFCB_EIP		0x0200
+#define RXFCB_ETU		0x0100
+#define RXFCB_PERR_MASK		0x000c
+#define RXFCB_PERR_BADL3	0x0008
+
 struct txbd8
 {
 	u16	status;	/* Status Fields */
@@ -280,6 +338,22 @@ struct txbd8
 	u32	bufPtr;	/* Buffer Pointer */
 };
 
+struct txfcb {
+	u8	vln:1,
+		ip:1,
+		ip6:1,
+		tup:1,
+		udp:1,
+		cip:1,
+		ctu:1,
+		nph:1;
+	u8	reserved;
+	u8	l4os;	/* Level 4 Header Offset */
+	u8	l3os; 	/* Level 3 Header Offset */
+	u16	phcs;	/* Pseudo-header Checksum */
+	u16	vlctl;	/* VLAN control word */
+};
+
 struct rxbd8
 {
 	u16	status;	/* Status Fields */
@@ -287,6 +361,21 @@ struct rxbd8
 	u32	bufPtr;	/* Buffer Pointer */
 };
 
+struct rxfcb {
+	u16	vln:1,
+		ip:1,
+		ip6:1,
+		tup:1,
+		cip:1,
+		ctu:1,
+		eip:1,
+		etu:1;
+	u8	rq;	/* Receive Queue index */
+	u8	pro;	/* Layer 4 Protocol */
+	u16	reserved;
+	u16	vlctl;	/* VLAN control word */
+};
+
 struct rmon_mib
 {
 	u32	tr64;	/* 0x.680 - Transmit and Receive 64-byte Frame Counter */
@@ -371,90 +460,191 @@ struct gfar_stats {
 
 
 struct gfar {
-	u8	res1[16];
-	u32	ievent;			/* 0x.010 - Interrupt Event Register */
-	u32	imask;			/* 0x.014 - Interrupt Mask Register */
-	u32	edis;			/* 0x.018 - Error Disabled Register */
+	u32	tsec_id;	/* 0x.000 - Controller ID register */
+	u8	res1[12];
+	u32	ievent;		/* 0x.010 - Interrupt Event Register */
+	u32	imask;		/* 0x.014 - Interrupt Mask Register */
+	u32	edis;		/* 0x.018 - Error Disabled Register */
 	u8	res2[4];
-	u32	ecntrl;			/* 0x.020 - Ethernet Control Register */
-	u32	minflr;			/* 0x.024 - Minimum Frame Length Register */
-	u32	ptv;			/* 0x.028 - Pause Time Value Register */
-	u32	dmactrl;		/* 0x.02c - DMA Control Register */
-	u32	tbipa;			/* 0x.030 - TBI PHY Address Register */
+	u32	ecntrl;		/* 0x.020 - Ethernet Control Register */
+	u32	minflr;		/* 0x.024 - Minimum Frame Length Register */
+	u32	ptv;		/* 0x.028 - Pause Time Value Register */
+	u32	dmactrl;	/* 0x.02c - DMA Control Register */
+	u32	tbipa;		/* 0x.030 - TBI PHY Address Register */
 	u8	res3[88];
-	u32	fifo_tx_thr;		/* 0x.08c - FIFO transmit threshold register */
+	u32	fifo_tx_thr;	/* 0x.08c - FIFO transmit threshold register */
 	u8	res4[8];
-	u32	fifo_tx_starve;		/* 0x.098 - FIFO transmit starve register */
+	u32	fifo_tx_starve;	/* 0x.098 - FIFO transmit starve register */
 	u32	fifo_tx_starve_shutoff;	/* 0x.09c - FIFO transmit starve shutoff register */
-	u8	res5[96];
-	u32	tctrl;			/* 0x.100 - Transmit Control Register */
-	u32	tstat;			/* 0x.104 - Transmit Status Register */
-	u8	res6[4];
-	u32	tbdlen;			/* 0x.10c - Transmit Buffer Descriptor Data Length Register */
-	u32	txic;			/* 0x.110 - Transmit Interrupt Coalescing Configuration Register */
-	u8	res7[16];
-	u32	ctbptr;			/* 0x.124 - Current Transmit Buffer Descriptor Pointer Register */
-	u8	res8[92];
-	u32	tbptr;			/* 0x.184 - Transmit Buffer Descriptor Pointer Low Register */
-	u8	res9[124];
-	u32	tbase;			/* 0x.204 - Transmit Descriptor Base Address Register */
-	u8	res10[168];
-	u32	ostbd;			/* 0x.2b0 - Out-of-Sequence Transmit Buffer Descriptor Register */
-	u32	ostbdp;			/* 0x.2b4 - Out-of-Sequence Transmit Data Buffer Pointer Register */
-	u8	res11[72];
-	u32	rctrl;			/* 0x.300 - Receive Control Register */
-	u32	rstat;			/* 0x.304 - Receive Status Register */
-	u8	res12[4];
-	u32	rbdlen;			/* 0x.30c - RxBD Data Length Register */
-	u32	rxic;			/* 0x.310 - Receive Interrupt Coalescing Configuration Register */
-	u8	res13[16];
-	u32	crbptr;			/* 0x.324 - Current Receive Buffer Descriptor Pointer */
-	u8	res14[24];
-	u32	mrblr;			/* 0x.340 - Maximum Receive Buffer Length Register */
-	u8	res15[64];
-	u32	rbptr;			/* 0x.384 - Receive Buffer Descriptor Pointer */
-	u8	res16[124];
-	u32	rbase;			/* 0x.404 - Receive Descriptor Base Address */
-	u8	res17[248];
-	u32	maccfg1;		/* 0x.500 - MAC Configuration 1 Register */
-	u32	maccfg2;		/* 0x.504 - MAC Configuration 2 Register */
-	u32	ipgifg;			/* 0x.508 - Inter Packet Gap/Inter Frame Gap Register */
-	u32	hafdup;			/* 0x.50c - Half Duplex Register */
-	u32	maxfrm;			/* 0x.510 - Maximum Frame Length Register */
+	u8	res5[4];
+	u32	fifo_rx_pause;	/* 0x.0a4 - FIFO receive pause threshold register */
+	u32	fifo_rx_alarm;	/* 0x.0a8 - FIFO receive alarm threshold register */
+	u8	res6[84];
+	u32	tctrl;		/* 0x.100 - Transmit Control Register */
+	u32	tstat;		/* 0x.104 - Transmit Status Register */
+	u32	dfvlan;		/* 0x.108 - Default VLAN Control word */
+	u32	tbdlen;		/* 0x.10c - Transmit Buffer Descriptor Data Length Register */
+	u32	txic;		/* 0x.110 - Transmit Interrupt Coalescing Configuration Register */
+	u32	tqueue;		/* 0x.114 - Transmit queue control register */
+	u8	res7[40];
+	u32	tr03wt;		/* 0x.140 - TxBD Rings 0-3 round-robin weightings */
+	u32	tr47wt;		/* 0x.144 - TxBD Rings 4-7 round-robin weightings */
+	u8	res8[52];
+	u32	tbdbph;		/* 0x.17c - Tx data buffer pointer high */
+	u8	res9a[4];
+	u32	tbptr0;		/* 0x.184 - TxBD Pointer for ring 0 */
+	u8	res9b[4];
+	u32	tbptr1;		/* 0x.18c - TxBD Pointer for ring 1 */
+	u8	res9c[4];
+	u32	tbptr2;		/* 0x.194 - TxBD Pointer for ring 2 */
+	u8	res9d[4];
+	u32	tbptr3;		/* 0x.19c - TxBD Pointer for ring 3 */
+	u8	res9e[4];
+	u32	tbptr4;		/* 0x.1a4 - TxBD Pointer for ring 4 */
+	u8	res9f[4];
+	u32	tbptr5;		/* 0x.1ac - TxBD Pointer for ring 5 */
+	u8	res9g[4];
+	u32	tbptr6;		/* 0x.1b4 - TxBD Pointer for ring 6 */
+	u8	res9h[4];
+	u32	tbptr7;		/* 0x.1bc - TxBD Pointer for ring 7 */
+	u8	res9[64];
+	u32	tbaseh;		/* 0x.200 - TxBD base address high */
+	u32	tbase0;		/* 0x.204 - TxBD Base Address of ring 0 */
+	u8	res10a[4];
+	u32	tbase1;		/* 0x.20c - TxBD Base Address of ring 1 */
+	u8	res10b[4];
+	u32	tbase2;		/* 0x.214 - TxBD Base Address of ring 2 */
+	u8	res10c[4];
+	u32	tbase3;		/* 0x.21c - TxBD Base Address of ring 3 */
+	u8	res10d[4];
+	u32	tbase4;		/* 0x.224 - TxBD Base Address of ring 4 */
+	u8	res10e[4];
+	u32	tbase5;		/* 0x.22c - TxBD Base Address of ring 5 */
+	u8	res10f[4];
+	u32	tbase6;		/* 0x.234 - TxBD Base Address of ring 6 */
+	u8	res10g[4];
+	u32	tbase7;		/* 0x.23c - TxBD Base Address of ring 7 */
+	u8	res10[192];
+	u32	rctrl;		/* 0x.300 - Receive Control Register */
+	u32	rstat;		/* 0x.304 - Receive Status Register */
+	u8	res12[8];
+	u32	rxic;		/* 0x.310 - Receive Interrupt Coalescing Configuration Register */
+	u32	rqueue;		/* 0x.314 - Receive queue control register */
+	u8	res13[24];
+	u32	rbifx;		/* 0x.330 - Receive bit field extract control register */
+	u32	rqfar;		/* 0x.334 - Receive queue filing table address register */
+	u32	rqfcr;		/* 0x.338 - Receive queue filing table control register */
+	u32	rqfpr;		/* 0x.33c - Receive queue filing table property register */
+	u32	mrblr;		/* 0x.340 - Maximum Receive Buffer Length Register */
+	u8	res14[56];
+	u32	rbdbph;		/* 0x.37c - Rx data buffer pointer high */
+	u8	res15a[4];
+	u32	rbptr0;		/* 0x.384 - RxBD pointer for ring 0 */
+	u8	res15b[4];
+	u32	rbptr1;		/* 0x.38c - RxBD pointer for ring 1 */
+	u8	res15c[4];
+	u32	rbptr2;		/* 0x.394 - RxBD pointer for ring 2 */
+	u8	res15d[4];
+	u32	rbptr3;		/* 0x.39c - RxBD pointer for ring 3 */
+	u8	res15e[4];
+	u32	rbptr4;		/* 0x.3a4 - RxBD pointer for ring 4 */
+	u8	res15f[4];
+	u32	rbptr5;		/* 0x.3ac - RxBD pointer for ring 5 */
+	u8	res15g[4];
+	u32	rbptr6;		/* 0x.3b4 - RxBD pointer for ring 6 */
+	u8	res15h[4];
+	u32	rbptr7;		/* 0x.3bc - RxBD pointer for ring 7 */
+	u8	res16[64];
+	u32	rbaseh;		/* 0x.400 - RxBD base address high */
+	u32	rbase0;		/* 0x.404 - RxBD base address of ring 0 */
+	u8	res17a[4];
+	u32	rbase1;		/* 0x.40c - RxBD base address of ring 1 */
+	u8	res17b[4];
+	u32	rbase2;		/* 0x.414 - RxBD base address of ring 2 */
+	u8	res17c[4];
+	u32	rbase3;		/* 0x.41c - RxBD base address of ring 3 */
+	u8	res17d[4];
+	u32	rbase4;		/* 0x.424 - RxBD base address of ring 4 */
+	u8	res17e[4];
+	u32	rbase5;		/* 0x.42c - RxBD base address of ring 5 */
+	u8	res17f[4];
+	u32	rbase6;		/* 0x.434 - RxBD base address of ring 6 */
+	u8	res17g[4];
+	u32	rbase7;		/* 0x.43c - RxBD base address of ring 7 */
+	u8	res17[192];
+	u32	maccfg1;	/* 0x.500 - MAC Configuration 1 Register */
+	u32	maccfg2;	/* 0x.504 - MAC Configuration 2 Register */
+	u32	ipgifg;		/* 0x.508 - Inter Packet Gap/Inter Frame Gap Register */
+	u32	hafdup;		/* 0x.50c - Half Duplex Register */
+	u32	maxfrm;		/* 0x.510 - Maximum Frame Length Register */
 	u8	res18[12];
-	u32	miimcfg;		/* 0x.520 - MII Management Configuration Register */
-	u32	miimcom;		/* 0x.524 - MII Management Command Register */
-	u32	miimadd;		/* 0x.528 - MII Management Address Register */
-	u32	miimcon;		/* 0x.52c - MII Management Control Register */
-	u32	miimstat;		/* 0x.530 - MII Management Status Register */
-	u32	miimind;		/* 0x.534 - MII Management Indicator Register */
+	u32	miimcfg;	/* 0x.520 - MII Management Configuration Register */
+	u32	miimcom;	/* 0x.524 - MII Management Command Register */
+	u32	miimadd;	/* 0x.528 - MII Management Address Register */
+	u32	miimcon;	/* 0x.52c - MII Management Control Register */
+	u32	miimstat;	/* 0x.530 - MII Management Status Register */
+	u32	miimind;	/* 0x.534 - MII Management Indicator Register */
 	u8	res19[4];
-	u32	ifstat;			/* 0x.53c - Interface Status Register */
-	u32	macstnaddr1;		/* 0x.540 - Station Address Part 1 Register */
-	u32	macstnaddr2;		/* 0x.544 - Station Address Part 2 Register */
-	u8	res20[312];
-	struct rmon_mib	rmon;
-	u8	res21[192];
-	u32	iaddr0;			/* 0x.800 - Indivdual address register 0 */
-	u32	iaddr1;			/* 0x.804 - Indivdual address register 1 */
-	u32	iaddr2;			/* 0x.808 - Indivdual address register 2 */
-	u32	iaddr3;			/* 0x.80c - Indivdual address register 3 */
-	u32	iaddr4;			/* 0x.810 - Indivdual address register 4 */
-	u32	iaddr5;			/* 0x.814 - Indivdual address register 5 */
-	u32	iaddr6;			/* 0x.818 - Indivdual address register 6 */
-	u32	iaddr7;			/* 0x.81c - Indivdual address register 7 */
+	u32	ifstat;		/* 0x.53c - Interface Status Register */
+	u32	macstnaddr1;	/* 0x.540 - Station Address Part 1 Register */
+	u32	macstnaddr2;	/* 0x.544 - Station Address Part 2 Register */
+	u32	mac01addr1;	/* 0x.548 - MAC exact match address 1, part 1 */
+	u32	mac01addr2;	/* 0x.54c - MAC exact match address 1, part 2 */
+	u32	mac02addr1;	/* 0x.550 - MAC exact match address 2, part 1 */
+	u32	mac02addr2;	/* 0x.554 - MAC exact match address 2, part 2 */
+	u32	mac03addr1;	/* 0x.558 - MAC exact match address 3, part 1 */
+	u32	mac03addr2;	/* 0x.55c - MAC exact match address 3, part 2 */
+	u32	mac04addr1;	/* 0x.560 - MAC exact match address 4, part 1 */
+	u32	mac04addr2;	/* 0x.564 - MAC exact match address 4, part 2 */
+	u32	mac05addr1;	/* 0x.568 - MAC exact match address 5, part 1 */
+	u32	mac05addr2;	/* 0x.56c - MAC exact match address 5, part 2 */
+	u32	mac06addr1;	/* 0x.570 - MAC exact match address 6, part 1 */
+	u32	mac06addr2;	/* 0x.574 - MAC exact match address 6, part 2 */
+	u32	mac07addr1;	/* 0x.578 - MAC exact match address 7, part 1 */
+	u32	mac07addr2;	/* 0x.57c - MAC exact match address 7, part 2 */
+	u32	mac08addr1;	/* 0x.580 - MAC exact match address 8, part 1 */
+	u32	mac08addr2;	/* 0x.584 - MAC exact match address 8, part 2 */
+	u32	mac09addr1;	/* 0x.588 - MAC exact match address 9, part 1 */
+	u32	mac09addr2;	/* 0x.58c - MAC exact match address 9, part 2 */
+	u32	mac10addr1;	/* 0x.590 - MAC exact match address 10, part 1*/
+	u32	mac10addr2;	/* 0x.594 - MAC exact match address 10, part 2*/
+	u32	mac11addr1;	/* 0x.598 - MAC exact match address 11, part 1*/
+	u32	mac11addr2;	/* 0x.59c - MAC exact match address 11, part 2*/
+	u32	mac12addr1;	/* 0x.5a0 - MAC exact match address 12, part 1*/
+	u32	mac12addr2;	/* 0x.5a4 - MAC exact match address 12, part 2*/
+	u32	mac13addr1;	/* 0x.5a8 - MAC exact match address 13, part 1*/
+	u32	mac13addr2;	/* 0x.5ac - MAC exact match address 13, part 2*/
+	u32	mac14addr1;	/* 0x.5b0 - MAC exact match address 14, part 1*/
+	u32	mac14addr2;	/* 0x.5b4 - MAC exact match address 14, part 2*/
+	u32	mac15addr1;	/* 0x.5b8 - MAC exact match address 15, part 1*/
+	u32	mac15addr2;	/* 0x.5bc - MAC exact match address 15, part 2*/
+	u8	res20[192];
+	struct rmon_mib	rmon;	/* 0x.680-0x.73c */
+	u32	rrej;		/* 0x.740 - Receive filer rejected packet counter */
+	u8	res21[188];
+	u32	igaddr0;	/* 0x.800 - Indivdual/Group address register 0*/
+	u32	igaddr1;	/* 0x.804 - Indivdual/Group address register 1*/
+	u32	igaddr2;	/* 0x.808 - Indivdual/Group address register 2*/
+	u32	igaddr3;	/* 0x.80c - Indivdual/Group address register 3*/
+	u32	igaddr4;	/* 0x.810 - Indivdual/Group address register 4*/
+	u32	igaddr5;	/* 0x.814 - Indivdual/Group address register 5*/
+	u32	igaddr6;	/* 0x.818 - Indivdual/Group address register 6*/
+	u32	igaddr7;	/* 0x.81c - Indivdual/Group address register 7*/
 	u8	res22[96];
-	u32	gaddr0;			/* 0x.880 - Global address register 0 */
-	u32	gaddr1;			/* 0x.884 - Global address register 1 */
-	u32	gaddr2;			/* 0x.888 - Global address register 2 */
-	u32	gaddr3;			/* 0x.88c - Global address register 3 */
-	u32	gaddr4;			/* 0x.890 - Global address register 4 */
-	u32	gaddr5;			/* 0x.894 - Global address register 5 */
-	u32	gaddr6;			/* 0x.898 - Global address register 6 */
-	u32	gaddr7;			/* 0x.89c - Global address register 7 */
-	u8	res23[856];
-	u32	attr;			/* 0x.bf8 - Attributes Register */
-	u32	attreli;		/* 0x.bfc - Attributes Extract Length and Extract Index Register */
+	u32	gaddr0;		/* 0x.880 - Group address register 0 */
+	u32	gaddr1;		/* 0x.884 - Group address register 1 */
+	u32	gaddr2;		/* 0x.888 - Group address register 2 */
+	u32	gaddr3;		/* 0x.88c - Group address register 3 */
+	u32	gaddr4;		/* 0x.890 - Group address register 4 */
+	u32	gaddr5;		/* 0x.894 - Group address register 5 */
+	u32	gaddr6;		/* 0x.898 - Group address register 6 */
+	u32	gaddr7;		/* 0x.89c - Group address register 7 */
+	u8	res23a[352];
+	u32	fifocfg;	/* 0x.a00 - FIFO interface config register */
+	u8	res23b[252];
+	u8	res23c[248];
+	u32	attr;		/* 0x.bf8 - Attributes Register */
+	u32	attreli;	/* 0x.bfc - Attributes Extract Length and Extract Index Register */
 	u8	res24[1024];
 
 };
@@ -496,6 +686,8 @@ struct gfar_private {
 	struct txbd8 *cur_tx;	        /* Next free ring entry */
 	struct txbd8 *dirty_tx;		/* The Ring entry to be freed. */
 	struct gfar *regs;	/* Pointer to the GFAR memory mapped Registers */
+	u32 *hash_regs[16];
+	int hash_width;
 	struct gfar *phyregs;
 	struct work_struct tq;
 	struct timer_list phy_info_timer;
@@ -506,9 +698,12 @@ struct gfar_private {
 	unsigned int rx_stash_size;
 	unsigned int tx_ring_size;
 	unsigned int rx_ring_size;
-	wait_queue_head_t rxcleanupq;
-	unsigned int rxclean;
 
+	unsigned char vlan_enable:1,
+		rx_csum_enable:1,
+		extended_hash:1;
+	unsigned short padding;
+	struct vlan_group *vlgrp;
 	/* Info structure initialized by board setup code */
 	unsigned int interruptTransmit;
 	unsigned int interruptReceive;
@@ -519,6 +714,8 @@ struct gfar_private {
 	int oldspeed;
 	int oldduplex;
 	int oldlink;
+
+	uint32_t msg_enable;
 };
 
 extern inline u32 gfar_read(volatile unsigned *addr)
diff --git a/drivers/net/gianfar_ethtool.c b/drivers/net/gianfar_ethtool.c
--- a/drivers/net/gianfar_ethtool.c
+++ b/drivers/net/gianfar_ethtool.c
@@ -46,16 +46,18 @@
 
 extern int startup_gfar(struct net_device *dev);
 extern void stop_gfar(struct net_device *dev);
-extern void gfar_receive(int irq, void *dev_id, struct pt_regs *regs);
+extern void gfar_halt(struct net_device *dev);
+extern void gfar_start(struct net_device *dev);
+extern int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit);
 
-void gfar_fill_stats(struct net_device *dev, struct ethtool_stats *dummy,
+static void gfar_fill_stats(struct net_device *dev, struct ethtool_stats *dummy,
 		     u64 * buf);
-void gfar_gstrings(struct net_device *dev, u32 stringset, u8 * buf);
-int gfar_gcoalesce(struct net_device *dev, struct ethtool_coalesce *cvals);
-int gfar_scoalesce(struct net_device *dev, struct ethtool_coalesce *cvals);
-void gfar_gringparam(struct net_device *dev, struct ethtool_ringparam *rvals);
-int gfar_sringparam(struct net_device *dev, struct ethtool_ringparam *rvals);
-void gfar_gdrvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo);
+static void gfar_gstrings(struct net_device *dev, u32 stringset, u8 * buf);
+static int gfar_gcoalesce(struct net_device *dev, struct ethtool_coalesce *cvals);
+static int gfar_scoalesce(struct net_device *dev, struct ethtool_coalesce *cvals);
+static void gfar_gringparam(struct net_device *dev, struct ethtool_ringparam *rvals);
+static int gfar_sringparam(struct net_device *dev, struct ethtool_ringparam *rvals);
+static void gfar_gdrvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo);
 
 static char stat_gstrings[][ETH_GSTRING_LEN] = {
 	"rx-dropped-by-kernel",
@@ -118,57 +120,56 @@ static char stat_gstrings[][ETH_GSTRING_
 	"tx-fragmented-frames",
 };
 
+/* Fill in a buffer with the strings which correspond to the
+ * stats */
+static void gfar_gstrings(struct net_device *dev, u32 stringset, u8 * buf)
+{
+	struct gfar_private *priv = netdev_priv(dev);
+	
+	if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_RMON)
+		memcpy(buf, stat_gstrings, GFAR_STATS_LEN * ETH_GSTRING_LEN);
+	else
+		memcpy(buf, stat_gstrings,
+				GFAR_EXTRA_STATS_LEN * ETH_GSTRING_LEN);
+}
+
 /* Fill in an array of 64-bit statistics from various sources.
  * This array will be appended to the end of the ethtool_stats
  * structure, and returned to user space
  */
-void gfar_fill_stats(struct net_device *dev, struct ethtool_stats *dummy, u64 * buf)
+static void gfar_fill_stats(struct net_device *dev, struct ethtool_stats *dummy, u64 * buf)
 {
 	int i;
 	struct gfar_private *priv = netdev_priv(dev);
-	u32 *rmon = (u32 *) & priv->regs->rmon;
 	u64 *extra = (u64 *) & priv->extra_stats;
-	struct gfar_stats *stats = (struct gfar_stats *) buf;
 
-	for (i = 0; i < GFAR_RMON_LEN; i++) {
-		stats->rmon[i] = (u64) (rmon[i]);
-	}
-
-	for (i = 0; i < GFAR_EXTRA_STATS_LEN; i++) {
-		stats->extra[i] = extra[i];
-	}
+	if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_RMON) {
+		u32 *rmon = (u32 *) & priv->regs->rmon;
+		struct gfar_stats *stats = (struct gfar_stats *) buf;
+
+		for (i = 0; i < GFAR_RMON_LEN; i++)
+			stats->rmon[i] = (u64) (rmon[i]);
+
+		for (i = 0; i < GFAR_EXTRA_STATS_LEN; i++)
+			stats->extra[i] = extra[i];
+	} else
+		for (i = 0; i < GFAR_EXTRA_STATS_LEN; i++)
+			buf[i] = extra[i];
 }
 
 /* Returns the number of stats (and their corresponding strings) */
-int gfar_stats_count(struct net_device *dev)
-{
-	return GFAR_STATS_LEN;
-}
-
-void gfar_gstrings_normon(struct net_device *dev, u32 stringset, u8 * buf)
-{
-	memcpy(buf, stat_gstrings, GFAR_EXTRA_STATS_LEN * ETH_GSTRING_LEN);
-}
-
-void gfar_fill_stats_normon(struct net_device *dev, 
-		struct ethtool_stats *dummy, u64 * buf)
+static int gfar_stats_count(struct net_device *dev)
 {
-	int i;
 	struct gfar_private *priv = netdev_priv(dev);
-	u64 *extra = (u64 *) & priv->extra_stats;
 
-	for (i = 0; i < GFAR_EXTRA_STATS_LEN; i++) {
-		buf[i] = extra[i];
-	}
+	if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_RMON)
+		return GFAR_STATS_LEN;
+	else
+		return GFAR_EXTRA_STATS_LEN;
 }
 
-
-int gfar_stats_count_normon(struct net_device *dev)
-{
-	return GFAR_EXTRA_STATS_LEN;
-}
 /* Fills in the drvinfo structure with some basic info */
-void gfar_gdrvinfo(struct net_device *dev, struct
+static void gfar_gdrvinfo(struct net_device *dev, struct
 	      ethtool_drvinfo *drvinfo)
 {
 	strncpy(drvinfo->driver, DRV_NAME, GFAR_INFOSTR_LEN);
@@ -182,7 +183,7 @@ void gfar_gdrvinfo(struct net_device *de
 }
 
 /* Return the current settings in the ethtool_cmd structure */
-int gfar_gsettings(struct net_device *dev, struct ethtool_cmd *cmd)
+static int gfar_gsettings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
 	struct gfar_private *priv = netdev_priv(dev);
 	uint gigabit_support = 
@@ -216,13 +217,13 @@ int gfar_gsettings(struct net_device *de
 }
 
 /* Return the length of the register structure */
-int gfar_reglen(struct net_device *dev)
+static int gfar_reglen(struct net_device *dev)
 {
 	return sizeof (struct gfar);
 }
 
 /* Return a dump of the GFAR register space */
-void gfar_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *regbuf)
+static void gfar_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *regbuf)
 {
 	int i;
 	struct gfar_private *priv = netdev_priv(dev);
@@ -233,13 +234,6 @@ void gfar_get_regs(struct net_device *de
 		buf[i] = theregs[i];
 }
 
-/* Fill in a buffer with the strings which correspond to the
- * stats */
-void gfar_gstrings(struct net_device *dev, u32 stringset, u8 * buf)
-{
-	memcpy(buf, stat_gstrings, GFAR_STATS_LEN * ETH_GSTRING_LEN);
-}
-
 /* Convert microseconds to ethernet clock ticks, which changes
  * depending on what speed the controller is running at */
 static unsigned int gfar_usecs2ticks(struct gfar_private *priv, unsigned int usecs)
@@ -291,9 +285,12 @@ static unsigned int gfar_ticks2usecs(str
 
 /* Get the coalescing parameters, and put them in the cvals
  * structure.  */
-int gfar_gcoalesce(struct net_device *dev, struct ethtool_coalesce *cvals)
+static int gfar_gcoalesce(struct net_device *dev, struct ethtool_coalesce *cvals)
 {
 	struct gfar_private *priv = netdev_priv(dev);
+	
+	if (!(priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_COALESCE))
+		return -EOPNOTSUPP;
 
 	cvals->rx_coalesce_usecs = gfar_ticks2usecs(priv, priv->rxtime);
 	cvals->rx_max_coalesced_frames = priv->rxcount;
@@ -337,10 +334,13 @@ int gfar_gcoalesce(struct net_device *de
  * Both cvals->*_usecs and cvals->*_frames have to be > 0
  * in order for coalescing to be active
  */
-int gfar_scoalesce(struct net_device *dev, struct ethtool_coalesce *cvals)
+static int gfar_scoalesce(struct net_device *dev, struct ethtool_coalesce *cvals)
 {
 	struct gfar_private *priv = netdev_priv(dev);
 
+	if (!(priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_COALESCE))
+		return -EOPNOTSUPP;
+
 	/* Set up rx coalescing */
 	if ((cvals->rx_coalesce_usecs == 0) ||
 	    (cvals->rx_max_coalesced_frames == 0))
@@ -379,7 +379,7 @@ int gfar_scoalesce(struct net_device *de
 /* Fills in rvals with the current ring parameters.  Currently,
  * rx, rx_mini, and rx_jumbo rings are the same size, as mini and
  * jumbo are ignored by the driver */
-void gfar_gringparam(struct net_device *dev, struct ethtool_ringparam *rvals)
+static void gfar_gringparam(struct net_device *dev, struct ethtool_ringparam *rvals)
 {
 	struct gfar_private *priv = netdev_priv(dev);
 
@@ -401,9 +401,8 @@ void gfar_gringparam(struct net_device *
  * necessary so that we don't mess things up while we're in
  * motion.  We wait for the ring to be clean before reallocating
  * the rings. */
-int gfar_sringparam(struct net_device *dev, struct ethtool_ringparam *rvals)
+static int gfar_sringparam(struct net_device *dev, struct ethtool_ringparam *rvals)
 {
-	u32 tempval;
 	struct gfar_private *priv = netdev_priv(dev);
 	int err = 0;
 
@@ -425,37 +424,54 @@ int gfar_sringparam(struct net_device *d
 		return -EINVAL;
 	}
 
-	/* Stop the controller so we don't rx any more frames */
-	/* But first, make sure we clear the bits */
-	tempval = gfar_read(&priv->regs->dmactrl);
-	tempval &= ~(DMACTRL_GRS | DMACTRL_GTS);
-	gfar_write(&priv->regs->dmactrl, tempval);
-
-	tempval = gfar_read(&priv->regs->dmactrl);
-	tempval |= (DMACTRL_GRS | DMACTRL_GTS);
-	gfar_write(&priv->regs->dmactrl, tempval);
+	if (dev->flags & IFF_UP) {
+		unsigned long flags;
 
-	while (!(gfar_read(&priv->regs->ievent) & (IEVENT_GRSC | IEVENT_GTSC)))
-		cpu_relax();
+		/* Halt TX and RX, and process the frames which
+		 * have already been received */
+		spin_lock_irqsave(&priv->lock, flags);
+		gfar_halt(dev);
+		gfar_clean_rx_ring(dev, priv->rx_ring_size);
+		spin_unlock_irqrestore(&priv->lock, flags);
 
-	/* Note that rx is not clean right now */
-	priv->rxclean = 0;
+		/* Now we take down the rings to rebuild them */
+		stop_gfar(dev);
+	}
 
-	if (dev->flags & IFF_UP) {
-		/* Tell the driver to process the rest of the frames */
-		gfar_receive(0, (void *) dev, NULL);
+	/* Change the size */
+	priv->rx_ring_size = rvals->rx_pending;
+	priv->tx_ring_size = rvals->tx_pending;
+
+	/* Rebuild the rings with the new size */
+	if (dev->flags & IFF_UP)
+		err = startup_gfar(dev);
+
+	return err;
+}
+
+static int gfar_set_rx_csum(struct net_device *dev, uint32_t data)
+{
+	struct gfar_private *priv = netdev_priv(dev);
+	int err = 0;
 
-		/* Now wait for it to be done */
-		wait_event_interruptible(priv->rxcleanupq, priv->rxclean);
+	if (!(priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_CSUM))
+		return -EOPNOTSUPP;
 
-		/* Ok, all packets have been handled.  Now we bring it down,
-		 * change the ring size, and bring it up */
+	if (dev->flags & IFF_UP) {
+		unsigned long flags;
 
+		/* Halt TX and RX, and process the frames which
+		 * have already been received */
+		spin_lock_irqsave(&priv->lock, flags);
+		gfar_halt(dev);
+		gfar_clean_rx_ring(dev, priv->rx_ring_size);
+		spin_unlock_irqrestore(&priv->lock, flags);
+
+		/* Now we take down the rings to rebuild them */
 		stop_gfar(dev);
 	}
 
-	priv->rx_ring_size = rvals->rx_pending;
-	priv->tx_ring_size = rvals->tx_pending;
+	priv->rx_csum_enable = data;
 
 	if (dev->flags & IFF_UP)
 		err = startup_gfar(dev);
@@ -463,6 +479,61 @@ int gfar_sringparam(struct net_device *d
 	return err;
 }
 
+static uint32_t gfar_get_rx_csum(struct net_device *dev)
+{
+	struct gfar_private *priv = netdev_priv(dev);
+
+	if (!(priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_CSUM))
+		return 0;
+
+	return priv->rx_csum_enable;
+}
+
+static int gfar_set_tx_csum(struct net_device *dev, uint32_t data)
+{
+	unsigned long flags;
+	struct gfar_private *priv = netdev_priv(dev);
+
+	if (!(priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_CSUM))
+		return -EOPNOTSUPP;
+
+	spin_lock_irqsave(&priv->lock, flags);
+	gfar_halt(dev);
+
+	if (data)
+		dev->features |= NETIF_F_IP_CSUM;
+	else
+		dev->features &= ~NETIF_F_IP_CSUM;
+
+	gfar_start(dev);
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	return 0;
+}
+
+static uint32_t gfar_get_tx_csum(struct net_device *dev)
+{
+	struct gfar_private *priv = netdev_priv(dev);
+
+	if (!(priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_CSUM))
+		return 0;
+
+	return (dev->features & NETIF_F_IP_CSUM) != 0;
+}
+
+static uint32_t gfar_get_msglevel(struct net_device *dev)
+{       
+	struct gfar_private *priv = netdev_priv(dev);
+	return priv->msg_enable;
+}       
+        
+static void gfar_set_msglevel(struct net_device *dev, uint32_t data)
+{       
+	struct gfar_private *priv = netdev_priv(dev);
+	priv->msg_enable = data;
+}
+
+
 struct ethtool_ops gfar_ethtool_ops = {
 	.get_settings = gfar_gsettings,
 	.get_drvinfo = gfar_gdrvinfo,
@@ -476,52 +547,10 @@ struct ethtool_ops gfar_ethtool_ops = {
 	.get_strings = gfar_gstrings,
 	.get_stats_count = gfar_stats_count,
 	.get_ethtool_stats = gfar_fill_stats,
-};
-
-struct ethtool_ops gfar_normon_nocoalesce_ethtool_ops = {
-	.get_settings = gfar_gsettings,
-	.get_drvinfo = gfar_gdrvinfo,
-	.get_regs_len = gfar_reglen,
-	.get_regs = gfar_get_regs,
-	.get_link = ethtool_op_get_link,
-	.get_ringparam = gfar_gringparam,
-	.set_ringparam = gfar_sringparam,
-	.get_strings = gfar_gstrings_normon,
-	.get_stats_count = gfar_stats_count_normon,
-	.get_ethtool_stats = gfar_fill_stats_normon,
-};
-
-struct ethtool_ops gfar_nocoalesce_ethtool_ops = {
-	.get_settings = gfar_gsettings,
-	.get_drvinfo = gfar_gdrvinfo,
-	.get_regs_len = gfar_reglen,
-	.get_regs = gfar_get_regs,
-	.get_link = ethtool_op_get_link,
-	.get_ringparam = gfar_gringparam,
-	.set_ringparam = gfar_sringparam,
-	.get_strings = gfar_gstrings,
-	.get_stats_count = gfar_stats_count,
-	.get_ethtool_stats = gfar_fill_stats,
-};
-
-struct ethtool_ops gfar_normon_ethtool_ops = {
-	.get_settings = gfar_gsettings,
-	.get_drvinfo = gfar_gdrvinfo,
-	.get_regs_len = gfar_reglen,
-	.get_regs = gfar_get_regs,
-	.get_link = ethtool_op_get_link,
-	.get_coalesce = gfar_gcoalesce,
-	.set_coalesce = gfar_scoalesce,
-	.get_ringparam = gfar_gringparam,
-	.set_ringparam = gfar_sringparam,
-	.get_strings = gfar_gstrings_normon,
-	.get_stats_count = gfar_stats_count_normon,
-	.get_ethtool_stats = gfar_fill_stats_normon,
-};
-
-struct ethtool_ops *gfar_op_array[] = {
-	&gfar_ethtool_ops,
-	&gfar_normon_ethtool_ops,
-	&gfar_nocoalesce_ethtool_ops,
-	&gfar_normon_nocoalesce_ethtool_ops
+	.get_rx_csum = gfar_get_rx_csum,
+	.get_tx_csum = gfar_get_tx_csum,
+	.set_rx_csum = gfar_set_rx_csum,
+	.set_tx_csum = gfar_set_tx_csum,
+	.get_msglevel = gfar_get_msglevel,
+	.set_msglevel = gfar_set_msglevel,
 };
diff --git a/drivers/net/gianfar_phy.c b/drivers/net/gianfar_phy.c
--- a/drivers/net/gianfar_phy.c
+++ b/drivers/net/gianfar_phy.c
@@ -572,7 +572,7 @@ static struct phy_info phy_info_dm9161 =
 static struct phy_info phy_info_marvell = {
 	.phy_id		= 0x01410c00,
 	.phy_id_mask	= 0xffffff00,
-	.name		= "Marvell 88E1101",
+	.name		= "Marvell 88E1101/88E1111",
 	.features	= MII_GBIT_FEATURES,
 	.config_aneg	= &marvell_config_aneg,
 	.read_status	= &marvell_read_status,
diff --git a/drivers/net/hamachi.c b/drivers/net/hamachi.c
--- a/drivers/net/hamachi.c
+++ b/drivers/net/hamachi.c
@@ -1149,7 +1149,7 @@ static void hamachi_tx_timeout(struct ne
 		skb->dev = dev;         /* Mark as being used by this device. */
 		skb_reserve(skb, 2); /* 16 byte align the IP header. */
                 hmp->rx_ring[i].addr = cpu_to_leXX(pci_map_single(hmp->pci_dev, 
-			skb->tail, hmp->rx_buf_sz, PCI_DMA_FROMDEVICE));
+			skb->data, hmp->rx_buf_sz, PCI_DMA_FROMDEVICE));
 		hmp->rx_ring[i].status_n_length = cpu_to_le32(DescOwn | 
 			DescEndPacket | DescIntr | (hmp->rx_buf_sz - 2));
 	}
@@ -1210,7 +1210,7 @@ static void hamachi_init_ring(struct net
 		skb->dev = dev;         /* Mark as being used by this device. */
 		skb_reserve(skb, 2); /* 16 byte align the IP header. */
                 hmp->rx_ring[i].addr = cpu_to_leXX(pci_map_single(hmp->pci_dev, 
-			skb->tail, hmp->rx_buf_sz, PCI_DMA_FROMDEVICE));
+			skb->data, hmp->rx_buf_sz, PCI_DMA_FROMDEVICE));
 		/* -2 because it doesn't REALLY have that first 2 bytes -KDU */
 		hmp->rx_ring[i].status_n_length = cpu_to_le32(DescOwn | 
 			DescEndPacket | DescIntr | (hmp->rx_buf_sz -2));
@@ -1509,7 +1509,7 @@ static int hamachi_rx(struct net_device 
 					    desc->addr,
 					    hmp->rx_buf_sz,
 					    PCI_DMA_FROMDEVICE);
-		buf_addr = (u8 *) hmp->rx_skbuff[entry]->tail;
+		buf_addr = (u8 *) hmp->rx_skbuff[entry]->data;
 		frame_status = le32_to_cpu(get_unaligned((s32*)&(buf_addr[data_size - 12])));
 		if (hamachi_debug > 4)
 			printk(KERN_DEBUG "  hamachi_rx() status was %8.8x.\n",
@@ -1678,7 +1678,7 @@ static int hamachi_rx(struct net_device 
 			skb->dev = dev;		/* Mark as being used by this device. */
 			skb_reserve(skb, 2);	/* Align IP on 16 byte boundaries */
                 	desc->addr = cpu_to_leXX(pci_map_single(hmp->pci_dev, 
-				skb->tail, hmp->rx_buf_sz, PCI_DMA_FROMDEVICE));
+				skb->data, hmp->rx_buf_sz, PCI_DMA_FROMDEVICE));
 		}
 		desc->status_n_length = cpu_to_le32(hmp->rx_buf_sz);
 		if (entry >= RX_RING_SIZE-1)
@@ -1772,9 +1772,9 @@ static int hamachi_close(struct net_devi
 				   readl(ioaddr + RxCurPtr) == (long)&hmp->rx_ring[i] ? '>' : ' ',
 				   i, hmp->rx_ring[i].status_n_length, hmp->rx_ring[i].addr);
 			if (hamachi_debug > 6) {
-				if (*(u8*)hmp->rx_skbuff[i]->tail != 0x69) {
+				if (*(u8*)hmp->rx_skbuff[i]->data != 0x69) {
 					u16 *addr = (u16 *)
-						hmp->rx_skbuff[i]->tail;
+						hmp->rx_skbuff[i]->data;
 					int j;
 
 					for (j = 0; j < 0x50; j++)
diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c
--- a/drivers/net/hamradio/6pack.c
+++ b/drivers/net/hamradio/6pack.c
@@ -130,12 +130,11 @@ struct sixpack {
 
 #define AX25_6PACK_HEADER_LEN 0
 
-static void sp_start_tx_timer(struct sixpack *);
 static void sixpack_decode(struct sixpack *, unsigned char[], int);
 static int encode_sixpack(unsigned char *, unsigned char *, int, unsigned char);
 
 /*
- * perform the persistence/slottime algorithm for CSMA access. If the
+ * Perform the persistence/slottime algorithm for CSMA access. If the
  * persistence check was successful, write the data to the serial driver.
  * Note that in case of DAMA operation, the data is not sent here.
  */
@@ -143,7 +142,7 @@ static int encode_sixpack(unsigned char 
 static void sp_xmit_on_air(unsigned long channel)
 {
 	struct sixpack *sp = (struct sixpack *) channel;
-	int actual;
+	int actual, when = sp->slottime;
 	static unsigned char random;
 
 	random = random * 17 + 41;
@@ -159,20 +158,10 @@ static void sp_xmit_on_air(unsigned long
 		sp->tty->driver->write(sp->tty, &sp->led_state, 1);
 		sp->status2 = 0;
 	} else
-		sp_start_tx_timer(sp);
+		mod_timer(&sp->tx_t, jiffies + ((when + 1) * HZ) / 100);
 }
 
 /* ----> 6pack timer interrupt handler and friends. <---- */
-static void sp_start_tx_timer(struct sixpack *sp)
-{
-	int when = sp->slottime;
-
-	del_timer(&sp->tx_t);
-	sp->tx_t.data = (unsigned long) sp;
-	sp->tx_t.function = sp_xmit_on_air;
-	sp->tx_t.expires = jiffies + ((when + 1) * HZ) / 100;
-	add_timer(&sp->tx_t);
-}
 
 /* Encapsulate one AX.25 frame and stuff into a TTY queue. */
 static void sp_encaps(struct sixpack *sp, unsigned char *icp, int len)
@@ -243,8 +232,7 @@ static void sp_encaps(struct sixpack *sp
 		sp->xleft = count;
 		sp->xhead = sp->xbuff;
 		sp->status2 = count;
-		if (sp->duplex == 0)
-			sp_start_tx_timer(sp);
+		sp_xmit_on_air((unsigned long)sp);
 	}
 
 	return;
@@ -320,12 +308,6 @@ static int sp_set_mac_address(struct net
 {
 	struct sockaddr_ax25 *sa = addr;
 
-	if (sa->sax25_family != AF_AX25)
-		return -EINVAL;
-
-	if (!sa->sax25_ndigis)
-		return -EINVAL;
-
 	spin_lock_irq(&dev->xmit_lock);
 	memcpy(dev->dev_addr, &sa->sax25_call, AX25_ADDR_LEN);
 	spin_unlock_irq(&dev->xmit_lock);
@@ -680,6 +662,9 @@ static int sixpack_open(struct tty_struc
 	netif_start_queue(dev);
 
 	init_timer(&sp->tx_t);
+	sp->tx_t.function = sp_xmit_on_air;
+	sp->tx_t.data = (unsigned long) sp;
+
 	init_timer(&sp->resync_t);
 
 	spin_unlock_bh(&sp->lock);
@@ -848,7 +833,7 @@ static void __exit sixpack_exit_driver(v
 {
 	int ret;
 
-	if ((ret = tty_register_ldisc(N_6PACK, NULL)))
+	if ((ret = tty_unregister_ldisc(N_6PACK)))
 		printk(msg_unregfail, ret);
 }
 
diff --git a/drivers/net/hamradio/Kconfig b/drivers/net/hamradio/Kconfig
--- a/drivers/net/hamradio/Kconfig
+++ b/drivers/net/hamradio/Kconfig
@@ -17,7 +17,7 @@ config MKISS
 
 config 6PACK
 	tristate "Serial port 6PACK driver"
-	depends on AX25 && BROKEN_ON_SMP
+	depends on AX25
 	---help---
 	  6pack is a transmission protocol for the data exchange between your
 	  PC and your TNC (the Terminal Node Controller acts as a kind of
diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c
--- a/drivers/net/hamradio/mkiss.c
+++ b/drivers/net/hamradio/mkiss.c
@@ -934,7 +934,7 @@ static void __exit mkiss_exit_driver(voi
 	kfree(ax25_ctrls);
 	ax25_ctrls = NULL;
 
-	if ((i = tty_register_ldisc(N_AX25, NULL)))
+	if ((i = tty_unregister_ldisc(N_AX25)))
 		printk(KERN_ERR "mkiss: can't unregister line discipline (err = %d)\n", i);
 }
 
diff --git a/drivers/net/hamradio/scc.c b/drivers/net/hamradio/scc.c
--- a/drivers/net/hamradio/scc.c
+++ b/drivers/net/hamradio/scc.c
@@ -304,7 +304,7 @@ static inline void scc_discard_buffers(s
 		scc->tx_buff = NULL;
 	}
 	
-	while (skb_queue_len(&scc->tx_queue))
+	while (!skb_queue_empty(&scc->tx_queue))
 		dev_kfree_skb(skb_dequeue(&scc->tx_queue));
 
 	spin_unlock_irqrestore(&scc->lock, flags);
@@ -1126,8 +1126,7 @@ static void t_dwait(unsigned long channe
 	
 	if (scc->stat.tx_state == TXS_WAIT)	/* maxkeyup or idle timeout */
 	{
-		if (skb_queue_len(&scc->tx_queue) == 0)	/* nothing to send */
-		{
+		if (skb_queue_empty(&scc->tx_queue)) {	/* nothing to send */
 			scc->stat.tx_state = TXS_IDLE;
 			netif_wake_queue(scc->dev);	/* t_maxkeyup locked it. */
 			return;
diff --git a/drivers/net/hp-plus.c b/drivers/net/hp-plus.c
--- a/drivers/net/hp-plus.c
+++ b/drivers/net/hp-plus.c
@@ -159,12 +159,7 @@ struct net_device * __init hp_plus_probe
 	err = do_hpp_probe(dev);
 	if (err)
 		goto out;
-	err = register_netdev(dev);
-	if (err)
-		goto out1;
 	return dev;
-out1:
-	cleanup_card(dev);
 out:
 	free_netdev(dev);
 	return ERR_PTR(err);
@@ -271,6 +266,9 @@ static int __init hpp_probe1(struct net_
 	/* Leave the 8390 and HP chip reset. */
 	outw(inw(ioaddr + HPP_OPTION) & ~EnableIRQ, ioaddr + HPP_OPTION);
 
+	retval = register_netdev(dev);
+	if (retval)
+		goto out;
 	return 0;
 out:
 	release_region(ioaddr, HP_IO_EXTENT);
@@ -463,11 +461,8 @@ init_module(void)
 		dev->irq = irq[this_dev];
 		dev->base_addr = io[this_dev];
 		if (do_hpp_probe(dev) == 0) {
-			if (register_netdev(dev) == 0) {
-				dev_hpp[found++] = dev;
-				continue;
-			}
-			cleanup_card(dev);
+			dev_hpp[found++] = dev;
+			continue;
 		}
 		free_netdev(dev);
 		printk(KERN_WARNING "hp-plus.c: No HP-Plus card found (i/o = 0x%x).\n", io[this_dev]);
diff --git a/drivers/net/hp.c b/drivers/net/hp.c
--- a/drivers/net/hp.c
+++ b/drivers/net/hp.c
@@ -123,12 +123,7 @@ struct net_device * __init hp_probe(int 
 	err = do_hp_probe(dev);
 	if (err)
 		goto out;
-	err = register_netdev(dev);
-	if (err)
-		goto out1;
 	return dev;
-out1:
-	cleanup_card(dev);
 out:
 	free_netdev(dev);
 	return ERR_PTR(err);
@@ -227,7 +222,12 @@ static int __init hp_probe1(struct net_d
 	ei_status.block_output = &hp_block_output;
 	hp_init_card(dev);
 
+	retval = register_netdev(dev);
+	if (retval)
+		goto out1;
 	return 0;
+out1:
+	free_irq(dev->irq, dev);
 out:
 	release_region(ioaddr, HP_IO_EXTENT);
 	return retval;
@@ -432,11 +432,8 @@ init_module(void)
 		dev->irq = irq[this_dev];
 		dev->base_addr = io[this_dev];
 		if (do_hp_probe(dev) == 0) {
-			if (register_netdev(dev) == 0) {
-				dev_hp[found++] = dev;
-				continue;
-			}
-			cleanup_card(dev);
+			dev_hp[found++] = dev;
+			continue;
 		}
 		free_netdev(dev);
 		printk(KERN_WARNING "hp.c: No HP card found (i/o = 0x%x).\n", io[this_dev]);
diff --git a/drivers/net/hp100.c b/drivers/net/hp100.c
--- a/drivers/net/hp100.c
+++ b/drivers/net/hp100.c
@@ -106,6 +106,7 @@
 #include <linux/interrupt.h>
 #include <linux/eisa.h>
 #include <linux/pci.h>
+#include <linux/dma-mapping.h>
 #include <linux/spinlock.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
@@ -417,12 +418,7 @@ struct net_device * __init hp100_probe(i
 	if (err)
 		goto out;
 
-	err = register_netdev(dev);
-	if (err)
-		goto out1;
 	return dev;
- out1:
-	release_region(dev->base_addr, HP100_REGION_SIZE);
  out:
 	free_netdev(dev);
 	return ERR_PTR(err);
@@ -562,7 +558,7 @@ static int __devinit hp100_probe1(struct
 			 * Also, we can have EISA Busmaster cards (not tested),
 			 * so beware !!! - Jean II */
 			if((bus == HP100_BUS_PCI) &&
-			   (pci_set_dma_mask(pci_dev, 0xffffffff))) {
+			   (pci_set_dma_mask(pci_dev, DMA_32BIT_MASK))) {
 				/* Gracefully fallback to shared memory */
 				goto busmasterfail;
 			}
@@ -776,11 +772,22 @@ static int __devinit hp100_probe1(struct
 		printk("Warning! Link down.\n");
 	}
 
+	err = register_netdev(dev);
+	if (err)
+		goto out3;
+
 	return 0;
+out3:
+	if (local_mode == 1)
+		pci_free_consistent(lp->pci_dev, MAX_RINGSIZE + 0x0f, 
+				    lp->page_vaddr_algn, 
+				    virt_to_whatever(dev, lp->page_vaddr_algn));
+	if (mem_ptr_virt)
+		iounmap(mem_ptr_virt);
 out2:
 	release_region(ioaddr, HP100_REGION_SIZE);
 out1:
-	return -ENODEV;
+	return err;
 }
 
 /* This procedure puts the card into a stable init state */
@@ -2875,18 +2882,12 @@ static int __init hp100_eisa_probe (stru
 	if (err)
 		goto out1;
 
-	err = register_netdev(dev);
-	if (err)
-		goto out2;
-	
 #ifdef HP100_DEBUG
 	printk("hp100: %s: EISA adapter found at 0x%x\n", dev->name, 
 	       dev->base_addr);
 #endif
 	gendev->driver_data = dev;
 	return 0;
- out2:
-	release_region(dev->base_addr, HP100_REGION_SIZE);
  out1:
 	free_netdev(dev);
 	return err;
@@ -2951,17 +2952,12 @@ static int __devinit hp100_pci_probe (st
 	err = hp100_probe1(dev, ioaddr, HP100_BUS_PCI, pdev);
 	if (err) 
 		goto out1;
-	err = register_netdev(dev);
-	if (err)
-		goto out2;
 	
 #ifdef HP100_DEBUG
 	printk("hp100: %s: PCI adapter found at 0x%x\n", dev->name, ioaddr);
 #endif
 	pci_set_drvdata(pdev, dev);
 	return 0;
- out2:
-	release_region(dev->base_addr, HP100_REGION_SIZE);
  out1:
 	free_netdev(dev);
  out0:
@@ -3032,15 +3028,9 @@ static int __init hp100_isa_init(void)
 		SET_MODULE_OWNER(dev);
 
 		err = hp100_isa_probe(dev, hp100_port[i]);
-		if (!err) {
-			err = register_netdev(dev);
-			if (!err) 
-				hp100_devlist[cards++] = dev;
-			else
-				release_region(dev->base_addr, HP100_REGION_SIZE);
-		}
-
-		if (err)
+		if (!err)
+			hp100_devlist[cards++] = dev;
+		else
 			free_netdev(dev);
 	}
 
diff --git a/drivers/net/ibm_emac/ibm_emac_core.c b/drivers/net/ibm_emac/ibm_emac_core.c
--- a/drivers/net/ibm_emac/ibm_emac_core.c
+++ b/drivers/net/ibm_emac/ibm_emac_core.c
@@ -1253,7 +1253,7 @@ static int emac_init_tah(struct ocp_enet
 		 TAH_MR_CVR | TAH_MR_ST_768 | TAH_MR_TFS_10KB | TAH_MR_DTFP |
 		 TAH_MR_DIG);
 
-	iounmap(&tahp);
+	iounmap(tahp);
 
 	return 0;
 }
@@ -1712,11 +1712,10 @@ struct mal_commac_ops emac_commac_ops = 
 };
 
 #ifdef CONFIG_NET_POLL_CONTROLLER
-static int emac_netpoll(struct net_device *ndev)
+static void emac_netpoll(struct net_device *ndev)
 {
 	emac_rxeob_dev((void *)ndev, 0);
 	emac_txeob_dev((void *)ndev, 0);
-	return 0;
 }
 #endif
 
diff --git a/drivers/net/ioc3-eth.c b/drivers/net/ioc3-eth.c
--- a/drivers/net/ioc3-eth.c
+++ b/drivers/net/ioc3-eth.c
@@ -499,7 +499,7 @@ static int ioc3_mdio_read(struct net_dev
 	ioc3_w_micr((phy << MICR_PHYADDR_SHIFT) | reg | MICR_READTRIG);
 	while (ioc3_r_micr() & MICR_BUSY);
 
-	return ioc3_r_micr() & MIDR_DATA_MASK;
+	return ioc3_r_midr_r() & MIDR_DATA_MASK;
 }
 
 static void ioc3_mdio_write(struct net_device *dev, int phy, int reg, int data)
@@ -1291,7 +1291,6 @@ static int ioc3_probe(struct pci_dev *pd
 	dev->features		= NETIF_F_IP_CSUM;
 #endif
 
-	ioc3_setup_duplex(ip);
 	sw_physid1 = ioc3_mdio_read(dev, ip->mii.phy_id, MII_PHYSID1);
 	sw_physid2 = ioc3_mdio_read(dev, ip->mii.phy_id, MII_PHYSID2);
 
@@ -1300,6 +1299,7 @@ static int ioc3_probe(struct pci_dev *pd
 		goto out_stop;
 
 	mii_check_media(&ip->mii, 1, 1);
+	ioc3_setup_duplex(ip);
 
 	vendor = (sw_physid1 << 12) | (sw_physid2 >> 4);
 	model  = (sw_physid2 >> 4) & 0x3f;
@@ -1524,7 +1524,7 @@ static void ioc3_get_drvinfo (struct net
 	struct ethtool_drvinfo *info)
 {
 	struct ioc3_private *ip = netdev_priv(dev);
-                                                                                
+
         strcpy (info->driver, IOC3_NAME);
         strcpy (info->version, IOC3_VERSION);
         strcpy (info->bus_info, pci_name(ip->pdev));
@@ -1550,7 +1550,7 @@ static int ioc3_set_settings(struct net_
 	spin_lock_irq(&ip->ioc3_lock);
 	rc = mii_ethtool_sset(&ip->mii, cmd);
 	spin_unlock_irq(&ip->ioc3_lock);
-                                                                        
+
 	return rc;
 }
 
diff --git a/drivers/net/irda/irtty-sir.c b/drivers/net/irda/irtty-sir.c
--- a/drivers/net/irda/irtty-sir.c
+++ b/drivers/net/irda/irtty-sir.c
@@ -626,7 +626,7 @@ static void __exit irtty_sir_cleanup(voi
 {
 	int err;
 
-	if ((err = tty_register_ldisc(N_IRDA, NULL))) {
+	if ((err = tty_unregister_ldisc(N_IRDA))) {
 		IRDA_ERROR("%s(), can't unregister line discipline (err = %d)\n",
 			   __FUNCTION__, err);
 	}
diff --git a/drivers/net/irda/sir_kthread.c b/drivers/net/irda/sir_kthread.c
--- a/drivers/net/irda/sir_kthread.c
+++ b/drivers/net/irda/sir_kthread.c
@@ -135,8 +135,7 @@ static int irda_thread(void *startup)
 		remove_wait_queue(&irda_rq_queue.kick, &wait);
 
 		/* make swsusp happy with our thread */
-		if (current->flags & PF_FREEZE)
-			refrigerator(PF_FREEZE);
+		try_to_freeze();
 
 		run_irda_queue();
 	}
diff --git a/drivers/net/irda/stir4200.c b/drivers/net/irda/stir4200.c
--- a/drivers/net/irda/stir4200.c
+++ b/drivers/net/irda/stir4200.c
@@ -763,7 +763,7 @@ static int stir_transmit_thread(void *ar
 	{
 #ifdef CONFIG_PM
 		/* if suspending, then power off and wait */
-		if (unlikely(current->flags & PF_FREEZE)) {
+		if (unlikely(freezing(current))) {
 			if (stir->receiving)
 				receive_stop(stir);
 			else
@@ -771,7 +771,7 @@ static int stir_transmit_thread(void *ar
 
 			write_reg(stir, REG_CTRL1, CTRL1_TXPWD|CTRL1_RXPWD);
 
-			refrigerator(PF_FREEZE);
+			refrigerator();
 
 			if (change_speed(stir, stir->speed))
 				break;
diff --git a/drivers/net/isa-skeleton.c b/drivers/net/isa-skeleton.c
--- a/drivers/net/isa-skeleton.c
+++ b/drivers/net/isa-skeleton.c
@@ -176,12 +176,7 @@ struct net_device * __init netcard_probe
 	err = do_netcard_probe(dev);
 	if (err)
 		goto out;
-	err = register_netdev(dev);
-	if (err)
-		goto out1;
 	return dev;
-out1:
-	cleanup_card(dev);
 out:
 	free_netdev(dev);
 	return ERR_PTR(err);
@@ -316,7 +311,15 @@ static int __init netcard_probe1(struct 
 
         dev->tx_timeout		= &net_tx_timeout;
         dev->watchdog_timeo	= MY_TX_TIMEOUT; 
+
+	err = register_netdev(dev);
+	if (err)
+		goto out2;
 	return 0;
+out2:
+#ifdef jumpered_dma
+	free_dma(dev->dma);
+#endif
 out1:
 #ifdef jumpered_interrupts
 	free_irq(dev->irq, dev);
@@ -691,11 +694,8 @@ int init_module(void)
 	dev->dma       = dma;
 	dev->mem_start = mem;
 	if (do_netcard_probe(dev) == 0) {
-		if (register_netdev(dev) == 0)
-			this_device = dev;
-			return 0;
-		}
-		cleanup_card(dev);
+		this_device = dev;
+		return 0;
 	}
 	free_netdev(dev);
 	return -ENXIO;
diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c
--- a/drivers/net/ixgb/ixgb_main.c
+++ b/drivers/net/ixgb/ixgb_main.c
@@ -47,7 +47,9 @@ char ixgb_driver_string[] = "Intel(R) PR
 #else
 #define DRIVERNAPI "-NAPI"
 #endif
-char ixgb_driver_version[] = "1.0.95-k2"DRIVERNAPI;
+
+#define DRV_VERSION "1.0.95-k2"DRIVERNAPI
+char ixgb_driver_version[] = DRV_VERSION;
 char ixgb_copyright[] = "Copyright (c) 1999-2005 Intel Corporation.";
 
 /* ixgb_pci_tbl - PCI Device ID Table
@@ -140,6 +142,7 @@ static struct pci_driver ixgb_driver = {
 MODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>");
 MODULE_DESCRIPTION("Intel(R) PRO/10GbE Network Driver");
 MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_VERSION);
 
 /* some defines for controlling descriptor fetches in h/w */
 #define RXDCTL_PTHRESH_DEFAULT 128	/* chip considers prefech below this */
diff --git a/drivers/net/lance.c b/drivers/net/lance.c
--- a/drivers/net/lance.c
+++ b/drivers/net/lance.c
@@ -356,11 +356,8 @@ int init_module(void)
 		dev->base_addr = io[this_dev];
 		dev->dma = dma[this_dev];
 		if (do_lance_probe(dev) == 0) {
-			if (register_netdev(dev) == 0) {
-				dev_lance[found++] = dev;
-				continue;
-			}
-			cleanup_card(dev);
+			dev_lance[found++] = dev;
+			continue;
 		}
 		free_netdev(dev);
 		break;
@@ -448,12 +445,7 @@ struct net_device * __init lance_probe(i
 	err = do_lance_probe(dev);
 	if (err)
 		goto out;
-	err = register_netdev(dev);
-	if (err)
-		goto out1;
 	return dev;
-out1:
-	cleanup_card(dev);
 out:
 	free_netdev(dev);
 	return ERR_PTR(err);
@@ -724,6 +716,9 @@ static int __init lance_probe1(struct ne
 	dev->tx_timeout = lance_tx_timeout;
 	dev->watchdog_timeo = TX_TIMEOUT;
 
+	err = register_netdev(dev);
+	if (err)
+		goto out_dma;
 	return 0;
 out_dma:
 	if (dev->dma != 4)
@@ -867,7 +862,7 @@ lance_init_ring(struct net_device *dev, 
 		lp->rx_skbuff[i] = skb;
 		if (skb) {
 			skb->dev = dev;
-			rx_buff = skb->tail;
+			rx_buff = skb->data;
 		} else
 			rx_buff = kmalloc(PKT_BUF_SZ, GFP_DMA | gfp);
 		if (rx_buff == NULL)
diff --git a/drivers/net/lasi_82596.c b/drivers/net/lasi_82596.c
--- a/drivers/net/lasi_82596.c
+++ b/drivers/net/lasi_82596.c
@@ -553,14 +553,14 @@ static inline void init_rx_bufs(struct n
 		if (skb == NULL)
 			panic("%s: alloc_skb() failed", __FILE__);
 		skb_reserve(skb, 2);
-		dma_addr = dma_map_single(lp->dev, skb->tail,PKT_BUF_SZ,
+		dma_addr = dma_map_single(lp->dev, skb->data,PKT_BUF_SZ,
 					  DMA_FROM_DEVICE);
 		skb->dev = dev;
 		rbd->v_next = rbd+1;
 		rbd->b_next = WSWAPrbd(virt_to_dma(lp,rbd+1));
 		rbd->b_addr = WSWAPrbd(virt_to_dma(lp,rbd));
 		rbd->skb = skb;
-		rbd->v_data = skb->tail;
+		rbd->v_data = skb->data;
 		rbd->b_data = WSWAPchar(dma_addr);
 		rbd->size = PKT_BUF_SZ;
 	}
@@ -783,8 +783,8 @@ static inline int i596_rx(struct net_dev
 				rx_in_place = 1;
 				rbd->skb = newskb;
 				newskb->dev = dev;
-				dma_addr = dma_map_single(lp->dev, newskb->tail, PKT_BUF_SZ, DMA_FROM_DEVICE);
-				rbd->v_data = newskb->tail;
+				dma_addr = dma_map_single(lp->dev, newskb->data, PKT_BUF_SZ, DMA_FROM_DEVICE);
+				rbd->v_data = newskb->data;
 				rbd->b_data = WSWAPchar(dma_addr);
 				CHECK_WBACK_INV(rbd, sizeof(struct i596_rbd));
 			}
diff --git a/drivers/net/lne390.c b/drivers/net/lne390.c
--- a/drivers/net/lne390.c
+++ b/drivers/net/lne390.c
@@ -167,12 +167,7 @@ struct net_device * __init lne390_probe(
 	err = do_lne390_probe(dev);
 	if (err)
 		goto out;
-	err = register_netdev(dev);
-	if (err)
-		goto out1;
 	return dev;
-out1:
-	cleanup_card(dev);
 out:
 	free_netdev(dev);
 	return ERR_PTR(err);
@@ -296,7 +291,14 @@ static int __init lne390_probe1(struct n
 	dev->poll_controller = ei_poll;
 #endif
 	NS8390_init(dev, 0);
+
+	ret = register_netdev(dev);
+	if (ret)
+		goto unmap;
 	return 0;
+unmap:
+	if (ei_status.reg0)
+		iounmap((void *)dev->mem_start);
 cleanup:
 	free_irq(dev->irq, dev);
 	return ret;
@@ -426,11 +428,8 @@ int init_module(void)
 		dev->base_addr = io[this_dev];
 		dev->mem_start = mem[this_dev];
 		if (do_lne390_probe(dev) == 0) {
-			if (register_netdev(dev) == 0) {
-				dev_lne[found++] = dev;
-				continue;
-			}
-			cleanup_card(dev);
+			dev_lne[found++] = dev;
+			continue;
 		}
 		free_netdev(dev);
 		printk(KERN_WARNING "lne390.c: No LNE390 card found (i/o = 0x%x).\n", io[this_dev]);
diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c
--- a/drivers/net/loopback.c
+++ b/drivers/net/loopback.c
@@ -214,7 +214,7 @@ struct net_device loopback_dev = {
 	.ethtool_ops		= &loopback_ethtool_ops,
 };
 
-/* Setup and register the of the LOOPBACK device. */
+/* Setup and register the loopback device. */
 int __init loopback_init(void)
 {
 	struct net_device_stats *stats;
diff --git a/drivers/net/mace.c b/drivers/net/mace.c
--- a/drivers/net/mace.c
+++ b/drivers/net/mace.c
@@ -109,7 +109,7 @@ bitrev(int b)
 }
 
 
-static int __devinit mace_probe(struct macio_dev *mdev, const struct of_match *match)
+static int __devinit mace_probe(struct macio_dev *mdev, const struct of_device_id *match)
 {
 	struct device_node *mace = macio_get_of_node(mdev);
 	struct net_device *dev;
@@ -1009,12 +1009,10 @@ static irqreturn_t mace_rxdma_intr(int i
     return IRQ_HANDLED;
 }
 
-static struct of_match mace_match[] = 
+static struct of_device_id mace_match[] = 
 {
 	{
 	.name 		= "mace",
-	.type		= OF_ANY_MATCH,
-	.compatible	= OF_ANY_MATCH
 	},
 	{},
 };
diff --git a/drivers/net/myri_code.h b/drivers/net/myri_code.h
--- a/drivers/net/myri_code.h
+++ b/drivers/net/myri_code.h
@@ -4775,1288 +4775,7 @@ static unsigned char lanai4_code[76256] 
 /* This is the LANai data */ 
 
 static unsigned int lanai4_data_off = 0x94F0; /* half-word offset */
-static unsigned char lanai4_data[20472] __initdata = {
-0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x01, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, 
-0x00,0x00, 0x00,0x00, 0x00,0x00, } ;
+static unsigned char lanai4_data[20472] __initdata;
 
 
 #ifdef SYMBOL_DEFINES_COMPILED
diff --git a/drivers/net/myri_sbus.c b/drivers/net/myri_sbus.c
--- a/drivers/net/myri_sbus.c
+++ b/drivers/net/myri_sbus.c
@@ -369,7 +369,7 @@ static void myri_tx(struct myri_eth *mp,
  * assume 802.3 if the type field is short enough to be a length.
  * This is normal practice and works for any 'now in use' protocol.
  */
-static unsigned short myri_type_trans(struct sk_buff *skb, struct net_device *dev)
+static __be16 myri_type_trans(struct sk_buff *skb, struct net_device *dev)
 {
 	struct ethhdr *eth;
 	unsigned char *rawp;
diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c
--- a/drivers/net/natsemi.c
+++ b/drivers/net/natsemi.c
@@ -1926,7 +1926,7 @@ static void refill_rx(struct net_device 
 				break; /* Better luck next round. */
 			skb->dev = dev; /* Mark as being used by this device. */
 			np->rx_dma[entry] = pci_map_single(np->pci_dev,
-				skb->tail, buflen, PCI_DMA_FROMDEVICE);
+				skb->data, buflen, PCI_DMA_FROMDEVICE);
 			np->rx_ring[entry].addr = cpu_to_le32(np->rx_dma[entry]);
 		}
 		np->rx_ring[entry].cmd_status = cpu_to_le32(np->rx_buf_sz);
@@ -2280,7 +2280,7 @@ static void netdev_rx(struct net_device 
 					buflen,
 					PCI_DMA_FROMDEVICE);
 				eth_copy_and_sum(skb,
-					np->rx_skbuff[entry]->tail, pkt_len, 0);
+					np->rx_skbuff[entry]->data, pkt_len, 0);
 				skb_put(skb, pkt_len);
 				pci_dma_sync_single_for_device(np->pci_dev,
 					np->rx_dma[entry],
diff --git a/drivers/net/ne-h8300.c b/drivers/net/ne-h8300.c
--- a/drivers/net/ne-h8300.c
+++ b/drivers/net/ne-h8300.c
@@ -180,12 +180,7 @@ struct net_device * __init ne_probe(int 
 	err = do_ne_probe(dev);
 	if (err)
 		goto out;
-	err = register_netdev(dev);
-	if (err)
-		goto out1;
 	return dev;
-out1:
-	cleanup_card(dev);
 out:
 	free_netdev(dev);
 	return ERR_PTR(err);
@@ -325,8 +320,13 @@ static int __init ne_probe1(struct net_d
 	dev->poll_controller = ei_poll;
 #endif
 	NS8390_init(dev, 0);
-	return 0;
 
+	ret = register_netdev(dev);
+	if (ret)
+		goto out_irq;
+	return 0;
+out_irq:
+	free_irq(dev->irq, dev);
 err_out:
 	release_region(ioaddr, NE_IO_EXTENT);
 	return ret;
@@ -633,11 +633,8 @@ int init_module(void)
 		err = init_reg_offset(dev, dev->base_addr);
 		if (!err) {
 			if (do_ne_probe(dev) == 0) {
-				if (register_netdev(dev) == 0) {
-					dev_ne[found++] = dev;
-					continue;
-				}
-				cleanup_card(dev);
+				dev_ne[found++] = dev;
+				continue;
 			}
 		}
 		free_netdev(dev);
diff --git a/drivers/net/ne.c b/drivers/net/ne.c
--- a/drivers/net/ne.c
+++ b/drivers/net/ne.c
@@ -129,9 +129,9 @@ bad_clone_list[] __initdata = {
 #define NESM_START_PG	0x40	/* First page of TX buffer */
 #define NESM_STOP_PG	0x80	/* Last page +1 of RX ring */
 
-#ifdef CONFIG_PLAT_MAPPI
+#if defined(CONFIG_PLAT_MAPPI)
 #  define DCR_VAL 0x4b
-#elif CONFIG_PLAT_OAKS32R
+#elif defined(CONFIG_PLAT_OAKS32R)
 #  define DCR_VAL 0x48
 #else
 #  define DCR_VAL 0x49
@@ -229,12 +229,7 @@ struct net_device * __init ne_probe(int 
 	err = do_ne_probe(dev);
 	if (err)
 		goto out;
-	err = register_netdev(dev);
-	if (err)
-		goto out1;
 	return dev;
-out1:
-	cleanup_card(dev);
 out:
 	free_netdev(dev);
 	return ERR_PTR(err);
@@ -534,8 +529,14 @@ static int __init ne_probe1(struct net_d
 	dev->poll_controller = ei_poll;
 #endif
 	NS8390_init(dev, 0);
+
+	ret = register_netdev(dev);
+	if (ret)
+		goto out_irq;
 	return 0;
 
+out_irq:
+	free_irq(dev->irq, dev);
 err_out:
 	release_region(ioaddr, NE_IO_EXTENT);
 	return ret;
@@ -826,11 +827,8 @@ int init_module(void)
 		dev->mem_end = bad[this_dev];
 		dev->base_addr = io[this_dev];
 		if (do_ne_probe(dev) == 0) {
-			if (register_netdev(dev) == 0) {
-				dev_ne[found++] = dev;
-				continue;
-			}
-			cleanup_card(dev);
+			dev_ne[found++] = dev;
+			continue;
 		}
 		free_netdev(dev);
 		if (found)
diff --git a/drivers/net/ne2.c b/drivers/net/ne2.c
--- a/drivers/net/ne2.c
+++ b/drivers/net/ne2.c
@@ -301,12 +301,7 @@ struct net_device * __init ne2_probe(int
 	err = do_ne2_probe(dev);
 	if (err)
 		goto out;
-	err = register_netdev(dev);
-	if (err)
-		goto out1;
 	return dev;
-out1:
-	cleanup_card(dev);
 out:
 	free_netdev(dev);
 	return ERR_PTR(err);
@@ -517,7 +512,14 @@ static int __init ne2_probe1(struct net_
 	dev->poll_controller = ei_poll;
 #endif
 	NS8390_init(dev, 0);
+
+	retval = register_netdev(dev);
+	if (retval)
+		goto out1;
 	return 0;
+out1:
+	mca_set_adapter_procfn( ei_status.priv, NULL, NULL);
+	free_irq(dev->irq, dev);
 out:
 	release_region(base_addr, NE_IO_EXTENT);
 	return retval;
@@ -798,11 +800,8 @@ int init_module(void)
 		dev->mem_end = bad[this_dev];
 		dev->base_addr = io[this_dev];
 		if (do_ne2_probe(dev) == 0) {
-			if (register_netdev(dev) == 0) {
-				dev_ne[found++] = dev;
-				continue;
-			}
-			cleanup_card(dev);
+			dev_ne[found++] = dev;
+			continue;
 		}
 		free_netdev(dev);
 		break;
diff --git a/drivers/net/ne2k-pci.c b/drivers/net/ne2k-pci.c
--- a/drivers/net/ne2k-pci.c
+++ b/drivers/net/ne2k-pci.c
@@ -660,6 +660,7 @@ static int ne2k_pci_suspend (struct pci_
 
 	netif_device_detach(dev);
 	pci_save_state(pdev);
+	pci_disable_device(pdev);
 	pci_set_power_state(pdev, pci_choose_state(pdev, state));
 
 	return 0;
@@ -671,6 +672,8 @@ static int ne2k_pci_resume (struct pci_d
 
 	pci_set_power_state(pdev, 0);
 	pci_restore_state(pdev);
+	pci_enable_device(pdev);
+	pci_set_master(pdev);
 	NS8390_init(dev, 1);
 	netif_device_attach(dev);
 
diff --git a/drivers/net/ns83820.c b/drivers/net/ns83820.c
--- a/drivers/net/ns83820.c
+++ b/drivers/net/ns83820.c
@@ -101,6 +101,7 @@
 #include <linux/moduleparam.h>
 #include <linux/types.h>
 #include <linux/pci.h>
+#include <linux/dma-mapping.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/delay.h>
@@ -573,7 +574,7 @@ static inline int ns83820_add_rx_skb(str
 
 	dev->rx_info.next_empty = (next_empty + 1) % NR_RX_DESC;
 	cmdsts = REAL_RX_BUF_SIZE | CMDSTS_INTR;
-	buf = pci_map_single(dev->pci_dev, skb->tail,
+	buf = pci_map_single(dev->pci_dev, skb->data,
 			     REAL_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
 	build_rx_desc(dev, sg, 0, buf, cmdsts, 0);
 	/* update link of previous rx */
@@ -603,7 +604,7 @@ static inline int rx_refill(struct net_d
 		if (unlikely(!skb))
 			break;
 
-		res = (long)skb->tail & 0xf;
+		res = (long)skb->data & 0xf;
 		res = 0x10 - res;
 		res &= 0xf;
 		skb_reserve(skb, res);
diff --git a/drivers/net/pcmcia/3c574_cs.c b/drivers/net/pcmcia/3c574_cs.c
--- a/drivers/net/pcmcia/3c574_cs.c
+++ b/drivers/net/pcmcia/3c574_cs.c
@@ -86,7 +86,6 @@ earlier 3Com products.
 #include <linux/ethtool.h>
 #include <linux/bitops.h>
 
-#include <pcmcia/version.h>
 #include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
@@ -312,11 +311,6 @@ static dev_link_t *tc574_attach(void)
 	link->next = dev_list;
 	dev_list = link;
 	client_reg.dev_info = &dev_info;
-	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 = &tc574_event;
 	client_reg.Version = 0x0210;
 	client_reg.event_callback_args.client_data = link;
 	ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -1286,13 +1280,22 @@ static int el3_close(struct net_device *
 	return 0;
 }
 
+static struct pcmcia_device_id tc574_ids[] = {
+	PCMCIA_DEVICE_MANF_CARD(0x0101, 0x0574),
+	PCMCIA_MFC_DEVICE_CIS_MANF_CARD(0, 0x0101, 0x0556, "3CCFEM556.cis"),
+	PCMCIA_DEVICE_NULL,
+};
+MODULE_DEVICE_TABLE(pcmcia, tc574_ids);
+
 static struct pcmcia_driver tc574_driver = {
 	.owner		= THIS_MODULE,
 	.drv		= {
 		.name	= "3c574_cs",
 	},
 	.attach		= tc574_attach,
+	.event		= tc574_event,
 	.detach		= tc574_detach,
+	.id_table       = tc574_ids,
 };
 
 static int __init init_tc574(void)
diff --git a/drivers/net/pcmcia/3c589_cs.c b/drivers/net/pcmcia/3c589_cs.c
--- a/drivers/net/pcmcia/3c589_cs.c
+++ b/drivers/net/pcmcia/3c589_cs.c
@@ -40,7 +40,6 @@
 #include <linux/ioport.h>
 #include <linux/bitops.h>
 
-#include <pcmcia/version.h>
 #include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
@@ -226,11 +225,6 @@ static dev_link_t *tc589_attach(void)
     link->next = dev_list;
     dev_list = link;
     client_reg.dev_info = &dev_info;
-    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 = &tc589_event;
     client_reg.Version = 0x0210;
     client_reg.event_callback_args.client_data = link;
     ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -1057,13 +1051,26 @@ static int el3_close(struct net_device *
     return 0;
 }
 
+static struct pcmcia_device_id tc589_ids[] = {
+	PCMCIA_MFC_DEVICE_MANF_CARD(0, 0x0101, 0x0562),
+	PCMCIA_MFC_DEVICE_PROD_ID1(0, "Motorola MARQUIS", 0xf03e4e77),
+	PCMCIA_DEVICE_MANF_CARD(0x0101, 0x0589),
+	PCMCIA_DEVICE_PROD_ID12("Farallon", "ENet", 0x58d93fc4, 0x992c2202),
+	PCMCIA_MFC_DEVICE_CIS_MANF_CARD(0, 0x0101, 0x0035, "3CXEM556.cis"),
+	PCMCIA_MFC_DEVICE_CIS_MANF_CARD(0, 0x0101, 0x003d, "3CXEM556.cis"),
+	PCMCIA_DEVICE_NULL,
+};
+MODULE_DEVICE_TABLE(pcmcia, tc589_ids);
+
 static struct pcmcia_driver tc589_driver = {
 	.owner		= THIS_MODULE,
 	.drv		= {
 		.name	= "3c589_cs",
 	},
 	.attach		= tc589_attach,
+	.event		= tc589_event,
 	.detach		= tc589_detach,
+        .id_table       = tc589_ids,
 };
 
 static int __init init_tc589(void)
diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c
--- a/drivers/net/pcmcia/axnet_cs.c
+++ b/drivers/net/pcmcia/axnet_cs.c
@@ -37,7 +37,6 @@
 #include <linux/netdevice.h>
 #include "../8390.h"
 
-#include <pcmcia/version.h>
 #include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
@@ -181,11 +180,6 @@ static dev_link_t *axnet_attach(void)
     link->next = dev_list;
     dev_list = link;
     client_reg.dev_info = &dev_info;
-    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 = &axnet_event;
     client_reg.Version = 0x0210;
     client_reg.event_callback_args.client_data = link;
     ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -850,13 +844,43 @@ static void block_output(struct net_devi
     outsw(nic_base + AXNET_DATAPORT, buf, count>>1);
 }
 
+static struct pcmcia_device_id axnet_ids[] = {
+	PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x016c, 0x0081),
+	PCMCIA_DEVICE_MANF_CARD(0x018a, 0x0301),
+	PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0301),
+	PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0303),
+	PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0309),
+	PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1106),
+	PCMCIA_DEVICE_MANF_CARD(0x8a01, 0xc1ab),
+	PCMCIA_DEVICE_PROD_ID124("Fast Ethernet", "16-bit PC Card", "AX88190", 0xb4be14e3, 0x9a12eb6a, 0xab9be5ef),
+	PCMCIA_DEVICE_PROD_ID12("ASIX", "AX88190", 0x0959823b, 0xab9be5ef),
+	PCMCIA_DEVICE_PROD_ID12("Billionton", "LNA-100B", 0x552ab682, 0xbc3b87e1),
+	PCMCIA_DEVICE_PROD_ID12("CHEETAH ETHERCARD", "EN2228", 0x00fa7bc8, 0x00e990cc),
+	PCMCIA_DEVICE_PROD_ID12("CNet", "CNF301", 0xbc477dde, 0x78c5f40b),
+	PCMCIA_DEVICE_PROD_ID12("corega K.K.", "corega FEther PCC-TXD", 0x5261440f, 0x436768c5),
+	PCMCIA_DEVICE_PROD_ID12("corega K.K.", "corega FEtherII PCC-TXD", 0x5261440f, 0x730df72e),
+	PCMCIA_DEVICE_PROD_ID12("Dynalink", "L100C16", 0x55632fd5, 0x66bc2a90),
+	PCMCIA_DEVICE_PROD_ID12("Linksys", "EtherFast 10/100 PC Card (PCMPC100 V3)", 0x0733cc81, 0x232019a8),
+	PCMCIA_DEVICE_PROD_ID12("MELCO", "LPC3-TX", 0x481e0094, 0xf91af609),
+	PCMCIA_DEVICE_PROD_ID12("PCMCIA", "100BASE", 0x281f1c5d, 0x7c2add04),
+	PCMCIA_DEVICE_PROD_ID12("PCMCIA", "FastEtherCard", 0x281f1c5d, 0x7ef26116),
+	PCMCIA_DEVICE_PROD_ID12("PCMCIA", "FEP501", 0x281f1c5d, 0x2e272058),
+	PCMCIA_DEVICE_PROD_ID14("Network Everywhere", "AX88190", 0x820a67b6,  0xab9be5ef),
+	/* this is not specific enough */
+	/* PCMCIA_DEVICE_MANF_CARD(0x021b, 0x0202), */
+	PCMCIA_DEVICE_NULL,
+};
+MODULE_DEVICE_TABLE(pcmcia, axnet_ids);
+
 static struct pcmcia_driver axnet_cs_driver = {
 	.owner		= THIS_MODULE,
 	.drv		= {
 		.name	= "axnet_cs",
 	},
 	.attach		= axnet_attach,
+	.event		= axnet_event,
 	.detach		= axnet_detach,
+	.id_table       = axnet_ids,
 };
 
 static int __init init_axnet_cs(void)
diff --git a/drivers/net/pcmcia/com20020_cs.c b/drivers/net/pcmcia/com20020_cs.c
--- a/drivers/net/pcmcia/com20020_cs.c
+++ b/drivers/net/pcmcia/com20020_cs.c
@@ -43,7 +43,6 @@
 #include <linux/arcdevice.h>
 #include <linux/com20020.h>
 
-#include <pcmcia/version.h>
 #include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
@@ -200,11 +199,6 @@ static dev_link_t *com20020_attach(void)
     link->next = dev_list;
     dev_list = link;
     client_reg.dev_info = &dev_info;
-    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 = &com20020_event;
     client_reg.Version = 0x0210;
     client_reg.event_callback_args.client_data = link;
     ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -483,7 +477,11 @@ static int com20020_event(event_t event,
     return 0;
 } /* com20020_event */
 
-
+static struct pcmcia_device_id com20020_ids[] = {
+	PCMCIA_DEVICE_PROD_ID12("Contemporary Control Systems, Inc.", "PCM20 Arcnet Adapter", 0x59991666, 0x95dfffaf),
+	PCMCIA_DEVICE_NULL
+};
+MODULE_DEVICE_TABLE(pcmcia, com20020_ids);
 
 static struct pcmcia_driver com20020_cs_driver = {
 	.owner		= THIS_MODULE,
@@ -491,7 +489,9 @@ static struct pcmcia_driver com20020_cs_
 		.name	= "com20020_cs",
 	},
 	.attach		= com20020_attach,
+	.event		= com20020_event,
 	.detach		= com20020_detach,
+	.id_table	= com20020_ids,
 };
 
 static int __init init_com20020_cs(void)
diff --git a/drivers/net/pcmcia/fmvj18x_cs.c b/drivers/net/pcmcia/fmvj18x_cs.c
--- a/drivers/net/pcmcia/fmvj18x_cs.c
+++ b/drivers/net/pcmcia/fmvj18x_cs.c
@@ -49,7 +49,6 @@
 #include <linux/ioport.h>
 #include <linux/crc32.h>
 
-#include <pcmcia/version.h>
 #include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
@@ -288,11 +287,6 @@ static dev_link_t *fmvj18x_attach(void)
     link->next = dev_list;
     dev_list = link;
     client_reg.dev_info = &dev_info;
-    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 = &fmvj18x_event;
     client_reg.Version = 0x0210;
     client_reg.event_callback_args.client_data = link;
     ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -435,7 +429,9 @@ static void fmvj18x_config(dev_link_t *l
 		pcmcia_get_status(handle, &status);
 		if (status.CardState & CS_EVENT_3VCARD)
 		    link->conf.Vcc = 33; /* inserted in 3.3V slot */
-	    } else if (le16_to_cpu(buf[1]) == PRODID_TDK_GN3410) {
+	    } else if (le16_to_cpu(buf[1]) == PRODID_TDK_GN3410
+			|| le16_to_cpu(buf[1]) == PRODID_TDK_NP9610
+			|| le16_to_cpu(buf[1]) == PRODID_TDK_MN3200) {
 		/* MultiFunction Card */
 		link->conf.ConfigBase = 0x800;
 		link->conf.ConfigIndex = 0x47;
@@ -764,13 +760,40 @@ static int fmvj18x_event(event_t event, 
     return 0;
 } /* fmvj18x_event */
 
+static struct pcmcia_device_id fmvj18x_ids[] = {
+	PCMCIA_DEVICE_MANF_CARD(0x0004, 0x0004),
+	PCMCIA_DEVICE_PROD_ID12("EAGLE Technology", "NE200 ETHERNET LAN MBH10302 04", 0x528c88c4, 0x74f91e59),
+	PCMCIA_DEVICE_PROD_ID12("Eiger Labs,Inc", "EPX-10BT PC Card Ethernet 10BT", 0x53af556e, 0x877f9922),
+	PCMCIA_DEVICE_PROD_ID12("Eiger labs,Inc.", "EPX-10BT PC Card Ethernet 10BT", 0xf47e6c66, 0x877f9922),
+	PCMCIA_DEVICE_PROD_ID12("FUJITSU", "LAN Card(FMV-J182)", 0x6ee5a3d8, 0x5baf31db),
+	PCMCIA_DEVICE_PROD_ID12("FUJITSU", "MBH10308", 0x6ee5a3d8, 0x3f04875e),
+	PCMCIA_DEVICE_PROD_ID12("FUJITSU TOWA", "LA501", 0xb8451188, 0x12939ba2),
+	PCMCIA_DEVICE_PROD_ID12("HITACHI", "HT-4840-11", 0xf4f43949, 0x773910f4),
+	PCMCIA_DEVICE_PROD_ID12("NextComK.K.", "NC5310B Ver1.0       ", 0x8cef4d3a, 0x075fc7b6),
+	PCMCIA_DEVICE_PROD_ID12("NextComK.K.", "NC5310 Ver1.0        ", 0x8cef4d3a, 0xbccf43e6),
+	PCMCIA_DEVICE_PROD_ID12("RATOC System Inc.", "10BASE_T CARD R280", 0x85c10e17, 0xd9413666),
+	PCMCIA_DEVICE_PROD_ID12("TDK", "LAC-CD02x", 0x1eae9475, 0x8fa0ee70),
+	PCMCIA_DEVICE_PROD_ID12("TDK", "LAC-CF010", 0x1eae9475, 0x7683bc9a),
+	PCMCIA_DEVICE_PROD_ID1("CONTEC Co.,Ltd.", 0x58d8fee2),
+	PCMCIA_DEVICE_PROD_ID1("PCMCIA LAN MBH10304  ES", 0x2599f454),
+	PCMCIA_DEVICE_PROD_ID1("PCMCIA MBH10302", 0x8f4005da),
+	PCMCIA_DEVICE_PROD_ID1("UBKK,V2.0", 0x90888080),
+	PCMCIA_PFC_DEVICE_PROD_ID12(0, "TDK", "GlobalNetworker 3410/3412", 0x1eae9475, 0xd9a93bed),
+	PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0105, 0x0d0a),
+	PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0105, 0x0e0a),
+	PCMCIA_DEVICE_NULL,
+};
+MODULE_DEVICE_TABLE(pcmcia, fmvj18x_ids);
+
 static struct pcmcia_driver fmvj18x_cs_driver = {
 	.owner		= THIS_MODULE,
 	.drv		= {
 		.name	= "fmvj18x_cs",
 	},
 	.attach		= fmvj18x_attach,
+	.event		= fmvj18x_event,
 	.detach		= fmvj18x_detach,
+	.id_table       = fmvj18x_ids,
 };
 
 static int __init init_fmvj18x_cs(void)
diff --git a/drivers/net/pcmcia/ibmtr_cs.c b/drivers/net/pcmcia/ibmtr_cs.c
--- a/drivers/net/pcmcia/ibmtr_cs.c
+++ b/drivers/net/pcmcia/ibmtr_cs.c
@@ -57,7 +57,6 @@
 #include <linux/trdevice.h>
 #include <linux/ibmtr.h>
 
-#include <pcmcia/version.h>
 #include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
@@ -119,9 +118,6 @@ static void ibmtr_detach(dev_link_t *);
 
 static dev_link_t *dev_list;
 
-extern int ibmtr_probe_card(struct net_device *dev);
-extern irqreturn_t tok_interrupt (int irq, void *dev_id, struct pt_regs *regs);
-
 /*====================================================================*/
 
 typedef struct ibmtr_dev_t {
@@ -193,11 +189,6 @@ static dev_link_t *ibmtr_attach(void)
     link->next = dev_list;
     dev_list = link;
     client_reg.dev_info = &dev_info;
-    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 = &ibmtr_event;
     client_reg.Version = 0x0210;
     client_reg.event_callback_args.client_data = link;
     ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -511,13 +502,22 @@ static void ibmtr_hw_setup(struct net_de
     return;
 }
 
+static struct pcmcia_device_id ibmtr_ids[] = {
+	PCMCIA_DEVICE_PROD_ID12("3Com", "TokenLink Velocity PC Card", 0x41240e5b, 0x82c3734e),
+	PCMCIA_DEVICE_PROD_ID12("IBM", "TOKEN RING", 0xb569a6e5, 0xbf8eed47),
+	PCMCIA_DEVICE_NULL,
+};
+MODULE_DEVICE_TABLE(pcmcia, ibmtr_ids);
+
 static struct pcmcia_driver ibmtr_cs_driver = {
 	.owner		= THIS_MODULE,
 	.drv		= {
 		.name	= "ibmtr_cs",
 	},
 	.attach		= ibmtr_attach,
+	.event		= ibmtr_event,
 	.detach		= ibmtr_detach,
+	.id_table       = ibmtr_ids,
 };
 
 static int __init init_ibmtr_cs(void)
diff --git a/drivers/net/pcmcia/nmclan_cs.c b/drivers/net/pcmcia/nmclan_cs.c
--- a/drivers/net/pcmcia/nmclan_cs.c
+++ b/drivers/net/pcmcia/nmclan_cs.c
@@ -146,7 +146,6 @@ Include Files
 #include <linux/ioport.h>
 #include <linux/bitops.h>
 
-#include <pcmcia/version.h>
 #include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cisreg.h>
@@ -502,11 +501,6 @@ static dev_link_t *nmclan_attach(void)
     link->next = dev_list;
     dev_list = link;
     client_reg.dev_info = &dev_info;
-    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 = &nmclan_event;
     client_reg.Version = 0x0210;
     client_reg.event_callback_args.client_data = link;
     ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -1675,13 +1669,22 @@ static void set_multicast_list(struct ne
 
 } /* set_multicast_list */
 
+static struct pcmcia_device_id nmclan_ids[] = {
+	PCMCIA_DEVICE_PROD_ID12("New Media Corporation", "Ethernet", 0x085a850b, 0x00b2e941),
+	PCMCIA_DEVICE_PROD_ID12("Portable Add-ons", "Ethernet+", 0xebf1d60, 0xad673aaf),
+	PCMCIA_DEVICE_NULL,
+};
+MODULE_DEVICE_TABLE(pcmcia, nmclan_ids);
+
 static struct pcmcia_driver nmclan_cs_driver = {
 	.owner		= THIS_MODULE,
 	.drv		= {
 		.name	= "nmclan_cs",
 	},
 	.attach		= nmclan_attach,
+	.event		= nmclan_event,
 	.detach		= nmclan_detach,
+	.id_table       = nmclan_ids,
 };
 
 static int __init init_nmclan_cs(void)
diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c
--- a/drivers/net/pcmcia/pcnet_cs.c
+++ b/drivers/net/pcmcia/pcnet_cs.c
@@ -40,7 +40,6 @@
 #include <linux/netdevice.h>
 #include <../drivers/net/8390.h>
 
-#include <pcmcia/version.h>
 #include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
@@ -276,11 +275,6 @@ static dev_link_t *pcnet_attach(void)
     link->next = dev_list;
     dev_list = link;
     client_reg.dev_info = &dev_info;
-    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 = &pcnet_event;
     client_reg.Version = 0x0210;
     client_reg.event_callback_args.client_data = link;
     ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -1155,11 +1149,13 @@ static int set_config(struct net_device 
 static irqreturn_t ei_irq_wrapper(int irq, void *dev_id, struct pt_regs *regs)
 {
     struct net_device *dev = dev_id;
-    pcnet_dev_t *info = PRIV(dev);
+    pcnet_dev_t *info;
     irqreturn_t ret = ei_interrupt(irq, dev_id, regs);
 
-    if (ret == IRQ_HANDLED)
+    if (ret == IRQ_HANDLED) {
+	    info = PRIV(dev);
 	    info->stale = 0;
+    }
     return ret;
 }
 
@@ -1350,7 +1346,7 @@ static void dma_block_input(struct net_d
     if (count & 0x01)
 	buf[count-1] = inb(nic_base + PCNET_DATAPORT), xfer_count++;
 
-    /* This was for the ALPHA version only, but enough people have
+    /* This was for the ALPHA version only, but enough people have been
        encountering problems that it is still here. */
 #ifdef PCMCIA_DEBUG
     if (ei_debug > 4) {		/* DMA termination address check... */
@@ -1424,7 +1420,7 @@ static void dma_block_output(struct net_
     dma_start = jiffies;
 
 #ifdef PCMCIA_DEBUG
-    /* This was for the ALPHA version only, but enough people have
+    /* This was for the ALPHA version only, but enough people have been
        encountering problems that it is still here. */
     if (ei_debug > 4) {	/* DMA termination address check... */
 	int addr, tries = 20;
@@ -1537,20 +1533,20 @@ static void shmem_get_8390_hdr(struct ne
 static void shmem_block_input(struct net_device *dev, int count,
 			      struct sk_buff *skb, int ring_offset)
 {
-    void __iomem *xfer_start = ei_status.mem + (TX_PAGES<<8)
-				+ ring_offset
+    void __iomem *base = ei_status.mem;
+    unsigned long offset = (TX_PAGES<<8) + ring_offset
 				- (ei_status.rx_start_page << 8);
     char *buf = skb->data;
     
-    if (xfer_start + count > (void __iomem *)ei_status.rmem_end) {
+    if (offset + count > ei_status.priv) {
 	/* We must wrap the input move. */
-	int semi_count = (void __iomem *)ei_status.rmem_end - xfer_start;
-	copyin(buf, xfer_start, semi_count);
+	int semi_count = ei_status.priv - offset;
+	copyin(buf, base + offset, semi_count);
 	buf += semi_count;
-	xfer_start = ei_status.mem + (TX_PAGES<<8);
+	offset = TX_PAGES<<8;
 	count -= semi_count;
     }
-    copyin(buf, xfer_start, count);
+    copyin(buf, base + offset, count);
 }
 
 /*====================================================================*/
@@ -1611,8 +1607,9 @@ static int setup_shmem_window(dev_link_t
     }
     
     ei_status.mem = info->base + offset;
+    ei_status.priv = req.Size;
     dev->mem_start = (u_long)ei_status.mem;
-    dev->mem_end = ei_status.rmem_end = (u_long)info->base + req.Size;
+    dev->mem_end = dev->mem_start + req.Size;
 
     ei_status.tx_start_page = start_pg;
     ei_status.rx_start_page = start_pg + TX_PAGES;
@@ -1634,13 +1631,218 @@ failed:
 
 /*====================================================================*/
 
+static struct pcmcia_device_id pcnet_ids[] = {
+	PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0057, 0x0021),
+	PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0104, 0x000a),
+	PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0105, 0xea15),
+	PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0143, 0x3341),
+	PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0143, 0xc0ab),
+	PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x021b, 0x0101),
+	PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x08a1, 0xc0ab),
+	PCMCIA_PFC_DEVICE_PROD_ID12(0, "AnyCom", "Fast Ethernet + 56K COMBO", 0x578ba6e7, 0xb0ac62c4),
+	PCMCIA_PFC_DEVICE_PROD_ID12(0, "D-Link", "DME336T", 0x1a424a1c, 0xb23897ff),
+	PCMCIA_PFC_DEVICE_PROD_ID12(0, "Grey Cell", "GCS3000", 0x2a151fac, 0x48b932ae),
+	PCMCIA_PFC_DEVICE_PROD_ID12(0, "Linksys", "EtherFast 10&100 + 56K PC Card (PCMLM56)", 0x0733cc81, 0xb3765033),
+	PCMCIA_PFC_DEVICE_PROD_ID12(0, "LINKSYS", "PCMLM336", 0xf7cb0b07, 0x7a821b58),
+	PCMCIA_PFC_DEVICE_PROD_ID12(0, "PCMCIAs", "ComboCard", 0xdcfe12d3, 0xcd8906cc),
+	PCMCIA_PFC_DEVICE_PROD_ID12(0, "PCMCIAs", "LanModem", 0xdcfe12d3, 0xc67c648f),
+	PCMCIA_MFC_DEVICE_PROD_ID12(0, "IBM", "Home and Away 28.8 PC Card       ", 0xb569a6e5, 0x5bd4ff2c),
+	PCMCIA_MFC_DEVICE_PROD_ID12(0, "IBM", "Home and Away Credit Card Adapter", 0xb569a6e5, 0x4bdf15c3),
+	PCMCIA_MFC_DEVICE_PROD_ID12(0, "IBM", "w95 Home and Away Credit Card ", 0xb569a6e5, 0xae911c15),
+	PCMCIA_MFC_DEVICE_PROD_ID123(0, "APEX DATA", "MULTICARD", "ETHERNET-MODEM", 0x11c2da09, 0x7289dc5d, 0xaad95e1f),
+	PCMCIA_MFC_DEVICE_PROD_ID2(0, "FAX/Modem/Ethernet Combo Card ", 0x1ed59302),
+	PCMCIA_DEVICE_MANF_CARD(0x0057, 0x1004),
+	PCMCIA_DEVICE_MANF_CARD(0x0104, 0x000d),
+	PCMCIA_DEVICE_MANF_CARD(0x0104, 0x0075),
+	PCMCIA_DEVICE_MANF_CARD(0x0104, 0x0145),
+	PCMCIA_DEVICE_MANF_CARD(0x0149, 0x0230),
+	PCMCIA_DEVICE_MANF_CARD(0x0149, 0x4530),
+/*	PCMCIA_DEVICE_MANF_CARD(0x0149, 0xc1ab), conflict with axnet_cs */
+	PCMCIA_DEVICE_MANF_CARD(0x0186, 0x0110),
+	PCMCIA_DEVICE_MANF_CARD(0x01bf, 0x2328),
+	PCMCIA_DEVICE_MANF_CARD(0x01bf, 0x8041),
+	PCMCIA_DEVICE_MANF_CARD(0x0213, 0x2452),
+/*	PCMCIA_DEVICE_MANF_CARD(0x021b, 0x0202), conflict with axnet_cs */
+	PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0300),
+	PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0307),
+	PCMCIA_DEVICE_MANF_CARD(0x026f, 0x030a),
+	PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1103),
+	PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1121),
+	PCMCIA_DEVICE_PROD_ID12("2408LAN", "Ethernet", 0x352fff7f, 0x00b2e941),
+	PCMCIA_DEVICE_PROD_ID123("Cardwell", "PCMCIA", "ETHERNET", 0x9533672e, 0x281f1c5d, 0x3ff7175b),
+	PCMCIA_DEVICE_PROD_ID123("CNet  ", "CN30BC", "ETHERNET", 0x9fe55d3d, 0x85601198, 0x3ff7175b),
+	PCMCIA_DEVICE_PROD_ID123("Digital", "Ethernet", "Adapter", 0x9999ab35, 0x00b2e941, 0x4b0d829e),
+	PCMCIA_DEVICE_PROD_ID123("Edimax Technology Inc.", "PCMCIA", "Ethernet Card", 0x738a0019, 0x281f1c5d, 0x5e9d92c0),
+	PCMCIA_DEVICE_PROD_ID123("EFA   ", "EFA207", "ETHERNET", 0x3d294be4, 0xeb9aab6c, 0x3ff7175b),
+	PCMCIA_DEVICE_PROD_ID123("I-O DATA", "PCLA", "ETHERNET", 0x1d55d7ec, 0xe4c64d34, 0x3ff7175b),
+	PCMCIA_DEVICE_PROD_ID123("IO DATA", "PCLATE", "ETHERNET", 0x547e66dc, 0x6b260753, 0x3ff7175b),
+	PCMCIA_DEVICE_PROD_ID123("KingMax Technology Inc.", "EN10-T2", "PCMCIA Ethernet Card", 0x932b7189, 0x699e4436, 0x6f6652e0),
+	PCMCIA_DEVICE_PROD_ID123("PCMCIA", "PCMCIA-ETHERNET-CARD", "UE2216", 0x281f1c5d, 0xd4cd2f20, 0xb87add82),
+	PCMCIA_DEVICE_PROD_ID123("PCMCIA", "PCMCIA-ETHERNET-CARD", "UE2620", 0x281f1c5d, 0xd4cd2f20, 0x7d3d83a8),
+	PCMCIA_DEVICE_PROD_ID1("2412LAN", 0x67f236ab),
+	PCMCIA_DEVICE_PROD_ID12("ACCTON", "EN2212", 0xdfc6b5b2, 0xcb112a11),
+	PCMCIA_DEVICE_PROD_ID12("ACCTON", "EN2216-PCMCIA-ETHERNET", 0xdfc6b5b2, 0x5542bfff),
+	PCMCIA_DEVICE_PROD_ID12("Allied Telesis, K.K.", "CentreCOM LA100-PCM-T V2 100/10M LAN PC Card", 0xbb7fbdd7, 0xcd91cc68),
+	PCMCIA_DEVICE_PROD_ID12("Allied Telesis K.K.", "LA100-PCM V2", 0x36634a66, 0xc6d05997),
+  	PCMCIA_DEVICE_PROD_ID12("Allied Telesis, K.K.", "CentreCOM LA-PCM_V2", 0xbb7fBdd7, 0x28e299f8),
+	PCMCIA_DEVICE_PROD_ID12("Allied Telesis K.K.", "LA-PCM V3", 0x36634a66, 0x62241d96),
+	PCMCIA_DEVICE_PROD_ID12("AmbiCom", "AMB8010", 0x5070a7f9, 0x82f96e96),
+	PCMCIA_DEVICE_PROD_ID12("AmbiCom", "AMB8610", 0x5070a7f9, 0x86741224),
+	PCMCIA_DEVICE_PROD_ID12("AmbiCom Inc", "AMB8002", 0x93b15570, 0x75ec3efb),
+	PCMCIA_DEVICE_PROD_ID12("AmbiCom Inc", "AMB8002T", 0x93b15570, 0x461c5247),
+	PCMCIA_DEVICE_PROD_ID12("AmbiCom Inc", "AMB8010", 0x93b15570, 0x82f96e96),
+	PCMCIA_DEVICE_PROD_ID12("AnyCom", "ECO Ethernet", 0x578ba6e7, 0x0a9888c1),
+	PCMCIA_DEVICE_PROD_ID12("AnyCom", "ECO Ethernet 10/100", 0x578ba6e7, 0x939fedbd),
+	PCMCIA_DEVICE_PROD_ID12("AROWANA", "PCMCIA Ethernet LAN Card", 0x313adbc8, 0x08d9f190),
+	PCMCIA_DEVICE_PROD_ID12("ASANTE", "FriendlyNet PC Card", 0x3a7ade0f, 0x41c64504),
+	PCMCIA_DEVICE_PROD_ID12("Billionton", "LNT-10TB", 0x552ab682, 0xeeb1ba6a),
+	PCMCIA_DEVICE_PROD_ID12("CF", "10Base-Ethernet", 0x44ebf863, 0x93ae4d79),
+	PCMCIA_DEVICE_PROD_ID12("CNet", "CN40BC Ethernet", 0xbc477dde, 0xfba775a7),
+	PCMCIA_DEVICE_PROD_ID12("COMPU-SHACK", "BASEline PCMCIA 10 MBit Ethernetadapter", 0xfa2e424d, 0xe9190d8a),
+	PCMCIA_DEVICE_PROD_ID12("COMPU-SHACK", "FASTline PCMCIA 10/100 Fast-Ethernet", 0xfa2e424d, 0x3953d9b9),
+	PCMCIA_DEVICE_PROD_ID12("CONTEC", "C-NET(PC)C-10L", 0x21cab552, 0xf6f90722),
+	PCMCIA_DEVICE_PROD_ID12("corega", "FEther PCC-TXF", 0x0a21501a, 0xa51564a2),
+	PCMCIA_DEVICE_PROD_ID12("corega K.K.", "corega EtherII PCC-T", 0x5261440f, 0xfa9d85bd),
+	PCMCIA_DEVICE_PROD_ID12("Corega K.K.", "corega EtherII PCC-TD", 0xd4fdcbd8, 0xc49bd73d),
+	PCMCIA_DEVICE_PROD_ID12("corega K.K.", "corega Ether PCC-T", 0x5261440f, 0x6705fcaa),
+	PCMCIA_DEVICE_PROD_ID12("corega K.K.", "corega FastEther PCC-TX", 0x5261440f, 0x485e85d9),
+	PCMCIA_DEVICE_PROD_ID12("Corega,K.K.", "Ethernet LAN Card", 0x110d26d9, 0x9fd2f0a2),
+	PCMCIA_DEVICE_PROD_ID12("corega,K.K.", "Ethernet LAN Card", 0x9791a90e, 0x9fd2f0a2),
+	PCMCIA_DEVICE_PROD_ID12("CouplerlessPCMCIA", "100BASE", 0xee5af0ad, 0x7c2add04),
+	PCMCIA_DEVICE_PROD_ID12("CyQ've", "ELA-010", 0x77008979, 0x9d8d445d),
+	PCMCIA_DEVICE_PROD_ID12("CyQ've", "ELA-110E 10/100M LAN Card", 0x77008979, 0xfd184814),
+	PCMCIA_DEVICE_PROD_ID12("DataTrek.", "NetCard ", 0x5cd66d9d, 0x84697ce0),
+	PCMCIA_DEVICE_PROD_ID12("Dayna Communications, Inc.", "CommuniCard E", 0x0c629325, 0xb4e7dbaf),
+	PCMCIA_DEVICE_PROD_ID12("Digicom", "Palladio LAN 10/100", 0x697403d8, 0xe160b995),
+	PCMCIA_DEVICE_PROD_ID12("Digicom", "Palladio LAN 10/100 Dongless", 0x697403d8, 0xa6d3b233),
+	PCMCIA_DEVICE_PROD_ID12("DIGITAL", "DEPCM-XX", 0x69616cb3, 0xe600e76e),
+	PCMCIA_DEVICE_PROD_ID12("D-Link", "DE-650", 0x1a424a1c, 0xf28c8398),
+	PCMCIA_DEVICE_PROD_ID12("D-Link", "DE-660", 0x1a424a1c, 0xd9a1d05b),
+	PCMCIA_DEVICE_PROD_ID12("D-Link", "DE-660+", 0x1a424a1c, 0x50dcd0ec),
+	PCMCIA_DEVICE_PROD_ID12("D-Link", "DFE-650", 0x1a424a1c, 0x0f0073f9),
+	PCMCIA_DEVICE_PROD_ID12("Dual Speed", "10/100 PC Card", 0x725b842d, 0xf1efee84),
+	PCMCIA_DEVICE_PROD_ID12("Dual Speed", "10/100 Port Attached PC Card", 0x725b842d, 0x2db1f8e9),
+	PCMCIA_DEVICE_PROD_ID12("Dynalink", "L10BC", 0x55632fd5, 0xdc65f2b1),
+	PCMCIA_DEVICE_PROD_ID12("DYNALINK", "L10BC", 0x6a26d1cf, 0xdc65f2b1),
+	PCMCIA_DEVICE_PROD_ID12("DYNALINK", "L10C", 0x6a26d1cf, 0xc4f84efb),
+	PCMCIA_DEVICE_PROD_ID12("E-CARD", "E-CARD", 0x6701da11, 0x6701da11),
+	PCMCIA_DEVICE_PROD_ID12("EIGER Labs Inc.", "Ethernet 10BaseT card", 0x53c864c6, 0xedd059f6),
+	PCMCIA_DEVICE_PROD_ID12("EIGER Labs Inc.", "Ethernet Combo card", 0x53c864c6, 0x929c486c),
+	PCMCIA_DEVICE_PROD_ID12("Ethernet", "Adapter", 0x00b2e941, 0x4b0d829e),
+	PCMCIA_DEVICE_PROD_ID12("Ethernet Adapter", "E2000 PCMCIA Ethernet", 0x96767301, 0x71fbbc61),
+	PCMCIA_DEVICE_PROD_ID12("Ethernet PCMCIA adapter", "EP-210", 0x8dd86181, 0xf2b52517),
+	PCMCIA_DEVICE_PROD_ID12("Fast Ethernet", "Adapter", 0xb4be14e3, 0x4b0d829e),
+	PCMCIA_DEVICE_PROD_ID12("Grey Cell", "GCS2000", 0x2a151fac, 0xf00555cb),
+	PCMCIA_DEVICE_PROD_ID12("Grey Cell", "GCS2220", 0x2a151fac, 0xc1b7e327),
+	PCMCIA_DEVICE_PROD_ID12("GVC", "NIC-2000p", 0x76e171bd, 0x6eb1c947),
+	PCMCIA_DEVICE_PROD_ID12("IBM Corp.", "Ethernet", 0xe3736c88, 0x00b2e941),
+	PCMCIA_DEVICE_PROD_ID12("IC-CARD", "IC-CARD", 0x60cb09a6, 0x60cb09a6),
+	PCMCIA_DEVICE_PROD_ID12("IC-CARD+", "IC-CARD+", 0x93693494, 0x93693494),
+	PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCETTX", 0x547e66dc, 0x6fc5459b),
+	PCMCIA_DEVICE_PROD_ID12("iPort", "10/100 Ethernet Card", 0x56c538d2, 0x11b0ffc0),
+	PCMCIA_DEVICE_PROD_ID12("KANSAI ELECTRIC CO.,LTD", "KLA-PCM/T", 0xb18dc3b4, 0xcc51a956),
+	PCMCIA_DEVICE_PROD_ID12("KCI", "PE520 PCMCIA Ethernet Adapter", 0xa89b87d3, 0x1eb88e64),
+	PCMCIA_DEVICE_PROD_ID12("KINGMAX", "EN10T2T", 0x7bcb459a, 0xa5c81fa5),
+	PCMCIA_DEVICE_PROD_ID12("Kingston", "KNE-PC2", 0x1128e633, 0xce2a89b3),
+	PCMCIA_DEVICE_PROD_ID12("Kingston Technology Corp.", "EtheRx PC Card Ethernet Adapter", 0x313c7be3, 0x0afb54a2),
+	PCMCIA_DEVICE_PROD_ID12("Laneed", "LD-10/100CD", 0x1b7827b2, 0xcda71d1c),
+	PCMCIA_DEVICE_PROD_ID12("Laneed", "LD-CDF", 0x1b7827b2, 0xfec71e40),
+	PCMCIA_DEVICE_PROD_ID12("Laneed", "LD-CDL/T", 0x1b7827b2, 0x79fba4f7),
+	PCMCIA_DEVICE_PROD_ID12("Laneed", "LD-CDS", 0x1b7827b2, 0x931afaab),
+	PCMCIA_DEVICE_PROD_ID12("Linksys", "Combo PCMCIA EthernetCard (EC2T)", 0x0733cc81, 0x32ee8c78),
+	PCMCIA_DEVICE_PROD_ID12("LINKSYS", "E-CARD", 0xf7cb0b07, 0x6701da11),
+	PCMCIA_DEVICE_PROD_ID12("Linksys", "EtherFast 10/100 Integrated PC Card (PCM100)", 0x0733cc81, 0x453c3f9d),
+	PCMCIA_DEVICE_PROD_ID12("Linksys", "EtherFast 10/100 PC Card (PCMPC100)", 0x0733cc81, 0x66c5a389),
+	PCMCIA_DEVICE_PROD_ID12("Linksys", "EtherFast 10/100 PC Card (PCMPC100 V2)", 0x0733cc81, 0x3a3b28e9),
+	PCMCIA_DEVICE_PROD_ID12("Linksys", "HomeLink Phoneline + 10/100 Network PC Card (PCM100H1)", 0x733cc81, 0x7a3e5c3a),
+	PCMCIA_DEVICE_PROD_ID12("Logitec", "LPM-LN100TX", 0x88fcdeda, 0x6d772737),
+	PCMCIA_DEVICE_PROD_ID12("Logitec", "LPM-LN20T", 0x88fcdeda, 0x81090922),
+	PCMCIA_DEVICE_PROD_ID12("LONGSHINE", "PCMCIA Ethernet Card", 0xf866b0b0, 0x6f6652e0),
+	PCMCIA_DEVICE_PROD_ID12("MACNICA", "ME1-JEIDA", 0x20841b68, 0xaf8a3578),
+	PCMCIA_DEVICE_PROD_ID12("Macsense", "MPC-10", 0xd830297f, 0xd265c307),
+	PCMCIA_DEVICE_PROD_ID12("Matsushita Electric Industrial Co.,LTD.", "CF-VEL211", 0x44445376, 0x8ded41d4),
+	PCMCIA_DEVICE_PROD_ID12("MAXTECH", "PCN2000", 0x78d64bc0, 0xca0ca4b8),
+	PCMCIA_DEVICE_PROD_ID12("MELCO", "LPC2-T", 0x481e0094, 0xa2eb0cf3),
+	PCMCIA_DEVICE_PROD_ID12("MELCO", "LPC2-TX", 0x481e0094, 0x41a6916c),
+	PCMCIA_DEVICE_PROD_ID12("Microcom C.E.", "Travel Card LAN 10/100", 0x4b91cec7, 0xe70220d6),
+	PCMCIA_DEVICE_PROD_ID12("Microdyne", "NE4200", 0x2e6da59b, 0x0478e472),
+	PCMCIA_DEVICE_PROD_ID12("MIDORI ELEC.", "LT-PCMT", 0x648d55c1, 0xbde526c7),
+	PCMCIA_DEVICE_PROD_ID12("National Semiconductor", "InfoMover 4100", 0x36e1191f, 0x60c229b9),
+	PCMCIA_DEVICE_PROD_ID12("National Semiconductor", "InfoMover NE4100", 0x36e1191f, 0xa6617ec8),
+	PCMCIA_DEVICE_PROD_ID12("NEC", "PC-9801N-J12", 0x18df0ba0, 0xbc912d76),
+	PCMCIA_DEVICE_PROD_ID12("NETGEAR", "FA410TX", 0x9aa79dc3, 0x60e5bc0e),
+	PCMCIA_DEVICE_PROD_ID12("NETGEAR", "FA411", 0x9aa79dc3, 0x40fad875),
+	PCMCIA_DEVICE_PROD_ID12("Network Everywhere", "Fast Ethernet 10/100 PC Card", 0x820a67b6, 0x31ed1a5f),
+	PCMCIA_DEVICE_PROD_ID12("NextCom K.K.", "Next Hawk", 0xaedaec74, 0xad050ef1),
+	PCMCIA_DEVICE_PROD_ID12("PCMCIA", "10/100Mbps Ethernet Card", 0x281f1c5d, 0x6e41773b),
+	PCMCIA_DEVICE_PROD_ID12("PCMCIA", "Ethernet", 0x281f1c5d, 0x00b2e941),
+	PCMCIA_DEVICE_PROD_ID12("PCMCIA", "ETHERNET", 0x281f1c5d, 0x3ff7175b),
+	PCMCIA_DEVICE_PROD_ID12("PCMCIA", "Ethernet 10BaseT Card", 0x281f1c5d, 0x4de2f6c8),
+	PCMCIA_DEVICE_PROD_ID12("PCMCIA", "Ethernet Card", 0x281f1c5d, 0x5e9d92c0),
+	PCMCIA_DEVICE_PROD_ID12("PCMCIA", "Ethernet Combo card", 0x281f1c5d, 0x929c486c),
+	PCMCIA_DEVICE_PROD_ID12("PCMCIA", "ETHERNET V1.0", 0x281f1c5d, 0x4d8817c8),
+	PCMCIA_DEVICE_PROD_ID12("PCMCIA", "FastEthernet", 0x281f1c5d, 0xfe871eeb),
+	PCMCIA_DEVICE_PROD_ID12("PCMCIA", "Fast-Ethernet", 0x281f1c5d, 0x45f1f3b4),
+	PCMCIA_DEVICE_PROD_ID12("PCMCIA", "FAST ETHERNET CARD", 0x281f1c5d, 0xec5dbca7),
+	PCMCIA_DEVICE_PROD_ID12("PCMCIA LAN", "Ethernet", 0x7500e246, 0x00b2e941),
+	PCMCIA_DEVICE_PROD_ID12("PCMCIA", "LNT-10TN", 0x281f1c5d, 0xe707f641),
+	PCMCIA_DEVICE_PROD_ID12("PCMCIAs", "ComboCard", 0xdcfe12d3, 0xcd8906cc),
+	PCMCIA_DEVICE_PROD_ID12("PCMCIA", "UE2212", 0x281f1c5d, 0xbf17199b),
+	PCMCIA_DEVICE_PROD_ID12("PCMCIA", "    Ethernet NE2000 Compatible", 0x281f1c5d, 0x42d5d7e1),
+	PCMCIA_DEVICE_PROD_ID12("PRETEC", "Ethernet CompactLAN 10baseT 3.3V", 0xebf91155, 0x30074c80),
+	PCMCIA_DEVICE_PROD_ID12("PRETEC", "Ethernet CompactLAN 10BaseT 3.3V", 0xebf91155, 0x7f5a4f50),
+	PCMCIA_DEVICE_PROD_ID12("Psion Dacom", "Gold Card Ethernet", 0xf5f025c2, 0x3a30e110),
+	PCMCIA_DEVICE_PROD_ID12("=RELIA==", "Ethernet", 0xcdd0644a, 0x00b2e941),
+	PCMCIA_DEVICE_PROD_ID12("RP", "1625B Ethernet NE2000 Compatible", 0xe3e66e22, 0xb96150df),
+	PCMCIA_DEVICE_PROD_ID12("RPTI", "EP400 Ethernet NE2000 Compatible", 0xdc6f88fd, 0x4a7e2ae0),
+	PCMCIA_DEVICE_PROD_ID12("RPTI", "EP401 Ethernet NE2000 Compatible", 0xdc6f88fd, 0x4bcbd7fd),
+	PCMCIA_DEVICE_PROD_ID12("RPTI LTD.", "EP400", 0xc53ac515, 0x81e39388),
+	PCMCIA_DEVICE_PROD_ID12("SCM", "Ethernet Combo card", 0xbdc3b102, 0x929c486c),
+	PCMCIA_DEVICE_PROD_ID12("Seiko Epson Corp.", "Ethernet", 0x09928730, 0x00b2e941),
+	PCMCIA_DEVICE_PROD_ID12("SMC", "EZCard-10-PCMCIA", 0xc4f8b18b, 0xfb21d265),
+	PCMCIA_DEVICE_PROD_ID12("Socket Communications Inc", "Socket EA PCMCIA LAN Adapter Revision D", 0xc70a4760, 0x2ade483e),
+	PCMCIA_DEVICE_PROD_ID12("Socket Communications Inc", "Socket EA PCMCIA LAN Adapter Revision E", 0xc70a4760, 0x5dd978a8),
+	PCMCIA_DEVICE_PROD_ID12("TDK", "LAK-CD031 for PCMCIA", 0x1eae9475, 0x0ed386fa),
+	PCMCIA_DEVICE_PROD_ID12("Telecom Device K.K.", "SuperSocket RE450T", 0x466b05f0, 0x8b74bc4f),
+	PCMCIA_DEVICE_PROD_ID12("Telecom Device K.K.", "SuperSocket RE550T", 0x466b05f0, 0x33c8db2a),
+	PCMCIA_DEVICE_PROD_ID13("Hypertec",  "EP401", 0x8787bec7, 0xf6e4a31e),
+	PCMCIA_DEVICE_PROD_ID13("KingMax Technology Inc.", "Ethernet Card", 0x932b7189, 0x5e9d92c0),
+	PCMCIA_DEVICE_PROD_ID13("LONGSHINE", "EP401", 0xf866b0b0, 0xf6e4a31e),
+	PCMCIA_DEVICE_PROD_ID13("Xircom", "CFE-10", 0x2e3ee845, 0x22a49f89),
+	PCMCIA_DEVICE_PROD_ID1("CyQ've 10 Base-T LAN CARD", 0x94faf360),
+	PCMCIA_DEVICE_PROD_ID1("EP-210 PCMCIA LAN CARD.", 0x8850b4de),
+	PCMCIA_DEVICE_PROD_ID1("ETHER-C16", 0x06a8514f),
+	PCMCIA_DEVICE_PROD_ID1("IC-CARD", 0x60cb09a6),
+	PCMCIA_DEVICE_PROD_ID1("NE2000 Compatible", 0x75b8ad5a),
+	PCMCIA_DEVICE_PROD_ID2("EN-6200P2", 0xa996d078),
+	/* too generic! */
+	/* PCMCIA_DEVICE_PROD_ID12("PCMCIA", "10/100 Ethernet Card", 0x281f1c5d, 0x11b0ffc0), */
+	PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "PCMCIA", "EN2218-LAN/MODEM", 0x281f1c5d, 0x570f348e, "PCMLM28.cis"),
+	PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "PCMCIA", "UE2218-LAN/MODEM", 0x281f1c5d, 0x6fdcacee, "PCMLM28.cis"),
+	PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "Psion Dacom", "Gold Card V34 Ethernet", 0xf5f025c2, 0x338e8155, "PCMLM28.cis"),
+	PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "Psion Dacom", "Gold Card V34 Ethernet GSM", 0xf5f025c2, 0x4ae85d35, "PCMLM28.cis"),
+	PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "LINKSYS", "PCMLM28", 0xf7cb0b07, 0x66881874, "PCMLM28.cis"),
+	PCMCIA_MFC_DEVICE_CIS_PROD_ID12(0, "DAYNA COMMUNICATIONS", "LAN AND MODEM MULTIFUNCTION", 0x8fdf8f89, 0xdd5ed9e8, "DP83903.cis"),
+	PCMCIA_MFC_DEVICE_CIS_PROD_ID4(0, "NSC MF LAN/Modem", 0x58fc6056, "DP83903.cis"),
+	PCMCIA_MFC_DEVICE_CIS_MANF_CARD(0, 0x0175, 0x0000, "DP83903.cis"),
+	PCMCIA_DEVICE_CIS_MANF_CARD(0xc00f, 0x0002, "LA-PCM.cis"),
+	PCMCIA_DEVICE_CIS_PROD_ID12("KTI", "PE520 PLUS", 0xad180345, 0x9d58d392, "PE520.cis"),
+	PCMCIA_DEVICE_CIS_PROD_ID12("NDC", "Ethernet", 0x01c43ae1, 0x00b2e941, "NE2K.cis"),
+	PCMCIA_DEVICE_CIS_PROD_ID12("PMX   ", "PE-200", 0x34f3f1c8, 0x10b59f8c, "PE-200.cis"),
+	PCMCIA_DEVICE_CIS_PROD_ID12("TAMARACK", "Ethernet", 0xcf434fba, 0x00b2e941, "tamarack.cis"),
+	PCMCIA_DEVICE_NULL
+};
+MODULE_DEVICE_TABLE(pcmcia, pcnet_ids);
+
 static struct pcmcia_driver pcnet_driver = {
 	.drv		= {
 		.name	= "pcnet_cs",
 	},
 	.attach		= pcnet_attach,
+	.event		= pcnet_event,
 	.detach		= pcnet_detach,
 	.owner		= THIS_MODULE,
+	.id_table	= pcnet_ids,
 };
 
 static int __init init_pcnet_cs(void)
diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c
--- a/drivers/net/pcmcia/smc91c92_cs.c
+++ b/drivers/net/pcmcia/smc91c92_cs.c
@@ -41,8 +41,8 @@
 #include <linux/ioport.h>
 #include <linux/ethtool.h>
 #include <linux/mii.h>
+#include <linux/jiffies.h>
 
-#include <pcmcia/version.h>
 #include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
@@ -127,6 +127,12 @@ struct smc_private {
     int				rx_ovrn;
 };
 
+struct smc_cfg_mem {
+    tuple_t tuple;
+    cisparse_t parse;
+    u_char buf[255];
+};
+
 /* Special definitions for Megahertz multifunction cards */
 #define MEGAHERTZ_ISR		0x0380
 
@@ -364,10 +370,6 @@ static dev_link_t *smc91c92_attach(void)
     link->next = dev_list;
     dev_list = link;
     client_reg.dev_info = &dev_info;
-    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 = &smc91c92_event;
     client_reg.Version = 0x0210;
     client_reg.event_callback_args.client_data = link;
     ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -498,14 +500,24 @@ static int mhz_mfc_config(dev_link_t *li
 {
     struct net_device *dev = link->priv;
     struct smc_private *smc = netdev_priv(dev);
-    tuple_t tuple;
-    cisparse_t parse;
-    u_char buf[255];
-    cistpl_cftable_entry_t *cf = &parse.cftable_entry;
+    struct smc_cfg_mem *cfg_mem;
+    tuple_t *tuple;
+    cisparse_t *parse;
+    cistpl_cftable_entry_t *cf;
+    u_char *buf;
     win_req_t req;
     memreq_t mem;
     int i, k;
 
+    cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL);
+    if (!cfg_mem)
+        return CS_OUT_OF_RESOURCE;
+
+    tuple = &cfg_mem->tuple;
+    parse = &cfg_mem->parse;
+    cf = &parse->cftable_entry;
+    buf = cfg_mem->buf;
+
     link->conf.Attributes |= CONF_ENABLE_SPKR;
     link->conf.Status = CCSR_AUDIO_ENA;
     link->irq.Attributes =
@@ -514,12 +526,12 @@ static int mhz_mfc_config(dev_link_t *li
     link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
     link->io.NumPorts2 = 8;
 
-    tuple.Attributes = tuple.TupleOffset = 0;
-    tuple.TupleData = (cisdata_t *)buf;
-    tuple.TupleDataMax = sizeof(buf);
-    tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
+    tuple->Attributes = tuple->TupleOffset = 0;
+    tuple->TupleData = (cisdata_t *)buf;
+    tuple->TupleDataMax = 255;
+    tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY;
 
-    i = first_tuple(link->handle, &tuple, &parse);
+    i = first_tuple(link->handle, tuple, parse);
     /* The Megahertz combo cards have modem-like CIS entries, so
        we have to explicitly try a bunch of port combinations. */
     while (i == CS_SUCCESS) {
@@ -532,10 +544,10 @@ static int mhz_mfc_config(dev_link_t *li
 	    if (i == CS_SUCCESS) break;
 	}
 	if (i == CS_SUCCESS) break;
-	i = next_tuple(link->handle, &tuple, &parse);
+	i = next_tuple(link->handle, tuple, parse);
     }
     if (i != CS_SUCCESS)
-	return i;
+	goto free_cfg_mem;
     dev->base_addr = link->io.BasePort1;
 
     /* Allocate a memory window, for accessing the ISR */
@@ -544,7 +556,7 @@ static int mhz_mfc_config(dev_link_t *li
     req.AccessSpeed = 0;
     i = pcmcia_request_window(&link->handle, &req, &link->win);
     if (i != CS_SUCCESS)
-	return i;
+	goto free_cfg_mem;
     smc->base = ioremap(req.Base, req.Size);
     mem.CardOffset = mem.Page = 0;
     if (smc->manfid == MANFID_MOTOROLA)
@@ -556,6 +568,8 @@ static int mhz_mfc_config(dev_link_t *li
 	&& (smc->cardid == PRODID_MEGAHERTZ_EM3288))
 	mhz_3288_power(link);
 
+free_cfg_mem:
+    kfree(cfg_mem);
     return i;
 }
 
@@ -563,39 +577,61 @@ static int mhz_setup(dev_link_t *link)
 {
     client_handle_t handle = link->handle;
     struct net_device *dev = link->priv;
-    tuple_t tuple;
-    cisparse_t parse;
-    u_char buf[255], *station_addr;
+    struct smc_cfg_mem *cfg_mem;
+    tuple_t *tuple;
+    cisparse_t *parse;
+    u_char *buf, *station_addr;
+    int rc;
+
+    cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL);
+    if (!cfg_mem)
+	return -1;
 
-    tuple.Attributes = tuple.TupleOffset = 0;
-    tuple.TupleData = buf;
-    tuple.TupleDataMax = sizeof(buf);
+    tuple = &cfg_mem->tuple;
+    parse = &cfg_mem->parse;
+    buf = cfg_mem->buf;
+
+    tuple->Attributes = tuple->TupleOffset = 0;
+    tuple->TupleData = (cisdata_t *)buf;
+    tuple->TupleDataMax = 255;
 
     /* Read the station address from the CIS.  It is stored as the last
        (fourth) string in the Version 1 Version/ID tuple. */
-    tuple.DesiredTuple = CISTPL_VERS_1;
-    if (first_tuple(handle, &tuple, &parse) != CS_SUCCESS)
-	return -1;
+    tuple->DesiredTuple = CISTPL_VERS_1;
+    if (first_tuple(handle, tuple, parse) != CS_SUCCESS) {
+	rc = -1;
+	goto free_cfg_mem;
+    }
     /* Ugh -- the EM1144 card has two VERS_1 tuples!?! */
-    if (next_tuple(handle, &tuple, &parse) != CS_SUCCESS)
-	first_tuple(handle, &tuple, &parse);
-    if (parse.version_1.ns > 3) {
-	station_addr = parse.version_1.str + parse.version_1.ofs[3];
-	if (cvt_ascii_address(dev, station_addr) == 0)
-	    return 0;
+    if (next_tuple(handle, tuple, parse) != CS_SUCCESS)
+	first_tuple(handle, tuple, parse);
+    if (parse->version_1.ns > 3) {
+	station_addr = parse->version_1.str + parse->version_1.ofs[3];
+	if (cvt_ascii_address(dev, station_addr) == 0) {
+		rc = 0;
+		goto free_cfg_mem;
+	}
     }
 
     /* Another possibility: for the EM3288, in a special tuple */
-    tuple.DesiredTuple = 0x81;
-    if (pcmcia_get_first_tuple(handle, &tuple) != CS_SUCCESS)
-	return -1;
-    if (pcmcia_get_tuple_data(handle, &tuple) != CS_SUCCESS)
-	return -1;
+    tuple->DesiredTuple = 0x81;
+    if (pcmcia_get_first_tuple(handle, tuple) != CS_SUCCESS) {
+	rc = -1;
+	goto free_cfg_mem;
+    }
+    if (pcmcia_get_tuple_data(handle, tuple) != CS_SUCCESS) {
+	rc = -1;
+	goto free_cfg_mem;
+    }
     buf[12] = '\0';
-    if (cvt_ascii_address(dev, buf) == 0)
-	return 0;
-
-    return -1;
+    if (cvt_ascii_address(dev, buf) == 0) {
+	rc = 0;
+	goto free_cfg_mem;
+   }
+    rc = -1;
+free_cfg_mem:
+   kfree(cfg_mem);
+   return rc;
 }
 
 /*======================================================================
@@ -665,19 +701,29 @@ static int mot_setup(dev_link_t *link)
 static int smc_config(dev_link_t *link)
 {
     struct net_device *dev = link->priv;
-    tuple_t tuple;
-    cisparse_t parse;
-    u_char buf[255];
-    cistpl_cftable_entry_t *cf = &parse.cftable_entry;
+    struct smc_cfg_mem *cfg_mem;
+    tuple_t *tuple;
+    cisparse_t *parse;
+    cistpl_cftable_entry_t *cf;
+    u_char *buf;
     int i;
 
-    tuple.Attributes = tuple.TupleOffset = 0;
-    tuple.TupleData = (cisdata_t *)buf;
-    tuple.TupleDataMax = sizeof(buf);
-    tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
+    cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL);
+    if (!cfg_mem)
+	return CS_OUT_OF_RESOURCE;
+
+    tuple = &cfg_mem->tuple;
+    parse = &cfg_mem->parse;
+    cf = &parse->cftable_entry;
+    buf = cfg_mem->buf;
+
+    tuple->Attributes = tuple->TupleOffset = 0;
+    tuple->TupleData = (cisdata_t *)buf;
+    tuple->TupleDataMax = 255;
+    tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY;
 
     link->io.NumPorts1 = 16;
-    i = first_tuple(link->handle, &tuple, &parse);
+    i = first_tuple(link->handle, tuple, parse);
     while (i != CS_NO_MORE_ITEMS) {
 	if (i == CS_SUCCESS) {
 	    link->conf.ConfigIndex = cf->index;
@@ -686,10 +732,12 @@ static int smc_config(dev_link_t *link)
 	    i = pcmcia_request_io(link->handle, &link->io);
 	    if (i == CS_SUCCESS) break;
 	}
-	i = next_tuple(link->handle, &tuple, &parse);
+	i = next_tuple(link->handle, tuple, parse);
     }
     if (i == CS_SUCCESS)
 	dev->base_addr = link->io.BasePort1;
+
+    kfree(cfg_mem);
     return i;
 }
 
@@ -697,41 +745,58 @@ static int smc_setup(dev_link_t *link)
 {
     client_handle_t handle = link->handle;
     struct net_device *dev = link->priv;
-    tuple_t tuple;
-    cisparse_t parse;
+    struct smc_cfg_mem *cfg_mem;
+    tuple_t *tuple;
+    cisparse_t *parse;
     cistpl_lan_node_id_t *node_id;
-    u_char buf[255], *station_addr;
-    int i;
+    u_char *buf, *station_addr;
+    int i, rc;
 
-    tuple.Attributes = tuple.TupleOffset = 0;
-    tuple.TupleData = buf;
-    tuple.TupleDataMax = sizeof(buf);
+    cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL);
+    if (!cfg_mem)
+	return CS_OUT_OF_RESOURCE;
+
+    tuple = &cfg_mem->tuple;
+    parse = &cfg_mem->parse;
+    buf = cfg_mem->buf;
+
+    tuple->Attributes = tuple->TupleOffset = 0;
+    tuple->TupleData = (cisdata_t *)buf;
+    tuple->TupleDataMax = 255;
 
     /* Check for a LAN function extension tuple */
-    tuple.DesiredTuple = CISTPL_FUNCE;
-    i = first_tuple(handle, &tuple, &parse);
+    tuple->DesiredTuple = CISTPL_FUNCE;
+    i = first_tuple(handle, tuple, parse);
     while (i == CS_SUCCESS) {
-	if (parse.funce.type == CISTPL_FUNCE_LAN_NODE_ID)
+	if (parse->funce.type == CISTPL_FUNCE_LAN_NODE_ID)
 	    break;
-	i = next_tuple(handle, &tuple, &parse);
+	i = next_tuple(handle, tuple, parse);
     }
     if (i == CS_SUCCESS) {
-	node_id = (cistpl_lan_node_id_t *)parse.funce.data;
+	node_id = (cistpl_lan_node_id_t *)parse->funce.data;
 	if (node_id->nb == 6) {
 	    for (i = 0; i < 6; i++)
 		dev->dev_addr[i] = node_id->id[i];
-	    return 0;
+	    rc = 0;
+	    goto free_cfg_mem;
 	}
     }
     /* Try the third string in the Version 1 Version/ID tuple. */
-    tuple.DesiredTuple = CISTPL_VERS_1;
-    if (first_tuple(handle, &tuple, &parse) != CS_SUCCESS)
-	return -1;
-    station_addr = parse.version_1.str + parse.version_1.ofs[2];
-    if (cvt_ascii_address(dev, station_addr) == 0)
-	return 0;
+    tuple->DesiredTuple = CISTPL_VERS_1;
+    if (first_tuple(handle, tuple, parse) != CS_SUCCESS) {
+	rc = -1;
+	goto free_cfg_mem;
+    }
+    station_addr = parse->version_1.str + parse->version_1.ofs[2];
+    if (cvt_ascii_address(dev, station_addr) == 0) {
+	rc = 0;
+	goto free_cfg_mem;
+    }
 
-    return -1;
+    rc = -1;
+free_cfg_mem:
+    kfree(cfg_mem);
+    return rc;
 }
 
 /*====================================================================*/
@@ -773,26 +838,36 @@ static int osi_setup(dev_link_t *link, u
 {
     client_handle_t handle = link->handle;
     struct net_device *dev = link->priv;
-    tuple_t tuple;
-    u_char buf[255];
-    int i;
-
-    tuple.Attributes = TUPLE_RETURN_COMMON;
-    tuple.TupleData = buf;
-    tuple.TupleDataMax = sizeof(buf);
-    tuple.TupleOffset = 0;
+    struct smc_cfg_mem *cfg_mem;
+    tuple_t *tuple;
+    u_char *buf;
+    int i, rc;
+
+    cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL);
+    if (!cfg_mem)
+        return -1;
+
+    tuple = &cfg_mem->tuple;
+    buf = cfg_mem->buf;
+
+    tuple->Attributes = TUPLE_RETURN_COMMON;
+    tuple->TupleData = (cisdata_t *)buf;
+    tuple->TupleDataMax = 255;
+    tuple->TupleOffset = 0;
 
     /* Read the station address from tuple 0x90, subtuple 0x04 */
-    tuple.DesiredTuple = 0x90;
-    i = pcmcia_get_first_tuple(handle, &tuple);
+    tuple->DesiredTuple = 0x90;
+    i = pcmcia_get_first_tuple(handle, tuple);
     while (i == CS_SUCCESS) {
-	i = pcmcia_get_tuple_data(handle, &tuple);
+	i = pcmcia_get_tuple_data(handle, tuple);
 	if ((i != CS_SUCCESS) || (buf[0] == 0x04))
 	    break;
-	i = pcmcia_get_next_tuple(handle, &tuple);
+	i = pcmcia_get_next_tuple(handle, tuple);
+    }
+    if (i != CS_SUCCESS) {
+	rc = -1;
+	goto free_cfg_mem;
     }
-    if (i != CS_SUCCESS)
-	return -1;
     for (i = 0; i < 6; i++)
 	dev->dev_addr[i] = buf[i+2];
 
@@ -814,8 +889,10 @@ static int osi_setup(dev_link_t *link, u
 	      inw(link->io.BasePort1 + OSITECH_AUI_PWR),
 	      inw(link->io.BasePort1 + OSITECH_RESET_ISR));
     }
-
-    return 0;
+    rc = 0;
+free_cfg_mem:
+   kfree(cfg_mem);
+   return rc;
 }
 
 /*======================================================================
@@ -887,9 +964,10 @@ static void smc91c92_config(dev_link_t *
     client_handle_t handle = link->handle;
     struct net_device *dev = link->priv;
     struct smc_private *smc = netdev_priv(dev);
-    tuple_t tuple;
-    cisparse_t parse;
-    u_short buf[32];
+    struct smc_cfg_mem *cfg_mem;
+    tuple_t *tuple;
+    cisparse_t *parse;
+    u_char *buf;
     char *name;
     int i, j, rev;
     kio_addr_t ioaddr;
@@ -897,21 +975,29 @@ static void smc91c92_config(dev_link_t *
 
     DEBUG(0, "smc91c92_config(0x%p)\n", link);
 
-    tuple.Attributes = tuple.TupleOffset = 0;
-    tuple.TupleData = (cisdata_t *)buf;
-    tuple.TupleDataMax = sizeof(buf);
+    cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL);
+    if (!cfg_mem)
+	goto config_failed;
+
+    tuple = &cfg_mem->tuple;
+    parse = &cfg_mem->parse;
+    buf = cfg_mem->buf;
+
+    tuple->Attributes = tuple->TupleOffset = 0;
+    tuple->TupleData = (cisdata_t *)buf;
+    tuple->TupleDataMax = 64;
 
-    tuple.DesiredTuple = CISTPL_CONFIG;
-    i = first_tuple(handle, &tuple, &parse);
+    tuple->DesiredTuple = CISTPL_CONFIG;
+    i = first_tuple(handle, tuple, parse);
     CS_EXIT_TEST(i, ParseTuple, config_failed);
-    link->conf.ConfigBase = parse.config.base;
-    link->conf.Present = parse.config.rmask[0];
+    link->conf.ConfigBase = parse->config.base;
+    link->conf.Present = parse->config.rmask[0];
 
-    tuple.DesiredTuple = CISTPL_MANFID;
-    tuple.Attributes = TUPLE_RETURN_COMMON;
-    if (first_tuple(handle, &tuple, &parse) == CS_SUCCESS) {
-	smc->manfid = parse.manfid.manf;
-	smc->cardid = parse.manfid.card;
+    tuple->DesiredTuple = CISTPL_MANFID;
+    tuple->Attributes = TUPLE_RETURN_COMMON;
+    if (first_tuple(handle, tuple, parse) == CS_SUCCESS) {
+	smc->manfid = parse->manfid.manf;
+	smc->cardid = parse->manfid.card;
     }
 
     /* Configure card */
@@ -1046,7 +1132,7 @@ static void smc91c92_config(dev_link_t *
     	    printk(KERN_NOTICE "  No MII transceivers found!\n");
 	}
     }
-
+    kfree(cfg_mem);
     return;
 
 config_undo:
@@ -1054,6 +1140,7 @@ config_undo:
 config_failed:			/* CS_EXIT_TEST() calls jump to here... */
     smc91c92_release(link);
     link->state &= ~DEV_CONFIG_PENDING;
+    kfree(cfg_mem);
 
 } /* smc91c92_config */
 
@@ -2006,7 +2093,7 @@ static void media_check(u_long arg)
     }
 
     /* Ignore collisions unless we've had no rx's recently */
-    if (jiffies - dev->last_rx > HZ) {
+    if (time_after(jiffies, dev->last_rx + HZ)) {
 	if (smc->tx_err || (smc->media_status & EPH_16COL))
 	    media |= EPH_16COL;
     }
@@ -2236,13 +2323,47 @@ static int smc_ioctl (struct net_device 
 	return rc;
 }
 
+static struct pcmcia_device_id smc91c92_ids[] = {
+	PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0109, 0x0501),
+	PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0140, 0x000a),
+	PCMCIA_PFC_DEVICE_PROD_ID123(0, "MEGAHERTZ", "CC/XJEM3288", "DATA/FAX/CELL ETHERNET MODEM", 0xf510db04, 0x04cd2988, 0x46a52d63),
+	PCMCIA_PFC_DEVICE_PROD_ID123(0, "MEGAHERTZ", "CC/XJEM3336", "DATA/FAX/CELL ETHERNET MODEM", 0xf510db04, 0x0143b773, 0x46a52d63),
+	PCMCIA_PFC_DEVICE_PROD_ID123(0, "MEGAHERTZ", "EM1144T", "PCMCIA MODEM", 0xf510db04, 0x856d66c8, 0xbd6c43ef),
+	PCMCIA_PFC_DEVICE_PROD_ID123(0, "MEGAHERTZ", "XJEM1144/CCEM1144", "PCMCIA MODEM", 0xf510db04, 0x52d21e1e, 0xbd6c43ef),
+	PCMCIA_PFC_DEVICE_PROD_ID12(0, "Gateway 2000", "XJEM3336", 0xdd9989be, 0x662c394c),
+	PCMCIA_PFC_DEVICE_PROD_ID12(0, "MEGAHERTZ", "XJEM1144/CCEM1144", 0xf510db04, 0x52d21e1e),
+	PCMCIA_PFC_DEVICE_PROD_ID12(0, "Ositech", "Trumpcard:Jack of Diamonds Modem+Ethernet", 0xc2f80cd, 0x656947b9),
+	PCMCIA_PFC_DEVICE_PROD_ID12(0, "Ositech", "Trumpcard:Jack of Hearts Modem+Ethernet", 0xc2f80cd, 0xdc9ba5ed),
+	PCMCIA_MFC_DEVICE_MANF_CARD(0, 0x016c, 0x0020),
+	PCMCIA_DEVICE_MANF_CARD(0x016c, 0x0023),
+	PCMCIA_DEVICE_PROD_ID123("BASICS by New Media Corporation", "Ethernet", "SMC91C94", 0x23c78a9d, 0x00b2e941, 0xcef397fb),
+	PCMCIA_DEVICE_PROD_ID12("ARGOSY", "Fast Ethernet PCCard", 0x78f308dc, 0xdcea68bc),
+	PCMCIA_DEVICE_PROD_ID12("dit Co., Ltd.", "PC Card-10/100BTX", 0xe59365c8, 0x6a2161d1),
+	PCMCIA_DEVICE_PROD_ID12("DYNALINK", "L100C", 0x6a26d1cf, 0xc16ce9c5),
+	PCMCIA_DEVICE_PROD_ID12("Farallon", "Farallon Enet", 0x58d93fc4, 0x244734e9),
+	PCMCIA_DEVICE_PROD_ID12("Megahertz", "CC10BT/2", 0x33234748, 0x3c95b953),
+	PCMCIA_DEVICE_PROD_ID12("MELCO/SMC", "LPC-TX", 0xa2cd8e6d, 0x42da662a),
+	PCMCIA_DEVICE_PROD_ID12("Ositech", "Trumpcard:Four of Diamonds Ethernet", 0xc2f80cd, 0xb3466314),
+	PCMCIA_DEVICE_PROD_ID12("Ositech", "Trumpcard:Seven of Diamonds Ethernet", 0xc2f80cd, 0x194b650a),
+	PCMCIA_DEVICE_PROD_ID12("PCMCIA", "Fast Ethernet PCCard", 0x281f1c5d, 0xdcea68bc),
+	PCMCIA_DEVICE_PROD_ID12("Psion", "10Mb Ethernet", 0x4ef00b21, 0x844be9e9),
+	PCMCIA_DEVICE_PROD_ID12("SMC", "EtherEZ Ethernet 8020", 0xc4f8b18b, 0x4a0eeb2d),
+	/* These conflict with other cards! */
+	/* PCMCIA_DEVICE_MANF_CARD(0x0186, 0x0100), */
+	/* PCMCIA_DEVICE_MANF_CARD(0x8a01, 0xc1ab), */
+	PCMCIA_DEVICE_NULL,
+};
+MODULE_DEVICE_TABLE(pcmcia, smc91c92_ids);
+
 static struct pcmcia_driver smc91c92_cs_driver = {
 	.owner		= THIS_MODULE,
 	.drv		= {
 		.name	= "smc91c92_cs",
 	},
 	.attach		= smc91c92_attach,
+	.event		= smc91c92_event,
 	.detach		= smc91c92_detach,
+	.id_table       = smc91c92_ids,
 };
 
 static int __init init_smc91c92_cs(void)
diff --git a/drivers/net/pcmcia/xirc2ps_cs.c b/drivers/net/pcmcia/xirc2ps_cs.c
--- a/drivers/net/pcmcia/xirc2ps_cs.c
+++ b/drivers/net/pcmcia/xirc2ps_cs.c
@@ -81,7 +81,6 @@
 #include <linux/ioport.h>
 #include <linux/bitops.h>
 
-#include <pcmcia/version.h>
 #include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
@@ -619,11 +618,6 @@ xirc2ps_attach(void)
     link->next = dev_list;
     dev_list = link;
     client_reg.dev_info = &dev_info;
-    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 = &xirc2ps_event;
     client_reg.Version = 0x0210;
     client_reg.event_callback_args.client_data = link;
     if ((err = pcmcia_register_client(&link->handle, &client_reg))) {
@@ -1983,13 +1977,42 @@ do_stop(struct net_device *dev)
     return 0;
 }
 
+static struct pcmcia_device_id xirc2ps_ids[] = {
+	PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0089, 0x110a),
+	PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0138, 0x110a),
+	PCMCIA_PFC_DEVICE_PROD_ID13(0, "Xircom", "CEM28", 0x2e3ee845, 0x0ea978ea),
+	PCMCIA_PFC_DEVICE_PROD_ID13(0, "Xircom", "CEM33", 0x2e3ee845, 0x80609023),
+	PCMCIA_PFC_DEVICE_PROD_ID13(0, "Xircom", "CEM56", 0x2e3ee845, 0xa650c32a),
+	PCMCIA_PFC_DEVICE_PROD_ID13(0, "Xircom", "REM10", 0x2e3ee845, 0x76df1d29),
+	PCMCIA_PFC_DEVICE_PROD_ID13(0, "Xircom", "XEM5600", 0x2e3ee845, 0xf1403719),
+	PCMCIA_PFC_DEVICE_PROD_ID12(0, "Xircom", "CreditCard Ethernet+Modem II", 0x2e3ee845, 0xeca401bf),
+	PCMCIA_DEVICE_MANF_CARD(0x01bf, 0x010a),
+	PCMCIA_DEVICE_PROD_ID13("Toshiba Information Systems", "TPCENET", 0x1b3b94fe, 0xf381c1a2),
+	PCMCIA_DEVICE_PROD_ID13("Xircom", "CE3-10/100", 0x2e3ee845, 0x0ec0ac37),
+	PCMCIA_DEVICE_PROD_ID13("Xircom", "PS-CE2-10", 0x2e3ee845, 0x947d9073),
+	PCMCIA_DEVICE_PROD_ID13("Xircom", "R2E-100BTX", 0x2e3ee845, 0x2464a6e3),
+	PCMCIA_DEVICE_PROD_ID13("Xircom", "RE-10", 0x2e3ee845, 0x3e08d609),
+	PCMCIA_DEVICE_PROD_ID13("Xircom", "XE2000", 0x2e3ee845, 0xf7188e46),
+	PCMCIA_DEVICE_PROD_ID12("Compaq", "Ethernet LAN Card", 0x54f7c49c, 0x9fd2f0a2),
+	PCMCIA_DEVICE_PROD_ID12("Compaq", "Netelligent 10/100 PC Card", 0x54f7c49c, 0xefe96769),
+	PCMCIA_DEVICE_PROD_ID12("Intel", "EtherExpress(TM) PRO/100 PC Card Mobile Adapter16", 0x816cc815, 0x174397db),
+	PCMCIA_DEVICE_PROD_ID12("Toshiba", "10/100 Ethernet PC Card", 0x44a09d9c, 0xb44deecf),
+	/* also matches CFE-10 cards! */
+	/* PCMCIA_DEVICE_MANF_CARD(0x0105, 0x010a), */
+	PCMCIA_DEVICE_NULL,
+};
+MODULE_DEVICE_TABLE(pcmcia, xirc2ps_ids);
+
+
 static struct pcmcia_driver xirc2ps_cs_driver = {
 	.owner		= THIS_MODULE,
 	.drv		= {
 		.name	= "xirc2ps_cs",
 	},
 	.attach		= xirc2ps_attach,
+	.event		= xirc2ps_event,
 	.detach		= xirc2ps_detach,
+	.id_table       = xirc2ps_ids,
 };
 
 static int __init
diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c
--- a/drivers/net/pcnet32.c
+++ b/drivers/net/pcnet32.c
@@ -850,7 +850,7 @@ static int pcnet32_phys_id(struct net_de
     if ((!data) || (data > (u32)(MAX_SCHEDULE_TIMEOUT / HZ)))
     data = (u32)(MAX_SCHEDULE_TIMEOUT / HZ);
 
-    schedule_timeout(data * HZ);
+    msleep_interruptible(data * 1000);
     del_timer_sync(&lp->blink_timer);
 
     /* Restore the original value of the bcrs */
@@ -1602,7 +1602,7 @@ pcnet32_init_ring(struct net_device *dev
 
 	rmb();
 	if (lp->rx_dma_addr[i] == 0)
-	    lp->rx_dma_addr[i] = pci_map_single(lp->pci_dev, rx_skbuff->tail,
+	    lp->rx_dma_addr[i] = pci_map_single(lp->pci_dev, rx_skbuff->data,
 		    PKT_BUF_SZ-2, PCI_DMA_FROMDEVICE);
 	lp->rx_ring[i].base = (u32)le32_to_cpu(lp->rx_dma_addr[i]);
 	lp->rx_ring[i].buf_length = le16_to_cpu(2-PKT_BUF_SZ);
@@ -1983,7 +1983,7 @@ pcnet32_rx(struct net_device *dev)
 			lp->rx_skbuff[entry] = newskb;
 			newskb->dev = dev;
 			lp->rx_dma_addr[entry] =
-			    pci_map_single(lp->pci_dev, newskb->tail,
+			    pci_map_single(lp->pci_dev, newskb->data,
 				    PKT_BUF_SZ-2, PCI_DMA_FROMDEVICE);
 			lp->rx_ring[entry].base = le32_to_cpu(lp->rx_dma_addr[entry]);
 			rx_in_place = 1;
@@ -2020,7 +2020,7 @@ pcnet32_rx(struct net_device *dev)
 						PKT_BUF_SZ-2,
 						PCI_DMA_FROMDEVICE);
 		    eth_copy_and_sum(skb,
-			    (unsigned char *)(lp->rx_skbuff[entry]->tail),
+			    (unsigned char *)(lp->rx_skbuff[entry]->data),
 			    pkt_len,0);
 		    pci_dma_sync_single_for_device(lp->pci_dev,
 						   lp->rx_dma_addr[entry],
diff --git a/drivers/net/plip.c b/drivers/net/plip.c
--- a/drivers/net/plip.c
+++ b/drivers/net/plip.c
@@ -160,7 +160,7 @@ static struct net_device_stats *plip_get
 static int plip_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
 static int plip_preempt(void *handle);
 static void plip_wakeup(void *handle);
-
+
 enum plip_connection_state {
 	PLIP_CN_NONE=0,
 	PLIP_CN_RECEIVE,
@@ -231,8 +231,8 @@ struct net_local {
 	atomic_t kill_timer;
 	struct semaphore killed_timer_sem;
 };
-
-inline static void enable_parport_interrupts (struct net_device *dev)
+
+static inline void enable_parport_interrupts (struct net_device *dev)
 {
 	if (dev->irq != -1)
 	{
@@ -242,7 +242,7 @@ inline static void enable_parport_interr
 	}
 }
 
-inline static void disable_parport_interrupts (struct net_device *dev)
+static inline void disable_parport_interrupts (struct net_device *dev)
 {
 	if (dev->irq != -1)
 	{
@@ -252,7 +252,7 @@ inline static void disable_parport_inter
 	}
 }
 
-inline static void write_data (struct net_device *dev, unsigned char data)
+static inline void write_data (struct net_device *dev, unsigned char data)
 {
 	struct parport *port =
 	   ((struct net_local *)dev->priv)->pardev->port;
@@ -260,14 +260,14 @@ inline static void write_data (struct ne
 	port->ops->write_data (port, data);
 }
 
-inline static unsigned char read_status (struct net_device *dev)
+static inline unsigned char read_status (struct net_device *dev)
 {
 	struct parport *port =
 	   ((struct net_local *)dev->priv)->pardev->port;
 
 	return port->ops->read_status (port);
 }
-
+
 /* Entry point of PLIP driver.
    Probe the hardware, and register/initialize the driver.
 
@@ -316,7 +316,7 @@ plip_init_netdev(struct net_device *dev)
 
 	spin_lock_init(&nl->lock);
 }
-
+
 /* Bottom half handler for the delayed request.
    This routine is kicked by do_timer().
    Request `plip_bh' to be invoked. */
@@ -471,7 +471,7 @@ plip_bh_timeout_error(struct net_device 
 
 	return TIMEOUT;
 }
-
+
 static int
 plip_none(struct net_device *dev, struct net_local *nl,
 	  struct plip_local *snd, struct plip_local *rcv)
@@ -481,7 +481,7 @@ plip_none(struct net_device *dev, struct
 
 /* PLIP_RECEIVE --- receive a byte(two nibbles)
    Returns OK on success, TIMEOUT on timeout */
-inline static int
+static inline int
 plip_receive(unsigned short nibble_timeout, struct net_device *dev,
 	     enum plip_nibble_state *ns_p, unsigned char *data_p)
 {
@@ -540,7 +540,7 @@ plip_receive(unsigned short nibble_timeo
  *	in far too many old systems not all even running Linux.
  */
  
-static unsigned short plip_type_trans(struct sk_buff *skb, struct net_device *dev)
+static __be16 plip_type_trans(struct sk_buff *skb, struct net_device *dev)
 {
 	struct ethhdr *eth;
 	unsigned char *rawp;
@@ -582,7 +582,6 @@ static unsigned short plip_type_trans(st
 	return htons(ETH_P_802_2);
 }
 
-
 /* PLIP_RECEIVE_PACKET --- receive a packet */
 static int
 plip_receive_packet(struct net_device *dev, struct net_local *nl,
@@ -702,7 +701,7 @@ plip_receive_packet(struct net_device *d
 
 /* PLIP_SEND --- send a byte (two nibbles)
    Returns OK on success, TIMEOUT when timeout    */
-inline static int
+static inline int
 plip_send(unsigned short nibble_timeout, struct net_device *dev,
 	  enum plip_nibble_state *ns_p, unsigned char data)
 {
@@ -902,7 +901,7 @@ plip_error(struct net_device *dev, struc
 
 	return OK;
 }
-
+
 /* Handle the parallel port interrupts. */
 static void
 plip_interrupt(int irq, void *dev_id, struct pt_regs * regs)
@@ -957,7 +956,7 @@ plip_interrupt(int irq, void *dev_id, st
 
 	spin_unlock_irq(&nl->lock);
 }
-
+
 static int
 plip_tx_packet(struct sk_buff *skb, struct net_device *dev)
 {
@@ -1238,7 +1237,7 @@ plip_ioctl(struct net_device *dev, struc
 	}
 	return 0;
 }
-
+
 static int parport[PLIP_MAX] = { [0 ... PLIP_MAX-1] = -1 };
 static int timid;
 
diff --git a/drivers/net/ppp_async.c b/drivers/net/ppp_async.c
--- a/drivers/net/ppp_async.c
+++ b/drivers/net/ppp_async.c
@@ -364,7 +364,7 @@ ppp_asynctty_receive(struct tty_struct *
 	spin_lock_irqsave(&ap->recv_lock, flags);
 	ppp_async_input(ap, buf, cflags, count);
 	spin_unlock_irqrestore(&ap->recv_lock, flags);
-	if (skb_queue_len(&ap->rqueue))
+	if (!skb_queue_empty(&ap->rqueue))
 		tasklet_schedule(&ap->tsk);
 	ap_put(ap);
 	if (test_and_clear_bit(TTY_THROTTLED, &tty->flags)
@@ -1025,7 +1025,7 @@ static void async_lcp_peek(struct asyncp
 
 static void __exit ppp_async_cleanup(void)
 {
-	if (tty_register_ldisc(N_PPP, NULL) != 0)
+	if (tty_unregister_ldisc(N_PPP) != 0)
 		printk(KERN_ERR "failed to unregister PPP line discipline\n");
 }
 
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c
--- a/drivers/net/ppp_generic.c
+++ b/drivers/net/ppp_generic.c
@@ -273,7 +273,7 @@ static int ppp_connect_channel(struct ch
 static int ppp_disconnect_channel(struct channel *pch);
 static void ppp_destroy_channel(struct channel *pch);
 
-static struct class_simple *ppp_class;
+static struct class *ppp_class;
 
 /* Translates a PPP protocol number to a NP index (NP == network protocol) */
 static inline int proto_to_npindex(int proto)
@@ -858,12 +858,12 @@ static int __init ppp_init(void)
 	printk(KERN_INFO "PPP generic driver version " PPP_VERSION "\n");
 	err = register_chrdev(PPP_MAJOR, "ppp", &ppp_device_fops);
 	if (!err) {
-		ppp_class = class_simple_create(THIS_MODULE, "ppp");
+		ppp_class = class_create(THIS_MODULE, "ppp");
 		if (IS_ERR(ppp_class)) {
 			err = PTR_ERR(ppp_class);
 			goto out_chrdev;
 		}
-		class_simple_device_add(ppp_class, MKDEV(PPP_MAJOR, 0), NULL, "ppp");
+		class_device_create(ppp_class, MKDEV(PPP_MAJOR, 0), NULL, "ppp");
 		err = devfs_mk_cdev(MKDEV(PPP_MAJOR, 0),
 				S_IFCHR|S_IRUSR|S_IWUSR, "ppp");
 		if (err)
@@ -876,8 +876,8 @@ out:
 	return err;
 
 out_class:
-	class_simple_device_remove(MKDEV(PPP_MAJOR,0));
-	class_simple_destroy(ppp_class);
+	class_device_destroy(ppp_class, MKDEV(PPP_MAJOR,0));
+	class_destroy(ppp_class);
 out_chrdev:
 	unregister_chrdev(PPP_MAJOR, "ppp");
 	goto out;
@@ -1217,36 +1217,43 @@ ppp_push(struct ppp *ppp)
  */
 static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb)
 {
-	int nch, len, fragsize;
+	int len, fragsize;
 	int i, bits, hdrlen, mtu;
-	int flen, fnb;
+	int flen;
+	int navail, nfree;
+	int nbigger;
 	unsigned char *p, *q;
 	struct list_head *list;
 	struct channel *pch;
 	struct sk_buff *frag;
 	struct ppp_channel *chan;
 
-	nch = 0;
+	nfree = 0;	/* # channels which have no packet already queued */
+	navail = 0;	/* total # of usable channels (not deregistered) */
 	hdrlen = (ppp->flags & SC_MP_XSHORTSEQ)? MPHDRLEN_SSN: MPHDRLEN;
+	i = 0;
 	list = &ppp->channels;
 	while ((list = list->next) != &ppp->channels) {
 		pch = list_entry(list, struct channel, clist);
-		nch += pch->avail = (skb_queue_len(&pch->file.xq) == 0);
-		/*
-		 * If a channel hasn't had a fragment yet, it has to get
-		 * one before we send any fragments on later channels.
-		 * If it can't take a fragment now, don't give any
-		 * to subsequent channels.
-		 */
-		if (!pch->had_frag && !pch->avail) {
-			while ((list = list->next) != &ppp->channels) {
-				pch = list_entry(list, struct channel, clist);
-				pch->avail = 0;
+		navail += pch->avail = (pch->chan != NULL);
+		if (pch->avail) {
+			if (skb_queue_empty(&pch->file.xq) ||
+			    !pch->had_frag) {
+				pch->avail = 2;
+				++nfree;
 			}
-			break;
+			if (!pch->had_frag && i < ppp->nxchan)
+				ppp->nxchan = i;
 		}
+		++i;
 	}
-	if (nch == 0)
+
+	/*
+	 * Don't start sending this packet unless at least half of
+	 * the channels are free.  This gives much better TCP
+	 * performance if we have a lot of channels.
+	 */
+	if (nfree == 0 || nfree < navail / 2)
 		return 0;	/* can't take now, leave it in xmit_pending */
 
 	/* Do protocol field compression (XXX this should be optional) */
@@ -1257,14 +1264,19 @@ static int ppp_mp_explode(struct ppp *pp
 		--len;
 	}
 
-	/* decide on fragment size */
+	/*
+	 * Decide on fragment size.
+	 * We create a fragment for each free channel regardless of
+	 * how small they are (i.e. even 0 length) in order to minimize
+	 * the time that it will take to detect when a channel drops
+	 * a fragment.
+	 */
 	fragsize = len;
-	if (nch > 1) {
-		int maxch = ROUNDUP(len, MIN_FRAG_SIZE);
-		if (nch > maxch)
-			nch = maxch;
-		fragsize = ROUNDUP(fragsize, nch);
-	}
+	if (nfree > 1)
+		fragsize = ROUNDUP(fragsize, nfree);
+	/* nbigger channels get fragsize bytes, the rest get fragsize-1,
+	   except if nbigger==0, then they all get fragsize. */
+	nbigger = len % nfree;
 
 	/* skip to the channel after the one we last used
 	   and start at that one */
@@ -1278,7 +1290,7 @@ static int ppp_mp_explode(struct ppp *pp
 
 	/* create a fragment for each channel */
 	bits = B;
-	do {
+	while (nfree > 0 || len > 0) {
 		list = list->next;
 		if (list == &ppp->channels) {
 			i = 0;
@@ -1289,61 +1301,92 @@ static int ppp_mp_explode(struct ppp *pp
 		if (!pch->avail)
 			continue;
 
+		/*
+		 * Skip this channel if it has a fragment pending already and
+		 * we haven't given a fragment to all of the free channels.
+		 */
+		if (pch->avail == 1) {
+			if (nfree > 0)
+				continue;
+		} else {
+			--nfree;
+			pch->avail = 1;
+		}
+
 		/* check the channel's mtu and whether it is still attached. */
 		spin_lock_bh(&pch->downl);
-		if (pch->chan == 0 || (mtu = pch->chan->mtu) < hdrlen) {
-			/* can't use this channel */
+		if (pch->chan == NULL) {
+			/* can't use this channel, it's being deregistered */
 			spin_unlock_bh(&pch->downl);
 			pch->avail = 0;
-			if (--nch == 0)
+			if (--navail == 0)
 				break;
 			continue;
 		}
 
 		/*
-		 * We have to create multiple fragments for this channel
-		 * if fragsize is greater than the channel's mtu.
+		 * Create a fragment for this channel of
+		 * min(max(mtu+2-hdrlen, 4), fragsize, len) bytes.
+		 * If mtu+2-hdrlen < 4, that is a ridiculously small
+		 * MTU, so we use mtu = 2 + hdrlen.
 		 */
 		if (fragsize > len)
 			fragsize = len;
-		for (flen = fragsize; flen > 0; flen -= fnb) {
-			fnb = flen;
-			if (fnb > mtu + 2 - hdrlen)
-				fnb = mtu + 2 - hdrlen;
-			if (fnb >= len)
-				bits |= E;
-			frag = alloc_skb(fnb + hdrlen, GFP_ATOMIC);
-			if (frag == 0)
-				goto noskb;
-			q = skb_put(frag, fnb + hdrlen);
-			/* make the MP header */
-			q[0] = PPP_MP >> 8;
-			q[1] = PPP_MP;
-			if (ppp->flags & SC_MP_XSHORTSEQ) {
-				q[2] = bits + ((ppp->nxseq >> 8) & 0xf);
-				q[3] = ppp->nxseq;
-			} else {
-				q[2] = bits;
-				q[3] = ppp->nxseq >> 16;
-				q[4] = ppp->nxseq >> 8;
-				q[5] = ppp->nxseq;
-			}
+		flen = fragsize;
+		mtu = pch->chan->mtu + 2 - hdrlen;
+		if (mtu < 4)
+			mtu = 4;
+		if (flen > mtu)
+			flen = mtu;
+		if (flen == len && nfree == 0)
+			bits |= E;
+		frag = alloc_skb(flen + hdrlen + (flen == 0), GFP_ATOMIC);
+		if (frag == 0)
+			goto noskb;
+		q = skb_put(frag, flen + hdrlen);
+
+		/* make the MP header */
+		q[0] = PPP_MP >> 8;
+		q[1] = PPP_MP;
+		if (ppp->flags & SC_MP_XSHORTSEQ) {
+			q[2] = bits + ((ppp->nxseq >> 8) & 0xf);
+			q[3] = ppp->nxseq;
+		} else {
+			q[2] = bits;
+			q[3] = ppp->nxseq >> 16;
+			q[4] = ppp->nxseq >> 8;
+			q[5] = ppp->nxseq;
+		}
 
-			/* copy the data in */
-			memcpy(q + hdrlen, p, fnb);
+		/*
+		 * Copy the data in.
+		 * Unfortunately there is a bug in older versions of
+		 * the Linux PPP multilink reconstruction code where it
+		 * drops 0-length fragments.  Therefore we make sure the
+		 * fragment has at least one byte of data.  Any bytes
+		 * we add in this situation will end up as padding on the
+		 * end of the reconstructed packet.
+		 */
+		if (flen == 0)
+			*skb_put(frag, 1) = 0;
+		else
+			memcpy(q + hdrlen, p, flen);
 
-			/* try to send it down the channel */
-			chan = pch->chan;
-			if (!chan->ops->start_xmit(chan, frag))
-				skb_queue_tail(&pch->file.xq, frag);
-			pch->had_frag = 1;
-			p += fnb;
-			len -= fnb;
-			++ppp->nxseq;
-			bits = 0;
-		}
+		/* try to send it down the channel */
+		chan = pch->chan;
+		if (!skb_queue_empty(&pch->file.xq) ||
+		    !chan->ops->start_xmit(chan, frag))
+			skb_queue_tail(&pch->file.xq, frag);
+		pch->had_frag = 1;
+		p += flen;
+		len -= flen;
+		++ppp->nxseq;
+		bits = 0;
 		spin_unlock_bh(&pch->downl);
-	} while (len > 0);
+
+		if (--nbigger == 0 && fragsize > 0)
+			--fragsize;
+	}
 	ppp->nxchan = i;
 
 	return 1;
@@ -1369,7 +1412,7 @@ ppp_channel_push(struct channel *pch)
 
 	spin_lock_bh(&pch->downl);
 	if (pch->chan != 0) {
-		while (skb_queue_len(&pch->file.xq) > 0) {
+		while (!skb_queue_empty(&pch->file.xq)) {
 			skb = skb_dequeue(&pch->file.xq);
 			if (!pch->chan->ops->start_xmit(pch->chan, skb)) {
 				/* put the packet back and try again later */
@@ -1383,7 +1426,7 @@ ppp_channel_push(struct channel *pch)
 	}
 	spin_unlock_bh(&pch->downl);
 	/* see if there is anything from the attached unit to be sent */
-	if (skb_queue_len(&pch->file.xq) == 0) {
+	if (skb_queue_empty(&pch->file.xq)) {
 		read_lock_bh(&pch->upl);
 		ppp = pch->ppp;
 		if (ppp != 0)
@@ -1422,7 +1465,7 @@ ppp_input(struct ppp_channel *chan, stru
 		kfree_skb(skb);
 		return;
 	}
-	
+
 	proto = PPP_PROTO(skb);
 	read_lock_bh(&pch->upl);
 	if (pch->ppp == 0 || proto >= 0xc000 || proto == PPP_CCPFRAG) {
@@ -1691,7 +1734,7 @@ ppp_receive_mp_frame(struct ppp *ppp, st
 	struct list_head *l;
 	int mphdrlen = (ppp->flags & SC_MP_SHORTSEQ)? MPHDRLEN_SSN: MPHDRLEN;
 
-	if (!pskb_may_pull(skb, mphdrlen + 1) || ppp->mrru == 0)
+	if (!pskb_may_pull(skb, mphdrlen) || ppp->mrru == 0)
 		goto err;		/* no good, throw it away */
 
 	/* Decode sequence number and begin/end bits */
@@ -2611,8 +2654,8 @@ static void __exit ppp_cleanup(void)
 	if (unregister_chrdev(PPP_MAJOR, "ppp") != 0)
 		printk(KERN_ERR "PPP: failed to unregister PPP device\n");
 	devfs_remove("ppp");
-	class_simple_device_remove(MKDEV(PPP_MAJOR, 0));
-	class_simple_destroy(ppp_class);
+	class_device_destroy(ppp_class, MKDEV(PPP_MAJOR, 0));
+	class_destroy(ppp_class);
 }
 
 /*
diff --git a/drivers/net/ppp_synctty.c b/drivers/net/ppp_synctty.c
--- a/drivers/net/ppp_synctty.c
+++ b/drivers/net/ppp_synctty.c
@@ -406,7 +406,7 @@ ppp_sync_receive(struct tty_struct *tty,
 	spin_lock_irqsave(&ap->recv_lock, flags);
 	ppp_sync_input(ap, buf, cflags, count);
 	spin_unlock_irqrestore(&ap->recv_lock, flags);
-	if (skb_queue_len(&ap->rqueue))
+	if (!skb_queue_empty(&ap->rqueue))
 		tasklet_schedule(&ap->tsk);
 	sp_put(ap);
 	if (test_and_clear_bit(TTY_THROTTLED, &tty->flags)
@@ -793,7 +793,7 @@ err:
 static void __exit
 ppp_sync_cleanup(void)
 {
-	if (tty_register_ldisc(N_SYNC_PPP, NULL) != 0)
+	if (tty_unregister_ldisc(N_SYNC_PPP) != 0)
 		printk(KERN_ERR "failed to unregister Sync PPP line discipline\n");
 }
 
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -69,7 +69,13 @@ VERSION 2.2LK	<2005/01/25>
 #include <asm/io.h>
 #include <asm/irq.h>
 
-#define RTL8169_VERSION "2.2LK"
+#ifdef CONFIG_R8169_NAPI
+#define NAPI_SUFFIX	"-NAPI"
+#else
+#define NAPI_SUFFIX	""
+#endif
+
+#define RTL8169_VERSION "2.2LK" NAPI_SUFFIX
 #define MODULENAME "r8169"
 #define PFX MODULENAME ": "
 
@@ -85,6 +91,10 @@ VERSION 2.2LK	<2005/01/25>
 #define dprintk(fmt, args...)	do {} while (0)
 #endif /* RTL8169_DEBUG */
 
+#define R8169_MSG_DEFAULT \
+	(NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK | NETIF_MSG_IFUP | \
+	 NETIF_MSG_IFDOWN)
+
 #define TX_BUFFS_AVAIL(tp) \
 	(tp->dirty_tx + NUM_TX_DESC - tp->cur_tx - 1)
 
@@ -174,8 +184,9 @@ const static struct {
 #undef _R
 
 static struct pci_device_id rtl8169_pci_tbl[] = {
-	{0x10ec, 0x8169, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{0x1186, 0x4300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK,	0x8169), },
+	{ PCI_DEVICE(PCI_VENDOR_ID_DLINK,	0x4300), },
+	{ PCI_DEVICE(0x16ec,			0x0116), },
 	{0,},
 };
 
@@ -183,10 +194,15 @@ MODULE_DEVICE_TABLE(pci, rtl8169_pci_tbl
 
 static int rx_copybreak = 200;
 static int use_dac;
+static struct {
+	u32 msg_enable;
+} debug = { -1 };
 
 enum RTL8169_registers {
 	MAC0 = 0,		/* Ethernet hardware address. */
 	MAR0 = 8,		/* Multicast filter. */
+	CounterAddrLow = 0x10,
+	CounterAddrHigh = 0x14,
 	TxDescStartAddrLow = 0x20,
 	TxDescStartAddrHigh = 0x24,
 	TxHDescStartAddrLow = 0x28,
@@ -328,6 +344,9 @@ enum RTL8169_register_content {
 
 	/* _TBICSRBit */
 	TBILinkOK = 0x02000000,
+
+	/* DumpCounterCommand */
+	CounterDump = 0x8,
 };
 
 enum _DescStatusBit {
@@ -385,6 +404,7 @@ struct rtl8169_private {
 	struct pci_dev *pci_dev;	/* Index of PCI device */
 	struct net_device_stats stats;	/* statistics of net device */
 	spinlock_t lock;		/* spin lock flag */
+	u32 msg_enable;
 	int chipset;
 	int mac_version;
 	int phy_version;
@@ -418,9 +438,13 @@ struct rtl8169_private {
 MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@vger.kernel.org>");
 MODULE_DESCRIPTION("RealTek RTL-8169 Gigabit Ethernet driver");
 module_param_array(media, int, &num_media, 0);
+MODULE_PARM_DESC(media, "force phy operation. Deprecated by ethtool (8).");
 module_param(rx_copybreak, int, 0);
+MODULE_PARM_DESC(rx_copybreak, "Copy breakpoint for copy-only-tiny-frames");
 module_param(use_dac, int, 0);
 MODULE_PARM_DESC(use_dac, "Enable PCI DAC. Unsafe on 32 bit PCI slot.");
+module_param_named(debug, debug.msg_enable, int, 0);
+MODULE_PARM_DESC(debug, "Debug verbosity level (0=none, ..., 16=all)");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(RTL8169_VERSION);
 
@@ -433,10 +457,10 @@ static void rtl8169_hw_start(struct net_
 static int rtl8169_close(struct net_device *dev);
 static void rtl8169_set_rx_mode(struct net_device *dev);
 static void rtl8169_tx_timeout(struct net_device *dev);
-static struct net_device_stats *rtl8169_get_stats(struct net_device *netdev);
+static struct net_device_stats *rtl8169_get_stats(struct net_device *dev);
 static int rtl8169_rx_interrupt(struct net_device *, struct rtl8169_private *,
 				void __iomem *);
-static int rtl8169_change_mtu(struct net_device *netdev, int new_mtu);
+static int rtl8169_change_mtu(struct net_device *dev, int new_mtu);
 static void rtl8169_down(struct net_device *dev);
 
 #ifdef CONFIG_R8169_NAPI
@@ -543,9 +567,13 @@ static void rtl8169_check_link_status(st
 	spin_lock_irqsave(&tp->lock, flags);
 	if (tp->link_ok(ioaddr)) {
 		netif_carrier_on(dev);
-		printk(KERN_INFO PFX "%s: link up\n", dev->name);
-	} else
+		if (netif_msg_ifup(tp))
+			printk(KERN_INFO PFX "%s: link up\n", dev->name);
+	} else {
+		if (netif_msg_ifdown(tp))
+			printk(KERN_INFO PFX "%s: link down\n", dev->name);
 		netif_carrier_off(dev);
+	}
 	spin_unlock_irqrestore(&tp->lock, flags);
 }
 
@@ -569,7 +597,7 @@ static void rtl8169_link_option(int idx,
 	
 	option = ((idx < MAX_UNITS) && (idx >= 0)) ? media[idx] : 0xff;
 
-	if ((option != 0xff) && !idx)
+	if ((option != 0xff) && !idx && netif_msg_drv(&debug))
 		printk(KERN_WARNING PFX "media option is deprecated.\n");
 
 	for (p = link_settings; p->media != 0xff; p++) {
@@ -611,9 +639,11 @@ static int rtl8169_set_speed_tbi(struct 
 	} else if (autoneg == AUTONEG_ENABLE)
 		RTL_W32(TBICSR, reg | TBINwEnable | TBINwRestart);
 	else {
-		printk(KERN_WARNING PFX
-		       "%s: incorrect speed setting refused in TBI mode\n",
-		       dev->name);
+		if (netif_msg_link(tp)) {
+			printk(KERN_WARNING "%s: "
+			       "incorrect speed setting refused in TBI mode\n",
+			       dev->name);
+		}
 		ret = -EOPNOTSUPP;
 	}
 
@@ -871,12 +901,120 @@ static void rtl8169_get_regs(struct net_
         spin_unlock_irqrestore(&tp->lock, flags);
 }
 
+static u32 rtl8169_get_msglevel(struct net_device *dev)
+{
+	struct rtl8169_private *tp = netdev_priv(dev);
+
+	return tp->msg_enable;
+}
+
+static void rtl8169_set_msglevel(struct net_device *dev, u32 value)
+{
+	struct rtl8169_private *tp = netdev_priv(dev);
+
+	tp->msg_enable = value;
+}
+
+static const char rtl8169_gstrings[][ETH_GSTRING_LEN] = {
+	"tx_packets",
+	"rx_packets",
+	"tx_errors",
+	"rx_errors",
+	"rx_missed",
+	"align_errors",
+	"tx_single_collisions",
+	"tx_multi_collisions",
+	"unicast",
+	"broadcast",
+	"multicast",
+	"tx_aborted",
+	"tx_underrun",
+};
+
+struct rtl8169_counters {
+	u64	tx_packets;
+	u64	rx_packets;
+	u64	tx_errors;
+	u32	rx_errors;
+	u16	rx_missed;
+	u16	align_errors;
+	u32	tx_one_collision;
+	u32	tx_multi_collision;
+	u64	rx_unicast;
+	u64	rx_broadcast;
+	u32	rx_multicast;
+	u16	tx_aborted;
+	u16	tx_underun;
+};
+
+static int rtl8169_get_stats_count(struct net_device *dev)
+{
+	return ARRAY_SIZE(rtl8169_gstrings);
+}
+
+static void rtl8169_get_ethtool_stats(struct net_device *dev,
+				      struct ethtool_stats *stats, u64 *data)
+{
+	struct rtl8169_private *tp = netdev_priv(dev);
+	void __iomem *ioaddr = tp->mmio_addr;
+	struct rtl8169_counters *counters;
+	dma_addr_t paddr;
+	u32 cmd;
+
+	ASSERT_RTNL();
+
+	counters = pci_alloc_consistent(tp->pci_dev, sizeof(*counters), &paddr);
+	if (!counters)
+		return;
+
+	RTL_W32(CounterAddrHigh, (u64)paddr >> 32);
+	cmd = (u64)paddr & DMA_32BIT_MASK;
+	RTL_W32(CounterAddrLow, cmd);
+	RTL_W32(CounterAddrLow, cmd | CounterDump);
+
+	while (RTL_R32(CounterAddrLow) & CounterDump) {
+		if (msleep_interruptible(1))
+			break;
+	}
+
+	RTL_W32(CounterAddrLow, 0);
+	RTL_W32(CounterAddrHigh, 0);
+
+	data[0]	= le64_to_cpu(counters->tx_packets);
+	data[1] = le64_to_cpu(counters->rx_packets);
+	data[2] = le64_to_cpu(counters->tx_errors);
+	data[3] = le32_to_cpu(counters->rx_errors);
+	data[4] = le16_to_cpu(counters->rx_missed);
+	data[5] = le16_to_cpu(counters->align_errors);
+	data[6] = le32_to_cpu(counters->tx_one_collision);
+	data[7] = le32_to_cpu(counters->tx_multi_collision);
+	data[8] = le64_to_cpu(counters->rx_unicast);
+	data[9] = le64_to_cpu(counters->rx_broadcast);
+	data[10] = le32_to_cpu(counters->rx_multicast);
+	data[11] = le16_to_cpu(counters->tx_aborted);
+	data[12] = le16_to_cpu(counters->tx_underun);
+
+	pci_free_consistent(tp->pci_dev, sizeof(*counters), counters, paddr);
+}
+
+static void rtl8169_get_strings(struct net_device *dev, u32 stringset, u8 *data)
+{
+	switch(stringset) {
+	case ETH_SS_STATS:
+		memcpy(data, *rtl8169_gstrings, sizeof(rtl8169_gstrings));
+		break;
+	}
+}
+
+
 static struct ethtool_ops rtl8169_ethtool_ops = {
 	.get_drvinfo		= rtl8169_get_drvinfo,
 	.get_regs_len		= rtl8169_get_regs_len,
 	.get_link		= ethtool_op_get_link,
 	.get_settings		= rtl8169_get_settings,
 	.set_settings		= rtl8169_set_settings,
+	.get_msglevel		= rtl8169_get_msglevel,
+	.set_msglevel		= rtl8169_set_msglevel,
 	.get_rx_csum		= rtl8169_get_rx_csum,
 	.set_rx_csum		= rtl8169_set_rx_csum,
 	.get_tx_csum		= ethtool_op_get_tx_csum,
@@ -886,6 +1024,9 @@ static struct ethtool_ops rtl8169_ethtoo
 	.get_tso		= ethtool_op_get_tso,
 	.set_tso		= ethtool_op_set_tso,
 	.get_regs		= rtl8169_get_regs,
+	.get_strings		= rtl8169_get_strings,
+	.get_stats_count	= rtl8169_get_stats_count,
+	.get_ethtool_stats	= rtl8169_get_ethtool_stats,
 };
 
 static void rtl8169_write_gmii_reg_bit(void __iomem *ioaddr, int reg, int bitnum,
@@ -1091,7 +1232,8 @@ static void rtl8169_phy_timer(unsigned l
 	if (tp->link_ok(ioaddr))
 		goto out_unlock;
 
-	printk(KERN_WARNING PFX "%s: PHY reset until link up\n", dev->name);
+	if (netif_msg_link(tp))
+		printk(KERN_WARNING "%s: PHY reset until link up\n", dev->name);
 
 	tp->phy_reset_enable(ioaddr);
 
@@ -1169,18 +1311,23 @@ rtl8169_init_board(struct pci_dev *pdev,
 	/* dev zeroed in alloc_etherdev */
 	dev = alloc_etherdev(sizeof (*tp));
 	if (dev == NULL) {
-		printk(KERN_ERR PFX "unable to alloc new ethernet\n");
+		if (netif_msg_drv(&debug))
+			printk(KERN_ERR PFX "unable to alloc new ethernet\n");
 		goto err_out;
 	}
 
 	SET_MODULE_OWNER(dev);
 	SET_NETDEV_DEV(dev, &pdev->dev);
 	tp = netdev_priv(dev);
+	tp->msg_enable = netif_msg_init(debug.msg_enable, R8169_MSG_DEFAULT);
 
 	/* enable device (incl. PCI PM wakeup and hotplug setup) */
 	rc = pci_enable_device(pdev);
-	if (rc) {
-		printk(KERN_ERR PFX "%s: enable failure\n", pci_name(pdev));
+	if (rc < 0) {
+		if (netif_msg_probe(tp)) {
+			printk(KERN_ERR PFX "%s: enable failure\n",
+			       pci_name(pdev));
+		}
 		goto err_out_free_dev;
 	}
 
@@ -1196,29 +1343,39 @@ rtl8169_init_board(struct pci_dev *pdev,
 		pci_read_config_word(pdev, pm_cap + PCI_PM_CTRL, &pwr_command);
 		acpi_idle_state = pwr_command & PCI_PM_CTRL_STATE_MASK;
 	} else {
-		printk(KERN_ERR PFX
-		       "Cannot find PowerManagement capability, aborting.\n");
+		if (netif_msg_probe(tp)) {
+			printk(KERN_ERR PFX
+			       "Cannot find PowerManagement capability. "
+			       "Aborting.\n");
+		}
 		goto err_out_mwi;
 	}
 
 	/* make sure PCI base addr 1 is MMIO */
 	if (!(pci_resource_flags(pdev, 1) & IORESOURCE_MEM)) {
-		printk(KERN_ERR PFX
-		       "region #1 not an MMIO resource, aborting\n");
+		if (netif_msg_probe(tp)) {
+			printk(KERN_ERR PFX
+			       "region #1 not an MMIO resource, aborting\n");
+		}
 		rc = -ENODEV;
 		goto err_out_mwi;
 	}
 	/* check for weird/broken PCI region reporting */
 	if (pci_resource_len(pdev, 1) < R8169_REGS_SIZE) {
-		printk(KERN_ERR PFX "Invalid PCI region size(s), aborting\n");
+		if (netif_msg_probe(tp)) {
+			printk(KERN_ERR PFX
+			       "Invalid PCI region size(s), aborting\n");
+		}
 		rc = -ENODEV;
 		goto err_out_mwi;
 	}
 
 	rc = pci_request_regions(pdev, MODULENAME);
-	if (rc) {
-		printk(KERN_ERR PFX "%s: could not request regions.\n",
-		       pci_name(pdev));
+	if (rc < 0) {
+		if (netif_msg_probe(tp)) {
+			printk(KERN_ERR PFX "%s: could not request regions.\n",
+			       pci_name(pdev));
+		}
 		goto err_out_mwi;
 	}
 
@@ -1231,7 +1388,10 @@ rtl8169_init_board(struct pci_dev *pdev,
 	} else {
 		rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
 		if (rc < 0) {
-			printk(KERN_ERR PFX "DMA configuration failed.\n");
+			if (netif_msg_probe(tp)) {
+				printk(KERN_ERR PFX
+				       "DMA configuration failed.\n");
+			}
 			goto err_out_free_res;
 		}
 	}
@@ -1241,7 +1401,8 @@ rtl8169_init_board(struct pci_dev *pdev,
 	/* ioremap MMIO region */
 	ioaddr = ioremap(pci_resource_start(pdev, 1), R8169_REGS_SIZE);
 	if (ioaddr == NULL) {
-		printk(KERN_ERR PFX "cannot remap MMIO, aborting\n");
+		if (netif_msg_probe(tp))
+			printk(KERN_ERR PFX "cannot remap MMIO, aborting\n");
 		rc = -EIO;
 		goto err_out_free_res;
 	}
@@ -1272,9 +1433,11 @@ rtl8169_init_board(struct pci_dev *pdev,
 	}
 	if (i < 0) {
 		/* Unknown chip: assume array element #0, original RTL-8169 */
-		printk(KERN_DEBUG PFX
-		       "PCI device %s: unknown chip version, assuming %s\n",
-		       pci_name(pdev), rtl_chip_info[0].name);
+		if (netif_msg_probe(tp)) {
+			printk(KERN_DEBUG PFX "PCI device %s: "
+			       "unknown chip version, assuming %s\n",
+			       pci_name(pdev), rtl_chip_info[0].name);
+		}
 		i++;
 	}
 	tp->chipset = i;
@@ -1308,7 +1471,6 @@ rtl8169_init_one(struct pci_dev *pdev, c
 	struct rtl8169_private *tp;
 	void __iomem *ioaddr = NULL;
 	static int board_idx = -1;
-	static int printed_version = 0;
 	u8 autoneg, duplex;
 	u16 speed;
 	int i, rc;
@@ -1318,10 +1480,9 @@ rtl8169_init_one(struct pci_dev *pdev, c
 
 	board_idx++;
 
-	if (!printed_version) {
+	if (netif_msg_drv(&debug)) {
 		printk(KERN_INFO "%s Gigabit Ethernet driver %s loaded\n",
 		       MODULENAME, RTL8169_VERSION);
-		printed_version = 1;
 	}
 
 	rc = rtl8169_init_board(pdev, &dev, &ioaddr);
@@ -1366,7 +1527,6 @@ rtl8169_init_one(struct pci_dev *pdev, c
 #ifdef CONFIG_R8169_NAPI
 	dev->poll = rtl8169_poll;
 	dev->weight = R8169_NAPI_WEIGHT;
-	printk(KERN_INFO PFX "NAPI enabled\n");
 #endif
 
 #ifdef CONFIG_R8169_VLAN
@@ -1391,20 +1551,24 @@ rtl8169_init_one(struct pci_dev *pdev, c
 		return rc;
 	}
 
-	printk(KERN_DEBUG "%s: Identified chip type is '%s'.\n", dev->name,
-	       rtl_chip_info[tp->chipset].name);
+	if (netif_msg_probe(tp)) {
+		printk(KERN_DEBUG "%s: Identified chip type is '%s'.\n",
+		       dev->name, rtl_chip_info[tp->chipset].name);
+	}
 
 	pci_set_drvdata(pdev, dev);
 
-	printk(KERN_INFO "%s: %s at 0x%lx, "
-	       "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x, "
-	       "IRQ %d\n",
-	       dev->name,
-	       rtl_chip_info[ent->driver_data].name,
-	       dev->base_addr,
-	       dev->dev_addr[0], dev->dev_addr[1],
-	       dev->dev_addr[2], dev->dev_addr[3],
-	       dev->dev_addr[4], dev->dev_addr[5], dev->irq);
+	if (netif_msg_probe(tp)) {
+		printk(KERN_INFO "%s: %s at 0x%lx, "
+		       "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x, "
+		       "IRQ %d\n",
+		       dev->name,
+		       rtl_chip_info[ent->driver_data].name,
+		       dev->base_addr,
+		       dev->dev_addr[0], dev->dev_addr[1],
+		       dev->dev_addr[2], dev->dev_addr[3],
+		       dev->dev_addr[4], dev->dev_addr[5], dev->irq);
+	}
 
 	rtl8169_hw_phy_config(dev);
 
@@ -1427,7 +1591,7 @@ rtl8169_init_one(struct pci_dev *pdev, c
 
 	rtl8169_set_speed(dev, autoneg, speed, duplex);
 	
-	if (RTL_R8(PHYstatus) & TBI_Enable)
+	if ((RTL_R8(PHYstatus) & TBI_Enable) && netif_msg_link(tp))
 		printk(KERN_INFO PFX "%s: TBI auto-negotiating\n", dev->name);
 
 	return 0;
@@ -1712,7 +1876,7 @@ static int rtl8169_alloc_rx_skb(struct p
 	skb_reserve(skb, NET_IP_ALIGN);
 	*sk_buff = skb;
 
-	mapping = pci_map_single(pdev, skb->tail, rx_buf_sz,
+	mapping = pci_map_single(pdev, skb->data, rx_buf_sz,
 				 PCI_DMA_FROMDEVICE);
 
 	rtl8169_map_to_asic(desc, mapping, rx_buf_sz);
@@ -1860,8 +2024,13 @@ static void rtl8169_reinit_task(void *_d
 	ret = rtl8169_open(dev);
 	if (unlikely(ret < 0)) {
 		if (net_ratelimit()) {
-			printk(PFX KERN_ERR "%s: reinit failure (status = %d)."
-			       " Rescheduling.\n", dev->name, ret);
+			struct rtl8169_private *tp = netdev_priv(dev);
+
+			if (netif_msg_drv(tp)) {
+				printk(PFX KERN_ERR
+				       "%s: reinit failure (status = %d)."
+				       " Rescheduling.\n", dev->name, ret);
+			}
 		}
 		rtl8169_schedule_work(dev, rtl8169_reinit_task);
 	}
@@ -1886,8 +2055,12 @@ static void rtl8169_reset_task(void *_da
 		netif_wake_queue(dev);
 	} else {
 		if (net_ratelimit()) {
-			printk(PFX KERN_EMERG "%s: Rx buffers shortage\n",
-			       dev->name);
+			struct rtl8169_private *tp = netdev_priv(dev);
+
+			if (netif_msg_intr(tp)) {
+				printk(PFX KERN_EMERG
+				       "%s: Rx buffers shortage\n", dev->name);
+			}
 		}
 		rtl8169_schedule_work(dev, rtl8169_reset_task);
 	}
@@ -1973,8 +2146,11 @@ static int rtl8169_start_xmit(struct sk_
 	int ret = 0;
 	
 	if (unlikely(TX_BUFFS_AVAIL(tp) < skb_shinfo(skb)->nr_frags)) {
-		printk(KERN_ERR PFX "%s: BUG! Tx Ring full when queue awake!\n",
-		       dev->name);
+		if (netif_msg_drv(tp)) {
+			printk(KERN_ERR
+			       "%s: BUG! Tx Ring full when queue awake!\n",
+			       dev->name);
+		}
 		goto err_stop;
 	}
 
@@ -2049,8 +2225,11 @@ static void rtl8169_pcierr_interrupt(str
 	pci_read_config_word(pdev, PCI_COMMAND, &pci_cmd);
 	pci_read_config_word(pdev, PCI_STATUS, &pci_status);
 
-	printk(KERN_ERR PFX "%s: PCI error (cmd = 0x%04x, status = 0x%04x).\n",
-	       dev->name, pci_cmd, pci_status);
+	if (netif_msg_intr(tp)) {
+		printk(KERN_ERR
+		       "%s: PCI error (cmd = 0x%04x, status = 0x%04x).\n",
+		       dev->name, pci_cmd, pci_status);
+	}
 
 	/*
 	 * The recovery sequence below admits a very elaborated explanation:
@@ -2069,7 +2248,8 @@ static void rtl8169_pcierr_interrupt(str
 
 	/* The infamous DAC f*ckup only happens at boot time */
 	if ((tp->cp_cmd & PCIDAC) && !tp->dirty_rx && !tp->cur_rx) {
-		printk(KERN_INFO PFX "%s: disabling PCI DAC.\n", dev->name);
+		if (netif_msg_intr(tp))
+			printk(KERN_INFO "%s: disabling PCI DAC.\n", dev->name);
 		tp->cp_cmd &= ~PCIDAC;
 		RTL_W16(CPlusCmd, tp->cp_cmd);
 		dev->features &= ~NETIF_F_HIGHDMA;
@@ -2156,7 +2336,7 @@ static inline int rtl8169_try_rx_copy(st
 		skb = dev_alloc_skb(pkt_size + NET_IP_ALIGN);
 		if (skb) {
 			skb_reserve(skb, NET_IP_ALIGN);
-			eth_copy_and_sum(skb, sk_buff[0]->tail, pkt_size, 0);
+			eth_copy_and_sum(skb, sk_buff[0]->data, pkt_size, 0);
 			*sk_buff = skb;
 			rtl8169_mark_to_asic(desc, rx_buf_sz);
 			ret = 0;
@@ -2180,7 +2360,7 @@ rtl8169_rx_interrupt(struct net_device *
 	rx_left = NUM_RX_DESC + tp->dirty_rx - cur_rx;
 	rx_left = rtl8169_rx_quota(rx_left, (u32) dev->quota);
 
-	while (rx_left > 0) {
+	for (; rx_left > 0; rx_left--, cur_rx++) {
 		unsigned int entry = cur_rx % NUM_RX_DESC;
 		struct RxDesc *desc = tp->RxDescArray + entry;
 		u32 status;
@@ -2190,9 +2370,12 @@ rtl8169_rx_interrupt(struct net_device *
 
 		if (status & DescOwn)
 			break;
-		if (status & RxRES) {
-			printk(KERN_INFO "%s: Rx ERROR. status = %08x\n",
-			       dev->name, status);
+		if (unlikely(status & RxRES)) {
+			if (netif_msg_rx_err(tp)) {
+				printk(KERN_INFO
+				       "%s: Rx ERROR. status = %08x\n",
+				       dev->name, status);
+			}
 			tp->stats.rx_errors++;
 			if (status & (RxRWT | RxRUNT))
 				tp->stats.rx_length_errors++;
@@ -2214,7 +2397,7 @@ rtl8169_rx_interrupt(struct net_device *
 				tp->stats.rx_dropped++;
 				tp->stats.rx_length_errors++;
 				rtl8169_mark_to_asic(desc, tp->rx_buf_sz);
-				goto move_on;
+				continue;
 			}
 
 			rtl8169_rx_csum(skb, desc);
@@ -2243,16 +2426,13 @@ rtl8169_rx_interrupt(struct net_device *
 			tp->stats.rx_bytes += pkt_size;
 			tp->stats.rx_packets++;
 		}
-move_on:		
-		cur_rx++; 
-		rx_left--;
 	}
 
 	count = cur_rx - tp->cur_rx;
 	tp->cur_rx = cur_rx;
 
 	delta = rtl8169_rx_fill(tp, dev, tp->dirty_rx, tp->cur_rx);
-	if (!delta && count)
+	if (!delta && count && netif_msg_intr(tp))
 		printk(KERN_INFO "%s: no Rx buffer allocated\n", dev->name);
 	tp->dirty_rx += delta;
 
@@ -2263,7 +2443,7 @@ move_on:		
 	 *   after refill ?
 	 * - how do others driver handle this condition (Uh oh...).
 	 */
-	if (tp->dirty_rx + NUM_RX_DESC == tp->cur_rx)
+	if ((tp->dirty_rx + NUM_RX_DESC == tp->cur_rx) && netif_msg_intr(tp))
 		printk(KERN_EMERG "%s: Rx buffers exhausted\n", dev->name);
 
 	return count;
@@ -2315,7 +2495,7 @@ rtl8169_interrupt(int irq, void *dev_ins
 
 		if (likely(netif_rx_schedule_prep(dev)))
 			__netif_rx_schedule(dev);
-		else {
+		else if (netif_msg_intr(tp)) {
 			printk(KERN_INFO "%s: interrupt %04x taken in poll\n",
 			       dev->name, status);	
 		}
@@ -2334,8 +2514,10 @@ rtl8169_interrupt(int irq, void *dev_ins
 	} while (boguscnt > 0);
 
 	if (boguscnt <= 0) {
-		printk(KERN_WARNING "%s: Too much work at interrupt!\n",
-		       dev->name);
+		if (net_ratelimit() && netif_msg_intr(tp)) {
+			printk(KERN_WARNING
+			       "%s: Too much work at interrupt!\n", dev->name);
+		}
 		/* Clear all interrupt sources. */
 		RTL_W16(IntrStatus, 0xffff);
 	}
@@ -2458,8 +2640,10 @@ rtl8169_set_rx_mode(struct net_device *d
 
 	if (dev->flags & IFF_PROMISC) {
 		/* Unconditionally log net taps. */
-		printk(KERN_NOTICE "%s: Promiscuous mode enabled.\n",
-		       dev->name);
+		if (netif_msg_link(tp)) {
+			printk(KERN_NOTICE "%s: Promiscuous mode enabled.\n",
+			       dev->name);
+		}
 		rx_mode =
 		    AcceptBroadcast | AcceptMulticast | AcceptMyPhys |
 		    AcceptAllPhys;
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -42,6 +42,7 @@
 #include <linux/errno.h>
 #include <linux/ioport.h>
 #include <linux/pci.h>
+#include <linux/dma-mapping.h>
 #include <linux/kernel.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
@@ -1698,11 +1699,9 @@ static int fill_rx_buffers(struct s2io_n
 #else
 		ba = &nic->ba[ring_no][block_no][off];
 		skb_reserve(skb, BUF0_LEN);
-		tmp = (unsigned long) skb->data;
-		tmp += ALIGN_SIZE;
-		tmp &= ~ALIGN_SIZE;
-		skb->data = (void *) tmp;
-		skb->tail = (void *) tmp;
+		tmp = ((unsigned long) skb->data & ALIGN_SIZE);
+		if (tmp)
+			skb_reserve(skb, (ALIGN_SIZE + 1) - tmp);
 
 		memset(rxdp, 0, sizeof(RxD_t));
 		rxdp->Buffer2_ptr = pci_map_single
@@ -4593,19 +4592,19 @@ s2io_init_nic(struct pci_dev *pdev, cons
 		return ret;
 	}
 
-	if (!pci_set_dma_mask(pdev, 0xffffffffffffffffULL)) {
+	if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
 		DBG_PRINT(INIT_DBG, "s2io_init_nic: Using 64bit DMA\n");
 		dma_flag = TRUE;
 
 		if (pci_set_consistent_dma_mask
-		    (pdev, 0xffffffffffffffffULL)) {
+		    (pdev, DMA_64BIT_MASK)) {
 			DBG_PRINT(ERR_DBG,
 				  "Unable to obtain 64bit DMA for \
 					consistent allocations\n");
 			pci_disable_device(pdev);
 			return -ENOMEM;
 		}
-	} else if (!pci_set_dma_mask(pdev, 0xffffffffUL)) {
+	} else if (!pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
 		DBG_PRINT(INIT_DBG, "s2io_init_nic: Using 32bit DMA\n");
 	} else {
 		pci_disable_device(pdev);
diff --git a/drivers/net/sb1000.c b/drivers/net/sb1000.c
--- a/drivers/net/sb1000.c
+++ b/drivers/net/sb1000.c
@@ -90,7 +90,6 @@ static int sb1000_close(struct net_devic
 
 
 /* SB1000 hardware routines to be used during open/configuration phases */
-static inline void nicedelay(unsigned long usecs);
 static inline int card_wait_for_busy_clear(const int ioaddr[],
 	const char* name);
 static inline int card_wait_for_ready(const int ioaddr[], const char* name,
@@ -254,13 +253,6 @@ static struct pnp_driver sb1000_driver =
 
 static const int TimeOutJiffies = (875 * HZ) / 100;
 
-static inline void nicedelay(unsigned long usecs)
-{
-	current->state = TASK_INTERRUPTIBLE;
-	schedule_timeout(HZ);
-	return;
-}
-
 /* Card Wait For Busy Clear (cannot be used during an interrupt) */
 static inline int
 card_wait_for_busy_clear(const int ioaddr[], const char* name)
@@ -475,7 +467,7 @@ sb1000_reset(const int ioaddr[], const c
 	udelay(1000);
 	outb(0x0, port);
 	inb(port);
-	nicedelay(60000);
+	ssleep(1);
 	outb(0x4, port);
 	inb(port);
 	udelay(1000);
@@ -537,7 +529,7 @@ sb1000_activate(const int ioaddr[], cons
 	const unsigned char Command0[6] = {0x80, 0x11, 0x00, 0x00, 0x00, 0x00};
 	const unsigned char Command1[6] = {0x80, 0x16, 0x00, 0x00, 0x00, 0x00};
 
-	nicedelay(50000);
+	ssleep(1);
 	if ((status = card_send_command(ioaddr, name, Command0, st)))
 		return status;
 	if ((status = card_send_command(ioaddr, name, Command1, st)))
@@ -944,7 +936,7 @@ sb1000_open(struct net_device *dev)
 	/* initialize sb1000 */
 	if ((status = sb1000_reset(ioaddr, name)))
 		return status;
-	nicedelay(200000);
+	ssleep(1);
 	if ((status = sb1000_check_CRC(ioaddr, name)))
 		return status;
 
diff --git a/drivers/net/sb1250-mac.c b/drivers/net/sb1250-mac.c
--- a/drivers/net/sb1250-mac.c
+++ b/drivers/net/sb1250-mac.c
@@ -963,11 +963,11 @@ static int sbdma_add_rcvbuffer(sbmacdma_
 	/*
 	 * Do not interrupt per DMA transfer.
 	 */
-	dsc->dscr_a = virt_to_phys(sb_new->tail) |
+	dsc->dscr_a = virt_to_phys(sb_new->data) |
 		V_DMA_DSCRA_A_SIZE(NUMCACHEBLKS(pktsize+ETHER_ALIGN)) |
 		0;
 #else
-	dsc->dscr_a = virt_to_phys(sb_new->tail) |
+	dsc->dscr_a = virt_to_phys(sb_new->data) |
 		V_DMA_DSCRA_A_SIZE(NUMCACHEBLKS(pktsize+ETHER_ALIGN)) |
 		M_DMA_DSCRA_INTERRUPT;
 #endif
diff --git a/drivers/net/shaper.c b/drivers/net/shaper.c
--- a/drivers/net/shaper.c
+++ b/drivers/net/shaper.c
@@ -135,10 +135,8 @@ static int shaper_start_xmit(struct sk_b
 {
 	struct shaper *shaper = dev->priv;
  	struct sk_buff *ptr;
-   
-	if (down_trylock(&shaper->sem))
-		return -1;
-
+  
+	spin_lock(&shaper->lock);
  	ptr=shaper->sendq.prev;
  	
  	/*
@@ -232,7 +230,7 @@ static int shaper_start_xmit(struct sk_b
                 shaper->stats.collisions++;
  	}
 	shaper_kick(shaper);
-	up(&shaper->sem);
+	spin_unlock(&shaper->lock);
  	return 0;
 }
 
@@ -271,11 +269,9 @@ static void shaper_timer(unsigned long d
 {
 	struct shaper *shaper = (struct shaper *)data;
 
-	if (!down_trylock(&shaper->sem)) {
-		shaper_kick(shaper);
-		up(&shaper->sem);
-	} else
-		mod_timer(&shaper->timer, jiffies);
+	spin_lock(&shaper->lock);
+	shaper_kick(shaper);
+	spin_unlock(&shaper->lock);
 }
 
 /*
@@ -332,21 +328,6 @@ static void shaper_kick(struct shaper *s
 
 
 /*
- *	Flush the shaper queues on a closedown
- */
- 
-static void shaper_flush(struct shaper *shaper)
-{
-	struct sk_buff *skb;
-
-	down(&shaper->sem);
-	while((skb=skb_dequeue(&shaper->sendq))!=NULL)
-		dev_kfree_skb(skb);
-	shaper_kick(shaper);
-	up(&shaper->sem);
-}
-
-/*
  *	Bring the interface up. We just disallow this until a 
  *	bind.
  */
@@ -375,7 +356,15 @@ static int shaper_open(struct net_device
 static int shaper_close(struct net_device *dev)
 {
 	struct shaper *shaper=dev->priv;
-	shaper_flush(shaper);
+	struct sk_buff *skb;
+
+	while ((skb = skb_dequeue(&shaper->sendq)) != NULL)
+		dev_kfree_skb(skb);
+
+	spin_lock_bh(&shaper->lock);
+	shaper_kick(shaper);
+	spin_unlock_bh(&shaper->lock);
+
 	del_timer_sync(&shaper->timer);
 	return 0;
 }
@@ -576,6 +565,7 @@ static void shaper_init_priv(struct net_
 	init_timer(&sh->timer);
 	sh->timer.function=shaper_timer;
 	sh->timer.data=(unsigned long)sh;
+	spin_lock_init(&sh->lock);
 }
 
 /*
diff --git a/drivers/net/sis900.c b/drivers/net/sis900.c
--- a/drivers/net/sis900.c
+++ b/drivers/net/sis900.c
@@ -66,6 +66,7 @@
 #include <linux/ethtool.h>
 #include <linux/crc32.h>
 #include <linux/bitops.h>
+#include <linux/dma-mapping.h>
 
 #include <asm/processor.h>      /* Processor type for cache alignment. */
 #include <asm/io.h>
@@ -93,8 +94,6 @@ static int sis900_debug = -1; /* Use SIS
 
 /* Time in jiffies before concluding the transmitter is hung. */
 #define TX_TIMEOUT  (4*HZ)
-/* SiS 900 is capable of 32 bits BM DMA */
-#define SIS900_DMA_MASK 0xffffffff
 
 enum {
 	SIS_900 = 0,
@@ -414,7 +413,7 @@ static int __devinit sis900_probe(struct
 	ret = pci_enable_device(pci_dev);
 	if(ret) return ret;
 	
-	i = pci_set_dma_mask(pci_dev, SIS900_DMA_MASK);
+	i = pci_set_dma_mask(pci_dev, DMA_32BIT_MASK);
 	if(i){
 		printk(KERN_ERR "sis900.c: architecture does not support"
 			"32bit PCI busmaster DMA\n");
@@ -1155,7 +1154,7 @@ sis900_init_rx_ring(struct net_device *n
 		sis_priv->rx_skbuff[i] = skb;
 		sis_priv->rx_ring[i].cmdsts = RX_BUF_SIZE;
                 sis_priv->rx_ring[i].bufptr = pci_map_single(sis_priv->pci_dev,
-                        skb->tail, RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
+                        skb->data, RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
 	}
 	sis_priv->dirty_rx = (unsigned int) (i - NUM_RX_DESC);
 
@@ -1777,7 +1776,7 @@ static int sis900_rx(struct net_device *
 			sis_priv->rx_skbuff[entry] = skb;
 			sis_priv->rx_ring[entry].cmdsts = RX_BUF_SIZE;
                 	sis_priv->rx_ring[entry].bufptr = 
-				pci_map_single(sis_priv->pci_dev, skb->tail, 
+				pci_map_single(sis_priv->pci_dev, skb->data, 
 					RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
 			sis_priv->dirty_rx++;
 		}
@@ -1810,7 +1809,7 @@ static int sis900_rx(struct net_device *
 			sis_priv->rx_skbuff[entry] = skb;
 			sis_priv->rx_ring[entry].cmdsts = RX_BUF_SIZE;
                 	sis_priv->rx_ring[entry].bufptr =
-				pci_map_single(sis_priv->pci_dev, skb->tail,
+				pci_map_single(sis_priv->pci_dev, skb->data,
 					RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
 		}
 	}
diff --git a/drivers/net/sk98lin/skge.c b/drivers/net/sk98lin/skge.c
--- a/drivers/net/sk98lin/skge.c
+++ b/drivers/net/sk98lin/skge.c
@@ -112,6 +112,7 @@
 #include	<linux/moduleparam.h>
 #include	<linux/init.h>
 #include 	<linux/proc_fs.h>
+#include	<linux/dma-mapping.h>
 
 #include	"h/skdrv1st.h"
 #include	"h/skdrv2nd.h"
@@ -4212,7 +4213,7 @@ SK_BOOL		DualNet;
 			Flags);
 
 		SkGeStopPort(pAC, IoC, FromPort, SK_STOP_ALL, SK_HARD_RST);
-		pAC->dev[Param.Para32[0]]->flags &= ~IFF_RUNNING;
+		netif_carrier_off(pAC->dev[Param.Para32[0]]);
 		spin_unlock_irqrestore(
 			&pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
 			Flags);
@@ -4355,7 +4356,7 @@ SK_BOOL		DualNet;
 		}
 
 		/* Inform the world that link protocol is up. */
-		pAC->dev[Param.Para32[0]]->flags |= IFF_RUNNING;
+		netif_carrier_on(pAC->dev[Param.Para32[0]]);
 
 		break;
 	case SK_DRV_NET_DOWN:	 /* SK_U32 Reason */
@@ -4368,7 +4369,7 @@ SK_BOOL		DualNet;
 		} else {
 			DoPrintInterfaceChange = SK_TRUE;
 		}
-		pAC->dev[Param.Para32[1]]->flags &= ~IFF_RUNNING;
+		netif_carrier_off(pAC->dev[Param.Para32[1]]);
 		break;
 	case SK_DRV_SWITCH_HARD: /* SK_U32 FromPortIdx SK_U32 ToPortIdx */
 		SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
@@ -4912,8 +4913,8 @@ static int __devinit skge_probe_one(stru
 		goto out;
  
 	/* Configure DMA attributes. */
-	if (pci_set_dma_mask(pdev, (u64) 0xffffffffffffffffULL) &&
-	    pci_set_dma_mask(pdev, (u64) 0xffffffff))
+	if (pci_set_dma_mask(pdev, DMA_64BIT_MASK) &&
+	    pci_set_dma_mask(pdev, DMA_32BIT_MASK))
 		goto out_disable_device;
 
 
@@ -4961,7 +4962,6 @@ static int __devinit skge_probe_one(stru
 #ifdef CONFIG_NET_POLL_CONTROLLER
 	dev->poll_controller =	&SkGePollController;
 #endif
-	dev->flags &= 		~IFF_RUNNING;
 	SET_NETDEV_DEV(dev, &pdev->dev);
 	SET_ETHTOOL_OPS(dev, &SkGeEthtoolOps);
 
@@ -5035,7 +5035,6 @@ static int __devinit skge_probe_one(stru
 		dev->set_mac_address    = &SkGeSetMacAddr;
 		dev->do_ioctl           = &SkGeIoctl;
 		dev->change_mtu         = &SkGeChangeMtu;
-		dev->flags             &= ~IFF_RUNNING;
 		SET_NETDEV_DEV(dev, &pdev->dev);
 		SET_ETHTOOL_OPS(dev, &SkGeEthtoolOps);
 
@@ -5134,6 +5133,84 @@ static void __devexit skge_remove_one(st
 	kfree(pAC);
 }
 
+#ifdef CONFIG_PM
+static int skge_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+	struct net_device *dev = pci_get_drvdata(pdev);
+	DEV_NET *pNet = netdev_priv(dev);
+	SK_AC *pAC = pNet->pAC;
+	struct net_device *otherdev = pAC->dev[1];
+
+	if (netif_running(dev)) {
+		netif_carrier_off(dev);
+		DoPrintInterfaceChange = SK_FALSE;
+		SkDrvDeInitAdapter(pAC, 0);  /* performs SkGeClose */
+		netif_device_detach(dev);
+	}
+	if (otherdev != dev) {
+		if (netif_running(otherdev)) {
+			netif_carrier_off(otherdev);
+			DoPrintInterfaceChange = SK_FALSE;
+			SkDrvDeInitAdapter(pAC, 1);  /* performs SkGeClose */
+			netif_device_detach(otherdev);
+		}
+	}
+
+	pci_save_state(pdev);
+	pci_enable_wake(pdev, pci_choose_state(pdev, state), 0);
+	if (pAC->AllocFlag & SK_ALLOC_IRQ) {
+		free_irq(dev->irq, dev);
+	}
+	pci_disable_device(pdev);
+	pci_set_power_state(pdev, pci_choose_state(pdev, state));
+
+	return 0;
+}
+
+static int skge_resume(struct pci_dev *pdev)
+{
+	struct net_device *dev = pci_get_drvdata(pdev);
+	DEV_NET *pNet = netdev_priv(dev);
+	SK_AC *pAC = pNet->pAC;
+	struct net_device *otherdev = pAC->dev[1];
+	int ret;
+
+	pci_set_power_state(pdev, PCI_D0);
+	pci_restore_state(pdev);
+	pci_enable_device(pdev);
+	pci_set_master(pdev);
+	if (pAC->GIni.GIMacsFound == 2)
+		ret = request_irq(dev->irq, SkGeIsr, SA_SHIRQ, pAC->Name, dev);
+	else
+		ret = request_irq(dev->irq, SkGeIsrOnePort, SA_SHIRQ, pAC->Name, dev);
+	if (ret) {
+		printk(KERN_WARNING "sk98lin: unable to acquire IRQ %d\n", dev->irq);
+		pAC->AllocFlag &= ~SK_ALLOC_IRQ;
+		dev->irq = 0;
+		pci_disable_device(pdev);
+		return -EBUSY;
+	}
+
+	netif_device_attach(dev);
+	if (netif_running(dev)) {
+		DoPrintInterfaceChange = SK_FALSE;
+		SkDrvInitAdapter(pAC, 0);    /* first device  */
+	}
+	if (otherdev != dev) {
+		netif_device_attach(otherdev);
+		if (netif_running(otherdev)) {
+			DoPrintInterfaceChange = SK_FALSE;
+			SkDrvInitAdapter(pAC, 1);    /* second device  */
+		}
+	}
+
+	return 0;
+}
+#else
+#define skge_suspend NULL
+#define skge_resume NULL
+#endif
+
 static struct pci_device_id skge_pci_tbl[] = {
 	{ PCI_VENDOR_ID_3COM, 0x1700, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
 	{ PCI_VENDOR_ID_3COM, 0x80eb, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
@@ -5159,6 +5236,8 @@ static struct pci_driver skge_driver = {
 	.id_table	= skge_pci_tbl,
 	.probe		= skge_probe_one,
 	.remove		= __devexit_p(skge_remove_one),
+	.suspend	= skge_suspend,
+	.resume		= skge_resume,
 };
 
 static int __init skge_init(void)
diff --git a/drivers/net/sk98lin/skgeinit.c b/drivers/net/sk98lin/skgeinit.c
--- a/drivers/net/sk98lin/skgeinit.c
+++ b/drivers/net/sk98lin/skgeinit.c
@@ -2016,7 +2016,7 @@ SK_IOC	IoC)		/* IO context */
 	 * we set the PHY to coma mode and switch to D3 power state.
 	 */
 	if (pAC->GIni.GIYukonLite &&
-		pAC->GIni.GIChipRev == CHIP_REV_YU_LITE_A3) {
+		pAC->GIni.GIChipRev >= CHIP_REV_YU_LITE_A3) {
 
 		/* for all ports switch PHY to coma mode */
 		for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
diff --git a/drivers/net/sk98lin/skxmac2.c b/drivers/net/sk98lin/skxmac2.c
--- a/drivers/net/sk98lin/skxmac2.c
+++ b/drivers/net/sk98lin/skxmac2.c
@@ -1065,7 +1065,7 @@ int		Port)	/* Port Index (MAC_1 + n) */
 	
 	/* WA code for COMA mode */
 	if (pAC->GIni.GIYukonLite &&
-		pAC->GIni.GIChipRev == CHIP_REV_YU_LITE_A3) {
+		pAC->GIni.GIChipRev >= CHIP_REV_YU_LITE_A3) {
 		
 		SK_IN32(IoC, B2_GP_IO, &DWord);
 
@@ -1110,7 +1110,7 @@ int		Port)	/* Port Index (MAC_1 + n) */
 
 	/* WA code for COMA mode */
 	if (pAC->GIni.GIYukonLite &&
-		pAC->GIni.GIChipRev == CHIP_REV_YU_LITE_A3) {
+		pAC->GIni.GIChipRev >= CHIP_REV_YU_LITE_A3) {
 		
 		SK_IN32(IoC, B2_GP_IO, &DWord);
 
@@ -2126,7 +2126,7 @@ SK_U8	Mode)		/* low power mode */
 	int		Ret = 0;
 
 	if (pAC->GIni.GIYukonLite &&
-	    pAC->GIni.GIChipRev == CHIP_REV_YU_LITE_A3) {
+	    pAC->GIni.GIChipRev >= CHIP_REV_YU_LITE_A3) {
 
 		/* save current power mode */
 		LastMode = pAC->GIni.GP[Port].PPhyPowerState;
@@ -2253,7 +2253,7 @@ int		Port)		/* Port Index (e.g. MAC_1) *
 	int		Ret = 0;
 
 	if (pAC->GIni.GIYukonLite &&
-		pAC->GIni.GIChipRev == CHIP_REV_YU_LITE_A3) {
+		pAC->GIni.GIChipRev >= CHIP_REV_YU_LITE_A3) {
 
 		/* save current power mode */
 		LastMode = pAC->GIni.GP[Port].PPhyPowerState;
diff --git a/drivers/net/sk_g16.c b/drivers/net/sk_g16.c
deleted file mode 100644
--- a/drivers/net/sk_g16.c
+++ /dev/null
@@ -1,2066 +0,0 @@
-/*-
- * Copyright (C) 1994 by PJD Weichmann & SWS Bern, Switzerland
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- * Module         : sk_g16.c
- *
- * Version        : $Revision: 1.1 $
- *
- * Author         : Patrick J.D. Weichmann
- *
- * Date Created   : 94/05/26
- * Last Updated   : $Date: 1994/06/30 16:25:15 $
- *
- * Description    : Schneider & Koch G16 Ethernet Device Driver for
- *                  Linux Kernel >= 1.1.22
- * Update History :
- *                  Paul Gortmaker, 03/97: Fix for v2.1.x to use read{b,w}
- *                  write{b,w} and memcpy -> memcpy_{to,from}io
- *
- *		    Jeff Garzik, 06/2000, Modularize
- *
--*/
-
-static const char rcsid[] = "$Id: sk_g16.c,v 1.1 1994/06/30 16:25:15 root Exp $";
-
-/*
- * The Schneider & Koch (SK) G16 Network device driver is based
- * on the 'ni6510' driver from Michael Hipp which can be found at
- * ftp://sunsite.unc.edu/pub/Linux/system/Network/drivers/nidrivers.tar.gz
- * 
- * Sources: 1) ni6510.c by M. Hipp
- *          2) depca.c  by D.C. Davies
- *          3) skeleton.c by D. Becker
- *          4) Am7990 Local Area Network Controller for Ethernet (LANCE),
- *             AMD, Pub. #05698, June 1989
- *
- * Many Thanks for helping me to get things working to: 
- *                 
- *                 A. Cox (A.Cox@swansea.ac.uk)
- *                 M. Hipp (mhipp@student.uni-tuebingen.de)
- *                 R. Bolz (Schneider & Koch, Germany)
- *
- * To Do: 
- *        - Support of SK_G8 and other SK Network Cards.
- *        - Autoset memory mapped RAM. Check for free memory and then
- *          configure RAM correctly. 
- *        - SK_close should really set card in to initial state.
- *        - Test if IRQ 3 is not switched off. Use autoirq() functionality.
- *          (as in /drivers/net/skeleton.c)
- *        - Implement Multicast addressing. At minimum something like
- *          in depca.c. 
- *        - Redo the statistics part.
- *        - Try to find out if the board is in 8 Bit or 16 Bit slot.
- *          If in 8 Bit mode don't use IRQ 11.
- *        - (Try to make it slightly faster.) 
- *	  - Power management support
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/fcntl.h>
-#include <linux/ioport.h>
-#include <linux/interrupt.h>
-#include <linux/slab.h>
-#include <linux/string.h> 
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/spinlock.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/bitops.h>
-
-#include <asm/system.h>
-#include <asm/io.h>
-
-#include "sk_g16.h"
-
-/* 
- * Schneider & Koch Card Definitions 
- * =================================
- */  
-
-#define SK_NAME   "SK_G16"
-
-/*
- * SK_G16 Configuration
- * --------------------
- */ 
-
-/* 
- * Abbreviations
- * -------------
- *  
- * RAM - used for the 16KB shared memory 
- * Boot_ROM, ROM - are used for referencing the BootEPROM
- *
- * SK_BOOT_ROM and SK_ADDR are symbolic constants used to configure
- * the behaviour of the driver and the SK_G16.
- *
- * ! See sk_g16.install on how to install and configure the driver !   
- *
- * SK_BOOT_ROM defines if the Boot_ROM should be switched off or not.
- *
- * SK_ADDR defines the address where the RAM will be mapped into the real
- *         host memory.
- *         valid addresses are from 0xa0000 to 0xfc000 in 16Kbyte steps.
- */  
- 
-#define SK_BOOT_ROM     1              /* 1=BootROM on 0=off */
-
-#define SK_ADDR         0xcc000
-
-/* 
- * In POS3 are bits A14-A19 of the address bus. These bits can be set
- * to choose the RAM address. That's why we only can choose the RAM address
- * in 16KB steps.
- */
-
-#define POS_ADDR       (rom_addr>>14)  /* Do not change this line */
-
-/* 
- * SK_G16 I/O PORT's + IRQ's + Boot_ROM locations
- * ----------------------------------------------
- */
-
-/* 
- * As nearly every card has also SK_G16 a specified I/O Port region and
- * only a few possible IRQ's.
- * In the Installation Guide from Schneider & Koch is listed a possible
- * Interrupt IRQ2. IRQ2 is always IRQ9 in boards with two cascaded interrupt
- * controllers. So we use in SK_IRQS IRQ9.
- */
-
-/* Don't touch any of the following #defines. */
-
-#define SK_IO_PORTS     { 0x100, 0x180, 0x208, 0x220, 0x288, 0x320, 0x328, 0x390, 0 }
-
-#define SK_IRQS         { 3, 5, 9, 11, 0 }
-
-#define SK_BOOT_ROM_LOCATIONS { 0xc0000, 0xc4000, 0xc8000, 0xcc000, 0xd0000, 0xd4000, 0xd8000, 0xdc000, 0 }
-
-#define SK_BOOT_ROM_ID  { 0x55, 0xaa, 0x10, 0x50, 0x06, 0x33 }
-
-/* 
- * SK_G16 POS REGISTERS 
- * --------------------
- */
-
-/*
- * SK_G16 has a Programmable Option Select (POS) Register.
- * The POS is composed of 8 separate registers (POS0-7) which 
- * are I/O mapped on an address set by the W1 switch.                    
- *
- */
-
-#define SK_POS_SIZE 8           /* 8 I/O Ports are used by SK_G16 */
-
-#define SK_POS0     ioaddr      /* Card-ID Low (R) */
-#define SK_POS1     ioaddr+1    /* Card-ID High (R) */
-#define SK_POS2     ioaddr+2    /* Card-Enable, Boot-ROM Disable (RW) */
-#define SK_POS3     ioaddr+3    /* Base address of RAM */
-#define SK_POS4     ioaddr+4    /* IRQ */
-
-/* POS5 - POS7 are unused */
-
-/* 
- * SK_G16 MAC PREFIX 
- * -----------------
- */
-
-/* 
- * Scheider & Koch manufacturer code (00:00:a5).
- * This must be checked, that we are sure it is a SK card.
- */
-
-#define SK_MAC0         0x00
-#define SK_MAC1         0x00
-#define SK_MAC2         0x5a
-
-/* 
- * SK_G16 ID 
- * ---------
- */ 
-
-/* 
- * If POS0,POS1 contain the following ID, then we know
- * at which I/O Port Address we are. 
- */
-
-#define SK_IDLOW  0xfd 
-#define SK_IDHIGH 0x6a
-
-
-/* 
- * LANCE POS Bit definitions 
- * -------------------------
- */
-
-#define SK_ROM_RAM_ON  (POS2_CARD)
-#define SK_ROM_RAM_OFF (POS2_EPROM)
-#define SK_ROM_ON      (inb(SK_POS2) & POS2_CARD)
-#define SK_ROM_OFF     (inb(SK_POS2) | POS2_EPROM)
-#define SK_RAM_ON      (inb(SK_POS2) | POS2_CARD)
-#define SK_RAM_OFF     (inb(SK_POS2) & POS2_EPROM) 
-
-#define POS2_CARD  0x0001              /* 1 = SK_G16 on      0 = off */
-#define POS2_EPROM 0x0002              /* 1 = Boot EPROM off 0 = on */ 
-
-/* 
- * SK_G16 Memory mapped Registers
- * ------------------------------
- *
- */ 
-
-#define SK_IOREG        (&board->ioreg) /* LANCE data registers.     */ 
-#define SK_PORT         (&board->port)  /* Control, Status register  */
-#define SK_IOCOM        (&board->iocom) /* I/O Command               */
-
-/* 
- * SK_G16 Status/Control Register bits
- * -----------------------------------
- *
- * (C) Controlreg (S) Statusreg 
- */
-
-/* 
- * Register transfer: 0 = no transfer
- *                    1 = transferring data between LANCE and I/O reg 
- */
-#define SK_IORUN        0x20   
-
-/* 
- * LANCE interrupt: 0 = LANCE interrupt occurred	
- *                  1 = no LANCE interrupt occurred
- */
-#define SK_IRQ          0x10   
-			
-#define SK_RESET        0x08   /* Reset SK_CARD: 0 = RESET 1 = normal */
-#define SK_RW           0x02   /* 0 = write to 1 = read from */
-#define SK_ADR          0x01   /* 0 = REG DataPort 1 = RAP Reg addr port */
-
-  
-#define SK_RREG         SK_RW  /* Transferdirection to read from lance */
-#define SK_WREG         0      /* Transferdirection to write to lance */
-#define SK_RAP          SK_ADR /* Destination Register RAP */
-#define SK_RDATA        0      /* Destination Register REG DataPort */
-
-/* 
- * SK_G16 I/O Command 
- * ------------------
- */
-
-/* 
- * Any bitcombination sets the internal I/O bit (transfer will start) 
- * when written to I/O Command
- */
-
-#define SK_DOIO         0x80   /* Do Transfer */ 
- 
-/* 
- * LANCE RAP (Register Address Port). 
- * ---------------------------------
- */
-
-/*   
- * The LANCE internal registers are selected through the RAP. 
- * The Registers are:
- *
- * CSR0 - Status and Control flags 
- * CSR1 - Low order bits of initialize block (bits 15:00)
- * CSR2 - High order bits of initialize block (bits 07:00, 15:08 are reserved)
- * CSR3 - Allows redefinition of the Bus Master Interface.
- *        This register must be set to 0x0002, which means BSWAP = 0,
- *        ACON = 1, BCON = 0;
- *
- */
- 
-#define CSR0            0x00   
-#define CSR1            0x01  
-#define CSR2            0x02 
-#define CSR3            0x03
-
-/* 
- * General Definitions 
- * ===================
- */
-
-/* 
- * Set the number of Tx and Rx buffers, using Log_2(# buffers).
- * We have 16KB RAM which can be accessed by the LANCE. In the 
- * memory are not only the buffers but also the ring descriptors and
- * the initialize block. 
- * Don't change anything unless you really know what you do.
- */
-
-#define LC_LOG_TX_BUFFERS 1               /* (2 == 2^^1) 2 Transmit buffers */
-#define LC_LOG_RX_BUFFERS 3               /* (8 == 2^^3) 8 Receive buffers */
-
-/* Descriptor ring sizes */
-
-#define TMDNUM (1 << (LC_LOG_TX_BUFFERS)) /* 2 Transmit descriptor rings */
-#define RMDNUM (1 << (LC_LOG_RX_BUFFERS)) /* 8 Receive Buffers */
-
-/* Define Mask for setting RMD, TMD length in the LANCE init_block */
-
-#define TMDNUMMASK (LC_LOG_TX_BUFFERS << 29)
-#define RMDNUMMASK (LC_LOG_RX_BUFFERS << 29)
-
-/*
- * Data Buffer size is set to maximum packet length.
- */
-
-#define PKT_BUF_SZ              1518 
-
-/* 
- * The number of low I/O ports used by the ethercard. 
- */
-
-#define ETHERCARD_TOTAL_SIZE    SK_POS_SIZE
-
-/* 
- * SK_DEBUG
- *
- * Here you can choose what level of debugging wanted.
- *
- * If SK_DEBUG and SK_DEBUG2 are undefined, then only the
- *  necessary messages will be printed.
- *
- * If SK_DEBUG is defined, there will be many debugging prints
- *  which can help to find some mistakes in configuration or even
- *  in the driver code.
- *
- * If SK_DEBUG2 is defined, many many messages will be printed 
- *  which normally you don't need. I used this to check the interrupt
- *  routine. 
- *
- * (If you define only SK_DEBUG2 then only the messages for 
- *  checking interrupts will be printed!)
- *
- * Normal way of live is: 
- *
- * For the whole thing get going let both symbolic constants
- * undefined. If you face any problems and you know what's going
- * on (you know something about the card and you can interpret some
- * hex LANCE register output) then define SK_DEBUG
- * 
- */
-
-#undef  SK_DEBUG	/* debugging */
-#undef  SK_DEBUG2	/* debugging with more verbose report */
-
-#ifdef SK_DEBUG
-#define PRINTK(x) printk x
-#else
-#define PRINTK(x) /**/
-#endif
-
-#ifdef SK_DEBUG2
-#define PRINTK2(x) printk x
-#else
-#define PRINTK2(x) /**/
-#endif
-
-/* 
- * SK_G16 RAM
- *
- * The components are memory mapped and can be set in a region from
- * 0x00000 through 0xfc000 in 16KB steps. 
- *
- * The Network components are: dual ported RAM, Prom, I/O Reg, Status-,
- * Controlregister and I/O Command.
- *
- * dual ported RAM: This is the only memory region which the LANCE chip
- *      has access to. From the Lance it is addressed from 0x0000 to
- *      0x3fbf. The host accesses it normally.
- *
- * PROM: The PROM obtains the ETHERNET-MAC-Address. It is realised as a
- *       8-Bit PROM, this means only the 16 even addresses are used of the
- *       32 Byte Address region. Access to an odd address results in invalid
- *       data.
- * 
- * LANCE I/O Reg: The I/O Reg is build of 4 single Registers, Low-Byte Write,
- *       Hi-Byte Write, Low-Byte Read, Hi-Byte Read.
- *       Transfer from or to the LANCE is always in 16Bit so Low and High
- *       registers are always relevant.
- *
- *       The Data from the Readregister is not the data in the Writeregister!!
- *       
- * Port: Status- and Controlregister. 
- *       Two different registers which share the same address, Status is 
- *       read-only, Control is write-only.
- *    
- * I/O Command: 
- *       Any bitcombination written in here starts the transmission between
- *       Host and LANCE.
- */
-
-typedef struct
-{
-	unsigned char  ram[0x3fc0];   /* 16KB dual ported ram */
-	unsigned char  rom[0x0020];   /* 32Byte PROM containing 6Byte MAC */
-	unsigned char  res1[0x0010];  /* reserved */
-	unsigned volatile short ioreg;/* LANCE I/O Register */
-	unsigned volatile char  port; /* Statusregister and Controlregister */
-	unsigned char  iocom;         /* I/O Command Register */
-} SK_RAM;
-
-/* struct  */
-
-/* 
- * This is the structure for the dual ported ram. We
- * have exactly 16 320 Bytes. In here there must be:
- *
- *     - Initialize Block   (starting at a word boundary)
- *     - Receive and Transmit Descriptor Rings (quadword boundary)
- *     - Data Buffers (arbitrary boundary)
- *
- * This is because LANCE has on SK_G16 only access to the dual ported
- * RAM and nowhere else.
- */
-
-struct SK_ram
-{
-    struct init_block ib;
-    struct tmd tmde[TMDNUM];
-    struct rmd rmde[RMDNUM];
-    char tmdbuf[TMDNUM][PKT_BUF_SZ];
-    char rmdbuf[RMDNUM][PKT_BUF_SZ];
-};
-
-/* 
- * Structure where all necessary information is for ring buffer 
- * management and statistics.
- */
-
-struct priv
-{
-    struct SK_ram *ram;  /* dual ported ram structure */
-    struct rmd *rmdhead; /* start of receive ring descriptors */
-    struct tmd *tmdhead; /* start of transmit ring descriptors */
-    int        rmdnum;   /* actual used ring descriptor */
-    int        tmdnum;   /* actual transmit descriptor for transmitting data */
-    int        tmdlast;  /* last sent descriptor used for error handling, etc */
-    void       *rmdbufs[RMDNUM]; /* pointer to the receive buffers */
-    void       *tmdbufs[TMDNUM]; /* pointer to the transmit buffers */
-    struct net_device_stats stats; /* Device driver statistics */
-};
-
-/* global variable declaration */
-
-/* IRQ map used to reserve a IRQ (see SK_open()) */
-
-/* static variables */
-
-static SK_RAM *board;  /* pointer to our memory mapped board components */
-static DEFINE_SPINLOCK(SK_lock);
-
-/* Macros */
-
-
-/* Function Prototypes */
-
-/*
- * Device Driver functions
- * -----------------------
- * See for short explanation of each function its definitions header.
- */
-
-static int   SK_probe(struct net_device *dev, short ioaddr);
-
-static void  SK_timeout(struct net_device *dev);
-static int   SK_open(struct net_device *dev);
-static int   SK_send_packet(struct sk_buff *skb, struct net_device *dev);
-static irqreturn_t SK_interrupt(int irq, void *dev_id, struct pt_regs * regs);
-static void  SK_rxintr(struct net_device *dev);
-static void  SK_txintr(struct net_device *dev);
-static int   SK_close(struct net_device *dev);
-
-static struct net_device_stats *SK_get_stats(struct net_device *dev);
-
-unsigned int SK_rom_addr(void);
-
-static void set_multicast_list(struct net_device *dev);
-
-/*
- * LANCE Functions
- * ---------------
- */
-
-static int SK_lance_init(struct net_device *dev, unsigned short mode);
-void   SK_reset_board(void);
-void   SK_set_RAP(int reg_number);
-int    SK_read_reg(int reg_number);
-int    SK_rread_reg(void);
-void   SK_write_reg(int reg_number, int value);
-
-/* 
- * Debugging functions
- * -------------------
- */
-
-void SK_print_pos(struct net_device *dev, char *text);
-void SK_print_dev(struct net_device *dev, char *text);
-void SK_print_ram(struct net_device *dev);
-
-
-/*-
- * Function       : SK_init
- * Author         : Patrick J.D. Weichmann
- * Date Created   : 94/05/26
- *
- * Description    : Check for a SK_G16 network adaptor and initialize it.
- *                  This function gets called by dev_init which initializes
- *                  all Network devices.
- *
- * Parameters     : I : struct net_device *dev - structure preconfigured 
- *                                           from Space.c
- * Return Value   : 0 = Driver Found and initialized 
- * Errors         : ENODEV - no device found
- *                  ENXIO  - not probed
- * Globals        : None
- * Update History :
- *     YY/MM/DD  uid  Description
--*/
-
-static int io;	/* 0 == probe */
-
-/* 
- * Check for a network adaptor of this type, and return '0' if one exists.
- * If dev->base_addr == 0, probe all likely locations.
- * If dev->base_addr == 1, always return failure.
- */
-
-struct net_device * __init SK_init(int unit)
-{
-	int *port, ports[] = SK_IO_PORTS;  /* SK_G16 supported ports */
-	static unsigned version_printed;
-	struct net_device *dev = alloc_etherdev(sizeof(struct priv));
-	int err = -ENODEV;
-
-	if (!dev)
-		return ERR_PTR(-ENOMEM);
-
-	if (unit >= 0) {
-		sprintf(dev->name, "eth%d", unit);
-		netdev_boot_setup_check(dev);
-		io = dev->base_addr;
-	}
-
-	if (version_printed++ == 0)
-	        PRINTK(("%s: %s", SK_NAME, rcsid));
-
-	if (io > 0xff) {        /* Check a single specified address */
-		err = -EBUSY;
-		/* Check if on specified address is a SK_G16 */
-		if (request_region(io, ETHERCARD_TOTAL_SIZE, "sk_g16")) {
-			err = SK_probe(dev, io);
-			if (!err)
-				goto got_it;
-			release_region(io, ETHERCARD_TOTAL_SIZE);
-		}
-	} else if (io > 0) {       /* Don't probe at all */
-		err = -ENXIO;
-	} else {
-		/* Autoprobe base_addr */
-		for (port = &ports[0]; *port; port++) {
-			io = *port;
-
-			/* Check if I/O Port region is used by another board */
-			if (!request_region(io, ETHERCARD_TOTAL_SIZE, "sk_g16"))
-				continue;       /* Try next Port address */
-
-			/* Check if at ioaddr is a SK_G16 */
-			if (SK_probe(dev, io) == 0)
-				goto got_it;
-
-			release_region(io, ETHERCARD_TOTAL_SIZE);
-		}
-	}
-err_out:
-	free_netdev(dev);
-	return ERR_PTR(err);
-
-got_it:
-	err = register_netdev(dev);
-	if (err) {
-		release_region(dev->base_addr, ETHERCARD_TOTAL_SIZE);
-		goto err_out;
-	}
-	return dev;
-
-} /* End of SK_init */
-
-
-MODULE_AUTHOR("Patrick J.D. Weichmann");
-MODULE_DESCRIPTION("Schneider & Koch G16 Ethernet Device Driver");
-MODULE_LICENSE("GPL");
-MODULE_PARM(io, "i");
-MODULE_PARM_DESC(io, "0 to probe common ports (unsafe), or the I/O base of the board");
-
-
-#ifdef MODULE
-
-static struct net_device *SK_dev;
-
-static int __init SK_init_module (void)
-{
- 	SK_dev = SK_init(-1);
- 	return IS_ERR(SK_dev) ? PTR_ERR(SK_dev) : 0;
-}
-
-static void __exit SK_cleanup_module (void)
-{
- 	unregister_netdev(SK_dev);
- 	release_region(SK_dev->base_addr, ETHERCARD_TOTAL_SIZE);
- 	free_netdev(SK_dev);
-}
-
-module_init(SK_init_module);
-module_exit(SK_cleanup_module);
-#endif
-
-
-/*-
- * Function       : SK_probe
- * Author         : Patrick J.D. Weichmann
- * Date Created   : 94/05/26
- *
- * Description    : This function is called by SK_init and 
- *                  does the main part of initialization.
- *                  
- * Parameters     : I : struct net_device *dev - SK_G16 device structure
- *                  I : short ioaddr       - I/O Port address where POS is.
- * Return Value   : 0 = Initialization done             
- * Errors         : ENODEV - No SK_G16 found
- *                  -1     - Configuration problem
- * Globals        : board       - pointer to SK_RAM
- * Update History :
- *     YY/MM/DD  uid  Description
- *     94/06/30  pwe  SK_ADDR now checked and at the correct place
--*/
-
-int __init SK_probe(struct net_device *dev, short ioaddr)
-{
-    int i,j;                /* Counters */
-    int sk_addr_flag = 0;   /* SK ADDR correct? 1 - no, 0 - yes */
-    unsigned int rom_addr;  /* used to store RAM address used for POS_ADDR */
-
-    struct priv *p = netdev_priv(dev);	/* SK_G16 private structure */
-
-    if (inb(SK_POS0) != SK_IDLOW || inb(SK_POS1) != SK_IDHIGH)
-	return -ENODEV;
-    dev->base_addr = ioaddr;
-
-    if (SK_ADDR & 0x3fff || SK_ADDR < 0xa0000)
-    {
-      
-       sk_addr_flag = 1;
-
-       /* 
-        * Now here we could use a routine which searches for a free
-        * place in the ram and set SK_ADDR if found. TODO. 
-        */
-    }
-
-    if (SK_BOOT_ROM)            /* Shall we keep Boot_ROM on ? */
-    {
-        PRINTK(("## %s: SK_BOOT_ROM is set.\n", SK_NAME));
-
-        rom_addr = SK_rom_addr();
-
-	if (rom_addr == 0)      /* No Boot_ROM found */
-	{
-            if (sk_addr_flag)   /* No or Invalid SK_ADDR is defined */ 
-            {
-                printk("%s: SK_ADDR %#08x is not valid. Check configuration.\n",
-                       dev->name, SK_ADDR);
-                return -1;
-            }
-
-	    rom_addr = SK_ADDR; /* assign predefined address */
-
-	    PRINTK(("## %s: NO Bootrom found \n", SK_NAME));
-
-	    outb(SK_ROM_RAM_OFF, SK_POS2); /* Boot_ROM + RAM off */
-	    outb(POS_ADDR, SK_POS3);       /* Set RAM address */
-	    outb(SK_RAM_ON, SK_POS2);      /* enable RAM */
-	}
-	else if (rom_addr == SK_ADDR) 
-	{
-            printk("%s: RAM + ROM are set to the same address %#08x\n"
-                   "   Check configuration. Now switching off Boot_ROM\n",
-                   SK_NAME, rom_addr);
-
-	    outb(SK_ROM_RAM_OFF, SK_POS2); /* Boot_ROM + RAM off*/
-	    outb(POS_ADDR, SK_POS3);       /* Set RAM address */
-	    outb(SK_RAM_ON, SK_POS2);      /* enable RAM */
-	}
-	else
-	{
-            PRINTK(("## %s: Found ROM at %#08x\n", SK_NAME, rom_addr));
-	    PRINTK(("## %s: Keeping Boot_ROM on\n", SK_NAME));
-
-            if (sk_addr_flag)       /* No or Invalid SK_ADDR is defined */ 
-            {
-                printk("%s: SK_ADDR %#08x is not valid. Check configuration.\n",
-                       dev->name, SK_ADDR);
-                return -1;
-            }
-
-	    rom_addr = SK_ADDR;
-
-	    outb(SK_ROM_RAM_OFF, SK_POS2); /* Boot_ROM + RAM off */ 
-	    outb(POS_ADDR, SK_POS3);       /* Set RAM address */
-	    outb(SK_ROM_RAM_ON, SK_POS2);  /* RAM on, BOOT_ROM on */
-	}
-    }
-    else /* Don't keep Boot_ROM */
-    {
-        PRINTK(("## %s: SK_BOOT_ROM is not set.\n", SK_NAME));
-
-        if (sk_addr_flag)           /* No or Invalid SK_ADDR is defined */ 
-        {
-            printk("%s: SK_ADDR %#08x is not valid. Check configuration.\n",
-                   dev->name, SK_ADDR);
-            return -1;
-        }
-
-	rom_addr = SK_rom_addr();          /* Try to find a Boot_ROM */
-
-	/* IF we find a Boot_ROM disable it */
-
-	outb(SK_ROM_RAM_OFF, SK_POS2);     /* Boot_ROM + RAM off */  
-
-        /* We found a Boot_ROM and it's gone. Set RAM address on
-         * Boot_ROM address. 
-         */ 
-
-	if (rom_addr) 
-	{
-            printk("%s: We found Boot_ROM at %#08x. Now setting RAM on"
-                   "that address\n", SK_NAME, rom_addr);
-
-	    outb(POS_ADDR, SK_POS3);       /* Set RAM on Boot_ROM address */
-	}
-	else /* We did not find a Boot_ROM, use predefined SK_ADDR for ram */
-	{
-            if (sk_addr_flag)       /* No or Invalid SK_ADDR is defined */ 
-            {
-                printk("%s: SK_ADDR %#08x is not valid. Check configuration.\n",
-                       dev->name, SK_ADDR);
-                return -1;
-            }
-
-	    rom_addr = SK_ADDR;
-
-	    outb(POS_ADDR, SK_POS3);       /* Set RAM address */ 
-	}
-	outb(SK_RAM_ON, SK_POS2);          /* enable RAM */
-    }
-
-#ifdef SK_DEBUG
-    SK_print_pos(dev, "POS registers after ROM, RAM config");
-#endif
-
-    board = (SK_RAM *) isa_bus_to_virt(rom_addr);
-
-    /* Read in station address */
-    for (i = 0, j = 0; i < ETH_ALEN; i++, j+=2)
-    {
-	dev->dev_addr[i] = readb(board->rom+j);          
-    }
-
-    /* Check for manufacturer code */
-    if (!(dev->dev_addr[0] == SK_MAC0 &&
-	  dev->dev_addr[1] == SK_MAC1 &&
-	  dev->dev_addr[2] == SK_MAC2) )
-    {
-        PRINTK(("## %s: We did not find SK_G16 at RAM location.\n",
-                SK_NAME)); 
-	return -ENODEV;                     /* NO SK_G16 found */
-    }
-
-    printk("%s: %s found at %#3x, HW addr: %#04x:%02x:%02x:%02x:%02x:%02x\n",
-	    dev->name,
-	    "Schneider & Koch Netcard",
-	    (unsigned int) dev->base_addr,
-	    dev->dev_addr[0],
-	    dev->dev_addr[1],
-	    dev->dev_addr[2],
-	    dev->dev_addr[3],
-	    dev->dev_addr[4],
-	    dev->dev_addr[5]);
-
-    memset((char *) dev->priv, 0, sizeof(struct priv)); /* clear memory */
-
-    /* Assign our Device Driver functions */
-
-    dev->open                   = SK_open;
-    dev->stop                   = SK_close;
-    dev->hard_start_xmit        = SK_send_packet;
-    dev->get_stats              = SK_get_stats;
-    dev->set_multicast_list     = set_multicast_list;
-    dev->tx_timeout		= SK_timeout;
-    dev->watchdog_timeo		= HZ/7;
-
-
-    dev->flags &= ~IFF_MULTICAST;
-
-    /* Initialize private structure */
-
-    p->ram = (struct SK_ram *) rom_addr; /* Set dual ported RAM addr */
-    p->tmdhead = &(p->ram)->tmde[0];     /* Set TMD head */
-    p->rmdhead = &(p->ram)->rmde[0];     /* Set RMD head */
-
-    /* Initialize buffer pointers */
-
-    for (i = 0; i < TMDNUM; i++)
-    {
-	p->tmdbufs[i] = &(p->ram)->tmdbuf[i];
-    }
-
-    for (i = 0; i < RMDNUM; i++)
-    {
-	p->rmdbufs[i] = &(p->ram)->rmdbuf[i]; 
-    }
-
-#ifdef SK_DEBUG
-    SK_print_pos(dev, "End of SK_probe");
-    SK_print_ram(dev);
-#endif 
-    return 0;                            /* Initialization done */
-} /* End of SK_probe() */
-
-
-/*- 
- * Function       : SK_open
- * Author         : Patrick J.D. Weichmann
- * Date Created   : 94/05/26
- *
- * Description    : This function is called sometimes after booting 
- *                  when ifconfig program is run.
- *
- *                  This function requests an IRQ, sets the correct
- *                  IRQ in the card. Then calls SK_lance_init() to 
- *                  init and start the LANCE chip. Then if everything is 
- *                  ok returns with 0 (OK), which means SK_G16 is now
- *                  opened and operational.
- *
- *                  (Called by dev_open() /net/inet/dev.c)
- *
- * Parameters     : I : struct net_device *dev - SK_G16 device structure
- * Return Value   : 0 - Device opened
- * Errors         : -EAGAIN - Open failed
- * Side Effects   : None
- * Update History :
- *     YY/MM/DD  uid  Description
--*/
-
-static int SK_open(struct net_device *dev)
-{
-    int i = 0;
-    int irqval = 0;
-    int ioaddr = dev->base_addr;
-
-    int irqtab[] = SK_IRQS; 
-
-    struct priv *p = netdev_priv(dev);
-
-    PRINTK(("## %s: At beginning of SK_open(). CSR0: %#06x\n", 
-           SK_NAME, SK_read_reg(CSR0)));
-
-    if (dev->irq == 0) /* Autoirq */
-    {
-	i = 0;
-
-	/* 
-         * Check if one IRQ out of SK_IRQS is free and install 
-	 * interrupt handler.
-	 * Most done by request_irq(). 
-	 * irqval: 0       - interrupt handler installed for IRQ irqtab[i]
-	 *         -EBUSY  - interrupt busy 
-         *         -EINVAL - irq > 15 or handler = NULL
-	 */
-
-	do
-	{
-	  irqval = request_irq(irqtab[i], &SK_interrupt, 0, "sk_g16", dev);
-	  i++;
-	} while (irqval && irqtab[i]);
-
-	if (irqval) /* We tried every possible IRQ but no success */
-	{
-	    printk("%s: unable to get an IRQ\n", dev->name);
-	    return -EAGAIN;
-	}
-
-	dev->irq = irqtab[--i]; 
-	
-	outb(i<<2, SK_POS4);           /* Set Card on probed IRQ */
-
-    }
-    else if (dev->irq == 2) /* IRQ2 is always IRQ9 */
-    {
-	if (request_irq(9, &SK_interrupt, 0, "sk_g16", dev))
-	{
-	    printk("%s: unable to get IRQ 9\n", dev->name);
-	    return -EAGAIN;
-	} 
-	dev->irq = 9;
-	
-        /* 
-         * Now we set card on IRQ2.
-         * This can be confusing, but remember that IRQ2 on the network
-         * card is in reality IRQ9
-         */
-	outb(0x08, SK_POS4);           /* set card to IRQ2 */
-
-    }
-    else  /* Check IRQ as defined in Space.c */
-    {
-	int i = 0;
-
-	/* check if IRQ free and valid. Then install Interrupt handler */
-
-	if (request_irq(dev->irq, &SK_interrupt, 0, "sk_g16", dev))
-	{
-	    printk("%s: unable to get selected IRQ\n", dev->name);
-	    return -EAGAIN;
-	}
-
-	switch(dev->irq)
-	{
-	    case 3: i = 0;
-		    break;
-	    case 5: i = 1;
-		    break;
-	    case 2: i = 2;
-		    break;
-	    case 11:i = 3;
-		    break;
-	    default: 
-		printk("%s: Preselected IRQ %d is invalid for %s boards",
-		       dev->name,
-		       dev->irq,
-                       SK_NAME);
-		return -EAGAIN;
-	}      
-  
-	outb(i<<2, SK_POS4);           /* Set IRQ on card */
-    }
-
-    printk("%s: Schneider & Koch G16 at %#3x, IRQ %d, shared mem at %#08x\n",
-	    dev->name, (unsigned int)dev->base_addr, 
-	    (int) dev->irq, (unsigned int) p->ram);
-
-    if (!(i = SK_lance_init(dev, 0)))  /* LANCE init OK? */
-    {
-	netif_start_queue(dev);
-
-#ifdef SK_DEBUG
-
-        /* 
-         * This debug block tries to stop LANCE,
-         * reinit LANCE with transmitter and receiver disabled,
-         * then stop again and reinit with NORMAL_MODE
-         */
-
-        printk("## %s: After lance init. CSR0: %#06x\n", 
-               SK_NAME, SK_read_reg(CSR0));
-        SK_write_reg(CSR0, CSR0_STOP);
-        printk("## %s: LANCE stopped. CSR0: %#06x\n", 
-               SK_NAME, SK_read_reg(CSR0));
-        SK_lance_init(dev, MODE_DTX | MODE_DRX);
-        printk("## %s: Reinit with DTX + DRX off. CSR0: %#06x\n", 
-               SK_NAME, SK_read_reg(CSR0));
-        SK_write_reg(CSR0, CSR0_STOP);
-        printk("## %s: LANCE stopped. CSR0: %#06x\n", 
-               SK_NAME, SK_read_reg(CSR0));
-        SK_lance_init(dev, MODE_NORMAL);
-        printk("## %s: LANCE back to normal mode. CSR0: %#06x\n", 
-               SK_NAME, SK_read_reg(CSR0));
-        SK_print_pos(dev, "POS regs before returning OK");
-
-#endif /* SK_DEBUG */
-       
-	return 0;              /* SK_open() is successful */
-    }
-    else /* LANCE init failed */
-    {
-
-	PRINTK(("## %s: LANCE init failed: CSR0: %#06x\n", 
-               SK_NAME, SK_read_reg(CSR0)));
-
-	return -EAGAIN;
-    }
-
-} /* End of SK_open() */
-
-
-/*-
- * Function       : SK_lance_init
- * Author         : Patrick J.D. Weichmann
- * Date Created   : 94/05/26
- *
- * Description    : Reset LANCE chip, fill RMD, TMD structures with
- *                  start values and Start LANCE.
- *
- * Parameters     : I : struct net_device *dev - SK_G16 device structure
- *                  I : int mode - put LANCE into "mode" see data-sheet for
- *                                 more info.
- * Return Value   : 0  - Init done
- * Errors         : -1 - Init failed
- * Update History :
- *     YY/MM/DD  uid  Description
--*/
-
-static int SK_lance_init(struct net_device *dev, unsigned short mode)
-{
-    int i;
-    unsigned long flags;
-    struct priv *p = netdev_priv(dev);
-    struct tmd  *tmdp;
-    struct rmd  *rmdp;
-
-    PRINTK(("## %s: At beginning of LANCE init. CSR0: %#06x\n", 
-           SK_NAME, SK_read_reg(CSR0)));
-
-    /* Reset LANCE */
-    SK_reset_board();
-
-    /* Initialize TMD's with start values */
-    p->tmdnum = 0;                   /* First descriptor for transmitting */ 
-    p->tmdlast = 0;                  /* First descriptor for reading stats */
-
-    for (i = 0; i < TMDNUM; i++)     /* Init all TMD's */
-    {
-	tmdp = p->tmdhead + i; 
-   
-	writel((unsigned long) p->tmdbufs[i], tmdp->u.buffer); /* assign buffer */
-	
-	/* Mark TMD as start and end of packet */
-	writeb(TX_STP | TX_ENP, &tmdp->u.s.status);
-    }
-
-
-    /* Initialize RMD's with start values */
-
-    p->rmdnum = 0;                   /* First RMD which will be used */
- 
-    for (i = 0; i < RMDNUM; i++)     /* Init all RMD's */
-    {
-	rmdp = p->rmdhead + i;
-
-	
-	writel((unsigned long) p->rmdbufs[i], rmdp->u.buffer); /* assign buffer */
-	
-	/* 
-         * LANCE must be owner at beginning so that he can fill in 
-	 * receiving packets, set status and release RMD 
-	 */
-
-	writeb(RX_OWN, &rmdp->u.s.status);
-
-	writew(-PKT_BUF_SZ, &rmdp->blen); /* Buffer Size (two's complement) */
-
-	writeb(0, &rmdp->mlen);           /* init message length */       
-	
-    }
-
-    /* Fill LANCE Initialize Block */
-
-    writew(mode, (&((p->ram)->ib.mode))); /* Set operation mode */
-
-    for (i = 0; i < ETH_ALEN; i++)   /* Set physical address */
-    {
-	writeb(dev->dev_addr[i], (&((p->ram)->ib.paddr[i]))); 
-    }
-
-    for (i = 0; i < 8; i++)          /* Set multicast, logical address */
-    {
-	writeb(0, (&((p->ram)->ib.laddr[i]))); /* We do not use logical addressing */
-    } 
-
-    /* Set ring descriptor pointers and set number of descriptors */
-
-    writel((int)p->rmdhead | RMDNUMMASK, (&((p->ram)->ib.rdrp)));
-    writel((int)p->tmdhead | TMDNUMMASK, (&((p->ram)->ib.tdrp)));
-
-    /* Prepare LANCE Control and Status Registers */
-
-    spin_lock_irqsave(&SK_lock, flags);
-
-    SK_write_reg(CSR3, CSR3_ACON);   /* Ale Control !!!THIS MUST BE SET!!!! */
- 
-    /* 
-     * LANCE addresses the RAM from 0x0000 to 0x3fbf and has no access to
-     * PC Memory locations.
-     *
-     * In structure SK_ram is defined that the first thing in ram
-     * is the initialization block. So his address is for LANCE always
-     * 0x0000
-     *
-     * CSR1 contains low order bits 15:0 of initialization block address
-     * CSR2 is built of: 
-     *    7:0  High order bits 23:16 of initialization block address
-     *   15:8  reserved, must be 0
-     */
-    
-    /* Set initialization block address (must be on word boundary) */
-    SK_write_reg(CSR1, 0);          /* Set low order bits 15:0 */
-    SK_write_reg(CSR2, 0);          /* Set high order bits 23:16 */ 
-    
-
-    PRINTK(("## %s: After setting CSR1-3. CSR0: %#06x\n", 
-           SK_NAME, SK_read_reg(CSR0)));
-
-    /* Initialize LANCE */
-
-    /* 
-     * INIT = Initialize, when set, causes the LANCE to begin the
-     * initialization procedure and access the Init Block.
-     */
-
-    SK_write_reg(CSR0, CSR0_INIT); 
-
-    spin_unlock_irqrestore(&SK_lock, flags);
-
-    /* Wait until LANCE finished initialization */
-    
-    SK_set_RAP(CSR0);              /* Register Address Pointer to CSR0 */
-
-    for (i = 0; (i < 100) && !(SK_rread_reg() & CSR0_IDON); i++) 
-	; /* Wait until init done or go ahead if problems (i>=100) */
-
-    if (i >= 100) /* Something is wrong ! */
-    {
-	printk("%s: can't init am7990, status: %04x "
-	       "init_block: %#08x\n", 
-		dev->name, (int) SK_read_reg(CSR0), 
-		(unsigned int) &(p->ram)->ib);
-
-#ifdef SK_DEBUG
-	SK_print_pos(dev, "LANCE INIT failed");
-	SK_print_dev(dev,"Device Structure:");
-#endif
-
-	return -1;                 /* LANCE init failed */
-    }
-
-    PRINTK(("## %s: init done after %d ticks\n", SK_NAME, i));
-
-    /* Clear Initialize done, enable Interrupts, start LANCE */
-
-    SK_write_reg(CSR0, CSR0_IDON | CSR0_INEA | CSR0_STRT);
-
-    PRINTK(("## %s: LANCE started. CSR0: %#06x\n", SK_NAME, 
-            SK_read_reg(CSR0)));
-
-    return 0;                      /* LANCE is up and running */
-
-} /* End of SK_lance_init() */
-
-
-
-/*-
- * Function       : SK_send_packet
- * Author         : Patrick J.D. Weichmann
- * Date Created   : 94/05/27
- *
- * Description    : Writes an socket buffer into a transmit descriptor
- *                  and starts transmission.
- *
- * Parameters     : I : struct sk_buff *skb - packet to transfer
- *                  I : struct net_device *dev  - SK_G16 device structure
- * Return Value   : 0 - OK
- *                  1 - Could not transmit (dev_queue_xmit will queue it)
- *                      and try to sent it later
- * Globals        : None
- * Side Effects   : None
- * Update History :
- *     YY/MM/DD  uid  Description
--*/
-
-static void SK_timeout(struct net_device *dev)
-{
-	printk(KERN_WARNING "%s: xmitter timed out, try to restart!\n", dev->name);
-	SK_lance_init(dev, MODE_NORMAL); /* Reinit LANCE */
-	netif_wake_queue(dev);		 /* Clear Transmitter flag */
-	dev->trans_start = jiffies;      /* Mark Start of transmission */
-}
-
-static int SK_send_packet(struct sk_buff *skb, struct net_device *dev)
-{
-    struct priv *p = netdev_priv(dev);
-    struct tmd *tmdp;
-    static char pad[64];
-
-    PRINTK2(("## %s: SK_send_packet() called, CSR0 %#04x.\n", 
-	    SK_NAME, SK_read_reg(CSR0)));
-
-
-    /* 
-     * Block a timer-based transmit from overlapping. 
-     * This means check if we are already in. 
-     */
-
-    netif_stop_queue (dev);
-
-    {
-
-	/* Evaluate Packet length */
-	short len = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; 
-       
-	tmdp = p->tmdhead + p->tmdnum; /* Which descriptor for transmitting */
-
-	/* Fill in Transmit Message Descriptor */
-
-	/* Copy data into dual ported ram */
-
-	memcpy_toio((tmdp->u.buffer & 0x00ffffff), skb->data, skb->len);
-	if (len != skb->len)
-		memcpy_toio((tmdp->u.buffer & 0x00ffffff) + skb->len, pad, len-skb->len);
-
-	writew(-len, &tmdp->blen);            /* set length to transmit */
-
-	/* 
-	 * Packet start and end is always set because we use the maximum
-	 * packet length as buffer length.
-	 * Relinquish ownership to LANCE
-	 */
-
-	writeb(TX_OWN | TX_STP | TX_ENP, &tmdp->u.s.status);
-	
-	/* Start Demand Transmission */
-	SK_write_reg(CSR0, CSR0_TDMD | CSR0_INEA);
-
-	dev->trans_start = jiffies;   /* Mark start of transmission */
-
-	/* Set pointer to next transmit buffer */
-	p->tmdnum++; 
-	p->tmdnum &= TMDNUM-1; 
-
-	/* Do we own the next transmit buffer ? */
-	if (! (readb(&((p->tmdhead + p->tmdnum)->u.s.status)) & TX_OWN) )
-	{
-	   /* 
-	    * We own next buffer and are ready to transmit, so
-	    * clear busy flag
-	    */
-	   netif_start_queue(dev);
-	}
-
-	p->stats.tx_bytes += skb->len;
-
-    }
-
-    dev_kfree_skb(skb);
-    return 0;  
-} /* End of SK_send_packet */
-
-
-/*-
- * Function       : SK_interrupt
- * Author         : Patrick J.D. Weichmann
- * Date Created   : 94/05/27
- *
- * Description    : SK_G16 interrupt handler which checks for LANCE
- *                  Errors, handles transmit and receive interrupts
- *
- * Parameters     : I : int irq, void *dev_id, struct pt_regs * regs -
- * Return Value   : None
- * Errors         : None
- * Globals        : None
- * Side Effects   : None
- * Update History :
- *     YY/MM/DD  uid  Description
--*/
-
-static irqreturn_t SK_interrupt(int irq, void *dev_id, struct pt_regs * regs)
-{
-    int csr0;
-    struct net_device *dev = dev_id;
-    struct priv *p = netdev_priv(dev);
-
-
-    PRINTK2(("## %s: SK_interrupt(). status: %#06x\n", 
-            SK_NAME, SK_read_reg(CSR0)));
-
-    if (dev == NULL)
-    {
-	printk("SK_interrupt(): IRQ %d for unknown device.\n", irq);
-    }
-    
-    spin_lock (&SK_lock);
-
-    csr0 = SK_read_reg(CSR0);      /* store register for checking */
-
-    /* 
-     * Acknowledge all of the current interrupt sources, disable      
-     * Interrupts (INEA = 0) 
-     */
-
-    SK_write_reg(CSR0, csr0 & CSR0_CLRALL); 
-
-    if (csr0 & CSR0_ERR) /* LANCE Error */
-    {
-	printk("%s: error: %04x\n", dev->name, csr0);
-      
-        if (csr0 & CSR0_MISS)      /* No place to store packet ? */
-        { 
-            p->stats.rx_dropped++;
-        }
-    }
-
-    if (csr0 & CSR0_RINT)          /* Receive Interrupt (packet arrived) */ 
-    {
-	SK_rxintr(dev); 
-    }
-
-    if (csr0 & CSR0_TINT)          /* Transmit interrupt (packet sent) */
-    {
-	SK_txintr(dev);
-    }
-
-    SK_write_reg(CSR0, CSR0_INEA); /* Enable Interrupts */
-
-    spin_unlock (&SK_lock);
-    return IRQ_HANDLED;
-} /* End of SK_interrupt() */ 
-
-
-/*-
- * Function       : SK_txintr
- * Author         : Patrick J.D. Weichmann
- * Date Created   : 94/05/27
- *
- * Description    : After sending a packet we check status, update
- *                  statistics and relinquish ownership of transmit 
- *                  descriptor ring.
- *
- * Parameters     : I : struct net_device *dev - SK_G16 device structure
- * Return Value   : None
- * Errors         : None
- * Globals        : None
- * Update History :
- *     YY/MM/DD  uid  Description
--*/
-
-static void SK_txintr(struct net_device *dev)
-{
-    int tmdstat;
-    struct tmd *tmdp;
-    struct priv *p = netdev_priv(dev);
-
-
-    PRINTK2(("## %s: SK_txintr() status: %#06x\n", 
-            SK_NAME, SK_read_reg(CSR0)));
-
-    tmdp = p->tmdhead + p->tmdlast;     /* Which buffer we sent at last ? */
-
-    /* Set next buffer */
-    p->tmdlast++;
-    p->tmdlast &= TMDNUM-1;
-
-    tmdstat = readb(&tmdp->u.s.status);
-
-    /* 
-     * We check status of transmitted packet.
-     * see LANCE data-sheet for error explanation
-     */
-    if (tmdstat & TX_ERR) /* Error occurred */
-    {
-	int stat2 = readw(&tmdp->status2);
-
-	printk("%s: TX error: %04x %04x\n", dev->name, tmdstat, stat2);
-
-	if (stat2 & TX_TDR)    /* TDR problems? */
-	{
-	    printk("%s: tdr-problems \n", dev->name);
-	}
-
-	if (stat2 & TX_RTRY)   /* Failed in 16 attempts to transmit ? */
-            p->stats.tx_aborted_errors++;   
-        if (stat2 & TX_LCOL)   /* Late collision ? */
-            p->stats.tx_window_errors++; 
-	if (stat2 & TX_LCAR)   /* Loss of Carrier ? */  
-            p->stats.tx_carrier_errors++;
-        if (stat2 & TX_UFLO)   /* Underflow error ? */
-        {
-            p->stats.tx_fifo_errors++;
-
-            /* 
-             * If UFLO error occurs it will turn transmitter of.
-             * So we must reinit LANCE
-             */
-
-            SK_lance_init(dev, MODE_NORMAL);
-        }
-	
-	p->stats.tx_errors++;
-
-	writew(0, &tmdp->status2);             /* Clear error flags */
-    }
-    else if (tmdstat & TX_MORE)        /* Collisions occurred ? */
-    {
-        /* 
-         * Here I have a problem.
-         * I only know that there must be one or up to 15 collisions.
-         * That's why TX_MORE is set, because after 16 attempts TX_RTRY
-         * will be set which means couldn't send packet aborted transfer.
-         *
-         * First I did not have this in but then I thought at minimum
-         * we see that something was not ok.
-         * If anyone knows something better than this to handle this
-         * please report it.
-         */ 
-
-        p->stats.collisions++; 
-    }
-    else   /* Packet sent without any problems */
-    {
-        p->stats.tx_packets++; 
-    }
-
-    /* 
-     * We mark transmitter not busy anymore, because now we have a free
-     * transmit descriptor which can be filled by SK_send_packet and
-     * afterwards sent by the LANCE
-     * 
-     * The function which do handle slow IRQ parts is do_bottom_half()
-     * which runs at normal kernel priority, that means all interrupt are
-     * enabled. (see kernel/irq.c)
-     *  
-     * net_bh does something like this:
-     *  - check if already in net_bh
-     *  - try to transmit something from the send queue
-     *  - if something is in the receive queue send it up to higher 
-     *    levels if it is a known protocol
-     *  - try to transmit something from the send queue
-     */
-
-    netif_wake_queue(dev);
-
-} /* End of SK_txintr() */
-
-
-/*-
- * Function       : SK_rxintr
- * Author         : Patrick J.D. Weichmann
- * Date Created   : 94/05/27
- *
- * Description    : Buffer sent, check for errors, relinquish ownership
- *                  of the receive message descriptor. 
- *
- * Parameters     : I : SK_G16 device structure
- * Return Value   : None
- * Globals        : None
- * Update History :
- *     YY/MM/DD  uid  Description
--*/
-
-static void SK_rxintr(struct net_device *dev)
-{
-
-    struct rmd *rmdp;
-    int rmdstat;
-    struct priv *p = netdev_priv(dev);
-
-    PRINTK2(("## %s: SK_rxintr(). CSR0: %#06x\n", 
-            SK_NAME, SK_read_reg(CSR0)));
-
-    rmdp = p->rmdhead + p->rmdnum;
-
-    /* As long as we own the next entry, check status and send
-     * it up to higher layer 
-     */
-
-    while (!( (rmdstat = readb(&rmdp->u.s.status)) & RX_OWN))
-    {
-	/* 
-         * Start and end of packet must be set, because we use 
-	 * the ethernet maximum packet length (1518) as buffer size.
-	 * 
-	 * Because our buffers are at maximum OFLO and BUFF errors are
-	 * not to be concerned (see Data sheet)
-	 */
-
-	if ((rmdstat & (RX_STP | RX_ENP)) != (RX_STP | RX_ENP))
-	{
-	    /* Start of a frame > 1518 Bytes ? */
-
-	    if (rmdstat & RX_STP) 
-	    {
-		p->stats.rx_errors++;        /* bad packet received */
-		p->stats.rx_length_errors++; /* packet too long */
-
-		printk("%s: packet too long\n", dev->name);
-	    }
-	    
-	    /* 
-             * All other packets will be ignored until a new frame with
-	     * start (RX_STP) set follows.
-	     * 
-	     * What we do is just give descriptor free for new incoming
-	     * packets. 
-	     */
-
-	    writeb(RX_OWN, &rmdp->u.s.status); /* Relinquish ownership to LANCE */ 
-
-	}
-	else if (rmdstat & RX_ERR)          /* Receive Error ? */
-	{
-	    printk("%s: RX error: %04x\n", dev->name, (int) rmdstat);
-	    
-	    p->stats.rx_errors++;
-
-	    if (rmdstat & RX_FRAM) p->stats.rx_frame_errors++;
-	    if (rmdstat & RX_CRC)  p->stats.rx_crc_errors++;
-
-	    writeb(RX_OWN, &rmdp->u.s.status); /* Relinquish ownership to LANCE */
-
-	}
-	else /* We have a packet which can be queued for the upper layers */
-	{
-
-	    int len = readw(&rmdp->mlen) & 0x0fff;  /* extract message length from receive buffer */
-	    struct sk_buff *skb;
-
-	    skb = dev_alloc_skb(len+2); /* allocate socket buffer */ 
-
-	    if (skb == NULL)                /* Could not get mem ? */
-	    {
-    
-		/* 
-                 * Couldn't allocate sk_buffer so we give descriptor back
-		 * to Lance, update statistics and go ahead.
-		 */
-
-		writeb(RX_OWN, &rmdp->u.s.status); /* Relinquish ownership to LANCE */
-		printk("%s: Couldn't allocate sk_buff, deferring packet.\n",
-		       dev->name);
-		p->stats.rx_dropped++;
-
-		break;                      /* Jump out */
-	    }
-	    
-	    /* Prepare sk_buff to queue for upper layers */
-
-	    skb->dev = dev;
-	    skb_reserve(skb,2);		/* Align IP header on 16 byte boundary */
-	    
-	    /* 
-             * Copy data out of our receive descriptor into sk_buff.
-	     *
-	     * (rmdp->u.buffer & 0x00ffffff) -> get address of buffer and 
-	     * ignore status fields) 
-	     */
-
-	    memcpy_fromio(skb_put(skb,len), (rmdp->u.buffer & 0x00ffffff), len);
-
-
-	    /* 
-             * Notify the upper protocol layers that there is another packet
-	     * to handle
-	     *
-	     * netif_rx() always succeeds. see /net/inet/dev.c for more.
-	     */
-
-	    skb->protocol=eth_type_trans(skb,dev);
-	    netif_rx(skb);                 /* queue packet and mark it for processing */
-	   
-	    /* 
-             * Packet is queued and marked for processing so we
-	     * free our descriptor and update statistics 
-	     */
-
-	    writeb(RX_OWN, &rmdp->u.s.status);
-	    dev->last_rx = jiffies;
-	    p->stats.rx_packets++;
-	    p->stats.rx_bytes += len;
-
-
-	    p->rmdnum++;
-	    p->rmdnum %= RMDNUM;
-
-	    rmdp = p->rmdhead + p->rmdnum;
-	}
-    }
-} /* End of SK_rxintr() */
-
-
-/*-
- * Function       : SK_close
- * Author         : Patrick J.D. Weichmann
- * Date Created   : 94/05/26
- *
- * Description    : close gets called from dev_close() and should
- *                  deinstall the card (free_irq, mem etc).
- *
- * Parameters     : I : struct net_device *dev - our device structure
- * Return Value   : 0 - closed device driver
- * Errors         : None
- * Globals        : None
- * Update History :
- *     YY/MM/DD  uid  Description
--*/
-
-/* I have tried to set BOOT_ROM on and RAM off but then, after a 'ifconfig
- * down' the system stops. So I don't shut set card to init state.
- */
-
-static int SK_close(struct net_device *dev)
-{
-
-    PRINTK(("## %s: SK_close(). CSR0: %#06x\n", 
-           SK_NAME, SK_read_reg(CSR0)));
-
-    netif_stop_queue(dev);	   /* Transmitter busy */
-
-    printk("%s: Shutting %s down CSR0 %#06x\n", dev->name, SK_NAME, 
-           (int) SK_read_reg(CSR0));
-
-    SK_write_reg(CSR0, CSR0_STOP); /* STOP the LANCE */
-
-    free_irq(dev->irq, dev);      /* Free IRQ */
-
-    return 0; /* always succeed */
-    
-} /* End of SK_close() */
-
-
-/*-
- * Function       : SK_get_stats
- * Author         : Patrick J.D. Weichmann
- * Date Created   : 94/05/26
- *
- * Description    : Return current status structure to upper layers.
- *                  It is called by sprintf_stats (dev.c).
- *
- * Parameters     : I : struct net_device *dev   - our device structure
- * Return Value   : struct net_device_stats * - our current statistics
- * Errors         : None
- * Side Effects   : None
- * Update History :
- *     YY/MM/DD  uid  Description
--*/
-
-static struct net_device_stats *SK_get_stats(struct net_device *dev)
-{
-
-    struct priv *p = netdev_priv(dev);
-
-    PRINTK(("## %s: SK_get_stats(). CSR0: %#06x\n", 
-           SK_NAME, SK_read_reg(CSR0)));
-
-    return &p->stats;             /* Return Device status */
-
-} /* End of SK_get_stats() */
-
-
-/*-
- * Function       : set_multicast_list
- * Author         : Patrick J.D. Weichmann
- * Date Created   : 94/05/26
- *
- * Description    : This function gets called when a program performs
- *                  a SIOCSIFFLAGS call. Ifconfig does this if you call
- *                  'ifconfig [-]allmulti' which enables or disables the
- *                  Promiscuous mode.
- *                  Promiscuous mode is when the Network card accepts all
- *                  packets, not only the packets which match our MAC 
- *                  Address. It is useful for writing a network monitor,
- *                  but it is also a security problem. You have to remember
- *                  that all information on the net is not encrypted.
- *
- * Parameters     : I : struct net_device *dev - SK_G16 device Structure
- * Return Value   : None
- * Errors         : None
- * Globals        : None
- * Update History :
- *     YY/MM/DD  uid  Description
- *     95/10/18  ACox  New multicast calling scheme
--*/
-
-
-/* Set or clear the multicast filter for SK_G16.
- */
-
-static void set_multicast_list(struct net_device *dev)
-{
-
-    if (dev->flags&IFF_PROMISC)
-    {
-	/* Reinitialize LANCE with MODE_PROM set */
-	SK_lance_init(dev, MODE_PROM);
-    }
-    else if (dev->mc_count==0 && !(dev->flags&IFF_ALLMULTI))
-    {
-	/* Reinitialize LANCE without MODE_PROM */
-	SK_lance_init(dev, MODE_NORMAL);
-    }
-    else
-    {
-	/* Multicast with logical address filter on */
-	/* Reinitialize LANCE without MODE_PROM */
-	SK_lance_init(dev, MODE_NORMAL);
-	
-	/* Not implemented yet. */
-    }
-} /* End of set_multicast_list() */
-
-
-
-/*-
- * Function       : SK_rom_addr
- * Author         : Patrick J.D. Weichmann
- * Date Created   : 94/06/01
- *
- * Description    : Try to find a Boot_ROM at all possible locations
- *
- * Parameters     : None
- * Return Value   : Address where Boot_ROM is
- * Errors         : 0 - Did not find Boot_ROM
- * Globals        : None
- * Update History :
- *     YY/MM/DD  uid  Description
--*/
-
-unsigned int __init SK_rom_addr(void)
-{
-    int i,j;
-    int rom_found = 0;
-    unsigned int rom_location[] = SK_BOOT_ROM_LOCATIONS;
-    unsigned char rom_id[] = SK_BOOT_ROM_ID;
-    unsigned char test_byte;
-
-    /* Autodetect Boot_ROM */
-    PRINTK(("## %s: Autodetection of Boot_ROM\n", SK_NAME));
-
-    for (i = 0; (rom_location[i] != 0) && (rom_found == 0); i++)
-    {
-	
-	PRINTK(("##   Trying ROM location %#08x", rom_location[i]));
-	
-	rom_found = 1; 
-	for (j = 0; j < 6; j++)
-	{
-	    test_byte = readb(rom_location[i]+j);
-	    PRINTK((" %02x ", *test_byte));
-
-	    if(test_byte != rom_id[j])
-	    {
-		rom_found = 0;
-	    } 
-	}
-	PRINTK(("\n"));
-    }
-
-    if (rom_found == 1)
-    {
-	PRINTK(("## %s: Boot_ROM found at %#08x\n", 
-               SK_NAME, rom_location[(i-1)]));
-
-	return (rom_location[--i]);
-    }
-    else
-    {
-	PRINTK(("%s: No Boot_ROM found\n", SK_NAME));
-	return 0;
-    }
-} /* End of SK_rom_addr() */
-
-
-
-/* LANCE access functions 
- *
- * ! CSR1-3 can only be accessed when in CSR0 the STOP bit is set !
- */
-
-
-/*-
- * Function       : SK_reset_board
- *
- * Author         : Patrick J.D. Weichmann
- *
- * Date Created   : 94/05/25
- *
- * Description    : This function resets SK_G16 and all components, but
- *                  POS registers are not changed
- *
- * Parameters     : None
- * Return Value   : None
- * Errors         : None
- * Globals        : SK_RAM *board - SK_RAM structure pointer
- *
- * Update History :
- *     YY/MM/DD  uid  Description
--*/
-
-void SK_reset_board(void)
-{
-    writeb(0x00, SK_PORT);       /* Reset active */
-    mdelay(5);                /* Delay min 5ms */
-    writeb(SK_RESET, SK_PORT);   /* Set back to normal operation */
-
-} /* End of SK_reset_board() */
-
-
-/*-
- * Function       : SK_set_RAP
- * Author         : Patrick J.D. Weichmann
- * Date Created   : 94/05/25
- *
- * Description    : Set LANCE Register Address Port to register
- *                  for later data transfer.
- *
- * Parameters     : I : reg_number - which CSR to read/write from/to
- * Return Value   : None
- * Errors         : None
- * Globals        : SK_RAM *board - SK_RAM structure pointer
- * Update History :
- *     YY/MM/DD  uid  Description
--*/
-
-void SK_set_RAP(int reg_number)
-{
-    writew(reg_number, SK_IOREG);
-    writeb(SK_RESET | SK_RAP | SK_WREG, SK_PORT);
-    writeb(SK_DOIO, SK_IOCOM);
-
-    while (readb(SK_PORT) & SK_IORUN) 
-	barrier();
-} /* End of SK_set_RAP() */
-
-
-/*-
- * Function       : SK_read_reg
- * Author         : Patrick J.D. Weichmann
- * Date Created   : 94/05/25
- *
- * Description    : Set RAP and read data from a LANCE CSR register
- *
- * Parameters     : I : reg_number - which CSR to read from
- * Return Value   : Register contents
- * Errors         : None
- * Globals        : SK_RAM *board - SK_RAM structure pointer
- * Update History :
- *     YY/MM/DD  uid  Description
--*/
-
-int SK_read_reg(int reg_number)
-{
-    SK_set_RAP(reg_number);
-
-    writeb(SK_RESET | SK_RDATA | SK_RREG, SK_PORT);
-    writeb(SK_DOIO, SK_IOCOM);
-
-    while (readb(SK_PORT) & SK_IORUN)
-	barrier();
-    return (readw(SK_IOREG));
-
-} /* End of SK_read_reg() */
-
-
-/*-
- * Function       : SK_rread_reg
- * Author         : Patrick J.D. Weichmann
- * Date Created   : 94/05/28
- *
- * Description    : Read data from preseted register.
- *                  This function requires that you know which
- *                  Register is actually set. Be aware that CSR1-3
- *                  can only be accessed when in CSR0 STOP is set.
- *
- * Return Value   : Register contents
- * Errors         : None
- * Globals        : SK_RAM *board - SK_RAM structure pointer
- * Update History :
- *     YY/MM/DD  uid  Description
--*/
-
-int SK_rread_reg(void)
-{
-    writeb(SK_RESET | SK_RDATA | SK_RREG, SK_PORT);
-
-    writeb(SK_DOIO, SK_IOCOM);
-
-    while (readb(SK_PORT) & SK_IORUN)
-	barrier();
-    return (readw(SK_IOREG));
-
-} /* End of SK_rread_reg() */
-
-
-/*-
- * Function       : SK_write_reg
- * Author         : Patrick J.D. Weichmann
- * Date Created   : 94/05/25
- *
- * Description    : This function sets the RAP then fills in the
- *                  LANCE I/O Reg and starts Transfer to LANCE.
- *                  It waits until transfer has ended which is max. 7 ms
- *                  and then it returns.
- *
- * Parameters     : I : reg_number - which CSR to write to
- *                  I : value      - what value to fill into register 
- * Return Value   : None
- * Errors         : None
- * Globals        : SK_RAM *board - SK_RAM structure pointer
- * Update History :
- *     YY/MM/DD  uid  Description
--*/
-
-void SK_write_reg(int reg_number, int value)
-{
-    SK_set_RAP(reg_number);
-
-    writew(value, SK_IOREG);
-    writeb(SK_RESET | SK_RDATA | SK_WREG, SK_PORT);
-    writeb(SK_DOIO, SK_IOCOM);
-
-    while (readb(SK_PORT) & SK_IORUN)
-	barrier();
-} /* End of SK_write_reg */
-
-
-
-/* 
- * Debugging functions
- * -------------------
- */
-
-/*-
- * Function       : SK_print_pos
- * Author         : Patrick J.D. Weichmann
- * Date Created   : 94/05/25
- *
- * Description    : This function prints out the 4 POS (Programmable
- *                  Option Select) Registers. Used mainly to debug operation.
- *
- * Parameters     : I : struct net_device *dev - SK_G16 device structure
- *                  I : char * - Text which will be printed as title
- * Return Value   : None
- * Errors         : None
- * Update History :
- *     YY/MM/DD  uid  Description
--*/
-
-void SK_print_pos(struct net_device *dev, char *text)
-{
-    int ioaddr = dev->base_addr;
-
-    unsigned char pos0 = inb(SK_POS0),
-		  pos1 = inb(SK_POS1),
-		  pos2 = inb(SK_POS2),
-		  pos3 = inb(SK_POS3),
-		  pos4 = inb(SK_POS4);
-
-
-    printk("## %s: %s.\n"
-           "##   pos0=%#4x pos1=%#4x pos2=%#04x pos3=%#08x pos4=%#04x\n",
-           SK_NAME, text, pos0, pos1, pos2, (pos3<<14), pos4);
-
-} /* End of SK_print_pos() */
-
-
-
-/*-
- * Function       : SK_print_dev
- * Author         : Patrick J.D. Weichmann
- * Date Created   : 94/05/25
- *
- * Description    : This function simply prints out the important fields
- *                  of the device structure.
- *
- * Parameters     : I : struct net_device *dev  - SK_G16 device structure
- *                  I : char *text - Title for printing
- * Return Value   : None
- * Errors         : None
- * Update History :
- *     YY/MM/DD  uid  Description
--*/
-
-void SK_print_dev(struct net_device *dev, char *text)
-{
-    if (dev == NULL)
-    {
-	printk("## %s: Device Structure. %s\n", SK_NAME, text);
-	printk("## DEVICE == NULL\n");
-    }
-    else
-    {
-	printk("## %s: Device Structure. %s\n", SK_NAME, text);
-	printk("## Device Name: %s Base Address: %#06lx IRQ: %d\n", 
-               dev->name, dev->base_addr, dev->irq);
-	       
-	printk("## next device: %#08x init function: %#08x\n", 
-              (int) dev->next, (int) dev->init);
-    }
-
-} /* End of SK_print_dev() */
-
-
-
-/*-
- * Function       : SK_print_ram
- * Author         : Patrick J.D. Weichmann
- * Date Created   : 94/06/02
- *
- * Description    : This function is used to check how are things set up
- *                  in the 16KB RAM. Also the pointers to the receive and 
- *                  transmit descriptor rings and rx and tx buffers locations.
- *                  It contains a minor bug in printing, but has no effect to the values
- *                  only newlines are not correct.
- *
- * Parameters     : I : struct net_device *dev - SK_G16 device structure
- * Return Value   : None
- * Errors         : None
- * Globals        : None
- * Update History :
- *     YY/MM/DD  uid  Description
--*/
-
-void __init SK_print_ram(struct net_device *dev)
-{
-
-    int i;    
-    struct priv *p = netdev_priv(dev);
-
-    printk("## %s: RAM Details.\n"
-           "##   RAM at %#08x tmdhead: %#08x rmdhead: %#08x initblock: %#08x\n",
-           SK_NAME, 
-           (unsigned int) p->ram,
-           (unsigned int) p->tmdhead, 
-           (unsigned int) p->rmdhead, 
-           (unsigned int) &(p->ram)->ib);
-           
-    printk("##   ");
-
-    for(i = 0; i < TMDNUM; i++)
-    {
-           if (!(i % 3)) /* Every third line do a newline */
-           {
-               printk("\n##   ");
-           }
-        printk("tmdbufs%d: %#08x ", (i+1), (int) p->tmdbufs[i]);
-    }
-    printk("##   ");
-
-    for(i = 0; i < RMDNUM; i++)
-    {
-         if (!(i % 3)) /* Every third line do a newline */
-           {
-               printk("\n##   ");
-           }
-        printk("rmdbufs%d: %#08x ", (i+1), (int) p->rmdbufs[i]);
-    } 
-    printk("\n");
-
-} /* End of SK_print_ram() */
-
diff --git a/drivers/net/sk_g16.h b/drivers/net/sk_g16.h
deleted file mode 100644
--- a/drivers/net/sk_g16.h
+++ /dev/null
@@ -1,165 +0,0 @@
-/*-
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- * Module         : sk_g16.h
- * Version        : $Revision$  
- *
- * Author         : M.Hipp (mhipp@student.uni-tuebingen.de)
- * changes by     : Patrick J.D. Weichmann
- *
- * Date Created   : 94/05/25
- *
- * Description    : In here are all necessary definitions of  
- *                  the am7990 (LANCE) chip used for writing a
- *                  network device driver which uses this chip 
- *
- * $Log$
--*/
-
-#ifndef SK_G16_H
-
-#define SK_G16_H
-
-
-/*
- * 	Control and Status Register 0 (CSR0) bit definitions
- *
- * (R=Readable) (W=Writeable) (S=Set on write) (C-Clear on write)
- *
- */
-
-#define CSR0_ERR	0x8000	/* Error summary (R) */
-#define CSR0_BABL	0x4000	/* Babble transmitter timeout error (RC) */
-#define CSR0_CERR	0x2000	/* Collision Error (RC) */
-#define CSR0_MISS	0x1000	/* Missed packet (RC) */
-#define CSR0_MERR	0x0800	/* Memory Error  (RC) */ 
-#define CSR0_RINT	0x0400	/* Receiver Interrupt (RC) */
-#define CSR0_TINT       0x0200	/* Transmit Interrupt (RC) */ 
-#define CSR0_IDON	0x0100	/* Initialization Done (RC) */
-#define CSR0_INTR	0x0080	/* Interrupt Flag (R) */
-#define CSR0_INEA	0x0040	/* Interrupt Enable (RW) */
-#define CSR0_RXON	0x0020	/* Receiver on (R) */
-#define CSR0_TXON	0x0010  /* Transmitter on (R) */
-#define CSR0_TDMD	0x0008	/* Transmit Demand (RS) */
-#define CSR0_STOP	0x0004 	/* Stop (RS) */
-#define CSR0_STRT	0x0002	/* Start (RS) */
-#define CSR0_INIT	0x0001	/* Initialize (RS) */
-
-#define CSR0_CLRALL     0x7f00  /* mask for all clearable bits */
-
-/*
- *    Control and Status Register 3 (CSR3) bit definitions
- *
- */
-
-#define CSR3_BSWAP	0x0004	/* Byte Swap (RW) */
-#define CSR3_ACON	0x0002  /* ALE Control (RW) */
-#define CSR3_BCON	0x0001	/* Byte Control (RW) */
-
-/*
- *	Initialization Block Mode operation Bit Definitions.
- */
-
-#define MODE_PROM	0x8000	/* Promiscuous Mode */
-#define MODE_INTL	0x0040  /* Internal Loopback */
-#define MODE_DRTY	0x0020  /* Disable Retry */ 
-#define MODE_COLL	0x0010	/* Force Collision */
-#define MODE_DTCR	0x0008	/* Disable Transmit CRC) */
-#define MODE_LOOP	0x0004	/* Loopback */
-#define MODE_DTX	0x0002	/* Disable the Transmitter */ 
-#define MODE_DRX	0x0001  /* Disable the Receiver */
-
-#define MODE_NORMAL 	0x0000  /* Normal operation mode */
-
-/*
- * 	Receive message descriptor status bit definitions.
- */
-
-#define RX_OWN		0x80	/* Owner bit 0 = host, 1 = lance */
-#define RX_ERR		0x40	/* Error Summary */
-#define RX_FRAM		0x20	/* Framing Error */
-#define RX_OFLO		0x10	/* Overflow Error */
-#define RX_CRC		0x08	/* CRC Error */ 
-#define RX_BUFF		0x04	/* Buffer Error */
-#define RX_STP		0x02	/* Start of Packet */
-#define RX_ENP		0x01	/* End of Packet */
-
-
-/*
- *	Transmit message descriptor status bit definitions.
- */
-
-#define TX_OWN		0x80	/* Owner bit 0 = host, 1 = lance */
-#define TX_ERR		0x40    /* Error Summary */
-#define TX_MORE		0x10	/* More the 1 retry needed to Xmit */
-#define TX_ONE		0x08	/* One retry needed to Xmit */
-#define TX_DEF		0x04	/* Deferred */
-#define TX_STP 		0x02	/* Start of Packet */
-#define TX_ENP		0x01	/* End of Packet */
-
-/*
- *      Transmit status (2) (valid if TX_ERR == 1)
- */
-
-#define TX_BUFF 	0x8000  /* Buffering error (no ENP) */
-#define TX_UFLO 	0x4000  /* Underflow (late memory) */
-#define TX_LCOL 	0x1000  /* Late collision */
-#define TX_LCAR 	0x0400  /* Loss of Carrier */
-#define TX_RTRY 	0x0200  /* Failed after 16 retransmissions  */
-#define TX_TDR          0x003f  /* Time-domain-reflectometer-value */
-
-
-/* 
- * Structures used for Communication with the LANCE 
- */
-
-/* LANCE Initialize Block */
-
-struct init_block 
-{
-  unsigned short mode;     /* Mode Register */
-  unsigned char  paddr[6]; /* Physical Address (MAC) */
-  unsigned char  laddr[8]; /* Logical Filter Address (not used) */
-  unsigned int   rdrp;     /* Receive Descriptor Ring pointer */
-  unsigned int   tdrp;     /* Transmit Descriptor Ring pointer */
-};
-
-
-/* Receive Message Descriptor Entry */
-
-struct rmd 
-{ 
-  union
-  {
-    unsigned long buffer;     /* Address of buffer */
-    struct 
-    {
-      unsigned char unused[3]; 
-      unsigned volatile char status;   /* Status Bits */
-    } s;
-  } u;
-  volatile short blen;        /* Buffer Length (two's complement) */
-  unsigned short mlen;        /* Message Byte Count */
-};
-
-
-/* Transmit Message Descriptor Entry */
-
-struct tmd   
-{
-  union 
-  {
-    unsigned long  buffer;    /* Address of buffer */
-    struct 
-    {
-      unsigned char unused[3];
-      unsigned volatile char status;   /* Status Bits */
-    } s;
-  } u;
-  unsigned short blen;             /* Buffer Length (two's complement) */
-  unsigned volatile short status2; /* Error Status Bits */
-};
-
-#endif /* End of SK_G16_H */
diff --git a/drivers/net/skfp/Makefile b/drivers/net/skfp/Makefile
--- a/drivers/net/skfp/Makefile
+++ b/drivers/net/skfp/Makefile
@@ -6,8 +6,8 @@ obj-$(CONFIG_SKFP) += skfp.o
 
 skfp-objs :=  skfddi.o    hwmtm.o    fplustm.o  smt.o      cfm.o     \
               ecm.o       pcmplc.o   pmf.o      queue.o    rmt.o     \
-	      smtdef.o    smtinit.o  smttimer.o srf.o      lnkstat.o \
-              smtparse.o  hwt.o      drvfbi.o   ess.o
+	      smtdef.o    smtinit.o  smttimer.o srf.o      hwt.o     \
+	      drvfbi.o   ess.o
 
 # NOTE:
 #   Compiling this driver produces some warnings (and some more are 
diff --git a/drivers/net/skfp/drvfbi.c b/drivers/net/skfp/drvfbi.c
--- a/drivers/net/skfp/drvfbi.c
+++ b/drivers/net/skfp/drvfbi.c
@@ -105,8 +105,8 @@ extern int AIX_vpdReadByte() ;
 #endif
 
 
-/* Prototypes of local functions. */
-void smt_stop_watchdog(struct s_smc *smc);
+/* Prototype of a local function. */
+static void smt_stop_watchdog(struct s_smc *smc);
 
 #ifdef MCA
 static int read_card_id() ;
@@ -631,7 +631,7 @@ void plc_clear_irq(struct s_smc *smc, in
  *	LED_Y_OFF	just switch yellow LED off
  *	LED_Y_ON	just switch yello LED on
  */
-void led_indication(struct s_smc *smc, int led_event)
+static void led_indication(struct s_smc *smc, int led_event)
 {
 	/* use smc->hw.mac_ring_is_up == TRUE 
 	 * as indication for Ring Operational
@@ -764,122 +764,6 @@ void llc_recover_tx(struct s_smc *smc)
 #endif
 }
 
-/*--------------------------- DMA init ----------------------------*/
-#ifdef	ISA
-
-/*
- * init DMA
- */
-void init_dma(struct s_smc *smc, int dma)
-{
-	SK_UNUSED(smc) ;
-
-	/*
-	 * set cascade mode,
-	 * clear mask bit (enable DMA cannal)
-	 */
-	if (dma > 3) {
-		outp(0xd6,(dma & 0x03) | 0xc0) ;
-		outp(0xd4, dma & 0x03) ;
-	}
-	else {
-		outp(0x0b,(dma & 0x03) | 0xc0) ;
-		outp(0x0a,dma & 0x03) ;
-	}
-}
-
-/*
- * disable DMA
- */
-void dis_dma(struct s_smc *smc, int dma)
-{
-	SK_UNUSED(smc) ;
-
-	/*
-	 * set mask bit (disable DMA cannal)
-	 */
-	if (dma > 3) {
-		outp(0xd4,(dma & 0x03) | 0x04) ;
-	}
-	else {
-		outp(0x0a,(dma & 0x03) | 0x04) ;
-	}
-}
-
-#endif	/* ISA */
-
-#ifdef	EISA
-
-/*arrays with io addresses of dma controller length and address registers*/
-static const int cntr[8] = { 0x001,0x003,0x005,0x007,0,0x0c6,0x0ca,0x0ce } ;
-static const int base[8] = { 0x000,0x002,0x004,0x006,0,0x0c4,0x0c8,0x0cc } ;
-static const int page[8] = { 0x087,0x083,0x081,0x082,0,0x08b,0x089,0x08a } ;
-
-void init_dma(struct s_smc *smc, int dma)
-{
-	/*
-	 * extended mode register
-	 * 32 bit IO
-	 * type c
-	 * TC output
-	 * disable stop
-	 */
-
-	/* mode read (write) demand */
-	smc->hw.dma_rmode = (dma & 3) | 0x08 | 0x0 ;
-	smc->hw.dma_wmode = (dma & 3) | 0x04 | 0x0 ;
-
-	/* 32 bit IO's, burst DMA mode (type "C") */
-	smc->hw.dma_emode = (dma & 3) | 0x08 | 0x30 ;
-
-	outp((dma < 4) ? 0x40b : 0x4d6,smc->hw.dma_emode) ;
-
-	/* disable chaining */
-	outp((dma < 4) ? 0x40a : 0x4d4,(dma&3)) ;
-
-	/*load dma controller addresses for fast access during set dma*/
-	smc->hw.dma_base_word_count = cntr[smc->hw.dma];
-	smc->hw.dma_base_address = base[smc->hw.dma];
-	smc->hw.dma_base_address_page = page[smc->hw.dma];
-
-}
-
-void dis_dma(struct s_smc *smc, int dma)
-{
-	SK_UNUSED(smc) ;
-
-	outp((dma < 4) ? 0x0a : 0xd4,(dma&3)|4) ;/* mask bit */
-}
-#endif	/* EISA */
-
-#ifdef	MCA
-void init_dma(struct s_smc *smc, int dma)
-{
-	SK_UNUSED(smc) ;
-	SK_UNUSED(dma) ;
-}
-
-void dis_dma(struct s_smc *smc, int dma)
-{
-	SK_UNUSED(smc) ;
-	SK_UNUSED(dma) ;
-}
-#endif
-
-#ifdef	PCI
-void init_dma(struct s_smc *smc, int dma)
-{
-	SK_UNUSED(smc) ;
-	SK_UNUSED(dma) ;
-}
-
-void dis_dma(struct s_smc *smc, int dma)
-{
-	SK_UNUSED(smc) ;
-	SK_UNUSED(dma) ;
-}
-#endif
-
 #ifdef MULT_OEM
 static int is_equal_num(char comp1[], char comp2[], int num)
 {
@@ -1407,7 +1291,7 @@ void smt_start_watchdog(struct s_smc *sm
 #endif	/* DEBUG */
 }
 
-void smt_stop_watchdog(struct s_smc *smc)
+static void smt_stop_watchdog(struct s_smc *smc)
 {
 	SK_UNUSED(smc) ;	/* Make LINT happy. */
 #ifndef	DEBUG
@@ -1422,104 +1306,6 @@ void smt_stop_watchdog(struct s_smc *smc
 }
 
 #ifdef	PCI
-static char get_rom_byte(struct s_smc *smc, u_short addr)
-{
-	GET_PAGE(addr) ;
-	return (READ_PROM(ADDR(B2_FDP))) ;
-}
-
-/*
- * ROM image defines
- */
-#define	ROM_SIG_1	0
-#define ROM_SIG_2	1
-#define PCI_DATA_1	0x18
-#define PCI_DATA_2	0x19
-
-/*
- * PCI data structure defines
- */
-#define	VPD_DATA_1	0x08
-#define	VPD_DATA_2	0x09
-#define IMAGE_LEN_1	0x10
-#define IMAGE_LEN_2	0x11
-#define	CODE_TYPE	0x14
-#define	INDICATOR	0x15
-
-/*
- *	BEGIN_MANUAL_ENTRY(mac_drv_vpd_read)
- *	mac_drv_vpd_read(smc,buf,size,image)
- *
- * function	DOWNCALL	(FDDIWARE)
- *		reads the VPD data of the FPROM and writes it into the
- *		buffer
- *
- * para	buf	points to the buffer for the VPD data
- *	size	size of the VPD data buffer
- *	image	boot image; code type of the boot image
- *		image = 0	Intel x86, PC-AT compatible
- *			1	OPENBOOT standard for PCI
- *			2-FF	reserved
- *
- * returns	len	number of VPD data bytes read form the FPROM
- *		<0	number of read bytes
- *		>0	error: data invalid
- *
- *	END_MANUAL_ENTRY
- */
-int mac_drv_vpd_read(struct s_smc *smc, char *buf, int size, char image)
-{
-	u_short	ibase ;
-	u_short pci_base ;
-	u_short vpd ;
-	int	len ;
-
-	len = 0 ;
-	ibase = 0 ;
-	/*
-	 * as long images defined
-	 */
-	while (get_rom_byte(smc,ibase+ROM_SIG_1) == 0x55 &&
-		(u_char) get_rom_byte(smc,ibase+ROM_SIG_2) == 0xaa) {
-		/*
-		 * get the pointer to the PCI data structure
-		 */
-		pci_base = ibase + get_rom_byte(smc,ibase+PCI_DATA_1) +
-				(get_rom_byte(smc,ibase+PCI_DATA_2) << 8) ;
-
-		if (image == get_rom_byte(smc,pci_base+CODE_TYPE)) {
-			/*
-			 * we have the right image, read the VPD data
-			 */
-			vpd = ibase + get_rom_byte(smc,pci_base+VPD_DATA_1) +
-				(get_rom_byte(smc,pci_base+VPD_DATA_2) << 8) ;
-			if (vpd == ibase) {
-				break ;		/* no VPD data */
-			}
-			for (len = 0; len < size; len++,buf++,vpd++) {
-				*buf = get_rom_byte(smc,vpd) ;
-			}
-			break ;
-		}
-		else {
-			/*
-			 * try the next image
-			 */
-			if (get_rom_byte(smc,pci_base+INDICATOR) & 0x80) {
-				break ;		/* this was the last image */
-			}
-			ibase = ibase + get_rom_byte(smc,ibase+IMAGE_LEN_1) +
-				(get_rom_byte(smc,ibase+IMAGE_LEN_2) << 8) ;
-		}
-	}
-
-	return(len) ;
-}
-
-void mac_drv_pci_fix(struct s_smc *smc, u_long fix_value)
-{
-	smc->hw.pci_fix_value = fix_value ;
-}
 
 void mac_do_pci_fix(struct s_smc *smc)
 {
diff --git a/drivers/net/skfp/ess.c b/drivers/net/skfp/ess.c
--- a/drivers/net/skfp/ess.c
+++ b/drivers/net/skfp/ess.c
@@ -102,7 +102,7 @@ void ess_timer_poll(struct s_smc *smc);
 void ess_para_change(struct s_smc *smc);
 int ess_raf_received_pack(struct s_smc *smc, SMbuf *mb, struct smt_header *sm,
 			  int fs);
-int process_bw_alloc(struct s_smc *smc, long int payload, long int overhead);
+static int process_bw_alloc(struct s_smc *smc, long int payload, long int overhead);
 
 
 /*
@@ -375,7 +375,7 @@ int ess_raf_received_pack(struct s_smc *
  * determines the synchronous bandwidth, set the TSYNC register and the
  * mib variables SBAPayload, SBAOverhead and fddiMACT-NEG.
  */
-int process_bw_alloc(struct s_smc *smc, long int payload, long int overhead)
+static int process_bw_alloc(struct s_smc *smc, long int payload, long int overhead)
 {
 	/*
 	 * determine the synchronous bandwidth (sync_bw) in bytes per T-NEG,
diff --git a/drivers/net/skfp/fplustm.c b/drivers/net/skfp/fplustm.c
--- a/drivers/net/skfp/fplustm.c
+++ b/drivers/net/skfp/fplustm.c
@@ -1117,30 +1117,6 @@ void mac_clear_multicast(struct s_smc *s
 /*
 	BEGIN_MANUAL_ENTRY(if,func;others;2)
 
-	int mac_set_func_addr(smc,f_addr)
-	struct s_smc *smc ;
-	u_long f_addr ;
-
-Function	DOWNCALL	(SMT, fplustm.c)
-		Set a Token-Ring functional address, the address will
-		be activated after calling mac_update_multicast()
-
-Para	f_addr	functional bits in non-canonical format
-
-Returns	0: always success
-
-	END_MANUAL_ENTRY()
- */
-int mac_set_func_addr(struct s_smc *smc, u_long f_addr)
-{
-	smc->hw.fp.func_addr = f_addr ;
-	return(0) ;
-}
-
-
-/*
-	BEGIN_MANUAL_ENTRY(if,func;others;2)
-
 	int mac_add_multicast(smc,addr,can)
 	struct s_smc *smc ;
 	struct fddi_addr *addr ;
@@ -1203,52 +1179,6 @@ int mac_add_multicast(struct s_smc *smc,
 }
 
 /*
-	BEGIN_MANUAL_ENTRY(if,func;others;2)
-
-	void mac_del_multicast(smc,addr,can)
-	struct s_smc *smc ;
-	struct fddi_addr *addr ;
-	int can ;
-
-Function	DOWNCALL	(SMT, fplustm.c)
-		Delete an entry from the multicast table
-
-Para	addr	pointer to a multicast address
-	can	= 0:	the multicast address has the physical format
-		= 1:	the multicast address has the canonical format
-		| 0x80	permanent
-
-	END_MANUAL_ENTRY()
- */
-void mac_del_multicast(struct s_smc *smc, struct fddi_addr *addr, int can)
-{
-	SK_LOC_DECL(struct fddi_addr,own) ;
-	struct s_fpmc	*tb ;
-
-	if (!(tb = mac_get_mc_table(smc,addr,&own,1,can & ~0x80)))
-		return ;
-	/*
-	 * permanent addresses must be deleted with perm bit
-	 * and vice versa
-	 */
-	if (( tb->perm &&  (can & 0x80)) ||
-	    (!tb->perm && !(can & 0x80))) {
-		/*
-		 * delete it
-		 */
-		if (tb->n) {
-			tb->n-- ;
-			if (tb->perm) {
-				smc->hw.fp.smt_slots_used-- ;
-			}
-			else {
-				smc->hw.fp.os_slots_used-- ;
-			}
-		}
-	}
-}
-
-/*
  * mode
  */
 
diff --git a/drivers/net/skfp/h/cmtdef.h b/drivers/net/skfp/h/cmtdef.h
--- a/drivers/net/skfp/h/cmtdef.h
+++ b/drivers/net/skfp/h/cmtdef.h
@@ -507,7 +507,6 @@ void pcm_status_state(struct s_smc *smc,
 		      int *remote, int *mac);
 void plc_config_mux(struct s_smc *smc, int mux);
 void sm_lem_evaluate(struct s_smc *smc);
-void smt_clear_una_dna(struct s_smc *smc);
 void mac_update_counter(struct s_smc *smc);
 void sm_pm_ls_latch(struct s_smc *smc, int phy, int on_off);
 void sm_ma_control(struct s_smc *smc, int mode);
@@ -541,11 +540,9 @@ void smt_timer_poll(struct s_smc *smc);
 u_long smt_get_time(void);
 u_long smt_get_tid(struct s_smc *smc);
 void smt_timer_done(struct s_smc *smc);
-void smt_set_defaults(struct s_smc *smc);
 void smt_fixup_mib(struct s_smc *smc);
 void smt_reset_defaults(struct s_smc *smc, int level);
 void smt_agent_task(struct s_smc *smc);
-void smt_please_reconnect(struct s_smc *smc, int reconn_time);
 int smt_check_para(struct s_smc *smc, struct smt_header *sm,
 		   const u_short list[]);
 void driver_get_bia(struct s_smc *smc, struct fddi_addr *bia_addr);
@@ -568,7 +565,6 @@ int pcm_get_s_port(struct s_smc *smc);
 int pcm_rooted_station(struct s_smc *smc);
 int cfm_get_mac_input(struct s_smc *smc);
 int cfm_get_mac_output(struct s_smc *smc);
-int port_to_mib(struct s_smc *smc, int p);
 int cem_build_path(struct s_smc *smc, char *to, int path_index);
 int sm_mac_get_tx_state(struct s_smc *smc);
 char *get_pcmstate(struct s_smc *smc, int np);
@@ -580,8 +576,6 @@ void smt_send_frame(struct s_smc *smc, S
 void smt_set_timestamp(struct s_smc *smc, u_char *p);
 void mac_set_rx_mode(struct s_smc *smc,	int mode);
 int mac_add_multicast(struct s_smc *smc, struct fddi_addr *addr, int can);
-int mac_set_func_addr(struct s_smc *smc, u_long f_addr);
-void mac_del_multicast(struct s_smc *smc, struct fddi_addr *addr, int can);
 void mac_update_multicast(struct s_smc *smc);
 void mac_clear_multicast(struct s_smc *smc);
 void set_formac_tsync(struct s_smc *smc, long sync_bw);
@@ -599,7 +593,6 @@ void plc_irq(struct s_smc *smc,	int np,	
 int smt_set_mac_opvalues(struct s_smc *smc);
 
 #ifdef TAG_MODE
-void mac_drv_pci_fix(struct s_smc *smc, u_long fix_value);
 void mac_do_pci_fix(struct s_smc *smc);
 void mac_drv_clear_tx_queue(struct s_smc *smc);
 void mac_drv_repair_descr(struct s_smc *smc);
diff --git a/drivers/net/skfp/h/hwmtm.h b/drivers/net/skfp/h/hwmtm.h
--- a/drivers/net/skfp/h/hwmtm.h
+++ b/drivers/net/skfp/h/hwmtm.h
@@ -262,31 +262,6 @@ struct os_debug {
 					(smc)->hw.fp.tx_q[queue].tx_curr_put
 
 /*
- *	BEGIN_MANUAL_ENTRY(HWM_TX_CHECK)
- *	void HWM_TX_CHECK(smc,frame_status,low_water)
- *
- * function	MACRO		(hardware module, hwmtm.h)
- *		This macro is invoked by the OS-specific before it left it's
- *		driver_send function. This macro calls mac_drv_clear_txd
- *		if the free TxDs of the current transmit queue is equal or
- *		lower than the given low water mark.
- *
- * para	frame_status	status of the frame, see design description
- *	low_water	low water mark of free TxD's
- *
- *	END_MANUAL_ENTRY
- */
-#ifndef HWM_NO_FLOW_CTL
-#define	HWM_TX_CHECK(smc,frame_status,low_water) {\
-	if ((low_water)>=(smc)->hw.fp.tx_q[(frame_status)&QUEUE_A0].tx_free) {\
-		mac_drv_clear_txd(smc) ;\
-	}\
-}
-#else
-#define	HWM_TX_CHECK(smc,frame_status,low_water)	mac_drv_clear_txd(smc)
-#endif
-
-/*
  *	BEGIN_MANUAL_ENTRY(HWM_GET_RX_FRAG_LEN)
  *	int HWM_GET_RX_FRAG_LEN(rxd)
  *
diff --git a/drivers/net/skfp/h/osdef1st.h b/drivers/net/skfp/h/osdef1st.h
--- a/drivers/net/skfp/h/osdef1st.h
+++ b/drivers/net/skfp/h/osdef1st.h
@@ -20,6 +20,8 @@
 // HWM (HardWare Module) Definitions
 // -----------------------
 
+#include <asm/byteorder.h>
+
 #ifdef __LITTLE_ENDIAN
 #define LITTLE_ENDIAN
 #else
diff --git a/drivers/net/skfp/hwmtm.c b/drivers/net/skfp/hwmtm.c
--- a/drivers/net/skfp/hwmtm.c
+++ b/drivers/net/skfp/hwmtm.c
@@ -86,6 +86,7 @@ static u_long repair_txd_ring(struct s_s
 static u_long repair_rxd_ring(struct s_smc *smc, struct s_smt_rx_queue *queue);
 static SMbuf* get_llc_rx(struct s_smc *smc);
 static SMbuf* get_txd_mb(struct s_smc *smc);
+static void mac_drv_clear_txd(struct s_smc *smc);
 
 /*
 	-------------------------------------------------------------
@@ -146,7 +147,6 @@ extern int mac_drv_rx_init(struct s_smc 
 */
 void process_receive(struct s_smc *smc);
 void fddi_isr(struct s_smc *smc);
-void mac_drv_clear_txd(struct s_smc *smc);
 void smt_free_mbuf(struct s_smc *smc, SMbuf *mb);
 void init_driver_fplus(struct s_smc *smc);
 void mac_drv_rx_mode(struct s_smc *smc, int mode);
@@ -158,7 +158,6 @@ void hwm_tx_frag(struct s_smc *smc, char
 void hwm_rx_frag(struct s_smc *smc, char far *virt, u_long phys, int len,
 		 int frame_status);
 
-int mac_drv_rx_frag(struct s_smc *smc, void far *virt, int len);
 int mac_drv_init(struct s_smc *smc);
 int hwm_tx_init(struct s_smc *smc, u_char fc, int frag_count, int frame_len,
 		int frame_status);
@@ -1448,35 +1447,6 @@ void hwm_rx_frag(struct s_smc *smc, char
 	NDD_TRACE("RHfE",r,AIX_REVERSE(r->rxd_rbadr),0) ;
 }
 
-#ifndef	NDIS_OS2
-/*
- *	BEGIN_MANUAL_ENTRY(mac_drv_rx_frag)
- *	int mac_drv_rx_frag(smc,virt,len)
- *
- * function	DOWNCALL	(hwmtm.c)
- *		mac_drv_rx_frag fills the fragment with a part of the frame.
- *
- * para	virt	the virtual address of the fragment
- *	len	the length in bytes of the fragment
- *
- * return 0:	success code, no errors possible
- *
- *	END_MANUAL_ENTRY
- */
-int mac_drv_rx_frag(struct s_smc *smc, void far *virt, int len)
-{
-	NDD_TRACE("RHSB",virt,len,smc->os.hwm.r.mb_pos) ;
-
-	DB_RX("receive from queue: len/virt: = %d/%x",len,virt,4) ;
-	memcpy((char far *)virt,smc->os.hwm.r.mb_pos,len) ;
-	smc->os.hwm.r.mb_pos += len ;
-
-	NDD_TRACE("RHSE",smc->os.hwm.r.mb_pos,0,0) ;
-	return(0) ;
-}
-#endif
-
-
 /*
  *	BEGINN_MANUAL_ENTRY(mac_drv_clear_rx_queue)
  *
@@ -1978,7 +1948,7 @@ void smt_send_mbuf(struct s_smc *smc, SM
  *
  *	END_MANUAL_ENTRY
  */
-void mac_drv_clear_txd(struct s_smc *smc)
+static void mac_drv_clear_txd(struct s_smc *smc)
 {
 	struct s_smt_tx_queue *queue ;
 	struct s_smt_fp_txd volatile *t1 ;
diff --git a/drivers/net/skfp/lnkstat.c b/drivers/net/skfp/lnkstat.c
deleted file mode 100644
--- a/drivers/net/skfp/lnkstat.c
+++ /dev/null
@@ -1,204 +0,0 @@
-/******************************************************************************
- *
- *	(C)Copyright 1998,1999 SysKonnect,
- *	a business unit of Schneider & Koch & Co. Datensysteme GmbH.
- *
- *	See the file "skfddi.c" for further information.
- *
- *	This program is free software; you can redistribute it and/or modify
- *	it under the terms of the GNU General Public License as published by
- *	the Free Software Foundation; either version 2 of the License, or
- *	(at your option) any later version.
- *
- *	The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-/*
-	IBM FDDI read error log function
-*/
-
-#include "h/types.h"
-#include "h/fddi.h"
-#include "h/smc.h"
-#include "h/lnkstat.h"
-
-#ifndef	lint
-static const char ID_sccs[] = "@(#)lnkstat.c	1.8 97/04/11 (C) SK " ;
-#endif
-
-#ifdef	sun
-#define _far
-#endif
-
-#define EL_IS_OK(x,l)	((((int)&(((struct s_error_log *)0)->x)) + \
-			sizeof(er->x)) <= l)
-
-/*
-	BEGIN_MANUAL_ENTRY(if,func;others;11)
-
-	u_long smt_get_error_word(smc)
-	struct s_smc *smc ;
-
-Function	DOWNCALL	(SMT, lnkstat.c)
-		This functions returns the SMT error work for AIX events.
-
-Return	smt_error_word	These bits are supported:
-
-		SMT_ERL_ALC	== 	[PS/PA].fddiPORTLerFlag
-		SMT_ERL_BLC	==	[PB].fddiPORTLerFlag
-		SMT_ERL_NCC	==	fddiMACNotCopiedFlag
-		SMT_ERL_FEC	==	fddiMACFrameErrorFlag
-
-	END_MANUAL_ENTRY()
- */
-u_long smt_get_error_word(struct s_smc *smc)
-{
-	u_long	st;
-
-	/*
-	 * smt error word low
-	 */
-	st = 0 ;
-	if (smc->s.sas == SMT_SAS) {
-		if (smc->mib.p[PS].fddiPORTLerFlag)
-			st |= SMT_ERL_ALC ;
-	}
-	else {
-		if (smc->mib.p[PA].fddiPORTLerFlag)
-			st |= SMT_ERL_ALC ;
-		if (smc->mib.p[PB].fddiPORTLerFlag)
-			st |= SMT_ERL_BLC ;
-	}
-	if (smc->mib.m[MAC0].fddiMACNotCopiedFlag)
-		st |= SMT_ERL_NCC ;		/* not copied condition */
-	if (smc->mib.m[MAC0].fddiMACFrameErrorFlag)
-		st |= SMT_ERL_FEC ;		/* frame error condition */
-
-	return st;
-}
-
-/*
-	BEGIN_MANUAL_ENTRY(if,func;others;11)
-
-	u_long smt_get_event_word(smc)
-	struct s_smc *smc ;
-
-Function	DOWNCALL	(SMT, lnkstat.c)
-		This functions returns the SMT event work for AIX events.
-
-Return	smt_event_word	always 0
-
-	END_MANUAL_ENTRY()
- */
-u_long smt_get_event_word(struct s_smc *smc)
-{
-	return (u_long) 0;
-}
-
-/*
-	BEGIN_MANUAL_ENTRY(if,func;others;11)
-
-	u_long smt_get_port_event_word(smc)
-	struct s_smc *smc ;
-
-Function	DOWNCALL	(SMT, lnkstat.c)
-		This functions returns the SMT port event work for AIX events.
-
-Return	smt_port_event_word	always 0
-
-	END_MANUAL_ENTRY()
- */
-u_long smt_get_port_event_word(struct s_smc *smc)
-{
-	return (u_long) 0;
-}
-
-/*
-	BEGIN_MANUAL_ENTRY(if,func;others;11)
-
-	u_long smt_read_errorlog(smc,p,len)
-	struct s_smc *smc ;
-	char _far *p ;
-	int len ;
-
-Function	DOWNCALL	(SMT, lnkstat.c)
-		This functions returns the SMT error log field for AIX events.
-
-Para	p	pointer to the error log field
-	len	len of the error log field
-
-Return	len	used len of the error log field
-
-	END_MANUAL_ENTRY()
- */
-int smt_read_errorlog(struct s_smc *smc, char _far *p, int len)
-{
-	int			i ;
-	int			st ;
-	struct s_error_log _far	*er ;
-
-	er = (struct s_error_log _far *) p ;
-	if (len > sizeof(struct s_error_log))
-		len = sizeof(struct s_error_log) ;
-	for (i = 0 ; i < len ; i++)
-		*p++ = 0 ;
-	/*
-	 * set count
-	 */
-	if (EL_IS_OK(set_count_high,len)) {
-		er->set_count_low = (u_short)smc->mib.fddiSMTSetCount.count ;
-		er->set_count_high =
-			(u_short)(smc->mib.fddiSMTSetCount.count >> 16L) ;
-	}
-	/*
-	 * aci
-	 */
-	if (EL_IS_OK(aci_id_code,len)) {
-		er->aci_id_code = 0 ;
-	}
-	/*
-	 * purge counter is missed frames; 16 bits only
-	 */
-	if (EL_IS_OK(purge_frame_counter,len)) {
-		if (smc->mib.m[MAC0].fddiMACCopied_Ct > 0xffff)
-			er->purge_frame_counter = 0xffff ;
-		else
-			er->purge_frame_counter =
-				(u_short)smc->mib.m[MAC0].fddiMACCopied_Ct ;
-	}
-	/*
-	 * CMT and RMT state machines
-	 */
-	if (EL_IS_OK(ecm_state,len))
-		er->ecm_state = smc->mib.fddiSMTECMState ;
-
-	if (EL_IS_OK(pcm_b_state,len)) {
-		if (smc->s.sas == SMT_SAS) {
-			er->pcm_a_state = smc->y[PS].mib->fddiPORTPCMState ;
-			er->pcm_b_state = 0 ;
-		}
-		else {
-			er->pcm_a_state = smc->y[PA].mib->fddiPORTPCMState ;
-			er->pcm_b_state = smc->y[PB].mib->fddiPORTPCMState ;
-		}
-	}
-	if (EL_IS_OK(cfm_state,len))
-		er->cfm_state = smc->mib.fddiSMTCF_State ;
-	if (EL_IS_OK(rmt_state,len))
-		er->rmt_state = smc->mib.m[MAC0].fddiMACRMTState ;
-
-	/*
-	 * smt error word low (we only need the low order 16 bits.)
-	 */
-
-	st = smt_get_error_word(smc) & 0xffff ;
-
-	if (EL_IS_OK(smt_error_low,len))
-		er->smt_error_low = st ;
-
-	if (EL_IS_OK(ucode_version_level,len))
-		er->ucode_version_level = 0x0101 ;
-	return(len) ;
-}
-
diff --git a/drivers/net/skfp/pcmplc.c b/drivers/net/skfp/pcmplc.c
--- a/drivers/net/skfp/pcmplc.c
+++ b/drivers/net/skfp/pcmplc.c
@@ -1861,13 +1861,6 @@ void plc_irq(struct s_smc *smc, int np, 
 #endif
 }
 
-void pcm_set_lct_short(struct s_smc *smc, int n)
-{
-	if (n <= 0 || n > 1000)
-		return ;
-	smc->s.lct_short = n ;
-}
-
 #ifdef	DEBUG
 /*
  * fill state struct
diff --git a/drivers/net/skfp/pmf.c b/drivers/net/skfp/pmf.c
--- a/drivers/net/skfp/pmf.c
+++ b/drivers/net/skfp/pmf.c
@@ -36,12 +36,13 @@ static int smt_authorize(struct s_smc *s
 static int smt_check_set_count(struct s_smc *smc, struct smt_header *sm);
 static const struct s_p_tab* smt_get_ptab(u_short para);
 static int smt_mib_phys(struct s_smc *smc);
-int smt_set_para(struct s_smc *smc, struct smt_para *pa, int index, int local,
-		 int set);
+static int smt_set_para(struct s_smc *smc, struct smt_para *pa, int index,
+			int local, int set);
 void smt_add_para(struct s_smc *smc, struct s_pcon *pcon, u_short para,
 		  int index, int local);
 static SMbuf *smt_build_pmf_response(struct s_smc *smc, struct smt_header *req,
 				     int set, int local);
+static int port_to_mib(struct s_smc *smc, int p);
 
 #define MOFFSS(e)	((int)&(((struct fddi_mib *)0)->e))
 #define MOFFSA(e)	((int) (((struct fddi_mib *)0)->e))
@@ -1078,8 +1079,8 @@ wrong_error:
 /*
  * set parameter
  */
-int smt_set_para(struct s_smc *smc, struct smt_para *pa, int index, int local,
-		 int set)
+static int smt_set_para(struct s_smc *smc, struct smt_para *pa, int index,
+			int local, int set)
 {
 #define IFSET(x)	if (set) (x)
 
@@ -1549,7 +1550,7 @@ static int smt_mib_phys(struct s_smc *sm
 #endif
 }
 
-int port_to_mib(struct s_smc *smc, int p)
+static int port_to_mib(struct s_smc *smc, int p)
 {
 #ifdef	CONCENTRATOR
 	SK_UNUSED(smc) ;
diff --git a/drivers/net/skfp/skfddi.c b/drivers/net/skfp/skfddi.c
--- a/drivers/net/skfp/skfddi.c
+++ b/drivers/net/skfp/skfddi.c
@@ -149,7 +149,6 @@ extern void hwm_rx_frag(struct s_smc *sm
 extern void mac_drv_rx_mode(struct s_smc *smc, int mode);
 extern void mac_drv_clear_rx_queue(struct s_smc *smc);
 extern void enable_tx_irq(struct s_smc *smc, u_short queue);
-extern void mac_drv_clear_txd(struct s_smc *smc);
 
 static struct pci_device_id skfddi_pci_tbl[] = {
 	{ PCI_VENDOR_ID_SK, PCI_DEVICE_ID_SK_FP, PCI_ANY_ID, PCI_ANY_ID, },
diff --git a/drivers/net/skfp/smt.c b/drivers/net/skfp/smt.c
--- a/drivers/net/skfp/smt.c
+++ b/drivers/net/skfp/smt.c
@@ -86,7 +86,7 @@ static void smt_send_sif_config(struct s
 static void smt_send_sif_operation(struct s_smc *smc, struct fddi_addr *dest,
 				   u_long tid, int local);
 #ifdef LITTLE_ENDIAN
-static void smt_string_swap(void);
+static void smt_string_swap(char *data, const char *format, int len);
 #endif
 static void smt_add_frame_len(SMbuf *mb, int len);
 static void smt_fill_una(struct s_smc *smc, struct smt_p_una *una);
@@ -110,7 +110,7 @@ static void smt_fill_setcount(struct s_s
 static void smt_fill_echo(struct s_smc *smc, struct smt_p_echo *echo, u_long seed,
 			  int len);
 
-void smt_clear_una_dna(struct s_smc *smc);
+static void smt_clear_una_dna(struct s_smc *smc);
 static void smt_clear_old_una_dna(struct s_smc *smc);
 #ifdef	CONCENTRATOR
 static int entity_to_index(void);
@@ -118,7 +118,7 @@ static int entity_to_index(void);
 static void update_dac(struct s_smc *smc, int report);
 static int div_ratio(u_long upper, u_long lower);
 #ifdef  USE_CAN_ADDR
-void	hwm_conv_can(struct s_smc *smc, char *data, int len);
+static void	hwm_conv_can(struct s_smc *smc, char *data, int len);
 #else
 #define		hwm_conv_can(smc,data,len)
 #endif
@@ -216,24 +216,6 @@ void smt_agent_task(struct s_smc *smc)
 	DB_SMT("SMT agent task\n",0,0) ;
 }
 
-void smt_please_reconnect(struct s_smc *smc, int reconn_time)
-/* struct s_smc	*smc;  Pointer to SMT context */
-/* int reconn_time;    Wait for reconnect time in seconds */
-{
-	/*
-	 * The please reconnect variable is used as a timer.
-	 * It is decremented each time smt_event is called.
-	 * This happens every second or when smt_force_irq is called.
-	 * Note: smt_force_irq () is called on some packet receives and
-	 *       when a multicast address is changed. Since nothing
-	 *       is received during the disconnect and the multicast
-	 *       address changes can be viewed as not very often and
-	 *       the timer runs out close to its given value
-	 *       (reconn_time).
-	 */
-	smc->sm.please_reconnect = reconn_time ;
-}
-
 #ifndef SMT_REAL_TOKEN_CT
 void smt_emulate_token_ct(struct s_smc *smc, int mac_index)
 {
@@ -1574,7 +1556,7 @@ static void smt_fill_echo(struct s_smc *
  * clear DNA and UNA
  * called from CFM if configuration changes
  */
-void smt_clear_una_dna(struct s_smc *smc)
+static void smt_clear_una_dna(struct s_smc *smc)
 {
 	smc->mib.m[MAC0].fddiMACUpstreamNbr = SMT_Unknown ;
 	smc->mib.m[MAC0].fddiMACDownstreamNbr = SMT_Unknown ;
@@ -2058,30 +2040,10 @@ int smt_action(struct s_smc *smc, int cl
 }
 
 /*
- * change tneg
- *	set T_Req in MIB (Path Attribute)
- *	calculate new values for MAC
- *	if change required
- *		disconnect
- *		set reconnect
- *	end
- */
-void smt_change_t_neg(struct s_smc *smc, u_long tneg)
-{
-	smc->mib.a[PATH0].fddiPATHMaxT_Req = tneg ;
-
-	if (smt_set_mac_opvalues(smc)) {
-		RS_SET(smc,RS_EVENT) ;
-		smc->sm.please_reconnect = 1 ;
-		queue_event(smc,EVENT_ECM,EC_DISCONNECT) ;
-	}
-}
-
-/*
  * canonical conversion of <len> bytes beginning form *data
  */
 #ifdef  USE_CAN_ADDR
-void hwm_conv_can(struct s_smc *smc, char *data, int len)
+static void hwm_conv_can(struct s_smc *smc, char *data, int len)
 {
 	int i ;
 
diff --git a/drivers/net/skfp/smtdef.c b/drivers/net/skfp/smtdef.c
--- a/drivers/net/skfp/smtdef.c
+++ b/drivers/net/skfp/smtdef.c
@@ -76,11 +76,6 @@ void smt_reset_defaults(struct s_smc *sm
 static void smt_init_mib(struct s_smc *smc, int level);
 static int set_min_max(int maxflag, u_long mib, u_long limit, u_long *oper);
 
-void smt_set_defaults(struct s_smc *smc)
-{
-	smt_reset_defaults(smc,0) ;
-}
-
 #define MS2BCLK(x)	((x)*12500L)
 #define US2BCLK(x)	((x)*1250L)
 
diff --git a/drivers/net/skfp/smtparse.c b/drivers/net/skfp/smtparse.c
deleted file mode 100644
--- a/drivers/net/skfp/smtparse.c
+++ /dev/null
@@ -1,467 +0,0 @@
-/******************************************************************************
- *
- *	(C)Copyright 1998,1999 SysKonnect,
- *	a business unit of Schneider & Koch & Co. Datensysteme GmbH.
- *
- *	See the file "skfddi.c" for further information.
- *
- *	This program is free software; you can redistribute it and/or modify
- *	it under the terms of the GNU General Public License as published by
- *	the Free Software Foundation; either version 2 of the License, or
- *	(at your option) any later version.
- *
- *	The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-
-/*
-	parser for SMT parameters
-*/
-
-#include "h/types.h"
-#include "h/fddi.h"
-#include "h/smc.h"
-#include "h/smt_p.h"
-
-#define KERNEL
-#include "h/smtstate.h"
-
-#ifndef	lint
-static const char ID_sccs[] = "@(#)smtparse.c	1.12 98/10/06 (C) SK " ;
-#endif
-
-#ifdef	sun
-#define _far
-#endif
-
-/*
- * convert to BCLK units
- */
-#define MS2BCLK(x)      ((x)*12500L)
-#define US2BCLK(x)      ((x/10)*125L)
-
-/*
- * parameter table
- */
-static struct s_ptab {
-	char	*pt_name ;
-	u_short	pt_num ;
-	u_short	pt_type ;
-	u_long	pt_min ;
-	u_long	pt_max ;
-} ptab[] = {
-	{ "PMFPASSWD",0,	0 } ,
-	{ "USERDATA",1,		0 } ,
-	{ "LERCUTOFFA",2,	1,	4,	15	} ,
-	{ "LERCUTOFFB",3,	1,	4,	15	} ,
-	{ "LERALARMA",4,	1,	4,	15	} ,
-	{ "LERALARMB",5,	1,	4,	15	} ,
-	{ "TMAX",6,		1,	5,	165	} ,
-	{ "TMIN",7,		1,	5,	165	} ,
-	{ "TREQ",8,		1,	5,	165	} ,
-	{ "TVX",9,		1,	2500,	10000	} ,
-#ifdef ESS
-	{ "SBAPAYLOAD",10,	1,	0,	1562	} ,
-	{ "SBAOVERHEAD",11,	1,	50,	5000	} ,
-	{ "MAXTNEG",12,		1,	5,	165	} ,
-	{ "MINSEGMENTSIZE",13,	1,	0,	4478	} ,
-	{ "SBACATEGORY",14,	1,	0,	0xffff	} ,
-	{ "SYNCHTXMODE",15,	0 } ,
-#endif
-#ifdef SBA
-	{ "SBACOMMAND",16,	0 } ,
-	{ "SBAAVAILABLE",17,	1,	0,	100	} ,
-#endif
-	{ NULL }
-} ;
-
-/* Define maximum string size for values and keybuffer */
-#define MAX_VAL	40
-
-/*
- * local function declarations
- */
-static u_long parse_num(int type, char _far *value, char *v, u_long mn,
-			u_long mx, int scale);
-static int parse_word(char *buf, char _far *text);
-
-#ifdef SIM
-#define DB_MAIN(a,b,c)	printf(a,b,c)
-#else
-#define DB_MAIN(a,b,c)
-#endif
-
-/*
- * BEGIN_MANUAL_ENTRY()
- *
- *	int smt_parse_arg(struct s_smc *,char _far *keyword,int type,
-		char _far *value)
- *
- *	parse SMT parameter
- *	*keyword
- *		pointer to keyword, must be \0, \n or \r terminated
- *	*value	pointer to value, either char * or u_long *
- *		if char *
- *			pointer to value, must be \0, \n or \r terminated
- *		if u_long *
- *			contains binary value
- *
- *	type	0: integer
- *		1: string
- *	return
- *		0	parameter parsed ok
- *		!= 0	error
- *	NOTE:
- *		function can be called with DS != SS
- *
- *
- * END_MANUAL_ENTRY()
- */
-int smt_parse_arg(struct s_smc *smc, char _far *keyword, int type,
-		  char _far *value)
-{
-	char		keybuf[MAX_VAL+1];
-	char		valbuf[MAX_VAL+1];
-	char		c ;
-	char 		*p ;
-	char		*v ;
-	char		*d ;
-	u_long		val = 0 ;
-	struct s_ptab	*pt ;
-	int		st ;
-	int		i ;
-
-	/*
-	 * parse keyword
-	 */
-	if ((st = parse_word(keybuf,keyword)))
-		return(st) ;
-	/*
-	 * parse value if given as string
-	 */
-	if (type == 1) {
-		if ((st = parse_word(valbuf,value)))
-			return(st) ;
-	}
-	/*
-	 * search in table
-	 */
-	st = 0 ;
-	for (pt = ptab ; (v = pt->pt_name) ; pt++) {
-		for (p = keybuf ; (c = *p) ; p++,v++) {
-			if (c != *v)
-				break ;
-		}
-		if (!c && !*v)
-			break ;
-	}
-	if (!v)
-		return(-1) ;
-#if	0
-	printf("=>%s<==>%s<=\n",pt->pt_name,valbuf) ;
-#endif
-	/*
-	 * set value in MIB
-	 */
-	if (pt->pt_type)
-		val = parse_num(type,value,valbuf,pt->pt_min,pt->pt_max,1) ;
-	switch (pt->pt_num) {
-	case 0 :
-		v = valbuf ;
-		d = (char *) smc->mib.fddiPRPMFPasswd ;
-		for (i = 0 ; i < (signed)sizeof(smc->mib.fddiPRPMFPasswd) ; i++)
-			*d++ = *v++ ;
-		DB_MAIN("SET %s = %s\n",pt->pt_name,smc->mib.fddiPRPMFPasswd) ;
-		break ;
-	case 1 :
-		v = valbuf ;
-		d = (char *) smc->mib.fddiSMTUserData ;
-		for (i = 0 ; i < (signed)sizeof(smc->mib.fddiSMTUserData) ; i++)
-			*d++ = *v++ ;
-		DB_MAIN("SET %s = %s\n",pt->pt_name,smc->mib.fddiSMTUserData) ;
-		break ;
-	case 2 :
-		smc->mib.p[PA].fddiPORTLer_Cutoff = (u_char) val ;
-		DB_MAIN("SET %s = %d\n",
-			pt->pt_name,smc->mib.p[PA].fddiPORTLer_Cutoff) ;
-		break ;
-	case 3 :
-		smc->mib.p[PB].fddiPORTLer_Cutoff = (u_char) val ;
-		DB_MAIN("SET %s = %d\n",
-			pt->pt_name,smc->mib.p[PB].fddiPORTLer_Cutoff) ;
-		break ;
-	case 4 :
-		smc->mib.p[PA].fddiPORTLer_Alarm = (u_char) val ;
-		DB_MAIN("SET %s = %d\n",
-			pt->pt_name,smc->mib.p[PA].fddiPORTLer_Alarm) ;
-		break ;
-	case 5 :
-		smc->mib.p[PB].fddiPORTLer_Alarm = (u_char) val ;
-		DB_MAIN("SET %s = %d\n",
-			pt->pt_name,smc->mib.p[PB].fddiPORTLer_Alarm) ;
-		break ;
-	case 6 :			/* TMAX */
-		DB_MAIN("SET %s = %d\n",pt->pt_name,val) ;
-		smc->mib.a[PATH0].fddiPATHT_MaxLowerBound =
-			(u_long) -MS2BCLK((long)val) ;
-		break ;
-	case 7 :			/* TMIN */
-		DB_MAIN("SET %s = %d\n",pt->pt_name,val) ;
-		smc->mib.m[MAC0].fddiMACT_Min =
-			(u_long) -MS2BCLK((long)val) ;
-		break ;
-	case 8 :			/* TREQ */
-		DB_MAIN("SET %s = %d\n",pt->pt_name,val) ;
-		smc->mib.a[PATH0].fddiPATHMaxT_Req =
-			(u_long) -MS2BCLK((long)val) ;
-		break ;
-	case 9 :			/* TVX */
-		DB_MAIN("SET %s = %d \n",pt->pt_name,val) ;
-		smc->mib.a[PATH0].fddiPATHTVXLowerBound =
-			(u_long) -US2BCLK((long)val) ;
-		break ;
-#ifdef	ESS
-	case 10 :			/* SBAPAYLOAD */
-		DB_MAIN("SET %s = %d\n",pt->pt_name,val) ;
-		if (smc->mib.fddiESSPayload != val) {
-			smc->ess.raf_act_timer_poll = TRUE ;
-			smc->mib.fddiESSPayload = val ;
-		}
-		break ;
-	case 11 :			/* SBAOVERHEAD */
-		DB_MAIN("SET %s = %d\n",pt->pt_name,val) ;
-		smc->mib.fddiESSOverhead = val ;
-		break ;
-	case 12 :			/* MAXTNEG */
-		DB_MAIN("SET %s = %d\n",pt->pt_name,val) ;
-		smc->mib.fddiESSMaxTNeg = (u_long) -MS2BCLK((long)val) ;
-		break ;
-	case 13 :			/* MINSEGMENTSIZE */
-		DB_MAIN("SET %s = %d\n",pt->pt_name,val) ;
-		smc->mib.fddiESSMinSegmentSize = val ;
-		break ;
-	case 14 :			/* SBACATEGORY */
-		DB_MAIN("SET %s = %d\n",pt->pt_name,val) ;
-		smc->mib.fddiESSCategory =
-			(smc->mib.fddiESSCategory & 0xffff) |
-			((u_long)(val << 16)) ;
-		break ;
-	case 15 :			/* SYNCHTXMODE */
-		/* do not use memcmp(valbuf,"ALL",3) because DS != SS */
-		if (valbuf[0] == 'A' && valbuf[1] == 'L' && valbuf[2] == 'L') {
-			smc->mib.fddiESSSynchTxMode = TRUE ;
-			DB_MAIN("SET %s = %s\n",pt->pt_name,valbuf) ;
-		}
-		/* if (!memcmp(valbuf,"SPLIT",5)) { */
-		if (valbuf[0] == 'S' && valbuf[1] == 'P' && valbuf[2] == 'L' &&
-			valbuf[3] == 'I' && valbuf[4] == 'T') {
-			DB_MAIN("SET %s = %s\n",pt->pt_name,valbuf) ;
-			smc->mib.fddiESSSynchTxMode = FALSE ;
-		}
-		break ;
-#endif
-#ifdef	SBA
-	case 16 :			/* SBACOMMAND */
-		/* if (!memcmp(valbuf,"START",5)) { */
-		if (valbuf[0] == 'S' && valbuf[1] == 'T' && valbuf[2] == 'A' &&
-			valbuf[3] == 'R' && valbuf[4] == 'T') {
-			DB_MAIN("SET %s = %s\n",pt->pt_name,valbuf) ;
-			smc->mib.fddiSBACommand = SB_START ;
-		}
-		/* if (!memcmp(valbuf,"STOP",4)) { */
-		if (valbuf[0] == 'S' && valbuf[1] == 'T' && valbuf[2] == 'O' &&
-			valbuf[3] == 'P') {
-			DB_MAIN("SET %s = %s\n",pt->pt_name,valbuf) ;
-			smc->mib.fddiSBACommand = SB_STOP ;
-		}
-		break ;
-	case 17 :			/* SBAAVAILABLE */
-		DB_MAIN("SET %s = %d\n",pt->pt_name,val) ;
-		smc->mib.fddiSBAAvailable = (u_char) val ;
-		break ;
-#endif
-	}
-	return(0) ;
-}
-
-static int parse_word(char *buf, char _far *text)
-{
-	char		c ;
-	char 		*p ;
-	int		p_len ;
-	int		quote ;
-	int		i ;
-	int		ok ;
-
-	/*
-	 * skip leading white space
-	 */
-	p = buf ;
-	for (i = 0 ; i < MAX_VAL ; i++)
-		*p++ = 0 ;
-	p = buf ;
-	p_len = 0 ;
-	ok = 0 ;
-	while ( (c = *text++) && (c != '\n') && (c != '\r')) {
-		if ((c != ' ') && (c != '\t')) {
-			ok = 1 ;
-			break ;
-		}
-	}
-	if (!ok)
-		return(-1) ;
-	if (c == '"') {
-		quote = 1 ;
-	}
-	else {
-		quote = 0 ;
-		text-- ;
-	}
-	/*
-	 * parse valbuf
-	 */
-	ok = 0 ;
-	while (!ok && p_len < MAX_VAL-1 && (c = *text++) && (c != '\n')
-		&& (c != '\r')) {
-		switch (quote) {
-		case 0 :
-			if ((c == ' ') || (c == '\t') || (c == '=')) {
-				ok = 1 ;
-				break ;
-			}
-			*p++ = c ;
-			p_len++ ;
-			break ;
-		case 2 :
-			*p++ = c ;
-			p_len++ ;
-			quote = 1 ;
-			break ;
-		case 1 :
-			switch (c) {
-			case '"' :
-				ok = 1 ;
-				break ;
-			case '\\' :
-				quote = 2 ;
-				break ;
-			default :
-				*p++ = c ;
-				p_len++ ;
-			}
-		}
-	}
-	*p++ = 0 ;
-	for (p = buf ; (c = *p) ; p++) {
-		if (c >= 'a' && c <= 'z')
-			*p = c + 'A' - 'a' ;
-	}
-	return(0) ;
-}
-
-static u_long parse_num(int type, char _far *value, char *v, u_long mn,
-			u_long mx, int scale)
-{
-	u_long	x = 0 ;
-	char	c ;
-
-	if (type == 0) {		/* integer */
-		u_long _far	*l ;
-		u_long		u1 ;
-
-		l = (u_long _far *) value ;
-		u1 = *l ;
-		/*
-		 * if the value is negative take the lower limit
-		 */
-		if ((long)u1 < 0) {
-			if (- ((long)u1) > (long) mx) {
-				u1 = 0 ;
-			}
-			else {
-				u1 = (u_long) - ((long)u1) ;
-			}
-		}
-		x = u1 ;
-	}
-	else {				/* string */
-		int	sign = 0 ;
-
-		if (*v == '-') {
-			sign = 1 ;
-		}
-		while ((c = *v++) && (c >= '0') && (c <= '9')) {
-			x = x * 10 + c - '0' ;
-		}
-		if (scale == 10) {
-			x *= 10 ;
-			if (c == '.') {
-				if ((c = *v++) && (c >= '0') && (c <= '9')) {
-					x += c - '0' ;
-				}
-			}
-		}
-		if (sign)
-			x = (u_long) - ((long)x) ;
-	}
-	/*
-	 * if the value is negative
-	 *	and the absolute value is outside the limits
-	 *		take the lower limit
-	 *	else
-	 *		take the absoute value
-	 */
-	if ((long)x < 0) {
-		if (- ((long)x) > (long) mx) {
-			x = 0 ;
-		}
-		else {
-			x = (u_long) - ((long)x) ;
-		}
-	}
-	if (x < mn)
-		return(mn) ;
-	else if (x > mx)
-		return(mx) ;
-	return(x) ;
-}
-
-#if 0
-struct	s_smc	SMC ;
-main()
-{
-	char	*p ;
-	char	*v ;
-	char	buf[100] ;
-	int	toggle = 0 ;
-
-	while (gets(buf)) {
-		p = buf ;
-		while (*p && ((*p == ' ') || (*p == '\t')))
-			p++ ;
-
-		while (*p && ((*p != ' ') && (*p != '\t')))
-			p++ ;
-
-		v = p ;
-		while (*v && ((*v == ' ') || (*v == '\t')))
-			v++ ;
-		if ((*v >= '0') && (*v <= '9')) {
-			toggle = !toggle ;
-			if (toggle) {
-				u_long	l ;
-				l = atol(v) ;
-				smt_parse_arg(&SMC,buf,0,(char _far *)&l) ;
-			}
-			else
-				smt_parse_arg(&SMC,buf,1,(char _far *)p) ;
-		}
-		else {
-			smt_parse_arg(&SMC,buf,1,(char _far *)p) ;
-		}
-	}
-	exit(0) ;
-}
-#endif
-
diff --git a/drivers/net/skge.c b/drivers/net/skge.c
new file mode 100644
--- /dev/null
+++ b/drivers/net/skge.c
@@ -0,0 +1,3317 @@
+/*
+ * New driver for Marvell Yukon chipset and SysKonnect Gigabit
+ * Ethernet adapters. Based on earlier sk98lin, e100 and
+ * FreeBSD if_sk drivers.
+ *
+ * This driver intentionally does not support all the features
+ * of the original driver such as link fail-over and link management because
+ * those should be done at higher levels.
+ *
+ * Copyright (C) 2004, 2005 Stephen Hemminger <shemminger@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.
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/pci.h>
+#include <linux/if_vlan.h>
+#include <linux/ip.h>
+#include <linux/delay.h>
+#include <linux/crc32.h>
+#include <linux/dma-mapping.h>
+#include <asm/irq.h>
+
+#include "skge.h"
+
+#define DRV_NAME		"skge"
+#define DRV_VERSION		"0.8"
+#define PFX			DRV_NAME " "
+
+#define DEFAULT_TX_RING_SIZE	128
+#define DEFAULT_RX_RING_SIZE	512
+#define MAX_TX_RING_SIZE	1024
+#define MAX_RX_RING_SIZE	4096
+#define RX_COPY_THRESHOLD	128
+#define RX_BUF_SIZE		1536
+#define PHY_RETRIES	        1000
+#define ETH_JUMBO_MTU		9000
+#define TX_WATCHDOG		(5 * HZ)
+#define NAPI_WEIGHT		64
+#define BLINK_MS		250
+
+MODULE_DESCRIPTION("SysKonnect Gigabit Ethernet driver");
+MODULE_AUTHOR("Stephen Hemminger <shemminger@osdl.org>");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_VERSION);
+
+static const u32 default_msg
+	= NETIF_MSG_DRV| NETIF_MSG_PROBE| NETIF_MSG_LINK
+	  | NETIF_MSG_IFUP| NETIF_MSG_IFDOWN;
+
+static int debug = -1;	/* defaults above */
+module_param(debug, int, 0);
+MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
+
+static const struct pci_device_id skge_id_table[] = {
+	{ PCI_DEVICE(PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C940) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C940B) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_GE) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_YU) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_DLINK, PCI_DEVICE_ID_DLINK_DGE510T), },
+	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4320) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x5005) }, /* Belkin */
+	{ PCI_DEVICE(PCI_VENDOR_ID_CNET, PCI_DEVICE_ID_CNET_GIGACARD) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_LINKSYS, PCI_DEVICE_ID_LINKSYS_EG1032) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_LINKSYS, PCI_DEVICE_ID_LINKSYS_EG1064) },
+	{ 0 }
+};
+MODULE_DEVICE_TABLE(pci, skge_id_table);
+
+static int skge_up(struct net_device *dev);
+static int skge_down(struct net_device *dev);
+static void skge_tx_clean(struct skge_port *skge);
+static void xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val);
+static void gm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val);
+static void genesis_get_stats(struct skge_port *skge, u64 *data);
+static void yukon_get_stats(struct skge_port *skge, u64 *data);
+static void yukon_init(struct skge_hw *hw, int port);
+static void yukon_reset(struct skge_hw *hw, int port);
+static void genesis_mac_init(struct skge_hw *hw, int port);
+static void genesis_reset(struct skge_hw *hw, int port);
+static void genesis_link_up(struct skge_port *skge);
+
+/* Avoid conditionals by using array */
+static const int txqaddr[] = { Q_XA1, Q_XA2 };
+static const int rxqaddr[] = { Q_R1, Q_R2 };
+static const u32 rxirqmask[] = { IS_R1_F, IS_R2_F };
+static const u32 txirqmask[] = { IS_XA1_F, IS_XA2_F };
+static const u32 portirqmask[] = { IS_PORT_1, IS_PORT_2 };
+
+/* Don't need to look at whole 16K.
+ * last interesting register is descriptor poll timer.
+ */
+#define SKGE_REGS_LEN	(29*128)
+
+static int skge_get_regs_len(struct net_device *dev)
+{
+	return SKGE_REGS_LEN;
+}
+
+/*
+ * Returns copy of control register region
+ * I/O region is divided into banks and certain regions are unreadable
+ */
+static void skge_get_regs(struct net_device *dev, struct ethtool_regs *regs,
+			  void *p)
+{
+	const struct skge_port *skge = netdev_priv(dev);
+	unsigned long offs;
+	const void __iomem *io = skge->hw->regs;
+	static const unsigned long bankmap
+		= (1<<0) | (1<<2) | (1<<8) | (1<<9)
+		  | (1<<12) | (1<<13) | (1<<14) | (1<<15) | (1<<16)
+		  | (1<<17) | (1<<20) | (1<<21) | (1<<22) | (1<<23)
+		  | (1<<24)  | (1<<25) | (1<<26) | (1<<27) | (1<<28);
+
+	regs->version = 1;
+	for (offs = 0; offs < regs->len; offs += 128) {
+		u32 len = min_t(u32, 128, regs->len - offs);
+
+		if (bankmap & (1<<(offs/128)))
+			memcpy_fromio(p + offs, io + offs, len);
+		else
+			memset(p + offs, 0, len);
+	}
+}
+
+/* Wake on Lan only supported on Yukon chps with rev 1 or above */
+static int wol_supported(const struct skge_hw *hw)
+{
+	return !((hw->chip_id == CHIP_ID_GENESIS ||
+		  (hw->chip_id == CHIP_ID_YUKON && hw->chip_rev == 0)));
+}
+
+static void skge_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+{
+	struct skge_port *skge = netdev_priv(dev);
+
+	wol->supported = wol_supported(skge->hw) ? WAKE_MAGIC : 0;
+	wol->wolopts = skge->wol ? WAKE_MAGIC : 0;
+}
+
+static int skge_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+{
+	struct skge_port *skge = netdev_priv(dev);
+	struct skge_hw *hw = skge->hw;
+
+	if (wol->wolopts != WAKE_MAGIC && wol->wolopts != 0)
+		return -EOPNOTSUPP;
+
+	if (wol->wolopts == WAKE_MAGIC && !wol_supported(hw))
+		return -EOPNOTSUPP;
+
+	skge->wol = wol->wolopts == WAKE_MAGIC;
+
+	if (skge->wol) {
+		memcpy_toio(hw->regs + WOL_MAC_ADDR, dev->dev_addr, ETH_ALEN);
+
+		skge_write16(hw, WOL_CTRL_STAT,
+			     WOL_CTL_ENA_PME_ON_MAGIC_PKT |
+			     WOL_CTL_ENA_MAGIC_PKT_UNIT);
+	} else
+		skge_write16(hw, WOL_CTRL_STAT, WOL_CTL_DEFAULT);
+
+	return 0;
+}
+
+/* Determine supported/adverised modes based on hardware.
+ * Note: ethtoool ADVERTISED_xxx == SUPPORTED_xxx
+ */
+static u32 skge_supported_modes(const struct skge_hw *hw)
+{
+	u32 supported;
+
+	if (iscopper(hw)) {
+		supported = SUPPORTED_10baseT_Half
+			| SUPPORTED_10baseT_Full
+			| SUPPORTED_100baseT_Half
+			| SUPPORTED_100baseT_Full
+			| SUPPORTED_1000baseT_Half
+			| SUPPORTED_1000baseT_Full
+			| SUPPORTED_Autoneg| SUPPORTED_TP;
+
+		if (hw->chip_id == CHIP_ID_GENESIS)
+			supported &= ~(SUPPORTED_10baseT_Half
+					     | SUPPORTED_10baseT_Full
+					     | SUPPORTED_100baseT_Half
+					     | SUPPORTED_100baseT_Full);
+
+		else if (hw->chip_id == CHIP_ID_YUKON)
+			supported &= ~SUPPORTED_1000baseT_Half;
+	} else
+		supported = SUPPORTED_1000baseT_Full | SUPPORTED_FIBRE
+			| SUPPORTED_Autoneg;
+
+	return supported;
+}
+
+static int skge_get_settings(struct net_device *dev,
+			     struct ethtool_cmd *ecmd)
+{
+	struct skge_port *skge = netdev_priv(dev);
+	struct skge_hw *hw = skge->hw;
+
+	ecmd->transceiver = XCVR_INTERNAL;
+	ecmd->supported = skge_supported_modes(hw);
+
+	if (iscopper(hw)) {
+		ecmd->port = PORT_TP;
+		ecmd->phy_address = hw->phy_addr;
+	} else
+		ecmd->port = PORT_FIBRE;
+
+	ecmd->advertising = skge->advertising;
+	ecmd->autoneg = skge->autoneg;
+	ecmd->speed = skge->speed;
+	ecmd->duplex = skge->duplex;
+	return 0;
+}
+
+static int skge_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
+{
+	struct skge_port *skge = netdev_priv(dev);
+	const struct skge_hw *hw = skge->hw;
+	u32 supported = skge_supported_modes(hw);
+
+	if (ecmd->autoneg == AUTONEG_ENABLE) {
+		ecmd->advertising = supported;
+		skge->duplex = -1;
+		skge->speed = -1;
+	} else {
+		u32 setting;
+
+		switch (ecmd->speed) {
+		case SPEED_1000:
+			if (ecmd->duplex == DUPLEX_FULL)
+				setting = SUPPORTED_1000baseT_Full;
+			else if (ecmd->duplex == DUPLEX_HALF)
+				setting = SUPPORTED_1000baseT_Half;
+			else
+				return -EINVAL;
+			break;
+		case SPEED_100:
+			if (ecmd->duplex == DUPLEX_FULL)
+				setting = SUPPORTED_100baseT_Full;
+			else if (ecmd->duplex == DUPLEX_HALF)
+				setting = SUPPORTED_100baseT_Half;
+			else
+				return -EINVAL;
+			break;
+
+		case SPEED_10:
+			if (ecmd->duplex == DUPLEX_FULL)
+				setting = SUPPORTED_10baseT_Full;
+			else if (ecmd->duplex == DUPLEX_HALF)
+				setting = SUPPORTED_10baseT_Half;
+			else
+				return -EINVAL;
+			break;
+		default:
+			return -EINVAL;
+		}
+
+		if ((setting & supported) == 0)
+			return -EINVAL;
+
+		skge->speed = ecmd->speed;
+		skge->duplex = ecmd->duplex;
+	}
+
+	skge->autoneg = ecmd->autoneg;
+	skge->advertising = ecmd->advertising;
+
+	if (netif_running(dev)) {
+		skge_down(dev);
+		skge_up(dev);
+	}
+	return (0);
+}
+
+static void skge_get_drvinfo(struct net_device *dev,
+			     struct ethtool_drvinfo *info)
+{
+	struct skge_port *skge = netdev_priv(dev);
+
+	strcpy(info->driver, DRV_NAME);
+	strcpy(info->version, DRV_VERSION);
+	strcpy(info->fw_version, "N/A");
+	strcpy(info->bus_info, pci_name(skge->hw->pdev));
+}
+
+static const struct skge_stat {
+	char 	   name[ETH_GSTRING_LEN];
+	u16	   xmac_offset;
+	u16	   gma_offset;
+} skge_stats[] = {
+	{ "tx_bytes",		XM_TXO_OK_HI,  GM_TXO_OK_HI },
+	{ "rx_bytes",		XM_RXO_OK_HI,  GM_RXO_OK_HI },
+
+	{ "tx_broadcast",	XM_TXF_BC_OK,  GM_TXF_BC_OK },
+	{ "rx_broadcast",	XM_RXF_BC_OK,  GM_RXF_BC_OK },
+	{ "tx_multicast",	XM_TXF_MC_OK,  GM_TXF_MC_OK },
+	{ "rx_multicast",	XM_RXF_MC_OK,  GM_RXF_MC_OK },
+	{ "tx_unicast",		XM_TXF_UC_OK,  GM_TXF_UC_OK },
+	{ "rx_unicast",		XM_RXF_UC_OK,  GM_RXF_UC_OK },
+	{ "tx_mac_pause",	XM_TXF_MPAUSE, GM_TXF_MPAUSE },
+	{ "rx_mac_pause",	XM_RXF_MPAUSE, GM_RXF_MPAUSE },
+
+	{ "collisions",		XM_TXF_SNG_COL, GM_TXF_SNG_COL },
+	{ "multi_collisions",	XM_TXF_MUL_COL, GM_TXF_MUL_COL },
+	{ "aborted",		XM_TXF_ABO_COL, GM_TXF_ABO_COL },
+	{ "late_collision",	XM_TXF_LAT_COL, GM_TXF_LAT_COL },
+	{ "fifo_underrun",	XM_TXE_FIFO_UR, GM_TXE_FIFO_UR },
+	{ "fifo_overflow",	XM_RXE_FIFO_OV, GM_RXE_FIFO_OV },
+
+	{ "rx_toolong",		XM_RXF_LNG_ERR, GM_RXF_LNG_ERR },
+	{ "rx_jabber",		XM_RXF_JAB_PKT, GM_RXF_JAB_PKT },
+	{ "rx_runt",		XM_RXE_RUNT, 	GM_RXE_FRAG },
+	{ "rx_too_long",	XM_RXF_LNG_ERR, GM_RXF_LNG_ERR },
+	{ "rx_fcs_error",	XM_RXF_FCS_ERR, GM_RXF_FCS_ERR },
+};
+
+static int skge_get_stats_count(struct net_device *dev)
+{
+	return ARRAY_SIZE(skge_stats);
+}
+
+static void skge_get_ethtool_stats(struct net_device *dev,
+				   struct ethtool_stats *stats, u64 *data)
+{
+	struct skge_port *skge = netdev_priv(dev);
+
+	if (skge->hw->chip_id == CHIP_ID_GENESIS)
+		genesis_get_stats(skge, data);
+	else
+		yukon_get_stats(skge, data);
+}
+
+/* Use hardware MIB variables for critical path statistics and
+ * transmit feedback not reported at interrupt.
+ * Other errors are accounted for in interrupt handler.
+ */
+static struct net_device_stats *skge_get_stats(struct net_device *dev)
+{
+	struct skge_port *skge = netdev_priv(dev);
+	u64 data[ARRAY_SIZE(skge_stats)];
+
+	if (skge->hw->chip_id == CHIP_ID_GENESIS)
+		genesis_get_stats(skge, data);
+	else
+		yukon_get_stats(skge, data);
+
+	skge->net_stats.tx_bytes = data[0];
+	skge->net_stats.rx_bytes = data[1];
+	skge->net_stats.tx_packets = data[2] + data[4] + data[6];
+	skge->net_stats.rx_packets = data[3] + data[5] + data[7];
+	skge->net_stats.multicast = data[5] + data[7];
+	skge->net_stats.collisions = data[10];
+	skge->net_stats.tx_aborted_errors = data[12];
+
+	return &skge->net_stats;
+}
+
+static void skge_get_strings(struct net_device *dev, u32 stringset, u8 *data)
+{
+	int i;
+
+	switch (stringset) {
+	case ETH_SS_STATS:
+		for (i = 0; i < ARRAY_SIZE(skge_stats); i++)
+			memcpy(data + i * ETH_GSTRING_LEN,
+			       skge_stats[i].name, ETH_GSTRING_LEN);
+		break;
+	}
+}
+
+static void skge_get_ring_param(struct net_device *dev,
+				struct ethtool_ringparam *p)
+{
+	struct skge_port *skge = netdev_priv(dev);
+
+	p->rx_max_pending = MAX_RX_RING_SIZE;
+	p->tx_max_pending = MAX_TX_RING_SIZE;
+	p->rx_mini_max_pending = 0;
+	p->rx_jumbo_max_pending = 0;
+
+	p->rx_pending = skge->rx_ring.count;
+	p->tx_pending = skge->tx_ring.count;
+	p->rx_mini_pending = 0;
+	p->rx_jumbo_pending = 0;
+}
+
+static int skge_set_ring_param(struct net_device *dev,
+			       struct ethtool_ringparam *p)
+{
+	struct skge_port *skge = netdev_priv(dev);
+
+	if (p->rx_pending == 0 || p->rx_pending > MAX_RX_RING_SIZE ||
+	    p->tx_pending == 0 || p->tx_pending > MAX_TX_RING_SIZE)
+		return -EINVAL;
+
+	skge->rx_ring.count = p->rx_pending;
+	skge->tx_ring.count = p->tx_pending;
+
+	if (netif_running(dev)) {
+		skge_down(dev);
+		skge_up(dev);
+	}
+
+	return 0;
+}
+
+static u32 skge_get_msglevel(struct net_device *netdev)
+{
+	struct skge_port *skge = netdev_priv(netdev);
+	return skge->msg_enable;
+}
+
+static void skge_set_msglevel(struct net_device *netdev, u32 value)
+{
+	struct skge_port *skge = netdev_priv(netdev);
+	skge->msg_enable = value;
+}
+
+static int skge_nway_reset(struct net_device *dev)
+{
+	struct skge_port *skge = netdev_priv(dev);
+	struct skge_hw *hw = skge->hw;
+	int port = skge->port;
+
+	if (skge->autoneg != AUTONEG_ENABLE || !netif_running(dev))
+		return -EINVAL;
+
+	spin_lock_bh(&hw->phy_lock);
+	if (hw->chip_id == CHIP_ID_GENESIS) {
+		genesis_reset(hw, port);
+		genesis_mac_init(hw, port);
+	} else {
+		yukon_reset(hw, port);
+		yukon_init(hw, port);
+	}
+	spin_unlock_bh(&hw->phy_lock);
+	return 0;
+}
+
+static int skge_set_sg(struct net_device *dev, u32 data)
+{
+	struct skge_port *skge = netdev_priv(dev);
+	struct skge_hw *hw = skge->hw;
+
+	if (hw->chip_id == CHIP_ID_GENESIS && data)
+		return -EOPNOTSUPP;
+	return ethtool_op_set_sg(dev, data);
+}
+
+static int skge_set_tx_csum(struct net_device *dev, u32 data)
+{
+	struct skge_port *skge = netdev_priv(dev);
+	struct skge_hw *hw = skge->hw;
+
+	if (hw->chip_id == CHIP_ID_GENESIS && data)
+		return -EOPNOTSUPP;
+
+	return ethtool_op_set_tx_csum(dev, data);
+}
+
+static u32 skge_get_rx_csum(struct net_device *dev)
+{
+	struct skge_port *skge = netdev_priv(dev);
+
+	return skge->rx_csum;
+}
+
+/* Only Yukon supports checksum offload. */
+static int skge_set_rx_csum(struct net_device *dev, u32 data)
+{
+	struct skge_port *skge = netdev_priv(dev);
+
+	if (skge->hw->chip_id == CHIP_ID_GENESIS && data)
+		return -EOPNOTSUPP;
+
+	skge->rx_csum = data;
+	return 0;
+}
+
+static void skge_get_pauseparam(struct net_device *dev,
+				struct ethtool_pauseparam *ecmd)
+{
+	struct skge_port *skge = netdev_priv(dev);
+
+	ecmd->tx_pause = (skge->flow_control == FLOW_MODE_LOC_SEND)
+		|| (skge->flow_control == FLOW_MODE_SYMMETRIC);
+	ecmd->rx_pause = (skge->flow_control == FLOW_MODE_REM_SEND)
+		|| (skge->flow_control == FLOW_MODE_SYMMETRIC);
+
+	ecmd->autoneg = skge->autoneg;
+}
+
+static int skge_set_pauseparam(struct net_device *dev,
+			       struct ethtool_pauseparam *ecmd)
+{
+	struct skge_port *skge = netdev_priv(dev);
+
+	skge->autoneg = ecmd->autoneg;
+	if (ecmd->rx_pause && ecmd->tx_pause)
+		skge->flow_control = FLOW_MODE_SYMMETRIC;
+	else if (ecmd->rx_pause && !ecmd->tx_pause)
+		skge->flow_control = FLOW_MODE_REM_SEND;
+	else if (!ecmd->rx_pause && ecmd->tx_pause)
+		skge->flow_control = FLOW_MODE_LOC_SEND;
+	else
+		skge->flow_control = FLOW_MODE_NONE;
+
+	if (netif_running(dev)) {
+		skge_down(dev);
+		skge_up(dev);
+	}
+	return 0;
+}
+
+/* Chip internal frequency for clock calculations */
+static inline u32 hwkhz(const struct skge_hw *hw)
+{
+	if (hw->chip_id == CHIP_ID_GENESIS)
+		return 53215; /* or:  53.125 MHz */
+	else
+		return 78215; /* or:  78.125 MHz */
+}
+
+/* Chip hz to microseconds */
+static inline u32 skge_clk2usec(const struct skge_hw *hw, u32 ticks)
+{
+	return (ticks * 1000) / hwkhz(hw);
+}
+
+/* Microseconds to chip hz */
+static inline u32 skge_usecs2clk(const struct skge_hw *hw, u32 usec)
+{
+	return hwkhz(hw) * usec / 1000;
+}
+
+static int skge_get_coalesce(struct net_device *dev,
+			     struct ethtool_coalesce *ecmd)
+{
+	struct skge_port *skge = netdev_priv(dev);
+	struct skge_hw *hw = skge->hw;
+	int port = skge->port;
+
+	ecmd->rx_coalesce_usecs = 0;
+	ecmd->tx_coalesce_usecs = 0;
+
+	if (skge_read32(hw, B2_IRQM_CTRL) & TIM_START) {
+		u32 delay = skge_clk2usec(hw, skge_read32(hw, B2_IRQM_INI));
+		u32 msk = skge_read32(hw, B2_IRQM_MSK);
+
+		if (msk & rxirqmask[port])
+			ecmd->rx_coalesce_usecs = delay;
+		if (msk & txirqmask[port])
+			ecmd->tx_coalesce_usecs = delay;
+	}
+
+	return 0;
+}
+
+/* Note: interrupt timer is per board, but can turn on/off per port */
+static int skge_set_coalesce(struct net_device *dev,
+			     struct ethtool_coalesce *ecmd)
+{
+	struct skge_port *skge = netdev_priv(dev);
+	struct skge_hw *hw = skge->hw;
+	int port = skge->port;
+	u32 msk = skge_read32(hw, B2_IRQM_MSK);
+	u32 delay = 25;
+
+	if (ecmd->rx_coalesce_usecs == 0)
+		msk &= ~rxirqmask[port];
+	else if (ecmd->rx_coalesce_usecs < 25 ||
+		 ecmd->rx_coalesce_usecs > 33333)
+		return -EINVAL;
+	else {
+		msk |= rxirqmask[port];
+		delay = ecmd->rx_coalesce_usecs;
+	}
+
+	if (ecmd->tx_coalesce_usecs == 0)
+		msk &= ~txirqmask[port];
+	else if (ecmd->tx_coalesce_usecs < 25 ||
+		 ecmd->tx_coalesce_usecs > 33333)
+		return -EINVAL;
+	else {
+		msk |= txirqmask[port];
+		delay = min(delay, ecmd->rx_coalesce_usecs);
+	}
+
+	skge_write32(hw, B2_IRQM_MSK, msk);
+	if (msk == 0)
+		skge_write32(hw, B2_IRQM_CTRL, TIM_STOP);
+	else {
+		skge_write32(hw, B2_IRQM_INI, skge_usecs2clk(hw, delay));
+		skge_write32(hw, B2_IRQM_CTRL, TIM_START);
+	}
+	return 0;
+}
+
+enum led_mode { LED_MODE_OFF, LED_MODE_ON, LED_MODE_TST };
+static void skge_led(struct skge_port *skge, enum led_mode mode)
+{
+	struct skge_hw *hw = skge->hw;
+	int port = skge->port;
+
+	spin_lock_bh(&hw->phy_lock);
+	if (hw->chip_id == CHIP_ID_GENESIS) {
+		switch (mode) {
+		case LED_MODE_OFF:
+			xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, PHY_B_PEC_LED_OFF);
+			skge_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_OFF);
+			skge_write32(hw, SK_REG(port, RX_LED_VAL), 0);
+			skge_write8(hw, SK_REG(port, RX_LED_CTRL), LED_T_OFF);
+			break;
+
+		case LED_MODE_ON:
+			skge_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_ON);
+			skge_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_LINKSYNC_ON);
+
+			skge_write8(hw, SK_REG(port, RX_LED_CTRL), LED_START);
+			skge_write8(hw, SK_REG(port, TX_LED_CTRL), LED_START);
+
+			break;
+
+		case LED_MODE_TST:
+			skge_write8(hw, SK_REG(port, RX_LED_TST), LED_T_ON);
+			skge_write32(hw, SK_REG(port, RX_LED_VAL), 100);
+			skge_write8(hw, SK_REG(port, RX_LED_CTRL), LED_START);
+
+			xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, PHY_B_PEC_LED_ON);
+			break;
+		}
+	} else {
+		switch (mode) {
+		case LED_MODE_OFF:
+			gm_phy_write(hw, port, PHY_MARV_LED_CTRL, 0);
+			gm_phy_write(hw, port, PHY_MARV_LED_OVER,
+				     PHY_M_LED_MO_DUP(MO_LED_OFF)  |
+				     PHY_M_LED_MO_10(MO_LED_OFF)   |
+				     PHY_M_LED_MO_100(MO_LED_OFF)  |
+				     PHY_M_LED_MO_1000(MO_LED_OFF) |
+				     PHY_M_LED_MO_RX(MO_LED_OFF));
+			break;
+		case LED_MODE_ON:
+			gm_phy_write(hw, port, PHY_MARV_LED_CTRL,
+				     PHY_M_LED_PULS_DUR(PULS_170MS) |
+				     PHY_M_LED_BLINK_RT(BLINK_84MS) |
+				     PHY_M_LEDC_TX_CTRL |
+				     PHY_M_LEDC_DP_CTRL);
+		
+			gm_phy_write(hw, port, PHY_MARV_LED_OVER,
+				     PHY_M_LED_MO_RX(MO_LED_OFF) |
+				     (skge->speed == SPEED_100 ?
+				      PHY_M_LED_MO_100(MO_LED_ON) : 0));
+			break;
+		case LED_MODE_TST:
+			gm_phy_write(hw, port, PHY_MARV_LED_CTRL, 0);
+			gm_phy_write(hw, port, PHY_MARV_LED_OVER,
+				     PHY_M_LED_MO_DUP(MO_LED_ON)  |
+				     PHY_M_LED_MO_10(MO_LED_ON)   |
+				     PHY_M_LED_MO_100(MO_LED_ON)  |
+				     PHY_M_LED_MO_1000(MO_LED_ON) |
+				     PHY_M_LED_MO_RX(MO_LED_ON));
+		}
+	}
+	spin_unlock_bh(&hw->phy_lock);
+}
+
+/* blink LED's for finding board */
+static int skge_phys_id(struct net_device *dev, u32 data)
+{
+	struct skge_port *skge = netdev_priv(dev);
+	unsigned long ms;
+	enum led_mode mode = LED_MODE_TST;
+
+	if (!data || data > (u32)(MAX_SCHEDULE_TIMEOUT / HZ))
+		ms = jiffies_to_msecs(MAX_SCHEDULE_TIMEOUT / HZ) * 1000;
+	else
+		ms = data * 1000;
+
+	while (ms > 0) {
+		skge_led(skge, mode);
+		mode ^= LED_MODE_TST;
+
+		if (msleep_interruptible(BLINK_MS))
+			break;
+		ms -= BLINK_MS;
+	}
+
+	/* back to regular LED state */
+	skge_led(skge, netif_running(dev) ? LED_MODE_ON : LED_MODE_OFF);
+
+	return 0;
+}
+
+static struct ethtool_ops skge_ethtool_ops = {
+	.get_settings	= skge_get_settings,
+	.set_settings	= skge_set_settings,
+	.get_drvinfo	= skge_get_drvinfo,
+	.get_regs_len	= skge_get_regs_len,
+	.get_regs	= skge_get_regs,
+	.get_wol	= skge_get_wol,
+	.set_wol	= skge_set_wol,
+	.get_msglevel	= skge_get_msglevel,
+	.set_msglevel	= skge_set_msglevel,
+	.nway_reset	= skge_nway_reset,
+	.get_link	= ethtool_op_get_link,
+	.get_ringparam	= skge_get_ring_param,
+	.set_ringparam	= skge_set_ring_param,
+	.get_pauseparam = skge_get_pauseparam,
+	.set_pauseparam = skge_set_pauseparam,
+	.get_coalesce	= skge_get_coalesce,
+	.set_coalesce	= skge_set_coalesce,
+	.get_sg		= ethtool_op_get_sg,
+	.set_sg		= skge_set_sg,
+	.get_tx_csum	= ethtool_op_get_tx_csum,
+	.set_tx_csum	= skge_set_tx_csum,
+	.get_rx_csum	= skge_get_rx_csum,
+	.set_rx_csum	= skge_set_rx_csum,
+	.get_strings	= skge_get_strings,
+	.phys_id	= skge_phys_id,
+	.get_stats_count = skge_get_stats_count,
+	.get_ethtool_stats = skge_get_ethtool_stats,
+};
+
+/*
+ * Allocate ring elements and chain them together
+ * One-to-one association of board descriptors with ring elements
+ */
+static int skge_ring_alloc(struct skge_ring *ring, void *vaddr, u64 base)
+{
+	struct skge_tx_desc *d;
+	struct skge_element *e;
+	int i;
+
+	ring->start = kmalloc(sizeof(*e)*ring->count, GFP_KERNEL);
+	if (!ring->start)
+		return -ENOMEM;
+
+	for (i = 0, e = ring->start, d = vaddr; i < ring->count; i++, e++, d++) {
+		e->desc = d;
+		e->skb = NULL;
+		if (i == ring->count - 1) {
+			e->next = ring->start;
+			d->next_offset = base;
+		} else {
+			e->next = e + 1;
+			d->next_offset = base + (i+1) * sizeof(*d);
+		}
+	}
+	ring->to_use = ring->to_clean = ring->start;
+
+	return 0;
+}
+
+static struct sk_buff *skge_rx_alloc(struct net_device *dev, unsigned int size)
+{
+	struct sk_buff *skb = dev_alloc_skb(size);
+
+	if (likely(skb)) {
+		skb->dev = dev;
+		skb_reserve(skb, NET_IP_ALIGN);
+	}
+	return skb;
+}
+
+/* Allocate and setup a new buffer for receiving */
+static void skge_rx_setup(struct skge_port *skge, struct skge_element *e,
+			  struct sk_buff *skb, unsigned int bufsize)
+{
+	struct skge_rx_desc *rd = e->desc;
+	u64 map;
+
+	map = pci_map_single(skge->hw->pdev, skb->data, bufsize,
+			     PCI_DMA_FROMDEVICE);
+
+	rd->dma_lo = map;
+	rd->dma_hi = map >> 32;
+	e->skb = skb;
+	rd->csum1_start = ETH_HLEN;
+	rd->csum2_start = ETH_HLEN;
+	rd->csum1 = 0;
+	rd->csum2 = 0;
+
+	wmb();
+
+	rd->control = BMU_OWN | BMU_STF | BMU_IRQ_EOF | BMU_TCP_CHECK | bufsize;
+	pci_unmap_addr_set(e, mapaddr, map);
+	pci_unmap_len_set(e, maplen, bufsize);
+}
+
+/* Resume receiving using existing skb,
+ * Note: DMA address is not changed by chip.
+ * 	 MTU not changed while receiver active.
+ */
+static void skge_rx_reuse(struct skge_element *e, unsigned int size)
+{
+	struct skge_rx_desc *rd = e->desc;
+
+	rd->csum2 = 0;
+	rd->csum2_start = ETH_HLEN;
+
+	wmb();
+
+	rd->control = BMU_OWN | BMU_STF | BMU_IRQ_EOF | BMU_TCP_CHECK | size;
+}
+
+
+/* Free all  buffers in receive ring, assumes receiver stopped */
+static void skge_rx_clean(struct skge_port *skge)
+{
+	struct skge_hw *hw = skge->hw;
+	struct skge_ring *ring = &skge->rx_ring;
+	struct skge_element *e;
+
+	e = ring->start;
+	do {
+		struct skge_rx_desc *rd = e->desc;
+		rd->control = 0;
+		if (e->skb) {
+			pci_unmap_single(hw->pdev,
+					 pci_unmap_addr(e, mapaddr),
+					 pci_unmap_len(e, maplen),
+					 PCI_DMA_FROMDEVICE);
+			dev_kfree_skb(e->skb);
+			e->skb = NULL;
+		}
+	} while ((e = e->next) != ring->start);
+}
+
+
+/* Allocate buffers for receive ring
+ * For receive:  to_clean is next received frame.
+ */
+static int skge_rx_fill(struct skge_port *skge)
+{
+	struct skge_ring *ring = &skge->rx_ring;
+	struct skge_element *e;
+	unsigned int bufsize = skge->rx_buf_size;
+
+	e = ring->start;
+	do {
+		struct sk_buff *skb = skge_rx_alloc(skge->netdev, bufsize);
+
+		if (!skb)
+			return -ENOMEM;
+
+		skge_rx_setup(skge, e, skb, bufsize);
+	} while ( (e = e->next) != ring->start);
+
+	ring->to_clean = ring->start;
+	return 0;
+}
+
+static void skge_link_up(struct skge_port *skge)
+{
+	netif_carrier_on(skge->netdev);
+	if (skge->tx_avail > MAX_SKB_FRAGS + 1)
+		netif_wake_queue(skge->netdev);
+
+	if (netif_msg_link(skge))
+		printk(KERN_INFO PFX
+		       "%s: Link is up at %d Mbps, %s duplex, flow control %s\n",
+		       skge->netdev->name, skge->speed,
+		       skge->duplex == DUPLEX_FULL ? "full" : "half",
+		       (skge->flow_control == FLOW_MODE_NONE) ? "none" :
+		       (skge->flow_control == FLOW_MODE_LOC_SEND) ? "tx only" :
+		       (skge->flow_control == FLOW_MODE_REM_SEND) ? "rx only" :
+		       (skge->flow_control == FLOW_MODE_SYMMETRIC) ? "tx and rx" :
+		       "unknown");
+}
+
+static void skge_link_down(struct skge_port *skge)
+{
+	netif_carrier_off(skge->netdev);
+	netif_stop_queue(skge->netdev);
+
+	if (netif_msg_link(skge))
+		printk(KERN_INFO PFX "%s: Link is down.\n", skge->netdev->name);
+}
+
+static u16 xm_phy_read(struct skge_hw *hw, int port, u16 reg)
+{
+	int i;
+	u16 v;
+
+	xm_write16(hw, port, XM_PHY_ADDR, reg | hw->phy_addr);
+	v = xm_read16(hw, port, XM_PHY_DATA);
+
+	/* Need to wait for external PHY */
+	for (i = 0; i < PHY_RETRIES; i++) {
+		udelay(1);
+		if (xm_read16(hw, port, XM_MMU_CMD)
+		    & XM_MMU_PHY_RDY)
+			goto ready;
+	}
+
+	printk(KERN_WARNING PFX "%s: phy read timed out\n",
+	       hw->dev[port]->name);
+	return 0;
+ ready:
+	v = xm_read16(hw, port, XM_PHY_DATA);
+
+	return v;
+}
+
+static void xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val)
+{
+	int i;
+
+	xm_write16(hw, port, XM_PHY_ADDR, reg | hw->phy_addr);
+	for (i = 0; i < PHY_RETRIES; i++) {
+		if (!(xm_read16(hw, port, XM_MMU_CMD) & XM_MMU_PHY_BUSY))
+			goto ready;
+		udelay(1);
+	}
+	printk(KERN_WARNING PFX "%s: phy write failed to come ready\n",
+	       hw->dev[port]->name);
+
+
+ ready:
+	xm_write16(hw, port, XM_PHY_DATA, val);
+	for (i = 0; i < PHY_RETRIES; i++) {
+		udelay(1);
+		if (!(xm_read16(hw, port, XM_MMU_CMD) & XM_MMU_PHY_BUSY))
+			return;
+	}
+	printk(KERN_WARNING PFX "%s: phy write timed out\n",
+		       hw->dev[port]->name);
+}
+
+static void genesis_init(struct skge_hw *hw)
+{
+	/* set blink source counter */
+	skge_write32(hw, B2_BSC_INI, (SK_BLK_DUR * SK_FACT_53) / 100);
+	skge_write8(hw, B2_BSC_CTRL, BSC_START);
+
+	/* configure mac arbiter */
+	skge_write16(hw, B3_MA_TO_CTRL, MA_RST_CLR);
+
+	/* configure mac arbiter timeout values */
+	skge_write8(hw, B3_MA_TOINI_RX1, SK_MAC_TO_53);
+	skge_write8(hw, B3_MA_TOINI_RX2, SK_MAC_TO_53);
+	skge_write8(hw, B3_MA_TOINI_TX1, SK_MAC_TO_53);
+	skge_write8(hw, B3_MA_TOINI_TX2, SK_MAC_TO_53);
+
+	skge_write8(hw, B3_MA_RCINI_RX1, 0);
+	skge_write8(hw, B3_MA_RCINI_RX2, 0);
+	skge_write8(hw, B3_MA_RCINI_TX1, 0);
+	skge_write8(hw, B3_MA_RCINI_TX2, 0);
+
+	/* configure packet arbiter timeout */
+	skge_write16(hw, B3_PA_CTRL, PA_RST_CLR);
+	skge_write16(hw, B3_PA_TOINI_RX1, SK_PKT_TO_MAX);
+	skge_write16(hw, B3_PA_TOINI_TX1, SK_PKT_TO_MAX);
+	skge_write16(hw, B3_PA_TOINI_RX2, SK_PKT_TO_MAX);
+	skge_write16(hw, B3_PA_TOINI_TX2, SK_PKT_TO_MAX);
+}
+
+static void genesis_reset(struct skge_hw *hw, int port)
+{
+	const u8 zero[8]  = { 0 };
+
+	/* reset the statistics module */
+	xm_write32(hw, port, XM_GP_PORT, XM_GP_RES_STAT);
+	xm_write16(hw, port, XM_IMSK, 0xffff);	/* disable XMAC IRQs */
+	xm_write32(hw, port, XM_MODE, 0);		/* clear Mode Reg */
+	xm_write16(hw, port, XM_TX_CMD, 0);	/* reset TX CMD Reg */
+	xm_write16(hw, port, XM_RX_CMD, 0);	/* reset RX CMD Reg */
+
+	/* disable Broadcom PHY IRQ */
+	xm_write16(hw, port, PHY_BCOM_INT_MASK, 0xffff);
+
+	xm_outhash(hw, port, XM_HSM, zero);
+}
+
+
+/* Convert mode to MII values  */
+static const u16 phy_pause_map[] = {
+	[FLOW_MODE_NONE] =	0,
+	[FLOW_MODE_LOC_SEND] =	PHY_AN_PAUSE_ASYM,
+	[FLOW_MODE_SYMMETRIC] = PHY_AN_PAUSE_CAP,
+	[FLOW_MODE_REM_SEND]  = PHY_AN_PAUSE_CAP | PHY_AN_PAUSE_ASYM,
+};
+
+
+/* Check status of Broadcom phy link */
+static void bcom_check_link(struct skge_hw *hw, int port)
+{
+	struct net_device *dev = hw->dev[port];
+	struct skge_port *skge = netdev_priv(dev);
+	u16 status;
+
+	/* read twice because of latch */
+	(void) xm_phy_read(hw, port, PHY_BCOM_STAT);
+	status = xm_phy_read(hw, port, PHY_BCOM_STAT);
+
+	pr_debug("bcom_check_link status=0x%x\n", status);
+
+	if ((status & PHY_ST_LSYNC) == 0) {
+		u16 cmd = xm_read16(hw, port, XM_MMU_CMD);
+		cmd &= ~(XM_MMU_ENA_RX | XM_MMU_ENA_TX);
+		xm_write16(hw, port, XM_MMU_CMD, cmd);
+		/* dummy read to ensure writing */
+		(void) xm_read16(hw, port, XM_MMU_CMD);
+
+		if (netif_carrier_ok(dev))
+			skge_link_down(skge);
+	} else {
+		if (skge->autoneg == AUTONEG_ENABLE &&
+		    (status & PHY_ST_AN_OVER)) {
+			u16 lpa = xm_phy_read(hw, port, PHY_BCOM_AUNE_LP);
+			u16 aux = xm_phy_read(hw, port, PHY_BCOM_AUX_STAT);
+
+			if (lpa & PHY_B_AN_RF) {
+				printk(KERN_NOTICE PFX "%s: remote fault\n",
+				       dev->name);
+				return;
+			}
+
+			/* Check Duplex mismatch */
+			switch (aux & PHY_B_AS_AN_RES_MSK) {
+			case PHY_B_RES_1000FD:
+				skge->duplex = DUPLEX_FULL;
+				break;
+			case PHY_B_RES_1000HD:
+				skge->duplex = DUPLEX_HALF;
+				break;
+			default:
+				printk(KERN_NOTICE PFX "%s: duplex mismatch\n",
+				       dev->name);
+				return;
+			}
+
+
+			/* We are using IEEE 802.3z/D5.0 Table 37-4 */
+			switch (aux & PHY_B_AS_PAUSE_MSK) {
+			case PHY_B_AS_PAUSE_MSK:
+				skge->flow_control = FLOW_MODE_SYMMETRIC;
+				break;
+			case PHY_B_AS_PRR:
+				skge->flow_control = FLOW_MODE_REM_SEND;
+				break;
+			case PHY_B_AS_PRT:
+				skge->flow_control = FLOW_MODE_LOC_SEND;
+				break;
+			default:
+				skge->flow_control = FLOW_MODE_NONE;
+			}
+
+			skge->speed = SPEED_1000;
+		}
+
+		if (!netif_carrier_ok(dev))
+			genesis_link_up(skge);
+	}
+}
+
+/* Broadcom 5400 only supports giagabit! SysKonnect did not put an additional
+ * Phy on for 100 or 10Mbit operation
+ */
+static void bcom_phy_init(struct skge_port *skge, int jumbo)
+{
+	struct skge_hw *hw = skge->hw;
+	int port = skge->port;
+	int i;
+	u16 id1, r, ext, ctl;
+
+	/* magic workaround patterns for Broadcom */
+	static const struct {
+		u16 reg;
+		u16 val;
+	} A1hack[] = {
+		{ 0x18, 0x0c20 }, { 0x17, 0x0012 }, { 0x15, 0x1104 },
+		{ 0x17, 0x0013 }, { 0x15, 0x0404 }, { 0x17, 0x8006 },
+		{ 0x15, 0x0132 }, { 0x17, 0x8006 }, { 0x15, 0x0232 },
+		{ 0x17, 0x800D }, { 0x15, 0x000F }, { 0x18, 0x0420 },
+	}, C0hack[] = {
+		{ 0x18, 0x0c20 }, { 0x17, 0x0012 }, { 0x15, 0x1204 },
+		{ 0x17, 0x0013 }, { 0x15, 0x0A04 }, { 0x18, 0x0420 },
+	};
+
+	pr_debug("bcom_phy_init\n");
+
+	/* read Id from external PHY (all have the same address) */
+	id1 = xm_phy_read(hw, port, PHY_XMAC_ID1);
+
+	/* Optimize MDIO transfer by suppressing preamble. */
+	r = xm_read16(hw, port, XM_MMU_CMD);
+	r |=  XM_MMU_NO_PRE;
+	xm_write16(hw, port, XM_MMU_CMD,r);
+
+	switch (id1) {
+	case PHY_BCOM_ID1_C0:
+		/*
+		 * Workaround BCOM Errata for the C0 type.
+		 * Write magic patterns to reserved registers.
+		 */
+		for (i = 0; i < ARRAY_SIZE(C0hack); i++)
+			xm_phy_write(hw, port,
+				     C0hack[i].reg, C0hack[i].val);
+
+		break;
+	case PHY_BCOM_ID1_A1:
+		/*
+		 * Workaround BCOM Errata for the A1 type.
+		 * Write magic patterns to reserved registers.
+		 */
+		for (i = 0; i < ARRAY_SIZE(A1hack); i++)
+			xm_phy_write(hw, port,
+				     A1hack[i].reg, A1hack[i].val);
+		break;
+	}
+
+	/*
+	 * Workaround BCOM Errata (#10523) for all BCom PHYs.
+	 * Disable Power Management after reset.
+	 */
+	r = xm_phy_read(hw, port, PHY_BCOM_AUX_CTRL);
+	r |= PHY_B_AC_DIS_PM;
+	xm_phy_write(hw, port, PHY_BCOM_AUX_CTRL, r);
+
+	/* Dummy read */
+	xm_read16(hw, port, XM_ISRC);
+
+	ext = PHY_B_PEC_EN_LTR; /* enable tx led */
+	ctl = PHY_CT_SP1000;	/* always 1000mbit */
+
+	if (skge->autoneg == AUTONEG_ENABLE) {
+		/*
+		 * Workaround BCOM Errata #1 for the C5 type.
+		 * 1000Base-T Link Acquisition Failure in Slave Mode
+		 * Set Repeater/DTE bit 10 of the 1000Base-T Control Register
+		 */
+		u16 adv = PHY_B_1000C_RD;
+		if (skge->advertising & ADVERTISED_1000baseT_Half)
+			adv |= PHY_B_1000C_AHD;
+		if (skge->advertising & ADVERTISED_1000baseT_Full)
+			adv |= PHY_B_1000C_AFD;
+		xm_phy_write(hw, port, PHY_BCOM_1000T_CTRL, adv);
+
+		ctl |= PHY_CT_ANE | PHY_CT_RE_CFG;
+	} else {
+		if (skge->duplex == DUPLEX_FULL)
+			ctl |= PHY_CT_DUP_MD;
+		/* Force to slave */
+		xm_phy_write(hw, port, PHY_BCOM_1000T_CTRL, PHY_B_1000C_MSE);
+	}
+
+	/* Set autonegotiation pause parameters */
+	xm_phy_write(hw, port, PHY_BCOM_AUNE_ADV,
+		     phy_pause_map[skge->flow_control] | PHY_AN_CSMA);
+
+	/* Handle Jumbo frames */
+	if (jumbo) {
+		xm_phy_write(hw, port, PHY_BCOM_AUX_CTRL,
+			     PHY_B_AC_TX_TST | PHY_B_AC_LONG_PACK);
+
+		ext |= PHY_B_PEC_HIGH_LA;
+
+	}
+
+	xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, ext);
+	xm_phy_write(hw, port, PHY_BCOM_CTRL, ctl);
+
+	/* Use link status change interrrupt */
+	xm_phy_write(hw, port, PHY_BCOM_INT_MASK, PHY_B_DEF_MSK);
+
+	bcom_check_link(hw, port);
+}
+
+static void genesis_mac_init(struct skge_hw *hw, int port)
+{
+	struct net_device *dev = hw->dev[port];
+	struct skge_port *skge = netdev_priv(dev);
+	int jumbo = hw->dev[port]->mtu > ETH_DATA_LEN;
+	int i;
+	u32 r;
+	const u8 zero[6]  = { 0 };
+
+	/* Clear MIB counters */
+	xm_write16(hw, port, XM_STAT_CMD,
+			XM_SC_CLR_RXC | XM_SC_CLR_TXC);
+	/* Clear two times according to Errata #3 */
+	xm_write16(hw, port, XM_STAT_CMD,
+			XM_SC_CLR_RXC | XM_SC_CLR_TXC);
+
+	/* Unreset the XMAC. */
+	skge_write16(hw, SK_REG(port, TX_MFF_CTRL1), MFF_CLR_MAC_RST);
+
+	/*
+	 * Perform additional initialization for external PHYs,
+	 * namely for the 1000baseTX cards that use the XMAC's
+	 * GMII mode.
+	 */
+	/* Take external Phy out of reset */
+	r = skge_read32(hw, B2_GP_IO);
+	if (port == 0)
+		r |= GP_DIR_0|GP_IO_0;
+	else
+		r |= GP_DIR_2|GP_IO_2;
+
+	skge_write32(hw, B2_GP_IO, r);
+	skge_read32(hw, B2_GP_IO);
+
+	/* Enable GMII interfac */
+	xm_write16(hw, port, XM_HW_CFG, XM_HW_GMII_MD);
+
+	bcom_phy_init(skge, jumbo);
+
+	/* Set Station Address */
+	xm_outaddr(hw, port, XM_SA, dev->dev_addr);
+
+	/* We don't use match addresses so clear */
+	for (i = 1; i < 16; i++)
+		xm_outaddr(hw, port, XM_EXM(i), zero);
+
+	/* configure Rx High Water Mark (XM_RX_HI_WM) */
+	xm_write16(hw, port, XM_RX_HI_WM, 1450);
+
+	/* We don't need the FCS appended to the packet. */
+	r = XM_RX_LENERR_OK | XM_RX_STRIP_FCS;
+	if (jumbo)
+		r |= XM_RX_BIG_PK_OK;
+
+	if (skge->duplex == DUPLEX_HALF) {
+		/*
+		 * If in manual half duplex mode the other side might be in
+		 * full duplex mode, so ignore if a carrier extension is not seen
+		 * on frames received
+		 */
+		r |= XM_RX_DIS_CEXT;
+	}
+	xm_write16(hw, port, XM_RX_CMD, r);
+
+
+	/* We want short frames padded to 60 bytes. */
+	xm_write16(hw, port, XM_TX_CMD, XM_TX_AUTO_PAD);
+
+	/*
+	 * Bump up the transmit threshold. This helps hold off transmit
+	 * underruns when we're blasting traffic from both ports at once.
+	 */
+	xm_write16(hw, port, XM_TX_THR, 512);
+
+	/*
+	 * Enable the reception of all error frames. This is is
+	 * a necessary evil due to the design of the XMAC. The
+	 * XMAC's receive FIFO is only 8K in size, however jumbo
+	 * frames can be up to 9000 bytes in length. When bad
+	 * frame filtering is enabled, the XMAC's RX FIFO operates
+	 * in 'store and forward' mode. For this to work, the
+	 * entire frame has to fit into the FIFO, but that means
+	 * that jumbo frames larger than 8192 bytes will be
+	 * truncated. Disabling all bad frame filtering causes
+	 * the RX FIFO to operate in streaming mode, in which
+	 * case the XMAC will start transfering frames out of the
+	 * RX FIFO as soon as the FIFO threshold is reached.
+	 */
+	xm_write32(hw, port, XM_MODE, XM_DEF_MODE);
+
+
+	/*
+	 * Initialize the Receive Counter Event Mask (XM_RX_EV_MSK)
+	 *	- Enable all bits excepting 'Octets Rx OK Low CntOv'
+	 *	  and 'Octets Rx OK Hi Cnt Ov'.
+	 */
+	xm_write32(hw, port, XM_RX_EV_MSK, XMR_DEF_MSK);
+
+	/*
+	 * Initialize the Transmit Counter Event Mask (XM_TX_EV_MSK)
+	 *	- Enable all bits excepting 'Octets Tx OK Low CntOv'
+	 *	  and 'Octets Tx OK Hi Cnt Ov'.
+	 */
+	xm_write32(hw, port, XM_TX_EV_MSK, XMT_DEF_MSK);
+
+	/* Configure MAC arbiter */
+	skge_write16(hw, B3_MA_TO_CTRL, MA_RST_CLR);
+
+	/* configure timeout values */
+	skge_write8(hw, B3_MA_TOINI_RX1, 72);
+	skge_write8(hw, B3_MA_TOINI_RX2, 72);
+	skge_write8(hw, B3_MA_TOINI_TX1, 72);
+	skge_write8(hw, B3_MA_TOINI_TX2, 72);
+
+	skge_write8(hw, B3_MA_RCINI_RX1, 0);
+	skge_write8(hw, B3_MA_RCINI_RX2, 0);
+	skge_write8(hw, B3_MA_RCINI_TX1, 0);
+	skge_write8(hw, B3_MA_RCINI_TX2, 0);
+
+	/* Configure Rx MAC FIFO */
+	skge_write8(hw, SK_REG(port, RX_MFF_CTRL2), MFF_RST_CLR);
+	skge_write16(hw, SK_REG(port, RX_MFF_CTRL1), MFF_ENA_TIM_PAT);
+	skge_write8(hw, SK_REG(port, RX_MFF_CTRL2), MFF_ENA_OP_MD);
+
+	/* Configure Tx MAC FIFO */
+	skge_write8(hw, SK_REG(port, TX_MFF_CTRL2), MFF_RST_CLR);
+	skge_write16(hw, SK_REG(port, TX_MFF_CTRL1), MFF_TX_CTRL_DEF);
+	skge_write8(hw, SK_REG(port, TX_MFF_CTRL2), MFF_ENA_OP_MD);
+
+	if (jumbo) {
+		/* Enable frame flushing if jumbo frames used */
+		skge_write16(hw, SK_REG(port,RX_MFF_CTRL1), MFF_ENA_FLUSH);
+	} else {
+		/* enable timeout timers if normal frames */
+		skge_write16(hw, B3_PA_CTRL,
+			     (port == 0) ? PA_ENA_TO_TX1 : PA_ENA_TO_TX2);
+	}
+}
+
+static void genesis_stop(struct skge_port *skge)
+{
+	struct skge_hw *hw = skge->hw;
+	int port = skge->port;
+	u32 reg;
+
+	/* Clear Tx packet arbiter timeout IRQ */
+	skge_write16(hw, B3_PA_CTRL,
+		     port == 0 ? PA_CLR_TO_TX1 : PA_CLR_TO_TX2);
+
+	/*
+	 * If the transfer stucks at the MAC the STOP command will not
+	 * terminate if we don't flush the XMAC's transmit FIFO !
+	 */
+	xm_write32(hw, port, XM_MODE,
+			xm_read32(hw, port, XM_MODE)|XM_MD_FTF);
+
+
+	/* Reset the MAC */
+	skge_write16(hw, SK_REG(port, TX_MFF_CTRL1), MFF_SET_MAC_RST);
+
+	/* For external PHYs there must be special handling */
+	reg = skge_read32(hw, B2_GP_IO);
+	if (port == 0) {
+		reg |= GP_DIR_0;
+		reg &= ~GP_IO_0;
+	} else {
+		reg |= GP_DIR_2;
+		reg &= ~GP_IO_2;
+	}
+	skge_write32(hw, B2_GP_IO, reg);
+	skge_read32(hw, B2_GP_IO);
+
+	xm_write16(hw, port, XM_MMU_CMD,
+			xm_read16(hw, port, XM_MMU_CMD)
+			& ~(XM_MMU_ENA_RX | XM_MMU_ENA_TX));
+
+	xm_read16(hw, port, XM_MMU_CMD);
+}
+
+
+static void genesis_get_stats(struct skge_port *skge, u64 *data)
+{
+	struct skge_hw *hw = skge->hw;
+	int port = skge->port;
+	int i;
+	unsigned long timeout = jiffies + HZ;
+
+	xm_write16(hw, port,
+			XM_STAT_CMD, XM_SC_SNP_TXC | XM_SC_SNP_RXC);
+
+	/* wait for update to complete */
+	while (xm_read16(hw, port, XM_STAT_CMD)
+	       & (XM_SC_SNP_TXC | XM_SC_SNP_RXC)) {
+		if (time_after(jiffies, timeout))
+			break;
+		udelay(10);
+	}
+
+	/* special case for 64 bit octet counter */
+	data[0] = (u64) xm_read32(hw, port, XM_TXO_OK_HI) << 32
+		| xm_read32(hw, port, XM_TXO_OK_LO);
+	data[1] = (u64) xm_read32(hw, port, XM_RXO_OK_HI) << 32
+		| xm_read32(hw, port, XM_RXO_OK_LO);
+
+	for (i = 2; i < ARRAY_SIZE(skge_stats); i++)
+		data[i] = xm_read32(hw, port, skge_stats[i].xmac_offset);
+}
+
+static void genesis_mac_intr(struct skge_hw *hw, int port)
+{
+	struct skge_port *skge = netdev_priv(hw->dev[port]);
+	u16 status = xm_read16(hw, port, XM_ISRC);
+
+	if (netif_msg_intr(skge))
+		printk(KERN_DEBUG PFX "%s: mac interrupt status 0x%x\n",
+		       skge->netdev->name, status);
+
+	if (status & XM_IS_TXF_UR) {
+		xm_write32(hw, port, XM_MODE, XM_MD_FTF);
+		++skge->net_stats.tx_fifo_errors;
+	}
+	if (status & XM_IS_RXF_OV) {
+		xm_write32(hw, port, XM_MODE, XM_MD_FRF);
+		++skge->net_stats.rx_fifo_errors;
+	}
+}
+
+static void gm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val)
+{
+	int i;
+
+	gma_write16(hw, port, GM_SMI_DATA, val);
+	gma_write16(hw, port, GM_SMI_CTRL,
+			 GM_SMI_CT_PHY_AD(hw->phy_addr) | GM_SMI_CT_REG_AD(reg));
+	for (i = 0; i < PHY_RETRIES; i++) {
+		udelay(1);
+
+		if (!(gma_read16(hw, port, GM_SMI_CTRL) & GM_SMI_CT_BUSY))
+			break;
+	}
+}
+
+static u16 gm_phy_read(struct skge_hw *hw, int port, u16 reg)
+{
+	int i;
+
+	gma_write16(hw, port, GM_SMI_CTRL,
+			 GM_SMI_CT_PHY_AD(hw->phy_addr)
+			 | GM_SMI_CT_REG_AD(reg) | GM_SMI_CT_OP_RD);
+
+	for (i = 0; i < PHY_RETRIES; i++) {
+		udelay(1);
+		if (gma_read16(hw, port, GM_SMI_CTRL) & GM_SMI_CT_RD_VAL)
+			goto ready;
+	}
+
+	printk(KERN_WARNING PFX "%s: phy read timeout\n",
+	       hw->dev[port]->name);
+	return 0;
+ ready:
+	return gma_read16(hw, port, GM_SMI_DATA);
+}
+
+static void genesis_link_up(struct skge_port *skge)
+{
+	struct skge_hw *hw = skge->hw;
+	int port = skge->port;
+	u16 cmd;
+	u32 mode, msk;
+
+	pr_debug("genesis_link_up\n");
+	cmd = xm_read16(hw, port, XM_MMU_CMD);
+
+	/*
+	 * enabling pause frame reception is required for 1000BT
+	 * because the XMAC is not reset if the link is going down
+	 */
+	if (skge->flow_control == FLOW_MODE_NONE ||
+	    skge->flow_control == FLOW_MODE_LOC_SEND)
+		/* Disable Pause Frame Reception */
+		cmd |= XM_MMU_IGN_PF;
+	else
+		/* Enable Pause Frame Reception */
+		cmd &= ~XM_MMU_IGN_PF;
+
+	xm_write16(hw, port, XM_MMU_CMD, cmd);
+
+	mode = xm_read32(hw, port, XM_MODE);
+	if (skge->flow_control == FLOW_MODE_SYMMETRIC ||
+	    skge->flow_control == FLOW_MODE_LOC_SEND) {
+		/*
+		 * Configure Pause Frame Generation
+		 * Use internal and external Pause Frame Generation.
+		 * Sending pause frames is edge triggered.
+		 * Send a Pause frame with the maximum pause time if
+		 * internal oder external FIFO full condition occurs.
+		 * Send a zero pause time frame to re-start transmission.
+		 */
+		/* XM_PAUSE_DA = '010000C28001' (default) */
+		/* XM_MAC_PTIME = 0xffff (maximum) */
+		/* remember this value is defined in big endian (!) */
+		xm_write16(hw, port, XM_MAC_PTIME, 0xffff);
+
+		mode |= XM_PAUSE_MODE;
+		skge_write16(hw, SK_REG(port, RX_MFF_CTRL1), MFF_ENA_PAUSE);
+	} else {
+		/*
+		 * disable pause frame generation is required for 1000BT
+		 * because the XMAC is not reset if the link is going down
+		 */
+		/* Disable Pause Mode in Mode Register */
+		mode &= ~XM_PAUSE_MODE;
+
+		skge_write16(hw, SK_REG(port, RX_MFF_CTRL1), MFF_DIS_PAUSE);
+	}
+
+	xm_write32(hw, port, XM_MODE, mode);
+
+	msk = XM_DEF_MSK;
+	/* disable GP0 interrupt bit for external Phy */
+	msk |= XM_IS_INP_ASS;
+
+	xm_write16(hw, port, XM_IMSK, msk);
+	xm_read16(hw, port, XM_ISRC);
+
+	/* get MMU Command Reg. */
+	cmd = xm_read16(hw, port, XM_MMU_CMD);
+	if (skge->duplex == DUPLEX_FULL)
+		cmd |= XM_MMU_GMII_FD;
+
+	/*
+	 * Workaround BCOM Errata (#10523) for all BCom Phys
+	 * Enable Power Management after link up
+	 */
+	xm_phy_write(hw, port, PHY_BCOM_AUX_CTRL,
+		     xm_phy_read(hw, port, PHY_BCOM_AUX_CTRL)
+		     & ~PHY_B_AC_DIS_PM);
+	xm_phy_write(hw, port, PHY_BCOM_INT_MASK, PHY_B_DEF_MSK);
+
+	/* enable Rx/Tx */
+	xm_write16(hw, port, XM_MMU_CMD,
+			cmd | XM_MMU_ENA_RX | XM_MMU_ENA_TX);
+	skge_link_up(skge);
+}
+
+
+static inline void bcom_phy_intr(struct skge_port *skge)
+{
+	struct skge_hw *hw = skge->hw;
+	int port = skge->port;
+	u16 isrc;
+
+	isrc = xm_phy_read(hw, port, PHY_BCOM_INT_STAT);
+	if (netif_msg_intr(skge))
+		printk(KERN_DEBUG PFX "%s: phy interrupt status 0x%x\n",
+		       skge->netdev->name, isrc);
+
+	if (isrc & PHY_B_IS_PSE)
+		printk(KERN_ERR PFX "%s: uncorrectable pair swap error\n",
+		       hw->dev[port]->name);
+
+	/* Workaround BCom Errata:
+	 *	enable and disable loopback mode if "NO HCD" occurs.
+	 */
+	if (isrc & PHY_B_IS_NO_HDCL) {
+		u16 ctrl = xm_phy_read(hw, port, PHY_BCOM_CTRL);
+		xm_phy_write(hw, port, PHY_BCOM_CTRL,
+				  ctrl | PHY_CT_LOOP);
+		xm_phy_write(hw, port, PHY_BCOM_CTRL,
+				  ctrl & ~PHY_CT_LOOP);
+	}
+
+	if (isrc & (PHY_B_IS_AN_PR | PHY_B_IS_LST_CHANGE))
+		bcom_check_link(hw, port);
+
+}
+
+/* Marvell Phy Initailization */
+static void yukon_init(struct skge_hw *hw, int port)
+{
+	struct skge_port *skge = netdev_priv(hw->dev[port]);
+	u16 ctrl, ct1000, adv;
+
+	pr_debug("yukon_init\n");
+	if (skge->autoneg == AUTONEG_ENABLE) {
+		u16 ectrl = gm_phy_read(hw, port, PHY_MARV_EXT_CTRL);
+
+		ectrl &= ~(PHY_M_EC_M_DSC_MSK | PHY_M_EC_S_DSC_MSK |
+			  PHY_M_EC_MAC_S_MSK);
+		ectrl |= PHY_M_EC_MAC_S(MAC_TX_CLK_25_MHZ);
+
+		ectrl |= PHY_M_EC_M_DSC(0) | PHY_M_EC_S_DSC(1);
+
+		gm_phy_write(hw, port, PHY_MARV_EXT_CTRL, ectrl);
+	}
+
+	ctrl = gm_phy_read(hw, port, PHY_MARV_CTRL);
+	if (skge->autoneg == AUTONEG_DISABLE)
+		ctrl &= ~PHY_CT_ANE;
+
+	ctrl |= PHY_CT_RESET;
+	gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl);
+
+	ctrl = 0;
+	ct1000 = 0;
+	adv = PHY_AN_CSMA;
+
+	if (skge->autoneg == AUTONEG_ENABLE) {
+		if (iscopper(hw)) {
+			if (skge->advertising & ADVERTISED_1000baseT_Full)
+				ct1000 |= PHY_M_1000C_AFD;
+			if (skge->advertising & ADVERTISED_1000baseT_Half)
+				ct1000 |= PHY_M_1000C_AHD;
+			if (skge->advertising & ADVERTISED_100baseT_Full)
+				adv |= PHY_M_AN_100_FD;
+			if (skge->advertising & ADVERTISED_100baseT_Half)
+				adv |= PHY_M_AN_100_HD;
+			if (skge->advertising & ADVERTISED_10baseT_Full)
+				adv |= PHY_M_AN_10_FD;
+			if (skge->advertising & ADVERTISED_10baseT_Half)
+				adv |= PHY_M_AN_10_HD;
+		} else	/* special defines for FIBER (88E1011S only) */
+			adv |= PHY_M_AN_1000X_AHD | PHY_M_AN_1000X_AFD;
+
+		/* Set Flow-control capabilities */
+		adv |= phy_pause_map[skge->flow_control];
+
+		/* Restart Auto-negotiation */
+		ctrl |= PHY_CT_ANE | PHY_CT_RE_CFG;
+	} else {
+		/* forced speed/duplex settings */
+		ct1000 = PHY_M_1000C_MSE;
+
+		if (skge->duplex == DUPLEX_FULL)
+			ctrl |= PHY_CT_DUP_MD;
+
+		switch (skge->speed) {
+		case SPEED_1000:
+			ctrl |= PHY_CT_SP1000;
+			break;
+		case SPEED_100:
+			ctrl |= PHY_CT_SP100;
+			break;
+		}
+
+		ctrl |= PHY_CT_RESET;
+	}
+
+	gm_phy_write(hw, port, PHY_MARV_1000T_CTRL, ct1000);
+
+	gm_phy_write(hw, port, PHY_MARV_AUNE_ADV, adv);
+	gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl);
+
+	/* Enable phy interrupt on autonegotiation complete (or link up) */
+	if (skge->autoneg == AUTONEG_ENABLE)
+		gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_IS_AN_MSK);
+	else
+		gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_IS_DEF_MSK);
+}
+
+static void yukon_reset(struct skge_hw *hw, int port)
+{
+	gm_phy_write(hw, port, PHY_MARV_INT_MASK, 0);/* disable PHY IRQs */
+	gma_write16(hw, port, GM_MC_ADDR_H1, 0);	/* clear MC hash */
+	gma_write16(hw, port, GM_MC_ADDR_H2, 0);
+	gma_write16(hw, port, GM_MC_ADDR_H3, 0);
+	gma_write16(hw, port, GM_MC_ADDR_H4, 0);
+
+	gma_write16(hw, port, GM_RX_CTRL,
+			 gma_read16(hw, port, GM_RX_CTRL)
+			 | GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA);
+}
+
+static void yukon_mac_init(struct skge_hw *hw, int port)
+{
+	struct skge_port *skge = netdev_priv(hw->dev[port]);
+	int i;
+	u32 reg;
+	const u8 *addr = hw->dev[port]->dev_addr;
+
+	/* WA code for COMA mode -- set PHY reset */
+	if (hw->chip_id == CHIP_ID_YUKON_LITE &&
+	    hw->chip_rev >= CHIP_REV_YU_LITE_A3)
+		skge_write32(hw, B2_GP_IO,
+			     (skge_read32(hw, B2_GP_IO) | GP_DIR_9 | GP_IO_9));
+
+	/* hard reset */
+	skge_write32(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET);
+	skge_write32(hw, SK_REG(port, GMAC_CTRL), GMC_RST_SET);
+
+	/* WA code for COMA mode -- clear PHY reset */
+	if (hw->chip_id == CHIP_ID_YUKON_LITE &&
+	    hw->chip_rev >= CHIP_REV_YU_LITE_A3)
+		skge_write32(hw, B2_GP_IO,
+			     (skge_read32(hw, B2_GP_IO) | GP_DIR_9)
+			     & ~GP_IO_9);
+
+	/* Set hardware config mode */
+	reg = GPC_INT_POL_HI | GPC_DIS_FC | GPC_DIS_SLEEP |
+		GPC_ENA_XC | GPC_ANEG_ADV_ALL_M | GPC_ENA_PAUSE;
+	reg |= iscopper(hw) ? GPC_HWCFG_GMII_COP : GPC_HWCFG_GMII_FIB;
+
+	/* Clear GMC reset */
+	skge_write32(hw, SK_REG(port, GPHY_CTRL), reg | GPC_RST_SET);
+	skge_write32(hw, SK_REG(port, GPHY_CTRL), reg | GPC_RST_CLR);
+	skge_write32(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_ON | GMC_RST_CLR);
+	if (skge->autoneg == AUTONEG_DISABLE) {
+		reg = GM_GPCR_AU_ALL_DIS;
+		gma_write16(hw, port, GM_GP_CTRL,
+				 gma_read16(hw, port, GM_GP_CTRL) | reg);
+
+		switch (skge->speed) {
+		case SPEED_1000:
+			reg |= GM_GPCR_SPEED_1000;
+			/* fallthru */
+		case SPEED_100:
+			reg |= GM_GPCR_SPEED_100;
+		}
+
+		if (skge->duplex == DUPLEX_FULL)
+			reg |= GM_GPCR_DUP_FULL;
+	} else
+		reg = GM_GPCR_SPEED_1000 | GM_GPCR_SPEED_100 | GM_GPCR_DUP_FULL;
+	switch (skge->flow_control) {
+	case FLOW_MODE_NONE:
+		skge_write32(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_OFF);
+		reg |= GM_GPCR_FC_TX_DIS | GM_GPCR_FC_RX_DIS | GM_GPCR_AU_FCT_DIS;
+		break;
+	case FLOW_MODE_LOC_SEND:
+		/* disable Rx flow-control */
+		reg |= GM_GPCR_FC_RX_DIS | GM_GPCR_AU_FCT_DIS;
+	}
+
+	gma_write16(hw, port, GM_GP_CTRL, reg);
+	skge_read16(hw, GMAC_IRQ_SRC);
+
+	yukon_init(hw, port);
+
+	/* MIB clear */
+	reg = gma_read16(hw, port, GM_PHY_ADDR);
+	gma_write16(hw, port, GM_PHY_ADDR, reg | GM_PAR_MIB_CLR);
+
+	for (i = 0; i < GM_MIB_CNT_SIZE; i++)
+		gma_read16(hw, port, GM_MIB_CNT_BASE + 8*i);
+	gma_write16(hw, port, GM_PHY_ADDR, reg);
+
+	/* transmit control */
+	gma_write16(hw, port, GM_TX_CTRL, TX_COL_THR(TX_COL_DEF));
+
+	/* receive control reg: unicast + multicast + no FCS  */
+	gma_write16(hw, port, GM_RX_CTRL,
+			 GM_RXCR_UCF_ENA | GM_RXCR_CRC_DIS | GM_RXCR_MCF_ENA);
+
+	/* transmit flow control */
+	gma_write16(hw, port, GM_TX_FLOW_CTRL, 0xffff);
+
+	/* transmit parameter */
+	gma_write16(hw, port, GM_TX_PARAM,
+			 TX_JAM_LEN_VAL(TX_JAM_LEN_DEF) |
+			 TX_JAM_IPG_VAL(TX_JAM_IPG_DEF) |
+			 TX_IPG_JAM_DATA(TX_IPG_JAM_DEF));
+
+	/* serial mode register */
+	reg = GM_SMOD_VLAN_ENA | IPG_DATA_VAL(IPG_DATA_DEF);
+	if (hw->dev[port]->mtu > 1500)
+		reg |= GM_SMOD_JUMBO_ENA;
+
+	gma_write16(hw, port, GM_SERIAL_MODE, reg);
+
+	/* physical address: used for pause frames */
+	gma_set_addr(hw, port, GM_SRC_ADDR_1L, addr);
+	/* virtual address for data */
+	gma_set_addr(hw, port, GM_SRC_ADDR_2L, addr);
+
+	/* enable interrupt mask for counter overflows */
+	gma_write16(hw, port, GM_TX_IRQ_MSK, 0);
+	gma_write16(hw, port, GM_RX_IRQ_MSK, 0);
+	gma_write16(hw, port, GM_TR_IRQ_MSK, 0);
+
+	/* Initialize Mac Fifo */
+
+	/* Configure Rx MAC FIFO */
+	skge_write16(hw, SK_REG(port, RX_GMF_FL_MSK), RX_FF_FL_DEF_MSK);
+	reg = GMF_OPER_ON | GMF_RX_F_FL_ON;
+	if (hw->chip_id == CHIP_ID_YUKON_LITE &&
+	    hw->chip_rev >= CHIP_REV_YU_LITE_A3)
+		reg &= ~GMF_RX_F_FL_ON;
+	skge_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_CLR);
+	skge_write16(hw, SK_REG(port, RX_GMF_CTRL_T), reg);
+	skge_write16(hw, SK_REG(port, RX_GMF_FL_THR), RX_GMF_FL_THR_DEF);
+
+	/* Configure Tx MAC FIFO */
+	skge_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_CLR);
+	skge_write16(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_OPER_ON);
+}
+
+static void yukon_stop(struct skge_port *skge)
+{
+	struct skge_hw *hw = skge->hw;
+	int port = skge->port;
+
+	if (hw->chip_id == CHIP_ID_YUKON_LITE &&
+	    hw->chip_rev >= CHIP_REV_YU_LITE_A3) {
+		skge_write32(hw, B2_GP_IO,
+			     skge_read32(hw, B2_GP_IO) | GP_DIR_9 | GP_IO_9);
+	}
+
+	gma_write16(hw, port, GM_GP_CTRL,
+			 gma_read16(hw, port, GM_GP_CTRL)
+			 & ~(GM_GPCR_TX_ENA|GM_GPCR_RX_ENA));
+	gma_read16(hw, port, GM_GP_CTRL);
+
+	/* set GPHY Control reset */
+	skge_write32(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET);
+	skge_write32(hw, SK_REG(port, GMAC_CTRL), GMC_RST_SET);
+}
+
+static void yukon_get_stats(struct skge_port *skge, u64 *data)
+{
+	struct skge_hw *hw = skge->hw;
+	int port = skge->port;
+	int i;
+
+	data[0] = (u64) gma_read32(hw, port, GM_TXO_OK_HI) << 32
+		| gma_read32(hw, port, GM_TXO_OK_LO);
+	data[1] = (u64) gma_read32(hw, port, GM_RXO_OK_HI) << 32
+		| gma_read32(hw, port, GM_RXO_OK_LO);
+
+	for (i = 2; i < ARRAY_SIZE(skge_stats); i++)
+		data[i] = gma_read32(hw, port,
+					  skge_stats[i].gma_offset);
+}
+
+static void yukon_mac_intr(struct skge_hw *hw, int port)
+{
+	struct net_device *dev = hw->dev[port];
+	struct skge_port *skge = netdev_priv(dev);
+	u8 status = skge_read8(hw, SK_REG(port, GMAC_IRQ_SRC));
+
+	if (netif_msg_intr(skge))
+		printk(KERN_DEBUG PFX "%s: mac interrupt status 0x%x\n",
+		       dev->name, status);
+
+	if (status & GM_IS_RX_FF_OR) {
+		++skge->net_stats.rx_fifo_errors;
+		skge_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_CLI_RX_FO);
+	}
+
+	if (status & GM_IS_TX_FF_UR) {
+		++skge->net_stats.tx_fifo_errors;
+		skge_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_CLI_TX_FU);
+	}
+
+}
+
+static u16 yukon_speed(const struct skge_hw *hw, u16 aux)
+{
+	switch (aux & PHY_M_PS_SPEED_MSK) {
+	case PHY_M_PS_SPEED_1000:
+		return SPEED_1000;
+	case PHY_M_PS_SPEED_100:
+		return SPEED_100;
+	default:
+		return SPEED_10;
+	}
+}
+
+static void yukon_link_up(struct skge_port *skge)
+{
+	struct skge_hw *hw = skge->hw;
+	int port = skge->port;
+	u16 reg;
+
+	pr_debug("yukon_link_up\n");
+
+	/* Enable Transmit FIFO Underrun */
+	skge_write8(hw, GMAC_IRQ_MSK, GMAC_DEF_MSK);
+
+	reg = gma_read16(hw, port, GM_GP_CTRL);
+	if (skge->duplex == DUPLEX_FULL || skge->autoneg == AUTONEG_ENABLE)
+		reg |= GM_GPCR_DUP_FULL;
+
+	/* enable Rx/Tx */
+	reg |= GM_GPCR_RX_ENA | GM_GPCR_TX_ENA;
+	gma_write16(hw, port, GM_GP_CTRL, reg);
+
+	gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_IS_DEF_MSK);
+	skge_link_up(skge);
+}
+
+static void yukon_link_down(struct skge_port *skge)
+{
+	struct skge_hw *hw = skge->hw;
+	int port = skge->port;
+	u16 ctrl;
+
+	pr_debug("yukon_link_down\n");
+	gm_phy_write(hw, port, PHY_MARV_INT_MASK, 0);
+
+	ctrl = gma_read16(hw, port, GM_GP_CTRL);
+	ctrl &= ~(GM_GPCR_RX_ENA | GM_GPCR_TX_ENA);
+	gma_write16(hw, port, GM_GP_CTRL, ctrl);
+
+	if (skge->flow_control == FLOW_MODE_REM_SEND) {
+		/* restore Asymmetric Pause bit */
+		gm_phy_write(hw, port, PHY_MARV_AUNE_ADV,
+				  gm_phy_read(hw, port,
+						   PHY_MARV_AUNE_ADV)
+				  | PHY_M_AN_ASP);
+
+	}
+
+	yukon_reset(hw, port);
+	skge_link_down(skge);
+
+	yukon_init(hw, port);
+}
+
+static void yukon_phy_intr(struct skge_port *skge)
+{
+	struct skge_hw *hw = skge->hw;
+	int port = skge->port;
+	const char *reason = NULL;
+	u16 istatus, phystat;
+
+	istatus = gm_phy_read(hw, port, PHY_MARV_INT_STAT);
+	phystat = gm_phy_read(hw, port, PHY_MARV_PHY_STAT);
+
+	if (netif_msg_intr(skge))
+		printk(KERN_DEBUG PFX "%s: phy interrupt status 0x%x 0x%x\n",
+		       skge->netdev->name, istatus, phystat);
+
+	if (istatus & PHY_M_IS_AN_COMPL) {
+		if (gm_phy_read(hw, port, PHY_MARV_AUNE_LP)
+		    & PHY_M_AN_RF) {
+			reason = "remote fault";
+			goto failed;
+		}
+
+		if (gm_phy_read(hw, port, PHY_MARV_1000T_STAT) & PHY_B_1000S_MSF) {
+			reason = "master/slave fault";
+			goto failed;
+		}
+
+		if (!(phystat & PHY_M_PS_SPDUP_RES)) {
+			reason = "speed/duplex";
+			goto failed;
+		}
+
+		skge->duplex = (phystat & PHY_M_PS_FULL_DUP)
+			? DUPLEX_FULL : DUPLEX_HALF;
+		skge->speed = yukon_speed(hw, phystat);
+
+		/* We are using IEEE 802.3z/D5.0 Table 37-4 */
+		switch (phystat & PHY_M_PS_PAUSE_MSK) {
+		case PHY_M_PS_PAUSE_MSK:
+			skge->flow_control = FLOW_MODE_SYMMETRIC;
+			break;
+		case PHY_M_PS_RX_P_EN:
+			skge->flow_control = FLOW_MODE_REM_SEND;
+			break;
+		case PHY_M_PS_TX_P_EN:
+			skge->flow_control = FLOW_MODE_LOC_SEND;
+			break;
+		default:
+			skge->flow_control = FLOW_MODE_NONE;
+		}
+
+		if (skge->flow_control == FLOW_MODE_NONE ||
+		    (skge->speed < SPEED_1000 && skge->duplex == DUPLEX_HALF))
+			skge_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_OFF);
+		else
+			skge_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_ON);
+		yukon_link_up(skge);
+		return;
+	}
+
+	if (istatus & PHY_M_IS_LSP_CHANGE)
+		skge->speed = yukon_speed(hw, phystat);
+
+	if (istatus & PHY_M_IS_DUP_CHANGE)
+		skge->duplex = (phystat & PHY_M_PS_FULL_DUP) ? DUPLEX_FULL : DUPLEX_HALF;
+	if (istatus & PHY_M_IS_LST_CHANGE) {
+		if (phystat & PHY_M_PS_LINK_UP)
+			yukon_link_up(skge);
+		else
+			yukon_link_down(skge);
+	}
+	return;
+ failed:
+	printk(KERN_ERR PFX "%s: autonegotiation failed (%s)\n",
+	       skge->netdev->name, reason);
+
+	/* XXX restart autonegotiation? */
+}
+
+static void skge_ramset(struct skge_hw *hw, u16 q, u32 start, size_t len)
+{
+	u32 end;
+
+	start /= 8;
+	len /= 8;
+	end = start + len - 1;
+
+	skge_write8(hw, RB_ADDR(q, RB_CTRL), RB_RST_CLR);
+	skge_write32(hw, RB_ADDR(q, RB_START), start);
+	skge_write32(hw, RB_ADDR(q, RB_WP), start);
+	skge_write32(hw, RB_ADDR(q, RB_RP), start);
+	skge_write32(hw, RB_ADDR(q, RB_END), end);
+
+	if (q == Q_R1 || q == Q_R2) {
+		/* Set thresholds on receive queue's */
+		skge_write32(hw, RB_ADDR(q, RB_RX_UTPP),
+			     start + (2*len)/3);
+		skge_write32(hw, RB_ADDR(q, RB_RX_LTPP),
+			     start + (len/3));
+	} else {
+		/* Enable store & forward on Tx queue's because
+		 * Tx FIFO is only 4K on Genesis and 1K on Yukon
+		 */
+		skge_write8(hw, RB_ADDR(q, RB_CTRL), RB_ENA_STFWD);
+	}
+
+	skge_write8(hw, RB_ADDR(q, RB_CTRL), RB_ENA_OP_MD);
+}
+
+/* Setup Bus Memory Interface */
+static void skge_qset(struct skge_port *skge, u16 q,
+		      const struct skge_element *e)
+{
+	struct skge_hw *hw = skge->hw;
+	u32 watermark = 0x600;
+	u64 base = skge->dma + (e->desc - skge->mem);
+
+	/* optimization to reduce window on 32bit/33mhz */
+	if ((skge_read16(hw, B0_CTST) & (CS_BUS_CLOCK | CS_BUS_SLOT_SZ)) == 0)
+		watermark /= 2;
+
+	skge_write32(hw, Q_ADDR(q, Q_CSR), CSR_CLR_RESET);
+	skge_write32(hw, Q_ADDR(q, Q_F), watermark);
+	skge_write32(hw, Q_ADDR(q, Q_DA_H), (u32)(base >> 32));
+	skge_write32(hw, Q_ADDR(q, Q_DA_L), (u32)base);
+}
+
+static int skge_up(struct net_device *dev)
+{
+	struct skge_port *skge = netdev_priv(dev);
+	struct skge_hw *hw = skge->hw;
+	int port = skge->port;
+	u32 chunk, ram_addr;
+	size_t rx_size, tx_size;
+	int err;
+
+	if (netif_msg_ifup(skge))
+		printk(KERN_INFO PFX "%s: enabling interface\n", dev->name);
+
+	if (dev->mtu > RX_BUF_SIZE)
+		skge->rx_buf_size = dev->mtu + ETH_HLEN + NET_IP_ALIGN;
+	else
+		skge->rx_buf_size = RX_BUF_SIZE;
+
+
+	rx_size = skge->rx_ring.count * sizeof(struct skge_rx_desc);
+	tx_size = skge->tx_ring.count * sizeof(struct skge_tx_desc);
+	skge->mem_size = tx_size + rx_size;
+	skge->mem = pci_alloc_consistent(hw->pdev, skge->mem_size, &skge->dma);
+	if (!skge->mem)
+		return -ENOMEM;
+
+	memset(skge->mem, 0, skge->mem_size);
+
+	if ((err = skge_ring_alloc(&skge->rx_ring, skge->mem, skge->dma)))
+		goto free_pci_mem;
+
+	err = skge_rx_fill(skge);
+	if (err)
+		goto free_rx_ring;
+
+	if ((err = skge_ring_alloc(&skge->tx_ring, skge->mem + rx_size,
+				   skge->dma + rx_size)))
+		goto free_rx_ring;
+
+	skge->tx_avail = skge->tx_ring.count - 1;
+
+	/* Enable IRQ from port */
+	hw->intr_mask |= portirqmask[port];
+	skge_write32(hw, B0_IMSK, hw->intr_mask);
+
+	/* Initialze MAC */
+	spin_lock_bh(&hw->phy_lock);
+	if (hw->chip_id == CHIP_ID_GENESIS)
+		genesis_mac_init(hw, port);
+	else
+		yukon_mac_init(hw, port);
+	spin_unlock_bh(&hw->phy_lock);
+
+	/* Configure RAMbuffers */
+	chunk = hw->ram_size / ((hw->ports + 1)*2);
+	ram_addr = hw->ram_offset + 2 * chunk * port;
+
+	skge_ramset(hw, rxqaddr[port], ram_addr, chunk);
+	skge_qset(skge, rxqaddr[port], skge->rx_ring.to_clean);
+
+	BUG_ON(skge->tx_ring.to_use != skge->tx_ring.to_clean);
+	skge_ramset(hw, txqaddr[port], ram_addr+chunk, chunk);
+	skge_qset(skge, txqaddr[port], skge->tx_ring.to_use);
+
+	/* Start receiver BMU */
+	wmb();
+	skge_write8(hw, Q_ADDR(rxqaddr[port], Q_CSR), CSR_START | CSR_IRQ_CL_F);
+	skge_led(skge, LED_MODE_ON);
+
+	pr_debug("skge_up completed\n");
+	return 0;
+
+ free_rx_ring:
+	skge_rx_clean(skge);
+	kfree(skge->rx_ring.start);
+ free_pci_mem:
+	pci_free_consistent(hw->pdev, skge->mem_size, skge->mem, skge->dma);
+
+	return err;
+}
+
+static int skge_down(struct net_device *dev)
+{
+	struct skge_port *skge = netdev_priv(dev);
+	struct skge_hw *hw = skge->hw;
+	int port = skge->port;
+
+	if (netif_msg_ifdown(skge))
+		printk(KERN_INFO PFX "%s: disabling interface\n", dev->name);
+
+	netif_stop_queue(dev);
+
+	/* Stop transmitter */
+	skge_write8(hw, Q_ADDR(txqaddr[port], Q_CSR), CSR_STOP);
+	skge_write32(hw, RB_ADDR(txqaddr[port], RB_CTRL),
+		     RB_RST_SET|RB_DIS_OP_MD);
+
+	if (hw->chip_id == CHIP_ID_GENESIS)
+		genesis_stop(skge);
+	else
+		yukon_stop(skge);
+
+	/* Disable Force Sync bit and Enable Alloc bit */
+	skge_write8(hw, SK_REG(port, TXA_CTRL),
+		    TXA_DIS_FSYNC | TXA_DIS_ALLOC | TXA_STOP_RC);
+
+	/* Stop Interval Timer and Limit Counter of Tx Arbiter */
+	skge_write32(hw, SK_REG(port, TXA_ITI_INI), 0L);
+	skge_write32(hw, SK_REG(port, TXA_LIM_INI), 0L);
+
+	/* Reset PCI FIFO */
+	skge_write32(hw, Q_ADDR(txqaddr[port], Q_CSR), CSR_SET_RESET);
+	skge_write32(hw, RB_ADDR(txqaddr[port], RB_CTRL), RB_RST_SET);
+
+	/* Reset the RAM Buffer async Tx queue */
+	skge_write8(hw, RB_ADDR(port == 0 ? Q_XA1 : Q_XA2, RB_CTRL), RB_RST_SET);
+	/* stop receiver */
+	skge_write8(hw, Q_ADDR(rxqaddr[port], Q_CSR), CSR_STOP);
+	skge_write32(hw, RB_ADDR(port ? Q_R2 : Q_R1, RB_CTRL),
+		     RB_RST_SET|RB_DIS_OP_MD);
+	skge_write32(hw, Q_ADDR(rxqaddr[port], Q_CSR), CSR_SET_RESET);
+
+	if (hw->chip_id == CHIP_ID_GENESIS) {
+		skge_write8(hw, SK_REG(port, TX_MFF_CTRL2), MFF_RST_SET);
+		skge_write8(hw, SK_REG(port, RX_MFF_CTRL2), MFF_RST_SET);
+	} else {
+		skge_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET);
+		skge_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_SET);
+	}
+
+	skge_led(skge, LED_MODE_OFF);
+
+	skge_tx_clean(skge);
+	skge_rx_clean(skge);
+
+	kfree(skge->rx_ring.start);
+	kfree(skge->tx_ring.start);
+	pci_free_consistent(hw->pdev, skge->mem_size, skge->mem, skge->dma);
+	return 0;
+}
+
+static int skge_xmit_frame(struct sk_buff *skb, struct net_device *dev)
+{
+	struct skge_port *skge = netdev_priv(dev);
+	struct skge_hw *hw = skge->hw;
+	struct skge_ring *ring = &skge->tx_ring;
+	struct skge_element *e;
+	struct skge_tx_desc *td;
+	int i;
+	u32 control, len;
+	u64 map;
+	unsigned long flags;
+
+	skb = skb_padto(skb, ETH_ZLEN);
+	if (!skb)
+		return NETDEV_TX_OK;
+
+	local_irq_save(flags);
+	if (!spin_trylock(&skge->tx_lock)) {
+ 		/* Collision - tell upper layer to requeue */
+ 		local_irq_restore(flags);
+ 		return NETDEV_TX_LOCKED;
+ 	}
+
+	if (unlikely(skge->tx_avail < skb_shinfo(skb)->nr_frags +1)) {
+		netif_stop_queue(dev);
+		spin_unlock_irqrestore(&skge->tx_lock, flags);
+
+		printk(KERN_WARNING PFX "%s: ring full when queue awake!\n",
+		       dev->name);
+		return NETDEV_TX_BUSY;
+	}
+
+	e = ring->to_use;
+	td = e->desc;
+	e->skb = skb;
+	len = skb_headlen(skb);
+	map = pci_map_single(hw->pdev, skb->data, len, PCI_DMA_TODEVICE);
+	pci_unmap_addr_set(e, mapaddr, map);
+	pci_unmap_len_set(e, maplen, len);
+
+	td->dma_lo = map;
+	td->dma_hi = map >> 32;
+
+	if (skb->ip_summed == CHECKSUM_HW) {
+		const struct iphdr *ip
+			= (const struct iphdr *) (skb->data + ETH_HLEN);
+		int offset = skb->h.raw - skb->data;
+
+		/* This seems backwards, but it is what the sk98lin
+		 * does.  Looks like hardware is wrong?
+		 */
+		if (ip->protocol == IPPROTO_UDP
+	            && hw->chip_rev == 0 && hw->chip_id == CHIP_ID_YUKON)
+			control = BMU_TCP_CHECK;
+		else
+			control = BMU_UDP_CHECK;
+
+		td->csum_offs = 0;
+		td->csum_start = offset;
+		td->csum_write = offset + skb->csum;
+	} else
+		control = BMU_CHECK;
+
+	if (!skb_shinfo(skb)->nr_frags) /* single buffer i.e. no fragments */
+		control |= BMU_EOF| BMU_IRQ_EOF;
+	else {
+		struct skge_tx_desc *tf = td;
+
+		control |= BMU_STFWD;
+		for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
+			skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+
+			map = pci_map_page(hw->pdev, frag->page, frag->page_offset,
+					   frag->size, PCI_DMA_TODEVICE);
+
+			e = e->next;
+			e->skb = NULL;
+			tf = e->desc;
+			tf->dma_lo = map;
+			tf->dma_hi = (u64) map >> 32;
+			pci_unmap_addr_set(e, mapaddr, map);
+			pci_unmap_len_set(e, maplen, frag->size);
+
+			tf->control = BMU_OWN | BMU_SW | control | frag->size;
+		}
+		tf->control |= BMU_EOF | BMU_IRQ_EOF;
+	}
+	/* Make sure all the descriptors written */
+	wmb();
+	td->control = BMU_OWN | BMU_SW | BMU_STF | control | len;
+	wmb();
+
+	skge_write8(hw, Q_ADDR(txqaddr[skge->port], Q_CSR), CSR_START);
+
+	if (netif_msg_tx_queued(skge))
+		printk(KERN_DEBUG "%s: tx queued, slot %td, len %d\n",
+		       dev->name, e - ring->start, skb->len);
+
+	ring->to_use = e->next;
+	skge->tx_avail -= skb_shinfo(skb)->nr_frags + 1;
+	if (skge->tx_avail <= MAX_SKB_FRAGS + 1) {
+		pr_debug("%s: transmit queue full\n", dev->name);
+		netif_stop_queue(dev);
+	}
+
+	dev->trans_start = jiffies;
+	spin_unlock_irqrestore(&skge->tx_lock, flags);
+
+	return NETDEV_TX_OK;
+}
+
+static inline void skge_tx_free(struct skge_hw *hw, struct skge_element *e)
+{
+	/* This ring element can be skb or fragment */
+	if (e->skb) {
+		pci_unmap_single(hw->pdev,
+			       pci_unmap_addr(e, mapaddr),
+			       pci_unmap_len(e, maplen),
+			       PCI_DMA_TODEVICE);
+		dev_kfree_skb_any(e->skb);
+		e->skb = NULL;
+	} else {
+		pci_unmap_page(hw->pdev,
+			       pci_unmap_addr(e, mapaddr),
+			       pci_unmap_len(e, maplen),
+			       PCI_DMA_TODEVICE);
+	}
+}
+
+static void skge_tx_clean(struct skge_port *skge)
+{
+	struct skge_ring *ring = &skge->tx_ring;
+	struct skge_element *e;
+	unsigned long flags;
+
+	spin_lock_irqsave(&skge->tx_lock, flags);
+	for (e = ring->to_clean; e != ring->to_use; e = e->next) {
+		++skge->tx_avail;
+		skge_tx_free(skge->hw, e);
+	}
+	ring->to_clean = e;
+	spin_unlock_irqrestore(&skge->tx_lock, flags);
+}
+
+static void skge_tx_timeout(struct net_device *dev)
+{
+	struct skge_port *skge = netdev_priv(dev);
+
+	if (netif_msg_timer(skge))
+		printk(KERN_DEBUG PFX "%s: tx timeout\n", dev->name);
+
+	skge_write8(skge->hw, Q_ADDR(txqaddr[skge->port], Q_CSR), CSR_STOP);
+	skge_tx_clean(skge);
+}
+
+static int skge_change_mtu(struct net_device *dev, int new_mtu)
+{
+	int err = 0;
+	int running = netif_running(dev);
+
+	if (new_mtu < ETH_ZLEN || new_mtu > ETH_JUMBO_MTU)
+		return -EINVAL;
+
+
+	if (running)
+		skge_down(dev);
+	dev->mtu = new_mtu;
+	if (running)
+		skge_up(dev);
+
+	return err;
+}
+
+static void genesis_set_multicast(struct net_device *dev)
+{
+	struct skge_port *skge = netdev_priv(dev);
+	struct skge_hw *hw = skge->hw;
+	int port = skge->port;
+	int i, count = dev->mc_count;
+	struct dev_mc_list *list = dev->mc_list;
+	u32 mode;
+	u8 filter[8];
+
+	pr_debug("genesis_set_multicast flags=%x count=%d\n", dev->flags, dev->mc_count);
+
+	mode = xm_read32(hw, port, XM_MODE);
+	mode |= XM_MD_ENA_HASH;
+	if (dev->flags & IFF_PROMISC)
+		mode |= XM_MD_ENA_PROM;
+	else
+		mode &= ~XM_MD_ENA_PROM;
+
+	if (dev->flags & IFF_ALLMULTI)
+		memset(filter, 0xff, sizeof(filter));
+	else {
+		memset(filter, 0, sizeof(filter));
+		for (i = 0; list && i < count; i++, list = list->next) {
+			u32 crc, bit;
+			crc = ether_crc_le(ETH_ALEN, list->dmi_addr);
+			bit = ~crc & 0x3f;
+			filter[bit/8] |= 1 << (bit%8);
+		}
+	}
+
+	xm_write32(hw, port, XM_MODE, mode);
+	xm_outhash(hw, port, XM_HSM, filter);
+}
+
+static void yukon_set_multicast(struct net_device *dev)
+{
+	struct skge_port *skge = netdev_priv(dev);
+	struct skge_hw *hw = skge->hw;
+	int port = skge->port;
+	struct dev_mc_list *list = dev->mc_list;
+	u16 reg;
+	u8 filter[8];
+
+	memset(filter, 0, sizeof(filter));
+
+	reg = gma_read16(hw, port, GM_RX_CTRL);
+	reg |= GM_RXCR_UCF_ENA;
+
+	if (dev->flags & IFF_PROMISC) 		/* promiscious */
+		reg &= ~(GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA);
+	else if (dev->flags & IFF_ALLMULTI)	/* all multicast */
+		memset(filter, 0xff, sizeof(filter));
+	else if (dev->mc_count == 0)		/* no multicast */
+		reg &= ~GM_RXCR_MCF_ENA;
+	else {
+		int i;
+		reg |= GM_RXCR_MCF_ENA;
+
+		for (i = 0; list && i < dev->mc_count; i++, list = list->next) {
+			u32 bit = ether_crc(ETH_ALEN, list->dmi_addr) & 0x3f;
+			filter[bit/8] |= 1 << (bit%8);
+		}
+	}
+
+
+	gma_write16(hw, port, GM_MC_ADDR_H1,
+			 (u16)filter[0] | ((u16)filter[1] << 8));
+	gma_write16(hw, port, GM_MC_ADDR_H2,
+			 (u16)filter[2] | ((u16)filter[3] << 8));
+	gma_write16(hw, port, GM_MC_ADDR_H3,
+			 (u16)filter[4] | ((u16)filter[5] << 8));
+	gma_write16(hw, port, GM_MC_ADDR_H4,
+			 (u16)filter[6] | ((u16)filter[7] << 8));
+
+	gma_write16(hw, port, GM_RX_CTRL, reg);
+}
+
+static inline int bad_phy_status(const struct skge_hw *hw, u32 status)
+{
+	if (hw->chip_id == CHIP_ID_GENESIS)
+		return (status & (XMR_FS_ERR | XMR_FS_2L_VLAN)) != 0;
+	else
+		return (status & GMR_FS_ANY_ERR) ||
+			(status & GMR_FS_RX_OK) == 0;
+}
+
+static void skge_rx_error(struct skge_port *skge, int slot,
+			  u32 control, u32 status)
+{
+	if (netif_msg_rx_err(skge))
+		printk(KERN_DEBUG PFX "%s: rx err, slot %d control 0x%x status 0x%x\n",
+		       skge->netdev->name, slot, control, status);
+
+	if ((control & (BMU_EOF|BMU_STF)) != (BMU_STF|BMU_EOF))
+		skge->net_stats.rx_length_errors++;
+	else if (skge->hw->chip_id == CHIP_ID_GENESIS) {
+		if (status & (XMR_FS_RUNT|XMR_FS_LNG_ERR))
+			skge->net_stats.rx_length_errors++;
+		if (status & XMR_FS_FRA_ERR)
+			skge->net_stats.rx_frame_errors++;
+		if (status & XMR_FS_FCS_ERR)
+			skge->net_stats.rx_crc_errors++;
+	} else {
+		if (status & (GMR_FS_LONG_ERR|GMR_FS_UN_SIZE))
+			skge->net_stats.rx_length_errors++;
+		if (status & GMR_FS_FRAGMENT)
+			skge->net_stats.rx_frame_errors++;
+		if (status & GMR_FS_CRC_ERR)
+			skge->net_stats.rx_crc_errors++;
+	}
+}
+
+/* Get receive buffer from descriptor.
+ * Handles copy of small buffers and reallocation failures
+ */
+static inline struct sk_buff *skge_rx_get(struct skge_port *skge,
+					  struct skge_element *e,
+					  unsigned int len)
+{
+	struct sk_buff *nskb, *skb;
+
+	if (len < RX_COPY_THRESHOLD) {
+		nskb = skge_rx_alloc(skge->netdev, len + NET_IP_ALIGN);
+		if (unlikely(!nskb))
+			return NULL;
+
+		pci_dma_sync_single_for_cpu(skge->hw->pdev,
+					    pci_unmap_addr(e, mapaddr),
+					    len, PCI_DMA_FROMDEVICE);
+		memcpy(nskb->data, e->skb->data, len);
+		pci_dma_sync_single_for_device(skge->hw->pdev,
+					       pci_unmap_addr(e, mapaddr),
+					       len, PCI_DMA_FROMDEVICE);
+
+		if (skge->rx_csum) {
+			struct skge_rx_desc *rd = e->desc;
+			nskb->csum = le16_to_cpu(rd->csum2);
+			nskb->ip_summed = CHECKSUM_HW;
+		}
+		skge_rx_reuse(e, skge->rx_buf_size);
+		return nskb;
+	} else {
+		nskb = skge_rx_alloc(skge->netdev, skge->rx_buf_size);
+		if (unlikely(!nskb))
+			return NULL;
+
+		pci_unmap_single(skge->hw->pdev,
+				 pci_unmap_addr(e, mapaddr),
+				 pci_unmap_len(e, maplen),
+				 PCI_DMA_FROMDEVICE);
+		skb = e->skb;
+		if (skge->rx_csum) {
+			struct skge_rx_desc *rd = e->desc;
+			skb->csum = le16_to_cpu(rd->csum2);
+			skb->ip_summed = CHECKSUM_HW;
+		}
+
+		skge_rx_setup(skge, e, nskb, skge->rx_buf_size);
+		return skb;
+	}
+}
+
+
+static int skge_poll(struct net_device *dev, int *budget)
+{
+	struct skge_port *skge = netdev_priv(dev);
+	struct skge_hw *hw = skge->hw;
+	struct skge_ring *ring = &skge->rx_ring;
+	struct skge_element *e;
+	unsigned int to_do = min(dev->quota, *budget);
+	unsigned int work_done = 0;
+
+	pr_debug("skge_poll\n");
+
+	for (e = ring->to_clean; work_done < to_do; e = e->next) {
+		struct skge_rx_desc *rd = e->desc;
+		struct sk_buff *skb;
+		u32 control, len, status;
+
+		rmb();
+		control = rd->control;
+		if (control & BMU_OWN)
+			break;
+
+		len = control & BMU_BBC;
+		status = rd->status;
+
+		if (unlikely((control & (BMU_EOF|BMU_STF)) != (BMU_STF|BMU_EOF)
+			     || bad_phy_status(hw, status))) {
+			skge_rx_error(skge, e - ring->start, control, status);
+			skge_rx_reuse(e, skge->rx_buf_size);
+			continue;
+		}
+
+		if (netif_msg_rx_status(skge))
+		    printk(KERN_DEBUG PFX "%s: rx slot %td status 0x%x len %d\n",
+			   dev->name, e - ring->start, rd->status, len);
+
+		skb = skge_rx_get(skge, e, len);
+		if (likely(skb)) {
+			skb_put(skb, len);
+			skb->protocol = eth_type_trans(skb, dev);
+
+			dev->last_rx = jiffies;
+			netif_receive_skb(skb);
+
+			++work_done;
+		} else
+			skge_rx_reuse(e, skge->rx_buf_size);
+	}
+	ring->to_clean = e;
+
+	/* restart receiver */
+	wmb();
+	skge_write8(hw, Q_ADDR(rxqaddr[skge->port], Q_CSR),
+		    CSR_START | CSR_IRQ_CL_F);
+
+	*budget -= work_done;
+	dev->quota -= work_done;
+
+	if (work_done >=  to_do)
+		return 1; /* not done */
+
+	local_irq_disable();
+	__netif_rx_complete(dev);
+	hw->intr_mask |= portirqmask[skge->port];
+	skge_write32(hw, B0_IMSK, hw->intr_mask);
+	local_irq_enable();
+	return 0;
+}
+
+static inline void skge_tx_intr(struct net_device *dev)
+{
+	struct skge_port *skge = netdev_priv(dev);
+	struct skge_hw *hw = skge->hw;
+	struct skge_ring *ring = &skge->tx_ring;
+	struct skge_element *e;
+
+	spin_lock(&skge->tx_lock);
+	for (e = ring->to_clean; e != ring->to_use; e = e->next) {
+		struct skge_tx_desc *td = e->desc;
+		u32 control;
+
+		rmb();
+		control = td->control;
+		if (control & BMU_OWN)
+			break;
+
+		if (unlikely(netif_msg_tx_done(skge)))
+			printk(KERN_DEBUG PFX "%s: tx done slot %td status 0x%x\n",
+			       dev->name, e - ring->start, td->status);
+
+		skge_tx_free(hw, e);
+		e->skb = NULL;
+		++skge->tx_avail;
+	}
+	ring->to_clean = e;
+	skge_write8(hw, Q_ADDR(txqaddr[skge->port], Q_CSR), CSR_IRQ_CL_F);
+
+	if (skge->tx_avail > MAX_SKB_FRAGS + 1)
+		netif_wake_queue(dev);
+
+	spin_unlock(&skge->tx_lock);
+}
+
+/* Parity errors seem to happen when Genesis is connected to a switch
+ * with no other ports present. Heartbeat error??
+ */
+static void skge_mac_parity(struct skge_hw *hw, int port)
+{
+	struct net_device *dev = hw->dev[port];
+
+	if (dev) {
+		struct skge_port *skge = netdev_priv(dev);
+		++skge->net_stats.tx_heartbeat_errors;
+	}
+
+	if (hw->chip_id == CHIP_ID_GENESIS)
+		skge_write16(hw, SK_REG(port, TX_MFF_CTRL1),
+			     MFF_CLR_PERR);
+	else
+		/* HW-Bug #8: cleared by GMF_CLI_TX_FC instead of GMF_CLI_TX_PE */
+		skge_write8(hw, SK_REG(port, TX_GMF_CTRL_T),
+			    (hw->chip_id == CHIP_ID_YUKON && hw->chip_rev == 0)
+			    ? GMF_CLI_TX_FC : GMF_CLI_TX_PE);
+}
+
+static void skge_pci_clear(struct skge_hw *hw)
+{
+	u16 status;
+
+	pci_read_config_word(hw->pdev, PCI_STATUS, &status);
+	skge_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
+	pci_write_config_word(hw->pdev, PCI_STATUS,
+			      status | PCI_STATUS_ERROR_BITS);
+	skge_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
+}
+
+static void skge_mac_intr(struct skge_hw *hw, int port)
+{
+	if (hw->chip_id == CHIP_ID_GENESIS)
+		genesis_mac_intr(hw, port);
+	else
+		yukon_mac_intr(hw, port);
+}
+
+/* Handle device specific framing and timeout interrupts */
+static void skge_error_irq(struct skge_hw *hw)
+{
+	u32 hwstatus = skge_read32(hw, B0_HWE_ISRC);
+
+	if (hw->chip_id == CHIP_ID_GENESIS) {
+		/* clear xmac errors */
+		if (hwstatus & (IS_NO_STAT_M1|IS_NO_TIST_M1))
+			skge_write16(hw, SK_REG(0, RX_MFF_CTRL1), MFF_CLR_INSTAT);
+		if (hwstatus & (IS_NO_STAT_M2|IS_NO_TIST_M2))
+			skge_write16(hw, SK_REG(0, RX_MFF_CTRL2), MFF_CLR_INSTAT);
+	} else {
+		/* Timestamp (unused) overflow */
+		if (hwstatus & IS_IRQ_TIST_OV)
+			skge_write8(hw, GMAC_TI_ST_CTRL, GMT_ST_CLR_IRQ);
+
+		if (hwstatus & IS_IRQ_SENSOR) {
+			/* no sensors on 32-bit Yukon */
+			if (!(skge_read16(hw, B0_CTST) & CS_BUS_SLOT_SZ)) {
+				printk(KERN_ERR PFX "ignoring bogus sensor interrups\n");
+				skge_write32(hw, B0_HWE_IMSK,
+					     IS_ERR_MSK & ~IS_IRQ_SENSOR);
+			} else
+				printk(KERN_WARNING PFX "sensor interrupt\n");
+		}
+
+
+	}
+
+	if (hwstatus & IS_RAM_RD_PAR) {
+		printk(KERN_ERR PFX "Ram read data parity error\n");
+		skge_write16(hw, B3_RI_CTRL, RI_CLR_RD_PERR);
+	}
+
+	if (hwstatus & IS_RAM_WR_PAR) {
+		printk(KERN_ERR PFX "Ram write data parity error\n");
+		skge_write16(hw, B3_RI_CTRL, RI_CLR_WR_PERR);
+	}
+
+	if (hwstatus & IS_M1_PAR_ERR)
+		skge_mac_parity(hw, 0);
+
+	if (hwstatus & IS_M2_PAR_ERR)
+		skge_mac_parity(hw, 1);
+
+	if (hwstatus & IS_R1_PAR_ERR)
+		skge_write32(hw, B0_R1_CSR, CSR_IRQ_CL_P);
+
+	if (hwstatus & IS_R2_PAR_ERR)
+		skge_write32(hw, B0_R2_CSR, CSR_IRQ_CL_P);
+
+	if (hwstatus & (IS_IRQ_MST_ERR|IS_IRQ_STAT)) {
+		printk(KERN_ERR PFX "hardware error detected (status 0x%x)\n",
+		       hwstatus);
+
+		skge_pci_clear(hw);
+
+		hwstatus = skge_read32(hw, B0_HWE_ISRC);
+		if (hwstatus & IS_IRQ_STAT) {
+			printk(KERN_WARNING PFX "IRQ status %x: still set ignoring hardware errors\n",
+			       hwstatus);
+			hw->intr_mask &= ~IS_HW_ERR;
+		}
+	}
+}
+
+/*
+ * Interrrupt from PHY are handled in tasklet (soft irq)
+ * because accessing phy registers requires spin wait which might
+ * cause excess interrupt latency.
+ */
+static void skge_extirq(unsigned long data)
+{
+	struct skge_hw *hw = (struct skge_hw *) data;
+	int port;
+
+	spin_lock(&hw->phy_lock);
+	for (port = 0; port < 2; port++) {
+		struct net_device *dev = hw->dev[port];
+
+		if (dev && netif_running(dev)) {
+			struct skge_port *skge = netdev_priv(dev);
+
+			if (hw->chip_id != CHIP_ID_GENESIS)
+				yukon_phy_intr(skge);
+			else
+				bcom_phy_intr(skge);
+		}
+	}
+	spin_unlock(&hw->phy_lock);
+
+	local_irq_disable();
+	hw->intr_mask |= IS_EXT_REG;
+	skge_write32(hw, B0_IMSK, hw->intr_mask);
+	local_irq_enable();
+}
+
+static irqreturn_t skge_intr(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct skge_hw *hw = dev_id;
+	u32 status = skge_read32(hw, B0_SP_ISRC);
+
+	if (status == 0 || status == ~0) /* hotplug or shared irq */
+		return IRQ_NONE;
+
+	status &= hw->intr_mask;
+	if (status & IS_R1_F) {
+		hw->intr_mask &= ~IS_R1_F;
+		netif_rx_schedule(hw->dev[0]);
+	}
+
+	if (status & IS_R2_F) {
+		hw->intr_mask &= ~IS_R2_F;
+		netif_rx_schedule(hw->dev[1]);
+	}
+
+	if (status & IS_XA1_F)
+		skge_tx_intr(hw->dev[0]);
+
+	if (status & IS_XA2_F)
+		skge_tx_intr(hw->dev[1]);
+
+	if (status & IS_PA_TO_RX1) {
+		struct skge_port *skge = netdev_priv(hw->dev[0]);
+		++skge->net_stats.rx_over_errors;
+		skge_write16(hw, B3_PA_CTRL, PA_CLR_TO_RX1);
+	}
+
+	if (status & IS_PA_TO_RX2) {
+		struct skge_port *skge = netdev_priv(hw->dev[1]);
+		++skge->net_stats.rx_over_errors;
+		skge_write16(hw, B3_PA_CTRL, PA_CLR_TO_RX2);
+	}
+
+	if (status & IS_PA_TO_TX1)
+		skge_write16(hw, B3_PA_CTRL, PA_CLR_TO_TX1);
+
+	if (status & IS_PA_TO_TX2)
+		skge_write16(hw, B3_PA_CTRL, PA_CLR_TO_TX2);
+
+	if (status & IS_MAC1)
+		skge_mac_intr(hw, 0);
+
+	if (status & IS_MAC2)
+		skge_mac_intr(hw, 1);
+
+	if (status & IS_HW_ERR)
+		skge_error_irq(hw);
+
+	if (status & IS_EXT_REG) {
+		hw->intr_mask &= ~IS_EXT_REG;
+		tasklet_schedule(&hw->ext_tasklet);
+	}
+
+	skge_write32(hw, B0_IMSK, hw->intr_mask);
+
+	return IRQ_HANDLED;
+}
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void skge_netpoll(struct net_device *dev)
+{
+	struct skge_port *skge = netdev_priv(dev);
+
+	disable_irq(dev->irq);
+	skge_intr(dev->irq, skge->hw, NULL);
+	enable_irq(dev->irq);
+}
+#endif
+
+static int skge_set_mac_address(struct net_device *dev, void *p)
+{
+	struct skge_port *skge = netdev_priv(dev);
+	struct sockaddr *addr = p;
+	int err = 0;
+
+	if (!is_valid_ether_addr(addr->sa_data))
+		return -EADDRNOTAVAIL;
+
+	skge_down(dev);
+	memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
+	memcpy_toio(skge->hw->regs + B2_MAC_1 + skge->port*8,
+		    dev->dev_addr, ETH_ALEN);
+	memcpy_toio(skge->hw->regs + B2_MAC_2 + skge->port*8,
+		    dev->dev_addr, ETH_ALEN);
+	if (dev->flags & IFF_UP)
+		err = skge_up(dev);
+	return err;
+}
+
+static const struct {
+	u8 id;
+	const char *name;
+} skge_chips[] = {
+	{ CHIP_ID_GENESIS,	"Genesis" },
+	{ CHIP_ID_YUKON,	 "Yukon" },
+	{ CHIP_ID_YUKON_LITE,	 "Yukon-Lite"},
+	{ CHIP_ID_YUKON_LP,	 "Yukon-LP"},
+};
+
+static const char *skge_board_name(const struct skge_hw *hw)
+{
+	int i;
+	static char buf[16];
+
+	for (i = 0; i < ARRAY_SIZE(skge_chips); i++)
+		if (skge_chips[i].id == hw->chip_id)
+			return skge_chips[i].name;
+
+	snprintf(buf, sizeof buf, "chipid 0x%x", hw->chip_id);
+	return buf;
+}
+
+
+/*
+ * Setup the board data structure, but don't bring up
+ * the port(s)
+ */
+static int skge_reset(struct skge_hw *hw)
+{
+	u16 ctst;
+	u8 t8, mac_cfg;
+	int i;
+
+	ctst = skge_read16(hw, B0_CTST);
+
+	/* do a SW reset */
+	skge_write8(hw, B0_CTST, CS_RST_SET);
+	skge_write8(hw, B0_CTST, CS_RST_CLR);
+
+	/* clear PCI errors, if any */
+	skge_pci_clear(hw);
+
+	skge_write8(hw, B0_CTST, CS_MRST_CLR);
+
+	/* restore CLK_RUN bits (for Yukon-Lite) */
+	skge_write16(hw, B0_CTST,
+		     ctst & (CS_CLK_RUN_HOT|CS_CLK_RUN_RST|CS_CLK_RUN_ENA));
+
+	hw->chip_id = skge_read8(hw, B2_CHIP_ID);
+	hw->phy_type = skge_read8(hw, B2_E_1) & 0xf;
+	hw->pmd_type = skge_read8(hw, B2_PMD_TYP);
+
+	switch (hw->chip_id) {
+	case CHIP_ID_GENESIS:
+		switch (hw->phy_type) {
+		case SK_PHY_BCOM:
+			hw->phy_addr = PHY_ADDR_BCOM;
+			break;
+		default:
+			printk(KERN_ERR PFX "%s: unsupported phy type 0x%x\n",
+			       pci_name(hw->pdev), hw->phy_type);
+			return -EOPNOTSUPP;
+		}
+		break;
+
+	case CHIP_ID_YUKON:
+	case CHIP_ID_YUKON_LITE:
+	case CHIP_ID_YUKON_LP:
+		if (hw->phy_type < SK_PHY_MARV_COPPER && hw->pmd_type != 'S')
+			hw->phy_type = SK_PHY_MARV_COPPER;
+
+		hw->phy_addr = PHY_ADDR_MARV;
+		if (!iscopper(hw))
+			hw->phy_type = SK_PHY_MARV_FIBER;
+
+		break;
+
+	default:
+		printk(KERN_ERR PFX "%s: unsupported chip type 0x%x\n",
+		       pci_name(hw->pdev), hw->chip_id);
+		return -EOPNOTSUPP;
+	}
+
+	mac_cfg = skge_read8(hw, B2_MAC_CFG);
+	hw->ports = (mac_cfg & CFG_SNG_MAC) ? 1 : 2;
+	hw->chip_rev = (mac_cfg & CFG_CHIP_R_MSK) >> 4;
+
+	/* read the adapters RAM size */
+	t8 = skge_read8(hw, B2_E_0);
+	if (hw->chip_id == CHIP_ID_GENESIS) {
+		if (t8 == 3) {
+			/* special case: 4 x 64k x 36, offset = 0x80000 */
+			hw->ram_size = 0x100000;
+			hw->ram_offset = 0x80000;
+		} else
+			hw->ram_size = t8 * 512;
+	}
+	else if (t8 == 0)
+		hw->ram_size = 0x20000;
+	else
+		hw->ram_size = t8 * 4096;
+
+	if (hw->chip_id == CHIP_ID_GENESIS)
+		genesis_init(hw);
+	else {
+		/* switch power to VCC (WA for VAUX problem) */
+		skge_write8(hw, B0_POWER_CTRL,
+			    PC_VAUX_ENA | PC_VCC_ENA | PC_VAUX_OFF | PC_VCC_ON);
+		for (i = 0; i < hw->ports; i++) {
+			skge_write16(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_SET);
+			skge_write16(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_CLR);
+		}
+	}
+
+	/* turn off hardware timer (unused) */
+	skge_write8(hw, B2_TI_CTRL, TIM_STOP);
+	skge_write8(hw, B2_TI_CTRL, TIM_CLR_IRQ);
+	skge_write8(hw, B0_LED, LED_STAT_ON);
+
+	/* enable the Tx Arbiters */
+	for (i = 0; i < hw->ports; i++)
+		skge_write8(hw, SK_REG(i, TXA_CTRL), TXA_ENA_ARB);
+
+	/* Initialize ram interface */
+	skge_write16(hw, B3_RI_CTRL, RI_RST_CLR);
+
+	skge_write8(hw, B3_RI_WTO_R1, SK_RI_TO_53);
+	skge_write8(hw, B3_RI_WTO_XA1, SK_RI_TO_53);
+	skge_write8(hw, B3_RI_WTO_XS1, SK_RI_TO_53);
+	skge_write8(hw, B3_RI_RTO_R1, SK_RI_TO_53);
+	skge_write8(hw, B3_RI_RTO_XA1, SK_RI_TO_53);
+	skge_write8(hw, B3_RI_RTO_XS1, SK_RI_TO_53);
+	skge_write8(hw, B3_RI_WTO_R2, SK_RI_TO_53);
+	skge_write8(hw, B3_RI_WTO_XA2, SK_RI_TO_53);
+	skge_write8(hw, B3_RI_WTO_XS2, SK_RI_TO_53);
+	skge_write8(hw, B3_RI_RTO_R2, SK_RI_TO_53);
+	skge_write8(hw, B3_RI_RTO_XA2, SK_RI_TO_53);
+	skge_write8(hw, B3_RI_RTO_XS2, SK_RI_TO_53);
+
+	skge_write32(hw, B0_HWE_IMSK, IS_ERR_MSK);
+
+	/* Set interrupt moderation for Transmit only
+	 * Receive interrupts avoided by NAPI
+	 */
+	skge_write32(hw, B2_IRQM_MSK, IS_XA1_F|IS_XA2_F);
+	skge_write32(hw, B2_IRQM_INI, skge_usecs2clk(hw, 100));
+	skge_write32(hw, B2_IRQM_CTRL, TIM_START);
+
+	hw->intr_mask = IS_HW_ERR | IS_EXT_REG;
+	skge_write32(hw, B0_IMSK, hw->intr_mask);
+
+	if (hw->chip_id != CHIP_ID_GENESIS)
+		skge_write8(hw, GMAC_IRQ_MSK, 0);
+
+	spin_lock_bh(&hw->phy_lock);
+	for (i = 0; i < hw->ports; i++) {
+		if (hw->chip_id == CHIP_ID_GENESIS)
+			genesis_reset(hw, i);
+		else
+			yukon_reset(hw, i);
+	}
+	spin_unlock_bh(&hw->phy_lock);
+
+	return 0;
+}
+
+/* Initialize network device */
+static struct net_device *skge_devinit(struct skge_hw *hw, int port,
+				       int highmem)
+{
+	struct skge_port *skge;
+	struct net_device *dev = alloc_etherdev(sizeof(*skge));
+
+	if (!dev) {
+		printk(KERN_ERR "skge etherdev alloc failed");
+		return NULL;
+	}
+
+	SET_MODULE_OWNER(dev);
+	SET_NETDEV_DEV(dev, &hw->pdev->dev);
+	dev->open = skge_up;
+	dev->stop = skge_down;
+	dev->hard_start_xmit = skge_xmit_frame;
+	dev->get_stats = skge_get_stats;
+	if (hw->chip_id == CHIP_ID_GENESIS)
+		dev->set_multicast_list = genesis_set_multicast;
+	else
+		dev->set_multicast_list = yukon_set_multicast;
+
+	dev->set_mac_address = skge_set_mac_address;
+	dev->change_mtu = skge_change_mtu;
+	SET_ETHTOOL_OPS(dev, &skge_ethtool_ops);
+	dev->tx_timeout = skge_tx_timeout;
+	dev->watchdog_timeo = TX_WATCHDOG;
+	dev->poll = skge_poll;
+	dev->weight = NAPI_WEIGHT;
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	dev->poll_controller = skge_netpoll;
+#endif
+	dev->irq = hw->pdev->irq;
+	dev->features = NETIF_F_LLTX;
+	if (highmem)
+		dev->features |= NETIF_F_HIGHDMA;
+
+	skge = netdev_priv(dev);
+	skge->netdev = dev;
+	skge->hw = hw;
+	skge->msg_enable = netif_msg_init(debug, default_msg);
+	skge->tx_ring.count = DEFAULT_TX_RING_SIZE;
+	skge->rx_ring.count = DEFAULT_RX_RING_SIZE;
+
+	/* Auto speed and flow control */
+	skge->autoneg = AUTONEG_ENABLE;
+	skge->flow_control = FLOW_MODE_SYMMETRIC;
+	skge->duplex = -1;
+	skge->speed = -1;
+	skge->advertising = skge_supported_modes(hw);
+
+	hw->dev[port] = dev;
+
+	skge->port = port;
+
+	spin_lock_init(&skge->tx_lock);
+
+	if (hw->chip_id != CHIP_ID_GENESIS) {
+		dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
+		skge->rx_csum = 1;
+	}
+
+	/* read the mac address */
+	memcpy_fromio(dev->dev_addr, hw->regs + B2_MAC_1 + port*8, ETH_ALEN);
+
+	/* device is off until link detection */
+	netif_carrier_off(dev);
+	netif_stop_queue(dev);
+
+	return dev;
+}
+
+static void __devinit skge_show_addr(struct net_device *dev)
+{
+	const struct skge_port *skge = netdev_priv(dev);
+
+	if (netif_msg_probe(skge))
+		printk(KERN_INFO PFX "%s: addr %02x:%02x:%02x:%02x:%02x:%02x\n",
+		       dev->name,
+		       dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
+		       dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
+}
+
+static int __devinit skge_probe(struct pci_dev *pdev,
+				const struct pci_device_id *ent)
+{
+	struct net_device *dev, *dev1;
+	struct skge_hw *hw;
+	int err, using_dac = 0;
+
+	if ((err = pci_enable_device(pdev))) {
+		printk(KERN_ERR PFX "%s cannot enable PCI device\n",
+		       pci_name(pdev));
+		goto err_out;
+	}
+
+	if ((err = pci_request_regions(pdev, DRV_NAME))) {
+		printk(KERN_ERR PFX "%s cannot obtain PCI resources\n",
+		       pci_name(pdev));
+		goto err_out_disable_pdev;
+	}
+
+	pci_set_master(pdev);
+
+	if (!(err = pci_set_dma_mask(pdev, DMA_64BIT_MASK)))
+		using_dac = 1;
+	else if (!(err = pci_set_dma_mask(pdev, DMA_32BIT_MASK))) {
+		printk(KERN_ERR PFX "%s no usable DMA configuration\n",
+		       pci_name(pdev));
+		goto err_out_free_regions;
+	}
+
+#ifdef __BIG_ENDIAN
+	/* byte swap decriptors in hardware */
+	{
+		u32 reg;
+
+		pci_read_config_dword(pdev, PCI_DEV_REG2, &reg);
+		reg |= PCI_REV_DESC;
+		pci_write_config_dword(pdev, PCI_DEV_REG2, reg);
+	}
+#endif
+
+	err = -ENOMEM;
+	hw = kmalloc(sizeof(*hw), GFP_KERNEL);
+	if (!hw) {
+		printk(KERN_ERR PFX "%s: cannot allocate hardware struct\n",
+		       pci_name(pdev));
+		goto err_out_free_regions;
+	}
+
+	memset(hw, 0, sizeof(*hw));
+	hw->pdev = pdev;
+	spin_lock_init(&hw->phy_lock);
+	tasklet_init(&hw->ext_tasklet, skge_extirq, (unsigned long) hw);
+
+	hw->regs = ioremap_nocache(pci_resource_start(pdev, 0), 0x4000);
+	if (!hw->regs) {
+		printk(KERN_ERR PFX "%s: cannot map device registers\n",
+		       pci_name(pdev));
+		goto err_out_free_hw;
+	}
+
+	if ((err = request_irq(pdev->irq, skge_intr, SA_SHIRQ, DRV_NAME, hw))) {
+		printk(KERN_ERR PFX "%s: cannot assign irq %d\n",
+		       pci_name(pdev), pdev->irq);
+		goto err_out_iounmap;
+	}
+	pci_set_drvdata(pdev, hw);
+
+	err = skge_reset(hw);
+	if (err)
+		goto err_out_free_irq;
+
+	printk(KERN_INFO PFX "addr 0x%lx irq %d chip %s rev %d\n",
+	       pci_resource_start(pdev, 0), pdev->irq,
+	       skge_board_name(hw), hw->chip_rev);
+
+	if ((dev = skge_devinit(hw, 0, using_dac)) == NULL)
+		goto err_out_led_off;
+
+	if ((err = register_netdev(dev))) {
+		printk(KERN_ERR PFX "%s: cannot register net device\n",
+		       pci_name(pdev));
+		goto err_out_free_netdev;
+	}
+
+	skge_show_addr(dev);
+
+	if (hw->ports > 1 && (dev1 = skge_devinit(hw, 1, using_dac))) {
+		if (register_netdev(dev1) == 0)
+			skge_show_addr(dev1);
+		else {
+			/* Failure to register second port need not be fatal */
+			printk(KERN_WARNING PFX "register of second port failed\n");
+			hw->dev[1] = NULL;
+			free_netdev(dev1);
+		}
+	}
+
+	return 0;
+
+err_out_free_netdev:
+	free_netdev(dev);
+err_out_led_off:
+	skge_write16(hw, B0_LED, LED_STAT_OFF);
+err_out_free_irq:
+	free_irq(pdev->irq, hw);
+err_out_iounmap:
+	iounmap(hw->regs);
+err_out_free_hw:
+	kfree(hw);
+err_out_free_regions:
+	pci_release_regions(pdev);
+err_out_disable_pdev:
+	pci_disable_device(pdev);
+	pci_set_drvdata(pdev, NULL);
+err_out:
+	return err;
+}
+
+static void __devexit skge_remove(struct pci_dev *pdev)
+{
+	struct skge_hw *hw  = pci_get_drvdata(pdev);
+	struct net_device *dev0, *dev1;
+
+	if (!hw)
+		return;
+
+	if ((dev1 = hw->dev[1]))
+		unregister_netdev(dev1);
+	dev0 = hw->dev[0];
+	unregister_netdev(dev0);
+
+	tasklet_kill(&hw->ext_tasklet);
+
+	free_irq(pdev->irq, hw);
+	pci_release_regions(pdev);
+	pci_disable_device(pdev);
+	if (dev1)
+		free_netdev(dev1);
+	free_netdev(dev0);
+	skge_write16(hw, B0_LED, LED_STAT_OFF);
+	iounmap(hw->regs);
+	kfree(hw);
+	pci_set_drvdata(pdev, NULL);
+}
+
+#ifdef CONFIG_PM
+static int skge_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+	struct skge_hw *hw  = pci_get_drvdata(pdev);
+	int i, wol = 0;
+
+	for (i = 0; i < 2; i++) {
+		struct net_device *dev = hw->dev[i];
+
+		if (dev) {
+			struct skge_port *skge = netdev_priv(dev);
+			if (netif_running(dev)) {
+				netif_carrier_off(dev);
+				skge_down(dev);
+			}
+			netif_device_detach(dev);
+			wol |= skge->wol;
+		}
+	}
+
+	pci_save_state(pdev);
+	pci_enable_wake(pdev, pci_choose_state(pdev, state), wol);
+	pci_disable_device(pdev);
+	pci_set_power_state(pdev, pci_choose_state(pdev, state));
+
+	return 0;
+}
+
+static int skge_resume(struct pci_dev *pdev)
+{
+	struct skge_hw *hw  = pci_get_drvdata(pdev);
+	int i;
+
+	pci_set_power_state(pdev, PCI_D0);
+	pci_restore_state(pdev);
+	pci_enable_wake(pdev, PCI_D0, 0);
+
+	skge_reset(hw);
+
+	for (i = 0; i < 2; i++) {
+		struct net_device *dev = hw->dev[i];
+		if (dev) {
+			netif_device_attach(dev);
+			if (netif_running(dev))
+				skge_up(dev);
+		}
+	}
+	return 0;
+}
+#endif
+
+static struct pci_driver skge_driver = {
+	.name =         DRV_NAME,
+	.id_table =     skge_id_table,
+	.probe =        skge_probe,
+	.remove =       __devexit_p(skge_remove),
+#ifdef CONFIG_PM
+	.suspend = 	skge_suspend,
+	.resume = 	skge_resume,
+#endif
+};
+
+static int __init skge_init_module(void)
+{
+	return pci_module_init(&skge_driver);
+}
+
+static void __exit skge_cleanup_module(void)
+{
+	pci_unregister_driver(&skge_driver);
+}
+
+module_init(skge_init_module);
+module_exit(skge_cleanup_module);
diff --git a/drivers/net/skge.h b/drivers/net/skge.h
new file mode 100644
--- /dev/null
+++ b/drivers/net/skge.h
@@ -0,0 +1,2617 @@
+/*
+ * Definitions for the new Marvell Yukon / SysKonenct driver.
+ */
+#ifndef _SKGE_H
+#define _SKGE_H
+
+/* PCI config registers */
+#define PCI_DEV_REG1	0x40
+#define PCI_DEV_REG2	0x44
+#define  PCI_REV_DESC	 0x4
+
+#define PCI_STATUS_ERROR_BITS (PCI_STATUS_DETECTED_PARITY | \
+			       PCI_STATUS_SIG_SYSTEM_ERROR | \
+			       PCI_STATUS_REC_MASTER_ABORT | \
+			       PCI_STATUS_REC_TARGET_ABORT | \
+			       PCI_STATUS_PARITY)
+
+enum csr_regs {
+	B0_RAP	= 0x0000,
+	B0_CTST	= 0x0004,
+	B0_LED	= 0x0006,
+	B0_POWER_CTRL	= 0x0007,
+	B0_ISRC	= 0x0008,
+	B0_IMSK	= 0x000c,
+	B0_HWE_ISRC	= 0x0010,
+	B0_HWE_IMSK	= 0x0014,
+	B0_SP_ISRC	= 0x0018,
+	B0_XM1_IMSK	= 0x0020,
+	B0_XM1_ISRC	= 0x0028,
+	B0_XM1_PHY_ADDR	= 0x0030,
+	B0_XM1_PHY_DATA	= 0x0034,
+	B0_XM2_IMSK	= 0x0040,
+	B0_XM2_ISRC	= 0x0048,
+	B0_XM2_PHY_ADDR	= 0x0050,
+	B0_XM2_PHY_DATA	= 0x0054,
+	B0_R1_CSR	= 0x0060,
+	B0_R2_CSR	= 0x0064,
+	B0_XS1_CSR	= 0x0068,
+	B0_XA1_CSR	= 0x006c,
+	B0_XS2_CSR	= 0x0070,
+	B0_XA2_CSR	= 0x0074,
+
+	B2_MAC_1	= 0x0100,
+	B2_MAC_2	= 0x0108,
+	B2_MAC_3	= 0x0110,
+	B2_CONN_TYP	= 0x0118,
+	B2_PMD_TYP	= 0x0119,
+	B2_MAC_CFG	= 0x011a,
+	B2_CHIP_ID	= 0x011b,
+	B2_E_0		= 0x011c,
+	B2_E_1		= 0x011d,
+	B2_E_2		= 0x011e,
+	B2_E_3		= 0x011f,
+	B2_FAR		= 0x0120,
+	B2_FDP		= 0x0124,
+	B2_LD_CTRL	= 0x0128,
+	B2_LD_TEST	= 0x0129,
+	B2_TI_INI	= 0x0130,
+	B2_TI_VAL	= 0x0134,
+	B2_TI_CTRL	= 0x0138,
+	B2_TI_TEST	= 0x0139,
+	B2_IRQM_INI	= 0x0140,
+	B2_IRQM_VAL	= 0x0144,
+	B2_IRQM_CTRL	= 0x0148,
+	B2_IRQM_TEST	= 0x0149,
+	B2_IRQM_MSK	= 0x014c,
+	B2_IRQM_HWE_MSK	= 0x0150,
+	B2_TST_CTRL1	= 0x0158,
+	B2_TST_CTRL2	= 0x0159,
+	B2_GP_IO	= 0x015c,
+	B2_I2C_CTRL	= 0x0160,
+	B2_I2C_DATA	= 0x0164,
+	B2_I2C_IRQ	= 0x0168,
+	B2_I2C_SW	= 0x016c,
+	B2_BSC_INI	= 0x0170,
+	B2_BSC_VAL	= 0x0174,
+	B2_BSC_CTRL	= 0x0178,
+	B2_BSC_STAT	= 0x0179,
+	B2_BSC_TST	= 0x017a,
+
+	B3_RAM_ADDR	= 0x0180,
+	B3_RAM_DATA_LO	= 0x0184,
+	B3_RAM_DATA_HI	= 0x0188,
+	B3_RI_WTO_R1	= 0x0190,
+	B3_RI_WTO_XA1	= 0x0191,
+	B3_RI_WTO_XS1	= 0x0192,
+	B3_RI_RTO_R1	= 0x0193,
+	B3_RI_RTO_XA1	= 0x0194,
+	B3_RI_RTO_XS1	= 0x0195,
+	B3_RI_WTO_R2	= 0x0196,
+	B3_RI_WTO_XA2	= 0x0197,
+	B3_RI_WTO_XS2	= 0x0198,
+	B3_RI_RTO_R2	= 0x0199,
+	B3_RI_RTO_XA2	= 0x019a,
+	B3_RI_RTO_XS2	= 0x019b,
+	B3_RI_TO_VAL	= 0x019c,
+	B3_RI_CTRL	= 0x01a0,
+	B3_RI_TEST	= 0x01a2,
+	B3_MA_TOINI_RX1	= 0x01b0,
+	B3_MA_TOINI_RX2	= 0x01b1,
+	B3_MA_TOINI_TX1	= 0x01b2,
+	B3_MA_TOINI_TX2	= 0x01b3,
+	B3_MA_TOVAL_RX1	= 0x01b4,
+	B3_MA_TOVAL_RX2	= 0x01b5,
+	B3_MA_TOVAL_TX1	= 0x01b6,
+	B3_MA_TOVAL_TX2	= 0x01b7,
+	B3_MA_TO_CTRL	= 0x01b8,
+	B3_MA_TO_TEST	= 0x01ba,
+	B3_MA_RCINI_RX1	= 0x01c0,
+	B3_MA_RCINI_RX2	= 0x01c1,
+	B3_MA_RCINI_TX1	= 0x01c2,
+	B3_MA_RCINI_TX2	= 0x01c3,
+	B3_MA_RCVAL_RX1	= 0x01c4,
+	B3_MA_RCVAL_RX2	= 0x01c5,
+	B3_MA_RCVAL_TX1	= 0x01c6,
+	B3_MA_RCVAL_TX2	= 0x01c7,
+	B3_MA_RC_CTRL	= 0x01c8,
+	B3_MA_RC_TEST	= 0x01ca,
+	B3_PA_TOINI_RX1	= 0x01d0,
+	B3_PA_TOINI_RX2	= 0x01d4,
+	B3_PA_TOINI_TX1	= 0x01d8,
+	B3_PA_TOINI_TX2	= 0x01dc,
+	B3_PA_TOVAL_RX1	= 0x01e0,
+	B3_PA_TOVAL_RX2	= 0x01e4,
+	B3_PA_TOVAL_TX1	= 0x01e8,
+	B3_PA_TOVAL_TX2	= 0x01ec,
+	B3_PA_CTRL	= 0x01f0,
+	B3_PA_TEST	= 0x01f2,
+};
+
+/*	B0_CTST			16 bit	Control/Status register */
+enum {
+	CS_CLK_RUN_HOT	= 1<<13,/* CLK_RUN hot m. (YUKON-Lite only) */
+	CS_CLK_RUN_RST	= 1<<12,/* CLK_RUN reset  (YUKON-Lite only) */
+	CS_CLK_RUN_ENA	= 1<<11,/* CLK_RUN enable (YUKON-Lite only) */
+	CS_VAUX_AVAIL	= 1<<10,/* VAUX available (YUKON only) */
+	CS_BUS_CLOCK	= 1<<9,	/* Bus Clock 0/1 = 33/66 MHz */
+	CS_BUS_SLOT_SZ	= 1<<8,	/* Slot Size 0/1 = 32/64 bit slot */
+	CS_ST_SW_IRQ	= 1<<7,	/* Set IRQ SW Request */
+	CS_CL_SW_IRQ	= 1<<6,	/* Clear IRQ SW Request */
+	CS_STOP_DONE	= 1<<5,	/* Stop Master is finished */
+	CS_STOP_MAST	= 1<<4,	/* Command Bit to stop the master */
+	CS_MRST_CLR	= 1<<3,	/* Clear Master reset	*/
+	CS_MRST_SET	= 1<<2,	/* Set Master reset	*/
+	CS_RST_CLR	= 1<<1,	/* Clear Software reset	*/
+	CS_RST_SET	= 1,	/* Set   Software reset	*/
+
+/*	B0_LED			 8 Bit	LED register */
+/* Bit  7.. 2:	reserved */
+	LED_STAT_ON	= 1<<1,	/* Status LED on	*/
+	LED_STAT_OFF	= 1,		/* Status LED off	*/
+
+/*	B0_POWER_CTRL	 8 Bit	Power Control reg (YUKON only) */
+	PC_VAUX_ENA	= 1<<7,	/* Switch VAUX Enable  */
+	PC_VAUX_DIS	= 1<<6,	/* Switch VAUX Disable */
+	PC_VCC_ENA	= 1<<5,	/* Switch VCC Enable  */
+	PC_VCC_DIS	= 1<<4,	/* Switch VCC Disable */
+	PC_VAUX_ON	= 1<<3,	/* Switch VAUX On  */
+	PC_VAUX_OFF	= 1<<2,	/* Switch VAUX Off */
+	PC_VCC_ON	= 1<<1,	/* Switch VCC On  */
+	PC_VCC_OFF	= 1<<0,	/* Switch VCC Off */
+};
+
+/*	B2_IRQM_MSK 	32 bit	IRQ Moderation Mask */
+enum {
+	IS_ALL_MSK	= 0xbffffffful,	/* All Interrupt bits */
+	IS_HW_ERR	= 1<<31,	/* Interrupt HW Error */
+					/* Bit 30:	reserved */
+	IS_PA_TO_RX1	= 1<<29,	/* Packet Arb Timeout Rx1 */
+	IS_PA_TO_RX2	= 1<<28,	/* Packet Arb Timeout Rx2 */
+	IS_PA_TO_TX1	= 1<<27,	/* Packet Arb Timeout Tx1 */
+	IS_PA_TO_TX2	= 1<<26,	/* Packet Arb Timeout Tx2 */
+	IS_I2C_READY	= 1<<25,	/* IRQ on end of I2C Tx */
+	IS_IRQ_SW	= 1<<24,	/* SW forced IRQ	*/
+	IS_EXT_REG	= 1<<23,	/* IRQ from LM80 or PHY (GENESIS only) */
+					/* IRQ from PHY (YUKON only) */
+	IS_TIMINT	= 1<<22,	/* IRQ from Timer	*/
+	IS_MAC1		= 1<<21,	/* IRQ from MAC 1	*/
+	IS_LNK_SYNC_M1	= 1<<20,	/* Link Sync Cnt wrap MAC 1 */
+	IS_MAC2		= 1<<19,	/* IRQ from MAC 2	*/
+	IS_LNK_SYNC_M2	= 1<<18,	/* Link Sync Cnt wrap MAC 2 */
+/* Receive Queue 1 */
+	IS_R1_B		= 1<<17,	/* Q_R1 End of Buffer */
+	IS_R1_F		= 1<<16,	/* Q_R1 End of Frame */
+	IS_R1_C		= 1<<15,	/* Q_R1 Encoding Error */
+/* Receive Queue 2 */
+	IS_R2_B		= 1<<14,	/* Q_R2 End of Buffer */
+	IS_R2_F		= 1<<13,	/* Q_R2 End of Frame */
+	IS_R2_C		= 1<<12,	/* Q_R2 Encoding Error */
+/* Synchronous Transmit Queue 1 */
+	IS_XS1_B	= 1<<11,	/* Q_XS1 End of Buffer */
+	IS_XS1_F	= 1<<10,	/* Q_XS1 End of Frame */
+	IS_XS1_C	= 1<<9,		/* Q_XS1 Encoding Error */
+/* Asynchronous Transmit Queue 1 */
+	IS_XA1_B	= 1<<8,		/* Q_XA1 End of Buffer */
+	IS_XA1_F	= 1<<7,		/* Q_XA1 End of Frame */
+	IS_XA1_C	= 1<<6,		/* Q_XA1 Encoding Error */
+/* Synchronous Transmit Queue 2 */
+	IS_XS2_B	= 1<<5,		/* Q_XS2 End of Buffer */
+	IS_XS2_F	= 1<<4,		/* Q_XS2 End of Frame */
+	IS_XS2_C	= 1<<3,		/* Q_XS2 Encoding Error */
+/* Asynchronous Transmit Queue 2 */
+	IS_XA2_B	= 1<<2,		/* Q_XA2 End of Buffer */
+	IS_XA2_F	= 1<<1,		/* Q_XA2 End of Frame */
+	IS_XA2_C	= 1<<0,		/* Q_XA2 Encoding Error */
+
+	IS_TO_PORT1	= IS_PA_TO_RX1 | IS_PA_TO_TX1,
+	IS_TO_PORT2	= IS_PA_TO_RX2 | IS_PA_TO_TX2,
+
+	IS_PORT_1	= IS_XA1_F| IS_R1_F | IS_TO_PORT1 | IS_MAC1,
+	IS_PORT_2	= IS_XA2_F| IS_R2_F | IS_TO_PORT2 | IS_MAC2,
+};
+
+
+/*	B2_IRQM_HWE_MSK	32 bit	IRQ Moderation HW Error Mask */
+enum {
+	IS_ERR_MSK	= 0x00003fff,/* 		All Error bits */
+
+	IS_IRQ_TIST_OV	= 1<<13, /* Time Stamp Timer Overflow (YUKON only) */
+	IS_IRQ_SENSOR	= 1<<12, /* IRQ from Sensor (YUKON only) */
+	IS_IRQ_MST_ERR	= 1<<11, /* IRQ master error detected */
+	IS_IRQ_STAT	= 1<<10, /* IRQ status exception */
+	IS_NO_STAT_M1	= 1<<9,	/* No Rx Status from MAC 1 */
+	IS_NO_STAT_M2	= 1<<8,	/* No Rx Status from MAC 2 */
+	IS_NO_TIST_M1	= 1<<7,	/* No Time Stamp from MAC 1 */
+	IS_NO_TIST_M2	= 1<<6,	/* No Time Stamp from MAC 2 */
+	IS_RAM_RD_PAR	= 1<<5,	/* RAM Read  Parity Error */
+	IS_RAM_WR_PAR	= 1<<4,	/* RAM Write Parity Error */
+	IS_M1_PAR_ERR	= 1<<3,	/* MAC 1 Parity Error */
+	IS_M2_PAR_ERR	= 1<<2,	/* MAC 2 Parity Error */
+	IS_R1_PAR_ERR	= 1<<1,	/* Queue R1 Parity Error */
+	IS_R2_PAR_ERR	= 1<<0,	/* Queue R2 Parity Error */
+};
+
+/*	B2_TST_CTRL1	 8 bit	Test Control Register 1 */
+enum {
+	TST_FRC_DPERR_MR = 1<<7, /* force DATAPERR on MST RD */
+	TST_FRC_DPERR_MW = 1<<6, /* force DATAPERR on MST WR */
+	TST_FRC_DPERR_TR = 1<<5, /* force DATAPERR on TRG RD */
+	TST_FRC_DPERR_TW = 1<<4, /* force DATAPERR on TRG WR */
+	TST_FRC_APERR_M	 = 1<<3, /* force ADDRPERR on MST */
+	TST_FRC_APERR_T	 = 1<<2, /* force ADDRPERR on TRG */
+	TST_CFG_WRITE_ON = 1<<1, /* Enable  Config Reg WR */
+	TST_CFG_WRITE_OFF= 1<<0, /* Disable Config Reg WR */
+};
+
+/*	B2_MAC_CFG		 8 bit	MAC Configuration / Chip Revision */
+enum {
+	CFG_CHIP_R_MSK	  = 0xf<<4,	/* Bit 7.. 4: Chip Revision */
+					/* Bit 3.. 2:	reserved */
+	CFG_DIS_M2_CLK	  = 1<<1,	/* Disable Clock for 2nd MAC */
+	CFG_SNG_MAC	  = 1<<0,	/* MAC Config: 0=2 MACs / 1=1 MAC*/
+};
+
+/*	B2_CHIP_ID		 8 bit 	Chip Identification Number */
+enum {
+	CHIP_ID_GENESIS	   = 0x0a, /* Chip ID for GENESIS */
+	CHIP_ID_YUKON	   = 0xb0, /* Chip ID for YUKON */
+	CHIP_ID_YUKON_LITE = 0xb1, /* Chip ID for YUKON-Lite (Rev. A1-A3) */
+	CHIP_ID_YUKON_LP   = 0xb2, /* Chip ID for YUKON-LP */
+	CHIP_ID_YUKON_XL   = 0xb3, /* Chip ID for YUKON-2 XL */
+	CHIP_ID_YUKON_EC   = 0xb6, /* Chip ID for YUKON-2 EC */
+ 	CHIP_ID_YUKON_FE   = 0xb7, /* Chip ID for YUKON-2 FE */
+
+	CHIP_REV_YU_LITE_A1  = 3,	/* Chip Rev. for YUKON-Lite A1,A2 */
+	CHIP_REV_YU_LITE_A3  = 7,	/* Chip Rev. for YUKON-Lite A3 */
+};
+
+/*	B2_TI_CTRL		 8 bit	Timer control */
+/*	B2_IRQM_CTRL	 8 bit	IRQ Moderation Timer Control */
+enum {
+	TIM_START	= 1<<2,	/* Start Timer */
+	TIM_STOP	= 1<<1,	/* Stop  Timer */
+	TIM_CLR_IRQ	= 1<<0,	/* Clear Timer IRQ (!IRQM) */
+};
+
+/*	B2_TI_TEST		 8 Bit	Timer Test */
+/*	B2_IRQM_TEST	 8 bit	IRQ Moderation Timer Test */
+/*	B28_DPT_TST		 8 bit	Descriptor Poll Timer Test Reg */
+enum {
+	TIM_T_ON	= 1<<2,	/* Test mode on */
+	TIM_T_OFF	= 1<<1,	/* Test mode off */
+	TIM_T_STEP	= 1<<0,	/* Test step */
+};
+
+/*	B2_GP_IO		32 bit	General Purpose I/O Register */
+enum {
+	GP_DIR_9 = 1<<25, /* IO_9 direct, 0=In/1=Out */
+	GP_DIR_8 = 1<<24, /* IO_8 direct, 0=In/1=Out */
+	GP_DIR_7 = 1<<23, /* IO_7 direct, 0=In/1=Out */
+	GP_DIR_6 = 1<<22, /* IO_6 direct, 0=In/1=Out */
+	GP_DIR_5 = 1<<21, /* IO_5 direct, 0=In/1=Out */
+	GP_DIR_4 = 1<<20, /* IO_4 direct, 0=In/1=Out */
+	GP_DIR_3 = 1<<19, /* IO_3 direct, 0=In/1=Out */
+	GP_DIR_2 = 1<<18, /* IO_2 direct, 0=In/1=Out */
+	GP_DIR_1 = 1<<17, /* IO_1 direct, 0=In/1=Out */
+	GP_DIR_0 = 1<<16, /* IO_0 direct, 0=In/1=Out */
+
+	GP_IO_9	= 1<<9,	/* IO_9 pin */
+	GP_IO_8	= 1<<8,	/* IO_8 pin */
+	GP_IO_7	= 1<<7,	/* IO_7 pin */
+	GP_IO_6	= 1<<6,	/* IO_6 pin */
+	GP_IO_5	= 1<<5,	/* IO_5 pin */
+	GP_IO_4	= 1<<4,	/* IO_4 pin */
+	GP_IO_3	= 1<<3,	/* IO_3 pin */
+	GP_IO_2	= 1<<2,	/* IO_2 pin */
+	GP_IO_1	= 1<<1,	/* IO_1 pin */
+	GP_IO_0	= 1<<0,	/* IO_0 pin */
+};
+
+/* Descriptor Bit Definition */
+/*	TxCtrl		Transmit Buffer Control Field */
+/*	RxCtrl		Receive  Buffer Control Field */
+enum {
+	BMU_OWN		= 1<<31, /* OWN bit: 0=host/1=BMU */
+	BMU_STF		= 1<<30, /* Start of Frame */
+	BMU_EOF		= 1<<29, /* End of Frame */
+	BMU_IRQ_EOB	= 1<<28, /* Req "End of Buffer" IRQ */
+	BMU_IRQ_EOF	= 1<<27, /* Req "End of Frame" IRQ */
+				/* TxCtrl specific bits */
+	BMU_STFWD	= 1<<26, /* (Tx)	Store & Forward Frame */
+	BMU_NO_FCS	= 1<<25, /* (Tx) Disable MAC FCS (CRC) generation */
+	BMU_SW	= 1<<24, /* (Tx)	1 bit res. for SW use */
+				/* RxCtrl specific bits */
+	BMU_DEV_0	= 1<<26, /* (Rx)	Transfer data to Dev0 */
+	BMU_STAT_VAL	= 1<<25, /* (Rx)	Rx Status Valid */
+	BMU_TIST_VAL	= 1<<24, /* (Rx)	Rx TimeStamp Valid */
+			/* Bit 23..16:	BMU Check Opcodes */
+	BMU_CHECK	= 0x55<<16, /* Default BMU check */
+	BMU_TCP_CHECK	= 0x56<<16, /* Descr with TCP ext */
+	BMU_UDP_CHECK	= 0x57<<16, /* Descr with UDP ext (YUKON only) */
+	BMU_BBC		= 0xffffL, /* Bit 15.. 0:	Buffer Byte Counter */
+};
+
+/*	B2_BSC_CTRL		 8 bit	Blink Source Counter Control */
+enum {
+	 BSC_START	= 1<<1,	/* Start Blink Source Counter */
+	 BSC_STOP	= 1<<0,	/* Stop  Blink Source Counter */
+};
+
+/*	B2_BSC_STAT		 8 bit	Blink Source Counter Status */
+enum {
+	BSC_SRC		= 1<<0,	/* Blink Source, 0=Off / 1=On */
+};
+
+/*	B2_BSC_TST		16 bit	Blink Source Counter Test Reg */
+enum {
+	BSC_T_ON	= 1<<2,	/* Test mode on */
+	BSC_T_OFF	= 1<<1,	/* Test mode off */
+	BSC_T_STEP	= 1<<0,	/* Test step */
+};
+
+/*	B3_RAM_ADDR		32 bit	RAM Address, to read or write */
+					/* Bit 31..19:	reserved */
+#define RAM_ADR_RAN	0x0007ffffL	/* Bit 18.. 0:	RAM Address Range */
+/* RAM Interface Registers */
+
+/*	B3_RI_CTRL		16 bit	RAM Iface Control Register */
+enum {
+	RI_CLR_RD_PERR	= 1<<9,	/* Clear IRQ RAM Read Parity Err */
+	RI_CLR_WR_PERR	= 1<<8,	/* Clear IRQ RAM Write Parity Err*/
+
+	RI_RST_CLR	= 1<<1,	/* Clear RAM Interface Reset */
+	RI_RST_SET	= 1<<0,	/* Set   RAM Interface Reset */
+};
+
+/* MAC Arbiter Registers */
+/*	B3_MA_TO_CTRL	16 bit	MAC Arbiter Timeout Ctrl Reg */
+enum {
+	MA_FOE_ON	= 1<<3,	/* XMAC Fast Output Enable ON */
+	MA_FOE_OFF	= 1<<2,	/* XMAC Fast Output Enable OFF */
+	MA_RST_CLR	= 1<<1,	/* Clear MAC Arbiter Reset */
+	MA_RST_SET	= 1<<0,	/* Set   MAC Arbiter Reset */
+
+};
+
+/* Timeout values */
+#define SK_MAC_TO_53	72		/* MAC arbiter timeout */
+#define SK_PKT_TO_53	0x2000		/* Packet arbiter timeout */
+#define SK_PKT_TO_MAX	0xffff		/* Maximum value */
+#define SK_RI_TO_53	36		/* RAM interface timeout */
+
+/* Packet Arbiter Registers */
+/*	B3_PA_CTRL		16 bit	Packet Arbiter Ctrl Register */
+enum {
+	PA_CLR_TO_TX2	= 1<<13,	/* Clear IRQ Packet Timeout TX2 */
+	PA_CLR_TO_TX1	= 1<<12,	/* Clear IRQ Packet Timeout TX1 */
+	PA_CLR_TO_RX2	= 1<<11,	/* Clear IRQ Packet Timeout RX2 */
+	PA_CLR_TO_RX1	= 1<<10,	/* Clear IRQ Packet Timeout RX1 */
+	PA_ENA_TO_TX2	= 1<<9,	/* Enable  Timeout Timer TX2 */
+	PA_DIS_TO_TX2	= 1<<8,	/* Disable Timeout Timer TX2 */
+	PA_ENA_TO_TX1	= 1<<7,	/* Enable  Timeout Timer TX1 */
+	PA_DIS_TO_TX1	= 1<<6,	/* Disable Timeout Timer TX1 */
+	PA_ENA_TO_RX2	= 1<<5,	/* Enable  Timeout Timer RX2 */
+	PA_DIS_TO_RX2	= 1<<4,	/* Disable Timeout Timer RX2 */
+	PA_ENA_TO_RX1	= 1<<3,	/* Enable  Timeout Timer RX1 */
+	PA_DIS_TO_RX1	= 1<<2,	/* Disable Timeout Timer RX1 */
+	PA_RST_CLR	= 1<<1,	/* Clear MAC Arbiter Reset */
+	PA_RST_SET	= 1<<0,	/* Set   MAC Arbiter Reset */
+};
+
+#define PA_ENA_TO_ALL	(PA_ENA_TO_RX1 | PA_ENA_TO_RX2 |\
+						PA_ENA_TO_TX1 | PA_ENA_TO_TX2)
+
+
+/* Transmit Arbiter Registers MAC 1 and 2, use SK_REG() to access */
+/*	TXA_ITI_INI		32 bit	Tx Arb Interval Timer Init Val */
+/*	TXA_ITI_VAL		32 bit	Tx Arb Interval Timer Value */
+/*	TXA_LIM_INI		32 bit	Tx Arb Limit Counter Init Val */
+/*	TXA_LIM_VAL		32 bit	Tx Arb Limit Counter Value */
+
+#define TXA_MAX_VAL	0x00ffffffUL	/* Bit 23.. 0:	Max TXA Timer/Cnt Val */
+
+/*	TXA_CTRL		 8 bit	Tx Arbiter Control Register */
+enum {
+	TXA_ENA_FSYNC	= 1<<7,	/* Enable  force of sync Tx queue */
+	TXA_DIS_FSYNC	= 1<<6,	/* Disable force of sync Tx queue */
+	TXA_ENA_ALLOC	= 1<<5,	/* Enable  alloc of free bandwidth */
+	TXA_DIS_ALLOC	= 1<<4,	/* Disable alloc of free bandwidth */
+	TXA_START_RC	= 1<<3,	/* Start sync Rate Control */
+	TXA_STOP_RC	= 1<<2,	/* Stop  sync Rate Control */
+	TXA_ENA_ARB	= 1<<1,	/* Enable  Tx Arbiter */
+	TXA_DIS_ARB	= 1<<0,	/* Disable Tx Arbiter */
+};
+
+/*
+ *	Bank 4 - 5
+ */
+/* Transmit Arbiter Registers MAC 1 and 2, use SK_REG() to access */
+enum {
+	TXA_ITI_INI	= 0x0200,/* 32 bit	Tx Arb Interval Timer Init Val*/
+	TXA_ITI_VAL	= 0x0204,/* 32 bit	Tx Arb Interval Timer Value */
+	TXA_LIM_INI	= 0x0208,/* 32 bit	Tx Arb Limit Counter Init Val */
+	TXA_LIM_VAL	= 0x020c,/* 32 bit	Tx Arb Limit Counter Value */
+	TXA_CTRL	= 0x0210,/*  8 bit	Tx Arbiter Control Register */
+	TXA_TEST	= 0x0211,/*  8 bit	Tx Arbiter Test Register */
+	TXA_STAT	= 0x0212,/*  8 bit	Tx Arbiter Status Register */
+};
+
+
+enum {
+	B6_EXT_REG	= 0x0300,/* External registers (GENESIS only) */
+	B7_CFG_SPC	= 0x0380,/* copy of the Configuration register */
+	B8_RQ1_REGS	= 0x0400,/* Receive Queue 1 */
+	B8_RQ2_REGS	= 0x0480,/* Receive Queue 2 */
+	B8_TS1_REGS	= 0x0600,/* Transmit sync queue 1 */
+	B8_TA1_REGS	= 0x0680,/* Transmit async queue 1 */
+	B8_TS2_REGS	= 0x0700,/* Transmit sync queue 2 */
+	B8_TA2_REGS	= 0x0780,/* Transmit sync queue 2 */
+	B16_RAM_REGS	= 0x0800,/* RAM Buffer Registers */
+};
+
+/* Queue Register Offsets, use Q_ADDR() to access */
+enum {
+	B8_Q_REGS = 0x0400, /* base of Queue registers */
+	Q_D	= 0x00,	/* 8*32	bit	Current Descriptor */
+	Q_DA_L	= 0x20,	/* 32 bit	Current Descriptor Address Low dWord */
+	Q_DA_H	= 0x24,	/* 32 bit	Current Descriptor Address High dWord */
+	Q_AC_L	= 0x28,	/* 32 bit	Current Address Counter Low dWord */
+	Q_AC_H	= 0x2c,	/* 32 bit	Current Address Counter High dWord */
+	Q_BC	= 0x30,	/* 32 bit	Current Byte Counter */
+	Q_CSR	= 0x34,	/* 32 bit	BMU Control/Status Register */
+	Q_F	= 0x38,	/* 32 bit	Flag Register */
+	Q_T1	= 0x3c,	/* 32 bit	Test Register 1 */
+	Q_T1_TR	= 0x3c,	/*  8 bit	Test Register 1 Transfer SM */
+	Q_T1_WR	= 0x3d,	/*  8 bit	Test Register 1 Write Descriptor SM */
+	Q_T1_RD	= 0x3e,	/*  8 bit	Test Register 1 Read Descriptor SM */
+	Q_T1_SV	= 0x3f,	/*  8 bit	Test Register 1 Supervisor SM */
+	Q_T2	= 0x40,	/* 32 bit	Test Register 2	*/
+	Q_T3	= 0x44,	/* 32 bit	Test Register 3	*/
+
+/* Yukon-2 */
+	Q_DONE	= 0x24,	/* 16 bit	Done Index 		(Yukon-2 only) */
+	Q_WM	= 0x40,	/* 16 bit	FIFO Watermark */
+	Q_AL	= 0x42,	/*  8 bit	FIFO Alignment */
+	Q_RSP	= 0x44,	/* 16 bit	FIFO Read Shadow Pointer */
+	Q_RSL	= 0x46,	/*  8 bit	FIFO Read Shadow Level */
+	Q_RP	= 0x48,	/*  8 bit	FIFO Read Pointer */
+	Q_RL	= 0x4a,	/*  8 bit	FIFO Read Level */
+	Q_WP	= 0x4c,	/*  8 bit	FIFO Write Pointer */
+	Q_WSP	= 0x4d,	/*  8 bit	FIFO Write Shadow Pointer */
+	Q_WL	= 0x4e,	/*  8 bit	FIFO Write Level */
+	Q_WSL	= 0x4f,	/*  8 bit	FIFO Write Shadow Level */
+};
+#define Q_ADDR(reg, offs) (B8_Q_REGS + (reg) + (offs))
+
+/* RAM Buffer Register Offsets */
+enum {
+
+	RB_START	= 0x00,/* 32 bit	RAM Buffer Start Address */
+	RB_END	= 0x04,/* 32 bit	RAM Buffer End Address */
+	RB_WP	= 0x08,/* 32 bit	RAM Buffer Write Pointer */
+	RB_RP	= 0x0c,/* 32 bit	RAM Buffer Read Pointer */
+	RB_RX_UTPP	= 0x10,/* 32 bit	Rx Upper Threshold, Pause Packet */
+	RB_RX_LTPP	= 0x14,/* 32 bit	Rx Lower Threshold, Pause Packet */
+	RB_RX_UTHP	= 0x18,/* 32 bit	Rx Upper Threshold, High Prio */
+	RB_RX_LTHP	= 0x1c,/* 32 bit	Rx Lower Threshold, High Prio */
+	/* 0x10 - 0x1f:	reserved at Tx RAM Buffer Registers */
+	RB_PC	= 0x20,/* 32 bit	RAM Buffer Packet Counter */
+	RB_LEV	= 0x24,/* 32 bit	RAM Buffer Level Register */
+	RB_CTRL	= 0x28,/* 32 bit	RAM Buffer Control Register */
+	RB_TST1	= 0x29,/*  8 bit	RAM Buffer Test Register 1 */
+	RB_TST2	= 0x2a,/*  8 bit	RAM Buffer Test Register 2 */
+};
+
+/* Receive and Transmit Queues */
+enum {
+	Q_R1	= 0x0000,	/* Receive Queue 1 */
+	Q_R2	= 0x0080,	/* Receive Queue 2 */
+	Q_XS1	= 0x0200,	/* Synchronous Transmit Queue 1 */
+	Q_XA1	= 0x0280,	/* Asynchronous Transmit Queue 1 */
+	Q_XS2	= 0x0300,	/* Synchronous Transmit Queue 2 */
+	Q_XA2	= 0x0380,	/* Asynchronous Transmit Queue 2 */
+};
+
+/* Different MAC Types */
+enum {
+	SK_MAC_XMAC =	0,	/* Xaqti XMAC II */
+	SK_MAC_GMAC =	1,	/* Marvell GMAC */
+};
+
+/* Different PHY Types */
+enum {
+	SK_PHY_XMAC	= 0,/* integrated in XMAC II */
+	SK_PHY_BCOM	= 1,/* Broadcom BCM5400 */
+	SK_PHY_LONE	= 2,/* Level One LXT1000  [not supported]*/
+	SK_PHY_NAT	= 3,/* National DP83891  [not supported] */
+	SK_PHY_MARV_COPPER= 4,/* Marvell 88E1011S */
+	SK_PHY_MARV_FIBER = 5,/* Marvell 88E1011S working on fiber */
+};
+
+/* PHY addresses (bits 12..8 of PHY address reg) */
+enum {
+	PHY_ADDR_XMAC	= 0<<8,
+	PHY_ADDR_BCOM	= 1<<8,
+
+/* GPHY address (bits 15..11 of SMI control reg) */
+	PHY_ADDR_MARV	= 0,
+};
+
+#define RB_ADDR(offs, queue) (B16_RAM_REGS + (queue) + (offs))
+
+/* Receive MAC FIFO, Receive LED, and Link_Sync regs (GENESIS only) */
+enum {
+	RX_MFF_EA	= 0x0c00,/* 32 bit	Receive MAC FIFO End Address */
+	RX_MFF_WP	= 0x0c04,/* 32 bit	Receive MAC FIFO Write Pointer */
+
+	RX_MFF_RP	= 0x0c0c,/* 32 bit	Receive MAC FIFO Read Pointer */
+	RX_MFF_PC	= 0x0c10,/* 32 bit	Receive MAC FIFO Packet Cnt */
+	RX_MFF_LEV	= 0x0c14,/* 32 bit	Receive MAC FIFO Level */
+	RX_MFF_CTRL1	= 0x0c18,/* 16 bit	Receive MAC FIFO Control Reg 1*/
+	RX_MFF_STAT_TO	= 0x0c1a,/*  8 bit	Receive MAC Status Timeout */
+	RX_MFF_TIST_TO	= 0x0c1b,/*  8 bit	Receive MAC Time Stamp Timeout */
+	RX_MFF_CTRL2	= 0x0c1c,/*  8 bit	Receive MAC FIFO Control Reg 2*/
+	RX_MFF_TST1	= 0x0c1d,/*  8 bit	Receive MAC FIFO Test Reg 1 */
+	RX_MFF_TST2	= 0x0c1e,/*  8 bit	Receive MAC FIFO Test Reg 2 */
+
+	RX_LED_INI	= 0x0c20,/* 32 bit	Receive LED Cnt Init Value */
+	RX_LED_VAL	= 0x0c24,/* 32 bit	Receive LED Cnt Current Value */
+	RX_LED_CTRL	= 0x0c28,/*  8 bit	Receive LED Cnt Control Reg */
+	RX_LED_TST	= 0x0c29,/*  8 bit	Receive LED Cnt Test Register */
+
+	LNK_SYNC_INI	= 0x0c30,/* 32 bit	Link Sync Cnt Init Value */
+	LNK_SYNC_VAL	= 0x0c34,/* 32 bit	Link Sync Cnt Current Value */
+	LNK_SYNC_CTRL	= 0x0c38,/*  8 bit	Link Sync Cnt Control Register */
+	LNK_SYNC_TST	= 0x0c39,/*  8 bit	Link Sync Cnt Test Register */
+	LNK_LED_REG	= 0x0c3c,/*  8 bit	Link LED Register */
+};
+
+/* Receive and Transmit MAC FIFO Registers (GENESIS only) */
+/*	RX_MFF_CTRL1	16 bit	Receive MAC FIFO Control Reg 1 */
+enum {
+	MFF_ENA_RDY_PAT	= 1<<13,	/* Enable  Ready Patch */
+	MFF_DIS_RDY_PAT	= 1<<12,	/* Disable Ready Patch */
+	MFF_ENA_TIM_PAT	= 1<<11,	/* Enable  Timing Patch */
+	MFF_DIS_TIM_PAT	= 1<<10,	/* Disable Timing Patch */
+	MFF_ENA_ALM_FUL	= 1<<9,	/* Enable  AlmostFull Sign */
+	MFF_DIS_ALM_FUL	= 1<<8,	/* Disable AlmostFull Sign */
+	MFF_ENA_PAUSE	= 1<<7,	/* Enable  Pause Signaling */
+	MFF_DIS_PAUSE	= 1<<6,	/* Disable Pause Signaling */
+	MFF_ENA_FLUSH	= 1<<5,	/* Enable  Frame Flushing */
+	MFF_DIS_FLUSH	= 1<<4,	/* Disable Frame Flushing */
+	MFF_ENA_TIST	= 1<<3,	/* Enable  Time Stamp Gener */
+	MFF_DIS_TIST	= 1<<2,	/* Disable Time Stamp Gener */
+	MFF_CLR_INTIST	= 1<<1,	/* Clear IRQ No Time Stamp */
+	MFF_CLR_INSTAT	= 1<<0,	/* Clear IRQ No Status */
+#define MFF_RX_CTRL_DEF MFF_ENA_TIM_PAT
+};
+
+/*	TX_MFF_CTRL1	16 bit	Transmit MAC FIFO Control Reg 1 */
+enum {
+	MFF_CLR_PERR	= 1<<15,	/* Clear Parity Error IRQ */
+								/* Bit 14:	reserved */
+	MFF_ENA_PKT_REC	= 1<<13,	/* Enable  Packet Recovery */
+	MFF_DIS_PKT_REC	= 1<<12,	/* Disable Packet Recovery */
+
+	MFF_ENA_W4E	= 1<<7,	/* Enable  Wait for Empty */
+	MFF_DIS_W4E	= 1<<6,	/* Disable Wait for Empty */
+
+	MFF_ENA_LOOPB	= 1<<3,	/* Enable  Loopback */
+	MFF_DIS_LOOPB	= 1<<2,	/* Disable Loopback */
+	MFF_CLR_MAC_RST	= 1<<1,	/* Clear XMAC Reset */
+	MFF_SET_MAC_RST	= 1<<0,	/* Set   XMAC Reset */
+};
+
+#define MFF_TX_CTRL_DEF	(MFF_ENA_PKT_REC | MFF_ENA_TIM_PAT | MFF_ENA_FLUSH)
+
+/*	RX_MFF_TST2	 	 8 bit	Receive MAC FIFO Test Register 2 */
+/*	TX_MFF_TST2	 	 8 bit	Transmit MAC FIFO Test Register 2 */
+enum {
+	MFF_WSP_T_ON	= 1<<6,	/* Tx: Write Shadow Ptr TestOn */
+	MFF_WSP_T_OFF	= 1<<5,	/* Tx: Write Shadow Ptr TstOff */
+	MFF_WSP_INC	= 1<<4,	/* Tx: Write Shadow Ptr Increment */
+	MFF_PC_DEC	= 1<<3,	/* Packet Counter Decrement */
+	MFF_PC_T_ON	= 1<<2,	/* Packet Counter Test On */
+	MFF_PC_T_OFF	= 1<<1,	/* Packet Counter Test Off */
+	MFF_PC_INC	= 1<<0,	/* Packet Counter Increment */
+};
+
+/*	RX_MFF_TST1	 	 8 bit	Receive MAC FIFO Test Register 1 */
+/*	TX_MFF_TST1	 	 8 bit	Transmit MAC FIFO Test Register 1 */
+enum {
+	MFF_WP_T_ON	= 1<<6,	/* Write Pointer Test On */
+	MFF_WP_T_OFF	= 1<<5,	/* Write Pointer Test Off */
+	MFF_WP_INC	= 1<<4,	/* Write Pointer Increm */
+
+	MFF_RP_T_ON	= 1<<2,	/* Read Pointer Test On */
+	MFF_RP_T_OFF	= 1<<1,	/* Read Pointer Test Off */
+	MFF_RP_DEC	= 1<<0,	/* Read Pointer Decrement */
+};
+
+/*	RX_MFF_CTRL2	 8 bit	Receive MAC FIFO Control Reg 2 */
+/*	TX_MFF_CTRL2	 8 bit	Transmit MAC FIFO Control Reg 2 */
+enum {
+	MFF_ENA_OP_MD	= 1<<3,	/* Enable  Operation Mode */
+	MFF_DIS_OP_MD	= 1<<2,	/* Disable Operation Mode */
+	MFF_RST_CLR	= 1<<1,	/* Clear MAC FIFO Reset */
+	MFF_RST_SET	= 1<<0,	/* Set   MAC FIFO Reset */
+};
+
+
+/*	Link LED Counter Registers (GENESIS only) */
+
+/*	RX_LED_CTRL		 8 bit	Receive LED Cnt Control Reg */
+/*	TX_LED_CTRL		 8 bit	Transmit LED Cnt Control Reg */
+/*	LNK_SYNC_CTRL	 8 bit	Link Sync Cnt Control Register */
+enum {
+	LED_START	= 1<<2,	/* Start Timer */
+	LED_STOP	= 1<<1,	/* Stop Timer */
+	LED_STATE	= 1<<0,	/* Rx/Tx: LED State, 1=LED on */
+};
+
+/*	RX_LED_TST		 8 bit	Receive LED Cnt Test Register */
+/*	TX_LED_TST		 8 bit	Transmit LED Cnt Test Register */
+/*	LNK_SYNC_TST	 8 bit	Link Sync Cnt Test Register */
+enum {
+	LED_T_ON	= 1<<2,	/* LED Counter Test mode On */
+	LED_T_OFF	= 1<<1,	/* LED Counter Test mode Off */
+	LED_T_STEP	= 1<<0,	/* LED Counter Step */
+};
+
+/*	LNK_LED_REG	 	 8 bit	Link LED Register */
+enum {
+	LED_BLK_ON	= 1<<5,	/* Link LED Blinking On */
+	LED_BLK_OFF	= 1<<4,	/* Link LED Blinking Off */
+	LED_SYNC_ON	= 1<<3,	/* Use Sync Wire to switch LED */
+	LED_SYNC_OFF	= 1<<2,	/* Disable Sync Wire Input */
+	LED_ON	= 1<<1,	/* switch LED on */
+	LED_OFF	= 1<<0,	/* switch LED off */
+};
+
+/* Receive GMAC FIFO (YUKON and Yukon-2) */
+enum {
+	RX_GMF_EA	= 0x0c40,/* 32 bit	Rx GMAC FIFO End Address */
+	RX_GMF_AF_THR	= 0x0c44,/* 32 bit	Rx GMAC FIFO Almost Full Thresh. */
+	RX_GMF_CTRL_T	= 0x0c48,/* 32 bit	Rx GMAC FIFO Control/Test */
+	RX_GMF_FL_MSK	= 0x0c4c,/* 32 bit	Rx GMAC FIFO Flush Mask */
+	RX_GMF_FL_THR	= 0x0c50,/* 32 bit	Rx GMAC FIFO Flush Threshold */
+	RX_GMF_TR_THR	= 0x0c54,/* 32 bit	Rx Truncation Threshold (Yukon-2) */
+
+	RX_GMF_VLAN	= 0x0c5c,/* 32 bit	Rx VLAN Type Register (Yukon-2) */
+	RX_GMF_WP	= 0x0c60,/* 32 bit	Rx GMAC FIFO Write Pointer */
+
+	RX_GMF_WLEV	= 0x0c68,/* 32 bit	Rx GMAC FIFO Write Level */
+
+	RX_GMF_RP	= 0x0c70,/* 32 bit	Rx GMAC FIFO Read Pointer */
+
+	RX_GMF_RLEV	= 0x0c78,/* 32 bit	Rx GMAC FIFO Read Level */
+};
+
+
+/*	TXA_TEST		 8 bit	Tx Arbiter Test Register */
+enum {
+	TXA_INT_T_ON	= 1<<5,	/* Tx Arb Interval Timer Test On */
+	TXA_INT_T_OFF	= 1<<4,	/* Tx Arb Interval Timer Test Off */
+	TXA_INT_T_STEP	= 1<<3,	/* Tx Arb Interval Timer Step */
+	TXA_LIM_T_ON	= 1<<2,	/* Tx Arb Limit Timer Test On */
+	TXA_LIM_T_OFF	= 1<<1,	/* Tx Arb Limit Timer Test Off */
+	TXA_LIM_T_STEP	= 1<<0,	/* Tx Arb Limit Timer Step */
+};
+
+/*	TXA_STAT		 8 bit	Tx Arbiter Status Register */
+enum {
+	TXA_PRIO_XS	= 1<<0,	/* sync queue has prio to send */
+};
+
+
+/*	Q_BC			32 bit	Current Byte Counter */
+
+/* BMU Control Status Registers */
+/*	B0_R1_CSR		32 bit	BMU Ctrl/Stat Rx Queue 1 */
+/*	B0_R2_CSR		32 bit	BMU Ctrl/Stat Rx Queue 2 */
+/*	B0_XA1_CSR		32 bit	BMU Ctrl/Stat Sync Tx Queue 1 */
+/*	B0_XS1_CSR		32 bit	BMU Ctrl/Stat Async Tx Queue 1 */
+/*	B0_XA2_CSR		32 bit	BMU Ctrl/Stat Sync Tx Queue 2 */
+/*	B0_XS2_CSR		32 bit	BMU Ctrl/Stat Async Tx Queue 2 */
+/*	Q_CSR			32 bit	BMU Control/Status Register */
+
+enum {
+	CSR_SV_IDLE	= 1<<24,	/* BMU SM Idle */
+
+	CSR_DESC_CLR	= 1<<21,	/* Clear Reset for Descr */
+	CSR_DESC_SET	= 1<<20,	/* Set   Reset for Descr */
+	CSR_FIFO_CLR	= 1<<19,	/* Clear Reset for FIFO */
+	CSR_FIFO_SET	= 1<<18,	/* Set   Reset for FIFO */
+	CSR_HPI_RUN	= 1<<17,	/* Release HPI SM */
+	CSR_HPI_RST	= 1<<16,	/* Reset   HPI SM to Idle */
+	CSR_SV_RUN	= 1<<15,	/* Release Supervisor SM */
+	CSR_SV_RST	= 1<<14,	/* Reset   Supervisor SM */
+	CSR_DREAD_RUN	= 1<<13,	/* Release Descr Read SM */
+	CSR_DREAD_RST	= 1<<12,	/* Reset   Descr Read SM */
+	CSR_DWRITE_RUN	= 1<<11,	/* Release Descr Write SM */
+	CSR_DWRITE_RST	= 1<<10,	/* Reset   Descr Write SM */
+	CSR_TRANS_RUN	= 1<<9,		/* Release Transfer SM */
+	CSR_TRANS_RST	= 1<<8,		/* Reset   Transfer SM */
+	CSR_ENA_POL	= 1<<7,		/* Enable  Descr Polling */
+	CSR_DIS_POL	= 1<<6,		/* Disable Descr Polling */
+	CSR_STOP	= 1<<5,		/* Stop  Rx/Tx Queue */
+	CSR_START	= 1<<4,		/* Start Rx/Tx Queue */
+	CSR_IRQ_CL_P	= 1<<3,		/* (Rx)	Clear Parity IRQ */
+	CSR_IRQ_CL_B	= 1<<2,		/* Clear EOB IRQ */
+	CSR_IRQ_CL_F	= 1<<1,		/* Clear EOF IRQ */
+	CSR_IRQ_CL_C	= 1<<0,		/* Clear ERR IRQ */
+};
+
+#define CSR_SET_RESET	(CSR_DESC_SET | CSR_FIFO_SET | CSR_HPI_RST |\
+			CSR_SV_RST | CSR_DREAD_RST | CSR_DWRITE_RST |\
+			CSR_TRANS_RST)
+#define CSR_CLR_RESET	(CSR_DESC_CLR | CSR_FIFO_CLR | CSR_HPI_RUN |\
+			CSR_SV_RUN | CSR_DREAD_RUN | CSR_DWRITE_RUN |\
+			CSR_TRANS_RUN)
+
+/*	Q_F				32 bit	Flag Register */
+enum {
+	F_ALM_FULL	= 1<<27,	/* Rx FIFO: almost full */
+	F_EMPTY		= 1<<27,	/* Tx FIFO: empty flag */
+	F_FIFO_EOF	= 1<<26,	/* Tag (EOF Flag) bit in FIFO */
+	F_WM_REACHED	= 1<<25,	/* Watermark reached */
+
+	F_FIFO_LEVEL	= 0x1fL<<16,	/* Bit 23..16:	# of Qwords in FIFO */
+	F_WATER_MARK	= 0x0007ffL,	/* Bit 10.. 0:	Watermark */
+};
+
+/* RAM Buffer Register Offsets, use RB_ADDR(Queue, Offs) to access */
+/*	RB_START		32 bit	RAM Buffer Start Address */
+/*	RB_END			32 bit	RAM Buffer End Address */
+/*	RB_WP			32 bit	RAM Buffer Write Pointer */
+/*	RB_RP			32 bit	RAM Buffer Read Pointer */
+/*	RB_RX_UTPP		32 bit	Rx Upper Threshold, Pause Pack */
+/*	RB_RX_LTPP		32 bit	Rx Lower Threshold, Pause Pack */
+/*	RB_RX_UTHP		32 bit	Rx Upper Threshold, High Prio */
+/*	RB_RX_LTHP		32 bit	Rx Lower Threshold, High Prio */
+/*	RB_PC			32 bit	RAM Buffer Packet Counter */
+/*	RB_LEV			32 bit	RAM Buffer Level Register */
+
+#define RB_MSK	0x0007ffff	/* Bit 18.. 0:	RAM Buffer Pointer Bits */
+/*	RB_TST2			 8 bit	RAM Buffer Test Register 2 */
+/*	RB_TST1			 8 bit	RAM Buffer Test Register 1 */
+
+/*	RB_CTRL			 8 bit	RAM Buffer Control Register */
+enum {
+	RB_ENA_STFWD	= 1<<5,	/* Enable  Store & Forward */
+	RB_DIS_STFWD	= 1<<4,	/* Disable Store & Forward */
+	RB_ENA_OP_MD	= 1<<3,	/* Enable  Operation Mode */
+	RB_DIS_OP_MD	= 1<<2,	/* Disable Operation Mode */
+	RB_RST_CLR	= 1<<1,	/* Clear RAM Buf STM Reset */
+	RB_RST_SET	= 1<<0,	/* Set   RAM Buf STM Reset */
+};
+
+/* Transmit MAC FIFO and Transmit LED Registers (GENESIS only), */
+enum {
+	TX_MFF_EA	= 0x0d00,/* 32 bit	Transmit MAC FIFO End Address */
+	TX_MFF_WP	= 0x0d04,/* 32 bit	Transmit MAC FIFO WR Pointer */
+	TX_MFF_WSP	= 0x0d08,/* 32 bit	Transmit MAC FIFO WR Shadow Ptr */
+	TX_MFF_RP	= 0x0d0c,/* 32 bit	Transmit MAC FIFO RD Pointer */
+	TX_MFF_PC	= 0x0d10,/* 32 bit	Transmit MAC FIFO Packet Cnt */
+	TX_MFF_LEV	= 0x0d14,/* 32 bit	Transmit MAC FIFO Level */
+	TX_MFF_CTRL1	= 0x0d18,/* 16 bit	Transmit MAC FIFO Ctrl Reg 1 */
+	TX_MFF_WAF	= 0x0d1a,/*  8 bit	Transmit MAC Wait after flush */
+
+	TX_MFF_CTRL2	= 0x0d1c,/*  8 bit	Transmit MAC FIFO Ctrl Reg 2 */
+	TX_MFF_TST1	= 0x0d1d,/*  8 bit	Transmit MAC FIFO Test Reg 1 */
+	TX_MFF_TST2	= 0x0d1e,/*  8 bit	Transmit MAC FIFO Test Reg 2 */
+
+	TX_LED_INI	= 0x0d20,/* 32 bit	Transmit LED Cnt Init Value */
+	TX_LED_VAL	= 0x0d24,/* 32 bit	Transmit LED Cnt Current Val */
+	TX_LED_CTRL	= 0x0d28,/*  8 bit	Transmit LED Cnt Control Reg */
+	TX_LED_TST	= 0x0d29,/*  8 bit	Transmit LED Cnt Test Reg */
+};
+
+/* Counter and Timer constants, for a host clock of 62.5 MHz */
+#define SK_XMIT_DUR		0x002faf08UL	/*  50 ms */
+#define SK_BLK_DUR		0x01dcd650UL	/* 500 ms */
+
+#define SK_DPOLL_DEF	0x00ee6b28UL	/* 250 ms at 62.5 MHz */
+
+#define SK_DPOLL_MAX	0x00ffffffUL	/* 268 ms at 62.5 MHz */
+					/* 215 ms at 78.12 MHz */
+
+#define SK_FACT_62		100	/* is given in percent */
+#define SK_FACT_53		 85     /* on GENESIS:	53.12 MHz */
+#define SK_FACT_78		125	/* on YUKON:	78.12 MHz */
+
+
+/* Transmit GMAC FIFO (YUKON only) */
+enum {
+	TX_GMF_EA	= 0x0d40,/* 32 bit	Tx GMAC FIFO End Address */
+	TX_GMF_AE_THR	= 0x0d44,/* 32 bit	Tx GMAC FIFO Almost Empty Thresh.*/
+	TX_GMF_CTRL_T	= 0x0d48,/* 32 bit	Tx GMAC FIFO Control/Test */
+
+	TX_GMF_WP	= 0x0d60,/* 32 bit 	Tx GMAC FIFO Write Pointer */
+	TX_GMF_WSP	= 0x0d64,/* 32 bit 	Tx GMAC FIFO Write Shadow Ptr. */
+	TX_GMF_WLEV	= 0x0d68,/* 32 bit 	Tx GMAC FIFO Write Level */
+
+	TX_GMF_RP	= 0x0d70,/* 32 bit 	Tx GMAC FIFO Read Pointer */
+	TX_GMF_RSTP	= 0x0d74,/* 32 bit 	Tx GMAC FIFO Restart Pointer */
+	TX_GMF_RLEV	= 0x0d78,/* 32 bit 	Tx GMAC FIFO Read Level */
+
+	/* Descriptor Poll Timer Registers */
+	B28_DPT_INI	= 0x0e00,/* 24 bit	Descriptor Poll Timer Init Val */
+	B28_DPT_VAL	= 0x0e04,/* 24 bit	Descriptor Poll Timer Curr Val */
+	B28_DPT_CTRL	= 0x0e08,/*  8 bit	Descriptor Poll Timer Ctrl Reg */
+
+	B28_DPT_TST	= 0x0e0a,/*  8 bit	Descriptor Poll Timer Test Reg */
+
+	/* Time Stamp Timer Registers (YUKON only) */
+	GMAC_TI_ST_VAL	= 0x0e14,/* 32 bit	Time Stamp Timer Curr Val */
+	GMAC_TI_ST_CTRL	= 0x0e18,/*  8 bit	Time Stamp Timer Ctrl Reg */
+	GMAC_TI_ST_TST	= 0x0e1a,/*  8 bit	Time Stamp Timer Test Reg */
+};
+
+/* Status BMU Registers (Yukon-2 only)*/
+enum {
+	STAT_CTRL	= 0x0e80,/* 32 bit	Status BMU Control Reg */
+	STAT_LAST_IDX	= 0x0e84,/* 16 bit	Status BMU Last Index */
+	/* 0x0e85 - 0x0e86:	reserved */
+	STAT_LIST_ADDR_LO	= 0x0e88,/* 32 bit	Status List Start Addr (low) */
+	STAT_LIST_ADDR_HI	= 0x0e8c,/* 32 bit	Status List Start Addr (high) */
+	STAT_TXA1_RIDX	= 0x0e90,/* 16 bit	Status TxA1 Report Index Reg */
+	STAT_TXS1_RIDX	= 0x0e92,/* 16 bit	Status TxS1 Report Index Reg */
+	STAT_TXA2_RIDX	= 0x0e94,/* 16 bit	Status TxA2 Report Index Reg */
+	STAT_TXS2_RIDX	= 0x0e96,/* 16 bit	Status TxS2 Report Index Reg */
+	STAT_TX_IDX_TH	= 0x0e98,/* 16 bit	Status Tx Index Threshold Reg */
+	STAT_PUT_IDX	= 0x0e9c,/* 16 bit	Status Put Index Reg */
+
+/* FIFO Control/Status Registers (Yukon-2 only)*/
+	STAT_FIFO_WP	= 0x0ea0,/*  8 bit	Status FIFO Write Pointer Reg */
+	STAT_FIFO_RP	= 0x0ea4,/*  8 bit	Status FIFO Read Pointer Reg */
+	STAT_FIFO_RSP	= 0x0ea6,/*  8 bit	Status FIFO Read Shadow Ptr */
+	STAT_FIFO_LEVEL	= 0x0ea8,/*  8 bit	Status FIFO Level Reg */
+	STAT_FIFO_SHLVL	= 0x0eaa,/*  8 bit	Status FIFO Shadow Level Reg */
+	STAT_FIFO_WM	= 0x0eac,/*  8 bit	Status FIFO Watermark Reg */
+	STAT_FIFO_ISR_WM	= 0x0ead,/*  8 bit	Status FIFO ISR Watermark Reg */
+
+/* Level and ISR Timer Registers (Yukon-2 only)*/
+	STAT_LEV_TIMER_INI	= 0x0eb0,/* 32 bit	Level Timer Init. Value Reg */
+	STAT_LEV_TIMER_CNT	= 0x0eb4,/* 32 bit	Level Timer Counter Reg */
+	STAT_LEV_TIMER_CTRL	= 0x0eb8,/*  8 bit	Level Timer Control Reg */
+	STAT_LEV_TIMER_TEST	= 0x0eb9,/*  8 bit	Level Timer Test Reg */
+	STAT_TX_TIMER_INI	= 0x0ec0,/* 32 bit	Tx Timer Init. Value Reg */
+	STAT_TX_TIMER_CNT	= 0x0ec4,/* 32 bit	Tx Timer Counter Reg */
+	STAT_TX_TIMER_CTRL	= 0x0ec8,/*  8 bit	Tx Timer Control Reg */
+	STAT_TX_TIMER_TEST	= 0x0ec9,/*  8 bit	Tx Timer Test Reg */
+	STAT_ISR_TIMER_INI	= 0x0ed0,/* 32 bit	ISR Timer Init. Value Reg */
+	STAT_ISR_TIMER_CNT	= 0x0ed4,/* 32 bit	ISR Timer Counter Reg */
+	STAT_ISR_TIMER_CTRL	= 0x0ed8,/*  8 bit	ISR Timer Control Reg */
+	STAT_ISR_TIMER_TEST	= 0x0ed9,/*  8 bit	ISR Timer Test Reg */
+
+	ST_LAST_IDX_MASK	= 0x007f,/* Last Index Mask */
+	ST_TXRP_IDX_MASK	= 0x0fff,/* Tx Report Index Mask */
+	ST_TXTH_IDX_MASK	= 0x0fff,/* Tx Threshold Index Mask */
+	ST_WM_IDX_MASK	= 0x3f,/* FIFO Watermark Index Mask */
+};
+
+enum {
+	LINKLED_OFF 	     = 0x01,
+	LINKLED_ON  	     = 0x02,
+	LINKLED_LINKSYNC_OFF = 0x04,
+	LINKLED_LINKSYNC_ON  = 0x08,
+	LINKLED_BLINK_OFF    = 0x10,
+	LINKLED_BLINK_ON     = 0x20,
+};
+
+/* GMAC and GPHY Control Registers (YUKON only) */
+enum {
+	GMAC_CTRL	= 0x0f00,/* 32 bit	GMAC Control Reg */
+	GPHY_CTRL	= 0x0f04,/* 32 bit	GPHY Control Reg */
+	GMAC_IRQ_SRC	= 0x0f08,/*  8 bit	GMAC Interrupt Source Reg */
+	GMAC_IRQ_MSK	= 0x0f0c,/*  8 bit	GMAC Interrupt Mask Reg */
+	GMAC_LINK_CTRL	= 0x0f10,/* 16 bit	Link Control Reg */
+
+/* Wake-up Frame Pattern Match Control Registers (YUKON only) */
+
+	WOL_REG_OFFS	= 0x20,/* HW-Bug: Address is + 0x20 against spec. */
+
+	WOL_CTRL_STAT	= 0x0f20,/* 16 bit	WOL Control/Status Reg */
+	WOL_MATCH_CTL	= 0x0f22,/*  8 bit	WOL Match Control Reg */
+	WOL_MATCH_RES	= 0x0f23,/*  8 bit	WOL Match Result Reg */
+	WOL_MAC_ADDR	= 0x0f24,/* 32 bit	WOL MAC Address */
+	WOL_PATT_PME	= 0x0f2a,/*  8 bit	WOL PME Match Enable (Yukon-2) */
+	WOL_PATT_ASFM	= 0x0f2b,/*  8 bit	WOL ASF Match Enable (Yukon-2) */
+	WOL_PATT_RPTR	= 0x0f2c,/*  8 bit	WOL Pattern Read Pointer */
+
+/* WOL Pattern Length Registers (YUKON only) */
+
+	WOL_PATT_LEN_LO	= 0x0f30,/* 32 bit	WOL Pattern Length 3..0 */
+	WOL_PATT_LEN_HI	= 0x0f34,/* 24 bit	WOL Pattern Length 6..4 */
+
+/* WOL Pattern Counter Registers (YUKON only) */
+
+	WOL_PATT_CNT_0	= 0x0f38,/* 32 bit	WOL Pattern Counter 3..0 */
+	WOL_PATT_CNT_4	= 0x0f3c,/* 24 bit	WOL Pattern Counter 6..4 */
+};
+
+enum {
+	WOL_PATT_RAM_1	= 0x1000,/*  WOL Pattern RAM Link 1 */
+	WOL_PATT_RAM_2	= 0x1400,/*  WOL Pattern RAM Link 2 */
+};
+
+enum {
+	BASE_XMAC_1	= 0x2000,/* XMAC 1 registers */
+	BASE_GMAC_1	= 0x2800,/* GMAC 1 registers */
+	BASE_XMAC_2	= 0x3000,/* XMAC 2 registers */
+	BASE_GMAC_2	= 0x3800,/* GMAC 2 registers */
+};
+
+/*
+ * Receive Frame Status Encoding
+ */
+enum {
+	XMR_FS_LEN	= 0x3fff<<18,	/* Bit 31..18:	Rx Frame Length */
+	XMR_FS_2L_VLAN	= 1<<17, /* Bit 17:	tagged wh 2Lev VLAN ID*/
+	XMR_FS_1_VLAN	= 1<<16, /* Bit 16:	tagged wh 1ev VLAN ID*/
+	XMR_FS_BC	= 1<<15, /* Bit 15:	Broadcast Frame */
+	XMR_FS_MC	= 1<<14, /* Bit 14:	Multicast Frame */
+	XMR_FS_UC	= 1<<13, /* Bit 13:	Unicast Frame */
+
+	XMR_FS_BURST	= 1<<11, /* Bit 11:	Burst Mode */
+	XMR_FS_CEX_ERR	= 1<<10, /* Bit 10:	Carrier Ext. Error */
+	XMR_FS_802_3	= 1<<9, /* Bit  9:	802.3 Frame */
+	XMR_FS_COL_ERR	= 1<<8, /* Bit  8:	Collision Error */
+	XMR_FS_CAR_ERR	= 1<<7, /* Bit  7:	Carrier Event Error */
+	XMR_FS_LEN_ERR	= 1<<6, /* Bit  6:	In-Range Length Error */
+	XMR_FS_FRA_ERR	= 1<<5, /* Bit  5:	Framing Error */
+	XMR_FS_RUNT	= 1<<4, /* Bit  4:	Runt Frame */
+	XMR_FS_LNG_ERR	= 1<<3, /* Bit  3:	Giant (Jumbo) Frame */
+	XMR_FS_FCS_ERR	= 1<<2, /* Bit  2:	Frame Check Sequ Err */
+	XMR_FS_ERR	= 1<<1, /* Bit  1:	Frame Error */
+	XMR_FS_MCTRL	= 1<<0, /* Bit  0:	MAC Control Packet */
+
+/*
+ * XMR_FS_ERR will be set if
+ *	XMR_FS_FCS_ERR, XMR_FS_LNG_ERR, XMR_FS_RUNT,
+ *	XMR_FS_FRA_ERR, XMR_FS_LEN_ERR, or XMR_FS_CEX_ERR
+ * is set. XMR_FS_LNG_ERR and XMR_FS_LEN_ERR will issue
+ * XMR_FS_ERR unless the corresponding bit in the Receive Command
+ * Register is set.
+ */
+};
+
+/*
+,* XMAC-PHY Registers, indirect addressed over the XMAC
+ */
+enum {
+	PHY_XMAC_CTRL		= 0x00,/* 16 bit r/w	PHY Control Register */
+	PHY_XMAC_STAT		= 0x01,/* 16 bit r/w	PHY Status Register */
+	PHY_XMAC_ID0		= 0x02,/* 16 bit r/o	PHY ID0 Register */
+	PHY_XMAC_ID1		= 0x03,/* 16 bit r/o	PHY ID1 Register */
+	PHY_XMAC_AUNE_ADV	= 0x04,/* 16 bit r/w	Auto-Neg. Advertisement */
+	PHY_XMAC_AUNE_LP	= 0x05,/* 16 bit r/o	Link Partner Abi Reg */
+	PHY_XMAC_AUNE_EXP	= 0x06,/* 16 bit r/o	Auto-Neg. Expansion Reg */
+	PHY_XMAC_NEPG	= 0x07,/* 16 bit r/w	Next Page Register */
+	PHY_XMAC_NEPG_LP	= 0x08,/* 16 bit r/o	Next Page Link Partner */
+
+	PHY_XMAC_EXT_STAT	= 0x0f,/* 16 bit r/o	Ext Status Register */
+	PHY_XMAC_RES_ABI	= 0x10,/* 16 bit r/o	PHY Resolved Ability */
+};
+/*
+ * Broadcom-PHY Registers, indirect addressed over XMAC
+ */
+enum {
+	PHY_BCOM_CTRL		= 0x00,/* 16 bit r/w	PHY Control Register */
+	PHY_BCOM_STAT		= 0x01,/* 16 bit r/o	PHY Status Register */
+	PHY_BCOM_ID0		= 0x02,/* 16 bit r/o	PHY ID0 Register */
+	PHY_BCOM_ID1		= 0x03,/* 16 bit r/o	PHY ID1 Register */
+	PHY_BCOM_AUNE_ADV	= 0x04,/* 16 bit r/w	Auto-Neg. Advertisement */
+	PHY_BCOM_AUNE_LP	= 0x05,/* 16 bit r/o	Link Part Ability Reg */
+	PHY_BCOM_AUNE_EXP	= 0x06,/* 16 bit r/o	Auto-Neg. Expansion Reg */
+	PHY_BCOM_NEPG		= 0x07,/* 16 bit r/w	Next Page Register */
+	PHY_BCOM_NEPG_LP	= 0x08,/* 16 bit r/o	Next Page Link Partner */
+	/* Broadcom-specific registers */
+	PHY_BCOM_1000T_CTRL	= 0x09,/* 16 bit r/w	1000Base-T Control Reg */
+	PHY_BCOM_1000T_STAT	= 0x0a,/* 16 bit r/o	1000Base-T Status Reg */
+	PHY_BCOM_EXT_STAT	= 0x0f,/* 16 bit r/o	Extended Status Reg */
+	PHY_BCOM_P_EXT_CTRL	= 0x10,/* 16 bit r/w	PHY Extended Ctrl Reg */
+	PHY_BCOM_P_EXT_STAT	= 0x11,/* 16 bit r/o	PHY Extended Stat Reg */
+	PHY_BCOM_RE_CTR		= 0x12,/* 16 bit r/w	Receive Error Counter */
+	PHY_BCOM_FC_CTR		= 0x13,/* 16 bit r/w	False Carrier Sense Cnt */
+	PHY_BCOM_RNO_CTR	= 0x14,/* 16 bit r/w	Receiver NOT_OK Cnt */
+
+	PHY_BCOM_AUX_CTRL	= 0x18,/* 16 bit r/w	Auxiliary Control Reg */
+	PHY_BCOM_AUX_STAT	= 0x19,/* 16 bit r/o	Auxiliary Stat Summary */
+	PHY_BCOM_INT_STAT	= 0x1a,/* 16 bit r/o	Interrupt Status Reg */
+	PHY_BCOM_INT_MASK	= 0x1b,/* 16 bit r/w	Interrupt Mask Reg */
+};
+
+/*
+ * Marvel-PHY Registers, indirect addressed over GMAC
+ */
+enum {
+	PHY_MARV_CTRL		= 0x00,/* 16 bit r/w	PHY Control Register */
+	PHY_MARV_STAT		= 0x01,/* 16 bit r/o	PHY Status Register */
+	PHY_MARV_ID0		= 0x02,/* 16 bit r/o	PHY ID0 Register */
+	PHY_MARV_ID1		= 0x03,/* 16 bit r/o	PHY ID1 Register */
+	PHY_MARV_AUNE_ADV	= 0x04,/* 16 bit r/w	Auto-Neg. Advertisement */
+	PHY_MARV_AUNE_LP	= 0x05,/* 16 bit r/o	Link Part Ability Reg */
+	PHY_MARV_AUNE_EXP	= 0x06,/* 16 bit r/o	Auto-Neg. Expansion Reg */
+	PHY_MARV_NEPG		= 0x07,/* 16 bit r/w	Next Page Register */
+	PHY_MARV_NEPG_LP	= 0x08,/* 16 bit r/o	Next Page Link Partner */
+	/* Marvel-specific registers */
+	PHY_MARV_1000T_CTRL	= 0x09,/* 16 bit r/w	1000Base-T Control Reg */
+	PHY_MARV_1000T_STAT	= 0x0a,/* 16 bit r/o	1000Base-T Status Reg */
+	PHY_MARV_EXT_STAT	= 0x0f,/* 16 bit r/o	Extended Status Reg */
+	PHY_MARV_PHY_CTRL	= 0x10,/* 16 bit r/w	PHY Specific Ctrl Reg */
+	PHY_MARV_PHY_STAT	= 0x11,/* 16 bit r/o	PHY Specific Stat Reg */
+	PHY_MARV_INT_MASK	= 0x12,/* 16 bit r/w	Interrupt Mask Reg */
+	PHY_MARV_INT_STAT	= 0x13,/* 16 bit r/o	Interrupt Status Reg */
+	PHY_MARV_EXT_CTRL	= 0x14,/* 16 bit r/w	Ext. PHY Specific Ctrl */
+	PHY_MARV_RXE_CNT	= 0x15,/* 16 bit r/w	Receive Error Counter */
+	PHY_MARV_EXT_ADR	= 0x16,/* 16 bit r/w	Ext. Ad. for Cable Diag. */
+	PHY_MARV_PORT_IRQ	= 0x17,/* 16 bit r/o	Port 0 IRQ (88E1111 only) */
+	PHY_MARV_LED_CTRL	= 0x18,/* 16 bit r/w	LED Control Reg */
+	PHY_MARV_LED_OVER	= 0x19,/* 16 bit r/w	Manual LED Override Reg */
+	PHY_MARV_EXT_CTRL_2	= 0x1a,/* 16 bit r/w	Ext. PHY Specific Ctrl 2 */
+	PHY_MARV_EXT_P_STAT	= 0x1b,/* 16 bit r/w	Ext. PHY Spec. Stat Reg */
+	PHY_MARV_CABLE_DIAG	= 0x1c,/* 16 bit r/o	Cable Diagnostic Reg */
+	PHY_MARV_PAGE_ADDR	= 0x1d,/* 16 bit r/w	Extended Page Address Reg */
+	PHY_MARV_PAGE_DATA	= 0x1e,/* 16 bit r/w	Extended Page Data Reg */
+
+/* for 10/100 Fast Ethernet PHY (88E3082 only) */
+	PHY_MARV_FE_LED_PAR	= 0x16,/* 16 bit r/w	LED Parallel Select Reg. */
+	PHY_MARV_FE_LED_SER	= 0x17,/* 16 bit r/w	LED Stream Select S. LED */
+	PHY_MARV_FE_VCT_TX	= 0x1a,/* 16 bit r/w	VCT Reg. for TXP/N Pins */
+	PHY_MARV_FE_VCT_RX	= 0x1b,/* 16 bit r/o	VCT Reg. for RXP/N Pins */
+	PHY_MARV_FE_SPEC_2	= 0x1c,/* 16 bit r/w	Specific Control Reg. 2 */
+};
+
+enum {
+	PHY_CT_RESET	= 1<<15, /* Bit 15: (sc)	clear all PHY related regs */
+	PHY_CT_LOOP	= 1<<14, /* Bit 14:	enable Loopback over PHY */
+	PHY_CT_SPS_LSB	= 1<<13, /* Bit 13:	Speed select, lower bit */
+	PHY_CT_ANE	= 1<<12, /* Bit 12:	Auto-Negotiation Enabled */
+	PHY_CT_PDOWN	= 1<<11, /* Bit 11:	Power Down Mode */
+	PHY_CT_ISOL	= 1<<10, /* Bit 10:	Isolate Mode */
+	PHY_CT_RE_CFG	= 1<<9, /* Bit  9:	(sc) Restart Auto-Negotiation */
+	PHY_CT_DUP_MD	= 1<<8, /* Bit  8:	Duplex Mode */
+	PHY_CT_COL_TST	= 1<<7, /* Bit  7:	Collision Test enabled */
+	PHY_CT_SPS_MSB	= 1<<6, /* Bit  6:	Speed select, upper bit */
+};
+
+enum {
+	PHY_CT_SP1000	= PHY_CT_SPS_MSB, /* enable speed of 1000 Mbps */
+	PHY_CT_SP100	= PHY_CT_SPS_LSB, /* enable speed of  100 Mbps */
+	PHY_CT_SP10	= 0,		  /* enable speed of   10 Mbps */
+};
+
+enum {
+	PHY_ST_EXT_ST	= 1<<8, /* Bit  8:	Extended Status Present */
+
+	PHY_ST_PRE_SUP	= 1<<6, /* Bit  6:	Preamble Suppression */
+	PHY_ST_AN_OVER	= 1<<5, /* Bit  5:	Auto-Negotiation Over */
+	PHY_ST_REM_FLT	= 1<<4, /* Bit  4:	Remote Fault Condition Occured */
+	PHY_ST_AN_CAP	= 1<<3, /* Bit  3:	Auto-Negotiation Capability */
+	PHY_ST_LSYNC	= 1<<2, /* Bit  2:	Link Synchronized */
+	PHY_ST_JAB_DET	= 1<<1, /* Bit  1:	Jabber Detected */
+	PHY_ST_EXT_REG	= 1<<0, /* Bit  0:	Extended Register available */
+};
+
+enum {
+	PHY_I1_OUI_MSK	= 0x3f<<10, /* Bit 15..10:	Organization Unique ID */
+	PHY_I1_MOD_NUM	= 0x3f<<4, /* Bit  9.. 4:	Model Number */
+	PHY_I1_REV_MSK	= 0xf, /* Bit  3.. 0:	Revision Number */
+};
+
+/* different Broadcom PHY Ids */
+enum {
+	PHY_BCOM_ID1_A1	= 0x6041,
+	PHY_BCOM_ID1_B2 = 0x6043,
+	PHY_BCOM_ID1_C0	= 0x6044,
+	PHY_BCOM_ID1_C5	= 0x6047,
+};
+
+/* different Marvell PHY Ids */
+enum {
+	PHY_MARV_ID0_VAL= 0x0141, /* Marvell Unique Identifier */
+	PHY_MARV_ID1_B0	= 0x0C23, /* Yukon (PHY 88E1011) */
+	PHY_MARV_ID1_B2	= 0x0C25, /* Yukon-Plus (PHY 88E1011) */
+	PHY_MARV_ID1_C2	= 0x0CC2, /* Yukon-EC (PHY 88E1111) */
+	PHY_MARV_ID1_Y2	= 0x0C91, /* Yukon-2 (PHY 88E1112) */
+};
+
+/* Advertisement register bits */
+enum {
+	PHY_AN_NXT_PG	= 1<<15, /* Bit 15:	Request Next Page */
+	PHY_AN_ACK	= 1<<14, /* Bit 14:	(ro) Acknowledge Received */
+	PHY_AN_RF	= 1<<13, /* Bit 13:	Remote Fault Bits */
+
+	PHY_AN_PAUSE_ASYM = 1<<11,/* Bit 11:	Try for asymmetric */
+	PHY_AN_PAUSE_CAP = 1<<10, /* Bit 10:	Try for pause */
+	PHY_AN_100BASE4	= 1<<9, /* Bit 9:	Try for 100mbps 4k packets */
+	PHY_AN_100FULL	= 1<<8, /* Bit 8:	Try for 100mbps full-duplex */
+	PHY_AN_100HALF	= 1<<7, /* Bit 7:	Try for 100mbps half-duplex */
+	PHY_AN_10FULL	= 1<<6, /* Bit 6:	Try for 10mbps full-duplex */
+	PHY_AN_10HALF	= 1<<5, /* Bit 5:	Try for 10mbps half-duplex */
+	PHY_AN_CSMA	= 1<<0, /* Bit 0:	Only selector supported */
+	PHY_AN_SEL	= 0x1f, /* Bit 4..0:	Selector Field, 00001=Ethernet*/
+	PHY_AN_FULL	= PHY_AN_100FULL | PHY_AN_10FULL | PHY_AN_CSMA,
+	PHY_AN_ALL	= PHY_AN_10HALF | PHY_AN_10FULL |
+		  	  PHY_AN_100HALF | PHY_AN_100FULL,
+};
+
+/* Xmac Specific */
+enum {
+	PHY_X_AN_NXT_PG	= 1<<15, /* Bit 15:	Request Next Page */
+	PHY_X_AN_ACK	= 1<<14, /* Bit 14:	(ro) Acknowledge Received */
+	PHY_X_AN_RFB	= 3<<12,/* Bit 13..12:	Remote Fault Bits */
+
+	PHY_X_AN_PAUSE	= 3<<7,/* Bit  8.. 7:	Pause Bits */
+	PHY_X_AN_HD	= 1<<6, /* Bit  6:	Half Duplex */
+	PHY_X_AN_FD	= 1<<5, /* Bit  5:	Full Duplex */
+};
+
+/* Pause Bits (PHY_X_AN_PAUSE and PHY_X_RS_PAUSE) encoding */
+enum {
+	PHY_X_P_NO_PAUSE	= 0<<7,/* Bit  8..7:	no Pause Mode */
+	PHY_X_P_SYM_MD	= 1<<7, /* Bit  8..7:	symmetric Pause Mode */
+	PHY_X_P_ASYM_MD	= 2<<7,/* Bit  8..7:	asymmetric Pause Mode */
+	PHY_X_P_BOTH_MD	= 3<<7,/* Bit  8..7:	both Pause Mode */
+};
+
+
+/* Broadcom-Specific */
+/*****  PHY_BCOM_1000T_CTRL	16 bit r/w	1000Base-T Control Reg *****/
+enum {
+	PHY_B_1000C_TEST	= 7<<13,/* Bit 15..13:	Test Modes */
+	PHY_B_1000C_MSE	= 1<<12, /* Bit 12:	Master/Slave Enable */
+	PHY_B_1000C_MSC	= 1<<11, /* Bit 11:	M/S Configuration */
+	PHY_B_1000C_RD	= 1<<10, /* Bit 10:	Repeater/DTE */
+	PHY_B_1000C_AFD	= 1<<9, /* Bit  9:	Advertise Full Duplex */
+	PHY_B_1000C_AHD	= 1<<8, /* Bit  8:	Advertise Half Duplex */
+};
+
+/*****  PHY_BCOM_1000T_STAT	16 bit r/o	1000Base-T Status Reg *****/
+/*****  PHY_MARV_1000T_STAT	16 bit r/o	1000Base-T Status Reg *****/
+enum {
+	PHY_B_1000S_MSF	= 1<<15, /* Bit 15:	Master/Slave Fault */
+	PHY_B_1000S_MSR	= 1<<14, /* Bit 14:	Master/Slave Result */
+	PHY_B_1000S_LRS	= 1<<13, /* Bit 13:	Local Receiver Status */
+	PHY_B_1000S_RRS	= 1<<12, /* Bit 12:	Remote Receiver Status */
+	PHY_B_1000S_LP_FD	= 1<<11, /* Bit 11:	Link Partner can FD */
+	PHY_B_1000S_LP_HD	= 1<<10, /* Bit 10:	Link Partner can HD */
+									/* Bit  9..8:	reserved */
+	PHY_B_1000S_IEC	= 0xff, /* Bit  7..0:	Idle Error Count */
+};
+
+/*****  PHY_BCOM_EXT_STAT	16 bit r/o	Extended Status Register *****/
+enum {
+	PHY_B_ES_X_FD_CAP	= 1<<15, /* Bit 15:	1000Base-X FD capable */
+	PHY_B_ES_X_HD_CAP	= 1<<14, /* Bit 14:	1000Base-X HD capable */
+	PHY_B_ES_T_FD_CAP	= 1<<13, /* Bit 13:	1000Base-T FD capable */
+	PHY_B_ES_T_HD_CAP	= 1<<12, /* Bit 12:	1000Base-T HD capable */
+};
+
+/*****  PHY_BCOM_P_EXT_CTRL	16 bit r/w	PHY Extended Control Reg *****/
+enum {
+	PHY_B_PEC_MAC_PHY	= 1<<15, /* Bit 15:	10BIT/GMI-Interface */
+	PHY_B_PEC_DIS_CROSS	= 1<<14, /* Bit 14:	Disable MDI Crossover */
+	PHY_B_PEC_TX_DIS	= 1<<13, /* Bit 13:	Tx output Disabled */
+	PHY_B_PEC_INT_DIS	= 1<<12, /* Bit 12:	Interrupts Disabled */
+	PHY_B_PEC_F_INT	= 1<<11, /* Bit 11:	Force Interrupt */
+	PHY_B_PEC_BY_45	= 1<<10, /* Bit 10:	Bypass 4B5B-Decoder */
+	PHY_B_PEC_BY_SCR	= 1<<9, /* Bit  9:	Bypass Scrambler */
+	PHY_B_PEC_BY_MLT3	= 1<<8, /* Bit  8:	Bypass MLT3 Encoder */
+	PHY_B_PEC_BY_RXA	= 1<<7, /* Bit  7:	Bypass Rx Alignm. */
+	PHY_B_PEC_RES_SCR	= 1<<6, /* Bit  6:	Reset Scrambler */
+	PHY_B_PEC_EN_LTR	= 1<<5, /* Bit  5:	Ena LED Traffic Mode */
+	PHY_B_PEC_LED_ON	= 1<<4, /* Bit  4:	Force LED's on */
+	PHY_B_PEC_LED_OFF	= 1<<3, /* Bit  3:	Force LED's off */
+	PHY_B_PEC_EX_IPG	= 1<<2, /* Bit  2:	Extend Tx IPG Mode */
+	PHY_B_PEC_3_LED	= 1<<1, /* Bit  1:	Three Link LED mode */
+	PHY_B_PEC_HIGH_LA	= 1<<0, /* Bit  0:	GMII FIFO Elasticy */
+};
+
+/*****  PHY_BCOM_P_EXT_STAT	16 bit r/o	PHY Extended Status Reg *****/
+enum {
+	PHY_B_PES_CROSS_STAT	= 1<<13, /* Bit 13:	MDI Crossover Status */
+	PHY_B_PES_INT_STAT	= 1<<12, /* Bit 12:	Interrupt Status */
+	PHY_B_PES_RRS	= 1<<11, /* Bit 11:	Remote Receiver Stat. */
+	PHY_B_PES_LRS	= 1<<10, /* Bit 10:	Local Receiver Stat. */
+	PHY_B_PES_LOCKED	= 1<<9, /* Bit  9:	Locked */
+	PHY_B_PES_LS	= 1<<8, /* Bit  8:	Link Status */
+	PHY_B_PES_RF	= 1<<7, /* Bit  7:	Remote Fault */
+	PHY_B_PES_CE_ER	= 1<<6, /* Bit  6:	Carrier Ext Error */
+	PHY_B_PES_BAD_SSD	= 1<<5, /* Bit  5:	Bad SSD */
+	PHY_B_PES_BAD_ESD	= 1<<4, /* Bit  4:	Bad ESD */
+	PHY_B_PES_RX_ER	= 1<<3, /* Bit  3:	Receive Error */
+	PHY_B_PES_TX_ER	= 1<<2, /* Bit  2:	Transmit Error */
+	PHY_B_PES_LOCK_ER	= 1<<1, /* Bit  1:	Lock Error */
+	PHY_B_PES_MLT3_ER	= 1<<0, /* Bit  0:	MLT3 code Error */
+};
+
+/*  PHY_BCOM_AUNE_ADV	16 bit r/w	Auto-Negotiation Advertisement *****/
+/*  PHY_BCOM_AUNE_LP	16 bit r/o	Link Partner Ability Reg *****/
+enum {
+	PHY_B_AN_RF	= 1<<13, /* Bit 13:	Remote Fault */
+
+	PHY_B_AN_ASP	= 1<<11, /* Bit 11:	Asymmetric Pause */
+	PHY_B_AN_PC	= 1<<10, /* Bit 10:	Pause Capable */
+};
+
+
+/*****  PHY_BCOM_FC_CTR		16 bit r/w	False Carrier Counter *****/
+enum {
+	PHY_B_FC_CTR	= 0xff, /* Bit  7..0:	False Carrier Counter */
+
+/*****  PHY_BCOM_RNO_CTR	16 bit r/w	Receive NOT_OK Counter *****/
+	PHY_B_RC_LOC_MSK	= 0xff00, /* Bit 15..8:	Local Rx NOT_OK cnt */
+	PHY_B_RC_REM_MSK	= 0x00ff, /* Bit  7..0:	Remote Rx NOT_OK cnt */
+
+/*****  PHY_BCOM_AUX_CTRL	16 bit r/w	Auxiliary Control Reg *****/
+	PHY_B_AC_L_SQE		= 1<<15, /* Bit 15:	Low Squelch */
+	PHY_B_AC_LONG_PACK	= 1<<14, /* Bit 14:	Rx Long Packets */
+	PHY_B_AC_ER_CTRL	= 3<<12,/* Bit 13..12:	Edgerate Control */
+									/* Bit 11:	reserved */
+	PHY_B_AC_TX_TST	= 1<<10, /* Bit 10:	Tx test bit, always 1 */
+									/* Bit  9.. 8:	reserved */
+	PHY_B_AC_DIS_PRF	= 1<<7, /* Bit  7:	dis part resp filter */
+									/* Bit  6:	reserved */
+	PHY_B_AC_DIS_PM	= 1<<5, /* Bit  5:	dis power management */
+									/* Bit  4:	reserved */
+	PHY_B_AC_DIAG	= 1<<3, /* Bit  3:	Diagnostic Mode */
+};
+
+/*****  PHY_BCOM_AUX_STAT	16 bit r/o	Auxiliary Status Reg *****/
+enum {
+	PHY_B_AS_AN_C	= 1<<15, /* Bit 15:	AutoNeg complete */
+	PHY_B_AS_AN_CA	= 1<<14, /* Bit 14:	AN Complete Ack */
+	PHY_B_AS_ANACK_D	= 1<<13, /* Bit 13:	AN Ack Detect */
+	PHY_B_AS_ANAB_D	= 1<<12, /* Bit 12:	AN Ability Detect */
+	PHY_B_AS_NPW	= 1<<11, /* Bit 11:	AN Next Page Wait */
+	PHY_B_AS_AN_RES_MSK	= 7<<8,/* Bit 10..8:	AN HDC */
+	PHY_B_AS_PDF	= 1<<7, /* Bit  7:	Parallel Detect. Fault */
+	PHY_B_AS_RF	= 1<<6, /* Bit  6:	Remote Fault */
+	PHY_B_AS_ANP_R	= 1<<5, /* Bit  5:	AN Page Received */
+	PHY_B_AS_LP_ANAB	= 1<<4, /* Bit  4:	LP AN Ability */
+	PHY_B_AS_LP_NPAB	= 1<<3, /* Bit  3:	LP Next Page Ability */
+	PHY_B_AS_LS	= 1<<2, /* Bit  2:	Link Status */
+	PHY_B_AS_PRR	= 1<<1, /* Bit  1:	Pause Resolution-Rx */
+	PHY_B_AS_PRT	= 1<<0, /* Bit  0:	Pause Resolution-Tx */
+};
+#define PHY_B_AS_PAUSE_MSK	(PHY_B_AS_PRR | PHY_B_AS_PRT)
+
+/*****  PHY_BCOM_INT_STAT	16 bit r/o	Interrupt Status Reg *****/
+/*****  PHY_BCOM_INT_MASK	16 bit r/w	Interrupt Mask Reg *****/
+enum {
+	PHY_B_IS_PSE	= 1<<14, /* Bit 14:	Pair Swap Error */
+	PHY_B_IS_MDXI_SC	= 1<<13, /* Bit 13:	MDIX Status Change */
+	PHY_B_IS_HCT	= 1<<12, /* Bit 12:	counter above 32k */
+	PHY_B_IS_LCT	= 1<<11, /* Bit 11:	counter above 128 */
+	PHY_B_IS_AN_PR	= 1<<10, /* Bit 10:	Page Received */
+	PHY_B_IS_NO_HDCL	= 1<<9, /* Bit  9:	No HCD Link */
+	PHY_B_IS_NO_HDC	= 1<<8, /* Bit  8:	No HCD */
+	PHY_B_IS_NEG_USHDC	= 1<<7, /* Bit  7:	Negotiated Unsup. HCD */
+	PHY_B_IS_SCR_S_ER	= 1<<6, /* Bit  6:	Scrambler Sync Error */
+	PHY_B_IS_RRS_CHANGE	= 1<<5, /* Bit  5:	Remote Rx Stat Change */
+	PHY_B_IS_LRS_CHANGE	= 1<<4, /* Bit  4:	Local Rx Stat Change */
+	PHY_B_IS_DUP_CHANGE	= 1<<3, /* Bit  3:	Duplex Mode Change */
+	PHY_B_IS_LSP_CHANGE	= 1<<2, /* Bit  2:	Link Speed Change */
+	PHY_B_IS_LST_CHANGE	= 1<<1, /* Bit  1:	Link Status Changed */
+	PHY_B_IS_CRC_ER	= 1<<0, /* Bit  0:	CRC Error */
+};
+#define PHY_B_DEF_MSK	\
+	(~(PHY_B_IS_PSE | PHY_B_IS_AN_PR | PHY_B_IS_DUP_CHANGE | \
+	    PHY_B_IS_LSP_CHANGE | PHY_B_IS_LST_CHANGE))
+
+/* Pause Bits (PHY_B_AN_ASP and PHY_B_AN_PC) encoding */
+enum {
+	PHY_B_P_NO_PAUSE	= 0<<10,/* Bit 11..10:	no Pause Mode */
+	PHY_B_P_SYM_MD	= 1<<10, /* Bit 11..10:	symmetric Pause Mode */
+	PHY_B_P_ASYM_MD	= 2<<10,/* Bit 11..10:	asymmetric Pause Mode */
+	PHY_B_P_BOTH_MD	= 3<<10,/* Bit 11..10:	both Pause Mode */
+};
+/*
+ * Resolved Duplex mode and Capabilities (Aux Status Summary Reg)
+ */
+enum {
+	PHY_B_RES_1000FD	= 7<<8,/* Bit 10..8:	1000Base-T Full Dup. */
+	PHY_B_RES_1000HD	= 6<<8,/* Bit 10..8:	1000Base-T Half Dup. */
+};
+
+/** Marvell-Specific */
+enum {
+	PHY_M_AN_NXT_PG	= 1<<15, /* Request Next Page */
+	PHY_M_AN_ACK	= 1<<14, /* (ro)	Acknowledge Received */
+	PHY_M_AN_RF	= 1<<13, /* Remote Fault */
+
+	PHY_M_AN_ASP	= 1<<11, /* Asymmetric Pause */
+	PHY_M_AN_PC	= 1<<10, /* MAC Pause implemented */
+	PHY_M_AN_100_T4	= 1<<9, /* Not cap. 100Base-T4 (always 0) */
+	PHY_M_AN_100_FD	= 1<<8, /* Advertise 100Base-TX Full Duplex */
+	PHY_M_AN_100_HD	= 1<<7, /* Advertise 100Base-TX Half Duplex */
+	PHY_M_AN_10_FD	= 1<<6, /* Advertise 10Base-TX Full Duplex */
+	PHY_M_AN_10_HD	= 1<<5, /* Advertise 10Base-TX Half Duplex */
+	PHY_M_AN_SEL_MSK =0x1f<<4,	/* Bit  4.. 0: Selector Field Mask */
+};
+
+/* special defines for FIBER (88E1011S only) */
+enum {
+	PHY_M_AN_ASP_X	= 1<<8, /* Asymmetric Pause */
+	PHY_M_AN_PC_X	= 1<<7, /* MAC Pause implemented */
+	PHY_M_AN_1000X_AHD	= 1<<6, /* Advertise 10000Base-X Half Duplex */
+	PHY_M_AN_1000X_AFD	= 1<<5, /* Advertise 10000Base-X Full Duplex */
+};
+
+/* Pause Bits (PHY_M_AN_ASP_X and PHY_M_AN_PC_X) encoding */
+enum {
+	PHY_M_P_NO_PAUSE_X	= 0<<7,/* Bit  8.. 7:	no Pause Mode */
+	PHY_M_P_SYM_MD_X	= 1<<7, /* Bit  8.. 7:	symmetric Pause Mode */
+	PHY_M_P_ASYM_MD_X	= 2<<7,/* Bit  8.. 7:	asymmetric Pause Mode */
+	PHY_M_P_BOTH_MD_X	= 3<<7,/* Bit  8.. 7:	both Pause Mode */
+};
+
+/*****  PHY_MARV_1000T_CTRL	16 bit r/w	1000Base-T Control Reg *****/
+enum {
+	PHY_M_1000C_TEST	= 7<<13,/* Bit 15..13:	Test Modes */
+	PHY_M_1000C_MSE	= 1<<12, /* Manual Master/Slave Enable */
+	PHY_M_1000C_MSC	= 1<<11, /* M/S Configuration (1=Master) */
+	PHY_M_1000C_MPD	= 1<<10, /* Multi-Port Device */
+	PHY_M_1000C_AFD	= 1<<9, /* Advertise Full Duplex */
+	PHY_M_1000C_AHD	= 1<<8, /* Advertise Half Duplex */
+};
+
+/*****  PHY_MARV_PHY_CTRL	16 bit r/w	PHY Specific Ctrl Reg *****/
+enum {
+	PHY_M_PC_TX_FFD_MSK	= 3<<14,/* Bit 15..14: Tx FIFO Depth Mask */
+	PHY_M_PC_RX_FFD_MSK	= 3<<12,/* Bit 13..12: Rx FIFO Depth Mask */
+	PHY_M_PC_ASS_CRS_TX	= 1<<11, /* Assert CRS on Transmit */
+	PHY_M_PC_FL_GOOD	= 1<<10, /* Force Link Good */
+	PHY_M_PC_EN_DET_MSK	= 3<<8,/* Bit  9.. 8: Energy Detect Mask */
+	PHY_M_PC_ENA_EXT_D	= 1<<7, /* Enable Ext. Distance (10BT) */
+	PHY_M_PC_MDIX_MSK	= 3<<5,/* Bit  6.. 5: MDI/MDIX Config. Mask */
+	PHY_M_PC_DIS_125CLK	= 1<<4, /* Disable 125 CLK */
+	PHY_M_PC_MAC_POW_UP	= 1<<3, /* MAC Power up */
+	PHY_M_PC_SQE_T_ENA	= 1<<2, /* SQE Test Enabled */
+	PHY_M_PC_POL_R_DIS	= 1<<1, /* Polarity Reversal Disabled */
+	PHY_M_PC_DIS_JABBER	= 1<<0, /* Disable Jabber */
+};
+
+enum {
+	PHY_M_PC_EN_DET		= 2<<8,	/* Energy Detect (Mode 1) */
+	PHY_M_PC_EN_DET_PLUS	= 3<<8, /* Energy Detect Plus (Mode 2) */
+};
+
+#define PHY_M_PC_MDI_XMODE(x)	(((x)<<5) & PHY_M_PC_MDIX_MSK)
+
+enum {
+	PHY_M_PC_MAN_MDI	= 0, /* 00 = Manual MDI configuration */
+	PHY_M_PC_MAN_MDIX	= 1, /* 01 = Manual MDIX configuration */
+	PHY_M_PC_ENA_AUTO	= 3, /* 11 = Enable Automatic Crossover */
+};
+
+/* for 10/100 Fast Ethernet PHY (88E3082 only) */
+enum {
+	PHY_M_PC_ENA_DTE_DT	= 1<<15, /* Enable Data Terminal Equ. (DTE) Detect */
+	PHY_M_PC_ENA_ENE_DT	= 1<<14, /* Enable Energy Detect (sense & pulse) */
+	PHY_M_PC_DIS_NLP_CK	= 1<<13, /* Disable Normal Link Puls (NLP) Check */
+	PHY_M_PC_ENA_LIP_NP	= 1<<12, /* Enable Link Partner Next Page Reg. */
+	PHY_M_PC_DIS_NLP_GN	= 1<<11, /* Disable Normal Link Puls Generation */
+
+	PHY_M_PC_DIS_SCRAMB	= 1<<9, /* Disable Scrambler */
+	PHY_M_PC_DIS_FEFI	= 1<<8, /* Disable Far End Fault Indic. (FEFI) */
+
+	PHY_M_PC_SH_TP_SEL	= 1<<6, /* Shielded Twisted Pair Select */
+	PHY_M_PC_RX_FD_MSK	= 3<<2,/* Bit  3.. 2: Rx FIFO Depth Mask */
+};
+
+/*****  PHY_MARV_PHY_STAT	16 bit r/o	PHY Specific Status Reg *****/
+enum {
+	PHY_M_PS_SPEED_MSK	= 3<<14, /* Bit 15..14: Speed Mask */
+	PHY_M_PS_SPEED_1000	= 1<<15, /*		10 = 1000 Mbps */
+	PHY_M_PS_SPEED_100	= 1<<14, /*		01 =  100 Mbps */
+	PHY_M_PS_SPEED_10	= 0,	 /*		00 =   10 Mbps */
+	PHY_M_PS_FULL_DUP	= 1<<13, /* Full Duplex */
+	PHY_M_PS_PAGE_REC	= 1<<12, /* Page Received */
+	PHY_M_PS_SPDUP_RES	= 1<<11, /* Speed & Duplex Resolved */
+	PHY_M_PS_LINK_UP	= 1<<10, /* Link Up */
+	PHY_M_PS_CABLE_MSK	= 7<<7,  /* Bit  9.. 7: Cable Length Mask */
+	PHY_M_PS_MDI_X_STAT	= 1<<6,  /* MDI Crossover Stat (1=MDIX) */
+	PHY_M_PS_DOWNS_STAT	= 1<<5,  /* Downshift Status (1=downsh.) */
+	PHY_M_PS_ENDET_STAT	= 1<<4,  /* Energy Detect Status (1=act) */
+	PHY_M_PS_TX_P_EN	= 1<<3,  /* Tx Pause Enabled */
+	PHY_M_PS_RX_P_EN	= 1<<2,  /* Rx Pause Enabled */
+	PHY_M_PS_POL_REV	= 1<<1,  /* Polarity Reversed */
+	PHY_M_PS_JABBER		= 1<<0,  /* Jabber */
+};
+
+#define PHY_M_PS_PAUSE_MSK	(PHY_M_PS_TX_P_EN | PHY_M_PS_RX_P_EN)
+
+/* for 10/100 Fast Ethernet PHY (88E3082 only) */
+enum {
+	PHY_M_PS_DTE_DETECT	= 1<<15, /* Data Terminal Equipment (DTE) Detected */
+	PHY_M_PS_RES_SPEED	= 1<<14, /* Resolved Speed (1=100 Mbps, 0=10 Mbps */
+};
+
+enum {
+	PHY_M_IS_AN_ERROR	= 1<<15, /* Auto-Negotiation Error */
+	PHY_M_IS_LSP_CHANGE	= 1<<14, /* Link Speed Changed */
+	PHY_M_IS_DUP_CHANGE	= 1<<13, /* Duplex Mode Changed */
+	PHY_M_IS_AN_PR		= 1<<12, /* Page Received */
+	PHY_M_IS_AN_COMPL	= 1<<11, /* Auto-Negotiation Completed */
+	PHY_M_IS_LST_CHANGE	= 1<<10, /* Link Status Changed */
+	PHY_M_IS_SYMB_ERROR	= 1<<9, /* Symbol Error */
+	PHY_M_IS_FALSE_CARR	= 1<<8, /* False Carrier */
+	PHY_M_IS_FIFO_ERROR	= 1<<7, /* FIFO Overflow/Underrun Error */
+	PHY_M_IS_MDI_CHANGE	= 1<<6, /* MDI Crossover Changed */
+	PHY_M_IS_DOWNSH_DET	= 1<<5, /* Downshift Detected */
+	PHY_M_IS_END_CHANGE	= 1<<4, /* Energy Detect Changed */
+
+	PHY_M_IS_DTE_CHANGE	= 1<<2, /* DTE Power Det. Status Changed */
+	PHY_M_IS_POL_CHANGE	= 1<<1, /* Polarity Changed */
+	PHY_M_IS_JABBER		= 1<<0, /* Jabber */
+
+	PHY_M_IS_DEF_MSK	= PHY_M_IS_AN_ERROR | PHY_M_IS_LSP_CHANGE |
+				  PHY_M_IS_LST_CHANGE | PHY_M_IS_FIFO_ERROR,
+
+	PHY_M_IS_AN_MSK		= PHY_M_IS_AN_ERROR | PHY_M_IS_AN_COMPL,
+};
+
+/*****  PHY_MARV_EXT_CTRL	16 bit r/w	Ext. PHY Specific Ctrl *****/
+enum {
+	PHY_M_EC_ENA_BC_EXT = 1<<15, /* Enable Block Carr. Ext. (88E1111 only) */
+	PHY_M_EC_ENA_LIN_LB = 1<<14, /* Enable Line Loopback (88E1111 only) */
+
+	PHY_M_EC_DIS_LINK_P = 1<<12, /* Disable Link Pulses (88E1111 only) */
+	PHY_M_EC_M_DSC_MSK  = 3<<10, /* Bit 11..10:	Master Downshift Counter */
+					/* (88E1011 only) */
+	PHY_M_EC_S_DSC_MSK	= 3<<8,/* Bit  9.. 8:	Slave  Downshift Counter */
+				       /* (88E1011 only) */
+	PHY_M_EC_M_DSC_MSK2	= 7<<9,/* Bit 11.. 9:	Master Downshift Counter */
+					/* (88E1111 only) */
+	PHY_M_EC_DOWN_S_ENA	= 1<<8, /* Downshift Enable (88E1111 only) */
+					/* !!! Errata in spec. (1 = disable) */
+	PHY_M_EC_RX_TIM_CT	= 1<<7, /* RGMII Rx Timing Control*/
+	PHY_M_EC_MAC_S_MSK	= 7<<4,/* Bit  6.. 4:	Def. MAC interface speed */
+	PHY_M_EC_FIB_AN_ENA	= 1<<3, /* Fiber Auto-Neg. Enable (88E1011S only) */
+	PHY_M_EC_DTE_D_ENA	= 1<<2, /* DTE Detect Enable (88E1111 only) */
+	PHY_M_EC_TX_TIM_CT	= 1<<1, /* RGMII Tx Timing Control */
+	PHY_M_EC_TRANS_DIS	= 1<<0, /* Transmitter Disable (88E1111 only) */};
+
+#define PHY_M_EC_M_DSC(x)	((x)<<10) /* 00=1x; 01=2x; 10=3x; 11=4x */
+#define PHY_M_EC_S_DSC(x)	((x)<<8) /* 00=dis; 01=1x; 10=2x; 11=3x */
+#define PHY_M_EC_MAC_S(x)	((x)<<4) /* 01X=0; 110=2.5; 111=25 (MHz) */
+
+#define PHY_M_EC_M_DSC_2(x)	((x)<<9) /* 000=1x; 001=2x; 010=3x; 011=4x */
+											/* 100=5x; 101=6x; 110=7x; 111=8x */
+enum {
+	MAC_TX_CLK_0_MHZ	= 2,
+	MAC_TX_CLK_2_5_MHZ	= 6,
+	MAC_TX_CLK_25_MHZ 	= 7,
+};
+
+/*****  PHY_MARV_LED_CTRL	16 bit r/w	LED Control Reg *****/
+enum {
+	PHY_M_LEDC_DIS_LED	= 1<<15, /* Disable LED */
+	PHY_M_LEDC_PULS_MSK	= 7<<12,/* Bit 14..12: Pulse Stretch Mask */
+	PHY_M_LEDC_F_INT	= 1<<11, /* Force Interrupt */
+	PHY_M_LEDC_BL_R_MSK	= 7<<8,/* Bit 10.. 8: Blink Rate Mask */
+	PHY_M_LEDC_DP_C_LSB	= 1<<7, /* Duplex Control (LSB, 88E1111 only) */
+	PHY_M_LEDC_TX_C_LSB	= 1<<6, /* Tx Control (LSB, 88E1111 only) */
+	PHY_M_LEDC_LK_C_MSK	= 7<<3,/* Bit  5.. 3: Link Control Mask */
+					/* (88E1111 only) */
+};
+
+enum {
+	PHY_M_LEDC_LINK_MSK	= 3<<3,/* Bit  4.. 3: Link Control Mask */
+									/* (88E1011 only) */
+	PHY_M_LEDC_DP_CTRL	= 1<<2, /* Duplex Control */
+	PHY_M_LEDC_DP_C_MSB	= 1<<2, /* Duplex Control (MSB, 88E1111 only) */
+	PHY_M_LEDC_RX_CTRL	= 1<<1, /* Rx Activity / Link */
+	PHY_M_LEDC_TX_CTRL	= 1<<0, /* Tx Activity / Link */
+	PHY_M_LEDC_TX_C_MSB	= 1<<0, /* Tx Control (MSB, 88E1111 only) */
+};
+
+#define PHY_M_LED_PULS_DUR(x)	(((x)<<12) & PHY_M_LEDC_PULS_MSK)
+
+enum {
+	PULS_NO_STR	= 0,/* no pulse stretching */
+	PULS_21MS	= 1,/* 21 ms to 42 ms */
+	PULS_42MS	= 2,/* 42 ms to 84 ms */
+	PULS_84MS	= 3,/* 84 ms to 170 ms */
+	PULS_170MS	= 4,/* 170 ms to 340 ms */
+	PULS_340MS	= 5,/* 340 ms to 670 ms */
+	PULS_670MS	= 6,/* 670 ms to 1.3 s */
+	PULS_1300MS	= 7,/* 1.3 s to 2.7 s */
+};
+
+#define PHY_M_LED_BLINK_RT(x)	(((x)<<8) & PHY_M_LEDC_BL_R_MSK)
+
+enum {
+	BLINK_42MS	= 0,/* 42 ms */
+	BLINK_84MS	= 1,/* 84 ms */
+	BLINK_170MS	= 2,/* 170 ms */
+	BLINK_340MS	= 3,/* 340 ms */
+	BLINK_670MS	= 4,/* 670 ms */
+};
+
+/*****  PHY_MARV_LED_OVER	16 bit r/w	Manual LED Override Reg *****/
+#define PHY_M_LED_MO_SGMII(x)	((x)<<14) /* Bit 15..14:  SGMII AN Timer */
+										/* Bit 13..12:	reserved */
+#define PHY_M_LED_MO_DUP(x)	((x)<<10) /* Bit 11..10:  Duplex */
+#define PHY_M_LED_MO_10(x)	((x)<<8) /* Bit  9.. 8:  Link 10 */
+#define PHY_M_LED_MO_100(x)	((x)<<6) /* Bit  7.. 6:  Link 100 */
+#define PHY_M_LED_MO_1000(x)	((x)<<4) /* Bit  5.. 4:  Link 1000 */
+#define PHY_M_LED_MO_RX(x)	((x)<<2) /* Bit  3.. 2:  Rx */
+#define PHY_M_LED_MO_TX(x)	((x)<<0) /* Bit  1.. 0:  Tx */
+
+enum {
+	MO_LED_NORM	= 0,
+	MO_LED_BLINK	= 1,
+	MO_LED_OFF	= 2,
+	MO_LED_ON	= 3,
+};
+
+/*****  PHY_MARV_EXT_CTRL_2	16 bit r/w	Ext. PHY Specific Ctrl 2 *****/
+enum {
+	PHY_M_EC2_FI_IMPED	= 1<<6, /* Fiber Input  Impedance */
+	PHY_M_EC2_FO_IMPED	= 1<<5, /* Fiber Output Impedance */
+	PHY_M_EC2_FO_M_CLK	= 1<<4, /* Fiber Mode Clock Enable */
+	PHY_M_EC2_FO_BOOST	= 1<<3, /* Fiber Output Boost */
+	PHY_M_EC2_FO_AM_MSK	= 7,/* Bit  2.. 0:	Fiber Output Amplitude */
+};
+
+/*****  PHY_MARV_EXT_P_STAT 16 bit r/w	Ext. PHY Specific Status *****/
+enum {
+	PHY_M_FC_AUTO_SEL	= 1<<15, /* Fiber/Copper Auto Sel. Dis. */
+	PHY_M_FC_AN_REG_ACC	= 1<<14, /* Fiber/Copper AN Reg. Access */
+	PHY_M_FC_RESOLUTION	= 1<<13, /* Fiber/Copper Resolution */
+	PHY_M_SER_IF_AN_BP	= 1<<12, /* Ser. IF AN Bypass Enable */
+	PHY_M_SER_IF_BP_ST	= 1<<11, /* Ser. IF AN Bypass Status */
+	PHY_M_IRQ_POLARITY	= 1<<10, /* IRQ polarity */
+	PHY_M_DIS_AUT_MED	= 1<<9, /* Disable Aut. Medium Reg. Selection */
+									/* (88E1111 only) */
+								/* Bit  9.. 4: reserved (88E1011 only) */
+	PHY_M_UNDOC1	= 1<<7, /* undocumented bit !! */
+	PHY_M_DTE_POW_STAT	= 1<<4, /* DTE Power Status (88E1111 only) */
+	PHY_M_MODE_MASK	= 0xf, /* Bit  3.. 0: copy of HWCFG MODE[3:0] */
+};
+
+/*****  PHY_MARV_CABLE_DIAG	16 bit r/o	Cable Diagnostic Reg *****/
+enum {
+	PHY_M_CABD_ENA_TEST	= 1<<15, /* Enable Test (Page 0) */
+	PHY_M_CABD_DIS_WAIT	= 1<<15, /* Disable Waiting Period (Page 1) */
+					/* (88E1111 only) */
+	PHY_M_CABD_STAT_MSK	= 3<<13, /* Bit 14..13: Status Mask */
+	PHY_M_CABD_AMPL_MSK	= 0x1f<<8,/* Bit 12.. 8: Amplitude Mask */
+					/* (88E1111 only) */
+	PHY_M_CABD_DIST_MSK	= 0xff, /* Bit  7.. 0: Distance Mask */
+};
+
+/* values for Cable Diagnostic Status (11=fail; 00=OK; 10=open; 01=short) */
+enum {
+	CABD_STAT_NORMAL= 0,
+	CABD_STAT_SHORT	= 1,
+	CABD_STAT_OPEN	= 2,
+	CABD_STAT_FAIL	= 3,
+};
+
+/* for 10/100 Fast Ethernet PHY (88E3082 only) */
+/*****  PHY_MARV_FE_LED_PAR		16 bit r/w	LED Parallel Select Reg. *****/
+									/* Bit 15..12: reserved (used internally) */
+enum {
+	PHY_M_FELP_LED2_MSK = 0xf<<8,	/* Bit 11.. 8: LED2 Mask (LINK) */
+	PHY_M_FELP_LED1_MSK = 0xf<<4,	/* Bit  7.. 4: LED1 Mask (ACT) */
+	PHY_M_FELP_LED0_MSK = 0xf, /* Bit  3.. 0: LED0 Mask (SPEED) */
+};
+
+#define PHY_M_FELP_LED2_CTRL(x)	(((x)<<8) & PHY_M_FELP_LED2_MSK)
+#define PHY_M_FELP_LED1_CTRL(x)	(((x)<<4) & PHY_M_FELP_LED1_MSK)
+#define PHY_M_FELP_LED0_CTRL(x)	(((x)<<0) & PHY_M_FELP_LED0_MSK)
+
+enum {
+	LED_PAR_CTRL_COLX	= 0x00,
+	LED_PAR_CTRL_ERROR	= 0x01,
+	LED_PAR_CTRL_DUPLEX	= 0x02,
+	LED_PAR_CTRL_DP_COL	= 0x03,
+	LED_PAR_CTRL_SPEED	= 0x04,
+	LED_PAR_CTRL_LINK	= 0x05,
+	LED_PAR_CTRL_TX		= 0x06,
+	LED_PAR_CTRL_RX		= 0x07,
+	LED_PAR_CTRL_ACT	= 0x08,
+	LED_PAR_CTRL_LNK_RX	= 0x09,
+	LED_PAR_CTRL_LNK_AC	= 0x0a,
+	LED_PAR_CTRL_ACT_BL	= 0x0b,
+	LED_PAR_CTRL_TX_BL	= 0x0c,
+	LED_PAR_CTRL_RX_BL	= 0x0d,
+	LED_PAR_CTRL_COL_BL	= 0x0e,
+	LED_PAR_CTRL_INACT	= 0x0f
+};
+
+/*****,PHY_MARV_FE_SPEC_2		16 bit r/w	Specific Control Reg. 2 *****/
+enum {
+	PHY_M_FESC_DIS_WAIT	= 1<<2, /* Disable TDR Waiting Period */
+	PHY_M_FESC_ENA_MCLK	= 1<<1, /* Enable MAC Rx Clock in sleep mode */
+	PHY_M_FESC_SEL_CL_A	= 1<<0, /* Select Class A driver (100B-TX) */
+};
+
+/* for Yukon-2 Gigabit Ethernet PHY (88E1112 only) */
+/*****  PHY_MARV_PHY_CTRL (page 2)		16 bit r/w	MAC Specific Ctrl *****/
+enum {
+	PHY_M_MAC_MD_MSK	= 7<<7, /* Bit  9.. 7: Mode Select Mask */
+	PHY_M_MAC_MD_AUTO	= 3,/* Auto Copper/1000Base-X */
+	PHY_M_MAC_MD_COPPER	= 5,/* Copper only */
+	PHY_M_MAC_MD_1000BX	= 7,/* 1000Base-X only */
+};
+#define PHY_M_MAC_MODE_SEL(x)	(((x)<<7) & PHY_M_MAC_MD_MSK)
+
+/*****  PHY_MARV_PHY_CTRL (page 3)		16 bit r/w	LED Control Reg. *****/
+enum {
+	PHY_M_LEDC_LOS_MSK	= 0xf<<12,/* Bit 15..12: LOS LED Ctrl. Mask */
+	PHY_M_LEDC_INIT_MSK	= 0xf<<8, /* Bit 11.. 8: INIT LED Ctrl. Mask */
+	PHY_M_LEDC_STA1_MSK	= 0xf<<4,/* Bit  7.. 4: STAT1 LED Ctrl. Mask */
+	PHY_M_LEDC_STA0_MSK	= 0xf, /* Bit  3.. 0: STAT0 LED Ctrl. Mask */
+};
+
+#define PHY_M_LEDC_LOS_CTRL(x)	(((x)<<12) & PHY_M_LEDC_LOS_MSK)
+#define PHY_M_LEDC_INIT_CTRL(x)	(((x)<<8) & PHY_M_LEDC_INIT_MSK)
+#define PHY_M_LEDC_STA1_CTRL(x)	(((x)<<4) & PHY_M_LEDC_STA1_MSK)
+#define PHY_M_LEDC_STA0_CTRL(x)	(((x)<<0) & PHY_M_LEDC_STA0_MSK)
+
+/* GMAC registers  */
+/* Port Registers */
+enum {
+	GM_GP_STAT	= 0x0000,	/* 16 bit r/o	General Purpose Status */
+	GM_GP_CTRL	= 0x0004,	/* 16 bit r/w	General Purpose Control */
+	GM_TX_CTRL	= 0x0008,	/* 16 bit r/w	Transmit Control Reg. */
+	GM_RX_CTRL	= 0x000c,	/* 16 bit r/w	Receive Control Reg. */
+	GM_TX_FLOW_CTRL	= 0x0010,	/* 16 bit r/w	Transmit Flow-Control */
+	GM_TX_PARAM	= 0x0014,	/* 16 bit r/w	Transmit Parameter Reg. */
+	GM_SERIAL_MODE	= 0x0018,	/* 16 bit r/w	Serial Mode Register */
+/* Source Address Registers */
+	GM_SRC_ADDR_1L	= 0x001c,	/* 16 bit r/w	Source Address 1 (low) */
+	GM_SRC_ADDR_1M	= 0x0020,	/* 16 bit r/w	Source Address 1 (middle) */
+	GM_SRC_ADDR_1H	= 0x0024,	/* 16 bit r/w	Source Address 1 (high) */
+	GM_SRC_ADDR_2L	= 0x0028,	/* 16 bit r/w	Source Address 2 (low) */
+	GM_SRC_ADDR_2M	= 0x002c,	/* 16 bit r/w	Source Address 2 (middle) */
+	GM_SRC_ADDR_2H	= 0x0030,	/* 16 bit r/w	Source Address 2 (high) */
+
+/* Multicast Address Hash Registers */
+	GM_MC_ADDR_H1	= 0x0034,	/* 16 bit r/w	Multicast Address Hash 1 */
+	GM_MC_ADDR_H2	= 0x0038,	/* 16 bit r/w	Multicast Address Hash 2 */
+	GM_MC_ADDR_H3	= 0x003c,	/* 16 bit r/w	Multicast Address Hash 3 */
+	GM_MC_ADDR_H4	= 0x0040,	/* 16 bit r/w	Multicast Address Hash 4 */
+
+/* Interrupt Source Registers */
+	GM_TX_IRQ_SRC	= 0x0044,	/* 16 bit r/o	Tx Overflow IRQ Source */
+	GM_RX_IRQ_SRC	= 0x0048,	/* 16 bit r/o	Rx Overflow IRQ Source */
+	GM_TR_IRQ_SRC	= 0x004c,	/* 16 bit r/o	Tx/Rx Over. IRQ Source */
+
+/* Interrupt Mask Registers */
+	GM_TX_IRQ_MSK	= 0x0050,	/* 16 bit r/w	Tx Overflow IRQ Mask */
+	GM_RX_IRQ_MSK	= 0x0054,	/* 16 bit r/w	Rx Overflow IRQ Mask */
+	GM_TR_IRQ_MSK	= 0x0058,	/* 16 bit r/w	Tx/Rx Over. IRQ Mask */
+
+/* Serial Management Interface (SMI) Registers */
+	GM_SMI_CTRL	= 0x0080,	/* 16 bit r/w	SMI Control Register */
+	GM_SMI_DATA	= 0x0084,	/* 16 bit r/w	SMI Data Register */
+	GM_PHY_ADDR	= 0x0088,	/* 16 bit r/w	GPHY Address Register */
+};
+
+/* MIB Counters */
+#define GM_MIB_CNT_BASE	0x0100		/* Base Address of MIB Counters */
+#define GM_MIB_CNT_SIZE	44		/* Number of MIB Counters */
+
+/*
+ * MIB Counters base address definitions (low word) -
+ * use offset 4 for access to high word	(32 bit r/o)
+ */
+enum {
+	GM_RXF_UC_OK  = GM_MIB_CNT_BASE + 0,	/* Unicast Frames Received OK */
+	GM_RXF_BC_OK	= GM_MIB_CNT_BASE + 8,	/* Broadcast Frames Received OK */
+	GM_RXF_MPAUSE	= GM_MIB_CNT_BASE + 16,	/* Pause MAC Ctrl Frames Received */
+	GM_RXF_MC_OK	= GM_MIB_CNT_BASE + 24,	/* Multicast Frames Received OK */
+	GM_RXF_FCS_ERR	= GM_MIB_CNT_BASE + 32,	/* Rx Frame Check Seq. Error */
+	/* GM_MIB_CNT_BASE + 40:	reserved */
+	GM_RXO_OK_LO	= GM_MIB_CNT_BASE + 48,	/* Octets Received OK Low */
+	GM_RXO_OK_HI	= GM_MIB_CNT_BASE + 56,	/* Octets Received OK High */
+	GM_RXO_ERR_LO	= GM_MIB_CNT_BASE + 64,	/* Octets Received Invalid Low */
+	GM_RXO_ERR_HI	= GM_MIB_CNT_BASE + 72,	/* Octets Received Invalid High */
+	GM_RXF_SHT	= GM_MIB_CNT_BASE + 80,	/* Frames <64 Byte Received OK */
+	GM_RXE_FRAG	= GM_MIB_CNT_BASE + 88,	/* Frames <64 Byte Received with FCS Err */
+	GM_RXF_64B	= GM_MIB_CNT_BASE + 96,	/* 64 Byte Rx Frame */
+	GM_RXF_127B	= GM_MIB_CNT_BASE + 104,	/* 65-127 Byte Rx Frame */
+	GM_RXF_255B	= GM_MIB_CNT_BASE + 112,	/* 128-255 Byte Rx Frame */
+	GM_RXF_511B	= GM_MIB_CNT_BASE + 120,	/* 256-511 Byte Rx Frame */
+	GM_RXF_1023B	= GM_MIB_CNT_BASE + 128,	/* 512-1023 Byte Rx Frame */
+	GM_RXF_1518B	= GM_MIB_CNT_BASE + 136,	/* 1024-1518 Byte Rx Frame */
+	GM_RXF_MAX_SZ	= GM_MIB_CNT_BASE + 144,	/* 1519-MaxSize Byte Rx Frame */
+	GM_RXF_LNG_ERR	= GM_MIB_CNT_BASE + 152,	/* Rx Frame too Long Error */
+	GM_RXF_JAB_PKT	= GM_MIB_CNT_BASE + 160,	/* Rx Jabber Packet Frame */
+	/* GM_MIB_CNT_BASE + 168:	reserved */
+	GM_RXE_FIFO_OV	= GM_MIB_CNT_BASE + 176,	/* Rx FIFO overflow Event */
+	/* GM_MIB_CNT_BASE + 184:	reserved */
+	GM_TXF_UC_OK	= GM_MIB_CNT_BASE + 192,	/* Unicast Frames Xmitted OK */
+	GM_TXF_BC_OK	= GM_MIB_CNT_BASE + 200,	/* Broadcast Frames Xmitted OK */
+	GM_TXF_MPAUSE	= GM_MIB_CNT_BASE + 208,	/* Pause MAC Ctrl Frames Xmitted */
+	GM_TXF_MC_OK	= GM_MIB_CNT_BASE + 216,	/* Multicast Frames Xmitted OK */
+	GM_TXO_OK_LO	= GM_MIB_CNT_BASE + 224,	/* Octets Transmitted OK Low */
+	GM_TXO_OK_HI	= GM_MIB_CNT_BASE + 232,	/* Octets Transmitted OK High */
+	GM_TXF_64B	= GM_MIB_CNT_BASE + 240,	/* 64 Byte Tx Frame */
+	GM_TXF_127B	= GM_MIB_CNT_BASE + 248,	/* 65-127 Byte Tx Frame */
+	GM_TXF_255B	= GM_MIB_CNT_BASE + 256,	/* 128-255 Byte Tx Frame */
+	GM_TXF_511B	= GM_MIB_CNT_BASE + 264,	/* 256-511 Byte Tx Frame */
+	GM_TXF_1023B	= GM_MIB_CNT_BASE + 272,	/* 512-1023 Byte Tx Frame */
+	GM_TXF_1518B	= GM_MIB_CNT_BASE + 280,	/* 1024-1518 Byte Tx Frame */
+	GM_TXF_MAX_SZ	= GM_MIB_CNT_BASE + 288,	/* 1519-MaxSize Byte Tx Frame */
+
+	GM_TXF_COL	= GM_MIB_CNT_BASE + 304,	/* Tx Collision */
+	GM_TXF_LAT_COL	= GM_MIB_CNT_BASE + 312,	/* Tx Late Collision */
+	GM_TXF_ABO_COL	= GM_MIB_CNT_BASE + 320,	/* Tx aborted due to Exces. Col. */
+	GM_TXF_MUL_COL	= GM_MIB_CNT_BASE + 328,	/* Tx Multiple Collision */
+	GM_TXF_SNG_COL	= GM_MIB_CNT_BASE + 336,	/* Tx Single Collision */
+	GM_TXE_FIFO_UR	= GM_MIB_CNT_BASE + 344,	/* Tx FIFO Underrun Event */
+};
+
+/* GMAC Bit Definitions */
+/*	GM_GP_STAT	16 bit r/o	General Purpose Status Register */
+enum {
+	GM_GPSR_SPEED		= 1<<15, /* Bit 15:	Port Speed (1 = 100 Mbps) */
+	GM_GPSR_DUPLEX		= 1<<14, /* Bit 14:	Duplex Mode (1 = Full) */
+	GM_GPSR_FC_TX_DIS	= 1<<13, /* Bit 13:	Tx Flow-Control Mode Disabled */
+	GM_GPSR_LINK_UP		= 1<<12, /* Bit 12:	Link Up Status */
+	GM_GPSR_PAUSE		= 1<<11, /* Bit 11:	Pause State */
+	GM_GPSR_TX_ACTIVE	= 1<<10, /* Bit 10:	Tx in Progress */
+	GM_GPSR_EXC_COL		= 1<<9,	/* Bit  9:	Excessive Collisions Occured */
+	GM_GPSR_LAT_COL		= 1<<8,	/* Bit  8:	Late Collisions Occured */
+
+	GM_GPSR_PHY_ST_CH	= 1<<5,	/* Bit  5:	PHY Status Change */
+	GM_GPSR_GIG_SPEED	= 1<<4,	/* Bit  4:	Gigabit Speed (1 = 1000 Mbps) */
+	GM_GPSR_PART_MODE	= 1<<3,	/* Bit  3:	Partition mode */
+	GM_GPSR_FC_RX_DIS	= 1<<2,	/* Bit  2:	Rx Flow-Control Mode Disabled */
+	GM_GPSR_PROM_EN		= 1<<1,	/* Bit  1:	Promiscuous Mode Enabled */
+};
+
+/*	GM_GP_CTRL	16 bit r/w	General Purpose Control Register */
+enum {
+	GM_GPCR_PROM_ENA	= 1<<14,	/* Bit 14:	Enable Promiscuous Mode */
+	GM_GPCR_FC_TX_DIS	= 1<<13, /* Bit 13:	Disable Tx Flow-Control Mode */
+	GM_GPCR_TX_ENA		= 1<<12, /* Bit 12:	Enable Transmit */
+	GM_GPCR_RX_ENA		= 1<<11, /* Bit 11:	Enable Receive */
+	GM_GPCR_BURST_ENA	= 1<<10, /* Bit 10:	Enable Burst Mode */
+	GM_GPCR_LOOP_ENA	= 1<<9,	/* Bit  9:	Enable MAC Loopback Mode */
+	GM_GPCR_PART_ENA	= 1<<8,	/* Bit  8:	Enable Partition Mode */
+	GM_GPCR_GIGS_ENA	= 1<<7,	/* Bit  7:	Gigabit Speed (1000 Mbps) */
+	GM_GPCR_FL_PASS		= 1<<6,	/* Bit  6:	Force Link Pass */
+	GM_GPCR_DUP_FULL	= 1<<5,	/* Bit  5:	Full Duplex Mode */
+	GM_GPCR_FC_RX_DIS	= 1<<4,	/* Bit  4:	Disable Rx Flow-Control Mode */
+	GM_GPCR_SPEED_100	= 1<<3,   /* Bit  3:	Port Speed 100 Mbps */
+	GM_GPCR_AU_DUP_DIS	= 1<<2,	/* Bit  2:	Disable Auto-Update Duplex */
+	GM_GPCR_AU_FCT_DIS	= 1<<1,	/* Bit  1:	Disable Auto-Update Flow-C. */
+	GM_GPCR_AU_SPD_DIS	= 1<<0,	/* Bit  0:	Disable Auto-Update Speed */
+};
+
+#define GM_GPCR_SPEED_1000	(GM_GPCR_GIGS_ENA | GM_GPCR_SPEED_100)
+#define GM_GPCR_AU_ALL_DIS	(GM_GPCR_AU_DUP_DIS | GM_GPCR_AU_FCT_DIS|GM_GPCR_AU_SPD_DIS)
+
+/*	GM_TX_CTRL			16 bit r/w	Transmit Control Register */
+enum {
+	GM_TXCR_FORCE_JAM	= 1<<15, /* Bit 15:	Force Jam / Flow-Control */
+	GM_TXCR_CRC_DIS		= 1<<14, /* Bit 14:	Disable insertion of CRC */
+	GM_TXCR_PAD_DIS		= 1<<13, /* Bit 13:	Disable padding of packets */
+	GM_TXCR_COL_THR_MSK	= 1<<10, /* Bit 12..10:	Collision Threshold */
+};
+
+#define TX_COL_THR(x)		(((x)<<10) & GM_TXCR_COL_THR_MSK)
+#define TX_COL_DEF		0x04
+
+/*	GM_RX_CTRL			16 bit r/w	Receive Control Register */
+enum {
+	GM_RXCR_UCF_ENA	= 1<<15, /* Bit 15:	Enable Unicast filtering */
+	GM_RXCR_MCF_ENA	= 1<<14, /* Bit 14:	Enable Multicast filtering */
+	GM_RXCR_CRC_DIS	= 1<<13, /* Bit 13:	Remove 4-byte CRC */
+	GM_RXCR_PASS_FC	= 1<<12, /* Bit 12:	Pass FC packets to FIFO */
+};
+
+/*	GM_TX_PARAM		16 bit r/w	Transmit Parameter Register */
+enum {
+	GM_TXPA_JAMLEN_MSK	= 0x03<<14,	/* Bit 15..14:	Jam Length */
+	GM_TXPA_JAMIPG_MSK	= 0x1f<<9,	/* Bit 13..9:	Jam IPG */
+	GM_TXPA_JAMDAT_MSK	= 0x1f<<4,	/* Bit  8..4:	IPG Jam to Data */
+
+	TX_JAM_LEN_DEF		= 0x03,
+	TX_JAM_IPG_DEF		= 0x0b,
+	TX_IPG_JAM_DEF		= 0x1c,
+};
+
+#define TX_JAM_LEN_VAL(x)	(((x)<<14) & GM_TXPA_JAMLEN_MSK)
+#define TX_JAM_IPG_VAL(x)	(((x)<<9)  & GM_TXPA_JAMIPG_MSK)
+#define TX_IPG_JAM_DATA(x)	(((x)<<4)  & GM_TXPA_JAMDAT_MSK)
+
+
+/*	GM_SERIAL_MODE			16 bit r/w	Serial Mode Register */
+enum {
+	GM_SMOD_DATABL_MSK	= 0x1f<<11, /* Bit 15..11:	Data Blinder (r/o) */
+	GM_SMOD_LIMIT_4		= 1<<10, /* Bit 10:	4 consecutive Tx trials */
+	GM_SMOD_VLAN_ENA	= 1<<9,	/* Bit  9:	Enable VLAN  (Max. Frame Len) */
+	GM_SMOD_JUMBO_ENA	= 1<<8,	/* Bit  8:	Enable Jumbo (Max. Frame Len) */
+	 GM_SMOD_IPG_MSK	= 0x1f	/* Bit 4..0:	Inter-Packet Gap (IPG) */
+};
+
+#define DATA_BLIND_VAL(x)	(((x)<<11) & GM_SMOD_DATABL_MSK)
+#define DATA_BLIND_DEF		0x04
+
+#define IPG_DATA_VAL(x)		(x & GM_SMOD_IPG_MSK)
+#define IPG_DATA_DEF		0x1e
+
+/*	GM_SMI_CTRL			16 bit r/w	SMI Control Register */
+enum {
+	GM_SMI_CT_PHY_A_MSK	= 0x1f<<11,/* Bit 15..11:	PHY Device Address */
+	GM_SMI_CT_REG_A_MSK	= 0x1f<<6,/* Bit 10.. 6:	PHY Register Address */
+	GM_SMI_CT_OP_RD		= 1<<5,	/* Bit  5:	OpCode Read (0=Write)*/
+	GM_SMI_CT_RD_VAL	= 1<<4,	/* Bit  4:	Read Valid (Read completed) */
+	GM_SMI_CT_BUSY		= 1<<3,	/* Bit  3:	Busy (Operation in progress) */
+};
+
+#define GM_SMI_CT_PHY_AD(x)	(((x)<<11) & GM_SMI_CT_PHY_A_MSK)
+#define GM_SMI_CT_REG_AD(x)	(((x)<<6) & GM_SMI_CT_REG_A_MSK)
+
+/*	GM_PHY_ADDR				16 bit r/w	GPHY Address Register */
+enum {
+	GM_PAR_MIB_CLR	= 1<<5,	/* Bit  5:	Set MIB Clear Counter Mode */
+	GM_PAR_MIB_TST	= 1<<4,	/* Bit  4:	MIB Load Counter (Test Mode) */
+};
+
+/* Receive Frame Status Encoding */
+enum {
+	GMR_FS_LEN	= 0xffff<<16, /* Bit 31..16:	Rx Frame Length */
+	GMR_FS_VLAN	= 1<<13, /* Bit 13:	VLAN Packet */
+	GMR_FS_JABBER	= 1<<12, /* Bit 12:	Jabber Packet */
+	GMR_FS_UN_SIZE	= 1<<11, /* Bit 11:	Undersize Packet */
+	GMR_FS_MC	= 1<<10, /* Bit 10:	Multicast Packet */
+	GMR_FS_BC	= 1<<9, /* Bit  9:	Broadcast Packet */
+	GMR_FS_RX_OK	= 1<<8, /* Bit  8:	Receive OK (Good Packet) */
+	GMR_FS_GOOD_FC	= 1<<7, /* Bit  7:	Good Flow-Control Packet */
+	GMR_FS_BAD_FC	= 1<<6, /* Bit  6:	Bad  Flow-Control Packet */
+	GMR_FS_MII_ERR	= 1<<5, /* Bit  5:	MII Error */
+	GMR_FS_LONG_ERR	= 1<<4, /* Bit  4:	Too Long Packet */
+	GMR_FS_FRAGMENT	= 1<<3, /* Bit  3:	Fragment */
+
+	GMR_FS_CRC_ERR	= 1<<1, /* Bit  1:	CRC Error */
+	GMR_FS_RX_FF_OV	= 1<<0, /* Bit  0:	Rx FIFO Overflow */
+
+/*
+ * GMR_FS_ANY_ERR (analogous to XMR_FS_ANY_ERR)
+ */
+	GMR_FS_ANY_ERR	= GMR_FS_CRC_ERR | GMR_FS_LONG_ERR |
+		  	  GMR_FS_MII_ERR | GMR_FS_BAD_FC | GMR_FS_GOOD_FC |
+			  GMR_FS_JABBER,
+/* Rx GMAC FIFO Flush Mask (default) */
+	RX_FF_FL_DEF_MSK = GMR_FS_CRC_ERR | GMR_FS_RX_FF_OV |GMR_FS_MII_ERR |
+			   GMR_FS_BAD_FC | GMR_FS_GOOD_FC | GMR_FS_UN_SIZE |
+			   GMR_FS_JABBER,
+};
+
+/*	RX_GMF_CTRL_T	32 bit	Rx GMAC FIFO Control/Test */
+enum {
+	GMF_WP_TST_ON	= 1<<14,	/* Write Pointer Test On */
+	GMF_WP_TST_OFF	= 1<<13,	/* Write Pointer Test Off */
+	GMF_WP_STEP	= 1<<12,	/* Write Pointer Step/Increment */
+
+	GMF_RP_TST_ON	= 1<<10,	/* Read Pointer Test On */
+	GMF_RP_TST_OFF	= 1<<9,		/* Read Pointer Test Off */
+	GMF_RP_STEP	= 1<<8,		/* Read Pointer Step/Increment */
+	GMF_RX_F_FL_ON	= 1<<7,		/* Rx FIFO Flush Mode On */
+	GMF_RX_F_FL_OFF	= 1<<6,		/* Rx FIFO Flush Mode Off */
+	GMF_CLI_RX_FO	= 1<<5,		/* Clear IRQ Rx FIFO Overrun */
+	GMF_CLI_RX_FC	= 1<<4,		/* Clear IRQ Rx Frame Complete */
+	GMF_OPER_ON	= 1<<3,		/* Operational Mode On */
+	GMF_OPER_OFF	= 1<<2,		/* Operational Mode Off */
+	GMF_RST_CLR	= 1<<1,		/* Clear GMAC FIFO Reset */
+	GMF_RST_SET	= 1<<0,		/* Set   GMAC FIFO Reset */
+
+	RX_GMF_FL_THR_DEF = 0xa,	/* flush threshold (default) */
+};
+
+
+/*	TX_GMF_CTRL_T	32 bit	Tx GMAC FIFO Control/Test */
+enum {
+	GMF_WSP_TST_ON	= 1<<18,/* Write Shadow Pointer Test On */
+	GMF_WSP_TST_OFF	= 1<<17,/* Write Shadow Pointer Test Off */
+	GMF_WSP_STEP	= 1<<16,/* Write Shadow Pointer Step/Increment */
+
+	GMF_CLI_TX_FU	= 1<<6,	/* Clear IRQ Tx FIFO Underrun */
+	GMF_CLI_TX_FC	= 1<<5,	/* Clear IRQ Tx Frame Complete */
+	GMF_CLI_TX_PE	= 1<<4,	/* Clear IRQ Tx Parity Error */
+};
+
+/*	GMAC_TI_ST_CTRL	 8 bit	Time Stamp Timer Ctrl Reg (YUKON only) */
+enum {
+	GMT_ST_START	= 1<<2,	/* Start Time Stamp Timer */
+	GMT_ST_STOP	= 1<<1,	/* Stop  Time Stamp Timer */
+	GMT_ST_CLR_IRQ	= 1<<0,	/* Clear Time Stamp Timer IRQ */
+};
+
+/*	GMAC_CTRL		32 bit	GMAC Control Reg (YUKON only) */
+enum {
+	GMC_H_BURST_ON	= 1<<7,	/* Half Duplex Burst Mode On */
+	GMC_H_BURST_OFF	= 1<<6,	/* Half Duplex Burst Mode Off */
+	GMC_F_LOOPB_ON	= 1<<5,	/* FIFO Loopback On */
+	GMC_F_LOOPB_OFF	= 1<<4,	/* FIFO Loopback Off */
+	GMC_PAUSE_ON	= 1<<3,	/* Pause On */
+	GMC_PAUSE_OFF	= 1<<2,	/* Pause Off */
+	GMC_RST_CLR	= 1<<1,	/* Clear GMAC Reset */
+	GMC_RST_SET	= 1<<0,	/* Set   GMAC Reset */
+};
+
+/*	GPHY_CTRL		32 bit	GPHY Control Reg (YUKON only) */
+enum {
+	GPC_SEL_BDT	= 1<<28, /* Select Bi-Dir. Transfer for MDC/MDIO */
+	GPC_INT_POL_HI	= 1<<27, /* IRQ Polarity is Active HIGH */
+	GPC_75_OHM	= 1<<26, /* Use 75 Ohm Termination instead of 50 */
+	GPC_DIS_FC	= 1<<25, /* Disable Automatic Fiber/Copper Detection */
+	GPC_DIS_SLEEP	= 1<<24, /* Disable Energy Detect */
+	GPC_HWCFG_M_3	= 1<<23, /* HWCFG_MODE[3] */
+	GPC_HWCFG_M_2	= 1<<22, /* HWCFG_MODE[2] */
+	GPC_HWCFG_M_1	= 1<<21, /* HWCFG_MODE[1] */
+	GPC_HWCFG_M_0	= 1<<20, /* HWCFG_MODE[0] */
+	GPC_ANEG_0	= 1<<19, /* ANEG[0] */
+	GPC_ENA_XC	= 1<<18, /* Enable MDI crossover */
+	GPC_DIS_125	= 1<<17, /* Disable 125 MHz clock */
+	GPC_ANEG_3	= 1<<16, /* ANEG[3] */
+	GPC_ANEG_2	= 1<<15, /* ANEG[2] */
+	GPC_ANEG_1	= 1<<14, /* ANEG[1] */
+	GPC_ENA_PAUSE	= 1<<13, /* Enable Pause (SYM_OR_REM) */
+	GPC_PHYADDR_4	= 1<<12, /* Bit 4 of Phy Addr */
+	GPC_PHYADDR_3	= 1<<11, /* Bit 3 of Phy Addr */
+	GPC_PHYADDR_2	= 1<<10, /* Bit 2 of Phy Addr */
+	GPC_PHYADDR_1	= 1<<9,	 /* Bit 1 of Phy Addr */
+	GPC_PHYADDR_0	= 1<<8,	 /* Bit 0 of Phy Addr */
+						/* Bits  7..2:	reserved */
+	GPC_RST_CLR	= 1<<1,	/* Clear GPHY Reset */
+	GPC_RST_SET	= 1<<0,	/* Set   GPHY Reset */
+};
+
+#define GPC_HWCFG_GMII_COP (GPC_HWCFG_M_3|GPC_HWCFG_M_2 | GPC_HWCFG_M_1 | GPC_HWCFG_M_0)
+#define GPC_HWCFG_GMII_FIB (GPC_HWCFG_M_2 | GPC_HWCFG_M_1 | GPC_HWCFG_M_0)
+#define GPC_ANEG_ADV_ALL_M  (GPC_ANEG_3 | GPC_ANEG_2 | GPC_ANEG_1 | GPC_ANEG_0)
+
+/* forced speed and duplex mode (don't mix with other ANEG bits) */
+#define GPC_FRC10MBIT_HALF	0
+#define GPC_FRC10MBIT_FULL	GPC_ANEG_0
+#define GPC_FRC100MBIT_HALF	GPC_ANEG_1
+#define GPC_FRC100MBIT_FULL	(GPC_ANEG_0 | GPC_ANEG_1)
+
+/* auto-negotiation with limited advertised speeds */
+/* mix only with master/slave settings (for copper) */
+#define GPC_ADV_1000_HALF	GPC_ANEG_2
+#define GPC_ADV_1000_FULL	GPC_ANEG_3
+#define GPC_ADV_ALL		(GPC_ANEG_2 | GPC_ANEG_3)
+
+/* master/slave settings */
+/* only for copper with 1000 Mbps */
+#define GPC_FORCE_MASTER	0
+#define GPC_FORCE_SLAVE		GPC_ANEG_0
+#define GPC_PREF_MASTER		GPC_ANEG_1
+#define GPC_PREF_SLAVE		(GPC_ANEG_1 | GPC_ANEG_0)
+
+/*	GMAC_IRQ_SRC	 8 bit	GMAC Interrupt Source Reg (YUKON only) */
+/*	GMAC_IRQ_MSK	 8 bit	GMAC Interrupt Mask   Reg (YUKON only) */
+enum {
+	GM_IS_TX_CO_OV	= 1<<5,	/* Transmit Counter Overflow IRQ */
+	GM_IS_RX_CO_OV	= 1<<4,	/* Receive Counter Overflow IRQ */
+	GM_IS_TX_FF_UR	= 1<<3,	/* Transmit FIFO Underrun */
+	GM_IS_TX_COMPL	= 1<<2,	/* Frame Transmission Complete */
+	GM_IS_RX_FF_OR	= 1<<1,	/* Receive FIFO Overrun */
+	GM_IS_RX_COMPL	= 1<<0,	/* Frame Reception Complete */
+
+#define GMAC_DEF_MSK	(GM_IS_TX_CO_OV | GM_IS_RX_CO_OV | GM_IS_TX_FF_UR)
+
+/*	GMAC_LINK_CTRL	16 bit	GMAC Link Control Reg (YUKON only) */
+						/* Bits 15.. 2:	reserved */
+	GMLC_RST_CLR	= 1<<1,	/* Clear GMAC Link Reset */
+	GMLC_RST_SET	= 1<<0,	/* Set   GMAC Link Reset */
+
+
+/*	WOL_CTRL_STAT	16 bit	WOL Control/Status Reg */
+	WOL_CTL_LINK_CHG_OCC		= 1<<15,
+	WOL_CTL_MAGIC_PKT_OCC		= 1<<14,
+	WOL_CTL_PATTERN_OCC		= 1<<13,
+	WOL_CTL_CLEAR_RESULT		= 1<<12,
+	WOL_CTL_ENA_PME_ON_LINK_CHG	= 1<<11,
+	WOL_CTL_DIS_PME_ON_LINK_CHG	= 1<<10,
+	WOL_CTL_ENA_PME_ON_MAGIC_PKT	= 1<<9,
+	WOL_CTL_DIS_PME_ON_MAGIC_PKT	= 1<<8,
+	WOL_CTL_ENA_PME_ON_PATTERN	= 1<<7,
+	WOL_CTL_DIS_PME_ON_PATTERN	= 1<<6,
+	WOL_CTL_ENA_LINK_CHG_UNIT	= 1<<5,
+	WOL_CTL_DIS_LINK_CHG_UNIT	= 1<<4,
+	WOL_CTL_ENA_MAGIC_PKT_UNIT	= 1<<3,
+	WOL_CTL_DIS_MAGIC_PKT_UNIT	= 1<<2,
+	WOL_CTL_ENA_PATTERN_UNIT	= 1<<1,
+	WOL_CTL_DIS_PATTERN_UNIT	= 1<<0,
+};
+
+#define WOL_CTL_DEFAULT				\
+	(WOL_CTL_DIS_PME_ON_LINK_CHG |	\
+	WOL_CTL_DIS_PME_ON_PATTERN |	\
+	WOL_CTL_DIS_PME_ON_MAGIC_PKT |	\
+	WOL_CTL_DIS_LINK_CHG_UNIT |		\
+	WOL_CTL_DIS_PATTERN_UNIT |		\
+	WOL_CTL_DIS_MAGIC_PKT_UNIT)
+
+/*	WOL_MATCH_CTL	 8 bit	WOL Match Control Reg */
+#define WOL_CTL_PATT_ENA(x)	(1 << (x))
+
+
+/* XMAC II registers				      */
+enum {
+	XM_MMU_CMD	= 0x0000, /* 16 bit r/w	MMU Command Register */
+	XM_POFF		= 0x0008, /* 32 bit r/w	Packet Offset Register */
+	XM_BURST	= 0x000c, /* 32 bit r/w	Burst Register for half duplex*/
+	XM_1L_VLAN_TAG	= 0x0010, /* 16 bit r/w	One Level VLAN Tag ID */
+	XM_2L_VLAN_TAG	= 0x0014, /* 16 bit r/w	Two Level VLAN Tag ID */
+	XM_TX_CMD	= 0x0020, /* 16 bit r/w	Transmit Command Register */
+	XM_TX_RT_LIM	= 0x0024, /* 16 bit r/w	Transmit Retry Limit Register */
+	XM_TX_STIME	= 0x0028, /* 16 bit r/w	Transmit Slottime Register */
+	XM_TX_IPG	= 0x002c, /* 16 bit r/w	Transmit Inter Packet Gap */
+	XM_RX_CMD	= 0x0030, /* 16 bit r/w	Receive Command Register */
+	XM_PHY_ADDR	= 0x0034, /* 16 bit r/w	PHY Address Register */
+	XM_PHY_DATA	= 0x0038, /* 16 bit r/w	PHY Data Register */
+	XM_GP_PORT	= 0x0040, /* 32 bit r/w	General Purpose Port Register */
+	XM_IMSK		= 0x0044, /* 16 bit r/w	Interrupt Mask Register */
+	XM_ISRC		= 0x0048, /* 16 bit r/o	Interrupt Status Register */
+	XM_HW_CFG	= 0x004c, /* 16 bit r/w	Hardware Config Register */
+	XM_TX_LO_WM	= 0x0060, /* 16 bit r/w	Tx FIFO Low Water Mark */
+	XM_TX_HI_WM	= 0x0062, /* 16 bit r/w	Tx FIFO High Water Mark */
+	XM_TX_THR	= 0x0064, /* 16 bit r/w	Tx Request Threshold */
+	XM_HT_THR	= 0x0066, /* 16 bit r/w	Host Request Threshold */
+	XM_PAUSE_DA	= 0x0068, /* NA reg r/w	Pause Destination Address */
+	XM_CTL_PARA	= 0x0070, /* 32 bit r/w	Control Parameter Register */
+	XM_MAC_OPCODE	= 0x0074, /* 16 bit r/w	Opcode for MAC control frames */
+	XM_MAC_PTIME	= 0x0076, /* 16 bit r/w	Pause time for MAC ctrl frames*/
+	XM_TX_STAT	= 0x0078, /* 32 bit r/o	Tx Status LIFO Register */
+
+	XM_EXM_START	= 0x0080, /* r/w	Start Address of the EXM Regs */
+#define XM_EXM(reg)	(XM_EXM_START + ((reg) << 3))
+};
+
+enum {
+	XM_SRC_CHK	= 0x0100, /* NA reg r/w	Source Check Address Register */
+	XM_SA		= 0x0108, /* NA reg r/w	Station Address Register */
+	XM_HSM		= 0x0110, /* 64 bit r/w	Hash Match Address Registers */
+	XM_RX_LO_WM	= 0x0118, /* 16 bit r/w	Receive Low Water Mark */
+	XM_RX_HI_WM	= 0x011a, /* 16 bit r/w	Receive High Water Mark */
+	XM_RX_THR	= 0x011c, /* 32 bit r/w	Receive Request Threshold */
+	XM_DEV_ID	= 0x0120, /* 32 bit r/o	Device ID Register */
+	XM_MODE		= 0x0124, /* 32 bit r/w	Mode Register */
+	XM_LSA		= 0x0128, /* NA reg r/o	Last Source Register */
+	XM_TS_READ	= 0x0130, /* 32 bit r/o	Time Stamp Read Register */
+	XM_TS_LOAD	= 0x0134, /* 32 bit r/o	Time Stamp Load Value */
+	XM_STAT_CMD	= 0x0200, /* 16 bit r/w	Statistics Command Register */
+	XM_RX_CNT_EV	= 0x0204, /* 32 bit r/o	Rx Counter Event Register */
+	XM_TX_CNT_EV	= 0x0208, /* 32 bit r/o	Tx Counter Event Register */
+	XM_RX_EV_MSK	= 0x020c, /* 32 bit r/w	Rx Counter Event Mask */
+	XM_TX_EV_MSK	= 0x0210, /* 32 bit r/w	Tx Counter Event Mask */
+	XM_TXF_OK	= 0x0280, /* 32 bit r/o	Frames Transmitted OK Conuter */
+	XM_TXO_OK_HI	= 0x0284, /* 32 bit r/o	Octets Transmitted OK High Cnt*/
+	XM_TXO_OK_LO	= 0x0288, /* 32 bit r/o	Octets Transmitted OK Low Cnt */
+	XM_TXF_BC_OK	= 0x028c, /* 32 bit r/o	Broadcast Frames Xmitted OK */
+	XM_TXF_MC_OK	= 0x0290, /* 32 bit r/o	Multicast Frames Xmitted OK */
+	XM_TXF_UC_OK	= 0x0294, /* 32 bit r/o	Unicast Frames Xmitted OK */
+	XM_TXF_LONG	= 0x0298, /* 32 bit r/o	Tx Long Frame Counter */
+	XM_TXE_BURST	= 0x029c, /* 32 bit r/o	Tx Burst Event Counter */
+	XM_TXF_MPAUSE	= 0x02a0, /* 32 bit r/o	Tx Pause MAC Ctrl Frame Cnt */
+	XM_TXF_MCTRL	= 0x02a4, /* 32 bit r/o	Tx MAC Ctrl Frame Counter */
+	XM_TXF_SNG_COL	= 0x02a8, /* 32 bit r/o	Tx Single Collision Counter */
+	XM_TXF_MUL_COL	= 0x02ac, /* 32 bit r/o	Tx Multiple Collision Counter */
+	XM_TXF_ABO_COL	= 0x02b0, /* 32 bit r/o	Tx aborted due to Exces. Col. */
+	XM_TXF_LAT_COL	= 0x02b4, /* 32 bit r/o	Tx Late Collision Counter */
+	XM_TXF_DEF	= 0x02b8, /* 32 bit r/o	Tx Deferred Frame Counter */
+	XM_TXF_EX_DEF	= 0x02bc, /* 32 bit r/o	Tx Excessive Deferall Counter */
+	XM_TXE_FIFO_UR	= 0x02c0, /* 32 bit r/o	Tx FIFO Underrun Event Cnt */
+	XM_TXE_CS_ERR	= 0x02c4, /* 32 bit r/o	Tx Carrier Sense Error Cnt */
+	XM_TXP_UTIL	= 0x02c8, /* 32 bit r/o	Tx Utilization in % */
+	XM_TXF_64B	= 0x02d0, /* 32 bit r/o	64 Byte Tx Frame Counter */
+	XM_TXF_127B	= 0x02d4, /* 32 bit r/o	65-127 Byte Tx Frame Counter */
+	XM_TXF_255B	= 0x02d8, /* 32 bit r/o	128-255 Byte Tx Frame Counter */
+	XM_TXF_511B	= 0x02dc, /* 32 bit r/o	256-511 Byte Tx Frame Counter */
+	XM_TXF_1023B	= 0x02e0, /* 32 bit r/o	512-1023 Byte Tx Frame Counter*/
+	XM_TXF_MAX_SZ	= 0x02e4, /* 32 bit r/o	1024-MaxSize Byte Tx Frame Cnt*/
+	XM_RXF_OK	= 0x0300, /* 32 bit r/o	Frames Received OK */
+	XM_RXO_OK_HI	= 0x0304, /* 32 bit r/o	Octets Received OK High Cnt */
+	XM_RXO_OK_LO	= 0x0308, /* 32 bit r/o	Octets Received OK Low Counter*/
+	XM_RXF_BC_OK	= 0x030c, /* 32 bit r/o	Broadcast Frames Received OK */
+	XM_RXF_MC_OK	= 0x0310, /* 32 bit r/o	Multicast Frames Received OK */
+	XM_RXF_UC_OK	= 0x0314, /* 32 bit r/o	Unicast Frames Received OK */
+	XM_RXF_MPAUSE	= 0x0318, /* 32 bit r/o	Rx Pause MAC Ctrl Frame Cnt */
+	XM_RXF_MCTRL	= 0x031c, /* 32 bit r/o	Rx MAC Ctrl Frame Counter */
+	XM_RXF_INV_MP	= 0x0320, /* 32 bit r/o	Rx invalid Pause Frame Cnt */
+	XM_RXF_INV_MOC	= 0x0324, /* 32 bit r/o	Rx Frames with inv. MAC Opcode*/
+	XM_RXE_BURST	= 0x0328, /* 32 bit r/o	Rx Burst Event Counter */
+	XM_RXE_FMISS	= 0x032c, /* 32 bit r/o	Rx Missed Frames Event Cnt */
+	XM_RXF_FRA_ERR	= 0x0330, /* 32 bit r/o	Rx Framing Error Counter */
+	XM_RXE_FIFO_OV	= 0x0334, /* 32 bit r/o	Rx FIFO overflow Event Cnt */
+	XM_RXF_JAB_PKT	= 0x0338, /* 32 bit r/o	Rx Jabber Packet Frame Cnt */
+	XM_RXE_CAR_ERR	= 0x033c, /* 32 bit r/o	Rx Carrier Event Error Cnt */
+	XM_RXF_LEN_ERR	= 0x0340, /* 32 bit r/o	Rx in Range Length Error */
+	XM_RXE_SYM_ERR	= 0x0344, /* 32 bit r/o	Rx Symbol Error Counter */
+	XM_RXE_SHT_ERR	= 0x0348, /* 32 bit r/o	Rx Short Event Error Cnt */
+	XM_RXE_RUNT	= 0x034c, /* 32 bit r/o	Rx Runt Event Counter */
+	XM_RXF_LNG_ERR	= 0x0350, /* 32 bit r/o	Rx Frame too Long Error Cnt */
+	XM_RXF_FCS_ERR	= 0x0354, /* 32 bit r/o	Rx Frame Check Seq. Error Cnt */
+	XM_RXF_CEX_ERR	= 0x035c, /* 32 bit r/o	Rx Carrier Ext Error Frame Cnt*/
+	XM_RXP_UTIL	= 0x0360, /* 32 bit r/o	Rx Utilization in % */
+	XM_RXF_64B	= 0x0368, /* 32 bit r/o	64 Byte Rx Frame Counter */
+	XM_RXF_127B	= 0x036c, /* 32 bit r/o	65-127 Byte Rx Frame Counter */
+	XM_RXF_255B	= 0x0370, /* 32 bit r/o	128-255 Byte Rx Frame Counter */
+	XM_RXF_511B	= 0x0374, /* 32 bit r/o	256-511 Byte Rx Frame Counter */
+	XM_RXF_1023B	= 0x0378, /* 32 bit r/o	512-1023 Byte Rx Frame Counter*/
+	XM_RXF_MAX_SZ	= 0x037c, /* 32 bit r/o	1024-MaxSize Byte Rx Frame Cnt*/
+};
+
+/*	XM_MMU_CMD	16 bit r/w	MMU Command Register */
+enum {
+	XM_MMU_PHY_RDY	= 1<<12,/* Bit 12:	PHY Read Ready */
+	XM_MMU_PHY_BUSY	= 1<<11,/* Bit 11:	PHY Busy */
+	XM_MMU_IGN_PF	= 1<<10,/* Bit 10:	Ignore Pause Frame */
+	XM_MMU_MAC_LB	= 1<<9,	/* Bit  9:	Enable MAC Loopback */
+	XM_MMU_FRC_COL	= 1<<7,	/* Bit  7:	Force Collision */
+	XM_MMU_SIM_COL	= 1<<6,	/* Bit  6:	Simulate Collision */
+	XM_MMU_NO_PRE	= 1<<5,	/* Bit  5:	No MDIO Preamble */
+	XM_MMU_GMII_FD	= 1<<4,	/* Bit  4:	GMII uses Full Duplex */
+	XM_MMU_RAT_CTRL	= 1<<3,	/* Bit  3:	Enable Rate Control */
+	XM_MMU_GMII_LOOP= 1<<2,	/* Bit  2:	PHY is in Loopback Mode */
+	XM_MMU_ENA_RX	= 1<<1,	/* Bit  1:	Enable Receiver */
+	XM_MMU_ENA_TX	= 1<<0,	/* Bit  0:	Enable Transmitter */
+};
+
+
+/*	XM_TX_CMD	16 bit r/w	Transmit Command Register */
+enum {
+	XM_TX_BK2BK	= 1<<6,	/* Bit  6:	Ignor Carrier Sense (Tx Bk2Bk)*/
+	XM_TX_ENC_BYP	= 1<<5,	/* Bit  5:	Set Encoder in Bypass Mode */
+	XM_TX_SAM_LINE	= 1<<4,	/* Bit  4: (sc)	Start utilization calculation */
+	XM_TX_NO_GIG_MD	= 1<<3,	/* Bit  3:	Disable Carrier Extension */
+	XM_TX_NO_PRE	= 1<<2,	/* Bit  2:	Disable Preamble Generation */
+	XM_TX_NO_CRC	= 1<<1,	/* Bit  1:	Disable CRC Generation */
+	XM_TX_AUTO_PAD	= 1<<0,	/* Bit  0:	Enable Automatic Padding */
+};
+
+/*	XM_TX_RT_LIM	16 bit r/w	Transmit Retry Limit Register */
+#define XM_RT_LIM_MSK	0x1f	/* Bit  4..0:	Tx Retry Limit */
+
+
+/*	XM_TX_STIME	16 bit r/w	Transmit Slottime Register */
+#define XM_STIME_MSK	0x7f	/* Bit  6..0:	Tx Slottime bits */
+
+
+/*	XM_TX_IPG	16 bit r/w	Transmit Inter Packet Gap */
+#define XM_IPG_MSK		0xff	/* Bit  7..0:	IPG value bits */
+
+
+/*	XM_RX_CMD	16 bit r/w	Receive Command Register */
+enum {
+	XM_RX_LENERR_OK	= 1<<8,	/* Bit  8	don't set Rx Err bit for */
+				/*		inrange error packets */
+	XM_RX_BIG_PK_OK	= 1<<7,	/* Bit  7	don't set Rx Err bit for */
+				/*		jumbo packets */
+	XM_RX_IPG_CAP	= 1<<6,	/* Bit  6	repl. type field with IPG */
+	XM_RX_TP_MD	= 1<<5,	/* Bit  5:	Enable transparent Mode */
+	XM_RX_STRIP_FCS	= 1<<4,	/* Bit  4:	Enable FCS Stripping */
+	XM_RX_SELF_RX	= 1<<3,	/* Bit  3: 	Enable Rx of own packets */
+	XM_RX_SAM_LINE	= 1<<2,	/* Bit  2: (sc)	Start utilization calculation */
+	XM_RX_STRIP_PAD	= 1<<1,	/* Bit  1:	Strip pad bytes of Rx frames */
+	XM_RX_DIS_CEXT	= 1<<0,	/* Bit  0:	Disable carrier ext. check */
+};
+
+
+/*	XM_GP_PORT	32 bit r/w	General Purpose Port Register */
+enum {
+	XM_GP_ANIP	= 1<<6,	/* Bit  6: (ro)	Auto-Neg. in progress */
+	XM_GP_FRC_INT	= 1<<5,	/* Bit  5: (sc)	Force Interrupt */
+	XM_GP_RES_MAC	= 1<<3,	/* Bit  3: (sc)	Reset MAC and FIFOs */
+	XM_GP_RES_STAT	= 1<<2,	/* Bit  2: (sc)	Reset the statistics module */
+	XM_GP_INP_ASS	= 1<<0,	/* Bit  0: (ro) GP Input Pin asserted */
+};
+
+
+/*	XM_IMSK		16 bit r/w	Interrupt Mask Register */
+/*	XM_ISRC		16 bit r/o	Interrupt Status Register */
+enum {
+	XM_IS_LNK_AE	= 1<<14, /* Bit 14:	Link Asynchronous Event */
+	XM_IS_TX_ABORT	= 1<<13, /* Bit 13:	Transmit Abort, late Col. etc */
+	XM_IS_FRC_INT	= 1<<12, /* Bit 12:	Force INT bit set in GP */
+	XM_IS_INP_ASS	= 1<<11,	/* Bit 11:	Input Asserted, GP bit 0 set */
+	XM_IS_LIPA_RC	= 1<<10,	/* Bit 10:	Link Partner requests config */
+	XM_IS_RX_PAGE	= 1<<9,	/* Bit  9:	Page Received */
+	XM_IS_TX_PAGE	= 1<<8,	/* Bit  8:	Next Page Loaded for Transmit */
+	XM_IS_AND	= 1<<7,	/* Bit  7:	Auto-Negotiation Done */
+	XM_IS_TSC_OV	= 1<<6,	/* Bit  6:	Time Stamp Counter Overflow */
+	XM_IS_RXC_OV	= 1<<5,	/* Bit  5:	Rx Counter Event Overflow */
+	XM_IS_TXC_OV	= 1<<4,	/* Bit  4:	Tx Counter Event Overflow */
+	XM_IS_RXF_OV	= 1<<3,	/* Bit  3:	Receive FIFO Overflow */
+	XM_IS_TXF_UR	= 1<<2,	/* Bit  2:	Transmit FIFO Underrun */
+	XM_IS_TX_COMP	= 1<<1,	/* Bit  1:	Frame Tx Complete */
+	XM_IS_RX_COMP	= 1<<0,	/* Bit  0:	Frame Rx Complete */
+};
+
+#define XM_DEF_MSK	(~(XM_IS_INP_ASS | XM_IS_LIPA_RC | XM_IS_RX_PAGE | \
+			   XM_IS_AND | XM_IS_RXC_OV | XM_IS_TXC_OV | \
+			   XM_IS_RXF_OV | XM_IS_TXF_UR))
+
+
+/*	XM_HW_CFG	16 bit r/w	Hardware Config Register */
+enum {
+	XM_HW_GEN_EOP	= 1<<3,	/* Bit  3:	generate End of Packet pulse */
+	XM_HW_COM4SIG	= 1<<2,	/* Bit  2:	use Comma Detect for Sig. Det.*/
+	XM_HW_GMII_MD	= 1<<0,	/* Bit  0:	GMII Interface selected */
+};
+
+
+/*	XM_TX_LO_WM	16 bit r/w	Tx FIFO Low Water Mark */
+/*	XM_TX_HI_WM	16 bit r/w	Tx FIFO High Water Mark */
+#define XM_TX_WM_MSK	0x01ff	/* Bit  9.. 0	Tx FIFO Watermark bits */
+
+/*	XM_TX_THR	16 bit r/w	Tx Request Threshold */
+/*	XM_HT_THR	16 bit r/w	Host Request Threshold */
+/*	XM_RX_THR	16 bit r/w	Rx Request Threshold */
+#define XM_THR_MSK		0x03ff	/* Bit 10.. 0	Rx/Tx Request Threshold bits */
+
+
+/*	XM_TX_STAT	32 bit r/o	Tx Status LIFO Register */
+enum {
+	XM_ST_VALID	= (1UL<<31),	/* Bit 31:	Status Valid */
+	XM_ST_BYTE_CNT	= (0x3fffL<<17),	/* Bit 30..17:	Tx frame Length */
+	XM_ST_RETRY_CNT	= (0x1fL<<12),	/* Bit 16..12:	Retry Count */
+	XM_ST_EX_COL	= 1<<11,	/* Bit 11:	Excessive Collisions */
+	XM_ST_EX_DEF	= 1<<10,	/* Bit 10:	Excessive Deferral */
+	XM_ST_BURST	= 1<<9,		/* Bit  9:	p. xmitted in burst md*/
+	XM_ST_DEFER	= 1<<8,		/* Bit  8:	packet was defered */
+	XM_ST_BC	= 1<<7,		/* Bit  7:	Broadcast packet */
+	XM_ST_MC	= 1<<6,		/* Bit  6:	Multicast packet */
+	XM_ST_UC	= 1<<5,		/* Bit  5:	Unicast packet */
+	XM_ST_TX_UR	= 1<<4,		/* Bit  4:	FIFO Underrun occured */
+	XM_ST_CS_ERR	= 1<<3,		/* Bit  3:	Carrier Sense Error */
+	XM_ST_LAT_COL	= 1<<2,		/* Bit  2:	Late Collision Error */
+	XM_ST_MUL_COL	= 1<<1,		/* Bit  1:	Multiple Collisions */
+	XM_ST_SGN_COL	= 1<<0,		/* Bit  0:	Single Collision */
+};
+
+/*	XM_RX_LO_WM	16 bit r/w	Receive Low Water Mark */
+/*	XM_RX_HI_WM	16 bit r/w	Receive High Water Mark */
+#define XM_RX_WM_MSK	0x03ff		/* Bit 11.. 0:	Rx FIFO Watermark bits */
+
+
+/*	XM_DEV_ID	32 bit r/o	Device ID Register */
+#define XM_DEV_OUI	(0x00ffffffUL<<8)	/* Bit 31..8:	Device OUI */
+#define XM_DEV_REV	(0x07L << 5)		/* Bit  7..5:	Chip Rev Num */
+
+
+/*	XM_MODE		32 bit r/w	Mode Register */
+enum {
+	XM_MD_ENA_REJ	= 1<<26, /* Bit 26:	Enable Frame Reject */
+	XM_MD_SPOE_E	= 1<<25, /* Bit 25:	Send Pause on Edge */
+									/* 		extern generated */
+	XM_MD_TX_REP	= 1<<24, /* Bit 24:	Transmit Repeater Mode */
+	XM_MD_SPOFF_I	= 1<<23, /* Bit 23:	Send Pause on FIFO full */
+									/*		intern generated */
+	XM_MD_LE_STW	= 1<<22, /* Bit 22:	Rx Stat Word in Little Endian */
+	XM_MD_TX_CONT	= 1<<21, /* Bit 21:	Send Continuous */
+	XM_MD_TX_PAUSE	= 1<<20, /* Bit 20: (sc)	Send Pause Frame */
+	XM_MD_ATS	= 1<<19, /* Bit 19:	Append Time Stamp */
+	XM_MD_SPOL_I	= 1<<18, /* Bit 18:	Send Pause on Low */
+									/*		intern generated */
+	XM_MD_SPOH_I	= 1<<17, /* Bit 17:	Send Pause on High */
+									/*		intern generated */
+	XM_MD_CAP	= 1<<16, /* Bit 16:	Check Address Pair */
+	XM_MD_ENA_HASH	= 1<<15, /* Bit 15:	Enable Hashing */
+	XM_MD_CSA	= 1<<14, /* Bit 14:	Check Station Address */
+	XM_MD_CAA	= 1<<13, /* Bit 13:	Check Address Array */
+	XM_MD_RX_MCTRL	= 1<<12, /* Bit 12:	Rx MAC Control Frame */
+	XM_MD_RX_RUNT	= 1<<11, /* Bit 11:	Rx Runt Frames */
+	XM_MD_RX_IRLE	= 1<<10, /* Bit 10:	Rx in Range Len Err Frame */
+	XM_MD_RX_LONG	= 1<<9,  /* Bit  9:	Rx Long Frame */
+	XM_MD_RX_CRCE	= 1<<8,  /* Bit  8:	Rx CRC Error Frame */
+	XM_MD_RX_ERR	= 1<<7,  /* Bit  7:	Rx Error Frame */
+	XM_MD_DIS_UC	= 1<<6,  /* Bit  6:	Disable Rx Unicast */
+	XM_MD_DIS_MC	= 1<<5,  /* Bit  5:	Disable Rx Multicast */
+	XM_MD_DIS_BC	= 1<<4,  /* Bit  4:	Disable Rx Broadcast */
+	XM_MD_ENA_PROM	= 1<<3,  /* Bit  3:	Enable Promiscuous */
+	XM_MD_ENA_BE	= 1<<2,  /* Bit  2:	Enable Big Endian */
+	XM_MD_FTF	= 1<<1,  /* Bit  1: (sc)	Flush Tx FIFO */
+	XM_MD_FRF	= 1<<0,  /* Bit  0: (sc)	Flush Rx FIFO */
+};
+
+#define XM_PAUSE_MODE	(XM_MD_SPOE_E | XM_MD_SPOL_I | XM_MD_SPOH_I)
+#define XM_DEF_MODE	(XM_MD_RX_RUNT | XM_MD_RX_IRLE | XM_MD_RX_LONG |\
+			 XM_MD_RX_CRCE | XM_MD_RX_ERR | XM_MD_CSA)
+
+/*	XM_STAT_CMD	16 bit r/w	Statistics Command Register */
+enum {
+	XM_SC_SNP_RXC	= 1<<5,	/* Bit  5: (sc)	Snap Rx Counters */
+	XM_SC_SNP_TXC	= 1<<4,	/* Bit  4: (sc)	Snap Tx Counters */
+	XM_SC_CP_RXC	= 1<<3,	/* Bit  3: 	Copy Rx Counters Continuously */
+	XM_SC_CP_TXC	= 1<<2,	/* Bit  2:	Copy Tx Counters Continuously */
+	XM_SC_CLR_RXC	= 1<<1,	/* Bit  1: (sc)	Clear Rx Counters */
+	XM_SC_CLR_TXC	= 1<<0,	/* Bit  0: (sc) Clear Tx Counters */
+};
+
+
+/*	XM_RX_CNT_EV	32 bit r/o	Rx Counter Event Register */
+/*	XM_RX_EV_MSK	32 bit r/w	Rx Counter Event Mask */
+enum {
+	XMR_MAX_SZ_OV	= 1<<31, /* Bit 31:	1024-MaxSize Rx Cnt Ov*/
+	XMR_1023B_OV	= 1<<30, /* Bit 30:	512-1023Byte Rx Cnt Ov*/
+	XMR_511B_OV	= 1<<29, /* Bit 29:	256-511 Byte Rx Cnt Ov*/
+	XMR_255B_OV	= 1<<28, /* Bit 28:	128-255 Byte Rx Cnt Ov*/
+	XMR_127B_OV	= 1<<27, /* Bit 27:	65-127 Byte Rx Cnt Ov */
+	XMR_64B_OV	= 1<<26, /* Bit 26:	64 Byte Rx Cnt Ov */
+	XMR_UTIL_OV	= 1<<25, /* Bit 25:	Rx Util Cnt Overflow */
+	XMR_UTIL_UR	= 1<<24, /* Bit 24:	Rx Util Cnt Underrun */
+	XMR_CEX_ERR_OV	= 1<<23, /* Bit 23:	CEXT Err Cnt Ov */
+	XMR_FCS_ERR_OV	= 1<<21, /* Bit 21:	Rx FCS Error Cnt Ov */
+	XMR_LNG_ERR_OV	= 1<<20, /* Bit 20:	Rx too Long Err Cnt Ov*/
+	XMR_RUNT_OV	= 1<<19, /* Bit 19:	Runt Event Cnt Ov */
+	XMR_SHT_ERR_OV	= 1<<18, /* Bit 18:	Rx Short Ev Err Cnt Ov*/
+	XMR_SYM_ERR_OV	= 1<<17, /* Bit 17:	Rx Sym Err Cnt Ov */
+	XMR_CAR_ERR_OV	= 1<<15, /* Bit 15:	Rx Carr Ev Err Cnt Ov */
+	XMR_JAB_PKT_OV	= 1<<14, /* Bit 14:	Rx Jabb Packet Cnt Ov */
+	XMR_FIFO_OV	= 1<<13, /* Bit 13:	Rx FIFO Ov Ev Cnt Ov */
+	XMR_FRA_ERR_OV	= 1<<12, /* Bit 12:	Rx Framing Err Cnt Ov */
+	XMR_FMISS_OV	= 1<<11, /* Bit 11:	Rx Missed Ev Cnt Ov */
+	XMR_BURST	= 1<<10, /* Bit 10:	Rx Burst Event Cnt Ov */
+	XMR_INV_MOC	= 1<<9,  /* Bit  9:	Rx with inv. MAC OC Ov*/
+	XMR_INV_MP	= 1<<8,  /* Bit  8:	Rx inv Pause Frame Ov */
+	XMR_MCTRL_OV	= 1<<7,  /* Bit  7:	Rx MAC Ctrl-F Cnt Ov */
+	XMR_MPAUSE_OV	= 1<<6,  /* Bit  6:	Rx Pause MAC Ctrl-F Ov*/
+	XMR_UC_OK_OV	= 1<<5,  /* Bit  5:	Rx Unicast Frame CntOv*/
+	XMR_MC_OK_OV	= 1<<4,  /* Bit  4:	Rx Multicast Cnt Ov */
+	XMR_BC_OK_OV	= 1<<3,  /* Bit  3:	Rx Broadcast Cnt Ov */
+	XMR_OK_LO_OV	= 1<<2,  /* Bit  2:	Octets Rx OK Low CntOv*/
+	XMR_OK_HI_OV	= 1<<1,  /* Bit  1:	Octets Rx OK Hi Cnt Ov*/
+	XMR_OK_OV	= 1<<0,  /* Bit  0:	Frames Received Ok Ov */
+};
+
+#define XMR_DEF_MSK		(XMR_OK_LO_OV | XMR_OK_HI_OV)
+
+/*	XM_TX_CNT_EV	32 bit r/o	Tx Counter Event Register */
+/*	XM_TX_EV_MSK	32 bit r/w	Tx Counter Event Mask */
+enum {
+	XMT_MAX_SZ_OV	= 1<<25,	/* Bit 25:	1024-MaxSize Tx Cnt Ov*/
+	XMT_1023B_OV	= 1<<24,	/* Bit 24:	512-1023Byte Tx Cnt Ov*/
+	XMT_511B_OV	= 1<<23,	/* Bit 23:	256-511 Byte Tx Cnt Ov*/
+	XMT_255B_OV	= 1<<22,	/* Bit 22:	128-255 Byte Tx Cnt Ov*/
+	XMT_127B_OV	= 1<<21,	/* Bit 21:	65-127 Byte Tx Cnt Ov */
+	XMT_64B_OV	= 1<<20,	/* Bit 20:	64 Byte Tx Cnt Ov */
+	XMT_UTIL_OV	= 1<<19,	/* Bit 19:	Tx Util Cnt Overflow */
+	XMT_UTIL_UR	= 1<<18,	/* Bit 18:	Tx Util Cnt Underrun */
+	XMT_CS_ERR_OV	= 1<<17,	/* Bit 17:	Tx Carr Sen Err Cnt Ov*/
+	XMT_FIFO_UR_OV	= 1<<16,	/* Bit 16:	Tx FIFO Ur Ev Cnt Ov */
+	XMT_EX_DEF_OV	= 1<<15,	/* Bit 15:	Tx Ex Deferall Cnt Ov */
+	XMT_DEF	= 1<<14,	/* Bit 14:	Tx Deferred Cnt Ov */
+	XMT_LAT_COL_OV	= 1<<13,	/* Bit 13:	Tx Late Col Cnt Ov */
+	XMT_ABO_COL_OV	= 1<<12,	/* Bit 12:	Tx abo dueto Ex Col Ov*/
+	XMT_MUL_COL_OV	= 1<<11,	/* Bit 11:	Tx Mult Col Cnt Ov */
+	XMT_SNG_COL	= 1<<10,	/* Bit 10:	Tx Single Col Cnt Ov */
+	XMT_MCTRL_OV	= 1<<9,		/* Bit  9:	Tx MAC Ctrl Counter Ov*/
+	XMT_MPAUSE	= 1<<8,		/* Bit  8:	Tx Pause MAC Ctrl-F Ov*/
+	XMT_BURST	= 1<<7,		/* Bit  7:	Tx Burst Event Cnt Ov */
+	XMT_LONG	= 1<<6,		/* Bit  6:	Tx Long Frame Cnt Ov */
+	XMT_UC_OK_OV	= 1<<5,		/* Bit  5:	Tx Unicast Cnt Ov */
+	XMT_MC_OK_OV	= 1<<4,		/* Bit  4:	Tx Multicast Cnt Ov */
+	XMT_BC_OK_OV	= 1<<3,		/* Bit  3:	Tx Broadcast Cnt Ov */
+	XMT_OK_LO_OV	= 1<<2,		/* Bit  2:	Octets Tx OK Low CntOv*/
+	XMT_OK_HI_OV	= 1<<1,		/* Bit  1:	Octets Tx OK Hi Cnt Ov*/
+	XMT_OK_OV	= 1<<0,		/* Bit  0:	Frames Tx Ok Ov */
+};
+
+#define XMT_DEF_MSK		(XMT_OK_LO_OV | XMT_OK_HI_OV)
+
+struct skge_rx_desc {
+	u32		control;
+	u32		next_offset;
+	u32		dma_lo;
+	u32		dma_hi;
+	u32		status;
+	u32		timestamp;
+	u16		csum2;
+	u16		csum1;
+	u16		csum2_start;
+	u16		csum1_start;
+};
+
+struct skge_tx_desc {
+	u32		control;
+	u32		next_offset;
+	u32		dma_lo;
+	u32		dma_hi;
+	u32		status;
+	u32		csum_offs;
+	u16		csum_write;
+	u16		csum_start;
+	u32		rsvd;
+};
+
+struct skge_element {
+	struct skge_element	*next;
+	void			*desc;
+	struct sk_buff  	*skb;
+	DECLARE_PCI_UNMAP_ADDR(mapaddr);
+	DECLARE_PCI_UNMAP_LEN(maplen);
+};
+
+struct skge_ring {
+	struct skge_element *to_clean;
+	struct skge_element *to_use;
+	struct skge_element *start;
+	unsigned long	    count;
+};
+
+
+struct skge_hw {
+	void __iomem  	     *regs;
+	struct pci_dev	     *pdev;
+	u32		     intr_mask;
+	struct net_device    *dev[2];
+
+	u8	     	     chip_id;
+	u8		     chip_rev;
+	u8		     phy_type;
+	u8		     pmd_type;
+	u16		     phy_addr;
+	u8		     ports;
+
+	u32	     	     ram_size;
+	u32	     	     ram_offset;
+
+	struct tasklet_struct ext_tasklet;
+	spinlock_t	     phy_lock;
+};
+
+
+static inline int iscopper(const struct skge_hw *hw)
+{
+	return (hw->pmd_type == 'T');
+}
+
+enum {
+	FLOW_MODE_NONE 		= 0, /* No Flow-Control */
+	FLOW_MODE_LOC_SEND	= 1, /* Local station sends PAUSE */
+	FLOW_MODE_REM_SEND	= 2, /* Symmetric or just remote */
+	FLOW_MODE_SYMMETRIC	= 3, /* Both stations may send PAUSE */
+};
+
+struct skge_port {
+	u32		     msg_enable;
+	struct skge_hw	     *hw;
+	struct net_device    *netdev;
+	int		     port;
+
+	spinlock_t	     tx_lock;
+	u32		     tx_avail;
+	struct skge_ring     tx_ring;
+	struct skge_ring     rx_ring;
+
+	struct net_device_stats net_stats;
+
+	u8		     rx_csum;
+	u8		     blink_on;
+	u8		     flow_control;
+	u8		     wol;
+	u8		     autoneg;	/* AUTONEG_ENABLE, AUTONEG_DISABLE */
+	u8		     duplex;	/* DUPLEX_HALF, DUPLEX_FULL */
+	u16		     speed;	/* SPEED_1000, SPEED_100, ... */
+	u32		     advertising;
+
+	void		     *mem;	/* PCI memory for rings */
+	dma_addr_t	     dma;
+	unsigned long	     mem_size;
+	unsigned int	     rx_buf_size;
+};
+
+
+/* Register accessor for memory mapped device */
+static inline u32 skge_read32(const struct skge_hw *hw, int reg)
+{
+	return readl(hw->regs + reg);
+}
+
+static inline u16 skge_read16(const struct skge_hw *hw, int reg)
+{
+	return readw(hw->regs + reg);
+}
+
+static inline u8 skge_read8(const struct skge_hw *hw, int reg)
+{
+	return readb(hw->regs + reg);
+}
+
+static inline void skge_write32(const struct skge_hw *hw, int reg, u32 val)
+{
+	writel(val, hw->regs + reg);
+}
+
+static inline void skge_write16(const struct skge_hw *hw, int reg, u16 val)
+{
+	writew(val, hw->regs + reg);
+}
+
+static inline void skge_write8(const struct skge_hw *hw, int reg, u8 val)
+{
+	writeb(val, hw->regs + reg);
+}
+
+/* MAC Related Registers inside the device. */
+#define SK_REG(port,reg)	(((port)<<7)+(reg))
+#define SK_XMAC_REG(port, reg) \
+	((BASE_XMAC_1 + (port) * (BASE_XMAC_2 - BASE_XMAC_1)) | (reg) << 1)
+
+static inline u32 xm_read32(const struct skge_hw *hw, int port, int reg)
+{
+	u32 v;
+	v = skge_read16(hw, SK_XMAC_REG(port, reg));
+	v |= (u32)skge_read16(hw, SK_XMAC_REG(port, reg+2)) << 16;
+	return v;
+}
+
+static inline u16 xm_read16(const struct skge_hw *hw, int port, int reg)
+{
+	return skge_read16(hw, SK_XMAC_REG(port,reg));
+}
+
+static inline void xm_write32(const struct skge_hw *hw, int port, int r, u32 v)
+{
+	skge_write16(hw, SK_XMAC_REG(port,r), v & 0xffff);
+	skge_write16(hw, SK_XMAC_REG(port,r+2), v >> 16);
+}
+
+static inline void xm_write16(const struct skge_hw *hw, int port, int r, u16 v)
+{
+	skge_write16(hw, SK_XMAC_REG(port,r), v);
+}
+
+static inline void xm_outhash(const struct skge_hw *hw, int port, int reg,
+				   const u8 *hash)
+{
+	xm_write16(hw, port, reg,   (u16)hash[0] | ((u16)hash[1] << 8));
+	xm_write16(hw, port, reg+2, (u16)hash[2] | ((u16)hash[3] << 8));
+	xm_write16(hw, port, reg+4, (u16)hash[4] | ((u16)hash[5] << 8));
+	xm_write16(hw, port, reg+6, (u16)hash[6] | ((u16)hash[7] << 8));
+}
+
+static inline void xm_outaddr(const struct skge_hw *hw, int port, int reg,
+				   const u8 *addr)
+{
+	xm_write16(hw, port, reg,   (u16)addr[0] | ((u16)addr[1] << 8));
+	xm_write16(hw, port, reg+2, (u16)addr[2] | ((u16)addr[3] << 8));
+	xm_write16(hw, port, reg+4, (u16)addr[4] | ((u16)addr[5] << 8));
+}
+
+#define SK_GMAC_REG(port,reg) \
+	(BASE_GMAC_1 + (port) * (BASE_GMAC_2-BASE_GMAC_1) + (reg))
+
+static inline u16 gma_read16(const struct skge_hw *hw, int port, int reg)
+{
+	return skge_read16(hw, SK_GMAC_REG(port,reg));
+}
+
+static inline u32 gma_read32(const struct skge_hw *hw, int port, int reg)
+{
+	return (u32) skge_read16(hw, SK_GMAC_REG(port,reg))
+		| ((u32)skge_read16(hw, SK_GMAC_REG(port,reg+4)) << 16);
+}
+
+static inline void gma_write16(const struct skge_hw *hw, int port, int r, u16 v)
+{
+	skge_write16(hw, SK_GMAC_REG(port,r), v);
+}
+
+static inline void gma_set_addr(struct skge_hw *hw, int port, int reg,
+				    const u8 *addr)
+{
+	gma_write16(hw, port, reg,  (u16) addr[0] | ((u16) addr[1] << 8));
+	gma_write16(hw, port, reg+4,(u16) addr[2] | ((u16) addr[3] << 8));
+	gma_write16(hw, port, reg+8,(u16) addr[4] | ((u16) addr[5] << 8));
+}
+
+#endif
diff --git a/drivers/net/slip.c b/drivers/net/slip.c
--- a/drivers/net/slip.c
+++ b/drivers/net/slip.c
@@ -74,6 +74,7 @@
 #include <linux/rtnetlink.h>
 #include <linux/if_arp.h>
 #include <linux/if_slip.h>
+#include <linux/delay.h>
 #include <linux/init.h>
 #include "slip.h"
 #ifdef CONFIG_INET
@@ -198,18 +199,12 @@ err_exit:
 static void
 sl_free_bufs(struct slip *sl)
 {
-	void * tmp;
-
 	/* Free all SLIP frame buffers. */
-	tmp = xchg(&sl->rbuff, NULL);
-	kfree(tmp);
-	tmp = xchg(&sl->xbuff, NULL);
-	kfree(tmp);
+	kfree(xchg(&sl->rbuff, NULL));
+	kfree(xchg(&sl->xbuff, NULL));
 #ifdef SL_INCLUDE_CSLIP
-	tmp = xchg(&sl->cbuff, NULL);
-	kfree(tmp);
-	if ((tmp = xchg(&sl->slcomp, NULL)) != NULL)
-		slhc_free(tmp);
+	kfree(xchg(&sl->cbuff, NULL));
+	slhc_free(xchg(&sl->slcomp, NULL));
 #endif
 }
 
@@ -1389,10 +1384,8 @@ static void __exit slip_exit(void)
 	/* First of all: check for active disciplines and hangup them.
 	 */
 	do {
-		if (busy) {
-			set_current_state(TASK_INTERRUPTIBLE);
-			schedule_timeout(HZ / 10);
-		}
+		if (busy)
+			msleep_interruptible(100);
 
 		busy = 0;
 		for (i = 0; i < slip_maxdev; i++) {
@@ -1430,7 +1423,7 @@ static void __exit slip_exit(void)
 	kfree(slip_devs);
 	slip_devs = NULL;
 
-	if ((i = tty_register_ldisc(N_SLIP, NULL)))
+	if ((i = tty_unregister_ldisc(N_SLIP)))
 	{
 		printk(KERN_ERR "SLIP: can't unregister line discipline (err = %d)\n", i);
 	}
diff --git a/drivers/net/smc-mca.c b/drivers/net/smc-mca.c
--- a/drivers/net/smc-mca.c
+++ b/drivers/net/smc-mca.c
@@ -49,7 +49,6 @@
 #include <asm/system.h>
 
 #include "8390.h"
-#include "smc-mca.h"
 
 #define DRV_NAME "smc-mca"
 
@@ -100,6 +99,63 @@ module_param_array(ultra_irq, int, NULL,
 MODULE_PARM_DESC(ultra_io, "SMC Ultra/EtherEZ MCA I/O base address(es)");
 MODULE_PARM_DESC(ultra_irq, "SMC Ultra/EtherEZ MCA IRQ number(s)");
 
+static const struct {
+  unsigned int base_addr;
+} addr_table[] = {
+    { 0x0800 },
+    { 0x1800 },
+    { 0x2800 },
+    { 0x3800 },
+    { 0x4800 },
+    { 0x5800 },
+    { 0x6800 },
+    { 0x7800 },
+    { 0x8800 },
+    { 0x9800 },
+    { 0xa800 },
+    { 0xb800 },
+    { 0xc800 },
+    { 0xd800 },
+    { 0xe800 },
+    { 0xf800 }
+};
+
+#define MEM_MASK 64
+
+static const struct {
+  unsigned char mem_index;
+  unsigned long mem_start;
+  unsigned char num_pages;
+} mem_table[] = {
+    { 16, 0x0c0000, 40 },
+    { 18, 0x0c4000, 40 },
+    { 20, 0x0c8000, 40 },
+    { 22, 0x0cc000, 40 },
+    { 24, 0x0d0000, 40 },
+    { 26, 0x0d4000, 40 },
+    { 28, 0x0d8000, 40 },
+    { 30, 0x0dc000, 40 },
+    {144, 0xfc0000, 40 },
+    {148, 0xfc8000, 40 },
+    {154, 0xfd0000, 40 },
+    {156, 0xfd8000, 40 },
+    {  0, 0x0c0000, 20 },
+    {  1, 0x0c2000, 20 },
+    {  2, 0x0c4000, 20 },
+    {  3, 0x0c6000, 20 }
+};
+
+#define IRQ_MASK 243
+static const struct {
+   unsigned char new_irq;
+   unsigned char old_irq;
+} irq_table[] = {
+   {  3,  3 },
+   {  4,  4 },
+   { 10, 10 },
+   { 14, 15 }
+};
+
 static short smc_mca_adapter_ids[] __initdata = {
 	0x61c8,
 	0x61c9,
@@ -126,7 +182,7 @@ static char *smc_mca_adapter_names[] __i
 
 static int ultra_found = 0;
 
-int __init ultramca_probe(struct device *gen_dev)
+static int __init ultramca_probe(struct device *gen_dev)
 {
 	unsigned short ioaddr;
 	struct net_device *dev;
diff --git a/drivers/net/smc-mca.h b/drivers/net/smc-mca.h
deleted file mode 100644
--- a/drivers/net/smc-mca.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * djweis weisd3458@uni.edu
- * most of this file was taken from ps2esdi.h
- */
-
-struct {
-  unsigned int base_addr;
-} addr_table[] = {
-    { 0x0800 },
-    { 0x1800 },
-    { 0x2800 },
-    { 0x3800 },
-    { 0x4800 },
-    { 0x5800 },
-    { 0x6800 },
-    { 0x7800 },
-    { 0x8800 },
-    { 0x9800 },
-    { 0xa800 },
-    { 0xb800 },
-    { 0xc800 },
-    { 0xd800 },
-    { 0xe800 },
-    { 0xf800 }
-};
-
-#define MEM_MASK 64
-
-struct {
-  unsigned char mem_index;
-  unsigned long mem_start;
-  unsigned char num_pages;
-} mem_table[] = {
-    { 16, 0x0c0000, 40 },
-    { 18, 0x0c4000, 40 },
-    { 20, 0x0c8000, 40 },
-    { 22, 0x0cc000, 40 },
-    { 24, 0x0d0000, 40 },
-    { 26, 0x0d4000, 40 },
-    { 28, 0x0d8000, 40 },
-    { 30, 0x0dc000, 40 },
-    {144, 0xfc0000, 40 },
-    {148, 0xfc8000, 40 },
-    {154, 0xfd0000, 40 },
-    {156, 0xfd8000, 40 },
-    {  0, 0x0c0000, 20 },
-    {  1, 0x0c2000, 20 },
-    {  2, 0x0c4000, 20 },
-    {  3, 0x0c6000, 20 }
-};
-
-#define IRQ_MASK 243
-struct {
-   unsigned char new_irq;
-   unsigned char old_irq;
-} irq_table[] = {
-   {  3,  3 },
-   {  4,  4 },
-   { 10, 10 },
-   { 14, 15 }
-};
diff --git a/drivers/net/smc-ultra.c b/drivers/net/smc-ultra.c
--- a/drivers/net/smc-ultra.c
+++ b/drivers/net/smc-ultra.c
@@ -194,12 +194,7 @@ struct net_device * __init ultra_probe(i
 	err = do_ultra_probe(dev);
 	if (err)
 		goto out;
-	err = register_netdev(dev);
-	if (err)
-		goto out1;
 	return dev;
-out1:
-	cleanup_card(dev);
 out:
 	free_netdev(dev);
 	return ERR_PTR(err);
@@ -325,6 +320,9 @@ static int __init ultra_probe1(struct ne
 #endif
 	NS8390_init(dev, 0);
 
+	retval = register_netdev(dev);
+	if (retval)
+		goto out;
 	return 0;
 out:
 	release_region(ioaddr, ULTRA_IO_EXTENT);
@@ -583,11 +581,8 @@ init_module(void)
 		dev->irq = irq[this_dev];
 		dev->base_addr = io[this_dev];
 		if (do_ultra_probe(dev) == 0) {
-			if (register_netdev(dev) == 0) {
-				dev_ultra[found++] = dev;
-				continue;
-			}
-			cleanup_card(dev);
+			dev_ultra[found++] = dev;
+			continue;
 		}
 		free_netdev(dev);
 		printk(KERN_WARNING "smc-ultra.c: No SMC Ultra card found (i/o = 0x%x).\n", io[this_dev]);
diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c
--- a/drivers/net/smc91x.c
+++ b/drivers/net/smc91x.c
@@ -129,7 +129,7 @@ MODULE_PARM_DESC(nowait, "set to 1 for n
 /*
  * Transmit timeout, default 5 seconds.
  */
-static int watchdog = 5000;
+static int watchdog = 1000;
 module_param(watchdog, int, 0400);
 MODULE_PARM_DESC(watchdog, "transmit timeout in milliseconds");
 
@@ -315,15 +315,25 @@ static void smc_reset(struct net_device 
 	struct smc_local *lp = netdev_priv(dev);
 	void __iomem *ioaddr = lp->base;
 	unsigned int ctl, cfg;
+	struct sk_buff *pending_skb;
 
 	DBG(2, "%s: %s\n", dev->name, __FUNCTION__);
 
-	/* Disable all interrupts */
+	/* Disable all interrupts, block TX tasklet */
 	spin_lock(&lp->lock);
 	SMC_SELECT_BANK(2);
 	SMC_SET_INT_MASK(0);
+	pending_skb = lp->pending_tx_skb;
+	lp->pending_tx_skb = NULL;
 	spin_unlock(&lp->lock);
 
+	/* free any pending tx skb */
+	if (pending_skb) {
+		dev_kfree_skb(pending_skb);
+		lp->stats.tx_errors++;
+		lp->stats.tx_aborted_errors++;
+	}
+
 	/*
 	 * This resets the registers mostly to defaults, but doesn't
 	 * affect EEPROM.  That seems unnecessary
@@ -389,14 +399,6 @@ static void smc_reset(struct net_device 
 	SMC_SELECT_BANK(2);
 	SMC_SET_MMU_CMD(MC_RESET);
 	SMC_WAIT_MMU_BUSY();
-
-	/* clear anything saved */
-	if (lp->pending_tx_skb != NULL) {
-		dev_kfree_skb (lp->pending_tx_skb);
-		lp->pending_tx_skb = NULL;
-		lp->stats.tx_errors++;
-		lp->stats.tx_aborted_errors++;
-	}
 }
 
 /*
@@ -440,6 +442,7 @@ static void smc_shutdown(struct net_devi
 {
 	struct smc_local *lp = netdev_priv(dev);
 	void __iomem *ioaddr = lp->base;
+	struct sk_buff *pending_skb;
 
 	DBG(2, "%s: %s\n", CARDNAME, __FUNCTION__);
 
@@ -447,7 +450,11 @@ static void smc_shutdown(struct net_devi
 	spin_lock(&lp->lock);
 	SMC_SELECT_BANK(2);
 	SMC_SET_INT_MASK(0);
+	pending_skb = lp->pending_tx_skb;
+	lp->pending_tx_skb = NULL;
 	spin_unlock(&lp->lock);
+	if (pending_skb)
+		dev_kfree_skb(pending_skb);
 
 	/* and tell the card to stay away from that nasty outside world */
 	SMC_SELECT_BANK(0);
@@ -627,7 +634,12 @@ static void smc_hardware_send_pkt(unsign
 	}
 
 	skb = lp->pending_tx_skb;
+	if (unlikely(!skb)) {
+		smc_special_unlock(&lp->lock);
+		return;
+	}
 	lp->pending_tx_skb = NULL;
+
 	packet_no = SMC_GET_AR();
 	if (unlikely(packet_no & AR_FAILED)) {
 		printk("%s: Memory allocation failed.\n", dev->name);
@@ -660,15 +672,14 @@ static void smc_hardware_send_pkt(unsign
 	SMC_outw(((len & 1) ? (0x2000 | buf[len-1]) : 0), ioaddr, DATA_REG);
 
 	/*
-	 * If THROTTLE_TX_PKTS is set, we look at the TX_EMPTY flag
-	 * before queueing this packet for TX, and if it's clear then
-	 * we stop the queue here.  This will have the effect of
-	 * having at most 2 packets queued for TX in the chip's memory
-	 * at all time. If THROTTLE_TX_PKTS is not set then the queue
-	 * is stopped only when memory allocation (MC_ALLOC) does not
-	 * succeed right away.
+	 * If THROTTLE_TX_PKTS is set, we stop the queue here. This will
+	 * have the effect of having at most one packet queued for TX
+	 * in the chip's memory at all time.
+	 *
+	 * If THROTTLE_TX_PKTS is not set then the queue is stopped only
+	 * when memory allocation (MC_ALLOC) does not succeed right away.
 	 */
-	if (THROTTLE_TX_PKTS && !(SMC_GET_INT() & IM_TX_EMPTY_INT))
+	if (THROTTLE_TX_PKTS)
 		netif_stop_queue(dev);
 
 	/* queue the packet for TX */
@@ -703,7 +714,6 @@ static int smc_hard_start_xmit(struct sk
 	DBG(3, "%s: %s\n", dev->name, __FUNCTION__);
 
 	BUG_ON(lp->pending_tx_skb != NULL);
-	lp->pending_tx_skb = skb;
 
 	/*
 	 * The MMU wants the number of pages to be the number of 256 bytes
@@ -719,7 +729,6 @@ static int smc_hard_start_xmit(struct sk
 	numPages = ((skb->len & ~1) + (6 - 1)) >> 8;
 	if (unlikely(numPages > 7)) {
 		printk("%s: Far too big packet error.\n", dev->name);
-		lp->pending_tx_skb = NULL;
 		lp->stats.tx_errors++;
 		lp->stats.tx_dropped++;
 		dev_kfree_skb(skb);
@@ -746,6 +755,7 @@ static int smc_hard_start_xmit(struct sk
 
 	smc_special_unlock(&lp->lock);
 
+	lp->pending_tx_skb = skb;
    	if (!poll_count) {
 		/* oh well, wait until the chip finds memory later */
 		netif_stop_queue(dev);
@@ -792,17 +802,20 @@ static void smc_tx(struct net_device *de
 	DBG(2, "%s: TX STATUS 0x%04x PNR 0x%02x\n",
 		dev->name, tx_status, packet_no);
 
-	if (!(tx_status & TS_SUCCESS))
+	if (!(tx_status & ES_TX_SUC))
 		lp->stats.tx_errors++;
-	if (tx_status & TS_LOSTCAR)
+
+	if (tx_status & ES_LOSTCARR)
 		lp->stats.tx_carrier_errors++;
 
-	if (tx_status & TS_LATCOL) {
-		PRINTK("%s: late collision occurred on last xmit\n", dev->name);
+	if (tx_status & (ES_LATCOL | ES_16COL)) {
+		PRINTK("%s: %s occurred on last xmit\n", dev->name,
+		       (tx_status & ES_LATCOL) ?
+			"late collision" : "too many collisions");
 		lp->stats.tx_window_errors++;
 		if (!(lp->stats.tx_window_errors & 63) && net_ratelimit()) {
-			printk(KERN_INFO "%s: unexpectedly large numbers of "
-			       "late collisions. Please check duplex "
+			printk(KERN_INFO "%s: unexpectedly large number of "
+			       "bad collisions. Please check duplex "
 			       "setting.\n", dev->name);
 		}
 	}
@@ -1060,7 +1073,7 @@ static void smc_phy_powerdown(struct net
 	   above). linkwatch_event() also wants the netlink semaphore.
 	*/
 	while(lp->work_pending)
-		schedule();
+		yield();
 
 	bmcr = smc_phy_read(dev, phy, MII_BMCR);
 	smc_phy_write(dev, phy, MII_BMCR, bmcr | BMCR_PDOWN);
@@ -1236,7 +1249,7 @@ static void smc_10bt_check_media(struct 
 	old_carrier = netif_carrier_ok(dev) ? 1 : 0;
 
 	SMC_SELECT_BANK(0);
-	new_carrier = SMC_inw(ioaddr, EPH_STATUS_REG) & ES_LINK_OK ? 1 : 0;
+	new_carrier = (SMC_GET_EPH_STATUS() & ES_LINK_OK) ? 1 : 0;
 	SMC_SELECT_BANK(2);
 
 	if (init || (old_carrier != new_carrier)) {
@@ -1308,15 +1321,16 @@ static irqreturn_t smc_interrupt(int irq
 		if (!status)
 			break;
 
-		if (status & IM_RCV_INT) {
-			DBG(3, "%s: RX irq\n", dev->name);
-			smc_rcv(dev);
-		} else if (status & IM_TX_INT) {
+		if (status & IM_TX_INT) {
+			/* do this before RX as it will free memory quickly */
 			DBG(3, "%s: TX int\n", dev->name);
 			smc_tx(dev);
 			SMC_ACK_INT(IM_TX_INT);
 			if (THROTTLE_TX_PKTS)
 				netif_wake_queue(dev);
+		} else if (status & IM_RCV_INT) {
+			DBG(3, "%s: RX irq\n", dev->name);
+			smc_rcv(dev);
 		} else if (status & IM_ALLOC_INT) {
 			DBG(3, "%s: Allocation irq\n", dev->name);
 			tasklet_hi_schedule(&lp->tx_task);
@@ -1337,7 +1351,10 @@ static irqreturn_t smc_interrupt(int irq
 			/* multiple collisions */
 			lp->stats.collisions += card_stats & 0xF;
 		} else if (status & IM_RX_OVRN_INT) {
-			DBG(1, "%s: RX overrun\n", dev->name);
+			DBG(1, "%s: RX overrun (EPH_ST 0x%04x)\n", dev->name,
+			       ({ int eph_st; SMC_SELECT_BANK(0);
+				  eph_st = SMC_GET_EPH_STATUS();
+				  SMC_SELECT_BANK(2); eph_st; }) );
 			SMC_ACK_INT(IM_RX_OVRN_INT);
 			lp->stats.rx_errors++;
 			lp->stats.rx_fifo_errors++;
@@ -1389,7 +1406,7 @@ static void smc_timeout(struct net_devic
 {
 	struct smc_local *lp = netdev_priv(dev);
 	void __iomem *ioaddr = lp->base;
-	int status, mask, meminfo, fifo;
+	int status, mask, eph_st, meminfo, fifo;
 
 	DBG(2, "%s: %s\n", dev->name, __FUNCTION__);
 
@@ -1398,11 +1415,13 @@ static void smc_timeout(struct net_devic
 	mask = SMC_GET_INT_MASK();
 	fifo = SMC_GET_FIFO();
 	SMC_SELECT_BANK(0);
+	eph_st = SMC_GET_EPH_STATUS();
 	meminfo = SMC_GET_MIR();
 	SMC_SELECT_BANK(2);
 	spin_unlock_irq(&lp->lock);
-	PRINTK( "%s: INT 0x%02x MASK 0x%02x MEM 0x%04x FIFO 0x%04x\n",
-		dev->name, status, mask, meminfo, fifo );
+	PRINTK( "%s: TX timeout (INT 0x%02x INTMASK 0x%02x "
+		"MEM 0x%04x FIFO 0x%04x EPH_ST 0x%04x)\n",
+		dev->name, status, mask, meminfo, fifo, eph_st );
 
 	smc_reset(dev);
 	smc_enable(dev);
@@ -1598,14 +1617,8 @@ static int smc_close(struct net_device *
 
 	/* clear everything */
 	smc_shutdown(dev);
-
+	tasklet_kill(&lp->tx_task);
 	smc_phy_powerdown(dev);
-
-	if (lp->pending_tx_skb) {
-		dev_kfree_skb(lp->pending_tx_skb);
-		lp->pending_tx_skb = NULL;
-	}
-
 	return 0;
 }
 
@@ -1863,7 +1876,7 @@ static int __init smc_probe(struct net_d
 	SMC_SELECT_BANK(1);
 	val = SMC_GET_BASE();
 	val = ((val & 0x1F00) >> 3) << SMC_IO_SHIFT;
-	if (((unsigned long)ioaddr & ((PAGE_SIZE-1)<<SMC_IO_SHIFT)) != val) { /*XXX: WTF? */
+	if (((unsigned int)ioaddr & (0x3e0 << SMC_IO_SHIFT)) != val) {
 		printk("%s: IOADDR %p doesn't match configuration (%x).\n",
 			CARDNAME, ioaddr, val);
 	}
@@ -1985,7 +1998,7 @@ static int __init smc_probe(struct net_d
       	if (retval)
       		goto err_out;
 
-	set_irq_type(dev->irq, IRQT_RISING);
+	set_irq_type(dev->irq, SMC_IRQ_TRIGGER_TYPE);
 
 #ifdef SMC_USE_PXA_DMA
 	{
diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h
--- a/drivers/net/smc91x.h
+++ b/drivers/net/smc91x.h
@@ -151,7 +151,7 @@
 
 /* We actually can't write halfwords properly if not word aligned */
 static inline void
-SMC_outw(u16 val, unsigned long ioaddr, int reg)
+SMC_outw(u16 val, void __iomem *ioaddr, int reg)
 {
 	if (reg & 2) {
 		unsigned int v = val << 16;
@@ -182,6 +182,16 @@ SMC_outw(u16 val, unsigned long ioaddr, 
 #define SMC_insl(a, r, p, l)	readsl((a) + (r), p, l)
 #define SMC_outsl(a, r, p, l)	writesl((a) + (r), p, l)
 
+#include <asm/mach-types.h>
+#include <asm/arch/cpu.h>
+
+#define	SMC_IRQ_TRIGGER_TYPE (( \
+		   machine_is_omap_h2() \
+		|| machine_is_omap_h3() \
+		|| (machine_is_omap_innovator() && !cpu_is_omap1510()) \
+	) ? IRQT_FALLING : IRQT_RISING)
+
+
 #elif	defined(CONFIG_SH_SH4202_MICRODEV)
 
 #define SMC_CAN_USE_8BIT	0
@@ -300,6 +310,9 @@ static inline void SMC_outsw (unsigned l
 
 #endif
 
+#ifndef	SMC_IRQ_TRIGGER_TYPE
+#define	SMC_IRQ_TRIGGER_TYPE	IRQT_RISING
+#endif
 
 #ifdef SMC_USE_PXA_DMA
 /*
@@ -317,7 +330,7 @@ static inline void SMC_outsw (unsigned l
 #define SMC_insl(a, r, p, l) \
 	smc_pxa_dma_insl(a, lp->physaddr, r, dev->dma, p, l)
 static inline void
-smc_pxa_dma_insl(u_long ioaddr, u_long physaddr, int reg, int dma,
+smc_pxa_dma_insl(void __iomem *ioaddr, u_long physaddr, int reg, int dma,
 		 u_char *buf, int len)
 {
 	dma_addr_t dmabuf;
@@ -355,7 +368,7 @@ smc_pxa_dma_insl(u_long ioaddr, u_long p
 #define SMC_insw(a, r, p, l) \
 	smc_pxa_dma_insw(a, lp->physaddr, r, dev->dma, p, l)
 static inline void
-smc_pxa_dma_insw(u_long ioaddr, u_long physaddr, int reg, int dma,
+smc_pxa_dma_insw(void __iomem *ioaddr, u_long physaddr, int reg, int dma,
 		 u_char *buf, int len)
 {
 	dma_addr_t dmabuf;
@@ -681,14 +694,6 @@ static const char * chip_ids[ 16 ] =  {
 
 
 /*
- . Transmit status bits
-*/
-#define TS_SUCCESS 0x0001
-#define TS_LOSTCAR 0x0400
-#define TS_LATCOL  0x0200
-#define TS_16COL   0x0010
-
-/*
  . Receive status bits
 */
 #define RS_ALGNERR	0x8000
@@ -845,6 +850,7 @@ static const char * chip_ids[ 16 ] =  {
 #define SMC_GET_FIFO()		SMC_inw( ioaddr, FIFO_REG )
 #define SMC_GET_PTR()		SMC_inw( ioaddr, PTR_REG )
 #define SMC_SET_PTR(x)		SMC_outw( x, ioaddr, PTR_REG )
+#define SMC_GET_EPH_STATUS()	SMC_inw( ioaddr, EPH_STATUS_REG )
 #define SMC_GET_RCR()		SMC_inw( ioaddr, RCR_REG )
 #define SMC_SET_RCR(x)		SMC_outw( x, ioaddr, RCR_REG )
 #define SMC_GET_REV()		SMC_inw( ioaddr, REV_REG )
diff --git a/drivers/net/starfire.c b/drivers/net/starfire.c
--- a/drivers/net/starfire.c
+++ b/drivers/net/starfire.c
@@ -2,7 +2,7 @@
 /*
 	Written 1998-2000 by Donald Becker.
 
-	Current maintainer is Ion Badulescu <ionut@cs.columbia.edu>. Please
+	Current maintainer is Ion Badulescu <ionut ta badula tod org>. Please
 	send all bug reports to me, and not to Donald Becker, as this code
 	has been heavily modified from Donald's original version.
 
@@ -129,12 +129,18 @@
 	- put the chip to a D3 slumber on driver unload
 	- added config option to enable/disable NAPI
 
-TODO:	bugfixes (no bugs known as of right now)
+	LK1.4.2 (Ion Badulescu)
+	- finally added firmware (GPL'ed by Adaptec)
+	- removed compatibility code for 2.2.x
+
+TODO:	- fix forced speed/duplexing code (broken a long time ago, when
+	somebody converted the driver to use the generic MII code)
+	- fix VLAN support
 */
 
 #define DRV_NAME	"starfire"
-#define DRV_VERSION	"1.03+LK1.4.1"
-#define DRV_RELDATE	"February 10, 2002"
+#define DRV_VERSION	"1.03+LK1.4.2"
+#define DRV_RELDATE	"January 19, 2005"
 
 #include <linux/config.h>
 #include <linux/version.h>
@@ -145,25 +151,15 @@ TODO:	bugfixes (no bugs known as of righ
 #include <linux/etherdevice.h>
 #include <linux/init.h>
 #include <linux/delay.h>
+#include <linux/crc32.h>
+#include <linux/ethtool.h>
+#include <linux/mii.h>
+#include <linux/if_vlan.h>
 #include <asm/processor.h>		/* Processor type for cache alignment. */
 #include <asm/uaccess.h>
 #include <asm/io.h>
 
-/*
- * Adaptec's license for their drivers (which is where I got the
- * firmware files) does not allow one to redistribute them. Thus, we can't
- * include the firmware with this driver.
- *
- * However, should a legal-to-distribute firmware become available,
- * the driver developer would need only to obtain the firmware in the
- * form of a C header file.
- * Once that's done, the #undef below must be changed into a #define
- * for this driver to really use the firmware. Note that Rx/Tx
- * hardware TCP checksumming is not possible without the firmware.
- *
- * WANTED: legal firmware to include with this GPL'd driver.
- */
-#undef HAS_FIRMWARE
+#include "starfire_firmware.h"
 /*
  * The current frame processor firmware fails to checksum a fragment
  * of length 1. If and when this is fixed, the #define below can be removed.
@@ -172,13 +168,7 @@ TODO:	bugfixes (no bugs known as of righ
 /*
  * Define this if using the driver with the zero-copy patch
  */
-#if defined(HAS_FIRMWARE) && defined(MAX_SKB_FRAGS)
 #define ZEROCOPY
-#endif
-
-#ifdef HAS_FIRMWARE
-#include "starfire_firmware.h"
-#endif /* HAS_FIRMWARE */
 
 #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
 #define VLAN_SUPPORT
@@ -202,11 +192,7 @@ static int mtu;
    The Starfire has a 512 element hash table based on the Ethernet CRC. */
 static int multicast_filter_limit = 512;
 /* Whether to do TCP/UDP checksums in hardware */
-#ifdef HAS_FIRMWARE
 static int enable_hw_cksum = 1;
-#else
-static int enable_hw_cksum = 0;
-#endif
 
 #define PKT_BUF_SZ	1536		/* Size of each temporary Rx buffer.*/
 /*
@@ -291,43 +277,15 @@ static int full_duplex[MAX_UNITS] = {0, 
 #define RX_DESC_ADDR_SIZE RxDescAddr32bit
 #endif
 
-#ifdef MAX_SKB_FRAGS
 #define skb_first_frag_len(skb)	skb_headlen(skb)
 #define skb_num_frags(skb) (skb_shinfo(skb)->nr_frags + 1)
-#else  /* not MAX_SKB_FRAGS */
-#define skb_first_frag_len(skb)	(skb->len)
-#define skb_num_frags(skb) 1
-#endif /* not MAX_SKB_FRAGS */
-
-/* 2.2.x compatibility code */
-#if LINUX_VERSION_CODE < 0x20300
-
-#include "starfire-kcomp22.h"
-
-#else  /* LINUX_VERSION_CODE > 0x20300 */
-
-#include <linux/crc32.h>
-#include <linux/ethtool.h>
-#include <linux/mii.h>
-
-#include <linux/if_vlan.h>
-
-#define init_tx_timer(dev, func, timeout) \
-	dev->tx_timeout = func; \
-	dev->watchdog_timeo = timeout;
-#define kick_tx_timer(dev, func, timeout)
-
-#define netif_start_if(dev)
-#define netif_stop_if(dev)
-
-#define PCI_SLOT_NAME(pci_dev)	pci_name(pci_dev)
-
-#endif /* LINUX_VERSION_CODE > 0x20300 */
 
 #ifdef HAVE_NETDEV_POLL
 #define init_poll(dev) \
+do { \
 	dev->poll = &netdev_poll; \
-	dev->weight = max_interrupt_work;
+	dev->weight = max_interrupt_work; \
+} while (0)
 #define netdev_rx(dev, ioaddr) \
 do { \
 	u32 intr_enable; \
@@ -341,7 +299,7 @@ do { \
 		/* Paranoia check */ \
 		intr_enable = readl(ioaddr + IntrEnable); \
 		if (intr_enable & (IntrRxDone | IntrRxEmpty)) { \
-			printk("%s: interrupt while in polling mode!\n", dev->name); \
+			printk(KERN_INFO "%s: interrupt while in polling mode!\n", dev->name); \
 			intr_enable &= ~(IntrRxDone | IntrRxEmpty); \
 			writel(intr_enable, ioaddr + IntrEnable); \
 		} \
@@ -371,6 +329,7 @@ KERN_INFO " (unofficial 2.2/2.4 kernel p
 MODULE_AUTHOR("Donald Becker <becker@scyld.com>");
 MODULE_DESCRIPTION("Adaptec Starfire Ethernet driver");
 MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_VERSION);
 
 module_param(max_interrupt_work, int, 0);
 module_param(mtu, int, 0);
@@ -425,7 +384,7 @@ on the 32/64 bitness of the architecture
 minimum-length padding.  It does not use the completion queue
 consumer index, but instead checks for non-zero status entries.
 
-For receive this driver uses type 0/1/2/3 receive descriptors.  The driver
+For receive this driver uses type 2/3 receive descriptors.  The driver
 allocates full frame size skbuffs for the Rx ring buffers, so all frames
 should fit in a single descriptor.  The driver does not use the completion
 queue consumer index, but instead checks for non-zero status entries.
@@ -476,7 +435,7 @@ IVc. Errata
 
 */
 
-
+
 
 enum chip_capability_flags {CanHaveMII=1, };
 
@@ -670,7 +629,6 @@ struct full_rx_done_desc {
 	u32 timestamp;
 };
 /* XXX: this is ugly and I'm not sure it's worth the trouble -Ion */
-#ifdef HAS_FIRMWARE
 #ifdef VLAN_SUPPORT
 typedef struct full_rx_done_desc rx_done_desc;
 #define RxComplType RxComplType3
@@ -678,15 +636,6 @@ typedef struct full_rx_done_desc rx_done
 typedef struct csum_rx_done_desc rx_done_desc;
 #define RxComplType RxComplType2
 #endif /* not VLAN_SUPPORT */
-#else  /* not HAS_FIRMWARE */
-#ifdef VLAN_SUPPORT
-typedef struct basic_rx_done_desc rx_done_desc;
-#define RxComplType RxComplType1
-#else  /* not VLAN_SUPPORT */
-typedef struct short_rx_done_desc rx_done_desc;
-#define RxComplType RxComplType0
-#endif /* not VLAN_SUPPORT */
-#endif /* not HAS_FIRMWARE */
 
 enum rx_done_bits {
 	RxOK=0x20000000, RxFIFOErr=0x10000000, RxBufQ2=0x08000000,
@@ -898,13 +847,10 @@ static int __devinit starfire_init_one(s
 	/* enable MWI -- it vastly improves Rx performance on sparc64 */
 	pci_set_mwi(pdev);
 
-#ifdef MAX_SKB_FRAGS
-	dev->features |= NETIF_F_SG;
-#endif /* MAX_SKB_FRAGS */
 #ifdef ZEROCOPY
 	/* Starfire can do TCP/UDP checksumming */
 	if (enable_hw_cksum)
-		dev->features |= NETIF_F_IP_CSUM;
+		dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
 #endif /* ZEROCOPY */
 #ifdef VLAN_SUPPORT
 	dev->features |= NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER;
@@ -1008,7 +954,8 @@ static int __devinit starfire_init_one(s
 	/* The chip-specific entries in the device structure. */
 	dev->open = &netdev_open;
 	dev->hard_start_xmit = &start_tx;
-	init_tx_timer(dev, tx_timeout, TX_TIMEOUT);
+	dev->tx_timeout = tx_timeout;
+	dev->watchdog_timeo = TX_TIMEOUT;
 	init_poll(dev);
 	dev->stop = &netdev_close;
 	dev->get_stats = &get_stats;
@@ -1039,7 +986,7 @@ static int __devinit starfire_init_one(s
 				if ((mdio_read(dev, phy, MII_BMCR) & BMCR_RESET) == 0)
 					break;
 			if (boguscnt == 0) {
-				printk("%s: PHY reset never completed!\n", dev->name);
+				printk("%s: PHY#%d reset never completed!\n", dev->name, phy);
 				continue;
 			}
 			mii_status = mdio_read(dev, phy, MII_BMSR);
@@ -1110,6 +1057,7 @@ static int netdev_open(struct net_device
 	size_t tx_done_q_size, rx_done_q_size, tx_ring_size, rx_ring_size;
 
 	/* Do we ever need to reset the chip??? */
+
 	retval = request_irq(dev->irq, &intr_handler, SA_SHIRQ, dev->name, dev);
 	if (retval)
 		return retval;
@@ -1211,7 +1159,6 @@ static int netdev_open(struct net_device
 
 	writel(np->intr_timer_ctrl, ioaddr + IntrTimerCtrl);
 
-	netif_start_if(dev);
 	netif_start_queue(dev);
 
 	if (debug > 1)
@@ -1238,13 +1185,11 @@ static int netdev_open(struct net_device
 	writel(ETH_P_8021Q, ioaddr + VlanType);
 #endif /* VLAN_SUPPORT */
 
-#ifdef HAS_FIRMWARE
 	/* Load Rx/Tx firmware into the frame processors */
 	for (i = 0; i < FIRMWARE_RX_SIZE * 2; i++)
 		writel(firmware_rx[i], ioaddr + RxGfpMem + i * 4);
 	for (i = 0; i < FIRMWARE_TX_SIZE * 2; i++)
 		writel(firmware_tx[i], ioaddr + TxGfpMem + i * 4);
-#endif /* HAS_FIRMWARE */
 	if (enable_hw_cksum)
 		/* Enable the Rx and Tx units, and the Rx/Tx frame processors. */
 		writel(TxEnable|TxGFPEnable|RxEnable|RxGFPEnable, ioaddr + GenCtrl);
@@ -1341,7 +1286,7 @@ static void init_ring(struct net_device 
 		np->rx_info[i].skb = skb;
 		if (skb == NULL)
 			break;
-		np->rx_info[i].mapping = pci_map_single(np->pci_dev, skb->tail, np->rx_buf_sz, PCI_DMA_FROMDEVICE);
+		np->rx_info[i].mapping = pci_map_single(np->pci_dev, skb->data, np->rx_buf_sz, PCI_DMA_FROMDEVICE);
 		skb->dev = dev;			/* Mark as being used by this device. */
 		/* Grrr, we cannot offset to correctly align the IP header. */
 		np->rx_ring[i].rxaddr = cpu_to_dma(np->rx_info[i].mapping | RxDescValid);
@@ -1378,8 +1323,6 @@ static int start_tx(struct sk_buff *skb,
 	u32 status;
 	int i;
 
-	kick_tx_timer(dev, tx_timeout, TX_TIMEOUT);
-
 	/*
 	 * be cautious here, wrapping the queue has weird semantics
 	 * and we may not have enough slots even when it seems we do.
@@ -1404,7 +1347,7 @@ static int start_tx(struct sk_buff *skb,
 		}
 
 		if (has_bad_length)
-			skb_checksum_help(skb);
+			skb_checksum_help(skb, 0);
 	}
 #endif /* ZEROCOPY && HAS_BROKEN_FIRMWARE */
 
@@ -1433,12 +1376,10 @@ static int start_tx(struct sk_buff *skb,
 			np->tx_info[entry].mapping =
 				pci_map_single(np->pci_dev, skb->data, skb_first_frag_len(skb), PCI_DMA_TODEVICE);
 		} else {
-#ifdef MAX_SKB_FRAGS
 			skb_frag_t *this_frag = &skb_shinfo(skb)->frags[i - 1];
 			status |= this_frag->size;
 			np->tx_info[entry].mapping =
 				pci_map_single(np->pci_dev, page_address(this_frag->page) + this_frag->page_offset, this_frag->size, PCI_DMA_TODEVICE);
-#endif /* MAX_SKB_FRAGS */
 		}
 
 		np->tx_ring[entry].addr = cpu_to_dma(np->tx_info[entry].mapping);
@@ -1531,7 +1472,6 @@ static irqreturn_t intr_handler(int irq,
 				np->tx_info[entry].mapping = 0;
 				np->dirty_tx += np->tx_info[entry].used_slots;
 				entry = (entry + np->tx_info[entry].used_slots) % TX_RING_SIZE;
-#ifdef MAX_SKB_FRAGS
 				{
 					int i;
 					for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
@@ -1543,7 +1483,7 @@ static irqreturn_t intr_handler(int irq,
 						entry++;
 					}
 				}
-#endif /* MAX_SKB_FRAGS */
+
 				dev_kfree_skb_irq(skb);
 			}
 			np->tx_done_q[np->tx_done].status = 0;
@@ -1603,7 +1543,7 @@ static int __netdev_rx(struct net_device
 		if (debug > 4)
 			printk(KERN_DEBUG "  netdev_rx() status of %d was %#8.8x.\n", np->rx_done, desc_status);
 		if (!(desc_status & RxOK)) {
-			/* There was a error. */
+			/* There was an error. */
 			if (debug > 2)
 				printk(KERN_DEBUG "  netdev_rx() Rx error was %#8.8x.\n", desc_status);
 			np->stats.rx_errors++;
@@ -1632,7 +1572,7 @@ static int __netdev_rx(struct net_device
 			pci_dma_sync_single_for_cpu(np->pci_dev,
 						    np->rx_info[entry].mapping,
 						    pkt_len, PCI_DMA_FROMDEVICE);
-			eth_copy_and_sum(skb, np->rx_info[entry].skb->tail, pkt_len, 0);
+			eth_copy_and_sum(skb, np->rx_info[entry].skb->data, pkt_len, 0);
 			pci_dma_sync_single_for_device(np->pci_dev,
 						       np->rx_info[entry].mapping,
 						       pkt_len, PCI_DMA_FROMDEVICE);
@@ -1656,11 +1596,10 @@ static int __netdev_rx(struct net_device
 #endif
 
 		skb->protocol = eth_type_trans(skb, dev);
-#if defined(HAS_FIRMWARE) || defined(VLAN_SUPPORT)
+#ifdef VLAN_SUPPORT
 		if (debug > 4)
 			printk(KERN_DEBUG "  netdev_rx() status2 of %d was %#4.4x.\n", np->rx_done, le16_to_cpu(desc->status2));
 #endif
-#ifdef HAS_FIRMWARE
 		if (le16_to_cpu(desc->status2) & 0x0100) {
 			skb->ip_summed = CHECKSUM_UNNECESSARY;
 			np->stats.rx_compressed++;
@@ -1679,7 +1618,6 @@ static int __netdev_rx(struct net_device
 			skb->csum = le16_to_cpu(desc->csum);
 			printk(KERN_DEBUG "%s: checksum_hw, status2 = %#x\n", dev->name, le16_to_cpu(desc->status2));
 		}
-#endif /* HAS_FIRMWARE */
 #ifdef VLAN_SUPPORT
 		if (np->vlgrp && le16_to_cpu(desc->status2) & 0x0200) {
 			if (debug > 4)
@@ -1758,7 +1696,7 @@ static void refill_rx_ring(struct net_de
 			if (skb == NULL)
 				break;	/* Better luck next round. */
 			np->rx_info[entry].mapping =
-				pci_map_single(np->pci_dev, skb->tail, np->rx_buf_sz, PCI_DMA_FROMDEVICE);
+				pci_map_single(np->pci_dev, skb->data, np->rx_buf_sz, PCI_DMA_FROMDEVICE);
 			skb->dev = dev;	/* Mark as being used by this device. */
 			np->rx_ring[entry].rxaddr =
 				cpu_to_dma(np->rx_info[entry].mapping | RxDescValid);
@@ -1900,9 +1838,6 @@ static struct net_device_stats *get_stat
 }
 
 
-/* Chips may use the upper or lower CRC bits, and may reverse and/or invert
-   them.  Select the endian-ness that results in minimal calculations.
-*/
 static void set_rx_mode(struct net_device *dev)
 {
 	struct netdev_private *np = netdev_priv(dev);
@@ -1969,6 +1904,8 @@ static void set_rx_mode(struct net_devic
 		memset(mc_filter, 0, sizeof(mc_filter));
 		for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
 		     i++, mclist = mclist->next) {
+			/* The chip uses the upper 9 CRC bits
+			   as index into the hash table */
 			int bit_nr = ether_crc_le(ETH_ALEN, mclist->dmi_addr) >> 23;
 			__u32 *fptr = (__u32 *) &mc_filter[(bit_nr >> 4) & ~1];
 
@@ -2001,7 +1938,7 @@ static void get_drvinfo(struct net_devic
 	struct netdev_private *np = netdev_priv(dev);
 	strcpy(info->driver, DRV_NAME);
 	strcpy(info->version, DRV_VERSION);
-	strcpy(info->bus_info, PCI_SLOT_NAME(np->pci_dev));
+	strcpy(info->bus_info, pci_name(np->pci_dev));
 }
 
 static int get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
@@ -2083,7 +2020,6 @@ static int netdev_close(struct net_devic
 	int i;
 
 	netif_stop_queue(dev);
-	netif_stop_if(dev);
 
 	if (debug > 1) {
 		printk(KERN_DEBUG "%s: Shutting down ethercard, Intr status %#8.8x.\n",
@@ -2184,7 +2120,13 @@ static int __init starfire_init (void)
 /* when a module, this is printed whether or not devices are found in probe */
 #ifdef MODULE
 	printk(version);
+#ifdef HAVE_NETDEV_POLL
+	printk(KERN_INFO DRV_NAME ": polling (NAPI) enabled\n");
+#else
+	printk(KERN_INFO DRV_NAME ": polling (NAPI) disabled\n");
 #endif
+#endif
+
 #ifndef ADDR_64BITS
 	/* we can do this test only at run-time... sigh */
 	if (sizeof(dma_addr_t) == sizeof(u64)) {
@@ -2192,10 +2134,6 @@ static int __init starfire_init (void)
 		return -ENODEV;
 	}
 #endif /* not ADDR_64BITS */
-#ifndef HAS_FIRMWARE
-	/* unconditionally disable hw cksums if firmware is not present */
-	enable_hw_cksum = 0;
-#endif /* not HAS_FIRMWARE */
 	return pci_module_init (&starfire_driver);
 }
 
diff --git a/drivers/net/starfire_firmware.h b/drivers/net/starfire_firmware.h
new file mode 100644
--- /dev/null
+++ b/drivers/net/starfire_firmware.h
@@ -0,0 +1,346 @@
+/*
+ * Copyright 2003 Adaptec, Inc.
+ *
+ * Please read the following license before using the Adaptec Software
+ * ("Program"). If you do not agree to the license terms, do not use the
+ * Program:
+ *
+ * You agree to be bound by version 2 of the General Public License ("GPL")
+ * dated June 1991, which can be found at http://www.fsf.org/licenses/gpl.html.
+ * If the link is broken, write to Free Software Foundation, 59 Temple Place,
+ * Boston, Massachusetts 02111-1307.
+ *
+ * BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE IT IS LICENSED "AS IS" AND
+ * THERE IS NO WARRANTY FOR THE PROGRAM, INCLUDING BUT NOT LIMITED TO THE
+ * IMPLIED WARRANTIES OF MERCHANTIBILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * (TO THE EXTENT PERMITTED BY APPLICABLE LAW). USE OF THE PROGRAM IS AT YOUR
+ * OWN RISK. IN NO EVENT WILL ADAPTEC OR ITS LICENSORS 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.
+ *
+ */
+
+static const u32 firmware_rx[] = {
+  0x010003dc, 0x00000000,
+  0x04000421, 0x00000086,
+  0x80000015, 0x0000180e,
+  0x81000015, 0x00006664,
+  0x1a0040ab, 0x00000b06,
+  0x14200011, 0x00000000,
+  0x14204022, 0x0000aaaa,
+  0x14204022, 0x00000300,
+  0x14204022, 0x00000000,
+  0x1a0040ab, 0x00000b14,
+  0x14200011, 0x00000000,
+  0x83000015, 0x00000002,
+  0x04000021, 0x00000000,
+  0x00000010, 0x00000000,
+  0x04000421, 0x00000087,
+  0x00000010, 0x00000000,
+  0x00000010, 0x00000000,
+  0x00008015, 0x00000000,
+  0x0000003e, 0x00000000,
+  0x00000010, 0x00000000,
+  0x82000015, 0x00004000,
+  0x009e8050, 0x00000000,
+  0x03008015, 0x00000000,
+  0x86008015, 0x00000000,
+  0x82000015, 0x00008000,
+  0x0100001c, 0x00000000,
+  0x000050a0, 0x0000010c,
+  0x4e20d011, 0x00006008,
+  0x1420d012, 0x00004008,
+  0x0000f090, 0x00007000,
+  0x0000c8b0, 0x00003000,
+  0x00004040, 0x00000000,
+  0x00108015, 0x00000000,
+  0x00a2c150, 0x00004000,
+  0x00a400b0, 0x00000014,
+  0x00000020, 0x00000000,
+  0x2500400d, 0x00002525,
+  0x00047220, 0x00003100,
+  0x00934070, 0x00000000,
+  0x00000020, 0x00000000,
+  0x00924460, 0x00000184,
+  0x2b20c011, 0x00000000,
+  0x0000c420, 0x00000540,
+  0x36014018, 0x0000422d,
+  0x14200011, 0x00000000,
+  0x00924460, 0x00000183,
+  0x3200001f, 0x00000034,
+  0x02ac0015, 0x00000002,
+  0x00a60110, 0x00000008,
+  0x42200011, 0x00000000,
+  0x00924060, 0x00000103,
+  0x0000001e, 0x00000000,
+  0x00000020, 0x00000100,
+  0x0000001e, 0x00000000,
+  0x00924460, 0x00000086,
+  0x00004080, 0x00000000,
+  0x0092c070, 0x00000000,
+  0x00924060, 0x00000100,
+  0x0000c890, 0x00005000,
+  0x00a6c110, 0x00000000,
+  0x00b0c090, 0x00000012,
+  0x021c0015, 0x00000000,
+  0x3200001f, 0x00000034,
+  0x00924460, 0x00000510,
+  0x44210011, 0x00000000,
+  0x42000011, 0x00000000,
+  0x83000015, 0x00000040,
+  0x00924460, 0x00000508,
+  0x45014018, 0x00004545,
+  0x00808050, 0x00000000,
+  0x62208012, 0x00000000,
+  0x82000015, 0x00000800,
+  0x15200011, 0x00000000,
+  0x00000010, 0x00000000,
+  0x00000010, 0x00000000,
+  0x00000010, 0x00000000,
+  0x00000010, 0x00000000,
+  0x00000010, 0x00000000,
+  0x80000015, 0x0000eea4,
+  0x81000015, 0x0000005f,
+  0x00000060, 0x00000000,
+  0x00004120, 0x00000000,
+  0x00004a00, 0x00004000,
+  0x00924460, 0x00000190,
+  0x5601401a, 0x00005956,
+  0x14000011, 0x00000000,
+  0x00934050, 0x00000018,
+  0x00930050, 0x00000018,
+  0x3601403a, 0x0000002d,
+  0x000643a9, 0x00000000,
+  0x0000c420, 0x00000140,
+  0x5601401a, 0x00005956,
+  0x14000011, 0x00000000,
+  0x00000010, 0x00000000,
+  0x00000010, 0x00000000,
+  0x000642a9, 0x00000000,
+  0x00024420, 0x00000183,
+  0x5601401a, 0x00005956,
+  0x82000015, 0x00002000,
+  0x15200011, 0x00000000,
+  0x82000015, 0x00000010,
+  0x15200011, 0x00000000,
+  0x82000015, 0x00000010,
+  0x15200011, 0x00000000,
+};	/* 104 Rx instructions */
+#define FIRMWARE_RX_SIZE 104
+
+static const u32 firmware_tx[] = {
+  0x010003dc, 0x00000000,
+  0x04000421, 0x00000086,
+  0x80000015, 0x0000180e,
+  0x81000015, 0x00006664,
+  0x1a0040ab, 0x00000b06,
+  0x14200011, 0x00000000,
+  0x14204022, 0x0000aaaa,
+  0x14204022, 0x00000300,
+  0x14204022, 0x00000000,
+  0x1a0040ab, 0x00000b14,
+  0x14200011, 0x00000000,
+  0x83000015, 0x00000002,
+  0x04000021, 0x00000000,
+  0x00000010, 0x00000000,
+  0x04000421, 0x00000087,
+  0x00000010, 0x00000000,
+  0x00000010, 0x00000000,
+  0x00008015, 0x00000000,
+  0x0000003e, 0x00000000,
+  0x00000010, 0x00000000,
+  0x82000015, 0x00004000,
+  0x009e8050, 0x00000000,
+  0x03008015, 0x00000000,
+  0x86008015, 0x00000000,
+  0x82000015, 0x00008000,
+  0x0100001c, 0x00000000,
+  0x000050a0, 0x0000010c,
+  0x4e20d011, 0x00006008,
+  0x1420d012, 0x00004008,
+  0x0000f090, 0x00007000,
+  0x0000c8b0, 0x00003000,
+  0x00004040, 0x00000000,
+  0x00108015, 0x00000000,
+  0x00a2c150, 0x00004000,
+  0x00a400b0, 0x00000014,
+  0x00000020, 0x00000000,
+  0x2500400d, 0x00002525,
+  0x00047220, 0x00003100,
+  0x00934070, 0x00000000,
+  0x00000020, 0x00000000,
+  0x00924460, 0x00000184,
+  0x2b20c011, 0x00000000,
+  0x0000c420, 0x00000540,
+  0x36014018, 0x0000422d,
+  0x14200011, 0x00000000,
+  0x00924460, 0x00000183,
+  0x3200001f, 0x00000034,
+  0x02ac0015, 0x00000002,
+  0x00a60110, 0x00000008,
+  0x42200011, 0x00000000,
+  0x00924060, 0x00000103,
+  0x0000001e, 0x00000000,
+  0x00000020, 0x00000100,
+  0x0000001e, 0x00000000,
+  0x00924460, 0x00000086,
+  0x00004080, 0x00000000,
+  0x0092c070, 0x00000000,
+  0x00924060, 0x00000100,
+  0x0000c890, 0x00005000,
+  0x00a6c110, 0x00000000,
+  0x00b0c090, 0x00000012,
+  0x021c0015, 0x00000000,
+  0x3200001f, 0x00000034,
+  0x00924460, 0x00000510,
+  0x44210011, 0x00000000,
+  0x42000011, 0x00000000,
+  0x83000015, 0x00000040,
+  0x00924460, 0x00000508,
+  0x45014018, 0x00004545,
+  0x00808050, 0x00000000,
+  0x62208012, 0x00000000,
+  0x82000015, 0x00000800,
+  0x15200011, 0x00000000,
+  0x00000010, 0x00000000,
+  0x00000010, 0x00000000,
+  0x00000010, 0x00000000,
+  0x00000010, 0x00000000,
+  0x00000010, 0x00000000,
+  0x80000015, 0x0000eea4,
+  0x81000015, 0x0000005f,
+  0x00000060, 0x00000000,
+  0x00004120, 0x00000000,
+  0x00004a00, 0x00004000,
+  0x00924460, 0x00000190,
+  0x5601401a, 0x00005956,
+  0x14000011, 0x00000000,
+  0x00934050, 0x00000018,
+  0x00930050, 0x00000018,
+  0x3601403a, 0x0000002d,
+  0x000643a9, 0x00000000,
+  0x0000c420, 0x00000140,
+  0x5601401a, 0x00005956,
+  0x14000011, 0x00000000,
+  0x00000010, 0x00000000,
+  0x00000010, 0x00000000,
+  0x000642a9, 0x00000000,
+  0x00024420, 0x00000183,
+  0x5601401a, 0x00005956,
+  0x82000015, 0x00002000,
+  0x15200011, 0x00000000,
+  0x82000015, 0x00000010,
+  0x15200011, 0x00000000,
+  0x82000015, 0x00000010,
+  0x15200011, 0x00000000,
+};	/* 104 Tx instructions */
+#define FIRMWARE_TX_SIZE 104
+#if 0
+static const u32 firmware_wol[] = {
+  0x010003dc, 0x00000000,
+  0x19000421, 0x00000087,
+  0x80000015, 0x00001a1a,
+  0x81000015, 0x00001a1a,
+  0x1a0040ab, 0x00000b06,
+  0x15200011, 0x00000000,
+  0x15204022, 0x0000aaaa,
+  0x15204022, 0x00000300,
+  0x15204022, 0x00000000,
+  0x1a0040ab, 0x00000b15,
+  0x15200011, 0x00000000,
+  0x83000015, 0x00000002,
+  0x04000021, 0x00000000,
+  0x00000010, 0x00000000,
+  0x04000421, 0x00000087,
+  0x00000010, 0x00000000,
+  0x00000010, 0x00000000,
+  0x00008015, 0x00000000,
+  0x0000003e, 0x00000000,
+  0x00000010, 0x00000000,
+  0x00000010, 0x00000000,
+  0x82000015, 0x00004000,
+  0x82000015, 0x00008000,
+  0x0000000c, 0x00000000,
+  0x00000010, 0x00000000,
+  0x00004080, 0x00000100,
+  0x1f20c011, 0x00001122,
+  0x2720f011, 0x00003011,
+  0x19200071, 0x00000000,
+  0x1a200051, 0x00000000,
+  0x00000010, 0x00000000,
+  0x00000010, 0x00000000,
+  0x1d2040a4, 0x00003344,
+  0x1d2040a2, 0x00005566,
+  0x000040a0, 0x00000100,
+  0x00108050, 0x00000001,
+  0x1a208012, 0x00000006,
+  0x82000015, 0x00008080,
+  0x010003dc, 0x00000000,
+  0x1d2040a4, 0x00002233,
+  0x1d2040a4, 0x00004455,
+  0x2d208011, 0x00000005,
+  0x1d2040a4, 0x00006611,
+  0x00108050, 0x00000001,
+  0x27200011, 0x00000000,
+  0x1d2050a4, 0x00006600,
+  0x82000015, 0x00008080,
+  0x010003dc, 0x00000000,
+  0x00000050, 0x00000000,
+  0x1b200031, 0x00000000,
+  0x0000001e, 0x00000000,
+  0x0000001e, 0x00000000,
+  0x0000001e, 0x00000000,
+  0x0000001e, 0x00000000,
+  0x00924460, 0x00000086,
+  0x00004080, 0x00000000,
+  0x0092c070, 0x00000000,
+  0x00924060, 0x00000100,
+  0x0000c890, 0x00005000,
+  0x00a6c110, 0x00000000,
+  0x00b0c090, 0x00000012,
+  0x021c0015, 0x00000000,
+  0x3200001f, 0x00000034,
+  0x00924460, 0x00000510,
+  0x44210011, 0x00000000,
+  0x42000011, 0x00000000,
+  0x83000015, 0x00000040,
+  0x00924460, 0x00000508,
+  0x476a0012, 0x00000100,
+  0x83000015, 0x00000008,
+  0x16200011, 0x00000000,
+  0x001e8050, 0x00000000,
+  0x001e8050, 0x00000000,
+  0x00808050, 0x00000000,
+  0x03008015, 0x00000000,
+  0x62208012, 0x00000000,
+  0x82000015, 0x00000800,
+  0x16200011, 0x00000000,
+  0x80000015, 0x0000eea4,
+  0x81000015, 0x0000005f,
+  0x00000020, 0x00000000,
+  0x00004120, 0x00000000,
+  0x00004a00, 0x00004000,
+  0x00924460, 0x00000190,
+  0x5c01401a, 0x0000595c,
+  0x15000011, 0x00000000,
+  0x00934050, 0x00000018,
+  0x00930050, 0x00000018,
+  0x3601403a, 0x0000002d,
+  0x00064029, 0x00000000,
+  0x0000c420, 0x00000140,
+  0x5c01401a, 0x0000595c,
+  0x15000011, 0x00000000,
+  0x00000010, 0x00000000,
+  0x00000010, 0x00000000,
+  0x00064029, 0x00000000,
+  0x00024420, 0x00000183,
+  0x5c01401a, 0x0000595c,
+  0x82000015, 0x00002000,
+  0x16200011, 0x00000000,
+  0x82000015, 0x00000010,
+  0x16200011, 0x00000000,
+  0x82000015, 0x00000010,
+  0x16200011, 0x00000000,
+};	/* 104 WoL instructions */
+#define FIRMWARE_WOL_SIZE 104
+#endif
diff --git a/drivers/net/sundance.c b/drivers/net/sundance.c
--- a/drivers/net/sundance.c
+++ b/drivers/net/sundance.c
@@ -1028,7 +1028,7 @@ static void init_ring(struct net_device 
 		skb->dev = dev;		/* Mark as being used by this device. */
 		skb_reserve(skb, 2);	/* 16 byte align the IP header. */
 		np->rx_ring[i].frag[0].addr = cpu_to_le32(
-			pci_map_single(np->pci_dev, skb->tail, np->rx_buf_sz,
+			pci_map_single(np->pci_dev, skb->data, np->rx_buf_sz,
 				PCI_DMA_FROMDEVICE));
 		np->rx_ring[i].frag[0].length = cpu_to_le32(np->rx_buf_sz | LastFrag);
 	}
@@ -1341,7 +1341,7 @@ static void rx_poll(unsigned long data)
 							    np->rx_buf_sz,
 							    PCI_DMA_FROMDEVICE);
 
-				eth_copy_and_sum(skb, np->rx_skbuff[entry]->tail, pkt_len, 0);
+				eth_copy_and_sum(skb, np->rx_skbuff[entry]->data, pkt_len, 0);
 				pci_dma_sync_single_for_device(np->pci_dev,
 							       desc->frag[0].addr,
 							       np->rx_buf_sz,
@@ -1400,7 +1400,7 @@ static void refill_rx (struct net_device
 			skb->dev = dev;		/* Mark as being used by this device. */
 			skb_reserve(skb, 2);	/* Align IP on 16 byte boundaries */
 			np->rx_ring[entry].frag[0].addr = cpu_to_le32(
-				pci_map_single(np->pci_dev, skb->tail,
+				pci_map_single(np->pci_dev, skb->data,
 					np->rx_buf_sz, PCI_DMA_FROMDEVICE));
 		}
 		/* Perhaps we need not reset this field. */
diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c
--- a/drivers/net/sungem.c
+++ b/drivers/net/sungem.c
@@ -44,6 +44,7 @@
 #include <linux/init.h>
 #include <linux/errno.h>
 #include <linux/pci.h>
+#include <linux/dma-mapping.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
@@ -2989,10 +2990,10 @@ static int __devinit gem_init_one(struct
 	 */
 	if (pdev->vendor == PCI_VENDOR_ID_SUN &&
 	    pdev->device == PCI_DEVICE_ID_SUN_GEM &&
-	    !pci_set_dma_mask(pdev, (u64) 0xffffffffffffffffULL)) {
+	    !pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
 		pci_using_dac = 1;
 	} else {
-		err = pci_set_dma_mask(pdev, (u64) 0xffffffff);
+		err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
 		if (err) {
 			printk(KERN_ERR PFX "No usable DMA configuration, "
 			       "aborting.\n");
@@ -3078,7 +3079,9 @@ static int __devinit gem_init_one(struct
 	gp->phy_mii.dev = dev;
 	gp->phy_mii.mdio_read = _phy_read;
 	gp->phy_mii.mdio_write = _phy_write;
-
+#ifdef CONFIG_PPC_PMAC
+	gp->phy_mii.platform_data = gp->of_node;
+#endif
 	/* By default, we start with autoneg */
 	gp->want_autoneg = 1;
 
diff --git a/drivers/net/sungem_phy.c b/drivers/net/sungem_phy.c
--- a/drivers/net/sungem_phy.c
+++ b/drivers/net/sungem_phy.c
@@ -32,6 +32,10 @@
 #include <linux/ethtool.h>
 #include <linux/delay.h>
 
+#ifdef CONFIG_PPC_PMAC
+#include <asm/prom.h>
+#endif
+
 #include "sungem_phy.h"
 
 /* Link modes of the BCM5400 PHY */
@@ -281,10 +285,12 @@ static int bcm5411_suspend(struct mii_ph
 static int bcm5421_init(struct mii_phy* phy)
 {
 	u16 data;
-	int rev;
+	unsigned int id;
 
-	rev = phy_read(phy, MII_PHYSID2) & 0x000f;
-	if (rev == 0) {
+	id = (phy_read(phy, MII_PHYSID1) << 16 | phy_read(phy, MII_PHYSID2));
+
+	/* Revision 0 of 5421 needs some fixups */
+	if (id == 0x002060e0) {
 		/* This is borrowed from MacOS
 		 */
 		phy_write(phy, 0x18, 0x1007);
@@ -297,21 +303,28 @@ static int bcm5421_init(struct mii_phy* 
 		data = phy_read(phy, 0x15);
 		phy_write(phy, 0x15, data | 0x0200);
 	}
-#if 0
-	/* This has to be verified before I enable it */
-	/* Enable automatic low-power */
-	phy_write(phy, 0x1c, 0x9002);
-	phy_write(phy, 0x1c, 0xa821);
-	phy_write(phy, 0x1c, 0x941d);
-#endif
-	return 0;
-}
 
-static int bcm5421k2_init(struct mii_phy* phy)
-{
-	/* Init code borrowed from OF */
-	phy_write(phy, 4, 0x01e1);
-	phy_write(phy, 9, 0x0300);
+	/* Pick up some init code from OF for K2 version */
+	if ((id & 0xfffffff0) == 0x002062e0) {
+		phy_write(phy, 4, 0x01e1);
+		phy_write(phy, 9, 0x0300);
+	}
+
+	/* Check if we can enable automatic low power */
+#ifdef CONFIG_PPC_PMAC
+	if (phy->platform_data) {
+		struct device_node *np = of_get_parent(phy->platform_data);
+		int can_low_power = 1;
+		if (np == NULL || get_property(np, "no-autolowpower", NULL))
+			can_low_power = 0;
+		if (can_low_power) {
+			/* Enable automatic low-power */
+			phy_write(phy, 0x1c, 0x9002);
+			phy_write(phy, 0x1c, 0xa821);
+			phy_write(phy, 0x1c, 0x941d);
+		}
+	}
+#endif /* CONFIG_PPC_PMAC */
 
 	return 0;
 }
@@ -762,7 +775,7 @@ static struct mii_phy_def bcm5421_phy_de
 
 /* Broadcom BCM 5421 built-in K2 */
 static struct mii_phy_ops bcm5421k2_phy_ops = {
-	.init		= bcm5421k2_init,
+	.init		= bcm5421_init,
 	.suspend	= bcm5411_suspend,
 	.setup_aneg	= bcm54xx_setup_aneg,
 	.setup_forced	= bcm54xx_setup_forced,
@@ -779,6 +792,25 @@ static struct mii_phy_def bcm5421k2_phy_
 	.ops		= &bcm5421k2_phy_ops
 };
 
+/* Broadcom BCM 5462 built-in Vesta */
+static struct mii_phy_ops bcm5462V_phy_ops = {
+	.init		= bcm5421_init,
+	.suspend	= bcm5411_suspend,
+	.setup_aneg	= bcm54xx_setup_aneg,
+	.setup_forced	= bcm54xx_setup_forced,
+	.poll_link	= genmii_poll_link,
+	.read_link	= bcm54xx_read_link,
+};
+
+static struct mii_phy_def bcm5462V_phy_def = {
+	.phy_id		= 0x002060d0,
+	.phy_id_mask	= 0xfffffff0,
+	.name		= "BCM5462-Vesta",
+	.features	= MII_GBIT_FEATURES,
+	.magic_aneg	= 1,
+	.ops		= &bcm5462V_phy_ops
+};
+
 /* Marvell 88E1101 (Apple seem to deal with 2 different revs,
  * I masked out the 8 last bits to get both, but some specs
  * would be useful here) --BenH.
@@ -824,6 +856,7 @@ static struct mii_phy_def* mii_phy_table
 	&bcm5411_phy_def,
 	&bcm5421_phy_def,
 	&bcm5421k2_phy_def,
+	&bcm5462V_phy_def,
 	&marvell_phy_def,
 	&genmii_phy_def,
 	NULL
diff --git a/drivers/net/sungem_phy.h b/drivers/net/sungem_phy.h
--- a/drivers/net/sungem_phy.h
+++ b/drivers/net/sungem_phy.h
@@ -43,9 +43,10 @@ struct mii_phy
 	int			pause;
 
 	/* Provided by host chip */
-	struct net_device*	dev;
+	struct net_device	*dev;
 	int (*mdio_read) (struct net_device *dev, int mii_id, int reg);
 	void (*mdio_write) (struct net_device *dev, int mii_id, int reg, int val);
+	void			*platform_data;
 };
 
 /* Pass in a struct mii_phy with dev, mdio_read and mdio_write
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -66,8 +66,8 @@
 
 #define DRV_MODULE_NAME		"tg3"
 #define PFX DRV_MODULE_NAME	": "
-#define DRV_MODULE_VERSION	"3.31"
-#define DRV_MODULE_RELDATE	"June 8, 2005"
+#define DRV_MODULE_VERSION	"3.37"
+#define DRV_MODULE_RELDATE	"August 25, 2005"
 
 #define TG3_DEF_MAC_MODE	0
 #define TG3_DEF_RX_MODE		0
@@ -90,7 +90,7 @@
 /* hardware minimum and maximum for a single frame's data payload */
 #define TG3_MIN_MTU			60
 #define TG3_MAX_MTU(tp)	\
-	(!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS) ? 9000 : 1500)
+	((tp->tg3_flags2 & TG3_FLG2_JUMBO_CAPABLE) ? 9000 : 1500)
 
 /* These numbers seem to be hard coded in the NIC firmware somehow.
  * You can't change the ring sizes, but you can change where you place
@@ -221,6 +221,10 @@ static struct pci_device_id tg3_pci_tbl[
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
 	{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5753F,
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+	{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5780,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+	{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5780S,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
 	{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5781,
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
 	{ PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9DXX,
@@ -337,12 +341,10 @@ static struct {
 static void tg3_write_indirect_reg32(struct tg3 *tp, u32 off, u32 val)
 {
 	if ((tp->tg3_flags & TG3_FLAG_PCIX_TARGET_HWBUG) != 0) {
-		unsigned long flags;
-
-		spin_lock_irqsave(&tp->indirect_lock, flags);
+		spin_lock_bh(&tp->indirect_lock);
 		pci_write_config_dword(tp->pdev, TG3PCI_REG_BASE_ADDR, off);
 		pci_write_config_dword(tp->pdev, TG3PCI_REG_DATA, val);
-		spin_unlock_irqrestore(&tp->indirect_lock, flags);
+		spin_unlock_bh(&tp->indirect_lock);
 	} else {
 		writel(val, tp->regs + off);
 		if ((tp->tg3_flags & TG3_FLAG_5701_REG_WRITE_BUG) != 0)
@@ -353,12 +355,10 @@ static void tg3_write_indirect_reg32(str
 static void _tw32_flush(struct tg3 *tp, u32 off, u32 val)
 {
 	if ((tp->tg3_flags & TG3_FLAG_PCIX_TARGET_HWBUG) != 0) {
-		unsigned long flags;
-
-		spin_lock_irqsave(&tp->indirect_lock, flags);
+		spin_lock_bh(&tp->indirect_lock);
 		pci_write_config_dword(tp->pdev, TG3PCI_REG_BASE_ADDR, off);
 		pci_write_config_dword(tp->pdev, TG3PCI_REG_DATA, val);
-		spin_unlock_irqrestore(&tp->indirect_lock, flags);
+		spin_unlock_bh(&tp->indirect_lock);
 	} else {
 		void __iomem *dest = tp->regs + off;
 		writel(val, dest);
@@ -398,28 +398,24 @@ static inline void _tw32_tx_mbox(struct 
 
 static void tg3_write_mem(struct tg3 *tp, u32 off, u32 val)
 {
-	unsigned long flags;
-
-	spin_lock_irqsave(&tp->indirect_lock, flags);
+	spin_lock_bh(&tp->indirect_lock);
 	pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off);
 	pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val);
 
 	/* Always leave this as zero. */
 	pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0);
-	spin_unlock_irqrestore(&tp->indirect_lock, flags);
+	spin_unlock_bh(&tp->indirect_lock);
 }
 
 static void tg3_read_mem(struct tg3 *tp, u32 off, u32 *val)
 {
-	unsigned long flags;
-
-	spin_lock_irqsave(&tp->indirect_lock, flags);
+	spin_lock_bh(&tp->indirect_lock);
 	pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off);
 	pci_read_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val);
 
 	/* Always leave this as zero. */
 	pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0);
-	spin_unlock_irqrestore(&tp->indirect_lock, flags);
+	spin_unlock_bh(&tp->indirect_lock);
 }
 
 static void tg3_disable_ints(struct tg3 *tp)
@@ -438,12 +434,14 @@ static inline void tg3_cond_int(struct t
 
 static void tg3_enable_ints(struct tg3 *tp)
 {
+	tp->irq_sync = 0;
+	wmb();
+
 	tw32(TG3PCI_MISC_HOST_CTRL,
 	     (tp->misc_host_ctrl & ~MISC_HOST_CTRL_MASK_PCI_INT));
 	tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
 		     (tp->last_tag << 24));
 	tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW);
-
 	tg3_cond_int(tp);
 }
 
@@ -492,6 +490,7 @@ static void tg3_restart_ints(struct tg3 
 
 static inline void tg3_netif_stop(struct tg3 *tp)
 {
+	tp->dev->trans_start = jiffies;	/* prevent tx timeout */
 	netif_poll_disable(tp->dev);
 	netif_tx_disable(tp->dev);
 }
@@ -504,7 +503,8 @@ static inline void tg3_netif_start(struc
 	 * (such as after tg3_init_hw)
 	 */
 	netif_poll_enable(tp->dev);
-	tg3_cond_int(tp);
+	tp->hw_status->status |= SD_STATUS_UPDATED;
+	tg3_enable_ints(tp);
 }
 
 static void tg3_switch_clocks(struct tg3 *tp)
@@ -512,6 +512,9 @@ static void tg3_switch_clocks(struct tg3
 	u32 clock_ctrl = tr32(TG3PCI_CLOCK_CTRL);
 	u32 orig_clock_ctrl;
 
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780)
+		return;
+
 	orig_clock_ctrl = clock_ctrl;
 	clock_ctrl &= (CLOCK_CTRL_FORCE_CLKRUN |
 		       CLOCK_CTRL_CLKRUN_OENABLE |
@@ -911,7 +914,7 @@ out:
 	if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5401) {
 		/* Cannot do read-modify-write on 5401 */
 		tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x4c20);
-	} else if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) {
+	} else if (tp->tg3_flags2 & TG3_FLG2_JUMBO_CAPABLE) {
 		u32 phy_reg;
 
 		/* Set bit 14 with read-modify-write to preserve other bits */
@@ -923,7 +926,7 @@ out:
 	/* Set phy register 0x10 bit 0 to high fifo elasticity to support
 	 * jumbo frames transmission.
 	 */
-	if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) {
+	if (tp->tg3_flags2 & TG3_FLG2_JUMBO_CAPABLE) {
 		u32 phy_reg;
 
 		if (!tg3_readphy(tp, MII_TG3_EXT_CTRL, &phy_reg))
@@ -1097,7 +1100,7 @@ static int tg3_set_power_state(struct tg
 		tp->link_config.orig_autoneg = tp->link_config.autoneg;
 	}
 
-	if (!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)) {
+	if (!(tp->tg3_flags2 & TG3_FLG2_ANY_SERDES)) {
 		tp->link_config.speed = SPEED_10;
 		tp->link_config.duplex = DUPLEX_HALF;
 		tp->link_config.autoneg = AUTONEG_ENABLE;
@@ -1149,6 +1152,8 @@ static int tg3_set_power_state(struct tg
 		     CLOCK_CTRL_ALTCLK |
 		     CLOCK_CTRL_PWRDOWN_PLL133);
 		udelay(40);
+	} else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780) {
+		/* do nothing */
 	} else if (!((tp->tg3_flags2 & TG3_FLG2_5750_PLUS) &&
 		     (tp->tg3_flags & TG3_FLAG_ENABLE_ASF))) {
 		u32 newbits1, newbits2;
@@ -1242,6 +1247,25 @@ static void tg3_setup_flow_control(struc
 	u32 old_tx_mode = tp->tx_mode;
 
 	if (tp->tg3_flags & TG3_FLAG_PAUSE_AUTONEG) {
+
+		/* Convert 1000BaseX flow control bits to 1000BaseT
+		 * bits before resolving flow control.
+		 */
+		if (tp->tg3_flags2 & TG3_FLG2_MII_SERDES) {
+			local_adv &= ~(ADVERTISE_PAUSE_CAP |
+				       ADVERTISE_PAUSE_ASYM);
+			remote_adv &= ~(LPA_PAUSE_CAP | LPA_PAUSE_ASYM);
+
+			if (local_adv & ADVERTISE_1000XPAUSE)
+				local_adv |= ADVERTISE_PAUSE_CAP;
+			if (local_adv & ADVERTISE_1000XPSE_ASYM)
+				local_adv |= ADVERTISE_PAUSE_ASYM;
+			if (remote_adv & LPA_1000XPAUSE)
+				remote_adv |= LPA_PAUSE_CAP;
+			if (remote_adv & LPA_1000XPAUSE_ASYM)
+				remote_adv |= LPA_PAUSE_ASYM;
+		}
+
 		if (local_adv & ADVERTISE_PAUSE_CAP) {
 			if (local_adv & ADVERTISE_PAUSE_ASYM) {
 				if (remote_adv & LPA_PAUSE_CAP)
@@ -2502,12 +2526,226 @@ static int tg3_setup_fiber_phy(struct tg
 	return 0;
 }
 
+static int tg3_setup_fiber_mii_phy(struct tg3 *tp, int force_reset)
+{
+	int current_link_up, err = 0;
+	u32 bmsr, bmcr;
+	u16 current_speed;
+	u8 current_duplex;
+
+	tp->mac_mode |= MAC_MODE_PORT_MODE_GMII;
+	tw32_f(MAC_MODE, tp->mac_mode);
+	udelay(40);
+
+	tw32(MAC_EVENT, 0);
+
+	tw32_f(MAC_STATUS,
+	     (MAC_STATUS_SYNC_CHANGED |
+	      MAC_STATUS_CFG_CHANGED |
+	      MAC_STATUS_MI_COMPLETION |
+	      MAC_STATUS_LNKSTATE_CHANGED));
+	udelay(40);
+
+	if (force_reset)
+		tg3_phy_reset(tp);
+
+	current_link_up = 0;
+	current_speed = SPEED_INVALID;
+	current_duplex = DUPLEX_INVALID;
+
+	err |= tg3_readphy(tp, MII_BMSR, &bmsr);
+	err |= tg3_readphy(tp, MII_BMSR, &bmsr);
+
+	err |= tg3_readphy(tp, MII_BMCR, &bmcr);
+
+	if ((tp->link_config.autoneg == AUTONEG_ENABLE) && !force_reset &&
+	    (tp->tg3_flags2 & TG3_FLG2_PARALLEL_DETECT)) {
+		/* do nothing, just check for link up at the end */
+	} else if (tp->link_config.autoneg == AUTONEG_ENABLE) {
+		u32 adv, new_adv;
+
+		err |= tg3_readphy(tp, MII_ADVERTISE, &adv);
+		new_adv = adv & ~(ADVERTISE_1000XFULL | ADVERTISE_1000XHALF |
+				  ADVERTISE_1000XPAUSE |
+				  ADVERTISE_1000XPSE_ASYM |
+				  ADVERTISE_SLCT);
+
+		/* Always advertise symmetric PAUSE just like copper */
+		new_adv |= ADVERTISE_1000XPAUSE;
+
+		if (tp->link_config.advertising & ADVERTISED_1000baseT_Half)
+			new_adv |= ADVERTISE_1000XHALF;
+		if (tp->link_config.advertising & ADVERTISED_1000baseT_Full)
+			new_adv |= ADVERTISE_1000XFULL;
+
+		if ((new_adv != adv) || !(bmcr & BMCR_ANENABLE)) {
+			tg3_writephy(tp, MII_ADVERTISE, new_adv);
+			bmcr |= BMCR_ANENABLE | BMCR_ANRESTART;
+			tg3_writephy(tp, MII_BMCR, bmcr);
+
+			tw32_f(MAC_EVENT, MAC_EVENT_LNKSTATE_CHANGED);
+			tp->tg3_flags2 |= TG3_FLG2_PHY_JUST_INITTED;
+			tp->tg3_flags2 &= ~TG3_FLG2_PARALLEL_DETECT;
+
+			return err;
+		}
+	} else {
+		u32 new_bmcr;
+
+		bmcr &= ~BMCR_SPEED1000;
+		new_bmcr = bmcr & ~(BMCR_ANENABLE | BMCR_FULLDPLX);
+
+		if (tp->link_config.duplex == DUPLEX_FULL)
+			new_bmcr |= BMCR_FULLDPLX;
+
+		if (new_bmcr != bmcr) {
+			/* BMCR_SPEED1000 is a reserved bit that needs
+			 * to be set on write.
+			 */
+			new_bmcr |= BMCR_SPEED1000;
+
+			/* Force a linkdown */
+			if (netif_carrier_ok(tp->dev)) {
+				u32 adv;
+
+				err |= tg3_readphy(tp, MII_ADVERTISE, &adv);
+				adv &= ~(ADVERTISE_1000XFULL |
+					 ADVERTISE_1000XHALF |
+					 ADVERTISE_SLCT);
+				tg3_writephy(tp, MII_ADVERTISE, adv);
+				tg3_writephy(tp, MII_BMCR, bmcr |
+							   BMCR_ANRESTART |
+							   BMCR_ANENABLE);
+				udelay(10);
+				netif_carrier_off(tp->dev);
+			}
+			tg3_writephy(tp, MII_BMCR, new_bmcr);
+			bmcr = new_bmcr;
+			err |= tg3_readphy(tp, MII_BMSR, &bmsr);
+			err |= tg3_readphy(tp, MII_BMSR, &bmsr);
+			tp->tg3_flags2 &= ~TG3_FLG2_PARALLEL_DETECT;
+		}
+	}
+
+	if (bmsr & BMSR_LSTATUS) {
+		current_speed = SPEED_1000;
+		current_link_up = 1;
+		if (bmcr & BMCR_FULLDPLX)
+			current_duplex = DUPLEX_FULL;
+		else
+			current_duplex = DUPLEX_HALF;
+
+		if (bmcr & BMCR_ANENABLE) {
+			u32 local_adv, remote_adv, common;
+
+			err |= tg3_readphy(tp, MII_ADVERTISE, &local_adv);
+			err |= tg3_readphy(tp, MII_LPA, &remote_adv);
+			common = local_adv & remote_adv;
+			if (common & (ADVERTISE_1000XHALF |
+				      ADVERTISE_1000XFULL)) {
+				if (common & ADVERTISE_1000XFULL)
+					current_duplex = DUPLEX_FULL;
+				else
+					current_duplex = DUPLEX_HALF;
+
+				tg3_setup_flow_control(tp, local_adv,
+						       remote_adv);
+			}
+			else
+				current_link_up = 0;
+		}
+	}
+
+	tp->mac_mode &= ~MAC_MODE_HALF_DUPLEX;
+	if (tp->link_config.active_duplex == DUPLEX_HALF)
+		tp->mac_mode |= MAC_MODE_HALF_DUPLEX;
+
+	tw32_f(MAC_MODE, tp->mac_mode);
+	udelay(40);
+
+	tw32_f(MAC_EVENT, MAC_EVENT_LNKSTATE_CHANGED);
+
+	tp->link_config.active_speed = current_speed;
+	tp->link_config.active_duplex = current_duplex;
+
+	if (current_link_up != netif_carrier_ok(tp->dev)) {
+		if (current_link_up)
+			netif_carrier_on(tp->dev);
+		else {
+			netif_carrier_off(tp->dev);
+			tp->tg3_flags2 &= ~TG3_FLG2_PARALLEL_DETECT;
+		}
+		tg3_link_report(tp);
+	}
+	return err;
+}
+
+static void tg3_serdes_parallel_detect(struct tg3 *tp)
+{
+	if (tp->tg3_flags2 & TG3_FLG2_PHY_JUST_INITTED) {
+		/* Give autoneg time to complete. */
+		tp->tg3_flags2 &= ~TG3_FLG2_PHY_JUST_INITTED;
+		return;
+	}
+	if (!netif_carrier_ok(tp->dev) &&
+	    (tp->link_config.autoneg == AUTONEG_ENABLE)) {
+		u32 bmcr;
+
+		tg3_readphy(tp, MII_BMCR, &bmcr);
+		if (bmcr & BMCR_ANENABLE) {
+			u32 phy1, phy2;
+
+			/* Select shadow register 0x1f */
+			tg3_writephy(tp, 0x1c, 0x7c00);
+			tg3_readphy(tp, 0x1c, &phy1);
+
+			/* Select expansion interrupt status register */
+			tg3_writephy(tp, 0x17, 0x0f01);
+			tg3_readphy(tp, 0x15, &phy2);
+			tg3_readphy(tp, 0x15, &phy2);
+
+			if ((phy1 & 0x10) && !(phy2 & 0x20)) {
+				/* We have signal detect and not receiving
+				 * config code words, link is up by parallel
+				 * detection.
+				 */
+
+				bmcr &= ~BMCR_ANENABLE;
+				bmcr |= BMCR_SPEED1000 | BMCR_FULLDPLX;
+				tg3_writephy(tp, MII_BMCR, bmcr);
+				tp->tg3_flags2 |= TG3_FLG2_PARALLEL_DETECT;
+			}
+		}
+	}
+	else if (netif_carrier_ok(tp->dev) &&
+		 (tp->link_config.autoneg == AUTONEG_ENABLE) &&
+		 (tp->tg3_flags2 & TG3_FLG2_PARALLEL_DETECT)) {
+		u32 phy2;
+
+		/* Select expansion interrupt status register */
+		tg3_writephy(tp, 0x17, 0x0f01);
+		tg3_readphy(tp, 0x15, &phy2);
+		if (phy2 & 0x20) {
+			u32 bmcr;
+
+			/* Config code words received, turn on autoneg. */
+			tg3_readphy(tp, MII_BMCR, &bmcr);
+			tg3_writephy(tp, MII_BMCR, bmcr | BMCR_ANENABLE);
+
+			tp->tg3_flags2 &= ~TG3_FLG2_PARALLEL_DETECT;
+
+		}
+	}
+}
+
 static int tg3_setup_phy(struct tg3 *tp, int force_reset)
 {
 	int err;
 
 	if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) {
 		err = tg3_setup_fiber_phy(tp, force_reset);
+	} else if (tp->tg3_flags2 & TG3_FLG2_MII_SERDES) {
+		err = tg3_setup_fiber_mii_phy(tp, force_reset);
 	} else {
 		err = tg3_setup_copper_phy(tp, force_reset);
 	}
@@ -2578,7 +2816,7 @@ static void tg3_tx(struct tg3 *tp)
 			sw_idx = NEXT_TX(sw_idx);
 		}
 
-		dev_kfree_skb_irq(skb);
+		dev_kfree_skb(skb);
 	}
 
 	tp->tx_cons = sw_idx;
@@ -2616,7 +2854,7 @@ static int tg3_alloc_rx_skb(struct tg3 *
 		map = &tp->rx_std_buffers[dest_idx];
 		if (src_idx >= 0)
 			src_map = &tp->rx_std_buffers[src_idx];
-		skb_size = RX_PKT_BUF_SZ;
+		skb_size = tp->rx_pkt_buf_sz;
 		break;
 
 	case RXD_OPAQUE_RING_JUMBO:
@@ -2884,11 +3122,8 @@ static int tg3_poll(struct net_device *n
 {
 	struct tg3 *tp = netdev_priv(netdev);
 	struct tg3_hw_status *sblk = tp->hw_status;
-	unsigned long flags;
 	int done;
 
-	spin_lock_irqsave(&tp->lock, flags);
-
 	/* handle link change and other phy events */
 	if (!(tp->tg3_flags &
 	      (TG3_FLAG_USE_LINKCHG_REG |
@@ -2896,7 +3131,9 @@ static int tg3_poll(struct net_device *n
 		if (sblk->status & SD_STATUS_LINK_CHG) {
 			sblk->status = SD_STATUS_UPDATED |
 				(sblk->status & ~SD_STATUS_LINK_CHG);
+			spin_lock(&tp->lock);
 			tg3_setup_phy(tp, 0);
+			spin_unlock(&tp->lock);
 		}
 	}
 
@@ -2907,8 +3144,6 @@ static int tg3_poll(struct net_device *n
 		spin_unlock(&tp->tx_lock);
 	}
 
-	spin_unlock_irqrestore(&tp->lock, flags);
-
 	/* run RX thread, within the bounds set by NAPI.
 	 * All RX "locking" is done by ensuring outside
 	 * code synchronizes with dev->poll()
@@ -2929,19 +3164,54 @@ static int tg3_poll(struct net_device *n
 	if (tp->tg3_flags & TG3_FLAG_TAGGED_STATUS)
 		tp->last_tag = sblk->status_tag;
 	rmb();
+	sblk->status &= ~SD_STATUS_UPDATED;
 
 	/* if no more work, tell net stack and NIC we're done */
 	done = !tg3_has_work(tp);
 	if (done) {
-		spin_lock_irqsave(&tp->lock, flags);
-		__netif_rx_complete(netdev);
+		spin_lock(&tp->lock);
+		netif_rx_complete(netdev);
 		tg3_restart_ints(tp);
-		spin_unlock_irqrestore(&tp->lock, flags);
+		spin_unlock(&tp->lock);
 	}
 
 	return (done ? 0 : 1);
 }
 
+static void tg3_irq_quiesce(struct tg3 *tp)
+{
+	BUG_ON(tp->irq_sync);
+
+	tp->irq_sync = 1;
+	smp_mb();
+
+	synchronize_irq(tp->pdev->irq);
+}
+
+static inline int tg3_irq_sync(struct tg3 *tp)
+{
+	return tp->irq_sync;
+}
+
+/* Fully shutdown all tg3 driver activity elsewhere in the system.
+ * If irq_sync is non-zero, then the IRQ handler must be synchronized
+ * with as well.  Most of the time, this is not necessary except when
+ * shutting down the device.
+ */
+static inline void tg3_full_lock(struct tg3 *tp, int irq_sync)
+{
+	if (irq_sync)
+		tg3_irq_quiesce(tp);
+	spin_lock_bh(&tp->lock);
+	spin_lock(&tp->tx_lock);
+}
+
+static inline void tg3_full_unlock(struct tg3 *tp)
+{
+	spin_unlock(&tp->tx_lock);
+	spin_unlock_bh(&tp->lock);
+}
+
 /* MSI ISR - No need to check for interrupt sharing and no need to
  * flush status block and interrupt mailbox. PCI ordering rules
  * guarantee that MSI will arrive after the status block.
@@ -2951,9 +3221,6 @@ static irqreturn_t tg3_msi(int irq, void
 	struct net_device *dev = dev_id;
 	struct tg3 *tp = netdev_priv(dev);
 	struct tg3_hw_status *sblk = tp->hw_status;
-	unsigned long flags;
-
-	spin_lock_irqsave(&tp->lock, flags);
 
 	/*
 	 * Writing any value to intr-mbox-0 clears PCI INTA# and
@@ -2964,6 +3231,9 @@ static irqreturn_t tg3_msi(int irq, void
 	 */
 	tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001);
 	tp->last_tag = sblk->status_tag;
+	rmb();
+	if (tg3_irq_sync(tp))
+		goto out;
 	sblk->status &= ~SD_STATUS_UPDATED;
 	if (likely(tg3_has_work(tp)))
 		netif_rx_schedule(dev);		/* schedule NAPI poll */
@@ -2972,9 +3242,7 @@ static irqreturn_t tg3_msi(int irq, void
 		tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
 			     tp->last_tag << 24);
 	}
-
-	spin_unlock_irqrestore(&tp->lock, flags);
-
+out:
 	return IRQ_RETVAL(1);
 }
 
@@ -2983,11 +3251,8 @@ static irqreturn_t tg3_interrupt(int irq
 	struct net_device *dev = dev_id;
 	struct tg3 *tp = netdev_priv(dev);
 	struct tg3_hw_status *sblk = tp->hw_status;
-	unsigned long flags;
 	unsigned int handled = 1;
 
-	spin_lock_irqsave(&tp->lock, flags);
-
 	/* In INTx mode, it is possible for the interrupt to arrive at
 	 * the CPU before the status block posted prior to the interrupt.
 	 * Reading the PCI State register will confirm whether the
@@ -3004,6 +3269,8 @@ static irqreturn_t tg3_interrupt(int irq
 		 */
 		tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
 			     0x00000001);
+		if (tg3_irq_sync(tp))
+			goto out;
 		sblk->status &= ~SD_STATUS_UPDATED;
 		if (likely(tg3_has_work(tp)))
 			netif_rx_schedule(dev);		/* schedule NAPI poll */
@@ -3018,9 +3285,7 @@ static irqreturn_t tg3_interrupt(int irq
 	} else {	/* shared interrupt */
 		handled = 0;
 	}
-
-	spin_unlock_irqrestore(&tp->lock, flags);
-
+out:
 	return IRQ_RETVAL(handled);
 }
 
@@ -3029,11 +3294,8 @@ static irqreturn_t tg3_interrupt_tagged(
 	struct net_device *dev = dev_id;
 	struct tg3 *tp = netdev_priv(dev);
 	struct tg3_hw_status *sblk = tp->hw_status;
-	unsigned long flags;
 	unsigned int handled = 1;
 
-	spin_lock_irqsave(&tp->lock, flags);
-
 	/* In INTx mode, it is possible for the interrupt to arrive at
 	 * the CPU before the status block posted prior to the interrupt.
 	 * Reading the PCI State register will confirm whether the
@@ -3051,6 +3313,9 @@ static irqreturn_t tg3_interrupt_tagged(
 		tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
 			     0x00000001);
 		tp->last_tag = sblk->status_tag;
+		rmb();
+		if (tg3_irq_sync(tp))
+			goto out;
 		sblk->status &= ~SD_STATUS_UPDATED;
 		if (likely(tg3_has_work(tp)))
 			netif_rx_schedule(dev);		/* schedule NAPI poll */
@@ -3065,9 +3330,7 @@ static irqreturn_t tg3_interrupt_tagged(
 	} else {	/* shared interrupt */
 		handled = 0;
 	}
-
-	spin_unlock_irqrestore(&tp->lock, flags);
-
+out:
 	return IRQ_RETVAL(handled);
 }
 
@@ -3106,8 +3369,7 @@ static void tg3_reset_task(void *_data)
 
 	tg3_netif_stop(tp);
 
-	spin_lock_irq(&tp->lock);
-	spin_lock(&tp->tx_lock);
+	tg3_full_lock(tp, 1);
 
 	restart_timer = tp->tg3_flags2 & TG3_FLG2_RESTART_TIMER;
 	tp->tg3_flags2 &= ~TG3_FLG2_RESTART_TIMER;
@@ -3117,8 +3379,7 @@ static void tg3_reset_task(void *_data)
 
 	tg3_netif_start(tp);
 
-	spin_unlock(&tp->tx_lock);
-	spin_unlock_irq(&tp->lock);
+	tg3_full_unlock(tp);
 
 	if (restart_timer)
 		mod_timer(&tp->timer, jiffies + 1);
@@ -3224,39 +3485,21 @@ static int tg3_start_xmit(struct sk_buff
 	unsigned int i;
 	u32 len, entry, base_flags, mss;
 	int would_hit_hwbug;
-	unsigned long flags;
 
 	len = skb_headlen(skb);
 
 	/* No BH disabling for tx_lock here.  We are running in BH disabled
 	 * context and TX reclaim runs via tp->poll inside of a software
-	 * interrupt.  Rejoice!
-	 *
-	 * Actually, things are not so simple.  If we are to take a hw
-	 * IRQ here, we can deadlock, consider:
-	 *
-	 *       CPU1		CPU2
-	 *   tg3_start_xmit
-	 *   take tp->tx_lock
-	 *			tg3_timer
-	 *			take tp->lock
-	 *   tg3_interrupt
-	 *   spin on tp->lock
-	 *			spin on tp->tx_lock
-	 *
-	 * So we really do need to disable interrupts when taking
-	 * tx_lock here.
+	 * interrupt.  Furthermore, IRQ processing runs lockless so we have
+	 * no IRQ context deadlocks to worry about either.  Rejoice!
 	 */
-	local_irq_save(flags);
-	if (!spin_trylock(&tp->tx_lock)) { 
-		local_irq_restore(flags);
+	if (!spin_trylock(&tp->tx_lock))
 		return NETDEV_TX_LOCKED; 
-	} 
 
 	/* This is a hard error, log it. */
 	if (unlikely(TX_BUFFS_AVAIL(tp) <= (skb_shinfo(skb)->nr_frags + 1))) {
 		netif_stop_queue(dev);
-		spin_unlock_irqrestore(&tp->tx_lock, flags);
+		spin_unlock(&tp->tx_lock);
 		printk(KERN_ERR PFX "%s: BUG! Tx Ring full when queue awake!\n",
 		       dev->name);
 		return NETDEV_TX_BUSY;
@@ -3421,7 +3664,7 @@ static int tg3_start_xmit(struct sk_buff
 
 out_unlock:
     	mmiowb();
-	spin_unlock_irqrestore(&tp->tx_lock, flags);
+	spin_unlock(&tp->tx_lock);
 
 	dev->trans_start = jiffies;
 
@@ -3433,10 +3676,18 @@ static inline void tg3_set_mtu(struct ne
 {
 	dev->mtu = new_mtu;
 
-	if (new_mtu > ETH_DATA_LEN)
-		tp->tg3_flags |= TG3_FLAG_JUMBO_ENABLE;
-	else
-		tp->tg3_flags &= ~TG3_FLAG_JUMBO_ENABLE;
+	if (new_mtu > ETH_DATA_LEN) {
+		if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780) {
+			tp->tg3_flags2 &= ~TG3_FLG2_TSO_CAPABLE;
+			ethtool_op_set_tso(dev, 0);
+		}
+		else
+			tp->tg3_flags |= TG3_FLAG_JUMBO_RING_ENABLE;
+	} else {
+		if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780)
+			tp->tg3_flags2 |= TG3_FLG2_TSO_CAPABLE;
+		tp->tg3_flags &= ~TG3_FLAG_JUMBO_RING_ENABLE;
+	}
 }
 
 static int tg3_change_mtu(struct net_device *dev, int new_mtu)
@@ -3455,8 +3706,8 @@ static int tg3_change_mtu(struct net_dev
 	}
 
 	tg3_netif_stop(tp);
-	spin_lock_irq(&tp->lock);
-	spin_lock(&tp->tx_lock);
+
+	tg3_full_lock(tp, 1);
 
 	tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
 
@@ -3466,8 +3717,7 @@ static int tg3_change_mtu(struct net_dev
 
 	tg3_netif_start(tp);
 
-	spin_unlock(&tp->tx_lock);
-	spin_unlock_irq(&tp->lock);
+	tg3_full_unlock(tp);
 
 	return 0;
 }
@@ -3491,7 +3741,7 @@ static void tg3_free_rings(struct tg3 *t
 			continue;
 		pci_unmap_single(tp->pdev,
 				 pci_unmap_addr(rxp, mapping),
-				 RX_PKT_BUF_SZ - tp->rx_offset,
+				 tp->rx_pkt_buf_sz - tp->rx_offset,
 				 PCI_DMA_FROMDEVICE);
 		dev_kfree_skb_any(rxp->skb);
 		rxp->skb = NULL;
@@ -3564,6 +3814,11 @@ static void tg3_init_rings(struct tg3 *t
 	memset(tp->rx_rcb, 0, TG3_RX_RCB_RING_BYTES(tp));
 	memset(tp->tx_ring, 0, TG3_TX_RING_BYTES);
 
+	tp->rx_pkt_buf_sz = RX_PKT_BUF_SZ;
+	if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780) &&
+	    (tp->dev->mtu > ETH_DATA_LEN))
+		tp->rx_pkt_buf_sz = RX_JUMBO_PKT_BUF_SZ;
+
 	/* Initialize invariants of the rings, we only set this
 	 * stuff once.  This works because the card does not
 	 * write into the rx buffer posting rings.
@@ -3572,14 +3827,14 @@ static void tg3_init_rings(struct tg3 *t
 		struct tg3_rx_buffer_desc *rxd;
 
 		rxd = &tp->rx_std[i];
-		rxd->idx_len = (RX_PKT_BUF_SZ - tp->rx_offset - 64)
+		rxd->idx_len = (tp->rx_pkt_buf_sz - tp->rx_offset - 64)
 			<< RXD_LEN_SHIFT;
 		rxd->type_flags = (RXD_FLAG_END << RXD_FLAGS_SHIFT);
 		rxd->opaque = (RXD_OPAQUE_RING_STD |
 			       (i << RXD_OPAQUE_INDEX_SHIFT));
 	}
 
-	if (tp->tg3_flags & TG3_FLAG_JUMBO_ENABLE) {
+	if (tp->tg3_flags & TG3_FLAG_JUMBO_RING_ENABLE) {
 		for (i = 0; i < TG3_RX_JUMBO_RING_SIZE; i++) {
 			struct tg3_rx_buffer_desc *rxd;
 
@@ -3600,7 +3855,7 @@ static void tg3_init_rings(struct tg3 *t
 			break;
 	}
 
-	if (tp->tg3_flags & TG3_FLAG_JUMBO_ENABLE) {
+	if (tp->tg3_flags & TG3_FLAG_JUMBO_RING_ENABLE) {
 		for (i = 0; i < tp->rx_jumbo_pending; i++) {
 			if (tg3_alloc_rx_skb(tp, RXD_OPAQUE_RING_JUMBO,
 					     -1, i) < 0)
@@ -4056,7 +4311,30 @@ static int tg3_chip_reset(struct tg3 *tp
 	val &= ~PCIX_CAPS_RELAXED_ORDERING;
 	pci_write_config_dword(tp->pdev, TG3PCI_X_CAPS, val);
 
-	tw32(MEMARB_MODE, MEMARB_MODE_ENABLE);
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780) {
+		u32 val;
+
+		/* Chip reset on 5780 will reset MSI enable bit,
+		 * so need to restore it.
+		 */
+		if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) {
+			u16 ctrl;
+
+			pci_read_config_word(tp->pdev,
+					     tp->msi_cap + PCI_MSI_FLAGS,
+					     &ctrl);
+			pci_write_config_word(tp->pdev,
+					      tp->msi_cap + PCI_MSI_FLAGS,
+					      ctrl | PCI_MSI_FLAGS_ENABLE);
+			val = tr32(MSGINT_MODE);
+			tw32(MSGINT_MODE, val | MSGINT_MODE_ENABLE);
+		}
+
+		val = tr32(MEMARB_MODE);
+		tw32(MEMARB_MODE, val | MEMARB_MODE_ENABLE);
+
+	} else
+		tw32(MEMARB_MODE, MEMARB_MODE_ENABLE);
 
 	if (tp->pci_chip_rev_id == CHIPREV_ID_5750_A3) {
 		tg3_stop_fw(tp);
@@ -4082,6 +4360,9 @@ static int tg3_chip_reset(struct tg3 *tp
 	if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) {
 		tp->mac_mode = MAC_MODE_PORT_MODE_TBI;
 		tw32_f(MAC_MODE, tp->mac_mode);
+	} else if (tp->tg3_flags2 & TG3_FLG2_MII_SERDES) {
+		tp->mac_mode = MAC_MODE_PORT_MODE_GMII;
+		tw32_f(MAC_MODE, tp->mac_mode);
 	} else
 		tw32_f(MAC_MODE, 0);
 	udelay(40);
@@ -5088,9 +5369,9 @@ static int tg3_set_mac_addr(struct net_d
 
 	memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
 
-	spin_lock_irq(&tp->lock);
+	spin_lock_bh(&tp->lock);
 	__tg3_set_mac_addr(tp);
-	spin_unlock_irq(&tp->lock);
+	spin_unlock_bh(&tp->lock);
 
 	return 0;
 }
@@ -5117,7 +5398,7 @@ static void tg3_set_bdinfo(struct tg3 *t
 }
 
 static void __tg3_set_rx_mode(struct net_device *);
-static void tg3_set_coalesce(struct tg3 *tp, struct ethtool_coalesce *ec)
+static void __tg3_set_coalesce(struct tg3 *tp, struct ethtool_coalesce *ec)
 {
 	tw32(HOSTCC_RXCOL_TICKS, ec->rx_coalesce_usecs);
 	tw32(HOSTCC_TXCOL_TICKS, ec->tx_coalesce_usecs);
@@ -5245,7 +5526,7 @@ static int tg3_reset_hw(struct tg3 *tp)
 	}
 #endif
 
-	if (!(tp->tg3_flags & TG3_FLAG_JUMBO_ENABLE)) {
+	if (tp->dev->mtu <= ETH_DATA_LEN) {
 		tw32(BUFMGR_MB_RDMA_LOW_WATER,
 		     tp->bufmgr_config.mbuf_read_dma_low_water);
 		tw32(BUFMGR_MB_MACRX_LOW_WATER,
@@ -5320,7 +5601,7 @@ static int tg3_reset_hw(struct tg3 *tp)
 		/* Setup replenish threshold. */
 		tw32(RCVBDI_JUMBO_THRESH, tp->rx_jumbo_pending / 8);
 
-		if (tp->tg3_flags & TG3_FLAG_JUMBO_ENABLE) {
+		if (tp->tg3_flags & TG3_FLAG_JUMBO_RING_ENABLE) {
 			tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_HOST_ADDR + TG3_64BIT_REG_HIGH,
 			     ((u64) tp->rx_jumbo_mapping >> 32));
 			tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_HOST_ADDR + TG3_64BIT_REG_LOW,
@@ -5381,7 +5662,7 @@ static int tg3_reset_hw(struct tg3 *tp)
 	tw32_rx_mbox(MAILBOX_RCV_STD_PROD_IDX + TG3_64BIT_REG_LOW,
 		     tp->rx_std_ptr);
 
-	tp->rx_jumbo_ptr = (tp->tg3_flags & TG3_FLAG_JUMBO_ENABLE) ?
+	tp->rx_jumbo_ptr = (tp->tg3_flags & TG3_FLAG_JUMBO_RING_ENABLE) ?
 						tp->rx_jumbo_pending : 0;
 	tw32_rx_mbox(MAILBOX_RCV_JUMBO_PROD_IDX + TG3_64BIT_REG_LOW,
 		     tp->rx_jumbo_ptr);
@@ -5460,7 +5741,7 @@ static int tg3_reset_hw(struct tg3 *tp)
 		udelay(10);
 	}
 
-	tg3_set_coalesce(tp, &tp->coal);
+	__tg3_set_coalesce(tp, &tp->coal);
 
 	/* set status block DMA address */
 	tw32(HOSTCC_STATUS_BLK_HOST_ADDR + TG3_64BIT_REG_HIGH,
@@ -5683,7 +5964,8 @@ static int tg3_reset_hw(struct tg3 *tp)
 	tw32(MAC_RCV_RULE_1,  0x86000004 & RCV_RULE_DISABLE_MASK);
 	tw32(MAC_RCV_VALUE_1, 0xffffffff & RCV_RULE_DISABLE_MASK);
 
-	if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS)
+	if ((tp->tg3_flags2 & TG3_FLG2_5705_PLUS) &&
+	    (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5780))
 		limit = 8;
 	else
 		limit = 16;
@@ -5727,9 +6009,6 @@ static int tg3_reset_hw(struct tg3 *tp)
 
 	tg3_write_sig_post_reset(tp, RESET_KIND_INIT);
 
-	if (tp->tg3_flags & TG3_FLAG_INIT_COMPLETE)
-		tg3_enable_ints(tp);
-
 	return 0;
 }
 
@@ -5802,10 +6081,8 @@ static void tg3_periodic_fetch_stats(str
 static void tg3_timer(unsigned long __opaque)
 {
 	struct tg3 *tp = (struct tg3 *) __opaque;
-	unsigned long flags;
 
-	spin_lock_irqsave(&tp->lock, flags);
-	spin_lock(&tp->tx_lock);
+	spin_lock(&tp->lock);
 
 	if (!(tp->tg3_flags & TG3_FLAG_TAGGED_STATUS)) {
 		/* All of this garbage is because when using non-tagged
@@ -5822,8 +6099,7 @@ static void tg3_timer(unsigned long __op
 
 		if (!(tr32(WDMAC_MODE) & WDMAC_MODE_ENABLE)) {
 			tp->tg3_flags2 |= TG3_FLG2_RESTART_TIMER;
-			spin_unlock(&tp->tx_lock);
-			spin_unlock_irqrestore(&tp->lock, flags);
+			spin_unlock(&tp->lock);
 			schedule_work(&tp->reset_task);
 			return;
 		}
@@ -5871,7 +6147,8 @@ static void tg3_timer(unsigned long __op
 				udelay(40);
 				tg3_setup_phy(tp, 0);
 			}
-		}
+		} else if (tp->tg3_flags2 & TG3_FLG2_MII_SERDES)
+			tg3_serdes_parallel_detect(tp);
 
 		tp->timer_counter = tp->timer_multiplier;
 	}
@@ -5891,8 +6168,7 @@ static void tg3_timer(unsigned long __op
 		tp->asf_counter = tp->asf_multiplier;
 	}
 
-	spin_unlock(&tp->tx_lock);
-	spin_unlock_irqrestore(&tp->lock, flags);
+	spin_unlock(&tp->lock);
 
 	tp->timer.expires = jiffies + tp->timer_offset;
 	add_timer(&tp->timer);
@@ -6007,14 +6283,12 @@ static int tg3_test_msi(struct tg3 *tp)
 	/* Need to reset the chip because the MSI cycle may have terminated
 	 * with Master Abort.
 	 */
-	spin_lock_irq(&tp->lock);
-	spin_lock(&tp->tx_lock);
+	tg3_full_lock(tp, 1);
 
 	tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
 	err = tg3_init_hw(tp);
 
-	spin_unlock(&tp->tx_lock);
-	spin_unlock_irq(&tp->lock);
+	tg3_full_unlock(tp);
 
 	if (err)
 		free_irq(tp->pdev->irq, dev);
@@ -6027,14 +6301,12 @@ static int tg3_open(struct net_device *d
 	struct tg3 *tp = netdev_priv(dev);
 	int err;
 
-	spin_lock_irq(&tp->lock);
-	spin_lock(&tp->tx_lock);
+	tg3_full_lock(tp, 0);
 
 	tg3_disable_ints(tp);
 	tp->tg3_flags &= ~TG3_FLAG_INIT_COMPLETE;
 
-	spin_unlock(&tp->tx_lock);
-	spin_unlock_irq(&tp->lock);
+	tg3_full_unlock(tp);
 
 	/* The placement of this call is tied
 	 * to the setup and use of Host TX descriptors.
@@ -6081,8 +6353,7 @@ static int tg3_open(struct net_device *d
 		return err;
 	}
 
-	spin_lock_irq(&tp->lock);
-	spin_lock(&tp->tx_lock);
+	tg3_full_lock(tp, 0);
 
 	err = tg3_init_hw(tp);
 	if (err) {
@@ -6106,8 +6377,7 @@ static int tg3_open(struct net_device *d
 		tp->timer.function = tg3_timer;
 	}
 
-	spin_unlock(&tp->tx_lock);
-	spin_unlock_irq(&tp->lock);
+	tg3_full_unlock(tp);
 
 	if (err) {
 		free_irq(tp->pdev->irq, dev);
@@ -6123,8 +6393,7 @@ static int tg3_open(struct net_device *d
 		err = tg3_test_msi(tp);
 
 		if (err) {
-			spin_lock_irq(&tp->lock);
-			spin_lock(&tp->tx_lock);
+			tg3_full_lock(tp, 0);
 
 			if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) {
 				pci_disable_msi(tp->pdev);
@@ -6134,22 +6403,19 @@ static int tg3_open(struct net_device *d
 			tg3_free_rings(tp);
 			tg3_free_consistent(tp);
 
-			spin_unlock(&tp->tx_lock);
-			spin_unlock_irq(&tp->lock);
+			tg3_full_unlock(tp);
 
 			return err;
 		}
 	}
 
-	spin_lock_irq(&tp->lock);
-	spin_lock(&tp->tx_lock);
+	tg3_full_lock(tp, 0);
 
 	add_timer(&tp->timer);
 	tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE;
 	tg3_enable_ints(tp);
 
-	spin_unlock(&tp->tx_lock);
-	spin_unlock_irq(&tp->lock);
+	tg3_full_unlock(tp);
 
 	netif_start_queue(dev);
 
@@ -6395,8 +6661,7 @@ static int tg3_close(struct net_device *
 
 	del_timer_sync(&tp->timer);
 
-	spin_lock_irq(&tp->lock);
-	spin_lock(&tp->tx_lock);
+	tg3_full_lock(tp, 1);
 #if 0
 	tg3_dump_state(tp);
 #endif
@@ -6410,8 +6675,7 @@ static int tg3_close(struct net_device *
 		  TG3_FLAG_GOT_SERDES_FLOWCTL);
 	netif_carrier_off(tp->dev);
 
-	spin_unlock(&tp->tx_lock);
-	spin_unlock_irq(&tp->lock);
+	tg3_full_unlock(tp);
 
 	free_irq(tp->pdev->irq, dev);
 	if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) {
@@ -6448,16 +6712,15 @@ static unsigned long calc_crc_errors(str
 	if (!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) &&
 	    (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 ||
 	     GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701)) {
-		unsigned long flags;
 		u32 val;
 
-		spin_lock_irqsave(&tp->lock, flags);
+		spin_lock_bh(&tp->lock);
 		if (!tg3_readphy(tp, 0x1e, &val)) {
 			tg3_writephy(tp, 0x1e, val | 0x8000);
 			tg3_readphy(tp, 0x14, &val);
 		} else
 			val = 0;
-		spin_unlock_irqrestore(&tp->lock, flags);
+		spin_unlock_bh(&tp->lock);
 
 		tp->phy_crc_errors += val;
 
@@ -6719,11 +6982,9 @@ static void tg3_set_rx_mode(struct net_d
 {
 	struct tg3 *tp = netdev_priv(dev);
 
-	spin_lock_irq(&tp->lock);
-	spin_lock(&tp->tx_lock);
+	tg3_full_lock(tp, 0);
 	__tg3_set_rx_mode(dev);
-	spin_unlock(&tp->tx_lock);
-	spin_unlock_irq(&tp->lock);
+	tg3_full_unlock(tp);
 }
 
 #define TG3_REGDUMP_LEN		(32 * 1024)
@@ -6745,8 +7006,7 @@ static void tg3_get_regs(struct net_devi
 
 	memset(p, 0, TG3_REGDUMP_LEN);
 
-	spin_lock_irq(&tp->lock);
-	spin_lock(&tp->tx_lock);
+	tg3_full_lock(tp, 0);
 
 #define __GET_REG32(reg)	(*(p)++ = tr32(reg))
 #define GET_REG32_LOOP(base,len)		\
@@ -6796,8 +7056,7 @@ do {	p = (u32 *)(orig_p + (reg));		\
 #undef GET_REG32_LOOP
 #undef GET_REG32_1
 
-	spin_unlock(&tp->tx_lock);
-	spin_unlock_irq(&tp->lock);
+	tg3_full_unlock(tp);
 }
 
 static int tg3_get_eeprom_len(struct net_device *dev)
@@ -6973,8 +7232,7 @@ static int tg3_set_settings(struct net_d
 			return -EINVAL;
 	}
 
-	spin_lock_irq(&tp->lock);
-	spin_lock(&tp->tx_lock);
+	tg3_full_lock(tp, 0);
 
 	tp->link_config.autoneg = cmd->autoneg;
 	if (cmd->autoneg == AUTONEG_ENABLE) {
@@ -6990,8 +7248,7 @@ static int tg3_set_settings(struct net_d
 	if (netif_running(dev))
 		tg3_setup_phy(tp, 1);
 
-	spin_unlock(&tp->tx_lock);
-	spin_unlock_irq(&tp->lock);
+	tg3_full_unlock(tp);
   
 	return 0;
 }
@@ -7027,12 +7284,12 @@ static int tg3_set_wol(struct net_device
 	    !(tp->tg3_flags & TG3_FLAG_SERDES_WOL_CAP))
 		return -EINVAL;
   
-	spin_lock_irq(&tp->lock);
+	spin_lock_bh(&tp->lock);
 	if (wol->wolopts & WAKE_MAGIC)
 		tp->tg3_flags |= TG3_FLAG_WOL_ENABLE;
 	else
 		tp->tg3_flags &= ~TG3_FLAG_WOL_ENABLE;
-	spin_unlock_irq(&tp->lock);
+	spin_unlock_bh(&tp->lock);
   
 	return 0;
 }
@@ -7072,7 +7329,7 @@ static int tg3_nway_reset(struct net_dev
 	if (!netif_running(dev))
 		return -EAGAIN;
 
-	spin_lock_irq(&tp->lock);
+	spin_lock_bh(&tp->lock);
 	r = -EINVAL;
 	tg3_readphy(tp, MII_BMCR, &bmcr);
 	if (!tg3_readphy(tp, MII_BMCR, &bmcr) &&
@@ -7080,7 +7337,7 @@ static int tg3_nway_reset(struct net_dev
 		tg3_writephy(tp, MII_BMCR, bmcr | BMCR_ANRESTART);
 		r = 0;
 	}
-	spin_unlock_irq(&tp->lock);
+	spin_unlock_bh(&tp->lock);
   
 	return r;
 }
@@ -7102,17 +7359,19 @@ static void tg3_get_ringparam(struct net
 static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *ering)
 {
 	struct tg3 *tp = netdev_priv(dev);
+	int irq_sync = 0;
   
 	if ((ering->rx_pending > TG3_RX_RING_SIZE - 1) ||
 	    (ering->rx_jumbo_pending > TG3_RX_JUMBO_RING_SIZE - 1) ||
 	    (ering->tx_pending > TG3_TX_RING_SIZE - 1))
 		return -EINVAL;
   
-	if (netif_running(dev))
+	if (netif_running(dev)) {
 		tg3_netif_stop(tp);
+		irq_sync = 1;
+	}
 
-	spin_lock_irq(&tp->lock);
-	spin_lock(&tp->tx_lock);
+	tg3_full_lock(tp, irq_sync);
   
 	tp->rx_pending = ering->rx_pending;
 
@@ -7128,8 +7387,7 @@ static int tg3_set_ringparam(struct net_
 		tg3_netif_start(tp);
 	}
 
-	spin_unlock(&tp->tx_lock);
-	spin_unlock_irq(&tp->lock);
+	tg3_full_unlock(tp);
   
 	return 0;
 }
@@ -7146,12 +7404,15 @@ static void tg3_get_pauseparam(struct ne
 static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause)
 {
 	struct tg3 *tp = netdev_priv(dev);
+	int irq_sync = 0;
   
-	if (netif_running(dev))
+	if (netif_running(dev)) {
 		tg3_netif_stop(tp);
+		irq_sync = 1;
+	}
+
+	tg3_full_lock(tp, irq_sync);
 
-	spin_lock_irq(&tp->lock);
-	spin_lock(&tp->tx_lock);
 	if (epause->autoneg)
 		tp->tg3_flags |= TG3_FLAG_PAUSE_AUTONEG;
 	else
@@ -7170,8 +7431,8 @@ static int tg3_set_pauseparam(struct net
 		tg3_init_hw(tp);
 		tg3_netif_start(tp);
 	}
-	spin_unlock(&tp->tx_lock);
-	spin_unlock_irq(&tp->lock);
+
+	tg3_full_unlock(tp);
   
 	return 0;
 }
@@ -7192,12 +7453,12 @@ static int tg3_set_rx_csum(struct net_de
   		return 0;
   	}
   
-	spin_lock_irq(&tp->lock);
+	spin_lock_bh(&tp->lock);
 	if (data)
 		tp->tg3_flags |= TG3_FLAG_RX_CHECKSUMS;
 	else
 		tp->tg3_flags &= ~TG3_FLAG_RX_CHECKSUMS;
-	spin_unlock_irq(&tp->lock);
+	spin_unlock_bh(&tp->lock);
   
 	return 0;
 }
@@ -7604,10 +7865,6 @@ static int tg3_test_loopback(struct tg3 
 
 	err = -EIO;
 
-	tg3_abort_hw(tp, 1);
-
-	/* Clearing this flag to keep interrupts disabled */
-	tp->tg3_flags &= ~TG3_FLAG_INIT_COMPLETE;
 	tg3_reset_hw(tp);
 
 	mac_mode = (tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK) |
@@ -7716,11 +7973,14 @@ static void tg3_self_test(struct net_dev
 		data[1] = 1;
 	}
 	if (etest->flags & ETH_TEST_FL_OFFLINE) {
-		if (netif_running(dev))
+		int irq_sync = 0;
+
+		if (netif_running(dev)) {
 			tg3_netif_stop(tp);
+			irq_sync = 1;
+		}
 
-		spin_lock_irq(&tp->lock);
-		spin_lock(&tp->tx_lock);
+		tg3_full_lock(tp, irq_sync);
 
 		tg3_halt(tp, RESET_KIND_SUSPEND, 1);
 		tg3_nvram_lock(tp);
@@ -7742,14 +8002,14 @@ static void tg3_self_test(struct net_dev
 			data[4] = 1;
 		}
 
-		spin_unlock(&tp->tx_lock);
-		spin_unlock_irq(&tp->lock);
+		tg3_full_unlock(tp);
+
 		if (tg3_test_interrupt(tp) != 0) {
 			etest->flags |= ETH_TEST_FL_FAILED;
 			data[5] = 1;
 		}
-		spin_lock_irq(&tp->lock);
-		spin_lock(&tp->tx_lock);
+
+		tg3_full_lock(tp, 0);
 
 		tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
 		if (netif_running(dev)) {
@@ -7757,8 +8017,8 @@ static void tg3_self_test(struct net_dev
 			tg3_init_hw(tp);
 			tg3_netif_start(tp);
 		}
-		spin_unlock(&tp->tx_lock);
-		spin_unlock_irq(&tp->lock);
+
+		tg3_full_unlock(tp);
 	}
 }
 
@@ -7779,9 +8039,9 @@ static int tg3_ioctl(struct net_device *
 		if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)
 			break;			/* We have no PHY */
 
-		spin_lock_irq(&tp->lock);
+		spin_lock_bh(&tp->lock);
 		err = tg3_readphy(tp, data->reg_num & 0x1f, &mii_regval);
-		spin_unlock_irq(&tp->lock);
+		spin_unlock_bh(&tp->lock);
 
 		data->val_out = mii_regval;
 
@@ -7795,9 +8055,9 @@ static int tg3_ioctl(struct net_device *
 		if (!capable(CAP_NET_ADMIN))
 			return -EPERM;
 
-		spin_lock_irq(&tp->lock);
+		spin_lock_bh(&tp->lock);
 		err = tg3_writephy(tp, data->reg_num & 0x1f, data->val_in);
-		spin_unlock_irq(&tp->lock);
+		spin_unlock_bh(&tp->lock);
 
 		return err;
 
@@ -7813,28 +8073,24 @@ static void tg3_vlan_rx_register(struct 
 {
 	struct tg3 *tp = netdev_priv(dev);
 
-	spin_lock_irq(&tp->lock);
-	spin_lock(&tp->tx_lock);
+	tg3_full_lock(tp, 0);
 
 	tp->vlgrp = grp;
 
 	/* Update RX_MODE_KEEP_VLAN_TAG bit in RX_MODE register. */
 	__tg3_set_rx_mode(dev);
 
-	spin_unlock(&tp->tx_lock);
-	spin_unlock_irq(&tp->lock);
+	tg3_full_unlock(tp);
 }
 
 static void tg3_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
 {
 	struct tg3 *tp = netdev_priv(dev);
 
-	spin_lock_irq(&tp->lock);
-	spin_lock(&tp->tx_lock);
+	tg3_full_lock(tp, 0);
 	if (tp->vlgrp)
 		tp->vlgrp->vlan_devices[vid] = NULL;
-	spin_unlock(&tp->tx_lock);
-	spin_unlock_irq(&tp->lock);
+	tg3_full_unlock(tp);
 }
 #endif
 
@@ -7846,6 +8102,60 @@ static int tg3_get_coalesce(struct net_d
 	return 0;
 }
 
+static int tg3_set_coalesce(struct net_device *dev, struct ethtool_coalesce *ec)
+{
+	struct tg3 *tp = netdev_priv(dev);
+	u32 max_rxcoal_tick_int = 0, max_txcoal_tick_int = 0;
+	u32 max_stat_coal_ticks = 0, min_stat_coal_ticks = 0;
+
+	if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) {
+		max_rxcoal_tick_int = MAX_RXCOAL_TICK_INT;
+		max_txcoal_tick_int = MAX_TXCOAL_TICK_INT;
+		max_stat_coal_ticks = MAX_STAT_COAL_TICKS;
+		min_stat_coal_ticks = MIN_STAT_COAL_TICKS;
+	}
+
+	if ((ec->rx_coalesce_usecs > MAX_RXCOL_TICKS) ||
+	    (ec->tx_coalesce_usecs > MAX_TXCOL_TICKS) ||
+	    (ec->rx_max_coalesced_frames > MAX_RXMAX_FRAMES) ||
+	    (ec->tx_max_coalesced_frames > MAX_TXMAX_FRAMES) ||
+	    (ec->rx_coalesce_usecs_irq > max_rxcoal_tick_int) ||
+	    (ec->tx_coalesce_usecs_irq > max_txcoal_tick_int) ||
+	    (ec->rx_max_coalesced_frames_irq > MAX_RXCOAL_MAXF_INT) ||
+	    (ec->tx_max_coalesced_frames_irq > MAX_TXCOAL_MAXF_INT) ||
+	    (ec->stats_block_coalesce_usecs > max_stat_coal_ticks) ||
+	    (ec->stats_block_coalesce_usecs < min_stat_coal_ticks))
+		return -EINVAL;
+
+	/* No rx interrupts will be generated if both are zero */
+	if ((ec->rx_coalesce_usecs == 0) &&
+	    (ec->rx_max_coalesced_frames == 0))
+		return -EINVAL;
+
+	/* No tx interrupts will be generated if both are zero */
+	if ((ec->tx_coalesce_usecs == 0) &&
+	    (ec->tx_max_coalesced_frames == 0))
+		return -EINVAL;
+
+	/* Only copy relevant parameters, ignore all others. */
+	tp->coal.rx_coalesce_usecs = ec->rx_coalesce_usecs;
+	tp->coal.tx_coalesce_usecs = ec->tx_coalesce_usecs;
+	tp->coal.rx_max_coalesced_frames = ec->rx_max_coalesced_frames;
+	tp->coal.tx_max_coalesced_frames = ec->tx_max_coalesced_frames;
+	tp->coal.rx_coalesce_usecs_irq = ec->rx_coalesce_usecs_irq;
+	tp->coal.tx_coalesce_usecs_irq = ec->tx_coalesce_usecs_irq;
+	tp->coal.rx_max_coalesced_frames_irq = ec->rx_max_coalesced_frames_irq;
+	tp->coal.tx_max_coalesced_frames_irq = ec->tx_max_coalesced_frames_irq;
+	tp->coal.stats_block_coalesce_usecs = ec->stats_block_coalesce_usecs;
+
+	if (netif_running(dev)) {
+		tg3_full_lock(tp, 0);
+		__tg3_set_coalesce(tp, &tp->coal);
+		tg3_full_unlock(tp);
+	}
+	return 0;
+}
+
 static struct ethtool_ops tg3_ethtool_ops = {
 	.get_settings		= tg3_get_settings,
 	.set_settings		= tg3_set_settings,
@@ -7881,6 +8191,7 @@ static struct ethtool_ops tg3_ethtool_op
 	.get_stats_count	= tg3_get_stats_count,
 	.get_ethtool_stats	= tg3_get_ethtool_stats,
 	.get_coalesce		= tg3_get_coalesce,
+	.set_coalesce		= tg3_set_coalesce,
 };
 
 static void __devinit tg3_get_eeprom_size(struct tg3 *tp)
@@ -8539,8 +8850,12 @@ static void __devinit tg3_get_eeprom_hw_
 			eeprom_phy_id = 0;
 
 		tp->phy_id = eeprom_phy_id;
-		if (eeprom_phy_serdes)
-			tp->tg3_flags2 |= TG3_FLG2_PHY_SERDES;
+		if (eeprom_phy_serdes) {
+			if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780)
+				tp->tg3_flags2 |= TG3_FLG2_MII_SERDES;
+			else
+				tp->tg3_flags2 |= TG3_FLG2_PHY_SERDES;
+		}
 
 		if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS)
 			led_cfg = cfg2 & (NIC_SRAM_DATA_CFG_LED_MODE_MASK |
@@ -8653,6 +8968,8 @@ static int __devinit tg3_phy_probe(struc
 		tp->phy_id = hw_phy_id;
 		if (hw_phy_id_masked == PHY_ID_BCM8002)
 			tp->tg3_flags2 |= TG3_FLG2_PHY_SERDES;
+		else
+			tp->tg3_flags2 &= ~TG3_FLG2_PHY_SERDES;
 	} else {
 		if (tp->phy_id != PHY_ID_INVALID) {
 			/* Do nothing, phy ID already set up in
@@ -8675,7 +8992,7 @@ static int __devinit tg3_phy_probe(struc
 		}
 	}
 
-	if (!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) &&
+	if (!(tp->tg3_flags2 & TG3_FLG2_ANY_SERDES) &&
 	    !(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) {
 		u32 bmsr, adv_reg, tg3_ctrl;
 
@@ -8728,7 +9045,7 @@ skip_phy_reset:
 		err = tg3_init_5401phy_dsp(tp);
 	}
 
-	if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)
+	if (tp->tg3_flags2 & TG3_FLG2_ANY_SERDES)
 		tp->link_config.advertising =
 			(ADVERTISED_1000baseT_Half |
 			 ADVERTISED_1000baseT_Full |
@@ -8898,6 +9215,10 @@ static int __devinit tg3_get_invariants(
 	if (tp->pci_chip_rev_id == CHIPREV_ID_5752_A0_HW)
 		tp->pci_chip_rev_id = CHIPREV_ID_5752_A0;
 
+	/* Find msi capability. */
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780)
+		tp->msi_cap = pci_find_capability(tp->pdev, PCI_CAP_ID_MSI);
+
 	/* Initialize misc host control in PCI block. */
 	tp->misc_host_ctrl |= (misc_ctrl_reg &
 			       MISC_HOST_CTRL_CHIPREV);
@@ -8913,7 +9234,8 @@ static int __devinit tg3_get_invariants(
 	tp->pci_bist         = (cacheline_sz_reg >> 24) & 0xff;
 
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750 ||
-	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752)
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752 ||
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780)
 		tp->tg3_flags2 |= TG3_FLG2_5750_PLUS;
 
 	if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) ||
@@ -8923,6 +9245,11 @@ static int __devinit tg3_get_invariants(
 	if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS)
 		tp->tg3_flags2 |= TG3_FLG2_HW_TSO;
 
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705 &&
+	    GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5750 &&
+	    GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5752)
+		tp->tg3_flags2 |= TG3_FLG2_JUMBO_CAPABLE;
+
 	if (pci_find_capability(tp->pdev, PCI_CAP_ID_EXP) != 0)
 		tp->tg3_flags2 |= TG3_FLG2_PCI_EXPRESS;
 
@@ -9049,8 +9376,9 @@ static int __devinit tg3_get_invariants(
 	/* Derive initial jumbo mode from MTU assigned in
 	 * ether_setup() via the alloc_etherdev() call
 	 */
-	if (tp->dev->mtu > ETH_DATA_LEN)
-		tp->tg3_flags |= TG3_FLAG_JUMBO_ENABLE;
+	if (tp->dev->mtu > ETH_DATA_LEN &&
+	    GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5780)
+		tp->tg3_flags |= TG3_FLAG_JUMBO_RING_ENABLE;
 
 	/* Determine WakeOnLan speed to use. */
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 ||
@@ -9066,7 +9394,8 @@ static int __devinit tg3_get_invariants(
 	if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700) ||
 	    ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) &&
 	     (tp->pci_chip_rev_id != CHIPREV_ID_5705_A0) &&
-	     (tp->pci_chip_rev_id != CHIPREV_ID_5705_A1)))
+	     (tp->pci_chip_rev_id != CHIPREV_ID_5705_A1)) ||
+	    (tp->tg3_flags2 & TG3_FLG2_ANY_SERDES))
 		tp->tg3_flags2 |= TG3_FLG2_NO_ETH_WIRE_SPEED;
 
 	if (GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5703_AX ||
@@ -9275,8 +9604,9 @@ static int __devinit tg3_get_device_addr
 #endif
 
 	mac_offset = 0x7c;
-	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 &&
-	    !(tp->tg3_flags & TG3_FLG2_SUN_570X)) {
+	if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 &&
+	     !(tp->tg3_flags & TG3_FLG2_SUN_570X)) ||
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780) {
 		if (tr32(TG3PCI_DUAL_MAC_CTRL) & DUAL_MAC_CTRL_ID)
 			mac_offset = 0xcc;
 		if (tg3_nvram_lock(tp))
@@ -9590,6 +9920,9 @@ static int __devinit tg3_test_dma(struct
 
 			/* Set bit 23 to enable PCIX hw bug fix */
 			tp->dma_rwctrl |= 0x009f0000;
+		} else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780) {
+			/* 5780 always in PCIX mode */
+			tp->dma_rwctrl |= 0x00144000;
 		} else {
 			tp->dma_rwctrl |= 0x001b000f;
 		}
@@ -9743,19 +10076,35 @@ static void __devinit tg3_init_link_conf
 
 static void __devinit tg3_init_bufmgr_config(struct tg3 *tp)
 {
-	tp->bufmgr_config.mbuf_read_dma_low_water =
-		DEFAULT_MB_RDMA_LOW_WATER;
-	tp->bufmgr_config.mbuf_mac_rx_low_water =
-		DEFAULT_MB_MACRX_LOW_WATER;
-	tp->bufmgr_config.mbuf_high_water =
-		DEFAULT_MB_HIGH_WATER;
-
-	tp->bufmgr_config.mbuf_read_dma_low_water_jumbo =
-		DEFAULT_MB_RDMA_LOW_WATER_JUMBO;
-	tp->bufmgr_config.mbuf_mac_rx_low_water_jumbo =
-		DEFAULT_MB_MACRX_LOW_WATER_JUMBO;
-	tp->bufmgr_config.mbuf_high_water_jumbo =
-		DEFAULT_MB_HIGH_WATER_JUMBO;
+	if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) {
+		tp->bufmgr_config.mbuf_read_dma_low_water =
+			DEFAULT_MB_RDMA_LOW_WATER_5705;
+		tp->bufmgr_config.mbuf_mac_rx_low_water =
+			DEFAULT_MB_MACRX_LOW_WATER_5705;
+		tp->bufmgr_config.mbuf_high_water =
+			DEFAULT_MB_HIGH_WATER_5705;
+
+		tp->bufmgr_config.mbuf_read_dma_low_water_jumbo =
+			DEFAULT_MB_RDMA_LOW_WATER_JUMBO_5780;
+		tp->bufmgr_config.mbuf_mac_rx_low_water_jumbo =
+			DEFAULT_MB_MACRX_LOW_WATER_JUMBO_5780;
+		tp->bufmgr_config.mbuf_high_water_jumbo =
+			DEFAULT_MB_HIGH_WATER_JUMBO_5780;
+	} else {
+		tp->bufmgr_config.mbuf_read_dma_low_water =
+			DEFAULT_MB_RDMA_LOW_WATER;
+		tp->bufmgr_config.mbuf_mac_rx_low_water =
+			DEFAULT_MB_MACRX_LOW_WATER;
+		tp->bufmgr_config.mbuf_high_water =
+			DEFAULT_MB_HIGH_WATER;
+
+		tp->bufmgr_config.mbuf_read_dma_low_water_jumbo =
+			DEFAULT_MB_RDMA_LOW_WATER_JUMBO;
+		tp->bufmgr_config.mbuf_mac_rx_low_water_jumbo =
+			DEFAULT_MB_MACRX_LOW_WATER_JUMBO;
+		tp->bufmgr_config.mbuf_high_water_jumbo =
+			DEFAULT_MB_HIGH_WATER_JUMBO;
+	}
 
 	tp->bufmgr_config.dma_low_water = DEFAULT_DMA_LOW_WATER;
 	tp->bufmgr_config.dma_high_water = DEFAULT_DMA_HIGH_WATER;
@@ -9773,6 +10122,7 @@ static char * __devinit tg3_phy_string(s
 	case PHY_ID_BCM5705:	return "5705";
 	case PHY_ID_BCM5750:	return "5750";
 	case PHY_ID_BCM5752:	return "5752";
+	case PHY_ID_BCM5780:	return "5780";
 	case PHY_ID_BCM8002:	return "8002/serdes";
 	case 0:			return "serdes";
 	default:		return "unknown";
@@ -9825,6 +10175,12 @@ static void __devinit tg3_init_coal(stru
 		ec->tx_coalesce_usecs = LOW_TXCOL_TICKS_CLRTCKS;
 		ec->tx_coalesce_usecs_irq = DEFAULT_TXCOAL_TICK_INT_CLRTCKS;
 	}
+
+	if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) {
+		ec->rx_coalesce_usecs_irq = 0;
+		ec->tx_coalesce_usecs_irq = 0;
+		ec->stats_block_coalesce_usecs = 0;
+	}
 }
 
 static int __devinit tg3_init_one(struct pci_dev *pdev,
@@ -9962,8 +10318,6 @@ static int __devinit tg3_init_one(struct
 
 	tg3_init_link_config(tp);
 
-	tg3_init_bufmgr_config(tp);
-
 	tp->rx_pending = TG3_DEF_RX_RING_PENDING;
 	tp->rx_jumbo_pending = TG3_DEF_RX_JUMBO_RING_PENDING;
 	tp->tx_pending = TG3_DEF_TX_RING_PENDING;
@@ -9992,14 +10346,7 @@ static int __devinit tg3_init_one(struct
 		goto err_out_iounmap;
 	}
 
-	if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) {
-		tp->bufmgr_config.mbuf_read_dma_low_water =
-			DEFAULT_MB_RDMA_LOW_WATER_5705;
-		tp->bufmgr_config.mbuf_mac_rx_low_water =
-			DEFAULT_MB_MACRX_LOW_WATER_5705;
-		tp->bufmgr_config.mbuf_high_water =
-			DEFAULT_MB_HIGH_WATER_5705;
-	}
+	tg3_init_bufmgr_config(tp);
 
 #if TG3_TSO_SUPPORT != 0
 	if (tp->tg3_flags2 & TG3_FLG2_HW_TSO) {
@@ -10074,6 +10421,12 @@ static int __devinit tg3_init_one(struct
 
 	tg3_init_coal(tp);
 
+	/* Now that we have fully setup the chip, save away a snapshot
+	 * of the PCI config space.  We need to restore this after
+	 * GRC_MISC_CFG core clock resets and some resume events.
+	 */
+	pci_save_state(tp->pdev);
+
 	err = register_netdev(dev);
 	if (err) {
 		printk(KERN_ERR PFX "Cannot register net device, "
@@ -10083,12 +10436,6 @@ static int __devinit tg3_init_one(struct
 
 	pci_set_drvdata(pdev, dev);
 
-	/* Now that we have fully setup the chip, save away a snapshot
-	 * of the PCI config space.  We need to restore this after
-	 * GRC_MISC_CFG core clock resets and some resume events.
-	 */
-	pci_save_state(tp->pdev);
-
 	printk(KERN_INFO "%s: Tigon3 [partno(%s) rev %04x PHY(%s)] (PCI%s:%s:%s) %sBaseT Ethernet ",
 	       dev->name,
 	       tp->board_part_number,
@@ -10165,24 +10512,19 @@ static int tg3_suspend(struct pci_dev *p
 
 	del_timer_sync(&tp->timer);
 
-	spin_lock_irq(&tp->lock);
-	spin_lock(&tp->tx_lock);
+	tg3_full_lock(tp, 1);
 	tg3_disable_ints(tp);
-	spin_unlock(&tp->tx_lock);
-	spin_unlock_irq(&tp->lock);
+	tg3_full_unlock(tp);
 
 	netif_device_detach(dev);
 
-	spin_lock_irq(&tp->lock);
-	spin_lock(&tp->tx_lock);
+	tg3_full_lock(tp, 0);
 	tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
-	spin_unlock(&tp->tx_lock);
-	spin_unlock_irq(&tp->lock);
+	tg3_full_unlock(tp);
 
 	err = tg3_set_power_state(tp, pci_choose_state(pdev, state));
 	if (err) {
-		spin_lock_irq(&tp->lock);
-		spin_lock(&tp->tx_lock);
+		tg3_full_lock(tp, 0);
 
 		tg3_init_hw(tp);
 
@@ -10192,8 +10534,7 @@ static int tg3_suspend(struct pci_dev *p
 		netif_device_attach(dev);
 		tg3_netif_start(tp);
 
-		spin_unlock(&tp->tx_lock);
-		spin_unlock_irq(&tp->lock);
+		tg3_full_unlock(tp);
 	}
 
 	return err;
@@ -10216,20 +10557,16 @@ static int tg3_resume(struct pci_dev *pd
 
 	netif_device_attach(dev);
 
-	spin_lock_irq(&tp->lock);
-	spin_lock(&tp->tx_lock);
+	tg3_full_lock(tp, 0);
 
 	tg3_init_hw(tp);
 
 	tp->timer.expires = jiffies + tp->timer_offset;
 	add_timer(&tp->timer);
 
-	tg3_enable_ints(tp);
-
 	tg3_netif_start(tp);
 
-	spin_unlock(&tp->tx_lock);
-	spin_unlock_irq(&tp->lock);
+	tg3_full_unlock(tp);
 
 	return 0;
 }
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -136,6 +136,7 @@
 #define   ASIC_REV_5705			 0x03
 #define   ASIC_REV_5750			 0x04
 #define   ASIC_REV_5752			 0x06
+#define   ASIC_REV_5780			 0x08
 #define  GET_CHIP_REV(CHIP_REV_ID)	((CHIP_REV_ID) >> 8)
 #define   CHIPREV_5700_AX		 0x70
 #define   CHIPREV_5700_BX		 0x71
@@ -879,31 +880,41 @@
 #define  LOW_RXCOL_TICKS_CLRTCKS	 0x00000014
 #define  DEFAULT_RXCOL_TICKS		 0x00000048
 #define  HIGH_RXCOL_TICKS		 0x00000096
+#define  MAX_RXCOL_TICKS		 0x000003ff
 #define HOSTCC_TXCOL_TICKS		0x00003c0c
 #define  LOW_TXCOL_TICKS		 0x00000096
 #define  LOW_TXCOL_TICKS_CLRTCKS	 0x00000048
 #define  DEFAULT_TXCOL_TICKS		 0x0000012c
 #define  HIGH_TXCOL_TICKS		 0x00000145
+#define  MAX_TXCOL_TICKS		 0x000003ff
 #define HOSTCC_RXMAX_FRAMES		0x00003c10
 #define  LOW_RXMAX_FRAMES		 0x00000005
 #define  DEFAULT_RXMAX_FRAMES		 0x00000008
 #define  HIGH_RXMAX_FRAMES		 0x00000012
+#define  MAX_RXMAX_FRAMES		 0x000000ff
 #define HOSTCC_TXMAX_FRAMES		0x00003c14
 #define  LOW_TXMAX_FRAMES		 0x00000035
 #define  DEFAULT_TXMAX_FRAMES		 0x0000004b
 #define  HIGH_TXMAX_FRAMES		 0x00000052
+#define  MAX_TXMAX_FRAMES		 0x000000ff
 #define HOSTCC_RXCOAL_TICK_INT		0x00003c18
 #define  DEFAULT_RXCOAL_TICK_INT	 0x00000019
 #define  DEFAULT_RXCOAL_TICK_INT_CLRTCKS 0x00000014
+#define  MAX_RXCOAL_TICK_INT		 0x000003ff
 #define HOSTCC_TXCOAL_TICK_INT		0x00003c1c
 #define  DEFAULT_TXCOAL_TICK_INT	 0x00000019
 #define  DEFAULT_TXCOAL_TICK_INT_CLRTCKS 0x00000014
+#define  MAX_TXCOAL_TICK_INT		 0x000003ff
 #define HOSTCC_RXCOAL_MAXF_INT		0x00003c20
 #define  DEFAULT_RXCOAL_MAXF_INT	 0x00000005
+#define  MAX_RXCOAL_MAXF_INT		 0x000000ff
 #define HOSTCC_TXCOAL_MAXF_INT		0x00003c24
 #define  DEFAULT_TXCOAL_MAXF_INT	 0x00000005
+#define  MAX_TXCOAL_MAXF_INT		 0x000000ff
 #define HOSTCC_STAT_COAL_TICKS		0x00003c28
 #define  DEFAULT_STAT_COAL_TICKS	 0x000f4240
+#define  MAX_STAT_COAL_TICKS		 0xd693d400
+#define  MIN_STAT_COAL_TICKS		 0x00000064
 /* 0x3c2c --> 0x3c30 unused */
 #define HOSTCC_STATS_BLK_HOST_ADDR	0x00003c30 /* 64-bit */
 #define HOSTCC_STATUS_BLK_HOST_ADDR	0x00003c38 /* 64-bit */
@@ -974,14 +985,17 @@
 #define  DEFAULT_MB_RDMA_LOW_WATER	 0x00000050
 #define  DEFAULT_MB_RDMA_LOW_WATER_5705	 0x00000000
 #define  DEFAULT_MB_RDMA_LOW_WATER_JUMBO 0x00000130
+#define  DEFAULT_MB_RDMA_LOW_WATER_JUMBO_5780 0x00000000
 #define BUFMGR_MB_MACRX_LOW_WATER	0x00004414
 #define  DEFAULT_MB_MACRX_LOW_WATER	  0x00000020
 #define  DEFAULT_MB_MACRX_LOW_WATER_5705  0x00000010
 #define  DEFAULT_MB_MACRX_LOW_WATER_JUMBO 0x00000098
+#define  DEFAULT_MB_MACRX_LOW_WATER_JUMBO_5780 0x0000004b
 #define BUFMGR_MB_HIGH_WATER		0x00004418
 #define  DEFAULT_MB_HIGH_WATER		 0x00000060
 #define  DEFAULT_MB_HIGH_WATER_5705	 0x00000060
 #define  DEFAULT_MB_HIGH_WATER_JUMBO	 0x0000017c
+#define  DEFAULT_MB_HIGH_WATER_JUMBO_5780 0x00000096
 #define BUFMGR_RX_MB_ALLOC_REQ		0x0000441c
 #define  BUFMGR_MB_ALLOC_BIT		 0x10000000
 #define BUFMGR_RX_MB_ALLOC_RESP		0x00004420
@@ -2006,17 +2020,31 @@ struct tg3_ethtool_stats {
 struct tg3 {
 	/* begin "general, frequently-used members" cacheline section */
 
+	/* If the IRQ handler (which runs lockless) needs to be
+	 * quiesced, the following bitmask state is used.  The
+	 * SYNC flag is set by non-IRQ context code to initiate
+	 * the quiescence.
+	 *
+	 * When the IRQ handler notices that SYNC is set, it
+	 * disables interrupts and returns.
+	 *
+	 * When all outstanding IRQ handlers have returned after
+	 * the SYNC flag has been set, the setter can be assured
+	 * that interrupts will no longer get run.
+	 *
+	 * In this way all SMP driver locks are never acquired
+	 * in hw IRQ context, only sw IRQ context or lower.
+	 */
+	unsigned int			irq_sync;
+
 	/* SMP locking strategy:
 	 *
 	 * lock: Held during all operations except TX packet
 	 *       processing.
 	 *
-	 * tx_lock: Held during tg3_start_xmit{,_4gbug} and tg3_tx
+	 * tx_lock: Held during tg3_start_xmit and tg3_tx
 	 *
-	 * If you want to shut up all asynchronous processing you must
-	 * acquire both locks, 'lock' taken before 'tx_lock'.  IRQs must
-	 * be disabled to take 'lock' but only softirq disabling is
-	 * necessary for acquisition of 'tx_lock'.
+	 * Both of these locks are to be held with BH safety.
 	 */
 	spinlock_t			lock;
 	spinlock_t			indirect_lock;
@@ -2063,6 +2091,8 @@ struct tg3 {
 	struct tg3_rx_buffer_desc	*rx_rcb;
 	dma_addr_t			rx_rcb_mapping;
 
+	u32				rx_pkt_buf_sz;
+
 	/* begin "everything else" cacheline(s) section */
 	struct net_device_stats		net_stats;
 	struct net_device_stats		net_stats_prev;
@@ -2100,7 +2130,7 @@ struct tg3 {
 #define TG3_FLAG_NO_TX_PSEUDO_CSUM	0x00100000
 #define TG3_FLAG_NO_RX_PSEUDO_CSUM	0x00200000
 #define TG3_FLAG_SERDES_WOL_CAP		0x00400000
-#define TG3_FLAG_JUMBO_ENABLE		0x00800000
+#define TG3_FLAG_JUMBO_RING_ENABLE	0x00800000
 #define TG3_FLAG_10_100_ONLY		0x01000000
 #define TG3_FLAG_PAUSE_AUTONEG		0x02000000
 #define TG3_FLAG_BROKEN_CHECKSUMS	0x10000000
@@ -2130,6 +2160,11 @@ struct tg3 {
 #define TG3_FLG2_5750_PLUS		0x00080000
 #define TG3_FLG2_PROTECTED_NVRAM	0x00100000
 #define TG3_FLG2_USING_MSI		0x00200000
+#define TG3_FLG2_JUMBO_CAPABLE		0x00400000
+#define TG3_FLG2_MII_SERDES		0x00800000
+#define TG3_FLG2_ANY_SERDES		(TG3_FLG2_PHY_SERDES |	\
+					TG3_FLG2_MII_SERDES)
+#define TG3_FLG2_PARALLEL_DETECT	0x01000000
 
 	u32				split_mode_max_reqs;
 #define SPLIT_MODE_5704_MAX_REQ		3
@@ -2163,6 +2198,7 @@ struct tg3 {
 	u8				pci_bist;
 
 	int				pm_cap;
+	int				msi_cap;
 
 	/* PHY info */
 	u32				phy_id;
@@ -2176,6 +2212,7 @@ struct tg3 {
 #define PHY_ID_BCM5705			0x600081a0
 #define PHY_ID_BCM5750			0x60008180
 #define PHY_ID_BCM5752			0x60008100
+#define PHY_ID_BCM5780			0x60008350
 #define PHY_ID_BCM8002			0x60010140
 #define PHY_ID_INVALID			0xffffffff
 #define PHY_ID_REV_MASK			0x0000000f
diff --git a/drivers/net/tlan.c b/drivers/net/tlan.c
--- a/drivers/net/tlan.c
+++ b/drivers/net/tlan.c
@@ -171,6 +171,7 @@
 #include <linux/ioport.h>
 #include <linux/eisa.h>
 #include <linux/pci.h>
+#include <linux/dma-mapping.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/delay.h>
@@ -566,7 +567,7 @@ static int __devinit TLan_probe1(struct 
 
 		priv->adapter = &board_info[ent->driver_data];
 
-		rc = pci_set_dma_mask(pdev, 0xFFFFFFFF);
+		rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
 		if (rc) {
 			printk(KERN_ERR "TLAN: No suitable PCI mapping available.\n");
 			goto err_out_free_dev;
@@ -2819,7 +2820,7 @@ void TLan_PhyMonitor( struct net_device 
  	       if (priv->link) {
 		      priv->link = 0;
 	              printk(KERN_DEBUG "TLAN: %s has lost link\n", dev->name);
-	              dev->flags &= ~IFF_RUNNING;
+		      netif_carrier_off(dev);
 		      TLan_SetTimer( dev, (2*HZ), TLAN_TIMER_LINK_BEAT );
 		      return;
 		}
@@ -2829,7 +2830,7 @@ void TLan_PhyMonitor( struct net_device 
         if ((phy_status & MII_GS_LINK) && !priv->link) {
  		priv->link = 1;
         	printk(KERN_DEBUG "TLAN: %s has reestablished link\n", dev->name);
-        	dev->flags |= IFF_RUNNING;
+		netif_carrier_on(dev);
         }
 
 	/* Setup a new monitor */
diff --git a/drivers/net/tokenring/3c359.c b/drivers/net/tokenring/3c359.c
--- a/drivers/net/tokenring/3c359.c
+++ b/drivers/net/tokenring/3c359.c
@@ -276,7 +276,8 @@ static void  xl_ee_write(struct net_devi
 	return ; 
 }
  
-int __devinit xl_probe(struct pci_dev *pdev, const struct pci_device_id *ent) 
+static int __devinit xl_probe(struct pci_dev *pdev,
+			      const struct pci_device_id *ent) 
 {
 	struct net_device *dev ; 
 	struct xl_private *xl_priv ; 
diff --git a/drivers/net/tokenring/3c359_microcode.h b/drivers/net/tokenring/3c359_microcode.h
--- a/drivers/net/tokenring/3c359_microcode.h
+++ b/drivers/net/tokenring/3c359_microcode.h
@@ -22,7 +22,7 @@
 
 static int mc_size = 24880 ; 
 
-u8 microcode[] = { 
+static const u8 microcode[] = { 
  0xfe,0x3a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
diff --git a/drivers/net/tokenring/Kconfig b/drivers/net/tokenring/Kconfig
--- a/drivers/net/tokenring/Kconfig
+++ b/drivers/net/tokenring/Kconfig
@@ -84,7 +84,7 @@ config 3C359
 
 config TMS380TR
 	tristate "Generic TMS380 Token Ring ISA/PCI adapter support"
-	depends on TR && (PCI || ISA)
+	depends on TR && (PCI || ISA && ISA_DMA_API)
 	select FW_LOADER
 	---help---
 	  This driver provides generic support for token ring adapters
diff --git a/drivers/net/tokenring/abyss.c b/drivers/net/tokenring/abyss.c
--- a/drivers/net/tokenring/abyss.c
+++ b/drivers/net/tokenring/abyss.c
@@ -468,14 +468,3 @@ static void __exit abyss_rmmod (void)
 module_init(abyss_init);
 module_exit(abyss_rmmod);
 
-
-/*
- * Local variables:
- *  compile-command: "gcc -DMODVERSIONS  -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer -I/usr/src/linux/drivers/net/tokenring/ -c abyss.c"
- *  alt-compile-command: "gcc -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer -I/usr/src/linux/drivers/net/tokenring/ -c abyss.c"
- *  c-set-style "K&R"
- *  c-indent-level: 8
- *  c-basic-offset: 8
- *  tab-width: 8
- * End:
- */
diff --git a/drivers/net/tokenring/ibmtr.c b/drivers/net/tokenring/ibmtr.c
--- a/drivers/net/tokenring/ibmtr.c
+++ b/drivers/net/tokenring/ibmtr.c
@@ -151,7 +151,7 @@ static char version[] __initdata =
 
 /* this allows displaying full adapter information */
 
-char *channel_def[] __devinitdata = { "ISA", "MCA", "ISA P&P" };
+static char *channel_def[] __devinitdata = { "ISA", "MCA", "ISA P&P" };
 
 static char pcchannelid[] __devinitdata = {
 	0x05, 0x00, 0x04, 0x09,
@@ -171,7 +171,7 @@ static char mcchannelid[] __devinitdata 
 	0x03, 0x08, 0x02, 0x00
 };
 
-char __devinit *adapter_def(char type)
+static char __devinit *adapter_def(char type)
 {
 	switch (type) {
 	case 0xF: return "PC Adapter | PC Adapter II | Adapter/A";
@@ -184,7 +184,7 @@ char __devinit *adapter_def(char type)
 
 #define TRC_INIT 0x01		/*  Trace initialization & PROBEs */
 #define TRC_INITV 0x02		/*  verbose init trace points     */
-unsigned char ibmtr_debug_trace = 0;
+static unsigned char ibmtr_debug_trace = 0;
 
 static int 	ibmtr_probe(struct net_device *dev);
 static int	ibmtr_probe1(struct net_device *dev, int ioaddr);
@@ -192,20 +192,20 @@ static unsigned char get_sram_size(struc
 static int 	trdev_init(struct net_device *dev);
 static int 	tok_open(struct net_device *dev);
 static int 	tok_init_card(struct net_device *dev);
-void 		tok_open_adapter(unsigned long dev_addr);
+static void	tok_open_adapter(unsigned long dev_addr);
 static void 	open_sap(unsigned char type, struct net_device *dev);
 static void 	tok_set_multicast_list(struct net_device *dev);
 static int 	tok_send_packet(struct sk_buff *skb, struct net_device *dev);
 static int 	tok_close(struct net_device *dev);
-irqreturn_t tok_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t tok_interrupt(int irq, void *dev_id, struct pt_regs *regs);
 static void 	initial_tok_int(struct net_device *dev);
 static void 	tr_tx(struct net_device *dev);
 static void 	tr_rx(struct net_device *dev);
-void 		ibmtr_reset_timer(struct timer_list*tmr,struct net_device *dev);
+static void	ibmtr_reset_timer(struct timer_list*tmr,struct net_device *dev);
 static void	tok_rerun(unsigned long dev_addr);
-void 		ibmtr_readlog(struct net_device *dev);
+static void	ibmtr_readlog(struct net_device *dev);
 static struct 	net_device_stats *tok_get_stats(struct net_device *dev);
-int 		ibmtr_change_mtu(struct net_device *dev, int mtu);
+static int	ibmtr_change_mtu(struct net_device *dev, int mtu);
 static void	find_turbo_adapters(int *iolist);
 
 static int ibmtr_portlist[IBMTR_MAX_ADAPTERS+1] __devinitdata = {
@@ -888,11 +888,6 @@ static int tok_open(struct net_device *d
 	ti->sap_status   = CLOSED; /* CLOSED or OPEN      */
 	ti->open_failure =     NO; /* NO     or YES       */
 	ti->open_mode    = MANUAL; /* MANUAL or AUTOMATIC */
-	/* 12/2000 not typical Linux, but we can use RUNNING to let us know when
-	the network has crapped out or cables are disconnected. Useful because
-	the IFF_UP flag stays up the whole time, until ifconfig tr0 down.
-	*/
-	dev->flags &= ~IFF_RUNNING;
 
 	ti->sram_phys &= ~1; /* to reverse what we do in tok_close */
 	/* init the spinlock */
@@ -933,7 +928,7 @@ static int tok_open(struct net_device *d
 #define DLC_MAX_SAP_OFST        32
 #define DLC_MAX_STA_OFST        33
 
-void tok_open_adapter(unsigned long dev_addr)
+static void tok_open_adapter(unsigned long dev_addr)
 {
 	struct net_device *dev = (struct net_device *) dev_addr;
 	struct tok_info *ti;
@@ -1104,7 +1099,7 @@ static void __iomem *map_address(struct 
 	return ti->sram_virt + index;
 }
 
-void dir_open_adapter (struct net_device *dev)
+static void dir_open_adapter (struct net_device *dev)
 {
         struct tok_info *ti = (struct tok_info *) dev->priv;
         unsigned char ret_code;
@@ -1177,7 +1172,7 @@ void dir_open_adapter (struct net_device
 
 /******************************************************************************/
 
-irqreturn_t tok_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t tok_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	unsigned char status;
 	/*  unsigned char status_even ; */
@@ -1242,7 +1237,7 @@ irqreturn_t tok_interrupt(int irq, void 
 		ti->open_status = CLOSED;
 		ti->sap_status  = CLOSED;
 		ti->open_mode   = AUTOMATIC;
-		dev->flags &= ~IFF_RUNNING;
+		netif_carrier_off(dev);
 		netif_stop_queue(dev);
 		ti->open_action = RESTART;
 		outb(0, dev->base_addr + ADAPTRESET);
@@ -1323,7 +1318,7 @@ irqreturn_t tok_interrupt(int irq, void 
 				break;
 			}
 			netif_wake_queue(dev);
-			dev->flags |= IFF_RUNNING;/*BMS 12/2000*/
+			netif_carrier_on(dev);
 			break;
 		case DIR_INTERRUPT:
 		case DIR_MOD_OPEN_PARAMS:
@@ -1427,7 +1422,7 @@ irqreturn_t tok_interrupt(int irq, void 
 								ring_status);
 			if(ring_status& (REMOVE_RECV|AUTO_REMOVAL|LOBE_FAULT)){
 				netif_stop_queue(dev);
-				dev->flags &= ~IFF_RUNNING;/*not typical Linux*/
+				netif_carrier_off(dev);
 				DPRINTK("Remove received, or Auto-removal error"
 					", or Lobe fault\n");
 				DPRINTK("We'll try to reopen the closed adapter"
@@ -1845,7 +1840,7 @@ static void tr_rx(struct net_device *dev
 
 /*****************************************************************************/
 
-void ibmtr_reset_timer(struct timer_list *tmr, struct net_device *dev)
+static void ibmtr_reset_timer(struct timer_list *tmr, struct net_device *dev)
 {
 	tmr->expires = jiffies + TR_RETRY_INTERVAL;
 	tmr->data = (unsigned long) dev;
@@ -1877,7 +1872,7 @@ void tok_rerun(unsigned long dev_addr){
 
 /*****************************************************************************/
 
-void ibmtr_readlog(struct net_device *dev)
+static void ibmtr_readlog(struct net_device *dev)
 {
 	struct tok_info *ti;
 
@@ -1910,7 +1905,7 @@ static struct net_device_stats *tok_get_
 
 /*****************************************************************************/
 
-int ibmtr_change_mtu(struct net_device *dev, int mtu)
+static int ibmtr_change_mtu(struct net_device *dev, int mtu)
 {
 	struct tok_info *ti = (struct tok_info *) dev->priv;
 
diff --git a/drivers/net/tokenring/lanstreamer.c b/drivers/net/tokenring/lanstreamer.c
--- a/drivers/net/tokenring/lanstreamer.c
+++ b/drivers/net/tokenring/lanstreamer.c
@@ -118,6 +118,7 @@
 #include <linux/stddef.h>
 #include <linux/init.h>
 #include <linux/pci.h>
+#include <linux/dma-mapping.h>
 #include <linux/spinlock.h>
 #include <linux/version.h>
 #include <linux/bitops.h>
@@ -257,7 +258,7 @@ static int __devinit streamer_init_one(s
 #endif
 #endif
 
-	rc = pci_set_dma_mask(pdev, 0xFFFFFFFFULL);
+	rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
 	if (rc) {
 		printk(KERN_ERR "%s: No suitable PCI mapping available.\n",
 				dev->name);
@@ -454,8 +455,7 @@ static int streamer_reset(struct net_dev
 	writew(readw(streamer_mmio + BCTL) | BCTL_SOFTRESET, streamer_mmio + BCTL);
 	t = jiffies;
 	/* Hold soft reset bit for a while */
-	current->state = TASK_UNINTERRUPTIBLE;
-	schedule_timeout(HZ);
+	ssleep(1);
 	
 	writew(readw(streamer_mmio + BCTL) & ~BCTL_SOFTRESET,
 	       streamer_mmio + BCTL);
@@ -511,8 +511,7 @@ static int streamer_reset(struct net_dev
 	writew(SISR_MI, streamer_mmio + SISR_MASK_SUM);
 
 	while (!((readw(streamer_mmio + SISR)) & SISR_SRB_REPLY)) {
-		current->state = TASK_INTERRUPTIBLE;
-		schedule_timeout(HZ/10);
+		msleep_interruptible(100);
 		if (jiffies - t > 40 * HZ) {
 			printk(KERN_ERR
 			       "IBM PCI tokenring card not responding\n");
diff --git a/drivers/net/tokenring/madgemc.c b/drivers/net/tokenring/madgemc.c
--- a/drivers/net/tokenring/madgemc.c
+++ b/drivers/net/tokenring/madgemc.c
@@ -625,7 +625,7 @@ static int madgemc_chipset_init(struct n
 /*
  * Disable the board, and put back into power-up state.
  */
-void madgemc_chipset_close(struct net_device *dev)
+static void madgemc_chipset_close(struct net_device *dev)
 {
 	/* disable interrupts */
 	madgemc_setint(dev, 0);
@@ -786,15 +786,3 @@ module_exit(madgemc_exit);
 
 MODULE_LICENSE("GPL");
 
-
-/*
- * Local variables:
- *  compile-command: "gcc -DMODVERSIONS  -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer -I/usr/src/linux/drivers/net/tokenring/ -c madgemc.c"
- *  alt-compile-command: "gcc -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer -I/usr/src/linux/drivers/net/tokenring/ -c madgemc.c"
- *  c-set-style "K&R"
- *  c-indent-level: 8
- *  c-basic-offset: 8
- *  tab-width: 8
- * End:
- */
-
diff --git a/drivers/net/tokenring/proteon.c b/drivers/net/tokenring/proteon.c
--- a/drivers/net/tokenring/proteon.c
+++ b/drivers/net/tokenring/proteon.c
@@ -419,14 +419,3 @@ void cleanup_module(void)
 }
 #endif /* MODULE */
 
-
-/*
- * Local variables:
- *  compile-command: "gcc -DMODVERSIONS  -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer -I/usr/src/linux/drivers/net/tokenring/ -c proteon.c"
- *  alt-compile-command: "gcc -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer -I/usr/src/linux/drivers/net/tokenring/ -c proteon.c"
- *  c-set-style "K&R"
- *  c-indent-level: 8
- *  c-basic-offset: 8
- *  tab-width: 8
- * End:
- */
diff --git a/drivers/net/tokenring/skisa.c b/drivers/net/tokenring/skisa.c
--- a/drivers/net/tokenring/skisa.c
+++ b/drivers/net/tokenring/skisa.c
@@ -429,14 +429,3 @@ void cleanup_module(void)
 }
 #endif /* MODULE */
 
-
-/*
- * Local variables:
- *  compile-command: "gcc -DMODVERSIONS  -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer -I/usr/src/linux/drivers/net/tokenring/ -c skisa.c"
- *  alt-compile-command: "gcc -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer -I/usr/src/linux/drivers/net/tokenring/ -c skisa.c"
- *  c-set-style "K&R"
- *  c-indent-level: 8
- *  c-basic-offset: 8
- *  tab-width: 8
- * End:
- */
diff --git a/drivers/net/tokenring/smctr.c b/drivers/net/tokenring/smctr.c
--- a/drivers/net/tokenring/smctr.c
+++ b/drivers/net/tokenring/smctr.c
@@ -77,7 +77,7 @@ static int ringspeed;
 
 /* SMC Name of the Adapter. */
 static char smctr_name[] = "SMC TokenCard";
-char *smctr_model = "Unknown";
+static char *smctr_model = "Unknown";
 
 /* Use 0 for production, 1 for verification, 2 for debug, and
  * 3 for very verbose debug.
diff --git a/drivers/net/tokenring/smctr_firmware.h b/drivers/net/tokenring/smctr_firmware.h
--- a/drivers/net/tokenring/smctr_firmware.h
+++ b/drivers/net/tokenring/smctr_firmware.h
@@ -21,7 +21,7 @@
 
 #if defined(CONFIG_SMCTR) || defined(CONFIG_SMCTR_MODULE)
 
-unsigned char smctr_code[] = {
+static const unsigned char smctr_code[] = {
 	0x0BC, 0x01D, 0x012, 0x03B, 0x063, 0x0B4, 0x0E9, 0x000,
 	0x000, 0x01F, 0x000, 0x001, 0x001, 0x000, 0x002, 0x005,
 	0x001, 0x000, 0x006, 0x003, 0x001, 0x000, 0x004, 0x009,
diff --git a/drivers/net/tokenring/tms380tr.c b/drivers/net/tokenring/tms380tr.c
--- a/drivers/net/tokenring/tms380tr.c
+++ b/drivers/net/tokenring/tms380tr.c
@@ -2379,7 +2379,7 @@ EXPORT_SYMBOL(tmsdev_init);
 EXPORT_SYMBOL(tmsdev_term);
 EXPORT_SYMBOL(tms380tr_wait);
 
-struct module *TMS380_module = NULL;
+static struct module *TMS380_module = NULL;
 
 int init_module(void)
 {
@@ -2397,14 +2397,3 @@ void cleanup_module(void)
 
 MODULE_LICENSE("GPL");
 
-
-/*
- * Local variables:
- *  compile-command: "gcc -DMODVERSIONS  -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer -I/usr/src/linux/drivers/net/tokenring/ -c tms380tr.c"
- *  alt-compile-command: "gcc -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer -I/usr/src/linux/drivers/net/tokenring/ -c tms380tr.c"
- *  c-set-style "K&R"
- *  c-indent-level: 8
- *  c-basic-offset: 8
- *  tab-width: 8
- * End:
- */
diff --git a/drivers/net/tokenring/tmspci.c b/drivers/net/tokenring/tmspci.c
--- a/drivers/net/tokenring/tmspci.c
+++ b/drivers/net/tokenring/tmspci.c
@@ -254,14 +254,3 @@ static void __exit tms_pci_rmmod (void)
 module_init(tms_pci_init);
 module_exit(tms_pci_rmmod);
 
-
-/*
- * Local variables:
- *  compile-command: "gcc -DMODVERSIONS  -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer -I/usr/src/linux/drivers/net/tokenring/ -c tmspci.c"
- *  alt-compile-command: "gcc -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer -I/usr/src/linux/drivers/net/tokenring/ -c tmspci.c"
- *  c-set-style "K&R"
- *  c-indent-level: 8
- *  c-basic-offset: 8
- *  tab-width: 8
- * End:
- */
diff --git a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c
--- a/drivers/net/tulip/de2104x.c
+++ b/drivers/net/tulip/de2104x.c
@@ -446,13 +446,13 @@ static void de_rx (struct de_private *de
 
 			mapping =
 			de->rx_skb[rx_tail].mapping =
-				pci_map_single(de->pdev, copy_skb->tail,
+				pci_map_single(de->pdev, copy_skb->data,
 					       buflen, PCI_DMA_FROMDEVICE);
 			de->rx_skb[rx_tail].skb = copy_skb;
 		} else {
 			pci_dma_sync_single_for_cpu(de->pdev, mapping, len, PCI_DMA_FROMDEVICE);
 			skb_reserve(copy_skb, RX_OFFSET);
-			memcpy(skb_put(copy_skb, len), skb->tail, len);
+			memcpy(skb_put(copy_skb, len), skb->data, len);
 
 			pci_dma_sync_single_for_device(de->pdev, mapping, len, PCI_DMA_FROMDEVICE);
 
@@ -1269,7 +1269,7 @@ static int de_refill_rx (struct de_priva
 		skb->dev = de->dev;
 
 		de->rx_skb[i].mapping = pci_map_single(de->pdev,
-			skb->tail, de->rx_buf_sz, PCI_DMA_FROMDEVICE);
+			skb->data, de->rx_buf_sz, PCI_DMA_FROMDEVICE);
 		de->rx_skb[i].skb = skb;
 
 		de->rx_ring[i].opts1 = cpu_to_le32(DescOwn);
diff --git a/drivers/net/tulip/dmfe.c b/drivers/net/tulip/dmfe.c
--- a/drivers/net/tulip/dmfe.c
+++ b/drivers/net/tulip/dmfe.c
@@ -78,6 +78,7 @@
 #include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
+#include <linux/dma-mapping.h>
 #include <linux/init.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
@@ -354,7 +355,7 @@ static int __devinit dmfe_init_one (stru
 	SET_MODULE_OWNER(dev);
 	SET_NETDEV_DEV(dev, &pdev->dev);
 
-	if (pci_set_dma_mask(pdev, 0xffffffff)) {
+	if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
 		printk(KERN_WARNING DRV_NAME ": 32-bit PCI DMA not available.\n");
 		err = -ENODEV;
 		goto err_out_free;
@@ -743,11 +744,6 @@ static irqreturn_t dmfe_interrupt(int ir
 
 	DMFE_DBUG(0, "dmfe_interrupt()", 0);
 
-	if (!dev) {
-		DMFE_DBUG(1, "dmfe_interrupt() without DEVICE arg", 0);
-		return IRQ_NONE;
-	}
-
 	spin_lock_irqsave(&db->lock, flags);
 
 	/* Got DM910X status */
@@ -949,8 +945,8 @@ static void dmfe_rx_packet(struct DEVICE
 
 				/* Received Packet CRC check need or not */
 				if ( (db->dm910x_chk_mode & 1) &&
-					(cal_CRC(skb->tail, rxlen, 1) !=
-					(*(u32 *) (skb->tail+rxlen) ))) { /* FIXME (?) */
+					(cal_CRC(skb->data, rxlen, 1) !=
+					(*(u32 *) (skb->data+rxlen) ))) { /* FIXME (?) */
 					/* Found a error received packet */
 					dmfe_reuse_skb(db, rxptr->rx_skb_ptr);
 					db->dm910x_chk_mode = 3;
@@ -963,7 +959,7 @@ static void dmfe_rx_packet(struct DEVICE
 						/* size less than COPY_SIZE, allocate a rxlen SKB */
 						skb->dev = dev;
 						skb_reserve(skb, 2); /* 16byte align */
-						memcpy(skb_put(skb, rxlen), rxptr->rx_skb_ptr->tail, rxlen);
+						memcpy(skb_put(skb, rxlen), rxptr->rx_skb_ptr->data, rxlen);
 						dmfe_reuse_skb(db, rxptr->rx_skb_ptr);
 					} else {
 						skb->dev = dev;
@@ -1256,7 +1252,7 @@ static void dmfe_reuse_skb(struct dmfe_b
 
 	if (!(rxptr->rdes0 & cpu_to_le32(0x80000000))) {
 		rxptr->rx_skb_ptr = skb;
-		rxptr->rdes2 = cpu_to_le32( pci_map_single(db->pdev, skb->tail, RX_ALLOC_SIZE, PCI_DMA_FROMDEVICE) );
+		rxptr->rdes2 = cpu_to_le32( pci_map_single(db->pdev, skb->data, RX_ALLOC_SIZE, PCI_DMA_FROMDEVICE) );
 		wmb();
 		rxptr->rdes0 = cpu_to_le32(0x80000000);
 		db->rx_avail_cnt++;
@@ -1467,7 +1463,7 @@ static void allocate_rx_buffer(struct dm
 		if ( ( skb = dev_alloc_skb(RX_ALLOC_SIZE) ) == NULL )
 			break;
 		rxptr->rx_skb_ptr = skb; /* FIXME (?) */
-		rxptr->rdes2 = cpu_to_le32( pci_map_single(db->pdev, skb->tail, RX_ALLOC_SIZE, PCI_DMA_FROMDEVICE) );
+		rxptr->rdes2 = cpu_to_le32( pci_map_single(db->pdev, skb->data, RX_ALLOC_SIZE, PCI_DMA_FROMDEVICE) );
 		wmb();
 		rxptr->rdes0 = cpu_to_le32(0x80000000);
 		rxptr = rxptr->next_rx_desc;
@@ -1806,7 +1802,7 @@ static void dmfe_parse_srom(struct dmfe_
 	if ( ( (int) srom[18] & 0xff) == SROM_V41_CODE) {
 		/* SROM V4.01 */
 		/* Get NIC support media mode */
-		db->NIC_capability = le16_to_cpup(srom + 34);
+		db->NIC_capability = le16_to_cpup((__le16 *)srom + 34/2);
 		db->PHY_reg4 = 0;
 		for (tmp_reg = 1; tmp_reg < 0x10; tmp_reg <<= 1) {
 			switch( db->NIC_capability & tmp_reg ) {
@@ -1818,7 +1814,8 @@ static void dmfe_parse_srom(struct dmfe_
 		}
 
 		/* Media Mode Force or not check */
-		dmfe_mode = le32_to_cpup(srom + 34) & le32_to_cpup(srom + 36);
+		dmfe_mode = le32_to_cpup((__le32 *)srom + 34/4) &
+				le32_to_cpup((__le32 *)srom + 36/4);
 		switch(dmfe_mode) {
 		case 0x4: dmfe_media_mode = DMFE_100MHF; break;	/* 100MHF */
 		case 0x2: dmfe_media_mode = DMFE_10MFD; break;	/* 10MFD */
diff --git a/drivers/net/tulip/eeprom.c b/drivers/net/tulip/eeprom.c
--- a/drivers/net/tulip/eeprom.c
+++ b/drivers/net/tulip/eeprom.c
@@ -63,6 +63,22 @@ static struct eeprom_fixup eeprom_fixups
 	 */
 	{ 0x1e00, 0x0000, 0x000b, 0x8f01, 0x0103, 0x0300, 0x0821, 0x000, 0x0001, 0x0000, 0x01e1 }
   },
+  {"Cobalt Microserver", 0, 0x10, 0xE0, {0x1e00, /* 0 == controller #, 1e == offset	*/
+					 0x0000, /* 0 == high offset, 0 == gap		*/
+					 0x0800, /* Default Autoselect			*/
+					 0x8001, /* 1 leaf, extended type, bogus len	*/
+					 0x0003, /* Type 3 (MII), PHY #0		*/
+					 0x0400, /* 0 init instr, 4 reset instr		*/
+					 0x0801, /* Set control mode, GP0 output	*/
+					 0x0000, /* Drive GP0 Low (RST is active low)	*/
+					 0x0800, /* control mode, GP0 input (undriven)	*/
+					 0x0000, /* clear control mode			*/
+					 0x7800, /* 100TX FDX + HDX, 10bT FDX + HDX	*/
+					 0x01e0, /* Advertise all above			*/
+					 0x5000, /* FDX all above			*/
+					 0x1800, /* Set fast TTM in 100bt modes		*/
+					 0x0000, /* PHY cannot be unplugged		*/
+  }},
   {NULL}};
 
 
diff --git a/drivers/net/tulip/interrupt.c b/drivers/net/tulip/interrupt.c
--- a/drivers/net/tulip/interrupt.c
+++ b/drivers/net/tulip/interrupt.c
@@ -78,7 +78,7 @@ int tulip_refill_rx(struct net_device *d
 			if (skb == NULL)
 				break;
 
-			mapping = pci_map_single(tp->pdev, skb->tail, PKT_BUF_SZ,
+			mapping = pci_map_single(tp->pdev, skb->data, PKT_BUF_SZ,
 						 PCI_DMA_FROMDEVICE);
 			tp->rx_buffers[entry].mapping = mapping;
 
@@ -199,12 +199,12 @@ int tulip_poll(struct net_device *dev, i
 								   tp->rx_buffers[entry].mapping,
 								   pkt_len, PCI_DMA_FROMDEVICE);
 #if ! defined(__alpha__)
-                                       eth_copy_and_sum(skb, tp->rx_buffers[entry].skb->tail,
+                                       eth_copy_and_sum(skb, tp->rx_buffers[entry].skb->data,
                                                         pkt_len, 0);
                                        skb_put(skb, pkt_len);
 #else
                                        memcpy(skb_put(skb, pkt_len),
-                                              tp->rx_buffers[entry].skb->tail,
+                                              tp->rx_buffers[entry].skb->data,
                                               pkt_len);
 #endif
                                        pci_dma_sync_single_for_device(tp->pdev,
@@ -423,12 +423,12 @@ static int tulip_rx(struct net_device *d
 							    tp->rx_buffers[entry].mapping,
 							    pkt_len, PCI_DMA_FROMDEVICE);
 #if ! defined(__alpha__)
-				eth_copy_and_sum(skb, tp->rx_buffers[entry].skb->tail,
+				eth_copy_and_sum(skb, tp->rx_buffers[entry].skb->data,
 						 pkt_len, 0);
 				skb_put(skb, pkt_len);
 #else
 				memcpy(skb_put(skb, pkt_len),
-				       tp->rx_buffers[entry].skb->tail,
+				       tp->rx_buffers[entry].skb->data,
 				       pkt_len);
 #endif
 				pci_dma_sync_single_for_device(tp->pdev,
diff --git a/drivers/net/tulip/media.c b/drivers/net/tulip/media.c
--- a/drivers/net/tulip/media.c
+++ b/drivers/net/tulip/media.c
@@ -400,6 +400,9 @@ void tulip_select_media(struct net_devic
 	}
 
 	tp->csr6 = new_csr6 | (tp->csr6 & 0xfdff) | (tp->full_duplex ? 0x0200 : 0);
+
+	mdelay(1);
+
 	return;
 }
 
diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c
--- a/drivers/net/tulip/tulip_core.c
+++ b/drivers/net/tulip/tulip_core.c
@@ -242,6 +242,7 @@ static struct pci_device_id tulip_pci_tb
  	{ 0x10b9, 0x5261, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ULI526X },	/* ALi 1563 integrated ethernet */
  	{ 0x10b9, 0x5263, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ULI526X },	/* ALi 1563 integrated ethernet */
 	{ 0x10b7, 0x9300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, /* 3Com 3CSOHO100B-TX */
+	{ 0x14ea, 0xab08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, /* Planex FNW-3602-TX */
 	{ } /* terminate list */
 };
 MODULE_DEVICE_TABLE(pci, tulip_pci_tbl);
@@ -624,7 +625,7 @@ static void tulip_init_ring(struct net_d
 		tp->rx_buffers[i].skb = skb;
 		if (skb == NULL)
 			break;
-		mapping = pci_map_single(tp->pdev, skb->tail,
+		mapping = pci_map_single(tp->pdev, skb->data,
 					 PKT_BUF_SZ, PCI_DMA_FROMDEVICE);
 		tp->rx_buffers[i].mapping = mapping;
 		skb->dev = dev;			/* Mark as being used by this device. */
@@ -1514,8 +1515,8 @@ static int __devinit tulip_init_one (str
                     (PCI_SLOT(pdev->devfn) == 12))) {
                        /* Cobalt MAC address in first EEPROM locations. */
                        sa_offset = 0;
-                       /* No media table either */
-                       tp->flags &= ~HAS_MEDIA_TABLE;
+		       /* Ensure our media table fixup get's applied */
+		       memcpy(ee_data + 16, ee_data, 8);
                }
 #endif
 #ifdef CONFIG_GSC
@@ -1756,11 +1757,19 @@ static int tulip_suspend (struct pci_dev
 {
 	struct net_device *dev = pci_get_drvdata(pdev);
 
-	if (dev && netif_running (dev) && netif_device_present (dev)) {
-		netif_device_detach (dev);
-		tulip_down (dev);
-		/* pci_power_off(pdev, -1); */
-	}
+	if (!dev)
+		return -EINVAL;
+
+	if (netif_running(dev))
+		tulip_down(dev);
+
+	netif_device_detach(dev);
+	free_irq(dev->irq, dev);
+
+	pci_save_state(pdev);
+	pci_disable_device(pdev);
+	pci_set_power_state(pdev, pci_choose_state(pdev, state));
+
 	return 0;
 }
 
@@ -1768,15 +1777,26 @@ static int tulip_suspend (struct pci_dev
 static int tulip_resume(struct pci_dev *pdev)
 {
 	struct net_device *dev = pci_get_drvdata(pdev);
+	int retval;
 
-	if (dev && netif_running (dev) && !netif_device_present (dev)) {
-#if 1
-		pci_enable_device (pdev);
-#endif
-		/* pci_power_on(pdev); */
-		tulip_up (dev);
-		netif_device_attach (dev);
+	if (!dev)
+		return -EINVAL;
+
+	pci_set_power_state(pdev, PCI_D0);
+	pci_restore_state(pdev);
+
+	pci_enable_device(pdev);
+
+	if ((retval = request_irq(dev->irq, &tulip_interrupt, SA_SHIRQ, dev->name, dev))) {
+		printk (KERN_ERR "tulip: request_irq failed in resume\n");
+		return retval;
 	}
+
+	netif_device_attach(dev);
+
+	if (netif_running(dev))
+		tulip_up(dev);
+
 	return 0;
 }
 
diff --git a/drivers/net/tulip/winbond-840.c b/drivers/net/tulip/winbond-840.c
--- a/drivers/net/tulip/winbond-840.c
+++ b/drivers/net/tulip/winbond-840.c
@@ -121,6 +121,7 @@ static int full_duplex[MAX_UNITS] = {-1,
 #include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
+#include <linux/dma-mapping.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
@@ -394,7 +395,7 @@ static int __devinit w840_probe1 (struct
 
 	irq = pdev->irq;
 
-	if (pci_set_dma_mask(pdev,0xFFFFffff)) {
+	if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
 		printk(KERN_WARNING "Winbond-840: Device %s disabled due to DMA limitations.\n",
 		       pci_name(pdev));
 		return -EIO;
@@ -848,7 +849,7 @@ static void init_rxtx_rings(struct net_d
 		if (skb == NULL)
 			break;
 		skb->dev = dev;			/* Mark as being used by this device. */
-		np->rx_addr[i] = pci_map_single(np->pci_dev,skb->tail,
+		np->rx_addr[i] = pci_map_single(np->pci_dev,skb->data,
 					skb->len,PCI_DMA_FROMDEVICE);
 
 		np->rx_ring[i].buffer1 = np->rx_addr[i];
@@ -1268,7 +1269,7 @@ static int netdev_rx(struct net_device *
 				pci_dma_sync_single_for_cpu(np->pci_dev,np->rx_addr[entry],
 							    np->rx_skbuff[entry]->len,
 							    PCI_DMA_FROMDEVICE);
-				eth_copy_and_sum(skb, np->rx_skbuff[entry]->tail, pkt_len, 0);
+				eth_copy_and_sum(skb, np->rx_skbuff[entry]->data, pkt_len, 0);
 				skb_put(skb, pkt_len);
 				pci_dma_sync_single_for_device(np->pci_dev,np->rx_addr[entry],
 							       np->rx_skbuff[entry]->len,
@@ -1314,7 +1315,7 @@ static int netdev_rx(struct net_device *
 				break;			/* Better luck next round. */
 			skb->dev = dev;			/* Mark as being used by this device. */
 			np->rx_addr[entry] = pci_map_single(np->pci_dev,
-							skb->tail,
+							skb->data,
 							skb->len, PCI_DMA_FROMDEVICE);
 			np->rx_ring[entry].buffer1 = np->rx_addr[entry];
 		}
diff --git a/drivers/net/tulip/xircom_tulip_cb.c b/drivers/net/tulip/xircom_tulip_cb.c
--- a/drivers/net/tulip/xircom_tulip_cb.c
+++ b/drivers/net/tulip/xircom_tulip_cb.c
@@ -899,7 +899,7 @@ static void xircom_init_ring(struct net_
 			break;
 		skb->dev = dev;			/* Mark as being used by this device. */
 		tp->rx_ring[i].status = Rx0DescOwned;	/* Owned by Xircom chip */
-		tp->rx_ring[i].buffer1 = virt_to_bus(skb->tail);
+		tp->rx_ring[i].buffer1 = virt_to_bus(skb->data);
 	}
 	tp->dirty_rx = (unsigned int)(i - RX_RING_SIZE);
 
@@ -1291,7 +1291,7 @@ xircom_rx(struct net_device *dev)
 			if (skb == NULL)
 				break;
 			skb->dev = dev;			/* Mark as being used by this device. */
-			tp->rx_ring[entry].buffer1 = virt_to_bus(skb->tail);
+			tp->rx_ring[entry].buffer1 = virt_to_bus(skb->data);
 			work_done++;
 		}
 		tp->rx_ring[entry].status = Rx0DescOwned;
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -215,7 +215,7 @@ static unsigned int tun_chr_poll(struct 
 
 	poll_wait(file, &tun->read_wait, wait);
  
-	if (skb_queue_len(&tun->readq))
+	if (!skb_queue_empty(&tun->readq))
 		mask |= POLLIN | POLLRDNORM;
 
 	return mask;
diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c
--- a/drivers/net/typhoon.c
+++ b/drivers/net/typhoon.c
@@ -1661,7 +1661,7 @@ typhoon_alloc_rx_skb(struct typhoon *tp,
 #endif
 
 	skb->dev = tp->dev;
-	dma_addr = pci_map_single(tp->pdev, skb->tail,
+	dma_addr = pci_map_single(tp->pdev, skb->data,
 				  PKT_BUF_SZ, PCI_DMA_FROMDEVICE);
 
 	/* Since no card does 64 bit DAC, the high bits will never
@@ -1721,7 +1721,7 @@ typhoon_rx(struct typhoon *tp, struct ba
 			pci_dma_sync_single_for_cpu(tp->pdev, dma_addr,
 						    PKT_BUF_SZ,
 						    PCI_DMA_FROMDEVICE);
-			eth_copy_and_sum(new_skb, skb->tail, pkt_len, 0);
+			eth_copy_and_sum(new_skb, skb->data, pkt_len, 0);
 			pci_dma_sync_single_for_device(tp->pdev, dma_addr,
 						       PKT_BUF_SZ,
 						       PCI_DMA_FROMDEVICE);
@@ -1906,9 +1906,9 @@ typhoon_sleep(struct typhoon *tp, pci_po
 	 */
 	netif_carrier_off(tp->dev);
 
-	pci_enable_wake(tp->pdev, pci_choose_state(pdev, state), 1);
+	pci_enable_wake(tp->pdev, state, 1);
 	pci_disable_device(pdev);
-	return pci_set_power_state(pdev, pci_choose_state(pdev, state));
+	return pci_set_power_state(pdev, state);
 }
 
 static int
@@ -2274,7 +2274,7 @@ typhoon_suspend(struct pci_dev *pdev, pm
 		goto need_resume;
 	}
 
-	if(typhoon_sleep(tp, state, tp->wol_events) < 0) {
+	if(typhoon_sleep(tp, pci_choose_state(pdev, state), tp->wol_events) < 0) {
 		printk(KERN_ERR "%s: unable to put card to sleep\n", dev->name);
 		goto need_resume;
 	}
diff --git a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c
--- a/drivers/net/via-rhine.c
+++ b/drivers/net/via-rhine.c
@@ -186,6 +186,7 @@ static const int multicast_filter_limit 
 #include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
+#include <linux/dma-mapping.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
@@ -506,7 +507,7 @@ static struct net_device_stats *rhine_ge
 static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
 static struct ethtool_ops netdev_ethtool_ops;
 static int  rhine_close(struct net_device *dev);
-static void rhine_shutdown (struct device *gdev);
+static void rhine_shutdown (struct pci_dev *pdev);
 
 #define RHINE_WAIT_FOR(condition) do {					\
 	int i=1024;							\
@@ -740,7 +741,7 @@ static int __devinit rhine_init_one(stru
 		goto err_out;
 
 	/* this should always be supported */
-	rc = pci_set_dma_mask(pdev, 0xffffffff);
+	rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
 	if (rc) {
 		printk(KERN_ERR "32-bit PCI DMA addresses not supported by "
 		       "the card!?\n");
@@ -989,7 +990,7 @@ static void alloc_rbufs(struct net_devic
 		skb->dev = dev;                 /* Mark as being used by this device. */
 
 		rp->rx_skbuff_dma[i] =
-			pci_map_single(rp->pdev, skb->tail, rp->rx_buf_sz,
+			pci_map_single(rp->pdev, skb->data, rp->rx_buf_sz,
 				       PCI_DMA_FROMDEVICE);
 
 		rp->rx_ring[i].addr = cpu_to_le32(rp->rx_skbuff_dma[i]);
@@ -1397,7 +1398,7 @@ static void rhine_tx(struct net_device *
 	while (rp->dirty_tx != rp->cur_tx) {
 		txstatus = le32_to_cpu(rp->tx_ring[entry].tx_status);
 		if (debug > 6)
-			printk(KERN_DEBUG " Tx scavenge %d status %8.8x.\n",
+			printk(KERN_DEBUG "Tx scavenge %d status %8.8x.\n",
 			       entry, txstatus);
 		if (txstatus & DescOwn)
 			break;
@@ -1468,7 +1469,7 @@ static void rhine_rx(struct net_device *
 		int data_size = desc_status >> 16;
 
 		if (debug > 4)
-			printk(KERN_DEBUG " rhine_rx() status is %8.8x.\n",
+			printk(KERN_DEBUG "rhine_rx() status is %8.8x.\n",
 			       desc_status);
 		if (--boguscnt < 0)
 			break;
@@ -1486,7 +1487,7 @@ static void rhine_rx(struct net_device *
 			} else if (desc_status & RxErr) {
 				/* There was a error. */
 				if (debug > 2)
-					printk(KERN_DEBUG " rhine_rx() Rx "
+					printk(KERN_DEBUG "rhine_rx() Rx "
 					       "error was %8.8x.\n",
 					       desc_status);
 				rp->stats.rx_errors++;
@@ -1517,7 +1518,7 @@ static void rhine_rx(struct net_device *
 							    PCI_DMA_FROMDEVICE);
 
 				eth_copy_and_sum(skb,
-						 rp->rx_skbuff[entry]->tail,
+						 rp->rx_skbuff[entry]->data,
 						 pkt_len, 0);
 				skb_put(skb, pkt_len);
 				pci_dma_sync_single_for_device(rp->pdev,
@@ -1560,7 +1561,7 @@ static void rhine_rx(struct net_device *
 				break;	/* Better luck next round. */
 			skb->dev = dev;	/* Mark as being used by this device. */
 			rp->rx_skbuff_dma[entry] =
-				pci_map_single(rp->pdev, skb->tail,
+				pci_map_single(rp->pdev, skb->data,
 					       rp->rx_buf_sz,
 					       PCI_DMA_FROMDEVICE);
 			rp->rx_ring[entry].addr = cpu_to_le32(rp->rx_skbuff_dma[entry]);
@@ -1894,9 +1895,8 @@ static void __devexit rhine_remove_one(s
 	pci_set_drvdata(pdev, NULL);
 }
 
-static void rhine_shutdown (struct device *gendev)
+static void rhine_shutdown (struct pci_dev *pdev)
 {
-	struct pci_dev *pdev = to_pci_dev(gendev);
 	struct net_device *dev = pci_get_drvdata(pdev);
 	struct rhine_private *rp = netdev_priv(dev);
 	void __iomem *ioaddr = rp->base;
@@ -1955,7 +1955,7 @@ static int rhine_suspend(struct pci_dev 
 	pci_save_state(pdev);
 
 	spin_lock_irqsave(&rp->lock, flags);
-	rhine_shutdown(&pdev->dev);
+	rhine_shutdown(pdev);
 	spin_unlock_irqrestore(&rp->lock, flags);
 
 	free_irq(dev->irq, dev);
@@ -2009,9 +2009,7 @@ static struct pci_driver rhine_driver = 
 	.suspend	= rhine_suspend,
 	.resume		= rhine_resume,
 #endif /* CONFIG_PM */
-	.driver = {
-		.shutdown = rhine_shutdown,
-	}
+	.shutdown =	rhine_shutdown,
 };
 
 
diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c
--- a/drivers/net/via-velocity.c
+++ b/drivers/net/via-velocity.c
@@ -1335,7 +1335,7 @@ static inline int velocity_rx_copy(struc
 			if (vptr->flags & VELOCITY_FLAGS_IP_ALIGN)
 				skb_reserve(new_skb, 2);
 
-			memcpy(new_skb->data, rx_skb[0]->tail, pkt_size);
+			memcpy(new_skb->data, rx_skb[0]->data, pkt_size);
 			*rx_skb = new_skb;
 			ret = 0;
 		}
@@ -1456,9 +1456,9 @@ static int velocity_alloc_rx_buf(struct 
 	 *	Do the gymnastics to get the buffer head for data at
 	 *	64byte alignment.
 	 */
-	skb_reserve(rd_info->skb, (unsigned long) rd_info->skb->tail & 63);
+	skb_reserve(rd_info->skb, (unsigned long) rd_info->skb->data & 63);
 	rd_info->skb->dev = vptr->dev;
-	rd_info->skb_dma = pci_map_single(vptr->pdev, rd_info->skb->tail, vptr->rx_buf_sz, PCI_DMA_FROMDEVICE);
+	rd_info->skb_dma = pci_map_single(vptr->pdev, rd_info->skb->data, vptr->rx_buf_sz, PCI_DMA_FROMDEVICE);
 	
 	/*
 	 *	Fill in the descriptor to match
diff --git a/drivers/net/via-velocity.h b/drivers/net/via-velocity.h
--- a/drivers/net/via-velocity.h
+++ b/drivers/net/via-velocity.h
@@ -1414,7 +1414,7 @@ static inline void mac_get_cam(struct ma
  *	the rest of the logic from the result of sleep/wakeup
  */
 
-inline static void mac_wol_reset(struct mac_regs __iomem * regs)
+static inline void mac_wol_reset(struct mac_regs __iomem * regs)
 {
 
 	/* Turn off SWPTAG right after leaving power mode */
@@ -1811,7 +1811,7 @@ struct velocity_info {
  *	CHECK ME: locking
  */
 
-inline static int velocity_get_ip(struct velocity_info *vptr)
+static inline int velocity_get_ip(struct velocity_info *vptr)
 {
 	struct in_device *in_dev = (struct in_device *) vptr->dev->ip_ptr;
 	struct in_ifaddr *ifa;
diff --git a/drivers/net/wan/Kconfig b/drivers/net/wan/Kconfig
--- a/drivers/net/wan/Kconfig
+++ b/drivers/net/wan/Kconfig
@@ -435,7 +435,7 @@ config VENDOR_SANGOMA
 	  the driver to support.
 
 	  If you have one or more of these cards, say M to this option;
-	  and read <file:Documentation/networking/wanpipe.txt>.
+	  and read <file:Documentation/networking/wan-router.txt>.
 
 	  To compile this driver as a module, choose M here: the
 	  module will be called wanpipe.
diff --git a/drivers/net/wan/cosa.c b/drivers/net/wan/cosa.c
--- a/drivers/net/wan/cosa.c
+++ b/drivers/net/wan/cosa.c
@@ -235,7 +235,7 @@ static int dma[MAX_CARDS+1];
 static int irq[MAX_CARDS+1] = { -1, -1, -1, -1, -1, -1, 0, };
 
 /* for class stuff*/
-static struct class_simple *cosa_class;
+static struct class *cosa_class;
 
 #ifdef MODULE
 module_param_array(io, int, NULL, 0);
@@ -394,19 +394,19 @@ static int __init cosa_init(void)
 		goto out;
 	}
 	devfs_mk_dir("cosa");
-	cosa_class = class_simple_create(THIS_MODULE, "cosa");
+	cosa_class = class_create(THIS_MODULE, "cosa");
 	if (IS_ERR(cosa_class)) {
 		err = PTR_ERR(cosa_class);
 		goto out_chrdev;
 	}
 	for (i=0; i<nr_cards; i++) {
-		class_simple_device_add(cosa_class, MKDEV(cosa_major, i),
+		class_device_create(cosa_class, MKDEV(cosa_major, i),
 				NULL, "cosa%d", i);
 		err = devfs_mk_cdev(MKDEV(cosa_major, i),
 				S_IFCHR|S_IRUSR|S_IWUSR,
 				"cosa/%d", i);
 		if (err) {
-			class_simple_device_remove(MKDEV(cosa_major, i));
+			class_device_destroy(cosa_class, MKDEV(cosa_major, i));
 			goto out_chrdev;		
 		}
 	}
@@ -427,10 +427,10 @@ static void __exit cosa_exit(void)
 	printk(KERN_INFO "Unloading the cosa module\n");
 
 	for (i=0; i<nr_cards; i++) {
-		class_simple_device_remove(MKDEV(cosa_major, i));
+		class_device_destroy(cosa_class, MKDEV(cosa_major, i));
 		devfs_remove("cosa/%d", i);
 	}
-	class_simple_destroy(cosa_class);
+	class_destroy(cosa_class);
 	devfs_remove("cosa");
 	for (cosa=cosa_cards; nr_cards--; cosa++) {
 		/* Clean up the per-channel data */
diff --git a/drivers/net/wan/farsync.c b/drivers/net/wan/farsync.c
--- a/drivers/net/wan/farsync.c
+++ b/drivers/net/wan/farsync.c
@@ -861,8 +861,7 @@ fst_tx_dma_complete(struct fst_card_info
 /*
  * Mark it for our own raw sockets interface
  */
-static unsigned short farsync_type_trans(struct sk_buff *skb,
-					 struct net_device *dev)
+static __be16 farsync_type_trans(struct sk_buff *skb, struct net_device *dev)
 {
 	skb->dev = dev;
 	skb->mac.raw = skb->data;
@@ -981,6 +980,7 @@ fst_issue_cmd(struct fst_port_info *port
 	/* Wait for any previous command to complete */
 	while (mbval > NAK) {
 		spin_unlock_irqrestore(&card->card_lock, flags);
+		set_current_state(TASK_UNINTERRUPTIBLE);
 		schedule_timeout(1);
 		spin_lock_irqsave(&card->card_lock, flags);
 
diff --git a/drivers/net/wan/hdlc_cisco.c b/drivers/net/wan/hdlc_cisco.c
--- a/drivers/net/wan/hdlc_cisco.c
+++ b/drivers/net/wan/hdlc_cisco.c
@@ -72,7 +72,7 @@ static void cisco_keepalive_send(struct 
 	}
 	skb_reserve(skb, 4);
 	cisco_hard_header(skb, dev, CISCO_KEEPALIVE, NULL, NULL, 0);
-	data = (cisco_packet*)skb->tail;
+	data = (cisco_packet*)skb->data;
 
 	data->type = htonl(type);
 	data->par1 = htonl(par1);
@@ -91,8 +91,7 @@ static void cisco_keepalive_send(struct 
 
 
 
-static unsigned short cisco_type_trans(struct sk_buff *skb,
-				       struct net_device *dev)
+static __be16 cisco_type_trans(struct sk_buff *skb, struct net_device *dev)
 {
 	hdlc_header *data = (hdlc_header*)skb->data;
 
diff --git a/drivers/net/wan/hdlc_fr.c b/drivers/net/wan/hdlc_fr.c
--- a/drivers/net/wan/hdlc_fr.c
+++ b/drivers/net/wan/hdlc_fr.c
@@ -2,7 +2,7 @@
  * Generic HDLC support routines for Linux
  * Frame Relay support
  *
- * Copyright (C) 1999 - 2003 Krzysztof Halasa <khc@pm.waw.pl>
+ * Copyright (C) 1999 - 2005 Krzysztof Halasa <khc@pm.waw.pl>
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License
@@ -27,6 +27,10 @@
  active = open and "link reliable"
  exist = new = not used
 
+ CCITT LMI: ITU-T Q.933 Annex A
+ ANSI LMI: ANSI T1.617 Annex D
+ CISCO LMI: the original, aka "Gang of Four" LMI
+
 */
 
 #include <linux/module.h>
@@ -49,45 +53,41 @@
 #undef DEBUG_ECN
 #undef DEBUG_LINK
 
-#define MAXLEN_LMISTAT  20	/* max size of status enquiry frame */
+#define FR_UI			0x03
+#define FR_PAD			0x00
+
+#define NLPID_IP		0xCC
+#define NLPID_IPV6		0x8E
+#define NLPID_SNAP		0x80
+#define NLPID_PAD		0x00
+#define NLPID_CCITT_ANSI_LMI	0x08
+#define NLPID_CISCO_LMI		0x09
+
+
+#define LMI_CCITT_ANSI_DLCI	   0 /* LMI DLCI */
+#define LMI_CISCO_DLCI		1023
+
+#define LMI_CALLREF		0x00 /* Call Reference */
+#define LMI_ANSI_LOCKSHIFT	0x95 /* ANSI locking shift */
+#define LMI_ANSI_CISCO_REPTYPE	0x01 /* report type */
+#define LMI_CCITT_REPTYPE	0x51
+#define LMI_ANSI_CISCO_ALIVE	0x03 /* keep alive */
+#define LMI_CCITT_ALIVE		0x53
+#define LMI_ANSI_CISCO_PVCSTAT	0x07 /* PVC status */
+#define LMI_CCITT_PVCSTAT	0x57
+
+#define LMI_FULLREP		0x00 /* full report  */
+#define LMI_INTEGRITY		0x01 /* link integrity report */
+#define LMI_SINGLE		0x02 /* single PVC report */
 
-#define PVC_STATE_NEW	 0x01
-#define PVC_STATE_ACTIVE 0x02
-#define PVC_STATE_FECN	 0x08 /* FECN condition */
-#define PVC_STATE_BECN	 0x10 /* BECN condition */
-
-
-#define FR_UI		 0x03
-#define FR_PAD		 0x00
-
-#define NLPID_IP	 0xCC
-#define NLPID_IPV6	 0x8E
-#define NLPID_SNAP	 0x80
-#define NLPID_PAD	 0x00
-#define NLPID_Q933	 0x08
-
-
-#define LMI_DLCI                   0 /* LMI DLCI */
-#define LMI_PROTO               0x08
-#define LMI_CALLREF             0x00 /* Call Reference */
-#define LMI_ANSI_LOCKSHIFT      0x95 /* ANSI lockshift */
-#define LMI_REPTYPE                1 /* report type */
-#define LMI_CCITT_REPTYPE       0x51
-#define LMI_ALIVE                  3 /* keep alive */
-#define LMI_CCITT_ALIVE         0x53
-#define LMI_PVCSTAT                7 /* pvc status */
-#define LMI_CCITT_PVCSTAT       0x57
-#define LMI_FULLREP                0 /* full report  */
-#define LMI_INTEGRITY              1 /* link integrity report */
-#define LMI_SINGLE                 2 /* single pvc report */
 #define LMI_STATUS_ENQUIRY      0x75
 #define LMI_STATUS              0x7D /* reply */
 
 #define LMI_REPT_LEN               1 /* report type element length */
 #define LMI_INTEG_LEN              2 /* link integrity element length */
 
-#define LMI_LENGTH                13 /* standard LMI frame length */
-#define LMI_ANSI_LENGTH           14
+#define LMI_CCITT_CISCO_LENGTH	  13 /* LMI frame lengths */
+#define LMI_ANSI_LENGTH		  14
 
 
 typedef struct {
@@ -223,51 +223,34 @@ static inline struct net_device** get_de
 }
 
 
-static inline u16 status_to_dlci(u8 *status, int *active, int *new)
-{
-	*new = (status[2] & 0x08) ? 1 : 0;
-	*active = (status[2] & 0x02) ? 1 : 0;
-
-	return ((status[0] & 0x3F) << 4) | ((status[1] & 0x78) >> 3);
-}
-
-
-static inline void dlci_to_status(u16 dlci, u8 *status, int active, int new)
-{
-	status[0] = (dlci >> 4) & 0x3F;
-	status[1] = ((dlci << 3) & 0x78) | 0x80;
-	status[2] = 0x80;
-
-	if (new)
-		status[2] |= 0x08;
-	else if (active)
-		status[2] |= 0x02;
-}
-
-
-
 static int fr_hard_header(struct sk_buff **skb_p, u16 dlci)
 {
 	u16 head_len;
 	struct sk_buff *skb = *skb_p;
 
 	switch (skb->protocol) {
-	case __constant_ntohs(ETH_P_IP):
+	case __constant_ntohs(NLPID_CCITT_ANSI_LMI):
 		head_len = 4;
 		skb_push(skb, head_len);
-		skb->data[3] = NLPID_IP;
+		skb->data[3] = NLPID_CCITT_ANSI_LMI;
 		break;
 
-	case __constant_ntohs(ETH_P_IPV6):
+	case __constant_ntohs(NLPID_CISCO_LMI):
 		head_len = 4;
 		skb_push(skb, head_len);
-		skb->data[3] = NLPID_IPV6;
+		skb->data[3] = NLPID_CISCO_LMI;
 		break;
 
-	case __constant_ntohs(LMI_PROTO):
+	case __constant_ntohs(ETH_P_IP):
 		head_len = 4;
 		skb_push(skb, head_len);
-		skb->data[3] = LMI_PROTO;
+		skb->data[3] = NLPID_IP;
+		break;
+
+	case __constant_ntohs(ETH_P_IPV6):
+		head_len = 4;
+		skb_push(skb, head_len);
+		skb->data[3] = NLPID_IPV6;
 		break;
 
 	case __constant_ntohs(ETH_P_802_3):
@@ -461,13 +444,14 @@ static void fr_lmi_send(struct net_devic
 	hdlc_device *hdlc = dev_to_hdlc(dev);
 	struct sk_buff *skb;
 	pvc_device *pvc = hdlc->state.fr.first_pvc;
-	int len = (hdlc->state.fr.settings.lmi == LMI_ANSI) ? LMI_ANSI_LENGTH
-		: LMI_LENGTH;
-	int stat_len = 3;
+	int lmi = hdlc->state.fr.settings.lmi;
+	int dce = hdlc->state.fr.settings.dce;
+	int len = lmi == LMI_ANSI ? LMI_ANSI_LENGTH : LMI_CCITT_CISCO_LENGTH;
+	int stat_len = (lmi == LMI_CISCO) ? 6 : 3;
 	u8 *data;
 	int i = 0;
 
-	if (hdlc->state.fr.settings.dce && fullrep) {
+	if (dce && fullrep) {
 		len += hdlc->state.fr.dce_pvc_count * (2 + stat_len);
 		if (len > HDLC_MAX_MRU) {
 			printk(KERN_WARNING "%s: Too many PVCs while sending "
@@ -484,29 +468,31 @@ static void fr_lmi_send(struct net_devic
 	}
 	memset(skb->data, 0, len);
 	skb_reserve(skb, 4);
-	skb->protocol = __constant_htons(LMI_PROTO);
-	fr_hard_header(&skb, LMI_DLCI);
+	if (lmi == LMI_CISCO) {
+		skb->protocol = __constant_htons(NLPID_CISCO_LMI);
+		fr_hard_header(&skb, LMI_CISCO_DLCI);
+	} else {
+		skb->protocol = __constant_htons(NLPID_CCITT_ANSI_LMI);
+		fr_hard_header(&skb, LMI_CCITT_ANSI_DLCI);
+	}
 	data = skb->tail;
 	data[i++] = LMI_CALLREF;
-	data[i++] = hdlc->state.fr.settings.dce
-		? LMI_STATUS : LMI_STATUS_ENQUIRY;
-	if (hdlc->state.fr.settings.lmi == LMI_ANSI)
+	data[i++] = dce ? LMI_STATUS : LMI_STATUS_ENQUIRY;
+	if (lmi == LMI_ANSI)
 		data[i++] = LMI_ANSI_LOCKSHIFT;
-	data[i++] = (hdlc->state.fr.settings.lmi == LMI_CCITT)
-		? LMI_CCITT_REPTYPE : LMI_REPTYPE;
+	data[i++] = lmi == LMI_CCITT ? LMI_CCITT_REPTYPE :
+		LMI_ANSI_CISCO_REPTYPE;
 	data[i++] = LMI_REPT_LEN;
 	data[i++] = fullrep ? LMI_FULLREP : LMI_INTEGRITY;
-
-	data[i++] = (hdlc->state.fr.settings.lmi == LMI_CCITT)
-		? LMI_CCITT_ALIVE : LMI_ALIVE;
+	data[i++] = lmi == LMI_CCITT ? LMI_CCITT_ALIVE : LMI_ANSI_CISCO_ALIVE;
 	data[i++] = LMI_INTEG_LEN;
 	data[i++] = hdlc->state.fr.txseq =fr_lmi_nextseq(hdlc->state.fr.txseq);
 	data[i++] = hdlc->state.fr.rxseq;
 
-	if (hdlc->state.fr.settings.dce && fullrep) {
+	if (dce && fullrep) {
 		while (pvc) {
-			data[i++] = (hdlc->state.fr.settings.lmi == LMI_CCITT)
-				? LMI_CCITT_PVCSTAT : LMI_PVCSTAT;
+			data[i++] = lmi == LMI_CCITT ? LMI_CCITT_PVCSTAT :
+				LMI_ANSI_CISCO_PVCSTAT;
 			data[i++] = stat_len;
 
 			/* LMI start/restart */
@@ -523,8 +509,20 @@ static void fr_lmi_send(struct net_devic
 				fr_log_dlci_active(pvc);
 			}
 
-			dlci_to_status(pvc->dlci, data + i,
-				       pvc->state.active, pvc->state.new);
+			if (lmi == LMI_CISCO) {
+				data[i] = pvc->dlci >> 8;
+				data[i + 1] = pvc->dlci & 0xFF;
+			} else {
+				data[i] = (pvc->dlci >> 4) & 0x3F;
+				data[i + 1] = ((pvc->dlci << 3) & 0x78) | 0x80;
+				data[i + 2] = 0x80;
+			}
+
+			if (pvc->state.new)
+				data[i + 2] |= 0x08;
+			else if (pvc->state.active)
+				data[i + 2] |= 0x02;
+
 			i += stat_len;
 			pvc = pvc->next;
 		}
@@ -569,6 +567,8 @@ static void fr_set_link_state(int reliab
 			pvc_carrier(0, pvc);
 			pvc->state.exist = pvc->state.active = 0;
 			pvc->state.new = 0;
+			if (!hdlc->state.fr.settings.dce)
+				pvc->state.bandwidth = 0;
 			pvc = pvc->next;
 		}
 	}
@@ -583,11 +583,12 @@ static void fr_timer(unsigned long arg)
 	int i, cnt = 0, reliable;
 	u32 list;
 
-	if (hdlc->state.fr.settings.dce)
+	if (hdlc->state.fr.settings.dce) {
 		reliable = hdlc->state.fr.request &&
 			time_before(jiffies, hdlc->state.fr.last_poll +
 				    hdlc->state.fr.settings.t392 * HZ);
-	else {
+		hdlc->state.fr.request = 0;
+	} else {
 		hdlc->state.fr.last_errors <<= 1; /* Shift the list */
 		if (hdlc->state.fr.request) {
 			if (hdlc->state.fr.reliable)
@@ -634,65 +635,88 @@ static void fr_timer(unsigned long arg)
 static int fr_lmi_recv(struct net_device *dev, struct sk_buff *skb)
 {
 	hdlc_device *hdlc = dev_to_hdlc(dev);
-	int stat_len;
 	pvc_device *pvc;
-	int reptype = -1, error, no_ram;
 	u8 rxseq, txseq;
-	int i;
+	int lmi = hdlc->state.fr.settings.lmi;
+	int dce = hdlc->state.fr.settings.dce;
+	int stat_len = (lmi == LMI_CISCO) ? 6 : 3, reptype, error, no_ram, i;
 
-	if (skb->len < ((hdlc->state.fr.settings.lmi == LMI_ANSI)
-			? LMI_ANSI_LENGTH : LMI_LENGTH)) {
+	if (skb->len < (lmi == LMI_ANSI ? LMI_ANSI_LENGTH :
+			LMI_CCITT_CISCO_LENGTH)) {
 		printk(KERN_INFO "%s: Short LMI frame\n", dev->name);
 		return 1;
 	}
 
-	if (skb->data[5] != (!hdlc->state.fr.settings.dce ?
-			     LMI_STATUS : LMI_STATUS_ENQUIRY)) {
-		printk(KERN_INFO "%s: LMI msgtype=%x, Not LMI status %s\n",
-		       dev->name, skb->data[2],
-		       hdlc->state.fr.settings.dce ? "enquiry" : "reply");
+	if (skb->data[3] != (lmi == LMI_CISCO ? NLPID_CISCO_LMI :
+			     NLPID_CCITT_ANSI_LMI)) {
+		printk(KERN_INFO "%s: Received non-LMI frame with LMI"
+		       " DLCI\n", dev->name);
 		return 1;
 	}
 
-	i = (hdlc->state.fr.settings.lmi == LMI_ANSI) ? 7 : 6;
+	if (skb->data[4] != LMI_CALLREF) {
+		printk(KERN_INFO "%s: Invalid LMI Call reference (0x%02X)\n",
+		       dev->name, skb->data[4]);
+		return 1;
+	}
+
+	if (skb->data[5] != (dce ? LMI_STATUS_ENQUIRY : LMI_STATUS)) {
+		printk(KERN_INFO "%s: Invalid LMI Message type (0x%02X)\n",
+		       dev->name, skb->data[5]);
+		return 1;
+	}
+
+	if (lmi == LMI_ANSI) {
+		if (skb->data[6] != LMI_ANSI_LOCKSHIFT) {
+			printk(KERN_INFO "%s: Not ANSI locking shift in LMI"
+			       " message (0x%02X)\n", dev->name, skb->data[6]);
+			return 1;
+		}
+		i = 7;
+	} else
+		i = 6;
 
-	if (skb->data[i] !=
-	    ((hdlc->state.fr.settings.lmi == LMI_CCITT)
-	     ? LMI_CCITT_REPTYPE : LMI_REPTYPE)) {
-		printk(KERN_INFO "%s: Not a report type=%x\n",
+	if (skb->data[i] != (lmi == LMI_CCITT ? LMI_CCITT_REPTYPE :
+			     LMI_ANSI_CISCO_REPTYPE)) {
+		printk(KERN_INFO "%s: Not an LMI Report type IE (0x%02X)\n",
 		       dev->name, skb->data[i]);
 		return 1;
 	}
-	i++;
 
-	i++;				/* Skip length field */
+	if (skb->data[++i] != LMI_REPT_LEN) {
+		printk(KERN_INFO "%s: Invalid LMI Report type IE length"
+		       " (%u)\n", dev->name, skb->data[i]);
+		return 1;
+	}
 
-	reptype = skb->data[i++];
+	reptype = skb->data[++i];
+	if (reptype != LMI_INTEGRITY && reptype != LMI_FULLREP) {
+		printk(KERN_INFO "%s: Unsupported LMI Report type (0x%02X)\n",
+		       dev->name, reptype);
+		return 1;
+	}
 
-	if (skb->data[i]!=
-	    ((hdlc->state.fr.settings.lmi == LMI_CCITT)
-	     ? LMI_CCITT_ALIVE : LMI_ALIVE)) {
-		printk(KERN_INFO "%s: Unsupported status element=%x\n",
-		       dev->name, skb->data[i]);
+	if (skb->data[++i] != (lmi == LMI_CCITT ? LMI_CCITT_ALIVE :
+			       LMI_ANSI_CISCO_ALIVE)) {
+		printk(KERN_INFO "%s: Not an LMI Link integrity verification"
+		       " IE (0x%02X)\n", dev->name, skb->data[i]);
 		return 1;
 	}
-	i++;
 
-	i++;			/* Skip length field */
+	if (skb->data[++i] != LMI_INTEG_LEN) {
+		printk(KERN_INFO "%s: Invalid LMI Link integrity verification"
+		       " IE length (%u)\n", dev->name, skb->data[i]);
+		return 1;
+	}
+	i++;
 
 	hdlc->state.fr.rxseq = skb->data[i++]; /* TX sequence from peer */
 	rxseq = skb->data[i++];	/* Should confirm our sequence */
 
 	txseq = hdlc->state.fr.txseq;
 
-	if (hdlc->state.fr.settings.dce) {
-		if (reptype != LMI_FULLREP && reptype != LMI_INTEGRITY) {
-			printk(KERN_INFO "%s: Unsupported report type=%x\n",
-			       dev->name, reptype);
-			return 1;
-		}
+	if (dce)
 		hdlc->state.fr.last_poll = jiffies;
-	}
 
 	error = 0;
 	if (!hdlc->state.fr.reliable)
@@ -703,7 +727,7 @@ static int fr_lmi_recv(struct net_device
 		error = 1;
 	}
 
-	if (hdlc->state.fr.settings.dce) {
+	if (dce) {
 		if (hdlc->state.fr.fullrep_sent && !error) {
 /* Stop sending full report - the last one has been confirmed by DTE */
 			hdlc->state.fr.fullrep_sent = 0;
@@ -725,6 +749,7 @@ static int fr_lmi_recv(struct net_device
 			hdlc->state.fr.dce_changed = 0;
 		}
 
+		hdlc->state.fr.request = 1; /* got request */
 		fr_lmi_send(dev, reptype == LMI_FULLREP ? 1 : 0);
 		return 0;
 	}
@@ -739,7 +764,6 @@ static int fr_lmi_recv(struct net_device
 	if (reptype != LMI_FULLREP)
 		return 0;
 
-	stat_len = 3;
 	pvc = hdlc->state.fr.first_pvc;
 
 	while (pvc) {
@@ -750,24 +774,35 @@ static int fr_lmi_recv(struct net_device
 	no_ram = 0;
 	while (skb->len >= i + 2 + stat_len) {
 		u16 dlci;
+		u32 bw;
 		unsigned int active, new;
 
-		if (skb->data[i] != ((hdlc->state.fr.settings.lmi == LMI_CCITT)
-				     ? LMI_CCITT_PVCSTAT : LMI_PVCSTAT)) {
-			printk(KERN_WARNING "%s: Invalid PVCSTAT ID: %x\n",
-			       dev->name, skb->data[i]);
+		if (skb->data[i] != (lmi == LMI_CCITT ? LMI_CCITT_PVCSTAT :
+				       LMI_ANSI_CISCO_PVCSTAT)) {
+			printk(KERN_INFO "%s: Not an LMI PVC status IE"
+			       " (0x%02X)\n", dev->name, skb->data[i]);
 			return 1;
 		}
-		i++;
 
-		if (skb->data[i] != stat_len) {
-			printk(KERN_WARNING "%s: Invalid PVCSTAT length: %x\n",
-			       dev->name, skb->data[i]);
+		if (skb->data[++i] != stat_len) {
+			printk(KERN_INFO "%s: Invalid LMI PVC status IE length"
+			       " (%u)\n", dev->name, skb->data[i]);
 			return 1;
 		}
 		i++;
 
-		dlci = status_to_dlci(skb->data + i, &active, &new);
+		new = !! (skb->data[i + 2] & 0x08);
+		active = !! (skb->data[i + 2] & 0x02);
+		if (lmi == LMI_CISCO) {
+			dlci = (skb->data[i] << 8) | skb->data[i + 1];
+			bw = (skb->data[i + 3] << 16) |
+				(skb->data[i + 4] << 8) |
+				(skb->data[i + 5]);
+		} else {
+			dlci = ((skb->data[i] & 0x3F) << 4) |
+				((skb->data[i + 1] & 0x78) >> 3);
+			bw = 0;
+		}
 
 		pvc = add_pvc(dev, dlci);
 
@@ -783,9 +818,11 @@ static int fr_lmi_recv(struct net_device
 			pvc->state.deleted = 0;
 			if (active != pvc->state.active ||
 			    new != pvc->state.new ||
+			    bw != pvc->state.bandwidth ||
 			    !pvc->state.exist) {
 				pvc->state.new = new;
 				pvc->state.active = active;
+				pvc->state.bandwidth = bw;
 				pvc_carrier(active, pvc);
 				fr_log_dlci_active(pvc);
 			}
@@ -801,6 +838,7 @@ static int fr_lmi_recv(struct net_device
 			pvc_carrier(0, pvc);
 			pvc->state.active = pvc->state.new = 0;
 			pvc->state.exist = 0;
+			pvc->state.bandwidth = 0;
 			fr_log_dlci_active(pvc);
 		}
 		pvc = pvc->next;
@@ -829,22 +867,15 @@ static int fr_rx(struct sk_buff *skb)
 
 	dlci = q922_to_dlci(skb->data);
 
-	if (dlci == LMI_DLCI) {
-		if (hdlc->state.fr.settings.lmi == LMI_NONE)
-			goto rx_error; /* LMI packet with no LMI? */
-
-		if (data[3] == LMI_PROTO) {
-			if (fr_lmi_recv(ndev, skb))
-				goto rx_error;
-			else {
-				dev_kfree_skb_any(skb);
-				return NET_RX_SUCCESS;
-			}
-		}
-
-		printk(KERN_INFO "%s: Received non-LMI frame with LMI DLCI\n",
-		       ndev->name);
-		goto rx_error;
+	if ((dlci == LMI_CCITT_ANSI_DLCI &&
+	     (hdlc->state.fr.settings.lmi == LMI_ANSI ||
+	      hdlc->state.fr.settings.lmi == LMI_CCITT)) ||
+	    (dlci == LMI_CISCO_DLCI &&
+	     hdlc->state.fr.settings.lmi == LMI_CISCO)) {
+		if (fr_lmi_recv(ndev, skb))
+			goto rx_error;
+		dev_kfree_skb_any(skb);
+		return NET_RX_SUCCESS;
 	}
 
 	pvc = find_pvc(hdlc, dlci);
@@ -1170,7 +1201,8 @@ int hdlc_fr_ioctl(struct net_device *dev
 
 		if ((new_settings.lmi != LMI_NONE &&
 		     new_settings.lmi != LMI_ANSI &&
-		     new_settings.lmi != LMI_CCITT) ||
+		     new_settings.lmi != LMI_CCITT &&
+		     new_settings.lmi != LMI_CISCO) ||
 		    new_settings.t391 < 1 ||
 		    new_settings.t392 < 2 ||
 		    new_settings.n391 < 1 ||
diff --git a/drivers/net/wan/hdlc_generic.c b/drivers/net/wan/hdlc_generic.c
--- a/drivers/net/wan/hdlc_generic.c
+++ b/drivers/net/wan/hdlc_generic.c
@@ -1,7 +1,7 @@
 /*
  * Generic HDLC support routines for Linux
  *
- * Copyright (C) 1999 - 2003 Krzysztof Halasa <khc@pm.waw.pl>
+ * Copyright (C) 1999 - 2005 Krzysztof Halasa <khc@pm.waw.pl>
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License
@@ -38,7 +38,7 @@
 #include <linux/hdlc.h>
 
 
-static const char* version = "HDLC support module revision 1.17";
+static const char* version = "HDLC support module revision 1.18";
 
 #undef DEBUG_LINK
 
@@ -126,10 +126,13 @@ void hdlc_set_carrier(int on, struct net
 	if (!hdlc->open)
 		goto carrier_exit;
 
-	if (hdlc->carrier)
+	if (hdlc->carrier) {
+		printk(KERN_INFO "%s: Carrier detected\n", dev->name);
 		__hdlc_set_carrier_on(dev);
-	else
+	} else {
+		printk(KERN_INFO "%s: Carrier lost\n", dev->name);
 		__hdlc_set_carrier_off(dev);
+	}
 
 carrier_exit:
 	spin_unlock_irqrestore(&hdlc->state_lock, flags);
@@ -157,8 +160,11 @@ int hdlc_open(struct net_device *dev)
 
 	spin_lock_irq(&hdlc->state_lock);
 
-	if (hdlc->carrier)
+	if (hdlc->carrier) {
+		printk(KERN_INFO "%s: Carrier detected\n", dev->name);
 		__hdlc_set_carrier_on(dev);
+	} else
+		printk(KERN_INFO "%s: No carrier\n", dev->name);
 
 	hdlc->open = 1;
 
diff --git a/drivers/net/wan/hdlc_ppp.c b/drivers/net/wan/hdlc_ppp.c
--- a/drivers/net/wan/hdlc_ppp.c
+++ b/drivers/net/wan/hdlc_ppp.c
@@ -66,8 +66,7 @@ static void ppp_close(struct net_device 
 
 
 
-static unsigned short ppp_type_trans(struct sk_buff *skb,
-				     struct net_device *dev)
+static __be16 ppp_type_trans(struct sk_buff *skb, struct net_device *dev)
 {
 	return __constant_htons(ETH_P_WAN_PPP);
 }
diff --git a/drivers/net/wan/hdlc_raw.c b/drivers/net/wan/hdlc_raw.c
--- a/drivers/net/wan/hdlc_raw.c
+++ b/drivers/net/wan/hdlc_raw.c
@@ -24,8 +24,7 @@
 #include <linux/hdlc.h>
 
 
-static unsigned short raw_type_trans(struct sk_buff *skb,
-				     struct net_device *dev)
+static __be16 raw_type_trans(struct sk_buff *skb, struct net_device *dev)
 {
 	return __constant_htons(ETH_P_IP);
 }
diff --git a/drivers/net/wan/lmc/lmc_main.c b/drivers/net/wan/lmc/lmc_main.c
--- a/drivers/net/wan/lmc/lmc_main.c
+++ b/drivers/net/wan/lmc/lmc_main.c
@@ -723,7 +723,7 @@ static void lmc_watchdog (unsigned long 
         /* lmc_reset (sc); Why reset??? The link can go down ok */
 
         /* Inform the world that link has been lost */
-        dev->flags &= ~IFF_RUNNING;
+	netif_carrier_off(dev);
     }
 
     /*
@@ -736,7 +736,7 @@ static void lmc_watchdog (unsigned long 
          /* lmc_reset (sc); Again why reset??? */
 
          /* Inform the world that link protocol is back up. */
-         dev->flags |= IFF_RUNNING;
+	 netif_carrier_on(dev);
 
          /* Now we have to tell the syncppp that we had an outage
           * and that it should deal.  Calling sppp_reopen here
@@ -1168,8 +1168,6 @@ static void lmc_running_reset (struct ne
     sc->lmc_media->set_link_status (sc, 1);
     sc->lmc_media->set_status (sc, NULL);
 
-    //dev->flags |= IFF_RUNNING;
-    
     netif_wake_queue(dev);
 
     sc->lmc_txfull = 0;
@@ -1233,8 +1231,6 @@ static int lmc_ifdown (struct net_device
     csr6 &= ~LMC_DEC_SR;		/* Turn off the Receive bit */
     LMC_CSR_WRITE (sc, csr_command, csr6);
 
-    dev->flags &= ~IFF_RUNNING;
-
     sc->stats.rx_missed_errors +=
         LMC_CSR_READ (sc, csr_missed_frames) & 0xffff;
 
diff --git a/drivers/net/wan/sdla_fr.c b/drivers/net/wan/sdla_fr.c
--- a/drivers/net/wan/sdla_fr.c
+++ b/drivers/net/wan/sdla_fr.c
@@ -152,6 +152,7 @@
 #include <asm/io.h>		/* for inb(), outb(), etc. */
 #include <linux/time.h>	 	/* for do_gettimeofday */	
 #include <linux/in.h>		/* sockaddr_in */
+#include <linux/jiffies.h>	/* time_after() macro */
 #include <asm/errno.h>
 
 #include <linux/ip.h>
@@ -773,7 +774,7 @@ static int update(struct wan_device* wan
        	for(;;) {
 		if(card->u.f.update_comms_stats == 0)
 			break;
-                if ((jiffies - timeout) > (1 * HZ)){
+                if (time_after(jiffies, timeout + 1 * HZ)){
     			card->u.f.update_comms_stats = 0;
  			return -EAGAIN;
 		}
@@ -4799,7 +4800,7 @@ static void trigger_unconfig_fr(struct n
 {
 	fr_channel_t *chan = dev->priv;
 	volatile sdla_t *card = chan->card;
-	u32 timeout;
+	unsigned long timeout;
 	fr508_flags_t* flags = card->flags;
 	int reset_critical=0;
 	
@@ -4821,7 +4822,7 @@ static void trigger_unconfig_fr(struct n
 		if(!(card->u.f.timer_int_enabled & TMR_INT_ENABLED_UNCONFIG))
 			break;
 
-             	if ((jiffies - timeout) > (1 * HZ)){
+             	if (time_after(jiffies, timeout + 1 * HZ)){
     			card->u.f.timer_int_enabled &= ~TMR_INT_ENABLED_UNCONFIG;
 			printk(KERN_INFO "%s: Failed to delete DLCI %i\n",
 				card->devname,chan->dlci);
diff --git a/drivers/net/wan/sdla_ft1.c b/drivers/net/wan/sdla_ft1.c
--- a/drivers/net/wan/sdla_ft1.c
+++ b/drivers/net/wan/sdla_ft1.c
@@ -29,6 +29,7 @@
 #include <linux/wanrouter.h>	/* WAN router definitions */
 #include <linux/wanpipe.h>	/* WANPIPE common user API definitions */
 #include <linux/if_arp.h>	/* ARPHRD_* defines */
+#include <linux/jiffies.h>	/* time_after() macro */
 
 #include <linux/inetdevice.h>
 #include <asm/uaccess.h>
@@ -164,7 +165,7 @@ int wpft1_init (sdla_t* card, wandev_con
 
 		timeout = jiffies;
 		while (mb->return_code != 'I')	/* Wait 1s for board to initialize */
-			if ((jiffies - timeout) > 1*HZ) break;
+			if (time_after(jiffies, timeout + 1*HZ)) break;
 
 		if (mb->return_code != 'I') {
 			printk(KERN_INFO
diff --git a/drivers/net/wan/sdla_ppp.c b/drivers/net/wan/sdla_ppp.c
--- a/drivers/net/wan/sdla_ppp.c
+++ b/drivers/net/wan/sdla_ppp.c
@@ -101,6 +101,7 @@
 #include <linux/if_arp.h>	/* ARPHRD_* defines */
 #include <asm/byteorder.h>	/* htons(), etc. */
 #include <linux/in.h>		/* sockaddr_in */
+#include <linux/jiffies.h>	/* time_after() macro */
 
 
 #include <asm/uaccess.h>
@@ -482,7 +483,7 @@ static int update(struct wan_device *wan
 		if(ppp_priv_area->update_comms_stats == 0){
 			break;
 		}
-                if ((jiffies - timeout) > (1 * HZ)){
+                if (time_after(jiffies, timeout + 1 * HZ)){
     			ppp_priv_area->update_comms_stats = 0;
  			ppp_priv_area->timer_int_enabled &=
 				~TMR_INT_ENABLED_UPDATE; 
diff --git a/drivers/net/wan/sdla_x25.c b/drivers/net/wan/sdla_x25.c
--- a/drivers/net/wan/sdla_x25.c
+++ b/drivers/net/wan/sdla_x25.c
@@ -91,6 +91,7 @@
 #include <linux/wanrouter.h>	/* WAN router definitions */
 #include <linux/wanpipe.h>	/* WANPIPE common user API definitions */
 #include <linux/workqueue.h>
+#include <linux/jiffies.h>	/* time_after() macro */
 #include <asm/byteorder.h>	/* htons(), etc. */
 #include <asm/atomic.h>
 #include <linux/delay.h>	/* Experimental delay */
@@ -867,7 +868,7 @@ static int update(struct wan_device* wan
 		if (!(card->u.x.timer_int_enabled & TMR_INT_ENABLED_UPDATE)){	
 			break;
 		}
-		if ((jiffies-timeout) > 1*HZ){
+		if (time_after(jiffies, timeout + 1*HZ)){
 			card->u.x.timer_int_enabled &= ~TMR_INT_ENABLED_UPDATE;
 			return -EAGAIN;
 		}
diff --git a/drivers/net/wan/wanpipe_multppp.c b/drivers/net/wan/wanpipe_multppp.c
--- a/drivers/net/wan/wanpipe_multppp.c
+++ b/drivers/net/wan/wanpipe_multppp.c
@@ -26,6 +26,7 @@
 #include <linux/wanrouter.h>	/* WAN router definitions */
 #include <linux/wanpipe.h>	/* WANPIPE common user API definitions */
 #include <linux/if_arp.h>	/* ARPHRD_* defines */
+#include <linux/jiffies.h>	/* time_after() macro */
 
 #include <linux/in.h>		/* sockaddr_in */
 #include <linux/inet.h>	
@@ -270,9 +271,9 @@ int wsppp_init (sdla_t* card, wandev_con
 	   	ready to accept commands.  We expect this to be completed in less
            	than 1 second. */
 
-		timeout = jiffies;
+		timeout = jiffies + 1 * HZ;
 		while (mb->return_code != 'I')	/* Wait 1s for board to initialize */
-			if ((jiffies - timeout) > 1*HZ) break;
+			if (time_after(jiffies, timeout)) break;
 
 		if (mb->return_code != 'I') {
 			printk(KERN_INFO
@@ -493,11 +494,11 @@ static int update(struct wan_device* wan
 	chdlc_priv_area->timer_int_enabled = TMR_INT_ENABLED_UPDATE;
   
 	/* wait a maximum of 1 second for the statistics to be updated */ 
-        timeout = jiffies;
+        timeout = jiffies + 1 * HZ;
         for(;;) {
 		if(chdlc_priv_area->update_comms_stats == 0)
 			break;
-                if ((jiffies - timeout) > (1 * HZ)){
+                if (time_after(jiffies, timeout)){
     			chdlc_priv_area->update_comms_stats = 0;
  			chdlc_priv_area->timer_int_enabled &=
 				~TMR_INT_ENABLED_UPDATE; 
diff --git a/drivers/net/wan/wanxl.c b/drivers/net/wan/wanxl.c
--- a/drivers/net/wan/wanxl.c
+++ b/drivers/net/wan/wanxl.c
@@ -26,6 +26,7 @@
 #include <linux/netdevice.h>
 #include <linux/hdlc.h>
 #include <linux/pci.h>
+#include <linux/dma-mapping.h>
 #include <asm/io.h>
 #include <asm/delay.h>
 
@@ -624,8 +625,8 @@ static int __devinit wanxl_pci_init_one(
 	/* FIXME when PCI/DMA subsystems are fixed.
 	   We set both dma_mask and consistent_dma_mask back to 32 bits
 	   to indicate the card can do 32-bit DMA addressing */
-	if (pci_set_consistent_dma_mask(pdev, 0xFFFFFFFF) ||
-	    pci_set_dma_mask(pdev, 0xFFFFFFFF)) {
+	if (pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK) ||
+	    pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
 		printk(KERN_ERR "wanXL: No usable DMA configuration\n");
 		wanxl_pci_remove_one(pdev);
 		return -EIO;
diff --git a/drivers/net/wan/x25_asy.c b/drivers/net/wan/x25_asy.c
--- a/drivers/net/wan/x25_asy.c
+++ b/drivers/net/wan/x25_asy.c
@@ -829,7 +829,7 @@ static void __exit exit_x25_asy(void)
 	}
 
 	kfree(x25_asy_devs);
-	tty_register_ldisc(N_X25, NULL);
+	tty_unregister_ldisc(N_X25);
 }
 
 module_init(init_x25_asy);
diff --git a/drivers/net/wd.c b/drivers/net/wd.c
--- a/drivers/net/wd.c
+++ b/drivers/net/wd.c
@@ -149,12 +149,7 @@ struct net_device * __init wd_probe(int 
 	err = do_wd_probe(dev);
 	if (err)
 		goto out;
-	err = register_netdev(dev);
-	if (err)
-		goto out1;
 	return dev;
-out1:
-	cleanup_card(dev);
 out:
 	free_netdev(dev);
 	return ERR_PTR(err);
@@ -164,6 +159,7 @@ out:
 static int __init wd_probe1(struct net_device *dev, int ioaddr)
 {
 	int i;
+	int err;
 	int checksum = 0;
 	int ancient = 0;			/* An old card without config registers. */
 	int word16 = 0;				/* 0 = 8 bit, 1 = 16 bit */
@@ -356,7 +352,10 @@ static int __init wd_probe1(struct net_d
 		outb(inb(ioaddr+4)|0x80, ioaddr+4);
 #endif
 
-	return 0;
+	err = register_netdev(dev);
+	if (err)
+		free_irq(dev->irq, dev);
+	return err;
 }
 
 static int
@@ -527,11 +526,8 @@ init_module(void)
 		dev->mem_start = mem[this_dev];
 		dev->mem_end = mem_end[this_dev];
 		if (do_wd_probe(dev) == 0) {
-			if (register_netdev(dev) == 0) {
-				dev_wd[found++] = dev;
-				continue;
-			}
-			cleanup_card(dev);
+			dev_wd[found++] = dev;
+			continue;
 		}
 		free_netdev(dev);
 		printk(KERN_WARNING "wd.c: No wd80x3 card found (i/o = 0x%x).\n", io[this_dev]);
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -270,7 +270,7 @@ config PCMCIA_HERMES
 
 config AIRO_CS
 	tristate "Cisco/Aironet 34X/35X/4500/4800 PCMCIA cards"
-	depends on NET_RADIO && PCMCIA
+	depends on NET_RADIO && PCMCIA && (BROKEN || !M32R)
 	---help---
 	  This is the standard Linux driver to support Cisco/Aironet PCMCIA
 	  802.11 wireless cards.  This driver is the same as the Aironet
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -900,7 +900,7 @@ typedef struct aironet_ioctl {
 	unsigned char __user *data;	// d-data
 } aironet_ioctl;
 
-static char *swversion = "2.1";
+static char swversion[] = "2.1";
 #endif /* CISCO_EXT */
 
 #define NUM_MODULES       2
@@ -1209,7 +1209,7 @@ struct airo_info {
 	unsigned char		__iomem *pciaux;
 	unsigned char		*shared;
 	dma_addr_t		shared_dma;
-	int			power;
+	pm_message_t		power;
 	SsidRid			*SSID;
 	APListRid		*APList;
 #define	PCI_SHARED_LEN		2*MPI_MAX_FIDS*PKTSIZE+RIDSIZE
@@ -2374,7 +2374,7 @@ void stop_airo_card( struct net_device *
 	/*
 	 * Clean out tx queue
 	 */
-	if (test_bit(FLAG_MPI, &ai->flags) && skb_queue_len (&ai->txq) > 0) {
+	if (test_bit(FLAG_MPI, &ai->flags) && !skb_queue_empty(&ai->txq)) {
 		struct sk_buff *skb = NULL;
 		for (;(skb = skb_dequeue(&ai->txq));)
 			dev_kfree_skb(skb);
@@ -2918,7 +2918,7 @@ static int airo_thread(void *data) {
 			flush_signals(current);
 
 		/* make swsusp happy with our thread */
-		try_to_freeze(PF_FREEZE);
+		try_to_freeze();
 
 		if (test_bit(JOB_DIE, &ai->flags))
 			break;
@@ -3287,7 +3287,7 @@ exitrx:
 				if (status & EV_TXEXC)
 					get_tx_error(apriv, -1);
 				spin_lock_irqsave(&apriv->aux_lock, flags);
-				if (skb_queue_len (&apriv->txq)) {
+				if (!skb_queue_empty(&apriv->txq)) {
 					spin_unlock_irqrestore(&apriv->aux_lock,flags);
 					mpi_send_packet (dev);
 				} else {
@@ -5013,7 +5013,7 @@ static void proc_SSID_on_close( struct i
 	enable_MAC(ai, &rsp, 1);
 }
 
-inline static u8 hexVal(char c) {
+static inline u8 hexVal(char c) {
 	if (c>='0' && c<='9') return c -= '0';
 	if (c>='a' && c<='f') return c -= 'a'-10;
 	if (c>='A' && c<='F') return c -= 'A'-10;
@@ -5499,9 +5499,9 @@ static int airo_pci_suspend(struct pci_d
 	cmd.cmd=HOSTSLEEP;
 	issuecommand(ai, &cmd, &rsp);
 
-	pci_enable_wake(pdev, state, 1);
+	pci_enable_wake(pdev, pci_choose_state(pdev, state), 1);
 	pci_save_state(pdev);
-	return pci_set_power_state(pdev, state);
+	return pci_set_power_state(pdev, pci_choose_state(pdev, state));
 }
 
 static int airo_pci_resume(struct pci_dev *pdev)
@@ -5512,7 +5512,7 @@ static int airo_pci_resume(struct pci_de
 
 	pci_set_power_state(pdev, 0);
 	pci_restore_state(pdev);
-	pci_enable_wake(pdev, ai->power, 0);
+	pci_enable_wake(pdev, pci_choose_state(pdev, ai->power), 0);
 
 	if (ai->power > 1) {
 		reset_card(dev, 0);
@@ -5541,7 +5541,7 @@ static int airo_pci_resume(struct pci_de
 	}
 	writeConfigRid(ai, 0);
 	enable_MAC(ai, &rsp, 0);
-	ai->power = 0;
+	ai->power = PMSG_ON;
 	netif_device_attach(dev);
 	netif_wake_queue(dev);
 	enable_interrupts(ai);
diff --git a/drivers/net/wireless/airo_cs.c b/drivers/net/wireless/airo_cs.c
--- a/drivers/net/wireless/airo_cs.c
+++ b/drivers/net/wireless/airo_cs.c
@@ -33,7 +33,6 @@
 #include <linux/timer.h>
 #include <linux/netdevice.h>
 
-#include <pcmcia/version.h>
 #include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
@@ -210,11 +209,6 @@ static dev_link_t *airo_attach(void)
 	link->next = dev_list;
 	dev_list = link;
 	client_reg.dev_info = &dev_info;
-	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 = &airo_event;
 	client_reg.Version = 0x0210;
 	client_reg.event_callback_args.client_data = link;
 	ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -559,13 +553,24 @@ static int airo_event(event_t event, int
 	return 0;
 } /* airo_event */
 
+static struct pcmcia_device_id airo_ids[] = {
+	PCMCIA_DEVICE_MANF_CARD(0x015f, 0x000a),
+	PCMCIA_DEVICE_MANF_CARD(0x015f, 0x0005),
+	PCMCIA_DEVICE_MANF_CARD(0x015f, 0x0007),
+	PCMCIA_DEVICE_MANF_CARD(0x0105, 0x0007),
+	PCMCIA_DEVICE_NULL,
+};
+MODULE_DEVICE_TABLE(pcmcia, airo_ids);
+
 static struct pcmcia_driver airo_driver = {
 	.owner		= THIS_MODULE,
 	.drv		= {
 		.name	= "airo_cs",
 	},
 	.attach		= airo_attach,
+	.event		= airo_event,
 	.detach		= airo_detach,
+	.id_table       = airo_ids,
 };
 
 static int airo_cs_init(void)
diff --git a/drivers/net/wireless/airport.c b/drivers/net/wireless/airport.c
--- a/drivers/net/wireless/airport.c
+++ b/drivers/net/wireless/airport.c
@@ -184,7 +184,7 @@ static int airport_hard_reset(struct ori
 }
 
 static int
-airport_attach(struct macio_dev *mdev, const struct of_match *match)
+airport_attach(struct macio_dev *mdev, const struct of_device_id *match)
 {
 	struct orinoco_private *priv;
 	struct net_device *dev;
@@ -266,16 +266,16 @@ MODULE_AUTHOR("Benjamin Herrenschmidt <b
 MODULE_DESCRIPTION("Driver for the Apple Airport wireless card.");
 MODULE_LICENSE("Dual MPL/GPL");
 
-static struct of_match airport_match[] = 
+static struct of_device_id airport_match[] = 
 {
 	{
 	.name 		= "radio",
-	.type		= OF_ANY_MATCH,
-	.compatible	= OF_ANY_MATCH
 	},
 	{},
 };
 
+MODULE_DEVICE_TABLE (of, airport_match);
+
 static struct macio_driver airport_driver = 
 {
 	.name 		= DRIVER_NAME,
diff --git a/drivers/net/wireless/arlan-main.c b/drivers/net/wireless/arlan-main.c
--- a/drivers/net/wireless/arlan-main.c
+++ b/drivers/net/wireless/arlan-main.c
@@ -33,8 +33,6 @@ static int arlan_EEPROM_bad;
 
 #ifdef ARLAN_DEBUGGING
 
-static int arlan_entry_debug;
-static int arlan_exit_debug;
 static int testMemory = testMemoryUNKNOWN;
 static int irq = irqUNKNOWN;
 static int txScrambled = 1;
@@ -43,15 +41,13 @@ static int mdebug;
 module_param(irq, int, 0);
 module_param(mdebug, int, 0);
 module_param(testMemory, int, 0);
-module_param(arlan_entry_debug, int, 0);
-module_param(arlan_exit_debug, int, 0);
 module_param(txScrambled, int, 0);
 MODULE_PARM_DESC(irq, "(unused)");
 MODULE_PARM_DESC(testMemory, "(unused)");
 MODULE_PARM_DESC(mdebug, "Arlan multicast debugging (0-1)");
 #endif
 
-module_param(arlan_debug, int, 0);
+module_param_named(debug, arlan_debug, int, 0);
 module_param(spreadingCode, int, 0);
 module_param(channelNumber, int, 0);
 module_param(channelSet, int, 0);
@@ -63,17 +59,19 @@ module_param(keyStart, int, 0);
 module_param(tx_delay_ms, int, 0);
 module_param(retries, int, 0);
 module_param(tx_queue_len, int, 0);
-module_param(arlan_EEPROM_bad, int, 0);
-MODULE_PARM_DESC(arlan_debug, "Arlan debug enable (0-1)");
+module_param_named(EEPROM_bad, arlan_EEPROM_bad, int, 0);
+MODULE_PARM_DESC(debug, "Arlan debug enable (0-1)");
 MODULE_PARM_DESC(retries, "Arlan maximum packet retransmisions");
 #ifdef ARLAN_ENTRY_EXIT_DEBUGGING
-MODULE_PARM_DESC(arlan_entry_debug, "Arlan driver function entry debugging");
-MODULE_PARM_DESC(arlan_exit_debug, "Arlan driver function exit debugging");
-MODULE_PARM_DESC(arlan_entry_and_exit_debug, "Arlan driver function entry and exit debugging");
-#else
-MODULE_PARM_DESC(arlan_entry_debug, "(ignored)");
-MODULE_PARM_DESC(arlan_exit_debug, "(ignored)");
-MODULE_PARM_DESC(arlan_entry_and_exit_debug, "(ignored)");
+static int arlan_entry_debug;
+static int arlan_exit_debug;
+static int arlan_entry_and_exit_debug;
+module_param_named(entry_debug, arlan_entry_debug, int, 0);
+module_param_named(exit_debug, arlan_exit_debug, int, 0);
+module_param_named(entry_and_exit_debug, arlan_entry_and_exit_debug, int, 0);
+MODULE_PARM_DESC(entry_debug, "Arlan driver function entry debugging");
+MODULE_PARM_DESC(exit_debug, "Arlan driver function exit debugging");
+MODULE_PARM_DESC(entry_and_exit_debug, "Arlan driver function entry and exit debugging");
 #endif
 
 struct arlan_conf_stru arlan_conf[MAX_ARLANS];
diff --git a/drivers/net/wireless/atmel_cs.c b/drivers/net/wireless/atmel_cs.c
--- a/drivers/net/wireless/atmel_cs.c
+++ b/drivers/net/wireless/atmel_cs.c
@@ -43,7 +43,6 @@
 #include <linux/moduleparam.h>
 #include <linux/device.h>
 
-#include <pcmcia/version.h>
 #include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
@@ -218,11 +217,6 @@ static dev_link_t *atmel_attach(void)
 	link->next = dev_list;
 	dev_list = link;
 	client_reg.dev_info = &dev_info;
-	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 = &atmel_event;
 	client_reg.Version = 0x0210;
 	client_reg.event_callback_args.client_data = link;
 	ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -646,13 +640,36 @@ static int atmel_event(event_t event, in
 } /* atmel_event */
 
 /*====================================================================*/
+static struct pcmcia_device_id atmel_ids[] = {
+	PCMCIA_DEVICE_MANF_CARD(0x0101, 0x0620),
+	PCMCIA_DEVICE_MANF_CARD(0x0101, 0x0696),
+	PCMCIA_DEVICE_MANF_CARD(0x01bf, 0x3302),
+	PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0007),
+	PCMCIA_DEVICE_PROD_ID12("11WAVE", "11WP611AL-E", 0x9eb2da1f, 0xc9a0d3f9),
+	PCMCIA_DEVICE_PROD_ID12("ATMEL", "AT76C502AR", 0xabda4164, 0x41b37e1f),
+	PCMCIA_DEVICE_PROD_ID12("ATMEL", "AT76C504", 0xabda4164, 0x5040670a),
+	PCMCIA_DEVICE_PROD_ID12("ATMEL", "AT76C504A", 0xabda4164, 0xe15ed87f),
+	PCMCIA_DEVICE_PROD_ID12("BT", "Voyager 1020 Laptop Adapter", 0xae49b86a, 0x1e957cd5),
+	PCMCIA_DEVICE_PROD_ID12("CNet", "CNWLC 11Mbps Wireless PC Card V-5", 0xbc477dde, 0x502fae6b),
+	PCMCIA_DEVICE_PROD_ID12("IEEE 802.11b", "Wireless LAN PC Card", 0x5b878724, 0x122f1df6),
+	PCMCIA_DEVICE_PROD_ID12("OEM", "11Mbps Wireless LAN PC Card V-3", 0xfea54c90, 0x1c5b0f68),
+	PCMCIA_DEVICE_PROD_ID12("SMC", "2632W", 0xc4f8b18b, 0x30f38774),
+	PCMCIA_DEVICE_PROD_ID12("SMC", "2632W-V2", 0xc4f8b18b, 0x172d1377),
+	PCMCIA_DEVICE_PROD_ID12("Wireless", "PC", 0xa407ecdd, 0x556e4d7e),
+	PCMCIA_DEVICE_PROD_ID12("WLAN", "802.11b PC CARD", 0x575c516c, 0xb1f6dbc4),
+	PCMCIA_DEVICE_NULL
+};
+MODULE_DEVICE_TABLE(pcmcia, atmel_ids);
+
 static struct pcmcia_driver atmel_driver = {
-        .owner          = THIS_MODULE,
-        .drv            = {
-                .name   = "atmel_cs",
+	.owner		= THIS_MODULE,
+	.drv		= {
+		.name	= "atmel_cs",
         },
-        .attach         = atmel_attach,
-        .detach         = atmel_detach,
+	.attach         = atmel_attach,
+	.event		= atmel_event,
+	.detach		= atmel_detach,
+	.id_table	= atmel_ids,
 };
 
 static int atmel_cs_init(void)
diff --git a/drivers/net/wireless/netwave_cs.c b/drivers/net/wireless/netwave_cs.c
--- a/drivers/net/wireless/netwave_cs.c
+++ b/drivers/net/wireless/netwave_cs.c
@@ -62,7 +62,6 @@
 #endif	/* WIRELESS_EXT > 12 */
 #endif
 
-#include <pcmcia/version.h>
 #include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
@@ -491,11 +490,6 @@ static dev_link_t *netwave_attach(void)
     link->next = dev_list;
     dev_list = link;
     client_reg.dev_info = &dev_info;
-    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 = &netwave_event;
     client_reg.Version = 0x0210;
     client_reg.event_callback_args.client_data = link;
     ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -1668,13 +1662,21 @@ static int netwave_close(struct net_devi
     return 0;
 }
 
+static struct pcmcia_device_id netwave_ids[] = {
+	PCMCIA_DEVICE_PROD_ID12("Xircom", "CreditCard Netwave", 0x2e3ee845, 0x54e28a28),
+	PCMCIA_DEVICE_NULL,
+};
+MODULE_DEVICE_TABLE(pcmcia, netwave_ids);
+
 static struct pcmcia_driver netwave_driver = {
 	.owner		= THIS_MODULE,
 	.drv		= {
 		.name	= "netwave_cs",
 	},
 	.attach		= netwave_attach,
+	.event		= netwave_event,
 	.detach		= netwave_detach,
+	.id_table       = netwave_ids,
 };
 
 static int __init init_netwave_cs(void)
diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c
--- a/drivers/net/wireless/orinoco.c
+++ b/drivers/net/wireless/orinoco.c
@@ -46,382 +46,9 @@
  * under either the MPL or the GPL.  */
 
 /*
- * v0.01 -> v0.02 - 21/3/2001 - Jean II
- *	o Allow to use regular ethX device name instead of dldwdX
- *	o Warning on IBSS with ESSID=any for firmware 6.06
- *	o Put proper range.throughput values (optimistic)
- *	o IWSPY support (IOCTL and stat gather in Rx path)
- *	o Allow setting frequency in Ad-Hoc mode
- *	o Disable WEP setting if !has_wep to work on old firmware
- *	o Fix txpower range
- *	o Start adding support for Samsung/Compaq firmware
- *
- * v0.02 -> v0.03 - 23/3/2001 - Jean II
- *	o Start adding Symbol support - need to check all that
- *	o Fix Prism2/Symbol WEP to accept 128 bits keys
- *	o Add Symbol WEP (add authentication type)
- *	o Add Prism2/Symbol rate
- *	o Add PM timeout (holdover duration)
- *	o Enable "iwconfig eth0 key off" and friends (toggle flags)
- *	o Enable "iwconfig eth0 power unicast/all" (toggle flags)
- *	o Try with an Intel card. It report firmware 1.01, behave like
- *	  an antiquated firmware, however on windows it says 2.00. Yuck !
- *	o Workaround firmware bug in allocate buffer (Intel 1.01)
- *	o Finish external renaming to orinoco...
- *	o Testing with various Wavelan firmwares
- *
- * v0.03 -> v0.04 - 30/3/2001 - Jean II
- *	o Update to Wireless 11 -> add retry limit/lifetime support
- *	o Tested with a D-Link DWL 650 card, fill in firmware support
- *	o Warning on Vcc mismatch (D-Link 3.3v card in Lucent 5v only slot)
- *	o Fixed the Prism2 WEP bugs that I introduced in v0.03 :-(
- *	  It works on D-Link *only* after a tcpdump. Weird...
- *	  And still doesn't work on Intel card. Grrrr...
- *	o Update the mode after a setport3
- *	o Add preamble setting for Symbol cards (not yet enabled)
- *	o Don't complain as much about Symbol cards...
- *
- * v0.04 -> v0.04b - 22/4/2001 - David Gibson
- *      o Removed the 'eth' parameter - always use ethXX as the
- *        interface name instead of dldwdXX.  The other was racy
- *        anyway.
- *	o Clean up RID definitions in hermes.h, other cleanups
- *
- * v0.04b -> v0.04c - 24/4/2001 - Jean II
- *	o Tim Hurley <timster AT seiki.bliztech.com> reported a D-Link card
- *	  with vendor 02 and firmware 0.08. Added in the capabilities...
- *	o Tested Lucent firmware 7.28, everything works...
- *
- * v0.04c -> v0.05 - 3/5/2001 - Benjamin Herrenschmidt
- *	o Spin-off Pcmcia code. This file is renamed orinoco.c,
- *	  and orinoco_cs.c now contains only the Pcmcia specific stuff
- *	o Add Airport driver support on top of orinoco.c (see airport.c)
- *
- * v0.05 -> v0.05a - 4/5/2001 - Jean II
- *	o Revert to old Pcmcia code to fix breakage of Ben's changes...
- *
- * v0.05a -> v0.05b - 4/5/2001 - Jean II
- *	o add module parameter 'ignore_cis_vcc' for D-Link @ 5V
- *	o D-Link firmware doesn't support multicast. We just print a few
- *	  error messages, but otherwise everything works...
- *	o For David : set/getport3 works fine, just upgrade iwpriv...
- *
- * v0.05b -> v0.05c - 5/5/2001 - Benjamin Herrenschmidt
- *	o Adapt airport.c to latest changes in orinoco.c
- *	o Remove deferred power enabling code
- *
- * v0.05c -> v0.05d - 5/5/2001 - Jean II
- *	o Workaround to SNAP decapsulate frame from Linksys AP
- *	  original patch from : Dong Liu <dliu AT research.bell-labs.com>
- *	  (note : the memcmp bug was mine - fixed)
- *	o Remove set_retry stuff, no firmware support it (bloat--).
- *
- * v0.05d -> v0.06 - 25/5/2001 - Jean II
- *		Original patch from "Hong Lin" <alin AT redhat.com>,
- *		"Ian Kinner" <ikinner AT redhat.com>
- *		and "David Smith" <dsmith AT redhat.com>
- *	o Init of priv->tx_rate_ctrl in firmware specific section.
- *	o Prism2/Symbol rate, upto should be 0xF and not 0x15. Doh !
- *	o Spectrum card always need cor_reset (for every reset)
- *	o Fix cor_reset to not lose bit 7 in the register
- *	o flush_stale_links to remove zombie Pcmcia instances
- *	o Ack previous hermes event before reset
- *		Me (with my little hands)
- *	o Allow orinoco.c to call cor_reset via priv->card_reset_handler
- *	o Add priv->need_card_reset to toggle this feature
- *	o Fix various buglets when setting WEP in Symbol firmware
- *	  Now, encryption is fully functional on Symbol cards. Youpi !
- *
- * v0.06 -> v0.06b - 25/5/2001 - Jean II
- *	o IBSS on Symbol use port_mode = 4. Please don't ask...
- *
- * v0.06b -> v0.06c - 29/5/2001 - Jean II
- *	o Show first spy address in /proc/net/wireless for IBSS mode as well
- *
- * v0.06c -> v0.06d - 6/7/2001 - David Gibson
- *      o Change a bunch of KERN_INFO messages to KERN_DEBUG, as per Linus'
- *        wishes to reduce the number of unnecessary messages.
- *	o Removed bogus message on CRC error.
- *	o Merged fixes for v0.08 Prism 2 firmware from William Waghorn
- *	  <willwaghorn AT yahoo.co.uk>
- *	o Slight cleanup/re-arrangement of firmware detection code.
- *
- * v0.06d -> v0.06e - 1/8/2001 - David Gibson
- *	o Removed some redundant global initializers (orinoco_cs.c).
- *	o Added some module metadata
- *
- * v0.06e -> v0.06f - 14/8/2001 - David Gibson
- *	o Wording fix to license
- *	o Added a 'use_alternate_encaps' module parameter for APs which need an
- *	  oui of 00:00:00.  We really need a better way of handling this, but
- *	  the module flag is better than nothing for now.
- *
- * v0.06f -> v0.07 - 20/8/2001 - David Gibson
- *	o Removed BAP error retries from hermes_bap_seek().  For Tx we now
- *	  let the upper layers handle the retry, we retry explicitly in the
- *	  Rx path, but don't make as much noise about it.
- *	o Firmware detection cleanups.
- *
- * v0.07 -> v0.07a - 1/10/3001 - Jean II
- *	o Add code to read Symbol firmware revision, inspired by latest code
- *	  in Spectrum24 by Lee John Keyser-Allen - Thanks Lee !
- *	o Thanks to Jared Valentine <hidden AT xmission.com> for "providing" me
- *	  a 3Com card with a recent firmware, fill out Symbol firmware
- *	  capabilities of latest rev (2.20), as well as older Symbol cards.
- *	o Disable Power Management in newer Symbol firmware, the API 
- *	  has changed (documentation needed).
- *
- * v0.07a -> v0.08 - 3/10/2001 - David Gibson
- *	o Fixed a possible buffer overrun found by the Stanford checker (in
- *	  dldwd_ioctl_setiwencode()).  Can only be called by root anyway, so not
- *	  a big problem.
- *	o Turned has_big_wep on for Intersil cards.  That's not true for all of
- *	  them but we should at least let the capable ones try.
- *	o Wait for BUSY to clear at the beginning of hermes_bap_seek().  I
- *	  realized that my assumption that the driver's serialization
- *	  would prevent the BAP being busy on entry was possibly false, because
- *	  things other than seeks may make the BAP busy.
- *	o Use "alternate" (oui 00:00:00) encapsulation by default.
- *	  Setting use_old_encaps will mimic the old behaviour, but I think we
- *	  will be able to eliminate this.
- *	o Don't try to make __initdata const (the version string).  This can't
- *	  work because of the way the __initdata sectioning works.
- *	o Added MODULE_LICENSE tags.
- *	o Support for PLX (transparent PCMCIA->PCI bridge) cards.
- *	o Changed to using the new type-fascist min/max.
- *
- * v0.08 -> v0.08a - 9/10/2001 - David Gibson
- *	o Inserted some missing acknowledgements/info into the Changelog.
- *	o Fixed some bugs in the normalization of signal level reporting.
- *	o Fixed bad bug in WEP key handling on Intersil and Symbol firmware,
- *	  which led to an instant crash on big-endian machines.
- *
- * v0.08a -> v0.08b - 20/11/2001 - David Gibson
- *	o Lots of cleanup and bugfixes in orinoco_plx.c
- *	o Cleanup to handling of Tx rate setting.
- *	o Removed support for old encapsulation method.
- *	o Removed old "dldwd" names.
- *	o Split RID constants into a new file hermes_rid.h
- *	o Renamed RID constants to match linux-wlan-ng and prism2.o
- *	o Bugfixes in hermes.c
- *	o Poke the PLX's INTCSR register, so it actually starts
- *	  generating interrupts.  These cards might actually work now.
- *	o Update to wireless extensions v12 (Jean II)
- *	o Support for tallies and inquire command (Jean II)
- *	o Airport updates for newer PPC kernels (BenH)
- *
- * v0.08b -> v0.09 - 21/12/2001 - David Gibson
- *	o Some new PCI IDs for PLX cards.
- *	o Removed broken attempt to do ALLMULTI reception.  Just use
- *	  promiscuous mode instead
- *	o Preliminary work for list-AP (Jean II)
- *	o Airport updates from (BenH)
- *	o Eliminated racy hw_ready stuff
- *	o Fixed generation of fake events in irq handler.  This should
- *	  finally kill the EIO problems (Jean II & dgibson)
- *	o Fixed breakage of bitrate set/get on Agere firmware (Jean II)
- *
- * v0.09 -> v0.09a - 2/1/2002 - David Gibson
- *	o Fixed stupid mistake in multicast list handling, triggering
- *	  a BUG()
- *
- * v0.09a -> v0.09b - 16/1/2002 - David Gibson
- *	o Fixed even stupider mistake in new interrupt handling, which
- *	  seriously broke things on big-endian machines.
- *	o Removed a bunch of redundant includes and exports.
- *	o Removed a redundant MOD_{INC,DEC}_USE_COUNT pair in airport.c
- *	o Don't attempt to do hardware level multicast reception on
- *	  Intersil firmware, just go promisc instead.
- *	o Typo fixed in hermes_issue_cmd()
- *	o Eliminated WIRELESS_SPY #ifdefs
- *	o Status code reported on Tx exceptions
- *	o Moved netif_wake_queue() from ALLOC interrupts to TX and TXEXC
- *	  interrupts, which should fix the timeouts we're seeing.
- *
- * v0.09b -> v0.10 - 25 Feb 2002 - David Gibson
- *	o Removed nested structures used for header parsing, so the
- *	  driver should now work without hackery on ARM
- *	o Fix for WEP handling on Intersil (Hawk Newton)
- *	o Eliminated the /proc/hermes/ethXX/regs debugging file.  It
- *	  was never very useful.
- *	o Make Rx errors less noisy.
- *
- * v0.10 -> v0.11 - 5 Apr 2002 - David Gibson
- *	o Laid the groundwork in hermes.[ch] for devices which map
- *	  into PCI memory space rather than IO space.
- *	o Fixed bug in multicast handling (cleared multicast list when
- *	  leaving promiscuous mode).
- *	o Relegated Tx error messages to debug.
- *	o Cleaned up / corrected handling of allocation lengths.
- *	o Set OWNSSID in IBSS mode for WinXP interoperability (jimc).
- *	o Change to using alloc_etherdev() for structure allocations. 
- *	o Check for and drop undersized packets.
- *	o Fixed a race in stopping/waking the queue.  This should fix
- *	  the timeout problems (Pavel Roskin)
- *	o Reverted to netif_wake_queue() on the ALLOC event.
- *	o Fixes for recent Symbol firmwares which lack AP density
- *	  (Pavel Roskin).
- *
- * v0.11 -> v0.11a - 29 Apr 2002 - David Gibson
- *	o Handle different register spacing, necessary for Prism 2.5
- *	  PCI adaptors (Steve Hill).
- *	o Cleaned up initialization of card structures in orinoco_cs
- *	  and airport.  Removed card->priv field.
- *	o Make response structure optional for hermes_docmd_wait()
- *	  Pavel Roskin)
- *	o Added PCI id for Nortel emobility to orinoco_plx.c.
- *	o Cleanup to handling of Symbol's allocation bug. (Pavel Roskin)
- *	o Cleanups to firmware capability detection.
- *	o Arrange for orinoco_pci.c to override firmware detection.
- *	  We should be able to support the PCI Intersil cards now.
- *	o Cleanup handling of reset_cor and hard_reset (Pavel Roskin).
- *	o Remove erroneous use of USER_BAP in the TxExc handler (Jouni
- *	  Malinen).
- *	o Makefile changes for better integration into David Hinds
- *	  pcmcia-cs package.
- *
- * v0.11a -> v0.11b - 1 May 2002 - David Gibson
- *	o Better error reporting in orinoco_plx_init_one()
- *	o Fixed multiple bad kfree() bugs introduced by the
- *	  alloc_orinocodev() changes.
- *
- * v0.11b -> v0.12 - 19 Jun 2002 - David Gibson
- *	o Support changing the MAC address.
- *	o Correct display of Intersil firmware revision numbers.
- *	o Entirely revised locking scheme.  Should be both simpler and
- *	   better.
- *	o Merged some common code in orinoco_plx, orinoco_pci and
- *	  airport by creating orinoco_default_{open,stop,reset}()
- *	  which are used as the dev->open, dev->stop, priv->reset
- *	  callbacks if none are specified when alloc_orinocodev() is
- *	  called.
- *	o Removed orinoco_plx_interrupt() and orinoco_pci_interrupt().
- *	  They didn't do anything.
- *
- * v0.12 -> v0.12a - 4 Jul 2002 - David Gibson
- *	o Some rearrangement of code.
- *	o Numerous fixups to locking and rest handling, particularly
- *	  for PCMCIA.
- *	o This allows open and stop net_device methods to be in
- *	  orinoco.c now, rather than in the init modules.
- *	o In orinoco_cs.c link->priv now points to the struct
- *	  net_device not to the struct orinoco_private.
- *	o Added a check for undersized SNAP frames, which could cause
- *	  crashes.
- *
- * v0.12a -> v0.12b - 11 Jul 2002 - David Gibson
- *	o Fix hw->num_init testing code, so num_init is actually
- *	  incremented.
- *	o Fix very stupid bug in orinoco_cs which broke compile with
- *	  CONFIG_SMP.
- *	o Squashed a warning.
- *
- * v0.12b -> v0.12c - 26 Jul 2002 - David Gibson
- *	o Change to C9X style designated initializers.
- *	o Add support for 3Com AirConnect PCI.
- *	o No longer ignore the hard_reset argument to
- *	  alloc_orinocodev().  Oops.
- *
- * v0.12c -> v0.13beta1 - 13 Sep 2002 - David Gibson
- *	o Revert the broken 0.12* locking scheme and go to a new yet
- *	  simpler scheme.
- *	o Do firmware resets only in orinoco_init() and when waking
- *	  the card from hard sleep.
- *
- * v0.13beta1 -> v0.13 - 27 Sep 2002 - David Gibson
- *	o Re-introduced full resets (via schedule_task()) on Tx
- *	  timeout.
- *
- * v0.13 -> v0.13a - 30 Sep 2002 - David Gibson
- *	o Minor cleanups to info frame handling.  Add basic support
- *	  for linkstatus info frames.
- *	o Include required kernel headers in orinoco.h, to avoid
- *	  compile problems.
- *
- * v0.13a -> v0.13b - 10 Feb 2003 - David Gibson
- *	o Implemented hard reset for Airport cards
- *	o Experimental suspend/resume implementation for orinoco_pci
- *	o Abolished /proc debugging support, replaced with a debugging
- *	  iwpriv.  Now it's ugly and simple instead of ugly and complex.
- *	o Bugfix in hermes.c if the firmware returned a record length
- *	  of 0, we could go clobbering memory.
- *	o Bugfix in orinoco_stop() - it used to fail if hw_unavailable
- *	  was set, which was usually true on PCMCIA hot removes.
- * 	o Track LINKSTATUS messages, silently drop Tx packets before
- * 	  we are connected (avoids confusing the firmware), and only
- * 	  give LINKSTATUS printk()s if the status has changed.
- *
- * v0.13b -> v0.13c - 11 Mar 2003 - David Gibson
- *	o Cleanup: use dev instead of priv in various places.
- *	o Bug fix: Don't ReleaseConfiguration on RESET_PHYSICAL event
- *	  if we're in the middle of a (driver initiated) hard reset.
- *	o Bug fix: ETH_ZLEN is supposed to include the header
- *	  (Dionysus Blazakis & Manish Karir)
- *	o Convert to using workqueues instead of taskqueues (and
- *	  backwards compatibility macros for pre 2.5.41 kernels).
- *	o Drop redundant (I think...) MOD_{INC,DEC}_USE_COUNT in
- *	  airport.c
- *	o New orinoco_tmd.c init module from Joerg Dorchain for
- *	  TMD7160 based PCI to PCMCIA bridges (similar to
- *	  orinoco_plx.c).
- *
- * v0.13c -> v0.13d - 22 Apr 2003 - David Gibson
- *	o Make hw_unavailable a counter, rather than just a flag, this
- *	  is necessary to avoid some races (such as a card being
- *	  removed in the middle of orinoco_reset().
- *	o Restore Release/RequestConfiguration in the PCMCIA event handler
- *	  when dealing with a driver initiated hard reset.  This is
- *	  necessary to prevent hangs due to a spurious interrupt while
- *	  the reset is in progress.
- *	o Clear the 802.11 header when transmitting, even though we
- *	  don't use it.  This fixes a long standing bug on some
- *	  firmwares, which seem to get confused if that isn't done.
- *	o Be less eager to de-encapsulate SNAP frames, only do so if
- *	  the OUI is 00:00:00 or 00:00:f8, leave others alone.  The old
- *	  behaviour broke CDP (Cisco Discovery Protocol).
- *	o Use dev instead of priv for free_irq() as well as
- *	  request_irq() (oops).
- *	o Attempt to reset rather than giving up if we get too many
- *	  IRQs.
- *	o Changed semantics of __orinoco_down() so it can be called
- *	  safely with hw_unavailable set.  It also now clears the
- *	  linkstatus (since we're going to have to reassociate).
- *
- * v0.13d -> v0.13e - 12 May 2003 - David Gibson
- *	o Support for post-2.5.68 return values from irq handler.
- *	o Fixed bug where underlength packets would be double counted
- *	  in the rx_dropped statistics.
- *	o Provided a module parameter to suppress linkstatus messages.
- *
- * v0.13e -> v0.14alpha1 - 30 Sep 2003 - David Gibson
- *	o Replaced priv->connected logic with netif_carrier_on/off()
- *	  calls.
- *	o Remove has_ibss_any and never set the CREATEIBSS RID when
- *	  the ESSID is empty.  Too many firmwares break if we do.
- *	o 2.6 merges: Replace pdev->slot_name with pci_name(), remove
- *	  __devinitdata from PCI ID tables, use free_netdev().
- *	o Enabled shared-key authentication for Agere firmware (from
- *	  Robert J. Moore <Robert.J.Moore AT allanbank.com>
- *	o Move netif_wake_queue() (back) to the Tx completion from the
- *	  ALLOC event.  This seems to prevent/mitigate the rolling
- *	  error -110 problems at least on some Intersil firmwares.
- *	  Theoretically reduces performance, but I can't measure it.
- *	  Patch from Andrew Tridgell <tridge AT samba.org>
- *
- * v0.14alpha1 -> v0.14alpha2 - 20 Oct 2003 - David Gibson
- *	o Correctly turn off shared-key authentication when requested
- *	  (bugfix from Robert J. Moore).
- *	o Correct airport sleep interfaces for current 2.6 kernels.
- *	o Add code for key change without disabling/enabling the MAC
- *	  port.  This is supposed to allow 802.1x to work sanely, but
- *	  doesn't seem to yet.
- *
  * TODO
- *	o New wireless extensions API (patch from Moustafa
- *	  Youssef, updated by Jim Carter and Pavel Roskin).
  *	o Handle de-encapsulation within network layer, provide 802.11
  *	  headers (patch from Thomas 'Dent' Mirlacher)
- *	o RF monitor mode support
  *	o Fix possible races in SPY handling.
  *	o Disconnect wireless extensions from fundamental configuration.
  *	o (maybe) Software WEP support (patch from Stano Meduna).
@@ -462,7 +89,10 @@
 #include <linux/netdevice.h>
 #include <linux/if_arp.h>
 #include <linux/etherdevice.h>
+#include <linux/ethtool.h>
 #include <linux/wireless.h>
+#include <net/iw_handler.h>
+#include <net/ieee80211.h>
 
 #include <asm/uaccess.h>
 #include <asm/io.h>
@@ -492,6 +122,13 @@ EXPORT_SYMBOL(orinoco_debug);
 static int suppress_linkstatus; /* = 0 */
 module_param(suppress_linkstatus, bool, 0644);
 MODULE_PARM_DESC(suppress_linkstatus, "Don't log link status changes");
+static int ignore_disconnect; /* = 0 */
+module_param(ignore_disconnect, int, 0644);
+MODULE_PARM_DESC(ignore_disconnect, "Don't report lost link to the network layer");
+
+static int force_monitor; /* = 0 */
+module_param(force_monitor, int, 0644);
+MODULE_PARM_DESC(force_monitor, "Allow monitor mode for all firmware versions");
 
 /********************************************************************/
 /* Compile time configuration and compatibility stuff               */
@@ -508,6 +145,10 @@ MODULE_PARM_DESC(suppress_linkstatus, "D
 /* Internal constants                                               */
 /********************************************************************/
 
+/* 802.2 LLC/SNAP header used for Ethernet encapsulation over 802.11 */
+static const u8 encaps_hdr[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
+#define ENCAPS_OVERHEAD		(sizeof(encaps_hdr) + 2)
+
 #define ORINOCO_MIN_MTU		256
 #define ORINOCO_MAX_MTU		(IEEE802_11_DATA_LEN - ENCAPS_OVERHEAD)
 
@@ -534,6 +175,11 @@ MODULE_PARM_DESC(suppress_linkstatus, "D
 				 | HERMES_EV_WTERR | HERMES_EV_INFO \
 				 | HERMES_EV_INFDROP )
 
+#define MAX_RID_LEN 1024
+
+static const struct iw_handler_def orinoco_handler_def;
+static struct ethtool_ops orinoco_ethtool_ops;
+
 /********************************************************************/
 /* Data tables                                                      */
 /********************************************************************/
@@ -568,26 +214,45 @@ static struct {
 /* Data types                                                       */
 /********************************************************************/
 
-struct header_struct {
-	/* 802.3 */
-	u8 dest[ETH_ALEN];
-	u8 src[ETH_ALEN];
-	u16 len;
-	/* 802.2 */
+/* Used in Event handling.
+ * We avoid nested structres as they break on ARM -- Moustafa */
+struct hermes_tx_descriptor_802_11 {
+	/* hermes_tx_descriptor */
+	u16 status;
+	u16 reserved1;
+	u16 reserved2;
+	u32 sw_support;
+	u8 retry_count;
+	u8 tx_rate;
+	u16 tx_control;
+
+	/* ieee802_11_hdr */
+	u16 frame_ctl;
+	u16 duration_id;
+	u8 addr1[ETH_ALEN];
+	u8 addr2[ETH_ALEN];
+	u8 addr3[ETH_ALEN];
+	u16 seq_ctl;
+	u8 addr4[ETH_ALEN];
+	u16 data_len;
+
+	/* ethhdr */
+	unsigned char   h_dest[ETH_ALEN];       /* destination eth addr */
+	unsigned char   h_source[ETH_ALEN];     /* source ether addr    */
+	unsigned short  h_proto;                /* packet type ID field */
+
+	/* p8022_hdr */
 	u8 dsap;
 	u8 ssap;
 	u8 ctrl;
-	/* SNAP */
 	u8 oui[3];
+
 	u16 ethertype;
 } __attribute__ ((packed));
 
-/* 802.2 LLC/SNAP header used for Ethernet encapsulation over 802.11 */
-u8 encaps_hdr[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
-
-#define ENCAPS_OVERHEAD		(sizeof(encaps_hdr) + 2)
-
+/* Rx frame header except compatibility 802.3 header */
 struct hermes_rx_descriptor {
+	/* Control */
 	u16 status;
 	u32 time;
 	u8 silence;
@@ -595,16 +260,26 @@ struct hermes_rx_descriptor {
 	u8 rate;
 	u8 rxflow;
 	u32 reserved;
+
+	/* 802.11 header */
+	u16 frame_ctl;
+	u16 duration_id;
+	u8 addr1[ETH_ALEN];
+	u8 addr2[ETH_ALEN];
+	u8 addr3[ETH_ALEN];
+	u16 seq_ctl;
+	u8 addr4[ETH_ALEN];
+
+	/* Data length */
+	u16 data_len;
 } __attribute__ ((packed));
 
 /********************************************************************/
 /* Function prototypes                                              */
 /********************************************************************/
 
-static int orinoco_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
 static int __orinoco_program_rids(struct net_device *dev);
 static void __orinoco_set_multicast_list(struct net_device *dev);
-static int orinoco_debug_dump_recs(struct net_device *dev);
 
 /********************************************************************/
 /* Internal helper functions                                        */
@@ -626,6 +301,10 @@ static inline void set_port_type(struct 
 			priv->createibss = 1;
 		}
 		break;
+	case IW_MODE_MONITOR:
+		priv->port_type = 3;
+		priv->createibss = 0;
+		break;
 	default:
 		printk(KERN_ERR "%s: Invalid priv->iw_mode in set_port_type()\n",
 		       priv->ndev->name);
@@ -655,7 +334,7 @@ static int orinoco_open(struct net_devic
 	return err;
 }
 
-int orinoco_stop(struct net_device *dev)
+static int orinoco_stop(struct net_device *dev)
 {
 	struct orinoco_private *priv = netdev_priv(dev);
 	int err = 0;
@@ -686,7 +365,7 @@ static struct iw_statistics *orinoco_get
 	struct orinoco_private *priv = netdev_priv(dev);
 	hermes_t *hw = &priv->hw;
 	struct iw_statistics *wstats = &priv->wstats;
-	int err = 0;
+	int err;
 	unsigned long flags;
 
 	if (! netif_device_present(dev)) {
@@ -695,9 +374,21 @@ static struct iw_statistics *orinoco_get
 		return NULL; /* FIXME: Can we do better than this? */
 	}
 
+	/* If busy, return the old stats.  Returning NULL may cause
+	 * the interface to disappear from /proc/net/wireless */
 	if (orinoco_lock(priv, &flags) != 0)
-		return NULL;  /* FIXME: Erg, we've been signalled, how
-			       * do we propagate this back up? */
+		return wstats;
+
+	/* We can't really wait for the tallies inquiry command to
+	 * complete, so we just use the previous results and trigger
+	 * a new tallies inquiry command for next time - Jean II */
+	/* FIXME: Really we should wait for the inquiry to come back -
+	 * as it is the stats we give don't make a whole lot of sense.
+	 * Unfortunately, it's not clear how to do that within the
+	 * wireless extensions framework: I think we're in user
+	 * context, but a lock seems to be held by the time we get in
+	 * here so we're not safe to sleep here. */
+	hermes_inquire(hw, HERMES_INQ_TALLIES);
 
 	if (priv->iw_mode == IW_MODE_ADHOC) {
 		memset(&wstats->qual, 0, sizeof(wstats->qual));
@@ -716,25 +407,16 @@ static struct iw_statistics *orinoco_get
 
 		err = HERMES_READ_RECORD(hw, USER_BAP,
 					 HERMES_RID_COMMSQUALITY, &cq);
-		
-		wstats->qual.qual = (int)le16_to_cpu(cq.qual);
-		wstats->qual.level = (int)le16_to_cpu(cq.signal) - 0x95;
-		wstats->qual.noise = (int)le16_to_cpu(cq.noise) - 0x95;
-		wstats->qual.updated = 7;
+
+		if (!err) {
+			wstats->qual.qual = (int)le16_to_cpu(cq.qual);
+			wstats->qual.level = (int)le16_to_cpu(cq.signal) - 0x95;
+			wstats->qual.noise = (int)le16_to_cpu(cq.noise) - 0x95;
+			wstats->qual.updated = 7;
+		}
 	}
 
-	/* We can't really wait for the tallies inquiry command to
-	 * complete, so we just use the previous results and trigger
-	 * a new tallies inquiry command for next time - Jean II */
-	/* FIXME: We're in user context (I think?), so we should just
-           wait for the tallies to come through */
-	err = hermes_inquire(hw, HERMES_INQ_TALLIES);
-               
 	orinoco_unlock(priv, &flags);
-
-	if (err)
-		return NULL;
-		
 	return wstats;
 }
 
@@ -809,7 +491,7 @@ static int orinoco_xmit(struct sk_buff *
 		return 1;
 	}
 
-	if (! netif_carrier_ok(dev)) {
+	if (! netif_carrier_ok(dev) || (priv->iw_mode == IW_MODE_MONITOR)) {
 		/* Oops, the firmware hasn't established a connection,
                    silently drop the packet (this seems to be the
                    safest approach). */
@@ -946,26 +628,55 @@ static void __orinoco_ev_txexc(struct ne
 	struct orinoco_private *priv = netdev_priv(dev);
 	struct net_device_stats *stats = &priv->stats;
 	u16 fid = hermes_read_regn(hw, TXCOMPLFID);
-	struct hermes_tx_descriptor desc;
+	struct hermes_tx_descriptor_802_11 hdr;
 	int err = 0;
 
 	if (fid == DUMMY_FID)
 		return; /* Nothing's really happened */
 
-	err = hermes_bap_pread(hw, IRQ_BAP, &desc, sizeof(desc), fid, 0);
+	/* Read the frame header */
+	err = hermes_bap_pread(hw, IRQ_BAP, &hdr,
+			       sizeof(struct hermes_tx_descriptor) +
+			       sizeof(struct ieee80211_hdr),
+			       fid, 0);
+
+	hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID);
+	stats->tx_errors++;
+
 	if (err) {
 		printk(KERN_WARNING "%s: Unable to read descriptor on Tx error "
 		       "(FID=%04X error %d)\n",
 		       dev->name, fid, err);
-	} else {
-		DEBUG(1, "%s: Tx error, status %d\n",
-		      dev->name, le16_to_cpu(desc.status));
+		return;
 	}
 	
-	stats->tx_errors++;
+	DEBUG(1, "%s: Tx error, err %d (FID=%04X)\n", dev->name,
+	      err, fid);
+    
+	/* We produce a TXDROP event only for retry or lifetime
+	 * exceeded, because that's the only status that really mean
+	 * that this particular node went away.
+	 * Other errors means that *we* screwed up. - Jean II */
+	hdr.status = le16_to_cpu(hdr.status);
+	if (hdr.status & (HERMES_TXSTAT_RETRYERR | HERMES_TXSTAT_AGEDERR)) {
+		union iwreq_data	wrqu;
+
+		/* Copy 802.11 dest address.
+		 * We use the 802.11 header because the frame may
+		 * not be 802.3 or may be mangled...
+		 * In Ad-Hoc mode, it will be the node address.
+		 * In managed mode, it will be most likely the AP addr
+		 * User space will figure out how to convert it to
+		 * whatever it needs (IP address or else).
+		 * - Jean II */
+		memcpy(wrqu.addr.sa_data, hdr.addr1, ETH_ALEN);
+		wrqu.addr.sa_family = ARPHRD_ETHER;
+
+		/* Send event to user space */
+		wireless_send_event(dev, IWEVTXDROP, &wrqu, NULL);
+	}
 
 	netif_wake_queue(dev);
-	hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID);
 }
 
 static void orinoco_tx_timeout(struct net_device *dev)
@@ -1042,18 +753,127 @@ static void orinoco_stat_gather(struct n
 	}
 }
 
+/*
+ * orinoco_rx_monitor - handle received monitor frames.
+ *
+ * Arguments:
+ *	dev		network device
+ *	rxfid		received FID
+ *	desc		rx descriptor of the frame
+ *
+ * Call context: interrupt
+ */
+static void orinoco_rx_monitor(struct net_device *dev, u16 rxfid,
+			       struct hermes_rx_descriptor *desc)
+{
+	u32 hdrlen = 30;	/* return full header by default */
+	u32 datalen = 0;
+	u16 fc;
+	int err;
+	int len;
+	struct sk_buff *skb;
+	struct orinoco_private *priv = netdev_priv(dev);
+	struct net_device_stats *stats = &priv->stats;
+	hermes_t *hw = &priv->hw;
+
+	len = le16_to_cpu(desc->data_len);
+
+	/* Determine the size of the header and the data */
+	fc = le16_to_cpu(desc->frame_ctl);
+	switch (fc & IEEE80211_FCTL_FTYPE) {
+	case IEEE80211_FTYPE_DATA:
+		if ((fc & IEEE80211_FCTL_TODS)
+		    && (fc & IEEE80211_FCTL_FROMDS))
+			hdrlen = 30;
+		else
+			hdrlen = 24;
+		datalen = len;
+		break;
+	case IEEE80211_FTYPE_MGMT:
+		hdrlen = 24;
+		datalen = len;
+		break;
+	case IEEE80211_FTYPE_CTL:
+		switch (fc & IEEE80211_FCTL_STYPE) {
+		case IEEE80211_STYPE_PSPOLL:
+		case IEEE80211_STYPE_RTS:
+		case IEEE80211_STYPE_CFEND:
+		case IEEE80211_STYPE_CFENDACK:
+			hdrlen = 16;
+			break;
+		case IEEE80211_STYPE_CTS:
+		case IEEE80211_STYPE_ACK:
+			hdrlen = 10;
+			break;
+		}
+		break;
+	default:
+		/* Unknown frame type */
+		break;
+	}
+
+	/* sanity check the length */
+	if (datalen > IEEE80211_DATA_LEN + 12) {
+		printk(KERN_DEBUG "%s: oversized monitor frame, "
+		       "data length = %d\n", dev->name, datalen);
+		err = -EIO;
+		stats->rx_length_errors++;
+		goto update_stats;
+	}
+
+	skb = dev_alloc_skb(hdrlen + datalen);
+	if (!skb) {
+		printk(KERN_WARNING "%s: Cannot allocate skb for monitor frame\n",
+		       dev->name);
+		err = -ENOMEM;
+		goto drop;
+	}
+
+	/* Copy the 802.11 header to the skb */
+	memcpy(skb_put(skb, hdrlen), &(desc->frame_ctl), hdrlen);
+	skb->mac.raw = skb->data;
+
+	/* If any, copy the data from the card to the skb */
+	if (datalen > 0) {
+		err = hermes_bap_pread(hw, IRQ_BAP, skb_put(skb, datalen),
+				       ALIGN(datalen, 2), rxfid,
+				       HERMES_802_2_OFFSET);
+		if (err) {
+			printk(KERN_ERR "%s: error %d reading monitor frame\n",
+			       dev->name, err);
+			goto drop;
+		}
+	}
+
+	skb->dev = dev;
+	skb->ip_summed = CHECKSUM_NONE;
+	skb->pkt_type = PACKET_OTHERHOST;
+	skb->protocol = __constant_htons(ETH_P_802_2);
+	
+	dev->last_rx = jiffies;
+	stats->rx_packets++;
+	stats->rx_bytes += skb->len;
+
+	netif_rx(skb);
+	return;
+
+ drop:
+	dev_kfree_skb_irq(skb);
+ update_stats:
+	stats->rx_errors++;
+	stats->rx_dropped++;
+}
+
 static void __orinoco_ev_rx(struct net_device *dev, hermes_t *hw)
 {
 	struct orinoco_private *priv = netdev_priv(dev);
 	struct net_device_stats *stats = &priv->stats;
 	struct iw_statistics *wstats = &priv->wstats;
 	struct sk_buff *skb = NULL;
-	u16 rxfid, status;
-	int length, data_len, data_off;
-	char *p;
+	u16 rxfid, status, fc;
+	int length;
 	struct hermes_rx_descriptor desc;
-	struct header_struct hdr;
-	struct ethhdr *eh;
+	struct ethhdr *hdr;
 	int err;
 
 	rxfid = hermes_read_regn(hw, RXFID);
@@ -1063,53 +883,46 @@ static void __orinoco_ev_rx(struct net_d
 	if (err) {
 		printk(KERN_ERR "%s: error %d reading Rx descriptor. "
 		       "Frame dropped.\n", dev->name, err);
-		stats->rx_errors++;
-		goto drop;
+		goto update_stats;
 	}
 
 	status = le16_to_cpu(desc.status);
 
-	if (status & HERMES_RXSTAT_ERR) {
-		if (status & HERMES_RXSTAT_UNDECRYPTABLE) {
-			wstats->discard.code++;
-			DEBUG(1, "%s: Undecryptable frame on Rx. Frame dropped.\n",
-			       dev->name);
-		} else {
-			stats->rx_crc_errors++;
-			DEBUG(1, "%s: Bad CRC on Rx. Frame dropped.\n", dev->name);
-		}
-		stats->rx_errors++;
-		goto drop;
+	if (status & HERMES_RXSTAT_BADCRC) {
+		DEBUG(1, "%s: Bad CRC on Rx. Frame dropped.\n",
+		      dev->name);
+		stats->rx_crc_errors++;
+		goto update_stats;
 	}
 
-	/* For now we ignore the 802.11 header completely, assuming
-           that the card's firmware has handled anything vital */
+	/* Handle frames in monitor mode */
+	if (priv->iw_mode == IW_MODE_MONITOR) {
+		orinoco_rx_monitor(dev, rxfid, &desc);
+		return;
+	}
 
-	err = hermes_bap_pread(hw, IRQ_BAP, &hdr, sizeof(hdr),
-			       rxfid, HERMES_802_3_OFFSET);
-	if (err) {
-		printk(KERN_ERR "%s: error %d reading frame header. "
-		       "Frame dropped.\n", dev->name, err);
-		stats->rx_errors++;
-		goto drop;
+	if (status & HERMES_RXSTAT_UNDECRYPTABLE) {
+		DEBUG(1, "%s: Undecryptable frame on Rx. Frame dropped.\n",
+		      dev->name);
+		wstats->discard.code++;
+		goto update_stats;
 	}
 
-	length = ntohs(hdr.len);
-	
+	length = le16_to_cpu(desc.data_len);
+	fc = le16_to_cpu(desc.frame_ctl);
+
 	/* Sanity checks */
 	if (length < 3) { /* No for even an 802.2 LLC header */
 		/* At least on Symbol firmware with PCF we get quite a
                    lot of these legitimately - Poll frames with no
                    data. */
-		stats->rx_dropped++;
-		goto drop;
+		return;
 	}
 	if (length > IEEE802_11_DATA_LEN) {
 		printk(KERN_WARNING "%s: Oversized frame received (%d bytes)\n",
 		       dev->name, length);
 		stats->rx_length_errors++;
-		stats->rx_errors++;
-		goto drop;
+		goto update_stats;
 	}
 
 	/* We need space for the packet data itself, plus an ethernet
@@ -1121,60 +934,53 @@ static void __orinoco_ev_rx(struct net_d
 	if (!skb) {
 		printk(KERN_WARNING "%s: Can't allocate skb for Rx\n",
 		       dev->name);
-		goto drop;
+		goto update_stats;
 	}
 
-	skb_reserve(skb, 2); /* This way the IP header is aligned */
+	/* We'll prepend the header, so reserve space for it.  The worst
+	   case is no decapsulation, when 802.3 header is prepended and
+	   nothing is removed.  2 is for aligning the IP header.  */
+	skb_reserve(skb, ETH_HLEN + 2);
+
+	err = hermes_bap_pread(hw, IRQ_BAP, skb_put(skb, length),
+			       ALIGN(length, 2), rxfid,
+			       HERMES_802_2_OFFSET);
+	if (err) {
+		printk(KERN_ERR "%s: error %d reading frame. "
+		       "Frame dropped.\n", dev->name, err);
+		goto drop;
+	}
 
 	/* Handle decapsulation
 	 * In most cases, the firmware tell us about SNAP frames.
 	 * For some reason, the SNAP frames sent by LinkSys APs
 	 * are not properly recognised by most firmwares.
 	 * So, check ourselves */
-	if (((status & HERMES_RXSTAT_MSGTYPE) == HERMES_RXSTAT_1042) ||
-	    ((status & HERMES_RXSTAT_MSGTYPE) == HERMES_RXSTAT_TUNNEL) ||
-	    is_ethersnap(&hdr)) {
+	if (length >= ENCAPS_OVERHEAD &&
+	    (((status & HERMES_RXSTAT_MSGTYPE) == HERMES_RXSTAT_1042) ||
+	     ((status & HERMES_RXSTAT_MSGTYPE) == HERMES_RXSTAT_TUNNEL) ||
+	     is_ethersnap(skb->data))) {
 		/* These indicate a SNAP within 802.2 LLC within
 		   802.11 frame which we'll need to de-encapsulate to
 		   the original EthernetII frame. */
-
-		if (length < ENCAPS_OVERHEAD) { /* No room for full LLC+SNAP */
-			stats->rx_length_errors++;
-			goto drop;
-		}
-
-		/* Remove SNAP header, reconstruct EthernetII frame */
-		data_len = length - ENCAPS_OVERHEAD;
-		data_off = HERMES_802_3_OFFSET + sizeof(hdr);
-
-		eh = (struct ethhdr *)skb_put(skb, ETH_HLEN);
-
-		memcpy(eh, &hdr, 2 * ETH_ALEN);
-		eh->h_proto = hdr.ethertype;
+		hdr = (struct ethhdr *)skb_push(skb, ETH_HLEN - ENCAPS_OVERHEAD);
 	} else {
-		/* All other cases indicate a genuine 802.3 frame.  No
-		   decapsulation needed.  We just throw the whole
-		   thing in, and hope the protocol layer can deal with
-		   it as 802.3 */
-		data_len = length;
-		data_off = HERMES_802_3_OFFSET;
-		/* FIXME: we re-read from the card data we already read here */
-	}
-
-	p = skb_put(skb, data_len);
-	err = hermes_bap_pread(hw, IRQ_BAP, p, ALIGN(data_len, 2),
-			       rxfid, data_off);
-	if (err) {
-		printk(KERN_ERR "%s: error %d reading frame. "
-		       "Frame dropped.\n", dev->name, err);
-		stats->rx_errors++;
-		goto drop;
-	}
+		/* 802.3 frame - prepend 802.3 header as is */
+		hdr = (struct ethhdr *)skb_push(skb, ETH_HLEN);
+		hdr->h_proto = htons(length);
+	}
+	memcpy(hdr->h_dest, desc.addr1, ETH_ALEN);
+	if (fc & IEEE80211_FCTL_FROMDS)
+		memcpy(hdr->h_source, desc.addr3, ETH_ALEN);
+	else
+		memcpy(hdr->h_source, desc.addr2, ETH_ALEN);
 
 	dev->last_rx = jiffies;
 	skb->dev = dev;
 	skb->protocol = eth_type_trans(skb, dev);
 	skb->ip_summed = CHECKSUM_NONE;
+	if (fc & IEEE80211_FCTL_TODS)
+		skb->pkt_type = PACKET_OTHERHOST;
 	
 	/* Process the wireless stats if needed */
 	orinoco_stat_gather(dev, skb, &desc);
@@ -1187,11 +993,10 @@ static void __orinoco_ev_rx(struct net_d
 	return;
 
  drop:	
+	dev_kfree_skb_irq(skb);
+ update_stats:
+	stats->rx_errors++;
 	stats->rx_dropped++;
-
-	if (skb)
-		dev_kfree_skb_irq(skb);
-	return;
 }
 
 /********************************************************************/
@@ -1235,6 +1040,99 @@ static void print_linkstatus(struct net_
 	       dev->name, s, status);
 }
 
+/* Search scan results for requested BSSID, join it if found */
+static void orinoco_join_ap(struct net_device *dev)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+	struct hermes *hw = &priv->hw;
+	int err;
+	unsigned long flags;
+	struct join_req {
+		u8 bssid[ETH_ALEN];
+		u16 channel;
+	} __attribute__ ((packed)) req;
+	const int atom_len = offsetof(struct prism2_scan_apinfo, atim);
+	struct prism2_scan_apinfo *atom;
+	int offset = 4;
+	u8 *buf;
+	u16 len;
+
+	/* Allocate buffer for scan results */
+	buf = kmalloc(MAX_SCAN_LEN, GFP_KERNEL);
+	if (! buf)
+		return;
+
+	if (orinoco_lock(priv, &flags) != 0)
+		goto out;
+
+	/* Sanity checks in case user changed something in the meantime */
+	if (! priv->bssid_fixed)
+		goto out;
+
+	if (strlen(priv->desired_essid) == 0)
+		goto out;
+
+	/* Read scan results from the firmware */
+	err = hermes_read_ltv(hw, USER_BAP,
+			      HERMES_RID_SCANRESULTSTABLE,
+			      MAX_SCAN_LEN, &len, buf);
+	if (err) {
+		printk(KERN_ERR "%s: Cannot read scan results\n",
+		       dev->name);
+		goto out;
+	}
+
+	len = HERMES_RECLEN_TO_BYTES(len);
+
+	/* Go through the scan results looking for the channel of the AP
+	 * we were requested to join */
+	for (; offset + atom_len <= len; offset += atom_len) {
+		atom = (struct prism2_scan_apinfo *) (buf + offset);
+		if (memcmp(&atom->bssid, priv->desired_bssid, ETH_ALEN) == 0)
+			goto found;
+	}
+
+	DEBUG(1, "%s: Requested AP not found in scan results\n",
+	      dev->name);
+	goto out;
+
+ found:
+	memcpy(req.bssid, priv->desired_bssid, ETH_ALEN);
+	req.channel = atom->channel;	/* both are little-endian */
+	err = HERMES_WRITE_RECORD(hw, USER_BAP, HERMES_RID_CNFJOINREQUEST,
+				  &req);
+	if (err)
+		printk(KERN_ERR "%s: Error issuing join request\n", dev->name);
+
+ out:
+	kfree(buf);
+	orinoco_unlock(priv, &flags);
+}
+
+/* Send new BSSID to userspace */
+static void orinoco_send_wevents(struct net_device *dev)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+	struct hermes *hw = &priv->hw;
+	union iwreq_data wrqu;
+	int err;
+	unsigned long flags;
+
+	if (orinoco_lock(priv, &flags) != 0)
+		return;
+
+	err = hermes_read_ltv(hw, IRQ_BAP, HERMES_RID_CURRENTBSSID,
+			      ETH_ALEN, NULL, wrqu.ap_addr.sa_data);
+	if (err != 0)
+		return;
+
+	wrqu.ap_addr.sa_family = ARPHRD_ETHER;
+
+	/* Send event to user space */
+	wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
+	orinoco_unlock(priv, &flags);
+}
+
 static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
 {
 	struct orinoco_private *priv = netdev_priv(dev);
@@ -1275,9 +1173,10 @@ static void __orinoco_ev_info(struct net
 			len = sizeof(tallies);
 		}
 		
-		/* Read directly the data (no seek) */
-		hermes_read_words(hw, HERMES_DATA1, (void *) &tallies,
-				  len / 2); /* FIXME: blech! */
+		err = hermes_bap_pread(hw, IRQ_BAP, &tallies, len,
+				       infofid, sizeof(info));
+		if (err)
+			break;
 		
 		/* Increment our various counters */
 		/* wstats->discard.nwid - no wrong BSSID stuff */
@@ -1301,31 +1200,122 @@ static void __orinoco_ev_info(struct net
 		u16 newstatus;
 		int connected;
 
+		if (priv->iw_mode == IW_MODE_MONITOR)
+			break;
+
 		if (len != sizeof(linkstatus)) {
 			printk(KERN_WARNING "%s: Unexpected size for linkstatus frame (%d bytes)\n",
 			       dev->name, len);
 			break;
 		}
 
-		hermes_read_words(hw, HERMES_DATA1, (void *) &linkstatus,
-				  len / 2);
+		err = hermes_bap_pread(hw, IRQ_BAP, &linkstatus, len,
+				       infofid, sizeof(info));
+		if (err)
+			break;
 		newstatus = le16_to_cpu(linkstatus.linkstatus);
 
+		/* Symbol firmware uses "out of range" to signal that
+		 * the hostscan frame can be requested.  */
+		if (newstatus == HERMES_LINKSTATUS_AP_OUT_OF_RANGE &&
+		    priv->firmware_type == FIRMWARE_TYPE_SYMBOL &&
+		    priv->has_hostscan && priv->scan_inprogress) {
+			hermes_inquire(hw, HERMES_INQ_HOSTSCAN_SYMBOL);
+			break;
+		}
+
 		connected = (newstatus == HERMES_LINKSTATUS_CONNECTED)
 			|| (newstatus == HERMES_LINKSTATUS_AP_CHANGE)
 			|| (newstatus == HERMES_LINKSTATUS_AP_IN_RANGE);
 
 		if (connected)
 			netif_carrier_on(dev);
-		else
+		else if (!ignore_disconnect)
 			netif_carrier_off(dev);
 
-		if (newstatus != priv->last_linkstatus)
+		if (newstatus != priv->last_linkstatus) {
+			priv->last_linkstatus = newstatus;
 			print_linkstatus(dev, newstatus);
+			/* The info frame contains only one word which is the
+			 * status (see hermes.h). The status is pretty boring
+			 * in itself, that's why we export the new BSSID...
+			 * Jean II */
+			schedule_work(&priv->wevent_work);
+		}
+	}
+	break;
+	case HERMES_INQ_SCAN:
+		if (!priv->scan_inprogress && priv->bssid_fixed &&
+		    priv->firmware_type == FIRMWARE_TYPE_INTERSIL) {
+			schedule_work(&priv->join_work);
+			break;
+		}
+		/* fall through */
+	case HERMES_INQ_HOSTSCAN:
+	case HERMES_INQ_HOSTSCAN_SYMBOL: {
+		/* Result of a scanning. Contains information about
+		 * cells in the vicinity - Jean II */
+		union iwreq_data	wrqu;
+		unsigned char *buf;
+
+		/* Sanity check */
+		if (len > 4096) {
+			printk(KERN_WARNING "%s: Scan results too large (%d bytes)\n",
+			       dev->name, len);
+			break;
+		}
+
+		/* We are a strict producer. If the previous scan results
+		 * have not been consumed, we just have to drop this
+		 * frame. We can't remove the previous results ourselves,
+		 * that would be *very* racy... Jean II */
+		if (priv->scan_result != NULL) {
+			printk(KERN_WARNING "%s: Previous scan results not consumed, dropping info frame.\n", dev->name);
+			break;
+		}
+
+		/* Allocate buffer for results */
+		buf = kmalloc(len, GFP_ATOMIC);
+		if (buf == NULL)
+			/* No memory, so can't printk()... */
+			break;
+
+		/* Read scan data */
+		err = hermes_bap_pread(hw, IRQ_BAP, (void *) buf, len,
+				       infofid, sizeof(info));
+		if (err)
+			break;
 
-		priv->last_linkstatus = newstatus;
+#ifdef ORINOCO_DEBUG
+		{
+			int	i;
+			printk(KERN_DEBUG "Scan result [%02X", buf[0]);
+			for(i = 1; i < (len * 2); i++)
+				printk(":%02X", buf[i]);
+			printk("]\n");
+		}
+#endif	/* ORINOCO_DEBUG */
+
+		/* Allow the clients to access the results */
+		priv->scan_len = len;
+		priv->scan_result = buf;
+
+		/* Send an empty event to user space.
+		 * We don't send the received data on the event because
+		 * it would require us to do complex transcoding, and
+		 * we want to minimise the work done in the irq handler
+		 * Use a request to extract the data - Jean II */
+		wrqu.data.length = 0;
+		wrqu.data.flags = 0;
+		wireless_send_event(dev, SIOCGIWSCAN, &wrqu, NULL);
 	}
 	break;
+	case HERMES_INQ_SEC_STAT_AGERE:
+		/* Security status (Agere specific) */
+		/* Ignore this frame for now */
+		if (priv->firmware_type == FIRMWARE_TYPE_AGERE)
+			break;
+		/* fall through */
 	default:
 		printk(KERN_DEBUG "%s: Unknown information frame received: "
 		       "type 0x%04x, length %d\n", dev->name, type, len);
@@ -1350,6 +1340,8 @@ int __orinoco_up(struct net_device *dev)
 	struct hermes *hw = &priv->hw;
 	int err;
 
+	netif_carrier_off(dev); /* just to make sure */
+
 	err = __orinoco_program_rids(dev);
 	if (err) {
 		printk(KERN_ERR "%s: Error %d configuring card\n",
@@ -1413,7 +1405,7 @@ int orinoco_reinit_firmware(struct net_d
 		return err;
 
 	err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid);
-	if (err == -EIO) {
+	if (err == -EIO && priv->nicbuf_size > TX_NICBUF_SIZE_BUG) {
 		/* Try workaround for old Symbol firmware bug */
 		printk(KERN_WARNING "%s: firmware ALLOC bug detected "
 		       "(old Symbol firmware?). Trying to work around... ",
@@ -1460,12 +1452,42 @@ static int __orinoco_hw_set_bitrate(stru
 	return err;
 }
 
-/* Change the WEP keys and/or the current keys.  Can be called
- * either from __orinoco_hw_setup_wep() or directly from
- * orinoco_ioctl_setiwencode().  In the later case the association
- * with the AP is not broken (if the firmware can handle it),
- * which is needed for 802.1x implementations. */
-static int __orinoco_hw_setup_wepkeys(struct orinoco_private *priv)
+/* Set fixed AP address */
+static int __orinoco_hw_set_wap(struct orinoco_private *priv)
+{
+	int roaming_flag;
+	int err = 0;
+	hermes_t *hw = &priv->hw;
+
+	switch (priv->firmware_type) {
+	case FIRMWARE_TYPE_AGERE:
+		/* not supported */
+		break;
+	case FIRMWARE_TYPE_INTERSIL:
+		if (priv->bssid_fixed)
+			roaming_flag = 2;
+		else
+			roaming_flag = 1;
+
+		err = hermes_write_wordrec(hw, USER_BAP,
+					   HERMES_RID_CNFROAMINGMODE,
+					   roaming_flag);
+		break;
+	case FIRMWARE_TYPE_SYMBOL:
+		err = HERMES_WRITE_RECORD(hw, USER_BAP,
+					  HERMES_RID_CNFMANDATORYBSSID_SYMBOL,
+					  &priv->desired_bssid);
+		break;
+	}
+	return err;
+}
+
+/* Change the WEP keys and/or the current keys.  Can be called
+ * either from __orinoco_hw_setup_wep() or directly from
+ * orinoco_ioctl_setiwencode().  In the later case the association
+ * with the AP is not broken (if the firmware can handle it),
+ * which is needed for 802.1x implementations. */
+static int __orinoco_hw_setup_wepkeys(struct orinoco_private *priv)
 {
 	hermes_t *hw = &priv->hw;
 	int err = 0;
@@ -1610,17 +1632,15 @@ static int __orinoco_program_rids(struct
 		return err;
 	}
 	/* Set the channel/frequency */
-	if (priv->channel == 0) {
-		printk(KERN_DEBUG "%s: Channel is 0 in __orinoco_program_rids()\n", dev->name);
-		if (priv->createibss)
-			priv->channel = 10;
-	}
-	err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFOWNCHANNEL,
-				   priv->channel);
-	if (err) {
-		printk(KERN_ERR "%s: Error %d setting channel\n",
-		       dev->name, err);
-		return err;
+	if (priv->channel != 0 && priv->iw_mode != IW_MODE_INFRA) {
+		err = hermes_write_wordrec(hw, USER_BAP,
+					   HERMES_RID_CNFOWNCHANNEL,
+					   priv->channel);
+		if (err) {
+			printk(KERN_ERR "%s: Error %d setting channel %d\n",
+			       dev->name, err, priv->channel);
+			return err;
+		}
 	}
 
 	if (priv->has_ibss) {
@@ -1647,6 +1667,13 @@ static int __orinoco_program_rids(struct
 		}
 	}
 
+	/* Set the desired BSSID */
+	err = __orinoco_hw_set_wap(priv);
+	if (err) {
+		printk(KERN_ERR "%s: Error %d setting AP address\n",
+		       dev->name, err);
+		return err;
+	}
 	/* Set the desired ESSID */
 	idbuf.len = cpu_to_le16(strlen(priv->desired_essid));
 	memcpy(&idbuf.val, priv->desired_essid, sizeof(idbuf.val));
@@ -1785,6 +1812,20 @@ static int __orinoco_program_rids(struct
 		}
 	}
 
+	if (priv->iw_mode == IW_MODE_MONITOR) {
+		/* Enable monitor mode */
+		dev->type = ARPHRD_IEEE80211;
+		err = hermes_docmd_wait(hw, HERMES_CMD_TEST | 
+					    HERMES_TEST_MONITOR, 0, NULL);
+	} else {
+		/* Disable monitor mode */
+		dev->type = ARPHRD_ETHER;
+		err = hermes_docmd_wait(hw, HERMES_CMD_TEST |
+					    HERMES_TEST_STOP, 0, NULL);
+	}
+	if (err)
+		return err;
+
 	/* Set promiscuity / multicast*/
 	priv->promiscuous = 0;
 	priv->mc_count = 0;
@@ -1861,62 +1902,13 @@ __orinoco_set_multicast_list(struct net_
 		dev->flags &= ~IFF_PROMISC;
 }
 
-static int orinoco_reconfigure(struct net_device *dev)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	struct hermes *hw = &priv->hw;
-	unsigned long flags;
-	int err = 0;
-
-	if (priv->broken_disableport) {
-		schedule_work(&priv->reset_work);
-		return 0;
-	}
-
-	if (orinoco_lock(priv, &flags) != 0)
-		return -EBUSY;
-		
-	err = hermes_disable_port(hw, 0);
-	if (err) {
-		printk(KERN_WARNING "%s: Unable to disable port while reconfiguring card\n",
-		       dev->name);
-		priv->broken_disableport = 1;
-		goto out;
-	}
-
-	err = __orinoco_program_rids(dev);
-	if (err) {
-		printk(KERN_WARNING "%s: Unable to reconfigure card\n",
-		       dev->name);
-		goto out;
-	}
-
-	err = hermes_enable_port(hw, 0);
-	if (err) {
-		printk(KERN_WARNING "%s: Unable to enable port while reconfiguring card\n",
-		       dev->name);
-		goto out;
-	}
-
- out:
-	if (err) {
-		printk(KERN_WARNING "%s: Resetting instead...\n", dev->name);
-		schedule_work(&priv->reset_work);
-		err = 0;
-	}
-
-	orinoco_unlock(priv, &flags);
-	return err;
-
-}
-
 /* This must be called from user context, without locks held - use
  * schedule_work() */
 static void orinoco_reset(struct net_device *dev)
 {
 	struct orinoco_private *priv = netdev_priv(dev);
 	struct hermes *hw = &priv->hw;
-	int err = 0;
+	int err;
 	unsigned long flags;
 
 	if (orinoco_lock(priv, &flags) != 0)
@@ -1938,20 +1930,25 @@ static void orinoco_reset(struct net_dev
 
 	orinoco_unlock(priv, &flags);
 
-	if (priv->hard_reset)
+ 	/* Scanning support: Cleanup of driver struct */
+	kfree(priv->scan_result);
+	priv->scan_result = NULL;
+	priv->scan_inprogress = 0;
+
+	if (priv->hard_reset) {
 		err = (*priv->hard_reset)(priv);
-	if (err) {
-		printk(KERN_ERR "%s: orinoco_reset: Error %d "
-		       "performing  hard reset\n", dev->name, err);
-		/* FIXME: shutdown of some sort */
-		return;
+		if (err) {
+			printk(KERN_ERR "%s: orinoco_reset: Error %d "
+			       "performing hard reset\n", dev->name, err);
+			goto disable;
+		}
 	}
 
 	err = orinoco_reinit_firmware(dev);
 	if (err) {
 		printk(KERN_ERR "%s: orinoco_reset: Error %d re-initializing firmware\n",
 		       dev->name, err);
-		return;
+		goto disable;
 	}
 
 	spin_lock_irq(&priv->lock); /* This has to be called from user context */
@@ -1972,6 +1969,10 @@ static void orinoco_reset(struct net_dev
 	spin_unlock_irq(&priv->lock);
 
 	return;
+ disable:
+	hermes_set_irqmask(hw, 0);
+	netif_device_detach(dev);
+	printk(KERN_ERR "%s: Device has been disabled!\n", dev->name);
 }
 
 /********************************************************************/
@@ -2056,7 +2057,7 @@ irqreturn_t orinoco_interrupt(int irq, v
 		if (events & HERMES_EV_ALLOC)
 			__orinoco_ev_alloc(dev, hw);
 		
-		hermes_write_regn(hw, EVACK, events);
+		hermes_write_regn(hw, EVACK, evstat);
 
 		evstat = hermes_read_regn(hw, EVSTAT);
 		events = evstat & hw->inten;
@@ -2172,6 +2173,8 @@ static int determine_firmware(struct net
 		priv->has_mwo = (firmver >= 0x60000);
 		priv->has_pm = (firmver >= 0x40020); /* Don't work in 7.52 ? */
 		priv->ibss_port = 1;
+		priv->has_hostscan = (firmver >= 0x8000a);
+		priv->broken_monitor = (firmver >= 0x80000);
 
 		/* Tested with Agere firmware :
 		 *	1.16 ; 4.08 ; 4.52 ; 6.04 ; 6.16 ; 7.28 => Jean II
@@ -2215,6 +2218,10 @@ static int determine_firmware(struct net
 			       firmver >= 0x31000;
 		priv->has_preamble = (firmver >= 0x20000);
 		priv->ibss_port = 4;
+ 		priv->broken_disableport = (firmver == 0x25013) ||
+ 					   (firmver >= 0x30000 && firmver <= 0x31000);
+		priv->has_hostscan = (firmver >= 0x31001) ||
+				     (firmver >= 0x29057 && firmver < 0x30000);
 		/* Tested with Intel firmware : 0x20015 => Jean II */
 		/* Tested with 3Com firmware : 0x15012 & 0x22001 => Jean II */
 		break;
@@ -2234,6 +2241,7 @@ static int determine_firmware(struct net
 		priv->has_ibss = (firmver >= 0x000700); /* FIXME */
 		priv->has_big_wep = priv->has_wep = (firmver >= 0x000800);
 		priv->has_pm = (firmver >= 0x000700);
+		priv->has_hostscan = (firmver >= 0x010301);
 
 		if (firmver >= 0x000800)
 			priv->ibss_port = 0;
@@ -2267,7 +2275,7 @@ static int orinoco_init(struct net_devic
 	priv->nicbuf_size = IEEE802_11_FRAME_LEN + ETH_HLEN;
 
 	/* Initialize the firmware */
-	err = hermes_init(hw);
+	err = orinoco_reinit_firmware(dev);
 	if (err != 0) {
 		printk(KERN_ERR "%s: failed to initialize firmware (err = %d)\n",
 		       dev->name, err);
@@ -2400,31 +2408,12 @@ static int orinoco_init(struct net_devic
 	/* By default use IEEE/IBSS ad-hoc mode if we have it */
 	priv->prefer_port3 = priv->has_port3 && (! priv->has_ibss);
 	set_port_type(priv);
-	priv->channel = 10; /* default channel, more-or-less arbitrary */
+	priv->channel = 0; /* use firmware default */
 
 	priv->promiscuous = 0;
 	priv->wep_on = 0;
 	priv->tx_key = 0;
 
-	err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid);
-	if (err == -EIO) {
-		/* Try workaround for old Symbol firmware bug */
-		printk(KERN_WARNING "%s: firmware ALLOC bug detected "
-		       "(old Symbol firmware?). Trying to work around... ",
-		       dev->name);
-		
-		priv->nicbuf_size = TX_NICBUF_SIZE_BUG;
-		err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid);
-		if (err)
-			printk("failed!\n");
-		else
-			printk("ok.\n");
-	}
-	if (err) {
-		printk("%s: Error %d allocating Tx buffer\n", dev->name, err);
-		goto out;
-	}
-
 	/* Make the hardware available, as long as it hasn't been
 	 * removed elsewhere (e.g. by PCMCIA hot unplug) */
 	spin_lock_irq(&priv->lock);
@@ -2450,7 +2439,7 @@ struct net_device *alloc_orinocodev(int 
 	priv = netdev_priv(dev);
 	priv->ndev = dev;
 	if (sizeof_card)
-		priv->card = (void *)((unsigned long)netdev_priv(dev)
+		priv->card = (void *)((unsigned long)priv
 				      + sizeof(struct orinoco_private));
 	else
 		priv->card = NULL;
@@ -2461,8 +2450,9 @@ struct net_device *alloc_orinocodev(int 
 	dev->tx_timeout = orinoco_tx_timeout;
 	dev->watchdog_timeo = HZ; /* 1 second timeout */
 	dev->get_stats = orinoco_get_stats;
+	dev->ethtool_ops = &orinoco_ethtool_ops;
 	dev->get_wireless_stats = orinoco_get_wireless_stats;
-	dev->do_ioctl = orinoco_ioctl;
+	dev->wireless_handlers = (struct iw_handler_def *)&orinoco_handler_def;
 	dev->change_mtu = orinoco_change_mtu;
 	dev->set_multicast_list = orinoco_set_multicast_list;
 	/* we use the default eth_mac_addr for setting the MAC addr */
@@ -2478,6 +2468,8 @@ struct net_device *alloc_orinocodev(int 
 				   * before anything else touches the
 				   * hardware */
 	INIT_WORK(&priv->reset_work, (void (*)(void *))orinoco_reset, dev);
+	INIT_WORK(&priv->join_work, (void (*)(void *))orinoco_join_ap, dev);
+	INIT_WORK(&priv->wevent_work, (void (*)(void *))orinoco_send_wevents, dev);
 
 	netif_carrier_off(dev);
 	priv->last_linkstatus = 0xffff;
@@ -2488,6 +2480,9 @@ struct net_device *alloc_orinocodev(int 
 
 void free_orinocodev(struct net_device *dev)
 {
+	struct orinoco_private *priv = netdev_priv(dev);
+
+	kfree(priv->scan_result);
 	free_netdev(dev);
 }
 
@@ -2495,24 +2490,6 @@ void free_orinocodev(struct net_device *
 /* Wireless extensions                                              */
 /********************************************************************/
 
-static int orinoco_hw_get_bssid(struct orinoco_private *priv,
-				char buf[ETH_ALEN])
-{
-	hermes_t *hw = &priv->hw;
-	int err = 0;
-	unsigned long flags;
-
-	if (orinoco_lock(priv, &flags) != 0)
-		return -EBUSY;
-
-	err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENTBSSID,
-			      ETH_ALEN, NULL, buf);
-
-	orinoco_unlock(priv, &flags);
-
-	return err;
-}
-
 static int orinoco_hw_get_essid(struct orinoco_private *priv, int *active,
 				char buf[IW_ESSID_MAX_SIZE+1])
 {
@@ -2555,6 +2532,7 @@ static int orinoco_hw_get_essid(struct o
 	}
 
 	len = le16_to_cpu(essidbuf.len);
+	BUG_ON(len > IW_ESSID_MAX_SIZE);
 
 	memset(buf, 0, IW_ESSID_MAX_SIZE+1);
 	memcpy(buf, p, len);
@@ -2637,140 +2615,271 @@ static int orinoco_hw_get_bitratelist(st
 	return 0;
 }
 
-static int orinoco_ioctl_getiwrange(struct net_device *dev, struct iw_point *rrq)
+static int orinoco_ioctl_getname(struct net_device *dev,
+				 struct iw_request_info *info,
+				 char *name,
+				 char *extra)
 {
 	struct orinoco_private *priv = netdev_priv(dev);
-	int err = 0;
-	int mode;
-	struct iw_range range;
 	int numrates;
-	int i, k;
+	int err;
+
+	err = orinoco_hw_get_bitratelist(priv, &numrates, NULL, 0);
+
+	if (!err && (numrates > 2))
+		strcpy(name, "IEEE 802.11b");
+	else
+		strcpy(name, "IEEE 802.11-DS");
+
+	return 0;
+}
+
+static int orinoco_ioctl_setwap(struct net_device *dev,
+				struct iw_request_info *info,
+				struct sockaddr *ap_addr,
+				char *extra)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+	int err = -EINPROGRESS;		/* Call commit handler */
 	unsigned long flags;
+	static const u8 off_addr[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+	static const u8 any_addr[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
 
-	TRACE_ENTER(dev->name);
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
+
+	/* Enable automatic roaming - no sanity checks are needed */
+	if (memcmp(&ap_addr->sa_data, off_addr, ETH_ALEN) == 0 ||
+	    memcmp(&ap_addr->sa_data, any_addr, ETH_ALEN) == 0) {
+		priv->bssid_fixed = 0;
+		memset(priv->desired_bssid, 0, ETH_ALEN);
+
+		/* "off" means keep existing connection */
+		if (ap_addr->sa_data[0] == 0) {
+			__orinoco_hw_set_wap(priv);
+			err = 0;
+		}
+		goto out;
+	}
+
+	if (priv->firmware_type == FIRMWARE_TYPE_AGERE) {
+		printk(KERN_WARNING "%s: Lucent/Agere firmware doesn't "
+		       "support manual roaming\n",
+		       dev->name);
+		err = -EOPNOTSUPP;
+		goto out;
+	}
+
+	if (priv->iw_mode != IW_MODE_INFRA) {
+		printk(KERN_WARNING "%s: Manual roaming supported only in "
+		       "managed mode\n", dev->name);
+		err = -EOPNOTSUPP;
+		goto out;
+	}
+
+	/* Intersil firmware hangs without Desired ESSID */
+	if (priv->firmware_type == FIRMWARE_TYPE_INTERSIL &&
+	    strlen(priv->desired_essid) == 0) {
+		printk(KERN_WARNING "%s: Desired ESSID must be set for "
+		       "manual roaming\n", dev->name);
+		err = -EOPNOTSUPP;
+		goto out;
+	}
+
+	/* Finally, enable manual roaming */
+	priv->bssid_fixed = 1;
+	memcpy(priv->desired_bssid, &ap_addr->sa_data, ETH_ALEN);
+
+ out:
+	orinoco_unlock(priv, &flags);
+	return err;
+}
+
+static int orinoco_ioctl_getwap(struct net_device *dev,
+				struct iw_request_info *info,
+				struct sockaddr *ap_addr,
+				char *extra)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+
+	hermes_t *hw = &priv->hw;
+	int err = 0;
+	unsigned long flags;
+
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
+
+	ap_addr->sa_family = ARPHRD_ETHER;
+	err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENTBSSID,
+			      ETH_ALEN, NULL, ap_addr->sa_data);
 
-	if (!access_ok(VERIFY_WRITE, rrq->pointer, sizeof(range)))
-		return -EFAULT;
+	orinoco_unlock(priv, &flags);
+
+	return err;
+}
+
+static int orinoco_ioctl_setmode(struct net_device *dev,
+				 struct iw_request_info *info,
+				 u32 *mode,
+				 char *extra)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+	int err = -EINPROGRESS;		/* Call commit handler */
+	unsigned long flags;
 
-	rrq->length = sizeof(range);
+	if (priv->iw_mode == *mode)
+		return 0;
 
 	if (orinoco_lock(priv, &flags) != 0)
 		return -EBUSY;
 
-	mode = priv->iw_mode;
+	switch (*mode) {
+	case IW_MODE_ADHOC:
+		if (!priv->has_ibss && !priv->has_port3)
+			err = -EOPNOTSUPP;
+		break;
+
+	case IW_MODE_INFRA:
+		break;
+
+	case IW_MODE_MONITOR:
+		if (priv->broken_monitor && !force_monitor) {
+			printk(KERN_WARNING "%s: Monitor mode support is "
+			       "buggy in this firmware, not enabling\n",
+			       dev->name);
+			err = -EOPNOTSUPP;
+		}
+		break;
+
+	default:
+		err = -EOPNOTSUPP;
+		break;
+	}
+
+	if (err == -EINPROGRESS) {
+		priv->iw_mode = *mode;
+		set_port_type(priv);
+	}
+
 	orinoco_unlock(priv, &flags);
 
-	memset(&range, 0, sizeof(range));
+	return err;
+}
+
+static int orinoco_ioctl_getmode(struct net_device *dev,
+				 struct iw_request_info *info,
+				 u32 *mode,
+				 char *extra)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+
+	*mode = priv->iw_mode;
+	return 0;
+}
+
+static int orinoco_ioctl_getiwrange(struct net_device *dev,
+				    struct iw_request_info *info,
+				    struct iw_point *rrq,
+				    char *extra)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+	int err = 0;
+	struct iw_range *range = (struct iw_range *) extra;
+	int numrates;
+	int i, k;
+
+	TRACE_ENTER(dev->name);
 
-	/* Much of this shamelessly taken from wvlan_cs.c. No idea
-	 * what it all means -dgibson */
-	range.we_version_compiled = WIRELESS_EXT;
-	range.we_version_source = 11;
+	rrq->length = sizeof(struct iw_range);
+	memset(range, 0, sizeof(struct iw_range));
 
-	range.min_nwid = range.max_nwid = 0; /* We don't use nwids */
+	range->we_version_compiled = WIRELESS_EXT;
+	range->we_version_source = 14;
 
 	/* Set available channels/frequencies */
-	range.num_channels = NUM_CHANNELS;
+	range->num_channels = NUM_CHANNELS;
 	k = 0;
 	for (i = 0; i < NUM_CHANNELS; i++) {
 		if (priv->channel_mask & (1 << i)) {
-			range.freq[k].i = i + 1;
-			range.freq[k].m = channel_frequency[i] * 100000;
-			range.freq[k].e = 1;
+			range->freq[k].i = i + 1;
+			range->freq[k].m = channel_frequency[i] * 100000;
+			range->freq[k].e = 1;
 			k++;
 		}
 		
 		if (k >= IW_MAX_FREQUENCIES)
 			break;
 	}
-	range.num_frequency = k;
+	range->num_frequency = k;
+	range->sensitivity = 3;
+
+	if (priv->has_wep) {
+		range->max_encoding_tokens = ORINOCO_MAX_KEYS;
+		range->encoding_size[0] = SMALL_KEY_SIZE;
+		range->num_encoding_sizes = 1;
 
-	range.sensitivity = 3;
+		if (priv->has_big_wep) {
+			range->encoding_size[1] = LARGE_KEY_SIZE;
+			range->num_encoding_sizes = 2;
+		}
+	}
 
-	if ((mode == IW_MODE_ADHOC) && (priv->spy_number == 0)){
+	if ((priv->iw_mode == IW_MODE_ADHOC) && (priv->spy_number == 0)){
 		/* Quality stats meaningless in ad-hoc mode */
-		range.max_qual.qual = 0;
-		range.max_qual.level = 0;
-		range.max_qual.noise = 0;
-		range.avg_qual.qual = 0;
-		range.avg_qual.level = 0;
-		range.avg_qual.noise = 0;
 	} else {
-		range.max_qual.qual = 0x8b - 0x2f;
-		range.max_qual.level = 0x2f - 0x95 - 1;
-		range.max_qual.noise = 0x2f - 0x95 - 1;
+		range->max_qual.qual = 0x8b - 0x2f;
+		range->max_qual.level = 0x2f - 0x95 - 1;
+		range->max_qual.noise = 0x2f - 0x95 - 1;
 		/* Need to get better values */
-		range.avg_qual.qual = 0x24;
-		range.avg_qual.level = 0xC2;
-		range.avg_qual.noise = 0x9E;
+		range->avg_qual.qual = 0x24;
+		range->avg_qual.level = 0xC2;
+		range->avg_qual.noise = 0x9E;
 	}
 
 	err = orinoco_hw_get_bitratelist(priv, &numrates,
-					 range.bitrate, IW_MAX_BITRATES);
+					 range->bitrate, IW_MAX_BITRATES);
 	if (err)
 		return err;
-	range.num_bitrates = numrates;
-	
+	range->num_bitrates = numrates;
+
 	/* Set an indication of the max TCP throughput in bit/s that we can
 	 * expect using this interface. May be use for QoS stuff...
 	 * Jean II */
-	if(numrates > 2)
-		range.throughput = 5 * 1000 * 1000;	/* ~5 Mb/s */
+	if (numrates > 2)
+		range->throughput = 5 * 1000 * 1000;	/* ~5 Mb/s */
 	else
-		range.throughput = 1.5 * 1000 * 1000;	/* ~1.5 Mb/s */
-
-	range.min_rts = 0;
-	range.max_rts = 2347;
-	range.min_frag = 256;
-	range.max_frag = 2346;
-
-	if (orinoco_lock(priv, &flags) != 0)
-		return -EBUSY;
-	if (priv->has_wep) {
-		range.max_encoding_tokens = ORINOCO_MAX_KEYS;
-
-		range.encoding_size[0] = SMALL_KEY_SIZE;
-		range.num_encoding_sizes = 1;
-
-		if (priv->has_big_wep) {
-			range.encoding_size[1] = LARGE_KEY_SIZE;
-			range.num_encoding_sizes = 2;
-		}
-	} else {
-		range.num_encoding_sizes = 0;
-		range.max_encoding_tokens = 0;
-	}
-	orinoco_unlock(priv, &flags);
-		
-	range.min_pmp = 0;
-	range.max_pmp = 65535000;
-	range.min_pmt = 0;
-	range.max_pmt = 65535 * 1000;	/* ??? */
-	range.pmp_flags = IW_POWER_PERIOD;
-	range.pmt_flags = IW_POWER_TIMEOUT;
-	range.pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_UNICAST_R;
-
-	range.num_txpower = 1;
-	range.txpower[0] = 15; /* 15dBm */
-	range.txpower_capa = IW_TXPOW_DBM;
-
-	range.retry_capa = IW_RETRY_LIMIT | IW_RETRY_LIFETIME;
-	range.retry_flags = IW_RETRY_LIMIT;
-	range.r_time_flags = IW_RETRY_LIFETIME;
-	range.min_retry = 0;
-	range.max_retry = 65535;	/* ??? */
-	range.min_r_time = 0;
-	range.max_r_time = 65535 * 1000;	/* ??? */
+		range->throughput = 1.5 * 1000 * 1000;	/* ~1.5 Mb/s */
 
-	if (copy_to_user(rrq->pointer, &range, sizeof(range)))
-		return -EFAULT;
+	range->min_rts = 0;
+	range->max_rts = 2347;
+	range->min_frag = 256;
+	range->max_frag = 2346;
+
+	range->min_pmp = 0;
+	range->max_pmp = 65535000;
+	range->min_pmt = 0;
+	range->max_pmt = 65535 * 1000;	/* ??? */
+	range->pmp_flags = IW_POWER_PERIOD;
+	range->pmt_flags = IW_POWER_TIMEOUT;
+	range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_UNICAST_R;
+
+	range->retry_capa = IW_RETRY_LIMIT | IW_RETRY_LIFETIME;
+	range->retry_flags = IW_RETRY_LIMIT;
+	range->r_time_flags = IW_RETRY_LIFETIME;
+	range->min_retry = 0;
+	range->max_retry = 65535;	/* ??? */
+	range->min_r_time = 0;
+	range->max_r_time = 65535 * 1000;	/* ??? */
 
 	TRACE_EXIT(dev->name);
 
 	return 0;
 }
 
-static int orinoco_ioctl_setiwencode(struct net_device *dev, struct iw_point *erq)
+static int orinoco_ioctl_setiwencode(struct net_device *dev,
+				     struct iw_request_info *info,
+				     struct iw_point *erq,
+				     char *keybuf)
 {
 	struct orinoco_private *priv = netdev_priv(dev);
 	int index = (erq->flags & IW_ENCODE_INDEX) - 1;
@@ -2778,8 +2887,7 @@ static int orinoco_ioctl_setiwencode(str
 	int enable = priv->wep_on;
 	int restricted = priv->wep_restrict;
 	u16 xlen = 0;
-	int err = 0;
-	char keybuf[ORINOCO_MAX_KEY_SIZE];
+	int err = -EINPROGRESS;		/* Call commit handler */
 	unsigned long flags;
 
 	if (! priv->has_wep)
@@ -2792,9 +2900,6 @@ static int orinoco_ioctl_setiwencode(str
 
 		if ( (erq->length > SMALL_KEY_SIZE) && !priv->has_big_wep )
 			return -E2BIG;
-		
-		if (copy_from_user(keybuf, erq->pointer, erq->length))
-			return -EFAULT;
 	}
 
 	if (orinoco_lock(priv, &flags) != 0)
@@ -2868,12 +2973,14 @@ static int orinoco_ioctl_setiwencode(str
 	return err;
 }
 
-static int orinoco_ioctl_getiwencode(struct net_device *dev, struct iw_point *erq)
+static int orinoco_ioctl_getiwencode(struct net_device *dev,
+				     struct iw_request_info *info,
+				     struct iw_point *erq,
+				     char *keybuf)
 {
 	struct orinoco_private *priv = netdev_priv(dev);
 	int index = (erq->flags & IW_ENCODE_INDEX) - 1;
 	u16 xlen = 0;
-	char keybuf[ORINOCO_MAX_KEY_SIZE];
 	unsigned long flags;
 
 	if (! priv->has_wep)
@@ -2902,50 +3009,47 @@ static int orinoco_ioctl_getiwencode(str
 	memcpy(keybuf, priv->keys[index].data, ORINOCO_MAX_KEY_SIZE);
 
 	orinoco_unlock(priv, &flags);
-
-	if (erq->pointer) {
-		if (copy_to_user(erq->pointer, keybuf, xlen))
-			return -EFAULT;
-	}
-
 	return 0;
 }
 
-static int orinoco_ioctl_setessid(struct net_device *dev, struct iw_point *erq)
+static int orinoco_ioctl_setessid(struct net_device *dev,
+				  struct iw_request_info *info,
+				  struct iw_point *erq,
+				  char *essidbuf)
 {
 	struct orinoco_private *priv = netdev_priv(dev);
-	char essidbuf[IW_ESSID_MAX_SIZE+1];
 	unsigned long flags;
 
 	/* Note : ESSID is ignored in Ad-Hoc demo mode, but we can set it
 	 * anyway... - Jean II */
 
-	memset(&essidbuf, 0, sizeof(essidbuf));
-
-	if (erq->flags) {
-		if (erq->length > IW_ESSID_MAX_SIZE)
-			return -E2BIG;
-		
-		if (copy_from_user(&essidbuf, erq->pointer, erq->length))
-			return -EFAULT;
-
-		essidbuf[erq->length] = '\0';
-	}
+	/* Hum... Should not use Wireless Extension constant (may change),
+	 * should use our own... - Jean II */
+	if (erq->length > IW_ESSID_MAX_SIZE)
+		return -E2BIG;
 
 	if (orinoco_lock(priv, &flags) != 0)
 		return -EBUSY;
 
-	memcpy(priv->desired_essid, essidbuf, sizeof(priv->desired_essid));
+	/* NULL the string (for NULL termination & ESSID = ANY) - Jean II */
+	memset(priv->desired_essid, 0, sizeof(priv->desired_essid));
+
+	/* If not ANY, get the new ESSID */
+	if (erq->flags) {
+		memcpy(priv->desired_essid, essidbuf, erq->length);
+	}
 
 	orinoco_unlock(priv, &flags);
 
-	return 0;
+	return -EINPROGRESS;		/* Call commit handler */
 }
 
-static int orinoco_ioctl_getessid(struct net_device *dev, struct iw_point *erq)
+static int orinoco_ioctl_getessid(struct net_device *dev,
+				  struct iw_request_info *info,
+				  struct iw_point *erq,
+				  char *essidbuf)
 {
 	struct orinoco_private *priv = netdev_priv(dev);
-	char essidbuf[IW_ESSID_MAX_SIZE+1];
 	int active;
 	int err = 0;
 	unsigned long flags;
@@ -2959,51 +3063,46 @@ static int orinoco_ioctl_getessid(struct
 	} else {
 		if (orinoco_lock(priv, &flags) != 0)
 			return -EBUSY;
-		memcpy(essidbuf, priv->desired_essid, sizeof(essidbuf));
+		memcpy(essidbuf, priv->desired_essid, IW_ESSID_MAX_SIZE + 1);
 		orinoco_unlock(priv, &flags);
 	}
 
 	erq->flags = 1;
 	erq->length = strlen(essidbuf) + 1;
-	if (erq->pointer)
-		if (copy_to_user(erq->pointer, essidbuf, erq->length))
-			return -EFAULT;
 
 	TRACE_EXIT(dev->name);
 	
 	return 0;
 }
 
-static int orinoco_ioctl_setnick(struct net_device *dev, struct iw_point *nrq)
+static int orinoco_ioctl_setnick(struct net_device *dev,
+				 struct iw_request_info *info,
+				 struct iw_point *nrq,
+				 char *nickbuf)
 {
 	struct orinoco_private *priv = netdev_priv(dev);
-	char nickbuf[IW_ESSID_MAX_SIZE+1];
 	unsigned long flags;
 
 	if (nrq->length > IW_ESSID_MAX_SIZE)
 		return -E2BIG;
 
-	memset(nickbuf, 0, sizeof(nickbuf));
-
-	if (copy_from_user(nickbuf, nrq->pointer, nrq->length))
-		return -EFAULT;
-
-	nickbuf[nrq->length] = '\0';
-	
 	if (orinoco_lock(priv, &flags) != 0)
 		return -EBUSY;
 
-	memcpy(priv->nick, nickbuf, sizeof(priv->nick));
+	memset(priv->nick, 0, sizeof(priv->nick));
+	memcpy(priv->nick, nickbuf, nrq->length);
 
 	orinoco_unlock(priv, &flags);
 
-	return 0;
+	return -EINPROGRESS;		/* Call commit handler */
 }
 
-static int orinoco_ioctl_getnick(struct net_device *dev, struct iw_point *nrq)
+static int orinoco_ioctl_getnick(struct net_device *dev,
+				 struct iw_request_info *info,
+				 struct iw_point *nrq,
+				 char *nickbuf)
 {
 	struct orinoco_private *priv = netdev_priv(dev);
-	char nickbuf[IW_ESSID_MAX_SIZE+1];
 	unsigned long flags;
 
 	if (orinoco_lock(priv, &flags) != 0)
@@ -3014,23 +3113,22 @@ static int orinoco_ioctl_getnick(struct 
 
 	nrq->length = strlen(nickbuf)+1;
 
-	if (copy_to_user(nrq->pointer, nickbuf, sizeof(nickbuf)))
-		return -EFAULT;
-
 	return 0;
 }
 
-static int orinoco_ioctl_setfreq(struct net_device *dev, struct iw_freq *frq)
+static int orinoco_ioctl_setfreq(struct net_device *dev,
+				 struct iw_request_info *info,
+				 struct iw_freq *frq,
+				 char *extra)
 {
 	struct orinoco_private *priv = netdev_priv(dev);
 	int chan = -1;
 	unsigned long flags;
+	int err = -EINPROGRESS;		/* Call commit handler */
 
-	/* We can only use this in Ad-Hoc demo mode to set the operating
-	 * frequency, or in IBSS mode to set the frequency where the IBSS
-	 * will be created - Jean II */
-	if (priv->iw_mode != IW_MODE_ADHOC)
-		return -EOPNOTSUPP;
+	/* In infrastructure mode the AP sets the channel */
+	if (priv->iw_mode == IW_MODE_INFRA)
+		return -EBUSY;
 
 	if ( (frq->e == 0) && (frq->m <= 1000) ) {
 		/* Setting by channel number */
@@ -3054,13 +3152,44 @@ static int orinoco_ioctl_setfreq(struct 
 
 	if (orinoco_lock(priv, &flags) != 0)
 		return -EBUSY;
+
 	priv->channel = chan;
+	if (priv->iw_mode == IW_MODE_MONITOR) {
+		/* Fast channel change - no commit if successful */
+		hermes_t *hw = &priv->hw;
+		err = hermes_docmd_wait(hw, HERMES_CMD_TEST |
+					    HERMES_TEST_SET_CHANNEL,
+					chan, NULL);
+	}
 	orinoco_unlock(priv, &flags);
 
+	return err;
+}
+
+static int orinoco_ioctl_getfreq(struct net_device *dev,
+				 struct iw_request_info *info,
+				 struct iw_freq *frq,
+				 char *extra)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+	int tmp;
+
+	/* Locking done in there */
+	tmp = orinoco_hw_get_freq(priv);
+	if (tmp < 0) {
+		return tmp;
+	}
+
+	frq->m = tmp;
+	frq->e = 1;
+
 	return 0;
 }
 
-static int orinoco_ioctl_getsens(struct net_device *dev, struct iw_param *srq)
+static int orinoco_ioctl_getsens(struct net_device *dev,
+				 struct iw_request_info *info,
+				 struct iw_param *srq,
+				 char *extra)
 {
 	struct orinoco_private *priv = netdev_priv(dev);
 	hermes_t *hw = &priv->hw;
@@ -3086,7 +3215,10 @@ static int orinoco_ioctl_getsens(struct 
 	return 0;
 }
 
-static int orinoco_ioctl_setsens(struct net_device *dev, struct iw_param *srq)
+static int orinoco_ioctl_setsens(struct net_device *dev,
+				 struct iw_request_info *info,
+				 struct iw_param *srq,
+				 char *extra)
 {
 	struct orinoco_private *priv = netdev_priv(dev);
 	int val = srq->value;
@@ -3103,10 +3235,13 @@ static int orinoco_ioctl_setsens(struct 
 	priv->ap_density = val;
 	orinoco_unlock(priv, &flags);
 
-	return 0;
+	return -EINPROGRESS;		/* Call commit handler */
 }
 
-static int orinoco_ioctl_setrts(struct net_device *dev, struct iw_param *rrq)
+static int orinoco_ioctl_setrts(struct net_device *dev,
+				struct iw_request_info *info,
+				struct iw_param *rrq,
+				char *extra)
 {
 	struct orinoco_private *priv = netdev_priv(dev);
 	int val = rrq->value;
@@ -3124,13 +3259,30 @@ static int orinoco_ioctl_setrts(struct n
 	priv->rts_thresh = val;
 	orinoco_unlock(priv, &flags);
 
+	return -EINPROGRESS;		/* Call commit handler */
+}
+
+static int orinoco_ioctl_getrts(struct net_device *dev,
+				struct iw_request_info *info,
+				struct iw_param *rrq,
+				char *extra)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+
+	rrq->value = priv->rts_thresh;
+	rrq->disabled = (rrq->value == 2347);
+	rrq->fixed = 1;
+
 	return 0;
 }
 
-static int orinoco_ioctl_setfrag(struct net_device *dev, struct iw_param *frq)
+static int orinoco_ioctl_setfrag(struct net_device *dev,
+				 struct iw_request_info *info,
+				 struct iw_param *frq,
+				 char *extra)
 {
 	struct orinoco_private *priv = netdev_priv(dev);
-	int err = 0;
+	int err = -EINPROGRESS;		/* Call commit handler */
 	unsigned long flags;
 
 	if (orinoco_lock(priv, &flags) != 0)
@@ -3162,11 +3314,14 @@ static int orinoco_ioctl_setfrag(struct 
 	return err;
 }
 
-static int orinoco_ioctl_getfrag(struct net_device *dev, struct iw_param *frq)
+static int orinoco_ioctl_getfrag(struct net_device *dev,
+				 struct iw_request_info *info,
+				 struct iw_param *frq,
+				 char *extra)
 {
 	struct orinoco_private *priv = netdev_priv(dev);
 	hermes_t *hw = &priv->hw;
-	int err = 0;
+	int err;
 	u16 val;
 	unsigned long flags;
 
@@ -3199,10 +3354,12 @@ static int orinoco_ioctl_getfrag(struct 
 	return err;
 }
 
-static int orinoco_ioctl_setrate(struct net_device *dev, struct iw_param *rrq)
+static int orinoco_ioctl_setrate(struct net_device *dev,
+				 struct iw_request_info *info,
+				 struct iw_param *rrq,
+				 char *extra)
 {
 	struct orinoco_private *priv = netdev_priv(dev);
-	int err = 0;
 	int ratemode = -1;
 	int bitrate; /* 100s of kilobits */
 	int i;
@@ -3238,10 +3395,13 @@ static int orinoco_ioctl_setrate(struct 
 	priv->bitratemode = ratemode;
 	orinoco_unlock(priv, &flags);
 
-	return err;
+	return -EINPROGRESS;
 }
 
-static int orinoco_ioctl_getrate(struct net_device *dev, struct iw_param *rrq)
+static int orinoco_ioctl_getrate(struct net_device *dev,
+				 struct iw_request_info *info,
+				 struct iw_param *rrq,
+				 char *extra)
 {
 	struct orinoco_private *priv = netdev_priv(dev);
 	hermes_t *hw = &priv->hw;
@@ -3306,10 +3466,13 @@ static int orinoco_ioctl_getrate(struct 
 	return err;
 }
 
-static int orinoco_ioctl_setpower(struct net_device *dev, struct iw_param *prq)
+static int orinoco_ioctl_setpower(struct net_device *dev,
+				  struct iw_request_info *info,
+				  struct iw_param *prq,
+				  char *extra)
 {
 	struct orinoco_private *priv = netdev_priv(dev);
-	int err = 0;
+	int err = -EINPROGRESS;		/* Call commit handler */
 	unsigned long flags;
 
 	if (orinoco_lock(priv, &flags) != 0)
@@ -3358,7 +3521,10 @@ static int orinoco_ioctl_setpower(struct
 	return err;
 }
 
-static int orinoco_ioctl_getpower(struct net_device *dev, struct iw_param *prq)
+static int orinoco_ioctl_getpower(struct net_device *dev,
+				  struct iw_request_info *info,
+				  struct iw_param *prq,
+				  char *extra)
 {
 	struct orinoco_private *priv = netdev_priv(dev);
 	hermes_t *hw = &priv->hw;
@@ -3406,7 +3572,10 @@ static int orinoco_ioctl_getpower(struct
 	return err;
 }
 
-static int orinoco_ioctl_getretry(struct net_device *dev, struct iw_param *rrq)
+static int orinoco_ioctl_getretry(struct net_device *dev,
+				  struct iw_request_info *info,
+				  struct iw_param *rrq,
+				  char *extra)
 {
 	struct orinoco_private *priv = netdev_priv(dev);
 	hermes_t *hw = &priv->hw;
@@ -3457,10 +3626,38 @@ static int orinoco_ioctl_getretry(struct
 	return err;
 }
 
-static int orinoco_ioctl_setibssport(struct net_device *dev, struct iwreq *wrq)
+static int orinoco_ioctl_reset(struct net_device *dev,
+			       struct iw_request_info *info,
+			       void *wrqu,
+			       char *extra)
 {
 	struct orinoco_private *priv = netdev_priv(dev);
-	int val = *( (int *) wrq->u.name );
+
+	if (! capable(CAP_NET_ADMIN))
+		return -EPERM;
+
+	if (info->cmd == (SIOCIWFIRSTPRIV + 0x1)) {
+		printk(KERN_DEBUG "%s: Forcing reset!\n", dev->name);
+
+		/* Firmware reset */
+		orinoco_reset(dev);
+	} else {
+		printk(KERN_DEBUG "%s: Force scheduling reset!\n", dev->name);
+
+		schedule_work(&priv->reset_work);
+	}
+
+	return 0;
+}
+
+static int orinoco_ioctl_setibssport(struct net_device *dev,
+				     struct iw_request_info *info,
+				     void *wrqu,
+				     char *extra)
+
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+	int val = *( (int *) extra );
 	unsigned long flags;
 
 	if (orinoco_lock(priv, &flags) != 0)
@@ -3472,28 +3669,28 @@ static int orinoco_ioctl_setibssport(str
 	set_port_type(priv);
 
 	orinoco_unlock(priv, &flags);
-	return 0;
+	return -EINPROGRESS;		/* Call commit handler */
 }
 
-static int orinoco_ioctl_getibssport(struct net_device *dev, struct iwreq *wrq)
+static int orinoco_ioctl_getibssport(struct net_device *dev,
+				     struct iw_request_info *info,
+				     void *wrqu,
+				     char *extra)
 {
 	struct orinoco_private *priv = netdev_priv(dev);
-	int *val = (int *)wrq->u.name;
-	unsigned long flags;
-
-	if (orinoco_lock(priv, &flags) != 0)
-		return -EBUSY;
+	int *val = (int *) extra;
 
 	*val = priv->ibss_port;
-	orinoco_unlock(priv, &flags);
-
 	return 0;
 }
 
-static int orinoco_ioctl_setport3(struct net_device *dev, struct iwreq *wrq)
+static int orinoco_ioctl_setport3(struct net_device *dev,
+				  struct iw_request_info *info,
+				  void *wrqu,
+				  char *extra)
 {
 	struct orinoco_private *priv = netdev_priv(dev);
-	int val = *( (int *) wrq->u.name );
+	int val = *( (int *) extra );
 	int err = 0;
 	unsigned long flags;
 
@@ -3522,51 +3719,131 @@ static int orinoco_ioctl_setport3(struct
 		err = -EINVAL;
 	}
 
-	if (! err)
+	if (! err) {
 		/* Actually update the mode we are using */
 		set_port_type(priv);
+		err = -EINPROGRESS;
+	}
 
 	orinoco_unlock(priv, &flags);
 
 	return err;
 }
 
-static int orinoco_ioctl_getport3(struct net_device *dev, struct iwreq *wrq)
+static int orinoco_ioctl_getport3(struct net_device *dev,
+				  struct iw_request_info *info,
+				  void *wrqu,
+				  char *extra)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+	int *val = (int *) extra;
+
+	*val = priv->prefer_port3;
+	return 0;
+}
+
+static int orinoco_ioctl_setpreamble(struct net_device *dev,
+				     struct iw_request_info *info,
+				     void *wrqu,
+				     char *extra)
 {
 	struct orinoco_private *priv = netdev_priv(dev);
-	int *val = (int *)wrq->u.name;
 	unsigned long flags;
+	int val;
+
+	if (! priv->has_preamble)
+		return -EOPNOTSUPP;
+
+	/* 802.11b has recently defined some short preamble.
+	 * Basically, the Phy header has been reduced in size.
+	 * This increase performance, especially at high rates
+	 * (the preamble is transmitted at 1Mb/s), unfortunately
+	 * this give compatibility troubles... - Jean II */
+	val = *( (int *) extra );
 
 	if (orinoco_lock(priv, &flags) != 0)
 		return -EBUSY;
 
-	*val = priv->prefer_port3;
+	if (val)
+		priv->preamble = 1;
+	else
+		priv->preamble = 0;
+
 	orinoco_unlock(priv, &flags);
+
+	return -EINPROGRESS;		/* Call commit handler */
+}
+
+static int orinoco_ioctl_getpreamble(struct net_device *dev,
+				     struct iw_request_info *info,
+				     void *wrqu,
+				     char *extra)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+	int *val = (int *) extra;
+
+	if (! priv->has_preamble)
+		return -EOPNOTSUPP;
+
+	*val = priv->preamble;
 	return 0;
 }
 
+/* ioctl interface to hermes_read_ltv()
+ * To use with iwpriv, pass the RID as the token argument, e.g.
+ * iwpriv get_rid [0xfc00]
+ * At least Wireless Tools 25 is required to use iwpriv.
+ * For Wireless Tools 25 and 26 append "dummy" are the end. */
+static int orinoco_ioctl_getrid(struct net_device *dev,
+				struct iw_request_info *info,
+				struct iw_point *data,
+				char *extra)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+	hermes_t *hw = &priv->hw;
+	int rid = data->flags;
+	u16 length;
+	int err;
+	unsigned long flags;
+
+	/* It's a "get" function, but we don't want users to access the
+	 * WEP key and other raw firmware data */
+	if (! capable(CAP_NET_ADMIN))
+		return -EPERM;
+
+	if (rid < 0xfc00 || rid > 0xffff)
+		return -EINVAL;
+
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
+
+	err = hermes_read_ltv(hw, USER_BAP, rid, MAX_RID_LEN, &length,
+			      extra);
+	if (err)
+		goto out;
+
+	data->length = min_t(u16, HERMES_RECLEN_TO_BYTES(length),
+			     MAX_RID_LEN);
+
+ out:
+	orinoco_unlock(priv, &flags);
+	return err;
+}
+
 /* Spy is used for link quality/strength measurements in Ad-Hoc mode
  * Jean II */
-static int orinoco_ioctl_setspy(struct net_device *dev, struct iw_point *srq)
+static int orinoco_ioctl_setspy(struct net_device *dev,
+				struct iw_request_info *info,
+				struct iw_point *srq,
+				char *extra)
+
 {
 	struct orinoco_private *priv = netdev_priv(dev);
-	struct sockaddr address[IW_MAX_SPY];
+	struct sockaddr *address = (struct sockaddr *) extra;
 	int number = srq->length;
 	int i;
-	int err = 0;
 	unsigned long flags;
 
-	/* Check the number of addresses */
-	if (number > IW_MAX_SPY)
-		return -E2BIG;
-
-	/* Get the data in the driver */
-	if (srq->pointer) {
-		if (copy_from_user(address, srq->pointer,
-				   sizeof(struct sockaddr) * number))
-			return -EFAULT;
-	}
-
 	/* Make sure nobody mess with the structure while we do */
 	if (orinoco_lock(priv, &flags) != 0)
 		return -EBUSY;
@@ -3590,14 +3867,17 @@ static int orinoco_ioctl_setspy(struct n
 	/* Now, let the others play */
 	orinoco_unlock(priv, &flags);
 
-	return err;
+	/* Do NOT call commit handler */
+	return 0;
 }
 
-static int orinoco_ioctl_getspy(struct net_device *dev, struct iw_point *srq)
+static int orinoco_ioctl_getspy(struct net_device *dev,
+				struct iw_request_info *info,
+				struct iw_point *srq,
+				char *extra)
 {
 	struct orinoco_private *priv = netdev_priv(dev);
-	struct sockaddr address[IW_MAX_SPY];
-	struct iw_quality spy_stat[IW_MAX_SPY];
+	struct sockaddr *address = (struct sockaddr *) extra;
 	int number;
 	int i;
 	unsigned long flags;
@@ -3606,7 +3886,12 @@ static int orinoco_ioctl_getspy(struct n
 		return -EBUSY;
 
 	number = priv->spy_number;
-	if ((number > 0) && (srq->pointer)) {
+	/* Create address struct */
+	for (i = 0; i < number; i++) {
+		memcpy(address[i].sa_data, priv->spy_address[i], ETH_ALEN);
+		address[i].sa_family = AF_UNIX;
+	}
+	if (number > 0) {
 		/* Create address struct */
 		for (i = 0; i < number; i++) {
 			memcpy(address[i].sa_data, priv->spy_address[i],
@@ -3617,535 +3902,504 @@ static int orinoco_ioctl_getspy(struct n
 		/* In theory, we should disable irqs while copying the stats
 		 * because the rx path might update it in the middle...
 		 * Bah, who care ? - Jean II */
-		memcpy(&spy_stat, priv->spy_stat,
-		       sizeof(struct iw_quality) * IW_MAX_SPY);
-		for (i=0; i < number; i++)
-			priv->spy_stat[i].updated = 0;
+		memcpy(extra  + (sizeof(struct sockaddr) * number),
+		       priv->spy_stat, sizeof(struct iw_quality) * number);
 	}
+	/* Reset updated flags. */
+	for (i = 0; i < number; i++)
+		priv->spy_stat[i].updated = 0;
 
 	orinoco_unlock(priv, &flags);
 
-	/* Push stuff to user space */
 	srq->length = number;
-	if(copy_to_user(srq->pointer, address,
-			 sizeof(struct sockaddr) * number))
-		return -EFAULT;
-	if(copy_to_user(srq->pointer + (sizeof(struct sockaddr)*number),
-			&spy_stat, sizeof(struct iw_quality) * number))
-		return -EFAULT;
 
 	return 0;
 }
 
-static int
-orinoco_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+/* Trigger a scan (look for other cells in the vicinity */
+static int orinoco_ioctl_setscan(struct net_device *dev,
+				 struct iw_request_info *info,
+				 struct iw_param *srq,
+				 char *extra)
 {
 	struct orinoco_private *priv = netdev_priv(dev);
-	struct iwreq *wrq = (struct iwreq *)rq;
+	hermes_t *hw = &priv->hw;
 	int err = 0;
-	int tmp;
-	int changed = 0;
 	unsigned long flags;
 
-	TRACE_ENTER(dev->name);
+	/* Note : you may have realised that, as this is a SET operation,
+	 * this is priviledged and therefore a normal user can't
+	 * perform scanning.
+	 * This is not an error, while the device perform scanning,
+	 * traffic doesn't flow, so it's a perfect DoS...
+	 * Jean II */
 
-	/* In theory, we could allow most of the the SET stuff to be
-	 * done. In practice, the lapse of time at startup when the
-	 * card is not ready is very short, so why bother...  Note
-	 * that netif_device_present is different from up/down
-	 * (ifconfig), when the device is not yet up, it is usually
-	 * already ready...  Jean II */
-	if (! netif_device_present(dev))
-		return -ENODEV;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 
-	switch (cmd) {
-	case SIOCGIWNAME:
-		strcpy(wrq->u.name, "IEEE 802.11-DS");
-		break;
-		
-	case SIOCGIWAP:
-		wrq->u.ap_addr.sa_family = ARPHRD_ETHER;
-		err = orinoco_hw_get_bssid(priv, wrq->u.ap_addr.sa_data);
-		break;
+	/* Scanning with port 0 disabled would fail */
+	if (!netif_running(dev)) {
+		err = -ENETDOWN;
+		goto out;
+	}
 
-	case SIOCGIWRANGE:
-		err = orinoco_ioctl_getiwrange(dev, &wrq->u.data);
-		break;
+	/* In monitor mode, the scan results are always empty.
+	 * Probe responses are passed to the driver as received
+	 * frames and could be processed in software. */
+	if (priv->iw_mode == IW_MODE_MONITOR) {
+		err = -EOPNOTSUPP;
+		goto out;
+	}
 
-	case SIOCSIWMODE:
-		if (orinoco_lock(priv, &flags) != 0)
-			return -EBUSY;
-		switch (wrq->u.mode) {
-		case IW_MODE_ADHOC:
-			if (! (priv->has_ibss || priv->has_port3) )
-				err = -EINVAL;
-			else {
-				priv->iw_mode = IW_MODE_ADHOC;
-				changed = 1;
-			}
-			break;
+	/* Note : because we don't lock out the irq handler, the way
+	 * we access scan variables in priv is critical.
+	 *	o scan_inprogress : not touched by irq handler
+	 *	o scan_mode : not touched by irq handler
+	 *	o scan_result : irq is strict producer, non-irq is strict
+	 *		consumer.
+	 *	o scan_len : synchronised with scan_result
+	 * Before modifying anything on those variables, please think hard !
+	 * Jean II */
 
-		case IW_MODE_INFRA:
-			priv->iw_mode = IW_MODE_INFRA;
-			changed = 1;
-			break;
+	/* If there is still some left-over scan results, get rid of it */
+	if (priv->scan_result != NULL) {
+		/* What's likely is that a client did crash or was killed
+		 * between triggering the scan request and reading the
+		 * results, so we need to reset everything.
+		 * Some clients that are too slow may suffer from that...
+		 * Jean II */
+		kfree(priv->scan_result);
+		priv->scan_result = NULL;
+	}
+
+	/* Save flags */
+	priv->scan_mode = srq->flags;
+
+	/* Always trigger scanning, even if it's in progress.
+	 * This way, if the info frame get lost, we will recover somewhat
+	 * gracefully  - Jean II */
 
-		default:
-			err = -EINVAL;
+	if (priv->has_hostscan) {
+		switch (priv->firmware_type) {
+		case FIRMWARE_TYPE_SYMBOL:
+			err = hermes_write_wordrec(hw, USER_BAP,
+						   HERMES_RID_CNFHOSTSCAN_SYMBOL,
+						   HERMES_HOSTSCAN_SYMBOL_ONCE |
+						   HERMES_HOSTSCAN_SYMBOL_BCAST);
 			break;
-		}
-		set_port_type(priv);
-		orinoco_unlock(priv, &flags);
-		break;
-
-	case SIOCGIWMODE:
-		if (orinoco_lock(priv, &flags) != 0)
-			return -EBUSY;
-		wrq->u.mode = priv->iw_mode;
-		orinoco_unlock(priv, &flags);
-		break;
-
-	case SIOCSIWENCODE:
-		err = orinoco_ioctl_setiwencode(dev, &wrq->u.encoding);
-		if (! err)
-			changed = 1;
-		break;
+		case FIRMWARE_TYPE_INTERSIL: {
+			u16 req[3];
 
-	case SIOCGIWENCODE:
-		if (! capable(CAP_NET_ADMIN)) {
-			err = -EPERM;
-			break;
+			req[0] = cpu_to_le16(0x3fff);	/* All channels */
+			req[1] = cpu_to_le16(0x0001);	/* rate 1 Mbps */
+			req[2] = 0;			/* Any ESSID */
+			err = HERMES_WRITE_RECORD(hw, USER_BAP,
+						  HERMES_RID_CNFHOSTSCAN, &req);
 		}
-
-		err = orinoco_ioctl_getiwencode(dev, &wrq->u.encoding);
-		break;
-
-	case SIOCSIWESSID:
-		err = orinoco_ioctl_setessid(dev, &wrq->u.essid);
-		if (! err)
-			changed = 1;
-		break;
-
-	case SIOCGIWESSID:
-		err = orinoco_ioctl_getessid(dev, &wrq->u.essid);
-		break;
-
-	case SIOCSIWNICKN:
-		err = orinoco_ioctl_setnick(dev, &wrq->u.data);
-		if (! err)
-			changed = 1;
-		break;
-
-	case SIOCGIWNICKN:
-		err = orinoco_ioctl_getnick(dev, &wrq->u.data);
 		break;
+		case FIRMWARE_TYPE_AGERE:
+			err = hermes_write_wordrec(hw, USER_BAP,
+						   HERMES_RID_CNFSCANSSID_AGERE,
+						   0);	/* Any ESSID */
+			if (err)
+				break;
 
-	case SIOCGIWFREQ:
-		tmp = orinoco_hw_get_freq(priv);
-		if (tmp < 0) {
-			err = tmp;
-		} else {
-			wrq->u.freq.m = tmp;
-			wrq->u.freq.e = 1;
+			err = hermes_inquire(hw, HERMES_INQ_SCAN);
+			break;
 		}
-		break;
+	} else
+		err = hermes_inquire(hw, HERMES_INQ_SCAN);
 
-	case SIOCSIWFREQ:
-		err = orinoco_ioctl_setfreq(dev, &wrq->u.freq);
-		if (! err)
-			changed = 1;
-		break;
-
-	case SIOCGIWSENS:
-		err = orinoco_ioctl_getsens(dev, &wrq->u.sens);
-		break;
-
-	case SIOCSIWSENS:
-		err = orinoco_ioctl_setsens(dev, &wrq->u.sens);
-		if (! err)
-			changed = 1;
-		break;
-
-	case SIOCGIWRTS:
-		wrq->u.rts.value = priv->rts_thresh;
-		wrq->u.rts.disabled = (wrq->u.rts.value == 2347);
-		wrq->u.rts.fixed = 1;
-		break;
-
-	case SIOCSIWRTS:
-		err = orinoco_ioctl_setrts(dev, &wrq->u.rts);
-		if (! err)
-			changed = 1;
-		break;
-
-	case SIOCSIWFRAG:
-		err = orinoco_ioctl_setfrag(dev, &wrq->u.frag);
-		if (! err)
-			changed = 1;
-		break;
+	/* One more client */
+	if (! err)
+		priv->scan_inprogress = 1;
 
-	case SIOCGIWFRAG:
-		err = orinoco_ioctl_getfrag(dev, &wrq->u.frag);
-		break;
+ out:
+	orinoco_unlock(priv, &flags);
+	return err;
+}
 
-	case SIOCSIWRATE:
-		err = orinoco_ioctl_setrate(dev, &wrq->u.bitrate);
-		if (! err)
-			changed = 1;
-		break;
+/* Translate scan data returned from the card to a card independant
+ * format that the Wireless Tools will understand - Jean II */
+static inline int orinoco_translate_scan(struct net_device *dev,
+					 char *buffer,
+					 char *scan,
+					 int scan_len)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+	int			offset;		/* In the scan data */
+	union hermes_scan_info *atom;
+	int			atom_len;
+	u16			capabilities;
+	u16			channel;
+	struct iw_event		iwe;		/* Temporary buffer */
+	char *			current_ev = buffer;
+	char *			end_buf = buffer + IW_SCAN_MAX_DATA;
 
-	case SIOCGIWRATE:
-		err = orinoco_ioctl_getrate(dev, &wrq->u.bitrate);
+	switch (priv->firmware_type) {
+	case FIRMWARE_TYPE_AGERE:
+		atom_len = sizeof(struct agere_scan_apinfo);
+ 		offset = 0;
 		break;
-
-	case SIOCSIWPOWER:
-		err = orinoco_ioctl_setpower(dev, &wrq->u.power);
-		if (! err)
-			changed = 1;
+	case FIRMWARE_TYPE_SYMBOL:
+		/* Lack of documentation necessitates this hack.
+		 * Different firmwares have 68 or 76 byte long atoms.
+		 * We try modulo first.  If the length divides by both,
+		 * we check what would be the channel in the second
+		 * frame for a 68-byte atom.  76-byte atoms have 0 there.
+		 * Valid channel cannot be 0.  */
+		if (scan_len % 76)
+			atom_len = 68;
+		else if (scan_len % 68)
+			atom_len = 76;
+		else if (scan_len >= 1292 && scan[68] == 0)
+			atom_len = 76;
+		else
+			atom_len = 68;
+		offset = 0;
 		break;
-
-	case SIOCGIWPOWER:
-		err = orinoco_ioctl_getpower(dev, &wrq->u.power);
+	case FIRMWARE_TYPE_INTERSIL:
+		offset = 4;
+		if (priv->has_hostscan)
+			atom_len = scan[0] + (scan[1] << 8);
+		else
+			atom_len = offsetof(struct prism2_scan_apinfo, atim);
 		break;
+	default:
+		return 0;
+	}
 
-	case SIOCGIWTXPOW:
-		/* The card only supports one tx power, so this is easy */
-		wrq->u.txpower.value = 15; /* dBm */
-		wrq->u.txpower.fixed = 1;
-		wrq->u.txpower.disabled = 0;
-		wrq->u.txpower.flags = IW_TXPOW_DBM;
-		break;
+	/* Check that we got an whole number of atoms */
+	if ((scan_len - offset) % atom_len) {
+		printk(KERN_ERR "%s: Unexpected scan data length %d, "
+		       "atom_len %d, offset %d\n", dev->name, scan_len,
+		       atom_len, offset);
+		return 0;
+	}
 
-	case SIOCSIWRETRY:
-		err = -EOPNOTSUPP;
-		break;
+	/* Read the entries one by one */
+	for (; offset + atom_len <= scan_len; offset += atom_len) {
+		/* Get next atom */
+		atom = (union hermes_scan_info *) (scan + offset);
+
+		/* First entry *MUST* be the AP MAC address */
+		iwe.cmd = SIOCGIWAP;
+		iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
+		memcpy(iwe.u.ap_addr.sa_data, atom->a.bssid, ETH_ALEN);
+		current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_ADDR_LEN);
+
+		/* Other entries will be displayed in the order we give them */
+
+		/* Add the ESSID */
+		iwe.u.data.length = le16_to_cpu(atom->a.essid_len);
+		if (iwe.u.data.length > 32)
+			iwe.u.data.length = 32;
+		iwe.cmd = SIOCGIWESSID;
+		iwe.u.data.flags = 1;
+		current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, atom->a.essid);
+
+		/* Add mode */
+		iwe.cmd = SIOCGIWMODE;
+		capabilities = le16_to_cpu(atom->a.capabilities);
+		if (capabilities & 0x3) {
+			if (capabilities & 0x1)
+				iwe.u.mode = IW_MODE_MASTER;
+			else
+				iwe.u.mode = IW_MODE_ADHOC;
+			current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_UINT_LEN);
+		}
 
-	case SIOCGIWRETRY:
-		err = orinoco_ioctl_getretry(dev, &wrq->u.retry);
-		break;
+		channel = atom->s.channel;
+		if ( (channel >= 1) && (channel <= NUM_CHANNELS) ) {
+			/* Add frequency */
+			iwe.cmd = SIOCGIWFREQ;
+			iwe.u.freq.m = channel_frequency[channel-1] * 100000;
+			iwe.u.freq.e = 1;
+			current_ev = iwe_stream_add_event(current_ev, end_buf,
+							  &iwe, IW_EV_FREQ_LEN);
+		}
+
+		/* Add quality statistics */
+		iwe.cmd = IWEVQUAL;
+		iwe.u.qual.updated = 0x10;	/* no link quality */
+		iwe.u.qual.level = (__u8) le16_to_cpu(atom->a.level) - 0x95;
+		iwe.u.qual.noise = (__u8) le16_to_cpu(atom->a.noise) - 0x95;
+		/* Wireless tools prior to 27.pre22 will show link quality
+		 * anyway, so we provide a reasonable value. */
+		if (iwe.u.qual.level > iwe.u.qual.noise)
+			iwe.u.qual.qual = iwe.u.qual.level - iwe.u.qual.noise;
+		else
+			iwe.u.qual.qual = 0;
+		current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_QUAL_LEN);
 
-	case SIOCSIWSPY:
-		err = orinoco_ioctl_setspy(dev, &wrq->u.data);
-		break;
+		/* Add encryption capability */
+		iwe.cmd = SIOCGIWENCODE;
+		if (capabilities & 0x10)
+			iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
+		else
+			iwe.u.data.flags = IW_ENCODE_DISABLED;
+		iwe.u.data.length = 0;
+		current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, atom->a.essid);
+
+		/* Bit rate is not available in Lucent/Agere firmwares */
+		if (priv->firmware_type != FIRMWARE_TYPE_AGERE) {
+			char *	current_val = current_ev + IW_EV_LCP_LEN;
+			int	i;
+			int	step;
 
-	case SIOCGIWSPY:
-		err = orinoco_ioctl_getspy(dev, &wrq->u.data);
-		break;
+			if (priv->firmware_type == FIRMWARE_TYPE_SYMBOL)
+				step = 2;
+			else
+				step = 1;
 
-	case SIOCGIWPRIV:
-		if (wrq->u.data.pointer) {
-			struct iw_priv_args privtab[] = {
-				{ SIOCIWFIRSTPRIV + 0x0, 0, 0, "force_reset" },
-				{ SIOCIWFIRSTPRIV + 0x1, 0, 0, "card_reset" },
-				{ SIOCIWFIRSTPRIV + 0x2,
-				  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-				  0, "set_port3" },
-				{ SIOCIWFIRSTPRIV + 0x3, 0,
-				  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-				  "get_port3" },
-				{ SIOCIWFIRSTPRIV + 0x4,
-				  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-				  0, "set_preamble" },
-				{ SIOCIWFIRSTPRIV + 0x5, 0,
-				  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-				  "get_preamble" },
-				{ SIOCIWFIRSTPRIV + 0x6,
-				  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-				  0, "set_ibssport" },
-				{ SIOCIWFIRSTPRIV + 0x7, 0,
-				  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-				  "get_ibssport" },
-				{ SIOCIWLASTPRIV, 0, 0, "dump_recs" },
-			};
-
-			wrq->u.data.length = sizeof(privtab) / sizeof(privtab[0]);
-			if (copy_to_user(wrq->u.data.pointer, privtab, sizeof(privtab)))
-				err = -EFAULT;
-		}
-		break;
-	       
-	case SIOCIWFIRSTPRIV + 0x0: /* force_reset */
-	case SIOCIWFIRSTPRIV + 0x1: /* card_reset */
-		if (! capable(CAP_NET_ADMIN)) {
-			err = -EPERM;
-			break;
+			iwe.cmd = SIOCGIWRATE;
+			/* Those two flags are ignored... */
+			iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
+			/* Max 10 values */
+			for (i = 0; i < 10; i += step) {
+				/* NULL terminated */
+				if (atom->p.rates[i] == 0x0)
+					break;
+				/* Bit rate given in 500 kb/s units (+ 0x80) */
+				iwe.u.bitrate.value = ((atom->p.rates[i] & 0x7f) * 500000);
+				current_val = iwe_stream_add_value(current_ev, current_val,
+								   end_buf, &iwe,
+								   IW_EV_PARAM_LEN);
+			}
+			/* Check if we added any event */
+			if ((current_val - current_ev) > IW_EV_LCP_LEN)
+				current_ev = current_val;
 		}
-		
-		printk(KERN_DEBUG "%s: Force scheduling reset!\n", dev->name);
 
-		schedule_work(&priv->reset_work);
-		break;
+		/* The other data in the scan result are not really
+		 * interesting, so for now drop it - Jean II */
+	}
+	return current_ev - buffer;
+}
 
-	case SIOCIWFIRSTPRIV + 0x2: /* set_port3 */
-		if (! capable(CAP_NET_ADMIN)) {
-			err = -EPERM;
-			break;
-		}
+/* Return results of a scan */
+static int orinoco_ioctl_getscan(struct net_device *dev,
+				 struct iw_request_info *info,
+				 struct iw_point *srq,
+				 char *extra)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+	int err = 0;
+	unsigned long flags;
 
-		err = orinoco_ioctl_setport3(dev, wrq);
-		if (! err)
-			changed = 1;
-		break;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 
-	case SIOCIWFIRSTPRIV + 0x3: /* get_port3 */
-		err = orinoco_ioctl_getport3(dev, wrq);
-		break;
+	/* If no results yet, ask to try again later */
+	if (priv->scan_result == NULL) {
+		if (priv->scan_inprogress)
+			/* Important note : we don't want to block the caller
+			 * until results are ready for various reasons.
+			 * First, managing wait queues is complex and racy.
+			 * Second, we grab some rtnetlink lock before comming
+			 * here (in dev_ioctl()).
+			 * Third, we generate an Wireless Event, so the
+			 * caller can wait itself on that - Jean II */
+			err = -EAGAIN;
+		else
+			/* Client error, no scan results...
+			 * The caller need to restart the scan. */
+			err = -ENODATA;
+	} else {
+		/* We have some results to push back to user space */
 
-	case SIOCIWFIRSTPRIV + 0x4: /* set_preamble */
-		if (! capable(CAP_NET_ADMIN)) {
-			err = -EPERM;
-			break;
-		}
+		/* Translate to WE format */
+		srq->length = orinoco_translate_scan(dev, extra,
+						     priv->scan_result,
+						     priv->scan_len);
+
+		/* Return flags */
+		srq->flags = (__u16) priv->scan_mode;
+
+		/* Results are here, so scan no longer in progress */
+		priv->scan_inprogress = 0;
+
+		/* In any case, Scan results will be cleaned up in the
+		 * reset function and when exiting the driver.
+		 * The person triggering the scanning may never come to
+		 * pick the results, so we need to do it in those places.
+		 * Jean II */
+
+#ifdef SCAN_SINGLE_READ
+		/* If you enable this option, only one client (the first
+		 * one) will be able to read the result (and only one
+		 * time). If there is multiple concurent clients that
+		 * want to read scan results, this behavior is not
+		 * advisable - Jean II */
+		kfree(priv->scan_result);
+		priv->scan_result = NULL;
+#endif /* SCAN_SINGLE_READ */
+		/* Here, if too much time has elapsed since last scan,
+		 * we may want to clean up scan results... - Jean II */
+	}
+	  
+	orinoco_unlock(priv, &flags);
+	return err;
+}
 
-		/* 802.11b has recently defined some short preamble.
-		 * Basically, the Phy header has been reduced in size.
-		 * This increase performance, especially at high rates
-		 * (the preamble is transmitted at 1Mb/s), unfortunately
-		 * this give compatibility troubles... - Jean II */
-		if(priv->has_preamble) {
-			int val = *( (int *) wrq->u.name );
-
-			if (orinoco_lock(priv, &flags) != 0)
-				return -EBUSY;
-			if (val)
-				priv->preamble = 1;
-			else
-				priv->preamble = 0;
-			orinoco_unlock(priv, &flags);
-			changed = 1;
-		} else
-			err = -EOPNOTSUPP;
-		break;
+/* Commit handler, called after set operations */
+static int orinoco_ioctl_commit(struct net_device *dev,
+				struct iw_request_info *info,
+				void *wrqu,
+				char *extra)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
+	struct hermes *hw = &priv->hw;
+	unsigned long flags;
+	int err = 0;
 
-	case SIOCIWFIRSTPRIV + 0x5: /* get_preamble */
-		if(priv->has_preamble) {
-			int *val = (int *)wrq->u.name;
-
-			if (orinoco_lock(priv, &flags) != 0)
-				return -EBUSY;
-			*val = priv->preamble;
-			orinoco_unlock(priv, &flags);
-		} else
-			err = -EOPNOTSUPP;
-		break;
-	case SIOCIWFIRSTPRIV + 0x6: /* set_ibssport */
-		if (! capable(CAP_NET_ADMIN)) {
-			err = -EPERM;
-			break;
-		}
+	if (!priv->open)
+		return 0;
 
-		err = orinoco_ioctl_setibssport(dev, wrq);
-		if (! err)
-			changed = 1;
-		break;
+	if (priv->broken_disableport) {
+		orinoco_reset(dev);
+		return 0;
+	}
 
-	case SIOCIWFIRSTPRIV + 0x7: /* get_ibssport */
-		err = orinoco_ioctl_getibssport(dev, wrq);
-		break;
+	if (orinoco_lock(priv, &flags) != 0)
+		return err;
 
-	case SIOCIWLASTPRIV:
-		err = orinoco_debug_dump_recs(dev);
-		if (err)
-			printk(KERN_ERR "%s: Unable to dump records (%d)\n",
-			       dev->name, err);
-		break;
+	err = hermes_disable_port(hw, 0);
+	if (err) {
+		printk(KERN_WARNING "%s: Unable to disable port "
+		       "while reconfiguring card\n", dev->name);
+		priv->broken_disableport = 1;
+		goto out;
+	}
 
+	err = __orinoco_program_rids(dev);
+	if (err) {
+		printk(KERN_WARNING "%s: Unable to reconfigure card\n",
+		       dev->name);
+		goto out;
+	}
 
-	default:
-		err = -EOPNOTSUPP;
+	err = hermes_enable_port(hw, 0);
+	if (err) {
+		printk(KERN_WARNING "%s: Unable to enable port while reconfiguring card\n",
+		       dev->name);
+		goto out;
 	}
-	
-	if (! err && changed && netif_running(dev)) {
-		err = orinoco_reconfigure(dev);
-	}		
 
-	TRACE_EXIT(dev->name);
+ out:
+	if (err) {
+		printk(KERN_WARNING "%s: Resetting instead...\n", dev->name);
+		schedule_work(&priv->reset_work);
+		err = 0;
+	}
 
+	orinoco_unlock(priv, &flags);
 	return err;
 }
 
-struct {
-	u16 rid;
-	char *name;
-	int displaytype;
-#define DISPLAY_WORDS	0
-#define DISPLAY_BYTES	1
-#define DISPLAY_STRING	2
-#define DISPLAY_XSTRING	3
-} record_table[] = {
-#define DEBUG_REC(name,type) { HERMES_RID_##name, #name, DISPLAY_##type }
-	DEBUG_REC(CNFPORTTYPE,WORDS),
-	DEBUG_REC(CNFOWNMACADDR,BYTES),
-	DEBUG_REC(CNFDESIREDSSID,STRING),
-	DEBUG_REC(CNFOWNCHANNEL,WORDS),
-	DEBUG_REC(CNFOWNSSID,STRING),
-	DEBUG_REC(CNFOWNATIMWINDOW,WORDS),
-	DEBUG_REC(CNFSYSTEMSCALE,WORDS),
-	DEBUG_REC(CNFMAXDATALEN,WORDS),
-	DEBUG_REC(CNFPMENABLED,WORDS),
-	DEBUG_REC(CNFPMEPS,WORDS),
-	DEBUG_REC(CNFMULTICASTRECEIVE,WORDS),
-	DEBUG_REC(CNFMAXSLEEPDURATION,WORDS),
-	DEBUG_REC(CNFPMHOLDOVERDURATION,WORDS),
-	DEBUG_REC(CNFOWNNAME,STRING),
-	DEBUG_REC(CNFOWNDTIMPERIOD,WORDS),
-	DEBUG_REC(CNFMULTICASTPMBUFFERING,WORDS),
-	DEBUG_REC(CNFWEPENABLED_AGERE,WORDS),
-	DEBUG_REC(CNFMANDATORYBSSID_SYMBOL,WORDS),
-	DEBUG_REC(CNFWEPDEFAULTKEYID,WORDS),
-	DEBUG_REC(CNFDEFAULTKEY0,BYTES),
-	DEBUG_REC(CNFDEFAULTKEY1,BYTES),
-	DEBUG_REC(CNFMWOROBUST_AGERE,WORDS),
-	DEBUG_REC(CNFDEFAULTKEY2,BYTES),
-	DEBUG_REC(CNFDEFAULTKEY3,BYTES),
-	DEBUG_REC(CNFWEPFLAGS_INTERSIL,WORDS),
-	DEBUG_REC(CNFWEPKEYMAPPINGTABLE,WORDS),
-	DEBUG_REC(CNFAUTHENTICATION,WORDS),
-	DEBUG_REC(CNFMAXASSOCSTA,WORDS),
-	DEBUG_REC(CNFKEYLENGTH_SYMBOL,WORDS),
-	DEBUG_REC(CNFTXCONTROL,WORDS),
-	DEBUG_REC(CNFROAMINGMODE,WORDS),
-	DEBUG_REC(CNFHOSTAUTHENTICATION,WORDS),
-	DEBUG_REC(CNFRCVCRCERROR,WORDS),
-	DEBUG_REC(CNFMMLIFE,WORDS),
-	DEBUG_REC(CNFALTRETRYCOUNT,WORDS),
-	DEBUG_REC(CNFBEACONINT,WORDS),
-	DEBUG_REC(CNFAPPCFINFO,WORDS),
-	DEBUG_REC(CNFSTAPCFINFO,WORDS),
-	DEBUG_REC(CNFPRIORITYQUSAGE,WORDS),
-	DEBUG_REC(CNFTIMCTRL,WORDS),
-	DEBUG_REC(CNFTHIRTY2TALLY,WORDS),
-	DEBUG_REC(CNFENHSECURITY,WORDS),
-	DEBUG_REC(CNFGROUPADDRESSES,BYTES),
-	DEBUG_REC(CNFCREATEIBSS,WORDS),
-	DEBUG_REC(CNFFRAGMENTATIONTHRESHOLD,WORDS),
-	DEBUG_REC(CNFRTSTHRESHOLD,WORDS),
-	DEBUG_REC(CNFTXRATECONTROL,WORDS),
-	DEBUG_REC(CNFPROMISCUOUSMODE,WORDS),
-	DEBUG_REC(CNFBASICRATES_SYMBOL,WORDS),
-	DEBUG_REC(CNFPREAMBLE_SYMBOL,WORDS),
-	DEBUG_REC(CNFSHORTPREAMBLE,WORDS),
-	DEBUG_REC(CNFWEPKEYS_AGERE,BYTES),
-	DEBUG_REC(CNFEXCLUDELONGPREAMBLE,WORDS),
-	DEBUG_REC(CNFTXKEY_AGERE,WORDS),
-	DEBUG_REC(CNFAUTHENTICATIONRSPTO,WORDS),
-	DEBUG_REC(CNFBASICRATES,WORDS),
-	DEBUG_REC(CNFSUPPORTEDRATES,WORDS),
-	DEBUG_REC(CNFTICKTIME,WORDS),
-	DEBUG_REC(CNFSCANREQUEST,WORDS),
-	DEBUG_REC(CNFJOINREQUEST,WORDS),
-	DEBUG_REC(CNFAUTHENTICATESTATION,WORDS),
-	DEBUG_REC(CNFCHANNELINFOREQUEST,WORDS),
-	DEBUG_REC(MAXLOADTIME,WORDS),
-	DEBUG_REC(DOWNLOADBUFFER,WORDS),
-	DEBUG_REC(PRIID,WORDS),
-	DEBUG_REC(PRISUPRANGE,WORDS),
-	DEBUG_REC(CFIACTRANGES,WORDS),
-	DEBUG_REC(NICSERNUM,XSTRING),
-	DEBUG_REC(NICID,WORDS),
-	DEBUG_REC(MFISUPRANGE,WORDS),
-	DEBUG_REC(CFISUPRANGE,WORDS),
-	DEBUG_REC(CHANNELLIST,WORDS),
-	DEBUG_REC(REGULATORYDOMAINS,WORDS),
-	DEBUG_REC(TEMPTYPE,WORDS),
-/*  	DEBUG_REC(CIS,BYTES), */
-	DEBUG_REC(STAID,WORDS),
-	DEBUG_REC(CURRENTSSID,STRING),
-	DEBUG_REC(CURRENTBSSID,BYTES),
-	DEBUG_REC(COMMSQUALITY,WORDS),
-	DEBUG_REC(CURRENTTXRATE,WORDS),
-	DEBUG_REC(CURRENTBEACONINTERVAL,WORDS),
-	DEBUG_REC(CURRENTSCALETHRESHOLDS,WORDS),
-	DEBUG_REC(PROTOCOLRSPTIME,WORDS),
-	DEBUG_REC(SHORTRETRYLIMIT,WORDS),
-	DEBUG_REC(LONGRETRYLIMIT,WORDS),
-	DEBUG_REC(MAXTRANSMITLIFETIME,WORDS),
-	DEBUG_REC(MAXRECEIVELIFETIME,WORDS),
-	DEBUG_REC(CFPOLLABLE,WORDS),
-	DEBUG_REC(AUTHENTICATIONALGORITHMS,WORDS),
-	DEBUG_REC(PRIVACYOPTIONIMPLEMENTED,WORDS),
-	DEBUG_REC(OWNMACADDR,BYTES),
-	DEBUG_REC(SCANRESULTSTABLE,WORDS),
-	DEBUG_REC(PHYTYPE,WORDS),
-	DEBUG_REC(CURRENTCHANNEL,WORDS),
-	DEBUG_REC(CURRENTPOWERSTATE,WORDS),
-	DEBUG_REC(CCAMODE,WORDS),
-	DEBUG_REC(SUPPORTEDDATARATES,WORDS),
-	DEBUG_REC(BUILDSEQ,BYTES),
-	DEBUG_REC(FWID,XSTRING)
-#undef DEBUG_REC
+static const struct iw_priv_args orinoco_privtab[] = {
+	{ SIOCIWFIRSTPRIV + 0x0, 0, 0, "force_reset" },
+	{ SIOCIWFIRSTPRIV + 0x1, 0, 0, "card_reset" },
+	{ SIOCIWFIRSTPRIV + 0x2, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	  0, "set_port3" },
+	{ SIOCIWFIRSTPRIV + 0x3, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	  "get_port3" },
+	{ SIOCIWFIRSTPRIV + 0x4, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	  0, "set_preamble" },
+	{ SIOCIWFIRSTPRIV + 0x5, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	  "get_preamble" },
+	{ SIOCIWFIRSTPRIV + 0x6, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	  0, "set_ibssport" },
+	{ SIOCIWFIRSTPRIV + 0x7, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+	  "get_ibssport" },
+	{ SIOCIWFIRSTPRIV + 0x9, 0, IW_PRIV_TYPE_BYTE | MAX_RID_LEN,
+	  "get_rid" },
 };
 
-#define DEBUG_LTV_SIZE		128
-
-static int orinoco_debug_dump_recs(struct net_device *dev)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	hermes_t *hw = &priv->hw;
-	u8 *val8;
-	u16 *val16;
-	int i,j;
-	u16 length;
-	int err;
-
-	/* I'm not sure: we might have a lock here, so we'd better go
-           atomic, just in case. */
-	val8 = kmalloc(DEBUG_LTV_SIZE + 2, GFP_ATOMIC);
-	if (! val8)
-		return -ENOMEM;
-	val16 = (u16 *)val8;
-
-	for (i = 0; i < ARRAY_SIZE(record_table); i++) {
-		u16 rid = record_table[i].rid;
-		int len;
 
-		memset(val8, 0, DEBUG_LTV_SIZE + 2);
-
-		err = hermes_read_ltv(hw, USER_BAP, rid, DEBUG_LTV_SIZE,
-				      &length, val8);
-		if (err) {
-			DEBUG(0, "Error %d reading RID 0x%04x\n", err, rid);
-			continue;
-		}
-		val16 = (u16 *)val8;
-		if (length == 0)
-			continue;
-
-		printk(KERN_DEBUG "%-15s (0x%04x): length=%d (%d bytes)\tvalue=",
-		       record_table[i].name,
-		       rid, length, (length-1)*2);
-		len = min(((int)length-1)*2, DEBUG_LTV_SIZE);
-
-		switch (record_table[i].displaytype) {
-		case DISPLAY_WORDS:
-			for (j = 0; j < len / 2; j++)
-				printk("%04X-", le16_to_cpu(val16[j]));
-			break;
+/*
+ * Structures to export the Wireless Handlers
+ */
 
-		case DISPLAY_BYTES:
-		default:
-			for (j = 0; j < len; j++)
-				printk("%02X:", val8[j]);
-			break;
+static const iw_handler	orinoco_handler[] = {
+	[SIOCSIWCOMMIT-SIOCIWFIRST] (iw_handler) orinoco_ioctl_commit,
+	[SIOCGIWNAME  -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getname,
+	[SIOCSIWFREQ  -SIOCIWFIRST] (iw_handler) orinoco_ioctl_setfreq,
+	[SIOCGIWFREQ  -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getfreq,
+	[SIOCSIWMODE  -SIOCIWFIRST] (iw_handler) orinoco_ioctl_setmode,
+	[SIOCGIWMODE  -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getmode,
+	[SIOCSIWSENS  -SIOCIWFIRST] (iw_handler) orinoco_ioctl_setsens,
+	[SIOCGIWSENS  -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getsens,
+	[SIOCGIWRANGE -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getiwrange,
+	[SIOCSIWSPY   -SIOCIWFIRST] (iw_handler) orinoco_ioctl_setspy,
+	[SIOCGIWSPY   -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getspy,
+	[SIOCSIWAP    -SIOCIWFIRST] (iw_handler) orinoco_ioctl_setwap,
+	[SIOCGIWAP    -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getwap,
+	[SIOCSIWSCAN  -SIOCIWFIRST] (iw_handler) orinoco_ioctl_setscan,
+	[SIOCGIWSCAN  -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getscan,
+	[SIOCSIWESSID -SIOCIWFIRST] (iw_handler) orinoco_ioctl_setessid,
+	[SIOCGIWESSID -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getessid,
+	[SIOCSIWNICKN -SIOCIWFIRST] (iw_handler) orinoco_ioctl_setnick,
+	[SIOCGIWNICKN -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getnick,
+	[SIOCSIWRATE  -SIOCIWFIRST] (iw_handler) orinoco_ioctl_setrate,
+	[SIOCGIWRATE  -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getrate,
+	[SIOCSIWRTS   -SIOCIWFIRST] (iw_handler) orinoco_ioctl_setrts,
+	[SIOCGIWRTS   -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getrts,
+	[SIOCSIWFRAG  -SIOCIWFIRST] (iw_handler) orinoco_ioctl_setfrag,
+	[SIOCGIWFRAG  -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getfrag,
+	[SIOCGIWRETRY -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getretry,
+	[SIOCSIWENCODE-SIOCIWFIRST] (iw_handler) orinoco_ioctl_setiwencode,
+	[SIOCGIWENCODE-SIOCIWFIRST] (iw_handler) orinoco_ioctl_getiwencode,
+	[SIOCSIWPOWER -SIOCIWFIRST] (iw_handler) orinoco_ioctl_setpower,
+	[SIOCGIWPOWER -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getpower,
+};
 
-		case DISPLAY_STRING:
-			len = min(len, le16_to_cpu(val16[0])+2);
-			val8[len] = '\0';
-			printk("\"%s\"", (char *)&val16[1]);
-			break;
 
-		case DISPLAY_XSTRING:
-			printk("'%s'", (char *)val8);
-		}
+/*
+  Added typecasting since we no longer use iwreq_data -- Moustafa
+ */
+static const iw_handler	orinoco_private_handler[] = {
+	[0] (iw_handler) orinoco_ioctl_reset,
+	[1] (iw_handler) orinoco_ioctl_reset,
+	[2] (iw_handler) orinoco_ioctl_setport3,
+	[3] (iw_handler) orinoco_ioctl_getport3,
+	[4] (iw_handler) orinoco_ioctl_setpreamble,
+	[5] (iw_handler) orinoco_ioctl_getpreamble,
+	[6] (iw_handler) orinoco_ioctl_setibssport,
+	[7] (iw_handler) orinoco_ioctl_getibssport,
+	[9] (iw_handler) orinoco_ioctl_getrid,
+};
 
-		printk("\n");
-	}
+static const struct iw_handler_def orinoco_handler_def = {
+	.num_standard = ARRAY_SIZE(orinoco_handler),
+	.num_private = ARRAY_SIZE(orinoco_private_handler),
+	.num_private_args = ARRAY_SIZE(orinoco_privtab),
+	.standard = orinoco_handler,
+	.private = orinoco_private_handler,
+	.private_args = orinoco_privtab,
+};
 
-	kfree(val8);
+static void orinoco_get_drvinfo(struct net_device *dev,
+				struct ethtool_drvinfo *info)
+{
+	struct orinoco_private *priv = netdev_priv(dev);
 
-	return 0;
+	strncpy(info->driver, DRIVER_NAME, sizeof(info->driver) - 1);
+	strncpy(info->version, DRIVER_VERSION, sizeof(info->version) - 1);
+	strncpy(info->fw_version, priv->fw_name, sizeof(info->fw_version) - 1);
+	if (dev->class_dev.dev)
+		strncpy(info->bus_info, dev->class_dev.dev->bus_id,
+			sizeof(info->bus_info) - 1);
+	else
+		snprintf(info->bus_info, sizeof(info->bus_info) - 1,
+			 "PCMCIA %p", priv->hw.iobase);
 }
 
+static struct ethtool_ops orinoco_ethtool_ops = {
+	.get_drvinfo = orinoco_get_drvinfo,
+	.get_link = ethtool_op_get_link,
+};
+
 /********************************************************************/
 /* Debugging                                                        */
 /********************************************************************/
@@ -4218,7 +4472,6 @@ EXPORT_SYMBOL(free_orinocodev);
 
 EXPORT_SYMBOL(__orinoco_up);
 EXPORT_SYMBOL(__orinoco_down);
-EXPORT_SYMBOL(orinoco_stop);
 EXPORT_SYMBOL(orinoco_reinit_firmware);
 
 EXPORT_SYMBOL(orinoco_interrupt);
diff --git a/drivers/net/wireless/orinoco.h b/drivers/net/wireless/orinoco.h
--- a/drivers/net/wireless/orinoco.h
+++ b/drivers/net/wireless/orinoco.h
@@ -7,7 +7,7 @@
 #ifndef _ORINOCO_H
 #define _ORINOCO_H
 
-#define DRIVER_VERSION "0.14alpha2"
+#define DRIVER_VERSION "0.15rc2"
 
 #include <linux/types.h>
 #include <linux/spinlock.h>
@@ -22,6 +22,8 @@
 
 #define WIRELESS_SPY		// enable iwspy support
 
+#define MAX_SCAN_LEN		4096
+
 #define ORINOCO_MAX_KEY_SIZE	14
 #define ORINOCO_MAX_KEYS	4
 
@@ -30,6 +32,20 @@ struct orinoco_key {
 	char data[ORINOCO_MAX_KEY_SIZE];
 } __attribute__ ((packed));
 
+struct header_struct {
+	/* 802.3 */
+	u8 dest[ETH_ALEN];
+	u8 src[ETH_ALEN];
+	u16 len;
+	/* 802.2 */
+	u8 dsap;
+	u8 ssap;
+	u8 ctrl;
+	/* SNAP */
+	u8 oui[3];
+	u16 ethertype;
+} __attribute__ ((packed));
+
 typedef enum {
 	FIRMWARE_TYPE_AGERE,
 	FIRMWARE_TYPE_INTERSIL,
@@ -48,6 +64,8 @@ struct orinoco_private {
 	/* driver state */
 	int open;
 	u16 last_linkstatus;
+	struct work_struct join_work;
+	struct work_struct wevent_work;
 
 	/* Net device stuff */
 	struct net_device *ndev;
@@ -74,7 +92,9 @@ struct orinoco_private {
 	unsigned int has_pm:1;
 	unsigned int has_preamble:1;
 	unsigned int has_sensitivity:1;
+	unsigned int has_hostscan:1;
 	unsigned int broken_disableport:1;
+	unsigned int broken_monitor:1;
 
 	/* Configuration paramaters */
 	u32 iw_mode;
@@ -84,6 +104,8 @@ struct orinoco_private {
 	int bitratemode;
  	char nick[IW_ESSID_MAX_SIZE+1];
 	char desired_essid[IW_ESSID_MAX_SIZE+1];
+	char desired_bssid[ETH_ALEN];
+	int bssid_fixed;
 	u16 frag_thresh, mwo_robust;
 	u16 channel;
 	u16 ap_density, rts_thresh;
@@ -98,6 +120,12 @@ struct orinoco_private {
 	/* Configuration dependent variables */
 	int port_type, createibss;
 	int promiscuous, mc_count;
+
+	/* Scanning support */
+	int	scan_inprogress;	/* Scan pending... */
+	u32	scan_mode;		/* Type of scan done */
+	char *	scan_result;		/* Result of previous scan */
+	int	scan_len;		/* Lenght of result */
 };
 
 #ifdef ORINOCO_DEBUG
@@ -119,7 +147,6 @@ extern struct net_device *alloc_orinocod
 extern void free_orinocodev(struct net_device *dev);
 extern int __orinoco_up(struct net_device *dev);
 extern int __orinoco_down(struct net_device *dev);
-extern int orinoco_stop(struct net_device *dev);
 extern int orinoco_reinit_firmware(struct net_device *dev);
 extern irqreturn_t orinoco_interrupt(int irq, void * dev_id, struct pt_regs *regs);
 
diff --git a/drivers/net/wireless/orinoco_cs.c b/drivers/net/wireless/orinoco_cs.c
--- a/drivers/net/wireless/orinoco_cs.c
+++ b/drivers/net/wireless/orinoco_cs.c
@@ -31,7 +31,6 @@
 #include <linux/etherdevice.h>
 #include <linux/wireless.h>
 
-#include <pcmcia/version.h>
 #include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
@@ -186,11 +185,6 @@ orinoco_cs_attach(void)
 	dev_list = link;
 
 	client_reg.dev_info = &dev_info;
-	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 = &orinoco_cs_event;
 	client_reg.Version = 0x0210; /* FIXME: what does this mean? */
 	client_reg.event_callback_args.client_data = link;
 
@@ -608,13 +602,63 @@ static char version[] __initdata = DRIVE
 	" (David Gibson <hermes@gibson.dropbear.id.au>, "
 	"Pavel Roskin <proski@gnu.org>, et al)";
 
+static struct pcmcia_device_id orinoco_cs_ids[] = {
+	PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7300),
+	PCMCIA_DEVICE_MANF_CARD(0x0089, 0x0001),
+	PCMCIA_DEVICE_MANF_CARD(0x0138, 0x0002),
+	PCMCIA_DEVICE_MANF_CARD(0x0156, 0x0002),
+	PCMCIA_DEVICE_MANF_CARD(0x01eb, 0x080a),
+	PCMCIA_DEVICE_MANF_CARD(0x0261, 0x0002),
+	PCMCIA_DEVICE_MANF_CARD(0x0268, 0x0001),
+	PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0305),
+	PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1613),
+	PCMCIA_DEVICE_MANF_CARD(0x028a, 0x0002),
+	PCMCIA_DEVICE_MANF_CARD(0x028a, 0x0673),
+	PCMCIA_DEVICE_MANF_CARD(0x02aa, 0x0002),
+	PCMCIA_DEVICE_MANF_CARD(0x02ac, 0x0002),
+	PCMCIA_DEVICE_MANF_CARD(0x14ea, 0xb001),
+	PCMCIA_DEVICE_MANF_CARD(0x50c2, 0x7300),
+	PCMCIA_DEVICE_MANF_CARD(0x9005, 0x0021),
+	PCMCIA_DEVICE_MANF_CARD(0xc250, 0x0002),
+	PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0002),
+	PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0005),
+	PCMCIA_DEVICE_PROD_ID12("3Com", "3CRWE737A AirConnect Wireless LAN PC Card", 0x41240e5b, 0x56010af3),
+	PCMCIA_DEVICE_PROD_ID123("Instant Wireless ", " Network PC CARD", "Version 01.02", 0x11d901af, 0x6e9bd926, 0x4b74baa0),
+	PCMCIA_DEVICE_PROD_ID12("ACTIONTEC", "PRISM Wireless LAN PC Card", 0x393089da, 0xa71e69d5),
+	PCMCIA_DEVICE_PROD_ID12("Avaya Communication", "Avaya Wireless PC Card", 0xd8a43b78, 0x0d341169),
+	PCMCIA_DEVICE_PROD_ID12("BUFFALO", "WLI-PCM-L11G", 0x2decece3, 0xf57ca4b3),
+	PCMCIA_DEVICE_PROD_ID12("Cabletron", "RoamAbout 802.11 DS", 0x32d445f5, 0xedeffd90),
+	PCMCIA_DEVICE_PROD_ID12("corega K.K.", "Wireless LAN PCC-11", 0x5261440f, 0xa6405584),
+	PCMCIA_DEVICE_PROD_ID12("corega K.K.", "Wireless LAN PCCA-11", 0x5261440f, 0xdf6115f9),
+	PCMCIA_DEVICE_PROD_ID12("D", "Link DRC-650 11Mbps WLAN Card", 0x71b18589, 0xf144e3ac),
+	PCMCIA_DEVICE_PROD_ID12("D", "Link DWL-650 11Mbps WLAN Card", 0x71b18589, 0xb6f1b0ab),
+	PCMCIA_DEVICE_PROD_ID12("ELSA", "AirLancer MC-11", 0x4507a33a, 0xef54f0e3),
+	PCMCIA_DEVICE_PROD_ID12("HyperLink", "Wireless PC Card 11Mbps", 0x56cc3f1a, 0x0bcf220c),
+	PCMCIA_DEVICE_PROD_ID12("INTERSIL", "HFA384x/IEEE", 0x74c5e40d, 0xdb472a18),
+	PCMCIA_DEVICE_PROD_ID12("Lucent Technologies", "WaveLAN/IEEE", 0x23eb9949, 0xc562e72a),
+	PCMCIA_DEVICE_PROD_ID12("MELCO", "WLI-PCM-L11", 0x481e0094, 0x7360e410),
+	PCMCIA_DEVICE_PROD_ID12("MELCO", "WLI-PCM-L11G", 0x481e0094, 0xf57ca4b3),
+	PCMCIA_DEVICE_PROD_ID12("Microsoft", "Wireless Notebook Adapter MN-520", 0x5961bf85, 0x6eec8c01),
+	PCMCIA_DEVICE_PROD_ID12("NCR", "WaveLAN/IEEE", 0x24358cd4, 0xc562e72a),
+	PCMCIA_DEVICE_PROD_ID12("NETGEAR MA401RA Wireless PC", "Card", 0x0306467f, 0x9762e8f1),
+	PCMCIA_DEVICE_PROD_ID12("PLANEX", "GeoWave/GW-CF110", 0x209f40ab, 0xd9715264),
+	PCMCIA_DEVICE_PROD_ID12("PROXIM", "LAN PC CARD HARMONY 80211B", 0xc6536a5e, 0x090c3cd9),
+	PCMCIA_DEVICE_PROD_ID12("PROXIM", "LAN PCI CARD HARMONY 80211B", 0xc6536a5e, 0x9f494e26),
+	PCMCIA_DEVICE_PROD_ID12("SAMSUNG", "11Mbps WLAN Card", 0x43d74cb4, 0x579bd91b),
+	PCMCIA_DEVICE_PROD_ID1("Symbol Technologies", 0x3f02b4d6),
+	PCMCIA_DEVICE_NULL,
+};
+MODULE_DEVICE_TABLE(pcmcia, orinoco_cs_ids);
+
 static struct pcmcia_driver orinoco_driver = {
 	.owner		= THIS_MODULE,
 	.drv		= {
 		.name	= DRIVER_NAME,
 	},
 	.attach		= orinoco_cs_attach,
+	.event		= orinoco_cs_event,
 	.detach		= orinoco_cs_detach,
+	.id_table       = orinoco_cs_ids,
 };
 
 static int __init
diff --git a/drivers/net/wireless/prism54/isl_38xx.c b/drivers/net/wireless/prism54/isl_38xx.c
--- a/drivers/net/wireless/prism54/isl_38xx.c
+++ b/drivers/net/wireless/prism54/isl_38xx.c
@@ -112,10 +112,10 @@ isl38xx_handle_wakeup(isl38xx_control_bl
 void
 isl38xx_trigger_device(int asleep, void __iomem *device_base)
 {
-	struct timeval current_time;
 	u32 reg, counter = 0;
 
 #if VERBOSE > SHOW_ERROR_MESSAGES
+	struct timeval current_time;
 	DEBUG(SHOW_FUNCTION_CALLS, "isl38xx trigger device\n");
 #endif
 
@@ -126,11 +126,11 @@ isl38xx_trigger_device(int asleep, void 
 		do_gettimeofday(&current_time);
 		DEBUG(SHOW_TRACING, "%08li.%08li Device wakeup triggered\n",
 		      current_time.tv_sec, (long)current_time.tv_usec);
-#endif
 
 		DEBUG(SHOW_TRACING, "%08li.%08li Device register read %08x\n",
 		      current_time.tv_sec, (long)current_time.tv_usec,
 		      readl(device_base + ISL38XX_CTRL_STAT_REG));
+#endif
 		udelay(ISL38XX_WRITEIO_DELAY);
 
 		reg = readl(device_base + ISL38XX_INT_IDENT_REG);
@@ -148,10 +148,12 @@ isl38xx_trigger_device(int asleep, void 
 				counter++;
 			}
 
+#if VERBOSE > SHOW_ERROR_MESSAGES
 			DEBUG(SHOW_TRACING,
 			      "%08li.%08li Device register read %08x\n",
 			      current_time.tv_sec, (long)current_time.tv_usec,
 			      readl(device_base + ISL38XX_CTRL_STAT_REG));
+#endif
 			udelay(ISL38XX_WRITEIO_DELAY);
 
 #if VERBOSE > SHOW_ERROR_MESSAGES
diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c
--- a/drivers/net/wireless/ray_cs.c
+++ b/drivers/net/wireless/ray_cs.c
@@ -46,7 +46,6 @@
 #include <linux/skbuff.h>
 #include <linux/ethtool.h>
 
-#include <pcmcia/version.h>
 #include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
@@ -393,11 +392,6 @@ static dev_link_t *ray_attach(void)
     link->next = dev_list;
     dev_list = link;
     client_reg.dev_info = &dev_info;
-    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 = &ray_event;
     client_reg.Version = 0x0210;
     client_reg.event_callback_args.client_data = link;
 
@@ -2904,13 +2898,21 @@ static int write_int(struct file *file, 
 }
 #endif
 
+static struct pcmcia_device_id ray_ids[] = {
+	PCMCIA_DEVICE_MANF_CARD(0x01a6, 0x0000),
+	PCMCIA_DEVICE_NULL,
+};
+MODULE_DEVICE_TABLE(pcmcia, ray_ids);
+
 static struct pcmcia_driver ray_driver = {
 	.owner		= THIS_MODULE,
 	.drv		= {
 		.name	= "ray_cs",
 	},
 	.attach		= ray_attach,
+	.event		= ray_event,
 	.detach		= ray_detach,
+	.id_table       = ray_ids,
 };
 
 static int __init init_ray_cs(void)
diff --git a/drivers/net/wireless/strip.c b/drivers/net/wireless/strip.c
--- a/drivers/net/wireless/strip.c
+++ b/drivers/net/wireless/strip.c
@@ -2828,7 +2828,7 @@ static void __exit strip_exit_driver(voi
 	/* Unregister with the /proc/net file here. */
 	proc_net_remove("strip");
 
-	if ((i = tty_register_ldisc(N_STRIP, NULL)))
+	if ((i = tty_unregister_ldisc(N_STRIP)))
 		printk(KERN_ERR "STRIP: can't unregister line discipline (err = %d)\n", i);
 
 	printk(signoff);
diff --git a/drivers/net/wireless/wavelan_cs.c b/drivers/net/wireless/wavelan_cs.c
--- a/drivers/net/wireless/wavelan_cs.c
+++ b/drivers/net/wireless/wavelan_cs.c
@@ -4684,12 +4684,6 @@ wavelan_attach(void)
 
   /* Register with Card Services */
   client_reg.dev_info = &dev_info;
-  client_reg.EventMask = 
-    CS_EVENT_REGISTRATION_COMPLETE |
-    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 = &wavelan_event;
   client_reg.Version = 0x0210;
   client_reg.event_callback_args.client_data = link;
 
@@ -4889,13 +4883,24 @@ wavelan_event(event_t		event,		/* The ev
   return 0;
 }
 
+static struct pcmcia_device_id wavelan_ids[] = {
+	PCMCIA_DEVICE_PROD_ID12("AT&T","WaveLAN/PCMCIA", 0xe7c5affd, 0x1bc50975),
+	PCMCIA_DEVICE_PROD_ID12("Digital", "RoamAbout/DS", 0x9999ab35, 0x00d05e06),
+	PCMCIA_DEVICE_PROD_ID12("Lucent Technologies", "WaveLAN/PCMCIA", 0x23eb9949, 0x1bc50975),
+	PCMCIA_DEVICE_PROD_ID12("NCR", "WaveLAN/PCMCIA", 0x24358cd4, 0x1bc50975),
+	PCMCIA_DEVICE_NULL,
+};
+MODULE_DEVICE_TABLE(pcmcia, wavelan_ids);
+
 static struct pcmcia_driver wavelan_driver = {
 	.owner		= THIS_MODULE,
 	.drv		= {
 		.name	= "wavelan_cs",
 	},
 	.attach		= wavelan_attach,
+	.event		= wavelan_event,
 	.detach		= wavelan_detach,
+	.id_table       = wavelan_ids,
 };
 
 static int __init
diff --git a/drivers/net/wireless/wavelan_cs.p.h b/drivers/net/wireless/wavelan_cs.p.h
--- a/drivers/net/wireless/wavelan_cs.p.h
+++ b/drivers/net/wireless/wavelan_cs.p.h
@@ -452,7 +452,6 @@
 #include <pcmcia/cistpl.h>
 #include <pcmcia/cisreg.h>
 #include <pcmcia/ds.h>
-#include <pcmcia/version.h>
 
 /* Wavelan declarations */
 #include "i82593.h"	/* Definitions for the Intel chip */
diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c
--- a/drivers/net/wireless/wl3501_cs.c
+++ b/drivers/net/wireless/wl3501_cs.c
@@ -49,7 +49,6 @@
 
 #include <net/iw_handler.h>
 
-#include <pcmcia/version.h>
 #include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
@@ -2005,13 +2004,6 @@ static dev_link_t *wl3501_attach(void)
 	link->next		 = wl3501_dev_list;
 	wl3501_dev_list		 = link;
 	client_reg.dev_info	 = &wl3501_dev_info;
-	client_reg.EventMask	 = CS_EVENT_CARD_INSERTION |
-				   CS_EVENT_RESET_PHYSICAL |
-				   CS_EVENT_CARD_RESET |
-				   CS_EVENT_CARD_REMOVAL |
-				   CS_EVENT_PM_SUSPEND |
-				   CS_EVENT_PM_RESUME;
-	client_reg.event_handler = wl3501_event;
 	client_reg.Version	 = 0x0210;
 	client_reg.event_callback_args.client_data = link;
 	ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -2239,13 +2231,21 @@ static int wl3501_event(event_t event, i
 	return 0;
 }
 
+static struct pcmcia_device_id wl3501_ids[] = {
+	PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0001),
+	PCMCIA_DEVICE_NULL
+};
+MODULE_DEVICE_TABLE(pcmcia, wl3501_ids);
+
 static struct pcmcia_driver wl3501_driver = {
-	.owner          = THIS_MODULE,
-	.drv            = {
-		.name   = "wl3501_cs",
+	.owner		= THIS_MODULE,
+	.drv		= {
+		.name	= "wl3501_cs",
 	},
-	.attach         = wl3501_attach,
-	.detach         = wl3501_detach,
+	.attach		= wl3501_attach,
+	.event		= wl3501_event,
+	.detach		= wl3501_detach,
+	.id_table	= wl3501_ids,
 };
 
 static int __init wl3501_init_module(void)
diff --git a/drivers/net/yellowfin.c b/drivers/net/yellowfin.c
--- a/drivers/net/yellowfin.c
+++ b/drivers/net/yellowfin.c
@@ -786,7 +786,7 @@ static void yellowfin_init_ring(struct n
 		skb->dev = dev;		/* Mark as being used by this device. */
 		skb_reserve(skb, 2);	/* 16 byte align the IP header. */
 		yp->rx_ring[i].addr = cpu_to_le32(pci_map_single(yp->pci_dev,
-			skb->tail, yp->rx_buf_sz, PCI_DMA_FROMDEVICE));
+			skb->data, yp->rx_buf_sz, PCI_DMA_FROMDEVICE));
 	}
 	yp->rx_ring[i-1].dbdma_cmd = cpu_to_le32(CMD_STOP);
 	yp->dirty_rx = (unsigned int)(i - RX_RING_SIZE);
@@ -1111,7 +1111,7 @@ static int yellowfin_rx(struct net_devic
 		pci_dma_sync_single_for_cpu(yp->pci_dev, desc->addr,
 			yp->rx_buf_sz, PCI_DMA_FROMDEVICE);
 		desc_status = le32_to_cpu(desc->result_status) >> 16;
-		buf_addr = rx_skb->tail;
+		buf_addr = rx_skb->data;
 		data_size = (le32_to_cpu(desc->dbdma_cmd) - 
 			le32_to_cpu(desc->result_status)) & 0xffff;
 		frame_status = le16_to_cpu(get_unaligned((s16*)&(buf_addr[data_size - 2])));
@@ -1185,7 +1185,7 @@ static int yellowfin_rx(struct net_devic
 					break;
 				skb->dev = dev;
 				skb_reserve(skb, 2);	/* 16 byte align the IP header */
-				eth_copy_and_sum(skb, rx_skb->tail, pkt_len, 0);
+				eth_copy_and_sum(skb, rx_skb->data, pkt_len, 0);
 				skb_put(skb, pkt_len);
 				pci_dma_sync_single_for_device(yp->pci_dev, desc->addr,
 											   yp->rx_buf_sz,
@@ -1211,7 +1211,7 @@ static int yellowfin_rx(struct net_devic
 			skb->dev = dev;	/* Mark as being used by this device. */
 			skb_reserve(skb, 2);	/* Align IP on 16 byte boundaries */
 			yp->rx_ring[entry].addr = cpu_to_le32(pci_map_single(yp->pci_dev,
-				skb->tail, yp->rx_buf_sz, PCI_DMA_FROMDEVICE));
+				skb->data, yp->rx_buf_sz, PCI_DMA_FROMDEVICE));
 		}
 		yp->rx_ring[entry].dbdma_cmd = cpu_to_le32(CMD_STOP);
 		yp->rx_ring[entry].result_status = 0;	/* Clear complete bit. */
diff --git a/drivers/oprofile/buffer_sync.c b/drivers/oprofile/buffer_sync.c
--- a/drivers/oprofile/buffer_sync.c
+++ b/drivers/oprofile/buffer_sync.c
@@ -62,7 +62,7 @@ static int task_exit_notify(struct notif
 	/* To avoid latency problems, we only process the current CPU,
 	 * hoping that most samples for the task are on this CPU
 	 */
-	sync_buffer(_smp_processor_id());
+	sync_buffer(raw_smp_processor_id());
   	return 0;
 }
 
@@ -86,7 +86,7 @@ static int munmap_notify(struct notifier
 		/* To avoid latency problems, we only process the current CPU,
 		 * hoping that most samples for the task are on this CPU
 		 */
-		sync_buffer(_smp_processor_id());
+		sync_buffer(raw_smp_processor_id());
 		return 0;
 	}
 
@@ -206,7 +206,7 @@ static inline unsigned long fast_get_dco
  */
 static unsigned long get_exec_dcookie(struct mm_struct * mm)
 {
-	unsigned long cookie = 0;
+	unsigned long cookie = NO_COOKIE;
 	struct vm_area_struct * vma;
  
 	if (!mm)
@@ -234,35 +234,42 @@ out:
  */
 static unsigned long lookup_dcookie(struct mm_struct * mm, unsigned long addr, off_t * offset)
 {
-	unsigned long cookie = 0;
+	unsigned long cookie = NO_COOKIE;
 	struct vm_area_struct * vma;
 
 	for (vma = find_vma(mm, addr); vma; vma = vma->vm_next) {
  
-		if (!vma->vm_file)
-			continue;
-
 		if (addr < vma->vm_start || addr >= vma->vm_end)
 			continue;
 
-		cookie = fast_get_dcookie(vma->vm_file->f_dentry,
-			vma->vm_file->f_vfsmnt);
-		*offset = (vma->vm_pgoff << PAGE_SHIFT) + addr - vma->vm_start; 
+		if (vma->vm_file) {
+			cookie = fast_get_dcookie(vma->vm_file->f_dentry,
+				vma->vm_file->f_vfsmnt);
+			*offset = (vma->vm_pgoff << PAGE_SHIFT) + addr -
+				vma->vm_start;
+		} else {
+			/* must be an anonymous map */
+			*offset = addr;
+		}
+
 		break;
 	}
 
+	if (!vma)
+		cookie = INVALID_COOKIE;
+
 	return cookie;
 }
 
 
-static unsigned long last_cookie = ~0UL;
+static unsigned long last_cookie = INVALID_COOKIE;
  
 static void add_cpu_switch(int i)
 {
 	add_event_entry(ESCAPE_CODE);
 	add_event_entry(CPU_SWITCH_CODE);
 	add_event_entry(i);
-	last_cookie = ~0UL;
+	last_cookie = INVALID_COOKIE;
 }
 
 static void add_kernel_ctx_switch(unsigned int in_kernel)
@@ -317,7 +324,7 @@ static int add_us_sample(struct mm_struc
  
  	cookie = lookup_dcookie(mm, s->eip, &offset);
  
-	if (!cookie) {
+	if (cookie == INVALID_COOKIE) {
 		atomic_inc(&oprofile_stats.sample_lost_no_mapping);
 		return 0;
 	}
diff --git a/drivers/oprofile/cpu_buffer.c b/drivers/oprofile/cpu_buffer.c
--- a/drivers/oprofile/cpu_buffer.c
+++ b/drivers/oprofile/cpu_buffer.c
@@ -42,8 +42,7 @@ void free_cpu_buffers(void)
 		vfree(cpu_buffer[i].buffer);
 	}
 }
- 
- 
+
 int alloc_cpu_buffers(void)
 {
 	int i;
@@ -74,7 +73,6 @@ fail:
 	free_cpu_buffers();
 	return -ENOMEM;
 }
- 
 
 void start_cpu_work(void)
 {
@@ -93,7 +91,6 @@ void start_cpu_work(void)
 	}
 }
 
-
 void end_cpu_work(void)
 {
 	int i;
@@ -109,7 +106,6 @@ void end_cpu_work(void)
 	flush_scheduled_work();
 }
 
-
 /* Resets the cpu buffer to a sane state. */
 void cpu_buffer_reset(struct oprofile_cpu_buffer * cpu_buf)
 {
@@ -121,7 +117,6 @@ void cpu_buffer_reset(struct oprofile_cp
 	cpu_buf->last_task = NULL;
 }
 
-
 /* compute number of available slots in cpu_buffer queue */
 static unsigned long nr_available_slots(struct oprofile_cpu_buffer const * b)
 {
@@ -134,7 +129,6 @@ static unsigned long nr_available_slots(
 	return tail + (b->buffer_size - head) - 1;
 }
 
-
 static void increment_head(struct oprofile_cpu_buffer * b)
 {
 	unsigned long new_head = b->head_pos + 1;
@@ -149,10 +143,7 @@ static void increment_head(struct oprofi
 		b->head_pos = 0;
 }
 
-
-
-
-inline static void
+static inline void
 add_sample(struct oprofile_cpu_buffer * cpu_buf,
            unsigned long pc, unsigned long event)
 {
@@ -162,14 +153,12 @@ add_sample(struct oprofile_cpu_buffer * 
 	increment_head(cpu_buf);
 }
 
-
-inline static void
+static inline void
 add_code(struct oprofile_cpu_buffer * buffer, unsigned long value)
 {
 	add_sample(buffer, ESCAPE_CODE, value);
 }
 
-
 /* This must be safe from any context. It's safe writing here
  * because of the head/tail separation of the writer and reader
  * of the CPU buffer.
@@ -223,13 +212,11 @@ static int oprofile_begin_trace(struct o
 	return 1;
 }
 
-
 static void oprofile_end_trace(struct oprofile_cpu_buffer * cpu_buf)
 {
 	cpu_buf->tracing = 0;
 }
 
-
 void oprofile_add_sample(struct pt_regs * const regs, unsigned long event)
 {
 	struct oprofile_cpu_buffer * cpu_buf = &cpu_buffer[smp_processor_id()];
@@ -251,14 +238,12 @@ void oprofile_add_sample(struct pt_regs 
 	oprofile_end_trace(cpu_buf);
 }
 
-
 void oprofile_add_pc(unsigned long pc, int is_kernel, unsigned long event)
 {
 	struct oprofile_cpu_buffer * cpu_buf = &cpu_buffer[smp_processor_id()];
 	log_sample(cpu_buf, pc, is_kernel, event);
 }
 
-
 void oprofile_add_trace(unsigned long pc)
 {
 	struct oprofile_cpu_buffer * cpu_buf = &cpu_buffer[smp_processor_id()];
@@ -283,8 +268,6 @@ void oprofile_add_trace(unsigned long pc
 	add_sample(cpu_buf, pc, 0);
 }
 
-
-
 /*
  * This serves to avoid cpu buffer overflow, and makes sure
  * the task mortuary progresses
diff --git a/drivers/oprofile/event_buffer.h b/drivers/oprofile/event_buffer.h
--- a/drivers/oprofile/event_buffer.h
+++ b/drivers/oprofile/event_buffer.h
@@ -35,6 +35,9 @@ void wake_up_buffer_waiter(void);
 #define TRACE_BEGIN_CODE		8
 #define TRACE_END_CODE			9
  
+#define INVALID_COOKIE ~0UL
+#define NO_COOKIE 0UL
+
 /* add data to the event buffer */
 void add_event_entry(unsigned long data);
  
diff --git a/drivers/parisc/dino.c b/drivers/parisc/dino.c
--- a/drivers/parisc/dino.c
+++ b/drivers/parisc/dino.c
@@ -993,6 +993,7 @@ dino_driver_callback(struct parisc_devic
 	bus = pci_scan_bus_parented(&dev->dev, dino_current_bus,
 				    &dino_cfg_ops, NULL);
 	if(bus) {
+		pci_bus_add_devices(bus);
 		/* This code *depends* on scanning being single threaded
 		 * if it isn't, this global bus number count will fail
 		 */
diff --git a/drivers/parisc/lba_pci.c b/drivers/parisc/lba_pci.c
--- a/drivers/parisc/lba_pci.c
+++ b/drivers/parisc/lba_pci.c
@@ -1570,6 +1570,8 @@ lba_driver_probe(struct parisc_device *d
 	lba_bus = lba_dev->hba.hba_bus =
 		pci_scan_bus_parented(&dev->dev, lba_dev->hba.bus_num.start,
 				cfg_ops, NULL);
+	if (lba_bus)
+		pci_bus_add_devices(lba_bus);
 
 	/* This is in lieu of calling pci_assign_unassigned_resources() */
 	if (is_pdc_pat()) {
diff --git a/drivers/parport/Kconfig b/drivers/parport/Kconfig
--- a/drivers/parport/Kconfig
+++ b/drivers/parport/Kconfig
@@ -34,7 +34,7 @@ config PARPORT
 
 config PARPORT_PC
 	tristate "PC-style hardware"
-	depends on PARPORT && (!SPARC64 || PCI) && !SPARC32
+	depends on PARPORT && (!SPARC64 || PCI) && !SPARC32 && !M32R
 	---help---
 	  You should say Y here if you have a PC-style parallel port. All
 	  IBM PC compatible computers and some Alphas have PC-style
diff --git a/drivers/parport/parport_cs.c b/drivers/parport/parport_cs.c
--- a/drivers/parport/parport_cs.c
+++ b/drivers/parport/parport_cs.c
@@ -48,7 +48,6 @@
 #include <linux/parport.h>
 #include <linux/parport_pc.h>
 
-#include <pcmcia/version.h>
 #include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
@@ -133,11 +132,6 @@ static dev_link_t *parport_attach(void)
     link->next = dev_list;
     dev_list = link;
     client_reg.dev_info = &dev_info;
-    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 = &parport_event;
     client_reg.Version = 0x0210;
     client_reg.event_callback_args.client_data = link;
     ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -373,13 +367,23 @@ int parport_event(event_t event, int pri
     return 0;
 } /* parport_event */
 
+static struct pcmcia_device_id parport_ids[] = {
+	PCMCIA_DEVICE_FUNC_ID(3),
+	PCMCIA_DEVICE_MANF_CARD(0x0137, 0x0003),
+	PCMCIA_DEVICE_NULL
+};
+MODULE_DEVICE_TABLE(pcmcia, parport_ids);
+
 static struct pcmcia_driver parport_cs_driver = {
 	.owner		= THIS_MODULE,
 	.drv		= {
 		.name	= "parport_cs",
 	},
 	.attach		= parport_attach,
+	.event		= parport_event,
 	.detach		= parport_detach,
+	.id_table	= parport_ids,
+
 };
 
 static int __init init_parport_cs(void)
diff --git a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c
--- a/drivers/parport/parport_pc.c
+++ b/drivers/parport/parport_pc.c
@@ -2751,7 +2751,6 @@ enum parport_pc_pci_cards {
 	netmos_9755,
 	netmos_9805,
 	netmos_9815,
-	netmos_9855,
 };
 
 
@@ -2826,7 +2825,6 @@ static struct parport_pc_pci {
         /* netmos_9755 */               { 2, { { 0, 1 }, { 2, 3 },} }, /* untested */
 	/* netmos_9805 */               { 1, { { 0, -1 }, } }, /* untested */
 	/* netmos_9815 */               { 2, { { 0, -1 }, { 2, -1 }, } }, /* untested */
-	/* netmos_9855 */               { 2, { { 0, -1 }, { 2, -1 }, } }, /* untested */
 };
 
 static struct pci_device_id parport_pc_pci_tbl[] = {
@@ -2907,8 +2905,6 @@ static struct pci_device_id parport_pc_p
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9805 },
 	{ PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9815,
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9815 },
-	{ PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9855,
-	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9855 },
 	{ 0, } /* terminate list */
 };
 MODULE_DEVICE_TABLE(pci,parport_pc_pci_tbl);
@@ -3012,7 +3008,7 @@ static int __init parport_pc_init_superi
 	int ret = 0;
 
 	while ((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) != NULL) {
-		id = pci_match_device (parport_pc_pci_tbl, pdev);
+		id = pci_match_id(parport_pc_pci_tbl, pdev);
 		if (id == NULL || id->driver_data >= last_sio)
 			continue;
 
diff --git a/drivers/parport/parport_serial.c b/drivers/parport/parport_serial.c
--- a/drivers/parport/parport_serial.c
+++ b/drivers/parport/parport_serial.c
@@ -34,6 +34,7 @@ enum parport_pc_pci_cards {
 	titan_110l = 0,
 	titan_210l,
 	netmos_9xx5_combo,
+	netmos_9855,
 	avlab_1s1p,
 	avlab_1s1p_650,
 	avlab_1s1p_850,
@@ -87,6 +88,7 @@ static struct parport_pc_pci cards[] __d
 	/* titan_110l */		{ 1, { { 3, -1 }, } },
 	/* titan_210l */		{ 1, { { 3, -1 }, } },
 	/* netmos_9xx5_combo */		{ 1, { { 2, -1 }, }, netmos_parallel_init },
+	/* netmos_9855 */		{ 1, { { 0, -1 }, }, netmos_parallel_init },
 	/* avlab_1s1p     */		{ 1, { { 1, 2}, } },
 	/* avlab_1s1p_650 */		{ 1, { { 1, 2}, } },
 	/* avlab_1s1p_850 */		{ 1, { { 1, 2}, } },
@@ -120,7 +122,7 @@ static struct pci_device_id parport_seri
 	{ PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9845,
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9xx5_combo },
 	{ PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9855,
-	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9xx5_combo },
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9855 },
 	/* PCI_VENDOR_ID_AVLAB/Intek21 has another bunch of cards ...*/
 	{ 0x14db, 0x2110, PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1s1p},
 	{ 0x14db, 0x2111, PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1s1p_650},
@@ -207,6 +209,7 @@ static struct pci_board_no_ids pci_board
 /* titan_110l */	{ SPCI_FL_BASE1 | SPCI_FL_BASE_TABLE, 1, 921600 },
 /* titan_210l */	{ SPCI_FL_BASE1 | SPCI_FL_BASE_TABLE, 2, 921600 },
 /* netmos_9xx5_combo */	{ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 1, 115200, 0, 0, netmos_serial_init },
+/* netmos_9855 */	{ SPCI_FL_BASE2 | SPCI_FL_BASE_TABLE, 1, 115200, 0, 0, netmos_serial_init },
 /* avlab_1s1p (n/t) */	{ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 1, 115200 },
 /* avlab_1s1p_650 (nt)*/{ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 1, 115200 },
 /* avlab_1s1p_850 (nt)*/{ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 1, 115200 },
diff --git a/drivers/parport/probe.c b/drivers/parport/probe.c
--- a/drivers/parport/probe.c
+++ b/drivers/parport/probe.c
@@ -48,14 +48,6 @@ static void pretty_print(struct parport 
 	printk("\n");
 }
 
-static char *strdup(char *str)
-{
-	int n = strlen(str)+1;
-	char *s = kmalloc(n, GFP_KERNEL);
-	if (!s) return NULL;
-	return strcpy(s, str);
-}
-
 static void parse_data(struct parport *port, int device, char *str)
 {
 	char *txt = kmalloc(strlen(str)+1, GFP_KERNEL);
@@ -88,16 +80,16 @@ static void parse_data(struct parport *p
 			if (!strcmp(p, "MFG") || !strcmp(p, "MANUFACTURER")) {
 				if (info->mfr)
 					kfree (info->mfr);
-				info->mfr = strdup(sep);
+				info->mfr = kstrdup(sep, GFP_KERNEL);
 			} else if (!strcmp(p, "MDL") || !strcmp(p, "MODEL")) {
 				if (info->model)
 					kfree (info->model);
-				info->model = strdup(sep);
+				info->model = kstrdup(sep, GFP_KERNEL);
 			} else if (!strcmp(p, "CLS") || !strcmp(p, "CLASS")) {
 				int i;
 				if (info->class_name)
 					kfree (info->class_name);
-				info->class_name = strdup(sep);
+				info->class_name = kstrdup(sep, GFP_KERNEL);
 				for (u = sep; *u; u++)
 					*u = toupper(*u);
 				for (i = 0; classes[i].token; i++) {
@@ -112,7 +104,7 @@ static void parse_data(struct parport *p
 				   !strcmp(p, "COMMAND SET")) {
 				if (info->cmdset)
 					kfree (info->cmdset);
-				info->cmdset = strdup(sep);
+				info->cmdset = kstrdup(sep, GFP_KERNEL);
 				/* if it speaks printer language, it's
 				   probably a printer */
 				if (strstr(sep, "PJL") || strstr(sep, "PCL"))
@@ -120,7 +112,7 @@ static void parse_data(struct parport *p
 			} else if (!strcmp(p, "DES") || !strcmp(p, "DESCRIPTION")) {
 				if (info->description)
 					kfree (info->description);
-				info->description = strdup(sep);
+				info->description = kstrdup(sep, GFP_KERNEL);
 			}
 		}
 	rock_on:
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
--- a/drivers/pci/Makefile
+++ b/drivers/pci/Makefile
@@ -19,6 +19,7 @@ obj-$(CONFIG_HOTPLUG_PCI) += hotplug/
 #
 # Some architectures use the generic PCI setup functions
 #
+obj-$(CONFIG_X86) += setup-bus.o
 obj-$(CONFIG_ALPHA) += setup-bus.o setup-irq.o
 obj-$(CONFIG_ARM) += setup-bus.o setup-irq.o
 obj-$(CONFIG_PARISC) += setup-bus.o
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c
--- a/drivers/pci/bus.c
+++ b/drivers/pci/bus.c
@@ -60,7 +60,9 @@ pci_bus_alloc_resource(struct pci_bus *b
 			continue;
 
 		/* Ok, try it out.. */
-		ret = allocate_resource(r, res, size, min, -1, align,
+		ret = allocate_resource(r, res, size,
+					r->start ? : min,
+					-1, align,
 					alignf, alignf_data);
 		if (ret == 0)
 			break;
@@ -121,10 +123,13 @@ void __devinit pci_bus_add_devices(struc
 		 * If there is an unattached subordinate bus, attach
 		 * it and then scan for unattached PCI devices.
 		 */
-		if (dev->subordinate && list_empty(&dev->subordinate->node)) {
-			spin_lock(&pci_bus_lock);
-			list_add_tail(&dev->subordinate->node, &dev->bus->children);
-			spin_unlock(&pci_bus_lock);
+		if (dev->subordinate) {
+		       if (list_empty(&dev->subordinate->node)) {
+			       spin_lock(&pci_bus_lock);
+			       list_add_tail(&dev->subordinate->node,
+					       &dev->bus->children);
+			       spin_unlock(&pci_bus_lock);
+		       }
 			pci_bus_add_devices(dev->subordinate);
 
 			sysfs_create_link(&dev->subordinate->class_dev.kobj, &dev->dev.kobj, "bridge");
diff --git a/drivers/pci/hotplug.c b/drivers/pci/hotplug.c
--- a/drivers/pci/hotplug.c
+++ b/drivers/pci/hotplug.c
@@ -54,7 +54,7 @@ int pci_hotplug (struct device *dev, cha
 
 	envp[i++] = scratch;
 	length += scnprintf (scratch, buffer_size - length,
-			    "MODALIAS=pci:v%08Xd%08Xsv%08Xsd%08Xbc%02Xsc%02Xi%02x\n",
+			    "MODALIAS=pci:v%08Xd%08Xsv%08Xsd%08Xbc%02Xsc%02Xi%02x",
 			    pdev->vendor, pdev->device,
 			    pdev->subsystem_vendor, pdev->subsystem_device,
 			    (u8)(pdev->class >> 16), (u8)(pdev->class >> 8),
diff --git a/drivers/pci/hotplug/Kconfig b/drivers/pci/hotplug/Kconfig
--- a/drivers/pci/hotplug/Kconfig
+++ b/drivers/pci/hotplug/Kconfig
@@ -187,9 +187,10 @@ config HOTPLUG_PCI_RPA_DLPAR
 
 config HOTPLUG_PCI_SGI
 	tristate "SGI PCI Hotplug Support"
-	depends on HOTPLUG_PCI && IA64_SGI_SN2
+	depends on HOTPLUG_PCI && (IA64_SGI_SN2 || IA64_GENERIC)
 	help
-	  Say Y here if you have an SGI IA64 Altix system.
+	  Say Y here if you want to use the SGI Altix Hotplug
+	  Driver for PCI devices.
 
 	  When in doubt, say N.
 
diff --git a/drivers/pci/hotplug/Makefile b/drivers/pci/hotplug/Makefile
--- a/drivers/pci/hotplug/Makefile
+++ b/drivers/pci/hotplug/Makefile
@@ -14,6 +14,7 @@ obj-$(CONFIG_HOTPLUG_PCI_PCIE)		+= pcieh
 obj-$(CONFIG_HOTPLUG_PCI_SHPC)		+= shpchp.o
 obj-$(CONFIG_HOTPLUG_PCI_RPA)		+= rpaphp.o
 obj-$(CONFIG_HOTPLUG_PCI_RPA_DLPAR)	+= rpadlpar_io.o
+obj-$(CONFIG_HOTPLUG_PCI_SGI)		+= sgi_hotplug.o
 
 pci_hotplug-objs	:=	pci_hotplug_core.o
 
@@ -36,9 +37,7 @@ ibmphp-objs		:=	ibmphp_core.o	\
 				ibmphp_hpc.o
 
 acpiphp-objs		:=	acpiphp_core.o	\
-				acpiphp_glue.o	\
-				acpiphp_pci.o	\
-				acpiphp_res.o
+				acpiphp_glue.o
 
 rpaphp-objs		:=	rpaphp_core.o	\
 				rpaphp_pci.o	\
diff --git a/drivers/pci/hotplug/acpiphp.h b/drivers/pci/hotplug/acpiphp.h
--- a/drivers/pci/hotplug/acpiphp.h
+++ b/drivers/pci/hotplug/acpiphp.h
@@ -7,6 +7,8 @@
  * Copyright (C) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
  * Copyright (C) 2002,2003 Takayoshi Kochi (t-kochi@bq.jp.nec.com)
  * Copyright (C) 2002,2003 NEC Corporation
+ * Copyright (C) 2003-2005 Matthew Wilcox (matthew.wilcox@hp.com)
+ * Copyright (C) 2003-2005 Hewlett Packard
  *
  * All rights reserved.
  *
@@ -52,7 +54,6 @@
 
 struct acpiphp_bridge;
 struct acpiphp_slot;
-struct pci_resource;
 
 /*
  * struct slot - slot information for each *physical* slot
@@ -65,15 +66,6 @@ struct slot {
 	struct acpiphp_slot	*acpi_slot;
 };
 
-/*
- * struct pci_resource - describes pci resource (mem, pfmem, io, bus)
- */
-struct pci_resource {
-	struct pci_resource * next;
-	u64 base;
-	u32 length;
-};
-
 /**
  * struct hpp_param - ACPI 2.0 _HPP Hot Plug Parameters
  * @cache_line_size in DWORD
@@ -101,10 +93,6 @@ struct acpiphp_bridge {
 	int type;
 	int nr_slots;
 
-	u8 seg;
-	u8 bus;
-	u8 sub;
-
 	u32 flags;
 
 	/* This bus (host bridge) or Secondary bus (PCI-to-PCI bridge) */
@@ -117,12 +105,6 @@ struct acpiphp_bridge {
 	struct hpp_param hpp;
 
 	spinlock_t res_lock;
-
-	/* available resources on this bus */
-	struct pci_resource *mem_head;
-	struct pci_resource *p_mem_head;
-	struct pci_resource *io_head;
-	struct pci_resource *bus_head;
 };
 
 
@@ -163,12 +145,6 @@ struct acpiphp_func {
 
 	u8		function;	/* pci function# */
 	u32		flags;		/* see below */
-
-	/* resources used for this function */
-	struct pci_resource *mem_head;
-	struct pci_resource *p_mem_head;
-	struct pci_resource *io_head;
-	struct pci_resource *bus_head;
 };
 
 /**
@@ -243,25 +219,6 @@ extern u8 acpiphp_get_latch_status (stru
 extern u8 acpiphp_get_adapter_status (struct acpiphp_slot *slot);
 extern u32 acpiphp_get_address (struct acpiphp_slot *slot);
 
-/* acpiphp_pci.c */
-extern struct pci_dev *acpiphp_allocate_pcidev (struct pci_bus *pbus, int dev, int fn);
-extern int acpiphp_configure_slot (struct acpiphp_slot *slot);
-extern int acpiphp_configure_function (struct acpiphp_func *func);
-extern void acpiphp_unconfigure_function (struct acpiphp_func *func);
-extern int acpiphp_detect_pci_resource (struct acpiphp_bridge *bridge);
-extern int acpiphp_init_func_resource (struct acpiphp_func *func);
-
-/* acpiphp_res.c */
-extern struct pci_resource *acpiphp_get_io_resource (struct pci_resource **head, u32 size);
-extern struct pci_resource *acpiphp_get_resource (struct pci_resource **head, u32 size);
-extern struct pci_resource *acpiphp_get_resource_with_base (struct pci_resource **head, u64 base, u32 size);
-extern int acpiphp_resource_sort_and_combine (struct pci_resource **head);
-extern struct pci_resource *acpiphp_make_resource (u64 base, u32 length);
-extern void acpiphp_move_resource (struct pci_resource **from, struct pci_resource **to);
-extern void acpiphp_free_resource (struct pci_resource **res);
-extern void acpiphp_dump_resource (struct acpiphp_bridge *bridge); /* debug */
-extern void acpiphp_dump_func_resource (struct acpiphp_func *func); /* debug */
-
 /* variables */
 extern int acpiphp_debug;
 
diff --git a/drivers/pci/hotplug/acpiphp_core.c b/drivers/pci/hotplug/acpiphp_core.c
--- a/drivers/pci/hotplug/acpiphp_core.c
+++ b/drivers/pci/hotplug/acpiphp_core.c
@@ -7,6 +7,8 @@
  * Copyright (C) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
  * Copyright (C) 2002,2003 Takayoshi Kochi (t-kochi@bq.jp.nec.com)
  * Copyright (C) 2002,2003 NEC Corporation
+ * Copyright (C) 2003-2005 Matthew Wilcox (matthew.wilcox@hp.com)
+ * Copyright (C) 2003-2005 Hewlett Packard
  *
  * All rights reserved.
  *
@@ -53,8 +55,8 @@ int acpiphp_debug;
 static int num_slots;
 static struct acpiphp_attention_info *attention_info;
 
-#define DRIVER_VERSION	"0.4"
-#define DRIVER_AUTHOR	"Greg Kroah-Hartman <gregkh@us.ibm.com>, Takayoshi Kochi <t-kochi@bq.jp.nec.com>"
+#define DRIVER_VERSION	"0.5"
+#define DRIVER_AUTHOR	"Greg Kroah-Hartman <gregkh@us.ibm.com>, Takayoshi Kochi <t-kochi@bq.jp.nec.com>, Matthew Wilcox <willy@hp.com>"
 #define DRIVER_DESC	"ACPI Hot Plug PCI Controller Driver"
 
 MODULE_AUTHOR(DRIVER_AUTHOR);
@@ -281,8 +283,7 @@ static int get_adapter_status(struct hot
 /**
  * get_address - get pci address of a slot
  * @hotplug_slot: slot to get status
- * @busdev: pointer to struct pci_busdev (seg, bus, dev)
- *
+ * @value: pointer to struct pci_busdev (seg, bus, dev)
  */
 static int get_address(struct hotplug_slot *hotplug_slot, u32 *value)
 {
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -4,6 +4,10 @@
  * Copyright (C) 2002,2003 Takayoshi Kochi (t-kochi@bq.jp.nec.com)
  * Copyright (C) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
  * Copyright (C) 2002,2003 NEC Corporation
+ * Copyright (C) 2003-2005 Matthew Wilcox (matthew.wilcox@hp.com)
+ * Copyright (C) 2003-2005 Hewlett Packard
+ * Copyright (C) 2005 Rajesh Shah (rajesh.shah@intel.com)
+ * Copyright (C) 2005 Intel Corporation
  *
  * All rights reserved.
  *
@@ -26,6 +30,16 @@
  *
  */
 
+/*
+ * Lifetime rules for pci_dev:
+ *  - The one in acpiphp_func has its refcount elevated by pci_get_slot()
+ *    when the driver is loaded or when an insertion event occurs.  It loses
+ *    a refcount when its ejected or the driver unloads.
+ *  - The one in acpiphp_bridge has its refcount elevated by pci_get_slot()
+ *    when the bridge is scanned and it loses a refcount when the bridge
+ *    is removed.
+ */
+
 #include <linux/init.h>
 #include <linux/module.h>
 
@@ -178,21 +192,18 @@ register_slot(acpi_handle handle, u32 lv
 
 		bridge->nr_slots++;
 
-		dbg("found ACPI PCI Hotplug slot at PCI %02x:%02x Slot:%d\n",
-		    slot->bridge->bus, slot->device, slot->sun);
+		dbg("found ACPI PCI Hotplug slot %d at PCI %04x:%02x:%02x\n",
+				slot->sun, pci_domain_nr(bridge->pci_bus),
+				bridge->pci_bus->number, slot->device);
 	}
 
 	newfunc->slot = slot;
 	list_add_tail(&newfunc->sibling, &slot->funcs);
 
 	/* associate corresponding pci_dev */
-	newfunc->pci_dev = pci_find_slot(bridge->bus,
+	newfunc->pci_dev = pci_get_slot(bridge->pci_bus,
 					 PCI_DEVFN(device, function));
 	if (newfunc->pci_dev) {
-		if (acpiphp_init_func_resource(newfunc) < 0) {
-			kfree(newfunc);
-			return AE_ERROR;
-		}
 		slot->flags |= (SLOT_ENABLED | SLOT_POWEREDON);
 	}
 
@@ -227,62 +238,6 @@ static int detect_ejectable_slots(acpi_h
 }
 
 
-/* decode ACPI _CRS data and convert into our internal resource list
- * TBD: _TRA, etc.
- */
-static acpi_status
-decode_acpi_resource(struct acpi_resource *resource, void *context)
-{
-	struct acpiphp_bridge *bridge = (struct acpiphp_bridge *) context;
-	struct acpi_resource_address64 address;
-	struct pci_resource *res;
-
-	if (resource->id != ACPI_RSTYPE_ADDRESS16 &&
-	    resource->id != ACPI_RSTYPE_ADDRESS32 &&
-	    resource->id != ACPI_RSTYPE_ADDRESS64)
-		return AE_OK;
-
-	acpi_resource_to_address64(resource, &address);
-
-	if (address.producer_consumer == ACPI_PRODUCER && address.address_length > 0) {
-		dbg("resource type: %d: 0x%llx - 0x%llx\n", address.resource_type,
-		    (unsigned long long)address.min_address_range,
-		    (unsigned long long)address.max_address_range);
-		res = acpiphp_make_resource(address.min_address_range,
-				    address.address_length);
-		if (!res) {
-			err("out of memory\n");
-			return AE_OK;
-		}
-
-		switch (address.resource_type) {
-		case ACPI_MEMORY_RANGE:
-			if (address.attribute.memory.cache_attribute == ACPI_PREFETCHABLE_MEMORY) {
-				res->next = bridge->p_mem_head;
-				bridge->p_mem_head = res;
-			} else {
-				res->next = bridge->mem_head;
-				bridge->mem_head = res;
-			}
-			break;
-		case ACPI_IO_RANGE:
-			res->next = bridge->io_head;
-			bridge->io_head = res;
-			break;
-		case ACPI_BUS_NUMBER_RANGE:
-			res->next = bridge->bus_head;
-			bridge->bus_head = res;
-			break;
-		default:
-			/* invalid type */
-			kfree(res);
-			break;
-		}
-	}
-
-	return AE_OK;
-}
-
 /* decode ACPI 2.0 _HPP hot plug parameters */
 static void decode_hpp(struct acpiphp_bridge *bridge)
 {
@@ -346,34 +301,29 @@ static void init_bridge_misc(struct acpi
 	/* decode ACPI 2.0 _HPP (hot plug parameters) */
 	decode_hpp(bridge);
 
-	/* subtract all resources already allocated */
-	acpiphp_detect_pci_resource(bridge);
-
 	/* register all slot objects under this bridge */
 	status = acpi_walk_namespace(ACPI_TYPE_DEVICE, bridge->handle, (u32)1,
 				     register_slot, bridge, NULL);
 
 	/* install notify handler */
-	status = acpi_install_notify_handler(bridge->handle,
+	if (bridge->type != BRIDGE_TYPE_HOST) {
+		status = acpi_install_notify_handler(bridge->handle,
 					     ACPI_SYSTEM_NOTIFY,
 					     handle_hotplug_event_bridge,
 					     bridge);
 
-	if (ACPI_FAILURE(status)) {
-		err("failed to register interrupt notify handler\n");
+		if (ACPI_FAILURE(status)) {
+			err("failed to register interrupt notify handler\n");
+		}
 	}
 
 	list_add(&bridge->list, &bridge_list);
-
-	dbg("Bridge resource:\n");
-	acpiphp_dump_resource(bridge);
 }
 
 
 /* allocate and initialize host bridge data structure */
-static void add_host_bridge(acpi_handle *handle, int seg, int bus)
+static void add_host_bridge(acpi_handle *handle, struct pci_bus *pci_bus)
 {
-	acpi_status status;
 	struct acpiphp_bridge *bridge;
 
 	bridge = kmalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL);
@@ -384,52 +334,19 @@ static void add_host_bridge(acpi_handle 
 
 	bridge->type = BRIDGE_TYPE_HOST;
 	bridge->handle = handle;
-	bridge->seg = seg;
-	bridge->bus = bus;
 
-	bridge->pci_bus = pci_find_bus(seg, bus);
+	bridge->pci_bus = pci_bus;
 
 	spin_lock_init(&bridge->res_lock);
 
-	/* to be overridden when we decode _CRS	*/
-	bridge->sub = bridge->bus;
-
-	/* decode resources */
-
-	status = acpi_walk_resources(handle, METHOD_NAME__CRS,
-		decode_acpi_resource, bridge);
-
-	if (ACPI_FAILURE(status)) {
-		err("failed to decode bridge resources\n");
-		kfree(bridge);
-		return;
-	}
-
-	acpiphp_resource_sort_and_combine(&bridge->io_head);
-	acpiphp_resource_sort_and_combine(&bridge->mem_head);
-	acpiphp_resource_sort_and_combine(&bridge->p_mem_head);
-	acpiphp_resource_sort_and_combine(&bridge->bus_head);
-
-	dbg("ACPI _CRS resource:\n");
-	acpiphp_dump_resource(bridge);
-
-	if (bridge->bus_head) {
-		bridge->bus = bridge->bus_head->base;
-		bridge->sub = bridge->bus_head->base + bridge->bus_head->length - 1;
-	}
-
 	init_bridge_misc(bridge);
 }
 
 
 /* allocate and initialize PCI-to-PCI bridge data structure */
-static void add_p2p_bridge(acpi_handle *handle, int seg, int bus, int dev, int fn)
+static void add_p2p_bridge(acpi_handle *handle, struct pci_dev *pci_dev)
 {
 	struct acpiphp_bridge *bridge;
-	u8 tmp8;
-	u16 tmp16;
-	u64 base64, limit64;
-	u32 base, limit, base32u, limit32u;
 
 	bridge = kmalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL);
 	if (bridge == NULL) {
@@ -441,133 +358,22 @@ static void add_p2p_bridge(acpi_handle *
 
 	bridge->type = BRIDGE_TYPE_P2P;
 	bridge->handle = handle;
-	bridge->seg = seg;
-
-	bridge->pci_dev = pci_find_slot(bus, PCI_DEVFN(dev, fn));
-	if (!bridge->pci_dev) {
-		err("Can't get pci_dev\n");
-		kfree(bridge);
-		return;
-	}
 
-	bridge->pci_bus = bridge->pci_dev->subordinate;
+	bridge->pci_dev = pci_dev_get(pci_dev);
+	bridge->pci_bus = pci_dev->subordinate;
 	if (!bridge->pci_bus) {
 		err("This is not a PCI-to-PCI bridge!\n");
-		kfree(bridge);
-		return;
+		goto err;
 	}
 
 	spin_lock_init(&bridge->res_lock);
 
-	bridge->bus = bridge->pci_bus->number;
-	bridge->sub = bridge->pci_bus->subordinate;
-
-	/*
-	 * decode resources under this P2P bridge
-	 */
-
-	/* I/O resources */
-	pci_read_config_byte(bridge->pci_dev, PCI_IO_BASE, &tmp8);
-	base = tmp8;
-	pci_read_config_byte(bridge->pci_dev, PCI_IO_LIMIT, &tmp8);
-	limit = tmp8;
-
-	switch (base & PCI_IO_RANGE_TYPE_MASK) {
-	case PCI_IO_RANGE_TYPE_16:
-		base = (base << 8) & 0xf000;
-		limit = ((limit << 8) & 0xf000) + 0xfff;
-		bridge->io_head = acpiphp_make_resource((u64)base, limit - base + 1);
-		if (!bridge->io_head) {
-			err("out of memory\n");
-			kfree(bridge);
-			return;
-		}
-		dbg("16bit I/O range: %04x-%04x\n",
-		    (u32)bridge->io_head->base,
-		    (u32)(bridge->io_head->base + bridge->io_head->length - 1));
-		break;
-	case PCI_IO_RANGE_TYPE_32:
-		pci_read_config_word(bridge->pci_dev, PCI_IO_BASE_UPPER16, &tmp16);
-		base = ((u32)tmp16 << 16) | ((base << 8) & 0xf000);
-		pci_read_config_word(bridge->pci_dev, PCI_IO_LIMIT_UPPER16, &tmp16);
-		limit = (((u32)tmp16 << 16) | ((limit << 8) & 0xf000)) + 0xfff;
-		bridge->io_head = acpiphp_make_resource((u64)base, limit - base + 1);
-		if (!bridge->io_head) {
-			err("out of memory\n");
-			kfree(bridge);
-			return;
-		}
-		dbg("32bit I/O range: %08x-%08x\n",
-		    (u32)bridge->io_head->base,
-		    (u32)(bridge->io_head->base + bridge->io_head->length - 1));
-		break;
-	case 0x0f:
-		dbg("I/O space unsupported\n");
-		break;
-	default:
-		warn("Unknown I/O range type\n");
-	}
-
-	/* Memory resources (mandatory for P2P bridge) */
-	pci_read_config_word(bridge->pci_dev, PCI_MEMORY_BASE, &tmp16);
-	base = (tmp16 & 0xfff0) << 16;
-	pci_read_config_word(bridge->pci_dev, PCI_MEMORY_LIMIT, &tmp16);
-	limit = ((tmp16 & 0xfff0) << 16) | 0xfffff;
-	bridge->mem_head = acpiphp_make_resource((u64)base, limit - base + 1);
-	if (!bridge->mem_head) {
-		err("out of memory\n");
-		kfree(bridge);
-		return;
-	}
-	dbg("32bit Memory range: %08x-%08x\n",
-	    (u32)bridge->mem_head->base,
-	    (u32)(bridge->mem_head->base + bridge->mem_head->length-1));
-
-	/* Prefetchable Memory resources (optional) */
-	pci_read_config_word(bridge->pci_dev, PCI_PREF_MEMORY_BASE, &tmp16);
-	base = tmp16;
-	pci_read_config_word(bridge->pci_dev, PCI_PREF_MEMORY_LIMIT, &tmp16);
-	limit = tmp16;
-
-	switch (base & PCI_MEMORY_RANGE_TYPE_MASK) {
-	case PCI_PREF_RANGE_TYPE_32:
-		base = (base & 0xfff0) << 16;
-		limit = ((limit & 0xfff0) << 16) | 0xfffff;
-		bridge->p_mem_head = acpiphp_make_resource((u64)base, limit - base + 1);
-		if (!bridge->p_mem_head) {
-			err("out of memory\n");
-			kfree(bridge);
-			return;
-		}
-		dbg("32bit Prefetchable memory range: %08x-%08x\n",
-		    (u32)bridge->p_mem_head->base,
-		    (u32)(bridge->p_mem_head->base + bridge->p_mem_head->length - 1));
-		break;
-	case PCI_PREF_RANGE_TYPE_64:
-		pci_read_config_dword(bridge->pci_dev, PCI_PREF_BASE_UPPER32, &base32u);
-		pci_read_config_dword(bridge->pci_dev, PCI_PREF_LIMIT_UPPER32, &limit32u);
-		base64 = ((u64)base32u << 32) | ((base & 0xfff0) << 16);
-		limit64 = (((u64)limit32u << 32) | ((limit & 0xfff0) << 16)) + 0xfffff;
-
-		bridge->p_mem_head = acpiphp_make_resource(base64, limit64 - base64 + 1);
-		if (!bridge->p_mem_head) {
-			err("out of memory\n");
-			kfree(bridge);
-			return;
-		}
-		dbg("64bit Prefetchable memory range: %08x%08x-%08x%08x\n",
-		    (u32)(bridge->p_mem_head->base >> 32),
-		    (u32)(bridge->p_mem_head->base & 0xffffffff),
-		    (u32)((bridge->p_mem_head->base + bridge->p_mem_head->length - 1) >> 32),
-		    (u32)((bridge->p_mem_head->base + bridge->p_mem_head->length - 1) & 0xffffffff));
-		break;
-	case 0x0f:
-		break;
-	default:
-		warn("Unknown prefetchale memory type\n");
-	}
-
 	init_bridge_misc(bridge);
+	return;
+ err:
+	pci_dev_put(pci_dev);
+	kfree(bridge);
+	return;
 }
 
 
@@ -577,14 +383,10 @@ find_p2p_bridge(acpi_handle handle, u32 
 {
 	acpi_status status;
 	acpi_handle dummy_handle;
-	unsigned long *segbus = context;
 	unsigned long tmp;
-	int seg, bus, device, function;
+	int device, function;
 	struct pci_dev *dev;
-
-	/* get PCI address */
-	seg = (*segbus >> 8) & 0xff;
-	bus = *segbus & 0xff;
+	struct pci_bus *pci_bus = context;
 
 	status = acpi_get_handle(handle, "_ADR", &dummy_handle);
 	if (ACPI_FAILURE(status))
@@ -599,20 +401,19 @@ find_p2p_bridge(acpi_handle handle, u32 
 	device = (tmp >> 16) & 0xffff;
 	function = tmp & 0xffff;
 
-	dev = pci_find_slot(bus, PCI_DEVFN(device, function));
+	dev = pci_get_slot(pci_bus, PCI_DEVFN(device, function));
 
-	if (!dev)
-		return AE_OK;
-
-	if (!dev->subordinate)
-		return AE_OK;
+	if (!dev || !dev->subordinate)
+		goto out;
 
 	/* check if this bridge has ejectable slots */
 	if (detect_ejectable_slots(handle) > 0) {
 		dbg("found PCI-to-PCI bridge at PCI %s\n", pci_name(dev));
-		add_p2p_bridge(handle, seg, bus, device, function);
+		add_p2p_bridge(handle, dev);
 	}
 
+ out:
+	pci_dev_put(dev);
 	return AE_OK;
 }
 
@@ -624,6 +425,7 @@ static int add_bridge(acpi_handle handle
 	unsigned long tmp;
 	int seg, bus;
 	acpi_handle dummy_handle;
+	struct pci_bus *pci_bus;
 
 	/* if the bridge doesn't have _STA, we assume it is always there */
 	status = acpi_get_handle(handle, "_STA", &dummy_handle);
@@ -653,18 +455,22 @@ static int add_bridge(acpi_handle handle
 		bus = 0;
 	}
 
+	pci_bus = pci_find_bus(seg, bus);
+	if (!pci_bus) {
+		err("Can't find bus %04x:%02x\n", seg, bus);
+		return 0;
+	}
+
 	/* check if this bridge has ejectable slots */
 	if (detect_ejectable_slots(handle) > 0) {
 		dbg("found PCI host-bus bridge with hot-pluggable slots\n");
-		add_host_bridge(handle, seg, bus);
+		add_host_bridge(handle, pci_bus);
 		return 0;
 	}
 
-	tmp = seg << 8 | bus;
-
 	/* search P2P bridges under this host bridge */
 	status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1,
-				     find_p2p_bridge, &tmp, NULL);
+				     find_p2p_bridge, pci_bus, NULL);
 
 	if (ACPI_FAILURE(status))
 		warn("find_p2p_bridge faied (error code = 0x%x)\n",status);
@@ -672,12 +478,205 @@ static int add_bridge(acpi_handle handle
 	return 0;
 }
 
+static struct acpiphp_bridge *acpiphp_handle_to_bridge(acpi_handle handle)
+{
+	struct list_head *head;
+	list_for_each(head, &bridge_list) {
+		struct acpiphp_bridge *bridge = list_entry(head,
+						struct acpiphp_bridge, list);
+		if (bridge->handle == handle)
+			return bridge;
+	}
+
+	return NULL;
+}
+
+static void cleanup_bridge(struct acpiphp_bridge *bridge)
+{
+	struct list_head *list, *tmp;
+	struct acpiphp_slot *slot;
+	acpi_status status;
+	acpi_handle handle = bridge->handle;
+
+	status = acpi_remove_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
+					    handle_hotplug_event_bridge);
+	if (ACPI_FAILURE(status))
+		err("failed to remove notify handler\n");
+
+	slot = bridge->slots;
+	while (slot) {
+		struct acpiphp_slot *next = slot->next;
+		list_for_each_safe (list, tmp, &slot->funcs) {
+			struct acpiphp_func *func;
+			func = list_entry(list, struct acpiphp_func, sibling);
+			status = acpi_remove_notify_handler(func->handle,
+						ACPI_SYSTEM_NOTIFY,
+						handle_hotplug_event_func);
+			if (ACPI_FAILURE(status))
+				err("failed to remove notify handler\n");
+			pci_dev_put(func->pci_dev);
+			list_del(list);
+			kfree(func);
+		}
+		kfree(slot);
+		slot = next;
+	}
+
+	pci_dev_put(bridge->pci_dev);
+	list_del(&bridge->list);
+	kfree(bridge);
+}
+
+static acpi_status
+cleanup_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv)
+{
+	struct acpiphp_bridge *bridge;
+
+	if (!(bridge = acpiphp_handle_to_bridge(handle)))
+		return AE_OK;
+	cleanup_bridge(bridge);
+	return AE_OK;
+}
 
 static void remove_bridge(acpi_handle handle)
 {
-	/* No-op for now .. */
+	struct acpiphp_bridge *bridge;
+
+	bridge = acpiphp_handle_to_bridge(handle);
+	if (bridge) {
+		cleanup_bridge(bridge);
+	} else {
+		/* clean-up p2p bridges under this host bridge */
+		acpi_walk_namespace(ACPI_TYPE_DEVICE, handle,
+				(u32)1, cleanup_p2p_bridge, NULL, NULL);
+	}
+}
+
+static struct pci_dev * get_apic_pci_info(acpi_handle handle)
+{
+	struct acpi_pci_id id;
+	struct pci_bus *bus;
+	struct pci_dev *dev;
+
+	if (ACPI_FAILURE(acpi_get_pci_id(handle, &id)))
+		return NULL;
+
+	bus = pci_find_bus(id.segment, id.bus);
+	if (!bus)
+		return NULL;
+
+	dev = pci_get_slot(bus, PCI_DEVFN(id.device, id.function));
+	if (!dev)
+		return NULL;
+
+	if ((dev->class != PCI_CLASS_SYSTEM_PIC_IOAPIC) &&
+	    (dev->class != PCI_CLASS_SYSTEM_PIC_IOXAPIC))
+	{
+		pci_dev_put(dev);
+		return NULL;
+	}
+
+	return dev;
+}
+
+static int get_gsi_base(acpi_handle handle, u32 *gsi_base)
+{
+	acpi_status status;
+	int result = -1;
+	unsigned long gsb;
+	struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
+	union acpi_object *obj;
+	void *table;
+
+	status = acpi_evaluate_integer(handle, "_GSB", NULL, &gsb);
+	if (ACPI_SUCCESS(status)) {
+		*gsi_base = (u32)gsb;
+		return 0;
+	}
+
+	status = acpi_evaluate_object(handle, "_MAT", NULL, &buffer);
+	if (ACPI_FAILURE(status) || !buffer.length || !buffer.pointer)
+		return -1;
+
+	obj = buffer.pointer;
+	if (obj->type != ACPI_TYPE_BUFFER)
+		goto out;
+
+	table = obj->buffer.pointer;
+	switch (((acpi_table_entry_header *)table)->type) {
+	case ACPI_MADT_IOSAPIC:
+		*gsi_base = ((struct acpi_table_iosapic *)table)->global_irq_base;
+		result = 0;
+		break;
+	case ACPI_MADT_IOAPIC:
+		*gsi_base = ((struct acpi_table_ioapic *)table)->global_irq_base;
+		result = 0;
+		break;
+	default:
+		break;
+	}
+ out:
+	acpi_os_free(buffer.pointer);
+	return result;
+}
+
+static acpi_status
+ioapic_add(acpi_handle handle, u32 lvl, void *context, void **rv)
+{
+	acpi_status status;
+	unsigned long sta;
+	acpi_handle tmp;
+	struct pci_dev *pdev;
+	u32 gsi_base;
+	u64 phys_addr;
+
+	/* Evaluate _STA if present */
+	status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);
+	if (ACPI_SUCCESS(status) && sta != ACPI_STA_ALL)
+		return AE_CTRL_DEPTH;
+
+	/* Scan only PCI bus scope */
+	status = acpi_get_handle(handle, "_HID", &tmp);
+	if (ACPI_SUCCESS(status))
+		return AE_CTRL_DEPTH;
+
+	if (get_gsi_base(handle, &gsi_base))
+		return AE_OK;
+
+	pdev = get_apic_pci_info(handle);
+	if (!pdev)
+		return AE_OK;
+
+	if (pci_enable_device(pdev)) {
+		pci_dev_put(pdev);
+		return AE_OK;
+	}
+
+	pci_set_master(pdev);
+
+	if (pci_request_region(pdev, 0, "I/O APIC(acpiphp)")) {
+		pci_disable_device(pdev);
+		pci_dev_put(pdev);
+		return AE_OK;
+	}
+
+	phys_addr = pci_resource_start(pdev, 0);
+	if (acpi_register_ioapic(handle, phys_addr, gsi_base)) {
+		pci_release_region(pdev, 0);
+		pci_disable_device(pdev);
+		pci_dev_put(pdev);
+		return AE_OK;
+	}
+
+	return AE_OK;
 }
 
+static int acpiphp_configure_ioapics(acpi_handle handle)
+{
+	acpi_walk_namespace(ACPI_TYPE_DEVICE, handle,
+			    ACPI_UINT32_MAX, ioapic_add, NULL, NULL);
+	return 0;
+}
 
 static int power_on_slot(struct acpiphp_slot *slot)
 {
@@ -719,8 +718,6 @@ static int power_off_slot(struct acpiphp
 	acpi_status status;
 	struct acpiphp_func *func;
 	struct list_head *l;
-	struct acpi_object_list arg_list;
-	union acpi_object arg;
 
 	int retval = 0;
 
@@ -731,7 +728,7 @@ static int power_off_slot(struct acpiphp
 	list_for_each (l, &slot->funcs) {
 		func = list_entry(l, struct acpiphp_func, sibling);
 
-		if (func->pci_dev && (func->flags & FUNC_HAS_PS3)) {
+		if (func->flags & FUNC_HAS_PS3) {
 			status = acpi_evaluate_object(func->handle, "_PS3", NULL, NULL);
 			if (ACPI_FAILURE(status)) {
 				warn("%s: _PS3 failed\n", __FUNCTION__);
@@ -742,27 +739,6 @@ static int power_off_slot(struct acpiphp
 		}
 	}
 
-	list_for_each (l, &slot->funcs) {
-		func = list_entry(l, struct acpiphp_func, sibling);
-
-		/* We don't want to call _EJ0 on non-existing functions. */
-		if (func->pci_dev && (func->flags & FUNC_HAS_EJ0)) {
-			/* _EJ0 method take one argument */
-			arg_list.count = 1;
-			arg_list.pointer = &arg;
-			arg.type = ACPI_TYPE_INTEGER;
-			arg.integer.value = 1;
-
-			status = acpi_evaluate_object(func->handle, "_EJ0", &arg_list, NULL);
-			if (ACPI_FAILURE(status)) {
-				warn("%s: _EJ0 failed\n", __FUNCTION__);
-				retval = -1;
-				goto err_exit;
-			} else
-				break;
-		}
-	}
-
 	/* TBD: evaluate _STA to check if the slot is disabled */
 
 	slot->flags &= (~SLOT_POWEREDON);
@@ -782,70 +758,56 @@ static int power_off_slot(struct acpiphp
  */
 static int enable_device(struct acpiphp_slot *slot)
 {
-	u8 bus;
 	struct pci_dev *dev;
-	struct pci_bus *child;
+	struct pci_bus *bus = slot->bridge->pci_bus;
 	struct list_head *l;
 	struct acpiphp_func *func;
 	int retval = 0;
-	int num;
+	int num, max, pass;
 
 	if (slot->flags & SLOT_ENABLED)
 		goto err_exit;
 
 	/* sanity check: dev should be NULL when hot-plugged in */
-	dev = pci_find_slot(slot->bridge->bus, PCI_DEVFN(slot->device, 0));
+	dev = pci_get_slot(bus, PCI_DEVFN(slot->device, 0));
 	if (dev) {
 		/* This case shouldn't happen */
 		err("pci_dev structure already exists.\n");
+		pci_dev_put(dev);
 		retval = -1;
 		goto err_exit;
 	}
 
-	/* allocate resources to device */
-	retval = acpiphp_configure_slot(slot);
-	if (retval)
-		goto err_exit;
-
-	/* returned `dev' is the *first function* only! */
-	num = pci_scan_slot(slot->bridge->pci_bus, PCI_DEVFN(slot->device, 0));
-	if (num)
-		pci_bus_add_devices(slot->bridge->pci_bus);
-	dev = pci_find_slot(slot->bridge->bus, PCI_DEVFN(slot->device, 0));
-
-	if (!dev) {
+	num = pci_scan_slot(bus, PCI_DEVFN(slot->device, 0));
+	if (num == 0) {
 		err("No new device found\n");
 		retval = -1;
 		goto err_exit;
 	}
 
-	if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
-		pci_read_config_byte(dev, PCI_SECONDARY_BUS, &bus);
-		child = (struct pci_bus*) pci_add_new_bus(dev->bus, dev, bus);
-		pci_do_scan_bus(child);
+	max = bus->secondary;
+	for (pass = 0; pass < 2; pass++) {
+		list_for_each_entry(dev, &bus->devices, bus_list) {
+			if (PCI_SLOT(dev->devfn) != slot->device)
+				continue;
+			if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
+			    dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)
+				max = pci_scan_bridge(bus, dev, max, pass);
+		}
 	}
 
+	pci_bus_assign_resources(bus);
+	pci_bus_add_devices(bus);
+
 	/* associate pci_dev to our representation */
 	list_for_each (l, &slot->funcs) {
 		func = list_entry(l, struct acpiphp_func, sibling);
-
-		func->pci_dev = pci_find_slot(slot->bridge->bus,
-					      PCI_DEVFN(slot->device,
+		func->pci_dev = pci_get_slot(bus, PCI_DEVFN(slot->device,
 							func->function));
-		if (!func->pci_dev)
-			continue;
-
-		/* configure device */
-		retval = acpiphp_configure_function(func);
-		if (retval)
-			goto err_exit;
 	}
 
 	slot->flags |= SLOT_ENABLED;
 
-	dbg("Available resources:\n");
-	acpiphp_dump_resource(slot->bridge);
-
  err_exit:
 	return retval;
 }
@@ -866,9 +828,12 @@ static int disable_device(struct acpiphp
 
 	list_for_each (l, &slot->funcs) {
 		func = list_entry(l, struct acpiphp_func, sibling);
+		if (!func->pci_dev)
+			continue;
 
-		if (func->pci_dev)
-			acpiphp_unconfigure_function(func);
+		pci_remove_bus_device(func->pci_dev);
+		pci_dev_put(func->pci_dev);
+		func->pci_dev = NULL;
 	}
 
 	slot->flags &= (~SLOT_ENABLED);
@@ -920,6 +885,39 @@ static unsigned int get_slot_status(stru
 }
 
 /**
+ * acpiphp_eject_slot - physically eject the slot
+ */
+static int acpiphp_eject_slot(struct acpiphp_slot *slot)
+{
+	acpi_status status;
+	struct acpiphp_func *func;
+	struct list_head *l;
+	struct acpi_object_list arg_list;
+	union acpi_object arg;
+
+	list_for_each (l, &slot->funcs) {
+		func = list_entry(l, struct acpiphp_func, sibling);
+
+		/* We don't want to call _EJ0 on non-existing functions. */
+		if ((func->flags & FUNC_HAS_EJ0)) {
+			/* _EJ0 method take one argument */
+			arg_list.count = 1;
+			arg_list.pointer = &arg;
+			arg.type = ACPI_TYPE_INTEGER;
+			arg.integer.value = 1;
+
+			status = acpi_evaluate_object(func->handle, "_EJ0", &arg_list, NULL);
+			if (ACPI_FAILURE(status)) {
+				warn("%s: _EJ0 failed\n", __FUNCTION__);
+				return -1;
+			} else
+				break;
+		}
+	}
+	return 0;
+}
+
+/**
  * acpiphp_check_bridge - re-enumerate devices
  *
  * Iterate over all slots under this bridge and make sure that if a
@@ -942,6 +940,8 @@ static int acpiphp_check_bridge(struct a
 			if (retval) {
 				err("Error occurred in disabling\n");
 				goto err_exit;
+			} else {
+				acpiphp_eject_slot(slot);
 			}
 			disabled++;
 		} else {
@@ -962,6 +962,144 @@ static int acpiphp_check_bridge(struct a
 	return retval;
 }
 
+static void program_hpp(struct pci_dev *dev, struct acpiphp_bridge *bridge)
+{
+	u16 pci_cmd, pci_bctl;
+	struct pci_dev *cdev;
+
+	/* Program hpp values for this device */
+	if (!(dev->hdr_type == PCI_HEADER_TYPE_NORMAL ||
+			(dev->hdr_type == PCI_HEADER_TYPE_BRIDGE &&
+			(dev->class >> 8) == PCI_CLASS_BRIDGE_PCI)))
+		return;
+	pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE,
+			bridge->hpp.cache_line_size);
+	pci_write_config_byte(dev, PCI_LATENCY_TIMER,
+			bridge->hpp.latency_timer);
+	pci_read_config_word(dev, PCI_COMMAND, &pci_cmd);
+	if (bridge->hpp.enable_SERR)
+		pci_cmd |= PCI_COMMAND_SERR;
+	else
+		pci_cmd &= ~PCI_COMMAND_SERR;
+	if (bridge->hpp.enable_PERR)
+		pci_cmd |= PCI_COMMAND_PARITY;
+	else
+		pci_cmd &= ~PCI_COMMAND_PARITY;
+	pci_write_config_word(dev, PCI_COMMAND, pci_cmd);
+
+	/* Program bridge control value and child devices */
+	if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
+		pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER,
+				bridge->hpp.latency_timer);
+		pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &pci_bctl);
+		if (bridge->hpp.enable_SERR)
+			pci_bctl |= PCI_BRIDGE_CTL_SERR;
+		else
+			pci_bctl &= ~PCI_BRIDGE_CTL_SERR;
+		if (bridge->hpp.enable_PERR)
+			pci_bctl |= PCI_BRIDGE_CTL_PARITY;
+		else
+			pci_bctl &= ~PCI_BRIDGE_CTL_PARITY;
+		pci_write_config_word(dev, PCI_BRIDGE_CONTROL, pci_bctl);
+		if (dev->subordinate) {
+			list_for_each_entry(cdev, &dev->subordinate->devices,
+					bus_list)
+				program_hpp(cdev, bridge);
+		}
+	}
+}
+
+static void acpiphp_set_hpp_values(acpi_handle handle, struct pci_bus *bus)
+{
+	struct acpiphp_bridge bridge;
+	struct pci_dev *dev;
+
+	memset(&bridge, 0, sizeof(bridge));
+	bridge.handle = handle;
+	decode_hpp(&bridge);
+	list_for_each_entry(dev, &bus->devices, bus_list)
+		program_hpp(dev, &bridge);
+
+}
+
+/*
+ * Remove devices for which we could not assign resources, call
+ * arch specific code to fix-up the bus
+ */
+static void acpiphp_sanitize_bus(struct pci_bus *bus)
+{
+	struct pci_dev *dev;
+	int i;
+	unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM;
+
+	list_for_each_entry(dev, &bus->devices, bus_list) {
+		for (i=0; i<PCI_BRIDGE_RESOURCES; i++) {
+			struct resource *res = &dev->resource[i];
+			if ((res->flags & type_mask) && !res->start &&
+					res->end) {
+				/* Could not assign a required resources
+				 * for this device, remove it */
+				pci_remove_bus_device(dev);
+				break;
+			}
+		}
+	}
+}
+
+/* Program resources in newly inserted bridge */
+static int acpiphp_configure_bridge (acpi_handle handle)
+{
+	struct acpi_pci_id pci_id;
+	struct pci_bus *bus;
+
+	if (ACPI_FAILURE(acpi_get_pci_id(handle, &pci_id))) {
+		err("cannot get PCI domain and bus number for bridge\n");
+		return -EINVAL;
+	}
+	bus = pci_find_bus(pci_id.segment, pci_id.bus);
+	if (!bus) {
+		err("cannot find bus %d:%d\n",
+				pci_id.segment, pci_id.bus);
+		return -EINVAL;
+	}
+
+	pci_bus_size_bridges(bus);
+	pci_bus_assign_resources(bus);
+	acpiphp_sanitize_bus(bus);
+	acpiphp_set_hpp_values(handle, bus);
+	pci_enable_bridges(bus);
+	acpiphp_configure_ioapics(handle);
+	return 0;
+}
+
+static void handle_bridge_insertion(acpi_handle handle, u32 type)
+{
+	struct acpi_device *device, *pdevice;
+	acpi_handle phandle;
+
+	if ((type != ACPI_NOTIFY_BUS_CHECK) &&
+			(type != ACPI_NOTIFY_DEVICE_CHECK)) {
+		err("unexpected notification type %d\n", type);
+		return;
+	}
+
+	acpi_get_parent(handle, &phandle);
+	if (acpi_bus_get_device(phandle, &pdevice)) {
+		dbg("no parent device, assuming NULL\n");
+		pdevice = NULL;
+	}
+	if (acpi_bus_add(&device, pdevice, handle, ACPI_BUS_TYPE_DEVICE)) {
+		err("cannot add bridge to acpi list\n");
+		return;
+	}
+	if (!acpiphp_configure_bridge(handle) &&
+		!acpi_bus_start(device))
+		add_bridge(handle);
+	else
+		err("cannot configure and start bridge\n");
+
+}
+
 /*
  * ACPI event handlers
  */
@@ -982,8 +1120,19 @@ static void handle_hotplug_event_bridge(
 	char objname[64];
 	struct acpi_buffer buffer = { .length = sizeof(objname),
 				      .pointer = objname };
+	struct acpi_device *device;
+
+	if (acpi_bus_get_device(handle, &device)) {
+		/* This bridge must have just been physically inserted */
+		handle_bridge_insertion(handle, type);
+		return;
+	}
 
-	bridge = (struct acpiphp_bridge *)context;
+	bridge = acpiphp_handle_to_bridge(handle);
+	if (!bridge) {
+		err("cannot get bridge info\n");
+		return;
+	}
 
 	acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
 
@@ -1031,7 +1180,6 @@ static void handle_hotplug_event_bridge(
 	}
 }
 
-
 /**
  * handle_hotplug_event_func - handle ACPI event on functions (i.e. slots)
  *
@@ -1074,7 +1222,8 @@ static void handle_hotplug_event_func(ac
 	case ACPI_NOTIFY_EJECT_REQUEST:
 		/* request device eject */
 		dbg("%s: Device eject notify on %s\n", __FUNCTION__, objname);
-		acpiphp_disable_slot(func->slot);
+		if (!(acpiphp_disable_slot(func->slot)))
+			acpiphp_eject_slot(func->slot);
 		break;
 
 	default:
@@ -1083,6 +1232,47 @@ static void handle_hotplug_event_func(ac
 	}
 }
 
+static int is_root_bridge(acpi_handle handle)
+{
+	acpi_status status;
+	struct acpi_device_info *info;
+	struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
+	int i;
+
+	status = acpi_get_object_info(handle, &buffer);
+	if (ACPI_SUCCESS(status)) {
+		info = buffer.pointer;
+		if ((info->valid & ACPI_VALID_HID) &&
+			!strcmp(PCI_ROOT_HID_STRING,
+					info->hardware_id.value)) {
+			acpi_os_free(buffer.pointer);
+			return 1;
+		}
+		if (info->valid & ACPI_VALID_CID) {
+			for (i=0; i < info->compatibility_id.count; i++) {
+				if (!strcmp(PCI_ROOT_HID_STRING,
+					info->compatibility_id.id[i].value)) {
+					acpi_os_free(buffer.pointer);
+					return 1;
+				}
+			}
+		}
+	}
+	return 0;
+}
+
+static acpi_status
+find_root_bridges(acpi_handle handle, u32 lvl, void *context, void **rv)
+{
+	int *count = (int *)context;
+
+	if (is_root_bridge(handle)) {
+		acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
+				handle_hotplug_event_bridge, NULL);
+			(*count)++;
+	}
+	return AE_OK ;
+}
 
 static struct acpi_pci_driver acpi_pci_hp_driver = {
 	.add =		add_bridge,
@@ -1095,15 +1285,15 @@ static struct acpi_pci_driver acpi_pci_h
  */
 int __init acpiphp_glue_init(void)
 {
-	int num;
+	int num = 0;
 
-	if (list_empty(&pci_root_buses))
-		return -1;
-
-	num = acpi_pci_register_driver(&acpi_pci_hp_driver);
+	acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
+			ACPI_UINT32_MAX, find_root_bridges, &num, NULL);
 
 	if (num <= 0)
 		return -1;
+	else
+		acpi_pci_register_driver(&acpi_pci_hp_driver);
 
 	return 0;
 }
@@ -1116,46 +1306,6 @@ int __init acpiphp_glue_init(void)
  */
 void __exit acpiphp_glue_exit(void)
 {
-	struct list_head *l1, *l2, *n1, *n2;
-	struct acpiphp_bridge *bridge;
-	struct acpiphp_slot *slot, *next;
-	struct acpiphp_func *func;
-	acpi_status status;
-
-	list_for_each_safe (l1, n1, &bridge_list) {
-		bridge = (struct acpiphp_bridge *)l1;
-		slot = bridge->slots;
-		while (slot) {
-			next = slot->next;
-			list_for_each_safe (l2, n2, &slot->funcs) {
-				func = list_entry(l2, struct acpiphp_func, sibling);
-				acpiphp_free_resource(&func->io_head);
-				acpiphp_free_resource(&func->mem_head);
-				acpiphp_free_resource(&func->p_mem_head);
-				acpiphp_free_resource(&func->bus_head);
-				status = acpi_remove_notify_handler(func->handle,
-								    ACPI_SYSTEM_NOTIFY,
-								    handle_hotplug_event_func);
-				if (ACPI_FAILURE(status))
-					err("failed to remove notify handler\n");
-				kfree(func);
-			}
-			kfree(slot);
-			slot = next;
-		}
-		status = acpi_remove_notify_handler(bridge->handle, ACPI_SYSTEM_NOTIFY,
-						    handle_hotplug_event_bridge);
-		if (ACPI_FAILURE(status))
-			err("failed to remove notify handler\n");
-
-		acpiphp_free_resource(&bridge->io_head);
-		acpiphp_free_resource(&bridge->mem_head);
-		acpiphp_free_resource(&bridge->p_mem_head);
-		acpiphp_free_resource(&bridge->bus_head);
-
-		kfree(bridge);
-	}
-
 	acpi_pci_unregister_driver(&acpi_pci_hp_driver);
 }
 
@@ -1173,11 +1323,14 @@ int __init acpiphp_get_num_slots(void)
 
 	list_for_each (node, &bridge_list) {
 		bridge = (struct acpiphp_bridge *)node;
-		dbg("Bus%d %dslot(s)\n", bridge->bus, bridge->nr_slots);
+		dbg("Bus %04x:%02x has %d slot%s\n",
+				pci_domain_nr(bridge->pci_bus),
+				bridge->pci_bus->number, bridge->nr_slots,
+				bridge->nr_slots == 1 ? "" : "s");
 		num_slots += bridge->nr_slots;
 	}
 
-	dbg("Total %dslots\n", num_slots);
+	dbg("Total %d slots\n", num_slots);
 	return num_slots;
 }
 
@@ -1254,7 +1407,6 @@ int acpiphp_enable_slot(struct acpiphp_s
 	return retval;
 }
 
-
 /**
  * acpiphp_disable_slot - power off slot
  */
@@ -1274,13 +1426,6 @@ int acpiphp_disable_slot(struct acpiphp_
 	if (retval)
 		goto err_exit;
 
-	acpiphp_resource_sort_and_combine(&slot->bridge->io_head);
-	acpiphp_resource_sort_and_combine(&slot->bridge->mem_head);
-	acpiphp_resource_sort_and_combine(&slot->bridge->p_mem_head);
-	acpiphp_resource_sort_and_combine(&slot->bridge->bus_head);
-	dbg("Available resources:\n");
-	acpiphp_dump_resource(slot->bridge);
-
  err_exit:
 	up(&slot->crit_sect);
 	return retval;
@@ -1293,11 +1438,7 @@ int acpiphp_disable_slot(struct acpiphp_
  */
 u8 acpiphp_get_power_status(struct acpiphp_slot *slot)
 {
-	unsigned int sta;
-
-	sta = get_slot_status(slot);
-
-	return (sta & ACPI_STA_ENABLED) ? 1 : 0;
+	return (slot->flags & SLOT_POWEREDON);
 }
 
 
@@ -1335,9 +1476,10 @@ u8 acpiphp_get_adapter_status(struct acp
 u32 acpiphp_get_address(struct acpiphp_slot *slot)
 {
 	u32 address;
+	struct pci_bus *pci_bus = slot->bridge->pci_bus;
 
-	address = ((slot->bridge->seg) << 16) |
-		  ((slot->bridge->bus) << 8) |
+	address = (pci_domain_nr(pci_bus) << 16) |
+		  (pci_bus->number << 8) |
 		  slot->device;
 
 	return address;
diff --git a/drivers/pci/hotplug/acpiphp_pci.c b/drivers/pci/hotplug/acpiphp_pci.c
deleted file mode 100644
--- a/drivers/pci/hotplug/acpiphp_pci.c
+++ /dev/null
@@ -1,449 +0,0 @@
-/*
- * ACPI PCI HotPlug PCI configuration space management
- *
- * Copyright (C) 1995,2001 Compaq Computer Corporation
- * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
- * Copyright (C) 2001,2002 IBM Corp.
- * Copyright (C) 2002 Takayoshi Kochi (t-kochi@bq.jp.nec.com)
- * Copyright (C) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
- * Copyright (C) 2002 NEC Corporation
- *
- * 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, GOOD TITLE or
- * NON INFRINGEMENT.  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.
- *
- * Send feedback to <t-kochi@bq.jp.nec.com>
- *
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-
-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <linux/acpi.h>
-#include "../pci.h"
-#include "pci_hotplug.h"
-#include "acpiphp.h"
-
-#define MY_NAME "acpiphp_pci"
-
-
-/* allocate mem/pmem/io resource to a new function */
-static int init_config_space (struct acpiphp_func *func)
-{
-	u32 bar, len;
-	u32 address[] = {
-		PCI_BASE_ADDRESS_0,
-		PCI_BASE_ADDRESS_1,
-		PCI_BASE_ADDRESS_2,
-		PCI_BASE_ADDRESS_3,
-		PCI_BASE_ADDRESS_4,
-		PCI_BASE_ADDRESS_5,
-		0
-	};
-	int count;
-	struct acpiphp_bridge *bridge;
-	struct pci_resource *res;
-	struct pci_bus *pbus;
-	int bus, device, function;
-	unsigned int devfn;
-	u16 tmp;
-
-	bridge = func->slot->bridge;
-	pbus = bridge->pci_bus;
-	bus = bridge->bus;
-	device = func->slot->device;
-	function = func->function;
-	devfn = PCI_DEVFN(device, function);
-
-	for (count = 0; address[count]; count++) {	/* for 6 BARs */
-		pci_bus_write_config_dword(pbus, devfn,
-					   address[count], 0xFFFFFFFF);
-		pci_bus_read_config_dword(pbus, devfn, address[count], &bar);
-
-		if (!bar)	/* This BAR is not implemented */
-			continue;
-
-		dbg("Device %02x.%02x BAR %d wants %x\n", device, function, count, bar);
-
-		if (bar & PCI_BASE_ADDRESS_SPACE_IO) {
-			/* This is IO */
-
-			len = bar & (PCI_BASE_ADDRESS_IO_MASK & 0xFFFF);
-			len = len & ~(len - 1);
-
-			dbg("len in IO %x, BAR %d\n", len, count);
-
-			spin_lock(&bridge->res_lock);
-			res = acpiphp_get_io_resource(&bridge->io_head, len);
-			spin_unlock(&bridge->res_lock);
-
-			if (!res) {
-				err("cannot allocate requested io for %02x:%02x.%d len %x\n",
-				    bus, device, function, len);
-				return -1;
-			}
-			pci_bus_write_config_dword(pbus, devfn,
-						   address[count],
-						   (u32)res->base);
-			res->next = func->io_head;
-			func->io_head = res;
-
-		} else {
-			/* This is Memory */
-			if (bar & PCI_BASE_ADDRESS_MEM_PREFETCH) {
-				/* pfmem */
-
-				len = bar & 0xFFFFFFF0;
-				len = ~len + 1;
-
-				dbg("len in PFMEM %x, BAR %d\n", len, count);
-
-				spin_lock(&bridge->res_lock);
-				res = acpiphp_get_resource(&bridge->p_mem_head, len);
-				spin_unlock(&bridge->res_lock);
-
-				if (!res) {
-					err("cannot allocate requested pfmem for %02x:%02x.%d len %x\n",
-					    bus, device, function, len);
-					return -1;
-				}
-
-				pci_bus_write_config_dword(pbus, devfn,
-							   address[count],
-							   (u32)res->base);
-
-				if (bar & PCI_BASE_ADDRESS_MEM_TYPE_64) {	/* takes up another dword */
-					dbg("inside the pfmem 64 case, count %d\n", count);
-					count += 1;
-					pci_bus_write_config_dword(pbus, devfn,
-								   address[count],
-								   (u32)(res->base >> 32));
-				}
-
-				res->next = func->p_mem_head;
-				func->p_mem_head = res;
-
-			} else {
-				/* regular memory */
-
-				len = bar & 0xFFFFFFF0;
-				len = ~len + 1;
-
-				dbg("len in MEM %x, BAR %d\n", len, count);
-
-				spin_lock(&bridge->res_lock);
-				res = acpiphp_get_resource(&bridge->mem_head, len);
-				spin_unlock(&bridge->res_lock);
-
-				if (!res) {
-					err("cannot allocate requested pfmem for %02x:%02x.%d len %x\n",
-					    bus, device, function, len);
-					return -1;
-				}
-
-				pci_bus_write_config_dword(pbus, devfn,
-							   address[count],
-							   (u32)res->base);
-
-				if (bar & PCI_BASE_ADDRESS_MEM_TYPE_64) {
-					/* takes up another dword */
-					dbg("inside mem 64 case, reg. mem, count %d\n", count);
-					count += 1;
-					pci_bus_write_config_dword(pbus, devfn,
-								   address[count],
-								   (u32)(res->base >> 32));
-				}
-
-				res->next = func->mem_head;
-				func->mem_head = res;
-
-			}
-		}
-	}
-
-	/* disable expansion rom */
-	pci_bus_write_config_dword(pbus, devfn, PCI_ROM_ADDRESS, 0x00000000);
-
-	/* set PCI parameters from _HPP */
-	pci_bus_write_config_byte(pbus, devfn, PCI_CACHE_LINE_SIZE,
-				  bridge->hpp.cache_line_size);
-	pci_bus_write_config_byte(pbus, devfn, PCI_LATENCY_TIMER,
-				  bridge->hpp.latency_timer);
-
-	pci_bus_read_config_word(pbus, devfn, PCI_COMMAND, &tmp);
-	if (bridge->hpp.enable_SERR)
-		tmp |= PCI_COMMAND_SERR;
-	if (bridge->hpp.enable_PERR)
-		tmp |= PCI_COMMAND_PARITY;
-	pci_bus_write_config_word(pbus, devfn, PCI_COMMAND, tmp);
-
-	return 0;
-}
-
-/* detect_used_resource - subtract resource under dev from bridge */
-static int detect_used_resource (struct acpiphp_bridge *bridge, struct pci_dev *dev)
-{
-	int count;
-
-	dbg("Device %s\n", pci_name(dev));
-
-	for (count = 0; count < DEVICE_COUNT_RESOURCE; count++) {
-		struct pci_resource *res;
-		struct pci_resource **head;
-		unsigned long base = dev->resource[count].start;
-		unsigned long len = dev->resource[count].end - base + 1;
-		unsigned long flags = dev->resource[count].flags;
-
-		if (!flags)
-			continue;
-
-		dbg("BAR[%d] 0x%lx - 0x%lx (0x%lx)\n", count, base,
-				base + len - 1, flags);
-
-		if (flags & IORESOURCE_IO) {
-			head = &bridge->io_head;
-		} else if (flags & IORESOURCE_PREFETCH) {
-			head = &bridge->p_mem_head;
-		} else {
-			head = &bridge->mem_head;
-		}
-
-		spin_lock(&bridge->res_lock);
-		res = acpiphp_get_resource_with_base(head, base, len);
-		spin_unlock(&bridge->res_lock);
-		if (res)
-			kfree(res);
-	}
-
-	return 0;
-}
-
-
-/**
- * acpiphp_detect_pci_resource - detect resources under bridge
- * @bridge: detect all resources already used under this bridge
- *
- * collect all resources already allocated for all devices under a bridge.
- */
-int acpiphp_detect_pci_resource (struct acpiphp_bridge *bridge)
-{
-	struct list_head *l;
-	struct pci_dev *dev;
-
-	list_for_each (l, &bridge->pci_bus->devices) {
-		dev = pci_dev_b(l);
-		detect_used_resource(bridge, dev);
-	}
-
-	return 0;
-}
-
-
-/**
- * acpiphp_init_slot_resource - gather resource usage information of a slot
- * @slot: ACPI slot object to be checked, should have valid pci_dev member
- *
- * TBD: PCI-to-PCI bridge case
- *      use pci_dev->resource[]
- */
-int acpiphp_init_func_resource (struct acpiphp_func *func)
-{
-	u64 base;
-	u32 bar, len;
-	u32 address[] = {
-		PCI_BASE_ADDRESS_0,
-		PCI_BASE_ADDRESS_1,
-		PCI_BASE_ADDRESS_2,
-		PCI_BASE_ADDRESS_3,
-		PCI_BASE_ADDRESS_4,
-		PCI_BASE_ADDRESS_5,
-		0
-	};
-	int count;
-	struct pci_resource *res;
-	struct pci_dev *dev;
-
-	dev = func->pci_dev;
-	dbg("Hot-pluggable device %s\n", pci_name(dev));
-
-	for (count = 0; address[count]; count++) {	/* for 6 BARs */
-		pci_read_config_dword(dev, address[count], &bar);
-
-		if (!bar)	/* This BAR is not implemented */
-			continue;
-
-		pci_write_config_dword(dev, address[count], 0xFFFFFFFF);
-		pci_read_config_dword(dev, address[count], &len);
-
-		if (len & PCI_BASE_ADDRESS_SPACE_IO) {
-			/* This is IO */
-			base = bar & 0xFFFFFFFC;
-			len = len & (PCI_BASE_ADDRESS_IO_MASK & 0xFFFF);
-			len = len & ~(len - 1);
-
-			dbg("BAR[%d] %08x - %08x (IO)\n", count, (u32)base, (u32)base + len - 1);
-
-			res = acpiphp_make_resource(base, len);
-			if (!res)
-				goto no_memory;
-
-			res->next = func->io_head;
-			func->io_head = res;
-
-		} else {
-			/* This is Memory */
-			base = bar & 0xFFFFFFF0;
-			if (len & PCI_BASE_ADDRESS_MEM_PREFETCH) {
-				/* pfmem */
-
-				len &= 0xFFFFFFF0;
-				len = ~len + 1;
-
-				if (len & PCI_BASE_ADDRESS_MEM_TYPE_64) {	/* takes up another dword */
-					dbg("prefetch mem 64\n");
-					count += 1;
-				}
-				dbg("BAR[%d] %08x - %08x (PMEM)\n", count, (u32)base, (u32)base + len - 1);
-				res = acpiphp_make_resource(base, len);
-				if (!res)
-					goto no_memory;
-
-				res->next = func->p_mem_head;
-				func->p_mem_head = res;
-
-			} else {
-				/* regular memory */
-
-				len &= 0xFFFFFFF0;
-				len = ~len + 1;
-
-				if (len & PCI_BASE_ADDRESS_MEM_TYPE_64) {
-					/* takes up another dword */
-					dbg("mem 64\n");
-					count += 1;
-				}
-				dbg("BAR[%d] %08x - %08x (MEM)\n", count, (u32)base, (u32)base + len - 1);
-				res = acpiphp_make_resource(base, len);
-				if (!res)
-					goto no_memory;
-
-				res->next = func->mem_head;
-				func->mem_head = res;
-
-			}
-		}
-
-		pci_write_config_dword(dev, address[count], bar);
-	}
-#if 1
-	acpiphp_dump_func_resource(func);
-#endif
-
-	return 0;
-
- no_memory:
-	err("out of memory\n");
-	acpiphp_free_resource(&func->io_head);
-	acpiphp_free_resource(&func->mem_head);
-	acpiphp_free_resource(&func->p_mem_head);
-
-	return -1;
-}
-
-
-/**
- * acpiphp_configure_slot - allocate PCI resources
- * @slot: slot to be configured
- *
- * initializes a PCI functions on a device inserted
- * into the slot
- *
- */
-int acpiphp_configure_slot (struct acpiphp_slot *slot)
-{
-	struct acpiphp_func *func;
-	struct list_head *l;
-	u8 hdr;
-	u32 dvid;
-	int retval = 0;
-	int is_multi = 0;
-
-	pci_bus_read_config_byte(slot->bridge->pci_bus,
-				 PCI_DEVFN(slot->device, 0),
-				 PCI_HEADER_TYPE, &hdr);
-
-	if (hdr & 0x80)
-		is_multi = 1;
-
-	list_for_each (l, &slot->funcs) {
-		func = list_entry(l, struct acpiphp_func, sibling);
-		if (is_multi || func->function == 0) {
-			pci_bus_read_config_dword(slot->bridge->pci_bus,
-						  PCI_DEVFN(slot->device,
-							    func->function),
-						  PCI_VENDOR_ID, &dvid);
-			if (dvid != 0xffffffff) {
-				retval = init_config_space(func);
-				if (retval)
-					break;
-			}
-		}
-	}
-
-	return retval;
-}
-
-/**
- * acpiphp_configure_function - configure PCI function
- * @func: function to be configured
- *
- * initializes a PCI functions on a device inserted
- * into the slot
- *
- */
-int acpiphp_configure_function (struct acpiphp_func *func)
-{
-	/* all handled by the pci core now */
-	return 0;
-}
-
-/**
- * acpiphp_unconfigure_function - unconfigure PCI function
- * @func: function to be unconfigured
- *
- */
-void acpiphp_unconfigure_function (struct acpiphp_func *func)
-{
-	struct acpiphp_bridge *bridge;
-
-	/* if pci_dev is NULL, ignore it */
-	if (!func->pci_dev)
-		return;
-
-	pci_remove_bus_device(func->pci_dev);
-
-	/* free all resources */
-	bridge = func->slot->bridge;
-
-	spin_lock(&bridge->res_lock);
-	acpiphp_move_resource(&func->io_head, &bridge->io_head);
-	acpiphp_move_resource(&func->mem_head, &bridge->mem_head);
-	acpiphp_move_resource(&func->p_mem_head, &bridge->p_mem_head);
-	acpiphp_move_resource(&func->bus_head, &bridge->bus_head);
-	spin_unlock(&bridge->res_lock);
-}
diff --git a/drivers/pci/hotplug/acpiphp_res.c b/drivers/pci/hotplug/acpiphp_res.c
deleted file mode 100644
--- a/drivers/pci/hotplug/acpiphp_res.c
+++ /dev/null
@@ -1,700 +0,0 @@
-/*
- * ACPI PCI HotPlug Utility functions
- *
- * Copyright (C) 1995,2001 Compaq Computer Corporation
- * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
- * Copyright (C) 2001 IBM Corp.
- * Copyright (C) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
- * Copyright (C) 2002 Takayoshi Kochi (t-kochi@bq.jp.nec.com)
- * Copyright (C) 2002 NEC Corporation
- *
- * 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, GOOD TITLE or
- * NON INFRINGEMENT.  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.
- *
- * Send feedback to <gregkh@us.ibm.com>, <t-kochi@bq.jp.nec.com>
- *
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/proc_fs.h>
-#include <linux/sysctl.h>
-#include <linux/pci.h>
-#include <linux/smp.h>
-#include <linux/smp_lock.h>
-
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/errno.h>
-#include <linux/ioport.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/timer.h>
-
-#include <linux/ioctl.h>
-#include <linux/fcntl.h>
-
-#include <linux/list.h>
-
-#include "pci_hotplug.h"
-#include "acpiphp.h"
-
-#define MY_NAME "acpiphp_res"
-
-
-/*
- * sort_by_size - sort nodes by their length, smallest first
- */
-static int sort_by_size(struct pci_resource **head)
-{
-	struct pci_resource *current_res;
-	struct pci_resource *next_res;
-	int out_of_order = 1;
-
-	if (!(*head))
-		return 1;
-
-	if (!((*head)->next))
-		return 0;
-
-	while (out_of_order) {
-		out_of_order = 0;
-
-		/* Special case for swapping list head */
-		if (((*head)->next) &&
-		    ((*head)->length > (*head)->next->length)) {
-			out_of_order++;
-			current_res = *head;
-			*head = (*head)->next;
-			current_res->next = (*head)->next;
-			(*head)->next = current_res;
-		}
-
-		current_res = *head;
-
-		while (current_res->next && current_res->next->next) {
-			if (current_res->next->length > current_res->next->next->length) {
-				out_of_order++;
-				next_res = current_res->next;
-				current_res->next = current_res->next->next;
-				current_res = current_res->next;
-				next_res->next = current_res->next;
-				current_res->next = next_res;
-			} else
-				current_res = current_res->next;
-		}
-	}  /* End of out_of_order loop */
-
-	return 0;
-}
-
-#if 0
-/*
- * sort_by_max_size - sort nodes by their length, largest first
- */
-static int sort_by_max_size(struct pci_resource **head)
-{
-	struct pci_resource *current_res;
-	struct pci_resource *next_res;
-	int out_of_order = 1;
-
-	if (!(*head))
-		return 1;
-
-	if (!((*head)->next))
-		return 0;
-
-	while (out_of_order) {
-		out_of_order = 0;
-
-		/* Special case for swapping list head */
-		if (((*head)->next) &&
-		    ((*head)->length < (*head)->next->length)) {
-			out_of_order++;
-			current_res = *head;
-			*head = (*head)->next;
-			current_res->next = (*head)->next;
-			(*head)->next = current_res;
-		}
-
-		current_res = *head;
-
-		while (current_res->next && current_res->next->next) {
-			if (current_res->next->length < current_res->next->next->length) {
-				out_of_order++;
-				next_res = current_res->next;
-				current_res->next = current_res->next->next;
-				current_res = current_res->next;
-				next_res->next = current_res->next;
-				current_res->next = next_res;
-			} else
-				current_res = current_res->next;
-		}
-	}  /* End of out_of_order loop */
-
-	return 0;
-}
-#endif
-
-/**
- * get_io_resource - get resource for I/O ports
- *
- * this function sorts the resource list by size and then
- * returns the first node of "size" length that is not in the
- * ISA aliasing window.  If it finds a node larger than "size"
- * it will split it up.
- *
- * size must be a power of two.
- *
- * difference from get_resource is handling of ISA aliasing space.
- *
- */
-struct pci_resource *acpiphp_get_io_resource (struct pci_resource **head, u32 size)
-{
-	struct pci_resource *prevnode;
-	struct pci_resource *node;
-	struct pci_resource *split_node;
-	u64 temp_qword;
-
-	if (!(*head))
-		return NULL;
-
-	if (acpiphp_resource_sort_and_combine(head))
-		return NULL;
-
-	if (sort_by_size(head))
-		return NULL;
-
-	for (node = *head; node; node = node->next) {
-		if (node->length < size)
-			continue;
-
-		if (node->base & (size - 1)) {
-			/* this one isn't base aligned properly
-			   so we'll make a new entry and split it up */
-			temp_qword = (node->base | (size-1)) + 1;
-
-			/* Short circuit if adjusted size is too small */
-			if ((node->length - (temp_qword - node->base)) < size)
-				continue;
-
-			split_node = acpiphp_make_resource(node->base, temp_qword - node->base);
-
-			if (!split_node)
-				return NULL;
-
-			node->base = temp_qword;
-			node->length -= split_node->length;
-
-			/* Put it in the list */
-			split_node->next = node->next;
-			node->next = split_node;
-		} /* End of non-aligned base */
-
-		/* Don't need to check if too small since we already did */
-		if (node->length > size) {
-			/* this one is longer than we need
-			   so we'll make a new entry and split it up */
-			split_node = acpiphp_make_resource(node->base + size, node->length - size);
-
-			if (!split_node)
-				return NULL;
-
-			node->length = size;
-
-			/* Put it in the list */
-			split_node->next = node->next;
-			node->next = split_node;
-		}  /* End of too big on top end */
-
-		/* For IO make sure it's not in the ISA aliasing space */
-		if ((node->base & 0x300L) && !(node->base & 0xfffff000))
-			continue;
-
-		/* If we got here, then it is the right size
-		   Now take it out of the list */
-		if (*head == node) {
-			*head = node->next;
-		} else {
-			prevnode = *head;
-			while (prevnode->next != node)
-				prevnode = prevnode->next;
-
-			prevnode->next = node->next;
-		}
-		node->next = NULL;
-		/* Stop looping */
-		break;
-	}
-
-	return node;
-}
-
-
-#if 0
-/**
- * get_max_resource - get the largest resource
- *
- * Gets the largest node that is at least "size" big from the
- * list pointed to by head.  It aligns the node on top and bottom
- * to "size" alignment before returning it.
- */
-static struct pci_resource *acpiphp_get_max_resource (struct pci_resource **head, u32 size)
-{
-	struct pci_resource *max;
-	struct pci_resource *temp;
-	struct pci_resource *split_node;
-	u64 temp_qword;
-
-	if (!(*head))
-		return NULL;
-
-	if (acpiphp_resource_sort_and_combine(head))
-		return NULL;
-
-	if (sort_by_max_size(head))
-		return NULL;
-
-	for (max = *head;max; max = max->next) {
-
-		/* If not big enough we could probably just bail,
-		   instead we'll continue to the next. */
-		if (max->length < size)
-			continue;
-
-		if (max->base & (size - 1)) {
-			/* this one isn't base aligned properly
-			   so we'll make a new entry and split it up */
-			temp_qword = (max->base | (size-1)) + 1;
-
-			/* Short circuit if adjusted size is too small */
-			if ((max->length - (temp_qword - max->base)) < size)
-				continue;
-
-			split_node = acpiphp_make_resource(max->base, temp_qword - max->base);
-
-			if (!split_node)
-				return NULL;
-
-			max->base = temp_qword;
-			max->length -= split_node->length;
-
-			/* Put it next in the list */
-			split_node->next = max->next;
-			max->next = split_node;
-		}
-
-		if ((max->base + max->length) & (size - 1)) {
-			/* this one isn't end aligned properly at the top
-			   so we'll make a new entry and split it up */
-			temp_qword = ((max->base + max->length) & ~(size - 1));
-
-			split_node = acpiphp_make_resource(temp_qword,
-							   max->length + max->base - temp_qword);
-
-			if (!split_node)
-				return NULL;
-
-			max->length -= split_node->length;
-
-			/* Put it in the list */
-			split_node->next = max->next;
-			max->next = split_node;
-		}
-
-		/* Make sure it didn't shrink too much when we aligned it */
-		if (max->length < size)
-			continue;
-
-		/* Now take it out of the list */
-		temp = (struct pci_resource*) *head;
-		if (temp == max) {
-			*head = max->next;
-		} else {
-			while (temp && temp->next != max) {
-				temp = temp->next;
-			}
-
-			temp->next = max->next;
-		}
-
-		max->next = NULL;
-		return max;
-	}
-
-	/* If we get here, we couldn't find one */
-	return NULL;
-}
-#endif
-
-/**
- * get_resource - get resource (mem, pfmem)
- *
- * this function sorts the resource list by size and then
- * returns the first node of "size" length.  If it finds a node
- * larger than "size" it will split it up.
- *
- * size must be a power of two.
- *
- */
-struct pci_resource *acpiphp_get_resource (struct pci_resource **head, u32 size)
-{
-	struct pci_resource *prevnode;
-	struct pci_resource *node;
-	struct pci_resource *split_node;
-	u64 temp_qword;
-
-	if (!(*head))
-		return NULL;
-
-	if (acpiphp_resource_sort_and_combine(head))
-		return NULL;
-
-	if (sort_by_size(head))
-		return NULL;
-
-	for (node = *head; node; node = node->next) {
-		dbg("%s: req_size =%x node=%p, base=%x, length=%x\n",
-		    __FUNCTION__, size, node, (u32)node->base, node->length);
-		if (node->length < size)
-			continue;
-
-		if (node->base & (size - 1)) {
-			dbg("%s: not aligned\n", __FUNCTION__);
-			/* this one isn't base aligned properly
-			   so we'll make a new entry and split it up */
-			temp_qword = (node->base | (size-1)) + 1;
-
-			/* Short circuit if adjusted size is too small */
-			if ((node->length - (temp_qword - node->base)) < size)
-				continue;
-
-			split_node = acpiphp_make_resource(node->base, temp_qword - node->base);
-
-			if (!split_node)
-				return NULL;
-
-			node->base = temp_qword;
-			node->length -= split_node->length;
-
-			/* Put it in the list */
-			split_node->next = node->next;
-			node->next = split_node;
-		} /* End of non-aligned base */
-
-		/* Don't need to check if too small since we already did */
-		if (node->length > size) {
-			dbg("%s: too big\n", __FUNCTION__);
-			/* this one is longer than we need
-			   so we'll make a new entry and split it up */
-			split_node = acpiphp_make_resource(node->base + size, node->length - size);
-
-			if (!split_node)
-				return NULL;
-
-			node->length = size;
-
-			/* Put it in the list */
-			split_node->next = node->next;
-			node->next = split_node;
-		}  /* End of too big on top end */
-
-		dbg("%s: got one!!!\n", __FUNCTION__);
-		/* If we got here, then it is the right size
-		   Now take it out of the list */
-		if (*head == node) {
-			*head = node->next;
-		} else {
-			prevnode = *head;
-			while (prevnode->next != node)
-				prevnode = prevnode->next;
-
-			prevnode->next = node->next;
-		}
-		node->next = NULL;
-		/* Stop looping */
-		break;
-	}
-	return node;
-}
-
-/**
- * get_resource_with_base - get resource with specific base address
- *
- * this function
- * returns the first node of "size" length located at specified base address.
- * If it finds a node larger than "size" it will split it up.
- *
- * size must be a power of two.
- *
- */
-struct pci_resource *acpiphp_get_resource_with_base (struct pci_resource **head, u64 base, u32 size)
-{
-	struct pci_resource *prevnode;
-	struct pci_resource *node;
-	struct pci_resource *split_node;
-	u64 temp_qword;
-
-	if (!(*head))
-		return NULL;
-
-	if (acpiphp_resource_sort_and_combine(head))
-		return NULL;
-
-	for (node = *head; node; node = node->next) {
-		dbg(": 1st req_base=%x req_size =%x node=%p, base=%x, length=%x\n",
-		    (u32)base, size, node, (u32)node->base, node->length);
-		if (node->base > base)
-			continue;
-
-		if ((node->base + node->length) < (base + size))
-			continue;
-
-		if (node->base < base) {
-			dbg(": split 1\n");
-			/* this one isn't base aligned properly
-			   so we'll make a new entry and split it up */
-			temp_qword = base;
-
-			/* Short circuit if adjusted size is too small */
-			if ((node->length - (temp_qword - node->base)) < size)
-				continue;
-
-			split_node = acpiphp_make_resource(node->base, temp_qword - node->base);
-
-			if (!split_node)
-				return NULL;
-
-			node->base = temp_qword;
-			node->length -= split_node->length;
-
-			/* Put it in the list */
-			split_node->next = node->next;
-			node->next = split_node;
-		}
-
-		dbg(": 2nd req_base=%x req_size =%x node=%p, base=%x, length=%x\n",
-		    (u32)base, size, node, (u32)node->base, node->length);
-
-		/* Don't need to check if too small since we already did */
-		if (node->length > size) {
-			dbg(": split 2\n");
-			/* this one is longer than we need
-			   so we'll make a new entry and split it up */
-			split_node = acpiphp_make_resource(node->base + size, node->length - size);
-
-			if (!split_node)
-				return NULL;
-
-			node->length = size;
-
-			/* Put it in the list */
-			split_node->next = node->next;
-			node->next = split_node;
-		}  /* End of too big on top end */
-
-		dbg(": got one!!!\n");
-		/* If we got here, then it is the right size
-		   Now take it out of the list */
-		if (*head == node) {
-			*head = node->next;
-		} else {
-			prevnode = *head;
-			while (prevnode->next != node)
-				prevnode = prevnode->next;
-
-			prevnode->next = node->next;
-		}
-		node->next = NULL;
-		/* Stop looping */
-		break;
-	}
-	return node;
-}
-
-
-/**
- * acpiphp_resource_sort_and_combine
- *
- * Sorts all of the nodes in the list in ascending order by
- * their base addresses.  Also does garbage collection by
- * combining adjacent nodes.
- *
- * returns 0 if success
- */
-int acpiphp_resource_sort_and_combine (struct pci_resource **head)
-{
-	struct pci_resource *node1;
-	struct pci_resource *node2;
-	int out_of_order = 1;
-
-	if (!(*head))
-		return 1;
-
-	dbg("*head->next = %p\n",(*head)->next);
-
-	if (!(*head)->next)
-		return 0;	/* only one item on the list, already sorted! */
-
-	dbg("*head->base = 0x%x\n",(u32)(*head)->base);
-	dbg("*head->next->base = 0x%x\n", (u32)(*head)->next->base);
-	while (out_of_order) {
-		out_of_order = 0;
-
-		/* Special case for swapping list head */
-		if (((*head)->next) &&
-		    ((*head)->base > (*head)->next->base)) {
-			node1 = *head;
-			(*head) = (*head)->next;
-			node1->next = (*head)->next;
-			(*head)->next = node1;
-			out_of_order++;
-		}
-
-		node1 = (*head);
-
-		while (node1->next && node1->next->next) {
-			if (node1->next->base > node1->next->next->base) {
-				out_of_order++;
-				node2 = node1->next;
-				node1->next = node1->next->next;
-				node1 = node1->next;
-				node2->next = node1->next;
-				node1->next = node2;
-			} else
-				node1 = node1->next;
-		}
-	}  /* End of out_of_order loop */
-
-	node1 = *head;
-
-	while (node1 && node1->next) {
-		if ((node1->base + node1->length) == node1->next->base) {
-			/* Combine */
-			dbg("8..\n");
-			node1->length += node1->next->length;
-			node2 = node1->next;
-			node1->next = node1->next->next;
-			kfree(node2);
-		} else
-			node1 = node1->next;
-	}
-
-	return 0;
-}
-
-
-/**
- * acpiphp_make_resource - make resource structure
- * @base: base address of a resource
- * @length: length of a resource
- */
-struct pci_resource *acpiphp_make_resource (u64 base, u32 length)
-{
-	struct pci_resource *res;
-
-	res = kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
-	if (res) {
-		memset(res, 0, sizeof(struct pci_resource));
-		res->base = base;
-		res->length = length;
-	}
-
-	return res;
-}
-
-
-/**
- * acpiphp_move_resource - move linked resources from one to another
- * @from: head of linked resource list
- * @to: head of linked resource list
- */
-void acpiphp_move_resource (struct pci_resource **from, struct pci_resource **to)
-{
-	struct pci_resource *tmp;
-
-	while (*from) {
-		tmp = (*from)->next;
-		(*from)->next = *to;
-		*to = *from;
-		*from = tmp;
-	}
-
-	/* *from = NULL is guaranteed */
-}
-
-
-/**
- * acpiphp_free_resource - free all linked resources
- * @res: head of linked resource list
- */
-void acpiphp_free_resource (struct pci_resource **res)
-{
-	struct pci_resource *tmp;
-
-	while (*res) {
-		tmp = (*res)->next;
-		kfree(*res);
-		*res = tmp;
-	}
-
-	/* *res = NULL is guaranteed */
-}
-
-
-/* debug support functions;  will go away sometime :) */
-static void dump_resource(struct pci_resource *head)
-{
-	struct pci_resource *p;
-	int cnt;
-
-	p = head;
-	cnt = 0;
-
-	while (p) {
-		dbg("[%02d] %08x - %08x\n",
-		    cnt++, (u32)p->base, (u32)p->base + p->length - 1);
-		p = p->next;
-	}
-}
-
-void acpiphp_dump_resource(struct acpiphp_bridge *bridge)
-{
-	dbg("I/O resource:\n");
-	dump_resource(bridge->io_head);
-	dbg("MEM resource:\n");
-	dump_resource(bridge->mem_head);
-	dbg("PMEM resource:\n");
-	dump_resource(bridge->p_mem_head);
-	dbg("BUS resource:\n");
-	dump_resource(bridge->bus_head);
-}
-
-void acpiphp_dump_func_resource(struct acpiphp_func *func)
-{
-	dbg("I/O resource:\n");
-	dump_resource(func->io_head);
-	dbg("MEM resource:\n");
-	dump_resource(func->mem_head);
-	dbg("PMEM resource:\n");
-	dump_resource(func->p_mem_head);
-	dbg("BUS resource:\n");
-	dump_resource(func->bus_head);
-}
diff --git a/drivers/pci/hotplug/cpqphp_core.c b/drivers/pci/hotplug/cpqphp_core.c
--- a/drivers/pci/hotplug/cpqphp_core.c
+++ b/drivers/pci/hotplug/cpqphp_core.c
@@ -60,6 +60,7 @@ static void __iomem *smbios_start;
 static void __iomem *cpqhp_rom_start;
 static int power_mode;
 static int debug;
+static int initialized;
 
 #define DRIVER_VERSION	"0.9.8"
 #define DRIVER_AUTHOR	"Dan Zink <dan.zink@compaq.com>, Greg Kroah-Hartman <greg@kroah.com>"
@@ -1271,7 +1272,6 @@ static int one_time_init(void)
 {
 	int loop;
 	int retval = 0;
-	static int initialized = 0;
 
 	if (initialized)
 		return 0;
@@ -1441,7 +1441,8 @@ static void __exit unload_cpqphpd(void)
 	}
 
 	// Stop the notification mechanism
-	cpqhp_event_stop_thread();
+	if (initialized)
+		cpqhp_event_stop_thread();
 
 	//unmap the rom address
 	if (cpqhp_rom_start)
diff --git a/drivers/pci/hotplug/cpqphp_sysfs.c b/drivers/pci/hotplug/cpqphp_sysfs.c
--- a/drivers/pci/hotplug/cpqphp_sysfs.c
+++ b/drivers/pci/hotplug/cpqphp_sysfs.c
@@ -38,7 +38,7 @@
 
 /* A few routines that create sysfs entries for the hot plug controller */
 
-static ssize_t show_ctrl (struct device *dev, char *buf)
+static ssize_t show_ctrl (struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct pci_dev *pci_dev;
 	struct controller *ctrl;
@@ -82,7 +82,7 @@ static ssize_t show_ctrl (struct device 
 }
 static DEVICE_ATTR (ctrl, S_IRUGO, show_ctrl, NULL);
 
-static ssize_t show_dev (struct device *dev, char *buf)
+static ssize_t show_dev (struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct pci_dev *pci_dev;
 	struct controller *ctrl;
diff --git a/drivers/pci/hotplug/pci_hotplug_core.c b/drivers/pci/hotplug/pci_hotplug_core.c
--- a/drivers/pci/hotplug/pci_hotplug_core.c
+++ b/drivers/pci/hotplug/pci_hotplug_core.c
@@ -73,7 +73,7 @@ static ssize_t hotplug_slot_attr_show(st
 {
 	struct hotplug_slot *slot = to_hotplug_slot(kobj);
 	struct hotplug_slot_attribute *attribute = to_hotplug_attr(attr);
-	return attribute->show ? attribute->show(slot, buf) : 0;
+	return attribute->show ? attribute->show(slot, buf) : -EIO;
 }
 
 static ssize_t hotplug_slot_attr_store(struct kobject *kobj,
@@ -81,7 +81,7 @@ static ssize_t hotplug_slot_attr_store(s
 {
 	struct hotplug_slot *slot = to_hotplug_slot(kobj);
 	struct hotplug_slot_attribute *attribute = to_hotplug_attr(attr);
-	return attribute->store ? attribute->store(slot, buf, len) : 0;
+	return attribute->store ? attribute->store(slot, buf, len) : -EIO;
 }
 
 static struct sysfs_ops hotplug_slot_sysfs_ops = {
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h
--- a/drivers/pci/hotplug/pciehp.h
+++ b/drivers/pci/hotplug/pciehp.h
@@ -23,7 +23,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- * Send feedback to <greg@kroah.com>, <dely.l.sy@intel.com>
+ * Send feedback to <greg@kroah.com>, <kristen.c.accardi@intel.com>
  *
  */
 #ifndef _PCIEHP_H
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c
--- a/drivers/pci/hotplug/pciehp_core.c
+++ b/drivers/pci/hotplug/pciehp_core.c
@@ -23,7 +23,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- * Send feedback to <greg@kroah.com>, <dely.l.sy@intel.com>
+ * Send feedback to <greg@kroah.com>, <kristen.c.accardi@intel.com>
  *
  */
 
diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c
--- a/drivers/pci/hotplug/pciehp_ctrl.c
+++ b/drivers/pci/hotplug/pciehp_ctrl.c
@@ -23,7 +23,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- * Send feedback to <greg@kroah.com>, <dely.l.sy@intel.com>
+ * Send feedback to <greg@kroah.com>, <kristen.c.accardi@intel.com>
  *
  */
 
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -23,7 +23,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- * Send feedback to <greg@kroah.com>,<dely.l.sy@intel.com>
+ * Send feedback to <greg@kroah.com>,<kristen.c.accardi@intel.com>
  *
  */
 
diff --git a/drivers/pci/hotplug/pciehp_pci.c b/drivers/pci/hotplug/pciehp_pci.c
--- a/drivers/pci/hotplug/pciehp_pci.c
+++ b/drivers/pci/hotplug/pciehp_pci.c
@@ -23,7 +23,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- * Send feedback to <greg@kroah.com>, <dely.l.sy@intel.com>
+ * Send feedback to <greg@kroah.com>, <kristen.c.accardi@intel.com>
  *
  */
 
diff --git a/drivers/pci/hotplug/pciehprm.h b/drivers/pci/hotplug/pciehprm.h
--- a/drivers/pci/hotplug/pciehprm.h
+++ b/drivers/pci/hotplug/pciehprm.h
@@ -23,7 +23,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- * Send feedback to <greg@kroah.com>, <dely.l.sy@intel.com>
+ * Send feedback to <greg@kroah.com>, <kristen.c.accardi@intel.com>
  *
  */
 
diff --git a/drivers/pci/hotplug/pciehprm_acpi.c b/drivers/pci/hotplug/pciehprm_acpi.c
--- a/drivers/pci/hotplug/pciehprm_acpi.c
+++ b/drivers/pci/hotplug/pciehprm_acpi.c
@@ -20,7 +20,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- * Send feedback to <dely.l.sy@intel.com>
+ * Send feedback to <kristen.c.accardi@intel.com>
  *
  */
 
diff --git a/drivers/pci/hotplug/pciehprm_nonacpi.c b/drivers/pci/hotplug/pciehprm_nonacpi.c
--- a/drivers/pci/hotplug/pciehprm_nonacpi.c
+++ b/drivers/pci/hotplug/pciehprm_nonacpi.c
@@ -23,7 +23,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- * Send feedback to <greg@kroah.com>, <dely.l.sy@intel.com>
+ * Send feedback to <greg@kroah.com>, <kristen.c.accardi@intel.com>
  *
  */
 
diff --git a/drivers/pci/hotplug/pciehprm_nonacpi.h b/drivers/pci/hotplug/pciehprm_nonacpi.h
--- a/drivers/pci/hotplug/pciehprm_nonacpi.h
+++ b/drivers/pci/hotplug/pciehprm_nonacpi.h
@@ -23,7 +23,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- * Send feedback to <greg@kroah.com>, <dely.l.sy@intel.com>
+ * Send feedback to <greg@kroah.com>, <kristen.c.accardi@intel.com>
  *
  */
 
diff --git a/drivers/pci/hotplug/rpadlpar_sysfs.c b/drivers/pci/hotplug/rpadlpar_sysfs.c
--- a/drivers/pci/hotplug/rpadlpar_sysfs.c
+++ b/drivers/pci/hotplug/rpadlpar_sysfs.c
@@ -48,7 +48,7 @@ dlpar_attr_store(struct kobject * kobj, 
 	struct dlpar_io_attr *dlpar_attr = container_of(attr,
 						struct dlpar_io_attr, attr);
 	return dlpar_attr->store ?
-		dlpar_attr->store(dlpar_attr, buf, nbytes) : 0;
+		dlpar_attr->store(dlpar_attr, buf, nbytes) : -EIO;
 }
 
 static struct sysfs_ops dlpar_attr_sysfs_ops = {
diff --git a/drivers/pci/hotplug/sgi_hotplug.c b/drivers/pci/hotplug/sgi_hotplug.c
new file mode 100644
--- /dev/null
+++ b/drivers/pci/hotplug/sgi_hotplug.c
@@ -0,0 +1,611 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2005 Silicon Graphics, Inc. All rights reserved.
+ *
+ * This work was based on the 2.4/2.6 kernel development by Dick Reigner.
+ * Work to add BIOS PROM support was completed by Mike Habeck.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/proc_fs.h>
+#include <linux/types.h>
+
+#include <asm/sn/addrs.h>
+#include <asm/sn/l1.h>
+#include <asm/sn/module.h>
+#include <asm/sn/pcibr_provider.h>
+#include <asm/sn/pcibus_provider_defs.h>
+#include <asm/sn/pcidev.h>
+#include <asm/sn/sn_sal.h>
+#include <asm/sn/types.h>
+
+#include "../pci.h"
+#include "pci_hotplug.h"
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("SGI (prarit@sgi.com, dickie@sgi.com, habeck@sgi.com)");
+MODULE_DESCRIPTION("SGI Altix Hot Plug PCI Controller Driver");
+
+#define PCIIO_ASIC_TYPE_TIOCA     4
+#define PCI_SLOT_ALREADY_UP       2     /* slot already up */
+#define PCI_SLOT_ALREADY_DOWN     3     /* slot already down */
+#define PCI_L1_ERR                7     /* L1 console command error */
+#define PCI_EMPTY_33MHZ          15     /* empty 33 MHz bus */
+#define PCI_L1_QSIZE            128     /* our L1 message buffer size */
+#define SN_MAX_HP_SLOTS		 32	/* max number of hotplug slots */
+#define SGI_HOTPLUG_PROM_REV	0x0420  /* Min. required PROM version */
+
+/* internal list head */
+static struct list_head sn_hp_list;
+
+/* hotplug_slot struct's private pointer */
+struct slot {
+	int device_num;
+	struct pci_bus *pci_bus;
+	/* this struct for glue internal only */
+	struct hotplug_slot *hotplug_slot;
+	struct list_head hp_list;
+};
+
+struct pcibr_slot_enable_resp {
+	int resp_sub_errno;
+	char resp_l1_msg[PCI_L1_QSIZE + 1];
+};
+
+struct pcibr_slot_disable_resp {
+	int resp_sub_errno;
+	char resp_l1_msg[PCI_L1_QSIZE + 1];
+};
+
+enum sn_pci_req_e {
+	PCI_REQ_SLOT_ELIGIBLE,
+	PCI_REQ_SLOT_DISABLE
+};
+
+static int enable_slot(struct hotplug_slot *slot);
+static int disable_slot(struct hotplug_slot *slot);
+static int get_power_status(struct hotplug_slot *slot, u8 *value);
+
+static struct hotplug_slot_ops sn_hotplug_slot_ops = {
+	.owner                  = THIS_MODULE,
+	.enable_slot            = enable_slot,
+	.disable_slot           = disable_slot,
+	.get_power_status       = get_power_status,
+};
+
+static DECLARE_MUTEX(sn_hotplug_sem);
+
+static int sn_pci_slot_valid(struct pci_bus *pci_bus, int device)
+{
+	struct pcibus_info *pcibus_info;
+	int bricktype;
+	int bus_num;
+
+	pcibus_info = SN_PCIBUS_BUSSOFT_INFO(pci_bus);
+
+	/* Check to see if this is a valid slot on 'pci_bus' */
+	if (!(pcibus_info->pbi_valid_devices & (1 << device)))
+		return -EPERM;
+
+	bricktype = MODULE_GET_BTYPE(pcibus_info->pbi_moduleid);
+	bus_num = pcibus_info->pbi_buscommon.bs_persist_busnum & 0xf;
+
+	/* Do not allow hotplug operations on base I/O cards */
+	if ((bricktype == L1_BRICKTYPE_IX ||  bricktype == L1_BRICKTYPE_IA) &&
+	    (bus_num == 1 && device != 1))
+		return -EPERM;
+
+	return 1;
+}
+
+static int sn_pci_bus_valid(struct pci_bus *pci_bus)
+{
+	struct pcibus_info *pcibus_info;
+	int asic_type;
+	int bricktype;
+
+	pcibus_info = SN_PCIBUS_BUSSOFT_INFO(pci_bus);
+
+	/* Don't register slots hanging off the TIOCA bus */
+	asic_type = pcibus_info->pbi_buscommon.bs_asic_type;
+	if (asic_type == PCIIO_ASIC_TYPE_TIOCA)
+		return -EPERM;
+
+	/* Only register slots in I/O Bricks that support hotplug */
+	bricktype = MODULE_GET_BTYPE(pcibus_info->pbi_moduleid);
+	switch (bricktype) {
+	case L1_BRICKTYPE_IX:
+	case L1_BRICKTYPE_PX:
+	case L1_BRICKTYPE_IA:
+	case L1_BRICKTYPE_PA:
+		return 1;
+		break;
+	default:
+		return -EPERM;
+		break;
+	}
+
+	return -EIO;
+}
+
+static int sn_hp_slot_private_alloc(struct hotplug_slot *bss_hotplug_slot,
+				    struct pci_bus *pci_bus, int device)
+{
+	struct pcibus_info *pcibus_info;
+	struct slot *slot;
+
+	pcibus_info = SN_PCIBUS_BUSSOFT_INFO(pci_bus);
+
+	bss_hotplug_slot->private = kcalloc(1, sizeof(struct slot),
+					    GFP_KERNEL);
+	if (!bss_hotplug_slot->private)
+		return -ENOMEM;
+	slot = (struct slot *)bss_hotplug_slot->private;
+
+	bss_hotplug_slot->name = kmalloc(33, GFP_KERNEL);
+	if (!bss_hotplug_slot->name) {
+		kfree(bss_hotplug_slot->private);
+		return -ENOMEM;
+	}
+
+	slot->device_num = device;
+	slot->pci_bus = pci_bus;
+
+	sprintf(bss_hotplug_slot->name, "module_%c%c%c%c%.2d_b_%d_s_%d",
+		'0'+RACK_GET_CLASS(MODULE_GET_RACK(pcibus_info->pbi_moduleid)),
+		'0'+RACK_GET_GROUP(MODULE_GET_RACK(pcibus_info->pbi_moduleid)),
+		'0'+RACK_GET_NUM(MODULE_GET_RACK(pcibus_info->pbi_moduleid)),
+		MODULE_GET_BTCHAR(pcibus_info->pbi_moduleid),
+		MODULE_GET_BPOS(pcibus_info->pbi_moduleid),
+		((int)pcibus_info->pbi_buscommon.bs_persist_busnum) & 0xf,
+		device + 1);
+
+	slot->hotplug_slot = bss_hotplug_slot;
+	list_add(&slot->hp_list, &sn_hp_list);
+
+	return 0;
+}
+
+static struct hotplug_slot * sn_hp_destroy(void)
+{
+	struct slot *slot;
+	struct list_head *list;
+	struct hotplug_slot *bss_hotplug_slot = NULL;
+
+	list_for_each(list, &sn_hp_list) {
+		slot = list_entry(list, struct slot, hp_list);
+		bss_hotplug_slot = slot->hotplug_slot;
+		list_del(&((struct slot *)bss_hotplug_slot->private)->
+			 hp_list);
+		break;
+	}
+	return bss_hotplug_slot;
+}
+
+static void sn_bus_alloc_data(struct pci_dev *dev)
+{
+	struct list_head *node;
+	struct pci_bus *subordinate_bus;
+	struct pci_dev *child;
+
+	sn_pci_fixup_slot(dev);
+
+	/* Recursively sets up the sn_irq_info structs */
+	if (dev->subordinate) {
+		subordinate_bus = dev->subordinate;
+		list_for_each(node, &subordinate_bus->devices) {
+			child = list_entry(node, struct pci_dev, bus_list);
+			sn_bus_alloc_data(child);
+		}
+	}
+}
+
+static void sn_bus_free_data(struct pci_dev *dev)
+{
+	struct list_head *node;
+	struct pci_bus *subordinate_bus;
+	struct pci_dev *child;
+
+	/* Recursively clean up sn_irq_info structs */
+	if (dev->subordinate) {
+		subordinate_bus = dev->subordinate;
+		list_for_each(node, &subordinate_bus->devices) {
+			child = list_entry(node, struct pci_dev, bus_list);
+			sn_bus_free_data(child);
+		}
+	}
+	sn_pci_unfixup_slot(dev);
+}
+
+static u8 sn_power_status_get(struct hotplug_slot *bss_hotplug_slot)
+{
+	struct slot *slot = (struct slot *)bss_hotplug_slot->private;
+	struct pcibus_info *pcibus_info;
+	u8 retval;
+
+	pcibus_info = SN_PCIBUS_BUSSOFT_INFO(slot->pci_bus);
+	retval = pcibus_info->pbi_enabled_devices & (1 << slot->device_num);
+
+	return retval ? 1 : 0;
+}
+
+static void sn_slot_mark_enable(struct hotplug_slot *bss_hotplug_slot,
+				int device_num)
+{
+	struct slot *slot = (struct slot *)bss_hotplug_slot->private;
+	struct pcibus_info *pcibus_info;
+
+	pcibus_info = SN_PCIBUS_BUSSOFT_INFO(slot->pci_bus);
+	pcibus_info->pbi_enabled_devices |= (1 << device_num);
+}
+
+static void sn_slot_mark_disable(struct hotplug_slot *bss_hotplug_slot,
+				 int device_num)
+{
+	struct slot *slot = (struct slot *)bss_hotplug_slot->private;
+	struct pcibus_info *pcibus_info;
+
+	pcibus_info = SN_PCIBUS_BUSSOFT_INFO(slot->pci_bus);
+	pcibus_info->pbi_enabled_devices &= ~(1 << device_num);
+}
+
+static int sn_slot_enable(struct hotplug_slot *bss_hotplug_slot,
+			  int device_num)
+{
+	struct slot *slot = (struct slot *)bss_hotplug_slot->private;
+	struct pcibus_info *pcibus_info;
+	struct pcibr_slot_enable_resp resp;
+	int rc;
+
+	pcibus_info = SN_PCIBUS_BUSSOFT_INFO(slot->pci_bus);
+
+	/*
+	 * Power-on and initialize the slot in the SN
+	 * PCI infrastructure.
+	 */
+	rc = sal_pcibr_slot_enable(pcibus_info, device_num, &resp);
+
+	if (rc == PCI_SLOT_ALREADY_UP) {
+		dev_dbg(slot->pci_bus->self, "is already active\n");
+		return -EPERM;
+	}
+
+	if (rc == PCI_L1_ERR) {
+		dev_dbg(slot->pci_bus->self,
+			"L1 failure %d with message: %s",
+			resp.resp_sub_errno, resp.resp_l1_msg);
+		return -EPERM;
+	}
+
+	if (rc) {
+		dev_dbg(slot->pci_bus->self,
+			"insert failed with error %d sub-error %d\n",
+			rc, resp.resp_sub_errno);
+		return -EIO;
+	}
+
+	sn_slot_mark_enable(bss_hotplug_slot, device_num);
+
+	return 0;
+}
+
+static int sn_slot_disable(struct hotplug_slot *bss_hotplug_slot,
+			   int device_num, int action)
+{
+	struct slot *slot = (struct slot *)bss_hotplug_slot->private;
+	struct pcibus_info *pcibus_info;
+	struct pcibr_slot_disable_resp resp;
+	int rc;
+
+	pcibus_info = SN_PCIBUS_BUSSOFT_INFO(slot->pci_bus);
+
+	rc = sal_pcibr_slot_disable(pcibus_info, device_num, action, &resp);
+
+	if (action == PCI_REQ_SLOT_ELIGIBLE && rc == PCI_SLOT_ALREADY_DOWN) {
+		dev_dbg(slot->pci_bus->self, "Slot %s already inactive\n");
+		return -ENODEV;
+	}
+
+	if (action == PCI_REQ_SLOT_ELIGIBLE && rc == PCI_EMPTY_33MHZ) {
+		dev_dbg(slot->pci_bus->self,
+			"Cannot remove last 33MHz card\n");
+		return -EPERM;
+	}
+
+	if (action == PCI_REQ_SLOT_ELIGIBLE && rc == PCI_L1_ERR) {
+		dev_dbg(slot->pci_bus->self,
+			"L1 failure %d with message \n%s\n",
+			resp.resp_sub_errno, resp.resp_l1_msg);
+		return -EPERM;
+	}
+
+	if (action == PCI_REQ_SLOT_ELIGIBLE && rc) {
+		dev_dbg(slot->pci_bus->self,
+			"remove failed with error %d sub-error %d\n",
+			rc, resp.resp_sub_errno);
+		return -EIO;
+	}
+
+	if (action == PCI_REQ_SLOT_ELIGIBLE && !rc)
+		return 0;
+
+	if (action == PCI_REQ_SLOT_DISABLE && !rc) {
+		sn_slot_mark_disable(bss_hotplug_slot, device_num);
+		dev_dbg(slot->pci_bus->self, "remove successful\n");
+		return 0;
+	}
+
+	if (action == PCI_REQ_SLOT_DISABLE && rc) {
+		dev_dbg(slot->pci_bus->self,"remove failed rc = %d\n", rc);
+		return rc;
+	}
+
+	return rc;
+}
+
+static int enable_slot(struct hotplug_slot *bss_hotplug_slot)
+{
+	struct slot *slot = (struct slot *)bss_hotplug_slot->private;
+	struct pci_bus *new_bus = NULL;
+	struct pci_dev *dev;
+	int func, num_funcs;
+	int new_ppb = 0;
+	int rc;
+
+	/* Serialize the Linux PCI infrastructure */
+	down(&sn_hotplug_sem);
+
+	/*
+	 * Power-on and initialize the slot in the SN
+	 * PCI infrastructure.
+	 */
+	rc = sn_slot_enable(bss_hotplug_slot, slot->device_num);
+	if (rc) {
+		up(&sn_hotplug_sem);
+		return rc;
+	}
+
+	num_funcs = pci_scan_slot(slot->pci_bus, PCI_DEVFN(slot->device_num+1,
+							   PCI_FUNC(0)));
+	if (!num_funcs) {
+		dev_dbg(slot->pci_bus->self, "no device in slot\n");
+		up(&sn_hotplug_sem);
+		return -ENODEV;
+	}
+
+	sn_pci_controller_fixup(pci_domain_nr(slot->pci_bus),
+				slot->pci_bus->number,
+				slot->pci_bus);
+	/*
+	 * Map SN resources for all functions on the card
+	 * to the Linux PCI interface and tell the drivers
+	 * about them.
+	 */
+	for (func = 0; func < num_funcs;  func++) {
+		dev = pci_get_slot(slot->pci_bus,
+				   PCI_DEVFN(slot->device_num + 1,
+					     PCI_FUNC(func)));
+
+
+		if (dev) {
+			if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
+				unsigned char sec_bus;
+				pci_read_config_byte(dev, PCI_SECONDARY_BUS,
+						     &sec_bus);
+				new_bus = pci_add_new_bus(dev->bus, dev,
+							  sec_bus);
+				pci_scan_child_bus(new_bus);
+				sn_pci_controller_fixup(pci_domain_nr(new_bus),
+							new_bus->number,
+							new_bus);
+				new_ppb = 1;
+			}
+			sn_bus_alloc_data(dev);
+			pci_dev_put(dev);
+		}
+	}
+
+	/* Call the driver for the new device */
+	pci_bus_add_devices(slot->pci_bus);
+	/* Call the drivers for the new devices subordinate to PPB */
+	if (new_ppb)
+		pci_bus_add_devices(new_bus);
+
+	up(&sn_hotplug_sem);
+
+	if (rc == 0)
+		dev_dbg(slot->pci_bus->self,
+			"insert operation successful\n");
+	else
+		dev_dbg(slot->pci_bus->self,
+			"insert operation failed rc = %d\n", rc);
+
+	return rc;
+}
+
+static int disable_slot(struct hotplug_slot *bss_hotplug_slot)
+{
+	struct slot *slot = (struct slot *)bss_hotplug_slot->private;
+	struct pci_dev *dev;
+	int func;
+	int rc;
+
+	/* Acquire update access to the bus */
+	down(&sn_hotplug_sem);
+
+	/* is it okay to bring this slot down? */
+	rc = sn_slot_disable(bss_hotplug_slot, slot->device_num,
+			     PCI_REQ_SLOT_ELIGIBLE);
+	if (rc)
+		goto leaving;
+
+	/* Free the SN resources assigned to the Linux device.*/
+	for (func = 0; func < 8;  func++) {
+		dev = pci_get_slot(slot->pci_bus,
+				   PCI_DEVFN(slot->device_num+1,
+				   	     PCI_FUNC(func)));
+		if (dev) {
+			/*
+			 * Some drivers may use dma accesses during the
+			 * driver remove function. We release the sysdata
+			 * areas after the driver remove functions have
+			 * been called.
+			 */
+			sn_bus_store_sysdata(dev);
+			sn_bus_free_data(dev);
+			pci_remove_bus_device(dev);
+			pci_dev_put(dev);
+		}
+	}
+
+	/* free the collected sysdata pointers */
+	sn_bus_free_sysdata();
+
+	/* Deactivate slot */
+	rc = sn_slot_disable(bss_hotplug_slot, slot->device_num,
+			     PCI_REQ_SLOT_DISABLE);
+ leaving:
+	/* Release the bus lock */
+	up(&sn_hotplug_sem);
+
+	return rc;
+}
+
+static int get_power_status(struct hotplug_slot *bss_hotplug_slot, u8 *value)
+{
+	down(&sn_hotplug_sem);
+	*value = sn_power_status_get(bss_hotplug_slot);
+	up(&sn_hotplug_sem);
+	return 0;
+}
+
+static void sn_release_slot(struct hotplug_slot *bss_hotplug_slot)
+{
+	kfree(bss_hotplug_slot->info);
+	kfree(bss_hotplug_slot->name);
+	kfree(bss_hotplug_slot->private);
+	kfree(bss_hotplug_slot);
+}
+
+static int sn_hotplug_slot_register(struct pci_bus *pci_bus)
+{
+	int device;
+	struct hotplug_slot *bss_hotplug_slot;
+	int rc = 0;
+
+	/*
+	 * Currently only four devices are supported,
+	 * in the future there maybe more -- up to 32.
+	 */
+
+	for (device = 0; device < SN_MAX_HP_SLOTS ; device++) {
+		if (sn_pci_slot_valid(pci_bus, device) != 1)
+			continue;
+
+		bss_hotplug_slot = kcalloc(1,sizeof(struct hotplug_slot),
+					   GFP_KERNEL);
+		if (!bss_hotplug_slot) {
+			rc = -ENOMEM;
+			goto alloc_err;
+		}
+
+		bss_hotplug_slot->info =
+			kcalloc(1,sizeof(struct hotplug_slot_info),
+				GFP_KERNEL);
+		if (!bss_hotplug_slot->info) {
+			rc = -ENOMEM;
+			goto alloc_err;
+		}
+
+		if (sn_hp_slot_private_alloc(bss_hotplug_slot,
+					     pci_bus, device)) {
+			rc = -ENOMEM;
+			goto alloc_err;
+		}
+
+		bss_hotplug_slot->ops = &sn_hotplug_slot_ops;
+		bss_hotplug_slot->release = &sn_release_slot;
+
+		rc = pci_hp_register(bss_hotplug_slot);
+		if (rc)
+			goto register_err;
+	}
+	dev_dbg(pci_bus->self, "Registered bus with hotplug\n");
+	return rc;
+
+register_err:
+	dev_dbg(pci_bus->self, "bus failed to register with err = %d\n",
+	        rc);
+
+alloc_err:
+	if (rc == -ENOMEM)
+		dev_dbg(pci_bus->self, "Memory allocation error\n");
+
+	/* destroy THIS element */
+	if (bss_hotplug_slot)
+		sn_release_slot(bss_hotplug_slot);
+
+	/* destroy anything else on the list */
+	while ((bss_hotplug_slot = sn_hp_destroy()))
+		pci_hp_deregister(bss_hotplug_slot);
+
+	return rc;
+}
+
+static int sn_pci_hotplug_init(void)
+{
+	struct pci_bus *pci_bus = NULL;
+	int rc;
+	int registered = 0;
+
+	INIT_LIST_HEAD(&sn_hp_list);
+
+	if (sn_sal_rev() < SGI_HOTPLUG_PROM_REV) {
+		printk(KERN_ERR "%s: PROM version must be greater than 4.05\n",
+		       __FUNCTION__);
+		return -EPERM;
+	}
+
+	while ((pci_bus = pci_find_next_bus(pci_bus))) {
+		if (!pci_bus->sysdata)
+			continue;
+
+		rc = sn_pci_bus_valid(pci_bus);
+		if (rc != 1) {
+			dev_dbg(pci_bus->self, "not a valid hotplug bus\n");
+			continue;
+		}
+		dev_dbg(pci_bus->self, "valid hotplug bus\n");
+
+		rc = sn_hotplug_slot_register(pci_bus);
+		if (!rc)
+			registered = 1;
+		else {
+			registered = 0;
+			break;
+		}
+	}
+
+	return registered == 1 ? 0 : -ENODEV;
+}
+
+static void sn_pci_hotplug_exit(void)
+{
+	struct hotplug_slot *bss_hotplug_slot;
+
+	while ((bss_hotplug_slot = sn_hp_destroy())) {
+		pci_hp_deregister(bss_hotplug_slot);
+	}
+
+	if (!list_empty(&sn_hp_list))
+		printk(KERN_ERR "%s: internal list is not empty\n", __FILE__);
+}
+
+module_init(sn_pci_hotplug_init);
+module_exit(sn_pci_hotplug_exit);
diff --git a/drivers/pci/hotplug/shpchp.h b/drivers/pci/hotplug/shpchp.h
--- a/drivers/pci/hotplug/shpchp.h
+++ b/drivers/pci/hotplug/shpchp.h
@@ -23,7 +23,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- * Send feedback to <greg@kroah.com>,<dely.l.sy@intel.com>
+ * Send feedback to <greg@kroah.com>,<kristen.c.accardi@intel.com>
  *
  */
 #ifndef _SHPCHP_H
diff --git a/drivers/pci/hotplug/shpchp_core.c b/drivers/pci/hotplug/shpchp_core.c
--- a/drivers/pci/hotplug/shpchp_core.c
+++ b/drivers/pci/hotplug/shpchp_core.c
@@ -23,7 +23,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- * Send feedback to <greg@kroah.com>, <dely.l.sy@intel.com>
+ * Send feedback to <greg@kroah.com>, <kristen.c.accardi@intel.com>
  *
  */
 
diff --git a/drivers/pci/hotplug/shpchp_ctrl.c b/drivers/pci/hotplug/shpchp_ctrl.c
--- a/drivers/pci/hotplug/shpchp_ctrl.c
+++ b/drivers/pci/hotplug/shpchp_ctrl.c
@@ -23,7 +23,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- * Send feedback to <greg@kroah.com>, <dely.l.sy@intel.com>
+ * Send feedback to <greg@kroah.com>, <kristen.c.accardi@intel.com>
  *
  */
 
diff --git a/drivers/pci/hotplug/shpchp_hpc.c b/drivers/pci/hotplug/shpchp_hpc.c
--- a/drivers/pci/hotplug/shpchp_hpc.c
+++ b/drivers/pci/hotplug/shpchp_hpc.c
@@ -23,7 +23,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- * Send feedback to <greg@kroah.com>,<dely.l.sy@intel.com>
+ * Send feedback to <greg@kroah.com>,<kristen.c.accardi@intel.com>
  *
  */
 
diff --git a/drivers/pci/hotplug/shpchp_pci.c b/drivers/pci/hotplug/shpchp_pci.c
--- a/drivers/pci/hotplug/shpchp_pci.c
+++ b/drivers/pci/hotplug/shpchp_pci.c
@@ -23,7 +23,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- * Send feedback to <greg@kroah.com>, <dely.l.sy@intel.com>
+ * Send feedback to <greg@kroah.com>, <kristen.c.accardi@intel.com>
  *
  */
 
diff --git a/drivers/pci/hotplug/shpchp_sysfs.c b/drivers/pci/hotplug/shpchp_sysfs.c
--- a/drivers/pci/hotplug/shpchp_sysfs.c
+++ b/drivers/pci/hotplug/shpchp_sysfs.c
@@ -38,7 +38,7 @@
 
 /* A few routines that create sysfs entries for the hot plug controller */
 
-static ssize_t show_ctrl (struct device *dev, char *buf)
+static ssize_t show_ctrl (struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct pci_dev *pci_dev;
 	struct controller *ctrl;
@@ -82,7 +82,7 @@ static ssize_t show_ctrl (struct device 
 }
 static DEVICE_ATTR (ctrl, S_IRUGO, show_ctrl, NULL);
 
-static ssize_t show_dev (struct device *dev, char *buf)
+static ssize_t show_dev (struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct pci_dev *pci_dev;
 	struct controller *ctrl;
diff --git a/drivers/pci/hotplug/shpchprm.h b/drivers/pci/hotplug/shpchprm.h
--- a/drivers/pci/hotplug/shpchprm.h
+++ b/drivers/pci/hotplug/shpchprm.h
@@ -23,7 +23,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- * Send feedback to <greg@kroah.com>, <dely.l.sy@intel.com>
+ * Send feedback to <greg@kroah.com>, <kristen.c.accardi@intel.com>
  *
  */
 
diff --git a/drivers/pci/hotplug/shpchprm_acpi.c b/drivers/pci/hotplug/shpchprm_acpi.c
--- a/drivers/pci/hotplug/shpchprm_acpi.c
+++ b/drivers/pci/hotplug/shpchprm_acpi.c
@@ -20,7 +20,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- * Send feedback to <dely.l.sy@intel.com>
+ * Send feedback to <kristen.c.accardi@intel.com>
  *
  */
 
diff --git a/drivers/pci/hotplug/shpchprm_legacy.c b/drivers/pci/hotplug/shpchprm_legacy.c
--- a/drivers/pci/hotplug/shpchprm_legacy.c
+++ b/drivers/pci/hotplug/shpchprm_legacy.c
@@ -23,7 +23,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- * Send feedback to <greg@kroah.com>,<dely.l.sy@intel.com>
+ * Send feedback to <greg@kroah.com>,<kristen.c.accardi@intel.com>
  *
  */
 
diff --git a/drivers/pci/hotplug/shpchprm_legacy.h b/drivers/pci/hotplug/shpchprm_legacy.h
--- a/drivers/pci/hotplug/shpchprm_legacy.h
+++ b/drivers/pci/hotplug/shpchprm_legacy.h
@@ -23,7 +23,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- * Send feedback to <greg@kroah.com>, <dely.l.sy@intel.com>
+ * Send feedback to <greg@kroah.com>, <kristen.c.accardi@intel.com>
  *
  */
 
diff --git a/drivers/pci/hotplug/shpchprm_nonacpi.c b/drivers/pci/hotplug/shpchprm_nonacpi.c
--- a/drivers/pci/hotplug/shpchprm_nonacpi.c
+++ b/drivers/pci/hotplug/shpchprm_nonacpi.c
@@ -23,7 +23,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- * Send feedback to <greg@kroah.com>, <dely.l.sy@intel.com>
+ * Send feedback to <greg@kroah.com>, <kristen.c.accardi@intel.com>
  *
  */
 
diff --git a/drivers/pci/hotplug/shpchprm_nonacpi.h b/drivers/pci/hotplug/shpchprm_nonacpi.h
--- a/drivers/pci/hotplug/shpchprm_nonacpi.h
+++ b/drivers/pci/hotplug/shpchprm_nonacpi.h
@@ -23,7 +23,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- * Send feedback to <greg@kroah.com>, <dely.l.sy@intel.com>
+ * Send feedback to <greg@kroah.com>, <kristen.c.accardi@intel.com>
  *
  */
 
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -28,10 +28,10 @@ static struct msi_desc* msi_desc[NR_IRQS
 static kmem_cache_t* msi_cachep;
 
 static int pci_msi_enable = 1;
-static int last_alloc_vector = 0;
-static int nr_released_vectors = 0;
+static int last_alloc_vector;
+static int nr_released_vectors;
 static int nr_reserved_vectors = NR_HP_RESERVED_VECTORS;
-static int nr_msix_devices = 0;
+static int nr_msix_devices;
 
 #ifndef CONFIG_X86_IO_APIC
 int vector_irq[NR_VECTORS] = { [0 ... NR_VECTORS - 1] = -1};
@@ -170,44 +170,30 @@ static unsigned int startup_msi_irq_wo_m
 	return 0;	/* never anything pending */
 }
 
-static void release_msi(unsigned int vector);
-static void shutdown_msi_irq(unsigned int vector)
-{
-	release_msi(vector);
-}
-
-#define shutdown_msi_irq_wo_maskbit	shutdown_msi_irq
-static void enable_msi_irq_wo_maskbit(unsigned int vector) {}
-static void disable_msi_irq_wo_maskbit(unsigned int vector) {}
-static void ack_msi_irq_wo_maskbit(unsigned int vector) {}
-static void end_msi_irq_wo_maskbit(unsigned int vector)
+static unsigned int startup_msi_irq_w_maskbit(unsigned int vector)
 {
-	move_msi(vector);
-	ack_APIC_irq();
+	startup_msi_irq_wo_maskbit(vector);
+	unmask_MSI_irq(vector);
+	return 0;	/* never anything pending */
 }
 
-static unsigned int startup_msi_irq_w_maskbit(unsigned int vector)
+static void shutdown_msi_irq(unsigned int vector)
 {
 	struct msi_desc *entry;
 	unsigned long flags;
 
 	spin_lock_irqsave(&msi_lock, flags);
 	entry = msi_desc[vector];
-	if (!entry || !entry->dev) {
-		spin_unlock_irqrestore(&msi_lock, flags);
-		return 0;
-	}
-	entry->msi_attrib.state = 1;	/* Mark it active */
+	if (entry && entry->dev)
+		entry->msi_attrib.state = 0;	/* Mark it not active */
 	spin_unlock_irqrestore(&msi_lock, flags);
-
-	unmask_MSI_irq(vector);
-	return 0;	/* never anything pending */
 }
 
-#define shutdown_msi_irq_w_maskbit	shutdown_msi_irq
-#define enable_msi_irq_w_maskbit	unmask_MSI_irq
-#define disable_msi_irq_w_maskbit	mask_MSI_irq
-#define ack_msi_irq_w_maskbit		mask_MSI_irq
+static void end_msi_irq_wo_maskbit(unsigned int vector)
+{
+	move_msi(vector);
+	ack_APIC_irq();
+}
 
 static void end_msi_irq_w_maskbit(unsigned int vector)
 {
@@ -216,6 +202,10 @@ static void end_msi_irq_w_maskbit(unsign
 	ack_APIC_irq();
 }
 
+static void do_nothing(unsigned int vector)
+{
+}
+
 /*
  * Interrupt Type for MSI-X PCI/PCI-X/PCI-Express Devices,
  * which implement the MSI-X Capability Structure.
@@ -223,10 +213,10 @@ static void end_msi_irq_w_maskbit(unsign
 static struct hw_interrupt_type msix_irq_type = {
 	.typename	= "PCI-MSI-X",
 	.startup	= startup_msi_irq_w_maskbit,
-	.shutdown	= shutdown_msi_irq_w_maskbit,
-	.enable		= enable_msi_irq_w_maskbit,
-	.disable	= disable_msi_irq_w_maskbit,
-	.ack		= ack_msi_irq_w_maskbit,
+	.shutdown	= shutdown_msi_irq,
+	.enable		= unmask_MSI_irq,
+	.disable	= mask_MSI_irq,
+	.ack		= mask_MSI_irq,
 	.end		= end_msi_irq_w_maskbit,
 	.set_affinity	= set_msi_irq_affinity
 };
@@ -239,10 +229,10 @@ static struct hw_interrupt_type msix_irq
 static struct hw_interrupt_type msi_irq_w_maskbit_type = {
 	.typename	= "PCI-MSI",
 	.startup	= startup_msi_irq_w_maskbit,
-	.shutdown	= shutdown_msi_irq_w_maskbit,
-	.enable		= enable_msi_irq_w_maskbit,
-	.disable	= disable_msi_irq_w_maskbit,
-	.ack		= ack_msi_irq_w_maskbit,
+	.shutdown	= shutdown_msi_irq,
+	.enable		= unmask_MSI_irq,
+	.disable	= mask_MSI_irq,
+	.ack		= mask_MSI_irq,
 	.end		= end_msi_irq_w_maskbit,
 	.set_affinity	= set_msi_irq_affinity
 };
@@ -255,10 +245,10 @@ static struct hw_interrupt_type msi_irq_
 static struct hw_interrupt_type msi_irq_wo_maskbit_type = {
 	.typename	= "PCI-MSI",
 	.startup	= startup_msi_irq_wo_maskbit,
-	.shutdown	= shutdown_msi_irq_wo_maskbit,
-	.enable		= enable_msi_irq_wo_maskbit,
-	.disable	= disable_msi_irq_wo_maskbit,
-	.ack		= ack_msi_irq_wo_maskbit,
+	.shutdown	= shutdown_msi_irq,
+	.enable		= do_nothing,
+	.disable	= do_nothing,
+	.ack		= do_nothing,
 	.end		= end_msi_irq_wo_maskbit,
 	.set_affinity	= set_msi_irq_affinity
 };
@@ -407,7 +397,7 @@ static struct msi_desc* alloc_msi_entry(
 {
 	struct msi_desc *entry;
 
-	entry = (struct msi_desc*) kmem_cache_alloc(msi_cachep, SLAB_KERNEL);
+	entry = kmem_cache_alloc(msi_cachep, SLAB_KERNEL);
 	if (!entry)
 		return NULL;
 
@@ -463,7 +453,7 @@ static void enable_msi_mode(struct pci_d
 	}
 }
 
-static void disable_msi_mode(struct pci_dev *dev, int pos, int type)
+void disable_msi_mode(struct pci_dev *dev, int pos, int type)
 {
 	u16 control;
 
@@ -709,6 +699,9 @@ int pci_enable_msi(struct pci_dev* dev)
 	if (!pci_msi_enable || !dev)
  		return status;
 
+	if (dev->no_msi)
+		return status;
+
 	temp = dev->irq;
 
 	if ((status = msi_init()) < 0)
@@ -796,18 +789,6 @@ void pci_disable_msi(struct pci_dev* dev
 	}
 }
 
-static void release_msi(unsigned int vector)
-{
-	struct msi_desc *entry;
-	unsigned long flags;
-
-	spin_lock_irqsave(&msi_lock, flags);
-	entry = msi_desc[vector];
-	if (entry && entry->dev)
-		entry->msi_attrib.state = 0;	/* Mark it not active */
-	spin_unlock_irqrestore(&msi_lock, flags);
-}
-
 static int msi_free_vector(struct pci_dev* dev, int vector, int reassign)
 {
 	struct msi_desc *entry;
@@ -924,7 +905,7 @@ static int reroute_msix_table(int head, 
 /**
  * pci_enable_msix - configure device's MSI-X capability structure
  * @dev: pointer to the pci_dev data structure of MSI-X device function
- * @data: pointer to an array of MSI-X entries
+ * @entries: pointer to an array of MSI-X entries
  * @nvec: number of MSI-X vectors requested for allocation by device driver
  *
  * Setup the MSI-X capability structure of device function with the number
diff --git a/drivers/pci/msi.h b/drivers/pci/msi.h
--- a/drivers/pci/msi.h
+++ b/drivers/pci/msi.h
@@ -41,11 +41,11 @@ static inline void move_msi(int vector) 
 #define PCI_MSIX_FLAGS_BIRMASK		(7 << 0)
 #define PCI_MSIX_FLAGS_BITMASK		(1 << 0)
 
-#define PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET	0
-#define PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET	4
-#define PCI_MSIX_ENTRY_DATA_OFFSET		8
-#define PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET	12
 #define PCI_MSIX_ENTRY_SIZE			16
+#define  PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET	0
+#define  PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET	4
+#define  PCI_MSIX_ENTRY_DATA_OFFSET		8
+#define  PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET	12
 
 #define msi_control_reg(base)		(base + PCI_MSI_FLAGS)
 #define msi_lower_address_reg(base)	(base + PCI_MSI_ADDRESS_LO)
@@ -64,7 +64,6 @@ static inline void move_msi(int vector) 
 #define msi_enable(control, num) multi_msi_enable(control, num); \
 	control |= PCI_MSI_FLAGS_ENABLE
 
-#define msix_control_reg		msi_control_reg
 #define msix_table_offset_reg(base)	(base + 0x04)
 #define msix_pba_offset_reg(base)	(base + 0x08)
 #define msix_enable(control)	 	control |= PCI_MSIX_FLAGS_ENABLE
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
--- a/drivers/pci/pci-acpi.c
+++ b/drivers/pci/pci-acpi.c
@@ -1,9 +1,10 @@
 /*
  * File:	pci-acpi.c
- * Purpose:	Provide PCI supports in ACPI
+ * Purpose:	Provide PCI support in ACPI
  *
- * Copyright (C) 2004 Intel
- * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com)
+ * Copyright (C) 2005 David Shaohua Li <shaohua.li@intel.com>
+ * Copyright (C) 2004 Tom Long Nguyen <tom.l.nguyen@intel.com>
+ * Copyright (C) 2004 Intel Corp.
  */
 
 #include <linux/delay.h>
@@ -16,6 +17,7 @@
 #include <acpi/acpi_bus.h>
 
 #include <linux/pci-acpi.h>
+#include "pci.h"
 
 static u32 ctrlset_buf[3] = {0, 0, 0};
 static u32 global_ctrlsets = 0;
@@ -207,3 +209,105 @@ acpi_status pci_osc_control_set(u32 flag
 	return status;
 }
 EXPORT_SYMBOL(pci_osc_control_set);
+
+/*
+ * _SxD returns the D-state with the highest power
+ * (lowest D-state number) supported in the S-state "x".
+ *
+ * If the devices does not have a _PRW
+ * (Power Resources for Wake) supporting system wakeup from "x"
+ * then the OS is free to choose a lower power (higher number
+ * D-state) than the return value from _SxD.
+ *
+ * But if _PRW is enabled at S-state "x", the OS
+ * must not choose a power lower than _SxD --
+ * unless the device has an _SxW method specifying
+ * the lowest power (highest D-state number) the device
+ * may enter while still able to wake the system.
+ *
+ * ie. depending on global OS policy:
+ *
+ * if (_PRW at S-state x)
+ *	choose from highest power _SxD to lowest power _SxW
+ * else // no _PRW at S-state x
+ * 	choose highest power _SxD or any lower power
+ *
+ * currently we simply return _SxD, if present.
+ */
+
+static int acpi_pci_choose_state(struct pci_dev *pdev, pm_message_t state)
+{
+	/* TBD */
+
+	return -ENODEV;
+}
+
+static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state)
+{
+	acpi_handle handle = DEVICE_ACPI_HANDLE(&dev->dev);
+	static int state_conv[] = {
+		[0] = 0,
+		[1] = 1,
+		[2] = 2,
+		[3] = 3,
+		[4] = 3
+	};
+	int acpi_state = state_conv[(int __force) state];
+
+	if (!handle)
+		return -ENODEV;
+	return acpi_bus_set_power(handle, acpi_state);
+}
+
+
+/* ACPI bus type */
+static int pci_acpi_find_device(struct device *dev, acpi_handle *handle)
+{
+	struct pci_dev * pci_dev;
+	acpi_integer	addr;
+
+	pci_dev = to_pci_dev(dev);
+	/* Please ref to ACPI spec for the syntax of _ADR */
+	addr = (PCI_SLOT(pci_dev->devfn) << 16) | PCI_FUNC(pci_dev->devfn);
+	*handle = acpi_get_child(DEVICE_ACPI_HANDLE(dev->parent), addr);
+	if (!*handle)
+		return -ENODEV;
+	return 0;
+}
+
+static int pci_acpi_find_root_bridge(struct device *dev, acpi_handle *handle)
+{
+	int num;
+	unsigned int seg, bus;
+
+	/*
+	 * The string should be the same as root bridge's name
+	 * Please look at 'pci_scan_bus_parented'
+	 */
+	num = sscanf(dev->bus_id, "pci%04x:%02x", &seg, &bus);
+	if (num != 2)
+		return -ENODEV;
+	*handle = acpi_get_pci_rootbridge_handle(seg, bus);
+	if (!*handle)
+		return -ENODEV;
+	return 0;
+}
+
+static struct acpi_bus_type pci_acpi_bus = {
+	.bus = &pci_bus_type,
+	.find_device = pci_acpi_find_device,
+	.find_bridge = pci_acpi_find_root_bridge,
+};
+
+static int __init pci_acpi_init(void)
+{
+	int ret;
+
+	ret = register_acpi_bus_type(&pci_acpi_bus);
+	if (ret)
+		return 0;
+	platform_pci_choose_state = acpi_pci_choose_state;
+	platform_pci_set_power_state = acpi_pci_set_power_state;
+	return 0;
+}
+arch_initcall(pci_acpi_init);
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -7,7 +7,6 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/device.h>
-#include <linux/pci-dynids.h>
 #include "pci.h"
 
 /*
@@ -18,36 +17,12 @@
  * Dynamic device IDs are disabled for !CONFIG_HOTPLUG
  */
 
-#ifdef CONFIG_HOTPLUG
-/**
- * pci_device_probe_dynamic()
- *
- * Walk the dynamic ID list looking for a match.
- * returns 0 and sets pci_dev->driver when drv claims pci_dev, else error.
- */
-static int
-pci_device_probe_dynamic(struct pci_driver *drv, struct pci_dev *pci_dev)
-{
-	int error = -ENODEV;
-	struct list_head *pos;
-	struct dynid *dynid;
+struct pci_dynid {
+	struct list_head node;
+	struct pci_device_id id;
+};
 
-	spin_lock(&drv->dynids.lock);
-	list_for_each(pos, &drv->dynids.list) {
-		dynid = list_entry(pos, struct dynid, node);
-		if (pci_match_one_device(&dynid->id, pci_dev)) {
-			spin_unlock(&drv->dynids.lock);
-			error = drv->probe(pci_dev, &dynid->id);
-			if (error >= 0) {
-				pci_dev->driver = drv;
-				return 0;
-			}
-			return error;
-		}
-	}
-	spin_unlock(&drv->dynids.lock);
-	return error;
-}
+#ifdef CONFIG_HOTPLUG
 
 /**
  * store_new_id
@@ -58,8 +33,7 @@ pci_device_probe_dynamic(struct pci_driv
 static inline ssize_t
 store_new_id(struct device_driver *driver, const char *buf, size_t count)
 {
-	struct dynid *dynid;
-	struct bus_type * bus;
+	struct pci_dynid *dynid;
 	struct pci_driver *pdrv = to_pci_driver(driver);
 	__u32 vendor=PCI_ANY_ID, device=PCI_ANY_ID, subvendor=PCI_ANY_ID,
 		subdevice=PCI_ANY_ID, class=0, class_mask=0;
@@ -91,37 +65,22 @@ store_new_id(struct device_driver *drive
 	list_add_tail(&pdrv->dynids.list, &dynid->node);
 	spin_unlock(&pdrv->dynids.lock);
 
-	bus = get_bus(pdrv->driver.bus);
-	if (bus) {
-		if (get_driver(&pdrv->driver)) {
-			down_write(&bus->subsys.rwsem);
-			driver_attach(&pdrv->driver);
-			up_write(&bus->subsys.rwsem);
-			put_driver(&pdrv->driver);
-		}
-		put_bus(bus);
+	if (get_driver(&pdrv->driver)) {
+		driver_attach(&pdrv->driver);
+		put_driver(&pdrv->driver);
 	}
 
 	return count;
 }
-
 static DRIVER_ATTR(new_id, S_IWUSR, NULL, store_new_id);
-static inline void
-pci_init_dynids(struct pci_dynids *dynids)
-{
-	spin_lock_init(&dynids->lock);
-	INIT_LIST_HEAD(&dynids->list);
-}
 
 static void
 pci_free_dynids(struct pci_driver *drv)
 {
-	struct list_head *pos, *n;
-	struct dynid *dynid;
+	struct pci_dynid *dynid, *n;
 
 	spin_lock(&drv->dynids.lock);
-	list_for_each_safe(pos, n, &drv->dynids.list) {
-		dynid = list_entry(pos, struct dynid, node);
+	list_for_each_entry_safe(dynid, n, &drv->dynids.list, node) {
 		list_del(&dynid->node);
 		kfree(dynid);
 	}
@@ -138,83 +97,70 @@ pci_create_newid_file(struct pci_driver 
 	return error;
 }
 
-static int
-pci_bus_match_dynids(const struct pci_dev *pci_dev, struct pci_driver *pci_drv)
-{
-	struct list_head *pos;
-	struct dynid *dynid;
-
-	spin_lock(&pci_drv->dynids.lock);
-	list_for_each(pos, &pci_drv->dynids.list) {
-		dynid = list_entry(pos, struct dynid, node);
-		if (pci_match_one_device(&dynid->id, pci_dev)) {
-			spin_unlock(&pci_drv->dynids.lock);
-			return 1;
-		}
-	}
-	spin_unlock(&pci_drv->dynids.lock);
-	return 0;
-}
-
 #else /* !CONFIG_HOTPLUG */
-static inline int pci_device_probe_dynamic(struct pci_driver *drv, struct pci_dev *pci_dev)
-{
-	return -ENODEV;
-}
-static inline void pci_init_dynids(struct pci_dynids *dynids) {}
 static inline void pci_free_dynids(struct pci_driver *drv) {}
 static inline int pci_create_newid_file(struct pci_driver *drv)
 {
 	return 0;
 }
-static inline int pci_bus_match_dynids(const struct pci_dev *pci_dev, struct pci_driver *pci_drv)
-{
-	return 0;
-}
 #endif
 
 /**
- * pci_match_device - Tell if a PCI device structure has a matching
- *                    PCI device id structure
+ * pci_match_id - See if a pci device matches a given pci_id table
  * @ids: array of PCI device id structures to search in
- * @dev: the PCI device structure to match against
- * 
+ * @dev: the PCI device structure to match against.
+ *
  * Used by a driver to check whether a PCI device present in the
- * system is in its list of supported devices.Returns the matching
+ * system is in its list of supported devices.  Returns the matching
  * pci_device_id structure or %NULL if there is no match.
+ *
+ * Depreciated, don't use this as it will not catch any dynamic ids
+ * that a driver might want to check for.
  */
-const struct pci_device_id *
-pci_match_device(const struct pci_device_id *ids, const struct pci_dev *dev)
+const struct pci_device_id *pci_match_id(const struct pci_device_id *ids,
+					 struct pci_dev *dev)
 {
-	while (ids->vendor || ids->subvendor || ids->class_mask) {
-		if (pci_match_one_device(ids, dev))
-			return ids;
-		ids++;
+	if (ids) {
+		while (ids->vendor || ids->subvendor || ids->class_mask) {
+			if (pci_match_one_device(ids, dev))
+				return ids;
+			ids++;
+		}
 	}
 	return NULL;
 }
 
 /**
- * pci_device_probe_static()
- * 
- * returns 0 and sets pci_dev->driver when drv claims pci_dev, else error.
+ * pci_match_device - Tell if a PCI device structure has a matching
+ *                    PCI device id structure
+ * @ids: array of PCI device id structures to search in
+ * @dev: the PCI device structure to match against
+ * @drv: the PCI driver to match against
+ *
+ * Used by a driver to check whether a PCI device present in the
+ * system is in its list of supported devices.  Returns the matching
+ * pci_device_id structure or %NULL if there is no match.
  */
-static int
-pci_device_probe_static(struct pci_driver *drv, struct pci_dev *pci_dev)
-{		   
-	int error = -ENODEV;
+const struct pci_device_id *pci_match_device(struct pci_driver *drv,
+					     struct pci_dev *dev)
+{
 	const struct pci_device_id *id;
+	struct pci_dynid *dynid;
 
-	if (!drv->id_table)
-		return error;
-	id = pci_match_device(drv->id_table, pci_dev);
+	id = pci_match_id(drv->id_table, dev);
 	if (id)
-		error = drv->probe(pci_dev, id);
-	if (error >= 0) {
-		pci_dev->driver = drv;
-		error = 0;
+		return id;
+
+	/* static ids didn't match, lets look at the dynamic ones */
+	spin_lock(&drv->dynids.lock);
+	list_for_each_entry(dynid, &drv->dynids.list, node) {
+		if (pci_match_one_device(&dynid->id, dev)) {
+			spin_unlock(&drv->dynids.lock);
+			return &dynid->id;
+		}
 	}
-	return error;
+	spin_unlock(&drv->dynids.lock);
+	return NULL;
 }
 
 /**
@@ -225,13 +171,20 @@ pci_device_probe_static(struct pci_drive
  */
 static int
 __pci_device_probe(struct pci_driver *drv, struct pci_dev *pci_dev)
-{		   
+{
+	const struct pci_device_id *id;
 	int error = 0;
 
 	if (!pci_dev->driver && drv->probe) {
-		error = pci_device_probe_static(drv, pci_dev);
-		if (error == -ENODEV)
-			error = pci_device_probe_dynamic(drv, pci_dev);
+		error = -ENODEV;
+
+		id = pci_match_device(drv, pci_dev);
+		if (id)
+			error = drv->probe(pci_dev, id);
+		if (error >= 0) {
+			pci_dev->driver = drv;
+			error = 0;
+		}
 	}
 	return error;
 }
@@ -335,13 +288,14 @@ pci_driver_attr_show(struct kobject * ko
 {
 	struct device_driver *driver = kobj_to_pci_driver(kobj);
 	struct driver_attribute *dattr = attr_to_driver_attribute(attr);
-	ssize_t ret = 0;
+	ssize_t ret;
 
-	if (get_driver(driver)) {
-		if (dattr->show)
-			ret = dattr->show(driver, buf);
-		put_driver(driver);
-	}
+	if (!get_driver(driver))
+		return -ENODEV;
+
+	ret = dattr->show ? dattr->show(driver, buf) : -EIO;
+
+	put_driver(driver);
 	return ret;
 }
 
@@ -351,13 +305,14 @@ pci_driver_attr_store(struct kobject * k
 {
 	struct device_driver *driver = kobj_to_pci_driver(kobj);
 	struct driver_attribute *dattr = attr_to_driver_attribute(attr);
-	ssize_t ret = 0;
+	ssize_t ret;
 
-	if (get_driver(driver)) {
-		if (dattr->store)
-			ret = dattr->store(driver, buf, count);
-		put_driver(driver);
-	}
+	if (!get_driver(driver))
+		return -ENODEV;
+
+	ret = dattr->store ? dattr->store(driver, buf, count) : -EIO;
+
+	put_driver(driver);
 	return ret;
 }
 
@@ -369,12 +324,6 @@ static struct kobj_type pci_driver_kobj_
 	.sysfs_ops = &pci_driver_sysfs_ops,
 };
 
-static int
-pci_populate_driver_dir(struct pci_driver *drv)
-{
-	return pci_create_newid_file(drv);
-}
-
 /**
  * pci_register_driver - register a new pci driver
  * @drv: the driver structure to register
@@ -396,16 +345,18 @@ int pci_register_driver(struct pci_drive
 	/* FIXME, once all of the existing PCI drivers have been fixed to set
 	 * the pci shutdown function, this test can go away. */
 	if (!drv->driver.shutdown)
-		drv->driver.shutdown = pci_device_shutdown,
+		drv->driver.shutdown = pci_device_shutdown;
 	drv->driver.owner = drv->owner;
 	drv->driver.kobj.ktype = &pci_driver_kobj_type;
-	pci_init_dynids(&drv->dynids);
+
+	spin_lock_init(&drv->dynids.lock);
+	INIT_LIST_HEAD(&drv->dynids.list);
 
 	/* register with core */
 	error = driver_register(&drv->driver);
 
 	if (!error)
-		pci_populate_driver_dir(drv);
+		error = pci_create_newid_file(drv);
 
 	return error;
 }
@@ -461,21 +412,17 @@ pci_dev_driver(const struct pci_dev *dev
  * system is in its list of supported devices.Returns the matching
  * pci_device_id structure or %NULL if there is no match.
  */
-static int pci_bus_match(struct device * dev, struct device_driver * drv) 
+static int pci_bus_match(struct device *dev, struct device_driver *drv)
 {
-	const struct pci_dev * pci_dev = to_pci_dev(dev);
-	struct pci_driver * pci_drv = to_pci_driver(drv);
-	const struct pci_device_id * ids = pci_drv->id_table;
+	struct pci_dev *pci_dev = to_pci_dev(dev);
+	struct pci_driver *pci_drv = to_pci_driver(drv);
 	const struct pci_device_id *found_id;
 
-	if (!ids)
-		return 0;
-
-	found_id = pci_match_device(ids, pci_dev);
+	found_id = pci_match_device(pci_drv, pci_dev);
 	if (found_id)
 		return 1;
 
-	return pci_bus_match_dynids(pci_dev, pci_drv);
+	return 0;
 }
 
 /**
@@ -534,6 +481,7 @@ static int __init pci_driver_init(void)
 
 postcore_initcall(pci_driver_init);
 
+EXPORT_SYMBOL(pci_match_id);
 EXPORT_SYMBOL(pci_match_device);
 EXPORT_SYMBOL(pci_register_driver);
 EXPORT_SYMBOL(pci_unregister_driver);
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -29,7 +29,7 @@ static int sysfs_initialized;	/* = 0 */
 /* show configuration fields */
 #define pci_config_attr(field, format_string)				\
 static ssize_t								\
-field##_show(struct device *dev, char *buf)				\
+field##_show(struct device *dev, struct device_attribute *attr, char *buf)				\
 {									\
 	struct pci_dev *pdev;						\
 									\
@@ -44,7 +44,7 @@ pci_config_attr(subsystem_device, "0x%04
 pci_config_attr(class, "0x%06x\n");
 pci_config_attr(irq, "%u\n");
 
-static ssize_t local_cpus_show(struct device *dev, char *buf)
+static ssize_t local_cpus_show(struct device *dev, struct device_attribute *attr, char *buf)
 {		
 	cpumask_t mask = pcibus_to_cpumask(to_pci_dev(dev)->bus);
 	int len = cpumask_scnprintf(buf, PAGE_SIZE-2, mask);
@@ -54,26 +54,29 @@ static ssize_t local_cpus_show(struct de
 
 /* show resources */
 static ssize_t
-resource_show(struct device * dev, char * buf)
+resource_show(struct device * dev, struct device_attribute *attr, char * buf)
 {
 	struct pci_dev * pci_dev = to_pci_dev(dev);
 	char * str = buf;
 	int i;
 	int max = 7;
+	u64 start, end;
 
 	if (pci_dev->subordinate)
 		max = DEVICE_COUNT_RESOURCE;
 
 	for (i = 0; i < max; i++) {
-		str += sprintf(str,"0x%016lx 0x%016lx 0x%016lx\n",
-			       pci_resource_start(pci_dev,i),
-			       pci_resource_end(pci_dev,i),
-			       pci_resource_flags(pci_dev,i));
+		struct resource *res =  &pci_dev->resource[i];
+		pci_resource_to_user(pci_dev, i, res, &start, &end);
+		str += sprintf(str,"0x%016llx 0x%016llx 0x%016llx\n",
+			       (unsigned long long)start,
+			       (unsigned long long)end,
+			       (unsigned long long)res->flags);
 	}
 	return (str - buf);
 }
 
-static ssize_t modalias_show(struct device *dev, char *buf)
+static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct pci_dev *pci_dev = to_pci_dev(dev);
 
@@ -313,8 +316,21 @@ pci_mmap_resource(struct kobject *kobj, 
 						       struct device, kobj));
 	struct resource *res = (struct resource *)attr->private;
 	enum pci_mmap_state mmap_type;
+	u64 start, end;
+	int i;
 
-	vma->vm_pgoff += res->start >> PAGE_SHIFT;
+	for (i = 0; i < PCI_ROM_RESOURCE; i++)
+		if (res == &pdev->resource[i])
+			break;
+	if (i >= PCI_ROM_RESOURCE)
+		return -ENODEV;
+
+	/* pci_mmap_page_range() expects the same kind of entry as coming
+	 * from /proc/bus/pci/ which is a "user visible" value. If this is
+	 * different from the resource itself, arch will do necessary fixup.
+	 */
+	pci_resource_to_user(pdev, i, res, &start, &end);
+	vma->vm_pgoff += start >> PAGE_SHIFT;
 	mmap_type = res->flags & IORESOURCE_MEM ? pci_mmap_mem : pci_mmap_io;
 
 	return pci_mmap_page_range(pdev, vma, mmap_type, 0);
@@ -339,16 +355,17 @@ pci_create_resource_files(struct pci_dev
 		if (!pci_resource_len(pdev, i))
 			continue;
 
-		res_attr = kmalloc(sizeof(*res_attr) + 10, GFP_ATOMIC);
+		/* allocate attribute structure, piggyback attribute name */
+		res_attr = kcalloc(1, sizeof(*res_attr) + 10, GFP_ATOMIC);
 		if (res_attr) {
-			memset(res_attr, 0, sizeof(*res_attr) + 10);
+			char *res_attr_name = (char *)(res_attr + 1);
+
 			pdev->res_attr[i] = res_attr;
-			/* Allocated above after the res_attr struct */
-			res_attr->attr.name = (char *)(res_attr + 1);
-			sprintf(res_attr->attr.name, "resource%d", i);
-			res_attr->size = pci_resource_len(pdev, i);
+			sprintf(res_attr_name, "resource%d", i);
+			res_attr->attr.name = res_attr_name;
 			res_attr->attr.mode = S_IRUSR | S_IWUSR;
 			res_attr->attr.owner = THIS_MODULE;
+			res_attr->size = pci_resource_len(pdev, i);
 			res_attr->mmap = pci_mmap_resource;
 			res_attr->private = &pdev->resource[i];
 			sysfs_create_bin_file(&pdev->dev.kobj, res_attr);
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -235,7 +235,7 @@ pci_find_parent_resource(const struct pc
  * -EIO if device does not support PCI PM.
  * 0 if we can successfully change the power state.
  */
-
+int (*platform_pci_set_power_state)(struct pci_dev *dev, pci_power_t t);
 int
 pci_set_power_state(struct pci_dev *dev, pci_power_t state)
 {
@@ -299,11 +299,20 @@ pci_set_power_state(struct pci_dev *dev,
 		msleep(10);
 	else if (state == PCI_D2 || dev->current_state == PCI_D2)
 		udelay(200);
-	dev->current_state = state;
 
+	/*
+	 * Give firmware a chance to be called, such as ACPI _PRx, _PSx
+	 * Firmware method after natice method ?
+	 */
+	if (platform_pci_set_power_state)
+		platform_pci_set_power_state(dev, state);
+
+	dev->current_state = state;
 	return 0;
 }
 
+int (*platform_pci_choose_state)(struct pci_dev *dev, pm_message_t state);
+ 
 /**
  * pci_choose_state - Choose the power state of a PCI device
  * @dev: PCI device to be suspended
@@ -316,10 +325,17 @@ pci_set_power_state(struct pci_dev *dev,
 
 pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state)
 {
+	int ret;
+
 	if (!pci_find_capability(dev, PCI_CAP_ID_PM))
 		return PCI_D0;
 
-	switch (state) {
+	if (platform_pci_choose_state) {
+		ret = platform_pci_choose_state(dev, state);
+		if (ret >= 0)
+			state = ret;
+	}
+ 	switch (state) {
 	case 0: return PCI_D0;
 	case 3: return PCI_D3hot;
 	default:
@@ -334,10 +350,6 @@ EXPORT_SYMBOL(pci_choose_state);
 /**
  * pci_save_state - save the PCI configuration space of a device before suspending
  * @dev: - PCI device that we're dealing with
- * @buffer: - buffer to hold config space context
- *
- * @buffer must be large enough to hold the entire PCI 2.2 config space 
- * (>= 64 bytes).
  */
 int
 pci_save_state(struct pci_dev *dev)
@@ -352,8 +364,6 @@ pci_save_state(struct pci_dev *dev)
 /** 
  * pci_restore_state - Restore the saved state of a PCI device
  * @dev: - PCI device that we're dealing with
- * @buffer: - saved PCI config space
- *
  */
 int 
 pci_restore_state(struct pci_dev *dev)
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -11,6 +11,10 @@ extern int pci_bus_alloc_resource(struct
 				  void (*alignf)(void *, struct resource *,
 					  	 unsigned long, unsigned long),
 				  void *alignf_data);
+/* Firmware callbacks */
+extern int (*platform_pci_choose_state)(struct pci_dev *dev, pm_message_t state);
+extern int (*platform_pci_set_power_state)(struct pci_dev *dev, pci_power_t state);
+
 /* PCI /proc functions */
 #ifdef CONFIG_PROC_FS
 extern int pci_proc_attach_device(struct pci_dev *dev);
@@ -43,6 +47,12 @@ extern int pci_msi_quirk;
 #define pci_msi_quirk 0
 #endif
 
+#ifdef CONFIG_PCI_MSI
+void disable_msi_mode(struct pci_dev *dev, int pos, int type);
+#else
+static inline void disable_msi_mode(struct pci_dev *dev, int pos, int type) { }
+#endif
+
 extern int pcie_mch_quirk;
 extern struct device_attribute pci_dev_attrs[];
 extern struct class_device_attribute class_device_attr_cpuaffinity;
diff --git a/drivers/pci/pcie/portdrv.h b/drivers/pci/pcie/portdrv.h
--- a/drivers/pci/pcie/portdrv.h
+++ b/drivers/pci/pcie/portdrv.h
@@ -27,6 +27,11 @@
 
 #define get_descriptor_id(type, service) (((type - 4) << 4) | service)
 
+struct pcie_port_device_ext {
+	int interrupt_mode;	/* [0:INTx | 1:MSI | 2:MSI-X] */
+	unsigned int saved_msi_config_space[5];
+};
+
 extern struct bus_type pcie_port_bus_type;
 extern int pcie_port_device_probe(struct pci_dev *dev);
 extern int pcie_port_device_register(struct pci_dev *dev);
diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c
--- a/drivers/pci/pcie/portdrv_core.c
+++ b/drivers/pci/pcie/portdrv_core.c
@@ -232,19 +232,16 @@ static void pcie_device_init(struct pci_
 	/* Initialize generic device interface */
 	device = &dev->device;
 	memset(device, 0, sizeof(struct device));
-	INIT_LIST_HEAD(&device->node);
-	INIT_LIST_HEAD(&device->children);
-	INIT_LIST_HEAD(&device->bus_list);
 	device->bus = &pcie_port_bus_type;
 	device->driver = NULL;
-	device->driver_data = NULL; 
+	device->driver_data = NULL;
 	device->release = release_pcie_device;	/* callback to free pcie dev */
-	sprintf(&device->bus_id[0], "pcie%02x", 
+	sprintf(&device->bus_id[0], "pcie%02x",
 		get_descriptor_id(port_type, service_type));
 	device->parent = &parent->dev;
 }
 
-static struct pcie_device* alloc_pcie_device(struct pci_dev *parent, 
+static struct pcie_device* alloc_pcie_device(struct pci_dev *parent,
 	int port_type, int service_type, int irq, int irq_mode)
 {
 	struct pcie_device *device;
@@ -270,27 +267,35 @@ int pcie_port_device_probe(struct pci_de
 	pci_read_config_word(dev, pos + PCIE_CAPABILITIES_REG, &reg);
 	type = (reg >> 4) & PORT_TYPE_MASK;
 	if (	type == PCIE_RC_PORT || type == PCIE_SW_UPSTREAM_PORT ||
-		type == PCIE_SW_DOWNSTREAM_PORT )  
+		type == PCIE_SW_DOWNSTREAM_PORT )
 		return 0;
- 
+
 	return -ENODEV;
 }
 
 int pcie_port_device_register(struct pci_dev *dev)
 {
+	struct pcie_port_device_ext *p_ext;
 	int status, type, capabilities, irq_mode, i;
 	int vectors[PCIE_PORT_DEVICE_MAXSERVICES];
 	u16 reg16;
 
+	/* Allocate port device extension */
+	if (!(p_ext = kmalloc(sizeof(struct pcie_port_device_ext), GFP_KERNEL)))
+		return -ENOMEM;
+
+	pci_set_drvdata(dev, p_ext);
+
 	/* Get port type */
-	pci_read_config_word(dev, 
-		pci_find_capability(dev, PCI_CAP_ID_EXP) + 
+	pci_read_config_word(dev,
+		pci_find_capability(dev, PCI_CAP_ID_EXP) +
 		PCIE_CAPABILITIES_REG, &reg16);
 	type = (reg16 >> 4) & PORT_TYPE_MASK;
 
 	/* Now get port services */
 	capabilities = get_port_device_capability(dev);
 	irq_mode = assign_interrupt_mode(dev, vectors, capabilities);
+	p_ext->interrupt_mode = irq_mode;
 
 	/* Allocate child services if any */
 	for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) {
@@ -299,11 +304,11 @@ int pcie_port_device_register(struct pci
 		if (capabilities & (1 << i)) {
 			child = alloc_pcie_device(
 				dev, 		/* parent */
-				type,		/* port type */ 
+				type,		/* port type */
 				i,		/* service type */
 				vectors[i],	/* irq */
 				irq_mode	/* interrupt mode */);
-			if (child) { 
+			if (child) {
 				status = device_register(&child->device);
 				if (status) {
 					kfree(child);
@@ -317,84 +322,78 @@ int pcie_port_device_register(struct pci
 }
 
 #ifdef CONFIG_PM
-int pcie_port_device_suspend(struct pci_dev *dev, pm_message_t state)
+static int suspend_iter(struct device *dev, void *data)
 {
-	struct list_head 		*head, *tmp;
-	struct device 			*parent, *child;
-	struct device_driver 		*driver;
 	struct pcie_port_service_driver *service_driver;
+	pm_message_t state = * (pm_message_t *) data;
 
-	parent = &dev->dev;
-	head = &parent->children;
-	tmp = head->next;
-	while (head != tmp) {
-		child = container_of(tmp, struct device, node);
-		tmp = tmp->next;
-		if (child->bus != &pcie_port_bus_type)
-			continue;
-		driver = child->driver;
-		if (!driver)
-			continue;
-		service_driver = to_service_driver(driver);
-		if (service_driver->suspend)  
-			service_driver->suspend(to_pcie_device(child), state);
-	}
-	return 0; 
+ 	if ((dev->bus == &pcie_port_bus_type) &&
+ 	    (dev->driver)) {
+ 		service_driver = to_service_driver(dev->driver);
+ 		if (service_driver->suspend)
+ 			service_driver->suspend(to_pcie_device(dev), state);
+  	}
+	return 0;
+}
+
+int pcie_port_device_suspend(struct pci_dev *dev, pm_message_t state)
+{
+	device_for_each_child(&dev->dev, &state, suspend_iter);
+	return 0;
 }
 
-int pcie_port_device_resume(struct pci_dev *dev) 
-{ 
-	struct list_head 		*head, *tmp;
-	struct device 			*parent, *child;
-	struct device_driver 		*driver;
+static int resume_iter(struct device *dev, void *data)
+{
 	struct pcie_port_service_driver *service_driver;
 
-	parent = &dev->dev;
-	head = &parent->children;
-	tmp = head->next;
-	while (head != tmp) {
-		child = container_of(tmp, struct device, node);
-		tmp = tmp->next;
-		if (child->bus != &pcie_port_bus_type)
-			continue;
-		driver = child->driver;
-		if (!driver)
-			continue;
-		service_driver = to_service_driver(driver);
-		if (service_driver->resume)  
-			service_driver->resume(to_pcie_device(child));
+	if ((dev->bus == &pcie_port_bus_type) &&
+	    (dev->driver)) {
+		service_driver = to_service_driver(dev->driver);
+		if (service_driver->resume)
+			service_driver->resume(to_pcie_device(dev));
 	}
-	return 0; 
+	return 0;
+}
 
+int pcie_port_device_resume(struct pci_dev *dev)
+{
+	device_for_each_child(&dev->dev, NULL, resume_iter);
+	return 0;
 }
 #endif
 
-void pcie_port_device_remove(struct pci_dev *dev)
+static int remove_iter(struct device *dev, void *data)
 {
-	struct list_head 		*head, *tmp;
-	struct device 			*parent, *child;
-	struct device_driver 		*driver;
 	struct pcie_port_service_driver *service_driver;
-	int interrupt_mode = PCIE_PORT_INTx_MODE;
 
-	parent = &dev->dev;
-	head = &parent->children;
-	tmp = head->next;
-	while (head != tmp) {
-		child = container_of(tmp, struct device, node);
-		tmp = tmp->next;
-		if (child->bus != &pcie_port_bus_type)
-			continue;
-		driver = child->driver;
-		if (driver) { 
-			service_driver = to_service_driver(driver);
-			if (service_driver->remove)  
-				service_driver->remove(to_pcie_device(child));
+	if (dev->bus == &pcie_port_bus_type) {
+		if (dev->driver) {
+			service_driver = to_service_driver(dev->driver);
+			if (service_driver->remove)
+				service_driver->remove(to_pcie_device(dev));
 		}
-		interrupt_mode = (to_pcie_device(child))->interrupt_mode;
-		put_device(child);
-		device_unregister(child);
+		*(unsigned long*)data = (unsigned long)dev;
+		return 1;
 	}
+	return 0;
+}
+
+void pcie_port_device_remove(struct pci_dev *dev)
+{
+	struct device *device;
+	unsigned long device_addr;
+	int interrupt_mode = PCIE_PORT_INTx_MODE;
+	int status;
+
+	do {
+		status = device_for_each_child(&dev->dev, &device_addr, remove_iter);
+		if (status) {
+			device = (struct device*)device_addr;
+			interrupt_mode = (to_pcie_device(device))->interrupt_mode;
+			put_device(device);
+			device_unregister(device);
+		}
+	} while (status);
 	/* Switch to INTx by default if MSI enabled */
 	if (interrupt_mode == PCIE_PORT_MSIX_MODE)
 		pci_disable_msix(dev);
@@ -423,7 +422,7 @@ int pcie_port_service_register(struct pc
 	new->driver.resume = pcie_port_resume_service;
 
 	return driver_register(&new->driver);
-} 
+}
 
 void pcie_port_service_unregister(struct pcie_port_service_driver *new)
 {
diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c
--- a/drivers/pci/pcie/portdrv_pci.c
+++ b/drivers/pci/pcie/portdrv_pci.c
@@ -29,6 +29,78 @@ MODULE_LICENSE("GPL");
 /* global data */
 static const char device_name[] = "pcieport-driver";
 
+static void pci_save_msi_state(struct pci_dev *dev)
+{
+	struct pcie_port_device_ext *p_ext = pci_get_drvdata(dev);
+	int i = 0, pos;
+	u16 control;
+
+   	if ((pos = pci_find_capability(dev, PCI_CAP_ID_MSI)) <= 0)
+		return;
+
+	pci_read_config_dword(dev, pos, &p_ext->saved_msi_config_space[i++]);
+	control = p_ext->saved_msi_config_space[0] >> 16;
+	pci_read_config_dword(dev, pos + PCI_MSI_ADDRESS_LO,
+		&p_ext->saved_msi_config_space[i++]);
+	if (control & PCI_MSI_FLAGS_64BIT) {
+		pci_read_config_dword(dev, pos + PCI_MSI_ADDRESS_HI,
+			&p_ext->saved_msi_config_space[i++]);
+		pci_read_config_dword(dev, pos + PCI_MSI_DATA_64,
+			&p_ext->saved_msi_config_space[i++]);
+	} else
+		pci_read_config_dword(dev, pos + PCI_MSI_DATA_32,
+			&p_ext->saved_msi_config_space[i++]);
+	if (control & PCI_MSI_FLAGS_MASKBIT)
+		pci_read_config_dword(dev, pos + PCI_MSI_MASK_BIT,
+			&p_ext->saved_msi_config_space[i++]);
+}
+
+static void pci_restore_msi_state(struct pci_dev *dev)
+{
+	struct pcie_port_device_ext *p_ext = pci_get_drvdata(dev);
+	int i = 0, pos;
+	u16 control;
+
+   	if ((pos = pci_find_capability(dev, PCI_CAP_ID_MSI)) <= 0)
+		return;
+
+	control = p_ext->saved_msi_config_space[i++] >> 16;
+	pci_write_config_word(dev, pos + PCI_MSI_FLAGS, control);
+	pci_write_config_dword(dev, pos + PCI_MSI_ADDRESS_LO,
+		p_ext->saved_msi_config_space[i++]);
+	if (control & PCI_MSI_FLAGS_64BIT) {
+		pci_write_config_dword(dev, pos + PCI_MSI_ADDRESS_HI,
+			p_ext->saved_msi_config_space[i++]);
+		pci_write_config_dword(dev, pos + PCI_MSI_DATA_64,
+			p_ext->saved_msi_config_space[i++]);
+	} else
+		pci_write_config_dword(dev, pos + PCI_MSI_DATA_32,
+			p_ext->saved_msi_config_space[i++]);
+	if (control & PCI_MSI_FLAGS_MASKBIT)
+		pci_write_config_dword(dev, pos + PCI_MSI_MASK_BIT,
+			p_ext->saved_msi_config_space[i++]);
+}
+
+static void pcie_portdrv_save_config(struct pci_dev *dev)
+{
+	struct pcie_port_device_ext *p_ext = pci_get_drvdata(dev);
+
+	pci_save_state(dev);
+	if (p_ext->interrupt_mode == PCIE_PORT_MSI_MODE)
+		pci_save_msi_state(dev);
+}
+
+static void pcie_portdrv_restore_config(struct pci_dev *dev)
+{
+	struct pcie_port_device_ext *p_ext = pci_get_drvdata(dev);
+
+	pci_restore_state(dev);
+	if (p_ext->interrupt_mode == PCIE_PORT_MSI_MODE)
+		pci_restore_msi_state(dev);
+	pci_enable_device(dev);
+	pci_set_master(dev);
+}
+
 /*
  * pcie_portdrv_probe - Probe PCI-Express port devices
  * @dev: PCI-Express port device being probed
@@ -64,16 +136,21 @@ static int __devinit pcie_portdrv_probe 
 static void pcie_portdrv_remove (struct pci_dev *dev)
 {
 	pcie_port_device_remove(dev);
+	kfree(pci_get_drvdata(dev));
 }
 
 #ifdef CONFIG_PM
 static int pcie_portdrv_suspend (struct pci_dev *dev, pm_message_t state)
 {
-	return pcie_port_device_suspend(dev, state);
+	int ret = pcie_port_device_suspend(dev, state);
+
+	pcie_portdrv_save_config(dev);
+	return ret;
 }
 
 static int pcie_portdrv_resume (struct pci_dev *dev)
 {
+	pcie_portdrv_restore_config(dev);
 	return pcie_port_device_resume(dev);
 }
 #endif
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -239,9 +239,8 @@ void __devinit pci_read_bridge_bases(str
 
 	if (dev->transparent) {
 		printk(KERN_INFO "PCI: Transparent bridge - %s\n", pci_name(dev));
-		for(i = 0; i < PCI_BUS_NUM_RESOURCES; i++)
-			child->resource[i] = child->parent->resource[i];
-		return;
+		for(i = 3; i < PCI_BUS_NUM_RESOURCES; i++)
+			child->resource[i] = child->parent->resource[i - 3];
 	}
 
 	for(i=0; i<3; i++)
@@ -374,8 +373,11 @@ struct pci_bus * __devinit pci_add_new_b
 	struct pci_bus *child;
 
 	child = pci_alloc_child_bus(parent, dev, busnr);
-	if (child)
+	if (child) {
+		spin_lock(&pci_bus_lock);
 		list_add_tail(&child->node, &parent->children);
+		spin_unlock(&pci_bus_lock);
+	}
 	return child;
 }
 
@@ -395,6 +397,16 @@ static void pci_enable_crs(struct pci_de
 	pci_write_config_word(dev, rpcap + PCI_EXP_RTCTL, rpctl);
 }
 
+static void __devinit pci_fixup_parent_subordinate_busnr(struct pci_bus *child, int max)
+{
+	struct pci_bus *parent = child->parent;
+	while (parent->parent && parent->subordinate < max) {
+		parent->subordinate = max;
+		pci_write_config_byte(parent->self, PCI_SUBORDINATE_BUS, max);
+		parent = parent->parent;
+	}
+}
+
 unsigned int __devinit pci_scan_child_bus(struct pci_bus *bus);
 
 /*
@@ -411,7 +423,7 @@ int __devinit pci_scan_bridge(struct pci
 {
 	struct pci_bus *child;
 	int is_cardbus = (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS);
-	u32 buses;
+	u32 buses, i;
 	u16 bctl;
 
 	pci_read_config_dword(dev, PCI_PRIMARY_BUS, &buses);
@@ -447,7 +459,7 @@ int __devinit pci_scan_bridge(struct pci
 			return max;
 		}
 
-		child = pci_alloc_child_bus(bus, dev, busnr);
+		child = pci_add_new_bus(bus, dev, busnr);
 		if (!child)
 			return max;
 		child->primary = buses & 0xFF;
@@ -470,7 +482,11 @@ int __devinit pci_scan_bridge(struct pci
 		/* Clear errors */
 		pci_write_config_word(dev, PCI_STATUS, 0xffff);
 
-		child = pci_alloc_child_bus(bus, dev, ++max);
+		/* Prevent assigning a bus number that already exists.
+		 * This can happen when a bridge is hot-plugged */
+		if (pci_find_bus(pci_domain_nr(bus), max+1))
+			return max;
+		child = pci_add_new_bus(bus, dev, ++max);
 		buses = (buses & 0xff000000)
 		      | ((unsigned int)(child->primary)     <<  0)
 		      | ((unsigned int)(child->secondary)   <<  8)
@@ -491,8 +507,14 @@ int __devinit pci_scan_bridge(struct pci
 		pci_write_config_dword(dev, PCI_PRIMARY_BUS, buses);
 
 		if (!is_cardbus) {
-			child->bridge_ctl = PCI_BRIDGE_CTL_NO_ISA;
-
+			child->bridge_ctl = bctl | PCI_BRIDGE_CTL_NO_ISA;
+			/*
+			 * Adjust subordinate busnr in parent buses.
+			 * We do this before scanning for children because
+			 * some devices may not be detected if the bios
+			 * was lazy.
+			 */
+			pci_fixup_parent_subordinate_busnr(child, max);
 			/* Now we can scan all subordinate buses... */
 			max = pci_scan_child_bus(child);
 		} else {
@@ -501,7 +523,12 @@ int __devinit pci_scan_bridge(struct pci
 			 * as cards with a PCI-to-PCI bridge can be
 			 * inserted later.
 			 */
-			max += CARDBUS_RESERVE_BUSNR;
+			for (i=0; i<CARDBUS_RESERVE_BUSNR; i++)
+				if (pci_find_bus(pci_domain_nr(bus),
+							max+i+1))
+					break;
+			max += i;
+			pci_fixup_parent_subordinate_busnr(child, max);
 		}
 		/*
 		 * Set the subordinate bus number to its real value.
@@ -757,7 +784,9 @@ pci_scan_single_device(struct pci_bus *b
 	 * and the bus list for fixup functions, etc.
 	 */
 	INIT_LIST_HEAD(&dev->global_list);
+	spin_lock(&pci_bus_lock);
 	list_add_tail(&dev->bus_list, &bus->devices);
+	spin_unlock(&pci_bus_lock);
 
 	return dev;
 }
@@ -878,7 +907,9 @@ struct pci_bus * __devinit pci_scan_bus_
 		pr_debug("PCI: Bus %04x:%02x already known\n", pci_domain_nr(b), bus);
 		goto err_out;
 	}
+	spin_lock(&pci_bus_lock);
 	list_add_tail(&b->node, &pci_root_buses);
+	spin_unlock(&pci_bus_lock);
 
 	memset(dev, 0, sizeof(*dev));
 	dev->parent = parent;
@@ -911,8 +942,6 @@ struct pci_bus * __devinit pci_scan_bus_
 
 	b->subordinate = pci_scan_child_bus(b);
 
-	pci_bus_add_devices(b);
-
 	return b;
 
 sys_create_link_err:
@@ -922,7 +951,9 @@ class_dev_create_file_err:
 class_dev_reg_err:
 	device_unregister(dev);
 dev_reg_err:
+	spin_lock(&pci_bus_lock);
 	list_del(&b->node);
+	spin_unlock(&pci_bus_lock);
 err_out:
 	kfree(dev);
 	kfree(b);
diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c
--- a/drivers/pci/proc.c
+++ b/drivers/pci/proc.c
@@ -355,14 +355,20 @@ static int show_device(struct seq_file *
 			dev->device,
 			dev->irq);
 	/* Here should be 7 and not PCI_NUM_RESOURCES as we need to preserve compatibility */
-	for(i=0; i<7; i++)
+	for (i=0; i<7; i++) {
+		u64 start, end;
+		pci_resource_to_user(dev, i, &dev->resource[i], &start, &end);
 		seq_printf(m, LONG_FORMAT,
-			dev->resource[i].start |
+			((unsigned long)start) |
 			(dev->resource[i].flags & PCI_REGION_FLAG_MASK));
-	for(i=0; i<7; i++)
+	}
+	for (i=0; i<7; i++) {
+		u64 start, end;
+		pci_resource_to_user(dev, i, &dev->resource[i], &start, &end);
 		seq_printf(m, LONG_FORMAT,
 			dev->resource[i].start < dev->resource[i].end ?
-			dev->resource[i].end - dev->resource[i].start + 1 : 0);
+			(unsigned long)(end - start) + 1 : 0);
+	}
 	seq_putc(m, '\t');
 	if (drv)
 		seq_printf(m, "%s", drv->name);
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -373,6 +373,25 @@ static void __devinit quirk_vt82c686_acp
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_82C686_4,	quirk_vt82c686_acpi );
 
+/*
+ * VIA VT8235 ISA Bridge: Two IO regions pointed to by words at
+ *	0x88 (128 bytes of power management registers)
+ *	0xd0 (16 bytes of SMB registers)
+ */
+static void __devinit quirk_vt8235_acpi(struct pci_dev *dev)
+{
+	u16 pm, smb;
+
+	pci_read_config_word(dev, 0x88, &pm);
+	pm &= PCI_BASE_ADDRESS_IO_MASK;
+	quirk_io_region(dev, pm, 128, PCI_BRIDGE_RESOURCES);
+
+	pci_read_config_word(dev, 0xd0, &smb);
+	smb &= PCI_BASE_ADDRESS_IO_MASK;
+	quirk_io_region(dev, smb, 16, PCI_BRIDGE_RESOURCES + 1);
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_8235,	quirk_vt8235_acpi);
+
 
 #ifdef CONFIG_X86_IO_APIC 
 
@@ -767,6 +786,7 @@ static void __init asus_hides_smbus_host
 	if (unlikely(dev->subsystem_vendor == PCI_VENDOR_ID_ASUSTEK)) {
 		if (dev->device == PCI_DEVICE_ID_INTEL_82845_HB)
 			switch(dev->subsystem_device) {
+			case 0x8025: /* P4B-LX */
 			case 0x8070: /* P4B */
 			case 0x8088: /* P4B533 */
 			case 0x1626: /* L3C notebook */
@@ -819,6 +839,11 @@ static void __init asus_hides_smbus_host
 			case 0x0001: /* Toshiba Satellite A40 */
 				asus_hides_smbus = 1;
 			}
+		if (dev->device == PCI_DEVICE_ID_INTEL_82855PM_HB)
+			switch(dev->subsystem_device) {
+			case 0x0001: /* Toshiba Tecra M2 */
+				asus_hides_smbus = 1;
+			}
        } else if (unlikely(dev->subsystem_vendor == PCI_VENDOR_ID_SAMSUNG)) {
                if (dev->device ==  PCI_DEVICE_ID_INTEL_82855PM_HB)
                        switch(dev->subsystem_device) {
@@ -1266,6 +1291,27 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_IN
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_E7320_MCH,	quirk_pcie_mch );
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_E7525_MCH,	quirk_pcie_mch );
 
+
+/*
+ * It's possible for the MSI to get corrupted if shpc and acpi
+ * are used together on certain PXH-based systems.
+ */
+static void __devinit quirk_pcie_pxh(struct pci_dev *dev)
+{
+	disable_msi_mode(dev, pci_find_capability(dev, PCI_CAP_ID_MSI),
+					PCI_CAP_ID_MSI);
+	dev->no_msi = 1;
+
+	printk(KERN_WARNING "PCI: PXH quirk detected, "
+		"disabling MSI for SHPC device\n");
+}
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_PXHD_0,	quirk_pcie_pxh);
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_PXHD_1,	quirk_pcie_pxh);
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_PXH_0,	quirk_pcie_pxh);
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_PXH_1,	quirk_pcie_pxh);
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_PXHV,	quirk_pcie_pxh);
+
+
 static void __devinit quirk_netmos(struct pci_dev *dev)
 {
 	unsigned int num_parallel = (dev->subsystem_device & 0xf0) >> 4;
diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c
--- a/drivers/pci/remove.c
+++ b/drivers/pci/remove.c
@@ -18,17 +18,21 @@ static void pci_free_resources(struct pc
 
 static void pci_destroy_dev(struct pci_dev *dev)
 {
-	pci_proc_detach_device(dev);
-	pci_remove_sysfs_dev_files(dev);
-	device_unregister(&dev->dev);
+	if (!list_empty(&dev->global_list)) {
+		pci_proc_detach_device(dev);
+		pci_remove_sysfs_dev_files(dev);
+		device_unregister(&dev->dev);
+		spin_lock(&pci_bus_lock);
+		list_del(&dev->global_list);
+		dev->global_list.next = dev->global_list.prev = NULL;
+		spin_unlock(&pci_bus_lock);
+	}
 
 	/* Remove the device from the device lists, and prevent any further
 	 * list accesses from this device */
 	spin_lock(&pci_bus_lock);
 	list_del(&dev->bus_list);
-	list_del(&dev->global_list);
 	dev->bus_list.next = dev->bus_list.prev = NULL;
-	dev->global_list.next = dev->global_list.prev = NULL;
 	spin_unlock(&pci_bus_lock);
 
 	pci_free_resources(dev);
diff --git a/drivers/pci/rom.c b/drivers/pci/rom.c
--- a/drivers/pci/rom.c
+++ b/drivers/pci/rom.c
@@ -125,7 +125,9 @@ void __iomem *pci_map_rom(struct pci_dev
 		image += readw(pds + 16) * 512;
 	} while (!last_image);
 
-	*size = image - rom;
+	/* never return a size larger than the PCI resource window */
+	/* there are known ROMs that get the size wrong */
+	*size = min((size_t)(image - rom), *size);
 
 	return rom;
 }
diff --git a/drivers/pci/search.c b/drivers/pci/search.c
--- a/drivers/pci/search.c
+++ b/drivers/pci/search.c
@@ -379,6 +379,7 @@ exit:				
 EXPORT_SYMBOL(pci_dev_present);
 
 EXPORT_SYMBOL(pci_find_bus);
+EXPORT_SYMBOL(pci_find_next_bus);
 EXPORT_SYMBOL(pci_find_device);
 EXPORT_SYMBOL(pci_find_device_reverse);
 EXPORT_SYMBOL(pci_find_slot);
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -40,7 +40,7 @@
  * FIXME: IO should be max 256 bytes.  However, since we may
  * have a P2P bridge below a cardbus bridge, we need 4K.
  */
-#define CARDBUS_IO_SIZE		(4096)
+#define CARDBUS_IO_SIZE		(256)
 #define CARDBUS_MEM_SIZE	(32*1024*1024)
 
 static void __devinit
@@ -51,8 +51,6 @@ pbus_assign_resources_sorted(struct pci_
 	struct resource_list head, *list, *tmp;
 	int idx;
 
-	bus->bridge_ctl &= ~PCI_BRIDGE_CTL_VGA;
-
 	head.next = NULL;
 	list_for_each_entry(dev, &bus->devices, bus_list) {
 		u16 class = dev->class >> 8;
@@ -62,17 +60,17 @@ pbus_assign_resources_sorted(struct pci_
 		    class == PCI_CLASS_BRIDGE_HOST)
 			continue;
 
-		if (class == PCI_CLASS_DISPLAY_VGA ||
-		    class == PCI_CLASS_NOT_DEFINED_VGA)
-			bus->bridge_ctl |= PCI_BRIDGE_CTL_VGA;
-
 		pdev_sort_resources(dev, &head);
 	}
 
 	for (list = head.next; list;) {
 		res = list->res;
 		idx = res - &list->dev->resource[0];
-		pci_assign_resource(list->dev, idx);
+		if (pci_assign_resource(list->dev, idx)) {
+			res->start = 0;
+			res->end = 0;
+			res->flags = 0;
+		}
 		tmp = list;
 		list = list->next;
 		kfree(tmp);
@@ -270,6 +268,8 @@ find_free_bus_resource(struct pci_bus *b
 
 	for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) {
 		r = bus->resource[i];
+		if (r == &ioport_resource || r == &iomem_resource)
+			continue;
 		if (r && (r->flags & type_mask) == type && !r->parent)
 			return r;
 	}
@@ -503,12 +503,6 @@ pci_bus_assign_resources(struct pci_bus 
 
 	pbus_assign_resources_sorted(bus);
 
-	if (bus->bridge_ctl & PCI_BRIDGE_CTL_VGA) {
-		/* Propagate presence of the VGA to upstream bridges */
-		for (b = bus; b->parent; b = b->parent) {
-			b->bridge_ctl |= PCI_BRIDGE_CTL_VGA;
-		}
-	}
 	list_for_each_entry(dev, &bus->devices, bus_list) {
 		b = dev->subordinate;
 		if (!b)
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c
--- a/drivers/pci/setup-res.c
+++ b/drivers/pci/setup-res.c
@@ -33,6 +33,11 @@ pci_update_resource(struct pci_dev *dev,
 	u32 new, check, mask;
 	int reg;
 
+	/* Ignore resources for unimplemented BARs and unused resource slots
+	   for 64 bit BARs. */
+	if (!res->flags)
+		return;
+
 	pcibios_resource_to_bus(dev, &region, res);
 
 	pr_debug("  got res [%lx:%lx] bus [%lx:%lx] flags %lx for "
@@ -48,7 +53,9 @@ pci_update_resource(struct pci_dev *dev,
 	if (resno < 6) {
 		reg = PCI_BASE_ADDRESS_0 + 4 * resno;
 	} else if (resno == PCI_ROM_RESOURCE) {
-		new |= res->flags & IORESOURCE_ROM_ENABLE;
+		if (!(res->flags & IORESOURCE_ROM_ENABLE))
+			return;
+		new |= PCI_ROM_ADDRESS_ENABLE;
 		reg = dev->rom_base_reg;
 	} else {
 		/* Hmm, non-standard resource. */
@@ -67,7 +74,7 @@ pci_update_resource(struct pci_dev *dev,
 
 	if ((new & (PCI_BASE_ADDRESS_SPACE|PCI_BASE_ADDRESS_MEM_TYPE_MASK)) ==
 	    (PCI_BASE_ADDRESS_SPACE_MEMORY|PCI_BASE_ADDRESS_MEM_TYPE_64)) {
-		new = 0; /* currently everyone zeros the high address */
+		new = region.start >> 16 >> 16;
 		pci_write_config_dword(dev, reg + 4, new);
 		pci_read_config_dword(dev, reg + 4, &check);
 		if (check != new) {
diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig
--- a/drivers/pcmcia/Kconfig
+++ b/drivers/pcmcia/Kconfig
@@ -1,8 +1,5 @@
 #
-# PCMCIA bus subsystem configuration
-#
-# Right now the non-CardBus choices are not supported
-# by the integrated kernel driver.
+# PCCARD (PCMCIA/CardBus) bus subsystem configuration
 #
 
 menu "PCCARD (PCMCIA/CardBus) support"
@@ -14,8 +11,8 @@ config PCCARD
 	  Say Y here if you want to attach PCMCIA- or PC-cards to your Linux
 	  computer.  These are credit-card size devices such as network cards,
 	  modems or hard drives often used with laptops computers.  There are
-	  actually two varieties of these cards: the older 16 bit PCMCIA cards
-	  and the newer 32 bit CardBus cards.
+	  actually two varieties of these cards: 16 bit PCMCIA and 32 bit
+	  CardBus cards.
 
 	  To compile this driver as modules, choose M here: the
 	  module will be called pcmcia_core.
@@ -32,7 +29,7 @@ config PCMCIA_DEBUG
 
 	  The kernel command line options are:
 	    pcmcia_core.pc_debug=N
-	    ds.pc_debug=N
+	    pcmcia.pc_debug=N
 	    sa11xx_core.pc_debug=N
 
 	  The module option is called pc_debug=N
@@ -42,22 +39,50 @@ config PCMCIA_DEBUG
 
 config PCMCIA
 	tristate "16-bit PCMCIA support"
+	select CRC32
 	default y
 	---help---
 	   This option enables support for 16-bit PCMCIA cards. Most older
 	   PC-cards are such 16-bit PCMCIA cards, so unless you know you're
 	   only using 32-bit CardBus cards, say Y or M here.
 
-	   To use 16-bit PCMCIA cards, you will need supporting software from 
-	   David Hinds' pcmcia-cs package (see the file <file:Documentation/Changes>
- 	   for location).  Please also read the PCMCIA-HOWTO, available from
-	   <http://www.tldp.org/docs.html#howto>.
+	   To use 16-bit PCMCIA cards, you will need supporting software in
+	   most cases. (see the file <file:Documentation/Changes> for
+	   location and details).
 
 	   To compile this driver as modules, choose M here: the
 	   module will be called pcmcia.
 
 	   If unsure, say Y.
 
+config PCMCIA_LOAD_CIS
+	bool "Load CIS updates from userspace (EXPERIMENTAL)"
+	depends on PCMCIA && EXPERIMENTAL
+	select FW_LOADER
+	default y
+	help
+	  Some PCMCIA cards require an updated Card Information Structure (CIS)
+	  to be loaded from userspace to work correctly. If you say Y here,
+	  and your userspace is arranged correctly, this will be loaded
+	  automatically using the in-kernel firmware loader and the hotplug
+	  subsystem, instead of relying on cardmgr from pcmcia-cs to do so.
+
+	  If unsure, say Y.
+
+config PCMCIA_IOCTL
+	bool "PCMCIA control ioctl (obsolete)"
+	depends on PCMCIA
+	default y
+	help
+	  If you say Y here, the deprecated ioctl interface to the PCMCIA
+	  subsystem will be built. It is needed by cardmgr and cardctl
+	  (pcmcia-cs) to function properly.
+
+	  You should use the new pcmciautils package instead (see
+	  <file:Documentation/Changes> for location and details).
+
+	  If unsure, say Y.
+
 config CARDBUS
 	bool "32-bit CardBus support"	
 	depends on PCI
@@ -78,8 +103,7 @@ comment "PC-card bridges"
 config YENTA
 	tristate "CardBus yenta-compatible bridge support"
 	depends on PCI
-#fixme: remove dependendcy on CARDBUS
-	depends on CARDBUS
+	select CARDBUS if !EMBEDDED
 	select PCCARD_NONSTATIC
 	---help---
 	  This option enables support for CardBus host bridges.  Virtually
@@ -171,19 +195,21 @@ config PCMCIA_PROBE
 config M32R_PCC
 	bool "M32R PCMCIA I/F"
 	depends on M32R && CHIP_M32700 && PCMCIA
+	select PCCARD_NONSTATIC
 	help
 	  Say Y here to use the M32R PCMCIA controller.
 
 config M32R_CFC
 	bool "M32R CF I/F Controller"
-	depends on M32R && (PLAT_USRV || PLAT_M32700UT || PLAT_MAPPI2 || PLAT_OPSPUT)
+	depends on M32R && (PLAT_USRV || PLAT_M32700UT || PLAT_MAPPI2 || PLAT_MAPPI3 || PLAT_OPSPUT)
+	select PCCARD_NONSTATIC
 	help
 	  Say Y here to use the M32R CompactFlash controller.
 
 config M32R_CFC_NUM
 	int "M32R CF I/F number"
 	depends on M32R_CFC
-	default "1" if PLAT_USRV || PLAT_M32700UT || PLAT_MAPPI2 || PLAT_OPSPUT
+	default "1" if PLAT_USRV || PLAT_M32700UT || PLAT_MAPPI2 || PLAT_MAPPI3 || PLAT_OPSPUT
 	help
 	  Set the number of M32R CF slots.
 
diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile
--- a/drivers/pcmcia/Makefile
+++ b/drivers/pcmcia/Makefile
@@ -10,7 +10,8 @@ pcmcia_core-y					+= cs.o cistpl.o rsrc_
 pcmcia_core-$(CONFIG_CARDBUS)			+= cardbus.o
 obj-$(CONFIG_PCCARD)				+= pcmcia_core.o
 
-pcmcia-y					+= ds.o pcmcia_compat.o
+pcmcia-y					+= ds.o pcmcia_compat.o pcmcia_resource.o
+pcmcia-$(CONFIG_PCMCIA_IOCTL)			+= pcmcia_ioctl.o
 obj-$(CONFIG_PCMCIA)				+= pcmcia.o
 
 obj-$(CONFIG_PCCARD_NONSTATIC)			+= rsrc_nonstatic.o
diff --git a/drivers/pcmcia/au1000_generic.c b/drivers/pcmcia/au1000_generic.c
--- a/drivers/pcmcia/au1000_generic.c
+++ b/drivers/pcmcia/au1000_generic.c
@@ -388,6 +388,7 @@ int au1x00_pcmcia_socket_probe(struct de
 		struct au1000_pcmcia_socket *skt = PCMCIA_SOCKET(i);
 		memset(skt, 0, sizeof(*skt));
 
+		skt->socket.resource_ops = &pccard_static_ops;
 		skt->socket.ops = &au1x00_pcmcia_operations;
 		skt->socket.owner = ops->owner;
 		skt->socket.dev.dev = dev;
diff --git a/drivers/pcmcia/au1000_generic.h b/drivers/pcmcia/au1000_generic.h
--- a/drivers/pcmcia/au1000_generic.h
+++ b/drivers/pcmcia/au1000_generic.h
@@ -22,7 +22,6 @@
 #define __ASM_AU1000_PCMCIA_H
 
 /* include the world */
-#include <pcmcia/version.h>
 #include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/ss.h>
diff --git a/drivers/pcmcia/au1000_pb1x00.c b/drivers/pcmcia/au1000_pb1x00.c
--- a/drivers/pcmcia/au1000_pb1x00.c
+++ b/drivers/pcmcia/au1000_pb1x00.c
@@ -33,7 +33,6 @@
 #include <linux/version.h>
 #include <linux/types.h>
 
-#include <pcmcia/version.h>
 #include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/ss.h>
diff --git a/drivers/pcmcia/au1000_xxs1500.c b/drivers/pcmcia/au1000_xxs1500.c
--- a/drivers/pcmcia/au1000_xxs1500.c
+++ b/drivers/pcmcia/au1000_xxs1500.c
@@ -38,7 +38,6 @@
 #include <linux/version.h>
 #include <linux/types.h>
 
-#include <pcmcia/version.h>
 #include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/ss.h>
diff --git a/drivers/pcmcia/cardbus.c b/drivers/pcmcia/cardbus.c
--- a/drivers/pcmcia/cardbus.c
+++ b/drivers/pcmcia/cardbus.c
@@ -31,7 +31,6 @@
 #include <asm/io.h>
 
 #define IN_CARD_SERVICES
-#include <pcmcia/version.h>
 #include <pcmcia/cs_types.h>
 #include <pcmcia/ss.h>
 #include <pcmcia/cs.h>
diff --git a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c
--- a/drivers/pcmcia/cistpl.c
+++ b/drivers/pcmcia/cistpl.c
@@ -88,24 +88,38 @@ EXPORT_SYMBOL(release_cis_mem);
 static void __iomem *
 set_cis_map(struct pcmcia_socket *s, unsigned int card_offset, unsigned int flags)
 {
-    pccard_mem_map *mem = &s->cis_mem;
-    if (!(s->features & SS_CAP_STATIC_MAP) && mem->res == NULL) {
-	mem->res = find_mem_region(0, s->map_size, s->map_size, 0, s);
-	if (mem->res == NULL) {
-	    printk(KERN_NOTICE "cs: unable to map card memory!\n");
-	    return NULL;
-	}
-	s->cis_virt = ioremap(mem->res->start, s->map_size);
-    }
-    mem->card_start = card_offset;
-    mem->flags = flags;
-    s->ops->set_mem_map(s, mem);
-    if (s->features & SS_CAP_STATIC_MAP) {
-	if (s->cis_virt)
-	    iounmap(s->cis_virt);
-	s->cis_virt = ioremap(mem->static_start, s->map_size);
-    }
-    return s->cis_virt;
+	pccard_mem_map *mem = &s->cis_mem;
+	int ret;
+
+	if (!(s->features & SS_CAP_STATIC_MAP) && (mem->res == NULL)) {
+		mem->res = pcmcia_find_mem_region(0, s->map_size, s->map_size, 0, s);
+		if (mem->res == NULL) {
+			printk(KERN_NOTICE "cs: unable to map card memory!\n");
+			return NULL;
+		}
+		s->cis_virt = NULL;
+	}
+
+	if (!(s->features & SS_CAP_STATIC_MAP) && (!s->cis_virt))
+		s->cis_virt = ioremap(mem->res->start, s->map_size);
+
+	mem->card_start = card_offset;
+	mem->flags = flags;
+
+	ret = s->ops->set_mem_map(s, mem);
+	if (ret) {
+		iounmap(s->cis_virt);
+		s->cis_virt = NULL;
+		return NULL;
+	}
+
+	if (s->features & SS_CAP_STATIC_MAP) {
+		if (s->cis_virt)
+			iounmap(s->cis_virt);
+		s->cis_virt = ioremap(mem->static_start, s->map_size);
+	}
+
+	return s->cis_virt;
 }
 
 /*======================================================================
@@ -119,13 +133,13 @@ set_cis_map(struct pcmcia_socket *s, uns
 #define IS_ATTR		1
 #define IS_INDIRECT	8
 
-int read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
+int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
 		 u_int len, void *ptr)
 {
     void __iomem *sys, *end;
     unsigned char *buf = ptr;
     
-    cs_dbg(s, 3, "read_cis_mem(%d, %#x, %u)\n", attr, addr, len);
+    cs_dbg(s, 3, "pcmcia_read_cis_mem(%d, %#x, %u)\n", attr, addr, len);
 
     if (attr & IS_INDIRECT) {
 	/* Indirect accesses use a bunch of special registers at fixed
@@ -182,14 +196,16 @@ int read_cis_mem(struct pcmcia_socket *s
 	  *(u_char *)(ptr+2), *(u_char *)(ptr+3));
     return 0;
 }
+EXPORT_SYMBOL(pcmcia_read_cis_mem);
+
 
-void write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
+void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
 		   u_int len, void *ptr)
 {
     void __iomem *sys, *end;
     unsigned char *buf = ptr;
     
-    cs_dbg(s, 3, "write_cis_mem(%d, %#x, %u)\n", attr, addr, len);
+    cs_dbg(s, 3, "pcmcia_write_cis_mem(%d, %#x, %u)\n", attr, addr, len);
 
     if (attr & IS_INDIRECT) {
 	/* Indirect accesses use a bunch of special registers at fixed
@@ -239,6 +255,8 @@ void write_cis_mem(struct pcmcia_socket 
 	}
     }
 }
+EXPORT_SYMBOL(pcmcia_write_cis_mem);
+
 
 /*======================================================================
 
@@ -274,7 +292,7 @@ static void read_cis_cache(struct pcmcia
 	ret = read_cb_mem(s, attr, addr, len, ptr);
     else
 #endif
-	ret = read_cis_mem(s, attr, addr, len, ptr);
+	ret = pcmcia_read_cis_mem(s, attr, addr, len, ptr);
 
 	if (ret == 0) {
 		/* Copy data into the cache */
@@ -348,7 +366,7 @@ int verify_cis_cache(struct pcmcia_socke
 			read_cb_mem(s, cis->attr, cis->addr, len, buf);
 		else
 #endif
-			read_cis_mem(s, cis->attr, cis->addr, len, buf);
+			pcmcia_read_cis_mem(s, cis->attr, cis->addr, len, buf);
 
 		if (memcmp(buf, cis->cache, len) != 0) {
 			kfree(buf);
@@ -381,6 +399,7 @@ int pcmcia_replace_cis(struct pcmcia_soc
     memcpy(s->fake_cis, cis->Data, cis->Length);
     return CS_SUCCESS;
 }
+EXPORT_SYMBOL(pcmcia_replace_cis);
 
 /*======================================================================
 
diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c
--- a/drivers/pcmcia/cs.c
+++ b/drivers/pcmcia/cs.c
@@ -33,7 +33,6 @@
 #include <asm/irq.h>
 
 #define IN_CARD_SERVICES
-#include <pcmcia/version.h>
 #include <pcmcia/cs_types.h>
 #include <pcmcia/ss.h>
 #include <pcmcia/cs.h>
@@ -43,36 +42,11 @@
 #include <pcmcia/ds.h>
 #include "cs_internal.h"
 
-#ifdef CONFIG_PCI
-#define PCI_OPT " [pci]"
-#else
-#define PCI_OPT ""
-#endif
-#ifdef CONFIG_CARDBUS
-#define CB_OPT " [cardbus]"
-#else
-#define CB_OPT ""
-#endif
-#ifdef CONFIG_PM
-#define PM_OPT " [pm]"
-#else
-#define PM_OPT ""
-#endif
-#if !defined(CONFIG_CARDBUS) && !defined(CONFIG_PCI) && !defined(CONFIG_PM)
-#define OPTIONS " none"
-#else
-#define OPTIONS PCI_OPT CB_OPT PM_OPT
-#endif
-
-static const char *release = "Linux Kernel Card Services";
-static const char *options = "options: " OPTIONS;
-
-/*====================================================================*/
 
 /* Module parameters */
 
 MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");
-MODULE_DESCRIPTION("Linux Kernel Card Services\noptions:" OPTIONS);
+MODULE_DESCRIPTION("Linux Kernel Card Services");
 MODULE_LICENSE("GPL");
 
 #define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0444)
@@ -89,9 +63,6 @@ INT_MODULE_PARM(unreset_limit,	30);		/* 
 /* Access speed for attribute memory windows */
 INT_MODULE_PARM(cis_speed,	300);		/* ns */
 
-/* Access speed for IO windows */
-INT_MODULE_PARM(io_speed,	0);		/* ns */
-
 #ifdef DEBUG
 static int pc_debug;
 
@@ -103,34 +74,26 @@ int cs_debug_level(int level)
 }
 #endif
 
-/*====================================================================*/
 
 socket_state_t dead_socket = {
 	.csc_mask	= SS_DETECT,
 };
+EXPORT_SYMBOL(dead_socket);
 
 
 /* List of all sockets, protected by a rwsem */
 LIST_HEAD(pcmcia_socket_list);
-DECLARE_RWSEM(pcmcia_socket_list_rwsem);
 EXPORT_SYMBOL(pcmcia_socket_list);
-EXPORT_SYMBOL(pcmcia_socket_list_rwsem);
-
 
-#ifdef CONFIG_PCMCIA_PROBE
-/* mask ofIRQs already reserved by other cards, we should avoid using them */
-static u8 pcmcia_used_irq[NR_IRQS];
-#endif
-
-/*====================================================================
+DECLARE_RWSEM(pcmcia_socket_list_rwsem);
+EXPORT_SYMBOL(pcmcia_socket_list_rwsem);
 
-    Low-level PC Card interface drivers need to register with Card
-    Services using these calls.
-    
-======================================================================*/
 
 /**
- * socket drivers are expected to use the following callbacks in their 
+ * Low-level PCMCIA socket drivers need to register with the PCCard
+ * core using pcmcia_register_socket.
+ *
+ * socket drivers are expected to use the following callbacks in their
  * .drv struct:
  *  - pcmcia_socket_dev_suspend
  *  - pcmcia_socket_dev_resume
@@ -230,8 +193,8 @@ int pcmcia_register_socket(struct pcmcia
 	}
 
 	/* try to obtain a socket number [yes, it gets ugly if we
-	 * register more than 2^sizeof(unsigned int) pcmcia 
-	 * sockets... but the socket number is deprecated 
+	 * register more than 2^sizeof(unsigned int) pcmcia
+	 * sockets... but the socket number is deprecated
 	 * anyways, so I don't care] */
 	down_write(&pcmcia_socket_list_rwsem);
 	if (list_empty(&pcmcia_socket_list))
@@ -252,6 +215,13 @@ int pcmcia_register_socket(struct pcmcia
 	list_add_tail(&socket->socket_list, &pcmcia_socket_list);
 	up_write(&pcmcia_socket_list_rwsem);
 
+#ifndef CONFIG_CARDBUS
+	/*
+	 * If we do not support Cardbus, ensure that
+	 * the Cardbus socket capability is disabled.
+	 */
+	socket->features &= ~SS_CAP_CARDBUS;
+#endif
 
 	/* set proper values in socket->dev */
 	socket->dev.class_data = socket;
@@ -340,54 +310,49 @@ struct pcmcia_socket * pcmcia_get_socket
 EXPORT_SYMBOL(pcmcia_get_socket_by_nr);
 
 
-/*======================================================================
-
-    socket_setup() and shutdown_socket() are called by the main event
-    handler when card insertion and removal events are received.
-    socket_setup() turns on socket power and resets the socket, in two stages.
-    shutdown_socket() unconfigures a socket and turns off socket power.
-
-======================================================================*/
-
+/**
+ * socket_setup() and shutdown_socket() are called by the main event
+ * handler when card insertion and removal events are received.
+ * socket_setup() turns on socket power and resets the socket, in two stages.
+ * shutdown_socket() unconfigures a socket and turns off socket power.
+ */
 static void shutdown_socket(struct pcmcia_socket *s)
 {
-    cs_dbg(s, 1, "shutdown_socket\n");
+	cs_dbg(s, 1, "shutdown_socket\n");
 
-    /* Blank out the socket state */
-    s->socket = dead_socket;
-    s->ops->init(s);
-    s->ops->set_socket(s, &s->socket);
-    s->irq.AssignedIRQ = s->irq.Config = 0;
-    s->lock_count = 0;
-    destroy_cis_cache(s);
+	/* Blank out the socket state */
+	s->socket = dead_socket;
+	s->ops->init(s);
+	s->ops->set_socket(s, &s->socket);
+	s->irq.AssignedIRQ = s->irq.Config = 0;
+	s->lock_count = 0;
+	destroy_cis_cache(s);
 #ifdef CONFIG_CARDBUS
-    cb_free(s);
+	cb_free(s);
 #endif
-    s->functions = 0;
-    if (s->config) {
-	kfree(s->config);
-	s->config = NULL;
-    }
-
-    {
-	int status;
-	s->ops->get_status(s, &status);
-	if (status & SS_POWERON) {
-		printk(KERN_ERR "PCMCIA: socket %p: *** DANGER *** unable to remove socket power\n", s);
+	s->functions = 0;
+	if (s->config) {
+		kfree(s->config);
+		s->config = NULL;
 	}
-    }
-} /* shutdown_socket */
 
-/*======================================================================
+	{
+		int status;
+		s->ops->get_status(s, &status);
+		if (status & SS_POWERON) {
+			printk(KERN_ERR "PCMCIA: socket %p: *** DANGER *** unable to remove socket power\n", s);
+		}
+	}
+} /* shutdown_socket */
 
-    The central event handler.  Send_event() sends an event to the
-    16-bit subsystem, which then calls the relevant device drivers.
-    Parse_events() interprets the event bits from
-    a card status change report.  Do_shutdown() handles the high
-    priority stuff associated with a card removal.
-    
-======================================================================*/
 
+/**
+ * The central event handler.  Send_event() sends an event to the
+ * 16-bit subsystem, which then calls the relevant device drivers.
+ * Parse_events() interprets the event bits from
+ * a card status change report.  Do_shutdown() handles the high
+ * priority stuff associated with a card removal.
+ */
 
 /* NOTE: send_event needs to be called with skt->sem held. */
 
@@ -490,11 +455,11 @@ static int socket_setup(struct pcmcia_so
 	}
 
 	if (status & SS_CARDBUS) {
+		if (!(skt->features & SS_CAP_CARDBUS)) {
+			cs_err(skt, "cardbus cards are not supported.\n");
+			return CS_BAD_TYPE;
+		}
 		skt->state |= SOCKET_CARDBUS;
-#ifndef CONFIG_CARDBUS
-		cs_err(skt, "cardbus cards are not supported.\n");
-		return CS_BAD_TYPE;
-#endif
 	}
 
 	/*
@@ -508,6 +473,10 @@ static int socket_setup(struct pcmcia_so
 		cs_err(skt, "unsupported voltage key.\n");
 		return CS_BAD_TYPE;
 	}
+
+	if (skt->power_hook)
+		skt->power_hook(skt, HOOK_POWER_PRE);
+
 	skt->socket.flags = 0;
 	skt->ops->set_socket(skt, &skt->socket);
 
@@ -522,7 +491,12 @@ static int socket_setup(struct pcmcia_so
 		return CS_BAD_TYPE;
 	}
 
-	return socket_reset(skt);
+	status = socket_reset(skt);
+
+	if (skt->power_hook)
+		skt->power_hook(skt, HOOK_POWER_POST);
+
+	return status;
 }
 
 /*
@@ -709,7 +683,7 @@ static int pccardd(void *__skt)
 		}
 
 		schedule();
-		try_to_freeze(PF_FREEZE);
+		try_to_freeze();
 
 		if (!skt->thread)
 			break;
@@ -737,420 +711,9 @@ void pcmcia_parse_events(struct pcmcia_s
 		wake_up(&s->thread_wait);
 	}
 } /* pcmcia_parse_events */
+EXPORT_SYMBOL(pcmcia_parse_events);
 
 
-/*======================================================================
-
-    Special stuff for managing IO windows, because they are scarce.
-    
-======================================================================*/
-
-static int alloc_io_space(struct pcmcia_socket *s, u_int attr, ioaddr_t *base,
-			  ioaddr_t num, u_int lines)
-{
-    int i;
-    kio_addr_t try, align;
-
-    align = (*base) ? (lines ? 1<<lines : 0) : 1;
-    if (align && (align < num)) {
-	if (*base) {
-	    cs_dbg(s, 0, "odd IO request: num %#x align %#lx\n",
-		   num, align);
-	    align = 0;
-	} else
-	    while (align && (align < num)) align <<= 1;
-    }
-    if (*base & ~(align-1)) {
-	cs_dbg(s, 0, "odd IO request: base %#x align %#lx\n",
-	       *base, align);
-	align = 0;
-    }
-    if ((s->features & SS_CAP_STATIC_MAP) && s->io_offset) {
-	*base = s->io_offset | (*base & 0x0fff);
-	return 0;
-    }
-    /* Check for an already-allocated window that must conflict with
-       what was asked for.  It is a hack because it does not catch all
-       potential conflicts, just the most obvious ones. */
-    for (i = 0; i < MAX_IO_WIN; i++)
-	if ((s->io[i].NumPorts != 0) &&
-	    ((s->io[i].BasePort & (align-1)) == *base))
-	    return 1;
-    for (i = 0; i < MAX_IO_WIN; i++) {
-	if (s->io[i].NumPorts == 0) {
-	    s->io[i].res = find_io_region(*base, num, align, s);
-	    if (s->io[i].res) {
-		s->io[i].Attributes = attr;
-		s->io[i].BasePort = *base = s->io[i].res->start;
-		s->io[i].NumPorts = s->io[i].InUse = num;
-		break;
-	    } else
-		return 1;
-	} else if (s->io[i].Attributes != attr)
-	    continue;
-	/* Try to extend top of window */
-	try = s->io[i].BasePort + s->io[i].NumPorts;
-	if ((*base == 0) || (*base == try))
-	    if (adjust_io_region(s->io[i].res, s->io[i].res->start,
-				 s->io[i].res->end + num, s) == 0) {
-		*base = try;
-		s->io[i].NumPorts += num;
-		s->io[i].InUse += num;
-		break;
-	    }
-	/* Try to extend bottom of window */
-	try = s->io[i].BasePort - num;
-	if ((*base == 0) || (*base == try))
-	    if (adjust_io_region(s->io[i].res, s->io[i].res->start - num,
-				 s->io[i].res->end, s) == 0) {
-		s->io[i].BasePort = *base = try;
-		s->io[i].NumPorts += num;
-		s->io[i].InUse += num;
-		break;
-	    }
-    }
-    return (i == MAX_IO_WIN);
-} /* alloc_io_space */
-
-static void release_io_space(struct pcmcia_socket *s, ioaddr_t base,
-			     ioaddr_t num)
-{
-    int i;
-
-    for (i = 0; i < MAX_IO_WIN; i++) {
-	if ((s->io[i].BasePort <= base) &&
-	    (s->io[i].BasePort+s->io[i].NumPorts >= base+num)) {
-	    s->io[i].InUse -= num;
-	    /* Free the window if no one else is using it */
-	    if (s->io[i].InUse == 0) {
-		s->io[i].NumPorts = 0;
-		release_resource(s->io[i].res);
-		kfree(s->io[i].res);
-		s->io[i].res = NULL;
-	    }
-	}
-    }
-}
-
-/*======================================================================
-
-    Access_configuration_register() reads and writes configuration
-    registers in attribute memory.  Memory window 0 is reserved for
-    this and the tuple reading services.
-    
-======================================================================*/
-
-int pccard_access_configuration_register(struct pcmcia_socket *s,
-					 unsigned int function,
-					 conf_reg_t *reg)
-{
-    config_t *c;
-    int addr;
-    u_char val;
-
-    if (!s || !s->config)
-	return CS_NO_CARD;    
-
-    c = &s->config[function];
-
-    if (c == NULL)
-	return CS_NO_CARD;
-
-    if (!(c->state & CONFIG_LOCKED))
-	return CS_CONFIGURATION_LOCKED;
-
-    addr = (c->ConfigBase + reg->Offset) >> 1;
-    
-    switch (reg->Action) {
-    case CS_READ:
-	read_cis_mem(s, 1, addr, 1, &val);
-	reg->Value = val;
-	break;
-    case CS_WRITE:
-	val = reg->Value;
-	write_cis_mem(s, 1, addr, 1, &val);
-	break;
-    default:
-	return CS_BAD_ARGS;
-	break;
-    }
-    return CS_SUCCESS;
-} /* access_configuration_register */
-EXPORT_SYMBOL(pccard_access_configuration_register);
-
-
-/*====================================================================*/
-
-int pccard_get_configuration_info(struct pcmcia_socket *s,
-				  unsigned int function,
-				  config_info_t *config)
-{
-    config_t *c;
-    
-    if (!(s->state & SOCKET_PRESENT))
-	return CS_NO_CARD;
-
-    config->Function = function;
-
-#ifdef CONFIG_CARDBUS
-    if (s->state & SOCKET_CARDBUS) {
-	memset(config, 0, sizeof(config_info_t));
-	config->Vcc = s->socket.Vcc;
-	config->Vpp1 = config->Vpp2 = s->socket.Vpp;
-	config->Option = s->cb_dev->subordinate->number;
-	if (s->state & SOCKET_CARDBUS_CONFIG) {
-	    config->Attributes = CONF_VALID_CLIENT;
-	    config->IntType = INT_CARDBUS;
-	    config->AssignedIRQ = s->irq.AssignedIRQ;
-	    if (config->AssignedIRQ)
-		config->Attributes |= CONF_ENABLE_IRQ;
-	    config->BasePort1 = s->io[0].BasePort;
-	    config->NumPorts1 = s->io[0].NumPorts;
-	}
-	return CS_SUCCESS;
-    }
-#endif
-    
-    c = (s->config != NULL) ? &s->config[function] : NULL;
-    
-    if ((c == NULL) || !(c->state & CONFIG_LOCKED)) {
-	config->Attributes = 0;
-	config->Vcc = s->socket.Vcc;
-	config->Vpp1 = config->Vpp2 = s->socket.Vpp;
-	return CS_SUCCESS;
-    }
-    
-    /* !!! This is a hack !!! */
-    memcpy(&config->Attributes, &c->Attributes, sizeof(config_t));
-    config->Attributes |= CONF_VALID_CLIENT;
-    config->CardValues = c->CardValues;
-    config->IRQAttributes = c->irq.Attributes;
-    config->AssignedIRQ = s->irq.AssignedIRQ;
-    config->BasePort1 = c->io.BasePort1;
-    config->NumPorts1 = c->io.NumPorts1;
-    config->Attributes1 = c->io.Attributes1;
-    config->BasePort2 = c->io.BasePort2;
-    config->NumPorts2 = c->io.NumPorts2;
-    config->Attributes2 = c->io.Attributes2;
-    config->IOAddrLines = c->io.IOAddrLines;
-    
-    return CS_SUCCESS;
-} /* get_configuration_info */
-EXPORT_SYMBOL(pccard_get_configuration_info);
-
-/*======================================================================
-
-    Return information about this version of Card Services.
-    
-======================================================================*/
-
-int pcmcia_get_card_services_info(servinfo_t *info)
-{
-    unsigned int socket_count = 0;
-    struct list_head *tmp;
-    info->Signature[0] = 'C';
-    info->Signature[1] = 'S';
-    down_read(&pcmcia_socket_list_rwsem);
-    list_for_each(tmp, &pcmcia_socket_list)
-	    socket_count++;
-    up_read(&pcmcia_socket_list_rwsem);
-    info->Count = socket_count;
-    info->Revision = CS_RELEASE_CODE;
-    info->CSLevel = 0x0210;
-    info->VendorString = (char *)release;
-    return CS_SUCCESS;
-} /* get_card_services_info */
-
-
-/*====================================================================*/
-
-int pcmcia_get_window(struct pcmcia_socket *s, window_handle_t *handle, int idx, win_req_t *req)
-{
-    window_t *win;
-    int w;
-
-    if (!s || !(s->state & SOCKET_PRESENT))
-	return CS_NO_CARD;
-    for (w = idx; w < MAX_WIN; w++)
-	if (s->state & SOCKET_WIN_REQ(w)) break;
-    if (w == MAX_WIN)
-	return CS_NO_MORE_ITEMS;
-    win = &s->win[w];
-    req->Base = win->ctl.res->start;
-    req->Size = win->ctl.res->end - win->ctl.res->start + 1;
-    req->AccessSpeed = win->ctl.speed;
-    req->Attributes = 0;
-    if (win->ctl.flags & MAP_ATTRIB)
-	req->Attributes |= WIN_MEMORY_TYPE_AM;
-    if (win->ctl.flags & MAP_ACTIVE)
-	req->Attributes |= WIN_ENABLE;
-    if (win->ctl.flags & MAP_16BIT)
-	req->Attributes |= WIN_DATA_WIDTH_16;
-    if (win->ctl.flags & MAP_USE_WAIT)
-	req->Attributes |= WIN_USE_WAIT;
-    *handle = win;
-    return CS_SUCCESS;
-} /* get_window */
-EXPORT_SYMBOL(pcmcia_get_window);
-
-/*=====================================================================
-
-    Return the PCI device associated with a card..
-
-======================================================================*/
-
-#ifdef CONFIG_CARDBUS
-
-struct pci_bus *pcmcia_lookup_bus(struct pcmcia_socket *s)
-{
-	if (!s || !(s->state & SOCKET_CARDBUS))
-		return NULL;
-
-	return s->cb_dev->subordinate;
-}
-
-EXPORT_SYMBOL(pcmcia_lookup_bus);
-
-#endif
-
-/*======================================================================
-
-    Get the current socket state bits.  We don't support the latched
-    SocketState yet: I haven't seen any point for it.
-    
-======================================================================*/
-
-int pccard_get_status(struct pcmcia_socket *s, unsigned int function, cs_status_t *status)
-{
-    config_t *c;
-    int val;
-    
-    s->ops->get_status(s, &val);
-    status->CardState = status->SocketState = 0;
-    status->CardState |= (val & SS_DETECT) ? CS_EVENT_CARD_DETECT : 0;
-    status->CardState |= (val & SS_CARDBUS) ? CS_EVENT_CB_DETECT : 0;
-    status->CardState |= (val & SS_3VCARD) ? CS_EVENT_3VCARD : 0;
-    status->CardState |= (val & SS_XVCARD) ? CS_EVENT_XVCARD : 0;
-    if (s->state & SOCKET_SUSPEND)
-	status->CardState |= CS_EVENT_PM_SUSPEND;
-    if (!(s->state & SOCKET_PRESENT))
-	return CS_NO_CARD;
-    
-    c = (s->config != NULL) ? &s->config[function] : NULL;
-    if ((c != NULL) && (c->state & CONFIG_LOCKED) &&
-	(c->IntType & (INT_MEMORY_AND_IO | INT_ZOOMED_VIDEO))) {
-	u_char reg;
-	if (c->Present & PRESENT_PIN_REPLACE) {
-	    read_cis_mem(s, 1, (c->ConfigBase+CISREG_PRR)>>1, 1, &reg);
-	    status->CardState |=
-		(reg & PRR_WP_STATUS) ? CS_EVENT_WRITE_PROTECT : 0;
-	    status->CardState |=
-		(reg & PRR_READY_STATUS) ? CS_EVENT_READY_CHANGE : 0;
-	    status->CardState |=
-		(reg & PRR_BVD2_STATUS) ? CS_EVENT_BATTERY_LOW : 0;
-	    status->CardState |=
-		(reg & PRR_BVD1_STATUS) ? CS_EVENT_BATTERY_DEAD : 0;
-	} else {
-	    /* No PRR?  Then assume we're always ready */
-	    status->CardState |= CS_EVENT_READY_CHANGE;
-	}
-	if (c->Present & PRESENT_EXT_STATUS) {
-	    read_cis_mem(s, 1, (c->ConfigBase+CISREG_ESR)>>1, 1, &reg);
-	    status->CardState |=
-		(reg & ESR_REQ_ATTN) ? CS_EVENT_REQUEST_ATTENTION : 0;
-	}
-	return CS_SUCCESS;
-    }
-    status->CardState |=
-	(val & SS_WRPROT) ? CS_EVENT_WRITE_PROTECT : 0;
-    status->CardState |=
-	(val & SS_BATDEAD) ? CS_EVENT_BATTERY_DEAD : 0;
-    status->CardState |=
-	(val & SS_BATWARN) ? CS_EVENT_BATTERY_LOW : 0;
-    status->CardState |=
-	(val & SS_READY) ? CS_EVENT_READY_CHANGE : 0;
-    return CS_SUCCESS;
-} /* get_status */
-EXPORT_SYMBOL(pccard_get_status);
-
-/*======================================================================
-
-    Change the card address of an already open memory window.
-    
-======================================================================*/
-
-int pcmcia_get_mem_page(window_handle_t win, memreq_t *req)
-{
-    if ((win == NULL) || (win->magic != WINDOW_MAGIC))
-	return CS_BAD_HANDLE;
-    req->Page = 0;
-    req->CardOffset = win->ctl.card_start;
-    return CS_SUCCESS;
-} /* get_mem_page */
-
-int pcmcia_map_mem_page(window_handle_t win, memreq_t *req)
-{
-    struct pcmcia_socket *s;
-    if ((win == NULL) || (win->magic != WINDOW_MAGIC))
-	return CS_BAD_HANDLE;
-    if (req->Page != 0)
-	return CS_BAD_PAGE;
-    s = win->sock;
-    win->ctl.card_start = req->CardOffset;
-    if (s->ops->set_mem_map(s, &win->ctl) != 0)
-	return CS_BAD_OFFSET;
-    return CS_SUCCESS;
-} /* map_mem_page */
-
-/*======================================================================
-
-    Modify a locked socket configuration
-    
-======================================================================*/
-
-int pcmcia_modify_configuration(client_handle_t handle,
-				modconf_t *mod)
-{
-    struct pcmcia_socket *s;
-    config_t *c;
-    
-    if (CHECK_HANDLE(handle))
-	return CS_BAD_HANDLE;
-    s = SOCKET(handle); c = CONFIG(handle);
-    if (!(s->state & SOCKET_PRESENT))
-	return CS_NO_CARD;
-    if (!(c->state & CONFIG_LOCKED))
-	return CS_CONFIGURATION_LOCKED;
-    
-    if (mod->Attributes & CONF_IRQ_CHANGE_VALID) {
-	if (mod->Attributes & CONF_ENABLE_IRQ) {
-	    c->Attributes |= CONF_ENABLE_IRQ;
-	    s->socket.io_irq = s->irq.AssignedIRQ;
-	} else {
-	    c->Attributes &= ~CONF_ENABLE_IRQ;
-	    s->socket.io_irq = 0;
-	}
-	s->ops->set_socket(s, &s->socket);
-    }
-
-    if (mod->Attributes & CONF_VCC_CHANGE_VALID)
-	return CS_BAD_VCC;
-
-    /* We only allow changing Vpp1 and Vpp2 to the same value */
-    if ((mod->Attributes & CONF_VPP1_CHANGE_VALID) &&
-	(mod->Attributes & CONF_VPP2_CHANGE_VALID)) {
-	if (mod->Vpp1 != mod->Vpp2)
-	    return CS_BAD_VPP;
-	c->Vpp1 = c->Vpp2 = s->socket.Vpp = mod->Vpp1;
-	if (s->ops->set_socket(s, &s->socket))
-	    return CS_BAD_VPP;
-    } else if ((mod->Attributes & CONF_VPP1_CHANGE_VALID) ||
-	       (mod->Attributes & CONF_VPP2_CHANGE_VALID))
-	return CS_BAD_VPP;
-
-    return CS_SUCCESS;
-} /* modify_configuration */
-
 /* register pcmcia_callback */
 int pccard_register_pcmcia(struct pcmcia_socket *s, struct pcmcia_callback *c)
 {
@@ -1179,543 +742,16 @@ int pccard_register_pcmcia(struct pcmcia
 }
 EXPORT_SYMBOL(pccard_register_pcmcia);
 
-/*====================================================================*/
 
-int pcmcia_release_configuration(client_handle_t handle)
-{
-    pccard_io_map io = { 0, 0, 0, 0, 1 };
-    struct pcmcia_socket *s;
-    int i;
-    
-    if (CHECK_HANDLE(handle) ||
-	!(handle->state & CLIENT_CONFIG_LOCKED))
-	return CS_BAD_HANDLE;
-    handle->state &= ~CLIENT_CONFIG_LOCKED;
-    s = SOCKET(handle);
-    
-#ifdef CONFIG_CARDBUS
-    if (handle->state & CLIENT_CARDBUS)
-	return CS_SUCCESS;
-#endif
-    
-    if (!(handle->state & CLIENT_STALE)) {
-	config_t *c = CONFIG(handle);
-	if (--(s->lock_count) == 0) {
-	    s->socket.flags = SS_OUTPUT_ENA;   /* Is this correct? */
-	    s->socket.Vpp = 0;
-	    s->socket.io_irq = 0;
-	    s->ops->set_socket(s, &s->socket);
-	}
-	if (c->state & CONFIG_IO_REQ)
-	    for (i = 0; i < MAX_IO_WIN; i++) {
-		if (s->io[i].NumPorts == 0)
-		    continue;
-		s->io[i].Config--;
-		if (s->io[i].Config != 0)
-		    continue;
-		io.map = i;
-		s->ops->set_io_map(s, &io);
-	    }
-	c->state &= ~CONFIG_LOCKED;
-    }
-    
-    return CS_SUCCESS;
-} /* release_configuration */
-
-/*======================================================================
-
-    Release_io() releases the I/O ranges allocated by a client.  This
-    may be invoked some time after a card ejection has already dumped
-    the actual socket configuration, so if the client is "stale", we
-    don't bother checking the port ranges against the current socket
-    values.
-    
-======================================================================*/
-
-int pcmcia_release_io(client_handle_t handle, io_req_t *req)
-{
-    struct pcmcia_socket *s;
-    
-    if (CHECK_HANDLE(handle) || !(handle->state & CLIENT_IO_REQ))
-	return CS_BAD_HANDLE;
-    handle->state &= ~CLIENT_IO_REQ;
-    s = SOCKET(handle);
-    
-#ifdef CONFIG_CARDBUS
-    if (handle->state & CLIENT_CARDBUS)
-	return CS_SUCCESS;
-#endif
-    
-    if (!(handle->state & CLIENT_STALE)) {
-	config_t *c = CONFIG(handle);
-	if (c->state & CONFIG_LOCKED)
-	    return CS_CONFIGURATION_LOCKED;
-	if ((c->io.BasePort1 != req->BasePort1) ||
-	    (c->io.NumPorts1 != req->NumPorts1) ||
-	    (c->io.BasePort2 != req->BasePort2) ||
-	    (c->io.NumPorts2 != req->NumPorts2))
-	    return CS_BAD_ARGS;
-	c->state &= ~CONFIG_IO_REQ;
-    }
-
-    release_io_space(s, req->BasePort1, req->NumPorts1);
-    if (req->NumPorts2)
-	release_io_space(s, req->BasePort2, req->NumPorts2);
-    
-    return CS_SUCCESS;
-} /* release_io */
-
-/*====================================================================*/
-
-int pcmcia_release_irq(client_handle_t handle, irq_req_t *req)
-{
-    struct pcmcia_socket *s;
-    if (CHECK_HANDLE(handle) || !(handle->state & CLIENT_IRQ_REQ))
-	return CS_BAD_HANDLE;
-    handle->state &= ~CLIENT_IRQ_REQ;
-    s = SOCKET(handle);
-    
-    if (!(handle->state & CLIENT_STALE)) {
-	config_t *c = CONFIG(handle);
-	if (c->state & CONFIG_LOCKED)
-	    return CS_CONFIGURATION_LOCKED;
-	if (c->irq.Attributes != req->Attributes)
-	    return CS_BAD_ATTRIBUTE;
-	if (s->irq.AssignedIRQ != req->AssignedIRQ)
-	    return CS_BAD_IRQ;
-	if (--s->irq.Config == 0) {
-	    c->state &= ~CONFIG_IRQ_REQ;
-	    s->irq.AssignedIRQ = 0;
-	}
-    }
-    
-    if (req->Attributes & IRQ_HANDLE_PRESENT) {
-	free_irq(req->AssignedIRQ, req->Instance);
-    }
-
-#ifdef CONFIG_PCMCIA_PROBE
-    pcmcia_used_irq[req->AssignedIRQ]--;
-#endif
-
-    return CS_SUCCESS;
-} /* cs_release_irq */
-
-/*====================================================================*/
-
-int pcmcia_release_window(window_handle_t win)
-{
-    struct pcmcia_socket *s;
-    
-    if ((win == NULL) || (win->magic != WINDOW_MAGIC))
-	return CS_BAD_HANDLE;
-    s = win->sock;
-    if (!(win->handle->state & CLIENT_WIN_REQ(win->index)))
-	return CS_BAD_HANDLE;
-
-    /* Shut down memory window */
-    win->ctl.flags &= ~MAP_ACTIVE;
-    s->ops->set_mem_map(s, &win->ctl);
-    s->state &= ~SOCKET_WIN_REQ(win->index);
-
-    /* Release system memory */
-    if (win->ctl.res) {
-	release_resource(win->ctl.res);
-	kfree(win->ctl.res);
-	win->ctl.res = NULL;
-    }
-    win->handle->state &= ~CLIENT_WIN_REQ(win->index);
-
-    win->magic = 0;
-    
-    return CS_SUCCESS;
-} /* release_window */
-
-/*====================================================================*/
-
-int pcmcia_request_configuration(client_handle_t handle,
-				 config_req_t *req)
-{
-    int i;
-    u_int base;
-    struct pcmcia_socket *s;
-    config_t *c;
-    pccard_io_map iomap;
-    
-    if (CHECK_HANDLE(handle))
-	return CS_BAD_HANDLE;
-    s = SOCKET(handle);
-    if (!(s->state & SOCKET_PRESENT))
-	return CS_NO_CARD;
-    
-#ifdef CONFIG_CARDBUS
-    if (handle->state & CLIENT_CARDBUS)
-	return CS_UNSUPPORTED_MODE;
-#endif
-    
-    if (req->IntType & INT_CARDBUS)
-	return CS_UNSUPPORTED_MODE;
-    c = CONFIG(handle);
-    if (c->state & CONFIG_LOCKED)
-	return CS_CONFIGURATION_LOCKED;
-
-    /* Do power control.  We don't allow changes in Vcc. */
-    if (s->socket.Vcc != req->Vcc)
-	return CS_BAD_VCC;
-    if (req->Vpp1 != req->Vpp2)
-	return CS_BAD_VPP;
-    s->socket.Vpp = req->Vpp1;
-    if (s->ops->set_socket(s, &s->socket))
-	return CS_BAD_VPP;
-    
-    c->Vcc = req->Vcc; c->Vpp1 = c->Vpp2 = req->Vpp1;
-    
-    /* Pick memory or I/O card, DMA mode, interrupt */
-    c->IntType = req->IntType;
-    c->Attributes = req->Attributes;
-    if (req->IntType & INT_MEMORY_AND_IO)
-	s->socket.flags |= SS_IOCARD;
-    if (req->IntType & INT_ZOOMED_VIDEO)
-	s->socket.flags |= SS_ZVCARD | SS_IOCARD;
-    if (req->Attributes & CONF_ENABLE_DMA)
-	s->socket.flags |= SS_DMA_MODE;
-    if (req->Attributes & CONF_ENABLE_SPKR)
-	s->socket.flags |= SS_SPKR_ENA;
-    if (req->Attributes & CONF_ENABLE_IRQ)
-	s->socket.io_irq = s->irq.AssignedIRQ;
-    else
-	s->socket.io_irq = 0;
-    s->ops->set_socket(s, &s->socket);
-    s->lock_count++;
-    
-    /* Set up CIS configuration registers */
-    base = c->ConfigBase = req->ConfigBase;
-    c->Present = c->CardValues = req->Present;
-    if (req->Present & PRESENT_COPY) {
-	c->Copy = req->Copy;
-	write_cis_mem(s, 1, (base + CISREG_SCR)>>1, 1, &c->Copy);
-    }
-    if (req->Present & PRESENT_OPTION) {
-	if (s->functions == 1) {
-	    c->Option = req->ConfigIndex & COR_CONFIG_MASK;
-	} else {
-	    c->Option = req->ConfigIndex & COR_MFC_CONFIG_MASK;
-	    c->Option |= COR_FUNC_ENA|COR_IREQ_ENA;
-	    if (req->Present & PRESENT_IOBASE_0)
-		c->Option |= COR_ADDR_DECODE;
-	}
-	if (c->state & CONFIG_IRQ_REQ)
-	    if (!(c->irq.Attributes & IRQ_FORCED_PULSE))
-		c->Option |= COR_LEVEL_REQ;
-	write_cis_mem(s, 1, (base + CISREG_COR)>>1, 1, &c->Option);
-	mdelay(40);
-    }
-    if (req->Present & PRESENT_STATUS) {
-	c->Status = req->Status;
-	write_cis_mem(s, 1, (base + CISREG_CCSR)>>1, 1, &c->Status);
-    }
-    if (req->Present & PRESENT_PIN_REPLACE) {
-	c->Pin = req->Pin;
-	write_cis_mem(s, 1, (base + CISREG_PRR)>>1, 1, &c->Pin);
-    }
-    if (req->Present & PRESENT_EXT_STATUS) {
-	c->ExtStatus = req->ExtStatus;
-	write_cis_mem(s, 1, (base + CISREG_ESR)>>1, 1, &c->ExtStatus);
-    }
-    if (req->Present & PRESENT_IOBASE_0) {
-	u_char b = c->io.BasePort1 & 0xff;
-	write_cis_mem(s, 1, (base + CISREG_IOBASE_0)>>1, 1, &b);
-	b = (c->io.BasePort1 >> 8) & 0xff;
-	write_cis_mem(s, 1, (base + CISREG_IOBASE_1)>>1, 1, &b);
-    }
-    if (req->Present & PRESENT_IOSIZE) {
-	u_char b = c->io.NumPorts1 + c->io.NumPorts2 - 1;
-	write_cis_mem(s, 1, (base + CISREG_IOSIZE)>>1, 1, &b);
-    }
-    
-    /* Configure I/O windows */
-    if (c->state & CONFIG_IO_REQ) {
-	iomap.speed = io_speed;
-	for (i = 0; i < MAX_IO_WIN; i++)
-	    if (s->io[i].NumPorts != 0) {
-		iomap.map = i;
-		iomap.flags = MAP_ACTIVE;
-		switch (s->io[i].Attributes & IO_DATA_PATH_WIDTH) {
-		case IO_DATA_PATH_WIDTH_16:
-		    iomap.flags |= MAP_16BIT; break;
-		case IO_DATA_PATH_WIDTH_AUTO:
-		    iomap.flags |= MAP_AUTOSZ; break;
-		default:
-		    break;
-		}
-		iomap.start = s->io[i].BasePort;
-		iomap.stop = iomap.start + s->io[i].NumPorts - 1;
-		s->ops->set_io_map(s, &iomap);
-		s->io[i].Config++;
-	    }
-    }
-    
-    c->state |= CONFIG_LOCKED;
-    handle->state |= CLIENT_CONFIG_LOCKED;
-    return CS_SUCCESS;
-} /* request_configuration */
-
-/*======================================================================
-  
-    Request_io() reserves ranges of port addresses for a socket.
-    I have not implemented range sharing or alias addressing.
-    
-======================================================================*/
-
-int pcmcia_request_io(client_handle_t handle, io_req_t *req)
-{
-    struct pcmcia_socket *s;
-    config_t *c;
-    
-    if (CHECK_HANDLE(handle))
-	return CS_BAD_HANDLE;
-    s = SOCKET(handle);
-    if (!(s->state & SOCKET_PRESENT))
-	return CS_NO_CARD;
-
-    if (handle->state & CLIENT_CARDBUS) {
-#ifdef CONFIG_CARDBUS
-	handle->state |= CLIENT_IO_REQ;
-	return CS_SUCCESS;
-#else
-	return CS_UNSUPPORTED_FUNCTION;
-#endif
-    }
-
-    if (!req)
-	return CS_UNSUPPORTED_MODE;
-    c = CONFIG(handle);
-    if (c->state & CONFIG_LOCKED)
-	return CS_CONFIGURATION_LOCKED;
-    if (c->state & CONFIG_IO_REQ)
-	return CS_IN_USE;
-    if (req->Attributes1 & (IO_SHARED | IO_FORCE_ALIAS_ACCESS))
-	return CS_BAD_ATTRIBUTE;
-    if ((req->NumPorts2 > 0) &&
-	(req->Attributes2 & (IO_SHARED | IO_FORCE_ALIAS_ACCESS)))
-	return CS_BAD_ATTRIBUTE;
-
-    if (alloc_io_space(s, req->Attributes1, &req->BasePort1,
-		       req->NumPorts1, req->IOAddrLines))
-	return CS_IN_USE;
-
-    if (req->NumPorts2) {
-	if (alloc_io_space(s, req->Attributes2, &req->BasePort2,
-			   req->NumPorts2, req->IOAddrLines)) {
-	    release_io_space(s, req->BasePort1, req->NumPorts1);
-	    return CS_IN_USE;
-	}
-    }
-
-    c->io = *req;
-    c->state |= CONFIG_IO_REQ;
-    handle->state |= CLIENT_IO_REQ;
-    return CS_SUCCESS;
-} /* request_io */
-
-/*======================================================================
-
-    Request_irq() reserves an irq for this client.
-
-    Also, since Linux only reserves irq's when they are actually
-    hooked, we don't guarantee that an irq will still be available
-    when the configuration is locked.  Now that I think about it,
-    there might be a way to fix this using a dummy handler.
-    
-======================================================================*/
-
-#ifdef CONFIG_PCMCIA_PROBE
-static irqreturn_t test_action(int cpl, void *dev_id, struct pt_regs *regs)
-{
-	return IRQ_NONE;
-}
-#endif
-
-int pcmcia_request_irq(client_handle_t handle, irq_req_t *req)
-{
-	struct pcmcia_socket *s;
-	config_t *c;
-	int ret = CS_IN_USE, irq = 0;
-	struct pcmcia_device *p_dev = handle_to_pdev(handle);
-
-	if (CHECK_HANDLE(handle))
-		return CS_BAD_HANDLE;
-	s = SOCKET(handle);
-	if (!(s->state & SOCKET_PRESENT))
-		return CS_NO_CARD;
-	c = CONFIG(handle);
-	if (c->state & CONFIG_LOCKED)
-		return CS_CONFIGURATION_LOCKED;
-	if (c->state & CONFIG_IRQ_REQ)
-		return CS_IN_USE;
-
-#ifdef CONFIG_PCMCIA_PROBE
-	if (s->irq.AssignedIRQ != 0) {
-		/* If the interrupt is already assigned, it must be the same */
-		irq = s->irq.AssignedIRQ;
-	} else {
-		int try;
-		u32 mask = s->irq_mask;
-		void *data = NULL;
-
-		for (try = 0; try < 64; try++) {
-			irq = try % 32;
-
-			/* marked as available by driver, and not blocked by userspace? */
-			if (!((mask >> irq) & 1))
-				continue;
-
-			/* avoid an IRQ which is already used by a PCMCIA card */
-			if ((try < 32) && pcmcia_used_irq[irq])
-				continue;
-
-			/* register the correct driver, if possible, of check whether
-			 * registering a dummy handle works, i.e. if the IRQ isn't
-			 * marked as used by the kernel resource management core */
-			ret = request_irq(irq,
-					  (req->Attributes & IRQ_HANDLE_PRESENT) ? req->Handler : test_action,
-					  ((req->Attributes & IRQ_TYPE_DYNAMIC_SHARING) ||
-					   (s->functions > 1) ||
-					   (irq == s->pci_irq)) ? SA_SHIRQ : 0,
-					  p_dev->dev.bus_id,
-					  (req->Attributes & IRQ_HANDLE_PRESENT) ? req->Instance : data);
-			if (!ret) {
-				if (!(req->Attributes & IRQ_HANDLE_PRESENT))
-					free_irq(irq, data);
-				break;
-			}
-		}
-	}
-#endif
-	if (ret) {
-		if (!s->pci_irq)
-			return ret;
-		irq = s->pci_irq;
-	}
-
-	if (ret && req->Attributes & IRQ_HANDLE_PRESENT) {
-		if (request_irq(irq, req->Handler,
-				((req->Attributes & IRQ_TYPE_DYNAMIC_SHARING) ||
-				 (s->functions > 1) ||
-				 (irq == s->pci_irq)) ? SA_SHIRQ : 0,
-				p_dev->dev.bus_id, req->Instance))
-			return CS_IN_USE;
-	}
-
-	c->irq.Attributes = req->Attributes;
-	s->irq.AssignedIRQ = req->AssignedIRQ = irq;
-	s->irq.Config++;
-
-	c->state |= CONFIG_IRQ_REQ;
-	handle->state |= CLIENT_IRQ_REQ;
-
-#ifdef CONFIG_PCMCIA_PROBE
-	pcmcia_used_irq[irq]++;
-#endif
-
-	return CS_SUCCESS;
-} /* pcmcia_request_irq */
-
-/*======================================================================
-
-    Request_window() establishes a mapping between card memory space
-    and system memory space.
-
-======================================================================*/
-
-int pcmcia_request_window(client_handle_t *handle, win_req_t *req, window_handle_t *wh)
-{
-    struct pcmcia_socket *s;
-    window_t *win;
-    u_long align;
-    int w;
-    
-    if (CHECK_HANDLE(*handle))
-	return CS_BAD_HANDLE;
-    s = (*handle)->Socket;
-    if (!(s->state & SOCKET_PRESENT))
-	return CS_NO_CARD;
-    if (req->Attributes & (WIN_PAGED | WIN_SHARED))
-	return CS_BAD_ATTRIBUTE;
-
-    /* Window size defaults to smallest available */
-    if (req->Size == 0)
-	req->Size = s->map_size;
-    align = (((s->features & SS_CAP_MEM_ALIGN) ||
-	      (req->Attributes & WIN_STRICT_ALIGN)) ?
-	     req->Size : s->map_size);
-    if (req->Size & (s->map_size-1))
-	return CS_BAD_SIZE;
-    if ((req->Base && (s->features & SS_CAP_STATIC_MAP)) ||
-	(req->Base & (align-1)))
-	return CS_BAD_BASE;
-    if (req->Base)
-	align = 0;
-
-    /* Allocate system memory window */
-    for (w = 0; w < MAX_WIN; w++)
-	if (!(s->state & SOCKET_WIN_REQ(w))) break;
-    if (w == MAX_WIN)
-	return CS_OUT_OF_RESOURCE;
-
-    win = &s->win[w];
-    win->magic = WINDOW_MAGIC;
-    win->index = w;
-    win->handle = *handle;
-    win->sock = s;
-
-    if (!(s->features & SS_CAP_STATIC_MAP)) {
-	win->ctl.res = find_mem_region(req->Base, req->Size, align,
-				       (req->Attributes & WIN_MAP_BELOW_1MB), s);
-	if (!win->ctl.res)
-	    return CS_IN_USE;
-    }
-    (*handle)->state |= CLIENT_WIN_REQ(w);
-
-    /* Configure the socket controller */
-    win->ctl.map = w+1;
-    win->ctl.flags = 0;
-    win->ctl.speed = req->AccessSpeed;
-    if (req->Attributes & WIN_MEMORY_TYPE)
-	win->ctl.flags |= MAP_ATTRIB;
-    if (req->Attributes & WIN_ENABLE)
-	win->ctl.flags |= MAP_ACTIVE;
-    if (req->Attributes & WIN_DATA_WIDTH_16)
-	win->ctl.flags |= MAP_16BIT;
-    if (req->Attributes & WIN_USE_WAIT)
-	win->ctl.flags |= MAP_USE_WAIT;
-    win->ctl.card_start = 0;
-    if (s->ops->set_mem_map(s, &win->ctl) != 0)
-	return CS_BAD_ARGS;
-    s->state |= SOCKET_WIN_REQ(w);
-
-    /* Return window handle */
-    if (s->features & SS_CAP_STATIC_MAP) {
-	req->Base = win->ctl.static_start;
-    } else {
-	req->Base = win->ctl.res->start;
-    }
-    *wh = win;
-    
-    return CS_SUCCESS;
-} /* request_window */
-
-/*======================================================================
-
-    I'm not sure which "reset" function this is supposed to use,
-    but for now, it uses the low-level interface's reset, not the
-    CIS register.
-    
-======================================================================*/
+/* I'm not sure which "reset" function this is supposed to use,
+ * but for now, it uses the low-level interface's reset, not the
+ * CIS register.
+ */
 
 int pccard_reset_card(struct pcmcia_socket *skt)
 {
 	int ret;
-    
+
 	cs_dbg(skt, 1, "resetting socket\n");
 
 	down(&skt->skt_sem);
@@ -1748,17 +784,14 @@ int pccard_reset_card(struct pcmcia_sock
 } /* reset_card */
 EXPORT_SYMBOL(pccard_reset_card);
 
-/*======================================================================
-
-    These shut down or wake up a socket.  They are sort of user
-    initiated versions of the APM suspend and resume actions.
-    
-======================================================================*/
 
+/* These shut down or wake up a socket.  They are sort of user
+ * initiated versions of the APM suspend and resume actions.
+ */
 int pcmcia_suspend_card(struct pcmcia_socket *skt)
 {
 	int ret;
-    
+
 	cs_dbg(skt, 1, "suspending socket\n");
 
 	down(&skt->skt_sem);
@@ -1777,6 +810,8 @@ int pcmcia_suspend_card(struct pcmcia_so
 
 	return ret;
 } /* suspend_card */
+EXPORT_SYMBOL(pcmcia_suspend_card);
+
 
 int pcmcia_resume_card(struct pcmcia_socket *skt)
 {
@@ -1800,13 +835,10 @@ int pcmcia_resume_card(struct pcmcia_soc
 
 	return ret;
 } /* resume_card */
+EXPORT_SYMBOL(pcmcia_resume_card);
 
-/*======================================================================
-
-    These handle user requests to eject or insert a card.
-    
-======================================================================*/
 
+/* These handle user requests to eject or insert a card. */
 int pcmcia_eject_card(struct pcmcia_socket *skt)
 {
 	int ret;
@@ -1833,6 +865,8 @@ int pcmcia_eject_card(struct pcmcia_sock
 
 	return ret;
 } /* eject_card */
+EXPORT_SYMBOL(pcmcia_eject_card);
+
 
 int pcmcia_insert_card(struct pcmcia_socket *skt)
 {
@@ -1856,37 +890,38 @@ int pcmcia_insert_card(struct pcmcia_soc
 
 	return ret;
 } /* insert_card */
+EXPORT_SYMBOL(pcmcia_insert_card);
 
-/*======================================================================
 
-    OS-specific module glue goes here
-    
-======================================================================*/
-/* in alpha order */
-EXPORT_SYMBOL(pcmcia_eject_card);
-EXPORT_SYMBOL(pcmcia_get_card_services_info);
-EXPORT_SYMBOL(pcmcia_get_mem_page);
-EXPORT_SYMBOL(pcmcia_insert_card);
-EXPORT_SYMBOL(pcmcia_map_mem_page);
-EXPORT_SYMBOL(pcmcia_modify_configuration);
-EXPORT_SYMBOL(pcmcia_release_configuration);
-EXPORT_SYMBOL(pcmcia_release_io);
-EXPORT_SYMBOL(pcmcia_release_irq);
-EXPORT_SYMBOL(pcmcia_release_window);
-EXPORT_SYMBOL(pcmcia_replace_cis);
-EXPORT_SYMBOL(pcmcia_request_configuration);
-EXPORT_SYMBOL(pcmcia_request_io);
-EXPORT_SYMBOL(pcmcia_request_irq);
-EXPORT_SYMBOL(pcmcia_request_window);
-EXPORT_SYMBOL(pcmcia_resume_card);
-EXPORT_SYMBOL(pcmcia_suspend_card);
+static int pcmcia_socket_hotplug(struct class_device *dev, char **envp,
+				int num_envp, char *buffer, int buffer_size)
+{
+	struct pcmcia_socket *s = container_of(dev, struct pcmcia_socket, dev);
+	int i = 0, length = 0;
+
+	if (add_hotplug_env_var(envp, num_envp, &i, buffer, buffer_size,
+				&length, "SOCKET_NO=%u", s->sock))
+		return -ENOMEM;
+
+	envp[i] = NULL;
+
+	return 0;
+}
+
+
+static struct completion pcmcia_unload;
+
+static void pcmcia_release_socket_class(struct class *data)
+{
+	complete(&pcmcia_unload);
+}
 
-EXPORT_SYMBOL(dead_socket);
-EXPORT_SYMBOL(pcmcia_parse_events);
 
 struct class pcmcia_socket_class = {
 	.name = "pcmcia_socket",
+        .hotplug = pcmcia_socket_hotplug,
 	.release = pcmcia_release_socket,
+	.class_release = pcmcia_release_socket_class,
 };
 EXPORT_SYMBOL(pcmcia_socket_class);
 
@@ -1894,9 +929,8 @@ EXPORT_SYMBOL(pcmcia_socket_class);
 static int __init init_pcmcia_cs(void)
 {
 	int ret;
-	printk(KERN_INFO "%s\n", release);
-	printk(KERN_INFO "  %s\n", options);
 
+	init_completion(&pcmcia_unload);
 	ret = class_register(&pcmcia_socket_class);
 	if (ret)
 		return (ret);
@@ -1905,13 +939,12 @@ static int __init init_pcmcia_cs(void)
 
 static void __exit exit_pcmcia_cs(void)
 {
-    printk(KERN_INFO "unloading Kernel Card Services\n");
-    class_interface_unregister(&pccard_sysfs_interface);
-    class_unregister(&pcmcia_socket_class);
+	class_interface_unregister(&pccard_sysfs_interface);
+	class_unregister(&pcmcia_socket_class);
+
+	wait_for_completion(&pcmcia_unload);
 }
 
 subsys_initcall(init_pcmcia_cs);
 module_exit(exit_pcmcia_cs);
 
-/*====================================================================*/
-
diff --git a/drivers/pcmcia/cs_internal.h b/drivers/pcmcia/cs_internal.h
--- a/drivers/pcmcia/cs_internal.h
+++ b/drivers/pcmcia/cs_internal.h
@@ -99,23 +99,11 @@ static inline void cs_socket_put(struct 
 	}
 }
 
-#define CHECK_HANDLE(h) \
-    (((h) == NULL) || ((h)->client_magic != CLIENT_MAGIC))
-
 #define CHECK_SOCKET(s) \
     (((s) >= sockets) || (socket_table[s]->ops == NULL))
 
-#define SOCKET(h) (h->Socket)
-#define CONFIG(h) (&SOCKET(h)->config[(h)->Function])
-
-#define CHECK_REGION(r) \
-    (((r) == NULL) || ((r)->region_magic != REGION_MAGIC))
-
-#define CHECK_ERASEQ(q) \
-    (((q) == NULL) || ((q)->eraseq_magic != ERASEQ_MAGIC))
-
-#define EVENT(h, e, p) \
-    ((h)->event_handler((e), (p), &(h)->event_callback_args))
+#define SOCKET(h) (h->socket)
+#define CONFIG(h) (&SOCKET(h)->config[(h)->func])
 
 /* In cardbus.c */
 int cb_alloc(struct pcmcia_socket *s);
@@ -123,9 +111,9 @@ void cb_free(struct pcmcia_socket *s);
 int read_cb_mem(struct pcmcia_socket *s, int space, u_int addr, u_int len, void *ptr);
 
 /* In cistpl.c */
-int read_cis_mem(struct pcmcia_socket *s, int attr,
+int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr,
 		 u_int addr, u_int len, void *ptr);
-void write_cis_mem(struct pcmcia_socket *s, int attr,
+void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr,
 		   u_int addr, u_int len, void *ptr);
 void release_cis_mem(struct pcmcia_socket *s);
 void destroy_cis_cache(struct pcmcia_socket *s);
@@ -134,13 +122,12 @@ int pccard_read_tuple(struct pcmcia_sock
 
 /* In rsrc_mgr */
 void pcmcia_validate_mem(struct pcmcia_socket *s);
-struct resource *find_io_region(unsigned long base, int num, unsigned long align,
+struct resource *pcmcia_find_io_region(unsigned long base, int num, unsigned long align,
 		   struct pcmcia_socket *s);
-int adjust_io_region(struct resource *res, unsigned long r_start,
+int pcmcia_adjust_io_region(struct resource *res, unsigned long r_start,
 		     unsigned long r_end, struct pcmcia_socket *s);
-struct resource *find_mem_region(u_long base, u_long num, u_long align,
+struct resource *pcmcia_find_mem_region(u_long base, u_long num, u_long align,
 		    int low, struct pcmcia_socket *s);
-int adjust_resource_info(client_handle_t handle, adjust_t *adj);
 void release_resource_db(struct pcmcia_socket *s);
 
 /* In socket_sysfs.c */
@@ -159,7 +146,7 @@ int pccard_access_configuration_register
 struct pcmcia_callback{
 	struct module	*owner;
 	int		(*event) (struct pcmcia_socket *s, event_t event, int priority);
-	int		(*resources_done) (struct pcmcia_socket *s);
+	void		(*requery) (struct pcmcia_socket *s);
 };
 
 int pccard_register_pcmcia(struct pcmcia_socket *s, struct pcmcia_callback *c);
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c
--- a/drivers/pcmcia/ds.c
+++ b/drivers/pcmcia/ds.c
@@ -10,44 +10,29 @@
  * are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
  *
  * (C) 1999		David A. Hinds
- * (C) 2003 - 2004	Dominik Brodowski
+ * (C) 2003 - 2005	Dominik Brodowski
  */
 
 #include <linux/config.h>
+#include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/major.h>
-#include <linux/string.h>
 #include <linux/errno.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/fcntl.h>
-#include <linux/sched.h>
-#include <linux/smp_lock.h>
-#include <linux/timer.h>
-#include <linux/ioctl.h>
-#include <linux/proc_fs.h>
-#include <linux/poll.h>
-#include <linux/pci.h>
 #include <linux/list.h>
 #include <linux/delay.h>
-#include <linux/kref.h>
 #include <linux/workqueue.h>
-
-#include <asm/atomic.h>
+#include <linux/crc32.h>
+#include <linux/firmware.h>
 
 #define IN_CARD_SERVICES
-#include <pcmcia/version.h>
 #include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
-#include <pcmcia/bulkmem.h>
 #include <pcmcia/cistpl.h>
 #include <pcmcia/ds.h>
 #include <pcmcia/ss.h>
 
 #include "cs_internal.h"
+#include "ds_internal.h"
 
 /*====================================================================*/
 
@@ -70,49 +55,9 @@ module_param_named(pc_debug, ds_pc_debug
 #define ds_dbg(lvl, fmt, arg...) do { } while (0)
 #endif
 
-/*====================================================================*/
+spinlock_t pcmcia_dev_list_lock;
 
-/* Device user information */
-#define MAX_EVENTS	32
-#define USER_MAGIC	0x7ea4
-#define CHECK_USER(u) \
-    (((u) == NULL) || ((u)->user_magic != USER_MAGIC))
-typedef struct user_info_t {
-    u_int		user_magic;
-    int			event_head, event_tail;
-    event_t		event[MAX_EVENTS];
-    struct user_info_t	*next;
-    struct pcmcia_bus_socket *socket;
-} user_info_t;
-
-/* Socket state information */
-struct pcmcia_bus_socket {
-	struct kref		refcount;
-	struct pcmcia_callback	callback;
-	int			state;
-	user_info_t		*user;
-	wait_queue_head_t	queue;
-	struct pcmcia_socket	*parent;
-
-	/* the PCMCIA devices connected to this socket (normally one, more
-	 * for multifunction devices: */
-	struct list_head	devices_list;
-	u8			device_count; /* the number of devices, used
-					       * only internally and subject
-					       * to incorrectness and change */
-};
-static spinlock_t pcmcia_dev_list_lock;
-
-#define DS_SOCKET_PRESENT		0x01
-#define DS_SOCKET_BUSY			0x02
-#define DS_SOCKET_REMOVAL_PENDING	0x10
-#define DS_SOCKET_DEAD			0x80
-
-/*====================================================================*/
-
-static int major_dev = -1;
-
-static int unbind_request(struct pcmcia_bus_socket *s);
+static int unbind_request(struct pcmcia_socket *s);
 
 /*====================================================================*/
 
@@ -213,17 +158,15 @@ static const lookup_t service_table[] = 
 };
 
 
-int pcmcia_report_error(client_handle_t handle, error_info_t *err)
+static int pcmcia_report_error(struct pcmcia_device *p_dev, error_info_t *err)
 {
 	int i;
 	char *serv;
 
-	if (CHECK_HANDLE(handle))
+	if (!p_dev)
 		printk(KERN_NOTICE);
-	else {
-		struct pcmcia_device *p_dev = handle_to_pdev(handle);
+	else
 		printk(KERN_NOTICE "%s: ", p_dev->dev.bus_id);
-	}
 
 	for (i = 0; i < ARRAY_SIZE(service_table); i++)
 		if (service_table[i].key == err->func)
@@ -243,42 +186,117 @@ int pcmcia_report_error(client_handle_t 
 
 	return CS_SUCCESS;
 } /* report_error */
-EXPORT_SYMBOL(pcmcia_report_error);
 
 /* end of code which was in cs.c before */
 
 /*======================================================================*/
 
-void cs_error(client_handle_t handle, int func, int ret)
+void cs_error(struct pcmcia_device *p_dev, int func, int ret)
 {
 	error_info_t err = { func, ret };
-	pcmcia_report_error(handle, &err);
+	pcmcia_report_error(p_dev, &err);
 }
 EXPORT_SYMBOL(cs_error);
 
-/*======================================================================*/
-
-static struct pcmcia_driver * get_pcmcia_driver (dev_info_t *dev_info);
-static struct pcmcia_bus_socket * get_socket_info_by_nr(unsigned int nr);
 
-static void pcmcia_release_bus_socket(struct kref *refcount)
+static void pcmcia_check_driver(struct pcmcia_driver *p_drv)
 {
-	struct pcmcia_bus_socket *s = container_of(refcount, struct pcmcia_bus_socket, refcount);
-	pcmcia_put_socket(s->parent);
-	kfree(s);
+	struct pcmcia_device_id *did = p_drv->id_table;
+	unsigned int i;
+	u32 hash;
+
+	if (!p_drv->attach || !p_drv->event || !p_drv->detach)
+		printk(KERN_DEBUG "pcmcia: %s lacks a requisite callback "
+		       "function\n", p_drv->drv.name);
+
+	while (did && did->match_flags) {
+		for (i=0; i<4; i++) {
+			if (!did->prod_id[i])
+				continue;
+
+			hash = crc32(0, did->prod_id[i], strlen(did->prod_id[i]));
+			if (hash == did->prod_id_hash[i])
+				continue;
+
+			printk(KERN_DEBUG "pcmcia: %s: invalid hash for "
+			       "product string \"%s\": is 0x%x, should "
+			       "be 0x%x\n", p_drv->drv.name, did->prod_id[i],
+			       did->prod_id_hash[i], hash);
+			printk(KERN_DEBUG "pcmcia: see "
+				"Documentation/pcmcia/devicetable.txt for "
+				"details\n");
+		}
+		did++;
+	}
+
+	return;
 }
 
-static void pcmcia_put_bus_socket(struct pcmcia_bus_socket *s)
+
+#ifdef CONFIG_PCMCIA_LOAD_CIS
+
+/**
+ * pcmcia_load_firmware - load CIS from userspace if device-provided is broken
+ * @dev - the pcmcia device which needs a CIS override
+ * @filename - requested filename in /lib/firmware/cis/
+ *
+ * This uses the in-kernel firmware loading mechanism to use a "fake CIS" if
+ * the one provided by the card is broken. The firmware files reside in
+ * /lib/firmware/cis/ in userspace.
+ */
+static int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename)
 {
-	kref_put(&s->refcount, pcmcia_release_bus_socket);
+	struct pcmcia_socket *s = dev->socket;
+	const struct firmware *fw;
+	char path[20];
+	int ret=-ENOMEM;
+	cisdump_t *cis;
+
+	if (!filename)
+		return -EINVAL;
+
+	ds_dbg(1, "trying to load firmware %s\n", filename);
+
+	if (strlen(filename) > 14)
+		return -EINVAL;
+
+	snprintf(path, 20, "%s", filename);
+
+	if (request_firmware(&fw, path, &dev->dev) == 0) {
+		if (fw->size >= CISTPL_MAX_CIS_SIZE)
+			goto release;
+
+		cis = kmalloc(sizeof(cisdump_t), GFP_KERNEL);
+		if (!cis)
+			goto release;
+
+		memset(cis, 0, sizeof(cisdump_t));
+
+		cis->Length = fw->size + 1;
+		memcpy(cis->Data, fw->data, fw->size);
+
+		if (!pcmcia_replace_cis(s, cis))
+			ret = 0;
+	}
+ release:
+	release_firmware(fw);
+
+	return (ret);
 }
 
-static struct pcmcia_bus_socket *pcmcia_get_bus_socket(struct pcmcia_bus_socket *s)
+#else /* !CONFIG_PCMCIA_LOAD_CIS */
+
+static inline int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename)
 {
-	kref_get(&s->refcount);
-	return (s);
+	return -ENODEV;
 }
 
+#endif
+
+
+/*======================================================================*/
+
+
 /**
  * pcmcia_register_driver - register a PCMCIA driver with the bus core
  *
@@ -292,6 +310,8 @@ int pcmcia_register_driver(struct pcmcia
 	if (!driver)
 		return -EINVAL;
 
+	pcmcia_check_driver(driver);
+
 	/* initialize common fields */
 	driver->drv.bus = &pcmcia_bus_type;
 	driver->drv.owner = driver->owner;
@@ -311,42 +331,10 @@ void pcmcia_unregister_driver(struct pcm
 }
 EXPORT_SYMBOL(pcmcia_unregister_driver);
 
-#ifdef CONFIG_PROC_FS
-static struct proc_dir_entry *proc_pccard = NULL;
-
-static int proc_read_drivers_callback(struct device_driver *driver, void *d)
-{
-	char **p = d;
-	struct pcmcia_driver *p_drv = container_of(driver,
-						   struct pcmcia_driver, drv);
-
-	*p += sprintf(*p, "%-24.24s 1 %d\n", p_drv->drv.name,
-#ifdef CONFIG_MODULE_UNLOAD
-		      (p_drv->owner) ? module_refcount(p_drv->owner) : 1
-#else
-		      1
-#endif
-	);
-	d = (void *) p;
-
-	return 0;
-}
-
-static int proc_read_drivers(char *buf, char **start, off_t pos,
-			     int count, int *eof, void *data)
-{
-	char *p = buf;
-
-	bus_for_each_drv(&pcmcia_bus_type, NULL, 
-			 (void *) &p, proc_read_drivers_callback);
-
-	return (p - buf);
-}
-#endif
 
 /* pcmcia_device handling */
 
-static struct pcmcia_device * pcmcia_get_dev(struct pcmcia_device *p_dev)
+struct pcmcia_device * pcmcia_get_dev(struct pcmcia_device *p_dev)
 {
 	struct device *tmp_dev;
 	tmp_dev = get_device(&p_dev->dev);
@@ -355,7 +343,7 @@ static struct pcmcia_device * pcmcia_get
 	return to_pcmcia_dev(tmp_dev);
 }
 
-static void pcmcia_put_dev(struct pcmcia_device *p_dev)
+void pcmcia_put_dev(struct pcmcia_device *p_dev)
 {
 	if (p_dev)
 		put_device(&p_dev->dev);
@@ -365,7 +353,7 @@ static void pcmcia_release_dev(struct de
 {
 	struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
 	ds_dbg(1, "releasing dev %p\n", p_dev);
-	pcmcia_put_bus_socket(p_dev->socket->pcmcia);
+	pcmcia_put_socket(p_dev->socket);
 	kfree(p_dev);
 }
 
@@ -390,7 +378,7 @@ static int pcmcia_device_probe(struct de
 
 	if (p_drv->attach) {
 		p_dev->instance = p_drv->attach();
-		if ((!p_dev->instance) || (p_dev->client.state & CLIENT_UNBOUND)) {
+		if ((!p_dev->instance) || (p_dev->state & CLIENT_UNBOUND)) {
 			printk(KERN_NOTICE "ds: unable to create instance "
 			       "of '%s'!\n", p_drv->drv.name);
 			ret = -EINVAL;
@@ -500,42 +488,45 @@ static int pcmcia_device_query(struct pc
  */
 static DECLARE_MUTEX(device_add_lock);
 
-static struct pcmcia_device * pcmcia_device_add(struct pcmcia_bus_socket *s, unsigned int function)
+struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int function)
 {
 	struct pcmcia_device *p_dev;
 	unsigned long flags;
 
-	s = pcmcia_get_bus_socket(s);
+	s = pcmcia_get_socket(s);
 	if (!s)
 		return NULL;
 
 	down(&device_add_lock);
 
+	/* max of 2 devices per card */
+	if (s->device_count == 2)
+		goto err_put;
+
 	p_dev = kmalloc(sizeof(struct pcmcia_device), GFP_KERNEL);
 	if (!p_dev)
 		goto err_put;
 	memset(p_dev, 0, sizeof(struct pcmcia_device));
 
-	p_dev->socket = s->parent;
+	p_dev->socket = s;
 	p_dev->device_no = (s->device_count++);
 	p_dev->func   = function;
 
 	p_dev->dev.bus = &pcmcia_bus_type;
-	p_dev->dev.parent = s->parent->dev.dev;
+	p_dev->dev.parent = s->dev.dev;
 	p_dev->dev.release = pcmcia_release_dev;
 	sprintf (p_dev->dev.bus_id, "%d.%d", p_dev->socket->sock, p_dev->device_no);
 
 	/* compat */
-	p_dev->client.client_magic = CLIENT_MAGIC;
-	p_dev->client.Socket = s->parent;
-	p_dev->client.Function = function;
-	p_dev->client.state = CLIENT_UNBOUND;
+	p_dev->state = CLIENT_UNBOUND;
 
 	/* Add to the list in pcmcia_bus_socket */
 	spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
 	list_add_tail(&p_dev->socket_device_list, &s->devices_list);
 	spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
 
+	pcmcia_device_query(p_dev);
+
 	if (device_register(&p_dev->dev)) {
 		spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
 		list_del(&p_dev->socket_device_list);
@@ -553,7 +544,7 @@ static struct pcmcia_device * pcmcia_dev
 	s->device_count--;
  err_put:
 	up(&device_add_lock);
-	pcmcia_put_bus_socket(s);
+	pcmcia_put_socket(s);
 
 	return NULL;
 }
@@ -581,37 +572,264 @@ static int pcmcia_card_add(struct pcmcia
 	else
 		no_funcs = 1;
 
-	/* this doesn't handle multifunction devices on one pcmcia function
-	 * yet. */
 	for (i=0; i < no_funcs; i++)
-		pcmcia_device_add(s->pcmcia, i);
+		pcmcia_device_add(s, i);
 
 	return (ret);
 }
 
 
+static void pcmcia_delayed_add_pseudo_device(void *data)
+{
+	struct pcmcia_socket *s = data;
+	pcmcia_device_add(s, 0);
+	s->pcmcia_state.device_add_pending = 0;
+}
+
+static inline void pcmcia_add_pseudo_device(struct pcmcia_socket *s)
+{
+	if (!s->pcmcia_state.device_add_pending) {
+		s->pcmcia_state.device_add_pending = 1;
+		schedule_work(&s->device_add);
+	}
+	return;
+}
+
+static int pcmcia_requery(struct device *dev, void * _data)
+{
+	struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
+	if (!p_dev->dev.driver)
+		pcmcia_device_query(p_dev);
+
+	return 0;
+}
+
+static void pcmcia_bus_rescan(struct pcmcia_socket *skt)
+{
+	int no_devices=0;
+	unsigned long flags;
+
+	/* must be called with skt_sem held */
+	spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
+	if (list_empty(&skt->devices_list))
+		no_devices=1;
+	spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
+
+	/* if no devices were added for this socket yet because of
+	 * missing resource information or other trouble, we need to
+	 * do this now. */
+	if (no_devices) {
+		int ret = pcmcia_card_add(skt);
+		if (ret)
+			return;
+	}
+
+	/* some device information might have changed because of a CIS
+	 * update or because we can finally read it correctly... so
+	 * determine it again, overwriting old values if necessary. */
+	bus_for_each_dev(&pcmcia_bus_type, NULL, NULL, pcmcia_requery);
+
+	/* we re-scan all devices, not just the ones connected to this
+	 * socket. This does not matter, though. */
+	bus_rescan_devices(&pcmcia_bus_type);
+}
+
+static inline int pcmcia_devmatch(struct pcmcia_device *dev,
+				  struct pcmcia_device_id *did)
+{
+	if (did->match_flags & PCMCIA_DEV_ID_MATCH_MANF_ID) {
+		if ((!dev->has_manf_id) || (dev->manf_id != did->manf_id))
+			return 0;
+	}
+
+	if (did->match_flags & PCMCIA_DEV_ID_MATCH_CARD_ID) {
+		if ((!dev->has_card_id) || (dev->card_id != did->card_id))
+			return 0;
+	}
+
+	if (did->match_flags & PCMCIA_DEV_ID_MATCH_FUNCTION) {
+		if (dev->func != did->function)
+			return 0;
+	}
+
+	if (did->match_flags & PCMCIA_DEV_ID_MATCH_PROD_ID1) {
+		if (!dev->prod_id[0])
+			return 0;
+		if (strcmp(did->prod_id[0], dev->prod_id[0]))
+			return 0;
+	}
+
+	if (did->match_flags & PCMCIA_DEV_ID_MATCH_PROD_ID2) {
+		if (!dev->prod_id[1])
+			return 0;
+		if (strcmp(did->prod_id[1], dev->prod_id[1]))
+			return 0;
+	}
+
+	if (did->match_flags & PCMCIA_DEV_ID_MATCH_PROD_ID3) {
+		if (!dev->prod_id[2])
+			return 0;
+		if (strcmp(did->prod_id[2], dev->prod_id[2]))
+			return 0;
+	}
+
+	if (did->match_flags & PCMCIA_DEV_ID_MATCH_PROD_ID4) {
+		if (!dev->prod_id[3])
+			return 0;
+		if (strcmp(did->prod_id[3], dev->prod_id[3]))
+			return 0;
+	}
+
+	if (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO) {
+		/* handle pseudo multifunction devices:
+		 * there are at most two pseudo multifunction devices.
+		 * if we're matching against the first, schedule a
+		 * call which will then check whether there are two
+		 * pseudo devices, and if not, add the second one.
+		 */
+		if (dev->device_no == 0)
+			pcmcia_add_pseudo_device(dev->socket);
+
+		if (dev->device_no != did->device_no)
+			return 0;
+	}
+
+	if (did->match_flags & PCMCIA_DEV_ID_MATCH_FUNC_ID) {
+		if ((!dev->has_func_id) || (dev->func_id != did->func_id))
+			return 0;
+
+		/* if this is a pseudo-multi-function device,
+		 * we need explicit matches */
+		if (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO)
+			return 0;
+		if (dev->device_no)
+			return 0;
+
+		/* also, FUNC_ID matching needs to be activated by userspace
+		 * after it has re-checked that there is no possible module
+		 * with a prod_id/manf_id/card_id match.
+		 */
+		if (!dev->allow_func_id_match)
+			return 0;
+	}
+
+	if (did->match_flags & PCMCIA_DEV_ID_MATCH_FAKE_CIS) {
+		if (!dev->socket->fake_cis)
+			pcmcia_load_firmware(dev, did->cisfile);
+
+		if (!dev->socket->fake_cis)
+			return 0;
+	}
+
+	if (did->match_flags & PCMCIA_DEV_ID_MATCH_ANONYMOUS) {
+		int i;
+		for (i=0; i<4; i++)
+			if (dev->prod_id[i])
+				return 0;
+		if (dev->has_manf_id || dev->has_card_id || dev->has_func_id)
+			return 0;
+	}
+
+	dev->dev.driver_data = (void *) did;
+
+	return 1;
+}
+
+
 static int pcmcia_bus_match(struct device * dev, struct device_driver * drv) {
 	struct pcmcia_device * p_dev = to_pcmcia_dev(dev);
 	struct pcmcia_driver * p_drv = to_pcmcia_drv(drv);
+	struct pcmcia_device_id *did = p_drv->id_table;
 
 	/* matching by cardmgr */
 	if (p_dev->cardmgr == p_drv)
 		return 1;
 
+	while (did && did->match_flags) {
+		if (pcmcia_devmatch(p_dev, did))
+			return 1;
+		did++;
+	}
+
 	return 0;
 }
 
+#ifdef CONFIG_HOTPLUG
+
+static int pcmcia_bus_hotplug(struct device *dev, char **envp, int num_envp,
+			      char *buffer, int buffer_size)
+{
+	struct pcmcia_device *p_dev;
+	int i, length = 0;
+	u32 hash[4] = { 0, 0, 0, 0};
+
+	if (!dev)
+		return -ENODEV;
+
+	p_dev = to_pcmcia_dev(dev);
+
+	/* calculate hashes */
+	for (i=0; i<4; i++) {
+		if (!p_dev->prod_id[i])
+			continue;
+		hash[i] = crc32(0, p_dev->prod_id[i], strlen(p_dev->prod_id[i]));
+	}
+
+	i = 0;
+
+	if (add_hotplug_env_var(envp, num_envp, &i,
+				buffer, buffer_size, &length,
+				"SOCKET_NO=%u",
+				p_dev->socket->sock))
+		return -ENOMEM;
+
+	if (add_hotplug_env_var(envp, num_envp, &i,
+				buffer, buffer_size, &length,
+				"DEVICE_NO=%02X",
+				p_dev->device_no))
+		return -ENOMEM;
+
+	if (add_hotplug_env_var(envp, num_envp, &i,
+				buffer, buffer_size, &length,
+				"MODALIAS=pcmcia:m%04Xc%04Xf%02Xfn%02Xpfn%02X"
+				"pa%08Xpb%08Xpc%08Xpd%08X",
+				p_dev->has_manf_id ? p_dev->manf_id : 0,
+				p_dev->has_card_id ? p_dev->card_id : 0,
+				p_dev->has_func_id ? p_dev->func_id : 0,
+				p_dev->func,
+				p_dev->device_no,
+				hash[0],
+				hash[1],
+				hash[2],
+				hash[3]))
+		return -ENOMEM;
+
+	envp[i] = NULL;
+
+	return 0;
+}
+
+#else
+
+static int pcmcia_bus_hotplug(struct device *dev, char **envp, int num_envp,
+			      char *buffer, int buffer_size)
+{
+	return -ENODEV;
+}
+
+#endif
+
 /************************ per-device sysfs output ***************************/
 
 #define pcmcia_device_attr(field, test, format)				\
-static ssize_t field##_show (struct device *dev, char *buf)		\
+static ssize_t field##_show (struct device *dev, struct device_attribute *attr, char *buf)		\
 {									\
 	struct pcmcia_device *p_dev = to_pcmcia_dev(dev);		\
 	return p_dev->test ? sprintf (buf, format, p_dev->field) : -ENODEV; \
 }
 
 #define pcmcia_device_stringattr(name, field)					\
-static ssize_t name##_show (struct device *dev, char *buf)		\
+static ssize_t name##_show (struct device *dev, struct device_attribute *attr, char *buf)		\
 {									\
 	struct pcmcia_device *p_dev = to_pcmcia_dev(dev);		\
 	return p_dev->field ? sprintf (buf, "%s\n", p_dev->field) : -ENODEV; \
@@ -626,6 +844,43 @@ pcmcia_device_stringattr(prod_id2, prod_
 pcmcia_device_stringattr(prod_id3, prod_id[2]);
 pcmcia_device_stringattr(prod_id4, prod_id[3]);
 
+static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
+	int i;
+	u32 hash[4] = { 0, 0, 0, 0};
+
+	/* calculate hashes */
+	for (i=0; i<4; i++) {
+		if (!p_dev->prod_id[i])
+			continue;
+		hash[i] = crc32(0,p_dev->prod_id[i],strlen(p_dev->prod_id[i]));
+	}
+	return sprintf(buf, "pcmcia:m%04Xc%04Xf%02Xfn%02Xpfn%02X"
+				"pa%08Xpb%08Xpc%08Xpd%08X\n",
+				p_dev->has_manf_id ? p_dev->manf_id : 0,
+				p_dev->has_card_id ? p_dev->card_id : 0,
+				p_dev->has_func_id ? p_dev->func_id : 0,
+				p_dev->func, p_dev->device_no,
+				hash[0], hash[1], hash[2], hash[3]);
+}
+
+static ssize_t pcmcia_store_allow_func_id_match(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
+        if (!count)
+                return -EINVAL;
+
+	down(&p_dev->socket->skt_sem);
+	p_dev->allow_func_id_match = 1;
+	up(&p_dev->socket->skt_sem);
+
+	bus_rescan_devices(&pcmcia_bus_type);
+
+	return count;
+}
+
 static struct device_attribute pcmcia_dev_attrs[] = {
 	__ATTR(function, 0444, func_show, NULL),
 	__ATTR_RO(func_id),
@@ -635,46 +890,14 @@ static struct device_attribute pcmcia_de
 	__ATTR_RO(prod_id2),
 	__ATTR_RO(prod_id3),
 	__ATTR_RO(prod_id4),
+	__ATTR_RO(modalias),
+	__ATTR(allow_func_id_match, 0200, NULL, pcmcia_store_allow_func_id_match),
 	__ATTR_NULL,
 };
 
 
 /*======================================================================
 
-    These manage a ring buffer of events pending for one user process
-    
-======================================================================*/
-
-static int queue_empty(user_info_t *user)
-{
-    return (user->event_head == user->event_tail);
-}
-
-static event_t get_queued_event(user_info_t *user)
-{
-    user->event_tail = (user->event_tail+1) % MAX_EVENTS;
-    return user->event[user->event_tail];
-}
-
-static void queue_event(user_info_t *user, event_t event)
-{
-    user->event_head = (user->event_head+1) % MAX_EVENTS;
-    if (user->event_head == user->event_tail)
-	user->event_tail = (user->event_tail+1) % MAX_EVENTS;
-    user->event[user->event_head] = event;
-}
-
-static void handle_event(struct pcmcia_bus_socket *s, event_t event)
-{
-    user_info_t *user;
-    for (user = s->user; user; user = user->next)
-	queue_event(user, event);
-    wake_up_interruptible(&s->queue);
-}
-
-
-/*======================================================================
-
     The card status event handler.
     
 ======================================================================*/
@@ -688,6 +911,7 @@ struct send_event_data {
 static int send_event_callback(struct device *dev, void * _data)
 {
 	struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
+	struct pcmcia_driver *p_drv;
 	struct send_event_data *data = _data;
 
 	/* we get called for all sockets, but may only pass the event
@@ -695,32 +919,29 @@ static int send_event_callback(struct de
 	if (p_dev->socket != data->skt)
 		return 0;
 
-	if (p_dev->client.state & (CLIENT_UNBOUND|CLIENT_STALE))
+	p_drv = to_pcmcia_drv(p_dev->dev.driver);
+	if (!p_drv)
+		return 0;
+
+	if (p_dev->state & (CLIENT_UNBOUND|CLIENT_STALE))
 		return 0;
 
-	if (p_dev->client.EventMask & data->event)
-		return EVENT(&p_dev->client, data->event, data->priority);
+	if (p_drv->event)
+		return p_drv->event(data->event, data->priority,
+				    &p_dev->event_callback_args);
 
 	return 0;
 }
 
 static int send_event(struct pcmcia_socket *s, event_t event, int priority)
 {
-	int ret = 0;
 	struct send_event_data private;
-	struct pcmcia_bus_socket *skt = pcmcia_get_bus_socket(s->pcmcia);
-
-	if (!skt)
-		return 0;
 
 	private.skt = s;
 	private.event = event;
 	private.priority = priority;
 
-	ret = bus_for_each_dev(&pcmcia_bus_type, NULL, &private, send_event_callback);
-
-	pcmcia_put_bus_socket(skt);
-	return ret;
+	return bus_for_each_dev(&pcmcia_bus_type, NULL, &private, send_event_callback);
 } /* send_event */
 
 
@@ -731,25 +952,25 @@ static int send_event(struct pcmcia_sock
 
 static int ds_event(struct pcmcia_socket *skt, event_t event, int priority)
 {
-	struct pcmcia_bus_socket *s = skt->pcmcia;
+	struct pcmcia_socket *s = pcmcia_get_socket(skt);
 	int ret = 0;
 
 	ds_dbg(1, "ds_event(0x%06x, %d, 0x%p)\n",
-	       event, priority, s);
+	       event, priority, skt);
     
 	switch (event) {
 
 	case CS_EVENT_CARD_REMOVAL:
-		s->state &= ~DS_SOCKET_PRESENT;
+		s->pcmcia_state.present = 0;
 	    	send_event(skt, event, priority);
-		unbind_request(s);
-		handle_event(s, event);
+		unbind_request(skt);
+		handle_event(skt, event);
 		break;
 	
 	case CS_EVENT_CARD_INSERTION:
-		s->state |= DS_SOCKET_PRESENT;
+		s->pcmcia_state.present = 1;
 		pcmcia_card_add(skt);
-		handle_event(s, event);
+		handle_event(skt, event);
 		break;
 
 	case CS_EVENT_EJECTION_REQUEST:
@@ -757,138 +978,23 @@ static int ds_event(struct pcmcia_socket
 		break;
 
 	default:
-		handle_event(s, event);
+		handle_event(skt, event);
 		send_event(skt, event, priority);
 		break;
     }
 
+    pcmcia_put_socket(s);
+
     return 0;
 } /* ds_event */
 
 
-/*======================================================================
-
-    bind_request() and bind_device() are merged by now. Register_client()
-    is called right at the end of bind_request(), during the driver's
-    ->attach() call. Individual descriptions:
-
-    bind_request() connects a socket to a particular client driver.
-    It looks up the specified device ID in the list of registered
-    drivers, binds it to the socket, and tries to create an instance
-    of the device.  unbind_request() deletes a driver instance.
-    
-    Bind_device() associates a device driver with a particular socket.
-    It is normally called by Driver Services after it has identified
-    a newly inserted card.  An instance of that driver will then be
-    eligible to register as a client of this socket.
-
-    Register_client() uses the dev_info_t handle to match the
-    caller with a socket.  The driver must have already been bound
-    to a socket with bind_device() -- in fact, bind_device()
-    allocates the client structure that will be used.
 
-======================================================================*/
-
-static int bind_request(struct pcmcia_bus_socket *s, bind_info_t *bind_info)
+int pcmcia_register_client(struct pcmcia_device **handle, client_reg_t *req)
 {
-	struct pcmcia_driver *p_drv;
-	struct pcmcia_device *p_dev;
-	int ret = 0;
-	unsigned long flags;
-
-	s = pcmcia_get_bus_socket(s);
-	if (!s)
-		return -EINVAL;
-
-	ds_dbg(2, "bind_request(%d, '%s')\n", s->parent->sock,
-	       (char *)bind_info->dev_info);
-
-	p_drv = get_pcmcia_driver(&bind_info->dev_info);
-	if (!p_drv) {
-		ret = -EINVAL;
-		goto err_put;
-	}
-
-	if (!try_module_get(p_drv->owner)) {
-		ret = -EINVAL;
-		goto err_put_driver;
-	}
-
-	spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
-        list_for_each_entry(p_dev, &s->devices_list, socket_device_list) {
-		if (p_dev->func == bind_info->function) {
-			if ((p_dev->dev.driver == &p_drv->drv)) {
-				if (p_dev->cardmgr) {
-					/* if there's already a device
-					 * registered, and it was registered
-					 * by userspace before, we need to
-					 * return the "instance". */
-					spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
-					bind_info->instance = p_dev->instance;
-					ret = -EBUSY;
-					goto err_put_module;
-				} else {
-					/* the correct driver managed to bind
-					 * itself magically to the correct
-					 * device. */
-					spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
-					p_dev->cardmgr = p_drv;
-					ret = 0;
-					goto err_put_module;
-				}
-			} else if (!p_dev->dev.driver) {
-				/* there's already a device available where
-				 * no device has been bound to yet. So we don't
-				 * need to register a device! */
-				spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
-				goto rescan;
-			}
-		}
-	}
-	spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
-
-	p_dev = pcmcia_device_add(s, bind_info->function);
-	if (!p_dev) {
-		ret = -EIO;
-		goto err_put_module;
-	}
-
-rescan:
-	p_dev->cardmgr = p_drv;
-
-	pcmcia_device_query(p_dev);
-
-	/*
-	 * Prevent this racing with a card insertion.
-	 */
-	down(&s->parent->skt_sem);
-	bus_rescan_devices(&pcmcia_bus_type);
-	up(&s->parent->skt_sem);
-
-	/* check whether the driver indeed matched. I don't care if this
-	 * is racy or not, because it can only happen on cardmgr access
-	 * paths...
-	 */
-	if (!(p_dev->dev.driver == &p_drv->drv))
-		p_dev->cardmgr = NULL;
-
- err_put_module:
-	module_put(p_drv->owner);
- err_put_driver:
-	put_driver(&p_drv->drv);
- err_put:
-	pcmcia_put_bus_socket(s);
-
-	return (ret);
-} /* bind_request */
-
-
-int pcmcia_register_client(client_handle_t *handle, client_reg_t *req)
-{
-	client_t *client = NULL;
-	struct pcmcia_socket *s;
-	struct pcmcia_bus_socket *skt = NULL;
+	struct pcmcia_socket *s = NULL;
 	struct pcmcia_device *p_dev = NULL;
+	struct pcmcia_driver *p_drv = NULL;
 
 	/* Look for unbound client with matching dev_info */
 	down_read(&pcmcia_socket_list_rwsem);
@@ -898,56 +1004,45 @@ int pcmcia_register_client(client_handle
 		if (s->state & SOCKET_CARDBUS)
 			continue;
 
-		skt = s->pcmcia;
-		if (!skt)
-			continue;
-		skt = pcmcia_get_bus_socket(skt);
-		if (!skt)
+		s = pcmcia_get_socket(s);
+		if (!s)
 			continue;
 		spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
-		list_for_each_entry(p_dev, &skt->devices_list, socket_device_list) {
-			struct pcmcia_driver *p_drv;
+		list_for_each_entry(p_dev, &s->devices_list, socket_device_list) {
 			p_dev = pcmcia_get_dev(p_dev);
 			if (!p_dev)
 				continue;
-			if (!(p_dev->client.state & CLIENT_UNBOUND) ||
+			if (!(p_dev->state & CLIENT_UNBOUND) ||
 			    (!p_dev->dev.driver)) {
 				pcmcia_put_dev(p_dev);
 				continue;
 			}
 			p_drv = to_pcmcia_drv(p_dev->dev.driver);
 			if (!strncmp(p_drv->drv.name, (char *)req->dev_info, DEV_NAME_LEN)) {
-				client = &p_dev->client;
 				spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
 				goto found;
 			}
 			pcmcia_put_dev(p_dev);
 		}
 		spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
-		pcmcia_put_bus_socket(skt);
+		pcmcia_put_socket(s);
 	}
  found:
 	up_read(&pcmcia_socket_list_rwsem);
-	if (!p_dev || !client)
+	if (!p_dev)
 		return -ENODEV;
 
-	pcmcia_put_bus_socket(skt); /* safe, as we already hold a reference from bind_device */
+	pcmcia_put_socket(s); /* safe, as we already hold a reference from bind_device */
 
-	*handle = client;
-	client->state &= ~CLIENT_UNBOUND;
-	client->Socket = s;
-	client->EventMask = req->EventMask;
-	client->event_handler = req->event_handler;
-	client->event_callback_args = req->event_callback_args;
-	client->event_callback_args.client_handle = client;
+	*handle = p_dev;
+	p_dev->state &= ~CLIENT_UNBOUND;
+	p_dev->event_callback_args = req->event_callback_args;
+	p_dev->event_callback_args.client_handle = p_dev;
 
-	if (s->state & SOCKET_CARDBUS)
-		client->state |= CLIENT_CARDBUS;
 
-	if ((!(s->state & SOCKET_CARDBUS)) && (s->functions == 0) &&
-	    (client->Function != BIND_FN_ALL)) {
+	if (!s->functions) {
 		cistpl_longlink_mfc_t mfc;
-		if (pccard_read_tuple(s, client->Function, CISTPL_LONGLINK_MFC, &mfc)
+		if (pccard_read_tuple(s, p_dev->func, CISTPL_LONGLINK_MFC, &mfc)
 		    == CS_SUCCESS)
 			s->functions = mfc.nfn;
 		else
@@ -960,13 +1055,13 @@ int pcmcia_register_client(client_handle
 	}
 
 	ds_dbg(1, "register_client(): client 0x%p, dev %s\n",
-	       client, p_dev->dev.bus_id);
-	if (client->EventMask & CS_EVENT_REGISTRATION_COMPLETE)
-		EVENT(client, CS_EVENT_REGISTRATION_COMPLETE, CS_EVENT_PRI_LOW);
+	       p_dev, p_dev->dev.bus_id);
 
 	if ((s->state & (SOCKET_PRESENT|SOCKET_CARDBUS)) == SOCKET_PRESENT) {
-		if (client->EventMask & CS_EVENT_CARD_INSERTION)
-			EVENT(client, CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW);
+		if (p_drv->event)
+			p_drv->event(CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW,
+				     &p_dev->event_callback_args);
+
 	}
 
 	return CS_SUCCESS;
@@ -978,106 +1073,15 @@ int pcmcia_register_client(client_handle
 EXPORT_SYMBOL(pcmcia_register_client);
 
 
-/*====================================================================*/
-
-extern struct pci_bus *pcmcia_lookup_bus(struct pcmcia_socket *s);
-
-static int get_device_info(struct pcmcia_bus_socket *s, bind_info_t *bind_info, int first)
-{
-	dev_node_t *node;
-	struct pcmcia_device *p_dev;
-	unsigned long flags;
-	int ret = 0;
-
-#ifdef CONFIG_CARDBUS
-	/*
-	 * Some unbelievably ugly code to associate the PCI cardbus
-	 * device and its driver with the PCMCIA "bind" information.
-	 */
-	{
-		struct pci_bus *bus;
-
-		bus = pcmcia_lookup_bus(s->parent);
-		if (bus) {
-			struct list_head *list;
-			struct pci_dev *dev = NULL;
-
-			list = bus->devices.next;
-			while (list != &bus->devices) {
-				struct pci_dev *pdev = pci_dev_b(list);
-				list = list->next;
-
-				if (first) {
-					dev = pdev;
-					break;
-				}
-
-				/* Try to handle "next" here some way? */
-			}
-			if (dev && dev->driver) {
-				strlcpy(bind_info->name, dev->driver->name, DEV_NAME_LEN);
-				bind_info->major = 0;
-				bind_info->minor = 0;
-				bind_info->next = NULL;
-				return 0;
-			}
-		}
-	}
-#endif
-
-	spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
-	list_for_each_entry(p_dev, &s->devices_list, socket_device_list) {
-		if (p_dev->func == bind_info->function) {
-			p_dev = pcmcia_get_dev(p_dev);
-			if (!p_dev)
-				continue;
-			goto found;
-		}
-	}
-	spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
-	return -ENODEV;
-
- found:
-	spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
-
-	if ((!p_dev->instance) ||
-	    (p_dev->instance->state & DEV_CONFIG_PENDING)) {
-		ret = -EAGAIN;
-		goto err_put;
-	}
-
-	if (first)
-		node = p_dev->instance->dev;
-	else
-		for (node = p_dev->instance->dev; node; node = node->next)
-			if (node == bind_info->next)
-				break;
-	if (!node) {
-		ret = -ENODEV;
-		goto err_put;
-	}
-
-	strlcpy(bind_info->name, node->dev_name, DEV_NAME_LEN);
-	bind_info->major = node->major;
-	bind_info->minor = node->minor;
-	bind_info->next = node->next;
-
- err_put:
-	pcmcia_put_dev(p_dev);
-	return (ret);
-} /* get_device_info */
-
-/*====================================================================*/
-
 /* unbind _all_ devices attached to a given pcmcia_bus_socket. The
  * drivers have been called with EVENT_CARD_REMOVAL before.
  */
-static int unbind_request(struct pcmcia_bus_socket *s)
+static int unbind_request(struct pcmcia_socket *s)
 {
 	struct pcmcia_device	*p_dev;
 	unsigned long		flags;
 
-	ds_dbg(2, "unbind_request(%d)\n", s->parent->sock);
+	ds_dbg(2, "unbind_request(%d)\n", s->sock);
 
 	s->device_count = 0;
 
@@ -1090,7 +1094,7 @@ static int unbind_request(struct pcmcia_
 		}
 		p_dev = list_entry((&s->devices_list)->next, struct pcmcia_device, socket_device_list);
 		list_del(&p_dev->socket_device_list);
-		p_dev->client.state |= CLIENT_STALE;
+		p_dev->state |= CLIENT_STALE;
 		spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
 
 		device_unregister(&p_dev->dev);
@@ -1099,31 +1103,25 @@ static int unbind_request(struct pcmcia_
 	return 0;
 } /* unbind_request */
 
-int pcmcia_deregister_client(client_handle_t handle)
+int pcmcia_deregister_client(struct pcmcia_device *p_dev)
 {
 	struct pcmcia_socket *s;
 	int i;
-	struct pcmcia_device *p_dev = handle_to_pdev(handle);
-
-	if (CHECK_HANDLE(handle))
-		return CS_BAD_HANDLE;
 
-	s = SOCKET(handle);
-	ds_dbg(1, "deregister_client(%p)\n", handle);
+	s = p_dev->socket;
+	ds_dbg(1, "deregister_client(%p)\n", p_dev);
 
-	if (handle->state & (CLIENT_IRQ_REQ|CLIENT_IO_REQ|CLIENT_CONFIG_LOCKED))
+	if (p_dev->state & (CLIENT_IRQ_REQ|CLIENT_IO_REQ|CLIENT_CONFIG_LOCKED))
 		goto warn_out;
 	for (i = 0; i < MAX_WIN; i++)
-		if (handle->state & CLIENT_WIN_REQ(i))
+		if (p_dev->state & CLIENT_WIN_REQ(i))
 			goto warn_out;
 
-	if (handle->state & CLIENT_STALE) {
-		handle->client_magic = 0;
-		handle->state &= ~CLIENT_STALE;
+	if (p_dev->state & CLIENT_STALE) {
+		p_dev->state &= ~CLIENT_STALE;
 		pcmcia_put_dev(p_dev);
 	} else {
-		handle->state = CLIENT_UNBOUND;
-		handle->event_handler = NULL;
+		p_dev->state = CLIENT_UNBOUND;
 	}
 
 	return CS_SUCCESS;
@@ -1133,433 +1131,58 @@ int pcmcia_deregister_client(client_hand
 } /* deregister_client */
 EXPORT_SYMBOL(pcmcia_deregister_client);
 
-
-/*======================================================================
-
-    The user-mode PC Card device interface
-
-======================================================================*/
-
-static int ds_open(struct inode *inode, struct file *file)
-{
-    socket_t i = iminor(inode);
-    struct pcmcia_bus_socket *s;
-    user_info_t *user;
-
-    ds_dbg(0, "ds_open(socket %d)\n", i);
-
-    s = get_socket_info_by_nr(i);
-    if (!s)
-	    return -ENODEV;
-    s = pcmcia_get_bus_socket(s);
-    if (!s)
-	    return -ENODEV;
-
-    if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
-	    if (s->state & DS_SOCKET_BUSY) {
-		    pcmcia_put_bus_socket(s);
-		    return -EBUSY;
-	    }
-	else
-	    s->state |= DS_SOCKET_BUSY;
-    }
-    
-    user = kmalloc(sizeof(user_info_t), GFP_KERNEL);
-    if (!user) {
-	    pcmcia_put_bus_socket(s);
-	    return -ENOMEM;
-    }
-    user->event_tail = user->event_head = 0;
-    user->next = s->user;
-    user->user_magic = USER_MAGIC;
-    user->socket = s;
-    s->user = user;
-    file->private_data = user;
-    
-    if (s->state & DS_SOCKET_PRESENT)
-	queue_event(user, CS_EVENT_CARD_INSERTION);
-    return 0;
-} /* ds_open */
-
-/*====================================================================*/
-
-static int ds_release(struct inode *inode, struct file *file)
-{
-    struct pcmcia_bus_socket *s;
-    user_info_t *user, **link;
-
-    ds_dbg(0, "ds_release(socket %d)\n", iminor(inode));
-
-    user = file->private_data;
-    if (CHECK_USER(user))
-	goto out;
-
-    s = user->socket;
-
-    /* Unlink user data structure */
-    if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
-	s->state &= ~DS_SOCKET_BUSY;
-    }
-    file->private_data = NULL;
-    for (link = &s->user; *link; link = &(*link)->next)
-	if (*link == user) break;
-    if (link == NULL)
-	goto out;
-    *link = user->next;
-    user->user_magic = 0;
-    kfree(user);
-    pcmcia_put_bus_socket(s);
-out:
-    return 0;
-} /* ds_release */
-
-/*====================================================================*/
-
-static ssize_t ds_read(struct file *file, char __user *buf,
-		       size_t count, loff_t *ppos)
-{
-    struct pcmcia_bus_socket *s;
-    user_info_t *user;
-    int ret;
-
-    ds_dbg(2, "ds_read(socket %d)\n", iminor(file->f_dentry->d_inode));
-    
-    if (count < 4)
-	return -EINVAL;
-
-    user = file->private_data;
-    if (CHECK_USER(user))
-	return -EIO;
-    
-    s = user->socket;
-    if (s->state & DS_SOCKET_DEAD)
-        return -EIO;
-
-    ret = wait_event_interruptible(s->queue, !queue_empty(user));
-    if (ret == 0)
-	ret = put_user(get_queued_event(user), (int __user *)buf) ? -EFAULT : 4;
-
-    return ret;
-} /* ds_read */
-
-/*====================================================================*/
-
-static ssize_t ds_write(struct file *file, const char __user *buf,
-			size_t count, loff_t *ppos)
-{
-    ds_dbg(2, "ds_write(socket %d)\n", iminor(file->f_dentry->d_inode));
-
-    if (count != 4)
-	return -EINVAL;
-    if ((file->f_flags & O_ACCMODE) == O_RDONLY)
-	return -EBADF;
-
-    return -EIO;
-} /* ds_write */
-
-/*====================================================================*/
-
-/* No kernel lock - fine */
-static u_int ds_poll(struct file *file, poll_table *wait)
-{
-    struct pcmcia_bus_socket *s;
-    user_info_t *user;
-
-    ds_dbg(2, "ds_poll(socket %d)\n", iminor(file->f_dentry->d_inode));
-    
-    user = file->private_data;
-    if (CHECK_USER(user))
-	return POLLERR;
-    s = user->socket;
-    /*
-     * We don't check for a dead socket here since that
-     * will send cardmgr into an endless spin.
-     */
-    poll_wait(file, &s->queue, wait);
-    if (!queue_empty(user))
-	return POLLIN | POLLRDNORM;
-    return 0;
-} /* ds_poll */
-
-/*====================================================================*/
-
-extern int pcmcia_adjust_resource_info(adjust_t *adj);
-
-static int ds_ioctl(struct inode * inode, struct file * file,
-		    u_int cmd, u_long arg)
-{
-    struct pcmcia_bus_socket *s;
-    void __user *uarg = (char __user *)arg;
-    u_int size;
-    int ret, err;
-    ds_ioctl_arg_t *buf;
-    user_info_t *user;
-
-    ds_dbg(2, "ds_ioctl(socket %d, %#x, %#lx)\n", iminor(inode), cmd, arg);
-    
-    user = file->private_data;
-    if (CHECK_USER(user))
-	return -EIO;
-
-    s = user->socket;
-    if (s->state & DS_SOCKET_DEAD)
-        return -EIO;
-    
-    size = (cmd & IOCSIZE_MASK) >> IOCSIZE_SHIFT;
-    if (size > sizeof(ds_ioctl_arg_t)) return -EINVAL;
-
-    /* Permission check */
-    if (!(cmd & IOC_OUT) && !capable(CAP_SYS_ADMIN))
-	return -EPERM;
-	
-    if (cmd & IOC_IN) {
-	if (!access_ok(VERIFY_READ, uarg, size)) {
-	    ds_dbg(3, "ds_ioctl(): verify_read = %d\n", -EFAULT);
-	    return -EFAULT;
-	}
-    }
-    if (cmd & IOC_OUT) {
-	if (!access_ok(VERIFY_WRITE, uarg, size)) {
-	    ds_dbg(3, "ds_ioctl(): verify_write = %d\n", -EFAULT);
-	    return -EFAULT;
-	}
-    }
-    buf = kmalloc(sizeof(ds_ioctl_arg_t), GFP_KERNEL);
-    if (!buf)
-	return -ENOMEM;
-    
-    err = ret = 0;
-    
-    if (cmd & IOC_IN) __copy_from_user((char *)buf, uarg, size);
-    
-    switch (cmd) {
-    case DS_ADJUST_RESOURCE_INFO:
-	ret = pcmcia_adjust_resource_info(&buf->adjust);
-	break;
-    case DS_GET_CARD_SERVICES_INFO:
-	ret = pcmcia_get_card_services_info(&buf->servinfo);
-	break;
-    case DS_GET_CONFIGURATION_INFO:
-	if (buf->config.Function &&
-	   (buf->config.Function >= s->parent->functions))
-	    ret = CS_BAD_ARGS;
-	else
-	    ret = pccard_get_configuration_info(s->parent,
-			buf->config.Function, &buf->config);
-	break;
-    case DS_GET_FIRST_TUPLE:
-	down(&s->parent->skt_sem);
-	pcmcia_validate_mem(s->parent);
-	up(&s->parent->skt_sem);
-	ret = pccard_get_first_tuple(s->parent, BIND_FN_ALL, &buf->tuple);
-	break;
-    case DS_GET_NEXT_TUPLE:
-	ret = pccard_get_next_tuple(s->parent, BIND_FN_ALL, &buf->tuple);
-	break;
-    case DS_GET_TUPLE_DATA:
-	buf->tuple.TupleData = buf->tuple_parse.data;
-	buf->tuple.TupleDataMax = sizeof(buf->tuple_parse.data);
-	ret = pccard_get_tuple_data(s->parent, &buf->tuple);
-	break;
-    case DS_PARSE_TUPLE:
-	buf->tuple.TupleData = buf->tuple_parse.data;
-	ret = pccard_parse_tuple(&buf->tuple, &buf->tuple_parse.parse);
-	break;
-    case DS_RESET_CARD:
-	ret = pccard_reset_card(s->parent);
-	break;
-    case DS_GET_STATUS:
-	if (buf->status.Function &&
-	   (buf->status.Function >= s->parent->functions))
-	    ret = CS_BAD_ARGS;
-	else
-	ret = pccard_get_status(s->parent, buf->status.Function, &buf->status);
-	break;
-    case DS_VALIDATE_CIS:
-	down(&s->parent->skt_sem);
-	pcmcia_validate_mem(s->parent);
-	up(&s->parent->skt_sem);
-	ret = pccard_validate_cis(s->parent, BIND_FN_ALL, &buf->cisinfo);
-	break;
-    case DS_SUSPEND_CARD:
-	ret = pcmcia_suspend_card(s->parent);
-	break;
-    case DS_RESUME_CARD:
-	ret = pcmcia_resume_card(s->parent);
-	break;
-    case DS_EJECT_CARD:
-	err = pcmcia_eject_card(s->parent);
-	break;
-    case DS_INSERT_CARD:
-	err = pcmcia_insert_card(s->parent);
-	break;
-    case DS_ACCESS_CONFIGURATION_REGISTER:
-	if ((buf->conf_reg.Action == CS_WRITE) && !capable(CAP_SYS_ADMIN)) {
-	    err = -EPERM;
-	    goto free_out;
-	}
-	if (buf->conf_reg.Function &&
-	   (buf->conf_reg.Function >= s->parent->functions))
-	    ret = CS_BAD_ARGS;
-	else
-	    ret = pccard_access_configuration_register(s->parent,
-			buf->conf_reg.Function, &buf->conf_reg);
-	break;
-    case DS_GET_FIRST_REGION:
-    case DS_GET_NEXT_REGION:
-    case DS_BIND_MTD:
-	if (!capable(CAP_SYS_ADMIN)) {
-		err = -EPERM;
-		goto free_out;
-	} else {
-		static int printed = 0;
-		if (!printed) {
-			printk(KERN_WARNING "2.6. kernels use pcmciamtd instead of memory_cs.c and do not require special\n");
-			printk(KERN_WARNING "MTD handling any more.\n");
-			printed++;
-		}
-	}
-	err = -EINVAL;
-	goto free_out;
-	break;
-    case DS_GET_FIRST_WINDOW:
-	ret = pcmcia_get_window(s->parent, &buf->win_info.handle, 0,
-			&buf->win_info.window);
-	break;
-    case DS_GET_NEXT_WINDOW:
-	ret = pcmcia_get_window(s->parent, &buf->win_info.handle,
-			buf->win_info.handle->index + 1, &buf->win_info.window);
-	break;
-    case DS_GET_MEM_PAGE:
-	ret = pcmcia_get_mem_page(buf->win_info.handle,
-			   &buf->win_info.map);
-	break;
-    case DS_REPLACE_CIS:
-	ret = pcmcia_replace_cis(s->parent, &buf->cisdump);
-	break;
-    case DS_BIND_REQUEST:
-	if (!capable(CAP_SYS_ADMIN)) {
-		err = -EPERM;
-		goto free_out;
-	}
-	err = bind_request(s, &buf->bind_info);
-	break;
-    case DS_GET_DEVICE_INFO:
-	err = get_device_info(s, &buf->bind_info, 1);
-	break;
-    case DS_GET_NEXT_DEVICE:
-	err = get_device_info(s, &buf->bind_info, 0);
-	break;
-    case DS_UNBIND_REQUEST:
-	err = 0;
-	break;
-    default:
-	err = -EINVAL;
-    }
-    
-    if ((err == 0) && (ret != CS_SUCCESS)) {
-	ds_dbg(2, "ds_ioctl: ret = %d\n", ret);
-	switch (ret) {
-	case CS_BAD_SOCKET: case CS_NO_CARD:
-	    err = -ENODEV; break;
-	case CS_BAD_ARGS: case CS_BAD_ATTRIBUTE: case CS_BAD_IRQ:
-	case CS_BAD_TUPLE:
-	    err = -EINVAL; break;
-	case CS_IN_USE:
-	    err = -EBUSY; break;
-	case CS_OUT_OF_RESOURCE:
-	    err = -ENOSPC; break;
-	case CS_NO_MORE_ITEMS:
-	    err = -ENODATA; break;
-	case CS_UNSUPPORTED_FUNCTION:
-	    err = -ENOSYS; break;
-	default:
-	    err = -EIO; break;
-	}
-    }
-
-    if (cmd & IOC_OUT) {
-        if (__copy_to_user(uarg, (char *)buf, size))
-            err = -EFAULT;
-    }
-
-free_out:
-    kfree(buf);
-    return err;
-} /* ds_ioctl */
-
-/*====================================================================*/
-
-static struct file_operations ds_fops = {
-	.owner		= THIS_MODULE,
-	.open		= ds_open,
-	.release	= ds_release,
-	.ioctl		= ds_ioctl,
-	.read		= ds_read,
-	.write		= ds_write,
-	.poll		= ds_poll,
+static struct pcmcia_callback pcmcia_bus_callback = {
+	.owner = THIS_MODULE,
+	.event = ds_event,
+	.requery = pcmcia_bus_rescan,
 };
 
 static int __devinit pcmcia_bus_add_socket(struct class_device *class_dev)
 {
 	struct pcmcia_socket *socket = class_get_devdata(class_dev);
-	struct pcmcia_bus_socket *s;
 	int ret;
 
-	s = kmalloc(sizeof(struct pcmcia_bus_socket), GFP_KERNEL);
-	if(!s)
-		return -ENOMEM;
-	memset(s, 0, sizeof(struct pcmcia_bus_socket));
-
-	/* get reference to parent socket */
-	s->parent = pcmcia_get_socket(socket);
-	if (!s->parent) {
+	socket = pcmcia_get_socket(socket);
+	if (!socket) {
 		printk(KERN_ERR "PCMCIA obtaining reference to socket %p failed\n", socket);
-		kfree (s);
 		return -ENODEV;
 	}
 
-	kref_init(&s->refcount);
-    
 	/*
 	 * Ugly. But we want to wait for the socket threads to have started up.
 	 * We really should let the drivers themselves drive some of this..
 	 */
 	msleep(250);
 
-	init_waitqueue_head(&s->queue);
-	INIT_LIST_HEAD(&s->devices_list);
-
-	/* Set up hotline to Card Services */
-	s->callback.owner = THIS_MODULE;
-	s->callback.event = &ds_event;
-	s->callback.resources_done = &pcmcia_card_add;
-	socket->pcmcia = s;
+#ifdef CONFIG_PCMCIA_IOCTL
+	init_waitqueue_head(&socket->queue);
+#endif
+	INIT_LIST_HEAD(&socket->devices_list);
+	INIT_WORK(&socket->device_add, pcmcia_delayed_add_pseudo_device, socket);
+	memset(&socket->pcmcia_state, 0, sizeof(u8));
+	socket->device_count = 0;
 
-	ret = pccard_register_pcmcia(socket, &s->callback);
+	ret = pccard_register_pcmcia(socket, &pcmcia_bus_callback);
 	if (ret) {
 		printk(KERN_ERR "PCMCIA registration PCCard core failed for socket %p\n", socket);
-		pcmcia_put_bus_socket(s);
-		socket->pcmcia = NULL;
+		pcmcia_put_socket(socket);
 		return (ret);
 	}
 
 	return 0;
 }
 
-
 static void pcmcia_bus_remove_socket(struct class_device *class_dev)
 {
 	struct pcmcia_socket *socket = class_get_devdata(class_dev);
 
-	if (!socket || !socket->pcmcia)
+	if (!socket)
 		return;
 
+	socket->pcmcia_state.dead = 1;
 	pccard_register_pcmcia(socket, NULL);
 
-	socket->pcmcia->state |= DS_SOCKET_DEAD;
-	pcmcia_put_bus_socket(socket->pcmcia);
-	socket->pcmcia = NULL;
+	pcmcia_put_socket(socket);
 
 	return;
 }
@@ -1575,34 +1198,20 @@ static struct class_interface pcmcia_bus
 
 struct bus_type pcmcia_bus_type = {
 	.name = "pcmcia",
+	.hotplug = pcmcia_bus_hotplug,
 	.match = pcmcia_bus_match,
 	.dev_attrs = pcmcia_dev_attrs,
 };
-EXPORT_SYMBOL(pcmcia_bus_type);
 
 
 static int __init init_pcmcia_bus(void)
 {
-	int i;
-
 	spin_lock_init(&pcmcia_dev_list_lock);
 
 	bus_register(&pcmcia_bus_type);
 	class_interface_register(&pcmcia_bus_interface);
 
-	/* Set up character device for user mode clients */
-	i = register_chrdev(0, "pcmcia", &ds_fops);
-	if (i < 0)
-		printk(KERN_NOTICE "unable to find a free device # for "
-		       "Driver Services (error=%d)\n", i);
-	else
-		major_dev = i;
-
-#ifdef CONFIG_PROC_FS
-	proc_pccard = proc_mkdir("pccard", proc_bus);
-	if (proc_pccard)
-		create_proc_read_entry("drivers",0,proc_pccard,proc_read_drivers,NULL);
-#endif
+	pcmcia_setup_ioctl();
 
 	return 0;
 }
@@ -1612,48 +1221,13 @@ fs_initcall(init_pcmcia_bus); /* one lev
 
 static void __exit exit_pcmcia_bus(void)
 {
-	class_interface_unregister(&pcmcia_bus_interface);
+	pcmcia_cleanup_ioctl();
 
-#ifdef CONFIG_PROC_FS
-	if (proc_pccard) {
-		remove_proc_entry("drivers", proc_pccard);
-		remove_proc_entry("pccard", proc_bus);
-	}
-#endif
-	if (major_dev != -1)
-		unregister_chrdev(major_dev, "pcmcia");
+	class_interface_unregister(&pcmcia_bus_interface);
 
 	bus_unregister(&pcmcia_bus_type);
 }
 module_exit(exit_pcmcia_bus);
 
 
-
-/* helpers for backwards-compatible functions */
-
-static struct pcmcia_bus_socket * get_socket_info_by_nr(unsigned int nr)
-{
-	struct pcmcia_socket * s = pcmcia_get_socket_by_nr(nr);
-	if (s && s->pcmcia)
-		return s->pcmcia;
-	else
-		return NULL;
-}
-
-/* backwards-compatible accessing of driver --- by name! */
-
-static struct pcmcia_driver * get_pcmcia_driver (dev_info_t *dev_info)
-{
-	struct device_driver *drv;
-	struct pcmcia_driver *p_drv;
-
-	drv = driver_find((char *) dev_info, &pcmcia_bus_type);
-	if (!drv)
-		return NULL;
-
-	p_drv = container_of(drv, struct pcmcia_driver, drv);
-
-	return (p_drv);
-}
-
 MODULE_ALIAS("ds");
diff --git a/drivers/pcmcia/ds_internal.h b/drivers/pcmcia/ds_internal.h
new file mode 100644
--- /dev/null
+++ b/drivers/pcmcia/ds_internal.h
@@ -0,0 +1,21 @@
+/* ds_internal.h - internal header for 16-bit PCMCIA devices management */
+
+extern spinlock_t pcmcia_dev_list_lock;
+extern struct bus_type pcmcia_bus_type;
+
+extern struct pcmcia_device * pcmcia_get_dev(struct pcmcia_device *p_dev);
+extern void pcmcia_put_dev(struct pcmcia_device *p_dev);
+
+struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int function);
+
+#ifdef CONFIG_PCMCIA_IOCTL
+extern void __init pcmcia_setup_ioctl(void);
+extern void __exit pcmcia_cleanup_ioctl(void);
+extern void handle_event(struct pcmcia_socket *s, event_t event);
+extern int handle_request(struct pcmcia_socket *s, event_t event);
+#else
+static inline void __init pcmcia_setup_ioctl(void) { return; }
+static inline void __init pcmcia_cleanup_ioctl(void) { return; }
+static inline void handle_event(struct pcmcia_socket *s, event_t event) { return; }
+static inline int handle_request(struct pcmcia_socket *s, event_t event) { return CS_SUCCESS; }
+#endif
diff --git a/drivers/pcmcia/hd64465_ss.c b/drivers/pcmcia/hd64465_ss.c
--- a/drivers/pcmcia/hd64465_ss.c
+++ b/drivers/pcmcia/hd64465_ss.c
@@ -43,7 +43,6 @@
 #include <asm/hd64465/hd64465.h>
 #include <asm/hd64465/io.h>
 
-#include <pcmcia/version.h>
 #include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
diff --git a/drivers/pcmcia/i82365.c b/drivers/pcmcia/i82365.c
--- a/drivers/pcmcia/i82365.c
+++ b/drivers/pcmcia/i82365.c
@@ -53,7 +53,6 @@
 #include <asm/io.h>
 #include <asm/system.h>
 
-#include <pcmcia/version.h>
 #include <pcmcia/cs_types.h>
 #include <pcmcia/ss.h>
 #include <pcmcia/cs.h>
@@ -669,11 +668,13 @@ static int __init is_alive(u_short sock)
     if ((stat & I365_CS_DETECT) && (stat & I365_CS_POWERON) &&
 	(i365_get(sock, I365_INTCTL) & I365_PC_IOCARD) &&
 	(i365_get(sock, I365_ADDRWIN) & I365_ENA_IO(0)) &&
-	(check_region(start, stop-start+1) != 0) &&
-	((start & 0xfeef) != 0x02e8))
-	return 1;
-    else
-	return 0;
+	((start & 0xfeef) != 0x02e8)) {
+	if (!request_region(start, stop-start+1, "i82365"))
+	    return 1;
+	release_region(start, stop-start+1);
+    }
+
+    return 0;
 }
 
 /*====================================================================*/
@@ -696,8 +697,6 @@ static void __init add_pcic(int ns, int 
     struct i82365_socket *t = &socket[sockets-ns];
 
     base = sockets-ns;
-    if (t->ioaddr > 0) request_region(t->ioaddr, 2, "i82365");
-    
     if (base == 0) printk("\n");
     printk(KERN_INFO "  %s", pcic[type].name);
     printk(" ISA-to-PCMCIA at port %#lx ofs 0x%02x",
@@ -803,7 +802,7 @@ static void __init isa_probe(void)
     }
 #endif
 
-    if (check_region(i365_base, 2) != 0) {
+    if (!request_region(i365_base, 2, "i82365")) {
 	if (sockets == 0)
 	    printk("port conflict at %#lx\n", i365_base);
 	return;
@@ -1441,6 +1440,7 @@ static void __exit exit_i82365(void)
 	i365_set(i, I365_CSCINT, 0);
 	release_region(socket[i].ioaddr, 2);
     }
+    release_region(i365_base, 2);
 #ifdef CONFIG_PNP
     if (i82365_pnpdev)
     		pnp_disable_dev(i82365_pnpdev);
diff --git a/drivers/pcmcia/m32r_cfc.c b/drivers/pcmcia/m32r_cfc.c
--- a/drivers/pcmcia/m32r_cfc.c
+++ b/drivers/pcmcia/m32r_cfc.c
@@ -24,12 +24,11 @@
 #include <linux/workqueue.h>
 #include <linux/interrupt.h>
 #include <linux/device.h>
+#include <linux/bitops.h>
 #include <asm/irq.h>
 #include <asm/io.h>
-#include <asm/bitops.h>
 #include <asm/system.h>
 
-#include <pcmcia/version.h>
 #include <pcmcia/cs_types.h>
 #include <pcmcia/ss.h>
 #include <pcmcia/cs.h>
@@ -444,7 +443,7 @@ static int _pcc_get_status(u_short sock,
 		debug(3, "m32r_cfc: _pcc_get_status: "
 			 "power off (CPCR=0x%08x)\n", status);
 	}
-#elif defined(CONFIG_PLAT_MAPPI2)
+#elif defined(CONFIG_PLAT_MAPPI2) || defined(CONFIG_PLAT_MAPPI3)
 	if ( status ) {
 		status = pcc_get(sock, (unsigned int)PLD_CPCR);
 		if (status == 0) { /* power off */
@@ -452,18 +451,23 @@ static int _pcc_get_status(u_short sock,
 			pcc_set(sock, (unsigned int)PLD_CFBUFCR,0); /* force buffer off for ZA-36 */
 			udelay(50);
 		}
-		status = pcc_get(sock, (unsigned int)PLD_CFBUFCR);
-		if (status != 0) { /* buffer off */
-			pcc_set(sock, (unsigned int)PLD_CFBUFCR,0);
-			udelay(50);
-			pcc_set(sock, (unsigned int)PLD_CFRSTCR, 0x0101);
-			udelay(25); /* for IDE reset */
-			pcc_set(sock, (unsigned int)PLD_CFRSTCR, 0x0100);
-			mdelay(2);  /* for IDE reset */
-		} else {
-			*value |= SS_POWERON;
-			*value |= SS_READY;
-		}
+		*value |= SS_POWERON;
+
+		pcc_set(sock, (unsigned int)PLD_CFBUFCR,0);
+		udelay(50);
+		pcc_set(sock, (unsigned int)PLD_CFRSTCR, 0x0101);
+		udelay(25); /* for IDE reset */
+		pcc_set(sock, (unsigned int)PLD_CFRSTCR, 0x0100);
+		mdelay(2);  /* for IDE reset */
+
+		*value |= SS_READY;
+		*value |= SS_3VCARD;
+	} else {
+		/* disable CF power */
+	        pcc_set(sock, (unsigned int)PLD_CPCR, 0);
+		udelay(100);
+		debug(3, "m32r_cfc: _pcc_get_status: "
+			 "power off (CPCR=0x%08x)\n", status);
 	}
 #else
 #error no platform configuration
@@ -479,14 +483,13 @@ static int _pcc_get_socket(u_short sock,
 {
 //	pcc_socket_t *t = &socket[sock];
 
-#if defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_USRV) || defined(CONFIG_PLAT_OPSPUT)
 	state->flags = 0;
 	state->csc_mask = SS_DETECT;
 	state->csc_mask |= SS_READY;
 	state->io_irq = 0;
 	state->Vcc = 33;	/* 3.3V fixed */
 	state->Vpp = 33;
-#endif
+
 	debug(3, "m32r_cfc: GetSocket(%d) = flags %#3.3x, Vcc %d, Vpp %d, "
 		  "io_irq %d, csc_mask %#2.2x\n", sock, state->flags,
 		  state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
@@ -497,32 +500,17 @@ static int _pcc_get_socket(u_short sock,
 
 static int _pcc_set_socket(u_short sock, socket_state_t *state)
 {
-#if defined(CONFIG_PLAT_MAPPI2)
-	u_long reg = 0;
-#endif
 	debug(3, "m32r_cfc: SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
 		  "io_irq %d, csc_mask %#2.2x)\n", sock, state->flags,
 		  state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
 
-#if defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_USRV) || defined(CONFIG_PLAT_OPSPUT)
+#if defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_USRV) || defined(CONFIG_PLAT_OPSPUT) || defined(CONFIG_PLAT_MAPPI2) || defined(CONFIG_PLAT_MAPPI3)
 	if (state->Vcc) {
 		if ((state->Vcc != 50) && (state->Vcc != 33))
 			return -EINVAL;
 		/* accept 5V and 3.3V */
 	}
-#elif defined(CONFIG_PLAT_MAPPI2)
-	if (state->Vcc) {
-		/*
-		 * 5V only
-		 */
-		if (state->Vcc == 50) {
-			reg |= PCCSIGCR_VEN;
-		} else {
-			return -EINVAL;
-		}
-	}
 #endif
-
 	if (state->flags & SS_RESET) {
 		debug(3, ":RESET\n");
 		pcc_set(sock,(unsigned int)PLD_CFRSTCR,0x101);
@@ -788,7 +776,7 @@ static int __init init_m32r_pcc(void)
 		return ret;
 	}
 
-#if defined(CONFIG_PLAT_MAPPI2)
+#if defined(CONFIG_PLAT_MAPPI2) || defined(CONFIG_PLAT_MAPPI3)
 	pcc_set(0, (unsigned int)PLD_CFCR0, 0x0f0f);
 	pcc_set(0, (unsigned int)PLD_CFCR1, 0x0200);
 #endif
@@ -825,7 +813,7 @@ static int __init init_m32r_pcc(void)
 	for (i = 0 ; i < pcc_sockets ; i++) {
 		socket[i].socket.dev.dev = &pcc_device.dev;
 		socket[i].socket.ops = &pcc_operations;
-		socket[i].socket.resource_ops = &pccard_static_ops;
+		socket[i].socket.resource_ops = &pccard_nonstatic_ops;
 		socket[i].socket.owner = THIS_MODULE;
 		socket[i].number = i;
 		ret = pcmcia_register_socket(&socket[i].socket);
diff --git a/drivers/pcmcia/m32r_cfc.h b/drivers/pcmcia/m32r_cfc.h
--- a/drivers/pcmcia/m32r_cfc.h
+++ b/drivers/pcmcia/m32r_cfc.h
@@ -71,11 +71,15 @@
 
 #define CFC_IOPORT_BASE		0x1000
 
-#if !defined(CONFIG_PLAT_USRV)
+#if defined(CONFIG_PLAT_MAPPI3)
+#define CFC_ATTR_MAPBASE	0x14014000
+#define CFC_IO_MAPBASE_BYTE	0xb4012000
+#define CFC_IO_MAPBASE_WORD	0xb4002000
+#elif !defined(CONFIG_PLAT_USRV)
 #define CFC_ATTR_MAPBASE        0x0c014000
 #define CFC_IO_MAPBASE_BYTE     0xac012000
 #define CFC_IO_MAPBASE_WORD     0xac002000
-#else	/* CONFIG_PLAT_USRV */
+#else
 #define CFC_ATTR_MAPBASE	0x04014000
 #define CFC_IO_MAPBASE_BYTE	0xa4012000
 #define CFC_IO_MAPBASE_WORD	0xa4002000
diff --git a/drivers/pcmcia/m32r_pcc.c b/drivers/pcmcia/m32r_pcc.c
--- a/drivers/pcmcia/m32r_pcc.c
+++ b/drivers/pcmcia/m32r_pcc.c
@@ -30,7 +30,6 @@
 #include <asm/system.h>
 #include <asm/addrspace.h>
 
-#include <pcmcia/version.h>
 #include <pcmcia/cs_types.h>
 #include <pcmcia/ss.h>
 #include <pcmcia/cs.h>
diff --git a/drivers/pcmcia/o2micro.h b/drivers/pcmcia/o2micro.h
--- a/drivers/pcmcia/o2micro.h
+++ b/drivers/pcmcia/o2micro.h
@@ -120,11 +120,16 @@
 #define  O2_MODE_E_LED_OUT	0x08
 #define  O2_MODE_E_SKTA_ACTV	0x10
 
+#define O2_RESERVED1		0x94
+#define O2_RESERVED2		0xD4
+#define O2_RES_READ_PREFETCH	0x02
+#define O2_RES_WRITE_BURST	0x08
+
 static int o2micro_override(struct yenta_socket *socket)
 {
 	/*
-	 * 'reserved' register at 0x94/D4. chaning it to 0xCA (8 bit) enables
-	 * read prefetching which for example makes the RME Hammerfall DSP
+	 * 'reserved' register at 0x94/D4. allows setting read prefetch and write
+	 * bursting. read prefetching for example makes the RME Hammerfall DSP
 	 * working. for some bridges it is at 0x94, for others at 0xD4. it's
 	 * ok to write to both registers on all O2 bridges.
 	 * from Eric Still, 02Micro.
@@ -132,20 +137,35 @@ static int o2micro_override(struct yenta
 	u8 a, b;
 
 	if (PCI_FUNC(socket->dev->devfn) == 0) {
-		a = config_readb(socket, 0x94);
-		b = config_readb(socket, 0xD4);
+		a = config_readb(socket, O2_RESERVED1);
+		b = config_readb(socket, O2_RESERVED2);
 
 		printk(KERN_INFO "Yenta O2: res at 0x94/0xD4: %02x/%02x\n", a, b);
 
 		switch (socket->dev->device) {
+		/*
+		 * older bridges have problems with both read prefetch and write
+		 * bursting depending on the combination of the chipset, bridge
+		 * and the cardbus card. so disable them to be on the safe side.
+		 */
+		case PCI_DEVICE_ID_O2_6729:
+		case PCI_DEVICE_ID_O2_6730:
+		case PCI_DEVICE_ID_O2_6812:
 		case PCI_DEVICE_ID_O2_6832:
-			printk(KERN_INFO "Yenta O2: old bridge, not enabling read prefetch / write burst\n");
+		case PCI_DEVICE_ID_O2_6836:
+			printk(KERN_INFO "Yenta O2: old bridge, disabling read prefetch/write burst\n");
+			config_writeb(socket, O2_RESERVED1,
+			              a & ~(O2_RES_READ_PREFETCH | O2_RES_WRITE_BURST));
+			config_writeb(socket, O2_RESERVED2,
+			              b & ~(O2_RES_READ_PREFETCH | O2_RES_WRITE_BURST));
 			break;
 
 		default:
 			printk(KERN_INFO "Yenta O2: enabling read prefetch/write burst\n");
-			config_writeb(socket, 0x94, a | 0x0a);
-			config_writeb(socket, 0xD4, b | 0x0a);
+			config_writeb(socket, O2_RESERVED1,
+			              a | O2_RES_READ_PREFETCH | O2_RES_WRITE_BURST);
+			config_writeb(socket, O2_RESERVED2,
+			              b | O2_RES_READ_PREFETCH | O2_RES_WRITE_BURST);
 		}
 	}
 
diff --git a/drivers/pcmcia/pcmcia_compat.c b/drivers/pcmcia/pcmcia_compat.c
--- a/drivers/pcmcia/pcmcia_compat.c
+++ b/drivers/pcmcia/pcmcia_compat.c
@@ -18,7 +18,6 @@
 #include <linux/init.h>
 
 #define IN_CARD_SERVICES
-#include <pcmcia/version.h>
 #include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/bulkmem.h>
@@ -28,98 +27,39 @@
 
 #include "cs_internal.h"
 
-int pcmcia_get_first_tuple(client_handle_t handle, tuple_t *tuple)
+int pcmcia_get_first_tuple(struct pcmcia_device *p_dev, tuple_t *tuple)
 {
-	struct pcmcia_socket *s;
-	if (CHECK_HANDLE(handle))
-		return CS_BAD_HANDLE;
-	s = SOCKET(handle);
-	return pccard_get_first_tuple(s, handle->Function, tuple);
+	return pccard_get_first_tuple(p_dev->socket, p_dev->func, tuple);
 }
 EXPORT_SYMBOL(pcmcia_get_first_tuple);
 
-int pcmcia_get_next_tuple(client_handle_t handle, tuple_t *tuple)
+int pcmcia_get_next_tuple(struct pcmcia_device *p_dev, tuple_t *tuple)
 {
-	struct pcmcia_socket *s;
-	if (CHECK_HANDLE(handle))
-		return CS_BAD_HANDLE;
-	s = SOCKET(handle);
-	return pccard_get_next_tuple(s, handle->Function, tuple);
+	return pccard_get_next_tuple(p_dev->socket, p_dev->func, tuple);
 }
 EXPORT_SYMBOL(pcmcia_get_next_tuple);
 
-int pcmcia_get_tuple_data(client_handle_t handle, tuple_t *tuple)
+int pcmcia_get_tuple_data(struct pcmcia_device *p_dev, tuple_t *tuple)
 {
-	struct pcmcia_socket *s;
-	if (CHECK_HANDLE(handle))
-		return CS_BAD_HANDLE;
-	s = SOCKET(handle);
-	return pccard_get_tuple_data(s, tuple);
+	return pccard_get_tuple_data(p_dev->socket, tuple);
 }
 EXPORT_SYMBOL(pcmcia_get_tuple_data);
 
-int pcmcia_parse_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse)
+int pcmcia_parse_tuple(struct pcmcia_device *p_dev, tuple_t *tuple, cisparse_t *parse)
 {
 	return pccard_parse_tuple(tuple, parse);
 }
 EXPORT_SYMBOL(pcmcia_parse_tuple);
 
-int pcmcia_validate_cis(client_handle_t handle, cisinfo_t *info)
+int pcmcia_validate_cis(struct pcmcia_device *p_dev, cisinfo_t *info)
 {
-	struct pcmcia_socket *s;
-	if (CHECK_HANDLE(handle))
-		return CS_BAD_HANDLE;
-	s = SOCKET(handle);
-	return pccard_validate_cis(s, handle->Function, info);
+	return pccard_validate_cis(p_dev->socket, p_dev->func, info);
 }
 EXPORT_SYMBOL(pcmcia_validate_cis);
 
-int pcmcia_get_configuration_info(client_handle_t handle,
-				  config_info_t *config)
-{
-	struct pcmcia_socket *s;
-
-	if ((CHECK_HANDLE(handle)) || !config)
-		return CS_BAD_HANDLE;
-	s = SOCKET(handle);
-	if (!s)
-		return CS_BAD_HANDLE;
-	return pccard_get_configuration_info(s, handle->Function, config);
-}
-EXPORT_SYMBOL(pcmcia_get_configuration_info);
-
-int pcmcia_reset_card(client_handle_t handle, client_req_t *req)
-{
-	struct pcmcia_socket *skt;
-    
-	if (CHECK_HANDLE(handle))
-		return CS_BAD_HANDLE;
-	skt = SOCKET(handle);
-	if (!skt)
-		return CS_BAD_HANDLE;
 
-	return pccard_reset_card(skt);
-}
-EXPORT_SYMBOL(pcmcia_reset_card);
-
-int pcmcia_get_status(client_handle_t handle, cs_status_t *status)
+int pcmcia_reset_card(struct pcmcia_device *p_dev, client_req_t *req)
 {
-	struct pcmcia_socket *s;
-	if (CHECK_HANDLE(handle))
-		return CS_BAD_HANDLE;
-	s = SOCKET(handle);
-	return pccard_get_status(s, handle->Function, status);
-}
-EXPORT_SYMBOL(pcmcia_get_status);
-
-int pcmcia_access_configuration_register(client_handle_t handle,
-					 conf_reg_t *reg)
-{
-	struct pcmcia_socket *s;
-	if (CHECK_HANDLE(handle))
-		return CS_BAD_HANDLE;
-	s = SOCKET(handle);
-	return pccard_access_configuration_register(s, handle->Function, reg);
+	return pccard_reset_card(p_dev->socket);
 }
-EXPORT_SYMBOL(pcmcia_access_configuration_register);
-
+EXPORT_SYMBOL(pcmcia_reset_card);
diff --git a/drivers/pcmcia/pcmcia_ioctl.c b/drivers/pcmcia/pcmcia_ioctl.c
new file mode 100644
--- /dev/null
+++ b/drivers/pcmcia/pcmcia_ioctl.c
@@ -0,0 +1,759 @@
+/*
+ * pcmcia_ioctl.c -- ioctl interface for cardmgr and cardctl
+ *
+ * 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.
+ *
+ * The initial developer of the original code is David A. Hinds
+ * <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
+ * are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
+ *
+ * (C) 1999		David A. Hinds
+ * (C) 2003 - 2004	Dominik Brodowski
+ */
+
+/*
+ * This file will go away soon.
+ */
+
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/major.h>
+#include <linux/errno.h>
+#include <linux/ioctl.h>
+#include <linux/proc_fs.h>
+#include <linux/poll.h>
+#include <linux/pci.h>
+#include <linux/workqueue.h>
+
+#define IN_CARD_SERVICES
+#include <pcmcia/cs_types.h>
+#include <pcmcia/cs.h>
+#include <pcmcia/cistpl.h>
+#include <pcmcia/ds.h>
+#include <pcmcia/ss.h>
+
+#include "cs_internal.h"
+#include "ds_internal.h"
+
+static int major_dev = -1;
+
+
+/* Device user information */
+#define MAX_EVENTS	32
+#define USER_MAGIC	0x7ea4
+#define CHECK_USER(u) \
+    (((u) == NULL) || ((u)->user_magic != USER_MAGIC))
+
+typedef struct user_info_t {
+	u_int			user_magic;
+	int			event_head, event_tail;
+	event_t			event[MAX_EVENTS];
+	struct user_info_t	*next;
+	struct pcmcia_socket	*socket;
+} user_info_t;
+
+
+#ifdef DEBUG
+extern int ds_pc_debug;
+#define cs_socket_name(skt)    ((skt)->dev.class_id)
+
+#define ds_dbg(lvl, fmt, arg...) do {		\
+	if (ds_pc_debug >= lvl)				\
+		printk(KERN_DEBUG "ds: " fmt , ## arg);		\
+} while (0)
+#else
+#define ds_dbg(lvl, fmt, arg...) do { } while (0)
+#endif
+
+
+/* backwards-compatible accessing of driver --- by name! */
+
+static struct pcmcia_driver * get_pcmcia_driver (dev_info_t *dev_info)
+{
+	struct device_driver *drv;
+	struct pcmcia_driver *p_drv;
+
+	drv = driver_find((char *) dev_info, &pcmcia_bus_type);
+	if (!drv)
+		return NULL;
+
+	p_drv = container_of(drv, struct pcmcia_driver, drv);
+
+	return (p_drv);
+}
+
+
+#ifdef CONFIG_PROC_FS
+static struct proc_dir_entry *proc_pccard = NULL;
+
+static int proc_read_drivers_callback(struct device_driver *driver, void *d)
+{
+	char **p = d;
+	struct pcmcia_driver *p_drv = container_of(driver,
+						   struct pcmcia_driver, drv);
+
+	*p += sprintf(*p, "%-24.24s 1 %d\n", p_drv->drv.name,
+#ifdef CONFIG_MODULE_UNLOAD
+		      (p_drv->owner) ? module_refcount(p_drv->owner) : 1
+#else
+		      1
+#endif
+	);
+	d = (void *) p;
+
+	return 0;
+}
+
+static int proc_read_drivers(char *buf, char **start, off_t pos,
+			     int count, int *eof, void *data)
+{
+	char *p = buf;
+
+	bus_for_each_drv(&pcmcia_bus_type, NULL,
+			 (void *) &p, proc_read_drivers_callback);
+
+	return (p - buf);
+}
+#endif
+
+/*======================================================================
+
+    These manage a ring buffer of events pending for one user process
+
+======================================================================*/
+
+
+static int queue_empty(user_info_t *user)
+{
+    return (user->event_head == user->event_tail);
+}
+
+static event_t get_queued_event(user_info_t *user)
+{
+    user->event_tail = (user->event_tail+1) % MAX_EVENTS;
+    return user->event[user->event_tail];
+}
+
+static void queue_event(user_info_t *user, event_t event)
+{
+    user->event_head = (user->event_head+1) % MAX_EVENTS;
+    if (user->event_head == user->event_tail)
+	user->event_tail = (user->event_tail+1) % MAX_EVENTS;
+    user->event[user->event_head] = event;
+}
+
+void handle_event(struct pcmcia_socket *s, event_t event)
+{
+    user_info_t *user;
+    for (user = s->user; user; user = user->next)
+	queue_event(user, event);
+    wake_up_interruptible(&s->queue);
+}
+
+
+/*======================================================================
+
+    bind_request() and bind_device() are merged by now. Register_client()
+    is called right at the end of bind_request(), during the driver's
+    ->attach() call. Individual descriptions:
+
+    bind_request() connects a socket to a particular client driver.
+    It looks up the specified device ID in the list of registered
+    drivers, binds it to the socket, and tries to create an instance
+    of the device.  unbind_request() deletes a driver instance.
+
+    Bind_device() associates a device driver with a particular socket.
+    It is normally called by Driver Services after it has identified
+    a newly inserted card.  An instance of that driver will then be
+    eligible to register as a client of this socket.
+
+    Register_client() uses the dev_info_t handle to match the
+    caller with a socket.  The driver must have already been bound
+    to a socket with bind_device() -- in fact, bind_device()
+    allocates the client structure that will be used.
+
+======================================================================*/
+
+static int bind_request(struct pcmcia_socket *s, bind_info_t *bind_info)
+{
+	struct pcmcia_driver *p_drv;
+	struct pcmcia_device *p_dev;
+	int ret = 0;
+	unsigned long flags;
+
+	s = pcmcia_get_socket(s);
+	if (!s)
+		return -EINVAL;
+
+	ds_dbg(2, "bind_request(%d, '%s')\n", s->sock,
+	       (char *)bind_info->dev_info);
+
+	p_drv = get_pcmcia_driver(&bind_info->dev_info);
+	if (!p_drv) {
+		ret = -EINVAL;
+		goto err_put;
+	}
+
+	if (!try_module_get(p_drv->owner)) {
+		ret = -EINVAL;
+		goto err_put_driver;
+	}
+
+	spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
+        list_for_each_entry(p_dev, &s->devices_list, socket_device_list) {
+		if (p_dev->func == bind_info->function) {
+			if ((p_dev->dev.driver == &p_drv->drv)) {
+				if (p_dev->cardmgr) {
+					/* if there's already a device
+					 * registered, and it was registered
+					 * by userspace before, we need to
+					 * return the "instance". */
+					spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
+					bind_info->instance = p_dev->instance;
+					ret = -EBUSY;
+					goto err_put_module;
+				} else {
+					/* the correct driver managed to bind
+					 * itself magically to the correct
+					 * device. */
+					spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
+					p_dev->cardmgr = p_drv;
+					ret = 0;
+					goto err_put_module;
+				}
+			} else if (!p_dev->dev.driver) {
+				/* there's already a device available where
+				 * no device has been bound to yet. So we don't
+				 * need to register a device! */
+				spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
+				goto rescan;
+			}
+		}
+	}
+	spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
+
+	p_dev = pcmcia_device_add(s, bind_info->function);
+	if (!p_dev) {
+		ret = -EIO;
+		goto err_put_module;
+	}
+
+rescan:
+	p_dev->cardmgr = p_drv;
+
+	/* if a driver is already running, we can abort */
+	if (p_dev->dev.driver)
+		goto err_put_module;
+
+	/*
+	 * Prevent this racing with a card insertion.
+	 */
+	down(&s->skt_sem);
+	bus_rescan_devices(&pcmcia_bus_type);
+	up(&s->skt_sem);
+
+	/* check whether the driver indeed matched. I don't care if this
+	 * is racy or not, because it can only happen on cardmgr access
+	 * paths...
+	 */
+	if (!(p_dev->dev.driver == &p_drv->drv))
+		p_dev->cardmgr = NULL;
+
+ err_put_module:
+	module_put(p_drv->owner);
+ err_put_driver:
+	put_driver(&p_drv->drv);
+ err_put:
+	pcmcia_put_socket(s);
+
+	return (ret);
+} /* bind_request */
+
+#ifdef CONFIG_CARDBUS
+
+static struct pci_bus *pcmcia_lookup_bus(struct pcmcia_socket *s)
+{
+	if (!s || !(s->state & SOCKET_CARDBUS))
+		return NULL;
+
+	return s->cb_dev->subordinate;
+}
+#endif
+
+static int get_device_info(struct pcmcia_socket *s, bind_info_t *bind_info, int first)
+{
+	dev_node_t *node;
+	struct pcmcia_device *p_dev;
+	unsigned long flags;
+	int ret = 0;
+
+#ifdef CONFIG_CARDBUS
+	/*
+	 * Some unbelievably ugly code to associate the PCI cardbus
+	 * device and its driver with the PCMCIA "bind" information.
+	 */
+	{
+		struct pci_bus *bus;
+
+		bus = pcmcia_lookup_bus(s);
+		if (bus) {
+			struct list_head *list;
+			struct pci_dev *dev = NULL;
+
+			list = bus->devices.next;
+			while (list != &bus->devices) {
+				struct pci_dev *pdev = pci_dev_b(list);
+				list = list->next;
+
+				if (first) {
+					dev = pdev;
+					break;
+				}
+
+				/* Try to handle "next" here some way? */
+			}
+			if (dev && dev->driver) {
+				strlcpy(bind_info->name, dev->driver->name, DEV_NAME_LEN);
+				bind_info->major = 0;
+				bind_info->minor = 0;
+				bind_info->next = NULL;
+				return 0;
+			}
+		}
+	}
+#endif
+
+	spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
+	list_for_each_entry(p_dev, &s->devices_list, socket_device_list) {
+		if (p_dev->func == bind_info->function) {
+			p_dev = pcmcia_get_dev(p_dev);
+			if (!p_dev)
+				continue;
+			goto found;
+		}
+	}
+	spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
+	return -ENODEV;
+
+ found:
+	spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
+
+	if ((!p_dev->instance) ||
+	    (p_dev->instance->state & DEV_CONFIG_PENDING)) {
+		ret = -EAGAIN;
+		goto err_put;
+	}
+
+	if (first)
+		node = p_dev->instance->dev;
+	else
+		for (node = p_dev->instance->dev; node; node = node->next)
+			if (node == bind_info->next)
+				break;
+	if (!node) {
+		ret = -ENODEV;
+		goto err_put;
+	}
+
+	strlcpy(bind_info->name, node->dev_name, DEV_NAME_LEN);
+	bind_info->major = node->major;
+	bind_info->minor = node->minor;
+	bind_info->next = node->next;
+
+ err_put:
+	pcmcia_put_dev(p_dev);
+	return (ret);
+} /* get_device_info */
+
+
+static int ds_open(struct inode *inode, struct file *file)
+{
+    socket_t i = iminor(inode);
+    struct pcmcia_socket *s;
+    user_info_t *user;
+
+    ds_dbg(0, "ds_open(socket %d)\n", i);
+
+    s = pcmcia_get_socket_by_nr(i);
+    if (!s)
+	    return -ENODEV;
+    s = pcmcia_get_socket(s);
+    if (!s)
+	    return -ENODEV;
+
+    if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
+	    if (s->pcmcia_state.busy) {
+		    pcmcia_put_socket(s);
+		    return -EBUSY;
+	    }
+	else
+	    s->pcmcia_state.busy = 1;
+    }
+
+    user = kmalloc(sizeof(user_info_t), GFP_KERNEL);
+    if (!user) {
+	    pcmcia_put_socket(s);
+	    return -ENOMEM;
+    }
+    user->event_tail = user->event_head = 0;
+    user->next = s->user;
+    user->user_magic = USER_MAGIC;
+    user->socket = s;
+    s->user = user;
+    file->private_data = user;
+
+    if (s->pcmcia_state.present)
+	queue_event(user, CS_EVENT_CARD_INSERTION);
+    return 0;
+} /* ds_open */
+
+/*====================================================================*/
+
+static int ds_release(struct inode *inode, struct file *file)
+{
+    struct pcmcia_socket *s;
+    user_info_t *user, **link;
+
+    ds_dbg(0, "ds_release(socket %d)\n", iminor(inode));
+
+    user = file->private_data;
+    if (CHECK_USER(user))
+	goto out;
+
+    s = user->socket;
+
+    /* Unlink user data structure */
+    if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
+	s->pcmcia_state.busy = 0;
+    }
+    file->private_data = NULL;
+    for (link = &s->user; *link; link = &(*link)->next)
+	if (*link == user) break;
+    if (link == NULL)
+	goto out;
+    *link = user->next;
+    user->user_magic = 0;
+    kfree(user);
+    pcmcia_put_socket(s);
+out:
+    return 0;
+} /* ds_release */
+
+/*====================================================================*/
+
+static ssize_t ds_read(struct file *file, char __user *buf,
+		       size_t count, loff_t *ppos)
+{
+    struct pcmcia_socket *s;
+    user_info_t *user;
+    int ret;
+
+    ds_dbg(2, "ds_read(socket %d)\n", iminor(file->f_dentry->d_inode));
+
+    if (count < 4)
+	return -EINVAL;
+
+    user = file->private_data;
+    if (CHECK_USER(user))
+	return -EIO;
+
+    s = user->socket;
+    if (s->pcmcia_state.dead)
+        return -EIO;
+
+    ret = wait_event_interruptible(s->queue, !queue_empty(user));
+    if (ret == 0)
+	ret = put_user(get_queued_event(user), (int __user *)buf) ? -EFAULT : 4;
+
+    return ret;
+} /* ds_read */
+
+/*====================================================================*/
+
+static ssize_t ds_write(struct file *file, const char __user *buf,
+			size_t count, loff_t *ppos)
+{
+    ds_dbg(2, "ds_write(socket %d)\n", iminor(file->f_dentry->d_inode));
+
+    if (count != 4)
+	return -EINVAL;
+    if ((file->f_flags & O_ACCMODE) == O_RDONLY)
+	return -EBADF;
+
+    return -EIO;
+} /* ds_write */
+
+/*====================================================================*/
+
+/* No kernel lock - fine */
+static u_int ds_poll(struct file *file, poll_table *wait)
+{
+    struct pcmcia_socket *s;
+    user_info_t *user;
+
+    ds_dbg(2, "ds_poll(socket %d)\n", iminor(file->f_dentry->d_inode));
+
+    user = file->private_data;
+    if (CHECK_USER(user))
+	return POLLERR;
+    s = user->socket;
+    /*
+     * We don't check for a dead socket here since that
+     * will send cardmgr into an endless spin.
+     */
+    poll_wait(file, &s->queue, wait);
+    if (!queue_empty(user))
+	return POLLIN | POLLRDNORM;
+    return 0;
+} /* ds_poll */
+
+/*====================================================================*/
+
+extern int pcmcia_adjust_resource_info(adjust_t *adj);
+
+static int ds_ioctl(struct inode * inode, struct file * file,
+		    u_int cmd, u_long arg)
+{
+    struct pcmcia_socket *s;
+    void __user *uarg = (char __user *)arg;
+    u_int size;
+    int ret, err;
+    ds_ioctl_arg_t *buf;
+    user_info_t *user;
+
+    ds_dbg(2, "ds_ioctl(socket %d, %#x, %#lx)\n", iminor(inode), cmd, arg);
+
+    user = file->private_data;
+    if (CHECK_USER(user))
+	return -EIO;
+
+    s = user->socket;
+    if (s->pcmcia_state.dead)
+        return -EIO;
+
+    size = (cmd & IOCSIZE_MASK) >> IOCSIZE_SHIFT;
+    if (size > sizeof(ds_ioctl_arg_t)) return -EINVAL;
+
+    /* Permission check */
+    if (!(cmd & IOC_OUT) && !capable(CAP_SYS_ADMIN))
+	return -EPERM;
+
+    if (cmd & IOC_IN) {
+	if (!access_ok(VERIFY_READ, uarg, size)) {
+	    ds_dbg(3, "ds_ioctl(): verify_read = %d\n", -EFAULT);
+	    return -EFAULT;
+	}
+    }
+    if (cmd & IOC_OUT) {
+	if (!access_ok(VERIFY_WRITE, uarg, size)) {
+	    ds_dbg(3, "ds_ioctl(): verify_write = %d\n", -EFAULT);
+	    return -EFAULT;
+	}
+    }
+    buf = kmalloc(sizeof(ds_ioctl_arg_t), GFP_KERNEL);
+    if (!buf)
+	return -ENOMEM;
+
+    err = ret = 0;
+
+    if (cmd & IOC_IN) __copy_from_user((char *)buf, uarg, size);
+
+    switch (cmd) {
+    case DS_ADJUST_RESOURCE_INFO:
+	ret = pcmcia_adjust_resource_info(&buf->adjust);
+	break;
+    case DS_GET_CONFIGURATION_INFO:
+	if (buf->config.Function &&
+	   (buf->config.Function >= s->functions))
+	    ret = CS_BAD_ARGS;
+	else
+	    ret = pccard_get_configuration_info(s,
+			buf->config.Function, &buf->config);
+	break;
+    case DS_GET_FIRST_TUPLE:
+	down(&s->skt_sem);
+	pcmcia_validate_mem(s);
+	up(&s->skt_sem);
+	ret = pccard_get_first_tuple(s, BIND_FN_ALL, &buf->tuple);
+	break;
+    case DS_GET_NEXT_TUPLE:
+	ret = pccard_get_next_tuple(s, BIND_FN_ALL, &buf->tuple);
+	break;
+    case DS_GET_TUPLE_DATA:
+	buf->tuple.TupleData = buf->tuple_parse.data;
+	buf->tuple.TupleDataMax = sizeof(buf->tuple_parse.data);
+	ret = pccard_get_tuple_data(s, &buf->tuple);
+	break;
+    case DS_PARSE_TUPLE:
+	buf->tuple.TupleData = buf->tuple_parse.data;
+	ret = pccard_parse_tuple(&buf->tuple, &buf->tuple_parse.parse);
+	break;
+    case DS_RESET_CARD:
+	ret = pccard_reset_card(s);
+	break;
+    case DS_GET_STATUS:
+	if (buf->status.Function &&
+	   (buf->status.Function >= s->functions))
+	    ret = CS_BAD_ARGS;
+	else
+	ret = pccard_get_status(s, buf->status.Function, &buf->status);
+	break;
+    case DS_VALIDATE_CIS:
+	down(&s->skt_sem);
+	pcmcia_validate_mem(s);
+	up(&s->skt_sem);
+	ret = pccard_validate_cis(s, BIND_FN_ALL, &buf->cisinfo);
+	break;
+    case DS_SUSPEND_CARD:
+	ret = pcmcia_suspend_card(s);
+	break;
+    case DS_RESUME_CARD:
+	ret = pcmcia_resume_card(s);
+	break;
+    case DS_EJECT_CARD:
+	err = pcmcia_eject_card(s);
+	break;
+    case DS_INSERT_CARD:
+	err = pcmcia_insert_card(s);
+	break;
+    case DS_ACCESS_CONFIGURATION_REGISTER:
+	if ((buf->conf_reg.Action == CS_WRITE) && !capable(CAP_SYS_ADMIN)) {
+	    err = -EPERM;
+	    goto free_out;
+	}
+	if (buf->conf_reg.Function &&
+	   (buf->conf_reg.Function >= s->functions))
+	    ret = CS_BAD_ARGS;
+	else
+	    ret = pccard_access_configuration_register(s,
+			buf->conf_reg.Function, &buf->conf_reg);
+	break;
+    case DS_GET_FIRST_REGION:
+    case DS_GET_NEXT_REGION:
+    case DS_BIND_MTD:
+	if (!capable(CAP_SYS_ADMIN)) {
+		err = -EPERM;
+		goto free_out;
+	} else {
+		static int printed = 0;
+		if (!printed) {
+			printk(KERN_WARNING "2.6. kernels use pcmciamtd instead of memory_cs.c and do not require special\n");
+			printk(KERN_WARNING "MTD handling any more.\n");
+			printed++;
+		}
+	}
+	err = -EINVAL;
+	goto free_out;
+	break;
+    case DS_GET_FIRST_WINDOW:
+	ret = pcmcia_get_window(s, &buf->win_info.handle, 0,
+			&buf->win_info.window);
+	break;
+    case DS_GET_NEXT_WINDOW:
+	ret = pcmcia_get_window(s, &buf->win_info.handle,
+			buf->win_info.handle->index + 1, &buf->win_info.window);
+	break;
+    case DS_GET_MEM_PAGE:
+	ret = pcmcia_get_mem_page(buf->win_info.handle,
+			   &buf->win_info.map);
+	break;
+    case DS_REPLACE_CIS:
+	ret = pcmcia_replace_cis(s, &buf->cisdump);
+	break;
+    case DS_BIND_REQUEST:
+	if (!capable(CAP_SYS_ADMIN)) {
+		err = -EPERM;
+		goto free_out;
+	}
+	err = bind_request(s, &buf->bind_info);
+	break;
+    case DS_GET_DEVICE_INFO:
+	err = get_device_info(s, &buf->bind_info, 1);
+	break;
+    case DS_GET_NEXT_DEVICE:
+	err = get_device_info(s, &buf->bind_info, 0);
+	break;
+    case DS_UNBIND_REQUEST:
+	err = 0;
+	break;
+    default:
+	err = -EINVAL;
+    }
+
+    if ((err == 0) && (ret != CS_SUCCESS)) {
+	ds_dbg(2, "ds_ioctl: ret = %d\n", ret);
+	switch (ret) {
+	case CS_BAD_SOCKET: case CS_NO_CARD:
+	    err = -ENODEV; break;
+	case CS_BAD_ARGS: case CS_BAD_ATTRIBUTE: case CS_BAD_IRQ:
+	case CS_BAD_TUPLE:
+	    err = -EINVAL; break;
+	case CS_IN_USE:
+	    err = -EBUSY; break;
+	case CS_OUT_OF_RESOURCE:
+	    err = -ENOSPC; break;
+	case CS_NO_MORE_ITEMS:
+	    err = -ENODATA; break;
+	case CS_UNSUPPORTED_FUNCTION:
+	    err = -ENOSYS; break;
+	default:
+	    err = -EIO; break;
+	}
+    }
+
+    if (cmd & IOC_OUT) {
+        if (__copy_to_user(uarg, (char *)buf, size))
+            err = -EFAULT;
+    }
+
+free_out:
+    kfree(buf);
+    return err;
+} /* ds_ioctl */
+
+/*====================================================================*/
+
+static struct file_operations ds_fops = {
+	.owner		= THIS_MODULE,
+	.open		= ds_open,
+	.release	= ds_release,
+	.ioctl		= ds_ioctl,
+	.read		= ds_read,
+	.write		= ds_write,
+	.poll		= ds_poll,
+};
+
+void __init pcmcia_setup_ioctl(void) {
+	int i;
+
+	/* Set up character device for user mode clients */
+	i = register_chrdev(0, "pcmcia", &ds_fops);
+	if (i < 0)
+		printk(KERN_NOTICE "unable to find a free device # for "
+		       "Driver Services (error=%d)\n", i);
+	else
+		major_dev = i;
+
+#ifdef CONFIG_PROC_FS
+	proc_pccard = proc_mkdir("pccard", proc_bus);
+	if (proc_pccard)
+		create_proc_read_entry("drivers",0,proc_pccard,proc_read_drivers,NULL);
+#endif
+}
+
+
+void __exit pcmcia_cleanup_ioctl(void) {
+#ifdef CONFIG_PROC_FS
+	if (proc_pccard) {
+		remove_proc_entry("drivers", proc_pccard);
+		remove_proc_entry("pccard", proc_bus);
+	}
+#endif
+	if (major_dev != -1)
+		unregister_chrdev(major_dev, "pcmcia");
+}
diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c
new file mode 100644
--- /dev/null
+++ b/drivers/pcmcia/pcmcia_resource.c
@@ -0,0 +1,944 @@
+/*
+ * PCMCIA 16-bit resource management functions
+ *
+ * The initial developer of the original code is David A. Hinds
+ * <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
+ * are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
+ *
+ * Copyright (C) 1999	     David A. Hinds
+ * Copyright (C) 2004-2005   Dominik Brodowski
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/pci.h>
+#include <linux/device.h>
+
+#define IN_CARD_SERVICES
+#include <pcmcia/cs_types.h>
+#include <pcmcia/ss.h>
+#include <pcmcia/cs.h>
+#include <pcmcia/bulkmem.h>
+#include <pcmcia/cistpl.h>
+#include <pcmcia/cisreg.h>
+#include <pcmcia/ds.h>
+
+#include "cs_internal.h"
+#include "ds_internal.h"
+
+
+/* Access speed for IO windows */
+static int io_speed = 0;
+module_param(io_speed, int, 0444);
+
+
+#ifdef CONFIG_PCMCIA_PROBE
+#include <asm/irq.h>
+/* mask of IRQs already reserved by other cards, we should avoid using them */
+static u8 pcmcia_used_irq[NR_IRQS];
+#endif
+
+
+#ifdef DEBUG
+extern int ds_pc_debug;
+#define cs_socket_name(skt)    ((skt)->dev.class_id)
+
+#define ds_dbg(skt, lvl, fmt, arg...) do {			\
+	if (ds_pc_debug >= lvl)					\
+		printk(KERN_DEBUG "pcmcia_resource: %s: " fmt,	\
+			cs_socket_name(skt) , ## arg);		\
+} while (0)
+#else
+#define ds_dbg(lvl, fmt, arg...) do { } while (0)
+#endif
+
+
+
+/** alloc_io_space
+ *
+ * Special stuff for managing IO windows, because they are scarce
+ */
+
+static int alloc_io_space(struct pcmcia_socket *s, u_int attr, ioaddr_t *base,
+			  ioaddr_t num, u_int lines)
+{
+	int i;
+	kio_addr_t try, align;
+
+	align = (*base) ? (lines ? 1<<lines : 0) : 1;
+	if (align && (align < num)) {
+		if (*base) {
+			ds_dbg(s, 0, "odd IO request: num %#x align %#lx\n",
+			       num, align);
+			align = 0;
+		} else
+			while (align && (align < num)) align <<= 1;
+	}
+	if (*base & ~(align-1)) {
+		ds_dbg(s, 0, "odd IO request: base %#x align %#lx\n",
+		       *base, align);
+		align = 0;
+	}
+	if ((s->features & SS_CAP_STATIC_MAP) && s->io_offset) {
+		*base = s->io_offset | (*base & 0x0fff);
+		s->io[0].Attributes = attr;
+		return 0;
+	}
+	/* Check for an already-allocated window that must conflict with
+	 * what was asked for.  It is a hack because it does not catch all
+	 * potential conflicts, just the most obvious ones.
+	 */
+	for (i = 0; i < MAX_IO_WIN; i++)
+		if ((s->io[i].NumPorts != 0) &&
+		    ((s->io[i].BasePort & (align-1)) == *base))
+			return 1;
+	for (i = 0; i < MAX_IO_WIN; i++) {
+		if (s->io[i].NumPorts == 0) {
+			s->io[i].res = pcmcia_find_io_region(*base, num, align, s);
+			if (s->io[i].res) {
+				s->io[i].Attributes = attr;
+				s->io[i].BasePort = *base = s->io[i].res->start;
+				s->io[i].NumPorts = s->io[i].InUse = num;
+				break;
+			} else
+				return 1;
+		} else if (s->io[i].Attributes != attr)
+			continue;
+		/* Try to extend top of window */
+		try = s->io[i].BasePort + s->io[i].NumPorts;
+		if ((*base == 0) || (*base == try))
+			if (pcmcia_adjust_io_region(s->io[i].res, s->io[i].res->start,
+						    s->io[i].res->end + num, s) == 0) {
+				*base = try;
+				s->io[i].NumPorts += num;
+				s->io[i].InUse += num;
+				break;
+			}
+		/* Try to extend bottom of window */
+		try = s->io[i].BasePort - num;
+		if ((*base == 0) || (*base == try))
+			if (pcmcia_adjust_io_region(s->io[i].res, s->io[i].res->start - num,
+						    s->io[i].res->end, s) == 0) {
+				s->io[i].BasePort = *base = try;
+				s->io[i].NumPorts += num;
+				s->io[i].InUse += num;
+				break;
+			}
+	}
+	return (i == MAX_IO_WIN);
+} /* alloc_io_space */
+
+
+static void release_io_space(struct pcmcia_socket *s, ioaddr_t base,
+			     ioaddr_t num)
+{
+	int i;
+
+	for (i = 0; i < MAX_IO_WIN; i++) {
+		if ((s->io[i].BasePort <= base) &&
+		    (s->io[i].BasePort+s->io[i].NumPorts >= base+num)) {
+			s->io[i].InUse -= num;
+			/* Free the window if no one else is using it */
+			if (s->io[i].InUse == 0) {
+				s->io[i].NumPorts = 0;
+				release_resource(s->io[i].res);
+				kfree(s->io[i].res);
+				s->io[i].res = NULL;
+			}
+		}
+	}
+} /* release_io_space */
+
+
+/** pccard_access_configuration_register
+ *
+ * Access_configuration_register() reads and writes configuration
+ * registers in attribute memory.  Memory window 0 is reserved for
+ * this and the tuple reading services.
+ */
+
+int pccard_access_configuration_register(struct pcmcia_socket *s,
+					 unsigned int function,
+					 conf_reg_t *reg)
+{
+	config_t *c;
+	int addr;
+	u_char val;
+
+	if (!s || !s->config)
+		return CS_NO_CARD;
+
+	c = &s->config[function];
+
+	if (c == NULL)
+		return CS_NO_CARD;
+
+	if (!(c->state & CONFIG_LOCKED))
+		return CS_CONFIGURATION_LOCKED;
+
+	addr = (c->ConfigBase + reg->Offset) >> 1;
+
+	switch (reg->Action) {
+	case CS_READ:
+		pcmcia_read_cis_mem(s, 1, addr, 1, &val);
+		reg->Value = val;
+		break;
+	case CS_WRITE:
+		val = reg->Value;
+		pcmcia_write_cis_mem(s, 1, addr, 1, &val);
+		break;
+	default:
+		return CS_BAD_ARGS;
+		break;
+	}
+	return CS_SUCCESS;
+} /* pccard_access_configuration_register */
+
+int pcmcia_access_configuration_register(struct pcmcia_device *p_dev,
+					 conf_reg_t *reg)
+{
+	return pccard_access_configuration_register(p_dev->socket,
+						    p_dev->func, reg);
+}
+EXPORT_SYMBOL(pcmcia_access_configuration_register);
+
+
+
+int pccard_get_configuration_info(struct pcmcia_socket *s,
+				  unsigned int function,
+				  config_info_t *config)
+{
+	config_t *c;
+
+	if (!(s->state & SOCKET_PRESENT))
+		return CS_NO_CARD;
+
+	config->Function = function;
+
+#ifdef CONFIG_CARDBUS
+	if (s->state & SOCKET_CARDBUS) {
+		memset(config, 0, sizeof(config_info_t));
+		config->Vcc = s->socket.Vcc;
+		config->Vpp1 = config->Vpp2 = s->socket.Vpp;
+		config->Option = s->cb_dev->subordinate->number;
+		if (s->state & SOCKET_CARDBUS_CONFIG) {
+			config->Attributes = CONF_VALID_CLIENT;
+			config->IntType = INT_CARDBUS;
+			config->AssignedIRQ = s->irq.AssignedIRQ;
+			if (config->AssignedIRQ)
+				config->Attributes |= CONF_ENABLE_IRQ;
+			config->BasePort1 = s->io[0].BasePort;
+			config->NumPorts1 = s->io[0].NumPorts;
+		}
+		return CS_SUCCESS;
+	}
+#endif
+
+	c = (s->config != NULL) ? &s->config[function] : NULL;
+
+	if ((c == NULL) || !(c->state & CONFIG_LOCKED)) {
+		config->Attributes = 0;
+		config->Vcc = s->socket.Vcc;
+		config->Vpp1 = config->Vpp2 = s->socket.Vpp;
+		return CS_SUCCESS;
+	}
+
+	/* !!! This is a hack !!! */
+	memcpy(&config->Attributes, &c->Attributes, sizeof(config_t));
+	config->Attributes |= CONF_VALID_CLIENT;
+	config->CardValues = c->CardValues;
+	config->IRQAttributes = c->irq.Attributes;
+	config->AssignedIRQ = s->irq.AssignedIRQ;
+	config->BasePort1 = c->io.BasePort1;
+	config->NumPorts1 = c->io.NumPorts1;
+	config->Attributes1 = c->io.Attributes1;
+	config->BasePort2 = c->io.BasePort2;
+	config->NumPorts2 = c->io.NumPorts2;
+	config->Attributes2 = c->io.Attributes2;
+	config->IOAddrLines = c->io.IOAddrLines;
+
+	return CS_SUCCESS;
+} /* pccard_get_configuration_info */
+
+int pcmcia_get_configuration_info(struct pcmcia_device *p_dev,
+				  config_info_t *config)
+{
+	return pccard_get_configuration_info(p_dev->socket, p_dev->func,
+					     config);
+}
+EXPORT_SYMBOL(pcmcia_get_configuration_info);
+
+
+/** pcmcia_get_window
+ */
+int pcmcia_get_window(struct pcmcia_socket *s, window_handle_t *handle,
+		      int idx, win_req_t *req)
+{
+	window_t *win;
+	int w;
+
+	if (!s || !(s->state & SOCKET_PRESENT))
+		return CS_NO_CARD;
+	for (w = idx; w < MAX_WIN; w++)
+		if (s->state & SOCKET_WIN_REQ(w))
+			break;
+	if (w == MAX_WIN)
+		return CS_NO_MORE_ITEMS;
+	win = &s->win[w];
+	req->Base = win->ctl.res->start;
+	req->Size = win->ctl.res->end - win->ctl.res->start + 1;
+	req->AccessSpeed = win->ctl.speed;
+	req->Attributes = 0;
+	if (win->ctl.flags & MAP_ATTRIB)
+		req->Attributes |= WIN_MEMORY_TYPE_AM;
+	if (win->ctl.flags & MAP_ACTIVE)
+		req->Attributes |= WIN_ENABLE;
+	if (win->ctl.flags & MAP_16BIT)
+		req->Attributes |= WIN_DATA_WIDTH_16;
+	if (win->ctl.flags & MAP_USE_WAIT)
+		req->Attributes |= WIN_USE_WAIT;
+	*handle = win;
+	return CS_SUCCESS;
+} /* pcmcia_get_window */
+EXPORT_SYMBOL(pcmcia_get_window);
+
+
+/** pccard_get_status
+ *
+ * Get the current socket state bits.  We don't support the latched
+ * SocketState yet: I haven't seen any point for it.
+ */
+
+int pccard_get_status(struct pcmcia_socket *s, unsigned int function,
+		      cs_status_t *status)
+{
+	config_t *c;
+	int val;
+
+	s->ops->get_status(s, &val);
+	status->CardState = status->SocketState = 0;
+	status->CardState |= (val & SS_DETECT) ? CS_EVENT_CARD_DETECT : 0;
+	status->CardState |= (val & SS_CARDBUS) ? CS_EVENT_CB_DETECT : 0;
+	status->CardState |= (val & SS_3VCARD) ? CS_EVENT_3VCARD : 0;
+	status->CardState |= (val & SS_XVCARD) ? CS_EVENT_XVCARD : 0;
+	if (s->state & SOCKET_SUSPEND)
+		status->CardState |= CS_EVENT_PM_SUSPEND;
+	if (!(s->state & SOCKET_PRESENT))
+		return CS_NO_CARD;
+
+	c = (s->config != NULL) ? &s->config[function] : NULL;
+	if ((c != NULL) && (c->state & CONFIG_LOCKED) &&
+	    (c->IntType & (INT_MEMORY_AND_IO | INT_ZOOMED_VIDEO))) {
+		u_char reg;
+		if (c->Present & PRESENT_PIN_REPLACE) {
+			pcmcia_read_cis_mem(s, 1, (c->ConfigBase+CISREG_PRR)>>1, 1, &reg);
+			status->CardState |=
+				(reg & PRR_WP_STATUS) ? CS_EVENT_WRITE_PROTECT : 0;
+			status->CardState |=
+				(reg & PRR_READY_STATUS) ? CS_EVENT_READY_CHANGE : 0;
+			status->CardState |=
+				(reg & PRR_BVD2_STATUS) ? CS_EVENT_BATTERY_LOW : 0;
+			status->CardState |=
+				(reg & PRR_BVD1_STATUS) ? CS_EVENT_BATTERY_DEAD : 0;
+		} else {
+			/* No PRR?  Then assume we're always ready */
+			status->CardState |= CS_EVENT_READY_CHANGE;
+		}
+		if (c->Present & PRESENT_EXT_STATUS) {
+			pcmcia_read_cis_mem(s, 1, (c->ConfigBase+CISREG_ESR)>>1, 1, &reg);
+			status->CardState |=
+				(reg & ESR_REQ_ATTN) ? CS_EVENT_REQUEST_ATTENTION : 0;
+		}
+		return CS_SUCCESS;
+	}
+	status->CardState |=
+		(val & SS_WRPROT) ? CS_EVENT_WRITE_PROTECT : 0;
+	status->CardState |=
+		(val & SS_BATDEAD) ? CS_EVENT_BATTERY_DEAD : 0;
+	status->CardState |=
+		(val & SS_BATWARN) ? CS_EVENT_BATTERY_LOW : 0;
+	status->CardState |=
+		(val & SS_READY) ? CS_EVENT_READY_CHANGE : 0;
+	return CS_SUCCESS;
+} /* pccard_get_status */
+
+int pcmcia_get_status(client_handle_t handle, cs_status_t *status)
+{
+	struct pcmcia_socket *s;
+	s = SOCKET(handle);
+	return pccard_get_status(s, handle->func, status);
+}
+EXPORT_SYMBOL(pcmcia_get_status);
+
+
+
+/** pcmcia_get_mem_page
+ *
+ * Change the card address of an already open memory window.
+ */
+int pcmcia_get_mem_page(window_handle_t win, memreq_t *req)
+{
+	if ((win == NULL) || (win->magic != WINDOW_MAGIC))
+		return CS_BAD_HANDLE;
+	req->Page = 0;
+	req->CardOffset = win->ctl.card_start;
+	return CS_SUCCESS;
+} /* pcmcia_get_mem_page */
+EXPORT_SYMBOL(pcmcia_get_mem_page);
+
+
+int pcmcia_map_mem_page(window_handle_t win, memreq_t *req)
+{
+	struct pcmcia_socket *s;
+	if ((win == NULL) || (win->magic != WINDOW_MAGIC))
+		return CS_BAD_HANDLE;
+	if (req->Page != 0)
+		return CS_BAD_PAGE;
+	s = win->sock;
+	win->ctl.card_start = req->CardOffset;
+	if (s->ops->set_mem_map(s, &win->ctl) != 0)
+		return CS_BAD_OFFSET;
+	return CS_SUCCESS;
+} /* pcmcia_map_mem_page */
+EXPORT_SYMBOL(pcmcia_map_mem_page);
+
+
+/** pcmcia_modify_configuration
+ *
+ * Modify a locked socket configuration
+ */
+int pcmcia_modify_configuration(struct pcmcia_device *p_dev,
+				modconf_t *mod)
+{
+	struct pcmcia_socket *s;
+	config_t *c;
+
+	s = p_dev->socket;
+	c = CONFIG(p_dev);
+	if (!(s->state & SOCKET_PRESENT))
+		return CS_NO_CARD;
+	if (!(c->state & CONFIG_LOCKED))
+		return CS_CONFIGURATION_LOCKED;
+
+	if (mod->Attributes & CONF_IRQ_CHANGE_VALID) {
+		if (mod->Attributes & CONF_ENABLE_IRQ) {
+			c->Attributes |= CONF_ENABLE_IRQ;
+			s->socket.io_irq = s->irq.AssignedIRQ;
+		} else {
+			c->Attributes &= ~CONF_ENABLE_IRQ;
+			s->socket.io_irq = 0;
+		}
+		s->ops->set_socket(s, &s->socket);
+	}
+
+	if (mod->Attributes & CONF_VCC_CHANGE_VALID)
+		return CS_BAD_VCC;
+
+	/* We only allow changing Vpp1 and Vpp2 to the same value */
+	if ((mod->Attributes & CONF_VPP1_CHANGE_VALID) &&
+	    (mod->Attributes & CONF_VPP2_CHANGE_VALID)) {
+		if (mod->Vpp1 != mod->Vpp2)
+			return CS_BAD_VPP;
+		c->Vpp1 = c->Vpp2 = s->socket.Vpp = mod->Vpp1;
+		if (s->ops->set_socket(s, &s->socket))
+			return CS_BAD_VPP;
+	} else if ((mod->Attributes & CONF_VPP1_CHANGE_VALID) ||
+		   (mod->Attributes & CONF_VPP2_CHANGE_VALID))
+		return CS_BAD_VPP;
+
+	return CS_SUCCESS;
+} /* modify_configuration */
+EXPORT_SYMBOL(pcmcia_modify_configuration);
+
+
+int pcmcia_release_configuration(struct pcmcia_device *p_dev)
+{
+	pccard_io_map io = { 0, 0, 0, 0, 1 };
+	struct pcmcia_socket *s = p_dev->socket;
+	int i;
+
+	if (!(p_dev->state & CLIENT_CONFIG_LOCKED))
+		return CS_BAD_HANDLE;
+	p_dev->state &= ~CLIENT_CONFIG_LOCKED;
+
+	if (!(p_dev->state & CLIENT_STALE)) {
+		config_t *c = CONFIG(p_dev);
+		if (--(s->lock_count) == 0) {
+			s->socket.flags = SS_OUTPUT_ENA;   /* Is this correct? */
+			s->socket.Vpp = 0;
+			s->socket.io_irq = 0;
+			s->ops->set_socket(s, &s->socket);
+		}
+		if (c->state & CONFIG_IO_REQ)
+			for (i = 0; i < MAX_IO_WIN; i++) {
+				if (s->io[i].NumPorts == 0)
+					continue;
+				s->io[i].Config--;
+				if (s->io[i].Config != 0)
+					continue;
+				io.map = i;
+				s->ops->set_io_map(s, &io);
+			}
+		c->state &= ~CONFIG_LOCKED;
+	}
+
+	return CS_SUCCESS;
+} /* pcmcia_release_configuration */
+EXPORT_SYMBOL(pcmcia_release_configuration);
+
+
+/** pcmcia_release_io
+ *
+ * Release_io() releases the I/O ranges allocated by a client.  This
+ * may be invoked some time after a card ejection has already dumped
+ * the actual socket configuration, so if the client is "stale", we
+ * don't bother checking the port ranges against the current socket
+ * values.
+ */
+int pcmcia_release_io(struct pcmcia_device *p_dev, io_req_t *req)
+{
+	struct pcmcia_socket *s = p_dev->socket;
+
+	if (!(p_dev->state & CLIENT_IO_REQ))
+		return CS_BAD_HANDLE;
+	p_dev->state &= ~CLIENT_IO_REQ;
+
+	if (!(p_dev->state & CLIENT_STALE)) {
+		config_t *c = CONFIG(p_dev);
+		if (c->state & CONFIG_LOCKED)
+			return CS_CONFIGURATION_LOCKED;
+		if ((c->io.BasePort1 != req->BasePort1) ||
+		    (c->io.NumPorts1 != req->NumPorts1) ||
+		    (c->io.BasePort2 != req->BasePort2) ||
+		    (c->io.NumPorts2 != req->NumPorts2))
+			return CS_BAD_ARGS;
+		c->state &= ~CONFIG_IO_REQ;
+	}
+
+	release_io_space(s, req->BasePort1, req->NumPorts1);
+	if (req->NumPorts2)
+		release_io_space(s, req->BasePort2, req->NumPorts2);
+
+	return CS_SUCCESS;
+} /* pcmcia_release_io */
+EXPORT_SYMBOL(pcmcia_release_io);
+
+
+int pcmcia_release_irq(struct pcmcia_device *p_dev, irq_req_t *req)
+{
+	struct pcmcia_socket *s = p_dev->socket;
+	if (!(p_dev->state & CLIENT_IRQ_REQ))
+		return CS_BAD_HANDLE;
+	p_dev->state &= ~CLIENT_IRQ_REQ;
+
+	if (!(p_dev->state & CLIENT_STALE)) {
+		config_t *c = CONFIG(p_dev);
+		if (c->state & CONFIG_LOCKED)
+			return CS_CONFIGURATION_LOCKED;
+		if (c->irq.Attributes != req->Attributes)
+			return CS_BAD_ATTRIBUTE;
+		if (s->irq.AssignedIRQ != req->AssignedIRQ)
+			return CS_BAD_IRQ;
+		if (--s->irq.Config == 0) {
+			c->state &= ~CONFIG_IRQ_REQ;
+			s->irq.AssignedIRQ = 0;
+		}
+	}
+
+	if (req->Attributes & IRQ_HANDLE_PRESENT) {
+		free_irq(req->AssignedIRQ, req->Instance);
+	}
+
+#ifdef CONFIG_PCMCIA_PROBE
+	pcmcia_used_irq[req->AssignedIRQ]--;
+#endif
+
+	return CS_SUCCESS;
+} /* pcmcia_release_irq */
+EXPORT_SYMBOL(pcmcia_release_irq);
+
+
+int pcmcia_release_window(window_handle_t win)
+{
+	struct pcmcia_socket *s;
+
+	if ((win == NULL) || (win->magic != WINDOW_MAGIC))
+		return CS_BAD_HANDLE;
+	s = win->sock;
+	if (!(win->handle->state & CLIENT_WIN_REQ(win->index)))
+		return CS_BAD_HANDLE;
+
+	/* Shut down memory window */
+	win->ctl.flags &= ~MAP_ACTIVE;
+	s->ops->set_mem_map(s, &win->ctl);
+	s->state &= ~SOCKET_WIN_REQ(win->index);
+
+	/* Release system memory */
+	if (win->ctl.res) {
+		release_resource(win->ctl.res);
+		kfree(win->ctl.res);
+		win->ctl.res = NULL;
+	}
+	win->handle->state &= ~CLIENT_WIN_REQ(win->index);
+
+	win->magic = 0;
+
+	return CS_SUCCESS;
+} /* pcmcia_release_window */
+EXPORT_SYMBOL(pcmcia_release_window);
+
+
+int pcmcia_request_configuration(struct pcmcia_device *p_dev,
+				 config_req_t *req)
+{
+	int i;
+	u_int base;
+	struct pcmcia_socket *s = p_dev->socket;
+	config_t *c;
+	pccard_io_map iomap;
+
+	if (!(s->state & SOCKET_PRESENT))
+		return CS_NO_CARD;
+
+	if (req->IntType & INT_CARDBUS)
+		return CS_UNSUPPORTED_MODE;
+	c = CONFIG(p_dev);
+	if (c->state & CONFIG_LOCKED)
+		return CS_CONFIGURATION_LOCKED;
+
+	/* Do power control.  We don't allow changes in Vcc. */
+	if (s->socket.Vcc != req->Vcc)
+		return CS_BAD_VCC;
+	if (req->Vpp1 != req->Vpp2)
+		return CS_BAD_VPP;
+	s->socket.Vpp = req->Vpp1;
+	if (s->ops->set_socket(s, &s->socket))
+		return CS_BAD_VPP;
+
+	c->Vcc = req->Vcc; c->Vpp1 = c->Vpp2 = req->Vpp1;
+
+	/* Pick memory or I/O card, DMA mode, interrupt */
+	c->IntType = req->IntType;
+	c->Attributes = req->Attributes;
+	if (req->IntType & INT_MEMORY_AND_IO)
+		s->socket.flags |= SS_IOCARD;
+	if (req->IntType & INT_ZOOMED_VIDEO)
+		s->socket.flags |= SS_ZVCARD | SS_IOCARD;
+	if (req->Attributes & CONF_ENABLE_DMA)
+		s->socket.flags |= SS_DMA_MODE;
+	if (req->Attributes & CONF_ENABLE_SPKR)
+		s->socket.flags |= SS_SPKR_ENA;
+	if (req->Attributes & CONF_ENABLE_IRQ)
+		s->socket.io_irq = s->irq.AssignedIRQ;
+	else
+		s->socket.io_irq = 0;
+	s->ops->set_socket(s, &s->socket);
+	s->lock_count++;
+
+	/* Set up CIS configuration registers */
+	base = c->ConfigBase = req->ConfigBase;
+	c->Present = c->CardValues = req->Present;
+	if (req->Present & PRESENT_COPY) {
+		c->Copy = req->Copy;
+		pcmcia_write_cis_mem(s, 1, (base + CISREG_SCR)>>1, 1, &c->Copy);
+	}
+	if (req->Present & PRESENT_OPTION) {
+		if (s->functions == 1) {
+			c->Option = req->ConfigIndex & COR_CONFIG_MASK;
+		} else {
+			c->Option = req->ConfigIndex & COR_MFC_CONFIG_MASK;
+			c->Option |= COR_FUNC_ENA|COR_IREQ_ENA;
+			if (req->Present & PRESENT_IOBASE_0)
+				c->Option |= COR_ADDR_DECODE;
+		}
+		if (c->state & CONFIG_IRQ_REQ)
+			if (!(c->irq.Attributes & IRQ_FORCED_PULSE))
+				c->Option |= COR_LEVEL_REQ;
+		pcmcia_write_cis_mem(s, 1, (base + CISREG_COR)>>1, 1, &c->Option);
+		mdelay(40);
+	}
+	if (req->Present & PRESENT_STATUS) {
+		c->Status = req->Status;
+		pcmcia_write_cis_mem(s, 1, (base + CISREG_CCSR)>>1, 1, &c->Status);
+	}
+	if (req->Present & PRESENT_PIN_REPLACE) {
+		c->Pin = req->Pin;
+		pcmcia_write_cis_mem(s, 1, (base + CISREG_PRR)>>1, 1, &c->Pin);
+	}
+	if (req->Present & PRESENT_EXT_STATUS) {
+		c->ExtStatus = req->ExtStatus;
+		pcmcia_write_cis_mem(s, 1, (base + CISREG_ESR)>>1, 1, &c->ExtStatus);
+	}
+	if (req->Present & PRESENT_IOBASE_0) {
+		u_char b = c->io.BasePort1 & 0xff;
+		pcmcia_write_cis_mem(s, 1, (base + CISREG_IOBASE_0)>>1, 1, &b);
+		b = (c->io.BasePort1 >> 8) & 0xff;
+		pcmcia_write_cis_mem(s, 1, (base + CISREG_IOBASE_1)>>1, 1, &b);
+	}
+	if (req->Present & PRESENT_IOSIZE) {
+		u_char b = c->io.NumPorts1 + c->io.NumPorts2 - 1;
+		pcmcia_write_cis_mem(s, 1, (base + CISREG_IOSIZE)>>1, 1, &b);
+	}
+
+	/* Configure I/O windows */
+	if (c->state & CONFIG_IO_REQ) {
+		iomap.speed = io_speed;
+		for (i = 0; i < MAX_IO_WIN; i++)
+			if (s->io[i].NumPorts != 0) {
+				iomap.map = i;
+				iomap.flags = MAP_ACTIVE;
+				switch (s->io[i].Attributes & IO_DATA_PATH_WIDTH) {
+				case IO_DATA_PATH_WIDTH_16:
+					iomap.flags |= MAP_16BIT; break;
+				case IO_DATA_PATH_WIDTH_AUTO:
+					iomap.flags |= MAP_AUTOSZ; break;
+				default:
+					break;
+				}
+				iomap.start = s->io[i].BasePort;
+				iomap.stop = iomap.start + s->io[i].NumPorts - 1;
+				s->ops->set_io_map(s, &iomap);
+				s->io[i].Config++;
+			}
+	}
+
+	c->state |= CONFIG_LOCKED;
+	p_dev->state |= CLIENT_CONFIG_LOCKED;
+	return CS_SUCCESS;
+} /* pcmcia_request_configuration */
+EXPORT_SYMBOL(pcmcia_request_configuration);
+
+
+/** pcmcia_request_io
+ *
+ * Request_io() reserves ranges of port addresses for a socket.
+ * I have not implemented range sharing or alias addressing.
+ */
+int pcmcia_request_io(struct pcmcia_device *p_dev, io_req_t *req)
+{
+	struct pcmcia_socket *s = p_dev->socket;
+	config_t *c;
+
+	if (!(s->state & SOCKET_PRESENT))
+		return CS_NO_CARD;
+
+	if (!req)
+		return CS_UNSUPPORTED_MODE;
+	c = CONFIG(p_dev);
+	if (c->state & CONFIG_LOCKED)
+		return CS_CONFIGURATION_LOCKED;
+	if (c->state & CONFIG_IO_REQ)
+		return CS_IN_USE;
+	if (req->Attributes1 & (IO_SHARED | IO_FORCE_ALIAS_ACCESS))
+		return CS_BAD_ATTRIBUTE;
+	if ((req->NumPorts2 > 0) &&
+	    (req->Attributes2 & (IO_SHARED | IO_FORCE_ALIAS_ACCESS)))
+		return CS_BAD_ATTRIBUTE;
+
+	if (alloc_io_space(s, req->Attributes1, &req->BasePort1,
+			   req->NumPorts1, req->IOAddrLines))
+		return CS_IN_USE;
+
+	if (req->NumPorts2) {
+		if (alloc_io_space(s, req->Attributes2, &req->BasePort2,
+				   req->NumPorts2, req->IOAddrLines)) {
+			release_io_space(s, req->BasePort1, req->NumPorts1);
+			return CS_IN_USE;
+		}
+	}
+
+	c->io = *req;
+	c->state |= CONFIG_IO_REQ;
+	p_dev->state |= CLIENT_IO_REQ;
+	return CS_SUCCESS;
+} /* pcmcia_request_io */
+EXPORT_SYMBOL(pcmcia_request_io);
+
+
+/** pcmcia_request_irq
+ *
+ * Request_irq() reserves an irq for this client.
+ *
+ * Also, since Linux only reserves irq's when they are actually
+ * hooked, we don't guarantee that an irq will still be available
+ * when the configuration is locked.  Now that I think about it,
+ * there might be a way to fix this using a dummy handler.
+ */
+
+#ifdef CONFIG_PCMCIA_PROBE
+static irqreturn_t test_action(int cpl, void *dev_id, struct pt_regs *regs)
+{
+	return IRQ_NONE;
+}
+#endif
+
+int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req)
+{
+	struct pcmcia_socket *s = p_dev->socket;
+	config_t *c;
+	int ret = CS_IN_USE, irq = 0;
+
+	if (!(s->state & SOCKET_PRESENT))
+		return CS_NO_CARD;
+	c = CONFIG(p_dev);
+	if (c->state & CONFIG_LOCKED)
+		return CS_CONFIGURATION_LOCKED;
+	if (c->state & CONFIG_IRQ_REQ)
+		return CS_IN_USE;
+
+#ifdef CONFIG_PCMCIA_PROBE
+	if (s->irq.AssignedIRQ != 0) {
+		/* If the interrupt is already assigned, it must be the same */
+		irq = s->irq.AssignedIRQ;
+	} else {
+		int try;
+		u32 mask = s->irq_mask;
+		void *data = &p_dev->dev.driver; /* something unique to this device */
+
+		for (try = 0; try < 64; try++) {
+			irq = try % 32;
+
+			/* marked as available by driver, and not blocked by userspace? */
+			if (!((mask >> irq) & 1))
+				continue;
+
+			/* avoid an IRQ which is already used by a PCMCIA card */
+			if ((try < 32) && pcmcia_used_irq[irq])
+				continue;
+
+			/* register the correct driver, if possible, of check whether
+			 * registering a dummy handle works, i.e. if the IRQ isn't
+			 * marked as used by the kernel resource management core */
+			ret = request_irq(irq,
+					  (req->Attributes & IRQ_HANDLE_PRESENT) ? req->Handler : test_action,
+					  ((req->Attributes & IRQ_TYPE_DYNAMIC_SHARING) ||
+					   (s->functions > 1) ||
+					   (irq == s->pci_irq)) ? SA_SHIRQ : 0,
+					  p_dev->dev.bus_id,
+					  (req->Attributes & IRQ_HANDLE_PRESENT) ? req->Instance : data);
+			if (!ret) {
+				if (!(req->Attributes & IRQ_HANDLE_PRESENT))
+					free_irq(irq, data);
+				break;
+			}
+		}
+	}
+#endif
+	if (ret) {
+		if (!s->pci_irq)
+			return ret;
+		irq = s->pci_irq;
+	}
+
+	if (ret && req->Attributes & IRQ_HANDLE_PRESENT) {
+		if (request_irq(irq, req->Handler,
+				((req->Attributes & IRQ_TYPE_DYNAMIC_SHARING) ||
+				 (s->functions > 1) ||
+				 (irq == s->pci_irq)) ? SA_SHIRQ : 0,
+				p_dev->dev.bus_id, req->Instance))
+			return CS_IN_USE;
+	}
+
+	c->irq.Attributes = req->Attributes;
+	s->irq.AssignedIRQ = req->AssignedIRQ = irq;
+	s->irq.Config++;
+
+	c->state |= CONFIG_IRQ_REQ;
+	p_dev->state |= CLIENT_IRQ_REQ;
+
+#ifdef CONFIG_PCMCIA_PROBE
+	pcmcia_used_irq[irq]++;
+#endif
+
+	return CS_SUCCESS;
+} /* pcmcia_request_irq */
+EXPORT_SYMBOL(pcmcia_request_irq);
+
+
+/** pcmcia_request_window
+ *
+ * Request_window() establishes a mapping between card memory space
+ * and system memory space.
+ */
+int pcmcia_request_window(struct pcmcia_device **p_dev, win_req_t *req, window_handle_t *wh)
+{
+	struct pcmcia_socket *s = (*p_dev)->socket;
+	window_t *win;
+	u_long align;
+	int w;
+
+	if (!(s->state & SOCKET_PRESENT))
+		return CS_NO_CARD;
+	if (req->Attributes & (WIN_PAGED | WIN_SHARED))
+		return CS_BAD_ATTRIBUTE;
+
+	/* Window size defaults to smallest available */
+	if (req->Size == 0)
+		req->Size = s->map_size;
+	align = (((s->features & SS_CAP_MEM_ALIGN) ||
+		  (req->Attributes & WIN_STRICT_ALIGN)) ?
+		 req->Size : s->map_size);
+	if (req->Size & (s->map_size-1))
+		return CS_BAD_SIZE;
+	if ((req->Base && (s->features & SS_CAP_STATIC_MAP)) ||
+	    (req->Base & (align-1)))
+		return CS_BAD_BASE;
+	if (req->Base)
+		align = 0;
+
+	/* Allocate system memory window */
+	for (w = 0; w < MAX_WIN; w++)
+		if (!(s->state & SOCKET_WIN_REQ(w))) break;
+	if (w == MAX_WIN)
+		return CS_OUT_OF_RESOURCE;
+
+	win = &s->win[w];
+	win->magic = WINDOW_MAGIC;
+	win->index = w;
+	win->handle = *p_dev;
+	win->sock = s;
+
+	if (!(s->features & SS_CAP_STATIC_MAP)) {
+		win->ctl.res = pcmcia_find_mem_region(req->Base, req->Size, align,
+						      (req->Attributes & WIN_MAP_BELOW_1MB), s);
+		if (!win->ctl.res)
+			return CS_IN_USE;
+	}
+	(*p_dev)->state |= CLIENT_WIN_REQ(w);
+
+	/* Configure the socket controller */
+	win->ctl.map = w+1;
+	win->ctl.flags = 0;
+	win->ctl.speed = req->AccessSpeed;
+	if (req->Attributes & WIN_MEMORY_TYPE)
+		win->ctl.flags |= MAP_ATTRIB;
+	if (req->Attributes & WIN_ENABLE)
+		win->ctl.flags |= MAP_ACTIVE;
+	if (req->Attributes & WIN_DATA_WIDTH_16)
+		win->ctl.flags |= MAP_16BIT;
+	if (req->Attributes & WIN_USE_WAIT)
+		win->ctl.flags |= MAP_USE_WAIT;
+	win->ctl.card_start = 0;
+	if (s->ops->set_mem_map(s, &win->ctl) != 0)
+		return CS_BAD_ARGS;
+	s->state |= SOCKET_WIN_REQ(w);
+
+	/* Return window handle */
+	if (s->features & SS_CAP_STATIC_MAP) {
+		req->Base = win->ctl.static_start;
+	} else {
+		req->Base = win->ctl.res->start;
+	}
+	*wh = win;
+
+	return CS_SUCCESS;
+} /* pcmcia_request_window */
+EXPORT_SYMBOL(pcmcia_request_window);
diff --git a/drivers/pcmcia/rsrc_mgr.c b/drivers/pcmcia/rsrc_mgr.c
--- a/drivers/pcmcia/rsrc_mgr.c
+++ b/drivers/pcmcia/rsrc_mgr.c
@@ -72,7 +72,7 @@ int pcmcia_adjust_resource_info(adjust_t
 			/* you can't use the old interface if the new
 			 * one was used before */
 			spin_lock_irqsave(&s->lock, flags);
-			if ((s->resource_setup_done) &&
+			if ((s->resource_setup_new) &&
 			    !(s->resource_setup_old)) {
 				spin_unlock_irqrestore(&s->lock, flags);
 				continue;
@@ -105,29 +105,32 @@ void pcmcia_validate_mem(struct pcmcia_s
 }
 EXPORT_SYMBOL(pcmcia_validate_mem);
 
-int adjust_io_region(struct resource *res, unsigned long r_start,
+int pcmcia_adjust_io_region(struct resource *res, unsigned long r_start,
 		     unsigned long r_end, struct pcmcia_socket *s)
 {
 	if (s->resource_ops->adjust_io_region)
 		return s->resource_ops->adjust_io_region(res, r_start, r_end, s);
 	return -ENOMEM;
 }
+EXPORT_SYMBOL(pcmcia_adjust_io_region);
 
-struct resource *find_io_region(unsigned long base, int num,
+struct resource *pcmcia_find_io_region(unsigned long base, int num,
 		   unsigned long align, struct pcmcia_socket *s)
 {
 	if (s->resource_ops->find_io)
 		return s->resource_ops->find_io(base, num, align, s);
 	return NULL;
 }
+EXPORT_SYMBOL(pcmcia_find_io_region);
 
-struct resource *find_mem_region(u_long base, u_long num, u_long align,
+struct resource *pcmcia_find_mem_region(u_long base, u_long num, u_long align,
 				 int low, struct pcmcia_socket *s)
 {
 	if (s->resource_ops->find_mem)
 		return s->resource_ops->find_mem(base, num, align, low, s);
 	return NULL;
 }
+EXPORT_SYMBOL(pcmcia_find_mem_region);
 
 void release_resource_db(struct pcmcia_socket *s)
 {
diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c
--- a/drivers/pcmcia/rsrc_nonstatic.c
+++ b/drivers/pcmcia/rsrc_nonstatic.c
@@ -372,6 +372,9 @@ static int do_mem_probe(u_long base, u_l
 	   base, base+num-1);
     bad = fail = 0;
     step = (num < 0x20000) ? 0x2000 : ((num>>4) & ~0x1fff);
+    /* don't allow too large steps */
+    if (step > 0x800000)
+	step = 0x800000;
     /* cis_readable wants to map 2x map_size */
     if (step < 2 * s->map_size)
 	step = 2 * s->map_size;
@@ -465,8 +468,7 @@ static void validate_mem(struct pcmcia_s
 
 	for (m = s_data->mem_db.next; m != &s_data->mem_db; m = mm.next) {
 		mm = *m;
-		if (do_mem_probe(mm.base, mm.num, s))
-			break;
+		do_mem_probe(mm.base, mm.num, s);
 	}
 }
 
@@ -601,7 +603,7 @@ static int nonstatic_adjust_io_region(st
 
 ======================================================================*/
 
-struct resource *nonstatic_find_io_region(unsigned long base, int num,
+static struct resource *nonstatic_find_io_region(unsigned long base, int num,
 		   unsigned long align, struct pcmcia_socket *s)
 {
 	struct resource *res = make_resource(0, num, IORESOURCE_IO, s->dev.class_id);
@@ -635,8 +637,8 @@ struct resource *nonstatic_find_io_regio
 	return res;
 }
 
-struct resource * nonstatic_find_mem_region(u_long base, u_long num, u_long align,
-				 int low, struct pcmcia_socket *s)
+static struct resource * nonstatic_find_mem_region(u_long base, u_long num,
+		u_long align, int low, struct pcmcia_socket *s)
 {
 	struct resource *res = make_resource(0, num, IORESOURCE_MEM, s->dev.class_id);
 	struct socket_data *s_data = s->resource_data;
@@ -683,27 +685,23 @@ struct resource * nonstatic_find_mem_reg
 }
 
 
-static int adjust_memory(struct pcmcia_socket *s, adjust_t *adj)
+static int adjust_memory(struct pcmcia_socket *s, unsigned int action, unsigned long start, unsigned long end)
 {
-	u_long base, num;
 	struct socket_data *data = s->resource_data;
-	int ret;
-
-	base = adj->resource.memory.Base;
-	num = adj->resource.memory.Size;
-	if ((num == 0) || (base+num-1 < base))
-		return CS_BAD_SIZE;
+	unsigned long size = end - start + 1;
+	int ret = 0;
 
-	ret = CS_SUCCESS;
+	if (end <= start)
+		return -EINVAL;
 
 	down(&rsrc_sem);
-	switch (adj->Action) {
+	switch (action) {
 	case ADD_MANAGED_RESOURCE:
-		ret = add_interval(&data->mem_db, base, num);
+		ret = add_interval(&data->mem_db, start, size);
 		break;
 	case REMOVE_MANAGED_RESOURCE:
-		ret = sub_interval(&data->mem_db, base, num);
-		if (ret == CS_SUCCESS) {
+		ret = sub_interval(&data->mem_db, start, size);
+		if (!ret) {
 			struct pcmcia_socket *socket;
 			down_read(&pcmcia_socket_list_rwsem);
 			list_for_each_entry(socket, &pcmcia_socket_list, socket_list)
@@ -712,7 +710,7 @@ static int adjust_memory(struct pcmcia_s
 		}
 		break;
 	default:
-		ret = CS_UNSUPPORTED_FUNCTION;
+		ret = -EINVAL;
 	}
 	up(&rsrc_sem);
 
@@ -720,36 +718,35 @@ static int adjust_memory(struct pcmcia_s
 }
 
 
-static int adjust_io(struct pcmcia_socket *s, adjust_t *adj)
+static int adjust_io(struct pcmcia_socket *s, unsigned int action, unsigned long start, unsigned long end)
 {
 	struct socket_data *data = s->resource_data;
-	kio_addr_t base, num;
-	int ret = CS_SUCCESS;
+	unsigned long size = end - start + 1;
+	int ret = 0;
 
-	base = adj->resource.io.BasePort;
-	num = adj->resource.io.NumPorts;
-	if ((base < 0) || (base > 0xffff))
-		return CS_BAD_BASE;
-	if ((num <= 0) || (base+num > 0x10000) || (base+num <= base))
-		return CS_BAD_SIZE;
+	if (end <= start)
+		return -EINVAL;
+
+	if (end > IO_SPACE_LIMIT)
+		return -EINVAL;
 
 	down(&rsrc_sem);
-	switch (adj->Action) {
+	switch (action) {
 	case ADD_MANAGED_RESOURCE:
-		if (add_interval(&data->io_db, base, num) != 0) {
-			ret = CS_IN_USE;
+		if (add_interval(&data->io_db, start, size) != 0) {
+			ret = -EBUSY;
 			break;
 		}
 #ifdef CONFIG_PCMCIA_PROBE
 		if (probe_io)
-			do_io_probe(s, base, num);
+			do_io_probe(s, start, size);
 #endif
 		break;
 	case REMOVE_MANAGED_RESOURCE:
-		sub_interval(&data->io_db, base, num);
+		sub_interval(&data->io_db, start, size);
 		break;
 	default:
-		ret = CS_UNSUPPORTED_FUNCTION;
+		ret = -EINVAL;
 		break;
 	}
 	up(&rsrc_sem);
@@ -760,15 +757,82 @@ static int adjust_io(struct pcmcia_socke
 
 static int nonstatic_adjust_resource_info(struct pcmcia_socket *s, adjust_t *adj)
 {
+	unsigned long end;
+
 	switch (adj->Resource) {
 	case RES_MEMORY_RANGE:
-		return adjust_memory(s, adj);
+		end = adj->resource.memory.Base + adj->resource.memory.Size - 1;
+		return adjust_memory(s, adj->Action, adj->resource.memory.Base, end);
 	case RES_IO_RANGE:
-		return adjust_io(s, adj);
+		end = adj->resource.io.BasePort + adj->resource.io.NumPorts - 1;
+		return adjust_io(s, adj->Action, adj->resource.io.BasePort, end);
 	}
 	return CS_UNSUPPORTED_FUNCTION;
 }
 
+#ifdef CONFIG_PCI
+static int nonstatic_autoadd_resources(struct pcmcia_socket *s)
+{
+	struct resource *res;
+	int i, done = 0;
+
+	if (!s->cb_dev || !s->cb_dev->bus)
+		return -ENODEV;
+
+#if defined(CONFIG_X86) || defined(CONFIG_X86_64)
+	/* If this is the root bus, the risk of hitting
+	 * some strange system devices which aren't protected
+	 * by either ACPI resource tables or properly requested
+	 * resources is too big. Therefore, don't do auto-adding
+	 * of resources at the moment.
+	 */
+	if (s->cb_dev->bus->number == 0)
+		return -EINVAL;
+#endif
+
+	for (i=0; i < PCI_BUS_NUM_RESOURCES; i++) {
+		res = s->cb_dev->bus->resource[i];
+		if (!res)
+			continue;
+
+		if (res->flags & IORESOURCE_IO) {
+			if (res == &ioport_resource)
+				continue;
+			printk(KERN_INFO "pcmcia: parent PCI bridge I/O window: 0x%lx - 0x%lx\n",
+			       res->start, res->end);
+			if (!adjust_io(s, ADD_MANAGED_RESOURCE, res->start, res->end))
+				done |= IORESOURCE_IO;
+
+		}
+
+		if (res->flags & IORESOURCE_MEM) {
+			if (res == &iomem_resource)
+				continue;
+			printk(KERN_INFO "pcmcia: parent PCI bridge Memory window: 0x%lx - 0x%lx\n",
+			       res->start, res->end);
+			if (!adjust_memory(s, ADD_MANAGED_RESOURCE, res->start, res->end))
+				done |= IORESOURCE_MEM;
+		}
+	}
+
+	/* if we got at least one of IO, and one of MEM, we can be glad and
+	 * activate the PCMCIA subsystem */
+	if (done & (IORESOURCE_MEM | IORESOURCE_IO))
+		s->resource_setup_done = 1;
+
+	return 0;
+}
+
+#else
+
+static inline int nonstatic_autoadd_resources(struct pcmcia_socket *s)
+{
+	return -ENODEV;
+}
+
+#endif
+
+
 static int nonstatic_init(struct pcmcia_socket *s)
 {
 	struct socket_data *data;
@@ -783,6 +847,8 @@ static int nonstatic_init(struct pcmcia_
 
 	s->resource_data = (void *) data;
 
+	nonstatic_autoadd_resources(s);
+
 	return 0;
 }
 
@@ -845,17 +911,16 @@ static ssize_t store_io_db(struct class_
 {
 	struct pcmcia_socket *s = class_get_devdata(class_dev);
 	unsigned long start_addr, end_addr;
-	unsigned int add = 1;
-	adjust_t adj;
+	unsigned int add = ADD_MANAGED_RESOURCE;
 	ssize_t ret = 0;
 
 	ret = sscanf (buf, "+ 0x%lx - 0x%lx", &start_addr, &end_addr);
 	if (ret != 2) {
 		ret = sscanf (buf, "- 0x%lx - 0x%lx", &start_addr, &end_addr);
-		add = 0;
+		add = REMOVE_MANAGED_RESOURCE;
 		if (ret != 2) {
 			ret = sscanf (buf, "0x%lx - 0x%lx", &start_addr, &end_addr);
-			add = 1;
+			add = ADD_MANAGED_RESOURCE;
 			if (ret != 2)
 				return -EINVAL;
 		}
@@ -863,12 +928,9 @@ static ssize_t store_io_db(struct class_
 	if (end_addr <= start_addr)
 		return -EINVAL;
 
-	adj.Action = add ? ADD_MANAGED_RESOURCE : REMOVE_MANAGED_RESOURCE;
-	adj.Resource = RES_IO_RANGE;
-	adj.resource.io.BasePort = start_addr;
-	adj.resource.io.NumPorts = end_addr - start_addr + 1;
-
-	ret = adjust_io(s, &adj);
+	ret = adjust_io(s, add, start_addr, end_addr);
+	if (!ret)
+		s->resource_setup_new = 1;
 
 	return ret ? ret : count;
 }
@@ -901,17 +963,16 @@ static ssize_t store_mem_db(struct class
 {
 	struct pcmcia_socket *s = class_get_devdata(class_dev);
 	unsigned long start_addr, end_addr;
-	unsigned int add = 1;
-	adjust_t adj;
+	unsigned int add = ADD_MANAGED_RESOURCE;
 	ssize_t ret = 0;
 
 	ret = sscanf (buf, "+ 0x%lx - 0x%lx", &start_addr, &end_addr);
 	if (ret != 2) {
 		ret = sscanf (buf, "- 0x%lx - 0x%lx", &start_addr, &end_addr);
-		add = 0;
+		add = REMOVE_MANAGED_RESOURCE;
 		if (ret != 2) {
 			ret = sscanf (buf, "0x%lx - 0x%lx", &start_addr, &end_addr);
-			add = 1;
+			add = ADD_MANAGED_RESOURCE;
 			if (ret != 2)
 				return -EINVAL;
 		}
@@ -919,12 +980,9 @@ static ssize_t store_mem_db(struct class
 	if (end_addr <= start_addr)
 		return -EINVAL;
 
-	adj.Action = add ? ADD_MANAGED_RESOURCE : REMOVE_MANAGED_RESOURCE;
-	adj.Resource = RES_MEMORY_RANGE;
-	adj.resource.memory.Base = start_addr;
-	adj.resource.memory.Size = end_addr - start_addr + 1;
-
-	ret = adjust_memory(s, &adj);
+	ret = adjust_memory(s, add, start_addr, end_addr);
+	if (!ret)
+		s->resource_setup_new = 1;
 
 	return ret ? ret : count;
 }
diff --git a/drivers/pcmcia/sa1100_generic.c b/drivers/pcmcia/sa1100_generic.c
--- a/drivers/pcmcia/sa1100_generic.c
+++ b/drivers/pcmcia/sa1100_generic.c
@@ -34,7 +34,6 @@
 #include <linux/init.h>
 #include <linux/config.h>
 
-#include <pcmcia/version.h>
 #include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/ss.h>
diff --git a/drivers/pcmcia/sa1100_jornada720.c b/drivers/pcmcia/sa1100_jornada720.c
--- a/drivers/pcmcia/sa1100_jornada720.c
+++ b/drivers/pcmcia/sa1100_jornada720.c
@@ -30,20 +30,9 @@ static int jornada720_pcmcia_hw_init(str
    */
   GRER |= 0x00000002;
   /* Set GPIO_A<3:1> to be outputs for PCMCIA/CF power controller: */
-  PA_DDR = 0;
-  PA_DWR = 0;
-  PA_SDR = 0;
-  PA_SSR = 0;
-
-  PB_DDR = 0;
-  PB_DWR = 0x01;
-  PB_SDR = 0;
-  PB_SSR = 0;
-
-  PC_DDR = 0x88;
-  PC_DWR = 0x20;
-  PC_SDR = 0;
-  PC_SSR = 0;
+  sa1111_set_io_dir(SA1111_DEV(skt->dev), GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0, 0);
+  sa1111_set_io(SA1111_DEV(skt->dev), GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0);
+  sa1111_set_sleep_io(SA1111_DEV(skt->dev), GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0);
 
   return sa1111_pcmcia_hw_init(skt);
 }
@@ -95,7 +84,7 @@ printk("%s(): config socket %d vcc %d vp
     unsigned long flags;
 
     local_irq_save(flags);
-    PA_DWR = (PA_DWR & ~pa_dwr_mask) | pa_dwr_set;
+    sa1111_set_io(SA1111_DEV(skt->dev), pa_dwr_mask, pa_dwr_set);
     local_irq_restore(flags);
   }
 
diff --git a/drivers/pcmcia/soc_common.h b/drivers/pcmcia/soc_common.h
--- a/drivers/pcmcia/soc_common.h
+++ b/drivers/pcmcia/soc_common.h
@@ -11,7 +11,6 @@
 
 /* include the world */
 #include <linux/cpufreq.h>
-#include <pcmcia/version.h>
 #include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/ss.h>
diff --git a/drivers/pcmcia/socket_sysfs.c b/drivers/pcmcia/socket_sysfs.c
--- a/drivers/pcmcia/socket_sysfs.c
+++ b/drivers/pcmcia/socket_sysfs.c
@@ -29,7 +29,6 @@
 #include <asm/irq.h>
 
 #define IN_CARD_SERVICES
-#include <pcmcia/version.h>
 #include <pcmcia/cs_types.h>
 #include <pcmcia/ss.h>
 #include <pcmcia/cs.h>
@@ -163,28 +162,164 @@ static ssize_t pccard_store_resource(str
 		return -EINVAL;
 
 	spin_lock_irqsave(&s->lock, flags);
-	if (!s->resource_setup_done) {
+	if (!s->resource_setup_done)
 		s->resource_setup_done = 1;
-		spin_unlock_irqrestore(&s->lock, flags);
+	spin_unlock_irqrestore(&s->lock, flags);
+
+	down(&s->skt_sem);
+	if ((s->callback) &&
+	    (s->state & SOCKET_PRESENT) &&
+	    !(s->state & SOCKET_CARDBUS)) {
+		if (try_module_get(s->callback->owner)) {
+			s->callback->requery(s);
+			module_put(s->callback->owner);
+		}
+	}
+	up(&s->skt_sem);
+
+	return count;
+}
+static CLASS_DEVICE_ATTR(available_resources_setup_done, 0600, pccard_show_resource, pccard_store_resource);
+
+
+static ssize_t pccard_extract_cis(struct pcmcia_socket *s, char *buf, loff_t off, size_t count)
+{
+	tuple_t tuple;
+	int status, i;
+	loff_t pointer = 0;
+	ssize_t ret = 0;
+	u_char *tuplebuffer;
+	u_char *tempbuffer;
+
+	tuplebuffer = kmalloc(sizeof(u_char) * 256, GFP_KERNEL);
+	if (!tuplebuffer)
+		return -ENOMEM;
+
+	tempbuffer = kmalloc(sizeof(u_char) * 258, GFP_KERNEL);
+	if (!tempbuffer) {
+		ret = -ENOMEM;
+		goto free_tuple;
+	}
+
+	memset(&tuple, 0, sizeof(tuple_t));
+
+	tuple.Attributes = TUPLE_RETURN_LINK | TUPLE_RETURN_COMMON;
+	tuple.DesiredTuple = RETURN_FIRST_TUPLE;
+	tuple.TupleOffset = 0;
+
+	status = pccard_get_first_tuple(s, BIND_FN_ALL, &tuple);
+	while (!status) {
+		tuple.TupleData = tuplebuffer;
+		tuple.TupleDataMax = 255;
+		memset(tuplebuffer, 0, sizeof(u_char) * 255);
+
+		status = pccard_get_tuple_data(s, &tuple);
+		if (status)
+			break;
+
+		if (off < (pointer + 2 + tuple.TupleDataLen)) {
+			tempbuffer[0] = tuple.TupleCode & 0xff;
+			tempbuffer[1] = tuple.TupleLink & 0xff;
+			for (i = 0; i < tuple.TupleDataLen; i++)
+				tempbuffer[i + 2] = tuplebuffer[i] & 0xff;
+
+			for (i = 0; i < (2 + tuple.TupleDataLen); i++) {
+				if (((i + pointer) >= off) &&
+				    (i + pointer) < (off + count)) {
+					buf[ret] = tempbuffer[i];
+					ret++;
+				}
+			}
+		}
+
+		pointer += 2 + tuple.TupleDataLen;
+
+		if (pointer >= (off + count))
+			break;
+
+		if (tuple.TupleCode == CISTPL_END)
+			break;
+		status = pccard_get_next_tuple(s, BIND_FN_ALL, &tuple);
+	}
+
+	kfree(tempbuffer);
+ free_tuple:
+	kfree(tuplebuffer);
+
+	return (ret);
+}
+
+static ssize_t pccard_show_cis(struct kobject *kobj, char *buf, loff_t off, size_t count)
+{
+	unsigned int size = 0x200;
+
+	if (off >= size)
+		count = 0;
+	else {
+		struct pcmcia_socket *s;
+		cisinfo_t cisinfo;
+
+		if (off + count > size)
+			count = size - off;
+
+		s = to_socket(container_of(kobj, struct class_device, kobj));
+
+		if (!(s->state & SOCKET_PRESENT))
+			return -ENODEV;
+		if (pccard_validate_cis(s, BIND_FN_ALL, &cisinfo))
+			return -EIO;
+		if (!cisinfo.Chains)
+			return -ENODATA;
+
+		count = pccard_extract_cis(s, buf, off, count);
+	}
+
+	return (count);
+}
+
+static ssize_t pccard_store_cis(struct kobject *kobj, char *buf, loff_t off, size_t count)
+{
+	struct pcmcia_socket *s = to_socket(container_of(kobj, struct class_device, kobj));
+	cisdump_t *cis;
+	ssize_t ret = count;
+
+	if (off)
+		return -EINVAL;
+
+	if (count >= 0x200)
+		return -EINVAL;
 
+	if (!(s->state & SOCKET_PRESENT))
+		return -ENODEV;
+
+	cis = kmalloc(sizeof(cisdump_t), GFP_KERNEL);
+	if (!cis)
+		return -ENOMEM;
+	memset(cis, 0, sizeof(cisdump_t));
+
+	cis->Length = count + 1;
+	memcpy(cis->Data, buf, count);
+
+	if (pcmcia_replace_cis(s, cis))
+		ret  = -EIO;
+
+	kfree(cis);
+
+	if (!ret) {
 		down(&s->skt_sem);
-		if ((s->callback) &&
-		    (s->state & SOCKET_PRESENT) &&
+		if ((s->callback) && (s->state & SOCKET_PRESENT) &&
 		    !(s->state & SOCKET_CARDBUS)) {
 			if (try_module_get(s->callback->owner)) {
-				s->callback->resources_done(s);
+				s->callback->requery(s);
 				module_put(s->callback->owner);
 			}
 		}
 		up(&s->skt_sem);
-
-		return count;
 	}
-	spin_unlock_irqrestore(&s->lock, flags);
 
-	return count;
+
+	return (ret);
 }
-static CLASS_DEVICE_ATTR(available_resources_setup_done, 0600, pccard_show_resource, pccard_store_resource);
 
 
 static struct class_device_attribute *pccard_socket_attributes[] = {
@@ -199,6 +334,13 @@ static struct class_device_attribute *pc
 	NULL,
 };
 
+static struct bin_attribute pccard_cis_attr = {
+	.attr = { .name = "cis", .mode = S_IRUGO | S_IWUSR, .owner = THIS_MODULE},
+	.size = 0x200,
+	.read = pccard_show_cis,
+	.write = pccard_store_cis,
+};
+
 static int __devinit pccard_sysfs_add_socket(struct class_device *class_dev)
 {
 	struct class_device_attribute **attr;
@@ -209,6 +351,8 @@ static int __devinit pccard_sysfs_add_so
 		if (ret)
 			break;
 	}
+	if (!ret)
+		ret = sysfs_create_bin_file(&class_dev->kobj, &pccard_cis_attr);
 
 	return ret;
 }
@@ -217,6 +361,7 @@ static void __devexit pccard_sysfs_remov
 {
 	struct class_device_attribute **attr;
 
+	sysfs_remove_bin_file(&class_dev->kobj, &pccard_cis_attr);
 	for (attr = pccard_socket_attributes; *attr; attr++)
 		class_device_remove_file(class_dev, *attr);
 }
diff --git a/drivers/pcmcia/tcic.c b/drivers/pcmcia/tcic.c
--- a/drivers/pcmcia/tcic.c
+++ b/drivers/pcmcia/tcic.c
@@ -50,7 +50,6 @@
 #include <asm/io.h>
 #include <asm/system.h>
 
-#include <pcmcia/version.h>
 #include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/ss.h>
diff --git a/drivers/pcmcia/ti113x.h b/drivers/pcmcia/ti113x.h
--- a/drivers/pcmcia/ti113x.h
+++ b/drivers/pcmcia/ti113x.h
@@ -154,8 +154,6 @@
 #define ENE_TEST_C9			0xc9	/* 8bit */
 #define ENE_TEST_C9_TLTENABLE		0x02
 
-#ifdef CONFIG_CARDBUS
-
 /*
  * Texas Instruments CardBus controller overrides.
  */
@@ -611,6 +609,170 @@ out:
 	}
 }
 
+
+/* Returns true value if the second slot of a two-slot controller is empty */
+static int ti12xx_2nd_slot_empty(struct yenta_socket *socket)
+{
+	struct pci_dev *func;
+	struct yenta_socket *slot2;
+	int devfn;
+	unsigned int state;
+	int ret = 1;
+
+	/* catch the two-slot controllers */
+	switch (socket->dev->device) {
+	case PCI_DEVICE_ID_TI_1220:
+	case PCI_DEVICE_ID_TI_1221:
+	case PCI_DEVICE_ID_TI_1225:
+	case PCI_DEVICE_ID_TI_1251A:
+	case PCI_DEVICE_ID_TI_1251B:
+	case PCI_DEVICE_ID_TI_1420:
+	case PCI_DEVICE_ID_TI_1450:
+	case PCI_DEVICE_ID_TI_1451A:
+	case PCI_DEVICE_ID_TI_1520:
+	case PCI_DEVICE_ID_TI_1620:
+	case PCI_DEVICE_ID_TI_4520:
+	case PCI_DEVICE_ID_TI_4450:
+	case PCI_DEVICE_ID_TI_4451:
+		/*
+		 * there are way more, but they need to be added in yenta_socket.c
+		 * and pci_ids.h first anyway.
+		 */
+		break;
+
+	/* single-slot controllers have the 2nd slot empty always :) */
+	default:
+		return 1;
+	}
+
+	/* get other slot */
+	devfn = socket->dev->devfn & ~0x07;
+	func = pci_get_slot(socket->dev->bus,
+	                    (socket->dev->devfn & 0x07) ? devfn : devfn | 0x01);
+	if (!func)
+		return 1;
+
+	slot2 = pci_get_drvdata(func);
+	if (!slot2)
+		goto out;
+
+	/* check state */
+	yenta_get_status(&socket->socket, &state);
+	if (state & SS_DETECT) {
+		ret = 0;
+		goto out;
+	}
+
+out:
+	pci_dev_put(func);
+	return ret;
+}
+
+/*
+ * TI specifiy parts for the power hook.
+ *
+ * some TI's with some CB's produces interrupt storm on power on. it has been
+ * seen with atheros wlan cards on TI1225 and TI1410. solution is simply to
+ * disable any CB interrupts during this time.
+ */
+static int ti12xx_power_hook(struct pcmcia_socket *sock, int operation)
+{
+	struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
+	u32 mfunc, devctl, sysctl;
+	u8 gpio3;
+
+	/* only POWER_PRE and POWER_POST are interesting */
+	if ((operation != HOOK_POWER_PRE) && (operation != HOOK_POWER_POST))
+		return 0;
+
+	devctl = config_readb(socket, TI113X_DEVICE_CONTROL);
+	sysctl = config_readl(socket, TI113X_SYSTEM_CONTROL);
+	mfunc = config_readl(socket, TI122X_MFUNC);
+
+	/*
+	 * all serial/tied: only disable when modparm set. always doing it
+	 * would mean a regression for working setups 'cos it disables the
+	 * interrupts for both both slots on 2-slot controllers
+	 * (and users of single slot controllers where it's save have to
+	 * live with setting the modparm, most don't have to anyway)
+	 */
+	if (((devctl & TI113X_DCR_IMODE_MASK) == TI12XX_DCR_IMODE_ALL_SERIAL) &&
+	    (pwr_irqs_off || ti12xx_2nd_slot_empty(socket))) {
+		switch (socket->dev->device) {
+		case PCI_DEVICE_ID_TI_1250:
+		case PCI_DEVICE_ID_TI_1251A:
+		case PCI_DEVICE_ID_TI_1251B:
+		case PCI_DEVICE_ID_TI_1450:
+		case PCI_DEVICE_ID_TI_1451A:
+		case PCI_DEVICE_ID_TI_4450:
+		case PCI_DEVICE_ID_TI_4451:
+			/* these chips have no IRQSER setting in MFUNC3  */
+			break;
+
+		default:
+			if (operation == HOOK_POWER_PRE)
+				mfunc = (mfunc & ~TI122X_MFUNC3_MASK);
+			else
+				mfunc = (mfunc & ~TI122X_MFUNC3_MASK) | TI122X_MFUNC3_IRQSER;
+		}
+
+		return 0;
+	}
+
+	/* do the job differently for func0/1 */
+	if ((PCI_FUNC(socket->dev->devfn) == 0) ||
+	    ((sysctl & TI122X_SCR_INTRTIE) &&
+	     (pwr_irqs_off || ti12xx_2nd_slot_empty(socket)))) {
+		/* some bridges are different */
+		switch (socket->dev->device) {
+		case PCI_DEVICE_ID_TI_1250:
+		case PCI_DEVICE_ID_TI_1251A:
+		case PCI_DEVICE_ID_TI_1251B:
+		case PCI_DEVICE_ID_TI_1450:
+			/* those oldies use gpio3 for INTA */
+			gpio3 = config_readb(socket, TI1250_GPIO3_CONTROL);
+			if (operation == HOOK_POWER_PRE)
+				gpio3 = (gpio3 & ~TI1250_GPIO_MODE_MASK) | 0x40;
+			else
+				gpio3 &= ~TI1250_GPIO_MODE_MASK;
+			config_writeb(socket, TI1250_GPIO3_CONTROL, gpio3);
+			break;
+
+		default:
+			/* all new bridges are the same */
+			if (operation == HOOK_POWER_PRE)
+				mfunc &= ~TI122X_MFUNC0_MASK;
+			else
+				mfunc |= TI122X_MFUNC0_INTA;
+			config_writel(socket, TI122X_MFUNC, mfunc);
+		}
+	} else {
+		switch (socket->dev->device) {
+		case PCI_DEVICE_ID_TI_1251A:
+		case PCI_DEVICE_ID_TI_1251B:
+		case PCI_DEVICE_ID_TI_1450:
+			/* those have INTA elsewhere and INTB in MFUNC0 */
+			if (operation == HOOK_POWER_PRE)
+				mfunc &= ~TI122X_MFUNC0_MASK;
+			else
+				mfunc |= TI125X_MFUNC0_INTB;
+			config_writel(socket, TI122X_MFUNC, mfunc);
+
+			break;
+
+		default:
+			/* all new bridges are the same */
+			if (operation == HOOK_POWER_PRE)
+				mfunc &= ~TI122X_MFUNC1_MASK;
+			else
+				mfunc |= TI122X_MFUNC1_INTB;
+			config_writel(socket, TI122X_MFUNC, mfunc);
+		}
+	}
+
+	return 0;
+}
+
 static int ti12xx_override(struct yenta_socket *socket)
 {
 	u32 val, val_orig;
@@ -654,6 +816,9 @@ static int ti12xx_override(struct yenta_
 	else
 		ti12xx_irqroute_func1(socket);
 
+	/* install power hook */
+	socket->socket.power_hook = ti12xx_power_hook;
+
 	return ti_override(socket);
 }
 
@@ -676,7 +841,5 @@ static int ti1250_override(struct yenta_
 	return ti12xx_override(socket);
 }
 
-#endif /* CONFIG_CARDBUS */
-
 #endif /* _LINUX_TI113X_H */
 
diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c
--- a/drivers/pcmcia/yenta_socket.c
+++ b/drivers/pcmcia/yenta_socket.c
@@ -18,7 +18,6 @@
 #include <linux/delay.h>
 #include <linux/module.h>
 
-#include <pcmcia/version.h>
 #include <pcmcia/cs_types.h>
 #include <pcmcia/ss.h>
 #include <pcmcia/cs.h>
@@ -32,6 +31,14 @@ static int disable_clkrun;
 module_param(disable_clkrun, bool, 0444);
 MODULE_PARM_DESC(disable_clkrun, "If PC card doesn't function properly, please try this option");
 
+static int isa_probe = 1;
+module_param(isa_probe, bool, 0444);
+MODULE_PARM_DESC(isa_probe, "If set ISA interrupts are probed (default). Set to N to disable probing");
+
+static int pwr_irqs_off;
+module_param(pwr_irqs_off, bool, 0644);
+MODULE_PARM_DESC(pwr_irqs_off, "Force IRQs off during power-on of slot. Use only when seeing IRQ storms!");
+
 #if 0
 #define debug(x,args...) printk(KERN_DEBUG "%s: " x, __func__ , ##args)
 #else
@@ -150,15 +157,16 @@ static int yenta_get_status(struct pcmci
 
 	val  = (state & CB_3VCARD) ? SS_3VCARD : 0;
 	val |= (state & CB_XVCARD) ? SS_XVCARD : 0;
-	val |= (state & (CB_CDETECT1 | CB_CDETECT2 | CB_5VCARD | CB_3VCARD
-			 | CB_XVCARD | CB_YVCARD)) ? 0 : SS_PENDING;
+	val |= (state & (CB_5VCARD | CB_3VCARD | CB_XVCARD | CB_YVCARD)) ? 0 : SS_PENDING;
+	val |= (state & (CB_CDETECT1 | CB_CDETECT2)) ? SS_PENDING : 0;
+
 
 	if (state & CB_CBCARD) {
 		val |= SS_CARDBUS;	
 		val |= (state & CB_CARDSTS) ? SS_STSCHG : 0;
 		val |= (state & (CB_CDETECT1 | CB_CDETECT2)) ? 0 : SS_DETECT;
 		val |= (state & CB_PWRCYCLE) ? SS_POWERON | SS_READY : 0;
-	} else {
+	} else if (state & CB_16BITCARD) {
 		u8 status = exca_readb(socket, I365_STATUS);
 		val |= ((status & I365_CS_DETECT) == I365_CS_DETECT) ? SS_DETECT : 0;
 		if (exca_readb(socket, I365_INTCTL) & I365_PC_IOCARD) {
@@ -405,11 +413,13 @@ static int yenta_set_mem_map(struct pcmc
 }
 
 
-static unsigned int yenta_events(struct yenta_socket *socket)
+
+static irqreturn_t yenta_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
+	unsigned int events;
+	struct yenta_socket *socket = (struct yenta_socket *) dev_id;
 	u8 csc;
 	u32 cb_event;
-	unsigned int events;
 
 	/* Clear interrupt status for the event */
 	cb_event = cb_readl(socket, CB_SOCKET_EVENT);
@@ -426,20 +436,13 @@ static unsigned int yenta_events(struct 
 		events |= (csc & I365_CSC_BVD2) ? SS_BATWARN : 0;
 		events |= (csc & I365_CSC_READY) ? SS_READY : 0;
 	}
-	return events;
-}
-
-
-static irqreturn_t yenta_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
-	unsigned int events;
-	struct yenta_socket *socket = (struct yenta_socket *) dev_id;
 
-	events = yenta_events(socket);
-	if (events) {
+	if (events)
 		pcmcia_parse_events(&socket->socket, events);
+
+	if (cb_event || csc)
 		return IRQ_HANDLED;
-	}
+
 	return IRQ_NONE;
 }
 
@@ -470,11 +473,22 @@ static void yenta_clear_maps(struct yent
 	}
 }
 
+/* redoes voltage interrogation if required */
+static void yenta_interrogate(struct yenta_socket *socket)
+{
+	u32 state;
+
+	state = cb_readl(socket, CB_SOCKET_STATE);
+	if (!(state & (CB_5VCARD | CB_3VCARD | CB_XVCARD | CB_YVCARD)) ||
+	    (state & (CB_CDETECT1 | CB_CDETECT2 | CB_NOTACARD | CB_BADVCCREQ)) ||
+	    ((state & (CB_16BITCARD | CB_CBCARD)) == (CB_16BITCARD | CB_CBCARD)))
+		cb_writel(socket, CB_SOCKET_FORCE, CB_CVSTEST);
+}
+
 /* Called at resume and initialization events */
 static int yenta_sock_init(struct pcmcia_socket *sock)
 {
 	struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
-	u32 state;
 	u16 bridge;
 
 	bridge = config_readw(socket, CB_BRIDGE_CONTROL) & ~CB_BRIDGE_INTR;
@@ -486,10 +500,7 @@ static int yenta_sock_init(struct pcmcia
 	exca_writeb(socket, I365_GENCTL, 0x00);
 
 	/* Redo card voltage interrogation */
-	state = cb_readl(socket, CB_SOCKET_STATE);
-	if (!(state & (CB_CDETECT1 | CB_CDETECT2 | CB_5VCARD |
-	               CB_3VCARD | CB_XVCARD | CB_YVCARD)))
-		cb_writel(socket, CB_SOCKET_FORCE, CB_CVSTEST);
+	yenta_interrogate(socket);
 
 	yenta_clear_maps(socket);
 
@@ -516,60 +527,29 @@ static int yenta_sock_suspend(struct pcm
  * Use an adaptive allocation for the memory resource,
  * sometimes the memory behind pci bridges is limited:
  * 1/8 of the size of the io window of the parent.
- * max 4 MB, min 16 kB.
+ * max 4 MB, min 16 kB. We try very hard to not get below
+ * the "ACC" values, though.
  */
 #define BRIDGE_MEM_MAX 4*1024*1024
+#define BRIDGE_MEM_ACC 128*1024
 #define BRIDGE_MEM_MIN 16*1024
 
-#define BRIDGE_IO_MAX 256
+#define BRIDGE_IO_MAX 512
+#define BRIDGE_IO_ACC 256
 #define BRIDGE_IO_MIN 32
 
 #ifndef PCIBIOS_MIN_CARDBUS_IO
 #define PCIBIOS_MIN_CARDBUS_IO PCIBIOS_MIN_IO
 #endif
 
-static void yenta_allocate_res(struct yenta_socket *socket, int nr, unsigned type)
+static int yenta_search_one_res(struct resource *root, struct resource *res,
+				u32 min)
 {
-	struct pci_bus *bus;
-	struct resource *root, *res;
-	u32 start, end;
-	u32 align, size, min;
-	unsigned offset;
-	unsigned mask;
-
-	/* The granularity of the memory limit is 4kB, on IO it's 4 bytes */
-	mask = ~0xfff;
-	if (type & IORESOURCE_IO)
-		mask = ~3;
-
-	offset = 0x1c + 8*nr;
-	bus = socket->dev->subordinate;
-	res = socket->dev->resource + PCI_BRIDGE_RESOURCES + nr;
-	res->name = bus->name;
-	res->flags = type;
-	res->start = 0;
-	res->end = 0;
-	root = pci_find_parent_resource(socket->dev, res);
-
-	if (!root)
-		return;
-
-	start = config_readl(socket, offset) & mask;
-	end = config_readl(socket, offset+4) | ~mask;
-	if (start && end > start && !override_bios) {
-		res->start = start;
-		res->end = end;
-		if (request_resource(root, res) == 0)
-			return;
-		printk(KERN_INFO "yenta %s: Preassigned resource %d busy, reconfiguring...\n",
-				pci_name(socket->dev), nr);
-		res->start = res->end = 0;
-	}
+	u32 align, size, start, end;
 
-	if (type & IORESOURCE_IO) {
+	if (res->flags & IORESOURCE_IO) {
 		align = 1024;
 		size = BRIDGE_IO_MAX;
-		min = BRIDGE_IO_MIN;
 		start = PCIBIOS_MIN_CARDBUS_IO;
 		end = ~0U;
 	} else {
@@ -584,26 +564,107 @@ static void yenta_allocate_res(struct ye
 				i++;
 			size = 1 << i;
 		}
-		if (size < BRIDGE_MEM_MIN)
-			size = BRIDGE_MEM_MIN;
-		min = BRIDGE_MEM_MIN;
+		if (size < min)
+			size = min;
 		align = size;
 		start = PCIBIOS_MIN_MEM;
 		end = ~0U;
 	}
-	
+
 	do {
-		if (allocate_resource(root, res, size, start, end, align, NULL, NULL)==0) {
-			config_writel(socket, offset, res->start);
-			config_writel(socket, offset+4, res->end);
-			return;
+		if (allocate_resource(root, res, size, start, end, align,
+				      NULL, NULL)==0) {
+			return 1;
 		}
 		size = size/2;
 		align = size;
 	} while (size >= min);
+
+	return 0;
+}
+
+
+static int yenta_search_res(struct yenta_socket *socket, struct resource *res,
+			    u32 min)
+{
+	int i;
+	for (i=0; i<PCI_BUS_NUM_RESOURCES; i++) {
+		struct resource * root = socket->dev->bus->resource[i];
+		if (!root)
+			continue;
+
+		if ((res->flags ^ root->flags) &
+		    (IORESOURCE_IO | IORESOURCE_MEM | IORESOURCE_PREFETCH))
+			continue; /* Wrong type */
+
+		if (yenta_search_one_res(root, res, min))
+			return 1;
+	}
+	return 0;
+}
+
+static void yenta_allocate_res(struct yenta_socket *socket, int nr, unsigned type, int addr_start, int addr_end)
+{
+	struct resource *root, *res;
+	struct pci_bus_region region;
+	unsigned mask;
+
+	res = socket->dev->resource + PCI_BRIDGE_RESOURCES + nr;
+	/* Already allocated? */
+	if (res->parent)
+		return;
+
+	/* The granularity of the memory limit is 4kB, on IO it's 4 bytes */
+	mask = ~0xfff;
+	if (type & IORESOURCE_IO)
+		mask = ~3;
+
+	res->name = socket->dev->subordinate->name;
+	res->flags = type;
+
+	region.start = config_readl(socket, addr_start) & mask;
+	region.end = config_readl(socket, addr_end) | ~mask;
+	if (region.start && region.end > region.start && !override_bios) {
+		pcibios_bus_to_resource(socket->dev, res, &region);
+		root = pci_find_parent_resource(socket->dev, res);
+		if (root && (request_resource(root, res) == 0))
+			return;
+		printk(KERN_INFO "yenta %s: Preassigned resource %d busy or not available, reconfiguring...\n",
+				pci_name(socket->dev), nr);
+	}
+
+	if (type & IORESOURCE_IO) {
+		if ((yenta_search_res(socket, res, BRIDGE_IO_MAX)) ||
+		    (yenta_search_res(socket, res, BRIDGE_IO_ACC)) ||
+		    (yenta_search_res(socket, res, BRIDGE_IO_MIN))) {
+			config_writel(socket, addr_start, res->start);
+			config_writel(socket, addr_end, res->end);
+			return;
+		}
+	} else {
+		if (type & IORESOURCE_PREFETCH) {
+			if ((yenta_search_res(socket, res, BRIDGE_MEM_MAX)) ||
+			    (yenta_search_res(socket, res, BRIDGE_MEM_ACC)) ||
+			    (yenta_search_res(socket, res, BRIDGE_MEM_MIN))) {
+				config_writel(socket, addr_start, res->start);
+				config_writel(socket, addr_end, res->end);
+				return;
+			}
+			/* Approximating prefetchable by non-prefetchable */
+			res->flags = IORESOURCE_MEM;
+		}
+		if ((yenta_search_res(socket, res, BRIDGE_MEM_MAX)) ||
+		    (yenta_search_res(socket, res, BRIDGE_MEM_ACC)) ||
+		    (yenta_search_res(socket, res, BRIDGE_MEM_MIN))) {
+			config_writel(socket, addr_start, res->start);
+			config_writel(socket, addr_end, res->end);
+			return;
+		}
+	}
+
 	printk(KERN_INFO "yenta %s: no resource of type %x available, trying to continue...\n",
-			pci_name(socket->dev), type);
-	res->start = res->end = 0;
+	       pci_name(socket->dev), type);
+	res->start = res->end = res->flags = 0;
 }
 
 /*
@@ -611,10 +672,14 @@ static void yenta_allocate_res(struct ye
  */
 static void yenta_allocate_resources(struct yenta_socket *socket)
 {
-	yenta_allocate_res(socket, 0, IORESOURCE_MEM|IORESOURCE_PREFETCH);
-	yenta_allocate_res(socket, 1, IORESOURCE_MEM);
-	yenta_allocate_res(socket, 2, IORESOURCE_IO);
-	yenta_allocate_res(socket, 3, IORESOURCE_IO);	/* PCI isn't clever enough to use this one yet */
+	yenta_allocate_res(socket, 0, IORESOURCE_IO,
+			   PCI_CB_IO_BASE_0, PCI_CB_IO_LIMIT_0);
+	yenta_allocate_res(socket, 1, IORESOURCE_IO,
+			   PCI_CB_IO_BASE_1, PCI_CB_IO_LIMIT_1);
+	yenta_allocate_res(socket, 2, IORESOURCE_MEM|IORESOURCE_PREFETCH,
+			   PCI_CB_MEMORY_BASE_0, PCI_CB_MEMORY_LIMIT_0);
+	yenta_allocate_res(socket, 3, IORESOURCE_MEM,
+			   PCI_CB_MEMORY_BASE_1, PCI_CB_MEMORY_LIMIT_1);
 }
 
 
@@ -853,11 +918,11 @@ static int yenta_probe_cb_irq(struct yen
  */
 static void yenta_get_socket_capabilities(struct yenta_socket *socket, u32 isa_irq_mask)
 {
-	socket->socket.features |= SS_CAP_PAGE_REGS | SS_CAP_PCCARD | SS_CAP_CARDBUS;
-	socket->socket.map_size = 0x1000;
 	socket->socket.pci_irq = socket->cb_irq;
-	socket->socket.irq_mask = yenta_probe_irq(socket, isa_irq_mask);
-	socket->socket.cb_dev = socket->dev;
+	if (isa_probe)
+		socket->socket.irq_mask = yenta_probe_irq(socket, isa_irq_mask);
+	else
+		socket->socket.irq_mask = 0;
 
 	printk(KERN_INFO "Yenta: ISA IRQ mask 0x%04x, PCI irq %d\n",
 	       socket->socket.irq_mask, socket->cb_irq);
@@ -923,6 +988,9 @@ static int __devinit yenta_probe (struct
 	socket->socket.dev.dev = &dev->dev;
 	socket->socket.driver_data = socket;
 	socket->socket.owner = THIS_MODULE;
+	socket->socket.features = SS_CAP_PAGE_REGS | SS_CAP_PCCARD;
+	socket->socket.map_size = 0x1000;
+	socket->socket.cb_dev = dev;
 
 	/* prepare struct yenta_socket */
 	socket->dev = dev;
@@ -993,9 +1061,14 @@ static int __devinit yenta_probe (struct
 		socket->poll_timer.data = (unsigned long)socket;
 		socket->poll_timer.expires = jiffies + HZ;
 		add_timer(&socket->poll_timer);
+		printk(KERN_INFO "Yenta: no PCI IRQ, CardBus support disabled for this socket.\n"
+		       KERN_INFO "Yenta: check your BIOS CardBus, BIOS IRQ or ACPI settings.\n");
+	} else {
+		socket->socket.features |= SS_CAP_CARDBUS;
 	}
 
 	/* Figure out what the dang thing can do for the PCMCIA layer... */
+	yenta_interrogate(socket);
 	yenta_get_socket_capabilities(socket, isa_interrupts);
 	printk(KERN_INFO "Socket status: %08x\n", cb_readl(socket, CB_SOCKET_STATE));
 
@@ -1032,6 +1105,7 @@ static int yenta_dev_suspend (struct pci
 		pci_save_state(dev);
 		pci_read_config_dword(dev, 16*4, &socket->saved_state[0]);
 		pci_read_config_dword(dev, 17*4, &socket->saved_state[1]);
+		pci_disable_device(dev);
 
 		/*
 		 * Some laptops (IBM T22) do not like us putting the Cardbus
@@ -1055,6 +1129,8 @@ static int yenta_dev_resume (struct pci_
 		pci_restore_state(dev);
 		pci_write_config_dword(dev, 16*4, socket->saved_state[0]);
 		pci_write_config_dword(dev, 17*4, socket->saved_state[1]);
+		pci_enable_device(dev);
+		pci_set_master(dev);
 
 		if (socket->type && socket->type->restore_state)
 			socket->type->restore_state(socket);
diff --git a/drivers/pnp/card.c b/drivers/pnp/card.c
--- a/drivers/pnp/card.c
+++ b/drivers/pnp/card.c
@@ -140,7 +140,7 @@ static void pnp_release_card(struct devi
 }
 
 
-static ssize_t pnp_show_card_name(struct device *dmdev, char *buf)
+static ssize_t pnp_show_card_name(struct device *dmdev, struct device_attribute *attr, char *buf)
 {
 	char *str = buf;
 	struct pnp_card *card = to_pnp_card(dmdev);
@@ -150,7 +150,7 @@ static ssize_t pnp_show_card_name(struct
 
 static DEVICE_ATTR(name,S_IRUGO,pnp_show_card_name,NULL);
 
-static ssize_t pnp_show_card_ids(struct device *dmdev, char *buf)
+static ssize_t pnp_show_card_ids(struct device *dmdev, struct device_attribute *attr, char *buf)
 {
 	char *str = buf;
 	struct pnp_card *card = to_pnp_card(dmdev);
@@ -259,7 +259,6 @@ int pnp_add_card_device(struct pnp_card 
 
 /**
  * pnp_remove_card_device- removes a device from the specified card
- * @card: pointer to the card to remove from
  * @dev: pointer to the device to remove
  */
 
@@ -274,7 +273,7 @@ void pnp_remove_card_device(struct pnp_d
 
 /**
  * pnp_request_card_device - Searches for a PnP device under the specified card
- * @lcard: pointer to the card link, cannot be NULL
+ * @clink: pointer to the card link, cannot be NULL
  * @id: pointer to a PnP ID structure that explains the rules for finding the device
  * @from: Starting place to search from. If NULL it will start from the begining.
  */
@@ -313,6 +312,8 @@ found:
 	if (drv->link.driver.probe) {
 		if (drv->link.driver.probe(&dev->dev)) {
 			dev->dev.driver = NULL;
+			dev->card_link = NULL;
+			up_write(&dev->dev.bus->subsys.rwsem);
 			return NULL;
 		}
 	}
diff --git a/drivers/pnp/driver.c b/drivers/pnp/driver.c
--- a/drivers/pnp/driver.c
+++ b/drivers/pnp/driver.c
@@ -160,10 +160,16 @@ struct bus_type pnp_bus_type = {
 };
 
 
+static int count_devices(struct device * dev, void * c)
+{
+	int * count = c;
+	(*count)++;
+	return 0;
+}
+
 int pnp_register_driver(struct pnp_driver *drv)
 {
 	int count;
-	struct list_head *pos;
 
 	pnp_dbg("the driver '%s' has been registered", drv->name);
 
@@ -177,9 +183,7 @@ int pnp_register_driver(struct pnp_drive
 	/* get the number of initial matches */
 	if (count >= 0){
 		count = 0;
-		list_for_each(pos,&drv->driver.devices){
-			count++;
-		}
+		driver_for_each_device(&drv->driver, NULL, &count, count_devices);
 	}
 	return count;
 }
diff --git a/drivers/pnp/interface.c b/drivers/pnp/interface.c
--- a/drivers/pnp/interface.c
+++ b/drivers/pnp/interface.c
@@ -205,7 +205,7 @@ static void pnp_print_option(pnp_info_bu
 }
 
 
-static ssize_t pnp_show_options(struct device *dmdev, char *buf)
+static ssize_t pnp_show_options(struct device *dmdev, struct device_attribute *attr, char *buf)
 {
 	struct pnp_dev *dev = to_pnp_dev(dmdev);
 	struct pnp_option * independent = dev->independent;
@@ -236,7 +236,7 @@ static ssize_t pnp_show_options(struct d
 static DEVICE_ATTR(options,S_IRUGO,pnp_show_options,NULL);
 
 
-static ssize_t pnp_show_current_resources(struct device *dmdev, char *buf)
+static ssize_t pnp_show_current_resources(struct device *dmdev, struct device_attribute *attr, char *buf)
 {
 	struct pnp_dev *dev = to_pnp_dev(dmdev);
 	int i, ret;
@@ -308,7 +308,7 @@ static ssize_t pnp_show_current_resource
 extern struct semaphore pnp_res_mutex;
 
 static ssize_t
-pnp_set_current_resources(struct device * dmdev, const char * ubuf, size_t count)
+pnp_set_current_resources(struct device * dmdev, struct device_attribute *attr, const char * ubuf, size_t count)
 {
 	struct pnp_dev *dev = to_pnp_dev(dmdev);
 	char	*buf = (void *)ubuf;
@@ -444,7 +444,7 @@ pnp_set_current_resources(struct device 
 static DEVICE_ATTR(resources,S_IRUGO | S_IWUSR,
 		   pnp_show_current_resources,pnp_set_current_resources);
 
-static ssize_t pnp_show_current_ids(struct device *dmdev, char *buf)
+static ssize_t pnp_show_current_ids(struct device *dmdev, struct device_attribute *attr, char *buf)
 {
 	char *str = buf;
 	struct pnp_dev *dev = to_pnp_dev(dmdev);
diff --git a/drivers/pnp/manager.c b/drivers/pnp/manager.c
--- a/drivers/pnp/manager.c
+++ b/drivers/pnp/manager.c
@@ -390,6 +390,7 @@ fail:
  * pnp_manual_config_dev - Disables Auto Config and Manually sets the resource table
  * @dev: pointer to the desired device
  * @res: pointer to the new resource config
+ * @mode: 0 or PNP_CONFIG_FORCE
  *
  * This function can be used by drivers that want to manually set thier resources.
  */
diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c
--- a/drivers/pnp/pnpacpi/rsparser.c
+++ b/drivers/pnp/pnpacpi/rsparser.c
@@ -160,7 +160,7 @@ static acpi_status pnpacpi_allocated_res
 				acpi_register_gsi(res->data.irq.interrupts[0],
 					res->data.irq.edge_level,
 					res->data.irq.active_high_low));
-			pcibios_penalize_isa_irq(res->data.irq.interrupts[0]);
+			pcibios_penalize_isa_irq(res->data.irq.interrupts[0], 1);
 		}
 		break;
 
@@ -171,7 +171,7 @@ static acpi_status pnpacpi_allocated_res
 				acpi_register_gsi(res->data.extended_irq.interrupts[0],
 					res->data.extended_irq.edge_level,
 					res->data.extended_irq.active_high_low));
-			pcibios_penalize_isa_irq(res->data.extended_irq.interrupts[0]);
+			pcibios_penalize_isa_irq(res->data.extended_irq.interrupts[0], 1);
 		}
 		break;
 	case ACPI_RSTYPE_DMA:
@@ -444,6 +444,7 @@ pnpacpi_parse_fixed_mem32_option(struct 
 
 struct acpipnp_parse_option_s {
 	struct pnp_option *option;
+	struct pnp_option *option_independent;
 	struct pnp_dev *dev;
 };
 
@@ -507,7 +508,14 @@ static acpi_status pnpacpi_option_resour
 			parse_data->option = option;	
 			break;
 		case ACPI_RSTYPE_END_DPF:
-			return AE_CTRL_TERMINATE;
+			/*only one EndDependentFn is allowed*/
+			if (!parse_data->option_independent) {
+				pnp_warn("PnPACPI: more than one EndDependentFn");
+				return AE_ERROR;
+			}
+			parse_data->option = parse_data->option_independent;
+			parse_data->option_independent = NULL;
+			break;
 		default:
 			pnp_warn("PnPACPI: unknown resource type %d", res->id);
 			return AE_ERROR;
@@ -525,6 +533,7 @@ acpi_status pnpacpi_parse_resource_optio
 	parse_data.option = pnp_register_independent_option(dev);
 	if (!parse_data.option)
 		return AE_ERROR;
+	parse_data.option_independent = parse_data.option;
 	parse_data.dev = dev;
 	status = acpi_walk_resources(handle, METHOD_NAME__PRS, 
 		pnpacpi_option_resource, &parse_data);
diff --git a/drivers/pnp/pnpbios/core.c b/drivers/pnp/pnpbios/core.c
--- a/drivers/pnp/pnpbios/core.c
+++ b/drivers/pnp/pnpbios/core.c
@@ -182,7 +182,7 @@ static int pnp_dock_thread(void * unused
 		msleep_interruptible(2000);
 
 		if(signal_pending(current)) {
-			if (try_to_freeze(PF_FREEZE))
+			if (try_to_freeze())
 				continue;
 			break;
 		}
diff --git a/drivers/pnp/pnpbios/rsparser.c b/drivers/pnp/pnpbios/rsparser.c
--- a/drivers/pnp/pnpbios/rsparser.c
+++ b/drivers/pnp/pnpbios/rsparser.c
@@ -11,7 +11,7 @@
 #ifdef CONFIG_PCI
 #include <linux/pci.h>
 #else
-inline void pcibios_penalize_isa_irq(int irq) {}
+inline void pcibios_penalize_isa_irq(int irq, int active) {}
 #endif /* CONFIG_PCI */
 
 #include "pnpbios.h"
@@ -64,7 +64,7 @@ pnpbios_parse_allocated_irqresource(stru
 		}
 		res->irq_resource[i].start =
 		res->irq_resource[i].end = (unsigned long) irq;
-		pcibios_penalize_isa_irq(irq);
+		pcibios_penalize_isa_irq(irq, 1);
 	}
 }
 
diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c
--- a/drivers/pnp/resource.c
+++ b/drivers/pnp/resource.c
@@ -102,7 +102,7 @@ int pnp_register_irq_resource(struct pnp
 
 		for (i = 0; i < 16; i++)
 			if (test_bit(i, data->map))
-				pcibios_penalize_isa_irq(i);
+				pcibios_penalize_isa_irq(i, 0);
 	}
 #endif
 	return 0;
diff --git a/drivers/s390/Kconfig b/drivers/s390/Kconfig
--- a/drivers/s390/Kconfig
+++ b/drivers/s390/Kconfig
@@ -187,6 +187,13 @@ config VMLOGRDR
 	  *SYMPTOM.
 	  This driver depends on the IUCV support driver.
 
+config VMCP
+	tristate "Support for the z/VM CP interface (VM only)"
+	help
+	  Select this option if you want to be able to interact with the control
+	  program on z/VM
+
+
 config MONREADER
 	tristate "API for reading z/VM monitor service records"
 	depends on IUCV
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -7,7 +7,7 @@
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999-2001
  *
- * $Revision: 1.164 $
+ * $Revision: 1.165 $
  */
 
 #include <linux/config.h>
@@ -176,7 +176,7 @@ dasd_state_known_to_basic(struct dasd_de
 		return rc;
 
 	/* register 'device' debug area, used for all DBF_DEV_XXX calls */
-	device->debug_area = debug_register(device->cdev->dev.bus_id, 0, 2,
+	device->debug_area = debug_register(device->cdev->dev.bus_id, 1, 2,
 					    8 * sizeof (long));
 	debug_register_view(device->debug_area, &debug_sprintf_view);
 	debug_set_level(device->debug_area, DBF_EMERG);
@@ -1740,6 +1740,10 @@ dasd_exit(void)
 	dasd_proc_exit();
 #endif
 	dasd_ioctl_exit();
+        if (dasd_page_cache != NULL) {
+		kmem_cache_destroy(dasd_page_cache);
+		dasd_page_cache = NULL;
+	}
 	dasd_gendisk_exit();
 	dasd_devmap_exit();
 	devfs_remove("dasd");
@@ -1952,26 +1956,24 @@ dasd_generic_notify(struct ccw_device *c
  * Automatically online either all dasd devices (dasd_autodetect) or
  * all devices specified with dasd= parameters.
  */
+static int
+__dasd_auto_online(struct device *dev, void *data)
+{
+	struct ccw_device *cdev;
+
+	cdev = to_ccwdev(dev);
+	if (dasd_autodetect || dasd_busid_known(cdev->dev.bus_id) == 0)
+		ccw_device_set_online(cdev);
+	return 0;
+}
+
 void
 dasd_generic_auto_online (struct ccw_driver *dasd_discipline_driver)
 {
 	struct device_driver *drv;
-	struct device *d, *dev;
-	struct ccw_device *cdev;
 
 	drv = get_driver(&dasd_discipline_driver->driver);
-	down_read(&drv->bus->subsys.rwsem);
-	dev = NULL;
-	list_for_each_entry(d, &drv->devices, driver_list) {
-		dev = get_device(d);
-		if (!dev)
-			continue;
-		cdev = to_ccwdev(dev);
-		if (dasd_autodetect || dasd_busid_known(cdev->dev.bus_id) == 0)
-			ccw_device_set_online(cdev);
-		put_device(dev);
-	}
-	up_read(&drv->bus->subsys.rwsem);
+	driver_for_each_device(drv, NULL, NULL, __dasd_auto_online);
 	put_driver(drv);
 }
 
@@ -1983,7 +1985,7 @@ dasd_init(void)
 	init_waitqueue_head(&dasd_init_waitq);
 
 	/* register 'common' DASD debug area, used for all DBF_XXX calls */
-	dasd_debug_area = debug_register("dasd", 0, 2, 8 * sizeof (long));
+	dasd_debug_area = debug_register("dasd", 1, 2, 8 * sizeof (long));
 	if (dasd_debug_area == NULL) {
 		rc = -ENOMEM;
 		goto failed;
diff --git a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c
--- a/drivers/s390/block/dasd_devmap.c
+++ b/drivers/s390/block/dasd_devmap.c
@@ -615,7 +615,7 @@ dasd_device_from_cdev(struct ccw_device 
  * readonly controls the readonly status of a dasd
  */
 static ssize_t
-dasd_ro_show(struct device *dev, char *buf)
+dasd_ro_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct dasd_devmap *devmap;
 	int ro_flag;
@@ -629,7 +629,7 @@ dasd_ro_show(struct device *dev, char *b
 }
 
 static ssize_t
-dasd_ro_store(struct device *dev, const char *buf, size_t count)
+dasd_ro_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct dasd_devmap *devmap;
 	int ro_flag;
@@ -656,7 +656,7 @@ static DEVICE_ATTR(readonly, 0644, dasd_
  * to talk to the device
  */
 static ssize_t 
-dasd_use_diag_show(struct device *dev, char *buf)
+dasd_use_diag_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct dasd_devmap *devmap;
 	int use_diag;
@@ -670,7 +670,7 @@ dasd_use_diag_show(struct device *dev, c
 }
 
 static ssize_t
-dasd_use_diag_store(struct device *dev, const char *buf, size_t count)
+dasd_use_diag_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct dasd_devmap *devmap;
 	ssize_t rc;
@@ -698,7 +698,7 @@ static
 DEVICE_ATTR(use_diag, 0644, dasd_use_diag_show, dasd_use_diag_store);
 
 static ssize_t
-dasd_discipline_show(struct device *dev, char *buf)
+dasd_discipline_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct dasd_devmap *devmap;
 	char *dname;
diff --git a/drivers/s390/block/dasd_fba.c b/drivers/s390/block/dasd_fba.c
--- a/drivers/s390/block/dasd_fba.c
+++ b/drivers/s390/block/dasd_fba.c
@@ -4,7 +4,7 @@
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
  *
- * $Revision: 1.39 $
+ * $Revision: 1.40 $
  */
 
 #include <linux/config.h>
@@ -354,6 +354,8 @@ dasd_fba_build_cp(struct dasd_device * d
 	}
 	cqr->device = device;
 	cqr->expires = 5 * 60 * HZ;	/* 5 minutes */
+	cqr->retries = 32;
+	cqr->buildclk = get_clock();
 	cqr->status = DASD_CQR_FILLED;
 	return cqr;
 }
diff --git a/drivers/s390/block/dasd_proc.c b/drivers/s390/block/dasd_proc.c
--- a/drivers/s390/block/dasd_proc.c
+++ b/drivers/s390/block/dasd_proc.c
@@ -9,13 +9,14 @@
  *
  * /proc interface for the dasd driver.
  *
- * $Revision: 1.31 $
+ * $Revision: 1.32 $
  */
 
 #include <linux/config.h>
 #include <linux/ctype.h>
 #include <linux/seq_file.h>
 #include <linux/vmalloc.h>
+#include <linux/proc_fs.h>
 
 #include <asm/debug.h>
 #include <asm/uaccess.h>
diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c
--- a/drivers/s390/block/dcssblk.c
+++ b/drivers/s390/block/dcssblk.c
@@ -35,26 +35,29 @@
 static int dcssblk_open(struct inode *inode, struct file *filp);
 static int dcssblk_release(struct inode *inode, struct file *filp);
 static int dcssblk_make_request(struct request_queue *q, struct bio *bio);
+static int dcssblk_direct_access(struct block_device *bdev, sector_t secnum,
+				 unsigned long *data);
 
 static char dcssblk_segments[DCSSBLK_PARM_LEN] = "\0";
 
 static int dcssblk_major;
 static struct block_device_operations dcssblk_devops = {
-	.owner   = THIS_MODULE,
-	.open    = dcssblk_open,
-	.release = dcssblk_release,
+	.owner   	= THIS_MODULE,
+	.open    	= dcssblk_open,
+	.release 	= dcssblk_release,
+	.direct_access 	= dcssblk_direct_access,
 };
 
-static ssize_t dcssblk_add_store(struct device * dev, const char * buf,
+static ssize_t dcssblk_add_store(struct device * dev, struct device_attribute *attr, const char * buf,
 				  size_t count);
-static ssize_t dcssblk_remove_store(struct device * dev, const char * buf,
+static ssize_t dcssblk_remove_store(struct device * dev, struct device_attribute *attr, const char * buf,
 				  size_t count);
-static ssize_t dcssblk_save_store(struct device * dev, const char * buf,
+static ssize_t dcssblk_save_store(struct device * dev, struct device_attribute *attr, const char * buf,
 				  size_t count);
-static ssize_t dcssblk_save_show(struct device *dev, char *buf);
-static ssize_t dcssblk_shared_store(struct device * dev, const char * buf,
+static ssize_t dcssblk_save_show(struct device *dev, struct device_attribute *attr, char *buf);
+static ssize_t dcssblk_shared_store(struct device * dev, struct device_attribute *attr, const char * buf,
 				  size_t count);
-static ssize_t dcssblk_shared_show(struct device *dev, char *buf);
+static ssize_t dcssblk_shared_show(struct device *dev, struct device_attribute *attr, char *buf);
 
 static DEVICE_ATTR(add, S_IWUSR, NULL, dcssblk_add_store);
 static DEVICE_ATTR(remove, S_IWUSR, NULL, dcssblk_remove_store);
@@ -195,7 +198,7 @@ dcssblk_segment_warn(int rc, char* seg_n
  * operation (show + store)
  */
 static ssize_t
-dcssblk_shared_show(struct device *dev, char *buf)
+dcssblk_shared_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct dcssblk_dev_info *dev_info;
 
@@ -204,7 +207,7 @@ dcssblk_shared_show(struct device *dev, 
 }
 
 static ssize_t
-dcssblk_shared_store(struct device *dev, const char *inbuf, size_t count)
+dcssblk_shared_store(struct device *dev, struct device_attribute *attr, const char *inbuf, size_t count)
 {
 	struct dcssblk_dev_info *dev_info;
 	int rc;
@@ -288,7 +291,7 @@ out:
  * (show + store)
  */
 static ssize_t
-dcssblk_save_show(struct device *dev, char *buf)
+dcssblk_save_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct dcssblk_dev_info *dev_info;
 
@@ -297,7 +300,7 @@ dcssblk_save_show(struct device *dev, ch
 }
 
 static ssize_t
-dcssblk_save_store(struct device *dev, const char *inbuf, size_t count)
+dcssblk_save_store(struct device *dev, struct device_attribute *attr, const char *inbuf, size_t count)
 {
 	struct dcssblk_dev_info *dev_info;
 
@@ -343,7 +346,7 @@ dcssblk_save_store(struct device *dev, c
  * device attribute for adding devices
  */
 static ssize_t
-dcssblk_add_store(struct device *dev, const char *buf, size_t count)
+dcssblk_add_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	int rc, i;
 	struct dcssblk_dev_info *dev_info;
@@ -517,7 +520,7 @@ out_nobuf:
  * device attribute for removing devices
  */
 static ssize_t
-dcssblk_remove_store(struct device *dev, const char *buf, size_t count)
+dcssblk_remove_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct dcssblk_dev_info *dev_info;
 	int rc, i;
@@ -641,6 +644,20 @@ dcssblk_make_request(request_queue_t *q,
 		/* Request beyond end of DCSS segment. */
 		goto fail;
 	}
+	/* verify data transfer direction */
+	if (dev_info->is_shared) {
+		switch (dev_info->segment_type) {
+		case SEG_TYPE_SR:
+		case SEG_TYPE_ER:
+		case SEG_TYPE_SC:
+			/* cannot write to these segments */
+			if (bio_data_dir(bio) == WRITE) {
+				PRINT_WARN("rejecting write to ro segment %s\n", dev_info->dev.bus_id);
+				goto fail;
+			}
+		}
+	}
+
 	index = (bio->bi_sector >> 3);
 	bio_for_each_segment(bvec, bio, i) {
 		page_addr = (unsigned long)
@@ -661,7 +678,26 @@ dcssblk_make_request(request_queue_t *q,
 	bio_endio(bio, bytes_done, 0);
 	return 0;
 fail:
-	bio_io_error(bio, bytes_done);
+	bio_io_error(bio, bio->bi_size);
+	return 0;
+}
+
+static int
+dcssblk_direct_access (struct block_device *bdev, sector_t secnum,
+			unsigned long *data)
+{
+	struct dcssblk_dev_info *dev_info;
+	unsigned long pgoff;
+
+	dev_info = bdev->bd_disk->private_data;
+	if (!dev_info)
+		return -ENODEV;
+	if (secnum % (PAGE_SIZE/512))
+		return -EINVAL;
+	pgoff = secnum / (PAGE_SIZE / 512);
+	if ((pgoff+1)*PAGE_SIZE-1 > dev_info->end - dev_info->start)
+		return -ERANGE;
+	*data = (unsigned long) (dev_info->start+pgoff*PAGE_SIZE);
 	return 0;
 }
 
@@ -682,7 +718,7 @@ dcssblk_check_params(void)
 			buf[j-i] = dcssblk_segments[j];
 		}
 		buf[j-i] = '\0';
-		rc = dcssblk_add_store(dcssblk_root_dev, buf, j-i);
+		rc = dcssblk_add_store(dcssblk_root_dev, NULL, buf, j-i);
 		if ((rc >= 0) && (dcssblk_segments[j] == '(')) {
 			for (k = 0; buf[k] != '\0'; k++)
 				buf[k] = toupper(buf[k]);
@@ -692,7 +728,7 @@ dcssblk_check_params(void)
 				up_read(&dcssblk_devices_sem);
 				if (dev_info)
 					dcssblk_shared_store(&dev_info->dev,
-							     "0\n", 2);
+							     NULL, "0\n", 2);
 			}
 		}
 		while ((dcssblk_segments[j] != ',') &&
diff --git a/drivers/s390/char/Makefile b/drivers/s390/char/Makefile
--- a/drivers/s390/char/Makefile
+++ b/drivers/s390/char/Makefile
@@ -19,6 +19,7 @@ obj-$(CONFIG_SCLP_CPI) += sclp_cpi.o
 
 obj-$(CONFIG_ZVM_WATCHDOG) += vmwatchdog.o
 obj-$(CONFIG_VMLOGRDR) += vmlogrdr.o
+obj-$(CONFIG_VMCP) += vmcp.o
 
 tape-$(CONFIG_S390_TAPE_BLOCK) += tape_block.o
 tape-$(CONFIG_PROC_FS) += tape_proc.o
diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c
--- a/drivers/s390/char/con3215.c
+++ b/drivers/s390/char/con3215.c
@@ -860,8 +860,8 @@ con3215_init(void)
 
 	/* Set the console mode for VM */
 	if (MACHINE_IS_VM) {
-		cpcmd("TERM CONMODE 3215", NULL, 0);
-		cpcmd("TERM AUTOCR OFF", NULL, 0);
+		cpcmd("TERM CONMODE 3215", NULL, 0, NULL);
+		cpcmd("TERM AUTOCR OFF", NULL, 0, NULL);
 	}
 
 	/* allocate 3215 request structures */
diff --git a/drivers/s390/char/con3270.c b/drivers/s390/char/con3270.c
--- a/drivers/s390/char/con3270.c
+++ b/drivers/s390/char/con3270.c
@@ -591,8 +591,8 @@ con3270_init(void)
 
 	/* Set the console mode for VM */
 	if (MACHINE_IS_VM) {
-		cpcmd("TERM CONMODE 3270", 0, 0);
-		cpcmd("TERM AUTOCR OFF", 0, 0);
+		cpcmd("TERM CONMODE 3270", NULL, 0, NULL);
+		cpcmd("TERM AUTOCR OFF", NULL, 0, NULL);
 	}
 
 	cdev = ccw_device_probe_console();
diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c
--- a/drivers/s390/char/raw3270.c
+++ b/drivers/s390/char/raw3270.c
@@ -1084,7 +1084,7 @@ raw3270_probe (struct ccw_device *cdev)
  * Additional attributes for a 3270 device
  */
 static ssize_t
-raw3270_model_show(struct device *dev, char *buf)
+raw3270_model_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	return snprintf(buf, PAGE_SIZE, "%i\n",
 			((struct raw3270 *) dev->driver_data)->model);
@@ -1092,7 +1092,7 @@ raw3270_model_show(struct device *dev, c
 static DEVICE_ATTR(model, 0444, raw3270_model_show, 0);
 
 static ssize_t
-raw3270_rows_show(struct device *dev, char *buf)
+raw3270_rows_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	return snprintf(buf, PAGE_SIZE, "%i\n",
 			((struct raw3270 *) dev->driver_data)->rows);
@@ -1100,7 +1100,7 @@ raw3270_rows_show(struct device *dev, ch
 static DEVICE_ATTR(rows, 0444, raw3270_rows_show, 0);
 
 static ssize_t
-raw3270_columns_show(struct device *dev, char *buf)
+raw3270_columns_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	return snprintf(buf, PAGE_SIZE, "%i\n",
 			((struct raw3270 *) dev->driver_data)->cols);
diff --git a/drivers/s390/char/tape.h b/drivers/s390/char/tape.h
--- a/drivers/s390/char/tape.h
+++ b/drivers/s390/char/tape.h
@@ -3,10 +3,11 @@
  *    tape device driver for 3480/3490E/3590 tapes.
  *
  *  S390 and zSeries version
- *    Copyright (C) 2001,2002 IBM Deutschland Entwicklung GmbH, IBM Corporation
+ *    Copyright (C) 2001,2005 IBM Deutschland Entwicklung GmbH, IBM Corporation
  *    Author(s): Carsten Otte <cotte@de.ibm.com>
  *		 Tuan Ngo-Anh <ngoanh@de.ibm.com>
  *		 Martin Schwidefsky <schwidefsky@de.ibm.com>
+ *		 Stefan Bader <shbader@de.ibm.com>
  */
 
 #ifndef _TAPE_H
@@ -111,6 +112,7 @@ enum tape_request_status {
 	TAPE_REQUEST_QUEUED,	/* request is queued to be processed */
 	TAPE_REQUEST_IN_IO,	/* request is currently in IO */
 	TAPE_REQUEST_DONE,	/* request is completed. */
+	TAPE_REQUEST_CANCEL,	/* request should be canceled. */
 };
 
 /* Tape CCW request */
@@ -237,6 +239,9 @@ struct tape_device {
 	/* Block dev frontend data */
 	struct tape_blk_data		blk_data;
 #endif
+
+	/* Function to start or stop the next request later. */
+	struct work_struct		tape_dnr;
 };
 
 /* Externals from tape_core.c */
diff --git a/drivers/s390/char/tape_34xx.c b/drivers/s390/char/tape_34xx.c
--- a/drivers/s390/char/tape_34xx.c
+++ b/drivers/s390/char/tape_34xx.c
@@ -1351,13 +1351,13 @@ tape_34xx_init (void)
 {
 	int rc;
 
-	TAPE_DBF_AREA = debug_register ( "tape_34xx", 1, 2, 4*sizeof(long));
+	TAPE_DBF_AREA = debug_register ( "tape_34xx", 2, 2, 4*sizeof(long));
 	debug_register_view(TAPE_DBF_AREA, &debug_sprintf_view);
 #ifdef DBF_LIKE_HELL
 	debug_set_level(TAPE_DBF_AREA, 6);
 #endif
 
-	DBF_EVENT(3, "34xx init: $Revision: 1.21 $\n");
+	DBF_EVENT(3, "34xx init: $Revision: 1.23 $\n");
 	/* Register driver for 3480/3490 tapes. */
 	rc = ccw_driver_register(&tape_34xx_driver);
 	if (rc)
@@ -1378,7 +1378,7 @@ tape_34xx_exit(void)
 MODULE_DEVICE_TABLE(ccw, tape_34xx_ids);
 MODULE_AUTHOR("(C) 2001-2002 IBM Deutschland Entwicklung GmbH");
 MODULE_DESCRIPTION("Linux on zSeries channel attached 3480 tape "
-		   "device driver ($Revision: 1.21 $)");
+		   "device driver ($Revision: 1.23 $)");
 MODULE_LICENSE("GPL");
 
 module_init(tape_34xx_init);
diff --git a/drivers/s390/char/tape_class.c b/drivers/s390/char/tape_class.c
--- a/drivers/s390/char/tape_class.c
+++ b/drivers/s390/char/tape_class.c
@@ -16,7 +16,7 @@ MODULE_DESCRIPTION(
 );
 MODULE_LICENSE("GPL");
 
-struct class_simple *tape_class;
+static struct class *tape_class;
 
 /*
  * Register a tape device and return a pointer to the cdev structure.
@@ -70,7 +70,7 @@ struct tape_class_device *register_tape_
 	if (rc)
 		goto fail_with_cdev;
 
-	tcd->class_device = class_simple_device_add(
+	tcd->class_device = class_device_create(
 				tape_class,
 				tcd->char_device->dev,
 				device,
@@ -101,7 +101,7 @@ void unregister_tape_dev(struct tape_cla
 			&tcd->class_device->dev->kobj,
 			tcd->mode_name
 		);
-		class_simple_device_remove(tcd->char_device->dev);
+		class_device_destroy(tape_class, tcd->char_device->dev);
 		cdev_del(tcd->char_device);
 		kfree(tcd);
 	}
@@ -111,14 +111,14 @@ EXPORT_SYMBOL(unregister_tape_dev);
 
 static int __init tape_init(void)
 {
-	tape_class = class_simple_create(THIS_MODULE, "tape390");
+	tape_class = class_create(THIS_MODULE, "tape390");
 
 	return 0;
 }
 
 static void __exit tape_exit(void)
 {
-	class_simple_destroy(tape_class);
+	class_destroy(tape_class);
 	tape_class = NULL;
 }
 
diff --git a/drivers/s390/char/tape_core.c b/drivers/s390/char/tape_core.c
--- a/drivers/s390/char/tape_core.c
+++ b/drivers/s390/char/tape_core.c
@@ -3,11 +3,12 @@
  *    basic function of the tape device driver
  *
  *  S390 and zSeries version
- *    Copyright (C) 2001,2002 IBM Deutschland Entwicklung GmbH, IBM Corporation
+ *    Copyright (C) 2001,2005 IBM Deutschland Entwicklung GmbH, IBM Corporation
  *    Author(s): Carsten Otte <cotte@de.ibm.com>
  *		 Michael Holzheu <holzheu@de.ibm.com>
  *		 Tuan Ngo-Anh <ngoanh@de.ibm.com>
  *		 Martin Schwidefsky <schwidefsky@de.ibm.com>
+ *		 Stefan Bader <shbader@de.ibm.com>
  */
 
 #include <linux/config.h>
@@ -28,7 +29,7 @@
 #define PRINTK_HEADER "TAPE_CORE: "
 
 static void __tape_do_irq (struct ccw_device *, unsigned long, struct irb *);
-static void __tape_remove_request(struct tape_device *, struct tape_request *);
+static void tape_delayed_next_request(void * data);
 
 /*
  * One list to contain all tape devices of all disciplines, so
@@ -107,7 +108,7 @@ busid_to_int(char *bus_id)
  *        replaced by a link to the cdev tree.
  */
 static ssize_t
-tape_medium_state_show(struct device *dev, char *buf)
+tape_medium_state_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct tape_device *tdev;
 
@@ -119,7 +120,7 @@ static
 DEVICE_ATTR(medium_state, 0444, tape_medium_state_show, NULL);
 
 static ssize_t
-tape_first_minor_show(struct device *dev, char *buf)
+tape_first_minor_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct tape_device *tdev;
 
@@ -131,7 +132,7 @@ static
 DEVICE_ATTR(first_minor, 0444, tape_first_minor_show, NULL);
 
 static ssize_t
-tape_state_show(struct device *dev, char *buf)
+tape_state_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct tape_device *tdev;
 
@@ -144,7 +145,7 @@ static
 DEVICE_ATTR(state, 0444, tape_state_show, NULL);
 
 static ssize_t
-tape_operation_show(struct device *dev, char *buf)
+tape_operation_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct tape_device *tdev;
 	ssize_t rc;
@@ -171,7 +172,7 @@ static
 DEVICE_ATTR(operation, 0444, tape_operation_show, NULL);
 
 static ssize_t
-tape_blocksize_show(struct device *dev, char *buf)
+tape_blocksize_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct tape_device *tdev;
 
@@ -257,7 +258,7 @@ tape_med_state_set(struct tape_device *d
  * Stop running ccw. Has to be called with the device lock held.
  */
 static inline int
-__tape_halt_io(struct tape_device *device, struct tape_request *request)
+__tape_cancel_io(struct tape_device *device, struct tape_request *request)
 {
 	int retries;
 	int rc;
@@ -270,20 +271,23 @@ __tape_halt_io(struct tape_device *devic
 	for (retries = 0; retries < 5; retries++) {
 		rc = ccw_device_clear(device->cdev, (long) request);
 
-		if (rc == 0) {                     /* Termination successful */
-			request->rc     = -EIO;
-			request->status = TAPE_REQUEST_DONE;
-			return 0;
+		switch (rc) {
+			case 0:
+				request->status	= TAPE_REQUEST_DONE;
+				return 0;
+			case -EBUSY:
+				request->status	= TAPE_REQUEST_CANCEL;
+				schedule_work(&device->tape_dnr);
+				return 0;
+			case -ENODEV:
+				DBF_EXCEPTION(2, "device gone, retry\n");
+				break;
+			case -EIO:
+				DBF_EXCEPTION(2, "I/O error, retry\n");
+				break;
+			default:
+				BUG();
 		}
-
-		if (rc == -ENODEV)
-			DBF_EXCEPTION(2, "device gone, retry\n");
-		else if (rc == -EIO)
-			DBF_EXCEPTION(2, "I/O error, retry\n");
-		else if (rc == -EBUSY)
-			DBF_EXCEPTION(2, "device busy, retry late\n");
-		else
-			BUG();
 	}
 
 	return rc;
@@ -473,6 +477,7 @@ tape_alloc_device(void)
 	*device->modeset_byte = 0;
 	device->first_minor = -1;
 	atomic_set(&device->ref_count, 1);
+	INIT_WORK(&device->tape_dnr, tape_delayed_next_request, device);
 
 	return device;
 }
@@ -708,54 +713,119 @@ tape_free_request (struct tape_request *
 	kfree(request);
 }
 
+static inline int
+__tape_start_io(struct tape_device *device, struct tape_request *request)
+{
+	int rc;
+
+#ifdef CONFIG_S390_TAPE_BLOCK
+	if (request->op == TO_BLOCK)
+		device->discipline->check_locate(device, request);
+#endif
+	rc = ccw_device_start(
+		device->cdev,
+		request->cpaddr,
+		(unsigned long) request,
+		0x00,
+		request->options
+	);
+	if (rc == 0) {
+		request->status = TAPE_REQUEST_IN_IO;
+	} else if (rc == -EBUSY) {
+		/* The common I/O subsystem is currently busy. Retry later. */
+		request->status = TAPE_REQUEST_QUEUED;
+		schedule_work(&device->tape_dnr);
+		rc = 0;
+	} else {
+		/* Start failed. Remove request and indicate failure. */
+		DBF_EVENT(1, "tape: start request failed with RC = %i\n", rc);
+	}
+	return rc;
+}
+
 static inline void
-__tape_do_io_list(struct tape_device *device)
+__tape_start_next_request(struct tape_device *device)
 {
 	struct list_head *l, *n;
 	struct tape_request *request;
 	int rc;
 
-	DBF_LH(6, "__tape_do_io_list(%p)\n", device);
+	DBF_LH(6, "__tape_start_next_request(%p)\n", device);
 	/*
 	 * Try to start each request on request queue until one is
 	 * started successful.
 	 */
 	list_for_each_safe(l, n, &device->req_queue) {
 		request = list_entry(l, struct tape_request, list);
-#ifdef CONFIG_S390_TAPE_BLOCK
-		if (request->op == TO_BLOCK)
-			device->discipline->check_locate(device, request);
-#endif
-		rc = ccw_device_start(device->cdev, request->cpaddr,
-				      (unsigned long) request, 0x00,
-				      request->options);
-		if (rc == 0) {
-			request->status = TAPE_REQUEST_IN_IO;
-			break;
+
+		/*
+		 * Avoid race condition if bottom-half was triggered more than
+		 * once.
+		 */
+		if (request->status == TAPE_REQUEST_IN_IO)
+			return;
+
+		/*
+		 * We wanted to cancel the request but the common I/O layer
+		 * was busy at that time. This can only happen if this
+		 * function is called by delayed_next_request.
+		 * Otherwise we start the next request on the queue.
+		 */
+		if (request->status == TAPE_REQUEST_CANCEL) {
+			rc = __tape_cancel_io(device, request);
+		} else {
+			rc = __tape_start_io(device, request);
 		}
-		/* Start failed. Remove request and indicate failure. */
-		DBF_EVENT(1, "tape: DOIO failed with er = %i\n", rc);
+		if (rc == 0)
+			return;
 
-		/* Set ending status and do callback. */
+		/* Set ending status. */
 		request->rc = rc;
 		request->status = TAPE_REQUEST_DONE;
-		__tape_remove_request(device, request);
+
+		/* Remove from request queue. */
+		list_del(&request->list);
+
+		/* Do callback. */
+		if (request->callback != NULL)
+			request->callback(request, request->callback_data);
 	}
 }
 
 static void
-__tape_remove_request(struct tape_device *device, struct tape_request *request)
+tape_delayed_next_request(void *data)
 {
-	/* Remove from request queue. */
-	list_del(&request->list);
+	struct tape_device *	device;
 
-	/* Do callback. */
-	if (request->callback != NULL)
-		request->callback(request, request->callback_data);
+	device = (struct tape_device *) data;
+	DBF_LH(6, "tape_delayed_next_request(%p)\n", device);
+	spin_lock_irq(get_ccwdev_lock(device->cdev));
+	__tape_start_next_request(device);
+	spin_unlock_irq(get_ccwdev_lock(device->cdev));
+}
+
+static inline void
+__tape_end_request(
+	struct tape_device *	device,
+	struct tape_request *	request,
+	int			rc)
+{
+	DBF_LH(6, "__tape_end_request(%p, %p, %i)\n", device, request, rc);
+	if (request) {
+		request->rc = rc;
+		request->status = TAPE_REQUEST_DONE;
+
+		/* Remove from request queue. */
+		list_del(&request->list);
+
+		/* Do callback. */
+		if (request->callback != NULL)
+			request->callback(request, request->callback_data);
+	}
 
 	/* Start next request. */
 	if (!list_empty(&device->req_queue))
-		__tape_do_io_list(device);
+		__tape_start_next_request(device);
 }
 
 /*
@@ -812,7 +882,7 @@ tape_dump_sense_dbf(struct tape_device *
  * the device lock held.
  */
 static inline int
-__tape_do_io(struct tape_device *device, struct tape_request *request)
+__tape_start_request(struct tape_device *device, struct tape_request *request)
 {
 	int rc;
 
@@ -837,24 +907,16 @@ __tape_do_io(struct tape_device *device,
 
 	if (list_empty(&device->req_queue)) {
 		/* No other requests are on the queue. Start this one. */
-#ifdef CONFIG_S390_TAPE_BLOCK
-		if (request->op == TO_BLOCK)
-			device->discipline->check_locate(device, request);
-#endif
-		rc = ccw_device_start(device->cdev, request->cpaddr,
-				      (unsigned long) request, 0x00,
-				      request->options);
-		if (rc) {
-			DBF_EVENT(1, "tape: DOIO failed with rc = %i\n", rc);
+		rc = __tape_start_io(device, request);
+		if (rc)
 			return rc;
-		}
+
 		DBF_LH(5, "Request %p added for execution.\n", request);
 		list_add(&request->list, &device->req_queue);
-		request->status = TAPE_REQUEST_IN_IO;
 	} else {
 		DBF_LH(5, "Request %p add to queue.\n", request);
-		list_add_tail(&request->list, &device->req_queue);
 		request->status = TAPE_REQUEST_QUEUED;
+		list_add_tail(&request->list, &device->req_queue);
 	}
 	return 0;
 }
@@ -872,7 +934,7 @@ tape_do_io_async(struct tape_device *dev
 
 	spin_lock_irq(get_ccwdev_lock(device->cdev));
 	/* Add request to request queue and try to start it. */
-	rc = __tape_do_io(device, request);
+	rc = __tape_start_request(device, request);
 	spin_unlock_irq(get_ccwdev_lock(device->cdev));
 	return rc;
 }
@@ -901,7 +963,7 @@ tape_do_io(struct tape_device *device, s
 	request->callback = __tape_wake_up;
 	request->callback_data = &wq;
 	/* Add request to request queue and try to start it. */
-	rc = __tape_do_io(device, request);
+	rc = __tape_start_request(device, request);
 	spin_unlock_irq(get_ccwdev_lock(device->cdev));
 	if (rc)
 		return rc;
@@ -935,7 +997,7 @@ tape_do_io_interruptible(struct tape_dev
 	/* Setup callback */
 	request->callback = __tape_wake_up_interruptible;
 	request->callback_data = &wq;
-	rc = __tape_do_io(device, request);
+	rc = __tape_start_request(device, request);
 	spin_unlock_irq(get_ccwdev_lock(device->cdev));
 	if (rc)
 		return rc;
@@ -944,36 +1006,27 @@ tape_do_io_interruptible(struct tape_dev
 	if (rc != -ERESTARTSYS)
 		/* Request finished normally. */
 		return request->rc;
+
 	/* Interrupted by a signal. We have to stop the current request. */
 	spin_lock_irq(get_ccwdev_lock(device->cdev));
-	rc = __tape_halt_io(device, request);
+	rc = __tape_cancel_io(device, request);
+	spin_unlock_irq(get_ccwdev_lock(device->cdev));
 	if (rc == 0) {
+		/* Wait for the interrupt that acknowledges the halt. */
+		do {
+			rc = wait_event_interruptible(
+				wq,
+				(request->callback == NULL)
+			);
+		} while (rc != -ERESTARTSYS);
+
 		DBF_EVENT(3, "IO stopped on %08x\n", device->cdev_id);
 		rc = -ERESTARTSYS;
 	}
-	spin_unlock_irq(get_ccwdev_lock(device->cdev));
 	return rc;
 }
 
 /*
- * Handle requests that return an i/o error in the irb.
- */
-static inline void
-tape_handle_killed_request(
-	struct tape_device *device,
-	struct tape_request *request)
-{
-	if(request != NULL) {
-		/* Set ending status. FIXME: Should the request be retried? */
-		request->rc = -EIO;
-		request->status = TAPE_REQUEST_DONE;
-		__tape_remove_request(device, request);
-	} else {
-		__tape_do_io_list(device);
-	}
-}
-
-/*
  * Tape interrupt routine, called from the ccw_device layer
  */
 static void
@@ -981,7 +1034,6 @@ __tape_do_irq (struct ccw_device *cdev, 
 {
 	struct tape_device *device;
 	struct tape_request *request;
-	int final;
 	int rc;
 
 	device = (struct tape_device *) cdev->dev.driver_data;
@@ -996,12 +1048,13 @@ __tape_do_irq (struct ccw_device *cdev, 
 
 	/* On special conditions irb is an error pointer */
 	if (IS_ERR(irb)) {
+		/* FIXME: What to do with the request? */
 		switch (PTR_ERR(irb)) {
 			case -ETIMEDOUT:
 				PRINT_WARN("(%s): Request timed out\n",
 					cdev->dev.bus_id);
 			case -EIO:
-				tape_handle_killed_request(device, request);
+				__tape_end_request(device, request, -EIO);
 				break;
 			default:
 				PRINT_ERR("(%s): Unexpected i/o error %li\n",
@@ -1011,6 +1064,21 @@ __tape_do_irq (struct ccw_device *cdev, 
 		return;
 	}
 
+	/*
+	 * If the condition code is not zero and the start function bit is
+	 * still set, this is an deferred error and the last start I/O did
+	 * not succeed. Restart the request now.
+	 */
+	if (irb->scsw.cc != 0 && (irb->scsw.fctl & SCSW_FCTL_START_FUNC)) {
+		PRINT_WARN("(%s): deferred cc=%i. restaring\n",
+			cdev->dev.bus_id,
+			irb->scsw.cc);
+		rc = __tape_start_io(device, request);
+		if (rc)
+			__tape_end_request(device, request, rc);
+		return;
+	}
+
 	/* May be an unsolicited irq */
 	if(request != NULL)
 		request->rescnt = irb->scsw.count;
@@ -1042,7 +1110,7 @@ __tape_do_irq (struct ccw_device *cdev, 
 	 * To detect these request the state will be set to TAPE_REQUEST_DONE.
 	 */
 	if(request != NULL && request->status == TAPE_REQUEST_DONE) {
-		__tape_remove_request(device, request);
+		__tape_end_request(device, request, -EIO);
 		return;
 	}
 
@@ -1054,51 +1122,34 @@ __tape_do_irq (struct ccw_device *cdev, 
 	 * rc == TAPE_IO_RETRY: request finished but needs another go.
 	 * rc == TAPE_IO_STOP: request needs to get terminated.
 	 */
-	final = 0;
 	switch (rc) {
-	case TAPE_IO_SUCCESS:
-		/* Upon normal completion the device _is_ online */
-		device->tape_generic_status |= GMT_ONLINE(~0);
-		final = 1;
-		break;
-	case TAPE_IO_PENDING:
-		break;
-	case TAPE_IO_RETRY:
-#ifdef CONFIG_S390_TAPE_BLOCK
-		if (request->op == TO_BLOCK)
-			device->discipline->check_locate(device, request);
-#endif
-		rc = ccw_device_start(cdev, request->cpaddr,
-				      (unsigned long) request, 0x00,
-				      request->options);
-		if (rc) {
-			DBF_EVENT(1, "tape: DOIO failed with er = %i\n", rc);
-			final = 1;
-		}
-		break;
-	case TAPE_IO_STOP:
-		__tape_halt_io(device, request);
-		break;
-	default:
-		if (rc > 0) {
-			DBF_EVENT(6, "xunknownrc\n");
-			PRINT_ERR("Invalid return code from discipline "
-				  "interrupt function.\n");
-			rc = -EIO;
-		}
-		final = 1;
-		break;
-	}
-	if (final) {
-		/* May be an unsolicited irq */
-		if(request != NULL) {
-			/* Set ending status. */
-			request->rc = rc;
-			request->status = TAPE_REQUEST_DONE;
-			__tape_remove_request(device, request);
-		} else {
-			__tape_do_io_list(device);
-		}
+		case TAPE_IO_SUCCESS:
+			/* Upon normal completion the device _is_ online */
+			device->tape_generic_status |= GMT_ONLINE(~0);
+			__tape_end_request(device, request, rc);
+			break;
+		case TAPE_IO_PENDING:
+			break;
+		case TAPE_IO_RETRY:
+			rc = __tape_start_io(device, request);
+			if (rc)
+				__tape_end_request(device, request, rc);
+			break;
+		case TAPE_IO_STOP:
+			rc = __tape_cancel_io(device, request);
+			if (rc)
+				__tape_end_request(device, request, rc);
+			break;
+		default:
+			if (rc > 0) {
+				DBF_EVENT(6, "xunknownrc\n");
+				PRINT_ERR("Invalid return code from discipline "
+				  	"interrupt function.\n");
+				__tape_end_request(device, request, -EIO);
+			} else {
+				__tape_end_request(device, request, rc);
+			}
+			break;
 	}
 }
 
@@ -1186,12 +1237,12 @@ tape_mtop(struct tape_device *device, in
 static int
 tape_init (void)
 {
-	TAPE_DBF_AREA = debug_register ( "tape", 1, 2, 4*sizeof(long));
+	TAPE_DBF_AREA = debug_register ( "tape", 2, 2, 4*sizeof(long));
 	debug_register_view(TAPE_DBF_AREA, &debug_sprintf_view);
 #ifdef DBF_LIKE_HELL
 	debug_set_level(TAPE_DBF_AREA, 6);
 #endif
-	DBF_EVENT(3, "tape init: ($Revision: 1.51 $)\n");
+	DBF_EVENT(3, "tape init: ($Revision: 1.54 $)\n");
 	tape_proc_init();
 	tapechar_init ();
 	tapeblock_init ();
@@ -1216,7 +1267,7 @@ tape_exit(void)
 MODULE_AUTHOR("(C) 2001 IBM Deutschland Entwicklung GmbH by Carsten Otte and "
 	      "Michael Holzheu (cotte@de.ibm.com,holzheu@de.ibm.com)");
 MODULE_DESCRIPTION("Linux on zSeries channel attached "
-		   "tape device driver ($Revision: 1.51 $)");
+		   "tape device driver ($Revision: 1.54 $)");
 MODULE_LICENSE("GPL");
 
 module_init(tape_init);
diff --git a/drivers/s390/char/tape_proc.c b/drivers/s390/char/tape_proc.c
--- a/drivers/s390/char/tape_proc.c
+++ b/drivers/s390/char/tape_proc.c
@@ -15,6 +15,7 @@
 #include <linux/module.h>
 #include <linux/vmalloc.h>
 #include <linux/seq_file.h>
+#include <linux/proc_fs.h>
 
 #define TAPE_DBF_AREA	tape_core_dbf
 
diff --git a/drivers/s390/char/vmcp.c b/drivers/s390/char/vmcp.c
new file mode 100644
--- /dev/null
+++ b/drivers/s390/char/vmcp.c
@@ -0,0 +1,219 @@
+/*
+ * Copyright (C) 2004,2005 IBM Corporation
+ * Interface implementation for communication with the v/VM control program
+ * Author(s): Christian Borntraeger <cborntra@de.ibm.com>
+ *
+ *
+ * z/VMs CP offers the possibility to issue commands via the diagnose code 8
+ * this driver implements a character device that issues these commands and
+ * returns the answer of CP.
+
+ * The idea of this driver is based on cpint from Neale Ferguson and #CP in CMS
+ */
+
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/miscdevice.h>
+#include <linux/module.h>
+#include <asm/cpcmd.h>
+#include <asm/debug.h>
+#include <asm/uaccess.h>
+#include "vmcp.h"
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Christian Borntraeger <cborntra@de.ibm.com>");
+MODULE_DESCRIPTION("z/VM CP interface");
+
+static debug_info_t *vmcp_debug;
+
+static int vmcp_open(struct inode *inode, struct file *file)
+{
+	struct vmcp_session *session;
+
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	session = kmalloc(sizeof(*session), GFP_KERNEL);
+	if (!session)
+		return -ENOMEM;
+	session->bufsize = PAGE_SIZE;
+	session->response = NULL;
+	session->resp_size = 0;
+	init_MUTEX(&session->mutex);
+	file->private_data = session;
+	return nonseekable_open(inode, file);
+}
+
+static int vmcp_release(struct inode *inode, struct file *file)
+{
+	struct vmcp_session *session;
+
+	session = (struct vmcp_session *)file->private_data;
+	file->private_data = NULL;
+	free_pages((unsigned long)session->response, get_order(session->bufsize));
+	kfree(session);
+	return 0;
+}
+
+static ssize_t
+vmcp_read(struct file *file, char __user * buff, size_t count, loff_t * ppos)
+{
+	size_t tocopy;
+	struct vmcp_session *session;
+
+	session = (struct vmcp_session *)file->private_data;
+	if (down_interruptible(&session->mutex))
+		return -ERESTARTSYS;
+	if (!session->response) {
+		up(&session->mutex);
+		return 0;
+	}
+	if (*ppos > session->resp_size) {
+		up(&session->mutex);
+		return 0;
+	}
+	tocopy = min(session->resp_size - (size_t) (*ppos), count);
+	tocopy = min(tocopy,session->bufsize - (size_t) (*ppos));
+
+	if (copy_to_user(buff, session->response + (*ppos), tocopy)) {
+		up(&session->mutex);
+		return -EFAULT;
+	}
+	up(&session->mutex);
+	*ppos += tocopy;
+	return tocopy;
+}
+
+static ssize_t
+vmcp_write(struct file *file, const char __user * buff, size_t count,
+	   loff_t * ppos)
+{
+	char *cmd;
+	struct vmcp_session *session;
+
+	if (count > 240)
+		return -EINVAL;
+	cmd = kmalloc(count + 1, GFP_KERNEL);
+	if (!cmd)
+		return -ENOMEM;
+	if (copy_from_user(cmd, buff, count)) {
+		kfree(cmd);
+		return -EFAULT;
+	}
+	cmd[count] = '\0';
+	session = (struct vmcp_session *)file->private_data;
+	if (down_interruptible(&session->mutex))
+		return -ERESTARTSYS;
+	if (!session->response)
+		session->response = (char *)__get_free_pages(GFP_KERNEL
+						| __GFP_REPEAT 	| GFP_DMA,
+						get_order(session->bufsize));
+	if (!session->response) {
+		up(&session->mutex);
+		kfree(cmd);
+		return -ENOMEM;
+	}
+	debug_text_event(vmcp_debug, 1, cmd);
+	session->resp_size = __cpcmd(cmd, session->response,
+				     session->bufsize,
+				     &session->resp_code);
+	up(&session->mutex);
+	kfree(cmd);
+	*ppos = 0;		/* reset the file pointer after a command */
+	return count;
+}
+
+
+/*
+ * These ioctls are available, as the semantics of the diagnose 8 call
+ * does not fit very well into a Linux call. Diagnose X'08' is described in
+ * CP Programming Services SC24-6084-00
+ *
+ * VMCP_GETCODE: gives the CP return code back to user space
+ * VMCP_SETBUF: sets the response buffer for the next write call. diagnose 8
+ * expects adjacent pages in real storage and to make matters worse, we
+ * dont know the size of the response. Therefore we default to PAGESIZE and
+ * let userspace to change the response size, if userspace expects a bigger
+ * response
+ */
+static long vmcp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+	struct vmcp_session *session;
+	int temp;
+
+	session = (struct vmcp_session *)file->private_data;
+	if (down_interruptible(&session->mutex))
+		return -ERESTARTSYS;
+	switch (cmd) {
+	case VMCP_GETCODE:
+		temp = session->resp_code;
+		up(&session->mutex);
+		return put_user(temp, (int __user *)arg);
+	case VMCP_SETBUF:
+		free_pages((unsigned long)session->response,
+				get_order(session->bufsize));
+		session->response=NULL;
+		temp = get_user(session->bufsize, (int __user *)arg);
+		if (get_order(session->bufsize) > 8) {
+			session->bufsize = PAGE_SIZE;
+			temp = -EINVAL;
+		}
+		up(&session->mutex);
+		return temp;
+	case VMCP_GETSIZE:
+		temp = session->resp_size;
+		up(&session->mutex);
+		return put_user(temp, (int __user *)arg);
+	default:
+		up(&session->mutex);
+		return -ENOIOCTLCMD;
+	}
+}
+
+static struct file_operations vmcp_fops = {
+	.owner		= THIS_MODULE,
+	.open		= &vmcp_open,
+	.release	= &vmcp_release,
+	.read		= &vmcp_read,
+	.llseek		= &no_llseek,
+	.write		= &vmcp_write,
+	.unlocked_ioctl	= &vmcp_ioctl,
+	.compat_ioctl	= &vmcp_ioctl
+};
+
+static struct miscdevice vmcp_dev = {
+	.name	= "vmcp",
+	.minor	= MISC_DYNAMIC_MINOR,
+	.fops	= &vmcp_fops,
+};
+
+static int __init vmcp_init(void)
+{
+	int ret;
+
+	if (!MACHINE_IS_VM) {
+		printk(KERN_WARNING
+		       "z/VM CP interface is only available under z/VM\n");
+		return -ENODEV;
+	}
+	ret = misc_register(&vmcp_dev);
+	if (!ret)
+		printk(KERN_INFO "z/VM CP interface loaded\n");
+	else
+		printk(KERN_WARNING
+		       "z/VM CP interface not loaded. Could not register misc device.\n");
+	vmcp_debug = debug_register("vmcp", 1, 1, 240);
+	debug_register_view(vmcp_debug, &debug_hex_ascii_view);
+	return ret;
+}
+
+static void __exit vmcp_exit(void)
+{
+	WARN_ON(misc_deregister(&vmcp_dev) != 0);
+	debug_unregister(vmcp_debug);
+	printk(KERN_INFO "z/VM CP interface unloaded.\n");
+}
+
+module_init(vmcp_init);
+module_exit(vmcp_exit);
diff --git a/drivers/s390/char/vmcp.h b/drivers/s390/char/vmcp.h
new file mode 100644
--- /dev/null
+++ b/drivers/s390/char/vmcp.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2004, 2005 IBM Corporation
+ * Interface implementation for communication with the v/VM control program
+ * Version 1.0
+ * Author(s): Christian Borntraeger <cborntra@de.ibm.com>
+ *
+ *
+ * z/VMs CP offers the possibility to issue commands via the diagnose code 8
+ * this driver implements a character device that issues these commands and
+ * returns the answer of CP.
+ *
+ * The idea of this driver is based on cpint from Neale Ferguson
+ */
+
+#include <asm/semaphore.h>
+#include <linux/ioctl.h>
+
+#define VMCP_GETCODE _IOR(0x10, 1, int)
+#define VMCP_SETBUF _IOW(0x10, 2, int)
+#define VMCP_GETSIZE _IOR(0x10, 3, int)
+
+struct vmcp_session {
+	unsigned int bufsize;
+	char *response;
+	int resp_size;
+	int resp_code;
+	/* As we use copy_from/to_user, which might     *
+	 * sleep and cannot use a spinlock              */
+	struct semaphore mutex;
+};
diff --git a/drivers/s390/char/vmlogrdr.c b/drivers/s390/char/vmlogrdr.c
--- a/drivers/s390/char/vmlogrdr.c
+++ b/drivers/s390/char/vmlogrdr.c
@@ -236,7 +236,7 @@ vmlogrdr_get_recording_class_AB(void) {
 	int len,i;
 
 	printk (KERN_DEBUG "vmlogrdr: query command: %s\n", cp_command);
-	cpcmd(cp_command, cp_response, sizeof(cp_response));
+	cpcmd(cp_command, cp_response, sizeof(cp_response), NULL);
 	printk (KERN_DEBUG "vmlogrdr: response: %s", cp_response);
 	len = strnlen(cp_response,sizeof(cp_response));
 	// now the parsing
@@ -288,7 +288,7 @@ vmlogrdr_recording(struct vmlogrdr_priv_
 
 		printk (KERN_DEBUG "vmlogrdr: recording command: %s\n",
 			cp_command);
-		cpcmd(cp_command, cp_response, sizeof(cp_response));
+		cpcmd(cp_command, cp_response, sizeof(cp_response), NULL);
 		printk (KERN_DEBUG "vmlogrdr: recording response: %s",
 			cp_response);
 	}
@@ -301,7 +301,7 @@ vmlogrdr_recording(struct vmlogrdr_priv_
 		qid_string);
 
 	printk (KERN_DEBUG "vmlogrdr: recording command: %s\n", cp_command);
-	cpcmd(cp_command, cp_response, sizeof(cp_response));
+	cpcmd(cp_command, cp_response, sizeof(cp_response), NULL);
 	printk (KERN_DEBUG "vmlogrdr: recording response: %s",
 		cp_response);
 	/* The recording command will usually answer with 'Command complete'
@@ -548,7 +548,7 @@ vmlogrdr_read (struct file *filp, char *
 }
 
 static ssize_t
-vmlogrdr_autopurge_store(struct device * dev, const char * buf, size_t count) {
+vmlogrdr_autopurge_store(struct device * dev, struct device_attribute *attr, const char * buf, size_t count) {
 	struct vmlogrdr_priv_t *priv = dev->driver_data;
 	ssize_t ret = count;
 
@@ -567,7 +567,7 @@ vmlogrdr_autopurge_store(struct device *
 
 
 static ssize_t
-vmlogrdr_autopurge_show(struct device *dev, char *buf) {
+vmlogrdr_autopurge_show(struct device *dev, struct device_attribute *attr, char *buf) {
 	struct vmlogrdr_priv_t *priv = dev->driver_data;
 	return sprintf(buf, "%u\n", priv->autopurge);
 }
@@ -578,7 +578,7 @@ static DEVICE_ATTR(autopurge, 0644, vmlo
 
 
 static ssize_t
-vmlogrdr_purge_store(struct device * dev, const char * buf, size_t count) {
+vmlogrdr_purge_store(struct device * dev, struct device_attribute *attr, const char * buf, size_t count) {
 
 	char cp_command[80];
 	char cp_response[80];
@@ -607,7 +607,7 @@ vmlogrdr_purge_store(struct device * dev
 			 priv->recording_name);
 
 	printk (KERN_DEBUG "vmlogrdr: recording command: %s\n", cp_command);
-	cpcmd(cp_command, cp_response, sizeof(cp_response));
+	cpcmd(cp_command, cp_response, sizeof(cp_response), NULL);
 	printk (KERN_DEBUG "vmlogrdr: recording response: %s",
 		cp_response);
 
@@ -619,7 +619,7 @@ static DEVICE_ATTR(purge, 0200, NULL, vm
 
 
 static ssize_t
-vmlogrdr_autorecording_store(struct device *dev, const char *buf,
+vmlogrdr_autorecording_store(struct device *dev, struct device_attribute *attr, const char *buf,
 			     size_t count) {
 	struct vmlogrdr_priv_t *priv = dev->driver_data;
 	ssize_t ret = count;
@@ -639,7 +639,7 @@ vmlogrdr_autorecording_store(struct devi
 
 
 static ssize_t
-vmlogrdr_autorecording_show(struct device *dev, char *buf) {
+vmlogrdr_autorecording_show(struct device *dev, struct device_attribute *attr, char *buf) {
 	struct vmlogrdr_priv_t *priv = dev->driver_data;
 	return sprintf(buf, "%u\n", priv->autorecording);
 }
@@ -650,7 +650,7 @@ static DEVICE_ATTR(autorecording, 0644, 
 
 
 static ssize_t
-vmlogrdr_recording_store(struct device * dev, const char * buf, size_t count) {
+vmlogrdr_recording_store(struct device * dev, struct device_attribute *attr, const char * buf, size_t count) {
 
 	struct vmlogrdr_priv_t *priv = dev->driver_data;
 	ssize_t ret;
@@ -682,7 +682,7 @@ vmlogrdr_recording_status_show(struct de
 	char cp_command[] = "QUERY RECORDING ";
 	int len;
 
-	cpcmd(cp_command, buf, 4096);
+	cpcmd(cp_command, buf, 4096, NULL);
 	len = strlen(buf);
 	return len;
 }
@@ -703,7 +703,7 @@ static struct attribute_group vmlogrdr_a
 	.attrs = vmlogrdr_attrs,
 };
 
-static struct class_simple *vmlogrdr_class;
+static struct class *vmlogrdr_class;
 static struct device_driver vmlogrdr_driver = {
 	.name = "vmlogrdr",
 	.bus  = &iucv_bus,
@@ -727,7 +727,7 @@ vmlogrdr_register_driver(void) {
 		goto unregdriver;
 	}
 
-	vmlogrdr_class = class_simple_create(THIS_MODULE, "vmlogrdr");
+	vmlogrdr_class = class_create(THIS_MODULE, "vmlogrdr");
 	if (IS_ERR(vmlogrdr_class)) {
 		printk(KERN_ERR "vmlogrdr: failed to create class.\n");
 		ret=PTR_ERR(vmlogrdr_class);
@@ -746,7 +746,7 @@ unregdriver:
 
 static void
 vmlogrdr_unregister_driver(void) {
-	class_simple_destroy(vmlogrdr_class);
+	class_destroy(vmlogrdr_class);
 	vmlogrdr_class = NULL;
 	driver_remove_file(&vmlogrdr_driver, &driver_attr_recording_status);
 	driver_unregister(&vmlogrdr_driver);
@@ -786,7 +786,7 @@ vmlogrdr_register_device(struct vmlogrdr
 		device_unregister(dev);
 		return ret;
 	}
-	priv->class_device = class_simple_device_add(
+	priv->class_device = class_device_create(
 				vmlogrdr_class,
 				MKDEV(vmlogrdr_major, priv->minor_num),
 				dev,
@@ -806,7 +806,7 @@ vmlogrdr_register_device(struct vmlogrdr
 
 static int
 vmlogrdr_unregister_device(struct vmlogrdr_priv_t *priv ) {
-	class_simple_device_remove(MKDEV(vmlogrdr_major, priv->minor_num));
+	class_device_destroy(vmlogrdr_class, MKDEV(vmlogrdr_major, priv->minor_num));
 	if (priv->device != NULL) {
 		sysfs_remove_group(&priv->device->kobj, &vmlogrdr_attr_group);
 		device_unregister(priv->device);
diff --git a/drivers/s390/char/vmwatchdog.c b/drivers/s390/char/vmwatchdog.c
--- a/drivers/s390/char/vmwatchdog.c
+++ b/drivers/s390/char/vmwatchdog.c
@@ -23,11 +23,7 @@
 static char vmwdt_cmd[MAX_CMDLEN] = "IPL";
 static int vmwdt_conceal;
 
-#ifdef CONFIG_WATCHDOG_NOWAYOUT
-static int vmwdt_nowayout = 1;
-#else
-static int vmwdt_nowayout = 0;
-#endif
+static int vmwdt_nowayout = WATCHDOG_NOWAYOUT;
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Arnd Bergmann <arndb@de.ibm.com>");
diff --git a/drivers/s390/cio/blacklist.c b/drivers/s390/cio/blacklist.c
--- a/drivers/s390/cio/blacklist.c
+++ b/drivers/s390/cio/blacklist.c
@@ -1,7 +1,7 @@
 /*
  *  drivers/s390/cio/blacklist.c
  *   S/390 common I/O routines -- blacklisting of specific devices
- *   $Revision: 1.33 $
+ *   $Revision: 1.34 $
  *
  *    Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH,
  *			      IBM Corporation
@@ -289,7 +289,7 @@ static int cio_ignore_read (char *page, 
 	len = 0;
 	for (devno = off; /* abuse the page variable
 			   * as counter, see fs/proc/generic.c */
-	     devno <= __MAX_SUBCHANNELS && len + entry_size < count; devno++) {
+	     devno < __MAX_SUBCHANNELS && len + entry_size < count; devno++) {
 		if (!test_bit(devno, bl_dev))
 			continue;
 		len += sprintf(page + len, "0.0.%04lx", devno);
@@ -302,7 +302,7 @@ static int cio_ignore_read (char *page, 
 		len += sprintf(page + len, "\n");
 	}
 
-	if (devno <= __MAX_SUBCHANNELS)
+	if (devno < __MAX_SUBCHANNELS)
 		*eof = 1;
 	*start = (char *) (devno - off); /* number of checked entries */
 	return len;
diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c
--- a/drivers/s390/cio/ccwgroup.c
+++ b/drivers/s390/cio/ccwgroup.c
@@ -77,7 +77,7 @@ __ccwgroup_remove_symlinks(struct ccwgro
  * longer needed or accidentially created. Saves memory :)
  */
 static ssize_t
-ccwgroup_ungroup_store(struct device *dev, const char *buf, size_t count)
+ccwgroup_ungroup_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct ccwgroup_device *gdev;
 
@@ -310,7 +310,7 @@ ccwgroup_set_offline(struct ccwgroup_dev
 }
 
 static ssize_t
-ccwgroup_online_store (struct device *dev, const char *buf, size_t count)
+ccwgroup_online_store (struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct ccwgroup_device *gdev;
 	struct ccwgroup_driver *gdrv;
@@ -338,7 +338,7 @@ ccwgroup_online_store (struct device *de
 }
 
 static ssize_t
-ccwgroup_online_show (struct device *dev, char *buf)
+ccwgroup_online_show (struct device *dev, struct device_attribute *attr, char *buf)
 {
 	int online;
 
@@ -403,34 +403,22 @@ ccwgroup_driver_register (struct ccwgrou
 	return driver_register(&cdriver->driver);
 }
 
-static inline struct device *
-__get_next_ccwgroup_device(struct device_driver *drv)
+static int
+__ccwgroup_driver_unregister_device(struct device *dev, void *data)
 {
-	struct device *dev, *d;
-
-	down_read(&drv->bus->subsys.rwsem);
-	dev = NULL;
-	list_for_each_entry(d, &drv->devices, driver_list) {
-		dev = get_device(d);
-		if (dev)
-			break;
-	}
-	up_read(&drv->bus->subsys.rwsem);
-	return dev;
+	__ccwgroup_remove_symlinks(to_ccwgroupdev(dev));
+	device_unregister(dev);
+	put_device(dev);
+	return 0;
 }
 
 void
 ccwgroup_driver_unregister (struct ccwgroup_driver *cdriver)
 {
-	struct device *dev;
-
 	/* We don't want ccwgroup devices to live longer than their driver. */
 	get_driver(&cdriver->driver);
-	while ((dev = __get_next_ccwgroup_device(&cdriver->driver))) {
-		__ccwgroup_remove_symlinks(to_ccwgroupdev(dev));
-		device_unregister(dev);
-		put_device(dev);
-	};
+	driver_for_each_device(&cdriver->driver, NULL, NULL,
+			       __ccwgroup_driver_unregister_device);
 	put_driver(&cdriver->driver);
 	driver_unregister(&cdriver->driver);
 }
@@ -449,7 +437,7 @@ __ccwgroup_get_gdev_by_cdev(struct ccw_d
 	if (cdev->dev.driver_data) {
 		gdev = (struct ccwgroup_device *)cdev->dev.driver_data;
 		if (get_device(&gdev->dev)) {
-			if (!list_empty(&gdev->dev.node))
+			if (klist_node_attached(&gdev->dev.knode_bus))
 				return gdev;
 			put_device(&gdev->dev);
 		}
diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c
--- a/drivers/s390/cio/chsc.c
+++ b/drivers/s390/cio/chsc.c
@@ -1,7 +1,7 @@
 /*
  *  drivers/s390/cio/chsc.c
  *   S/390 common I/O routines -- channel subsystem call
- *   $Revision: 1.119 $
+ *   $Revision: 1.120 $
  *
  *    Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH,
  *			      IBM Corporation
@@ -412,11 +412,7 @@ s390_process_res_acc (u8 chpid, __u16 fl
 		if (chp_mask == 0) {
 
 			spin_unlock_irq(&sch->lock);
-
-			if (fla_mask != 0)
-				break;
-			else
-				continue;
+			continue;
 		}
 		old_lpm = sch->lpm;
 		sch->lpm = ((sch->schib.pmcw.pim &
@@ -430,7 +426,7 @@ s390_process_res_acc (u8 chpid, __u16 fl
 
 		spin_unlock_irq(&sch->lock);
 		put_device(&sch->dev);
-		if (fla_mask != 0)
+		if (fla_mask == 0xffff)
 			break;
 	}
 	return rc;
@@ -852,7 +848,7 @@ out:
  * Files for the channel path entries.
  */
 static ssize_t
-chp_status_show(struct device *dev, char *buf)
+chp_status_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct channel_path *chp = container_of(dev, struct channel_path, dev);
 
@@ -863,7 +859,7 @@ chp_status_show(struct device *dev, char
 }
 
 static ssize_t
-chp_status_write(struct device *dev, const char *buf, size_t count)
+chp_status_write(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct channel_path *cp = container_of(dev, struct channel_path, dev);
 	char cmd[10];
@@ -888,7 +884,7 @@ chp_status_write(struct device *dev, con
 static DEVICE_ATTR(status, 0644, chp_status_show, chp_status_write);
 
 static ssize_t
-chp_type_show(struct device *dev, char *buf)
+chp_type_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct channel_path *chp = container_of(dev, struct channel_path, dev);
 
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c
--- a/drivers/s390/cio/cio.c
+++ b/drivers/s390/cio/cio.c
@@ -1,7 +1,7 @@
 /*
  *  drivers/s390/cio/cio.c
  *   S/390 common I/O routines -- low level i/o calls
- *   $Revision: 1.133 $
+ *   $Revision: 1.134 $
  *
  *    Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH,
  *			      IBM Corporation
@@ -63,17 +63,17 @@ __setup ("cio_msg=", cio_setup);
 static int __init
 cio_debug_init (void)
 {
-	cio_debug_msg_id = debug_register ("cio_msg", 4, 4, 16*sizeof (long));
+	cio_debug_msg_id = debug_register ("cio_msg", 16, 4, 16*sizeof (long));
 	if (!cio_debug_msg_id)
 		goto out_unregister;
 	debug_register_view (cio_debug_msg_id, &debug_sprintf_view);
 	debug_set_level (cio_debug_msg_id, 2);
-	cio_debug_trace_id = debug_register ("cio_trace", 4, 4, 8);
+	cio_debug_trace_id = debug_register ("cio_trace", 16, 4, 8);
 	if (!cio_debug_trace_id)
 		goto out_unregister;
 	debug_register_view (cio_debug_trace_id, &debug_hex_ascii_view);
 	debug_set_level (cio_debug_trace_id, 2);
-	cio_debug_crw_id = debug_register ("cio_crw", 2, 4, 16*sizeof (long));
+	cio_debug_crw_id = debug_register ("cio_crw", 4, 4, 16*sizeof (long));
 	if (!cio_debug_crw_id)
 		goto out_unregister;
 	debug_register_view (cio_debug_crw_id, &debug_sprintf_view);
diff --git a/drivers/s390/cio/cmf.c b/drivers/s390/cio/cmf.c
--- a/drivers/s390/cio/cmf.c
+++ b/drivers/s390/cio/cmf.c
@@ -796,7 +796,7 @@ cmb_show_attr(struct device *dev, char *
 }
 
 static ssize_t
-cmb_show_avg_sample_interval(struct device *dev, char *buf)
+cmb_show_avg_sample_interval(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct ccw_device *cdev;
 	long interval;
@@ -813,7 +813,7 @@ cmb_show_avg_sample_interval(struct devi
 }
 
 static ssize_t
-cmb_show_avg_utilization(struct device *dev, char *buf)
+cmb_show_avg_utilization(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct cmbdata data;
 	u64 utilization;
@@ -842,12 +842,12 @@ cmb_show_avg_utilization(struct device *
 }
 
 #define cmf_attr(name) \
-static ssize_t show_ ## name (struct device * dev, char * buf) \
+static ssize_t show_ ## name (struct device * dev, struct device_attribute *attr, char * buf) \
 { return cmb_show_attr((dev), buf, cmb_ ## name); } \
 static DEVICE_ATTR(name, 0444, show_ ## name, NULL);
 
 #define cmf_attr_avg(name) \
-static ssize_t show_avg_ ## name (struct device * dev, char * buf) \
+static ssize_t show_avg_ ## name (struct device * dev, struct device_attribute *attr, char * buf) \
 { return cmb_show_attr((dev), buf, cmb_ ## name); } \
 static DEVICE_ATTR(avg_ ## name, 0444, show_avg_ ## name, NULL);
 
@@ -902,12 +902,12 @@ static struct attribute_group cmf_attr_g
 	.attrs = cmf_attributes_ext,
 };
 
-static ssize_t cmb_enable_show(struct device *dev, char *buf)
+static ssize_t cmb_enable_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	return sprintf(buf, "%d\n", to_ccwdev(dev)->private->cmb ? 1 : 0);
 }
 
-static ssize_t cmb_enable_store(struct device *dev, const char *buf, size_t c)
+static ssize_t cmb_enable_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t c)
 {
 	struct ccw_device *cdev;
 	int ret;
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c
--- a/drivers/s390/cio/css.c
+++ b/drivers/s390/cio/css.c
@@ -128,34 +128,28 @@ css_probe_device(int irq)
 	return ret;
 }
 
+static int
+check_subchannel(struct device * dev, void * data)
+{
+	struct subchannel *sch;
+	int irq = (unsigned long)data;
+
+	sch = to_subchannel(dev);
+	return (sch->irq == irq);
+}
+
 struct subchannel *
 get_subchannel_by_schid(int irq)
 {
-	struct subchannel *sch;
-	struct list_head *entry;
 	struct device *dev;
 
-	if (!get_bus(&css_bus_type))
-		return NULL;
-	down_read(&css_bus_type.subsys.rwsem);
-	sch = NULL;
-	list_for_each(entry, &css_bus_type.devices.list) {
-		dev = get_device(container_of(entry,
-					      struct device, bus_list));
-		if (!dev)
-			continue;
-		sch = to_subchannel(dev);
-		if (sch->irq == irq)
-			break;
-		put_device(dev);
-		sch = NULL;
-	}
-	up_read(&css_bus_type.subsys.rwsem);
-	put_bus(&css_bus_type);
+	dev = bus_find_device(&css_bus_type, NULL,
+			      (void *)(unsigned long)irq, check_subchannel);
 
-	return sch;
+	return dev ? to_subchannel(dev) : NULL;
 }
 
+
 static inline int
 css_get_subchannel_status(struct subchannel *sch, int schid)
 {
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -204,7 +204,7 @@ module_exit(cleanup_ccw_bus_type);
  * TODO: Split chpids and pimpampom up? Where is "in use" in the tree?
  */
 static ssize_t
-chpids_show (struct device * dev, char * buf)
+chpids_show (struct device * dev, struct device_attribute *attr, char * buf)
 {
 	struct subchannel *sch = to_subchannel(dev);
 	struct ssd_info *ssd = &sch->ssd_info;
@@ -219,7 +219,7 @@ chpids_show (struct device * dev, char *
 }
 
 static ssize_t
-pimpampom_show (struct device * dev, char * buf)
+pimpampom_show (struct device * dev, struct device_attribute *attr, char * buf)
 {
 	struct subchannel *sch = to_subchannel(dev);
 	struct pmcw *pmcw = &sch->schib.pmcw;
@@ -229,7 +229,7 @@ pimpampom_show (struct device * dev, cha
 }
 
 static ssize_t
-devtype_show (struct device *dev, char *buf)
+devtype_show (struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct ccw_device *cdev = to_ccwdev(dev);
 	struct ccw_device_id *id = &(cdev->id);
@@ -242,7 +242,7 @@ devtype_show (struct device *dev, char *
 }
 
 static ssize_t
-cutype_show (struct device *dev, char *buf)
+cutype_show (struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct ccw_device *cdev = to_ccwdev(dev);
 	struct ccw_device_id *id = &(cdev->id);
@@ -252,7 +252,7 @@ cutype_show (struct device *dev, char *b
 }
 
 static ssize_t
-online_show (struct device *dev, char *buf)
+online_show (struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct ccw_device *cdev = to_ccwdev(dev);
 
@@ -350,7 +350,7 @@ ccw_device_set_online(struct ccw_device 
 }
 
 static ssize_t
-online_store (struct device *dev, const char *buf, size_t count)
+online_store (struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct ccw_device *cdev = to_ccwdev(dev);
 	int i, force, ret;
@@ -422,7 +422,7 @@ online_store (struct device *dev, const 
 }
 
 static ssize_t
-available_show (struct device *dev, char *buf)
+available_show (struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct ccw_device *cdev = to_ccwdev(dev);
 	struct subchannel *sch;
@@ -514,36 +514,39 @@ ccw_device_register(struct ccw_device *c
 	return ret;
 }
 
+struct match_data {
+	unsigned int  devno;
+	struct ccw_device * sibling;
+};
+
+static int
+match_devno(struct device * dev, void * data)
+{
+	struct match_data * d = (struct match_data *)data;
+	struct ccw_device * cdev;
+
+	cdev = to_ccwdev(dev);
+	if ((cdev->private->state == DEV_STATE_DISCONNECTED) &&
+	    (cdev->private->devno == d->devno) &&
+	    (cdev != d->sibling)) {
+		cdev->private->state = DEV_STATE_NOT_OPER;
+		return 1;
+	}
+	return 0;
+}
+
 static struct ccw_device *
 get_disc_ccwdev_by_devno(unsigned int devno, struct ccw_device *sibling)
 {
-	struct ccw_device *cdev;
-	struct list_head *entry;
 	struct device *dev;
+	struct match_data data = {
+		.devno  = devno,
+		.sibling = sibling,
+	};
 
-	if (!get_bus(&ccw_bus_type))
-		return NULL;
-	down_read(&ccw_bus_type.subsys.rwsem);
-	cdev = NULL;
-	list_for_each(entry, &ccw_bus_type.devices.list) {
-		dev = get_device(container_of(entry,
-					      struct device, bus_list));
-		if (!dev)
-			continue;
-		cdev = to_ccwdev(dev);
-		if ((cdev->private->state == DEV_STATE_DISCONNECTED) &&
-		    (cdev->private->devno == devno) &&
-		    (cdev != sibling)) {
-			cdev->private->state = DEV_STATE_NOT_OPER;
-			break;
-		}
-		put_device(dev);
-		cdev = NULL;
-	}
-	up_read(&ccw_bus_type.subsys.rwsem);
-	put_bus(&ccw_bus_type);
+	dev = bus_find_device(&css_bus_type, NULL, &data, match_devno);
 
-	return cdev;
+	return dev ? to_ccwdev(dev) : NULL;
 }
 
 static void
@@ -647,7 +650,7 @@ io_subchannel_register(void *data)
 	cdev = (struct ccw_device *) data;
 	sch = to_subchannel(cdev->dev.parent);
 
-	if (!list_empty(&sch->dev.children)) {
+	if (klist_node_attached(&cdev->dev.knode_parent)) {
 		bus_rescan_devices(&ccw_bus_type);
 		goto out;
 	}
@@ -1019,30 +1022,29 @@ ccw_device_probe_console(void)
 /*
  * get ccw_device matching the busid, but only if owned by cdrv
  */
+static int
+__ccwdev_check_busid(struct device *dev, void *id)
+{
+	char *bus_id;
+
+	bus_id = (char *)id;
+
+	return (strncmp(bus_id, dev->bus_id, BUS_ID_SIZE) == 0);
+}
+
+
 struct ccw_device *
 get_ccwdev_by_busid(struct ccw_driver *cdrv, const char *bus_id)
 {
-	struct device *d, *dev;
+	struct device *dev;
 	struct device_driver *drv;
 
 	drv = get_driver(&cdrv->driver);
 	if (!drv)
-		return 0;
-
-	down_read(&drv->bus->subsys.rwsem);
-
-	dev = NULL;
-	list_for_each_entry(d, &drv->devices, driver_list) {
-		dev = get_device(d);
+		return NULL;
 
-		if (dev && !strncmp(bus_id, dev->bus_id, BUS_ID_SIZE))
-			break;
-		else if (dev) {
-			put_device(dev);
-			dev = NULL;
-		}
-	}
-	up_read(&drv->bus->subsys.rwsem);
+	dev = driver_find_device(drv, NULL, (void *)bus_id,
+				 __ccwdev_check_busid);
 	put_driver(drv);
 
 	return dev ? to_ccwdev(dev) : 0;
diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c
--- a/drivers/s390/cio/device_fsm.c
+++ b/drivers/s390/cio/device_fsm.c
@@ -235,6 +235,9 @@ ccw_device_recog_done(struct ccw_device 
 		sch->schib.pmcw.pam &
 		sch->schib.pmcw.pom &
 		sch->opm;
+	/* Check since device may again have become not operational. */
+	if (!sch->schib.pmcw.dnv)
+		state = DEV_STATE_NOT_OPER;
 	if (cdev->private->state == DEV_STATE_DISCONNECTED_SENSE_ID)
 		/* Force reprobe on all chpids. */
 		old_lpm = 0;
diff --git a/drivers/s390/cio/device_status.c b/drivers/s390/cio/device_status.c
--- a/drivers/s390/cio/device_status.c
+++ b/drivers/s390/cio/device_status.c
@@ -39,15 +39,14 @@ ccw_device_msg_control_check(struct ccw_
 		      " ... device %04X on subchannel %04X, dev_stat "
 		      ": %02X sch_stat : %02X\n",
 		      cdev->private->devno, cdev->private->irq,
-		      cdev->private->irb.scsw.dstat,
-		      cdev->private->irb.scsw.cstat);
+		      irb->scsw.dstat, irb->scsw.cstat);
 
 	if (irb->scsw.cc != 3) {
 		char dbf_text[15];
 
 		sprintf(dbf_text, "chk%x", cdev->private->irq);
 		CIO_TRACE_EVENT(0, dbf_text);
-		CIO_HEX_EVENT(0, &cdev->private->irb, sizeof (struct irb));
+		CIO_HEX_EVENT(0, irb, sizeof (struct irb));
 	}
 }
 
diff --git a/drivers/s390/cio/qdio.c b/drivers/s390/cio/qdio.c
--- a/drivers/s390/cio/qdio.c
+++ b/drivers/s390/cio/qdio.c
@@ -56,7 +56,7 @@
 #include "ioasm.h"
 #include "chsc.h"
 
-#define VERSION_QDIO_C "$Revision: 1.98 $"
+#define VERSION_QDIO_C "$Revision: 1.101 $"
 
 /****************** MODULE PARAMETER VARIABLES ********************/
 MODULE_AUTHOR("Utz Bacher <utz.bacher@de.ibm.com>");
@@ -112,7 +112,7 @@ qdio_min(int a,int b)
 
 /***************** SCRUBBER HELPER ROUTINES **********************/
 
-static inline volatile __u64 
+static inline __u64 
 qdio_get_micros(void)
 {
         return (get_clock() >> 10); /* time>>12 is microseconds */
@@ -230,7 +230,7 @@ qdio_siga_input(struct qdio_q *q)
 }
 
 /* locked by the locks in qdio_activate and qdio_cleanup */
-static __u32 * volatile 
+static __u32 volatile *
 qdio_get_indicator(void)
 {
 	int i;
@@ -432,7 +432,7 @@ tiqdio_clear_global_summary(void)
 
 /************************* OUTBOUND ROUTINES *******************************/
 
-inline static int
+static inline int
 qdio_get_outbound_buffer_frontier(struct qdio_q *q)
 {
 	int f,f_mod_no;
@@ -510,7 +510,7 @@ out:
 }
 
 /* all buffers are processed */
-inline static int
+static inline int
 qdio_is_outbound_q_done(struct qdio_q *q)
 {
 	int no_used;
@@ -532,7 +532,7 @@ qdio_is_outbound_q_done(struct qdio_q *q
 	return (no_used==0);
 }
 
-inline static int
+static inline int
 qdio_has_outbound_q_moved(struct qdio_q *q)
 {
 	int i;
@@ -552,7 +552,7 @@ qdio_has_outbound_q_moved(struct qdio_q 
 	}
 }
 
-inline static void
+static inline void
 qdio_kick_outbound_q(struct qdio_q *q)
 {
 	int result;
@@ -641,7 +641,7 @@ qdio_kick_outbound_q(struct qdio_q *q)
 		}
 }
 
-inline static void
+static inline void
 qdio_kick_outbound_handler(struct qdio_q *q)
 {
 	int start, end, real_end, count;
@@ -740,7 +740,7 @@ qdio_outbound_processing(struct qdio_q *
 /************************* INBOUND ROUTINES *******************************/
 
 
-inline static int
+static inline int
 qdio_get_inbound_buffer_frontier(struct qdio_q *q)
 {
 	int f,f_mod_no;
@@ -865,7 +865,7 @@ out:
 	return q->first_to_check;
 }
 
-inline static int
+static inline int
 qdio_has_inbound_q_moved(struct qdio_q *q)
 {
 	int i;
@@ -898,7 +898,7 @@ qdio_has_inbound_q_moved(struct qdio_q *
 }
 
 /* means, no more buffers to be filled */
-inline static int
+static inline int
 tiqdio_is_inbound_q_done(struct qdio_q *q)
 {
 	int no_used;
@@ -951,7 +951,7 @@ tiqdio_is_inbound_q_done(struct qdio_q *
 	return 0;
 }
 
-inline static int
+static inline int
 qdio_is_inbound_q_done(struct qdio_q *q)
 {
 	int no_used;
@@ -1010,7 +1010,7 @@ qdio_is_inbound_q_done(struct qdio_q *q)
 	}
 }
 
-inline static void
+static inline void
 qdio_kick_inbound_handler(struct qdio_q *q)
 {
 	int count, start, end, real_end, i;
@@ -3342,7 +3342,7 @@ static int
 qdio_register_dbf_views(void)
 {
 	qdio_dbf_setup=debug_register(QDIO_DBF_SETUP_NAME,
-				      QDIO_DBF_SETUP_INDEX,
+				      QDIO_DBF_SETUP_PAGES,
 				      QDIO_DBF_SETUP_NR_AREAS,
 				      QDIO_DBF_SETUP_LEN);
 	if (!qdio_dbf_setup)
@@ -3351,7 +3351,7 @@ qdio_register_dbf_views(void)
 	debug_set_level(qdio_dbf_setup,QDIO_DBF_SETUP_LEVEL);
 
 	qdio_dbf_sbal=debug_register(QDIO_DBF_SBAL_NAME,
-				     QDIO_DBF_SBAL_INDEX,
+				     QDIO_DBF_SBAL_PAGES,
 				     QDIO_DBF_SBAL_NR_AREAS,
 				     QDIO_DBF_SBAL_LEN);
 	if (!qdio_dbf_sbal)
@@ -3361,7 +3361,7 @@ qdio_register_dbf_views(void)
 	debug_set_level(qdio_dbf_sbal,QDIO_DBF_SBAL_LEVEL);
 
 	qdio_dbf_sense=debug_register(QDIO_DBF_SENSE_NAME,
-				      QDIO_DBF_SENSE_INDEX,
+				      QDIO_DBF_SENSE_PAGES,
 				      QDIO_DBF_SENSE_NR_AREAS,
 				      QDIO_DBF_SENSE_LEN);
 	if (!qdio_dbf_sense)
@@ -3371,7 +3371,7 @@ qdio_register_dbf_views(void)
 	debug_set_level(qdio_dbf_sense,QDIO_DBF_SENSE_LEVEL);
 
 	qdio_dbf_trace=debug_register(QDIO_DBF_TRACE_NAME,
-				      QDIO_DBF_TRACE_INDEX,
+				      QDIO_DBF_TRACE_PAGES,
 				      QDIO_DBF_TRACE_NR_AREAS,
 				      QDIO_DBF_TRACE_LEN);
 	if (!qdio_dbf_trace)
@@ -3382,7 +3382,7 @@ qdio_register_dbf_views(void)
 
 #ifdef CONFIG_QDIO_DEBUG
         qdio_dbf_slsb_out=debug_register(QDIO_DBF_SLSB_OUT_NAME,
-                                         QDIO_DBF_SLSB_OUT_INDEX,
+                                         QDIO_DBF_SLSB_OUT_PAGES,
                                          QDIO_DBF_SLSB_OUT_NR_AREAS,
                                          QDIO_DBF_SLSB_OUT_LEN);
         if (!qdio_dbf_slsb_out)
@@ -3391,7 +3391,7 @@ qdio_register_dbf_views(void)
         debug_set_level(qdio_dbf_slsb_out,QDIO_DBF_SLSB_OUT_LEVEL);
 
         qdio_dbf_slsb_in=debug_register(QDIO_DBF_SLSB_IN_NAME,
-                                        QDIO_DBF_SLSB_IN_INDEX,
+                                        QDIO_DBF_SLSB_IN_PAGES,
                                         QDIO_DBF_SLSB_IN_NR_AREAS,
                                         QDIO_DBF_SLSB_IN_LEN);
         if (!qdio_dbf_slsb_in)
diff --git a/drivers/s390/cio/qdio.h b/drivers/s390/cio/qdio.h
--- a/drivers/s390/cio/qdio.h
+++ b/drivers/s390/cio/qdio.h
@@ -3,7 +3,7 @@
 
 #include <asm/page.h>
 
-#define VERSION_CIO_QDIO_H "$Revision: 1.32 $"
+#define VERSION_CIO_QDIO_H "$Revision: 1.33 $"
 
 #ifdef CONFIG_QDIO_DEBUG
 #define QDIO_VERBOSE_LEVEL 9
@@ -132,7 +132,7 @@ enum qdio_irq_states {
 
 #define QDIO_DBF_SETUP_NAME "qdio_setup"
 #define QDIO_DBF_SETUP_LEN 8
-#define QDIO_DBF_SETUP_INDEX 2
+#define QDIO_DBF_SETUP_PAGES 4
 #define QDIO_DBF_SETUP_NR_AREAS 1
 #ifdef CONFIG_QDIO_DEBUG
 #define QDIO_DBF_SETUP_LEVEL 6
@@ -142,7 +142,7 @@ enum qdio_irq_states {
 
 #define QDIO_DBF_SBAL_NAME "qdio_labs" /* sbal */
 #define QDIO_DBF_SBAL_LEN 256
-#define QDIO_DBF_SBAL_INDEX 2
+#define QDIO_DBF_SBAL_PAGES 4
 #define QDIO_DBF_SBAL_NR_AREAS 2
 #ifdef CONFIG_QDIO_DEBUG
 #define QDIO_DBF_SBAL_LEVEL 6
@@ -154,16 +154,16 @@ enum qdio_irq_states {
 #define QDIO_DBF_TRACE_LEN 8
 #define QDIO_DBF_TRACE_NR_AREAS 2
 #ifdef CONFIG_QDIO_DEBUG
-#define QDIO_DBF_TRACE_INDEX 4
+#define QDIO_DBF_TRACE_PAGES 16
 #define QDIO_DBF_TRACE_LEVEL 4 /* -------- could be even more verbose here */
 #else /* CONFIG_QDIO_DEBUG */
-#define QDIO_DBF_TRACE_INDEX 2
+#define QDIO_DBF_TRACE_PAGES 4
 #define QDIO_DBF_TRACE_LEVEL 2
 #endif /* CONFIG_QDIO_DEBUG */
 
 #define QDIO_DBF_SENSE_NAME "qdio_sense"
 #define QDIO_DBF_SENSE_LEN 64
-#define QDIO_DBF_SENSE_INDEX 1
+#define QDIO_DBF_SENSE_PAGES 2
 #define QDIO_DBF_SENSE_NR_AREAS 1
 #ifdef CONFIG_QDIO_DEBUG
 #define QDIO_DBF_SENSE_LEVEL 6
@@ -176,13 +176,13 @@ enum qdio_irq_states {
 
 #define QDIO_DBF_SLSB_OUT_NAME "qdio_slsb_out"
 #define QDIO_DBF_SLSB_OUT_LEN QDIO_MAX_BUFFERS_PER_Q
-#define QDIO_DBF_SLSB_OUT_INDEX 8
+#define QDIO_DBF_SLSB_OUT_PAGES 256
 #define QDIO_DBF_SLSB_OUT_NR_AREAS 1
 #define QDIO_DBF_SLSB_OUT_LEVEL 6
 
 #define QDIO_DBF_SLSB_IN_NAME "qdio_slsb_in"
 #define QDIO_DBF_SLSB_IN_LEN QDIO_MAX_BUFFERS_PER_Q
-#define QDIO_DBF_SLSB_IN_INDEX 8
+#define QDIO_DBF_SLSB_IN_PAGES 256
 #define QDIO_DBF_SLSB_IN_NR_AREAS 1
 #define QDIO_DBF_SLSB_IN_LEVEL 6
 #endif /* CONFIG_QDIO_DEBUG */
diff --git a/drivers/s390/crypto/z90crypt.h b/drivers/s390/crypto/z90crypt.h
--- a/drivers/s390/crypto/z90crypt.h
+++ b/drivers/s390/crypto/z90crypt.h
@@ -36,15 +36,6 @@
 #define z90crypt_VARIANT 2	// 2 = added PCIXCC MCL3 and CEX2C support
 
 /**
- * If we are not using the sparse checker, __user has no use.
- */
-#ifdef __CHECKER__
-# define __user		__attribute__((noderef, address_space(1)))
-#else
-# define __user
-#endif
-
-/**
  * struct ica_rsa_modexpo
  *
  * Requirements:
diff --git a/drivers/s390/net/claw.c b/drivers/s390/net/claw.c
--- a/drivers/s390/net/claw.c
+++ b/drivers/s390/net/claw.c
@@ -146,8 +146,8 @@ claw_unregister_debug_facility(void)
 static int
 claw_register_debug_facility(void)
 {
-	claw_dbf_setup = debug_register("claw_setup", 1, 1, 8);
-	claw_dbf_trace = debug_register("claw_trace", 1, 2, 8);
+	claw_dbf_setup = debug_register("claw_setup", 2, 1, 8);
+	claw_dbf_trace = debug_register("claw_trace", 2, 2, 8);
 	if (claw_dbf_setup == NULL || claw_dbf_trace == NULL) {
 		printk(KERN_WARNING "Not enough memory for debug facility.\n");
 		claw_unregister_debug_facility();
@@ -241,20 +241,20 @@ static struct sk_buff *claw_pack_skb(str
 static void dumpit (char *buf, int len);
 #endif
 /* sysfs Functions */
-static ssize_t claw_hname_show(struct device *dev, char *buf);
-static ssize_t claw_hname_write(struct device *dev,
+static ssize_t claw_hname_show(struct device *dev, struct device_attribute *attr, char *buf);
+static ssize_t claw_hname_write(struct device *dev, struct device_attribute *attr,
 	const char *buf, size_t count);
-static ssize_t claw_adname_show(struct device *dev, char *buf);
-static ssize_t claw_adname_write(struct device *dev,
+static ssize_t claw_adname_show(struct device *dev, struct device_attribute *attr, char *buf);
+static ssize_t claw_adname_write(struct device *dev, struct device_attribute *attr,
 	const char *buf, size_t count);
-static ssize_t claw_apname_show(struct device *dev, char *buf);
-static ssize_t claw_apname_write(struct device *dev,
+static ssize_t claw_apname_show(struct device *dev, struct device_attribute *attr, char *buf);
+static ssize_t claw_apname_write(struct device *dev, struct device_attribute *attr,
 	const char *buf, size_t count);
-static ssize_t claw_wbuff_show(struct device *dev, char *buf);
-static ssize_t claw_wbuff_write(struct device *dev,
+static ssize_t claw_wbuff_show(struct device *dev, struct device_attribute *attr, char *buf);
+static ssize_t claw_wbuff_write(struct device *dev, struct device_attribute *attr,
 	const char *buf, size_t count);
-static ssize_t claw_rbuff_show(struct device *dev, char *buf);
-static ssize_t claw_rbuff_write(struct device *dev,
+static ssize_t claw_rbuff_show(struct device *dev, struct device_attribute *attr, char *buf);
+static ssize_t claw_rbuff_write(struct device *dev, struct device_attribute *attr,
 	const char *buf, size_t count);
 static int claw_add_files(struct device *dev);
 static void claw_remove_files(struct device *dev);
@@ -428,7 +428,7 @@ claw_pack_skb(struct claw_privbk *privpt
 	new_skb = NULL;		/* assume no dice */
 	pkt_cnt = 0;
 	CLAW_DBF_TEXT(4,trace,"PackSKBe");
-	if (skb_queue_len(&p_ch->collect_queue) > 0) {
+	if (!skb_queue_empty(&p_ch->collect_queue)) {
 	/* some data */
 		held_skb = skb_dequeue(&p_ch->collect_queue);
 		if (p_env->packing != DO_PACKED)
@@ -1254,7 +1254,7 @@ claw_write_next ( struct chbk * p_ch )
 	privptr = (struct claw_privbk *) dev->priv;
         claw_free_wrt_buf( dev );
 	if ((privptr->write_free_count > 0) &&
-	    (skb_queue_len(&p_ch->collect_queue) > 0)) {
+	    !skb_queue_empty(&p_ch->collect_queue)) {
 	  	pk_skb = claw_pack_skb(privptr);
 		while (pk_skb != NULL) {
 			rc = claw_hw_tx( pk_skb, dev,1);
@@ -4149,7 +4149,7 @@ claw_remove_device(struct ccwgroup_devic
  * sysfs attributes
  */
 static ssize_t
-claw_hname_show(struct device *dev, char *buf)
+claw_hname_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct claw_privbk *priv;
 	struct claw_env *  p_env;
@@ -4162,7 +4162,7 @@ claw_hname_show(struct device *dev, char
 }
 
 static ssize_t
-claw_hname_write(struct device *dev, const char *buf, size_t count)
+claw_hname_write(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct claw_privbk *priv;
 	struct claw_env *  p_env;
@@ -4186,7 +4186,7 @@ claw_hname_write(struct device *dev, con
 static DEVICE_ATTR(host_name, 0644, claw_hname_show, claw_hname_write);
 
 static ssize_t
-claw_adname_show(struct device *dev, char *buf)
+claw_adname_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct claw_privbk *priv;
 	struct claw_env *  p_env;
@@ -4199,7 +4199,7 @@ claw_adname_show(struct device *dev, cha
 }
 
 static ssize_t
-claw_adname_write(struct device *dev, const char *buf, size_t count)
+claw_adname_write(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct claw_privbk *priv;
 	struct claw_env *  p_env;
@@ -4223,7 +4223,7 @@ claw_adname_write(struct device *dev, co
 static DEVICE_ATTR(adapter_name, 0644, claw_adname_show, claw_adname_write);
 
 static ssize_t
-claw_apname_show(struct device *dev, char *buf)
+claw_apname_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct claw_privbk *priv;
 	struct claw_env *  p_env;
@@ -4237,7 +4237,7 @@ claw_apname_show(struct device *dev, cha
 }
 
 static ssize_t
-claw_apname_write(struct device *dev, const char *buf, size_t count)
+claw_apname_write(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct claw_privbk *priv;
 	struct claw_env *  p_env;
@@ -4271,7 +4271,7 @@ claw_apname_write(struct device *dev, co
 static DEVICE_ATTR(api_type, 0644, claw_apname_show, claw_apname_write);
 
 static ssize_t
-claw_wbuff_show(struct device *dev, char *buf)
+claw_wbuff_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct claw_privbk *priv;
 	struct claw_env * p_env;
@@ -4284,7 +4284,7 @@ claw_wbuff_show(struct device *dev, char
 }
 
 static ssize_t
-claw_wbuff_write(struct device *dev, const char *buf, size_t count)
+claw_wbuff_write(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct claw_privbk *priv;
 	struct claw_env *  p_env;
@@ -4312,7 +4312,7 @@ claw_wbuff_write(struct device *dev, con
 static DEVICE_ATTR(write_buffer, 0644, claw_wbuff_show, claw_wbuff_write);
 
 static ssize_t
-claw_rbuff_show(struct device *dev, char *buf)
+claw_rbuff_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct claw_privbk *priv;
 	struct claw_env *  p_env;
@@ -4325,7 +4325,7 @@ claw_rbuff_show(struct device *dev, char
 }
 
 static ssize_t
-claw_rbuff_write(struct device *dev, const char *buf, size_t count)
+claw_rbuff_write(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct claw_privbk *priv;
 	struct claw_env *p_env;
diff --git a/drivers/s390/net/ctcdbug.c b/drivers/s390/net/ctcdbug.c
--- a/drivers/s390/net/ctcdbug.c
+++ b/drivers/s390/net/ctcdbug.c
@@ -1,6 +1,6 @@
 /*
  *
- * linux/drivers/s390/net/ctcdbug.c ($Revision: 1.4 $)
+ * linux/drivers/s390/net/ctcdbug.c ($Revision: 1.6 $)
  *
  * CTC / ESCON network driver - s390 dbf exploit.
  *
@@ -9,7 +9,7 @@
  *    Author(s): Original Code written by
  *			  Peter Tiedemann (ptiedem@de.ibm.com)
  *
- *    $Revision: 1.4 $	 $Date: 2004/08/04 10:11:59 $
+ *    $Revision: 1.6 $	 $Date: 2005/05/11 08:10:17 $
  *
  * 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
@@ -51,15 +51,15 @@ int
 ctc_register_dbf_views(void)
 {
 	ctc_dbf_setup = debug_register(CTC_DBF_SETUP_NAME,
-					CTC_DBF_SETUP_INDEX,
+					CTC_DBF_SETUP_PAGES,
 					CTC_DBF_SETUP_NR_AREAS,
 					CTC_DBF_SETUP_LEN);
 	ctc_dbf_data = debug_register(CTC_DBF_DATA_NAME,
-				       CTC_DBF_DATA_INDEX,
+				       CTC_DBF_DATA_PAGES,
 				       CTC_DBF_DATA_NR_AREAS,
 				       CTC_DBF_DATA_LEN);
 	ctc_dbf_trace = debug_register(CTC_DBF_TRACE_NAME,
-					CTC_DBF_TRACE_INDEX,
+					CTC_DBF_TRACE_PAGES,
 					CTC_DBF_TRACE_NR_AREAS,
 					CTC_DBF_TRACE_LEN);
 
diff --git a/drivers/s390/net/ctcdbug.h b/drivers/s390/net/ctcdbug.h
--- a/drivers/s390/net/ctcdbug.h
+++ b/drivers/s390/net/ctcdbug.h
@@ -1,6 +1,6 @@
 /*
  *
- * linux/drivers/s390/net/ctcdbug.h ($Revision: 1.5 $)
+ * linux/drivers/s390/net/ctcdbug.h ($Revision: 1.6 $)
  *
  * CTC / ESCON network driver - s390 dbf exploit.
  *
@@ -9,7 +9,7 @@
  *    Author(s): Original Code written by
  *			  Peter Tiedemann (ptiedem@de.ibm.com)
  *
- *    $Revision: 1.5 $	 $Date: 2005/02/27 19:46:44 $
+ *    $Revision: 1.6 $	 $Date: 2005/05/11 08:10:17 $
  *
  * 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
@@ -35,19 +35,19 @@
  */
 #define CTC_DBF_SETUP_NAME "ctc_setup"
 #define CTC_DBF_SETUP_LEN 16
-#define CTC_DBF_SETUP_INDEX 3
+#define CTC_DBF_SETUP_PAGES 8
 #define CTC_DBF_SETUP_NR_AREAS 1
 #define CTC_DBF_SETUP_LEVEL 3
 
 #define CTC_DBF_DATA_NAME "ctc_data"
 #define CTC_DBF_DATA_LEN 128
-#define CTC_DBF_DATA_INDEX 3
+#define CTC_DBF_DATA_PAGES 8
 #define CTC_DBF_DATA_NR_AREAS 1
 #define CTC_DBF_DATA_LEVEL 3
 
 #define CTC_DBF_TRACE_NAME "ctc_trace"
 #define CTC_DBF_TRACE_LEN 16
-#define CTC_DBF_TRACE_INDEX 2
+#define CTC_DBF_TRACE_PAGES 4
 #define CTC_DBF_TRACE_NR_AREAS 2
 #define CTC_DBF_TRACE_LEVEL 3
 
diff --git a/drivers/s390/net/ctcmain.c b/drivers/s390/net/ctcmain.c
--- a/drivers/s390/net/ctcmain.c
+++ b/drivers/s390/net/ctcmain.c
@@ -2469,7 +2469,7 @@ ctc_stats(struct net_device * dev)
  */
 
 static ssize_t
-buffer_show(struct device *dev, char *buf)
+buffer_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct ctc_priv *priv;
 
@@ -2481,7 +2481,7 @@ buffer_show(struct device *dev, char *bu
 }
 
 static ssize_t
-buffer_write(struct device *dev, const char *buf, size_t count)
+buffer_write(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct ctc_priv *priv;
 	struct net_device *ndev;
@@ -2530,13 +2530,13 @@ einval:
 }
 
 static ssize_t
-loglevel_show(struct device *dev, char *buf)
+loglevel_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	return sprintf(buf, "%d\n", loglevel);
 }
 
 static ssize_t
-loglevel_write(struct device *dev, const char *buf, size_t count)
+loglevel_write(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	int ll1;
 
@@ -2589,7 +2589,7 @@ ctc_print_statistics(struct ctc_priv *pr
 }
 
 static ssize_t
-stats_show(struct device *dev, char *buf)
+stats_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct ctc_priv *priv = dev->driver_data;
 	if (!priv)
@@ -2599,7 +2599,7 @@ stats_show(struct device *dev, char *buf
 }
 
 static ssize_t
-stats_write(struct device *dev, const char *buf, size_t count)
+stats_write(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct ctc_priv *priv = dev->driver_data;
 	if (!priv)
@@ -2654,7 +2654,7 @@ ctc_free_netdevice(struct net_device * d
 }
 
 static ssize_t
-ctc_proto_show(struct device *dev, char *buf)
+ctc_proto_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct ctc_priv *priv;
 
@@ -2666,7 +2666,7 @@ ctc_proto_show(struct device *dev, char 
 }
 
 static ssize_t
-ctc_proto_store(struct device *dev, const char *buf, size_t count)
+ctc_proto_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct ctc_priv *priv;
 	int value;
@@ -2687,7 +2687,7 @@ ctc_proto_store(struct device *dev, cons
 
 
 static ssize_t
-ctc_type_show(struct device *dev, char *buf)
+ctc_type_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct ccwgroup_device *cgdev;
 
diff --git a/drivers/s390/net/ctctty.c b/drivers/s390/net/ctctty.c
--- a/drivers/s390/net/ctctty.c
+++ b/drivers/s390/net/ctctty.c
@@ -156,7 +156,7 @@ ctc_tty_readmodem(ctc_tty_info *info)
 					skb_queue_head(&info->rx_queue, skb);
 				else {
 					kfree_skb(skb);
-					ret = skb_queue_len(&info->rx_queue);
+					ret = !skb_queue_empty(&info->rx_queue);
 				}
 			}
 		}
@@ -530,7 +530,7 @@ ctc_tty_write(struct tty_struct *tty, co
 		total += c;
 		count -= c;
 	}
-	if (skb_queue_len(&info->tx_queue)) {
+	if (!skb_queue_empty(&info->tx_queue)) {
 		info->lsr &= ~UART_LSR_TEMT;
 		tasklet_schedule(&info->tasklet);
 	}
@@ -594,7 +594,7 @@ ctc_tty_flush_chars(struct tty_struct *t
 		return;
 	if (ctc_tty_paranoia_check(info, tty->name, "ctc_tty_flush_chars"))
 		return;
-	if (tty->stopped || tty->hw_stopped || (!skb_queue_len(&info->tx_queue)))
+	if (tty->stopped || tty->hw_stopped || skb_queue_empty(&info->tx_queue))
 		return;
 	tasklet_schedule(&info->tasklet);
 }
diff --git a/drivers/s390/net/iucv.h b/drivers/s390/net/iucv.h
--- a/drivers/s390/net/iucv.h
+++ b/drivers/s390/net/iucv.h
@@ -37,19 +37,19 @@
  */
 #define IUCV_DBF_SETUP_NAME "iucv_setup"
 #define IUCV_DBF_SETUP_LEN 32
-#define IUCV_DBF_SETUP_INDEX 1
+#define IUCV_DBF_SETUP_PAGES 2
 #define IUCV_DBF_SETUP_NR_AREAS 1
 #define IUCV_DBF_SETUP_LEVEL 3
 
 #define IUCV_DBF_DATA_NAME "iucv_data"
 #define IUCV_DBF_DATA_LEN 128
-#define IUCV_DBF_DATA_INDEX 1
+#define IUCV_DBF_DATA_PAGES 2
 #define IUCV_DBF_DATA_NR_AREAS 1
 #define IUCV_DBF_DATA_LEVEL 2
 
 #define IUCV_DBF_TRACE_NAME "iucv_trace"
 #define IUCV_DBF_TRACE_LEN 16
-#define IUCV_DBF_TRACE_INDEX 2
+#define IUCV_DBF_TRACE_PAGES 4
 #define IUCV_DBF_TRACE_NR_AREAS 1
 #define IUCV_DBF_TRACE_LEVEL 3
 
diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c
--- a/drivers/s390/net/lcs.c
+++ b/drivers/s390/net/lcs.c
@@ -11,7 +11,7 @@
  *			  Frank Pavlic (pavlic@de.ibm.com) and
  *		 	  Martin Schwidefsky <schwidefsky@de.ibm.com>
  *
- *    $Revision: 1.98 $	 $Date: 2005/04/18 13:41:29 $
+ *    $Revision: 1.99 $	 $Date: 2005/05/11 08:10:17 $
  *
  * 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
@@ -59,7 +59,7 @@
 /**
  * initialization string for output
  */
-#define VERSION_LCS_C  "$Revision: 1.98 $"
+#define VERSION_LCS_C  "$Revision: 1.99 $"
 
 static char version[] __initdata = "LCS driver ("VERSION_LCS_C "/" VERSION_LCS_H ")";
 static char debug_buffer[255];
@@ -93,8 +93,8 @@ lcs_unregister_debug_facility(void)
 static int
 lcs_register_debug_facility(void)
 {
-	lcs_dbf_setup = debug_register("lcs_setup", 1, 1, 8);
-	lcs_dbf_trace = debug_register("lcs_trace", 1, 2, 8);
+	lcs_dbf_setup = debug_register("lcs_setup", 2, 1, 8);
+	lcs_dbf_trace = debug_register("lcs_trace", 2, 2, 8);
 	if (lcs_dbf_setup == NULL || lcs_dbf_trace == NULL) {
 		PRINT_ERR("Not enough memory for debug facility.\n");
 		lcs_unregister_debug_facility();
@@ -1984,7 +1984,7 @@ lcs_open_device(struct net_device *dev)
  * show function for portno called by cat or similar things
  */
 static ssize_t
-lcs_portno_show (struct device *dev, char *buf)
+lcs_portno_show (struct device *dev, struct device_attribute *attr, char *buf)
 {
         struct lcs_card *card;
 
@@ -2000,7 +2000,7 @@ lcs_portno_show (struct device *dev, cha
  * store the value which is piped to file portno
  */
 static ssize_t
-lcs_portno_store (struct device *dev, const char *buf, size_t count)
+lcs_portno_store (struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
         struct lcs_card *card;
         int value;
@@ -2021,7 +2021,7 @@ lcs_portno_store (struct device *dev, co
 static DEVICE_ATTR(portno, 0644, lcs_portno_show, lcs_portno_store);
 
 static ssize_t
-lcs_type_show(struct device *dev, char *buf)
+lcs_type_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct ccwgroup_device *cgdev;
 
@@ -2035,7 +2035,7 @@ lcs_type_show(struct device *dev, char *
 static DEVICE_ATTR(type, 0444, lcs_type_show, NULL);
 
 static ssize_t
-lcs_timeout_show(struct device *dev, char *buf)
+lcs_timeout_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct lcs_card *card;
 
@@ -2045,7 +2045,7 @@ lcs_timeout_show(struct device *dev, cha
 }
 
 static ssize_t
-lcs_timeout_store (struct device *dev, const char *buf, size_t count)
+lcs_timeout_store (struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
         struct lcs_card *card;
         int value;
diff --git a/drivers/s390/net/netiucv.c b/drivers/s390/net/netiucv.c
--- a/drivers/s390/net/netiucv.c
+++ b/drivers/s390/net/netiucv.c
@@ -1,5 +1,5 @@
 /*
- * $Id: netiucv.c,v 1.63 2004/07/27 13:36:05 mschwide Exp $
+ * $Id: netiucv.c,v 1.66 2005/05/11 08:10:17 holzheu Exp $
  *
  * IUCV network driver
  *
@@ -30,7 +30,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- * RELEASE-TAG: IUCV network driver $Revision: 1.63 $
+ * RELEASE-TAG: IUCV network driver $Revision: 1.66 $
  *
  */
 
@@ -391,15 +391,15 @@ static int
 iucv_register_dbf_views(void)
 {
 	iucv_dbf_setup = debug_register(IUCV_DBF_SETUP_NAME,
-					IUCV_DBF_SETUP_INDEX,
+					IUCV_DBF_SETUP_PAGES,
 					IUCV_DBF_SETUP_NR_AREAS,
 					IUCV_DBF_SETUP_LEN);
 	iucv_dbf_data = debug_register(IUCV_DBF_DATA_NAME,
-				       IUCV_DBF_DATA_INDEX,
+				       IUCV_DBF_DATA_PAGES,
 				       IUCV_DBF_DATA_NR_AREAS,
 				       IUCV_DBF_DATA_LEN);
 	iucv_dbf_trace = debug_register(IUCV_DBF_TRACE_NAME,
-					IUCV_DBF_TRACE_INDEX,
+					IUCV_DBF_TRACE_PAGES,
 					IUCV_DBF_TRACE_NR_AREAS,
 					IUCV_DBF_TRACE_LEN);
 
@@ -1356,7 +1356,7 @@ netiucv_change_mtu (struct net_device * 
  *****************************************************************************/
 
 static ssize_t
-user_show (struct device *dev, char *buf)
+user_show (struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct netiucv_priv *priv = dev->driver_data;
 
@@ -1365,7 +1365,7 @@ user_show (struct device *dev, char *buf
 }
 
 static ssize_t
-user_write (struct device *dev, const char *buf, size_t count)
+user_write (struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct netiucv_priv *priv = dev->driver_data;
 	struct net_device *ndev = priv->conn->netdev;
@@ -1422,7 +1422,7 @@ user_write (struct device *dev, const ch
 static DEVICE_ATTR(user, 0644, user_show, user_write);
 
 static ssize_t
-buffer_show (struct device *dev, char *buf)
+buffer_show (struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct netiucv_priv *priv = dev->driver_data;
 
@@ -1431,7 +1431,7 @@ buffer_show (struct device *dev, char *b
 }
 
 static ssize_t
-buffer_write (struct device *dev, const char *buf, size_t count)
+buffer_write (struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct netiucv_priv *priv = dev->driver_data;
 	struct net_device *ndev = priv->conn->netdev;
@@ -1486,7 +1486,7 @@ buffer_write (struct device *dev, const 
 static DEVICE_ATTR(buffer, 0644, buffer_show, buffer_write);
 
 static ssize_t
-dev_fsm_show (struct device *dev, char *buf)
+dev_fsm_show (struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct netiucv_priv *priv = dev->driver_data;
 
@@ -1497,7 +1497,7 @@ dev_fsm_show (struct device *dev, char *
 static DEVICE_ATTR(device_fsm_state, 0444, dev_fsm_show, NULL);
 
 static ssize_t
-conn_fsm_show (struct device *dev, char *buf)
+conn_fsm_show (struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct netiucv_priv *priv = dev->driver_data;
 
@@ -1508,7 +1508,7 @@ conn_fsm_show (struct device *dev, char 
 static DEVICE_ATTR(connection_fsm_state, 0444, conn_fsm_show, NULL);
 
 static ssize_t
-maxmulti_show (struct device *dev, char *buf)
+maxmulti_show (struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct netiucv_priv *priv = dev->driver_data;
 
@@ -1517,7 +1517,7 @@ maxmulti_show (struct device *dev, char 
 }
 
 static ssize_t
-maxmulti_write (struct device *dev, const char *buf, size_t count)
+maxmulti_write (struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct netiucv_priv *priv = dev->driver_data;
 
@@ -1529,7 +1529,7 @@ maxmulti_write (struct device *dev, cons
 static DEVICE_ATTR(max_tx_buffer_used, 0644, maxmulti_show, maxmulti_write);
 
 static ssize_t
-maxcq_show (struct device *dev, char *buf)
+maxcq_show (struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct netiucv_priv *priv = dev->driver_data;
 
@@ -1538,7 +1538,7 @@ maxcq_show (struct device *dev, char *bu
 }
 
 static ssize_t
-maxcq_write (struct device *dev, const char *buf, size_t count)
+maxcq_write (struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct netiucv_priv *priv = dev->driver_data;
 	
@@ -1550,7 +1550,7 @@ maxcq_write (struct device *dev, const c
 static DEVICE_ATTR(max_chained_skbs, 0644, maxcq_show, maxcq_write);
 
 static ssize_t
-sdoio_show (struct device *dev, char *buf)
+sdoio_show (struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct netiucv_priv *priv = dev->driver_data;
 
@@ -1559,7 +1559,7 @@ sdoio_show (struct device *dev, char *bu
 }
 
 static ssize_t
-sdoio_write (struct device *dev, const char *buf, size_t count)
+sdoio_write (struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct netiucv_priv *priv = dev->driver_data;
 	
@@ -1571,7 +1571,7 @@ sdoio_write (struct device *dev, const c
 static DEVICE_ATTR(tx_single_write_ops, 0644, sdoio_show, sdoio_write);
 
 static ssize_t
-mdoio_show (struct device *dev, char *buf)
+mdoio_show (struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct netiucv_priv *priv = dev->driver_data;
 
@@ -1580,7 +1580,7 @@ mdoio_show (struct device *dev, char *bu
 }
 
 static ssize_t
-mdoio_write (struct device *dev, const char *buf, size_t count)
+mdoio_write (struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct netiucv_priv *priv = dev->driver_data;
 	
@@ -1592,7 +1592,7 @@ mdoio_write (struct device *dev, const c
 static DEVICE_ATTR(tx_multi_write_ops, 0644, mdoio_show, mdoio_write);
 
 static ssize_t
-txlen_show (struct device *dev, char *buf)
+txlen_show (struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct netiucv_priv *priv = dev->driver_data;
 
@@ -1601,7 +1601,7 @@ txlen_show (struct device *dev, char *bu
 }
 
 static ssize_t
-txlen_write (struct device *dev, const char *buf, size_t count)
+txlen_write (struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct netiucv_priv *priv = dev->driver_data;
 	
@@ -1613,7 +1613,7 @@ txlen_write (struct device *dev, const c
 static DEVICE_ATTR(netto_bytes, 0644, txlen_show, txlen_write);
 
 static ssize_t
-txtime_show (struct device *dev, char *buf)
+txtime_show (struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct netiucv_priv *priv = dev->driver_data;
 
@@ -1622,7 +1622,7 @@ txtime_show (struct device *dev, char *b
 }
 
 static ssize_t
-txtime_write (struct device *dev, const char *buf, size_t count)
+txtime_write (struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct netiucv_priv *priv = dev->driver_data;
 	
@@ -1634,7 +1634,7 @@ txtime_write (struct device *dev, const 
 static DEVICE_ATTR(max_tx_io_time, 0644, txtime_show, txtime_write);
 
 static ssize_t
-txpend_show (struct device *dev, char *buf)
+txpend_show (struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct netiucv_priv *priv = dev->driver_data;
 
@@ -1643,7 +1643,7 @@ txpend_show (struct device *dev, char *b
 }
 
 static ssize_t
-txpend_write (struct device *dev, const char *buf, size_t count)
+txpend_write (struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct netiucv_priv *priv = dev->driver_data;
 
@@ -1655,7 +1655,7 @@ txpend_write (struct device *dev, const 
 static DEVICE_ATTR(tx_pending, 0644, txpend_show, txpend_write);
 
 static ssize_t
-txmpnd_show (struct device *dev, char *buf)
+txmpnd_show (struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct netiucv_priv *priv = dev->driver_data;
 
@@ -1664,7 +1664,7 @@ txmpnd_show (struct device *dev, char *b
 }
 
 static ssize_t
-txmpnd_write (struct device *dev, const char *buf, size_t count)
+txmpnd_write (struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct netiucv_priv *priv = dev->driver_data;
 
@@ -2076,7 +2076,7 @@ DRIVER_ATTR(remove, 0200, NULL, remove_w
 static void
 netiucv_banner(void)
 {
-	char vbuf[] = "$Revision: 1.63 $";
+	char vbuf[] = "$Revision: 1.66 $";
 	char *version = vbuf;
 
 	if ((version = strchr(version, ':'))) {
diff --git a/drivers/s390/net/qeth.h b/drivers/s390/net/qeth.h
--- a/drivers/s390/net/qeth.h
+++ b/drivers/s390/net/qeth.h
@@ -42,44 +42,44 @@
  */
 #define QETH_DBF_SETUP_NAME "qeth_setup"
 #define QETH_DBF_SETUP_LEN 8
-#define QETH_DBF_SETUP_INDEX 3
+#define QETH_DBF_SETUP_PAGES 8
 #define QETH_DBF_SETUP_NR_AREAS 1
 #define QETH_DBF_SETUP_LEVEL 5
 
 #define QETH_DBF_MISC_NAME "qeth_misc"
 #define QETH_DBF_MISC_LEN 128
-#define QETH_DBF_MISC_INDEX 1
+#define QETH_DBF_MISC_PAGES 2
 #define QETH_DBF_MISC_NR_AREAS 1
 #define QETH_DBF_MISC_LEVEL 2
 
 #define QETH_DBF_DATA_NAME "qeth_data"
 #define QETH_DBF_DATA_LEN 96
-#define QETH_DBF_DATA_INDEX 3
+#define QETH_DBF_DATA_PAGES 8
 #define QETH_DBF_DATA_NR_AREAS 1
 #define QETH_DBF_DATA_LEVEL 2
 
 #define QETH_DBF_CONTROL_NAME "qeth_control"
 #define QETH_DBF_CONTROL_LEN 256
-#define QETH_DBF_CONTROL_INDEX 3
+#define QETH_DBF_CONTROL_PAGES 8
 #define QETH_DBF_CONTROL_NR_AREAS 2
 #define QETH_DBF_CONTROL_LEVEL 5
 
 #define QETH_DBF_TRACE_NAME "qeth_trace"
 #define QETH_DBF_TRACE_LEN 8
-#define QETH_DBF_TRACE_INDEX 2
+#define QETH_DBF_TRACE_PAGES 4
 #define QETH_DBF_TRACE_NR_AREAS 2
 #define QETH_DBF_TRACE_LEVEL 3
 extern debug_info_t *qeth_dbf_trace;
 
 #define QETH_DBF_SENSE_NAME "qeth_sense"
 #define QETH_DBF_SENSE_LEN 64
-#define QETH_DBF_SENSE_INDEX 1
+#define QETH_DBF_SENSE_PAGES 2
 #define QETH_DBF_SENSE_NR_AREAS 1
 #define QETH_DBF_SENSE_LEVEL 2
 
 #define QETH_DBF_QERR_NAME "qeth_qerr"
 #define QETH_DBF_QERR_LEN 8
-#define QETH_DBF_QERR_INDEX 1
+#define QETH_DBF_QERR_PAGES 2
 #define QETH_DBF_QERR_NR_AREAS 2
 #define QETH_DBF_QERR_LEVEL 2
 
@@ -824,7 +824,7 @@ extern struct list_head qeth_notify_list
 
 #define QETH_CARD_IFNAME(card) (((card)->dev)? (card)->dev->name : "")
 
-inline static __u8
+static inline __u8
 qeth_get_ipa_adp_type(enum qeth_link_types link_type)
 {
 	switch (link_type) {
@@ -835,7 +835,7 @@ qeth_get_ipa_adp_type(enum qeth_link_typ
 	}
 }
 
-inline static int
+static inline int
 qeth_realloc_headroom(struct qeth_card *card, struct sk_buff **skb, int size)
 {
 	struct sk_buff *new_skb = NULL;
@@ -852,6 +852,7 @@ qeth_realloc_headroom(struct qeth_card *
 	}
 	return 0;
 }
+
 static inline struct sk_buff *
 qeth_pskb_unshare(struct sk_buff *skb, int pri)
 {
@@ -863,8 +864,7 @@ qeth_pskb_unshare(struct sk_buff *skb, i
         return nskb;
 }
 
-
-inline static void *
+static inline void *
 qeth_push_skb(struct qeth_card *card, struct sk_buff **skb, int size)
 {
         void *hdr;
@@ -887,7 +887,7 @@ qeth_push_skb(struct qeth_card *card, st
 }
 
 
-inline static int
+static inline int
 qeth_get_hlen(__u8 link_type)
 {
 #ifdef CONFIG_QETH_IPV6
@@ -911,7 +911,7 @@ qeth_get_hlen(__u8 link_type)
 #endif /* CONFIG_QETH_IPV6 */
 }
 
-inline static unsigned short
+static inline unsigned short
 qeth_get_netdev_flags(struct qeth_card *card)
 {
 	if (card->options.layer2)
@@ -929,7 +929,7 @@ qeth_get_netdev_flags(struct qeth_card *
 	}
 }
 
-inline static int
+static inline int
 qeth_get_initial_mtu_for_card(struct qeth_card * card)
 {
 	switch (card->info.type) {
@@ -950,7 +950,7 @@ qeth_get_initial_mtu_for_card(struct qet
 	}
 }
 
-inline static int
+static inline int
 qeth_get_max_mtu_for_card(int cardtype)
 {
 	switch (cardtype) {
@@ -965,7 +965,7 @@ qeth_get_max_mtu_for_card(int cardtype)
 	}
 }
 
-inline static int
+static inline int
 qeth_get_mtu_out_of_mpc(int cardtype)
 {
 	switch (cardtype) {
@@ -976,7 +976,7 @@ qeth_get_mtu_out_of_mpc(int cardtype)
 	}
 }
 
-inline static int
+static inline int
 qeth_get_mtu_outof_framesize(int framesize)
 {
 	switch (framesize) {
@@ -993,7 +993,7 @@ qeth_get_mtu_outof_framesize(int framesi
 	}
 }
 
-inline static int
+static inline int
 qeth_mtu_is_valid(struct qeth_card * card, int mtu)
 {
 	switch (card->info.type) {
@@ -1008,7 +1008,7 @@ qeth_mtu_is_valid(struct qeth_card * car
 	}
 }
 
-inline static int
+static inline int
 qeth_get_arphdr_type(int cardtype, int linktype)
 {
 	switch (cardtype) {
@@ -1027,7 +1027,7 @@ qeth_get_arphdr_type(int cardtype, int l
 }
 
 #ifdef CONFIG_QETH_PERF_STATS
-inline static int
+static inline int
 qeth_get_micros(void)
 {
 	return (int) (get_clock() >> 12);
diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c
--- a/drivers/s390/net/qeth_main.c
+++ b/drivers/s390/net/qeth_main.c
@@ -2210,7 +2210,7 @@ no_mem:
 	return NULL;
 }
 
-static inline unsigned short
+static inline __be16
 qeth_type_trans(struct sk_buff *skb, struct net_device *dev)
 {
 	struct qeth_card *card;
@@ -7639,31 +7639,31 @@ static int
 qeth_register_dbf_views(void)
 {
 	qeth_dbf_setup = debug_register(QETH_DBF_SETUP_NAME,
-					QETH_DBF_SETUP_INDEX,
+					QETH_DBF_SETUP_PAGES,
 					QETH_DBF_SETUP_NR_AREAS,
 					QETH_DBF_SETUP_LEN);
 	qeth_dbf_misc = debug_register(QETH_DBF_MISC_NAME,
-				       QETH_DBF_MISC_INDEX,
+				       QETH_DBF_MISC_PAGES,
 				       QETH_DBF_MISC_NR_AREAS,
 				       QETH_DBF_MISC_LEN);
 	qeth_dbf_data = debug_register(QETH_DBF_DATA_NAME,
-				       QETH_DBF_DATA_INDEX,
+				       QETH_DBF_DATA_PAGES,
 				       QETH_DBF_DATA_NR_AREAS,
 				       QETH_DBF_DATA_LEN);
 	qeth_dbf_control = debug_register(QETH_DBF_CONTROL_NAME,
-					  QETH_DBF_CONTROL_INDEX,
+					  QETH_DBF_CONTROL_PAGES,
 					  QETH_DBF_CONTROL_NR_AREAS,
 					  QETH_DBF_CONTROL_LEN);
 	qeth_dbf_sense = debug_register(QETH_DBF_SENSE_NAME,
-					QETH_DBF_SENSE_INDEX,
+					QETH_DBF_SENSE_PAGES,
 					QETH_DBF_SENSE_NR_AREAS,
 					QETH_DBF_SENSE_LEN);
 	qeth_dbf_qerr = debug_register(QETH_DBF_QERR_NAME,
-				       QETH_DBF_QERR_INDEX,
+				       QETH_DBF_QERR_PAGES,
 				       QETH_DBF_QERR_NR_AREAS,
 				       QETH_DBF_QERR_LEN);
 	qeth_dbf_trace = debug_register(QETH_DBF_TRACE_NAME,
-					QETH_DBF_TRACE_INDEX,
+					QETH_DBF_TRACE_PAGES,
 					QETH_DBF_TRACE_NR_AREAS,
 					QETH_DBF_TRACE_LEN);
 
@@ -8120,20 +8120,22 @@ static struct notifier_block qeth_ip6_no
 #endif
 
 static int
-qeth_reboot_event(struct notifier_block *this, unsigned long event, void *ptr)
+__qeth_reboot_event_card(struct device *dev, void *data)
 {
-
-	struct device *entry;
 	struct qeth_card *card;
 
-	down_read(&qeth_ccwgroup_driver.driver.bus->subsys.rwsem);
-	       list_for_each_entry(entry, &qeth_ccwgroup_driver.driver.devices,
-			           driver_list) {
-	               card = (struct qeth_card *) entry->driver_data;
-		       qeth_clear_ip_list(card, 0, 0);
-		       qeth_qdio_clear_card(card, 0);
-	       }
-	up_read(&qeth_ccwgroup_driver.driver.bus->subsys.rwsem);
+	card = (struct qeth_card *) dev->driver_data;
+	qeth_clear_ip_list(card, 0, 0);
+	qeth_qdio_clear_card(card, 0);
+	return 0;
+}
+
+static int
+qeth_reboot_event(struct notifier_block *this, unsigned long event, void *ptr)
+{
+
+	driver_for_each_device(&qeth_ccwgroup_driver.driver, NULL, NULL,
+			       __qeth_reboot_event_card);
 	return NOTIFY_DONE;
 }
 
diff --git a/drivers/s390/net/qeth_proc.c b/drivers/s390/net/qeth_proc.c
--- a/drivers/s390/net/qeth_proc.c
+++ b/drivers/s390/net/qeth_proc.c
@@ -27,23 +27,33 @@ const char *VERSION_QETH_PROC_C = "$Revi
 #define QETH_PROCFILE_NAME "qeth"
 static struct proc_dir_entry *qeth_procfile;
 
+static int
+qeth_procfile_seq_match(struct device *dev, void *data)
+{
+	return 1;
+}
+
 static void *
 qeth_procfile_seq_start(struct seq_file *s, loff_t *offset)
 {
-	struct list_head *next_card = NULL;
-	int i = 0;
+	struct device *dev;
+	loff_t nr;
 
 	down_read(&qeth_ccwgroup_driver.driver.bus->subsys.rwsem);
 
-	if (*offset == 0)
+	nr = *offset;
+	if (nr == 0)
 		return SEQ_START_TOKEN;
 
-	/* get card at pos *offset */
-	list_for_each(next_card, &qeth_ccwgroup_driver.driver.devices)
-		if (++i == *offset)
-			return next_card;
+	dev = driver_find_device(&qeth_ccwgroup_driver.driver, NULL,
+				 NULL, qeth_procfile_seq_match);
 
-	return NULL;
+	/* get card at pos *offset */
+	nr = *offset;
+	while (nr-- > 1 && dev)
+		dev = driver_find_device(&qeth_ccwgroup_driver.driver, dev,
+					 NULL, qeth_procfile_seq_match);
+	return (void *) dev;
 }
 
 static void
@@ -55,23 +65,21 @@ qeth_procfile_seq_stop(struct seq_file *
 static void *
 qeth_procfile_seq_next(struct seq_file *s, void *it, loff_t *offset)
 {
-	struct list_head *next_card = NULL;
-	struct list_head *current_card;
+	struct device *prev, *next;
 
 	if (it == SEQ_START_TOKEN) {
-		next_card = qeth_ccwgroup_driver.driver.devices.next;
-		if (next_card->next == next_card) /* list empty */
-			return NULL;
-		(*offset)++;
-	} else {
-		current_card = (struct list_head *)it;
-		if (current_card->next == &qeth_ccwgroup_driver.driver.devices)
-			return NULL; /* end of list reached */
-		next_card = current_card->next;
-		(*offset)++;
+		next = driver_find_device(&qeth_ccwgroup_driver.driver,
+					  NULL, NULL, qeth_procfile_seq_match);
+		if (next)
+			(*offset)++;
+		return (void *) next;
 	}
-
-	return next_card;
+	prev = (struct device *) it;
+	next = driver_find_device(&qeth_ccwgroup_driver.driver,
+				  prev, NULL, qeth_procfile_seq_match);
+	if (next)
+		(*offset)++;
+	return (void *) next;
 }
 
 static inline const char *
@@ -126,7 +134,7 @@ qeth_procfile_seq_show(struct seq_file *
 			      "-------------- ---- ------ ---------- ---- "
 			      "---- ----- -----\n");
 	} else {
-		device = list_entry(it, struct device, driver_list);
+		device = (struct device *) it;
 		card = device->driver_data;
 		seq_printf(s, "%s/%s/%s x%02X   %-10s %-14s %-4i ",
 				CARD_RDEV_ID(card),
@@ -180,17 +188,20 @@ static struct proc_dir_entry *qeth_perf_
 static void *
 qeth_perf_procfile_seq_start(struct seq_file *s, loff_t *offset)
 {
-	struct list_head *next_card = NULL;
-	int i = 0;
+	struct device *dev = NULL;
+	int nr;
 
 	down_read(&qeth_ccwgroup_driver.driver.bus->subsys.rwsem);
 	/* get card at pos *offset */
-	list_for_each(next_card, &qeth_ccwgroup_driver.driver.devices){
-		if (i == *offset)
-			return next_card;
-		i++;
-	}
-	return NULL;
+	dev = driver_find_device(&qeth_ccwgroup_driver.driver, NULL, NULL,
+				 qeth_procfile_seq_match);
+
+	/* get card at pos *offset */
+	nr = *offset;
+	while (nr-- > 1 && dev)
+		dev = driver_find_device(&qeth_ccwgroup_driver.driver, dev,
+					 NULL, qeth_procfile_seq_match);
+	return (void *) dev;
 }
 
 static void
@@ -202,12 +213,14 @@ qeth_perf_procfile_seq_stop(struct seq_f
 static void *
 qeth_perf_procfile_seq_next(struct seq_file *s, void *it, loff_t *offset)
 {
-	struct list_head *current_card = (struct list_head *)it;
+	struct device *prev, *next;
 
-	if (current_card->next == &qeth_ccwgroup_driver.driver.devices)
-		return NULL; /* end of list reached */
-	(*offset)++;
-	return current_card->next;
+	prev = (struct device *) it;
+	next = driver_find_device(&qeth_ccwgroup_driver.driver, prev,
+				  NULL, qeth_procfile_seq_match);
+	if (next)
+		(*offset)++;
+	return (void *) next;
 }
 
 static int
@@ -216,7 +229,7 @@ qeth_perf_procfile_seq_show(struct seq_f
 	struct device *device;
 	struct qeth_card *card;
 
-	device = list_entry(it, struct device, driver_list);
+	device = (struct device *) it;
 	card = device->driver_data;
 	seq_printf(s, "For card with devnos %s/%s/%s (%s):\n",
 			CARD_RDEV_ID(card),
@@ -318,8 +331,8 @@ static struct proc_dir_entry *qeth_ipato
 static void *
 qeth_ipato_procfile_seq_start(struct seq_file *s, loff_t *offset)
 {
-	struct list_head *next_card = NULL;
-	int i = 0;
+	struct device *dev;
+	loff_t nr;
 
 	down_read(&qeth_ccwgroup_driver.driver.bus->subsys.rwsem);
 	/* TODO: finish this */
@@ -328,13 +341,16 @@ qeth_ipato_procfile_seq_start(struct seq
 	 * output driver settings then;
 	 * else output setting for respective card
 	 */
+
+	dev = driver_find_device(&qeth_ccwgroup_driver.driver, NULL, NULL,
+				 qeth_procfile_seq_match);
+
 	/* get card at pos *offset */
-	list_for_each(next_card, &qeth_ccwgroup_driver.driver.devices){
-		if (i == *offset)
-			return next_card;
-		i++;
-	}
-	return NULL;
+	nr = *offset;
+	while (nr-- > 1 && dev)
+		dev = driver_find_device(&qeth_ccwgroup_driver.driver, dev,
+					 NULL, qeth_procfile_seq_match);
+	return (void *) dev;
 }
 
 static void
@@ -346,18 +362,14 @@ qeth_ipato_procfile_seq_stop(struct seq_
 static void *
 qeth_ipato_procfile_seq_next(struct seq_file *s, void *it, loff_t *offset)
 {
-	struct list_head *current_card = (struct list_head *)it;
+	struct device *prev, *next;
 
-	/* TODO: finish this */
-	/*
-	 * maybe SEQ_SATRT_TOKEN can be returned for offset 0
-	 * output driver settings then;
-	 * else output setting for respective card
-	 */
-	if (current_card->next == &qeth_ccwgroup_driver.driver.devices)
-		return NULL; /* end of list reached */
-	(*offset)++;
-	return current_card->next;
+	prev = (struct device *) it;
+	next = driver_find_device(&qeth_ccwgroup_driver.driver, prev,
+				  NULL, qeth_procfile_seq_match);
+	if (next)
+		(*offset)++;
+	return (void *) next;
 }
 
 static int
@@ -372,7 +384,7 @@ qeth_ipato_procfile_seq_show(struct seq_
 	 * output driver settings then;
 	 * else output setting for respective card
 	 */
-	device = list_entry(it, struct device, driver_list);
+	device = (struct device *) it;
 	card = device->driver_data;
 
 	return 0;
diff --git a/drivers/s390/net/qeth_sys.c b/drivers/s390/net/qeth_sys.c
--- a/drivers/s390/net/qeth_sys.c
+++ b/drivers/s390/net/qeth_sys.c
@@ -30,7 +30,7 @@ const char *VERSION_QETH_SYS_C = "$Revis
 //low/high watermark
 
 static ssize_t
-qeth_dev_state_show(struct device *dev, char *buf)
+qeth_dev_state_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct qeth_card *card = dev->driver_data;
 	if (!card)
@@ -58,7 +58,7 @@ qeth_dev_state_show(struct device *dev, 
 static DEVICE_ATTR(state, 0444, qeth_dev_state_show, NULL);
 
 static ssize_t
-qeth_dev_chpid_show(struct device *dev, char *buf)
+qeth_dev_chpid_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct qeth_card *card = dev->driver_data;
 	if (!card)
@@ -70,7 +70,7 @@ qeth_dev_chpid_show(struct device *dev, 
 static DEVICE_ATTR(chpid, 0444, qeth_dev_chpid_show, NULL);
 
 static ssize_t
-qeth_dev_if_name_show(struct device *dev, char *buf)
+qeth_dev_if_name_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct qeth_card *card = dev->driver_data;
 	if (!card)
@@ -81,7 +81,7 @@ qeth_dev_if_name_show(struct device *dev
 static DEVICE_ATTR(if_name, 0444, qeth_dev_if_name_show, NULL);
 
 static ssize_t
-qeth_dev_card_type_show(struct device *dev, char *buf)
+qeth_dev_card_type_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct qeth_card *card = dev->driver_data;
 	if (!card)
@@ -93,7 +93,7 @@ qeth_dev_card_type_show(struct device *d
 static DEVICE_ATTR(card_type, 0444, qeth_dev_card_type_show, NULL);
 
 static ssize_t
-qeth_dev_portno_show(struct device *dev, char *buf)
+qeth_dev_portno_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct qeth_card *card = dev->driver_data;
 	if (!card)
@@ -103,7 +103,7 @@ qeth_dev_portno_show(struct device *dev,
 }
 
 static ssize_t
-qeth_dev_portno_store(struct device *dev, const char *buf, size_t count)
+qeth_dev_portno_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct qeth_card *card = dev->driver_data;
 	char *tmp;
@@ -129,7 +129,7 @@ qeth_dev_portno_store(struct device *dev
 static DEVICE_ATTR(portno, 0644, qeth_dev_portno_show, qeth_dev_portno_store);
 
 static ssize_t
-qeth_dev_portname_show(struct device *dev, char *buf)
+qeth_dev_portname_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct qeth_card *card = dev->driver_data;
 	char portname[9] = {0, };
@@ -146,7 +146,7 @@ qeth_dev_portname_show(struct device *de
 }
 
 static ssize_t
-qeth_dev_portname_store(struct device *dev, const char *buf, size_t count)
+qeth_dev_portname_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct qeth_card *card = dev->driver_data;
 	char *tmp;
@@ -177,7 +177,7 @@ static DEVICE_ATTR(portname, 0644, qeth_
 		qeth_dev_portname_store);
 
 static ssize_t
-qeth_dev_checksum_show(struct device *dev, char *buf)
+qeth_dev_checksum_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct qeth_card *card = dev->driver_data;
 
@@ -188,7 +188,7 @@ qeth_dev_checksum_show(struct device *de
 }
 
 static ssize_t
-qeth_dev_checksum_store(struct device *dev, const char *buf, size_t count)
+qeth_dev_checksum_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct qeth_card *card = dev->driver_data;
 	char *tmp;
@@ -218,7 +218,7 @@ static DEVICE_ATTR(checksumming, 0644, q
 		qeth_dev_checksum_store);
 
 static ssize_t
-qeth_dev_prioqing_show(struct device *dev, char *buf)
+qeth_dev_prioqing_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct qeth_card *card = dev->driver_data;
 
@@ -237,7 +237,7 @@ qeth_dev_prioqing_show(struct device *de
 }
 
 static ssize_t
-qeth_dev_prioqing_store(struct device *dev, const char *buf, size_t count)
+qeth_dev_prioqing_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct qeth_card *card = dev->driver_data;
 	char *tmp;
@@ -290,7 +290,7 @@ static DEVICE_ATTR(priority_queueing, 06
 		qeth_dev_prioqing_store);
 
 static ssize_t
-qeth_dev_bufcnt_show(struct device *dev, char *buf)
+qeth_dev_bufcnt_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct qeth_card *card = dev->driver_data;
 
@@ -301,7 +301,7 @@ qeth_dev_bufcnt_show(struct device *dev,
 }
 
 static ssize_t
-qeth_dev_bufcnt_store(struct device *dev, const char *buf, size_t count)
+qeth_dev_bufcnt_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct qeth_card *card = dev->driver_data;
 	char *tmp;
@@ -360,7 +360,7 @@ qeth_dev_route_show(struct qeth_card *ca
 }
 
 static ssize_t
-qeth_dev_route4_show(struct device *dev, char *buf)
+qeth_dev_route4_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct qeth_card *card = dev->driver_data;
 
@@ -410,7 +410,7 @@ qeth_dev_route_store(struct qeth_card *c
 }
 
 static ssize_t
-qeth_dev_route4_store(struct device *dev, const char *buf, size_t count)
+qeth_dev_route4_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct qeth_card *card = dev->driver_data;
 
@@ -425,7 +425,7 @@ static DEVICE_ATTR(route4, 0644, qeth_de
 
 #ifdef CONFIG_QETH_IPV6
 static ssize_t
-qeth_dev_route6_show(struct device *dev, char *buf)
+qeth_dev_route6_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct qeth_card *card = dev->driver_data;
 
@@ -439,7 +439,7 @@ qeth_dev_route6_show(struct device *dev,
 }
 
 static ssize_t
-qeth_dev_route6_store(struct device *dev, const char *buf, size_t count)
+qeth_dev_route6_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct qeth_card *card = dev->driver_data;
 
@@ -461,7 +461,7 @@ static DEVICE_ATTR(route6, 0644, qeth_de
 #endif
 
 static ssize_t
-qeth_dev_add_hhlen_show(struct device *dev, char *buf)
+qeth_dev_add_hhlen_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct qeth_card *card = dev->driver_data;
 
@@ -472,7 +472,7 @@ qeth_dev_add_hhlen_show(struct device *d
 }
 
 static ssize_t
-qeth_dev_add_hhlen_store(struct device *dev, const char *buf, size_t count)
+qeth_dev_add_hhlen_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct qeth_card *card = dev->driver_data;
 	char *tmp;
@@ -499,7 +499,7 @@ static DEVICE_ATTR(add_hhlen, 0644, qeth
 		   qeth_dev_add_hhlen_store);
 
 static ssize_t
-qeth_dev_fake_ll_show(struct device *dev, char *buf)
+qeth_dev_fake_ll_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct qeth_card *card = dev->driver_data;
 
@@ -510,7 +510,7 @@ qeth_dev_fake_ll_show(struct device *dev
 }
 
 static ssize_t
-qeth_dev_fake_ll_store(struct device *dev, const char *buf, size_t count)
+qeth_dev_fake_ll_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct qeth_card *card = dev->driver_data;
 	char *tmp;
@@ -536,7 +536,7 @@ static DEVICE_ATTR(fake_ll, 0644, qeth_d
 		   qeth_dev_fake_ll_store);
 
 static ssize_t
-qeth_dev_fake_broadcast_show(struct device *dev, char *buf)
+qeth_dev_fake_broadcast_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct qeth_card *card = dev->driver_data;
 
@@ -547,7 +547,7 @@ qeth_dev_fake_broadcast_show(struct devi
 }
 
 static ssize_t
-qeth_dev_fake_broadcast_store(struct device *dev, const char *buf, size_t count)
+qeth_dev_fake_broadcast_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct qeth_card *card = dev->driver_data;
 	char *tmp;
@@ -574,7 +574,7 @@ static DEVICE_ATTR(fake_broadcast, 0644,
 		   qeth_dev_fake_broadcast_store);
 
 static ssize_t
-qeth_dev_recover_store(struct device *dev, const char *buf, size_t count)
+qeth_dev_recover_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct qeth_card *card = dev->driver_data;
 	char *tmp;
@@ -596,7 +596,7 @@ qeth_dev_recover_store(struct device *de
 static DEVICE_ATTR(recover, 0200, NULL, qeth_dev_recover_store);
 
 static ssize_t
-qeth_dev_broadcast_mode_show(struct device *dev, char *buf)
+qeth_dev_broadcast_mode_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct qeth_card *card = dev->driver_data;
 
@@ -613,7 +613,7 @@ qeth_dev_broadcast_mode_show(struct devi
 }
 
 static ssize_t
-qeth_dev_broadcast_mode_store(struct device *dev, const char *buf, size_t count)
+qeth_dev_broadcast_mode_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct qeth_card *card = dev->driver_data;
 	char *tmp;
@@ -651,7 +651,7 @@ static DEVICE_ATTR(broadcast_mode, 0644,
 		   qeth_dev_broadcast_mode_store);
 
 static ssize_t
-qeth_dev_canonical_macaddr_show(struct device *dev, char *buf)
+qeth_dev_canonical_macaddr_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct qeth_card *card = dev->driver_data;
 
@@ -667,7 +667,7 @@ qeth_dev_canonical_macaddr_show(struct d
 }
 
 static ssize_t
-qeth_dev_canonical_macaddr_store(struct device *dev, const char *buf,
+qeth_dev_canonical_macaddr_store(struct device *dev, struct device_attribute *attr, const char *buf,
 				  size_t count)
 {
 	struct qeth_card *card = dev->driver_data;
@@ -703,7 +703,7 @@ static DEVICE_ATTR(canonical_macaddr, 06
 		   qeth_dev_canonical_macaddr_store);
 
 static ssize_t
-qeth_dev_layer2_show(struct device *dev, char *buf)
+qeth_dev_layer2_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct qeth_card *card = dev->driver_data;
 
@@ -714,7 +714,7 @@ qeth_dev_layer2_show(struct device *dev,
 }
 
 static ssize_t
-qeth_dev_layer2_store(struct device *dev, const char *buf, size_t count)
+qeth_dev_layer2_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct qeth_card *card = dev->driver_data;
 	char *tmp;
@@ -742,7 +742,7 @@ static DEVICE_ATTR(layer2, 0644, qeth_de
 		   qeth_dev_layer2_store);
 
 static ssize_t
-qeth_dev_large_send_show(struct device *dev, char *buf)
+qeth_dev_large_send_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct qeth_card *card = dev->driver_data;
 
@@ -762,7 +762,7 @@ qeth_dev_large_send_show(struct device *
 }
 
 static ssize_t
-qeth_dev_large_send_store(struct device *dev, const char *buf, size_t count)
+qeth_dev_large_send_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct qeth_card *card = dev->driver_data;
 	enum qeth_large_send_types type;
@@ -832,7 +832,7 @@ qeth_dev_blkt_store(struct qeth_card *ca
 }
 
 static ssize_t
-qeth_dev_blkt_total_show(struct device *dev, char *buf)
+qeth_dev_blkt_total_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct qeth_card *card = dev->driver_data;
 
@@ -841,7 +841,7 @@ qeth_dev_blkt_total_show(struct device *
 
 
 static ssize_t
-qeth_dev_blkt_total_store(struct device *dev, const char *buf, size_t count)
+qeth_dev_blkt_total_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct qeth_card *card = dev->driver_data;
 
@@ -855,7 +855,7 @@ static DEVICE_ATTR(total, 0644, qeth_dev
 		   qeth_dev_blkt_total_store);
 
 static ssize_t
-qeth_dev_blkt_inter_show(struct device *dev, char *buf)
+qeth_dev_blkt_inter_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct qeth_card *card = dev->driver_data;
 
@@ -864,7 +864,7 @@ qeth_dev_blkt_inter_show(struct device *
 
 
 static ssize_t
-qeth_dev_blkt_inter_store(struct device *dev, const char *buf, size_t count)
+qeth_dev_blkt_inter_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct qeth_card *card = dev->driver_data;
 
@@ -876,7 +876,7 @@ static DEVICE_ATTR(inter, 0644, qeth_dev
 		   qeth_dev_blkt_inter_store);
 
 static ssize_t
-qeth_dev_blkt_inter_jumbo_show(struct device *dev, char *buf)
+qeth_dev_blkt_inter_jumbo_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct qeth_card *card = dev->driver_data;
 
@@ -886,7 +886,7 @@ qeth_dev_blkt_inter_jumbo_show(struct de
 
 
 static ssize_t
-qeth_dev_blkt_inter_jumbo_store(struct device *dev, const char *buf, size_t count)
+qeth_dev_blkt_inter_jumbo_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct qeth_card *card = dev->driver_data;
 
@@ -956,7 +956,7 @@ qeth_check_layer2(struct qeth_card *card
 
 
 static ssize_t
-qeth_dev_ipato_enable_show(struct device *dev, char *buf)
+qeth_dev_ipato_enable_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct qeth_card *card = dev->driver_data;
 
@@ -969,7 +969,7 @@ qeth_dev_ipato_enable_show(struct device
 }
 
 static ssize_t
-qeth_dev_ipato_enable_store(struct device *dev, const char *buf, size_t count)
+qeth_dev_ipato_enable_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct qeth_card *card = dev->driver_data;
 	char *tmp;
@@ -1004,7 +1004,7 @@ static QETH_DEVICE_ATTR(ipato_enable, en
 			qeth_dev_ipato_enable_store);
 
 static ssize_t
-qeth_dev_ipato_invert4_show(struct device *dev, char *buf)
+qeth_dev_ipato_invert4_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct qeth_card *card = dev->driver_data;
 
@@ -1018,7 +1018,7 @@ qeth_dev_ipato_invert4_show(struct devic
 }
 
 static ssize_t
-qeth_dev_ipato_invert4_store(struct device *dev, const char *buf, size_t count)
+qeth_dev_ipato_invert4_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct qeth_card *card = dev->driver_data;
 	char *tmp;
@@ -1084,7 +1084,7 @@ qeth_dev_ipato_add_show(char *buf, struc
 }
 
 static ssize_t
-qeth_dev_ipato_add4_show(struct device *dev, char *buf)
+qeth_dev_ipato_add4_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct qeth_card *card = dev->driver_data;
 
@@ -1153,7 +1153,7 @@ qeth_dev_ipato_add_store(const char *buf
 }
 
 static ssize_t
-qeth_dev_ipato_add4_store(struct device *dev, const char *buf, size_t count)
+qeth_dev_ipato_add4_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct qeth_card *card = dev->driver_data;
 
@@ -1186,7 +1186,7 @@ qeth_dev_ipato_del_store(const char *buf
 }
 
 static ssize_t
-qeth_dev_ipato_del4_store(struct device *dev, const char *buf, size_t count)
+qeth_dev_ipato_del4_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct qeth_card *card = dev->driver_data;
 
@@ -1201,7 +1201,7 @@ static QETH_DEVICE_ATTR(ipato_del4, del4
 
 #ifdef CONFIG_QETH_IPV6
 static ssize_t
-qeth_dev_ipato_invert6_show(struct device *dev, char *buf)
+qeth_dev_ipato_invert6_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct qeth_card *card = dev->driver_data;
 
@@ -1215,7 +1215,7 @@ qeth_dev_ipato_invert6_show(struct devic
 }
 
 static ssize_t
-qeth_dev_ipato_invert6_store(struct device *dev, const char *buf, size_t count)
+qeth_dev_ipato_invert6_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct qeth_card *card = dev->driver_data;
 	char *tmp;
@@ -1247,7 +1247,7 @@ static QETH_DEVICE_ATTR(ipato_invert6, i
 
 
 static ssize_t
-qeth_dev_ipato_add6_show(struct device *dev, char *buf)
+qeth_dev_ipato_add6_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct qeth_card *card = dev->driver_data;
 
@@ -1258,7 +1258,7 @@ qeth_dev_ipato_add6_show(struct device *
 }
 
 static ssize_t
-qeth_dev_ipato_add6_store(struct device *dev, const char *buf, size_t count)
+qeth_dev_ipato_add6_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct qeth_card *card = dev->driver_data;
 
@@ -1273,7 +1273,7 @@ static QETH_DEVICE_ATTR(ipato_add6, add6
 			qeth_dev_ipato_add6_store);
 
 static ssize_t
-qeth_dev_ipato_del6_store(struct device *dev, const char *buf, size_t count)
+qeth_dev_ipato_del6_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct qeth_card *card = dev->driver_data;
 
@@ -1341,7 +1341,7 @@ qeth_dev_vipa_add_show(char *buf, struct
 }
 
 static ssize_t
-qeth_dev_vipa_add4_show(struct device *dev, char *buf)
+qeth_dev_vipa_add4_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct qeth_card *card = dev->driver_data;
 
@@ -1381,7 +1381,7 @@ qeth_dev_vipa_add_store(const char *buf,
 }
 
 static ssize_t
-qeth_dev_vipa_add4_store(struct device *dev, const char *buf, size_t count)
+qeth_dev_vipa_add4_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct qeth_card *card = dev->driver_data;
 
@@ -1413,7 +1413,7 @@ qeth_dev_vipa_del_store(const char *buf,
 }
 
 static ssize_t
-qeth_dev_vipa_del4_store(struct device *dev, const char *buf, size_t count)
+qeth_dev_vipa_del4_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct qeth_card *card = dev->driver_data;
 
@@ -1428,7 +1428,7 @@ static QETH_DEVICE_ATTR(vipa_del4, del4,
 
 #ifdef CONFIG_QETH_IPV6
 static ssize_t
-qeth_dev_vipa_add6_show(struct device *dev, char *buf)
+qeth_dev_vipa_add6_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct qeth_card *card = dev->driver_data;
 
@@ -1439,7 +1439,7 @@ qeth_dev_vipa_add6_show(struct device *d
 }
 
 static ssize_t
-qeth_dev_vipa_add6_store(struct device *dev, const char *buf, size_t count)
+qeth_dev_vipa_add6_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct qeth_card *card = dev->driver_data;
 
@@ -1454,7 +1454,7 @@ static QETH_DEVICE_ATTR(vipa_add6, add6,
 			qeth_dev_vipa_add6_store);
 
 static ssize_t
-qeth_dev_vipa_del6_store(struct device *dev, const char *buf, size_t count)
+qeth_dev_vipa_del6_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct qeth_card *card = dev->driver_data;
 
@@ -1522,7 +1522,7 @@ qeth_dev_rxip_add_show(char *buf, struct
 }
 
 static ssize_t
-qeth_dev_rxip_add4_show(struct device *dev, char *buf)
+qeth_dev_rxip_add4_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct qeth_card *card = dev->driver_data;
 
@@ -1562,7 +1562,7 @@ qeth_dev_rxip_add_store(const char *buf,
 }
 
 static ssize_t
-qeth_dev_rxip_add4_store(struct device *dev, const char *buf, size_t count)
+qeth_dev_rxip_add4_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct qeth_card *card = dev->driver_data;
 
@@ -1594,7 +1594,7 @@ qeth_dev_rxip_del_store(const char *buf,
 }
 
 static ssize_t
-qeth_dev_rxip_del4_store(struct device *dev, const char *buf, size_t count)
+qeth_dev_rxip_del4_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct qeth_card *card = dev->driver_data;
 
@@ -1609,7 +1609,7 @@ static QETH_DEVICE_ATTR(rxip_del4, del4,
 
 #ifdef CONFIG_QETH_IPV6
 static ssize_t
-qeth_dev_rxip_add6_show(struct device *dev, char *buf)
+qeth_dev_rxip_add6_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct qeth_card *card = dev->driver_data;
 
@@ -1620,7 +1620,7 @@ qeth_dev_rxip_add6_show(struct device *d
 }
 
 static ssize_t
-qeth_dev_rxip_add6_store(struct device *dev, const char *buf, size_t count)
+qeth_dev_rxip_add6_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct qeth_card *card = dev->driver_data;
 
@@ -1635,7 +1635,7 @@ static QETH_DEVICE_ATTR(rxip_add6, add6,
 			qeth_dev_rxip_add6_store);
 
 static ssize_t
-qeth_dev_rxip_del6_store(struct device *dev, const char *buf, size_t count)
+qeth_dev_rxip_del6_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct qeth_card *card = dev->driver_data;
 
diff --git a/drivers/s390/net/smsgiucv.c b/drivers/s390/net/smsgiucv.c
--- a/drivers/s390/net/smsgiucv.c
+++ b/drivers/s390/net/smsgiucv.c
@@ -138,7 +138,7 @@ static void __exit
 smsg_exit(void)
 {
 	if (smsg_handle > 0) {
-		cpcmd("SET SMSG OFF", 0, 0);
+		cpcmd("SET SMSG OFF", NULL, 0, NULL);
 		iucv_sever(smsg_pathid, 0);
 		iucv_unregister_program(smsg_handle);
 		driver_unregister(&smsg_driver);
@@ -177,7 +177,7 @@ smsg_init(void)
 		smsg_handle = 0;
 		return -EIO;
 	}
-	cpcmd("SET SMSG IUCV", 0, 0);
+	cpcmd("SET SMSG IUCV", NULL, 0, NULL);
 	return 0;
 }
 
diff --git a/drivers/s390/s390mach.c b/drivers/s390/s390mach.c
--- a/drivers/s390/s390mach.c
+++ b/drivers/s390/s390mach.c
@@ -31,14 +31,14 @@ extern void css_reiterate_subchannels(vo
 extern struct workqueue_struct *slow_path_wq;
 extern struct work_struct slow_path_work;
 
-static void
+static NORET_TYPE void
 s390_handle_damage(char *msg)
 {
-	printk(KERN_EMERG "%s\n", msg);
 #ifdef CONFIG_SMP
 	smp_send_stop();
 #endif
 	disabled_wait((unsigned long) __builtin_return_address(0));
+	for(;;);
 }
 
 /*
@@ -122,40 +122,39 @@ repeat:
 	return 0;
 }
 
+struct mcck_struct {
+	int kill_task;
+	int channel_report;
+	int warning;
+	unsigned long long mcck_code;
+};
+
+static DEFINE_PER_CPU(struct mcck_struct, cpu_mcck);
+
 /*
- * machine check handler.
+ * Main machine check handler function. Will be called with interrupts enabled
+ * or disabled and machine checks enabled or disabled.
  */
 void
-s390_do_machine_check(void)
+s390_handle_mcck(void)
 {
-	struct mci *mci;
-
-	mci = (struct mci *) &S390_lowcore.mcck_interruption_code;
-
-	if (mci->sd)		/* system damage */
-		s390_handle_damage("received system damage machine check\n");
-
-	if (mci->pd)		/* instruction processing damage */
-		s390_handle_damage("received instruction processing "
-				   "damage machine check\n");
-
-	if (mci->se)		/* storage error uncorrected */
-		s390_handle_damage("received storage error uncorrected "
-				   "machine check\n");
+	unsigned long flags;
+	struct mcck_struct mcck;
 
-	if (mci->sc)		/* storage error corrected */
-		printk(KERN_WARNING
-		       "received storage error corrected machine check\n");
+	/*
+	 * Disable machine checks and get the current state of accumulated
+	 * machine checks. Afterwards delete the old state and enable machine
+	 * checks again.
+	 */
+	local_irq_save(flags);
+	local_mcck_disable();
+	mcck = __get_cpu_var(cpu_mcck);
+	memset(&__get_cpu_var(cpu_mcck), 0, sizeof(struct mcck_struct));
+	clear_thread_flag(TIF_MCCK_PENDING);
+	local_mcck_enable();
+	local_irq_restore(flags);
 
-	if (mci->ke)		/* storage key-error uncorrected */
-		s390_handle_damage("received storage key-error uncorrected "
-				   "machine check\n");
-
-	if (mci->ds && mci->fa)	/* storage degradation */
-		s390_handle_damage("received storage degradation machine "
-				   "check\n");
-
-	if (mci->cp)		/* channel report word pending */
+	if (mcck.channel_report)
 		up(&m_sem);
 
 #ifdef CONFIG_MACHCHK_WARNING
@@ -168,7 +167,7 @@ s390_do_machine_check(void)
  * On VM we only get one interrupt per virtally presented machinecheck.
  * Though one suffices, we may get one interrupt per (virtual) processor.
  */
-	if (mci->w) {	/* WARNING pending ? */
+	if (mcck.warning) {	/* WARNING pending ? */
 		static int mchchk_wng_posted = 0;
 		/*
 		 * Use single machine clear, as we cannot handle smp right now
@@ -178,6 +177,261 @@ s390_do_machine_check(void)
 			kill_proc(1, SIGPWR, 1);
 	}
 #endif
+
+	if (mcck.kill_task) {
+		local_irq_enable();
+		printk(KERN_EMERG "mcck: Terminating task because of machine "
+		       "malfunction (code 0x%016llx).\n", mcck.mcck_code);
+		printk(KERN_EMERG "mcck: task: %s, pid: %d.\n",
+		       current->comm, current->pid);
+		do_exit(SIGSEGV);
+	}
+}
+
+/*
+ * returns 0 if all registers could be validated
+ * returns 1 otherwise
+ */
+static int
+s390_revalidate_registers(struct mci *mci)
+{
+	int kill_task;
+	u64 tmpclock;
+	u64 zero;
+	void *fpt_save_area, *fpt_creg_save_area;
+
+	kill_task = 0;
+	zero = 0;
+	/* General purpose registers */
+	if (!mci->gr)
+		/*
+		 * General purpose registers couldn't be restored and have
+		 * unknown contents. Process needs to be terminated.
+		 */
+		kill_task = 1;
+
+	/* Revalidate floating point registers */
+	if (!mci->fp)
+		/*
+		 * Floating point registers can't be restored and
+		 * therefore the process needs to be terminated.
+		 */
+		kill_task = 1;
+
+#ifndef __s390x__
+	asm volatile("ld 0,0(%0)\n"
+		     "ld 2,8(%0)\n"
+		     "ld 4,16(%0)\n"
+		     "ld 6,24(%0)"
+		     : : "a" (&S390_lowcore.floating_pt_save_area));
+#endif
+
+	if (MACHINE_HAS_IEEE) {
+#ifdef __s390x__
+		fpt_save_area = &S390_lowcore.floating_pt_save_area;
+		fpt_creg_save_area = &S390_lowcore.fpt_creg_save_area;
+#else
+		fpt_save_area = (void *) S390_lowcore.extended_save_area_addr;
+		fpt_creg_save_area = fpt_save_area+128;
+#endif
+		/* Floating point control register */
+		if (!mci->fc) {
+			/*
+			 * Floating point control register can't be restored.
+			 * Task will be terminated.
+			 */
+			asm volatile ("lfpc 0(%0)" : : "a" (&zero));
+			kill_task = 1;
+
+		}
+		else
+			asm volatile (
+				"lfpc 0(%0)"
+				: : "a" (fpt_creg_save_area));
+
+		asm volatile("ld  0,0(%0)\n"
+			     "ld  1,8(%0)\n"
+			     "ld  2,16(%0)\n"
+			     "ld  3,24(%0)\n"
+			     "ld  4,32(%0)\n"
+			     "ld  5,40(%0)\n"
+			     "ld  6,48(%0)\n"
+			     "ld  7,56(%0)\n"
+			     "ld  8,64(%0)\n"
+			     "ld  9,72(%0)\n"
+			     "ld 10,80(%0)\n"
+			     "ld 11,88(%0)\n"
+			     "ld 12,96(%0)\n"
+			     "ld 13,104(%0)\n"
+			     "ld 14,112(%0)\n"
+			     "ld 15,120(%0)\n"
+			     : : "a" (fpt_save_area));
+	}
+
+	/* Revalidate access registers */
+	asm volatile("lam 0,15,0(%0)"
+		     : : "a" (&S390_lowcore.access_regs_save_area));
+	if (!mci->ar)
+		/*
+		 * Access registers have unknown contents.
+		 * Terminating task.
+		 */
+		kill_task = 1;
+
+	/* Revalidate control registers */
+	if (!mci->cr)
+		/*
+		 * Control registers have unknown contents.
+		 * Can't recover and therefore stopping machine.
+		 */
+		s390_handle_damage("invalid control registers.");
+	else
+#ifdef __s390x__
+		asm volatile("lctlg 0,15,0(%0)"
+			     : : "a" (&S390_lowcore.cregs_save_area));
+#else
+		asm volatile("lctl 0,15,0(%0)"
+			     : : "a" (&S390_lowcore.cregs_save_area));
+#endif
+
+	/*
+	 * We don't even try to revalidate the TOD register, since we simply
+	 * can't write something sensible into that register.
+	 */
+
+#ifdef __s390x__
+	/*
+	 * See if we can revalidate the TOD programmable register with its
+	 * old contents (should be zero) otherwise set it to zero.
+	 */
+	if (!mci->pr)
+		asm volatile("sr 0,0\n"
+			     "sckpf"
+			     : : : "0", "cc");
+	else
+		asm volatile(
+			"l 0,0(%0)\n"
+			"sckpf"
+			: : "a" (&S390_lowcore.tod_progreg_save_area) : "0", "cc");
+#endif
+
+	/* Revalidate clock comparator register */
+	asm volatile ("stck 0(%1)\n"
+		      "sckc 0(%1)"
+		      : "=m" (tmpclock) : "a" (&(tmpclock)) : "cc", "memory");
+
+	/* Check if old PSW is valid */
+	if (!mci->wp)
+		/*
+		 * Can't tell if we come from user or kernel mode
+		 * -> stopping machine.
+		 */
+		s390_handle_damage("old psw invalid.");
+
+	if (!mci->ms || !mci->pm || !mci->ia)
+		kill_task = 1;
+
+	return kill_task;
+}
+
+/*
+ * machine check handler.
+ */
+void
+s390_do_machine_check(struct pt_regs *regs)
+{
+	struct mci *mci;
+	struct mcck_struct *mcck;
+	int umode;
+
+	mci = (struct mci *) &S390_lowcore.mcck_interruption_code;
+	mcck = &__get_cpu_var(cpu_mcck);
+	umode = user_mode(regs);
+
+	if (mci->sd)
+		/* System damage -> stopping machine */
+		s390_handle_damage("received system damage machine check.");
+
+	if (mci->pd) {
+		if (mci->b) {
+			/* Processing backup -> verify if we can survive this */
+			u64 z_mcic, o_mcic, t_mcic;
+#ifdef __s390x__
+			z_mcic = (1ULL<<63 | 1ULL<<59 | 1ULL<<29);
+			o_mcic = (1ULL<<43 | 1ULL<<42 | 1ULL<<41 | 1ULL<<40 |
+				  1ULL<<36 | 1ULL<<35 | 1ULL<<34 | 1ULL<<32 |
+				  1ULL<<30 | 1ULL<<21 | 1ULL<<20 | 1ULL<<17 |
+				  1ULL<<16);
+#else
+			z_mcic = (1ULL<<63 | 1ULL<<59 | 1ULL<<57 | 1ULL<<50 |
+				  1ULL<<29);
+			o_mcic = (1ULL<<43 | 1ULL<<42 | 1ULL<<41 | 1ULL<<40 |
+				  1ULL<<36 | 1ULL<<35 | 1ULL<<34 | 1ULL<<32 |
+				  1ULL<<30 | 1ULL<<20 | 1ULL<<17 | 1ULL<<16);
+#endif
+			t_mcic = *(u64 *)mci;
+
+			if (((t_mcic & z_mcic) != 0) ||
+			    ((t_mcic & o_mcic) != o_mcic)) {
+				s390_handle_damage("processing backup machine "
+						   "check with damage.");
+			}
+			if (!umode)
+				s390_handle_damage("processing backup machine "
+						   "check in kernel mode.");
+			mcck->kill_task = 1;
+			mcck->mcck_code = *(unsigned long long *) mci;
+		}
+		else {
+			/* Processing damage -> stopping machine */
+			s390_handle_damage("received instruction processing "
+					   "damage machine check.");
+		}
+	}
+	if (s390_revalidate_registers(mci)) {
+		if (umode) {
+			/*
+			 * Couldn't restore all register contents while in
+			 * user mode -> mark task for termination.
+			 */
+			mcck->kill_task = 1;
+			mcck->mcck_code = *(unsigned long long *) mci;
+			set_thread_flag(TIF_MCCK_PENDING);
+		}
+		else
+			/*
+			 * Couldn't restore all register contents while in
+			 * kernel mode -> stopping machine.
+			 */
+			s390_handle_damage("unable to revalidate registers.");
+	}
+
+	if (mci->se)
+		/* Storage error uncorrected */
+		s390_handle_damage("received storage error uncorrected "
+				   "machine check.");
+
+	if (mci->ke)
+		/* Storage key-error uncorrected */
+		s390_handle_damage("received storage key-error uncorrected "
+				   "machine check.");
+
+	if (mci->ds && mci->fa)
+		/* Storage degradation */
+		s390_handle_damage("received storage degradation machine "
+				   "check.");
+
+	if (mci->cp) {
+		/* Channel report word pending */
+		mcck->channel_report = 1;
+		set_thread_flag(TIF_MCCK_PENDING);
+	}
+
+	if (mci->w) {
+		/* Warning pending */
+		mcck->warning = 1;
+		set_thread_flag(TIF_MCCK_PENDING);
+	}
 }
 
 /*
@@ -189,9 +443,8 @@ static int
 machine_check_init(void)
 {
 	init_MUTEX_LOCKED(&m_sem);
-	ctl_clear_bit(14, 25);	/* disable damage MCH */
-	ctl_set_bit(14, 26);	/* enable degradation MCH */
-	ctl_set_bit(14, 27);	/* enable system recovery MCH */
+	ctl_clear_bit(14, 25);	/* disable external damage MCH */
+	ctl_set_bit(14, 27);    /* enable system recovery MCH */
 #ifdef CONFIG_MACHCHK_WARNING
 	ctl_set_bit(14, 24);	/* enable warning MCH */
 #endif
diff --git a/drivers/s390/s390mach.h b/drivers/s390/s390mach.h
--- a/drivers/s390/s390mach.h
+++ b/drivers/s390/s390mach.h
@@ -16,20 +16,45 @@ struct mci {
 	__u32   sd              :  1; /* 00 system damage */
 	__u32   pd              :  1; /* 01 instruction-processing damage */
 	__u32   sr              :  1; /* 02 system recovery */
-	__u32   to_be_defined_1 :  4; /* 03-06 */
+	__u32   to_be_defined_1 :  1; /* 03 */
+	__u32   cd              :  1; /* 04 timing-facility damage */
+	__u32   ed              :  1; /* 05 external damage */
+	__u32   to_be_defined_2 :  1; /* 06 */
 	__u32   dg              :  1; /* 07 degradation */
 	__u32   w               :  1; /* 08 warning pending */
 	__u32   cp              :  1; /* 09 channel-report pending */
-	__u32   to_be_defined_2 :  6; /* 10-15 */
+	__u32   sp              :  1; /* 10 service-processor damage */
+	__u32   ck              :  1; /* 11 channel-subsystem damage */
+	__u32   to_be_defined_3 :  2; /* 12-13 */
+	__u32   b               :  1; /* 14 backed up */
+	__u32   to_be_defined_4 :  1; /* 15 */
 	__u32   se              :  1; /* 16 storage error uncorrected */
 	__u32   sc              :  1; /* 17 storage error corrected */
 	__u32   ke              :  1; /* 18 storage-key error uncorrected */
 	__u32   ds              :  1; /* 19 storage degradation */
-	__u32	to_be_defined_3 :  4; /* 20-23 */
+	__u32   wp              :  1; /* 20 psw mwp validity */
+	__u32   ms              :  1; /* 21 psw mask and key validity */
+	__u32   pm              :  1; /* 22 psw program mask and cc validity */
+	__u32   ia              :  1; /* 23 psw instruction address validity */
 	__u32   fa              :  1; /* 24 failing storage address validity */
-	__u32   to_be_defined_4 :  7; /* 25-31 */
+	__u32   to_be_defined_5 :  1; /* 25 */
+	__u32   ec              :  1; /* 26 external damage code validity */
+	__u32   fp              :  1; /* 27 floating point register validity */
+	__u32   gr              :  1; /* 28 general register validity */
+	__u32   cr              :  1; /* 29 control register validity */
+	__u32   to_be_defined_6 :  1; /* 30 */
+	__u32   st              :  1; /* 31 storage logical validity */
 	__u32   ie              :  1; /* 32 indirect storage error */
-	__u32	to_be_defined_5 : 31; /* 33-63 */
+	__u32   ar              :  1; /* 33 access register validity */
+	__u32   da              :  1; /* 34 delayed access exception */
+	__u32   to_be_defined_7 :  7; /* 35-41 */
+	__u32   pr              :  1; /* 42 tod programmable register validity */
+	__u32   fc              :  1; /* 43 fp control register validity */
+	__u32   ap              :  1; /* 44 ancillary report */
+	__u32   to_be_defined_8 :  1; /* 45 */
+	__u32   ct              :  1; /* 46 cpu timer validity */
+	__u32   cc              :  1; /* 47 clock comparator validity */
+	__u32	to_be_defined_9 : 16; /* 47-63 */
 };
 
 /*
diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c
--- a/drivers/s390/scsi/zfcp_aux.c
+++ b/drivers/s390/scsi/zfcp_aux.c
@@ -97,11 +97,6 @@ MODULE_PARM_DESC(loglevel,
 		 "FC ERP QDIO CIO Config FSF SCSI Other, "
 		 "levels: 0=none 1=normal 2=devel 3=trace");
 
-#ifdef ZFCP_PRINT_FLAGS
-u32 flags_dump = 0;
-module_param(flags_dump, uint, 0);
-#endif
-
 /****************************************************************/
 /************** Functions without logging ***********************/
 /****************************************************************/
@@ -223,13 +218,20 @@ zfcp_in_els_dbf_event(struct zfcp_adapte
  * Parse "device=..." parameter string.
  */
 static int __init
-zfcp_device_setup(char *str)
+zfcp_device_setup(char *devstr)
 {
-	char *tmp;
+	char *tmp, *str;
+	size_t len;
 
-	if (!str)
+	if (!devstr)
 		return 0;
 
+	len = strlen(devstr) + 1;
+	str = (char *) kmalloc(len, GFP_KERNEL);
+	if (!str)
+		goto err_out;
+	memcpy(str, devstr, len);
+
 	tmp = strchr(str, ',');
 	if (!tmp)
 		goto err_out;
@@ -246,10 +248,12 @@ zfcp_device_setup(char *str)
 	zfcp_data.init_fcp_lun = simple_strtoull(tmp, &tmp, 0);
 	if (*tmp != '\0')
 		goto err_out;
+	kfree(str);
 	return 1;
 
  err_out:
 	ZFCP_LOG_NORMAL("Parse error for device parameter string %s\n", str);
+	kfree(str);
 	return 0;
 }
 
@@ -525,7 +529,7 @@ zfcp_cfdc_dev_ioctl(struct file *file, u
 
  out:
 	if (fsf_req != NULL)
-		zfcp_fsf_req_cleanup(fsf_req);
+		zfcp_fsf_req_free(fsf_req);
 
 	if ((adapter != NULL) && (retval != -ENXIO))
 		zfcp_adapter_put(adapter);
@@ -1154,7 +1158,7 @@ zfcp_adapter_enqueue(struct ccw_device *
 	INIT_LIST_HEAD(&adapter->port_remove_lh);
 
 	/* initialize list of fsf requests */
-	rwlock_init(&adapter->fsf_req_list_lock);
+	spin_lock_init(&adapter->fsf_req_list_lock);
 	INIT_LIST_HEAD(&adapter->fsf_req_list_head);
 
 	/* initialize abort lock */
@@ -1239,9 +1243,9 @@ zfcp_adapter_dequeue(struct zfcp_adapter
 	zfcp_sysfs_adapter_remove_files(&adapter->ccw_device->dev);
 	dev_set_drvdata(&adapter->ccw_device->dev, NULL);
 	/* sanity check: no pending FSF requests */
-	read_lock_irqsave(&adapter->fsf_req_list_lock, flags);
+	spin_lock_irqsave(&adapter->fsf_req_list_lock, flags);
 	retval = !list_empty(&adapter->fsf_req_list_head);
-	read_unlock_irqrestore(&adapter->fsf_req_list_lock, flags);
+	spin_unlock_irqrestore(&adapter->fsf_req_list_lock, flags);
 	if (retval) {
 		ZFCP_LOG_NORMAL("bug: adapter %s (%p) still in use, "
 				"%i requests outstanding\n",
@@ -1295,13 +1299,10 @@ struct zfcp_port *
 zfcp_port_enqueue(struct zfcp_adapter *adapter, wwn_t wwpn, u32 status,
 		  u32 d_id)
 {
-	struct zfcp_port *port, *tmp_port;
+	struct zfcp_port *port;
 	int check_wwpn;
-	scsi_id_t scsi_id;
-	int found;
 
 	check_wwpn = !(status & ZFCP_STATUS_PORT_NO_WWPN);
-
 	/*
 	 * check that there is no port with this WWPN already in list
 	 */
@@ -1364,7 +1365,7 @@ zfcp_port_enqueue(struct zfcp_adapter *a
 	} else {
 		snprintf(port->sysfs_device.bus_id,
 			 BUS_ID_SIZE, "0x%016llx", wwpn);
-	port->sysfs_device.parent = &adapter->ccw_device->dev;
+		port->sysfs_device.parent = &adapter->ccw_device->dev;
 	}
 	port->sysfs_device.release = zfcp_sysfs_port_release;
 	dev_set_drvdata(&port->sysfs_device, port);
@@ -1384,24 +1385,8 @@ zfcp_port_enqueue(struct zfcp_adapter *a
 
 	zfcp_port_get(port);
 
-	scsi_id = 1;
-	found = 0;
 	write_lock_irq(&zfcp_data.config_lock);
-	list_for_each_entry(tmp_port, &adapter->port_list_head, list) {
-		if (atomic_test_mask(ZFCP_STATUS_PORT_NO_SCSI_ID,
-				     &tmp_port->status))
-			continue;
-		if (tmp_port->scsi_id != scsi_id) {
-			found = 1;
-			break;
-		}
-		scsi_id++;
-	}
-	port->scsi_id = scsi_id;
-	if (found)
-		list_add_tail(&port->list, &tmp_port->list);
-	else
-		list_add_tail(&port->list, &adapter->port_list_head);
+	list_add_tail(&port->list, &adapter->port_list_head);
 	atomic_clear_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status);
 	atomic_set_mask(ZFCP_STATUS_COMMON_RUNNING, &port->status);
 	if (d_id == ZFCP_DID_DIRECTORY_SERVICE)
@@ -1423,6 +1408,9 @@ zfcp_port_dequeue(struct zfcp_port *port
 	list_del(&port->list);
 	port->adapter->ports--;
 	write_unlock_irq(&zfcp_data.config_lock);
+	if (port->rport)
+		fc_remote_port_delete(port->rport);
+	port->rport = NULL;
 	zfcp_adapter_put(port->adapter);
 	zfcp_sysfs_port_remove_files(&port->sysfs_device,
 				     atomic_read(&port->status));
@@ -1483,19 +1471,15 @@ zfcp_fsf_incoming_els_rscn(struct zfcp_a
 		fcp_rscn_element++;
 		switch (fcp_rscn_element->addr_format) {
 		case ZFCP_PORT_ADDRESS:
-			ZFCP_LOG_FLAGS(1, "ZFCP_PORT_ADDRESS\n");
 			range_mask = ZFCP_PORTS_RANGE_PORT;
 			break;
 		case ZFCP_AREA_ADDRESS:
-			ZFCP_LOG_FLAGS(1, "ZFCP_AREA_ADDRESS\n");
 			range_mask = ZFCP_PORTS_RANGE_AREA;
 			break;
 		case ZFCP_DOMAIN_ADDRESS:
-			ZFCP_LOG_FLAGS(1, "ZFCP_DOMAIN_ADDRESS\n");
 			range_mask = ZFCP_PORTS_RANGE_DOMAIN;
 			break;
 		case ZFCP_FABRIC_ADDRESS:
-			ZFCP_LOG_FLAGS(1, "ZFCP_FABRIC_ADDRESS\n");
 			range_mask = ZFCP_PORTS_RANGE_FABRIC;
 			break;
 		default:
@@ -1762,7 +1746,10 @@ static void zfcp_ns_gid_pn_handler(unsig
 	ct_iu_req = zfcp_sg_to_address(ct->req);
 	ct_iu_resp = zfcp_sg_to_address(ct->resp);
 
-	if ((ct->status != 0) || zfcp_check_ct_response(&ct_iu_resp->header)) {
+	if (ct->status != 0)
+		goto failed;
+
+	if (zfcp_check_ct_response(&ct_iu_resp->header)) {
 		/* FIXME: do we need some specific erp entry points */
 		atomic_set_mask(ZFCP_STATUS_PORT_INVALID_WWPN, &port->status);
 		goto failed;
diff --git a/drivers/s390/scsi/zfcp_ccw.c b/drivers/s390/scsi/zfcp_ccw.c
--- a/drivers/s390/scsi/zfcp_ccw.c
+++ b/drivers/s390/scsi/zfcp_ccw.c
@@ -202,9 +202,19 @@ static int
 zfcp_ccw_set_offline(struct ccw_device *ccw_device)
 {
 	struct zfcp_adapter *adapter;
+	struct zfcp_port *port;
+	struct fc_rport *rport;
 
 	down(&zfcp_data.config_sema);
 	adapter = dev_get_drvdata(&ccw_device->dev);
+	/* might be racy, but we cannot take config_lock due to the fact that
+	   fc_remote_port_delete might sleep */
+	list_for_each_entry(port, &adapter->port_list_head, list)
+		if (port->rport) {
+			rport = port->rport;
+			port->rport = NULL;
+			fc_remote_port_delete(rport);
+		}
 	zfcp_erp_adapter_shutdown(adapter, 0);
 	zfcp_erp_wait(adapter);
 	zfcp_adapter_scsi_unregister(adapter);
diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h
--- a/drivers/s390/scsi/zfcp_def.h
+++ b/drivers/s390/scsi/zfcp_def.h
@@ -62,9 +62,6 @@
 #include <linux/syscalls.h>
 #include <linux/ioctl.h>
 
-/************************ DEBUG FLAGS *****************************************/
-
-#define	ZFCP_PRINT_FLAGS
 
 /********************* GENERAL DEFINES *********************************/
 
@@ -152,8 +149,10 @@ typedef u32 scsi_lun_t;
 #define FSF_QTCB_UNSOLICITED_STATUS		0x6305
 #define ZFCP_STATUS_READ_FAILED_THRESHOLD	3
 #define ZFCP_STATUS_READS_RECOM		        FSF_STATUS_READS_RECOM
-#define ZFCP_EXCHANGE_CONFIG_DATA_RETRIES	6
-#define ZFCP_EXCHANGE_CONFIG_DATA_SLEEP		50
+
+/* Do 1st retry in 1 second, then double the timeout for each following retry */
+#define ZFCP_EXCHANGE_CONFIG_DATA_FIRST_SLEEP	100
+#define ZFCP_EXCHANGE_CONFIG_DATA_RETRIES	7
 
 /* timeout value for "default timer" for fsf requests */
 #define ZFCP_FSF_REQUEST_TIMEOUT (60*HZ);
@@ -472,17 +471,6 @@ do { \
 	ZFCP_LOG(ZFCP_LOG_LEVEL_TRACE, fmt , ##args)
 #endif
 
-#ifndef ZFCP_PRINT_FLAGS
-# define ZFCP_LOG_FLAGS(level, fmt, args...)
-#else
-extern u32 flags_dump;
-# define ZFCP_LOG_FLAGS(level, fmt, args...) \
-do { \
-	if (level <= flags_dump) \
-		_ZFCP_LOG(fmt, ##args); \
-} while (0)
-#endif
-
 /*************** ADAPTER/PORT/UNIT AND FSF_REQ STATUS FLAGS ******************/
 
 /* 
@@ -502,6 +490,7 @@ do { \
 #define ZFCP_STATUS_COMMON_CLOSING              0x02000000
 #define ZFCP_STATUS_COMMON_ERP_INUSE		0x01000000
 #define ZFCP_STATUS_COMMON_ACCESS_DENIED	0x00800000
+#define ZFCP_STATUS_COMMON_ACCESS_BOXED		0x00400000
 
 /* adapter status */
 #define ZFCP_STATUS_ADAPTER_QDIOUP		0x00000002
@@ -763,6 +752,7 @@ typedef void (*zfcp_send_els_handler_t)(
 /**
  * struct zfcp_send_els - used to pass parameters to function zfcp_fsf_send_els
  * @adapter: adapter where request is sent from
+ * @port: port where ELS is destinated (port reference count has to be increased)
  * @d_id: destiniation id of port where request is sent to
  * @req: scatter-gather list for request
  * @resp: scatter-gather list for response
@@ -777,6 +767,7 @@ typedef void (*zfcp_send_els_handler_t)(
  */
 struct zfcp_send_els {
 	struct zfcp_adapter *adapter;
+	struct zfcp_port *port;
 	fc_id_t d_id;
 	struct scatterlist *req;
 	struct scatterlist *resp;
@@ -871,7 +862,7 @@ struct zfcp_adapter {
 	u32			ports;	           /* number of remote ports */
         struct timer_list       scsi_er_timer;     /* SCSI err recovery watch */
 	struct list_head	fsf_req_list_head; /* head of FSF req list */
-	rwlock_t		fsf_req_list_lock; /* lock for ops on list of
+	spinlock_t		fsf_req_list_lock; /* lock for ops on list of
 						      FSF requests */
         atomic_t       		fsf_reqs_active;   /* # active FSF reqs */
 	struct zfcp_qdio_queue	request_queue;	   /* request queue */
@@ -915,6 +906,7 @@ struct zfcp_adapter {
  */
 struct zfcp_port {
 	struct device          sysfs_device;   /* sysfs device */
+	struct fc_rport        *rport;         /* rport of fc transport class */
 	struct list_head       list;	       /* list of remote ports */
 	atomic_t               refcount;       /* reference count */
 	wait_queue_head_t      remove_wq;      /* can be used to wait for
@@ -925,7 +917,6 @@ struct zfcp_port {
 						  list */
 	u32		       units;	       /* # of logical units in list */
 	atomic_t	       status;	       /* status of this remote port */
-	scsi_id_t	       scsi_id;	       /* own SCSI ID */
 	wwn_t		       wwnn;	       /* WWNN if known */
 	wwn_t		       wwpn;	       /* WWPN */
 	fc_id_t		       d_id;	       /* D_ID */
diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c
--- a/drivers/s390/scsi/zfcp_erp.c
+++ b/drivers/s390/scsi/zfcp_erp.c
@@ -35,7 +35,7 @@
 
 #include "zfcp_ext.h"
 
-static int zfcp_erp_adisc(struct zfcp_adapter *, fc_id_t);
+static int zfcp_erp_adisc(struct zfcp_port *);
 static void zfcp_erp_adisc_handler(unsigned long);
 
 static int zfcp_erp_adapter_reopen_internal(struct zfcp_adapter *, int);
@@ -295,12 +295,12 @@ zfcp_erp_unit_shutdown(struct zfcp_unit 
 
 /**
  * zfcp_erp_adisc - send ADISC ELS command
- * @adapter: adapter structure
- * @d_id: d_id of port where ADISC is sent to
+ * @port: port structure
  */
 int
-zfcp_erp_adisc(struct zfcp_adapter *adapter, fc_id_t d_id)
+zfcp_erp_adisc(struct zfcp_port *port)
 {
+	struct zfcp_adapter *adapter = port->adapter;
 	struct zfcp_send_els *send_els;
 	struct zfcp_ls_adisc *adisc;
 	void *address = NULL;
@@ -332,7 +332,8 @@ zfcp_erp_adisc(struct zfcp_adapter *adap
 	send_els->req_count = send_els->resp_count = 1;
 
 	send_els->adapter = adapter;
-	send_els->d_id = d_id;
+	send_els->port = port;
+	send_els->d_id = port->d_id;
 	send_els->handler = zfcp_erp_adisc_handler;
 	send_els->handler_data = (unsigned long) send_els;
 
@@ -350,7 +351,7 @@ zfcp_erp_adisc(struct zfcp_adapter *adap
 	ZFCP_LOG_INFO("ADISC request from s_id 0x%08x to d_id 0x%08x "
 		      "(wwpn=0x%016Lx, wwnn=0x%016Lx, "
 		      "hard_nport_id=0x%08x, nport_id=0x%08x)\n",
-		      adapter->s_id, d_id, (wwn_t) adisc->wwpn,
+		      adapter->s_id, send_els->d_id, (wwn_t) adisc->wwpn,
 		      (wwn_t) adisc->wwnn, adisc->hard_nport_id,
 		      adisc->nport_id);
 
@@ -367,7 +368,7 @@ zfcp_erp_adisc(struct zfcp_adapter *adap
 	retval = zfcp_fsf_send_els(send_els);
 	if (retval != 0) {
 		ZFCP_LOG_NORMAL("error: initiation of Send ELS failed for port "
-				"0x%08x on adapter %s\n", d_id,
+				"0x%08x on adapter %s\n", send_els->d_id,
 				zfcp_get_busid_by_adapter(adapter));
 		del_timer(send_els->timer);
 		goto freemem;
@@ -411,14 +412,9 @@ zfcp_erp_adisc_handler(unsigned long dat
 	del_timer(send_els->timer);
 
 	adapter = send_els->adapter;
+	port = send_els->port;
 	d_id = send_els->d_id;
 
-	read_lock(&zfcp_data.config_lock);
-	port = zfcp_get_port_by_did(send_els->adapter, send_els->d_id);
-	read_unlock(&zfcp_data.config_lock);
-
-	BUG_ON(port == NULL);
-
 	/* request rejected or timed out */
 	if (send_els->status != 0) {
 		ZFCP_LOG_NORMAL("ELS request rejected/timed out, "
@@ -482,7 +478,7 @@ zfcp_test_link(struct zfcp_port *port)
 	int retval;
 
 	zfcp_port_get(port);
-	retval = zfcp_erp_adisc(port->adapter, port->d_id);
+	retval = zfcp_erp_adisc(port);
 	if (retval != 0) {
 		zfcp_port_put(port);
 		ZFCP_LOG_NORMAL("reopen needed for port 0x%016Lx "
@@ -895,7 +891,7 @@ zfcp_erp_strategy_check_fsfreq(struct zf
 
 	if (erp_action->fsf_req) {
 		/* take lock to ensure that request is not being deleted meanwhile */
-		write_lock(&adapter->fsf_req_list_lock);
+		spin_lock(&adapter->fsf_req_list_lock);
 		/* check whether fsf req does still exist */
 		list_for_each_entry(fsf_req, &adapter->fsf_req_list_head, list)
 		    if (fsf_req == erp_action->fsf_req)
@@ -938,7 +934,7 @@ zfcp_erp_strategy_check_fsfreq(struct zf
 			 */
 			erp_action->fsf_req = NULL;
 		}
-		write_unlock(&adapter->fsf_req_list_lock);
+		spin_unlock(&adapter->fsf_req_list_lock);
 	} else
 		debug_text_event(adapter->erp_dbf, 3, "a_ca_noreq");
 
@@ -2286,12 +2282,12 @@ zfcp_erp_adapter_strategy_open_fsf_xconf
 {
 	int retval = ZFCP_ERP_SUCCEEDED;
 	int retries;
+	int sleep = ZFCP_EXCHANGE_CONFIG_DATA_FIRST_SLEEP;
 	struct zfcp_adapter *adapter = erp_action->adapter;
 
 	atomic_clear_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK, &adapter->status);
-	retries = ZFCP_EXCHANGE_CONFIG_DATA_RETRIES;
 
-	do {
+	for (retries = ZFCP_EXCHANGE_CONFIG_DATA_RETRIES; retries; retries--) {
 		atomic_clear_mask(ZFCP_STATUS_ADAPTER_HOST_CON_INIT,
 				  &adapter->status);
 		ZFCP_LOG_DEBUG("Doing exchange config data\n");
@@ -2329,16 +2325,17 @@ zfcp_erp_adapter_strategy_open_fsf_xconf
 				      zfcp_get_busid_by_adapter(adapter));
 			break;
 		}
-		if (atomic_test_mask(ZFCP_STATUS_ADAPTER_HOST_CON_INIT,
-				     &adapter->status)) {
-			ZFCP_LOG_DEBUG("host connection still initialising... "
-				       "waiting and retrying...\n");
-			/* sleep a little bit before retry */
-			msleep(jiffies_to_msecs(ZFCP_EXCHANGE_CONFIG_DATA_SLEEP));
-		}
-	} while ((retries--) &&
-		 atomic_test_mask(ZFCP_STATUS_ADAPTER_HOST_CON_INIT,
-				  &adapter->status));
+
+		if (!atomic_test_mask(ZFCP_STATUS_ADAPTER_HOST_CON_INIT,
+				     &adapter->status))
+			break;
+
+		ZFCP_LOG_DEBUG("host connection still initialising... "
+			       "waiting and retrying...\n");
+		/* sleep a little bit before retry */
+		msleep(jiffies_to_msecs(sleep));
+		sleep *= 2;
+	}
 
 	if (!atomic_test_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK,
 			      &adapter->status)) {
@@ -3363,13 +3360,32 @@ zfcp_erp_action_cleanup(int action, stru
 		if ((result == ZFCP_ERP_SUCCEEDED)
 		    && (!atomic_test_mask(ZFCP_STATUS_UNIT_TEMPORARY,
 					  &unit->status))
-		    && (!unit->device))
- 			scsi_add_device(unit->port->adapter->scsi_host, 0,
- 					unit->port->scsi_id, unit->scsi_lun);
+		    && !unit->device
+		    && port->rport)
+ 			scsi_add_device(port->adapter->scsi_host, 0,
+ 					port->rport->scsi_target_id,
+					unit->scsi_lun);
 		zfcp_unit_put(unit);
 		break;
 	case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED:
 	case ZFCP_ERP_ACTION_REOPEN_PORT:
+		if ((result == ZFCP_ERP_SUCCEEDED)
+		    && !atomic_test_mask(ZFCP_STATUS_PORT_NO_WWPN,
+					 &port->status)
+		    && !port->rport) {
+			struct fc_rport_identifiers ids;
+			ids.node_name = port->wwnn;
+			ids.port_name = port->wwpn;
+			ids.port_id = port->d_id;
+			ids.roles = FC_RPORT_ROLE_FCP_TARGET;
+			port->rport =
+				fc_remote_port_add(adapter->scsi_host, 0, &ids);
+			if (!port->rport)
+				ZFCP_LOG_NORMAL("failed registration of rport"
+						"(adapter %s, wwpn=0x%016Lx)\n",
+						zfcp_get_busid_by_port(port),
+						port->wwpn);
+		}
 		zfcp_port_put(port);
 		break;
 	case ZFCP_ERP_ACTION_REOPEN_ADAPTER:
@@ -3485,6 +3501,45 @@ zfcp_erp_action_to_ready(struct zfcp_erp
 }
 
 /*
+ * function:	zfcp_erp_port_boxed
+ *
+ * purpose:
+ */
+void
+zfcp_erp_port_boxed(struct zfcp_port *port)
+{
+	struct zfcp_adapter *adapter = port->adapter;
+	unsigned long flags;
+
+	debug_text_event(adapter->erp_dbf, 3, "p_access_boxed");
+	debug_event(adapter->erp_dbf, 3, &port->wwpn, sizeof(wwn_t));
+	read_lock_irqsave(&zfcp_data.config_lock, flags);
+	zfcp_erp_modify_port_status(port,
+			ZFCP_STATUS_COMMON_ACCESS_BOXED,
+			ZFCP_SET);
+	read_unlock_irqrestore(&zfcp_data.config_lock, flags);
+	zfcp_erp_port_reopen(port, ZFCP_STATUS_COMMON_ERP_FAILED);
+}
+
+/*
+ * function:	zfcp_erp_unit_boxed
+ *
+ * purpose:
+ */
+void
+zfcp_erp_unit_boxed(struct zfcp_unit *unit)
+{
+	struct zfcp_adapter *adapter = unit->port->adapter;
+
+	debug_text_event(adapter->erp_dbf, 3, "u_access_boxed");
+	debug_event(adapter->erp_dbf, 3, &unit->fcp_lun, sizeof(fcp_lun_t));
+	zfcp_erp_modify_unit_status(unit,
+			ZFCP_STATUS_COMMON_ACCESS_BOXED,
+			ZFCP_SET);
+	zfcp_erp_unit_reopen(unit, ZFCP_STATUS_COMMON_ERP_FAILED);
+}
+
+/*
  * function:	zfcp_erp_port_access_denied
  *
  * purpose:
@@ -3495,11 +3550,13 @@ zfcp_erp_port_access_denied(struct zfcp_
 	struct zfcp_adapter *adapter = port->adapter;
 	unsigned long flags;
 
-	debug_text_event(adapter->erp_dbf, 3, "p_access_block");
+	debug_text_event(adapter->erp_dbf, 3, "p_access_denied");
 	debug_event(adapter->erp_dbf, 3, &port->wwpn, sizeof(wwn_t));
 	read_lock_irqsave(&zfcp_data.config_lock, flags);
-	zfcp_erp_modify_port_status(port, ZFCP_STATUS_COMMON_ERP_FAILED |
-				    ZFCP_STATUS_COMMON_ACCESS_DENIED, ZFCP_SET);
+	zfcp_erp_modify_port_status(port,
+			ZFCP_STATUS_COMMON_ERP_FAILED |
+			ZFCP_STATUS_COMMON_ACCESS_DENIED,
+			ZFCP_SET);
 	read_unlock_irqrestore(&zfcp_data.config_lock, flags);
 }
 
@@ -3513,10 +3570,12 @@ zfcp_erp_unit_access_denied(struct zfcp_
 {
 	struct zfcp_adapter *adapter = unit->port->adapter;
 
-	debug_text_event(adapter->erp_dbf, 3, "u_access_block");
+	debug_text_event(adapter->erp_dbf, 3, "u_access_denied");
 	debug_event(adapter->erp_dbf, 3, &unit->fcp_lun, sizeof(fcp_lun_t));
-	zfcp_erp_modify_unit_status(unit, ZFCP_STATUS_COMMON_ERP_FAILED |
-				    ZFCP_STATUS_COMMON_ACCESS_DENIED, ZFCP_SET);
+	zfcp_erp_modify_unit_status(unit,
+			ZFCP_STATUS_COMMON_ERP_FAILED |
+			ZFCP_STATUS_COMMON_ACCESS_DENIED,
+			ZFCP_SET);
 }
 
 /*
@@ -3530,7 +3589,7 @@ zfcp_erp_adapter_access_changed(struct z
 	struct zfcp_port *port;
 	unsigned long flags;
 
-	debug_text_event(adapter->erp_dbf, 3, "a_access_unblock");
+	debug_text_event(adapter->erp_dbf, 3, "a_access_recover");
 	debug_event(adapter->erp_dbf, 3, &adapter->name, 8);
 
 	read_lock_irqsave(&zfcp_data.config_lock, flags);
@@ -3553,10 +3612,12 @@ zfcp_erp_port_access_changed(struct zfcp
 	struct zfcp_adapter *adapter = port->adapter;
 	struct zfcp_unit *unit;
 
-	debug_text_event(adapter->erp_dbf, 3, "p_access_unblock");
+	debug_text_event(adapter->erp_dbf, 3, "p_access_recover");
 	debug_event(adapter->erp_dbf, 3, &port->wwpn, sizeof(wwn_t));
 
 	if (!atomic_test_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED,
+			      &port->status) &&
+	    !atomic_test_mask(ZFCP_STATUS_COMMON_ACCESS_BOXED,
 			      &port->status)) {
 		if (!atomic_test_mask(ZFCP_STATUS_PORT_WKA, &port->status))
 			list_for_each_entry(unit, &port->unit_list_head, list)
@@ -3583,10 +3644,13 @@ zfcp_erp_unit_access_changed(struct zfcp
 {
 	struct zfcp_adapter *adapter = unit->port->adapter;
 
-	debug_text_event(adapter->erp_dbf, 3, "u_access_unblock");
+	debug_text_event(adapter->erp_dbf, 3, "u_access_recover");
 	debug_event(adapter->erp_dbf, 3, &unit->fcp_lun, sizeof(fcp_lun_t));
 
-	if (!atomic_test_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED, &unit->status))
+	if (!atomic_test_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED,
+			      &unit->status) &&
+	    !atomic_test_mask(ZFCP_STATUS_COMMON_ACCESS_BOXED,
+			      &unit->status))
 		return;
 
 	ZFCP_LOG_NORMAL("reopen of unit 0x%016Lx on port 0x%016Lx "
diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h
--- a/drivers/s390/scsi/zfcp_ext.h
+++ b/drivers/s390/scsi/zfcp_ext.h
@@ -116,7 +116,7 @@ extern int  zfcp_fsf_send_fcp_command_ta
 					   struct timer_list*, int);
 extern int  zfcp_fsf_req_complete(struct zfcp_fsf_req *);
 extern void zfcp_fsf_incoming_els(struct zfcp_fsf_req *);
-extern void zfcp_fsf_req_cleanup(struct zfcp_fsf_req *);
+extern void zfcp_fsf_req_free(struct zfcp_fsf_req *);
 extern struct zfcp_fsf_req *zfcp_fsf_send_fcp_command_task_management(
 	struct zfcp_adapter *, struct zfcp_unit *, u8, int);
 extern struct zfcp_fsf_req *zfcp_fsf_abort_fcp_command(
@@ -143,6 +143,8 @@ extern int zfcp_scsi_command_async(struc
 				   struct scsi_cmnd *, struct timer_list *);
 extern int zfcp_scsi_command_sync(struct zfcp_unit *, struct scsi_cmnd *,
 				  struct timer_list *);
+extern void zfcp_set_fc_host_attrs(struct zfcp_adapter *);
+extern void zfcp_set_fc_rport_attrs(struct zfcp_port *);
 extern struct scsi_transport_template *zfcp_transport_template;
 extern struct fc_function_template zfcp_transport_functions;
 
@@ -171,6 +173,8 @@ extern int  zfcp_erp_async_handler(struc
 
 extern int  zfcp_test_link(struct zfcp_port *);
 
+extern void zfcp_erp_port_boxed(struct zfcp_port *);
+extern void zfcp_erp_unit_boxed(struct zfcp_unit *);
 extern void zfcp_erp_port_access_denied(struct zfcp_port *);
 extern void zfcp_erp_unit_access_denied(struct zfcp_unit *);
 extern void zfcp_erp_adapter_access_changed(struct zfcp_adapter *);
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -61,7 +61,6 @@ static int zfcp_fsf_fsfstatus_eval(struc
 static int zfcp_fsf_fsfstatus_qual_eval(struct zfcp_fsf_req *);
 static int zfcp_fsf_req_dispatch(struct zfcp_fsf_req *);
 static void zfcp_fsf_req_dismiss(struct zfcp_fsf_req *);
-static void zfcp_fsf_req_free(struct zfcp_fsf_req *);
 
 /* association between FSF command and FSF QTCB type */
 static u32 fsf_qtcb_type[] = {
@@ -149,13 +148,13 @@ zfcp_fsf_req_alloc(mempool_t *pool, int 
  *
  * locks:       none
  */
-static void
+void
 zfcp_fsf_req_free(struct zfcp_fsf_req *fsf_req)
 {
 	if (likely(fsf_req->pool != NULL))
 		mempool_free(fsf_req, fsf_req->pool);
-		else
-			kfree(fsf_req);
+	else
+		kfree(fsf_req);
 }
 
 /*
@@ -170,30 +169,21 @@ zfcp_fsf_req_free(struct zfcp_fsf_req *f
 int
 zfcp_fsf_req_dismiss_all(struct zfcp_adapter *adapter)
 {
-	int retval = 0;
 	struct zfcp_fsf_req *fsf_req, *tmp;
+	unsigned long flags;
+	LIST_HEAD(remove_queue);
 
-	list_for_each_entry_safe(fsf_req, tmp, &adapter->fsf_req_list_head,
-				 list)
-	    zfcp_fsf_req_dismiss(fsf_req);
-	/* wait_event_timeout? */
-	while (!list_empty(&adapter->fsf_req_list_head)) {
-		ZFCP_LOG_DEBUG("fsf req list of adapter %s not yet empty\n",
-			       zfcp_get_busid_by_adapter(adapter));
-		/* wait for woken intiators to clean up their requests */
-		msleep(jiffies_to_msecs(ZFCP_FSFREQ_CLEANUP_TIMEOUT));
-	}
+	spin_lock_irqsave(&adapter->fsf_req_list_lock, flags);
+	list_splice_init(&adapter->fsf_req_list_head, &remove_queue);
+	atomic_set(&adapter->fsf_reqs_active, 0);
+	spin_unlock_irqrestore(&adapter->fsf_req_list_lock, flags);
 
-	/* consistency check */
-	if (atomic_read(&adapter->fsf_reqs_active)) {
-		ZFCP_LOG_NORMAL("bug: There are still %d FSF requests pending "
-				"on adapter %s after cleanup.\n",
-				atomic_read(&adapter->fsf_reqs_active),
-				zfcp_get_busid_by_adapter(adapter));
-		atomic_set(&adapter->fsf_reqs_active, 0);
+	list_for_each_entry_safe(fsf_req, tmp, &remove_queue, list) {
+		list_del(&fsf_req->list);
+		zfcp_fsf_req_dismiss(fsf_req);
 	}
 
-	return retval;
+	return 0;
 }
 
 /*
@@ -226,10 +216,6 @@ zfcp_fsf_req_complete(struct zfcp_fsf_re
 {
 	int retval = 0;
 	int cleanup;
-	struct zfcp_adapter *adapter = fsf_req->adapter;
-
-	/* do some statistics */
-	atomic_dec(&adapter->fsf_reqs_active);
 
 	if (unlikely(fsf_req->fsf_command == FSF_QTCB_UNSOLICITED_STATUS)) {
 		ZFCP_LOG_DEBUG("Status read response received\n");
@@ -260,7 +246,7 @@ zfcp_fsf_req_complete(struct zfcp_fsf_re
 		 * lock must not be held here since it will be
 		 * grabed by the called routine, too
 		 */
-		zfcp_fsf_req_cleanup(fsf_req);
+		zfcp_fsf_req_free(fsf_req);
 	} else {
 		/* notify initiator waiting for the requests completion */
 		ZFCP_LOG_TRACE("waking initiator of FSF request %p\n",fsf_req);
@@ -346,15 +332,10 @@ zfcp_fsf_protstatus_eval(struct zfcp_fsf
 	switch (fsf_req->qtcb->prefix.prot_status) {
 
 	case FSF_PROT_GOOD:
-		ZFCP_LOG_TRACE("FSF_PROT_GOOD\n");
-		break;
-
 	case FSF_PROT_FSF_STATUS_PRESENTED:
-		ZFCP_LOG_TRACE("FSF_PROT_FSF_STATUS_PRESENTED\n");
 		break;
 
 	case FSF_PROT_QTCB_VERSION_ERROR:
-		ZFCP_LOG_FLAGS(0, "FSF_PROT_QTCB_VERSION_ERROR\n");
 		ZFCP_LOG_NORMAL("error: The adapter %s contains "
 				"microcode of version 0x%x, the device driver "
 				"only supports 0x%x. Aborting.\n",
@@ -371,7 +352,6 @@ zfcp_fsf_protstatus_eval(struct zfcp_fsf
 		break;
 
 	case FSF_PROT_SEQ_NUMB_ERROR:
-		ZFCP_LOG_FLAGS(0, "FSF_PROT_SEQ_NUMB_ERROR\n");
 		ZFCP_LOG_NORMAL("bug: Sequence number mismatch between "
 				"driver (0x%x) and adapter %s (0x%x). "
 				"Restarting all operations on this adapter.\n",
@@ -390,7 +370,6 @@ zfcp_fsf_protstatus_eval(struct zfcp_fsf
 		break;
 
 	case FSF_PROT_UNSUPP_QTCB_TYPE:
-		ZFCP_LOG_FLAGS(0, "FSF_PROT_UNSUP_QTCB_TYPE\n");
 		ZFCP_LOG_NORMAL("error: Packet header type used by the "
 				"device driver is incompatible with "
 				"that used on adapter %s. "
@@ -405,7 +384,6 @@ zfcp_fsf_protstatus_eval(struct zfcp_fsf
 		break;
 
 	case FSF_PROT_HOST_CONNECTION_INITIALIZING:
-		ZFCP_LOG_FLAGS(1, "FSF_PROT_HOST_CONNECTION_INITIALIZING\n");
 		zfcp_cmd_dbf_event_fsf("hconinit", fsf_req,
 				       &fsf_req->qtcb->prefix.prot_status_qual,
 				       sizeof (union fsf_prot_status_qual));
@@ -416,7 +394,6 @@ zfcp_fsf_protstatus_eval(struct zfcp_fsf
 		break;
 
 	case FSF_PROT_DUPLICATE_REQUEST_ID:
-		ZFCP_LOG_FLAGS(0, "FSF_PROT_DUPLICATE_REQUEST_IDS\n");
 		if (fsf_req->qtcb) {
 			ZFCP_LOG_NORMAL("bug: The request identifier 0x%Lx "
 					"to the adapter %s is ambiguous. "
@@ -445,7 +422,6 @@ zfcp_fsf_protstatus_eval(struct zfcp_fsf
 		break;
 
 	case FSF_PROT_LINK_DOWN:
-		ZFCP_LOG_FLAGS(1, "FSF_PROT_LINK_DOWN\n");
 		/*
 		 * 'test and set' is not atomic here -
 		 * it's ok as long as calls to our response queue handler
@@ -502,13 +478,11 @@ zfcp_fsf_protstatus_eval(struct zfcp_fsf
 					ZFCP_STATUS_COMMON_ERP_FAILED,
 					&adapter->status);
 			zfcp_erp_adapter_reopen(adapter, 0);
-			debug_text_event(adapter->erp_dbf, 1, "prot_link_down");
 		}
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		break;
 
 	case FSF_PROT_REEST_QUEUE:
-		ZFCP_LOG_FLAGS(1, "FSF_PROT_REEST_QUEUE\n");
 		debug_text_event(adapter->erp_dbf, 1, "prot_reest_queue");
 		ZFCP_LOG_INFO("The local link to adapter with "
 			      "%s was re-plugged. "
@@ -528,7 +502,6 @@ zfcp_fsf_protstatus_eval(struct zfcp_fsf
 		break;
 
 	case FSF_PROT_ERROR_STATE:
-		ZFCP_LOG_FLAGS(0, "FSF_PROT_ERROR_STATE\n");
 		ZFCP_LOG_NORMAL("error: The adapter %s "
 				"has entered the error state. "
 				"Restarting all operations on this "
@@ -589,7 +562,6 @@ zfcp_fsf_fsfstatus_eval(struct zfcp_fsf_
 	/* evaluate FSF Status */
 	switch (fsf_req->qtcb->header.fsf_status) {
 	case FSF_UNKNOWN_COMMAND:
-		ZFCP_LOG_FLAGS(0, "FSF_UNKNOWN_COMMAND\n");
 		ZFCP_LOG_NORMAL("bug: Command issued by the device driver is "
 				"not known by the adapter %s "
 				"Stopping all operations on this adapter. "
@@ -606,14 +578,12 @@ zfcp_fsf_fsfstatus_eval(struct zfcp_fsf_
 		break;
 
 	case FSF_FCP_RSP_AVAILABLE:
-		ZFCP_LOG_FLAGS(2, "FSF_FCP_RSP_AVAILABLE\n");
 		ZFCP_LOG_DEBUG("FCP Sense data will be presented to the "
 			       "SCSI stack.\n");
 		debug_text_event(fsf_req->adapter->erp_dbf, 3, "fsf_s_rsp");
 		break;
 
 	case FSF_ADAPTER_STATUS_AVAILABLE:
-		ZFCP_LOG_FLAGS(2, "FSF_ADAPTER_STATUS_AVAILABLE\n");
 		debug_text_event(fsf_req->adapter->erp_dbf, 2, "fsf_s_astatus");
 		zfcp_fsf_fsfstatus_qual_eval(fsf_req);
 		break;
@@ -647,11 +617,9 @@ zfcp_fsf_fsfstatus_qual_eval(struct zfcp
 
 	switch (fsf_req->qtcb->header.fsf_status_qual.word[0]) {
 	case FSF_SQ_FCP_RSP_AVAILABLE:
-		ZFCP_LOG_FLAGS(2, "FSF_SQ_FCP_RSP_AVAILABLE\n");
 		debug_text_event(fsf_req->adapter->erp_dbf, 4, "fsf_sq_rsp");
 		break;
 	case FSF_SQ_RETRY_IF_POSSIBLE:
-		ZFCP_LOG_FLAGS(2, "FSF_SQ_RETRY_IF_POSSIBLE\n");
 		/* The SCSI-stack may now issue retries or escalate */
 		debug_text_event(fsf_req->adapter->erp_dbf, 2, "fsf_sq_retry");
 		zfcp_cmd_dbf_event_fsf("sqretry", fsf_req,
@@ -660,7 +628,6 @@ zfcp_fsf_fsfstatus_qual_eval(struct zfcp
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		break;
 	case FSF_SQ_COMMAND_ABORTED:
-		ZFCP_LOG_FLAGS(2, "FSF_SQ_COMMAND_ABORTED\n");
 		/* Carry the aborted state on to upper layer */
 		debug_text_event(fsf_req->adapter->erp_dbf, 2, "fsf_sq_abort");
 		zfcp_cmd_dbf_event_fsf("sqabort", fsf_req,
@@ -670,7 +637,6 @@ zfcp_fsf_fsfstatus_qual_eval(struct zfcp
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		break;
 	case FSF_SQ_NO_RECOM:
-		ZFCP_LOG_FLAGS(0, "FSF_SQ_NO_RECOM\n");
 		debug_text_exception(fsf_req->adapter->erp_dbf, 0,
 				     "fsf_sq_no_rec");
 		ZFCP_LOG_NORMAL("bug: No recommendation could be given for a"
@@ -684,7 +650,6 @@ zfcp_fsf_fsfstatus_qual_eval(struct zfcp
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		break;
 	case FSF_SQ_ULP_PROGRAMMING_ERROR:
-		ZFCP_LOG_FLAGS(0, "FSF_SQ_ULP_PROGRAMMING_ERROR\n");
 		ZFCP_LOG_NORMAL("error: not enough SBALs for data transfer "
 				"(adapter %s)\n",
 				zfcp_get_busid_by_adapter(fsf_req->adapter));
@@ -740,72 +705,58 @@ zfcp_fsf_req_dispatch(struct zfcp_fsf_re
 	switch (fsf_req->fsf_command) {
 
 	case FSF_QTCB_FCP_CMND:
-		ZFCP_LOG_FLAGS(3, "FSF_QTCB_FCP_CMND\n");
 		zfcp_fsf_send_fcp_command_handler(fsf_req);
 		break;
 
 	case FSF_QTCB_ABORT_FCP_CMND:
-		ZFCP_LOG_FLAGS(2, "FSF_QTCB_ABORT_FCP_CMND\n");
 		zfcp_fsf_abort_fcp_command_handler(fsf_req);
 		break;
 
 	case FSF_QTCB_SEND_GENERIC:
-		ZFCP_LOG_FLAGS(2, "FSF_QTCB_SEND_GENERIC\n");
 		zfcp_fsf_send_ct_handler(fsf_req);
 		break;
 
 	case FSF_QTCB_OPEN_PORT_WITH_DID:
-		ZFCP_LOG_FLAGS(2, "FSF_QTCB_OPEN_PORT_WITH_DID\n");
 		zfcp_fsf_open_port_handler(fsf_req);
 		break;
 
 	case FSF_QTCB_OPEN_LUN:
-		ZFCP_LOG_FLAGS(2, "FSF_QTCB_OPEN_LUN\n");
 		zfcp_fsf_open_unit_handler(fsf_req);
 		break;
 
 	case FSF_QTCB_CLOSE_LUN:
-		ZFCP_LOG_FLAGS(2, "FSF_QTCB_CLOSE_LUN\n");
 		zfcp_fsf_close_unit_handler(fsf_req);
 		break;
 
 	case FSF_QTCB_CLOSE_PORT:
-		ZFCP_LOG_FLAGS(2, "FSF_QTCB_CLOSE_PORT\n");
 		zfcp_fsf_close_port_handler(fsf_req);
 		break;
 
 	case FSF_QTCB_CLOSE_PHYSICAL_PORT:
-		ZFCP_LOG_FLAGS(2, "FSF_QTCB_CLOSE_PHYSICAL_PORT\n");
 		zfcp_fsf_close_physical_port_handler(fsf_req);
 		break;
 
 	case FSF_QTCB_EXCHANGE_CONFIG_DATA:
-		ZFCP_LOG_FLAGS(2, "FSF_QTCB_EXCHANGE_CONFIG_DATA\n");
 		zfcp_fsf_exchange_config_data_handler(fsf_req);
 		break;
 
 	case FSF_QTCB_EXCHANGE_PORT_DATA:
-		ZFCP_LOG_FLAGS(2, "FSF_QTCB_EXCHANGE_PORT_DATA\n");
 		zfcp_fsf_exchange_port_data_handler(fsf_req);
 		break;
 
 	case FSF_QTCB_SEND_ELS:
-		ZFCP_LOG_FLAGS(2, "FSF_QTCB_SEND_ELS\n");
 		zfcp_fsf_send_els_handler(fsf_req);
 		break;
 
 	case FSF_QTCB_DOWNLOAD_CONTROL_FILE:
-		ZFCP_LOG_FLAGS(2, "FSF_QTCB_DOWNLOAD_CONTROL_FILE\n");
 		zfcp_fsf_control_file_handler(fsf_req);
 		break;
 
 	case FSF_QTCB_UPLOAD_CONTROL_FILE:
-		ZFCP_LOG_FLAGS(2, "FSF_QTCB_UPLOAD_CONTROL_FILE\n");
 		zfcp_fsf_control_file_handler(fsf_req);
 		break;
 
 	default:
-		ZFCP_LOG_FLAGS(2, "FSF_QTCB_UNKNOWN\n");
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		ZFCP_LOG_NORMAL("bug: Command issued by the device driver is "
 				"not supported by the adapter %s\n",
@@ -929,13 +880,11 @@ zfcp_fsf_status_read_port_closed(struct 
 	switch (status_buffer->status_subtype) {
 
 	case FSF_STATUS_READ_SUB_CLOSE_PHYS_PORT:
-		ZFCP_LOG_FLAGS(2, "FSF_STATUS_READ_SUB_CLOSE_PHYS_PORT\n");
 		debug_text_event(adapter->erp_dbf, 3, "unsol_pc_phys:");
 		zfcp_erp_port_reopen(port, 0);
 		break;
 
 	case FSF_STATUS_READ_SUB_ERROR_PORT:
-		ZFCP_LOG_FLAGS(1, "FSF_STATUS_READ_SUB_ERROR_PORT\n");
 		debug_text_event(adapter->erp_dbf, 1, "unsol_pc_err:");
 		zfcp_erp_port_shutdown(port, 0);
 		break;
@@ -973,14 +922,13 @@ zfcp_fsf_status_read_handler(struct zfcp
 
 	if (fsf_req->status & ZFCP_STATUS_FSFREQ_DISMISSED) {
 		mempool_free(status_buffer, adapter->pool.data_status_read);
-		zfcp_fsf_req_cleanup(fsf_req);
+		zfcp_fsf_req_free(fsf_req);
 		goto out;
 	}
 
 	switch (status_buffer->status_type) {
 
 	case FSF_STATUS_READ_PORT_CLOSED:
-		ZFCP_LOG_FLAGS(1, "FSF_STATUS_READ_PORT_CLOSED\n");
 		debug_text_event(adapter->erp_dbf, 3, "unsol_pclosed:");
 		debug_event(adapter->erp_dbf, 3,
 			    &status_buffer->d_id, sizeof (u32));
@@ -988,13 +936,11 @@ zfcp_fsf_status_read_handler(struct zfcp
 		break;
 
 	case FSF_STATUS_READ_INCOMING_ELS:
-		ZFCP_LOG_FLAGS(1, "FSF_STATUS_READ_INCOMING_ELS\n");
 		debug_text_event(adapter->erp_dbf, 3, "unsol_els:");
 		zfcp_fsf_incoming_els(fsf_req);
 		break;
 
 	case FSF_STATUS_READ_SENSE_DATA_AVAIL:
-		ZFCP_LOG_FLAGS(1, "FSF_STATUS_READ_SENSE_DATA_AVAIL\n");
 		debug_text_event(adapter->erp_dbf, 3, "unsol_sense:");
 		ZFCP_LOG_INFO("unsolicited sense data received (adapter %s)\n",
 			      zfcp_get_busid_by_adapter(adapter));
@@ -1003,7 +949,6 @@ zfcp_fsf_status_read_handler(struct zfcp
 		break;
 
 	case FSF_STATUS_READ_BIT_ERROR_THRESHOLD:
-		ZFCP_LOG_FLAGS(1, "FSF_STATUS_READ_BIT_ERROR_THRESHOLD\n");
 		debug_text_event(adapter->erp_dbf, 3, "unsol_bit_err:");
 		ZFCP_LOG_NORMAL("Bit error threshold data received:\n");
 		ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_NORMAL,
@@ -1012,7 +957,6 @@ zfcp_fsf_status_read_handler(struct zfcp
 		break;
 
 	case FSF_STATUS_READ_LINK_DOWN:
-		ZFCP_LOG_FLAGS(1, "FSF_STATUS_READ_LINK_DOWN\n");
 		debug_text_event(adapter->erp_dbf, 0, "unsol_link_down:");
 		ZFCP_LOG_INFO("Local link to adapter %s is down\n",
 			      zfcp_get_busid_by_adapter(adapter));
@@ -1022,7 +966,6 @@ zfcp_fsf_status_read_handler(struct zfcp
 		break;
 
 	case FSF_STATUS_READ_LINK_UP:
-		ZFCP_LOG_FLAGS(1, "FSF_STATUS_READ_LINK_UP\n");
 		debug_text_event(adapter->erp_dbf, 2, "unsol_link_up:");
 		ZFCP_LOG_INFO("Local link to adapter %s was replugged. "
 			      "Restarting operations on this adapter\n",
@@ -1037,7 +980,6 @@ zfcp_fsf_status_read_handler(struct zfcp
 		break;
 
 	case FSF_STATUS_READ_CFDC_UPDATED:
-		ZFCP_LOG_FLAGS(1, "FSF_STATUS_READ_CFDC_UPDATED\n");
 		debug_text_event(adapter->erp_dbf, 2, "unsol_cfdc_update:");
 		ZFCP_LOG_INFO("CFDC has been updated on the adapter %s\n",
 			      zfcp_get_busid_by_adapter(adapter));
@@ -1045,7 +987,6 @@ zfcp_fsf_status_read_handler(struct zfcp
 		break;
 
 	case FSF_STATUS_READ_CFDC_HARDENED:
-		ZFCP_LOG_FLAGS(1, "FSF_STATUS_READ_CFDC_HARDENED\n");
 		debug_text_event(adapter->erp_dbf, 2, "unsol_cfdc_harden:");
 		switch (status_buffer->status_subtype) {
 		case FSF_STATUS_READ_SUB_CFDC_HARDENED_ON_SE:
@@ -1078,7 +1019,7 @@ zfcp_fsf_status_read_handler(struct zfcp
 		break;
 	}
 	mempool_free(status_buffer, adapter->pool.data_status_read);
-	zfcp_fsf_req_cleanup(fsf_req);
+	zfcp_fsf_req_free(fsf_req);
 	/*
 	 * recycle buffer and start new request repeat until outbound
 	 * queue is empty or adapter shutdown is requested
@@ -1214,7 +1155,6 @@ zfcp_fsf_abort_fcp_command_handler(struc
 
 	case FSF_PORT_HANDLE_NOT_VALID:
 		if (status_qual >> 4 != status_qual % 0xf) {
-			ZFCP_LOG_FLAGS(2, "FSF_PORT_HANDLE_NOT_VALID\n");
 			debug_text_event(new_fsf_req->adapter->erp_dbf, 3,
 					 "fsf_s_phand_nv0");
 			/*
@@ -1223,7 +1163,6 @@ zfcp_fsf_abort_fcp_command_handler(struc
 			 * fine.
 			 */
 		} else {
-			ZFCP_LOG_FLAGS(1, "FSF_PORT_HANDLE_NOT_VALID\n");
 			ZFCP_LOG_INFO("Temporary port identifier 0x%x for "
 				      "port 0x%016Lx on adapter %s invalid. "
 				      "This may happen occasionally.\n",
@@ -1246,7 +1185,6 @@ zfcp_fsf_abort_fcp_command_handler(struc
 	case FSF_LUN_HANDLE_NOT_VALID:
 		if (status_qual >> 4 != status_qual % 0xf) {
 			/* 2 */
-			ZFCP_LOG_FLAGS(0, "FSF_LUN_HANDLE_NOT_VALID\n");
 			debug_text_event(new_fsf_req->adapter->erp_dbf, 3,
 					 "fsf_s_lhand_nv0");
 			/*
@@ -1255,7 +1193,6 @@ zfcp_fsf_abort_fcp_command_handler(struc
 			 * This is fine.
 			 */
 		} else {
-			ZFCP_LOG_FLAGS(1, "FSF_LUN_HANDLE_NOT_VALID\n");
 			ZFCP_LOG_INFO
 			    ("Warning: Temporary LUN identifier 0x%x of LUN "
 			     "0x%016Lx on port 0x%016Lx on adapter %s is "
@@ -1279,7 +1216,6 @@ zfcp_fsf_abort_fcp_command_handler(struc
 		break;
 
 	case FSF_FCP_COMMAND_DOES_NOT_EXIST:
-		ZFCP_LOG_FLAGS(2, "FSF_FCP_COMMAND_DOES_NOT_EXIST\n");
 		retval = 0;
 		debug_text_event(new_fsf_req->adapter->erp_dbf, 3,
 				 "fsf_s_no_exist");
@@ -1287,50 +1223,37 @@ zfcp_fsf_abort_fcp_command_handler(struc
 		break;
 
 	case FSF_PORT_BOXED:
-		/* 2 */
-		ZFCP_LOG_FLAGS(0, "FSF_PORT_BOXED\n");
 		ZFCP_LOG_INFO("Remote port 0x%016Lx on adapter %s needs to "
 			      "be reopened\n", unit->port->wwpn,
 			      zfcp_get_busid_by_unit(unit));
 		debug_text_event(new_fsf_req->adapter->erp_dbf, 2,
 				 "fsf_s_pboxed");
-		zfcp_erp_port_reopen(unit->port, 0);
+		zfcp_erp_port_boxed(unit->port);
 		new_fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR
 		    | ZFCP_STATUS_FSFREQ_RETRY;
 		break;
 
 	case FSF_LUN_BOXED:
-                ZFCP_LOG_FLAGS(0, "FSF_LUN_BOXED\n");
                 ZFCP_LOG_INFO(
                         "unit 0x%016Lx on port 0x%016Lx on adapter %s needs "
                         "to be reopened\n",
                         unit->fcp_lun, unit->port->wwpn,
                         zfcp_get_busid_by_unit(unit));
                 debug_text_event(new_fsf_req->adapter->erp_dbf, 1, "fsf_s_lboxed");
-                zfcp_erp_unit_reopen(unit, 0);
-                zfcp_cmd_dbf_event_fsf("unitbox", new_fsf_req,
-                        &new_fsf_req->qtcb->header.fsf_status_qual,
-                        sizeof(union fsf_status_qual));
+		zfcp_erp_unit_boxed(unit);
                 new_fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR
                         | ZFCP_STATUS_FSFREQ_RETRY;
                 break;
 
 	case FSF_ADAPTER_STATUS_AVAILABLE:
-		/* 2 */
-		ZFCP_LOG_FLAGS(0, "FSF_ADAPTER_STATUS_AVAILABLE\n");
 		switch (new_fsf_req->qtcb->header.fsf_status_qual.word[0]) {
 		case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE:
-			ZFCP_LOG_FLAGS(2,
-				       "FSF_SQ_INVOKE_LINK_TEST_PROCEDURE\n");
 			debug_text_event(new_fsf_req->adapter->erp_dbf, 1,
 					 "fsf_sq_ltest");
-			/* reopening link to port */
-			zfcp_erp_port_reopen(unit->port, 0);
+			zfcp_test_link(unit->port);
 			new_fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 			break;
 		case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED:
-			ZFCP_LOG_FLAGS(2,
-				       "FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED\n");
 			/* SCSI stack will escalate */
 			debug_text_event(new_fsf_req->adapter->erp_dbf, 1,
 					 "fsf_sq_ulp");
@@ -1350,8 +1273,6 @@ zfcp_fsf_abort_fcp_command_handler(struc
 		break;
 
 	case FSF_GOOD:
-		/* 3 */
-		ZFCP_LOG_FLAGS(0, "FSF_GOOD\n");
 		retval = 0;
 		new_fsf_req->status |= ZFCP_STATUS_FSFREQ_ABORTSUCCEEDED;
 		break;
@@ -1553,12 +1474,10 @@ zfcp_fsf_send_ct_handler(struct zfcp_fsf
 	switch (header->fsf_status) {
 
         case FSF_GOOD:
-                ZFCP_LOG_FLAGS(2,"FSF_GOOD\n");
                 retval = 0;
 		break;
 
         case FSF_SERVICE_CLASS_NOT_SUPPORTED:
-		ZFCP_LOG_FLAGS(2, "FSF_SERVICE_CLASS_NOT_SUPPORTED\n");
 		if (adapter->fc_service_class <= 3) {
 			ZFCP_LOG_INFO("error: adapter %s does not support fc "
 				      "class %d.\n",
@@ -1578,17 +1497,14 @@ zfcp_fsf_send_ct_handler(struct zfcp_fsf
 		break;
 
         case FSF_ADAPTER_STATUS_AVAILABLE:
-                ZFCP_LOG_FLAGS(2, "FSF_ADAPTER_STATUS_AVAILABLE\n");
                 switch (header->fsf_status_qual.word[0]){
                 case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE:
-			ZFCP_LOG_FLAGS(2,"FSF_SQ_INVOKE_LINK_TEST_PROCEDURE\n");
 			/* reopening link to port */
 			debug_text_event(adapter->erp_dbf, 1, "fsf_sq_ltest");
 			zfcp_test_link(port);
 			fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 			break;
                 case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED:
-			ZFCP_LOG_FLAGS(2,"FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED\n");
 			/* ERP strategy will escalate */
 			debug_text_event(adapter->erp_dbf, 1, "fsf_sq_ulp");
 			fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
@@ -1602,7 +1518,6 @@ zfcp_fsf_send_ct_handler(struct zfcp_fsf
                 break;
 
 	case FSF_ACCESS_DENIED:
-		ZFCP_LOG_FLAGS(2, "FSF_ACCESS_DENIED\n");
 		ZFCP_LOG_NORMAL("access denied, cannot send generic service "
 				"command (adapter %s, port d_id=0x%08x)\n",
 				zfcp_get_busid_by_port(port), port->d_id);
@@ -1625,7 +1540,6 @@ zfcp_fsf_send_ct_handler(struct zfcp_fsf
 		break;
 
         case FSF_GENERIC_COMMAND_REJECTED:
-		ZFCP_LOG_FLAGS(2, "FSF_GENERIC_COMMAND_REJECTED\n");
 		ZFCP_LOG_INFO("generic service command rejected "
 			      "(adapter %s, port d_id=0x%08x)\n",
 			      zfcp_get_busid_by_port(port), port->d_id);
@@ -1638,7 +1552,6 @@ zfcp_fsf_send_ct_handler(struct zfcp_fsf
 		break;
 
         case FSF_PORT_HANDLE_NOT_VALID:
-		ZFCP_LOG_FLAGS(2, "FSF_PORT_HANDLE_NOT_VALID\n");
 		ZFCP_LOG_DEBUG("Temporary port identifier 0x%x for port "
 			       "0x%016Lx on adapter %s invalid. This may "
 			       "happen occasionally.\n", port->handle,
@@ -1653,12 +1566,11 @@ zfcp_fsf_send_ct_handler(struct zfcp_fsf
 		break;
 
         case FSF_PORT_BOXED:
-		ZFCP_LOG_FLAGS(2, "FSF_PORT_BOXED\n");
 		ZFCP_LOG_INFO("port needs to be reopened "
 			      "(adapter %s, port d_id=0x%08x)\n",
 			      zfcp_get_busid_by_port(port), port->d_id);
 		debug_text_event(adapter->erp_dbf, 2, "fsf_s_pboxed");
-		zfcp_erp_port_reopen(port, 0);
+		zfcp_erp_port_boxed(port);
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR
 		    | ZFCP_STATUS_FSFREQ_RETRY;
 		break;
@@ -1666,7 +1578,6 @@ zfcp_fsf_send_ct_handler(struct zfcp_fsf
 	/* following states should never occure, all cases avoided
 	   in zfcp_fsf_send_ct - but who knows ... */
 	case FSF_PAYLOAD_SIZE_MISMATCH:
-		ZFCP_LOG_FLAGS(2, "FSF_PAYLOAD_SIZE_MISMATCH\n");
 		ZFCP_LOG_INFO("payload size mismatch (adapter: %s, "
 			      "req_buf_length=%d, resp_buf_length=%d)\n",
 			      zfcp_get_busid_by_adapter(adapter),
@@ -1674,7 +1585,6 @@ zfcp_fsf_send_ct_handler(struct zfcp_fsf
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		break;
 	case FSF_REQUEST_SIZE_TOO_LARGE:
-		ZFCP_LOG_FLAGS(2, "FSF_REQUEST_SIZE_TOO_LARGE\n");
 		ZFCP_LOG_INFO("request size too large (adapter: %s, "
 			      "req_buf_length=%d)\n",
 			      zfcp_get_busid_by_adapter(adapter),
@@ -1682,7 +1592,6 @@ zfcp_fsf_send_ct_handler(struct zfcp_fsf
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		break;
 	case FSF_RESPONSE_SIZE_TOO_LARGE:
-		ZFCP_LOG_FLAGS(2, "FSF_RESPONSE_SIZE_TOO_LARGE\n");
 		ZFCP_LOG_INFO("response size too large (adapter: %s, "
 			      "resp_buf_length=%d)\n",
 			      zfcp_get_busid_by_adapter(adapter),
@@ -1690,7 +1599,6 @@ zfcp_fsf_send_ct_handler(struct zfcp_fsf
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		break;
 	case FSF_SBAL_MISMATCH:
-		ZFCP_LOG_FLAGS(2, "FSF_SBAL_MISMATCH\n");
 		ZFCP_LOG_INFO("SBAL mismatch (adapter: %s, req_buf_length=%d, "
 			      "resp_buf_length=%d)\n",
 			      zfcp_get_busid_by_adapter(adapter),
@@ -1846,8 +1754,8 @@ zfcp_fsf_send_els(struct zfcp_send_els *
 static int zfcp_fsf_send_els_handler(struct zfcp_fsf_req *fsf_req)
 {
 	struct zfcp_adapter *adapter;
-	fc_id_t d_id;
 	struct zfcp_port *port;
+	fc_id_t d_id;
 	struct fsf_qtcb_header *header;
 	struct fsf_qtcb_bottom_support *bottom;
 	struct zfcp_send_els *send_els;
@@ -1856,6 +1764,7 @@ static int zfcp_fsf_send_els_handler(str
 
 	send_els = fsf_req->data.send_els;
 	adapter = send_els->adapter;
+	port = send_els->port;
 	d_id = send_els->d_id;
 	header = &fsf_req->qtcb->header;
 	bottom = &fsf_req->qtcb->bottom.support;
@@ -1866,12 +1775,10 @@ static int zfcp_fsf_send_els_handler(str
 	switch (header->fsf_status) {
 
 	case FSF_GOOD:
-		ZFCP_LOG_FLAGS(2, "FSF_GOOD\n");
 		retval = 0;
 		break;
 
 	case FSF_SERVICE_CLASS_NOT_SUPPORTED:
-		ZFCP_LOG_FLAGS(2, "FSF_SERVICE_CLASS_NOT_SUPPORTED\n");
 		if (adapter->fc_service_class <= 3) {
 			ZFCP_LOG_INFO("error: adapter %s does "
 				      "not support fibrechannel class %d.\n",
@@ -1891,22 +1798,14 @@ static int zfcp_fsf_send_els_handler(str
 		break;
 
 	case FSF_ADAPTER_STATUS_AVAILABLE:
-		ZFCP_LOG_FLAGS(2, "FSF_ADAPTER_STATUS_AVAILABLE\n");
 		switch (header->fsf_status_qual.word[0]){
 		case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE:
-			ZFCP_LOG_FLAGS(2,"FSF_SQ_INVOKE_LINK_TEST_PROCEDURE\n");
 			debug_text_event(adapter->erp_dbf, 1, "fsf_sq_ltest");
-			if (send_els->ls_code != ZFCP_LS_ADISC) {
-				read_lock(&zfcp_data.config_lock);
-				port = zfcp_get_port_by_did(adapter, d_id);
-				if (port)
-					zfcp_test_link(port);
-				read_unlock(&zfcp_data.config_lock);
-			}
+			if (port && (send_els->ls_code != ZFCP_LS_ADISC))
+				zfcp_test_link(port);
 			fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 			break;
 		case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED:
-			ZFCP_LOG_FLAGS(2,"FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED\n");
 			debug_text_event(adapter->erp_dbf, 1, "fsf_sq_ulp");
 			fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 			retval =
@@ -1915,7 +1814,6 @@ static int zfcp_fsf_send_els_handler(str
 					      &header->fsf_status_qual.word[2]);
 			break;
 		case FSF_SQ_RETRY_IF_POSSIBLE:
-			ZFCP_LOG_FLAGS(2, "FSF_SQ_RETRY_IF_POSSIBLE\n");
 			debug_text_event(adapter->erp_dbf, 1, "fsf_sq_retry");
 			fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 			break;
@@ -1928,7 +1826,6 @@ static int zfcp_fsf_send_els_handler(str
 		break;
 
 	case FSF_ELS_COMMAND_REJECTED:
-		ZFCP_LOG_FLAGS(2, "FSF_ELS_COMMAND_REJECTED\n");
 		ZFCP_LOG_INFO("ELS has been rejected because command filter "
 			      "prohibited sending "
 			      "(adapter: %s, port d_id: 0x%08x)\n",
@@ -1937,7 +1834,6 @@ static int zfcp_fsf_send_els_handler(str
 		break;
 
 	case FSF_PAYLOAD_SIZE_MISMATCH:
-		ZFCP_LOG_FLAGS(2, "FSF_PAYLOAD_SIZE_MISMATCH\n");
 		ZFCP_LOG_INFO(
 			"ELS request size and ELS response size must be either "
 			"both 0, or both greater than 0 "
@@ -1948,7 +1844,6 @@ static int zfcp_fsf_send_els_handler(str
 		break;
 
 	case FSF_REQUEST_SIZE_TOO_LARGE:
-		ZFCP_LOG_FLAGS(2, "FSF_REQUEST_SIZE_TOO_LARGE\n");
 		ZFCP_LOG_INFO(
 			"Length of the ELS request buffer, "
 			"specified in QTCB bottom, "
@@ -1960,7 +1855,6 @@ static int zfcp_fsf_send_els_handler(str
 		break;
 
 	case FSF_RESPONSE_SIZE_TOO_LARGE:
-		ZFCP_LOG_FLAGS(2, "FSF_RESPONSE_SIZE_TOO_LARGE\n");
 		ZFCP_LOG_INFO(
 			"Length of the ELS response buffer, "
 			"specified in QTCB bottom, "
@@ -1973,7 +1867,6 @@ static int zfcp_fsf_send_els_handler(str
 
 	case FSF_SBAL_MISMATCH:
 		/* should never occure, avoided in zfcp_fsf_send_els */
-		ZFCP_LOG_FLAGS(2, "FSF_SBAL_MISMATCH\n");
 		ZFCP_LOG_INFO("SBAL mismatch (adapter: %s, req_buf_length=%d, "
 			      "resp_buf_length=%d)\n",
 			      zfcp_get_busid_by_adapter(adapter),
@@ -1982,7 +1875,6 @@ static int zfcp_fsf_send_els_handler(str
 		break;
 
 	case FSF_ACCESS_DENIED:
-		ZFCP_LOG_FLAGS(2, "FSF_ACCESS_DENIED\n");
 		ZFCP_LOG_NORMAL("access denied, cannot send ELS command "
 				"(adapter %s, port d_id=0x%08x)\n",
 				zfcp_get_busid_by_adapter(adapter), d_id);
@@ -2000,11 +1892,8 @@ static int zfcp_fsf_send_els_handler(str
 			}
 		}
 		debug_text_event(adapter->erp_dbf, 1, "fsf_s_access");
-		read_lock(&zfcp_data.config_lock);
-		port = zfcp_get_port_by_did(adapter, d_id);
 		if (port != NULL)
 			zfcp_erp_port_access_denied(port);
-		read_unlock(&zfcp_data.config_lock);
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		break;
 
@@ -2173,6 +2062,7 @@ zfcp_fsf_exchange_config_evaluate(struct
 		zfcp_erp_adapter_shutdown(adapter, 0);
 		return -EIO;
 	}
+	zfcp_set_fc_host_attrs(adapter);
 	return 0;
 }
 
@@ -2195,14 +2085,11 @@ zfcp_fsf_exchange_config_data_handler(st
 	switch (fsf_req->qtcb->header.fsf_status) {
 
 	case FSF_GOOD:
-		ZFCP_LOG_FLAGS(2, "FSF_GOOD\n");
-
 		if (zfcp_fsf_exchange_config_evaluate(fsf_req, 1))
 			return -EIO;
 
 		switch (adapter->fc_topology) {
 		case FSF_TOPO_P2P:
-			ZFCP_LOG_FLAGS(1, "FSF_TOPO_P2P\n");
 			ZFCP_LOG_NORMAL("Point-to-Point fibrechannel "
 					"configuration detected at adapter %s\n"
 					"Peer WWNN 0x%016llx, "
@@ -2216,7 +2103,6 @@ zfcp_fsf_exchange_config_data_handler(st
 					 "top-p-to-p");
 			break;
 		case FSF_TOPO_AL:
-			ZFCP_LOG_FLAGS(1, "FSF_TOPO_AL\n");
 			ZFCP_LOG_NORMAL("error: Arbitrated loop fibrechannel "
 					"topology detected at adapter %s "
 					"unsupported, shutting down adapter\n",
@@ -2226,7 +2112,6 @@ zfcp_fsf_exchange_config_data_handler(st
 			zfcp_erp_adapter_shutdown(adapter, 0);
 			return -EIO;
 		case FSF_TOPO_FABRIC:
-			ZFCP_LOG_FLAGS(1, "FSF_TOPO_FABRIC\n");
 			ZFCP_LOG_INFO("Switched fabric fibrechannel "
 				      "network detected at adapter %s.\n",
 				      zfcp_get_busid_by_adapter(adapter));
@@ -2357,7 +2242,7 @@ zfcp_fsf_exchange_port_data(struct zfcp_
 	wait_event(fsf_req->completion_wq,
 		   fsf_req->status & ZFCP_STATUS_FSFREQ_COMPLETED);
 	del_timer_sync(timer);
-	zfcp_fsf_req_cleanup(fsf_req);
+	zfcp_fsf_req_free(fsf_req);
  out:
 	kfree(timer);
 	return retval;
@@ -2379,7 +2264,6 @@ zfcp_fsf_exchange_port_data_handler(stru
 
 	switch (fsf_req->qtcb->header.fsf_status) {
         case FSF_GOOD:
-                ZFCP_LOG_FLAGS(2,"FSF_GOOD\n");
                 bottom = &fsf_req->qtcb->bottom.port;
                 memcpy(data, bottom, sizeof(*data));
                 break;
@@ -2481,7 +2365,6 @@ zfcp_fsf_open_port_handler(struct zfcp_f
 	switch (header->fsf_status) {
 
 	case FSF_PORT_ALREADY_OPEN:
-		ZFCP_LOG_FLAGS(0, "FSF_PORT_ALREADY_OPEN\n");
 		ZFCP_LOG_NORMAL("bug: remote port 0x%016Lx on adapter %s "
 				"is already open.\n",
 				port->wwpn, zfcp_get_busid_by_port(port));
@@ -2494,7 +2377,6 @@ zfcp_fsf_open_port_handler(struct zfcp_f
 		break;
 
 	case FSF_ACCESS_DENIED:
-		ZFCP_LOG_FLAGS(2, "FSF_ACCESS_DENIED\n");
 		ZFCP_LOG_NORMAL("Access denied, cannot open port 0x%016Lx "
 				"on adapter %s\n",
 				port->wwpn, zfcp_get_busid_by_port(port));
@@ -2517,7 +2399,6 @@ zfcp_fsf_open_port_handler(struct zfcp_f
 		break;
 
 	case FSF_MAXIMUM_NUMBER_OF_PORTS_EXCEEDED:
-		ZFCP_LOG_FLAGS(1, "FSF_MAXIMUM_NUMBER_OF_PORTS_EXCEEDED\n");
 		ZFCP_LOG_INFO("error: The FSF adapter is out of resources. "
 			      "The remote port 0x%016Lx on adapter %s "
 			      "could not be opened. Disabling it.\n",
@@ -2529,11 +2410,8 @@ zfcp_fsf_open_port_handler(struct zfcp_f
 		break;
 
 	case FSF_ADAPTER_STATUS_AVAILABLE:
-		ZFCP_LOG_FLAGS(2, "FSF_ADAPTER_STATUS_AVAILABLE\n");
 		switch (header->fsf_status_qual.word[0]) {
 		case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE:
-			ZFCP_LOG_FLAGS(2,
-				       "FSF_SQ_INVOKE_LINK_TEST_PROCEDURE\n");
 			debug_text_event(fsf_req->adapter->erp_dbf, 1,
 					 "fsf_sq_ltest");
 			/* ERP strategy will escalate */
@@ -2546,7 +2424,6 @@ zfcp_fsf_open_port_handler(struct zfcp_f
 			fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 			break;
 		case FSF_SQ_NO_RETRY_POSSIBLE:
-			ZFCP_LOG_FLAGS(0, "FSF_SQ_NO_RETRY_POSSIBLE\n");
 			ZFCP_LOG_NORMAL("The remote port 0x%016Lx on "
 					"adapter %s could not be opened. "
 					"Disabling it.\n",
@@ -2572,7 +2449,6 @@ zfcp_fsf_open_port_handler(struct zfcp_f
 		break;
 
 	case FSF_GOOD:
-		ZFCP_LOG_FLAGS(3, "FSF_GOOD\n");
 		/* save port handle assigned by FSF */
 		port->handle = header->port_handle;
 		ZFCP_LOG_INFO("The remote port 0x%016Lx via adapter %s "
@@ -2582,6 +2458,9 @@ zfcp_fsf_open_port_handler(struct zfcp_f
 		/* mark port as open */
 		atomic_set_mask(ZFCP_STATUS_COMMON_OPEN |
 				ZFCP_STATUS_PORT_PHYS_OPEN, &port->status);
+		atomic_clear_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED |
+		                  ZFCP_STATUS_COMMON_ACCESS_BOXED,
+		                  &port->status);
 		retval = 0;
 		/* check whether D_ID has changed during open */
 		/*
@@ -2630,7 +2509,6 @@ zfcp_fsf_open_port_handler(struct zfcp_f
 
 	case FSF_UNKNOWN_OP_SUBTYPE:
 		/* should never occure, subtype not set in zfcp_fsf_open_port */
-		ZFCP_LOG_FLAGS(2, "FSF_UNKNOWN_OP_SUBTYPE\n");
 		ZFCP_LOG_INFO("unknown operation subtype (adapter: %s, "
 			      "op_subtype=0x%x)\n",
 			      zfcp_get_busid_by_port(port),
@@ -2739,7 +2617,6 @@ zfcp_fsf_close_port_handler(struct zfcp_
 	switch (fsf_req->qtcb->header.fsf_status) {
 
 	case FSF_PORT_HANDLE_NOT_VALID:
-		ZFCP_LOG_FLAGS(1, "FSF_PORT_HANDLE_NOT_VALID\n");
 		ZFCP_LOG_INFO("Temporary port identifier 0x%x for port "
 			      "0x%016Lx on adapter %s invalid. This may happen "
 			      "occasionally.\n", port->handle,
@@ -2755,7 +2632,6 @@ zfcp_fsf_close_port_handler(struct zfcp_
 		break;
 
 	case FSF_ADAPTER_STATUS_AVAILABLE:
-		ZFCP_LOG_FLAGS(2, "FSF_ADAPTER_STATUS_AVAILABLE\n");
 		/* Note: FSF has actually closed the port in this case.
 		 * The status code is just daft. Fingers crossed for a change
 		 */
@@ -2763,7 +2639,6 @@ zfcp_fsf_close_port_handler(struct zfcp_
 		break;
 
 	case FSF_GOOD:
-		ZFCP_LOG_FLAGS(3, "FSF_GOOD\n");
 		ZFCP_LOG_TRACE("remote port 0x016%Lx on adapter %s closed, "
 			       "port handle 0x%x\n", port->wwpn,
 			       zfcp_get_busid_by_port(port), port->handle);
@@ -2884,7 +2759,6 @@ zfcp_fsf_close_physical_port_handler(str
 	switch (header->fsf_status) {
 
 	case FSF_PORT_HANDLE_NOT_VALID:
-		ZFCP_LOG_FLAGS(1, "FSF_PORT_HANDLE_NOT_VALID\n");
 		ZFCP_LOG_INFO("Temporary port identifier 0x%x invalid"
 			      "(adapter %s, port 0x%016Lx). "
 			      "This may happen occasionally.\n",
@@ -2902,7 +2776,6 @@ zfcp_fsf_close_physical_port_handler(str
 		break;
 
 	case FSF_ACCESS_DENIED:
-		ZFCP_LOG_FLAGS(2, "FSF_ACCESS_DENIED\n");
 		ZFCP_LOG_NORMAL("Access denied, cannot close "
 				"physical port 0x%016Lx on adapter %s\n",
 				port->wwpn, zfcp_get_busid_by_port(port));
@@ -2925,32 +2798,26 @@ zfcp_fsf_close_physical_port_handler(str
 		break;
 
 	case FSF_PORT_BOXED:
-		ZFCP_LOG_FLAGS(2, "FSF_PORT_BOXED\n");
 		ZFCP_LOG_DEBUG("The remote port 0x%016Lx on adapter "
 			       "%s needs to be reopened but it was attempted "
 			       "to close it physically.\n",
 			       port->wwpn,
 			       zfcp_get_busid_by_port(port));
 		debug_text_event(fsf_req->adapter->erp_dbf, 1, "fsf_s_pboxed");
-		zfcp_erp_port_reopen(port, 0);
+		zfcp_erp_port_boxed(port);
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR |
 			ZFCP_STATUS_FSFREQ_RETRY;
 		break;
 
 	case FSF_ADAPTER_STATUS_AVAILABLE:
-		ZFCP_LOG_FLAGS(2, "FSF_ADAPTER_STATUS_AVAILABLE\n");
 		switch (header->fsf_status_qual.word[0]) {
 		case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE:
-			ZFCP_LOG_FLAGS(2,
-				       "FSF_SQ_INVOKE_LINK_TEST_PROCEDURE\n");
 			debug_text_event(fsf_req->adapter->erp_dbf, 1,
 					 "fsf_sq_ltest");
 			/* This will now be escalated by ERP */
 			fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 			break;
 		case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED:
-			ZFCP_LOG_FLAGS(2,
-				       "FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED\n");
 			/* ERP strategy will escalate */
 			debug_text_event(fsf_req->adapter->erp_dbf, 1,
 					 "fsf_sq_ulp");
@@ -2970,7 +2837,6 @@ zfcp_fsf_close_physical_port_handler(str
 		break;
 
 	case FSF_GOOD:
-		ZFCP_LOG_FLAGS(3, "FSF_GOOD\n");
 		ZFCP_LOG_DEBUG("Remote port 0x%016Lx via adapter %s "
 			       "physically closed, port handle 0x%x\n",
 			       port->wwpn,
@@ -3116,7 +2982,6 @@ zfcp_fsf_open_unit_handler(struct zfcp_f
 	switch (header->fsf_status) {
 
 	case FSF_PORT_HANDLE_NOT_VALID:
-		ZFCP_LOG_FLAGS(1, "FSF_PORT_HANDLE_NOT_VALID\n");
 		ZFCP_LOG_INFO("Temporary port identifier 0x%x "
 			      "for port 0x%016Lx on adapter %s invalid "
 			      "This may happen occasionally\n",
@@ -3132,7 +2997,6 @@ zfcp_fsf_open_unit_handler(struct zfcp_f
 		break;
 
 	case FSF_LUN_ALREADY_OPEN:
-		ZFCP_LOG_FLAGS(0, "FSF_LUN_ALREADY_OPEN\n");
 		ZFCP_LOG_NORMAL("bug: Attempted to open unit 0x%016Lx on "
 				"remote port 0x%016Lx on adapter %s twice.\n",
 				unit->fcp_lun,
@@ -3143,7 +3007,6 @@ zfcp_fsf_open_unit_handler(struct zfcp_f
 		break;
 
 	case FSF_ACCESS_DENIED:
-		ZFCP_LOG_FLAGS(2, "FSF_ACCESS_DENIED\n");
 		ZFCP_LOG_NORMAL("Access denied, cannot open unit 0x%016Lx on "
 				"remote port 0x%016Lx on adapter %s\n",
 				unit->fcp_lun, unit->port->wwpn,
@@ -3169,18 +3032,16 @@ zfcp_fsf_open_unit_handler(struct zfcp_f
 		break;
 
 	case FSF_PORT_BOXED:
-		ZFCP_LOG_FLAGS(2, "FSF_PORT_BOXED\n");
 		ZFCP_LOG_DEBUG("The remote port 0x%016Lx on adapter %s "
 			       "needs to be reopened\n",
 			       unit->port->wwpn, zfcp_get_busid_by_unit(unit));
 		debug_text_event(adapter->erp_dbf, 2, "fsf_s_pboxed");
-		zfcp_erp_port_reopen(unit->port, 0);
+		zfcp_erp_port_boxed(unit->port);
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR |
 			ZFCP_STATUS_FSFREQ_RETRY;
 		break;
 
 	case FSF_LUN_SHARING_VIOLATION:
-		ZFCP_LOG_FLAGS(2, "FSF_LUN_SHARING_VIOLATION\n");
 		if (header->fsf_status_qual.word[0] != 0) {
 			ZFCP_LOG_NORMAL("FCP-LUN 0x%Lx at the remote port "
 					"with WWPN 0x%Lx "
@@ -3224,7 +3085,6 @@ zfcp_fsf_open_unit_handler(struct zfcp_f
 		break;
 
 	case FSF_MAXIMUM_NUMBER_OF_LUNS_EXCEEDED:
-		ZFCP_LOG_FLAGS(1, "FSF_MAXIMUM_NUMBER_OF_LUNS_EXCEEDED\n");
 		ZFCP_LOG_INFO("error: The adapter ran out of resources. "
 			      "There is no handle (temporary port identifier) "
 			      "available for unit 0x%016Lx on port 0x%016Lx "
@@ -3239,20 +3099,15 @@ zfcp_fsf_open_unit_handler(struct zfcp_f
 		break;
 
 	case FSF_ADAPTER_STATUS_AVAILABLE:
-		ZFCP_LOG_FLAGS(2, "FSF_ADAPTER_STATUS_AVAILABLE\n");
 		switch (header->fsf_status_qual.word[0]) {
 		case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE:
-			ZFCP_LOG_FLAGS(2,
-				       "FSF_SQ_INVOKE_LINK_TEST_PROCEDURE\n");
 			/* Re-establish link to port */
 			debug_text_event(adapter->erp_dbf, 1,
 					 "fsf_sq_ltest");
-			zfcp_erp_port_reopen(unit->port, 0);
+			zfcp_test_link(unit->port);
 			fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 			break;
 		case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED:
-			ZFCP_LOG_FLAGS(2,
-				       "FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED\n");
 			/* ERP strategy will escalate */
 			debug_text_event(adapter->erp_dbf, 1,
 					 "fsf_sq_ulp");
@@ -3271,7 +3126,6 @@ zfcp_fsf_open_unit_handler(struct zfcp_f
 		break;
 
 	case FSF_INVALID_COMMAND_OPTION:
-		ZFCP_LOG_FLAGS(2, "FSF_INVALID_COMMAND_OPTION\n");
 		ZFCP_LOG_NORMAL(
 			"Invalid option 0x%x has been specified "
 			"in QTCB bottom sent to the adapter %s\n",
@@ -3282,7 +3136,6 @@ zfcp_fsf_open_unit_handler(struct zfcp_f
 		break;
 
 	case FSF_GOOD:
-		ZFCP_LOG_FLAGS(3, "FSF_GOOD\n");
 		/* save LUN handle assigned by FSF */
 		unit->handle = header->lun_handle;
 		ZFCP_LOG_TRACE("unit 0x%016Lx on remote port 0x%016Lx on "
@@ -3293,7 +3146,9 @@ zfcp_fsf_open_unit_handler(struct zfcp_f
 			       unit->handle);
 		/* mark unit as open */
 		atomic_set_mask(ZFCP_STATUS_COMMON_OPEN, &unit->status);
-
+		atomic_clear_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED |
+		                  ZFCP_STATUS_COMMON_ACCESS_BOXED,
+		                  &unit->status);
 		if (adapter->supported_features & FSF_FEATURE_LUN_SHARING){
 			if (!exclusive)
 		                atomic_set_mask(ZFCP_STATUS_UNIT_SHARED,
@@ -3437,7 +3292,6 @@ zfcp_fsf_close_unit_handler(struct zfcp_
 	switch (fsf_req->qtcb->header.fsf_status) {
 
 	case FSF_PORT_HANDLE_NOT_VALID:
-		ZFCP_LOG_FLAGS(1, "FSF_PORT_HANDLE_NOT_VALID\n");
 		ZFCP_LOG_INFO("Temporary port identifier 0x%x for port "
 			      "0x%016Lx on adapter %s invalid. This may "
 			      "happen in rare circumstances\n",
@@ -3458,7 +3312,6 @@ zfcp_fsf_close_unit_handler(struct zfcp_
 		break;
 
 	case FSF_LUN_HANDLE_NOT_VALID:
-		ZFCP_LOG_FLAGS(1, "FSF_LUN_HANDLE_NOT_VALID\n");
 		ZFCP_LOG_INFO("Temporary LUN identifier 0x%x of unit "
 			      "0x%016Lx on port 0x%016Lx on adapter %s is "
 			      "invalid. This may happen occasionally.\n",
@@ -3480,32 +3333,26 @@ zfcp_fsf_close_unit_handler(struct zfcp_
 		break;
 
 	case FSF_PORT_BOXED:
-		ZFCP_LOG_FLAGS(2, "FSF_PORT_BOXED\n");
 		ZFCP_LOG_DEBUG("The remote port 0x%016Lx on adapter %s "
 			       "needs to be reopened\n",
 			       unit->port->wwpn,
 			       zfcp_get_busid_by_unit(unit));
 		debug_text_event(fsf_req->adapter->erp_dbf, 2, "fsf_s_pboxed");
-		zfcp_erp_port_reopen(unit->port, 0);
+		zfcp_erp_port_boxed(unit->port);
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR |
 			ZFCP_STATUS_FSFREQ_RETRY;
 		break;
 
 	case FSF_ADAPTER_STATUS_AVAILABLE:
-		ZFCP_LOG_FLAGS(2, "FSF_ADAPTER_STATUS_AVAILABLE\n");
 		switch (fsf_req->qtcb->header.fsf_status_qual.word[0]) {
 		case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE:
-			ZFCP_LOG_FLAGS(2,
-				       "FSF_SQ_INVOKE_LINK_TEST_PROCEDURE\n");
 			/* re-establish link to port */
 			debug_text_event(fsf_req->adapter->erp_dbf, 1,
 					 "fsf_sq_ltest");
-			zfcp_erp_port_reopen(unit->port, 0);
+			zfcp_test_link(unit->port);
 			fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 			break;
 		case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED:
-			ZFCP_LOG_FLAGS(2,
-				       "FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED\n");
 			/* ERP strategy will escalate */
 			debug_text_event(fsf_req->adapter->erp_dbf, 1,
 					 "fsf_sq_ulp");
@@ -3526,7 +3373,6 @@ zfcp_fsf_close_unit_handler(struct zfcp_
 		break;
 
 	case FSF_GOOD:
-		ZFCP_LOG_FLAGS(3, "FSF_GOOD\n");
 		ZFCP_LOG_TRACE("unit 0x%016Lx on port 0x%016Lx on adapter %s "
 			       "closed, port handle 0x%x\n",
 			       unit->fcp_lun,
@@ -3622,7 +3468,6 @@ zfcp_fsf_send_fcp_command_task(struct zf
 	 */
 	switch (scsi_cmnd->sc_data_direction) {
 	case DMA_NONE:
-		ZFCP_LOG_FLAGS(3, "DMA_NONE\n");
 		fsf_req->qtcb->bottom.io.data_direction = FSF_DATADIR_CMND;
 		/*
 		 * FIXME(qdio):
@@ -3632,19 +3477,16 @@ zfcp_fsf_send_fcp_command_task(struct zf
 		sbtype = SBAL_FLAGS0_TYPE_READ;
 		break;
 	case DMA_FROM_DEVICE:
-		ZFCP_LOG_FLAGS(3, "DMA_FROM_DEVICE\n");
 		fsf_req->qtcb->bottom.io.data_direction = FSF_DATADIR_READ;
 		sbtype = SBAL_FLAGS0_TYPE_READ;
 		fcp_cmnd_iu->rddata = 1;
 		break;
 	case DMA_TO_DEVICE:
-		ZFCP_LOG_FLAGS(3, "DMA_TO_DEVICE\n");
 		fsf_req->qtcb->bottom.io.data_direction = FSF_DATADIR_WRITE;
 		sbtype = SBAL_FLAGS0_TYPE_WRITE;
 		fcp_cmnd_iu->wddata = 1;
 		break;
 	case DMA_BIDIRECTIONAL:
-		ZFCP_LOG_FLAGS(0, "DMA_BIDIRECTIONAL not supported\n");
 	default:
 		/*
 		 * dummy, catch this condition earlier
@@ -3877,7 +3719,6 @@ zfcp_fsf_send_fcp_command_handler(struct
 	switch (header->fsf_status) {
 
 	case FSF_PORT_HANDLE_NOT_VALID:
-		ZFCP_LOG_FLAGS(1, "FSF_PORT_HANDLE_NOT_VALID\n");
 		ZFCP_LOG_INFO("Temporary port identifier 0x%x for port "
 			      "0x%016Lx on adapter %s invalid\n",
 			      unit->port->handle,
@@ -3892,7 +3733,6 @@ zfcp_fsf_send_fcp_command_handler(struct
 		break;
 
 	case FSF_LUN_HANDLE_NOT_VALID:
-		ZFCP_LOG_FLAGS(1, "FSF_LUN_HANDLE_NOT_VALID\n");
 		ZFCP_LOG_INFO("Temporary LUN identifier 0x%x for unit "
 			      "0x%016Lx on port 0x%016Lx on adapter %s is "
 			      "invalid. This may happen occasionally.\n",
@@ -3911,7 +3751,6 @@ zfcp_fsf_send_fcp_command_handler(struct
 		break;
 
 	case FSF_HANDLE_MISMATCH:
-		ZFCP_LOG_FLAGS(0, "FSF_HANDLE_MISMATCH\n");
 		ZFCP_LOG_NORMAL("bug: The port handle 0x%x has changed "
 				"unexpectedly. (adapter %s, port 0x%016Lx, "
 				"unit 0x%016Lx)\n",
@@ -3934,7 +3773,6 @@ zfcp_fsf_send_fcp_command_handler(struct
 		break;
 
 	case FSF_SERVICE_CLASS_NOT_SUPPORTED:
-		ZFCP_LOG_FLAGS(0, "FSF_SERVICE_CLASS_NOT_SUPPORTED\n");
 		if (fsf_req->adapter->fc_service_class <= 3) {
 			ZFCP_LOG_NORMAL("error: The adapter %s does "
 					"not support fibrechannel class %d.\n",
@@ -3959,7 +3797,6 @@ zfcp_fsf_send_fcp_command_handler(struct
 		break;
 
 	case FSF_FCPLUN_NOT_VALID:
-		ZFCP_LOG_FLAGS(0, "FSF_FCPLUN_NOT_VALID\n");
 		ZFCP_LOG_NORMAL("bug: unit 0x%016Lx on port 0x%016Lx on "
 				"adapter %s does not have correct unit "
 				"handle 0x%x\n",
@@ -3982,7 +3819,6 @@ zfcp_fsf_send_fcp_command_handler(struct
 		break;
 
 	case FSF_ACCESS_DENIED:
-		ZFCP_LOG_FLAGS(2, "FSF_ACCESS_DENIED\n");
 		ZFCP_LOG_NORMAL("Access denied, cannot send FCP command to "
 				"unit 0x%016Lx on port 0x%016Lx on "
 				"adapter %s\n",	unit->fcp_lun, unit->port->wwpn,
@@ -4006,7 +3842,6 @@ zfcp_fsf_send_fcp_command_handler(struct
 		break;
 
 	case FSF_DIRECTION_INDICATOR_NOT_VALID:
-		ZFCP_LOG_FLAGS(0, "FSF_DIRECTION_INDICATOR_NOT_VALID\n");
 		ZFCP_LOG_INFO("bug: Invalid data direction given for unit "
 			      "0x%016Lx on port 0x%016Lx on adapter %s "
 			      "(debug info %d)\n",
@@ -4026,7 +3861,6 @@ zfcp_fsf_send_fcp_command_handler(struct
 		break;
 
 	case FSF_CMND_LENGTH_NOT_VALID:
-		ZFCP_LOG_FLAGS(0, "FSF_CMND_LENGTH_NOT_VALID\n");
 		ZFCP_LOG_NORMAL
 		    ("bug: An invalid control-data-block length field "
 		     "was found in a command for unit 0x%016Lx on port "
@@ -4046,69 +3880,43 @@ zfcp_fsf_send_fcp_command_handler(struct
 		break;
 
 	case FSF_PORT_BOXED:
-		ZFCP_LOG_FLAGS(2, "FSF_PORT_BOXED\n");
 		ZFCP_LOG_DEBUG("The remote port 0x%016Lx on adapter %s "
 			       "needs to be reopened\n",
 			       unit->port->wwpn, zfcp_get_busid_by_unit(unit));
 		debug_text_event(fsf_req->adapter->erp_dbf, 2, "fsf_s_pboxed");
-		zfcp_erp_port_reopen(unit->port, 0);
-		zfcp_cmd_dbf_event_fsf("portbox", fsf_req,
-				       &header->fsf_status_qual,
-				       sizeof (union fsf_status_qual));
+		zfcp_erp_port_boxed(unit->port);
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR |
 			ZFCP_STATUS_FSFREQ_RETRY;
 		break;
 
 	case FSF_LUN_BOXED:
-		ZFCP_LOG_FLAGS(0, "FSF_LUN_BOXED\n");
 		ZFCP_LOG_NORMAL("unit needs to be reopened (adapter %s, "
 				"wwpn=0x%016Lx, fcp_lun=0x%016Lx)\n",
 				zfcp_get_busid_by_unit(unit),
 				unit->port->wwpn, unit->fcp_lun);
 		debug_text_event(fsf_req->adapter->erp_dbf, 1, "fsf_s_lboxed");
-		zfcp_erp_unit_reopen(unit, 0);
-		zfcp_cmd_dbf_event_fsf("unitbox", fsf_req,
-				       &header->fsf_status_qual,
-				       sizeof(union fsf_status_qual));
+		zfcp_erp_unit_boxed(unit);
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR
 			| ZFCP_STATUS_FSFREQ_RETRY;
 		break;
 
 	case FSF_ADAPTER_STATUS_AVAILABLE:
-		ZFCP_LOG_FLAGS(2, "FSF_ADAPTER_STATUS_AVAILABLE\n");
 		switch (header->fsf_status_qual.word[0]) {
 		case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE:
-			ZFCP_LOG_FLAGS(2,
-				       "FSF_SQ_INVOKE_LINK_TEST_PROCEDURE\n");
 			/* re-establish link to port */
 			debug_text_event(fsf_req->adapter->erp_dbf, 1,
 					 "fsf_sq_ltest");
-			zfcp_erp_port_reopen(unit->port, 0);
-			zfcp_cmd_dbf_event_fsf(
-				"sqltest",
-				fsf_req,
-				&header->fsf_status_qual,
-				sizeof (union fsf_status_qual));
-			fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
+ 			zfcp_test_link(unit->port);
 			break;
 		case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED:
-			ZFCP_LOG_FLAGS(3,
-				       "FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED\n");
 			/* FIXME(hw) need proper specs for proper action */
 			/* let scsi stack deal with retries and escalation */
 			debug_text_event(fsf_req->adapter->erp_dbf, 1,
 					 "fsf_sq_ulp");
-			zfcp_cmd_dbf_event_fsf(
-				"sqdeperp",
-				fsf_req,
-				&header->fsf_status_qual,
-				sizeof (union fsf_status_qual));
-			fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 			break;
 		default:
-			/* FIXME: shall we consider this a successful transfer? */
 			ZFCP_LOG_NORMAL
-			    ("bug: Wrong status qualifier 0x%x arrived.\n",
+ 			    ("Unknown status qualifier 0x%x arrived.\n",
 			     header->fsf_status_qual.word[0]);
 			debug_text_event(fsf_req->adapter->erp_dbf, 0,
 					 "fsf_sq_inval:");
@@ -4117,14 +3925,13 @@ zfcp_fsf_send_fcp_command_handler(struct
 					sizeof(u32));
 			break;
 		}
+		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		break;
 
 	case FSF_GOOD:
-		ZFCP_LOG_FLAGS(3, "FSF_GOOD\n");
 		break;
 
 	case FSF_FCP_RSP_AVAILABLE:
-		ZFCP_LOG_FLAGS(2, "FSF_FCP_RSP_AVAILABLE\n");
 		break;
 
 	default:
@@ -4217,14 +4024,12 @@ zfcp_fsf_send_fcp_command_task_handler(s
 		ZFCP_LOG_DEBUG("rsp_len is valid\n");
 		switch (fcp_rsp_info[3]) {
 		case RSP_CODE_GOOD:
-			ZFCP_LOG_FLAGS(3, "RSP_CODE_GOOD\n");
 			/* ok, continue */
 			ZFCP_LOG_TRACE("no failure or Task Management "
 				       "Function complete\n");
 			set_host_byte(&scpnt->result, DID_OK);
 			break;
 		case RSP_CODE_LENGTH_MISMATCH:
-			ZFCP_LOG_FLAGS(0, "RSP_CODE_LENGTH_MISMATCH\n");
 			/* hardware bug */
 			ZFCP_LOG_NORMAL("bug: FCP response code indictates "
 					"that the fibrechannel protocol data "
@@ -4242,7 +4047,6 @@ zfcp_fsf_send_fcp_command_task_handler(s
 			set_host_byte(&scpnt->result, DID_ERROR);
 			goto skip_fsfstatus;
 		case RSP_CODE_FIELD_INVALID:
-			ZFCP_LOG_FLAGS(0, "RSP_CODE_FIELD_INVALID\n");
 			/* driver or hardware bug */
 			ZFCP_LOG_NORMAL("bug: FCP response code indictates "
 					"that the fibrechannel protocol data "
@@ -4261,7 +4065,6 @@ zfcp_fsf_send_fcp_command_task_handler(s
 			zfcp_cmd_dbf_event_fsf("codeinv", fsf_req, NULL, 0);
 			goto skip_fsfstatus;
 		case RSP_CODE_RO_MISMATCH:
-			ZFCP_LOG_FLAGS(0, "RSP_CODE_RO_MISMATCH\n");
 			/* hardware bug */
 			ZFCP_LOG_NORMAL("bug: The FCP response code indicates "
 					"that conflicting  values for the "
@@ -4407,13 +4210,11 @@ zfcp_fsf_send_fcp_command_task_managemen
 	/* check FCP_RSP_INFO */
 	switch (fcp_rsp_info[3]) {
 	case RSP_CODE_GOOD:
-		ZFCP_LOG_FLAGS(3, "RSP_CODE_GOOD\n");
 		/* ok, continue */
 		ZFCP_LOG_DEBUG("no failure or Task Management "
 			       "Function complete\n");
 		break;
 	case RSP_CODE_TASKMAN_UNSUPP:
-		ZFCP_LOG_FLAGS(0, "RSP_CODE_TASKMAN_UNSUPP\n");
 		ZFCP_LOG_NORMAL("bug: A reuested task management function "
 				"is not supported on the target device "
 				"unit 0x%016Lx, port 0x%016Lx, adapter %s\n ",
@@ -4423,7 +4224,6 @@ zfcp_fsf_send_fcp_command_task_managemen
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_TMFUNCNOTSUPP;
 		break;
 	case RSP_CODE_TASKMAN_FAILED:
-		ZFCP_LOG_FLAGS(0, "RSP_CODE_TASKMAN_FAILED\n");
 		ZFCP_LOG_NORMAL("bug: A reuested task management function "
 				"failed to complete successfully. "
 				"unit 0x%016Lx, port 0x%016Lx, adapter %s.\n",
@@ -4610,7 +4410,6 @@ zfcp_fsf_control_file_handler(struct zfc
 	switch (header->fsf_status) {
 
 	case FSF_GOOD:
-		ZFCP_LOG_FLAGS(2, "FSF_GOOD\n");
 		ZFCP_LOG_NORMAL(
 			"The FSF request has been successfully completed "
 			"on the adapter %s\n",
@@ -4618,7 +4417,6 @@ zfcp_fsf_control_file_handler(struct zfc
 		break;
 
 	case FSF_OPERATION_PARTIALLY_SUCCESSFUL:
-		ZFCP_LOG_FLAGS(2, "FSF_OPERATION_PARTIALLY_SUCCESSFUL\n");
 		if (bottom->operation_subtype == FSF_CFDC_OPERATION_SUBTYPE) {
 			switch (header->fsf_status_qual.word[0]) {
 
@@ -4655,7 +4453,6 @@ zfcp_fsf_control_file_handler(struct zfc
 		break;
 
 	case FSF_AUTHORIZATION_FAILURE:
-		ZFCP_LOG_FLAGS(2, "FSF_AUTHORIZATION_FAILURE\n");
 		ZFCP_LOG_NORMAL(
 			"Adapter %s does not accept privileged commands\n",
 			zfcp_get_busid_by_adapter(adapter));
@@ -4664,7 +4461,6 @@ zfcp_fsf_control_file_handler(struct zfc
 		break;
 
 	case FSF_CFDC_ERROR_DETECTED:
-		ZFCP_LOG_FLAGS(2, "FSF_CFDC_ERROR_DETECTED\n");
 		ZFCP_LOG_NORMAL(
 			"Error at position %d in the CFDC, "
 			"CFDC is discarded by the adapter %s\n",
@@ -4675,7 +4471,6 @@ zfcp_fsf_control_file_handler(struct zfc
 		break;
 
 	case FSF_CONTROL_FILE_UPDATE_ERROR:
-		ZFCP_LOG_FLAGS(2, "FSF_CONTROL_FILE_UPDATE_ERROR\n");
 		ZFCP_LOG_NORMAL(
 			"Adapter %s cannot harden the control file, "
 			"file is discarded\n",
@@ -4685,7 +4480,6 @@ zfcp_fsf_control_file_handler(struct zfc
 		break;
 
 	case FSF_CONTROL_FILE_TOO_LARGE:
-		ZFCP_LOG_FLAGS(2, "FSF_CONTROL_FILE_TOO_LARGE\n");
 		ZFCP_LOG_NORMAL(
 			"Control file is too large, file is discarded "
 			"by the adapter %s\n",
@@ -4695,7 +4489,6 @@ zfcp_fsf_control_file_handler(struct zfc
 		break;
 
 	case FSF_ACCESS_CONFLICT_DETECTED:
-		ZFCP_LOG_FLAGS(2, "FSF_ACCESS_CONFLICT_DETECTED\n");
 		if (bottom->operation_subtype == FSF_CFDC_OPERATION_SUBTYPE)
 			ZFCP_LOG_NORMAL(
 				"CFDC has been discarded by the adapter %s, "
@@ -4708,7 +4501,6 @@ zfcp_fsf_control_file_handler(struct zfc
 		break;
 
 	case FSF_CONFLICTS_OVERRULED:
-		ZFCP_LOG_FLAGS(2, "FSF_CONFLICTS_OVERRULED\n");
 		if (bottom->operation_subtype == FSF_CFDC_OPERATION_SUBTYPE)
 			ZFCP_LOG_NORMAL(
 				"CFDC has been activated on the adapter %s, "
@@ -4721,7 +4513,6 @@ zfcp_fsf_control_file_handler(struct zfc
 		break;
 
 	case FSF_UNKNOWN_OP_SUBTYPE:
-		ZFCP_LOG_FLAGS(2, "FSF_UNKNOWN_OP_SUBTYPE\n");
 		ZFCP_LOG_NORMAL("unknown operation subtype (adapter: %s, "
 				"op_subtype=0x%x)\n",
 				zfcp_get_busid_by_adapter(adapter),
@@ -4731,7 +4522,6 @@ zfcp_fsf_control_file_handler(struct zfc
 		break;
 
 	case FSF_INVALID_COMMAND_OPTION:
-		ZFCP_LOG_FLAGS(2, "FSF_INVALID_COMMAND_OPTION\n");
 		ZFCP_LOG_NORMAL(
 			"Invalid option 0x%x has been specified "
 			"in QTCB bottom sent to the adapter %s\n",
@@ -4800,7 +4590,7 @@ zfcp_fsf_req_wait_and_cleanup(struct zfc
 	*status = fsf_req->status;
 
 	/* cleanup request */
-	zfcp_fsf_req_cleanup(fsf_req);
+	zfcp_fsf_req_free(fsf_req);
  out:
 	return retval;
 }
@@ -4999,9 +4789,9 @@ zfcp_fsf_req_send(struct zfcp_fsf_req *f
 		inc_seq_no = 0;
 
 	/* put allocated FSF request at list tail */
-	write_lock_irqsave(&adapter->fsf_req_list_lock, flags);
+	spin_lock_irqsave(&adapter->fsf_req_list_lock, flags);
 	list_add_tail(&fsf_req->list, &adapter->fsf_req_list_head);
-	write_unlock_irqrestore(&adapter->fsf_req_list_lock, flags);
+	spin_unlock_irqrestore(&adapter->fsf_req_list_lock, flags);
 
 	/* figure out expiration time of timeout and start timeout */
 	if (unlikely(timer)) {
@@ -5045,9 +4835,9 @@ zfcp_fsf_req_send(struct zfcp_fsf_req *f
 		 */
 		if (timer)
 			del_timer(timer);
-		write_lock_irqsave(&adapter->fsf_req_list_lock, flags);
+		spin_lock_irqsave(&adapter->fsf_req_list_lock, flags);
 		list_del(&fsf_req->list);
-		write_unlock_irqrestore(&adapter->fsf_req_list_lock, flags);
+		spin_unlock_irqrestore(&adapter->fsf_req_list_lock, flags);
 		/*
 		 * adjust the number of free SBALs in request queue as well as
 		 * position of first one
@@ -5085,25 +4875,4 @@ zfcp_fsf_req_send(struct zfcp_fsf_req *f
 	return retval;
 }
 
-/*
- * function:    zfcp_fsf_req_cleanup
- *
- * purpose:	cleans up an FSF request and removes it from the specified list
- *
- * returns:
- *
- * assumption:	no pending SB in SBALEs other than QTCB
- */
-void
-zfcp_fsf_req_cleanup(struct zfcp_fsf_req *fsf_req)
-{
-	struct zfcp_adapter *adapter = fsf_req->adapter;
-	unsigned long flags;
-
-	write_lock_irqsave(&adapter->fsf_req_list_lock, flags);
-	list_del(&fsf_req->list);
-	write_unlock_irqrestore(&adapter->fsf_req_list_lock, flags);
-	zfcp_fsf_req_free(fsf_req);
-}
-
 #undef ZFCP_LOG_AREA
diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c
--- a/drivers/s390/scsi/zfcp_qdio.c
+++ b/drivers/s390/scsi/zfcp_qdio.c
@@ -229,52 +229,14 @@ zfcp_qdio_handler_error_check(struct zfc
 			ZFCP_LOG_TRACE("status is"
 				       " QDIO_STATUS_OUTBOUND_INT \n");
 		}
-	}			// if (ZFCP_LOG_CHECK(ZFCP_LOG_LEVEL_TRACE))
+	}
 	if (unlikely(status & QDIO_STATUS_LOOK_FOR_ERROR)) {
 		retval = -EIO;
 
-		ZFCP_LOG_FLAGS(1, "QDIO_STATUS_LOOK_FOR_ERROR \n");
-
 		ZFCP_LOG_INFO("QDIO problem occurred (status=0x%x, "
 			      "qdio_error=0x%x, siga_error=0x%x)\n",
 			      status, qdio_error, siga_error);
 
-		if (status & QDIO_STATUS_ACTIVATE_CHECK_CONDITION) {
-			ZFCP_LOG_FLAGS(2,
-				       "QDIO_STATUS_ACTIVATE_CHECK_CONDITION\n");
-		}
-		if (status & QDIO_STATUS_MORE_THAN_ONE_QDIO_ERROR) {
-			ZFCP_LOG_FLAGS(2,
-				       "QDIO_STATUS_MORE_THAN_ONE_QDIO_ERROR\n");
-		}
-		if (status & QDIO_STATUS_MORE_THAN_ONE_SIGA_ERROR) {
-			ZFCP_LOG_FLAGS(2,
-				       "QDIO_STATUS_MORE_THAN_ONE_SIGA_ERROR\n");
-		}
-
-		if (siga_error & QDIO_SIGA_ERROR_ACCESS_EXCEPTION) {
-			ZFCP_LOG_FLAGS(2, "QDIO_SIGA_ERROR_ACCESS_EXCEPTION\n");
-		}
-
-		if (siga_error & QDIO_SIGA_ERROR_B_BIT_SET) {
-			ZFCP_LOG_FLAGS(2, "QDIO_SIGA_ERROR_B_BIT_SET\n");
-		}
-
-		switch (qdio_error) {
-		case 0:
-			ZFCP_LOG_FLAGS(3, "QDIO_OK");
-			break;
-		case SLSB_P_INPUT_ERROR:
-			ZFCP_LOG_FLAGS(1, "SLSB_P_INPUT_ERROR\n");
-			break;
-		case SLSB_P_OUTPUT_ERROR:
-			ZFCP_LOG_FLAGS(1, "SLSB_P_OUTPUT_ERROR\n");
-			break;
-		default:
-			ZFCP_LOG_NORMAL("bug: unknown QDIO error 0x%x\n",
-					qdio_error);
-			break;
-		}
 		/* Restarting IO on the failed adapter from scratch */
 		debug_text_event(adapter->erp_dbf, 1, "qdio_err");
                /*
@@ -484,37 +446,37 @@ int
 zfcp_qdio_reqid_check(struct zfcp_adapter *adapter, void *sbale_addr)
 {
 	struct zfcp_fsf_req *fsf_req;
-	int retval = 0;
 
 	/* invalid (per convention used in this driver) */
 	if (unlikely(!sbale_addr)) {
 		ZFCP_LOG_NORMAL("bug: invalid reqid\n");
-		retval = -EINVAL;
-		goto out;
+		return -EINVAL;
 	}
 
 	/* valid request id and thus (hopefully :) valid fsf_req address */
 	fsf_req = (struct zfcp_fsf_req *) sbale_addr;
 
+	/* serialize with zfcp_fsf_req_dismiss_all */
+	spin_lock(&adapter->fsf_req_list_lock);
+	if (list_empty(&adapter->fsf_req_list_head)) {
+		spin_unlock(&adapter->fsf_req_list_lock);
+		return 0;
+	}
+	list_del(&fsf_req->list);
+	atomic_dec(&adapter->fsf_reqs_active);
+	spin_unlock(&adapter->fsf_req_list_lock);
+	
 	if (unlikely(adapter != fsf_req->adapter)) {
 		ZFCP_LOG_NORMAL("bug: invalid reqid (fsf_req=%p, "
 				"fsf_req->adapter=%p, adapter=%p)\n",
 				fsf_req, fsf_req->adapter, adapter);
-		retval = -EINVAL;
-		goto out;
-	}
-
-	ZFCP_LOG_TRACE("fsf_req at %p, QTCB at %p\n", fsf_req, fsf_req->qtcb);
-	if (likely(fsf_req->qtcb)) {
-		ZFCP_LOG_TRACE("hex dump of QTCB:\n");
-		ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_TRACE, (char *) fsf_req->qtcb,
-			      sizeof(struct fsf_qtcb));
+		return -EINVAL;
 	}
 
 	/* finish the FSF request */
 	zfcp_fsf_req_complete(fsf_req);
- out:
-	return retval;
+
+	return 0;
 }
 
 /**
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
--- a/drivers/s390/scsi/zfcp_scsi.c
+++ b/drivers/s390/scsi/zfcp_scsi.c
@@ -389,7 +389,7 @@ zfcp_unit_lookup(struct zfcp_adapter *ad
 	struct zfcp_unit *unit, *retval = NULL;
 
 	list_for_each_entry(port, &adapter->port_list_head, list) {
-		if (id != port->scsi_id)
+		if (!port->rport || (id != port->rport->scsi_target_id))
 			continue;
 		list_for_each_entry(unit, &port->unit_list_head, list) {
 			if (lun == unit->scsi_lun) {
@@ -408,7 +408,7 @@ zfcp_port_lookup(struct zfcp_adapter *ad
 	struct zfcp_port *port;
 
 	list_for_each_entry(port, &adapter->port_list_head, list) {
-		if (id == port->scsi_id)
+		if (port->rport && (id == port->rport->scsi_target_id))
 			return port;
 	}
 	return (struct zfcp_port *) NULL;
@@ -433,7 +433,7 @@ zfcp_port_lookup(struct zfcp_adapter *ad
  *		FAILED	- otherwise
  */
 int
-zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)
+__zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)
 {
 	int retval = SUCCESS;
 	struct zfcp_fsf_req *new_fsf_req, *old_fsf_req;
@@ -575,7 +575,7 @@ zfcp_scsi_eh_abort_handler(struct scsi_c
 	    *(u64 *) & new_fsf_req->qtcb->header.fsf_status_qual.word[0];
 	dbf_fsf_qual[1] =
 	    *(u64 *) & new_fsf_req->qtcb->header.fsf_status_qual.word[2];
-	zfcp_fsf_req_cleanup(new_fsf_req);
+	zfcp_fsf_req_free(new_fsf_req);
 #else
 	retval = zfcp_fsf_req_wait_and_cleanup(new_fsf_req,
 					       ZFCP_UNINTERRUPTIBLE, &status);
@@ -611,6 +611,17 @@ zfcp_scsi_eh_abort_handler(struct scsi_c
 	return retval;
 }
 
+int
+zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)
+{
+	int rc;
+	struct Scsi_Host *scsi_host = scpnt->device->host;
+	spin_lock_irq(scsi_host->host_lock);
+	rc = __zfcp_scsi_eh_abort_handler(scpnt);
+	spin_unlock_irq(scsi_host->host_lock);
+	return rc;
+}
+
 /*
  * function:	zfcp_scsi_eh_device_reset_handler
  *
@@ -623,9 +634,6 @@ zfcp_scsi_eh_device_reset_handler(struct
 {
 	int retval;
 	struct zfcp_unit *unit = (struct zfcp_unit *) scpnt->device->hostdata;
-	struct Scsi_Host *scsi_host = scpnt->device->host;
-
-	spin_unlock_irq(scsi_host->host_lock);
 
 	if (!unit) {
 		ZFCP_LOG_NORMAL("bug: Tried reset for nonexistent unit\n");
@@ -669,7 +677,6 @@ zfcp_scsi_eh_device_reset_handler(struct
 		retval = SUCCESS;
 	}
  out:
-	spin_lock_irq(scsi_host->host_lock);
 	return retval;
 }
 
@@ -721,9 +728,6 @@ zfcp_scsi_eh_bus_reset_handler(struct sc
 {
 	int retval = 0;
 	struct zfcp_unit *unit;
-	struct Scsi_Host *scsi_host = scpnt->device->host;
-
-	spin_unlock_irq(scsi_host->host_lock);
 
 	unit = (struct zfcp_unit *) scpnt->device->hostdata;
 	ZFCP_LOG_NORMAL("bus reset because of problems with "
@@ -732,7 +736,6 @@ zfcp_scsi_eh_bus_reset_handler(struct sc
 	zfcp_erp_wait(unit->port->adapter);
 	retval = SUCCESS;
 
-	spin_lock_irq(scsi_host->host_lock);
 	return retval;
 }
 
@@ -748,9 +751,6 @@ zfcp_scsi_eh_host_reset_handler(struct s
 {
 	int retval = 0;
 	struct zfcp_unit *unit;
-	struct Scsi_Host *scsi_host = scpnt->device->host;
-
-	spin_unlock_irq(scsi_host->host_lock);
 
 	unit = (struct zfcp_unit *) scpnt->device->hostdata;
 	ZFCP_LOG_NORMAL("host reset because of problems with "
@@ -759,7 +759,6 @@ zfcp_scsi_eh_host_reset_handler(struct s
 	zfcp_erp_wait(unit->port->adapter);
 	retval = SUCCESS;
 
-	spin_lock_irq(scsi_host->host_lock);
 	return retval;
 }
 
@@ -831,6 +830,7 @@ zfcp_adapter_scsi_unregister(struct zfcp
 	shost = adapter->scsi_host;
 	if (!shost)
 		return;
+	fc_remove_host(shost);
 	scsi_remove_host(shost);
 	scsi_host_put(shost);
 	adapter->scsi_host = NULL;
@@ -904,6 +904,18 @@ zfcp_get_node_name(struct scsi_target *s
 	read_unlock_irqrestore(&zfcp_data.config_lock, flags);
 }
 
+void
+zfcp_set_fc_host_attrs(struct zfcp_adapter *adapter)
+{
+	struct Scsi_Host *shost = adapter->scsi_host;
+
+	fc_host_node_name(shost) = adapter->wwnn;
+	fc_host_port_name(shost) = adapter->wwpn;
+	strncpy(fc_host_serial_number(shost), adapter->serial_number,
+                min(FC_SERIAL_NUMBER_SIZE, 32));
+	fc_host_supported_classes(shost) = FC_COS_CLASS2 | FC_COS_CLASS3;
+}
+
 struct fc_function_template zfcp_transport_functions = {
 	.get_starget_port_id = zfcp_get_port_id,
 	.get_starget_port_name = zfcp_get_port_name,
@@ -911,6 +923,11 @@ struct fc_function_template zfcp_transpo
 	.show_starget_port_id = 1,
 	.show_starget_port_name = 1,
 	.show_starget_node_name = 1,
+	.show_rport_supported_classes = 1,
+	.show_host_node_name = 1,
+	.show_host_port_name = 1,
+	.show_host_supported_classes = 1,
+	.show_host_serial_number = 1,
 };
 
 /**
@@ -922,7 +939,7 @@ struct fc_function_template zfcp_transpo
  * Generates attribute for a unit.
  */
 #define ZFCP_DEFINE_SCSI_ATTR(_name, _format, _value)                    \
-static ssize_t zfcp_sysfs_scsi_##_name##_show(struct device *dev,        \
+static ssize_t zfcp_sysfs_scsi_##_name##_show(struct device *dev, struct device_attribute *attr,        \
                                               char *buf)                 \
 {                                                                        \
         struct scsi_device *sdev;                                        \
diff --git a/drivers/s390/scsi/zfcp_sysfs_adapter.c b/drivers/s390/scsi/zfcp_sysfs_adapter.c
--- a/drivers/s390/scsi/zfcp_sysfs_adapter.c
+++ b/drivers/s390/scsi/zfcp_sysfs_adapter.c
@@ -50,7 +50,7 @@ static const char fc_topologies[5][25] =
  * Generates attributes for an adapter.
  */
 #define ZFCP_DEFINE_ADAPTER_ATTR(_name, _format, _value)                      \
-static ssize_t zfcp_sysfs_adapter_##_name##_show(struct device *dev,          \
+static ssize_t zfcp_sysfs_adapter_##_name##_show(struct device *dev, struct device_attribute *attr,          \
 						 char *buf)                   \
 {                                                                             \
 	struct zfcp_adapter *adapter;                                         \
@@ -90,7 +90,7 @@ ZFCP_DEFINE_ADAPTER_ATTR(in_recovery, "%
  * Store function of the "port_add" attribute of an adapter.
  */
 static ssize_t
-zfcp_sysfs_port_add_store(struct device *dev, const char *buf, size_t count)
+zfcp_sysfs_port_add_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	wwn_t wwpn;
 	char *endp;
@@ -135,7 +135,7 @@ static DEVICE_ATTR(port_add, S_IWUSR, NU
  * Store function of the "port_remove" attribute of an adapter.
  */
 static ssize_t
-zfcp_sysfs_port_remove_store(struct device *dev, const char *buf, size_t count)
+zfcp_sysfs_port_remove_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct zfcp_adapter *adapter;
 	struct zfcp_port *port;
@@ -196,7 +196,7 @@ static DEVICE_ATTR(port_remove, S_IWUSR,
  * started for the belonging adapter.
  */
 static ssize_t
-zfcp_sysfs_adapter_failed_store(struct device *dev,
+zfcp_sysfs_adapter_failed_store(struct device *dev, struct device_attribute *attr,
 				const char *buf, size_t count)
 {
 	struct zfcp_adapter *adapter;
@@ -236,7 +236,7 @@ zfcp_sysfs_adapter_failed_store(struct d
  * "0" if adapter is working, otherwise "1".
  */
 static ssize_t
-zfcp_sysfs_adapter_failed_show(struct device *dev, char *buf)
+zfcp_sysfs_adapter_failed_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct zfcp_adapter *adapter;
 
diff --git a/drivers/s390/scsi/zfcp_sysfs_port.c b/drivers/s390/scsi/zfcp_sysfs_port.c
--- a/drivers/s390/scsi/zfcp_sysfs_port.c
+++ b/drivers/s390/scsi/zfcp_sysfs_port.c
@@ -53,7 +53,7 @@ zfcp_sysfs_port_release(struct device *d
  * Generates attributes for a port.
  */
 #define ZFCP_DEFINE_PORT_ATTR(_name, _format, _value)                    \
-static ssize_t zfcp_sysfs_port_##_name##_show(struct device *dev,        \
+static ssize_t zfcp_sysfs_port_##_name##_show(struct device *dev, struct device_attribute *attr,        \
                                               char *buf)                 \
 {                                                                        \
         struct zfcp_port *port;                                          \
@@ -67,7 +67,6 @@ static DEVICE_ATTR(_name, S_IRUGO, zfcp_
 ZFCP_DEFINE_PORT_ATTR(status, "0x%08x\n", atomic_read(&port->status));
 ZFCP_DEFINE_PORT_ATTR(wwnn, "0x%016llx\n", port->wwnn);
 ZFCP_DEFINE_PORT_ATTR(d_id, "0x%06x\n", port->d_id);
-ZFCP_DEFINE_PORT_ATTR(scsi_id, "0x%x\n", port->scsi_id);
 ZFCP_DEFINE_PORT_ATTR(in_recovery, "%d\n", atomic_test_mask
 		      (ZFCP_STATUS_COMMON_ERP_INUSE, &port->status));
 ZFCP_DEFINE_PORT_ATTR(access_denied, "%d\n", atomic_test_mask
@@ -82,7 +81,7 @@ ZFCP_DEFINE_PORT_ATTR(access_denied, "%d
  * Store function of the "unit_add" attribute of a port.
  */
 static ssize_t
-zfcp_sysfs_unit_add_store(struct device *dev, const char *buf, size_t count)
+zfcp_sysfs_unit_add_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	fcp_lun_t fcp_lun;
 	char *endp;
@@ -125,7 +124,7 @@ static DEVICE_ATTR(unit_add, S_IWUSR, NU
  * @count: number of bytes in buffer
  */
 static ssize_t
-zfcp_sysfs_unit_remove_store(struct device *dev, const char *buf, size_t count)
+zfcp_sysfs_unit_remove_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct zfcp_port *port;
 	struct zfcp_unit *unit;
@@ -186,7 +185,7 @@ static DEVICE_ATTR(unit_remove, S_IWUSR,
  * started for the belonging port.
  */
 static ssize_t
-zfcp_sysfs_port_failed_store(struct device *dev, const char *buf, size_t count)
+zfcp_sysfs_port_failed_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct zfcp_port *port;
 	unsigned int val;
@@ -224,7 +223,7 @@ zfcp_sysfs_port_failed_store(struct devi
  * "0" if port is working, otherwise "1".
  */
 static ssize_t
-zfcp_sysfs_port_failed_show(struct device *dev, char *buf)
+zfcp_sysfs_port_failed_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct zfcp_port *port;
 
@@ -263,7 +262,6 @@ static struct attribute_group zfcp_port_
 static struct attribute *zfcp_port_no_ns_attrs[] = {
 	&dev_attr_unit_add.attr,
 	&dev_attr_unit_remove.attr,
-	&dev_attr_scsi_id.attr,
 	NULL
 };
 
diff --git a/drivers/s390/scsi/zfcp_sysfs_unit.c b/drivers/s390/scsi/zfcp_sysfs_unit.c
--- a/drivers/s390/scsi/zfcp_sysfs_unit.c
+++ b/drivers/s390/scsi/zfcp_sysfs_unit.c
@@ -53,7 +53,7 @@ zfcp_sysfs_unit_release(struct device *d
  * Generates attribute for a unit.
  */
 #define ZFCP_DEFINE_UNIT_ATTR(_name, _format, _value)                    \
-static ssize_t zfcp_sysfs_unit_##_name##_show(struct device *dev,        \
+static ssize_t zfcp_sysfs_unit_##_name##_show(struct device *dev, struct device_attribute *attr,        \
                                               char *buf)                 \
 {                                                                        \
         struct zfcp_unit *unit;                                          \
@@ -86,7 +86,7 @@ ZFCP_DEFINE_UNIT_ATTR(access_readonly, "
  * started for the belonging unit.
  */
 static ssize_t
-zfcp_sysfs_unit_failed_store(struct device *dev, const char *buf, size_t count)
+zfcp_sysfs_unit_failed_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct zfcp_unit *unit;
 	unsigned int val;
@@ -123,7 +123,7 @@ zfcp_sysfs_unit_failed_store(struct devi
  * "0" if unit is working, otherwise "1".
  */
 static ssize_t
-zfcp_sysfs_unit_failed_show(struct device *dev, char *buf)
+zfcp_sysfs_unit_failed_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct zfcp_unit *unit;
 
diff --git a/drivers/sbus/char/Kconfig b/drivers/sbus/char/Kconfig
--- a/drivers/sbus/char/Kconfig
+++ b/drivers/sbus/char/Kconfig
@@ -71,20 +71,6 @@ config SUN_JSFLASH
 
 # XXX Why don't we do "source drivers/char/Config.in" somewhere?
 # no shit
-config APM_RTC_IS_GMT
-	bool
-	depends on EXPERIMENTAL && SPARC32 && PCI
-	default y
-	help
-	  Say Y here if your RTC (Real Time Clock a.k.a. hardware clock)
-	  stores the time in GMT (Greenwich Mean Time). Say N if your RTC
-	  stores localtime.
-
-	  It is in fact recommended to store GMT in your RTC, because then you
-	  don't have to worry about daylight savings time changes. The only
-	  reason not to use GMT in your RTC is if you also run a broken OS
-	  that doesn't understand GMT.
-
 config RTC
 	tristate "PC-style Real Time Clock Support"
 	depends on PCI && EXPERIMENTAL && SPARC32
diff --git a/drivers/sbus/char/aurora.c b/drivers/sbus/char/aurora.c
--- a/drivers/sbus/char/aurora.c
+++ b/drivers/sbus/char/aurora.c
@@ -1515,8 +1515,7 @@ static void aurora_close(struct tty_stru
 		 */
 		timeout = jiffies+HZ;
 		while(port->SRER & SRER_TXEMPTY)  {
-			current->state = TASK_INTERRUPTIBLE;
-			schedule_timeout(port->timeout);
+			msleep_interruptible(jiffies_to_msecs(port->timeout));
 			if (time_after(jiffies, timeout))
 				break;
 		}
@@ -1533,8 +1532,7 @@ static void aurora_close(struct tty_stru
 	port->tty = 0;
 	if (port->blocked_open) {
 		if (port->close_delay) {
-			current->state = TASK_INTERRUPTIBLE;
-			schedule_timeout(port->close_delay);
+			msleep_interruptible(jiffies_to_msecs(port->close_delay));
 		}
 		wake_up_interruptible(&port->open_wait);
 	}
diff --git a/drivers/sbus/char/bbc_envctrl.c b/drivers/sbus/char/bbc_envctrl.c
--- a/drivers/sbus/char/bbc_envctrl.c
+++ b/drivers/sbus/char/bbc_envctrl.c
@@ -4,13 +4,15 @@
  * Copyright (C) 2001 David S. Miller (davem@redhat.com)
  */
 
+#define __KERNEL_SYSCALLS__
+
 #include <linux/kernel.h>
+#include <linux/kthread.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
 #include <asm/oplib.h>
 #include <asm/ebus.h>
-#define __KERNEL_SYSCALLS__
 static int errno;
 #include <asm/unistd.h>
 
@@ -458,10 +460,6 @@ static struct task_struct *kenvctrld_tas
 
 static int kenvctrld(void *__unused)
 {
-	daemonize("kenvctrld");
-	allow_signal(SIGKILL);
-	kenvctrld_task = current;
-
 	printk(KERN_INFO "bbc_envctrl: kenvctrld starting...\n");
 	last_warning_jiffies = jiffies - WARN_INTERVAL;
 	for (;;) {
@@ -469,7 +467,7 @@ static int kenvctrld(void *__unused)
 		struct bbc_fan_control *fp;
 
 		msleep_interruptible(POLL_INTERVAL);
-		if (signal_pending(current))
+		if (kthread_should_stop())
 			break;
 
 		for (tp = all_bbc_temps; tp; tp = tp->next) {
@@ -576,7 +574,6 @@ int bbc_envctrl_init(void)
 	int temp_index = 0;
 	int fan_index = 0;
 	int devidx = 0;
-	int err = 0;
 
 	while ((echild = bbc_i2c_getdev(devidx++)) != NULL) {
 		if (!strcmp(echild->prom_name, "temperature"))
@@ -584,9 +581,13 @@ int bbc_envctrl_init(void)
 		if (!strcmp(echild->prom_name, "fan-control"))
 			attach_one_fan(echild, fan_index++);
 	}
-	if (temp_index != 0 && fan_index != 0)
-		err = kernel_thread(kenvctrld, NULL, CLONE_FS | CLONE_FILES);
-	return err;
+	if (temp_index != 0 && fan_index != 0) {
+		kenvctrld_task = kthread_run(kenvctrld, NULL, "kenvctrld");
+		if (IS_ERR(kenvctrld_task))
+			return PTR_ERR(kenvctrld_task);
+	}
+
+	return 0;
 }
 
 static void destroy_one_temp(struct bbc_cpu_temperature *tp)
@@ -606,26 +607,7 @@ void bbc_envctrl_cleanup(void)
 	struct bbc_cpu_temperature *tp;
 	struct bbc_fan_control *fp;
 
-	if (kenvctrld_task != NULL) {
-		force_sig(SIGKILL, kenvctrld_task);
-		for (;;) {
-			struct task_struct *p;
-			int found = 0;
-
-			read_lock(&tasklist_lock);
-			for_each_process(p) {
-				if (p == kenvctrld_task) {
-					found = 1;
-					break;
-				}
-			}
-			read_unlock(&tasklist_lock);
-			if (!found)
-				break;
-			msleep(1000);
-		}
-		kenvctrld_task = NULL;
-	}
+	kthread_stop(kenvctrld_task);
 
 	tp = all_bbc_temps;
 	while (tp != NULL) {
diff --git a/drivers/sbus/char/bpp.c b/drivers/sbus/char/bpp.c
--- a/drivers/sbus/char/bpp.c
+++ b/drivers/sbus/char/bpp.c
@@ -79,10 +79,6 @@ struct inst {
 
       unsigned char run_length;
       unsigned char repeat_byte;
-
-      /* These members manage timeouts for programmed delays */
-      wait_queue_head_t wait_queue;
-      struct timer_list timer_list;
 };
 
 static struct inst instances[BPP_NO];
@@ -297,16 +293,10 @@ static unsigned short get_pins(unsigned 
 
 #endif /* __sparc__ */
 
-static void bpp_wake_up(unsigned long val)
-{ wake_up(&instances[val].wait_queue); }
-
 static void snooze(unsigned long snooze_time, unsigned minor)
 {
-      init_timer(&instances[minor].timer_list);
-      instances[minor].timer_list.expires = jiffies + snooze_time + 1;
-      instances[minor].timer_list.data    = minor;
-      add_timer(&instances[minor].timer_list);
-      sleep_on (&instances[minor].wait_queue);
+	set_current_state(TASK_UNINTERRUPTIBLE);
+	schedule_timeout(snooze_time + 1);
 }
 
 static int wait_for(unsigned short set, unsigned short clr,
@@ -880,11 +870,8 @@ static void probeLptPort(unsigned idx)
       instances[idx].enhanced = 0;
       instances[idx].direction = 0;
       instances[idx].mode = COMPATIBILITY;
-      instances[idx].wait_queue = 0;
       instances[idx].run_length = 0;
       instances[idx].run_flag = 0;
-      init_timer(&instances[idx].timer_list);
-      instances[idx].timer_list.function = bpp_wake_up;
       if (!request_region(lpAddr,3, dev_name)) return;
 
       /*
@@ -977,11 +964,8 @@ static void probeLptPort(unsigned idx)
       instances[idx].enhanced = 0;
       instances[idx].direction = 0;
       instances[idx].mode = COMPATIBILITY;
-      init_waitqueue_head(&instances[idx].wait_queue);
       instances[idx].run_length = 0;
       instances[idx].run_flag = 0;
-      init_timer(&instances[idx].timer_list);
-      instances[idx].timer_list.function = bpp_wake_up;
 
       if (!rp) return;
 
diff --git a/drivers/sbus/char/envctrl.c b/drivers/sbus/char/envctrl.c
--- a/drivers/sbus/char/envctrl.c
+++ b/drivers/sbus/char/envctrl.c
@@ -19,9 +19,12 @@
  *              Daniele Bellucci <bellucda@tiscali.it>
  */
 
+#define __KERNEL_SYSCALLS__
+
 #include <linux/config.h>
 #include <linux/module.h>
 #include <linux/sched.h>
+#include <linux/kthread.h>
 #include <linux/errno.h>
 #include <linux/delay.h>
 #include <linux/ioport.h>
@@ -35,7 +38,6 @@
 #include <asm/uaccess.h>
 #include <asm/envctrl.h>
 
-#define __KERNEL_SYSCALLS__
 static int errno;
 #include <asm/unistd.h>
 
@@ -1007,21 +1009,15 @@ static int kenvctrld(void *__unused)
 		return -ENODEV;
 	}
 
-	poll_interval = 5 * HZ; /* TODO env_mon_interval */
-
-	daemonize("kenvctrld");
-	allow_signal(SIGKILL);
-
-	kenvctrld_task = current;
+	poll_interval = 5000; /* TODO env_mon_interval */
 
 	printk(KERN_INFO "envctrl: %s starting...\n", current->comm);
 	for (;;) {
-		current->state = TASK_INTERRUPTIBLE;
-		schedule_timeout(poll_interval);
+		msleep_interruptible(poll_interval);
 
-		if(signal_pending(current))
+		if (kthread_should_stop())
 			break;
-
+		
 		for (whichcpu = 0; whichcpu < ENVCTRL_MAX_CPU; ++whichcpu) {
 			if (0 < envctrl_read_cpu_info(whichcpu, cputemp,
 						      ENVCTRL_CPUTEMP_MON,
@@ -1043,7 +1039,6 @@ static int kenvctrld(void *__unused)
 
 static int __init envctrl_init(void)
 {
-#ifdef CONFIG_PCI
 	struct linux_ebus *ebus = NULL;
 	struct linux_ebus_device *edev = NULL;
 	struct linux_ebus_child *edev_child = NULL;
@@ -1120,9 +1115,11 @@ done:
 			i2c_childlist[i].addr, (0 == i) ? ("\n") : (" "));
 	}
 
-	err = kernel_thread(kenvctrld, NULL, CLONE_FS | CLONE_FILES);
-	if (err < 0)
+	kenvctrld_task = kthread_run(kenvctrld, NULL, "kenvctrld");
+	if (IS_ERR(kenvctrld_task)) {
+		err = PTR_ERR(kenvctrld_task);
 		goto out_deregister;
+	}
 
 	return 0;
 
@@ -1135,37 +1132,13 @@ out_iounmap:
 			kfree(i2c_childlist[i].tables);
 	}
 	return err;
-#else
-	return -ENODEV;
-#endif
 }
 
 static void __exit envctrl_cleanup(void)
 {
 	int i;
 
-	if (NULL != kenvctrld_task) {
-		force_sig(SIGKILL, kenvctrld_task);
-		for (;;) {
-			struct task_struct *p;
-			int found = 0;
-
-			read_lock(&tasklist_lock);
-			for_each_process(p) {
-				if (p == kenvctrld_task) {
-					found = 1;
-					break;
-				}
-			}
-			read_unlock(&tasklist_lock);
-
-			if (!found)
-				break;
-
-			msleep(1000);
-		}
-		kenvctrld_task = NULL;
-	}
+	kthread_stop(kenvctrld_task);
 
 	iounmap(i2c);
 	misc_deregister(&envctrl_dev);
diff --git a/drivers/sbus/char/vfc.h b/drivers/sbus/char/vfc.h
--- a/drivers/sbus/char/vfc.h
+++ b/drivers/sbus/char/vfc.h
@@ -129,8 +129,6 @@ struct vfc_dev {
 	struct vfc_regs *phys_regs;
 	unsigned int control_reg;
 	struct semaphore device_lock_sem;
-	struct timer_list poll_timer;
-	wait_queue_head_t poll_wait;
 	int instance;
 	int busy;
 	unsigned long which_io;
diff --git a/drivers/sbus/char/vfc_dev.c b/drivers/sbus/char/vfc_dev.c
--- a/drivers/sbus/char/vfc_dev.c
+++ b/drivers/sbus/char/vfc_dev.c
@@ -137,7 +137,6 @@ int init_vfc_devstruct(struct vfc_dev *d
 	dev->instance=instance;
 	init_MUTEX(&dev->device_lock_sem);
 	dev->control_reg=0;
-	init_waitqueue_head(&dev->poll_wait);
 	dev->busy=0;
 	return 0;
 }
diff --git a/drivers/sbus/char/vfc_i2c.c b/drivers/sbus/char/vfc_i2c.c
--- a/drivers/sbus/char/vfc_i2c.c
+++ b/drivers/sbus/char/vfc_i2c.c
@@ -79,23 +79,10 @@ int vfc_pcf8584_init(struct vfc_dev *dev
 	return 0;
 }
 
-void vfc_i2c_delay_wakeup(struct vfc_dev *dev) 
-{
-	/* Used to profile code and eliminate too many delays */
-	VFC_I2C_DEBUG_PRINTK(("vfc%d: Delaying\n", dev->instance));
-	wake_up(&dev->poll_wait);
-}
-
 void vfc_i2c_delay_no_busy(struct vfc_dev *dev, unsigned long usecs) 
 {
-	init_timer(&dev->poll_timer);
-	dev->poll_timer.expires = jiffies + 
-		((unsigned long)usecs*(HZ))/1000000;
-	dev->poll_timer.data=(unsigned long)dev;
-	dev->poll_timer.function=(void *)(unsigned long)vfc_i2c_delay_wakeup;
-	add_timer(&dev->poll_timer);
-	sleep_on(&dev->poll_wait);
-	del_timer(&dev->poll_timer);
+	set_current_state(TASK_UNINTERRUPTIBLE);
+	schedule_timeout(usecs_to_jiffies(usecs));
 }
 
 void inline vfc_i2c_delay(struct vfc_dev *dev) 
diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c
--- a/drivers/scsi/3w-9xxx.c
+++ b/drivers/scsi/3w-9xxx.c
@@ -1695,8 +1695,6 @@ static int twa_scsi_eh_reset(struct scsi
 
 	tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
 
-	spin_unlock_irq(tw_dev->host->host_lock);
-
 	tw_dev->num_resets++;
 
 	printk(KERN_WARNING "3w-9xxx: scsi%d: WARNING: (0x%02X:0x%04X): Unit #%d: Command (0x%x) timed out, resetting card.\n", tw_dev->host->host_no, TW_DRIVER, 0x2c, SCpnt->device->id, SCpnt->cmnd[0]);
@@ -1709,7 +1707,6 @@ static int twa_scsi_eh_reset(struct scsi
 
 	retval = SUCCESS;
 out:
-	spin_lock_irq(tw_dev->host->host_lock);
 	return retval;
 } /* End twa_scsi_eh_reset() */
 
@@ -1919,9 +1916,9 @@ static void __twa_shutdown(TW_Device_Ext
 } /* End __twa_shutdown() */
 
 /* Wrapper for __twa_shutdown */
-static void twa_shutdown(struct device *dev)
+static void twa_shutdown(struct pci_dev *pdev)
 {
-	struct Scsi_Host *host = pci_get_drvdata(to_pci_dev(dev));
+	struct Scsi_Host *host = pci_get_drvdata(pdev);
 	TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
 
 	__twa_shutdown(tw_dev);
@@ -2143,9 +2140,7 @@ static struct pci_driver twa_driver = {
 	.id_table	= twa_pci_tbl,
 	.probe		= twa_probe,
 	.remove		= twa_remove,
-	.driver		= {
-		.shutdown = twa_shutdown
-	}
+	.shutdown	= twa_shutdown
 };
 
 /* This function is called on driver initialization */
diff --git a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c
--- a/drivers/scsi/3w-xxxx.c
+++ b/drivers/scsi/3w-xxxx.c
@@ -1430,8 +1430,6 @@ static int tw_scsi_eh_reset(struct scsi_
 
 	tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
 
-	spin_unlock_irq(tw_dev->host->host_lock);
-
 	tw_dev->num_resets++;
 
 	printk(KERN_WARNING "3w-xxxx: scsi%d: WARNING: Unit #%d: Command (0x%x) timed out, resetting card.\n", tw_dev->host->host_no, SCpnt->device->id, SCpnt->cmnd[0]);
@@ -1444,7 +1442,6 @@ static int tw_scsi_eh_reset(struct scsi_
 
 	retval = SUCCESS;
 out:
-	spin_lock_irq(tw_dev->host->host_lock);
 	return retval;
 } /* End tw_scsi_eh_reset() */
 
@@ -2267,9 +2264,9 @@ static void __tw_shutdown(TW_Device_Exte
 } /* End __tw_shutdown() */
 
 /* Wrapper for __tw_shutdown */
-static void tw_shutdown(struct device *dev)
+static void tw_shutdown(struct pci_dev *pdev)
 {
-	struct Scsi_Host *host = pci_get_drvdata(to_pci_dev(dev));
+	struct Scsi_Host *host = pci_get_drvdata(pdev);
 	TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
 
 	__tw_shutdown(tw_dev);
@@ -2454,9 +2451,7 @@ static struct pci_driver tw_driver = {
 	.id_table	= tw_pci_tbl,
 	.probe		= tw_probe,
 	.remove		= tw_remove,
-	.driver		= {
-		.shutdown = tw_shutdown
-	}
+	.shutdown	= tw_shutdown,
 };
 
 /* This function is called on driver initialization */
diff --git a/drivers/scsi/53c700.c b/drivers/scsi/53c700.c
--- a/drivers/scsi/53c700.c
+++ b/drivers/scsi/53c700.c
@@ -170,7 +170,6 @@ MODULE_LICENSE("GPL");
 STATIC int NCR_700_queuecommand(struct scsi_cmnd *, void (*done)(struct scsi_cmnd *));
 STATIC int NCR_700_abort(struct scsi_cmnd * SCpnt);
 STATIC int NCR_700_bus_reset(struct scsi_cmnd * SCpnt);
-STATIC int NCR_700_dev_reset(struct scsi_cmnd * SCpnt);
 STATIC int NCR_700_host_reset(struct scsi_cmnd * SCpnt);
 STATIC void NCR_700_chip_setup(struct Scsi_Host *host);
 STATIC void NCR_700_chip_reset(struct Scsi_Host *host);
@@ -330,7 +329,6 @@ NCR_700_detect(struct scsi_host_template
 	/* Fill in the missing routines from the host template */
 	tpnt->queuecommand = NCR_700_queuecommand;
 	tpnt->eh_abort_handler = NCR_700_abort;
-	tpnt->eh_device_reset_handler = NCR_700_dev_reset;
 	tpnt->eh_bus_reset_handler = NCR_700_bus_reset;
 	tpnt->eh_host_reset_handler = NCR_700_host_reset;
 	tpnt->can_queue = NCR_700_COMMAND_SLOTS_PER_HOST;
@@ -1959,34 +1957,31 @@ NCR_700_bus_reset(struct scsi_cmnd * SCp
 	printk(KERN_INFO "scsi%d (%d:%d) New error handler wants BUS reset, cmd %p\n\t",
 	       SCp->device->host->host_no, SCp->device->id, SCp->device->lun, SCp);
 	scsi_print_command(SCp);
+
 	/* In theory, eh_complete should always be null because the
 	 * eh is single threaded, but just in case we're handling a
 	 * reset via sg or something */
-	while(hostdata->eh_complete != NULL) {
+	spin_lock_irq(SCp->device->host->host_lock);
+	while (hostdata->eh_complete != NULL) {
 		spin_unlock_irq(SCp->device->host->host_lock);
 		msleep_interruptible(100);
 		spin_lock_irq(SCp->device->host->host_lock);
 	}
+
 	hostdata->eh_complete = &complete;
 	NCR_700_internal_bus_reset(SCp->device->host);
+
 	spin_unlock_irq(SCp->device->host->host_lock);
 	wait_for_completion(&complete);
 	spin_lock_irq(SCp->device->host->host_lock);
+
 	hostdata->eh_complete = NULL;
 	/* Revalidate the transport parameters of the failing device */
 	if(hostdata->fast)
 		spi_schedule_dv_device(SCp->device);
-	return SUCCESS;
-}
 
-STATIC int
-NCR_700_dev_reset(struct scsi_cmnd * SCp)
-{
-	printk(KERN_INFO "scsi%d (%d:%d) New error handler wants device reset\n\t",
-	       SCp->device->host->host_no, SCp->device->id, SCp->device->lun);
-	scsi_print_command(SCp);
-	
-	return FAILED;
+	spin_unlock_irq(SCp->device->host->host_lock);
+	return SUCCESS;
 }
 
 STATIC int
@@ -1996,8 +1991,13 @@ NCR_700_host_reset(struct scsi_cmnd * SC
 	       SCp->device->host->host_no, SCp->device->id, SCp->device->lun);
 	scsi_print_command(SCp);
 
+	spin_lock_irq(SCp->device->host->host_lock);
+
 	NCR_700_internal_bus_reset(SCp->device->host);
 	NCR_700_chip_reset(SCp->device->host);
+
+	spin_unlock_irq(SCp->device->host->host_lock);
+
 	return SUCCESS;
 }
 
@@ -2125,7 +2125,7 @@ static int NCR_700_change_queue_type(str
 }
 
 static ssize_t
-NCR_700_show_active_tags(struct device *dev, char *buf)
+NCR_700_show_active_tags(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct scsi_device *SDp = to_scsi_device(dev);
 
diff --git a/drivers/scsi/BusLogic.c b/drivers/scsi/BusLogic.c
--- a/drivers/scsi/BusLogic.c
+++ b/drivers/scsi/BusLogic.c
@@ -2746,9 +2746,15 @@ static int BusLogic_host_reset(struct sc
 
 	unsigned int id = SCpnt->device->id;
 	struct BusLogic_TargetStatistics *stats = &HostAdapter->TargetStatistics[id];
+	int rc;
+
+	spin_lock_irq(SCpnt->device->host->host_lock);
+
 	BusLogic_IncrementErrorCounter(&stats->HostAdapterResetsRequested);
 
-	return BusLogic_ResetHostAdapter(HostAdapter, false);
+	rc = BusLogic_ResetHostAdapter(HostAdapter, false);
+	spin_unlock_irq(SCpnt->device->host->host_lock);
+	return rc;
 }
 
 /*
diff --git a/drivers/scsi/FlashPoint.c b/drivers/scsi/FlashPoint.c
--- a/drivers/scsi/FlashPoint.c
+++ b/drivers/scsi/FlashPoint.c
@@ -22,8 +22,6 @@
 #ifndef CONFIG_SCSI_OMIT_FLASHPOINT
 
 
-#define UNIX
-#define FW_TYPE		_SCCB_MGR_
 #define MAX_CARDS	8
 #undef BUSTYPE_PCI
 
@@ -34,8 +32,6 @@
 #define OS_OutPortByte(port, value)	outb(value, port)
 #define OS_OutPortWord(port, value)	outw(value, port)
 #define OS_OutPortLong(port, value)	outl(value, port)
-#define OS_Lock(x)
-#define OS_UnLock(x)
 
 
 /*
@@ -51,164 +47,17 @@
 #define SccbMgr_isr			FlashPoint_HandleInterrupt
 
 
-/*
-  Define name replacements to avoid kernel namespace pollution.
-*/
-
-#define BL_Card				FPT_BL_Card
-#define BusMasterInit			FPT_BusMasterInit
-#define CalcCrc16			FPT_CalcCrc16
-#define CalcLrc				FPT_CalcLrc
-#define ChkIfChipInitialized		FPT_ChkIfChipInitialized
-#define DiagBusMaster			FPT_DiagBusMaster
-#define DiagEEPROM			FPT_DiagEEPROM
-#define DiagXbow			FPT_DiagXbow
-#define GetTarLun			FPT_GetTarLun
-#define RNVRamData			FPT_RNVRamData
-#define RdStack				FPT_RdStack
-#define SccbMgrTableInitAll		FPT_SccbMgrTableInitAll
-#define SccbMgrTableInitCard		FPT_SccbMgrTableInitCard
-#define SccbMgrTableInitTarget		FPT_SccbMgrTableInitTarget
-#define SccbMgr_bad_isr			FPT_SccbMgr_bad_isr
-#define SccbMgr_scsi_reset		FPT_SccbMgr_scsi_reset
-#define SccbMgr_timer_expired		FPT_SccbMgr_timer_expired
-#define SendMsg				FPT_SendMsg
-#define Wait				FPT_Wait
-#define Wait1Second			FPT_Wait1Second
-#define WrStack				FPT_WrStack
-#define XbowInit			FPT_XbowInit
-#define autoCmdCmplt			FPT_autoCmdCmplt
-#define autoLoadDefaultMap		FPT_autoLoadDefaultMap
-#define busMstrDataXferStart		FPT_busMstrDataXferStart
-#define busMstrSGDataXferStart		FPT_busMstrSGDataXferStart
-#define busMstrTimeOut			FPT_busMstrTimeOut
-#define dataXferProcessor		FPT_dataXferProcessor
-#define default_intena			FPT_default_intena
-#define hostDataXferAbort		FPT_hostDataXferAbort
-#define hostDataXferRestart		FPT_hostDataXferRestart
-#define inisci				FPT_inisci
-#define mbCards				FPT_mbCards
-#define nvRamInfo			FPT_nvRamInfo
-#define phaseBusFree			FPT_phaseBusFree
-#define phaseChkFifo			FPT_phaseChkFifo
-#define phaseCommand			FPT_phaseCommand
-#define phaseDataIn			FPT_phaseDataIn
-#define phaseDataOut			FPT_phaseDataOut
-#define phaseDecode			FPT_phaseDecode
-#define phaseIllegal			FPT_phaseIllegal
-#define phaseMsgIn			FPT_phaseMsgIn
-#define phaseMsgOut			FPT_phaseMsgOut
-#define phaseStatus			FPT_phaseStatus
-#define queueAddSccb			FPT_queueAddSccb
-#define queueCmdComplete		FPT_queueCmdComplete
-#define queueDisconnect			FPT_queueDisconnect
-#define queueFindSccb			FPT_queueFindSccb
-#define queueFlushSccb			FPT_queueFlushSccb
-#define queueFlushTargSccb		FPT_queueFlushTargSccb
-#define queueSearchSelect		FPT_queueSearchSelect
-#define queueSelectFail			FPT_queueSelectFail
-#define s_PhaseTbl			FPT_s_PhaseTbl
-#define scamHAString			FPT_scamHAString
-#define scamInfo			FPT_scamInfo
-#define scarb				FPT_scarb
-#define scasid				FPT_scasid
-#define scbusf				FPT_scbusf
-#define sccbMgrTbl			FPT_sccbMgrTbl
-#define schkdd				FPT_schkdd
-#define scini				FPT_scini
-#define sciso				FPT_sciso
-#define scmachid			FPT_scmachid
-#define scsavdi				FPT_scsavdi
-#define scsel				FPT_scsel
-#define scsell				FPT_scsell
-#define scsendi				FPT_scsendi
-#define scvalq				FPT_scvalq
-#define scwirod				FPT_scwirod
-#define scwiros				FPT_scwiros
-#define scwtsel				FPT_scwtsel
-#define scxferc				FPT_scxferc
-#define sdecm				FPT_sdecm
-#define sfm				FPT_sfm
-#define shandem				FPT_shandem
-#define sinits				FPT_sinits
-#define sisyncn				FPT_sisyncn
-#define sisyncr				FPT_sisyncr
-#define siwidn				FPT_siwidn
-#define siwidr				FPT_siwidr
-#define sres				FPT_sres
-#define sresb				FPT_sresb
-#define ssel				FPT_ssel
-#define ssenss				FPT_ssenss
-#define sssyncv				FPT_sssyncv
-#define stsyncn				FPT_stsyncn
-#define stwidn				FPT_stwidn
-#define sxfrp				FPT_sxfrp
-#define utilEERead			FPT_utilEERead
-#define utilEEReadOrg			FPT_utilEEReadOrg
-#define utilEESendCmdAddr		FPT_utilEESendCmdAddr
-#define utilEEWrite			FPT_utilEEWrite
-#define utilEEWriteOnOff		FPT_utilEEWriteOnOff
-#define utilUpdateResidual		FPT_utilUpdateResidual
-
-
-/*----------------------------------------------------------------------
- *
- *
- *   Copyright 1995-1996 by Mylex Corporation.  All Rights Reserved
- *
- *   This file is available under both the GNU General Public License
- *   and a BSD-style copyright; see LICENSE.FlashPoint for details.
- *
- *   $Workfile:   globals.h  $
- *
- *   Description:  Common shared global defines.
- *
- *   $Date: 1996/09/04 01:26:13 $
- *
- *   $Revision: 1.11 $
- *
- *----------------------------------------------------------------------*/
-#ifndef __GLOBALS_H__
-#define __GLOBALS_H__
-
-#define _UCB_MGR_  1
-#define _SCCB_MGR_ 2
-
-/*#include <osflags.h>*/
-
 #define MAX_CDBLEN  12
 
 #define SCAM_LEV_2	1
 
 #define CRCMASK	0xA001
 
-/*  In your osflags.h file, please ENSURE that only ONE OS FLAG 
-    is on at a time !!! Also, please make sure you turn set the 
- 	 variable FW_TYPE to either _UCB_MGR_ or _SCCB_MGR_  !!! */
-
-#if defined(DOS) || defined(WIN95_16) || defined(OS2) || defined(OTHER_16)
-   #define       COMPILER_16_BIT 1
-#elif defined(NETWARE) || defined(NT) || defined(WIN95_32) || defined(UNIX) || defined(OTHER_32) || defined(SOLARIS_REAL_MODE)
-   #define       COMPILER_32_BIT 1
-#endif
-
-
 #define     BL_VENDOR_ID      0x104B
 #define     FP_DEVICE_ID      0x8130
 #define     MM_DEVICE_ID      0x1040
 
 
-#ifndef FALSE
-#define FALSE           0
-#endif
-#ifndef TRUE
-#define TRUE            (!(FALSE))
-#endif
-
-#ifndef NULL
-#define NULL            0
-#endif
-
 #define FAILURE         0xFFFFFFFFL
 
 
@@ -222,26 +71,10 @@ typedef unsigned long * PULONG;
 typedef void *          PVOID;
 
 
-#if defined(COMPILER_16_BIT)
-typedef unsigned char far       * uchar_ptr;
-typedef unsigned short far      * ushort_ptr;
-typedef unsigned long far       * ulong_ptr;
-#endif  /* 16_BIT_COMPILER */
-
-#if defined(COMPILER_32_BIT)
 typedef unsigned char           * uchar_ptr;
 typedef unsigned short          * ushort_ptr;
 typedef unsigned long           * ulong_ptr;
-#endif  /* 32_BIT_COMPILER */
-
 
-/*	 			NEW TYPE DEFINITIONS (shared with Mylex North)
-
-**  Use following type defines to avoid confusion in 16 and 32-bit
-**  environments.  Avoid using 'int' as it denotes 16 bits in 16-bit
-**  environment and 32 in 32-bit environments.
-
-*/
 
 #define s08bits	char
 #define s16bits 	short
@@ -251,195 +84,19 @@ typedef unsigned long           * ulong_
 #define u16bits	unsigned s16bits
 #define u32bits	unsigned s32bits
 
-#if defined(COMPILER_16_BIT)
-
-typedef u08bits far 	* pu08bits;
-typedef u16bits far 	* pu16bits;
-typedef u32bits far	* pu32bits;
-
-#endif	/* COMPILER_16_BIT */
-
-#if defined(COMPILER_32_BIT)
-
 typedef u08bits 	* pu08bits;
 typedef u16bits 	* pu16bits;
 typedef u32bits 	* pu32bits;
 
-#endif	/* COMPILER_32_BIT */
-
 
 #define BIT(x)          ((UCHAR)(1<<(x)))    /* single-bit mask in bit position x */
 #define BITW(x)          ((USHORT)(1<<(x)))  /* single-bit mask in bit position x */
 
 
 
-#if defined(DOS)
-/*#include <dos.h>*/
-	#undef inportb          /* undefine for Borland Lib */
-	#undef inport           /* they may have define I/O function in LIB */
-	#undef outportb
-	#undef outport
-
-	#define OS_InPortByte(ioport) 		inportb(ioport)
-	#define OS_InPortWord(ioport) 		inport(ioport)
-	#define OS_InPortLong(ioport)			inportq(ioport, val)
-	#define OS_OutPortByte(ioport, val) outportb(ioport, val)
-	#define OS_OutPortWord(ioport, val)	outport(ioport, val)
-	#define OS_OutPortLong(ioport)		outportq(ioport, val)
-#endif	/* DOS */
-
-#if defined(NETWARE) || defined(OTHER_32) ||  defined(OTHER_16)
-	extern u08bits	OS_InPortByte(u32bits ioport);
-	extern u16bits	OS_InPortWord(u32bits ioport);
-	extern u32bits	OS_InPortLong(u32bits ioport);
-
-	extern OS_InPortByteBuffer(u32bits ioport, pu08bits buffer, u32bits count);
-	extern OS_InPortWordBuffer(u32bits ioport, pu16bits buffer, u32bits count);
-	extern OS_OutPortByte(u32bits ioport, u08bits val);
-	extern OS_OutPortWord(u32bits ioport, u16bits val);
-	extern OS_OutPortLong(u32bits ioport, u32bits val);
-	extern OS_OutPortByteBuffer(u32bits ioport, pu08bits buffer, u32bits count);
-	extern OS_OutPortWordBuffer(u32bits ioport, pu16bits buffer, u32bits count);
-#endif	/* NETWARE || OTHER_32 || OTHER_16 */
-
-#if defined (NT) || defined(WIN95_32) || defined(WIN95_16)
-	#if defined(NT)
-
-		extern __declspec(dllimport) u08bits ScsiPortReadPortUchar(pu08bits ioport);
-		extern __declspec(dllimport) u16bits ScsiPortReadPortUshort(pu16bits ioport);
-		extern __declspec(dllimport) u32bits ScsiPortReadPortUlong(pu32bits ioport);
-		extern __declspec(dllimport) void ScsiPortWritePortUchar(pu08bits ioport, u08bits val);
-		extern __declspec(dllimport) void ScsiPortWritePortUshort(pu16bits port, u16bits val);
-		extern __declspec(dllimport) void ScsiPortWritePortUlong(pu32bits port, u32bits val);
-
-	#else
-
-		extern u08bits ScsiPortReadPortUchar(pu08bits ioport);
-		extern u16bits ScsiPortReadPortUshort(pu16bits ioport);
-		extern u32bits ScsiPortReadPortUlong(pu32bits ioport);
-		extern void ScsiPortWritePortUchar(pu08bits ioport, u08bits val);
-		extern void ScsiPortWritePortUshort(pu16bits port, u16bits val);
-		extern void ScsiPortWritePortUlong(pu32bits port, u32bits val);
-	#endif
-
-
-	#define OS_InPortByte(ioport) ScsiPortReadPortUchar((pu08bits) ioport)
-	#define OS_InPortWord(ioport) ScsiPortReadPortUshort((pu16bits) ioport)
-	#define OS_InPortLong(ioport) ScsiPortReadPortUlong((pu32bits) ioport)
-
-	#define OS_OutPortByte(ioport, val) ScsiPortWritePortUchar((pu08bits) ioport, (u08bits) val)
-	#define OS_OutPortWord(ioport, val) ScsiPortWritePortUshort((pu16bits) ioport, (u16bits) val)
-	#define OS_OutPortLong(ioport, val) ScsiPortWritePortUlong((pu32bits) ioport, (u32bits) val)
-	#define OS_OutPortByteBuffer(ioport, buffer, count) \
-		ScsiPortWritePortBufferUchar((pu08bits)&port, (pu08bits) buffer, (u32bits) count)
-	#define OS_OutPortWordBuffer(ioport, buffer, count) \
-		ScsiPortWritePortBufferUshort((pu16bits)&port, (pu16bits) buffer, (u32bits) count)
-
-	#define OS_Lock(x)
-	#define OS_UnLock(x)
-#endif /* NT || WIN95_32 || WIN95_16 */
-
-#if defined (UNIX) && !defined(OS_InPortByte)
-	#define OS_InPortByte(ioport)    inb((u16bits)ioport)
-	#define OS_InPortWord(ioport)    inw((u16bits)ioport)
-	#define OS_InPortLong(ioport)    inl((u16bits)ioport)
-	#define OS_OutPortByte(ioport,val)  outb((u16bits)ioport, (u08bits)val)
-	#define OS_OutPortWord(ioport,val)  outw((u16bits)ioport, (u16bits)val)
-	#define OS_OutPortLong(ioport,val)  outl((u16bits)ioport, (u32bits)val)
-
-	#define OS_Lock(x)
-	#define OS_UnLock(x)
-#endif /* UNIX */
-
-
-#if defined(OS2)
-	extern u08bits	inb(u32bits ioport);
-	extern u16bits	inw(u32bits ioport);
-	extern void	outb(u32bits ioport, u08bits val);
-	extern void	outw(u32bits ioport, u16bits val);
-
-	#define OS_InPortByte(ioport)			inb(ioport)
-	#define OS_InPortWord(ioport)			inw(ioport)
-	#define OS_OutPortByte(ioport, val)	outb(ioport, val)
-	#define OS_OutPortWord(ioport, val)	outw(ioport, val)
-	extern u32bits	OS_InPortLong(u32bits ioport);
-	extern void	OS_OutPortLong(u32bits ioport, u32bits val);
-
-	#define OS_Lock(x)
-	#define OS_UnLock(x)
-#endif /* OS2 */
-
-#if defined(SOLARIS_REAL_MODE)
-
-extern unsigned char    inb(unsigned long ioport);
-extern unsigned short   inw(unsigned long ioport);
-
-#define OS_InPortByte(ioport)    inb(ioport)
-#define OS_InPortWord(ioport)    inw(ioport)
-
-extern void OS_OutPortByte(unsigned long ioport, unsigned char val);
-extern void OS_OutPortWord(unsigned long ioport, unsigned short val);
-extern unsigned long  OS_InPortLong(unsigned long ioport);
-extern void     OS_OutPortLong(unsigned long ioport, unsigned long val);
-
-#define OS_Lock(x)
-#define OS_UnLock(x)
-
-#endif  /* SOLARIS_REAL_MODE */
-
-#endif  /* __GLOBALS_H__ */
-
-/*----------------------------------------------------------------------
- *
- *
- *   Copyright 1995-1996 by Mylex Corporation.  All Rights Reserved
- *
- *   This file is available under both the GNU General Public License
- *   and a BSD-style copyright; see LICENSE.FlashPoint for details.
- *
- *   $Workfile:   sccbmgr.h  $
- *
- *   Description:  Common shared SCCB Interface defines and SCCB 
- *						 Manager specifics defines.
- *
- *   $Date: 1996/10/24 23:09:33 $
- *
- *   $Revision: 1.14 $
- *
- *----------------------------------------------------------------------*/
-
-#ifndef __SCCB_H__
-#define __SCCB_H__
-
-/*#include <osflags.h>*/
-/*#include <globals.h>*/
-
-#if defined(BUGBUG)
-#define debug_size 32
-#endif
-
-#if defined(DOS)
-
-   typedef struct _SCCB near *PSCCB;
-	#if (FW_TYPE == _SCCB_MGR_)
-   	typedef void (*CALL_BK_FN)(PSCCB);
-	#endif
-
-#elif defined(OS2)
-
-   typedef struct _SCCB far *PSCCB;
-	#if (FW_TYPE == _SCCB_MGR_)
-   	typedef void (far *CALL_BK_FN)(PSCCB);
-	#endif
-
-#else
-
-   typedef struct _SCCB *PSCCB;
-	#if (FW_TYPE == _SCCB_MGR_)
-   	typedef void (*CALL_BK_FN)(PSCCB);
-	#endif
 
-#endif
+typedef struct _SCCB *PSCCB;
+typedef void (*CALL_BK_FN)(PSCCB);
 
 
 typedef struct SCCBMgr_info {
@@ -466,25 +123,13 @@ typedef struct SCCBMgr_info {
    ULONG    si_secondary_range;
 } SCCBMGR_INFO;
 
-#if defined(DOS)
-   typedef SCCBMGR_INFO *      PSCCBMGR_INFO;
-#else
-   #if defined (COMPILER_16_BIT)
-   typedef SCCBMGR_INFO far *  PSCCBMGR_INFO;
-   #else
-   typedef SCCBMGR_INFO *      PSCCBMGR_INFO;
-   #endif
-#endif // defined(DOS)
-
-
+typedef SCCBMGR_INFO *      PSCCBMGR_INFO;
 
 
-#if (FW_TYPE==_SCCB_MGR_)
-	#define SCSI_PARITY_ENA		  0x0001
-	#define LOW_BYTE_TERM		  0x0010
-	#define HIGH_BYTE_TERM		  0x0020
-	#define BUSTYPE_PCI	  0x3
-#endif
+#define SCSI_PARITY_ENA		  0x0001
+#define LOW_BYTE_TERM		  0x0010
+#define HIGH_BYTE_TERM		  0x0020
+#define BUSTYPE_PCI	  0x3
 
 #define SUPPORT_16TAR_32LUN	  0x0002
 #define SOFT_RESET		  0x0004
@@ -553,9 +198,6 @@ typedef struct _SCCB {
    UCHAR   Save_CdbLen;
    UCHAR   Sccb_XferState;
    ULONG   Sccb_SGoffset;
-#if (FW_TYPE == _UCB_MGR_)
-   PUCB    Sccb_ucb_ptr;
-#endif
    } SCCB;
 
 #define SCCB_SIZE sizeof(SCCB)
@@ -626,25 +268,9 @@ typedef struct _SCCB {
 
 
 
-#if (FW_TYPE==_UCB_MGR_)  
-   #define  HBA_AUTO_SENSE_FAIL        0x1B  
-   #define  HBA_TQ_REJECTED            0x1C  
-   #define  HBA_UNSUPPORTED_MSG         0x1D  
-   #define  HBA_HW_ERROR               0x20  
-   #define  HBA_ATN_NOT_RESPONDED      0x21  
-   #define  HBA_SCSI_RESET_BY_ADAPTER  0x22
-   #define  HBA_SCSI_RESET_BY_TARGET   0x23
-   #define  HBA_WRONG_CONNECTION       0x24
-   #define  HBA_BUS_DEVICE_RESET       0x25
-   #define  HBA_ABORT_QUEUE            0x26
-
-#else // these are not defined in BUDI/UCB
-
-   #define SCCB_INVALID_DIRECTION      0x18  /* Invalid target direction */
-   #define SCCB_DUPLICATE_SCCB         0x19  /* Duplicate SCCB */
-   #define SCCB_SCSI_RST               0x35  /* SCSI RESET detected. */
-
-#endif // (FW_TYPE==_UCB_MGR_)  
+#define SCCB_INVALID_DIRECTION      0x18  /* Invalid target direction */
+#define SCCB_DUPLICATE_SCCB         0x19  /* Duplicate SCCB */
+#define SCCB_SCSI_RST               0x35  /* SCSI RESET detected. */
 
 
 #define SCCB_IN_PROCESS            0x00
@@ -657,115 +283,20 @@ typedef struct _SCCB {
 #define SCCB_SIZE sizeof(SCCB)
 
 
-
-
-#if (FW_TYPE == _UCB_MGR_)
-	void SccbMgr_start_sccb(CARD_HANDLE pCurrCard, PUCB p_ucb);
-	s32bits SccbMgr_abort_sccb(CARD_HANDLE pCurrCard, PUCB p_ucb);
-	u08bits SccbMgr_my_int(CARD_HANDLE pCurrCard);
-	s32bits SccbMgr_isr(CARD_HANDLE pCurrCard);
-	void SccbMgr_scsi_reset(CARD_HANDLE pCurrCard);
-	void SccbMgr_timer_expired(CARD_HANDLE pCurrCard);
-	void SccbMgr_unload_card(CARD_HANDLE pCurrCard);
-	void SccbMgr_restore_foreign_state(CARD_HANDLE pCurrCard);
-	void SccbMgr_restore_native_state(CARD_HANDLE pCurrCard);
-	void SccbMgr_save_foreign_state(PADAPTER_INFO pAdapterInfo);
-
-#endif
-
-
-#if (FW_TYPE == _SCCB_MGR_)
-
- #if defined (DOS)
-	int    SccbMgr_sense_adapter(PSCCBMGR_INFO pCardInfo);
-	USHORT SccbMgr_config_adapter(PSCCBMGR_INFO pCardInfo);
-	void  SccbMgr_start_sccb(USHORT pCurrCard, PSCCB p_SCCB);
-	int   SccbMgr_abort_sccb(USHORT pCurrCard, PSCCB p_SCCB);
-	UCHAR SccbMgr_my_int(USHORT pCurrCard);
-	int   SccbMgr_isr(USHORT pCurrCard);
-	void  SccbMgr_scsi_reset(USHORT pCurrCard);
-	void  SccbMgr_timer_expired(USHORT pCurrCard);
-	USHORT SccbMgr_status(USHORT pCurrCard);
-	void SccbMgr_unload_card(USHORT pCurrCard);
-
- #else    //non-DOS
-
-	int   SccbMgr_sense_adapter(PSCCBMGR_INFO pCardInfo);
-	ULONG SccbMgr_config_adapter(PSCCBMGR_INFO pCardInfo);
-	void  SccbMgr_start_sccb(ULONG pCurrCard, PSCCB p_SCCB);
-	int   SccbMgr_abort_sccb(ULONG pCurrCard, PSCCB p_SCCB);
-	UCHAR SccbMgr_my_int(ULONG pCurrCard);
-	int   SccbMgr_isr(ULONG pCurrCard);
-	void  SccbMgr_scsi_reset(ULONG pCurrCard);
-	void  SccbMgr_enable_int(ULONG pCurrCard);
-	void  SccbMgr_disable_int(ULONG pCurrCard);
-	void  SccbMgr_timer_expired(ULONG pCurrCard);
-	void SccbMgr_unload_card(ULONG pCurrCard);
-
-  #endif
-#endif  // (FW_TYPE == _SCCB_MGR_)
-
-#endif  /* __SCCB_H__ */
-
-/*----------------------------------------------------------------------
- *
- *
- *   Copyright 1995-1996 by Mylex Corporation.  All Rights Reserved
- *
- *   This file is available under both the GNU General Public License
- *   and a BSD-style copyright; see LICENSE.FlashPoint for details.
- *
- *   $Workfile:   blx30.h  $
- *
- *   Description: This module contains SCCB/UCB Manager implementation
- *                specific stuff.
- *
- *   $Date: 1996/11/13 18:34:22 $
- *
- *   $Revision: 1.10 $
- *
- *----------------------------------------------------------------------*/
-
-
-#ifndef __blx30_H__
-#define __blx30_H__
-
-/*#include <globals.h>*/
-
 #define  ORION_FW_REV      3110
 
-
-
-
 #define HARP_REVD    1
 
 
-#if defined(DOS)
-#define QUEUE_DEPTH     8+1            /*1 for Normal disconnect 0 for Q'ing. */
-#else
 #define QUEUE_DEPTH     254+1            /*1 for Normal disconnect 32 for Q'ing. */
-#endif   // defined(DOS)
 
 #define	MAX_MB_CARDS	4					/* Max. no of cards suppoerted on Mother Board */
 
 #define WIDE_SCSI       1
 
-#if defined(WIDE_SCSI)
-   #if defined(DOS)
-      #define MAX_SCSI_TAR    16
-      #define MAX_LUN         8
-		#define LUN_MASK			0x07
-   #else
-      #define MAX_SCSI_TAR    16
-      #define MAX_LUN         32
-		#define LUN_MASK			0x1f
-	
-   #endif
-#else
-   #define MAX_SCSI_TAR    8
-   #define MAX_LUN         8
-	#define LUN_MASK			0x07
-#endif 
+#define MAX_SCSI_TAR    16
+#define MAX_LUN         32
+#define LUN_MASK			0x1f
 
 #if defined(HARP_REVA)
 #define SG_BUF_CNT      15             /*Number of prefetched elements. */
@@ -778,116 +309,12 @@ typedef struct _SCCB {
 #define SG_ELEMENT_MASK 0xFFFFFFFFL
 
 
-#if (FW_TYPE == _UCB_MGR_)
-	#define OPC_DECODE_NORMAL       0x0f7f
-#endif   // _UCB_MGR_
-
-
-
-#if defined(DOS)
-
-/*#include <dos.h>*/
-	#define RD_HARPOON(ioport)          (OS_InPortByte(ioport))
-	#define RDW_HARPOON(ioport)         (OS_InPortWord(ioport))
-	#define WR_HARPOON(ioport,val)      (OS_OutPortByte(ioport,val))
-	#define WRW_HARPOON(ioport,val)     (OS_OutPortWord(ioport,val))
-
-	#define RD_HARP32(port,offset,data)  asm{db 66h;         \
-                                       push ax;             \
-                                       mov dx,port;         \
-                                       add dx, offset;      \
-                                       db 66h;              \
-                                       in ax,dx;            \
-                                       db 66h;              \
-                                       mov word ptr data,ax;\
-                                       db 66h;              \
-                                       pop ax}
-
-	#define WR_HARP32(port,offset,data) asm{db 66h;          \
-                                       push ax;             \
-                                       mov dx,port;         \
-                                       add dx, offset;      \
-                                       db 66h;              \
-                                       mov ax,word ptr data;\
-                                       db 66h;              \
-                                       out dx,ax;           \
-                                       db 66h;              \
-                                       pop ax}
-#endif	/* DOS */
-
-#if defined(NETWARE) || defined(OTHER_32) ||  defined(OTHER_16)
-	#define RD_HARPOON(ioport)     OS_InPortByte((unsigned long)ioport)
-	#define RDW_HARPOON(ioport)    OS_InPortWord((unsigned long)ioport)
-	#define RD_HARP32(ioport,offset,data) (data = OS_InPortLong(ioport + offset))
-	#define WR_HARPOON(ioport,val) OS_OutPortByte((ULONG)ioport,(UCHAR) val)
-	#define WRW_HARPOON(ioport,val)  OS_OutPortWord((ULONG)ioport,(USHORT)val)
-	#define WR_HARP32(ioport,offset,data)  OS_OutPortLong((ioport + offset), data)
-#endif	/* NETWARE || OTHER_32 || OTHER_16 */
-
-#if defined(NT) || defined(WIN95_32) || defined(WIN95_16)
-	#define RD_HARPOON(ioport)          OS_InPortByte((ULONG)ioport)
-	#define RDW_HARPOON(ioport)         OS_InPortWord((ULONG)ioport)
-	#define RD_HARP32(ioport,offset,data) (data = OS_InPortLong((ULONG)(ioport + offset)))
-	#define WR_HARPOON(ioport,val)      OS_OutPortByte((ULONG)ioport,(UCHAR) val)
-	#define WRW_HARPOON(ioport,val)     OS_OutPortWord((ULONG)ioport,(USHORT)val)
-	#define WR_HARP32(ioport,offset,data)  OS_OutPortLong((ULONG)(ioport + offset), data)
-#endif /* NT || WIN95_32 || WIN95_16 */
-
-#if defined (UNIX)
-	#define RD_HARPOON(ioport)          OS_InPortByte((u32bits)ioport)
-	#define RDW_HARPOON(ioport)         OS_InPortWord((u32bits)ioport)
-	#define RD_HARP32(ioport,offset,data) (data = OS_InPortLong((u32bits)(ioport + offset)))
-	#define WR_HARPOON(ioport,val)      OS_OutPortByte((u32bits)ioport,(u08bits) val)
-	#define WRW_HARPOON(ioport,val)       OS_OutPortWord((u32bits)ioport,(u16bits)val)
-	#define WR_HARP32(ioport,offset,data)  OS_OutPortLong((u32bits)(ioport + offset), data)
-#endif /* UNIX */
-
-#if defined(OS2)
-	#define RD_HARPOON(ioport)          OS_InPortByte((unsigned long)ioport)
-	#define RDW_HARPOON(ioport)         OS_InPortWord((unsigned long)ioport)
-	#define RD_HARP32(ioport,offset,data) (data = OS_InPortLong((ULONG)(ioport + offset)))
-	#define WR_HARPOON(ioport,val)      OS_OutPortByte((ULONG)ioport,(UCHAR) val)
-	#define WRW_HARPOON(ioport,val)       OS_OutPortWord((ULONG)ioport,(USHORT)val)
-	#define WR_HARP32(ioport,offset,data)  OS_OutPortLong(((ULONG)(ioport + offset)), data)
-#endif /* OS2 */
-
-#if defined(SOLARIS_REAL_MODE)
-
-	#define RD_HARPOON(ioport)          OS_InPortByte((unsigned long)ioport)
-	#define RDW_HARPOON(ioport)         OS_InPortWord((unsigned long)ioport)
-	#define RD_HARP32(ioport,offset,data) (data = OS_InPortLong((ULONG)(ioport + offset)))
-	#define WR_HARPOON(ioport,val)      OS_OutPortByte((ULONG)ioport,(UCHAR) val)
-	#define WRW_HARPOON(ioport,val)       OS_OutPortWord((ULONG)ioport,(USHORT)val)
-	#define WR_HARP32(ioport,offset,data)  OS_OutPortLong((ULONG)(ioport + offset), (ULONG)data)
-
-#endif  /* SOLARIS_REAL_MODE */
-
-#endif  /* __BLX30_H__ */
-
-
-/*----------------------------------------------------------------------
- * 
- *
- *   Copyright 1995-1996 by Mylex Corporation.  All Rights Reserved
- *
- *   This file is available under both the GNU General Public License
- *   and a BSD-style copyright; see LICENSE.FlashPoint for details.
- *
- *   $Workfile:   target.h  $
- *
- *   Description:  Definitions for Target related structures
- *
- *   $Date: 1996/12/11 22:06:20 $
- *
- *   $Revision: 1.9 $
- *
- *----------------------------------------------------------------------*/
-
-#ifndef __TARGET__
-#define __TARGET__
-
-/*#include <globals.h>*/
-/*#include <blx30.h>*/
+#define RD_HARPOON(ioport)          OS_InPortByte((u32bits)ioport)
+#define RDW_HARPOON(ioport)         OS_InPortWord((u32bits)ioport)
+#define RD_HARP32(ioport,offset,data) (data = OS_InPortLong((u32bits)(ioport + offset)))
+#define WR_HARPOON(ioport,val)      OS_OutPortByte((u32bits)ioport,(u08bits) val)
+#define WRW_HARPOON(ioport,val)       OS_OutPortWord((u32bits)ioport,(u16bits)val)
+#define WR_HARP32(ioport,offset,data)  OS_OutPortLong((u32bits)(ioport + offset), data)
 
 
 #define  TAR_SYNC_MASK     (BIT(7)+BIT(6))
@@ -919,16 +346,7 @@ typedef struct _SCCB {
 #define  EE_WIDE_SCSI      BIT(7)
 
 
-#if defined(DOS)
-   typedef struct SCCBMgr_tar_info near *PSCCBMgr_tar_info;
-
-#elif defined(OS2)
-   typedef struct SCCBMgr_tar_info far *PSCCBMgr_tar_info;
-
-#else
-   typedef struct SCCBMgr_tar_info *PSCCBMgr_tar_info;
-
-#endif
+typedef struct SCCBMgr_tar_info *PSCCBMgr_tar_info;
 
 
 typedef struct SCCBMgr_tar_info {
@@ -949,11 +367,7 @@ typedef struct SCCBMgr_tar_info {
 typedef struct NVRAMInfo {
 	UCHAR		niModel;								/* Model No. of card */
 	UCHAR		niCardNo;							/* Card no. */
-#if defined(DOS)
-	USHORT	niBaseAddr;							/* Port Address of card */
-#else
 	ULONG		niBaseAddr;							/* Port Address of card */
-#endif
 	UCHAR		niSysConf;							/* Adapter Configuration byte - Byte 16 of eeprom map */
 	UCHAR		niScsiConf;							/* SCSI Configuration byte - Byte 17 of eeprom map */
 	UCHAR		niScamConf;							/* SCAM Configuration byte - Byte 20 of eeprom map */
@@ -962,13 +376,7 @@ typedef struct NVRAMInfo {
 	UCHAR		niScamTbl[MAX_SCSI_TAR][4];	/* Compressed Scam name string of Targets */
 }NVRAMINFO;
 
-#if defined(DOS)
-typedef NVRAMINFO near *PNVRamInfo;
-#elif defined (OS2)
-typedef NVRAMINFO far *PNVRamInfo;
-#else
 typedef NVRAMINFO *PNVRamInfo;
-#endif
 
 #define	MODEL_LT		1
 #define	MODEL_DL		2
@@ -978,17 +386,9 @@ typedef NVRAMINFO *PNVRamInfo;
 
 typedef struct SCCBcard {
    PSCCB currentSCCB;
-#if (FW_TYPE==_SCCB_MGR_)
    PSCCBMGR_INFO cardInfo;
-#else
-   PADAPTER_INFO cardInfo;
-#endif
 
-#if defined(DOS)
-   USHORT ioPort;
-#else
    ULONG ioPort;
-#endif
 
    USHORT cmdCounter;
    UCHAR  discQCount;
@@ -1002,13 +402,7 @@ typedef struct SCCBcard {
       
 }SCCBCARD;
 
-#if defined(DOS)
-typedef struct SCCBcard near *PSCCBcard;
-#elif defined (OS2)
-typedef struct SCCBcard far *PSCCBcard;
-#else
 typedef struct SCCBcard *PSCCBcard;
-#endif
 
 
 #define F_TAG_STARTED		0x01
@@ -1063,29 +457,6 @@ typedef struct SCCBscam_info {
     
 } SCCBSCAM_INFO, *PSCCBSCAM_INFO;
 
-#endif
-/*----------------------------------------------------------------------
- *
- *
- *   Copyright 1995-1996 by Mylex Corporation.  All Rights Reserved
- *
- *   This file is available under both the GNU General Public License
- *   and a BSD-style copyright; see LICENSE.FlashPoint for details.
- *
- *   $Workfile:   scsi2.h  $
- *
- *   Description:  Register definitions for HARPOON ASIC.
- *
- *   $Date: 1996/11/13 18:32:57 $
- *
- *   $Revision: 1.4 $
- *
- *----------------------------------------------------------------------*/
-
-#ifndef __SCSI_H__
-#define __SCSI_H__
-
-
 
 #define  SCSI_TEST_UNIT_READY    0x00
 #define  SCSI_REZERO_UNIT        0x01
@@ -1195,29 +566,6 @@ typedef struct SCCBscam_info {
 #define  SYNC5MBS                0x32
 #define  MAX_OFFSET              0x0F  /* Maxbyteoffset for Sync Xfers */
 
-#endif
-/*----------------------------------------------------------------------
- *  
- *
- *   Copyright 1995-1996 by Mylex Corporation.  All Rights Reserved
- *
- *   This file is available under both the GNU General Public License
- *   and a BSD-style copyright; see LICENSE.FlashPoint for details.
- *
- *   $Workfile:   eeprom.h  $
- *
- *   Description:  Definitions for EEPROM related structures
- *
- *   $Date: 1996/11/13 18:28:39 $
- *
- *   $Revision: 1.4 $
- *
- *----------------------------------------------------------------------*/
-
-#ifndef __EEPROM__
-#define __EEPROM__
-
-/*#include <globals.h>*/
 
 #define  EEPROM_WD_CNT     256
 
@@ -1280,31 +628,6 @@ typedef struct SCCBscam_info {
    #define  DISC_ENABLE_BIT   BIT(6)
 
 
-#endif
-/*----------------------------------------------------------------------
- *
- *
- *   Copyright 1995-1996 by Mylex Corporation.  All Rights Reserved
- *
- *   This file is available under both the GNU General Public License
- *   and a BSD-style copyright; see LICENSE.FlashPoint for details.
- *
- *   $Workfile:   harpoon.h  $
- *
- *   Description:  Register definitions for HARPOON ASIC.
- *
- *   $Date: 1997/07/09 21:44:36 $
- *
- *   $Revision: 1.9 $
- *
- *----------------------------------------------------------------------*/
-
-
-/*#include <globals.h>*/
-
-#ifndef __HARPOON__
-#define __HARPOON__
-
 
    #define  hp_vendor_id_0       0x00		/* LSB */
       #define  ORION_VEND_0   0x4B
@@ -1578,8 +901,6 @@ typedef struct SCCBscam_info {
 
 
 
-   extern USHORT default_intena;
-
    #define  hp_intena		 0x40
 
       #define  RESET		 BITW(7)
@@ -1972,15 +1293,6 @@ typedef struct SCCBscam_info {
                                  xfercnt <<= 16,\
                                  xfercnt |= RDW_HARPOON((USHORT)(port+hp_xfercnt_0)))
  */
-#if defined(DOS)
-#define HP_SETUP_ADDR_CNT(port,addr,count) (WRW_HARPOON((USHORT)(port+hp_host_addr_lo), (USHORT)(addr & 0x0000FFFFL)),\
-         addr >>= 16,\
-         WRW_HARPOON((USHORT)(port+hp_host_addr_hmi), (USHORT)(addr & 0x0000FFFFL)),\
-         WR_HARP32(port,hp_xfercnt_0,count),\
-         WRW_HARPOON((USHORT)(port+hp_xfer_cnt_lo), (USHORT)(count & 0x0000FFFFL)),\
-         count >>= 16,\
-         WR_HARPOON(port+hp_xfer_cnt_hi, (count & 0xFF)))
-#else
 #define HP_SETUP_ADDR_CNT(port,addr,count) (WRW_HARPOON((port+hp_host_addr_lo), (USHORT)(addr & 0x0000FFFFL)),\
          addr >>= 16,\
          WRW_HARPOON((port+hp_host_addr_hmi), (USHORT)(addr & 0x0000FFFFL)),\
@@ -1988,7 +1300,6 @@ typedef struct SCCBscam_info {
          WRW_HARPOON((port+hp_xfer_cnt_lo), (USHORT)(count & 0x0000FFFFL)),\
          count >>= 16,\
          WR_HARPOON(port+hp_xfer_cnt_hi, (count & 0xFF)))
-#endif
 
 #define ACCEPT_MSG(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
                           WR_HARPOON(port+hp_scsisig, S_ILL_PH);}
@@ -2020,383 +1331,145 @@ typedef struct SCCBscam_info {
 
 
 
-#endif
-
-
-#if (FW_TYPE==_UCB_MGR_)
-void ReadNVRam(PSCCBcard pCurrCard,PUCB p_ucb);
-void WriteNVRam(PSCCBcard pCurrCard,PUCB p_ucb);
-void UpdateCheckSum(u32bits baseport);
-#endif // (FW_TYPE==_UCB_MGR_)
-
-#if defined(DOS)
-UCHAR sfm(USHORT port, PSCCB pcurrSCCB);
-void  scsiStartAuto(USHORT port);
-UCHAR sisyncn(USHORT port, UCHAR p_card, UCHAR syncFlag);
-void  ssel(USHORT port, UCHAR p_card);
-void  sres(USHORT port, UCHAR p_card, PSCCBcard pCurrCard);
-void  sdecm(UCHAR message, USHORT port, UCHAR p_card);
-void  shandem(USHORT port, UCHAR p_card,PSCCB pCurrSCCB);
-void  stsyncn(USHORT port, UCHAR p_card);
-void  sisyncr(USHORT port,UCHAR sync_pulse, UCHAR offset);
-void  sssyncv(USHORT p_port, UCHAR p_id, UCHAR p_sync_value, PSCCBMgr_tar_info currTar_Info);
-void  sresb(USHORT port, UCHAR p_card);
-void  sxfrp(USHORT p_port, UCHAR p_card);
-void  schkdd(USHORT port, UCHAR p_card);
-UCHAR RdStack(USHORT port, UCHAR index);
-void  WrStack(USHORT portBase, UCHAR index, UCHAR data);
-UCHAR ChkIfChipInitialized(USHORT ioPort);
-
-#if defined(V302)
-UCHAR GetTarLun(USHORT port, UCHAR p_card, UCHAR our_target, PSCCBcard pCurrCard, PUCHAR tag, PUCHAR lun);
-#endif
 
-void SendMsg(USHORT port, UCHAR message);
-void  queueFlushTargSccb(UCHAR p_card, UCHAR thisTarg, UCHAR error_code);
-UCHAR scsellDOS(USHORT p_port, UCHAR targ_id);
-#else
-UCHAR sfm(ULONG port, PSCCB pcurrSCCB);
 void  scsiStartAuto(ULONG port);
-UCHAR sisyncn(ULONG port, UCHAR p_card, UCHAR syncFlag);
-void  ssel(ULONG port, UCHAR p_card);
-void  sres(ULONG port, UCHAR p_card, PSCCBcard pCurrCard);
-void  sdecm(UCHAR message, ULONG port, UCHAR p_card);
-void  shandem(ULONG port, UCHAR p_card,PSCCB pCurrSCCB);
-void  stsyncn(ULONG port, UCHAR p_card);
-void  sisyncr(ULONG port,UCHAR sync_pulse, UCHAR offset);
-void  sssyncv(ULONG p_port, UCHAR p_id, UCHAR p_sync_value, PSCCBMgr_tar_info currTar_Info);
-void  sresb(ULONG port, UCHAR p_card);
-void  sxfrp(ULONG p_port, UCHAR p_card);
-void  schkdd(ULONG port, UCHAR p_card);
-UCHAR RdStack(ULONG port, UCHAR index);
-void  WrStack(ULONG portBase, UCHAR index, UCHAR data);
-UCHAR ChkIfChipInitialized(ULONG ioPort);
-
-#if defined(V302)
-UCHAR GetTarLun(ULONG port, UCHAR p_card, UCHAR our_target, PSCCBcard pCurrCard, PUCHAR tar, PUCHAR lun);
-#endif
-
-void SendMsg(ULONG port, UCHAR message);
-void  queueFlushTargSccb(UCHAR p_card, UCHAR thisTarg, UCHAR error_code);
-#endif
-
-void  ssenss(PSCCBcard pCurrCard);
-void  sinits(PSCCB p_sccb, UCHAR p_card);
-void  RNVRamData(PNVRamInfo pNvRamInfo);
-
-#if defined(WIDE_SCSI)
-   #if defined(DOS)
-   UCHAR siwidn(USHORT port, UCHAR p_card);
-   void  stwidn(USHORT port, UCHAR p_card);
-   void  siwidr(USHORT port, UCHAR width);
-   #else
-   UCHAR siwidn(ULONG port, UCHAR p_card);
-   void  stwidn(ULONG port, UCHAR p_card);
-   void  siwidr(ULONG port, UCHAR width);
-   #endif
-#endif
-
-
-void  queueSelectFail(PSCCBcard pCurrCard, UCHAR p_card);
-void  queueDisconnect(PSCCB p_SCCB, UCHAR p_card);
-void  queueCmdComplete(PSCCBcard pCurrCard, PSCCB p_SCCB, UCHAR p_card);
-void  queueSearchSelect(PSCCBcard pCurrCard, UCHAR p_card);
-void  queueFlushSccb(UCHAR p_card, UCHAR error_code);
-void  queueAddSccb(PSCCB p_SCCB, UCHAR card);
-UCHAR queueFindSccb(PSCCB p_SCCB, UCHAR p_card);
-void  utilUpdateResidual(PSCCB p_SCCB);
-USHORT CalcCrc16(UCHAR buffer[]);
-UCHAR  CalcLrc(UCHAR buffer[]);
-
-
-#if defined(DOS)
-void  Wait1Second(USHORT p_port);
-void  Wait(USHORT p_port, UCHAR p_delay);
-void  utilEEWriteOnOff(USHORT p_port,UCHAR p_mode);
-void  utilEEWrite(USHORT p_port, USHORT ee_data, USHORT ee_addr);
-USHORT utilEERead(USHORT p_port, USHORT ee_addr);
-USHORT utilEEReadOrg(USHORT p_port, USHORT ee_addr);
-void  utilEESendCmdAddr(USHORT p_port, UCHAR ee_cmd, USHORT ee_addr);
-#else
-void  Wait1Second(ULONG p_port);
-void  Wait(ULONG p_port, UCHAR p_delay);
-void  utilEEWriteOnOff(ULONG p_port,UCHAR p_mode);
-void  utilEEWrite(ULONG p_port, USHORT ee_data, USHORT ee_addr);
-USHORT utilEERead(ULONG p_port, USHORT ee_addr);
-USHORT utilEEReadOrg(ULONG p_port, USHORT ee_addr);
-void  utilEESendCmdAddr(ULONG p_port, UCHAR ee_cmd, USHORT ee_addr);
-#endif
-
-
-
-#if defined(OS2)
-   void  far phaseDataOut(ULONG port, UCHAR p_card);
-   void  far phaseDataIn(ULONG port, UCHAR p_card);
-   void  far phaseCommand(ULONG port, UCHAR p_card);
-   void  far phaseStatus(ULONG port, UCHAR p_card);
-   void  far phaseMsgOut(ULONG port, UCHAR p_card);
-   void  far phaseMsgIn(ULONG port, UCHAR p_card);
-   void  far phaseIllegal(ULONG port, UCHAR p_card);
-#else
-   #if defined(DOS)
-      void  phaseDataOut(USHORT port, UCHAR p_card);
-      void  phaseDataIn(USHORT port, UCHAR p_card);
-      void  phaseCommand(USHORT port, UCHAR p_card);
-      void  phaseStatus(USHORT port, UCHAR p_card);
-      void  phaseMsgOut(USHORT port, UCHAR p_card);
-      void  phaseMsgIn(USHORT port, UCHAR p_card);
-      void  phaseIllegal(USHORT port, UCHAR p_card);
-   #else
-      void  phaseDataOut(ULONG port, UCHAR p_card);
-      void  phaseDataIn(ULONG port, UCHAR p_card);
-      void  phaseCommand(ULONG port, UCHAR p_card);
-      void  phaseStatus(ULONG port, UCHAR p_card);
-      void  phaseMsgOut(ULONG port, UCHAR p_card);
-      void  phaseMsgIn(ULONG port, UCHAR p_card);
-      void  phaseIllegal(ULONG port, UCHAR p_card);
-   #endif
-#endif
-
-#if defined(DOS)
-void  phaseDecode(USHORT port, UCHAR p_card);
-void  phaseChkFifo(USHORT port, UCHAR p_card);
-void  phaseBusFree(USHORT p_port, UCHAR p_card);
-#else
-void  phaseDecode(ULONG port, UCHAR p_card);
-void  phaseChkFifo(ULONG port, UCHAR p_card);
-void  phaseBusFree(ULONG p_port, UCHAR p_card);
-#endif
-
-
-
-
-#if defined(DOS)
-void  XbowInit(USHORT port, UCHAR scamFlg);
-void  BusMasterInit(USHORT p_port);
-int   DiagXbow(USHORT port);
-int   DiagBusMaster(USHORT port);
-void  DiagEEPROM(USHORT p_port);
-#else
-void  XbowInit(ULONG port, UCHAR scamFlg);
-void  BusMasterInit(ULONG p_port);
-int   DiagXbow(ULONG port);
-int   DiagBusMaster(ULONG port);
-void  DiagEEPROM(ULONG p_port);
-#endif
+static UCHAR FPT_sisyncn(ULONG port, UCHAR p_card, UCHAR syncFlag);
+static void  FPT_ssel(ULONG port, UCHAR p_card);
+static void  FPT_sres(ULONG port, UCHAR p_card, PSCCBcard pCurrCard);
+static void  FPT_shandem(ULONG port, UCHAR p_card,PSCCB pCurrSCCB);
+static void  FPT_stsyncn(ULONG port, UCHAR p_card);
+static void  FPT_sisyncr(ULONG port,UCHAR sync_pulse, UCHAR offset);
+static void  FPT_sssyncv(ULONG p_port, UCHAR p_id, UCHAR p_sync_value,
+			 PSCCBMgr_tar_info currTar_Info);
+static void  FPT_sresb(ULONG port, UCHAR p_card);
+static void  FPT_sxfrp(ULONG p_port, UCHAR p_card);
+static void  FPT_schkdd(ULONG port, UCHAR p_card);
+static UCHAR FPT_RdStack(ULONG port, UCHAR index);
+static void  FPT_WrStack(ULONG portBase, UCHAR index, UCHAR data);
+static UCHAR FPT_ChkIfChipInitialized(ULONG ioPort);
+
+static void FPT_SendMsg(ULONG port, UCHAR message);
+static void  FPT_queueFlushTargSccb(UCHAR p_card, UCHAR thisTarg,
+				    UCHAR error_code);
+
+static void  FPT_sinits(PSCCB p_sccb, UCHAR p_card);
+static void  FPT_RNVRamData(PNVRamInfo pNvRamInfo);
+
+static UCHAR FPT_siwidn(ULONG port, UCHAR p_card);
+static void  FPT_stwidn(ULONG port, UCHAR p_card);
+static void  FPT_siwidr(ULONG port, UCHAR width);
+
+
+static void  FPT_queueSelectFail(PSCCBcard pCurrCard, UCHAR p_card);
+static void  FPT_queueDisconnect(PSCCB p_SCCB, UCHAR p_card);
+static void  FPT_queueCmdComplete(PSCCBcard pCurrCard, PSCCB p_SCCB,
+				  UCHAR p_card);
+static void  FPT_queueSearchSelect(PSCCBcard pCurrCard, UCHAR p_card);
+static void  FPT_queueFlushSccb(UCHAR p_card, UCHAR error_code);
+static void  FPT_queueAddSccb(PSCCB p_SCCB, UCHAR card);
+static UCHAR FPT_queueFindSccb(PSCCB p_SCCB, UCHAR p_card);
+static void  FPT_utilUpdateResidual(PSCCB p_SCCB);
+static USHORT FPT_CalcCrc16(UCHAR buffer[]);
+static UCHAR  FPT_CalcLrc(UCHAR buffer[]);
+
+
+static void  FPT_Wait1Second(ULONG p_port);
+static void  FPT_Wait(ULONG p_port, UCHAR p_delay);
+static void  FPT_utilEEWriteOnOff(ULONG p_port,UCHAR p_mode);
+static void  FPT_utilEEWrite(ULONG p_port, USHORT ee_data, USHORT ee_addr);
+static USHORT FPT_utilEERead(ULONG p_port, USHORT ee_addr);
+static USHORT FPT_utilEEReadOrg(ULONG p_port, USHORT ee_addr);
+static void  FPT_utilEESendCmdAddr(ULONG p_port, UCHAR ee_cmd, USHORT ee_addr);
+
+
+
+static void  FPT_phaseDataOut(ULONG port, UCHAR p_card);
+static void  FPT_phaseDataIn(ULONG port, UCHAR p_card);
+static void  FPT_phaseCommand(ULONG port, UCHAR p_card);
+static void  FPT_phaseStatus(ULONG port, UCHAR p_card);
+static void  FPT_phaseMsgOut(ULONG port, UCHAR p_card);
+static void  FPT_phaseMsgIn(ULONG port, UCHAR p_card);
+static void  FPT_phaseIllegal(ULONG port, UCHAR p_card);
+
+static void  FPT_phaseDecode(ULONG port, UCHAR p_card);
+static void  FPT_phaseChkFifo(ULONG port, UCHAR p_card);
+static void  FPT_phaseBusFree(ULONG p_port, UCHAR p_card);
+
+
+
+
+static void  FPT_XbowInit(ULONG port, UCHAR scamFlg);
+static void  FPT_BusMasterInit(ULONG p_port);
+static void  FPT_DiagEEPROM(ULONG p_port);
 
 
 
 
-#if defined(DOS)
-void  busMstrAbort(USHORT port);
-UCHAR busMstrTimeOut(USHORT port);
-void  dataXferProcessor(USHORT port, PSCCBcard pCurrCard);
-void  busMstrSGDataXferStart(USHORT port, PSCCB pCurrSCCB);
-void  busMstrDataXferStart(USHORT port, PSCCB pCurrSCCB);
-void  hostDataXferAbort(USHORT port, UCHAR p_card, PSCCB pCurrSCCB);
-#else
 void  busMstrAbort(ULONG port);
-UCHAR busMstrTimeOut(ULONG port);
-void  dataXferProcessor(ULONG port, PSCCBcard pCurrCard);
-void  busMstrSGDataXferStart(ULONG port, PSCCB pCurrSCCB);
-void  busMstrDataXferStart(ULONG port, PSCCB pCurrSCCB);
-void  hostDataXferAbort(ULONG port, UCHAR p_card, PSCCB pCurrSCCB);
-#endif
-void  hostDataXferRestart(PSCCB currSCCB);
-
-
-#if defined (DOS)
-UCHAR SccbMgr_bad_isr(USHORT p_port, UCHAR p_card, PSCCBcard pCurrCard, USHORT p_int);
-#else
-UCHAR SccbMgr_bad_isr(ULONG p_port, UCHAR p_card, PSCCBcard pCurrCard, USHORT p_int);
-
-#endif
-
-void  SccbMgrTableInitAll(void);
-void  SccbMgrTableInitCard(PSCCBcard pCurrCard, UCHAR p_card);
-void  SccbMgrTableInitTarget(UCHAR p_card, UCHAR target);
-
-
-
-void  scini(UCHAR p_card, UCHAR p_our_id, UCHAR p_power_up);
-
-#if defined(DOS)
-int   scarb(USHORT p_port, UCHAR p_sel_type);
-void  scbusf(USHORT p_port);
-void  scsel(USHORT p_port);
-void  scasid(UCHAR p_card, USHORT p_port);
-UCHAR scxferc(USHORT p_port, UCHAR p_data);
-UCHAR scsendi(USHORT p_port, UCHAR p_id_string[]);
-UCHAR sciso(USHORT p_port, UCHAR p_id_string[]);
-void  scwirod(USHORT p_port, UCHAR p_data_bit);
-void  scwiros(USHORT p_port, UCHAR p_data_bit);
-UCHAR scvalq(UCHAR p_quintet);
-UCHAR scsell(USHORT p_port, UCHAR targ_id);
-void  scwtsel(USHORT p_port);
-void  inisci(UCHAR p_card, USHORT p_port, UCHAR p_our_id);
-void  scsavdi(UCHAR p_card, USHORT p_port);
-#else
-int   scarb(ULONG p_port, UCHAR p_sel_type);
-void  scbusf(ULONG p_port);
-void  scsel(ULONG p_port);
-void  scasid(UCHAR p_card, ULONG p_port);
-UCHAR scxferc(ULONG p_port, UCHAR p_data);
-UCHAR scsendi(ULONG p_port, UCHAR p_id_string[]);
-UCHAR sciso(ULONG p_port, UCHAR p_id_string[]);
-void  scwirod(ULONG p_port, UCHAR p_data_bit);
-void  scwiros(ULONG p_port, UCHAR p_data_bit);
-UCHAR scvalq(UCHAR p_quintet);
-UCHAR scsell(ULONG p_port, UCHAR targ_id);
-void  scwtsel(ULONG p_port);
-void  inisci(UCHAR p_card, ULONG p_port, UCHAR p_our_id);
-void  scsavdi(UCHAR p_card, ULONG p_port);
-#endif
-UCHAR scmachid(UCHAR p_card, UCHAR p_id_string[]);
-
-
-#if defined(DOS)
-void  autoCmdCmplt(USHORT p_port, UCHAR p_card);
-void  autoLoadDefaultMap(USHORT p_port);
-#else
-void  autoCmdCmplt(ULONG p_port, UCHAR p_card);
-void  autoLoadDefaultMap(ULONG p_port);
-#endif
-
-
-
-#if (FW_TYPE==_SCCB_MGR_)
-	void  OS_start_timer(unsigned long ioport, unsigned long timeout);
-	void  OS_stop_timer(unsigned long ioport, unsigned long timeout);
-	void  OS_disable_int(unsigned char intvec);
-	void  OS_enable_int(unsigned char intvec);
-	void  OS_delay(unsigned long count);
-	int   OS_VirtToPhys(u32bits CardHandle, u32bits *physaddr, u32bits *virtaddr);
-	#if !(defined(UNIX) || defined(OS2) || defined(SOLARIS_REAL_MODE)) 
-	void  OS_Lock(PSCCBMGR_INFO pCardInfo);
-	void  OS_UnLock(PSCCBMGR_INFO pCardInfo);
-#endif // if FW_TYPE == ...
-
-#endif
-
-extern SCCBCARD BL_Card[MAX_CARDS];
-extern SCCBMGR_TAR_INFO sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR];
-
-
-#if defined(OS2)
-   extern void (far *s_PhaseTbl[8]) (ULONG, UCHAR);
-#else
-   #if defined(DOS)
-      extern void (*s_PhaseTbl[8]) (USHORT, UCHAR);
-   #else
-      extern void (*s_PhaseTbl[8]) (ULONG, UCHAR);
-   #endif
-#endif
-
-extern SCCBSCAM_INFO scamInfo[MAX_SCSI_TAR];
-extern NVRAMINFO nvRamInfo[MAX_MB_CARDS];
-#if defined(DOS) || defined(OS2)
-extern UCHAR temp_id_string[ID_STRING_LENGTH];
-#endif
-extern UCHAR scamHAString[];
-
-
-extern UCHAR mbCards;
-#if defined(BUGBUG)
-extern UCHAR debug_int[MAX_CARDS][debug_size];
-extern UCHAR debug_index[MAX_CARDS];
-void Debug_Load(UCHAR p_card, UCHAR p_bug_data);
-#endif
+static void  FPT_dataXferProcessor(ULONG port, PSCCBcard pCurrCard);
+static void  FPT_busMstrSGDataXferStart(ULONG port, PSCCB pCurrSCCB);
+static void  FPT_busMstrDataXferStart(ULONG port, PSCCB pCurrSCCB);
+static void  FPT_hostDataXferAbort(ULONG port, UCHAR p_card, PSCCB pCurrSCCB);
+static void  FPT_hostDataXferRestart(PSCCB currSCCB);
 
-#if (FW_TYPE==_SCCB_MGR_)
-#if defined(DOS)
-   extern UCHAR first_time;
-#endif
-#endif /* (FW_TYPE==_SCCB_MGR_) */
 
-#if (FW_TYPE==_UCB_MGR_)
-#if defined(DOS)
-   extern u08bits first_time;
-#endif
-#endif /* (FW_TYPE==_UCB_MGR_) */
+static UCHAR FPT_SccbMgr_bad_isr(ULONG p_port, UCHAR p_card,
+				 PSCCBcard pCurrCard, USHORT p_int);
 
-#if defined(BUGBUG)
-void Debug_Load(UCHAR p_card, UCHAR p_bug_data);
-#endif
+static void  FPT_SccbMgrTableInitAll(void);
+static void  FPT_SccbMgrTableInitCard(PSCCBcard pCurrCard, UCHAR p_card);
+static void  FPT_SccbMgrTableInitTarget(UCHAR p_card, UCHAR target);
 
-extern unsigned int SccbGlobalFlags;
 
 
-#ident "$Id: sccb.c 1.18 1997/06/10 16:47:04 mohan Exp $"
-/*----------------------------------------------------------------------
- *
- *
- *   Copyright 1995-1996 by Mylex Corporation.  All Rights Reserved
- *
- *   This file is available under both the GNU General Public License
- *   and a BSD-style copyright; see LICENSE.FlashPoint for details.
- *
- *   $Workfile:   sccb.c  $
- *
- *   Description:  Functions relating to handling of the SCCB interface
- *                 between the device driver and the HARPOON.
- *
- *   $Date: 1997/06/10 16:47:04 $
- *
- *   $Revision: 1.18 $
- *
- *----------------------------------------------------------------------*/
+static void  FPT_scini(UCHAR p_card, UCHAR p_our_id, UCHAR p_power_up);
 
-/*#include <globals.h>*/
+static int   FPT_scarb(ULONG p_port, UCHAR p_sel_type);
+static void  FPT_scbusf(ULONG p_port);
+static void  FPT_scsel(ULONG p_port);
+static void  FPT_scasid(UCHAR p_card, ULONG p_port);
+static UCHAR FPT_scxferc(ULONG p_port, UCHAR p_data);
+static UCHAR FPT_scsendi(ULONG p_port, UCHAR p_id_string[]);
+static UCHAR FPT_sciso(ULONG p_port, UCHAR p_id_string[]);
+static void  FPT_scwirod(ULONG p_port, UCHAR p_data_bit);
+static void  FPT_scwiros(ULONG p_port, UCHAR p_data_bit);
+static UCHAR FPT_scvalq(UCHAR p_quintet);
+static UCHAR FPT_scsell(ULONG p_port, UCHAR targ_id);
+static void  FPT_scwtsel(ULONG p_port);
+static void  FPT_inisci(UCHAR p_card, ULONG p_port, UCHAR p_our_id);
+static void  FPT_scsavdi(UCHAR p_card, ULONG p_port);
+static UCHAR FPT_scmachid(UCHAR p_card, UCHAR p_id_string[]);
 
-#if (FW_TYPE==_UCB_MGR_)
-	/*#include <budi.h>*/
-	/*#include <budioctl.h>*/
-#endif
 
-/*#include <sccbmgr.h>*/
-/*#include <blx30.h>*/
-/*#include <target.h>*/
-/*#include <eeprom.h>*/
-/*#include <scsi2.h>*/
-/*#include <harpoon.h>*/
+static void  FPT_autoCmdCmplt(ULONG p_port, UCHAR p_card);
+static void  FPT_autoLoadDefaultMap(ULONG p_port);
 
 
 
-#if (FW_TYPE==_SCCB_MGR_)
-#define mOS_Lock(card)    OS_Lock((PSCCBMGR_INFO)(((PSCCBcard)card)->cardInfo))
-#define mOS_UnLock(card)  OS_UnLock((PSCCBMGR_INFO)(((PSCCBcard)card)->cardInfo))
-#else /* FW_TYPE==_UCB_MGR_ */
-#define mOS_Lock(card)    OS_Lock((u32bits)(((PSCCBcard)card)->ioPort))
-#define mOS_UnLock(card)  OS_UnLock((u32bits)(((PSCCBcard)card)->ioPort))
-#endif
+void  OS_start_timer(unsigned long ioport, unsigned long timeout);
+void  OS_stop_timer(unsigned long ioport, unsigned long timeout);
+void  OS_disable_int(unsigned char intvec);
+void  OS_enable_int(unsigned char intvec);
+void  OS_delay(unsigned long count);
+int   OS_VirtToPhys(u32bits CardHandle, u32bits *physaddr, u32bits *virtaddr);
 
+static SCCBMGR_TAR_INFO FPT_sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR] = { { { 0 } } };
+static SCCBCARD FPT_BL_Card[MAX_CARDS] = { { 0 } };
+static SCCBSCAM_INFO FPT_scamInfo[MAX_SCSI_TAR] = { { { 0 } } };
+static NVRAMINFO FPT_nvRamInfo[MAX_MB_CARDS] = { { 0 } };
 
-/*
-extern SCCBMGR_TAR_INFO sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR];
-extern SCCBCARD BL_Card[MAX_CARDS];
 
-extern NVRAMINFO nvRamInfo[MAX_MB_CARDS];
-extern UCHAR mbCards;
+static UCHAR FPT_mbCards = 0;
+static UCHAR FPT_scamHAString[] = {0x63, 0x07, 'B', 'U', 'S', 'L', 'O', 'G', 'I', 'C', \
+				   ' ', 'B', 'T', '-', '9', '3', '0', \
+				   0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, \
+				   0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};
 
-#if defined (OS2)
-   extern void (far *s_PhaseTbl[8]) (ULONG, UCHAR);
-#else
-   #if defined(DOS)
-      extern void (*s_PhaseTbl[8]) (USHORT, UCHAR);
-   #else
-      extern void (*s_PhaseTbl[8]) (ULONG, UCHAR);
-   #endif
-#endif
+static USHORT FPT_default_intena = 0;
 
 
-#if defined(BUGBUG)
-extern UCHAR debug_int[MAX_CARDS][debug_size];
-extern UCHAR debug_index[MAX_CARDS];
-void Debug_Load(UCHAR p_card, UCHAR p_bug_data);
-#endif
-*/
+static void (*FPT_s_PhaseTbl[8]) (ULONG, UCHAR)= { 0 };
 
-#if (FW_TYPE==_SCCB_MGR_)
 
 /*---------------------------------------------------------------------
  *
@@ -2406,27 +1479,16 @@ void Debug_Load(UCHAR p_card, UCHAR p_bu
  *
  *---------------------------------------------------------------------*/
 
-int SccbMgr_sense_adapter(PSCCBMGR_INFO pCardInfo)
+static int SccbMgr_sense_adapter(PSCCBMGR_INFO pCardInfo)
 {
-#if defined(DOS)
-#else
    static UCHAR first_time = 1;
-#endif
 
    UCHAR i,j,id,ScamFlg;
    USHORT temp,temp2,temp3,temp4,temp5,temp6;
-#if defined(DOS)
-   USHORT ioport;
-#else
    ULONG ioport;
-#endif
 	PNVRamInfo pCurrNvRam;
 
-#if defined(DOS)
-   ioport = (USHORT)pCardInfo->si_baseaddr;
-#else
    ioport = pCardInfo->si_baseaddr;
-#endif
 
 
    if (RD_HARPOON(ioport+hp_vendor_id_0) != ORION_VEND_0)
@@ -2455,36 +1517,31 @@ int SccbMgr_sense_adapter(PSCCBMGR_INFO 
 
    if (first_time)
       {
-      SccbMgrTableInitAll();
+      FPT_SccbMgrTableInitAll();
       first_time = 0;
-		mbCards = 0;
+		FPT_mbCards = 0;
       }
 
-	if(RdStack(ioport, 0) != 0x00) {
-		if(ChkIfChipInitialized(ioport) == FALSE)
+	if(FPT_RdStack(ioport, 0) != 0x00) {
+		if(FPT_ChkIfChipInitialized(ioport) == 0)
 		{
 			pCurrNvRam = NULL;
 		   WR_HARPOON(ioport+hp_semaphore, 0x00);
-			XbowInit(ioport, 0);             /*Must Init the SCSI before attempting */
-			DiagEEPROM(ioport);
+			FPT_XbowInit(ioport, 0);             /*Must Init the SCSI before attempting */
+			FPT_DiagEEPROM(ioport);
 		}
 		else
 		{
-			if(mbCards < MAX_MB_CARDS) {
-				pCurrNvRam = &nvRamInfo[mbCards];
-				mbCards++;
+			if(FPT_mbCards < MAX_MB_CARDS) {
+				pCurrNvRam = &FPT_nvRamInfo[FPT_mbCards];
+				FPT_mbCards++;
 				pCurrNvRam->niBaseAddr = ioport;
-				RNVRamData(pCurrNvRam);
+				FPT_RNVRamData(pCurrNvRam);
 			}else
 				return((int) FAILURE);
 		}
 	}else
 		pCurrNvRam = NULL;
-#if defined (NO_BIOS_OPTION)
-	pCurrNvRam = NULL;
-   XbowInit(ioport, 0);                /*Must Init the SCSI before attempting */
-   DiagEEPROM(ioport);
-#endif  /* No BIOS Option */
 
    WR_HARPOON(ioport+hp_clkctrl_0, CLKCTRL_DEFAULT);
    WR_HARPOON(ioport+hp_sys_ctrl, 0x00);
@@ -2492,7 +1549,7 @@ int SccbMgr_sense_adapter(PSCCBMGR_INFO 
 	if(pCurrNvRam)
 		pCardInfo->si_id = pCurrNvRam->niAdapId;
 	else
-	   pCardInfo->si_id = (UCHAR)(utilEERead(ioport, (ADAPTER_SCSI_ID/2)) &
+	   pCardInfo->si_id = (UCHAR)(FPT_utilEERead(ioport, (ADAPTER_SCSI_ID/2)) &
    	   (UCHAR)0x0FF);
 
    pCardInfo->si_lun = 0x00;
@@ -2510,7 +1567,7 @@ int SccbMgr_sense_adapter(PSCCBMGR_INFO 
 			temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
 					 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
 		}else
-	      temp = utilEERead(ioport, (USHORT)((SYNC_RATE_TBL/2)+id));
+	      temp = FPT_utilEERead(ioport, (USHORT)((SYNC_RATE_TBL/2)+id));
 
       for (i = 0; i < 2; temp >>=8,i++) {
 
@@ -2549,12 +1606,12 @@ int SccbMgr_sense_adapter(PSCCBMGR_INFO 
 	if(pCurrNvRam)
 		i = pCurrNvRam->niSysConf;
 	else
-	   i = (UCHAR)(utilEERead(ioport, (SYSTEM_CONFIG/2)));
+	   i = (UCHAR)(FPT_utilEERead(ioport, (SYSTEM_CONFIG/2)));
 
 	if(pCurrNvRam)
 		ScamFlg = pCurrNvRam->niScamConf;
 	else
-	   ScamFlg = (UCHAR) utilEERead(ioport, SCAM_CONFIG/2);
+	   ScamFlg = (UCHAR) FPT_utilEERead(ioport, SCAM_CONFIG/2);
 
    pCardInfo->si_flags = 0x0000;
 
@@ -2613,9 +1670,9 @@ int SccbMgr_sense_adapter(PSCCBMGR_INFO 
 				break;
 		}
 	}else{
-	   temp = utilEERead(ioport, (MODEL_NUMB_0/2));
+	   temp = FPT_utilEERead(ioport, (MODEL_NUMB_0/2));
    	pCardInfo->si_card_model[0] = (UCHAR)(temp >> 8);
-	   temp = utilEERead(ioport, (MODEL_NUMB_2/2));
+	   temp = FPT_utilEERead(ioport, (MODEL_NUMB_2/2));
 
    	pCardInfo->si_card_model[1] = (UCHAR)(temp & 0x00FF);
 	   pCardInfo->si_card_model[2] = (UCHAR)(temp >> 8);
@@ -2677,29 +1734,17 @@ int SccbMgr_sense_adapter(PSCCBMGR_INFO 
 
    SGRAM_ACCESS(ioport);
 
-   s_PhaseTbl[0] = phaseDataOut;
-   s_PhaseTbl[1] = phaseDataIn;
-   s_PhaseTbl[2] = phaseIllegal;
-   s_PhaseTbl[3] = phaseIllegal;
-   s_PhaseTbl[4] = phaseCommand;
-   s_PhaseTbl[5] = phaseStatus;
-   s_PhaseTbl[6] = phaseMsgOut;
-   s_PhaseTbl[7] = phaseMsgIn;
+   FPT_s_PhaseTbl[0] = FPT_phaseDataOut;
+   FPT_s_PhaseTbl[1] = FPT_phaseDataIn;
+   FPT_s_PhaseTbl[2] = FPT_phaseIllegal;
+   FPT_s_PhaseTbl[3] = FPT_phaseIllegal;
+   FPT_s_PhaseTbl[4] = FPT_phaseCommand;
+   FPT_s_PhaseTbl[5] = FPT_phaseStatus;
+   FPT_s_PhaseTbl[6] = FPT_phaseMsgOut;
+   FPT_s_PhaseTbl[7] = FPT_phaseMsgIn;
 
    pCardInfo->si_present = 0x01;
 
-#if defined(BUGBUG)
-
-
-   for (i = 0; i < MAX_CARDS; i++) {
-
-      for (id=0; id<debug_size; id++)
-         debug_int[i][id] =  (UCHAR)0x00;
-      debug_index[i] = 0;
-      }
-
-#endif
-
    return(0);
 }
 
@@ -2712,27 +1757,15 @@ int SccbMgr_sense_adapter(PSCCBMGR_INFO 
  *
  *---------------------------------------------------------------------*/
 
-#if defined(DOS)
-USHORT SccbMgr_config_adapter(PSCCBMGR_INFO pCardInfo)
-#else
-ULONG SccbMgr_config_adapter(PSCCBMGR_INFO pCardInfo)
-#endif
+static ULONG SccbMgr_config_adapter(PSCCBMGR_INFO pCardInfo)
 {
    PSCCBcard CurrCard = NULL;
 	PNVRamInfo pCurrNvRam;
    UCHAR i,j,thisCard, ScamFlg;
    USHORT temp,sync_bit_map,id;
-#if defined(DOS)
-   USHORT ioport;
-#else
    ULONG ioport;
-#endif
 
-#if defined(DOS)
-   ioport = (USHORT)pCardInfo->si_baseaddr;
-#else
    ioport = pCardInfo->si_baseaddr;
-#endif
 
    for(thisCard =0; thisCard <= MAX_CARDS; thisCard++) {
 
@@ -2741,24 +1774,24 @@ ULONG SccbMgr_config_adapter(PSCCBMGR_IN
 	 return(FAILURE);
          }
 
-      if (BL_Card[thisCard].ioPort == ioport) {
+      if (FPT_BL_Card[thisCard].ioPort == ioport) {
 
-         CurrCard = &BL_Card[thisCard];
-         SccbMgrTableInitCard(CurrCard,thisCard);
+         CurrCard = &FPT_BL_Card[thisCard];
+         FPT_SccbMgrTableInitCard(CurrCard,thisCard);
          break;
          }
 
-      else if (BL_Card[thisCard].ioPort == 0x00) {
+      else if (FPT_BL_Card[thisCard].ioPort == 0x00) {
 
-         BL_Card[thisCard].ioPort = ioport;
-         CurrCard = &BL_Card[thisCard];
+         FPT_BL_Card[thisCard].ioPort = ioport;
+         CurrCard = &FPT_BL_Card[thisCard];
 
-			if(mbCards)
-				for(i = 0; i < mbCards; i++){
-					if(CurrCard->ioPort == nvRamInfo[i].niBaseAddr)
-						CurrCard->pNvRamInfo = &nvRamInfo[i];
+			if(FPT_mbCards)
+				for(i = 0; i < FPT_mbCards; i++){
+					if(CurrCard->ioPort == FPT_nvRamInfo[i].niBaseAddr)
+						CurrCard->pNvRamInfo = &FPT_nvRamInfo[i];
 				}
-         SccbMgrTableInitCard(CurrCard,thisCard);
+         FPT_SccbMgrTableInitCard(CurrCard,thisCard);
          CurrCard->cardIndex = thisCard;
          CurrCard->cardInfo = pCardInfo;
 
@@ -2772,22 +1805,14 @@ ULONG SccbMgr_config_adapter(PSCCBMGR_IN
 		ScamFlg = pCurrNvRam->niScamConf;
 	}
 	else{
-	   ScamFlg = (UCHAR) utilEERead(ioport, SCAM_CONFIG/2);
+	   ScamFlg = (UCHAR) FPT_utilEERead(ioport, SCAM_CONFIG/2);
 	}
 
 
-   BusMasterInit(ioport);
-   XbowInit(ioport, ScamFlg);
-
-#if defined (NO_BIOS_OPTION)
-
+   FPT_BusMasterInit(ioport);
+   FPT_XbowInit(ioport, ScamFlg);
 
-   if (DiagXbow(ioport)) return(FAILURE);
-   if (DiagBusMaster(ioport)) return(FAILURE);
-
-#endif  /* No BIOS Option */
-
-   autoLoadDefaultMap(ioport);
+   FPT_autoLoadDefaultMap(ioport);
 
 
    for (i = 0,id = 0x01; i != pCardInfo->si_id; i++,id <<= 1){}
@@ -2814,9 +1839,9 @@ ULONG SccbMgr_config_adapter(PSCCBMGR_IN
 
    if (!(pCardInfo->si_flags & SOFT_RESET)) {
 
-      sresb(ioport,thisCard);
+      FPT_sresb(ioport,thisCard);
 
-         scini(thisCard, pCardInfo->si_id, 0);
+         FPT_scini(thisCard, pCardInfo->si_id, 0);
       }
 
 
@@ -2824,1376 +1849,183 @@ ULONG SccbMgr_config_adapter(PSCCBMGR_IN
    if (pCardInfo->si_flags & POST_ALL_UNDERRRUNS)
       CurrCard->globalFlags |= F_NO_FILTER;
 
-	if(pCurrNvRam){
-		if(pCurrNvRam->niSysConf & 0x10)
-			CurrCard->globalFlags |= F_GREEN_PC;
-	}
-	else{
-	   if (utilEERead(ioport, (SYSTEM_CONFIG/2)) & GREEN_PC_ENA)
-   	   CurrCard->globalFlags |= F_GREEN_PC;
-	}
-
-	/* Set global flag to indicate Re-Negotiation to be done on all
-		ckeck condition */
-	if(pCurrNvRam){
-		if(pCurrNvRam->niScsiConf & 0x04)
-			CurrCard->globalFlags |= F_DO_RENEGO;
-	}
-	else{
-	   if (utilEERead(ioport, (SCSI_CONFIG/2)) & RENEGO_ENA)
-   	   CurrCard->globalFlags |= F_DO_RENEGO;
-	}
-
-	if(pCurrNvRam){
-		if(pCurrNvRam->niScsiConf & 0x08)
-			CurrCard->globalFlags |= F_CONLUN_IO;
-	}
-	else{
-	   if (utilEERead(ioport, (SCSI_CONFIG/2)) & CONNIO_ENA)
-   	   CurrCard->globalFlags |= F_CONLUN_IO;
-	}
-
-
-   temp = pCardInfo->si_per_targ_no_disc;
-
-   for (i = 0,id = 1; i < MAX_SCSI_TAR; i++, id <<= 1) {
-
-      if (temp & id)
-	 sccbMgrTbl[thisCard][i].TarStatus |= TAR_ALLOW_DISC;
-      }
-
-   sync_bit_map = 0x0001;
-
-   for (id = 0; id < (MAX_SCSI_TAR/2); id++) {
-
-		if(pCurrNvRam){
-			temp = (USHORT) pCurrNvRam->niSyncTbl[id];
-			temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
-					 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
-		}else
-	      temp = utilEERead(ioport, (USHORT)((SYNC_RATE_TBL/2)+id));
-
-      for (i = 0; i < 2; temp >>=8,i++) {
-
-         if (pCardInfo->si_per_targ_init_sync & sync_bit_map) {
-
-            sccbMgrTbl[thisCard][id*2+i].TarEEValue = (UCHAR)temp;
-            }
-
-         else {
-	    sccbMgrTbl[thisCard][id*2+i].TarStatus |= SYNC_SUPPORTED;
-            sccbMgrTbl[thisCard][id*2+i].TarEEValue =
-               (UCHAR)(temp & ~EE_SYNC_MASK);
-            }
-
-#if defined(WIDE_SCSI)
-/*         if ((pCardInfo->si_per_targ_wide_nego & sync_bit_map) ||
-            (id*2+i >= 8)){
-*/
-         if (pCardInfo->si_per_targ_wide_nego & sync_bit_map){
-
-            sccbMgrTbl[thisCard][id*2+i].TarEEValue |= EE_WIDE_SCSI;
-
-            }
-
-         else { /* NARROW SCSI */
-            sccbMgrTbl[thisCard][id*2+i].TarStatus |= WIDE_NEGOCIATED;
-            }
-
-#else
-         sccbMgrTbl[thisCard][id*2+i].TarStatus |= WIDE_NEGOCIATED;
-#endif
-
-
-	 sync_bit_map <<= 1;
-
-
-
-         }
-      }
-
-   WR_HARPOON((ioport+hp_semaphore),
-      (UCHAR)(RD_HARPOON((ioport+hp_semaphore)) | SCCB_MGR_PRESENT));
-
-#if defined(DOS)
-   return((USHORT)CurrCard);
-#else
-   return((ULONG)CurrCard);
-#endif
-}
-
-#else  			/* end (FW_TYPE==_SCCB_MGR_)  */
-
-
-
-STATIC s16bits FP_PresenceCheck(PMGR_INFO pMgrInfo)
-{
-	PMGR_ENTRYPNTS	pMgr_EntryPnts = &pMgrInfo->mi_Functions;
-
-      pMgr_EntryPnts->UCBMgr_probe_adapter = probe_adapter;
-      pMgr_EntryPnts->UCBMgr_init_adapter = init_adapter;
-      pMgr_EntryPnts->UCBMgr_start_UCB = SccbMgr_start_sccb;
-      pMgr_EntryPnts->UCBMgr_build_UCB = build_UCB;
-      pMgr_EntryPnts->UCBMgr_abort_UCB = SccbMgr_abort_sccb;
-      pMgr_EntryPnts->UCBMgr_my_int = SccbMgr_my_int;
-      pMgr_EntryPnts->UCBMgr_isr = SccbMgr_isr;
-      pMgr_EntryPnts->UCBMgr_scsi_reset = SccbMgr_scsi_reset;
-      pMgr_EntryPnts->UCBMgr_timer_expired = SccbMgr_timer_expired;
-#ifndef NO_IOCTLS
-	  pMgr_EntryPnts->UCBMgr_unload_card = SccbMgr_unload_card;
-	  pMgr_EntryPnts->UCBMgr_save_foreign_state =
-	  									SccbMgr_save_foreign_state;
-	  pMgr_EntryPnts->UCBMgr_restore_foreign_state =
-	  									SccbMgr_restore_foreign_state;
-	  pMgr_EntryPnts->UCBMgr_restore_native_state =
-	  									SccbMgr_restore_native_state;
-#endif /*NO_IOCTLS*/
-
-      pMgrInfo->mi_SGListFormat=0x01;
-      pMgrInfo->mi_DataPtrFormat=0x01;
-      pMgrInfo->mi_MaxSGElements= (u16bits) 0xffffffff;
-      pMgrInfo->mi_MgrPrivateLen=sizeof(SCCB);
-      pMgrInfo->mi_PCIVendorID=BL_VENDOR_ID;
-      pMgrInfo->mi_PCIDeviceID=FP_DEVICE_ID;
-      pMgrInfo->mi_MgrAttributes= ATTR_IO_MAPPED +
-											 ATTR_PHYSICAL_ADDRESS +
-											 ATTR_VIRTUAL_ADDRESS +
-											 ATTR_OVERLAPPED_IO_IOCTLS_OK;
-      pMgrInfo->mi_IoRangeLen = 256;
-      return(0);
-}
-
-
-
-/*---------------------------------------------------------------------
- *
- * Function: probe_adapter
- *
- * Description: Setup and/or Search for cards and return info to caller.
- *
- *---------------------------------------------------------------------*/
-STATIC s32bits probe_adapter(PADAPTER_INFO pAdapterInfo)
-{
-   u16bits temp,temp2,temp3,temp4;
-   u08bits i,j,id;
-
-#if defined(DOS)
-#else
-   static u08bits first_time = 1;
-#endif
-   BASE_PORT ioport;
-	PNVRamInfo pCurrNvRam;
-
-   ioport = (BASE_PORT)pAdapterInfo->ai_baseaddr;
-
-
-
-   if (RD_HARPOON(ioport+hp_vendor_id_0) != ORION_VEND_0)
-      return(1);
-
-   if ((RD_HARPOON(ioport+hp_vendor_id_1) != ORION_VEND_1))
-      return(2);
-
-   if ((RD_HARPOON(ioport+hp_device_id_0) != ORION_DEV_0))
-      return(3);
-
-   if ((RD_HARPOON(ioport+hp_device_id_1) != ORION_DEV_1))
-      return(4);
-
-
-   if (RD_HARPOON(ioport+hp_rev_num) != 0x0f){
-
-
-/* For new Harpoon then check for sub_device ID LSB
-   the bits(0-3) must be all ZERO for compatible with
-   current version of SCCBMgr, else skip this Harpoon
-	device. */
-
-	   if (RD_HARPOON(ioport+hp_sub_device_id_0) & 0x0f)
-	      return(5);
-	}
-
-   if (first_time) {
-
-      SccbMgrTableInitAll();
-      first_time = 0;
-		mbCards = 0;
-      }
-
-	if(RdStack(ioport, 0) != 0x00) {
-		if(ChkIfChipInitialized(ioport) == FALSE)
-		{
-			pCurrNvRam = NULL;
-		   WR_HARPOON(ioport+hp_semaphore, 0x00);
-			XbowInit(ioport, 0);                /*Must Init the SCSI before attempting */
-			DiagEEPROM(ioport);
-		}
-		else
-		{
-			if(mbCards < MAX_MB_CARDS) {
-				pCurrNvRam = &nvRamInfo[mbCards];
-				mbCards++;
-				pCurrNvRam->niBaseAddr = ioport;
-				RNVRamData(pCurrNvRam);
-			}else
-				return((int) FAILURE);
-		}
-	}else
-		pCurrNvRam = NULL;
-
-#if defined (NO_BIOS_OPTION)
-	pCurrNvRam = NULL;
-   XbowInit(ioport, 0);                /*Must Init the SCSI before attempting */
-   DiagEEPROM(ioport);
-#endif  /* No BIOS Option */
-
-   WR_HARPOON(ioport+hp_clkctrl_0, CLKCTRL_DEFAULT);
-   WR_HARPOON(ioport+hp_sys_ctrl, 0x00);
-
-	if(pCurrNvRam)
-		pAdapterInfo->ai_id = pCurrNvRam->niAdapId;
-	else
-   	pAdapterInfo->ai_id = (u08bits)(utilEERead(ioport, (ADAPTER_SCSI_ID/2)) &
-      	(u08bits)0x0FF);
-
-   pAdapterInfo->ai_lun = 0x00;
-   pAdapterInfo->ai_fw_revision[0] = '3';
-   pAdapterInfo->ai_fw_revision[1] = '1';
-   pAdapterInfo->ai_fw_revision[2] = '1';
-   pAdapterInfo->ai_fw_revision[3] = ' ';
-   pAdapterInfo->ai_NumChannels = 1;
-
-   temp2 = 0x0000;
-   temp3 = 0x0000;
-   temp4 = 0x0000;
-
-   for (id = 0; id < (16/2); id++) {
-
-		if(pCurrNvRam){
-			temp = (USHORT) pCurrNvRam->niSyncTbl[id];
-			temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
-					 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
-		}else
-	      temp = utilEERead(ioport, (u16bits)((SYNC_RATE_TBL/2)+id));
-
-      for (i = 0; i < 2; temp >>=8,i++) {
-
-         if ((temp & 0x03) != AUTO_RATE_00) {
-
-            temp2 >>= 0x01;
-            temp2 |= 0x8000;
-            }
-
-         else {
-            temp2 >>= 0x01;
-            }
-
-         if (temp & DISC_ENABLE_BIT) {
-
-            temp3 >>= 0x01;
-            temp3 |= 0x8000;
-            }
-
-         else {
-            temp3 >>= 0x01;
-            }
-
-         if (temp & WIDE_NEGO_BIT) {
-
-            temp4 >>= 0x01;
-            temp4 |= 0x8000;
-            }
-
-         else {
-            temp4 >>= 0x01;
-            }
-
-         }
-      }
-
-   pAdapterInfo->ai_per_targ_init_sync = temp2;
-   pAdapterInfo->ai_per_targ_no_disc = temp3;
-   pAdapterInfo->ai_per_targ_wide_nego = temp4;
-	if(pCurrNvRam)
-		i = pCurrNvRam->niSysConf;
-	else
-   	i = (u08bits)(utilEERead(ioport, (SYSTEM_CONFIG/2)));
-
-   /*
-   ** interrupts always level-triggered for FlashPoint
-   */
-   pAdapterInfo->ai_stateinfo |= LEVEL_TRIG;
-
-   if (i & 0x01)
-      pAdapterInfo->ai_stateinfo |= SCSI_PARITY_ENA;
-
-	if (i & 0x02)	/* SCSI Bus reset in AutoSCSI Set ? */
-	{
-		if(pCurrNvRam)
-		{
-			j = pCurrNvRam->niScamConf;
-		}
-		else
-		{
-		j = (u08bits) utilEERead(ioport, SCAM_CONFIG/2);
-		}
-		if(j & SCAM_ENABLED)
-		{
-			if(j & SCAM_LEVEL2)
-			{
-				pAdapterInfo->ai_stateinfo |= SCAM2_ENA;
-			}
-			else
-			{
-				pAdapterInfo->ai_stateinfo |= SCAM1_ENA;
-			}
-		}
-	}
-   j = (RD_HARPOON(ioport+hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
-   if (i & 0x04) {
-      j |= SCSI_TERM_ENA_L;
-      pAdapterInfo->ai_stateinfo |= LOW_BYTE_TERM_ENA;
-      }
-   WR_HARPOON(ioport+hp_bm_ctrl, j );
-
-   j = (RD_HARPOON(ioport+hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
-   if (i & 0x08) {
-      j |= SCSI_TERM_ENA_H;
-      pAdapterInfo->ai_stateinfo |= HIGH_BYTE_TERM_ENA;
-      }
-   WR_HARPOON(ioport+hp_ee_ctrl, j );
-
-	if(RD_HARPOON(ioport + hp_page_ctrl) & BIOS_SHADOW)
-	{
-		pAdapterInfo->ai_FlashRomSize = 64 * 1024;	/* 64k ROM */
-	}
-	else
-	{
-		pAdapterInfo->ai_FlashRomSize = 32 * 1024;	/* 32k ROM */
-	}
-
-   pAdapterInfo->ai_stateinfo |= (FAST20_ENA | TAG_QUEUE_ENA);
-   if (!(RD_HARPOON(ioport+hp_page_ctrl) & NARROW_SCSI_CARD))
-	{
-      pAdapterInfo->ai_attributes |= (WIDE_CAPABLE | FAST20_CAPABLE
-													| SCAM2_CAPABLE
-													| TAG_QUEUE_CAPABLE
-													| SUPRESS_UNDERRRUNS_CAPABLE
-													| SCSI_PARITY_CAPABLE);
-		pAdapterInfo->ai_MaxTarg = 16;
-		pAdapterInfo->ai_MaxLun  = 32;
-	}
-	else
-	{
-      pAdapterInfo->ai_attributes |= (FAST20_CAPABLE | SCAM2_CAPABLE
-													| TAG_QUEUE_CAPABLE
-													| SUPRESS_UNDERRRUNS_CAPABLE
-													| SCSI_PARITY_CAPABLE);
-		pAdapterInfo->ai_MaxTarg = 8;
-		pAdapterInfo->ai_MaxLun  = 8;
-	}
-
-   pAdapterInfo->ai_product_family = HARPOON_FAMILY;
-   pAdapterInfo->ai_HBAbustype = BUSTYPE_PCI;
-
-   for (i=0;i<CARD_MODEL_NAMELEN;i++)
-   {
-      pAdapterInfo->ai_card_model[i]=' '; /* initialize the ai_card_model */
-   }
-
-	if(pCurrNvRam){
-	pAdapterInfo->ai_card_model[0] = '9';
-		switch(pCurrNvRam->niModel & 0x0f){
-			case MODEL_LT:
-			pAdapterInfo->ai_card_model[1] = '3';
-			pAdapterInfo->ai_card_model[2] = '0';
-				break;
-			case MODEL_LW:
-			pAdapterInfo->ai_card_model[1] = '5';
-			pAdapterInfo->ai_card_model[2] = '0';
-				break;
-			case MODEL_DL:
-			pAdapterInfo->ai_card_model[1] = '3';
-			pAdapterInfo->ai_card_model[2] = '2';
-				break;
-			case MODEL_DW:
-			pAdapterInfo->ai_card_model[1] = '5';
-			pAdapterInfo->ai_card_model[2] = '2';
-				break;
-		}
-	}else{
-	   temp = utilEERead(ioport, (MODEL_NUMB_0/2));
-		pAdapterInfo->ai_card_model[0] = (u08bits)(temp >> 8);
-	   temp = utilEERead(ioport, (MODEL_NUMB_2/2));
-
-		pAdapterInfo->ai_card_model[1] = (u08bits)(temp & 0x00FF);
-	   pAdapterInfo->ai_card_model[2] = (u08bits)(temp >> 8);
-	}
-
-
-
-   pAdapterInfo->ai_FiberProductType = 0;
-
-   pAdapterInfo->ai_secondary_range = 0;
-
-   for (i=0;i<WORLD_WIDE_NAMELEN;i++)
-   {
-      pAdapterInfo->ai_worldwidename[i]='\0';
-   }
-
-   for (i=0;i<VENDOR_NAMELEN;i++)
-   {
-      pAdapterInfo->ai_vendorstring[i]='\0';
-   }
-   	pAdapterInfo->ai_vendorstring[0]='B';
-   	pAdapterInfo->ai_vendorstring[1]='U';
-   	pAdapterInfo->ai_vendorstring[2]='S';
-   	pAdapterInfo->ai_vendorstring[3]='L';
-   	pAdapterInfo->ai_vendorstring[4]='O';
-   	pAdapterInfo->ai_vendorstring[5]='G';
-   	pAdapterInfo->ai_vendorstring[6]='I';
-   	pAdapterInfo->ai_vendorstring[7]='C';
-
-	for (i=0;i<FAMILY_NAMELEN;i++)
-	{
-	   pAdapterInfo->ai_AdapterFamilyString[i]='\0';
-	}
-   	pAdapterInfo->ai_AdapterFamilyString[0]='F';
-   	pAdapterInfo->ai_AdapterFamilyString[1]='L';
-   	pAdapterInfo->ai_AdapterFamilyString[2]='A';
-   	pAdapterInfo->ai_AdapterFamilyString[3]='S';
-   	pAdapterInfo->ai_AdapterFamilyString[4]='H';
-   	pAdapterInfo->ai_AdapterFamilyString[5]='P';
-   	pAdapterInfo->ai_AdapterFamilyString[6]='O';
-   	pAdapterInfo->ai_AdapterFamilyString[7]='I';
-   	pAdapterInfo->ai_AdapterFamilyString[8]='N';
-   	pAdapterInfo->ai_AdapterFamilyString[9]='T';
-
-   ARAM_ACCESS(ioport);
-
-   for ( i = 0; i < 4; i++ ) {
-
-      pAdapterInfo->ai_XlatInfo[i] =
-         RD_HARPOON(ioport+hp_aramBase+BIOS_DATA_OFFSET+i);
-      }
-
-	/* return with -1 if no sort, else return with
-	   logical card number sorted by BIOS (zero-based) */
-
-
-	pAdapterInfo->ai_relative_cardnum = 
-      (u08bits)(RD_HARPOON(ioport+hp_aramBase+BIOS_RELATIVE_CARD)-1); 
-
-   SGRAM_ACCESS(ioport);
-
-   s_PhaseTbl[0] = phaseDataOut;
-   s_PhaseTbl[1] = phaseDataIn;
-   s_PhaseTbl[2] = phaseIllegal;
-   s_PhaseTbl[3] = phaseIllegal;
-   s_PhaseTbl[4] = phaseCommand;
-   s_PhaseTbl[5] = phaseStatus;
-   s_PhaseTbl[6] = phaseMsgOut;
-   s_PhaseTbl[7] = phaseMsgIn;
-
-   pAdapterInfo->ai_present = 0x01;
-
-#if defined(BUGBUG)
-
-
-   for (i = 0; i < MAX_CARDS; i++) {
-
-      for (id=0; id<debug_size; id++)
-         debug_int[i][id] =  (u08bits)0x00;
-      debug_index[i] = 0;
-      }
-
-#endif
-
-   return(0);
-}
-
-
-
-
-
-/*---------------------------------------------------------------------
- *
- * Function: init_adapter, exported to BUDI via UCBMgr_init_adapter entry
- *
- *
- * Description: Setup adapter for normal operation (hard reset).
- *
- *---------------------------------------------------------------------*/
-STATIC CARD_HANDLE init_adapter(PADAPTER_INFO pCardInfo)
-{
-   PSCCBcard CurrCard;
-	PNVRamInfo pCurrNvRam;
-   u08bits i,j,thisCard, ScamFlg;
-   u16bits temp,sync_bit_map,id;
-   BASE_PORT ioport;
-
-   ioport = (BASE_PORT)pCardInfo->ai_baseaddr;
-
-   for(thisCard =0; thisCard <= MAX_CARDS; thisCard++) {
-
-      if (thisCard == MAX_CARDS) {
-
-         return(FAILURE);
-         }
-
-      if (BL_Card[thisCard].ioPort == ioport) {
-
-         CurrCard = &BL_Card[thisCard];
-         SccbMgrTableInitCard(CurrCard,thisCard);
-         break;
-         }
-
-      else if (BL_Card[thisCard].ioPort == 0x00) {
-
-         BL_Card[thisCard].ioPort = ioport;
-         CurrCard = &BL_Card[thisCard];
-
-			if(mbCards)
-				for(i = 0; i < mbCards; i++){
-					if(CurrCard->ioPort == nvRamInfo[i].niBaseAddr)
-						CurrCard->pNvRamInfo = &nvRamInfo[i];
-				}
-         SccbMgrTableInitCard(CurrCard,thisCard);
-         CurrCard->cardIndex = thisCard;
-         CurrCard->cardInfo = pCardInfo;
-
-         break;
-         }
-      }
-
-	pCurrNvRam = CurrCard->pNvRamInfo;
-
-   
-	if(pCurrNvRam){
-		ScamFlg = pCurrNvRam->niScamConf;
-	}
-	else{
-	   ScamFlg = (UCHAR) utilEERead(ioport, SCAM_CONFIG/2);
-	}
-	
-
-   BusMasterInit(ioport);
-   XbowInit(ioport, ScamFlg);
-
-#if defined (NO_BIOS_OPTION)
-
-
-   if (DiagXbow(ioport)) return(FAILURE);
-   if (DiagBusMaster(ioport)) return(FAILURE);
-
-#endif  /* No BIOS Option */
-
-   autoLoadDefaultMap(ioport);
-
-
-   for (i = 0,id = 0x01; i != pCardInfo->ai_id; i++,id <<= 1){}
-
-   WR_HARPOON(ioport+hp_selfid_0, id);
-   WR_HARPOON(ioport+hp_selfid_1, 0x00);
-   WR_HARPOON(ioport+hp_arb_id, pCardInfo->ai_id);
-   CurrCard->ourId = (unsigned char) pCardInfo->ai_id;
-
-   i = (u08bits) pCardInfo->ai_stateinfo;
-   if (i & SCSI_PARITY_ENA)
-       WR_HARPOON(ioport+hp_portctrl_1,(HOST_MODE8 | CHK_SCSI_P));
-
-   j = (RD_HARPOON(ioport+hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
-   if (i & LOW_BYTE_TERM_ENA)
-      j |= SCSI_TERM_ENA_L;
-   WR_HARPOON(ioport+hp_bm_ctrl, j);
-
-   j = (RD_HARPOON(ioport+hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
-   if (i & HIGH_BYTE_TERM_ENA)
-      j |= SCSI_TERM_ENA_H;
-   WR_HARPOON(ioport+hp_ee_ctrl, j );
-
-
-   if (!(pCardInfo->ai_stateinfo & NO_RESET_IN_INIT)) {
-
-      sresb(ioport,thisCard);
-
-         scini(thisCard, (u08bits) pCardInfo->ai_id, 0);
-      }
-
-
-
-   if (pCardInfo->ai_stateinfo & SUPRESS_UNDERRRUNS_ENA)
-      CurrCard->globalFlags |= F_NO_FILTER;
-
-	if(pCurrNvRam){
-		if(pCurrNvRam->niSysConf & 0x10)
-			CurrCard->globalFlags |= F_GREEN_PC;
-	}
-	else{
-	   if (utilEERead(ioport, (SYSTEM_CONFIG/2)) & GREEN_PC_ENA)
-   	   CurrCard->globalFlags |= F_GREEN_PC;
-	}
-
-	/* Set global flag to indicate Re-Negotiation to be done on all
-		ckeck condition */
-	if(pCurrNvRam){
-		if(pCurrNvRam->niScsiConf & 0x04)
-			CurrCard->globalFlags |= F_DO_RENEGO;
-	}
-	else{
-	   if (utilEERead(ioport, (SCSI_CONFIG/2)) & RENEGO_ENA)
-   	   CurrCard->globalFlags |= F_DO_RENEGO;
-	}
-
-	if(pCurrNvRam){
-		if(pCurrNvRam->niScsiConf & 0x08)
-			CurrCard->globalFlags |= F_CONLUN_IO;
-	}
-	else{
-	   if (utilEERead(ioport, (SCSI_CONFIG/2)) & CONNIO_ENA)
-   	   CurrCard->globalFlags |= F_CONLUN_IO;
-	}
-
-   temp = pCardInfo->ai_per_targ_no_disc;
-
-   for (i = 0,id = 1; i < MAX_SCSI_TAR; i++, id <<= 1) {
-
-      if (temp & id)
-         sccbMgrTbl[thisCard][i].TarStatus |= TAR_ALLOW_DISC;
-      }
-
-   sync_bit_map = 0x0001;
-
-   for (id = 0; id < (MAX_SCSI_TAR/2); id++){
-
-		if(pCurrNvRam){
-			temp = (USHORT) pCurrNvRam->niSyncTbl[id];
-			temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
-					 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
-		}else
-	      temp = utilEERead(ioport, (u16bits)((SYNC_RATE_TBL/2)+id));
-
-      for (i = 0; i < 2; temp >>=8,i++){
-
-         if (pCardInfo->ai_per_targ_init_sync & sync_bit_map){
-
-            sccbMgrTbl[thisCard][id*2+i].TarEEValue = (u08bits)temp;
-            }
-
-         else {
-            sccbMgrTbl[thisCard][id*2+i].TarStatus |= SYNC_SUPPORTED;
-            sccbMgrTbl[thisCard][id*2+i].TarEEValue =
-               (u08bits)(temp & ~EE_SYNC_MASK);
-            }
-
-#if defined(WIDE_SCSI)
-/*         if ((pCardInfo->ai_per_targ_wide_nego & sync_bit_map) ||
-            (id*2+i >= 8)){
-*/
-         if (pCardInfo->ai_per_targ_wide_nego & sync_bit_map){
-
-            sccbMgrTbl[thisCard][id*2+i].TarEEValue |= EE_WIDE_SCSI;
-
-            }
-
-         else { /* NARROW SCSI */
-            sccbMgrTbl[thisCard][id*2+i].TarStatus |= WIDE_NEGOCIATED;
-            }
-
-#else
-         sccbMgrTbl[thisCard][id*2+i].TarStatus |= WIDE_NEGOCIATED;
-#endif
-
-
-         sync_bit_map <<= 1;
-         }
-      }
-
-
-   pCardInfo->ai_SGListFormat=0x01;
-   pCardInfo->ai_DataPtrFormat=0x01;
-   pCardInfo->ai_AEN_mask &= SCSI_RESET_COMPLETE;
-
-   WR_HARPOON((ioport+hp_semaphore),
-      (u08bits)(RD_HARPOON((ioport+hp_semaphore)) | SCCB_MGR_PRESENT));
-
-   return((u32bits)CurrCard);
-
-}
-
-
-/*---------------------------------------------------------------------
- *
- * Function: build_ucb, exported to BUDI via UCBMgr_build_ucb entry
- *
- * Description: prepare fw portion of ucb. do not start, resource not guaranteed
- *             so don't manipulate anything that's derived from states which
- *             may change
- *
- *---------------------------------------------------------------------*/
-void build_UCB(CARD_HANDLE pCurrCard, PUCB p_ucb)
-{
-
-   u08bits thisCard;
-   u08bits i,j;
-
-   PSCCB p_sccb;
-
-
-   thisCard = ((PSCCBcard) pCurrCard)->cardIndex;
-
-
-   p_sccb=(PSCCB)p_ucb->UCB_MgrPrivatePtr;
-
-
-   p_sccb->Sccb_ucb_ptr=p_ucb;
-
-   switch (p_ucb->UCB_opcode & (OPC_DEVICE_RESET+OPC_XFER_SG+OPC_CHK_RESIDUAL))
-   {
-      case OPC_DEVICE_RESET:
-         p_sccb->OperationCode=RESET_COMMAND;
-         break;
-      case OPC_XFER_SG:
-         p_sccb->OperationCode=SCATTER_GATHER_COMMAND;
-         break;
-      case OPC_XFER_SG+OPC_CHK_RESIDUAL:
-         p_sccb->OperationCode=RESIDUAL_SG_COMMAND;
-         break;
-      case OPC_CHK_RESIDUAL:
-
-	      p_sccb->OperationCode=RESIDUAL_COMMAND;
-	      break;
-      default:
-	      p_sccb->OperationCode=SCSI_INITIATOR_COMMAND;
-	      break;
-   }
-
-   if (p_ucb->UCB_opcode & OPC_TQ_ENABLE)
-   {
-      p_sccb->ControlByte = (u08bits)((p_ucb->UCB_opcode & OPC_TQ_MASK)>>2) | F_USE_CMD_Q;
-   }
-   else
-   {
-      p_sccb->ControlByte = 0;
-   }
-
-
-   p_sccb->CdbLength = (u08bits)p_ucb->UCB_cdblen;
-
-   if (p_ucb->UCB_opcode & OPC_NO_AUTO_SENSE)
-   {
-      p_sccb->RequestSenseLength = 0;
-   }
-   else
-   {
-      p_sccb->RequestSenseLength = (unsigned char) p_ucb->UCB_senselen;
-   }
-
-
-   if (p_ucb->UCB_opcode & OPC_XFER_SG)
-   {
-      p_sccb->DataPointer=p_ucb->UCB_virt_dataptr;
-      p_sccb->DataLength = (((u32bits)p_ucb->UCB_NumSgElements)<<3);
-   }
-   else
-   {
-      p_sccb->DataPointer=p_ucb->UCB_phys_dataptr;
-      p_sccb->DataLength=p_ucb->UCB_datalen;
-   };
-
-   p_sccb->HostStatus=0;
-   p_sccb->TargetStatus=0;
-   p_sccb->TargID=(unsigned char)p_ucb->UCB_targid;
-   p_sccb->Lun=(unsigned char) p_ucb->UCB_lun;
-   p_sccb->SccbIOPort=((PSCCBcard)pCurrCard)->ioPort;
-
-   j=p_ucb->UCB_cdblen;
-   for (i=0;i<j;i++)
-   {
-      p_sccb->Cdb[i] = p_ucb->UCB_cdb[i];
-   }
-
-   p_sccb->SensePointer=p_ucb->UCB_phys_senseptr;
-
-   sinits(p_sccb,thisCard);
-
-}
-#ifndef NO_IOCTLS
-
-/*---------------------------------------------------------------------
- *
- * Function: GetDevSyncRate
- *
- *---------------------------------------------------------------------*/
-STATIC  int GetDevSyncRate(PSCCBcard pCurrCard,PUCB p_ucb)
-{
-	struct _SYNC_RATE_INFO * pSyncStr;
-   PSCCBMgr_tar_info currTar_Info;
-	BASE_PORT ioport;
-	u08bits scsiID, j;
-
-#if (FW_TYPE != _SCCB_MGR_)
-	if( p_ucb->UCB_targid >= pCurrCard->cardInfo->ai_MaxTarg )
-	{
-		return(1);
-	}
-#endif
-
-	ioport  = pCurrCard->ioPort;
-	pSyncStr	= (struct _SYNC_RATE_INFO *) p_ucb->UCB_virt_dataptr;
-	scsiID = (u08bits) p_ucb->UCB_targid;
-   currTar_Info = &sccbMgrTbl[pCurrCard->cardIndex][scsiID];
-	j = currTar_Info->TarSyncCtrl;
-
-	switch (currTar_Info->TarEEValue & EE_SYNC_MASK)
-	{
-		case EE_SYNC_ASYNC:
-			pSyncStr->RequestMegaXferRate = 0x00;
-			break;
-		case EE_SYNC_5MB:
-			pSyncStr->RequestMegaXferRate = (j & NARROW_SCSI) ? 50 : 100;
-			break;
-		case EE_SYNC_10MB:
-			pSyncStr->RequestMegaXferRate = (j & NARROW_SCSI) ? 100 : 200;
-			break;
-		case EE_SYNC_20MB:
-			pSyncStr->RequestMegaXferRate = (j & NARROW_SCSI) ? 200 : 400;
-			break;
-	}
-
-	switch ((j >> 5) & 0x07)
-	{
-		case 0x00:
-			if((j & 0x07) == 0x00)
-			{
-				pSyncStr->ActualMegaXferRate = 0x00;	/* Async Mode */
-			}
-			else
-			{
-				pSyncStr->ActualMegaXferRate = (j & NARROW_SCSI) ? 200 : 400;
-			}
-			break;
-		case 0x01:
-			pSyncStr->ActualMegaXferRate = (j & NARROW_SCSI) ? 100 : 200;
-			break;
-		case 0x02:
-			pSyncStr->ActualMegaXferRate = (j & NARROW_SCSI) ? 66 : 122;
-			break;
-		case 0x03:
-			pSyncStr->ActualMegaXferRate = (j & NARROW_SCSI) ? 50 : 100;
-			break;
-		case 0x04:
-			pSyncStr->ActualMegaXferRate = (j & NARROW_SCSI) ? 40 : 80;
-			break;
-		case 0x05:
-			pSyncStr->ActualMegaXferRate = (j & NARROW_SCSI) ? 33 : 66;
-			break;
-		case 0x06:
-			pSyncStr->ActualMegaXferRate = (j & NARROW_SCSI) ? 28 : 56;
-			break;
-		case 0x07:
-			pSyncStr->ActualMegaXferRate = (j & NARROW_SCSI) ? 25 : 50;
-			break;
-	}
-	pSyncStr->NegotiatedOffset = j & 0x0f;
-
-	return(0);
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: SetDevSyncRate
- *
- *---------------------------------------------------------------------*/
-STATIC int SetDevSyncRate(PSCCBcard pCurrCard, PUCB p_ucb)
-{
-	struct _SYNC_RATE_INFO * pSyncStr;
-   PSCCBMgr_tar_info currTar_Info;
-	BASE_PORT ioPort;
-	u08bits scsiID, i, j, syncVal;
-	u16bits syncOffset, actualXferRate;
-	union {
-		u08bits tempb[2];
-		u16bits tempw;
-	}temp2;
-
-#if (FW_TYPE != _SCCB_MGR_)
-	if( p_ucb->UCB_targid >= pCurrCard->cardInfo->ai_MaxTarg )
-	{
-		return(1);
-	}
-#endif
-
-	ioPort  = pCurrCard->ioPort;
-	pSyncStr	= (struct _SYNC_RATE_INFO *) p_ucb->UCB_virt_dataptr;
-	scsiID = (u08bits) p_ucb->UCB_targid;
-   currTar_Info = &sccbMgrTbl[pCurrCard->cardIndex][scsiID];
-	i = RD_HARPOON(ioPort+hp_xfer_pad);		/* Save current value */
-	WR_HARPOON(ioPort+hp_xfer_pad, (i | ID_UNLOCK));
-	WR_HARPOON(ioPort+hp_select_id, ((scsiID << 4) | scsiID));
-	j = RD_HARPOON(ioPort+hp_synctarg_0);
-	WR_HARPOON(ioPort+hp_xfer_pad, i);		/* restore value */
-
-	actualXferRate = pSyncStr->ActualMegaXferRate;
-	if(!(j & NARROW_SCSI))
-	{
-		actualXferRate <<= 1;
-	}
-	if(actualXferRate == 0x00)
-	{
-		syncVal = EE_SYNC_ASYNC;			/* Async Mode */
-	}
-	if(actualXferRate == 0x0200)
-	{
-		syncVal = EE_SYNC_20MB;				/* 20/40 MB Mode */
-	}
-	if(actualXferRate > 0x0050 && actualXferRate < 0x0200 )
-	{
-		syncVal = EE_SYNC_10MB;				/* 10/20 MB Mode */
-	}
-	else
-	{
-		syncVal = EE_SYNC_5MB;				/* 5/10 MB Mode */
-	}
-	if(currTar_Info->TarEEValue && EE_SYNC_MASK == syncVal)
-		return(0);
-	currTar_Info->TarEEValue = (currTar_Info->TarEEValue & !EE_SYNC_MASK)
-											| syncVal;
-	syncOffset = (SYNC_RATE_TBL + scsiID) / 2;
-	temp2.tempw = utilEERead(ioPort, syncOffset);
-	if(scsiID & 0x01)
-	{
-		temp2.tempb[0] = (temp2.tempb[0] & !EE_SYNC_MASK) | syncVal;
-	}
-	else
-	{
-		temp2.tempb[1] = (temp2.tempb[1] & !EE_SYNC_MASK) | syncVal;
-	}
-	utilEEWriteOnOff(ioPort, 1);
-	utilEEWrite(ioPort, temp2.tempw, syncOffset);
-	utilEEWriteOnOff(ioPort, 0);
-	UpdateCheckSum(ioPort);
-
-	return(0);
-}
-/*---------------------------------------------------------------------
- *
- * Function: GetDevWideMode
- *
- *---------------------------------------------------------------------*/
-int GetDevWideMode(PSCCBcard pCurrCard,PUCB p_ucb)
-{
-	u08bits *pData;
-
-	pData = (u08bits *)p_ucb->UCB_virt_dataptr;
-	if(sccbMgrTbl[pCurrCard->cardIndex][p_ucb->UCB_targid].TarEEValue
-				& EE_WIDE_SCSI)
-	{
-		*pData = 1;
-	}
-	else
-	{
-		*pData = 0;
-	}
-
-	return(0);
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: SetDevWideMode
- *
- *---------------------------------------------------------------------*/
-int SetDevWideMode(PSCCBcard pCurrCard,PUCB p_ucb)
-{
-	u08bits *pData;
-   PSCCBMgr_tar_info currTar_Info;
-	BASE_PORT ioPort;
-	u08bits scsiID, scsiWideMode;
-	u16bits syncOffset;
-	union {
-		u08bits tempb[2];
-		u16bits tempw;
-	}temp2;
-
-#if (FW_TYPE != _SCCB_MGR_)
-	if( !(pCurrCard->cardInfo->ai_attributes & WIDE_CAPABLE) )
-	{
-		return(1);
-	}
-
-	if( p_ucb->UCB_targid >= pCurrCard->cardInfo->ai_MaxTarg )
-	{
-		return(1);
-	}
-#endif
-
-	ioPort  = pCurrCard->ioPort;
-	pData = (u08bits *)p_ucb->UCB_virt_dataptr;
-	scsiID = (u08bits) p_ucb->UCB_targid;
-	currTar_Info = &sccbMgrTbl[pCurrCard->cardIndex][scsiID];
-
-	if(*pData)
-	{
-		if(currTar_Info->TarEEValue & EE_WIDE_SCSI)
-		{
-			return(0);
-		}
-		else
-		{
-			scsiWideMode = EE_WIDE_SCSI;
-		}
-	}
-	else
-	{
-		if(!(currTar_Info->TarEEValue & EE_WIDE_SCSI))
-		{
-			return(0);
-		}
-		else
-		{
-			scsiWideMode = 0;
-		}
-	}
-	currTar_Info->TarEEValue = (currTar_Info->TarEEValue & !EE_WIDE_SCSI)
-											| scsiWideMode;
-
-	syncOffset = (SYNC_RATE_TBL + scsiID) / 2;
-	temp2.tempw = utilEERead(ioPort, syncOffset);
-	if(scsiID & 0x01)
-	{
-		temp2.tempb[0] = (temp2.tempb[0] & !EE_WIDE_SCSI) | scsiWideMode;
-	}
-	else
-	{
-		temp2.tempb[1] = (temp2.tempb[1] & !EE_WIDE_SCSI) | scsiWideMode;
-	}
-	utilEEWriteOnOff(ioPort, 1);
-	utilEEWrite(ioPort, temp2.tempw, syncOffset);
-	utilEEWriteOnOff(ioPort, 0);
-	UpdateCheckSum(ioPort);
-
-	return(0);
-}
-
-/*---------------------------------------------------------------------
- *
- * Function: ReadNVRam
- *
- *---------------------------------------------------------------------*/
-void ReadNVRam(PSCCBcard pCurrCard,PUCB p_ucb)
-{
-	u08bits *pdata;
-	u16bits i,numwrds,numbytes,offset,temp;
-	u08bits OneMore = FALSE;
-#if defined(DOS)
-	u16bits ioport;
-#else
-	u32bits ioport;
-#endif
-
-	numbytes = (u16bits) p_ucb->UCB_datalen;
-	ioport  = pCurrCard->ioPort;
-   pdata   = (u08bits *) p_ucb->UCB_virt_dataptr;
-	offset  = (u16bits) (p_ucb->UCB_IOCTLParams[0]);
-
-
-
-   if (offset & 0x1)
-	{
-	    *((u16bits*) pdata) = utilEERead(ioport,(u16bits)((offset - 1) / 2)); /* 16 bit read */
-		 *pdata = *(pdata + 1);
-		 ++offset;
-   	 ++pdata;
-		 --numbytes;
-	}
-
-	numwrds = numbytes / 2;
-	if (numbytes & 1)
-	 	OneMore = TRUE;
-
-	for (i = 0; i < numwrds; i++)
-	{
-   	*((u16bits*) pdata) = utilEERead(ioport,(u16bits)(offset / 2));
-		pdata += 2;
-		offset += 2;
-   }
-	if (OneMore)
-	{
-		--pdata;
-		-- offset;
-   	temp = utilEERead(ioport,(u16bits)(offset / 2));
-		*pdata = (u08bits) (temp);
-	}
-
-} /* end proc ReadNVRam */
-
-
-/*---------------------------------------------------------------------
- *
- * Function: WriteNVRam
- *
- *---------------------------------------------------------------------*/
-void WriteNVRam(PSCCBcard pCurrCard,PUCB p_ucb)
-{
-	u08bits *pdata;
-	u16bits i,numwrds,numbytes,offset, eeprom_end;
-	u08bits OneMore = FALSE;
-	union {
-		u08bits  tempb[2];
-		u16bits  tempw;
-	} temp2;
-
-#if defined(DOS)
-	u16bits ioport;
-#else
-	u32bits ioport;
-#endif
-
-	numbytes = (u16bits) p_ucb->UCB_datalen;
-	ioport  = pCurrCard->ioPort;
-   pdata   = (u08bits *) p_ucb->UCB_virt_dataptr;
-	offset  = (u16bits) (p_ucb->UCB_IOCTLParams[0]);
-
-   if (RD_HARPOON(ioport+hp_page_ctrl) & NARROW_SCSI_CARD)
-      eeprom_end = 512;
-   else
-      eeprom_end = 768;
-	
-	if(offset > eeprom_end)
-		return;
-
-	if((offset + numbytes) > eeprom_end)
-		numbytes = eeprom_end - offset;
-
-    utilEEWriteOnOff(ioport,1);   /* Enable write access to the EEPROM */
-
+	if(pCurrNvRam){
+		if(pCurrNvRam->niSysConf & 0x10)
+			CurrCard->globalFlags |= F_GREEN_PC;
+	}
+	else{
+	   if (FPT_utilEERead(ioport, (SYSTEM_CONFIG/2)) & GREEN_PC_ENA)
+   	   CurrCard->globalFlags |= F_GREEN_PC;
+	}
 
+	/* Set global flag to indicate Re-Negotiation to be done on all
+		ckeck condition */
+	if(pCurrNvRam){
+		if(pCurrNvRam->niScsiConf & 0x04)
+			CurrCard->globalFlags |= F_DO_RENEGO;
+	}
+	else{
+	   if (FPT_utilEERead(ioport, (SCSI_CONFIG/2)) & RENEGO_ENA)
+   	   CurrCard->globalFlags |= F_DO_RENEGO;
+	}
 
-   if (offset & 0x1)
-	{
-	    temp2.tempw = utilEERead(ioport,(u16bits)((offset - 1) / 2)); /* 16 bit read */
-		 temp2.tempb[1] = *pdata;
-	    utilEEWrite(ioport, temp2.tempw, (u16bits)((offset -1) / 2));
-		 *pdata = *(pdata + 1);
-		 ++offset;
-   	 ++pdata;
-		 --numbytes;
+	if(pCurrNvRam){
+		if(pCurrNvRam->niScsiConf & 0x08)
+			CurrCard->globalFlags |= F_CONLUN_IO;
+	}
+	else{
+	   if (FPT_utilEERead(ioport, (SCSI_CONFIG/2)) & CONNIO_ENA)
+   	   CurrCard->globalFlags |= F_CONLUN_IO;
 	}
 
-	numwrds = numbytes / 2;
-	if (numbytes & 1)
-	 	OneMore = TRUE;
 
-	for (i = 0; i < numwrds; i++)
-	{
-   	utilEEWrite(ioport, *((pu16bits)pdata),(u16bits)(offset / 2));
-		pdata += 2;
-		offset += 2;
-   }
-	if (OneMore)
-	{
+   temp = pCardInfo->si_per_targ_no_disc;
 
-   	temp2.tempw = utilEERead(ioport,(u16bits)(offset / 2));
-		temp2.tempb[0] = *pdata;
-   	utilEEWrite(ioport, temp2.tempw, (u16bits)(offset / 2));
-	}
-   utilEEWriteOnOff(ioport,0);   /* Turn off write access */
-   UpdateCheckSum((u32bits)ioport);
+   for (i = 0,id = 1; i < MAX_SCSI_TAR; i++, id <<= 1) {
+
+      if (temp & id)
+	 FPT_sccbMgrTbl[thisCard][i].TarStatus |= TAR_ALLOW_DISC;
+      }
 
-} /* end proc WriteNVRam */
+   sync_bit_map = 0x0001;
 
+   for (id = 0; id < (MAX_SCSI_TAR/2); id++) {
 
+		if(pCurrNvRam){
+			temp = (USHORT) pCurrNvRam->niSyncTbl[id];
+			temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
+					 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
+		}else
+	      temp = FPT_utilEERead(ioport, (USHORT)((SYNC_RATE_TBL/2)+id));
 
-/*---------------------------------------------------------------------
- *
- * Function: UpdateCheckSum
- *
- * Description: Update Check Sum in EEPROM
- *
- *---------------------------------------------------------------------*/
+      for (i = 0; i < 2; temp >>=8,i++) {
 
+         if (pCardInfo->si_per_targ_init_sync & sync_bit_map) {
 
-void UpdateCheckSum(u32bits baseport)
-{
-	USHORT i,sum_data, eeprom_end;
+            FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue = (UCHAR)temp;
+            }
 
-	sum_data = 0x0000;
+         else {
+	    FPT_sccbMgrTbl[thisCard][id*2+i].TarStatus |= SYNC_SUPPORTED;
+            FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue =
+               (UCHAR)(temp & ~EE_SYNC_MASK);
+            }
 
+/*         if ((pCardInfo->si_per_targ_wide_nego & sync_bit_map) ||
+            (id*2+i >= 8)){
+*/
+         if (pCardInfo->si_per_targ_wide_nego & sync_bit_map){
 
-   if (RD_HARPOON(baseport+hp_page_ctrl) & NARROW_SCSI_CARD)
-      eeprom_end = 512;
-   else
-      eeprom_end = 768;
+            FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue |= EE_WIDE_SCSI;
 
-	for (i = 1; i < eeprom_end/2; i++)
-	{
-		sum_data += utilEERead(baseport, i);
-	}
+            }
 
-   utilEEWriteOnOff(baseport,1);   /* Enable write access to the EEPROM */
+         else { /* NARROW SCSI */
+            FPT_sccbMgrTbl[thisCard][id*2+i].TarStatus |= WIDE_NEGOCIATED;
+            }
 
-   utilEEWrite(baseport, sum_data, EEPROM_CHECK_SUM/2);
-   utilEEWriteOnOff(baseport,0);   /* Turn off write access */
-}
 
-void SccbMgr_save_foreign_state(PADAPTER_INFO pAdapterInfo)
-{
-}
+	 sync_bit_map <<= 1;
 
 
-void SccbMgr_restore_foreign_state(CARD_HANDLE pCurrCard)
-{
-}
 
-void SccbMgr_restore_native_state(CARD_HANDLE pCurrCard)
-{
-}
+         }
+      }
 
-#endif /* NO_IOCTLS */
+   WR_HARPOON((ioport+hp_semaphore),
+      (UCHAR)(RD_HARPOON((ioport+hp_semaphore)) | SCCB_MGR_PRESENT));
 
-#endif /* (FW_TYPE==_UCB_MGR_)   */
+   return((ULONG)CurrCard);
+}
 
-#ifndef NO_IOCTLS
-#if (FW_TYPE==_UCB_MGR_)
-void SccbMgr_unload_card(CARD_HANDLE pCurrCard)
-#else
-#if defined(DOS)
-void SccbMgr_unload_card(USHORT pCurrCard)
-#else
-void SccbMgr_unload_card(ULONG pCurrCard)
-#endif
-#endif
+static void SccbMgr_unload_card(ULONG pCurrCard)
 {
 	UCHAR i;
-#if defined(DOS)
-	USHORT portBase;
-	USHORT regOffset;
-#else
 	ULONG portBase;
 	ULONG regOffset;
-#endif
 	ULONG scamData;
-#if defined(OS2)
-	ULONG far *pScamTbl;
-#else
 	ULONG *pScamTbl;
-#endif
 	PNVRamInfo pCurrNvRam;
 
 	pCurrNvRam = ((PSCCBcard)pCurrCard)->pNvRamInfo;
 
 	if(pCurrNvRam){
-		WrStack(pCurrNvRam->niBaseAddr, 0, pCurrNvRam->niModel);
-		WrStack(pCurrNvRam->niBaseAddr, 1, pCurrNvRam->niSysConf);
-		WrStack(pCurrNvRam->niBaseAddr, 2, pCurrNvRam->niScsiConf);
-		WrStack(pCurrNvRam->niBaseAddr, 3, pCurrNvRam->niScamConf);
-		WrStack(pCurrNvRam->niBaseAddr, 4, pCurrNvRam->niAdapId);
+		FPT_WrStack(pCurrNvRam->niBaseAddr, 0, pCurrNvRam->niModel);
+		FPT_WrStack(pCurrNvRam->niBaseAddr, 1, pCurrNvRam->niSysConf);
+		FPT_WrStack(pCurrNvRam->niBaseAddr, 2, pCurrNvRam->niScsiConf);
+		FPT_WrStack(pCurrNvRam->niBaseAddr, 3, pCurrNvRam->niScamConf);
+		FPT_WrStack(pCurrNvRam->niBaseAddr, 4, pCurrNvRam->niAdapId);
 
 		for(i = 0; i < MAX_SCSI_TAR / 2; i++)
-			WrStack(pCurrNvRam->niBaseAddr, (UCHAR)(i+5), pCurrNvRam->niSyncTbl[i]);
+			FPT_WrStack(pCurrNvRam->niBaseAddr, (UCHAR)(i+5), pCurrNvRam->niSyncTbl[i]);
 
 		portBase = pCurrNvRam->niBaseAddr;
 
 		for(i = 0; i < MAX_SCSI_TAR; i++){
 			regOffset = hp_aramBase + 64 + i*4;
-#if defined(OS2)
-			pScamTbl = (ULONG far *) &pCurrNvRam->niScamTbl[i];
-#else
 			pScamTbl = (ULONG *) &pCurrNvRam->niScamTbl[i];
-#endif
 			scamData = *pScamTbl;
 			WR_HARP32(portBase, regOffset, scamData);
 		}
 
 	}else{
-		WrStack(((PSCCBcard)pCurrCard)->ioPort, 0, 0);
+		FPT_WrStack(((PSCCBcard)pCurrCard)->ioPort, 0, 0);
 	}
 }
-#endif /* NO_IOCTLS */
 
 
-void RNVRamData(PNVRamInfo pNvRamInfo)
+static void FPT_RNVRamData(PNVRamInfo pNvRamInfo)
 {
 	UCHAR i;
-#if defined(DOS)
-	USHORT portBase;
-	USHORT regOffset;
-#else
 	ULONG portBase;
 	ULONG regOffset;
-#endif
 	ULONG scamData;
-#if defined (OS2)
-	ULONG far *pScamTbl;
-#else
 	ULONG *pScamTbl;
-#endif
 
-	pNvRamInfo->niModel    = RdStack(pNvRamInfo->niBaseAddr, 0);
-	pNvRamInfo->niSysConf  = RdStack(pNvRamInfo->niBaseAddr, 1);
-	pNvRamInfo->niScsiConf = RdStack(pNvRamInfo->niBaseAddr, 2);
-	pNvRamInfo->niScamConf = RdStack(pNvRamInfo->niBaseAddr, 3);
-	pNvRamInfo->niAdapId   = RdStack(pNvRamInfo->niBaseAddr, 4);
+	pNvRamInfo->niModel    = FPT_RdStack(pNvRamInfo->niBaseAddr, 0);
+	pNvRamInfo->niSysConf  = FPT_RdStack(pNvRamInfo->niBaseAddr, 1);
+	pNvRamInfo->niScsiConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 2);
+	pNvRamInfo->niScamConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 3);
+	pNvRamInfo->niAdapId   = FPT_RdStack(pNvRamInfo->niBaseAddr, 4);
 
 	for(i = 0; i < MAX_SCSI_TAR / 2; i++)
-		pNvRamInfo->niSyncTbl[i] = RdStack(pNvRamInfo->niBaseAddr, (UCHAR)(i+5));
+		pNvRamInfo->niSyncTbl[i] = FPT_RdStack(pNvRamInfo->niBaseAddr, (UCHAR)(i+5));
 
 	portBase = pNvRamInfo->niBaseAddr;
 
 	for(i = 0; i < MAX_SCSI_TAR; i++){
 		regOffset = hp_aramBase + 64 + i*4;
 		RD_HARP32(portBase, regOffset, scamData);
-#if defined(OS2)
-		pScamTbl = (ULONG far *) &pNvRamInfo->niScamTbl[i];
-#else
 		pScamTbl = (ULONG *) &pNvRamInfo->niScamTbl[i];
-#endif
 		*pScamTbl = scamData;
 	}
 
 }
 
-#if defined(DOS)
-UCHAR RdStack(USHORT portBase, UCHAR index)
-#else
-UCHAR RdStack(ULONG portBase, UCHAR index)
-#endif
+static UCHAR FPT_RdStack(ULONG portBase, UCHAR index)
 {
 	WR_HARPOON(portBase + hp_stack_addr, index);
 	return(RD_HARPOON(portBase + hp_stack_data));
 }
 
-#if defined(DOS)
-void WrStack(USHORT portBase, UCHAR index, UCHAR data)
-#else
-void WrStack(ULONG portBase, UCHAR index, UCHAR data)
-#endif
+static void FPT_WrStack(ULONG portBase, UCHAR index, UCHAR data)
 {
 	WR_HARPOON(portBase + hp_stack_addr, index);
 	WR_HARPOON(portBase + hp_stack_data, data);
 }
 
 
-#if (FW_TYPE==_UCB_MGR_)
-u08bits ChkIfChipInitialized(BASE_PORT ioPort)
-#else
-#if defined(DOS)
-UCHAR ChkIfChipInitialized(USHORT ioPort)
-#else
-UCHAR ChkIfChipInitialized(ULONG ioPort)
-#endif
-#endif
+static UCHAR FPT_ChkIfChipInitialized(ULONG ioPort)
 {
-	if((RD_HARPOON(ioPort + hp_arb_id) & 0x0f) != RdStack(ioPort, 4))
-		return(FALSE);
+	if((RD_HARPOON(ioPort + hp_arb_id) & 0x0f) != FPT_RdStack(ioPort, 4))
+		return(0);
 	if((RD_HARPOON(ioPort + hp_clkctrl_0) & CLKCTRL_DEFAULT)
 								!= CLKCTRL_DEFAULT)
-		return(FALSE);
+		return(0);
 	if((RD_HARPOON(ioPort + hp_seltimeout) == TO_250ms) ||
 		(RD_HARPOON(ioPort + hp_seltimeout) == TO_290ms))
-		return(TRUE);
-	return(FALSE);
+		return(1);
+	return(0);
 
 }
 /*---------------------------------------------------------------------
@@ -4205,185 +2037,29 @@ UCHAR ChkIfChipInitialized(ULONG ioPort)
  *              callback function.
  *
  *---------------------------------------------------------------------*/
-#if (FW_TYPE==_UCB_MGR_)
-void SccbMgr_start_sccb(CARD_HANDLE pCurrCard, PUCB p_ucb)
-#else
-#if defined(DOS)
-void SccbMgr_start_sccb(USHORT pCurrCard, PSCCB p_Sccb)
-#else
-void SccbMgr_start_sccb(ULONG pCurrCard, PSCCB p_Sccb)
-#endif
-#endif
+static void SccbMgr_start_sccb(ULONG pCurrCard, PSCCB p_Sccb)
 {
-#if defined(DOS)
-   USHORT ioport;
-#else
    ULONG ioport;
-#endif
    UCHAR thisCard, lun;
 	PSCCB pSaveSccb;
    CALL_BK_FN callback;
 
-#if (FW_TYPE==_UCB_MGR_)
-   PSCCB p_Sccb;
-#endif
-
-   mOS_Lock((PSCCBcard)pCurrCard);
    thisCard = ((PSCCBcard) pCurrCard)->cardIndex;
    ioport = ((PSCCBcard) pCurrCard)->ioPort;
 
-#if (FW_TYPE==_UCB_MGR_)
-   p_Sccb = (PSCCB)p_ucb->UCB_MgrPrivatePtr;
-#endif
-
 	if((p_Sccb->TargID > MAX_SCSI_TAR) || (p_Sccb->Lun > MAX_LUN))
 	{
 
-#if (FW_TYPE==_UCB_MGR_)
-		p_ucb->UCB_hbastat = SCCB_COMPLETE;
-		p_ucb->UCB_status=SCCB_ERROR;
-		callback = (CALL_BK_FN)p_ucb->UCB_callback;
-		if (callback)
-			callback(p_ucb);
-#endif
-
-#if (FW_TYPE==_SCCB_MGR_)
 		p_Sccb->HostStatus = SCCB_COMPLETE;
 		p_Sccb->SccbStatus = SCCB_ERROR;
 		callback = (CALL_BK_FN)p_Sccb->SccbCallback;
 		if (callback)
 			callback(p_Sccb);
-#endif
 
-		mOS_UnLock((PSCCBcard)pCurrCard);
 		return;
 	}
 
-#if (FW_TYPE==_SCCB_MGR_)
-   sinits(p_Sccb,thisCard);
-#endif
-
-
-#if (FW_TYPE==_UCB_MGR_)
-#ifndef NO_IOCTLS
-
-   if (p_ucb->UCB_opcode & OPC_IOCTL)
-	{
-
-		switch (p_ucb->UCB_IOCTLCommand) 
-		{
-			case READ_NVRAM:
-				ReadNVRam((PSCCBcard)pCurrCard,p_ucb);
-				p_ucb->UCB_status=UCB_SUCCESS;
-				callback = (CALL_BK_FN)p_ucb->UCB_callback;
-				if (callback)
-					callback(p_ucb);
-				mOS_UnLock((PSCCBcard)pCurrCard);
-				return;
-
-			case WRITE_NVRAM:
-				WriteNVRam((PSCCBcard)pCurrCard,p_ucb);
-				p_ucb->UCB_status=UCB_SUCCESS;
-				callback = (CALL_BK_FN)p_ucb->UCB_callback;
-				if (callback)
-					callback(p_ucb);
-				mOS_UnLock((PSCCBcard)pCurrCard);
-				return;
-
-			case SEND_SCSI_PASSTHRU:
-#if (FW_TYPE != _SCCB_MGR_)
-				if( p_ucb->UCB_targid >=
-				    ((PSCCBcard)pCurrCard)->cardInfo->ai_MaxTarg )
-				{
-					p_ucb->UCB_status = UCB_ERROR;
-					p_ucb->UCB_hbastat = HASTAT_HW_ERROR;
-					callback = (CALL_BK_FN)p_ucb->UCB_callback;
-					if (callback)
-						callback(p_ucb);
-					mOS_UnLock((PSCCBcard)pCurrCard);
-					return;
-				}
-#endif
-				break;
-
-			case HARD_RESET:
-				p_ucb->UCB_status = UCB_INVALID;
-				callback = (CALL_BK_FN)p_ucb->UCB_callback;
-				if (callback)
-					callback(p_ucb);
-				mOS_UnLock((PSCCBcard)pCurrCard);
-				return;
-			case GET_DEVICE_SYNCRATE:
-				if( !GetDevSyncRate((PSCCBcard)pCurrCard,p_ucb) )
-				{
-					p_ucb->UCB_status = UCB_SUCCESS;
-				}
-				else
-				{
-					p_ucb->UCB_status = UCB_ERROR;
-					p_ucb->UCB_hbastat = HASTAT_HW_ERROR;
-				}
-				callback = (CALL_BK_FN)p_ucb->UCB_callback;
-				if (callback)
-					callback(p_ucb);
-				mOS_UnLock((PSCCBcard)pCurrCard);
-				return;
-			case SET_DEVICE_SYNCRATE:
-				if( !SetDevSyncRate((PSCCBcard)pCurrCard,p_ucb) )
-				{
-					p_ucb->UCB_status = UCB_SUCCESS;
-				}
-				else
-				{
-					p_ucb->UCB_status = UCB_ERROR;
-					p_ucb->UCB_hbastat = HASTAT_HW_ERROR;
-				}
-				callback = (CALL_BK_FN)p_ucb->UCB_callback;
-				if (callback)
-					callback(p_ucb);
-				mOS_UnLock((PSCCBcard)pCurrCard);
-				return;
-			case GET_WIDE_MODE:
-				if( !GetDevWideMode((PSCCBcard)pCurrCard,p_ucb) )
-				{
-					p_ucb->UCB_status = UCB_SUCCESS;
-				}
-				else
-				{
-					p_ucb->UCB_status = UCB_ERROR;
-					p_ucb->UCB_hbastat = HASTAT_HW_ERROR;
-				}
-				callback = (CALL_BK_FN)p_ucb->UCB_callback;
-				if (callback)
-					callback(p_ucb);
-				mOS_UnLock((PSCCBcard)pCurrCard);
-				return;
-			case SET_WIDE_MODE:
-				if( !SetDevWideMode((PSCCBcard)pCurrCard,p_ucb) )
-				{
-					p_ucb->UCB_status = UCB_SUCCESS;
-				}
-				else
-				{
-					p_ucb->UCB_status = UCB_ERROR;
-					p_ucb->UCB_hbastat = HASTAT_HW_ERROR;
-				}
-				callback = (CALL_BK_FN)p_ucb->UCB_callback;
-				if (callback)
-					callback(p_ucb);
-				mOS_UnLock((PSCCBcard)pCurrCard);
-				return;
-			default:
-				p_ucb->UCB_status=UCB_INVALID;
-				callback = (CALL_BK_FN)p_ucb->UCB_callback;
-				if (callback)
-					callback(p_ucb);
-				mOS_UnLock((PSCCBcard)pCurrCard);
-				return;
-		}
-	}
-#endif /* NO_IOCTLS */
-#endif /* (FW_TYPE==_UCB_MGR_) */
+   FPT_sinits(p_Sccb,thisCard);
 
 
    if (!((PSCCBcard) pCurrCard)->cmdCounter)
@@ -4408,12 +2084,12 @@ void SccbMgr_start_sccb(ULONG pCurrCard,
 			{
 				pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
 				((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
-				queueSelectFail(&BL_Card[thisCard], thisCard);
+				FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
 				((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
 			}
 		else
 			{
-	      queueAddSccb(p_Sccb,thisCard);
+	      FPT_queueAddSccb(p_Sccb,thisCard);
 			}
       }
 
@@ -4423,12 +2099,12 @@ void SccbMgr_start_sccb(ULONG pCurrCard,
 				{
 					pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
 					((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
-					queueSelectFail(&BL_Card[thisCard], thisCard);
+					FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
 					((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
 				}
 			else
 				{
-		      queueAddSccb(p_Sccb,thisCard);
+		      FPT_queueAddSccb(p_Sccb,thisCard);
 				}
       }
 
@@ -4437,23 +2113,17 @@ void SccbMgr_start_sccb(ULONG pCurrCard,
       MDISABLE_INT(ioport);
 
 		if((((PSCCBcard) pCurrCard)->globalFlags & F_CONLUN_IO) && 
-			((sccbMgrTbl[thisCard][p_Sccb->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
+			((FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
 			lun = p_Sccb->Lun;
 		else
 			lun = 0;
       if ((((PSCCBcard) pCurrCard)->currentSCCB == NULL) &&
-         (sccbMgrTbl[thisCard][p_Sccb->TargID].TarSelQ_Cnt == 0) &&
-         (sccbMgrTbl[thisCard][p_Sccb->TargID].TarLUNBusy[lun]
-         == FALSE)) {
+         (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarSelQ_Cnt == 0) &&
+         (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarLUNBusy[lun]
+         == 0)) {
 
             ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
-			   mOS_UnLock((PSCCBcard)pCurrCard);
-#if defined(DOS)
-            ssel((USHORT)p_Sccb->SccbIOPort,thisCard);
-#else
-	    ssel(p_Sccb->SccbIOPort,thisCard);
-#endif
-			   mOS_Lock((PSCCBcard)pCurrCard);
+	    FPT_ssel(p_Sccb->SccbIOPort,thisCard);
          }
 
       else {
@@ -4462,12 +2132,12 @@ void SccbMgr_start_sccb(ULONG pCurrCard,
 				{
 					pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
 					((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
-					queueSelectFail(&BL_Card[thisCard], thisCard);
+					FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
 					((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
 				}
 			else
 				{
-	         	queueAddSccb(p_Sccb,thisCard);
+	         	FPT_queueAddSccb(p_Sccb,thisCard);
 				}
          }
 
@@ -4475,7 +2145,6 @@ void SccbMgr_start_sccb(ULONG pCurrCard,
       MENABLE_INT(ioport);
       }
 
-   mOS_UnLock((PSCCBcard)pCurrCard);
 }
 
 
@@ -4488,22 +2157,9 @@ void SccbMgr_start_sccb(ULONG pCurrCard,
  *              callback function.
  *
  *---------------------------------------------------------------------*/
-#if (FW_TYPE==_UCB_MGR_)
-s32bits SccbMgr_abort_sccb(CARD_HANDLE pCurrCard, PUCB p_ucb)
-#else
-#if defined(DOS)
-int SccbMgr_abort_sccb(USHORT pCurrCard, PSCCB p_Sccb)
-#else
-int SccbMgr_abort_sccb(ULONG pCurrCard, PSCCB p_Sccb)
-#endif
-#endif
-
+static int SccbMgr_abort_sccb(ULONG pCurrCard, PSCCB p_Sccb)
 {
-#if defined(DOS)
-	USHORT ioport;
-#else
 	ULONG ioport;
-#endif
 
 	UCHAR thisCard;
 	CALL_BK_FN callback;
@@ -4512,53 +2168,31 @@ int SccbMgr_abort_sccb(ULONG pCurrCard, 
 	PSCCBMgr_tar_info currTar_Info;
 
 
-#if (FW_TYPE==_UCB_MGR_)
-	PSCCB    p_Sccb;
-	p_Sccb=(PSCCB)p_ucb->UCB_MgrPrivatePtr;
-#endif
-
 	ioport = ((PSCCBcard) pCurrCard)->ioPort;
 
 	thisCard = ((PSCCBcard)pCurrCard)->cardIndex;
 
-	mOS_Lock((PSCCBcard)pCurrCard);
-
-	if (RD_HARPOON(ioport+hp_page_ctrl) & G_INT_DISABLE)
-	{
-		mOS_UnLock((PSCCBcard)pCurrCard);
-	}
-
-	else
+	if (!(RD_HARPOON(ioport+hp_page_ctrl) & G_INT_DISABLE))
 	{
 
-		if (queueFindSccb(p_Sccb,thisCard))
+		if (FPT_queueFindSccb(p_Sccb,thisCard))
 		{
 
-			mOS_UnLock((PSCCBcard)pCurrCard);
-
 			((PSCCBcard)pCurrCard)->cmdCounter--;
 
 			if (!((PSCCBcard)pCurrCard)->cmdCounter)
 				WR_HARPOON(ioport+hp_semaphore,(RD_HARPOON(ioport+hp_semaphore)
 					& (UCHAR)(~(SCCB_MGR_ACTIVE | TICKLE_ME)) ));
 
-#if (FW_TYPE==_SCCB_MGR_)
 			p_Sccb->SccbStatus = SCCB_ABORT;
 			callback = p_Sccb->SccbCallback;
 			callback(p_Sccb);
-#else
-			p_ucb->UCB_status=SCCB_ABORT;
-			callback = (CALL_BK_FN)p_ucb->UCB_callback;
-			callback(p_ucb);
-#endif
 
 			return(0);
 		}
 
 		else
 		{
-			mOS_UnLock((PSCCBcard)pCurrCard);
-
 			if (((PSCCBcard)pCurrCard)->currentSCCB == p_Sccb)
 			{
 				p_Sccb->SccbStatus = SCCB_ABORT;
@@ -4579,21 +2213,18 @@ int SccbMgr_abort_sccb(ULONG pCurrCard, 
 					{
 						p_Sccb->SccbStatus = SCCB_ABORT;
 						p_Sccb->Sccb_scsistat = ABORT_ST;
-#if (FW_TYPE==_UCB_MGR_)
-						p_ucb->UCB_status=SCCB_ABORT;
-#endif
 						p_Sccb->Sccb_scsimsg = SMABORT_TAG;
 
 						if(((PSCCBcard) pCurrCard)->currentSCCB == NULL)
 						{
 							((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
-							ssel(ioport, thisCard);
+							FPT_ssel(ioport, thisCard);
 						}
 						else
 						{
 							pSaveSCCB = ((PSCCBcard) pCurrCard)->currentSCCB;
 							((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
-							queueSelectFail((PSCCBcard) pCurrCard, thisCard);
+							FPT_queueSelectFail((PSCCBcard) pCurrCard, thisCard);
 							((PSCCBcard) pCurrCard)->currentSCCB = pSaveSCCB;
 						}
 					}
@@ -4602,9 +2233,9 @@ int SccbMgr_abort_sccb(ULONG pCurrCard, 
 				}
 				else
 				{
-					currTar_Info = &sccbMgrTbl[thisCard][p_Sccb->TargID];
+					currTar_Info = &FPT_sccbMgrTbl[thisCard][p_Sccb->TargID];
 
-					if(BL_Card[thisCard].discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_Sccb->Lun]] 
+					if(FPT_BL_Card[thisCard].discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_Sccb->Lun]] 
 							== p_Sccb)
 					{
 						p_Sccb->SccbStatus = SCCB_ABORT;
@@ -4626,37 +2257,20 @@ int SccbMgr_abort_sccb(ULONG pCurrCard, 
  *              interrupt for this card and disable the IRQ Pin if so.
  *
  *---------------------------------------------------------------------*/
-#if (FW_TYPE==_UCB_MGR_)
-u08bits SccbMgr_my_int(CARD_HANDLE pCurrCard)
-#else
-#if defined(DOS)
-UCHAR SccbMgr_my_int(USHORT pCurrCard)
-#else
-UCHAR SccbMgr_my_int(ULONG pCurrCard)
-#endif
-#endif
+static UCHAR SccbMgr_my_int(ULONG pCurrCard)
 {
-#if defined(DOS)
-   USHORT ioport;
-#else
    ULONG ioport;
-#endif
 
    ioport = ((PSCCBcard)pCurrCard)->ioPort;
 
    if (RD_HARPOON(ioport+hp_int_status) & INT_ASSERTED)
    {
-
-#if defined(DOS)
-      MDISABLE_INT(ioport);
-#endif
-
-      return(TRUE);
+      return(1);
    }
 
    else
 
-      return(FALSE);
+      return(0);
 }
 
 
@@ -4670,37 +2284,19 @@ UCHAR SccbMgr_my_int(ULONG pCurrCard)
  *              us.
  *
  *---------------------------------------------------------------------*/
-#if (FW_TYPE==_UCB_MGR_)
-s32bits SccbMgr_isr(CARD_HANDLE pCurrCard)
-#else
-#if defined(DOS)
-int SccbMgr_isr(USHORT pCurrCard)
-#else
-int SccbMgr_isr(ULONG pCurrCard)
-#endif
-#endif
+static int SccbMgr_isr(ULONG pCurrCard)
 {
    PSCCB currSCCB;
    UCHAR thisCard,result,bm_status, bm_int_st;
    USHORT hp_int;
    UCHAR i, target;
-#if defined(DOS)
-   USHORT ioport;
-#else
    ULONG ioport;
-#endif
-
-   mOS_Lock((PSCCBcard)pCurrCard);
 
    thisCard = ((PSCCBcard)pCurrCard)->cardIndex;
    ioport = ((PSCCBcard)pCurrCard)->ioPort;
 
    MDISABLE_INT(ioport);
 
-#if defined(BUGBUG)
-   WR_HARPOON(ioport+hp_user_defined_D, RD_HARPOON(ioport+hp_int_status));
-#endif
-
    if ((bm_int_st=RD_HARPOON(ioport+hp_int_status)) & EXT_STATUS_ON)
 		bm_status = RD_HARPOON(ioport+hp_ext_status) & (UCHAR)BAD_EXT_STATUS;
    else
@@ -4708,33 +2304,20 @@ int SccbMgr_isr(ULONG pCurrCard)
 
    WR_HARPOON(ioport+hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
 
-   mOS_UnLock((PSCCBcard)pCurrCard);
-
-   while ((hp_int = RDW_HARPOON((ioport+hp_intstat)) & default_intena) |
+   while ((hp_int = RDW_HARPOON((ioport+hp_intstat)) & FPT_default_intena) |
 	  bm_status)
      {
 
        currSCCB = ((PSCCBcard)pCurrCard)->currentSCCB;
 
-#if defined(BUGBUG)
-   Debug_Load(thisCard,(UCHAR) 0XFF);
-   Debug_Load(thisCard,bm_int_st);
-
-   Debug_Load(thisCard,hp_int_0);
-   Debug_Load(thisCard,hp_int_1);
-#endif
-
-
       if (hp_int & (FIFO | TIMEOUT | RESET | SCAM_SEL) || bm_status) {
-         result = SccbMgr_bad_isr(ioport,thisCard,((PSCCBcard)pCurrCard),hp_int);
+         result = FPT_SccbMgr_bad_isr(ioport,thisCard,((PSCCBcard)pCurrCard),hp_int);
          WRW_HARPOON((ioport+hp_intstat), (FIFO | TIMEOUT | RESET | SCAM_SEL));
          bm_status = 0;
 
          if (result) {
 
-			   mOS_Lock((PSCCBcard)pCurrCard);
             MENABLE_INT(ioport);
-			   mOS_UnLock((PSCCBcard)pCurrCard);
             return(result);
             }
          }
@@ -4753,7 +2336,7 @@ int SccbMgr_isr(ULONG pCurrCard)
 
          if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT)
 
-            phaseChkFifo(ioport, thisCard);
+            FPT_phaseChkFifo(ioport, thisCard);
 
 /*         WRW_HARPOON((ioport+hp_intstat),
             (BUS_FREE | ICMD_COMP | ITAR_DISC | XFER_CNT_0));
@@ -4761,7 +2344,7 @@ int SccbMgr_isr(ULONG pCurrCard)
 
 		 WRW_HARPOON((ioport+hp_intstat), CLR_ALL_INT_1);
 
-         autoCmdCmplt(ioport,thisCard);
+         FPT_autoCmdCmplt(ioport,thisCard);
 
          }
 
@@ -4771,7 +2354,7 @@ int SccbMgr_isr(ULONG pCurrCard)
 
          if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT) {
 
-            phaseChkFifo(ioport, thisCard);
+            FPT_phaseChkFifo(ioport, thisCard);
 
             }
 
@@ -4784,7 +2367,7 @@ int SccbMgr_isr(ULONG pCurrCard)
             }
 
          currSCCB->Sccb_scsistat = DISCONNECT_ST;
-         queueDisconnect(currSCCB,thisCard);
+         FPT_queueDisconnect(currSCCB,thisCard);
 
             /* Wait for the BusFree before starting a new command.  We
                must also check for being reselected since the BusFree
@@ -4803,9 +2386,7 @@ int SccbMgr_isr(ULONG pCurrCard)
 	   */
 	   if (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL)))
 	     {
-	       mOS_Lock((PSCCBcard)pCurrCard);
 	       MENABLE_INT(ioport);
-	       mOS_UnLock((PSCCBcard)pCurrCard);
 	       return 0xFE;
 	     }
 
@@ -4825,7 +2406,7 @@ int SccbMgr_isr(ULONG pCurrCard)
 		      {
             if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT)
 			      {
-               phaseChkFifo(ioport, thisCard);
+               FPT_phaseChkFifo(ioport, thisCard);
                }
 
             if (RD_HARPOON(ioport+hp_gp_reg_1) == SMSAVE_DATA_PTR)
@@ -4837,11 +2418,11 @@ int SccbMgr_isr(ULONG pCurrCard)
 
             WRW_HARPOON((ioport+hp_intstat), (BUS_FREE | ITAR_DISC));
             currSCCB->Sccb_scsistat = DISCONNECT_ST;
-            queueDisconnect(currSCCB,thisCard);
+            FPT_queueDisconnect(currSCCB,thisCard);
             }
 
-         sres(ioport,thisCard,((PSCCBcard)pCurrCard));
-         phaseDecode(ioport,thisCard);
+         FPT_sres(ioport,thisCard,((PSCCBcard)pCurrCard));
+         FPT_phaseDecode(ioport,thisCard);
 
          }
 
@@ -4850,7 +2431,7 @@ int SccbMgr_isr(ULONG pCurrCard)
          {
 
             WRW_HARPOON((ioport+hp_intstat), (IDO_STRT | XFER_CNT_0));
-            phaseDecode(ioport,thisCard);
+            FPT_phaseDecode(ioport,thisCard);
 
          }
 
@@ -4860,7 +2441,7 @@ int SccbMgr_isr(ULONG pCurrCard)
 	 	   WRW_HARPOON((ioport+hp_intstat), (PHASE | IUNKWN | PROG_HLT));
 	 	   if ((RD_HARPOON(ioport+hp_prgmcnt_0) & (UCHAR)0x3f)< (UCHAR)SELCHK)
 	    		{
-	    		phaseDecode(ioport,thisCard);
+	    		FPT_phaseDecode(ioport,thisCard);
 	    		}
 	 	   else
 	    		{
@@ -4885,7 +2466,7 @@ int SccbMgr_isr(ULONG pCurrCard)
 
          WRW_HARPOON((ioport+hp_intstat), XFER_CNT_0);
 
-         schkdd(ioport,thisCard);
+         FPT_schkdd(ioport,thisCard);
 
          }
 
@@ -4896,10 +2477,10 @@ int SccbMgr_isr(ULONG pCurrCard)
 
         	if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT) {
 
-           	hostDataXferAbort(ioport,thisCard,currSCCB);
+           	FPT_hostDataXferAbort(ioport,thisCard,currSCCB);
 				}
 
-         phaseBusFree(ioport,thisCard);
+         FPT_phaseBusFree(ioport,thisCard);
 			}
 
 
@@ -4919,12 +2500,12 @@ int SccbMgr_isr(ULONG pCurrCard)
 
          if (((PSCCBcard)pCurrCard)->currentSCCB == NULL) {
 
-            queueSearchSelect(((PSCCBcard)pCurrCard),thisCard);
+            FPT_queueSearchSelect(((PSCCBcard)pCurrCard),thisCard);
             }
 
          if (((PSCCBcard)pCurrCard)->currentSCCB != NULL) {
             ((PSCCBcard)pCurrCard)->globalFlags &= ~F_NEW_SCCB_CMD;
-            ssel(ioport,thisCard);
+            FPT_ssel(ioport,thisCard);
             }
 
          break;
@@ -4933,9 +2514,7 @@ int SccbMgr_isr(ULONG pCurrCard)
 
       }  /*end while */
 
-   mOS_Lock((PSCCBcard)pCurrCard);
    MENABLE_INT(ioport);
-   mOS_UnLock((PSCCBcard)pCurrCard);
 
    return(0);
 }
@@ -4950,18 +2529,12 @@ int SccbMgr_isr(ULONG pCurrCard)
  *              processing time.
  *
  *---------------------------------------------------------------------*/
-#if defined(DOS)
-UCHAR SccbMgr_bad_isr(USHORT p_port, UCHAR p_card, PSCCBcard pCurrCard, USHORT p_int)
-#else
-UCHAR SccbMgr_bad_isr(ULONG p_port, UCHAR p_card, PSCCBcard pCurrCard, USHORT p_int)
-#endif
+static UCHAR FPT_SccbMgr_bad_isr(ULONG p_port, UCHAR p_card,
+				 PSCCBcard pCurrCard, USHORT p_int)
 {
-#if defined(HARP_REVX)
-   ULONG timer;
-#endif
-UCHAR temp, ScamFlg;
-PSCCBMgr_tar_info currTar_Info;
-PNVRamInfo pCurrNvRam;
+   UCHAR temp, ScamFlg;
+   PSCCBMgr_tar_info currTar_Info;
+   PNVRamInfo pCurrNvRam;
 
 
    if (RD_HARPOON(p_port+hp_ext_status) &
@@ -4971,7 +2544,7 @@ PNVRamInfo pCurrNvRam;
       if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
          {
 
-         hostDataXferAbort(p_port,p_card, pCurrCard->currentSCCB);
+         FPT_hostDataXferAbort(p_port,p_card, pCurrCard->currentSCCB);
          }
 
       if (RD_HARPOON(p_port+hp_pci_stat_cfg) & REC_MASTER_ABORT)
@@ -4990,7 +2563,7 @@ PNVRamInfo pCurrNvRam;
          if (!pCurrCard->currentSCCB->HostStatus)
             pCurrCard->currentSCCB->HostStatus = SCCB_BM_ERR;
 
-         sxfrp(p_port,p_card);
+         FPT_sxfrp(p_port,p_card);
 
 	     temp = (UCHAR)(RD_HARPOON(p_port+hp_ee_ctrl) &
 							(EXT_ARB_ACK | SCSI_TERM_ENA_H));
@@ -4999,7 +2572,7 @@ PNVRamInfo pCurrNvRam;
 
          if (!(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
             {
-            phaseDecode(p_port,p_card);
+            FPT_phaseDecode(p_port,p_card);
             }
          }
       }
@@ -5014,13 +2587,13 @@ PNVRamInfo pCurrNvRam;
 
                if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
 
-               hostDataXferAbort(p_port,p_card, pCurrCard->currentSCCB);
+               FPT_hostDataXferAbort(p_port,p_card, pCurrCard->currentSCCB);
                }
 
 
            DISABLE_AUTO(p_port);
 
-           sresb(p_port,p_card);
+           FPT_sresb(p_port,p_card);
 
            while(RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST) {}
 
@@ -5029,12 +2602,12 @@ PNVRamInfo pCurrNvRam;
 					ScamFlg = pCurrNvRam->niScamConf;
 				}
 				else{
-				   ScamFlg = (UCHAR) utilEERead(p_port, SCAM_CONFIG/2);
+				   ScamFlg = (UCHAR) FPT_utilEERead(p_port, SCAM_CONFIG/2);
 				}
 
-           XbowInit(p_port, ScamFlg);
+           FPT_XbowInit(p_port, ScamFlg);
 
-               scini(p_card, pCurrCard->ourId, 0);
+               FPT_scini(p_card, pCurrCard->ourId, 0);
 
            return(0xFF);
          }
@@ -5044,34 +2617,8 @@ PNVRamInfo pCurrNvRam;
 
       WRW_HARPOON((p_port+hp_intstat), FIFO);
 
-#if defined(HARP_REVX)
-
-      for (timer=0x00FFFFFFL; timer != 0x00000000L; timer--) {
-
-         if (RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY)
-            break;
-
-         if (RDW_HARPOON((p_port+hp_intstat)) & BUS_FREE)
-            break;
-         }
-
-
-      if ( (RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY) &&
-           (RD_HARPOON(p_port+hp_fiforead) !=
-            RD_HARPOON(p_port+hp_fifowrite)) &&
-           (RD_HARPOON(p_port+hp_xfercnt_0))
-         )
-
-            WR_HARPOON((p_port+hp_xferstat), 0x01);
-
-/*      else
- */
-/*         sxfrp(p_port,p_card);
- */
-#else
       if (pCurrCard->currentSCCB != NULL)
-         sxfrp(p_port,p_card);
-#endif
+         FPT_sxfrp(p_port,p_card);
       }
 
    else if (p_int & TIMEOUT)
@@ -5085,12 +2632,12 @@ PNVRamInfo pCurrNvRam;
       pCurrCard->currentSCCB->HostStatus = SCCB_SELECTION_TIMEOUT;
 
 
-		currTar_Info = &sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
+		currTar_Info = &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
 		if((pCurrCard->globalFlags & F_CONLUN_IO) &&
 			((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
-	      currTar_Info->TarLUNBusy[pCurrCard->currentSCCB->Lun] = FALSE;
+	      currTar_Info->TarLUNBusy[pCurrCard->currentSCCB->Lun] = 0;
 		else
-	      currTar_Info->TarLUNBusy[0] = FALSE;
+	      currTar_Info->TarLUNBusy[0] = 0;
 
 
       if (currTar_Info->TarEEValue & EE_SYNC_MASK)
@@ -5101,134 +2648,30 @@ PNVRamInfo pCurrNvRam;
 
       if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
          {
-         currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
-         }
-
-      sssyncv(p_port, pCurrCard->currentSCCB->TargID, NARROW_SCSI,currTar_Info);
-
-      queueCmdComplete(pCurrCard, pCurrCard->currentSCCB, p_card);
-
-      }
-
-#if defined(SCAM_LEV_2)
-
-   else if (p_int & SCAM_SEL)
-      {
-
-      scarb(p_port,LEVEL2_TAR);
-      scsel(p_port);
-      scasid(p_card, p_port);
-
-      scbusf(p_port);
-
-      WRW_HARPOON((p_port+hp_intstat), SCAM_SEL);
-      }
-#endif
-
-   return(0x00);
-}
-
-
-/*---------------------------------------------------------------------
- *
- * Function: SccbMgr_scsi_reset
- *
- * Description: A SCSI bus reset will be generated and all outstanding
- *              Sccbs will be returned via the callback.
- *
- *---------------------------------------------------------------------*/
-#if (FW_TYPE==_UCB_MGR_)
-void SccbMgr_scsi_reset(CARD_HANDLE pCurrCard)
-#else
-#if defined(DOS)
-void SccbMgr_scsi_reset(USHORT pCurrCard)
-#else
-void SccbMgr_scsi_reset(ULONG pCurrCard)
-#endif
-#endif
-{
-   UCHAR thisCard;
+         currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
+         }
 
-   thisCard = ((PSCCBcard)pCurrCard)->cardIndex;
+      FPT_sssyncv(p_port, pCurrCard->currentSCCB->TargID, NARROW_SCSI,currTar_Info);
 
-   mOS_Lock((PSCCBcard)pCurrCard);
+      FPT_queueCmdComplete(pCurrCard, pCurrCard->currentSCCB, p_card);
 
-   if (((PSCCBcard) pCurrCard)->globalFlags & F_GREEN_PC)
-      {
-      WR_HARPOON(((PSCCBcard) pCurrCard)->ioPort+hp_clkctrl_0, CLKCTRL_DEFAULT);
-      WR_HARPOON(((PSCCBcard) pCurrCard)->ioPort+hp_sys_ctrl, 0x00);
       }
 
-   sresb(((PSCCBcard)pCurrCard)->ioPort,thisCard);
-
-   if (RD_HARPOON(((PSCCBcard)pCurrCard)->ioPort+hp_ext_status) & BM_CMD_BUSY)
+   else if (p_int & SCAM_SEL)
       {
-      WR_HARPOON(((PSCCBcard) pCurrCard)->ioPort+hp_page_ctrl,
-         (RD_HARPOON(((PSCCBcard) pCurrCard)->ioPort+hp_page_ctrl)
-         & ~SCATTER_EN));
 
-      WR_HARPOON(((PSCCBcard) pCurrCard)->ioPort+hp_sg_addr,0x00);
+      FPT_scarb(p_port,LEVEL2_TAR);
+      FPT_scsel(p_port);
+      FPT_scasid(p_card, p_port);
 
-      ((PSCCBcard) pCurrCard)->globalFlags &= ~F_HOST_XFER_ACT;
-      busMstrTimeOut(((PSCCBcard) pCurrCard)->ioPort);
+      FPT_scbusf(p_port);
 
-      WR_HARPOON(((PSCCBcard) pCurrCard)->ioPort+hp_int_mask,
-         (INT_CMD_COMPL | SCSI_INTERRUPT));
+      WRW_HARPOON((p_port+hp_intstat), SCAM_SEL);
       }
 
-/*
-      if (utilEERead(((PSCCBcard)pCurrCard)->ioPort, (SCAM_CONFIG/2))
-            & SCAM_ENABLED)
-*/
-         scini(thisCard, ((PSCCBcard)pCurrCard)->ourId, 0);
-
-#if (FW_TYPE==_UCB_MGR_)
-   ((PSCCBcard)pCurrCard)->cardInfo->ai_AEN_routine(0x01,pCurrCard,0,0,0,0);
-#endif
-
-   mOS_UnLock((PSCCBcard)pCurrCard);
-}
-
-
-/*---------------------------------------------------------------------
- *
- * Function: SccbMgr_timer_expired
- *
- * Description: This function allow me to kill my own job that has not
- *              yet completed, and has cause a timeout to occur.  This
- *              timeout has caused the upper level driver to call this
- *              function.
- *
- *---------------------------------------------------------------------*/
-
-#if (FW_TYPE==_UCB_MGR_)
-void SccbMgr_timer_expired(CARD_HANDLE pCurrCard)
-#else
-#if defined(DOS)
-void SccbMgr_timer_expired(USHORT pCurrCard)
-#else
-void SccbMgr_timer_expired(ULONG pCurrCard)
-#endif
-#endif
-{
+   return(0x00);
 }
 
-#if defined(DOS)
-/*---------------------------------------------------------------------
- *
- * Function: SccbMgr_status
- *
- * Description: This function returns the number of outstanding SCCB's.
- *              This is specific to the DOS enviroment, which needs this
- *              to help them keep protected and real mode commands staight.
- *
- *---------------------------------------------------------------------*/
-
-USHORT SccbMgr_status(USHORT pCurrCard)
-{
-   return(BL_Card[pCurrCard].cmdCounter);
-}
-#endif
 
 /*---------------------------------------------------------------------
  *
@@ -5238,19 +2681,19 @@ USHORT SccbMgr_status(USHORT pCurrCard)
  *
  *---------------------------------------------------------------------*/
 
-void SccbMgrTableInitAll()
+static void FPT_SccbMgrTableInitAll()
 {
    UCHAR thisCard;
 
    for (thisCard = 0; thisCard < MAX_CARDS; thisCard++)
       {
-      SccbMgrTableInitCard(&BL_Card[thisCard],thisCard);
+      FPT_SccbMgrTableInitCard(&FPT_BL_Card[thisCard],thisCard);
 
-      BL_Card[thisCard].ioPort      = 0x00;
-      BL_Card[thisCard].cardInfo    = NULL;
-      BL_Card[thisCard].cardIndex   = 0xFF;
-      BL_Card[thisCard].ourId       = 0x00;
-		BL_Card[thisCard].pNvRamInfo	= NULL;
+      FPT_BL_Card[thisCard].ioPort      = 0x00;
+      FPT_BL_Card[thisCard].cardInfo    = NULL;
+      FPT_BL_Card[thisCard].cardIndex   = 0xFF;
+      FPT_BL_Card[thisCard].ourId       = 0x00;
+		FPT_BL_Card[thisCard].pNvRamInfo	= NULL;
       }
 }
 
@@ -5263,20 +2706,20 @@ void SccbMgrTableInitAll()
  *
  *---------------------------------------------------------------------*/
 
-void SccbMgrTableInitCard(PSCCBcard pCurrCard, UCHAR p_card)
+static void FPT_SccbMgrTableInitCard(PSCCBcard pCurrCard, UCHAR p_card)
 {
    UCHAR scsiID, qtag;
 
 	for (qtag = 0; qtag < QUEUE_DEPTH; qtag++)
 	{
-		BL_Card[p_card].discQ_Tbl[qtag] = NULL;
+		FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
 	}
 
    for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++)
       {
-      sccbMgrTbl[p_card][scsiID].TarStatus = 0;
-      sccbMgrTbl[p_card][scsiID].TarEEValue = 0;
-      SccbMgrTableInitTarget(p_card, scsiID);
+      FPT_sccbMgrTbl[p_card][scsiID].TarStatus = 0;
+      FPT_sccbMgrTbl[p_card][scsiID].TarEEValue = 0;
+      FPT_SccbMgrTableInitTarget(p_card, scsiID);
       }
 
    pCurrCard->scanIndex = 0x00;
@@ -5298,13 +2741,13 @@ void SccbMgrTableInitCard(PSCCBcard pCur
  *
  *---------------------------------------------------------------------*/
 
-void SccbMgrTableInitTarget(UCHAR p_card, UCHAR target)
+static void FPT_SccbMgrTableInitTarget(UCHAR p_card, UCHAR target)
 {
 
 	UCHAR lun, qtag;
 	PSCCBMgr_tar_info currTar_Info;
 
-	currTar_Info = &sccbMgrTbl[p_card][target];
+	currTar_Info = &FPT_sccbMgrTbl[p_card][target];
 
 	currTar_Info->TarSelQ_Cnt = 0;
 	currTar_Info->TarSyncCtrl = 0;
@@ -5312,160 +2755,28 @@ void SccbMgrTableInitTarget(UCHAR p_card
 	currTar_Info->TarSelQ_Head = NULL;
 	currTar_Info->TarSelQ_Tail = NULL;
 	currTar_Info->TarTagQ_Cnt = 0;
-	currTar_Info->TarLUN_CA = FALSE;
+	currTar_Info->TarLUN_CA = 0;
 
 
 	for (lun = 0; lun < MAX_LUN; lun++)
 	{
-		currTar_Info->TarLUNBusy[lun] = FALSE;
+		currTar_Info->TarLUNBusy[lun] = 0;
 		currTar_Info->LunDiscQ_Idx[lun] = 0;
 	}
 
 	for (qtag = 0; qtag < QUEUE_DEPTH; qtag++)
 	{
-		if(BL_Card[p_card].discQ_Tbl[qtag] != NULL)
+		if(FPT_BL_Card[p_card].discQ_Tbl[qtag] != NULL)
 		{
-			if(BL_Card[p_card].discQ_Tbl[qtag]->TargID == target)
+			if(FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == target)
 			{
-				BL_Card[p_card].discQ_Tbl[qtag] = NULL;
-				BL_Card[p_card].discQCount--;
+				FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
+				FPT_BL_Card[p_card].discQCount--;
 			}
 		}
 	}
 }
 
-#if defined(BUGBUG)
-
-/*****************************************************************
- * Save the current byte in the debug array
- *****************************************************************/
-
-
-void Debug_Load(UCHAR p_card, UCHAR p_bug_data)
-{
-   debug_int[p_card][debug_index[p_card]] = p_bug_data;
-   debug_index[p_card]++;
-
-   if (debug_index[p_card] == debug_size)
-
-      debug_index[p_card] = 0;
-}
-
-#endif
-#ident "$Id: sccb_dat.c 1.10 1997/02/22 03:16:02 awin Exp $"
-/*----------------------------------------------------------------------
- *
- *
- *   Copyright 1995-1996 by Mylex Corporation.  All Rights Reserved
- *
- *   This file is available under both the GNU General Public License
- *   and a BSD-style copyright; see LICENSE.FlashPoint for details.
- *
- *   $Workfile:   sccb_dat.c  $
- *
- *   Description:  Functions relating to handling of the SCCB interface 
- *                 between the device driver and the HARPOON.
- *
- *   $Date: 1997/02/22 03:16:02 $
- *
- *   $Revision: 1.10 $
- *
- *----------------------------------------------------------------------*/
-
-/*#include <globals.h>*/
-
-#if (FW_TYPE==_UCB_MGR_)
-	/*#include <budi.h>*/
-#endif
-
-/*#include <sccbmgr.h>*/
-/*#include <blx30.h>*/
-/*#include <target.h>*/
-/*#include <harpoon.h>*/
-
-/*
-**  IMPORTANT NOTE!!!
-**
-**  You MUST preassign all data to a valid value or zero.  This is
-**  required due to the MS compiler bug under OS/2 and Solaris Real-Mode
-**  driver environment.
-*/
-
-
-SCCBMGR_TAR_INFO sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR] = { { { 0 } } };
-SCCBCARD BL_Card[MAX_CARDS] = { { 0 } };
-SCCBSCAM_INFO scamInfo[MAX_SCSI_TAR] = { { { 0 } } };
-NVRAMINFO nvRamInfo[MAX_MB_CARDS] = { { 0 } };
-
-
-#if defined(OS2)
-void (far *s_PhaseTbl[8]) (ULONG, UCHAR) = { 0 };
-UCHAR temp_id_string[ID_STRING_LENGTH] = { 0 };
-#elif defined(SOLARIS_REAL_MODE) || defined(__STDC__)
-void (*s_PhaseTbl[8]) (ULONG, UCHAR) = { 0 };
-#else
-void (*s_PhaseTbl[8]) ();
-#endif
-
-#if defined(DOS)
-UCHAR first_time = 0;
-#endif
-
-UCHAR mbCards = 0;
-UCHAR scamHAString[] = {0x63, 0x07, 'B', 'U', 'S', 'L', 'O', 'G', 'I', 'C', \
-								' ', 'B', 'T', '-', '9', '3', '0', \
-								0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, \
-								0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};
-
-USHORT default_intena = 0;
-
-#if defined(BUGBUG)
-UCHAR    debug_int[MAX_CARDS][debug_size] = { 0 };
-UCHAR    debug_index[MAX_CARDS] = { 0 };
-UCHAR    reserved_1[3] = { 0 };
-#endif
-#ident "$Id: scsi.c 1.23 1997/07/09 21:42:54 mohan Exp $"
-/*----------------------------------------------------------------------
- *
- *
- *   Copyright 1995-1996 by Mylex Corporation.  All Rights Reserved
- *
- *   This file is available under both the GNU General Public License
- *   and a BSD-style copyright; see LICENSE.FlashPoint for details.
- *
- *   $Workfile:   scsi.c  $
- *
- *   Description:  Functions for handling SCSI bus functions such as
- *                 selection/reselection, sync negotiation, message-in
- *                 decoding.
- *
- *   $Date: 1997/07/09 21:42:54 $
- *
- *   $Revision: 1.23 $
- *
- *----------------------------------------------------------------------*/
-
-/*#include <globals.h>*/
-
-#if (FW_TYPE==_UCB_MGR_)
-	/*#include <budi.h>*/
-#endif
-
-/*#include <sccbmgr.h>*/
-/*#include <blx30.h>*/
-/*#include <target.h>*/
-/*#include <scsi2.h>*/
-/*#include <eeprom.h>*/
-/*#include <harpoon.h>*/
-
-
-/*
-extern SCCBCARD BL_Card[MAX_CARDS];
-extern SCCBMGR_TAR_INFO sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR];
-#if defined(BUGBUG)
-void Debug_Load(UCHAR p_card, UCHAR p_bug_data);
-#endif
-*/
 
 /*---------------------------------------------------------------------
  *
@@ -5476,11 +2787,7 @@ void Debug_Load(UCHAR p_card, UCHAR p_bu
  *
  *---------------------------------------------------------------------*/
 
-#if defined(DOS)
-UCHAR sfm(USHORT port, PSCCB pCurrSCCB)
-#else
-UCHAR sfm(ULONG port, PSCCB pCurrSCCB)
-#endif
+static UCHAR FPT_sfm(ULONG port, PSCCB pCurrSCCB)
 {
 	UCHAR message;
 	USHORT TimeOutLoop;
@@ -5547,42 +2854,27 @@ UCHAR sfm(ULONG port, PSCCB pCurrSCCB)
 
 /*---------------------------------------------------------------------
  *
- * Function: ssel
+ * Function: FPT_ssel
  *
  * Description: Load up automation and select target device.
  *
  *---------------------------------------------------------------------*/
 
-#if defined(DOS)
-void ssel(USHORT port, UCHAR p_card)
-#else
-void ssel(ULONG port, UCHAR p_card)
-#endif
+static void FPT_ssel(ULONG port, UCHAR p_card)
 {
 
-#if defined(DOS)
-   UCHAR auto_loaded, i, target, *theCCB;
-#elif defined(OS2)
-   UCHAR auto_loaded, i, target;
-   UCHAR far *theCCB;
-#else
    UCHAR auto_loaded, i, target, *theCCB;
-#endif
 
-#if defined(DOS)
-   USHORT cdb_reg;
-#else
    ULONG cdb_reg;
-#endif
    PSCCBcard CurrCard;
    PSCCB currSCCB;
    PSCCBMgr_tar_info currTar_Info;
    UCHAR lastTag, lun;
 
-   CurrCard = &BL_Card[p_card];
+   CurrCard = &FPT_BL_Card[p_card];
    currSCCB = CurrCard->currentSCCB;
    target = currSCCB->TargID;
-   currTar_Info = &sccbMgrTbl[p_card][target];
+   currTar_Info = &FPT_sccbMgrTbl[p_card][target];
    lastTag = CurrCard->tagQ_Lst;
 
    ARAM_ACCESS(port);
@@ -5599,60 +2891,53 @@ void ssel(ULONG port, UCHAR p_card)
 		lun = 0;
 
 
-#if defined(DOS)
-   currTar_Info->TarLUNBusy[lun] = TRUE;
-
-#else
-
    if (CurrCard->globalFlags & F_TAG_STARTED)
       {
       if (!(currSCCB->ControlByte & F_USE_CMD_Q))
          {
-      	if ((currTar_Info->TarLUN_CA == FALSE)
+      	if ((currTar_Info->TarLUN_CA == 0)
       	    && ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
       	    == TAG_Q_TRYING))
             {
 
 	         if (currTar_Info->TarTagQ_Cnt !=0)
                   {
-         		   currTar_Info->TarLUNBusy[lun] = TRUE;
-            		queueSelectFail(CurrCard,p_card);
+         		   currTar_Info->TarLUNBusy[lun] = 1;
+            		FPT_queueSelectFail(CurrCard,p_card);
 					   SGRAM_ACCESS(port);
          		   return;
          		   }
 
             else {
-         		  currTar_Info->TarLUNBusy[lun] = TRUE;
+         		  currTar_Info->TarLUNBusy[lun] = 1;
          		  }
 
    	      }  /*End non-tagged */
 
 	      else {
-	         currTar_Info->TarLUNBusy[lun] = TRUE;
+	         currTar_Info->TarLUNBusy[lun] = 1;
 	         }
 
 	      }  /*!Use cmd Q Tagged */
 
 	   else {
-   	     if (currTar_Info->TarLUN_CA == TRUE)
+   	     if (currTar_Info->TarLUN_CA == 1)
                {
-      	      queueSelectFail(CurrCard,p_card);
+      	      FPT_queueSelectFail(CurrCard,p_card);
 				   SGRAM_ACCESS(port);
       	      return;
 	            }
 
-	        currTar_Info->TarLUNBusy[lun] = TRUE;
+	        currTar_Info->TarLUNBusy[lun] = 1;
 
    	     }  /*else use cmd Q tagged */
 
       }  /*if glob tagged started */
 
    else {
-        currTar_Info->TarLUNBusy[lun] = TRUE;
+        currTar_Info->TarLUNBusy[lun] = 1;
         }
 
-#endif /* DOS */
-
 
 
 	if((((CurrCard->globalFlags & F_CONLUN_IO) && 
@@ -5661,8 +2946,8 @@ void ssel(ULONG port, UCHAR p_card)
 	{
 		if(CurrCard->discQCount >= QUEUE_DEPTH)
 		{
-			currTar_Info->TarLUNBusy[lun] = TRUE;
-			queueSelectFail(CurrCard,p_card);
+			currTar_Info->TarLUNBusy[lun] = 1;
+			FPT_queueSelectFail(CurrCard,p_card);
 			SGRAM_ACCESS(port);
 			return;
 		}
@@ -5680,8 +2965,8 @@ void ssel(ULONG port, UCHAR p_card)
 		}
 		if(i == QUEUE_DEPTH)
 		{
-			currTar_Info->TarLUNBusy[lun] = TRUE;
-			queueSelectFail(CurrCard,p_card);
+			currTar_Info->TarLUNBusy[lun] = 1;
+			FPT_queueSelectFail(CurrCard,p_card);
 			SGRAM_ACCESS(port);
 			return;
 		}
@@ -5689,7 +2974,7 @@ void ssel(ULONG port, UCHAR p_card)
 
 
 
-   auto_loaded = FALSE;
+   auto_loaded = 0;
 
    WR_HARPOON(port+hp_select_id, target);
    WR_HARPOON(port+hp_gp_reg_3, target);  /* Use by new automation logic */
@@ -5703,7 +2988,7 @@ void ssel(ULONG port, UCHAR p_card)
       currSCCB->Sccb_scsimsg = SMDEV_RESET;
 
       WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
-      auto_loaded = TRUE;
+      auto_loaded = 1;
       currSCCB->Sccb_scsistat = SELECT_BDR_ST;
 
       if (currTar_Info->TarEEValue & EE_SYNC_MASK)
@@ -5712,16 +2997,13 @@ void ssel(ULONG port, UCHAR p_card)
 	      currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
 	      }
 
-#if defined(WIDE_SCSI)
-
       if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
          {
       	currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
       	}
-#endif
 
-      sssyncv(port, target, NARROW_SCSI,currTar_Info);
-      SccbMgrTableInitTarget(p_card, target);
+      FPT_sssyncv(port, target, NARROW_SCSI,currTar_Info);
+      FPT_SccbMgrTableInitTarget(p_card, target);
 
       }
 
@@ -5740,24 +3022,18 @@ void ssel(ULONG port, UCHAR p_card)
 			WRW_HARPOON((port+SYNC_MSGS+4), (BRH_OP+ALWAYS+NP ));
 
 			WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
-			auto_loaded = TRUE;
+			auto_loaded = 1;
 		
 		}
 
-#if defined(WIDE_SCSI)
-
-
    else if (!(currTar_Info->TarStatus & WIDE_NEGOCIATED))  {
-      auto_loaded = siwidn(port,p_card);
+      auto_loaded = FPT_siwidn(port,p_card);
       currSCCB->Sccb_scsistat = SELECT_WN_ST;
       }
 
-#endif
-
-
    else if (!((currTar_Info->TarStatus & TAR_SYNC_MASK)
       == SYNC_SUPPORTED))  {
-      auto_loaded = sisyncn(port,p_card, FALSE);
+      auto_loaded = FPT_sisyncn(port,p_card, 0);
       currSCCB->Sccb_scsistat = SELECT_SN_ST;
       }
 
@@ -5765,7 +3041,6 @@ void ssel(ULONG port, UCHAR p_card)
    if (!auto_loaded)
       {
 
-#if !defined(DOS)
       if (currSCCB->ControlByte & F_USE_CMD_Q)
          {
 
@@ -5789,7 +3064,7 @@ void ssel(ULONG port, UCHAR p_card)
                the wheels fall off. */
             currSCCB->Sccb_scsistat = SELECT_ST;
 
-	         currTar_Info->TarLUNBusy[lun] = TRUE;
+	         currTar_Info->TarLUNBusy[lun] = 1;
             }
 
          else
@@ -5818,8 +3093,8 @@ void ssel(ULONG port, UCHAR p_card)
 
             if ( i == QUEUE_DEPTH )
                {
-   	         currTar_Info->TarLUNBusy[lun] = TRUE;
-               queueSelectFail(CurrCard,p_card);
+   	         currTar_Info->TarLUNBusy[lun] = 1;
+               FPT_queueSelectFail(CurrCard,p_card);
 				   SGRAM_ACCESS(port);
    	         return;
    	         }
@@ -5832,7 +3107,6 @@ void ssel(ULONG port, UCHAR p_card)
 
       else
          {
-#endif   /* !DOS */
 
          WRW_HARPOON((port+ID_MSG_STRT),BRH_OP+ALWAYS+NTCMD);
 
@@ -5842,16 +3116,10 @@ void ssel(ULONG port, UCHAR p_card)
          currSCCB->Sccb_scsistat = SELECT_ST;
 
          WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
-#if !defined(DOS)
          }
-#endif
 
 
-#if defined(OS2)
-      theCCB = (UCHAR far *)&currSCCB->Cdb[0];
-#else
       theCCB = (UCHAR *)&currSCCB->Cdb[0];
-#endif
 
       cdb_reg = port + CMD_STRT;
 
@@ -5867,10 +3135,8 @@ void ssel(ULONG port, UCHAR p_card)
 
       }  /* auto_loaded */
 
-#if defined(WIDE_SCSI)
    WRW_HARPOON((port+hp_fiforead), (USHORT) 0x00);
    WR_HARPOON(port+hp_xferstat, 0x00);
-#endif
 
    WRW_HARPOON((port+hp_intstat), (PROG_HLT | TIMEOUT | SEL | BUS_FREE));
 
@@ -5899,30 +3165,16 @@ void ssel(ULONG port, UCHAR p_card)
 
 /*---------------------------------------------------------------------
  *
- * Function: sres
+ * Function: FPT_sres
  *
  * Description: Hookup the correct CCB and handle the incoming messages.
  *
  *---------------------------------------------------------------------*/
 
-#if defined(DOS)
-void sres(USHORT port, UCHAR p_card, PSCCBcard pCurrCard)
-#else
-void sres(ULONG port, UCHAR p_card, PSCCBcard pCurrCard)
-#endif
+static void FPT_sres(ULONG port, UCHAR p_card, PSCCBcard pCurrCard)
 {
 
-#if defined(V302)
-#ifdef DOS
-   UCHAR our_target,message, msgRetryCount;
-   extern UCHAR lun, tag;
-#else
-   UCHAR our_target,message,lun,tag, msgRetryCount;
-#endif
-
-#else  /* V302 */
    UCHAR our_target, message, lun = 0, tag, msgRetryCount;
-#endif /* V302 */
 
 
    PSCCBMgr_tar_info currTar_Info;
@@ -5933,7 +3185,7 @@ void sres(ULONG port, UCHAR p_card, PSCC
 
 	if(pCurrCard->currentSCCB != NULL)
 	{
-		currTar_Info = &sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
+		currTar_Info = &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
 		DISABLE_AUTO(port);
 
 
@@ -5954,7 +3206,7 @@ void sres(ULONG port, UCHAR p_card, PSCC
 		if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
 			((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
 		{
-      	currTar_Info->TarLUNBusy[currSCCB->Lun] = FALSE;
+      	currTar_Info->TarLUNBusy[currSCCB->Lun] = 0;
 			if(currSCCB->Sccb_scsistat != ABORT_ST)
 			{
 				pCurrCard->discQCount--;
@@ -5964,7 +3216,7 @@ void sres(ULONG port, UCHAR p_card, PSCC
 		}
 		else
 		{
-	      currTar_Info->TarLUNBusy[0] = FALSE;
+	      currTar_Info->TarLUNBusy[0] = 0;
 			if(currSCCB->Sccb_tag)
 			{
 				if(currSCCB->Sccb_scsistat != ABORT_ST)
@@ -5982,29 +3234,21 @@ void sres(ULONG port, UCHAR p_card, PSCC
 			}
 		}
 
-      queueSelectFail(&BL_Card[p_card],p_card);
+      FPT_queueSelectFail(&FPT_BL_Card[p_card],p_card);
 	}
 
-#if defined(WIDE_SCSI)
 	WRW_HARPOON((port+hp_fiforead), (USHORT) 0x00);
-#endif
 
 
 	our_target = (UCHAR)(RD_HARPOON(port+hp_select_id) >> 4);
-	currTar_Info = &sccbMgrTbl[p_card][our_target];
+	currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
 
 
 	msgRetryCount = 0;
 	do
 	{
 
-#if defined(V302)
-
-		message = GetTarLun(port, p_card, our_target, pCurrCard, &tag, &lun);
-
-#else /* V302 */
-
-		currTar_Info = &sccbMgrTbl[p_card][our_target];
+		currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
 		tag = 0;
 
 
@@ -6022,7 +3266,7 @@ void sres(ULONG port, UCHAR p_card, PSCC
 		if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) == S_MSGI_PH)
 		{
 
-			message = sfm(port,pCurrCard->currentSCCB);
+			message = FPT_sfm(port,pCurrCard->currentSCCB);
 			if (message)
 			{
 
@@ -6030,7 +3274,6 @@ void sres(ULONG port, UCHAR p_card, PSCC
 				{
 					lun = message & (UCHAR)LUN_MASK;
 
-#if !defined(DOS)
 					if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING)
 					{
 						if (currTar_Info->TarTagQ_Cnt != 0)
@@ -6041,21 +3284,21 @@ void sres(ULONG port, UCHAR p_card, PSCC
 								ACCEPT_MSG(port);    /*Release the ACK for ID msg. */
 
 
-								message = sfm(port,pCurrCard->currentSCCB);
+								message = FPT_sfm(port,pCurrCard->currentSCCB);
 								if (message)
 								{
 									ACCEPT_MSG(port);
 								}
 
 								else
-   								message = FALSE;
+   								message = 0;
 
-								if(message != FALSE)
+								if(message != 0)
 								{
-									tag = sfm(port,pCurrCard->currentSCCB);
+									tag = FPT_sfm(port,pCurrCard->currentSCCB);
 
 									if (!(tag)) 
-										message = FALSE;
+										message = 0;
 								}
 
 							} /*C.A. exists! */
@@ -6063,7 +3306,6 @@ void sres(ULONG port, UCHAR p_card, PSCC
 						} /*End Q cnt != 0 */
 
 					} /*End Tag cmds supported! */
-#endif /* !DOS */
 
 				} /*End valid ID message.  */
 
@@ -6078,7 +3320,7 @@ void sres(ULONG port, UCHAR p_card, PSCC
 			else
 			{
 
-				message = FALSE;
+				message = 0;
 			}
 		}
 		else
@@ -6091,49 +3333,47 @@ void sres(ULONG port, UCHAR p_card, PSCC
 
 			return;
 		}
-	
-#endif /* V302 */
 
-		if(message == FALSE)
+		if(message == 0)
 		{
 			msgRetryCount++;
 			if(msgRetryCount == 1)
 			{
-				SendMsg(port, SMPARITY);
+				FPT_SendMsg(port, SMPARITY);
 			}
 			else
 			{
-				SendMsg(port, SMDEV_RESET);
+				FPT_SendMsg(port, SMDEV_RESET);
 
-				sssyncv(port, our_target, NARROW_SCSI,currTar_Info);
+				FPT_sssyncv(port, our_target, NARROW_SCSI,currTar_Info);
 
-				if (sccbMgrTbl[p_card][our_target].TarEEValue & EE_SYNC_MASK) 
+				if (FPT_sccbMgrTbl[p_card][our_target].TarEEValue & EE_SYNC_MASK) 
 				{
 			
-					sccbMgrTbl[p_card][our_target].TarStatus &= ~TAR_SYNC_MASK;
+					FPT_sccbMgrTbl[p_card][our_target].TarStatus &= ~TAR_SYNC_MASK;
 
 				}
 
-				if (sccbMgrTbl[p_card][our_target].TarEEValue & EE_WIDE_SCSI) 
+				if (FPT_sccbMgrTbl[p_card][our_target].TarEEValue & EE_WIDE_SCSI) 
 				{
 
-					sccbMgrTbl[p_card][our_target].TarStatus &= ~TAR_WIDE_MASK;
+					FPT_sccbMgrTbl[p_card][our_target].TarStatus &= ~TAR_WIDE_MASK;
 				}
 
 
-				queueFlushTargSccb(p_card, our_target, SCCB_COMPLETE);
-				SccbMgrTableInitTarget(p_card,our_target);
+				FPT_queueFlushTargSccb(p_card, our_target, SCCB_COMPLETE);
+				FPT_SccbMgrTableInitTarget(p_card,our_target);
 				return;
 			}
 		}
-	}while(message == FALSE);
+	}while(message == 0);
 
 
 
 	if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
 		((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
 	{
-		currTar_Info->TarLUNBusy[lun] = TRUE;
+		currTar_Info->TarLUNBusy[lun] = 1;
 		pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[lun]];
 		if(pCurrCard->currentSCCB != NULL)
 		{
@@ -6146,7 +3386,7 @@ void sres(ULONG port, UCHAR p_card, PSCC
 	}
 	else
 	{
-		currTar_Info->TarLUNBusy[0] = TRUE;
+		currTar_Info->TarLUNBusy[0] = 1;
 
 
 		if (tag)
@@ -6182,7 +3422,7 @@ void sres(ULONG port, UCHAR p_card, PSCC
 		/* During Abort Tag command, the target could have got re-selected
 			and completed the command. Check the select Q and remove the CCB
 			if it is in the Select Q */
-			queueFindSccb(pCurrCard->currentSCCB, p_card);
+			FPT_queueFindSccb(pCurrCard->currentSCCB, p_card);
 		}
 	}
 
@@ -6192,106 +3432,7 @@ void sres(ULONG port, UCHAR p_card, PSCC
 	  (RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ;
 }
 
-#if defined(V302)
-
-#if defined(DOS)
-UCHAR GetTarLun(USHORT port, UCHAR p_card, UCHAR our_target, PSCCBcard pCurrCard, PUCHAR tag, PUCHAR lun)
-#else
-UCHAR GetTarLun(ULONG port, UCHAR p_card, UCHAR our_target, PSCCBcard pCurrCard, PUCHAR tag, PUCHAR lun)
-#endif
-{
-   UCHAR message;
-   PSCCBMgr_tar_info currTar_Info;
-
-
-	currTar_Info = &sccbMgrTbl[p_card][our_target];
-	*tag = 0;
-
-
-	while(!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ))
-	{
-		if (! (RD_HARPOON(port+hp_scsisig) & SCSI_BSY))
-		{
-
-			WRW_HARPOON((port+hp_intstat), PHASE);
-			return(TRUE);
-		}
-	}
-
-	WRW_HARPOON((port+hp_intstat), PHASE);
-	if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) == S_MSGI_PH)
-	{
-
-		message = sfm(port,pCurrCard->currentSCCB);
-		if (message)
-		{
-
-			if (message <= (0x80 | LUN_MASK))
-			{
-				*lun = message & (UCHAR)LUN_MASK;
-
-#if !defined(DOS)
-				if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING)
-				{
-					if (currTar_Info->TarTagQ_Cnt != 0)
-					{
-
-						if (!(currTar_Info->TarLUN_CA))
-						{
-							ACCEPT_MSG(port);    /*Release the ACK for ID msg. */
-
-
-							message = sfm(port,pCurrCard->currentSCCB);
-							if (message)
-							{
-								ACCEPT_MSG(port);
-							}
-
-							else
-   							return(FALSE);
-
-							*tag = sfm(port,pCurrCard->currentSCCB);
-
-							if (!(*tag)) return(FALSE);
-
-						} /*C.A. exists! */
-
-					} /*End Q cnt != 0 */
-
-				} /*End Tag cmds supported! */
-#endif /* !DOS */
-
-			} /*End valid ID message.  */
-
-			else
-			{
-
-				ACCEPT_MSG_ATN(port);
-			}
-
-		} /* End good id message. */
-
-		else
-		{
-
-			return(FALSE);
-		}
-	}
-	else
-	{
-		ACCEPT_MSG_ATN(port);
-		return(TRUE);
-	}
-	return(TRUE);
-}
-
-#endif /* V302 */
-
-#if defined(DOS)
-void SendMsg(USHORT port, UCHAR message)
-#else
-void SendMsg(ULONG port, UCHAR message)
-#endif
+static void FPT_SendMsg(ULONG port, UCHAR message)
 {
 	while(!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ))
 	{
@@ -6334,26 +3475,22 @@ void SendMsg(ULONG port, UCHAR message)
 
 /*---------------------------------------------------------------------
  *
- * Function: sdecm
+ * Function: FPT_sdecm
  *
  * Description: Determine the proper responce to the message from the
  *              target device.
  *
  *---------------------------------------------------------------------*/
-#if defined(DOS)
-void sdecm(UCHAR message, USHORT port, UCHAR p_card)
-#else
-void sdecm(UCHAR message, ULONG port, UCHAR p_card)
-#endif
+static void FPT_sdecm(UCHAR message, ULONG port, UCHAR p_card)
 {
 	PSCCB currSCCB;
 	PSCCBcard CurrCard;
 	PSCCBMgr_tar_info currTar_Info;
 
-	CurrCard = &BL_Card[p_card];
+	CurrCard = &FPT_BL_Card[p_card];
 	currSCCB = CurrCard->currentSCCB;
 
-	currTar_Info = &sccbMgrTbl[p_card][currSCCB->TargID];
+	currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
 
 	if (message == SMREST_DATA_PTR)
 	{
@@ -6361,7 +3498,7 @@ void sdecm(UCHAR message, ULONG port, UC
 		{
 			currSCCB->Sccb_ATC = currSCCB->Sccb_savedATC;
 
-			hostDataXferRestart(currSCCB);
+			FPT_hostDataXferRestart(currSCCB);
 		}
 
 		ACCEPT_MSG(port);
@@ -6417,7 +3554,6 @@ void sdecm(UCHAR message, ULONG port, UC
 					currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
 				}
 
-#if defined(WIDE_SCSI)
 				else if ((currSCCB->Sccb_scsistat == SELECT_WN_ST))
 				{
 
@@ -6428,7 +3564,6 @@ void sdecm(UCHAR message, ULONG port, UC
 					currTar_Info->TarEEValue &= ~EE_WIDE_SCSI;
 
 				}
-#endif
 
 				else if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING )
 				{
@@ -6460,9 +3595,9 @@ void sdecm(UCHAR message, ULONG port, UC
 
 				if((CurrCard->globalFlags & F_CONLUN_IO) &&
 					((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
-					currTar_Info->TarLUNBusy[currSCCB->Lun] = TRUE;
+					currTar_Info->TarLUNBusy[currSCCB->Lun] = 1;
 				else
-					currTar_Info->TarLUNBusy[0] = TRUE;
+					currTar_Info->TarLUNBusy[0] = 1;
 
 
 				currSCCB->ControlByte &= ~(UCHAR)F_USE_CMD_Q;
@@ -6490,7 +3625,7 @@ void sdecm(UCHAR message, ULONG port, UC
 	{
 
 		ACCEPT_MSG(port);
-		shandem(port,p_card,currSCCB);
+		FPT_shandem(port,p_card,currSCCB);
 	}
 
 	else if (message == SMIGNORWR)
@@ -6498,7 +3633,7 @@ void sdecm(UCHAR message, ULONG port, UC
 
 		ACCEPT_MSG(port);          /* ACK the RESIDUE MSG */
 
-		message = sfm(port,currSCCB);
+		message = FPT_sfm(port,currSCCB);
 
 		if(currSCCB->Sccb_scsimsg != SMPARITY)
 			ACCEPT_MSG(port);
@@ -6520,25 +3655,21 @@ void sdecm(UCHAR message, ULONG port, UC
 
 /*---------------------------------------------------------------------
  *
- * Function: shandem
+ * Function: FPT_shandem
  *
  * Description: Decide what to do with the extended message.
  *
  *---------------------------------------------------------------------*/
-#if defined(DOS)
-void shandem(USHORT port, UCHAR p_card, PSCCB pCurrSCCB)
-#else
-void shandem(ULONG port, UCHAR p_card, PSCCB pCurrSCCB)
-#endif
+static void FPT_shandem(ULONG port, UCHAR p_card, PSCCB pCurrSCCB)
 {
 	UCHAR length,message;
 
-	length = sfm(port,pCurrSCCB);
+	length = FPT_sfm(port,pCurrSCCB);
 	if (length) 
 	{
 
 		ACCEPT_MSG(port);
-		message = sfm(port,pCurrSCCB);
+		message = FPT_sfm(port,pCurrSCCB);
 		if (message) 
 		{
 
@@ -6549,7 +3680,7 @@ void shandem(ULONG port, UCHAR p_card, P
 				{
 
 					ACCEPT_MSG(port);
-					stsyncn(port,p_card);
+					FPT_stsyncn(port,p_card);
 				}
 				else 
 				{
@@ -6558,7 +3689,6 @@ void shandem(ULONG port, UCHAR p_card, P
 					ACCEPT_MSG_ATN(port);
 				}
 			}
-#if defined(WIDE_SCSI)
 			else if (message == SMWDTR) 
 			{
 
@@ -6566,7 +3696,7 @@ void shandem(ULONG port, UCHAR p_card, P
 				{
 
 					ACCEPT_MSG(port);
-					stwidn(port,p_card);
+					FPT_stwidn(port,p_card);
 				}
 				else 
 				{
@@ -6577,7 +3707,6 @@ void shandem(ULONG port, UCHAR p_card, P
 					WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
 				}
 			}
-#endif
 			else 
 			{
 
@@ -6603,24 +3732,20 @@ void shandem(ULONG port, UCHAR p_card, P
 
 /*---------------------------------------------------------------------
  *
- * Function: sisyncn
+ * Function: FPT_sisyncn
  *
  * Description: Read in a message byte from the SCSI bus, and check
  *              for a parity error.
  *
  *---------------------------------------------------------------------*/
 
-#if defined(DOS)
-UCHAR sisyncn(USHORT port, UCHAR p_card, UCHAR syncFlag)
-#else
-UCHAR sisyncn(ULONG port, UCHAR p_card, UCHAR syncFlag)
-#endif
+static UCHAR FPT_sisyncn(ULONG port, UCHAR p_card, UCHAR syncFlag)
 {
    PSCCB currSCCB;
    PSCCBMgr_tar_info currTar_Info;
 
-   currSCCB = BL_Card[p_card].currentSCCB;
-   currTar_Info = &sccbMgrTbl[p_card][currSCCB->TargID];
+   currSCCB = FPT_BL_Card[p_card].currentSCCB;
+   currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
 
    if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING)) {
 
@@ -6656,7 +3781,7 @@ UCHAR sisyncn(ULONG port, UCHAR p_card, 
       WRW_HARPOON((port+SYNC_MSGS+12),(BRH_OP+ALWAYS+NP      ));
 
 
-		if(syncFlag == FALSE)
+		if(syncFlag == 0)
 		{
 		   WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
 	      currTar_Info->TarStatus = ((currTar_Info->TarStatus &
@@ -6668,14 +3793,14 @@ UCHAR sisyncn(ULONG port, UCHAR p_card, 
 		}
 
 
-      return(TRUE);
+      return(1);
       }
 
    else {
 
       currTar_Info->TarStatus |=	 (UCHAR)SYNC_SUPPORTED;
       currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
-      return(FALSE);
+      return(0);
       }
 }
 
@@ -6683,26 +3808,22 @@ UCHAR sisyncn(ULONG port, UCHAR p_card, 
 
 /*---------------------------------------------------------------------
  *
- * Function: stsyncn
+ * Function: FPT_stsyncn
  *
  * Description: The has sent us a Sync Nego message so handle it as
  *              necessary.
  *
  *---------------------------------------------------------------------*/
-#if defined(DOS)
-void stsyncn(USHORT port, UCHAR p_card)
-#else
-void stsyncn(ULONG port, UCHAR p_card)
-#endif
+static void FPT_stsyncn(ULONG port, UCHAR p_card)
 {
    UCHAR sync_msg,offset,sync_reg,our_sync_msg;
    PSCCB currSCCB;
    PSCCBMgr_tar_info currTar_Info;
 
-   currSCCB = BL_Card[p_card].currentSCCB;
-   currTar_Info = &sccbMgrTbl[p_card][currSCCB->TargID];
+   currSCCB = FPT_BL_Card[p_card].currentSCCB;
+   currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
 
-   sync_msg = sfm(port,currSCCB);
+   sync_msg = FPT_sfm(port,currSCCB);
 
 	if((sync_msg == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
 	{
@@ -6713,7 +3834,7 @@ void stsyncn(ULONG port, UCHAR p_card)
    ACCEPT_MSG(port);
 
 
-   offset = sfm(port,currSCCB);
+   offset = FPT_sfm(port,currSCCB);
 
 	if((offset == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
 	{
@@ -6783,7 +3904,6 @@ void stsyncn(ULONG port, UCHAR p_card)
       }
 
 
-#if defined(WIDE_SCSI)
    if (currTar_Info->TarStatus & WIDE_ENABLED)
 
       sync_reg |= offset;
@@ -6792,11 +3912,7 @@ void stsyncn(ULONG port, UCHAR p_card)
 
       sync_reg |= (offset | NARROW_SCSI);
 
-#else
-   sync_reg |= (offset | NARROW_SCSI);
-#endif
-
-   sssyncv(port,currSCCB->TargID,sync_reg,currTar_Info);
+   FPT_sssyncv(port,currSCCB->TargID,sync_reg,currTar_Info);
 
 
    if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
@@ -6815,7 +3931,7 @@ void stsyncn(ULONG port, UCHAR p_card)
 
       ACCEPT_MSG_ATN(port);
 
-      sisyncr(port,sync_msg,offset);
+      FPT_sisyncr(port,sync_msg,offset);
 
       currTar_Info->TarStatus = ((currTar_Info->TarStatus &
          ~(UCHAR)TAR_SYNC_MASK) | (UCHAR)SYNC_SUPPORTED);
@@ -6825,16 +3941,12 @@ void stsyncn(ULONG port, UCHAR p_card)
 
 /*---------------------------------------------------------------------
  *
- * Function: sisyncr
+ * Function: FPT_sisyncr
  *
  * Description: Answer the targets sync message.
  *
  *---------------------------------------------------------------------*/
-#if defined(DOS)
-void sisyncr(USHORT port,UCHAR sync_pulse, UCHAR offset)
-#else
-void sisyncr(ULONG port,UCHAR sync_pulse, UCHAR offset)
-#endif
+static void FPT_sisyncr(ULONG port,UCHAR sync_pulse, UCHAR offset)
 {
    ARAM_ACCESS(port);
    WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
@@ -6856,28 +3968,22 @@ void sisyncr(ULONG port,UCHAR sync_pulse
 
 
 
-#if defined(WIDE_SCSI)
-
 /*---------------------------------------------------------------------
  *
- * Function: siwidn
+ * Function: FPT_siwidn
  *
  * Description: Read in a message byte from the SCSI bus, and check
  *              for a parity error.
  *
  *---------------------------------------------------------------------*/
 
-#if defined(DOS)
-UCHAR siwidn(USHORT port, UCHAR p_card)
-#else
-UCHAR siwidn(ULONG port, UCHAR p_card)
-#endif
+static UCHAR FPT_siwidn(ULONG port, UCHAR p_card)
 {
    PSCCB currSCCB;
    PSCCBMgr_tar_info currTar_Info;
 
-   currSCCB = BL_Card[p_card].currentSCCB;
-   currTar_Info = &sccbMgrTbl[p_card][currSCCB->TargID];
+   currSCCB = FPT_BL_Card[p_card].currentSCCB;
+   currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
 
    if (!((currTar_Info->TarStatus & TAR_WIDE_MASK) == WIDE_NEGOCIATED)) {
 
@@ -6900,7 +4006,7 @@ UCHAR siwidn(ULONG port, UCHAR p_card)
       currTar_Info->TarStatus = ((currTar_Info->TarStatus &
          ~(UCHAR)TAR_WIDE_MASK) | (UCHAR)WIDE_ENABLED);
 
-      return(TRUE);
+      return(1);
       }
 
    else {
@@ -6909,7 +4015,7 @@ UCHAR siwidn(ULONG port, UCHAR p_card)
                ~(UCHAR)TAR_WIDE_MASK) | WIDE_NEGOCIATED);
 
       currTar_Info->TarEEValue &= ~EE_WIDE_SCSI;
-      return(FALSE);
+      return(0);
       }
 }
 
@@ -6917,26 +4023,22 @@ UCHAR siwidn(ULONG port, UCHAR p_card)
 
 /*---------------------------------------------------------------------
  *
- * Function: stwidn
+ * Function: FPT_stwidn
  *
  * Description: The has sent us a Wide Nego message so handle it as
  *              necessary.
  *
  *---------------------------------------------------------------------*/
-#if defined(DOS)
-void stwidn(USHORT port, UCHAR p_card)
-#else
-void stwidn(ULONG port, UCHAR p_card)
-#endif
+static void FPT_stwidn(ULONG port, UCHAR p_card)
 {
    UCHAR width;
    PSCCB currSCCB;
    PSCCBMgr_tar_info currTar_Info;
 
-   currSCCB = BL_Card[p_card].currentSCCB;
-   currTar_Info = &sccbMgrTbl[p_card][currSCCB->TargID];
+   currSCCB = FPT_BL_Card[p_card].currentSCCB;
+   currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
 
-   width = sfm(port,currSCCB);
+   width = FPT_sfm(port,currSCCB);
 
 	if((width == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
 	{
@@ -6958,7 +4060,7 @@ void stwidn(ULONG port, UCHAR p_card)
       }
 
 
-   sssyncv(port,currSCCB->TargID,width,currTar_Info);
+   FPT_sssyncv(port,currSCCB->TargID,width,currTar_Info);
 
 
    if (currSCCB->Sccb_scsistat == SELECT_WN_ST)
@@ -6972,7 +4074,7 @@ void stwidn(ULONG port, UCHAR p_card)
 		{
 	      ACCEPT_MSG_ATN(port);
 		   ARAM_ACCESS(port);
-	     	sisyncn(port,p_card, TRUE);
+	     	FPT_sisyncn(port,p_card, 1);
 	      currSCCB->Sccb_scsistat = SELECT_SN_ST;
 		   SGRAM_ACCESS(port);
 		}
@@ -6993,7 +4095,7 @@ void stwidn(ULONG port, UCHAR p_card)
       else
       	 width = SM8BIT;
 
-      siwidr(port,width);
+      FPT_siwidr(port,width);
 
       currTar_Info->TarStatus |= (WIDE_NEGOCIATED | WIDE_ENABLED);
       }
@@ -7002,16 +4104,12 @@ void stwidn(ULONG port, UCHAR p_card)
 
 /*---------------------------------------------------------------------
  *
- * Function: siwidr
+ * Function: FPT_siwidr
  *
  * Description: Answer the targets Wide nego message.
  *
  *---------------------------------------------------------------------*/
-#if defined(DOS)
-void siwidr(USHORT port, UCHAR width)
-#else
-void siwidr(ULONG port, UCHAR width)
-#endif
+static void FPT_siwidr(ULONG port, UCHAR width)
 {
    ARAM_ACCESS(port);
    WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
@@ -7030,23 +4128,18 @@ void siwidr(ULONG port, UCHAR width)
    while (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | AUTO_INT))) {}
 }
 
-#endif
-
 
 
 /*---------------------------------------------------------------------
  *
- * Function: sssyncv
+ * Function: FPT_sssyncv
  *
  * Description: Write the desired value to the Sync Register for the
  *              ID specified.
  *
  *---------------------------------------------------------------------*/
-#if defined(DOS)
-void sssyncv(USHORT p_port, UCHAR p_id, UCHAR p_sync_value,PSCCBMgr_tar_info currTar_Info)
-#else
-void sssyncv(ULONG p_port, UCHAR p_id, UCHAR p_sync_value,PSCCBMgr_tar_info currTar_Info)
-#endif
+static void FPT_sssyncv(ULONG p_port, UCHAR p_id, UCHAR p_sync_value,
+			PSCCBMgr_tar_info currTar_Info)
 {
    UCHAR index;
 
@@ -7112,16 +4205,12 @@ void sssyncv(ULONG p_port, UCHAR p_id, U
 
 /*---------------------------------------------------------------------
  *
- * Function: sresb
+ * Function: FPT_sresb
  *
  * Description: Reset the desired card's SCSI bus.
  *
  *---------------------------------------------------------------------*/
-#if defined(DOS)
-void sresb(USHORT port, UCHAR p_card)
-#else
-void sresb(ULONG port, UCHAR p_card)
-#endif
+static void FPT_sresb(ULONG port, UCHAR p_card)
 {
    UCHAR scsiID, i;
 
@@ -7145,7 +4234,7 @@ void sresb(ULONG port, UCHAR p_card)
 
    WR_HARPOON(port+hp_scsictrl_0, ENA_SCAM_SEL);
 
-   Wait(port, TO_5ms);
+   FPT_Wait(port, TO_5ms);
 
    WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
 
@@ -7153,7 +4242,7 @@ void sresb(ULONG port, UCHAR p_card)
 
    for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++)
       {
-      currTar_Info = &sccbMgrTbl[p_card][scsiID];
+      currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
 
       if (currTar_Info->TarEEValue & EE_SYNC_MASK)
          {
@@ -7166,21 +4255,21 @@ void sresb(ULONG port, UCHAR p_card)
       	currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
       	}
 
-      sssyncv(port, scsiID, NARROW_SCSI,currTar_Info);
+      FPT_sssyncv(port, scsiID, NARROW_SCSI,currTar_Info);
 
-      SccbMgrTableInitTarget(p_card, scsiID);
+      FPT_SccbMgrTableInitTarget(p_card, scsiID);
       }
 
-   BL_Card[p_card].scanIndex = 0x00;
-   BL_Card[p_card].currentSCCB = NULL;
-   BL_Card[p_card].globalFlags &= ~(F_TAG_STARTED | F_HOST_XFER_ACT 
+   FPT_BL_Card[p_card].scanIndex = 0x00;
+   FPT_BL_Card[p_card].currentSCCB = NULL;
+   FPT_BL_Card[p_card].globalFlags &= ~(F_TAG_STARTED | F_HOST_XFER_ACT 
 													| F_NEW_SCCB_CMD);
-   BL_Card[p_card].cmdCounter  = 0x00;
-	BL_Card[p_card].discQCount = 0x00;
-   BL_Card[p_card].tagQ_Lst = 0x01; 
+   FPT_BL_Card[p_card].cmdCounter  = 0x00;
+	FPT_BL_Card[p_card].discQCount = 0x00;
+   FPT_BL_Card[p_card].tagQ_Lst = 0x01; 
 
 	for(i = 0; i < QUEUE_DEPTH; i++)
-		BL_Card[p_card].discQ_Tbl[i] = NULL;
+		FPT_BL_Card[p_card].discQ_Tbl[i] = NULL;
 
    WR_HARPOON(port+hp_page_ctrl,
       (RD_HARPOON(port+hp_page_ctrl) & ~G_INT_DISABLE));
@@ -7189,12 +4278,12 @@ void sresb(ULONG port, UCHAR p_card)
 
 /*---------------------------------------------------------------------
  *
- * Function: ssenss
+ * Function: FPT_ssenss
  *
  * Description: Setup for the Auto Sense command.
  *
  *---------------------------------------------------------------------*/
-void ssenss(PSCCBcard pCurrCard)
+static void FPT_ssenss(PSCCBcard pCurrCard)
 {
    UCHAR i;
    PSCCB currSCCB;
@@ -7236,27 +4325,23 @@ void ssenss(PSCCBcard pCurrCard)
 
 /*---------------------------------------------------------------------
  *
- * Function: sxfrp
+ * Function: FPT_sxfrp
  *
  * Description: Transfer data into the bit bucket until the device
  *              decides to switch phase.
  *
  *---------------------------------------------------------------------*/
 
-#if defined(DOS)
-void sxfrp(USHORT p_port, UCHAR p_card)
-#else
-void sxfrp(ULONG p_port, UCHAR p_card)
-#endif
+static void FPT_sxfrp(ULONG p_port, UCHAR p_card)
 {
    UCHAR curr_phz;
 
 
    DISABLE_AUTO(p_port);
 
-   if (BL_Card[p_card].globalFlags & F_HOST_XFER_ACT) {
+   if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT) {
 
-      hostDataXferAbort(p_port,p_card,BL_Card[p_card].currentSCCB);
+      FPT_hostDataXferAbort(p_port,p_card,FPT_BL_Card[p_card].currentSCCB);
 
       }
 
@@ -7322,25 +4407,21 @@ void sxfrp(ULONG p_port, UCHAR p_card)
 
 /*---------------------------------------------------------------------
  *
- * Function: schkdd
+ * Function: FPT_schkdd
  *
  * Description: Make sure data has been flushed from both FIFOs and abort
  *              the operations if necessary.
  *
  *---------------------------------------------------------------------*/
 
-#if defined(DOS)
-void schkdd(USHORT port, UCHAR p_card)
-#else
-void schkdd(ULONG port, UCHAR p_card)
-#endif
+static void FPT_schkdd(ULONG port, UCHAR p_card)
 {
    USHORT TimeOutLoop;
 	UCHAR sPhase;
 
    PSCCB currSCCB;
 
-   currSCCB = BL_Card[p_card].currentSCCB;
+   currSCCB = FPT_BL_Card[p_card].currentSCCB;
 
 
    if ((currSCCB->Sccb_scsistat != DATA_OUT_ST) &&
@@ -7378,7 +4459,7 @@ void schkdd(ULONG port, UCHAR p_card)
       }
 
 
-   hostDataXferAbort(port,p_card,currSCCB);
+   FPT_hostDataXferAbort(port,p_card,currSCCB);
 
 
    while (RD_HARPOON(port+hp_scsisig) & SCSI_ACK) {}
@@ -7412,21 +4493,21 @@ void schkdd(ULONG port, UCHAR p_card)
 	   if (!(currSCCB->Sccb_XferState & F_ALL_XFERRED))
          {
 	      if (currSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
-	         phaseDataIn(port,p_card);
+	         FPT_phaseDataIn(port,p_card);
 	      	}
 
 	   	else {
-	       phaseDataOut(port,p_card);
+	       FPT_phaseDataOut(port,p_card);
 	       	}
 	   	}
 		else
       	{
-	   	sxfrp(port,p_card);
+	   	FPT_sxfrp(port,p_card);
 	   	if (!(RDW_HARPOON((port+hp_intstat)) &
 		      (BUS_FREE | ICMD_COMP | ITAR_DISC | RESET)))
          {
    		WRW_HARPOON((port+hp_intstat), AUTO_INT);
-		   phaseDecode(port,p_card);
+		   FPT_phaseDecode(port,p_card);
 		   }
 	   }
 
@@ -7440,13 +4521,13 @@ void schkdd(ULONG port, UCHAR p_card)
 
 /*---------------------------------------------------------------------
  *
- * Function: sinits
+ * Function: FPT_sinits
  *
  * Description: Setup SCCB manager fields in this SCCB.
  *
  *---------------------------------------------------------------------*/
 
-void sinits(PSCCB p_sccb, UCHAR p_card)
+static void FPT_sinits(PSCCB p_sccb, UCHAR p_card)
 {
    PSCCBMgr_tar_info currTar_Info;
 
@@ -7454,7 +4535,7 @@ void sinits(PSCCB p_sccb, UCHAR p_card)
 	{
 		return;
 	}
-   currTar_Info = &sccbMgrTbl[p_card][p_sccb->TargID];
+   currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
 
    p_sccb->Sccb_XferState     = 0x00;
    p_sccb->Sccb_XferCnt       = p_sccb->DataLength;
@@ -7485,7 +4566,7 @@ void sinits(PSCCB p_sccb, UCHAR p_card)
 	else send Cmd with Disconnect Disable */
 
 /*
-   if (((!(BL_Card[p_card].globalFlags & F_SINGLE_DEVICE)) &&
+   if (((!(FPT_BL_Card[p_card].globalFlags & F_SINGLE_DEVICE)) &&
       (currTar_Info->TarStatus & TAR_ALLOW_DISC)) ||
       (currTar_Info->TarStatus & TAG_Q_TRYING)) {
 */
@@ -7518,55 +4599,6 @@ void sinits(PSCCB p_sccb, UCHAR p_card)
 }
 
 
-#ident "$Id: phase.c 1.11 1997/01/31 02:08:49 mohan Exp $"
-/*----------------------------------------------------------------------
- *
- *
- *   Copyright 1995-1996 by Mylex Corporation.  All Rights Reserved
- *
- *   This file is available under both the GNU General Public License
- *   and a BSD-style copyright; see LICENSE.FlashPoint for details.
- *
- *   $Workfile:   phase.c  $
- *
- *   Description:  Functions to initially handle the SCSI bus phase when
- *                 the target asserts request (and the automation is not
- *                 enabled to handle the situation).
- *
- *   $Date: 1997/01/31 02:08:49 $
- *
- *   $Revision: 1.11 $
- *
- *----------------------------------------------------------------------*/
-
-/*#include <globals.h>*/
-
-#if (FW_TYPE==_UCB_MGR_)
-	/*#include <budi.h>*/
-#endif
-
-/*#include <sccbmgr.h>*/
-/*#include <blx30.h>*/
-/*#include <target.h>*/
-/*#include <scsi2.h>*/
-/*#include <harpoon.h>*/
-
-
-/*
-extern SCCBCARD BL_Card[MAX_CARDS];
-extern SCCBMGR_TAR_INFO sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR];
-
-#if defined(OS2)
-   extern void (far *s_PhaseTbl[8]) (ULONG, UCHAR);
-#else
-   #if defined(DOS)
-      extern void (*s_PhaseTbl[8]) (USHORT, UCHAR);
-   #else
-      extern void (*s_PhaseTbl[8]) (ULONG, UCHAR);
-   #endif
-#endif
-*/
-
 /*---------------------------------------------------------------------
  *
  * Function: Phase Decode
@@ -7575,29 +4607,17 @@ extern SCCBMGR_TAR_INFO sccbMgrTbl[MAX_C
  *
  *---------------------------------------------------------------------*/
 
-#if defined(DOS)
-void phaseDecode(USHORT p_port, UCHAR p_card)
-#else
-void phaseDecode(ULONG p_port, UCHAR p_card)
-#endif
+static void FPT_phaseDecode(ULONG p_port, UCHAR p_card)
 {
    unsigned char phase_ref;
-#if defined(OS2)
-   void (far *phase) (ULONG, UCHAR);
-#else
-   #if defined(DOS)
-      void (*phase) (USHORT, UCHAR);
-   #else
-      void (*phase) (ULONG, UCHAR);
-   #endif
-#endif
+   void (*phase) (ULONG, UCHAR);
 
 
    DISABLE_AUTO(p_port);
 
    phase_ref = (UCHAR) (RD_HARPOON(p_port+hp_scsisig) & S_SCSI_PHZ);
 
-   phase = s_PhaseTbl[phase_ref];
+   phase = FPT_s_PhaseTbl[phase_ref];
 
    (*phase)(p_port, p_card);           /* Call the correct phase func */
 }
@@ -7612,20 +4632,12 @@ void phaseDecode(ULONG p_port, UCHAR p_c
  *
  *---------------------------------------------------------------------*/
 
-#if defined(OS2)
-void far phaseDataOut(ULONG port, UCHAR p_card)
-#else
-#if defined(DOS)
-void phaseDataOut(USHORT port, UCHAR p_card)
-#else
-void phaseDataOut(ULONG port, UCHAR p_card)
-#endif
-#endif
+static void FPT_phaseDataOut(ULONG port, UCHAR p_card)
 {
 
    PSCCB currSCCB;
 
-   currSCCB = BL_Card[p_card].currentSCCB;
+   currSCCB = FPT_BL_Card[p_card].currentSCCB;
    if (currSCCB == NULL)
       {
       return;  /* Exit if No SCCB record */
@@ -7640,14 +4652,7 @@ void phaseDataOut(ULONG port, UCHAR p_ca
 
    WR_HARPOON(port+hp_autostart_0, (END_DATA+END_DATA_START));
 
-   dataXferProcessor(port, &BL_Card[p_card]);
-
-#if defined(NOBUGBUG)
-   if (RDW_HARPOON((port+hp_intstat)) & XFER_CNT_0)
-      WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
-
-#endif
-
+   FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
 
    if (currSCCB->Sccb_XferCnt == 0) {
 
@@ -7656,9 +4661,9 @@ void phaseDataOut(ULONG port, UCHAR p_ca
 	 (currSCCB->HostStatus == SCCB_COMPLETE))
 	 currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
 
-      sxfrp(port,p_card);
+      FPT_sxfrp(port,p_card);
       if (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | RESET)))
-	    phaseDecode(port,p_card);
+	    FPT_phaseDecode(port,p_card);
       }
 }
 
@@ -7671,20 +4676,12 @@ void phaseDataOut(ULONG port, UCHAR p_ca
  *
  *---------------------------------------------------------------------*/
 
-#if defined(OS2)
-void far phaseDataIn(ULONG port, UCHAR p_card)
-#else
-#if defined(DOS)
-void phaseDataIn(USHORT port, UCHAR p_card)
-#else
-void phaseDataIn(ULONG port, UCHAR p_card)
-#endif
-#endif
+static void FPT_phaseDataIn(ULONG port, UCHAR p_card)
 {
 
    PSCCB currSCCB;
 
-   currSCCB = BL_Card[p_card].currentSCCB;
+   currSCCB = FPT_BL_Card[p_card].currentSCCB;
 
    if (currSCCB == NULL)
       {
@@ -7702,7 +4699,7 @@ void phaseDataIn(ULONG port, UCHAR p_car
 
    WR_HARPOON(port+hp_autostart_0, (END_DATA+END_DATA_START));
 
-   dataXferProcessor(port, &BL_Card[p_card]);
+   FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
 
    if (currSCCB->Sccb_XferCnt == 0) {
 
@@ -7711,9 +4708,9 @@ void phaseDataIn(ULONG port, UCHAR p_car
 	 (currSCCB->HostStatus == SCCB_COMPLETE))
 	 currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
 
-      sxfrp(port,p_card);
+      FPT_sxfrp(port,p_card);
       if (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | RESET)))
-	    phaseDecode(port,p_card);
+	    FPT_phaseDecode(port,p_card);
 
       }
 }
@@ -7726,25 +4723,13 @@ void phaseDataIn(ULONG port, UCHAR p_car
  *
  *---------------------------------------------------------------------*/
 
-#if defined(OS2)
-void far phaseCommand(ULONG p_port, UCHAR p_card)
-#else
-#if defined(DOS)
-void phaseCommand(USHORT p_port, UCHAR p_card)
-#else
-void phaseCommand(ULONG p_port, UCHAR p_card)
-#endif
-#endif
+static void FPT_phaseCommand(ULONG p_port, UCHAR p_card)
 {
    PSCCB currSCCB;
-#if defined(DOS)
-   USHORT cdb_reg;
-#else
    ULONG cdb_reg;
-#endif
    UCHAR i;
 
-   currSCCB = BL_Card[p_card].currentSCCB;
+   currSCCB = FPT_BL_Card[p_card].currentSCCB;
 
    if (currSCCB->OperationCode == RESET_COMMAND) {
 
@@ -7790,15 +4775,7 @@ void phaseCommand(ULONG p_port, UCHAR p_
  *
  *---------------------------------------------------------------------*/
 
-#if defined(OS2)
-void far phaseStatus(ULONG port, UCHAR p_card)
-#else
-#if defined(DOS)
-void phaseStatus(USHORT port, UCHAR p_card)
-#else
-void phaseStatus(ULONG port, UCHAR p_card)
-#endif
-#endif
+static void FPT_phaseStatus(ULONG port, UCHAR p_card)
 {
    /* Start-up the automation to finish off this command and let the
       isr handle the interrupt for command complete when it comes in.
@@ -7820,21 +4797,13 @@ void phaseStatus(ULONG port, UCHAR p_car
  *
  *---------------------------------------------------------------------*/
 
-#if defined(OS2)
-void far phaseMsgOut(ULONG port, UCHAR p_card)
-#else
-#if defined(DOS)
-void phaseMsgOut(USHORT port, UCHAR p_card)
-#else
-void phaseMsgOut(ULONG port, UCHAR p_card)
-#endif
-#endif
+static void FPT_phaseMsgOut(ULONG port, UCHAR p_card)
 {
 	UCHAR message,scsiID;
 	PSCCB currSCCB;
 	PSCCBMgr_tar_info currTar_Info;
 
-	currSCCB = BL_Card[p_card].currentSCCB;
+	currSCCB = FPT_BL_Card[p_card].currentSCCB;
 
 	if (currSCCB != NULL) {
 
@@ -7845,34 +4814,34 @@ void phaseMsgOut(ULONG port, UCHAR p_car
 		{
 
 
-			currTar_Info = &sccbMgrTbl[p_card][scsiID];
+			currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
 			currTar_Info->TarSyncCtrl = 0;
-			sssyncv(port, scsiID, NARROW_SCSI,currTar_Info);
+			FPT_sssyncv(port, scsiID, NARROW_SCSI,currTar_Info);
 
-			if (sccbMgrTbl[p_card][scsiID].TarEEValue & EE_SYNC_MASK) 
+			if (FPT_sccbMgrTbl[p_card][scsiID].TarEEValue & EE_SYNC_MASK) 
 			{
 
-				sccbMgrTbl[p_card][scsiID].TarStatus &= ~TAR_SYNC_MASK;
+				FPT_sccbMgrTbl[p_card][scsiID].TarStatus &= ~TAR_SYNC_MASK;
 
 			}
 
-			if (sccbMgrTbl[p_card][scsiID].TarEEValue & EE_WIDE_SCSI) 
+			if (FPT_sccbMgrTbl[p_card][scsiID].TarEEValue & EE_WIDE_SCSI) 
 			{
 
-				sccbMgrTbl[p_card][scsiID].TarStatus &= ~TAR_WIDE_MASK;
+				FPT_sccbMgrTbl[p_card][scsiID].TarStatus &= ~TAR_WIDE_MASK;
 			}
 
 
-			queueFlushSccb(p_card,SCCB_COMPLETE);
-			SccbMgrTableInitTarget(p_card,scsiID);
+			FPT_queueFlushSccb(p_card,SCCB_COMPLETE);
+			FPT_SccbMgrTableInitTarget(p_card,scsiID);
 		}
 		else if (currSCCB->Sccb_scsistat == ABORT_ST)
 		{
 			currSCCB->HostStatus = SCCB_COMPLETE;
-			if(BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] != NULL)
+			if(FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] != NULL)
 			{
-				BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
-				sccbMgrTbl[p_card][scsiID].TarTagQ_Cnt--;
+				FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
+				FPT_sccbMgrTbl[p_card][scsiID].TarTagQ_Cnt--;
 			}
 					
 		}
@@ -7885,7 +4854,7 @@ void phaseMsgOut(ULONG port, UCHAR p_car
 			{
 				currSCCB->Sccb_MGRFlags |= F_DEV_SELECTED;
 		
-				ssel(port,p_card);
+				FPT_ssel(port,p_card);
 				return;
 			}
 		}
@@ -7895,7 +4864,7 @@ void phaseMsgOut(ULONG port, UCHAR p_car
 
 			if (message == SMABORT)
 
-				queueFlushSccb(p_card,SCCB_COMPLETE);
+				FPT_queueFlushSccb(p_card,SCCB_COMPLETE);
 		}
 
 	}
@@ -7930,25 +4899,25 @@ void phaseMsgOut(ULONG port, UCHAR p_car
 			if (currSCCB != NULL) 
 			{
 
-				if((BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
-					((sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
-					sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = FALSE;
+				if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
+					((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
+					FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
 				else
-					sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = FALSE;
+					FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
 
-				queueCmdComplete(&BL_Card[p_card],currSCCB, p_card);
+				FPT_queueCmdComplete(&FPT_BL_Card[p_card],currSCCB, p_card);
 			}
 
 			else 
 			{
-				BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
+				FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
 			}
 		}
 
 		else 
 		{
 
-			sxfrp(port,p_card);
+			FPT_sxfrp(port,p_card);
 		}
 	}
 
@@ -7962,7 +4931,7 @@ void phaseMsgOut(ULONG port, UCHAR p_car
 		}
 		else
 		{
-			sxfrp(port,p_card);
+			FPT_sxfrp(port,p_card);
 		}
 	}
 }
@@ -7976,25 +4945,17 @@ void phaseMsgOut(ULONG port, UCHAR p_car
  *
  *---------------------------------------------------------------------*/
 
-#if defined(OS2)
-void far phaseMsgIn(ULONG port, UCHAR p_card)
-#else
-#if defined(DOS)
-void phaseMsgIn(USHORT port, UCHAR p_card)
-#else
-void phaseMsgIn(ULONG port, UCHAR p_card)
-#endif
-#endif
+static void FPT_phaseMsgIn(ULONG port, UCHAR p_card)
 {
 	UCHAR message;
 	PSCCB currSCCB;
 
-	currSCCB = BL_Card[p_card].currentSCCB;
+	currSCCB = FPT_BL_Card[p_card].currentSCCB;
 
-	if (BL_Card[p_card].globalFlags & F_HOST_XFER_ACT) 
+	if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT) 
 	{
 
-		phaseChkFifo(port, p_card);
+		FPT_phaseChkFifo(port, p_card);
 	}
 
 	message = RD_HARPOON(port+hp_scsidata_0);
@@ -8008,12 +4969,12 @@ void phaseMsgIn(ULONG port, UCHAR p_card
 	else 
 	{
 
-		message = sfm(port,currSCCB);
+		message = FPT_sfm(port,currSCCB);
 		if (message) 
 		{
 
 
-			sdecm(message,port,p_card);
+			FPT_sdecm(message,port,p_card);
 
 		}
 		else
@@ -8037,19 +4998,11 @@ void phaseMsgIn(ULONG port, UCHAR p_card
  *
  *---------------------------------------------------------------------*/
 
-#if defined(OS2)
-void far phaseIllegal(ULONG port, UCHAR p_card)
-#else
-#if defined(DOS)
-void phaseIllegal(USHORT port, UCHAR p_card)
-#else
-void phaseIllegal(ULONG port, UCHAR p_card)
-#endif
-#endif
+static void FPT_phaseIllegal(ULONG port, UCHAR p_card)
 {
    PSCCB currSCCB;
 
-   currSCCB = BL_Card[p_card].currentSCCB;
+   currSCCB = FPT_BL_Card[p_card].currentSCCB;
 
    WR_HARPOON(port+hp_scsisig, RD_HARPOON(port+hp_scsisig));
    if (currSCCB != NULL) {
@@ -8073,16 +5026,12 @@ void phaseIllegal(ULONG port, UCHAR p_ca
  *
  *---------------------------------------------------------------------*/
 
-#if defined(DOS)
-void phaseChkFifo(USHORT port, UCHAR p_card)
-#else
-void phaseChkFifo(ULONG port, UCHAR p_card)
-#endif
+static void FPT_phaseChkFifo(ULONG port, UCHAR p_card)
 {
    ULONG xfercnt;
    PSCCB currSCCB;
 
-   currSCCB = BL_Card[p_card].currentSCCB;
+   currSCCB = FPT_BL_Card[p_card].currentSCCB;
 
    if (currSCCB->Sccb_scsistat == DATA_IN_ST)
       {
@@ -8104,9 +5053,9 @@ void phaseChkFifo(ULONG port, UCHAR p_ca
 	         WRW_HARPOON((port+hp_intstat), PARITY);
 	         }
 
-	      hostDataXferAbort(port,p_card,currSCCB);
+	      FPT_hostDataXferAbort(port,p_card,currSCCB);
 
-	      dataXferProcessor(port, &BL_Card[p_card]);
+	      FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
 
 	      while((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) &&
 	         (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY)) {}
@@ -8116,22 +5065,7 @@ void phaseChkFifo(ULONG port, UCHAR p_ca
 
 
 
-#if defined(DOS)
-   asm { mov dx,port;
-      add dx,hp_xfercnt_2;
-      in  al,dx;
-      dec dx;
-      xor ah,ah;
-      mov word ptr xfercnt+2,ax;
-      in  al,dx;
-      dec dx;
-      mov ah,al;
-      in  al,dx;
-      mov word ptr xfercnt,ax;
-      }
-#else
    GET_XFER_CNT(port,xfercnt);
-#endif
 
 
    WR_HARPOON(port+hp_xfercnt_0, 0x00);
@@ -8151,7 +5085,7 @@ void phaseChkFifo(ULONG port, UCHAR p_ca
       }
 
 
-   hostDataXferAbort(port,p_card,currSCCB);
+   FPT_hostDataXferAbort(port,p_card,currSCCB);
 
 
    WR_HARPOON(port+hp_fifowrite, 0x00);
@@ -8170,15 +5104,11 @@ void phaseChkFifo(ULONG port, UCHAR p_ca
  *              because of command complete or from a disconnect.
  *
  *---------------------------------------------------------------------*/
-#if defined(DOS)
-void phaseBusFree(USHORT port, UCHAR p_card)
-#else
-void phaseBusFree(ULONG port, UCHAR p_card)
-#endif
+static void FPT_phaseBusFree(ULONG port, UCHAR p_card)
 {
    PSCCB currSCCB;
 
-   currSCCB = BL_Card[p_card].currentSCCB;
+   currSCCB = FPT_BL_Card[p_card].currentSCCB;
 
    if (currSCCB != NULL)
       {
@@ -8189,35 +5119,34 @@ void phaseBusFree(ULONG port, UCHAR p_ca
       if (currSCCB->OperationCode == RESET_COMMAND)
          {
 
-			if((BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
-				((sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
-	   		 sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = FALSE;
+			if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
+				((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
+	   		 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
 			else
-		   	 sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = FALSE;
+		   	 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
 
-	      queueCmdComplete(&BL_Card[p_card], currSCCB, p_card);
+	      FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
 
-	      queueSearchSelect(&BL_Card[p_card],p_card);
+	      FPT_queueSearchSelect(&FPT_BL_Card[p_card],p_card);
 
 	      }
 
       else if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
 	      {
-	      sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
+	      FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
 			         (UCHAR)SYNC_SUPPORTED;
-	      sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_SYNC_MASK;
+	      FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_SYNC_MASK;
 	      }
 
       else if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
 	      {
-	      sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
-		            (sccbMgrTbl[p_card][currSCCB->TargID].
+	      FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
+		            (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
 		   TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
 
-	      sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_WIDE_SCSI;
+	      FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_WIDE_SCSI;
 	      }
 
-#if !defined(DOS)
       else if(currSCCB->Sccb_scsistat == SELECT_Q_ST)
 	      {
 	      /* Make sure this is not a phony BUS_FREE.  If we were
@@ -8227,8 +5156,8 @@ void phaseBusFree(ULONG port, UCHAR p_ca
 	      if ((!(RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ||
 	         (RDW_HARPOON((port+hp_intstat)) & RSEL))
 	         {
-	         sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_TAG_Q_MASK;
-	         sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |= TAG_Q_REJECT;
+	         FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_TAG_Q_MASK;
+	         FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |= TAG_Q_REJECT;
 	         }
 
 	      else
@@ -8236,7 +5165,6 @@ void phaseBusFree(ULONG port, UCHAR p_ca
 	         return;
 	         }
          }
-#endif
 
       else
 	      {
@@ -8248,18 +5176,18 @@ void phaseBusFree(ULONG port, UCHAR p_ca
 	         currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
 	         }
 
-			if((BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
-				((sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
-	   		 sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = FALSE;
+			if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
+				((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
+	   		 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
 			else
-		   	 sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = FALSE;
+		   	 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
 
-	      queueCmdComplete(&BL_Card[p_card], currSCCB, p_card);
+	      FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
 	      return;
 	      }
 
 
-      BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
+      FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
 
       } /*end if !=null */
 }
@@ -8267,44 +5195,6 @@ void phaseBusFree(ULONG port, UCHAR p_ca
 
 
 
-#ident "$Id: automate.c 1.14 1997/01/31 02:11:46 mohan Exp $"
-/*----------------------------------------------------------------------
- *
- *
- *   Copyright 1995-1996 by Mylex Corporation.  All Rights Reserved
- *
- *   This file is available under both the GNU General Public License
- *   and a BSD-style copyright; see LICENSE.FlashPoint for details.
- *
- *   $Workfile:   automate.c  $
- *
- *   Description:  Functions relating to programming the automation of
- *                 the HARPOON.
- *
- *   $Date: 1997/01/31 02:11:46 $
- *
- *   $Revision: 1.14 $
- *
- *----------------------------------------------------------------------*/
-
-/*#include <globals.h>*/
-
-#if (FW_TYPE==_UCB_MGR_)
-	/*#include <budi.h>*/
-#endif
-
-/*#include <sccbmgr.h>*/
-/*#include <blx30.h>*/
-/*#include <target.h>*/
-/*#include <scsi2.h>*/
-/*#include <harpoon.h>*/
-
-/*
-extern SCCBCARD BL_Card[MAX_CARDS];
-extern SCCBMGR_TAR_INFO sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR];
-extern SCCBCARD BL_Card[MAX_CARDS];
-*/
-
 /*---------------------------------------------------------------------
  *
  * Function: Auto Load Default Map
@@ -8312,17 +5202,9 @@ extern SCCBCARD BL_Card[MAX_CARDS];
  * Description: Load the Automation RAM with the defualt map values.
  *
  *---------------------------------------------------------------------*/
-#if defined(DOS)
-void autoLoadDefaultMap(USHORT p_port)
-#else
-void autoLoadDefaultMap(ULONG p_port)
-#endif
+static void FPT_autoLoadDefaultMap(ULONG p_port)
 {
-#if defined(DOS)
-   USHORT map_addr;
-#else
    ULONG map_addr;
-#endif
 
    ARAM_ACCESS(p_port);
    map_addr = p_port + hp_aramBase;
@@ -8428,86 +5310,82 @@ void autoLoadDefaultMap(ULONG p_port)
  *
  *---------------------------------------------------------------------*/
 
-#if defined(DOS)
-void autoCmdCmplt(USHORT p_port, UCHAR p_card)
-#else
-void autoCmdCmplt(ULONG p_port, UCHAR p_card)
-#endif
+static void FPT_autoCmdCmplt(ULONG p_port, UCHAR p_card)
 {
    PSCCB currSCCB;
    UCHAR status_byte;
 
-   currSCCB = BL_Card[p_card].currentSCCB;
+   currSCCB = FPT_BL_Card[p_card].currentSCCB;
 
    status_byte = RD_HARPOON(p_port+hp_gp_reg_0);
 
-   sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA = FALSE;
+   FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA = 0;
 
    if (status_byte != SSGOOD) {
 
       if (status_byte == SSQ_FULL) {
 
 
-			if(((BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
-				((sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
+			if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
+				((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
 			{
-	         sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = TRUE;
-				if(BL_Card[p_card].discQCount != 0)
-					BL_Card[p_card].discQCount--;
-				BL_Card[p_card].discQ_Tbl[sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
+	         FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
+				if(FPT_BL_Card[p_card].discQCount != 0)
+					FPT_BL_Card[p_card].discQCount--;
+				FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
 			}
 			else
 			{
-	         sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = TRUE;
+	         FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
 				if(currSCCB->Sccb_tag)
 				{
-					if(BL_Card[p_card].discQCount != 0)
-						BL_Card[p_card].discQCount--;
-					BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
+					if(FPT_BL_Card[p_card].discQCount != 0)
+						FPT_BL_Card[p_card].discQCount--;
+					FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
 				}else
 				{
-					if(BL_Card[p_card].discQCount != 0)
-						BL_Card[p_card].discQCount--;
-					BL_Card[p_card].discQ_Tbl[sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
+					if(FPT_BL_Card[p_card].discQCount != 0)
+						FPT_BL_Card[p_card].discQCount--;
+					FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
 				}
 			}
 
          currSCCB->Sccb_MGRFlags |= F_STATUSLOADED;
 
-         queueSelectFail(&BL_Card[p_card],p_card);
+         FPT_queueSelectFail(&FPT_BL_Card[p_card],p_card);
 
          return;
          }
 
       if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
          {
-         sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
+         FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
             (UCHAR)SYNC_SUPPORTED;
 
-	      sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_SYNC_MASK;
-         BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
+	      FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_SYNC_MASK;
+         FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
 
-			if(((BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
-				((sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
+			if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
+				((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
 			{
-	         sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = TRUE;
-				if(BL_Card[p_card].discQCount != 0)
-					BL_Card[p_card].discQCount--;
-				BL_Card[p_card].discQ_Tbl[sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
+	         FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
+				if(FPT_BL_Card[p_card].discQCount != 0)
+					FPT_BL_Card[p_card].discQCount--;
+				FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
 			}
 			else
 			{
-	         sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = TRUE;
+	         FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
 				if(currSCCB->Sccb_tag)
 				{
-					if(BL_Card[p_card].discQCount != 0)
-						BL_Card[p_card].discQCount--;
-					BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
+					if(FPT_BL_Card[p_card].discQCount != 0)
+						FPT_BL_Card[p_card].discQCount--;
+					FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
 				}else
 				{
-					if(BL_Card[p_card].discQCount != 0)
-						BL_Card[p_card].discQCount--;
-					BL_Card[p_card].discQ_Tbl[sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
+					if(FPT_BL_Card[p_card].discQCount != 0)
+						FPT_BL_Card[p_card].discQCount--;
+					FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
 				}
 			}
          return;
@@ -8517,34 +5395,34 @@ void autoCmdCmplt(ULONG p_port, UCHAR p_
       if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
          {
 
-	      sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
-	         (sccbMgrTbl[p_card][currSCCB->TargID].
+	      FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
+	         (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
 	         TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
 
-	      sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_WIDE_SCSI;
-         BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
+	      FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_WIDE_SCSI;
+         FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
 
-			if(((BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
-				((sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
+			if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
+				((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
 			{
-	         sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = TRUE;
-				if(BL_Card[p_card].discQCount != 0)
-					BL_Card[p_card].discQCount--;
-				BL_Card[p_card].discQ_Tbl[sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
+	         FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
+				if(FPT_BL_Card[p_card].discQCount != 0)
+					FPT_BL_Card[p_card].discQCount--;
+				FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
 			}
 			else
 			{
-	         sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = TRUE;
+	         FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
 				if(currSCCB->Sccb_tag)
 				{
-					if(BL_Card[p_card].discQCount != 0)
-						BL_Card[p_card].discQCount--;
-					BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
+					if(FPT_BL_Card[p_card].discQCount != 0)
+						FPT_BL_Card[p_card].discQCount--;
+					FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
 				}else
 				{
-					if(BL_Card[p_card].discQCount != 0)
-						BL_Card[p_card].discQCount--;
-					BL_Card[p_card].discQ_Tbl[sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
+					if(FPT_BL_Card[p_card].discQCount != 0)
+						FPT_BL_Card[p_card].discQCount--;
+					FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
 				}
 			}
          return;
@@ -8553,15 +5431,15 @@ void autoCmdCmplt(ULONG p_port, UCHAR p_
      
 	   if (status_byte == SSCHECK) 
 		{
-			if(BL_Card[p_card].globalFlags & F_DO_RENEGO)
+			if(FPT_BL_Card[p_card].globalFlags & F_DO_RENEGO)
 			{
-				if (sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue & EE_SYNC_MASK)
+				if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue & EE_SYNC_MASK)
 				{
-					sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_SYNC_MASK;
+					FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_SYNC_MASK;
 				}
-				if (sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue & EE_WIDE_SCSI)
+				if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue & EE_WIDE_SCSI)
 				{
-					sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_WIDE_MASK;
+					FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_WIDE_MASK;
 				}
 			}
 		}
@@ -8573,135 +5451,61 @@ void autoCmdCmplt(ULONG p_port, UCHAR p_
 
          if (status_byte == SSCHECK) {
 
-            sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA
-               = TRUE;
+            FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA
+               = 1;
      
 
-#if (FW_TYPE==_SCCB_MGR_)
             if (currSCCB->RequestSenseLength != NO_AUTO_REQUEST_SENSE) {
 
                if (currSCCB->RequestSenseLength == 0)
                   currSCCB->RequestSenseLength = 14;
 
-               ssenss(&BL_Card[p_card]);
-               BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
+               FPT_ssenss(&FPT_BL_Card[p_card]);
+               FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
 
- 					if(((BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
-						((sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
+ 					if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
+						((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
 					{
-			         sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = TRUE;
-						if(BL_Card[p_card].discQCount != 0)
-							BL_Card[p_card].discQCount--;
-						BL_Card[p_card].discQ_Tbl[sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
+			         FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
+						if(FPT_BL_Card[p_card].discQCount != 0)
+							FPT_BL_Card[p_card].discQCount--;
+						FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
 					}
 					else
 					{
-	   		      sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = TRUE;
+	   		      FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
 						if(currSCCB->Sccb_tag)
 						{
-							if(BL_Card[p_card].discQCount != 0)
-								BL_Card[p_card].discQCount--;
-							BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
+							if(FPT_BL_Card[p_card].discQCount != 0)
+								FPT_BL_Card[p_card].discQCount--;
+							FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
 						}else
 						{
-							if(BL_Card[p_card].discQCount != 0)
-								BL_Card[p_card].discQCount--;
-							BL_Card[p_card].discQ_Tbl[sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
+							if(FPT_BL_Card[p_card].discQCount != 0)
+								FPT_BL_Card[p_card].discQCount--;
+							FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
 						}
 					}
                return;
                }
-#else
-				   if ((!(currSCCB->Sccb_ucb_ptr->UCB_opcode & OPC_NO_AUTO_SENSE)) &&
-			   		(currSCCB->RequestSenseLength))
-				   {
-				   	ssenss(&BL_Card[p_card]);
-				      BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
-
-						if(((BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
-							((sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
-						{
-	      			   sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = TRUE;
-							if(BL_Card[p_card].discQCount != 0)
-								BL_Card[p_card].discQCount--;
-							BL_Card[p_card].discQ_Tbl[sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
-						}
-						else
-						{
-	      			   sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = TRUE;
-							if(currSCCB->Sccb_tag)
-							{
-								if(BL_Card[p_card].discQCount != 0)
-									BL_Card[p_card].discQCount--;
-								BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
-							}else
-							{
-								if(BL_Card[p_card].discQCount != 0)
-									BL_Card[p_card].discQCount--;
-								BL_Card[p_card].discQ_Tbl[sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
-							}
-						}
-				      return;
-				   }
-
-#endif
             }
          }
       }
 
 
-	if((BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
-		((sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
-	   sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = FALSE;
+	if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
+		((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
+	   FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
 	else
-	   sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = FALSE;
+	   FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
 
 
-   queueCmdComplete(&BL_Card[p_card], currSCCB, p_card);
+   FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
 }
-#ident "$Id: busmstr.c 1.8 1997/01/31 02:10:27 mohan Exp $"
-/*----------------------------------------------------------------------
- *
- *
- *   Copyright 1995-1996 by Mylex Corporation.  All Rights Reserved
- *
- *   This file is available under both the GNU General Public License
- *   and a BSD-style copyright; see LICENSE.FlashPoint for details.
- *
- *   $Workfile:   busmstr.c  $
- *
- *   Description:  Functions to start, stop, and abort BusMaster operations.
- *
- *   $Date: 1997/01/31 02:10:27 $
- *
- *   $Revision: 1.8 $
- *
- *----------------------------------------------------------------------*/
-
-/*#include <globals.h>*/
-
-#if (FW_TYPE==_UCB_MGR_)
-	/*#include <budi.h>*/
-#endif
-
-/*#include <sccbmgr.h>*/
-/*#include <blx30.h>*/
-/*#include <target.h>*/
-/*#include <scsi2.h>*/
-/*#include <harpoon.h>*/
-
-
-/*
-extern SCCBCARD BL_Card[MAX_CARDS];
-extern SCCBMGR_TAR_INFO sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR];
-*/
 
 #define SHORT_WAIT   0x0000000F
 #define LONG_WAIT    0x0000FFFFL
 
-#if defined(BUGBUG)
-void Debug_Load(UCHAR p_card, UCHAR p_bug_data);
-#endif
 
 /*---------------------------------------------------------------------
  *
@@ -8721,11 +5525,7 @@ void Debug_Load(UCHAR p_card, UCHAR p_bu
  *              
  *---------------------------------------------------------------------*/
 
-#if defined(DOS)
-void dataXferProcessor(USHORT port, PSCCBcard pCurrCard)
-#else
-void dataXferProcessor(ULONG port, PSCCBcard pCurrCard)
-#endif
+static void FPT_dataXferProcessor(ULONG port, PSCCBcard pCurrCard)
 {
    PSCCB currSCCB;
 
@@ -8741,7 +5541,7 @@ void dataXferProcessor(ULONG port, PSCCB
  				}
 			pCurrCard->globalFlags |= F_HOST_XFER_ACT;
          
-         busMstrSGDataXferStart(port, currSCCB);
+         FPT_busMstrSGDataXferStart(port, currSCCB);
 			}
 
       else
@@ -8750,7 +5550,7 @@ void dataXferProcessor(ULONG port, PSCCB
 				{
 				pCurrCard->globalFlags |= F_HOST_XFER_ACT;
          
-         	busMstrDataXferStart(port, currSCCB);
+         	FPT_busMstrDataXferStart(port, currSCCB);
          	}
 			}
 }
@@ -8763,20 +5563,12 @@ void dataXferProcessor(ULONG port, PSCCB
  * Description:
  *
  *---------------------------------------------------------------------*/
-#if defined(DOS)
-void busMstrSGDataXferStart(USHORT p_port, PSCCB pcurrSCCB)
-#else
-void busMstrSGDataXferStart(ULONG p_port, PSCCB pcurrSCCB)
-#endif
+static void FPT_busMstrSGDataXferStart(ULONG p_port, PSCCB pcurrSCCB)
 {
    ULONG count,addr,tmpSGCnt;
    UINT sg_index;
    UCHAR sg_count, i;
-#if defined(DOS)
-   USHORT reg_offset;
-#else
    ULONG reg_offset;
-#endif
 
 
    if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
@@ -8802,17 +5594,6 @@ void busMstrSGDataXferStart(ULONG p_port
    while ((sg_count < (UCHAR)SG_BUF_CNT) &&
       ((ULONG)(sg_index * (UINT)SG_ELEMENT_SIZE) < pcurrSCCB->DataLength) ) {
 
-#if defined(COMPILER_16_BIT) && !defined(DOS)
-      tmpSGCnt += *(((ULONG far *)pcurrSCCB->DataPointer)+
-         (sg_index * 2));
-
-      count |= *(((ULONG far *)pcurrSCCB->DataPointer)+
-         (sg_index * 2));
-
-      addr = *(((ULONG far *)pcurrSCCB->DataPointer)+
-         ((sg_index * 2) + 1));
-
-#else
       tmpSGCnt += *(((ULONG *)pcurrSCCB->DataPointer)+
          (sg_index * 2));
 
@@ -8821,7 +5602,6 @@ void busMstrSGDataXferStart(ULONG p_port
 
       addr = *(((ULONG *)pcurrSCCB->DataPointer)+
          ((sg_index * 2) + 1));
-#endif
 
 
       if ((!sg_count) && (pcurrSCCB->Sccb_SGoffset)) {
@@ -8888,11 +5668,7 @@ void busMstrSGDataXferStart(ULONG p_port
  * Description: 
  *
  *---------------------------------------------------------------------*/
-#if defined(DOS)
-void busMstrDataXferStart(USHORT p_port, PSCCB pcurrSCCB)
-#else
-void busMstrDataXferStart(ULONG p_port, PSCCB pcurrSCCB)
-#endif
+static void FPT_busMstrDataXferStart(ULONG p_port, PSCCB pcurrSCCB)
 {
    ULONG addr,count;
 
@@ -8909,37 +5685,7 @@ void busMstrDataXferStart(ULONG p_port, 
 
       }
 
-#if defined(DOS)
-   asm { mov dx,p_port;
-         mov ax,word ptr count;
-         add dx,hp_xfer_cnt_lo;
-         out dx,al;
-         inc dx;
-         xchg ah,al
-         out dx,al;
-         inc dx;
-         mov ax,word ptr count+2;
-         out dx,al;
-         inc dx;
-         inc dx;
-         mov ax,word ptr addr;
-         out dx,al;
-         inc dx;
-         xchg ah,al
-         out dx,al;
-         inc dx;
-         mov ax,word ptr addr+2;
-         out dx,al;
-         inc dx;
-         xchg ah,al
-         out dx,al;
-         }
-
-   WR_HARP32(p_port,hp_xfercnt_0,count);
-
-#else
    HP_SETUP_ADDR_CNT(p_port,addr,count);
-#endif
 
 
    if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
@@ -8975,11 +5721,7 @@ void busMstrDataXferStart(ULONG p_port, 
  *               command busy is also time out, it'll just give up.
  *
  *---------------------------------------------------------------------*/
-#if defined(DOS)
-UCHAR busMstrTimeOut(USHORT p_port)
-#else
-UCHAR busMstrTimeOut(ULONG p_port)
-#endif
+static UCHAR FPT_busMstrTimeOut(ULONG p_port)
 {
    ULONG timeout;
 
@@ -9001,11 +5743,11 @@ UCHAR busMstrTimeOut(ULONG p_port)
    RD_HARPOON(p_port+hp_int_status);           /*Clear command complete */
 
    if (RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) {
-      return(TRUE);
+      return(1);
       }
 
    else {
-      return(FALSE);
+      return(0);
       }
 }
 
@@ -9017,18 +5759,14 @@ UCHAR busMstrTimeOut(ULONG p_port)
  * Description: Abort any in progress transfer.
  *
  *---------------------------------------------------------------------*/
-#if defined(DOS)
-void hostDataXferAbort(USHORT port, UCHAR p_card, PSCCB pCurrSCCB)
-#else
-void hostDataXferAbort(ULONG port, UCHAR p_card, PSCCB pCurrSCCB)
-#endif
+static void FPT_hostDataXferAbort(ULONG port, UCHAR p_card, PSCCB pCurrSCCB)
 {
 
    ULONG timeout;
    ULONG remain_cnt;
    UINT sg_ptr;
 
-   BL_Card[p_card].globalFlags &= ~F_HOST_XFER_ACT;
+   FPT_BL_Card[p_card].globalFlags &= ~F_HOST_XFER_ACT;
 
    if (pCurrSCCB->Sccb_XferState & F_AUTO_SENSE) {
 
@@ -9044,7 +5782,7 @@ void hostDataXferAbort(ULONG port, UCHAR
 
          if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
 
-            if (busMstrTimeOut(port)) {
+            if (FPT_busMstrTimeOut(port)) {
 
                if (pCurrSCCB->HostStatus == 0x00)
 
@@ -9060,10 +5798,6 @@ void hostDataXferAbort(ULONG port, UCHAR
 
                      {
                      pCurrSCCB->HostStatus = SCCB_BM_ERR;
-#if defined(BUGBUG)
-                     WR_HARPOON(port+hp_dual_addr_lo,
-                        RD_HARPOON(port+hp_ext_status));
-#endif
                      }
             }
          }
@@ -9092,22 +5826,12 @@ void hostDataXferAbort(ULONG port, UCHAR
 
             sg_ptr--;
 
-#if defined(COMPILER_16_BIT) && !defined(DOS)
-            if (remain_cnt > (ULONG)(*(((ULONG far *)pCurrSCCB->
-               DataPointer) + (sg_ptr * 2)))) {
-
-               remain_cnt -= (ULONG)(*(((ULONG far *)pCurrSCCB->
-                  DataPointer) + (sg_ptr * 2)));
-               }
-
-#else
             if (remain_cnt > (ULONG)(*(((ULONG *)pCurrSCCB->
                DataPointer) + (sg_ptr * 2)))) {
 
                remain_cnt -= (ULONG)(*(((ULONG *)pCurrSCCB->
                   DataPointer) + (sg_ptr * 2)));
                }
-#endif
 
             else {
 
@@ -9147,7 +5871,7 @@ void hostDataXferAbort(ULONG port, UCHAR
 
          if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
 
-            busMstrTimeOut(port);
+            FPT_busMstrTimeOut(port);
             }
 
          else {
@@ -9159,10 +5883,6 @@ void hostDataXferAbort(ULONG port, UCHAR
                   if (pCurrSCCB->HostStatus == 0x00) {
 
                      pCurrSCCB->HostStatus = SCCB_BM_ERR;
-#if defined(BUGBUG)
-                     WR_HARPOON(port+hp_dual_addr_lo,
-                        RD_HARPOON(port+hp_ext_status));
-#endif
                      }
                   }
                }
@@ -9203,7 +5923,7 @@ void hostDataXferAbort(ULONG port, UCHAR
                   pCurrSCCB->HostStatus = SCCB_BM_ERR;
                   }
 
-               busMstrTimeOut(port);
+               FPT_busMstrTimeOut(port);
                }
             }
 
@@ -9214,10 +5934,6 @@ void hostDataXferAbort(ULONG port, UCHAR
                if (pCurrSCCB->HostStatus == 0x00) {
 
                   pCurrSCCB->HostStatus = SCCB_BM_ERR;
-#if defined(BUGBUG)
-                  WR_HARPOON(port+hp_dual_addr_lo,
-                     RD_HARPOON(port+hp_ext_status));
-#endif
                   }
                }
             }
@@ -9241,7 +5957,7 @@ void hostDataXferAbort(ULONG port, UCHAR
                pCurrSCCB->HostStatus = SCCB_BM_ERR;
                }
 
-            busMstrTimeOut(port);
+            FPT_busMstrTimeOut(port);
             }
          }
 
@@ -9253,10 +5969,6 @@ void hostDataXferAbort(ULONG port, UCHAR
             if (pCurrSCCB->HostStatus == 0x00) {
 
                pCurrSCCB->HostStatus = SCCB_BM_ERR;
-#if defined(BUGBUG)
-               WR_HARPOON(port+hp_dual_addr_lo,
-                  RD_HARPOON(port+hp_ext_status));
-#endif
                }
             }
 
@@ -9305,15 +6017,11 @@ void hostDataXferAbort(ULONG port, UCHAR
  *              pointers message.
  *
  *---------------------------------------------------------------------*/
-void hostDataXferRestart(PSCCB currSCCB)
+static void FPT_hostDataXferRestart(PSCCB currSCCB)
 {
    ULONG data_count;
    UINT  sg_index;
-#if defined(COMPILER_16_BIT) && !defined(DOS)
-   ULONG far *sg_ptr;
-#else
    ULONG *sg_ptr;
-#endif
 
    if (currSCCB->Sccb_XferState & F_SG_XFER) {
 
@@ -9322,11 +6030,7 @@ void hostDataXferRestart(PSCCB currSCCB)
       sg_index = 0xffff;         /*Index by long words into sg list. */
       data_count = 0;            /*Running count of SG xfer counts. */
 
-#if defined(COMPILER_16_BIT) && !defined(DOS)
-      sg_ptr = (ULONG far *)currSCCB->DataPointer;
-#else
       sg_ptr = (ULONG *)currSCCB->DataPointer;
-#endif
 
       while (data_count < currSCCB->Sccb_ATC) {
 
@@ -9351,78 +6055,28 @@ void hostDataXferRestart(PSCCB currSCCB)
       currSCCB->Sccb_XferCnt = currSCCB->DataLength - currSCCB->Sccb_ATC;
       }
 }
-#ident "$Id: scam.c 1.17 1997/03/20 23:49:37 mohan Exp $"
-/*----------------------------------------------------------------------
- *
- *
- *   Copyright 1995-1996 by Mylex Corporation.  All Rights Reserved
- *
- *   This file is available under both the GNU General Public License
- *   and a BSD-style copyright; see LICENSE.FlashPoint for details.
- *
- *   $Workfile:   scam.c  $
- *
- *   Description:  Functions relating to handling of the SCAM selection
- *                 and the determination of the SCSI IDs to be assigned
- *                 to all perspective SCSI targets.
- *
- *   $Date: 1997/03/20 23:49:37 $
- *
- *   $Revision: 1.17 $
- *
- *----------------------------------------------------------------------*/
-
-/*#include <globals.h>*/
 
-#if (FW_TYPE==_UCB_MGR_)
-	/*#include <budi.h>*/
-#endif
-
-/*#include <sccbmgr.h>*/
-/*#include <blx30.h>*/
-/*#include <target.h>*/
-/*#include <scsi2.h>*/
-/*#include <eeprom.h>*/
-/*#include <harpoon.h>*/
 
 
-
-/*
-extern SCCBMGR_TAR_INFO sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR];
-extern SCCBCARD BL_Card[MAX_CARDS];
-extern SCCBSCAM_INFO scamInfo[MAX_SCSI_TAR];
-extern NVRAMINFO nvRamInfo[MAX_MB_CARDS];
-#if defined(DOS) || defined(OS2)
-extern UCHAR temp_id_string[ID_STRING_LENGTH];
-#endif
-extern UCHAR scamHAString[];
-*/
 /*---------------------------------------------------------------------
  *
- * Function: scini
+ * Function: FPT_scini
  *
  * Description: Setup all data structures necessary for SCAM selection.
  *
  *---------------------------------------------------------------------*/
 
-void scini(UCHAR p_card, UCHAR p_our_id, UCHAR p_power_up)
+static void FPT_scini(UCHAR p_card, UCHAR p_our_id, UCHAR p_power_up)
 {
 
-#if defined(SCAM_LEV_2)
    UCHAR loser,assigned_id;
-#endif
-#if defined(DOS)
-
-   USHORT p_port;
-#else
    ULONG p_port;
-#endif
 
    UCHAR i,k,ScamFlg ;
    PSCCBcard currCard;
 	PNVRamInfo pCurrNvRam;
 
-   currCard = &BL_Card[p_card];
+   currCard = &FPT_BL_Card[p_card];
    p_port = currCard->ioPort;
 	pCurrNvRam = currCard->pNvRamInfo;
 
@@ -9432,72 +6086,68 @@ void scini(UCHAR p_card, UCHAR p_our_id,
 		i = pCurrNvRam->niSysConf;
 	}
 	else{
-	   ScamFlg = (UCHAR) utilEERead(p_port, SCAM_CONFIG/2);
-	   i = (UCHAR)(utilEERead(p_port, (SYSTEM_CONFIG/2)));
+	   ScamFlg = (UCHAR) FPT_utilEERead(p_port, SCAM_CONFIG/2);
+	   i = (UCHAR)(FPT_utilEERead(p_port, (SYSTEM_CONFIG/2)));
 	}
 	if(!(i & 0x02))	/* check if reset bus in AutoSCSI parameter set */
 		return;
 
-   inisci(p_card,p_port, p_our_id);
+   FPT_inisci(p_card,p_port, p_our_id);
 
    /* Force to wait 1 sec after SCSI bus reset. Some SCAM device FW
       too slow to return to SCAM selection */
 
    /* if (p_power_up)
-         Wait1Second(p_port);
+         FPT_Wait1Second(p_port);
       else
-         Wait(p_port, TO_250ms); */
+         FPT_Wait(p_port, TO_250ms); */
 
-   Wait1Second(p_port);
-
-#if defined(SCAM_LEV_2)
+   FPT_Wait1Second(p_port);
 
    if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
       {
-      while (!(scarb(p_port,INIT_SELTD))) {}
+      while (!(FPT_scarb(p_port,INIT_SELTD))) {}
 
-      scsel(p_port);
+      FPT_scsel(p_port);
 
       do {
-         scxferc(p_port,SYNC_PTRN);
-         scxferc(p_port,DOM_MSTR);
-         loser = scsendi(p_port,&scamInfo[p_our_id].id_string[0]);
+         FPT_scxferc(p_port,SYNC_PTRN);
+         FPT_scxferc(p_port,DOM_MSTR);
+         loser = FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].id_string[0]);
          } while ( loser == 0xFF );
 
-      scbusf(p_port);
+      FPT_scbusf(p_port);
 
       if ((p_power_up) && (!loser))
          {
-         sresb(p_port,p_card);
-         Wait(p_port, TO_250ms);
+         FPT_sresb(p_port,p_card);
+         FPT_Wait(p_port, TO_250ms);
 
-         while (!(scarb(p_port,INIT_SELTD))) {}
+         while (!(FPT_scarb(p_port,INIT_SELTD))) {}
 
-         scsel(p_port);
+         FPT_scsel(p_port);
 
          do {
-            scxferc(p_port, SYNC_PTRN);
-            scxferc(p_port, DOM_MSTR);
-            loser = scsendi(p_port,&scamInfo[p_our_id].
+            FPT_scxferc(p_port, SYNC_PTRN);
+            FPT_scxferc(p_port, DOM_MSTR);
+            loser = FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].
                id_string[0]);
             } while ( loser == 0xFF );
 
-         scbusf(p_port);
+         FPT_scbusf(p_port);
          }
       }
 
    else
       {
-      loser = FALSE;
+      loser = 0;
       }
 
 
    if (!loser)
       {
 
-#endif  /* SCAM_LEV_2 */
-
-      scamInfo[p_our_id].state = ID_ASSIGNED;
+      FPT_scamInfo[p_our_id].state = ID_ASSIGNED;
 
 
 		if (ScamFlg & SCAM_ENABLED)
@@ -9505,18 +6155,18 @@ void scini(UCHAR p_card, UCHAR p_our_id,
 
 	      for (i=0; i < MAX_SCSI_TAR; i++)
   		   {
-      	   if ((scamInfo[i].state == ID_UNASSIGNED) ||
-  	      	   (scamInfo[i].state == ID_UNUSED))
+      	   if ((FPT_scamInfo[i].state == ID_UNASSIGNED) ||
+  	      	   (FPT_scamInfo[i].state == ID_UNUSED))
 	  	      {
-   	     	   if (scsell(p_port,i))
+   	     	   if (FPT_scsell(p_port,i))
       	  	   {
-            	   scamInfo[i].state = LEGACY;
-  	            	if ((scamInfo[i].id_string[0] != 0xFF) ||
-     	            	(scamInfo[i].id_string[1] != 0xFA))
+            	   FPT_scamInfo[i].state = LEGACY;
+  	            	if ((FPT_scamInfo[i].id_string[0] != 0xFF) ||
+     	            	(FPT_scamInfo[i].id_string[1] != 0xFA))
 	     	         {
 
-   	        	      scamInfo[i].id_string[0] = 0xFF;
-      	        	   scamInfo[i].id_string[1] = 0xFA;
+   	        	      FPT_scamInfo[i].id_string[0] = 0xFF;
+      	        	   FPT_scamInfo[i].id_string[1] = 0xFA;
 							if(pCurrNvRam == NULL)
 	         	         currCard->globalFlags |= F_UPDATE_EEPROM;
                	}
@@ -9524,45 +6174,43 @@ void scini(UCHAR p_card, UCHAR p_our_id,
    	  	   }
       	}
 
-	      sresb(p_port,p_card);
-      	Wait1Second(p_port);
-         while (!(scarb(p_port,INIT_SELTD))) {}
-         scsel(p_port);
-         scasid(p_card, p_port);
+	      FPT_sresb(p_port,p_card);
+      	FPT_Wait1Second(p_port);
+         while (!(FPT_scarb(p_port,INIT_SELTD))) {}
+         FPT_scsel(p_port);
+         FPT_scasid(p_card, p_port);
          }
 
-#if defined(SCAM_LEV_2)
-
       }
 
    else if ((loser) && (ScamFlg & SCAM_ENABLED))
       {
-      scamInfo[p_our_id].id_string[0] = SLV_TYPE_CODE0;
-      assigned_id = FALSE;
-      scwtsel(p_port);
+      FPT_scamInfo[p_our_id].id_string[0] = SLV_TYPE_CODE0;
+      assigned_id = 0;
+      FPT_scwtsel(p_port);
 
       do {
-         while (scxferc(p_port,0x00) != SYNC_PTRN) {}
+         while (FPT_scxferc(p_port,0x00) != SYNC_PTRN) {}
 
-         i = scxferc(p_port,0x00);
+         i = FPT_scxferc(p_port,0x00);
          if (i == ASSIGN_ID)
             {
-            if (!(scsendi(p_port,&scamInfo[p_our_id].id_string[0])))
+            if (!(FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].id_string[0])))
                   {
-                  i = scxferc(p_port,0x00);
-                  if (scvalq(i))
+                  i = FPT_scxferc(p_port,0x00);
+                  if (FPT_scvalq(i))
                      {
-                     k = scxferc(p_port,0x00);
+                     k = FPT_scxferc(p_port,0x00);
 
-                     if (scvalq(k))
+                     if (FPT_scvalq(k))
                         {
                         currCard->ourId =
                            ((UCHAR)(i<<3)+(k & (UCHAR)7)) & (UCHAR) 0x3F;
-                        inisci(p_card, p_port, p_our_id);
-                        scamInfo[currCard->ourId].state = ID_ASSIGNED;
-                        scamInfo[currCard->ourId].id_string[0]
+                        FPT_inisci(p_card, p_port, p_our_id);
+                        FPT_scamInfo[currCard->ourId].state = ID_ASSIGNED;
+                        FPT_scamInfo[currCard->ourId].id_string[0]
                            = SLV_TYPE_CODE0;
-                        assigned_id = TRUE;
+                        assigned_id = 1;
                         }
                      }
                   }
@@ -9570,43 +6218,31 @@ void scini(UCHAR p_card, UCHAR p_our_id,
 
          else if (i == SET_P_FLAG)
             {
-               if (!(scsendi(p_port,
-                        &scamInfo[p_our_id].id_string[0])))
-                        scamInfo[p_our_id].id_string[0] |= 0x80;
+               if (!(FPT_scsendi(p_port,
+                        &FPT_scamInfo[p_our_id].id_string[0])))
+                        FPT_scamInfo[p_our_id].id_string[0] |= 0x80;
             }
          }while (!assigned_id);
 
-      while (scxferc(p_port,0x00) != CFG_CMPLT) {}
+      while (FPT_scxferc(p_port,0x00) != CFG_CMPLT) {}
       }
 
-#endif   /* SCAM_LEV_2 */
    if (ScamFlg & SCAM_ENABLED)
       {
-      scbusf(p_port);
+      FPT_scbusf(p_port);
       if (currCard->globalFlags & F_UPDATE_EEPROM)
          {
-         scsavdi(p_card, p_port);
+         FPT_scsavdi(p_card, p_port);
          currCard->globalFlags &= ~F_UPDATE_EEPROM;
          }
       }
 
 
-#if defined(DOS)
-   for (i=0; i < MAX_SCSI_TAR; i++)
-   {
-     	if (((ScamFlg & SCAM_ENABLED) && (scamInfo[i].state == LEGACY))
-			|| (i != p_our_id))
-        	{
-         scsellDOS(p_port,i);
-  	      }
-  	}
-#endif
-
 /*
    for (i=0,k=0; i < MAX_SCSI_TAR; i++)
       {
-      if ((scamInfo[i].state == ID_ASSIGNED) ||
-         (scamInfo[i].state == LEGACY))
+      if ((FPT_scamInfo[i].state == ID_ASSIGNED) ||
+         (FPT_scamInfo[i].state == LEGACY))
          k++;
       }
 
@@ -9620,17 +6256,13 @@ void scini(UCHAR p_card, UCHAR p_our_id,
 
 /*---------------------------------------------------------------------
  *
- * Function: scarb
+ * Function: FPT_scarb
  *
  * Description: Gain control of the bus and wait SCAM select time (250ms)
  *
  *---------------------------------------------------------------------*/
 
-#if defined(DOS)
-int scarb(USHORT p_port, UCHAR p_sel_type)
-#else
-int scarb(ULONG p_port, UCHAR p_sel_type)
-#endif
+static int FPT_scarb(ULONG p_port, UCHAR p_sel_type)
 {
    if (p_sel_type == INIT_SELTD)
       {
@@ -9639,10 +6271,10 @@ int scarb(ULONG p_port, UCHAR p_sel_type
 
 
       if (RD_HARPOON(p_port+hp_scsisig) & SCSI_SEL)
-         return(FALSE);
+         return(0);
 
       if (RD_HARPOON(p_port+hp_scsidata_0) != 00)
-         return(FALSE);
+         return(0);
 
       WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_BSY));
 
@@ -9650,7 +6282,7 @@ int scarb(ULONG p_port, UCHAR p_sel_type
 
          WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) &
             ~SCSI_BSY));
-         return(FALSE);
+         return(0);
          }
 
 
@@ -9660,7 +6292,7 @@ int scarb(ULONG p_port, UCHAR p_sel_type
 
          WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) &
             ~(SCSI_BSY | SCSI_SEL)));
-         return(FALSE);
+         return(0);
          }
       }
 
@@ -9669,9 +6301,7 @@ int scarb(ULONG p_port, UCHAR p_sel_type
       & ~ACTdeassert));
    WR_HARPOON(p_port+hp_scsireset, SCAM_EN);
    WR_HARPOON(p_port+hp_scsidata_0, 0x00);
-#if defined(WIDE_SCSI)
    WR_HARPOON(p_port+hp_scsidata_1, 0x00);
-#endif
    WR_HARPOON(p_port+hp_portctrl_0, SCSI_BUS_EN);
 
    WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_MSG));
@@ -9679,25 +6309,21 @@ int scarb(ULONG p_port, UCHAR p_sel_type
    WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig)
       & ~SCSI_BSY));
 
-   Wait(p_port,TO_250ms);
+   FPT_Wait(p_port,TO_250ms);
 
-   return(TRUE);
+   return(1);
 }
 
 
 /*---------------------------------------------------------------------
  *
- * Function: scbusf
+ * Function: FPT_scbusf
  *
  * Description: Release the SCSI bus and disable SCAM selection.
  *
  *---------------------------------------------------------------------*/
 
-#if defined(DOS)
-void scbusf(USHORT p_port)
-#else
-void scbusf(ULONG p_port)
-#endif
+static void FPT_scbusf(ULONG p_port)
 {
    WR_HARPOON(p_port+hp_page_ctrl,
       (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE));
@@ -9717,11 +6343,7 @@ void scbusf(ULONG p_port)
    WR_HARPOON(p_port+hp_clkctrl_0, (RD_HARPOON(p_port+hp_clkctrl_0)
       | ACTdeassert));
 
-#if defined(SCAM_LEV_2)
    WRW_HARPOON((p_port+hp_intstat), (BUS_FREE | AUTO_INT | SCAM_SEL));
-#else
-   WRW_HARPOON((p_port+hp_intstat), (BUS_FREE | AUTO_INT));
-#endif
 
    WR_HARPOON(p_port+hp_page_ctrl,
       (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
@@ -9731,35 +6353,24 @@ void scbusf(ULONG p_port)
 
 /*---------------------------------------------------------------------
  *
- * Function: scasid
+ * Function: FPT_scasid
  *
  * Description: Assign an ID to all the SCAM devices.
  *
  *---------------------------------------------------------------------*/
 
-#if defined(DOS)
-void scasid(UCHAR p_card, USHORT p_port)
-#else
-void scasid(UCHAR p_card, ULONG p_port)
-#endif
+static void FPT_scasid(UCHAR p_card, ULONG p_port)
 {
-#if defined(DOS) || defined(OS2)
-   /* Use external defined in global space area, instead of Stack
-      space. WIN/95 DOS doesnot work TINY mode. The OS doesnot intialize
-      SS equal to DS. Thus the array allocated on stack doesnot get
-      access correctly */
-#else
    UCHAR temp_id_string[ID_STRING_LENGTH];
-#endif
 
    UCHAR i,k,scam_id;
 	UCHAR crcBytes[3];
 	PNVRamInfo pCurrNvRam;
 	ushort_ptr pCrcBytes;
 
-	pCurrNvRam = BL_Card[p_card].pNvRamInfo;
+	pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
 
-   i=FALSE;
+   i=0;
 
    while (!i)
       {
@@ -9769,36 +6380,36 @@ void scasid(UCHAR p_card, ULONG p_port)
          temp_id_string[k] = (UCHAR) 0x00;
          }
 
-      scxferc(p_port,SYNC_PTRN);
-      scxferc(p_port,ASSIGN_ID);
+      FPT_scxferc(p_port,SYNC_PTRN);
+      FPT_scxferc(p_port,ASSIGN_ID);
 
-      if (!(sciso(p_port,&temp_id_string[0])))
+      if (!(FPT_sciso(p_port,&temp_id_string[0])))
          {
 			if(pCurrNvRam){
 				pCrcBytes = (ushort_ptr)&crcBytes[0];
-				*pCrcBytes = CalcCrc16(&temp_id_string[0]);
-				crcBytes[2] = CalcLrc(&temp_id_string[0]);
+				*pCrcBytes = FPT_CalcCrc16(&temp_id_string[0]);
+				crcBytes[2] = FPT_CalcLrc(&temp_id_string[0]);
 				temp_id_string[1] = crcBytes[2];
 				temp_id_string[2] = crcBytes[0];
 				temp_id_string[3] = crcBytes[1];
 				for(k = 4; k < ID_STRING_LENGTH; k++)
 					temp_id_string[k] = (UCHAR) 0x00;
 			}
-         i = scmachid(p_card,temp_id_string);
+         i = FPT_scmachid(p_card,temp_id_string);
 
          if (i == CLR_PRIORITY)
             {
-            scxferc(p_port,MISC_CODE);
-            scxferc(p_port,CLR_P_FLAG);
-            i = FALSE;  /*Not the last ID yet. */
+            FPT_scxferc(p_port,MISC_CODE);
+            FPT_scxferc(p_port,CLR_P_FLAG);
+            i = 0;  /*Not the last ID yet. */
             }
 
          else if (i != NO_ID_AVAIL)
             {
             if (i < 8 )
-               scxferc(p_port,ID_0_7);
+               FPT_scxferc(p_port,ID_0_7);
             else
-               scxferc(p_port,ID_8_F);
+               FPT_scxferc(p_port,ID_8_F);
 
             scam_id = (i & (UCHAR) 0x07);
 
@@ -9807,21 +6418,21 @@ void scasid(UCHAR p_card, ULONG p_port)
                if (!( k & i ))
                   scam_id += 0x08;        /*Count number of zeros in DB0-3. */
 
-            scxferc(p_port,scam_id);
+            FPT_scxferc(p_port,scam_id);
 
-            i = FALSE;  /*Not the last ID yet. */
+            i = 0;  /*Not the last ID yet. */
             }
          }
 
       else
          {
-         i = TRUE;
+         i = 1;
          }
 
       }  /*End while */
 
-   scxferc(p_port,SYNC_PTRN);
-   scxferc(p_port,CFG_CMPLT);
+   FPT_scxferc(p_port,SYNC_PTRN);
+   FPT_scxferc(p_port,CFG_CMPLT);
 }
 
 
@@ -9830,21 +6441,17 @@ void scasid(UCHAR p_card, ULONG p_port)
 
 /*---------------------------------------------------------------------
  *
- * Function: scsel
+ * Function: FPT_scsel
  *
  * Description: Select all the SCAM devices.
  *
  *---------------------------------------------------------------------*/
 
-#if defined(DOS)
-void scsel(USHORT p_port)
-#else
-void scsel(ULONG p_port)
-#endif
+static void FPT_scsel(ULONG p_port)
 {
 
    WR_HARPOON(p_port+hp_scsisig, SCSI_SEL);
-   scwiros(p_port, SCSI_MSG);
+   FPT_scwiros(p_port, SCSI_MSG);
 
    WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY));
 
@@ -9855,11 +6462,11 @@ void scsel(ULONG p_port)
 
 
    WR_HARPOON(p_port+hp_scsisig, (SCSI_BSY | SCSI_IOBIT | SCSI_CD));
-   scwiros(p_port, SCSI_SEL);
+   FPT_scwiros(p_port, SCSI_SEL);
 
    WR_HARPOON(p_port+hp_scsidata_0, (UCHAR)(RD_HARPOON(p_port+hp_scsidata_0) &
       ~(UCHAR)BIT(6)));
-   scwirod(p_port, BIT(6));
+   FPT_scwirod(p_port, BIT(6));
 
    WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
 }
@@ -9868,17 +6475,13 @@ void scsel(ULONG p_port)
 
 /*---------------------------------------------------------------------
  *
- * Function: scxferc
+ * Function: FPT_scxferc
  *
  * Description: Handshake the p_data (DB4-0) across the bus.
  *
  *---------------------------------------------------------------------*/
 
-#if defined(DOS)
-UCHAR scxferc(USHORT p_port, UCHAR p_data)
-#else
-UCHAR scxferc(ULONG p_port, UCHAR p_data)
-#endif
+static UCHAR FPT_scxferc(ULONG p_port, UCHAR p_data)
 {
    UCHAR curr_data, ret_data;
 
@@ -9890,7 +6493,7 @@ UCHAR scxferc(ULONG p_port, UCHAR p_data
 
    WR_HARPOON(p_port+hp_scsidata_0, curr_data);
 
-   scwirod(p_port,BIT(7));              /*Wait for DB7 to be released. */
+   FPT_scwirod(p_port,BIT(7));              /*Wait for DB7 to be released. */
 	while (!(RD_HARPOON(p_port+hp_scsidata_0) & BIT(5)));
 
    ret_data = (RD_HARPOON(p_port+hp_scsidata_0) & (UCHAR) 0x1F);
@@ -9903,7 +6506,7 @@ UCHAR scxferc(ULONG p_port, UCHAR p_data
 
    WR_HARPOON(p_port+hp_scsidata_0, curr_data);
 
-   scwirod(p_port,BIT(5));              /*Wait for DB5 to be released. */
+   FPT_scwirod(p_port,BIT(5));              /*Wait for DB5 to be released. */
 
    curr_data &= ~(BIT(4)|BIT(3)|BIT(2)|BIT(1)|BIT(0)); /*Release data bits */
    curr_data |= BIT(7);
@@ -9914,7 +6517,7 @@ UCHAR scxferc(ULONG p_port, UCHAR p_data
 
    WR_HARPOON(p_port+hp_scsidata_0, curr_data);
 
-   scwirod(p_port,BIT(6));              /*Wait for DB6 to be released. */
+   FPT_scwirod(p_port,BIT(6));              /*Wait for DB6 to be released. */
 
    return(ret_data);
 }
@@ -9922,39 +6525,35 @@ UCHAR scxferc(ULONG p_port, UCHAR p_data
 
 /*---------------------------------------------------------------------
  *
- * Function: scsendi
+ * Function: FPT_scsendi
  *
  * Description: Transfer our Identification string to determine if we
  *              will be the dominant master.
  *
  *---------------------------------------------------------------------*/
 
-#if defined(DOS)
-UCHAR scsendi(USHORT p_port, UCHAR p_id_string[])
-#else
-UCHAR scsendi(ULONG p_port, UCHAR p_id_string[])
-#endif
+static UCHAR FPT_scsendi(ULONG p_port, UCHAR p_id_string[])
 {
    UCHAR ret_data,byte_cnt,bit_cnt,defer;
 
-   defer = FALSE;
+   defer = 0;
 
    for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
 
       for (bit_cnt = 0x80; bit_cnt != 0 ; bit_cnt >>= 1) {
 
          if (defer)
-            ret_data = scxferc(p_port,00);
+            ret_data = FPT_scxferc(p_port,00);
 
          else if (p_id_string[byte_cnt] & bit_cnt)
 
-               ret_data = scxferc(p_port,02);
+               ret_data = FPT_scxferc(p_port,02);
 
             else {
 
-               ret_data = scxferc(p_port,01);
+               ret_data = FPT_scxferc(p_port,01);
                if (ret_data & 02)
-                  defer = TRUE;
+                  defer = 1;
                }
 
          if ((ret_data & 0x1C) == 0x10)
@@ -9980,17 +6579,13 @@ UCHAR scsendi(ULONG p_port, UCHAR p_id_s
 
 /*---------------------------------------------------------------------
  *
- * Function: sciso
+ * Function: FPT_sciso
  *
  * Description: Transfer the Identification string.
  *
  *---------------------------------------------------------------------*/
 
-#if defined(DOS)
-UCHAR sciso(USHORT p_port, UCHAR p_id_string[])
-#else
-UCHAR sciso(ULONG p_port, UCHAR p_id_string[])
-#endif
+static UCHAR FPT_sciso(ULONG p_port, UCHAR p_id_string[])
 {
    UCHAR ret_data,the_data,byte_cnt,bit_cnt;
 
@@ -10000,7 +6595,7 @@ UCHAR sciso(ULONG p_port, UCHAR p_id_str
 
       for (bit_cnt = 0; bit_cnt < 8; bit_cnt++) {
 
-         ret_data = scxferc(p_port,0);
+         ret_data = FPT_scxferc(p_port,0);
 
          if (ret_data & 0xFC)
             return(0xFF);
@@ -10020,8 +6615,8 @@ UCHAR sciso(ULONG p_port, UCHAR p_id_str
 				{
 					byte_cnt = 0;
 					bit_cnt = 0;
-					scxferc(p_port, SYNC_PTRN);
-					scxferc(p_port, ASSIGN_ID);
+					FPT_scxferc(p_port, SYNC_PTRN);
+					FPT_scxferc(p_port, ASSIGN_ID);
 					continue;
 				}
 */
@@ -10044,18 +6639,14 @@ UCHAR sciso(ULONG p_port, UCHAR p_id_str
 
 /*---------------------------------------------------------------------
  *
- * Function: scwirod
+ * Function: FPT_scwirod
  *
  * Description: Sample the SCSI data bus making sure the signal has been
  *              deasserted for the correct number of consecutive samples.
  *
  *---------------------------------------------------------------------*/
 
-#if defined(DOS)
-void scwirod(USHORT p_port, UCHAR p_data_bit)
-#else
-void scwirod(ULONG p_port, UCHAR p_data_bit)
-#endif
+static void FPT_scwirod(ULONG p_port, UCHAR p_data_bit)
 {
    UCHAR i;
 
@@ -10077,166 +6668,70 @@ void scwirod(ULONG p_port, UCHAR p_data_
 
 /*---------------------------------------------------------------------
  *
- * Function: scwiros
+ * Function: FPT_scwiros
  *
  * Description: Sample the SCSI Signal lines making sure the signal has been
  *              deasserted for the correct number of consecutive samples.
  *
  *---------------------------------------------------------------------*/
 
-#if defined(DOS)
-void scwiros(USHORT p_port, UCHAR p_data_bit)
-#else
-void scwiros(ULONG p_port, UCHAR p_data_bit)
-#endif
+static void FPT_scwiros(ULONG p_port, UCHAR p_data_bit)
 {
    UCHAR i;
 
    i = 0;
    while ( i < MAX_SCSI_TAR ) {
 
-      if (RD_HARPOON(p_port+hp_scsisig) & p_data_bit)
-
-         i = 0;
-
-      else
-
-         i++;
-
-      }
-}
-
-
-/*---------------------------------------------------------------------
- *
- * Function: scvalq
- *
- * Description: Make sure we received a valid data byte.
- *
- *---------------------------------------------------------------------*/
-
-UCHAR scvalq(UCHAR p_quintet)
-{
-   UCHAR count;
-
-   for (count=1; count < 0x08; count<<=1) {
-      if (!(p_quintet & count))
-         p_quintet -= 0x80;
-      }
-
-   if (p_quintet & 0x18)
-      return(FALSE);
-
-   else
-      return(TRUE);
-}
-
-
-/*---------------------------------------------------------------------
- *
- * Function: scsell
- *
- * Description: Select the specified device ID using a selection timeout
- *              less than 4ms.  If somebody responds then it is a legacy
- *              drive and this ID must be marked as such.
- *
- *---------------------------------------------------------------------*/
-
-#if defined(DOS)
-UCHAR scsell(USHORT p_port, UCHAR targ_id)
-#else
-UCHAR scsell(ULONG p_port, UCHAR targ_id)
-#endif
-{
-#if defined(DOS)
-   USHORT i;
-#else
-   ULONG i;
-#endif
-
-   WR_HARPOON(p_port+hp_page_ctrl,
-      (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE));
-
-   ARAM_ACCESS(p_port);
-
-   WR_HARPOON(p_port+hp_addstat,(RD_HARPOON(p_port+hp_addstat) | SCAM_TIMER));
-   WR_HARPOON(p_port+hp_seltimeout,TO_4ms);
-
-
-   for (i = p_port+CMD_STRT; i < p_port+CMD_STRT+12; i+=2) {
-      WRW_HARPOON(i, (MPM_OP+ACOMMAND));
-      }
-   WRW_HARPOON(i, (BRH_OP+ALWAYS+    NP));
-
-   WRW_HARPOON((p_port+hp_intstat),
-	       (RESET | TIMEOUT | SEL | BUS_FREE | AUTO_INT));
-
-   WR_HARPOON(p_port+hp_select_id, targ_id);
-
-   WR_HARPOON(p_port+hp_portctrl_0, SCSI_PORT);
-   WR_HARPOON(p_port+hp_autostart_3, (SELECT | CMD_ONLY_STRT));
-   WR_HARPOON(p_port+hp_scsictrl_0, (SEL_TAR | ENA_RESEL));
-
-
-   while (!(RDW_HARPOON((p_port+hp_intstat)) &
-	    (RESET | PROG_HLT | TIMEOUT | AUTO_INT))) {}
-
-   if (RDW_HARPOON((p_port+hp_intstat)) & RESET)
-         Wait(p_port, TO_250ms);
-
-   DISABLE_AUTO(p_port);
-
-   WR_HARPOON(p_port+hp_addstat,(RD_HARPOON(p_port+hp_addstat) & ~SCAM_TIMER));
-   WR_HARPOON(p_port+hp_seltimeout,TO_290ms);
-
-   SGRAM_ACCESS(p_port);
+      if (RD_HARPOON(p_port+hp_scsisig) & p_data_bit)
 
-   if (RDW_HARPOON((p_port+hp_intstat)) & (RESET | TIMEOUT) ) {
+         i = 0;
 
-      WRW_HARPOON((p_port+hp_intstat),
-		  (RESET | TIMEOUT | SEL | BUS_FREE | PHASE));
+      else
 
-      WR_HARPOON(p_port+hp_page_ctrl,
-         (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
+         i++;
 
-      return(FALSE);  /*No legacy device */
       }
+}
 
-   else {
-
-      while(!(RDW_HARPOON((p_port+hp_intstat)) & BUS_FREE)) {
-				if (RD_HARPOON(p_port+hp_scsisig) & SCSI_REQ)
-					{
-					WR_HARPOON(p_port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
-      			ACCEPT_MSG(p_port);
-					}
-		}
 
-      WRW_HARPOON((p_port+hp_intstat), CLR_ALL_INT_1);
+/*---------------------------------------------------------------------
+ *
+ * Function: FPT_scvalq
+ *
+ * Description: Make sure we received a valid data byte.
+ *
+ *---------------------------------------------------------------------*/
 
-      WR_HARPOON(p_port+hp_page_ctrl,
-         (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
+static UCHAR FPT_scvalq(UCHAR p_quintet)
+{
+   UCHAR count;
 
-      return(TRUE);  /*Found one of them oldies! */
+   for (count=1; count < 0x08; count<<=1) {
+      if (!(p_quintet & count))
+         p_quintet -= 0x80;
       }
+
+   if (p_quintet & 0x18)
+      return(0);
+
+   else
+      return(1);
 }
 
-#if defined(DOS)
+
 /*---------------------------------------------------------------------
  *
- * Function: scsell for DOS
+ * Function: FPT_scsell
  *
  * Description: Select the specified device ID using a selection timeout
- *              less than 2ms.  This was specially required to solve
- *              the problem with Plextor 12X CD-ROM drive. This drive
- *					 was responding the Selection at the end of 4ms and 
- *					 hanging the system.
+ *              less than 4ms.  If somebody responds then it is a legacy
+ *              drive and this ID must be marked as such.
  *
  *---------------------------------------------------------------------*/
 
-UCHAR scsellDOS(USHORT p_port, UCHAR targ_id)
+static UCHAR FPT_scsell(ULONG p_port, UCHAR targ_id)
 {
-   USHORT i;
+   ULONG i;
 
    WR_HARPOON(p_port+hp_page_ctrl,
       (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE));
@@ -10244,7 +6739,7 @@ UCHAR scsellDOS(USHORT p_port, UCHAR tar
    ARAM_ACCESS(p_port);
 
    WR_HARPOON(p_port+hp_addstat,(RD_HARPOON(p_port+hp_addstat) | SCAM_TIMER));
-   WR_HARPOON(p_port+hp_seltimeout,TO_2ms);
+   WR_HARPOON(p_port+hp_seltimeout,TO_4ms);
 
 
    for (i = p_port+CMD_STRT; i < p_port+CMD_STRT+12; i+=2) {
@@ -10266,7 +6761,7 @@ UCHAR scsellDOS(USHORT p_port, UCHAR tar
 	    (RESET | PROG_HLT | TIMEOUT | AUTO_INT))) {}
 
    if (RDW_HARPOON((p_port+hp_intstat)) & RESET)
-         Wait(p_port, TO_250ms);
+         FPT_Wait(p_port, TO_250ms);
 
    DISABLE_AUTO(p_port);
 
@@ -10283,7 +6778,7 @@ UCHAR scsellDOS(USHORT p_port, UCHAR tar
       WR_HARPOON(p_port+hp_page_ctrl,
          (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
 
-      return(FALSE);  /*No legacy device */
+      return(0);  /*No legacy device */
       }
 
    else {
@@ -10301,24 +6796,19 @@ UCHAR scsellDOS(USHORT p_port, UCHAR tar
       WR_HARPOON(p_port+hp_page_ctrl,
          (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
 
-      return(TRUE);  /*Found one of them oldies! */
+      return(1);  /*Found one of them oldies! */
       }
 }
-#endif  /* DOS */
 
 /*---------------------------------------------------------------------
  *
- * Function: scwtsel
+ * Function: FPT_scwtsel
  *
  * Description: Wait to be selected by another SCAM initiator.
  *
  *---------------------------------------------------------------------*/
 
-#if defined(DOS)
-void scwtsel(USHORT p_port)
-#else
-void scwtsel(ULONG p_port)
-#endif
+static void FPT_scwtsel(ULONG p_port)
 {
    while(!(RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL)) {}
 }
@@ -10326,23 +6816,19 @@ void scwtsel(ULONG p_port)
 
 /*---------------------------------------------------------------------
  *
- * Function: inisci
+ * Function: FPT_inisci
  *
  * Description: Setup the data Structure with the info from the EEPROM.
  *
  *---------------------------------------------------------------------*/
 
-#if defined(DOS)
-void inisci(UCHAR p_card, USHORT p_port, UCHAR p_our_id)
-#else
-void inisci(UCHAR p_card, ULONG p_port, UCHAR p_our_id)
-#endif
+static void FPT_inisci(UCHAR p_card, ULONG p_port, UCHAR p_our_id)
 {
    UCHAR i,k,max_id;
    USHORT ee_data;
 	PNVRamInfo pCurrNvRam;
 
-	pCurrNvRam = BL_Card[p_card].pNvRamInfo;
+	pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
 
    if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
       max_id = 0x08;
@@ -10354,14 +6840,14 @@ void inisci(UCHAR p_card, ULONG p_port, 
 		for(i = 0; i < max_id; i++){
 
 			for(k = 0; k < 4; k++)
-				scamInfo[i].id_string[k] = pCurrNvRam->niScamTbl[i][k];
+				FPT_scamInfo[i].id_string[k] = pCurrNvRam->niScamTbl[i][k];
 			for(k = 4; k < ID_STRING_LENGTH; k++)
-				scamInfo[i].id_string[k] = (UCHAR) 0x00;
+				FPT_scamInfo[i].id_string[k] = (UCHAR) 0x00;
 
-	      if(scamInfo[i].id_string[0] == 0x00)
-      	   scamInfo[i].state = ID_UNUSED;  /*Default to unused ID. */
+	      if(FPT_scamInfo[i].id_string[0] == 0x00)
+      	   FPT_scamInfo[i].state = ID_UNUSED;  /*Default to unused ID. */
 	      else
-   	      scamInfo[i].state = ID_UNASSIGNED;  /*Default to unassigned ID. */
+   	      FPT_scamInfo[i].state = ID_UNASSIGNED;  /*Default to unassigned ID. */
 
 		}
 	}else {
@@ -10369,38 +6855,38 @@ void inisci(UCHAR p_card, ULONG p_port, 
    	   {
       	for (k=0; k < ID_STRING_LENGTH; k+=2)
 	         {
-   	      ee_data = utilEERead(p_port, (USHORT)((EE_SCAMBASE/2) +
+   	      ee_data = FPT_utilEERead(p_port, (USHORT)((EE_SCAMBASE/2) +
       	     (USHORT) (i*((USHORT)ID_STRING_LENGTH/2)) + (USHORT)(k/2)));
-         	scamInfo[i].id_string[k] = (UCHAR) ee_data;
+         	FPT_scamInfo[i].id_string[k] = (UCHAR) ee_data;
 	         ee_data >>= 8;
-   	      scamInfo[i].id_string[k+1] = (UCHAR) ee_data;
+   	      FPT_scamInfo[i].id_string[k+1] = (UCHAR) ee_data;
       	   }
 
-	      if ((scamInfo[i].id_string[0] == 0x00) ||
-   	       (scamInfo[i].id_string[0] == 0xFF))
+	      if ((FPT_scamInfo[i].id_string[0] == 0x00) ||
+   	       (FPT_scamInfo[i].id_string[0] == 0xFF))
 
-      	   scamInfo[i].state = ID_UNUSED;  /*Default to unused ID. */
+      	   FPT_scamInfo[i].state = ID_UNUSED;  /*Default to unused ID. */
 
 	      else
-   	      scamInfo[i].state = ID_UNASSIGNED;  /*Default to unassigned ID. */
+   	      FPT_scamInfo[i].state = ID_UNASSIGNED;  /*Default to unassigned ID. */
 
       	}
 	}
 	for(k = 0; k < ID_STRING_LENGTH; k++)
-		scamInfo[p_our_id].id_string[k] = scamHAString[k];
+		FPT_scamInfo[p_our_id].id_string[k] = FPT_scamHAString[k];
 
 }
 
 /*---------------------------------------------------------------------
  *
- * Function: scmachid
+ * Function: FPT_scmachid
  *
  * Description: Match the Device ID string with our values stored in
  *              the EEPROM.
  *
  *---------------------------------------------------------------------*/
 
-UCHAR scmachid(UCHAR p_card, UCHAR p_id_string[])
+static UCHAR FPT_scmachid(UCHAR p_card, UCHAR p_id_string[])
 {
 
    UCHAR i,k,match;
@@ -10408,28 +6894,20 @@ UCHAR scmachid(UCHAR p_card, UCHAR p_id_
 
    for (i=0; i < MAX_SCSI_TAR; i++) {
 
-#if !defined(SCAM_LEV_2)
-      if (scamInfo[i].state == ID_UNASSIGNED)
-         {
-#endif
-         match = TRUE;
+         match = 1;
 
          for (k=0; k < ID_STRING_LENGTH; k++)
             {
-            if (p_id_string[k] != scamInfo[i].id_string[k])
-               match = FALSE;
+            if (p_id_string[k] != FPT_scamInfo[i].id_string[k])
+               match = 0;
             }
 
          if (match)
             {
-            scamInfo[i].state = ID_ASSIGNED;
+            FPT_scamInfo[i].state = ID_ASSIGNED;
             return(i);
             }
 
-#if !defined(SCAM_LEV_2)
-         }
-#endif
-
       }
 
 
@@ -10448,17 +6926,17 @@ UCHAR scmachid(UCHAR p_card, UCHAR p_id_
       {
       i--;
 
-      if (scamInfo[match].state == ID_UNUSED)
+      if (FPT_scamInfo[match].state == ID_UNUSED)
          {
          for (k=0; k < ID_STRING_LENGTH; k++)
             {
-            scamInfo[match].id_string[k] = p_id_string[k];
+            FPT_scamInfo[match].id_string[k] = p_id_string[k];
             }
 
-         scamInfo[match].state = ID_ASSIGNED;
+         FPT_scamInfo[match].state = ID_ASSIGNED;
 
-			if(BL_Card[p_card].pNvRamInfo == NULL)
-	         BL_Card[p_card].globalFlags |= F_UPDATE_EEPROM;
+			if(FPT_BL_Card[p_card].pNvRamInfo == NULL)
+	         FPT_BL_Card[p_card].globalFlags |= F_UPDATE_EEPROM;
          return(match);
 
          }
@@ -10498,17 +6976,17 @@ UCHAR scmachid(UCHAR p_card, UCHAR p_id_
 
       i--;
 
-      if (scamInfo[match].state == ID_UNASSIGNED)
+      if (FPT_scamInfo[match].state == ID_UNASSIGNED)
          {
          for (k=0; k < ID_STRING_LENGTH; k++)
             {
-            scamInfo[match].id_string[k] = p_id_string[k];
+            FPT_scamInfo[match].id_string[k] = p_id_string[k];
             }
 
-         scamInfo[match].id_string[0] |= BIT(7);
-         scamInfo[match].state = ID_ASSIGNED;
-			if(BL_Card[p_card].pNvRamInfo == NULL)
-	         BL_Card[p_card].globalFlags |= F_UPDATE_EEPROM;
+         FPT_scamInfo[match].id_string[0] |= BIT(7);
+         FPT_scamInfo[match].state = ID_ASSIGNED;
+			if(FPT_BL_Card[p_card].pNvRamInfo == NULL)
+	         FPT_BL_Card[p_card].globalFlags |= F_UPDATE_EEPROM;
          return(match);
 
          }
@@ -10531,17 +7009,13 @@ UCHAR scmachid(UCHAR p_card, UCHAR p_id_
 
 /*---------------------------------------------------------------------
  *
- * Function: scsavdi
+ * Function: FPT_scsavdi
  *
  * Description: Save off the device SCAM ID strings.
  *
  *---------------------------------------------------------------------*/
 
-#if defined(DOS)
-void scsavdi(UCHAR p_card, USHORT p_port)
-#else
-void scsavdi(UCHAR p_card, ULONG p_port)
-#endif
+static void FPT_scsavdi(UCHAR p_card, ULONG p_port)
 {
    UCHAR i,k,max_id;
    USHORT ee_data,sum_data;
@@ -10551,11 +7025,11 @@ void scsavdi(UCHAR p_card, ULONG p_port)
 
    for (i = 1; i < EE_SCAMBASE/2; i++)
       {
-      sum_data += utilEERead(p_port, i);
+      sum_data += FPT_utilEERead(p_port, i);
       }
 
 
-   utilEEWriteOnOff(p_port,1);   /* Enable write access to the EEPROM */
+   FPT_utilEEWriteOnOff(p_port,1);   /* Enable write access to the EEPROM */
 
    if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
       max_id = 0x08;
@@ -10568,64 +7042,29 @@ void scsavdi(UCHAR p_card, ULONG p_port)
 
       for (k=0; k < ID_STRING_LENGTH; k+=2)
          {
-         ee_data = scamInfo[i].id_string[k+1];
+         ee_data = FPT_scamInfo[i].id_string[k+1];
          ee_data <<= 8;
-         ee_data |= scamInfo[i].id_string[k];
+         ee_data |= FPT_scamInfo[i].id_string[k];
          sum_data += ee_data;
-         utilEEWrite(p_port, ee_data, (USHORT)((EE_SCAMBASE/2) +
+         FPT_utilEEWrite(p_port, ee_data, (USHORT)((EE_SCAMBASE/2) +
             (USHORT)(i*((USHORT)ID_STRING_LENGTH/2)) + (USHORT)(k/2)));
          }
       }
 
 
-   utilEEWrite(p_port, sum_data, EEPROM_CHECK_SUM/2);
-   utilEEWriteOnOff(p_port,0);   /* Turn off write access */
+   FPT_utilEEWrite(p_port, sum_data, EEPROM_CHECK_SUM/2);
+   FPT_utilEEWriteOnOff(p_port,0);   /* Turn off write access */
 }
-#ident "$Id: diagnose.c 1.10 1997/06/10 16:51:47 mohan Exp $"
-/*----------------------------------------------------------------------
- *
- *
- *   Copyright 1995-1996 by Mylex Corporation.  All Rights Reserved
- *
- *   This file is available under both the GNU General Public License
- *   and a BSD-style copyright; see LICENSE.FlashPoint for details.
- *
- *   $Workfile:   diagnose.c  $
- *
- *   Description:  Diagnostic funtions for testing the integrity of
- *                 the HARPOON.
- *
- *   $Date: 1997/06/10 16:51:47 $
- *
- *   $Revision: 1.10 $
- *
- *----------------------------------------------------------------------*/
-
-/*#include <globals.h>*/
-
-#if (FW_TYPE==_UCB_MGR_)
-	/*#include <budi.h>*/
-#endif
-
-/*#include <sccbmgr.h>*/
-/*#include <blx30.h>*/
-/*#include <target.h>*/
-/*#include <eeprom.h>*/
-/*#include <harpoon.h>*/
 
 /*---------------------------------------------------------------------
  *
- * Function: XbowInit
+ * Function: FPT_XbowInit
  *
  * Description: Setup the Xbow for normal operation.
  *
  *---------------------------------------------------------------------*/
 
-#if defined(DOS)
-void XbowInit(USHORT port, UCHAR ScamFlg)
-#else
-void XbowInit(ULONG port, UCHAR ScamFlg)
-#endif
+static void FPT_XbowInit(ULONG port, UCHAR ScamFlg)
 {
 UCHAR i;
 
@@ -10647,18 +7086,13 @@ UCHAR i;
 
    WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
 
-#if defined(SCAM_LEV_2)
-   default_intena = RESET | RSEL | PROG_HLT | TIMEOUT |
+   FPT_default_intena = RESET | RSEL | PROG_HLT | TIMEOUT |
 		    BUS_FREE | XFER_CNT_0 | AUTO_INT;
 
    if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
-		default_intena |= SCAM_SEL;
+		FPT_default_intena |= SCAM_SEL;
 
-#else
-   default_intena = RESET | RSEL | PROG_HLT | TIMEOUT |
-		    BUS_FREE | XFER_CNT_0 | AUTO_INT;
-#endif
-   WRW_HARPOON((port+hp_intena), default_intena);
+   WRW_HARPOON((port+hp_intena), FPT_default_intena);
 
    WR_HARPOON(port+hp_seltimeout,TO_290ms);
 
@@ -10667,26 +7101,6 @@ UCHAR i;
    if (RD_HARPOON(port+hp_page_ctrl) & NARROW_SCSI_CARD)
       WR_HARPOON(port+hp_addstat,SCSI_MODE8);
 
-#if defined(NO_BIOS_OPTION)
-
-   WR_HARPOON(port+hp_synctarg_0,NARROW_SCSI);
-   WR_HARPOON(port+hp_synctarg_1,NARROW_SCSI);
-   WR_HARPOON(port+hp_synctarg_2,NARROW_SCSI);
-   WR_HARPOON(port+hp_synctarg_3,NARROW_SCSI);
-   WR_HARPOON(port+hp_synctarg_4,NARROW_SCSI);
-   WR_HARPOON(port+hp_synctarg_5,NARROW_SCSI);
-   WR_HARPOON(port+hp_synctarg_6,NARROW_SCSI);
-   WR_HARPOON(port+hp_synctarg_7,NARROW_SCSI);
-   WR_HARPOON(port+hp_synctarg_8,NARROW_SCSI);
-   WR_HARPOON(port+hp_synctarg_9,NARROW_SCSI);
-   WR_HARPOON(port+hp_synctarg_10,NARROW_SCSI);
-   WR_HARPOON(port+hp_synctarg_11,NARROW_SCSI);
-   WR_HARPOON(port+hp_synctarg_12,NARROW_SCSI);
-   WR_HARPOON(port+hp_synctarg_13,NARROW_SCSI);
-   WR_HARPOON(port+hp_synctarg_14,NARROW_SCSI);
-   WR_HARPOON(port+hp_synctarg_15,NARROW_SCSI);
-
-#endif
 	WR_HARPOON(port+hp_page_ctrl, i);
 
 }
@@ -10694,17 +7108,13 @@ UCHAR i;
 
 /*---------------------------------------------------------------------
  *
- * Function: BusMasterInit
+ * Function: FPT_BusMasterInit
  *
  * Description: Initialize the BusMaster for normal operations.
  *
  *---------------------------------------------------------------------*/
 
-#if defined(DOS)
-void BusMasterInit(USHORT p_port)
-#else
-void BusMasterInit(ULONG p_port)
-#endif
+static void FPT_BusMasterInit(ULONG p_port)
 {
 
 
@@ -10719,13 +7129,6 @@ void BusMasterInit(ULONG p_port)
    WR_HARPOON(p_port+hp_ee_ctrl, (SCSI_TERM_ENA_H));
 
 
-#if defined(NT)
-
-   WR_HARPOON(p_port+hp_pci_cmd_cfg, (RD_HARPOON(p_port+hp_pci_cmd_cfg)
-      & ~MEM_SPACE_ENA));
-
-#endif
-
    RD_HARPOON(p_port+hp_int_status);        /*Clear interrupts. */
    WR_HARPOON(p_port+hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
    WR_HARPOON(p_port+hp_page_ctrl, (RD_HARPOON(p_port+hp_page_ctrl) &
@@ -10735,147 +7138,14 @@ void BusMasterInit(ULONG p_port)
 
 /*---------------------------------------------------------------------
  *
- * Function: DiagXbow
- *
- * Description: Test Xbow integrity.  Non-zero return indicates an error.
- *
- *---------------------------------------------------------------------*/
-
-#if defined(DOS)
-int DiagXbow(USHORT port)
-#else
-int DiagXbow(ULONG port)
-#endif
-{
-   unsigned char fifo_cnt,loop_cnt;
-
-   unsigned char fifodata[5];
-   fifodata[0] = 0x00;
-   fifodata[1] = 0xFF;
-   fifodata[2] = 0x55;
-   fifodata[3] = 0xAA;
-   fifodata[4] = 0x00;
-
-
-   WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
-   WRW_HARPOON((port+hp_intena), 0x0000);
-
-   WR_HARPOON(port+hp_seltimeout,TO_5ms);
-
-   WR_HARPOON(port+hp_portctrl_0,START_TO);
-
-
-   for(fifodata[4] = 0x01; fifodata[4] != (UCHAR) 0; fifodata[4] = fifodata[4] << 1) {
-
-      WR_HARPOON(port+hp_selfid_0,fifodata[4]);
-      WR_HARPOON(port+hp_selfid_1,fifodata[4]);
-
-      if ((RD_HARPOON(port+hp_selfid_0) != fifodata[4]) ||
-          (RD_HARPOON(port+hp_selfid_1) != fifodata[4]))
-         return(1);
-      }
-
-
-   for(loop_cnt = 0; loop_cnt < 4; loop_cnt++) {
-
-      WR_HARPOON(port+hp_portctrl_0,(HOST_PORT | HOST_WRT | START_TO));
-
-
-      for (fifo_cnt = 0; fifo_cnt < FIFO_LEN; fifo_cnt++) {
-
-         WR_HARPOON(port+hp_fifodata_0, fifodata[loop_cnt]);
-         }
-
-
-      if (!(RD_HARPOON(port+hp_xferstat) & FIFO_FULL))
-         return(1);
-
-
-      WR_HARPOON(port+hp_portctrl_0,(HOST_PORT | START_TO));
-
-      for (fifo_cnt = 0; fifo_cnt < FIFO_LEN; fifo_cnt++) {
-
-         if (RD_HARPOON(port+hp_fifodata_0) != fifodata[loop_cnt])
-            return(1);
-         }
-
-
-      if (!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY))
-         return(1);
-      }
-
-
-   while(!(RDW_HARPOON((port+hp_intstat)) & TIMEOUT)) {}
-
-
-   WR_HARPOON(port+hp_seltimeout,TO_290ms);
-
-   WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
-
-   WRW_HARPOON((port+hp_intena), default_intena);
-
-   return(0);
-}
-
-
-/*---------------------------------------------------------------------
- *
- * Function: DiagBusMaster
- *
- * Description: Test BusMaster integrity.  Non-zero return indicates an
- *              error.
- *
- *---------------------------------------------------------------------*/
-
-#if defined(DOS)
-int DiagBusMaster(USHORT port)
-#else
-int DiagBusMaster(ULONG port)
-#endif
-{
-   UCHAR testdata;
-
-   for(testdata = (UCHAR) 1; testdata != (UCHAR)0; testdata = testdata << 1) {
-
-      WR_HARPOON(port+hp_xfer_cnt_lo,testdata);
-      WR_HARPOON(port+hp_xfer_cnt_mi,testdata);
-      WR_HARPOON(port+hp_xfer_cnt_hi,testdata);
-      WR_HARPOON(port+hp_host_addr_lo,testdata);
-      WR_HARPOON(port+hp_host_addr_lmi,testdata);
-      WR_HARPOON(port+hp_host_addr_hmi,testdata);
-      WR_HARPOON(port+hp_host_addr_hi,testdata);
-
-      if ((RD_HARPOON(port+hp_xfer_cnt_lo) != testdata)   ||
-          (RD_HARPOON(port+hp_xfer_cnt_mi) != testdata)   ||
-          (RD_HARPOON(port+hp_xfer_cnt_hi) != testdata)   ||
-          (RD_HARPOON(port+hp_host_addr_lo) != testdata)  ||
-          (RD_HARPOON(port+hp_host_addr_lmi) != testdata) ||
-          (RD_HARPOON(port+hp_host_addr_hmi) != testdata) ||
-          (RD_HARPOON(port+hp_host_addr_hi) != testdata))
-
-         return(1);
-      }
-   RD_HARPOON(port+hp_int_status);        /*Clear interrupts. */
-   return(0);
-}
-
-
-
-/*---------------------------------------------------------------------
- *
- * Function: DiagEEPROM
+ * Function: FPT_DiagEEPROM
  *
  * Description: Verfiy checksum and 'Key' and initialize the EEPROM if
  *              necessary.
  *
  *---------------------------------------------------------------------*/
 
-#if defined(DOS)
-void DiagEEPROM(USHORT p_port)
-#else
-void DiagEEPROM(ULONG p_port)
-#endif
-
+static void FPT_DiagEEPROM(ULONG p_port)
 {
    USHORT index,temp,max_wd_cnt;
 
@@ -10884,185 +7154,148 @@ void DiagEEPROM(ULONG p_port)
    else
       max_wd_cnt = EEPROM_WD_CNT * 2;
 
-   temp = utilEERead(p_port, FW_SIGNATURE/2);
+   temp = FPT_utilEERead(p_port, FW_SIGNATURE/2);
 
    if (temp == 0x4641) {
 
       for (index = 2; index < max_wd_cnt; index++) {
 
-         temp += utilEERead(p_port, index);
+         temp += FPT_utilEERead(p_port, index);
 
          }
 
-      if (temp == utilEERead(p_port, EEPROM_CHECK_SUM/2)) {
+      if (temp == FPT_utilEERead(p_port, EEPROM_CHECK_SUM/2)) {
 
          return;          /*EEPROM is Okay so return now! */
          }
       }
 
 
-   utilEEWriteOnOff(p_port,(UCHAR)1);
+   FPT_utilEEWriteOnOff(p_port,(UCHAR)1);
 
    for (index = 0; index < max_wd_cnt; index++) {
 
-      utilEEWrite(p_port, 0x0000, index);
+      FPT_utilEEWrite(p_port, 0x0000, index);
       }
 
    temp = 0;
 
-   utilEEWrite(p_port, 0x4641, FW_SIGNATURE/2);
+   FPT_utilEEWrite(p_port, 0x4641, FW_SIGNATURE/2);
    temp += 0x4641;
-   utilEEWrite(p_port, 0x3920, MODEL_NUMB_0/2);
+   FPT_utilEEWrite(p_port, 0x3920, MODEL_NUMB_0/2);
    temp += 0x3920;
-   utilEEWrite(p_port, 0x3033, MODEL_NUMB_2/2);
+   FPT_utilEEWrite(p_port, 0x3033, MODEL_NUMB_2/2);
    temp += 0x3033;
-   utilEEWrite(p_port, 0x2020, MODEL_NUMB_4/2);
+   FPT_utilEEWrite(p_port, 0x2020, MODEL_NUMB_4/2);
    temp += 0x2020;
-   utilEEWrite(p_port, 0x70D3, SYSTEM_CONFIG/2);
+   FPT_utilEEWrite(p_port, 0x70D3, SYSTEM_CONFIG/2);
    temp += 0x70D3;
-   utilEEWrite(p_port, 0x0010, BIOS_CONFIG/2);
+   FPT_utilEEWrite(p_port, 0x0010, BIOS_CONFIG/2);
    temp += 0x0010;
-   utilEEWrite(p_port, 0x0003, SCAM_CONFIG/2);
+   FPT_utilEEWrite(p_port, 0x0003, SCAM_CONFIG/2);
    temp += 0x0003;
-   utilEEWrite(p_port, 0x0007, ADAPTER_SCSI_ID/2);
+   FPT_utilEEWrite(p_port, 0x0007, ADAPTER_SCSI_ID/2);
    temp += 0x0007;
 
-   utilEEWrite(p_port, 0x0000, IGNORE_B_SCAN/2);
+   FPT_utilEEWrite(p_port, 0x0000, IGNORE_B_SCAN/2);
    temp += 0x0000;
-   utilEEWrite(p_port, 0x0000, SEND_START_ENA/2);
+   FPT_utilEEWrite(p_port, 0x0000, SEND_START_ENA/2);
    temp += 0x0000;
-   utilEEWrite(p_port, 0x0000, DEVICE_ENABLE/2);
+   FPT_utilEEWrite(p_port, 0x0000, DEVICE_ENABLE/2);
    temp += 0x0000;
 
-   utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL01/2);
+   FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL01/2);
    temp += 0x4242;
-   utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL23/2);
+   FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL23/2);
    temp += 0x4242;
-   utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL45/2);
+   FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL45/2);
    temp += 0x4242;
-   utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL67/2);
+   FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL67/2);
    temp += 0x4242;
-   utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL89/2);
+   FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL89/2);
    temp += 0x4242;
-   utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLab/2);
+   FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLab/2);
    temp += 0x4242;
-   utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLcd/2);
+   FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLcd/2);
    temp += 0x4242;
-   utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLef/2);
+   FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLef/2);
    temp += 0x4242;
 
 
-   utilEEWrite(p_port, 0x6C46, 64/2);  /*PRODUCT ID */
+   FPT_utilEEWrite(p_port, 0x6C46, 64/2);  /*PRODUCT ID */
    temp += 0x6C46;
-   utilEEWrite(p_port, 0x7361, 66/2);  /* FlashPoint LT   */
+   FPT_utilEEWrite(p_port, 0x7361, 66/2);  /* FlashPoint LT   */
    temp += 0x7361;
-   utilEEWrite(p_port, 0x5068, 68/2);
+   FPT_utilEEWrite(p_port, 0x5068, 68/2);
    temp += 0x5068;
-   utilEEWrite(p_port, 0x696F, 70/2);
+   FPT_utilEEWrite(p_port, 0x696F, 70/2);
    temp += 0x696F;
-   utilEEWrite(p_port, 0x746E, 72/2);
+   FPT_utilEEWrite(p_port, 0x746E, 72/2);
    temp += 0x746E;
-   utilEEWrite(p_port, 0x4C20, 74/2);
+   FPT_utilEEWrite(p_port, 0x4C20, 74/2);
    temp += 0x4C20;
-   utilEEWrite(p_port, 0x2054, 76/2);
+   FPT_utilEEWrite(p_port, 0x2054, 76/2);
    temp += 0x2054;
-   utilEEWrite(p_port, 0x2020, 78/2);
+   FPT_utilEEWrite(p_port, 0x2020, 78/2);
    temp += 0x2020;
 
    index = ((EE_SCAMBASE/2)+(7*16));
-   utilEEWrite(p_port, (0x0700+TYPE_CODE0), index);
+   FPT_utilEEWrite(p_port, (0x0700+TYPE_CODE0), index);
    temp += (0x0700+TYPE_CODE0);
    index++;
-   utilEEWrite(p_port, 0x5542, index);            /*Vendor ID code */
+   FPT_utilEEWrite(p_port, 0x5542, index);            /*Vendor ID code */
    temp += 0x5542;                                /* BUSLOGIC      */
    index++;
-   utilEEWrite(p_port, 0x4C53, index);
+   FPT_utilEEWrite(p_port, 0x4C53, index);
    temp += 0x4C53;
    index++;
-   utilEEWrite(p_port, 0x474F, index);
+   FPT_utilEEWrite(p_port, 0x474F, index);
    temp += 0x474F;
    index++;
-   utilEEWrite(p_port, 0x4349, index);
+   FPT_utilEEWrite(p_port, 0x4349, index);
    temp += 0x4349;
    index++;
-   utilEEWrite(p_port, 0x5442, index);            /*Vendor unique code */
+   FPT_utilEEWrite(p_port, 0x5442, index);            /*Vendor unique code */
    temp += 0x5442;                         /* BT- 930           */
    index++;
-   utilEEWrite(p_port, 0x202D, index);
+   FPT_utilEEWrite(p_port, 0x202D, index);
    temp += 0x202D;
    index++;
-   utilEEWrite(p_port, 0x3339, index);
+   FPT_utilEEWrite(p_port, 0x3339, index);
    temp += 0x3339;
    index++;                                 /*Serial #          */
-   utilEEWrite(p_port, 0x2030, index);             /* 01234567         */
+   FPT_utilEEWrite(p_port, 0x2030, index);             /* 01234567         */
    temp += 0x2030;
    index++;
-   utilEEWrite(p_port, 0x5453, index);
+   FPT_utilEEWrite(p_port, 0x5453, index);
    temp += 0x5453;
    index++;
-   utilEEWrite(p_port, 0x5645, index);
+   FPT_utilEEWrite(p_port, 0x5645, index);
    temp += 0x5645;
    index++;
-   utilEEWrite(p_port, 0x2045, index);
+   FPT_utilEEWrite(p_port, 0x2045, index);
    temp += 0x2045;
    index++;
-   utilEEWrite(p_port, 0x202F, index);
+   FPT_utilEEWrite(p_port, 0x202F, index);
    temp += 0x202F;
    index++;
-   utilEEWrite(p_port, 0x4F4A, index);
+   FPT_utilEEWrite(p_port, 0x4F4A, index);
    temp += 0x4F4A;
    index++;
-   utilEEWrite(p_port, 0x204E, index);
+   FPT_utilEEWrite(p_port, 0x204E, index);
    temp += 0x204E;
    index++;
-   utilEEWrite(p_port, 0x3539, index);
+   FPT_utilEEWrite(p_port, 0x3539, index);
    temp += 0x3539;
 
 
 
-   utilEEWrite(p_port, temp, EEPROM_CHECK_SUM/2);
+   FPT_utilEEWrite(p_port, temp, EEPROM_CHECK_SUM/2);
 
-   utilEEWriteOnOff(p_port,(UCHAR)0);
+   FPT_utilEEWriteOnOff(p_port,(UCHAR)0);
 
 }
 
-#ident "$Id: utility.c 1.23 1997/06/10 16:55:06 mohan Exp $"
-/*----------------------------------------------------------------------
- *
- *
- *   Copyright 1995-1996 by Mylex Corporation.  All Rights Reserved
- *
- *   This file is available under both the GNU General Public License
- *   and a BSD-style copyright; see LICENSE.FlashPoint for details.
- *
- *   $Workfile:   utility.c  $
- *
- *   Description:  Utility functions relating to queueing and EEPROM
- *                 manipulation and any other garbage functions.
- *
- *   $Date: 1997/06/10 16:55:06 $
- *
- *   $Revision: 1.23 $
- *
- *----------------------------------------------------------------------*/
-/*#include <globals.h>*/
-
-#if (FW_TYPE==_UCB_MGR_)
-	/*#include <budi.h>*/
-#endif
-
-/*#include <sccbmgr.h>*/
-/*#include <blx30.h>*/
-/*#include <target.h>*/
-/*#include <scsi2.h>*/
-/*#include <harpoon.h>*/
-
-
-/*
-extern SCCBCARD BL_Card[MAX_CARDS];
-extern SCCBMGR_TAR_INFO sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR];
-extern unsigned int SccbGlobalFlags;
-*/
 
 /*---------------------------------------------------------------------
  *
@@ -11072,7 +7305,7 @@ extern unsigned int SccbGlobalFlags;
  *
  *---------------------------------------------------------------------*/
 
-void queueSearchSelect(PSCCBcard pCurrCard, UCHAR p_card)
+static void FPT_queueSearchSelect(PSCCBcard pCurrCard, UCHAR p_card)
 {
    UCHAR scan_ptr, lun;
    PSCCBMgr_tar_info currTar_Info;
@@ -11081,7 +7314,7 @@ void queueSearchSelect(PSCCBcard pCurrCa
    scan_ptr = pCurrCard->scanIndex;
 	do 
 	{
-		currTar_Info = &sccbMgrTbl[p_card][scan_ptr];
+		currTar_Info = &FPT_sccbMgrTbl[p_card][scan_ptr];
 		if((pCurrCard->globalFlags & F_CONLUN_IO) && 
 			((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
 		{
@@ -11094,7 +7327,7 @@ void queueSearchSelect(PSCCBcard pCurrCa
 				
 				for(lun=0; lun < MAX_LUN; lun++)
 				{
-					if(currTar_Info->TarLUNBusy[lun] == FALSE)
+					if(currTar_Info->TarLUNBusy[lun] == 0)
 					{
 
 						pCurrCard->currentSCCB = currTar_Info->TarSelQ_Head;
@@ -11153,7 +7386,7 @@ void queueSearchSelect(PSCCBcard pCurrCa
 		else
 		{
 			if ((currTar_Info->TarSelQ_Cnt != 0) &&
-				(currTar_Info->TarLUNBusy[0] == FALSE))
+				(currTar_Info->TarLUNBusy[0] == 0))
 			{
 
 				pCurrCard->currentSCCB = currTar_Info->TarSelQ_Head;
@@ -11203,7 +7436,7 @@ void queueSearchSelect(PSCCBcard pCurrCa
  *
  *---------------------------------------------------------------------*/
 
-void queueSelectFail(PSCCBcard pCurrCard, UCHAR p_card)
+static void FPT_queueSelectFail(PSCCBcard pCurrCard, UCHAR p_card)
 {
    UCHAR thisTarg;
    PSCCBMgr_tar_info currTar_Info;
@@ -11211,7 +7444,7 @@ void queueSelectFail(PSCCBcard pCurrCard
    if (pCurrCard->currentSCCB != NULL)
 	  {
 	  thisTarg = (UCHAR)(((PSCCB)(pCurrCard->currentSCCB))->TargID);
-      currTar_Info = &sccbMgrTbl[p_card][thisTarg];
+      currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
 
       pCurrCard->currentSCCB->Sccb_backlink = (PSCCB)NULL;
 
@@ -11242,103 +7475,10 @@ void queueSelectFail(PSCCBcard pCurrCard
  *
  *---------------------------------------------------------------------*/
 
-void queueCmdComplete(PSCCBcard pCurrCard, PSCCB p_sccb, UCHAR p_card)
+static void FPT_queueCmdComplete(PSCCBcard pCurrCard, PSCCB p_sccb,
+				 UCHAR p_card)
 {
 
-#if (FW_TYPE==_UCB_MGR_)
-
-   u08bits SCSIcmd;
-   CALL_BK_FN callback;
-   PSCCBMgr_tar_info currTar_Info;
-
-   PUCB p_ucb;
-   p_ucb=p_sccb->Sccb_ucb_ptr;
-
-   SCSIcmd = p_sccb->Cdb[0];
-
-
-   if (!(p_sccb->Sccb_XferState & F_ALL_XFERRED))
-   {
-
-      if ((p_ucb->UCB_opcode & OPC_CHK_UNDER_OVER_RUN)                     &&
-         (p_sccb->HostStatus == SCCB_COMPLETE)                             &&
-         (p_sccb->TargetStatus != SSCHECK))
-
-         if ((SCSIcmd == SCSI_READ)             ||
-             (SCSIcmd == SCSI_WRITE)            ||
-             (SCSIcmd == SCSI_READ_EXTENDED)    ||
-             (SCSIcmd == SCSI_WRITE_EXTENDED)   ||
-             (SCSIcmd == SCSI_WRITE_AND_VERIFY) ||
-             (SCSIcmd == SCSI_START_STOP_UNIT)  ||
-             (pCurrCard->globalFlags & F_NO_FILTER)
-            )
-               p_sccb->HostStatus = SCCB_DATA_UNDER_RUN;
-   }
-
-   p_ucb->UCB_status=SCCB_SUCCESS;
-
-   if ((p_ucb->UCB_hbastat=p_sccb->HostStatus) || (p_ucb->UCB_scsistat=p_sccb->TargetStatus))
-   {
-      p_ucb->UCB_status=SCCB_ERROR;
-   }
-
-   if ((p_sccb->OperationCode == RESIDUAL_SG_COMMAND) ||
-      (p_sccb->OperationCode == RESIDUAL_COMMAND))
-   {
-
-         utilUpdateResidual(p_sccb);
-
-         p_ucb->UCB_datalen=p_sccb->DataLength;
-   }
-
-   pCurrCard->cmdCounter--;
-   if (!pCurrCard->cmdCounter)
-   {
-
-      if (pCurrCard->globalFlags & F_GREEN_PC)
-      {
-         WR_HARPOON(pCurrCard->ioPort+hp_clkctrl_0,(PWR_DWN | CLKCTRL_DEFAULT));
-         WR_HARPOON(pCurrCard->ioPort+hp_sys_ctrl, STOP_CLK);
-      }
-
-      WR_HARPOON(pCurrCard->ioPort+hp_semaphore,
-      (RD_HARPOON(pCurrCard->ioPort+hp_semaphore) & ~SCCB_MGR_ACTIVE));
-   }
-
-	if(pCurrCard->discQCount != 0)
-	{
-      currTar_Info = &sccbMgrTbl[p_card][p_sccb->TargID];
-		if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
-			((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
-		{
-			pCurrCard->discQCount--;
-			pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_sccb->Lun]] = NULL;
-		}
-		else
-		{
-			if(p_sccb->Sccb_tag)
-			{
-				pCurrCard->discQCount--;
-				pCurrCard->discQ_Tbl[p_sccb->Sccb_tag] = NULL;
-			}else
-			{
-				pCurrCard->discQCount--;
-				pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = NULL;
-			}
-		}
-
-	}
-   callback = (CALL_BK_FN)p_ucb->UCB_callback;
-   callback(p_ucb);
-   pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
-   pCurrCard->currentSCCB = NULL;
-}
-
-
-
-
-#else
-
    UCHAR i, SCSIcmd;
    CALL_BK_FN callback;
    PSCCBMgr_tar_info currTar_Info;
@@ -11383,7 +7523,7 @@ void queueCmdComplete(PSCCBcard pCurrCar
    if ((p_sccb->OperationCode == RESIDUAL_SG_COMMAND) ||
 	  (p_sccb->OperationCode == RESIDUAL_COMMAND)) {
 
-		 utilUpdateResidual(p_sccb);
+		 FPT_utilUpdateResidual(p_sccb);
 		 }
 
    pCurrCard->cmdCounter--;
@@ -11401,7 +7541,7 @@ void queueCmdComplete(PSCCBcard pCurrCar
 
 	if(pCurrCard->discQCount != 0)
 	{
-      currTar_Info = &sccbMgrTbl[p_card][p_sccb->TargID];
+      currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
 		if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
 			((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
 		{
@@ -11428,7 +7568,6 @@ void queueCmdComplete(PSCCBcard pCurrCar
    pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
    pCurrCard->currentSCCB = NULL;
 }
-#endif /* ( if FW_TYPE==...) */
 
 
 /*---------------------------------------------------------------------
@@ -11438,30 +7577,30 @@ void queueCmdComplete(PSCCBcard pCurrCar
  * Description: Add SCCB to our disconnect array.
  *
  *---------------------------------------------------------------------*/
-void queueDisconnect(PSCCB p_sccb, UCHAR p_card)
+static void FPT_queueDisconnect(PSCCB p_sccb, UCHAR p_card)
 {
    PSCCBMgr_tar_info currTar_Info;
 
-	currTar_Info = &sccbMgrTbl[p_card][p_sccb->TargID];
+	currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
 
-	if(((BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
+	if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
 		((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
 	{
-		BL_Card[p_card].discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_sccb->Lun]] = p_sccb;
+		FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_sccb->Lun]] = p_sccb;
 	}
 	else
 	{
 		if (p_sccb->Sccb_tag)
 		{
-			BL_Card[p_card].discQ_Tbl[p_sccb->Sccb_tag] = p_sccb;
-			sccbMgrTbl[p_card][p_sccb->TargID].TarLUNBusy[0] = FALSE;
-			sccbMgrTbl[p_card][p_sccb->TargID].TarTagQ_Cnt++;
+			FPT_BL_Card[p_card].discQ_Tbl[p_sccb->Sccb_tag] = p_sccb;
+			FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarLUNBusy[0] = 0;
+			FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarTagQ_Cnt++;
 		}else
 		{
-			BL_Card[p_card].discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = p_sccb;
+			FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = p_sccb;
 		}
 	}
-	BL_Card[p_card].currentSCCB = NULL;
+	FPT_BL_Card[p_card].currentSCCB = NULL;
 }
 
 
@@ -11473,29 +7612,29 @@ void queueDisconnect(PSCCB p_sccb, UCHAR
  *
  *---------------------------------------------------------------------*/
 
-void  queueFlushSccb(UCHAR p_card, UCHAR error_code)
+static void  FPT_queueFlushSccb(UCHAR p_card, UCHAR error_code)
 {
    UCHAR qtag,thisTarg;
    PSCCB currSCCB;
    PSCCBMgr_tar_info currTar_Info;
 
-   currSCCB = BL_Card[p_card].currentSCCB;
+   currSCCB = FPT_BL_Card[p_card].currentSCCB;
 	if(currSCCB != NULL)
 	{
 	   thisTarg = (UCHAR)currSCCB->TargID;
-   	currTar_Info = &sccbMgrTbl[p_card][thisTarg];
+   	currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
 
 	   for (qtag=0; qtag<QUEUE_DEPTH; qtag++) {
 
-		  if (BL_Card[p_card].discQ_Tbl[qtag] && 
-					(BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg))
+		  if (FPT_BL_Card[p_card].discQ_Tbl[qtag] && 
+					(FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg))
 			 {
 
-			 BL_Card[p_card].discQ_Tbl[qtag]->HostStatus = (UCHAR)error_code;
+			 FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus = (UCHAR)error_code;
 			
-			 queueCmdComplete(&BL_Card[p_card],BL_Card[p_card].discQ_Tbl[qtag], p_card);
+			 FPT_queueCmdComplete(&FPT_BL_Card[p_card],FPT_BL_Card[p_card].discQ_Tbl[qtag], p_card);
 
-			 BL_Card[p_card].discQ_Tbl[qtag] = NULL;
+			 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
 			 currTar_Info->TarTagQ_Cnt--;
 
 			 }
@@ -11512,24 +7651,25 @@ void  queueFlushSccb(UCHAR p_card, UCHAR
  *
  *---------------------------------------------------------------------*/
 
-void  queueFlushTargSccb(UCHAR p_card, UCHAR thisTarg, UCHAR error_code)
+static void  FPT_queueFlushTargSccb(UCHAR p_card, UCHAR thisTarg,
+				    UCHAR error_code)
 {
    UCHAR qtag;
    PSCCBMgr_tar_info currTar_Info;
 
-   currTar_Info = &sccbMgrTbl[p_card][thisTarg];
+   currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
 
    for (qtag=0; qtag<QUEUE_DEPTH; qtag++) {
 
-	  if (BL_Card[p_card].discQ_Tbl[qtag] && 
-				(BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg))
+	  if (FPT_BL_Card[p_card].discQ_Tbl[qtag] && 
+				(FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg))
 		 {
 
-		 BL_Card[p_card].discQ_Tbl[qtag]->HostStatus = (UCHAR)error_code;
+		 FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus = (UCHAR)error_code;
 
-		 queueCmdComplete(&BL_Card[p_card],BL_Card[p_card].discQ_Tbl[qtag], p_card);
+		 FPT_queueCmdComplete(&FPT_BL_Card[p_card],FPT_BL_Card[p_card].discQ_Tbl[qtag], p_card);
 
-		 BL_Card[p_card].discQ_Tbl[qtag] = NULL;
+		 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
 		 currTar_Info->TarTagQ_Cnt--;
 
 		 }
@@ -11541,10 +7681,10 @@ void  queueFlushTargSccb(UCHAR p_card, U
 
 
 
-void queueAddSccb(PSCCB p_SCCB, UCHAR p_card)
+static void FPT_queueAddSccb(PSCCB p_SCCB, UCHAR p_card)
 {
    PSCCBMgr_tar_info currTar_Info;
-   currTar_Info = &sccbMgrTbl[p_card][p_SCCB->TargID];
+   currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
 
    p_SCCB->Sccb_forwardlink = NULL;
 
@@ -11575,12 +7715,12 @@ void queueAddSccb(PSCCB p_SCCB, UCHAR p_
  *
  *---------------------------------------------------------------------*/
 
-UCHAR queueFindSccb(PSCCB p_SCCB, UCHAR p_card)
+static UCHAR FPT_queueFindSccb(PSCCB p_SCCB, UCHAR p_card)
 {
    PSCCB q_ptr;
    PSCCBMgr_tar_info currTar_Info;
 
-   currTar_Info = &sccbMgrTbl[p_card][p_SCCB->TargID];
+   currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
 
    q_ptr = currTar_Info->TarSelQ_Head;
 
@@ -11609,7 +7749,7 @@ UCHAR queueFindSccb(PSCCB p_SCCB, UCHAR 
 
 		 currTar_Info->TarSelQ_Cnt--;
 
-		 return(TRUE);
+		 return(1);
 		 }
 
 	  else {
@@ -11618,7 +7758,7 @@ UCHAR queueFindSccb(PSCCB p_SCCB, UCHAR 
 	  }
 
 
-   return(FALSE);
+   return(0);
 
 }
 
@@ -11636,15 +7776,11 @@ UCHAR queueFindSccb(PSCCB p_SCCB, UCHAR 
  *
  *---------------------------------------------------------------------*/
 
-void  utilUpdateResidual(PSCCB p_SCCB)
+static void  FPT_utilUpdateResidual(PSCCB p_SCCB)
 {
    ULONG partial_cnt;
    UINT  sg_index;
-#if defined(COMPILER_16_BIT) && !defined(DOS)
-   ULONG far *sg_ptr;
-#else
    ULONG *sg_ptr;
-#endif
 
    if (p_SCCB->Sccb_XferState & F_ALL_XFERRED) {
 
@@ -11657,11 +7793,7 @@ void  utilUpdateResidual(PSCCB p_SCCB)
 
 		 sg_index = p_SCCB->Sccb_sgseg;
 
-#if defined(COMPILER_16_BIT) && !defined(DOS)
-		 sg_ptr = (ULONG far *)p_SCCB->DataPointer;
-#else
 		 sg_ptr = (ULONG *)p_SCCB->DataPointer;
-#endif
 
 		 if (p_SCCB->Sccb_SGoffset) {
 
@@ -11694,17 +7826,13 @@ void  utilUpdateResidual(PSCCB p_SCCB)
  *
  *---------------------------------------------------------------------*/
 
-#if defined(DOS)
-void Wait1Second(USHORT p_port)
-#else
-void Wait1Second(ULONG p_port)
-#endif
+static void FPT_Wait1Second(ULONG p_port)
 {
    UCHAR i;
 
    for(i=0; i < 4; i++) {
 
-	  Wait(p_port, TO_250ms);
+	  FPT_Wait(p_port, TO_250ms);
 
 	  if ((RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST))
 		 break;
@@ -11717,17 +7845,13 @@ void Wait1Second(ULONG p_port)
 
 /*---------------------------------------------------------------------
  *
- * Function: Wait
+ * Function: FPT_Wait
  *
  * Description: Wait the desired delay.
  *
  *---------------------------------------------------------------------*/
 
-#if defined(DOS)
-void Wait(USHORT p_port, UCHAR p_delay)
-#else
-void Wait(ULONG p_port, UCHAR p_delay)
-#endif
+static void FPT_Wait(ULONG p_port, UCHAR p_delay)
 {
    UCHAR old_timer;
    UCHAR green_flag;
@@ -11739,7 +7863,7 @@ void Wait(ULONG p_port, UCHAR p_delay)
 
    WR_HARPOON(p_port+hp_seltimeout,p_delay);
    WRW_HARPOON((p_port+hp_intstat), TIMEOUT);
-   WRW_HARPOON((p_port+hp_intena), (default_intena & ~TIMEOUT));
+   WRW_HARPOON((p_port+hp_intena), (FPT_default_intena & ~TIMEOUT));
 
 
    WR_HARPOON(p_port+hp_portctrl_0,
@@ -11758,7 +7882,7 @@ void Wait(ULONG p_port, UCHAR p_delay)
 	  (RD_HARPOON(p_port+hp_portctrl_0) & ~START_TO));
 
    WRW_HARPOON((p_port+hp_intstat), TIMEOUT);
-   WRW_HARPOON((p_port+hp_intena), default_intena);
+   WRW_HARPOON((p_port+hp_intena), FPT_default_intena);
 
    WR_HARPOON(p_port+hp_clkctrl_0,green_flag);
 
@@ -11775,11 +7899,7 @@ void Wait(ULONG p_port, UCHAR p_delay)
  *
  *---------------------------------------------------------------------*/
 
-#if defined(DOS)
-void utilEEWriteOnOff(USHORT p_port,UCHAR p_mode)
-#else
-void utilEEWriteOnOff(ULONG p_port,UCHAR p_mode)
-#endif
+static void FPT_utilEEWriteOnOff(ULONG p_port,UCHAR p_mode)
 {
    UCHAR ee_value;
 
@@ -11787,12 +7907,12 @@ void utilEEWriteOnOff(ULONG p_port,UCHAR
 
    if (p_mode)
 
-	  utilEESendCmdAddr(p_port, EWEN, EWEN_ADDR);
+	  FPT_utilEESendCmdAddr(p_port, EWEN, EWEN_ADDR);
 
    else
 
 
-	  utilEESendCmdAddr(p_port, EWDS, EWDS_ADDR);
+	  FPT_utilEESendCmdAddr(p_port, EWDS, EWDS_ADDR);
 
    WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
    WR_HARPOON(p_port+hp_ee_ctrl, ee_value);       /*Turn off Master Select */
@@ -11808,11 +7928,7 @@ void utilEEWriteOnOff(ULONG p_port,UCHAR
  *
  *---------------------------------------------------------------------*/
 
-#if defined(DOS)
-void utilEEWrite(USHORT p_port, USHORT ee_data, USHORT ee_addr)
-#else
-void utilEEWrite(ULONG p_port, USHORT ee_data, USHORT ee_addr)
-#endif
+static void FPT_utilEEWrite(ULONG p_port, USHORT ee_data, USHORT ee_addr)
 {
 
    UCHAR ee_value;
@@ -11823,7 +7939,7 @@ void utilEEWrite(ULONG p_port, USHORT ee
 
 
 
-   utilEESendCmdAddr(p_port, EE_WRITE, ee_addr);
+   FPT_utilEESendCmdAddr(p_port, EE_WRITE, ee_addr);
 
 
    ee_value |= (SEE_MS + SEE_CS);
@@ -11847,7 +7963,7 @@ void utilEEWrite(ULONG p_port, USHORT ee
    ee_value &= (EXT_ARB_ACK | SCSI_TERM_ENA_H);
    WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS));
 
-   Wait(p_port, TO_10ms);
+   FPT_Wait(p_port, TO_10ms);
 
    WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS | SEE_CS)); /* Set CS to EEPROM */
    WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS));       /* Turn off CS */
@@ -11863,19 +7979,15 @@ void utilEEWrite(ULONG p_port, USHORT ee
  *
  *---------------------------------------------------------------------*/
 
-#if defined(DOS)
-USHORT utilEERead(USHORT p_port, USHORT ee_addr)
-#else
-USHORT utilEERead(ULONG p_port, USHORT ee_addr)
-#endif
+static USHORT FPT_utilEERead(ULONG p_port, USHORT ee_addr)
 {
    USHORT i, ee_data1, ee_data2;
 
 	i = 0;
-	ee_data1 = utilEEReadOrg(p_port, ee_addr);
+	ee_data1 = FPT_utilEEReadOrg(p_port, ee_addr);
 	do
 	{
-		ee_data2 = utilEEReadOrg(p_port, ee_addr);
+		ee_data2 = FPT_utilEEReadOrg(p_port, ee_addr);
 
 		if(ee_data1 == ee_data2)
 			return(ee_data1);
@@ -11897,11 +8009,7 @@ USHORT utilEERead(ULONG p_port, USHORT e
  *
  *---------------------------------------------------------------------*/
 
-#if defined(DOS)
-USHORT utilEEReadOrg(USHORT p_port, USHORT ee_addr)
-#else
-USHORT utilEEReadOrg(ULONG p_port, USHORT ee_addr)
-#endif
+static USHORT FPT_utilEEReadOrg(ULONG p_port, USHORT ee_addr)
 {
 
    UCHAR ee_value;
@@ -11911,7 +8019,7 @@ USHORT utilEEReadOrg(ULONG p_port, USHOR
 		   (SEE_MS | SEE_CS));
 
 
-   utilEESendCmdAddr(p_port, EE_READ, ee_addr);
+   FPT_utilEESendCmdAddr(p_port, EE_READ, ee_addr);
 
 
    ee_value |= (SEE_MS + SEE_CS);
@@ -11949,11 +8057,7 @@ USHORT utilEEReadOrg(ULONG p_port, USHOR
  *
  *---------------------------------------------------------------------*/
 
-#if defined(DOS)
-void utilEESendCmdAddr(USHORT p_port, UCHAR ee_cmd, USHORT ee_addr)
-#else
-void utilEESendCmdAddr(ULONG p_port, UCHAR ee_cmd, USHORT ee_addr)
-#endif
+static void FPT_utilEESendCmdAddr(ULONG p_port, UCHAR ee_cmd, USHORT ee_addr)
 {
    UCHAR ee_value;
    UCHAR narrow_flg;
@@ -12016,7 +8120,7 @@ void utilEESendCmdAddr(ULONG p_port, UCH
 	  }
 }
 
-USHORT CalcCrc16(UCHAR buffer[])
+static USHORT FPT_CalcCrc16(UCHAR buffer[])
 {
    USHORT crc=0;
 	int i,j;
@@ -12036,7 +8140,7 @@ USHORT CalcCrc16(UCHAR buffer[])
 	return(crc);
 }
 
-UCHAR CalcLrc(UCHAR buffer[])
+static UCHAR FPT_CalcLrc(UCHAR buffer[])
 {
 	int i;
 	UCHAR lrc;
@@ -12109,33 +8213,6 @@ FlashPoint__HandleInterrupt(FlashPoint_C
 #define FlashPoint_HandleInterrupt	    FlashPoint__HandleInterrupt
 
 
-/*
-  FlashPoint_InquireTargetInfo returns the Synchronous Period, Synchronous
-  Offset, and Wide Transfers Active information for TargetID on CardHandle.
-*/
-
-void FlashPoint_InquireTargetInfo(FlashPoint_CardHandle_T CardHandle,
-				  int TargetID,
-				  unsigned char *SynchronousPeriod,
-				  unsigned char *SynchronousOffset,
-				  unsigned char *WideTransfersActive)
-{
-  SCCBMGR_TAR_INFO *TargetInfo =
-    &sccbMgrTbl[((SCCBCARD *)CardHandle)->cardIndex][TargetID];
-  if ((TargetInfo->TarSyncCtrl & SYNC_OFFSET) > 0)
-    {
-      *SynchronousPeriod = 5 * ((TargetInfo->TarSyncCtrl >> 5) + 1);
-      *SynchronousOffset = TargetInfo->TarSyncCtrl & SYNC_OFFSET;
-    }
-  else
-    {
-      *SynchronousPeriod = 0;
-      *SynchronousOffset = 0;
-    }
-  *WideTransfersActive = (TargetInfo->TarSyncCtrl & NARROW_SCSI ? 0 : 1);
-}
-
-
 #else  /* CONFIG_SCSI_OMIT_FLASHPOINT */
 
 
@@ -12151,9 +8228,6 @@ extern int FlashPoint_AbortCCB(FlashPoin
 extern boolean FlashPoint_InterruptPending(FlashPoint_CardHandle_T);
 extern int FlashPoint_HandleInterrupt(FlashPoint_CardHandle_T);
 extern void FlashPoint_ReleaseHostAdapter(FlashPoint_CardHandle_T);
-extern void FlashPoint_InquireTargetInfo(FlashPoint_CardHandle_T,
-					 int, unsigned char *,
-					 unsigned char *, unsigned char *);
 
 
 #endif /* CONFIG_SCSI_OMIT_FLASHPOINT */
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -137,6 +137,24 @@ config CHR_DEV_SG
 
 	  If unsure, say N.
 
+config CHR_DEV_SCH
+	tristate "SCSI media changer support"
+	depends on SCSI
+	---help---
+	  This is a driver for SCSI media changers.  Most common devices are
+	  tape libraries and MOD/CDROM jukeboxes.  *Real* jukeboxes, you
+	  don't need this for those tiny 6-slot cdrom changers.  Media
+	  changers are listed as "Type: Medium Changer" in /proc/scsi/scsi.
+	  If you have such hardware and want to use it with linux, say Y
+	  here.  Check <file:Documentation/scsi-changer.txt> for details.
+	
+	  If you want to compile this as a module ( = code which can be
+	  inserted in and removed from the running kernel whenever you want),
+	  say M here and read <file:Documentation/modules.txt> and
+	  <file:Documentation/scsi.txt>. The module will be called ch.o.
+	  If unsure, say N.
+	
+
 comment "Some SCSI devices (e.g. CD jukebox) support multiple LUNs"
 	depends on SCSI
 
@@ -406,7 +424,7 @@ config SCSI_IN2000
 source "drivers/scsi/megaraid/Kconfig.megaraid"
 
 config SCSI_SATA
-	bool "Serial ATA (SATA) support"
+	tristate "Serial ATA (SATA) support"
 	depends on SCSI
 	help
 	  This driver family supports Serial ATA host controllers
@@ -1192,28 +1210,6 @@ config SCSI_PAS16
 	  To compile this driver as a module, choose M here: the
 	  module will be called pas16.
 
-config SCSI_PCI2000
-	tristate "PCI2000 support"
-	depends on PCI && SCSI && BROKEN
-	help
-	  This is support for the PCI2000I EIDE interface card which acts as a
-	  SCSI host adapter.  Please read the SCSI-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called pci2000.
-
-config SCSI_PCI2220I
-	tristate "PCI2220i support"
-	depends on PCI && SCSI && BROKEN
-	help
-	  This is support for the PCI2220i EIDE interface card which acts as a
-	  SCSI host adapter.  Please read the SCSI-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called pci2220i.
-
 config SCSI_PSI240I
 	tristate "PSI240i support"
 	depends on ISA && SCSI
@@ -1700,7 +1696,7 @@ config TT_DMA_EMUL
 
 config MAC_SCSI
 	bool "Macintosh NCR5380 SCSI"
-	depends on MAC && SCSI
+	depends on MAC && SCSI=y
 	help
 	  This is the NCR 5380 SCSI controller included on most of the 68030
 	  based Macintoshes.  If you have one of these say Y and read the
@@ -1721,7 +1717,7 @@ config SCSI_MAC_ESP
 
 config MVME147_SCSI
 	bool "WD33C93 SCSI driver for MVME147"
-	depends on MVME147 && SCSI
+	depends on MVME147 && SCSI=y
 	help
 	  Support for the on-board SCSI controller on the Motorola MVME147
 	  single-board computer.
@@ -1762,7 +1758,7 @@ config SUN3_SCSI
 
 config SUN3X_ESP
 	bool "Sun3x ESP SCSI"
-	depends on SUN3X && SCSI
+	depends on SUN3X && SCSI=y
 	help
 	  The ESP was an on-board SCSI controller used on Sun 3/80
 	  machines.  Say Y here to compile in support for it.
diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile
--- a/drivers/scsi/Makefile
+++ b/drivers/scsi/Makefile
@@ -50,8 +50,6 @@ obj-$(CONFIG_MVME16x_SCSI)	+= mvme16x.o	
 obj-$(CONFIG_BVME6000_SCSI)	+= bvme6000.o	53c7xx.o
 obj-$(CONFIG_SCSI_SIM710)	+= 53c700.o	sim710.o
 obj-$(CONFIG_SCSI_ADVANSYS)	+= advansys.o
-obj-$(CONFIG_SCSI_PCI2000)	+= pci2000.o
-obj-$(CONFIG_SCSI_PCI2220I)	+= pci2220i.o
 obj-$(CONFIG_SCSI_PSI240I)	+= psi240i.o
 obj-$(CONFIG_SCSI_BUSLOGIC)	+= BusLogic.o
 obj-$(CONFIG_SCSI_DPT_I2O)	+= dpt_i2o.o
@@ -142,6 +140,7 @@ obj-$(CONFIG_CHR_DEV_OSST)	+= osst.o
 obj-$(CONFIG_BLK_DEV_SD)	+= sd_mod.o
 obj-$(CONFIG_BLK_DEV_SR)	+= sr_mod.o
 obj-$(CONFIG_CHR_DEV_SG)	+= sg.o
+obj-$(CONFIG_CHR_DEV_SCH)	+= ch.o
 
 scsi_mod-y			+= scsi.o hosts.o scsi_ioctl.o constants.o \
 				   scsicam.o scsi_error.o scsi_lib.o \
diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c
--- a/drivers/scsi/NCR5380.c
+++ b/drivers/scsi/NCR5380.c
@@ -2825,39 +2825,17 @@ static int NCR5380_abort(Scsi_Cmnd * cmd
  * Locks: host lock taken by caller
  */
 
-static int NCR5380_bus_reset(Scsi_Cmnd * cmd) {
-	NCR5380_local_declare();
-	NCR5380_setup(cmd->device->host);
-
-	NCR5380_print_status(cmd->device->host);
-	do_reset(cmd->device->host);
-	return SUCCESS;
-}
-
-/* 
- * Function : int NCR5380_device_reset (Scsi_Cmnd *cmd)
- * 
- * Purpose : reset a SCSI device
- *
- * Returns : FAILED
- *
- * Locks: io_request_lock held by caller
- */
+static int NCR5380_bus_reset(Scsi_Cmnd * cmd)
+{
+	struct Scsi_Host *instance = cmd->device->host;
 
-static int NCR5380_device_reset(Scsi_Cmnd * cmd) {
-	return FAILED;
-}
+	NCR5380_local_declare();
+	NCR5380_setup(instance);
+	NCR5380_print_status(instance);
 
-/* 
- * Function : int NCR5380_host_reset (Scsi_Cmnd *cmd)
- * 
- * Purpose : reset a SCSI device
- *
- * Returns : FAILED
- *
- * Locks: io_request_lock held by caller
- */
+	spin_lock_irq(instance->host_lock);
+	do_reset(instance);
+	spin_unlock_irq(instance->host_lock);
 
-static int NCR5380_host_reset(Scsi_Cmnd * cmd) {
-	return FAILED;
+	return SUCCESS;
 }
diff --git a/drivers/scsi/NCR5380.h b/drivers/scsi/NCR5380.h
--- a/drivers/scsi/NCR5380.h
+++ b/drivers/scsi/NCR5380.h
@@ -306,8 +306,6 @@ static void NCR5380_print(struct Scsi_Ho
 #endif
 static int NCR5380_abort(Scsi_Cmnd * cmd);
 static int NCR5380_bus_reset(Scsi_Cmnd * cmd);
-static int NCR5380_host_reset(Scsi_Cmnd * cmd);
-static int NCR5380_device_reset(Scsi_Cmnd * cmd);
 static int NCR5380_queue_command(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *));
 static int NCR5380_proc_info(struct Scsi_Host *instance, char *buffer, char **start,
 off_t offset, int length, int inout);
diff --git a/drivers/scsi/NCR53C9x.c b/drivers/scsi/NCR53C9x.c
--- a/drivers/scsi/NCR53C9x.c
+++ b/drivers/scsi/NCR53C9x.c
@@ -94,7 +94,7 @@ enum {
 };
 
 /* The master ring of all esp hosts we are managing in this driver. */
-struct NCR_ESP *espchain;
+static struct NCR_ESP *espchain;
 int nesps = 0, esps_in_use = 0, esps_running = 0;
 
 irqreturn_t esp_intr(int irq, void *dev_id, struct pt_regs *pregs);
@@ -1467,14 +1467,12 @@ int esp_reset(Scsi_Cmnd *SCptr)
 {
 	struct NCR_ESP *esp = (struct NCR_ESP *) SCptr->device->host->hostdata;
 
+	spin_lock_irq(esp->ehost->host_lock);
 	(void) esp_do_resetbus(esp, esp->eregs);
-
 	spin_unlock_irq(esp->ehost->host_lock);
 
 	wait_event(esp->reset_queue, (esp->resetting_bus == 0));
 
-	spin_lock_irq(esp->ehost->host_lock);
-
 	return SUCCESS;
 }
 
diff --git a/drivers/scsi/NCR53c406a.c b/drivers/scsi/NCR53c406a.c
--- a/drivers/scsi/NCR53c406a.c
+++ b/drivers/scsi/NCR53c406a.c
@@ -182,13 +182,13 @@ static int irq_probe(void);
 static void *bios_base;
 #endif
 
-#if PORT_BASE
+#ifdef PORT_BASE
 static int port_base = PORT_BASE;
 #else
 static int port_base;
 #endif
 
-#if IRQ_LEV
+#ifdef IRQ_LEV
 static int irq_level = IRQ_LEV;
 #else
 static int irq_level = -1;	/* 0 is 'no irq', so use -1 for 'uninitialized' */
@@ -722,15 +722,12 @@ static int NCR53c406a_queue(Scsi_Cmnd * 
 	return 0;
 }
 
-static int NCR53c406a_abort(Scsi_Cmnd * SCpnt)
-{
-	DEB(printk("NCR53c406a_abort called\n"));
-	return FAILED;		/* Don't know how to abort */
-}
-
 static int NCR53c406a_host_reset(Scsi_Cmnd * SCpnt)
 {
 	DEB(printk("NCR53c406a_reset called\n"));
+
+	spin_lock_irq(SCpnt->device->host->host_lock);
+
 	outb(C4_IMG, CONFIG4);	/* Select reg set 0 */
 	outb(CHIP_RESET, CMD_REG);
 	outb(SCSI_NOP, CMD_REG);	/* required after reset */
@@ -738,17 +735,10 @@ static int NCR53c406a_host_reset(Scsi_Cm
 	chip_init();
 
 	rtrc(2);
-	return SUCCESS;
-}
 
-static int NCR53c406a_device_reset(Scsi_Cmnd * SCpnt)
-{
-	return FAILED;
-}
+	spin_unlock_irq(SCpnt->device->host->host_lock);
 
-static int NCR53c406a_bus_reset(Scsi_Cmnd * SCpnt)
-{
-	return FAILED;
+	return SUCCESS;
 }
 
 static int NCR53c406a_biosparm(struct scsi_device *disk,
@@ -1075,9 +1065,6 @@ static Scsi_Host_Template driver_templat
      .release            	= NCR53c406a_release,
      .info              	= NCR53c406a_info		/* info */,             
      .queuecommand      	= NCR53c406a_queue	/* queuecommand */,     
-     .eh_abort_handler  	= NCR53c406a_abort	/* abort */,            
-     .eh_bus_reset_handler      = NCR53c406a_bus_reset	/* reset */,            
-     .eh_device_reset_handler   = NCR53c406a_device_reset	/* reset */,            
      .eh_host_reset_handler     = NCR53c406a_host_reset	/* reset */,            
      .bios_param        	= NCR53c406a_biosparm	/* biosparm */,         
      .can_queue         	= 1			/* can_queue */,        
diff --git a/drivers/scsi/a2091.c b/drivers/scsi/a2091.c
--- a/drivers/scsi/a2091.c
+++ b/drivers/scsi/a2091.c
@@ -221,7 +221,14 @@ int __init a2091_detect(Scsi_Host_Templa
 static int a2091_bus_reset(Scsi_Cmnd *cmd)
 {
 	/* FIXME perform bus-specific reset */
+
+	/* FIXME 2: kill this function, and let midlayer fall back
+	   to the same action, calling wd33c93_host_reset() */
+
+	spin_lock_irq(cmd->device->host->host_lock);
 	wd33c93_host_reset(cmd);
+	spin_unlock_irq(cmd->device->host->host_lock);
+
 	return SUCCESS;
 }
 
diff --git a/drivers/scsi/a3000.c b/drivers/scsi/a3000.c
--- a/drivers/scsi/a3000.c
+++ b/drivers/scsi/a3000.c
@@ -208,7 +208,14 @@ fail_register:
 static int a3000_bus_reset(Scsi_Cmnd *cmd)
 {
 	/* FIXME perform bus-specific reset */
+	
+	/* FIXME 2: kill this entire function, which should
+	   cause mid-layer to call wd33c93_host_reset anyway? */
+
+	spin_lock_irq(cmd->device->host->host_lock);
 	wd33c93_host_reset(cmd);
+	spin_unlock_irq(cmd->device->host->host_lock);
+
 	return SUCCESS;
 }
 
diff --git a/drivers/scsi/aacraid/README b/drivers/scsi/aacraid/README
--- a/drivers/scsi/aacraid/README
+++ b/drivers/scsi/aacraid/README
@@ -13,6 +13,7 @@ Supported Cards/Chipsets
 	Adaptec 2020S
 	Adaptec 2025S
 	Adaptec 2120S
+	Adaptec 2130S
 	Adaptec 2200S
 	Adaptec 2230S
 	Adaptec 2240S
@@ -35,6 +36,13 @@ Supported Cards/Chipsets
 	HP NetRAID-4M
 	Legend S220
 	Legend S230
+	IBM ServeRAID 8i
+	ICP 9014R0
+	ICP 9024R0
+	ICP 9047MA
+	ICP 9087MA
+	ICP 9085LI
+	ICP 5085AU
 
 People
 -------------------------
diff --git a/drivers/scsi/aacraid/TODO b/drivers/scsi/aacraid/TODO
--- a/drivers/scsi/aacraid/TODO
+++ b/drivers/scsi/aacraid/TODO
@@ -1,6 +1,4 @@
 o	Testing
 o	More testing
-o	Feature request: display the firmware/bios/etc revisions in the
-	/proc info
 o	Drop irq_mask, basically unused
 o	I/O size increase
diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c
--- a/drivers/scsi/aacraid/aachba.c
+++ b/drivers/scsi/aacraid/aachba.c
@@ -53,10 +53,6 @@
 #define	INQD_PDT_DMASK	0x1F	/* Peripheral Device Type Mask */
 #define	INQD_PDT_QMASK	0xE0	/* Peripheral Device Qualifer Mask */
 
-#define MAX_FIB_DATA (sizeof(struct hw_fib) - sizeof(FIB_HEADER))
-
-#define MAX_DRIVER_SG_SEGMENT_COUNT 17
-
 /*
  *	Sense codes
  */
@@ -158,6 +154,13 @@ MODULE_PARM_DESC(dacmode, "Control wheth
 module_param(commit, int, 0);
 MODULE_PARM_DESC(commit, "Control whether a COMMIT_CONFIG is issued to the adapter for foreign arrays.\nThis is typically needed in systems that do not have a BIOS. 0=off, 1=on");
 
+int numacb = -1;
+module_param(numacb, int, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(numacb, "Request a limit to the number of adapter control blocks (FIB) allocated. Valid\nvalues are 512 and down. Default is to use suggestion from Firmware.");
+
+int acbsize = -1;
+module_param(acbsize, int, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(acbsize, "Request a specific adapter control block (FIB) size. Valid values are 512,\n2048, 4096 and 8192. Default is to use suggestion from Firmware.");
 /**
  *	aac_get_config_status	-	check the adapter configuration
  *	@common: adapter to query
@@ -273,7 +276,6 @@ int aac_get_containers(struct aac_dev *d
 
 	if (maximum_num_containers < MAXIMUM_NUM_CONTAINERS)
 		maximum_num_containers = MAXIMUM_NUM_CONTAINERS;
-
 	fsa_dev_ptr = (struct fsa_dev_info *) kmalloc(
 	  sizeof(*fsa_dev_ptr) * maximum_num_containers, GFP_KERNEL);
 	if (!fsa_dev_ptr) {
@@ -462,7 +464,7 @@ static int probe_container(struct aac_de
 			    1, 1,
 			    NULL, NULL);
 	if (status < 0) {
-		printk(KERN_WARNING "aacraid: probe_containers query failed.\n");
+		printk(KERN_WARNING "aacraid: probe_container query failed.\n");
 		goto error;
 	}
 
@@ -524,6 +526,11 @@ static char *container_types[] = {
         "V-MIRRORS",          
         "PSEUDO R4",          
 	"RAID50",
+	"RAID5D",
+	"RAID5D0",
+	"RAID1E",
+	"RAID6",
+	"RAID60",
         "Unknown"
 };
 
@@ -562,10 +569,10 @@ static void setinqstr(int devtype, void 
 	inqstrcpy ("V1.0", str->prl);
 }
 
-void set_sense(u8 *sense_buf, u8 sense_key, u8 sense_code,
-		    u8 a_sense_code, u8 incorrect_length,
-		    u8 bit_pointer, u16 field_pointer,
-		    u32 residue)
+static void set_sense(u8 *sense_buf, u8 sense_key, u8 sense_code,
+		      u8 a_sense_code, u8 incorrect_length,
+		      u8 bit_pointer, u16 field_pointer,
+		      u32 residue)
 {
 	sense_buf[0] = 0xF0;	/* Sense data valid, err code 70h (current error) */
 	sense_buf[1] = 0;	/* Segment number, always zero */
@@ -605,35 +612,95 @@ void set_sense(u8 *sense_buf, u8 sense_k
 int aac_get_adapter_info(struct aac_dev* dev)
 {
 	struct fib* fibptr;
-	struct aac_adapter_info* info;
 	int rcode;
 	u32 tmp;
+	struct aac_adapter_info *info;
+	struct aac_bus_info *command;
+	struct aac_bus_info_response *bus_info;
+
 	if (!(fibptr = fib_alloc(dev)))
 		return -ENOMEM;
 
 	fib_init(fibptr);
-	info = (struct aac_adapter_info*) fib_data(fibptr);
-
-	memset(info,0,sizeof(struct aac_adapter_info));
+	info = (struct aac_adapter_info *) fib_data(fibptr);
+	memset(info,0,sizeof(*info));
 
 	rcode = fib_send(RequestAdapterInfo,
-			fibptr, 
-			sizeof(struct aac_adapter_info),
-			FsaNormal, 
-			1, 1, 
-			NULL, 
-			NULL);
+			 fibptr, 
+			 sizeof(*info),
+			 FsaNormal, 
+			 1, 1, 
+			 NULL, 
+			 NULL);
+
+	if (rcode < 0) {
+		fib_complete(fibptr);
+		fib_free(fibptr);
+		return rcode;
+	}
+	memcpy(&dev->adapter_info, info, sizeof(*info));
+
+	if (dev->adapter_info.options & AAC_OPT_SUPPLEMENT_ADAPTER_INFO) {
+		struct aac_supplement_adapter_info * info;
+
+		fib_init(fibptr);
+
+		info = (struct aac_supplement_adapter_info *) fib_data(fibptr);
+
+		memset(info,0,sizeof(*info));
+
+		rcode = fib_send(RequestSupplementAdapterInfo,
+				 fibptr,
+				 sizeof(*info),
+				 FsaNormal,
+				 1, 1,
+				 NULL,
+				 NULL);
+
+		if (rcode >= 0)
+			memcpy(&dev->supplement_adapter_info, info, sizeof(*info));
+	}
+
+
+	/* 
+	 * GetBusInfo 
+	 */
+
+	fib_init(fibptr);
+
+	bus_info = (struct aac_bus_info_response *) fib_data(fibptr);
+
+	memset(bus_info, 0, sizeof(*bus_info));
 
-	memcpy(&dev->adapter_info, info, sizeof(struct aac_adapter_info));
+	command = (struct aac_bus_info *)bus_info;
+
+	command->Command = cpu_to_le32(VM_Ioctl);
+	command->ObjType = cpu_to_le32(FT_DRIVE);
+	command->MethodId = cpu_to_le32(1);
+	command->CtlCmd = cpu_to_le32(GetBusInfo);
+
+	rcode = fib_send(ContainerCommand,
+			 fibptr,
+			 sizeof (*bus_info),
+			 FsaNormal,
+			 1, 1,
+			 NULL, NULL);
+
+	if (rcode >= 0 && le32_to_cpu(bus_info->Status) == ST_OK) {
+		dev->maximum_num_physicals = le32_to_cpu(bus_info->TargetsPerBus);
+		dev->maximum_num_channels = le32_to_cpu(bus_info->BusCount);
+	}
 
 	tmp = le32_to_cpu(dev->adapter_info.kernelrev);
-	printk(KERN_INFO "%s%d: kernel %d.%d-%d[%d]\n", 
+	printk(KERN_INFO "%s%d: kernel %d.%d-%d[%d] %.*s\n", 
 			dev->name, 
 			dev->id,
 			tmp>>24,
 			(tmp>>16)&0xff,
 			tmp&0xff,
-			le32_to_cpu(dev->adapter_info.kernelbuild));
+			le32_to_cpu(dev->adapter_info.kernelbuild),
+			(int)sizeof(dev->supplement_adapter_info.BuildDate),
+			dev->supplement_adapter_info.BuildDate);
 	tmp = le32_to_cpu(dev->adapter_info.monitorrev);
 	printk(KERN_INFO "%s%d: monitor %d.%d-%d[%d]\n", 
 			dev->name, dev->id,
@@ -707,6 +774,38 @@ int aac_get_adapter_info(struct aac_dev*
 			rcode = -ENOMEM;
 		}
 	}
+	/* 
+	 * 57 scatter gather elements 
+	 */
+	dev->scsi_host_ptr->sg_tablesize = (dev->max_fib_size -
+		sizeof(struct aac_fibhdr) -
+		sizeof(struct aac_write) + sizeof(struct sgmap)) /
+			sizeof(struct sgmap);
+	if (dev->dac_support) {
+		/* 
+		 * 38 scatter gather elements 
+		 */
+		dev->scsi_host_ptr->sg_tablesize =
+			(dev->max_fib_size -
+			sizeof(struct aac_fibhdr) -
+			sizeof(struct aac_write64) +
+			sizeof(struct sgmap64)) /
+				sizeof(struct sgmap64);
+	}
+	dev->scsi_host_ptr->max_sectors = AAC_MAX_32BIT_SGBCOUNT;
+	if(!(dev->adapter_info.options & AAC_OPT_NEW_COMM)) {
+		/*
+		 * Worst case size that could cause sg overflow when
+		 * we break up SG elements that are larger than 64KB.
+		 * Would be nice if we could tell the SCSI layer what
+		 * the maximum SG element size can be. Worst case is
+		 * (sg_tablesize-1) 4KB elements with one 64KB
+		 * element.
+		 *	32bit -> 468 or 238KB	64bit -> 424 or 212KB
+		 */
+		dev->scsi_host_ptr->max_sectors =
+		  (dev->scsi_host_ptr->sg_tablesize * 8) + 112;
+	}
 
 	fib_complete(fibptr);
 	fib_free(fibptr);
@@ -747,8 +846,10 @@ static void read_callback(void *context,
 	if (le32_to_cpu(readreply->status) == ST_OK)
 		scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
 	else {
-		printk(KERN_WARNING "read_callback: read failed, status = %d\n",
-				le32_to_cpu(readreply->status));
+#ifdef AAC_DETAILED_STATUS_INFO
+		printk(KERN_WARNING "read_callback: io failed, status = %d\n",
+		  le32_to_cpu(readreply->status));
+#endif
 		scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_CHECK_CONDITION;
 		set_sense((u8 *) &dev->fsa_dev[cid].sense_data,
 				    HARDWARE_ERROR,
@@ -813,7 +914,7 @@ static void write_callback(void *context
 	aac_io_done(scsicmd);
 }
 
-int aac_read(struct scsi_cmnd * scsicmd, int cid)
+static int aac_read(struct scsi_cmnd * scsicmd, int cid)
 {
 	u32 lba;
 	u32 count;
@@ -842,7 +943,8 @@ int aac_read(struct scsi_cmnd * scsicmd,
 		lba = (scsicmd->cmnd[2] << 24) | (scsicmd->cmnd[3] << 16) | (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5];
 		count = (scsicmd->cmnd[7] << 8) | scsicmd->cmnd[8];
 	}
-	dprintk((KERN_DEBUG "aac_read[cpu %d]: lba = %u, t = %ld.\n", smp_processor_id(), lba, jiffies));
+	dprintk((KERN_DEBUG "aac_read[cpu %d]: lba = %u, t = %ld.\n",
+	  smp_processor_id(), (unsigned long long)lba, jiffies));
 	/*
 	 *	Alocate and initialize a Fib
 	 */
@@ -852,7 +954,7 @@ int aac_read(struct scsi_cmnd * scsicmd,
 
 	fib_init(cmd_fibcontext);
 
-	if(dev->dac_support == 1) {
+	if (dev->dac_support == 1) {
 		struct aac_read64 *readcmd;
 		readcmd = (struct aac_read64 *) fib_data(cmd_fibcontext);
 		readcmd->command = cpu_to_le32(VM_CtHostRead64);
@@ -886,14 +988,11 @@ int aac_read(struct scsi_cmnd * scsicmd,
 		readcmd->block = cpu_to_le32(lba);
 		readcmd->count = cpu_to_le32(count * 512);
 
-		if (count * 512 > (64 * 1024))
-			BUG();
-
 		aac_build_sg(scsicmd, &readcmd->sg);
 		fibsize = sizeof(struct aac_read) + 
 			((le32_to_cpu(readcmd->sg.count) - 1) * 
 			 sizeof (struct sgentry));
-		BUG_ON (fibsize > (sizeof(struct hw_fib) - 
+		BUG_ON (fibsize > (dev->max_fib_size -
 					sizeof(struct aac_fibhdr)));
 		/*
 		 *	Now send the Fib to the adapter
@@ -976,7 +1075,7 @@ static int aac_write(struct scsi_cmnd * 
 		fibsize = sizeof(struct aac_write64) + 
 			((le32_to_cpu(writecmd->sg.count) - 1) * 
 			 sizeof (struct sgentry64));
-		BUG_ON (fibsize > (sizeof(struct hw_fib) - 
+		BUG_ON (fibsize > (dev->max_fib_size -
 					sizeof(struct aac_fibhdr)));
 		/*
 		 *	Now send the Fib to the adapter
@@ -998,15 +1097,11 @@ static int aac_write(struct scsi_cmnd * 
 		writecmd->sg.count = cpu_to_le32(1);
 		/* ->stable is not used - it did mean which type of write */
 
-		if (count * 512 > (64 * 1024)) {
-			BUG();
-		}
-
 		aac_build_sg(scsicmd, &writecmd->sg);
 		fibsize = sizeof(struct aac_write) + 
 			((le32_to_cpu(writecmd->sg.count) - 1) * 
 			 sizeof (struct sgentry));
-		BUG_ON (fibsize > (sizeof(struct hw_fib) - 
+		BUG_ON (fibsize > (dev->max_fib_size -
 					sizeof(struct aac_fibhdr)));
 		/*
 		 *	Now send the Fib to the adapter
@@ -1025,7 +1120,6 @@ static int aac_write(struct scsi_cmnd * 
 	 */
 	if (status == -EINPROGRESS)
 	{
-		dprintk("write queued.\n");
 		return 0;
 	}
 
@@ -1111,7 +1205,7 @@ static int aac_synchronize(struct scsi_c
 		return SCSI_MLQUEUE_DEVICE_BUSY;
 
 	/*
-	 *	Alocate and initialize a Fib
+	 *	Allocate and initialize a Fib
 	 */
 	if (!(cmd_fibcontext = 
 	    fib_alloc((struct aac_dev *)scsicmd->device->host->hostdata))) 
@@ -1403,7 +1497,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsi
 			/*
 			 *	Unhandled commands
 			 */
-			printk(KERN_WARNING "Unhandled SCSI Command: 0x%x.\n", scsicmd->cmnd[0]);
+			dprintk((KERN_WARNING "Unhandled SCSI Command: 0x%x.\n", scsicmd->cmnd[0]));
 			scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_CHECK_CONDITION;
 			set_sense((u8 *) &dev->fsa_dev[cid].sense_data,
 				ILLEGAL_REQUEST, SENCODE_INVALID_COMMAND,
@@ -1760,7 +1854,9 @@ static int aac_send_srb_fib(struct scsi_
 	u32 flag;
 	u32 timeout;
 
-	if( scsicmd->device->id > 15 || scsicmd->device->lun > 7) {
+	dev = (struct aac_dev *)scsicmd->device->host->hostdata;
+	if (scsicmd->device->id >= dev->maximum_num_physicals || 
+			scsicmd->device->lun > 7) {
 		scsicmd->result = DID_NO_CONNECT << 16;
 		scsicmd->scsi_done(scsicmd);
 		return 0;
@@ -1818,7 +1914,7 @@ static int aac_send_srb_fib(struct scsi_
 		fibsize = sizeof (struct aac_srb) - sizeof (struct sgentry) +
 			((le32_to_cpu(srbcmd->sg.count) & 0xff) * 
 			 sizeof (struct sgentry64));
-		BUG_ON (fibsize > (sizeof(struct hw_fib) - 
+		BUG_ON (fibsize > (dev->max_fib_size -
 					sizeof(struct aac_fibhdr)));
 
 		/*
@@ -1840,7 +1936,7 @@ static int aac_send_srb_fib(struct scsi_
 		fibsize = sizeof (struct aac_srb) + 
 			(((le32_to_cpu(srbcmd->sg.count) & 0xff) - 1) * 
 			 sizeof (struct sgentry));
-		BUG_ON (fibsize > (sizeof(struct hw_fib) - 
+		BUG_ON (fibsize > (dev->max_fib_size -
 					sizeof(struct aac_fibhdr)));
 
 		/*
@@ -1893,7 +1989,9 @@ static unsigned long aac_build_sg(struct
 		}
 		/* hba wants the size to be exact */
 		if(byte_count > scsicmd->request_bufflen){
-			psg->sg[i-1].count -= (byte_count - scsicmd->request_bufflen);
+			u32 temp = le32_to_cpu(psg->sg[i-1].count) - 
+				(byte_count - scsicmd->request_bufflen);
+			psg->sg[i-1].count = cpu_to_le32(temp);
 			byte_count = scsicmd->request_bufflen;
 		}
 		/* Check for command underflow */
@@ -1922,7 +2020,7 @@ static unsigned long aac_build_sg64(stru
 {
 	struct aac_dev *dev;
 	unsigned long byte_count = 0;
-	u64 le_addr;
+	u64 addr;
 
 	dev = (struct aac_dev *)scsicmd->device->host->hostdata;
 	// Get rid of old data
@@ -1943,16 +2041,18 @@ static unsigned long aac_build_sg64(stru
 		byte_count = 0;
 
 		for (i = 0; i < sg_count; i++) {
-			le_addr = cpu_to_le64(sg_dma_address(sg));
-			psg->sg[i].addr[1] = (u32)(le_addr>>32);
-			psg->sg[i].addr[0] = (u32)(le_addr & 0xffffffff);
+			addr = sg_dma_address(sg);
+			psg->sg[i].addr[0] = cpu_to_le32(addr & 0xffffffff);
+			psg->sg[i].addr[1] = cpu_to_le32(addr>>32);
 			psg->sg[i].count = cpu_to_le32(sg_dma_len(sg));
 			byte_count += sg_dma_len(sg);
 			sg++;
 		}
 		/* hba wants the size to be exact */
 		if(byte_count > scsicmd->request_bufflen){
-			psg->sg[i-1].count -= (byte_count - scsicmd->request_bufflen);
+			u32 temp = le32_to_cpu(psg->sg[i-1].count) - 
+				(byte_count - scsicmd->request_bufflen);
+			psg->sg[i-1].count = cpu_to_le32(temp);
 			byte_count = scsicmd->request_bufflen;
 		}
 		/* Check for command underflow */
@@ -1962,15 +2062,14 @@ static unsigned long aac_build_sg64(stru
 		}
 	}
 	else if(scsicmd->request_bufflen) {
-		dma_addr_t addr; 
+		u64 addr; 
 		addr = pci_map_single(dev->pdev,
 				scsicmd->request_buffer,
 				scsicmd->request_bufflen,
 				scsicmd->sc_data_direction);
 		psg->count = cpu_to_le32(1);
-		le_addr = cpu_to_le64(addr);
-		psg->sg[0].addr[1] = (u32)(le_addr>>32);
-		psg->sg[0].addr[0] = (u32)(le_addr & 0xffffffff);
+		psg->sg[0].addr[0] = cpu_to_le32(addr & 0xffffffff);
+		psg->sg[0].addr[1] = cpu_to_le32(addr >> 32);
 		psg->sg[0].count = cpu_to_le32(scsicmd->request_bufflen);  
 		scsicmd->SCp.dma_handle = addr;
 		byte_count = scsicmd->request_bufflen;
diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
--- a/drivers/scsi/aacraid/aacraid.h
+++ b/drivers/scsi/aacraid/aacraid.h
@@ -8,12 +8,14 @@
 
 #define MAXIMUM_NUM_CONTAINERS	32
 
-#define AAC_NUM_FIB		(256 + 64)
-#define AAC_NUM_IO_FIB		100
+#define AAC_NUM_MGT_FIB         8
+#define AAC_NUM_IO_FIB		(512 - AAC_NUM_MGT_FIB)
+#define AAC_NUM_FIB		(AAC_NUM_IO_FIB + AAC_NUM_MGT_FIB)
 
 #define AAC_MAX_LUN		(8)
 
 #define AAC_MAX_HOSTPHYSMEMPAGES (0xfffff)
+#define AAC_MAX_32BIT_SGBCOUNT	((unsigned short)512)
 
 /*
  * These macros convert from physical channels to virtual channels
@@ -89,11 +91,21 @@ struct diskparm
  *	on 64 bit systems not all cards support the 64 bit version
  */
 struct sgentry {
+	__le32	addr;	/* 32-bit address. */
+	__le32	count;	/* Length. */
+};
+
+struct user_sgentry {
 	u32	addr;	/* 32-bit address. */
 	u32	count;	/* Length. */
 };
 
 struct sgentry64 {
+	__le32	addr[2];	/* 64-bit addr. 2 pieces for data alignment */
+	__le32	count;	/* Length. */
+};
+
+struct user_sgentry64 {
 	u32	addr[2];	/* 64-bit addr. 2 pieces for data alignment */
 	u32	count;	/* Length. */
 };
@@ -106,15 +118,25 @@ struct sgentry64 {
  */
 
 struct sgmap {
-	u32		count;
+	__le32		count;
 	struct sgentry	sg[1]; 
 };
 
-struct sgmap64 {
+struct user_sgmap {
 	u32		count;
+	struct user_sgentry	sg[1]; 
+};
+
+struct sgmap64 {
+	__le32		count;
 	struct sgentry64 sg[1];
 };
 
+struct user_sgmap64 {
+	u32		count;
+	struct user_sgentry64 sg[1];
+};
+
 struct creation_info
 {
 	u8 		buildnum;		/* e.g., 588 */
@@ -123,14 +145,14 @@ struct creation_info
 						 * 	 2 = API
 						 */
 	u8	 	year;		 	/* e.g., 1997 = 97 */
-	u32		date;			/*
+	__le32		date;			/*
 						 * unsigned 	Month		:4;	// 1 - 12
 						 * unsigned 	Day		:6;	// 1 - 32
 						 * unsigned 	Hour		:6;	// 0 - 23
 						 * unsigned 	Minute		:6;	// 0 - 60
 						 * unsigned 	Second		:6;	// 0 - 60
 						 */
-	u32		serial[2];			/* e.g., 0x1DEADB0BFAFAF001 */
+	__le32		serial[2];			/* e.g., 0x1DEADB0BFAFAF001 */
 };
 
 
@@ -175,8 +197,8 @@ struct creation_info
  */
 
 struct aac_entry {
-	u32 size;          /* Size in bytes of Fib which this QE points to */
-	u32 addr; /* Receiver address of the FIB */
+	__le32 size; /* Size in bytes of Fib which this QE points to */
+	__le32 addr; /* Receiver address of the FIB */
 };
 
 /*
@@ -185,9 +207,10 @@ struct aac_entry {
  */
  
 struct aac_qhdr {
-	u64 header_addr;		/* Address to hand the adapter to access to this queue head */
-	u32 *producer;			/* The producer index for this queue (host address) */
-	u32 *consumer;			/* The consumer index for this queue (host address) */
+	__le64 header_addr;/* Address to hand the adapter to access 
+			      to this queue head */
+	__le32 *producer; /* The producer index for this queue (host address) */
+	__le32 *consumer; /* The consumer index for this queue (host address) */
 };
 
 /*
@@ -261,29 +284,30 @@ enum aac_queue_types {
  */
 
 struct aac_fibhdr {
-	u32 XferState;			// Current transfer state for this CCB
-	u16 Command;			// Routing information for the destination
-	u8 StructType;			// Type FIB
-	u8 Flags;			// Flags for FIB
-	u16 Size;			// Size of this FIB in bytes
-	u16 SenderSize;			// Size of the FIB in the sender (for response sizing)
-	u32 SenderFibAddress;		// Host defined data in the FIB
-	u32 ReceiverFibAddress;		// Logical address of this FIB for the adapter
-	u32 SenderData;			// Place holder for the sender to store data
+	__le32 XferState;	/* Current transfer state for this CCB */
+	__le16 Command;		/* Routing information for the destination */
+	u8 StructType;		/* Type FIB */
+	u8 Flags;		/* Flags for FIB */
+	__le16 Size;		/* Size of this FIB in bytes */
+	__le16 SenderSize;	/* Size of the FIB in the sender 
+				   (for response sizing) */
+	__le32 SenderFibAddress;  /* Host defined data in the FIB */
+	__le32 ReceiverFibAddress;/* Logical address of this FIB for 
+				     the adapter */
+	u32 SenderData;		/* Place holder for the sender to store data */
 	union {
 		struct {
-		    u32 _ReceiverTimeStart; 	// Timestamp for receipt of fib
-		    u32 _ReceiverTimeDone;	// Timestamp for completion of fib
+		    __le32 _ReceiverTimeStart; 	/* Timestamp for 
+						   receipt of fib */
+		    __le32 _ReceiverTimeDone;	/* Timestamp for 
+						   completion of fib */
 		} _s;
 	} _u;
 };
 
-#define FIB_DATA_SIZE_IN_BYTES (512 - sizeof(struct aac_fibhdr))
-
-
 struct hw_fib {
 	struct aac_fibhdr header;
-	u8 data[FIB_DATA_SIZE_IN_BYTES];		// Command specific data
+	u8 data[512-sizeof(struct aac_fibhdr)];	// Command specific data
 };
 
 /*
@@ -345,11 +369,12 @@ struct hw_fib {
 #define		RequestAdapterInfo		703
 #define		IsAdapterPaused			704
 #define		SendHostTime			705
-#define		LastMiscCommand			706
+#define		RequestSupplementAdapterInfo	706
+#define		LastMiscCommand			707
 
-//
-// Commands that will target the failover level on the FSA adapter
-//
+/*
+ * Commands that will target the failover level on the FSA adapter
+ */
 
 enum fib_xfer_state {
 	HostOwned 			= (1<<0),
@@ -382,22 +407,32 @@ enum fib_xfer_state {
  */
 
 #define ADAPTER_INIT_STRUCT_REVISION		3
+#define ADAPTER_INIT_STRUCT_REVISION_4		4 // rocket science
 
 struct aac_init
 {
-	u32	InitStructRevision;
-	u32	MiniPortRevision;
-	u32	fsrev;
-	u32	CommHeaderAddress;
-	u32	FastIoCommAreaAddress;
-	u32	AdapterFibsPhysicalAddress;
-	u32	AdapterFibsVirtualAddress;
-	u32	AdapterFibsSize;
-	u32	AdapterFibAlign;
-	u32	printfbuf;
-	u32	printfbufsiz;
-	u32	HostPhysMemPages;		// number of 4k pages of host physical memory
-	u32	HostElapsedSeconds;		// number of seconds since 1970.
+	__le32	InitStructRevision;
+	__le32	MiniPortRevision;
+	__le32	fsrev;
+	__le32	CommHeaderAddress;
+	__le32	FastIoCommAreaAddress;
+	__le32	AdapterFibsPhysicalAddress;
+	__le32	AdapterFibsVirtualAddress;
+	__le32	AdapterFibsSize;
+	__le32	AdapterFibAlign;
+	__le32	printfbuf;
+	__le32	printfbufsiz;
+	__le32	HostPhysMemPages;   /* number of 4k pages of host 
+				       physical memory */
+	__le32	HostElapsedSeconds; /* number of seconds since 1970. */
+	/*
+	 * ADAPTER_INIT_STRUCT_REVISION_4 begins here
+	 */
+	__le32	InitFlags;	/* flags for supported features */
+#define INITFLAGS_NEW_COMM_SUPPORTED	0x00000001
+	__le32	MaxIoCommands;	/* max outstanding commands */
+	__le32	MaxIoSize;	/* largest I/O command */
+	__le32	MaxFibSize;	/* largest FIB to adapter */
 };
 
 enum aac_log_level {
@@ -421,7 +456,7 @@ struct adapter_ops
 {
 	void (*adapter_interrupt)(struct aac_dev *dev);
 	void (*adapter_notify)(struct aac_dev *dev, u32 event);
-	int  (*adapter_sync_cmd)(struct aac_dev *dev, u32 command, u32 p1, u32 *status);
+	int  (*adapter_sync_cmd)(struct aac_dev *dev, u32 command, u32 p1, u32 p2, u32 p3, u32 p4, u32 p5, u32 p6, u32 *status, u32 *r1, u32 *r2, u32 *r3, u32 *r4);
 	int  (*adapter_check_health)(struct aac_dev *dev);
 };
 
@@ -541,6 +576,7 @@ struct sa_drawbridge_CSR {
 #define Mailbox3	SaDbCSR.MAILBOX3
 #define Mailbox4	SaDbCSR.MAILBOX4
 #define Mailbox5	SaDbCSR.MAILBOX5
+#define Mailbox6	SaDbCSR.MAILBOX6
 #define Mailbox7	SaDbCSR.MAILBOX7
 	
 #define DoorbellReg_p SaDbCSR.PRISETIRQ
@@ -763,27 +799,68 @@ struct fib {
  
 struct aac_adapter_info
 {
-	u32	platform;
-	u32	cpu;
-	u32	subcpu;
-	u32	clock;
-	u32	execmem;
-	u32	buffermem;
-	u32	totalmem;
-	u32	kernelrev;
-	u32	kernelbuild;
-	u32	monitorrev;
-	u32	monitorbuild;
-	u32	hwrev;
-	u32	hwbuild;
-	u32	biosrev;
-	u32	biosbuild;
-	u32	cluster;
-	u32	clusterchannelmask; 
-	u32	serial[2];
-	u32	battery;
-	u32	options;
-	u32	OEM;
+	__le32	platform;
+	__le32	cpu;
+	__le32	subcpu;
+	__le32	clock;
+	__le32	execmem;
+	__le32	buffermem;
+	__le32	totalmem;
+	__le32	kernelrev;
+	__le32	kernelbuild;
+	__le32	monitorrev;
+	__le32	monitorbuild;
+	__le32	hwrev;
+	__le32	hwbuild;
+	__le32	biosrev;
+	__le32	biosbuild;
+	__le32	cluster;
+	__le32	clusterchannelmask; 
+	__le32	serial[2];
+	__le32	battery;
+	__le32	options;
+	__le32	OEM;
+};
+
+struct aac_supplement_adapter_info
+{
+	u8	AdapterTypeText[17+1];
+	u8	Pad[2];
+	__le32	FlashMemoryByteSize;
+	__le32	FlashImageId;
+	__le32	MaxNumberPorts;
+	__le32	Version;
+	__le32	FeatureBits;
+	u8	SlotNumber;
+	u8	ReservedPad0[0];
+	u8	BuildDate[12];
+	__le32	CurrentNumberPorts;
+	__le32	ReservedGrowth[24];
+};
+#define AAC_FEATURE_FALCON	0x00000010
+#define AAC_SIS_VERSION_V3	3
+#define AAC_SIS_SLOT_UNKNOWN	0xFF
+
+#define GetBusInfo 0x00000009
+struct aac_bus_info {
+	__le32	Command;	/* VM_Ioctl */
+	__le32	ObjType;	/* FT_DRIVE */
+	__le32	MethodId;	/* 1 = SCSI Layer */
+	__le32	ObjectId;	/* Handle */
+	__le32	CtlCmd;		/* GetBusInfo */
+};
+
+struct aac_bus_info_response {
+	__le32	Status;		/* ST_OK */
+	__le32	ObjType;
+	__le32	MethodId;	/* unused */
+	__le32	ObjectId;	/* unused */
+	__le32	CtlCmd;		/* unused */
+	__le32	ProbeComplete;
+	__le32	BusCount;
+	__le32	TargetsPerBus;
+	u8	InitiatorBusId[10];
+	u8	BusValid[10];
 };
 
 /*
@@ -831,6 +908,12 @@ struct aac_dev
 
 	u16			irq_mask;
 	/*
+	 *	negotiated FIB settings
+	 */
+	unsigned		max_fib_size;
+	unsigned		sg_tablesize;
+
+	/*
 	 *	Map for 128 fib objects (64k)
 	 */	
 	dma_addr_t		hw_fib_pa;
@@ -869,6 +952,8 @@ struct aac_dev
 
 	struct Scsi_Host	*scsi_host_ptr;
 	int			maximum_num_containers;
+	int			maximum_num_physicals;
+	int			maximum_num_channels;
 	struct fsa_dev_info	*fsa_dev;
 	pid_t			thread_pid;
 	int			cardtype;
@@ -889,12 +974,14 @@ struct aac_dev
 	u32			aif_thread;
 	struct completion	aif_completion;
 	struct aac_adapter_info adapter_info;
+	struct aac_supplement_adapter_info supplement_adapter_info;
 	/* These are in adapter info but they are in the io flow so
 	 * lets break them out so we don't have to do an AND to check them
 	 */
 	u8			nondasd_support; 
 	u8			dac_support;
 	u8			raid_scsi_mode;
+	u8			printf_enabled;
 };
 
 #define aac_adapter_interrupt(dev) \
@@ -903,6 +990,8 @@ struct aac_dev
 #define aac_adapter_notify(dev, event) \
 	(dev)->a_ops.adapter_notify(dev, event)
 
+#define aac_adapter_sync_cmd(dev, command, p1, p2, p3, p4, p5, p6, status, r1, r2, r3, r4) \
+	(dev)->a_ops.adapter_sync_cmd(dev, command, p1, p2, p3, p4, p5, p6, status, r1, r2, r3, r4)
 
 #define aac_adapter_check_health(dev) \
 	(dev)->a_ops.adapter_check_health(dev)
@@ -1016,83 +1105,102 @@ struct aac_dev
 
 struct aac_read
 {
-	u32	 	command;
-	u32 		cid;
-	u32 		block;
-	u32 		count;
+	__le32	 	command;
+	__le32 		cid;
+	__le32 		block;
+	__le32 		count;
 	struct sgmap	sg;	// Must be last in struct because it is variable
 };
 
 struct aac_read64
 {
-	u32	 	command;
-	u16 		cid;
-	u16 		sector_count;
-	u32 		block;
-	u16		pad;
-	u16		flags;
+	__le32	 	command;
+	__le16 		cid;
+	__le16 		sector_count;
+	__le32 		block;
+	__le16		pad;
+	__le16		flags;
 	struct sgmap64	sg;	// Must be last in struct because it is variable
 };
 
 struct aac_read_reply
 {
-	u32	 	status;
-	u32 		count;
+	__le32	 	status;
+	__le32 		count;
 };
 
 struct aac_write
 {
-	u32		command;
-	u32 		cid;
-	u32 		block;
-	u32 		count;
-	u32	 	stable;	// Not used
+	__le32		command;
+	__le32 		cid;
+	__le32 		block;
+	__le32 		count;
+	__le32	 	stable;	// Not used
 	struct sgmap	sg;	// Must be last in struct because it is variable
 };
 
 struct aac_write64
 {
-	u32	 	command;
-	u16 		cid;
-	u16 		sector_count;
-	u32 		block;
-	u16		pad;
-	u16		flags;
+	__le32	 	command;
+	__le16 		cid;
+	__le16 		sector_count;
+	__le32 		block;
+	__le16		pad;
+	__le16		flags;
 	struct sgmap64	sg;	// Must be last in struct because it is variable
 };
 struct aac_write_reply
 {
-	u32		status;
-	u32 		count;
-	u32		committed;
+	__le32		status;
+	__le32 		count;
+	__le32		committed;
 };
 
 #define CT_FLUSH_CACHE 129
 struct aac_synchronize {
-	u32		command;	/* VM_ContainerConfig */
-	u32		type;		/* CT_FLUSH_CACHE */
-	u32		cid;
-	u32		parm1;
-	u32		parm2;
-	u32		parm3;
-	u32		parm4;
-	u32		count;	/* sizeof(((struct aac_synchronize_reply *)NULL)->data) */
+	__le32		command;	/* VM_ContainerConfig */
+	__le32		type;		/* CT_FLUSH_CACHE */
+	__le32		cid;
+	__le32		parm1;
+	__le32		parm2;
+	__le32		parm3;
+	__le32		parm4;
+	__le32		count;	/* sizeof(((struct aac_synchronize_reply *)NULL)->data) */
 };
 
 struct aac_synchronize_reply {
-	u32		dummy0;
-	u32		dummy1;
-	u32		status;	/* CT_OK */
-	u32		parm1;
-	u32		parm2;
-	u32		parm3;
-	u32		parm4;
-	u32		parm5;
+	__le32		dummy0;
+	__le32		dummy1;
+	__le32		status;	/* CT_OK */
+	__le32		parm1;
+	__le32		parm2;
+	__le32		parm3;
+	__le32		parm4;
+	__le32		parm5;
 	u8		data[16];
 };
 
 struct aac_srb
 {
+	__le32		function;
+	__le32		channel;
+	__le32		id;
+	__le32		lun;
+	__le32		timeout;
+	__le32		flags;
+	__le32		count;		// Data xfer size
+	__le32		retry_limit;
+	__le32		cdb_size;
+	u8		cdb[16];
+	struct	sgmap	sg;
+};
+
+/*
+ * This and assocated data structs are used by the 
+ * ioctl caller and are in cpu order.
+ */
+struct user_aac_srb
+{
 	u32		function;
 	u32		channel;
 	u32		id;
@@ -1103,20 +1211,18 @@ struct aac_srb
 	u32		retry_limit;
 	u32		cdb_size;
 	u8		cdb[16];
-	struct	sgmap	sg;
+	struct	user_sgmap	sg;
 };
 
-
-
 #define		AAC_SENSE_BUFFERSIZE	 30
 
 struct aac_srb_reply
 {
-	u32		status;
-	u32		srb_status;
-	u32		scsi_status;
-	u32		data_xfer_length;
-	u32		sense_data_size;
+	__le32		status;
+	__le32		srb_status;
+	__le32		scsi_status;
+	__le32		data_xfer_length;
+	__le32		sense_data_size;
 	u8		sense_data[AAC_SENSE_BUFFERSIZE]; // Can this be SCSI_SENSE_BUFFERSIZE
 };
 /*
@@ -1223,14 +1329,14 @@ struct aac_srb_reply
  */
 
 struct aac_fsinfo {
-	u32  fsTotalSize;	/* Consumed by fs, incl. metadata */
-	u32  fsBlockSize;
-	u32  fsFragSize;
-	u32  fsMaxExtendSize;
-	u32  fsSpaceUnits;
-	u32  fsMaxNumFiles;
-	u32  fsNumFreeFiles;
-	u32  fsInodeDensity;
+	__le32  fsTotalSize;	/* Consumed by fs, incl. metadata */
+	__le32  fsBlockSize;
+	__le32  fsFragSize;
+	__le32  fsMaxExtendSize;
+	__le32  fsSpaceUnits;
+	__le32  fsMaxNumFiles;
+	__le32  fsNumFreeFiles;
+	__le32  fsInodeDensity;
 };	/* valid iff ObjType == FT_FILESYS && !(ContentState & FSCS_NOTCLEAN) */
 
 union aac_contentinfo {
@@ -1243,32 +1349,32 @@ union aac_contentinfo {
 
 #define CT_GET_CONFIG_STATUS 147
 struct aac_get_config_status {
-	u32		command;	/* VM_ContainerConfig */
-	u32		type;		/* CT_GET_CONFIG_STATUS */
-	u32		parm1;
-	u32		parm2;
-	u32		parm3;
-	u32		parm4;
-	u32		parm5;
-	u32		count;	/* sizeof(((struct aac_get_config_status_resp *)NULL)->data) */
+	__le32		command;	/* VM_ContainerConfig */
+	__le32		type;		/* CT_GET_CONFIG_STATUS */
+	__le32		parm1;
+	__le32		parm2;
+	__le32		parm3;
+	__le32		parm4;
+	__le32		parm5;
+	__le32		count;	/* sizeof(((struct aac_get_config_status_resp *)NULL)->data) */
 };
 
 #define CFACT_CONTINUE 0
 #define CFACT_PAUSE    1
 #define CFACT_ABORT    2
 struct aac_get_config_status_resp {
-	u32		response; /* ST_OK */
-	u32		dummy0;
-	u32		status;	/* CT_OK */
-	u32		parm1;
-	u32		parm2;
-	u32		parm3;
-	u32		parm4;
-	u32		parm5;
+	__le32		response; /* ST_OK */
+	__le32		dummy0;
+	__le32		status;	/* CT_OK */
+	__le32		parm1;
+	__le32		parm2;
+	__le32		parm3;
+	__le32		parm4;
+	__le32		parm5;
 	struct {
-		u32	action; /* CFACT_CONTINUE, CFACT_PAUSE or CFACT_ABORT */
-		u16	flags;
-		s16	count;
+		__le32	action; /* CFACT_CONTINUE, CFACT_PAUSE or CFACT_ABORT */
+		__le16	flags;
+		__le16	count;
 	}		data;
 };
 
@@ -1279,26 +1385,26 @@ struct aac_get_config_status_resp {
 #define CT_COMMIT_CONFIG 152
 
 struct aac_commit_config {
-	u32		command;	/* VM_ContainerConfig */
-	u32		type;		/* CT_COMMIT_CONFIG */
+	__le32		command;	/* VM_ContainerConfig */
+	__le32		type;		/* CT_COMMIT_CONFIG */
 };
 
 /*
- *	Query for Container Configuration Count
+ *	Query for Container Configuration Status
  */
 
 #define CT_GET_CONTAINER_COUNT 4
 struct aac_get_container_count {
-	u32		command;	/* VM_ContainerConfig */
-	u32		type;		/* CT_GET_CONTAINER_COUNT */
+	__le32		command;	/* VM_ContainerConfig */
+	__le32		type;		/* CT_GET_CONTAINER_COUNT */
 };
 
 struct aac_get_container_count_resp {
-	u32		response; /* ST_OK */
-	u32		dummy0;
-	u32		MaxContainers;
-	u32		ContainerSwitchEntries;
-	u32		MaxPartitions;
+	__le32		response; /* ST_OK */
+	__le32		dummy0;
+	__le32		MaxContainers;
+	__le32		ContainerSwitchEntries;
+	__le32		MaxPartitions;
 };
 
 
@@ -1308,15 +1414,19 @@ struct aac_get_container_count_resp {
  */
 
 struct aac_mntent {
-	u32    			oid;
-	u8			name[16];	// if applicable
-	struct creation_info	create_info;	// if applicable
-	u32			capacity;
-	u32			vol;    	// substrate structure
-	u32			obj;	        // FT_FILESYS, FT_DATABASE, etc.
-	u32			state;		// unready for mounting, readonly, etc.
-	union aac_contentinfo	fileinfo;	// Info specific to content manager (eg, filesystem)
-	u32			altoid;		// != oid <==> snapshot or broken mirror exists
+	__le32    		oid;
+	u8			name[16];	/* if applicable */
+	struct creation_info	create_info;	/* if applicable */
+	__le32			capacity;
+	__le32			vol;    	/* substrate structure */
+	__le32			obj;	        /* FT_FILESYS, 
+						   FT_DATABASE, etc. */
+	__le32			state;		/* unready for mounting, 
+						   readonly, etc. */
+	union aac_contentinfo	fileinfo;	/* Info specific to content 
+						   manager (eg, filesystem) */
+	__le32			altoid;		/* != oid <==> snapshot or 
+						   broken mirror exists */
 };
 
 #define FSCS_NOTCLEAN	0x0001  /* fsck is neccessary before mounting */
@@ -1324,40 +1434,40 @@ struct aac_mntent {
 #define FSCS_HIDDEN	0x0004	/* should be ignored - set during a clear */
 
 struct aac_query_mount {
-	u32		command;
-	u32		type;
-	u32		count;
+	__le32		command;
+	__le32		type;
+	__le32		count;
 };
 
 struct aac_mount {
-	u32		status;
-	u32	   	type;           /* should be same as that requested */
-	u32		count;
+	__le32		status;
+	__le32	   	type;           /* should be same as that requested */
+	__le32		count;
 	struct aac_mntent mnt[1];
 };
 
 #define CT_READ_NAME 130
 struct aac_get_name {
-	u32		command;	/* VM_ContainerConfig */
-	u32		type;		/* CT_READ_NAME */
-	u32		cid;
-	u32		parm1;
-	u32		parm2;
-	u32		parm3;
-	u32		parm4;
-	u32		count;	/* sizeof(((struct aac_get_name_resp *)NULL)->data) */
+	__le32		command;	/* VM_ContainerConfig */
+	__le32		type;		/* CT_READ_NAME */
+	__le32		cid;
+	__le32		parm1;
+	__le32		parm2;
+	__le32		parm3;
+	__le32		parm4;
+	__le32		count;	/* sizeof(((struct aac_get_name_resp *)NULL)->data) */
 };
 
 #define CT_OK        218
 struct aac_get_name_resp {
-	u32		dummy0;
-	u32		dummy1;
-	u32		status;	/* CT_OK */
-	u32		parm1;
-	u32		parm2;
-	u32		parm3;
-	u32		parm4;
-	u32		parm5;
+	__le32		dummy0;
+	__le32		dummy1;
+	__le32		status;	/* CT_OK */
+	__le32		parm1;
+	__le32		parm2;
+	__le32		parm3;
+	__le32		parm4;
+	__le32		parm5;
 	u8		data[16];
 };
 
@@ -1366,8 +1476,8 @@ struct aac_get_name_resp {
  */
 
 struct aac_close {
-	u32	command;
-	u32	cid;
+	__le32	command;
+	__le32	cid;
 };
 
 struct aac_query_disk
@@ -1434,6 +1544,7 @@ struct revision
 #define FSACTL_GET_PCI_INFO               	CTL_CODE(2119, METHOD_BUFFERED)
 #define FSACTL_FORCE_DELETE_DISK		CTL_CODE(2120, METHOD_NEITHER)
 #define FSACTL_GET_CONTAINERS			2131
+#define FSACTL_SEND_LARGE_FIB			CTL_CODE(2138, METHOD_BUFFERED)
 
 
 struct aac_common
@@ -1573,8 +1684,8 @@ extern struct aac_common aac_config;
  */
 
 struct aac_aifcmd {
-	u32 command;		/* Tell host what type of notify this is */
-	u32 seqnum;		/* To allow ordering of reports (if necessary) */
+	__le32 command;		/* Tell host what type of notify this is */
+	__le32 seqnum;		/* To allow ordering of reports (if necessary) */
 	u8 data[1];		/* Undefined length (from kernel viewpoint) */
 };
 
@@ -1597,7 +1708,6 @@ int fib_setup(struct aac_dev *dev);
 void fib_map_free(struct aac_dev *dev);
 void fib_free(struct fib * context);
 void fib_init(struct fib * context);
-void fib_dealloc(struct fib * context);
 void aac_printf(struct aac_dev *dev, u32 val);
 int fib_send(u16 command, struct fib * context, unsigned long size, int priority, int wait, int reply, fib_callback callback, void *ctxt);
 int aac_consumer_get(struct aac_dev * dev, struct aac_queue * q, struct aac_entry **entry);
@@ -1621,3 +1731,5 @@ int fib_adapter_complete(struct fib * fi
 struct aac_driver_ident* aac_get_driver_ident(int devtype);
 int aac_get_adapter_info(struct aac_dev* dev);
 int aac_send_shutdown(struct aac_dev *dev);
+extern int numacb;
+extern int acbsize;
diff --git a/drivers/scsi/aacraid/commctrl.c b/drivers/scsi/aacraid/commctrl.c
--- a/drivers/scsi/aacraid/commctrl.c
+++ b/drivers/scsi/aacraid/commctrl.c
@@ -51,15 +51,22 @@
  *	This routine sends a fib to the adapter on behalf of a user level
  *	program.
  */
+# define AAC_DEBUG_PREAMBLE	KERN_INFO
+# define AAC_DEBUG_POSTAMBLE
  
 static int ioctl_send_fib(struct aac_dev * dev, void __user *arg)
 {
 	struct hw_fib * kfib;
 	struct fib *fibptr;
+	struct hw_fib * hw_fib = (struct hw_fib *)0;
+	dma_addr_t hw_fib_pa = (dma_addr_t)0LL;
+	unsigned size;
+	int retval;
 
 	fibptr = fib_alloc(dev);
-	if(fibptr == NULL)
+	if(fibptr == NULL) {
 		return -ENOMEM;
+	}
 		
 	kfib = fibptr->hw_fib;
 	/*
@@ -74,19 +81,24 @@ static int ioctl_send_fib(struct aac_dev
 	 *	will not overrun the buffer when we copy the memory. Return
 	 *	an error if we would.
 	 */
-	if (le16_to_cpu(kfib->header.Size) > 
-			sizeof(struct hw_fib) - sizeof(struct aac_fibhdr)) {
-		fib_free(fibptr);
-		return -EINVAL;
+	size = le16_to_cpu(kfib->header.Size) + sizeof(struct aac_fibhdr);
+	if (size < le16_to_cpu(kfib->header.SenderSize))
+		size = le16_to_cpu(kfib->header.SenderSize);
+	if (size > dev->max_fib_size) {
+		/* Highjack the hw_fib */
+		hw_fib = fibptr->hw_fib;
+		hw_fib_pa = fibptr->hw_fib_pa;
+		fibptr->hw_fib = kfib = pci_alloc_consistent(dev->pdev, size, &fibptr->hw_fib_pa);
+		memset(((char *)kfib) + dev->max_fib_size, 0, size - dev->max_fib_size);
+		memcpy(kfib, hw_fib, dev->max_fib_size);
 	}
 
-	if (copy_from_user(kfib, arg, le16_to_cpu(kfib->header.Size) +
-				sizeof(struct aac_fibhdr))) {
-		fib_free(fibptr);
-		return -EFAULT;
+	if (copy_from_user(kfib, arg, size)) {
+		retval = -EFAULT;
+		goto cleanup;
 	}
 
-	if (kfib->header.Command == cpu_to_le32(TakeABreakPt)) {
+	if (kfib->header.Command == cpu_to_le16(TakeABreakPt)) {
 		aac_adapter_interrupt(dev);
 		/*
 		 * Since we didn't really send a fib, zero out the state to allow 
@@ -94,16 +106,15 @@ static int ioctl_send_fib(struct aac_dev
 		 */
 		kfib->header.XferState = 0;
 	} else {
-		int retval = fib_send(kfib->header.Command, fibptr,
+		retval = fib_send(le16_to_cpu(kfib->header.Command), fibptr,
 				le16_to_cpu(kfib->header.Size) , FsaNormal,
 				1, 1, NULL, NULL);
 		if (retval) {
-			fib_free(fibptr);
-			return retval;
+			goto cleanup;
 		}
 		if (fib_complete(fibptr) != 0) {
-			fib_free(fibptr);
-			return -EINVAL;
+			retval = -EINVAL;
+			goto cleanup;
 		}
 	}
 	/*
@@ -114,12 +125,17 @@ static int ioctl_send_fib(struct aac_dev
 	 *	was already included by the adapter.)
 	 */
 
-	if (copy_to_user(arg, (void *)kfib, kfib->header.Size)) {
-		fib_free(fibptr);
-		return -EFAULT;
+	retval = 0;
+	if (copy_to_user(arg, (void *)kfib, size))
+		retval = -EFAULT;
+cleanup:
+	if (hw_fib) {
+		pci_free_consistent(dev->pdev, size, kfib, fibptr->hw_fib_pa);
+		fibptr->hw_fib_pa = hw_fib_pa;
+		fibptr->hw_fib = hw_fib;
 	}
 	fib_free(fibptr);
-	return 0;
+	return retval;
 }
 
 /**
@@ -391,26 +407,28 @@ static int check_revision(struct aac_dev
 	struct revision response;
 
 	response.compat = 1;
-	response.version = dev->adapter_info.kernelrev;
-	response.build = dev->adapter_info.kernelbuild;
+	response.version = le32_to_cpu(dev->adapter_info.kernelrev);
+	response.build = le32_to_cpu(dev->adapter_info.kernelbuild);
 
 	if (copy_to_user(arg, &response, sizeof(response)))
 		return -EFAULT;
 	return 0;
 }
 
+
 /**
  *
  * aac_send_raw_scb
  *
  */
 
-int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
+static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
 {
 	struct fib* srbfib;
 	int status;
-	struct aac_srb *srbcmd;
-	struct aac_srb __user *user_srb = arg;
+	struct aac_srb *srbcmd = NULL;
+	struct user_aac_srb *user_srbcmd = NULL;
+	struct user_aac_srb __user *user_srb = arg;
 	struct aac_srb_reply __user *user_reply;
 	struct aac_srb_reply* reply;
 	u32 fibsize = 0;
@@ -426,50 +444,59 @@ int aac_send_raw_srb(struct aac_dev* dev
 
 
 	if (!capable(CAP_SYS_ADMIN)){
-		printk(KERN_DEBUG"aacraid: No permission to send raw srb\n"); 
+		dprintk((KERN_DEBUG"aacraid: No permission to send raw srb\n")); 
 		return -EPERM;
 	}
 	/*
 	 *	Allocate and initialize a Fib then setup a BlockWrite command
 	 */
 	if (!(srbfib = fib_alloc(dev))) {
-		return -1;
+		return -ENOMEM;
 	}
 	fib_init(srbfib);
 
 	srbcmd = (struct aac_srb*) fib_data(srbfib);
 
+	memset(sg_list, 0, sizeof(sg_list)); /* cleanup may take issue */
 	if(copy_from_user(&fibsize, &user_srb->count,sizeof(u32))){
-		printk(KERN_DEBUG"aacraid: Could not copy data size from user\n"); 
+		dprintk((KERN_DEBUG"aacraid: Could not copy data size from user\n")); 
 		rcode = -EFAULT;
 		goto cleanup;
 	}
 
-	if (fibsize > FIB_DATA_SIZE_IN_BYTES) {
+	if (fibsize > (dev->max_fib_size - sizeof(struct aac_fibhdr))) {
 		rcode = -EINVAL;
 		goto cleanup;
 	}
 
-	if(copy_from_user(srbcmd, user_srb,fibsize)){
-		printk(KERN_DEBUG"aacraid: Could not copy srb from user\n"); 
+	user_srbcmd = kmalloc(fibsize, GFP_KERNEL);
+	if (!user_srbcmd) {
+		dprintk((KERN_DEBUG"aacraid: Could not make a copy of the srb\n"));
+		rcode = -ENOMEM;
+		goto cleanup;
+	}
+	if(copy_from_user(user_srbcmd, user_srb,fibsize)){
+		dprintk((KERN_DEBUG"aacraid: Could not copy srb from user\n")); 
 		rcode = -EFAULT;
 		goto cleanup;
 	}
 
 	user_reply = arg+fibsize;
 
-	flags = srbcmd->flags;
+	flags = user_srbcmd->flags; /* from user in cpu order */
 	// Fix up srb for endian and force some values
+
 	srbcmd->function = cpu_to_le32(SRBF_ExecuteScsi);	// Force this
-	srbcmd->channel  = cpu_to_le32(srbcmd->channel);
-	srbcmd->id	 = cpu_to_le32(srbcmd->id);
-	srbcmd->lun      = cpu_to_le32(srbcmd->lun);
-	srbcmd->flags    = cpu_to_le32(srbcmd->flags);
-	srbcmd->timeout  = cpu_to_le32(srbcmd->timeout);
-	srbcmd->retry_limit =cpu_to_le32(0); // Obsolete parameter
-	srbcmd->cdb_size = cpu_to_le32(srbcmd->cdb_size);
+	srbcmd->channel  = cpu_to_le32(user_srbcmd->channel);
+	srbcmd->id	 = cpu_to_le32(user_srbcmd->id);
+	srbcmd->lun      = cpu_to_le32(user_srbcmd->lun);
+	srbcmd->timeout  = cpu_to_le32(user_srbcmd->timeout);
+	srbcmd->flags    = cpu_to_le32(flags);
+	srbcmd->retry_limit = 0; // Obsolete parameter
+	srbcmd->cdb_size = cpu_to_le32(user_srbcmd->cdb_size);
+	memcpy(srbcmd->cdb, user_srbcmd->cdb, sizeof(srbcmd->cdb));
 	
-	switch (srbcmd->flags & (SRB_DataIn | SRB_DataOut)) {
+	switch (flags & (SRB_DataIn | SRB_DataOut)) {
 	case SRB_DataOut:
 		data_dir = DMA_TO_DEVICE;
 		break;
@@ -482,118 +509,148 @@ int aac_send_raw_srb(struct aac_dev* dev
 	default:
 		data_dir = DMA_NONE;
 	}
+	if (user_srbcmd->sg.count > (sizeof(sg_list)/sizeof(sg_list[0]))) {
+		dprintk((KERN_DEBUG"aacraid: too many sg entries %d\n",
+		  le32_to_cpu(srbcmd->sg.count)));
+		rcode = -EINVAL;
+		goto cleanup;
+	}
 	if (dev->dac_support == 1) {
+		struct user_sgmap64* upsg = (struct user_sgmap64*)&user_srbcmd->sg;
 		struct sgmap64* psg = (struct sgmap64*)&srbcmd->sg;
+		struct user_sgmap* usg;
 		byte_count = 0;
 
 		/*
 		 * This should also catch if user used the 32 bit sgmap
 		 */
 		actual_fibsize = sizeof(struct aac_srb) - 
-			sizeof(struct sgentry) + ((srbcmd->sg.count & 0xff) * 
-			 	sizeof(struct sgentry64));
+			sizeof(struct sgentry) +
+			((upsg->count & 0xff) * 
+		 	sizeof(struct sgentry));
 		if(actual_fibsize != fibsize){ // User made a mistake - should not continue
-			printk(KERN_DEBUG"aacraid: Bad Size specified in Raw SRB command\n");
+			dprintk((KERN_DEBUG"aacraid: Bad Size specified in Raw SRB command\n"));
 			rcode = -EINVAL;
 			goto cleanup;
 		}
-		if ((data_dir == DMA_NONE) && psg->count) { 
-			printk(KERN_DEBUG"aacraid: SG with no direction specified in Raw SRB command\n");
+		usg = kmalloc(actual_fibsize - sizeof(struct aac_srb)
+		  + sizeof(struct sgmap), GFP_KERNEL);
+		if (!usg) {
+			dprintk((KERN_DEBUG"aacraid: Allocation error in Raw SRB command\n"));
+			rcode = -ENOMEM;
+			goto cleanup;
+		}
+		memcpy (usg, upsg, actual_fibsize - sizeof(struct aac_srb)
+		  + sizeof(struct sgmap));
+		actual_fibsize = sizeof(struct aac_srb) - 
+			sizeof(struct sgentry) + ((usg->count & 0xff) * 
+			 	sizeof(struct sgentry64));
+		if ((data_dir == DMA_NONE) && upsg->count) {
+			kfree (usg);
+			dprintk((KERN_DEBUG"aacraid: SG with no direction specified in Raw SRB command\n"));
 			rcode = -EINVAL;
 			goto cleanup;
 		}
 
-		for (i = 0; i < psg->count; i++) {
-			dma_addr_t addr; 
-			u64 le_addr;
+		for (i = 0; i < usg->count; i++) {
+			u64 addr;
 			void* p;
-			p = kmalloc(psg->sg[i].count,GFP_KERNEL|__GFP_DMA);
+			/* Does this really need to be GFP_DMA? */
+			p = kmalloc(usg->sg[i].count,GFP_KERNEL|__GFP_DMA);
 			if(p == 0) {
-				printk(KERN_DEBUG"aacraid: Could not allocate SG buffer - size = %d buffer number %d of %d\n",
-				psg->sg[i].count,i,psg->count);
+				kfree (usg);
+				dprintk((KERN_DEBUG"aacraid: Could not allocate SG buffer - size = %d buffer number %d of %d\n",
+				  usg->sg[i].count,i,usg->count));
 				rcode = -ENOMEM;
 				goto cleanup;
 			}
-			sg_user[i] = (void __user *)psg->sg[i].addr;
+			sg_user[i] = (void __user *)usg->sg[i].addr;
 			sg_list[i] = p; // save so we can clean up later
 			sg_indx = i;
 
 			if( flags & SRB_DataOut ){
-				if(copy_from_user(p,sg_user[i],psg->sg[i].count)){
-					printk(KERN_DEBUG"aacraid: Could not copy sg data from user\n"); 
+				if(copy_from_user(p,sg_user[i],upsg->sg[i].count)){
+					kfree (usg);
+					dprintk((KERN_DEBUG"aacraid: Could not copy sg data from user\n")); 
 					rcode = -EFAULT;
 					goto cleanup;
 				}
 			}
-			addr = pci_map_single(dev->pdev, p, psg->sg[i].count, data_dir);
+			addr = pci_map_single(dev->pdev, p, usg->sg[i].count, data_dir);
 
-			le_addr = cpu_to_le64(addr);
-			psg->sg[i].addr[1] = (u32)(le_addr>>32);
-			psg->sg[i].addr[0] = (u32)(le_addr & 0xffffffff);
-			psg->sg[i].count = cpu_to_le32(psg->sg[i].count);  
-			byte_count += psg->sg[i].count;
+			psg->sg[i].addr[0] = cpu_to_le32(addr & 0xffffffff);
+			psg->sg[i].addr[1] = cpu_to_le32(addr>>32);
+			psg->sg[i].count = cpu_to_le32(usg->sg[i].count);  
+			byte_count += usg->sg[i].count;
 		}
+		kfree (usg);
 
 		srbcmd->count = cpu_to_le32(byte_count);
+		psg->count = cpu_to_le32(sg_indx+1);
 		status = fib_send(ScsiPortCommand64, srbfib, actual_fibsize, FsaNormal, 1, 1,NULL,NULL);
 	} else {
+		struct user_sgmap* upsg = &user_srbcmd->sg;
 		struct sgmap* psg = &srbcmd->sg;
 		byte_count = 0;
 
-		actual_fibsize = sizeof (struct aac_srb) + 
-			(((le32_to_cpu(srbcmd->sg.count) & 0xff) - 1) * 
-			 sizeof (struct sgentry));
+		actual_fibsize = sizeof (struct aac_srb) + (((user_srbcmd->sg.count & 0xff) - 1) * sizeof (struct sgentry));
 		if(actual_fibsize != fibsize){ // User made a mistake - should not continue
-			printk(KERN_DEBUG"aacraid: Bad Size specified in Raw SRB command\n");
+			dprintk((KERN_DEBUG"aacraid: Bad Size specified in Raw SRB command\n"));
 			rcode = -EINVAL;
 			goto cleanup;
 		}
-		if ((data_dir == DMA_NONE) && psg->count) {
-			printk(KERN_DEBUG"aacraid: SG with no direction specified in Raw SRB command\n");
+		if ((data_dir == DMA_NONE) && upsg->count) {
+			dprintk((KERN_DEBUG"aacraid: SG with no direction specified in Raw SRB command\n"));
 			rcode = -EINVAL;
 			goto cleanup;
 		}
-		for (i = 0; i < psg->count; i++) {
+		for (i = 0; i < upsg->count; i++) {
 			dma_addr_t addr; 
 			void* p;
-			p = kmalloc(psg->sg[i].count,GFP_KERNEL);
+			p = kmalloc(upsg->sg[i].count, GFP_KERNEL);
 			if(p == 0) {
-				printk(KERN_DEBUG"aacraid: Could not allocate SG buffer - size = %d buffer number %d of %d\n",
-				psg->sg[i].count,i,psg->count);
+				dprintk((KERN_DEBUG"aacraid: Could not allocate SG buffer - size = %d buffer number %d of %d\n",
+				  upsg->sg[i].count, i, upsg->count));
 				rcode = -ENOMEM;
 				goto cleanup;
 			}
-			sg_user[i] = (void __user *)(psg->sg[i].addr);
+			sg_user[i] = (void __user *)upsg->sg[i].addr;
 			sg_list[i] = p; // save so we can clean up later
 			sg_indx = i;
 
 			if( flags & SRB_DataOut ){
-				if(copy_from_user(p,sg_user[i],psg->sg[i].count)){
-					printk(KERN_DEBUG"aacraid: Could not copy sg data from user\n"); 
+				if(copy_from_user(p, sg_user[i],
+						upsg->sg[i].count)) {
+					dprintk((KERN_DEBUG"aacraid: Could not copy sg data from user\n")); 
 					rcode = -EFAULT;
 					goto cleanup;
 				}
 			}
-			addr = pci_map_single(dev->pdev, p, psg->sg[i].count, data_dir);
+			addr = pci_map_single(dev->pdev, p,
+				upsg->sg[i].count, data_dir);
 
 			psg->sg[i].addr = cpu_to_le32(addr);
-			psg->sg[i].count = cpu_to_le32(psg->sg[i].count);  
-			byte_count += psg->sg[i].count;
+			psg->sg[i].count = cpu_to_le32(upsg->sg[i].count);  
+			byte_count += upsg->sg[i].count;
 		}
 		srbcmd->count = cpu_to_le32(byte_count);
+		psg->count = cpu_to_le32(sg_indx+1);
 		status = fib_send(ScsiPortCommand, srbfib, actual_fibsize, FsaNormal, 1, 1, NULL, NULL);
 	}
 
 	if (status != 0){
-		printk(KERN_DEBUG"aacraid: Could not send raw srb fib to hba\n"); 
-		rcode = -1;
+		dprintk((KERN_DEBUG"aacraid: Could not send raw srb fib to hba\n")); 
+		rcode = -ENXIO;
 		goto cleanup;
 	}
 
 	if( flags & SRB_DataIn ) {
 		for(i = 0 ; i <= sg_indx; i++){
-			if(copy_to_user(sg_user[i],sg_list[i],le32_to_cpu(srbcmd->sg.sg[i].count))){
-				printk(KERN_DEBUG"aacraid: Could not copy sg data to user\n"); 
+			byte_count = le32_to_cpu((dev->dac_support == 1)
+			      ? ((struct sgmap64*)&srbcmd->sg)->sg[i].count
+			      : srbcmd->sg.sg[i].count);
+			if(copy_to_user(sg_user[i], sg_list[i], byte_count)){
+				dprintk((KERN_DEBUG"aacraid: Could not copy sg data to user\n")); 
 				rcode = -EFAULT;
 				goto cleanup;
 
@@ -603,12 +660,13 @@ int aac_send_raw_srb(struct aac_dev* dev
 
 	reply = (struct aac_srb_reply *) fib_data(srbfib);
 	if(copy_to_user(user_reply,reply,sizeof(struct aac_srb_reply))){
-		printk(KERN_DEBUG"aacraid: Could not copy reply to user\n"); 
+		dprintk((KERN_DEBUG"aacraid: Could not copy reply to user\n")); 
 		rcode = -EFAULT;
 		goto cleanup;
 	}
 
 cleanup:
+	kfree(user_srbcmd);
 	for(i=0; i <= sg_indx; i++){
 		kfree(sg_list[i]);
 	}
@@ -618,14 +676,13 @@ cleanup:
 	return rcode;
 }
 
-
 struct aac_pci_info {
         u32 bus;
         u32 slot;
 };
 
 
-int aac_get_pci_info(struct aac_dev* dev, void __user *arg)
+static int aac_get_pci_info(struct aac_dev* dev, void __user *arg)
 {
         struct aac_pci_info pci_info;
 
@@ -633,11 +690,11 @@ int aac_get_pci_info(struct aac_dev* dev
 	pci_info.slot = PCI_SLOT(dev->pdev->devfn);
 
        if (copy_to_user(arg, &pci_info, sizeof(struct aac_pci_info))) {
-		printk(KERN_DEBUG "aacraid: Could not copy pci info\n");
+               dprintk((KERN_DEBUG "aacraid: Could not copy pci info\n"));
                return -EFAULT;
 	}
         return 0;
- }
+}
  
 
 int aac_do_ioctl(struct aac_dev * dev, int cmd, void __user *arg)
@@ -656,6 +713,7 @@ int aac_do_ioctl(struct aac_dev * dev, i
 	case FSACTL_MINIPORT_REV_CHECK:
 		status = check_revision(dev, arg);
 		break;
+	case FSACTL_SEND_LARGE_FIB:
 	case FSACTL_SENDFIB:
 		status = ioctl_send_fib(dev, arg);
 		break;
diff --git a/drivers/scsi/aacraid/comminit.c b/drivers/scsi/aacraid/comminit.c
--- a/drivers/scsi/aacraid/comminit.c
+++ b/drivers/scsi/aacraid/comminit.c
@@ -39,6 +39,7 @@
 #include <linux/blkdev.h>
 #include <linux/completion.h>
 #include <linux/mm.h>
+#include <scsi/scsi_host.h>
 #include <asm/semaphore.h>
 
 #include "aacraid.h"
@@ -49,8 +50,8 @@ static int aac_alloc_comm(struct aac_dev
 {
 	unsigned char *base;
 	unsigned long size, align;
-	unsigned long fibsize = 4096;
-	unsigned long printfbufsiz = 256;
+	const unsigned long fibsize = 4096;
+	const unsigned long printfbufsiz = 256;
 	struct aac_init *init;
 	dma_addr_t phys;
 
@@ -74,6 +75,8 @@ static int aac_alloc_comm(struct aac_dev
 	init = dev->init;
 
 	init->InitStructRevision = cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION);
+	if (dev->max_fib_size != sizeof(struct hw_fib))
+		init->InitStructRevision = cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION_4);
 	init->MiniPortRevision = cpu_to_le32(Sa_MINIPORT_REVISION);
 	init->fsrev = cpu_to_le32(dev->fsrev);
 
@@ -110,6 +113,10 @@ static int aac_alloc_comm(struct aac_dev
 		init->HostPhysMemPages = cpu_to_le32(AAC_MAX_HOSTPHYSMEMPAGES);
 	}
 
+	init->InitFlags = 0;
+	init->MaxIoCommands = cpu_to_le32(dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB);
+	init->MaxIoSize = cpu_to_le32(dev->scsi_host_ptr->max_sectors << 9);
+	init->MaxFibSize = cpu_to_le32(dev->max_fib_size);
 
 	/*
 	 * Increment the base address by the amount already used
@@ -152,8 +159,8 @@ static void aac_queue_init(struct aac_de
 	init_waitqueue_head(&q->qfull);
 	spin_lock_init(&q->lockdata);
 	q->lock = &q->lockdata;
-	q->headers.producer = mem;
-	q->headers.consumer = mem+1;
+	q->headers.producer = (__le32 *)mem;
+	q->headers.consumer = (__le32 *)(mem+1);
 	*(q->headers.producer) = cpu_to_le32(qsize);
 	*(q->headers.consumer) = cpu_to_le32(qsize);
 	q->entries = qsize;
@@ -173,6 +180,8 @@ int aac_send_shutdown(struct aac_dev * d
 	int status;
 
 	fibctx = fib_alloc(dev);
+	if (!fibctx)
+		return -ENOMEM;
 	fib_init(fibctx);
 
 	cmd = (struct aac_close *) fib_data(fibctx);
@@ -204,7 +213,7 @@ int aac_send_shutdown(struct aac_dev * d
  *		0 - If there were errors initing. This is a fatal error.
  */
  
-int aac_comm_init(struct aac_dev * dev)
+static int aac_comm_init(struct aac_dev * dev)
 {
 	unsigned long hdrsize = (sizeof(u32) * NUMBER_OF_COMM_QUEUES) * 2;
 	unsigned long queuesize = sizeof(struct aac_entry) * TOTAL_QUEUE_ENTRIES;
@@ -293,6 +302,79 @@ int aac_comm_init(struct aac_dev * dev)
 
 struct aac_dev *aac_init_adapter(struct aac_dev *dev)
 {
+	u32 status[5];
+	struct Scsi_Host * host = dev->scsi_host_ptr;
+
+	/*
+	 *	Check the preferred comm settings, defaults from template.
+	 */
+	dev->max_fib_size = sizeof(struct hw_fib);
+	dev->sg_tablesize = host->sg_tablesize = (dev->max_fib_size
+		- sizeof(struct aac_fibhdr)
+		- sizeof(struct aac_write) + sizeof(struct sgmap))
+			/ sizeof(struct sgmap);
+	if ((!aac_adapter_sync_cmd(dev, GET_COMM_PREFERRED_SETTINGS,
+	  0, 0, 0, 0, 0, 0,
+	  status+0, status+1, status+2, status+3, status+4))
+	 && (status[0] == 0x00000001)) {
+		/*
+		 *	status[1] >> 16		maximum command size in KB
+		 *	status[1] & 0xFFFF	maximum FIB size
+		 *	status[2] >> 16		maximum SG elements to driver
+		 *	status[2] & 0xFFFF	maximum SG elements from driver
+		 *	status[3] & 0xFFFF	maximum number FIBs outstanding
+		 */
+		host->max_sectors = (status[1] >> 16) << 1;
+		dev->max_fib_size = status[1] & 0xFFFF;
+		host->sg_tablesize = status[2] >> 16;
+		dev->sg_tablesize = status[2] & 0xFFFF;
+		host->can_queue = (status[3] & 0xFFFF) - AAC_NUM_MGT_FIB;
+		/*
+		 *	NOTE:
+		 *	All these overrides are based on a fixed internal
+		 *	knowledge and understanding of existing adapters,
+		 *	acbsize should be set with caution.
+		 */
+		if (acbsize == 512) {
+			host->max_sectors = AAC_MAX_32BIT_SGBCOUNT;
+			dev->max_fib_size = 512;
+			dev->sg_tablesize = host->sg_tablesize
+			  = (512 - sizeof(struct aac_fibhdr)
+			    - sizeof(struct aac_write) + sizeof(struct sgmap))
+			     / sizeof(struct sgmap);
+			host->can_queue = AAC_NUM_IO_FIB;
+		} else if (acbsize == 2048) {
+			host->max_sectors = 512;
+			dev->max_fib_size = 2048;
+			host->sg_tablesize = 65;
+			dev->sg_tablesize = 81;
+			host->can_queue = 512 - AAC_NUM_MGT_FIB;
+		} else if (acbsize == 4096) {
+			host->max_sectors = 1024;
+			dev->max_fib_size = 4096;
+			host->sg_tablesize = 129;
+			dev->sg_tablesize = 166;
+			host->can_queue = 256 - AAC_NUM_MGT_FIB;
+		} else if (acbsize == 8192) {
+			host->max_sectors = 2048;
+			dev->max_fib_size = 8192;
+			host->sg_tablesize = 257;
+			dev->sg_tablesize = 337;
+			host->can_queue = 128 - AAC_NUM_MGT_FIB;
+		} else if (acbsize > 0) {
+			printk("Illegal acbsize=%d ignored\n", acbsize);
+		}
+	}
+	{
+
+		if (numacb > 0) {
+			if (numacb < host->can_queue)
+				host->can_queue = numacb;
+			else
+				printk("numacb=%d ignored\n", numacb);
+		}
+	}
+
 	/*
 	 *	Ok now init the communication subsystem
 	 */
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
--- a/drivers/scsi/aacraid/commsup.c
+++ b/drivers/scsi/aacraid/commsup.c
@@ -25,7 +25,7 @@
  *  commsup.c
  *
  * Abstract: Contain all routines that are required for FSA host/adapter
- *    commuication.
+ *    communication.
  *
  */
 
@@ -38,6 +38,7 @@
 #include <linux/slab.h>
 #include <linux/completion.h>
 #include <linux/blkdev.h>
+#include <scsi/scsi_host.h>
 #include <asm/semaphore.h>
 
 #include "aacraid.h"
@@ -52,7 +53,13 @@
  
 static int fib_map_alloc(struct aac_dev *dev)
 {
-	if((dev->hw_fib_va = pci_alloc_consistent(dev->pdev, sizeof(struct hw_fib) * AAC_NUM_FIB, &dev->hw_fib_pa))==NULL)
+	dprintk((KERN_INFO
+	  "allocate hardware fibs pci_alloc_consistent(%p, %d * (%d + %d), %p)\n",
+	  dev->pdev, dev->max_fib_size, dev->scsi_host_ptr->can_queue,
+	  AAC_NUM_MGT_FIB, &dev->hw_fib_pa));
+	if((dev->hw_fib_va = pci_alloc_consistent(dev->pdev, dev->max_fib_size
+	  * (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB),
+	  &dev->hw_fib_pa))==NULL)
 		return -ENOMEM;
 	return 0;
 }
@@ -67,7 +74,7 @@ static int fib_map_alloc(struct aac_dev 
 
 void fib_map_free(struct aac_dev *dev)
 {
-	pci_free_consistent(dev->pdev, sizeof(struct hw_fib) * AAC_NUM_FIB, dev->hw_fib_va, dev->hw_fib_pa);
+	pci_free_consistent(dev->pdev, dev->max_fib_size * (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB), dev->hw_fib_va, dev->hw_fib_pa);
 }
 
 /**
@@ -84,17 +91,22 @@ int fib_setup(struct aac_dev * dev)
 	struct hw_fib *hw_fib_va;
 	dma_addr_t hw_fib_pa;
 	int i;
-	
-	if(fib_map_alloc(dev)<0)
+
+	while (((i = fib_map_alloc(dev)) == -ENOMEM)
+	 && (dev->scsi_host_ptr->can_queue > (64 - AAC_NUM_MGT_FIB))) {
+		dev->init->MaxIoCommands = cpu_to_le32((dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB) >> 1);
+		dev->scsi_host_ptr->can_queue = le32_to_cpu(dev->init->MaxIoCommands) - AAC_NUM_MGT_FIB;
+	}
+	if (i<0)
 		return -ENOMEM;
 		
 	hw_fib_va = dev->hw_fib_va;
 	hw_fib_pa = dev->hw_fib_pa;
-	memset(hw_fib_va, 0, sizeof(struct hw_fib) * AAC_NUM_FIB);
+	memset(hw_fib_va, 0, dev->max_fib_size * (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB));
 	/*
 	 *	Initialise the fibs
 	 */
-	for (i = 0, fibptr = &dev->fibs[i]; i < AAC_NUM_FIB; i++, fibptr++) 
+	for (i = 0, fibptr = &dev->fibs[i]; i < (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB); i++, fibptr++) 
 	{
 		fibptr->dev = dev;
 		fibptr->hw_fib = hw_fib_va;
@@ -102,16 +114,16 @@ int fib_setup(struct aac_dev * dev)
 		fibptr->next = fibptr+1;	/* Forward chain the fibs */
 		init_MUTEX_LOCKED(&fibptr->event_wait);
 		spin_lock_init(&fibptr->event_lock);
-		hw_fib_va->header.XferState = 0xffffffff;
-		hw_fib_va->header.SenderSize = cpu_to_le16(sizeof(struct hw_fib));
+		hw_fib_va->header.XferState = cpu_to_le32(0xffffffff);
+		hw_fib_va->header.SenderSize = cpu_to_le16(dev->max_fib_size);
 		fibptr->hw_fib_pa = hw_fib_pa;
-		hw_fib_va = (struct hw_fib *)((unsigned char *)hw_fib_va + sizeof(struct hw_fib));
-		hw_fib_pa = hw_fib_pa + sizeof(struct hw_fib); 
+		hw_fib_va = (struct hw_fib *)((unsigned char *)hw_fib_va + dev->max_fib_size);
+		hw_fib_pa = hw_fib_pa + dev->max_fib_size;
 	}
 	/*
 	 *	Add the fib chain to the free list
 	 */
-	dev->fibs[AAC_NUM_FIB-1].next = NULL;
+	dev->fibs[dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB - 1].next = NULL;
 	/*
 	 *	Enable this to debug out of queue space
 	 */
@@ -124,7 +136,7 @@ int fib_setup(struct aac_dev * dev)
  *	@dev: Adapter to allocate the fib for
  *
  *	Allocate a fib from the adapter fib pool. If the pool is empty we
- *	wait for fibs to become free.
+ *	return NULL.
  */
  
 struct fib * fib_alloc(struct aac_dev *dev)
@@ -133,10 +145,10 @@ struct fib * fib_alloc(struct aac_dev *d
 	unsigned long flags;
 	spin_lock_irqsave(&dev->fib_lock, flags);
 	fibptr = dev->free_fib;	
-	/* Cannot sleep here or you get hangs. Instead we did the
-	   maths at compile time. */
-	if(!fibptr)
-		BUG();
+	if(!fibptr){
+		spin_unlock_irqrestore(&dev->fib_lock, flags);
+		return fibptr;
+	}
 	dev->free_fib = fibptr->next;
 	spin_unlock_irqrestore(&dev->fib_lock, flags);
 	/*
@@ -196,11 +208,11 @@ void fib_init(struct fib *fibptr)
 	struct hw_fib *hw_fib = fibptr->hw_fib;
 
 	hw_fib->header.StructType = FIB_MAGIC;
-	hw_fib->header.Size = cpu_to_le16(sizeof(struct hw_fib));
-        hw_fib->header.XferState = cpu_to_le32(HostOwned | FibInitialized | FibEmpty | FastResponseCapable);
+	hw_fib->header.Size = cpu_to_le16(fibptr->dev->max_fib_size);
+	hw_fib->header.XferState = cpu_to_le32(HostOwned | FibInitialized | FibEmpty | FastResponseCapable);
 	hw_fib->header.SenderFibAddress = cpu_to_le32(fibptr->hw_fib_pa);
 	hw_fib->header.ReceiverFibAddress = cpu_to_le32(fibptr->hw_fib_pa);
-	hw_fib->header.SenderSize = cpu_to_le16(sizeof(struct hw_fib));
+	hw_fib->header.SenderSize = cpu_to_le16(fibptr->dev->max_fib_size);
 }
 
 /**
@@ -211,7 +223,7 @@ void fib_init(struct fib *fibptr)
  *	caller.
  */
  
-void fib_dealloc(struct fib * fibptr)
+static void fib_dealloc(struct fib * fibptr)
 {
 	struct hw_fib *hw_fib = fibptr->hw_fib;
 	if(hw_fib->header.StructType != FIB_MAGIC) 
@@ -279,7 +291,7 @@ static int aac_get_entry (struct aac_dev
 	}
 
         if ((*index + 1) == le32_to_cpu(*(q->headers.consumer))) { /* Queue is full */
-		printk(KERN_WARNING "Queue %d full, %d outstanding.\n",
+		printk(KERN_WARNING "Queue %d full, %u outstanding.\n",
 				qid, q->numpending);
 		return 0;
 	} else {
@@ -658,9 +670,8 @@ int fib_adapter_complete(struct fib * fi
 			}
 			if (aac_insert_entry(dev, index, AdapHighRespQueue,  (nointr & (int)aac_config.irq_mod)) != 0) {
 			}
-		}
-		else if (hw_fib->header.XferState & NormalPriority) 
-		{
+		} else if (hw_fib->header.XferState & 
+				cpu_to_le32(NormalPriority)) {
 			u32 index;
 
 			if (size) {
@@ -744,22 +755,25 @@ int fib_complete(struct fib * fibptr)
 
 void aac_printf(struct aac_dev *dev, u32 val)
 {
-	int length = val & 0xffff;
-	int level = (val >> 16) & 0xffff;
 	char *cp = dev->printfbuf;
-	
-	/*
-	 *	The size of the printfbuf is set in port.c
-	 *	There is no variable or define for it
-	 */
-	if (length > 255)
-		length = 255;
-	if (cp[length] != 0)
-		cp[length] = 0;
-	if (level == LOG_AAC_HIGH_ERROR)
-		printk(KERN_WARNING "aacraid:%s", cp);
-	else
-		printk(KERN_INFO "aacraid:%s", cp);
+	if (dev->printf_enabled)
+	{
+		int length = val & 0xffff;
+		int level = (val >> 16) & 0xffff;
+		
+		/*
+		 *	The size of the printfbuf is set in port.c
+		 *	There is no variable or define for it
+		 */
+		if (length > 255)
+			length = 255;
+		if (cp[length] != 0)
+			cp[length] = 0;
+		if (level == LOG_AAC_HIGH_ERROR)
+			printk(KERN_WARNING "aacraid:%s", cp);
+		else
+			printk(KERN_INFO "aacraid:%s", cp);
+	}
 	memset(cp, 0,  256);
 }
 
@@ -832,8 +846,8 @@ int aac_command_thread(struct aac_dev * 
 			aifcmd = (struct aac_aifcmd *) hw_fib->data;
 			if (aifcmd->command == cpu_to_le32(AifCmdDriverNotify)) {
 				/* Handle Driver Notify Events */
-				*(u32 *)hw_fib->data = cpu_to_le32(ST_OK);
-				fib_adapter_complete(fib, sizeof(u32));
+				*(__le32 *)hw_fib->data = cpu_to_le32(ST_OK);
+				fib_adapter_complete(fib, (u16)sizeof(u32));
 			} else {
 				struct list_head *entry;
 				/* The u32 here is important and intended. We are using
@@ -916,7 +930,7 @@ int aac_command_thread(struct aac_dev * 
 				/*
 				 *	Set the status of this FIB
 				 */
-				*(u32 *)hw_fib->data = cpu_to_le32(ST_OK);
+				*(__le32 *)hw_fib->data = cpu_to_le32(ST_OK);
 				fib_adapter_complete(fib, sizeof(u32));
 				spin_unlock_irqrestore(&dev->fib_lock, flagv);
 			}
diff --git a/drivers/scsi/aacraid/dpcsup.c b/drivers/scsi/aacraid/dpcsup.c
--- a/drivers/scsi/aacraid/dpcsup.c
+++ b/drivers/scsi/aacraid/dpcsup.c
@@ -99,7 +99,7 @@ unsigned int aac_response_normal(struct 
 			/*
 			 *	Doctor the fib
 			 */
-			*(u32 *)hwfib->data = cpu_to_le32(ST_OK);
+			*(__le32 *)hwfib->data = cpu_to_le32(ST_OK);
 			hwfib->header.XferState |= cpu_to_le32(AdapterProcessed);
 		}
 
@@ -107,7 +107,7 @@ unsigned int aac_response_normal(struct 
 
 		if (hwfib->header.Command == cpu_to_le16(NuFileSystem))
 		{
-			u32 *pstatus = (u32 *)hwfib->data;
+			__le32 *pstatus = (__le32 *)hwfib->data;
 			if (*pstatus & cpu_to_le32(0xffff0000))
 				*pstatus = cpu_to_le32(ST_OK);
 		}
@@ -205,7 +205,7 @@ unsigned int aac_command_normal(struct a
 			/*
 			 *	Set the status of this FIB
 			 */
-			*(u32 *)hw_fib->data = cpu_to_le32(ST_OK);
+			*(__le32 *)hw_fib->data = cpu_to_le32(ST_OK);
 			fib_adapter_complete(fib, sizeof(u32));
 			spin_lock_irqsave(q->lock, flags);
 		}		
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -102,32 +102,43 @@ static struct pci_device_id aac_pci_tbl[
 	{ 0x9005, 0x0286, 0x9005, 0x029b, 0, 0, 22 }, /* AAR-2820SA (Intruder) */
 	{ 0x9005, 0x0286, 0x9005, 0x029c, 0, 0, 23 }, /* AAR-2620SA (Intruder) */
 	{ 0x9005, 0x0286, 0x9005, 0x029d, 0, 0, 24 }, /* AAR-2420SA (Intruder) */
-	{ 0x9005, 0x0286, 0x9005, 0x0800, 0, 0, 25 }, /* Callisto Jupiter Platform */
-	{ 0x9005, 0x0285, 0x9005, 0x028e, 0, 0, 26 }, /* ASR-2020SA SATA PCI-X ZCR (Skyhawk) */
-	{ 0x9005, 0x0285, 0x9005, 0x028f, 0, 0, 27 }, /* ASR-2025SA SATA SO-DIMM PCI-X ZCR (Terminator) */
-	{ 0x9005, 0x0285, 0x9005, 0x0290, 0, 0, 28 }, /* AAR-2410SA PCI SATA 4ch (Jaguar II) */
-	{ 0x9005, 0x0285, 0x1028, 0x0291, 0, 0, 29 }, /* CERC SATA RAID 2 PCI SATA 6ch (DellCorsair) */
-	{ 0x9005, 0x0285, 0x9005, 0x0292, 0, 0, 30 }, /* AAR-2810SA PCI SATA 8ch (Corsair-8) */
-	{ 0x9005, 0x0285, 0x9005, 0x0293, 0, 0, 31 }, /* AAR-21610SA PCI SATA 16ch (Corsair-16) */
-	{ 0x9005, 0x0285, 0x9005, 0x0294, 0, 0, 32 }, /* ESD SO-DIMM PCI-X SATA ZCR (Prowler) */
-	{ 0x9005, 0x0285, 0x103C, 0x3227, 0, 0, 33 }, /* AAR-2610SA PCI SATA 6ch */
-	{ 0x9005, 0x0285, 0x9005, 0x0296, 0, 0, 34 }, /* ASR-2240S (SabreExpress) */
-	{ 0x9005, 0x0285, 0x9005, 0x0297, 0, 0, 35 }, /* ASR-4005SAS */
-	{ 0x9005, 0x0285, 0x1014, 0x02F2, 0, 0, 36 }, /* IBM 8i (AvonPark) */
-	{ 0x9005, 0x0285, 0x9005, 0x0298, 0, 0, 37 }, /* ASR-4000SAS (BlackBird) */
-	{ 0x9005, 0x0285, 0x9005, 0x0299, 0, 0, 38 }, /* ASR-4800SAS (Marauder-X) */
-	{ 0x9005, 0x0285, 0x9005, 0x029A, 0, 0, 39 }, /* ASR-4805SAS (Marauder-E) */
-
-	{ 0x9005, 0x0285, 0x1028, 0x0287, 0, 0, 40 }, /* Perc 320/DC*/
-	{ 0x1011, 0x0046, 0x9005, 0x0365, 0, 0, 41 }, /* Adaptec 5400S (Mustang)*/
-	{ 0x1011, 0x0046, 0x9005, 0x0364, 0, 0, 42 }, /* Adaptec 5400S (Mustang)*/
-	{ 0x1011, 0x0046, 0x9005, 0x1364, 0, 0, 43 }, /* Dell PERC2/QC */
-	{ 0x1011, 0x0046, 0x103c, 0x10c2, 0, 0, 44 }, /* HP NetRAID-4M */
-
-	{ 0x9005, 0x0285, 0x1028, PCI_ANY_ID, 0, 0, 45 }, /* Dell Catchall */
-	{ 0x9005, 0x0285, 0x17aa, PCI_ANY_ID, 0, 0, 46 }, /* Legend Catchall */
-	{ 0x9005, 0x0285, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 47 }, /* Adaptec Catch All */
-	{ 0x9005, 0x0286, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 48 }, /* Adaptec Rocket Catch All */
+	{ 0x9005, 0x0286, 0x9005, 0x029e, 0, 0, 25 }, /* ICP9024R0 (Lancer) */
+	{ 0x9005, 0x0286, 0x9005, 0x029f, 0, 0, 26 }, /* ICP9014R0 (Lancer) */
+	{ 0x9005, 0x0286, 0x9005, 0x02a0, 0, 0, 27 }, /* ICP9047MA (Lancer) */
+	{ 0x9005, 0x0286, 0x9005, 0x02a1, 0, 0, 28 }, /* ICP9087MA (Lancer) */
+	{ 0x9005, 0x0286, 0x9005, 0x02a3, 0, 0, 29 }, /* ICP5085AU (Hurricane) */
+	{ 0x9005, 0x0285, 0x9005, 0x02a4, 0, 0, 30 }, /* ICP9085LI (Marauder-X) */
+	{ 0x9005, 0x0285, 0x9005, 0x02a5, 0, 0, 31 }, /* ICP5085BR (Marauder-E) */
+	{ 0x9005, 0x0287, 0x9005, 0x0800, 0, 0, 32 }, /* Themisto Jupiter Platform */
+	{ 0x9005, 0x0200, 0x9005, 0x0200, 0, 0, 32 }, /* Themisto Jupiter Platform */
+	{ 0x9005, 0x0286, 0x9005, 0x0800, 0, 0, 33 }, /* Callisto Jupiter Platform */
+	{ 0x9005, 0x0285, 0x9005, 0x028e, 0, 0, 34 }, /* ASR-2020SA SATA PCI-X ZCR (Skyhawk) */
+	{ 0x9005, 0x0285, 0x9005, 0x028f, 0, 0, 35 }, /* ASR-2025SA SATA SO-DIMM PCI-X ZCR (Terminator) */
+	{ 0x9005, 0x0285, 0x9005, 0x0290, 0, 0, 36 }, /* AAR-2410SA PCI SATA 4ch (Jaguar II) */
+	{ 0x9005, 0x0285, 0x1028, 0x0291, 0, 0, 37 }, /* CERC SATA RAID 2 PCI SATA 6ch (DellCorsair) */
+	{ 0x9005, 0x0285, 0x9005, 0x0292, 0, 0, 38 }, /* AAR-2810SA PCI SATA 8ch (Corsair-8) */
+	{ 0x9005, 0x0285, 0x9005, 0x0293, 0, 0, 39 }, /* AAR-21610SA PCI SATA 16ch (Corsair-16) */
+	{ 0x9005, 0x0285, 0x9005, 0x0294, 0, 0, 40 }, /* ESD SO-DIMM PCI-X SATA ZCR (Prowler) */
+	{ 0x9005, 0x0285, 0x103C, 0x3227, 0, 0, 41 }, /* AAR-2610SA PCI SATA 6ch */
+	{ 0x9005, 0x0285, 0x9005, 0x0296, 0, 0, 42 }, /* ASR-2240S (SabreExpress) */
+	{ 0x9005, 0x0285, 0x9005, 0x0297, 0, 0, 43 }, /* ASR-4005SAS */
+	{ 0x9005, 0x0285, 0x1014, 0x02F2, 0, 0, 44 }, /* IBM 8i (AvonPark) */
+	{ 0x9005, 0x0285, 0x1014, 0x0312, 0, 0, 44 }, /* IBM 8i (AvonPark Lite) */
+	{ 0x9005, 0x0285, 0x9005, 0x0298, 0, 0, 45 }, /* ASR-4000SAS (BlackBird) */
+	{ 0x9005, 0x0285, 0x9005, 0x0299, 0, 0, 46 }, /* ASR-4800SAS (Marauder-X) */
+	{ 0x9005, 0x0285, 0x9005, 0x029a, 0, 0, 47 }, /* ASR-4805SAS (Marauder-E) */
+	{ 0x9005, 0x0286, 0x9005, 0x02a2, 0, 0, 48 }, /* ASR-4810SAS (Hurricane */
+
+	{ 0x9005, 0x0285, 0x1028, 0x0287, 0, 0, 49 }, /* Perc 320/DC*/
+	{ 0x1011, 0x0046, 0x9005, 0x0365, 0, 0, 50 }, /* Adaptec 5400S (Mustang)*/
+	{ 0x1011, 0x0046, 0x9005, 0x0364, 0, 0, 51 }, /* Adaptec 5400S (Mustang)*/
+	{ 0x1011, 0x0046, 0x9005, 0x1364, 0, 0, 52 }, /* Dell PERC2/QC */
+	{ 0x1011, 0x0046, 0x103c, 0x10c2, 0, 0, 53 }, /* HP NetRAID-4M */
+
+	{ 0x9005, 0x0285, 0x1028, PCI_ANY_ID, 0, 0, 54 }, /* Dell Catchall */
+	{ 0x9005, 0x0285, 0x17aa, PCI_ANY_ID, 0, 0, 55 }, /* Legend Catchall */
+	{ 0x9005, 0x0285, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 56 }, /* Adaptec Catch All */
+	{ 0x9005, 0x0286, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 57 }, /* Adaptec Rocket Catch All */
 	{ 0,}
 };
 MODULE_DEVICE_TABLE(pci, aac_pci_tbl);
@@ -164,6 +175,14 @@ static struct aac_driver_ident aac_drive
 	{ aac_rkt_init, "aacraid",  "ADAPTEC ", "AAR-2820SA      ", 1 }, /* AAR-2820SA (Intruder) */
 	{ aac_rkt_init, "aacraid",  "ADAPTEC ", "AAR-2620SA      ", 1 }, /* AAR-2620SA (Intruder) */
 	{ aac_rkt_init, "aacraid",  "ADAPTEC ", "AAR-2420SA      ", 1 }, /* AAR-2420SA (Intruder) */
+	{ aac_rkt_init, "aacraid",  "ICP     ", "ICP9024R0       ", 2 }, /* ICP9024R0 (Lancer) */
+	{ aac_rkt_init, "aacraid",  "ICP     ", "ICP9014R0       ", 1 }, /* ICP9014R0 (Lancer) */
+	{ aac_rkt_init, "aacraid",  "ICP     ", "ICP9047MA       ", 1 }, /* ICP9047MA (Lancer) */
+	{ aac_rkt_init, "aacraid",  "ICP     ", "ICP9087MA       ", 1 }, /* ICP9087MA (Lancer) */
+	{ aac_rkt_init, "aacraid",  "ICP     ", "ICP5085AU       ", 1 }, /* ICP5085AU (Hurricane) */
+	{ aac_rkt_init, "aacraid",  "ICP     ", "ICP9085LI       ", 1 }, /* ICP9085LI (Marauder-X) */
+	{ aac_rkt_init, "aacraid",  "ICP     ", "ICP5085BR       ", 1 }, /* ICP5085BR (Marauder-E) */
+	{ NULL        , "aacraid",  "ADAPTEC ", "Themisto        ", 0, AAC_QUIRK_SLAVE }, /* Jupiter Platform */
 	{ aac_rkt_init, "aacraid",  "ADAPTEC ", "Callisto        ", 2, AAC_QUIRK_MASTER }, /* Jupiter Platform */
 	{ aac_rx_init, "aacraid",  "ADAPTEC ", "ASR-2020SA       ", 1 }, /* ASR-2020SA SATA PCI-X ZCR (Skyhawk) */
 	{ aac_rx_init, "aacraid",  "ADAPTEC ", "ASR-2025SA       ", 1 }, /* ASR-2025SA SATA SO-DIMM PCI-X ZCR (Terminator) */
@@ -175,10 +194,11 @@ static struct aac_driver_ident aac_drive
 	{ aac_rx_init, "aacraid",  "ADAPTEC ", "AAR-2610SA      ", 1 }, /* SATA 6Ch (Bearcat) */
 	{ aac_rx_init, "aacraid",  "ADAPTEC ", "ASR-2240S       ", 1 }, /* ASR-2240S (SabreExpress) */
 	{ aac_rx_init, "aacraid",  "ADAPTEC ", "ASR-4005SAS     ", 1 }, /* ASR-4005SAS */
-	{ aac_rx_init, "aacraid",  "IBM     ", "ServeRAID 8i    ", 1 }, /* IBM 8i (AvonPark) */
+	{ aac_rx_init, "ServeRAID","IBM     ", "ServeRAID 8i    ", 1 }, /* IBM 8i (AvonPark) */
 	{ aac_rx_init, "aacraid",  "ADAPTEC ", "ASR-4000SAS     ", 1 }, /* ASR-4000SAS (BlackBird & AvonPark) */
 	{ aac_rx_init, "aacraid",  "ADAPTEC ", "ASR-4800SAS     ", 1 }, /* ASR-4800SAS (Marauder-X) */
 	{ aac_rx_init, "aacraid",  "ADAPTEC ", "ASR-4805SAS     ", 1 }, /* ASR-4805SAS (Marauder-E) */
+	{ aac_rx_init, "aacraid",  "ADAPTEC ", "ASR-4810SAS     ", 1 }, /* ASR-4810SAS (Hurricane) */
 
 	{ aac_rx_init, "percraid", "DELL    ", "PERC 320/DC     ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* Perc 320/DC*/
 	{ aac_sa_init, "aacraid",  "ADAPTEC ", "Adaptec 5400S   ", 4, AAC_QUIRK_34SG }, /* Adaptec 5400S (Mustang)*/
@@ -215,7 +235,7 @@ static int aac_queuecommand(struct scsi_
  *	Returns a static string describing the device in question
  */
 
-const char *aac_info(struct Scsi_Host *shost)
+static const char *aac_info(struct Scsi_Host *shost)
 {
 	struct aac_dev *dev = (struct aac_dev *)shost->hostdata;
 	return aac_drivers[dev->cardtype].name;
@@ -288,7 +308,7 @@ static int aac_biosparm(struct scsi_devi
 	 *	translations ( 64/32, 128/32, 255/63 ).
 	 */
 	buf = scsi_bios_ptable(bdev);
-	if(*(unsigned short *)(buf + 0x40) == cpu_to_le16(0xaa55)) {
+	if(*(__le16 *)(buf + 0x40) == cpu_to_le16(0xaa55)) {
 		struct partition *first = (struct partition * )buf;
 		struct partition *entry = first;
 		int saved_cylinders = param->cylinders;
@@ -347,10 +367,17 @@ static int aac_biosparm(struct scsi_devi
 
 static int aac_slave_configure(struct scsi_device *sdev)
 {
+	struct Scsi_Host *host = sdev->host;
+
 	if (sdev->tagged_supported)
 		scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, 128);
 	else
 		scsi_adjust_queue_depth(sdev, 0, 1);
+
+	if (!(((struct aac_dev *)host->hostdata)->adapter_info.options
+	  & AAC_OPT_NEW_COMM))
+		blk_queue_max_segment_size(sdev->request_queue, 65536);
+
 	return 0;
 }
 
@@ -361,14 +388,6 @@ static int aac_ioctl(struct scsi_device 
 }
 
 /*
- * XXX: does aac really need no error handling??
- */
-static int aac_eh_abort(struct scsi_cmnd *cmd)
-{
-	return FAILED;
-}
-
-/*
  *	aac_eh_reset	- Reset command handling
  *	@scsi_cmd:	SCSI command block causing the reset
  *
@@ -386,10 +405,13 @@ static int aac_eh_reset(struct scsi_cmnd
 					AAC_DRIVERNAME);
 
 
+	spin_lock_irq(host->host_lock);
+
 	aac = (struct aac_dev *)host->hostdata;
 	if (aac_adapter_check_health(aac)) {
 		printk(KERN_ERR "%s: Host adapter appears dead\n", 
 				AAC_DRIVERNAME);
+		spin_unlock_irq(host->host_lock);
 		return -ENODEV;
 	}
 	/*
@@ -420,6 +442,7 @@ static int aac_eh_reset(struct scsi_cmnd
 		ssleep(1);
 		spin_lock_irq(host->host_lock);
 	}
+	spin_unlock_irq(host->host_lock);
 	printk(KERN_ERR "%s: SCSI bus appears hung\n", AAC_DRIVERNAME);
 	return -ETIMEDOUT;
 }
@@ -439,11 +462,11 @@ static int aac_eh_reset(struct scsi_cmnd
 static int aac_cfg_open(struct inode *inode, struct file *file)
 {
 	struct aac_dev *aac;
-	unsigned minor = iminor(inode);
+	unsigned minor_number = iminor(inode);
 	int err = -ENODEV;
 
 	list_for_each_entry(aac, &aac_devices, entry) {
-		if (aac->id == minor) {
+		if (aac->id == minor_number) {
 			file->private_data = aac;
 			err = 0;
 			break;
@@ -489,6 +512,7 @@ static long aac_compat_do_ioctl(struct a
 	case FSACTL_DELETE_DISK:
 	case FSACTL_FORCE_DELETE_DISK:
 	case FSACTL_GET_CONTAINERS: 
+	case FSACTL_SEND_LARGE_FIB:
 		ret = aac_do_ioctl(dev, cmd, (void __user *)arg);
 		break;
 
@@ -526,6 +550,134 @@ static long aac_compat_cfg_ioctl(struct 
 }
 #endif
 
+static ssize_t aac_show_model(struct class_device *class_dev,
+		char *buf)
+{
+	struct aac_dev *dev = (struct aac_dev*)class_to_shost(class_dev)->hostdata;
+	int len;
+
+	len = snprintf(buf, PAGE_SIZE, "%s\n",
+		  aac_drivers[dev->cardtype].model);
+	return len;
+}
+
+static ssize_t aac_show_vendor(struct class_device *class_dev,
+		char *buf)
+{
+	struct aac_dev *dev = (struct aac_dev*)class_to_shost(class_dev)->hostdata;
+	int len;
+
+	len = snprintf(buf, PAGE_SIZE, "%s\n",
+		  aac_drivers[dev->cardtype].vname);
+	return len;
+}
+
+static ssize_t aac_show_kernel_version(struct class_device *class_dev,
+		char *buf)
+{
+	struct aac_dev *dev = (struct aac_dev*)class_to_shost(class_dev)->hostdata;
+	int len, tmp;
+
+	tmp = le32_to_cpu(dev->adapter_info.kernelrev);
+	len = snprintf(buf, PAGE_SIZE, "%d.%d-%d[%d]\n", 
+	  tmp >> 24, (tmp >> 16) & 0xff, tmp & 0xff,
+	  le32_to_cpu(dev->adapter_info.kernelbuild));
+	return len;
+}
+
+static ssize_t aac_show_monitor_version(struct class_device *class_dev,
+		char *buf)
+{
+	struct aac_dev *dev = (struct aac_dev*)class_to_shost(class_dev)->hostdata;
+	int len, tmp;
+
+	tmp = le32_to_cpu(dev->adapter_info.monitorrev);
+	len = snprintf(buf, PAGE_SIZE, "%d.%d-%d[%d]\n", 
+	  tmp >> 24, (tmp >> 16) & 0xff, tmp & 0xff,
+	  le32_to_cpu(dev->adapter_info.monitorbuild));
+	return len;
+}
+
+static ssize_t aac_show_bios_version(struct class_device *class_dev,
+		char *buf)
+{
+	struct aac_dev *dev = (struct aac_dev*)class_to_shost(class_dev)->hostdata;
+	int len, tmp;
+
+	tmp = le32_to_cpu(dev->adapter_info.biosrev);
+	len = snprintf(buf, PAGE_SIZE, "%d.%d-%d[%d]\n", 
+	  tmp >> 24, (tmp >> 16) & 0xff, tmp & 0xff,
+	  le32_to_cpu(dev->adapter_info.biosbuild));
+	return len;
+}
+
+static ssize_t aac_show_serial_number(struct class_device *class_dev,
+		char *buf)
+{
+	struct aac_dev *dev = (struct aac_dev*)class_to_shost(class_dev)->hostdata;
+	int len = 0;
+
+	if (le32_to_cpu(dev->adapter_info.serial[0]) != 0xBAD0)
+		len = snprintf(buf, PAGE_SIZE, "%x\n",
+		  le32_to_cpu(dev->adapter_info.serial[0]));
+	return len;
+}
+
+
+static struct class_device_attribute aac_model = {
+	.attr = {
+		.name = "model",
+		.mode = S_IRUGO,
+	},
+	.show = aac_show_model,
+};
+static struct class_device_attribute aac_vendor = {
+	.attr = {
+		.name = "vendor",
+		.mode = S_IRUGO,
+	},
+	.show = aac_show_vendor,
+};
+static struct class_device_attribute aac_kernel_version = {
+	.attr = {
+		.name = "hba_kernel_version",
+		.mode = S_IRUGO,
+	},
+	.show = aac_show_kernel_version,
+};
+static struct class_device_attribute aac_monitor_version = {
+	.attr = {
+		.name = "hba_monitor_version",
+		.mode = S_IRUGO,
+	},
+	.show = aac_show_monitor_version,
+};
+static struct class_device_attribute aac_bios_version = {
+	.attr = {
+		.name = "hba_bios_version",
+		.mode = S_IRUGO,
+	},
+	.show = aac_show_bios_version,
+};
+static struct class_device_attribute aac_serial_number = {
+	.attr = {
+		.name = "serial_number",
+		.mode = S_IRUGO,
+	},
+	.show = aac_show_serial_number,
+};
+
+static struct class_device_attribute *aac_attrs[] = {
+	&aac_model,
+	&aac_vendor,
+	&aac_kernel_version,
+	&aac_monitor_version,
+	&aac_bios_version,
+	&aac_serial_number,
+	NULL
+};
+
+
 static struct file_operations aac_cfg_fops = {
 	.owner		= THIS_MODULE,
 	.ioctl		= aac_cfg_ioctl,
@@ -538,7 +690,7 @@ static struct file_operations aac_cfg_fo
 static struct scsi_host_template aac_driver_template = {
 	.module				= THIS_MODULE,
 	.name           		= "AAC",
-	.proc_name			= "aacraid",
+	.proc_name			= AAC_DRIVERNAME,
 	.info           		= aac_info,
 	.ioctl          		= aac_ioctl,
 #ifdef CONFIG_COMPAT
@@ -546,11 +698,11 @@ static struct scsi_host_template aac_dri
 #endif
 	.queuecommand   		= aac_queuecommand,
 	.bios_param     		= aac_biosparm,	
+	.shost_attrs			= aac_attrs,
 	.slave_configure		= aac_slave_configure,
-	.eh_abort_handler		= aac_eh_abort,
 	.eh_host_reset_handler		= aac_eh_reset,
 	.can_queue      		= AAC_NUM_IO_FIB,	
-	.this_id        		= 16,
+	.this_id        		= MAXIMUM_NUM_CONTAINERS,
 	.sg_tablesize   		= 16,
 	.max_sectors    		= 128,
 #if (AAC_NUM_IO_FIB > 256)
@@ -612,7 +764,7 @@ static int __devinit aac_probe_one(struc
 	aac->cardtype =  index;
 	INIT_LIST_HEAD(&aac->entry);
 
-	aac->fibs = kmalloc(sizeof(struct fib) * AAC_NUM_FIB, GFP_KERNEL);
+	aac->fibs = kmalloc(sizeof(struct fib) * (shost->can_queue + AAC_NUM_MGT_FIB), GFP_KERNEL);
 	if (!aac->fibs)
 		goto out_free_host;
 	spin_lock_init(&aac->fib_lock);
@@ -629,15 +781,34 @@ static int __devinit aac_probe_one(struc
 		if (pci_set_dma_mask(pdev, 0xFFFFFFFFULL))
 			goto out_free_fibs;
 
+	aac->maximum_num_channels = aac_drivers[index].channels;
 	aac_get_adapter_info(aac);
 
 	/*
+ 	 * Lets override negotiations and drop the maximum SG limit to 34
+ 	 */
+ 	if ((aac_drivers[index].quirks & AAC_QUIRK_34SG) && 
+			(aac->scsi_host_ptr->sg_tablesize > 34)) {
+ 		aac->scsi_host_ptr->sg_tablesize = 34;
+ 		aac->scsi_host_ptr->max_sectors
+ 		  = (aac->scsi_host_ptr->sg_tablesize * 8) + 112;
+ 	}
+
+	/*
+	 * Firware printf works only with older firmware.
+	 */
+	if (aac_drivers[index].quirks & AAC_QUIRK_34SG) 
+		aac->printf_enabled = 1;
+	else
+		aac->printf_enabled = 0;
+ 
+ 	/*
 	 * max channel will be the physical channels plus 1 virtual channel
 	 * all containers are on the virtual channel 0
 	 * physical channels are address by their actual physical number+1
 	 */
 	if (aac->nondasd_support == 1)
-		shost->max_channel = aac_drivers[index].channels+1;
+		shost->max_channel = aac->maximum_num_channels + 1;
 	else
 		shost->max_channel = 1;
 
@@ -646,6 +817,8 @@ static int __devinit aac_probe_one(struc
 	list_add(&aac->entry, insert);
 
 	shost->max_id = aac->maximum_num_containers;
+	if (shost->max_id < aac->maximum_num_physicals)
+		shost->max_id = aac->maximum_num_physicals;
 	if (shost->max_id < MAXIMUM_NUM_CONTAINERS)
 		shost->max_id = MAXIMUM_NUM_CONTAINERS;
 	else
diff --git a/drivers/scsi/aacraid/rkt.c b/drivers/scsi/aacraid/rkt.c
--- a/drivers/scsi/aacraid/rkt.c
+++ b/drivers/scsi/aacraid/rkt.c
@@ -98,7 +98,9 @@ static irqreturn_t aac_rkt_intr(int irq,
  *	for its	completion.
  */
 
-static int rkt_sync_cmd(struct aac_dev *dev, u32 command, u32 p1, u32 *status)
+static int rkt_sync_cmd(struct aac_dev *dev, u32 command,
+	u32 p1, u32 p2, u32 p3, u32 p4, u32 p5, u32 p6,
+	u32 *status, u32 *r1, u32 *r2, u32 *r3, u32 *r4)
 {
 	unsigned long start;
 	int ok;
@@ -107,12 +109,12 @@ static int rkt_sync_cmd(struct aac_dev *
 	 */
 	rkt_writel(dev, InboundMailbox0, command);
 	/*
-	 *	Write the parameters into Mailboxes 1 - 4
+	 *	Write the parameters into Mailboxes 1 - 6
 	 */
 	rkt_writel(dev, InboundMailbox1, p1);
-	rkt_writel(dev, InboundMailbox2, 0);
-	rkt_writel(dev, InboundMailbox3, 0);
-	rkt_writel(dev, InboundMailbox4, 0);
+	rkt_writel(dev, InboundMailbox2, p2);
+	rkt_writel(dev, InboundMailbox3, p3);
+	rkt_writel(dev, InboundMailbox4, p4);
 	/*
 	 *	Clear the synch command doorbell to start on a clean slate.
 	 */
@@ -169,6 +171,14 @@ static int rkt_sync_cmd(struct aac_dev *
 	 */
 	if (status)
 		*status = rkt_readl(dev, IndexRegs.Mailbox[0]);
+	if (r1)
+		*r1 = rkt_readl(dev, IndexRegs.Mailbox[1]);
+	if (r2)
+		*r2 = rkt_readl(dev, IndexRegs.Mailbox[2]);
+	if (r3)
+		*r3 = rkt_readl(dev, IndexRegs.Mailbox[3]);
+	if (r4)
+		*r4 = rkt_readl(dev, IndexRegs.Mailbox[4]);
 	/*
 	 *	Clear the synch command doorbell.
 	 */
@@ -190,8 +200,8 @@ static int rkt_sync_cmd(struct aac_dev *
 
 static void aac_rkt_interrupt_adapter(struct aac_dev *dev)
 {
-	u32 ret;
-	rkt_sync_cmd(dev, BREAKPOINT_REQUEST, 0, &ret);
+	rkt_sync_cmd(dev, BREAKPOINT_REQUEST, 0, 0, 0, 0, 0, 0,
+	  NULL, NULL, NULL, NULL, NULL);
 }
 
 /**
@@ -220,7 +230,8 @@ static void aac_rkt_notify_adapter(struc
 		rkt_writel(dev, MUnit.IDR,INBOUNDDOORBELL_3);
 		break;
 	case HostShutdown:
-//		rkt_sync_cmd(dev, HOST_CRASHING, 0, 0, 0, 0, &ret);
+//		rkt_sync_cmd(dev, HOST_CRASHING, 0, 0, 0, 0, 0, 0,
+//		  NULL, NULL, NULL, NULL, NULL);
 		break;
 	case FastIo:
 		rkt_writel(dev, MUnit.IDR,INBOUNDDOORBELL_6);
@@ -243,17 +254,11 @@ static void aac_rkt_notify_adapter(struc
 
 static void aac_rkt_start_adapter(struct aac_dev *dev)
 {
-	u32 status;
 	struct aac_init *init;
 
 	init = dev->init;
 	init->HostElapsedSeconds = cpu_to_le32(get_seconds());
 	/*
-	 *	Tell the adapter we are back and up and running so it will scan
-	 *	its command queues and enable our interrupts
-	 */
-	dev->irq_mask = (DoorBellPrintfReady | OUTBOUNDDOORBELL_1 | OUTBOUNDDOORBELL_2 | OUTBOUNDDOORBELL_3 | OUTBOUNDDOORBELL_4);
-	/*
 	 *	First clear out all interrupts.  Then enable the one's that we
 	 *	can handle.
 	 */
@@ -263,7 +268,8 @@ static void aac_rkt_start_adapter(struct
 	rkt_writeb(dev, MUnit.OIMR, dev->OIMR = 0xfb);
 
 	// We can only use a 32 bit address here
-	rkt_sync_cmd(dev, INIT_STRUCT_BASE_ADDRESS, (u32)(ulong)dev->init_pa, &status);
+	rkt_sync_cmd(dev, INIT_STRUCT_BASE_ADDRESS, (u32)(ulong)dev->init_pa,
+	  0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL);
 }
 
 /**
@@ -288,8 +294,8 @@ static int aac_rkt_check_health(struct a
 	if (status & KERNEL_PANIC) {
 		char * buffer;
 		struct POSTSTATUS {
-			u32 Post_Command;
-			u32 Post_Address;
+			__le32 Post_Command;
+			__le32 Post_Address;
 		} * post;
 		dma_addr_t paddr, baddr;
 		int ret;
@@ -310,7 +316,8 @@ static int aac_rkt_check_health(struct a
 		post->Post_Command = cpu_to_le32(COMMAND_POST_RESULTS);
                 post->Post_Address = cpu_to_le32(baddr);
                 rkt_writel(dev, MUnit.IMRx[0], paddr);
-                rkt_sync_cmd(dev, COMMAND_POST_RESULTS, baddr, &status);
+                rkt_sync_cmd(dev, COMMAND_POST_RESULTS, baddr, 0, 0, 0, 0, 0,
+		  NULL, NULL, NULL, NULL, NULL);
 		pci_free_consistent(dev->pdev, sizeof(struct POSTSTATUS),
 		  post, paddr);
                 if ((buffer[0] == '0') && (buffer[1] == 'x')) {
diff --git a/drivers/scsi/aacraid/rx.c b/drivers/scsi/aacraid/rx.c
--- a/drivers/scsi/aacraid/rx.c
+++ b/drivers/scsi/aacraid/rx.c
@@ -63,7 +63,7 @@ static irqreturn_t aac_rx_intr(int irq, 
 	{
 		bellbits = rx_readl(dev, OutboundDoorbellReg);
 		if (bellbits & DoorBellPrintfReady) {
-			aac_printf(dev, le32_to_cpu(rx_readl (dev, IndexRegs.Mailbox[5])));
+			aac_printf(dev, rx_readl(dev, IndexRegs.Mailbox[5]));
 			rx_writel(dev, MUnit.ODR,DoorBellPrintfReady);
 			rx_writel(dev, InboundDoorbellReg,DoorBellPrintfDone);
 		}
@@ -98,7 +98,9 @@ static irqreturn_t aac_rx_intr(int irq, 
  *	for its	completion.
  */
 
-static int rx_sync_cmd(struct aac_dev *dev, u32 command, u32 p1, u32 *status)
+static int rx_sync_cmd(struct aac_dev *dev, u32 command,
+	u32 p1, u32 p2, u32 p3, u32 p4, u32 p5, u32 p6,
+	u32 *status, u32 * r1, u32 * r2, u32 * r3, u32 * r4)
 {
 	unsigned long start;
 	int ok;
@@ -107,12 +109,12 @@ static int rx_sync_cmd(struct aac_dev *d
 	 */
 	rx_writel(dev, InboundMailbox0, command);
 	/*
-	 *	Write the parameters into Mailboxes 1 - 4
+	 *	Write the parameters into Mailboxes 1 - 6
 	 */
 	rx_writel(dev, InboundMailbox1, p1);
-	rx_writel(dev, InboundMailbox2, 0);
-	rx_writel(dev, InboundMailbox3, 0);
-	rx_writel(dev, InboundMailbox4, 0);
+	rx_writel(dev, InboundMailbox2, p2);
+	rx_writel(dev, InboundMailbox3, p3);
+	rx_writel(dev, InboundMailbox4, p4);
 	/*
 	 *	Clear the synch command doorbell to start on a clean slate.
 	 */
@@ -120,7 +122,7 @@ static int rx_sync_cmd(struct aac_dev *d
 	/*
 	 *	Disable doorbell interrupts
 	 */
-	rx_writeb(dev, MUnit.OIMR, dev->OIMR |= 0x04);
+	rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xff);
 	/*
 	 *	Force the completion of the mask register write before issuing
 	 *	the interrupt.
@@ -169,6 +171,14 @@ static int rx_sync_cmd(struct aac_dev *d
 	 */
 	if (status)
 		*status = rx_readl(dev, IndexRegs.Mailbox[0]);
+	if (r1)
+		*r1 = rx_readl(dev, IndexRegs.Mailbox[1]);
+	if (r2)
+		*r2 = rx_readl(dev, IndexRegs.Mailbox[2]);
+	if (r3)
+		*r3 = rx_readl(dev, IndexRegs.Mailbox[3]);
+	if (r4)
+		*r4 = rx_readl(dev, IndexRegs.Mailbox[4]);
 	/*
 	 *	Clear the synch command doorbell.
 	 */
@@ -190,8 +200,7 @@ static int rx_sync_cmd(struct aac_dev *d
 
 static void aac_rx_interrupt_adapter(struct aac_dev *dev)
 {
-	u32 ret;
-	rx_sync_cmd(dev, BREAKPOINT_REQUEST, 0, &ret);
+	rx_sync_cmd(dev, BREAKPOINT_REQUEST, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL);
 }
 
 /**
@@ -220,7 +229,8 @@ static void aac_rx_notify_adapter(struct
 		rx_writel(dev, MUnit.IDR,INBOUNDDOORBELL_3);
 		break;
 	case HostShutdown:
-//		rx_sync_cmd(dev, HOST_CRASHING, 0, 0, 0, 0, &ret);
+//		rx_sync_cmd(dev, HOST_CRASHING, 0, 0, 0, 0, 0, 0,
+//		  NULL, NULL, NULL, NULL, NULL);
 		break;
 	case FastIo:
 		rx_writel(dev, MUnit.IDR,INBOUNDDOORBELL_6);
@@ -243,17 +253,11 @@ static void aac_rx_notify_adapter(struct
 
 static void aac_rx_start_adapter(struct aac_dev *dev)
 {
-	u32 status;
 	struct aac_init *init;
 
 	init = dev->init;
 	init->HostElapsedSeconds = cpu_to_le32(get_seconds());
 	/*
-	 *	Tell the adapter we are back and up and running so it will scan
-	 *	its command queues and enable our interrupts
-	 */
-	dev->irq_mask = (DoorBellPrintfReady | OUTBOUNDDOORBELL_1 | OUTBOUNDDOORBELL_2 | OUTBOUNDDOORBELL_3 | OUTBOUNDDOORBELL_4);
-	/*
 	 *	First clear out all interrupts.  Then enable the one's that we
 	 *	can handle.
 	 */
@@ -263,7 +267,8 @@ static void aac_rx_start_adapter(struct 
 	rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xfb);
 
 	// We can only use a 32 bit address here
-	rx_sync_cmd(dev, INIT_STRUCT_BASE_ADDRESS, (u32)(ulong)dev->init_pa, &status);
+	rx_sync_cmd(dev, INIT_STRUCT_BASE_ADDRESS, (u32)(ulong)dev->init_pa,
+	  0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL);
 }
 
 /**
@@ -288,8 +293,8 @@ static int aac_rx_check_health(struct aa
 	if (status & KERNEL_PANIC) {
 		char * buffer;
 		struct POSTSTATUS {
-			u32 Post_Command;
-			u32 Post_Address;
+			__le32 Post_Command;
+			__le32 Post_Address;
 		} * post;
 		dma_addr_t paddr, baddr;
 		int ret;
@@ -310,7 +315,8 @@ static int aac_rx_check_health(struct aa
 		post->Post_Command = cpu_to_le32(COMMAND_POST_RESULTS);
 		post->Post_Address = cpu_to_le32(baddr);
 		rx_writel(dev, MUnit.IMRx[0], paddr);
-		rx_sync_cmd(dev, COMMAND_POST_RESULTS, baddr, &status);
+		rx_sync_cmd(dev, COMMAND_POST_RESULTS, baddr, 0, 0, 0, 0, 0,
+		  NULL, NULL, NULL, NULL, NULL);
 		pci_free_consistent(dev->pdev, sizeof(struct POSTSTATUS),
 		  post, paddr);
 		if ((buffer[0] == '0') && (buffer[1] == 'x')) {
diff --git a/drivers/scsi/aacraid/sa.c b/drivers/scsi/aacraid/sa.c
--- a/drivers/scsi/aacraid/sa.c
+++ b/drivers/scsi/aacraid/sa.c
@@ -89,7 +89,7 @@ static irqreturn_t aac_sa_intr(int irq, 
  *	Notify the adapter of an event
  */
  
-void aac_sa_notify_adapter(struct aac_dev *dev, u32 event)
+static void aac_sa_notify_adapter(struct aac_dev *dev, u32 event)
 {
 	switch (event) {
 
@@ -106,7 +106,10 @@ void aac_sa_notify_adapter(struct aac_de
 		sa_writew(dev, DoorbellReg_s,DOORBELL_3);
 		break;
 	case HostShutdown:
-		//sa_sync_cmd(dev, HOST_CRASHING, 0, &ret);
+		/*
+		sa_sync_cmd(dev, HOST_CRASHING, 0, 0, 0, 0, 0, 0,
+		NULL, NULL, NULL, NULL, NULL);
+		*/
 		break;
 	case FastIo:
 		sa_writew(dev, DoorbellReg_s,DOORBELL_6);
@@ -132,7 +135,9 @@ void aac_sa_notify_adapter(struct aac_de
  *	for its	completion.
  */
 
-static int sa_sync_cmd(struct aac_dev *dev, u32 command, u32 p1, u32 *ret)
+static int sa_sync_cmd(struct aac_dev *dev, u32 command, 
+		u32 p1, u32 p2, u32 p3, u32 p4, u32 p5, u32 p6,
+		u32 *ret, u32 *r1, u32 *r2, u32 *r3, u32 *r4)
 {
 	unsigned long start;
  	int ok;
@@ -144,9 +149,10 @@ static int sa_sync_cmd(struct aac_dev *d
 	 *	Write the parameters into Mailboxes 1 - 4
 	 */
 	sa_writel(dev, Mailbox1, p1);
-	sa_writel(dev, Mailbox2, 0);
-	sa_writel(dev, Mailbox3, 0);
-	sa_writel(dev, Mailbox4, 0);
+	sa_writel(dev, Mailbox2, p2);
+	sa_writel(dev, Mailbox3, p3);
+	sa_writel(dev, Mailbox4, p4);
+
 	/*
 	 *	Clear the synch command doorbell to start on a clean slate.
 	 */
@@ -188,6 +194,14 @@ static int sa_sync_cmd(struct aac_dev *d
 	 */
 	if (ret)
 		*ret = sa_readl(dev, Mailbox0);
+	if (r1)
+		*r1 = sa_readl(dev, Mailbox1);
+	if (r2)
+		*r2 = sa_readl(dev, Mailbox2);
+	if (r3)
+		*r3 = sa_readl(dev, Mailbox3);
+	if (r4)
+		*r4 = sa_readl(dev, Mailbox4);
 	return 0;
 }
 
@@ -201,7 +215,8 @@ static int sa_sync_cmd(struct aac_dev *d
 static void aac_sa_interrupt_adapter (struct aac_dev *dev)
 {
 	u32 ret;
-	sa_sync_cmd(dev, BREAKPOINT_REQUEST, 0, &ret);
+	sa_sync_cmd(dev, BREAKPOINT_REQUEST, 0, 0, 0, 0, 0, 0,
+			&ret, NULL, NULL, NULL, NULL);
 }
 
 /**
@@ -230,10 +245,12 @@ static void aac_sa_start_adapter(struct 
 	 *	First clear out all interrupts.  Then enable the one's that 
 	 *	we can handle.
 	 */
-	sa_writew(dev, SaDbCSR.PRISETIRQMASK, cpu_to_le16(0xffff));
+	sa_writew(dev, SaDbCSR.PRISETIRQMASK, 0xffff);
 	sa_writew(dev, SaDbCSR.PRICLEARIRQMASK, (PrintfReady | DOORBELL_1 | DOORBELL_2 | DOORBELL_3 | DOORBELL_4));
 	/* We can only use a 32 bit address here */
-	sa_sync_cmd(dev, INIT_STRUCT_BASE_ADDRESS, (u32)(ulong)dev->init_pa, &ret);
+	sa_sync_cmd(dev, INIT_STRUCT_BASE_ADDRESS, 
+			(u32)(ulong)dev->init_pa, 0, 0, 0, 0, 0,
+			&ret, NULL, NULL, NULL, NULL);
 }
 
 /**
diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c
--- a/drivers/scsi/advansys.c
+++ b/drivers/scsi/advansys.c
@@ -4556,8 +4556,6 @@ advansys_detect(struct scsi_host_templat
                 continue;
             }
 
-	    scsi_set_device(shp, dev);
-
             /* Save a pointer to the Scsi_Host of each board found. */
             asc_host[asc_board_count++] = shp;
 
@@ -9194,8 +9192,8 @@ asc_prt_scsi_cmnd(struct scsi_cmnd *s)
         s->sc_data_direction, s->resid);
 
     printk(
-" use_sg %u, sglist_len %u, abort_reason 0x%x\n",
-        s->use_sg, s->sglist_len, s->abort_reason);
+" use_sg %u, sglist_len %u\n",
+        s->use_sg, s->sglist_len);
 
     printk(
 " serial_number 0x%x, retries %d, allowed %d\n",
diff --git a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c
--- a/drivers/scsi/aha152x.c
+++ b/drivers/scsi/aha152x.c
@@ -1225,8 +1225,6 @@ static int aha152x_device_reset(Scsi_Cmn
 	}
 
 	DO_UNLOCK(flags);
-
-	spin_lock_irq(shpnt->host_lock);
 	return ret;
 }
 
diff --git a/drivers/scsi/aha1542.c b/drivers/scsi/aha1542.c
--- a/drivers/scsi/aha1542.c
+++ b/drivers/scsi/aha1542.c
@@ -1348,20 +1348,6 @@ static int aha1542_restart(struct Scsi_H
 	return 0;
 }
 
-static int aha1542_abort(Scsi_Cmnd * SCpnt)
-{
-
-	/*
-	 * The abort command does not leave the device in a clean state where
-	 *  it is available to be used again.  Until this gets worked out, we
-	 * will leave it commented out.  
-	 */
-
-	printk(KERN_ERR "aha1542.c: Unable to abort command for target %d\n",
-	       SCpnt->device->id);
-	return FAILED;
-}
-
 /*
  * This is a device reset.  This is handled by sending a special command
  * to the device.
@@ -1478,8 +1464,8 @@ static int aha1542_bus_reset(Scsi_Cmnd *
 	 * check for timeout, and if we are doing something like this
 	 * we are pretty desperate anyways.
 	 */
-	spin_unlock_irq(SCpnt->device->host->host_lock);
 	ssleep(4);
+
 	spin_lock_irq(SCpnt->device->host->host_lock);
 
 	WAIT(STATUS(SCpnt->device->host->io_port),
@@ -1517,9 +1503,11 @@ static int aha1542_bus_reset(Scsi_Cmnd *
 		}
 	}
 
+	spin_unlock_irq(SCpnt->device->host->host_lock);
 	return SUCCESS;
 
 fail:
+	spin_unlock_irq(SCpnt->device->host->host_lock);
 	return FAILED;
 }
 
@@ -1542,7 +1530,6 @@ static int aha1542_host_reset(Scsi_Cmnd 
 	 * check for timeout, and if we are doing something like this
 	 * we are pretty desperate anyways.
 	 */
-	spin_unlock_irq(SCpnt->device->host->host_lock);
 	ssleep(4);
 	spin_lock_irq(SCpnt->device->host->host_lock);
 
@@ -1586,9 +1573,11 @@ static int aha1542_host_reset(Scsi_Cmnd 
 		}
 	}
 
+	spin_unlock_irq(SCpnt->device->host->host_lock);
 	return SUCCESS;
 
 fail:
+	spin_unlock_irq(SCpnt->device->host->host_lock);
 	return FAILED;
 }
 
@@ -1817,7 +1806,6 @@ static Scsi_Host_Template driver_templat
 	.detect			= aha1542_detect,
 	.release		= aha1542_release,
 	.queuecommand		= aha1542_queuecommand,
-	.eh_abort_handler	= aha1542_abort,
 	.eh_device_reset_handler= aha1542_dev_reset,
 	.eh_bus_reset_handler	= aha1542_bus_reset,
 	.eh_host_reset_handler	= aha1542_host_reset,
diff --git a/drivers/scsi/aha1542.h b/drivers/scsi/aha1542.h
--- a/drivers/scsi/aha1542.h
+++ b/drivers/scsi/aha1542.h
@@ -133,7 +133,6 @@ struct ccb {			/* Command Control Block 
 
 static int aha1542_detect(Scsi_Host_Template *);
 static int aha1542_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
-static int aha1542_abort(Scsi_Cmnd * SCpnt);
 static int aha1542_bus_reset(Scsi_Cmnd * SCpnt);
 static int aha1542_dev_reset(Scsi_Cmnd * SCpnt);
 static int aha1542_host_reset(Scsi_Cmnd * SCpnt);
diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c
--- a/drivers/scsi/ahci.c
+++ b/drivers/scsi/ahci.c
@@ -39,7 +39,7 @@
 #include <asm/io.h>
 
 #define DRV_NAME	"ahci"
-#define DRV_VERSION	"1.00"
+#define DRV_VERSION	"1.01"
 
 
 enum {
@@ -50,6 +50,7 @@ enum {
 	AHCI_CMD_SLOT_SZ	= 32 * 32,
 	AHCI_RX_FIS_SZ		= 256,
 	AHCI_CMD_TBL_HDR	= 0x80,
+	AHCI_CMD_TBL_CDB	= 0x40,
 	AHCI_CMD_TBL_SZ		= AHCI_CMD_TBL_HDR + (AHCI_MAX_SG * 16),
 	AHCI_PORT_PRIV_DMA_SZ	= AHCI_CMD_SLOT_SZ + AHCI_CMD_TBL_SZ +
 				  AHCI_RX_FIS_SZ,
@@ -134,6 +135,9 @@ enum {
 	PORT_CMD_ICC_ACTIVE	= (0x1 << 28), /* Put i/f in active state */
 	PORT_CMD_ICC_PARTIAL	= (0x2 << 28), /* Put i/f in partial state */
 	PORT_CMD_ICC_SLUMBER	= (0x6 << 28), /* Put i/f in slumber state */
+
+	/* hpriv->flags bits */
+	AHCI_FLAG_MSI		= (1 << 0),
 };
 
 struct ahci_cmd_hdr {
@@ -183,6 +187,7 @@ static void ahci_qc_prep(struct ata_queu
 static u8 ahci_check_status(struct ata_port *ap);
 static u8 ahci_check_err(struct ata_port *ap);
 static inline int ahci_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc);
+static void ahci_remove_one (struct pci_dev *pdev);
 
 static Scsi_Host_Template ahci_sht = {
 	.module			= THIS_MODULE,
@@ -272,7 +277,7 @@ static struct pci_driver ahci_pci_driver
 	.name			= DRV_NAME,
 	.id_table		= ahci_pci_tbl,
 	.probe			= ahci_init_one,
-	.remove			= ata_pci_remove_one,
+	.remove			= ahci_remove_one,
 };
 
 
@@ -299,26 +304,19 @@ static int ahci_port_start(struct ata_po
 	struct device *dev = ap->host_set->dev;
 	struct ahci_host_priv *hpriv = ap->host_set->private_data;
 	struct ahci_port_priv *pp;
-	int rc;
 	void *mem, *mmio = ap->host_set->mmio_base;
 	void *port_mmio = ahci_port_base(mmio, ap->port_no);
 	dma_addr_t mem_dma;
 
-	rc = ata_port_start(ap);
-	if (rc)
-		return rc;
-
 	pp = kmalloc(sizeof(*pp), GFP_KERNEL);
-	if (!pp) {
-		rc = -ENOMEM;
-		goto err_out;
-	}
+	if (!pp)
+		return -ENOMEM;
 	memset(pp, 0, sizeof(*pp));
 
 	mem = dma_alloc_coherent(dev, AHCI_PORT_PRIV_DMA_SZ, &mem_dma, GFP_KERNEL);
 	if (!mem) {
-		rc = -ENOMEM;
-		goto err_out_kfree;
+		kfree(pp);
+		return -ENOMEM;
 	}
 	memset(mem, 0, AHCI_PORT_PRIV_DMA_SZ);
 
@@ -368,12 +366,6 @@ static int ahci_port_start(struct ata_po
 	readl(port_mmio + PORT_CMD); /* flush */
 
 	return 0;
-
-err_out_kfree:
-	kfree(pp);
-err_out:
-	ata_port_stop(ap);
-	return rc;
 }
 
 
@@ -399,7 +391,6 @@ static void ahci_port_stop(struct ata_po
 	dma_free_coherent(dev, AHCI_PORT_PRIV_DMA_SZ,
 			  pp->cmd_slot, pp->cmd_slot_dma);
 	kfree(pp);
-	ata_port_stop(ap);
 }
 
 static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg_in)
@@ -506,7 +497,8 @@ static void ahci_fill_sg(struct ata_queu
 
 static void ahci_qc_prep(struct ata_queued_cmd *qc)
 {
-	struct ahci_port_priv *pp = qc->ap->private_data;
+	struct ata_port *ap = qc->ap;
+	struct ahci_port_priv *pp = ap->private_data;
 	u32 opts;
 	const u32 cmd_fis_len = 5; /* five dwords */
 
@@ -518,18 +510,8 @@ static void ahci_qc_prep(struct ata_queu
 	opts = (qc->n_elem << 16) | cmd_fis_len;
 	if (qc->tf.flags & ATA_TFLAG_WRITE)
 		opts |= AHCI_CMD_WRITE;
-
-	switch (qc->tf.protocol) {
-	case ATA_PROT_ATAPI:
-	case ATA_PROT_ATAPI_NODATA:
-	case ATA_PROT_ATAPI_DMA:
+	if (is_atapi_taskfile(&qc->tf))
 		opts |= AHCI_CMD_ATAPI;
-		break;
-
-	default:
-		/* do nothing */
-		break;
-	}
 
 	pp->cmd_slot[0].opts = cpu_to_le32(opts);
 	pp->cmd_slot[0].status = 0;
@@ -541,6 +523,10 @@ static void ahci_qc_prep(struct ata_queu
 	 * a SATA Register - Host to Device command FIS.
 	 */
 	ata_tf_to_fis(&qc->tf, pp->cmd_tbl, 0);
+	if (opts & AHCI_CMD_ATAPI) {
+		memset(pp->cmd_tbl + AHCI_CMD_TBL_CDB, 0, 32);
+		memcpy(pp->cmd_tbl + AHCI_CMD_TBL_CDB, qc->cdb, ap->cdb_len);
+	}
 
 	if (!(qc->flags & ATA_QCFLAG_DMAMAP))
 		return;
@@ -795,8 +781,6 @@ static int ahci_host_init(struct ata_pro
 				return rc;
 			}
 		}
-
-		hpriv->flags |= HOST_CAP_64;
 	} else {
 		rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
 		if (rc) {
@@ -879,15 +863,19 @@ static int ahci_host_init(struct ata_pro
 }
 
 /* move to PCI layer, integrate w/ MSI stuff */
-static void pci_enable_intx(struct pci_dev *pdev)
+static void pci_intx(struct pci_dev *pdev, int enable)
 {
-	u16 pci_command;
+	u16 pci_command, new;
 
 	pci_read_config_word(pdev, PCI_COMMAND, &pci_command);
-	if (pci_command & PCI_COMMAND_INTX_DISABLE) {
-		pci_command &= ~PCI_COMMAND_INTX_DISABLE;
+
+	if (enable)
+		new = pci_command & ~PCI_COMMAND_INTX_DISABLE;
+	else
+		new = pci_command | PCI_COMMAND_INTX_DISABLE;
+
+	if (new != pci_command)
 		pci_write_config_word(pdev, PCI_COMMAND, pci_command);
-	}
 }
 
 static void ahci_print_info(struct ata_probe_ent *probe_ent)
@@ -969,7 +957,7 @@ static int ahci_init_one (struct pci_dev
 	unsigned long base;
 	void *mmio_base;
 	unsigned int board_idx = (unsigned int) ent->driver_data;
-	int pci_dev_busy = 0;
+	int have_msi, pci_dev_busy = 0;
 	int rc;
 
 	VPRINTK("ENTER\n");
@@ -987,12 +975,17 @@ static int ahci_init_one (struct pci_dev
 		goto err_out;
 	}
 
-	pci_enable_intx(pdev);
+	if (pci_enable_msi(pdev) == 0)
+		have_msi = 1;
+	else {
+		pci_intx(pdev, 1);
+		have_msi = 0;
+	}
 
 	probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL);
 	if (probe_ent == NULL) {
 		rc = -ENOMEM;
-		goto err_out_regions;
+		goto err_out_msi;
 	}
 
 	memset(probe_ent, 0, sizeof(*probe_ent));
@@ -1025,6 +1018,9 @@ static int ahci_init_one (struct pci_dev
 	probe_ent->mmio_base = mmio_base;
 	probe_ent->private_data = hpriv;
 
+	if (have_msi)
+		hpriv->flags |= AHCI_FLAG_MSI;
+
 	/* initialize adapter */
 	rc = ahci_host_init(probe_ent);
 	if (rc)
@@ -1044,7 +1040,11 @@ err_out_iounmap:
 	iounmap(mmio_base);
 err_out_free_ent:
 	kfree(probe_ent);
-err_out_regions:
+err_out_msi:
+	if (have_msi)
+		pci_disable_msi(pdev);
+	else
+		pci_intx(pdev, 0);
 	pci_release_regions(pdev);
 err_out:
 	if (!pci_dev_busy)
@@ -1052,6 +1052,42 @@ err_out:
 	return rc;
 }
 
+static void ahci_remove_one (struct pci_dev *pdev)
+{
+	struct device *dev = pci_dev_to_dev(pdev);
+	struct ata_host_set *host_set = dev_get_drvdata(dev);
+	struct ahci_host_priv *hpriv = host_set->private_data;
+	struct ata_port *ap;
+	unsigned int i;
+	int have_msi;
+
+	for (i = 0; i < host_set->n_ports; i++) {
+		ap = host_set->ports[i];
+
+		scsi_remove_host(ap->host);
+	}
+
+	have_msi = hpriv->flags & AHCI_FLAG_MSI;
+	free_irq(host_set->irq, host_set);
+
+	for (i = 0; i < host_set->n_ports; i++) {
+		ap = host_set->ports[i];
+
+		ata_scsi_release(ap->host);
+		scsi_host_put(ap->host);
+	}
+
+	host_set->ops->host_stop(host_set);
+	kfree(host_set);
+
+	if (have_msi)
+		pci_disable_msi(pdev);
+	else
+		pci_intx(pdev, 0);
+	pci_release_regions(pdev);
+	pci_disable_device(pdev);
+	dev_set_drvdata(dev, NULL);
+}
 
 static int __init ahci_init(void)
 {
@@ -1069,6 +1105,7 @@ MODULE_AUTHOR("Jeff Garzik");
 MODULE_DESCRIPTION("AHCI SATA low-level driver");
 MODULE_LICENSE("GPL");
 MODULE_DEVICE_TABLE(pci, ahci_pci_tbl);
+MODULE_VERSION(DRV_VERSION);
 
 module_init(ahci_init);
 module_exit(ahci_exit);
diff --git a/drivers/scsi/aic7xxx/aic7770.c b/drivers/scsi/aic7xxx/aic7770.c
--- a/drivers/scsi/aic7xxx/aic7770.c
+++ b/drivers/scsi/aic7xxx/aic7770.c
@@ -254,19 +254,12 @@ aic7770_config(struct ahc_softc *ahc, st
 	if (error != 0)
 		return (error);
 
-	ahc_list_lock(&l);
-	/*
-	 * Link this softc in with all other ahc instances.
-	 */
-	ahc_softc_insert(ahc);
+	ahc->init_level++;
 
 	/*
 	 * Enable the board's BUS drivers
 	 */
 	ahc_outb(ahc, BCTL, ENABLE);
-
-	ahc_list_unlock(&l);
-
 	return (0);
 }
 
diff --git a/drivers/scsi/aic7xxx/aic7770_osm.c b/drivers/scsi/aic7xxx/aic7770_osm.c
--- a/drivers/scsi/aic7xxx/aic7770_osm.c
+++ b/drivers/scsi/aic7xxx/aic7770_osm.c
@@ -44,109 +44,6 @@
 #include <linux/device.h>
 #include <linux/eisa.h>
 
-#define EISA_MFCTR_CHAR0(ID) (char)(((ID>>26) & 0x1F) | '@')  /* Bits 26-30 */
-#define EISA_MFCTR_CHAR1(ID) (char)(((ID>>21) & 0x1F) | '@')  /* Bits 21-25 */
-#define EISA_MFCTR_CHAR2(ID) (char)(((ID>>16) & 0x1F) | '@')  /* Bits 16-20 */
-#define EISA_PRODUCT_ID(ID)  (short)((ID>>4)  & 0xFFF)        /* Bits  4-15 */
-#define EISA_REVISION_ID(ID) (uint8_t)(ID & 0x0F)             /* Bits  0-3  */
-
-static int aic7770_eisa_dev_probe(struct device *dev);
-static int aic7770_eisa_dev_remove(struct device *dev);
-static struct eisa_driver aic7770_driver = {
-	.driver = {
-		.name   = "aic7xxx",
-		.probe  = aic7770_eisa_dev_probe,
-		.remove = aic7770_eisa_dev_remove,
-	}
-};
-
-typedef  struct device *aic7770_dev_t;
-
-static int aic7770_linux_config(struct aic7770_identity *entry,
-				aic7770_dev_t dev, u_int eisaBase);
-
-int
-ahc_linux_eisa_init(void)
-{
-	struct eisa_device_id *eid;
-	struct aic7770_identity *id;
-	int i;
-
-	if (aic7xxx_probe_eisa_vl == 0)
-		return -ENODEV;
-
-	/*
-	 * Linux requires the EISA IDs to be specified in
-	 * the EISA ID string format.  Perform the conversion
-	 * and setup a table with a NUL terminal entry.
-	 */
-	aic7770_driver.id_table = malloc(sizeof(struct eisa_device_id) *
-					 (ahc_num_aic7770_devs + 1),
-					 M_DEVBUF, M_NOWAIT);
-	if (aic7770_driver.id_table == NULL)
-		return -ENOMEM;
-
-	for (eid = (struct eisa_device_id *)aic7770_driver.id_table,
-	     id = aic7770_ident_table, i = 0;
-	     i < ahc_num_aic7770_devs; eid++, id++, i++) {
-
-		sprintf(eid->sig, "%c%c%c%03X%01X",
-			EISA_MFCTR_CHAR0(id->full_id),
-			EISA_MFCTR_CHAR1(id->full_id),
-			EISA_MFCTR_CHAR2(id->full_id),
-			EISA_PRODUCT_ID(id->full_id),
-			EISA_REVISION_ID(id->full_id));
-		eid->driver_data = i;
-	}
-	eid->sig[0] = 0;
-
-	return eisa_driver_register(&aic7770_driver);
-}
-
-void
-ahc_linux_eisa_exit(void)
-{
-	if(aic7xxx_probe_eisa_vl != 0 && aic7770_driver.id_table != NULL) {
-		eisa_driver_unregister(&aic7770_driver);
-		free(aic7770_driver.id_table, M_DEVBUF);
-	}
-}
-
-static int
-aic7770_linux_config(struct aic7770_identity *entry, aic7770_dev_t dev,
-		     u_int eisaBase)
-{
-	struct	ahc_softc *ahc;
-	char	buf[80];
-	char   *name;
-	int	error;
-
-	/*
-	 * Allocate a softc for this card and
-	 * set it up for attachment by our
-	 * common detect routine.
-	 */
-	sprintf(buf, "ahc_eisa:%d", eisaBase >> 12);
-	name = malloc(strlen(buf) + 1, M_DEVBUF, M_NOWAIT);
-	if (name == NULL)
-		return (ENOMEM);
-	strcpy(name, buf);
-	ahc = ahc_alloc(&aic7xxx_driver_template, name);
-	if (ahc == NULL)
-		return (ENOMEM);
-	error = aic7770_config(ahc, entry, eisaBase);
-	if (error != 0) {
-		ahc->bsh.ioport = 0;
-		ahc_free(ahc);
-		return (error);
-	}
-
-	dev->driver_data = (void *)ahc;
-	if (aic7xxx_detect_complete)
-		error = ahc_linux_register_host(ahc, &aic7xxx_driver_template);
-	return (error);
-}
-
 int
 aic7770_map_registers(struct ahc_softc *ahc, u_int port)
 {
@@ -178,37 +75,78 @@ aic7770_map_int(struct ahc_softc *ahc, u
 }
 
 static int
-aic7770_eisa_dev_probe(struct device *dev)
+aic7770_probe(struct device *dev)
 {
-	struct eisa_device *edev;
+	struct eisa_device *edev = to_eisa_device(dev);
+	u_int eisaBase = edev->base_addr+AHC_EISA_SLOT_OFFSET;
+	struct	ahc_softc *ahc;
+	char	buf[80];
+	char   *name;
+	int	error;
 
-	edev = to_eisa_device(dev);
-	return (aic7770_linux_config(aic7770_ident_table + edev->id.driver_data,
-				    dev, edev->base_addr+AHC_EISA_SLOT_OFFSET));
+	sprintf(buf, "ahc_eisa:%d", eisaBase >> 12);
+	name = malloc(strlen(buf) + 1, M_DEVBUF, M_NOWAIT);
+	if (name == NULL)
+		return (ENOMEM);
+	strcpy(name, buf);
+	ahc = ahc_alloc(&aic7xxx_driver_template, name);
+	if (ahc == NULL)
+		return (ENOMEM);
+	error = aic7770_config(ahc, aic7770_ident_table + edev->id.driver_data,
+			       eisaBase);
+	if (error != 0) {
+		ahc->bsh.ioport = 0;
+		ahc_free(ahc);
+		return (error);
+	}
+
+ 	dev_set_drvdata(dev, ahc);
+
+	error = ahc_linux_register_host(ahc, &aic7xxx_driver_template);
+	return (error);
 }
 
 static int
-aic7770_eisa_dev_remove(struct device *dev)
+aic7770_remove(struct device *dev)
 {
-	struct ahc_softc *ahc;
-	u_long l;
+	struct ahc_softc *ahc = dev_get_drvdata(dev);
+	u_long s;
 
-	/*
-	 * We should be able to just perform
-	 * the free directly, but check our
-	 * list for extra sanity.
-	 */
-	ahc_list_lock(&l);
-	ahc = ahc_find_softc((struct ahc_softc *)dev->driver_data);
-	if (ahc != NULL) {
-		u_long s;
-
-		ahc_lock(ahc, &s);
-		ahc_intr_enable(ahc, FALSE);
-		ahc_unlock(ahc, &s);
-		ahc_free(ahc);
+	ahc_lock(ahc, &s);
+	ahc_intr_enable(ahc, FALSE);
+	ahc_unlock(ahc, &s);
+
+	ahc_free(ahc);
+	return 0;
+}
+ 
+static struct eisa_device_id aic7770_ids[] = {
+	{ "ADP7771", 0 }, /* AHA 274x */
+	{ "ADP7756", 1 }, /* AHA 284x BIOS enabled */
+	{ "ADP7757", 2 }, /* AHA 284x BIOS disabled */
+	{ "ADP7782", 3 }, /* AHA 274x Olivetti OEM */
+	{ "ADP7783", 4 }, /* AHA 274x Olivetti OEM (Differential) */
+	{ "ADP7770", 5 }, /* AIC7770 generic */
+	{ "" }
+};
+  
+static struct eisa_driver aic7770_driver = {
+	.id_table	= aic7770_ids,
+	.driver = {
+		.name   = "aic7xxx",
+		.probe  = aic7770_probe,
+		.remove = aic7770_remove,
 	}
-	ahc_list_unlock(&l);
-
-	return (0);
+};
+  
+int
+ahc_linux_eisa_init(void)
+{
+	return eisa_driver_register(&aic7770_driver);
+}
+  
+void
+ahc_linux_eisa_exit(void)
+{
+	eisa_driver_unregister(&aic7770_driver);
 }
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c
--- a/drivers/scsi/aic7xxx/aic79xx_osm.c
+++ b/drivers/scsi/aic7xxx/aic79xx_osm.c
@@ -1505,23 +1505,23 @@ ahd_linux_dev_reset(Scsi_Cmnd *cmd)
 	memset(recovery_cmd, 0, sizeof(struct scsi_cmnd));
 	recovery_cmd->device = cmd->device;
 	recovery_cmd->scsi_done = ahd_linux_dev_reset_complete;
-#if AHD_DEBUG
+#ifdef AHD_DEBUG
 	if ((ahd_debug & AHD_SHOW_RECOVERY) != 0)
 		printf("%s:%d:%d:%d: Device reset called for cmd %p\n",
 		       ahd_name(ahd), cmd->device->channel, cmd->device->id,
 		       cmd->device->lun, cmd);
 #endif
-	ahd_midlayer_entrypoint_lock(ahd, &s);
+	ahd_lock(ahd, &s);
 
 	dev = ahd_linux_get_device(ahd, cmd->device->channel, cmd->device->id,
 				   cmd->device->lun, /*alloc*/FALSE);
 	if (dev == NULL) {
-		ahd_midlayer_entrypoint_unlock(ahd, &s);
+		ahd_unlock(ahd, &s);
 		kfree(recovery_cmd);
 		return (FAILED);
 	}
 	if ((scb = ahd_get_scb(ahd, AHD_NEVER_COL_IDX)) == NULL) {
-		ahd_midlayer_entrypoint_unlock(ahd, &s);
+		ahd_unlock(ahd, &s);
 		kfree(recovery_cmd);
 		return (FAILED);
 	}
@@ -1553,7 +1553,7 @@ ahd_linux_dev_reset(Scsi_Cmnd *cmd)
 	ahd_queue_scb(ahd, scb);
 
 	scb->platform_data->flags |= AHD_SCB_UP_EH_SEM;
-	spin_unlock_irq(&ahd->platform_data->spin_lock);
+	ahd_unlock(ahd, &s);
 	init_timer(&timer);
 	timer.data = (u_long)scb;
 	timer.expires = jiffies + (5 * HZ);
@@ -1567,10 +1567,10 @@ ahd_linux_dev_reset(Scsi_Cmnd *cmd)
 		printf("Timer Expired\n");
 		retval = FAILED;
 	}
-	spin_lock_irq(&ahd->platform_data->spin_lock);
+	ahd_lock(ahd, &s);
 	ahd_schedule_runq(ahd);
 	ahd_linux_run_complete_queue(ahd);
-	ahd_midlayer_entrypoint_unlock(ahd, &s);
+	ahd_unlock(ahd, &s);
 	printf("%s: Device reset returning 0x%x\n", ahd_name(ahd), retval);
 	return (retval);
 }
@@ -1591,11 +1591,11 @@ ahd_linux_bus_reset(Scsi_Cmnd *cmd)
 		printf("%s: Bus reset called for cmd %p\n",
 		       ahd_name(ahd), cmd);
 #endif
-	ahd_midlayer_entrypoint_lock(ahd, &s);
+	ahd_lock(ahd, &s);
 	found = ahd_reset_channel(ahd, cmd->device->channel + 'A',
 				  /*initiate reset*/TRUE);
 	ahd_linux_run_complete_queue(ahd);
-	ahd_midlayer_entrypoint_unlock(ahd, &s);
+	ahd_unlock(ahd, &s);
 
 	if (bootverbose)
 		printf("%s: SCSI bus reset delivered. "
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.h b/drivers/scsi/aic7xxx/aic79xx_osm.h
--- a/drivers/scsi/aic7xxx/aic79xx_osm.h
+++ b/drivers/scsi/aic7xxx/aic79xx_osm.h
@@ -112,23 +112,6 @@ typedef Scsi_Cmnd      *ahd_io_ctx_t;
 #define ahd_le32toh(x)	le32_to_cpu(x)
 #define ahd_le64toh(x)	le64_to_cpu(x)
 
-#ifndef LITTLE_ENDIAN
-#define LITTLE_ENDIAN 1234
-#endif
-
-#ifndef BIG_ENDIAN
-#define BIG_ENDIAN 4321
-#endif
-
-#ifndef BYTE_ORDER
-#if defined(__BIG_ENDIAN)
-#define BYTE_ORDER BIG_ENDIAN
-#endif
-#if defined(__LITTLE_ENDIAN)
-#define BYTE_ORDER LITTLE_ENDIAN
-#endif
-#endif /* BYTE_ORDER */
-
 /************************* Configuration Data *********************************/
 extern uint32_t aic79xx_allow_memio;
 extern int aic79xx_detect_complete;
diff --git a/drivers/scsi/aic7xxx/aic79xx_pci.c b/drivers/scsi/aic7xxx/aic79xx_pci.c
--- a/drivers/scsi/aic7xxx/aic79xx_pci.c
+++ b/drivers/scsi/aic7xxx/aic79xx_pci.c
@@ -582,7 +582,7 @@ ahd_check_extport(struct ahd_softc *ahd)
 		}
 	}
 
-#if AHD_DEBUG
+#ifdef AHD_DEBUG
 	if (have_seeprom != 0
 	 && (ahd_debug & AHD_DUMP_SEEPROM) != 0) {
 		uint16_t *sc_data;
diff --git a/drivers/scsi/aic7xxx/aic7xxx.h b/drivers/scsi/aic7xxx/aic7xxx.h
--- a/drivers/scsi/aic7xxx/aic7xxx.h
+++ b/drivers/scsi/aic7xxx/aic7xxx.h
@@ -346,7 +346,6 @@ typedef enum {
 					  * controller.
 					  */
 	AHC_NEWEEPROM_FMT     = 0x4000,
-	AHC_RESOURCE_SHORTAGE = 0x8000,
 	AHC_TQINFIFO_BLOCKED  = 0x10000,  /* Blocked waiting for ATIOs */
 	AHC_INT50_SPEEDFLEX   = 0x20000,  /*
 					   * Internal 50pin connector
@@ -1024,9 +1023,6 @@ struct ahc_softc {
 	struct cs		 *critical_sections;
 	u_int			  num_critical_sections;
 
-	/* Links for chaining softcs */
-	TAILQ_ENTRY(ahc_softc)	  links;
-
 	/* Channel Names ('A', 'B', etc.) */
 	char			  channel;
 	char			  channel_b;
@@ -1111,9 +1107,6 @@ struct ahc_softc {
 	uint16_t		  user_tagenable;/* Tagged Queuing allowed */
 };
 
-TAILQ_HEAD(ahc_softc_tailq, ahc_softc);
-extern struct ahc_softc_tailq ahc_tailq;
-
 /************************ Active Device Information ***************************/
 typedef enum {
 	ROLE_UNKNOWN,
@@ -1199,8 +1192,6 @@ void			 ahc_intr_enable(struct ahc_softc
 void			 ahc_pause_and_flushwork(struct ahc_softc *ahc);
 int			 ahc_suspend(struct ahc_softc *ahc); 
 int			 ahc_resume(struct ahc_softc *ahc);
-void			 ahc_softc_insert(struct ahc_softc *);
-struct ahc_softc	*ahc_find_softc(struct ahc_softc *ahc);
 void			 ahc_set_unit(struct ahc_softc *, int);
 void			 ahc_set_name(struct ahc_softc *, char *);
 void			 ahc_alloc_scbs(struct ahc_softc *ahc);
diff --git a/drivers/scsi/aic7xxx/aic7xxx_core.c b/drivers/scsi/aic7xxx/aic7xxx_core.c
--- a/drivers/scsi/aic7xxx/aic7xxx_core.c
+++ b/drivers/scsi/aic7xxx/aic7xxx_core.c
@@ -52,9 +52,6 @@
 #include <dev/aic7xxx/aicasm/aicasm_insformat.h>
 #endif
 
-/****************************** Softc Data ************************************/
-struct ahc_softc_tailq ahc_tailq = TAILQ_HEAD_INITIALIZER(ahc_tailq);
-
 /***************************** Lookup Tables **********************************/
 char *ahc_chip_names[] =
 {
@@ -3879,78 +3876,6 @@ ahc_softc_init(struct ahc_softc *ahc)
 }
 
 void
-ahc_softc_insert(struct ahc_softc *ahc)
-{
-	struct ahc_softc *list_ahc;
-
-#if AHC_PCI_CONFIG > 0
-	/*
-	 * Second Function PCI devices need to inherit some
-	 * settings from function 0.
-	 */
-	if ((ahc->chip & AHC_BUS_MASK) == AHC_PCI
-	 && (ahc->features & AHC_MULTI_FUNC) != 0) {
-		TAILQ_FOREACH(list_ahc, &ahc_tailq, links) {
-			ahc_dev_softc_t list_pci;
-			ahc_dev_softc_t pci;
-
-			list_pci = list_ahc->dev_softc;
-			pci = ahc->dev_softc;
-			if (ahc_get_pci_slot(list_pci) == ahc_get_pci_slot(pci)
-			 && ahc_get_pci_bus(list_pci) == ahc_get_pci_bus(pci)) {
-				struct ahc_softc *master;
-				struct ahc_softc *slave;
-
-				if (ahc_get_pci_function(list_pci) == 0) {
-					master = list_ahc;
-					slave = ahc;
-				} else {
-					master = ahc;
-					slave = list_ahc;
-				}
-				slave->flags &= ~AHC_BIOS_ENABLED; 
-				slave->flags |=
-				    master->flags & AHC_BIOS_ENABLED;
-				slave->flags &= ~AHC_PRIMARY_CHANNEL; 
-				slave->flags |=
-				    master->flags & AHC_PRIMARY_CHANNEL;
-				break;
-			}
-		}
-	}
-#endif
-
-	/*
-	 * Insertion sort into our list of softcs.
-	 */
-	list_ahc = TAILQ_FIRST(&ahc_tailq);
-	while (list_ahc != NULL
-	    && ahc_softc_comp(ahc, list_ahc) <= 0)
-		list_ahc = TAILQ_NEXT(list_ahc, links);
-	if (list_ahc != NULL)
-		TAILQ_INSERT_BEFORE(list_ahc, ahc, links);
-	else
-		TAILQ_INSERT_TAIL(&ahc_tailq, ahc, links);
-	ahc->init_level++;
-}
-
-/*
- * Verify that the passed in softc pointer is for a
- * controller that is still configured.
- */
-struct ahc_softc *
-ahc_find_softc(struct ahc_softc *ahc)
-{
-	struct ahc_softc *list_ahc;
-
-	TAILQ_FOREACH(list_ahc, &ahc_tailq, links) {
-		if (list_ahc == ahc)
-			return (ahc);
-	}
-	return (NULL);
-}
-
-void
 ahc_set_unit(struct ahc_softc *ahc, int unit)
 {
 	ahc->unit = unit;
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c
--- a/drivers/scsi/aic7xxx/aic7xxx_osm.c
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c
@@ -122,8 +122,6 @@
 #include "aic7xxx_osm.h"
 #include "aic7xxx_inline.h"
 #include <scsi/scsicam.h>
-#include <scsi/scsi_transport.h>
-#include <scsi/scsi_transport_spi.h>
 
 static struct scsi_transport_template *ahc_linux_transport_template = NULL;
 
@@ -138,10 +136,6 @@ static struct scsi_transport_template *a
 #include <linux/blkdev.h>		/* For block_size() */
 #include <linux/delay.h>	/* For ssleep/msleep */
 
-/*
- * Lock protecting manipulation of the ahc softc list.
- */
-spinlock_t ahc_list_spinlock;
 
 /*
  * Set this to the delay in seconds after SCSI bus reset.
@@ -294,25 +288,6 @@ ahc_print_path(struct ahc_softc *ahc, st
 static uint32_t aic7xxx_no_reset;
 
 /*
- * Certain PCI motherboards will scan PCI devices from highest to lowest,
- * others scan from lowest to highest, and they tend to do all kinds of
- * strange things when they come into contact with PCI bridge chips.  The
- * net result of all this is that the PCI card that is actually used to boot
- * the machine is very hard to detect.  Most motherboards go from lowest
- * PCI slot number to highest, and the first SCSI controller found is the
- * one you boot from.  The only exceptions to this are when a controller
- * has its BIOS disabled.  So, we by default sort all of our SCSI controllers
- * from lowest PCI slot number to highest PCI slot number.  We also force
- * all controllers with their BIOS disabled to the end of the list.  This
- * works on *almost* all computers.  Where it doesn't work, we have this
- * option.  Setting this option to non-0 will reverse the order of the sort
- * to highest first, then lowest, but will still leave cards with their BIOS
- * disabled at the very end.  That should fix everyone up unless there are
- * really strange cirumstances.
- */
-static uint32_t aic7xxx_reverse_scan;
-
-/*
  * Should we force EXTENDED translation on a controller.
  *     0 == Use whatever is in the SEEPROM or default to off
  *     1 == Use whatever is in the SEEPROM or default to on
@@ -332,22 +307,6 @@ static uint32_t aic7xxx_extended;
 static uint32_t aic7xxx_pci_parity = ~0;
 
 /*
- * Certain newer motherboards have put new PCI based devices into the
- * IO spaces that used to typically be occupied by VLB or EISA cards.
- * This overlap can cause these newer motherboards to lock up when scanned
- * for older EISA and VLB devices.  Setting this option to non-0 will
- * cause the driver to skip scanning for any VLB or EISA controllers and
- * only support the PCI controllers.  NOTE: this means that if the kernel
- * os compiled with PCI support disabled, then setting this to non-0
- * would result in never finding any devices :)
- */
-#ifndef CONFIG_AIC7XXX_PROBE_EISA_VL
-uint32_t aic7xxx_probe_eisa_vl;
-#else
-uint32_t aic7xxx_probe_eisa_vl = ~0;
-#endif
-
-/*
  * There are lots of broken chipsets in the world.  Some of them will
  * violate the PCI spec when we issue byte sized memory writes to our
  * controller.  I/O mapped register access, if allowed by the given
@@ -356,13 +315,6 @@ uint32_t aic7xxx_probe_eisa_vl = ~0;
 uint32_t aic7xxx_allow_memio = ~0;
 
 /*
- * aic7xxx_detect() has been run, so register all device arrivals
- * immediately with the system rather than deferring to the sorted
- * attachment performed by aic7xxx_detect().
- */
-int aic7xxx_detect_complete;
-
-/*
  * So that we can set how long each device is given as a selection timeout.
  * The table of values goes like this:
  *   0 - 256ms
@@ -423,7 +375,7 @@ MODULE_PARM_DESC(aic7xxx,
 );
 
 static void ahc_linux_handle_scsi_status(struct ahc_softc *,
-					 struct ahc_linux_device *,
+					 struct scsi_device *,
 					 struct scb *);
 static void ahc_linux_queue_cmd_complete(struct ahc_softc *ahc,
 					 struct scsi_cmnd *cmd);
@@ -434,52 +386,24 @@ static int  ahc_linux_queue_recovery_cmd
 static void ahc_linux_initialize_scsi_bus(struct ahc_softc *ahc);
 static u_int ahc_linux_user_tagdepth(struct ahc_softc *ahc,
 				     struct ahc_devinfo *devinfo);
-static void ahc_linux_device_queue_depth(struct ahc_softc *ahc,
-					 struct ahc_linux_device *dev);
-static struct ahc_linux_target*	ahc_linux_alloc_target(struct ahc_softc*,
-						       u_int, u_int);
-static void			ahc_linux_free_target(struct ahc_softc*,
-						      struct ahc_linux_target*);
-static struct ahc_linux_device*	ahc_linux_alloc_device(struct ahc_softc*,
-						       struct ahc_linux_target*,
-						       u_int);
-static void			ahc_linux_free_device(struct ahc_softc*,
-						      struct ahc_linux_device*);
+static void ahc_linux_device_queue_depth(struct scsi_device *);
 static int ahc_linux_run_command(struct ahc_softc*,
 				 struct ahc_linux_device *,
 				 struct scsi_cmnd *);
 static void ahc_linux_setup_tag_info_global(char *p);
 static aic_option_callback_t ahc_linux_setup_tag_info;
 static int  aic7xxx_setup(char *s);
-static int  ahc_linux_next_unit(void);
+
+static int ahc_linux_unit;
+
 
 /********************************* Inlines ************************************/
-static __inline struct ahc_linux_device*
-		     ahc_linux_get_device(struct ahc_softc *ahc, u_int channel,
-					  u_int target, u_int lun);
 static __inline void ahc_linux_unmap_scb(struct ahc_softc*, struct scb*);
 
 static __inline int ahc_linux_map_seg(struct ahc_softc *ahc, struct scb *scb,
 		 		      struct ahc_dma_seg *sg,
 				      dma_addr_t addr, bus_size_t len);
 
-static __inline struct ahc_linux_device*
-ahc_linux_get_device(struct ahc_softc *ahc, u_int channel, u_int target,
-		     u_int lun)
-{
-	struct ahc_linux_target *targ;
-	struct ahc_linux_device *dev;
-	u_int target_offset;
-
-	target_offset = target;
-	if (channel != 0)
-		target_offset += 8;
-	targ = ahc->platform_data->targets[target_offset];
-	BUG_ON(targ == NULL);
-	dev = targ->devices[lun];
-	return dev;
-}
-
 static __inline void
 ahc_linux_unmap_scb(struct ahc_softc *ahc, struct scb *scb)
 {
@@ -524,59 +448,6 @@ ahc_linux_map_seg(struct ahc_softc *ahc,
 }
 
 /*
- * Try to detect an Adaptec 7XXX controller.
- */
-static int
-ahc_linux_detect(struct scsi_host_template *template)
-{
-	struct	ahc_softc *ahc;
-	int     found = 0;
-
-	/*
-	 * Sanity checking of Linux SCSI data structures so
-	 * that some of our hacks^H^H^H^H^Hassumptions aren't
-	 * violated.
-	 */
-	if (offsetof(struct ahc_cmd_internal, end)
-	  > offsetof(struct scsi_cmnd, host_scribble)) {
-		printf("ahc_linux_detect: SCSI data structures changed.\n");
-		printf("ahc_linux_detect: Unable to attach\n");
-		return (0);
-	}
-	/*
-	 * If we've been passed any parameters, process them now.
-	 */
-	if (aic7xxx)
-		aic7xxx_setup(aic7xxx);
-
-	template->proc_name = "aic7xxx";
-
-	/*
-	 * Initialize our softc list lock prior to
-	 * probing for any adapters.
-	 */
-	ahc_list_lockinit();
-
-	found = ahc_linux_pci_init();
-	if (!ahc_linux_eisa_init())
-		found++;
-	
-	/*
-	 * Register with the SCSI layer all
-	 * controllers we've found.
-	 */
-	TAILQ_FOREACH(ahc, &ahc_tailq, links) {
-
-		if (ahc_linux_register_host(ahc, template) == 0)
-			found++;
-	}
-
-	aic7xxx_detect_complete++;
-
-	return (found);
-}
-
-/*
  * Return a string describing the driver.
  */
 static const char *
@@ -611,7 +482,7 @@ static int
 ahc_linux_queue(struct scsi_cmnd * cmd, void (*scsi_done) (struct scsi_cmnd *))
 {
 	struct	 ahc_softc *ahc;
-	struct	 ahc_linux_device *dev;
+	struct	 ahc_linux_device *dev = scsi_transport_device_data(cmd->device);
 
 	ahc = *(struct ahc_softc **)cmd->device->host->hostdata;
 
@@ -629,132 +500,177 @@ ahc_linux_queue(struct scsi_cmnd * cmd, 
 	if (ahc->platform_data->qfrozen != 0)
 		return SCSI_MLQUEUE_HOST_BUSY;
 
-	dev = ahc_linux_get_device(ahc, cmd->device->channel, cmd->device->id,
-				   cmd->device->lun);
-	BUG_ON(dev == NULL);
-
 	cmd->result = CAM_REQ_INPROG << 16;
 
 	return ahc_linux_run_command(ahc, dev, cmd);
 }
 
-static int
-ahc_linux_slave_alloc(struct scsi_device *device)
+static inline struct scsi_target **
+ahc_linux_target_in_softc(struct scsi_target *starget)
 {
-	struct	ahc_softc *ahc;
-	struct ahc_linux_target *targ;
-	struct scsi_target *starget = device->sdev_target;
-	struct ahc_linux_device *dev;
+	struct	ahc_softc *ahc =
+		*((struct ahc_softc **)dev_to_shost(&starget->dev)->hostdata);
 	unsigned int target_offset;
+
+	target_offset = starget->id;
+	if (starget->channel != 0)
+		target_offset += 8;
+
+	return &ahc->platform_data->starget[target_offset];
+}
+
+static int
+ahc_linux_target_alloc(struct scsi_target *starget)
+{
+	struct	ahc_softc *ahc =
+		*((struct ahc_softc **)dev_to_shost(&starget->dev)->hostdata);
+	struct seeprom_config *sc = ahc->seep_config;
 	unsigned long flags;
-	int retval = -ENOMEM;
+	struct scsi_target **ahc_targp = ahc_linux_target_in_softc(starget);
+	struct ahc_linux_target *targ = scsi_transport_target_data(starget);
+	unsigned short scsirate;
+	struct ahc_devinfo devinfo;
+	struct ahc_initiator_tinfo *tinfo;
+	struct ahc_tmode_tstate *tstate;
+	char channel = starget->channel + 'A';
+	unsigned int our_id = ahc->our_id;
+	unsigned int target_offset;
 
 	target_offset = starget->id;
 	if (starget->channel != 0)
 		target_offset += 8;
+	  
+	if (starget->channel)
+		our_id = ahc->our_id_b;
 
-	ahc = *((struct ahc_softc **)device->host->hostdata);
-	if (bootverbose)
-		printf("%s: Slave Alloc %d\n", ahc_name(ahc), device->id);
 	ahc_lock(ahc, &flags);
-	targ = ahc->platform_data->targets[target_offset];
-	if (targ == NULL) {
-		struct seeprom_config *sc;
-
-		targ = ahc_linux_alloc_target(ahc, starget->channel,
-						starget->id);
-		sc = ahc->seep_config;
-		if (targ == NULL)
-			goto out;
 
-		if (sc) {
-			unsigned short scsirate;
-			struct ahc_devinfo devinfo;
-			struct ahc_initiator_tinfo *tinfo;
-			struct ahc_tmode_tstate *tstate;
-			char channel = starget->channel + 'A';
-			unsigned int our_id = ahc->our_id;
+	BUG_ON(*ahc_targp != NULL);
 
-			if (starget->channel)
-				our_id = ahc->our_id_b;
+	*ahc_targp = starget;
+	memset(targ, 0, sizeof(*targ));
 
-			if ((ahc->features & AHC_ULTRA2) != 0) {
-				scsirate = sc->device_flags[target_offset] & CFXFER;
-			} else {
-				scsirate = (sc->device_flags[target_offset] & CFXFER) << 4;
-				if (sc->device_flags[target_offset] & CFSYNCH)
-					scsirate |= SOFS;
-			}
-			if (sc->device_flags[target_offset] & CFWIDEB) {
-				scsirate |= WIDEXFER;
-				spi_max_width(starget) = 1;
-			} else
-				spi_max_width(starget) = 0;
-			spi_min_period(starget) = 
-				ahc_find_period(ahc, scsirate, AHC_SYNCRATE_DT);
-			tinfo = ahc_fetch_transinfo(ahc, channel, ahc->our_id,
-						    targ->target, &tstate);
-			ahc_compile_devinfo(&devinfo, our_id, targ->target,
-					    CAM_LUN_WILDCARD, channel,
-					    ROLE_INITIATOR);
-			ahc_set_syncrate(ahc, &devinfo, NULL, 0, 0, 0,
-					 AHC_TRANS_GOAL, /*paused*/FALSE);
-			ahc_set_width(ahc, &devinfo, MSG_EXT_WDTR_BUS_8_BIT,
-				      AHC_TRANS_GOAL, /*paused*/FALSE);
-		}
-			
-	}
-	dev = targ->devices[device->lun];
-	if (dev == NULL) {
-		dev = ahc_linux_alloc_device(ahc, targ, device->lun);
-		if (dev == NULL)
-			goto out;
-	}
-	retval = 0;
+	if (sc) {
+		int maxsync = AHC_SYNCRATE_DT;
+		int ultra = 0;
+		int flags = sc->device_flags[target_offset];
+
+		if (ahc->flags & AHC_NEWEEPROM_FMT) {
+		    if (flags & CFSYNCHISULTRA)
+			ultra = 1;
+		} else if (flags & CFULTRAEN)
+			ultra = 1;
+		/* AIC nutcase; 10MHz appears as ultra = 1, CFXFER = 0x04
+		 * change it to ultra=0, CFXFER = 0 */
+		if(ultra && (flags & CFXFER) == 0x04) {
+			ultra = 0;
+			flags &= ~CFXFER;
+		}
+	    
+		if ((ahc->features & AHC_ULTRA2) != 0) {
+			scsirate = (flags & CFXFER) | (ultra ? 0x8 : 0);
+		} else {
+			scsirate = (flags & CFXFER) << 4;
+			maxsync = ultra ? AHC_SYNCRATE_ULTRA : 
+				AHC_SYNCRATE_FAST;
+		}
+		spi_max_width(starget) = (flags & CFWIDEB) ? 1 : 0;
+		if (!(flags & CFSYNCH))
+			spi_max_offset(starget) = 0;
+		spi_min_period(starget) = 
+			ahc_find_period(ahc, scsirate, maxsync);
 
- out:
+		tinfo = ahc_fetch_transinfo(ahc, channel, ahc->our_id,
+					    starget->id, &tstate);
+	}
+	ahc_compile_devinfo(&devinfo, our_id, starget->id,
+			    CAM_LUN_WILDCARD, channel,
+			    ROLE_INITIATOR);
+	ahc_set_syncrate(ahc, &devinfo, NULL, 0, 0, 0,
+			 AHC_TRANS_GOAL, /*paused*/FALSE);
+	ahc_set_width(ahc, &devinfo, MSG_EXT_WDTR_BUS_8_BIT,
+		      AHC_TRANS_GOAL, /*paused*/FALSE);
 	ahc_unlock(ahc, &flags);
-	return retval;
+
+	return 0;
+}
+
+static void
+ahc_linux_target_destroy(struct scsi_target *starget)
+{
+	struct scsi_target **ahc_targp = ahc_linux_target_in_softc(starget);
+
+	*ahc_targp = NULL;
 }
 
 static int
-ahc_linux_slave_configure(struct scsi_device *device)
+ahc_linux_slave_alloc(struct scsi_device *sdev)
+{
+	struct	ahc_softc *ahc =
+		*((struct ahc_softc **)sdev->host->hostdata);
+	struct scsi_target *starget = sdev->sdev_target;
+	struct ahc_linux_target *targ = scsi_transport_target_data(starget);
+	struct ahc_linux_device *dev;
+
+	if (bootverbose)
+		printf("%s: Slave Alloc %d\n", ahc_name(ahc), sdev->id);
+
+	BUG_ON(targ->sdev[sdev->lun] != NULL);
+
+	dev = scsi_transport_device_data(sdev);
+	memset(dev, 0, sizeof(*dev));
+
+	/*
+	 * We start out life using untagged
+	 * transactions of which we allow one.
+	 */
+	dev->openings = 1;
+
+	/*
+	 * Set maxtags to 0.  This will be changed if we
+	 * later determine that we are dealing with
+	 * a tagged queuing capable device.
+	 */
+	dev->maxtags = 0;
+	
+	targ->sdev[sdev->lun] = sdev;
+
+	return 0;
+}
+
+static int
+ahc_linux_slave_configure(struct scsi_device *sdev)
 {
 	struct	ahc_softc *ahc;
-	struct	ahc_linux_device *dev;
 
-	ahc = *((struct ahc_softc **)device->host->hostdata);
+	ahc = *((struct ahc_softc **)sdev->host->hostdata);
 
 	if (bootverbose)
-		printf("%s: Slave Configure %d\n", ahc_name(ahc), device->id);
+		printf("%s: Slave Configure %d\n", ahc_name(ahc), sdev->id);
 
-	dev = ahc_linux_get_device(ahc, device->channel, device->id,
-				   device->lun);
-	dev->scsi_device = device;
-	ahc_linux_device_queue_depth(ahc, dev);
+	ahc_linux_device_queue_depth(sdev);
 
 	/* Initial Domain Validation */
-	if (!spi_initial_dv(device->sdev_target))
-		spi_dv_device(device);
+	if (!spi_initial_dv(sdev->sdev_target))
+		spi_dv_device(sdev);
 
 	return 0;
 }
 
 static void
-ahc_linux_slave_destroy(struct scsi_device *device)
+ahc_linux_slave_destroy(struct scsi_device *sdev)
 {
 	struct	ahc_softc *ahc;
-	struct	ahc_linux_device *dev;
+	struct	ahc_linux_device *dev = scsi_transport_device_data(sdev);
+	struct	ahc_linux_target *targ = scsi_transport_target_data(sdev->sdev_target);
 
-	ahc = *((struct ahc_softc **)device->host->hostdata);
+	ahc = *((struct ahc_softc **)sdev->host->hostdata);
 	if (bootverbose)
-		printf("%s: Slave Destroy %d\n", ahc_name(ahc), device->id);
-	dev = ahc_linux_get_device(ahc, device->channel,
-				   device->id, device->lun);
+		printf("%s: Slave Destroy %d\n", ahc_name(ahc), sdev->id);
 
 	BUG_ON(dev->active);
 
-	ahc_linux_free_device(ahc, dev);
+	targ->sdev[sdev->lun] = NULL;
 }
 
 #if defined(__i386__)
@@ -843,10 +759,14 @@ ahc_linux_bus_reset(struct scsi_cmnd *cm
 {
 	struct ahc_softc *ahc;
 	int    found;
+	unsigned long flags;
 
 	ahc = *(struct ahc_softc **)cmd->device->host->hostdata;
+
+	ahc_lock(ahc, &flags);
 	found = ahc_reset_channel(ahc, cmd->device->channel + 'A',
 				  /*initiate reset*/TRUE);
+	ahc_unlock(ahc, &flags);
 
 	if (bootverbose)
 		printf("%s: SCSI bus reset delivered. "
@@ -858,6 +778,7 @@ ahc_linux_bus_reset(struct scsi_cmnd *cm
 struct scsi_host_template aic7xxx_driver_template = {
 	.module			= THIS_MODULE,
 	.name			= "aic7xxx",
+	.proc_name		= "aic7xxx",
 	.proc_info		= ahc_linux_proc_info,
 	.info			= ahc_linux_info,
 	.queuecommand		= ahc_linux_queue,
@@ -874,6 +795,8 @@ struct scsi_host_template aic7xxx_driver
 	.slave_alloc		= ahc_linux_slave_alloc,
 	.slave_configure	= ahc_linux_slave_configure,
 	.slave_destroy		= ahc_linux_slave_destroy,
+	.target_alloc		= ahc_linux_target_alloc,
+	.target_destroy		= ahc_linux_target_destroy,
 };
 
 /**************************** Tasklet Handler *********************************/
@@ -967,99 +890,6 @@ ahc_dmamap_unload(struct ahc_softc *ahc,
 	return (0);
 }
 
-/********************* Platform Dependent Functions ***************************/
-/*
- * Compare "left hand" softc with "right hand" softc, returning:
- * < 0 - lahc has a lower priority than rahc
- *   0 - Softcs are equal
- * > 0 - lahc has a higher priority than rahc
- */
-int
-ahc_softc_comp(struct ahc_softc *lahc, struct ahc_softc *rahc)
-{
-	int	value;
-	int	rvalue;
-	int	lvalue;
-
-	/*
-	 * Under Linux, cards are ordered as follows:
-	 *	1) VLB/EISA BIOS enabled devices sorted by BIOS address.
-	 *	2) PCI devices with BIOS enabled sorted by bus/slot/func.
-	 *	3) All remaining VLB/EISA devices sorted by ioport.
-	 *	4) All remaining PCI devices sorted by bus/slot/func.
-	 */
-	value = (lahc->flags & AHC_BIOS_ENABLED)
-	      - (rahc->flags & AHC_BIOS_ENABLED);
-	if (value != 0)
-		/* Controllers with BIOS enabled have a *higher* priority */
-		return (value);
-
-	/*
-	 * Same BIOS setting, now sort based on bus type.
-	 * EISA and VL controllers sort together.  EISA/VL
-	 * have higher priority than PCI.
-	 */
-	rvalue = (rahc->chip & AHC_BUS_MASK);
- 	if (rvalue == AHC_VL)
-		rvalue = AHC_EISA;
-	lvalue = (lahc->chip & AHC_BUS_MASK);
- 	if (lvalue == AHC_VL)
-		lvalue = AHC_EISA;
-	value = rvalue - lvalue;
-	if (value != 0)
-		return (value);
-
-	/* Still equal.  Sort by BIOS address, ioport, or bus/slot/func. */
-	switch (rvalue) {
-#ifdef CONFIG_PCI
-	case AHC_PCI:
-	{
-		char primary_channel;
-
-		if (aic7xxx_reverse_scan != 0)
-			value = ahc_get_pci_bus(lahc->dev_softc)
-			      - ahc_get_pci_bus(rahc->dev_softc);
-		else
-			value = ahc_get_pci_bus(rahc->dev_softc)
-			      - ahc_get_pci_bus(lahc->dev_softc);
-		if (value != 0)
-			break;
-		if (aic7xxx_reverse_scan != 0)
-			value = ahc_get_pci_slot(lahc->dev_softc)
-			      - ahc_get_pci_slot(rahc->dev_softc);
-		else
-			value = ahc_get_pci_slot(rahc->dev_softc)
-			      - ahc_get_pci_slot(lahc->dev_softc);
-		if (value != 0)
-			break;
-		/*
-		 * On multi-function devices, the user can choose
-		 * to have function 1 probed before function 0.
-		 * Give whichever channel is the primary channel
-		 * the highest priority.
-		 */
-		primary_channel = (lahc->flags & AHC_PRIMARY_CHANNEL) + 'A';
-		value = -1;
-		if (lahc->channel == primary_channel)
-			value = 1;
-		break;
-	}
-#endif
-	case AHC_EISA:
-		if ((rahc->flags & AHC_BIOS_ENABLED) != 0) {
-			value = rahc->platform_data->bios_address
-			      - lahc->platform_data->bios_address; 
-		} else {
-			value = rahc->bsh.ioport
-			      - lahc->bsh.ioport; 
-		}
-		break;
-	default:
-		panic("ahc_softc_sort: invalid bus type");
-	}
-	return (value);
-}
-
 static void
 ahc_linux_setup_tag_info_global(char *p)
 {
@@ -1111,9 +941,6 @@ aic7xxx_setup(char *s)
 #ifdef AHC_DEBUG
 		{ "debug", &ahc_debug },
 #endif
-		{ "reverse_scan", &aic7xxx_reverse_scan },
-		{ "no_probe", &aic7xxx_probe_eisa_vl },
-		{ "probe_eisa_vl", &aic7xxx_probe_eisa_vl },
 		{ "periodic_otag", &aic7xxx_periodic_otag },
 		{ "pci_parity", &aic7xxx_pci_parity },
 		{ "seltime", &aic7xxx_seltime },
@@ -1188,7 +1015,7 @@ ahc_linux_register_host(struct ahc_softc
 	host->max_lun = AHC_NUM_LUNS;
 	host->max_channel = (ahc->features & AHC_TWIN) ? 1 : 0;
 	host->sg_tablesize = AHC_NSEG;
-	ahc_set_unit(ahc, ahc_linux_next_unit());
+	ahc_set_unit(ahc, ahc_linux_unit++);
 	sprintf(buf, "scsi%d", host->host_no);
 	new_name = malloc(strlen(buf) + 1, M_DEVBUF, M_NOWAIT);
 	if (new_name != NULL) {
@@ -1217,29 +1044,6 @@ ahc_linux_get_memsize(void)
 }
 
 /*
- * Find the smallest available unit number to use
- * for a new device.  We don't just use a static
- * count to handle the "repeated hot-(un)plug"
- * scenario.
- */
-static int
-ahc_linux_next_unit(void)
-{
-	struct ahc_softc *ahc;
-	int unit;
-
-	unit = 0;
-retry:
-	TAILQ_FOREACH(ahc, &ahc_tailq, links) {
-		if (ahc->unit == unit) {
-			unit++;
-			goto retry;
-		}
-	}
-	return (unit);
-}
-
-/*
  * Place the SCSI bus into a known state by either resetting it,
  * or forcing transfer negotiations on the next command to any
  * target.
@@ -1335,8 +1139,7 @@ ahc_platform_alloc(struct ahc_softc *ahc
 void
 ahc_platform_free(struct ahc_softc *ahc)
 {
-	struct ahc_linux_target *targ;
-	struct ahc_linux_device *dev;
+	struct scsi_target *starget;
 	int i, j;
 
 	if (ahc->platform_data != NULL) {
@@ -1347,22 +1150,17 @@ ahc_platform_free(struct ahc_softc *ahc)
 
 		/* destroy all of the device and target objects */
 		for (i = 0; i < AHC_NUM_TARGETS; i++) {
-			targ = ahc->platform_data->targets[i];
-			if (targ != NULL) {
-				/* Keep target around through the loop. */
-				targ->refcount++;
+			starget = ahc->platform_data->starget[i];
+			if (starget != NULL) {
 				for (j = 0; j < AHC_NUM_LUNS; j++) {
+					struct ahc_linux_target *targ =
+						scsi_transport_target_data(starget);
 
-					if (targ->devices[j] == NULL)
+					if (targ->sdev[j] == NULL)
 						continue;
-					dev = targ->devices[j];
-					ahc_linux_free_device(ahc, dev);
+					targ->sdev[j] = NULL;
 				}
-				/*
-				 * Forcibly free the target now that
-				 * all devices are gone.
-				 */
-				ahc_linux_free_target(ahc, targ);
+				ahc->platform_data->starget[i] = NULL;
  			}
  		}
 
@@ -1395,15 +1193,25 @@ void
 ahc_platform_set_tags(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
 		      ahc_queue_alg alg)
 {
+	struct scsi_target *starget;
+	struct ahc_linux_target *targ;
 	struct ahc_linux_device *dev;
+	struct scsi_device *sdev;
+	u_int target_offset;
 	int was_queuing;
 	int now_queuing;
 
-	dev = ahc_linux_get_device(ahc, devinfo->channel - 'A',
-				   devinfo->target,
-				   devinfo->lun);
-	if (dev == NULL)
+	target_offset = devinfo->target;
+	if (devinfo->channel != 'A')
+		target_offset += 8;
+	starget = ahc->platform_data->starget[target_offset];
+	targ = scsi_transport_target_data(starget);
+	BUG_ON(targ == NULL);
+	sdev = targ->sdev[devinfo->lun];
+	if (sdev == NULL)
 		return;
+	dev = scsi_transport_device_data(sdev);
+
 	was_queuing = dev->flags & (AHC_DEV_Q_BASIC|AHC_DEV_Q_TAGGED);
 	switch (alg) {
 	default:
@@ -1454,30 +1262,24 @@ ahc_platform_set_tags(struct ahc_softc *
 		dev->maxtags = 0;
 		dev->openings =  1 - dev->active;
 	}
-	if (dev->scsi_device != NULL) {
-		switch ((dev->flags & (AHC_DEV_Q_BASIC|AHC_DEV_Q_TAGGED))) {
-		case AHC_DEV_Q_BASIC:
-			scsi_adjust_queue_depth(dev->scsi_device,
-						MSG_SIMPLE_TASK,
-						dev->openings + dev->active);
-			break;
-		case AHC_DEV_Q_TAGGED:
-			scsi_adjust_queue_depth(dev->scsi_device,
-						MSG_ORDERED_TASK,
-						dev->openings + dev->active);
-			break;
-		default:
-			/*
-			 * We allow the OS to queue 2 untagged transactions to
-			 * us at any time even though we can only execute them
-			 * serially on the controller/device.  This should
-			 * remove some latency.
-			 */
-			scsi_adjust_queue_depth(dev->scsi_device,
-						/*NON-TAGGED*/0,
-						/*queue depth*/2);
-			break;
-		}
+	switch ((dev->flags & (AHC_DEV_Q_BASIC|AHC_DEV_Q_TAGGED))) {
+	case AHC_DEV_Q_BASIC:
+		scsi_set_tag_type(sdev, MSG_SIMPLE_TAG);
+		scsi_activate_tcq(sdev, dev->openings + dev->active);
+		break;
+	case AHC_DEV_Q_TAGGED:
+		scsi_set_tag_type(sdev, MSG_ORDERED_TAG);
+		scsi_activate_tcq(sdev, dev->openings + dev->active);
+		break;
+	default:
+		/*
+		 * We allow the OS to queue 2 untagged transactions to
+		 * us at any time even though we can only execute them
+		 * serially on the controller/device.  This should
+		 * remove some latency.
+		 */
+		scsi_deactivate_tcq(sdev, 2);
+		break;
 	}
 }
 
@@ -1523,22 +1325,20 @@ ahc_linux_user_tagdepth(struct ahc_softc
  * Determines the queue depth for a given device.
  */
 static void
-ahc_linux_device_queue_depth(struct ahc_softc *ahc,
-			     struct ahc_linux_device *dev)
+ahc_linux_device_queue_depth(struct scsi_device *sdev)
 {
 	struct	ahc_devinfo devinfo;
 	u_int	tags;
+	struct ahc_softc *ahc = *((struct ahc_softc **)sdev->host->hostdata);
 
 	ahc_compile_devinfo(&devinfo,
-			    dev->target->channel == 0
+			    sdev->sdev_target->channel == 0
 			  ? ahc->our_id : ahc->our_id_b,
-			    dev->target->target, dev->lun,
-			    dev->target->channel == 0 ? 'A' : 'B',
+			    sdev->sdev_target->id, sdev->lun,
+			    sdev->sdev_target->channel == 0 ? 'A' : 'B',
 			    ROLE_INITIATOR);
 	tags = ahc_linux_user_tagdepth(ahc, &devinfo);
-	if (tags != 0
-	 && dev->scsi_device != NULL
-	 && dev->scsi_device->tagged_supported != 0) {
+	if (tags != 0 && sdev->tagged_supported != 0) {
 
 		ahc_set_tags(ahc, &devinfo, AHC_QUEUE_TAGGED);
 		ahc_print_devinfo(ahc, &devinfo);
@@ -1587,10 +1387,9 @@ ahc_linux_run_command(struct ahc_softc *
 	/*
 	 * Get an scb to use.
 	 */
-	if ((scb = ahc_get_scb(ahc)) == NULL) {
-			ahc->flags |= AHC_RESOURCE_SHORTAGE;
-			return SCSI_MLQUEUE_HOST_BUSY;
-	}
+	scb = ahc_get_scb(ahc);
+	if (!scb)
+		return SCSI_MLQUEUE_HOST_BUSY;
 
 	scb->io_ctx = cmd;
 	scb->platform_data->dev = dev;
@@ -1767,106 +1566,6 @@ ahc_platform_flushwork(struct ahc_softc 
 
 }
 
-static struct ahc_linux_target*
-ahc_linux_alloc_target(struct ahc_softc *ahc, u_int channel, u_int target)
-{
-	struct ahc_linux_target *targ;
-	u_int target_offset;
-
-	target_offset = target;
-	if (channel != 0)
-		target_offset += 8;
-
-	targ = malloc(sizeof(*targ), M_DEVBUG, M_NOWAIT);
-	if (targ == NULL)
-		return (NULL);
-	memset(targ, 0, sizeof(*targ));
-	targ->channel = channel;
-	targ->target = target;
-	targ->ahc = ahc;
-	ahc->platform_data->targets[target_offset] = targ;
-	return (targ);
-}
-
-static void
-ahc_linux_free_target(struct ahc_softc *ahc, struct ahc_linux_target *targ)
-{
-	struct ahc_devinfo devinfo;
-	struct ahc_initiator_tinfo *tinfo;
-	struct ahc_tmode_tstate *tstate;
-	u_int our_id;
-	u_int target_offset;
-	char channel;
-
-	/*
-	 * Force a negotiation to async/narrow on any
-	 * future command to this device unless a bus
-	 * reset occurs between now and that command.
-	 */
-	channel = 'A' + targ->channel;
-	our_id = ahc->our_id;
-	target_offset = targ->target;
-	if (targ->channel != 0) {
-		target_offset += 8;
-		our_id = ahc->our_id_b;
-	}
-	tinfo = ahc_fetch_transinfo(ahc, channel, our_id,
-				    targ->target, &tstate);
-	ahc_compile_devinfo(&devinfo, our_id, targ->target, CAM_LUN_WILDCARD,
-			    channel, ROLE_INITIATOR);
-	ahc_set_syncrate(ahc, &devinfo, NULL, 0, 0, 0,
-			 AHC_TRANS_GOAL, /*paused*/FALSE);
-	ahc_set_width(ahc, &devinfo, MSG_EXT_WDTR_BUS_8_BIT,
-		      AHC_TRANS_GOAL, /*paused*/FALSE);
-	ahc_update_neg_request(ahc, &devinfo, tstate, tinfo, AHC_NEG_ALWAYS);
-	ahc->platform_data->targets[target_offset] = NULL;
-	free(targ, M_DEVBUF);
-}
-
-static struct ahc_linux_device*
-ahc_linux_alloc_device(struct ahc_softc *ahc,
-		 struct ahc_linux_target *targ, u_int lun)
-{
-	struct ahc_linux_device *dev;
-
-	dev = malloc(sizeof(*dev), M_DEVBUG, M_NOWAIT);
-	if (dev == NULL)
-		return (NULL);
-	memset(dev, 0, sizeof(*dev));
-	dev->lun = lun;
-	dev->target = targ;
-
-	/*
-	 * We start out life using untagged
-	 * transactions of which we allow one.
-	 */
-	dev->openings = 1;
-
-	/*
-	 * Set maxtags to 0.  This will be changed if we
-	 * later determine that we are dealing with
-	 * a tagged queuing capable device.
-	 */
-	dev->maxtags = 0;
-	
-	targ->refcount++;
-	targ->devices[lun] = dev;
-	return (dev);
-}
-
-static void
-ahc_linux_free_device(struct ahc_softc *ahc, struct ahc_linux_device *dev)
-{
-	struct ahc_linux_target *targ;
-
-	targ = dev->target;
-	targ->devices[dev->lun] = NULL;
-	free(dev, M_DEVBUF);
-	targ->refcount--;
-	if (targ->refcount == 0)
-		ahc_linux_free_target(ahc, targ);
-}
-
 void
 ahc_send_async(struct ahc_softc *ahc, char channel,
 	       u_int target, u_int lun, ac_code code, void *arg)
@@ -1875,11 +1574,15 @@ ahc_send_async(struct ahc_softc *ahc, ch
 	case AC_TRANSFER_NEG:
 	{
 		char	buf[80];
+		struct	scsi_target *starget;
 		struct	ahc_linux_target *targ;
 		struct	info_str info;
 		struct	ahc_initiator_tinfo *tinfo;
 		struct	ahc_tmode_tstate *tstate;
 		int	target_offset;
+		unsigned int target_ppr_options;
+
+		BUG_ON(target == CAM_TARGET_WILDCARD);
 
 		info.buffer = buf;
 		info.length = sizeof(buf);
@@ -1908,32 +1611,30 @@ ahc_send_async(struct ahc_softc *ahc, ch
 		target_offset = target;
 		if (channel == 'B')
 			target_offset += 8;
-		targ = ahc->platform_data->targets[target_offset];
+		starget = ahc->platform_data->starget[target_offset];
+		targ = scsi_transport_target_data(starget);
 		if (targ == NULL)
 			break;
-		if (tinfo->curr.period == targ->last_tinfo.period
-		 && tinfo->curr.width == targ->last_tinfo.width
-		 && tinfo->curr.offset == targ->last_tinfo.offset
-		 && tinfo->curr.ppr_options == targ->last_tinfo.ppr_options)
+
+		target_ppr_options =
+			(spi_dt(starget) ? MSG_EXT_PPR_DT_REQ : 0)
+			+ (spi_qas(starget) ? MSG_EXT_PPR_QAS_REQ : 0)
+			+ (spi_iu(starget) ?  MSG_EXT_PPR_IU_REQ : 0);
+
+		if (tinfo->curr.period == spi_period(starget)
+		    && tinfo->curr.width == spi_width(starget)
+		    && tinfo->curr.offset == spi_offset(starget)
+		 && tinfo->curr.ppr_options == target_ppr_options)
 			if (bootverbose == 0)
 				break;
 
-		targ->last_tinfo.period = tinfo->curr.period;
-		targ->last_tinfo.width = tinfo->curr.width;
-		targ->last_tinfo.offset = tinfo->curr.offset;
-		targ->last_tinfo.ppr_options = tinfo->curr.ppr_options;
-
-		printf("(%s:%c:", ahc_name(ahc), channel);
-		if (target == CAM_TARGET_WILDCARD)
-			printf("*): ");
-		else
-			printf("%d): ", target);
-		ahc_format_transinfo(&info, &tinfo->curr);
-		if (info.pos < info.length)
-			*info.buffer = '\0';
-		else
-			buf[info.length - 1] = '\0';
-		printf("%s", buf);
+		spi_period(starget) = tinfo->curr.period;
+		spi_width(starget) = tinfo->curr.width;
+		spi_offset(starget) = tinfo->curr.offset;
+		spi_dt(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_DT_REQ ? 1 : 0;
+		spi_qas(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_QAS_REQ ? 1 : 0;
+		spi_iu(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_IU_REQ ? 1 : 0;
+		spi_display_xfer_agreement(starget);
 		break;
 	}
         case AC_SENT_BDR:
@@ -2038,7 +1739,7 @@ ahc_done(struct ahc_softc *ahc, struct s
 			ahc_set_transaction_status(scb, CAM_REQ_CMP);
 		}
 	} else if (ahc_get_transaction_status(scb) == CAM_SCSI_STATUS_ERROR) {
-		ahc_linux_handle_scsi_status(ahc, dev, scb);
+		ahc_linux_handle_scsi_status(ahc, cmd->device, scb);
 	}
 
 	if (dev->openings == 1
@@ -2077,14 +1778,15 @@ ahc_done(struct ahc_softc *ahc, struct s
 
 static void
 ahc_linux_handle_scsi_status(struct ahc_softc *ahc,
-			     struct ahc_linux_device *dev, struct scb *scb)
+			     struct scsi_device *sdev, struct scb *scb)
 {
 	struct	ahc_devinfo devinfo;
+	struct ahc_linux_device *dev = scsi_transport_device_data(sdev);
 
 	ahc_compile_devinfo(&devinfo,
 			    ahc->our_id,
-			    dev->target->target, dev->lun,
-			    dev->target->channel == 0 ? 'A' : 'B',
+			    sdev->sdev_target->id, sdev->lun,
+			    sdev->sdev_target->channel == 0 ? 'A' : 'B',
 			    ROLE_INITIATOR);
 	
 	/*
@@ -2361,6 +2063,8 @@ ahc_linux_queue_recovery_cmd(struct scsi
 		printf(" 0x%x", cmd->cmnd[cdb_byte]);
 	printf("\n");
 
+	spin_lock_irq(&ahc->platform_data->spin_lock);
+
 	/*
 	 * First determine if we currently own this command.
 	 * Start by searching the device queue.  If not found
@@ -2368,8 +2072,7 @@ ahc_linux_queue_recovery_cmd(struct scsi
 	 * at all, and the system wanted us to just abort the
 	 * command, return success.
 	 */
-	dev = ahc_linux_get_device(ahc, cmd->device->channel, cmd->device->id,
-				   cmd->device->lun);
+	dev = scsi_transport_device_data(cmd->device);
 
 	if (dev == NULL) {
 		/*
@@ -2616,6 +2319,8 @@ done:
 		}
 		spin_lock_irq(&ahc->platform_data->spin_lock);
 	}
+
+	spin_unlock_irq(&ahc->platform_data->spin_lock);
 	return (retval);
 }
 
@@ -2626,18 +2331,6 @@ ahc_platform_dump_card_state(struct ahc_
 
 static void ahc_linux_exit(void);
 
-static void ahc_linux_get_width(struct scsi_target *starget)
-{
-	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
-	struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata);
-	struct ahc_tmode_tstate *tstate;
-	struct ahc_initiator_tinfo *tinfo 
-		= ahc_fetch_transinfo(ahc,
-				      starget->channel + 'A',
-				      shost->this_id, starget->id, &tstate);
-	spi_width(starget) = tinfo->curr.width;
-}
-
 static void ahc_linux_set_width(struct scsi_target *starget, int width)
 {
 	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
@@ -2652,18 +2345,6 @@ static void ahc_linux_set_width(struct s
 	ahc_unlock(ahc, &flags);
 }
 
-static void ahc_linux_get_period(struct scsi_target *starget)
-{
-	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
-	struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata);
-	struct ahc_tmode_tstate *tstate;
-	struct ahc_initiator_tinfo *tinfo 
-		= ahc_fetch_transinfo(ahc,
-				      starget->channel + 'A',
-				      shost->this_id, starget->id, &tstate);
-	spi_period(starget) = tinfo->curr.period;
-}
-
 static void ahc_linux_set_period(struct scsi_target *starget, int period)
 {
 	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
@@ -2674,9 +2355,9 @@ static void ahc_linux_set_period(struct 
 				      starget->channel + 'A',
 				      shost->this_id, starget->id, &tstate);
 	struct ahc_devinfo devinfo;
-	unsigned int ppr_options = tinfo->curr.ppr_options;
+	unsigned int ppr_options = tinfo->goal.ppr_options;
 	unsigned long flags;
-	unsigned long offset = tinfo->curr.offset;
+	unsigned long offset = tinfo->goal.offset;
 	struct ahc_syncrate *syncrate;
 
 	if (offset == 0)
@@ -2692,7 +2373,6 @@ static void ahc_linux_set_period(struct 
 
 	/* all PPR requests apart from QAS require wide transfers */
 	if (ppr_options & ~MSG_EXT_PPR_QAS_REQ) {
-		ahc_linux_get_width(starget);
 		if (spi_width(starget) == 0)
 			ppr_options &= MSG_EXT_PPR_QAS_REQ;
 	}
@@ -2704,18 +2384,6 @@ static void ahc_linux_set_period(struct 
 	ahc_unlock(ahc, &flags);
 }
 
-static void ahc_linux_get_offset(struct scsi_target *starget)
-{
-	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
-	struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata);
-	struct ahc_tmode_tstate *tstate;
-	struct ahc_initiator_tinfo *tinfo 
-		= ahc_fetch_transinfo(ahc,
-				      starget->channel + 'A',
-				      shost->this_id, starget->id, &tstate);
-	spi_offset(starget) = tinfo->curr.offset;
-}
-
 static void ahc_linux_set_offset(struct scsi_target *starget, int offset)
 {
 	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
@@ -2735,8 +2403,8 @@ static void ahc_linux_set_offset(struct 
 			    starget->channel + 'A', ROLE_INITIATOR);
 	if (offset != 0) {
 		syncrate = ahc_find_syncrate(ahc, &period, &ppr_options, AHC_SYNCRATE_DT);
-		period = tinfo->curr.period;
-		ppr_options = tinfo->curr.ppr_options;
+		period = tinfo->goal.period;
+		ppr_options = tinfo->goal.ppr_options;
 	}
 	ahc_lock(ahc, &flags);
 	ahc_set_syncrate(ahc, &devinfo, syncrate, period, offset,
@@ -2744,18 +2412,6 @@ static void ahc_linux_set_offset(struct 
 	ahc_unlock(ahc, &flags);
 }
 
-static void ahc_linux_get_dt(struct scsi_target *starget)
-{
-	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
-	struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata);
-	struct ahc_tmode_tstate *tstate;
-	struct ahc_initiator_tinfo *tinfo 
-		= ahc_fetch_transinfo(ahc,
-				      starget->channel + 'A',
-				      shost->this_id, starget->id, &tstate);
-	spi_dt(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_DT_REQ;
-}
-
 static void ahc_linux_set_dt(struct scsi_target *starget, int dt)
 {
 	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
@@ -2766,15 +2422,17 @@ static void ahc_linux_set_dt(struct scsi
 				      starget->channel + 'A',
 				      shost->this_id, starget->id, &tstate);
 	struct ahc_devinfo devinfo;
-	unsigned int ppr_options = tinfo->curr.ppr_options
+	unsigned int ppr_options = tinfo->goal.ppr_options
 		& ~MSG_EXT_PPR_DT_REQ;
-	unsigned int period = tinfo->curr.period;
+	unsigned int period = tinfo->goal.period;
+	unsigned int width = tinfo->goal.width;
 	unsigned long flags;
 	struct ahc_syncrate *syncrate;
 
 	if (dt) {
-		period = 9;	/* 12.5ns is the only period valid for DT */
 		ppr_options |= MSG_EXT_PPR_DT_REQ;
+		if (!width)
+			ahc_linux_set_width(starget, 1);
 	} else if (period == 9)
 		period = 10;	/* if resetting DT, period must be >= 25ns */
 
@@ -2782,23 +2440,16 @@ static void ahc_linux_set_dt(struct scsi
 			    starget->channel + 'A', ROLE_INITIATOR);
 	syncrate = ahc_find_syncrate(ahc, &period, &ppr_options,AHC_SYNCRATE_DT);
 	ahc_lock(ahc, &flags);
-	ahc_set_syncrate(ahc, &devinfo, syncrate, period, tinfo->curr.offset,
+	ahc_set_syncrate(ahc, &devinfo, syncrate, period, tinfo->goal.offset,
 			 ppr_options, AHC_TRANS_GOAL, FALSE);
 	ahc_unlock(ahc, &flags);
 }
 
-static void ahc_linux_get_qas(struct scsi_target *starget)
-{
-	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
-	struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata);
-	struct ahc_tmode_tstate *tstate;
-	struct ahc_initiator_tinfo *tinfo 
-		= ahc_fetch_transinfo(ahc,
-				      starget->channel + 'A',
-				      shost->this_id, starget->id, &tstate);
-	spi_dt(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_QAS_REQ;
-}
-
+#if 0
+/* FIXME: This code claims to support IU and QAS.  However, the actual
+ * sequencer code and aic7xxx_core have no support for these parameters and
+ * will get into a bad state if they're negotiated.  Do not enable this
+ * unless you know what you're doing */
 static void ahc_linux_set_qas(struct scsi_target *starget, int qas)
 {
 	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
@@ -2809,9 +2460,9 @@ static void ahc_linux_set_qas(struct scs
 				      starget->channel + 'A',
 				      shost->this_id, starget->id, &tstate);
 	struct ahc_devinfo devinfo;
-	unsigned int ppr_options = tinfo->curr.ppr_options
+	unsigned int ppr_options = tinfo->goal.ppr_options
 		& ~MSG_EXT_PPR_QAS_REQ;
-	unsigned int period = tinfo->curr.period;
+	unsigned int period = tinfo->goal.period;
 	unsigned long flags;
 	struct ahc_syncrate *syncrate;
 
@@ -2822,23 +2473,11 @@ static void ahc_linux_set_qas(struct scs
 			    starget->channel + 'A', ROLE_INITIATOR);
 	syncrate = ahc_find_syncrate(ahc, &period, &ppr_options, AHC_SYNCRATE_DT);
 	ahc_lock(ahc, &flags);
-	ahc_set_syncrate(ahc, &devinfo, syncrate, period, tinfo->curr.offset,
+	ahc_set_syncrate(ahc, &devinfo, syncrate, period, tinfo->goal.offset,
 			 ppr_options, AHC_TRANS_GOAL, FALSE);
 	ahc_unlock(ahc, &flags);
 }
 
-static void ahc_linux_get_iu(struct scsi_target *starget)
-{
-	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
-	struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata);
-	struct ahc_tmode_tstate *tstate;
-	struct ahc_initiator_tinfo *tinfo 
-		= ahc_fetch_transinfo(ahc,
-				      starget->channel + 'A',
-				      shost->this_id, starget->id, &tstate);
-	spi_dt(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_IU_REQ;
-}
-
 static void ahc_linux_set_iu(struct scsi_target *starget, int iu)
 {
 	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
@@ -2849,9 +2488,9 @@ static void ahc_linux_set_iu(struct scsi
 				      starget->channel + 'A',
 				      shost->this_id, starget->id, &tstate);
 	struct ahc_devinfo devinfo;
-	unsigned int ppr_options = tinfo->curr.ppr_options
+	unsigned int ppr_options = tinfo->goal.ppr_options
 		& ~MSG_EXT_PPR_IU_REQ;
-	unsigned int period = tinfo->curr.period;
+	unsigned int period = tinfo->goal.period;
 	unsigned long flags;
 	struct ahc_syncrate *syncrate;
 
@@ -2862,30 +2501,27 @@ static void ahc_linux_set_iu(struct scsi
 			    starget->channel + 'A', ROLE_INITIATOR);
 	syncrate = ahc_find_syncrate(ahc, &period, &ppr_options, AHC_SYNCRATE_DT);
 	ahc_lock(ahc, &flags);
-	ahc_set_syncrate(ahc, &devinfo, syncrate, period, tinfo->curr.offset,
+	ahc_set_syncrate(ahc, &devinfo, syncrate, period, tinfo->goal.offset,
 			 ppr_options, AHC_TRANS_GOAL, FALSE);
 	ahc_unlock(ahc, &flags);
 }
+#endif
 
 static struct spi_function_template ahc_linux_transport_functions = {
-	.get_offset	= ahc_linux_get_offset,
 	.set_offset	= ahc_linux_set_offset,
 	.show_offset	= 1,
-	.get_period	= ahc_linux_get_period,
 	.set_period	= ahc_linux_set_period,
 	.show_period	= 1,
-	.get_width	= ahc_linux_get_width,
 	.set_width	= ahc_linux_set_width,
 	.show_width	= 1,
-	.get_dt		= ahc_linux_get_dt,
 	.set_dt		= ahc_linux_set_dt,
 	.show_dt	= 1,
-	.get_iu		= ahc_linux_get_iu,
+#if 0
 	.set_iu		= ahc_linux_set_iu,
 	.show_iu	= 1,
-	.get_qas	= ahc_linux_get_qas,
 	.set_qas	= ahc_linux_set_qas,
 	.show_qas	= 1,
+#endif
 };
 
 
@@ -2893,14 +2529,25 @@ static struct spi_function_template ahc_
 static int __init
 ahc_linux_init(void)
 {
-	ahc_linux_transport_template = spi_attach_transport(&ahc_linux_transport_functions);
+	/*
+	 * If we've been passed any parameters, process them now.
+	 */
+	if (aic7xxx)
+		aic7xxx_setup(aic7xxx);
+
+	ahc_linux_transport_template =
+		spi_attach_transport(&ahc_linux_transport_functions);
 	if (!ahc_linux_transport_template)
 		return -ENODEV;
-	if (ahc_linux_detect(&aic7xxx_driver_template))
-		return 0;
-	spi_release_transport(ahc_linux_transport_template);
-	ahc_linux_exit();
-	return -ENODEV;
+
+	scsi_transport_reserve_target(ahc_linux_transport_template,
+				      sizeof(struct ahc_linux_target));
+	scsi_transport_reserve_device(ahc_linux_transport_template,
+				      sizeof(struct ahc_linux_device));
+
+	ahc_linux_pci_init();
+	ahc_linux_eisa_init();
+	return 0;
 }
 
 static void
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.h b/drivers/scsi/aic7xxx/aic7xxx_osm.h
--- a/drivers/scsi/aic7xxx/aic7xxx_osm.h
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm.h
@@ -79,6 +79,8 @@
 #include <scsi/scsi_device.h>
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_tcq.h>
+#include <scsi/scsi_transport.h>
+#include <scsi/scsi_transport_spi.h>
 
 /* Core SCSI definitions */
 #define AIC_LIB_PREFIX ahc
@@ -127,27 +129,9 @@ typedef struct scsi_cmnd      *ahc_io_ct
 #define ahc_le32toh(x)	le32_to_cpu(x)
 #define ahc_le64toh(x)	le64_to_cpu(x)
 
-#ifndef LITTLE_ENDIAN
-#define LITTLE_ENDIAN 1234
-#endif
-
-#ifndef BIG_ENDIAN
-#define BIG_ENDIAN 4321
-#endif
-
-#ifndef BYTE_ORDER
-#if defined(__BIG_ENDIAN)
-#define BYTE_ORDER BIG_ENDIAN
-#endif
-#if defined(__LITTLE_ENDIAN)
-#define BYTE_ORDER LITTLE_ENDIAN
-#endif
-#endif /* BYTE_ORDER */
-
 /************************* Configuration Data *********************************/
 extern u_int aic7xxx_no_probe;
 extern u_int aic7xxx_allow_memio;
-extern int aic7xxx_detect_complete;
 extern struct scsi_host_template aic7xxx_driver_template;
 
 /***************************** Bus Space/DMA **********************************/
@@ -283,35 +267,6 @@ ahc_scb_timer_reset(struct scb *scb, u_i
 
 #define AIC7XXX_DRIVER_VERSION "6.2.36"
 
-/**************************** Front End Queues ********************************/
-/*
- * Data structure used to cast the Linux struct scsi_cmnd to something
- * that allows us to use the queue macros.  The linux structure has
- * plenty of space to hold the links fields as required by the queue
- * macros, but the queue macors require them to have the correct type.
- */
-struct ahc_cmd_internal {
-	/* Area owned by the Linux scsi layer. */
-	uint8_t	private[offsetof(struct scsi_cmnd, SCp.Status)];
-	union {
-		STAILQ_ENTRY(ahc_cmd)	ste;
-		LIST_ENTRY(ahc_cmd)	le;
-		TAILQ_ENTRY(ahc_cmd)	tqe;
-	} links;
-	uint32_t			end;
-};
-
-struct ahc_cmd {
-	union {
-		struct ahc_cmd_internal	icmd;
-		struct scsi_cmnd	scsi_cmd;
-	} un;
-};
-
-#define acmd_icmd(cmd) ((cmd)->un.icmd)
-#define acmd_scsi_cmd(cmd) ((cmd)->un.scsi_cmd)
-#define acmd_links un.icmd.links
-
 /*************************** Device Data Structures ***************************/
 /*
  * A per probed device structure used to deal with some error recovery
@@ -320,7 +275,6 @@ struct ahc_cmd {
  * after a successfully completed inquiry command to the target when
  * that inquiry data indicates a lun is present.
  */
-TAILQ_HEAD(ahc_busyq, ahc_cmd);
 typedef enum {
 	AHC_DEV_FREEZE_TIL_EMPTY = 0x02, /* Freeze queue until active == 0 */
 	AHC_DEV_Q_BASIC		 = 0x10, /* Allow basic device queuing */
@@ -330,8 +284,6 @@ typedef enum {
 
 struct ahc_linux_target;
 struct ahc_linux_device {
-	TAILQ_ENTRY(ahc_linux_device) links;
-
 	/*
 	 * The number of transactions currently
 	 * queued to the device.
@@ -401,17 +353,10 @@ struct ahc_linux_device {
 	 */
 	u_int			commands_since_idle_or_otag;
 #define AHC_OTAG_THRESH	500
-
-	int			lun;
-	struct scsi_device       *scsi_device;
-	struct			ahc_linux_target *target;
 };
 
 struct ahc_linux_target {
-	struct ahc_linux_device	 *devices[AHC_NUM_LUNS];
-	int			  channel;
-	int			  target;
-	int			  refcount;
+	struct scsi_device	 *sdev[AHC_NUM_LUNS];
 	struct ahc_transinfo	  last_tinfo;
 	struct ahc_softc	 *ahc;
 };
@@ -445,7 +390,7 @@ struct ahc_platform_data {
 	/*
 	 * Fields accessed from interrupt context.
 	 */
-	struct ahc_linux_target *targets[AHC_NUM_TARGETS]; 
+	struct scsi_target *starget[AHC_NUM_TARGETS]; 
 
 	spinlock_t		 spin_lock;
 	u_int			 qfrozen;
@@ -564,15 +509,6 @@ void	ahc_format_transinfo(struct info_st
 
 /******************************** Locking *************************************/
 /* Lock protecting internal data structures */
-static __inline void ahc_lockinit(struct ahc_softc *);
-static __inline void ahc_lock(struct ahc_softc *, unsigned long *flags);
-static __inline void ahc_unlock(struct ahc_softc *, unsigned long *flags);
-
-/* Lock held during ahc_list manipulation and ahc softc frees */
-extern spinlock_t ahc_list_spinlock;
-static __inline void ahc_list_lockinit(void);
-static __inline void ahc_list_lock(unsigned long *flags);
-static __inline void ahc_list_unlock(unsigned long *flags);
 
 static __inline void
 ahc_lockinit(struct ahc_softc *ahc)
@@ -592,24 +528,6 @@ ahc_unlock(struct ahc_softc *ahc, unsign
 	spin_unlock_irqrestore(&ahc->platform_data->spin_lock, *flags);
 }
 
-static __inline void
-ahc_list_lockinit(void)
-{
-	spin_lock_init(&ahc_list_spinlock);
-}
-
-static __inline void
-ahc_list_lock(unsigned long *flags)
-{
-	spin_lock_irqsave(&ahc_list_spinlock, *flags);
-}
-
-static __inline void
-ahc_list_unlock(unsigned long *flags)
-{
-	spin_unlock_irqrestore(&ahc_list_spinlock, *flags);
-}
-
 /******************************* PCI Definitions ******************************/
 /*
  * PCIM_xxx: mask to locate subfield in register
@@ -659,7 +577,6 @@ typedef enum
 
 /**************************** VL/EISA Routines ********************************/
 #ifdef CONFIG_EISA
-extern uint32_t aic7xxx_probe_eisa_vl;
 int			 ahc_linux_eisa_init(void);
 void			 ahc_linux_eisa_exit(void);
 int			 aic7770_map_registers(struct ahc_softc *ahc,
@@ -924,7 +841,6 @@ ahc_notify_xfer_settings_change(struct a
 static __inline void
 ahc_platform_scb_free(struct ahc_softc *ahc, struct scb *scb)
 {
-	ahc->flags &= ~AHC_RESOURCE_SHORTAGE;
 }
 
 int	ahc_platform_alloc(struct ahc_softc *ahc, void *platform_arg);
@@ -948,7 +864,6 @@ int	ahc_platform_abort_scbs(struct ahc_s
 irqreturn_t
 	ahc_linux_isr(int irq, void *dev_id, struct pt_regs * regs);
 void	ahc_platform_flushwork(struct ahc_softc *ahc);
-int	ahc_softc_comp(struct ahc_softc *, struct ahc_softc *);
 void	ahc_done(struct ahc_softc*, struct scb*);
 void	ahc_send_async(struct ahc_softc *, char channel,
 		       u_int target, u_int lun, ac_code, void *);
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c b/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c
--- a/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c
@@ -140,27 +140,13 @@ struct pci_driver aic7xxx_pci_driver = {
 static void
 ahc_linux_pci_dev_remove(struct pci_dev *pdev)
 {
-	struct ahc_softc *ahc;
-	u_long l;
+	struct ahc_softc *ahc = pci_get_drvdata(pdev);
+	u_long s;
 
-	/*
-	 * We should be able to just perform
-	 * the free directly, but check our
-	 * list for extra sanity.
-	 */
-	ahc_list_lock(&l);
-	ahc = ahc_find_softc((struct ahc_softc *)pci_get_drvdata(pdev));
-	if (ahc != NULL) {
-		u_long s;
-
-		TAILQ_REMOVE(&ahc_tailq, ahc, links);
-		ahc_list_unlock(&l);
-		ahc_lock(ahc, &s);
-		ahc_intr_enable(ahc, FALSE);
-		ahc_unlock(ahc, &s);
-		ahc_free(ahc);
-	} else
-		ahc_list_unlock(&l);
+	ahc_lock(ahc, &s);
+	ahc_intr_enable(ahc, FALSE);
+	ahc_unlock(ahc, &s);
+	ahc_free(ahc);
 }
 
 static int
@@ -174,22 +160,6 @@ ahc_linux_pci_dev_probe(struct pci_dev *
 	char		*name;
 	int		 error;
 
-	/*
-	 * Some BIOSen report the same device multiple times.
-	 */
-	TAILQ_FOREACH(ahc, &ahc_tailq, links) {
-		struct pci_dev *probed_pdev;
-
-		probed_pdev = ahc->dev_softc;
-		if (probed_pdev->bus->number == pdev->bus->number
-		 && probed_pdev->devfn == pdev->devfn)
-			break;
-	}
-	if (ahc != NULL) {
-		/* Skip duplicate. */
-		return (-ENODEV);
-	}
-
 	pci = pdev;
 	entry = ahc_find_pci_device(pci);
 	if (entry == NULL)
@@ -234,8 +204,7 @@ ahc_linux_pci_dev_probe(struct pci_dev *
 		return (-error);
 	}
 	pci_set_drvdata(pdev, ahc);
-	if (aic7xxx_detect_complete)
-		ahc_linux_register_host(ahc, &aic7xxx_driver_template);
+	ahc_linux_register_host(ahc, &aic7xxx_driver_template);
 	return (0);
 }
 
diff --git a/drivers/scsi/aic7xxx/aic7xxx_pci.c b/drivers/scsi/aic7xxx/aic7xxx_pci.c
--- a/drivers/scsi/aic7xxx/aic7xxx_pci.c
+++ b/drivers/scsi/aic7xxx/aic7xxx_pci.c
@@ -704,7 +704,6 @@ ahc_find_pci_device(ahc_dev_softc_t pci)
 int
 ahc_pci_config(struct ahc_softc *ahc, struct ahc_pci_identity *entry)
 {
-	u_long	 l;
 	u_int	 command;
 	u_int	 our_id;
 	u_int	 sxfrctl1;
@@ -964,12 +963,7 @@ ahc_pci_config(struct ahc_softc *ahc, st
 	if (error != 0)
 		return (error);
 
-	ahc_list_lock(&l);
-	/*
-	 * Link this softc in with all other ahc instances.
-	 */
-	ahc_softc_insert(ahc);
-	ahc_list_unlock(&l);
+	ahc->init_level++;
 	return (0);
 }
 
diff --git a/drivers/scsi/aic7xxx/aic7xxx_proc.c b/drivers/scsi/aic7xxx/aic7xxx_proc.c
--- a/drivers/scsi/aic7xxx/aic7xxx_proc.c
+++ b/drivers/scsi/aic7xxx/aic7xxx_proc.c
@@ -50,7 +50,7 @@ static void	ahc_dump_target_state(struct
 				      u_int our_id, char channel,
 				      u_int target_id, u_int target_offset);
 static void	ahc_dump_device_state(struct info_str *info,
-				      struct ahc_linux_device *dev);
+				      struct scsi_device *dev);
 static int	ahc_proc_write_seeprom(struct ahc_softc *ahc,
 				       char *buffer, int length);
 
@@ -142,6 +142,7 @@ ahc_dump_target_state(struct ahc_softc *
 		      u_int target_offset)
 {
 	struct	ahc_linux_target *targ;
+	struct	scsi_target *starget;
 	struct	ahc_initiator_tinfo *tinfo;
 	struct	ahc_tmode_tstate *tstate;
 	int	lun;
@@ -153,9 +154,10 @@ ahc_dump_target_state(struct ahc_softc *
 	copy_info(info, "Target %d Negotiation Settings\n", target_id);
 	copy_info(info, "\tUser: ");
 	ahc_format_transinfo(info, &tinfo->user);
-	targ = ahc->platform_data->targets[target_offset];
-	if (targ == NULL)
+	starget = ahc->platform_data->starget[target_offset];
+	if (!starget)
 		return;
+	targ = scsi_transport_target_data(starget);
 
 	copy_info(info, "\tGoal: ");
 	ahc_format_transinfo(info, &tinfo->goal);
@@ -163,22 +165,25 @@ ahc_dump_target_state(struct ahc_softc *
 	ahc_format_transinfo(info, &tinfo->curr);
 
 	for (lun = 0; lun < AHC_NUM_LUNS; lun++) {
-		struct ahc_linux_device *dev;
+		struct scsi_device *sdev;
 
-		dev = targ->devices[lun];
+		sdev = targ->sdev[lun];
 
-		if (dev == NULL)
+		if (sdev == NULL)
 			continue;
 
-		ahc_dump_device_state(info, dev);
+		ahc_dump_device_state(info, sdev);
 	}
 }
 
 static void
-ahc_dump_device_state(struct info_str *info, struct ahc_linux_device *dev)
+ahc_dump_device_state(struct info_str *info, struct scsi_device *sdev)
 {
+	struct ahc_linux_device *dev = scsi_transport_device_data(sdev);
+
 	copy_info(info, "\tChannel %c Target %d Lun %d Settings\n",
-		  dev->target->channel + 'A', dev->target->target, dev->lun);
+		  sdev->sdev_target->channel + 'A',
+		  sdev->sdev_target->id, sdev->lun);
 
 	copy_info(info, "\t\tCommands Queued %ld\n", dev->commands_issued);
 	copy_info(info, "\t\tCommands Active %d\n", dev->active);
@@ -292,20 +297,13 @@ int
 ahc_linux_proc_info(struct Scsi_Host *shost, char *buffer, char **start,
 		    off_t offset, int length, int inout)
 {
-	struct	ahc_softc *ahc;
+	struct	ahc_softc *ahc = *(struct ahc_softc **)shost->hostdata;
 	struct	info_str info;
 	char	ahc_info[256];
-	u_long	s;
 	u_int	max_targ;
 	u_int	i;
 	int	retval;
 
-	retval = -EINVAL;
-	ahc_list_lock(&s);
-	ahc = ahc_find_softc(*(struct ahc_softc **)shost->hostdata);
-	if (ahc == NULL)
-		goto done;
-
 	 /* Has data been written to the file? */ 
 	if (inout == TRUE) {
 		retval = ahc_proc_write_seeprom(ahc, buffer, length);
@@ -367,6 +365,5 @@ ahc_linux_proc_info(struct Scsi_Host *sh
 	}
 	retval = info.pos > info.offset ? info.pos - info.offset : 0;
 done:
-	ahc_list_unlock(&s);
 	return (retval);
 }
diff --git a/drivers/scsi/aic7xxx/aicasm/aicasm.c b/drivers/scsi/aic7xxx/aicasm/aicasm.c
--- a/drivers/scsi/aic7xxx/aicasm/aicasm.c
+++ b/drivers/scsi/aic7xxx/aicasm/aicasm.c
@@ -369,7 +369,7 @@ output_code()
 
 		fprintf(ofile, "%s\t0x%02x, 0x%02x, 0x%02x, 0x%02x",
 			cur_instr == STAILQ_FIRST(&seq_program) ? "" : ",\n",
-#if BYTE_ORDER == LITTLE_ENDIAN
+#ifdef __LITTLE_ENDIAN
 			cur_instr->format.bytes[0],
 			cur_instr->format.bytes[1],
 			cur_instr->format.bytes[2],
@@ -613,7 +613,7 @@ output_listing(char *ifilename)
 				line++;
 		}
 		fprintf(listfile, "%03x %02x%02x%02x%02x", instrptr,
-#if BYTE_ORDER == LITTLE_ENDIAN
+#ifdef __LITTLE_ENDIAN
 			cur_instr->format.bytes[0],
 			cur_instr->format.bytes[1],
 			cur_instr->format.bytes[2],
diff --git a/drivers/scsi/aic7xxx/aicasm/aicasm_insformat.h b/drivers/scsi/aic7xxx/aicasm/aicasm_insformat.h
--- a/drivers/scsi/aic7xxx/aicasm/aicasm_insformat.h
+++ b/drivers/scsi/aic7xxx/aicasm/aicasm_insformat.h
@@ -42,8 +42,10 @@
  * $FreeBSD$
  */
 
+#include <asm/byteorder.h>
+
 struct ins_format1 {
-#if BYTE_ORDER == LITTLE_ENDIAN
+#ifdef __LITTLE_ENDIAN
 	uint32_t	immediate	: 8,
 			source		: 9,
 			destination	: 9,
@@ -61,7 +63,7 @@ struct ins_format1 {
 };
 
 struct ins_format2 {
-#if BYTE_ORDER == LITTLE_ENDIAN
+#ifdef __LITTLE_ENDIAN
 	uint32_t	shift_control	: 8,
 			source		: 9,
 			destination	: 9,
@@ -79,7 +81,7 @@ struct ins_format2 {
 };
 
 struct ins_format3 {
-#if BYTE_ORDER == LITTLE_ENDIAN
+#ifdef __LITTLE_ENDIAN
 	uint32_t	immediate	: 8,
 			source		: 9,
 			address		: 10,
diff --git a/drivers/scsi/aic7xxx_old.c b/drivers/scsi/aic7xxx_old.c
--- a/drivers/scsi/aic7xxx_old.c
+++ b/drivers/scsi/aic7xxx_old.c
@@ -8448,7 +8448,6 @@ aic7xxx_alloc(Scsi_Host_Template *sht, s
     }
     p->host_no = host->host_no;
   }
-  scsi_set_device(host, &p->pdev->dev);
   return (p);
 }
 
@@ -10358,7 +10357,7 @@ aic7xxx_queue(Scsi_Cmnd *cmd, void (*fn)
  *   Returns an enumerated type that indicates the status of the operation.
  *-F*************************************************************************/
 static int
-aic7xxx_bus_device_reset(Scsi_Cmnd *cmd)
+__aic7xxx_bus_device_reset(Scsi_Cmnd *cmd)
 {
   struct aic7xxx_host  *p;
   struct aic7xxx_scb   *scb;
@@ -10551,6 +10550,18 @@ aic7xxx_bus_device_reset(Scsi_Cmnd *cmd)
     return SUCCESS;
 }
 
+static int
+aic7xxx_bus_device_reset(Scsi_Cmnd *cmd)
+{
+      int rc;
+
+      spin_lock_irq(cmd->device->host->host_lock);
+      rc = __aic7xxx_bus_device_reset(cmd);
+      spin_unlock_irq(cmd->device->host->host_lock);
+
+      return rc;
+}
+
 
 /*+F*************************************************************************
  * Function:
@@ -10585,7 +10596,7 @@ aic7xxx_panic_abort(struct aic7xxx_host 
  *   Abort the current SCSI command(s).
  *-F*************************************************************************/
 static int
-aic7xxx_abort(Scsi_Cmnd *cmd)
+__aic7xxx_abort(Scsi_Cmnd *cmd)
 {
   struct aic7xxx_scb  *scb = NULL;
   struct aic7xxx_host *p;
@@ -10802,6 +10813,19 @@ success:
   return SUCCESS;
 }
 
+static int
+aic7xxx_abort(Scsi_Cmnd *cmd)
+{
+	int rc;
+
+	spin_lock_irq(cmd->device->host->host_lock);
+	rc = __aic7xxx_abort(cmd);
+	spin_unlock_irq(cmd->device->host->host_lock);
+
+	return rc;
+}
+
+
 /*+F*************************************************************************
  * Function:
  *   aic7xxx_reset
@@ -10820,6 +10844,8 @@ aic7xxx_reset(Scsi_Cmnd *cmd)
   struct aic_dev_data *aic_dev;
 
   p = (struct aic7xxx_host *) cmd->device->host->hostdata;
+  spin_lock_irq(p->host->host_lock);
+
   aic_dev = AIC_DEV(cmd);
   if(aic7xxx_position(cmd) < p->scb_data->numscbs)
   {
@@ -10859,6 +10885,7 @@ aic7xxx_reset(Scsi_Cmnd *cmd)
      * longer have it.
      */
     unpause_sequencer(p, FALSE);
+    spin_unlock_irq(p->host->host_lock);
     return SUCCESS;
   }
     
@@ -10882,7 +10909,6 @@ aic7xxx_reset(Scsi_Cmnd *cmd)
   unpause_sequencer(p, FALSE);
   spin_unlock_irq(p->host->host_lock);
   ssleep(2);
-  spin_lock_irq(p->host->host_lock);
   return SUCCESS;
 }
 
diff --git a/drivers/scsi/arm/Kconfig b/drivers/scsi/arm/Kconfig
--- a/drivers/scsi/arm/Kconfig
+++ b/drivers/scsi/arm/Kconfig
@@ -3,7 +3,7 @@
 #
 config SCSI_ACORNSCSI_3
 	tristate "Acorn SCSI card (aka30) support"
-	depends on ARCH_ACORN && SCSI
+	depends on ARCH_ACORN && SCSI && BROKEN
 	help
 	  This enables support for the Acorn SCSI card (aka30). If you have an
 	  Acorn system with one of these, say Y. If unsure, say N.
diff --git a/drivers/scsi/arm/cumana_1.c b/drivers/scsi/arm/cumana_1.c
--- a/drivers/scsi/arm/cumana_1.c
+++ b/drivers/scsi/arm/cumana_1.c
@@ -244,9 +244,7 @@ static Scsi_Host_Template cumanascsi_tem
 	.info			= cumanascsi_info,
 	.queuecommand		= cumanascsi_queue_command,
 	.eh_abort_handler	= NCR5380_abort,
-	.eh_device_reset_handler= NCR5380_device_reset,
 	.eh_bus_reset_handler	= NCR5380_bus_reset,
-	.eh_host_reset_handler	= NCR5380_host_reset,
 	.can_queue		= 16,
 	.this_id		= 7,
 	.sg_tablesize		= SG_ALL,
diff --git a/drivers/scsi/arm/ecoscsi.c b/drivers/scsi/arm/ecoscsi.c
--- a/drivers/scsi/arm/ecoscsi.c
+++ b/drivers/scsi/arm/ecoscsi.c
@@ -162,9 +162,7 @@ static Scsi_Host_Template ecoscsi_templa
 	.info		= ecoscsi_info,
 	.queuecommand	= ecoscsi_queue_command,
 	.eh_abort_handler	= NCR5380_abort,
-	.eh_device_reset_handler= NCR5380_device_reset,
 	.eh_bus_reset_handler	= NCR5380_bus_reset,
-	.eh_host_reset_handler	= NCR5380_host_reset,
 	.can_queue	= 16,
 	.this_id	= 7,
 	.sg_tablesize	= SG_ALL,
diff --git a/drivers/scsi/arm/eesox.c b/drivers/scsi/arm/eesox.c
--- a/drivers/scsi/arm/eesox.c
+++ b/drivers/scsi/arm/eesox.c
@@ -466,7 +466,7 @@ int eesoxscsi_proc_info(struct Scsi_Host
 	return pos;
 }
 
-static ssize_t eesoxscsi_show_term(struct device *dev, char *buf)
+static ssize_t eesoxscsi_show_term(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct expansion_card *ec = ECARD_DEV(dev);
 	struct Scsi_Host *host = ecard_get_drvdata(ec);
@@ -475,7 +475,7 @@ static ssize_t eesoxscsi_show_term(struc
 	return sprintf(buf, "%d\n", info->control & EESOX_TERM_ENABLE ? 1 : 0);
 }
 
-static ssize_t eesoxscsi_store_term(struct device *dev, const char *buf, size_t len)
+static ssize_t eesoxscsi_store_term(struct device *dev, struct device_attribute *attr, const char *buf, size_t len)
 {
 	struct expansion_card *ec = ECARD_DEV(dev);
 	struct Scsi_Host *host = ecard_get_drvdata(ec);
diff --git a/drivers/scsi/arm/fas216.c b/drivers/scsi/arm/fas216.c
--- a/drivers/scsi/arm/fas216.c
+++ b/drivers/scsi/arm/fas216.c
@@ -2659,6 +2659,8 @@ int fas216_eh_host_reset(Scsi_Cmnd *SCpn
 {
 	FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata;
 
+	spin_lock_irq(info->host->host_lock);
+
 	fas216_checkmagic(info);
 
 	printk("scsi%d.%c: %s: resetting host\n",
@@ -2686,6 +2688,7 @@ int fas216_eh_host_reset(Scsi_Cmnd *SCpn
 
 	fas216_init_chip(info);
 
+	spin_unlock_irq(info->host->host_lock);
 	return SUCCESS;
 }
 
diff --git a/drivers/scsi/arm/oak.c b/drivers/scsi/arm/oak.c
--- a/drivers/scsi/arm/oak.c
+++ b/drivers/scsi/arm/oak.c
@@ -118,9 +118,7 @@ static Scsi_Host_Template oakscsi_templa
 	.info			= oakscsi_info,
 	.queuecommand		= oakscsi_queue_command,
 	.eh_abort_handler	= NCR5380_abort,
-	.eh_device_reset_handler= NCR5380_device_reset,
 	.eh_bus_reset_handler	= NCR5380_bus_reset,
-	.eh_host_reset_handler	= NCR5380_host_reset,
 	.can_queue		= 16,
 	.this_id		= 7,
 	.sg_tablesize		= SG_ALL,
diff --git a/drivers/scsi/arm/powertec.c b/drivers/scsi/arm/powertec.c
--- a/drivers/scsi/arm/powertec.c
+++ b/drivers/scsi/arm/powertec.c
@@ -269,7 +269,7 @@ int powertecscsi_proc_info(struct Scsi_H
 	return pos;
 }
 
-static ssize_t powertecscsi_show_term(struct device *dev, char *buf)
+static ssize_t powertecscsi_show_term(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct expansion_card *ec = ECARD_DEV(dev);
 	struct Scsi_Host *host = ecard_get_drvdata(ec);
@@ -279,7 +279,7 @@ static ssize_t powertecscsi_show_term(st
 }
 
 static ssize_t
-powertecscsi_store_term(struct device *dev, const char *buf, size_t len)
+powertecscsi_store_term(struct device *dev, struct device_attribute *attr, const char *buf, size_t len)
 {
 	struct expansion_card *ec = ECARD_DEV(dev);
 	struct Scsi_Host *host = ecard_get_drvdata(ec);
diff --git a/drivers/scsi/ata_piix.c b/drivers/scsi/ata_piix.c
--- a/drivers/scsi/ata_piix.c
+++ b/drivers/scsi/ata_piix.c
@@ -32,12 +32,13 @@
 #include <linux/libata.h>
 
 #define DRV_NAME	"ata_piix"
-#define DRV_VERSION	"1.03"
+#define DRV_VERSION	"1.04"
 
 enum {
 	PIIX_IOCFG		= 0x54, /* IDE I/O configuration register */
 	ICH5_PMR		= 0x90, /* port mapping register */
 	ICH5_PCS		= 0x92,	/* port control and status */
+	PIIX_SCC		= 0x0A, /* sub-class code register */
 
 	PIIX_FLAG_AHCI		= (1 << 28), /* AHCI possible */
 	PIIX_FLAG_CHECKINTR	= (1 << 29), /* make sure PCI INTx enabled */
@@ -62,6 +63,8 @@ enum {
 	ich6_sata_rm		= 4,
 	ich7_sata		= 5,
 	esb2_sata		= 6,
+
+	PIIX_AHCI_DEVICE	= 6,
 };
 
 static int piix_init_one (struct pci_dev *pdev,
@@ -574,11 +577,11 @@ static int piix_disable_ahci(struct pci_
 	addr = pci_resource_start(pdev, AHCI_PCI_BAR);
 	if (!addr || !pci_resource_len(pdev, AHCI_PCI_BAR))
 		return 0;
-	
+
 	mmio = ioremap(addr, 64);
 	if (!mmio)
 		return -ENOMEM;
-	
+
 	tmp = readl(mmio + AHCI_GLOBAL_CTL);
 	if (tmp & AHCI_ENABLE) {
 		tmp &= ~AHCI_ENABLE;
@@ -588,7 +591,7 @@ static int piix_disable_ahci(struct pci_
 		if (tmp & AHCI_ENABLE)
 			rc = -EIO;
 	}
-	
+
 	iounmap(mmio);
 	return rc;
 }
@@ -626,9 +629,13 @@ static int piix_init_one (struct pci_dev
 	port_info[1] = NULL;
 
 	if (port_info[0]->host_flags & PIIX_FLAG_AHCI) {
-		int rc = piix_disable_ahci(pdev);
-		if (rc)
-			return rc;
+               u8 tmp;
+               pci_read_config_byte(pdev, PIIX_SCC, &tmp);
+               if (tmp == PIIX_AHCI_DEVICE) {
+                       int rc = piix_disable_ahci(pdev);
+                       if (rc)
+                           return rc;
+               }
 	}
 
 	if (port_info[0]->host_flags & PIIX_FLAG_COMBINED) {
diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c
--- a/drivers/scsi/atp870u.c
+++ b/drivers/scsi/atp870u.c
@@ -3146,8 +3146,8 @@ static const char *atp870u_info(struct S
 }
 
 #define BLS buffer + len + size
-int atp870u_proc_info(struct Scsi_Host *HBAptr, char *buffer, 
-		      char **start, off_t offset, int length, int inout)
+static int atp870u_proc_info(struct Scsi_Host *HBAptr, char *buffer, 
+			     char **start, off_t offset, int length, int inout)
 {
 	static u8 buff[512];
 	int size = 0;
diff --git a/drivers/scsi/ch.c b/drivers/scsi/ch.c
new file mode 100644
--- /dev/null
+++ b/drivers/scsi/ch.c
@@ -0,0 +1,1026 @@
+/*
+ * SCSI Media Changer device driver for Linux 2.6
+ *
+ *     (c) 1996-2003 Gerd Knorr <kraxel@bytesex.org>
+ *
+ */
+
+#define VERSION "0.25"
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/major.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/blkdev.h>
+#include <linux/completion.h>
+#include <linux/devfs_fs_kernel.h>
+#include <linux/ioctl32.h>
+#include <linux/compat.h>
+#include <linux/chio.h>			/* here are all the ioctls */
+
+#include <scsi/scsi.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_driver.h>
+#include <scsi/scsi_ioctl.h>
+#include <scsi/scsi_host.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_request.h>
+#include <scsi/scsi_dbg.h>
+
+#define CH_DT_MAX       16
+#define CH_TYPES        8
+
+MODULE_DESCRIPTION("device driver for scsi media changer devices");
+MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org>");
+MODULE_LICENSE("GPL");
+
+static int init = 1;
+module_param(init, int, 0444);
+MODULE_PARM_DESC(init, \
+    "initialize element status on driver load (default: on)");
+
+static int timeout_move = 300;
+module_param(timeout_move, int, 0644);
+MODULE_PARM_DESC(timeout_move,"timeout for move commands "
+		 "(default: 300 seconds)");
+
+static int timeout_init = 3600;
+module_param(timeout_init, int, 0644);
+MODULE_PARM_DESC(timeout_init,"timeout for INITIALIZE ELEMENT STATUS "
+		 "(default: 3600 seconds)");
+
+static int verbose = 1;
+module_param(verbose, int, 0644);
+MODULE_PARM_DESC(verbose,"be verbose (default: on)");
+
+static int debug = 0;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug,"enable/disable debug messages, also prints more "
+		 "detailed sense codes on scsi errors (default: off)");
+
+static int dt_id[CH_DT_MAX] = { [ 0 ... (CH_DT_MAX-1) ] = -1 };
+static int dt_lun[CH_DT_MAX];
+module_param_array(dt_id,  int, NULL, 0444);
+module_param_array(dt_lun, int, NULL, 0444);
+
+/* tell the driver about vendor-specific slots */
+static int vendor_firsts[CH_TYPES-4];
+static int vendor_counts[CH_TYPES-4];
+module_param_array(vendor_firsts, int, NULL, 0444);
+module_param_array(vendor_counts, int, NULL, 0444);
+
+static char *vendor_labels[CH_TYPES-4] = {
+	"v0", "v1", "v2", "v3"
+};
+// module_param_string_array(vendor_labels, NULL, 0444);
+
+#define dprintk(fmt, arg...)    if (debug) \
+        printk(KERN_DEBUG "%s: " fmt, ch->name , ## arg)
+#define vprintk(fmt, arg...)    if (verbose) \
+        printk(KERN_INFO "%s: " fmt, ch->name , ## arg)
+
+/* ------------------------------------------------------------------- */
+
+#define MAX_RETRIES   1
+
+static int  ch_probe(struct device *);
+static int  ch_remove(struct device *);
+static int  ch_open(struct inode * inode, struct file * filp);
+static int  ch_release(struct inode * inode, struct file * filp);
+static int  ch_ioctl(struct inode * inode, struct file * filp,
+		     unsigned int cmd, unsigned long arg);
+#ifdef CONFIG_COMPAT
+static long ch_ioctl_compat(struct file * filp,
+			    unsigned int cmd, unsigned long arg);
+#endif
+
+static struct class * ch_sysfs_class;
+
+typedef struct {
+	struct list_head    list;
+	int                 minor;
+	char                name[8];
+	struct scsi_device  *device;
+	struct scsi_device  **dt;        /* ptrs to data transfer elements */
+	u_int               firsts[CH_TYPES];
+	u_int               counts[CH_TYPES];
+	u_int               unit_attention;
+	u_int		    voltags;
+	struct semaphore    lock;
+} scsi_changer;
+
+static LIST_HEAD(ch_devlist);
+static spinlock_t ch_devlist_lock = SPIN_LOCK_UNLOCKED;
+static int ch_devcount;
+
+static struct scsi_driver ch_template =
+{
+	.owner     	= THIS_MODULE,
+	.gendrv     	= {
+		.name	= "ch",
+		.probe  = ch_probe,
+		.remove = ch_remove,
+	},
+};
+
+static struct file_operations changer_fops =
+{
+	.owner        = THIS_MODULE,
+	.open         = ch_open,
+	.release      = ch_release,
+	.ioctl        = ch_ioctl,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl = ch_ioctl_compat,
+#endif
+};
+
+static struct {
+	unsigned char  sense;
+	unsigned char  asc;
+	unsigned char  ascq;
+	int	       errno;
+} err[] = {
+/* Just filled in what looks right. Hav'nt checked any standard paper for
+   these errno assignments, so they may be wrong... */
+	{
+		.sense  = ILLEGAL_REQUEST,
+		.asc    = 0x21,
+		.ascq   = 0x01,
+		.errno  = EBADSLT, /* Invalid element address */
+	},{
+		.sense  = ILLEGAL_REQUEST,
+		.asc    = 0x28,
+		.ascq   = 0x01,
+		.errno  = EBADE,   /* Import or export element accessed */
+	},{
+		.sense  = ILLEGAL_REQUEST,
+		.asc    = 0x3B,
+		.ascq   = 0x0D,
+		.errno  = EXFULL,  /* Medium destination element full */
+	},{
+		.sense  = ILLEGAL_REQUEST,
+		.asc    = 0x3B,
+		.ascq   = 0x0E,
+		.errno  = EBADE,   /* Medium source element empty */
+	},{
+		.sense  = ILLEGAL_REQUEST,
+		.asc    = 0x20,
+		.ascq   = 0x00,
+		.errno  = EBADRQC, /* Invalid command operation code */
+	},{
+	        /* end of list */
+	}
+};
+
+/* ------------------------------------------------------------------- */
+
+static int ch_find_errno(unsigned char *sense_buffer)
+{
+	int i,errno = 0;
+
+	/* Check to see if additional sense information is available */
+	if (sense_buffer[7]  > 5 &&
+	    sense_buffer[12] != 0) {
+		for (i = 0; err[i].errno != 0; i++) {
+			if (err[i].sense == sense_buffer[ 2] &&
+			    err[i].asc   == sense_buffer[12] &&
+			    err[i].ascq  == sense_buffer[13]) {
+				errno = -err[i].errno;
+				break;
+			}
+		}
+	}
+	if (errno == 0)
+		errno = -EIO;
+	return errno;
+}
+
+static int
+ch_do_scsi(scsi_changer *ch, unsigned char *cmd,
+	   void *buffer, unsigned buflength,
+	   enum dma_data_direction direction)
+{
+	int errno, retries = 0, timeout;
+	struct scsi_request *sr;
+	
+	sr = scsi_allocate_request(ch->device, GFP_KERNEL);
+	if (NULL == sr)
+		return -ENOMEM;
+
+	timeout = (cmd[0] == INITIALIZE_ELEMENT_STATUS)
+		? timeout_init : timeout_move;
+
+ retry:
+	errno = 0;
+	if (debug) {
+		dprintk("command: ");
+		__scsi_print_command(cmd);
+	}
+
+        scsi_wait_req(sr, cmd, buffer, buflength,
+		      timeout * HZ, MAX_RETRIES);
+
+	dprintk("result: 0x%x\n",sr->sr_result);
+	if (driver_byte(sr->sr_result) & DRIVER_SENSE) {
+		if (debug)
+			scsi_print_req_sense(ch->name, sr);
+		errno = ch_find_errno(sr->sr_sense_buffer);
+
+		switch(sr->sr_sense_buffer[2] & 0xf) {
+		case UNIT_ATTENTION:
+			ch->unit_attention = 1;
+			if (retries++ < 3)
+				goto retry;
+			break;
+		}
+	}
+	scsi_release_request(sr);
+	return errno;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static int
+ch_elem_to_typecode(scsi_changer *ch, u_int elem)
+{
+	int i;
+	
+	for (i = 0; i < CH_TYPES; i++) {
+		if (elem >= ch->firsts[i]  &&
+		    elem <  ch->firsts[i] +
+	            ch->counts[i])
+			return i+1;
+	}
+	return 0;
+}
+
+static int
+ch_read_element_status(scsi_changer *ch, u_int elem, char *data)
+{
+	u_char  cmd[12];
+	u_char  *buffer;
+	int     result;
+	
+	buffer = kmalloc(512, GFP_KERNEL | GFP_DMA);
+	if(!buffer)
+		return -ENOMEM;
+	
+ retry:
+	memset(cmd,0,sizeof(cmd));
+	cmd[0] = READ_ELEMENT_STATUS;
+	cmd[1] = (ch->device->lun << 5) | 
+		(ch->voltags ? 0x10 : 0) |
+		ch_elem_to_typecode(ch,elem);
+	cmd[2] = (elem >> 8) & 0xff;
+	cmd[3] = elem        & 0xff;
+	cmd[5] = 1;
+	cmd[9] = 255;
+	if (0 == (result = ch_do_scsi(ch, cmd, buffer, 256, DMA_FROM_DEVICE))) {
+		if (((buffer[16] << 8) | buffer[17]) != elem) {
+			dprintk("asked for element 0x%02x, got 0x%02x\n",
+				elem,(buffer[16] << 8) | buffer[17]);
+			kfree(buffer);
+			return -EIO;
+		}
+		memcpy(data,buffer+16,16);
+	} else {
+		if (ch->voltags) {
+			ch->voltags = 0;
+			vprintk("device has no volume tag support\n");
+			goto retry;
+		}
+		dprintk("READ ELEMENT STATUS for element 0x%x failed\n",elem);
+	}
+	kfree(buffer);
+	return result;
+}
+
+static int 
+ch_init_elem(scsi_changer *ch)
+{
+	int err;
+	u_char cmd[6];
+
+	vprintk("INITIALIZE ELEMENT STATUS, may take some time ...\n");
+	memset(cmd,0,sizeof(cmd));
+	cmd[0] = INITIALIZE_ELEMENT_STATUS;
+	cmd[1] = ch->device->lun << 5;
+	err = ch_do_scsi(ch, cmd, NULL, 0, DMA_NONE);
+	vprintk("... finished\n");
+	return err;
+}
+
+static int
+ch_readconfig(scsi_changer *ch)
+{
+	u_char  cmd[10], data[16];
+	u_char  *buffer;
+	int     result,id,lun,i;
+	u_int   elem;
+
+	buffer = kmalloc(512, GFP_KERNEL | GFP_DMA);
+	if (!buffer)
+		return -ENOMEM;
+	memset(buffer,0,512);
+	
+	memset(cmd,0,sizeof(cmd));
+	cmd[0] = MODE_SENSE;
+	cmd[1] = ch->device->lun << 5;
+	cmd[2] = 0x1d;
+	cmd[4] = 255;
+	result = ch_do_scsi(ch, cmd, buffer, 255, DMA_FROM_DEVICE);
+	if (0 != result) {
+		cmd[1] |= (1<<3);
+		result  = ch_do_scsi(ch, cmd, buffer, 255, DMA_FROM_DEVICE);
+	}
+	if (0 == result) {
+		ch->firsts[CHET_MT] =
+			(buffer[buffer[3]+ 6] << 8) | buffer[buffer[3]+ 7];
+		ch->counts[CHET_MT] =
+			(buffer[buffer[3]+ 8] << 8) | buffer[buffer[3]+ 9];
+		ch->firsts[CHET_ST] =
+			(buffer[buffer[3]+10] << 8) | buffer[buffer[3]+11];
+		ch->counts[CHET_ST] =
+			(buffer[buffer[3]+12] << 8) | buffer[buffer[3]+13];
+		ch->firsts[CHET_IE] =
+			(buffer[buffer[3]+14] << 8) | buffer[buffer[3]+15];
+		ch->counts[CHET_IE] =
+			(buffer[buffer[3]+16] << 8) | buffer[buffer[3]+17];
+		ch->firsts[CHET_DT] =
+			(buffer[buffer[3]+18] << 8) | buffer[buffer[3]+19];
+		ch->counts[CHET_DT] =
+			(buffer[buffer[3]+20] << 8) | buffer[buffer[3]+21];
+		vprintk("type #1 (mt): 0x%x+%d [medium transport]\n",
+			ch->firsts[CHET_MT],
+			ch->counts[CHET_MT]);
+		vprintk("type #2 (st): 0x%x+%d [storage]\n",
+			ch->firsts[CHET_ST],
+			ch->counts[CHET_ST]);
+		vprintk("type #3 (ie): 0x%x+%d [import/export]\n",
+			ch->firsts[CHET_IE],
+			ch->counts[CHET_IE]);
+		vprintk("type #4 (dt): 0x%x+%d [data transfer]\n",
+			ch->firsts[CHET_DT],
+			ch->counts[CHET_DT]);
+	} else {
+		vprintk("reading element address assigment page failed!\n");
+	}
+	
+	/* vendor specific element types */
+	for (i = 0; i < 4; i++) {
+		if (0 == vendor_counts[i])
+			continue;
+		if (NULL == vendor_labels[i])
+			continue;
+		ch->firsts[CHET_V1+i] = vendor_firsts[i];
+		ch->counts[CHET_V1+i] = vendor_counts[i];
+		vprintk("type #%d (v%d): 0x%x+%d [%s, vendor specific]\n",
+			i+5,i+1,vendor_firsts[i],vendor_counts[i],
+			vendor_labels[i]);
+	}
+
+	/* look up the devices of the data transfer elements */
+	ch->dt = kmalloc(ch->counts[CHET_DT]*sizeof(struct scsi_device),
+			 GFP_KERNEL);
+	for (elem = 0; elem < ch->counts[CHET_DT]; elem++) {
+		id  = -1;
+		lun = 0;
+		if (elem < CH_DT_MAX  &&  -1 != dt_id[elem]) {
+			id  = dt_id[elem];
+			lun = dt_lun[elem];
+			vprintk("dt 0x%x: [insmod option] ",
+				elem+ch->firsts[CHET_DT]);
+		} else if (0 != ch_read_element_status
+			   (ch,elem+ch->firsts[CHET_DT],data)) {
+			vprintk("dt 0x%x: READ ELEMENT STATUS failed\n",
+				elem+ch->firsts[CHET_DT]);
+		} else {
+			vprintk("dt 0x%x: ",elem+ch->firsts[CHET_DT]);
+			if (data[6] & 0x80) {
+				if (verbose)
+					printk("not this SCSI bus\n");
+				ch->dt[elem] = NULL;
+			} else if (0 == (data[6] & 0x30)) {
+				if (verbose)
+					printk("ID/LUN unknown\n");
+				ch->dt[elem] = NULL;
+			} else {
+				id  = ch->device->id;
+				lun = 0;
+				if (data[6] & 0x20) id  = data[7];
+				if (data[6] & 0x10) lun = data[6] & 7;
+			}
+		}
+		if (-1 != id) {
+			if (verbose)
+				printk("ID %i, LUN %i, ",id,lun);
+			ch->dt[elem] =
+				scsi_device_lookup(ch->device->host,
+						   ch->device->channel,
+						   id,lun);
+			if (!ch->dt[elem]) {
+				/* should not happen */
+				if (verbose)
+					printk("Huh? device not found!\n");
+			} else {
+				if (verbose)
+					printk("name: %8.8s %16.16s %4.4s\n",
+					       ch->dt[elem]->vendor,
+					       ch->dt[elem]->model,
+					       ch->dt[elem]->rev);
+			}
+		}
+	}
+	ch->voltags = 1;
+	kfree(buffer);
+
+	return 0;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static int
+ch_position(scsi_changer *ch, u_int trans, u_int elem, int rotate)
+{
+	u_char  cmd[10];
+	
+	dprintk("position: 0x%x\n",elem);
+	if (0 == trans)
+		trans = ch->firsts[CHET_MT];
+	memset(cmd,0,sizeof(cmd));
+	cmd[0]  = POSITION_TO_ELEMENT;
+	cmd[1]  = ch->device->lun << 5;
+	cmd[2]  = (trans >> 8) & 0xff;
+	cmd[3]  =  trans       & 0xff;
+	cmd[4]  = (elem  >> 8) & 0xff;
+	cmd[5]  =  elem        & 0xff;
+	cmd[8]  = rotate ? 1 : 0;
+	return ch_do_scsi(ch, cmd, NULL, 0, DMA_NONE);
+}
+
+static int
+ch_move(scsi_changer *ch, u_int trans, u_int src, u_int dest, int rotate)
+{
+	u_char  cmd[12];
+	
+	dprintk("move: 0x%x => 0x%x\n",src,dest);
+	if (0 == trans)
+		trans = ch->firsts[CHET_MT];
+	memset(cmd,0,sizeof(cmd));
+	cmd[0]  = MOVE_MEDIUM;
+	cmd[1]  = ch->device->lun << 5;
+	cmd[2]  = (trans >> 8) & 0xff;
+	cmd[3]  =  trans       & 0xff;
+	cmd[4]  = (src   >> 8) & 0xff;
+	cmd[5]  =  src         & 0xff;
+	cmd[6]  = (dest  >> 8) & 0xff;
+	cmd[7]  =  dest        & 0xff;
+	cmd[10] = rotate ? 1 : 0;
+	return ch_do_scsi(ch, cmd, NULL,0, DMA_NONE);
+}
+
+static int
+ch_exchange(scsi_changer *ch, u_int trans, u_int src,
+	    u_int dest1, u_int dest2, int rotate1, int rotate2)
+{
+	u_char  cmd[12];
+	
+	dprintk("exchange: 0x%x => 0x%x => 0x%x\n",
+		src,dest1,dest2);
+	if (0 == trans)
+		trans = ch->firsts[CHET_MT];
+	memset(cmd,0,sizeof(cmd));
+	cmd[0]  = EXCHANGE_MEDIUM;
+	cmd[1]  = ch->device->lun << 5;
+	cmd[2]  = (trans >> 8) & 0xff;
+	cmd[3]  =  trans       & 0xff;
+	cmd[4]  = (src   >> 8) & 0xff;
+	cmd[5]  =  src         & 0xff;
+	cmd[6]  = (dest1 >> 8) & 0xff;
+	cmd[7]  =  dest1       & 0xff;
+	cmd[8]  = (dest2 >> 8) & 0xff;
+	cmd[9]  =  dest2       & 0xff;
+	cmd[10] = (rotate1 ? 1 : 0) | (rotate2 ? 2 : 0);
+	
+	return ch_do_scsi(ch, cmd, NULL,0, DMA_NONE);
+}
+
+static void
+ch_check_voltag(char *tag)
+{
+	int i;
+
+	for (i = 0; i < 32; i++) {
+		/* restrict to ascii */
+		if (tag[i] >= 0x7f || tag[i] < 0x20)
+			tag[i] = ' ';
+		/* don't allow search wildcards */
+		if (tag[i] == '?' ||
+		    tag[i] == '*')
+			tag[i] = ' ';
+	}
+}
+
+static int
+ch_set_voltag(scsi_changer *ch, u_int elem,
+	      int alternate, int clear, u_char *tag)
+{
+	u_char  cmd[12];
+	u_char  *buffer;
+	int result;
+
+	buffer = kmalloc(512, GFP_KERNEL);
+	if (!buffer)
+		return -ENOMEM;
+	memset(buffer,0,512);
+
+	dprintk("%s %s voltag: 0x%x => \"%s\"\n",
+		clear     ? "clear"     : "set",
+		alternate ? "alternate" : "primary",
+		elem, tag);
+	memset(cmd,0,sizeof(cmd));
+	cmd[0]  = SEND_VOLUME_TAG;
+	cmd[1] = (ch->device->lun << 5) | 
+		ch_elem_to_typecode(ch,elem);
+	cmd[2] = (elem >> 8) & 0xff;
+	cmd[3] = elem        & 0xff;
+	cmd[5] = clear
+		? (alternate ? 0x0d : 0x0c)
+		: (alternate ? 0x0b : 0x0a);
+	
+	cmd[9] = 255;
+
+	memcpy(buffer,tag,32);
+	ch_check_voltag(buffer);
+
+	result = ch_do_scsi(ch, cmd, buffer, 256, DMA_TO_DEVICE);
+	kfree(buffer);
+	return result;
+}
+
+static int ch_gstatus(scsi_changer *ch, int type, unsigned char *dest)
+{
+	int retval = 0;
+	u_char data[16];
+	unsigned int i;
+	
+	down(&ch->lock);
+	for (i = 0; i < ch->counts[type]; i++) {
+		if (0 != ch_read_element_status
+		    (ch, ch->firsts[type]+i,data)) {
+			retval = -EIO;
+			break;
+		}
+		put_user(data[2], dest+i);
+		if (data[2] & CESTATUS_EXCEPT)
+			vprintk("element 0x%x: asc=0x%x, ascq=0x%x\n",
+				ch->firsts[type]+i,
+				(int)data[4],(int)data[5]);
+		retval = ch_read_element_status
+			(ch, ch->firsts[type]+i,data);
+		if (0 != retval)
+			break;
+	}
+	up(&ch->lock);
+	return retval;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static int
+ch_release(struct inode *inode, struct file *file)
+{
+	scsi_changer *ch = file->private_data;
+
+	scsi_device_put(ch->device);
+	file->private_data = NULL;
+	return 0;
+}
+
+static int
+ch_open(struct inode *inode, struct file *file)
+{
+	scsi_changer *tmp, *ch;
+	int minor = iminor(inode);
+
+	spin_lock(&ch_devlist_lock);
+	ch = NULL;
+	list_for_each_entry(tmp,&ch_devlist,list) {
+		if (tmp->minor == minor)
+			ch = tmp;
+	}
+	if (NULL == ch || scsi_device_get(ch->device)) {
+		spin_unlock(&ch_devlist_lock);
+		return -ENXIO;
+	}
+	spin_unlock(&ch_devlist_lock);
+
+	file->private_data = ch;
+	return 0;
+}
+
+static int
+ch_checkrange(scsi_changer *ch, unsigned int type, unsigned int unit)
+{
+	if (type >= CH_TYPES  ||  unit >= ch->counts[type])
+		return -1;
+	return 0;
+}
+
+static int ch_ioctl(struct inode * inode, struct file * file,
+		    unsigned int cmd, unsigned long arg)
+{
+	scsi_changer *ch = file->private_data;
+	int retval;
+	
+	switch (cmd) {
+	case CHIOGPARAMS:
+	{
+		struct changer_params params;
+		
+		params.cp_curpicker = 0;
+		params.cp_npickers  = ch->counts[CHET_MT];
+		params.cp_nslots    = ch->counts[CHET_ST];
+		params.cp_nportals  = ch->counts[CHET_IE];
+		params.cp_ndrives   = ch->counts[CHET_DT];
+		
+		if (copy_to_user((void *) arg, &params, sizeof(params)))
+			return -EFAULT;
+		return 0;
+	}
+	case CHIOGVPARAMS:
+	{
+		struct changer_vendor_params vparams;
+
+		memset(&vparams,0,sizeof(vparams));
+		if (ch->counts[CHET_V1]) {
+			vparams.cvp_n1  = ch->counts[CHET_V1];
+			strncpy(vparams.cvp_label1,vendor_labels[0],16);
+		}
+		if (ch->counts[CHET_V2]) {
+			vparams.cvp_n2  = ch->counts[CHET_V2];
+			strncpy(vparams.cvp_label2,vendor_labels[1],16);
+		}
+		if (ch->counts[CHET_V3]) {
+			vparams.cvp_n3  = ch->counts[CHET_V3];
+			strncpy(vparams.cvp_label3,vendor_labels[2],16);
+		}
+		if (ch->counts[CHET_V4]) {
+			vparams.cvp_n4  = ch->counts[CHET_V4];
+			strncpy(vparams.cvp_label4,vendor_labels[3],16);
+		}
+		if (copy_to_user((void *) arg, &vparams, sizeof(vparams)))
+			return -EFAULT;
+		return 0;
+	}
+	
+	case CHIOPOSITION:
+	{
+		struct changer_position pos;
+		
+		if (copy_from_user(&pos, (void*)arg, sizeof (pos)))
+			return -EFAULT;
+
+		if (0 != ch_checkrange(ch, pos.cp_type, pos.cp_unit)) {
+			dprintk("CHIOPOSITION: invalid parameter\n");
+			return -EBADSLT;
+		}
+		down(&ch->lock);
+		retval = ch_position(ch,0,
+				     ch->firsts[pos.cp_type] + pos.cp_unit,
+				     pos.cp_flags & CP_INVERT);
+		up(&ch->lock);
+		return retval;
+	}
+	
+	case CHIOMOVE:
+	{
+		struct changer_move mv;
+
+		if (copy_from_user(&mv, (void*)arg, sizeof (mv)))
+			return -EFAULT;
+
+		if (0 != ch_checkrange(ch, mv.cm_fromtype, mv.cm_fromunit) ||
+		    0 != ch_checkrange(ch, mv.cm_totype,   mv.cm_tounit  )) {
+			dprintk("CHIOMOVE: invalid parameter\n");
+			return -EBADSLT;
+		}
+		
+		down(&ch->lock);
+		retval = ch_move(ch,0,
+				 ch->firsts[mv.cm_fromtype] + mv.cm_fromunit,
+				 ch->firsts[mv.cm_totype]   + mv.cm_tounit,
+				 mv.cm_flags & CM_INVERT);
+		up(&ch->lock);
+		return retval;
+	}
+
+	case CHIOEXCHANGE:
+	{
+		struct changer_exchange mv;
+		
+		if (copy_from_user(&mv, (void*)arg, sizeof (mv)))
+			return -EFAULT;
+
+		if (0 != ch_checkrange(ch, mv.ce_srctype,  mv.ce_srcunit ) ||
+		    0 != ch_checkrange(ch, mv.ce_fdsttype, mv.ce_fdstunit) ||
+		    0 != ch_checkrange(ch, mv.ce_sdsttype, mv.ce_sdstunit)) {
+			dprintk("CHIOEXCHANGE: invalid parameter\n");
+			return -EBADSLT;
+		}
+		
+		down(&ch->lock);
+		retval = ch_exchange
+			(ch,0,
+			 ch->firsts[mv.ce_srctype]  + mv.ce_srcunit,
+			 ch->firsts[mv.ce_fdsttype] + mv.ce_fdstunit,
+			 ch->firsts[mv.ce_sdsttype] + mv.ce_sdstunit,
+			 mv.ce_flags & CE_INVERT1, mv.ce_flags & CE_INVERT2);
+		up(&ch->lock);
+		return retval;
+	}
+
+	case CHIOGSTATUS:
+	{
+		struct changer_element_status ces;
+		
+		if (copy_from_user(&ces, (void*)arg, sizeof (ces)))
+			return -EFAULT;
+		if (ces.ces_type < 0 || ces.ces_type >= CH_TYPES)
+			return -EINVAL;
+
+		return ch_gstatus(ch, ces.ces_type, ces.ces_data);
+	}
+
+	case CHIOGELEM:
+	{
+		struct changer_get_element cge;
+		u_char  cmd[12];
+		u_char  *buffer;
+		unsigned int elem;
+		int     result,i;
+		
+		if (copy_from_user(&cge, (void*)arg, sizeof (cge)))
+			return -EFAULT;
+
+		if (0 != ch_checkrange(ch, cge.cge_type, cge.cge_unit))
+			return -EINVAL;
+		elem = ch->firsts[cge.cge_type] + cge.cge_unit;
+		
+		buffer = kmalloc(512, GFP_KERNEL | GFP_DMA);
+		if (!buffer)
+			return -ENOMEM;
+		down(&ch->lock);
+		
+	voltag_retry:
+		memset(cmd,0,sizeof(cmd));
+		cmd[0] = READ_ELEMENT_STATUS;
+		cmd[1] = (ch->device->lun << 5) |
+			(ch->voltags ? 0x10 : 0) |
+			ch_elem_to_typecode(ch,elem);
+		cmd[2] = (elem >> 8) & 0xff;
+		cmd[3] = elem        & 0xff;
+		cmd[5] = 1;
+		cmd[9] = 255;
+		
+		if (0 == (result = ch_do_scsi(ch, cmd, buffer, 256, DMA_FROM_DEVICE))) {
+			cge.cge_status = buffer[18];
+			cge.cge_flags = 0;
+			if (buffer[18] & CESTATUS_EXCEPT) {
+				cge.cge_errno = EIO;
+			}
+			if (buffer[25] & 0x80) {
+				cge.cge_flags |= CGE_SRC;
+				if (buffer[25] & 0x40)
+					cge.cge_flags |= CGE_INVERT;
+				elem = (buffer[26]<<8) | buffer[27];
+				for (i = 0; i < 4; i++) {
+					if (elem >= ch->firsts[i] &&
+					    elem <  ch->firsts[i] + ch->counts[i]) {
+						cge.cge_srctype = i;
+						cge.cge_srcunit = elem-ch->firsts[i];
+					}
+				}
+			}
+			if ((buffer[22] & 0x30) == 0x30) {
+				cge.cge_flags |= CGE_IDLUN;
+				cge.cge_id  = buffer[23];
+				cge.cge_lun = buffer[22] & 7;
+			}
+			if (buffer[9] & 0x80) {
+				cge.cge_flags |= CGE_PVOLTAG;
+				memcpy(cge.cge_pvoltag,buffer+28,36);
+			}
+			if (buffer[9] & 0x40) {
+				cge.cge_flags |= CGE_AVOLTAG;
+				memcpy(cge.cge_avoltag,buffer+64,36);
+			}
+		} else if (ch->voltags) {
+			ch->voltags = 0;
+			vprintk("device has no volume tag support\n");
+			goto voltag_retry;
+		}
+		kfree(buffer);
+		up(&ch->lock);
+		
+		if (copy_to_user((void*)arg, &cge, sizeof (cge)))
+			return -EFAULT;
+		return result;
+	}
+
+	case CHIOINITELEM:
+	{
+		down(&ch->lock);
+		retval = ch_init_elem(ch);
+		up(&ch->lock);
+		return retval;
+	}
+		
+	case CHIOSVOLTAG:
+	{
+		struct changer_set_voltag csv;
+		int elem;
+
+		if (copy_from_user(&csv, (void*)arg, sizeof(csv)))
+			return -EFAULT;
+
+		if (0 != ch_checkrange(ch, csv.csv_type, csv.csv_unit)) {
+			dprintk("CHIOSVOLTAG: invalid parameter\n");
+			return -EBADSLT;
+		}
+		elem = ch->firsts[csv.csv_type] + csv.csv_unit;
+		down(&ch->lock);
+		retval = ch_set_voltag(ch, elem,
+				       csv.csv_flags & CSV_AVOLTAG,
+				       csv.csv_flags & CSV_CLEARTAG,
+				       csv.csv_voltag);
+		up(&ch->lock);
+		return retval;
+	}
+
+	default:
+		return scsi_ioctl(ch->device, cmd, (void*)arg);
+
+	}
+}
+
+#ifdef CONFIG_COMPAT
+
+struct changer_element_status32 {
+	int		ces_type;
+	compat_uptr_t	ces_data;
+};
+#define CHIOGSTATUS32  _IOW('c', 8,struct changer_element_status32)
+
+static long ch_ioctl_compat(struct file * file,
+			    unsigned int cmd, unsigned long arg)
+{
+	scsi_changer *ch = file->private_data;
+	
+	switch (cmd) {
+	case CHIOGPARAMS:
+	case CHIOGVPARAMS:
+	case CHIOPOSITION:
+	case CHIOMOVE:
+	case CHIOEXCHANGE:
+	case CHIOGELEM:
+	case CHIOINITELEM:
+	case CHIOSVOLTAG:
+		/* compatible */
+		return ch_ioctl(NULL /* inode, unused */,
+				file, cmd, arg);
+	case CHIOGSTATUS32:
+	{
+		struct changer_element_status32 ces32;
+		unsigned char *data;
+		
+		if (copy_from_user(&ces32, (void*)arg, sizeof (ces32)))
+			return -EFAULT;
+		if (ces32.ces_type < 0 || ces32.ces_type >= CH_TYPES)
+			return -EINVAL;
+
+		data = compat_ptr(ces32.ces_data);
+		return ch_gstatus(ch, ces32.ces_type, data);
+	}
+	default:
+		// return scsi_ioctl_compat(ch->device, cmd, (void*)arg);
+		return -ENOIOCTLCMD;
+
+	}
+}
+#endif
+
+/* ------------------------------------------------------------------------ */
+
+static int ch_probe(struct device *dev)
+{
+	struct scsi_device *sd = to_scsi_device(dev);
+	scsi_changer *ch;
+	
+	if (sd->type != TYPE_MEDIUM_CHANGER)
+		return -ENODEV;
+    
+	ch = kmalloc(sizeof(*ch), GFP_KERNEL);
+	if (NULL == ch)
+		return -ENOMEM;
+
+	memset(ch,0,sizeof(*ch));
+	ch->minor = ch_devcount;
+	sprintf(ch->name,"ch%d",ch->minor);
+	init_MUTEX(&ch->lock);
+	ch->device = sd;
+	ch_readconfig(ch);
+	if (init)
+		ch_init_elem(ch);
+
+	devfs_mk_cdev(MKDEV(SCSI_CHANGER_MAJOR,ch->minor),
+		      S_IFCHR | S_IRUGO | S_IWUGO, ch->name);
+	class_device_create(ch_sysfs_class,
+			    MKDEV(SCSI_CHANGER_MAJOR,ch->minor),
+			    dev, "s%s", ch->name);
+
+	printk(KERN_INFO "Attached scsi changer %s "
+	       "at scsi%d, channel %d, id %d, lun %d\n", 
+	       ch->name, sd->host->host_no, sd->channel, sd->id, sd->lun);
+	
+	spin_lock(&ch_devlist_lock);
+	list_add_tail(&ch->list,&ch_devlist);
+	ch_devcount++;
+	spin_unlock(&ch_devlist_lock);
+	return 0;
+}
+
+static int ch_remove(struct device *dev)
+{
+	struct scsi_device *sd = to_scsi_device(dev);
+	scsi_changer *tmp, *ch;
+
+	spin_lock(&ch_devlist_lock);
+	ch = NULL;
+	list_for_each_entry(tmp,&ch_devlist,list) {
+		if (tmp->device == sd)
+			ch = tmp;
+	}
+	BUG_ON(NULL == ch);
+	list_del(&ch->list);
+	spin_unlock(&ch_devlist_lock);
+
+	class_device_destroy(ch_sysfs_class,
+			     MKDEV(SCSI_CHANGER_MAJOR,ch->minor));
+	devfs_remove(ch->name);
+	kfree(ch->dt);
+	kfree(ch);
+	ch_devcount--;
+	return 0;
+}
+
+static int __init init_ch_module(void)
+{
+	int rc;
+	
+	printk(KERN_INFO "SCSI Media Changer driver v" VERSION " \n");
+        ch_sysfs_class = class_create(THIS_MODULE, "scsi_changer");
+        if (IS_ERR(ch_sysfs_class)) {
+		rc = PTR_ERR(ch_sysfs_class);
+		return rc;
+        }
+	rc = register_chrdev(SCSI_CHANGER_MAJOR,"ch",&changer_fops);
+	if (rc < 0) {
+		printk("Unable to get major %d for SCSI-Changer\n",
+		       SCSI_CHANGER_MAJOR);
+		goto fail1;
+	}
+	rc = scsi_register_driver(&ch_template.gendrv);
+	if (rc < 0)
+		goto fail2;
+	return 0;
+
+ fail2:
+	unregister_chrdev(SCSI_CHANGER_MAJOR, "ch");
+ fail1:
+	class_destroy(ch_sysfs_class);
+	return rc;
+}
+
+static void __exit exit_ch_module(void) 
+{
+	scsi_unregister_driver(&ch_template.gendrv);
+	unregister_chrdev(SCSI_CHANGER_MAJOR, "ch");
+	class_destroy(ch_sysfs_class);
+}
+
+module_init(init_ch_module);
+module_exit(exit_ch_module);
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/drivers/scsi/cpqfcTSinit.c b/drivers/scsi/cpqfcTSinit.c
--- a/drivers/scsi/cpqfcTSinit.c
+++ b/drivers/scsi/cpqfcTSinit.c
@@ -336,7 +336,6 @@ int cpqfcTS_detect(Scsi_Host_Template *S
       DEBUG_PCI(printk("  PciDev->baseaddress[3]= %lx\n", 
 				PciDev->resource[3].start));
 
-      scsi_set_device(HostAdapter, &PciDev->dev);
       HostAdapter->irq = PciDev->irq;  // copy for Scsi layers
       
       // HP Tachlite uses two (255-byte) ranges of Port I/O (lower & upper),
diff --git a/drivers/scsi/dc395x.c b/drivers/scsi/dc395x.c
--- a/drivers/scsi/dc395x.c
+++ b/drivers/scsi/dc395x.c
@@ -183,7 +183,7 @@
  * cross a page boundy.
  */
 #define SEGMENTX_LEN	(sizeof(struct SGentry)*DC395x_MAX_SG_LISTENTRY)
-#define VIRTX_LEN	(sizeof(void *) * DC395x_MAX_SG_LISTENTRY)
+
 
 struct SGentry {
 	u32 address;		/* bus! address */
@@ -235,7 +235,6 @@ struct ScsiReqBlk {
 	u8 sg_count;			/* No of HW sg entries for this request */
 	u8 sg_index;			/* Index of HW sg entry for this request */
 	u32 total_xfer_length;		/* Total number of bytes remaining to be transfered */
-	void **virt_map;
 	unsigned char *virt_addr;	/* Virtual address of current transfer position */
 
 	/*
@@ -744,7 +743,7 @@ static void free_tag(struct DeviceCtlBlk
 
 
 /* Find cmd in SRB list */
-inline static struct ScsiReqBlk *find_cmd(struct scsi_cmnd *cmd, 
+static inline struct ScsiReqBlk *find_cmd(struct scsi_cmnd *cmd,
 		struct list_head *head)
 {
 	struct ScsiReqBlk *i;
@@ -1022,14 +1021,14 @@ static void build_srb(struct scsi_cmnd *
 			reqlen, cmd->request_buffer, cmd->use_sg,
 			srb->sg_count);
 
+		srb->virt_addr = page_address(sl->page);
 		for (i = 0; i < srb->sg_count; i++) {
-			u32 seglen = (u32)sg_dma_len(sl + i);
-			sgp[i].address = (u32)sg_dma_address(sl + i);
+			u32 busaddr = (u32)sg_dma_address(&sl[i]);
+			u32 seglen = (u32)sl[i].length;
+			sgp[i].address = busaddr;
 			sgp[i].length = seglen;
 			srb->total_xfer_length += seglen;
-			srb->virt_map[i] = kmap(sl[i].page);
 		}
-		srb->virt_addr = srb->virt_map[0];
 		sgp += srb->sg_count - 1;
 
 		/*
@@ -1310,7 +1309,7 @@ static void reset_dev_param(struct Adapt
  * @cmd - some command for this host (for fetching hooks)
  * Returns: SUCCESS (0x2002) on success, else FAILED (0x2003).
  */
-static int dc395x_eh_bus_reset(struct scsi_cmnd *cmd)
+static int __dc395x_eh_bus_reset(struct scsi_cmnd *cmd)
 {
 	struct AdapterCtlBlk *acb =
 		(struct AdapterCtlBlk *)cmd->device->host->hostdata;
@@ -1356,6 +1355,16 @@ static int dc395x_eh_bus_reset(struct sc
 	return SUCCESS;
 }
 
+static int dc395x_eh_bus_reset(struct scsi_cmnd *cmd)
+{
+	int rc;
+
+	spin_lock_irq(cmd->device->host->host_lock);
+	rc = __dc395x_eh_bus_reset(cmd);
+	spin_unlock_irq(cmd->device->host->host_lock);
+
+	return rc;
+}
 
 /*
  * abort an errant SCSI command
@@ -1966,7 +1975,6 @@ static void sg_update_list(struct ScsiRe
 	int segment = cmd->use_sg;
 	u32 xferred = srb->total_xfer_length - left; /* bytes transfered */
 	struct SGentry *psge = srb->segment_x + srb->sg_index;
-	void **virt = srb->virt_map;
 
 	dprintkdbg(DBG_0,
 		"sg_update_list: Transfered %i of %i bytes, %i remain\n",
@@ -2006,16 +2014,16 @@ static void sg_update_list(struct ScsiRe
 
 	/* We have to walk the scatterlist to find it */
 	sg = (struct scatterlist *)cmd->request_buffer;
-	idx = 0;
 	while (segment--) {
 		unsigned long mask =
 		    ~((unsigned long)sg->length - 1) & PAGE_MASK;
 		if ((sg_dma_address(sg) & mask) == (psge->address & mask)) {
-			srb->virt_addr = virt[idx] + (psge->address & ~PAGE_MASK);
+			srb->virt_addr = (page_address(sg->page)
+					   + psge->address -
+					   (psge->address & PAGE_MASK));
 			return;
 		}
 		++sg;
-		++idx;
 	}
 
 	dprintkl(KERN_ERR, "sg_update_list: sg_to_virt failed\n");
@@ -2141,7 +2149,7 @@ static void data_out_phase0(struct Adapt
 				DC395x_read32(acb, TRM_S1040_DMA_CXCNT));
 		}
 		/*
-		 * calculate all the residue data that not yet transfered
+		 * calculate all the residue data that not yet tranfered
 		 * SCSI transfer counter + left in SCSI FIFO data
 		 *
 		 * .....TRM_S1040_SCSI_COUNTER (24bits)
@@ -3259,7 +3267,6 @@ static void pci_unmap_srb(struct Adapter
 	struct scsi_cmnd *cmd = srb->cmd;
 	enum dma_data_direction dir = cmd->sc_data_direction;
 	if (cmd->use_sg && dir != PCI_DMA_NONE) {
-		int i;
 		/* unmap DC395x SG list */
 		dprintkdbg(DBG_SG, "pci_unmap_srb: list=%08x(%05x)\n",
 			srb->sg_bus_addr, SEGMENTX_LEN);
@@ -3269,8 +3276,6 @@ static void pci_unmap_srb(struct Adapter
 		dprintkdbg(DBG_SG, "pci_unmap_srb: segs=%i buffer=%p\n",
 			cmd->use_sg, cmd->request_buffer);
 		/* unmap the sg segments */
-		for (i = 0; i < srb->sg_count; i++)
-			kunmap(virt_to_page(srb->virt_map[i]));
 		pci_unmap_sg(acb->dev,
 			     (struct scatterlist *)cmd->request_buffer,
 			     cmd->use_sg, dir);
@@ -3317,7 +3322,7 @@ static void srb_done(struct AdapterCtlBl
 
 	if (cmd->use_sg) {
 		struct scatterlist* sg = (struct scatterlist *)cmd->request_buffer;
-		ptr = (struct ScsiInqData *)(srb->virt_map[0] + sg->offset);
+		ptr = (struct ScsiInqData *)(page_address(sg->page) + sg->offset);
 	} else {
 		ptr = (struct ScsiInqData *)(cmd->request_buffer);
 	}
@@ -4252,9 +4257,8 @@ static void adapter_sg_tables_free(struc
 	const unsigned srbs_per_page = PAGE_SIZE/SEGMENTX_LEN;
 
 	for (i = 0; i < DC395x_MAX_SRB_CNT; i += srbs_per_page)
-		kfree(acb->srb_array[i].segment_x);
-
-	vfree(acb->srb_array[0].virt_map);
+		if (acb->srb_array[i].segment_x)
+			kfree(acb->srb_array[i].segment_x);
 }
 
 
@@ -4270,12 +4274,9 @@ static int __devinit adapter_sg_tables_a
 	int srb_idx = 0;
 	unsigned i = 0;
 	struct SGentry *ptr;
-	void **virt_array;
 
-	for (i = 0; i < DC395x_MAX_SRB_CNT; i++) {
+	for (i = 0; i < DC395x_MAX_SRB_CNT; i++)
 		acb->srb_array[i].segment_x = NULL;
-		acb->srb_array[i].virt_map = NULL;
-	}
 
 	dprintkdbg(DBG_1, "Allocate %i pages for SG tables\n", pages);
 	while (pages--) {
@@ -4296,19 +4297,6 @@ static int __devinit adapter_sg_tables_a
 		    ptr + (i * DC395x_MAX_SG_LISTENTRY);
 	else
 		dprintkl(KERN_DEBUG, "No space for tmsrb SG table reserved?!\n");
-
-	virt_array = vmalloc((DC395x_MAX_SRB_CNT + 1) * DC395x_MAX_SG_LISTENTRY * sizeof(void*));
-
-	if (!virt_array) {
-		adapter_sg_tables_free(acb);
-		return 1;
-	}
-
-	for (i = 0; i < DC395x_MAX_SRB_CNT + 1; i++) {
-		acb->srb_array[i].virt_map = virt_array;
-		virt_array += DC395x_MAX_SG_LISTENTRY;
-	}
-
 	return 0;
 }
 
diff --git a/drivers/scsi/dmx3191d.c b/drivers/scsi/dmx3191d.c
--- a/drivers/scsi/dmx3191d.c
+++ b/drivers/scsi/dmx3191d.c
@@ -61,8 +61,6 @@ static struct scsi_host_template dmx3191
 	.queuecommand		= NCR5380_queue_command,
 	.eh_abort_handler	= NCR5380_abort,
 	.eh_bus_reset_handler	= NCR5380_bus_reset,
-	.eh_device_reset_handler= NCR5380_device_reset,
-	.eh_host_reset_handler	= NCR5380_host_reset,
 	.can_queue		= 32,
 	.this_id		= 7,
 	.sg_tablesize		= SG_ALL,
diff --git a/drivers/scsi/dpt/dptsig.h b/drivers/scsi/dpt/dptsig.h
--- a/drivers/scsi/dpt/dptsig.h
+++ b/drivers/scsi/dpt/dptsig.h
@@ -76,7 +76,7 @@ typedef unsigned long sigLONG;
 #endif  /* aix */
 #endif
 /* For the Macintosh */
-#if STRUCTALIGNMENTSUPPORTED
+#ifdef STRUCTALIGNMENTSUPPORTED
 #pragma options align=mac68k
 #endif
 
@@ -332,7 +332,7 @@ typedef struct dpt_sig {
 #endif  /* aix */
 #endif
 /* For the Macintosh */
-#if STRUCTALIGNMENTSUPPORTED
+#ifdef STRUCTALIGNMENTSUPPORTED
 #pragma options align=reset
 #endif
 
diff --git a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c
--- a/drivers/scsi/dpt_i2o.c
+++ b/drivers/scsi/dpt_i2o.c
@@ -34,7 +34,6 @@
 
 #define ADDR32 (0)
 
-#include <linux/version.h>
 #include <linux/module.h>
 
 MODULE_AUTHOR("Deanna Bonds, with _lots_ of help from Mark Salyzyn");
@@ -113,7 +112,6 @@ static struct i2o_sys_tbl *sys_tbl = NUL
 static int sys_tbl_ind = 0;
 static int sys_tbl_len = 0;
 
-static adpt_hba* hbas[DPTI_MAX_HBA];
 static adpt_hba* hba_chain = NULL;
 static int hba_count = 0;
 
@@ -384,7 +382,6 @@ static int adpt_queue(struct scsi_cmnd *
 {
 	adpt_hba* pHba = NULL;
 	struct adpt_device* pDev = NULL;	/* dpt per device information */
-	ulong timeout = jiffies + (TMOUT_SCSI*HZ);
 
 	cmd->scsi_done = done;
 	/*
@@ -420,11 +417,6 @@ static int adpt_queue(struct scsi_cmnd *
 		return 1;
 	}
 
-	if(cmd->eh_state != SCSI_STATE_QUEUED){
-		// If we are not doing error recovery
-		mod_timer(&cmd->eh_timeout, timeout);
-	}
-
 	// TODO if the cmd->device if offline then I may need to issue a bus rescan
 	// followed by a get_lct to see if the device is there anymore
 	if((pDev = (struct adpt_device*) (cmd->device->hostdata)) == NULL) {
@@ -691,7 +683,7 @@ static int adpt_device_reset(struct scsi
 	u32 msg[4];
 	u32 rcode;
 	int old_state;
-	struct adpt_device* d = (void*) cmd->device->hostdata;
+	struct adpt_device* d = cmd->device->hostdata;
 
 	pHba = (void*) cmd->device->host->hostdata[0];
 	printk(KERN_INFO"%s: Trying to reset device\n",pHba->name);
@@ -707,7 +699,7 @@ static int adpt_device_reset(struct scsi
 
 	old_state = d->state;
 	d->state |= DPTI_DEV_RESET;
-	if( (rcode = adpt_i2o_post_wait(pHba, (void*)msg,sizeof(msg), FOREVER)) ){
+	if( (rcode = adpt_i2o_post_wait(pHba, msg,sizeof(msg), FOREVER)) ){
 		d->state = old_state;
 		if(rcode == -EOPNOTSUPP ){
 			printk(KERN_INFO"%s: Device reset not supported\n",pHba->name);
@@ -737,7 +729,7 @@ static int adpt_bus_reset(struct scsi_cm
 	msg[1] = (I2O_HBA_BUS_RESET<<24|HOST_TID<<12|pHba->channel[cmd->device->channel].tid);
 	msg[2] = 0;
 	msg[3] = 0;
-	if(adpt_i2o_post_wait(pHba, (void*)msg,sizeof(msg), FOREVER) ){
+	if(adpt_i2o_post_wait(pHba, msg,sizeof(msg), FOREVER) ){
 		printk(KERN_WARNING"%s: Bus reset failed.\n",pHba->name);
 		return FAILED;
 	} else {
@@ -747,7 +739,7 @@ static int adpt_bus_reset(struct scsi_cm
 }
 
 // This version of reset is called by the eh_error_handler
-static int adpt_reset(struct scsi_cmnd* cmd)
+static int __adpt_reset(struct scsi_cmnd* cmd)
 {
 	adpt_hba* pHba;
 	int rcode;
@@ -763,6 +755,17 @@ static int adpt_reset(struct scsi_cmnd* 
 	}
 }
 
+static int adpt_reset(struct scsi_cmnd* cmd)
+{
+	int rc;
+
+	spin_lock_irq(cmd->device->host->host_lock);
+	rc = __adpt_reset(cmd);
+	spin_unlock_irq(cmd->device->host->host_lock);
+
+	return rc;
+}
+
 // This version of reset is called by the ioctls and indirectly from eh_error_handler via adpt_reset
 static int adpt_hba_reset(adpt_hba* pHba)
 {
@@ -875,7 +878,6 @@ static int adpt_install_hba(struct scsi_
 	void __iomem *msg_addr_virt = NULL;
 
 	int raptorFlag = FALSE;
-	int i;
 
 	if(pci_enable_device(pDev)) {
 		return -EINVAL;
@@ -905,9 +907,13 @@ static int adpt_install_hba(struct scsi_
 		raptorFlag = TRUE;
 	}
 
-
+	if (pci_request_regions(pDev, "dpt_i2o")) {
+		PERROR("dpti: adpt_config_hba: pci request region failed\n");
+		return -EINVAL;
+	}
 	base_addr_virt = ioremap(base_addr0_phys,hba_map0_area_size);
 	if (!base_addr_virt) {
+		pci_release_regions(pDev);
 		PERROR("dpti: adpt_config_hba: io remap failed\n");
 		return -EINVAL;
 	}
@@ -917,6 +923,7 @@ static int adpt_install_hba(struct scsi_
 		if (!msg_addr_virt) {
 			PERROR("dpti: adpt_config_hba: io remap failed on BAR1\n");
 			iounmap(base_addr_virt);
+			pci_release_regions(pDev);
 			return -EINVAL;
 		}
 	} else {
@@ -930,17 +937,12 @@ static int adpt_install_hba(struct scsi_
 			iounmap(msg_addr_virt);
 		}
 		iounmap(base_addr_virt);
+		pci_release_regions(pDev);
 		return -ENOMEM;
 	}
 	memset(pHba, 0, sizeof(adpt_hba));
 
 	down(&adpt_configuration_lock);
-	for(i=0;i<DPTI_MAX_HBA;i++) {
-		if(hbas[i]==NULL) {
-			hbas[i]=pHba;
-			break;
-		}
-	}
 
 	if(hba_chain != NULL){
 		for(p = hba_chain; p->next; p = p->next);
@@ -950,7 +952,7 @@ static int adpt_install_hba(struct scsi_
 	}
 	pHba->next = NULL;
 	pHba->unit = hba_count;
-	sprintf(pHba->name, "dpti%d", i);
+	sprintf(pHba->name, "dpti%d", hba_count);
 	hba_count++;
 	
 	up(&adpt_configuration_lock);
@@ -1015,11 +1017,6 @@ static void adpt_i2o_delete_hba(adpt_hba
 	if(pHba->host){
 		free_irq(pHba->host->irq, pHba);
 	}
-	for(i=0;i<DPTI_MAX_HBA;i++) {
-		if(hbas[i]==pHba) {
-			hbas[i] = NULL;
-		}
-	}
 	p2 = NULL;
 	for( p1 = hba_chain; p1; p2 = p1,p1=p1->next){
 		if(p1 == pHba) {
@@ -1036,6 +1033,7 @@ static void adpt_i2o_delete_hba(adpt_hba
 	up(&adpt_configuration_lock);
 
 	iounmap(pHba->base_addr_virt);
+	pci_release_regions(pHba->pDev);
 	if(pHba->msg_addr_virt != pHba->base_addr_virt){
 		iounmap(pHba->msg_addr_virt);
 	}
@@ -1076,12 +1074,7 @@ static void adpt_i2o_delete_hba(adpt_hba
 
 static int adpt_init(void)
 {
-	int i;
-
 	printk("Loading Adaptec I2O RAID: Version " DPT_I2O_VERSION "\n");
-	for (i = 0; i < DPTI_MAX_HBA; i++) {
-		hbas[i] = NULL;
-	}
 #ifdef REBOOT_NOTIFIER
 	register_reboot_notifier(&adpt_reboot_notifier);
 #endif
@@ -1133,11 +1126,11 @@ static int adpt_i2o_post_wait(adpt_hba* 
 	struct adpt_i2o_post_wait_data *p1, *p2;
 	struct adpt_i2o_post_wait_data *wait_data =
 		kmalloc(sizeof(struct adpt_i2o_post_wait_data),GFP_KERNEL);
-	adpt_wait_queue_t wait;
+	DECLARE_WAITQUEUE(wait, current);
 
-	if(!wait_data){
+	if (!wait_data)
 		return -ENOMEM;
-	}
+
 	/*
 	 * The spin locking is needed to keep anyone from playing
 	 * with the queue pointers and id while we do the same
@@ -1155,12 +1148,7 @@ static int adpt_i2o_post_wait(adpt_hba* 
 	wait_data->wq = &adpt_wq_i2o_post;
 	wait_data->status = -ETIMEDOUT;
 
-	// this code is taken from kernel/sched.c:interruptible_sleep_on_timeout
-	wait.task = current;
-	init_waitqueue_entry(&wait, current);
-	spin_lock_irqsave(&adpt_wq_i2o_post.lock, flags);
-	__add_wait_queue(&adpt_wq_i2o_post, &wait);
-	spin_unlock(&adpt_wq_i2o_post.lock);
+	add_wait_queue(&adpt_wq_i2o_post, &wait);
 
 	msg[2] |= 0x80000000 | ((u32)wait_data->id);
 	timeout *= HZ;
@@ -1182,9 +1170,7 @@ static int adpt_i2o_post_wait(adpt_hba* 
 		if(pHba->host)
 			spin_lock_irq(pHba->host->host_lock);
 	}
-	spin_lock_irq(&adpt_wq_i2o_post.lock);
-	__remove_wait_queue(&adpt_wq_i2o_post, &wait);
-	spin_unlock_irqrestore(&adpt_wq_i2o_post.lock, flags);
+	remove_wait_queue(&adpt_wq_i2o_post, &wait);
 
 	if(status == -ETIMEDOUT){
 		printk(KERN_INFO"dpti%d: POST WAIT TIMEOUT\n",pHba->unit);
@@ -1454,7 +1440,7 @@ static int adpt_i2o_parse_lct(adpt_hba* 
 			return -ENOMEM;
 		}
 		
-		d->controller = (void*)pHba;
+		d->controller = pHba;
 		d->next = NULL;
 
 		memcpy(&d->lct_data, &lct->lct_entry[i], sizeof(i2o_lct_entry));
@@ -1825,9 +1811,9 @@ static int adpt_system_info(void __user 
 	memset(&si, 0, sizeof(si));
 
 	si.osType = OS_LINUX;
-	si.osMajorVersion = (u8) (LINUX_VERSION_CODE >> 16);
-	si.osMinorVersion = (u8) (LINUX_VERSION_CODE >> 8 & 0x0ff);
-	si.osRevision =     (u8) (LINUX_VERSION_CODE & 0x0ff);
+	si.osMajorVersion = 0;
+	si.osMinorVersion = 0;
+	si.osRevision = 0;
 	si.busType = SI_PCI_BUS;
 	si.processorFamily = DPTI_sig.dsProcessorFamily;
 
@@ -2000,7 +1986,7 @@ static irqreturn_t adpt_isr(int irq, voi
 	struct scsi_cmnd* cmd;
 	adpt_hba* pHba = dev_id;
 	u32 m;
-	ulong reply;
+	void __iomem *reply;
 	u32 status=0;
 	u32 context;
 	ulong flags = 0;
@@ -2025,11 +2011,11 @@ static irqreturn_t adpt_isr(int irq, voi
 				goto out;
 			}
 		}
-		reply = (ulong)bus_to_virt(m);
+		reply = bus_to_virt(m);
 
 		if (readl(reply) & MSG_FAIL) {
 			u32 old_m = readl(reply+28); 
-			ulong msg;
+			void __iomem *msg;
 			u32 old_context;
 			PDEBUG("%s: Failed message\n",pHba->name);
 			if(old_m >= 0x100000){
@@ -2038,16 +2024,16 @@ static irqreturn_t adpt_isr(int irq, voi
 				continue;
 			}
 			// Transaction context is 0 in failed reply frame
-			msg = (ulong)(pHba->msg_addr_virt + old_m);
+			msg = pHba->msg_addr_virt + old_m;
 			old_context = readl(msg+12);
 			writel(old_context, reply+12);
 			adpt_send_nop(pHba, old_m);
 		} 
 		context = readl(reply+8);
 		if(context & 0x40000000){ // IOCTL
-			ulong p = (ulong)(readl(reply+12));
-			if( p != 0) {
-				memcpy((void*)p, (void*)reply, REPLY_FRAME_SIZE * 4);
+			void *p = (void *)readl(reply+12);
+			if( p != NULL) {
+				memcpy_fromio(p, reply, REPLY_FRAME_SIZE * 4);
 			}
 			// All IOCTLs will also be post wait
 		}
@@ -2231,7 +2217,7 @@ static s32 adpt_scsi_register(adpt_hba* 
 }
 
 
-static s32 adpt_i2o_to_scsi(ulong reply, struct scsi_cmnd* cmd)
+static s32 adpt_i2o_to_scsi(void __iomem *reply, struct scsi_cmnd* cmd)
 {
 	adpt_hba* pHba;
 	u32 hba_status;
@@ -2323,7 +2309,7 @@ static s32 adpt_i2o_to_scsi(ulong reply,
 			u32 len = sizeof(cmd->sense_buffer);
 			len = (len > 40) ?  40 : len;
 			// Copy over the sense data
-			memcpy(cmd->sense_buffer, (void*)(reply+28) , len);
+			memcpy_fromio(cmd->sense_buffer, (reply+28) , len);
 			if(cmd->sense_buffer[0] == 0x70 /* class 7 */ && 
 			   cmd->sense_buffer[2] == DATA_PROTECT ){
 				/* This is to handle an array failed */
@@ -2438,7 +2424,7 @@ static s32 adpt_i2o_reparse_lct(adpt_hba
 					return -ENOMEM;
 				}
 				
-				d->controller = (void*)pHba;
+				d->controller = pHba;
 				d->next = NULL;
 
 				memcpy(&d->lct_data, &lct->lct_entry[i], sizeof(i2o_lct_entry));
@@ -2985,8 +2971,8 @@ static int adpt_i2o_build_sys_table(void
 		sys_tbl->iops[count].frame_size = pHba->status_block->inbound_frame_size;
 		sys_tbl->iops[count].last_changed = sys_tbl_ind - 1; // ??
 		sys_tbl->iops[count].iop_capabilities = pHba->status_block->iop_capabilities;
-		sys_tbl->iops[count].inbound_low = (u32)virt_to_bus((void*)pHba->post_port);
-		sys_tbl->iops[count].inbound_high = (u32)((u64)virt_to_bus((void*)pHba->post_port)>>32);
+		sys_tbl->iops[count].inbound_low = (u32)virt_to_bus(pHba->post_port);
+		sys_tbl->iops[count].inbound_high = (u32)((u64)virt_to_bus(pHba->post_port)>>32);
 
 		count++;
 	}
diff --git a/drivers/scsi/dpti.h b/drivers/scsi/dpti.h
--- a/drivers/scsi/dpti.h
+++ b/drivers/scsi/dpti.h
@@ -20,15 +20,7 @@
 #ifndef _DPT_H
 #define _DPT_H
 
-#ifndef LINUX_VERSION_CODE
-#include <linux/version.h>
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,00)
-#define MAX_TO_IOP_MESSAGES   (210)
-#else
 #define MAX_TO_IOP_MESSAGES   (255)
-#endif
 #define MAX_FROM_IOP_MESSAGES (255)
 
 
@@ -296,7 +288,7 @@ static s32 adpt_i2o_status_get(adpt_hba*
 static s32 adpt_i2o_init_outbound_q(adpt_hba* pHba);
 static s32 adpt_i2o_hrt_get(adpt_hba* pHba);
 static s32 adpt_scsi_to_i2o(adpt_hba* pHba, struct scsi_cmnd* cmd, struct adpt_device* dptdevice);
-static s32 adpt_i2o_to_scsi(ulong reply, struct scsi_cmnd* cmd);
+static s32 adpt_i2o_to_scsi(void __iomem *reply, struct scsi_cmnd* cmd);
 static s32 adpt_scsi_register(adpt_hba* pHba,struct scsi_host_template * sht);
 static s32 adpt_hba_reset(adpt_hba* pHba);
 static s32 adpt_i2o_reset_hba(adpt_hba* pHba);
@@ -321,10 +313,6 @@ static int adpt_close(struct inode *inod
 static void adpt_delay(int millisec);
 #endif
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
-static struct pci_dev* adpt_pci_find_device(uint vendor, struct pci_dev* from);
-#endif
-
 #if defined __ia64__ 
 static void adpt_ia64_info(sysInfo_S* si);
 #endif
diff --git a/drivers/scsi/dtc.c b/drivers/scsi/dtc.c
--- a/drivers/scsi/dtc.c
+++ b/drivers/scsi/dtc.c
@@ -92,10 +92,6 @@
 
 #define DTC_PUBLIC_RELEASE 2
 
-/*#define DTCDEBUG 0x1*/
-#define DTCDEBUG_INIT	0x1
-#define DTCDEBUG_TRANSFER 0x2
-
 /*
  * The DTC3180 & 3280 boards are memory mapped.
  * 
@@ -482,8 +478,6 @@ static Scsi_Host_Template driver_templat
 	.queuecommand			= dtc_queue_command,
 	.eh_abort_handler		= dtc_abort,
 	.eh_bus_reset_handler		= dtc_bus_reset,
-	.eh_device_reset_handler	= dtc_device_reset,
-	.eh_host_reset_handler          = dtc_host_reset,
 	.bios_param     		= dtc_biosparam,
 	.can_queue      		= CAN_QUEUE,
 	.this_id        		= 7,
diff --git a/drivers/scsi/dtc.h b/drivers/scsi/dtc.h
--- a/drivers/scsi/dtc.h
+++ b/drivers/scsi/dtc.h
@@ -28,14 +28,16 @@
 #ifndef DTC3280_H
 #define DTC3280_H
 
+#define DTCDEBUG 0
+#define DTCDEBUG_INIT	0x1
+#define DTCDEBUG_TRANSFER 0x2
+
 static int dtc_abort(Scsi_Cmnd *);
 static int dtc_biosparam(struct scsi_device *, struct block_device *,
 		         sector_t, int*);
 static int dtc_detect(Scsi_Host_Template *);
 static int dtc_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
 static int dtc_bus_reset(Scsi_Cmnd *);
-static int dtc_device_reset(Scsi_Cmnd *);
-static int dtc_host_reset(Scsi_Cmnd *);
 
 #ifndef CMD_PER_LUN
 #define CMD_PER_LUN 2
@@ -86,8 +88,6 @@ static int dtc_host_reset(Scsi_Cmnd *);
 #define NCR5380_queue_command		dtc_queue_command
 #define NCR5380_abort			dtc_abort
 #define NCR5380_bus_reset		dtc_bus_reset
-#define NCR5380_device_reset		dtc_device_reset
-#define NCR5380_host_reset		dtc_host_reset
 #define NCR5380_proc_info		dtc_proc_info 
 
 /* 15 12 11 10
diff --git a/drivers/scsi/eata.c b/drivers/scsi/eata.c
--- a/drivers/scsi/eata.c
+++ b/drivers/scsi/eata.c
@@ -518,8 +518,6 @@ static struct scsi_host_template driver_
 	.release = eata2x_release,
 	.queuecommand = eata2x_queuecommand,
 	.eh_abort_handler = eata2x_eh_abort,
-	.eh_device_reset_handler = NULL,
-	.eh_bus_reset_handler = NULL,
 	.eh_host_reset_handler = eata2x_eh_host_reset,
 	.bios_param = eata2x_bios_param,
 	.slave_configure = eata2x_slave_configure,
@@ -1901,16 +1899,6 @@ static int eata2x_eh_abort(struct scsi_c
 			printk("%s: abort, mbox %d, interrupt pending.\n",
 			       ha->board_name, i);
 
-		if (SCarg->eh_state == SCSI_STATE_TIMEOUT) {
-			unmap_dma(i, ha);
-			SCarg->host_scribble = NULL;
-			ha->cp_stat[i] = FREE;
-			printk
-			    ("%s, abort, mbox %d, eh_state timeout, pid %ld.\n",
-			     ha->board_name, i, SCarg->pid);
-			return SUCCESS;
-		}
-
 		return FAILED;
 	}
 
@@ -1950,16 +1938,20 @@ static int eata2x_eh_host_reset(struct s
 	       ha->board_name, SCarg->device->channel, SCarg->device->id,
 	       SCarg->device->lun, SCarg->pid);
 
+	spin_lock_irq(shost->host_lock);
+
 	if (SCarg->host_scribble == NULL)
 		printk("%s: reset, pid %ld inactive.\n", ha->board_name, SCarg->pid);
 
 	if (ha->in_reset) {
 		printk("%s: reset, exit, already in reset.\n", ha->board_name);
+		spin_unlock_irq(shost->host_lock);
 		return FAILED;
 	}
 
 	if (wait_on_busy(shost->io_port, MAXLOOP)) {
 		printk("%s: reset, exit, timeout error.\n", ha->board_name);
+		spin_unlock_irq(shost->host_lock);
 		return FAILED;
 	}
 
@@ -2014,6 +2006,7 @@ static int eata2x_eh_host_reset(struct s
 
 	if (do_dma(shost->io_port, 0, RESET_PIO)) {
 		printk("%s: reset, cannot reset, timeout error.\n", ha->board_name);
+		spin_unlock_irq(shost->host_lock);
 		return FAILED;
 	}
 
@@ -2026,9 +2019,12 @@ static int eata2x_eh_host_reset(struct s
 	ha->in_reset = 1;
 
 	spin_unlock_irq(shost->host_lock);
+
+	/* FIXME: use a sleep instead */
 	time = jiffies;
 	while ((jiffies - time) < (10 * HZ) && limit++ < 200000)
 		udelay(100L);
+
 	spin_lock_irq(shost->host_lock);
 
 	printk("%s: reset, interrupts disabled, loops %d.\n", ha->board_name, limit);
@@ -2078,6 +2074,7 @@ static int eata2x_eh_host_reset(struct s
 	else
 		printk("%s: reset, exit.\n", ha->board_name);
 
+	spin_unlock_irq(shost->host_lock);
 	return SUCCESS;
 }
 
diff --git a/drivers/scsi/eata_pio.c b/drivers/scsi/eata_pio.c
--- a/drivers/scsi/eata_pio.c
+++ b/drivers/scsi/eata_pio.c
@@ -449,7 +449,7 @@ static int eata_pio_abort(struct scsi_cm
 {
 	uint loop = HZ;
 
-	DBG(DBG_ABNORM, printk(KERN_WARNING "eata_pio_abort called pid: %ld " "target: %x lun: %x reason %x\n", cmd->pid, cmd->device->id, cmd->device->lun, cmd->abort_reason));
+	DBG(DBG_ABNORM, printk(KERN_WARNING "eata_pio_abort called pid: %ld " "target: %x lun: %x\n", cmd->pid, cmd->device->id, cmd->device->lun));
 
 
 	while (inb(cmd->device->host->base + HA_RAUXSTAT) & HA_ABUSY)
@@ -484,10 +484,13 @@ static int eata_pio_host_reset(struct sc
 	struct scsi_cmnd *sp;
 	struct Scsi_Host *host = cmd->device->host;
 
-	DBG(DBG_ABNORM, printk(KERN_WARNING "eata_pio_reset called pid:%ld target:" " %x lun: %x reason %x\n", cmd->pid, cmd->device->id, cmd->device->lun, cmd->abort_reason));
+	DBG(DBG_ABNORM, printk(KERN_WARNING "eata_pio_reset called pid:%ld target:" " %x lun: %x\n", cmd->pid, cmd->device->id, cmd->device->lun));
+
+	spin_lock_irq(host->host_lock);
 
 	if (HD(cmd)->state == RESET) {
 		printk(KERN_WARNING "eata_pio_reset: exit, already in reset.\n");
+		spin_unlock_irq(host->host_lock);
 		return FAILED;
 	}
 
@@ -536,6 +539,8 @@ static int eata_pio_host_reset(struct sc
 
 	HD(cmd)->state = 0;
 
+	spin_unlock_irq(host->host_lock);
+
 	if (success) {		/* hmmm... */
 		DBG(DBG_ABNORM, printk(KERN_WARNING "eata_pio_reset: exit, success.\n"));
 		return SUCCESS;
diff --git a/drivers/scsi/fcal.c b/drivers/scsi/fcal.c
--- a/drivers/scsi/fcal.c
+++ b/drivers/scsi/fcal.c
@@ -311,7 +311,6 @@ static Scsi_Host_Template driver_templat
 	.use_clustering		= ENABLE_CLUSTERING,
 	.eh_abort_handler	= fcp_scsi_abort,
 	.eh_device_reset_handler = fcp_scsi_dev_reset,
-	.eh_bus_reset_handler	= fcp_scsi_bus_reset,
 	.eh_host_reset_handler	= fcp_scsi_host_reset,
 };
 #include "scsi_module.c"
diff --git a/drivers/scsi/fd_mcs.c b/drivers/scsi/fd_mcs.c
--- a/drivers/scsi/fd_mcs.c
+++ b/drivers/scsi/fd_mcs.c
@@ -1241,18 +1241,9 @@ static int fd_mcs_abort(Scsi_Cmnd * SCpn
 	return SUCCESS;
 }
 
-static int fd_mcs_host_reset(Scsi_Cmnd * SCpnt)
-{
-	return FAILED;
-}
-
-static int fd_mcs_device_reset(Scsi_Cmnd * SCpnt) 
-{
-	return FAILED;
-}
-
 static int fd_mcs_bus_reset(Scsi_Cmnd * SCpnt) {
 	struct Scsi_Host *shpnt = SCpnt->device->host;
+	unsigned long flags;
 
 #if DEBUG_RESET
 	static int called_once = 0;
@@ -1269,6 +1260,8 @@ static int fd_mcs_bus_reset(Scsi_Cmnd * 
 	called_once = 1;
 #endif
 
+	spin_lock_irqsave(shpnt->host_lock, flags);
+
 	outb(1, SCSI_Cntl_port);
 	do_pause(2);
 	outb(0, SCSI_Cntl_port);
@@ -1276,6 +1269,8 @@ static int fd_mcs_bus_reset(Scsi_Cmnd * 
 	outb(0, SCSI_Mode_Cntl_port);
 	outb(PARITY_MASK, TMC_Cntl_port);
 
+	spin_unlock_irqrestore(shpnt->host_lock, flags);
+
 	/* Unless this is the very first call (i.e., SCPnt == NULL), everything
 	   is probably hosed at this point.  We will, however, try to keep
 	   things going by informing the high-level code that we need help. */
@@ -1357,8 +1352,6 @@ static Scsi_Host_Template driver_templat
 	.queuecommand   		= fd_mcs_queue, 
 	.eh_abort_handler		= fd_mcs_abort,
 	.eh_bus_reset_handler		= fd_mcs_bus_reset,
-	.eh_host_reset_handler		= fd_mcs_host_reset,
-	.eh_device_reset_handler	= fd_mcs_device_reset,
 	.bios_param     		= fd_mcs_biosparam,
 	.can_queue      		= 1,
 	.this_id        		= 7,
diff --git a/drivers/scsi/fdomain.c b/drivers/scsi/fdomain.c
--- a/drivers/scsi/fdomain.c
+++ b/drivers/scsi/fdomain.c
@@ -570,7 +570,7 @@ static void do_pause(unsigned amount)	/*
 	mdelay(10*amount);
 }
 
-inline static void fdomain_make_bus_idle( void )
+static inline void fdomain_make_bus_idle( void )
 {
    outb(0, port_base + SCSI_Cntl);
    outb(0, port_base + SCSI_Mode_Cntl);
@@ -938,7 +938,6 @@ struct Scsi_Host *__fdomain_16x0_detect(
    }
    shpnt->irq = interrupt_level;
    shpnt->io_port = port_base;
-   scsi_set_device(shpnt, &pdev->dev);
    shpnt->n_io_port = 0x10;
    print_banner( shpnt );
 
@@ -1543,12 +1542,18 @@ static int fdomain_16x0_abort(struct scs
 
 int fdomain_16x0_bus_reset(struct scsi_cmnd *SCpnt)
 {
+   unsigned long flags;
+
+   local_irq_save(flags);
+
    outb(1, port_base + SCSI_Cntl);
    do_pause( 2 );
    outb(0, port_base + SCSI_Cntl);
    do_pause( 115 );
    outb(0, port_base + SCSI_Mode_Cntl);
    outb(PARITY_MASK, port_base + TMC_Cntl);
+
+   local_irq_restore(flags);
    return SUCCESS;
 }
 
diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c
--- a/drivers/scsi/g_NCR5380.c
+++ b/drivers/scsi/g_NCR5380.c
@@ -908,8 +908,6 @@ static Scsi_Host_Template driver_templat
 	.queuecommand   	= generic_NCR5380_queue_command,
 	.eh_abort_handler	= generic_NCR5380_abort,
 	.eh_bus_reset_handler	= generic_NCR5380_bus_reset,
-	.eh_device_reset_handler = generic_NCR5380_device_reset,
-	.eh_host_reset_handler	= generic_NCR5380_host_reset,
 	.bios_param     	= NCR5380_BIOSPARAM,
 	.can_queue      	= CAN_QUEUE,
         .this_id        	= 7,
diff --git a/drivers/scsi/g_NCR5380.h b/drivers/scsi/g_NCR5380.h
--- a/drivers/scsi/g_NCR5380.h
+++ b/drivers/scsi/g_NCR5380.h
@@ -49,8 +49,6 @@ static int generic_NCR5380_detect(Scsi_H
 static int generic_NCR5380_release_resources(struct Scsi_Host *);
 static int generic_NCR5380_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
 static int generic_NCR5380_bus_reset(Scsi_Cmnd *);
-static int generic_NCR5380_host_reset(Scsi_Cmnd *);
-static int generic_NCR5380_device_reset(Scsi_Cmnd *);
 static const char* generic_NCR5380_info(struct Scsi_Host *);
 
 #ifndef CMD_PER_LUN
@@ -114,8 +112,6 @@ static const char* generic_NCR5380_info(
 #define NCR5380_queue_command generic_NCR5380_queue_command
 #define NCR5380_abort generic_NCR5380_abort
 #define NCR5380_bus_reset generic_NCR5380_bus_reset
-#define NCR5380_device_reset generic_NCR5380_device_reset
-#define NCR5380_host_reset generic_NCR5380_host_reset
 #define NCR5380_pread generic_NCR5380_pread
 #define NCR5380_pwrite generic_NCR5380_pwrite
 #define NCR5380_proc_info notyet_generic_proc_info
diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c
--- a/drivers/scsi/gdth.c
+++ b/drivers/scsi/gdth.c
@@ -4521,9 +4521,7 @@ static int __init gdth_detect(Scsi_Host_
             ha->virt_bus = hdr_channel;
 
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-            scsi_set_device(shp, &pcistr[ctr].pdev->dev);
-#else
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
             scsi_set_pci_device(shp, pcistr[ctr].pdev);
 #endif
             if (!(ha->cache_feat & ha->raw_feat & ha->screen_feat &GDT_64BIT)||
@@ -4703,19 +4701,6 @@ static const char *gdth_info(struct Scsi
     return ((const char *)ha->binfo.type_string);
 }
 
-/* new error handling */
-static int gdth_eh_abort(Scsi_Cmnd *scp)
-{
-    TRACE2(("gdth_eh_abort()\n"));
-    return FAILED;
-}
-
-static int gdth_eh_device_reset(Scsi_Cmnd *scp)
-{
-    TRACE2(("gdth_eh_device_reset()\n"));
-    return FAILED;
-}
-
 static int gdth_eh_bus_reset(Scsi_Cmnd *scp)
 {
     int i, hanum;
@@ -4770,13 +4755,6 @@ static int gdth_eh_bus_reset(Scsi_Cmnd *
     return SUCCESS;
 }
 
-static int gdth_eh_host_reset(Scsi_Cmnd *scp)
-{
-    TRACE2(("gdth_eh_host_reset()\n"));
-    return FAILED;
-}
-
-
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
 static int gdth_bios_param(struct scsi_device *sdev,struct block_device *bdev,sector_t cap,int *ip)
 #else
@@ -5713,10 +5691,7 @@ static Scsi_Host_Template driver_templat
         .release                = gdth_release,
         .info                   = gdth_info, 
         .queuecommand           = gdth_queuecommand,
-        .eh_abort_handler       = gdth_eh_abort, 
-        .eh_device_reset_handler = gdth_eh_device_reset,
         .eh_bus_reset_handler   = gdth_eh_bus_reset,
-        .eh_host_reset_handler  = gdth_eh_host_reset,
         .bios_param             = gdth_bios_param,
         .can_queue              = GDTH_MAXCMDS,
         .this_id                = -1,
diff --git a/drivers/scsi/gvp11.c b/drivers/scsi/gvp11.c
--- a/drivers/scsi/gvp11.c
+++ b/drivers/scsi/gvp11.c
@@ -345,7 +345,15 @@ release:
 static int gvp11_bus_reset(Scsi_Cmnd *cmd)
 {
 	/* FIXME perform bus-specific reset */
+
+	/* FIXME 2: shouldn't we no-op this function (return
+	   FAILED), and fall back to host reset function,
+	   wd33c93_host_reset ? */
+
+	spin_lock_irq(cmd->device->host->host_lock);
 	wd33c93_host_reset(cmd);
+	spin_unlock_irq(cmd->device->host->host_lock);
+
 	return SUCCESS;
 }
 
diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c
--- a/drivers/scsi/hosts.c
+++ b/drivers/scsi/hosts.c
@@ -56,7 +56,7 @@ static struct class shost_class = {
  * @shost:	pointer to struct Scsi_Host
  * recovery:	recovery requested to run.
  **/
-void scsi_host_cancel(struct Scsi_Host *shost, int recovery)
+static void scsi_host_cancel(struct Scsi_Host *shost, int recovery)
 {
 	struct scsi_device *sdev;
 
@@ -180,11 +180,6 @@ static void scsi_host_dev_release(struct
 	scsi_destroy_command_freelist(shost);
 	kfree(shost->shost_data);
 
-	/*
-	 * Some drivers (eg aha1542) do scsi_register()/scsi_unregister()
-	 * during probing without performing a scsi_set_device() in between.
-	 * In this case dev->parent is NULL.
-	 */
 	if (parent)
 		put_device(parent);
 	kfree(shost);
diff --git a/drivers/scsi/ibmmca.c b/drivers/scsi/ibmmca.c
--- a/drivers/scsi/ibmmca.c
+++ b/drivers/scsi/ibmmca.c
@@ -2118,7 +2118,7 @@ static int ibmmca_queuecommand(Scsi_Cmnd
 	return 0;
 }
 
-static int ibmmca_abort(Scsi_Cmnd * cmd)
+static int __ibmmca_abort(Scsi_Cmnd * cmd)
 {
 	/* Abort does not work, as the adapter never generates an interrupt on
 	 * whatever situation is simulated, even when really pending commands
@@ -2225,7 +2225,19 @@ static int ibmmca_abort(Scsi_Cmnd * cmd)
 	}
 }
 
-static int ibmmca_host_reset(Scsi_Cmnd * cmd)
+static int ibmmca_abort(Scsi_Cmnd * cmd)
+{
+	struct Scsi_Host *shpnt = cmd->device->host;
+	int rc;
+
+	spin_lock_irq(shpnt->host_lock);
+	rc = __ibmmca_abort(cmd);
+	spin_unlock_irq(shpnt->host_lock);
+
+	return rc;
+}
+
+static int __ibmmca_host_reset(Scsi_Cmnd * cmd)
 {
 	struct Scsi_Host *shpnt;
 	Scsi_Cmnd *cmd_aid;
@@ -2312,6 +2324,18 @@ static int ibmmca_host_reset(Scsi_Cmnd *
 	return SUCCESS;
 }
 
+static int ibmmca_host_reset(Scsi_Cmnd * cmd)
+{
+	struct Scsi_Host *shpnt = cmd->device->host;
+	int rc;
+
+	spin_lock_irq(shpnt->host_lock);
+	rc = __ibmmca_host_reset(cmd);
+	spin_unlock_irq(shpnt->host_lock);
+
+	return rc;
+}
+
 static int ibmmca_biosparam(struct scsi_device *sdev, struct block_device *bdev, sector_t capacity, int *info)
 {
 	int size = capacity;
diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c
--- a/drivers/scsi/ibmvscsi/ibmvscsi.c
+++ b/drivers/scsi/ibmvscsi/ibmvscsi.c
@@ -87,7 +87,7 @@ static int max_channel = 3;
 static int init_timeout = 5;
 static int max_requests = 50;
 
-#define IBMVSCSI_VERSION "1.5.5"
+#define IBMVSCSI_VERSION "1.5.6"
 
 MODULE_DESCRIPTION("IBM Virtual SCSI");
 MODULE_AUTHOR("Dave Boutcher");
@@ -675,8 +675,6 @@ static void send_mad_adapter_info(struct
 	struct viosrp_adapter_info *req;
 	struct srp_event_struct *evt_struct;
 	
-	memset(&hostdata->madapter_info, 0x00, sizeof(hostdata->madapter_info));
-	
 	evt_struct = get_event_struct(&hostdata->pool);
 	if (!evt_struct) {
 		printk(KERN_ERR "ibmvscsi: couldn't allocate an event "
@@ -874,9 +872,7 @@ static int ibmvscsi_eh_abort_handler(str
 		return FAILED;
 	}
 
-	spin_unlock_irq(hostdata->host->host_lock);
 	wait_for_completion(&evt->comp);
-	spin_lock_irq(hostdata->host->host_lock);
 
 	/* make sure we got a good response */
 	if (unlikely(srp_rsp.srp.generic.type != SRP_RSP_TYPE)) {
@@ -978,9 +974,7 @@ static int ibmvscsi_eh_device_reset_hand
 		return FAILED;
 	}
 
-	spin_unlock_irq(hostdata->host->host_lock);
 	wait_for_completion(&evt->comp);
-	spin_lock_irq(hostdata->host->host_lock);
 
 	/* make sure we got a good response */
 	if (unlikely(srp_rsp.srp.generic.type != SRP_RSP_TYPE)) {
diff --git a/drivers/scsi/ibmvscsi/rpa_vscsi.c b/drivers/scsi/ibmvscsi/rpa_vscsi.c
--- a/drivers/scsi/ibmvscsi/rpa_vscsi.c
+++ b/drivers/scsi/ibmvscsi/rpa_vscsi.c
@@ -33,6 +33,10 @@
 #include <linux/dma-mapping.h>
 #include <linux/interrupt.h>
 #include "ibmvscsi.h"
+#include "srp.h"
+
+static char partition_name[97] = "UNKNOWN";
+static unsigned int partition_number = -1;
 
 /* ------------------------------------------------------------
  * Routines for managing the command/response queue
@@ -148,6 +152,48 @@ static void ibmvscsi_task(void *data)
 	}
 }
 
+static void gather_partition_info(void)
+{
+	struct device_node *rootdn;
+
+	char *ppartition_name;
+	unsigned int *p_number_ptr;
+
+	/* Retrieve information about this partition */
+	rootdn = find_path_device("/");
+	if (!rootdn) {
+		return;
+	}
+
+	ppartition_name =
+		get_property(rootdn, "ibm,partition-name", NULL);
+	if (ppartition_name)
+		strncpy(partition_name, ppartition_name,
+				sizeof(partition_name));
+	p_number_ptr =
+		(unsigned int *)get_property(rootdn, "ibm,partition-no",
+					     NULL);
+	if (p_number_ptr)
+		partition_number = *p_number_ptr;
+}
+
+static void set_adapter_info(struct ibmvscsi_host_data *hostdata)
+{
+	memset(&hostdata->madapter_info, 0x00,
+			sizeof(hostdata->madapter_info));
+
+	printk(KERN_INFO "rpa_vscsi: SPR_VERSION: %s\n", SRP_VERSION);
+	strcpy(hostdata->madapter_info.srp_version, SRP_VERSION);
+
+	strncpy(hostdata->madapter_info.partition_name, partition_name,
+			sizeof(hostdata->madapter_info.partition_name));
+
+	hostdata->madapter_info.partition_number = partition_number;
+
+	hostdata->madapter_info.mad_version = 1;
+	hostdata->madapter_info.os_type = 2;
+}
+
 /**
  * initialize_crq_queue: - Initializes and registers CRQ with hypervisor
  * @queue:	crq_queue to initialize and register
@@ -177,6 +223,9 @@ int ibmvscsi_init_crq_queue(struct crq_q
 	if (dma_mapping_error(queue->msg_token))
 		goto map_failed;
 
+	gather_partition_info();
+	set_adapter_info(hostdata);
+
 	rc = plpar_hcall_norets(H_REG_CRQ,
 				vdev->unit_address,
 				queue->msg_token, PAGE_SIZE);
@@ -246,6 +295,8 @@ void ibmvscsi_reset_crq_queue(struct crq
 	memset(queue->msgs, 0x00, PAGE_SIZE);
 	queue->cur = 0;
 
+	set_adapter_info(hostdata);
+
 	/* And re-open it again */
 	rc = plpar_hcall_norets(H_REG_CRQ,
 				vdev->unit_address,
diff --git a/drivers/scsi/ibmvscsi/srp.h b/drivers/scsi/ibmvscsi/srp.h
--- a/drivers/scsi/ibmvscsi/srp.h
+++ b/drivers/scsi/ibmvscsi/srp.h
@@ -28,12 +28,14 @@
 #ifndef SRP_H
 #define SRP_H
 
+#define SRP_VERSION "16.a"
+
 #define PACKED __attribute__((packed))
 
 enum srp_types {
 	SRP_LOGIN_REQ_TYPE = 0x00,
 	SRP_LOGIN_RSP_TYPE = 0xC0,
-	SRP_LOGIN_REJ_TYPE = 0x80,
+	SRP_LOGIN_REJ_TYPE = 0xC2,
 	SRP_I_LOGOUT_TYPE = 0x03,
 	SRP_T_LOGOUT_TYPE = 0x80,
 	SRP_TSK_MGMT_TYPE = 0x01,
diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
--- a/drivers/scsi/ide-scsi.c
+++ b/drivers/scsi/ide-scsi.c
@@ -46,6 +46,7 @@
 #include <linux/slab.h>
 #include <linux/ide.h>
 #include <linux/scatterlist.h>
+#include <linux/delay.h>
 
 #include <asm/io.h>
 #include <asm/bitops.h>
@@ -1026,11 +1027,13 @@ static int idescsi_eh_reset (struct scsi
 		return FAILED;
 	}
 
-	spin_lock_irq(&ide_lock);
+	spin_lock_irq(cmd->device->host->host_lock);
+	spin_lock(&ide_lock);
 
 	if (!scsi->pc || (req = scsi->pc->rq) != HWGROUP(drive)->rq || !HWGROUP(drive)->handler) {
 		printk (KERN_WARNING "ide-scsi: No active request in idescsi_eh_reset\n");
 		spin_unlock(&ide_lock);
+		spin_unlock_irq(cmd->device->host->host_lock);
 		return FAILED;
 	}
 
@@ -1052,16 +1055,15 @@ static int idescsi_eh_reset (struct scsi
 	HWGROUP(drive)->rq = NULL;
 	HWGROUP(drive)->handler = NULL;
 	HWGROUP(drive)->busy = 1;		/* will set this to zero when ide reset finished */
-	spin_unlock_irq(&ide_lock);
+	spin_unlock(&ide_lock);
 
 	ide_do_reset(drive);
 
 	/* ide_do_reset starts a polling handler which restarts itself every 50ms until the reset finishes */
 
 	do {
-		set_current_state(TASK_UNINTERRUPTIBLE);
 		spin_unlock_irq(cmd->device->host->host_lock);
-		schedule_timeout(HZ/20);
+		msleep(50);
 		spin_lock_irq(cmd->device->host->host_lock);
 	} while ( HWGROUP(drive)->handler );
 
@@ -1072,6 +1074,7 @@ static int idescsi_eh_reset (struct scsi
 		ret = FAILED;
 	}
 
+	spin_unlock_irq(cmd->device->host->host_lock);
 	return ret;
 }
 
diff --git a/drivers/scsi/imm.c b/drivers/scsi/imm.c
--- a/drivers/scsi/imm.c
+++ b/drivers/scsi/imm.c
@@ -18,6 +18,7 @@
 #include <linux/blkdev.h>
 #include <linux/parport.h>
 #include <linux/workqueue.h>
+#include <linux/delay.h>
 #include <asm/io.h>
 
 #include <scsi/scsi.h>
@@ -610,9 +611,9 @@ static int imm_init(imm_struct *dev)
 	if (imm_connect(dev, 0) != 1)
 		return -EIO;
 	imm_reset_pulse(dev->base);
-	udelay(1000);	/* Delay to allow devices to settle */
+	mdelay(1);	/* Delay to allow devices to settle */
 	imm_disconnect(dev);
-	udelay(1000);	/* Another delay to allow devices to settle */
+	mdelay(1);	/* Another delay to allow devices to settle */
 	return device_check(dev);
 }
 
@@ -1026,9 +1027,9 @@ static int imm_reset(struct scsi_cmnd *c
 
 	imm_connect(dev, CONNECT_NORMAL);
 	imm_reset_pulse(dev->base);
-	udelay(1000);		/* device settle delay */
+	mdelay(1);		/* device settle delay */
 	imm_disconnect(dev);
-	udelay(1000);		/* device settle delay */
+	mdelay(1);		/* device settle delay */
 	return SUCCESS;
 }
 
diff --git a/drivers/scsi/in2000.c b/drivers/scsi/in2000.c
--- a/drivers/scsi/in2000.c
+++ b/drivers/scsi/in2000.c
@@ -1644,14 +1644,16 @@ static int in2000_bus_reset(Scsi_Cmnd * 
 	struct Scsi_Host *instance;
 	struct IN2000_hostdata *hostdata;
 	int x;
+	unsigned long flags;
 
 	instance = cmd->device->host;
 	hostdata = (struct IN2000_hostdata *) instance->hostdata;
 
 	printk(KERN_WARNING "scsi%d: Reset. ", instance->host_no);
 
-	/* do scsi-reset here */
+	spin_lock_irqsave(instance->host_lock, flags);
 
+	/* do scsi-reset here */
 	reset_hardware(instance, RESET_CARD_AND_BUS);
 	for (x = 0; x < 8; x++) {
 		hostdata->busy[x] = 0;
@@ -1668,21 +1670,12 @@ static int in2000_bus_reset(Scsi_Cmnd * 
 	hostdata->outgoing_len = 0;
 
 	cmd->result = DID_RESET << 16;
-	return SUCCESS;
-}
 
-static int in2000_host_reset(Scsi_Cmnd * cmd)
-{
-	return FAILED;
-}
-
-static int in2000_device_reset(Scsi_Cmnd * cmd)
-{
-	return FAILED;
+	spin_unlock_irqrestore(instance->host_lock, flags);
+	return SUCCESS;
 }
 
-
-static int in2000_abort(Scsi_Cmnd * cmd)
+static int __in2000_abort(Scsi_Cmnd * cmd)
 {
 	struct Scsi_Host *instance;
 	struct IN2000_hostdata *hostdata;
@@ -1803,6 +1796,16 @@ static int in2000_abort(Scsi_Cmnd * cmd)
 	return SUCCESS;
 }
 
+static int in2000_abort(Scsi_Cmnd * cmd)
+{
+	int rc;
+
+	spin_lock_irq(cmd->device->host->host_lock);
+	rc = __in2000_abort(cmd);
+	spin_unlock_irq(cmd->device->host->host_lock);
+
+	return rc;
+}
 
 
 #define MAX_IN2000_HOSTS 3
@@ -2311,8 +2314,6 @@ static Scsi_Host_Template driver_templat
 	.queuecommand    		= in2000_queuecommand,
 	.eh_abort_handler		= in2000_abort,
 	.eh_bus_reset_handler		= in2000_bus_reset,
-	.eh_device_reset_handler	= in2000_device_reset,
-	.eh_host_reset_handler	= in2000_host_reset, 
 	.bios_param      		= in2000_biosparam, 
 	.can_queue       		= IN2000_CAN_Q,
 	.this_id         		= IN2000_HOST_ID,
diff --git a/drivers/scsi/in2000.h b/drivers/scsi/in2000.h
--- a/drivers/scsi/in2000.h
+++ b/drivers/scsi/in2000.h
@@ -401,9 +401,7 @@ static int in2000_abort(Scsi_Cmnd *);
 static void in2000_setup(char *, int *) in2000__INIT;
 static int in2000_biosparam(struct scsi_device *, struct block_device *,
 		sector_t, int *);
-static int in2000_host_reset(Scsi_Cmnd *);
 static int in2000_bus_reset(Scsi_Cmnd *);
-static int in2000_device_reset(Scsi_Cmnd *);
 
 
 #define IN2000_CAN_Q    16
diff --git a/drivers/scsi/initio.c b/drivers/scsi/initio.c
--- a/drivers/scsi/initio.c
+++ b/drivers/scsi/initio.c
@@ -223,7 +223,7 @@ static void tul_select_atn(HCS * pCurHcb
 static void tul_select_atn3(HCS * pCurHcb, SCB * pCurScb);
 static void tul_select_atn_stop(HCS * pCurHcb, SCB * pCurScb);
 static int int_tul_busfree(HCS * pCurHcb);
-int int_tul_scsi_rst(HCS * pCurHcb);
+static int int_tul_scsi_rst(HCS * pCurHcb);
 static int int_tul_bad_seq(HCS * pCurHcb);
 static int int_tul_resel(HCS * pCurHcb);
 static int tul_sync_done(HCS * pCurHcb);
@@ -240,9 +240,8 @@ static int tul_se2_rd_all(WORD CurBase);
 static void tul_se2_update_all(WORD CurBase);	/* setup default pattern */
 static void tul_read_eeprom(WORD CurBase);
 
-				/* ---- EXTERNAL VARIABLES ---- */
-HCS tul_hcs[MAX_SUPPORTED_ADAPTERS];
 				/* ---- INTERNAL VARIABLES ---- */
+static HCS tul_hcs[MAX_SUPPORTED_ADAPTERS];
 static INI_ADPT_STRUCT i91u_adpt[MAX_SUPPORTED_ADAPTERS];
 
 /*NVRAM nvram, *nvramp = &nvram; */
@@ -381,7 +380,7 @@ void tul_se2_wait(void)
 
 
 ******************************************************************/
-void tul_se2_instr(WORD CurBase, UCHAR instr)
+static void tul_se2_instr(WORD CurBase, UCHAR instr)
 {
 	int i;
 	UCHAR b;
@@ -437,7 +436,7 @@ void tul_se2_ew_ds(WORD CurBase)
 	Input  :address of Serial E2PROM
 	Output :value stored in  Serial E2PROM
 *******************************************************************/
-USHORT tul_se2_rd(WORD CurBase, ULONG adr)
+static USHORT tul_se2_rd(WORD CurBase, ULONG adr)
 {
 	UCHAR instr, readByte;
 	USHORT readWord;
@@ -468,7 +467,7 @@ USHORT tul_se2_rd(WORD CurBase, ULONG ad
 /******************************************************************
  Input: new value in  Serial E2PROM, address of Serial E2PROM
 *******************************************************************/
-void tul_se2_wr(WORD CurBase, UCHAR adr, USHORT writeWord)
+static void tul_se2_wr(WORD CurBase, UCHAR adr, USHORT writeWord)
 {
 	UCHAR readByte;
 	UCHAR instr;
@@ -584,8 +583,8 @@ void tul_read_eeprom(WORD CurBase)
 	TUL_WR(CurBase + TUL_GCTRL, gctrl & ~TUL_GCTRL_EEPROM_BIT);
 }				/* read_eeprom */
 
-int Addi91u_into_Adapter_table(WORD wBIOS, WORD wBASE, BYTE bInterrupt,
-			       BYTE bBus, BYTE bDevice)
+static int Addi91u_into_Adapter_table(WORD wBIOS, WORD wBASE, BYTE bInterrupt,
+				      BYTE bBus, BYTE bDevice)
 {
 	int i, j;
 
@@ -616,7 +615,7 @@ int Addi91u_into_Adapter_table(WORD wBIO
 	return 1;
 }
 
-void init_i91uAdapter_table(void)
+static void init_i91uAdapter_table(void)
 {
 	int i;
 
@@ -630,7 +629,7 @@ void init_i91uAdapter_table(void)
 	return;
 }
 
-void tul_stop_bm(HCS * pCurHcb)
+static void tul_stop_bm(HCS * pCurHcb)
 {
 
 	if (TUL_RD(pCurHcb->HCS_Base, TUL_XStatus) & XPEND) {	/* if DMA xfer is pending, abort DMA xfer */
@@ -642,7 +641,7 @@ void tul_stop_bm(HCS * pCurHcb)
 }
 
 /***************************************************************************/
-void get_tulipPCIConfig(HCS * pCurHcb, int ch_idx)
+static void get_tulipPCIConfig(HCS * pCurHcb, int ch_idx)
 {
 	pCurHcb->HCS_Base = i91u_adpt[ch_idx].ADPT_BASE;	/* Supply base address  */
 	pCurHcb->HCS_BIOS = i91u_adpt[ch_idx].ADPT_BIOS;	/* Supply BIOS address  */
@@ -651,7 +650,7 @@ void get_tulipPCIConfig(HCS * pCurHcb, i
 }
 
 /***************************************************************************/
-int tul_reset_scsi(HCS * pCurHcb, int seconds)
+static int tul_reset_scsi(HCS * pCurHcb, int seconds)
 {
 	TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_RST_BUS);
 
@@ -670,7 +669,8 @@ int tul_reset_scsi(HCS * pCurHcb, int se
 }
 
 /***************************************************************************/
-int init_tulip(HCS * pCurHcb, SCB * scbp, int tul_num_scb, BYTE * pbBiosAdr, int seconds)
+static int init_tulip(HCS * pCurHcb, SCB * scbp, int tul_num_scb,
+		      BYTE * pbBiosAdr, int seconds)
 {
 	int i;
 	BYTE *pwFlags;
@@ -716,7 +716,7 @@ int init_tulip(HCS * pCurHcb, SCB * scbp
 	pCurHcb->HCS_SCSI_ID = i91unvramp->NVM_SCSIInfo[0].NVM_ChSCSIID;
 	pCurHcb->HCS_IdMask = ~(1 << pCurHcb->HCS_SCSI_ID);
 
-#if CHK_PARITY
+#ifdef CHK_PARITY
 	/* Enable parity error response */
 	TUL_WR(pCurHcb->HCS_Base + TUL_PCMD, TUL_RD(pCurHcb->HCS_Base, TUL_PCMD) | 0x40);
 #endif
@@ -788,7 +788,7 @@ int init_tulip(HCS * pCurHcb, SCB * scbp
 }
 
 /***************************************************************************/
-SCB *tul_alloc_scb(HCS * hcsp)
+static SCB *tul_alloc_scb(HCS * hcsp)
 {
 	SCB *pTmpScb;
 	ULONG flags;
@@ -807,7 +807,7 @@ SCB *tul_alloc_scb(HCS * hcsp)
 }
 
 /***************************************************************************/
-void tul_release_scb(HCS * hcsp, SCB * scbp)
+static void tul_release_scb(HCS * hcsp, SCB * scbp)
 {
 	ULONG flags;
 
@@ -829,7 +829,7 @@ void tul_release_scb(HCS * hcsp, SCB * s
 }
 
 /***************************************************************************/
-void tul_append_pend_scb(HCS * pCurHcb, SCB * scbp)
+static void tul_append_pend_scb(HCS * pCurHcb, SCB * scbp)
 {
 
 #if DEBUG_QUEUE
@@ -847,7 +847,7 @@ void tul_append_pend_scb(HCS * pCurHcb, 
 }
 
 /***************************************************************************/
-void tul_push_pend_scb(HCS * pCurHcb, SCB * scbp)
+static void tul_push_pend_scb(HCS * pCurHcb, SCB * scbp)
 {
 
 #if DEBUG_QUEUE
@@ -863,7 +863,7 @@ void tul_push_pend_scb(HCS * pCurHcb, SC
 }
 
 /***************************************************************************/
-SCB *tul_find_first_pend_scb(HCS * pCurHcb)
+static SCB *tul_find_first_pend_scb(HCS * pCurHcb)
 {
 	SCB *pFirstPend;
 
@@ -894,24 +894,7 @@ SCB *tul_find_first_pend_scb(HCS * pCurH
 	return (pFirstPend);
 }
 /***************************************************************************/
-SCB *tul_pop_pend_scb(HCS * pCurHcb)
-{
-	SCB *pTmpScb;
-
-	if ((pTmpScb = pCurHcb->HCS_FirstPend) != NULL) {
-		if ((pCurHcb->HCS_FirstPend = pTmpScb->SCB_NxtScb) == NULL)
-			pCurHcb->HCS_LastPend = NULL;
-		pTmpScb->SCB_NxtScb = NULL;
-	}
-#if DEBUG_QUEUE
-	printk("Pop pend SCB %lx; ", (ULONG) pTmpScb);
-#endif
-	return (pTmpScb);
-}
-
-
-/***************************************************************************/
-void tul_unlink_pend_scb(HCS * pCurHcb, SCB * pCurScb)
+static void tul_unlink_pend_scb(HCS * pCurHcb, SCB * pCurScb)
 {
 	SCB *pTmpScb, *pPrevScb;
 
@@ -939,7 +922,7 @@ void tul_unlink_pend_scb(HCS * pCurHcb, 
 	return;
 }
 /***************************************************************************/
-void tul_append_busy_scb(HCS * pCurHcb, SCB * scbp)
+static void tul_append_busy_scb(HCS * pCurHcb, SCB * scbp)
 {
 
 #if DEBUG_QUEUE
@@ -961,7 +944,7 @@ void tul_append_busy_scb(HCS * pCurHcb, 
 }
 
 /***************************************************************************/
-SCB *tul_pop_busy_scb(HCS * pCurHcb)
+static SCB *tul_pop_busy_scb(HCS * pCurHcb)
 {
 	SCB *pTmpScb;
 
@@ -982,7 +965,7 @@ SCB *tul_pop_busy_scb(HCS * pCurHcb)
 }
 
 /***************************************************************************/
-void tul_unlink_busy_scb(HCS * pCurHcb, SCB * pCurScb)
+static void tul_unlink_busy_scb(HCS * pCurHcb, SCB * pCurScb)
 {
 	SCB *pTmpScb, *pPrevScb;
 
@@ -1037,7 +1020,7 @@ SCB *tul_find_busy_scb(HCS * pCurHcb, WO
 }
 
 /***************************************************************************/
-void tul_append_done_scb(HCS * pCurHcb, SCB * scbp)
+static void tul_append_done_scb(HCS * pCurHcb, SCB * scbp)
 {
 
 #if DEBUG_QUEUE
@@ -1073,7 +1056,7 @@ SCB *tul_find_done_scb(HCS * pCurHcb)
 }
 
 /***************************************************************************/
-int tul_abort_srb(HCS * pCurHcb, struct scsi_cmnd *srbp)
+static int tul_abort_srb(HCS * pCurHcb, struct scsi_cmnd *srbp)
 {
 	ULONG flags;
 	SCB *pTmpScb, *pPrevScb;
@@ -1163,7 +1146,7 @@ int tul_abort_srb(HCS * pCurHcb, struct 
 }
 
 /***************************************************************************/
-int tul_bad_seq(HCS * pCurHcb)
+static int tul_bad_seq(HCS * pCurHcb)
 {
 	SCB *pCurScb;
 
@@ -1182,9 +1165,11 @@ int tul_bad_seq(HCS * pCurHcb)
 	return (tul_post_scsi_rst(pCurHcb));
 }
 
+#if 0
+
 /************************************************************************/
-int tul_device_reset(HCS * pCurHcb, struct scsi_cmnd *pSrb,
-		unsigned int target, unsigned int ResetFlags)
+static int tul_device_reset(HCS * pCurHcb, struct scsi_cmnd *pSrb,
+			    unsigned int target, unsigned int ResetFlags)
 {
 	ULONG flags;
 	SCB *pScb;
@@ -1255,7 +1240,7 @@ int tul_device_reset(HCS * pCurHcb, stru
 	return SCSI_RESET_PENDING;
 }
 
-int tul_reset_scsi_bus(HCS * pCurHcb)
+static int tul_reset_scsi_bus(HCS * pCurHcb)
 {
 	ULONG flags;
 
@@ -1284,8 +1269,10 @@ int tul_reset_scsi_bus(HCS * pCurHcb)
 	return (SCSI_RESET_SUCCESS | SCSI_RESET_HOST_RESET);
 }
 
+#endif  /*  0  */
+
 /************************************************************************/
-void tul_exec_scb(HCS * pCurHcb, SCB * pCurScb)
+static void tul_exec_scb(HCS * pCurHcb, SCB * pCurScb)
 {
 	ULONG flags;
 
@@ -1318,7 +1305,7 @@ void tul_exec_scb(HCS * pCurHcb, SCB * p
 }
 
 /***************************************************************************/
-int tul_isr(HCS * pCurHcb)
+static int tul_isr(HCS * pCurHcb)
 {
 	/* Enter critical section       */
 
@@ -2108,7 +2095,7 @@ int int_tul_busfree(HCS * pCurHcb)
 
 /***************************************************************************/
 /* scsi bus reset */
-int int_tul_scsi_rst(HCS * pCurHcb)
+static int int_tul_scsi_rst(HCS * pCurHcb)
 {
 	SCB *pCurScb;
 	int i;
@@ -2214,7 +2201,7 @@ int int_tul_resel(HCS * pCurHcb)
 
 
 /***************************************************************************/
-int int_tul_bad_seq(HCS * pCurHcb)
+static int int_tul_bad_seq(HCS * pCurHcb)
 {				/* target wrong phase           */
 	SCB *pCurScb;
 	int i;
@@ -3014,7 +3001,11 @@ static int i91u_bus_reset(struct scsi_cm
 	HCS *pHCB;
 
 	pHCB = (HCS *) SCpnt->device->host->base;
+
+	spin_lock_irq(SCpnt->device->host->host_lock);
 	tul_reset_scsi(pHCB, 0);
+	spin_unlock_irq(SCpnt->device->host->host_lock);
+
 	return SUCCESS;
 }
 
diff --git a/drivers/scsi/initio.h b/drivers/scsi/initio.h
--- a/drivers/scsi/initio.h
+++ b/drivers/scsi/initio.h
@@ -719,21 +719,3 @@ typedef struct _HCSinfo {
 #define SCSI_RESET_HOST_RESET 0x200
 #define SCSI_RESET_ACTION   0xff
 
-extern void init_i91uAdapter_table(void);
-extern int Addi91u_into_Adapter_table(WORD, WORD, BYTE, BYTE, BYTE);
-extern int tul_ReturnNumberOfAdapters(void);
-extern void get_tulipPCIConfig(HCS * pHCB, int iChannel_index);
-extern int init_tulip(HCS * pHCB, SCB * pSCB, int tul_num_scb, BYTE * pbBiosAdr, int reset_time);
-extern SCB *tul_alloc_scb(HCS * pHCB);
-extern int tul_abort_srb(HCS * pHCB, struct scsi_cmnd * pSRB);
-extern void tul_exec_scb(HCS * pHCB, SCB * pSCB);
-extern void tul_release_scb(HCS * pHCB, SCB * pSCB);
-extern void tul_stop_bm(HCS * pHCB);
-extern int tul_reset_scsi(HCS * pCurHcb, int seconds);
-extern int tul_isr(HCS * pHCB);
-extern int tul_reset(HCS * pHCB, struct scsi_cmnd * pSRB, unsigned char target);
-extern int tul_reset_scsi_bus(HCS * pCurHcb);
-extern int tul_device_reset(HCS * pCurHcb, struct scsi_cmnd *pSrb,
-		unsigned int target, unsigned int ResetFlags);
-				/* ---- EXTERNAL VARIABLES ---- */
-extern HCS tul_hcs[];
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -1053,7 +1053,7 @@ static void ipr_log_array_error(struct i
 				array_entry->dev_res_addr.lun);
 		}
 
-		if (array_entry->dev_res_addr.bus >= IPR_MAX_NUM_BUSES) {
+		if (array_entry->expected_dev_res_addr.bus >= IPR_MAX_NUM_BUSES) {
 			ipr_err("Expected Location: unknown\n");
 		} else {
 			ipr_err("Expected Location: %d:%d:%d:%d\n",
@@ -2716,7 +2716,7 @@ static int ipr_change_queue_type(struct 
  * Return value:
  * 	number of bytes printed to buffer
  **/
-static ssize_t ipr_show_adapter_handle(struct device *dev, char *buf)
+static ssize_t ipr_show_adapter_handle(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct scsi_device *sdev = to_scsi_device(dev);
 	struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *)sdev->host->hostdata;
@@ -2885,7 +2885,7 @@ static int ipr_slave_alloc(struct scsi_d
  * Return value:
  * 	SUCCESS / FAILED
  **/
-static int ipr_eh_host_reset(struct scsi_cmnd * scsi_cmd)
+static int __ipr_eh_host_reset(struct scsi_cmnd * scsi_cmd)
 {
 	struct ipr_ioa_cfg *ioa_cfg;
 	int rc;
@@ -2905,6 +2905,17 @@ static int ipr_eh_host_reset(struct scsi
 	return rc;
 }
 
+static int ipr_eh_host_reset(struct scsi_cmnd * cmd)
+{
+	int rc;
+
+	spin_lock_irq(cmd->device->host->host_lock);
+	rc = __ipr_eh_host_reset(cmd);
+	spin_unlock_irq(cmd->device->host->host_lock);
+
+	return rc;
+}
+
 /**
  * ipr_eh_dev_reset - Reset the device
  * @scsi_cmd:	scsi command struct
@@ -2916,7 +2927,7 @@ static int ipr_eh_host_reset(struct scsi
  * Return value:
  *	SUCCESS / FAILED
  **/
-static int ipr_eh_dev_reset(struct scsi_cmnd * scsi_cmd)
+static int __ipr_eh_dev_reset(struct scsi_cmnd * scsi_cmd)
 {
 	struct ipr_cmnd *ipr_cmd;
 	struct ipr_ioa_cfg *ioa_cfg;
@@ -2970,6 +2981,17 @@ static int ipr_eh_dev_reset(struct scsi_
 	return (IPR_IOASC_SENSE_KEY(ioasc) ? FAILED : SUCCESS);
 }
 
+static int ipr_eh_dev_reset(struct scsi_cmnd * cmd)
+{
+	int rc;
+
+	spin_lock_irq(cmd->device->host->host_lock);
+	rc = __ipr_eh_dev_reset(cmd);
+	spin_unlock_irq(cmd->device->host->host_lock);
+
+	return rc;
+}
+
 /**
  * ipr_bus_reset_done - Op done function for bus reset.
  * @ipr_cmd:	ipr command struct
@@ -3068,6 +3090,12 @@ static int ipr_cancel_op(struct scsi_cmn
 	ioa_cfg = (struct ipr_ioa_cfg *)scsi_cmd->device->host->hostdata;
 	res = scsi_cmd->device->hostdata;
 
+	/* If we are currently going through reset/reload, return failed.
+	 * This will force the mid-layer to call ipr_eh_host_reset,
+	 * which will then go to sleep and wait for the reset to complete
+	 */
+	if (ioa_cfg->in_reset_reload || ioa_cfg->ioa_is_dead)
+		return FAILED;
 	if (!res || (!ipr_is_gscsi(res) && !ipr_is_vset_device(res)))
 		return FAILED;
 
@@ -3118,23 +3146,17 @@ static int ipr_cancel_op(struct scsi_cmn
  **/
 static int ipr_eh_abort(struct scsi_cmnd * scsi_cmd)
 {
-	struct ipr_ioa_cfg *ioa_cfg;
+	unsigned long flags;
+	int rc;
 
 	ENTER;
-	ioa_cfg = (struct ipr_ioa_cfg *) scsi_cmd->device->host->hostdata;
 
-	/* If we are currently going through reset/reload, return failed. This will force the
-	   mid-layer to call ipr_eh_host_reset, which will then go to sleep and wait for the
-	   reset to complete */
-	if (ioa_cfg->in_reset_reload)
-		return FAILED;
-	if (ioa_cfg->ioa_is_dead)
-		return FAILED;
-	if (!scsi_cmd->device->hostdata)
-		return FAILED;
+	spin_lock_irqsave(scsi_cmd->device->host->host_lock, flags);
+	rc = ipr_cancel_op(scsi_cmd);
+	spin_unlock_irqrestore(scsi_cmd->device->host->host_lock, flags);
 
 	LEAVE;
-	return ipr_cancel_op(scsi_cmd);
+	return rc;
 }
 
 /**
@@ -5886,6 +5908,7 @@ static void __ipr_remove(struct pci_dev 
 
 	spin_unlock_irqrestore(ioa_cfg->host->host_lock, host_lock_flags);
 	wait_event(ioa_cfg->reset_wait_q, !ioa_cfg->in_reset_reload);
+	flush_scheduled_work();
 	spin_lock_irqsave(ioa_cfg->host->host_lock, host_lock_flags);
 
 	spin_lock(&ipr_driver_lock);
@@ -5916,8 +5939,6 @@ static void ipr_remove(struct pci_dev *p
 
 	ENTER;
 
-	ioa_cfg->allow_cmds = 0;
-	flush_scheduled_work();
 	ipr_remove_trace_file(&ioa_cfg->host->shost_classdev.kobj,
 			      &ipr_trace_attr);
 	ipr_remove_dump_file(&ioa_cfg->host->shost_classdev.kobj,
@@ -5991,7 +6012,7 @@ static int __devinit ipr_probe(struct pc
 
 /**
  * ipr_shutdown - Shutdown handler.
- * @dev:	device struct
+ * @pdev:	pci device struct
  *
  * This function is invoked upon system shutdown/reboot. It will issue
  * an adapter shutdown to the adapter to flush the write cache.
@@ -5999,9 +6020,9 @@ static int __devinit ipr_probe(struct pc
  * Return value:
  * 	none
  **/
-static void ipr_shutdown(struct device *dev)
+static void ipr_shutdown(struct pci_dev *pdev)
 {
-	struct ipr_ioa_cfg *ioa_cfg = pci_get_drvdata(to_pci_dev(dev));
+	struct ipr_ioa_cfg *ioa_cfg = pci_get_drvdata(pdev);
 	unsigned long lock_flags = 0;
 
 	spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
@@ -6047,9 +6068,7 @@ static struct pci_driver ipr_driver = {
 	.id_table = ipr_pci_table,
 	.probe = ipr_probe,
 	.remove = ipr_remove,
-	.driver = {
-		.shutdown = ipr_shutdown,
-	},
+	.shutdown = ipr_shutdown,
 };
 
 /**
diff --git a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h
--- a/drivers/scsi/ipr.h
+++ b/drivers/scsi/ipr.h
@@ -36,8 +36,8 @@
 /*
  * Literals
  */
-#define IPR_DRIVER_VERSION "2.0.13"
-#define IPR_DRIVER_DATE "(February 21, 2005)"
+#define IPR_DRIVER_VERSION "2.0.14"
+#define IPR_DRIVER_DATE "(May 2, 2005)"
 
 /*
  * IPR_DBG_TRACE: Setting this to 1 will turn on some general function tracing
diff --git a/drivers/scsi/ips.c b/drivers/scsi/ips.c
--- a/drivers/scsi/ips.c
+++ b/drivers/scsi/ips.c
@@ -133,10 +133,12 @@
 /* 6.10.00  - Remove 1G Addressing Limitations                               */
 /* 6.11.xx  - Get VersionInfo buffer off the stack !              DDTS 60401 */
 /* 6.11.xx  - Make Logical Drive Info structure safe for DMA      DDTS 60639 */
-/* 7.10.xx  - Add highmem_io flag in SCSI Templete for 2.4 kernels           */
+/* 7.10.18  - Add highmem_io flag in SCSI Templete for 2.4 kernels           */
 /*          - Fix path/name for scsi_hosts.h include for 2.6 kernels         */
 /*          - Fix sort order of 7k                                           */
 /*          - Remove 3 unused "inline" functions                             */
+/* 7.12.xx  - Use STATIC functions whereever possible                        */
+/*          - Clean up deprecated MODULE_PARM calls                          */
 /*****************************************************************************/
 
 /*
@@ -207,8 +209,8 @@ module_param(ips, charp, 0);
 /*
  * DRIVER_VER
  */
-#define IPS_VERSION_HIGH        "7.10"
-#define IPS_VERSION_LOW         ".18 "
+#define IPS_VERSION_HIGH        "7.12"
+#define IPS_VERSION_LOW         ".02 "
 
 #if !defined(__i386__) && !defined(__ia64__) && !defined(__x86_64__)
 #warning "This driver has only been tested on the x86/ia64/x86_64 platforms"
@@ -819,12 +821,15 @@ ips_eh_abort(Scsi_Cmnd * SC)
 	ips_ha_t *ha;
 	ips_copp_wait_item_t *item;
 	int ret;
+	unsigned long cpu_flags;
+	struct Scsi_Host *host;
 
 	METHOD_TRACE("ips_eh_abort", 1);
 
 	if (!SC)
 		return (FAILED);
 
+	host = SC->device->host;
 	ha = (ips_ha_t *) SC->device->host->hostdata;
 
 	if (!ha)
@@ -833,6 +838,8 @@ ips_eh_abort(Scsi_Cmnd * SC)
 	if (!ha->active)
 		return (FAILED);
 
+	IPS_LOCK_SAVE(host->host_lock, cpu_flags);
+
 	/* See if the command is on the copp queue */
 	item = ha->copp_waitlist.head;
 	while ((item) && (item->scsi_cmd != SC))
@@ -851,6 +858,8 @@ ips_eh_abort(Scsi_Cmnd * SC)
 		/* command must have already been sent */
 		ret = (FAILED);
 	}
+
+	IPS_UNLOCK_RESTORE(host->host_lock, cpu_flags);
 	return ret;
 }
 
@@ -866,7 +875,7 @@ ips_eh_abort(Scsi_Cmnd * SC)
 /*                                                                          */
 /****************************************************************************/
 static int
-ips_eh_reset(Scsi_Cmnd * SC)
+__ips_eh_reset(Scsi_Cmnd * SC)
 {
 	int ret;
 	int i;
@@ -1053,6 +1062,18 @@ ips_eh_reset(Scsi_Cmnd * SC)
 
 }
 
+static int
+ips_eh_reset(Scsi_Cmnd * SC)
+{
+	int rc;
+
+	spin_lock_irq(SC->device->host->host_lock);
+	rc = __ips_eh_reset(SC);
+	spin_unlock_irq(SC->device->host->host_lock);
+
+	return rc;
+}
+
 /****************************************************************************/
 /*                                                                          */
 /* Routine Name: ips_queue                                                  */
diff --git a/drivers/scsi/ips.h b/drivers/scsi/ips.h
--- a/drivers/scsi/ips.h
+++ b/drivers/scsi/ips.h
@@ -87,15 +87,14 @@
       #define scsi_set_pci_device(sh,dev) (0)
    #endif
 
-   #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-   
-      #ifndef irqreturn_t
-         typedef void irqreturn_t;
-      #endif 
-      
+   #ifndef IRQ_NONE
+      typedef void irqreturn_t;
       #define IRQ_NONE
       #define IRQ_HANDLED
       #define IRQ_RETVAL(x)
+   #endif
+   
+   #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
       #define IPS_REGISTER_HOSTS(SHT)      scsi_register_module(MODULE_SCSI_HA,SHT)
       #define IPS_UNREGISTER_HOSTS(SHT)    scsi_unregister_module(MODULE_SCSI_HA,SHT)
       #define IPS_ADD_HOST(shost,device)
@@ -111,7 +110,7 @@
       #define IPS_UNREGISTER_HOSTS(SHT)
       #define IPS_ADD_HOST(shost,device)   do { scsi_add_host(shost,device); scsi_scan_host(shost); } while (0)
       #define IPS_REMOVE_HOST(shost)       scsi_remove_host(shost)
-      #define IPS_SCSI_SET_DEVICE(sh,ha)   scsi_set_device(sh, &(ha)->pcidev->dev)
+      #define IPS_SCSI_SET_DEVICE(sh,ha)   do { } while (0)
       #define IPS_PRINTK(level, pcidev, format, arg...)                 \
             dev_printk(level , &((pcidev)->dev) , format , ## arg)
    #endif
@@ -123,6 +122,10 @@
    #ifndef min
       #define min(x,y) ((x) < (y) ? x : y)
    #endif
+   
+   #ifndef __iomem       /* For clean compiles in earlier kernels without __iomem annotations */
+      #define __iomem
+   #endif
 
    #define pci_dma_hi32(a)         ((a >> 16) >> 16)
    #define pci_dma_lo32(a)         (a & 0xffffffff)
@@ -1206,13 +1209,13 @@ typedef struct {
 
 #define IPS_VER_MAJOR 7
 #define IPS_VER_MAJOR_STRING "7"
-#define IPS_VER_MINOR 10
-#define IPS_VER_MINOR_STRING "10"
-#define IPS_VER_BUILD 18
-#define IPS_VER_BUILD_STRING "18"
-#define IPS_VER_STRING "7.10.18"
+#define IPS_VER_MINOR 12
+#define IPS_VER_MINOR_STRING "12"
+#define IPS_VER_BUILD 02
+#define IPS_VER_BUILD_STRING "02"
+#define IPS_VER_STRING "7.12.02"
 #define IPS_RELEASE_ID 0x00020000
-#define IPS_BUILD_IDENT 731
+#define IPS_BUILD_IDENT 761
 #define IPS_LEGALCOPYRIGHT_STRING "(C) Copyright IBM Corp. 1994, 2002. All Rights Reserved."
 #define IPS_ADAPTECCOPYRIGHT_STRING "(c) Copyright Adaptec, Inc. 2002 to 2004. All Rights Reserved."
 #define IPS_DELLCOPYRIGHT_STRING "(c) Copyright Dell 2004. All Rights Reserved."
@@ -1223,12 +1226,12 @@ typedef struct {
 #define IPS_VER_SERVERAID2 "2.88.13"
 #define IPS_VER_NAVAJO "2.88.13"
 #define IPS_VER_SERVERAID3 "6.10.24"
-#define IPS_VER_SERVERAID4H "7.10.11"
-#define IPS_VER_SERVERAID4MLx "7.10.18"
-#define IPS_VER_SARASOTA "7.10.18"
-#define IPS_VER_MARCO "7.10.18"
-#define IPS_VER_SEBRING "7.10.18"
-#define IPS_VER_KEYWEST "7.10.18"
+#define IPS_VER_SERVERAID4H "7.12.02"
+#define IPS_VER_SERVERAID4MLx "7.12.02"
+#define IPS_VER_SARASOTA "7.12.02"
+#define IPS_VER_MARCO "7.12.02"
+#define IPS_VER_SEBRING "7.12.02"
+#define IPS_VER_KEYWEST "7.12.02"
 
 /* Compatability IDs for various adapters */
 #define IPS_COMPAT_UNKNOWN ""
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -1295,6 +1295,37 @@ err_out:
 	DPRINTK("EXIT, err\n");
 }
 
+
+static inline u8 ata_dev_knobble(struct ata_port *ap)
+{
+	return ((ap->cbl == ATA_CBL_SATA) && (!ata_id_is_sata(ap->device->id)));
+}
+
+/**
+ * 	ata_dev_config - Run device specific handlers and check for
+ * 			 SATA->PATA bridges
+ * 	@ap: Bus 
+ * 	@i:  Device
+ *
+ * 	LOCKING:
+ */
+ 
+void ata_dev_config(struct ata_port *ap, unsigned int i)
+{
+	/* limit bridge transfers to udma5, 200 sectors */
+	if (ata_dev_knobble(ap)) {
+		printk(KERN_INFO "ata%u(%u): applying bridge limits\n",
+			ap->id, ap->device->devno);
+		ap->udma_mask &= ATA_UDMA5;
+		ap->host->max_sectors = ATA_MAX_SECTORS;
+		ap->host->hostt->max_sectors = ATA_MAX_SECTORS;
+		ap->device->flags |= ATA_DFLAG_LOCK_SECTORS;
+	}
+
+	if (ap->ops->dev_config)
+		ap->ops->dev_config(ap, &ap->device[i]);
+}
+
 /**
  *	ata_bus_probe - Reset and probe ATA bus
  *	@ap: Bus to probe
@@ -1322,8 +1353,7 @@ static int ata_bus_probe(struct ata_port
 		ata_dev_identify(ap, i);
 		if (ata_dev_present(&ap->device[i])) {
 			found = 1;
-			if (ap->ops->dev_config)
-				ap->ops->dev_config(ap, &ap->device[i]);
+			ata_dev_config(ap,i);
 		}
 	}
 
@@ -1378,7 +1408,9 @@ void __sata_phy_reset(struct ata_port *a
 	if (ap->flags & ATA_FLAG_SATA_RESET) {
 		/* issue phy wake/reset */
 		scr_write_flush(ap, SCR_CONTROL, 0x301);
-		udelay(400);			/* FIXME: a guess */
+		/* Couldn't find anything in SATA I/II specs, but
+		 * AHCI-1.1 10.4.2 says at least 1 ms. */
+		mdelay(1);
 	}
 	scr_write_flush(ap, SCR_CONTROL, 0x300); /* phy wake/clear reset */
 
@@ -1890,6 +1922,7 @@ static const char * ata_dma_blacklist []
 	"HITACHI CDR-8335",
 	"HITACHI CDR-8435",
 	"Toshiba CD-ROM XM-6202B",
+	"TOSHIBA CD-ROM XM-1702BC",
 	"CD-532E-A",
 	"E-IDE CD-ROM CR-840",
 	"CD-ROM Drive/F5A",
@@ -1897,7 +1930,6 @@ static const char * ata_dma_blacklist []
 	"SAMSUNG CD-ROM SC-148C",
 	"SAMSUNG CD-ROM SC",
 	"SanDisk SDP3B-64",
-	"SAMSUNG CD-ROM SN-124",
 	"ATAPI CD-ROM DRIVE 40X MAXIMUM",
 	"_NEC DV5800A",
 };
@@ -2236,19 +2268,6 @@ void ata_qc_prep(struct ata_queued_cmd *
  *	spin_lock_irqsave(host_set lock)
  */
 
-
-
-/**
- *	ata_sg_init_one - Prepare a one-entry scatter-gather list.
- *	@qc:  Queued command
- *	@buf:  transfer buffer
- *	@buflen:  length of buf
- *
- *	Builds a single-entry scatter-gather list to initiate a
- *	transfer utilizing the specified buffer.
- *
- *	LOCKING:
- */
 void ata_sg_init_one(struct ata_queued_cmd *qc, void *buf, unsigned int buflen)
 {
 	struct scatterlist *sg;
@@ -2280,18 +2299,6 @@ void ata_sg_init_one(struct ata_queued_c
  *	spin_lock_irqsave(host_set lock)
  */
 
-
-/**
- *	ata_sg_init - Assign a scatter gather list to a queued command
- *	@qc:  Queued command
- *	@sg:  Scatter-gather list
- *	@n_elem:  length of sg list
- *
- *	Attaches a scatter-gather list to a queued command.
- *
- *	LOCKING:
- */
-
 void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg,
 		 unsigned int n_elem)
 {
@@ -2834,7 +2841,7 @@ static void ata_qc_timeout(struct ata_qu
 	if (qc->dev->class == ATA_DEV_ATAPI && qc->scsicmd) {
 		struct scsi_cmnd *cmd = qc->scsicmd;
 
-		if (!scsi_eh_eflags_chk(cmd, SCSI_EH_CANCEL_CMD)) {
+		if (!(cmd->eh_eflags & SCSI_EH_CANCEL_CMD)) {
 
 			/* finish completing original command */
 			__ata_qc_complete(qc);
@@ -3718,7 +3725,7 @@ static void ata_host_init(struct ata_por
 	host->max_channel = 1;
 	host->unique_id = ata_unique_id++;
 	host->max_cmd_len = 12;
-	scsi_set_device(host, ent->dev);
+
 	scsi_assign_lock(host, &host_set->lock);
 
 	ap->flags = ATA_FLAG_PORT_DISABLED;
@@ -4406,6 +4413,7 @@ EXPORT_SYMBOL_GPL(ata_scsi_release);
 EXPORT_SYMBOL_GPL(ata_host_intr);
 EXPORT_SYMBOL_GPL(ata_dev_classify);
 EXPORT_SYMBOL_GPL(ata_dev_id_string);
+EXPORT_SYMBOL_GPL(ata_dev_config);
 EXPORT_SYMBOL_GPL(ata_scsi_simulate);
 
 #ifdef CONFIG_PCI
diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c
--- a/drivers/scsi/libata-scsi.c
+++ b/drivers/scsi/libata-scsi.c
@@ -385,6 +385,7 @@ int ata_scsi_error(struct Scsi_Host *hos
 	 * appropriate place
 	 */
 	host->host_failed--;
+	INIT_LIST_HEAD(&host->eh_cmd_q);
 
 	DPRINTK("EXIT\n");
 	return 0;
@@ -1176,8 +1177,12 @@ unsigned int ata_scsiop_read_cap(struct 
 		n_sectors = ata_id_u32(args->id, 60);
 	n_sectors--;		/* ATA TotalUserSectors - 1 */
 
-	tmp = n_sectors;	/* note: truncates, if lba48 */
 	if (args->cmd->cmnd[0] == READ_CAPACITY) {
+		if( n_sectors >= 0xffffffffULL )
+			tmp = 0xffffffff ;  /* Return max count on overflow */
+		else
+			tmp = n_sectors ;
+
 		/* sector count, 32-bit */
 		rbuf[0] = tmp >> (8 * 3);
 		rbuf[1] = tmp >> (8 * 2);
@@ -1191,10 +1196,12 @@ unsigned int ata_scsiop_read_cap(struct 
 
 	} else {
 		/* sector count, 64-bit */
-		rbuf[2] = n_sectors >> (8 * 7);
-		rbuf[3] = n_sectors >> (8 * 6);
-		rbuf[4] = n_sectors >> (8 * 5);
-		rbuf[5] = n_sectors >> (8 * 4);
+		tmp = n_sectors >> (8 * 4);
+		rbuf[2] = tmp >> (8 * 3);
+		rbuf[3] = tmp >> (8 * 2);
+		rbuf[4] = tmp >> (8 * 1);
+		rbuf[5] = tmp;
+		tmp = n_sectors;
 		rbuf[6] = tmp >> (8 * 3);
 		rbuf[7] = tmp >> (8 * 2);
 		rbuf[8] = tmp >> (8 * 1);
diff --git a/drivers/scsi/libata.h b/drivers/scsi/libata.h
--- a/drivers/scsi/libata.h
+++ b/drivers/scsi/libata.h
@@ -26,7 +26,7 @@
 #define __LIBATA_H__
 
 #define DRV_NAME	"libata"
-#define DRV_VERSION	"1.11"	/* must be exactly four chars */
+#define DRV_VERSION	"1.12"	/* must be exactly four chars */
 
 struct ata_scsi_args {
 	u16			*id;
diff --git a/drivers/scsi/lpfc/Makefile b/drivers/scsi/lpfc/Makefile
--- a/drivers/scsi/lpfc/Makefile
+++ b/drivers/scsi/lpfc/Makefile
@@ -1,26 +1,24 @@
 #/*******************************************************************
 # * This file is part of the Emulex Linux Device Driver for         *
-# * Enterprise Fibre Channel Host Bus Adapters.                     *
-# * Refer to the README file included with this package for         *
-# * driver version and adapter support.                             *
-# * Copyright (C) 2004 Emulex Corporation.                          *
+# * Fibre Channel Host Bus Adapters.                                *
+# * Copyright (C) 2004-2005 Emulex.  All rights reserved.           *
+# * EMULEX and SLI are trademarks of Emulex.                        *
 # * www.emulex.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, a copy of which    *
-# * can be found in the file COPYING included with this package.    *
+# * modify it under the terms of version 2 of the GNU General       *
+# * Public License as published by the Free Software Foundation.    *
+# * This program is distributed in the hope that it will be useful. *
+# * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND          *
+# * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,  *
+# * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE      *
+# * DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD *
+# * TO BE LEGALLY INVALID.  See the GNU General Public License for  *
+# * more details, a copy of which can be found in the file COPYING  *
+# * included with this package.                                     *
 # *******************************************************************/
 ######################################################################
 
-#$Id: Makefile 1.58 2005/01/23 19:00:32EST sf_support Exp  $
-
 ifneq ($(GCOV),)
   EXTRA_CFLAGS += -fprofile-arcs -ftest-coverage
   EXTRA_CFLAGS += -O0
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
--- a/drivers/scsi/lpfc/lpfc.h
+++ b/drivers/scsi/lpfc/lpfc.h
@@ -1,27 +1,24 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
- * Enterprise Fibre Channel Host Bus Adapters.                     *
- * Refer to the README file included with this package for         *
- * driver version and adapter support.                             *
- * Copyright (C) 2004 Emulex Corporation.                          *
+ * Fibre Channel Host Bus Adapters.                                *
+ * Copyright (C) 2004-2005 Emulex.  All rights reserved.           *
+ * EMULEX and SLI are trademarks of Emulex.                        *
  * www.emulex.com                                                  *
+ * Portions Copyright (C) 2004-2005 Christoph Hellwig              *
  *                                                                 *
  * 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, a copy of which    *
- * can be found in the file COPYING included with this package.    *
+ * modify it under the terms of version 2 of the GNU General       *
+ * Public License as published by the Free Software Foundation.    *
+ * This program is distributed in the hope that it will be useful. *
+ * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND          *
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,  *
+ * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE      *
+ * DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD *
+ * TO BE LEGALLY INVALID.  See the GNU General Public License for  *
+ * more details, a copy of which can be found in the file COPYING  *
+ * included with this package.                                     *
  *******************************************************************/
 
-/*
- * $Id: lpfc.h 1.167 2005/04/07 08:47:05EDT sf_support Exp  $
- */
-
 struct lpfc_sli2_slim;
 
 #define LPFC_MAX_TARGET         256	/* max targets supported */
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -1,27 +1,24 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
- * Enterprise Fibre Channel Host Bus Adapters.                     *
- * Refer to the README file included with this package for         *
- * driver version and adapter support.                             *
- * Copyright (C) 2004 Emulex Corporation.                          *
+ * Fibre Channel Host Bus Adapters.                                *
+ * Copyright (C) 2004-2005 Emulex.  All rights reserved.           *
+ * EMULEX and SLI are trademarks of Emulex.                        *
  * www.emulex.com                                                  *
+ * Portions Copyright (C) 2004-2005 Christoph Hellwig              *
  *                                                                 *
  * 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, a copy of which    *
- * can be found in the file COPYING included with this package.    *
+ * modify it under the terms of version 2 of the GNU General       *
+ * Public License as published by the Free Software Foundation.    *
+ * This program is distributed in the hope that it will be useful. *
+ * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND          *
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,  *
+ * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE      *
+ * DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD *
+ * TO BE LEGALLY INVALID.  See the GNU General Public License for  *
+ * more details, a copy of which can be found in the file COPYING  *
+ * included with this package.                                     *
  *******************************************************************/
 
-/*
- * $Id: lpfc_attr.c 1.24 2005/04/13 11:58:55EDT sf_support Exp  $
- */
-
 #include <linux/ctype.h>
 #include <linux/pci.h>
 #include <linux/interrupt.h>
diff --git a/drivers/scsi/lpfc/lpfc_compat.h b/drivers/scsi/lpfc/lpfc_compat.h
--- a/drivers/scsi/lpfc/lpfc_compat.h
+++ b/drivers/scsi/lpfc/lpfc_compat.h
@@ -1,26 +1,24 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
- * Enterprise Fibre Channel Host Bus Adapters.                     *
- * Refer to the README file included with this package for         *
- * driver version and adapter support.                             *
- * Copyright (C) 2004 Emulex Corporation.                          *
+ * Fibre Channel Host Bus Adapters.                                *
+ * Copyright (C) 2004-2005 Emulex.  All rights reserved.           *
+ * EMULEX and SLI are trademarks of Emulex.                        *
  * www.emulex.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, a copy of which    *
- * can be found in the file COPYING included with this package.    *
+ * modify it under the terms of version 2 of the GNU General       *
+ * Public License as published by the Free Software Foundation.    *
+ * This program is distributed in the hope that it will be useful. *
+ * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND          *
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,  *
+ * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE      *
+ * DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD *
+ * TO BE LEGALLY INVALID.  See the GNU General Public License for  *
+ * more details, a copy of which can be found in the file COPYING  *
+ * included with this package.                                     *
  *******************************************************************/
 
 /*
- * $Id: lpfc_compat.h 1.32 2005/01/25 17:51:45EST sf_support Exp  $
- *
  * This file provides macros to aid compilation in the Linux 2.4 kernel
  * over various platform architectures.
  */
@@ -32,8 +30,9 @@ memcpy_toio() and memcpy_fromio() can be
 However on a big-endian host, copy 4 bytes at a time,
 using writel() and readl().
  *******************************************************************/
+#include <asm/byteorder.h>
 
-#if __BIG_ENDIAN
+#ifdef __BIG_ENDIAN
 
 static inline void
 lpfc_memcpy_to_slim(void __iomem *dest, void *src, unsigned int bytes)
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h
--- a/drivers/scsi/lpfc/lpfc_crtn.h
+++ b/drivers/scsi/lpfc/lpfc_crtn.h
@@ -1,27 +1,23 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
- * Enterprise Fibre Channel Host Bus Adapters.                     *
- * Refer to the README file included with this package for         *
- * driver version and adapter support.                             *
- * Copyright (C) 2004 Emulex Corporation.                          *
+ * Fibre Channel Host Bus Adapters.                                *
+ * Copyright (C) 2004-2005 Emulex.  All rights reserved.           *
+ * EMULEX and SLI are trademarks of Emulex.                        *
  * www.emulex.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, a copy of which    *
- * can be found in the file COPYING included with this package.    *
+ * modify it under the terms of version 2 of the GNU General       *
+ * Public License as published by the Free Software Foundation.    *
+ * This program is distributed in the hope that it will be useful. *
+ * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND          *
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,  *
+ * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE      *
+ * DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD *
+ * TO BE LEGALLY INVALID.  See the GNU General Public License for  *
+ * more details, a copy of which can be found in the file COPYING  *
+ * included with this package.                                     *
  *******************************************************************/
 
-/*
- * $Id: lpfc_crtn.h 1.166 2005/04/07 08:46:47EDT sf_support Exp  $
- */
-
 void lpfc_dump_mem(struct lpfc_hba *, LPFC_MBOXQ_t *, uint16_t);
 void lpfc_read_nv(struct lpfc_hba *, LPFC_MBOXQ_t *);
 int lpfc_read_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb,
@@ -195,6 +191,9 @@ int lpfc_sli_issue_iocb_wait_high_priori
 void lpfc_sli_wake_iocb_high_priority(struct lpfc_hba * phba,
 				      struct lpfc_iocbq * queue1,
 				      struct lpfc_iocbq * queue2);
+void lpfc_sli_abort_fcp_cmpl(struct lpfc_hba * phba,
+			     struct lpfc_iocbq * cmdiocb,
+			     struct lpfc_iocbq * rspiocb);
 
 void *lpfc_mbuf_alloc(struct lpfc_hba *, int, dma_addr_t *);
 void lpfc_mbuf_free(struct lpfc_hba *, void *, dma_addr_t);
diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c
--- a/drivers/scsi/lpfc/lpfc_ct.c
+++ b/drivers/scsi/lpfc/lpfc_ct.c
@@ -1,26 +1,24 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
- * Enterprise Fibre Channel Host Bus Adapters.                     *
- * Refer to the README file included with this package for         *
- * driver version and adapter support.                             *
- * Copyright (C) 2004 Emulex Corporation.                          *
+ * Fibre Channel Host Bus Adapters.                                *
+ * Copyright (C) 2004-2005 Emulex.  All rights reserved.           *
+ * EMULEX and SLI are trademarks of Emulex.                        *
  * www.emulex.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, a copy of which    *
- * can be found in the file COPYING included with this package.    *
+ * modify it under the terms of version 2 of the GNU General       *
+ * Public License as published by the Free Software Foundation.    *
+ * This program is distributed in the hope that it will be useful. *
+ * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND          *
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,  *
+ * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE      *
+ * DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD *
+ * TO BE LEGALLY INVALID.  See the GNU General Public License for  *
+ * more details, a copy of which can be found in the file COPYING  *
+ * included with this package.                                     *
  *******************************************************************/
 
 /*
- * $Id: lpfc_ct.c 1.161 2005/04/13 11:59:01EDT sf_support Exp  $
- *
  * Fibre Channel SCSI LAN Device Driver CT support
  */
 
diff --git a/drivers/scsi/lpfc/lpfc_disc.h b/drivers/scsi/lpfc/lpfc_disc.h
--- a/drivers/scsi/lpfc/lpfc_disc.h
+++ b/drivers/scsi/lpfc/lpfc_disc.h
@@ -1,27 +1,23 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
- * Enterprise Fibre Channel Host Bus Adapters.                     *
- * Refer to the README file included with this package for         *
- * driver version and adapter support.                             *
- * Copyright (C) 2004 Emulex Corporation.                          *
+ * Fibre Channel Host Bus Adapters.                                *
+ * Copyright (C) 2004-2005 Emulex.  All rights reserved.           *
+ * EMULEX and SLI are trademarks of Emulex.                        *
  * www.emulex.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, a copy of which    *
- * can be found in the file COPYING included with this package.    *
+ * modify it under the terms of version 2 of the GNU General       *
+ * Public License as published by the Free Software Foundation.    *
+ * This program is distributed in the hope that it will be useful. *
+ * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND          *
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,  *
+ * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE      *
+ * DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD *
+ * TO BE LEGALLY INVALID.  See the GNU General Public License for  *
+ * more details, a copy of which can be found in the file COPYING  *
+ * included with this package.                                     *
  *******************************************************************/
 
-/*
- * $Id: lpfc_disc.h 1.61 2005/04/07 08:46:52EDT sf_support Exp  $
- */
-
 #define FC_MAX_HOLD_RSCN     32	      /* max number of deferred RSCNs */
 #define FC_MAX_NS_RSP        65536    /* max size NameServer rsp */
 #define FC_MAXLOOP           126      /* max devices supported on a fc loop */
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -1,27 +1,24 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
- * Enterprise Fibre Channel Host Bus Adapters.                     *
- * Refer to the README file included with this package for         *
- * driver version and adapter support.                             *
- * Copyright (C) 2004 Emulex Corporation.                          *
+ * Fibre Channel Host Bus Adapters.                                *
+ * Copyright (C) 2004-2005 Emulex.  All rights reserved.           *
+ * EMULEX and SLI are trademarks of Emulex.                        *
  * www.emulex.com                                                  *
+ * Portions Copyright (C) 2004-2005 Christoph Hellwig              *
  *                                                                 *
  * 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, a copy of which    *
- * can be found in the file COPYING included with this package.    *
+ * modify it under the terms of version 2 of the GNU General       *
+ * Public License as published by the Free Software Foundation.    *
+ * This program is distributed in the hope that it will be useful. *
+ * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND          *
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,  *
+ * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE      *
+ * DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD *
+ * TO BE LEGALLY INVALID.  See the GNU General Public License for  *
+ * more details, a copy of which can be found in the file COPYING  *
+ * included with this package.                                     *
  *******************************************************************/
 
-/*
- * $Id: lpfc_els.c 1.186 2005/04/13 14:26:55EDT sf_support Exp  $
- */
-
 #include <linux/blkdev.h>
 #include <linux/pci.h>
 #include <linux/interrupt.h>
@@ -3139,7 +3136,7 @@ lpfc_els_unsol_event(struct lpfc_hba * p
 	case ELS_CMD_PLOGI:
 		phba->fc_stat.elsRcvPLOGI++;
 		if (phba->hba_state < LPFC_DISC_AUTH) {
-			rjt_err = LSEXP_NOTHING_MORE;
+			rjt_err = 1;
 			break;
 		}
 		lpfc_disc_state_machine(phba, ndlp, elsiocb, NLP_EVT_RCV_PLOGI);
@@ -3154,7 +3151,7 @@ lpfc_els_unsol_event(struct lpfc_hba * p
 	case ELS_CMD_LOGO:
 		phba->fc_stat.elsRcvLOGO++;
 		if (phba->hba_state < LPFC_DISC_AUTH) {
-			rjt_err = LSEXP_NOTHING_MORE;
+			rjt_err = 1;
 			break;
 		}
 		lpfc_disc_state_machine(phba, ndlp, elsiocb, NLP_EVT_RCV_LOGO);
@@ -3162,7 +3159,7 @@ lpfc_els_unsol_event(struct lpfc_hba * p
 	case ELS_CMD_PRLO:
 		phba->fc_stat.elsRcvPRLO++;
 		if (phba->hba_state < LPFC_DISC_AUTH) {
-			rjt_err = LSEXP_NOTHING_MORE;
+			rjt_err = 1;
 			break;
 		}
 		lpfc_disc_state_machine(phba, ndlp, elsiocb, NLP_EVT_RCV_PRLO);
@@ -3177,7 +3174,7 @@ lpfc_els_unsol_event(struct lpfc_hba * p
 	case ELS_CMD_ADISC:
 		phba->fc_stat.elsRcvADISC++;
 		if (phba->hba_state < LPFC_DISC_AUTH) {
-			rjt_err = LSEXP_NOTHING_MORE;
+			rjt_err = 1;
 			break;
 		}
 		lpfc_disc_state_machine(phba, ndlp, elsiocb, NLP_EVT_RCV_ADISC);
@@ -3185,7 +3182,7 @@ lpfc_els_unsol_event(struct lpfc_hba * p
 	case ELS_CMD_PDISC:
 		phba->fc_stat.elsRcvPDISC++;
 		if (phba->hba_state < LPFC_DISC_AUTH) {
-			rjt_err = LSEXP_NOTHING_MORE;
+			rjt_err = 1;
 			break;
 		}
 		lpfc_disc_state_machine(phba, ndlp, elsiocb, NLP_EVT_RCV_PDISC);
@@ -3209,7 +3206,7 @@ lpfc_els_unsol_event(struct lpfc_hba * p
 	case ELS_CMD_PRLI:
 		phba->fc_stat.elsRcvPRLI++;
 		if (phba->hba_state < LPFC_DISC_AUTH) {
-			rjt_err = LSEXP_NOTHING_MORE;
+			rjt_err = 1;
 			break;
 		}
 		lpfc_disc_state_machine(phba, ndlp, elsiocb, NLP_EVT_RCV_PRLI);
@@ -3220,7 +3217,7 @@ lpfc_els_unsol_event(struct lpfc_hba * p
 		break;
 	default:
 		/* Unsupported ELS command, reject */
-		rjt_err = LSEXP_NOTHING_MORE;
+		rjt_err = 1;
 
 		/* Unknown ELS command <elsCmd> received from NPORT <did> */
 		lpfc_printf_log(phba, KERN_ERR, LOG_ELS,
@@ -3236,7 +3233,7 @@ lpfc_els_unsol_event(struct lpfc_hba * p
 	if (rjt_err) {
 		stat.un.b.lsRjtRsvd0 = 0;
 		stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
-		stat.un.b.lsRjtRsnCodeExp = rjt_err;
+		stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE;
 		stat.un.b.vendorUnique = 0;
 		lpfc_els_rsp_reject(phba, stat.un.lsRjtError, elsiocb, ndlp);
 	}
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -1,27 +1,24 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
- * Enterprise Fibre Channel Host Bus Adapters.                     *
- * Refer to the README file included with this package for         *
- * driver version and adapter support.                             *
- * Copyright (C) 2004 Emulex Corporation.                          *
+ * Fibre Channel Host Bus Adapters.                                *
+ * Copyright (C) 2004-2005 Emulex.  All rights reserved.           *
+ * EMULEX and SLI are trademarks of Emulex.                        *
  * www.emulex.com                                                  *
+ * Portions Copyright (C) 2004-2005 Christoph Hellwig              *
  *                                                                 *
  * 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, a copy of which    *
- * can be found in the file COPYING included with this package.    *
+ * modify it under the terms of version 2 of the GNU General       *
+ * Public License as published by the Free Software Foundation.    *
+ * This program is distributed in the hope that it will be useful. *
+ * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND          *
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,  *
+ * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE      *
+ * DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD *
+ * TO BE LEGALLY INVALID.  See the GNU General Public License for  *
+ * more details, a copy of which can be found in the file COPYING  *
+ * included with this package.                                     *
  *******************************************************************/
 
-/*
- * $Id: lpfc_hbadisc.c 1.266 2005/04/13 11:59:06EDT sf_support Exp  $
- */
-
 #include <linux/blkdev.h>
 #include <linux/pci.h>
 #include <linux/kthread.h>
@@ -61,14 +58,7 @@ static void lpfc_disc_timeout_handler(st
 static void
 lpfc_process_nodev_timeout(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)
 {
-	if (!(ndlp->nlp_type & NLP_FABRIC)) {
-		/* Nodev timeout on NPort <nlp_DID> */
-		lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
-			"%d:0203 Nodev timeout on NPort x%x "
-			"Data: x%x x%x x%x\n",
-			phba->brd_no, ndlp->nlp_DID, ndlp->nlp_flag,
-			ndlp->nlp_state, ndlp->nlp_rpi);
-	}
+	int warn_on = 0;
 
 	spin_lock_irq(phba->host->host_lock);
 	if (!(ndlp->nlp_flag & NLP_NODEV_TMO)) {
@@ -79,12 +69,27 @@ lpfc_process_nodev_timeout(struct lpfc_h
 	ndlp->nlp_flag &= ~NLP_NODEV_TMO;
 
 	if (ndlp->nlp_sid != NLP_NO_SID) {
+		warn_on = 1;
 		/* flush the target */
 		lpfc_sli_abort_iocb(phba, &phba->sli.ring[phba->sli.fcp_ring],
 			ndlp->nlp_sid, 0, 0, LPFC_CTX_TGT);
 	}
 	spin_unlock_irq(phba->host->host_lock);
 
+	if (warn_on) {
+		lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
+				"%d:0203 Nodev timeout on NPort x%x "
+				"Data: x%x x%x x%x\n",
+				phba->brd_no, ndlp->nlp_DID, ndlp->nlp_flag,
+				ndlp->nlp_state, ndlp->nlp_rpi);
+	} else {
+		lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
+				"%d:0204 Nodev timeout on NPort x%x "
+				"Data: x%x x%x x%x\n",
+				phba->brd_no, ndlp->nlp_DID, ndlp->nlp_flag,
+				ndlp->nlp_state, ndlp->nlp_rpi);
+	}
+
 	lpfc_disc_state_machine(phba, ndlp, NULL, NLP_EVT_DEVICE_RM);
 	return;
 }
diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h
--- a/drivers/scsi/lpfc/lpfc_hw.h
+++ b/drivers/scsi/lpfc/lpfc_hw.h
@@ -1,27 +1,23 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
- * Enterprise Fibre Channel Host Bus Adapters.                     *
- * Refer to the README file included with this package for         *
- * driver version and adapter support.                             *
- * Copyright (C) 2004 Emulex Corporation.                          *
+ * Fibre Channel Host Bus Adapters.                                *
+ * Copyright (C) 2004-2005 Emulex.  All rights reserved.           *
+ * EMULEX and SLI are trademarks of Emulex.                        *
  * www.emulex.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, a copy of which    *
- * can be found in the file COPYING included with this package.    *
+ * modify it under the terms of version 2 of the GNU General       *
+ * Public License as published by the Free Software Foundation.    *
+ * This program is distributed in the hope that it will be useful. *
+ * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND          *
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,  *
+ * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE      *
+ * DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD *
+ * TO BE LEGALLY INVALID.  See the GNU General Public License for  *
+ * more details, a copy of which can be found in the file COPYING  *
+ * included with this package.                                     *
  *******************************************************************/
 
-/*
- * $Id: lpfc_hw.h 1.37 2005/03/29 19:51:45EST sf_support Exp  $
- */
-
 #define FDMI_DID        0xfffffaU
 #define NameServer_DID  0xfffffcU
 #define SCR_DID         0xfffffdU
@@ -2214,20 +2210,20 @@ typedef union {
  * SLI-2 specific structures
  */
 
-typedef struct {
-	uint32_t cmdPutInx;
-	uint32_t rspGetInx;
-} HGP;
+struct lpfc_hgp {
+	__le32 cmdPutInx;
+	__le32 rspGetInx;
+};
 
-typedef struct {
-	uint32_t cmdGetInx;
-	uint32_t rspPutInx;
-} PGP;
+struct lpfc_pgp {
+	__le32 cmdGetInx;
+	__le32 rspPutInx;
+};
 
 typedef struct _SLI2_DESC {
-	HGP host[MAX_RINGS];
+	struct lpfc_hgp host[MAX_RINGS];
 	uint32_t unused1[16];
-	PGP port[MAX_RINGS];
+	struct lpfc_pgp port[MAX_RINGS];
 } SLI2_DESC;
 
 typedef union {
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -1,27 +1,24 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
- * Enterprise Fibre Channel Host Bus Adapters.                     *
- * Refer to the README file included with this package for         *
- * driver version and adapter support.                             *
- * Copyright (C) 2004 Emulex Corporation.                          *
+ * Fibre Channel Host Bus Adapters.                                *
+ * Copyright (C) 2004-2005 Emulex.  All rights reserved.           *
+ * EMULEX and SLI are trademarks of Emulex.                        *
  * www.emulex.com                                                  *
+ * Portions Copyright (C) 2004-2005 Christoph Hellwig              *
  *                                                                 *
  * 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, a copy of which    *
- * can be found in the file COPYING included with this package.    *
+ * modify it under the terms of version 2 of the GNU General       *
+ * Public License as published by the Free Software Foundation.    *
+ * This program is distributed in the hope that it will be useful. *
+ * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND          *
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,  *
+ * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE      *
+ * DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD *
+ * TO BE LEGALLY INVALID.  See the GNU General Public License for  *
+ * more details, a copy of which can be found in the file COPYING  *
+ * included with this package.                                     *
  *******************************************************************/
 
-/*
- * $Id: lpfc_init.c 1.233 2005/04/13 11:59:09EDT sf_support Exp  $
- */
-
 #include <linux/blkdev.h>
 #include <linux/delay.h>
 #include <linux/dma-mapping.h>
@@ -780,6 +777,9 @@ lpfc_get_hba_model_desc(struct lpfc_hba 
 	pci_read_config_dword(phba->pcidev, PCI_VENDOR_ID, &id);
 
 	switch ((id >> 16) & 0xffff) {
+	case PCI_DEVICE_ID_FIREFLY:
+		strcpy(str, "LP6000 1");
+		break;
 	case PCI_DEVICE_ID_SUPERFLY:
 		if (vp->rev.biuRev >= 1 && vp->rev.biuRev <= 3)
 			strcpy(str, "LP7000 1");
@@ -837,6 +837,9 @@ lpfc_get_hba_model_desc(struct lpfc_hba 
 	case PCI_DEVICE_ID_LP10000S:
 		strcpy(str, "LP10000-S 2");
 		break;
+	default:
+		memset(str, 0, 16);
+		break;
 	}
 	if (mdp)
 		sscanf(str, "%s", mdp);
@@ -1662,6 +1665,8 @@ lpfc_pci_remove_one(struct pci_dev *pdev
 static struct pci_device_id lpfc_id_table[] = {
 	{PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_VIPER,
 		PCI_ANY_ID, PCI_ANY_ID, },
+	{PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_FIREFLY,
+		PCI_ANY_ID, PCI_ANY_ID, },
 	{PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_THOR,
 		PCI_ANY_ID, PCI_ANY_ID, },
 	{PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_PEGASUS,
@@ -1712,6 +1717,7 @@ lpfc_init(void)
 	int error = 0;
 
 	printk(LPFC_MODULE_DESC "\n");
+	printk(LPFC_COPYRIGHT "\n");
 
 	lpfc_transport_template =
 				fc_attach_transport(&lpfc_transport_functions);
diff --git a/drivers/scsi/lpfc/lpfc_logmsg.h b/drivers/scsi/lpfc/lpfc_logmsg.h
--- a/drivers/scsi/lpfc/lpfc_logmsg.h
+++ b/drivers/scsi/lpfc/lpfc_logmsg.h
@@ -1,27 +1,23 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
- * Enterprise Fibre Channel Host Bus Adapters.                     *
- * Refer to the README file included with this package for         *
- * driver version and adapter support.                             *
- * Copyright (C) 2004 Emulex Corporation.                          *
+ * Fibre Channel Host Bus Adapters.                                *
+ * Copyright (C) 2004-2005 Emulex.  All rights reserved.           *
+ * EMULEX and SLI are trademarks of Emulex.                        *
  * www.emulex.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, a copy of which    *
- * can be found in the file COPYING included with this package.    *
+ * modify it under the terms of version 2 of the GNU General       *
+ * Public License as published by the Free Software Foundation.    *
+ * This program is distributed in the hope that it will be useful. *
+ * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND          *
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,  *
+ * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE      *
+ * DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD *
+ * TO BE LEGALLY INVALID.  See the GNU General Public License for  *
+ * more details, a copy of which can be found in the file COPYING  *
+ * included with this package.                                     *
  *******************************************************************/
 
-/*
- * $Id: lpfc_logmsg.h 1.32 2005/01/25 17:52:01EST sf_support Exp  $
- */
-
 #define LOG_ELS                       0x1	/* ELS events */
 #define LOG_DISCOVERY                 0x2	/* Link discovery events */
 #define LOG_MBOX                      0x4	/* Mailbox events */
diff --git a/drivers/scsi/lpfc/lpfc_mbox.c b/drivers/scsi/lpfc/lpfc_mbox.c
--- a/drivers/scsi/lpfc/lpfc_mbox.c
+++ b/drivers/scsi/lpfc/lpfc_mbox.c
@@ -1,27 +1,24 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
- * Enterprise Fibre Channel Host Bus Adapters.                     *
- * Refer to the README file included with this package for         *
- * driver version and adapter support.                             *
- * Copyright (C) 2004 Emulex Corporation.                          *
+ * Fibre Channel Host Bus Adapters.                                *
+ * Copyright (C) 2004-2005 Emulex.  All rights reserved.           *
+ * EMULEX and SLI are trademarks of Emulex.                        *
  * www.emulex.com                                                  *
+ * Portions Copyright (C) 2004-2005 Christoph Hellwig              *
  *                                                                 *
  * 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, a copy of which    *
- * can be found in the file COPYING included with this package.    *
+ * modify it under the terms of version 2 of the GNU General       *
+ * Public License as published by the Free Software Foundation.    *
+ * This program is distributed in the hope that it will be useful. *
+ * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND          *
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,  *
+ * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE      *
+ * DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD *
+ * TO BE LEGALLY INVALID.  See the GNU General Public License for  *
+ * more details, a copy of which can be found in the file COPYING  *
+ * included with this package.                                     *
  *******************************************************************/
 
-/*
- * $Id: lpfc_mbox.c 1.85 2005/04/13 11:59:11EDT sf_support Exp  $
- */
-
 #include <linux/blkdev.h>
 #include <linux/pci.h>
 #include <linux/interrupt.h>
@@ -422,7 +419,6 @@ lpfc_config_pcb_setup(struct lpfc_hba * 
 	uint32_t iocbCnt;
 	int i;
 
-	psli->MBhostaddr = (uint32_t *)&phba->slim2p->mbx;
 	pcbp->maxRing = (psli->num_rings - 1);
 
 	iocbCnt = 0;
@@ -528,7 +524,7 @@ lpfc_config_port(struct lpfc_hba * phba,
 	dma_addr_t pdma_addr;
 	uint32_t bar_low, bar_high;
 	size_t offset;
-	HGP hgp;
+	struct lpfc_hgp hgp;
 	void __iomem *to_slim;
 
 	memset(pmb, 0, sizeof(LPFC_MBOXQ_t));
@@ -584,9 +580,9 @@ lpfc_config_port(struct lpfc_hba * phba,
 	else
 		phba->slim2p->pcb.hgpAddrHigh = 0;
 	/* write HGP data to SLIM at the required longword offset */
-	memset(&hgp, 0, sizeof(HGP));
+	memset(&hgp, 0, sizeof(struct lpfc_hgp));
 	to_slim = phba->MBslimaddr + (SLIMOFF*sizeof (uint32_t));
-	lpfc_memcpy_to_slim(to_slim, &hgp, sizeof (HGP));
+	lpfc_memcpy_to_slim(to_slim, &hgp, sizeof(struct lpfc_hgp));
 
 	/* Setup Port Group ring pointer */
 	offset = (uint8_t *)&phba->slim2p->mbx.us.s2.port -
diff --git a/drivers/scsi/lpfc/lpfc_mem.c b/drivers/scsi/lpfc/lpfc_mem.c
--- a/drivers/scsi/lpfc/lpfc_mem.c
+++ b/drivers/scsi/lpfc/lpfc_mem.c
@@ -1,27 +1,24 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
- * Enterprise Fibre Channel Host Bus Adapters.                     *
- * Refer to the README file included with this package for         *
- * driver version and adapter support.                             *
- * Copyright (C) 2004 Emulex Corporation.                          *
+ * Fibre Channel Host Bus Adapters.                                *
+ * Copyright (C) 2004-2005 Emulex.  All rights reserved.           *
+ * EMULEX and SLI are trademarks of Emulex.                        *
  * www.emulex.com                                                  *
+ * Portions Copyright (C) 2004-2005 Christoph Hellwig              *
  *                                                                 *
  * 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, a copy of which    *
- * can be found in the file COPYING included with this package.    *
+ * modify it under the terms of version 2 of the GNU General       *
+ * Public License as published by the Free Software Foundation.    *
+ * This program is distributed in the hope that it will be useful. *
+ * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND          *
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,  *
+ * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE      *
+ * DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD *
+ * TO BE LEGALLY INVALID.  See the GNU General Public License for  *
+ * more details, a copy of which can be found in the file COPYING  *
+ * included with this package.                                     *
  *******************************************************************/
 
-/*
- * $Id: lpfc_mem.c 1.79 2005/04/13 14:25:50EDT sf_support Exp  $
- */
-
 #include <linux/mempool.h>
 #include <linux/pci.h>
 #include <linux/interrupt.h>
diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c
--- a/drivers/scsi/lpfc/lpfc_nportdisc.c
+++ b/drivers/scsi/lpfc/lpfc_nportdisc.c
@@ -1,27 +1,24 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
- * Enterprise Fibre Channel Host Bus Adapters.                     *
- * Refer to the README file included with this package for         *
- * driver version and adapter support.                             *
- * Copyright (C) 2004 Emulex Corporation.                          *
+ * Fibre Channel Host Bus Adapters.                                *
+ * Copyright (C) 2004-2005 Emulex.  All rights reserved.           *
+ * EMULEX and SLI are trademarks of Emulex.                        *
  * www.emulex.com                                                  *
+ * Portions Copyright (C) 2004-2005 Christoph Hellwig              *
  *                                                                 *
  * 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, a copy of which    *
- * can be found in the file COPYING included with this package.    *
+ * modify it under the terms of version 2 of the GNU General       *
+ * Public License as published by the Free Software Foundation.    *
+ * This program is distributed in the hope that it will be useful. *
+ * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND          *
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,  *
+ * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE      *
+ * DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD *
+ * TO BE LEGALLY INVALID.  See the GNU General Public License for  *
+ * more details, a copy of which can be found in the file COPYING  *
+ * included with this package.                                     *
  *******************************************************************/
 
-/*
- * $Id: lpfc_nportdisc.c 1.179 2005/04/13 11:59:13EDT sf_support Exp  $
- */
-
 #include <linux/blkdev.h>
 #include <linux/pci.h>
 #include <linux/interrupt.h>
@@ -950,8 +947,13 @@ lpfc_cmpl_adisc_adisc_issue(struct lpfc_
 		lpfc_unreg_rpi(phba, ndlp);
 		return (ndlp->nlp_state);
 	}
-	ndlp->nlp_state = NLP_STE_MAPPED_NODE;
-	lpfc_nlp_list(phba, ndlp, NLP_MAPPED_LIST);
+	if (ndlp->nlp_type & NLP_FCP_TARGET) {
+		ndlp->nlp_state = NLP_STE_MAPPED_NODE;
+		lpfc_nlp_list(phba, ndlp, NLP_MAPPED_LIST);
+	} else {
+		ndlp->nlp_state = NLP_STE_UNMAPPED_NODE;
+		lpfc_nlp_list(phba, ndlp, NLP_UNMAPPED_LIST);
+	}
 	return (ndlp->nlp_state);
 }
 
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -1,27 +1,24 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
- * Enterprise Fibre Channel Host Bus Adapters.                     *
- * Refer to the README file included with this package for         *
- * driver version and adapter support.                             *
- * Copyright (C) 2004 Emulex Corporation.                          *
+ * Fibre Channel Host Bus Adapters.                                *
+ * Copyright (C) 2004-2005 Emulex.  All rights reserved.           *
+ * EMULEX and SLI are trademarks of Emulex.                        *
  * www.emulex.com                                                  *
+ * Portions Copyright (C) 2004-2005 Christoph Hellwig              *
  *                                                                 *
  * 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, a copy of which    *
- * can be found in the file COPYING included with this package.    *
+ * modify it under the terms of version 2 of the GNU General       *
+ * Public License as published by the Free Software Foundation.    *
+ * This program is distributed in the hope that it will be useful. *
+ * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND          *
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,  *
+ * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE      *
+ * DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD *
+ * TO BE LEGALLY INVALID.  See the GNU General Public License for  *
+ * more details, a copy of which can be found in the file COPYING  *
+ * included with this package.                                     *
  *******************************************************************/
 
-/*
- * $Id: lpfc_scsi.c 1.37 2005/04/13 14:27:09EDT sf_support Exp  $
- */
-
 #include <linux/pci.h>
 #include <linux/interrupt.h>
 
@@ -798,7 +795,7 @@ lpfc_queuecommand(struct scsi_cmnd *cmnd
 }
 
 static int
-lpfc_abort_handler(struct scsi_cmnd *cmnd)
+__lpfc_abort_handler(struct scsi_cmnd *cmnd)
 {
 	struct lpfc_hba *phba =
 			(struct lpfc_hba *)cmnd->device->host->hostdata[0];
@@ -874,6 +871,7 @@ lpfc_abort_handler(struct scsi_cmnd *cmn
 		else
 			icmd->ulpCommand = CMD_CLOSE_XRI_CN;
 
+		abtsiocb->iocb_cmpl = lpfc_sli_abort_fcp_cmpl;
 		if (lpfc_sli_issue_iocb(phba, pring, abtsiocb, 0) ==
 								IOCB_ERROR) {
 			list_add_tail(&abtsiocb->list, lpfc_iocb_list);
@@ -918,7 +916,17 @@ lpfc_abort_handler(struct scsi_cmnd *cmn
 }
 
 static int
-lpfc_reset_lun_handler(struct scsi_cmnd *cmnd)
+lpfc_abort_handler(struct scsi_cmnd *cmnd)
+{
+	int rc;
+	spin_lock_irq(cmnd->device->host->host_lock);
+	rc = __lpfc_abort_handler(cmnd);
+	spin_unlock_irq(cmnd->device->host->host_lock);
+	return rc;
+}
+
+static int
+__lpfc_reset_lun_handler(struct scsi_cmnd *cmnd)
 {
 	struct Scsi_Host *shost = cmnd->device->host;
 	struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata[0];
@@ -1030,11 +1038,21 @@ out:
 	return ret;
 }
 
+static int
+lpfc_reset_lun_handler(struct scsi_cmnd *cmnd)
+{
+	int rc;
+	spin_lock_irq(cmnd->device->host->host_lock);
+	rc = __lpfc_reset_lun_handler(cmnd);
+	spin_unlock_irq(cmnd->device->host->host_lock);
+	return rc;
+}
+
 /*
  * Note: midlayer calls this function with the host_lock held
  */
 static int
-lpfc_reset_bus_handler(struct scsi_cmnd *cmnd)
+__lpfc_reset_bus_handler(struct scsi_cmnd *cmnd)
 {
 	struct Scsi_Host *shost = cmnd->device->host;
 	struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata[0];
@@ -1124,6 +1142,16 @@ out:
 }
 
 static int
+lpfc_reset_bus_handler(struct scsi_cmnd *cmnd)
+{
+	int rc;
+	spin_lock_irq(cmnd->device->host->host_lock);
+	rc = __lpfc_reset_bus_handler(cmnd);
+	spin_unlock_irq(cmnd->device->host->host_lock);
+	return rc;
+}
+
+static int
 lpfc_slave_alloc(struct scsi_device *sdev)
 {
 	struct lpfc_hba *phba = (struct lpfc_hba *)sdev->host->hostdata[0];
@@ -1243,4 +1271,5 @@ struct scsi_host_template lpfc_template 
 	.cmd_per_lun		= LPFC_CMD_PER_LUN,
 	.use_clustering		= ENABLE_CLUSTERING,
 	.shost_attrs		= lpfc_host_attrs,
+	.max_sectors		= 0xFFFF,
 };
diff --git a/drivers/scsi/lpfc/lpfc_scsi.h b/drivers/scsi/lpfc/lpfc_scsi.h
--- a/drivers/scsi/lpfc/lpfc_scsi.h
+++ b/drivers/scsi/lpfc/lpfc_scsi.h
@@ -1,26 +1,24 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
- * Enterprise Fibre Channel Host Bus Adapters.                     *
- * Refer to the README file included with this package for         *
- * driver version and adapter support.                             *
- * Copyright (C) 2004 Emulex Corporation.                          *
+ * Fibre Channel Host Bus Adapters.                                *
+ * Copyright (C) 2004-2005 Emulex.  All rights reserved.           *
+ * EMULEX and SLI are trademarks of Emulex.                        *
  * www.emulex.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, a copy of which    *
- * can be found in the file COPYING included with this package.    *
+ * modify it under the terms of version 2 of the GNU General       *
+ * Public License as published by the Free Software Foundation.    *
+ * This program is distributed in the hope that it will be useful. *
+ * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND          *
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,  *
+ * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE      *
+ * DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD *
+ * TO BE LEGALLY INVALID.  See the GNU General Public License for  *
+ * more details, a copy of which can be found in the file COPYING  *
+ * included with this package.                                     *
  *******************************************************************/
 
-/*
- * $Id: lpfc_scsi.h 1.83 2005/04/07 08:47:43EDT sf_support Exp  $
- */
+#include <asm/byteorder.h>
 
 struct lpfc_hba;
 
@@ -85,7 +83,7 @@ struct fcp_cmnd {
 	/* # of bits to shift lun id to end up in right
 	 * payload word, little endian = 8, big = 16.
 	 */
-#if __BIG_ENDIAN
+#ifdef __BIG_ENDIAN
 #define FC_LUN_SHIFT         16
 #define FC_ADDR_MODE_SHIFT   24
 #else	/*  __LITTLE_ENDIAN */
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -1,27 +1,24 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
- * Enterprise Fibre Channel Host Bus Adapters.                     *
- * Refer to the README file included with this package for         *
- * driver version and adapter support.                             *
- * Copyright (C) 2004 Emulex Corporation.                          *
+ * Fibre Channel Host Bus Adapters.                                *
+ * Copyright (C) 2004-2005 Emulex.  All rights reserved.           *
+ * EMULEX and SLI are trademarks of Emulex.                        *
  * www.emulex.com                                                  *
+ * Portions Copyright (C) 2004-2005 Christoph Hellwig              *
  *                                                                 *
  * 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, a copy of which    *
- * can be found in the file COPYING included with this package.    *
+ * modify it under the terms of version 2 of the GNU General       *
+ * Public License as published by the Free Software Foundation.    *
+ * This program is distributed in the hope that it will be useful. *
+ * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND          *
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,  *
+ * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE      *
+ * DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD *
+ * TO BE LEGALLY INVALID.  See the GNU General Public License for  *
+ * more details, a copy of which can be found in the file COPYING  *
+ * included with this package.                                     *
  *******************************************************************/
 
-/*
- * $Id: lpfc_sli.c 1.232 2005/04/13 11:59:16EDT sf_support Exp  $
- */
-
 #include <linux/blkdev.h>
 #include <linux/pci.h>
 #include <linux/interrupt.h>
@@ -225,8 +222,7 @@ lpfc_sli_ringtx_get(struct lpfc_hba * ph
 static IOCB_t *
 lpfc_sli_next_iocb_slot (struct lpfc_hba *phba, struct lpfc_sli_ring *pring)
 {
-	MAILBOX_t *mbox = (MAILBOX_t *)phba->sli.MBhostaddr;
-	PGP *pgp = (PGP *)&mbox->us.s2.port[pring->ringno];
+	struct lpfc_pgp *pgp = &phba->slim2p->mbx.us.s2.port[pring->ringno];
 	uint32_t  max_cmd_idx = pring->numCiocb;
 	IOCB_t *iocb = NULL;
 
@@ -411,9 +407,7 @@ lpfc_sli_resume_iocb(struct lpfc_hba * p
 static void
 lpfc_sli_turn_on_ring(struct lpfc_hba * phba, int ringno)
 {
-	PGP *pgp =
-		((PGP *) &
-		 (((MAILBOX_t *)phba->sli.MBhostaddr)->us.s2.port[ringno]));
+	struct lpfc_pgp *pgp = &phba->slim2p->mbx.us.s2.port[ringno];
 
 	/* If the ring is active, flag it */
 	if (phba->sli.ring[ringno].cmdringaddr) {
@@ -537,7 +531,7 @@ lpfc_sli_handle_mb_event(struct lpfc_hba
 	/* Get a Mailbox buffer to setup mailbox commands for callback */
 	if ((pmb = phba->sli.mbox_active)) {
 		pmbox = &pmb->mb;
-		mbox = (MAILBOX_t *) phba->sli.MBhostaddr;
+		mbox = &phba->slim2p->mbx;
 
 		/* First check out the status word */
 		lpfc_sli_pcimem_bcopy(mbox, pmbox, sizeof (uint32_t));
@@ -905,10 +899,11 @@ static int
 lpfc_sli_handle_fast_ring_event(struct lpfc_hba * phba,
 				struct lpfc_sli_ring * pring, uint32_t mask)
 {
+ 	struct lpfc_pgp *pgp = &phba->slim2p->mbx.us.s2.port[pring->ringno];
 	IOCB_t *irsp = NULL;
+	IOCB_t *entry = NULL;
 	struct lpfc_iocbq *cmdiocbq = NULL;
 	struct lpfc_iocbq rspiocbq;
-	PGP *pgp;
 	uint32_t status;
 	uint32_t portRspPut, portRspMax;
 	int rc = 1;
@@ -920,10 +915,6 @@ lpfc_sli_handle_fast_ring_event(struct l
 	spin_lock_irqsave(phba->host->host_lock, iflag);
 	pring->stats.iocb_event++;
 
-	/* The driver assumes SLI-2 mode */
-	pgp = (PGP *) &((MAILBOX_t *) phba->sli.MBhostaddr)
-		->us.s2.port[pring->ringno];
-
 	/*
 	 * The next available response entry should never exceed the maximum
 	 * entries.  If it does, treat it as an adapter hardware error.
@@ -955,7 +946,17 @@ lpfc_sli_handle_fast_ring_event(struct l
 
 	rmb();
 	while (pring->rspidx != portRspPut) {
-		irsp = (IOCB_t *) IOCB_ENTRY(pring->rspringaddr, pring->rspidx);
+		/*
+		 * Fetch an entry off the ring and copy it into a local data
+		 * structure.  The copy involves a byte-swap since the
+		 * network byte order and pci byte orders are different.
+		 */
+		entry = (IOCB_t *) IOCB_ENTRY(pring->rspringaddr, pring->rspidx);
+		lpfc_sli_pcimem_bcopy((uint32_t *) entry,
+				      (uint32_t *) &rspiocbq.iocb,
+				      sizeof (IOCB_t));
+		irsp = &rspiocbq.iocb;
+
 		type = lpfc_sli_iocb_cmd_type(irsp->ulpCommand & CMD_IOCB_MASK);
 		pring->stats.iocb_rsp++;
 		rsp_cmpl++;
@@ -987,10 +988,6 @@ lpfc_sli_handle_fast_ring_event(struct l
 				break;
 			}
 
-			rspiocbq.iocb.un.ulpWord[4] = irsp->un.ulpWord[4];
-			rspiocbq.iocb.ulpStatus = irsp->ulpStatus;
-			rspiocbq.iocb.ulpContext = irsp->ulpContext;
-			rspiocbq.iocb.ulpIoTag = irsp->ulpIoTag;
 			cmdiocbq = lpfc_sli_txcmpl_ring_iotag_lookup(phba,
 								pring,
 								&rspiocbq);
@@ -1075,9 +1072,7 @@ lpfc_sli_handle_slow_ring_event(struct l
 	struct lpfc_iocbq *cmdiocbp;
 	struct lpfc_iocbq *saveq;
 	struct list_head *lpfc_iocb_list = &phba->lpfc_iocb_list;
-	HGP *hgp;
-	PGP *pgp;
-	MAILBOX_t *mbox;
+	struct lpfc_pgp *pgp = &phba->slim2p->mbx.us.s2.port[pring->ringno];
 	uint8_t iocb_cmd_type;
 	lpfc_iocb_type type;
 	uint32_t status, free_saveq;
@@ -1089,11 +1084,6 @@ lpfc_sli_handle_slow_ring_event(struct l
 	spin_lock_irqsave(phba->host->host_lock, iflag);
 	pring->stats.iocb_event++;
 
-	/* The driver assumes SLI-2 mode */
-	mbox = (MAILBOX_t *) phba->sli.MBhostaddr;
-	pgp = (PGP *) & mbox->us.s2.port[pring->ringno];
-	hgp = (HGP *) & mbox->us.s2.host[pring->ringno];
-
 	/*
 	 * The next available response entry should never exceed the maximum
 	 * entries.  If it does, treat it as an adapter hardware error.
@@ -1738,6 +1728,8 @@ lpfc_mbox_timeout_handler(struct lpfc_hb
 		return;
 	}
 
+	phba->work_hba_events &= ~WORKER_MBOX_TMO;
+
 	pmbox = phba->sli.mbox_active;
 	mb = &pmbox->mb;
 
@@ -1752,16 +1744,14 @@ lpfc_mbox_timeout_handler(struct lpfc_hb
 		phba->sli.sli_flag,
 		phba->sli.mbox_active);
 
-	if (phba->sli.mbox_active == pmbox) {
-		phba->sli.mbox_active = NULL;
-		if (pmbox->mbox_cmpl) {
-			mb->mbxStatus = MBX_NOT_FINISHED;
-			spin_unlock_irq(phba->host->host_lock);
-			(pmbox->mbox_cmpl) (phba, pmbox);
-			spin_lock_irq(phba->host->host_lock);
-		}
-		phba->sli.sli_flag &= ~LPFC_SLI_MBOX_ACTIVE;
+	phba->sli.mbox_active = NULL;
+	if (pmbox->mbox_cmpl) {
+		mb->mbxStatus = MBX_NOT_FINISHED;
+		spin_unlock_irq(phba->host->host_lock);
+		(pmbox->mbox_cmpl) (phba, pmbox);
+		spin_lock_irq(phba->host->host_lock);
 	}
+	phba->sli.sli_flag &= ~LPFC_SLI_MBOX_ACTIVE;
 
 	spin_unlock_irq(phba->host->host_lock);
 	lpfc_mbox_abort(phba);
@@ -1771,7 +1761,6 @@ lpfc_mbox_timeout_handler(struct lpfc_hb
 int
 lpfc_sli_issue_mbox(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmbox, uint32_t flag)
 {
-	MAILBOX_t *mbox;
 	MAILBOX_t *mb;
 	struct lpfc_sli *psli;
 	uint32_t status, evtctr;
@@ -1901,15 +1890,13 @@ lpfc_sli_issue_mbox(struct lpfc_hba * ph
 	mb->mbxOwner = OWN_CHIP;
 
 	if (psli->sli_flag & LPFC_SLI2_ACTIVE) {
-
 		/* First copy command data to host SLIM area */
-		mbox = (MAILBOX_t *) psli->MBhostaddr;
-		lpfc_sli_pcimem_bcopy(mb, mbox, MAILBOX_CMD_SIZE);
+		lpfc_sli_pcimem_bcopy(mb, &phba->slim2p->mbx, MAILBOX_CMD_SIZE);
 	} else {
 		if (mb->mbxCommand == MBX_CONFIG_PORT) {
 			/* copy command data into host mbox for cmpl */
-			mbox = (MAILBOX_t *) psli->MBhostaddr;
-			lpfc_sli_pcimem_bcopy(mb, mbox, MAILBOX_CMD_SIZE);
+			lpfc_sli_pcimem_bcopy(mb, &phba->slim2p->mbx,
+					MAILBOX_CMD_SIZE);
 		}
 
 		/* First copy mbox command data to HBA SLIM, skip past first
@@ -1946,8 +1933,7 @@ lpfc_sli_issue_mbox(struct lpfc_hba * ph
 		psli->mbox_active = NULL;
 		if (psli->sli_flag & LPFC_SLI2_ACTIVE) {
 			/* First read mbox status word */
-			mbox = (MAILBOX_t *) psli->MBhostaddr;
-			word0 = *((volatile uint32_t *)mbox);
+			word0 = *((volatile uint32_t *)&phba->slim2p->mbx);
 			word0 = le32_to_cpu(word0);
 		} else {
 			/* First read mbox status word */
@@ -1984,8 +1970,8 @@ lpfc_sli_issue_mbox(struct lpfc_hba * ph
 
 			if (psli->sli_flag & LPFC_SLI2_ACTIVE) {
 				/* First copy command data */
-				mbox = (MAILBOX_t *) psli->MBhostaddr;
-				word0 = *((volatile uint32_t *)mbox);
+				word0 = *((volatile uint32_t *)
+						&phba->slim2p->mbx);
 				word0 = le32_to_cpu(word0);
 				if (mb->mbxCommand == MBX_CONFIG_PORT) {
 					MAILBOX_t *slimmb;
@@ -2009,10 +1995,9 @@ lpfc_sli_issue_mbox(struct lpfc_hba * ph
 		}
 
 		if (psli->sli_flag & LPFC_SLI2_ACTIVE) {
-			/* First copy command data */
-			mbox = (MAILBOX_t *) psli->MBhostaddr;
 			/* copy results back to user */
-			lpfc_sli_pcimem_bcopy(mbox, mb, MAILBOX_CMD_SIZE);
+			lpfc_sli_pcimem_bcopy(&phba->slim2p->mbx, mb,
+					MAILBOX_CMD_SIZE);
 		} else {
 			/* First copy command data */
 			lpfc_memcpy_from_slim(mb, phba->MBslimaddr,
@@ -2089,8 +2074,6 @@ lpfc_sli_issue_iocb(struct lpfc_hba *phb
 		switch (piocb->iocb.ulpCommand) {
 		case CMD_QUE_RING_BUF_CN:
 		case CMD_QUE_RING_BUF64_CN:
-		case CMD_CLOSE_XRI_CN:
-		case CMD_ABORT_XRI_CN:
 			/*
 			 * For IOCBs, like QUE_RING_BUF, that have no rsp ring
 			 * completion, iocb_cmpl MUST be 0.
@@ -2573,6 +2556,16 @@ lpfc_sli_sum_iocb(struct lpfc_hba *phba,
 	return sum;
 }
 
+void
+lpfc_sli_abort_fcp_cmpl(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb,
+			   struct lpfc_iocbq * rspiocb)
+{
+	spin_lock_irq(phba->host->host_lock);
+	list_add_tail(&cmdiocb->list, &phba->lpfc_iocb_list);
+	spin_unlock_irq(phba->host->host_lock);
+	return;
+}
+
 int
 lpfc_sli_abort_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
 		    uint16_t tgt_id, uint64_t lun_id, uint32_t ctx,
@@ -2622,6 +2615,8 @@ lpfc_sli_abort_iocb(struct lpfc_hba *phb
 		else
 			abtsiocb->iocb.ulpCommand = CMD_CLOSE_XRI_CN;
 
+		/* Setup callback routine and issue the command. */
+		abtsiocb->iocb_cmpl = lpfc_sli_abort_fcp_cmpl;
 		ret_val = lpfc_sli_issue_iocb(phba, pring, abtsiocb, 0);
 		if (ret_val == IOCB_ERROR) {
 			list_add_tail(&abtsiocb->list, lpfc_iocb_list);
diff --git a/drivers/scsi/lpfc/lpfc_sli.h b/drivers/scsi/lpfc/lpfc_sli.h
--- a/drivers/scsi/lpfc/lpfc_sli.h
+++ b/drivers/scsi/lpfc/lpfc_sli.h
@@ -1,27 +1,23 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
- * Enterprise Fibre Channel Host Bus Adapters.                     *
- * Refer to the README file included with this package for         *
- * driver version and adapter support.                             *
- * Copyright (C) 2004 Emulex Corporation.                          *
+ * Fibre Channel Host Bus Adapters.                                *
+ * Copyright (C) 2004-2005 Emulex.  All rights reserved.           *
+ * EMULEX and SLI are trademarks of Emulex.                        *
  * www.emulex.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, a copy of which    *
- * can be found in the file COPYING included with this package.    *
+ * modify it under the terms of version 2 of the GNU General       *
+ * Public License as published by the Free Software Foundation.    *
+ * This program is distributed in the hope that it will be useful. *
+ * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND          *
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,  *
+ * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE      *
+ * DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD *
+ * TO BE LEGALLY INVALID.  See the GNU General Public License for  *
+ * more details, a copy of which can be found in the file COPYING  *
+ * included with this package.                                     *
  *******************************************************************/
 
-/*
- * $Id: lpfc_sli.h 1.42 2005/03/21 02:01:28EST sf_support Exp  $
- */
-
 /* forward declaration for LPFC_IOCB_t's use */
 struct lpfc_hba;
 
diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h
--- a/drivers/scsi/lpfc/lpfc_version.h
+++ b/drivers/scsi/lpfc/lpfc_version.h
@@ -1,32 +1,29 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
- * Enterprise Fibre Channel Host Bus Adapters.                     *
- * Refer to the README file included with this package for         *
- * driver version and adapter support.                             *
- * Copyright (C) 2004 Emulex Corporation.                          *
+ * Fibre Channel Host Bus Adapters.                                *
+ * Copyright (C) 2004-2005 Emulex.  All rights reserved.           *
+ * EMULEX and SLI are trademarks of Emulex.                        *
  * www.emulex.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, a copy of which    *
- * can be found in the file COPYING included with this package.    *
+ * modify it under the terms of version 2 of the GNU General       *
+ * Public License as published by the Free Software Foundation.    *
+ * This program is distributed in the hope that it will be useful. *
+ * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND          *
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,  *
+ * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE      *
+ * DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD *
+ * TO BE LEGALLY INVALID.  See the GNU General Public License for  *
+ * more details, a copy of which can be found in the file COPYING  *
+ * included with this package.                                     *
  *******************************************************************/
 
-/*
- * $Id: lpfc_version.h 1.49 2005/04/13 15:07:19EDT sf_support Exp  $
- */
-
-#define LPFC_DRIVER_VERSION "8.0.28"
+#define LPFC_DRIVER_VERSION "8.0.29"
 
 #define LPFC_DRIVER_NAME "lpfc"
 
 #define LPFC_MODULE_DESC "Emulex LightPulse Fibre Channel SCSI driver " \
 		LPFC_DRIVER_VERSION
+#define LPFC_COPYRIGHT "Copyright(c) 2004-2005 Emulex.  All rights reserved."
 
 #define DFC_API_VERSION "0.0.0"
diff --git a/drivers/scsi/mac53c94.c b/drivers/scsi/mac53c94.c
--- a/drivers/scsi/mac53c94.c
+++ b/drivers/scsi/mac53c94.c
@@ -98,16 +98,14 @@ static int mac53c94_queue(struct scsi_cm
 	return 0;
 }
 
-static int mac53c94_abort(struct scsi_cmnd *cmd)
-{
-	return FAILED;
-}
-
 static int mac53c94_host_reset(struct scsi_cmnd *cmd)
 {
 	struct fsc_state *state = (struct fsc_state *) cmd->device->host->hostdata;
 	struct mac53c94_regs __iomem *regs = state->regs;
 	struct dbdma_regs __iomem *dma = state->dma;
+	unsigned long flags;
+
+	spin_lock_irqsave(cmd->device->host->host_lock, flags);
 
 	writel((RUN|PAUSE|FLUSH|WAKE) << 16, &dma->control);
 	writeb(CMD_SCSI_RESET, &regs->command);	/* assert RST */
@@ -116,6 +114,8 @@ static int mac53c94_host_reset(struct sc
 	udelay(20);
 	mac53c94_init(state);
 	writeb(CMD_NOP, &regs->command);
+
+	spin_unlock_irqrestore(cmd->device->host->host_lock, flags);
 	return SUCCESS;
 }
 
@@ -416,7 +416,6 @@ static struct scsi_host_template mac53c9
 	.proc_name	= "53c94",
 	.name		= "53C94",
 	.queuecommand	= mac53c94_queue,
-	.eh_abort_handler = mac53c94_abort,
 	.eh_host_reset_handler = mac53c94_host_reset,
 	.can_queue	= 1,
 	.this_id	= 7,
@@ -425,7 +424,7 @@ static struct scsi_host_template mac53c9
 	.use_clustering	= DISABLE_CLUSTERING,
 };
 
-static int mac53c94_probe(struct macio_dev *mdev, const struct of_match *match)
+static int mac53c94_probe(struct macio_dev *mdev, const struct of_device_id *match)
 {
 	struct device_node *node = macio_get_of_node(mdev);
 	struct pci_dev *pdev = macio_get_pci_dev(mdev);
@@ -545,15 +544,14 @@ static int mac53c94_remove(struct macio_
 }
 
 
-static struct of_match mac53c94_match[] = 
+static struct of_device_id mac53c94_match[] = 
 {
 	{
 	.name 		= "53c94",
-	.type		= OF_ANY_MATCH,
-	.compatible	= OF_ANY_MATCH
 	},
 	{},
 };
+MODULE_DEVICE_TABLE (of, mac53c94_match);
 
 static struct macio_driver mac53c94_driver = 
 {
diff --git a/drivers/scsi/mac_scsi.c b/drivers/scsi/mac_scsi.c
--- a/drivers/scsi/mac_scsi.c
+++ b/drivers/scsi/mac_scsi.c
@@ -591,8 +591,6 @@ static Scsi_Host_Template driver_templat
 	.queuecommand			= macscsi_queue_command,
 	.eh_abort_handler		= macscsi_abort,
 	.eh_bus_reset_handler		= macscsi_bus_reset,
-	.eh_device_reset_handler	= macscsi_device_reset,
-	.eh_host_reset_handler		= macscsi_host_reset,
 	.can_queue			= CAN_QUEUE,
 	.this_id			= 7,
 	.sg_tablesize			= SG_ALL,
diff --git a/drivers/scsi/mac_scsi.h b/drivers/scsi/mac_scsi.h
--- a/drivers/scsi/mac_scsi.h
+++ b/drivers/scsi/mac_scsi.h
@@ -72,8 +72,6 @@
 #define NCR5380_queue_command macscsi_queue_command
 #define NCR5380_abort macscsi_abort
 #define NCR5380_bus_reset macscsi_bus_reset
-#define NCR5380_device_reset macscsi_device_reset
-#define NCR5380_host_reset macscsi_host_reset
 #define NCR5380_proc_info macscsi_proc_info
 
 #define BOARD_NORMAL	0
diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c
--- a/drivers/scsi/megaraid.c
+++ b/drivers/scsi/megaraid.c
@@ -35,6 +35,7 @@
 #include <linux/blkdev.h>
 #include <asm/uaccess.h>
 #include <asm/io.h>
+#include <linux/completion.h>
 #include <linux/delay.h>
 #include <linux/proc_fs.h>
 #include <linux/reboot.h>
@@ -1938,7 +1939,7 @@ megaraid_abort(Scsi_Cmnd *cmd)
 
 
 static int
-megaraid_reset(Scsi_Cmnd *cmd)
+megaraid_reset(struct scsi_cmnd *cmd)
 {
 	adapter_t	*adapter;
 	megacmd_t	mc;
@@ -1950,7 +1951,6 @@ megaraid_reset(Scsi_Cmnd *cmd)
 	mc.cmd = MEGA_CLUSTER_CMD;
 	mc.opcode = MEGA_RESET_RESERVATIONS;
 
-	spin_unlock_irq(&adapter->lock);
 	if( mega_internal_command(adapter, LOCK_INT, &mc, NULL) != 0 ) {
 		printk(KERN_WARNING
 				"megaraid: reservation reset failed.\n");
@@ -1958,9 +1958,10 @@ megaraid_reset(Scsi_Cmnd *cmd)
 	else {
 		printk(KERN_INFO "megaraid: reservation reset.\n");
 	}
-	spin_lock_irq(&adapter->lock);
 #endif
 
+	spin_lock_irq(&adapter->lock);
+
 	rval =  megaraid_abort_and_reset(adapter, cmd, SCB_RESET);
 
 	/*
@@ -1968,12 +1969,11 @@ megaraid_reset(Scsi_Cmnd *cmd)
 	 * to be communicated over to the mid layer.
 	 */
 	mega_rundoneq(adapter);
+	spin_unlock_irq(&adapter->lock);
 
 	return rval;
 }
 
-
-
 /**
  * megaraid_abort_and_reset()
  * @adapter - megaraid soft state
@@ -4478,8 +4478,6 @@ mega_internal_command(adapter_t *adapter
 
 	scb->idx = CMDID_INT_CMDS;
 
-	scmd->state = 0;
-
 	/*
 	 * Get the lock only if the caller has not acquired it already
 	 */
@@ -4489,15 +4487,7 @@ mega_internal_command(adapter_t *adapter
 
 	if( ls == LOCK_INT ) spin_unlock_irqrestore(&adapter->lock, flags);
 
-	/*
-	 * Wait till this command finishes. Do not use
-	 * wait_event_interruptible(). It causes panic if CTRL-C is hit when
-	 * dumping e.g., physical disk information through /proc interface.
-	 */
-#if 0
-	wait_event_interruptible(adapter->int_waitq, scmd->state);
-#endif
-	wait_event(adapter->int_waitq, scmd->state);
+	wait_for_completion(&adapter->int_waitq);
 
 	rval = scmd->result;
 	mc->status = scmd->result;
@@ -4531,16 +4521,7 @@ mega_internal_done(Scsi_Cmnd *scmd)
 
 	adapter = (adapter_t *)scmd->device->host->hostdata;
 
-	scmd->state = 1; /* thread waiting for its command to complete */
-
-	/*
-	 * See comment in mega_internal_command() routine for
-	 * wait_event_interruptible()
-	 */
-#if 0
-	wake_up_interruptible(&adapter->int_waitq);
-#endif
-	wake_up(&adapter->int_waitq);
+	complete(&adapter->int_waitq);
 
 }
 
@@ -4862,7 +4843,7 @@ megaraid_probe_one(struct pci_dev *pdev,
 	}
 		
 	init_MUTEX(&adapter->int_mtx);
-	init_waitqueue_head(&adapter->int_waitq);
+	init_completion(&adapter->int_waitq);
 
 	adapter->this_id = DEFAULT_INITIATOR_ID;
 	adapter->host->this_id = DEFAULT_INITIATOR_ID;
@@ -5024,9 +5005,9 @@ megaraid_remove_one(struct pci_dev *pdev
 }
 
 static void
-megaraid_shutdown(struct device *dev)
+megaraid_shutdown(struct pci_dev *pdev)
 {
-	struct Scsi_Host *host = pci_get_drvdata(to_pci_dev(dev));
+	struct Scsi_Host *host = pci_get_drvdata(pdev);
 	adapter_t *adapter = (adapter_t *)host->hostdata;
 
 	__megaraid_shutdown(adapter);
@@ -5058,9 +5039,7 @@ static struct pci_driver megaraid_pci_dr
 	.id_table	= megaraid_pci_tbl,
 	.probe		= megaraid_probe_one,
 	.remove		= __devexit_p(megaraid_remove_one),
-	.driver		= {
-		.shutdown = megaraid_shutdown,
-	},
+	.shutdown	= megaraid_shutdown,
 };
 
 static int __init megaraid_init(void)
diff --git a/drivers/scsi/megaraid.h b/drivers/scsi/megaraid.h
--- a/drivers/scsi/megaraid.h
+++ b/drivers/scsi/megaraid.h
@@ -891,7 +891,7 @@ typedef struct {
 	Scsi_Cmnd		int_scmd;
 	struct semaphore	int_mtx;	/* To synchronize the internal
 						commands */
-	wait_queue_head_t	int_waitq;	/* wait queue for internal
+	struct completion	int_waitq;	/* wait queue for internal
 						 cmds */
 
 	int	has_cluster;	/* cluster support on this HBA */
diff --git a/drivers/scsi/megaraid/mega_common.h b/drivers/scsi/megaraid/mega_common.h
--- a/drivers/scsi/megaraid/mega_common.h
+++ b/drivers/scsi/megaraid/mega_common.h
@@ -27,6 +27,7 @@
 #include <linux/list.h>
 #include <linux/version.h>
 #include <linux/moduleparam.h>
+#include <linux/dma-mapping.h>
 #include <asm/semaphore.h>
 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
diff --git a/drivers/scsi/megaraid/megaraid_mbox.c b/drivers/scsi/megaraid/megaraid_mbox.c
--- a/drivers/scsi/megaraid/megaraid_mbox.c
+++ b/drivers/scsi/megaraid/megaraid_mbox.c
@@ -10,7 +10,7 @@
  *	   2 of the License, or (at your option) any later version.
  *
  * FILE		: megaraid_mbox.c
- * Version	: v2.20.4.5 (Feb 03 2005)
+ * Version	: v2.20.4.6 (Mar 07 2005)
  *
  * Authors:
  * 	Atul Mukker		<Atul.Mukker@lsil.com>
@@ -124,7 +124,7 @@ static irqreturn_t megaraid_isr(int, voi
 static void megaraid_mbox_dpc(unsigned long);
 
 static ssize_t megaraid_sysfs_show_app_hndl(struct class_device *, char *);
-static ssize_t megaraid_sysfs_show_ldnum(struct device *, char *);
+static ssize_t megaraid_sysfs_show_ldnum(struct device *, struct device_attribute *attr, char *);
 
 static int megaraid_cmm_register(adapter_t *);
 static int megaraid_cmm_unregister(adapter_t *);
@@ -202,7 +202,7 @@ MODULE_PARM_DESC(debug_level, "Debug lev
  * ### global data ###
  */
 static uint8_t megaraid_mbox_version[8] =
-	{ 0x02, 0x20, 0x04, 0x05, 2, 3, 20, 5 };
+	{ 0x02, 0x20, 0x04, 0x06, 3, 7, 20, 5 };
 
 
 /*
@@ -229,9 +229,9 @@ static struct pci_device_id pci_id_table
 	},
 	{
 		PCI_VENDOR_ID_LSI_LOGIC,
-		PCI_DEVICE_ID_PERC4_QC,
-		PCI_VENDOR_ID_DELL,
-		PCI_SUBSYS_ID_PERC4_QC,
+		PCI_DEVICE_ID_VERDE,
+		PCI_ANY_ID,
+		PCI_ANY_ID,
 	},
 	{
 		PCI_VENDOR_ID_DELL,
@@ -271,15 +271,9 @@ static struct pci_device_id pci_id_table
 	},
 	{
 		PCI_VENDOR_ID_LSI_LOGIC,
-		PCI_DEVICE_ID_PERC4E_DC_320_2E,
-		PCI_VENDOR_ID_DELL,
-		PCI_SUBSYS_ID_PERC4E_DC_320_2E,
-	},
-	{
-		PCI_VENDOR_ID_LSI_LOGIC,
-		PCI_DEVICE_ID_PERC4E_SC_320_1E,
-		PCI_VENDOR_ID_DELL,
-		PCI_SUBSYS_ID_PERC4E_SC_320_1E,
+		PCI_DEVICE_ID_DOBSON,
+		PCI_ANY_ID,
+		PCI_ANY_ID,
 	},
 	{
 		PCI_VENDOR_ID_AMI,
@@ -331,36 +325,6 @@ static struct pci_device_id pci_id_table
 	},
 	{
 		PCI_VENDOR_ID_LSI_LOGIC,
-		PCI_DEVICE_ID_MEGARAID_SCSI_320_0x,
-		PCI_VENDOR_ID_LSI_LOGIC,
-		PCI_SUBSYS_ID_MEGARAID_SCSI_320_0x,
-	},
-	{
-		PCI_VENDOR_ID_LSI_LOGIC,
-		PCI_DEVICE_ID_MEGARAID_SCSI_320_2x,
-		PCI_VENDOR_ID_LSI_LOGIC,
-		PCI_SUBSYS_ID_MEGARAID_SCSI_320_2x,
-	},
-	{
-		PCI_VENDOR_ID_LSI_LOGIC,
-		PCI_DEVICE_ID_MEGARAID_SCSI_320_4x,
-		PCI_VENDOR_ID_LSI_LOGIC,
-		PCI_SUBSYS_ID_MEGARAID_SCSI_320_4x,
-	},
-	{
-		PCI_VENDOR_ID_LSI_LOGIC,
-		PCI_DEVICE_ID_MEGARAID_SCSI_320_1E,
-		PCI_VENDOR_ID_LSI_LOGIC,
-		PCI_SUBSYS_ID_MEGARAID_SCSI_320_1E,
-	},
-	{
-		PCI_VENDOR_ID_LSI_LOGIC,
-		PCI_DEVICE_ID_MEGARAID_SCSI_320_2E,
-		PCI_VENDOR_ID_LSI_LOGIC,
-		PCI_SUBSYS_ID_MEGARAID_SCSI_320_2E,
-	},
-	{
-		PCI_VENDOR_ID_LSI_LOGIC,
 		PCI_DEVICE_ID_MEGARAID_I4_133_RAID,
 		PCI_VENDOR_ID_LSI_LOGIC,
 		PCI_SUBSYS_ID_MEGARAID_I4_133_RAID,
@@ -379,21 +343,9 @@ static struct pci_device_id pci_id_table
 	},
 	{
 		PCI_VENDOR_ID_LSI_LOGIC,
-		PCI_DEVICE_ID_MEGARAID_SATA_300_4x,
-		PCI_VENDOR_ID_LSI_LOGIC,
-		PCI_SUBSYS_ID_MEGARAID_SATA_300_4x,
-	},
-	{
-		PCI_VENDOR_ID_LSI_LOGIC,
-		PCI_DEVICE_ID_MEGARAID_SATA_300_8x,
-		PCI_VENDOR_ID_LSI_LOGIC,
-		PCI_SUBSYS_ID_MEGARAID_SATA_300_8x,
-	},
-	{
-		PCI_VENDOR_ID_LSI_LOGIC,
-		PCI_DEVICE_ID_INTEL_RAID_SRCU42X,
-		PCI_VENDOR_ID_INTEL,
-		PCI_SUBSYS_ID_INTEL_RAID_SRCU42X,
+		PCI_DEVICE_ID_LINDSAY,
+		PCI_ANY_ID,
+		PCI_ANY_ID,
 	},
 	{
 		PCI_VENDOR_ID_LSI_LOGIC,
@@ -403,58 +355,10 @@ static struct pci_device_id pci_id_table
 	},
 	{
 		PCI_VENDOR_ID_LSI_LOGIC,
-		PCI_DEVICE_ID_INTEL_RAID_SRCU42E,
-		PCI_VENDOR_ID_INTEL,
-		PCI_SUBSYS_ID_INTEL_RAID_SRCU42E,
-	},
-	{
-		PCI_VENDOR_ID_LSI_LOGIC,
-		PCI_DEVICE_ID_INTEL_RAID_SRCZCRX,
-		PCI_VENDOR_ID_INTEL,
-		PCI_SUBSYS_ID_INTEL_RAID_SRCZCRX,
-	},
-	{
-		PCI_VENDOR_ID_LSI_LOGIC,
-		PCI_DEVICE_ID_INTEL_RAID_SRCS28X,
-		PCI_VENDOR_ID_INTEL,
-		PCI_SUBSYS_ID_INTEL_RAID_SRCS28X,
-	},
-	{
-		PCI_VENDOR_ID_LSI_LOGIC,
-		PCI_DEVICE_ID_INTEL_RAID_SROMBU42E_ALIEF,
-		PCI_VENDOR_ID_INTEL,
-		PCI_SUBSYS_ID_INTEL_RAID_SROMBU42E_ALIEF,
-	},
-	{
-		PCI_VENDOR_ID_LSI_LOGIC,
-		PCI_DEVICE_ID_INTEL_RAID_SROMBU42E_HARWICH,
-		PCI_VENDOR_ID_INTEL,
-		PCI_SUBSYS_ID_INTEL_RAID_SROMBU42E_HARWICH,
-	},
-	{
-		PCI_VENDOR_ID_LSI_LOGIC,
 		PCI_DEVICE_ID_INTEL_RAID_SRCU41L_LAKE_SHETEK,
 		PCI_VENDOR_ID_INTEL,
 		PCI_SUBSYS_ID_INTEL_RAID_SRCU41L_LAKE_SHETEK,
 	},
-	{
-		PCI_VENDOR_ID_LSI_LOGIC,
-		PCI_DEVICE_ID_FSC_MEGARAID_PCI_EXPRESS_ROMB,
-		PCI_SUBSYS_ID_FSC,
-		PCI_SUBSYS_ID_FSC_MEGARAID_PCI_EXPRESS_ROMB,
-	},
-	{
-		PCI_VENDOR_ID_LSI_LOGIC,
-		PCI_DEVICE_ID_MEGARAID_ACER_ROMB_2E,
-		PCI_VENDOR_ID_AI,
-		PCI_SUBSYS_ID_MEGARAID_ACER_ROMB_2E,
-	},
-	{
-		PCI_VENDOR_ID_LSI_LOGIC,
-		PCI_DEVICE_ID_MEGARAID_NEC_ROMB_2E,
-		PCI_VENDOR_ID_NEC,
-		PCI_SUBSYS_ID_MEGARAID_NEC_ROMB_2E,
-	},
 	{0}	/* Terminating entry */
 };
 MODULE_DEVICE_TABLE(pci, pci_id_table_g);
@@ -539,7 +443,8 @@ megaraid_init(void)
 
 
 	// register as a PCI hot-plug driver module
-	if ((rval = pci_module_init(&megaraid_pci_driver_g))) {
+	rval = pci_register_driver(&megaraid_pci_driver_g);
+	if (rval < 0) {
 		con_log(CL_ANN, (KERN_WARNING
 			"megaraid: could not register hotplug support.\n"));
 	}
@@ -619,7 +524,7 @@ megaraid_probe_one(struct pci_dev *pdev,
 
 	// Setup the default DMA mask. This would be changed later on
 	// depending on hardware capabilities
-	if (pci_set_dma_mask(adapter->pdev, 0xFFFFFFFF) != 0) {
+	if (pci_set_dma_mask(adapter->pdev, DMA_32BIT_MASK) != 0) {
 
 		con_log(CL_ANN, (KERN_WARNING
 			"megaraid: pci_set_dma_mask failed:%d\n", __LINE__));
@@ -814,7 +719,6 @@ megaraid_io_attach(adapter_t *adapter)
 
 	// export the parameters required by the mid-layer
 	scsi_assign_lock(host, adapter->host_lock);
-	scsi_set_device(host, &adapter->pdev->dev);
 
 	host->irq		= adapter->irq;
 	host->unique_id		= adapter->unique_id;
@@ -1031,7 +935,7 @@ megaraid_init_mbox(adapter_t *adapter)
 
 	// Set the DMA mask to 64-bit. All supported controllers as capable of
 	// DMA in this range
-	if (pci_set_dma_mask(adapter->pdev, 0xFFFFFFFFFFFFFFFFULL) != 0) {
+	if (pci_set_dma_mask(adapter->pdev, DMA_64BIT_MASK) != 0) {
 
 		con_log(CL_ANN, (KERN_WARNING
 			"megaraid: could not set DMA mask for 64-bit.\n"));
@@ -2661,7 +2565,7 @@ megaraid_mbox_dpc(unsigned long devp)
  * aborted. All the commands issued to the F/W must complete.
  **/
 static int
-megaraid_abort_handler(struct scsi_cmnd *scp)
+__megaraid_abort_handler(struct scsi_cmnd *scp)
 {
 	adapter_t		*adapter;
 	mraid_device_t		*raid_dev;
@@ -2794,6 +2698,21 @@ megaraid_abort_handler(struct scsi_cmnd 
 	return FAILED;
 }
 
+static int
+megaraid_abort_handler(struct scsi_cmnd *scp)
+{
+	adapter_t	*adapter;
+	int rc;
+
+	adapter		= SCP2ADAPTER(scp);
+
+	spin_lock_irq(adapter->host_lock);
+	rc = __megaraid_abort_handler(scp);
+	spin_unlock_irq(adapter->host_lock);
+
+	return rc;
+}
+
 
 /**
  * megaraid_reset_handler - device reset hadler for mailbox based driver
@@ -2806,7 +2725,7 @@ megaraid_abort_handler(struct scsi_cmnd 
  * host
  **/
 static int
-megaraid_reset_handler(struct scsi_cmnd *scp)
+__megaraid_reset_handler(struct scsi_cmnd *scp)
 {
 	adapter_t	*adapter;
 	scb_t		*scb;
@@ -2927,6 +2846,18 @@ megaraid_reset_handler(struct scsi_cmnd 
 	return rval;
 }
 
+static int
+megaraid_reset_handler(struct scsi_cmnd *cmd)
+{
+	int rc;
+
+	spin_lock_irq(cmd->device->host->host_lock);
+	rc = __megaraid_reset_handler(cmd);
+	spin_unlock_irq(cmd->device->host->host_lock);
+
+	return rc;
+}
+
 
 /*
  * START: internal commands library
@@ -4213,7 +4144,7 @@ megaraid_sysfs_show_app_hndl(struct clas
  * @param buf	: buffer to send data to
  */
 static ssize_t
-megaraid_sysfs_show_ldnum(struct device *dev, char *buf)
+megaraid_sysfs_show_ldnum(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct scsi_device *sdev = to_scsi_device(dev);
 	adapter_t	*adapter = (adapter_t *)SCSIHOST2ADAP(sdev->host);
diff --git a/drivers/scsi/megaraid/megaraid_mbox.h b/drivers/scsi/megaraid/megaraid_mbox.h
--- a/drivers/scsi/megaraid/megaraid_mbox.h
+++ b/drivers/scsi/megaraid/megaraid_mbox.h
@@ -21,8 +21,8 @@
 #include "megaraid_ioctl.h"
 
 
-#define MEGARAID_VERSION	"2.20.4.5"
-#define MEGARAID_EXT_VERSION	"(Release Date: Thu Feb 03 12:27:22 EST 2005)"
+#define MEGARAID_VERSION	"2.20.4.6"
+#define MEGARAID_EXT_VERSION	"(Release Date: Mon Mar 07 12:27:22 EST 2005)"
 
 
 /*
@@ -37,8 +37,7 @@
 #define PCI_DEVICE_ID_PERC4_DC				0x1960
 #define PCI_SUBSYS_ID_PERC4_DC				0x0518
 
-#define PCI_DEVICE_ID_PERC4_QC				0x0407
-#define PCI_SUBSYS_ID_PERC4_QC				0x0531
+#define PCI_DEVICE_ID_VERDE				0x0407
 
 #define PCI_DEVICE_ID_PERC4_DI_EVERGLADES		0x000F
 #define PCI_SUBSYS_ID_PERC4_DI_EVERGLADES		0x014A
@@ -58,11 +57,7 @@
 #define PCI_DEVICE_ID_PERC4E_DI_GUADALUPE		0x0013
 #define PCI_SUBSYS_ID_PERC4E_DI_GUADALUPE		0x0170
 
-#define PCI_DEVICE_ID_PERC4E_DC_320_2E			0x0408
-#define PCI_SUBSYS_ID_PERC4E_DC_320_2E			0x0002
-
-#define PCI_DEVICE_ID_PERC4E_SC_320_1E			0x0408
-#define PCI_SUBSYS_ID_PERC4E_SC_320_1E			0x0001
+#define PCI_DEVICE_ID_DOBSON				0x0408
 
 #define PCI_DEVICE_ID_MEGARAID_SCSI_320_0		0x1960
 #define PCI_SUBSYS_ID_MEGARAID_SCSI_320_0		0xA520
@@ -73,21 +68,6 @@
 #define PCI_DEVICE_ID_MEGARAID_SCSI_320_2		0x1960
 #define PCI_SUBSYS_ID_MEGARAID_SCSI_320_2		0x0518
 
-#define PCI_DEVICE_ID_MEGARAID_SCSI_320_0x		0x0407
-#define PCI_SUBSYS_ID_MEGARAID_SCSI_320_0x		0x0530
-
-#define PCI_DEVICE_ID_MEGARAID_SCSI_320_2x		0x0407
-#define PCI_SUBSYS_ID_MEGARAID_SCSI_320_2x		0x0532
-
-#define PCI_DEVICE_ID_MEGARAID_SCSI_320_4x		0x0407
-#define PCI_SUBSYS_ID_MEGARAID_SCSI_320_4x		0x0531
-
-#define PCI_DEVICE_ID_MEGARAID_SCSI_320_1E		0x0408
-#define PCI_SUBSYS_ID_MEGARAID_SCSI_320_1E		0x0001
-
-#define PCI_DEVICE_ID_MEGARAID_SCSI_320_2E		0x0408
-#define PCI_SUBSYS_ID_MEGARAID_SCSI_320_2E		0x0002
-
 #define PCI_DEVICE_ID_MEGARAID_I4_133_RAID		0x1960
 #define PCI_SUBSYS_ID_MEGARAID_I4_133_RAID		0x0522
 
@@ -97,52 +77,18 @@
 #define PCI_DEVICE_ID_MEGARAID_SATA_150_6		0x1960
 #define PCI_SUBSYS_ID_MEGARAID_SATA_150_6		0x0523
 
-#define PCI_DEVICE_ID_MEGARAID_SATA_300_4x		0x0409
-#define PCI_SUBSYS_ID_MEGARAID_SATA_300_4x		0x3004
-
-#define PCI_DEVICE_ID_MEGARAID_SATA_300_8x		0x0409
-#define PCI_SUBSYS_ID_MEGARAID_SATA_300_8x		0x3008
-
-#define PCI_DEVICE_ID_INTEL_RAID_SRCU42X		0x0407
-#define PCI_SUBSYS_ID_INTEL_RAID_SRCU42X		0x0532
+#define PCI_DEVICE_ID_LINDSAY				0x0409
 
 #define PCI_DEVICE_ID_INTEL_RAID_SRCS16			0x1960
 #define PCI_SUBSYS_ID_INTEL_RAID_SRCS16			0x0523
 
-#define PCI_DEVICE_ID_INTEL_RAID_SRCU42E		0x0408
-#define PCI_SUBSYS_ID_INTEL_RAID_SRCU42E		0x0002
-
-#define PCI_DEVICE_ID_INTEL_RAID_SRCZCRX		0x0407
-#define PCI_SUBSYS_ID_INTEL_RAID_SRCZCRX		0x0530
-
-#define PCI_DEVICE_ID_INTEL_RAID_SRCS28X		0x0409
-#define PCI_SUBSYS_ID_INTEL_RAID_SRCS28X		0x3008
-
-#define PCI_DEVICE_ID_INTEL_RAID_SROMBU42E_ALIEF	0x0408
-#define PCI_SUBSYS_ID_INTEL_RAID_SROMBU42E_ALIEF	0x3431
-
-#define PCI_DEVICE_ID_INTEL_RAID_SROMBU42E_HARWICH	0x0408
-#define PCI_SUBSYS_ID_INTEL_RAID_SROMBU42E_HARWICH	0x3499
-
 #define PCI_DEVICE_ID_INTEL_RAID_SRCU41L_LAKE_SHETEK	0x1960
 #define PCI_SUBSYS_ID_INTEL_RAID_SRCU41L_LAKE_SHETEK	0x0520
 
-#define PCI_DEVICE_ID_FSC_MEGARAID_PCI_EXPRESS_ROMB	0x0408
-#define PCI_SUBSYS_ID_FSC_MEGARAID_PCI_EXPRESS_ROMB	0x1065
-
-#define PCI_DEVICE_ID_MEGARAID_ACER_ROMB_2E		0x0408
-#define PCI_SUBSYS_ID_MEGARAID_ACER_ROMB_2E		0x004D
-
 #define PCI_SUBSYS_ID_PERC3_QC				0x0471
 #define PCI_SUBSYS_ID_PERC3_DC				0x0493
 #define PCI_SUBSYS_ID_PERC3_SC				0x0475
 
-#define PCI_DEVICE_ID_MEGARAID_NEC_ROMB_2E		0x0408
-#define PCI_SUBSYS_ID_MEGARAID_NEC_ROMB_2E		0x8287
-
-#ifndef PCI_SUBSYS_ID_FSC
-#define PCI_SUBSYS_ID_FSC				0x1734
-#endif
 
 #define MBOX_MAX_SCSI_CMDS	128	// number of cmds reserved for kernel
 #define MBOX_MAX_USER_CMDS	32	// number of cmds for applications
diff --git a/drivers/scsi/megaraid/megaraid_mm.c b/drivers/scsi/megaraid/megaraid_mm.c
--- a/drivers/scsi/megaraid/megaraid_mm.c
+++ b/drivers/scsi/megaraid/megaraid_mm.c
@@ -10,13 +10,12 @@
  *	   2 of the License, or (at your option) any later version.
  *
  * FILE		: megaraid_mm.c
- * Version	: v2.20.2.5 (Jan 21 2005)
+ * Version	: v2.20.2.6 (Mar 7 2005)
  *
  * Common management module
  */
 
 #include "megaraid_mm.h"
-#include <linux/smp_lock.h>
 
 
 // Entry points for char node driver
@@ -61,7 +60,7 @@ EXPORT_SYMBOL(mraid_mm_unregister_adp);
 EXPORT_SYMBOL(mraid_mm_adapter_app_handle);
 
 static int majorno;
-static uint32_t drvr_ver	= 0x02200201;
+static uint32_t drvr_ver	= 0x02200206;
 
 static int adapters_count_g;
 static struct list_head adapters_list_g;
@@ -1231,9 +1230,9 @@ mraid_mm_compat_ioctl(struct file *filep
 		      unsigned long arg)
 {
 	int err;
-	lock_kernel();
+
 	err = mraid_mm_ioctl(NULL, filep, cmd, arg);
-	unlock_kernel();
+
 	return err;
 }
 #endif
diff --git a/drivers/scsi/megaraid/megaraid_mm.h b/drivers/scsi/megaraid/megaraid_mm.h
--- a/drivers/scsi/megaraid/megaraid_mm.h
+++ b/drivers/scsi/megaraid/megaraid_mm.h
@@ -29,9 +29,9 @@
 #include "megaraid_ioctl.h"
 
 
-#define LSI_COMMON_MOD_VERSION	"2.20.2.5"
+#define LSI_COMMON_MOD_VERSION	"2.20.2.6"
 #define LSI_COMMON_MOD_EXT_VERSION	\
-		"(Release Date: Fri Jan 21 00:01:03 EST 2005)"
+		"(Release Date: Mon Mar 7 00:01:03 EST 2005)"
 
 
 #define LSI_DBGLVL			dbglevel
diff --git a/drivers/scsi/mesh.c b/drivers/scsi/mesh.c
--- a/drivers/scsi/mesh.c
+++ b/drivers/scsi/mesh.c
@@ -1715,9 +1715,12 @@ static int mesh_host_reset(struct scsi_c
 	struct mesh_state *ms = (struct mesh_state *) cmd->device->host->hostdata;
 	volatile struct mesh_regs __iomem *mr = ms->mesh;
 	volatile struct dbdma_regs __iomem *md = ms->dma;
+	unsigned long flags;
 
 	printk(KERN_DEBUG "mesh_host_reset\n");
 
+	spin_lock_irqsave(ms->host->host_lock, flags);
+
 	/* Reset the controller & dbdma channel */
 	out_le32(&md->control, (RUN|PAUSE|FLUSH|WAKE) << 16);	/* stop dma */
 	out_8(&mr->exception, 0xff);	/* clear all exception bits */
@@ -1739,6 +1742,7 @@ static int mesh_host_reset(struct scsi_c
 	/* Complete pending commands */
 	handle_reset(ms);
 	
+	spin_unlock_irqrestore(ms->host->host_lock, flags);
 	return SUCCESS;
 }
 
@@ -1843,7 +1847,7 @@ static struct scsi_host_template mesh_te
 	.use_clustering			= DISABLE_CLUSTERING,
 };
 
-static int mesh_probe(struct macio_dev *mdev, const struct of_match *match)
+static int mesh_probe(struct macio_dev *mdev, const struct of_device_id *match)
 {
 	struct device_node *mesh = macio_get_of_node(mdev);
 	struct pci_dev* pdev = macio_get_pci_dev(mdev);
@@ -2008,20 +2012,18 @@ static int mesh_remove(struct macio_dev 
 }
 
 
-static struct of_match mesh_match[] = 
+static struct of_device_id mesh_match[] = 
 {
 	{
 	.name 		= "mesh",
-	.type		= OF_ANY_MATCH,
-	.compatible	= OF_ANY_MATCH
 	},
 	{
-	.name 		= OF_ANY_MATCH,
 	.type		= "scsi",
 	.compatible	= "chrp,mesh0"
 	},
 	{},
 };
+MODULE_DEVICE_TABLE (of, mesh_match);
 
 static struct macio_driver mesh_driver = 
 {
diff --git a/drivers/scsi/mvme147.c b/drivers/scsi/mvme147.c
--- a/drivers/scsi/mvme147.c
+++ b/drivers/scsi/mvme147.c
@@ -116,7 +116,14 @@ int mvme147_detect(Scsi_Host_Template *t
 static int mvme147_bus_reset(Scsi_Cmnd *cmd)
 {
 	/* FIXME perform bus-specific reset */
+
+	/* FIXME 2: kill this function, and let midlayer fallback to 
+	   the same result, calling wd33c93_host_reset() */
+
+	spin_lock_irq(cmd->device->host->host_lock);
 	wd33c93_host_reset(cmd);
+	spin_unlock_irq(cmd->device->host->host_lock);
+
 	return SUCCESS;
 }
 
diff --git a/drivers/scsi/ncr53c8xx.c b/drivers/scsi/ncr53c8xx.c
--- a/drivers/scsi/ncr53c8xx.c
+++ b/drivers/scsi/ncr53c8xx.c
@@ -7756,7 +7756,6 @@ struct Scsi_Host * __init ncr_attach(str
 	 * your module_init */
 	BUG_ON(!ncr53c8xx_transport_template);
 	instance->transportt	= ncr53c8xx_transport_template;
-	scsi_set_device(instance, device->dev);
 
 	/* Patch script to physical addresses */
 	ncr_script_fill(&script0, &scripth0);
diff --git a/drivers/scsi/nsp32.c b/drivers/scsi/nsp32.c
--- a/drivers/scsi/nsp32.c
+++ b/drivers/scsi/nsp32.c
@@ -294,7 +294,6 @@ static struct scsi_host_template nsp32_t
 	.this_id			= NSP32_HOST_SCSIID,
 	.use_clustering			= DISABLE_CLUSTERING,
 	.eh_abort_handler       	= nsp32_eh_abort,
-/*	.eh_device_reset_handler	= NULL, */
 	.eh_bus_reset_handler		= nsp32_eh_bus_reset,
 	.eh_host_reset_handler		= nsp32_eh_host_reset,
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,74))
@@ -2720,9 +2719,7 @@ static int nsp32_detect(Scsi_Host_Templa
 	host->unique_id = data->BaseAddress;
 	host->n_io_port	= data->NumAddress;
 	host->base      = (unsigned long)data->MmioAddress;
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,63))
-	scsi_set_device(host, &PCIDEV->dev);
-#else
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,63))
 	scsi_set_pci_device(host, PCIDEV);
 #endif
 
@@ -2988,6 +2985,8 @@ static int nsp32_eh_bus_reset(struct scs
 	nsp32_hw_data *data = (nsp32_hw_data *)SCpnt->device->host->hostdata;
 	unsigned int   base = SCpnt->device->host->io_port;
 
+	spin_lock_irq(SCpnt->device->host->host_lock);
+
 	nsp32_msg(KERN_INFO, "Bus Reset");	
 	nsp32_dbg(NSP32_DEBUG_BUSRESET, "SCpnt=0x%x", SCpnt);
 
@@ -2995,6 +2994,7 @@ static int nsp32_eh_bus_reset(struct scs
 	nsp32_do_bus_reset(data);
 	nsp32_write2(base, IRQ_CONTROL, 0);
 
+	spin_unlock_irq(SCpnt->device->host->host_lock);
 	return SUCCESS;	/* SCSI bus reset is succeeded at any time. */
 }
 
@@ -3049,11 +3049,14 @@ static int nsp32_eh_host_reset(struct sc
 	nsp32_msg(KERN_INFO, "Host Reset");	
 	nsp32_dbg(NSP32_DEBUG_BUSRESET, "SCpnt=0x%x", SCpnt);
 
+	spin_lock_irq(SCpnt->device->host->host_lock);
+
 	nsp32hw_init(data);
 	nsp32_write2(base, IRQ_CONTROL, IRQ_CONTROL_ALL_IRQ_MASK);
 	nsp32_do_bus_reset(data);
 	nsp32_write2(base, IRQ_CONTROL, 0);
 
+	spin_unlock_irq(SCpnt->device->host->host_lock);
 	return SUCCESS;	/* Host reset is succeeded at any time. */
 }
 
diff --git a/drivers/scsi/osst.c b/drivers/scsi/osst.c
--- a/drivers/scsi/osst.c
+++ b/drivers/scsi/osst.c
@@ -5608,13 +5608,13 @@ static ssize_t osst_filemark_cnt_show(st
 
 CLASS_DEVICE_ATTR(file_count, S_IRUGO, osst_filemark_cnt_show, NULL);
 
-static struct class_simple * osst_sysfs_class;
+static struct class *osst_sysfs_class;
 
 static int osst_sysfs_valid = 0;
 
 static void osst_sysfs_init(void)
 {
-	osst_sysfs_class = class_simple_create(THIS_MODULE, "onstream_tape");
+	osst_sysfs_class = class_create(THIS_MODULE, "onstream_tape");
 	if ( IS_ERR(osst_sysfs_class) )
 		printk(KERN_WARNING "osst :W: Unable to register sysfs class\n");
 	else
@@ -5627,7 +5627,7 @@ static void osst_sysfs_add(dev_t dev, st
 
 	if (!osst_sysfs_valid) return;
 
-	osst_class_member = class_simple_device_add(osst_sysfs_class, dev, device, "%s", name);
+	osst_class_member = class_device_create(osst_sysfs_class, dev, device, "%s", name);
 	if (IS_ERR(osst_class_member)) {
 		printk(KERN_WARNING "osst :W: Unable to add sysfs class member %s\n", name);
 		return;
@@ -5645,13 +5645,13 @@ static void osst_sysfs_destroy(dev_t dev
 {
 	if (!osst_sysfs_valid) return; 
 
-	class_simple_device_remove(dev);
+	class_device_destroy(osst_sysfs_class, dev);
 }
 
 static void osst_sysfs_cleanup(void)
 {
 	if (osst_sysfs_valid) {
-		class_simple_destroy(osst_sysfs_class);
+		class_destroy(osst_sysfs_class);
 		osst_sysfs_valid = 0;
 	}
 }
diff --git a/drivers/scsi/pas16.c b/drivers/scsi/pas16.c
--- a/drivers/scsi/pas16.c
+++ b/drivers/scsi/pas16.c
@@ -2,6 +2,7 @@
 #define PSEUDO_DMA
 #define FOO
 #define UNSAFE  /* Not unsafe for PAS16 -- use it */
+#define PDEBUG 0
 
 /*
  * This driver adapted from Drew Eckhardt's Trantor T128 driver
@@ -621,8 +622,6 @@ static Scsi_Host_Template driver_templat
 	.queuecommand   = pas16_queue_command,
 	.eh_abort_handler = pas16_abort,
 	.eh_bus_reset_handler = pas16_bus_reset,
-	.eh_device_reset_handler = pas16_device_reset,
-	.eh_host_reset_handler = pas16_host_reset,
 	.bios_param     = pas16_biosparam, 
 	.can_queue      = CAN_QUEUE,
 	.this_id        = 7,
diff --git a/drivers/scsi/pas16.h b/drivers/scsi/pas16.h
--- a/drivers/scsi/pas16.h
+++ b/drivers/scsi/pas16.h
@@ -120,8 +120,6 @@ static int pas16_biosparam(struct scsi_d
 static int pas16_detect(Scsi_Host_Template *);
 static int pas16_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
 static int pas16_bus_reset(Scsi_Cmnd *);
-static int pas16_host_reset(Scsi_Cmnd *);
-static int pas16_device_reset(Scsi_Cmnd *);
 
 #ifndef CMD_PER_LUN
 #define CMD_PER_LUN 2
@@ -164,9 +162,7 @@ static int pas16_device_reset(Scsi_Cmnd 
 #define do_NCR5380_intr do_pas16_intr
 #define NCR5380_queue_command pas16_queue_command
 #define NCR5380_abort pas16_abort
-#define NCR5380_device_reset pas16_device_reset
 #define NCR5380_bus_reset pas16_bus_reset
-#define NCR5380_host_reset pas16_host_reset
 #define NCR5380_proc_info pas16_proc_info
 
 /* 15 14 12 10 7 5 3 
diff --git a/drivers/scsi/pci2000.c b/drivers/scsi/pci2000.c
deleted file mode 100644
--- a/drivers/scsi/pci2000.c
+++ /dev/null
@@ -1,836 +0,0 @@
-/****************************************************************************
- * Perceptive Solutions, Inc. PCI-2000 device driver for Linux.
- *
- * pci2000.c - Linux Host Driver for PCI-2000 IntelliCache SCSI Adapters
- *
- * Copyright (c) 1997-1999 Perceptive Solutions, Inc.
- * All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that redistributions of source
- * code retain the above copyright notice and this comment without
- * modification.
- *
- * Technical updates and product information at:
- *  http://www.psidisk.com
- *
- * Please send questions, comments, bug reports to:
- *  tech@psidisk.com Technical Support
- *
- *
- *	Revisions	1.10	Jan-21-1999
- *		- Fixed sign on message to reflect proper controller name.
- *		- Added support for RAID status monitoring and control.
- *
- *  Revisions	1.11	Mar-22-1999
- *		- Fixed control timeout to not lock up the entire system if
- *		  controller goes offline completely.
- *
- *	Revisions 1.12		Mar-26-1999
- *		- Fixed spinlock and PCI configuration.
- *
- *	Revisions 1.20		Mar-27-2000
- *		- Added support for dynamic DMA
- *
- ****************************************************************************/
-#define PCI2000_VERSION		"1.20"
-
-#include <linux/blkdev.h>
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/string.h>
-#include <linux/pci.h>
-#include <linux/ioport.h>
-#include <linux/delay.h>
-#include <linux/sched.h>
-#include <linux/proc_fs.h>
-#include <linux/stat.h>
-#include <linux/spinlock.h>
-
-#include <asm/dma.h>
-#include <asm/system.h>
-#include <asm/io.h>
-
-#include "scsi.h"
-#include <scsi/scsi_host.h>
-#include "pci2000.h"
-#include "psi_roy.h"
-
-
-//#define DEBUG 1
-
-#ifdef DEBUG
-#define DEB(x) x
-#define STOP_HERE	{int st;for(st=0;st<100;st++){st=1;}}
-#else
-#define DEB(x)
-#define STOP_HERE
-#endif
-
-typedef struct
-	{
-	unsigned int	address;
-	unsigned int	length;
-	}	SCATGATH, *PSCATGATH;
-
-typedef struct
-	{
-	Scsi_Cmnd		*SCpnt;
-	PSCATGATH		 scatGath;
-	dma_addr_t		 scatGathDma;
-	UCHAR			*cdb;
-	dma_addr_t		 cdbDma; 
-	UCHAR			 tag;
-	}	DEV2000, *PDEV2000;
-
-typedef struct
-	{
-	ULONG			 basePort;
-	ULONG			 mb0;
-	ULONG			 mb1;
-	ULONG			 mb2;
-	ULONG			 mb3;
-	ULONG			 mb4;
-	ULONG			 cmd;
-	ULONG			 tag;
-	ULONG			 irqOwned;
-	struct pci_dev	*pdev;
-	DEV2000	 		 dev[MAX_BUS][MAX_UNITS];
-	}	ADAPTER2000, *PADAPTER2000;
-
-#define HOSTDATA(host) ((PADAPTER2000)&host->hostdata)
-#define consistentLen (MAX_BUS * MAX_UNITS * (16 * sizeof (SCATGATH) + MAX_COMMAND_SIZE))
-
-
-static struct	Scsi_Host 	   *PsiHost[MAXADAPTER] = {NULL,};  // One for each adapter
-static			int				NumAdapters = 0;
-/****************************************************************
- *	Name:			WaitReady	:LOCAL
- *
- *	Description:	Wait for controller ready.
- *
- *	Parameters:		padapter - Pointer adapter data structure.
- *
- *	Returns:		TRUE on not ready.
- *
- ****************************************************************/
-static int WaitReady (PADAPTER2000 padapter)
-	{
-	ULONG	z;
-
-	for ( z = 0;  z < (TIMEOUT_COMMAND * 4);  z++ )
-		{
-		if ( !inb_p (padapter->cmd) )
-			return FALSE;
-		udelay (250);
-		};								
-	return TRUE;
-	}
-/****************************************************************
- *	Name:			WaitReadyLong	:LOCAL
- *
- *	Description:	Wait for controller ready.
- *
- *	Parameters:		padapter - Pointer adapter data structure.
- *
- *	Returns:		TRUE on not ready.
- *
- ****************************************************************/
-static int WaitReadyLong (PADAPTER2000 padapter)
-	{
-	ULONG	z;
-
-	for ( z = 0;  z < (5000 * 4);  z++ )
-		{
-		if ( !inb_p (padapter->cmd) )
-			return FALSE;
-		udelay (250);
-		};								
-	return TRUE;
-	}
-/****************************************************************
- *	Name:	OpDone	:LOCAL
- *
- *	Description:	Clean up operation and issue done to caller.
- *
- *	Parameters:		SCpnt	- Pointer to SCSI command structure.
- *					status	- Caller status.
- *
- *	Returns:		Nothing.
- *
- ****************************************************************/
-static void OpDone (Scsi_Cmnd *SCpnt, ULONG status)
-	{
-	SCpnt->result = status;
-	SCpnt->scsi_done (SCpnt);
-	}
-/****************************************************************
- *	Name:	Command		:LOCAL
- *
- *	Description:	Issue queued command to the PCI-2000.
- *
- *	Parameters:		padapter - Pointer to adapter information structure.
- *					cmd		 - PCI-2000 command byte.
- *
- *	Returns:		Non-zero command tag if operation is accepted.
- *
- ****************************************************************/
-static UCHAR Command (PADAPTER2000 padapter, UCHAR cmd)
-	{
-	outb_p (cmd, padapter->cmd);
-	if ( WaitReady (padapter) )
-		return 0;
-
-	if ( inw_p (padapter->mb0) )
-		return 0;
-
-	return inb_p (padapter->mb1);
-	}
-/****************************************************************
- *	Name:	BuildSgList		:LOCAL
- *
- *	Description:	Build the scatter gather list for controller.
- *
- *	Parameters:		SCpnt	 - Pointer to SCSI command structure.
- *					padapter - Pointer to adapter information structure.
- *					pdev	 - Pointer to adapter device structure.
- *
- *	Returns:		Non-zero in not scatter gather.
- *
- ****************************************************************/
-static int BuildSgList (Scsi_Cmnd *SCpnt, PADAPTER2000 padapter, PDEV2000 pdev)
-	{
-	int					 z;
-	int					 zc;
-	struct scatterlist	*sg;
-
-	if ( SCpnt->use_sg )
-		{
-		sg = (struct scatterlist *)SCpnt->request_buffer;
-		zc = pci_map_sg (padapter->pdev, sg, SCpnt->use_sg, SCpnt->sc_data_direction);
-		for ( z = 0;  z < zc;  z++ )
-			{
-			pdev->scatGath[z].address = cpu_to_le32 (sg_dma_address (sg));
-			pdev->scatGath[z].length = cpu_to_le32 (sg_dma_len (sg++));
-			}
-		outl (pdev->scatGathDma, padapter->mb2);
-		outl ((zc << 24) | SCpnt->request_bufflen, padapter->mb3);
-		return FALSE;
-		}
-	if ( !SCpnt->request_bufflen)
-		{
-		outl (0, padapter->mb2);
-		outl (0, padapter->mb3);
-		return TRUE;
-		}
-	SCpnt->SCp.have_data_in = pci_map_single (padapter->pdev,
-			SCpnt->request_buffer, SCpnt->request_bufflen,
-			SCpnt->sc_data_direction);
-	outl (SCpnt->SCp.have_data_in, padapter->mb2);
-	outl (SCpnt->request_bufflen, padapter->mb3);
-	return TRUE;
-	}
-/*********************************************************************
- *	Name:	PsiRaidCmd
- *
- *	Description:	Execute a simple command.
- *
- *	Parameters:		padapter - Pointer to adapter control structure.
- *					cmd		 - Roy command byte.
- *
- *	Returns:		Return error status.
- *
- ********************************************************************/
-static int PsiRaidCmd (PADAPTER2000 padapter, char cmd)
-	{
-	if ( WaitReady (padapter) )						// test for command register ready
-		return DID_TIME_OUT;
-	outb_p (cmd, padapter->cmd);					// issue command
-	if ( WaitReadyLong (padapter) )					// wait for adapter ready
-		return DID_TIME_OUT;
-	return DID_OK;
-	}
-/****************************************************************
- *	Name:	Irq_Handler	:LOCAL
- *
- *	Description:	Interrupt handler.
- *
- *	Parameters:		irq		- Hardware IRQ number.
- *					dev_id	-
- *					regs	-
- *
- *	Returns:		TRUE if drive is not ready in time.
- *
- ****************************************************************/
-static irqreturn_t Irq_Handler (int irq, void *dev_id, struct pt_regs *regs)
-	{
-	struct Scsi_Host   *shost = NULL;	// Pointer to host data block
-	PADAPTER2000		padapter;		// Pointer to adapter control structure
-	PDEV2000			pdev;
-	Scsi_Cmnd		   *SCpnt;
-	UCHAR				tag = 0;
-	UCHAR				tag0;
-	ULONG				error;
-	int					pun;
-	int					bus;
-	int					z;
-    unsigned long		flags;
-    int handled = 0;
-
-	DEB(printk ("\npci2000 received interrupt "));
-	for ( z = 0; z < NumAdapters;  z++ )										// scan for interrupt to process
-		{
-		if ( PsiHost[z]->irq == (UCHAR)(irq & 0xFF) )
-			{
-			tag = inb_p (HOSTDATA(PsiHost[z])->tag);
-			if (  tag )
-				{
-				shost = PsiHost[z];
-				break;
-				}
-			}
-		}
-
-	if ( !shost )
-		{
-		DEB (printk ("\npci2000: not my interrupt"));
-		goto out;
-		}
-
-    handled = 1;
-	spin_lock_irqsave(shost->host_lock, flags);
-	padapter = HOSTDATA(shost);
-
-	tag0 = tag & 0x7F;															// mask off the error bit
-	for ( bus = 0;  bus < MAX_BUS;  bus++ )										// scan the busses
-    	{
-		for ( pun = 0;  pun < MAX_UNITS;  pun++ )								// scan the targets
-    		{
-			pdev = &padapter->dev[bus][pun];
-			if ( !pdev->tag )
-    			continue;
-			if ( pdev->tag == tag0 )											// is this it?
-				{
-				pdev->tag = 0;
-				SCpnt = pdev->SCpnt;
-				goto unmapProceed;
-    			}
-			}
-    	}
-
-	outb_p (0xFF, padapter->tag);												// clear the op interrupt
-	outb_p (CMD_DONE, padapter->cmd);											// complete the op
-	goto irq_return;															// done, but, with what?
-
-unmapProceed:;
-	if ( !bus )
-		{
-		switch ( SCpnt->cmnd[0] )
-			{
-			case SCSIOP_TEST_UNIT_READY:
-				pci_unmap_single (padapter->pdev, SCpnt->SCp.have_data_in, sizeof (SCpnt->sense_buffer), PCI_DMA_FROMDEVICE);
-				goto irqProceed;
-			case SCSIOP_READ_CAPACITY:
-				pci_unmap_single (padapter->pdev, SCpnt->SCp.have_data_in, 8, PCI_DMA_FROMDEVICE);
-				goto irqProceed;
-			case SCSIOP_VERIFY:
-			case SCSIOP_START_STOP_UNIT:
-			case SCSIOP_MEDIUM_REMOVAL:
-				goto irqProceed;
-			}
-		}
-	if ( SCpnt->SCp.have_data_in )
-		pci_unmap_single (padapter->pdev, SCpnt->SCp.have_data_in, SCpnt->request_bufflen, SCpnt->sc_data_direction);
-	else 
-		{
-		if ( SCpnt->use_sg )
-			pci_unmap_sg (padapter->pdev, (struct scatterlist *)SCpnt->request_buffer, SCpnt->use_sg, SCpnt->sc_data_direction);
-		}
-
-irqProceed:;
-	if ( tag & ERR08_TAGGED )												// is there an error here?
-		{
-		if ( WaitReady (padapter) )
-			{
-			OpDone (SCpnt, DID_TIME_OUT << 16);
-			goto irq_return;
-			}
-
-		outb_p (tag0, padapter->mb0);										// get real error code
-		outb_p (CMD_ERROR, padapter->cmd);
-		if ( WaitReady (padapter) )											// wait for controller to suck up the op
-			{
-			OpDone (SCpnt, DID_TIME_OUT << 16);
-			goto irq_return;
-			}
-
-		error = inl (padapter->mb0);										// get error data
-		outb_p (0xFF, padapter->tag);										// clear the op interrupt
-		outb_p (CMD_DONE, padapter->cmd);									// complete the op
-
-		DEB (printk ("status: %lX ", error));
-		if ( error == 0x00020002 )											// is this error a check condition?
-			{
-			if ( bus )														// are we doint SCSI commands?
-				{
-				OpDone (SCpnt, (DID_OK << 16) | 2);
-				goto irq_return;
-				}
-			if ( *SCpnt->cmnd == SCSIOP_TEST_UNIT_READY )
-				OpDone (SCpnt, (DRIVER_SENSE << 24) | (DID_OK << 16) | 2);	// test caller we have sense data too
-			else
-				OpDone (SCpnt, DID_ERROR << 16);
-			goto irq_return;
-			}
-		OpDone (SCpnt, DID_ERROR << 16);
-		goto irq_return;
-		}
-
-	outb_p (0xFF, padapter->tag);											// clear the op interrupt
-	outb_p (CMD_DONE, padapter->cmd);										// complete the op
-	OpDone (SCpnt, DID_OK << 16);
-
-irq_return:
-    spin_unlock_irqrestore(shost->host_lock, flags);
-out:
-    return IRQ_RETVAL(handled);
-}
-/****************************************************************
- *	Name:	Pci2000_QueueCommand
- *
- *	Description:	Process a queued command from the SCSI manager.
- *
- *	Parameters:		SCpnt - Pointer to SCSI command structure.
- *					done  - Pointer to done function to call.
- *
- *	Returns:		Status code.
- *
- ****************************************************************/
-int Pci2000_QueueCommand (Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
-	{
-	UCHAR		   *cdb = (UCHAR *)SCpnt->cmnd;					// Pointer to SCSI CDB
-	PADAPTER2000	padapter = HOSTDATA(SCpnt->device->host);			// Pointer to adapter control structure
-	int				rc		 = -1;								// command return code
-	UCHAR			bus		 = SCpnt->device->channel;
-	UCHAR			pun		 = SCpnt->device->id;
-	UCHAR			lun		 = SCpnt->device->lun;
-	UCHAR			cmd;
-	PDEV2000		pdev	 = &padapter->dev[bus][pun];
-
-	if ( !done )
-		{
-		printk("pci2000_queuecommand: %02X: done can't be NULL\n", *cdb);
-		return 0;
-		}
-
-	SCpnt->scsi_done = done;
-	SCpnt->SCp.have_data_in = 0;
-	pdev->SCpnt = SCpnt;  									// Save this command data
-
-	if ( WaitReady (padapter) )
-		{
-		rc = DID_ERROR;
-		goto finished;
-		}
-
-	outw_p (pun | (lun << 8), padapter->mb0);
-
-	if ( bus )
-		{
-		DEB (if(*cdb) printk ("\nCDB: %X-  %X %X %X %X %X %X %X %X %X %X ", SCpnt->cmd_len, cdb[0], cdb[1], cdb[2], cdb[3], cdb[4], cdb[5], cdb[6], cdb[7], cdb[8], cdb[9]));
-		DEB (if(*cdb) printk ("\ntimeout_per_command: %d, timeout_total: %d, timeout: %d", SCpnt->timeout_per_command,
-							  SCpnt->timeout_total, SCpnt->timeout));
-		outl (SCpnt->timeout_per_command, padapter->mb1);
-		outb_p (CMD_SCSI_TIMEOUT, padapter->cmd);
-		if ( WaitReady (padapter) )
-			{
-			rc = DID_ERROR;
-			goto finished;
-			}
-
-		outw_p (pun | (lun << 8), padapter->mb0);
-		outw_p (SCpnt->cmd_len << 8, padapter->mb0 + 2);
-		memcpy (pdev->cdb, cdb, MAX_COMMAND_SIZE);
-
-		outl (pdev->cdbDma, padapter->mb1);
-		if ( BuildSgList (SCpnt, padapter, pdev) )
-			cmd = CMD_SCSI_THRU;
-		else
-			cmd = CMD_SCSI_THRU_SG;
-		if ( (pdev->tag = Command (padapter, cmd)) == 0 )
-			rc = DID_TIME_OUT;
-		goto finished;
-		}
-	else
-		{
-		if ( lun )
-			{
-			rc = DID_BAD_TARGET;
-			goto finished;
-			}
-		}
-
-	switch ( *cdb )
-		{
-		case SCSIOP_INQUIRY:   					// inquiry CDB
-			if ( cdb[2] == SC_MY_RAID )
-				{
-				switch ( cdb[3] ) 
-					{
-					case MY_SCSI_REBUILD:
-						OpDone (SCpnt, PsiRaidCmd (padapter, CMD_RAID_REBUILD) << 16);
-						return 0;
-					case MY_SCSI_ALARMMUTE:
-						OpDone (SCpnt, PsiRaidCmd (padapter, CMD_RAID_MUTE) << 16);
-						return 0;
-					case MY_SCSI_DEMOFAIL:
-						OpDone (SCpnt, PsiRaidCmd (padapter, CMD_RAID_FAIL) << 16);
-						return 0;
-					default:
-						if ( SCpnt->use_sg )
-							{
-							rc = DID_ERROR;
-							goto finished;
-							}
-						else
-							{
-							SCpnt->SCp.have_data_in = pci_map_single (padapter->pdev, SCpnt->request_buffer, SCpnt->request_bufflen,
-													  SCpnt->sc_data_direction);
-							outl (SCpnt->SCp.have_data_in, padapter->mb2);
-							}
-						outl (cdb[5], padapter->mb0);
-						outl (cdb[3], padapter->mb3);
-						cmd = CMD_DASD_RAID_RQ;
-						break;
-					}
-				break;
-				}
-			
-			if ( SCpnt->use_sg )
-				{
-				SCpnt->SCp.have_data_in = pci_map_single (padapter->pdev,
-									  ((struct scatterlist *)SCpnt->request_buffer)->address,
-									  SCpnt->request_bufflen,
-									  SCpnt->sc_data_direction);
-				}
-			else
-				{
-				SCpnt->SCp.have_data_in = pci_map_single (padapter->pdev, SCpnt->request_buffer,
-									  SCpnt->request_bufflen,
-									  SCpnt->sc_data_direction);
-				}
-			outl (SCpnt->SCp.have_data_in, padapter->mb2);
-			outl (SCpnt->request_bufflen, padapter->mb3);
-			cmd = CMD_DASD_SCSI_INQ;
-			break;
-
-		case SCSIOP_TEST_UNIT_READY:			// test unit ready CDB
-			SCpnt->SCp.have_data_in = pci_map_single (padapter->pdev, SCpnt->sense_buffer, sizeof (SCpnt->sense_buffer), PCI_DMA_FROMDEVICE);
-			outl (SCpnt->SCp.have_data_in, padapter->mb2);
-			outl (sizeof (SCpnt->sense_buffer), padapter->mb3);
-			cmd = CMD_TEST_READY;
-			break;
-
-		case SCSIOP_READ_CAPACITY:			  	// read capacity CDB
-			if ( SCpnt->use_sg )
-				{
-				SCpnt->SCp.have_data_in = pci_map_single (padapter->pdev, ((struct scatterlist *)(SCpnt->request_buffer))->address,
-										  8, PCI_DMA_FROMDEVICE);
-				}
-			else
-				SCpnt->SCp.have_data_in = pci_map_single (padapter->pdev, SCpnt->request_buffer, 8, PCI_DMA_FROMDEVICE);
-			outl (SCpnt->SCp.have_data_in, padapter->mb2);
-			outl (8, padapter->mb3);
-			cmd = CMD_DASD_CAP;
-			break;
-		case SCSIOP_VERIFY:						// verify CDB
-			outw_p ((USHORT)cdb[8] | ((USHORT)cdb[7] << 8), padapter->mb0 + 2);
-			outl (XSCSI2LONG (&cdb[2]), padapter->mb1);
-			cmd = CMD_READ_SG;
-			break;
-		case SCSIOP_READ:						// read10 CDB
-			outw_p ((USHORT)cdb[8] | ((USHORT)cdb[7] << 8), padapter->mb0 + 2);
-			outl (XSCSI2LONG (&cdb[2]), padapter->mb1);
-			if ( BuildSgList (SCpnt, padapter, pdev) )
-				cmd = CMD_READ;
-			else
-				cmd = CMD_READ_SG;
-			break;
-		case SCSIOP_READ6:						// read6  CDB
-			outw_p (cdb[4], padapter->mb0 + 2);
-			outl ((SCSI2LONG (&cdb[1])) & 0x001FFFFF, padapter->mb1);
-			if ( BuildSgList (SCpnt, padapter, pdev) )
-				cmd = CMD_READ;
-			else
-				cmd = CMD_READ_SG;
-			break;
-		case SCSIOP_WRITE:						// write10 CDB
-			outw_p ((USHORT)cdb[8] | ((USHORT)cdb[7] << 8), padapter->mb0 + 2);
-			outl (XSCSI2LONG (&cdb[2]), padapter->mb1);
-			if ( BuildSgList (SCpnt, padapter, pdev) )
-				cmd = CMD_WRITE;
-			else
-				cmd = CMD_WRITE_SG;
-			break;
-		case SCSIOP_WRITE6:						// write6  CDB
-			outw_p (cdb[4], padapter->mb0 + 2);
-			outl ((SCSI2LONG (&cdb[1])) & 0x001FFFFF, padapter->mb1);
-			if ( BuildSgList (SCpnt, padapter, pdev) )
-				cmd = CMD_WRITE;
-			else
-				cmd = CMD_WRITE_SG;
-			break;
-		case SCSIOP_START_STOP_UNIT:
-			cmd = CMD_EJECT_MEDIA;
-			break;
-		case SCSIOP_MEDIUM_REMOVAL:
-			switch ( cdb[4] )
-				{
-				case 0:
-					cmd = CMD_UNLOCK_DOOR;
-					break;
-				case 1:
-					cmd = CMD_LOCK_DOOR;
-					break;
-				default:
-					cmd = 0;
-					break;
-				}
-			if ( cmd )
-				break;
-		default:
-			DEB (printk ("pci2000_queuecommand: Unsupported command %02X\n", *cdb));
-			OpDone (SCpnt, DID_ERROR << 16);
-			return 0;
-		}
-
-	if ( (pdev->tag = Command (padapter, cmd)) == 0 )
-		rc = DID_TIME_OUT;
-finished:;
-	if ( rc != -1 )
-		OpDone (SCpnt, rc << 16);
-	return 0;
-	}
-/****************************************************************
- *	Name:	Pci2000_Detect
- *
- *	Description:	Detect and initialize our boards.
- *
- *	Parameters:		tpnt - Pointer to SCSI host template structure.
- *
- *	Returns:		Number of adapters installed.
- *
- ****************************************************************/
-int Pci2000_Detect (Scsi_Host_Template *tpnt)
-	{
-	int					found = 0;
-	int					installed = 0;
-	struct Scsi_Host   *pshost;
-	PADAPTER2000	    padapter;
-	int					z, zz;
-	int					setirq;
-	struct pci_dev	   *pdev = NULL;
-	UCHAR			   *consistent;
-	dma_addr_t			consistentDma;
-
-	while ( (pdev = pci_find_device (VENDOR_PSI, DEVICE_ROY_1, pdev)) != NULL )
-		{
-		if (pci_enable_device(pdev))
-			continue;
-		pshost = scsi_register (tpnt, sizeof(ADAPTER2000));
-		if(pshost == NULL)
-			continue;
-		padapter = HOSTDATA(pshost);
-
-		padapter->basePort = pci_resource_start (pdev, 1);
-		DEB (printk ("\nBase Regs = %#04X", padapter->basePort));			// get the base I/O port address
-		padapter->mb0	= padapter->basePort + RTR_MAILBOX;		   			// get the 32 bit mail boxes
-		padapter->mb1	= padapter->basePort + RTR_MAILBOX + 4;
-		padapter->mb2	= padapter->basePort + RTR_MAILBOX + 8;
-		padapter->mb3	= padapter->basePort + RTR_MAILBOX + 12;
-		padapter->mb4	= padapter->basePort + RTR_MAILBOX + 16;
-		padapter->cmd	= padapter->basePort + RTR_LOCAL_DOORBELL;			// command register
-		padapter->tag	= padapter->basePort + RTR_PCI_DOORBELL;			// tag/response register
-		padapter->pdev = pdev;
-
-		if ( WaitReady (padapter) )
-			goto unregister;
-		outb_p (0x84, padapter->mb0);
-		outb_p (CMD_SPECIFY, padapter->cmd);
-		if ( WaitReady (padapter) )
-			goto unregister;
-
-		consistent = pci_alloc_consistent (pdev, consistentLen, &consistentDma);
-		if ( !consistent )
-			{
-			printk ("Unable to allocate DMA memory for PCI-2000 controller.\n");
-			goto unregister;
-			}
-		
-		scsi_set_device(pshost, &pdev->dev);
-		pshost->irq = pdev->irq;
-		setirq = 1;
-		padapter->irqOwned = 0;
-		for ( z = 0;  z < installed;  z++ )									// scan for shared interrupts
-			{
-			if ( PsiHost[z]->irq == pshost->irq )							// if shared then, don't posses
-				setirq = 0;
-			}
-		if ( setirq )												// if not shared, posses
-			{
-			if ( request_irq (pshost->irq, Irq_Handler, SA_SHIRQ, "pci2000", padapter) < 0 )
-				{
-				if ( request_irq (pshost->irq, Irq_Handler, SA_INTERRUPT | SA_SHIRQ, "pci2000", padapter) < 0 )
-					{
-					printk ("Unable to allocate IRQ for PCI-2000 controller.\n");
-					pci_free_consistent (pdev, consistentLen, consistent, consistentDma);
-					goto unregister;
-					}
-				}
-			padapter->irqOwned = pshost->irq;						// set IRQ as owned
-			}
-		PsiHost[installed]	= pshost;										// save SCSI_HOST pointer
-
-		pshost->io_port		= padapter->basePort;
-		pshost->n_io_port	= 0xFF;
-		pshost->unique_id	= padapter->basePort;
-		pshost->max_id		= 16;
-		pshost->max_channel	= 1;
-
-		for ( zz = 0;  zz < MAX_BUS;  zz++ )
-			for ( z = 0; z < MAX_UNITS;  z++ )
-				{
-				padapter->dev[zz][z].tag = 0;
-				padapter->dev[zz][z].scatGath = (PSCATGATH)consistent;
-				padapter->dev[zz][z].scatGathDma = consistentDma;
-				consistent += 16 * sizeof (SCATGATH);
-				consistentDma += 16 * sizeof (SCATGATH);
-				padapter->dev[zz][z].cdb = (UCHAR *)consistent;
-				padapter->dev[zz][z].cdbDma = consistentDma;
-				consistent += MAX_COMMAND_SIZE;
-				consistentDma += MAX_COMMAND_SIZE;
-				}
-			
-		printk("\nPSI-2000 Intelligent Storage SCSI CONTROLLER: at I/O = %lX  IRQ = %d\n", padapter->basePort, pshost->irq);
-		printk("Version %s, Compiled %s %s\n\n", PCI2000_VERSION,  __DATE__, __TIME__);
-		found++;
-		if ( ++installed < MAXADAPTER )
-			continue;
-		break;
-unregister:;
-		scsi_unregister (pshost);
-		found++;
-		}
-	NumAdapters = installed;
-	return installed;
-	}
-/****************************************************************
- *	Name:	Pci2000_Abort
- *
- *	Description:	Process the Abort command from the SCSI manager.
- *
- *	Parameters:		SCpnt - Pointer to SCSI command structure.
- *
- *	Returns:		Allways snooze.
- *
- ****************************************************************/
-int Pci2000_Abort (Scsi_Cmnd *SCpnt)
-	{
-	DEB (printk ("pci2000_abort\n"));
-	return SCSI_ABORT_SNOOZE;
-	}
-/****************************************************************
- *	Name:	Pci2000_Reset
- *
- *	Description:	Process the Reset command from the SCSI manager.
- *
- *	Parameters:		SCpnt - Pointer to SCSI command structure.
- *					flags - Flags about the reset command
- *
- *	Returns:		No active command at this time, so this means
- *					that each time we got some kind of response the
- *					last time through.  Tell the mid-level code to
- *					request sense information in order to decide what
- *					to do next.
- *
- ****************************************************************/
-int Pci2000_Reset (Scsi_Cmnd *SCpnt, unsigned int reset_flags)
-	{
-	return SCSI_RESET_PUNT;
-	}
-/****************************************************************
- *	Name:	Pci2000_Release
- *
- *	Description:	Release resources allocated for a single each adapter.
- *
- *	Parameters:		pshost - Pointer to SCSI command structure.
- *
- *	Returns:		zero.
- *
- ****************************************************************/
-int Pci2000_Release (struct Scsi_Host *pshost)
-	{
-    PADAPTER2000	padapter = HOSTDATA (pshost);
-
-	if ( padapter->irqOwned )
-		free_irq (pshost->irq, padapter);
-	pci_free_consistent (padapter->pdev, consistentLen, padapter->dev[0][0].scatGath, padapter->dev[0][0].scatGathDma);
-	release_region (pshost->io_port, pshost->n_io_port);
-    scsi_unregister(pshost);
-    return 0;
-	}
-
-/****************************************************************
- *	Name:	Pci2000_BiosParam
- *
- *	Description:	Process the biosparam request from the SCSI manager to
- *					return C/H/S data.
- *
- *	Parameters:		disk - Pointer to SCSI disk structure.
- *					dev	 - Major/minor number from kernel.
- *					geom - Pointer to integer array to place geometry data.
- *
- *	Returns:		zero.
- *
- ****************************************************************/
-int Pci2000_BiosParam (struct scsi_device *sdev, struct block_device *dev,
-		sector_t capacity, int geom[])
-	{
-	PADAPTER2000	    padapter;
-
-	padapter = HOSTDATA(sdev->host);
-
-	if ( WaitReady (padapter) )
-		return 0;
-	outb_p (sdev->id, padapter->mb0);
-	outb_p (CMD_GET_PARMS, padapter->cmd);
-	if ( WaitReady (padapter) )
-		return 0;
-
-	geom[0] = inb_p (padapter->mb2 + 3);
-	geom[1] = inb_p (padapter->mb2 + 2);
-	geom[2] = inw_p (padapter->mb2);
-	return 0;
-	}
-
-
-MODULE_LICENSE("Dual BSD/GPL");
-
-static Scsi_Host_Template driver_template = {
-	.proc_name	= "pci2000",
-	.name		= "PCI-2000 SCSI Intelligent Disk Controller",
-	.detect		= Pci2000_Detect,
-	.release	= Pci2000_Release,
-	.queuecommand	= Pci2000_QueueCommand,
-	.abort		= Pci2000_Abort,
-	.reset		= Pci2000_Reset,
-	.bios_param	= Pci2000_BiosParam,
-	.can_queue	= 16,
-	.this_id	= -1,
-	.sg_tablesize	= 16,
-	.cmd_per_lun	= 1,
-	.use_clustering	= DISABLE_CLUSTERING,
-};
-#include "scsi_module.c"
diff --git a/drivers/scsi/pci2220i.c b/drivers/scsi/pci2220i.c
deleted file mode 100644
--- a/drivers/scsi/pci2220i.c
+++ /dev/null
@@ -1,2915 +0,0 @@
-/****************************************************************************
- * Perceptive Solutions, Inc. PCI-2220I device driver for Linux.
- *
- * pci2220i.c - Linux Host Driver for PCI-2220I EIDE RAID Adapters
- *
- * Copyright (c) 1997-1999 Perceptive Solutions, Inc.
- * All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that redistributions of source
- * code retain the above copyright notice and this comment without
- * modification.
- *
- * Technical updates and product information at:
- *  http://www.psidisk.com
- *
- * Please send questions, comments, bug reports to:
- *  tech@psidisk.com Technical Support
- *
- *
- *	Revisions 1.10		Mar-26-1999
- *		- Updated driver for RAID and hot reconstruct support.
- *
- *	Revisions 1.11		Mar-26-1999
- *		- Fixed spinlock and PCI configuration.
- *
- *	Revision 2.00		December-1-1999
- *		- Added code for the PCI-2240I controller
- *		- Added code for ATAPI devices.
- *		- Double buffer for scatter/gather support
- *
- *	Revision 2.10		March-27-2000
- *		- Added support for dynamic DMA
- *
- ****************************************************************************/
-
-#error Convert me to understand page+offset based scatterlists
-
-//#define DEBUG 1
-
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include <linux/pci.h>
-#include <linux/ioport.h>
-#include <linux/delay.h>
-#include <linux/sched.h>
-#include <linux/proc_fs.h>
-#include <linux/stat.h>
-#include <linux/blkdev.h>
-#include <linux/timer.h>
-#include <linux/spinlock.h>
-
-#include <asm/dma.h>
-#include <asm/system.h>
-#include <asm/io.h>
-
-#include "scsi.h"
-#include <scsi/scsi_host.h>
-#include "pci2220i.h"
-#include "psi_dale.h"
-
-
-#define	PCI2220I_VERSION		"2.10"
-#define	READ_CMD				IDE_CMD_READ_MULTIPLE
-#define	WRITE_CMD				IDE_CMD_WRITE_MULTIPLE
-#define	MAX_BUS_MASTER_BLOCKS	SECTORSXFER		// This is the maximum we can bus master
-
-#ifdef DEBUG
-#define DEB(x) x
-#define STOP_HERE()	{int st;for(st=0;st<100;st++){st=1;}}
-#else
-#define DEB(x)
-#define STOP_HERE()
-#endif
-
-#define MAXADAPTER 4					// Increase this and the sizes of the arrays below, if you need more.
-
-
-typedef struct
-	{
-	UCHAR			byte6;				// device select register image
-	UCHAR			spigot;				// spigot number
-	UCHAR			spigots[2];			// RAID spigots
-	UCHAR			deviceID[2];		// device ID codes
-	USHORT			sectors;			// number of sectors per track
-	USHORT			heads;				// number of heads
-	USHORT			cylinders;			// number of cylinders for this device
-	USHORT			spareword;			// placeholder
-	ULONG			blocks;				// number of blocks on device
-	DISK_MIRROR		DiskMirror[2];		// RAID status and control
-	ULONG			lastsectorlba[2];	// last addressable sector on the drive
-	USHORT			raid;				// RAID active flag
-	USHORT			mirrorRecon;
-	UCHAR			reconOn;
-	USHORT			reconCount;
-	USHORT			reconIsStarting;	// indicate hot reconstruct is starting
-	UCHAR			cmdDrqInt;			// flag for command interrupt
-	UCHAR			packet;				// command packet size in bytes
-	}	OUR_DEVICE, *POUR_DEVICE;	
-
-typedef struct
-	{
-	USHORT		 bigD;					// identity is a PCI-2240I if true, otherwise a PCI-2220I
-	USHORT		 atapi;					// this interface is for ATAPI devices only
-	ULONG		 regDmaDesc;			// address of the DMA discriptor register for direction of transfer
-	ULONG		 regDmaCmdStat;			// Byte #1 of DMA command status register
-	ULONG		 regDmaAddrPci;			// 32 bit register for PCI address of DMA
-	ULONG		 regDmaAddrLoc;			// 32 bit register for local bus address of DMA
-	ULONG		 regDmaCount;			// 32 bit register for DMA transfer count
-	ULONG		 regDmaMode;			// 32 bit register for DMA mode control
-	ULONG		 regRemap;				// 32 bit local space remap
-	ULONG		 regDesc;				// 32 bit local region descriptor
-	ULONG		 regRange;				// 32 bit local range
-	ULONG		 regIrqControl;			// 16 bit Interrupt enable/disable and status
-	ULONG		 regScratchPad;			// scratch pad I/O base address
-	ULONG		 regBase;				// Base I/O register for data space
-	ULONG		 regData;				// data register I/O address
-	ULONG		 regError;				// error register I/O address
-	ULONG		 regSectCount;			// sector count register I/O address
-	ULONG		 regLba0;				// least significant byte of LBA
-	ULONG		 regLba8;				// next least significant byte of LBA
-	ULONG		 regLba16;				// next most significan byte of LBA
-	ULONG		 regLba24;				// head and most 4 significant bits of LBA
-	ULONG		 regStatCmd;			// status on read and command on write register
-	ULONG		 regStatSel;			// board status on read and spigot select on write register
-	ULONG		 regFail;				// fail bits control register
-	ULONG		 regAltStat;			// alternate status and drive control register
-	ULONG		 basePort;				// PLX base I/O port
-	USHORT		 timingMode;			// timing mode currently set for adapter
-	USHORT		 timingPIO;				// TRUE if PIO timing is active
-	struct pci_dev	*pcidev;
-	ULONG		 timingAddress;			// address to use on adapter for current timing mode
-	ULONG		 irqOwned;				// owned IRQ or zero if shared
-	UCHAR		 numberOfDrives;		// saved number of drives on this controller
-	UCHAR		 failRegister;			// current inverted data in fail register
-	OUR_DEVICE	 device[BIGD_MAXDRIVES];
-	DISK_MIRROR	*raidData[BIGD_MAXDRIVES];
-	ULONG		 startSector;
-	USHORT		 sectorCount;
-	ULONG		 readCount;
-	UCHAR		*currentSgBuffer;
-	ULONG		 currentSgCount;
-	USHORT		 nextSg;
-	UCHAR		 cmd;
-	Scsi_Cmnd	*SCpnt;
-	POUR_DEVICE	 pdev;					// current device opearating on
-	USHORT		 devInReconIndex;
-	USHORT		 expectingIRQ;
-	USHORT		 reconOn;				// Hot reconstruct is to be done.
-	USHORT		 reconPhase;			// Hot reconstruct operation is in progress.
-	ULONG		 reconSize;
-	USHORT		 demoFail;				// flag for RAID failure demonstration
-	USHORT		 survivor;
-	USHORT		 failinprog;
-	struct timer_list	reconTimer;	
-	struct timer_list	timer;
-	UCHAR		*kBuffer;
-	dma_addr_t	 kBufferDma;
-	UCHAR		 reqSense;
-	UCHAR		 atapiCdb[16];
-	UCHAR		 atapiSpecial;
-	}	ADAPTER2220I, *PADAPTER2220I;
-
-#define HOSTDATA(host) ((PADAPTER2220I)&host->hostdata)
-
-#define	RECON_PHASE_READY		0x01
-#define	RECON_PHASE_COPY		0x02
-#define	RECON_PHASE_UPDATE		0x03
-#define	RECON_PHASE_LAST		0x04
-#define	RECON_PHASE_END			0x07	
-#define	RECON_PHASE_MARKING		0x80
-#define	RECON_PHASE_FAILOVER	0xFF
-
-static struct	Scsi_Host 	   *PsiHost[MAXADAPTER] = {NULL,};  // One for each adapter
-static			int				NumAdapters = 0;
-static			int				Installed = 0;
-static			SETUP			DaleSetup;
-static			DISK_MIRROR		DiskMirror[BIGD_MAXDRIVES];
-static			ULONG			ModeArray[] = {DALE_DATA_MODE2, DALE_DATA_MODE3, DALE_DATA_MODE4, DALE_DATA_MODE5};
-static			ULONG			ModeArray2[] = {BIGD_DATA_MODE2, BIGD_DATA_MODE3, BIGD_DATA_MODE4, BIGD_DATA_MODE5};
-
-static void ReconTimerExpiry (unsigned long data);
-
-/*******************************************************************************************************
- *	Name:			Alarm
- *
- *	Description:	Sound the for the given device
- *
- *	Parameters:		padapter - Pointer adapter data structure.
- *					device	 - Device number.
- *	
- *	Returns:		Nothing.
- *
- ******************************************************************************************************/
-static void Alarm (PADAPTER2220I padapter, UCHAR device)
-	{
-	UCHAR	zc;
-
-	if ( padapter->bigD )
-		{
-		zc = device | (FAIL_ANY | FAIL_AUDIBLE);
-		if ( padapter->failRegister & FAIL_ANY ) 
-			zc |= FAIL_MULTIPLE;
-		
-		padapter->failRegister = zc;
-		outb_p (~zc, padapter->regFail);
-		}
-	else
-		outb_p (0x3C | (1 << device), padapter->regFail);			// sound alarm and set fail light		
-	}
-/****************************************************************
- *	Name:	MuteAlarm	:LOCAL
- *
- *	Description:	Mute the audible alarm.
- *
- *	Parameters:		padapter - Pointer adapter data structure.
- *
- *	Returns:		TRUE if drive does not assert DRQ in time.
- *
- ****************************************************************/
-static void MuteAlarm (PADAPTER2220I padapter)
-	{
-	UCHAR	old;
-
-	if ( padapter->bigD )
-		{
-		padapter->failRegister &= ~FAIL_AUDIBLE;
-		outb_p (~padapter->failRegister, padapter->regFail);
-		}
-	else
-		{
-		old = (inb_p (padapter->regStatSel) >> 3) | (inb_p (padapter->regStatSel) & 0x83);
-		outb_p (old | 0x40, padapter->regFail);
-		}
-	}
-/****************************************************************
- *	Name:	WaitReady	:LOCAL
- *
- *	Description:	Wait for device ready.
- *
- *	Parameters:		padapter - Pointer adapter data structure.
- *
- *	Returns:		TRUE if drive does not assert DRQ in time.
- *
- ****************************************************************/
-static int WaitReady (PADAPTER2220I padapter)
-	{
-	ULONG	z;
-	UCHAR	status;
-
-	for ( z = 0;  z < (TIMEOUT_READY * 4);  z++ )
-		{
-		status = inb_p (padapter->regStatCmd);
-		if ( (status & (IDE_STATUS_DRDY | IDE_STATUS_BUSY)) == IDE_STATUS_DRDY )
-			return 0;
-		udelay (250);
-		}
-	return status;
-	}
-/****************************************************************
- *	Name:	WaitReadyReset	:LOCAL
- *
- *	Description:	Wait for device ready.
- *
- *	Parameters:		padapter - Pointer adapter data structure.
- *
- *	Returns:		TRUE if drive does not assert DRQ in time.
- *
- ****************************************************************/
-static int WaitReadyReset (PADAPTER2220I padapter)
-	{
-	ULONG	z;
-	UCHAR	status;
-
-	for ( z = 0;  z < (125 * 16);  z++ )				// wait up to 1/4 second
-		{
-		status = inb_p (padapter->regStatCmd);
-		if ( (status & (IDE_STATUS_DRDY | IDE_STATUS_BUSY)) == IDE_STATUS_DRDY )
-			{
-			DEB (printk ("\nPCI2220I:  Reset took %ld mSec to be ready", z / 8));
-			return 0;
-			}
-		udelay (125);
-		}
-	DEB (printk ("\nPCI2220I:  Reset took more than 2 Seconds to come ready, Disk Failure"));
-	return status;
-	}
-/****************************************************************
- *	Name:	WaitDrq	:LOCAL
- *
- *	Description:	Wait for device ready for data transfer.
- *
- *	Parameters:		padapter - Pointer adapter data structure.
- *
- *	Returns:		TRUE if drive does not assert DRQ in time.
- *
- ****************************************************************/
-static int WaitDrq (PADAPTER2220I padapter)
-	{
-	ULONG	z;
-	UCHAR	status;
-
-	for ( z = 0;  z < (TIMEOUT_DRQ * 4);  z++ )
-		{
-		status = inb_p (padapter->regStatCmd);
-		if ( status & IDE_STATUS_DRQ )
-			return 0;
-		udelay (250);
-		}
-	return status;
-	}
-/****************************************************************
- *	Name:	AtapiWaitReady	:LOCAL
- *
- *	Description:	Wait for device busy and DRQ to be cleared.
- *
- *	Parameters:		padapter - Pointer adapter data structure.
- *					msec	 - Number of milliseconds to wait.
- *
- *	Returns:		TRUE if drive does not clear busy in time.
- *
- ****************************************************************/
-static int AtapiWaitReady (PADAPTER2220I padapter, int msec)
-	{
-	int z;
-
-	for ( z = 0;  z < (msec * 16);  z++ )
-		{
-		if ( !(inb_p (padapter->regStatCmd) & (IDE_STATUS_BUSY | IDE_STATUS_DRQ)) )
-			return FALSE;
-		udelay (125);
-		}
-	return TRUE;
-	}
-/****************************************************************
- *	Name:	AtapiWaitDrq	:LOCAL
- *
- *	Description:	Wait for device ready for data transfer.
- *
- *	Parameters:		padapter - Pointer adapter data structure.
- *					msec	 - Number of milliseconds to wait.
- *
- *	Returns:		TRUE if drive does not assert DRQ in time.
- *
- ****************************************************************/
-static int AtapiWaitDrq (PADAPTER2220I padapter, int msec)
-	{
-	ULONG	z;
-
-	for ( z = 0;  z < (msec * 16);  z++ )
-		{
-		if ( inb_p (padapter->regStatCmd) & IDE_STATUS_DRQ )
-			return 0;
-		udelay (128);
-		}
-	return TRUE;
-	}
-/****************************************************************
- *	Name:	HardReset	:LOCAL
- *
- *	Description:	Wait for device ready for data transfer.
- *
- *	Parameters:		padapter - Pointer adapter data structure.
- *					pdev	 - Pointer to device.
- *					spigot	 - Spigot number.
- *
- *	Returns:		TRUE if drive does not assert DRQ in time.
- *
- ****************************************************************/
-static int HardReset (PADAPTER2220I padapter, POUR_DEVICE pdev, UCHAR spigot)
-	{
-	DEB (printk ("\npci2220i:RESET  spigot = %X  devices = %d, %d", spigot, pdev->deviceID[0], pdev->deviceID[1]));
-	mdelay (100);										// just wait 100 mSec to let drives flush	
-	SelectSpigot (padapter, spigot | SEL_IRQ_OFF);
-	
-	outb_p (0x0E, padapter->regAltStat);					// reset the suvivor
-	udelay (100);											// wait a little	
-	outb_p (0x08, padapter->regAltStat);					// clear the reset
-	udelay (100);
-
-	outb_p (0xA0, padapter->regLba24);						// select the master drive
-	if ( WaitReadyReset (padapter) )
-		{
-		DEB (printk ("\npci2220i: master not ready after reset"));
-		return TRUE;
-		}
-	outb_p (0xB0, padapter->regLba24);						// try the slave drive
-	if ( (inb_p (padapter->regStatCmd) & (IDE_STATUS_DRDY | IDE_STATUS_BUSY)) == IDE_STATUS_DRDY ) 
-		{
-		DEB (printk ("\nPCI2220I: initializing slave drive on spigot %X", spigot));
-		outb_p (SECTORSXFER, padapter->regSectCount);
-		WriteCommand (padapter, IDE_CMD_SET_MULTIPLE);	
-		if ( WaitReady (padapter) )
-			{
-			DEB (printk ("\npci2220i: slave not ready after set multiple"));
-			return TRUE;
-			}
-		}
-	
-	outb_p (0xA0, padapter->regLba24);				// select the drive
-	outb_p (SECTORSXFER, padapter->regSectCount);
-	WriteCommand (padapter, IDE_CMD_SET_MULTIPLE);	
-	if ( WaitReady (padapter) )
-		{
-		DEB (printk ("\npci2220i: master not ready after set multiple"));
-		return TRUE;
-		}
-	return FALSE;
-	}
-/****************************************************************
- *	Name:	AtapiReset	:LOCAL
- *
- *	Description:	Wait for device ready for data transfer.
- *
- *	Parameters:		padapter - Pointer adapter data structure.
- *					pdev	 - Pointer to device.
- *
- *	Returns:		TRUE if drive does not come ready.
- *
- ****************************************************************/
-static int AtapiReset (PADAPTER2220I padapter, POUR_DEVICE pdev)
-	{
-	SelectSpigot (padapter, pdev->spigot);
-	AtapiDevice (padapter, pdev->byte6);
-	AtapiCountLo (padapter, 0);
-	AtapiCountHi (padapter, 0);
-	WriteCommand (padapter, IDE_COMMAND_ATAPI_RESET);
-	udelay (125);
-	if ( AtapiWaitReady (padapter, 1000) )
-		return TRUE;
-	if ( inb_p (padapter->regStatCmd) || (inb_p (padapter->regLba8) != 0x14) || (inb_p (padapter->regLba16) != 0xEB) )
-		return TRUE;
-	return FALSE;
-	}
-/****************************************************************
- *	Name:	WalkScatGath	:LOCAL
- *
- *	Description:	Transfer data to/from scatter/gather buffers.
- *
- *	Parameters:		padapter - Pointer adapter data structure.
- *					datain   - TRUE if data read.
- *					length   - Number of bytes to transfer.
- *
- *	Returns:		Nothing.
- *
- ****************************************************************/
-static void WalkScatGath (PADAPTER2220I padapter, UCHAR datain, ULONG length)
-	{
-	ULONG	 count;
-	UCHAR	*buffer = padapter->kBuffer;
-
-	while ( length )
-		{
-		count = ( length > padapter->currentSgCount ) ? padapter->currentSgCount : length; 
-		
-		if ( datain )
-			memcpy (padapter->currentSgBuffer, buffer, count);
-		else
-			memcpy (buffer, padapter->currentSgBuffer, count);
-
-		padapter->currentSgCount -= count;
-		if ( !padapter->currentSgCount )
-			{
-			if ( padapter->nextSg < padapter->SCpnt->use_sg )
-				{
-				padapter->currentSgBuffer = ((struct scatterlist *)padapter->SCpnt->request_buffer)[padapter->nextSg].address;
-				padapter->currentSgCount = ((struct scatterlist *)padapter->SCpnt->request_buffer)[padapter->nextSg].length;
-				padapter->nextSg++;
-				}
-			}
-		else
-			padapter->currentSgBuffer += count;
-
-		length -= count;
-		buffer += count;
-		}
-	}
-/****************************************************************
- *	Name:	BusMaster	:LOCAL
- *
- *	Description:	Do a bus master I/O.
- *
- *	Parameters:		padapter - Pointer adapter data structure.
- *					datain	 - TRUE if data read.
- *					irq		 - TRUE if bus master interrupt expected.
- *
- *	Returns:		Nothing.
- *
- ****************************************************************/
-static void BusMaster (PADAPTER2220I padapter, UCHAR datain, UCHAR irq)
-	{
-	ULONG zl;
-	
-	zl = ( padapter->sectorCount > MAX_BUS_MASTER_BLOCKS ) ? MAX_BUS_MASTER_BLOCKS : padapter->sectorCount;
-	padapter->sectorCount -= zl;
-	zl *= (ULONG)BYTES_PER_SECTOR;
-
-	if ( datain )
-		{
-		padapter->readCount = zl;
-		outb_p (8, padapter->regDmaDesc);							// read operation
-		if ( padapter->bigD )
-			{
-			if ( irq && !padapter->sectorCount )
-				outb_p (0x0C, padapter->regDmaMode);				// interrupt on
-			else
-				outb_p (0x08, padapter->regDmaMode);				// no interrupt
-			}
-		else 
-			{
-			if ( irq && !padapter->sectorCount )
-				outb_p (0x05, padapter->regDmaMode);				// interrupt on
-			else
-				outb_p (0x01, padapter->regDmaMode);				// no interrupt
-			}
-		}
-	else
-		{
-		outb_p (0x00, padapter->regDmaDesc);						// write operation
-		if ( padapter->bigD )
-			outb_p (0x08, padapter->regDmaMode);					// no interrupt						
-		else
-			outb_p (0x01, padapter->regDmaMode);					// no interrupt
-		WalkScatGath (padapter, FALSE, zl);	
-		}
-	
-	outl (padapter->timingAddress, padapter->regDmaAddrLoc);
-	outl (padapter->kBufferDma, padapter->regDmaAddrPci);
-	outl (zl, padapter->regDmaCount);
-	outb_p (0x03, padapter->regDmaCmdStat);							// kick the DMA engine in gear
-	}
-/****************************************************************
- *	Name:	AtapiBusMaster	:LOCAL
- *
- *	Description:	Do a bus master I/O.
- *
- *	Parameters:		padapter - Pointer adapter data structure.
- *					datain	 - TRUE if data read.
- *					length	 - Number of bytes to transfer.
- *
- *	Returns:		Nothing.
- *
- ****************************************************************/
-static void AtapiBusMaster (PADAPTER2220I padapter, UCHAR datain, ULONG length)
-	{
-	outl (padapter->timingAddress, padapter->regDmaAddrLoc);
-	outl (padapter->kBufferDma, padapter->regDmaAddrPci);
-	outl (length, padapter->regDmaCount);
-	if ( datain )
-		{
-		if ( padapter->readCount )
-				WalkScatGath (padapter, TRUE, padapter->readCount);
-		outb_p (0x08, padapter->regDmaDesc);						// read operation
-		outb_p (0x08, padapter->regDmaMode);						// no interrupt
-		padapter->readCount = length;
-		}
-	else
-		{
-		outb_p (0x00, padapter->regDmaDesc);						// write operation
-		outb_p (0x08, padapter->regDmaMode);						// no interrupt						
-		if ( !padapter->atapiSpecial )
-			WalkScatGath (padapter, FALSE, length);	
-		}
-	outb_p (0x03, padapter->regDmaCmdStat);							// kick the DMA engine in gear
-	}
-/****************************************************************
- *	Name:	WriteData	:LOCAL
- *
- *	Description:	Write data to device.
- *
- *	Parameters:		padapter - Pointer adapter data structure.
- *
- *	Returns:		TRUE if drive does not assert DRQ in time.
- *
- ****************************************************************/
-static int WriteData (PADAPTER2220I padapter)
-	{
-	ULONG	zl;
-	
-	if ( !WaitDrq (padapter) )
-		{
-		if ( padapter->timingPIO )
-			{
-			zl = (padapter->sectorCount > MAX_BUS_MASTER_BLOCKS) ? MAX_BUS_MASTER_BLOCKS : padapter->sectorCount;
-			WalkScatGath (padapter, FALSE, zl * BYTES_PER_SECTOR);
-			outsw (padapter->regData, padapter->kBuffer, zl * (BYTES_PER_SECTOR / 2));
-			padapter->sectorCount -= zl;
-			}
-		else
-			BusMaster (padapter, 0, 0);
-		return 0;
-		}
-	padapter->cmd = 0;												// null out the command byte
-	return 1;
-	}
-/****************************************************************
- *	Name:	WriteDataBoth	:LOCAL
- *
- *	Description:	Write data to device.
- *
- *	Parameters:		padapter - Pointer to adapter structure.
- *					pdev	 - Pointer to device structure
- *
- *	Returns:		Index + 1 of drive not failed or zero for OK.
- *
- ****************************************************************/
-static int WriteDataBoth (PADAPTER2220I padapter, POUR_DEVICE pdev)
-	{
-	ULONG	zl;
-	UCHAR	status0, status1;
-
-	SelectSpigot (padapter, pdev->spigots[0]);
-	status0 = WaitDrq (padapter);
-	if ( !status0 )
-		{
-		SelectSpigot (padapter, pdev->spigots[1]);
-		status1 = WaitDrq (padapter);
-		if ( !status1 )
-			{
-			SelectSpigot (padapter, pdev->spigots[0] | pdev->spigots[1] | padapter->bigD);
-			if ( padapter->timingPIO )
-				{
-				zl = (padapter->sectorCount > MAX_BUS_MASTER_BLOCKS) ? MAX_BUS_MASTER_BLOCKS : padapter->sectorCount;
-				WalkScatGath (padapter, FALSE, zl * BYTES_PER_SECTOR);
-				outsw (padapter->regData, padapter->kBuffer, zl * (BYTES_PER_SECTOR / 2));
-				padapter->sectorCount -= zl;
-				}
-			else
-				BusMaster (padapter, 0, 0);
-			return 0;
-			}
-		}
-	padapter->cmd = 0;												// null out the command byte
-	if ( status0 )
-		return 2;
-	return 1;
-	}
-/****************************************************************
- *	Name:	IdeCmd	:LOCAL
- *
- *	Description:	Process an IDE command.
- *
- *	Parameters:		padapter - Pointer adapter data structure.
- *					pdev	 - Pointer to device.
- *
- *	Returns:		Zero if no error or status register contents on error.
- *
- ****************************************************************/
-static UCHAR IdeCmd (PADAPTER2220I padapter, POUR_DEVICE pdev)
-	{
-	UCHAR	status;
-
-	SelectSpigot (padapter, pdev->spigot | padapter->bigD);							// select the spigot
-	outb_p (pdev->byte6 | ((UCHAR *)(&padapter->startSector))[3], padapter->regLba24);			// select the drive
-	status = WaitReady (padapter);
-	if ( !status )
-		{
-		outb_p (padapter->sectorCount, padapter->regSectCount);
-		outb_p (((UCHAR *)(&padapter->startSector))[0], padapter->regLba0);
-		outb_p (((UCHAR *)(&padapter->startSector))[1], padapter->regLba8);
-		outb_p (((UCHAR *)(&padapter->startSector))[2], padapter->regLba16);
-		padapter->expectingIRQ = TRUE;
-		WriteCommand (padapter, padapter->cmd);
-		return 0;
-		}
-
-	padapter->cmd = 0;									// null out the command byte
-	return status;
-	}
-/****************************************************************
- *	Name:	IdeCmdBoth	:LOCAL
- *
- *	Description:	Process an IDE command to both drivers.
- *
- *	Parameters:		padapter - Pointer adapter data structure.
- *					pdev	 - Pointer to device structure
- *
- *	Returns:		Index + 1 of drive not failed or zero for OK.
- *
- ****************************************************************/
-static UCHAR IdeCmdBoth (PADAPTER2220I padapter, POUR_DEVICE pdev)
-	{
-	UCHAR	status0;
-	UCHAR	status1;
-
-	SelectSpigot (padapter, pdev->spigots[0] | pdev->spigots[1]);								// select the spigots
-	outb_p (padapter->pdev->byte6 | ((UCHAR *)(&padapter->startSector))[3], padapter->regLba24);// select the drive
-	SelectSpigot (padapter, pdev->spigots[0]);
-	status0 = WaitReady (padapter);
-	if ( !status0 )
-		{
-		SelectSpigot (padapter, pdev->spigots[1]);
-		status1 = WaitReady (padapter);
-		if ( !status1 )
-			{
-			SelectSpigot (padapter, pdev->spigots[0] | pdev->spigots[1] | padapter->bigD);
-			outb_p (padapter->sectorCount, padapter->regSectCount);
-			outb_p (((UCHAR *)(&padapter->startSector))[0], padapter->regLba0);
-			outb_p (((UCHAR *)(&padapter->startSector))[1], padapter->regLba8);
-			outb_p (((UCHAR *)(&padapter->startSector))[2], padapter->regLba16);
-			padapter->expectingIRQ = TRUE;
-			WriteCommand (padapter, padapter->cmd);
-			return 0;
-			}
-		}
-	padapter->cmd = 0;									// null out the command byte
-	if ( status0 )
-		return 2;
-	return 1;
-	}
-/****************************************************************
- *	Name:	OpDone	:LOCAL
- *
- *	Description:	Complete an operatoin done sequence.
- *
- *	Parameters:		padapter - Pointer to host data block.
- *					spigot	 - Spigot select code.
- *					device	 - Device byte code.
- *
- *	Returns:		Nothing.
- *
- ****************************************************************/
-static void OpDone (PADAPTER2220I padapter, ULONG result)
-	{
-	Scsi_Cmnd	   *SCpnt = padapter->SCpnt;
-	
-	if ( padapter->reconPhase )
-		{
-		padapter->reconPhase = 0;
-		if ( padapter->SCpnt )
-			{
-			Pci2220i_QueueCommand (SCpnt, SCpnt->scsi_done);
-			}
-		else
-			{
-			if ( padapter->reconOn )
-				{
-				ReconTimerExpiry ((unsigned long)padapter);
-				}
-			}
-		}
-	else
-		{
-		padapter->cmd = 0;
-		padapter->SCpnt = NULL;	
-		padapter->pdev = NULL;
-		SCpnt->result = result;
-		SCpnt->scsi_done (SCpnt);
-		if ( padapter->reconOn && !padapter->reconTimer.data )
-			{
-			padapter->reconTimer.expires = jiffies + (HZ / 4);	// start in 1/4 second
-			padapter->reconTimer.data = (unsigned long)padapter;
-			add_timer (&padapter->reconTimer);
-			}
-		}
-	}
-/****************************************************************
- *	Name:	InlineIdentify	:LOCAL
- *
- *	Description:	Do an intline inquiry on a drive.
- *
- *	Parameters:		padapter - Pointer to host data block.
- *					spigot	 - Spigot select code.
- *					device	 - Device byte code.
- *
- *	Returns:		Last addressable sector or zero if none.
- *
- ****************************************************************/
-static ULONG InlineIdentify (PADAPTER2220I padapter, UCHAR spigot, UCHAR device)
-	{
-	PIDENTIFY_DATA	pid = (PIDENTIFY_DATA)padapter->kBuffer;
-
-	SelectSpigot (padapter, spigot | SEL_IRQ_OFF);					// select the spigot
-	outb_p ((device << 4) | 0xA0, padapter->regLba24);				// select the drive
-	if ( WaitReady (padapter) )
-		return 0;
-	WriteCommand (padapter, IDE_COMMAND_IDENTIFY);	
-	if ( WaitDrq (padapter) )
-		return 0;
-	insw (padapter->regData, padapter->kBuffer, sizeof (IDENTIFY_DATA) >> 1);
-	return (pid->LBATotalSectors - 1);
-	}
-/****************************************************************
- *	Name:	AtapiIdentify	:LOCAL
- *
- *	Description:	Do an intline inquiry on a drive.
- *
- *	Parameters:		padapter - Pointer to host data block.
- *					pdev	 - Pointer to device table.
- *
- *	Returns:		TRUE on error.
- *
- ****************************************************************/
-static ULONG AtapiIdentify (PADAPTER2220I padapter, POUR_DEVICE pdev)
-	{
-	ATAPI_GENERAL_0		ag0;
-	USHORT				zs;
-	int					z;
-
-	AtapiDevice (padapter, pdev->byte6);	
-	WriteCommand (padapter, IDE_COMMAND_ATAPI_IDENTIFY);	
-	if ( AtapiWaitDrq (padapter, 3000) )
-		return TRUE;
-
-	*(USHORT *)&ag0 = inw_p (padapter->regData);
-	for ( z = 0;  z < 255;  z++ )
-		zs = inw_p (padapter->regData);
-
-	if ( ag0.ProtocolType == 2 )
-		{
-		if ( ag0.CmdDrqType == 1 )
-			pdev->cmdDrqInt = TRUE;
-		switch ( ag0.CmdPacketSize )
-			{
-			case 0:
-				pdev->packet = 6;
-				break;
-			case 1:
-				pdev->packet = 8;
-				break;
-			default:
-				pdev->packet = 6;
-				break;
-			}
-		return FALSE;
-		}
-	return TRUE;
-	}
-/****************************************************************
- *	Name:	Atapi2Scsi
- *
- *	Description:	Convert ATAPI data to SCSI data.
- *
- *	Parameters:		padapter - Pointer adapter data structure.
- *					SCpnt	 - Pointer to SCSI command structure.
- *
- *	Returns:		Nothing.
- *
- ****************************************************************/
-void Atapi2Scsi (PADAPTER2220I padapter, Scsi_Cmnd *SCpnt)
-	{
-	UCHAR	*buff = padapter->currentSgBuffer;
- 
-	switch ( SCpnt->cmnd[0] )
-		{
-		case SCSIOP_MODE_SENSE:
-			buff[0] = padapter->kBuffer[1];
-			buff[1] = padapter->kBuffer[2];
-			buff[2] = padapter->kBuffer[3];
-			buff[3] = padapter->kBuffer[7];
-			memcpy (&buff[4], &padapter->kBuffer[8], padapter->atapiCdb[8] - 8);
-			break;
-		case SCSIOP_INQUIRY:
-			padapter->kBuffer[2] = 2;
-			memcpy (buff, padapter->kBuffer, padapter->currentSgCount);
-			break;		
-		default:
-			if ( padapter->readCount )
-				WalkScatGath (padapter, TRUE, padapter->readCount);
-			break;
-		}
-	}
-/****************************************************************
- *	Name:	Scsi2Atapi
- *
- *	Description:	Convert SCSI packet command to Atapi packet command.
- *
- *	Parameters:		padapter - Pointer adapter data structure.
- *					SCpnt	 - Pointer to SCSI command structure.
- *
- *	Returns:		Nothing.
- *
- ****************************************************************/
-static void Scsi2Atapi (PADAPTER2220I padapter, Scsi_Cmnd *SCpnt)
-	{
-	UCHAR	*cdb = SCpnt->cmnd;
-	UCHAR	*buff = padapter->currentSgBuffer;
-
-	switch (cdb[0]) 
-		{
-		case SCSIOP_READ6:
-            padapter->atapiCdb[0] = SCSIOP_READ;
-			padapter->atapiCdb[1] = cdb[1] & 0xE0;
-            padapter->atapiCdb[3] = cdb[1] & 0x1F;
-			padapter->atapiCdb[4] = cdb[2];
-			padapter->atapiCdb[5] = cdb[3];
-			padapter->atapiCdb[8] = cdb[4];
-			padapter->atapiCdb[9] = cdb[5];
-			break;
-		case SCSIOP_WRITE6:
-            padapter->atapiCdb[0] = SCSIOP_WRITE;
-			padapter->atapiCdb[1] = cdb[1] & 0xE0;
-            padapter->atapiCdb[3] = cdb[1] & 0x1F;
-			padapter->atapiCdb[4] = cdb[2];
-			padapter->atapiCdb[5] = cdb[3];
-			padapter->atapiCdb[8] = cdb[4];
-			padapter->atapiCdb[9] = cdb[5];
-			break;
-        case SCSIOP_MODE_SENSE: 
-            padapter->atapiCdb[0] = SCSIOP_MODE_SENSE10;
-			padapter->atapiCdb[2] = cdb[2];
-			padapter->atapiCdb[8] = cdb[4] + 4;
-            break;
-
-        case SCSIOP_MODE_SELECT: 
-			padapter->atapiSpecial = TRUE;
-			padapter->atapiCdb[0] = SCSIOP_MODE_SELECT10;
-			padapter->atapiCdb[1] = cdb[1] | 0x10;
-			memcpy (padapter->kBuffer, buff, 4);
-			padapter->kBuffer[4] = padapter->kBuffer[5] = 0;
-			padapter->kBuffer[6] = padapter->kBuffer[7] = 0;
-			memcpy (&padapter->kBuffer[8], &buff[4], cdb[4] - 4);
-			padapter->atapiCdb[8] = cdb[4] + 4;
-			break;
-	    }
-	}
-/****************************************************************
- *	Name:	AtapiSendCdb
- *
- *	Description:	Send the CDB packet to the device.
- *
- *	Parameters:		padapter - Pointer adapter data structure.
- *					pdev	 - Pointer to device.
- *					cdb		 - Pointer to 16 byte SCSI cdb.
- *
- *	Returns:		Nothing.
- *
- ****************************************************************/
-static void AtapiSendCdb (PADAPTER2220I padapter, POUR_DEVICE pdev, CHAR *cdb)
-	{
-	DEB (printk ("\nPCI2242I: CDB: %X %X %X %X %X %X %X %X %X %X %X %X", cdb[0], cdb[1], cdb[2], cdb[3], cdb[4], cdb[5], cdb[6], cdb[7], cdb[8], cdb[9], cdb[10], cdb[11]));
-	outsw (padapter->regData, cdb, pdev->packet);
-	}
-/****************************************************************
- *	Name:	AtapiRequestSense
- *
- *	Description:	Send the CDB packet to the device.
- *
- *	Parameters:		padapter - Pointer adapter data structure.
- *					pdev	 - Pointer to device.
- *					SCpnt	 - Pointer to SCSI command structure.
- *					pass	 - If true then this is the second pass to send cdb.
- *
- *	Returns:		TRUE on error.
- *
- ****************************************************************/
-static int AtapiRequestSense (PADAPTER2220I padapter, POUR_DEVICE pdev, Scsi_Cmnd *SCpnt, UCHAR pass)
-	{
-	UCHAR	cdb[16] = {SCSIOP_REQUEST_SENSE,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0};		
-	
-	DEB (printk ("\nPCI2242I: AUTO REQUEST SENSE"));
-	cdb[4] = (UCHAR)(sizeof (SCpnt->sense_buffer));
-	if ( !pass )
-		{
-		padapter->reqSense = TRUE;
-	 	AtapiCountLo (padapter, cdb[4]);						
-		AtapiCountHi (padapter, 0);						
-		outb_p (0, padapter->regError);						
-		WriteCommand (padapter, IDE_COMMAND_ATAPI_PACKET);
-		if ( pdev->cmdDrqInt )
-			return FALSE;
-
-		if ( AtapiWaitDrq (padapter, 500) )
-			return TRUE;
-		}
-	AtapiSendCdb (padapter, pdev, cdb);	
-	return FALSE;
-	}
-/****************************************************************
- *	Name:	InlineReadSignature	:LOCAL
- *
- *	Description:	Do an inline read RAID sigature.
- *
- *	Parameters:		padapter - Pointer adapter data structure.
- *					pdev	 - Pointer to device.
- *					index	 - index of data to read.
- *
- *	Returns:		Zero if no error or status register contents on error.
- *
- ****************************************************************/
-static UCHAR InlineReadSignature (PADAPTER2220I padapter, POUR_DEVICE pdev, int index)
-	{
-	UCHAR	status;
-	ULONG	zl = pdev->lastsectorlba[index];
-
-	SelectSpigot (padapter, pdev->spigots[index] | SEL_IRQ_OFF);	// select the spigot without interrupts
-	outb_p (pdev->byte6 | ((UCHAR *)&zl)[3], padapter->regLba24);		
-	status = WaitReady (padapter);
-	if ( !status )
-		{
-		outb_p (((UCHAR *)&zl)[2], padapter->regLba16);
-		outb_p (((UCHAR *)&zl)[1], padapter->regLba8); 
-		outb_p (((UCHAR *)&zl)[0], padapter->regLba0);
-		outb_p (1, padapter->regSectCount);
-		WriteCommand (padapter, IDE_COMMAND_READ);
-		status = WaitDrq (padapter);
-		if ( !status )
-			{
-			insw (padapter->regData, padapter->kBuffer, BYTES_PER_SECTOR / 2);
-			((ULONG *)(&pdev->DiskMirror[index]))[0] = ((ULONG *)(&padapter->kBuffer[DISK_MIRROR_POSITION]))[0];
-			((ULONG *)(&pdev->DiskMirror[index]))[1] = ((ULONG *)(&padapter->kBuffer[DISK_MIRROR_POSITION]))[1];
-			// some drives assert DRQ before IRQ so let's make sure we clear the IRQ
-			WaitReady (padapter);
-			return 0;			
-			}
-		}
-	return status;
-	}
-/****************************************************************
- *	Name:	DecodeError	:LOCAL
- *
- *	Description:	Decode and process device errors.
- *
- *	Parameters:		padapter - Pointer to adapter data.
- *					status - Status register code.
- *
- *	Returns:		The driver status code.
- *
- ****************************************************************/
-static ULONG DecodeError (PADAPTER2220I	padapter, UCHAR status)
-	{
-	UCHAR			error;
-
-	padapter->expectingIRQ = 0;
-	if ( status & IDE_STATUS_WRITE_FAULT )
-		{
-		return DID_PARITY << 16;
-		}
-	if ( status & IDE_STATUS_BUSY )
-		return DID_BUS_BUSY << 16;
-
-	error = inb_p (padapter->regError);
-	DEB(printk ("\npci2220i error register: %x", error));
-	switch ( error )
-		{
-		case IDE_ERROR_AMNF:
-		case IDE_ERROR_TKONF:
-		case IDE_ERROR_ABRT:
-		case IDE_ERROR_IDFN:
-		case IDE_ERROR_UNC:
-		case IDE_ERROR_BBK:
-		default:
-			return DID_ERROR << 16;
-		}
-	return DID_ERROR << 16;
-	}
-/****************************************************************
- *	Name:	StartTimer	:LOCAL
- *
- *	Description:	Start the timer.
- *
- *	Parameters:		ipadapter - Pointer adapter data structure.
- *
- *	Returns:		Nothing.
- *
- ****************************************************************/
-static void StartTimer (PADAPTER2220I padapter)
-	{
-	padapter->timer.expires = jiffies + TIMEOUT_DATA;
-	add_timer (&padapter->timer);
-	}
-/****************************************************************
- *	Name:	WriteSignature	:LOCAL
- *
- *	Description:	Start the timer.
- *
- *	Parameters:		padapter - Pointer adapter data structure.
- *					pdev	 - Pointer to our device.
- *					spigot	 - Selected spigot.
- *					index	 - index of mirror signature on device.
- *
- *	Returns:		TRUE on any error.
- *
- ****************************************************************/
-static int WriteSignature (PADAPTER2220I padapter, POUR_DEVICE pdev, UCHAR spigot, int index)
-	{
-	ULONG	zl;
-
-	SelectSpigot (padapter, spigot);
-	zl = pdev->lastsectorlba[index];
-	outb_p (pdev->byte6 | ((UCHAR *)&zl)[3], padapter->regLba24);		
-	outb_p (((UCHAR *)&zl)[2], padapter->regLba16);
-	outb_p (((UCHAR *)&zl)[1], padapter->regLba8);
-	outb_p (((UCHAR *)&zl)[0], padapter->regLba0);
-	outb_p (1, padapter->regSectCount);
-
-	WriteCommand (padapter, IDE_COMMAND_WRITE);	
-	if ( WaitDrq (padapter) )
-		return TRUE;
-	StartTimer (padapter);	
-	padapter->expectingIRQ = TRUE;
-	
-	((ULONG *)(&padapter->kBuffer[DISK_MIRROR_POSITION]))[0] = ((ULONG *)(&pdev->DiskMirror[index]))[0];
-	((ULONG *)(&padapter->kBuffer[DISK_MIRROR_POSITION]))[1] = ((ULONG *)(&pdev->DiskMirror[index]))[1];
-	outsw (padapter->regData, padapter->kBuffer, BYTES_PER_SECTOR / 2);
-	return FALSE;
-	}
-/*******************************************************************************************************
- *	Name:			InitFailover
- *
- *	Description:	This is the beginning of the failover routine
- *
- *	Parameters:		SCpnt	 - Pointer to SCSI command structure.
- *					padapter - Pointer adapter data structure.
- *					pdev	 - Pointer to our device.
- *	
- *	Returns:		TRUE on error.
- *
- ******************************************************************************************************/
-static int InitFailover (PADAPTER2220I padapter, POUR_DEVICE pdev)
-	{
-	UCHAR	spigot;
-	
-	DEB (printk ("\npci2220i:  Initialize failover process - survivor = %d", pdev->deviceID[padapter->survivor]));
-	pdev->raid = FALSE;									//initializes system for non raid mode
-	pdev->reconOn = FALSE;
-	spigot = pdev->spigots[padapter->survivor];	
-
-	if ( pdev->DiskMirror[padapter->survivor].status & UCBF_REBUILD )
-		{
-		DEB (printk ("\n         failed, is survivor"));
-		return (TRUE); 
-		}
-
-	if ( HardReset (padapter, pdev, spigot) )
-		{
-		DEB (printk ("\n         failed, reset"));
-		return TRUE;
-		}
-
-	Alarm (padapter, pdev->deviceID[padapter->survivor ^ 1]);
-	pdev->DiskMirror[padapter->survivor].status = UCBF_MIRRORED | UCBF_SURVIVOR;	//clear present status
-	
-	if ( WriteSignature (padapter, pdev, spigot, padapter->survivor) )
-		{
-		DEB (printk ("\n         failed, write signature"));
-		return TRUE;
-		}
-	padapter->failinprog = TRUE;
-	return FALSE;
-	}
-/****************************************************************
- *	Name:	TimerExpiry	:LOCAL
- *
- *	Description:	Timer expiry routine.
- *
- *	Parameters:		data - Pointer adapter data structure.
- *
- *	Returns:		Nothing.
- *
- ****************************************************************/
-static void TimerExpiry (unsigned long data)
-	{
-	PADAPTER2220I	padapter = (PADAPTER2220I)data;
-	struct Scsi_Host *host = padapter->SCpnt->device->host;
-	POUR_DEVICE		pdev = padapter->pdev;
-	UCHAR			status = IDE_STATUS_BUSY;
-	UCHAR			temp, temp1;
-    unsigned long		flags;
-
-    /*
-     * Disable interrupts, if they aren't already disabled and acquire
-     * the I/O spinlock.
-     */
-    spin_lock_irqsave (host->host_lock, flags);
-	DEB (printk ("\nPCI2220I: Timeout expired "));
-
-	if ( padapter->failinprog )
-		{
-		DEB (printk ("in failover process"));
-		OpDone (padapter, DecodeError (padapter, inb_p (padapter->regStatCmd)));
-		goto timerExpiryDone;
-		}
-	
-	while ( padapter->reconPhase )
-		{
-		DEB (printk ("in recon phase %X", padapter->reconPhase));
-		switch ( padapter->reconPhase )
-			{
-			case RECON_PHASE_MARKING:
-			case RECON_PHASE_LAST:
-				padapter->survivor = ( pdev->spigot == pdev->spigots[0] ) ? 1 : 0;
-				DEB (printk ("\npci2220i: FAILURE 1"));
-				if ( InitFailover (padapter, pdev) )
-					OpDone (padapter, DID_ERROR << 16);
-				goto timerExpiryDone;
-			
-			case RECON_PHASE_READY:
-				OpDone (padapter, DID_ERROR << 16);
-				goto timerExpiryDone;
-
-			case RECON_PHASE_COPY:
-				padapter->survivor = ( pdev->spigot == pdev->spigots[0] ) ? 0 : 1;
-				DEB (printk ("\npci2220i: FAILURE 2"));
-				DEB (printk ("\n       spig/stat = %X", inb_p (padapter->regStatSel));
-				if ( InitFailover (padapter, pdev) )
-					OpDone (padapter, DID_ERROR << 16);
-				goto timerExpiryDone;
-
-			case RECON_PHASE_UPDATE:
-				padapter->survivor = ( pdev->spigot == pdev->spigots[0] ) ? 0 : 1;
-				DEB (printk ("\npci2220i: FAILURE 3")));
-				if ( InitFailover (padapter, pdev) )
-					OpDone (padapter, DID_ERROR << 16);
-				goto timerExpiryDone;
-
-			case RECON_PHASE_END:
-				padapter->survivor = ( pdev->spigot == pdev->spigots[0] ) ? 0 : 1;
-				DEB (printk ("\npci2220i: FAILURE 4"));
-				if ( InitFailover (padapter, pdev) )
-					OpDone (padapter, DID_ERROR << 16);
-				goto timerExpiryDone;
-			
-			default:
-				goto timerExpiryDone;
-			}
-		}
-	
-	while ( padapter->cmd )
-		{
-		outb_p (0x08, padapter->regDmaCmdStat);					// cancel interrupt from DMA engine
-		if ( pdev->raid )
-			{
-			if ( padapter->cmd == WRITE_CMD )
-				{
-				DEB (printk ("in RAID write operation"));
-				temp = ( pdev->spigot & (SEL_1 | SEL_2) ) ? SEL_1 : SEL_3;
-				if ( inb_p (padapter->regStatSel) & temp )
-					{
-					DEB (printk ("\npci2220i: Determined A OK"));
-					SelectSpigot (padapter, temp | SEL_IRQ_OFF); // Masking the interrupt during spigot select
-					temp = inb_p (padapter->regStatCmd);
-					}
-				else
-					temp = IDE_STATUS_BUSY;
-
-				temp1 = ( pdev->spigot & (SEL_1 | SEL_2) ) ? SEL_2 : SEL_4;
-				if ( inb (padapter->regStatSel) & temp1 )
-					{
-					DEB (printk ("\npci2220i: Determined B OK"));
-					SelectSpigot (padapter, temp1 | SEL_IRQ_OFF); // Masking the interrupt during spigot select
-					temp1 = inb_p (padapter->regStatCmd);
-					}
-				else
-					temp1 = IDE_STATUS_BUSY;
-			
-				if ( (temp & IDE_STATUS_BUSY) || (temp1 & IDE_STATUS_BUSY) )
-					{
-					DEB (printk ("\npci2220i: Status A: %X   B: %X", temp & 0xFF, temp1 & 0xFF));
-	 				if ( (temp & IDE_STATUS_BUSY) && (temp1 & IDE_STATUS_BUSY) ) 
-						{
-						status = temp;
-						break;
-						}		
-					else	
-						{
-						if ( temp & IDE_STATUS_BUSY )
-							padapter->survivor = 1;
-						else
-							padapter->survivor = 0;
-						if ( InitFailover (padapter, pdev) )
-							{
-							status = inb_p (padapter->regStatCmd);
-							break;
-							}
-						goto timerExpiryDone;
-						}
-					}
-				}
-			else
-				{
-				DEB (printk ("in RAID read operation"));
-				padapter->survivor = ( pdev->spigot == pdev->spigots[0] ) ? 0 : 1;
-				DEB (printk ("\npci2220i: FAILURE 6"));
-				if ( InitFailover (padapter, pdev) )
-					{
-					status = inb_p (padapter->regStatCmd);
-					break;
-					}
-				goto timerExpiryDone;
-				}
-			}
-		else
-			{
-			DEB (printk ("in I/O operation"));
-			status = inb_p (padapter->regStatCmd);
-			}
-		break;
-		}
-	
-	OpDone (padapter, DecodeError (padapter, status));
-
-timerExpiryDone:;
-    /*
-     * Release the I/O spinlock and restore the original flags
-     * which will enable interrupts if and only if they were
-     * enabled on entry.
-     */
-    spin_unlock_irqrestore (host->host_lock, flags);
-	}
-/****************************************************************
- *	Name:			SetReconstruct	:LOCAL
- *
- *	Description:	Set the reconstruct up.
- *
- *	Parameters:		pdev	- Pointer to device structure.
- *					index	- Mirror index number.
- *
- *	Returns:		Number of sectors on new disk required.
- *
- ****************************************************************/
-static LONG SetReconstruct (POUR_DEVICE pdev, int index)
-	{
-	pdev->DiskMirror[index].status = UCBF_MIRRORED;							// setup the flags
-	pdev->DiskMirror[index ^ 1].status = UCBF_MIRRORED | UCBF_REBUILD;
-	pdev->DiskMirror[index ^ 1].reconstructPoint = 0;						// start the reconstruct
-	pdev->reconCount = 1990;												// mark target drive early
-	return pdev->DiskMirror[index].reconstructPoint;
-	}
-/****************************************************************
- *	Name:	ReconTimerExpiry	:LOCAL
- *
- *	Description:	Reconstruct timer expiry routine.
- *
- *	Parameters:		data - Pointer adapter data structure.
- *
- *	Returns:		Nothing.
- *
- ****************************************************************/
-static void ReconTimerExpiry (unsigned long data)
-	{
-	PADAPTER2220I	padapter = (PADAPTER2220I)data;
-	struct Scsi_Host *host = padapter->SCpnt->device->host;
-	POUR_DEVICE		pdev;
-	ULONG			testsize = 0;
-	PIDENTIFY_DATA	pid;
-	USHORT			minmode;
-	ULONG			zl;
-	UCHAR			zc;
-	USHORT			z;
-    unsigned long	flags;
-
-    /*
-     * Disable interrupts, if they aren't already disabled and acquire
-     * the I/O spinlock.
-     */
-    spin_lock_irqsave(host->host_lock, flags);
-
-	if ( padapter->SCpnt )
-		goto reconTimerExpiry;
-
-	padapter->reconTimer.data = 0;
-	for ( z = padapter->devInReconIndex + 1;  z < BIGD_MAXDRIVES;  z++ )
-		{
-		if ( padapter->device[z].reconOn )
-			break;
-		}
-	if ( z < BIGD_MAXDRIVES )
-		pdev = &padapter->device[z];
-	else
-		{
-		for ( z = 0;  z < BIGD_MAXDRIVES;  z++ )
-			{
-			if ( padapter->device[z].reconOn )
-				break;
-			}
-		if ( z < BIGD_MAXDRIVES )
-			pdev = &padapter->device[z];
-		else
-			{
-			padapter->reconOn = FALSE;
-			goto reconTimerExpiry;
-			}
-		}
-
-	padapter->devInReconIndex = z;
-	pid = (PIDENTIFY_DATA)padapter->kBuffer;
-	padapter->pdev = pdev;
-	if ( pdev->reconIsStarting )
-		{
-		pdev->reconIsStarting = FALSE;
-		pdev->reconOn = FALSE;
-
-		while ( (pdev->DiskMirror[0].signature == SIGNATURE) && (pdev->DiskMirror[1].signature == SIGNATURE) &&
-			 (pdev->DiskMirror[0].pairIdentifier == (pdev->DiskMirror[1].pairIdentifier ^ 1)) )
-			{
-			if ( (pdev->DiskMirror[0].status & UCBF_MATCHED) && (pdev->DiskMirror[1].status & UCBF_MATCHED) )
-				break;
-
-			if ( pdev->DiskMirror[0].status & UCBF_SURVIVOR )				// is first drive survivor?
-				testsize = SetReconstruct (pdev, 0);
-			else
-				if ( pdev->DiskMirror[1].status & UCBF_SURVIVOR )			// is second drive survivor?
-					testsize = SetReconstruct (pdev, 1);
-
-			if ( (pdev->DiskMirror[0].status & UCBF_REBUILD) || (pdev->DiskMirror[1].status & UCBF_REBUILD) )
-				{
-				if ( pdev->DiskMirror[0].status & UCBF_REBUILD )
-					pdev->mirrorRecon = 0;
-				else
-					pdev->mirrorRecon = 1;
-				pdev->reconOn = TRUE;
-				}
-			break;
-			}
-
-		if ( !pdev->reconOn )
-			goto reconTimerExpiry;
-
-		if ( padapter->bigD )
-			{
-			padapter->failRegister = 0;
-			outb_p (~padapter->failRegister, padapter->regFail);
-			}
-		else
-			{
-			zc = ((inb_p (padapter->regStatSel) >> 3) | inb_p (padapter->regStatSel)) & 0x83;		// mute the alarm
-			outb_p (0xFF, padapter->regFail);
-			}
-
-		while ( 1 )
-			{
-			DEB (printk ("\npci2220i: hard reset issue"));
-			if ( HardReset (padapter, pdev, pdev->spigots[pdev->mirrorRecon]) )
-				{
-				DEB (printk ("\npci2220i: sub 1"));
-				break;
-				}
-
-			pdev->lastsectorlba[pdev->mirrorRecon] = InlineIdentify (padapter, pdev->spigots[pdev->mirrorRecon], pdev->deviceID[pdev->mirrorRecon] & 1);
-
-			if ( pdev->lastsectorlba[pdev->mirrorRecon] < testsize )
-				{
-				DEB (printk ("\npci2220i: sub 2 %ld %ld", pdev->lastsectorlba[pdev->mirrorRecon], testsize));
-				break;
-				}
-
-	        // test LBA and multiper sector transfer compatibility
-			if (!pid->SupportLBA || (pid->NumSectorsPerInt < SECTORSXFER) || !pid->Valid_64_70 )
-				{
-				DEB (printk ("\npci2220i: sub 3"));
-				break;
-				}
-
-	        // test PIO/bus matering mode compatibility
-			if ( (pid->MinPIOCycleWithoutFlow > 240) && !pid->SupportIORDYDisable && !padapter->timingPIO )
-				{
-				DEB (printk ("\npci2220i: sub 4"));
-				break;
-				}
-
-			if ( pid->MinPIOCycleWithoutFlow <= 120 )	// setup timing mode of drive
-				minmode = 5;
-			else
-				{
-				if ( pid->MinPIOCylceWithFlow <= 150 )
-					minmode = 4;
-				else
-					{
-					if ( pid->MinPIOCylceWithFlow <= 180 )
-						minmode = 3;
-					else
-						{
-						if ( pid->MinPIOCylceWithFlow <= 240 )
-							minmode = 2;
-						else
-							{
-							DEB (printk ("\npci2220i: sub 5"));
-							break;
-							}
-						}
-					}
-				}
-
-			if ( padapter->timingMode > minmode )									// set minimum timing mode
-				padapter->timingMode = minmode;
-			if ( padapter->timingMode >= 2 )
-				padapter->timingAddress	= ModeArray[padapter->timingMode - 2];
-			else
-				padapter->timingPIO = TRUE;
-
-			padapter->reconOn = TRUE;
-			break;
-			}
-
-		if ( !pdev->reconOn )
-			{		
-			padapter->survivor = pdev->mirrorRecon ^ 1;
-			padapter->reconPhase = RECON_PHASE_FAILOVER;
-			DEB (printk ("\npci2220i: FAILURE 7"));
-			InitFailover (padapter, pdev);
-			goto reconTimerExpiry;
-			}
-
-		pdev->raid = TRUE;
-	
-		if ( WriteSignature (padapter, pdev, pdev->spigot, pdev->mirrorRecon ^ 1) )
-			goto reconTimerExpiry;
-		padapter->reconPhase = RECON_PHASE_MARKING;
-		goto reconTimerExpiry;
-		}
-
-	//**********************************
-	// reconstruct copy starts here	
-	//**********************************
-	if ( pdev->reconCount++ > 2000 )
-		{
-		pdev->reconCount = 0;
-		if ( WriteSignature (padapter, pdev, pdev->spigots[pdev->mirrorRecon], pdev->mirrorRecon) )
-			{
-			padapter->survivor = pdev->mirrorRecon ^ 1;
-			padapter->reconPhase = RECON_PHASE_FAILOVER;
-			DEB (printk ("\npci2220i: FAILURE 8"));
-			InitFailover (padapter, pdev);
-			goto reconTimerExpiry;
-			}
-		padapter->reconPhase = RECON_PHASE_UPDATE;
-		goto reconTimerExpiry;
-		}
-
-	zl = pdev->DiskMirror[pdev->mirrorRecon].reconstructPoint;	
-	padapter->reconSize = pdev->DiskMirror[pdev->mirrorRecon ^ 1].reconstructPoint - zl;
-	if ( padapter->reconSize > MAX_BUS_MASTER_BLOCKS )
-		padapter->reconSize = MAX_BUS_MASTER_BLOCKS;
-
-	if ( padapter->reconSize )
-		{
-		SelectSpigot (padapter, pdev->spigots[0] | pdev->spigots[1]);	// select the spigots
-		outb_p (pdev->byte6 | ((UCHAR *)(&zl))[3], padapter->regLba24);	// select the drive
-		SelectSpigot (padapter, pdev->spigot);
-		if ( WaitReady (padapter) )
-			goto reconTimerExpiry;
-
-		SelectSpigot (padapter, pdev->spigots[pdev->mirrorRecon]);
-		if ( WaitReady (padapter) )
-			{
-			padapter->survivor = pdev->mirrorRecon ^ 1;
-			padapter->reconPhase = RECON_PHASE_FAILOVER;
-			DEB (printk ("\npci2220i: FAILURE 9"));
-			InitFailover (padapter, pdev);
-			goto reconTimerExpiry;
-			}
-	
-		SelectSpigot (padapter, pdev->spigots[0] | pdev->spigots[1]);
-		outb_p (padapter->reconSize & 0xFF, padapter->regSectCount);
-		outb_p (((UCHAR *)(&zl))[0], padapter->regLba0);
-		outb_p (((UCHAR *)(&zl))[1], padapter->regLba8);
-		outb_p (((UCHAR *)(&zl))[2], padapter->regLba16);
-		padapter->expectingIRQ = TRUE;
-		padapter->reconPhase = RECON_PHASE_READY;
-		SelectSpigot (padapter, pdev->spigots[pdev->mirrorRecon]);
-		WriteCommand (padapter, WRITE_CMD);
-		StartTimer (padapter);
-		SelectSpigot (padapter, pdev->spigot);
-		WriteCommand (padapter, READ_CMD);
-		goto reconTimerExpiry;
-		}
-
-	pdev->DiskMirror[pdev->mirrorRecon].status = UCBF_MIRRORED | UCBF_MATCHED;
-	pdev->DiskMirror[pdev->mirrorRecon ^ 1].status = UCBF_MIRRORED | UCBF_MATCHED;
-	if ( WriteSignature (padapter, pdev, pdev->spigot, pdev->mirrorRecon ^ 1) )
-		goto reconTimerExpiry;
-	padapter->reconPhase = RECON_PHASE_LAST;
-
-reconTimerExpiry:;
-    /*
-     * Release the I/O spinlock and restore the original flags
-     * which will enable interrupts if and only if they were
-     * enabled on entry.
-     */
-    spin_unlock_irqrestore(host->host_lock, flags);
-	}
-/****************************************************************
- *	Name:	Irq_Handler	:LOCAL
- *
- *	Description:	Interrupt handler.
- *
- *	Parameters:		irq		- Hardware IRQ number.
- *					dev_id	-
- *					regs	-
- *
- *	Returns:		TRUE if drive is not ready in time.
- *
- ****************************************************************/
-static irqreturn_t Irq_Handler (int irq, void *dev_id, struct pt_regs *regs)
-	{
-	struct Scsi_Host   *shost = NULL;	// Pointer to host data block
-	PADAPTER2220I		padapter;		// Pointer to adapter control structure
-	POUR_DEVICE			pdev;
-	Scsi_Cmnd		   *SCpnt;
-	UCHAR				status;
-	UCHAR				status1;
-	ATAPI_STATUS		statusa;
-	ATAPI_REASON		reasona;
-	ATAPI_ERROR			errora;
-	int					z;
-	ULONG				zl;
-    unsigned long		flags;
-    int handled = 0;
-
-//	DEB (printk ("\npci2220i received interrupt\n"));
-
-	for ( z = 0; z < NumAdapters;  z++ )								// scan for interrupt to process
-		{
-		if ( PsiHost[z]->irq == (UCHAR)(irq & 0xFF) )
-			{
-			if ( inw_p (HOSTDATA(PsiHost[z])->regIrqControl) & 0x8000 )
-				{
-				shost = PsiHost[z];
-				break;
-				}
-			}
-		}
-
-	if ( !shost )
-		{
-		DEB (printk ("\npci2220i: not my interrupt"));
-		goto out;
-		}
-
-	handled = 1;
-	spin_lock_irqsave(shost->host_lock, flags);
-	padapter = HOSTDATA(shost);
-	pdev = padapter->pdev;
-	SCpnt = padapter->SCpnt;
-	outb_p (0x08, padapter->regDmaCmdStat);									// cancel interrupt from DMA engine
-
-	if ( padapter->atapi && SCpnt )
-		{
-		*(char *)&statusa = inb_p (padapter->regStatCmd);						// read the device status
-		*(char *)&reasona = inb_p (padapter->regSectCount);						// read the device interrupt reason
-	
-		if ( !statusa.bsy )
-			{
-			if ( statusa.drq )													// test for transfer phase
-				{
-				if ( !reasona.cod )												// test for data phase
-					{
-					z = (ULONG)inb_p (padapter->regLba8) | (ULONG)(inb_p (padapter->regLba16) << 8);
-					if ( padapter->reqSense )
-						insw (padapter->regData, SCpnt->sense_buffer, z / 2);
-					else
-						AtapiBusMaster (padapter, reasona.io, z);
-					goto irq_return;
-					}
-				if ( reasona.cod && !reasona.io )								// test for command packet phase
-					{
-					if ( padapter->reqSense )
-						AtapiRequestSense (padapter, pdev, SCpnt, TRUE);
-					else
-						AtapiSendCdb (padapter, pdev, padapter->atapiCdb);
-					goto irq_return;
-					}
-				}
-			else
-				{
-				if ( reasona.io && statusa.drdy )								// test for status phase
-					{
-					Atapi2Scsi (padapter, SCpnt);
-					if ( statusa.check )
-						{
-						*(UCHAR *)&errora = inb_p (padapter->regError);			// read the device error
-						if ( errora.senseKey )
-							{
-							if ( padapter->reqSense || AtapiRequestSense (padapter, pdev, SCpnt, FALSE) )
-								OpDone (padapter, DID_ERROR << 16);
-							}
-						else
-							{
-							if ( errora.ili || errora.abort )
-								OpDone (padapter, DID_ERROR << 16);
-							else
-								OpDone (padapter, DID_OK << 16);	
-							}
-						}
-					else
-						if ( padapter->reqSense )
-							{
-							DEB (printk ("PCI2242I: Sense codes - %X %X %X ", ((UCHAR *)SCpnt->sense_buffer)[0], ((UCHAR *)SCpnt->sense_buffer)[12], ((UCHAR *)SCpnt->sense_buffer)[13]));
-							OpDone (padapter, (DRIVER_SENSE << 24) | (DID_OK << 16) | 2);
-							}
-						else
-							OpDone (padapter, DID_OK << 16);	
-					}
-				}
-			}		
-		goto irq_return;
-		}
-	
-	if ( !padapter->expectingIRQ || !(SCpnt || padapter->reconPhase) )
-		{
-		DEB(printk ("\npci2220i Unsolicited interrupt\n"));
-		STOP_HERE ();
-		goto irq_return;
-		}
-	padapter->expectingIRQ = 0;
-
-	if ( padapter->failinprog )
-		{
-		DEB (printk ("\npci2220i interrupt failover complete"));
-		padapter->failinprog = FALSE;
-		status = inb_p (padapter->regStatCmd);								// read the device status
-		if ( status & (IDE_STATUS_ERROR | IDE_STATUS_WRITE_FAULT) )
-			{
-			DEB (printk ("\npci2220i: interrupt failover error from drive %X", status));
-			padapter->cmd = 0;
-			}
-		else
-			{
-			DEB (printk ("\npci2220i: restarting failed opertation."));
-			pdev->spigot = (padapter->survivor) ? pdev->spigots[1] : pdev->spigots[0];
-			del_timer (&padapter->timer);
-			if ( padapter->reconPhase )
-				OpDone (padapter, DID_OK << 16);
-			else
-				Pci2220i_QueueCommand (SCpnt, SCpnt->scsi_done);
-			goto irq_return;		
-			}
-		}
-
-	if ( padapter->reconPhase )
-		{
-		switch ( padapter->reconPhase )
-			{
-			case RECON_PHASE_MARKING:
-			case RECON_PHASE_LAST:
-				status = inb_p (padapter->regStatCmd);						// read the device status
-				del_timer (&padapter->timer);
-				if ( padapter->reconPhase == RECON_PHASE_LAST )
-					{
-					if ( status & (IDE_STATUS_ERROR | IDE_STATUS_WRITE_FAULT) )
-						{
-						padapter->survivor = ( pdev->spigot == pdev->spigots[0] ) ? 1 : 0;
-						DEB (printk ("\npci2220i: FAILURE 10"));
-						if ( InitFailover (padapter, pdev) )
-							OpDone (padapter, DecodeError (padapter, status));
-						goto irq_return;
-						}
-					if ( WriteSignature (padapter, pdev, pdev->spigots[pdev->mirrorRecon], pdev->mirrorRecon) )
-						{
-						padapter->survivor = ( pdev->spigot == pdev->spigots[0] ) ? 0 : 1;
-						DEB (printk ("\npci2220i: FAILURE 11"));
-						if ( InitFailover (padapter, pdev) )
-							OpDone (padapter, DecodeError (padapter, status));
-						goto irq_return;
-						}
-					padapter->reconPhase = RECON_PHASE_END;	
-					goto irq_return;
-					}
-				OpDone (padapter, DID_OK << 16);
-				goto irq_return;
-
-			case RECON_PHASE_READY:
-				status = inb_p (padapter->regStatCmd);						// read the device status
-				if ( status & (IDE_STATUS_ERROR | IDE_STATUS_WRITE_FAULT) )
-					{
-					del_timer (&padapter->timer);
-					OpDone (padapter, DecodeError (padapter, status));
-					goto irq_return;
-					}
-				SelectSpigot (padapter, pdev->spigots[pdev->mirrorRecon]);
-				if ( WaitDrq (padapter) )
-					{
-					del_timer (&padapter->timer);
-					padapter->survivor = ( pdev->spigot == pdev->spigots[0] ) ? 0 : 1;
-					DEB (printk ("\npci2220i: FAILURE 12"));
-					if ( InitFailover (padapter, pdev) )
-						OpDone (padapter, DecodeError (padapter, status));
-					goto irq_return;
-					}
-				SelectSpigot (padapter, pdev->spigot | SEL_COPY | padapter->bigD);
-				padapter->reconPhase = RECON_PHASE_COPY;
-				padapter->expectingIRQ = TRUE;
-				if ( padapter->timingPIO )
-					{
-					insw (padapter->regData, padapter->kBuffer, padapter->reconSize * (BYTES_PER_SECTOR / 2));
-					}
-				else
-					{
-					if ( (padapter->timingMode > 3) )
-						{
-						if ( padapter->bigD )
-							outl (BIGD_DATA_MODE3, padapter->regDmaAddrLoc);
-						else
-							outl (DALE_DATA_MODE3, padapter->regDmaAddrLoc);
-						}
-					else
-						outl (padapter->timingAddress, padapter->regDmaAddrLoc);
-					outl (padapter->kBufferDma, padapter->regDmaAddrPci);
-					outl (padapter->reconSize * BYTES_PER_SECTOR, padapter->regDmaCount);
-					outb_p (8, padapter->regDmaDesc);						// read operation
-					if ( padapter->bigD )
-						outb_p (8, padapter->regDmaMode);					// no interrupt
-					else
-						outb_p (1, padapter->regDmaMode);					// no interrupt
-					outb_p (0x03, padapter->regDmaCmdStat);					// kick the DMA engine in gear
-					}
-				goto irq_return;
-
-			case RECON_PHASE_COPY:
-				pdev->DiskMirror[pdev->mirrorRecon].reconstructPoint += padapter->reconSize;
-
-			case RECON_PHASE_UPDATE:
-				SelectSpigot (padapter, pdev->spigots[pdev->mirrorRecon] | SEL_IRQ_OFF);
-				status = inb_p (padapter->regStatCmd);						// read the device status
-				del_timer (&padapter->timer);
-				if ( status & (IDE_STATUS_ERROR | IDE_STATUS_WRITE_FAULT) )
-					{
-					padapter->survivor = ( pdev->spigot == pdev->spigots[0] ) ? 0 : 1;
-					DEB (printk ("\npci2220i: FAILURE 13"));
-					DEB (printk ("\n  status register = %X   error = %X", status, inb_p (padapter->regError)));
-					if ( InitFailover (padapter, pdev) )
-						OpDone (padapter, DecodeError (padapter, status));
-					goto irq_return;
-					}
-				OpDone (padapter, DID_OK << 16);
-				goto irq_return;
-
-			case RECON_PHASE_END:
-				status = inb_p (padapter->regStatCmd);						// read the device status
-				del_timer (&padapter->timer);
-				if ( status & (IDE_STATUS_ERROR | IDE_STATUS_WRITE_FAULT) )
-					{
-					padapter->survivor = ( pdev->spigot == pdev->spigots[0] ) ? 0 : 1;
-					DEB (printk ("\npci2220i: FAILURE 14"));
-					if ( InitFailover (padapter, pdev) )
-						OpDone (padapter, DecodeError (padapter, status));
-					goto irq_return;
-					}
-				pdev->reconOn = 0;
-				if ( padapter->bigD )
-					{
-					for ( z = 0;  z < padapter->numberOfDrives;  z++ )
-						{
-						if ( padapter->device[z].DiskMirror[0].status & UCBF_SURVIVOR )
-							{
-							Alarm (padapter, padapter->device[z].deviceID[0] ^ 2);
-							MuteAlarm (padapter);
-							}
-						if ( padapter->device[z].DiskMirror[1].status & UCBF_SURVIVOR )
-							{
-							Alarm (padapter, padapter->device[z].deviceID[1] ^ 2);
-							MuteAlarm (padapter);
-							}
-						}
-					}
-				OpDone (padapter, DID_OK << 16);
-				goto irq_return;
-
-			default:
-				goto irq_return;
-			}
-		}
-		
-	switch ( padapter->cmd )												// decide how to handle the interrupt
-		{
-		case READ_CMD:
-			if ( padapter->sectorCount )
-				{
-				status = inb_p (padapter->regStatCmd);						// read the device status
-				if ( status & (IDE_STATUS_ERROR | IDE_STATUS_WRITE_FAULT) )
-					{
-					if ( pdev->raid )
-						{
-						padapter->survivor = ( pdev->spigot == pdev->spigots[0] ) ? 1 : 0;
-						del_timer (&padapter->timer);
-						DEB (printk ("\npci2220i: FAILURE 15"));
-						if ( !InitFailover (padapter, pdev) )
-							goto irq_return;
-						}
-					break;	
-					}
-				if ( padapter->timingPIO )
-					{
-					insw (padapter->regData, padapter->kBuffer, padapter->readCount / 2);
-					padapter->sectorCount -= padapter->readCount / BYTES_PER_SECTOR;
-					WalkScatGath (padapter, TRUE, padapter->readCount);
-					if ( !padapter->sectorCount )
-						{
-						status = 0;
-						break;
-						}
-					}
-				else
-					{
-					if ( padapter->readCount )
-						WalkScatGath (padapter, TRUE, padapter->readCount);
-					BusMaster (padapter, 1, 1);
-					}
-				padapter->expectingIRQ = TRUE;
-				goto irq_return;
-				}
-			if ( padapter->readCount && !padapter->timingPIO )
-				WalkScatGath (padapter, TRUE, padapter->readCount);
-			status = 0;
-			break;
-
-		case WRITE_CMD:
-			if ( pdev->raid )
-				{
-				SelectSpigot (padapter, pdev->spigots[0] | SEL_IRQ_OFF);				
-				status = inb_p (padapter->regStatCmd);								// read the device status
-				SelectSpigot (padapter, pdev->spigots[1] | SEL_IRQ_OFF);				
-				status1 = inb_p (padapter->regStatCmd);								// read the device status
-				}
-			else
-				SelectSpigot (padapter, pdev->spigot | SEL_IRQ_OFF);				
-				status = inb_p (padapter->regStatCmd);								// read the device status
-				status1 = 0;
-		
-			if ( status & (IDE_STATUS_ERROR | IDE_STATUS_WRITE_FAULT) )
-				{	
-				if ( pdev->raid && !(status1 & (IDE_STATUS_ERROR | IDE_STATUS_WRITE_FAULT)) )
-					{
-					padapter->survivor = 1;
-					del_timer (&padapter->timer);
-					SelectSpigot (padapter, pdev->spigot | SEL_IRQ_OFF);
-					DEB (printk ("\npci2220i: FAILURE 16  status = %X  error = %X", status, inb_p (padapter->regError)));
-					if ( !InitFailover (padapter, pdev) )
-						goto irq_return;
-					}
-				break;
-				}
-			if ( pdev->raid )
-				{
-				if ( status1 & (IDE_STATUS_ERROR | IDE_STATUS_WRITE_FAULT) )
-					{	
-					padapter->survivor = 0;
-					del_timer (&padapter->timer);
-					DEB (printk ("\npci2220i: FAILURE 17  status = %X  error = %X", status1, inb_p (padapter->regError)));
-					if ( !InitFailover (padapter, pdev) )
-						goto irq_return;
-					status = status1;
-					break;
-					}
-				if ( padapter->sectorCount )
-					{
-					status = WriteDataBoth (padapter, pdev);
-					if ( status )
-						{
-						padapter->survivor = status >> 1;
-						del_timer (&padapter->timer);
-						DEB (printk ("\npci2220i: FAILURE 18"));
-						if ( !InitFailover (padapter, pdev) )
-							goto irq_return;
-						SelectSpigot (padapter, pdev->spigots[status] | SEL_IRQ_OFF);				
-						status = inb_p (padapter->regStatCmd);								// read the device status
-						break;
-						}
-					padapter->expectingIRQ = TRUE;
-					goto irq_return;
-					}
-				status = 0;
-				break;
-				}
-			if ( padapter->sectorCount )	
-				{	
-				SelectSpigot (padapter, pdev->spigot | padapter->bigD);
-				status = WriteData (padapter);
-				if ( status )
-					break;
-				padapter->expectingIRQ = TRUE;
-				goto irq_return;
-				}
-			status = 0;
-			break;
-
-		case IDE_COMMAND_IDENTIFY:
-			{
-			PINQUIRYDATA	pinquiryData  = SCpnt->request_buffer;
-			PIDENTIFY_DATA	pid = (PIDENTIFY_DATA)padapter->kBuffer;
-
-			status = inb_p (padapter->regStatCmd);
-			if ( status & IDE_STATUS_DRQ )
-				{
-				insw (padapter->regData, pid, sizeof (IDENTIFY_DATA) >> 1);
-
-				memset (pinquiryData, 0, SCpnt->request_bufflen);		// Zero INQUIRY data structure.
-				pinquiryData->DeviceType = 0;
-				pinquiryData->Versions = 2;
-				pinquiryData->AdditionalLength = 35 - 4;
-
-				// Fill in vendor identification fields.
-				for ( z = 0;  z < 20;  z += 2 )
-					{
-					pinquiryData->VendorId[z]	  = ((UCHAR *)pid->ModelNumber)[z + 1];
-					pinquiryData->VendorId[z + 1] = ((UCHAR *)pid->ModelNumber)[z];
-					}
-
-				// Initialize unused portion of product id.
-				for ( z = 0;  z < 4;  z++ )
-					pinquiryData->ProductId[12 + z] = ' ';
-
-				// Move firmware revision from IDENTIFY data to
-				// product revision in INQUIRY data.
-				for ( z = 0;  z < 4;  z += 2 )
-					{
-					pinquiryData->ProductRevisionLevel[z]	 = ((UCHAR *)pid->FirmwareRevision)[z + 1];
-					pinquiryData->ProductRevisionLevel[z + 1] = ((UCHAR *)pid->FirmwareRevision)[z];
-					}
-				if ( pdev == padapter->device )
-					*((USHORT *)(&pinquiryData->VendorSpecific)) = DEVICE_DALE_1;
-				
-				status = 0;
-				}
-			break;
-			}
-
-		default:
-			status = 0;
-			break;
-		}
-
-	del_timer (&padapter->timer);
-	if ( status )
-		{
-		DEB (printk ("\npci2220i Interrupt handler return error"));
-		zl = DecodeError (padapter, status);
-		}
-	else
-		zl = DID_OK << 16;
-
-	OpDone (padapter, zl);
-irq_return:
-    spin_unlock_irqrestore(shost->host_lock, flags);
-out:
-	return IRQ_RETVAL(handled);
-}
-
-/****************************************************************
- *	Name:	Pci2220i_QueueCommand
- *
- *	Description:	Process a queued command from the SCSI manager.
- *
- *	Parameters:		SCpnt - Pointer to SCSI command structure.
- *					done  - Pointer to done function to call.
- *
- *	Returns:		Status code.
- *
- ****************************************************************/
-int Pci2220i_QueueCommand (Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
-	{
-	UCHAR		   *cdb = (UCHAR *)SCpnt->cmnd;					// Pointer to SCSI CDB
-	PADAPTER2220I	padapter = HOSTDATA(SCpnt->device->host);			// Pointer to adapter control structure
-	POUR_DEVICE		pdev	 = &padapter->device[SCpnt->device->id];// Pointer to device information
-	UCHAR			rc;											// command return code
-	int				z; 
-	PDEVICE_RAID1	pdr;
-
-	SCpnt->scsi_done = done;
-	padapter->SCpnt = SCpnt;  									// Save this command data
-	padapter->readCount = 0;
-
-	if ( SCpnt->use_sg )
-		{
-		padapter->currentSgBuffer = ((struct scatterlist *)SCpnt->request_buffer)[0].address;
-		padapter->currentSgCount = ((struct scatterlist *)SCpnt->request_buffer)[0].length;
-		}
-	else
-		{
-		padapter->currentSgBuffer = SCpnt->request_buffer;
-		padapter->currentSgCount = SCpnt->request_bufflen;
-		}
-	padapter->nextSg = 1;
-
-	if ( !done )
-		{
-		printk("pci2220i_queuecommand: %02X: done can't be NULL\n", *cdb);
-		return 0;
-		}
-	
-	if ( padapter->atapi )
-		{
-		UCHAR			zlo, zhi;
-
-		DEB (printk ("\nPCI2242I: ID %d, LUN %d opcode %X ", SCpnt->device->id, SCpnt->device->lun, *cdb));
-		padapter->pdev = pdev;
-		if ( !pdev->byte6 || SCpnt->device->lun )
-			{
-			OpDone (padapter, DID_BAD_TARGET << 16);
-			return 0;
-			}
-	
-		padapter->atapiSpecial = FALSE;
-		padapter->reqSense = FALSE;
-		memset (padapter->atapiCdb, 0, 16);
-		SelectSpigot (padapter, pdev->spigot);									// select the spigot
-		AtapiDevice (padapter, pdev->byte6);									// select the drive
-		if ( AtapiWaitReady (padapter, 100) )
-			{
-			OpDone (padapter, DID_NO_CONNECT << 16);
-			return 0;
-			}
-
-		switch ( cdb[0] ) 
-			{
-			case SCSIOP_MODE_SENSE:
-			case SCSIOP_MODE_SELECT:
-				Scsi2Atapi (padapter, SCpnt);
-				z = SCpnt->request_bufflen + 4;
-				break;
-			case SCSIOP_READ6:
-			case SCSIOP_WRITE6:
-				Scsi2Atapi (padapter, SCpnt);
-				z = SCpnt->request_bufflen;
-				break;
-			default:
-				memcpy (padapter->atapiCdb, cdb, SCpnt->cmd_len);
-				z = SCpnt->request_bufflen;
-				break;
-			}
-		if ( z > ATAPI_TRANSFER )
-			z = ATAPI_TRANSFER;
-	    zlo = (UCHAR)(z & 0xFF);
-	    zhi = (UCHAR)(z >> 8);
-
-	 	AtapiCountLo (padapter, zlo);						
-	   	AtapiCountHi (padapter, zhi);						
-	   	outb_p (0, padapter->regError);						
-		WriteCommand (padapter, IDE_COMMAND_ATAPI_PACKET);
-		if ( pdev->cmdDrqInt )
-			return 0;
-
-		if ( AtapiWaitDrq (padapter, 500) )
-			{
-			OpDone (padapter, DID_ERROR << 16);
-			return 0;
-			}
-		AtapiSendCdb (padapter, pdev, padapter->atapiCdb);	
-		return 0;
-		}
-	
-	if ( padapter->reconPhase )
-		return 0;
-	if ( padapter->reconTimer.data )
-		{
-		del_timer (&padapter->reconTimer);
-		padapter->reconTimer.data = 0;
-		}
-		
-	if ( (SCpnt->device->id >= padapter->numberOfDrives) || SCpnt->device->lun )
-		{
-		OpDone (padapter, DID_BAD_TARGET << 16);
-		return 0;
-		}
-	
-	switch ( *cdb )
-		{
-		case SCSIOP_INQUIRY:   					// inquiry CDB
-			{
-			if ( cdb[2] == SC_MY_RAID )
-				{
-				switch ( cdb[3] ) 
-					{
-					case MY_SCSI_REBUILD:
-						for ( z = 0;  z < padapter->numberOfDrives;  z++ )
-							{
-							pdev = &padapter->device[z];
-							if ( ((pdev->DiskMirror[0].status & UCBF_SURVIVOR) && (pdev->DiskMirror[1].status & UCBF_MIRRORED)) ||
-								 ((pdev->DiskMirror[1].status & UCBF_SURVIVOR) && (pdev->DiskMirror[0].status & UCBF_MIRRORED)) )
-								{
-								padapter->reconOn = pdev->reconOn = pdev->reconIsStarting = TRUE;
-								}
-							}
-						OpDone (padapter, DID_OK << 16);
-						break;
-					case MY_SCSI_ALARMMUTE:
-						MuteAlarm (padapter);
-						OpDone (padapter, DID_OK << 16);
-						break;
-					case MY_SCSI_DEMOFAIL:
-						padapter->demoFail = TRUE;				
-						OpDone (padapter, DID_OK << 16);
-						break;
-					default:
-						z = cdb[5];				// get index
-						pdr = (PDEVICE_RAID1)SCpnt->request_buffer;
-						if ( padapter->raidData[z] )
-							{
-							memcpy (&pdr->DiskRaid1, padapter->raidData[z], sizeof (DISK_MIRROR));
-							if ( padapter->raidData[z]->reconstructPoint > padapter->raidData[z ^ 2]->reconstructPoint )
-								pdr->TotalSectors = padapter->raidData[z]->reconstructPoint;
-							else
-								pdr->TotalSectors = padapter->raidData[z ^ 2]->reconstructPoint;
-							}
-						else
-							memset (pdr, 0, sizeof (DEVICE_RAID1));
-						OpDone (padapter, DID_OK << 16);
-						break;
-					}	
-				return 0;
-				}
-			padapter->cmd = IDE_COMMAND_IDENTIFY;
-			break;
-			}
-
-		case SCSIOP_TEST_UNIT_READY:			// test unit ready CDB
-			OpDone (padapter, DID_OK << 16);
-			return 0;
-		case SCSIOP_READ_CAPACITY:			  	// read capctiy CDB
-			{
-			PREAD_CAPACITY_DATA	pdata = (PREAD_CAPACITY_DATA)SCpnt->request_buffer;
-
-			pdata->blksiz = 0x20000;
-			XANY2SCSI ((UCHAR *)&pdata->blks, pdev->blocks);
-			OpDone (padapter, DID_OK << 16);
-			return 0;
-			}
-		case SCSIOP_VERIFY:						// verify CDB
-			padapter->startSector = XSCSI2LONG (&cdb[2]);
-			padapter->sectorCount = (UCHAR)((USHORT)cdb[8] | ((USHORT)cdb[7] << 8));
-			padapter->cmd = IDE_COMMAND_VERIFY;
-			break;
-		case SCSIOP_READ:						// read10 CDB
-			padapter->startSector = XSCSI2LONG (&cdb[2]);
-			padapter->sectorCount = (USHORT)cdb[8] | ((USHORT)cdb[7] << 8);
-			padapter->cmd = READ_CMD;
-			break;
-		case SCSIOP_READ6:						// read6  CDB
-			padapter->startSector = SCSI2LONG (&cdb[1]);
-			padapter->sectorCount = cdb[4];
-			padapter->cmd = READ_CMD;
-			break;
-		case SCSIOP_WRITE:						// write10 CDB
-			padapter->startSector = XSCSI2LONG (&cdb[2]);
-			padapter->sectorCount = (USHORT)cdb[8] | ((USHORT)cdb[7] << 8);
-			padapter->cmd = WRITE_CMD;
-			break;
-		case SCSIOP_WRITE6:						// write6  CDB
-			padapter->startSector = SCSI2LONG (&cdb[1]);
-			padapter->sectorCount = cdb[4];
-			padapter->cmd = WRITE_CMD;
-			break;
-		default:
-			DEB (printk ("pci2220i_queuecommand: Unsupported command %02X\n", *cdb));
-			OpDone (padapter, DID_ERROR << 16);
-			return 0;
-		}
-
-	if ( padapter->reconPhase )
-		return 0;
-	
-	padapter->pdev = pdev;
-
-	while ( padapter->demoFail )
-		{
-		pdev = padapter->pdev = &padapter->device[0];
-		padapter->demoFail = FALSE;
-		if ( !pdev->raid || 
-			 (pdev->DiskMirror[0].status & UCBF_SURVIVOR) || 
-			 (pdev->DiskMirror[1].status & UCBF_SURVIVOR) )
-			{
-			break;
-			}
-		if ( pdev->DiskMirror[0].status & UCBF_REBUILD )
-			padapter->survivor = 1;
-		else
-			padapter->survivor = 0;
-				DEB (printk ("\npci2220i: FAILURE 19"));
-		if ( InitFailover (padapter, pdev) )
-			break;
-		return 0;
-		}
-
-	StartTimer (padapter);
-	if ( pdev->raid && (padapter->cmd == WRITE_CMD) )
-		{
-		rc = IdeCmdBoth (padapter, pdev);
-		if ( !rc )
-			rc = WriteDataBoth (padapter, pdev);
-		if ( rc )
-			{
-			del_timer (&padapter->timer);
-			padapter->expectingIRQ = 0;
-			padapter->survivor = rc >> 1;
-				DEB (printk ("\npci2220i: FAILURE 20"));
-			if ( InitFailover (padapter, pdev) )
-				{
-				OpDone (padapter, DID_ERROR << 16);
-				return 0;
-				}
-			}
-		}
-	else
-		{
-		rc = IdeCmd (padapter, pdev);
-		if ( (padapter->cmd == WRITE_CMD) && !rc )
-			rc = WriteData (padapter);
-		if ( rc )
-			{
-			del_timer (&padapter->timer);
-			padapter->expectingIRQ = 0;
-			if ( pdev->raid )
-				{
-				padapter->survivor = (pdev->spigot ^ 3) >> 1;
-				DEB (printk ("\npci2220i: FAILURE 21"));
-				if ( !InitFailover (padapter, pdev) )
-					return 0;
-				}
-			OpDone (padapter, DID_ERROR << 16);
-			return 0;
-			}
-		}
-	return 0;
-	}
-/****************************************************************
- *	Name:			ReadFlash
- *
- *	Description:	Read information from controller Flash memory.
- *
- *	Parameters:		padapter - Pointer to host interface data structure.
- *					pdata	 - Pointer to data structures.
- *					base	 - base address in Flash.
- *					length	 - lenght of data space in bytes.
- *
- *	Returns:		Nothing.
- *
- ****************************************************************/
-static VOID ReadFlash (PADAPTER2220I padapter, VOID *pdata, ULONG base, ULONG length)
-	{
-	ULONG	 oldremap;
-	UCHAR	 olddesc;
-	ULONG	 z;
-	UCHAR	*pd = (UCHAR *)pdata;
-
-	oldremap = inl (padapter->regRemap);							// save values to restore later
-	olddesc  = inb_p (padapter->regDesc);
-
-	outl (base | 1, padapter->regRemap);							// remap to Flash space as specified
-	outb_p (0x40, padapter->regDesc);								// describe remap region as 8 bit
-	for ( z = 0;  z < length;  z++)									// get "length" data count
-		*pd++ = inb_p (padapter->regBase + z);						// read in the data
-
-	outl (oldremap, padapter->regRemap);							// restore remap register values
-	outb_p (olddesc, padapter->regDesc);
-	}
-/****************************************************************
- *	Name:			GetRegs
- *
- *	Description:	Initialize the regester information.
- *
- *	Parameters:		pshost		  - Pointer to SCSI host data structure.
- *					bigd		  - PCI-2240I identifier
- *					pcidev		  - Pointer to device data structure.
- *
- *	Returns:		TRUE if failure to install.
- *
- ****************************************************************/
-static USHORT GetRegs (struct Scsi_Host *pshost, BOOL bigd, struct pci_dev *pcidev)
-	{
-	PADAPTER2220I	padapter;
-	int				setirq;
-	int				z;
-	USHORT			zr, zl;
-	UCHAR		   *consistent;
-	dma_addr_t		consistentDma;
-
-	padapter = HOSTDATA(pshost);
-	memset (padapter, 0, sizeof (ADAPTER2220I));
-	memset (&DaleSetup, 0, sizeof (DaleSetup));
-	memset (DiskMirror, 0, sizeof (DiskMirror));
-
-	zr = pci_resource_start (pcidev, 1);
-	zl = pci_resource_start (pcidev, 2);
-
-	padapter->basePort = zr;
-	padapter->regRemap		= zr + RTR_LOCAL_REMAP;					// 32 bit local space remap
-	padapter->regDesc		= zr + RTR_REGIONS;	  					// 32 bit local region descriptor
-	padapter->regRange		= zr + RTR_LOCAL_RANGE;					// 32 bit local range
-	padapter->regIrqControl	= zr + RTR_INT_CONTROL_STATUS;			// 16 bit interrupt control and status
-	padapter->regScratchPad	= zr + RTR_MAILBOX;	  					// 16 byte scratchpad I/O base address
-
-	padapter->regBase		= zl;
-	padapter->regData		= zl + REG_DATA;						// data register I/O address
-	padapter->regError		= zl + REG_ERROR;						// error register I/O address
-	padapter->regSectCount	= zl + REG_SECTOR_COUNT;				// sector count register I/O address
-	padapter->regLba0		= zl + REG_LBA_0;						// least significant byte of LBA
-	padapter->regLba8		= zl + REG_LBA_8;						// next least significant byte of LBA
-	padapter->regLba16		= zl + REG_LBA_16;						// next most significan byte of LBA
-	padapter->regLba24		= zl + REG_LBA_24;						// head and most 4 significant bits of LBA
-	padapter->regStatCmd	= zl + REG_STAT_CMD;					// status on read and command on write register
-	padapter->regStatSel	= zl + REG_STAT_SEL;					// board status on read and spigot select on write register
-	padapter->regFail		= zl + REG_FAIL;
-	padapter->regAltStat	= zl + REG_ALT_STAT;
-	padapter->pcidev		= pcidev;
-
-	if ( bigd )
-		{
-		padapter->regDmaDesc	= zr + RTR_DMA0_DESC_PTR;			// address of the DMA discriptor register for direction of transfer
-		padapter->regDmaCmdStat	= zr + RTR_DMA_COMMAND_STATUS;		// Byte #0 of DMA command status register
-		padapter->regDmaAddrPci	= zr + RTR_DMA0_PCI_ADDR;			// 32 bit register for PCI address of DMA
-		padapter->regDmaAddrLoc	= zr + RTR_DMA0_LOCAL_ADDR;			// 32 bit register for local bus address of DMA
-		padapter->regDmaCount	= zr + RTR_DMA0_COUNT;				// 32 bit register for DMA transfer count
-		padapter->regDmaMode	= zr + RTR_DMA0_MODE + 1;			// 32 bit register for DMA mode control
-		padapter->bigD			= SEL_NEW_SPEED_1;					// set spigot speed control bit
-		}
-	else
-		{
-		padapter->regDmaDesc	= zl + RTL_DMA1_DESC_PTR;			// address of the DMA discriptor register for direction of transfer
-		padapter->regDmaCmdStat	= zl + RTL_DMA_COMMAND_STATUS + 1;	// Byte #1 of DMA command status register
-		padapter->regDmaAddrPci	= zl + RTL_DMA1_PCI_ADDR;			// 32 bit register for PCI address of DMA
-		padapter->regDmaAddrLoc	= zl + RTL_DMA1_LOCAL_ADDR;			// 32 bit register for local bus address of DMA
-		padapter->regDmaCount	= zl + RTL_DMA1_COUNT;				// 32 bit register for DMA transfer count
-		padapter->regDmaMode	= zl + RTL_DMA1_MODE + 1;			// 32 bit register for DMA mode control
-		}
-
-	padapter->numberOfDrives = inb_p (padapter->regScratchPad + BIGD_NUM_DRIVES);
-	if ( !bigd && !padapter->numberOfDrives )						// if no devices on this board
-		return TRUE;
-
-	pshost->irq = pcidev->irq;
-	setirq = 1;
-	for ( z = 0;  z < Installed;  z++ )								// scan for shared interrupts
-		{
-		if ( PsiHost[z]->irq == pshost->irq )						// if shared then, don't posses
-			setirq = 0;
-		}
-	if ( setirq )													// if not shared, posses
-		{
-		if ( request_irq (pshost->irq, Irq_Handler, SA_SHIRQ, "pci2220i", padapter) < 0 )
-			{
-			if ( request_irq (pshost->irq, Irq_Handler, SA_INTERRUPT | SA_SHIRQ, "pci2220i", padapter) < 0 )
-				{
-				printk ("Unable to allocate IRQ for PCI-2220I controller.\n");
-				return TRUE;
-				}
-			}
-		padapter->irqOwned = pshost->irq;							// set IRQ as owned
-		}
-
-	if ( padapter->numberOfDrives )
-		consistent = pci_alloc_consistent (pcidev, SECTORSXFER * BYTES_PER_SECTOR, &consistentDma);
-	else
-		consistent = pci_alloc_consistent (pcidev, ATAPI_TRANSFER, &consistentDma);
-	if ( !consistent )
-		{
-		printk ("Unable to allocate DMA buffer for PCI-2220I controller.\n");
-		free_irq (pshost->irq, padapter);
-		return TRUE;
-		}
-	padapter->kBuffer = consistent;
-	padapter->kBufferDma = consistentDma;
-
-	PsiHost[Installed]	= pshost;									// save SCSI_HOST pointer
-	pshost->io_port		= padapter->basePort;
-	pshost->n_io_port	= 0xFF;
-	pshost->unique_id	= padapter->regBase;
-
-	outb_p (0x01, padapter->regRange);								// fix our range register because other drivers want to tromp on it
-
-	padapter->timingMode = inb_p (padapter->regScratchPad + DALE_TIMING_MODE);
-	if ( padapter->timingMode >= 2 )
-		{
-		if ( bigd )
-			padapter->timingAddress	= ModeArray2[padapter->timingMode - 2];
-		else
-			padapter->timingAddress	= ModeArray[padapter->timingMode - 2];
-		}
-	else
-		padapter->timingPIO = TRUE;
-
-	ReadFlash (padapter, &DaleSetup, DALE_FLASH_SETUP, sizeof (SETUP));
-	ReadFlash (padapter, &DiskMirror, DALE_FLASH_RAID, sizeof (DiskMirror));
-
-	return FALSE;
-	}
-/****************************************************************
- *	Name:			SetupFinish
- *
- *	Description:	Complete the driver initialization process for a card
- *
- *	Parameters:		padapter  - Pointer to SCSI host data structure.
- *					str		  - Pointer to board type string.
- *
- *	Returns:		Nothing.
- *
- ****************************************************************/
-VOID SetupFinish (PADAPTER2220I padapter, char *str, int irq)
-	{
-	init_timer (&padapter->timer);
-	padapter->timer.function = TimerExpiry;
-	padapter->timer.data = (unsigned long)padapter;
-	init_timer (&padapter->reconTimer);
-	padapter->reconTimer.function = ReconTimerExpiry;
-	padapter->reconTimer.data = (unsigned long)padapter;
-	printk("\nPCI-%sI EIDE CONTROLLER: at I/O = %lX/%lX  IRQ = %d\n", str, padapter->basePort, padapter->regBase, irq);
-	printk("Version %s, Compiled %s %s\n\n", PCI2220I_VERSION, __DATE__, __TIME__);
-	}	
-/****************************************************************
- *	Name:	Pci2220i_Detect
- *
- *	Description:	Detect and initialize our boards.
- *
- *	Parameters:		tpnt - Pointer to SCSI host template structure.
- *
- *	Returns:		Number of adapters installed.
- *
- ****************************************************************/
-int Pci2220i_Detect (Scsi_Host_Template *tpnt)
-	{
-	struct Scsi_Host   *pshost;
-	PADAPTER2220I	    padapter;
-	POUR_DEVICE			pdev;
-	int					unit;
-	int					z;
-	USHORT				raidon;
-	UCHAR				spigot1, spigot2;
-	UCHAR				device;
-	struct pci_dev	   *pcidev = NULL;
-
-	while ( (pcidev = pci_find_device (VENDOR_PSI, DEVICE_DALE_1, pcidev)) != NULL )
-		{
-		if (pci_enable_device(pcidev))
-			continue;
-		pshost = scsi_register (tpnt, sizeof(ADAPTER2220I));
-		if(pshost==NULL)
-			continue;
-			
-		padapter = HOSTDATA(pshost);
-
-		if ( GetRegs (pshost, FALSE, pcidev) )
-			goto unregister;
-
-		scsi_set_device(pshost, &pcidev->dev);
-		pshost->max_id = padapter->numberOfDrives;
-		for ( z = 0;  z < padapter->numberOfDrives;  z++ )
-			{
-			unit = inb_p (padapter->regScratchPad + DALE_CHANNEL_DEVICE_0 + z) & 0x0F;
-			pdev = &padapter->device[z];
-			pdev->byte6		= (UCHAR)(((unit & 1) << 4) | 0xE0);
-			pdev->spigot	= (UCHAR)(1 << (unit >> 1));
-			pdev->sectors	= DaleSetup.setupDevice[unit].sectors;
-			pdev->heads		= DaleSetup.setupDevice[unit].heads;
-			pdev->cylinders = DaleSetup.setupDevice[unit].cylinders;
-			pdev->blocks	= DaleSetup.setupDevice[unit].blocks;
-
-			if ( !z )
-				{
-				DiskMirror[0].status = inb_p (padapter->regScratchPad + DALE_RAID_0_STATUS);		
-				DiskMirror[1].status = inb_p (padapter->regScratchPad + DALE_RAID_1_STATUS);		
-				if ( (DiskMirror[0].signature == SIGNATURE) && (DiskMirror[1].signature == SIGNATURE) &&
-				     (DiskMirror[0].pairIdentifier == (DiskMirror[1].pairIdentifier ^ 1)) )
-					{			 
-					raidon = TRUE;
-					if ( unit > (unit ^ 2) )
-						unit = unit ^ 2;
-					}	
-				else
-					raidon = FALSE;
-
-				memcpy (pdev->DiskMirror, DiskMirror, sizeof (DiskMirror));
-				padapter->raidData[0] = &pdev->DiskMirror[0];
-				padapter->raidData[2] = &pdev->DiskMirror[1];
-				
-				spigot1 = spigot2 = FALSE;
-				pdev->spigots[0] = 1;
-				pdev->spigots[1] = 2;
-				pdev->lastsectorlba[0] = InlineIdentify (padapter, 1, 0);
-				pdev->lastsectorlba[1] = InlineIdentify (padapter, 2, 0);
-						
-				if ( !(pdev->DiskMirror[1].status & UCBF_SURVIVOR) && pdev->lastsectorlba[0] )
-					spigot1 = TRUE;
-				if ( !(pdev->DiskMirror[0].status & UCBF_SURVIVOR) && pdev->lastsectorlba[1] )
-					spigot2 = TRUE;
-				if ( pdev->DiskMirror[0].status & DiskMirror[1].status & UCBF_SURVIVOR )
-					spigot1 = TRUE;
-
-				if ( spigot1 && (pdev->DiskMirror[0].status & UCBF_REBUILD) )
-					InlineReadSignature (padapter, pdev, 0);
-				if ( spigot2 && (pdev->DiskMirror[1].status & UCBF_REBUILD) )
-					InlineReadSignature (padapter, pdev, 1);
-
-				if ( spigot1 && spigot2 && raidon )
-					{
-					pdev->raid = 1;
-					if ( pdev->DiskMirror[0].status & UCBF_REBUILD )
-						pdev->spigot = 2;
-					else
-						pdev->spigot = 1;
-					if ( (pdev->DiskMirror[0].status & UCBF_REBUILD) || (pdev->DiskMirror[1].status & UCBF_REBUILD) )
-						padapter->reconOn = pdev->reconOn = pdev->reconIsStarting = TRUE;
-					}
-				else
-					{
-					if ( spigot1 )
-						{
-						if ( pdev->DiskMirror[0].status & UCBF_REBUILD )
-							goto unregister;
-						pdev->DiskMirror[0].status = UCBF_MIRRORED | UCBF_SURVIVOR;
-						pdev->spigot = 1;
-						}
-					else
-						{
-						if ( pdev->DiskMirror[1].status & UCBF_REBUILD )
-							goto unregister;
-						pdev->DiskMirror[1].status = UCBF_MIRRORED | UCBF_SURVIVOR;
-						pdev->spigot = 2;
-						}
-					if ( DaleSetup.rebootRebuild && raidon )
-						padapter->reconOn = pdev->reconOn = pdev->reconIsStarting = TRUE;
-					}
-			
-				if ( raidon )
-					break;
-				}
-			}
-
-		SetupFinish (padapter, "2220", pshost->irq);
-	
-		if ( ++Installed < MAXADAPTER )
-			continue;
-		break;
-unregister:;
-		scsi_unregister (pshost);
-		}
-
-	while ( (pcidev = pci_find_device (VENDOR_PSI, DEVICE_BIGD_1, pcidev)) != NULL )
-		{
-		pshost = scsi_register (tpnt, sizeof(ADAPTER2220I));
-		padapter = HOSTDATA(pshost);
-
-		if ( GetRegs (pshost, TRUE, pcidev) )
-			goto unregister1;
-
-		for ( z = 0;  z < BIGD_MAXDRIVES;  z++ )
-			DiskMirror[z].status = inb_p (padapter->regScratchPad + BIGD_RAID_0_STATUS + z);		
-
-		scsi_set_pci_device(pshost, pcidev);
-		pshost->max_id = padapter->numberOfDrives;
-		padapter->failRegister = inb_p (padapter->regScratchPad + BIGD_ALARM_IMAGE);
-		for ( z = 0;  z < padapter->numberOfDrives;  z++ )
-			{
-			unit = inb_p (padapter->regScratchPad + BIGD_DEVICE_0 + z);
-			pdev = &padapter->device[z];
-			pdev->byte6		= (UCHAR)(((unit & 1) << 4) | 0xE0);
-			pdev->spigot	= (UCHAR)(1 << (unit >> 1));
-			pdev->sectors	= DaleSetup.setupDevice[unit].sectors;
-			pdev->heads		= DaleSetup.setupDevice[unit].heads;
-			pdev->cylinders = DaleSetup.setupDevice[unit].cylinders;
-			pdev->blocks	= DaleSetup.setupDevice[unit].blocks;
-			
-			if ( (DiskMirror[unit].signature == SIGNATURE) && (DiskMirror[unit ^ 2].signature == SIGNATURE) &&
-			     (DiskMirror[unit].pairIdentifier == (DiskMirror[unit ^ 2].pairIdentifier ^ 1)) )
-				{			 
-				raidon = TRUE;
-				if ( unit > (unit ^ 2) )
-					unit = unit ^ 2;
-				}	
-			else
-				raidon = FALSE;
-				
-			spigot1 = spigot2 = FALSE;
-			memcpy (&pdev->DiskMirror[0], &DiskMirror[unit], sizeof (DISK_MIRROR));
-			memcpy (&pdev->DiskMirror[1], &DiskMirror[unit ^ 2], sizeof (DISK_MIRROR));
-			padapter->raidData[unit]	 = &pdev->DiskMirror[0];
-			padapter->raidData[unit ^ 2] = &pdev->DiskMirror[1];
-			pdev->spigots[0] = 1 << (unit >> 1);
-			pdev->spigots[1] = 1 << ((unit ^ 2) >> 1);
-			pdev->deviceID[0] = unit;
-			pdev->deviceID[1] = unit ^ 2;
-			pdev->lastsectorlba[0] = InlineIdentify (padapter, pdev->spigots[0], unit & 1);
-			pdev->lastsectorlba[1] = InlineIdentify (padapter, pdev->spigots[1], unit & 1);
-
-			if ( !(pdev->DiskMirror[1].status & UCBF_SURVIVOR) && pdev->lastsectorlba[0] )
-				spigot1 = TRUE;
-			if ( !(pdev->DiskMirror[0].status & UCBF_SURVIVOR) && pdev->lastsectorlba[1] )
-				spigot2 = TRUE;
-			if ( pdev->DiskMirror[0].status & pdev->DiskMirror[1].status & UCBF_SURVIVOR )
-				spigot1 = TRUE;
-
-			if ( spigot1 && (pdev->DiskMirror[0].status & UCBF_REBUILD) )
-				InlineReadSignature (padapter, pdev, 0);
-			if ( spigot2 && (pdev->DiskMirror[1].status & UCBF_REBUILD) )
-				InlineReadSignature (padapter, pdev, 1);
-
-			if ( spigot1 && spigot2 && raidon )
-				{
-				pdev->raid = 1;
-				if ( pdev->DiskMirror[0].status & UCBF_REBUILD )
-					pdev->spigot = pdev->spigots[1];
-				else
-					pdev->spigot = pdev->spigots[0];
-				if ( (pdev->DiskMirror[0].status & UCBF_REBUILD) || (pdev->DiskMirror[1].status & UCBF_REBUILD) )
-					padapter->reconOn = pdev->reconOn = pdev->reconIsStarting = TRUE;
-				}
-			else
-				{
-				if ( spigot1 )
-					{
-					if ( pdev->DiskMirror[0].status & UCBF_REBUILD )
-						goto unregister1;
-					pdev->DiskMirror[0].status = UCBF_MIRRORED | UCBF_SURVIVOR;
-					pdev->spigot = pdev->spigots[0];
-					}
-				else
-					{
-					if ( pdev->DiskMirror[1].status & UCBF_REBUILD )
-						goto unregister;
-					pdev->DiskMirror[1].status = UCBF_MIRRORED | UCBF_SURVIVOR;
-					pdev->spigot = pdev->spigots[1];
-					}
-				if ( DaleSetup.rebootRebuild && raidon )
-					padapter->reconOn = pdev->reconOn = pdev->reconIsStarting = TRUE;
-				}
-			}
-		
-		if ( !padapter->numberOfDrives )									// If no ATA devices then scan ATAPI
-			{
-			unit = 0;
-			for ( spigot1 = 0;  spigot1 < 4;  spigot1++ )
-				{
-				for ( device = 0;  device < 2;  device++ )
-					{
-					DEB (printk ("\nPCI2242I: scanning for ID %d ", (spigot1 * 2) + device));
-					pdev = &(padapter->device[(spigot1 * 2) + device]);
-					pdev->byte6 = 0x0A | (device << 4);
-					pdev->spigot = 1 << spigot1;
-					if ( !AtapiReset (padapter, pdev) )
-						{
-						DEB (printk (" Device found "));
-						if ( !AtapiIdentify (padapter, pdev) )
-							{
-							DEB (printk (" Device verified"));
-							unit++;
-							continue;
-							}
-						}
-					pdev->spigot = pdev->byte6 = 0;
-					}
-				}
-
-			if ( unit )
-				{
-				padapter->atapi = TRUE;
-				padapter->timingAddress = DALE_DATA_MODE3;
-				outw_p (0x0900, padapter->regIrqControl);					// Turn our interrupts on
-				outw_p (0x0C41, padapter->regDmaMode - 1);					// setup for 16 bits, ready enabled, done IRQ enabled, no incriment
-				outb_p (0xFF, padapter->regFail);							// all fail lights and alarm off
-				pshost->max_id = 8;
-				}
-			}
-		SetupFinish (padapter, "2240", pshost->irq);
-		
-		if ( ++Installed < MAXADAPTER )
-			continue;
-		break;
-unregister1:;
-		scsi_unregister (pshost);
-		}
-
-	NumAdapters = Installed;
-	return Installed;
-	}
-/****************************************************************
- *	Name:	Pci2220i_Abort
- *
- *	Description:	Process the Abort command from the SCSI manager.
- *
- *	Parameters:		SCpnt - Pointer to SCSI command structure.
- *
- *	Returns:		Allways snooze.
- *
- ****************************************************************/
-int Pci2220i_Abort (Scsi_Cmnd *SCpnt)
-	{
-	PADAPTER2220I	padapter = HOSTDATA(SCpnt->device->host);			// Pointer to adapter control structure
-	POUR_DEVICE		pdev	 = &padapter->device[SCpnt->device->id];// Pointer to device information
-
-	if ( !padapter->SCpnt )
-		return SCSI_ABORT_NOT_RUNNING;
-	
-	if ( padapter->atapi )
-		{
-		if ( AtapiReset (padapter, pdev) )
-			return SCSI_ABORT_ERROR;
-		OpDone (padapter, DID_ABORT << 16);
-		return SCSI_ABORT_SUCCESS;
-		}
-	return SCSI_ABORT_SNOOZE;
-	}
-/****************************************************************
- *	Name:	Pci2220i_Reset
- *
- *	Description:	Process the Reset command from the SCSI manager.
- *
- *	Parameters:		SCpnt - Pointer to SCSI command structure.
- *					flags - Flags about the reset command
- *
- *	Returns:		No active command at this time, so this means
- *					that each time we got some kind of response the
- *					last time through.  Tell the mid-level code to
- *					request sense information in order to decide what
- *					to do next.
- *
- ****************************************************************/
-int Pci2220i_Reset (Scsi_Cmnd *SCpnt, unsigned int reset_flags)
-	{
-	PADAPTER2220I	padapter = HOSTDATA(SCpnt->device->host);			// Pointer to adapter control structure
-	POUR_DEVICE		pdev	 = &padapter->device[SCpnt->device->id];// Pointer to device information
-
-	if ( padapter->atapi )
-		{
-		if ( AtapiReset (padapter, pdev) )
-			return SCSI_RESET_ERROR;
-		return SCSI_RESET_SUCCESS;
-		}
-	return SCSI_RESET_PUNT;
-	}
-/****************************************************************
- *	Name:	Pci2220i_Release
- *
- *	Description:	Release resources allocated for a single each adapter.
- *
- *	Parameters:		pshost - Pointer to SCSI command structure.
- *
- *	Returns:		zero.
- *
- ****************************************************************/
-int Pci2220i_Release (struct Scsi_Host *pshost)
-	{
-    PADAPTER2220I	padapter = HOSTDATA (pshost);
-	USHORT			z;
-
-	if ( padapter->reconOn )
-		{
-		padapter->reconOn = FALSE;						// shut down the hot reconstruct
-		if ( padapter->reconPhase )
-			mdelay (300);
-		if ( padapter->reconTimer.data )				// is the timer running?
-			{
-			del_timer (&padapter->reconTimer);
-			padapter->reconTimer.data = 0;
-			}
-		}
-
-	// save RAID status on the board
-	if ( padapter->bigD )
-		{
-		outb_p (padapter->failRegister, padapter->regScratchPad + BIGD_ALARM_IMAGE);
-		for ( z = 0;  z < BIGD_MAXDRIVES;  z++ )
-			{
-			if ( padapter->raidData )
-				outb_p (padapter->raidData[z]->status, padapter->regScratchPad + BIGD_RAID_0_STATUS + z);	
-			else
-				outb_p (0, padapter->regScratchPad + BIGD_RAID_0_STATUS);	
-			}
-		}
-	else
-		{
-		outb_p (padapter->device[0].DiskMirror[0].status, padapter->regScratchPad + DALE_RAID_0_STATUS);		
-		outb_p (padapter->device[0].DiskMirror[1].status, padapter->regScratchPad + DALE_RAID_1_STATUS);		
-		}
-
-	if ( padapter->irqOwned )
-		free_irq (pshost->irq, padapter);
-    release_region (pshost->io_port, pshost->n_io_port);
-	if ( padapter->numberOfDrives )
-		pci_free_consistent (padapter->pcidev, SECTORSXFER * BYTES_PER_SECTOR, padapter->kBuffer, padapter->kBufferDma);
-	else	
-		pci_free_consistent (padapter->pcidev, ATAPI_TRANSFER, padapter->kBuffer, padapter->kBufferDma);
-    scsi_unregister(pshost);
-    return 0;
-	}
-
-/****************************************************************
- *	Name:	Pci2220i_BiosParam
- *
- *	Description:	Process the biosparam request from the SCSI manager to
- *					return C/H/S data.
- *
- *	Parameters:		disk - Pointer to SCSI disk structure.
- *					dev	 - Major/minor number from kernel.
- *					geom - Pointer to integer array to place geometry data.
- *
- *	Returns:		zero.
- *
- ****************************************************************/
-int Pci2220i_BiosParam (struct scsi_device *sdev, struct block_device *dev,
-		sector_t capacity, int geom[])
-	{
-	POUR_DEVICE	pdev;
-
-	if ( !(HOSTDATA(sdev->host))->atapi )
-		{
-		pdev = &(HOSTDATA(sdev->host)->device[sdev->id]);
-
-		geom[0] = pdev->heads;
-		geom[1] = pdev->sectors;
-		geom[2] = pdev->cylinders;
-		}
-	return 0;
-	}
-
-MODULE_LICENSE("Dual BSD/GPL");
-
-static Scsi_Host_Template driver_template = {
-	.proc_name		= "pci2220i",
-	.name			= "PCI-2220I/PCI-2240I",
-	.detect			= Pci2220i_Detect,
-	.release		= Pci2220i_Release,
-	.queuecommand		= Pci2220i_QueueCommand,
-	.abort			= Pci2220i_Abort,
-	.reset			= Pci2220i_Reset,
-	.bios_param		= Pci2220i_BiosParam,
-	.can_queue		= 1,
-	.this_id		= -1,
-	.sg_tablesize		= SG_ALL,
-	.cmd_per_lun		= 1,
-	.use_clustering		= DISABLE_CLUSTERING,
-};
-#include "scsi_module.c"
diff --git a/drivers/scsi/pci2220i.h b/drivers/scsi/pci2220i.h
deleted file mode 100644
--- a/drivers/scsi/pci2220i.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/****************************************************************************
- * Perceptive Solutions, Inc. PCI-2220I device driver for Linux.
- *
- * pci2220i.h - Linux Host Driver for PCI-2220i EIDE Adapters
- *
- * Copyright (c) 1997-1999 Perceptive Solutions, Inc.
- * All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that redistributions of source
- * code retain the above copyright notice and this comment without
- * modification.
- *
- * Technical updates and product information at:
- *  http://www.psidisk.com
- *
- * Please send questions, comments, bug reports to:
- *  tech@psidisk.com Technical Support
- *
- ****************************************************************************/
-#ifndef _PCI2220I_H
-#define _PCI2220I_H
-
-#ifndef LINUX_VERSION_CODE
-#include <linux/version.h>
-#endif 
-#define	LINUXVERSION(v,p,s)    (((v)<<16) + ((p)<<8) + (s))
-
-// function prototypes
-int Pci2220i_Detect			(Scsi_Host_Template *tpnt);
-int Pci2220i_Command		(Scsi_Cmnd *SCpnt);
-int Pci2220i_QueueCommand	(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *));
-int Pci2220i_Abort			(Scsi_Cmnd *SCpnt);
-int Pci2220i_Reset			(Scsi_Cmnd *SCpnt, unsigned int flags);
-int Pci2220i_Release		(struct Scsi_Host *pshost);
-int Pci2220i_BiosParam		(struct scsi_device *sdev,
-					struct block_device *dev,
-					sector_t capacity, int geom[]);
-#endif
diff --git a/drivers/scsi/pcmcia/aha152x_stub.c b/drivers/scsi/pcmcia/aha152x_stub.c
--- a/drivers/scsi/pcmcia/aha152x_stub.c
+++ b/drivers/scsi/pcmcia/aha152x_stub.c
@@ -50,7 +50,6 @@
 #include <scsi/scsi_host.h>
 #include "aha152x.h"
 
-#include <pcmcia/version.h>
 #include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
@@ -134,11 +133,6 @@ static dev_link_t *aha152x_attach(void)
     link->next = dev_list;
     dev_list = link;
     client_reg.dev_info = &dev_info;
-    client_reg.event_handler = &aha152x_event;
-    client_reg.EventMask =
-	CS_EVENT_RESET_REQUEST | CS_EVENT_CARD_RESET |
-	CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
-	CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
     client_reg.Version = 0x0210;
     client_reg.event_callback_args.client_data = link;
     ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -318,13 +312,25 @@ static int aha152x_event(event_t event, 
     return 0;
 }
 
+static struct pcmcia_device_id aha152x_ids[] = {
+	PCMCIA_DEVICE_PROD_ID123("New Media", "SCSI", "Bus Toaster", 0xcdf7e4cc, 0x35f26476, 0xa8851d6e),
+	PCMCIA_DEVICE_PROD_ID123("NOTEWORTHY", "SCSI", "Bus Toaster", 0xad89c6e8, 0x35f26476, 0xa8851d6e),
+	PCMCIA_DEVICE_PROD_ID12("Adaptec, Inc.", "APA-1460 SCSI Host Adapter", 0x24ba9738, 0x3a3c3d20),
+	PCMCIA_DEVICE_PROD_ID12("New Media Corporation", "Multimedia Sound/SCSI", 0x085a850b, 0x80a6535c),
+	PCMCIA_DEVICE_PROD_ID12("NOTEWORTHY", "NWCOMB02 SCSI/AUDIO COMBO CARD", 0xad89c6e8, 0x5f9a615b),
+	PCMCIA_DEVICE_NULL,
+};
+MODULE_DEVICE_TABLE(pcmcia, aha152x_ids);
+
 static struct pcmcia_driver aha152x_cs_driver = {
 	.owner		= THIS_MODULE,
 	.drv		= {
 		.name	= "aha152x_cs",
 	},
 	.attach		= aha152x_attach,
+	.event		= aha152x_event,
 	.detach		= aha152x_detach,
+	.id_table       = aha152x_ids,
 };
 
 static int __init init_aha152x_cs(void)
diff --git a/drivers/scsi/pcmcia/fdomain_stub.c b/drivers/scsi/pcmcia/fdomain_stub.c
--- a/drivers/scsi/pcmcia/fdomain_stub.c
+++ b/drivers/scsi/pcmcia/fdomain_stub.c
@@ -47,7 +47,6 @@
 #include <scsi/scsi_host.h>
 #include "fdomain.h"
 
-#include <pcmcia/version.h>
 #include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
@@ -120,11 +119,6 @@ static dev_link_t *fdomain_attach(void)
     link->next = dev_list;
     dev_list = link;
     client_reg.dev_info = &dev_info;
-    client_reg.event_handler = &fdomain_event;
-    client_reg.EventMask =
-	CS_EVENT_RESET_REQUEST | CS_EVENT_CARD_RESET |
-	CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
-	CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
     client_reg.Version = 0x0210;
     client_reg.event_callback_args.client_data = link;
     ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -299,13 +293,24 @@ static int fdomain_event(event_t event, 
     return 0;
 } /* fdomain_event */
 
+
+static struct pcmcia_device_id fdomain_ids[] = {
+	PCMCIA_DEVICE_PROD_ID12("IBM Corp.", "SCSI PCMCIA Card", 0xe3736c88, 0x859cad20),
+	PCMCIA_DEVICE_PROD_ID1("SCSI PCMCIA Adapter Card", 0x8dacb57e),
+	PCMCIA_DEVICE_PROD_ID12(" SIMPLE TECHNOLOGY Corporation", "SCSI PCMCIA Credit Card Controller", 0x182bdafe, 0xc80d106f),
+	PCMCIA_DEVICE_NULL,
+};
+MODULE_DEVICE_TABLE(pcmcia, fdomain_ids);
+
 static struct pcmcia_driver fdomain_cs_driver = {
 	.owner		= THIS_MODULE,
 	.drv		= {
 		.name	= "fdomain_cs",
 	},
 	.attach		= fdomain_attach,
+	.event		= fdomain_event,
 	.detach		= fdomain_detach,
+	.id_table       = fdomain_ids,
 };
 
 static int __init init_fdomain_cs(void)
diff --git a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c
--- a/drivers/scsi/pcmcia/nsp_cs.c
+++ b/drivers/scsi/pcmcia/nsp_cs.c
@@ -51,7 +51,6 @@
 #include <scsi/scsi.h>
 #include <scsi/scsi_ioctl.h>
 
-#include <pcmcia/version.h>
 #include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
@@ -92,9 +91,7 @@ static Scsi_Host_Template nsp_driver_tem
 #endif
 	.info			 = nsp_info,
 	.queuecommand		 = nsp_queuecommand,
-/*	.eh_strategy_handler	 = nsp_eh_strategy,*/
 /*	.eh_abort_handler	 = nsp_eh_abort,*/
-/*	.eh_device_reset_handler = nsp_eh_device_reset,*/
 	.eh_bus_reset_handler	 = nsp_eh_bus_reset,
 	.eh_host_reset_handler	 = nsp_eh_host_reset,
 	.can_queue		 = 1,
@@ -1536,11 +1533,6 @@ nsp_proc_info(
 /* error handler                                                 */
 /*---------------------------------------------------------------*/
 
-/*static int nsp_eh_strategy(struct Scsi_Host *Shost)
-{
-	return FAILED;
-}*/
-
 /*
 static int nsp_eh_abort(Scsi_Cmnd *SCpnt)
 {
@@ -1549,14 +1541,6 @@ static int nsp_eh_abort(Scsi_Cmnd *SCpnt
 	return nsp_eh_bus_reset(SCpnt);
 }*/
 
-/*
-static int nsp_eh_device_reset(Scsi_Cmnd *SCpnt)
-{
-	nsp_dbg(NSP_DEBUG_BUSRESET, "%s: SCpnt=0x%p", SCpnt);
-
-	return FAILED;
-}*/
-
 static int nsp_bus_reset(nsp_hw_data *data)
 {
 	unsigned int base = data->BaseAddress;
@@ -1657,11 +1641,6 @@ static dev_link_t *nsp_cs_attach(void)
 	link->next               = dev_list;
 	dev_list                 = link;
 	client_reg.dev_info	 = &dev_info;
-	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 = &nsp_cs_event;
 	client_reg.Version	 = 0x0210;
 	client_reg.event_callback_args.client_data = link;
 	ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -2140,13 +2119,27 @@ static int nsp_cs_event(event_t		       
  *	module entry point
  *====================================================================*/
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,68))
+static struct pcmcia_device_id nsp_cs_ids[] = {
+	PCMCIA_DEVICE_PROD_ID123("IO DATA", "CBSC16       ", "1", 0x547e66dc, 0x0d63a3fd, 0x51de003a),
+	PCMCIA_DEVICE_PROD_ID123("KME    ", "SCSI-CARD-001", "1", 0x534c02bc, 0x52008408, 0x51de003a),
+	PCMCIA_DEVICE_PROD_ID123("KME    ", "SCSI-CARD-002", "1", 0x534c02bc, 0xcb09d5b2, 0x51de003a),
+	PCMCIA_DEVICE_PROD_ID123("KME    ", "SCSI-CARD-003", "1", 0x534c02bc, 0xbc0ee524, 0x51de003a),
+	PCMCIA_DEVICE_PROD_ID123("KME    ", "SCSI-CARD-004", "1", 0x534c02bc, 0x226a7087, 0x51de003a),
+	PCMCIA_DEVICE_PROD_ID123("WBT", "NinjaSCSI-3", "R1.0", 0xc7ba805f, 0xfdc7c97d, 0x6973710e),
+	PCMCIA_DEVICE_PROD_ID123("WORKBIT", "UltraNinja-16", "1", 0x28191418, 0xb70f4b09, 0x51de003a),
+	PCMCIA_DEVICE_NULL
+};
+MODULE_DEVICE_TABLE(pcmcia, nsp_cs_ids);
+
 static struct pcmcia_driver nsp_driver = {
-	.owner          = THIS_MODULE,
-	.drv            = {
-		.name   = "nsp_cs",
+	.owner		= THIS_MODULE,
+	.drv		= {
+		.name	= "nsp_cs",
 	},
-	.attach         = nsp_cs_attach,
-	.detach         = nsp_cs_detach,
+	.attach		= nsp_cs_attach,
+	.event		= nsp_cs_event,
+	.detach		= nsp_cs_detach,
+	.id_table	= nsp_cs_ids,
 };
 #endif
 
diff --git a/drivers/scsi/pcmcia/qlogic_stub.c b/drivers/scsi/pcmcia/qlogic_stub.c
--- a/drivers/scsi/pcmcia/qlogic_stub.c
+++ b/drivers/scsi/pcmcia/qlogic_stub.c
@@ -49,7 +49,6 @@
 #include <scsi/scsi_host.h>
 #include "../qlogicfas408.h"
 
-#include <pcmcia/version.h>
 #include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
@@ -81,8 +80,6 @@ static Scsi_Host_Template qlogicfas_driv
 	.queuecommand		= qlogicfas408_queuecommand,
 	.eh_abort_handler	= qlogicfas408_abort,
 	.eh_bus_reset_handler	= qlogicfas408_bus_reset,
-	.eh_device_reset_handler= qlogicfas408_device_reset,
-	.eh_host_reset_handler	= qlogicfas408_host_reset,
 	.bios_param		= qlogicfas408_biosparam,
 	.can_queue		= 1,
 	.this_id		= -1,
@@ -196,8 +193,6 @@ static dev_link_t *qlogic_attach(void)
 	link->next = dev_list;
 	dev_list = link;
 	client_reg.dev_info = &dev_info;
-	client_reg.event_handler = &qlogic_event;
-	client_reg.EventMask = CS_EVENT_RESET_REQUEST | CS_EVENT_CARD_RESET | CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL | CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
 	client_reg.Version = 0x0210;
 	client_reg.event_callback_args.client_data = link;
 	ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -397,6 +392,27 @@ static int qlogic_event(event_t event, i
 	return 0;
 }				/* qlogic_event */
 
+static struct pcmcia_device_id qlogic_ids[] = {
+	PCMCIA_DEVICE_PROD_ID12("EIger Labs", "PCMCIA-to-SCSI Adapter", 0x88395fa7, 0x33b7a5e6),
+	PCMCIA_DEVICE_PROD_ID12("EPSON", "SCSI-2 PC Card SC200", 0xd361772f, 0x299d1751),
+	PCMCIA_DEVICE_PROD_ID12("MACNICA", "MIRACLE SCSI-II mPS110", 0x20841b68, 0xab3c3b6d),
+	PCMCIA_DEVICE_PROD_ID12("MIDORI ELECTRONICS ", "CN-SC43", 0x6534382a, 0xd67eee79),
+	PCMCIA_DEVICE_PROD_ID12("NEC", "PC-9801N-J03R", 0x18df0ba0, 0x24662e8a),
+	PCMCIA_DEVICE_PROD_ID12("KME ", "KXLC003", 0x82375a27, 0xf68e5bf7),
+	PCMCIA_DEVICE_PROD_ID12("KME ", "KXLC004", 0x82375a27, 0x68eace54),
+	PCMCIA_DEVICE_PROD_ID12("KME", "KXLC101", 0x3faee676, 0x194250ec),
+	PCMCIA_DEVICE_PROD_ID12("QLOGIC CORPORATION", "pc05", 0xd77b2930, 0xa85b2735),
+	PCMCIA_DEVICE_PROD_ID12("QLOGIC CORPORATION", "pc05 rev 1.10", 0xd77b2930, 0x70f8b5f8),
+	PCMCIA_DEVICE_PROD_ID123("KME", "KXLC002", "00", 0x3faee676, 0x81896b61, 0xf99f065f),
+	PCMCIA_DEVICE_PROD_ID12("RATOC System Inc.", "SCSI2 CARD 37", 0x85c10e17, 0x1a2640c1),
+	PCMCIA_DEVICE_PROD_ID12("TOSHIBA", "SCSC200A PC CARD SCSI", 0xb4585a1a, 0xa6f06ebe),
+	PCMCIA_DEVICE_PROD_ID12("TOSHIBA", "SCSC200B PC CARD SCSI-10", 0xb4585a1a, 0x0a88dea0),
+	/* these conflict with other cards! */
+	/* PCMCIA_DEVICE_PROD_ID123("MACNICA", "MIRACLE SCSI", "mPS100", 0x20841b68, 0xf8dedaeb, 0x89f7fafb), */
+	/* PCMCIA_DEVICE_PROD_ID123("MACNICA", "MIRACLE SCSI", "mPS100", 0x20841b68, 0xf8dedaeb, 0x89f7fafb), */
+	PCMCIA_DEVICE_NULL,
+};
+MODULE_DEVICE_TABLE(pcmcia, qlogic_ids);
 
 static struct pcmcia_driver qlogic_cs_driver = {
 	.owner		= THIS_MODULE,
@@ -404,7 +420,9 @@ static struct pcmcia_driver qlogic_cs_dr
 	.name		= "qlogic_cs",
 	},
 	.attach		= qlogic_attach,
+	.event		= qlogic_event,
 	.detach		= qlogic_detach,
+	.id_table       = qlogic_ids,
 };
 
 static int __init init_qlogic_cs(void)
diff --git a/drivers/scsi/pcmcia/sym53c500_cs.c b/drivers/scsi/pcmcia/sym53c500_cs.c
--- a/drivers/scsi/pcmcia/sym53c500_cs.c
+++ b/drivers/scsi/pcmcia/sym53c500_cs.c
@@ -627,7 +627,9 @@ SYM53C500_host_reset(struct scsi_cmnd *S
 	int port_base = SCpnt->device->host->io_port;
 
 	DEB(printk("SYM53C500_host_reset called\n"));
+	spin_lock_irq(SCpnt->device->host->host_lock);
 	SYM53C500_int_host_reset(port_base);
+	spin_unlock_irq(SCpnt->device->host->host_lock);
 
 	return SUCCESS;
 }
@@ -977,10 +979,6 @@ SYM53C500_attach(void)
 	link->next = dev_list;
 	dev_list = link;
 	client_reg.dev_info = &dev_info;
-	client_reg.event_handler = &SYM53C500_event;
-	client_reg.EventMask = CS_EVENT_RESET_REQUEST | CS_EVENT_CARD_RESET |
-	    CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
-	    CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
 	client_reg.Version = 0x0210;
 	client_reg.event_callback_args.client_data = link;
 	ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -997,13 +995,23 @@ MODULE_AUTHOR("Bob Tracy <rct@frus.com>"
 MODULE_DESCRIPTION("SYM53C500 PCMCIA SCSI driver");
 MODULE_LICENSE("GPL");
 
+static struct pcmcia_device_id sym53c500_ids[] = {
+	PCMCIA_DEVICE_PROD_ID12("BASICS by New Media Corporation", "SCSI Sym53C500", 0x23c78a9d, 0x0099e7f7),
+	PCMCIA_DEVICE_PROD_ID12("New Media Corporation", "SCSI Bus Toaster Sym53C500", 0x085a850b, 0x45432eb8),
+	PCMCIA_DEVICE_PROD_ID2("SCSI9000", 0x21648f44),
+	PCMCIA_DEVICE_NULL,
+};
+MODULE_DEVICE_TABLE(pcmcia, sym53c500_ids);
+
 static struct pcmcia_driver sym53c500_cs_driver = {
 	.owner		= THIS_MODULE,
 	.drv		= {
 		.name	= "sym53c500_cs",
 	},
 	.attach		= SYM53C500_attach,
+	.event		= SYM53C500_event,
 	.detach		= SYM53C500_detach,
+	.id_table       = sym53c500_ids,
 };
 
 static int __init
diff --git a/drivers/scsi/pluto.c b/drivers/scsi/pluto.c
--- a/drivers/scsi/pluto.c
+++ b/drivers/scsi/pluto.c
@@ -354,7 +354,6 @@ static Scsi_Host_Template driver_templat
 	.use_clustering		= ENABLE_CLUSTERING,
 	.eh_abort_handler	= fcp_scsi_abort,
 	.eh_device_reset_handler = fcp_scsi_dev_reset,
-	.eh_bus_reset_handler	= fcp_scsi_bus_reset,
 	.eh_host_reset_handler	= fcp_scsi_host_reset,
 };
 
diff --git a/drivers/scsi/ppa.c b/drivers/scsi/ppa.c
--- a/drivers/scsi/ppa.c
+++ b/drivers/scsi/ppa.c
@@ -17,6 +17,7 @@
 #include <linux/blkdev.h>
 #include <linux/parport.h>
 #include <linux/workqueue.h>
+#include <linux/delay.h>
 #include <asm/io.h>
 
 #include <scsi/scsi.h>
@@ -891,9 +892,9 @@ static int ppa_reset(struct scsi_cmnd *c
 
 	ppa_connect(dev, CONNECT_NORMAL);
 	ppa_reset_pulse(dev->base);
-	udelay(1000);		/* device settle delay */
+	mdelay(1);		/* device settle delay */
 	ppa_disconnect(dev);
-	udelay(1000);		/* device settle delay */
+	mdelay(1);		/* device settle delay */
 	return SUCCESS;
 }
 
diff --git a/drivers/scsi/psi_dale.h b/drivers/scsi/psi_dale.h
deleted file mode 100644
--- a/drivers/scsi/psi_dale.h
+++ /dev/null
@@ -1,564 +0,0 @@
-/****************************************************************************
- * Perceptive Solutions, Inc. PCI-2220I device driver for Linux.
- *
- * psi_dalei.h - Linux Host Driver for PCI-2220i EIDE Adapters
- *
- * Copyright (c) 1997-1999 Perceptive Solutions, Inc.
- * All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that redistributions of source
- * code retain the above copyright notice and this comment without
- * modification.
- *
- * Technical updates and product information at:
- *  http://www.psidisk.com
- *
- * Please send questions, comments, bug reports to:
- *  tech@psidisk.com Technical Support
- *
- ****************************************************************************/
-
-/************************************************/
-/*		Some defines that we like 				*/
-/************************************************/
-#define	CHAR		char
-#define	UCHAR		unsigned char
-#define	SHORT		short
-#define	USHORT		unsigned short
-#define	BOOL		unsigned short
-#define	LONG		long
-#define	ULONG		unsigned long
-#define	VOID		void
-
-/************************************************/
-/*		Dale PCI setup							*/
-/************************************************/
-#define	VENDOR_PSI			0x1256
-#define	DEVICE_DALE_1		0x4401		/* 'D1' */
-#define	DEVICE_BIGD_1		0x4201		/* 'B1' */
-#define	DEVICE_BIGD_2		0x4202		/* 'B2' */
-
-/************************************************/
-/*		Misc konstants							*/
-/************************************************/
-#define	DALE_MAXDRIVES			4
-#define	BIGD_MAXDRIVES			8
-#define	SECTORSXFER				8
-#define	ATAPI_TRANSFER			8192
-#define	BYTES_PER_SECTOR		512
-#define	DEFAULT_TIMING_MODE		5
-
-/************************************************/
-/*		EEPROM locations						*/
-/************************************************/
-#define	DALE_FLASH_PAGE_SIZE	128				// number of bytes per page
-#define	DALE_FLASH_SIZE			65536L
-
-#define	DALE_FLASH_BIOS			0x00080000L		// BIOS base address
-#define	DALE_FLASH_SETUP		0x00088000L		// SETUP PROGRAM base address offset from BIOS
-#define	DALE_FLASH_RAID			0x00088400L		// RAID signature storage
-#define	DALE_FLASH_FACTORY		0x00089000L		// FACTORY data base address offset from BIOS
-
-#define	DALE_FLASH_BIOS_SIZE	32768U			// size of FLASH BIOS REGION
-
-/************************************************/
-/*		DALE Register address offsets			*/
-/************************************************/
-#define	REG_DATA					0x80
-#define	REG_ERROR					0x84
-#define	REG_SECTOR_COUNT			0x88
-#define	REG_LBA_0					0x8C
-#define	REG_LBA_8					0x90
-#define	REG_LBA_16					0x94
-#define	REG_LBA_24					0x98
-#define	REG_STAT_CMD				0x9C
-#define	REG_STAT_SEL				0xA0
-#define	REG_FAIL					0xB0
-#define	REG_ALT_STAT				0xB8
-#define	REG_DRIVE_ADRS				0xBC
-
-#define	DALE_DATA_SLOW				0x00040000L
-#define	DALE_DATA_MODE2				0x00040000L
-#define	DALE_DATA_MODE3				0x00050000L
-#define	DALE_DATA_MODE4				0x00060000L
-#define	DALE_DATA_MODE5				0x00070000L
-
-#define	BIGD_DATA_SLOW				0x00000000L
-#define	BIGD_DATA_MODE0				0x00000000L
-#define	BIGD_DATA_MODE2				0x00000000L
-#define	BIGD_DATA_MODE3				0x00000008L
-#define	BIGD_DATA_MODE4				0x00000010L
-#define	BIGD_DATA_MODE5				0x00000020L
-
-#define RTR_LOCAL_RANGE				0x000
-#define RTR_LOCAL_REMAP				0x004
-#define RTR_EXP_RANGE				0x010
-#define RTR_EXP_REMAP				0x014
-#define RTR_REGIONS					0x018
-#define RTR_DM_MASK					0x01C
-#define RTR_DM_LOCAL_BASE			0x020
-#define RTR_DM_IO_BASE				0x024
-#define RTR_DM_PCI_REMAP			0x028
-#define RTR_DM_IO_CONFIG			0x02C
-#define RTR_MAILBOX					0x040
-#define RTR_LOCAL_DOORBELL			0x060
-#define RTR_PCI_DOORBELL			0x064
-#define RTR_INT_CONTROL_STATUS 		0x068
-#define RTR_EEPROM_CONTROL_STATUS	0x06C
-
-#define RTR_DMA0_MODE				0x0080
-#define RTR_DMA0_PCI_ADDR			0x0084
-#define RTR_DMA0_LOCAL_ADDR			0x0088
-#define RTR_DMA0_COUNT				0x008C
-#define RTR_DMA0_DESC_PTR			0x0090
-#define RTR_DMA1_MODE				0x0094
-#define RTR_DMA1_PCI_ADDR			0x0098
-#define RTR_DMA1_LOCAL_ADDR			0x009C
-#define RTR_DMA1_COUNT				0x00A0
-#define RTR_DMA1_DESC_PTR			0x00A4
-#define RTR_DMA_COMMAND_STATUS		0x00A8
-#define RTR_DMA_ARB0				0x00AC
-#define RTR_DMA_ARB1				0x00B0
-
-#define RTL_DMA0_MODE				0x00
-#define RTL_DMA0_PCI_ADDR			0x04
-#define RTL_DMA0_LOCAL_ADDR			0x08
-#define RTL_DMA0_COUNT				0x0C
-#define RTL_DMA0_DESC_PTR			0x10
-#define RTL_DMA1_MODE				0x14
-#define RTL_DMA1_PCI_ADDR			0x18
-#define RTL_DMA1_LOCAL_ADDR			0x1C
-#define RTL_DMA1_COUNT				0x20
-#define RTL_DMA1_DESC_PTR			0x24
-#define RTL_DMA_COMMAND_STATUS		0x28
-#define RTL_DMA_ARB0				0x2C
-#define RTL_DMA_ARB1				0x30
-
-/************************************************/
-/*		Dale Scratchpad locations				*/
-/************************************************/
-#define	DALE_CHANNEL_DEVICE_0		0		// device channel locations
-#define	DALE_CHANNEL_DEVICE_1		1
-#define	DALE_CHANNEL_DEVICE_2		2
-#define	DALE_CHANNEL_DEVICE_3		3
-
-#define	DALE_SCRATCH_DEVICE_0		4		// device type codes
-#define	DALE_SCRATCH_DEVICE_1		5
-#define DALE_SCRATCH_DEVICE_2		6
-#define	DALE_SCRATCH_DEVICE_3		7
-
-#define	DALE_RAID_0_STATUS			8
-#define DALE_RAID_1_STATUS			9
-
-#define	DALE_TIMING_MODE			12		// bus master timing mode (2, 3, 4, 5)
-#define	DALE_NUM_DRIVES				13		// number of addressable drives on this board
-#define	DALE_RAID_ON				14 		// RAID status On
-#define	DALE_LAST_ERROR				15		// Last error code from BIOS
-
-/************************************************/
-/*		BigD Scratchpad locations				*/
-/************************************************/
-#define	BIGD_DEVICE_0			0		// device channel locations
-#define	BIGD_DEVICE_1			1
-#define	BIGD_DEVICE_2			2
-#define	BIGD_DEVICE_3			3
-
-#define	BIGD_DEVICE_4			4		// device type codes
-#define	BIGD_DEVICE_5			5
-#define BIGD_DEVICE_6			6
-#define	BIGD_DEVICE_7			7
-
-#define	BIGD_ALARM_IMAGE		11		// ~image of alarm fail register		
-#define	BIGD_TIMING_MODE		12		// bus master timing mode (2, 3, 4, 5)
-#define	BIGD_NUM_DRIVES			13		// number of addressable drives on this board
-#define	BIGD_RAID_ON			14 		// RAID status is on for the whole board
-#define	BIGD_LAST_ERROR			15		// Last error code from BIOS
-
-#define	BIGD_RAID_0_STATUS		16
-#define BIGD_RAID_1_STATUS		17
-#define	BIGD_RAID_2_STATUS		18
-#define	BIGD_RAID_3_STATUS		19
-#define	BIGD_RAID_4_STATUS		20
-#define BIGD_RAID_5_STATUS		21
-#define	BIGD_RAID_6_STATUS		22
-#define	BIGD_RAID_7_STATUS		23
-
-/************************************************/
-/*		Dale cable select bits					*/
-/************************************************/
-#define	SEL_NONE					0x00
-#define	SEL_1						0x01
-#define	SEL_2						0x02
-#define	SEL_3						0x04
-#define	SEL_4						0x08
-#define	SEL_NEW_SPEED_1				0x20
-#define	SEL_COPY					0x40
-#define	SEL_IRQ_OFF					0x80
-
-/************************************************/
-/*		Device/Geometry controls				*/
-/************************************************/
-#define GEOMETRY_NONE	 			0x0				// No device
-#define GEOMETRY_SET				0x1				// Geometry set
-#define	GEOMETRY_LBA				0x2				// Geometry set in default LBA mode
-#define	GEOMETRY_PHOENIX			0x3				// Geometry set in Pheonix BIOS compatibility mode
-
-#define	DEVICE_NONE					0x0				// No device present
-#define	DEVICE_INACTIVE				0x1				// device present but not registered active
-#define	DEVICE_ATAPI				0x2				// ATAPI device (CD_ROM, Tape, Etc...)
-#define	DEVICE_DASD_NONLBA			0x3				// Non LBA incompatible device
-#define	DEVICE_DASD_LBA				0x4				// LBA compatible device
-
-/************************************************/
-/*		BigD fail register bits					*/
-/************************************************/
-#define	FAIL_NONE				0x00
-#define	FAIL_0					0x01
-#define	FAIL_1					0x02
-#define	FAIL_2					0x04
-#define	FAIL_MULTIPLE			0x08
-#define	FAIL_GOOD				0x20
-#define	FAIL_AUDIBLE			0x40
-#define	FAIL_ANY				0x80
-
-/************************************************/
-/*		Setup Structure Definitions				*/
-/************************************************/
-typedef struct		// device setup parameters
-	{
-	UCHAR	geometryControl;	// geometry control flags
-	UCHAR	device;				// device code
-	USHORT	sectors;			// number of sectors per track
-	USHORT	heads;				// number of heads
-	USHORT	cylinders;			// number of cylinders for this device
-	ULONG	blocks;				// number of blocks on device
-	ULONG	realCapacity;		// number of real blocks on this device for drive changed testing
-	} SETUP_DEVICE, *PSETUP_DEVICE;
-
-typedef struct		// master setup structure
-	{
-	USHORT			startupDelay;
-	BOOL			promptBIOS;
-	BOOL			fastFormat;
-	BOOL			shareInterrupt;
-	BOOL			rebootRebuild;
-	USHORT			timingMode;
-	USHORT			spare5;
-	USHORT			spare6;
-	SETUP_DEVICE	setupDevice[BIGD_MAXDRIVES];
-	}	SETUP, *PSETUP;
-
-/************************************************/
-/*		RAID Structure Definitions				*/
-/************************************************/
-typedef	struct
-	{
-	UCHAR	signature;			// 0x55 our mirror signature
-	UCHAR	status;				// current status bits
-	UCHAR	pairIdentifier;		// unique identifier for pair
-	ULONG	reconstructPoint;	// recontruction point for hot reconstruct
-	}	DISK_MIRROR;
-
-typedef struct	DEVICE_RAID1
-	{
-	long		TotalSectors;
-	DISK_MIRROR DiskRaid1;
-	}	DEVICE_RAID1, *PDEVICE_RAID1;
-
-#define	DISK_MIRROR_POSITION	0x01A8
-#define	SIGNATURE				0x55
-
-#define	MASK_SERIAL_NUMBER	0x0FFE			// mask for serial number matching
-#define	MASK_SERIAL_UNIT	0x0001			// mask for unit portion of serial number
-
-// Status bits
-#define	UCBF_MIRRORED		0x0010								// drive has a pair
-#define	UCBF_MATCHED		0x0020								// drive pair is matched
-#define	UCBF_SURVIVOR		0x0040								// this unit is a survivor of a pair
-#define	UCBF_REBUILD		0x0080								// rebuild in progress on this device
-
-// SCSI controls for RAID
-#define	SC_MY_RAID			0xBF			// our special CDB command byte for Win95... interface
-#define	MY_SCSI_QUERY1		0x32			// byte 1 subcommand to query driver for RAID 1 informatation
-#define	MY_SCSI_REBUILD		0x40			// byte 1 subcommand to reconstruct a mirrored pair
-#define MY_SCSI_DEMOFAIL	0x54			// byte 1 subcommand for RAID failure demonstration
-#define	MY_SCSI_ALARMMUTE	0x60			// byte 1 subcommand to mute any alarm currently on
-
-/************************************************/
-/*		Timeout konstants		 				*/
-/************************************************/
-#define	TIMEOUT_READY				100			// 100 mSec
-#define	TIMEOUT_DRQ					300			// 300 mSec
-#define	TIMEOUT_DATA				(3 * HZ)	// 3 seconds
-
-/************************************************/
-/*		Misc. macros			 				*/
-/************************************************/
-#define ANY2SCSI(up, p)					\
-((UCHAR *)up)[0] = (((ULONG)(p)) >> 8);	\
-((UCHAR *)up)[1] = ((ULONG)(p));
-
-#define SCSI2LONG(up)					\
-( (((long)*(((UCHAR *)up))) << 16)		\
-+ (((long)(((UCHAR *)up)[1])) << 8)		\
-+ ((long)(((UCHAR *)up)[2])) )
-
-#define XANY2SCSI(up, p)				\
-((UCHAR *)up)[0] = ((long)(p)) >> 24;	\
-((UCHAR *)up)[1] = ((long)(p)) >> 16;	\
-((UCHAR *)up)[2] = ((long)(p)) >> 8;	\
-((UCHAR *)up)[3] = ((long)(p));
-
-#define XSCSI2LONG(up)					\
-( (((long)(((UCHAR *)up)[0])) << 24)	\
-+ (((long)(((UCHAR *)up)[1])) << 16)	\
-+ (((long)(((UCHAR *)up)[2])) <<  8)	\
-+ ((long)(((UCHAR *)up)[3])) )
-
-#define	SelectSpigot(padapter,spigot)	outb_p (spigot, padapter->regStatSel)
-#define WriteCommand(padapter,cmd)		outb_p (cmd, padapter->regStatCmd)
-#define	AtapiDevice(padapter,b)			outb_p (b, padapter->regLba24);
-#define	AtapiCountLo(padapter,b)		outb_p (b, padapter->regLba8)
-#define	AtapiCountHi(padapter,b)		outb_p (b, padapter->regLba16)
-
-/************************************************/
-/*		SCSI CDB operation codes 				*/
-/************************************************/
-#define SCSIOP_TEST_UNIT_READY		0x00
-#define SCSIOP_REZERO_UNIT			0x01
-#define SCSIOP_REWIND				0x01
-#define SCSIOP_REQUEST_BLOCK_ADDR	0x02
-#define SCSIOP_REQUEST_SENSE		0x03
-#define SCSIOP_FORMAT_UNIT			0x04
-#define SCSIOP_READ_BLOCK_LIMITS	0x05
-#define SCSIOP_REASSIGN_BLOCKS		0x07
-#define SCSIOP_READ6				0x08
-#define SCSIOP_RECEIVE				0x08
-#define SCSIOP_WRITE6				0x0A
-#define SCSIOP_PRINT				0x0A
-#define SCSIOP_SEND					0x0A
-#define SCSIOP_SEEK6				0x0B
-#define SCSIOP_TRACK_SELECT			0x0B
-#define SCSIOP_SLEW_PRINT			0x0B
-#define SCSIOP_SEEK_BLOCK			0x0C
-#define SCSIOP_PARTITION			0x0D
-#define SCSIOP_READ_REVERSE			0x0F
-#define SCSIOP_WRITE_FILEMARKS		0x10
-#define SCSIOP_FLUSH_BUFFER			0x10
-#define SCSIOP_SPACE				0x11
-#define SCSIOP_INQUIRY				0x12
-#define SCSIOP_VERIFY6				0x13
-#define SCSIOP_RECOVER_BUF_DATA		0x14
-#define SCSIOP_MODE_SELECT			0x15
-#define SCSIOP_RESERVE_UNIT			0x16
-#define SCSIOP_RELEASE_UNIT			0x17
-#define SCSIOP_COPY					0x18
-#define SCSIOP_ERASE				0x19
-#define SCSIOP_MODE_SENSE			0x1A
-#define SCSIOP_START_STOP_UNIT		0x1B
-#define SCSIOP_STOP_PRINT			0x1B
-#define SCSIOP_LOAD_UNLOAD			0x1B
-#define SCSIOP_RECEIVE_DIAGNOSTIC	0x1C
-#define SCSIOP_SEND_DIAGNOSTIC		0x1D
-#define SCSIOP_MEDIUM_REMOVAL		0x1E
-#define SCSIOP_READ_CAPACITY		0x25
-#define SCSIOP_READ					0x28
-#define SCSIOP_WRITE				0x2A
-#define SCSIOP_SEEK					0x2B
-#define SCSIOP_LOCATE				0x2B
-#define SCSIOP_WRITE_VERIFY			0x2E
-#define SCSIOP_VERIFY				0x2F
-#define SCSIOP_SEARCH_DATA_HIGH		0x30
-#define SCSIOP_SEARCH_DATA_EQUAL	0x31
-#define SCSIOP_SEARCH_DATA_LOW		0x32
-#define SCSIOP_SET_LIMITS			0x33
-#define SCSIOP_READ_POSITION		0x34
-#define SCSIOP_SYNCHRONIZE_CACHE	0x35
-#define SCSIOP_COMPARE				0x39
-#define SCSIOP_COPY_COMPARE			0x3A
-#define SCSIOP_WRITE_DATA_BUFF		0x3B
-#define SCSIOP_READ_DATA_BUFF		0x3C
-#define SCSIOP_CHANGE_DEFINITION	0x40
-#define SCSIOP_READ_SUB_CHANNEL		0x42
-#define SCSIOP_READ_TOC				0x43
-#define SCSIOP_READ_HEADER			0x44
-#define SCSIOP_PLAY_AUDIO			0x45
-#define SCSIOP_PLAY_AUDIO_MSF		0x47
-#define SCSIOP_PLAY_TRACK_INDEX		0x48
-#define SCSIOP_PLAY_TRACK_RELATIVE	0x49
-#define SCSIOP_PAUSE_RESUME			0x4B
-#define SCSIOP_LOG_SELECT			0x4C
-#define SCSIOP_LOG_SENSE			0x4D
-#define SCSIOP_MODE_SELECT10		0x55
-#define SCSIOP_MODE_SENSE10			0x5A
-#define SCSIOP_LOAD_UNLOAD_SLOT		0xA6
-#define SCSIOP_MECHANISM_STATUS		0xBD
-#define SCSIOP_READ_CD				0xBE
-
-// IDE command definitions
-#define IDE_COMMAND_ATAPI_RESET		0x08
-#define IDE_COMMAND_READ			0x20
-#define IDE_COMMAND_WRITE			0x30
-#define IDE_COMMAND_RECALIBRATE		0x10
-#define IDE_COMMAND_SEEK			0x70
-#define IDE_COMMAND_SET_PARAMETERS	0x91
-#define IDE_COMMAND_VERIFY			0x40
-#define IDE_COMMAND_ATAPI_PACKET	0xA0
-#define IDE_COMMAND_ATAPI_IDENTIFY	0xA1
-#define	IDE_CMD_READ_MULTIPLE		0xC4
-#define	IDE_CMD_WRITE_MULTIPLE		0xC5
-#define	IDE_CMD_SET_MULTIPLE		0xC6
-#define IDE_COMMAND_IDENTIFY		0xEC
-
-// IDE status definitions
-#define IDE_STATUS_ERROR			0x01
-#define IDE_STATUS_INDEX			0x02
-#define IDE_STATUS_CORRECTED_ERROR	0x04
-#define IDE_STATUS_DRQ				0x08
-#define IDE_STATUS_DSC				0x10
-#define	IDE_STATUS_WRITE_FAULT		0x20
-#define IDE_STATUS_DRDY				0x40
-#define IDE_STATUS_BUSY				0x80
-
-typedef struct _ATAPI_STATUS
-	{
-	CHAR	check		:1;
-	CHAR	reserved1	:1;
-	CHAR	corr		:1;
-	CHAR	drq			:1;
-	CHAR	dsc			:1;
-	CHAR	reserved2	:1;
-	CHAR	drdy		:1;
-	CHAR	bsy			:1;
-	}	ATAPI_STATUS;
-
-typedef struct _ATAPI_REASON
-	{
-	CHAR	cod			:1;
-	CHAR	io			:1;
-	CHAR	reserved1	:6;
-	}	ATAPI_REASON;
-
-typedef struct _ATAPI_ERROR
-	{
-	CHAR	ili			:1;
-	CHAR	eom			:1;
-	CHAR	abort		:1;
-	CHAR	mcr			:1;
-	CHAR	senseKey	:4;
-	}	ATAPI_ERROR;
-
-// IDE error definitions
-#define	IDE_ERROR_AMNF				0x01
-#define	IDE_ERROR_TKONF				0x02
-#define	IDE_ERROR_ABRT				0x04
-#define	IDE_ERROR_MCR				0x08
-#define	IDE_ERROR_IDFN				0x10
-#define	IDE_ERROR_MC				0x20
-#define	IDE_ERROR_UNC				0x40
-#define	IDE_ERROR_BBK				0x80
-
-// SCSI read capacity structure
-typedef	struct _READ_CAPACITY_DATA
-	{
-	ULONG blks;				/* total blocks (converted to little endian) */
-	ULONG blksiz;			/* size of each (converted to little endian) */
-	}	READ_CAPACITY_DATA, *PREAD_CAPACITY_DATA;
-
-// SCSI inquiry data
-typedef struct _INQUIRYDATA
-	{
-	UCHAR DeviceType			:5;
-	UCHAR DeviceTypeQualifier	:3;
-	UCHAR DeviceTypeModifier	:7;
-	UCHAR RemovableMedia		:1;
-    UCHAR Versions;
-    UCHAR ResponseDataFormat;
-    UCHAR AdditionalLength;
-    UCHAR Reserved[2];
-	UCHAR SoftReset				:1;
-	UCHAR CommandQueue			:1;
-	UCHAR Reserved2				:1;
-	UCHAR LinkedCommands		:1;
-	UCHAR Synchronous			:1;
-	UCHAR Wide16Bit				:1;
-	UCHAR Wide32Bit				:1;
-	UCHAR RelativeAddressing	:1;
-    UCHAR VendorId[8];
-    UCHAR ProductId[16];
-    UCHAR ProductRevisionLevel[4];
-    UCHAR VendorSpecific[20];
-    UCHAR Reserved3[40];
-	}	INQUIRYDATA, *PINQUIRYDATA;
-
-// IDE IDENTIFY data
-#pragma pack (1)
-typedef struct _IDENTIFY_DATA
-	{
-    USHORT	GeneralConfiguration;		//  0
-    USHORT	NumberOfCylinders;			//  1
-    USHORT	Reserved1;					//  2
-    USHORT	NumberOfHeads;				//  3
-    USHORT	UnformattedBytesPerTrack;	//  4
-    USHORT	UnformattedBytesPerSector;	//  5
-    USHORT	SectorsPerTrack;			//  6
-	USHORT	NumBytesISG;				//  7 Byte Len - inter-sector gap
-	USHORT	NumBytesSync;				//  8          - sync field
-	USHORT	NumWordsVUS;				//  9 Len - Vendor Unique Info
-    USHORT	SerialNumber[10];			// 10
-    USHORT	BufferType;					// 20
-    USHORT	BufferSectorSize;			// 21
-    USHORT	NumberOfEccBytes;			// 22
-    USHORT	FirmwareRevision[4];		// 23
-    USHORT	ModelNumber[20];			// 27
-	USHORT	NumSectorsPerInt	:8;		// 47 Multiple Mode - Sec/Blk
-	USHORT	Reserved2			:8;		// 47
-	USHORT	DoubleWordMode;				// 48 flag for double word mode capable
-	USHORT	VendorUnique1		:8;		// 49
-	USHORT	SupportDMA			:1;		// 49 DMA supported
-	USHORT	SupportLBA			:1;		// 49 LBA supported
-	USHORT	SupportIORDYDisable	:1;		// 49 IORDY can be disabled
-	USHORT	SupportIORDY		:1;		// 49 IORDY supported
-	USHORT	ReservedPsuedoDMA	:1;		// 49 reserved for pseudo DMA mode support
-	USHORT	Reserved3			:3;		// 49
-	USHORT	Reserved4;					// 50
-	USHORT	Reserved5			:8;		// 51 Transfer Cycle Timing - PIO
-	USHORT	PIOCycleTime		:8;		// 51 Transfer Cycle Timing - PIO
-	USHORT	Reserved6			:8;		// 52                       - DMA
-	USHORT	DMACycleTime		:8;		// 52                       - DMA
-	USHORT	Valid_54_58			:1;		// 53 words 54 - 58 are valid
-	USHORT	Valid_64_70			:1;		// 53 words 64 - 70 are valid
-	USHORT	Reserved7			:14;	// 53
-	USHORT	LogNumCyl;					// 54 Current Translation - Num Cyl
-	USHORT	LogNumHeads;				// 55                       Num Heads
-	USHORT	LogSectorsPerTrack;			// 56                       Sec/Trk
-	ULONG	LogTotalSectors;			// 57                       Total Sec
-	USHORT	CurrentNumSecPerInt	:8;		// 59 current setting for number of sectors per interrupt
-	USHORT	ValidNumSecPerInt	:1;		// 59 Current setting is valid for number of sectors per interrupt
-	USHORT	Reserved8			:7;		// 59
-	ULONG	LBATotalSectors;			// 60 LBA Mode - Sectors
-	USHORT	DMASWordFlags;				// 62
-	USHORT	DMAMWordFlags;				// 63
-	USHORT	AdvancedPIOSupport  :8;		// 64 Flow control PIO transfer modes supported
-	USHORT	Reserved9			:8;		// 64
-	USHORT	MinMultiDMACycle;			// 65 minimum multiword DMA transfer cycle time per word
-	USHORT	RecomendDMACycle;			// 66 Manufacturer's recommende multiword DMA transfer cycle time
-	USHORT	MinPIOCycleWithoutFlow;		// 67 Minimum PIO transfer cycle time without flow control
-	USHORT	MinPIOCylceWithFlow;		// 68 Minimum PIO transfer cycle time with IORDY flow control
-	USHORT	ReservedSpace[256-69];		// 69
-	}	IDENTIFY_DATA, *PIDENTIFY_DATA;
-
-// ATAPI configuration bits
-typedef struct _ATAPI_GENERAL_0
-	{
-	USHORT	CmdPacketSize		:2;		// Command packet size
-	USHORT	Reserved1			:3;
-	USHORT	CmdDrqType			:2;
-	USHORT	Removable			:1;
-	USHORT	DeviceType			:5;
-	USHORT	Reserved2			:1;
-	USHORT	ProtocolType		:2;
-	}	ATAPI_GENERAL_0;
-
-#pragma pack ()
diff --git a/drivers/scsi/psi_roy.h b/drivers/scsi/psi_roy.h
deleted file mode 100644
--- a/drivers/scsi/psi_roy.h
+++ /dev/null
@@ -1,331 +0,0 @@
-/****************************************************************************
- * Perceptive Solutions, Inc. PCI-2000 device driver for Linux.
- *
- * psi_roy.h - Linux Host Driver for PCI-2000 IntelliCache SCSI Adapters
- *
- * Copyright (c) 1997-1999 Perceptive Solutions, Inc.
- * All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that redistributions of source
- * code retain the above copyright notice and this comment without
- * modification.
- *
- * Technical updates and product information at:
- *  http://www.psidisk.com
- *
- * Please send questions, comments, bug reports to:
- *  tech@psidisk.com Technical Support
- *
- ****************************************************************************/
-
-#ifndef	ROY_HOST
-#define	ROY_HOST
-
-/************************************************/
-/*		PCI setup								*/
-/************************************************/
-#define	VENDOR_PSI			0x1256
-#define	DEVICE_ROY_1		0x5201		/* 'R1' */
-
-/************************************************/
-/*		controller constants					*/
-/************************************************/
-#define MAXADAPTER			4			// Increase this and the sizes of the arrays below, if you need more.
-#define	MAX_BUS				2
-#define	MAX_UNITS			16
-#define	TIMEOUT_COMMAND		400			// number of milliSecondos for command busy timeout
-
-/************************************************/
-/*		I/O address offsets						*/
-/************************************************/
-#define RTR_MAILBOX						0x040
-#define RTR_LOCAL_DOORBELL				0x060
-#define RTR_PCI_DOORBELL				0x064
-
-/************************************************/
-/*												*/
-/*			Host command codes					*/
-/*												*/
-/************************************************/
-#define	CMD_READ_CHS		0x01		/* read sectors as specified (CHS mode) */
-#define	CMD_READ			0x02		/* read sectors as specified (RBA mode) */
-#define	CMD_READ_SG			0x03		/* read sectors using scatter/gather list */
-#define	CMD_WRITE_CHS		0x04		/* write sectors as specified (CHS mode) */
-#define	CMD_WRITE			0x05		/* write sectors as specified (RBA mode) */
-#define	CMD_WRITE_SG		0x06		/* write sectors using scatter/gather list (LBA mode) */
-#define	CMD_READ_CHS_SG		0x07		/* read sectors using scatter/gather list (CHS mode) */
-#define	CMD_WRITE_CHS_SG	0x08		/* write sectors using scatter/gather list (CHS mode) */
-#define	CMD_VERIFY_CHS		0x09		/* verify data on sectors as specified (CHS mode) */
-#define	CMD_VERIFY			0x0A		/* verify data on sectors as specified (RBA mode) */
-#define	CMD_DASD_CDB		0x0B		/* process CDB for a DASD device */
-#define	CMD_DASD_CDB_SG		0x0C		/* process CDB for a DASD device with scatter/gather */
-
-#define	CMD_READ_ABS		0x10		/* read absolute disk */
-#define	CMD_WRITE_ABS		0x11		/* write absolute disk */
-#define	CMD_VERIFY_ABS		0x12		/* verify absolute disk */
-#define	CMD_TEST_READY		0x13		/* test unit ready and return status code */
-#define	CMD_LOCK_DOOR		0x14		/* lock device door */
-#define	CMD_UNLOCK_DOOR		0x15		/* unlock device door */
-#define	CMD_EJECT_MEDIA		0x16		/* eject the media */
-#define	CMD_UPDATE_CAP		0x17		/* update capacity information */
-#define	CMD_TEST_PRIV		0x18		/* test and setup private format media */
-
-
-#define	CMD_SCSI_THRU		0x30		/* SCSI pass through CDB */
-#define	CMD_SCSI_THRU_SG	0x31		/* SCSI pass through CDB with scatter/gather */
-#define	CMD_SCSI_REQ_SENSE	0x32		/* SCSI pass through request sense after check condition */
-
-#define	CMD_DASD_RAID_RQ	0x35		/* request DASD RAID drive data */
-#define	CMD_DASD_RAID_RQ0	0x31			/* byte 1 subcommand to query for RAID 0 informatation */
-#define	CMD_DASD_RAID_RQ1	0x32			/* byte 1 subcommand to query for RAID 1 informatation */
-#define	CMD_DASD_RAID_RQ5	0x33			/* byte 1 subcommand to query for RAID 5 informatation */
-
-#define	CMD_DASD_SCSI_INQ	0x36		/* do DASD inquire and return in SCSI format */
-#define	CMD_DASD_CAP		0x37		/* read DASD capacity */
-#define	CMD_DASD_INQ		0x38		/* do DASD inquire for type data and return SCSI/EIDE inquiry */
-#define	CMD_SCSI_INQ		0x39		/* do SCSI inquire */
-#define	CMD_READ_SETUP		0x3A		/* Get setup structures from controller */
-#define	CMD_WRITE_SETUP		0x3B		/* Put setup structures in controller and burn in flash */
-#define	CMD_READ_CONFIG		0x3C		/* Get the entire configuration and setup structures */
-#define	CMD_WRITE_CONFIG	0x3D		/* Put the entire configuration and setup structures in flash */
-
-#define	CMD_TEXT_DEVICE		0x3E		/* obtain device text */
-#define	CMD_TEXT_SIGNON		0x3F		/* get sign on banner */
-
-#define	CMD_QUEUE			0x40		/* any command below this generates a queue tag interrupt to host*/
-
-#define	CMD_PREFETCH		0x40		/* prefetch sectors as specified */
-#define	CMD_TEST_WRITE		0x41		/* Test a device for write protect */
-#define	CMD_LAST_STATUS		0x42		/* get last command status and error data*/
-#define	CMD_ABORT			0x43		/* abort command as specified */
-#define	CMD_ERROR			0x44		/* fetch error code from a tagged op */
-#define	CMD_DONE			0x45		/* done with operation */
-#define	CMD_DIAGNOSTICS		0x46		/* execute controller diagnostics and wait for results */
-#define	CMD_FEATURE_MODE	0x47		/* feature mode control word */
-#define	CMD_DASD_INQUIRE	0x48		/* inquire as to DASD SCSI device (32 possible) */
-#define	CMD_FEATURE_QUERY	0x49		/* query the feature control word */
-#define	CMD_DASD_EJECT		0x4A		/* Eject removable media for DASD type */
-#define	CMD_DASD_LOCK		0x4B		/* Lock removable media for DASD type */
-#define	CMD_DASD_TYPE		0x4C		/* obtain DASD device type */
-#define	CMD_NUM_DEV			0x4D		/* obtain the number of devices connected to the controller */
-#define	CMD_GET_PARMS		0x4E		/* obtain device parameters */
-#define	CMD_SPECIFY			0x4F		/* specify operating system for scatter/gather operations */
-
-#define	CMD_RAID_GET_DEV	0x50		/* read RAID device geometry */
-#define CMD_RAID_READ		0x51		/* read RAID 1 parameter block */
-#define	CMD_RAID_WRITE		0x52		/* write RAID 1 parameter block */
-#define	CMD_RAID_LITEUP		0x53		/* Light up the drive light for identification */
-#define	CMD_RAID_REBUILD	0x54		/* issue a RAID 1 pair rebuild */
-#define	CMD_RAID_MUTE		0x55		/* mute RAID failure alarm */
-#define	CMD_RAID_FAIL		0x56		/* induce a RAID failure */
-#define	CMD_RAID_STATUS		0x57		/* get status of RAID pair */
-#define	CMD_RAID_STOP		0x58		/* stop any reconstruct in progress */
-#define CMD_RAID_START		0x59		/* start reconstruct */
-#define	CMD_RAID0_READ		0x5A		/* read RAID 0 parameter block */
-#define	CMD_RAID0_WRITE		0x5B		/* write RAID 0 parameter block */
-#define	CMD_RAID5_READ		0x5C		/* read RAID 5 parameter block */
-#define	CMD_RAID5_WRITE		0x5D		/* write RAID 5 parameter block */
-
-#define	CMD_ERASE_TABLES	0x5F		/* erase partition table and RAID signatutures */
-
-#define	CMD_SCSI_GET		0x60		/* get SCSI pass through devices */
-#define	CMD_SCSI_TIMEOUT	0x61		/* set SCSI pass through timeout */
-#define	CMD_SCSI_ERROR		0x62		/* get SCSI pass through request sense length and residual data count */
-#define	CMD_GET_SPARMS		0x63		/* get SCSI bus and user parms */
-#define	CMD_SCSI_ABORT		0x64		/* abort by setting time-out to zero */
-
-#define	CMD_CHIRP_CHIRP		0x77		/* make a chirp chirp sound */
-#define	CMD_GET_LAST_DONE	0x78		/* get tag of last done in progress */
-#define	CMD_GET_FEATURES	0x79		/* get feature code and ESN */
-#define CMD_CLEAR_CACHE		0x7A		/* Clear cache on specified device */
-#define	CMD_BIOS_TEST		0x7B		/* Test whether or not to load BIOS */
-#define	CMD_WAIT_FLUSH		0x7C		/* wait for cache flushed and invalidate read cache */
-#define	CMD_RESET_BUS		0x7D		/* reset the SCSI bus */
-#define	CMD_STARTUP_QRY		0x7E		/* startup in progress query */
-#define	CMD_RESET			0x7F		/* reset the controller */
-
-#define	CMD_RESTART_RESET	0x80		/* reload and restart the controller at any reset issued */
-#define	CMD_SOFT_RESET		0x81		/* do a soft reset NOW! */
-
-/************************************************/
-/*												*/
-/*				Host return errors				*/
-/*												*/
-/************************************************/
-#define	ERR08_TAGGED		0x80		/* doorbell error ored with tag */
-
-#define	ERR16_NONE			0x0000		/* no errors */
-#define	ERR16_SC_COND_MET	0x0004		/* SCSI status - Condition Met */
-#define	ERR16_CMD			0x0101		/* command error */
-#define	ERR16_SC_CHECK_COND	0x0002		/* SCSI status - Check Condition */
-#define	ERR16_CMD_NOT		0x0201		/* command not supported */
-#define ERR16_NO_DEVICE     0x0301		/* invalid device selection */
-#define	ERR16_SECTOR		0x0202		/* bad sector */
-#define	ERR16_PROTECT		0x0303		/* write protected */
-#define	ERR16_NOSECTOR		0x0404		/* sector not found */
-#define	ERR16_MEDIA			0x0C0C		/* invalid media */
-#define	ERR16_CONTROL		0x2020		/* controller error */
-#define	ERR16_CONTROL_DMA	0x2120		/* controller DMA engine error */
-#define	ERR16_NO_ALARM		0x2220		/* alarm is not active */
-#define	ERR16_OP_BUSY		0x2320		/* operation busy */
-#define	ERR16_SEEK			0x4040		/* seek failure */
-#define	ERR16_DEVICE_FAIL	0x4140		/* device has failed */
-#define ERR16_TIMEOUT		0x8080		/* timeout error */
-#define	ERR16_DEV_NOT_READY	0xAAAA		/* drive not ready */
-#define	ERR16_UNDEFINED		0xBBBB		/* undefined error */
-#define	ERR16_WRITE_FAULT	0xCCCC		/* write fault */
-#define ERR16_INVALID_DEV	0x4001		/* invalid device access */
-#define	ERR16_DEVICE_BUSY	0x4002		/* device is busy */
-#define	ERR16_MEMORY		0x4003		/* device pass thru requires too much memory */
-#define	ERR16_NO_FEATURE	0x40FA		/* feature no implemented */
-#define	ERR16_NOTAG			0x40FD		/* no tag space available */
-#define	ERR16_NOT_READY		0x40FE		/* controller not ready error */
-#define	ERR16_SETUP_FLASH	0x5050		/* error when writing setup to flash memory */
-#define	ERR16_SETUP_SIZE	0x5051		/* setup block size error */
-#define	ERR16_SENSE			0xFFFF		/* sense opereration failed */
-#define	ERR16_SC_BUSY		0x0008		/* SCSI status - Busy */
-#define	ERR16_SC_RES_CONFL	0x0018		/* SCSI status - Reservation Conflict */
-#define	ERR16_SC_CMD_TERM	0x0022		/* SCSI status - Command Terminated */
-#define	ERR16_SC_OTHER		0x00FF		/* SCSI status - not recognized (any value masked) */
-#define	ERR16_MEDIA_CHANGED	0x8001		/* devices media has been changed */
-
-#define	ERR32_NONE			0x00000000	/* no errors */
-#define	ERR32_SC_COND_MET	0x00000004	/* SCSI status - Condition Met */
-#define	ERR32_CMD			0x00010101	/* command error */
-#define	ERR32_SC_CHECK_COND	0x00020002	/* SCSI status - Check Condition */
-#define	ERR32_CMD_NOT		0x00030201	/* command not supported */
-#define ERR32_NO_DEVICE     0x00040301	/* invalid device selection */
-#define	ERR32_SECTOR		0x00050202	/* bad sector */
-#define	ERR32_PROTECT		0x00060303	/* write protected */
-#define	ERR32_NOSECTOR		0x00070404	/* sector not found */
-#define	ERR32_MEDIA			0x00080C0C	/* invalid media */
-#define	ERR32_CONTROL		0x00092020	/* controller error */
-#define	ERR32_CONTROL_DMA	0x000A2120	/* Controller DMA error */
-#define	ERR32_NO_ALARM		0x000B2220 	/* alarm is not active */
-#define	ERR32_OP_BUSY		0x000C2320	/* operation busy */
-#define	ERR32_SEEK			0x000D4040	/* seek failure */
-#define	ERR32_DEVICE_FAIL	0x000E4140	/* device has failed */
-#define ERR32_TIMEOUT		0x000F8080	/* timeout error */
-#define	ERR32_DEV_NOT_READY	0x0010AAAA	/* drive not ready */
-#define	ERR32_UNDEFINED		0x0011BBBB	/* undefined error */
-#define	ERR32_WRITE_FAULT	0x0012CCCC	/* write fault */
-#define ERR32_INVALID_DEV	0x00134001	/* invalid device access */
-#define	ERR32_DEVICE_BUSY	0x00144002	/* device is busy */
-#define	ERR32_MEMORY		0x00154003	/* device pass thru requires too much memory */
-#define	ERR32_NO_FEATURE	0x001640FA	/* feature no implemented */
-#define	ERR32_NOTAG			0x001740FD	/* no tag space available */
-#define	ERR32_NOT_READY		0x001840FE	/* controller not ready error */
-#define	ERR32_SETUP_FLASH	0x00195050	/* error when writing setup to flash memory */
-#define	ERR32_SETUP_SIZE	0x001A5051	/* setup block size error */
-#define	ERR32_SENSE			0x001BFFFF	/* sense opereration failed */
-#define	ERR32_SC_BUSY		0x001C0008	/* SCSI status - Busy */
-#define	ERR32_SC_RES_CONFL	0x001D0018	/* SCSI status - Reservation Conflict */
-#define	ERR32_SC_CMD_TERM	0x001E0022	/* SCSI status - Command Terminated */
-#define	ERR32_SC_OTHER		0x001F00FF	/* SCSI status - not recognized (any value masked) */
-#define	ERR32_MEDIA_CHANGED	0x00208001	/* devices media has been changed */
-
-/************************************************/
-/*												*/
-/*	Host Operating System specification codes	*/
-/*												*/
-/************************************************/
-#define	SPEC_INTERRUPT		0x80		/* specification requires host interrupt */
-#define	SPEC_BACKWARD_SG	0x40		/* specification requires scatter/gather items reversed */
-#define	SPEC_DOS_BLOCK		0x01		/* DOS DASD blocking on pass through */
-#define	SPEC_OS2_V3			0x02		/* OS/2 Warp */
-#define	SPCE_SCO_3242		0x04		/* SCO 3.4.2.2 */
-#define	SPEC_QNX_4X			0x05		/* QNX 4.XX */
-#define	SPEC_NOVELL_NWPA	0x08		/* Novell NWPA scatter/gather support */
-
-/************************************************/
-/*												*/
-/*	Inquire structures							*/
-/*												*/
-/************************************************/
-typedef	struct	_CNT_SCSI_INQ
-	{
-	UCHAR	devt;						/* 00: device type */
-	UCHAR	devtm;						/* 01: device type modifier */
-	UCHAR	svers;						/* 02: SCSI version */
-	UCHAR	rfmt;						/* 03: response data format */
-	UCHAR	adlen;						/* 04: additional length of data */
-	UCHAR	res1;						/* 05: */
-	UCHAR	res2;						/* 06: */
-	UCHAR	fncs;						/* 07: functional capabilities */
-	UCHAR	vid[8];						/* 08: vendor ID */
-	UCHAR	pid[16];					/* 10: product ID */
-	UCHAR	rev[4];						/* 20: product revision */
-	}	CNT_SCSI_INQ;
-
-typedef	struct	_CNT_IDE_INQ
-	{
-	USHORT	GeneralConfiguration;		/* 00 */
-	USHORT	NumberOfCylinders;			/* 02 */
-	USHORT	Reserved1;					/* 04 */
-	USHORT	NumberOfHeads;				/* 06 */
-	USHORT	UnformattedBytesPerTrack;	/* 08 */
-	USHORT	UnformattedBytesPerSector;	/* 0A */
-	USHORT	SectorsPerTrack;			/* 0C */
-	USHORT	VendorUnique1[3];			/* 0E */
-	USHORT	SerialNumber[10];			/* 14 */
-	USHORT	BufferType;					/* 28 */
-	USHORT	BufferSectorSize;			/* 2A */
-	USHORT	NumberOfEccBytes;			/* 2C */
-	USHORT	FirmwareRevision[4];		/* 2E */
-	USHORT	ModelNumber[20];			/* 36 */
-	UCHAR	MaximumBlockTransfer;		/* 5E */
-	UCHAR	VendorUnique2;				/* 5F */
-	USHORT	DoubleWordIo;				/* 60 */
-	USHORT	Capabilities;				/* 62 */
-	USHORT	Reserved2;					/* 64 */
-	UCHAR	VendorUnique3;				/* 66 */
-	UCHAR	PioCycleTimingMode;			/* 67 */
-	UCHAR	VendorUnique4;				/* 68 */
-	UCHAR	DmaCycleTimingMode;			/* 69 */
-	USHORT	TranslationFieldsValid;		/* 6A */
-	USHORT	NumberOfCurrentCylinders;	/* 6C */
-	USHORT	NumberOfCurrentHeads;		/* 6E */
-	USHORT	CurrentSectorsPerTrack;		/* 70 */
-	ULONG	CurrentSectorCapacity;		/* 72 */
-	}	CNT_IDE_INQ;
-
-typedef struct	_DASD_INQUIRE
-	{
-	ULONG	type;						/* 0 = SCSI, 1 = IDE */
-	union
-		{
-		CNT_SCSI_INQ	scsi;			/* SCSI inquire data */
-		CNT_IDE_INQ		ide;			/* IDE inquire data */
-		}	inq;
-	}	DASD_INQUIRE;
-
-/************************************************/
-/*												*/
-/*	Device Codes								*/
-/*												*/
-/************************************************/
-#define DEVC_DASD			0x00		/* Direct-access Storage Device */
-#define DEVC_SEQACESS		0x01		/* Sequential-access device */
-#define DEVC_PRINTER		0x02		/* Printer device */
-#define DEVC_PROCESSOR		0x03		/* Processor device */
-#define DEVC_WRITEONCE		0x04		/* Write-once device */
-#define DEVC_CDROM			0x05		/* CD-ROM device */
-#define DEVC_SCANNER		0x06		/* Scanner device */
-#define DEVC_OPTICAL		0x07		/* Optical memory device */
-#define DEVC_MEDCHGR		0x08		/* Medium changer device */
-#define	DEVC_DASD_REMOVABLE	0x80		/* Direct-access storage device, Removable */
-#define	DEVC_NONE			0xFF		/* no device */
-
-// SCSI controls for RAID
-#define	SC_MY_RAID			0xBF			// our special CDB command byte for Win95... interface
-#define	MY_SCSI_QUERY0		0x31			// byte 1 subcommand to query driver for RAID 0 informatation
-#define	MY_SCSI_QUERY1		0x32			// byte 1 subcommand to query driver for RAID 1 informatation
-#define	MY_SCSI_QUERY5		0x33			// byte 1 subcommand to query driver for RAID 5 informatation
-#define	MY_SCSI_REBUILD		0x40			// byte 1 subcommand to reconstruct a mirrored pair
-#define MY_SCSI_DEMOFAIL	0x54			// byte 1 subcommand for RAID failure demonstration
-#define	MY_SCSI_ALARMMUTE	0x60			// byte 1 subcommand to mute any alarm currently on
-
-
-#endif
-
diff --git a/drivers/scsi/ql1040_fw.h b/drivers/scsi/ql1040_fw.h
--- a/drivers/scsi/ql1040_fw.h
+++ b/drivers/scsi/ql1040_fw.h
@@ -25,17 +25,17 @@
  */
 
 /*
- *	Firmware Version 7.65.00 (14:17 Jul 20, 1999)
+ *	Firmware Version 7.65.06 (14:38 Jan 07, 2002)
  */
 
-static unsigned char firmware_version[] = {7,65,0};
+static unsigned char firmware_version[] = {7,65,6};
 
-#define FW_VERSION_STRING "7.65.0"
+#define FW_VERSION_STRING "7.65.06"
 
 static unsigned short risc_code_addr01 = 0x1000 ;
 
 static unsigned short risc_code01[] = { 
-	0x0078, 0x103a, 0x0000, 0x4057, 0x0000, 0x2043, 0x4f50, 0x5952,
+	0x0078, 0x103a, 0x0000, 0x4158, 0x0000, 0x2043, 0x4f50, 0x5952,
 	0x4947, 0x4854, 0x2031, 0x3939, 0x3520, 0x514c, 0x4f47, 0x4943,
 	0x2043, 0x4f52, 0x504f, 0x5241, 0x5449, 0x4f4e, 0x2049, 0x5350,
 	0x3130, 0x3230, 0x2049, 0x2f54, 0x2046, 0x6972, 0x6d77, 0x6172,
@@ -45,7 +45,7 @@ static unsigned short risc_code01[] = { 
 	0x3031, 0x2024, 0x2001, 0x04fd, 0x2004, 0xa082, 0x0005, 0x0048,
 	0x1045, 0x0038, 0x104b, 0x0078, 0x1047, 0x0028, 0x104b, 0x20b9,
 	0x1212, 0x0078, 0x104d, 0x20b9, 0x2222, 0x20c1, 0x0008, 0x2071,
-	0x0010, 0x70c3, 0x0004, 0x20c9, 0x77ff, 0x2089, 0x1186, 0x70c7,
+	0x0010, 0x70c3, 0x0004, 0x20c9, 0x78ff, 0x2089, 0x1186, 0x70c7,
 	0x4953, 0x70cb, 0x5020, 0x70cf, 0x2020, 0x70d3, 0x0007, 0x3f00,
 	0x70d6, 0x20c1, 0x0008, 0x2019, 0x0000, 0x2009, 0xfeff, 0x2100,
 	0x200b, 0xa5a5, 0xa1ec, 0x7fff, 0x2d64, 0x206b, 0x0a0a, 0xaddc,
@@ -59,62 +59,62 @@ static unsigned short risc_code01[] = { 
 	0x118e, 0x284a, 0x263a, 0x98c0, 0xa188, 0x1000, 0x212c, 0x200b,
 	0xa5a5, 0x2114, 0xa286, 0xa5a5, 0x0040, 0x10bc, 0x250a, 0xa18a,
 	0x1000, 0x98c1, 0x0078, 0x10c1, 0x250a, 0x0078, 0x10c1, 0x2c6a,
-	0x2a5a, 0x2130, 0xa18a, 0x0040, 0x2128, 0xa1a2, 0x5100, 0x8424,
-	0x8424, 0x8424, 0x8424, 0x8424, 0x8424, 0xa192, 0x7800, 0x2009,
-	0x0000, 0x2001, 0x0031, 0x1078, 0x1cba, 0x2218, 0x2079, 0x5100,
+	0x2a5a, 0x2130, 0xa18a, 0x0040, 0x2128, 0xa1a2, 0x5200, 0x8424,
+	0x8424, 0x8424, 0x8424, 0x8424, 0x8424, 0xa192, 0x7900, 0x2009,
+	0x0000, 0x2001, 0x0031, 0x1078, 0x1d26, 0x2218, 0x2079, 0x5200,
 	0x2fa0, 0x2408, 0x2011, 0x0000, 0x20a9, 0x0040, 0x42a4, 0x8109,
 	0x00c0, 0x10dc, 0x7ef2, 0x8528, 0x7de6, 0x7cea, 0x7bee, 0x7883,
 	0x0000, 0x2031, 0x0030, 0x78cf, 0x0101, 0x780b, 0x0002, 0x780f,
-	0x0002, 0x784f, 0x0003, 0x2069, 0x5140, 0x2001, 0x04fd, 0x2004,
+	0x0002, 0x784f, 0x0003, 0x2069, 0x5240, 0x2001, 0x04fd, 0x2004,
 	0xa082, 0x0005, 0x0048, 0x1104, 0x0038, 0x1100, 0x0078, 0x1108,
 	0x681b, 0x003c, 0x0078, 0x110a, 0x00a8, 0x1108, 0x681b, 0x003c,
 	0x681b, 0x0028, 0x6807, 0x0007, 0x680b, 0x00fa, 0x680f, 0x0008,
 	0x6813, 0x0005, 0x6823, 0x0000, 0x6827, 0x0006, 0x6817, 0x0008,
-	0x682b, 0x0000, 0x681f, 0x0019, 0x2069, 0x5380, 0x2011, 0x0020,
+	0x682b, 0x0000, 0x681f, 0x0019, 0x2069, 0x5480, 0x2011, 0x0020,
 	0x2009, 0x0010, 0x680b, 0x080c, 0x680f, 0x0019, 0x6803, 0xfd00,
 	0x6807, 0x0018, 0x6a1a, 0x2d00, 0xa0e8, 0x0008, 0xa290, 0x0004,
-	0x8109, 0x00c0, 0x1122, 0x2069, 0x5400, 0x2009, 0x0002, 0x20a9,
+	0x8109, 0x00c0, 0x1122, 0x2069, 0x5500, 0x2009, 0x0002, 0x20a9,
 	0x0100, 0x6837, 0x0000, 0x680b, 0x0040, 0x7bf0, 0xa386, 0xfeff,
 	0x00c0, 0x1148, 0x6817, 0x0100, 0x681f, 0x0064, 0x0078, 0x114c,
 	0x6817, 0x0064, 0x681f, 0x0002, 0xade8, 0x0010, 0x0070, 0x1152,
-	0x0078, 0x1139, 0x8109, 0x00c0, 0x1137, 0x1078, 0x220a, 0x1078,
-	0x482c, 0x1078, 0x1963, 0x1078, 0x4d22, 0x3200, 0xa085, 0x000d,
+	0x0078, 0x1139, 0x8109, 0x00c0, 0x1137, 0x1078, 0x22a7, 0x1078,
+	0x493d, 0x1078, 0x19b5, 0x1078, 0x4e33, 0x3200, 0xa085, 0x000d,
 	0x2090, 0x70c3, 0x0000, 0x0090, 0x116c, 0x70c0, 0xa086, 0x0002,
 	0x00c0, 0x116c, 0x1078, 0x1284, 0x1078, 0x1196, 0x78cc, 0xa005,
-	0x00c0, 0x117a, 0x1078, 0x1ce3, 0x0010, 0x1180, 0x0068, 0x1180,
-	0x1078, 0x20e9, 0x0010, 0x1180, 0x0068, 0x1180, 0x1078, 0x1a48,
-	0x00e0, 0x116c, 0x1078, 0x4ba9, 0x0078, 0x116c, 0x118e, 0x1190,
-	0x240b, 0x240b, 0x48ad, 0x48ad, 0x240b, 0x240b, 0x0078, 0x118e,
+	0x00c0, 0x117a, 0x1078, 0x1d4f, 0x0010, 0x1180, 0x0068, 0x1180,
+	0x1078, 0x2186, 0x0010, 0x1180, 0x0068, 0x1180, 0x1078, 0x1ab9,
+	0x00e0, 0x116c, 0x1078, 0x4cba, 0x0078, 0x116c, 0x118e, 0x1190,
+	0x24ac, 0x24ac, 0x49be, 0x49be, 0x24ac, 0x24ac, 0x0078, 0x118e,
 	0x0078, 0x1190, 0x0078, 0x1192, 0x0078, 0x1194, 0x0068, 0x1201,
 	0x2061, 0x0000, 0x6018, 0xa084, 0x0001, 0x00c0, 0x1201, 0x7814,
 	0xa005, 0x00c0, 0x11a7, 0x0010, 0x1202, 0x0078, 0x1201, 0x2009,
-	0x515b, 0x2104, 0xa005, 0x00c0, 0x1201, 0x2009, 0x5164, 0x200b,
+	0x525b, 0x2104, 0xa005, 0x00c0, 0x1201, 0x2009, 0x5264, 0x200b,
 	0x0000, 0x7914, 0xa186, 0x0042, 0x00c0, 0x11cc, 0x7816, 0x2009,
-	0x5162, 0x2164, 0x200b, 0x0000, 0x6018, 0x70c6, 0x6014, 0x70ca,
+	0x5262, 0x2164, 0x200b, 0x0000, 0x6018, 0x70c6, 0x6014, 0x70ca,
 	0x611c, 0xa18c, 0xff00, 0x6020, 0xa084, 0x00ff, 0xa105, 0x70ce,
-	0x1078, 0x1948, 0x0078, 0x11ff, 0x7814, 0xa086, 0x0018, 0x00c0,
-	0x11d3, 0x1078, 0x165a, 0x7817, 0x0000, 0x2009, 0x5162, 0x2104,
-	0xa065, 0x0040, 0x11ef, 0x0c7e, 0x609c, 0x2060, 0x1078, 0x19b3,
-	0x0c7f, 0x609f, 0x0000, 0x1078, 0x1730, 0x2009, 0x000c, 0x6007,
-	0x0103, 0x1078, 0x1924, 0x00c0, 0x11fb, 0x1078, 0x1948, 0x2009,
-	0x5162, 0x200b, 0x0000, 0x2009, 0x515c, 0x2104, 0x200b, 0x0000,
+	0x1078, 0x199a, 0x0078, 0x11ff, 0x7814, 0xa086, 0x0018, 0x00c0,
+	0x11d3, 0x1078, 0x1678, 0x7817, 0x0000, 0x2009, 0x5262, 0x2104,
+	0xa065, 0x0040, 0x11ef, 0x0c7e, 0x609c, 0x2060, 0x1078, 0x1a17,
+	0x0c7f, 0x609f, 0x0000, 0x1078, 0x174e, 0x2009, 0x000c, 0x6007,
+	0x0103, 0x1078, 0x1976, 0x00c0, 0x11fb, 0x1078, 0x199a, 0x2009,
+	0x5262, 0x200b, 0x0000, 0x2009, 0x525c, 0x2104, 0x200b, 0x0000,
 	0xa005, 0x0040, 0x11ff, 0x2001, 0x4005, 0x0078, 0x1286, 0x0078,
 	0x1284, 0x007c, 0x70c3, 0x0000, 0x70c7, 0x0000, 0x70cb, 0x0000,
 	0x70cf, 0x0000, 0x70c0, 0xa0bc, 0xffc0, 0x00c0, 0x1252, 0x2038,
 	0x0079, 0x1212, 0x1284, 0x12e5, 0x12a9, 0x12fe, 0x130d, 0x1313,
-	0x12a0, 0x1748, 0x1317, 0x1298, 0x12ad, 0x12af, 0x12b1, 0x12b3,
-	0x174d, 0x1298, 0x1329, 0x1360, 0x1672, 0x1742, 0x12b5, 0x1591,
-	0x15ad, 0x15c9, 0x15f4, 0x154a, 0x1558, 0x156c, 0x1580, 0x13df,
-	0x1298, 0x138d, 0x1393, 0x1398, 0x139d, 0x13a3, 0x13a8, 0x13ad,
-	0x13b2, 0x13b7, 0x13bb, 0x13d0, 0x13dc, 0x1298, 0x1298, 0x1298,
-	0x1298, 0x13eb, 0x13f4, 0x1403, 0x1429, 0x1433, 0x143a, 0x1480,
-	0x148f, 0x149e, 0x14b0, 0x152a, 0x153a, 0x1298, 0x1298, 0x1298,
-	0x1298, 0x153f, 0xa0bc, 0xffa0, 0x00c0, 0x1298, 0x2038, 0xa084,
-	0x001f, 0x0079, 0x125b, 0x1786, 0x1789, 0x1799, 0x1298, 0x1298,
-	0x18df, 0x18fc, 0x1298, 0x1298, 0x1298, 0x1900, 0x1908, 0x1298,
-	0x1298, 0x1298, 0x1298, 0x12db, 0x12f4, 0x131f, 0x1356, 0x1668,
-	0x1764, 0x1778, 0x1298, 0x1829, 0x190e, 0x18bb, 0x18c5, 0x18c9,
-	0x18d7, 0x1298, 0x1298, 0x72ca, 0x71c6, 0x2001, 0x4006, 0x0078,
+	0x12a0, 0x1766, 0x1317, 0x1298, 0x12ad, 0x12af, 0x12b1, 0x12b3,
+	0x176b, 0x1298, 0x1329, 0x1365, 0x1690, 0x1760, 0x12b5, 0x15af,
+	0x15cb, 0x15e7, 0x1612, 0x1568, 0x1576, 0x158a, 0x159e, 0x13e9,
+	0x1298, 0x1397, 0x139d, 0x13a2, 0x13a7, 0x13ad, 0x13b2, 0x13b7,
+	0x13bc, 0x13c1, 0x13c5, 0x13da, 0x13e6, 0x1298, 0x1298, 0x1298,
+	0x1298, 0x13f5, 0x13fe, 0x140d, 0x1451, 0x145b, 0x1462, 0x14a8,
+	0x14b7, 0x14c6, 0x14d8, 0x1548, 0x1558, 0x1298, 0x1298, 0x1298,
+	0x1298, 0x155d, 0xa0bc, 0xffa0, 0x00c0, 0x1298, 0x2038, 0xa084,
+	0x001f, 0x0079, 0x125b, 0x17a4, 0x17a7, 0x17b7, 0x1298, 0x1298,
+	0x1931, 0x194e, 0x1298, 0x1298, 0x1298, 0x1952, 0x195a, 0x1298,
+	0x1298, 0x1298, 0x1298, 0x12db, 0x12f4, 0x131f, 0x135b, 0x1686,
+	0x1782, 0x1796, 0x1298, 0x1847, 0x1960, 0x190d, 0x1917, 0x191b,
+	0x1929, 0x1298, 0x1298, 0x72ca, 0x71c6, 0x2001, 0x4006, 0x0078,
 	0x1286, 0x73ce, 0x72ca, 0x71c6, 0x2001, 0x4000, 0x70c2, 0x0068,
 	0x1287, 0x2061, 0x0000, 0x601b, 0x0001, 0x2091, 0x5000, 0x00e0,
 	0x128f, 0x00e0, 0x1291, 0x0068, 0x1291, 0x2091, 0x4080, 0x007c,
@@ -126,1974 +126,2005 @@ static unsigned short risc_code01[] = { 
 	0x0007, 0x3f00, 0x70d6, 0x2079, 0x0000, 0x781b, 0x0001, 0x2031,
 	0x0030, 0x2059, 0x1000, 0x2029, 0x0457, 0x2051, 0x0470, 0x2061,
 	0x0472, 0x20b9, 0xffff, 0x20c1, 0x0000, 0x2091, 0x5000, 0x2091,
-	0x4080, 0x0078, 0x0455, 0x1078, 0x1b53, 0x00c0, 0x129c, 0x75d8,
+	0x4080, 0x0078, 0x0455, 0x1078, 0x1bc4, 0x00c0, 0x129c, 0x75d8,
 	0x74dc, 0x75da, 0x74de, 0x0078, 0x12e8, 0x2029, 0x0000, 0x2520,
-	0x71d0, 0x73c8, 0x72cc, 0x70c4, 0x1078, 0x1a8d, 0x0040, 0x1284,
-	0x70c3, 0x4002, 0x0078, 0x1284, 0x1078, 0x1b53, 0x00c0, 0x129c,
+	0x71d0, 0x73c8, 0x72cc, 0x70c4, 0x1078, 0x1afe, 0x0040, 0x1284,
+	0x70c3, 0x4002, 0x0078, 0x1284, 0x1078, 0x1bc4, 0x00c0, 0x129c,
 	0x75d8, 0x74dc, 0x75da, 0x74de, 0x0078, 0x1301, 0x2029, 0x0000,
-	0x2520, 0x71d0, 0x73c8, 0x72cc, 0x70c4, 0x1078, 0x1aed, 0x0040,
+	0x2520, 0x71d0, 0x73c8, 0x72cc, 0x70c4, 0x1078, 0x1b5e, 0x0040,
 	0x1284, 0x70c3, 0x4002, 0x0078, 0x1284, 0x71c4, 0x70c8, 0x2114,
 	0x200a, 0x0078, 0x1282, 0x71c4, 0x2114, 0x0078, 0x1282, 0x70c7,
-	0x0007, 0x70cb, 0x0041, 0x70cf, 0x0000, 0x0078, 0x1284, 0x1078,
-	0x1b53, 0x00c0, 0x129c, 0x75d8, 0x76dc, 0x75da, 0x76de, 0x0078,
+	0x0007, 0x70cb, 0x0041, 0x70cf, 0x0006, 0x0078, 0x1284, 0x1078,
+	0x1bc4, 0x00c0, 0x129c, 0x75d8, 0x76dc, 0x75da, 0x76de, 0x0078,
 	0x132c, 0x2029, 0x0000, 0x2530, 0x70c4, 0x72c8, 0x73cc, 0x74d0,
-	0x70c6, 0x72ca, 0x73ce, 0x74d2, 0xa005, 0x0040, 0x1350, 0x8001,
-	0x7892, 0xa084, 0xfc00, 0x0040, 0x1345, 0x78cc, 0xa085, 0x0001,
-	0x78ce, 0x2001, 0x4005, 0x0078, 0x1286, 0x7a9a, 0x7b9e, 0x7da2,
-	0x7ea6, 0x7c96, 0x78cc, 0xa084, 0xfffc, 0x78ce, 0x0078, 0x1354,
-	0x78cc, 0xa085, 0x0001, 0x78ce, 0x0078, 0x1284, 0x1078, 0x1b53,
-	0x00c0, 0x129c, 0x75d8, 0x76dc, 0x75da, 0x76de, 0x0078, 0x1363,
-	0x2029, 0x0000, 0x2530, 0x70c4, 0x72c8, 0x73cc, 0x74d4, 0x70c6,
-	0x72ca, 0x73ce, 0x74d6, 0xa005, 0x0040, 0x1387, 0x8001, 0x78ae,
-	0xa084, 0xfc00, 0x0040, 0x137c, 0x78cc, 0xa085, 0x0100, 0x78ce,
-	0x2001, 0x4005, 0x0078, 0x1286, 0x7ab6, 0x7bba, 0x7dbe, 0x7ec2,
-	0x7cb2, 0x78cc, 0xa084, 0xfcff, 0x78ce, 0x0078, 0x138b, 0x78cc,
-	0xa085, 0x0100, 0x78ce, 0x0078, 0x1284, 0x2009, 0x5161, 0x210c,
-	0x7aec, 0x0078, 0x1282, 0x2009, 0x5141, 0x210c, 0x0078, 0x1283,
-	0x2009, 0x5142, 0x210c, 0x0078, 0x1283, 0x2061, 0x5140, 0x610c,
-	0x6210, 0x0078, 0x1282, 0x2009, 0x5145, 0x210c, 0x0078, 0x1283,
-	0x2009, 0x5146, 0x210c, 0x0078, 0x1283, 0x2009, 0x5148, 0x210c,
-	0x0078, 0x1283, 0x2009, 0x5149, 0x210c, 0x0078, 0x1283, 0x7908,
-	0x7a0c, 0x0078, 0x1282, 0x71c4, 0x8107, 0xa084, 0x000f, 0x8003,
-	0x8003, 0x8003, 0xa0e8, 0x5380, 0x6a00, 0x6804, 0xa084, 0x0008,
-	0x0040, 0x13cd, 0x6b08, 0x0078, 0x13ce, 0x6b0c, 0x0078, 0x1281,
-	0x77c4, 0x1078, 0x1973, 0x2091, 0x8000, 0x6b1c, 0x6a14, 0x2091,
-	0x8001, 0x2708, 0x0078, 0x1281, 0x794c, 0x0078, 0x1283, 0x77c4,
-	0x1078, 0x1973, 0x2091, 0x8000, 0x6908, 0x6a18, 0x6b10, 0x2091,
-	0x8001, 0x0078, 0x1281, 0x71c4, 0xa182, 0x0010, 0x00c8, 0x127c,
-	0x1078, 0x22e2, 0x0078, 0x1281, 0x71c4, 0xa182, 0x0010, 0x00c8,
-	0x127c, 0x2011, 0x5141, 0x2204, 0x007e, 0x2112, 0x1078, 0x229b,
-	0x017f, 0x0078, 0x1283, 0x71c4, 0x2011, 0x1421, 0x20a9, 0x0008,
-	0x2204, 0xa106, 0x0040, 0x1413, 0x8210, 0x0070, 0x1411, 0x0078,
-	0x1408, 0x0078, 0x127c, 0xa292, 0x1421, 0x027e, 0x2011, 0x5142,
-	0x2204, 0x2112, 0x017f, 0x007e, 0x1078, 0x22a7, 0x017f, 0x0078,
+	0x70c6, 0x72ca, 0x73ce, 0x74d2, 0xa005, 0x0040, 0x1355, 0xa40a,
+	0x0040, 0x133c, 0x00c8, 0x1346, 0x8001, 0x7892, 0xa084, 0xfc00,
+	0x0040, 0x134a, 0x78cc, 0xa085, 0x0001, 0x78ce, 0x2001, 0x4005,
+	0x0078, 0x1286, 0x7a9a, 0x7b9e, 0x7da2, 0x7ea6, 0x7c96, 0x78cc,
+	0xa084, 0xfffc, 0x78ce, 0x0078, 0x1359, 0x78cc, 0xa085, 0x0001,
+	0x78ce, 0x0078, 0x1284, 0x1078, 0x1bc4, 0x00c0, 0x129c, 0x75d8,
+	0x76dc, 0x75da, 0x76de, 0x0078, 0x1368, 0x2029, 0x0000, 0x2530,
+	0x70c4, 0x72c8, 0x73cc, 0x74d4, 0x70c6, 0x72ca, 0x73ce, 0x74d6,
+	0xa005, 0x0040, 0x1391, 0xa40a, 0x0040, 0x1378, 0x00c8, 0x1382,
+	0x8001, 0x78ae, 0xa084, 0xfc00, 0x0040, 0x1386, 0x78cc, 0xa085,
+	0x0100, 0x78ce, 0x2001, 0x4005, 0x0078, 0x1286, 0x7ab6, 0x7bba,
+	0x7dbe, 0x7ec2, 0x7cb2, 0x78cc, 0xa084, 0xfcff, 0x78ce, 0x0078,
+	0x1395, 0x78cc, 0xa085, 0x0100, 0x78ce, 0x0078, 0x1284, 0x2009,
+	0x5261, 0x210c, 0x7aec, 0x0078, 0x1282, 0x2009, 0x5241, 0x210c,
+	0x0078, 0x1283, 0x2009, 0x5242, 0x210c, 0x0078, 0x1283, 0x2061,
+	0x5240, 0x610c, 0x6210, 0x0078, 0x1282, 0x2009, 0x5245, 0x210c,
+	0x0078, 0x1283, 0x2009, 0x5246, 0x210c, 0x0078, 0x1283, 0x2009,
+	0x5248, 0x210c, 0x0078, 0x1283, 0x2009, 0x5249, 0x210c, 0x0078,
+	0x1283, 0x7908, 0x7a0c, 0x0078, 0x1282, 0x71c4, 0x8107, 0xa084,
+	0x000f, 0x8003, 0x8003, 0x8003, 0xa0e8, 0x5480, 0x6a00, 0x6804,
+	0xa084, 0x0008, 0x0040, 0x13d7, 0x6b08, 0x0078, 0x13d8, 0x6b0c,
+	0x0078, 0x1281, 0x77c4, 0x1078, 0x19c5, 0x2091, 0x8000, 0x6b1c,
+	0x6a14, 0x2091, 0x8001, 0x2708, 0x0078, 0x1281, 0x794c, 0x0078,
+	0x1283, 0x77c4, 0x1078, 0x19c5, 0x2091, 0x8000, 0x6908, 0x6a18,
+	0x6b10, 0x2091, 0x8001, 0x0078, 0x1281, 0x71c4, 0xa182, 0x0010,
+	0x00c8, 0x127c, 0x1078, 0x237f, 0x0078, 0x1281, 0x71c4, 0xa182,
+	0x0010, 0x00c8, 0x127c, 0x2011, 0x5241, 0x2204, 0x007e, 0x2112,
+	0x1078, 0x2338, 0x017f, 0x0078, 0x1283, 0x71c4, 0x2019, 0x0100,
+	0x2304, 0xa082, 0x0006, 0x0048, 0x141b, 0x2011, 0x1449, 0x20a9,
+	0x0008, 0x0078, 0x141f, 0x2011, 0x1441, 0x20a9, 0x0008, 0x2204,
+	0xa106, 0x0040, 0x142a, 0x8210, 0x0070, 0x1428, 0x0078, 0x141f,
+	0x0078, 0x127c, 0x2304, 0xa082, 0x0006, 0x0048, 0x1433, 0xa292,
+	0x1449, 0x0078, 0x1435, 0xa292, 0x1441, 0x027e, 0x2011, 0x5242,
+	0x2204, 0x2112, 0x017f, 0x007e, 0x1078, 0x2344, 0x017f, 0x0078,
 	0x1283, 0x03e8, 0x00fa, 0x01f4, 0x02ee, 0x0064, 0x0019, 0x0032,
-	0x004b, 0x2061, 0x5140, 0x610c, 0x6210, 0x70c4, 0x600e, 0x70c8,
-	0x6012, 0x0078, 0x1282, 0x2061, 0x5140, 0x6114, 0x70c4, 0x6016,
-	0x0078, 0x1283, 0x2061, 0x5140, 0x71c4, 0x2011, 0x0004, 0x601f,
-	0x0019, 0x2019, 0x1212, 0xa186, 0x0028, 0x0040, 0x145b, 0x2011,
+	0x004b, 0x03e8, 0x00fa, 0x01f4, 0x02ee, 0x0004, 0x0001, 0x0002,
+	0x0003, 0x2061, 0x5240, 0x610c, 0x6210, 0x70c4, 0x600e, 0x70c8,
+	0x6012, 0x0078, 0x1282, 0x2061, 0x5240, 0x6114, 0x70c4, 0x6016,
+	0x0078, 0x1283, 0x2061, 0x5240, 0x71c4, 0x2011, 0x0004, 0x601f,
+	0x0019, 0x2019, 0x1212, 0xa186, 0x0028, 0x0040, 0x1483, 0x2011,
 	0x0005, 0x601f, 0x0019, 0x2019, 0x1212, 0xa186, 0x0032, 0x0040,
-	0x145b, 0x2011, 0x0006, 0x601f, 0x000c, 0x2019, 0x2222, 0xa186,
+	0x1483, 0x2011, 0x0006, 0x601f, 0x000c, 0x2019, 0x2222, 0xa186,
 	0x003c, 0x00c0, 0x127c, 0x6018, 0x007e, 0x611a, 0x7800, 0xa084,
-	0x0001, 0x00c0, 0x1476, 0x2001, 0x04fd, 0x2004, 0xa082, 0x0005,
-	0x0048, 0x146e, 0x0038, 0x1472, 0x0078, 0x1476, 0x0028, 0x1472,
-	0x0078, 0x1476, 0x2019, 0x2222, 0x0078, 0x1478, 0x2019, 0x1212,
-	0x23b8, 0x1078, 0x22b8, 0x1078, 0x4d22, 0x017f, 0x0078, 0x1283,
-	0x71c4, 0xa184, 0xffcf, 0x00c0, 0x127c, 0x2011, 0x5148, 0x2204,
-	0x2112, 0x007e, 0x1078, 0x22da, 0x017f, 0x0078, 0x1283, 0x71c4,
-	0xa182, 0x0010, 0x00c8, 0x127c, 0x2011, 0x5149, 0x2204, 0x007e,
-	0x2112, 0x1078, 0x22c9, 0x017f, 0x0078, 0x1283, 0x71c4, 0x72c8,
+	0x0001, 0x00c0, 0x149e, 0x2001, 0x04fd, 0x2004, 0xa082, 0x0005,
+	0x0048, 0x1496, 0x0038, 0x149a, 0x0078, 0x149e, 0x0028, 0x149a,
+	0x0078, 0x149e, 0x2019, 0x2222, 0x0078, 0x14a0, 0x2019, 0x1212,
+	0x23b8, 0x1078, 0x2355, 0x1078, 0x4e33, 0x017f, 0x0078, 0x1283,
+	0x71c4, 0xa184, 0xffcf, 0x00c0, 0x127c, 0x2011, 0x5248, 0x2204,
+	0x2112, 0x007e, 0x1078, 0x2377, 0x017f, 0x0078, 0x1283, 0x71c4,
+	0xa182, 0x0010, 0x00c8, 0x127c, 0x2011, 0x5249, 0x2204, 0x007e,
+	0x2112, 0x1078, 0x2366, 0x017f, 0x0078, 0x1283, 0x71c4, 0x72c8,
 	0xa184, 0xfffd, 0x00c0, 0x127b, 0xa284, 0xfffd, 0x00c0, 0x127b,
 	0x2100, 0x7908, 0x780a, 0x2200, 0x7a0c, 0x780e, 0x0078, 0x1282,
 	0x71c4, 0x8107, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xa0e8,
-	0x5380, 0x2019, 0x0000, 0x72c8, 0xa284, 0x0080, 0x0040, 0x14c6,
-	0x6c14, 0x84ff, 0x00c0, 0x14c6, 0x6817, 0x0040, 0xa284, 0x0040,
-	0x0040, 0x14d0, 0x6c10, 0x84ff, 0x00c0, 0x14d0, 0x6813, 0x0001,
-	0x6800, 0x007e, 0xa226, 0x0040, 0x14f3, 0x6a02, 0xa484, 0x2000,
-	0x0040, 0x14dc, 0xa39d, 0x0010, 0xa484, 0x1000, 0x0040, 0x14e2,
-	0xa39d, 0x0008, 0xa484, 0x4000, 0x0040, 0x14f3, 0x810f, 0xa284,
-	0x4000, 0x0040, 0x14ef, 0x1078, 0x22fc, 0x0078, 0x14f3, 0x1078,
-	0x22ee, 0x0078, 0x14f3, 0x72cc, 0x6808, 0xa206, 0x0040, 0x1522,
-	0xa2a4, 0x00ff, 0x2061, 0x5140, 0x6118, 0xa186, 0x0028, 0x0040,
-	0x1509, 0xa186, 0x0032, 0x0040, 0x150f, 0xa186, 0x003c, 0x0040,
-	0x1515, 0xa482, 0x0064, 0x0048, 0x151f, 0x0078, 0x1519, 0xa482,
-	0x0050, 0x0048, 0x151f, 0x0078, 0x1519, 0xa482, 0x0043, 0x0048,
-	0x151f, 0x71c4, 0x71c6, 0x027f, 0x72ca, 0x0078, 0x127d, 0x6a0a,
-	0xa39d, 0x000a, 0x6804, 0xa305, 0x6806, 0x027f, 0x6b0c, 0x71c4,
-	0x0078, 0x1281, 0x77c4, 0x1078, 0x1973, 0x2091, 0x8000, 0x6a14,
-	0x6b1c, 0x2091, 0x8001, 0x70c8, 0x6816, 0x70cc, 0x681e, 0x2708,
-	0x0078, 0x1281, 0x70c4, 0x794c, 0x784e, 0x0078, 0x1283, 0x71c4,
-	0x72c8, 0x73cc, 0xa182, 0x0010, 0x00c8, 0x127c, 0x1078, 0x230a,
-	0x0078, 0x1281, 0x77c4, 0x1078, 0x1973, 0x2091, 0x8000, 0x6a08,
-	0xa295, 0x0002, 0x6a0a, 0x2091, 0x8001, 0x2708, 0x0078, 0x1282,
-	0x77c4, 0x1078, 0x1973, 0x2091, 0x8000, 0x6a08, 0xa294, 0xfff9,
-	0x6a0a, 0x6804, 0xa005, 0x0040, 0x1567, 0x1078, 0x21d2, 0x2091,
-	0x8001, 0x2708, 0x0078, 0x1282, 0x77c4, 0x1078, 0x1973, 0x2091,
-	0x8000, 0x6a08, 0xa295, 0x0004, 0x6a0a, 0x6804, 0xa005, 0x0040,
-	0x157b, 0x1078, 0x21d2, 0x2091, 0x8001, 0x2708, 0x0078, 0x1282,
-	0x77c4, 0x2041, 0x0001, 0x2049, 0x0005, 0x2051, 0x0020, 0x2091,
-	0x8000, 0x1078, 0x1980, 0x2091, 0x8001, 0x2708, 0x6a08, 0x0078,
-	0x1282, 0x77c4, 0x72c8, 0x73cc, 0x77c6, 0x72ca, 0x73ce, 0x1078,
-	0x19e1, 0x00c0, 0x15a9, 0x6818, 0xa005, 0x0040, 0x15a9, 0x2708,
-	0x1078, 0x231a, 0x00c0, 0x15a9, 0x7817, 0x0015, 0x2091, 0x8001,
-	0x007c, 0x2091, 0x8001, 0x0078, 0x1284, 0x77c4, 0x77c6, 0x2041,
-	0x0021, 0x2049, 0x0005, 0x2051, 0x0020, 0x2091, 0x8000, 0x1078,
-	0x1980, 0x2061, 0x5140, 0x606f, 0x0003, 0x6782, 0x6093, 0x000f,
-	0x6073, 0x0000, 0x7817, 0x0016, 0x1078, 0x21d2, 0x2091, 0x8001,
-	0x007c, 0x77c8, 0x77ca, 0x77c4, 0x77c6, 0xa7bc, 0xff00, 0x2091,
-	0x8000, 0x2061, 0x5140, 0x606f, 0x0002, 0x6073, 0x0000, 0x6782,
-	0x6093, 0x000f, 0x7817, 0x0017, 0x1078, 0x21d2, 0x2091, 0x8001,
-	0x2041, 0x0021, 0x2049, 0x0004, 0x2051, 0x0010, 0x2091, 0x8000,
-	0x1078, 0x1980, 0x70c8, 0x6836, 0x8738, 0xa784, 0x001f, 0x00c0,
-	0x15e8, 0x2091, 0x8001, 0x007c, 0x78cc, 0xa084, 0x0003, 0x00c0,
-	0x1618, 0x2039, 0x0000, 0x2041, 0x0021, 0x2049, 0x0004, 0x2051,
-	0x0008, 0x1078, 0x1973, 0x2091, 0x8000, 0x6808, 0xa80d, 0x690a,
-	0x2091, 0x8001, 0x8738, 0xa784, 0x001f, 0x00c0, 0x1601, 0xa7bc,
-	0xff00, 0x873f, 0x8738, 0x873f, 0xa784, 0x0f00, 0x00c0, 0x1601,
-	0x2091, 0x8000, 0x2069, 0x0100, 0x6830, 0xa084, 0x0040, 0x0040,
-	0x1641, 0x684b, 0x0004, 0x20a9, 0x0014, 0x6848, 0xa084, 0x0004,
-	0x0040, 0x162e, 0x0070, 0x162e, 0x0078, 0x1625, 0x684b, 0x0009,
-	0x20a9, 0x0014, 0x6848, 0xa084, 0x0001, 0x0040, 0x163b, 0x0070,
-	0x163b, 0x0078, 0x1632, 0x20a9, 0x00fa, 0x0070, 0x1641, 0x0078,
-	0x163d, 0x2079, 0x5100, 0x7817, 0x0018, 0x2061, 0x5140, 0x606f,
-	0x0001, 0x6073, 0x0000, 0x6093, 0x000f, 0x78cc, 0xa085, 0x0002,
-	0x78ce, 0x6808, 0xa084, 0xfffd, 0x680a, 0x681b, 0x0048, 0x2091,
-	0x8001, 0x007c, 0x78cc, 0xa084, 0xfffd, 0x78ce, 0xa084, 0x0001,
-	0x00c0, 0x1664, 0x1078, 0x1a2b, 0x71c4, 0x71c6, 0x794a, 0x007c,
-	0x1078, 0x1b53, 0x00c0, 0x129c, 0x75d8, 0x74dc, 0x75da, 0x74de,
-	0x0078, 0x1675, 0x2029, 0x0000, 0x2520, 0x71c4, 0x73c8, 0x72cc,
-	0x71c6, 0x73ca, 0x72ce, 0x2079, 0x5100, 0x2091, 0x8000, 0x1078,
-	0x192e, 0x2091, 0x8001, 0x0040, 0x172c, 0x20a9, 0x0005, 0x20a1,
-	0x5118, 0x2091, 0x8000, 0x41a1, 0x2091, 0x8001, 0x2009, 0x0020,
-	0x1078, 0x1929, 0x0040, 0x1698, 0x1078, 0x1948, 0x0078, 0x172c,
-	0x6004, 0xa084, 0xff00, 0x8007, 0x8009, 0x0040, 0x16fb, 0x0c7e,
-	0x2c68, 0x2091, 0x8000, 0x1078, 0x192e, 0x2091, 0x8001, 0x0040,
-	0x16cc, 0x2c00, 0x689e, 0x8109, 0x00c0, 0x16a0, 0x609f, 0x0000,
-	0x0c7f, 0x0c7e, 0x7218, 0x731c, 0x7420, 0x7524, 0x2c68, 0x689c,
-	0xa065, 0x0040, 0x16fa, 0x2009, 0x0020, 0x1078, 0x1929, 0x00c0,
-	0x16e3, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0002, 0x00c0, 0x16cc,
-	0x2d00, 0x6002, 0x0078, 0x16b2, 0x0c7f, 0x0c7e, 0x609c, 0x2060,
-	0x1078, 0x19b3, 0x0c7f, 0x609f, 0x0000, 0x1078, 0x1730, 0x2009,
-	0x000c, 0x6008, 0xa085, 0x0200, 0x600a, 0x1078, 0x1924, 0x1078,
-	0x1948, 0x0078, 0x172c, 0x0c7f, 0x0c7e, 0x609c, 0x2060, 0x1078,
-	0x19b3, 0x0c7f, 0x609f, 0x0000, 0x1078, 0x1730, 0x2009, 0x000c,
-	0x6007, 0x0103, 0x601b, 0x0003, 0x1078, 0x1924, 0x1078, 0x1948,
-	0x0078, 0x172c, 0x0c7f, 0x74c4, 0x73c8, 0x72cc, 0x6014, 0x2091,
-	0x8000, 0x7817, 0x0012, 0x0e7e, 0x2071, 0x5140, 0x706f, 0x0005,
-	0x7073, 0x0000, 0x7376, 0x727a, 0x747e, 0x7082, 0x7087, 0x0000,
-	0x2c00, 0x708a, 0x708f, 0x0000, 0xa02e, 0x2530, 0x611c, 0x61a2,
-	0xa184, 0x0060, 0x0040, 0x171e, 0x1078, 0x47c2, 0x0e7f, 0x6596,
-	0x65a6, 0x669a, 0x66aa, 0x60af, 0x0000, 0x60b3, 0x0000, 0x1078,
-	0x21d2, 0x2091, 0x8001, 0x007c, 0x70c3, 0x4005, 0x0078, 0x1287,
-	0x20a9, 0x0005, 0x2099, 0x5118, 0x2091, 0x8000, 0x530a, 0x2091,
-	0x8001, 0x2100, 0xa210, 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9,
-	0x0000, 0x007c, 0x71c4, 0x70c7, 0x0000, 0x7906, 0x0078, 0x1284,
-	0x71c4, 0x71c6, 0x2168, 0x0078, 0x174f, 0x2069, 0x1000, 0x690c,
-	0xa016, 0x2d04, 0xa210, 0x8d68, 0x8109, 0x00c0, 0x1751, 0xa285,
-	0x0000, 0x00c0, 0x175f, 0x70c3, 0x4000, 0x0078, 0x1761, 0x70c3,
-	0x4003, 0x70ca, 0x0078, 0x1287, 0x2011, 0x5167, 0x220c, 0x70c4,
-	0x8003, 0x0048, 0x1771, 0x1078, 0x3b7f, 0xa184, 0x7fff, 0x0078,
-	0x1775, 0x1078, 0x3b72, 0xa185, 0x8000, 0x2012, 0x0078, 0x1283,
-	0x71c4, 0x1078, 0x3b69, 0x6100, 0x2001, 0x5167, 0x2004, 0xa084,
-	0x8000, 0xa10d, 0x6204, 0x6308, 0x0078, 0x1281, 0x79e4, 0x0078,
-	0x1283, 0x71c4, 0x71c6, 0x2198, 0x20a1, 0x0042, 0x20a9, 0x0004,
-	0x53a3, 0x21a0, 0x2099, 0x0042, 0x20a9, 0x0004, 0x53a3, 0x0078,
-	0x1284, 0x70c4, 0x2068, 0x2079, 0x5100, 0x2091, 0x8000, 0x1078,
-	0x192e, 0x2091, 0x8001, 0x0040, 0x1825, 0x6007, 0x0001, 0x600b,
-	0x0000, 0x602b, 0x0000, 0x601b, 0x0006, 0x6a10, 0xa28c, 0x000f,
-	0xa284, 0x00f0, 0x8003, 0x8003, 0x8003, 0x8003, 0xa105, 0x6016,
-	0xa284, 0x0800, 0x0040, 0x17c0, 0x601b, 0x000a, 0x0078, 0x17c6,
-	0xa284, 0x1000, 0x0040, 0x17c6, 0x601b, 0x000c, 0xa284, 0x0300,
-	0x0040, 0x17cf, 0x602b, 0x0001, 0x8004, 0x8004, 0x8004, 0xa085,
-	0x0001, 0x601e, 0x6023, 0x0000, 0x6027, 0x0000, 0xa284, 0x0400,
-	0x0040, 0x17dc, 0x602b, 0x0000, 0x20a9, 0x0006, 0xac80, 0x000b,
-	0x20a0, 0xad80, 0x0005, 0x2098, 0x53a3, 0xa284, 0x0300, 0x00c0,
-	0x17f1, 0x6046, 0x604a, 0x604e, 0x6052, 0x6096, 0x609a, 0x0078,
-	0x17fb, 0x6800, 0x6046, 0x6804, 0x604a, 0x6e08, 0x664e, 0x6d0c,
-	0x6552, 0x6596, 0x669a, 0x6014, 0x2091, 0x8000, 0x7817, 0x0042,
-	0x2c08, 0x2061, 0x5140, 0x606f, 0x0005, 0x6073, 0x0000, 0x6077,
-	0x0000, 0x607b, 0x0000, 0x607f, 0x0000, 0x6082, 0x618a, 0xa284,
-	0x0400, 0x608e, 0x2091, 0x8001, 0x0e7e, 0x2071, 0x0020, 0x7007,
-	0x000a, 0x7007, 0x0002, 0x7003, 0x0000, 0x0e7f, 0x2091, 0x8000,
-	0x1078, 0x21d2, 0x2091, 0x8001, 0x007c, 0x70c3, 0x4005, 0x0078,
-	0x1287, 0x0c7e, 0x0d7e, 0x0e7e, 0x0f7e, 0x2091, 0x8000, 0x2071,
-	0x5140, 0x2079, 0x0100, 0x2061, 0x0010, 0x70a0, 0xa06d, 0x0040,
-	0x18b1, 0x6a04, 0xa294, 0x00ff, 0xa286, 0x0007, 0x0040, 0x1844,
-	0xa286, 0x000f, 0x00c0, 0x18b1, 0x691c, 0xa184, 0x0080, 0x00c0,
-	0x18b1, 0x6824, 0xa18c, 0xff00, 0xa085, 0x0019, 0x6826, 0x71b0,
-	0x81ff, 0x0040, 0x1867, 0x0d7e, 0x2069, 0x0020, 0x6807, 0x0010,
-	0x6908, 0x6808, 0xa106, 0x00c0, 0x1858, 0x690c, 0x680c, 0xa106,
-	0x00c0, 0x185d, 0xa184, 0x00ff, 0x00c0, 0x185d, 0x0d7f, 0x78b8,
-	0xa084, 0x801f, 0x00c0, 0x1867, 0x7848, 0xa085, 0x000c, 0x784a,
-	0x71b0, 0x81ff, 0x0040, 0x188a, 0x70b3, 0x0000, 0x0d7e, 0x2069,
-	0x0020, 0x6807, 0x0018, 0x6804, 0xa084, 0x0008, 0x00c0, 0x187b,
-	0x6807, 0x0008, 0x6804, 0xa084, 0x0008, 0x00c0, 0x1882, 0x6807,
-	0x0002, 0x0d7f, 0x61c4, 0x62c8, 0x63cc, 0x61c6, 0x62ca, 0x63ce,
-	0x0e7e, 0x2071, 0x5100, 0x7266, 0x736a, 0xae80, 0x0019, 0x0e7f,
-	0x7848, 0xa084, 0x000c, 0x00c0, 0x1898, 0x1078, 0x46db, 0x78a3,
-	0x0000, 0x7858, 0xa084, 0xedff, 0x785a, 0x70b4, 0xa080, 0x00df,
-	0x781a, 0x0f7f, 0x0e7f, 0x0d7f, 0x0c7f, 0x2091, 0x8001, 0x0078,
-	0x1284, 0x0f7f, 0x0e7f, 0x0d7f, 0x0c7f, 0x2091, 0x8001, 0x2001,
-	0x4005, 0x0078, 0x1286, 0x7980, 0x71c6, 0x71c4, 0xa182, 0x0003,
-	0x00c8, 0x127c, 0x7982, 0x0078, 0x1284, 0x7980, 0x71c6, 0x0078,
-	0x1284, 0x7974, 0x71c6, 0x71c4, 0x7976, 0x7978, 0x71ca, 0x71c8,
-	0x797a, 0x797c, 0x71ce, 0x71cc, 0x797e, 0x0078, 0x1284, 0x7974,
-	0x71c6, 0x7978, 0x71ca, 0x797c, 0x71ce, 0x0078, 0x1284, 0x7900,
-	0x71c6, 0x71c4, 0x7902, 0x2001, 0x04fd, 0x2004, 0xa082, 0x0005,
-	0x0048, 0x18ee, 0x0038, 0x18f0, 0x0078, 0x18fa, 0x00a8, 0x18fa,
-	0xa18c, 0x0001, 0x00c0, 0x18f8, 0x20b9, 0x2222, 0x0078, 0x18fa,
-	0x20b9, 0x1212, 0x0078, 0x1284, 0x7900, 0x71c6, 0x0078, 0x1284,
-	0x2009, 0x5174, 0x2104, 0x70c6, 0x70c4, 0x200a, 0x0078, 0x1284,
-	0x2009, 0x5174, 0x2104, 0x70c6, 0x0078, 0x1284, 0x71c4, 0x8107,
-	0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xa0e8, 0x5380, 0x6a14,
-	0xd2b4, 0x0040, 0x191f, 0x2011, 0x0001, 0x0078, 0x1921, 0x2011,
-	0x0000, 0x6b0c, 0x0078, 0x1281, 0xac80, 0x0001, 0x1078, 0x1b0f,
-	0x007c, 0xac80, 0x0001, 0x1078, 0x1aaf, 0x007c, 0x7850, 0xa065,
-	0x0040, 0x1936, 0x2c04, 0x7852, 0x2063, 0x0000, 0x007c, 0x0f7e,
-	0x2079, 0x5100, 0x7850, 0xa06d, 0x0040, 0x1946, 0x2d04, 0x7852,
-	0x6803, 0x0000, 0x6807, 0x0000, 0x680b, 0x0000, 0x0f7f, 0x007c,
-	0x2091, 0x8000, 0x0f7e, 0x2079, 0x5100, 0x7850, 0x2062, 0x2c00,
-	0xa005, 0x00c0, 0x1955, 0x1078, 0x23eb, 0x7852, 0x0f7f, 0x2091,
-	0x8001, 0x007c, 0x0f7e, 0x2079, 0x5100, 0x7850, 0x206a, 0x2d00,
-	0x7852, 0x0f7f, 0x007c, 0x2011, 0x7800, 0x7a52, 0x7bec, 0x8319,
-	0x0040, 0x1970, 0xa280, 0x0031, 0x2012, 0x2010, 0x0078, 0x1967,
-	0x2013, 0x0000, 0x007c, 0xa784, 0x0f00, 0x800b, 0xa784, 0x001f,
-	0x8003, 0x8003, 0x8003, 0x8003, 0xa105, 0xa0e8, 0x5400, 0x007c,
-	0x1078, 0x1973, 0x2900, 0x682a, 0x2a00, 0x682e, 0x6808, 0xa084,
-	0xffef, 0xa80d, 0x690a, 0x2009, 0x5152, 0x210c, 0x6804, 0xa005,
-	0x0040, 0x19b2, 0xa116, 0x00c0, 0x199d, 0x2060, 0x6000, 0x6806,
-	0x017e, 0x200b, 0x0000, 0x0078, 0x19a0, 0x2009, 0x0000, 0x017e,
-	0x6804, 0xa065, 0x0040, 0x19af, 0x6000, 0x6806, 0x1078, 0x19c0,
-	0x1078, 0x1c5f, 0x6810, 0x8001, 0x6812, 0x00c0, 0x19a0, 0x017f,
-	0x6902, 0x6906, 0x007c, 0xa065, 0x0040, 0x19bf, 0x609c, 0x609f,
-	0x0000, 0x2008, 0x1078, 0x1948, 0x2100, 0x0078, 0x19b3, 0x007c,
-	0x6007, 0x0103, 0x608f, 0x0000, 0x20a9, 0x001c, 0xac80, 0x0005,
-	0x20a0, 0x2001, 0x0000, 0x40a4, 0x6828, 0x601a, 0x682c, 0x6022,
-	0x007c, 0x0e7e, 0x2071, 0x5140, 0x704c, 0xa08c, 0x0200, 0x00c0,
-	0x19df, 0xa088, 0x5180, 0x2d0a, 0x8000, 0x704e, 0xa006, 0x0e7f,
-	0x007c, 0x1078, 0x1973, 0x2091, 0x8000, 0x6804, 0x781e, 0xa065,
-	0x0040, 0x1a2a, 0x0078, 0x19f2, 0x2c00, 0x781e, 0x6000, 0xa065,
-	0x0040, 0x1a2a, 0x600c, 0xa306, 0x00c0, 0x19ec, 0x6010, 0xa206,
-	0x00c0, 0x19ec, 0x2c28, 0x2001, 0x5152, 0x2004, 0xac06, 0x00c0,
-	0x1a03, 0x0078, 0x1a28, 0x6804, 0xac06, 0x00c0, 0x1a10, 0x6000,
-	0xa065, 0x6806, 0x00c0, 0x1a1a, 0x6803, 0x0000, 0x0078, 0x1a1a,
-	0x6400, 0x781c, 0x2060, 0x6402, 0xa486, 0x0000, 0x00c0, 0x1a1a,
-	0x2c00, 0x6802, 0x2560, 0x1078, 0x19c0, 0x601b, 0x0005, 0x6023,
-	0x0020, 0x1078, 0x1c5f, 0x6810, 0x8001, 0x1050, 0x23eb, 0x6812,
-	0xa085, 0xffff, 0x007c, 0x2039, 0x0000, 0x2041, 0x0021, 0x2049,
-	0x0004, 0x2051, 0x0008, 0x2091, 0x8000, 0x1078, 0x1980, 0x8738,
-	0xa784, 0x001f, 0x00c0, 0x1a35, 0xa7bc, 0xff00, 0x873f, 0x8738,
-	0x873f, 0xa784, 0x0f00, 0x00c0, 0x1a35, 0x2091, 0x8001, 0x007c,
-	0x2061, 0x0000, 0x6018, 0xa084, 0x0001, 0x00c0, 0x1a59, 0x2091,
-	0x8000, 0x78e0, 0x78e3, 0x0000, 0x2091, 0x8001, 0xa005, 0x00c0,
-	0x1a5a, 0x007c, 0xa08c, 0xfff0, 0x0040, 0x1a60, 0x1078, 0x23eb,
-	0x0079, 0x1a62, 0x1a72, 0x1a75, 0x1a7b, 0x1a7f, 0x1a73, 0x1a83,
-	0x1a89, 0x1a73, 0x1a73, 0x1c29, 0x1c4d, 0x1c51, 0x1a73, 0x1a73,
-	0x1a73, 0x1a73, 0x007c, 0x1078, 0x23eb, 0x1078, 0x1a2b, 0x2001,
-	0x8001, 0x0078, 0x1c57, 0x2001, 0x8003, 0x0078, 0x1c57, 0x2001,
-	0x8004, 0x0078, 0x1c57, 0x1078, 0x1a2b, 0x2001, 0x8006, 0x0078,
-	0x1c57, 0x2001, 0x8007, 0x0078, 0x1c57, 0x2030, 0x2138, 0xa782,
-	0x0021, 0x0048, 0x1a95, 0x2009, 0x0020, 0x2600, 0x1078, 0x1aaf,
-	0x00c0, 0x1aae, 0xa7ba, 0x0020, 0x0048, 0x1aad, 0x0040, 0x1aad,
-	0x2708, 0xa6b0, 0x0020, 0xa290, 0x0040, 0xa399, 0x0000, 0xa4a1,
-	0x0000, 0xa5a9, 0x0000, 0x0078, 0x1a8f, 0xa006, 0x007c, 0x81ff,
-	0x0040, 0x1aea, 0x2099, 0x0030, 0x20a0, 0x700c, 0xa084, 0x00ff,
-	0x0040, 0x1ac1, 0x7007, 0x0004, 0x7004, 0xa084, 0x0004, 0x00c0,
-	0x1abc, 0x21a8, 0x7017, 0x0000, 0x810b, 0x7112, 0x721a, 0x731e,
-	0x7422, 0x7526, 0x780c, 0xa085, 0x0001, 0x7002, 0x7007, 0x0001,
-	0x2001, 0x04fd, 0x2004, 0xa082, 0x0005, 0x00c8, 0x1ade, 0x2009,
-	0x0022, 0x2104, 0xa084, 0x4000, 0x00c0, 0x1ad0, 0x7008, 0x800b,
-	0x00c8, 0x1ad0, 0x7007, 0x0002, 0xa08c, 0x01e0, 0x00c0, 0x1aea,
-	0x53a5, 0xa006, 0x7003, 0x0000, 0x007c, 0x2030, 0x2138, 0xa782,
-	0x0021, 0x0048, 0x1af5, 0x2009, 0x0020, 0x2600, 0x1078, 0x1b0f,
-	0x00c0, 0x1b0e, 0xa7ba, 0x0020, 0x0048, 0x1b0d, 0x0040, 0x1b0d,
-	0x2708, 0xa6b0, 0x0020, 0xa290, 0x0040, 0xa399, 0x0000, 0xa4a1,
-	0x0000, 0xa5a9, 0x0000, 0x0078, 0x1aef, 0xa006, 0x007c, 0x81ff,
-	0x0040, 0x1b50, 0x2098, 0x20a1, 0x0030, 0x700c, 0xa084, 0x00ff,
-	0x0040, 0x1b21, 0x7007, 0x0004, 0x7004, 0xa084, 0x0004, 0x00c0,
-	0x1b1c, 0x21a8, 0x7017, 0x0000, 0x810b, 0x7112, 0x721a, 0x731e,
-	0x7422, 0x7526, 0x780c, 0xa085, 0x0000, 0x7002, 0x53a6, 0x7007,
-	0x0001, 0x2001, 0x04fd, 0x2004, 0xa082, 0x0005, 0x00c8, 0x1b3f,
-	0x2009, 0x0022, 0x2104, 0xa084, 0x4000, 0x00c0, 0x1b31, 0x7010,
-	0xa084, 0xf000, 0x0040, 0x1b48, 0x7007, 0x0008, 0x0078, 0x1b4c,
-	0x7108, 0x8103, 0x00c8, 0x1b31, 0x7007, 0x0002, 0xa184, 0x01e0,
-	0x7003, 0x0000, 0x007c, 0x2001, 0x04fd, 0x2004, 0xa082, 0x0004,
-	0x00c8, 0x1b5c, 0x0078, 0x1b5f, 0xa006, 0x0078, 0x1b61, 0xa085,
-	0x0001, 0x007c, 0x0e7e, 0x2071, 0x5100, 0x2d08, 0x7058, 0x6802,
-	0xa005, 0x00c0, 0x1b6c, 0x715e, 0x715a, 0x0e7f, 0x007c, 0x2c08,
-	0x7858, 0x6002, 0xa005, 0x00c0, 0x1b76, 0x795e, 0x795a, 0x007c,
-	0x2091, 0x8000, 0x6003, 0x0000, 0x2c08, 0x785c, 0xa065, 0x00c0,
-	0x1b84, 0x795a, 0x0078, 0x1b85, 0x6102, 0x795e, 0x2091, 0x8001,
-	0x1078, 0x21ef, 0x007c, 0x0e7e, 0x2071, 0x5100, 0x7058, 0xa06d,
-	0x0040, 0x1b99, 0x6800, 0x705a, 0xa005, 0x00c0, 0x1b98, 0x705e,
-	0x8dff, 0x0e7f, 0x007c, 0x0d7e, 0x0c7e, 0x0f7e, 0x2079, 0x5100,
-	0xaf80, 0x0016, 0x2060, 0x6000, 0xa005, 0x0040, 0x1bc9, 0x2068,
-	0x6814, 0xa306, 0x00c0, 0x1bb2, 0x6828, 0xa084, 0x00ff, 0xa406,
-	0x0040, 0x1bb5, 0x2d60, 0x0078, 0x1ba3, 0x6800, 0xa005, 0x6002,
-	0x00c0, 0x1bc1, 0xaf80, 0x0016, 0xac06, 0x0040, 0x1bc0, 0x2c00,
-	0x785e, 0x0d7e, 0x689c, 0xa005, 0x0040, 0x1bc8, 0x1078, 0x19b3,
-	0x007f, 0x0f7f, 0x0c7f, 0x0d7f, 0xa005, 0x007c, 0x0d7e, 0x0c7e,
-	0x0f7e, 0x2079, 0x5100, 0xaf80, 0x0016, 0x2060, 0x6000, 0xa005,
-	0x0040, 0x1bf8, 0x2068, 0x6814, 0xa084, 0x00ff, 0xa306, 0x0040,
-	0x1be4, 0x2d60, 0x0078, 0x1bd6, 0x6800, 0xa005, 0x6002, 0x00c0,
-	0x1bf0, 0xaf80, 0x0016, 0xac06, 0x0040, 0x1bef, 0x2c00, 0x785e,
-	0x0d7e, 0x689c, 0xa005, 0x0040, 0x1bf7, 0x1078, 0x19b3, 0x007f,
-	0x0f7f, 0x0c7f, 0x0d7f, 0xa005, 0x007c, 0x0d7e, 0x0c7e, 0x0f7e,
-	0x2079, 0x5100, 0xaf80, 0x0016, 0x2060, 0x6000, 0xa06d, 0x0040,
-	0x1c24, 0x6814, 0xa306, 0x0040, 0x1c10, 0x2d60, 0x0078, 0x1c05,
-	0x6800, 0xa005, 0x6002, 0x00c0, 0x1c1c, 0xaf80, 0x0016, 0xac06,
-	0x0040, 0x1c1b, 0x2c00, 0x785e, 0x0d7e, 0x689c, 0xa005, 0x0040,
-	0x1c23, 0x1078, 0x19b3, 0x007f, 0x0f7f, 0x0c7f, 0x0d7f, 0xa005,
-	0x007c, 0x2091, 0x8000, 0x2069, 0x5140, 0x6800, 0xa086, 0x0000,
-	0x0040, 0x1c37, 0x2091, 0x8001, 0x78e3, 0x0009, 0x007c, 0x6880,
-	0xa0bc, 0xff00, 0x2041, 0x0021, 0x2049, 0x0004, 0x2051, 0x0010,
-	0x1078, 0x1980, 0x8738, 0xa784, 0x001f, 0x00c0, 0x1c40, 0x2091,
-	0x8001, 0x2001, 0x800a, 0x0078, 0x1c57, 0x2001, 0x800c, 0x0078,
-	0x1c57, 0x1078, 0x1a2b, 0x2001, 0x800d, 0x0078, 0x1c57, 0x70c2,
-	0x2061, 0x0000, 0x601b, 0x0001, 0x2091, 0x4080, 0x007c, 0x6004,
-	0x2c08, 0x2063, 0x0000, 0x7884, 0x8000, 0x7886, 0x7888, 0xa005,
-	0x798a, 0x0040, 0x1c6e, 0x2c02, 0x0078, 0x1c6f, 0x798e, 0x007c,
-	0x6807, 0x0103, 0x0c7e, 0x2061, 0x5100, 0x2d08, 0x206b, 0x0000,
-	0x6084, 0x8000, 0x6086, 0x6088, 0xa005, 0x618a, 0x0040, 0x1c83,
-	0x2d02, 0x0078, 0x1c84, 0x618e, 0x0c7f, 0x007c, 0x1078, 0x1c97,
-	0x0040, 0x1c96, 0x0c7e, 0x609c, 0xa065, 0x0040, 0x1c91, 0x1078,
-	0x19b3, 0x0c7f, 0x609f, 0x0000, 0x1078, 0x1948, 0x007c, 0x788c,
-	0xa065, 0x0040, 0x1ca9, 0x2091, 0x8000, 0x7884, 0x8001, 0x7886,
-	0x2c04, 0x788e, 0xa005, 0x00c0, 0x1ca7, 0x788a, 0x8000, 0x2091,
-	0x8001, 0x007c, 0x20a9, 0x0010, 0xa006, 0x8004, 0x8086, 0x818e,
-	0x00c8, 0x1cb3, 0xa200, 0x0070, 0x1cb7, 0x0078, 0x1cae, 0x8086,
-	0x818e, 0x007c, 0x157e, 0x20a9, 0x0010, 0xa005, 0x0040, 0x1cdd,
-	0xa11a, 0x00c8, 0x1cdd, 0x8213, 0x818d, 0x0048, 0x1cce, 0xa11a,
-	0x00c8, 0x1ccf, 0x0070, 0x1cd5, 0x0078, 0x1cc3, 0xa11a, 0x2308,
-	0x8210, 0x0070, 0x1cd5, 0x0078, 0x1cc3, 0x007e, 0x3200, 0xa084,
-	0xf7ff, 0x2080, 0x007f, 0x157f, 0x007c, 0x007e, 0x3200, 0xa085,
-	0x0800, 0x0078, 0x1cd9, 0x7994, 0x70d0, 0xa106, 0x0040, 0x1d51,
-	0x2091, 0x8000, 0x2071, 0x0020, 0x7004, 0xa005, 0x00c0, 0x1d51,
-	0x7008, 0x7208, 0xa206, 0x00c0, 0x1d51, 0xa286, 0x0008, 0x00c0,
-	0x1d51, 0x2071, 0x0010, 0x1078, 0x192e, 0x0040, 0x1d51, 0x7a9c,
-	0x7b98, 0x7ca4, 0x7da0, 0xa184, 0xff00, 0x0040, 0x1d1f, 0x2031,
-	0x0000, 0x810b, 0x86b5, 0x810b, 0x86b5, 0x810b, 0x86b5, 0x810b,
-	0x86b5, 0x810b, 0x86b5, 0x810b, 0x86b5, 0x2100, 0xa210, 0x2600,
-	0xa319, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x0078, 0x1d29, 0x8107,
-	0x8004, 0x8004, 0xa210, 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9,
-	0x0000, 0x2009, 0x0020, 0x1078, 0x1929, 0x2091, 0x8001, 0x0040,
-	0x1d48, 0x1078, 0x1948, 0x78a8, 0x8000, 0x78aa, 0xa086, 0x0002,
-	0x00c0, 0x1d51, 0x2091, 0x8000, 0x78e3, 0x0002, 0x78ab, 0x0000,
-	0x78cc, 0xa085, 0x0003, 0x78ce, 0x2091, 0x8001, 0x0078, 0x1d51,
-	0x78ab, 0x0000, 0x1078, 0x20ac, 0x6004, 0xa084, 0x000f, 0x0079,
-	0x1d56, 0x2071, 0x0010, 0x2091, 0x8001, 0x007c, 0x1d66, 0x1d88,
-	0x1dae, 0x1d66, 0x1dcb, 0x1d75, 0x1f2c, 0x1f47, 0x1d66, 0x1d82,
-	0x1da8, 0x1e13, 0x1e82, 0x1ed2, 0x1ee4, 0x1f43, 0x2039, 0x0400,
-	0x78dc, 0xa705, 0x78de, 0x6008, 0xa705, 0x600a, 0x1078, 0x1fc7,
-	0x609c, 0x78da, 0x1078, 0x2094, 0x007c, 0x78dc, 0xa084, 0x0100,
-	0x0040, 0x1d7c, 0x0078, 0x1d66, 0x601c, 0xa085, 0x0080, 0x601e,
-	0x0078, 0x1d8f, 0x1078, 0x1b53, 0x00c0, 0x1d66, 0x1078, 0x20c6,
-	0x78dc, 0xa084, 0x0100, 0x0040, 0x1d8f, 0x0078, 0x1d66, 0x78df,
-	0x0000, 0x6004, 0x8007, 0xa084, 0x00ff, 0x78d2, 0x8001, 0x609f,
-	0x0000, 0x0040, 0x1da5, 0x1078, 0x1fc7, 0x0040, 0x1da5, 0x78dc,
-	0xa085, 0x0100, 0x78de, 0x0078, 0x1da7, 0x1078, 0x1feb, 0x007c,
-	0x1078, 0x1b53, 0x00c0, 0x1d66, 0x1078, 0x20c2, 0x78dc, 0xa08c,
-	0x0e00, 0x00c0, 0x1db7, 0xa084, 0x0100, 0x00c0, 0x1db9, 0x0078,
-	0x1d66, 0x1078, 0x1fc7, 0x00c0, 0x1dca, 0x6104, 0xa18c, 0x00ff,
-	0xa186, 0x0007, 0x0040, 0x1f84, 0xa186, 0x000f, 0x0040, 0x1f84,
-	0x1078, 0x1feb, 0x007c, 0x78dc, 0xa084, 0x0100, 0x0040, 0x1dd2,
-	0x0078, 0x1d66, 0x78df, 0x0000, 0x6714, 0x2011, 0x0001, 0x20a9,
-	0x0001, 0x6018, 0xa084, 0x00ff, 0xa005, 0x0040, 0x1df5, 0x2011,
-	0x0001, 0xa7bc, 0xff00, 0x20a9, 0x0020, 0xa08e, 0x0001, 0x0040,
-	0x1df5, 0x2039, 0x0000, 0x2011, 0x0002, 0x20a9, 0x0100, 0xa08e,
-	0x0002, 0x0040, 0x1df5, 0x0078, 0x1e10, 0x1078, 0x1973, 0x2091,
-	0x8000, 0x682b, 0x0000, 0x682f, 0x0000, 0x6808, 0xa084, 0xffde,
-	0x680a, 0xade8, 0x0010, 0x2091, 0x8001, 0x0070, 0x1e09, 0x0078,
-	0x1df7, 0x8211, 0x0040, 0x1e10, 0x20a9, 0x0100, 0x0078, 0x1df7,
-	0x1078, 0x1948, 0x007c, 0x2001, 0x5167, 0x2004, 0xa084, 0x8000,
-	0x0040, 0x1fac, 0x6114, 0x1078, 0x20e3, 0x6900, 0xa184, 0x0001,
-	0x0040, 0x1e34, 0x6028, 0xa084, 0x00ff, 0x00c0, 0x1fa4, 0x6800,
-	0xa084, 0x0001, 0x0040, 0x1fac, 0x6803, 0x0000, 0x680b, 0x0000,
-	0x6807, 0x0000, 0x0078, 0x1fb4, 0x2011, 0x0001, 0x6020, 0xd0f4,
-	0x0040, 0x1e3c, 0xa295, 0x0002, 0xd0c4, 0x0040, 0x1e41, 0xa295,
-	0x0008, 0xd0cc, 0x0040, 0x1e46, 0xa295, 0x0400, 0x601c, 0xa084,
-	0x0002, 0x0040, 0x1e4d, 0xa295, 0x0004, 0x602c, 0xa08c, 0x00ff,
-	0xa182, 0x0002, 0x0048, 0x1fb0, 0xa182, 0x001b, 0x00c8, 0x1fb0,
-	0x0040, 0x1fb0, 0x690e, 0x602c, 0x8007, 0xa08c, 0x00ff, 0xa182,
-	0x0002, 0x0048, 0x1fb0, 0xa182, 0x001b, 0x00c8, 0x1fb0, 0x0040,
-	0x1fb0, 0x6912, 0x6030, 0xa005, 0x00c0, 0x1e70, 0x2001, 0x001e,
-	0x8000, 0x6816, 0x6028, 0xa084, 0x00ff, 0x0040, 0x1fac, 0x6806,
-	0x6028, 0x8007, 0xa084, 0x00ff, 0x0040, 0x1fac, 0x680a, 0x6a02,
-	0x0078, 0x1fb4, 0x2001, 0x5167, 0x2004, 0xa084, 0x8000, 0x0040,
-	0x1fac, 0x6114, 0x1078, 0x20e3, 0x2091, 0x8000, 0x6a04, 0x6b08,
-	0x6418, 0xa484, 0x0003, 0x0040, 0x1ea8, 0x6128, 0xa18c, 0x00ff,
-	0x8001, 0x00c0, 0x1ea1, 0x2100, 0xa210, 0x0048, 0x1ece, 0x0078,
-	0x1ea8, 0x8001, 0x00c0, 0x1ece, 0x2100, 0xa212, 0x0048, 0x1ece,
-	0xa484, 0x000c, 0x0040, 0x1ec2, 0x6128, 0x810f, 0xa18c, 0x00ff,
-	0xa082, 0x0004, 0x00c0, 0x1eba, 0x2100, 0xa318, 0x0048, 0x1ece,
-	0x0078, 0x1ec2, 0xa082, 0x0004, 0x00c0, 0x1ece, 0x2100, 0xa31a,
-	0x0048, 0x1ece, 0x6030, 0xa005, 0x0040, 0x1ec8, 0x8000, 0x6816,
-	0x6a06, 0x6b0a, 0x2091, 0x8001, 0x0078, 0x1fb4, 0x2091, 0x8001,
-	0x0078, 0x1fb0, 0x6114, 0x1078, 0x20e3, 0x2091, 0x8000, 0x6b08,
-	0x8318, 0x0048, 0x1ee0, 0x6b0a, 0x2091, 0x8001, 0x0078, 0x1fc3,
-	0x2091, 0x8001, 0x0078, 0x1fb0, 0x6024, 0x8007, 0xa084, 0x00ff,
-	0x0040, 0x1f02, 0xa086, 0x0080, 0x00c0, 0x1f2a, 0x20a9, 0x0008,
-	0x2069, 0x7510, 0x2091, 0x8000, 0x6800, 0xa084, 0xfcff, 0x6802,
-	0xade8, 0x0008, 0x0070, 0x1efe, 0x0078, 0x1ef4, 0x2091, 0x8001,
-	0x0078, 0x1fb4, 0x6028, 0xa015, 0x0040, 0x1f2a, 0x6114, 0x1078,
-	0x20e3, 0x0d7e, 0xade8, 0x0007, 0x2091, 0x8000, 0x6800, 0xa00d,
-	0x0040, 0x1f27, 0xa206, 0x0040, 0x1f18, 0x2168, 0x0078, 0x1f0e,
-	0x0c7e, 0x2160, 0x6000, 0x6802, 0x1078, 0x1948, 0x0c7f, 0x0d7f,
-	0x6808, 0x8000, 0x680a, 0x2091, 0x8001, 0x0078, 0x1fc3, 0x2091,
-	0x8001, 0x0d7f, 0x0078, 0x1fac, 0x6114, 0x1078, 0x20e3, 0x6800,
-	0xa084, 0x0001, 0x0040, 0x1f9c, 0x2091, 0x8000, 0x6a04, 0x8210,
-	0x0048, 0x1f3f, 0x6a06, 0x2091, 0x8001, 0x0078, 0x1fc3, 0x2091,
-	0x8001, 0x0078, 0x1fb0, 0x1078, 0x1b53, 0x00c0, 0x1d66, 0x6114,
-	0x1078, 0x20e3, 0x60be, 0x60bb, 0x0000, 0x6900, 0xa184, 0x0008,
-	0x0040, 0x1f56, 0x6020, 0xa085, 0x0100, 0x6022, 0xa184, 0x0001,
-	0x0040, 0x1fac, 0xa184, 0x0100, 0x00c0, 0x1f98, 0xa184, 0x0200,
-	0x00c0, 0x1f94, 0x681c, 0xa005, 0x00c0, 0x1fa0, 0x6004, 0xa084,
-	0x00ff, 0xa086, 0x000f, 0x00c0, 0x1f6f, 0x1078, 0x20c6, 0x78df,
-	0x0000, 0x6004, 0x8007, 0xa084, 0x00ff, 0x78d2, 0x8001, 0x609f,
-	0x0000, 0x0040, 0x1f84, 0x1078, 0x1fc7, 0x0040, 0x1f84, 0x78dc,
-	0xa085, 0x0100, 0x78de, 0x007c, 0x78d7, 0x0000, 0x78db, 0x0000,
-	0x6024, 0xa084, 0xff00, 0x6026, 0x1078, 0x39de, 0x0040, 0x1ce3,
-	0x1078, 0x1b78, 0x0078, 0x1ce3, 0x2009, 0x0017, 0x0078, 0x1fb6,
-	0x2009, 0x000e, 0x0078, 0x1fb6, 0x2009, 0x0007, 0x0078, 0x1fb6,
-	0x2009, 0x0035, 0x0078, 0x1fb6, 0x2009, 0x003e, 0x0078, 0x1fb6,
-	0x2009, 0x0004, 0x0078, 0x1fb6, 0x2009, 0x0006, 0x0078, 0x1fb6,
-	0x2009, 0x0016, 0x0078, 0x1fb6, 0x2009, 0x0001, 0x6024, 0xa084,
-	0xff00, 0xa105, 0x6026, 0x2091, 0x8000, 0x1078, 0x1c5f, 0x2091,
-	0x8001, 0x0078, 0x1ce3, 0x1078, 0x1948, 0x0078, 0x1ce3, 0x78d4,
-	0xa06d, 0x00c0, 0x1fd2, 0x2c00, 0x78d6, 0x78da, 0x609f, 0x0000,
-	0x0078, 0x1fde, 0x2c00, 0x689e, 0x609f, 0x0000, 0x78d6, 0x2d00,
-	0x6002, 0x78d8, 0xad06, 0x00c0, 0x1fde, 0x6002, 0x78d0, 0x8001,
-	0x78d2, 0x00c0, 0x1fea, 0x78dc, 0xa084, 0xfeff, 0x78de, 0x78d8,
-	0x2060, 0xa006, 0x007c, 0xa02e, 0x2530, 0x611c, 0x61a2, 0xa184,
-	0xe1ff, 0x601e, 0xa184, 0x0060, 0x0040, 0x1ffa, 0x0e7e, 0x1078,
-	0x47c2, 0x0e7f, 0x6596, 0x65a6, 0x669a, 0x66aa, 0x60af, 0x0000,
-	0x60b3, 0x0000, 0x6714, 0x1078, 0x1973, 0x2091, 0x8000, 0x60a0,
-	0xa084, 0x8000, 0x00c0, 0x2021, 0x6808, 0xa084, 0x0001, 0x0040,
-	0x2021, 0x2091, 0x8001, 0x1078, 0x19c0, 0x2091, 0x8000, 0x1078,
-	0x1c5f, 0x2091, 0x8001, 0x78d7, 0x0000, 0x78db, 0x0000, 0x0078,
-	0x2093, 0x6024, 0xa096, 0x0001, 0x00c0, 0x2028, 0x8000, 0x6026,
-	0x6a10, 0x6814, 0x2091, 0x8001, 0xa202, 0x0048, 0x2037, 0x0040,
-	0x2037, 0x2039, 0x0200, 0x1078, 0x2094, 0x0078, 0x2093, 0x2c08,
-	0x2091, 0x8000, 0x60a0, 0xa084, 0x8000, 0x0040, 0x2064, 0x6800,
-	0xa065, 0x0040, 0x2069, 0x6a04, 0x0e7e, 0x2071, 0x5140, 0x7000,
-	0xa084, 0x0001, 0x0040, 0x205e, 0x7048, 0xa206, 0x00c0, 0x205e,
-	0x6b04, 0x231c, 0x2160, 0x6302, 0x2300, 0xa005, 0x00c0, 0x2059,
-	0x6902, 0x2260, 0x6102, 0x0e7f, 0x0078, 0x2070, 0x2160, 0x6202,
-	0x6906, 0x0e7f, 0x0078, 0x2070, 0x6800, 0xa065, 0x0040, 0x2069,
-	0x6102, 0x6902, 0x00c0, 0x206d, 0x6906, 0x2160, 0x6003, 0x0000,
-	0x2160, 0x60a0, 0xa084, 0x8000, 0x0040, 0x207a, 0x6808, 0xa084,
-	0xfffc, 0x680a, 0x6810, 0x8000, 0x6812, 0x2091, 0x8001, 0x6808,
-	0xa08c, 0x0040, 0x0040, 0x2089, 0xa086, 0x0040, 0x680a, 0x1078,
-	0x19d1, 0x2091, 0x8000, 0x1078, 0x21d2, 0x2091, 0x8001, 0x78db,
-	0x0000, 0x78d7, 0x0000, 0x007c, 0x6008, 0xa705, 0x600a, 0x2091,
-	0x8000, 0x1078, 0x1c5f, 0x2091, 0x8001, 0x78d8, 0xa065, 0x0040,
-	0x20a7, 0x609c, 0x78da, 0x609f, 0x0000, 0x0078, 0x2097, 0x78d7,
-	0x0000, 0x78db, 0x0000, 0x007c, 0x7990, 0x7894, 0x8000, 0xa10a,
-	0x00c8, 0x20b3, 0xa006, 0x7896, 0x70d2, 0x7804, 0xa005, 0x0040,
-	0x20c1, 0x8001, 0x7806, 0x00c0, 0x20c1, 0x0068, 0x20c1, 0x2091,
-	0x4080, 0x007c, 0x2039, 0x20da, 0x0078, 0x20c8, 0x2039, 0x20e0,
-	0x2704, 0xa005, 0x0040, 0x20d9, 0xac00, 0x2068, 0x6b08, 0x6c0c,
-	0x6910, 0x6a14, 0x690a, 0x6a0e, 0x6b12, 0x6c16, 0x8738, 0x0078,
-	0x20c8, 0x007c, 0x0003, 0x0009, 0x000f, 0x0015, 0x001b, 0x0000,
-	0x0015, 0x001b, 0x0000, 0x0c7e, 0x1078, 0x3b69, 0x2c68, 0x0c7f,
-	0x007c, 0x0010, 0x215a, 0x0068, 0x215a, 0x2029, 0x0000, 0x78cb,
-	0x0000, 0x788c, 0xa065, 0x0040, 0x2153, 0x2009, 0x5174, 0x2104,
-	0xa084, 0x0001, 0x0040, 0x2121, 0x6004, 0xa086, 0x0103, 0x00c0,
-	0x2121, 0x6018, 0xa005, 0x00c0, 0x2121, 0x6014, 0xa005, 0x00c0,
-	0x2121, 0x0d7e, 0x2069, 0x0000, 0x6818, 0xa084, 0x0001, 0x00c0,
-	0x2120, 0x600c, 0x70c6, 0x6010, 0x70ca, 0x70c3, 0x8020, 0x681b,
-	0x0001, 0x2091, 0x4080, 0x0d7f, 0x1078, 0x1c86, 0x0078, 0x2158,
-	0x0d7f, 0x1078, 0x215b, 0x0040, 0x2153, 0x6204, 0xa294, 0x00ff,
-	0xa296, 0x0003, 0x0040, 0x2133, 0x6204, 0xa296, 0x0110, 0x00c0,
-	0x2141, 0x78cb, 0x0001, 0x6204, 0xa294, 0xff00, 0x8217, 0x8211,
-	0x0040, 0x2141, 0x85ff, 0x00c0, 0x2153, 0x8210, 0xa202, 0x00c8,
-	0x2153, 0x057e, 0x1078, 0x216a, 0x057f, 0x0040, 0x214e, 0x78e0,
-	0xa086, 0x0003, 0x0040, 0x2153, 0x0078, 0x2141, 0x8528, 0x78c8,
-	0xa005, 0x0040, 0x20f1, 0x85ff, 0x0040, 0x215a, 0x2091, 0x4080,
-	0x78b0, 0x70d6, 0x007c, 0x7bac, 0x79b0, 0x70d4, 0xa102, 0x00c0,
-	0x2164, 0x2300, 0xa005, 0x007c, 0x0048, 0x2168, 0xa302, 0x007c,
-	0x8002, 0x007c, 0x2001, 0x04fd, 0x2004, 0xa082, 0x0005, 0x00c8,
-	0x2184, 0x2091, 0x8000, 0x2071, 0x0020, 0x7004, 0xa005, 0x00c0,
-	0x21b9, 0x7008, 0x7208, 0xa206, 0x00c0, 0x21b9, 0xa286, 0x0008,
-	0x00c0, 0x21b9, 0x2071, 0x0010, 0x1078, 0x21be, 0x2009, 0x0020,
-	0x6004, 0xa086, 0x0103, 0x00c0, 0x2193, 0x6028, 0xa005, 0x00c0,
-	0x2193, 0x2009, 0x000c, 0x1078, 0x1924, 0x0040, 0x21ac, 0x78c4,
-	0x8000, 0x78c6, 0xa086, 0x0002, 0x00c0, 0x21b9, 0x2091, 0x8000,
-	0x78e3, 0x0003, 0x78c7, 0x0000, 0x78cc, 0xa085, 0x0300, 0x78ce,
-	0x2091, 0x8001, 0x0078, 0x21b9, 0x78c7, 0x0000, 0x1078, 0x1c86,
-	0x79ac, 0x78b0, 0x8000, 0xa10a, 0x00c8, 0x21b7, 0xa006, 0x78b2,
-	0xa006, 0x2071, 0x0010, 0x2091, 0x8001, 0x007c, 0x8107, 0x8004,
-	0x8004, 0x7ab8, 0x7bb4, 0x7cc0, 0x7dbc, 0xa210, 0xa399, 0x0000,
-	0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x007c, 0x2009, 0x515b, 0x2091,
-	0x8000, 0x200a, 0x0f7e, 0x0e7e, 0x2071, 0x5140, 0x7000, 0xa086,
-	0x0000, 0x00c0, 0x21ec, 0x2009, 0x5112, 0x2104, 0xa005, 0x00c0,
-	0x21ec, 0x2079, 0x0100, 0x7830, 0xa084, 0x00c0, 0x00c0, 0x21ec,
-	0x0018, 0x21ec, 0x781b, 0x004b, 0x0e7f, 0x0f7f, 0x007c, 0x0f7e,
-	0x0e7e, 0x2071, 0x5140, 0x2091, 0x8000, 0x7000, 0xa086, 0x0000,
-	0x00c0, 0x2205, 0x2079, 0x0100, 0x7830, 0xa084, 0x00c0, 0x00c0,
-	0x2205, 0x0018, 0x2205, 0x781b, 0x004d, 0x2091, 0x8001, 0x0e7f,
-	0x0f7f, 0x007c, 0x127e, 0x2091, 0x2300, 0x2071, 0x5140, 0x2079,
-	0x0100, 0x784b, 0x000f, 0x0098, 0x2218, 0x7838, 0x0078, 0x2211,
-	0x20a9, 0x0040, 0x7800, 0xa082, 0x0004, 0x0048, 0x2221, 0x20a9,
-	0x0060, 0x789b, 0x0000, 0x78af, 0x0000, 0x78af, 0x0000, 0x0070,
-	0x222b, 0x0078, 0x2223, 0x7800, 0xa082, 0x0004, 0x0048, 0x223a,
-	0x70b7, 0x0096, 0x2019, 0x4ee7, 0x1078, 0x2276, 0x702f, 0x8001,
-	0x0078, 0x2246, 0x70b7, 0x0000, 0x2019, 0x4d5f, 0x1078, 0x2276,
-	0x2019, 0x4d9e, 0x1078, 0x2276, 0x702f, 0x8000, 0x7003, 0x0000,
-	0x1078, 0x237f, 0x7004, 0xa084, 0x000f, 0x017e, 0x2009, 0x04fd,
-	0x210c, 0xa18a, 0x0005, 0x0048, 0x225b, 0x0038, 0x2261, 0xa085,
-	0x6280, 0x0078, 0x2263, 0x0028, 0x2261, 0xa085, 0x6280, 0x0078,
-	0x2263, 0xa085, 0x62c0, 0x017f, 0x7806, 0x780f, 0xb204, 0x7843,
-	0x00d8, 0x7853, 0x0080, 0x780b, 0x0008, 0x7047, 0x0008, 0x7053,
-	0x517f, 0x704f, 0x0000, 0x127f, 0x2000, 0x007c, 0x137e, 0x147e,
-	0x157e, 0x047e, 0x20a1, 0x012b, 0x2304, 0xa005, 0x789a, 0x0040,
-	0x2296, 0x8318, 0x2324, 0x8318, 0x2398, 0x24a8, 0xa484, 0xff00,
-	0x0040, 0x228e, 0xa482, 0x0100, 0x20a9, 0x0100, 0x2020, 0x53a6,
-	0xa005, 0x00c0, 0x2285, 0x3318, 0x0078, 0x227c, 0x047f, 0x157f,
-	0x147f, 0x137f, 0x007c, 0xa18c, 0x000f, 0x2011, 0x0101, 0x2204,
-	0xa084, 0xfff0, 0xa105, 0x2012, 0x1078, 0x237f, 0x007c, 0x2011,
-	0x0101, 0x20a9, 0x0009, 0x810b, 0x0070, 0x22b0, 0x0078, 0x22ab,
-	0xa18c, 0x0e00, 0x2204, 0xa084, 0xf1ff, 0xa105, 0x2012, 0x007c,
-	0x2009, 0x0101, 0x20a9, 0x0005, 0x8213, 0x0070, 0x22c1, 0x0078,
-	0x22bc, 0xa294, 0x00e0, 0x2104, 0xa084, 0xff1f, 0xa205, 0x200a,
-	0x007c, 0x2011, 0x0101, 0x20a9, 0x000c, 0x810b, 0x0070, 0x22d2,
-	0x0078, 0x22cd, 0xa18c, 0xf000, 0x2204, 0xa084, 0x0fff, 0xa105,
-	0x2012, 0x007c, 0x2011, 0x0102, 0x2204, 0xa084, 0xffcf, 0xa105,
-	0x2012, 0x007c, 0x8103, 0x8003, 0xa080, 0x0020, 0x0c7e, 0x2061,
-	0x0100, 0x609a, 0x62ac, 0x63ac, 0x0c7f, 0x007c, 0x8103, 0x8003,
-	0xa080, 0x0022, 0x0c7e, 0x2061, 0x0100, 0x609a, 0x60a4, 0xa084,
-	0xffdf, 0x60ae, 0x0c7f, 0x007c, 0x8103, 0x8003, 0xa080, 0x0022,
-	0x0c7e, 0x2061, 0x0100, 0x609a, 0x60a4, 0xa085, 0x0020, 0x60ae,
-	0x0c7f, 0x007c, 0x8103, 0x8003, 0xa080, 0x0020, 0x0c7e, 0x2061,
-	0x0100, 0x609a, 0x60a4, 0x62ae, 0x2010, 0x60a4, 0x63ae, 0x2018,
-	0x0c7f, 0x007c, 0x2091, 0x8000, 0x0c7e, 0x0e7e, 0x6818, 0xa005,
-	0x0040, 0x235d, 0x2061, 0x7500, 0x1078, 0x2365, 0x0040, 0x2349,
-	0x20a9, 0x0000, 0x2061, 0x7400, 0x0c7e, 0x1078, 0x2365, 0x0040,
-	0x2339, 0x0c7f, 0x8c60, 0x0070, 0x2337, 0x0078, 0x232c, 0x0078,
-	0x235d, 0x007f, 0xa082, 0x7400, 0x2071, 0x5140, 0x7086, 0x7182,
-	0x2001, 0x0004, 0x706e, 0x7093, 0x000f, 0x1078, 0x21cd, 0x0078,
-	0x2359, 0x60c0, 0xa005, 0x00c0, 0x235d, 0x2071, 0x5140, 0x7182,
-	0x2c00, 0x708a, 0x2001, 0x0006, 0x706e, 0x7093, 0x000f, 0x1078,
-	0x21cd, 0x2001, 0x0000, 0x0078, 0x235f, 0x2001, 0x0001, 0x2091,
-	0x8001, 0xa005, 0x0e7f, 0x0c7f, 0x007c, 0x2c04, 0xa005, 0x0040,
-	0x237c, 0x2060, 0x600c, 0xa306, 0x00c0, 0x2379, 0x6010, 0xa206,
-	0x00c0, 0x2379, 0x6014, 0xa106, 0x00c0, 0x2379, 0xa006, 0x0078,
-	0x237e, 0x6000, 0x0078, 0x2366, 0xa085, 0x0001, 0x007c, 0x2011,
-	0x5141, 0x220c, 0xa18c, 0x000f, 0x2011, 0x013b, 0x2204, 0xa084,
-	0x0100, 0x0040, 0x2395, 0x2021, 0xff04, 0x2122, 0x810b, 0x810b,
-	0x810b, 0x810b, 0xa18d, 0x0f00, 0x2104, 0x007c, 0x0e7e, 0x68e4,
-	0xa08c, 0x0020, 0x0040, 0x23e9, 0xa084, 0x0006, 0x00c0, 0x23e9,
-	0x6014, 0x8007, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xa0f0,
-	0x5380, 0x7004, 0xa084, 0x000a, 0x00c0, 0x23e9, 0x7108, 0xa194,
-	0xff00, 0x0040, 0x23e9, 0xa18c, 0x00ff, 0x2001, 0x000c, 0xa106,
-	0x0040, 0x23d0, 0x2001, 0x0012, 0xa106, 0x0040, 0x23d4, 0x2001,
-	0x0014, 0xa106, 0x0040, 0x23d8, 0x2001, 0x0019, 0xa106, 0x0040,
-	0x23dc, 0x2001, 0x0032, 0xa106, 0x0040, 0x23e0, 0x0078, 0x23e4,
-	0x2009, 0x0012, 0x0078, 0x23e6, 0x2009, 0x0014, 0x0078, 0x23e6,
-	0x2009, 0x0019, 0x0078, 0x23e6, 0x2009, 0x0020, 0x0078, 0x23e6,
-	0x2009, 0x003f, 0x0078, 0x23e6, 0x2011, 0x0000, 0x2100, 0xa205,
-	0x700a, 0x0e7f, 0x007c, 0x0068, 0x23eb, 0x2091, 0x8000, 0x2071,
-	0x0000, 0x007e, 0x7018, 0xa084, 0x0001, 0x00c0, 0x23f2, 0x007f,
-	0x2071, 0x0010, 0x70ca, 0x007f, 0x70c6, 0x70c3, 0x8002, 0x70db,
-	0x0741, 0x70df, 0x0000, 0x2071, 0x0000, 0x701b, 0x0001, 0x2091,
-	0x4080, 0x0078, 0x2409, 0x107e, 0x007e, 0x127e, 0x2091, 0x2300,
-	0x7f3c, 0x7e58, 0x7c30, 0x7d38, 0x77c2, 0x74c6, 0x76ca, 0x75ce,
-	0xa594, 0x003f, 0xa49c, 0x0003, 0xa484, 0x000f, 0x0079, 0x2420,
-	0x2432, 0x2432, 0x2432, 0x276c, 0x393b, 0x2430, 0x2461, 0x246b,
-	0x2430, 0x2430, 0x2430, 0x2430, 0x2430, 0x2430, 0x2430, 0x2430,
-	0x1078, 0x23eb, 0x8507, 0xa084, 0x001f, 0x0079, 0x2437, 0x2475,
-	0x276c, 0x2926, 0x2a23, 0x2a4b, 0x2ced, 0x2f98, 0x2fdb, 0x3026,
-	0x30ab, 0x3163, 0x320c, 0x2461, 0x2848, 0x2f6d, 0x2457, 0x3cc8,
-	0x3ce8, 0x3eae, 0x3eba, 0x3f8f, 0x2457, 0x2457, 0x4062, 0x4066,
-	0x3cc6, 0x2457, 0x3e19, 0x2457, 0x3b8c, 0x246b, 0x2457, 0x1078,
-	0x23eb, 0x0018, 0x2410, 0x127f, 0x2091, 0x8001, 0x007f, 0x107f,
-	0x007c, 0x2019, 0x4e3b, 0x1078, 0x2276, 0x702f, 0x0001, 0x781b,
-	0x004f, 0x0078, 0x2459, 0x2019, 0x4d9e, 0x1078, 0x2276, 0x702f,
-	0x8000, 0x781b, 0x00d0, 0x0078, 0x2459, 0x7242, 0x2009, 0x510f,
-	0x200b, 0x0000, 0xa584, 0x0001, 0x00c0, 0x3ba0, 0x0040, 0x2492,
-	0x1078, 0x23eb, 0x7003, 0x0000, 0x704b, 0x0000, 0x7043, 0x0000,
-	0x7037, 0x0000, 0x1078, 0x3912, 0x0018, 0x2410, 0x2009, 0x510f,
-	0x200b, 0x0000, 0x7068, 0xa005, 0x00c0, 0x255d, 0x706c, 0xa084,
-	0x0007, 0x0079, 0x249b, 0x2594, 0x24a3, 0x24af, 0x24cc, 0x24ee,
-	0x253b, 0x2514, 0x24a3, 0x1078, 0x38fa, 0x2009, 0x0048, 0x1078,
-	0x2e39, 0x00c0, 0x24ad, 0x7003, 0x0004, 0x0078, 0x2459, 0x1078,
-	0x38fa, 0x00c0, 0x24ca, 0x7080, 0x8007, 0x7882, 0x789b, 0x0010,
-	0x78ab, 0x000c, 0x789b, 0x0060, 0x78ab, 0x0001, 0x785b, 0x0004,
-	0x2009, 0x00e0, 0x1078, 0x2e2d, 0x00c0, 0x24ca, 0x7003, 0x0004,
-	0x7093, 0x000f, 0x0078, 0x2459, 0x1078, 0x38fa, 0x00c0, 0x24ec,
-	0x7180, 0x8107, 0x7882, 0x789b, 0x0010, 0xa18c, 0x001f, 0xa18d,
-	0x00c0, 0x79aa, 0x78ab, 0x0006, 0x789b, 0x0060, 0x78ab, 0x0002,
-	0x785b, 0x0004, 0x2009, 0x00e0, 0x1078, 0x2e2d, 0x00c0, 0x24ec,
-	0x7003, 0x0004, 0x7093, 0x000f, 0x0078, 0x2459, 0x1078, 0x38fa,
-	0x00c0, 0x2512, 0x7180, 0x8107, 0x7882, 0x789b, 0x0010, 0xa18c,
-	0x001f, 0xa18d, 0x00c0, 0x79aa, 0x78ab, 0x0020, 0x7184, 0x79aa,
-	0x78ab, 0x000d, 0x789b, 0x0060, 0x78ab, 0x0004, 0x785b, 0x0004,
-	0x2009, 0x00e0, 0x1078, 0x2e2d, 0x00c0, 0x2512, 0x7003, 0x0004,
-	0x7093, 0x000f, 0x0078, 0x2459, 0x1078, 0x38fa, 0x00c0, 0x2539,
-	0x7180, 0x8107, 0x7882, 0x789b, 0x0010, 0xa18c, 0x001f, 0xa18d,
-	0x00c0, 0x79aa, 0x78ab, 0x0006, 0x789b, 0x0060, 0x78ab, 0x0002,
-	0x785b, 0x0004, 0x2009, 0x00e0, 0x1078, 0x2e2d, 0x00c0, 0x2539,
-	0x7088, 0x708b, 0x0000, 0x2068, 0x704a, 0x7003, 0x0002, 0x7093,
-	0x000f, 0x0078, 0x2459, 0x1078, 0x38fa, 0x00c0, 0x2459, 0x7088,
-	0x2068, 0x6f14, 0x1078, 0x37ef, 0x2c50, 0x1078, 0x39ac, 0x789b,
-	0x0010, 0x6814, 0xa084, 0x001f, 0xa085, 0x0080, 0x78aa, 0x6e1c,
-	0x2041, 0x0001, 0x708c, 0xa084, 0x0400, 0x2001, 0x0004, 0x0040,
-	0x255b, 0x2001, 0x0006, 0x0078, 0x267c, 0x1078, 0x38fa, 0x00c0,
-	0x2459, 0x789b, 0x0010, 0x7068, 0x2068, 0x6f14, 0x1078, 0x37ef,
-	0x2c50, 0x1078, 0x39ac, 0x6008, 0xa085, 0x0010, 0x600a, 0x6824,
-	0xa005, 0x0040, 0x257b, 0xa082, 0x0006, 0x0048, 0x2579, 0x0078,
-	0x257b, 0x6827, 0x0005, 0x6b14, 0xa39c, 0x001f, 0xa39d, 0x00c0,
-	0x7058, 0xa084, 0x8000, 0x0040, 0x2589, 0xa684, 0x0001, 0x0040,
-	0x258b, 0xa39c, 0xffbf, 0x7baa, 0x2031, 0x0020, 0x2041, 0x0001,
-	0x2001, 0x0003, 0x0078, 0x267c, 0x0018, 0x2410, 0x744c, 0xa485,
-	0x0000, 0x0040, 0x25ae, 0xa080, 0x5180, 0x2030, 0x7150, 0x8108,
-	0xa12a, 0x0048, 0x25a5, 0x2009, 0x5180, 0x2164, 0x6504, 0x85ff,
-	0x00c0, 0x25bf, 0x8421, 0x00c0, 0x259f, 0x7152, 0x7003, 0x0000,
-	0x704b, 0x0000, 0x7040, 0xa005, 0x0040, 0x3ba0, 0x0078, 0x2459,
-	0x764c, 0xa6b0, 0x5180, 0x7150, 0x2600, 0x0078, 0x25aa, 0x7152,
-	0x2568, 0x2558, 0x754a, 0x2c50, 0x6034, 0xa085, 0x0000, 0x00c0,
-	0x25bc, 0x6708, 0x773a, 0xa784, 0x033f, 0x0040, 0x25f5, 0xa784,
-	0x0021, 0x00c0, 0x25bc, 0xa784, 0x0002, 0x0040, 0x25de, 0xa784,
-	0x0004, 0x0040, 0x25bc, 0xa7bc, 0xfffb, 0x670a, 0xa784, 0x0008,
-	0x00c0, 0x25bc, 0xa784, 0x0010, 0x00c0, 0x25bc, 0xa784, 0x0200,
-	0x00c0, 0x25bc, 0xa784, 0x0100, 0x0040, 0x25f5, 0x6018, 0xa005,
-	0x00c0, 0x25bc, 0xa7bc, 0xfeff, 0x670a, 0x6823, 0x0000, 0x6e1c,
-	0xa684, 0x000e, 0x6118, 0x0040, 0x2605, 0x601c, 0xa102, 0x0048,
-	0x2608, 0x0040, 0x2608, 0x0078, 0x25b8, 0x81ff, 0x00c0, 0x25b8,
-	0x68c3, 0x0000, 0xa784, 0x0080, 0x00c0, 0x2610, 0x700c, 0x6022,
-	0xa7bc, 0xff7f, 0x670a, 0x1078, 0x39ac, 0x0018, 0x2410, 0x789b,
-	0x0010, 0xa046, 0x1078, 0x38fa, 0x00c0, 0x2459, 0x6b14, 0xa39c,
-	0x001f, 0xa39d, 0x00c0, 0x7058, 0xa084, 0x8000, 0x0040, 0x262c,
-	0xa684, 0x0001, 0x0040, 0x262e, 0xa39c, 0xffbf, 0xa684, 0x0010,
-	0x0040, 0x2634, 0xa39d, 0x0020, 0x7baa, 0x8840, 0xa684, 0x000e,
-	0x00c0, 0x263f, 0xa7bd, 0x0010, 0x670a, 0x0078, 0x267a, 0x7158,
-	0xa18c, 0x0800, 0x0040, 0x3401, 0x2011, 0x0020, 0xa684, 0x0008,
-	0x00c0, 0x2650, 0x8210, 0xa684, 0x0002, 0x00c0, 0x2650, 0x8210,
-	0x7aaa, 0x8840, 0x1078, 0x3912, 0x6a14, 0x610c, 0x8108, 0xa18c,
-	0x00ff, 0xa1e0, 0x7400, 0x2c64, 0x8cff, 0x0040, 0x2671, 0x6014,
-	0xa206, 0x00c0, 0x265b, 0x60b8, 0x8001, 0x60ba, 0x00c0, 0x2656,
-	0x0c7e, 0x2a60, 0x6008, 0xa085, 0x0100, 0x600a, 0x0c7f, 0x0078,
-	0x2594, 0x1078, 0x38fa, 0x00c0, 0x2459, 0x2a60, 0x610e, 0x79aa,
-	0x8840, 0x7132, 0x2001, 0x0001, 0x007e, 0x715c, 0xa184, 0x0018,
-	0x0040, 0x2697, 0xa184, 0x0010, 0x0040, 0x268a, 0x1078, 0x3604,
-	0x00c0, 0x26ba, 0xa184, 0x0008, 0x0040, 0x2697, 0x69a0, 0xa184,
-	0x0600, 0x00c0, 0x2697, 0x1078, 0x34f1, 0x0078, 0x26ba, 0x69a0,
-	0xa184, 0x0800, 0x0040, 0x26ae, 0x0c7e, 0x027e, 0x2960, 0x6000,
-	0xa085, 0x2000, 0x6002, 0x6104, 0xa18d, 0x0010, 0x6106, 0x027f,
-	0x0c7f, 0x1078, 0x3604, 0x00c0, 0x26ba, 0x69a0, 0xa184, 0x0200,
-	0x0040, 0x26b6, 0x1078, 0x3540, 0x0078, 0x26ba, 0xa184, 0x0400,
-	0x00c0, 0x2693, 0x69a0, 0xa184, 0x1000, 0x0040, 0x26c5, 0x6914,
-	0xa18c, 0xff00, 0x810f, 0x1078, 0x22ee, 0x007f, 0x7002, 0xa68c,
-	0x00e0, 0xa684, 0x0060, 0x0040, 0x26d3, 0xa086, 0x0060, 0x00c0,
-	0x26d3, 0xa18d, 0x4000, 0x88ff, 0x0040, 0x26d8, 0xa18d, 0x0004,
-	0x795a, 0x69b6, 0x789b, 0x0060, 0x2800, 0x78aa, 0x789b, 0x0061,
-	0x6818, 0xa08d, 0x8000, 0xa084, 0x7fff, 0x691a, 0xa68c, 0x0080,
-	0x0040, 0x26f7, 0x7097, 0x0000, 0xa08a, 0x000d, 0x0050, 0x26f5,
-	0xa08a, 0x000c, 0x7196, 0x2001, 0x000c, 0x800c, 0x719a, 0x78aa,
-	0x8008, 0x810c, 0x0040, 0x3407, 0xa18c, 0x00f8, 0x00c0, 0x3407,
-	0x157e, 0x137e, 0x147e, 0x20a1, 0x012b, 0x789b, 0x0000, 0x8000,
-	0x80ac, 0xad80, 0x000b, 0x2098, 0x53a6, 0x147f, 0x137f, 0x157f,
-	0x6814, 0x8007, 0x7882, 0x6d94, 0x7dd6, 0x7dde, 0x6e98, 0x7ed2,
-	0x7eda, 0x1078, 0x38fa, 0x00c0, 0x272e, 0x702c, 0x8003, 0x0048,
-	0x2727, 0x2019, 0x4d9e, 0x1078, 0x2276, 0x702f, 0x8000, 0x7830,
-	0xa084, 0x00c0, 0x00c0, 0x272e, 0x0098, 0x2736, 0x6008, 0xa084,
-	0xffef, 0x600a, 0x1078, 0x3912, 0x0078, 0x2482, 0x7200, 0xa284,
-	0x0007, 0xa086, 0x0001, 0x00c0, 0x2743, 0x781b, 0x004f, 0x1078,
-	0x3912, 0x0078, 0x2754, 0x6ab4, 0xa295, 0x2000, 0x7a5a, 0x781b,
-	0x004f, 0x1078, 0x3912, 0x7200, 0x2500, 0xa605, 0x0040, 0x2754,
-	0xa284, 0x0007, 0x1079, 0x2762, 0xad80, 0x0009, 0x7036, 0xa284,
-	0x0007, 0xa086, 0x0001, 0x00c0, 0x2459, 0x6018, 0x8000, 0x601a,
-	0x0078, 0x2459, 0x276a, 0x4a3a, 0x4a3a, 0x4a29, 0x4a3a, 0x276a,
-	0x4a29, 0x276a, 0x1078, 0x23eb, 0x1078, 0x38fa, 0x0f7e, 0x2079,
-	0x5100, 0x78cc, 0x0f7f, 0xa084, 0x0001, 0x0040, 0x2790, 0x706c,
-	0xa086, 0x0001, 0x00c0, 0x277f, 0x706e, 0x0078, 0x2823, 0x706c,
-	0xa086, 0x0005, 0x00c0, 0x278e, 0x7088, 0x2068, 0x681b, 0x0004,
-	0x6817, 0x0000, 0x6820, 0xa085, 0x0008, 0x6822, 0x706f, 0x0000,
-	0x2011, 0x0004, 0x716c, 0xa186, 0x0001, 0x0040, 0x27b1, 0xa186,
-	0x0007, 0x00c0, 0x27a1, 0x2009, 0x5138, 0x200b, 0x0005, 0x0078,
-	0x27b1, 0x2009, 0x5113, 0x2104, 0x2009, 0x5112, 0x200a, 0x2009,
-	0x5138, 0x200b, 0x0001, 0x706f, 0x0000, 0x7073, 0x0001, 0x0078,
-	0x27b3, 0x706f, 0x0000, 0x1078, 0x4776, 0x157e, 0x20a9, 0x0010,
-	0x2039, 0x0000, 0x1078, 0x36e2, 0xa7b8, 0x0100, 0x0070, 0x27c2,
-	0x0078, 0x27ba, 0x157f, 0x7000, 0x0079, 0x27c6, 0x27f4, 0x27db,
-	0x27db, 0x27ce, 0x27f4, 0x27f4, 0x27f4, 0x27f4, 0x2021, 0x515a,
-	0x2404, 0xa005, 0x0040, 0x27f4, 0xad06, 0x00c0, 0x27db, 0x6800,
-	0x2022, 0x0078, 0x27eb, 0x6820, 0xa084, 0x0001, 0x00c0, 0x27e7,
-	0x6f14, 0x1078, 0x37ef, 0x1078, 0x33d8, 0x0078, 0x27eb, 0x7060,
-	0x2060, 0x6800, 0x6002, 0x6a1a, 0x6817, 0x0000, 0x6820, 0xa085,
-	0x0008, 0x6822, 0x1078, 0x1c70, 0x2021, 0x7500, 0x1078, 0x2830,
-	0x2021, 0x515a, 0x1078, 0x2830, 0x157e, 0x20a9, 0x0000, 0x2021,
-	0x7400, 0x1078, 0x2830, 0x8420, 0x0070, 0x2808, 0x0078, 0x2801,
-	0x2061, 0x5400, 0x2021, 0x0002, 0x20a9, 0x0100, 0x6018, 0x6110,
-	0x81ff, 0x0040, 0x2817, 0xa102, 0x0050, 0x2817, 0x6012, 0x601b,
-	0x0000, 0xace0, 0x0010, 0x0070, 0x281f, 0x0078, 0x280e, 0x8421,
-	0x00c0, 0x280c, 0x157f, 0x709c, 0xa084, 0x8000, 0x0040, 0x282a,
-	0x1078, 0x3a00, 0x7003, 0x0000, 0x704b, 0x0000, 0x0078, 0x2459,
-	0x047e, 0x2404, 0xa005, 0x0040, 0x2844, 0x2068, 0x6800, 0x007e,
-	0x6a1a, 0x6817, 0x0000, 0x6820, 0xa085, 0x0008, 0x6822, 0x1078,
-	0x1c70, 0x007f, 0x0078, 0x2832, 0x047f, 0x2023, 0x0000, 0x007c,
-	0xa282, 0x0003, 0x0050, 0x284e, 0x1078, 0x23eb, 0x2300, 0x0079,
-	0x2851, 0x2854, 0x28c7, 0x28e4, 0xa282, 0x0002, 0x0040, 0x285a,
-	0x1078, 0x23eb, 0x706c, 0x706f, 0x0000, 0x7093, 0x0000, 0x0079,
-	0x2861, 0x2869, 0x2869, 0x286b, 0x289f, 0x340d, 0x2869, 0x289f,
-	0x2869, 0x1078, 0x23eb, 0x7780, 0x1078, 0x36e2, 0x7780, 0xa7bc,
-	0x0f00, 0x1078, 0x37ef, 0x6018, 0xa005, 0x0040, 0x2896, 0x2021,
-	0x7500, 0x2009, 0x0004, 0x2011, 0x0010, 0x1078, 0x28ff, 0x0040,
-	0x2896, 0x157e, 0x20a9, 0x0000, 0x2021, 0x7400, 0x047e, 0x2009,
-	0x0004, 0x2011, 0x0010, 0x1078, 0x28ff, 0x047f, 0x0040, 0x2895,
-	0x8420, 0x0070, 0x2895, 0x0078, 0x2886, 0x157f, 0x8738, 0xa784,
-	0x001f, 0x00c0, 0x2871, 0x0078, 0x2482, 0x0078, 0x2482, 0x7780,
-	0x1078, 0x37ef, 0x6018, 0xa005, 0x0040, 0x28c5, 0x2021, 0x7500,
-	0x2009, 0x0005, 0x2011, 0x0020, 0x1078, 0x28ff, 0x0040, 0x28c5,
-	0x157e, 0x20a9, 0x0000, 0x2021, 0x7400, 0x047e, 0x2009, 0x0005,
-	0x2011, 0x0020, 0x1078, 0x28ff, 0x047f, 0x0040, 0x28c4, 0x8420,
-	0x0070, 0x28c4, 0x0078, 0x28b5, 0x157f, 0x0078, 0x2482, 0x2200,
-	0x0079, 0x28ca, 0x28cd, 0x28cf, 0x28cf, 0x1078, 0x23eb, 0x2009,
-	0x0012, 0x706c, 0xa086, 0x0002, 0x0040, 0x28d8, 0x2009, 0x000e,
-	0x6818, 0xa084, 0x8000, 0x0040, 0x28de, 0x691a, 0x706f, 0x0000,
-	0x7073, 0x0001, 0x0078, 0x3888, 0x2200, 0x0079, 0x28e7, 0x28ec,
-	0x28cf, 0x28ea, 0x1078, 0x23eb, 0x1078, 0x4776, 0x7000, 0xa086,
-	0x0001, 0x00c0, 0x339d, 0x1078, 0x33ee, 0x6008, 0xa084, 0xffef,
-	0x600a, 0x1078, 0x3390, 0x0040, 0x339d, 0x0078, 0x2594, 0x2404,
-	0xa005, 0x0040, 0x2922, 0x2068, 0x2d04, 0x007e, 0x6814, 0xa706,
-	0x0040, 0x290e, 0x2d20, 0x007f, 0x0078, 0x2900, 0x007f, 0x2022,
-	0x691a, 0x6817, 0x0000, 0x6820, 0xa205, 0x6822, 0x1078, 0x1c70,
-	0x6010, 0x8001, 0x6012, 0x6008, 0xa084, 0xffef, 0x600a, 0x1078,
-	0x33ee, 0x007c, 0xa085, 0x0001, 0x0078, 0x2921, 0x2300, 0x0079,
-	0x2929, 0x292e, 0x292c, 0x29c7, 0x1078, 0x23eb, 0x78ec, 0xa084,
-	0x0001, 0x00c0, 0x2942, 0x7000, 0xa086, 0x0004, 0x00c0, 0x293a,
-	0x0078, 0x2965, 0x1078, 0x33ee, 0x6008, 0xa084, 0xffef, 0x600a,
-	0x0078, 0x339d, 0x78e4, 0xa005, 0x00d0, 0x2965, 0x0018, 0x2459,
-	0x2008, 0xa084, 0x0030, 0x00c0, 0x2951, 0x781b, 0x004f, 0x0078,
-	0x2459, 0x78ec, 0xa084, 0x0003, 0x0040, 0x294d, 0x2100, 0xa084,
-	0x0007, 0x0079, 0x295b, 0x299e, 0x29a9, 0x298f, 0x2963, 0x38ed,
-	0x38ed, 0x2963, 0x29b8, 0x1078, 0x23eb, 0x7000, 0xa086, 0x0004,
-	0x00c0, 0x297f, 0x706c, 0xa086, 0x0002, 0x00c0, 0x2975, 0x2011,
-	0x0002, 0x2019, 0x0000, 0x0078, 0x2848, 0x706c, 0xa086, 0x0006,
-	0x0040, 0x296f, 0x706c, 0xa086, 0x0004, 0x0040, 0x296f, 0x79e4,
-	0xa184, 0x0030, 0x0040, 0x2989, 0x78ec, 0xa084, 0x0003, 0x00c0,
-	0x298b, 0x0078, 0x2f6d, 0x2001, 0x0003, 0x0078, 0x2d01, 0x6818,
-	0xa084, 0x8000, 0x0040, 0x2996, 0x681b, 0x001d, 0x1078, 0x36c1,
-	0x782b, 0x3008, 0x781b, 0x0056, 0x0078, 0x2459, 0x6818, 0xa084,
-	0x8000, 0x0040, 0x29a5, 0x681b, 0x001d, 0x1078, 0x36c1, 0x0078,
-	0x38b8, 0x6818, 0xa084, 0x8000, 0x0040, 0x29b0, 0x681b, 0x001d,
-	0x1078, 0x36c1, 0x782b, 0x3008, 0x781b, 0x00cd, 0x0078, 0x2459,
-	0x6818, 0xa084, 0x8000, 0x0040, 0x29bf, 0x681b, 0x001d, 0x1078,
-	0x36c1, 0x782b, 0x3008, 0x781b, 0x008e, 0x0078, 0x2459, 0xa584,
-	0x000f, 0x00c0, 0x29e4, 0x7000, 0x0079, 0x29ce, 0x2482, 0x29d8,
-	0x29d6, 0x339d, 0x339d, 0x339d, 0x339d, 0x29d6, 0x1078, 0x23eb,
-	0x1078, 0x33ee, 0x6008, 0xa084, 0xffef, 0x600a, 0x1078, 0x3390,
-	0x0040, 0x339d, 0x0078, 0x2594, 0x78e4, 0xa005, 0x00d0, 0x2965,
-	0x0018, 0x2965, 0x2008, 0xa084, 0x0030, 0x00c0, 0x29f3, 0x781b,
-	0x004f, 0x0078, 0x2459, 0x78ec, 0xa084, 0x0003, 0x0040, 0x29ef,
-	0x2100, 0xa184, 0x0007, 0x0079, 0x29fd, 0x2a0f, 0x2a13, 0x2a07,
-	0x2a05, 0x38ed, 0x38ed, 0x2a05, 0x38e3, 0x1078, 0x23eb, 0x1078,
-	0x36c9, 0x782b, 0x3008, 0x781b, 0x0056, 0x0078, 0x2459, 0x1078,
-	0x36c9, 0x0078, 0x38b8, 0x1078, 0x36c9, 0x782b, 0x3008, 0x781b,
-	0x00cd, 0x0078, 0x2459, 0x1078, 0x36c9, 0x782b, 0x3008, 0x781b,
-	0x008e, 0x0078, 0x2459, 0x2300, 0x0079, 0x2a26, 0x2a2b, 0x2a29,
-	0x2a2d, 0x1078, 0x23eb, 0x0078, 0x30ab, 0x681b, 0x0008, 0x78a3,
-	0x0000, 0x79e4, 0xa184, 0x0030, 0x0040, 0x30ab, 0x78ec, 0xa084,
-	0x0003, 0x0040, 0x30ab, 0xa184, 0x0007, 0x0079, 0x2a3f, 0x2a47,
-	0x2a13, 0x298f, 0x3888, 0x38ed, 0x38ed, 0x2a47, 0x38e3, 0x1078,
-	0x389c, 0x0078, 0x2459, 0xa282, 0x0005, 0x0050, 0x2a51, 0x1078,
-	0x23eb, 0x2300, 0x0079, 0x2a54, 0x2a57, 0x2cae, 0x2cbc, 0x2200,
-	0x0079, 0x2a5a, 0x2a74, 0x2a61, 0x2a74, 0x2a5f, 0x2c93, 0x1078,
-	0x23eb, 0x789b, 0x0018, 0x78a8, 0xa084, 0x00ff, 0xa082, 0x0020,
-	0x0048, 0x369d, 0xa08a, 0x0004, 0x00c8, 0x369d, 0x0079, 0x2a70,
-	0x369d, 0x369d, 0x369d, 0x364b, 0x789b, 0x0018, 0x79a8, 0xa184,
-	0x0080, 0x0040, 0x2a85, 0x0078, 0x369d, 0x7000, 0xa005, 0x00c0,
-	0x2a7b, 0x2011, 0x0004, 0x0078, 0x321f, 0xa184, 0x00ff, 0xa08a,
-	0x0010, 0x00c8, 0x369d, 0x0079, 0x2a8d, 0x2a9f, 0x2a9d, 0x2ab7,
-	0x2abb, 0x2b78, 0x369d, 0x369d, 0x2b7a, 0x369d, 0x369d, 0x2c8f,
-	0x2c8f, 0x369d, 0x369d, 0x369d, 0x2c91, 0x1078, 0x23eb, 0xa684,
-	0x1000, 0x0040, 0x2aac, 0x2001, 0x0500, 0x8000, 0x8000, 0x783a,
-	0x781b, 0x008c, 0x0078, 0x2459, 0x6818, 0xa084, 0x8000, 0x0040,
-	0x2ab5, 0x681b, 0x001d, 0x0078, 0x2aa3, 0x0078, 0x3888, 0x681b,
-	0x001d, 0x0078, 0x36ad, 0x6920, 0x6922, 0xa684, 0x1800, 0x00c0,
-	0x2afc, 0x6820, 0xa084, 0x0001, 0x00c0, 0x2b04, 0x6818, 0xa086,
-	0x0008, 0x00c0, 0x2acd, 0x681b, 0x0000, 0xa684, 0x0400, 0x0040,
-	0x2b74, 0xa684, 0x0080, 0x0040, 0x2af8, 0x7097, 0x0000, 0x6818,
-	0xa084, 0x003f, 0xa08a, 0x000d, 0x0050, 0x2af8, 0xa08a, 0x000c,
-	0x7196, 0x2001, 0x000c, 0x800c, 0x719a, 0x789b, 0x0061, 0x78aa,
+	0x5480, 0x2019, 0x0000, 0x72c8, 0xd2bc, 0x0040, 0x14e9, 0xa39d,
+	0x0010, 0xd2b4, 0x0040, 0x14ee, 0xa39d, 0x0008, 0x6800, 0x007e,
+	0xa226, 0x0040, 0x1511, 0x6a02, 0xa484, 0x2000, 0x0040, 0x14fa,
+	0xa39d, 0x0010, 0xa484, 0x1000, 0x0040, 0x1500, 0xa39d, 0x0008,
+	0xa484, 0x4000, 0x0040, 0x1511, 0x810f, 0xa284, 0x4000, 0x0040,
+	0x150d, 0x1078, 0x2399, 0x0078, 0x1511, 0x1078, 0x238b, 0x0078,
+	0x1511, 0x72cc, 0x6808, 0xa206, 0x0040, 0x1540, 0xa2a4, 0x00ff,
+	0x2061, 0x5240, 0x6118, 0xa186, 0x0028, 0x0040, 0x1527, 0xa186,
+	0x0032, 0x0040, 0x152d, 0xa186, 0x003c, 0x0040, 0x1533, 0xa482,
+	0x0064, 0x0048, 0x153d, 0x0078, 0x1537, 0xa482, 0x0050, 0x0048,
+	0x153d, 0x0078, 0x1537, 0xa482, 0x0043, 0x0048, 0x153d, 0x71c4,
+	0x71c6, 0x027f, 0x72ca, 0x0078, 0x127d, 0x6a0a, 0xa39d, 0x000a,
+	0x6804, 0xa305, 0x6806, 0x027f, 0x6b0c, 0x71c4, 0x0078, 0x1281,
+	0x77c4, 0x1078, 0x19c5, 0x2091, 0x8000, 0x6a14, 0x6b1c, 0x2091,
+	0x8001, 0x70c8, 0x6816, 0x70cc, 0x681e, 0x2708, 0x0078, 0x1281,
+	0x70c4, 0x794c, 0x784e, 0x0078, 0x1283, 0x71c4, 0x72c8, 0x73cc,
+	0xa182, 0x0010, 0x00c8, 0x127c, 0x1078, 0x23a7, 0x0078, 0x1281,
+	0x77c4, 0x1078, 0x19c5, 0x2091, 0x8000, 0x6a08, 0xa295, 0x0002,
+	0x6a0a, 0x2091, 0x8001, 0x2708, 0x0078, 0x1282, 0x77c4, 0x1078,
+	0x19c5, 0x2091, 0x8000, 0x6a08, 0xa294, 0xfff9, 0x6a0a, 0x6804,
+	0xa005, 0x0040, 0x1585, 0x1078, 0x226f, 0x2091, 0x8001, 0x2708,
+	0x0078, 0x1282, 0x77c4, 0x1078, 0x19c5, 0x2091, 0x8000, 0x6a08,
+	0xa295, 0x0004, 0x6a0a, 0x6804, 0xa005, 0x0040, 0x1599, 0x1078,
+	0x226f, 0x2091, 0x8001, 0x2708, 0x0078, 0x1282, 0x77c4, 0x2041,
+	0x0001, 0x2049, 0x0005, 0x2051, 0x0020, 0x2091, 0x8000, 0x1078,
+	0x19d2, 0x2091, 0x8001, 0x2708, 0x6a08, 0x0078, 0x1282, 0x77c4,
+	0x72c8, 0x73cc, 0x77c6, 0x72ca, 0x73ce, 0x1078, 0x1a52, 0x00c0,
+	0x15c7, 0x6818, 0xa005, 0x0040, 0x15c7, 0x2708, 0x1078, 0x23b7,
+	0x00c0, 0x15c7, 0x7817, 0x0015, 0x2091, 0x8001, 0x007c, 0x2091,
+	0x8001, 0x0078, 0x1284, 0x77c4, 0x77c6, 0x2041, 0x0021, 0x2049,
+	0x0005, 0x2051, 0x0020, 0x2091, 0x8000, 0x1078, 0x19d2, 0x2061,
+	0x5240, 0x606f, 0x0003, 0x6782, 0x6093, 0x000f, 0x6073, 0x0000,
+	0x7817, 0x0016, 0x1078, 0x226f, 0x2091, 0x8001, 0x007c, 0x77c8,
+	0x77ca, 0x77c4, 0x77c6, 0xa7bc, 0xff00, 0x2091, 0x8000, 0x2061,
+	0x5240, 0x606f, 0x0002, 0x6073, 0x0000, 0x6782, 0x6093, 0x000f,
+	0x7817, 0x0017, 0x1078, 0x226f, 0x2091, 0x8001, 0x2041, 0x0021,
+	0x2049, 0x0004, 0x2051, 0x0010, 0x2091, 0x8000, 0x1078, 0x19d2,
+	0x70c8, 0x6836, 0x8738, 0xa784, 0x001f, 0x00c0, 0x1606, 0x2091,
+	0x8001, 0x007c, 0x78cc, 0xa084, 0x0003, 0x00c0, 0x1636, 0x2039,
+	0x0000, 0x2041, 0x0021, 0x2049, 0x0004, 0x2051, 0x0008, 0x1078,
+	0x19c5, 0x2091, 0x8000, 0x6808, 0xa80d, 0x690a, 0x2091, 0x8001,
+	0x8738, 0xa784, 0x001f, 0x00c0, 0x161f, 0xa7bc, 0xff00, 0x873f,
+	0x8738, 0x873f, 0xa784, 0x0f00, 0x00c0, 0x161f, 0x2091, 0x8000,
+	0x2069, 0x0100, 0x6830, 0xa084, 0x0040, 0x0040, 0x165f, 0x684b,
+	0x0004, 0x20a9, 0x0014, 0x6848, 0xa084, 0x0004, 0x0040, 0x164c,
+	0x0070, 0x164c, 0x0078, 0x1643, 0x684b, 0x0009, 0x20a9, 0x0014,
+	0x6848, 0xa084, 0x0001, 0x0040, 0x1659, 0x0070, 0x1659, 0x0078,
+	0x1650, 0x20a9, 0x00fa, 0x0070, 0x165f, 0x0078, 0x165b, 0x2079,
+	0x5200, 0x7817, 0x0018, 0x2061, 0x5240, 0x606f, 0x0001, 0x6073,
+	0x0000, 0x6093, 0x000f, 0x78cc, 0xa085, 0x0002, 0x78ce, 0x6808,
+	0xa084, 0xfffd, 0x680a, 0x681b, 0x0048, 0x2091, 0x8001, 0x007c,
+	0x78cc, 0xa084, 0xfffd, 0x78ce, 0xa084, 0x0001, 0x00c0, 0x1682,
+	0x1078, 0x1a9c, 0x71c4, 0x71c6, 0x794a, 0x007c, 0x1078, 0x1bc4,
+	0x00c0, 0x129c, 0x75d8, 0x74dc, 0x75da, 0x74de, 0x0078, 0x1693,
+	0x2029, 0x0000, 0x2520, 0x71c4, 0x73c8, 0x72cc, 0x71c6, 0x73ca,
+	0x72ce, 0x2079, 0x5200, 0x2091, 0x8000, 0x1078, 0x1980, 0x2091,
+	0x8001, 0x0040, 0x174a, 0x20a9, 0x0005, 0x20a1, 0x5218, 0x2091,
+	0x8000, 0x41a1, 0x2091, 0x8001, 0x2009, 0x0020, 0x1078, 0x197b,
+	0x0040, 0x16b6, 0x1078, 0x199a, 0x0078, 0x174a, 0x6004, 0xa084,
+	0xff00, 0x8007, 0x8009, 0x0040, 0x1719, 0x0c7e, 0x2c68, 0x2091,
+	0x8000, 0x1078, 0x1980, 0x2091, 0x8001, 0x0040, 0x16ea, 0x2c00,
+	0x689e, 0x8109, 0x00c0, 0x16be, 0x609f, 0x0000, 0x0c7f, 0x0c7e,
+	0x7218, 0x731c, 0x7420, 0x7524, 0x2c68, 0x689c, 0xa065, 0x0040,
+	0x1718, 0x2009, 0x0020, 0x1078, 0x197b, 0x00c0, 0x1701, 0x6004,
+	0xa084, 0x00ff, 0xa086, 0x0002, 0x00c0, 0x16ea, 0x2d00, 0x6002,
+	0x0078, 0x16d0, 0x0c7f, 0x0c7e, 0x609c, 0x2060, 0x1078, 0x1a17,
+	0x0c7f, 0x609f, 0x0000, 0x1078, 0x174e, 0x2009, 0x000c, 0x6008,
+	0xa085, 0x0200, 0x600a, 0x1078, 0x1976, 0x1078, 0x199a, 0x0078,
+	0x174a, 0x0c7f, 0x0c7e, 0x609c, 0x2060, 0x1078, 0x1a17, 0x0c7f,
+	0x609f, 0x0000, 0x1078, 0x174e, 0x2009, 0x000c, 0x6007, 0x0103,
+	0x601b, 0x0003, 0x1078, 0x1976, 0x1078, 0x199a, 0x0078, 0x174a,
+	0x0c7f, 0x74c4, 0x73c8, 0x72cc, 0x6014, 0x2091, 0x8000, 0x7817,
+	0x0012, 0x0e7e, 0x2071, 0x5240, 0x706f, 0x0005, 0x7073, 0x0000,
+	0x7376, 0x727a, 0x747e, 0x7082, 0x7087, 0x0000, 0x2c00, 0x708a,
+	0x708f, 0x0000, 0xa02e, 0x2530, 0x611c, 0x61a2, 0xa184, 0x0060,
+	0x0040, 0x173c, 0x1078, 0x48d3, 0x0e7f, 0x6596, 0x65a6, 0x669a,
+	0x66aa, 0x60af, 0x0000, 0x60b3, 0x0000, 0x1078, 0x226f, 0x2091,
+	0x8001, 0x007c, 0x70c3, 0x4005, 0x0078, 0x1287, 0x20a9, 0x0005,
+	0x2099, 0x5218, 0x2091, 0x8000, 0x530a, 0x2091, 0x8001, 0x2100,
+	0xa210, 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x007c,
+	0x71c4, 0x70c7, 0x0000, 0x7906, 0x0078, 0x1284, 0x71c4, 0x71c6,
+	0x2168, 0x0078, 0x176d, 0x2069, 0x1000, 0x690c, 0xa016, 0x2d04,
+	0xa210, 0x8d68, 0x8109, 0x00c0, 0x176f, 0xa285, 0x0000, 0x00c0,
+	0x177d, 0x70c3, 0x4000, 0x0078, 0x177f, 0x70c3, 0x4003, 0x70ca,
+	0x0078, 0x1287, 0x2011, 0x5267, 0x220c, 0x70c4, 0x8003, 0x0048,
+	0x178f, 0x1078, 0x3c51, 0xa184, 0x7fff, 0x0078, 0x1793, 0x1078,
+	0x3c44, 0xa185, 0x8000, 0x2012, 0x0078, 0x1283, 0x71c4, 0x1078,
+	0x3c3b, 0x6100, 0x2001, 0x5267, 0x2004, 0xa084, 0x8000, 0xa10d,
+	0x6204, 0x6308, 0x0078, 0x1281, 0x79e4, 0x0078, 0x1283, 0x71c4,
+	0x71c6, 0x2198, 0x20a1, 0x0042, 0x20a9, 0x0004, 0x53a3, 0x21a0,
+	0x2099, 0x0042, 0x20a9, 0x0004, 0x53a3, 0x0078, 0x1284, 0x70c4,
+	0x2068, 0x2079, 0x5200, 0x2091, 0x8000, 0x1078, 0x1980, 0x2091,
+	0x8001, 0x0040, 0x1843, 0x6007, 0x0001, 0x600b, 0x0000, 0x602b,
+	0x0000, 0x601b, 0x0006, 0x6a10, 0xa28c, 0x000f, 0xa284, 0x00f0,
+	0x8003, 0x8003, 0x8003, 0x8003, 0xa105, 0x6016, 0xa284, 0x0800,
+	0x0040, 0x17de, 0x601b, 0x000a, 0x0078, 0x17e4, 0xa284, 0x1000,
+	0x0040, 0x17e4, 0x601b, 0x000c, 0xa284, 0x0300, 0x0040, 0x17ed,
+	0x602b, 0x0001, 0x8004, 0x8004, 0x8004, 0xa085, 0x0001, 0x601e,
+	0x6023, 0x0000, 0x6027, 0x0000, 0xa284, 0x0400, 0x0040, 0x17fa,
+	0x602b, 0x0000, 0x20a9, 0x0006, 0xac80, 0x000b, 0x20a0, 0xad80,
+	0x0005, 0x2098, 0x53a3, 0xa284, 0x0300, 0x00c0, 0x180f, 0x6046,
+	0x604a, 0x604e, 0x6052, 0x6096, 0x609a, 0x0078, 0x1819, 0x6800,
+	0x6046, 0x6804, 0x604a, 0x6e08, 0x664e, 0x6d0c, 0x6552, 0x6596,
+	0x669a, 0x6014, 0x2091, 0x8000, 0x7817, 0x0042, 0x2c08, 0x2061,
+	0x5240, 0x606f, 0x0005, 0x6073, 0x0000, 0x6077, 0x0000, 0x607b,
+	0x0000, 0x607f, 0x0000, 0x6082, 0x618a, 0xa284, 0x0400, 0x608e,
+	0x2091, 0x8001, 0x0e7e, 0x2071, 0x0020, 0x7007, 0x000a, 0x7007,
+	0x0002, 0x7003, 0x0000, 0x0e7f, 0x2091, 0x8000, 0x1078, 0x226f,
+	0x2091, 0x8001, 0x007c, 0x70c3, 0x4005, 0x0078, 0x1287, 0x0c7e,
+	0x0d7e, 0x0e7e, 0x0f7e, 0x2091, 0x8000, 0x2071, 0x5240, 0x2079,
+	0x0100, 0x2061, 0x0010, 0x70a0, 0xa06d, 0x0040, 0x1903, 0x6a04,
+	0xa294, 0x00ff, 0xa286, 0x0007, 0x0040, 0x1862, 0xa286, 0x000f,
+	0x00c0, 0x1903, 0x691c, 0xa184, 0x00c0, 0x0040, 0x1903, 0xa184,
+	0x0080, 0x00c0, 0x18d3, 0x6824, 0xa084, 0xff00, 0xa085, 0x0019,
+	0x6826, 0x71b0, 0x81ff, 0x0040, 0x1889, 0x0d7e, 0x2069, 0x0020,
+	0x6807, 0x0010, 0x6908, 0x6808, 0xa106, 0x00c0, 0x187a, 0x690c,
+	0x680c, 0xa106, 0x00c0, 0x187f, 0xa184, 0x00ff, 0x00c0, 0x187f,
+	0x0d7f, 0x78b8, 0xa084, 0x801f, 0x00c0, 0x1889, 0x7848, 0xa085,
+	0x000c, 0x784a, 0x71b0, 0x81ff, 0x0040, 0x18ac, 0x70b3, 0x0000,
+	0x0d7e, 0x2069, 0x0020, 0x6807, 0x0018, 0x6804, 0xa084, 0x0008,
+	0x00c0, 0x189d, 0x6807, 0x0008, 0x6804, 0xa084, 0x0008, 0x00c0,
+	0x18a4, 0x6807, 0x0002, 0x0d7f, 0x61c4, 0x62c8, 0x63cc, 0x61c6,
+	0x62ca, 0x63ce, 0x0e7e, 0x2071, 0x5200, 0x7266, 0x736a, 0xae80,
+	0x0019, 0x0e7f, 0x7848, 0xa084, 0x000c, 0x00c0, 0x18ba, 0x1078,
+	0x47e1, 0x78a3, 0x0000, 0x7858, 0xa084, 0xedff, 0x785a, 0x70b4,
+	0xa080, 0x00da, 0x781a, 0x0f7f, 0x0e7f, 0x0d7f, 0x0c7f, 0x2091,
+	0x8001, 0x0078, 0x1284, 0x6824, 0xa084, 0xff00, 0xa085, 0x0019,
+	0x6826, 0x78b8, 0xa084, 0x801f, 0x00c0, 0x18d9, 0x7848, 0xa085,
+	0x000c, 0x784a, 0x7848, 0xa084, 0x000c, 0x00c0, 0x18e2, 0x71b0,
+	0x81ff, 0x0040, 0x1901, 0x70b3, 0x0000, 0x0d7e, 0x2069, 0x0020,
+	0x6807, 0x0018, 0x6804, 0xa084, 0x0008, 0x00c0, 0x18f2, 0x6807,
+	0x0008, 0x6804, 0xa084, 0x0008, 0x00c0, 0x18f9, 0x6807, 0x0002,
+	0x0d7f, 0x0078, 0x18cb, 0x0f7f, 0x0e7f, 0x0d7f, 0x0c7f, 0x2091,
+	0x8001, 0x2001, 0x4005, 0x0078, 0x1286, 0x7980, 0x71c6, 0x71c4,
+	0xa182, 0x0003, 0x00c8, 0x127c, 0x7982, 0x0078, 0x1284, 0x7980,
+	0x71c6, 0x0078, 0x1284, 0x7974, 0x71c6, 0x71c4, 0x7976, 0x7978,
+	0x71ca, 0x71c8, 0x797a, 0x797c, 0x71ce, 0x71cc, 0x797e, 0x0078,
+	0x1284, 0x7974, 0x71c6, 0x7978, 0x71ca, 0x797c, 0x71ce, 0x0078,
+	0x1284, 0x7900, 0x71c6, 0x71c4, 0x7902, 0x2001, 0x04fd, 0x2004,
+	0xa082, 0x0005, 0x0048, 0x1940, 0x0038, 0x1942, 0x0078, 0x194c,
+	0x00a8, 0x194c, 0xa18c, 0x0001, 0x00c0, 0x194a, 0x20b9, 0x2222,
+	0x0078, 0x194c, 0x20b9, 0x1212, 0x0078, 0x1284, 0x7900, 0x71c6,
+	0x0078, 0x1284, 0x2009, 0x5274, 0x2104, 0x70c6, 0x70c4, 0x200a,
+	0x0078, 0x1284, 0x2009, 0x5274, 0x2104, 0x70c6, 0x0078, 0x1284,
+	0x71c4, 0x8107, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xa0e8,
+	0x5480, 0x6a14, 0xd2b4, 0x0040, 0x1971, 0x2011, 0x0001, 0x0078,
+	0x1973, 0x2011, 0x0000, 0x6b0c, 0x0078, 0x1281, 0xac80, 0x0001,
+	0x1078, 0x1b80, 0x007c, 0xac80, 0x0001, 0x1078, 0x1b20, 0x007c,
+	0x7850, 0xa065, 0x0040, 0x1988, 0x2c04, 0x7852, 0x2063, 0x0000,
+	0x007c, 0x0f7e, 0x2079, 0x5200, 0x7850, 0xa06d, 0x0040, 0x1998,
+	0x2d04, 0x7852, 0x6803, 0x0000, 0x6807, 0x0000, 0x680b, 0x0000,
+	0x0f7f, 0x007c, 0x2091, 0x8000, 0x0f7e, 0x2079, 0x5200, 0x7850,
+	0x2062, 0x2c00, 0xa005, 0x00c0, 0x19a7, 0x1078, 0x248c, 0x7852,
+	0x0f7f, 0x2091, 0x8001, 0x007c, 0x0f7e, 0x2079, 0x5200, 0x7850,
+	0x206a, 0x2d00, 0x7852, 0x0f7f, 0x007c, 0x2011, 0x7900, 0x7a52,
+	0x7bec, 0x8319, 0x0040, 0x19c2, 0xa280, 0x0031, 0x2012, 0x2010,
+	0x0078, 0x19b9, 0x2013, 0x0000, 0x007c, 0xa784, 0x0f00, 0x800b,
+	0xa784, 0x001f, 0x8003, 0x8003, 0x8003, 0x8003, 0xa105, 0xa0e8,
+	0x5500, 0x007c, 0x1078, 0x19c5, 0x2900, 0x682a, 0x2a00, 0x682e,
+	0x6808, 0xa084, 0xffef, 0xa80d, 0x690a, 0x2009, 0x5252, 0x210c,
+	0x6804, 0xa005, 0x0040, 0x1a04, 0xa116, 0x00c0, 0x19ef, 0x2060,
+	0x6000, 0x6806, 0x017e, 0x200b, 0x0000, 0x0078, 0x19f2, 0x2009,
+	0x0000, 0x017e, 0x6804, 0xa065, 0x0040, 0x1a01, 0x6000, 0x6806,
+	0x1078, 0x1a31, 0x1078, 0x1ccb, 0x6810, 0x8001, 0x6812, 0x00c0,
+	0x19f2, 0x017f, 0x6902, 0x6906, 0x007c, 0xa065, 0x0040, 0x1a16,
+	0x2008, 0x609c, 0xa005, 0x0040, 0x1a13, 0x2062, 0x609f, 0x0000,
+	0xa065, 0x0078, 0x1a09, 0x7850, 0x7952, 0x2062, 0x007c, 0xa065,
+	0x0040, 0x1a30, 0x2008, 0x609c, 0xa005, 0x0040, 0x1a25, 0x2062,
+	0x609f, 0x0000, 0xa065, 0x0078, 0x1a1b, 0x0f7e, 0x2079, 0x5200,
+	0x2091, 0x8000, 0x7850, 0x7952, 0x0f7f, 0x2062, 0x2091, 0x8001,
+	0x007c, 0x6007, 0x0103, 0x608f, 0x0000, 0x20a9, 0x001c, 0xac80,
+	0x0005, 0x20a0, 0x2001, 0x0000, 0x40a4, 0x6828, 0x601a, 0x682c,
+	0x6022, 0x007c, 0x0e7e, 0x2071, 0x5240, 0x704c, 0xa08c, 0x0200,
+	0x00c0, 0x1a50, 0xa088, 0x5280, 0x2d0a, 0x8000, 0x704e, 0xa006,
+	0x0e7f, 0x007c, 0x1078, 0x19c5, 0x2091, 0x8000, 0x6804, 0x781e,
+	0xa065, 0x0040, 0x1a9b, 0x0078, 0x1a63, 0x2c00, 0x781e, 0x6000,
+	0xa065, 0x0040, 0x1a9b, 0x600c, 0xa306, 0x00c0, 0x1a5d, 0x6010,
+	0xa206, 0x00c0, 0x1a5d, 0x2c28, 0x2001, 0x5252, 0x2004, 0xac06,
+	0x00c0, 0x1a74, 0x0078, 0x1a99, 0x6804, 0xac06, 0x00c0, 0x1a81,
+	0x6000, 0xa065, 0x6806, 0x00c0, 0x1a8b, 0x6803, 0x0000, 0x0078,
+	0x1a8b, 0x6400, 0x781c, 0x2060, 0x6402, 0xa486, 0x0000, 0x00c0,
+	0x1a8b, 0x2c00, 0x6802, 0x2560, 0x1078, 0x1a31, 0x601b, 0x0005,
+	0x6023, 0x0020, 0x1078, 0x1ccb, 0x6810, 0x8001, 0x1050, 0x248c,
+	0x6812, 0xa085, 0xffff, 0x007c, 0x2039, 0x0000, 0x2041, 0x0021,
+	0x2049, 0x0004, 0x2051, 0x0008, 0x2091, 0x8000, 0x1078, 0x19d2,
+	0x8738, 0xa784, 0x001f, 0x00c0, 0x1aa6, 0xa7bc, 0xff00, 0x873f,
+	0x8738, 0x873f, 0xa784, 0x0f00, 0x00c0, 0x1aa6, 0x2091, 0x8001,
+	0x007c, 0x2061, 0x0000, 0x6018, 0xa084, 0x0001, 0x00c0, 0x1aca,
+	0x2091, 0x8000, 0x78e0, 0x78e3, 0x0000, 0x2091, 0x8001, 0xa005,
+	0x00c0, 0x1acb, 0x007c, 0xa08c, 0xfff0, 0x0040, 0x1ad1, 0x1078,
+	0x248c, 0x0079, 0x1ad3, 0x1ae3, 0x1ae6, 0x1aec, 0x1af0, 0x1ae4,
+	0x1af4, 0x1afa, 0x1ae4, 0x1ae4, 0x1c95, 0x1cb9, 0x1cbd, 0x1ae4,
+	0x1ae4, 0x1ae4, 0x1ae4, 0x007c, 0x1078, 0x248c, 0x1078, 0x1a9c,
+	0x2001, 0x8001, 0x0078, 0x1cc3, 0x2001, 0x8003, 0x0078, 0x1cc3,
+	0x2001, 0x8004, 0x0078, 0x1cc3, 0x1078, 0x1a9c, 0x2001, 0x8006,
+	0x0078, 0x1cc3, 0x2001, 0x8007, 0x0078, 0x1cc3, 0x2030, 0x2138,
+	0xa782, 0x0021, 0x0048, 0x1b06, 0x2009, 0x0020, 0x2600, 0x1078,
+	0x1b20, 0x00c0, 0x1b1f, 0xa7ba, 0x0020, 0x0048, 0x1b1e, 0x0040,
+	0x1b1e, 0x2708, 0xa6b0, 0x0020, 0xa290, 0x0040, 0xa399, 0x0000,
+	0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x0078, 0x1b00, 0xa006, 0x007c,
+	0x81ff, 0x0040, 0x1b5b, 0x2099, 0x0030, 0x20a0, 0x700c, 0xa084,
+	0x00ff, 0x0040, 0x1b32, 0x7007, 0x0004, 0x7004, 0xa084, 0x0004,
+	0x00c0, 0x1b2d, 0x21a8, 0x7017, 0x0000, 0x810b, 0x7112, 0x721a,
+	0x731e, 0x7422, 0x7526, 0x780c, 0xa085, 0x0001, 0x7002, 0x7007,
+	0x0001, 0x2001, 0x04fd, 0x2004, 0xa082, 0x0005, 0x00c8, 0x1b4f,
+	0x2009, 0x0022, 0x2104, 0xa084, 0x4000, 0x00c0, 0x1b41, 0x7008,
+	0x800b, 0x00c8, 0x1b41, 0x7007, 0x0002, 0xa08c, 0x01e0, 0x00c0,
+	0x1b5b, 0x53a5, 0xa006, 0x7003, 0x0000, 0x007c, 0x2030, 0x2138,
+	0xa782, 0x0021, 0x0048, 0x1b66, 0x2009, 0x0020, 0x2600, 0x1078,
+	0x1b80, 0x00c0, 0x1b7f, 0xa7ba, 0x0020, 0x0048, 0x1b7e, 0x0040,
+	0x1b7e, 0x2708, 0xa6b0, 0x0020, 0xa290, 0x0040, 0xa399, 0x0000,
+	0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x0078, 0x1b60, 0xa006, 0x007c,
+	0x81ff, 0x0040, 0x1bc1, 0x2098, 0x20a1, 0x0030, 0x700c, 0xa084,
+	0x00ff, 0x0040, 0x1b92, 0x7007, 0x0004, 0x7004, 0xa084, 0x0004,
+	0x00c0, 0x1b8d, 0x21a8, 0x7017, 0x0000, 0x810b, 0x7112, 0x721a,
+	0x731e, 0x7422, 0x7526, 0x780c, 0xa085, 0x0000, 0x7002, 0x53a6,
+	0x7007, 0x0001, 0x2001, 0x04fd, 0x2004, 0xa082, 0x0005, 0x00c8,
+	0x1bb0, 0x2009, 0x0022, 0x2104, 0xa084, 0x4000, 0x00c0, 0x1ba2,
+	0x7010, 0xa084, 0xf000, 0x0040, 0x1bb9, 0x7007, 0x0008, 0x0078,
+	0x1bbd, 0x7108, 0x8103, 0x00c8, 0x1ba2, 0x7007, 0x0002, 0xa184,
+	0x01e0, 0x7003, 0x0000, 0x007c, 0x2001, 0x04fd, 0x2004, 0xa082,
+	0x0004, 0x00c8, 0x1bcd, 0x0078, 0x1bd0, 0xa006, 0x0078, 0x1bd2,
+	0xa085, 0x0001, 0x007c, 0x0e7e, 0x2071, 0x5200, 0x2d08, 0x7058,
+	0x6802, 0xa005, 0x00c0, 0x1bdd, 0x715e, 0x715a, 0x0e7f, 0x007c,
+	0x2c08, 0x7858, 0x6002, 0xa005, 0x00c0, 0x1be7, 0x795e, 0x795a,
+	0x007c, 0x2091, 0x8000, 0x6114, 0x1078, 0x2180, 0x6900, 0xa184,
+	0x0100, 0x00c0, 0x2035, 0xa184, 0x0200, 0x00c0, 0x2031, 0x681c,
+	0xa005, 0x00c0, 0x203d, 0x6003, 0x0000, 0x2c08, 0x785c, 0xa065,
+	0x00c0, 0x1c05, 0x795a, 0x0078, 0x1c06, 0x6102, 0x795e, 0x2091,
+	0x8001, 0x1078, 0x228c, 0x007c, 0x0e7e, 0x2071, 0x5200, 0x7058,
+	0xa06d, 0x0040, 0x1c1a, 0x6800, 0x705a, 0xa005, 0x00c0, 0x1c19,
+	0x705e, 0x8dff, 0x0e7f, 0x007c, 0x0d7e, 0x0c7e, 0x0f7e, 0x2079,
+	0x5200, 0xaf80, 0x0016, 0x2060, 0x6000, 0xa005, 0x0040, 0x1c43,
+	0x2068, 0x6814, 0xa306, 0x00c0, 0x1c33, 0x6828, 0xa084, 0x00ff,
+	0xa406, 0x0040, 0x1c36, 0x2d60, 0x0078, 0x1c24, 0x6800, 0xa005,
+	0x6002, 0x00c0, 0x1c42, 0xaf80, 0x0016, 0xac06, 0x0040, 0x1c41,
+	0x2c00, 0x785e, 0x2d00, 0x0f7f, 0x0c7f, 0x0d7f, 0xa005, 0x007c,
+	0x0d7e, 0x0c7e, 0x0f7e, 0x2079, 0x5200, 0xaf80, 0x0016, 0x2060,
+	0x6000, 0xa005, 0x0040, 0x1c6b, 0x2068, 0x6814, 0xa084, 0x00ff,
+	0xa306, 0x0040, 0x1c5e, 0x2d60, 0x0078, 0x1c50, 0x6800, 0xa005,
+	0x6002, 0x00c0, 0x1c6a, 0xaf80, 0x0016, 0xac06, 0x0040, 0x1c69,
+	0x2c00, 0x785e, 0x2d00, 0x0f7f, 0x0c7f, 0x0d7f, 0xa005, 0x007c,
+	0x0d7e, 0x0c7e, 0x0f7e, 0x2079, 0x5200, 0xaf80, 0x0016, 0x2060,
+	0x6000, 0xa06d, 0x0040, 0x1c90, 0x6814, 0xa306, 0x0040, 0x1c83,
+	0x2d60, 0x0078, 0x1c78, 0x6800, 0xa005, 0x6002, 0x00c0, 0x1c8f,
+	0xaf80, 0x0016, 0xac06, 0x0040, 0x1c8e, 0x2c00, 0x785e, 0x2d00,
+	0x0f7f, 0x0c7f, 0x0d7f, 0xa005, 0x007c, 0x2091, 0x8000, 0x2069,
+	0x5240, 0x6800, 0xa086, 0x0000, 0x0040, 0x1ca3, 0x2091, 0x8001,
+	0x78e3, 0x0009, 0x007c, 0x6880, 0xa0bc, 0xff00, 0x2041, 0x0021,
+	0x2049, 0x0004, 0x2051, 0x0010, 0x1078, 0x19d2, 0x8738, 0xa784,
+	0x001f, 0x00c0, 0x1cac, 0x2091, 0x8001, 0x2001, 0x800a, 0x0078,
+	0x1cc3, 0x2001, 0x800c, 0x0078, 0x1cc3, 0x1078, 0x1a9c, 0x2001,
+	0x800d, 0x0078, 0x1cc3, 0x70c2, 0x2061, 0x0000, 0x601b, 0x0001,
+	0x2091, 0x4080, 0x007c, 0x6004, 0x2c08, 0x2063, 0x0000, 0x7884,
+	0x8000, 0x7886, 0x7888, 0xa005, 0x798a, 0x0040, 0x1cda, 0x2c02,
+	0x0078, 0x1cdb, 0x798e, 0x007c, 0x6807, 0x0103, 0x0c7e, 0x2061,
+	0x5200, 0x2d08, 0x206b, 0x0000, 0x6084, 0x8000, 0x6086, 0x6088,
+	0xa005, 0x618a, 0x0040, 0x1cef, 0x2d02, 0x0078, 0x1cf0, 0x618e,
+	0x0c7f, 0x007c, 0x1078, 0x1d03, 0x0040, 0x1d02, 0x0c7e, 0x609c,
+	0xa065, 0x0040, 0x1cfd, 0x1078, 0x1a17, 0x0c7f, 0x609f, 0x0000,
+	0x1078, 0x199a, 0x007c, 0x788c, 0xa065, 0x0040, 0x1d15, 0x2091,
+	0x8000, 0x7884, 0x8001, 0x7886, 0x2c04, 0x788e, 0xa005, 0x00c0,
+	0x1d13, 0x788a, 0x8000, 0x2091, 0x8001, 0x007c, 0x20a9, 0x0010,
+	0xa006, 0x8004, 0x8086, 0x818e, 0x00c8, 0x1d1f, 0xa200, 0x0070,
+	0x1d23, 0x0078, 0x1d1a, 0x8086, 0x818e, 0x007c, 0x157e, 0x20a9,
+	0x0010, 0xa005, 0x0040, 0x1d49, 0xa11a, 0x00c8, 0x1d49, 0x8213,
+	0x818d, 0x0048, 0x1d3a, 0xa11a, 0x00c8, 0x1d3b, 0x0070, 0x1d41,
+	0x0078, 0x1d2f, 0xa11a, 0x2308, 0x8210, 0x0070, 0x1d41, 0x0078,
+	0x1d2f, 0x007e, 0x3200, 0xa084, 0xf7ff, 0x2080, 0x007f, 0x157f,
+	0x007c, 0x007e, 0x3200, 0xa085, 0x0800, 0x0078, 0x1d45, 0x7994,
+	0x70d0, 0xa106, 0x0040, 0x1dbd, 0x2091, 0x8000, 0x2071, 0x0020,
+	0x7004, 0xa005, 0x00c0, 0x1dbd, 0x7008, 0x7208, 0xa206, 0x00c0,
+	0x1dbd, 0xa286, 0x0008, 0x00c0, 0x1dbd, 0x2071, 0x0010, 0x1078,
+	0x1980, 0x0040, 0x1dbd, 0x7a9c, 0x7b98, 0x7ca4, 0x7da0, 0xa184,
+	0xff00, 0x0040, 0x1d8b, 0x2031, 0x0000, 0x810b, 0x86b5, 0x810b,
+	0x86b5, 0x810b, 0x86b5, 0x810b, 0x86b5, 0x810b, 0x86b5, 0x810b,
+	0x86b5, 0x2100, 0xa210, 0x2600, 0xa319, 0xa4a1, 0x0000, 0xa5a9,
+	0x0000, 0x0078, 0x1d95, 0x8107, 0x8004, 0x8004, 0xa210, 0xa399,
+	0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x2009, 0x0020, 0x1078,
+	0x197b, 0x2091, 0x8001, 0x0040, 0x1db4, 0x1078, 0x199a, 0x78a8,
+	0x8000, 0x78aa, 0xa086, 0x0002, 0x00c0, 0x1dbd, 0x2091, 0x8000,
+	0x78e3, 0x0002, 0x78ab, 0x0000, 0x78cc, 0xa085, 0x0003, 0x78ce,
+	0x2091, 0x8001, 0x0078, 0x1dbd, 0x78ab, 0x0000, 0x1078, 0x2149,
+	0x6004, 0xa084, 0x000f, 0x0079, 0x1dc2, 0x2071, 0x0010, 0x2091,
+	0x8001, 0x007c, 0x1dd2, 0x1df4, 0x1e1a, 0x1dd2, 0x1e37, 0x1de1,
+	0x1fc9, 0x1fe4, 0x1dd2, 0x1dee, 0x1e14, 0x1e7f, 0x1eee, 0x1f57,
+	0x1f69, 0x1fe0, 0x2039, 0x0400, 0x78dc, 0xa705, 0x78de, 0x6008,
+	0xa705, 0x600a, 0x1078, 0x2064, 0x609c, 0x78da, 0x1078, 0x2131,
+	0x007c, 0x78dc, 0xa084, 0x0100, 0x0040, 0x1de8, 0x0078, 0x1dd2,
+	0x601c, 0xa085, 0x0080, 0x601e, 0x0078, 0x1dfb, 0x1078, 0x1bc4,
+	0x00c0, 0x1dd2, 0x1078, 0x2163, 0x78dc, 0xa084, 0x0100, 0x0040,
+	0x1dfb, 0x0078, 0x1dd2, 0x78df, 0x0000, 0x6004, 0x8007, 0xa084,
+	0x00ff, 0x78d2, 0x8001, 0x609f, 0x0000, 0x0040, 0x1e11, 0x1078,
+	0x2064, 0x0040, 0x1e11, 0x78dc, 0xa085, 0x0100, 0x78de, 0x0078,
+	0x1e13, 0x1078, 0x2088, 0x007c, 0x1078, 0x1bc4, 0x00c0, 0x1dd2,
+	0x1078, 0x215f, 0x78dc, 0xa08c, 0x0e00, 0x00c0, 0x1e23, 0xa084,
+	0x0100, 0x00c0, 0x1e25, 0x0078, 0x1dd2, 0x1078, 0x2064, 0x00c0,
+	0x1e36, 0x6104, 0xa18c, 0x00ff, 0xa186, 0x0007, 0x0040, 0x2021,
+	0xa186, 0x000f, 0x0040, 0x2021, 0x1078, 0x2088, 0x007c, 0x78dc,
+	0xa084, 0x0100, 0x0040, 0x1e3e, 0x0078, 0x1dd2, 0x78df, 0x0000,
+	0x6714, 0x2011, 0x0001, 0x20a9, 0x0001, 0x6018, 0xa084, 0x00ff,
+	0xa005, 0x0040, 0x1e61, 0x2011, 0x0001, 0xa7bc, 0xff00, 0x20a9,
+	0x0020, 0xa08e, 0x0001, 0x0040, 0x1e61, 0x2039, 0x0000, 0x2011,
+	0x0002, 0x20a9, 0x0100, 0xa08e, 0x0002, 0x0040, 0x1e61, 0x0078,
+	0x1e7c, 0x1078, 0x19c5, 0x2091, 0x8000, 0x682b, 0x0000, 0x682f,
+	0x0000, 0x6808, 0xa084, 0xffde, 0x680a, 0xade8, 0x0010, 0x2091,
+	0x8001, 0x0070, 0x1e75, 0x0078, 0x1e63, 0x8211, 0x0040, 0x1e7c,
+	0x20a9, 0x0100, 0x0078, 0x1e63, 0x1078, 0x199a, 0x007c, 0x2001,
+	0x5267, 0x2004, 0xa084, 0x8000, 0x0040, 0x2049, 0x6114, 0x1078,
+	0x2180, 0x6900, 0xa184, 0x0001, 0x0040, 0x1ea0, 0x6028, 0xa084,
+	0x00ff, 0x00c0, 0x2041, 0x6800, 0xa084, 0x0001, 0x0040, 0x2049,
+	0x6803, 0x0000, 0x680b, 0x0000, 0x6807, 0x0000, 0x0078, 0x2051,
+	0x2011, 0x0001, 0x6020, 0xd0f4, 0x0040, 0x1ea8, 0xa295, 0x0002,
+	0xd0c4, 0x0040, 0x1ead, 0xa295, 0x0008, 0xd0cc, 0x0040, 0x1eb2,
+	0xa295, 0x0400, 0x601c, 0xa084, 0x0002, 0x0040, 0x1eb9, 0xa295,
+	0x0004, 0x602c, 0xa08c, 0x00ff, 0xa182, 0x0002, 0x0048, 0x204d,
+	0xa182, 0x001b, 0x00c8, 0x204d, 0x0040, 0x204d, 0x690e, 0x602c,
+	0x8007, 0xa08c, 0x00ff, 0xa182, 0x0002, 0x0048, 0x204d, 0xa182,
+	0x001b, 0x00c8, 0x204d, 0x0040, 0x204d, 0x6912, 0x6030, 0xa005,
+	0x00c0, 0x1edc, 0x2001, 0x001e, 0x8000, 0x6816, 0x6028, 0xa084,
+	0x00ff, 0x0040, 0x2049, 0x6806, 0x6028, 0x8007, 0xa084, 0x00ff,
+	0x0040, 0x2049, 0x680a, 0x6a02, 0x0078, 0x2051, 0x2001, 0x5240,
+	0x2004, 0xa086, 0x0007, 0x00c0, 0x1f53, 0x2001, 0x5267, 0x2004,
+	0xa084, 0x8000, 0x0040, 0x2049, 0x6114, 0x1078, 0x2180, 0x2001,
+	0x5252, 0x2004, 0x2010, 0x82ff, 0x0040, 0x1f0e, 0xa080, 0x0005,
+	0x2004, 0xa084, 0x00ff, 0xa106, 0x00c0, 0x1f53, 0x2091, 0x8000,
+	0x6a04, 0x6b08, 0x6418, 0xa484, 0x0003, 0x0040, 0x1f2d, 0x6128,
+	0xa18c, 0x00ff, 0x8001, 0x00c0, 0x1f23, 0x2100, 0xa210, 0x0048,
+	0x1f53, 0x0078, 0x1f2d, 0x8001, 0x00c0, 0x1f53, 0x2100, 0xa212,
+	0x0048, 0x1f53, 0x82ff, 0x0040, 0x1f53, 0xa484, 0x000c, 0x0040,
+	0x1f47, 0x6128, 0x810f, 0xa18c, 0x00ff, 0xa082, 0x0004, 0x00c0,
+	0x1f3f, 0x2100, 0xa318, 0x0048, 0x1f53, 0x0078, 0x1f47, 0xa082,
+	0x0004, 0x00c0, 0x1f53, 0x2100, 0xa31a, 0x0048, 0x1f53, 0x6030,
+	0xa005, 0x0040, 0x1f4d, 0x8000, 0x6816, 0x6a06, 0x6b0a, 0x2091,
+	0x8001, 0x0078, 0x2051, 0x2091, 0x8001, 0x0078, 0x204d, 0x6114,
+	0x1078, 0x2180, 0x2091, 0x8000, 0x6b08, 0x8318, 0x0048, 0x1f65,
+	0x6b0a, 0x2091, 0x8001, 0x0078, 0x2060, 0x2091, 0x8001, 0x0078,
+	0x204d, 0x6024, 0x8007, 0xa084, 0x00ff, 0x0040, 0x1f87, 0xa086,
+	0x0080, 0x00c0, 0x1fc7, 0x20a9, 0x0008, 0x2069, 0x7610, 0x2091,
+	0x8000, 0x6800, 0xa084, 0xfcff, 0x6802, 0xade8, 0x0008, 0x0070,
+	0x1f83, 0x0078, 0x1f79, 0x2091, 0x8001, 0x0078, 0x2051, 0x6028,
+	0xa015, 0x0040, 0x1fc7, 0x6114, 0x1078, 0x2180, 0x0c7e, 0x0d7e,
+	0xade8, 0x0007, 0x2091, 0x8000, 0x6800, 0xa00d, 0x0040, 0x1fc3,
+	0xa206, 0x0040, 0x1f9e, 0x2168, 0x0078, 0x1f94, 0x2160, 0x6000,
+	0x6802, 0x2c68, 0x1078, 0x19ac, 0x0d7f, 0x6818, 0xa00d, 0x0040,
+	0x1fbb, 0x2060, 0x6200, 0x6a1a, 0x6a1c, 0x6202, 0x681e, 0x1078,
+	0x1989, 0x2da0, 0x2198, 0x20a9, 0x0031, 0x53a3, 0x2d60, 0x1078,
+	0x1ccb, 0x0078, 0x1fbe, 0x6808, 0x8000, 0x680a, 0x2091, 0x8001,
+	0x0c7f, 0x0078, 0x2060, 0x2091, 0x8001, 0x0d7f, 0x0c7f, 0x0078,
+	0x2049, 0x6114, 0x1078, 0x2180, 0x6800, 0xa084, 0x0001, 0x0040,
+	0x2039, 0x2091, 0x8000, 0x6a04, 0x8210, 0x0048, 0x1fdc, 0x6a06,
+	0x2091, 0x8001, 0x0078, 0x2060, 0x2091, 0x8001, 0x0078, 0x204d,
+	0x1078, 0x1bc4, 0x00c0, 0x1dd2, 0x6114, 0x1078, 0x2180, 0x60be,
+	0x60bb, 0x0000, 0x6900, 0xa184, 0x0008, 0x0040, 0x1ff3, 0x6020,
+	0xa085, 0x0100, 0x6022, 0xa184, 0x0001, 0x0040, 0x2049, 0xa184,
+	0x0100, 0x00c0, 0x2035, 0xa184, 0x0200, 0x00c0, 0x2031, 0x681c,
+	0xa005, 0x00c0, 0x203d, 0x6004, 0xa084, 0x00ff, 0xa086, 0x000f,
+	0x00c0, 0x200c, 0x1078, 0x2163, 0x78df, 0x0000, 0x6004, 0x8007,
+	0xa084, 0x00ff, 0x78d2, 0x8001, 0x609f, 0x0000, 0x0040, 0x2021,
+	0x1078, 0x2064, 0x0040, 0x2021, 0x78dc, 0xa085, 0x0100, 0x78de,
+	0x007c, 0x78d7, 0x0000, 0x78db, 0x0000, 0x6024, 0xa084, 0xff00,
+	0x6026, 0x1078, 0x3aac, 0x0040, 0x1d4f, 0x1078, 0x1be9, 0x0078,
+	0x1d4f, 0x2009, 0x0017, 0x0078, 0x2053, 0x2009, 0x000e, 0x0078,
+	0x2053, 0x2009, 0x0007, 0x0078, 0x2053, 0x2009, 0x0035, 0x0078,
+	0x2053, 0x2009, 0x003e, 0x0078, 0x2053, 0x2009, 0x0004, 0x0078,
+	0x2053, 0x2009, 0x0006, 0x0078, 0x2053, 0x2009, 0x0016, 0x0078,
+	0x2053, 0x2009, 0x0001, 0x6024, 0xa084, 0xff00, 0xa105, 0x6026,
+	0x2091, 0x8000, 0x1078, 0x1ccb, 0x2091, 0x8001, 0x0078, 0x1d4f,
+	0x1078, 0x199a, 0x0078, 0x1d4f, 0x78d4, 0xa06d, 0x00c0, 0x206f,
+	0x2c00, 0x78d6, 0x78da, 0x609f, 0x0000, 0x0078, 0x207b, 0x2c00,
+	0x689e, 0x609f, 0x0000, 0x78d6, 0x2d00, 0x6002, 0x78d8, 0xad06,
+	0x00c0, 0x207b, 0x6002, 0x78d0, 0x8001, 0x78d2, 0x00c0, 0x2087,
+	0x78dc, 0xa084, 0xfeff, 0x78de, 0x78d8, 0x2060, 0xa006, 0x007c,
+	0xa02e, 0x2530, 0x611c, 0x61a2, 0xa184, 0xe1ff, 0x601e, 0xa184,
+	0x0060, 0x0040, 0x2097, 0x0e7e, 0x1078, 0x48d3, 0x0e7f, 0x6596,
+	0x65a6, 0x669a, 0x66aa, 0x60af, 0x0000, 0x60b3, 0x0000, 0x6714,
+	0x1078, 0x19c5, 0x2091, 0x8000, 0x60a0, 0xa084, 0x8000, 0x00c0,
+	0x20be, 0x6808, 0xa084, 0x0001, 0x0040, 0x20be, 0x2091, 0x8001,
+	0x1078, 0x1a31, 0x2091, 0x8000, 0x1078, 0x1ccb, 0x2091, 0x8001,
+	0x78d7, 0x0000, 0x78db, 0x0000, 0x0078, 0x2130, 0x6024, 0xa096,
+	0x0001, 0x00c0, 0x20c5, 0x8000, 0x6026, 0x6a10, 0x6814, 0x2091,
+	0x8001, 0xa202, 0x0048, 0x20d4, 0x0040, 0x20d4, 0x2039, 0x0200,
+	0x1078, 0x2131, 0x0078, 0x2130, 0x2c08, 0x2091, 0x8000, 0x60a0,
+	0xa084, 0x8000, 0x0040, 0x2101, 0x6800, 0xa065, 0x0040, 0x2106,
+	0x6a04, 0x0e7e, 0x2071, 0x5240, 0x7000, 0xa084, 0x0001, 0x0040,
+	0x20fb, 0x7048, 0xa206, 0x00c0, 0x20fb, 0x6b04, 0x231c, 0x2160,
+	0x6302, 0x2300, 0xa005, 0x00c0, 0x20f6, 0x6902, 0x2260, 0x6102,
+	0x0e7f, 0x0078, 0x210d, 0x2160, 0x6202, 0x6906, 0x0e7f, 0x0078,
+	0x210d, 0x6800, 0xa065, 0x0040, 0x2106, 0x6102, 0x6902, 0x00c0,
+	0x210a, 0x6906, 0x2160, 0x6003, 0x0000, 0x2160, 0x60a0, 0xa084,
+	0x8000, 0x0040, 0x2117, 0x6808, 0xa084, 0xfffc, 0x680a, 0x6810,
+	0x8000, 0x6812, 0x2091, 0x8001, 0x6808, 0xa08c, 0x0040, 0x0040,
+	0x2126, 0xa086, 0x0040, 0x680a, 0x1078, 0x1a42, 0x2091, 0x8000,
+	0x1078, 0x226f, 0x2091, 0x8001, 0x78db, 0x0000, 0x78d7, 0x0000,
+	0x007c, 0x6008, 0xa705, 0x600a, 0x2091, 0x8000, 0x1078, 0x1ccb,
+	0x2091, 0x8001, 0x78d8, 0xa065, 0x0040, 0x2144, 0x609c, 0x78da,
+	0x609f, 0x0000, 0x0078, 0x2134, 0x78d7, 0x0000, 0x78db, 0x0000,
+	0x007c, 0x7990, 0x7894, 0x8000, 0xa10a, 0x00c8, 0x2150, 0xa006,
+	0x7896, 0x70d2, 0x7804, 0xa005, 0x0040, 0x215e, 0x8001, 0x7806,
+	0x00c0, 0x215e, 0x0068, 0x215e, 0x2091, 0x4080, 0x007c, 0x2039,
+	0x2177, 0x0078, 0x2165, 0x2039, 0x217d, 0x2704, 0xa005, 0x0040,
+	0x2176, 0xac00, 0x2068, 0x6b08, 0x6c0c, 0x6910, 0x6a14, 0x690a,
+	0x6a0e, 0x6b12, 0x6c16, 0x8738, 0x0078, 0x2165, 0x007c, 0x0003,
+	0x0009, 0x000f, 0x0015, 0x001b, 0x0000, 0x0015, 0x001b, 0x0000,
+	0x0c7e, 0x1078, 0x3c3b, 0x2c68, 0x0c7f, 0x007c, 0x0010, 0x21f7,
+	0x0068, 0x21f7, 0x2029, 0x0000, 0x78cb, 0x0000, 0x788c, 0xa065,
+	0x0040, 0x21f0, 0x2009, 0x5274, 0x2104, 0xa084, 0x0001, 0x0040,
+	0x21be, 0x6004, 0xa086, 0x0103, 0x00c0, 0x21be, 0x6018, 0xa005,
+	0x00c0, 0x21be, 0x6014, 0xa005, 0x00c0, 0x21be, 0x0d7e, 0x2069,
+	0x0000, 0x6818, 0xa084, 0x0001, 0x00c0, 0x21bd, 0x600c, 0x70c6,
+	0x6010, 0x70ca, 0x70c3, 0x8020, 0x681b, 0x0001, 0x2091, 0x4080,
+	0x0d7f, 0x1078, 0x1cf2, 0x0078, 0x21f5, 0x0d7f, 0x1078, 0x21f8,
+	0x0040, 0x21f0, 0x6204, 0xa294, 0x00ff, 0xa296, 0x0003, 0x0040,
+	0x21d0, 0x6204, 0xa296, 0x0110, 0x00c0, 0x21de, 0x78cb, 0x0001,
+	0x6204, 0xa294, 0xff00, 0x8217, 0x8211, 0x0040, 0x21de, 0x85ff,
+	0x00c0, 0x21f0, 0x8210, 0xa202, 0x00c8, 0x21f0, 0x057e, 0x1078,
+	0x2207, 0x057f, 0x0040, 0x21eb, 0x78e0, 0xa086, 0x0003, 0x0040,
+	0x21f0, 0x0078, 0x21de, 0x8528, 0x78c8, 0xa005, 0x0040, 0x218e,
+	0x85ff, 0x0040, 0x21f7, 0x2091, 0x4080, 0x78b0, 0x70d6, 0x007c,
+	0x7bac, 0x79b0, 0x70d4, 0xa102, 0x00c0, 0x2201, 0x2300, 0xa005,
+	0x007c, 0x0048, 0x2205, 0xa302, 0x007c, 0x8002, 0x007c, 0x2001,
+	0x04fd, 0x2004, 0xa082, 0x0005, 0x00c8, 0x2221, 0x2091, 0x8000,
+	0x2071, 0x0020, 0x7004, 0xa005, 0x00c0, 0x2256, 0x7008, 0x7208,
+	0xa206, 0x00c0, 0x2256, 0xa286, 0x0008, 0x00c0, 0x2256, 0x2071,
+	0x0010, 0x1078, 0x225b, 0x2009, 0x0020, 0x6004, 0xa086, 0x0103,
+	0x00c0, 0x2230, 0x6028, 0xa005, 0x00c0, 0x2230, 0x2009, 0x000c,
+	0x1078, 0x1976, 0x0040, 0x2249, 0x78c4, 0x8000, 0x78c6, 0xa086,
+	0x0002, 0x00c0, 0x2256, 0x2091, 0x8000, 0x78e3, 0x0003, 0x78c7,
+	0x0000, 0x78cc, 0xa085, 0x0300, 0x78ce, 0x2091, 0x8001, 0x0078,
+	0x2256, 0x78c7, 0x0000, 0x1078, 0x1cf2, 0x79ac, 0x78b0, 0x8000,
+	0xa10a, 0x00c8, 0x2254, 0xa006, 0x78b2, 0xa006, 0x2071, 0x0010,
+	0x2091, 0x8001, 0x007c, 0x8107, 0x8004, 0x8004, 0x7ab8, 0x7bb4,
+	0x7cc0, 0x7dbc, 0xa210, 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9,
+	0x0000, 0x007c, 0x2009, 0x525b, 0x2091, 0x8000, 0x200a, 0x0f7e,
+	0x0e7e, 0x2071, 0x5240, 0x7000, 0xa086, 0x0000, 0x00c0, 0x2289,
+	0x2009, 0x5212, 0x2104, 0xa005, 0x00c0, 0x2289, 0x2079, 0x0100,
+	0x7830, 0xa084, 0x00c0, 0x00c0, 0x2289, 0x0018, 0x2289, 0x781b,
+	0x004b, 0x0e7f, 0x0f7f, 0x007c, 0x0f7e, 0x0e7e, 0x2071, 0x5240,
+	0x2091, 0x8000, 0x7000, 0xa086, 0x0000, 0x00c0, 0x22a2, 0x2079,
+	0x0100, 0x7830, 0xa084, 0x00c0, 0x00c0, 0x22a2, 0x0018, 0x22a2,
+	0x781b, 0x004d, 0x2091, 0x8001, 0x0e7f, 0x0f7f, 0x007c, 0x127e,
+	0x2091, 0x2300, 0x2071, 0x5240, 0x2079, 0x0100, 0x784b, 0x000f,
+	0x0098, 0x22b5, 0x7838, 0x0078, 0x22ae, 0x20a9, 0x0040, 0x7800,
+	0xa082, 0x0004, 0x0048, 0x22be, 0x20a9, 0x0060, 0x789b, 0x0000,
+	0x78af, 0x0000, 0x78af, 0x0000, 0x0070, 0x22c8, 0x0078, 0x22c0,
+	0x7800, 0xa082, 0x0004, 0x0048, 0x22d7, 0x70b7, 0x0093, 0x2019,
+	0x4ff0, 0x1078, 0x2313, 0x702f, 0x8001, 0x0078, 0x22e3, 0x70b7,
+	0x0000, 0x2019, 0x4e70, 0x1078, 0x2313, 0x2019, 0x4eaf, 0x1078,
+	0x2313, 0x702f, 0x8000, 0x7003, 0x0000, 0x1078, 0x2420, 0x7004,
+	0xa084, 0x000f, 0x017e, 0x2009, 0x04fd, 0x210c, 0xa18a, 0x0005,
+	0x0048, 0x22f8, 0x0038, 0x22fe, 0xa085, 0x6280, 0x0078, 0x2300,
+	0x0028, 0x22fe, 0xa085, 0x6280, 0x0078, 0x2300, 0xa085, 0x62c0,
+	0x017f, 0x7806, 0x780f, 0xb204, 0x7843, 0x00d8, 0x7853, 0x0080,
+	0x780b, 0x0008, 0x7047, 0x0008, 0x7053, 0x527f, 0x704f, 0x0000,
+	0x127f, 0x2000, 0x007c, 0x137e, 0x147e, 0x157e, 0x047e, 0x20a1,
+	0x012b, 0x2304, 0xa005, 0x789a, 0x0040, 0x2333, 0x8318, 0x2324,
+	0x8318, 0x2398, 0x24a8, 0xa484, 0xff00, 0x0040, 0x232b, 0xa482,
+	0x0100, 0x20a9, 0x0100, 0x2020, 0x53a6, 0xa005, 0x00c0, 0x2322,
+	0x3318, 0x0078, 0x2319, 0x047f, 0x157f, 0x147f, 0x137f, 0x007c,
+	0xa18c, 0x000f, 0x2011, 0x0101, 0x2204, 0xa084, 0xfff0, 0xa105,
+	0x2012, 0x1078, 0x2420, 0x007c, 0x2011, 0x0101, 0x20a9, 0x0009,
+	0x810b, 0x0070, 0x234d, 0x0078, 0x2348, 0xa18c, 0x0e00, 0x2204,
+	0xa084, 0xf1ff, 0xa105, 0x2012, 0x007c, 0x2009, 0x0101, 0x20a9,
+	0x0005, 0x8213, 0x0070, 0x235e, 0x0078, 0x2359, 0xa294, 0x00e0,
+	0x2104, 0xa084, 0xff1f, 0xa205, 0x200a, 0x007c, 0x2011, 0x0101,
+	0x20a9, 0x000c, 0x810b, 0x0070, 0x236f, 0x0078, 0x236a, 0xa18c,
+	0xf000, 0x2204, 0xa084, 0x0fff, 0xa105, 0x2012, 0x007c, 0x2011,
+	0x0102, 0x2204, 0xa084, 0xffcf, 0xa105, 0x2012, 0x007c, 0x8103,
+	0x8003, 0xa080, 0x0020, 0x0c7e, 0x2061, 0x0100, 0x609a, 0x62ac,
+	0x63ac, 0x0c7f, 0x007c, 0x8103, 0x8003, 0xa080, 0x0022, 0x0c7e,
+	0x2061, 0x0100, 0x609a, 0x60a4, 0xa084, 0xffdf, 0x60ae, 0x0c7f,
+	0x007c, 0x8103, 0x8003, 0xa080, 0x0022, 0x0c7e, 0x2061, 0x0100,
+	0x609a, 0x60a4, 0xa085, 0x0020, 0x60ae, 0x0c7f, 0x007c, 0x8103,
+	0x8003, 0xa080, 0x0020, 0x0c7e, 0x2061, 0x0100, 0x609a, 0x60a4,
+	0x62ae, 0x2010, 0x60a4, 0x63ae, 0x2018, 0x0c7f, 0x007c, 0x2091,
+	0x8000, 0x0c7e, 0x0e7e, 0x6818, 0xa005, 0x0040, 0x23fe, 0x2061,
+	0x7600, 0x1078, 0x2406, 0x0040, 0x23e8, 0x20a9, 0x0000, 0x2061,
+	0x7500, 0x0c7e, 0x1078, 0x2406, 0x0040, 0x23d6, 0x0c7f, 0x8c60,
+	0x0070, 0x23d4, 0x0078, 0x23c9, 0x0078, 0x23fe, 0x007f, 0xa082,
+	0x7500, 0x2071, 0x5240, 0x7086, 0x7182, 0x2001, 0x0004, 0x706e,
+	0x7093, 0x000f, 0x7073, 0x0000, 0x1078, 0x226a, 0x0078, 0x23fa,
+	0x60c0, 0xa005, 0x00c0, 0x23fe, 0x2071, 0x5240, 0x7182, 0x2c00,
+	0x708a, 0x2001, 0x0006, 0x706e, 0x7093, 0x000f, 0x7073, 0x0000,
+	0x1078, 0x226a, 0x2001, 0x0000, 0x0078, 0x2400, 0x2001, 0x0001,
+	0x2091, 0x8001, 0xa005, 0x0e7f, 0x0c7f, 0x007c, 0x2c04, 0xa005,
+	0x0040, 0x241d, 0x2060, 0x600c, 0xa306, 0x00c0, 0x241a, 0x6010,
+	0xa206, 0x00c0, 0x241a, 0x6014, 0xa106, 0x00c0, 0x241a, 0xa006,
+	0x0078, 0x241f, 0x6000, 0x0078, 0x2407, 0xa085, 0x0001, 0x007c,
+	0x2011, 0x5241, 0x220c, 0xa18c, 0x000f, 0x2011, 0x013b, 0x2204,
+	0xa084, 0x0100, 0x0040, 0x2436, 0x2021, 0xff04, 0x2122, 0x810b,
+	0x810b, 0x810b, 0x810b, 0xa18d, 0x0f00, 0x2104, 0x007c, 0x0e7e,
+	0x68e4, 0xa08c, 0x0020, 0x0040, 0x248a, 0xa084, 0x0006, 0x00c0,
+	0x248a, 0x6014, 0x8007, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003,
+	0xa0f0, 0x5480, 0x7004, 0xa084, 0x000a, 0x00c0, 0x248a, 0x7108,
+	0xa194, 0xff00, 0x0040, 0x248a, 0xa18c, 0x00ff, 0x2001, 0x000c,
+	0xa106, 0x0040, 0x2471, 0x2001, 0x0012, 0xa106, 0x0040, 0x2475,
+	0x2001, 0x0014, 0xa106, 0x0040, 0x2479, 0x2001, 0x0019, 0xa106,
+	0x0040, 0x247d, 0x2001, 0x0032, 0xa106, 0x0040, 0x2481, 0x0078,
+	0x2485, 0x2009, 0x0012, 0x0078, 0x2487, 0x2009, 0x0014, 0x0078,
+	0x2487, 0x2009, 0x0019, 0x0078, 0x2487, 0x2009, 0x0020, 0x0078,
+	0x2487, 0x2009, 0x003f, 0x0078, 0x2487, 0x2011, 0x0000, 0x2100,
+	0xa205, 0x700a, 0x0e7f, 0x007c, 0x0068, 0x248c, 0x2091, 0x8000,
+	0x2071, 0x0000, 0x007e, 0x7018, 0xa084, 0x0001, 0x00c0, 0x2493,
+	0x007f, 0x2071, 0x0010, 0x70ca, 0x007f, 0x70c6, 0x70c3, 0x8002,
+	0x70db, 0x0741, 0x70df, 0x0006, 0x2071, 0x0000, 0x701b, 0x0001,
+	0x2091, 0x4080, 0x0078, 0x24aa, 0x107e, 0x007e, 0x127e, 0x2091,
+	0x2300, 0x7f3c, 0x7e58, 0x7c30, 0x7d38, 0x77c2, 0x74c6, 0x76ca,
+	0x75ce, 0xa594, 0x003f, 0xa49c, 0x0003, 0xa484, 0x000f, 0x0079,
+	0x24c1, 0x24d3, 0x24d3, 0x24d3, 0x280d, 0x3a09, 0x24d1, 0x2502,
+	0x250c, 0x24d1, 0x24d1, 0x24d1, 0x24d1, 0x24d1, 0x24d1, 0x24d1,
+	0x24d1, 0x1078, 0x248c, 0x8507, 0xa084, 0x001f, 0x0079, 0x24d8,
+	0x2516, 0x280d, 0x29c7, 0x2ac4, 0x2aec, 0x2d8c, 0x3037, 0x309a,
+	0x30fb, 0x3180, 0x3238, 0x32d6, 0x2502, 0x28e9, 0x300c, 0x24f8,
+	0x3dac, 0x3dcc, 0x3f8f, 0x3f9b, 0x4074, 0x24f8, 0x24f8, 0x4149,
+	0x414d, 0x3daa, 0x24f8, 0x3efa, 0x24f8, 0x3c5e, 0x250c, 0x24f8,
+	0x1078, 0x248c, 0x0018, 0x24b1, 0x127f, 0x2091, 0x8001, 0x007f,
+	0x107f, 0x007c, 0x2019, 0x4f49, 0x1078, 0x2313, 0x702f, 0x0001,
+	0x781b, 0x004f, 0x0078, 0x24fa, 0x2019, 0x4eaf, 0x1078, 0x2313,
+	0x702f, 0x8000, 0x781b, 0x00cd, 0x0078, 0x24fa, 0x7242, 0x2009,
+	0x520f, 0x200b, 0x0000, 0xa584, 0x0001, 0x00c0, 0x3c72, 0x0040,
+	0x2533, 0x1078, 0x248c, 0x7003, 0x0000, 0x704b, 0x0000, 0x7043,
+	0x0000, 0x7037, 0x0000, 0x1078, 0x39e0, 0x0018, 0x24b1, 0x2009,
+	0x520f, 0x200b, 0x0000, 0x7068, 0xa005, 0x00c0, 0x25fe, 0x706c,
+	0xa084, 0x0007, 0x0079, 0x253c, 0x2635, 0x2544, 0x2550, 0x256d,
+	0x258f, 0x25dc, 0x25b5, 0x2544, 0x1078, 0x39c8, 0x2009, 0x0048,
+	0x1078, 0x2ed8, 0x00c0, 0x254e, 0x7003, 0x0004, 0x0078, 0x24fa,
+	0x1078, 0x39c8, 0x00c0, 0x256b, 0x7080, 0x8007, 0x7882, 0x789b,
+	0x0010, 0x78ab, 0x000c, 0x789b, 0x0060, 0x78ab, 0x0001, 0x785b,
+	0x0004, 0x2009, 0x00dd, 0x1078, 0x2ecc, 0x00c0, 0x256b, 0x7003,
+	0x0004, 0x7093, 0x000f, 0x0078, 0x24fa, 0x1078, 0x39c8, 0x00c0,
+	0x258d, 0x7180, 0x8107, 0x7882, 0x789b, 0x0010, 0xa18c, 0x001f,
+	0xa18d, 0x00c0, 0x79aa, 0x78ab, 0x0006, 0x789b, 0x0060, 0x78ab,
+	0x0002, 0x785b, 0x0004, 0x2009, 0x00dd, 0x1078, 0x2ecc, 0x00c0,
+	0x258d, 0x7003, 0x0004, 0x7093, 0x000f, 0x0078, 0x24fa, 0x1078,
+	0x39c8, 0x00c0, 0x25b3, 0x7180, 0x8107, 0x7882, 0x789b, 0x0010,
+	0xa18c, 0x001f, 0xa18d, 0x00c0, 0x79aa, 0x78ab, 0x0020, 0x7184,
+	0x79aa, 0x78ab, 0x000d, 0x789b, 0x0060, 0x78ab, 0x0004, 0x785b,
+	0x0004, 0x2009, 0x00dd, 0x1078, 0x2ecc, 0x00c0, 0x25b3, 0x7003,
+	0x0004, 0x7093, 0x000f, 0x0078, 0x24fa, 0x1078, 0x39c8, 0x00c0,
+	0x25da, 0x7180, 0x8107, 0x7882, 0x789b, 0x0010, 0xa18c, 0x001f,
+	0xa18d, 0x00c0, 0x79aa, 0x78ab, 0x0006, 0x789b, 0x0060, 0x78ab,
+	0x0002, 0x785b, 0x0004, 0x2009, 0x00dd, 0x1078, 0x2ecc, 0x00c0,
+	0x25da, 0x7088, 0x708b, 0x0000, 0x2068, 0x704a, 0x7003, 0x0002,
+	0x7093, 0x000f, 0x0078, 0x24fa, 0x1078, 0x39c8, 0x00c0, 0x24fa,
+	0x7088, 0x2068, 0x6f14, 0x1078, 0x38bd, 0x2c50, 0x1078, 0x3a7a,
+	0x789b, 0x0010, 0x6814, 0xa084, 0x001f, 0xa085, 0x0080, 0x78aa,
+	0x6e1c, 0x2041, 0x0001, 0x708c, 0xa084, 0x0400, 0x2001, 0x0004,
+	0x0040, 0x25fc, 0x2001, 0x0006, 0x0078, 0x271d, 0x1078, 0x39c8,
+	0x00c0, 0x24fa, 0x789b, 0x0010, 0x7068, 0x2068, 0x6f14, 0x1078,
+	0x38bd, 0x2c50, 0x1078, 0x3a7a, 0x6008, 0xa085, 0x0010, 0x600a,
+	0x6824, 0xa005, 0x0040, 0x261c, 0xa082, 0x0006, 0x0048, 0x261a,
+	0x0078, 0x261c, 0x6827, 0x0005, 0x6b14, 0xa39c, 0x001f, 0xa39d,
+	0x00c0, 0x7058, 0xa084, 0x8000, 0x0040, 0x262a, 0xa684, 0x0001,
+	0x0040, 0x262c, 0xa39c, 0xffbf, 0x7baa, 0x2031, 0x0020, 0x2041,
+	0x0001, 0x2001, 0x0003, 0x0078, 0x271d, 0x0018, 0x24b1, 0x744c,
+	0xa485, 0x0000, 0x0040, 0x264f, 0xa080, 0x5280, 0x2030, 0x7150,
+	0x8108, 0xa12a, 0x0048, 0x2646, 0x2009, 0x5280, 0x2164, 0x6504,
+	0x85ff, 0x00c0, 0x2660, 0x8421, 0x00c0, 0x2640, 0x7152, 0x7003,
+	0x0000, 0x704b, 0x0000, 0x7040, 0xa005, 0x0040, 0x3c72, 0x0078,
+	0x24fa, 0x764c, 0xa6b0, 0x5280, 0x7150, 0x2600, 0x0078, 0x264b,
+	0x7152, 0x2568, 0x2558, 0x754a, 0x2c50, 0x6034, 0xa085, 0x0000,
+	0x00c0, 0x265d, 0x6708, 0x773a, 0xa784, 0x033f, 0x0040, 0x2696,
+	0xa784, 0x0021, 0x00c0, 0x265d, 0xa784, 0x0002, 0x0040, 0x267f,
+	0xa784, 0x0004, 0x0040, 0x265d, 0xa7bc, 0xfffb, 0x670a, 0xa784,
+	0x0008, 0x00c0, 0x265d, 0xa784, 0x0010, 0x00c0, 0x265d, 0xa784,
+	0x0200, 0x00c0, 0x265d, 0xa784, 0x0100, 0x0040, 0x2696, 0x6018,
+	0xa005, 0x00c0, 0x265d, 0xa7bc, 0xfeff, 0x670a, 0x6823, 0x0000,
+	0x6e1c, 0xa684, 0x000e, 0x6118, 0x0040, 0x26a6, 0x601c, 0xa102,
+	0x0048, 0x26a9, 0x0040, 0x26a9, 0x0078, 0x2659, 0x81ff, 0x00c0,
+	0x2659, 0x68c3, 0x0000, 0xa784, 0x0080, 0x00c0, 0x26b1, 0x700c,
+	0x6022, 0xa7bc, 0xff7f, 0x670a, 0x1078, 0x3a7a, 0x0018, 0x24b1,
+	0x789b, 0x0010, 0xa046, 0x1078, 0x39c8, 0x00c0, 0x24fa, 0x6b14,
+	0xa39c, 0x001f, 0xa39d, 0x00c0, 0x7058, 0xa084, 0x8000, 0x0040,
+	0x26cd, 0xa684, 0x0001, 0x0040, 0x26cf, 0xa39c, 0xffbf, 0xa684,
+	0x0010, 0x0040, 0x26d5, 0xa39d, 0x0020, 0x7baa, 0x8840, 0xa684,
+	0x000e, 0x00c0, 0x26e0, 0xa7bd, 0x0010, 0x670a, 0x0078, 0x271b,
+	0x7158, 0xa18c, 0x0800, 0x0040, 0x34cb, 0x2011, 0x0020, 0xa684,
+	0x0008, 0x00c0, 0x26f1, 0x8210, 0xa684, 0x0002, 0x00c0, 0x26f1,
+	0x8210, 0x7aaa, 0x8840, 0x1078, 0x39e0, 0x6a14, 0x610c, 0x8108,
+	0xa18c, 0x00ff, 0xa1e0, 0x7500, 0x2c64, 0x8cff, 0x0040, 0x2712,
+	0x6014, 0xa206, 0x00c0, 0x26fc, 0x60b8, 0x8001, 0x60ba, 0x00c0,
+	0x26f7, 0x0c7e, 0x2a60, 0x6008, 0xa085, 0x0100, 0x600a, 0x0c7f,
+	0x0078, 0x2635, 0x1078, 0x39c8, 0x00c0, 0x24fa, 0x2a60, 0x610e,
+	0x79aa, 0x8840, 0x7132, 0x2001, 0x0001, 0x007e, 0x715c, 0xa184,
+	0x0018, 0x0040, 0x2738, 0xa184, 0x0010, 0x0040, 0x272b, 0x1078,
+	0x36d0, 0x00c0, 0x275b, 0xa184, 0x0008, 0x0040, 0x2738, 0x69a0,
+	0xa184, 0x0600, 0x00c0, 0x2738, 0x1078, 0x35bb, 0x0078, 0x275b,
+	0x69a0, 0xa184, 0x0800, 0x0040, 0x274f, 0x0c7e, 0x027e, 0x2960,
+	0x6000, 0xa085, 0x2000, 0x6002, 0x6104, 0xa18d, 0x0010, 0x6106,
+	0x027f, 0x0c7f, 0x1078, 0x36d0, 0x00c0, 0x275b, 0x69a0, 0xa184,
+	0x0200, 0x0040, 0x2757, 0x1078, 0x360c, 0x0078, 0x275b, 0xa184,
+	0x0400, 0x00c0, 0x2734, 0x69a0, 0xa184, 0x1000, 0x0040, 0x2766,
+	0x6914, 0xa18c, 0xff00, 0x810f, 0x1078, 0x238b, 0x007f, 0x7002,
+	0xa68c, 0x00e0, 0xa684, 0x0060, 0x0040, 0x2774, 0xa086, 0x0060,
+	0x00c0, 0x2774, 0xa18d, 0x4000, 0x88ff, 0x0040, 0x2779, 0xa18d,
+	0x0004, 0x795a, 0x69b6, 0x789b, 0x0060, 0x2800, 0x78aa, 0x789b,
+	0x0061, 0x6818, 0xa08d, 0x8000, 0xa084, 0x7fff, 0x691a, 0xa68c,
+	0x0080, 0x0040, 0x2798, 0x7097, 0x0000, 0xa08a, 0x000d, 0x0050,
+	0x2796, 0xa08a, 0x000c, 0x7196, 0x2001, 0x000c, 0x800c, 0x719a,
+	0x78aa, 0x8008, 0x810c, 0x0040, 0x34d1, 0xa18c, 0x00f8, 0x00c0,
+	0x34d1, 0x157e, 0x137e, 0x147e, 0x20a1, 0x012b, 0x789b, 0x0000,
+	0x8000, 0x80ac, 0xad80, 0x000b, 0x2098, 0x53a6, 0x147f, 0x137f,
+	0x157f, 0x6814, 0x8007, 0x7882, 0x6d94, 0x7dd6, 0x7dde, 0x6e98,
+	0x7ed2, 0x7eda, 0x1078, 0x39c8, 0x00c0, 0x27cf, 0x702c, 0x8003,
+	0x0048, 0x27c8, 0x2019, 0x4eaf, 0x1078, 0x2313, 0x702f, 0x8000,
+	0x7830, 0xa084, 0x00c0, 0x00c0, 0x27cf, 0x0098, 0x27d7, 0x6008,
+	0xa084, 0xffef, 0x600a, 0x1078, 0x39e0, 0x0078, 0x2523, 0x7200,
+	0xa284, 0x0007, 0xa086, 0x0001, 0x00c0, 0x27e4, 0x781b, 0x004f,
+	0x1078, 0x39e0, 0x0078, 0x27f5, 0x6ab4, 0xa295, 0x2000, 0x7a5a,
+	0x781b, 0x004f, 0x1078, 0x39e0, 0x7200, 0x2500, 0xa605, 0x0040,
+	0x27f5, 0xa284, 0x0007, 0x1079, 0x2803, 0xad80, 0x0009, 0x7036,
+	0xa284, 0x0007, 0xa086, 0x0001, 0x00c0, 0x24fa, 0x6018, 0x8000,
+	0x601a, 0x0078, 0x24fa, 0x280b, 0x4b4b, 0x4b4b, 0x4b3a, 0x4b4b,
+	0x280b, 0x4b3a, 0x280b, 0x1078, 0x248c, 0x1078, 0x39c8, 0x0f7e,
+	0x2079, 0x5200, 0x78cc, 0x0f7f, 0xa084, 0x0001, 0x0040, 0x2831,
+	0x706c, 0xa086, 0x0001, 0x00c0, 0x2820, 0x706e, 0x0078, 0x28c4,
+	0x706c, 0xa086, 0x0005, 0x00c0, 0x282f, 0x7088, 0x2068, 0x681b,
+	0x0004, 0x6817, 0x0000, 0x6820, 0xa085, 0x0008, 0x6822, 0x706f,
+	0x0000, 0x2011, 0x0004, 0x716c, 0xa186, 0x0001, 0x0040, 0x2852,
+	0xa186, 0x0007, 0x00c0, 0x2842, 0x2009, 0x5238, 0x200b, 0x0005,
+	0x0078, 0x2852, 0x2009, 0x5213, 0x2104, 0x2009, 0x5212, 0x200a,
+	0x2009, 0x5238, 0x200b, 0x0001, 0x706f, 0x0000, 0x7073, 0x0001,
+	0x0078, 0x2854, 0x706f, 0x0000, 0x1078, 0x4887, 0x157e, 0x20a9,
+	0x0010, 0x2039, 0x0000, 0x1078, 0x37b0, 0xa7b8, 0x0100, 0x0070,
+	0x2863, 0x0078, 0x285b, 0x157f, 0x7000, 0x0079, 0x2867, 0x2895,
+	0x287c, 0x287c, 0x286f, 0x2895, 0x2895, 0x2895, 0x2895, 0x2021,
+	0x525a, 0x2404, 0xa005, 0x0040, 0x2895, 0xad06, 0x00c0, 0x287c,
+	0x6800, 0x2022, 0x0078, 0x288c, 0x6820, 0xa084, 0x0001, 0x00c0,
+	0x2888, 0x6f14, 0x1078, 0x38bd, 0x1078, 0x34a2, 0x0078, 0x288c,
+	0x7060, 0x2060, 0x6800, 0x6002, 0x6a1a, 0x6817, 0x0000, 0x6820,
+	0xa085, 0x0008, 0x6822, 0x1078, 0x1cdc, 0x2021, 0x7600, 0x1078,
+	0x28d1, 0x2021, 0x525a, 0x1078, 0x28d1, 0x157e, 0x20a9, 0x0000,
+	0x2021, 0x7500, 0x1078, 0x28d1, 0x8420, 0x0070, 0x28a9, 0x0078,
+	0x28a2, 0x2061, 0x5500, 0x2021, 0x0002, 0x20a9, 0x0100, 0x6018,
+	0x6110, 0x81ff, 0x0040, 0x28b8, 0xa102, 0x0050, 0x28b8, 0x6012,
+	0x601b, 0x0000, 0xace0, 0x0010, 0x0070, 0x28c0, 0x0078, 0x28af,
+	0x8421, 0x00c0, 0x28ad, 0x157f, 0x709c, 0xa084, 0x8000, 0x0040,
+	0x28cb, 0x1078, 0x3ace, 0x7003, 0x0000, 0x704b, 0x0000, 0x0078,
+	0x24fa, 0x047e, 0x2404, 0xa005, 0x0040, 0x28e5, 0x2068, 0x6800,
+	0x007e, 0x6a1a, 0x6817, 0x0000, 0x6820, 0xa085, 0x0008, 0x6822,
+	0x1078, 0x1cdc, 0x007f, 0x0078, 0x28d3, 0x047f, 0x2023, 0x0000,
+	0x007c, 0xa282, 0x0003, 0x0050, 0x28ef, 0x1078, 0x248c, 0x2300,
+	0x0079, 0x28f2, 0x28f5, 0x2968, 0x2985, 0xa282, 0x0002, 0x0040,
+	0x28fb, 0x1078, 0x248c, 0x706c, 0x706f, 0x0000, 0x7093, 0x0000,
+	0x0079, 0x2902, 0x290a, 0x290a, 0x290c, 0x2940, 0x34d7, 0x290a,
+	0x2940, 0x290a, 0x1078, 0x248c, 0x7780, 0x1078, 0x37b0, 0x7780,
+	0xa7bc, 0x0f00, 0x1078, 0x38bd, 0x6018, 0xa005, 0x0040, 0x2937,
+	0x2021, 0x7600, 0x2009, 0x0004, 0x2011, 0x0010, 0x1078, 0x29a0,
+	0x0040, 0x2937, 0x157e, 0x20a9, 0x0000, 0x2021, 0x7500, 0x047e,
+	0x2009, 0x0004, 0x2011, 0x0010, 0x1078, 0x29a0, 0x047f, 0x0040,
+	0x2936, 0x8420, 0x0070, 0x2936, 0x0078, 0x2927, 0x157f, 0x8738,
+	0xa784, 0x001f, 0x00c0, 0x2912, 0x0078, 0x2523, 0x0078, 0x2523,
+	0x7780, 0x1078, 0x38bd, 0x6018, 0xa005, 0x0040, 0x2966, 0x2021,
+	0x7600, 0x2009, 0x0005, 0x2011, 0x0020, 0x1078, 0x29a0, 0x0040,
+	0x2966, 0x157e, 0x20a9, 0x0000, 0x2021, 0x7500, 0x047e, 0x2009,
+	0x0005, 0x2011, 0x0020, 0x1078, 0x29a0, 0x047f, 0x0040, 0x2965,
+	0x8420, 0x0070, 0x2965, 0x0078, 0x2956, 0x157f, 0x0078, 0x2523,
+	0x2200, 0x0079, 0x296b, 0x296e, 0x2970, 0x2970, 0x1078, 0x248c,
+	0x2009, 0x0012, 0x706c, 0xa086, 0x0002, 0x0040, 0x2979, 0x2009,
+	0x000e, 0x6818, 0xa084, 0x8000, 0x0040, 0x297f, 0x691a, 0x706f,
+	0x0000, 0x7073, 0x0001, 0x0078, 0x3956, 0x2200, 0x0079, 0x2988,
+	0x298d, 0x2970, 0x298b, 0x1078, 0x248c, 0x1078, 0x4887, 0x7000,
+	0xa086, 0x0001, 0x00c0, 0x3467, 0x1078, 0x34b8, 0x6008, 0xa084,
+	0xffef, 0x600a, 0x1078, 0x345a, 0x0040, 0x3467, 0x0078, 0x2635,
+	0x2404, 0xa005, 0x0040, 0x29c3, 0x2068, 0x2d04, 0x007e, 0x6814,
+	0xa706, 0x0040, 0x29af, 0x2d20, 0x007f, 0x0078, 0x29a1, 0x007f,
+	0x2022, 0x691a, 0x6817, 0x0000, 0x6820, 0xa205, 0x6822, 0x1078,
+	0x1cdc, 0x6010, 0x8001, 0x6012, 0x6008, 0xa084, 0xffef, 0x600a,
+	0x1078, 0x34b8, 0x007c, 0xa085, 0x0001, 0x0078, 0x29c2, 0x2300,
+	0x0079, 0x29ca, 0x29cf, 0x29cd, 0x2a68, 0x1078, 0x248c, 0x78ec,
+	0xa084, 0x0001, 0x00c0, 0x29e3, 0x7000, 0xa086, 0x0004, 0x00c0,
+	0x29db, 0x0078, 0x2a06, 0x1078, 0x34b8, 0x6008, 0xa084, 0xffef,
+	0x600a, 0x0078, 0x3467, 0x78e4, 0xa005, 0x00d0, 0x2a06, 0x0018,
+	0x24fa, 0x2008, 0xa084, 0x0030, 0x00c0, 0x29f2, 0x781b, 0x004f,
+	0x0078, 0x24fa, 0x78ec, 0xa084, 0x0003, 0x0040, 0x29ee, 0x2100,
+	0xa084, 0x0007, 0x0079, 0x29fc, 0x2a3f, 0x2a4a, 0x2a30, 0x2a04,
+	0x39bb, 0x39bb, 0x2a04, 0x2a59, 0x1078, 0x248c, 0x7000, 0xa086,
+	0x0004, 0x00c0, 0x2a20, 0x706c, 0xa086, 0x0002, 0x00c0, 0x2a16,
+	0x2011, 0x0002, 0x2019, 0x0000, 0x0078, 0x28e9, 0x706c, 0xa086,
+	0x0006, 0x0040, 0x2a10, 0x706c, 0xa086, 0x0004, 0x0040, 0x2a10,
+	0x79e4, 0xa184, 0x0030, 0x0040, 0x2a2a, 0x78ec, 0xa084, 0x0003,
+	0x00c0, 0x2a2c, 0x0078, 0x300c, 0x2001, 0x0003, 0x0078, 0x2da0,
+	0x6818, 0xa084, 0x8000, 0x0040, 0x2a37, 0x681b, 0x001d, 0x1078,
+	0x378f, 0x782b, 0x3008, 0x781b, 0x0056, 0x0078, 0x24fa, 0x6818,
+	0xa084, 0x8000, 0x0040, 0x2a46, 0x681b, 0x001d, 0x1078, 0x378f,
+	0x0078, 0x3986, 0x6818, 0xa084, 0x8000, 0x0040, 0x2a51, 0x681b,
+	0x001d, 0x1078, 0x378f, 0x782b, 0x3008, 0x781b, 0x00ca, 0x0078,
+	0x24fa, 0x6818, 0xa084, 0x8000, 0x0040, 0x2a60, 0x681b, 0x001d,
+	0x1078, 0x378f, 0x782b, 0x3008, 0x781b, 0x008f, 0x0078, 0x24fa,
+	0xa584, 0x000f, 0x00c0, 0x2a85, 0x7000, 0x0079, 0x2a6f, 0x2523,
+	0x2a79, 0x2a77, 0x3467, 0x3467, 0x3467, 0x3467, 0x2a77, 0x1078,
+	0x248c, 0x1078, 0x34b8, 0x6008, 0xa084, 0xffef, 0x600a, 0x1078,
+	0x345a, 0x0040, 0x3467, 0x0078, 0x2635, 0x78e4, 0xa005, 0x00d0,
+	0x2a06, 0x0018, 0x2a06, 0x2008, 0xa084, 0x0030, 0x00c0, 0x2a94,
+	0x781b, 0x004f, 0x0078, 0x24fa, 0x78ec, 0xa084, 0x0003, 0x0040,
+	0x2a90, 0x2100, 0xa184, 0x0007, 0x0079, 0x2a9e, 0x2ab0, 0x2ab4,
+	0x2aa8, 0x2aa6, 0x39bb, 0x39bb, 0x2aa6, 0x39b1, 0x1078, 0x248c,
+	0x1078, 0x3797, 0x782b, 0x3008, 0x781b, 0x0056, 0x0078, 0x24fa,
+	0x1078, 0x3797, 0x0078, 0x3986, 0x1078, 0x3797, 0x782b, 0x3008,
+	0x781b, 0x00ca, 0x0078, 0x24fa, 0x1078, 0x3797, 0x782b, 0x3008,
+	0x781b, 0x008f, 0x0078, 0x24fa, 0x2300, 0x0079, 0x2ac7, 0x2acc,
+	0x2aca, 0x2ace, 0x1078, 0x248c, 0x0078, 0x3180, 0x681b, 0x0008,
+	0x78a3, 0x0000, 0x79e4, 0xa184, 0x0030, 0x0040, 0x3180, 0x78ec,
+	0xa084, 0x0003, 0x0040, 0x3180, 0xa184, 0x0007, 0x0079, 0x2ae0,
+	0x2ae8, 0x2ab4, 0x2a30, 0x3956, 0x39bb, 0x39bb, 0x2ae8, 0x39b1,
+	0x1078, 0x396a, 0x0078, 0x24fa, 0xa282, 0x0005, 0x0050, 0x2af2,
+	0x1078, 0x248c, 0x2300, 0x0079, 0x2af5, 0x2af8, 0x2d4d, 0x2d5b,
+	0x2200, 0x0079, 0x2afb, 0x2b15, 0x2b02, 0x2b15, 0x2b00, 0x2d32,
+	0x1078, 0x248c, 0x789b, 0x0018, 0x78a8, 0xa084, 0x00ff, 0xa082,
+	0x0020, 0x0048, 0x376b, 0xa08a, 0x0004, 0x00c8, 0x376b, 0x0079,
+	0x2b11, 0x376b, 0x376b, 0x376b, 0x3719, 0x789b, 0x0018, 0x79a8,
+	0xa184, 0x0080, 0x0040, 0x2b26, 0x0078, 0x376b, 0x7000, 0xa005,
+	0x00c0, 0x2b1c, 0x2011, 0x0004, 0x0078, 0x32e9, 0xa184, 0x00ff,
+	0xa08a, 0x0010, 0x00c8, 0x376b, 0x0079, 0x2b2e, 0x2b40, 0x2b3e,
+	0x2b58, 0x2b5c, 0x2c17, 0x376b, 0x376b, 0x2c19, 0x376b, 0x376b,
+	0x2d2e, 0x2d2e, 0x376b, 0x376b, 0x376b, 0x2d30, 0x1078, 0x248c,
+	0xa684, 0x1000, 0x0040, 0x2b4d, 0x2001, 0x0500, 0x8000, 0x8000,
+	0x783a, 0x781b, 0x008d, 0x0078, 0x24fa, 0x6818, 0xa084, 0x8000,
+	0x0040, 0x2b56, 0x681b, 0x001d, 0x0078, 0x2b44, 0x0078, 0x3956,
+	0x681b, 0x001d, 0x0078, 0x377b, 0x6920, 0x6922, 0xa684, 0x1800,
+	0x00c0, 0x2b9d, 0x6820, 0xa084, 0x0001, 0x00c0, 0x2ba5, 0x6818,
+	0xa086, 0x0008, 0x00c0, 0x2b6e, 0x681b, 0x0000, 0xa684, 0x0400,
+	0x0040, 0x2c13, 0xa684, 0x0080, 0x0040, 0x2b99, 0x7097, 0x0000,
+	0x6818, 0xa084, 0x003f, 0xa08a, 0x000d, 0x0050, 0x2b99, 0xa08a,
+	0x000c, 0x7196, 0x2001, 0x000c, 0x800c, 0x719a, 0x789b, 0x0061,
+	0x78aa, 0x157e, 0x137e, 0x147e, 0x20a1, 0x012b, 0x789b, 0x0000,
+	0x8000, 0x80ac, 0xad80, 0x000b, 0x2098, 0x53a6, 0x147f, 0x137f,
+	0x157f, 0x781b, 0x0058, 0x0078, 0x24fa, 0xa684, 0x1000, 0x0040,
+	0x2ba5, 0x781b, 0x0065, 0x0078, 0x24fa, 0xa684, 0x0060, 0x0040,
+	0x2c0f, 0xa684, 0x0800, 0x0040, 0x2c0f, 0xa684, 0x8000, 0x00c0,
+	0x2bb3, 0x0078, 0x2bcb, 0xa6b4, 0x7fff, 0x7e5a, 0x6eb6, 0x7adc,
+	0x79d8, 0x78d0, 0x801b, 0x00c8, 0x2bbe, 0x8000, 0xa084, 0x003f,
+	0xa108, 0xa291, 0x0000, 0x6b98, 0x2100, 0xa302, 0x68b2, 0x6b94,
+	0x2200, 0xa303, 0x68ae, 0xa684, 0x4000, 0x0040, 0x2bd3, 0xa6b4,
+	0xbfff, 0x7e5a, 0x6eb6, 0x7000, 0xa086, 0x0003, 0x00c0, 0x2be0,
+	0x1078, 0x493d, 0x1078, 0x4b3a, 0x781b, 0x0064, 0x0078, 0x24fa,
+	0xa006, 0x1078, 0x4c41, 0x6ab0, 0x69ac, 0x6c98, 0x6b94, 0x2200,
+	0xa105, 0x0040, 0x2bef, 0x2200, 0xa422, 0x2100, 0xa31b, 0x6caa,
+	0x7cd2, 0x7cda, 0x6ba6, 0x7bd6, 0x7bde, 0x2300, 0xa405, 0x00c0,
+	0x2c01, 0xa6b5, 0x4000, 0x7e5a, 0x6eb6, 0x781b, 0x0064, 0x0078,
+	0x24fa, 0x781b, 0x0064, 0x2200, 0xa115, 0x00c0, 0x2c0b, 0x1078,
+	0x4b4b, 0x0078, 0x24fa, 0x1078, 0x4b96, 0x0078, 0x24fa, 0x781b,
+	0x0065, 0x0078, 0x24fa, 0x781b, 0x0058, 0x0078, 0x24fa, 0x1078,
+	0x248c, 0x0078, 0x2c7a, 0x6920, 0xa184, 0x0100, 0x0040, 0x2c31,
+	0xa18c, 0xfeff, 0x6922, 0x0c7e, 0x7054, 0x2060, 0x6000, 0xa084,
+	0xefff, 0x6002, 0x6004, 0xa084, 0xfff5, 0x6006, 0x0c7f, 0x0078,
+	0x2c69, 0xa184, 0x0200, 0x0040, 0x2c69, 0xa18c, 0xfdff, 0x6922,
+	0x0c7e, 0x7054, 0x2060, 0x6000, 0xa084, 0xdfff, 0x6002, 0x6004,
+	0xa084, 0xffef, 0x6006, 0x2008, 0x2c48, 0x0c7f, 0xa184, 0x0008,
+	0x0040, 0x2c69, 0x1078, 0x38b9, 0x1078, 0x35bb, 0x88ff, 0x0040,
+	0x2c69, 0x789b, 0x0060, 0x2800, 0x78aa, 0x7e58, 0xa6b5, 0x0004,
+	0x7e5a, 0xa684, 0x0400, 0x00c0, 0x2c63, 0x782b, 0x3008, 0x781b,
+	0x0056, 0x0078, 0x24fa, 0x782b, 0x3008, 0x781b, 0x0065, 0x0078,
+	0x24fa, 0x7e58, 0xa684, 0x0400, 0x00c0, 0x2c72, 0x781b, 0x0058,
+	0x0078, 0x24fa, 0x781b, 0x0065, 0x0078, 0x24fa, 0x0078, 0x3773,
+	0x0078, 0x3773, 0x2019, 0x0000, 0x7990, 0xa18c, 0x0007, 0x00c0,
+	0x2c88, 0x6820, 0xa084, 0x0100, 0x0040, 0x2c78, 0x2009, 0x0008,
+	0x789b, 0x0010, 0x78a8, 0xa094, 0x00ff, 0xa286, 0x0001, 0x00c0,
+	0x2cbf, 0x2300, 0x7ca8, 0xa400, 0x2018, 0xa102, 0x0040, 0x2cb7,
+	0x0048, 0x2c9c, 0x0078, 0x2cb9, 0xa380, 0x0002, 0xa102, 0x00c8,
+	0x2cb7, 0x6920, 0xa18c, 0xfcff, 0x6922, 0x0c7e, 0x7054, 0x2060,
+	0x6000, 0xa084, 0xefef, 0x6002, 0x6004, 0xa084, 0xffe5, 0x6006,
+	0x0c7f, 0x7e58, 0xa6b4, 0xfffb, 0x7e5a, 0x0078, 0x2c6a, 0x0078,
+	0x2c1b, 0x24a8, 0x7aa8, 0x00f0, 0x2cb9, 0x0078, 0x2c8a, 0xa284,
+	0x00f0, 0xa086, 0x0020, 0x00c0, 0x2d1f, 0x8318, 0x8318, 0x2300,
+	0xa102, 0x0040, 0x2ccf, 0x0048, 0x2ccf, 0x0078, 0x2d1c, 0xa286,
+	0x0023, 0x0040, 0x2c78, 0x681c, 0xa084, 0xfff1, 0x681e, 0x7e58,
+	0xa684, 0xfff1, 0xa085, 0x0010, 0x2030, 0x7e5a, 0x6008, 0xa085,
+	0x0010, 0x600a, 0x0c7e, 0x7054, 0x2060, 0x6004, 0x2008, 0x2c48,
+	0x0c7f, 0xa184, 0x0010, 0x0040, 0x2cf3, 0x1078, 0x38b9, 0x1078,
+	0x36d0, 0x0078, 0x2d02, 0x0c7e, 0x7054, 0x2060, 0x6004, 0x2008,
+	0x2c48, 0x0c7f, 0xa184, 0x0008, 0x0040, 0x2c69, 0x1078, 0x38b9,
+	0x1078, 0x35bb, 0x88ff, 0x0040, 0x2c69, 0x789b, 0x0060, 0x2800,
+	0x78aa, 0xa6b5, 0x0004, 0x7e5a, 0xa684, 0x0400, 0x00c0, 0x2d16,
+	0x782b, 0x3008, 0x781b, 0x0056, 0x0078, 0x24fa, 0x782b, 0x3008,
+	0x781b, 0x0065, 0x0078, 0x24fa, 0x7aa8, 0x0078, 0x2c8a, 0x8318,
+	0x2300, 0xa102, 0x0040, 0x2d28, 0x0048, 0x2d28, 0x0078, 0x2c8a,
+	0xa284, 0x0080, 0x00c0, 0x377b, 0x0078, 0x3773, 0x0078, 0x377b,
+	0x0078, 0x376b, 0x789b, 0x0018, 0x78a8, 0xa084, 0x00ff, 0xa08e,
+	0x0001, 0x0040, 0x2d3d, 0x1078, 0x248c, 0x7aa8, 0xa294, 0x00ff,
+	0x78a8, 0xa084, 0x00ff, 0xa08a, 0x0004, 0x00c8, 0x376b, 0x0079,
+	0x2d49, 0x376b, 0x3508, 0x376b, 0x3665, 0xa282, 0x0000, 0x00c0,
+	0x2d53, 0x1078, 0x248c, 0x1078, 0x378f, 0x782b, 0x3008, 0x781b,
+	0x0065, 0x0078, 0x24fa, 0xa282, 0x0003, 0x00c0, 0x2d61, 0x1078,
+	0x248c, 0xa484, 0x8000, 0x00c0, 0x2d84, 0x706c, 0xa005, 0x0040,
+	0x2d6b, 0x1078, 0x248c, 0x6f14, 0x7782, 0xa7bc, 0x0f00, 0x1078,
+	0x38bd, 0x6008, 0xa085, 0x0021, 0x600a, 0x8738, 0xa784, 0x001f,
+	0x00c0, 0x2d6f, 0x1078, 0x3793, 0x706f, 0x0002, 0x2009, 0x5238,
+	0x200b, 0x0009, 0x0078, 0x2d86, 0x1078, 0x379f, 0x782b, 0x3008,
+	0x781b, 0x0065, 0x0078, 0x24fa, 0xa282, 0x0004, 0x0050, 0x2d92,
+	0x1078, 0x248c, 0x2300, 0x0079, 0x2d95, 0x2d98, 0x2e81, 0x2eb4,
+	0xa286, 0x0003, 0x0040, 0x2d9e, 0x1078, 0x248c, 0x2001, 0x0000,
+	0x007e, 0x68c0, 0xa005, 0x0040, 0x2da7, 0x7003, 0x0003, 0x68a0,
+	0xa084, 0x2000, 0x0040, 0x2db0, 0x6008, 0xa085, 0x0002, 0x600a,
+	0x007f, 0x703e, 0x7000, 0xa084, 0x0007, 0x0079, 0x2db7, 0x2523,
+	0x2dc1, 0x2dc1, 0x2fb6, 0x2ff2, 0x2523, 0x2ff2, 0x2dbf, 0x1078,
+	0x248c, 0xa684, 0x1000, 0x00c0, 0x2dc9, 0x1078, 0x4887, 0x0040,
+	0x2e5b, 0x7868, 0xa08c, 0x00ff, 0x0040, 0x2e11, 0xa186, 0x0008,
+	0x00c0, 0x2de0, 0x1078, 0x34b8, 0x6008, 0xa084, 0xffef, 0x600a,
+	0x1078, 0x345a, 0x0040, 0x2e11, 0x1078, 0x4887, 0x0078, 0x2df8,
+	0xa186, 0x0028, 0x00c0, 0x2e11, 0x1078, 0x4887, 0x6008, 0xa084,
+	0xffef, 0x600a, 0x6018, 0xa005, 0x0040, 0x2df8, 0x8001, 0x601a,
+	0xa005, 0x0040, 0x2df8, 0x8001, 0xa005, 0x0040, 0x2df8, 0x601e,
+	0x6820, 0xa084, 0x0001, 0x0040, 0x2523, 0x6820, 0xa084, 0xfffe,
+	0x6822, 0x7060, 0x0c7e, 0x2060, 0x6800, 0x6002, 0x0c7f, 0x6004,
+	0x6802, 0xa005, 0x2d00, 0x00c0, 0x2e0e, 0x6002, 0x6006, 0x0078,
+	0x2523, 0x017e, 0x1078, 0x2ee5, 0x017f, 0xa684, 0xdf00, 0x681e,
+	0x682b, 0x0000, 0x6f14, 0x81ff, 0x0040, 0x2e5b, 0xa186, 0x0002,
+	0x00c0, 0x2e5b, 0xa684, 0x0800, 0x00c0, 0x2e2e, 0xa684, 0x0060,
+	0x0040, 0x2e2e, 0x78d8, 0x7adc, 0x682e, 0x6a32, 0x6820, 0xa084,
+	0x0800, 0x00c0, 0x2e5b, 0x8717, 0xa294, 0x000f, 0x8213, 0x8213,
+	0x8213, 0xa290, 0x5480, 0xa290, 0x0000, 0x221c, 0xa384, 0x0100,
+	0x00c0, 0x2e44, 0x0078, 0x2e4a, 0x8210, 0x2204, 0xa085, 0x0018,
+	0x2012, 0x8211, 0xa384, 0x0400, 0x0040, 0x2e57, 0x68a0, 0xa084,
+	0x0100, 0x00c0, 0x2e57, 0x1078, 0x2f69, 0x0078, 0x2523, 0x6008,
+	0xa085, 0x0002, 0x600a, 0x6916, 0x6818, 0xa084, 0x8000, 0x0040,
+	0x2e63, 0x703c, 0x681a, 0xa68c, 0xdf00, 0x691e, 0x1078, 0x34a9,
+	0x1078, 0x34b8, 0x00c0, 0x2e70, 0x6008, 0xa084, 0xffef, 0x600a,
+	0x6820, 0xa084, 0x0001, 0x00c0, 0x2e79, 0x1078, 0x34a2, 0x0078,
+	0x2e7d, 0x7060, 0x2060, 0x6800, 0x6002, 0x1078, 0x1cdc, 0x0078,
+	0x2523, 0xa282, 0x0004, 0x0048, 0x2e87, 0x1078, 0x248c, 0x2200,
+	0x0079, 0x2e8a, 0x2e85, 0x2e8e, 0x2e9b, 0x2e8e, 0x7000, 0xa086,
+	0x0005, 0x0040, 0x2e97, 0x1078, 0x378f, 0x782b, 0x3008, 0x781b,
+	0x0065, 0x0078, 0x24fa, 0x7890, 0x8007, 0x8001, 0xa084, 0x0007,
+	0xa080, 0x0018, 0x789a, 0x79a8, 0xa18c, 0x00ff, 0xa186, 0x0003,
+	0x0040, 0x2eb0, 0xa186, 0x0000, 0x0040, 0x2eb0, 0x0078, 0x376b,
+	0x781b, 0x0065, 0x0078, 0x24fa, 0x6820, 0xa085, 0x0004, 0x6822,
+	0x82ff, 0x00c0, 0x2ebf, 0x1078, 0x378f, 0x0078, 0x2ec6, 0x8211,
+	0x0040, 0x2ec4, 0x1078, 0x248c, 0x1078, 0x379f, 0x782b, 0x3008,
+	0x781b, 0x0065, 0x0078, 0x24fa, 0x702c, 0x8003, 0x0048, 0x2ed6,
+	0x2019, 0x4eaf, 0x1078, 0x2313, 0x702f, 0x8000, 0x1078, 0x39e0,
+	0x7830, 0xa084, 0x00c0, 0x00c0, 0x2ee2, 0x0018, 0x2ee2, 0x791a,
+	0xa006, 0x007c, 0xa085, 0x0001, 0x007c, 0xa684, 0x0060, 0x00c0,
+	0x2eef, 0x682f, 0x0000, 0x6833, 0x0000, 0x0078, 0x2f68, 0xa684,
+	0x0800, 0x00c0, 0x2f11, 0x68b4, 0xa084, 0x4800, 0xa635, 0xa684,
+	0x0800, 0x00c0, 0x2f11, 0x6998, 0x6a94, 0x692e, 0x6a32, 0x703c,
+	0xa005, 0x00c0, 0x2f09, 0x2200, 0xa105, 0x0040, 0x2f10, 0x703f,
+	0x0015, 0x7000, 0xa086, 0x0006, 0x0040, 0x2f10, 0x1078, 0x4887,
+	0x007c, 0xa684, 0x0020, 0x0040, 0x2f33, 0xa684, 0x4000, 0x0040,
+	0x2f1f, 0x682f, 0x0000, 0x6833, 0x0000, 0x0078, 0x2f09, 0x68b4,
+	0xa084, 0x4800, 0xa635, 0xa684, 0x4000, 0x00c0, 0x2f19, 0x703c,
+	0xa005, 0x00c0, 0x2f2d, 0x703f, 0x0015, 0x79d8, 0x7adc, 0x692e,
+	0x6a32, 0x0078, 0x2f09, 0xa684, 0x4000, 0x0040, 0x2f3d, 0x682f,
+	0x0000, 0x6833, 0x0000, 0x0078, 0x2f09, 0x68b4, 0xa084, 0x4800,
+	0xa635, 0xa684, 0x4000, 0x00c0, 0x2f37, 0x703c, 0xa005, 0x00c0,
+	0x2f4b, 0x703f, 0x0015, 0x79d8, 0x7adc, 0x78d0, 0x80fb, 0x00c8,
+	0x2f52, 0x8000, 0xa084, 0x003f, 0xa108, 0xa291, 0x0000, 0x692e,
+	0x6a32, 0x2100, 0xa205, 0x00c0, 0x2f5f, 0x0078, 0x2f09, 0x7000,
+	0xa086, 0x0006, 0x0040, 0x2f68, 0x1078, 0x4c41, 0x0078, 0x2f09,
+	0x007c, 0x6008, 0xa085, 0x0200, 0x600a, 0xa384, 0x0200, 0x0040,
+	0x2f75, 0x6008, 0xa085, 0x0002, 0x600a, 0x681b, 0x0006, 0x688f,
+	0x0000, 0x6893, 0x0000, 0x6a30, 0x692c, 0x6a3e, 0x6942, 0x682f,
+	0x0003, 0x6833, 0x0000, 0x6837, 0x0020, 0x6897, 0x0000, 0x689b,
+	0x0020, 0x68b3, 0x0000, 0x68af, 0x0000, 0x7000, 0x0079, 0x2f90,
+	0x2523, 0x2f9a, 0x2fa3, 0x2f98, 0x2f98, 0x2f98, 0x2f98, 0x2f98,
+	0x1078, 0x248c, 0x6820, 0xa084, 0x0001, 0x00c0, 0x2fa3, 0x1078,
+	0x34a2, 0x0078, 0x2fa9, 0x7060, 0x2c50, 0x2060, 0x6800, 0x6002,
+	0x2a60, 0x2021, 0x525a, 0x2404, 0xa005, 0x0040, 0x2fb2, 0x2020,
+	0x0078, 0x2fab, 0x2d22, 0x206b, 0x0000, 0x007c, 0x1078, 0x34a9,
+	0x1078, 0x34b8, 0x6008, 0xa084, 0xfdff, 0x600a, 0x682b, 0x0000,
+	0x789b, 0x000e, 0x6f14, 0x6817, 0x0002, 0x1078, 0x4c89, 0xa684,
+	0x0800, 0x0040, 0x2fcf, 0x691c, 0xa18d, 0x2000, 0x691e, 0x6818,
+	0xa084, 0x8000, 0x0040, 0x2fdf, 0x7868, 0xa08c, 0x00ff, 0x0040,
+	0x2fdd, 0x681b, 0x001e, 0x0078, 0x2fdf, 0x681b, 0x0000, 0x2021,
+	0x525a, 0x2404, 0xad06, 0x0040, 0x2fe6, 0x7460, 0x6800, 0x2022,
+	0x68c3, 0x0000, 0x6a3c, 0x6940, 0x6a32, 0x692e, 0x1078, 0x1cdc,
+	0x0078, 0x2523, 0x1078, 0x2ee5, 0x682b, 0x0000, 0x2001, 0x000e,
+	0x6f14, 0x1078, 0x39e6, 0xa08c, 0x00ff, 0x6916, 0x6818, 0xa084,
+	0x8000, 0x0040, 0x3005, 0x703c, 0x681a, 0xa68c, 0xdf00, 0x691e,
+	0x706f, 0x0000, 0x0078, 0x2523, 0x7000, 0xa005, 0x00c0, 0x3012,
+	0x0078, 0x2523, 0xa006, 0x1078, 0x4887, 0x6817, 0x0000, 0x681b,
+	0x0014, 0xa68c, 0xdf00, 0x691e, 0x682b, 0x0000, 0x6820, 0xa085,
+	0x00ff, 0x6822, 0x7000, 0x0079, 0x3025, 0x2523, 0x302f, 0x302f,
+	0x3031, 0x3031, 0x3031, 0x3031, 0x302d, 0x1078, 0x248c, 0x1078,
+	0x34b8, 0x6008, 0xa084, 0xffef, 0x600a, 0x0078, 0x3472, 0x2300,
+	0x0079, 0x303a, 0x303d, 0x303f, 0x3098, 0x1078, 0x248c, 0xa684,
+	0x8000, 0x00c0, 0x307d, 0x7000, 0x0079, 0x3046, 0x2523, 0x3050,
+	0x3050, 0x306c, 0x3050, 0x3079, 0x306c, 0x304e, 0x1078, 0x248c,
+	0xa684, 0x0060, 0xa086, 0x0060, 0x00c0, 0x3068, 0xa6b4, 0xffdf,
+	0xa6b4, 0xbfff, 0xa6b5, 0x2000, 0x7e5a, 0x6eb6, 0x681c, 0xa084,
+	0xffdf, 0x681e, 0x1078, 0x4887, 0x1078, 0x4b4b, 0x0078, 0x3956,
+	0xa684, 0x2000, 0x0040, 0x305a, 0x6818, 0xa084, 0x8000, 0x0040,
+	0x3079, 0x681b, 0x0015, 0xa684, 0x4000, 0x0040, 0x3079, 0x681b,
+	0x0007, 0x1078, 0x396a, 0x0078, 0x24fa, 0xa6b4, 0x7fff, 0x7e5a,
+	0x7adc, 0x79d8, 0x78d0, 0x79d2, 0x801b, 0x00c8, 0x3088, 0x8000,
+	0xa084, 0x003f, 0xa108, 0xa291, 0x0000, 0x6b98, 0x2100, 0xa302,
+	0x68b2, 0x6b94, 0x2200, 0xa303, 0x68ae, 0x781b, 0x0065, 0x007c,
+	0x1078, 0x248c, 0x2300, 0x0079, 0x309d, 0x30a0, 0x30a2, 0x30eb,
+	0x1078, 0x248c, 0xa684, 0x8000, 0x00c0, 0x30da, 0x7000, 0x0079,
+	0x30a9, 0x2523, 0x30b3, 0x30b3, 0x30cf, 0x30b3, 0x30d6, 0x30cf,
+	0x30b1, 0x1078, 0x248c, 0xa684, 0x0060, 0xa086, 0x0060, 0x00c0,
+	0x30cb, 0xa6b4, 0xffbf, 0xa6b4, 0xbfff, 0xa6b5, 0x2000, 0x7e5a,
+	0x6eb6, 0x681c, 0xa084, 0xffbf, 0x681e, 0x1078, 0x4887, 0x1078,
+	0x4b4b, 0x0078, 0x3956, 0xa684, 0x2000, 0x0040, 0x30bd, 0x6818,
+	0xa084, 0x8000, 0x0040, 0x30d6, 0x681b, 0x0007, 0x781b, 0x00ca,
+	0x0078, 0x24fa, 0xa6b4, 0x7fff, 0x7e5a, 0x7adc, 0x79d8, 0x6b98,
+	0x2100, 0xa302, 0x68b2, 0x6b94, 0x2200, 0xa303, 0x68ae, 0x79d2,
+	0x781b, 0x0065, 0x007c, 0x6820, 0xa085, 0x0004, 0x6822, 0x1078,
+	0x3921, 0xa6b5, 0x0800, 0x1078, 0x378f, 0x782b, 0x3008, 0x781b,
+	0x0065, 0x0078, 0x24fa, 0x2300, 0x0079, 0x30fe, 0x3101, 0x3103,
+	0x3105, 0x1078, 0x248c, 0x0078, 0x377b, 0xa684, 0x0400, 0x00c0,
+	0x312e, 0x79e4, 0xa184, 0x0020, 0x0040, 0x3115, 0x78ec, 0xa084,
+	0x0003, 0x0040, 0x3115, 0x782b, 0x3009, 0x789b, 0x0060, 0x78ab,
+	0x0000, 0xa684, 0xfffb, 0x785a, 0x79e4, 0xa184, 0x0020, 0x0040,
+	0x3126, 0x78ec, 0xa084, 0x0003, 0x00c0, 0x312a, 0x2001, 0x0014,
+	0x0078, 0x2da0, 0xa184, 0x0007, 0x0079, 0x3166, 0x7a90, 0xa294,
+	0x0007, 0x789b, 0x0060, 0x79a8, 0x81ff, 0x0040, 0x3164, 0x789b,
+	0x0010, 0x7ba8, 0xa384, 0x0001, 0x00c0, 0x3155, 0x7ba8, 0x7ba8,
+	0xa386, 0x0001, 0x00c0, 0x3148, 0x2009, 0xfff7, 0x0078, 0x314e,
+	0xa386, 0x0003, 0x00c0, 0x3155, 0x2009, 0xffef, 0x0c7e, 0x7054,
+	0x2060, 0x6004, 0xa104, 0x6006, 0x0c7f, 0x789b, 0x0060, 0x78ab,
+	0x0000, 0xa684, 0xfffb, 0x785a, 0x782b, 0x3009, 0x6920, 0xa18c,
+	0xfdff, 0xa18c, 0xfeff, 0x6922, 0x0078, 0x3956, 0x2a3f, 0x2a4a,
+	0x3170, 0x3178, 0x316e, 0x316e, 0x3956, 0x3956, 0x1078, 0x248c,
+	0x6920, 0xa18c, 0xfdff, 0xa18c, 0xfeff, 0x6922, 0x0078, 0x3960,
+	0x6920, 0xa18c, 0xfdff, 0xa18c, 0xfeff, 0x6922, 0x0078, 0x3956,
+	0x79e4, 0xa184, 0x0030, 0x0040, 0x318a, 0x78ec, 0xa084, 0x0003,
+	0x00c0, 0x31b1, 0x7000, 0xa086, 0x0004, 0x00c0, 0x31a4, 0x706c,
+	0xa086, 0x0002, 0x00c0, 0x319a, 0x2011, 0x0002, 0x2019, 0x0000,
+	0x0078, 0x28e9, 0x706c, 0xa086, 0x0006, 0x0040, 0x3194, 0x706c,
+	0xa086, 0x0004, 0x0040, 0x3194, 0x7000, 0xa086, 0x0000, 0x0040,
+	0x24fa, 0x6818, 0xa085, 0x8000, 0x681a, 0x2001, 0x0014, 0x0078,
+	0x2da0, 0xa184, 0x0007, 0x0079, 0x31b5, 0x3956, 0x3956, 0x31bd,
+	0x3956, 0x39bb, 0x39bb, 0x3956, 0x3956, 0xa684, 0x0080, 0x0040,
+	0x31ec, 0x7194, 0x81ff, 0x0040, 0x31ec, 0xa182, 0x000d, 0x00d0,
+	0x31cd, 0x7097, 0x0000, 0x0078, 0x31d2, 0xa182, 0x000c, 0x7096,
+	0x2009, 0x000c, 0x789b, 0x0061, 0x79aa, 0x157e, 0x137e, 0x147e,
+	0x7098, 0x8114, 0xa210, 0x729a, 0xa080, 0x000b, 0xad00, 0x2098,
+	0x20a1, 0x012b, 0x789b, 0x0000, 0x8108, 0x81ac, 0x53a6, 0x147f,
+	0x137f, 0x157f, 0x0078, 0x3960, 0xa684, 0x0400, 0x00c0, 0x322d,
+	0x6820, 0xa084, 0x0001, 0x0040, 0x3960, 0xa68c, 0x0060, 0xa684,
+	0x0060, 0x0040, 0x3201, 0xa086, 0x0060, 0x00c0, 0x3201, 0xa18d,
+	0x4000, 0xa18c, 0xfffb, 0x795a, 0x69b6, 0x789b, 0x0060, 0x78ab,
+	0x0000, 0x789b, 0x0061, 0x6818, 0xa085, 0x8000, 0x681a, 0x78aa,
+	0x8008, 0x810c, 0x0040, 0x34d1, 0xa18c, 0x00f8, 0x00c0, 0x34d1,
 	0x157e, 0x137e, 0x147e, 0x20a1, 0x012b, 0x789b, 0x0000, 0x8000,
 	0x80ac, 0xad80, 0x000b, 0x2098, 0x53a6, 0x147f, 0x137f, 0x157f,
-	0x781b, 0x0058, 0x0078, 0x2459, 0xa684, 0x1000, 0x0040, 0x2b04,
-	0x781b, 0x0065, 0x0078, 0x2459, 0xa684, 0x0060, 0x0040, 0x2b70,
-	0xa684, 0x0800, 0x0040, 0x2b70, 0xa684, 0x8000, 0x00c0, 0x2b12,
-	0x0078, 0x2b2c, 0xa6b4, 0x7fff, 0x7e5a, 0x6eb6, 0x789b, 0x0076,
-	0x7aac, 0x79ac, 0x78ac, 0x801b, 0x00c8, 0x2b1f, 0x8000, 0xa084,
-	0x003f, 0xa108, 0xa291, 0x0000, 0x6b98, 0x2100, 0xa302, 0x68b2,
-	0x6b94, 0x2200, 0xa303, 0x68ae, 0xa684, 0x4000, 0x0040, 0x2b34,
-	0xa6b4, 0xbfff, 0x7e5a, 0x6eb6, 0x7000, 0xa086, 0x0003, 0x00c0,
-	0x2b41, 0x1078, 0x482c, 0x1078, 0x4a29, 0x781b, 0x0064, 0x0078,
-	0x2459, 0xa006, 0x1078, 0x4b30, 0x6ab0, 0x69ac, 0x6c98, 0x6b94,
-	0x2200, 0xa105, 0x0040, 0x2b50, 0x2200, 0xa422, 0x2100, 0xa31b,
-	0x6caa, 0x7cd2, 0x7cda, 0x6ba6, 0x7bd6, 0x7bde, 0x2300, 0xa405,
-	0x00c0, 0x2b62, 0xa6b5, 0x4000, 0x7e5a, 0x6eb6, 0x781b, 0x0064,
-	0x0078, 0x2459, 0x781b, 0x0064, 0x2200, 0xa115, 0x00c0, 0x2b6c,
-	0x1078, 0x4a3a, 0x0078, 0x2459, 0x1078, 0x4a85, 0x0078, 0x2459,
-	0x781b, 0x0065, 0x0078, 0x2459, 0x781b, 0x0058, 0x0078, 0x2459,
-	0x1078, 0x23eb, 0x0078, 0x2bdb, 0x6920, 0xa184, 0x0100, 0x0040,
-	0x2b92, 0xa18c, 0xfeff, 0x6922, 0x0c7e, 0x7054, 0x2060, 0x6000,
-	0xa084, 0xefff, 0x6002, 0x6004, 0xa084, 0xfff5, 0x6006, 0x0c7f,
-	0x0078, 0x2bca, 0xa184, 0x0200, 0x0040, 0x2bca, 0xa18c, 0xfdff,
-	0x6922, 0x0c7e, 0x7054, 0x2060, 0x6000, 0xa084, 0xdfff, 0x6002,
-	0x6004, 0xa084, 0xffef, 0x6006, 0x2008, 0x2c48, 0x0c7f, 0xa184,
-	0x0008, 0x0040, 0x2bca, 0x1078, 0x37eb, 0x1078, 0x34f1, 0x88ff,
-	0x0040, 0x2bca, 0x789b, 0x0060, 0x2800, 0x78aa, 0x7e58, 0xa6b5,
-	0x0004, 0x7e5a, 0xa684, 0x0400, 0x00c0, 0x2bc4, 0x782b, 0x3008,
-	0x781b, 0x0056, 0x0078, 0x2459, 0x782b, 0x3008, 0x781b, 0x0065,
-	0x0078, 0x2459, 0x7e58, 0xa684, 0x0400, 0x00c0, 0x2bd3, 0x781b,
-	0x0058, 0x0078, 0x2459, 0x781b, 0x0065, 0x0078, 0x2459, 0x0078,
-	0x36a5, 0x0078, 0x36a5, 0x2019, 0x0000, 0x7990, 0xa18c, 0x0007,
-	0x00c0, 0x2be9, 0x6820, 0xa084, 0x0100, 0x0040, 0x2bd9, 0x2009,
-	0x0008, 0x789b, 0x0010, 0x78a8, 0xa094, 0x00ff, 0xa286, 0x0001,
-	0x00c0, 0x2c20, 0x2300, 0x7ca8, 0xa400, 0x2018, 0xa102, 0x0040,
-	0x2c18, 0x0048, 0x2bfd, 0x0078, 0x2c1a, 0xa380, 0x0002, 0xa102,
-	0x00c8, 0x2c18, 0x6920, 0xa18c, 0xfcff, 0x6922, 0x0c7e, 0x7054,
-	0x2060, 0x6000, 0xa084, 0xefef, 0x6002, 0x6004, 0xa084, 0xffe5,
-	0x6006, 0x0c7f, 0x7e58, 0xa6b4, 0xfffb, 0x7e5a, 0x0078, 0x2bcb,
-	0x0078, 0x2b7c, 0x24a8, 0x7aa8, 0x00f0, 0x2c1a, 0x0078, 0x2beb,
-	0xa284, 0x00f0, 0xa086, 0x0020, 0x00c0, 0x2c80, 0x8318, 0x8318,
-	0x2300, 0xa102, 0x0040, 0x2c30, 0x0048, 0x2c30, 0x0078, 0x2c7d,
-	0xa286, 0x0023, 0x0040, 0x2bd9, 0x681c, 0xa084, 0xfff1, 0x681e,
-	0x7e58, 0xa684, 0xfff1, 0xa085, 0x0010, 0x2030, 0x7e5a, 0x6008,
-	0xa085, 0x0010, 0x600a, 0x0c7e, 0x7054, 0x2060, 0x6004, 0x2008,
-	0x2c48, 0x0c7f, 0xa184, 0x0010, 0x0040, 0x2c54, 0x1078, 0x37eb,
-	0x1078, 0x3604, 0x0078, 0x2c63, 0x0c7e, 0x7054, 0x2060, 0x6004,
-	0x2008, 0x2c48, 0x0c7f, 0xa184, 0x0008, 0x0040, 0x2bca, 0x1078,
-	0x37eb, 0x1078, 0x34f1, 0x88ff, 0x0040, 0x2bca, 0x789b, 0x0060,
-	0x2800, 0x78aa, 0xa6b5, 0x0004, 0x7e5a, 0xa684, 0x0400, 0x00c0,
-	0x2c77, 0x782b, 0x3008, 0x781b, 0x0056, 0x0078, 0x2459, 0x782b,
-	0x3008, 0x781b, 0x0065, 0x0078, 0x2459, 0x7aa8, 0x0078, 0x2beb,
-	0x8318, 0x2300, 0xa102, 0x0040, 0x2c89, 0x0048, 0x2c89, 0x0078,
-	0x2beb, 0xa284, 0x0080, 0x00c0, 0x36ad, 0x0078, 0x36a5, 0x0078,
-	0x36ad, 0x0078, 0x369d, 0x789b, 0x0018, 0x78a8, 0xa084, 0x00ff,
-	0xa08e, 0x0001, 0x0040, 0x2c9e, 0x1078, 0x23eb, 0x7aa8, 0xa294,
-	0x00ff, 0x78a8, 0xa084, 0x00ff, 0xa08a, 0x0004, 0x00c8, 0x369d,
-	0x0079, 0x2caa, 0x369d, 0x343e, 0x369d, 0x3599, 0xa282, 0x0000,
-	0x00c0, 0x2cb4, 0x1078, 0x23eb, 0x1078, 0x36c1, 0x782b, 0x3008,
-	0x781b, 0x0065, 0x0078, 0x2459, 0xa282, 0x0003, 0x00c0, 0x2cc2,
-	0x1078, 0x23eb, 0xa484, 0x8000, 0x00c0, 0x2ce5, 0x706c, 0xa005,
-	0x0040, 0x2ccc, 0x1078, 0x23eb, 0x6f14, 0x7782, 0xa7bc, 0x0f00,
-	0x1078, 0x37ef, 0x6008, 0xa085, 0x0021, 0x600a, 0x8738, 0xa784,
-	0x001f, 0x00c0, 0x2cd0, 0x1078, 0x36c5, 0x706f, 0x0002, 0x2009,
-	0x5138, 0x200b, 0x0009, 0x0078, 0x2ce7, 0x1078, 0x36d1, 0x782b,
-	0x3008, 0x781b, 0x0065, 0x0078, 0x2459, 0xa282, 0x0004, 0x0050,
-	0x2cf3, 0x1078, 0x23eb, 0x2300, 0x0079, 0x2cf6, 0x2cf9, 0x2de2,
-	0x2e15, 0xa286, 0x0003, 0x0040, 0x2cff, 0x1078, 0x23eb, 0x2001,
-	0x0000, 0x007e, 0x68c0, 0xa005, 0x0040, 0x2d08, 0x7003, 0x0003,
-	0x68a0, 0xa084, 0x2000, 0x0040, 0x2d11, 0x6008, 0xa085, 0x0002,
-	0x600a, 0x007f, 0x703e, 0x7000, 0xa084, 0x0007, 0x0079, 0x2d18,
-	0x2482, 0x2d22, 0x2d22, 0x2f17, 0x2f53, 0x2482, 0x2f53, 0x2d20,
-	0x1078, 0x23eb, 0xa684, 0x1000, 0x00c0, 0x2d2a, 0x1078, 0x4776,
-	0x0040, 0x2dbc, 0x7868, 0xa08c, 0x00ff, 0x0040, 0x2d72, 0xa186,
-	0x0008, 0x00c0, 0x2d41, 0x1078, 0x33ee, 0x6008, 0xa084, 0xffef,
-	0x600a, 0x1078, 0x3390, 0x0040, 0x2d72, 0x1078, 0x4776, 0x0078,
-	0x2d59, 0xa186, 0x0028, 0x00c0, 0x2d72, 0x1078, 0x4776, 0x6008,
-	0xa084, 0xffef, 0x600a, 0x6018, 0xa005, 0x0040, 0x2d59, 0x8001,
-	0x601a, 0xa005, 0x0040, 0x2d59, 0x8001, 0xa005, 0x0040, 0x2d59,
-	0x601e, 0x6820, 0xa084, 0x0001, 0x0040, 0x2482, 0x6820, 0xa084,
-	0xfffe, 0x6822, 0x7060, 0x0c7e, 0x2060, 0x6800, 0x6002, 0x0c7f,
-	0x6004, 0x6802, 0xa005, 0x2d00, 0x00c0, 0x2d6f, 0x6002, 0x6006,
-	0x0078, 0x2482, 0x017e, 0x1078, 0x2e46, 0x017f, 0xa684, 0xdf00,
-	0x681e, 0x682b, 0x0000, 0x6f14, 0x81ff, 0x0040, 0x2dbc, 0xa186,
-	0x0002, 0x00c0, 0x2dbc, 0xa684, 0x0800, 0x00c0, 0x2d8f, 0xa684,
-	0x0060, 0x0040, 0x2d8f, 0x78d8, 0x7adc, 0x682e, 0x6a32, 0x6820,
-	0xa084, 0x0800, 0x00c0, 0x2dbc, 0x8717, 0xa294, 0x000f, 0x8213,
-	0x8213, 0x8213, 0xa290, 0x5380, 0xa290, 0x0000, 0x221c, 0xa384,
-	0x0100, 0x00c0, 0x2da5, 0x0078, 0x2dab, 0x8210, 0x2204, 0xa085,
-	0x0018, 0x2012, 0x8211, 0xa384, 0x0400, 0x0040, 0x2db8, 0x68a0,
-	0xa084, 0x0100, 0x00c0, 0x2db8, 0x1078, 0x2eca, 0x0078, 0x2482,
-	0x6008, 0xa085, 0x0002, 0x600a, 0x6916, 0x6818, 0xa084, 0x8000,
-	0x0040, 0x2dc4, 0x703c, 0x681a, 0xa68c, 0xdf00, 0x691e, 0x1078,
-	0x33df, 0x1078, 0x33ee, 0x00c0, 0x2dd1, 0x6008, 0xa084, 0xffef,
-	0x600a, 0x6820, 0xa084, 0x0001, 0x00c0, 0x2dda, 0x1078, 0x33d8,
-	0x0078, 0x2dde, 0x7060, 0x2060, 0x6800, 0x6002, 0x1078, 0x1c70,
-	0x0078, 0x2482, 0xa282, 0x0004, 0x0048, 0x2de8, 0x1078, 0x23eb,
-	0x2200, 0x0079, 0x2deb, 0x2de6, 0x2def, 0x2dfc, 0x2def, 0x7000,
-	0xa086, 0x0005, 0x0040, 0x2df8, 0x1078, 0x36c1, 0x782b, 0x3008,
-	0x781b, 0x0065, 0x0078, 0x2459, 0x7890, 0x8007, 0x8001, 0xa084,
-	0x0007, 0xa080, 0x0018, 0x789a, 0x79a8, 0xa18c, 0x00ff, 0xa186,
-	0x0003, 0x0040, 0x2e11, 0xa186, 0x0000, 0x0040, 0x2e11, 0x0078,
-	0x369d, 0x781b, 0x0065, 0x0078, 0x2459, 0x6820, 0xa085, 0x0004,
-	0x6822, 0x82ff, 0x00c0, 0x2e20, 0x1078, 0x36c1, 0x0078, 0x2e27,
-	0x8211, 0x0040, 0x2e25, 0x1078, 0x23eb, 0x1078, 0x36d1, 0x782b,
-	0x3008, 0x781b, 0x0065, 0x0078, 0x2459, 0x702c, 0x8003, 0x0048,
-	0x2e37, 0x2019, 0x4d9e, 0x1078, 0x2276, 0x702f, 0x8000, 0x1078,
-	0x3912, 0x7830, 0xa084, 0x00c0, 0x00c0, 0x2e43, 0x0018, 0x2e43,
-	0x791a, 0xa006, 0x007c, 0xa085, 0x0001, 0x007c, 0xa684, 0x0060,
-	0x00c0, 0x2e50, 0x682f, 0x0000, 0x6833, 0x0000, 0x0078, 0x2ec9,
-	0xa684, 0x0800, 0x00c0, 0x2e72, 0x68b4, 0xa084, 0x4800, 0xa635,
-	0xa684, 0x0800, 0x00c0, 0x2e72, 0x6998, 0x6a94, 0x692e, 0x6a32,
-	0x703c, 0xa005, 0x00c0, 0x2e6a, 0x2200, 0xa105, 0x0040, 0x2e71,
-	0x703f, 0x0015, 0x7000, 0xa086, 0x0006, 0x0040, 0x2e71, 0x1078,
-	0x4776, 0x007c, 0xa684, 0x0020, 0x0040, 0x2e94, 0xa684, 0x4000,
-	0x0040, 0x2e80, 0x682f, 0x0000, 0x6833, 0x0000, 0x0078, 0x2e6a,
-	0x68b4, 0xa084, 0x4800, 0xa635, 0xa684, 0x4000, 0x00c0, 0x2e7a,
-	0x703c, 0xa005, 0x00c0, 0x2e8e, 0x703f, 0x0015, 0x79d8, 0x7adc,
-	0x692e, 0x6a32, 0x0078, 0x2e6a, 0xa684, 0x4000, 0x0040, 0x2e9e,
-	0x682f, 0x0000, 0x6833, 0x0000, 0x0078, 0x2e6a, 0x68b4, 0xa084,
-	0x4800, 0xa635, 0xa684, 0x4000, 0x00c0, 0x2e98, 0x703c, 0xa005,
-	0x00c0, 0x2eac, 0x703f, 0x0015, 0x79d8, 0x7adc, 0x78d0, 0x80fb,
-	0x00c8, 0x2eb3, 0x8000, 0xa084, 0x003f, 0xa108, 0xa291, 0x0000,
-	0x692e, 0x6a32, 0x2100, 0xa205, 0x00c0, 0x2ec0, 0x0078, 0x2e6a,
-	0x7000, 0xa086, 0x0006, 0x0040, 0x2ec9, 0x1078, 0x4b30, 0x0078,
-	0x2e6a, 0x007c, 0x6008, 0xa085, 0x0200, 0x600a, 0xa384, 0x0200,
-	0x0040, 0x2ed6, 0x6008, 0xa085, 0x0002, 0x600a, 0x681b, 0x0006,
-	0x688f, 0x0000, 0x6893, 0x0000, 0x6a30, 0x692c, 0x6a3e, 0x6942,
-	0x682f, 0x0003, 0x6833, 0x0000, 0x6837, 0x0020, 0x6897, 0x0000,
-	0x689b, 0x0020, 0x68b3, 0x0000, 0x68af, 0x0000, 0x7000, 0x0079,
-	0x2ef1, 0x2482, 0x2efb, 0x2f04, 0x2ef9, 0x2ef9, 0x2ef9, 0x2ef9,
-	0x2ef9, 0x1078, 0x23eb, 0x6820, 0xa084, 0x0001, 0x00c0, 0x2f04,
-	0x1078, 0x33d8, 0x0078, 0x2f0a, 0x7060, 0x2c50, 0x2060, 0x6800,
-	0x6002, 0x2a60, 0x2021, 0x515a, 0x2404, 0xa005, 0x0040, 0x2f13,
-	0x2020, 0x0078, 0x2f0c, 0x2d22, 0x206b, 0x0000, 0x007c, 0x1078,
-	0x33df, 0x1078, 0x33ee, 0x6008, 0xa084, 0xfdff, 0x600a, 0x682b,
-	0x0000, 0x789b, 0x000e, 0x6f14, 0x6817, 0x0002, 0x1078, 0x4b78,
-	0xa684, 0x0800, 0x0040, 0x2f30, 0x691c, 0xa18d, 0x2000, 0x691e,
-	0x6818, 0xa084, 0x8000, 0x0040, 0x2f40, 0x7868, 0xa08c, 0x00ff,
-	0x0040, 0x2f3e, 0x681b, 0x001e, 0x0078, 0x2f40, 0x681b, 0x0000,
-	0x2021, 0x515a, 0x2404, 0xad06, 0x0040, 0x2f47, 0x7460, 0x6800,
-	0x2022, 0x68c3, 0x0000, 0x6a3c, 0x6940, 0x6a32, 0x692e, 0x1078,
-	0x1c70, 0x0078, 0x2482, 0x1078, 0x2e46, 0x682b, 0x0000, 0x2001,
-	0x000e, 0x6f14, 0x1078, 0x3918, 0xa08c, 0x00ff, 0x6916, 0x6818,
-	0xa084, 0x8000, 0x0040, 0x2f66, 0x703c, 0x681a, 0xa68c, 0xdf00,
-	0x691e, 0x706f, 0x0000, 0x0078, 0x2482, 0x7000, 0xa005, 0x00c0,
-	0x2f73, 0x0078, 0x2482, 0xa006, 0x1078, 0x4776, 0x6817, 0x0000,
-	0x681b, 0x0014, 0xa68c, 0xdf00, 0x691e, 0x682b, 0x0000, 0x6820,
-	0xa085, 0x00ff, 0x6822, 0x7000, 0x0079, 0x2f86, 0x2482, 0x2f90,
-	0x2f90, 0x2f92, 0x2f92, 0x2f92, 0x2f92, 0x2f8e, 0x1078, 0x23eb,
-	0x1078, 0x33ee, 0x6008, 0xa084, 0xffef, 0x600a, 0x0078, 0x33a8,
-	0x2300, 0x0079, 0x2f9b, 0x2f9e, 0x2fa0, 0x2fd9, 0x1078, 0x23eb,
-	0x7000, 0x0079, 0x2fa3, 0x2482, 0x2fad, 0x2fad, 0x2fc8, 0x2fad,
-	0x2fd5, 0x2fc8, 0x2fab, 0x1078, 0x23eb, 0xa684, 0x0060, 0xa086,
-	0x0060, 0x00c0, 0x2fc4, 0xa6b4, 0xffdf, 0xa6b4, 0xbfff, 0xa6b5,
-	0x2000, 0x7e5a, 0x681c, 0xa084, 0xffdf, 0x681e, 0x1078, 0x4776,
-	0x1078, 0x4a3a, 0x0078, 0x3888, 0xa684, 0x2000, 0x0040, 0x2fb7,
-	0x6818, 0xa084, 0x8000, 0x0040, 0x2fd5, 0x681b, 0x0015, 0xa684,
-	0x4000, 0x0040, 0x2fd5, 0x681b, 0x0007, 0x1078, 0x389c, 0x0078,
-	0x2459, 0x1078, 0x23eb, 0x2300, 0x0079, 0x2fde, 0x2fe1, 0x2fe3,
-	0x3016, 0x1078, 0x23eb, 0x7000, 0x0079, 0x2fe6, 0x2482, 0x2ff0,
-	0x2ff0, 0x300b, 0x2ff0, 0x3012, 0x300b, 0x2fee, 0x1078, 0x23eb,
-	0xa684, 0x0060, 0xa086, 0x0060, 0x00c0, 0x3007, 0xa6b4, 0xffbf,
-	0xa6b4, 0xbfff, 0xa6b5, 0x2000, 0x7e5a, 0x681c, 0xa084, 0xffbf,
-	0x681e, 0x1078, 0x4776, 0x1078, 0x4a3a, 0x0078, 0x3888, 0xa684,
-	0x2000, 0x0040, 0x2ffa, 0x6818, 0xa084, 0x8000, 0x0040, 0x3012,
-	0x681b, 0x0007, 0x781b, 0x00cd, 0x0078, 0x2459, 0x6820, 0xa085,
-	0x0004, 0x6822, 0x1078, 0x3853, 0xa6b5, 0x0800, 0x1078, 0x36c1,
-	0x782b, 0x3008, 0x781b, 0x0065, 0x0078, 0x2459, 0x2300, 0x0079,
-	0x3029, 0x302c, 0x302e, 0x3030, 0x1078, 0x23eb, 0x0078, 0x36ad,
-	0xa684, 0x0400, 0x00c0, 0x3059, 0x79e4, 0xa184, 0x0020, 0x0040,
-	0x3040, 0x78ec, 0xa084, 0x0003, 0x0040, 0x3040, 0x782b, 0x3009,
-	0x789b, 0x0060, 0x78ab, 0x0000, 0xa684, 0xfffb, 0x785a, 0x79e4,
-	0xa184, 0x0020, 0x0040, 0x3051, 0x78ec, 0xa084, 0x0003, 0x00c0,
-	0x3055, 0x2001, 0x0014, 0x0078, 0x2d01, 0xa184, 0x0007, 0x0079,
-	0x3091, 0x7a90, 0xa294, 0x0007, 0x789b, 0x0060, 0x79a8, 0x81ff,
-	0x0040, 0x308f, 0x789b, 0x0010, 0x7ba8, 0xa384, 0x0001, 0x00c0,
-	0x3080, 0x7ba8, 0x7ba8, 0xa386, 0x0001, 0x00c0, 0x3073, 0x2009,
-	0xfff7, 0x0078, 0x3079, 0xa386, 0x0003, 0x00c0, 0x3080, 0x2009,
-	0xffef, 0x0c7e, 0x7054, 0x2060, 0x6004, 0xa104, 0x6006, 0x0c7f,
-	0x789b, 0x0060, 0x78ab, 0x0000, 0xa684, 0xfffb, 0x785a, 0x782b,
-	0x3009, 0x6920, 0xa18c, 0xfdff, 0xa18c, 0xfeff, 0x6922, 0x0078,
-	0x3888, 0x299e, 0x29a9, 0x309b, 0x30a3, 0x3099, 0x3099, 0x3888,
-	0x3888, 0x1078, 0x23eb, 0x6920, 0xa18c, 0xfdff, 0xa18c, 0xfeff,
-	0x6922, 0x0078, 0x3892, 0x6920, 0xa18c, 0xfdff, 0xa18c, 0xfeff,
-	0x6922, 0x0078, 0x3888, 0x79e4, 0xa184, 0x0030, 0x0040, 0x30b5,
-	0x78ec, 0xa084, 0x0003, 0x00c0, 0x30dc, 0x7000, 0xa086, 0x0004,
-	0x00c0, 0x30cf, 0x706c, 0xa086, 0x0002, 0x00c0, 0x30c5, 0x2011,
-	0x0002, 0x2019, 0x0000, 0x0078, 0x2848, 0x706c, 0xa086, 0x0006,
-	0x0040, 0x30bf, 0x706c, 0xa086, 0x0004, 0x0040, 0x30bf, 0x7000,
-	0xa086, 0x0000, 0x0040, 0x2459, 0x6818, 0xa085, 0x8000, 0x681a,
-	0x2001, 0x0014, 0x0078, 0x2d01, 0xa184, 0x0007, 0x0079, 0x30e0,
-	0x3888, 0x3888, 0x30e8, 0x3888, 0x38ed, 0x38ed, 0x3888, 0x3888,
-	0xa684, 0x0080, 0x0040, 0x3117, 0x7194, 0x81ff, 0x0040, 0x3117,
-	0xa182, 0x000d, 0x00d0, 0x30f8, 0x7097, 0x0000, 0x0078, 0x30fd,
-	0xa182, 0x000c, 0x7096, 0x2009, 0x000c, 0x789b, 0x0061, 0x79aa,
-	0x157e, 0x137e, 0x147e, 0x7098, 0x8114, 0xa210, 0x729a, 0xa080,
-	0x000b, 0xad00, 0x2098, 0x20a1, 0x012b, 0x789b, 0x0000, 0x8108,
-	0x81ac, 0x53a6, 0x147f, 0x137f, 0x157f, 0x0078, 0x3892, 0xa684,
-	0x0400, 0x00c0, 0x3158, 0x6820, 0xa084, 0x0001, 0x0040, 0x3892,
-	0xa68c, 0x0060, 0xa684, 0x0060, 0x0040, 0x312c, 0xa086, 0x0060,
-	0x00c0, 0x312c, 0xa18d, 0x4000, 0xa18c, 0xfffb, 0x795a, 0x69b6,
-	0x789b, 0x0060, 0x78ab, 0x0000, 0x789b, 0x0061, 0x6818, 0xa085,
-	0x8000, 0x681a, 0x78aa, 0x8008, 0x810c, 0x0040, 0x3407, 0xa18c,
-	0x00f8, 0x00c0, 0x3407, 0x157e, 0x137e, 0x147e, 0x20a1, 0x012b,
-	0x789b, 0x0000, 0x8000, 0x80ac, 0xad80, 0x000b, 0x2098, 0x53a6,
-	0x147f, 0x137f, 0x157f, 0x6814, 0x8007, 0x7882, 0x0078, 0x3892,
-	0x6818, 0xa084, 0x8000, 0x0040, 0x315f, 0x681b, 0x0008, 0x781b,
-	0x00c3, 0x0078, 0x2459, 0x2300, 0x0079, 0x3166, 0x316b, 0x320a,
-	0x3169, 0x1078, 0x23eb, 0x7000, 0xa084, 0x0007, 0x0079, 0x3170,
-	0x2482, 0x317a, 0x31af, 0x3185, 0x3178, 0x2482, 0x3178, 0x3178,
-	0x1078, 0x23eb, 0x681c, 0xa084, 0x2000, 0x0040, 0x3193, 0x6008,
-	0xa085, 0x0002, 0x600a, 0x0078, 0x3193, 0x68c0, 0xa005, 0x00c0,
-	0x31af, 0x6920, 0xa18d, 0x0001, 0x6922, 0x68c3, 0x0001, 0x6800,
-	0x706a, 0x0078, 0x31a9, 0x6920, 0xa18d, 0x0001, 0x6922, 0x6800,
-	0x6006, 0xa005, 0x00c0, 0x319d, 0x6002, 0x681c, 0xa084, 0x000e,
-	0x0040, 0x31a9, 0x7014, 0x68ba, 0x7130, 0xa188, 0x7400, 0x0078,
-	0x31ab, 0x2009, 0x7500, 0x2104, 0x6802, 0x2d0a, 0x7162, 0x6eb6,
-	0xa684, 0x0060, 0x0040, 0x3208, 0xa684, 0x0800, 0x00c0, 0x31c3,
-	0xa684, 0x7fff, 0x68b6, 0x6894, 0x68a6, 0x6898, 0x68aa, 0x1078,
-	0x4776, 0x0078, 0x3208, 0xa684, 0x0020, 0x0040, 0x31d8, 0x68c0,
-	0xa005, 0x0040, 0x31cf, 0x1078, 0x4b78, 0x0078, 0x31d2, 0xa006,
-	0x1078, 0x4b30, 0x79d8, 0x7adc, 0x69aa, 0x6aa6, 0x0078, 0x31de,
-	0x1078, 0x37fc, 0x69aa, 0x6aa6, 0x1078, 0x4b30, 0xa684, 0x8000,
-	0x0040, 0x3208, 0xa684, 0x7fff, 0x68b6, 0x2001, 0x0076, 0x1078,
-	0x3918, 0x2010, 0x2001, 0x0078, 0x1078, 0x3918, 0x2008, 0xa684,
-	0x0020, 0x00c0, 0x3200, 0x2001, 0x007a, 0x1078, 0x3918, 0x801b,
-	0x00c8, 0x31fb, 0x8000, 0xa084, 0x003f, 0xa108, 0xa291, 0x0000,
-	0x6b98, 0x2100, 0xa302, 0x68b2, 0x6b94, 0x2200, 0xa303, 0x68ae,
-	0x0078, 0x2482, 0x0078, 0x36ad, 0x7037, 0x0000, 0xa282, 0x0006,
-	0x0050, 0x3214, 0x1078, 0x23eb, 0x7000, 0xa084, 0x0007, 0x10c0,
-	0x39be, 0x2300, 0x0079, 0x321c, 0x321f, 0x3248, 0x325c, 0x2200,
-	0x0079, 0x3222, 0x3246, 0x36ad, 0x3228, 0x3246, 0x3278, 0x32ba,
-	0x7003, 0x0005, 0x2001, 0x7610, 0x2068, 0x704a, 0x157e, 0x20a9,
-	0x0031, 0x2003, 0x0000, 0x8000, 0x0070, 0x3238, 0x0078, 0x3231,
-	0x157f, 0xad80, 0x0009, 0x7036, 0x6817, 0x0000, 0x68b7, 0x0700,
-	0x6823, 0x0800, 0x6827, 0x0003, 0x0078, 0x369d, 0x1078, 0x23eb,
-	0x7003, 0x0005, 0x2001, 0x7610, 0x2068, 0x704a, 0xad80, 0x0009,
-	0x7036, 0x2200, 0x0079, 0x3254, 0x36ad, 0x325a, 0x325a, 0x3278,
-	0x325a, 0x36ad, 0x1078, 0x23eb, 0x7003, 0x0005, 0x2001, 0x7610,
-	0x2068, 0x704a, 0xad80, 0x0009, 0x7036, 0x2200, 0x0079, 0x3268,
-	0x3270, 0x326e, 0x326e, 0x3270, 0x326e, 0x3270, 0x1078, 0x23eb,
-	0x1078, 0x36d1, 0x782b, 0x3008, 0x781b, 0x0065, 0x0078, 0x2459,
-	0x7003, 0x0002, 0x7a80, 0xa294, 0x0f00, 0x789b, 0x0018, 0x7ca8,
-	0xa484, 0x001f, 0xa215, 0x2069, 0x7500, 0x2d04, 0x2d08, 0x7162,
-	0x2068, 0xa005, 0x0040, 0x3293, 0x6814, 0xa206, 0x0040, 0x32af,
-	0x6800, 0x0078, 0x3286, 0x7003, 0x0005, 0x2001, 0x7610, 0x2068,
-	0x704a, 0x7036, 0x157e, 0x20a9, 0x0031, 0x2003, 0x0000, 0x8000,
-	0x0070, 0x32a4, 0x0078, 0x329d, 0x157f, 0xad80, 0x0009, 0x7036,
-	0x6a16, 0x68b7, 0x0700, 0x6823, 0x0800, 0x6827, 0x0003, 0x6eb4,
-	0x7e5a, 0x6820, 0xa084, 0x0c00, 0x0040, 0x3309, 0x1078, 0x36c9,
-	0x0078, 0x3309, 0x7003, 0x0002, 0x7a80, 0xa294, 0x0f00, 0x789b,
-	0x0018, 0x7ca8, 0xa484, 0x001f, 0xa215, 0x79a8, 0x79a8, 0xa18c,
-	0x00ff, 0xa1e8, 0x7400, 0x2d04, 0x2d08, 0x7162, 0x2068, 0xa005,
-	0x0040, 0x32d9, 0x6814, 0xa206, 0x0040, 0x32f4, 0x6800, 0x0078,
-	0x32cc, 0x7003, 0x0005, 0x2001, 0x7610, 0x2068, 0x704a, 0x157e,
-	0x20a9, 0x0031, 0x2003, 0x0000, 0x8000, 0x0070, 0x32e9, 0x0078,
-	0x32e2, 0x157f, 0xad80, 0x0009, 0x7036, 0x6a16, 0x68b7, 0x0700,
-	0x6823, 0x0800, 0x6827, 0x0003, 0x6eb4, 0x7e5a, 0x6820, 0xa084,
-	0x0c00, 0x0040, 0x3309, 0xa084, 0x0800, 0x0040, 0x3303, 0x1078,
-	0x36cd, 0x0078, 0x3309, 0x1078, 0x36c9, 0x708b, 0x0000, 0x0078,
-	0x3309, 0x027e, 0x8207, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003,
-	0xa080, 0x5380, 0x2060, 0x7056, 0x6000, 0x705a, 0x6004, 0x705e,
-	0xa684, 0x0060, 0x0040, 0x3361, 0x6b98, 0x6c94, 0x69ac, 0x68b0,
-	0xa105, 0x00c0, 0x3343, 0x7bd2, 0x7bda, 0x7cd6, 0x7cde, 0xa6b4,
-	0xb7ff, 0x7e5a, 0xa684, 0x0060, 0xa086, 0x0060, 0x0040, 0x3361,
-	0x68c0, 0xa005, 0x0040, 0x333c, 0x7003, 0x0003, 0x682b, 0x0000,
-	0x1078, 0x4a29, 0x0078, 0x333e, 0x1078, 0x4a3a, 0xa6b5, 0x2000,
-	0x7e5a, 0x0078, 0x3361, 0x68b0, 0xa31a, 0x2100, 0xa423, 0x2400,
-	0xa305, 0x0040, 0x3361, 0x7bd2, 0x7bda, 0x7cd6, 0x7cde, 0x68b0,
-	0xa6b4, 0xbfff, 0x7e5a, 0x007e, 0x68c0, 0xa005, 0x007f, 0x0040,
-	0x335f, 0x7003, 0x0003, 0x1078, 0x4a29, 0x0078, 0x3361, 0x1078,
-	0x4a85, 0x077f, 0x1078, 0x37ef, 0x2009, 0x0065, 0xa684, 0x0004,
-	0x0040, 0x3382, 0x78e4, 0xa084, 0x0030, 0x0040, 0x337a, 0x78ec,
-	0xa084, 0x0003, 0x0040, 0x337a, 0x782b, 0x3008, 0x2009, 0x0065,
-	0x0078, 0x3382, 0x0f7e, 0x2079, 0x5100, 0x1078, 0x4776, 0x0f7f,
-	0x0040, 0x2482, 0x791a, 0x2d00, 0x704a, 0x8207, 0xa084, 0x000f,
-	0x8003, 0x8003, 0x8003, 0xa080, 0x5380, 0x2048, 0x0078, 0x2459,
-	0x6020, 0xa005, 0x0040, 0x339c, 0x8001, 0x6022, 0x6008, 0xa085,
-	0x0008, 0x600a, 0x7010, 0x6026, 0x007c, 0xa006, 0x1078, 0x4776,
-	0x6817, 0x0000, 0x681b, 0x0001, 0x6823, 0x0040, 0x681f, 0x0100,
-	0x7000, 0xa084, 0x0007, 0x0079, 0x33ad, 0x2482, 0x33b7, 0x33b7,
-	0x33d4, 0x33bf, 0x33bd, 0x33bf, 0x33b5, 0x1078, 0x23eb, 0x1078,
-	0x33df, 0x1078, 0x33d8, 0x1078, 0x1c70, 0x0078, 0x2482, 0x706c,
-	0x706f, 0x0000, 0x7093, 0x0000, 0x0079, 0x33c6, 0x33d0, 0x33d0,
-	0x33ce, 0x33ce, 0x33ce, 0x33d0, 0x33ce, 0x33d0, 0x0079, 0x2861,
-	0x706f, 0x0000, 0x0078, 0x2482, 0x681b, 0x0000, 0x0078, 0x2f17,
-	0x6800, 0xa005, 0x00c0, 0x33dd, 0x6002, 0x6006, 0x007c, 0x6010,
-	0xa005, 0x0040, 0x33e8, 0x8001, 0x00d0, 0x33e8, 0x1078, 0x23eb,
-	0x6012, 0x6008, 0xa084, 0xffef, 0x600a, 0x007c, 0x6018, 0xa005,
-	0x0040, 0x33f4, 0x8001, 0x601a, 0x007c, 0x1078, 0x3912, 0x681b,
-	0x0018, 0x0078, 0x342b, 0x1078, 0x3912, 0x681b, 0x0019, 0x0078,
-	0x342b, 0x1078, 0x3912, 0x681b, 0x001a, 0x0078, 0x342b, 0x1078,
-	0x3912, 0x681b, 0x0003, 0x0078, 0x342b, 0x7780, 0x1078, 0x37ef,
-	0x7184, 0xa18c, 0x00ff, 0xa1e8, 0x7400, 0x2d04, 0x2d08, 0x2068,
-	0xa005, 0x00c0, 0x341d, 0x0078, 0x2482, 0x6814, 0x7280, 0xa206,
-	0x0040, 0x3425, 0x6800, 0x0078, 0x3416, 0x6800, 0x200a, 0x681b,
-	0x0005, 0x708b, 0x0000, 0x1078, 0x33df, 0x6820, 0xa084, 0x0001,
-	0x00c0, 0x3434, 0x1078, 0x33d8, 0x1078, 0x33ee, 0x681f, 0x0000,
-	0x6823, 0x0020, 0x1078, 0x1c70, 0x0078, 0x2482, 0xa282, 0x0003,
-	0x00c0, 0x369d, 0x7da8, 0xa5ac, 0x00ff, 0x7ca8, 0xa4a4, 0x00ff,
-	0x6920, 0xa18d, 0x0080, 0x6922, 0xa184, 0x0100, 0x0040, 0x34a2,
-	0xa18c, 0xfeff, 0x6922, 0xa4a4, 0x00ff, 0x0040, 0x348c, 0xa482,
-	0x000c, 0x0048, 0x345f, 0x0040, 0x345f, 0x2021, 0x000c, 0x852b,
-	0x852b, 0x1078, 0x3760, 0x0040, 0x3469, 0x1078, 0x355b, 0x0078,
-	0x3495, 0x1078, 0x371b, 0x0c7e, 0x2960, 0x6004, 0xa084, 0xfff5,
-	0x6006, 0x1078, 0x3586, 0x0c7f, 0x6920, 0xa18d, 0x0100, 0x6922,
-	0x7e58, 0xa6b5, 0x0004, 0x7e5a, 0xa684, 0x0400, 0x00c0, 0x3486,
-	0x782b, 0x3008, 0x781b, 0x0056, 0x0078, 0x2459, 0x782b, 0x3008,
-	0x781b, 0x0065, 0x0078, 0x2459, 0x0c7e, 0x2960, 0x6004, 0xa084,
-	0xfff5, 0x6006, 0x1078, 0x3586, 0x0c7f, 0x7e58, 0xa684, 0x0400,
-	0x00c0, 0x349e, 0x781b, 0x0058, 0x0078, 0x2459, 0x781b, 0x0065,
-	0x0078, 0x2459, 0x0c7e, 0x7054, 0x2060, 0x6100, 0xa18c, 0x1000,
-	0x0040, 0x34e2, 0x6208, 0x8217, 0xa294, 0x00ff, 0xa282, 0x000c,
-	0x0048, 0x34b6, 0x0040, 0x34b6, 0x2011, 0x000c, 0x2400, 0xa202,
-	0x00c8, 0x34bb, 0x2220, 0x6208, 0xa294, 0x00ff, 0x7018, 0xa086,
-	0x0028, 0x00c0, 0x34cb, 0xa282, 0x0019, 0x00c8, 0x34d1, 0x2011,
-	0x0019, 0x0078, 0x34d1, 0xa282, 0x000c, 0x00c8, 0x34d1, 0x2011,
-	0x000c, 0x2200, 0xa502, 0x00c8, 0x34d6, 0x2228, 0x1078, 0x371f,
-	0x852b, 0x852b, 0x1078, 0x3760, 0x0040, 0x34e2, 0x1078, 0x355b,
-	0x0078, 0x34e6, 0x1078, 0x371b, 0x1078, 0x3586, 0x7858, 0xa085,
-	0x0004, 0x785a, 0x0c7f, 0x782b, 0x3008, 0x781b, 0x0065, 0x0078,
-	0x2459, 0x0c7e, 0x2960, 0x6000, 0xa084, 0x1000, 0x00c0, 0x3509,
-	0x6010, 0xa084, 0x000f, 0x00c0, 0x3503, 0x6104, 0xa18c, 0xfff5,
-	0x6106, 0x0c7f, 0x007c, 0x2011, 0x0032, 0x2019, 0x0000, 0x0078,
-	0x3530, 0x68a0, 0xa084, 0x0200, 0x00c0, 0x3503, 0x6208, 0xa294,
-	0x00ff, 0x7018, 0xa086, 0x0028, 0x00c0, 0x351e, 0xa282, 0x0019,
-	0x00c8, 0x3524, 0x2011, 0x0019, 0x0078, 0x3524, 0xa282, 0x000c,
-	0x00c8, 0x3524, 0x2011, 0x000c, 0x6308, 0x831f, 0xa39c, 0x00ff,
-	0xa382, 0x000c, 0x0048, 0x3530, 0x0040, 0x3530, 0x2019, 0x000c,
-	0x78ab, 0x0001, 0x78ab, 0x0003, 0x78ab, 0x0001, 0x7aaa, 0x7baa,
-	0xa8c0, 0x0005, 0x6820, 0xa085, 0x0100, 0x6822, 0x0c7f, 0x007c,
-	0x0c7e, 0x2960, 0xa18c, 0xfff5, 0x6106, 0x2011, 0x0032, 0x2019,
-	0x0000, 0x0078, 0x354b, 0x78ab, 0x0001, 0x78ab, 0x0003, 0x78ab,
-	0x0001, 0x7aaa, 0x7baa, 0xa8c0, 0x0005, 0x6820, 0xa085, 0x0100,
-	0x6822, 0x0c7f, 0x007c, 0x0c7e, 0x7154, 0x2160, 0x1078, 0x3562,
-	0x0c7f, 0x007c, 0x2008, 0xa084, 0xfff0, 0xa425, 0x7c86, 0x6018,
-	0x789a, 0x7cae, 0x6412, 0x78a4, 0xa084, 0xfff8, 0xa18c, 0x0007,
-	0xa105, 0x78a6, 0x6016, 0x788a, 0xa4a4, 0x000f, 0x8427, 0x8204,
-	0x8004, 0xa084, 0x00ff, 0xa405, 0x600e, 0x78ec, 0xd08c, 0x00c0,
-	0x3585, 0x6004, 0xa084, 0xfff5, 0x6006, 0x007c, 0x0c7e, 0x7054,
-	0x2060, 0x1078, 0x358d, 0x0c7f, 0x007c, 0x6018, 0x789a, 0x78a4,
-	0xa084, 0xfff0, 0x78a6, 0x6012, 0x7884, 0xa084, 0xfff0, 0x7886,
-	0x007c, 0xa282, 0x0002, 0x00c0, 0x369d, 0x7aa8, 0x6920, 0xa18d,
-	0x0080, 0x6922, 0xa184, 0x0200, 0x0040, 0x35e2, 0xa18c, 0xfdff,
-	0x6922, 0xa294, 0x00ff, 0xa282, 0x0002, 0x00c8, 0x369d, 0x1078,
-	0x362b, 0x1078, 0x3586, 0xa980, 0x0001, 0x200c, 0x1078, 0x37eb,
-	0x1078, 0x34f1, 0x88ff, 0x0040, 0x35d5, 0x789b, 0x0060, 0x2800,
-	0x78aa, 0x7e58, 0xa6b5, 0x0004, 0x7e5a, 0xa684, 0x0400, 0x00c0,
-	0x35cf, 0x782b, 0x3008, 0x781b, 0x0056, 0x0078, 0x2459, 0x782b,
-	0x3008, 0x781b, 0x0065, 0x0078, 0x2459, 0x7e58, 0xa684, 0x0400,
-	0x00c0, 0x35de, 0x781b, 0x0058, 0x0078, 0x2459, 0x781b, 0x0065,
-	0x0078, 0x2459, 0xa282, 0x0002, 0x00c8, 0x35ea, 0xa284, 0x0001,
-	0x0040, 0x35f4, 0x7154, 0xa188, 0x0000, 0x210c, 0xa18c, 0x2000,
-	0x00c0, 0x35f4, 0x2011, 0x0000, 0x1078, 0x370d, 0x1078, 0x362b,
-	0x1078, 0x3586, 0x7858, 0xa085, 0x0004, 0x785a, 0x782b, 0x3008,
-	0x781b, 0x0065, 0x0078, 0x2459, 0x0c7e, 0x027e, 0x2960, 0x6000,
-	0x2011, 0x0001, 0xa084, 0x2000, 0x00c0, 0x361b, 0x6014, 0xa084,
-	0x0040, 0x00c0, 0x3619, 0xa18c, 0xffef, 0x6106, 0xa006, 0x0078,
-	0x3628, 0x2011, 0x0000, 0x78ab, 0x0001, 0x78ab, 0x0002, 0x78ab,
-	0x0003, 0x7aaa, 0xa8c0, 0x0004, 0x6820, 0xa085, 0x0200, 0x6822,
-	0x027f, 0x0c7f, 0x007c, 0x0c7e, 0x7054, 0x2060, 0x1078, 0x3632,
-	0x0c7f, 0x007c, 0x82ff, 0x0040, 0x3637, 0x2011, 0x0040, 0x6018,
-	0xa080, 0x0002, 0x789a, 0x78a4, 0xa084, 0xffbf, 0xa205, 0x78a6,
-	0x788a, 0x6016, 0x78ec, 0xd08c, 0x00c0, 0x364a, 0x6004, 0xa084,
-	0xffef, 0x6006, 0x007c, 0x007e, 0x7000, 0xa086, 0x0003, 0x0040,
-	0x3654, 0x007f, 0x0078, 0x3657, 0x007f, 0x0078, 0x3699, 0xa684,
-	0x0020, 0x0040, 0x3699, 0x7888, 0xa084, 0x0040, 0x0040, 0x3699,
-	0x7bb8, 0xa384, 0x003f, 0x831b, 0x00c8, 0x3667, 0x8000, 0xa005,
-	0x0040, 0x367d, 0x831b, 0x00c8, 0x3670, 0x8001, 0x0040, 0x3695,
-	0xa684, 0x4000, 0x0040, 0x367d, 0x78b8, 0x801b, 0x00c8, 0x3679,
-	0x8000, 0xa084, 0x003f, 0x00c0, 0x3695, 0xa6b4, 0xbfff, 0x7e5a,
-	0x79d8, 0x7adc, 0x2001, 0x0001, 0xa108, 0x00c8, 0x3689, 0xa291,
-	0x0000, 0x79d2, 0x79da, 0x7ad6, 0x7ade, 0x1078, 0x4b30, 0x781b,
-	0x0064, 0x1078, 0x49b5, 0x0078, 0x2459, 0x781b, 0x0064, 0x0078,
-	0x2459, 0x781b, 0x0065, 0x0078, 0x2459, 0x1078, 0x36d5, 0x782b,
-	0x3008, 0x781b, 0x0065, 0x0078, 0x2459, 0x1078, 0x36c1, 0x782b,
-	0x3008, 0x781b, 0x0065, 0x0078, 0x2459, 0x6827, 0x0002, 0x1078,
-	0x36c9, 0x78e4, 0xa084, 0x0030, 0x0040, 0x2482, 0x78ec, 0xa084,
-	0x0003, 0x0040, 0x2482, 0x782b, 0x3008, 0x781b, 0x0065, 0x0078,
-	0x2459, 0x2001, 0x0005, 0x0078, 0x36d7, 0x2001, 0x000c, 0x0078,
-	0x36d7, 0x2001, 0x0006, 0x0078, 0x36d7, 0x2001, 0x000d, 0x0078,
-	0x36d7, 0x2001, 0x0009, 0x0078, 0x36d7, 0x2001, 0x0007, 0x789b,
-	0x0010, 0x78aa, 0x789b, 0x0060, 0x78ab, 0x0001, 0xa6b5, 0x0004,
-	0x7e5a, 0x007c, 0x077e, 0x873f, 0xa7bc, 0x000f, 0x873b, 0x873b,
-	0x8703, 0xa0e0, 0x5380, 0xa7b8, 0x0020, 0x7f9a, 0x79a4, 0xa184,
-	0x000f, 0x0040, 0x36fb, 0xa184, 0xfff0, 0x78a6, 0x6012, 0x6004,
-	0xa085, 0x0008, 0x6006, 0x8738, 0x8738, 0x7f9a, 0x79a4, 0xa184,
-	0x0040, 0x0040, 0x370b, 0xa184, 0xffbf, 0x78a6, 0x6016, 0x6004,
-	0xa085, 0x0010, 0x6006, 0x077f, 0x007c, 0x789b, 0x0010, 0x78ab,
-	0x0001, 0x78ab, 0x0002, 0x78ab, 0x0003, 0x7aaa, 0x789b, 0x0060,
-	0x78ab, 0x0004, 0x007c, 0x2021, 0x0000, 0x2029, 0x0032, 0x789b,
-	0x0010, 0x78ab, 0x0001, 0x78ab, 0x0003, 0x78ab, 0x0001, 0x7daa,
-	0x7caa, 0x789b, 0x0060, 0x78ab, 0x0005, 0x007c, 0x157e, 0x8007,
-	0xa084, 0x00ff, 0x8003, 0x8003, 0xa080, 0x0020, 0x789a, 0x79a4,
-	0xa18c, 0xfff0, 0x2001, 0x5146, 0x2004, 0xa082, 0x0028, 0x0040,
-	0x3749, 0x2021, 0x37d2, 0x2019, 0x0014, 0x20a9, 0x000c, 0x0078,
-	0x374f, 0x2021, 0x37de, 0x2019, 0x0019, 0x20a9, 0x000d, 0x2011,
-	0x0064, 0x2404, 0xa084, 0xfff0, 0xa106, 0x0040, 0x375e, 0x8420,
-	0x2300, 0xa210, 0x0070, 0x375e, 0x0078, 0x3751, 0x157f, 0x007c,
-	0x157e, 0x2009, 0x5146, 0x210c, 0xa182, 0x0032, 0x0048, 0x3774,
-	0x0040, 0x3778, 0x2009, 0x37c4, 0x2019, 0x0011, 0x20a9, 0x000e,
-	0x2011, 0x0032, 0x0078, 0x378a, 0xa182, 0x0028, 0x0040, 0x3782,
-	0x2009, 0x37d2, 0x2019, 0x0014, 0x20a9, 0x000c, 0x2011, 0x0064,
-	0x0078, 0x378a, 0x2009, 0x37de, 0x2019, 0x0019, 0x20a9, 0x000d,
-	0x2011, 0x0064, 0x2200, 0xa502, 0x0040, 0x379a, 0x0048, 0x379a,
-	0x8108, 0x2300, 0xa210, 0x0070, 0x3797, 0x0078, 0x378a, 0x157f,
-	0xa006, 0x007c, 0x157f, 0xa582, 0x0064, 0x00c8, 0x37a9, 0x7808,
-	0xa085, 0x0070, 0x780a, 0x7044, 0xa085, 0x0070, 0x7046, 0x0078,
-	0x37a9, 0x78ec, 0xa084, 0x0300, 0x0040, 0x37b1, 0x2104, 0x0078,
-	0x37c2, 0x2104, 0xa09e, 0x1102, 0x00c0, 0x37c2, 0x2001, 0x04fd,
-	0x2004, 0xa082, 0x0005, 0x0048, 0x37c1, 0x2001, 0x1201, 0x0078,
-	0x37c2, 0x2104, 0xa005, 0x007c, 0x1102, 0x3002, 0x3202, 0x4203,
-	0x4403, 0x5404, 0x5604, 0x6605, 0x6805, 0x7806, 0x7a06, 0x0c07,
-	0x0c07, 0x0e07, 0x3202, 0x4202, 0x5202, 0x6202, 0x7202, 0x6605,
-	0x7605, 0x7805, 0x7a05, 0x7c05, 0x7e05, 0x7f05, 0x2202, 0x3202,
-	0x4202, 0x5202, 0x5404, 0x6404, 0x7404, 0x7604, 0x7804, 0x7a04,
-	0x7c04, 0x7e04, 0x7f04, 0x789b, 0x0010, 0xa046, 0x007c, 0xa784,
-	0x0f00, 0x800b, 0xa784, 0x001f, 0x8003, 0x8003, 0x8003, 0x8003,
-	0xa105, 0xa0e0, 0x5400, 0x007c, 0x79d8, 0x7adc, 0x78d0, 0x801b,
-	0x00c8, 0x3803, 0x8000, 0xa084, 0x003f, 0xa108, 0xa291, 0x0000,
-	0x007c, 0x0f7e, 0x2079, 0x0100, 0x2009, 0x5140, 0x2091, 0x8000,
-	0x2104, 0x0079, 0x3813, 0x3849, 0x381d, 0x381d, 0x381d, 0x381d,
-	0x381d, 0x381d, 0x384d, 0x1078, 0x23eb, 0x784b, 0x0004, 0x7848,
-	0xa084, 0x0004, 0x00c0, 0x381f, 0x784b, 0x0008, 0x7848, 0xa084,
-	0x0008, 0x00c0, 0x3826, 0x68b4, 0xa085, 0x4000, 0x68b6, 0x7858,
-	0xa085, 0x4000, 0x785a, 0x7830, 0xa084, 0x0080, 0x00c0, 0x3849,
-	0x0018, 0x3849, 0x681c, 0xa084, 0x0020, 0x00c0, 0x3847, 0x0e7e,
-	0x2071, 0x5140, 0x1078, 0x389c, 0x0e7f, 0x0078, 0x3849, 0x781b,
-	0x00cd, 0x2091, 0x8001, 0x0f7f, 0x007c, 0x70b3, 0x0000, 0x1078,
-	0x3a76, 0x0078, 0x3849, 0x0c7e, 0x6814, 0x8007, 0xa084, 0x000f,
-	0x8003, 0x8003, 0x8003, 0xa0e0, 0x5380, 0x6004, 0xa084, 0x000a,
-	0x00c0, 0x3886, 0x6108, 0xa194, 0xff00, 0x0040, 0x3886, 0xa18c,
-	0x00ff, 0x2001, 0x0019, 0xa106, 0x0040, 0x3875, 0x2001, 0x0032,
-	0xa106, 0x0040, 0x3879, 0x0078, 0x387d, 0x2009, 0x0020, 0x0078,
-	0x387f, 0x2009, 0x003f, 0x0078, 0x387f, 0x2011, 0x0000, 0x2100,
-	0xa205, 0x600a, 0x6004, 0xa085, 0x0002, 0x6006, 0x0c7f, 0x007c,
-	0x781b, 0x0065, 0x0078, 0x2459, 0x782b, 0x3008, 0x781b, 0x0065,
-	0x0078, 0x2459, 0x781b, 0x0058, 0x0078, 0x2459, 0x782b, 0x3008,
-	0x781b, 0x0056, 0x0078, 0x2459, 0x2009, 0x5120, 0x210c, 0xa186,
-	0x0000, 0x0040, 0x38b0, 0xa186, 0x0001, 0x0040, 0x38b3, 0x2009,
-	0x5138, 0x200b, 0x000b, 0x706f, 0x0001, 0x781b, 0x0048, 0x007c,
-	0x781b, 0x00c7, 0x007c, 0x2009, 0x5138, 0x200b, 0x000a, 0x007c,
-	0x2009, 0x5120, 0x210c, 0xa186, 0x0000, 0x0040, 0x38d3, 0xa186,
-	0x0001, 0x0040, 0x38cd, 0x2009, 0x5138, 0x200b, 0x000b, 0x706f,
-	0x0001, 0x781b, 0x0048, 0x0078, 0x2459, 0x2009, 0x5138, 0x200b,
-	0x000a, 0x0078, 0x2459, 0x782b, 0x3008, 0x781b, 0x00c7, 0x0078,
-	0x2459, 0x781b, 0x00cd, 0x0078, 0x2459, 0x782b, 0x3008, 0x781b,
-	0x00cd, 0x0078, 0x2459, 0x781b, 0x008e, 0x0078, 0x2459, 0x782b,
-	0x3008, 0x781b, 0x008e, 0x0078, 0x2459, 0x6818, 0xa084, 0x8000,
-	0x0040, 0x38f4, 0x681b, 0x001d, 0x706f, 0x0001, 0x781b, 0x0048,
-	0x0078, 0x2459, 0x007e, 0x7830, 0xa084, 0x00c0, 0x00c0, 0x3910,
-	0x7808, 0xa084, 0xfffc, 0x780a, 0x0005, 0x0005, 0x0005, 0x0005,
-	0x78ec, 0xa084, 0x0021, 0x0040, 0x3910, 0x7044, 0x780a, 0xa005,
-	0x007f, 0x007c, 0x7044, 0xa085, 0x0002, 0x7046, 0x780a, 0x007c,
-	0x007e, 0x7830, 0xa084, 0x0040, 0x00c0, 0x3919, 0x0098, 0x3924,
-	0x007f, 0x789a, 0x78ac, 0x007c, 0x7808, 0xa084, 0xfffd, 0x780a,
-	0x0005, 0x0005, 0x0005, 0x0005, 0x78ec, 0xa084, 0x0021, 0x0040,
-	0x3933, 0x0098, 0x3931, 0x007f, 0x789a, 0x78ac, 0x007e, 0x7044,
-	0x780a, 0x007f, 0x007c, 0x78ec, 0xa084, 0x0002, 0x00c0, 0x4760,
-	0xa784, 0x007d, 0x00c0, 0x3947, 0x2700, 0x1078, 0x23eb, 0xa784,
-	0x0001, 0x00c0, 0x2f6d, 0xa784, 0x0070, 0x0040, 0x3957, 0x0c7e,
-	0x2d60, 0x2f68, 0x1078, 0x2396, 0x2d78, 0x2c68, 0x0c7f, 0xa784,
-	0x0008, 0x0040, 0x3964, 0x784b, 0x0008, 0x78ec, 0xa084, 0x0003,
-	0x0040, 0x2482, 0x0078, 0x3888, 0xa784, 0x0004, 0x0040, 0x3997,
-	0x78b8, 0xa084, 0x4001, 0x0040, 0x3997, 0x784b, 0x0008, 0x78ec,
-	0xa084, 0x0003, 0x0040, 0x2482, 0x78e4, 0xa084, 0x0007, 0xa086,
-	0x0001, 0x00c0, 0x3997, 0x78c0, 0xa085, 0x4800, 0x2030, 0x7e5a,
-	0x781b, 0x00cd, 0x0078, 0x2459, 0x784b, 0x0008, 0x6818, 0xa084,
-	0x8000, 0x0040, 0x3993, 0x681b, 0x0015, 0xa684, 0x4000, 0x0040,
-	0x3993, 0x681b, 0x0007, 0x1078, 0x389c, 0x0078, 0x2459, 0x681b,
-	0x0003, 0x7858, 0xa084, 0x3f00, 0x681e, 0x682f, 0x0000, 0x6833,
-	0x0000, 0x784b, 0x0008, 0x78ec, 0xa084, 0x0003, 0x0040, 0x2965,
-	0x0018, 0x2459, 0x0078, 0x36a5, 0x6b14, 0x8307, 0xa084, 0x000f,
-	0x8003, 0x8003, 0x8003, 0xa080, 0x5380, 0x2060, 0x2048, 0x7056,
-	0x6000, 0x705a, 0x6004, 0x705e, 0x2a60, 0x007c, 0x0079, 0x39c0,
-	0x39c8, 0x39c9, 0x39c8, 0x39cb, 0x39c8, 0x39c8, 0x39c8, 0x39d0,
-	0x007c, 0x1078, 0x33ee, 0x1078, 0x4776, 0x7038, 0x600a, 0x007c,
-	0x70a0, 0xa005, 0x0040, 0x39dd, 0x2068, 0x1078, 0x1b62, 0x1078,
-	0x46f8, 0x1078, 0x46ff, 0x70a3, 0x0000, 0x007c, 0x0e7e, 0x2091,
-	0x8000, 0x2071, 0x5140, 0x7000, 0xa086, 0x0007, 0x00c0, 0x39f4,
-	0x6110, 0x70bc, 0xa106, 0x00c0, 0x39f4, 0x0e7f, 0x1078, 0x1b6f,
-	0x1078, 0x39fa, 0xa006, 0x007c, 0x2091, 0x8001, 0x0e7f, 0xa085,
-	0x0001, 0x007c, 0x0f7e, 0x0e7e, 0x2071, 0x5140, 0x0078, 0x21fa,
-	0x785b, 0x0000, 0x70af, 0x000e, 0x2009, 0x0100, 0x017e, 0x70a0,
-	0xa06d, 0x0040, 0x3a0f, 0x70a3, 0x0000, 0x0078, 0x3a15, 0x70b3,
-	0x0000, 0x1078, 0x1b8b, 0x0040, 0x3a1b, 0x70ac, 0x6826, 0x1078,
-	0x3af8, 0x0078, 0x3a0f, 0x017f, 0x157e, 0x0c7e, 0x0d7e, 0x20a9,
-	0x0008, 0x2061, 0x7510, 0x6000, 0xa105, 0x6002, 0x601c, 0xa06d,
-	0x0040, 0x3a33, 0x6800, 0x601e, 0x1078, 0x195a, 0x6008, 0x8000,
-	0x600a, 0x0078, 0x3a26, 0x6018, 0xa06d, 0x0040, 0x3a3d, 0x6800,
-	0x601a, 0x1078, 0x195a, 0x0078, 0x3a33, 0xace0, 0x0008, 0x0070,
-	0x3a43, 0x0078, 0x3a23, 0x709c, 0xa084, 0x8000, 0x0040, 0x3a4a,
-	0x1078, 0x3b72, 0x0d7f, 0x0c7f, 0x157f, 0x007c, 0x127e, 0x2091,
-	0x2300, 0x6804, 0xa084, 0x000f, 0x0079, 0x3a56, 0x3a66, 0x3a66,
-	0x3a66, 0x3a66, 0x3a66, 0x3a66, 0x3a68, 0x3a6e, 0x3a66, 0x3a66,
-	0x3a66, 0x3a66, 0x3a66, 0x3a70, 0x3a66, 0x3a68, 0x1078, 0x23eb,
-	0x1078, 0x44d0, 0x1078, 0x195a, 0x0078, 0x3a74, 0x6827, 0x000b,
-	0x1078, 0x44d0, 0x1078, 0x3af8, 0x127f, 0x007c, 0x127e, 0x2091,
-	0x2300, 0x0098, 0x3a92, 0x7830, 0xa084, 0x00c0, 0x00c0, 0x3a92,
-	0x0d7e, 0x1078, 0x4708, 0x2d00, 0x682e, 0x2009, 0x0004, 0x2001,
-	0x0000, 0x6827, 0x0084, 0x1078, 0x46c1, 0x1078, 0x3af8, 0x0d7f,
-	0x0078, 0x3ac6, 0x7948, 0xa185, 0x4000, 0x784a, 0x0098, 0x3a9b,
-	0x794a, 0x0078, 0x3a80, 0x7828, 0xa086, 0x1834, 0x00c0, 0x3aa4,
-	0xa185, 0x0004, 0x0078, 0x3aab, 0x7828, 0xa086, 0x1814, 0x00c0,
-	0x3a98, 0xa185, 0x000c, 0x784a, 0x789b, 0x000e, 0x78ab, 0x0002,
-	0x7858, 0xa084, 0x00ff, 0xa085, 0x0400, 0x785a, 0x70b4, 0xa080,
-	0x0091, 0x781a, 0x6827, 0x0284, 0x682c, 0x6836, 0x6830, 0x683a,
-	0x2009, 0x0004, 0x2001, 0x0000, 0x1078, 0x46c1, 0x127f, 0x007c,
-	0x0d7e, 0x6b14, 0x1078, 0x1bfd, 0x0040, 0x3ad5, 0x2068, 0x6827,
-	0x0002, 0x1078, 0x3af8, 0x0078, 0x3aca, 0x0d7f, 0x007c, 0x0d7e,
-	0x6b14, 0x6c28, 0xa4a4, 0x00ff, 0x1078, 0x1b9b, 0x0040, 0x3ae5,
-	0x2068, 0x6827, 0x0002, 0x1078, 0x3af8, 0x0d7f, 0x007c, 0x0d7e,
-	0x6b14, 0xa39c, 0x00ff, 0x1078, 0x1bce, 0x0040, 0x3af6, 0x2068,
-	0x6827, 0x0002, 0x1078, 0x3af8, 0x0078, 0x3aeb, 0x0d7f, 0x007c,
-	0x0c7e, 0x6914, 0x1078, 0x3b69, 0x6904, 0xa18c, 0x00ff, 0xa186,
-	0x0006, 0x0040, 0x3b13, 0xa186, 0x000d, 0x0040, 0x3b32, 0xa186,
-	0x0017, 0x00c0, 0x3b0f, 0x1078, 0x195a, 0x0078, 0x3b11, 0x1078,
-	0x1c72, 0x0c7f, 0x007c, 0x6004, 0x8001, 0x0048, 0x3b30, 0x6006,
-	0x2009, 0x0000, 0xa684, 0x0001, 0x00c0, 0x3b20, 0xa18d, 0x8000,
-	0xa684, 0x0004, 0x0040, 0x3b26, 0xa18d, 0x0002, 0x691e, 0x6823,
-	0x0000, 0x7104, 0x810f, 0x6818, 0xa105, 0x681a, 0x0078, 0x3b0f,
-	0x1078, 0x23eb, 0x6018, 0xa005, 0x00c0, 0x3b41, 0x6008, 0x8001,
-	0x0048, 0x3b41, 0x600a, 0x601c, 0x6802, 0x2d00, 0x601e, 0x0078,
-	0x3b57, 0xac88, 0x0006, 0x2104, 0xa005, 0x0040, 0x3b4a, 0x2008,
-	0x0078, 0x3b43, 0x6802, 0x2d0a, 0x6008, 0x8001, 0x0048, 0x3b11,
-	0x600a, 0x6018, 0x2068, 0x6800, 0x601a, 0x0078, 0x3b3b, 0x157e,
-	0x137e, 0x147e, 0x0c7e, 0x0d7e, 0x1078, 0x1937, 0x2da0, 0x137f,
-	0x20a9, 0x0031, 0x53a3, 0x0c7f, 0x147f, 0x137f, 0x157f, 0x0078,
-	0x3b0f, 0xa184, 0x001f, 0x8003, 0x8003, 0x8003, 0xa080, 0x7510,
-	0x2060, 0x007c, 0x2019, 0x5151, 0x2304, 0xa085, 0x0001, 0x201a,
-	0x2019, 0x0102, 0x2304, 0xa085, 0x0001, 0x201a, 0x007c, 0x2019,
-	0x5151, 0x2304, 0xa084, 0xfffe, 0x201a, 0x2019, 0x0102, 0x2304,
-	0xa084, 0xfffe, 0x201a, 0x007c, 0x7990, 0xa18c, 0xfff8, 0x7992,
-	0x70b4, 0xa080, 0x00dd, 0x781a, 0x0078, 0x2459, 0x70a3, 0x0000,
-	0x7003, 0x0000, 0x7043, 0x0001, 0x7037, 0x0000, 0x0018, 0x2410,
-	0x1078, 0x1b8b, 0x0040, 0x3bc7, 0x2009, 0x510f, 0x200b, 0x0000,
-	0x68bc, 0x2060, 0x6100, 0xa184, 0x0300, 0x0040, 0x3bbb, 0x6827,
-	0x000e, 0xa084, 0x0200, 0x0040, 0x3bb7, 0x6827, 0x0017, 0x1078,
-	0x3af8, 0x0078, 0x3b96, 0x7000, 0xa086, 0x0007, 0x00c0, 0x3c29,
-	0x2d00, 0x70a2, 0xad80, 0x000f, 0x7036, 0x0078, 0x3bce, 0x7040,
-	0xa086, 0x0001, 0x0040, 0x2492, 0x0078, 0x2459, 0x2031, 0x0000,
-	0x691c, 0xa184, 0x0002, 0x0040, 0x3bd7, 0xa6b5, 0x0004, 0xa184,
-	0x00c0, 0x8003, 0x8003, 0x8007, 0xa080, 0x3cc2, 0x2004, 0xa635,
-	0x6820, 0xa084, 0x0400, 0x0040, 0x3bef, 0x789b, 0x0018, 0x78ab,
-	0x0003, 0x789b, 0x0081, 0x78ab, 0x0001, 0xa6b5, 0x1000, 0x6820,
-	0xa084, 0x8000, 0x00c0, 0x3bfd, 0x681c, 0xa084, 0x8000, 0x00c0,
-	0x3c04, 0xa6b5, 0x0800, 0x0078, 0x3c04, 0xa6b5, 0x0400, 0x789b,
-	0x000e, 0x6824, 0x8007, 0x78aa, 0x6820, 0xa084, 0x0100, 0x0040,
-	0x3c0b, 0xa6b5, 0x4000, 0xa684, 0x0200, 0x0040, 0x3c25, 0x682c,
-	0x78d2, 0x6830, 0x78d6, 0xa684, 0x0100, 0x0040, 0x3c23, 0x682c,
-	0xa084, 0x0001, 0x0040, 0x3c23, 0x7888, 0xa084, 0x0040, 0x0040,
-	0x3c23, 0xa6b5, 0x8000, 0x1078, 0x46f0, 0x7e5a, 0x6eb6, 0x0078,
-	0x4727, 0x1078, 0x38fa, 0x00c0, 0x3cbc, 0x702c, 0x8004, 0x0048,
-	0x3c37, 0x2019, 0x4e3b, 0x1078, 0x2276, 0x702f, 0x0001, 0x2041,
-	0x0001, 0x2031, 0x1000, 0x789b, 0x0018, 0x6814, 0xa084, 0x001f,
-	0xa085, 0x0080, 0x78aa, 0x691c, 0xa184, 0x0002, 0x0040, 0x3c50,
-	0xa6b5, 0x0004, 0x78ab, 0x0020, 0x6828, 0x78aa, 0xa8c0, 0x0002,
-	0x681c, 0xd0f4, 0x0040, 0x3c59, 0x2c50, 0x1078, 0x39ac, 0x1078,
-	0x45ff, 0x6820, 0xa084, 0x8000, 0x0040, 0x3c67, 0xa6b5, 0x0400,
-	0x789b, 0x000e, 0x6824, 0x8007, 0x78aa, 0x0078, 0x3c6e, 0x681c,
-	0xa084, 0x8000, 0x00c0, 0x3c6e, 0xa6b5, 0x0800, 0x6820, 0xa084,
-	0x0100, 0x0040, 0x3c75, 0xa6b5, 0x4000, 0x681c, 0xa084, 0x00c0,
-	0x8003, 0x8003, 0x8007, 0xa080, 0x3cc2, 0x2004, 0xa635, 0xa684,
-	0x0100, 0x0040, 0x3c8f, 0x682c, 0xa084, 0x0001, 0x0040, 0x3c8f,
-	0x7888, 0xa084, 0x0040, 0x0040, 0x3c8f, 0xa6b5, 0x8000, 0x789b,
-	0x007e, 0x7eae, 0x6eb6, 0x6814, 0x8007, 0x78aa, 0x7882, 0x2810,
-	0x7aaa, 0x7830, 0xa084, 0x00c0, 0x00c0, 0x3cbc, 0x0018, 0x3cbc,
-	0x70b4, 0xa080, 0x00e2, 0x781a, 0x1078, 0x3912, 0xa684, 0x0200,
-	0x0040, 0x3cb0, 0x682c, 0x78d2, 0x6830, 0x78d6, 0x1078, 0x46f0,
-	0x2d00, 0x70a2, 0x704a, 0x6810, 0x70be, 0x7003, 0x0007, 0xad80,
-	0x000f, 0x7036, 0x0078, 0x2459, 0x1078, 0x1b62, 0x1078, 0x3912,
-	0x0078, 0x2459, 0x0000, 0x0300, 0x0200, 0x0000, 0x1078, 0x23eb,
-	0x2300, 0x0079, 0x3ccb, 0x3cce, 0x3cce, 0x3cd0, 0x1078, 0x23eb,
-	0x1078, 0x46ff, 0x6924, 0xa184, 0x00ff, 0xa086, 0x000a, 0x0040,
-	0x3ce2, 0xa184, 0xff00, 0xa085, 0x000a, 0x6826, 0x1078, 0x1b62,
-	0x0078, 0x3b96, 0x2001, 0x000a, 0x1078, 0x4691, 0x0078, 0x3b96,
-	0xa282, 0x0005, 0x0050, 0x3cee, 0x1078, 0x23eb, 0x7000, 0xa084,
-	0x0007, 0x10c0, 0x39be, 0x1078, 0x1937, 0x00c0, 0x3d0d, 0xa684,
-	0x0004, 0x0040, 0x3cff, 0x2001, 0x2800, 0x0078, 0x3d01, 0x2001,
-	0x0800, 0x71b4, 0xa188, 0x0091, 0x789b, 0x000e, 0x78aa, 0x2031,
-	0x0400, 0x7e5a, 0x791a, 0x0078, 0x2459, 0x6807, 0x0106, 0x680b,
-	0x0000, 0x689f, 0x0000, 0x6827, 0x0000, 0xa386, 0x0002, 0x00c0,
-	0x3d2e, 0xa286, 0x0002, 0x00c0, 0x3d2e, 0x78a0, 0xa005, 0x00c0,
-	0x3d2e, 0xa484, 0x8000, 0x00c0, 0x3d2e, 0x78e4, 0xa084, 0x0008,
-	0x0040, 0x3d2e, 0xa6b5, 0x0008, 0x2019, 0x0000, 0x1078, 0x411e,
-	0x2d00, 0x70a2, 0x704a, 0x7003, 0x0007, 0x7037, 0x0000, 0x6824,
-	0xa084, 0x0080, 0x0040, 0x3d40, 0x1078, 0x41d0, 0x0078, 0x2459,
-	0x2300, 0x0079, 0x3d43, 0x3d46, 0x3dc7, 0x3de6, 0x2200, 0x0079,
-	0x3d49, 0x3d4e, 0x3d5e, 0x3d84, 0x3d90, 0x3db3, 0x2029, 0x0001,
-	0xa026, 0x2011, 0x0000, 0x1078, 0x42f1, 0x0079, 0x3d57, 0x3d5c,
-	0x2459, 0x3b96, 0x3d5c, 0x3d5c, 0x1078, 0x23eb, 0x7990, 0xa18c,
-	0x0007, 0x00c0, 0x3d65, 0x2009, 0x0008, 0x2011, 0x0001, 0xa684,
-	0x0004, 0x0040, 0x3d6d, 0x2011, 0x0003, 0x2220, 0xa12a, 0x2011,
-	0x0001, 0x1078, 0x42f1, 0x0079, 0x3d75, 0x3d7a, 0x2459, 0x3b96,
-	0x3d82, 0x3d7c, 0x0078, 0x472d, 0x70ab, 0x3d80, 0x0078, 0x2459,
-	0x0078, 0x3d7a, 0x1078, 0x23eb, 0xa684, 0x0010, 0x0040, 0x3d8e,
-	0x1078, 0x419f, 0x0040, 0x3d8e, 0x0078, 0x2459, 0x0078, 0x420c,
-	0x6000, 0xa084, 0x0002, 0x0040, 0x3dad, 0x70b4, 0xa080, 0x00d2,
-	0x781a, 0x0d7e, 0x1078, 0x4708, 0x2d00, 0x682e, 0x6827, 0x0000,
-	0x1078, 0x3af8, 0x0d7f, 0x1078, 0x195a, 0x7003, 0x0000, 0x7037,
-	0x0000, 0x704b, 0x0000, 0x0078, 0x3b96, 0xa684, 0x0004, 0x00c0,
-	0x3db3, 0x0078, 0x472d, 0x6000, 0xa084, 0x0004, 0x00c0, 0x3dc5,
-	0x6000, 0xa084, 0x0001, 0x0040, 0x3dc5, 0x70ab, 0x3dc5, 0x2001,
-	0x0007, 0x1078, 0x4689, 0x0078, 0x4733, 0x0078, 0x472d, 0x2200,
-	0x0079, 0x3dca, 0x3dcf, 0x3dcf, 0x3dcf, 0x3dd1, 0x3dcf, 0x1078,
-	0x23eb, 0x70a7, 0x3dd5, 0x0078, 0x4739, 0x2011, 0x0018, 0x1078,
-	0x42eb, 0x0079, 0x3ddb, 0x3de0, 0x2459, 0x3b96, 0x3de2, 0x3de4,
-	0x1078, 0x23eb, 0x1078, 0x23eb, 0x1078, 0x23eb, 0x2200, 0x0079,
-	0x3de9, 0x3dee, 0x3df0, 0x3df0, 0x3dee, 0x3dee, 0x1078, 0x23eb,
-	0x78e4, 0xa084, 0x0008, 0x0040, 0x3e05, 0x70a7, 0x3df9, 0x0078,
-	0x4739, 0x2011, 0x0004, 0x1078, 0x42eb, 0x0079, 0x3dff, 0x3e05,
-	0x2459, 0x3b96, 0x3e05, 0x3e0f, 0x3e13, 0x70ab, 0x3e0d, 0x2001,
-	0x0003, 0x1078, 0x4689, 0x0078, 0x4733, 0x0078, 0x472d, 0x70ab,
-	0x3e05, 0x0078, 0x2459, 0x70ab, 0x3e17, 0x0078, 0x2459, 0x0078,
-	0x3e0d, 0xa282, 0x0003, 0x0050, 0x3e1f, 0x1078, 0x23eb, 0xa386,
-	0x0002, 0x00c0, 0x3e38, 0xa286, 0x0002, 0x00c0, 0x3e3e, 0x78a0,
-	0xa005, 0x00c0, 0x3e3e, 0xa484, 0x8000, 0x00c0, 0x3e3e, 0x78e4,
-	0xa084, 0x0008, 0x0040, 0x3e38, 0xa6b5, 0x0008, 0x2019, 0x0000,
-	0xa684, 0x0008, 0x0040, 0x3e3e, 0x1078, 0x417c, 0x6810, 0x70be,
-	0x7003, 0x0007, 0x2300, 0x0079, 0x3e45, 0x3e48, 0x3e75, 0x3e7d,
-	0x2200, 0x0079, 0x3e4b, 0x3e50, 0x3e4e, 0x3e69, 0x1078, 0x23eb,
-	0x7990, 0xa1ac, 0x0007, 0xa026, 0x2011, 0x0001, 0x1078, 0x42f1,
-	0x0079, 0x3e5a, 0x3e5f, 0x2459, 0x3b96, 0x3e67, 0x3e61, 0x0078,
-	0x472d, 0x70ab, 0x3e65, 0x0078, 0x2459, 0x0078, 0x3e5f, 0x1078,
-	0x23eb, 0xa684, 0x0010, 0x0040, 0x3e73, 0x1078, 0x419f, 0x0040,
-	0x3e73, 0x0078, 0x2459, 0x0078, 0x420c, 0x2200, 0x0079, 0x3e78,
-	0x3e7b, 0x3e7b, 0x3e7b, 0x1078, 0x23eb, 0x2200, 0x0079, 0x3e80,
-	0x3e83, 0x3e85, 0x3e85, 0x1078, 0x23eb, 0x78e4, 0xa084, 0x0008,
-	0x0040, 0x3e9a, 0x70a7, 0x3e8e, 0x0078, 0x4739, 0x2011, 0x0004,
-	0x1078, 0x42eb, 0x0079, 0x3e94, 0x3e9a, 0x2459, 0x3b96, 0x3e9a,
-	0x3ea4, 0x3ea8, 0x70ab, 0x3ea2, 0x2001, 0x0003, 0x1078, 0x4689,
-	0x0078, 0x4733, 0x0078, 0x472d, 0x70ab, 0x3e9a, 0x0078, 0x2459,
-	0x70ab, 0x3eac, 0x0078, 0x2459, 0x0078, 0x3ea2, 0x2300, 0x0079,
-	0x3eb1, 0x3eb6, 0x3eb8, 0x3eb4, 0x1078, 0x23eb, 0x70a4, 0x007a,
-	0x70a4, 0x007a, 0xa282, 0x0002, 0x0050, 0x3ec0, 0x1078, 0x23eb,
-	0xa684, 0x0200, 0x0040, 0x3eca, 0x1078, 0x46f8, 0x1078, 0x42d3,
-	0x1078, 0x46ff, 0x2300, 0x0079, 0x3ecd, 0x3ed0, 0x3ef4, 0x3f5a,
-	0xa286, 0x0001, 0x0040, 0x3ed6, 0x1078, 0x23eb, 0xa684, 0x0200,
-	0x0040, 0x3ede, 0x1078, 0x46f8, 0x1078, 0x46ff, 0x2001, 0x0001,
-	0x1078, 0x4691, 0x78b8, 0xa084, 0xc001, 0x0040, 0x3ef0, 0x7848,
-	0xa085, 0x0008, 0x784a, 0x7848, 0xa084, 0x0008, 0x00c0, 0x3eeb,
-	0x7003, 0x0000, 0x0078, 0x3b96, 0x2200, 0x0079, 0x3ef7, 0x3ef9,
-	0x3f2a, 0x70a7, 0x3efd, 0x0078, 0x4739, 0x2011, 0x000d, 0x1078,
-	0x42eb, 0x0079, 0x3f03, 0x3f0a, 0x2459, 0x3b96, 0x3f12, 0x3f1a,
-	0x3f20, 0x3f22, 0xa6b4, 0x00ff, 0xa6b5, 0x0400, 0x6eb6, 0x7e5a,
-	0x0078, 0x4727, 0xa6b4, 0x00ff, 0xa6b5, 0x0400, 0x6eb6, 0x7e5a,
-	0x0078, 0x4727, 0x70ab, 0x3f1e, 0x0078, 0x2459, 0x0078, 0x3f0a,
-	0x1078, 0x23eb, 0x70ab, 0x3f26, 0x0078, 0x2459, 0x1078, 0x473f,
-	0x0078, 0x2459, 0x70a7, 0x3f2e, 0x0078, 0x4739, 0x2011, 0x0012,
-	0x1078, 0x42eb, 0x0079, 0x3f34, 0x3f3a, 0x2459, 0x3b96, 0x3f46,
-	0x3f4e, 0x3f54, 0xa6b4, 0x00ff, 0xa6b5, 0x0400, 0x6eb6, 0x7e5a,
-	0x70b4, 0xa080, 0x00a6, 0x781a, 0x0078, 0x2459, 0xa6b4, 0x00ff,
-	0xa6b5, 0x0400, 0x6eb6, 0x7e5a, 0x0078, 0x4727, 0x70ab, 0x3f52,
-	0x0078, 0x2459, 0x0078, 0x3f3a, 0x70ab, 0x3f58, 0x0078, 0x2459,
-	0x0078, 0x3f46, 0xa286, 0x0001, 0x0040, 0x3f60, 0x1078, 0x23eb,
-	0x70a7, 0x3f64, 0x0078, 0x4739, 0x2011, 0x0015, 0x1078, 0x42eb,
-	0x0079, 0x3f6a, 0x3f6f, 0x2459, 0x3b96, 0x3f7d, 0x3f89, 0xa6b4,
-	0x00ff, 0xa6b5, 0x0400, 0x6eb6, 0x7e5a, 0x783b, 0x1301, 0x70b4,
-	0xa080, 0x00b4, 0x781a, 0x0078, 0x2459, 0xa6b4, 0x00ff, 0xa6b5,
-	0x0400, 0x6eb6, 0x7e5a, 0x70b4, 0xa080, 0x00a6, 0x781a, 0x0078,
-	0x2459, 0x70ab, 0x3f8d, 0x0078, 0x2459, 0x0078, 0x3f6f, 0xa282,
-	0x0003, 0x0050, 0x3f95, 0x1078, 0x23eb, 0x2300, 0x0079, 0x3f98,
-	0x3f9b, 0x3fd2, 0x402d, 0xa286, 0x0001, 0x0040, 0x3fa1, 0x1078,
-	0x23eb, 0x6804, 0xa084, 0x00ff, 0xa086, 0x0006, 0x00c0, 0x3fae,
-	0x1078, 0x3af8, 0x7003, 0x0000, 0x0078, 0x3b96, 0x683b, 0x0000,
-	0x6837, 0x0000, 0xa684, 0x0200, 0x0040, 0x3fbc, 0x1078, 0x46f8,
-	0x1078, 0x42d3, 0x1078, 0x46ff, 0x2001, 0x0001, 0x1078, 0x4691,
-	0x78b8, 0xa084, 0xc001, 0x0040, 0x3fce, 0x7848, 0xa085, 0x0008,
-	0x784a, 0x7848, 0xa084, 0x0008, 0x00c0, 0x3fc9, 0x7003, 0x0000,
-	0x0078, 0x3b96, 0x2200, 0x0079, 0x3fd5, 0x3fd7, 0x4008, 0x70a7,
-	0x3fdb, 0x0078, 0x4739, 0x2011, 0x000d, 0x1078, 0x42eb, 0x0079,
-	0x3fe1, 0x3fe8, 0x2459, 0x3b96, 0x3ff0, 0x3ff8, 0x3ffe, 0x4000,
-	0xa6b4, 0x00ff, 0xa6b5, 0x0800, 0x6eb6, 0x7e5a, 0x0078, 0x4727,
-	0xa6b4, 0x00ff, 0xa6b5, 0x0800, 0x6eb6, 0x7e5a, 0x0078, 0x4727,
-	0x70ab, 0x3ffc, 0x0078, 0x2459, 0x0078, 0x3fe8, 0x1078, 0x23eb,
-	0x70ab, 0x4004, 0x0078, 0x2459, 0x1078, 0x473f, 0x0078, 0x2459,
-	0x70a7, 0x400c, 0x0078, 0x4739, 0x2011, 0x0005, 0x1078, 0x42eb,
-	0x0079, 0x4012, 0x4017, 0x2459, 0x3b96, 0x401f, 0x4027, 0xa6b4,
-	0x00ff, 0xa6b5, 0x0800, 0x6eb6, 0x7e5a, 0x0078, 0x4727, 0xa6b4,
-	0x00ff, 0xa6b5, 0x0800, 0x6eb6, 0x7e5a, 0x0078, 0x4727, 0x70ab,
-	0x402b, 0x0078, 0x2459, 0x0078, 0x4017, 0xa286, 0x0001, 0x0040,
-	0x4033, 0x1078, 0x23eb, 0x70a7, 0x4037, 0x0078, 0x4739, 0x2011,
-	0x0006, 0x1078, 0x42eb, 0x0079, 0x403d, 0x4042, 0x2459, 0x3b96,
-	0x4048, 0x4052, 0xa6b5, 0x0800, 0x6eb6, 0x7e5a, 0x0078, 0x4727,
-	0xa6b4, 0x00ff, 0xa6b5, 0x0800, 0x6eb6, 0xa6b5, 0x4000, 0x7e5a,
-	0x0078, 0x4727, 0x70ab, 0x4056, 0x0078, 0x2459, 0x0078, 0x4042,
-	0x2300, 0x0079, 0x405b, 0x4060, 0x405e, 0x405e, 0x1078, 0x23eb,
-	0x1078, 0x23eb, 0x2300, 0x71a8, 0xa005, 0x017a, 0x6810, 0x70be,
-	0xa282, 0x0003, 0x0050, 0x406e, 0x1078, 0x23eb, 0x2300, 0x0079,
-	0x4071, 0x4074, 0x4082, 0x40a4, 0xa684, 0x0200, 0x0040, 0x407c,
-	0x1078, 0x46f8, 0x1078, 0x46ff, 0x2001, 0x0001, 0x1078, 0x4691,
-	0x0078, 0x2459, 0xa296, 0x0002, 0x0040, 0x408b, 0x82ff, 0x0040,
-	0x408b, 0x1078, 0x23eb, 0x70a7, 0x408f, 0x0078, 0x4739, 0x2011,
-	0x0018, 0x1078, 0x42eb, 0x0079, 0x4095, 0x409a, 0x2459, 0x3b96,
-	0x409c, 0x409e, 0x0078, 0x4727, 0x0078, 0x4727, 0x70ab, 0x40a2,
-	0x0078, 0x2459, 0x0078, 0x409a, 0x2200, 0x0079, 0x40a7, 0x40a9,
-	0x40c2, 0x70a7, 0x40ad, 0x0078, 0x4739, 0x2011, 0x0017, 0x1078,
-	0x42eb, 0x0079, 0x40b3, 0x40b8, 0x2459, 0x3b96, 0x40ba, 0x40bc,
-	0x0078, 0x4727, 0x0078, 0x4727, 0x70ab, 0x40c0, 0x0078, 0x2459,
-	0x0078, 0x40b8, 0xa484, 0x8000, 0x00c0, 0x410c, 0xa684, 0x0100,
-	0x0040, 0x40d6, 0x1078, 0x46f8, 0x1078, 0x42d3, 0x1078, 0x46ff,
-	0x7848, 0xa085, 0x000c, 0x784a, 0x0078, 0x40da, 0x78d8, 0x78d2,
-	0x78dc, 0x78d6, 0xa6b4, 0xefff, 0x7e5a, 0x70a7, 0x40e1, 0x0078,
-	0x4739, 0x2011, 0x000d, 0x1078, 0x42eb, 0x0079, 0x40e7, 0x40ee,
-	0x2459, 0x3b96, 0x40ee, 0x40fc, 0x4102, 0x4104, 0xa684, 0x0100,
-	0x0040, 0x40fa, 0x1078, 0x46b6, 0x682c, 0x78d2, 0x6830, 0x78d6,
-	0x1078, 0x46f0, 0x0078, 0x4727, 0x70ab, 0x4100, 0x0078, 0x2459,
-	0x0078, 0x40ee, 0x1078, 0x23eb, 0x70ab, 0x4108, 0x0078, 0x2459,
-	0x1078, 0x473f, 0x0078, 0x2459, 0x1078, 0x46ff, 0x70ab, 0x4116,
-	0x2001, 0x0003, 0x1078, 0x4689, 0x0078, 0x4733, 0x1078, 0x46f0,
-	0x682c, 0x78d2, 0x6830, 0x78d6, 0x0078, 0x4727, 0x70b8, 0x6812,
-	0x70be, 0x8000, 0x70ba, 0x681b, 0x0000, 0xa684, 0x0008, 0x0040,
-	0x4141, 0x157e, 0x137e, 0x147e, 0x7890, 0x8004, 0x8004, 0x8004,
-	0x8004, 0xa084, 0x000f, 0x681a, 0x80ac, 0x789b, 0x0000, 0xaf80,
-	0x002b, 0x2098, 0xad80, 0x000b, 0x20a0, 0x53a5, 0x147f, 0x137f,
-	0x157f, 0xa6c4, 0x0f00, 0xa684, 0x0002, 0x00c0, 0x4150, 0x692c,
-	0x810d, 0x810d, 0x810d, 0xa184, 0x0007, 0x2008, 0x0078, 0x415f,
-	0x789b, 0x0010, 0x79ac, 0xa184, 0x0020, 0x0040, 0x415f, 0x017e,
-	0x2009, 0x0005, 0x2001, 0x3d00, 0x1078, 0x46c1, 0x017f, 0xa184,
-	0x001f, 0xa805, 0x6816, 0x1078, 0x3b69, 0x68be, 0xa684, 0x0004,
-	0x0040, 0x4170, 0xa18c, 0xff00, 0x78a8, 0xa084, 0x00ff, 0xa105,
-	0x682a, 0xa6b4, 0x00ff, 0x6000, 0xa084, 0x0008, 0x0040, 0x417a,
-	0xa6b5, 0x4000, 0x6eb6, 0x007c, 0x157e, 0x137e, 0x147e, 0x6918,
-	0x7890, 0x8004, 0x8004, 0x8004, 0x8004, 0xa084, 0x000f, 0x007e,
-	0xa100, 0x681a, 0x007f, 0x8000, 0x8004, 0x0040, 0x419b, 0x20a8,
-	0x8104, 0xa080, 0x000b, 0xad00, 0x20a0, 0x789b, 0x0000, 0xaf80,
-	0x002b, 0x2098, 0x53a5, 0x147f, 0x137f, 0x157f, 0x007c, 0x682c,
-	0xa084, 0x0020, 0x00c0, 0x41a7, 0x620c, 0x0078, 0x41a8, 0x6210,
-	0x6b18, 0x2300, 0xa202, 0x0040, 0x41c8, 0x2018, 0xa382, 0x000e,
-	0x0048, 0x41b8, 0x0040, 0x41b8, 0x2019, 0x000e, 0x0078, 0x41bc,
-	0x7858, 0xa084, 0xffef, 0x785a, 0x783b, 0x1b01, 0x7893, 0x0000,
-	0x7ba2, 0x70b4, 0xa080, 0x008e, 0x781a, 0xa085, 0x0001, 0x007c,
-	0x7858, 0xa084, 0xffef, 0x785a, 0x7893, 0x0000, 0xa006, 0x007c,
-	0x6904, 0xa18c, 0x00ff, 0xa196, 0x0007, 0x0040, 0x41dd, 0xa196,
-	0x000f, 0x0040, 0x41dd, 0x6807, 0x0117, 0x6914, 0x1078, 0x3b69,
-	0x6100, 0x8104, 0x00c8, 0x41f8, 0x601c, 0xa005, 0x0040, 0x41ec,
-	0x2001, 0x0800, 0x0078, 0x41fa, 0x0d7e, 0x6824, 0x007e, 0x1078,
-	0x4708, 0x007f, 0x6826, 0x2d00, 0x682e, 0x1078, 0x3af8, 0x0d7f,
-	0x2001, 0x0200, 0x6826, 0x8007, 0x789b, 0x000e, 0x78aa, 0x6820,
-	0xa085, 0x8000, 0x6822, 0x2031, 0x0400, 0x6eb6, 0x7e5a, 0x71b4,
-	0xa188, 0x0091, 0x791a, 0x007c, 0xa6c4, 0x0f00, 0xa684, 0x0002,
-	0x00c0, 0x4220, 0x692c, 0x810d, 0x810d, 0x810d, 0xa184, 0x0007,
-	0x2008, 0xa805, 0x6816, 0x1078, 0x3b69, 0x68be, 0x0078, 0x4223,
-	0x6914, 0x1078, 0x3b69, 0x6100, 0x8104, 0x00c8, 0x4280, 0xa184,
-	0x0300, 0x0040, 0x422f, 0x6807, 0x0117, 0x0078, 0x424d, 0x6004,
-	0xa005, 0x00c0, 0x4256, 0x6807, 0x0117, 0x601c, 0xa005, 0x00c0,
-	0x4243, 0x0d7e, 0x1078, 0x4708, 0x6827, 0x0034, 0x2d00, 0x682e,
-	0x1078, 0x3af8, 0x0d7f, 0xa684, 0x0004, 0x0040, 0x424d, 0x2031,
-	0x0400, 0x2001, 0x2800, 0x0078, 0x4251, 0x2031, 0x0400, 0x2001,
-	0x0800, 0x71b4, 0xa188, 0x0091, 0x0078, 0x42ae, 0x6018, 0xa005,
-	0x00c0, 0x4243, 0x601c, 0xa005, 0x00c0, 0x4243, 0x689f, 0x0000,
-	0x6827, 0x003d, 0xa684, 0x0001, 0x0040, 0x42bc, 0xd694, 0x00c0,
-	0x4279, 0x6100, 0xd1d4, 0x0040, 0x4279, 0x692c, 0x81ff, 0x0040,
-	0x42bc, 0xa186, 0x0003, 0x0040, 0x42bc, 0xa186, 0x0012, 0x0040,
-	0x42bc, 0xa6b5, 0x0800, 0x71b4, 0xa188, 0x00af, 0x0078, 0x42b7,
-	0x6807, 0x0117, 0x2031, 0x0400, 0x692c, 0xa18c, 0x00ff, 0xa186,
-	0x0012, 0x00c0, 0x4291, 0x2001, 0x42c9, 0x2009, 0x0001, 0x0078,
-	0x42a2, 0xa186, 0x0003, 0x00c0, 0x429b, 0x2001, 0x42ca, 0x2009,
-	0x0012, 0x0078, 0x42a2, 0x2001, 0x0200, 0x71b4, 0xa188, 0x0091,
-	0x0078, 0x42ae, 0x1078, 0x46db, 0x78a3, 0x0000, 0x681c, 0xa085,
-	0x0040, 0x681e, 0x71b4, 0xa188, 0x00df, 0xa006, 0x6826, 0x8007,
-	0x789b, 0x000e, 0x78aa, 0x6820, 0xa085, 0x8000, 0x6822, 0x6eb6,
-	0x7e5a, 0x791a, 0x0078, 0x2459, 0x6eb6, 0x1078, 0x3af8, 0x6810,
-	0x70be, 0x7003, 0x0007, 0x70a3, 0x0000, 0x704b, 0x0000, 0x0078,
-	0x2459, 0x0023, 0x0070, 0x0005, 0x0000, 0x0a00, 0x0000, 0x0000,
-	0x0025, 0x0000, 0x0000, 0x683b, 0x0000, 0x6837, 0x0000, 0xa684,
-	0x0200, 0x0040, 0x42ea, 0x78b8, 0xa08c, 0x001f, 0xa084, 0x8000,
-	0x0040, 0x42e3, 0x8108, 0x78d8, 0xa100, 0x6836, 0x78dc, 0xa081,
-	0x0000, 0x683a, 0x007c, 0x7990, 0x810f, 0xa5ac, 0x0007, 0x2021,
-	0x0000, 0xa480, 0x0010, 0x789a, 0x79a8, 0xa18c, 0x00ff, 0xa184,
-	0x0080, 0x00c0, 0x4319, 0xa182, 0x0020, 0x00c8, 0x4337, 0xa182,
-	0x0012, 0x00c8, 0x467b, 0x2100, 0x1079, 0x4307, 0x007c, 0x467b,
-	0x44e8, 0x467b, 0x467b, 0x4344, 0x4347, 0x4381, 0x43b7, 0x43eb,
-	0x43ee, 0x467b, 0x467b, 0x43a2, 0x4412, 0x444c, 0x467b, 0x467b,
-	0x4473, 0xa184, 0x0020, 0x00c0, 0x44a7, 0xa18c, 0x001f, 0x6814,
-	0xa084, 0x001f, 0xa106, 0x0040, 0x4334, 0x70b4, 0xa080, 0x00d2,
-	0x781a, 0x2001, 0x0014, 0x1078, 0x4691, 0x1078, 0x46ff, 0x7003,
-	0x0000, 0x2001, 0x0002, 0x007c, 0x2001, 0x0000, 0x007c, 0xa182,
-	0x0024, 0x00c8, 0x467b, 0xa184, 0x0003, 0x1079, 0x4307, 0x007c,
-	0x467b, 0x467b, 0x467b, 0x467b, 0x1078, 0x467b, 0x007c, 0x2200,
-	0x0079, 0x434a, 0x4476, 0x4476, 0x436e, 0x436e, 0x436e, 0x436e,
-	0x436e, 0x436e, 0x436e, 0x436e, 0x436c, 0x436e, 0x4363, 0x436e,
-	0x436e, 0x436e, 0x436e, 0x436e, 0x4376, 0x4379, 0x4476, 0x4379,
-	0x436e, 0x436e, 0x436e, 0x0c7e, 0x077e, 0x6f14, 0x1078, 0x36e2,
-	0x077f, 0x0c7f, 0x0078, 0x436e, 0x1078, 0x458b, 0x6827, 0x02b3,
-	0x2009, 0x000b, 0x2001, 0x4800, 0x0078, 0x44aa, 0x1078, 0x4670,
-	0x007c, 0x6827, 0x0093, 0x2009, 0x000b, 0x2001, 0x4800, 0x0078,
-	0x4492, 0x2d58, 0x6804, 0xa084, 0x00ff, 0xa086, 0x0006, 0x00c0,
-	0x438b, 0x6807, 0x0117, 0x6827, 0x0002, 0x1078, 0x4708, 0x6827,
-	0x0036, 0x6932, 0x2d00, 0x682e, 0x0d7e, 0x1078, 0x3ac8, 0x1078,
-	0x44d0, 0x2b68, 0x1078, 0x3af8, 0x0d7f, 0x1078, 0x3af8, 0x2001,
-	0x0002, 0x007c, 0x1078, 0x44d0, 0x2001, 0x0017, 0x1078, 0x4691,
-	0x70a3, 0x0000, 0x2009, 0x5138, 0x200b, 0x0006, 0x70af, 0x0017,
-	0x2009, 0x0200, 0x1078, 0x3a06, 0x2001, 0x0001, 0x007c, 0x2200,
-	0x0079, 0x43ba, 0x4476, 0x44a7, 0x44a7, 0x44a7, 0x43db, 0x44b7,
-	0x43e3, 0x44b7, 0x44b7, 0x44ba, 0x44ba, 0x44bf, 0x44bf, 0x43d3,
-	0x43d3, 0x44a7, 0x44a7, 0x44b7, 0x44a7, 0x43e3, 0x4476, 0x43e3,
-	0x43e3, 0x43e3, 0x43e3, 0x6827, 0x0084, 0x2009, 0x000b, 0x2001,
-	0x4300, 0x0078, 0x44c9, 0x6827, 0x000d, 0x2009, 0x000b, 0x2001,
-	0x4300, 0x0078, 0x44aa, 0x6827, 0x0093, 0x2009, 0x000b, 0x2001,
-	0x4300, 0x0078, 0x4492, 0x2001, 0x0000, 0x007c, 0x2200, 0x0079,
-	0x43f1, 0x4476, 0x440a, 0x440a, 0x440a, 0x440a, 0x44b7, 0x44b7,
-	0x44b7, 0x44b7, 0x44b7, 0x44b7, 0x44b7, 0x44b7, 0x440a, 0x440a,
-	0x440a, 0x440a, 0x44b7, 0x440a, 0x440a, 0x44b7, 0x44b7, 0x44b7,
-	0x44b7, 0x4476, 0x6827, 0x0093, 0x2009, 0x000b, 0x2001, 0x4300,
-	0x0078, 0x4492, 0xa684, 0x0004, 0x00c0, 0x4426, 0x6804, 0xa084,
-	0x00ff, 0xa086, 0x0006, 0x00c0, 0x467b, 0x1078, 0x44d0, 0x6807,
-	0x0117, 0x1078, 0x3af8, 0x2001, 0x0002, 0x007c, 0x6000, 0xa084,
-	0x0004, 0x0040, 0x467b, 0x2d58, 0x6804, 0xa084, 0x00ff, 0xa086,
-	0x0006, 0x00c0, 0x4435, 0x6807, 0x0117, 0x6827, 0x0002, 0x1078,
-	0x4708, 0x6827, 0x0036, 0x6932, 0x2d00, 0x682e, 0x0d7e, 0x1078,
-	0x3ad7, 0x1078, 0x44d0, 0x2b68, 0x1078, 0x3af8, 0x0d7f, 0x1078,
-	0x3af8, 0x2001, 0x0002, 0x007c, 0x6000, 0xa084, 0x0004, 0x0040,
-	0x467b, 0x2d58, 0x6a04, 0xa294, 0x00ff, 0xa286, 0x0006, 0x00c0,
-	0x445b, 0x6807, 0x0117, 0x6827, 0x0002, 0x2d58, 0x1078, 0x4708,
-	0x6827, 0x0036, 0x6932, 0x2d00, 0x682e, 0x0d7e, 0x1078, 0x3ae7,
-	0x1078, 0x44d0, 0x2b68, 0x1078, 0x3af8, 0x0d7f, 0x1078, 0x3af8,
-	0x2001, 0x0002, 0x007c, 0x1078, 0x467b, 0x007c, 0x70b4, 0xa080,
-	0x00d2, 0x781a, 0x2001, 0x0001, 0x1078, 0x4691, 0x1078, 0x46ff,
-	0x7003, 0x0000, 0x2001, 0x0002, 0x007c, 0x1078, 0x46c1, 0x1078,
-	0x46f8, 0x1078, 0x42d3, 0x1078, 0x41d0, 0x1078, 0x46ff, 0x2001,
-	0x0001, 0x007c, 0x1078, 0x46c1, 0x1078, 0x46f8, 0x1078, 0x42d3,
-	0x70b4, 0xa080, 0x00d2, 0x781a, 0x2001, 0x0013, 0x1078, 0x4691,
-	0x1078, 0x46ff, 0x7003, 0x0000, 0x2001, 0x0002, 0x007c, 0x1078,
-	0x467b, 0x007c, 0x1078, 0x46c1, 0x1078, 0x46f8, 0x1078, 0x42d3,
-	0x1078, 0x41d0, 0x1078, 0x46ff, 0x2001, 0x0001, 0x007c, 0x2001,
-	0x0003, 0x007c, 0x1078, 0x458b, 0x2001, 0x0000, 0x007c, 0x0c7e,
-	0x077e, 0x6f14, 0x1078, 0x36e2, 0x077f, 0x0c7f, 0x2001, 0x0000,
-	0x007c, 0x1078, 0x46c1, 0x1078, 0x467b, 0x2001, 0x0006, 0x007c,
-	0x6904, 0xa18c, 0x00ff, 0xa186, 0x0007, 0x0040, 0x44db, 0xa186,
-	0x000f, 0x00c0, 0x44df, 0x1078, 0x46f8, 0x1078, 0x42d3, 0x70b4,
-	0xa080, 0x00d2, 0x781a, 0x1078, 0x46ff, 0x7003, 0x0000, 0x007c,
-	0x7aa8, 0xa294, 0x00ff, 0x78a8, 0xa084, 0x00ff, 0xa08a, 0x0004,
-	0x00c8, 0x467b, 0x1079, 0x44f5, 0x007c, 0x467b, 0x44f9, 0x467b,
-	0x4592, 0xa282, 0x0003, 0x0040, 0x4500, 0x1078, 0x467b, 0x007c,
-	0x7da8, 0xa5ac, 0x00ff, 0x7ca8, 0xa4a4, 0x00ff, 0x69b8, 0xa184,
-	0x0100, 0x0040, 0x453f, 0xa18c, 0xfeff, 0x69ba, 0x78a0, 0xa005,
-	0x00c0, 0x453f, 0xa4a4, 0x00ff, 0x0040, 0x4533, 0xa482, 0x000c,
-	0x0040, 0x451c, 0x00c8, 0x4526, 0x852b, 0x852b, 0x1078, 0x3760,
-	0x0040, 0x4526, 0x1078, 0x355b, 0x0078, 0x4535, 0x1078, 0x465d,
-	0x1078, 0x3586, 0x69b8, 0xa18d, 0x0100, 0x69ba, 0xa6b5, 0x1000,
-	0x7e5a, 0x0078, 0x4538, 0x1078, 0x3586, 0xa6b4, 0xefff, 0x7e5a,
-	0x70b4, 0xa080, 0x0091, 0x781a, 0x2001, 0x0001, 0x007c, 0x0c7e,
-	0x1078, 0x457f, 0x6200, 0xd2e4, 0x0040, 0x4570, 0x6208, 0x8217,
-	0xa294, 0x00ff, 0xa282, 0x000c, 0x0048, 0x4552, 0x0040, 0x4552,
-	0x2011, 0x000c, 0x2400, 0xa202, 0x00c8, 0x4557, 0x2220, 0x6208,
-	0xa294, 0x00ff, 0x701c, 0xa202, 0x00c8, 0x455f, 0x721c, 0x2200,
-	0xa502, 0x00c8, 0x4564, 0x2228, 0x1078, 0x4661, 0x852b, 0x852b,
-	0x1078, 0x3760, 0x0040, 0x4570, 0x1078, 0x3562, 0x0078, 0x4574,
-	0x1078, 0x465d, 0x1078, 0x358d, 0xa6b5, 0x1000, 0x7e5a, 0x70b4,
-	0xa080, 0x00be, 0x781a, 0x2001, 0x0004, 0x0c7f, 0x007c, 0x007e,
-	0x6814, 0x8007, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xa0e0,
-	0x5380, 0x007f, 0x007c, 0x0c7e, 0x1078, 0x457f, 0x1078, 0x358d,
-	0x0c7f, 0x007c, 0xa282, 0x0002, 0x00c0, 0x467b, 0x7aa8, 0xa294,
-	0x00ff, 0x69b8, 0xa184, 0x0200, 0x0040, 0x45c9, 0xa18c, 0xfdff,
-	0x69ba, 0x78a0, 0xa005, 0x00c0, 0x45c9, 0xa282, 0x0002, 0x00c8,
-	0x369d, 0x1078, 0x4627, 0x1078, 0x362b, 0x1078, 0x3586, 0xa684,
-	0x0100, 0x0040, 0x45bf, 0x682c, 0xa084, 0x0001, 0x0040, 0x45bf,
-	0xc6fc, 0x7888, 0xa084, 0x0040, 0x0040, 0x45bf, 0xc6fd, 0xa6b5,
-	0x1000, 0x7e5a, 0x70b4, 0xa080, 0x0091, 0x781a, 0x2001, 0x0001,
-	0x007c, 0x0c7e, 0x1078, 0x457f, 0xa284, 0xfffe, 0x0040, 0x45d4,
-	0x2011, 0x0001, 0x0078, 0x45d8, 0xa284, 0x0001, 0x0040, 0x45de,
-	0x6100, 0xd1ec, 0x00c0, 0x45de, 0x2011, 0x0000, 0x1078, 0x4619,
-	0x1078, 0x3632, 0x1078, 0x358d, 0xa684, 0x0100, 0x0040, 0x45f4,
-	0x682c, 0xa084, 0x0001, 0x0040, 0x45f4, 0xc6fc, 0x7888, 0xa084,
-	0x0040, 0x0040, 0x45f4, 0xc6fd, 0xa6b5, 0x1000, 0x7e5a, 0x70b4,
-	0xa080, 0x00be, 0x781a, 0x2001, 0x0004, 0x0c7f, 0x007c, 0x0c7e,
-	0x2960, 0x6000, 0x2011, 0x0001, 0xa084, 0x2000, 0x00c0, 0x460a,
-	0x2011, 0x0000, 0x78ab, 0x0001, 0x78ab, 0x0002, 0x78ab, 0x0003,
-	0x7aaa, 0xa8c0, 0x0004, 0x68b8, 0xa085, 0x0200, 0x68ba, 0x0c7f,
-	0x007c, 0x789b, 0x0018, 0x78ab, 0x0001, 0x78ab, 0x0002, 0x78ab,
-	0x0003, 0x7aaa, 0x789b, 0x0081, 0x78ab, 0x0004, 0x007c, 0x0c7e,
-	0x7054, 0x2060, 0x6000, 0xa084, 0x1000, 0x00c0, 0x4635, 0x2029,
-	0x0032, 0x2021, 0x0000, 0x0078, 0x4655, 0x6508, 0xa5ac, 0x00ff,
-	0x7018, 0xa086, 0x0028, 0x00c0, 0x4645, 0xa582, 0x0019, 0x00c8,
-	0x464b, 0x2029, 0x0019, 0x0078, 0x464b, 0xa582, 0x000c, 0x00c8,
-	0x464b, 0x2029, 0x000c, 0x6408, 0x8427, 0xa4a4, 0x00ff, 0xa482,
-	0x000c, 0x0048, 0x4655, 0x2021, 0x000c, 0x1078, 0x4661, 0x68b8,
-	0xa085, 0x0100, 0x68ba, 0x0c7f, 0x007c, 0x2021, 0x0000, 0x2029,
-	0x0032, 0x789b, 0x0018, 0x78ab, 0x0001, 0x78ab, 0x0003, 0x78ab,
-	0x0001, 0x7daa, 0x7caa, 0x789b, 0x0081, 0x78ab, 0x0005, 0x007c,
-	0x2001, 0x0003, 0x1078, 0x4689, 0x70b4, 0xa080, 0x00be, 0x781a,
-	0x2001, 0x0005, 0x007c, 0x2001, 0x0007, 0x1078, 0x4689, 0xa6b5,
-	0x1000, 0x7e5a, 0x70b4, 0xa080, 0x00be, 0x781a, 0x2001, 0x0004,
-	0x007c, 0x789b, 0x0018, 0x78aa, 0x789b, 0x0081, 0x78ab, 0x0001,
-	0x007c, 0x6904, 0xa18c, 0x00ff, 0xa196, 0x0007, 0x0040, 0x469f,
-	0xa196, 0x000f, 0x0040, 0x469f, 0x1078, 0x195a, 0x007c, 0x6924,
-	0xa194, 0x003f, 0x00c0, 0x46a8, 0xa18c, 0xffc0, 0xa105, 0x6826,
-	0x1078, 0x3af8, 0x691c, 0xa184, 0x0100, 0x0040, 0x46b5, 0x6914,
-	0x1078, 0x3b69, 0x6204, 0x8210, 0x6206, 0x007c, 0x692c, 0x6834,
-	0x682e, 0xa112, 0x6930, 0x6838, 0x6832, 0xa11b, 0xa200, 0xa301,
-	0x007c, 0x0c7e, 0xade0, 0x0018, 0x6003, 0x0070, 0x6106, 0x600b,
-	0x0000, 0x600f, 0x0a00, 0x6013, 0x0000, 0x6017, 0x0000, 0x8007,
-	0x601a, 0x601f, 0x0000, 0x6023, 0x0000, 0x0c7f, 0x6824, 0xa085,
-	0x0080, 0x6826, 0x007c, 0x157e, 0x137e, 0x147e, 0x2098, 0xaf80,
-	0x002d, 0x20a0, 0x81ac, 0x0040, 0x46e6, 0x53a6, 0xa184, 0x0001,
-	0x0040, 0x46ec, 0x3304, 0x78be, 0x147f, 0x137f, 0x157f, 0x007c,
-	0x70b0, 0xa005, 0x10c0, 0x23eb, 0x70b3, 0x8000, 0x0078, 0x4a3a,
-	0x71b0, 0x81ff, 0x0040, 0x46fe, 0x1078, 0x4b30, 0x007c, 0x71b0,
-	0x81ff, 0x0040, 0x4707, 0x70b3, 0x0000, 0x1078, 0x4776, 0x007c,
-	0x0c7e, 0x0d7e, 0x1078, 0x1937, 0x0c7f, 0x157e, 0x137e, 0x147e,
-	0x2da0, 0x2c98, 0x20a9, 0x0031, 0x53a3, 0x147f, 0x137f, 0x157f,
-	0x6807, 0x010d, 0x680b, 0x0000, 0x7004, 0x8007, 0x681a, 0x6823,
-	0x0000, 0x681f, 0x0000, 0x689f, 0x0000, 0x0c7f, 0x007c, 0x70b4,
-	0xa080, 0x0091, 0x781a, 0x0078, 0x2459, 0x70b4, 0xa080, 0x0081,
-	0x781a, 0x0078, 0x2459, 0x70b4, 0xa080, 0x00be, 0x781a, 0x0078,
-	0x2459, 0x70b4, 0xa080, 0x00c8, 0x781a, 0x0078, 0x2459, 0x6904,
-	0xa18c, 0x00ff, 0xa196, 0x0007, 0x0040, 0x474c, 0xa196, 0x000f,
-	0x0040, 0x474c, 0x6807, 0x0117, 0x2001, 0x0200, 0x6826, 0x8007,
-	0x789b, 0x000e, 0x78aa, 0x6820, 0xa085, 0x8000, 0x6822, 0x2031,
-	0x0400, 0x6eb6, 0x7e5a, 0x71b4, 0xa188, 0x0091, 0x791a, 0x007c,
-	0x1078, 0x46ff, 0x7848, 0xa085, 0x000c, 0x784a, 0x70b4, 0xa080,
-	0x00d2, 0x781a, 0x2009, 0x000b, 0x2001, 0x4400, 0x1078, 0x46c1,
-	0x2001, 0x0013, 0x1078, 0x4691, 0x0078, 0x3b96, 0x127e, 0x2091,
-	0x2200, 0x2049, 0x4776, 0x7000, 0x7204, 0xa205, 0x720c, 0xa215,
-	0x7008, 0xa084, 0xfff7, 0xa205, 0x0040, 0x4788, 0x0078, 0x478d,
-	0x7003, 0x0000, 0x127f, 0x2000, 0x007c, 0x7000, 0xa084, 0x0001,
-	0x00c0, 0x47bb, 0x7108, 0x8103, 0x00c8, 0x479a, 0x1078, 0x48bd,
-	0x0078, 0x4792, 0x700c, 0xa08c, 0x00ff, 0x0040, 0x47bb, 0x7004,
-	0x8004, 0x00c8, 0x47b2, 0x7014, 0xa005, 0x00c0, 0x47ae, 0x7010,
-	0xa005, 0x0040, 0x47b2, 0xa102, 0x00c8, 0x4792, 0x7007, 0x0010,
-	0x0078, 0x47bb, 0x8aff, 0x0040, 0x47bb, 0x1078, 0x4b07, 0x00c0,
-	0x47b5, 0x0040, 0x4792, 0x1078, 0x4846, 0x7003, 0x0000, 0x127f,
-	0x2000, 0x007c, 0x017e, 0x6104, 0xa18c, 0x00ff, 0xa186, 0x0007,
-	0x0040, 0x47ce, 0xa18e, 0x000f, 0x00c0, 0x47d1, 0x6040, 0x0078,
-	0x47d2, 0x6428, 0x017f, 0x84ff, 0x0040, 0x47fc, 0x2c70, 0x7004,
-	0xa0bc, 0x000f, 0xa7b8, 0x480c, 0x273c, 0x87fb, 0x00c0, 0x47ea,
-	0x0048, 0x47e4, 0x1078, 0x23eb, 0x609c, 0xa075, 0x0040, 0x47fc,
-	0x0078, 0x47d7, 0x2704, 0xae68, 0x6808, 0xa630, 0x680c, 0xa529,
-	0x8421, 0x0040, 0x47fc, 0x8738, 0x2704, 0xa005, 0x00c0, 0x47eb,
-	0x709c, 0xa075, 0x00c0, 0x47d7, 0x007c, 0x0000, 0x0005, 0x0009,
-	0x000d, 0x0011, 0x0015, 0x0019, 0x001d, 0x0000, 0x0003, 0x0009,
-	0x000f, 0x0015, 0x001b, 0x0000, 0x0000, 0x4801, 0x47fe, 0x0000,
-	0x0000, 0x8000, 0x0000, 0x4801, 0x0000, 0x4809, 0x4806, 0x0000,
-	0x0000, 0x0000, 0x0000, 0x4809, 0x0000, 0x4804, 0x4804, 0x0000,
-	0x0000, 0x8000, 0x0000, 0x4804, 0x0000, 0x480a, 0x480a, 0x0000,
-	0x0000, 0x0000, 0x0000, 0x480a, 0x127e, 0x2091, 0x2200, 0x2079,
-	0x5100, 0x2071, 0x0010, 0x7007, 0x000a, 0x7007, 0x0002, 0x7003,
-	0x0000, 0x2071, 0x0020, 0x7007, 0x000a, 0x7007, 0x0002, 0x7003,
-	0x0000, 0x2049, 0x0000, 0x127f, 0x2000, 0x007c, 0x2049, 0x4846,
-	0x2019, 0x0000, 0x7004, 0x8004, 0x00c8, 0x4899, 0x7007, 0x0012,
-	0x7108, 0x7008, 0xa106, 0x00c0, 0x4850, 0xa184, 0x01e0, 0x0040,
-	0x485b, 0x1078, 0x23eb, 0x2001, 0x04fd, 0x2004, 0xa082, 0x0005,
-	0x00c8, 0x4866, 0xa184, 0x4000, 0x00c0, 0x4850, 0xa19c, 0x300c,
-	0xa386, 0x2004, 0x0040, 0x4874, 0xa386, 0x0008, 0x0040, 0x487f,
-	0xa386, 0x200c, 0x00c0, 0x4850, 0x7200, 0x8204, 0x0048, 0x487f,
-	0x730c, 0xa384, 0x00ff, 0x0040, 0x487f, 0x1078, 0x23eb, 0x7007,
-	0x0012, 0x7000, 0xa084, 0x0001, 0x00c0, 0x4899, 0x7008, 0xa084,
-	0x01e0, 0x00c0, 0x4899, 0x7310, 0x7014, 0xa305, 0x0040, 0x4899,
-	0x710c, 0xa184, 0x0300, 0x00c0, 0x4899, 0xa184, 0x00ff, 0x00c0,
-	0x4846, 0x7007, 0x0012, 0x7007, 0x0008, 0x7004, 0xa084, 0x0008,
-	0x00c0, 0x489d, 0x7007, 0x0012, 0x7108, 0x8103, 0x0048, 0x48a2,
-	0x7003, 0x0000, 0x2049, 0x0000, 0x007c, 0x107e, 0x007e, 0x127e,
-	0x157e, 0x2091, 0x2200, 0x7108, 0x1078, 0x48bd, 0x157f, 0x127f,
-	0x2091, 0x8001, 0x007f, 0x107f, 0x007c, 0x7204, 0x7500, 0x730c,
-	0xa384, 0x0300, 0x00c0, 0x48e4, 0xa184, 0x01e0, 0x00c0, 0x4908,
-	0x7108, 0xa184, 0x01e0, 0x00c0, 0x4908, 0x2001, 0x04fd, 0x2004,
-	0xa082, 0x0005, 0x00c8, 0x48d8, 0xa184, 0x4000, 0x00c0, 0x48c8,
-	0xa184, 0x0007, 0x0079, 0x48dc, 0x48e6, 0x48f8, 0x48e4, 0x48f8,
-	0x48e4, 0x4944, 0x48e4, 0x4942, 0x1078, 0x23eb, 0x7004, 0xa084,
-	0x0010, 0xa085, 0x0002, 0x7006, 0x8aff, 0x00c0, 0x48f3, 0x2049,
-	0x0000, 0x0078, 0x48f7, 0x1078, 0x4b07, 0x00c0, 0x48f3, 0x007c,
-	0x7004, 0xa084, 0x0010, 0xa085, 0x0002, 0x7006, 0x8aff, 0x00c0,
-	0x4903, 0x0078, 0x4907, 0x1078, 0x4b07, 0x00c0, 0x4903, 0x007c,
-	0x7007, 0x0012, 0x7108, 0x00e0, 0x490b, 0x2091, 0x6000, 0x00e0,
-	0x490f, 0x2091, 0x6000, 0x7007, 0x0012, 0x7007, 0x0008, 0x7004,
-	0xa084, 0x0008, 0x00c0, 0x4917, 0x7007, 0x0012, 0x7108, 0x8103,
-	0x0048, 0x491c, 0x7003, 0x0000, 0x7000, 0xa005, 0x00c0, 0x4930,
-	0x7004, 0xa005, 0x00c0, 0x4930, 0x700c, 0xa005, 0x0040, 0x4932,
-	0x0078, 0x4913, 0x2049, 0x0000, 0x1078, 0x3809, 0x6818, 0xa084,
-	0x8000, 0x0040, 0x493d, 0x681b, 0x0002, 0x007c, 0x1078, 0x23eb,
-	0x1078, 0x23eb, 0x1078, 0x49a0, 0x7210, 0x7114, 0x700c, 0xa09c,
-	0x00ff, 0x2800, 0xa300, 0xa211, 0xa189, 0x0000, 0x1078, 0x49a0,
-	0x2704, 0x2c58, 0xac60, 0x6308, 0x2200, 0xa322, 0x630c, 0x2100,
-	0xa31b, 0x2400, 0xa305, 0x0040, 0x4967, 0x00c8, 0x4967, 0x8412,
-	0x8210, 0x830a, 0xa189, 0x0000, 0x2b60, 0x0078, 0x494e, 0x2b60,
-	0x8a07, 0x007e, 0x6004, 0xa084, 0x0008, 0x0040, 0x4973, 0xa7ba,
-	0x4806, 0x0078, 0x4975, 0xa7ba, 0x47fe, 0x007f, 0xa73d, 0x2c00,
-	0x6886, 0x6f8a, 0x6c92, 0x6b8e, 0x7007, 0x0012, 0x1078, 0x4846,
-	0x007c, 0x8738, 0x2704, 0xa005, 0x00c0, 0x4994, 0x609c, 0xa005,
-	0x0040, 0x499d, 0x2060, 0x6004, 0xa084, 0x000f, 0xa080, 0x480c,
-	0x203c, 0x87fb, 0x1040, 0x23eb, 0x8a51, 0x0040, 0x499c, 0x7008,
-	0xa084, 0x0003, 0xa086, 0x0003, 0x007c, 0x2051, 0x0000, 0x007c,
-	0x8a50, 0x8739, 0x2704, 0xa004, 0x00c0, 0x49b4, 0x6000, 0xa064,
-	0x00c0, 0x49ab, 0x2d60, 0x6004, 0xa084, 0x000f, 0xa080, 0x481c,
-	0x203c, 0x87fb, 0x1040, 0x23eb, 0x007c, 0x127e, 0x0d7e, 0x2091,
-	0x2200, 0x0d7f, 0x6884, 0x2060, 0x6888, 0x6b8c, 0x6c90, 0x8057,
-	0xaad4, 0x00ff, 0xa084, 0x00ff, 0x007e, 0x6804, 0xa084, 0x0008,
-	0x007f, 0x0040, 0x49cf, 0xa0b8, 0x4806, 0x0078, 0x49d1, 0xa0b8,
-	0x47fe, 0x7e08, 0xa6b5, 0x000c, 0x6904, 0xa18c, 0x00ff, 0xa186,
-	0x0007, 0x0040, 0x49df, 0xa18e, 0x000f, 0x00c0, 0x49e8, 0x681c,
-	0xa084, 0x0040, 0x0040, 0x49ef, 0xa6b5, 0x0001, 0x0078, 0x49ef,
-	0x681c, 0xa084, 0x0040, 0x0040, 0x49ef, 0xa6b5, 0x0001, 0x7007,
-	0x0004, 0x7004, 0xa084, 0x0004, 0x00c0, 0x49f1, 0x2400, 0xa305,
-	0x00c0, 0x49fc, 0x0078, 0x4a22, 0x2c58, 0x2704, 0x6104, 0xac60,
-	0x6000, 0xa400, 0x701a, 0x6004, 0xa301, 0x701e, 0xa184, 0x0008,
-	0x0040, 0x4a12, 0x6010, 0xa081, 0x0000, 0x7022, 0x6014, 0xa081,
-	0x0000, 0x7026, 0x6208, 0x2400, 0xa202, 0x7012, 0x620c, 0x2300,
-	0xa203, 0x7016, 0x7602, 0x7007, 0x0001, 0x2b60, 0x1078, 0x4981,
-	0x0078, 0x4a24, 0x1078, 0x4b07, 0x00c0, 0x4a22, 0x127f, 0x2000,
-	0x007c, 0x127e, 0x0d7e, 0x2091, 0x2200, 0x0d7f, 0x7007, 0x0004,
-	0x7004, 0xa084, 0x0004, 0x00c0, 0x4a30, 0x7003, 0x0008, 0x127f,
-	0x2000, 0x007c, 0x127e, 0x0d7e, 0x2091, 0x2200, 0x0d7f, 0x2049,
-	0x4a3a, 0x7007, 0x0004, 0x7004, 0xa084, 0x0004, 0x00c0, 0x4a43,
-	0x7e08, 0xa6b5, 0x000c, 0x6904, 0xa18c, 0x00ff, 0xa186, 0x0007,
-	0x0040, 0x4a56, 0xa18e, 0x000f, 0x00c0, 0x4a61, 0x681c, 0xa084,
-	0x0040, 0x0040, 0x4a5d, 0xa6b5, 0x0001, 0x6840, 0x2050, 0x0078,
-	0x4a6a, 0x681c, 0xa084, 0x0020, 0x00c0, 0x4a68, 0xa6b5, 0x0001,
-	0x6828, 0x2050, 0x2d60, 0x6004, 0xa0bc, 0x000f, 0xa7b8, 0x480c,
-	0x273c, 0x87fb, 0x00c0, 0x4a7e, 0x0048, 0x4a78, 0x1078, 0x23eb,
-	0x689c, 0xa065, 0x0040, 0x4a82, 0x0078, 0x4a6b, 0x1078, 0x4b07,
-	0x00c0, 0x4a7e, 0x127f, 0x2000, 0x007c, 0x127e, 0x007e, 0x017e,
-	0x0d7e, 0x2091, 0x2200, 0x0d7f, 0x037f, 0x047f, 0x7e08, 0xa6b5,
-	0x000c, 0x6904, 0xa18c, 0x00ff, 0xa186, 0x0007, 0x0040, 0x4a9c,
-	0xa18e, 0x000f, 0x00c0, 0x4aa5, 0x681c, 0xa084, 0x0040, 0x0040,
-	0x4aac, 0xa6b5, 0x0001, 0x0078, 0x4aac, 0x681c, 0xa084, 0x0040,
-	0x0040, 0x4aac, 0xa6b5, 0x0001, 0x2049, 0x4a85, 0x017e, 0x6904,
-	0xa18c, 0x00ff, 0xa186, 0x0007, 0x0040, 0x4aba, 0xa18e, 0x000f,
-	0x00c0, 0x4abd, 0x6840, 0x0078, 0x4abe, 0x6828, 0x017f, 0xa055,
-	0x0040, 0x4b04, 0x2d70, 0x2e60, 0x7004, 0xa0bc, 0x000f, 0xa7b8,
-	0x480c, 0x273c, 0x87fb, 0x00c0, 0x4ad8, 0x0048, 0x4ad1, 0x1078,
-	0x23eb, 0x709c, 0xa075, 0x2060, 0x0040, 0x4b04, 0x0078, 0x4ac4,
-	0x2704, 0xae68, 0x6808, 0xa422, 0x680c, 0xa31b, 0x0048, 0x4af1,
-	0x8a51, 0x00c0, 0x4ae5, 0x1078, 0x23eb, 0x8738, 0x2704, 0xa005,
-	0x00c0, 0x4ad9, 0x709c, 0xa075, 0x2060, 0x0040, 0x4b04, 0x0078,
-	0x4ac4, 0x8422, 0x8420, 0x831a, 0xa399, 0x0000, 0x6908, 0x2400,
-	0xa122, 0x690c, 0x2300, 0xa11b, 0x00c8, 0x4b00, 0x1078, 0x23eb,
-	0x2071, 0x0020, 0x0078, 0x49ef, 0x127f, 0x2000, 0x007c, 0x7008,
-	0xa084, 0x0003, 0xa086, 0x0003, 0x0040, 0x4b2f, 0x2704, 0xac08,
-	0x2104, 0x701a, 0x8108, 0x2104, 0x701e, 0x8108, 0x2104, 0x7012,
-	0x8108, 0x2104, 0x7016, 0x6004, 0xa084, 0x0008, 0x0040, 0x4b26,
-	0x8108, 0x2104, 0x7022, 0x8108, 0x2104, 0x7026, 0x7602, 0x7004,
-	0xa084, 0x0010, 0xa085, 0x0001, 0x7006, 0x1078, 0x4981, 0x007c,
-	0x127e, 0x007e, 0x0d7e, 0x2091, 0x2200, 0x2049, 0x4b30, 0x0d7f,
-	0x087f, 0x7108, 0xa184, 0x0003, 0x00c0, 0x4b5a, 0x017e, 0x6904,
-	0xa18c, 0x00ff, 0xa186, 0x0007, 0x0040, 0x4b4a, 0xa18e, 0x000f,
-	0x00c0, 0x4b4d, 0x6840, 0x0078, 0x4b4e, 0x6828, 0x017f, 0xa005,
-	0x0040, 0x4b68, 0x0078, 0x478d, 0x0020, 0x4b5a, 0x1078, 0x4944,
-	0x0078, 0x4b68, 0x00a0, 0x4b61, 0x7108, 0x1078, 0x48bd, 0x0078,
-	0x4b39, 0x7007, 0x0010, 0x00a0, 0x4b63, 0x7108, 0x1078, 0x48bd,
-	0x7008, 0xa086, 0x0008, 0x00c0, 0x4b39, 0x7000, 0xa005, 0x00c0,
-	0x4b39, 0x7003, 0x0000, 0x2049, 0x0000, 0x127f, 0x2000, 0x007c,
-	0x127e, 0x147e, 0x137e, 0x157e, 0x0c7e, 0x0d7e, 0x2091, 0x2200,
-	0x0d7f, 0x2049, 0x4b78, 0xad80, 0x0011, 0x20a0, 0x2099, 0x0031,
-	0x700c, 0xa084, 0x00ff, 0x682a, 0x7007, 0x0008, 0x7007, 0x0002,
-	0x7003, 0x0001, 0x0040, 0x4b97, 0x8000, 0x80ac, 0x53a5, 0x7007,
-	0x0004, 0x7004, 0xa084, 0x0004, 0x00c0, 0x4b99, 0x0c7f, 0x2049,
-	0x0000, 0x7003, 0x0000, 0x157f, 0x137f, 0x147f, 0x127f, 0x2000,
-	0x007c, 0x2091, 0x6000, 0x2091, 0x8000, 0x78cc, 0xa005, 0x0040,
-	0x4bc0, 0x7994, 0x70d0, 0xa106, 0x00c0, 0x4bc0, 0x7804, 0xa005,
-	0x0040, 0x4bc0, 0x7807, 0x0000, 0x0068, 0x4bc0, 0x2091, 0x4080,
-	0x7820, 0x8001, 0x7822, 0x00c0, 0x4c1b, 0x7824, 0x7822, 0x2069,
-	0x5140, 0x6800, 0xa084, 0x0007, 0x0040, 0x4bde, 0xa086, 0x0002,
-	0x0040, 0x4bde, 0x6834, 0xa00d, 0x0040, 0x4bde, 0x2104, 0xa005,
-	0x0040, 0x4bde, 0x8001, 0x200a, 0x0040, 0x4cc3, 0x7848, 0xa005,
-	0x0040, 0x4bec, 0x8001, 0x784a, 0x00c0, 0x4bec, 0x2009, 0x0102,
-	0x6844, 0x200a, 0x1078, 0x21d2, 0x6890, 0xa005, 0x0040, 0x4bf8,
-	0x8001, 0x6892, 0x00c0, 0x4bf8, 0x686f, 0x0000, 0x6873, 0x0001,
-	0x2061, 0x5400, 0x20a9, 0x0100, 0x2009, 0x0002, 0x6034, 0xa005,
-	0x0040, 0x4c0e, 0x8001, 0x6036, 0x00c0, 0x4c0e, 0x6010, 0xa005,
-	0x0040, 0x4c0e, 0x017e, 0x1078, 0x21d2, 0x017f, 0xace0, 0x0010,
-	0x0070, 0x4c14, 0x0078, 0x4bfe, 0x8109, 0x0040, 0x4c1b, 0x20a9,
-	0x0100, 0x0078, 0x4bfe, 0x1078, 0x4c28, 0x1078, 0x4c4d, 0x2009,
-	0x5151, 0x2104, 0x2009, 0x0102, 0x200a, 0x2091, 0x8001, 0x007c,
-	0x7834, 0x8001, 0x7836, 0x00c0, 0x4c4c, 0x7838, 0x7836, 0x2091,
-	0x8000, 0x7844, 0xa005, 0x00c0, 0x4c37, 0x2001, 0x0101, 0x8001,
-	0x7846, 0xa080, 0x7400, 0x2040, 0x2004, 0xa065, 0x0040, 0x4c4c,
-	0x6024, 0xa005, 0x0040, 0x4c48, 0x8001, 0x6026, 0x0040, 0x4c7c,
-	0x6000, 0x2c40, 0x0078, 0x4c3d, 0x007c, 0x7828, 0x8001, 0x782a,
-	0x00c0, 0x4c7b, 0x782c, 0x782a, 0x7830, 0xa005, 0x00c0, 0x4c5a,
-	0x2001, 0x0200, 0x8001, 0x7832, 0x8003, 0x8003, 0x8003, 0x8003,
-	0xa090, 0x5400, 0xa298, 0x0002, 0x2304, 0xa084, 0x0008, 0x0040,
-	0x4c7b, 0xa290, 0x0009, 0x2204, 0xa005, 0x0040, 0x4c73, 0x8001,
-	0x2012, 0x00c0, 0x4c7b, 0x2304, 0xa084, 0xfff7, 0xa085, 0x0080,
-	0x201a, 0x1078, 0x21d2, 0x007c, 0x2069, 0x5140, 0x6800, 0xa005,
-	0x0040, 0x4c86, 0x6848, 0xac06, 0x0040, 0x4cc3, 0x601b, 0x0006,
-	0x60b4, 0xa084, 0x3f00, 0x601e, 0x6020, 0xa084, 0x00ff, 0xa085,
-	0x0060, 0x6022, 0x6000, 0x2042, 0x6714, 0x6f82, 0x1078, 0x1973,
-	0x6818, 0xa005, 0x0040, 0x4c9e, 0x8001, 0x681a, 0x6808, 0xa084,
-	0xffef, 0x680a, 0x6810, 0x8001, 0x00d0, 0x4ca8, 0x1078, 0x23eb,
-	0x6812, 0x602f, 0x0000, 0x6033, 0x0000, 0x2c68, 0x1078, 0x1c70,
-	0x2069, 0x5140, 0x7944, 0xa184, 0x0100, 0x2001, 0x0006, 0x686e,
-	0x00c0, 0x4cbe, 0x6986, 0x2001, 0x0004, 0x686e, 0x1078, 0x21cd,
-	0x2091, 0x8001, 0x007c, 0x2069, 0x0100, 0x2009, 0x5140, 0x2104,
-	0xa084, 0x0007, 0x0040, 0x4d1f, 0xa086, 0x0007, 0x00c0, 0x4cd9,
-	0x0d7e, 0x2009, 0x5152, 0x216c, 0x1078, 0x3a4e, 0x0d7f, 0x0078,
-	0x4d1f, 0x2009, 0x5152, 0x2164, 0x1078, 0x2396, 0x601b, 0x0006,
-	0x6858, 0xa084, 0x3f00, 0x601e, 0x6020, 0xa084, 0x00ff, 0xa085,
-	0x0048, 0x6022, 0x602f, 0x0000, 0x6033, 0x0000, 0x6830, 0xa084,
-	0x0040, 0x0040, 0x4d13, 0x684b, 0x0004, 0x20a9, 0x0014, 0x6848,
-	0xa084, 0x0004, 0x0040, 0x4d00, 0x0070, 0x4d00, 0x0078, 0x4cf7,
-	0x684b, 0x0009, 0x20a9, 0x0014, 0x6848, 0xa084, 0x0001, 0x0040,
-	0x4d0d, 0x0070, 0x4d0d, 0x0078, 0x4d04, 0x20a9, 0x00fa, 0x0070,
-	0x4d13, 0x0078, 0x4d0f, 0x6808, 0xa084, 0xfffd, 0x680a, 0x681b,
-	0x0048, 0x2009, 0x515b, 0x200b, 0x0007, 0x784c, 0x784a, 0x2091,
-	0x8001, 0x007c, 0x2079, 0x5100, 0x1078, 0x4d4d, 0x1078, 0x4d31,
-	0x1078, 0x4d3f, 0x7833, 0x0000, 0x7847, 0x0000, 0x784b, 0x0000,
-	0x007c, 0x2019, 0x0003, 0x2011, 0x5146, 0x2204, 0xa086, 0x003c,
-	0x0040, 0x4d3c, 0x2019, 0x0002, 0x7b2a, 0x7b2e, 0x007c, 0x2019,
-	0x0039, 0x2011, 0x5146, 0x2204, 0xa086, 0x003c, 0x0040, 0x4d4a,
-	0x2019, 0x0027, 0x7b36, 0x7b3a, 0x007c, 0x2019, 0x3971, 0x2011,
-	0x5146, 0x2204, 0xa086, 0x003c, 0x0040, 0x4d58, 0x2019, 0x2626,
-	0x7b22, 0x7b26, 0x783f, 0x0000, 0x7843, 0x000a, 0x007c, 0x0020,
-	0x002b, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000,
-	0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000,
-	0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000,
-	0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000,
-	0x0020, 0x0000, 0x0014, 0x0014, 0x9849, 0x0014, 0x0014, 0x0014,
-	0x0014, 0x0014, 0x0014, 0x0014, 0x0080, 0x000f, 0x0000, 0x0201,
-	0x0604, 0x0c08, 0x2120, 0x4022, 0xf880, 0x0018, 0x300b, 0xa201,
-	0x0014, 0xa200, 0x0014, 0xa200, 0x0214, 0x0000, 0x006c, 0x0002,
-	0x0014, 0x98d0, 0x009e, 0x0096, 0xa202, 0x8838, 0x3806, 0x8839,
-	0x20c3, 0x0864, 0x9884, 0x28c1, 0x9cb1, 0xa203, 0x300c, 0x2846,
-	0x8161, 0x846a, 0x8300, 0x1856, 0x883a, 0x9865, 0x28f2, 0x9c90,
-	0x9858, 0x300c, 0x28e1, 0x9c90, 0x2802, 0xa206, 0x64c3, 0x282d,
-	0xa207, 0x64a0, 0x67a0, 0x6fc0, 0x1814, 0x883b, 0x7824, 0x68c1,
-	0x7864, 0x883e, 0x9878, 0x8576, 0x8677, 0x206b, 0x28c1, 0x9cb1,
-	0x2044, 0x2103, 0x20a2, 0x2081, 0x9865, 0xa209, 0x2901, 0x988c,
-	0x0014, 0xa205, 0xa300, 0x1872, 0x879a, 0x883c, 0x1fe2, 0xc601,
-	0xa20a, 0x856e, 0x0704, 0x9c90, 0x0014, 0xa204, 0xa300, 0x3009,
-	0x19e2, 0xf868, 0x8176, 0x86eb, 0x85eb, 0x872e, 0x87a9, 0x883f,
-	0x08e6, 0x9890, 0xf881, 0x988b, 0xc801, 0x0014, 0xf8c1, 0x0016,
-	0x85b2, 0x80f0, 0x9532, 0xfb02, 0x1de2, 0x0014, 0x8532, 0xf241,
-	0x0014, 0x1de2, 0x84a8, 0xd7a0, 0x1fe6, 0x0014, 0xa208, 0x6043,
-	0x8008, 0x1dc1, 0x0016, 0x8300, 0x8160, 0x842a, 0xf041, 0x3008,
-	0x84a8, 0x11d6, 0x7042, 0x20dd, 0x0011, 0x20d5, 0x8822, 0x0016,
-	0x8000, 0x2847, 0x1011, 0x98c3, 0x8000, 0xa000, 0x2802, 0x1011,
-	0x98c9, 0x9865, 0x283e, 0x1011, 0x98cd, 0xa20b, 0x0017, 0x300c,
-	0xa300, 0x1de2, 0xdb81, 0x0014, 0x0210, 0x98da, 0x0014, 0x26e0,
-	0x873a, 0xfb02, 0x19f2, 0x1fe2, 0x0014, 0xa20d, 0x3806, 0x0210,
-	0x9cb6, 0x0704, 0x0000, 0x006c, 0x0002, 0x984f, 0x0014, 0x009e,
-	0x00a5, 0x0017, 0x60ff, 0x300c, 0x8720, 0xa211, 0x9cd5, 0x8772,
-	0x8837, 0x2101, 0x987a, 0x10d2, 0x78e2, 0x9cd8, 0x9859, 0xd984,
-	0xf0e2, 0xf0a1, 0x98d2, 0x0014, 0x8831, 0xd166, 0x8830, 0x800f,
-	0x9401, 0xb520, 0xc802, 0x8820, 0x987a, 0x2301, 0x987a, 0x10d2,
-	0x78e4, 0x9cd8, 0x8821, 0x8820, 0x9859, 0xf123, 0xf142, 0xf101,
-	0x98cb, 0x10d2, 0x70f6, 0x8832, 0x8203, 0x870c, 0xd99e, 0x6001,
-	0x0014, 0x6845, 0x0214, 0xa21b, 0x9cd5, 0x2001, 0x98ca, 0x8201,
-	0x1852, 0xd184, 0xd163, 0x8834, 0x8001, 0x988d, 0x3027, 0x84a8,
-	0x1a56, 0x8833, 0x0014, 0xa218, 0x6981, 0x9cc1, 0x692a, 0x6902,
-	0x1834, 0x989d, 0x1a14, 0x8010, 0x8592, 0x8026, 0x84b9, 0x7021,
-	0x0014, 0xa300, 0x69e1, 0x9caa, 0x694c, 0xa213, 0x9cba, 0x1462,
-	0xa213, 0x8000, 0x16e1, 0x98b4, 0x8023, 0x16e1, 0x8001, 0x10f1,
-	0x0016, 0x6968, 0xa214, 0x9cba, 0x8004, 0x16e1, 0x0101, 0x300a,
-	0x8827, 0x0014, 0x9cba, 0x0014, 0x61c2, 0x8002, 0x14e1, 0x0016,
-	0xa217, 0x9cc1, 0x0014, 0xa300, 0x8181, 0x842a, 0x84a8, 0x1ce6,
-	0x882c, 0x0016, 0xa212, 0x9cd5, 0x10d2, 0x70e4, 0x0004, 0x8007,
-	0x9424, 0xcc1a, 0x9cd8, 0x98ca, 0x8827, 0x300a, 0x0013, 0x8000,
-	0x84a4, 0x0016, 0x11c2, 0x211e, 0x870e, 0xa21d, 0x0014, 0x878e,
-	0x0016, 0xa21c, 0x1035, 0x9891, 0xa210, 0xa000, 0x8010, 0x8592,
-	0x853b, 0xd044, 0x8022, 0x3807, 0x84bb, 0x98ef, 0x8021, 0x3807,
-	0x84b9, 0x300c, 0x817e, 0x872b, 0x8772, 0x9891, 0x0000, 0x0020,
-	0x002b, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000,
-	0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000,
-	0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000,
-	0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000,
-	0x0020, 0x0000, 0x0014, 0x0014, 0x9849, 0x0014, 0x0014, 0x98e5,
-	0x98d0, 0x0014, 0x0014, 0x0014, 0x0080, 0x013f, 0x0000, 0x0201,
-	0x0604, 0x0c08, 0x2120, 0x4022, 0xf880, 0x0018, 0x300b, 0xa201,
-	0x0014, 0xa200, 0x0014, 0xa200, 0x0214, 0xa202, 0x8838, 0x3806,
-	0x8839, 0x20c3, 0x0864, 0xa82e, 0x28c1, 0x9cb1, 0xa203, 0x300c,
-	0x2846, 0x8161, 0x846a, 0x8300, 0x1856, 0x883a, 0xa804, 0x28f2,
-	0x9c90, 0xa8f4, 0x300c, 0x28e1, 0x9c90, 0x2802, 0xa206, 0x64c3,
-	0x282d, 0xa207, 0x64a0, 0x67a0, 0x6fc0, 0x1814, 0x883b, 0x7824,
-	0x68c1, 0x7864, 0x883e, 0xa802, 0x8576, 0x8677, 0x206b, 0x28c1,
-	0x9cb1, 0x2044, 0x2103, 0x20a2, 0x2081, 0xa8e5, 0xa209, 0x2901,
-	0xa809, 0x0014, 0xa205, 0xa300, 0x1872, 0x879a, 0x883c, 0x1fe2,
-	0xc601, 0xa20a, 0x856e, 0x0704, 0x9c90, 0x0014, 0xa204, 0xa300,
-	0x3009, 0x19e2, 0xf868, 0x8176, 0x86eb, 0x85eb, 0x872e, 0x87a9,
-	0x883f, 0x08e6, 0xa8f3, 0xf881, 0xa8ec, 0xc801, 0x0014, 0xf8c1,
-	0x0016, 0x85b2, 0x80f0, 0x9532, 0xfb02, 0x1de2, 0x0014, 0x8532,
-	0xf241, 0x0014, 0x1de2, 0x84a8, 0xd7a0, 0x1fe6, 0x0014, 0xa208,
-	0x6043, 0x8008, 0x1dc1, 0x0016, 0x8300, 0x8160, 0x842a, 0xf041,
-	0x3008, 0x84a8, 0x11d6, 0x7042, 0x20dd, 0x0011, 0x20d5, 0x8822,
-	0x0016, 0x8000, 0x2847, 0x1011, 0xa8fc, 0x8000, 0xa000, 0x2802,
-	0x1011, 0xa8fd, 0xa898, 0x283e, 0x1011, 0xa8fd, 0xa20b, 0x0017,
-	0x300c, 0xa300, 0x1de2, 0xdb81, 0x0014, 0x0210, 0xa801, 0x0014,
-	0x26e0, 0x873a, 0xfb02, 0x19f2, 0x1fe2, 0x0014, 0xa20d, 0x3806,
-	0x0210, 0x9cb6, 0x0704, 0x0017, 0x60ff, 0x300c, 0x8720, 0xa211,
-	0x9d6b, 0x8772, 0x8837, 0x2101, 0xa821, 0x10d2, 0x78e2, 0x9d6e,
-	0xa8fc, 0xd984, 0xf0e2, 0xf0a1, 0xa871, 0x0014, 0x8831, 0xd166,
-	0x8830, 0x800f, 0x9401, 0xb520, 0xc802, 0x8820, 0xa80f, 0x2301,
-	0xa80d, 0x10d2, 0x78e4, 0x9d6e, 0x8821, 0x8820, 0xa8e6, 0xf123,
-	0xf142, 0xf101, 0xa854, 0x10d2, 0x70f6, 0x8832, 0x8203, 0x870c,
-	0xd99e, 0x6001, 0x0014, 0x6845, 0x0214, 0xa21b, 0x9d6b, 0x2001,
-	0xa845, 0x8201, 0x1852, 0xd184, 0xd163, 0x8834, 0x8001, 0xa801,
-	0x3027, 0x84a8, 0x1a56, 0x8833, 0x0014, 0xa218, 0x6981, 0x9d57,
-	0x692a, 0x6902, 0x1834, 0xa805, 0x1a14, 0x8010, 0x8592, 0x8026,
-	0x84b9, 0x7021, 0x0014, 0xa300, 0x69e1, 0x9d40, 0x694c, 0xa213,
-	0x9d50, 0x1462, 0xa213, 0x8000, 0x16e1, 0xa80a, 0x8023, 0x16e1,
-	0x8001, 0x10f1, 0x0016, 0x6968, 0xa214, 0x9d50, 0x8004, 0x16e1,
-	0x0101, 0x300a, 0x8827, 0x0014, 0x9d50, 0x0014, 0x61c2, 0x8002,
-	0x14e1, 0x0016, 0xa217, 0x9d57, 0x0014, 0xa300, 0x8181, 0x842a,
-	0x84a8, 0x1ce6, 0x882c, 0x0016, 0xa212, 0x9d6b, 0x10d2, 0x70e4,
-	0x0004, 0x8007, 0x9424, 0xcc1a, 0x9d6e, 0xa8f8, 0x8827, 0x300a,
-	0x0013, 0x8000, 0x84a4, 0x0016, 0x11c2, 0x211e, 0x870e, 0xa21d,
-	0x0014, 0x878e, 0x0016, 0xa21c, 0x1035, 0xa8af, 0xa210, 0x3807,
-	0x300c, 0x817e, 0x872b, 0x8772, 0xa8a8, 0x0000, 0xdf21
+	0x6814, 0x8007, 0x7882, 0x0078, 0x3960, 0x6818, 0xa084, 0x8000,
+	0x0040, 0x3234, 0x681b, 0x0008, 0x781b, 0x00c0, 0x0078, 0x24fa,
+	0x2300, 0x0079, 0x323b, 0x3240, 0x32d4, 0x323e, 0x1078, 0x248c,
+	0x7000, 0xa084, 0x0007, 0x0079, 0x3245, 0x2523, 0x324f, 0x3284,
+	0x325a, 0x324d, 0x2523, 0x324d, 0x324d, 0x1078, 0x248c, 0x681c,
+	0xa084, 0x2000, 0x0040, 0x3268, 0x6008, 0xa085, 0x0002, 0x600a,
+	0x0078, 0x3268, 0x68c0, 0xa005, 0x00c0, 0x3284, 0x6920, 0xa18d,
+	0x0001, 0x6922, 0x68c3, 0x0001, 0x6800, 0x706a, 0x0078, 0x327e,
+	0x6920, 0xa18d, 0x0001, 0x6922, 0x6800, 0x6006, 0xa005, 0x00c0,
+	0x3272, 0x6002, 0x681c, 0xa084, 0x000e, 0x0040, 0x327e, 0x7014,
+	0x68ba, 0x7130, 0xa188, 0x7500, 0x0078, 0x3280, 0x2009, 0x7600,
+	0x2104, 0x6802, 0x2d0a, 0x7162, 0x6eb6, 0xa684, 0x0060, 0x0040,
+	0x32d2, 0xa684, 0x0800, 0x00c0, 0x3298, 0xa684, 0x7fff, 0x68b6,
+	0x6894, 0x68a6, 0x6898, 0x68aa, 0x1078, 0x4887, 0x0078, 0x32d2,
+	0xa684, 0x0020, 0x0040, 0x32ad, 0x68c0, 0xa005, 0x0040, 0x32a4,
+	0x1078, 0x4c89, 0x0078, 0x32a7, 0xa006, 0x1078, 0x4c41, 0x79d8,
+	0x7adc, 0x69aa, 0x6aa6, 0x0078, 0x32b3, 0x1078, 0x38ca, 0x69aa,
+	0x6aa6, 0x1078, 0x4c41, 0xa684, 0x8000, 0x0040, 0x32d2, 0xa684,
+	0x7fff, 0x68b6, 0x7adc, 0x79d8, 0xa684, 0x0020, 0x00c0, 0x32ca,
+	0x78d0, 0x801b, 0x00c8, 0x32c5, 0x8000, 0xa084, 0x003f, 0xa108,
+	0xa291, 0x0000, 0x6b98, 0x2100, 0xa302, 0x68b2, 0x6b94, 0x2200,
+	0xa303, 0x68ae, 0x0078, 0x2523, 0x0078, 0x377b, 0x7037, 0x0000,
+	0xa282, 0x0006, 0x0050, 0x32de, 0x1078, 0x248c, 0x7000, 0xa084,
+	0x0007, 0x10c0, 0x3a8c, 0x2300, 0x0079, 0x32e6, 0x32e9, 0x3312,
+	0x3326, 0x2200, 0x0079, 0x32ec, 0x3310, 0x377b, 0x32f2, 0x3310,
+	0x3342, 0x3384, 0x7003, 0x0005, 0x2001, 0x7710, 0x2068, 0x704a,
+	0x157e, 0x20a9, 0x0031, 0x2003, 0x0000, 0x8000, 0x0070, 0x3302,
+	0x0078, 0x32fb, 0x157f, 0xad80, 0x0009, 0x7036, 0x6817, 0x0000,
+	0x68b7, 0x0700, 0x6823, 0x0800, 0x6827, 0x0003, 0x0078, 0x376b,
+	0x1078, 0x248c, 0x7003, 0x0005, 0x2001, 0x7710, 0x2068, 0x704a,
+	0xad80, 0x0009, 0x7036, 0x2200, 0x0079, 0x331e, 0x377b, 0x3324,
+	0x3324, 0x3342, 0x3324, 0x377b, 0x1078, 0x248c, 0x7003, 0x0005,
+	0x2001, 0x7710, 0x2068, 0x704a, 0xad80, 0x0009, 0x7036, 0x2200,
+	0x0079, 0x3332, 0x333a, 0x3338, 0x3338, 0x333a, 0x3338, 0x333a,
+	0x1078, 0x248c, 0x1078, 0x379f, 0x782b, 0x3008, 0x781b, 0x0065,
+	0x0078, 0x24fa, 0x7003, 0x0002, 0x7a80, 0xa294, 0x0f00, 0x789b,
+	0x0018, 0x7ca8, 0xa484, 0x001f, 0xa215, 0x2069, 0x7600, 0x2d04,
+	0x2d08, 0x7162, 0x2068, 0xa005, 0x0040, 0x335d, 0x6814, 0xa206,
+	0x0040, 0x3379, 0x6800, 0x0078, 0x3350, 0x7003, 0x0005, 0x2001,
+	0x7710, 0x2068, 0x704a, 0x7036, 0x157e, 0x20a9, 0x0031, 0x2003,
+	0x0000, 0x8000, 0x0070, 0x336e, 0x0078, 0x3367, 0x157f, 0xad80,
+	0x0009, 0x7036, 0x6a16, 0x68b7, 0x0700, 0x6823, 0x0800, 0x6827,
+	0x0003, 0x6eb4, 0x7e5a, 0x6820, 0xa084, 0x0c00, 0x0040, 0x33d3,
+	0x1078, 0x3797, 0x0078, 0x33d3, 0x7003, 0x0002, 0x7a80, 0xa294,
+	0x0f00, 0x789b, 0x0018, 0x7ca8, 0xa484, 0x001f, 0xa215, 0x79a8,
+	0x79a8, 0xa18c, 0x00ff, 0xa1e8, 0x7500, 0x2d04, 0x2d08, 0x7162,
+	0x2068, 0xa005, 0x0040, 0x33a3, 0x6814, 0xa206, 0x0040, 0x33be,
+	0x6800, 0x0078, 0x3396, 0x7003, 0x0005, 0x2001, 0x7710, 0x2068,
+	0x704a, 0x157e, 0x20a9, 0x0031, 0x2003, 0x0000, 0x8000, 0x0070,
+	0x33b3, 0x0078, 0x33ac, 0x157f, 0xad80, 0x0009, 0x7036, 0x6a16,
+	0x68b7, 0x0700, 0x6823, 0x0800, 0x6827, 0x0003, 0x6eb4, 0x7e5a,
+	0x6820, 0xa084, 0x0c00, 0x0040, 0x33d3, 0xa084, 0x0800, 0x0040,
+	0x33cd, 0x1078, 0x379b, 0x0078, 0x33d3, 0x1078, 0x3797, 0x708b,
+	0x0000, 0x0078, 0x33d3, 0x027e, 0x8207, 0xa084, 0x000f, 0x8003,
+	0x8003, 0x8003, 0xa080, 0x5480, 0x2060, 0x7056, 0x6000, 0x705a,
+	0x6004, 0x705e, 0xa684, 0x0060, 0x0040, 0x342b, 0x6b98, 0x6c94,
+	0x69ac, 0x68b0, 0xa105, 0x00c0, 0x340d, 0x7bd2, 0x7bda, 0x7cd6,
+	0x7cde, 0xa6b4, 0xb7ff, 0x7e5a, 0xa684, 0x0060, 0xa086, 0x0060,
+	0x0040, 0x342b, 0x68c0, 0xa005, 0x0040, 0x3406, 0x7003, 0x0003,
+	0x682b, 0x0000, 0x1078, 0x4b3a, 0x0078, 0x3408, 0x1078, 0x4b4b,
+	0xa6b5, 0x2000, 0x7e5a, 0x0078, 0x342b, 0x68b0, 0xa31a, 0x2100,
+	0xa423, 0x2400, 0xa305, 0x0040, 0x342b, 0x7bd2, 0x7bda, 0x7cd6,
+	0x7cde, 0x68b0, 0xa6b4, 0xbfff, 0x7e5a, 0x007e, 0x68c0, 0xa005,
+	0x007f, 0x0040, 0x3429, 0x7003, 0x0003, 0x1078, 0x4b3a, 0x0078,
+	0x342b, 0x1078, 0x4b96, 0x077f, 0x1078, 0x38bd, 0x2009, 0x0065,
+	0xa684, 0x0004, 0x0040, 0x344c, 0x78e4, 0xa084, 0x0030, 0x0040,
+	0x3444, 0x78ec, 0xa084, 0x0003, 0x0040, 0x3444, 0x782b, 0x3008,
+	0x2009, 0x0065, 0x0078, 0x344c, 0x0f7e, 0x2079, 0x5200, 0x1078,
+	0x4887, 0x0f7f, 0x0040, 0x2523, 0x791a, 0x2d00, 0x704a, 0x8207,
+	0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xa080, 0x5480, 0x2048,
+	0x0078, 0x24fa, 0x6020, 0xa005, 0x0040, 0x3466, 0x8001, 0x6022,
+	0x6008, 0xa085, 0x0008, 0x600a, 0x7010, 0x6026, 0x007c, 0xa006,
+	0x1078, 0x4887, 0x6817, 0x0000, 0x681b, 0x0001, 0x6823, 0x0040,
+	0x681f, 0x0100, 0x7000, 0xa084, 0x0007, 0x0079, 0x3477, 0x2523,
+	0x3481, 0x3481, 0x349e, 0x3489, 0x3487, 0x3489, 0x347f, 0x1078,
+	0x248c, 0x1078, 0x34a9, 0x1078, 0x34a2, 0x1078, 0x1cdc, 0x0078,
+	0x2523, 0x706c, 0x706f, 0x0000, 0x7093, 0x0000, 0x0079, 0x3490,
+	0x349a, 0x349a, 0x3498, 0x3498, 0x3498, 0x349a, 0x3498, 0x349a,
+	0x0079, 0x2902, 0x706f, 0x0000, 0x0078, 0x2523, 0x681b, 0x0000,
+	0x0078, 0x2fb6, 0x6800, 0xa005, 0x00c0, 0x34a7, 0x6002, 0x6006,
+	0x007c, 0x6010, 0xa005, 0x0040, 0x34b2, 0x8001, 0x00d0, 0x34b2,
+	0x1078, 0x248c, 0x6012, 0x6008, 0xa084, 0xffef, 0x600a, 0x007c,
+	0x6018, 0xa005, 0x0040, 0x34be, 0x8001, 0x601a, 0x007c, 0x1078,
+	0x39e0, 0x681b, 0x0018, 0x0078, 0x34f5, 0x1078, 0x39e0, 0x681b,
+	0x0019, 0x0078, 0x34f5, 0x1078, 0x39e0, 0x681b, 0x001a, 0x0078,
+	0x34f5, 0x1078, 0x39e0, 0x681b, 0x0003, 0x0078, 0x34f5, 0x7780,
+	0x1078, 0x38bd, 0x7184, 0xa18c, 0x00ff, 0xa1e8, 0x7500, 0x2d04,
+	0x2d08, 0x2068, 0xa005, 0x00c0, 0x34e7, 0x0078, 0x2523, 0x6814,
+	0x7280, 0xa206, 0x0040, 0x34ef, 0x6800, 0x0078, 0x34e0, 0x6800,
+	0x200a, 0x681b, 0x0005, 0x708b, 0x0000, 0x1078, 0x34a9, 0x6820,
+	0xa084, 0x0001, 0x00c0, 0x34fe, 0x1078, 0x34a2, 0x1078, 0x34b8,
+	0x681f, 0x0000, 0x6823, 0x0020, 0x1078, 0x1cdc, 0x0078, 0x2523,
+	0xa282, 0x0003, 0x00c0, 0x376b, 0x7da8, 0xa5ac, 0x00ff, 0x7ca8,
+	0xa4a4, 0x00ff, 0x6920, 0xa18d, 0x0080, 0x6922, 0xa184, 0x0100,
+	0x0040, 0x356c, 0xa18c, 0xfeff, 0x6922, 0xa4a4, 0x00ff, 0x0040,
+	0x3556, 0xa482, 0x000c, 0x0048, 0x3529, 0x0040, 0x3529, 0x2021,
+	0x000c, 0x852b, 0x852b, 0x1078, 0x382e, 0x0040, 0x3533, 0x1078,
+	0x3627, 0x0078, 0x355f, 0x1078, 0x37e9, 0x0c7e, 0x2960, 0x6004,
+	0xa084, 0xfff5, 0x6006, 0x1078, 0x3652, 0x0c7f, 0x6920, 0xa18d,
+	0x0100, 0x6922, 0x7e58, 0xa6b5, 0x0004, 0x7e5a, 0xa684, 0x0400,
+	0x00c0, 0x3550, 0x782b, 0x3008, 0x781b, 0x0056, 0x0078, 0x24fa,
+	0x782b, 0x3008, 0x781b, 0x0065, 0x0078, 0x24fa, 0x0c7e, 0x2960,
+	0x6004, 0xa084, 0xfff5, 0x6006, 0x1078, 0x3652, 0x0c7f, 0x7e58,
+	0xa684, 0x0400, 0x00c0, 0x3568, 0x781b, 0x0058, 0x0078, 0x24fa,
+	0x781b, 0x0065, 0x0078, 0x24fa, 0x0c7e, 0x7054, 0x2060, 0x6100,
+	0xa18c, 0x1000, 0x0040, 0x35ac, 0x6208, 0x8217, 0xa294, 0x00ff,
+	0xa282, 0x000c, 0x0048, 0x3580, 0x0040, 0x3580, 0x2011, 0x000c,
+	0x2400, 0xa202, 0x00c8, 0x3585, 0x2220, 0x6208, 0xa294, 0x00ff,
+	0x7018, 0xa086, 0x0028, 0x00c0, 0x3595, 0xa282, 0x0019, 0x00c8,
+	0x359b, 0x2011, 0x0019, 0x0078, 0x359b, 0xa282, 0x000c, 0x00c8,
+	0x359b, 0x2011, 0x000c, 0x2200, 0xa502, 0x00c8, 0x35a0, 0x2228,
+	0x1078, 0x37ed, 0x852b, 0x852b, 0x1078, 0x382e, 0x0040, 0x35ac,
+	0x1078, 0x3627, 0x0078, 0x35b0, 0x1078, 0x37e9, 0x1078, 0x3652,
+	0x7858, 0xa085, 0x0004, 0x785a, 0x0c7f, 0x782b, 0x3008, 0x781b,
+	0x0065, 0x0078, 0x24fa, 0x0c7e, 0x2960, 0x6000, 0xd0e4, 0x00c0,
+	0x35d5, 0xd0b4, 0x00c0, 0x35cf, 0x6010, 0xa084, 0x000f, 0x00c0,
+	0x35cf, 0x6104, 0xa18c, 0xfff5, 0x6106, 0x0c7f, 0x007c, 0x2011,
+	0x0032, 0x2019, 0x0000, 0x0078, 0x35fc, 0x68a0, 0xa084, 0x0200,
+	0x00c0, 0x35cf, 0x6208, 0xa294, 0x00ff, 0x7018, 0xa086, 0x0028,
+	0x00c0, 0x35ea, 0xa282, 0x0019, 0x00c8, 0x35f0, 0x2011, 0x0019,
+	0x0078, 0x35f0, 0xa282, 0x000c, 0x00c8, 0x35f0, 0x2011, 0x000c,
+	0x6308, 0x831f, 0xa39c, 0x00ff, 0xa382, 0x000c, 0x0048, 0x35fc,
+	0x0040, 0x35fc, 0x2019, 0x000c, 0x78ab, 0x0001, 0x78ab, 0x0003,
+	0x78ab, 0x0001, 0x7aaa, 0x7baa, 0xa8c0, 0x0005, 0x6820, 0xa085,
+	0x0100, 0x6822, 0x0c7f, 0x007c, 0x0c7e, 0x2960, 0xa18c, 0xfff5,
+	0x6106, 0x2011, 0x0032, 0x2019, 0x0000, 0x0078, 0x3617, 0x78ab,
+	0x0001, 0x78ab, 0x0003, 0x78ab, 0x0001, 0x7aaa, 0x7baa, 0xa8c0,
+	0x0005, 0x6820, 0xa085, 0x0100, 0x6822, 0x0c7f, 0x007c, 0x0c7e,
+	0x7154, 0x2160, 0x1078, 0x362e, 0x0c7f, 0x007c, 0x2008, 0xa084,
+	0xfff0, 0xa425, 0x7c86, 0x6018, 0x789a, 0x7cae, 0x6412, 0x78a4,
+	0xa084, 0xfff8, 0xa18c, 0x0007, 0xa105, 0x78a6, 0x6016, 0x788a,
+	0xa4a4, 0x000f, 0x8427, 0x8204, 0x8004, 0xa084, 0x00ff, 0xa405,
+	0x600e, 0x78ec, 0xd08c, 0x00c0, 0x3651, 0x6004, 0xa084, 0xfff5,
+	0x6006, 0x007c, 0x0c7e, 0x7054, 0x2060, 0x1078, 0x3659, 0x0c7f,
+	0x007c, 0x6018, 0x789a, 0x78a4, 0xa084, 0xfff0, 0x78a6, 0x6012,
+	0x7884, 0xa084, 0xfff0, 0x7886, 0x007c, 0xa282, 0x0002, 0x00c0,
+	0x376b, 0x7aa8, 0x6920, 0xa18d, 0x0080, 0x6922, 0xa184, 0x0200,
+	0x0040, 0x36ae, 0xa18c, 0xfdff, 0x6922, 0xa294, 0x00ff, 0xa282,
+	0x0002, 0x00c8, 0x376b, 0x1078, 0x36f9, 0x1078, 0x3652, 0xa980,
+	0x0001, 0x200c, 0x1078, 0x38b9, 0x1078, 0x35bb, 0x88ff, 0x0040,
+	0x36a1, 0x789b, 0x0060, 0x2800, 0x78aa, 0x7e58, 0xa6b5, 0x0004,
+	0x7e5a, 0xa684, 0x0400, 0x00c0, 0x369b, 0x782b, 0x3008, 0x781b,
+	0x0056, 0x0078, 0x24fa, 0x782b, 0x3008, 0x781b, 0x0065, 0x0078,
+	0x24fa, 0x7e58, 0xa684, 0x0400, 0x00c0, 0x36aa, 0x781b, 0x0058,
+	0x0078, 0x24fa, 0x781b, 0x0065, 0x0078, 0x24fa, 0xa282, 0x0002,
+	0x00c8, 0x36b6, 0xa284, 0x0001, 0x0040, 0x36c0, 0x7154, 0xa188,
+	0x0000, 0x210c, 0xa18c, 0x2000, 0x00c0, 0x36c0, 0x2011, 0x0000,
+	0x1078, 0x37db, 0x1078, 0x36f9, 0x1078, 0x3652, 0x7858, 0xa085,
+	0x0004, 0x785a, 0x782b, 0x3008, 0x781b, 0x0065, 0x0078, 0x24fa,
+	0x0c7e, 0x027e, 0x2960, 0x6000, 0x2011, 0x0001, 0xd0ec, 0x00c0,
+	0x36e9, 0xd0bc, 0x00c0, 0x36e7, 0x6014, 0xa084, 0x0040, 0x00c0,
+	0x36e7, 0xa18c, 0xffef, 0x6106, 0xa006, 0x0078, 0x36f6, 0x2011,
+	0x0000, 0x78ab, 0x0001, 0x78ab, 0x0002, 0x78ab, 0x0003, 0x7aaa,
+	0xa8c0, 0x0004, 0x6820, 0xa085, 0x0200, 0x6822, 0x027f, 0x0c7f,
+	0x007c, 0x0c7e, 0x7054, 0x2060, 0x1078, 0x3700, 0x0c7f, 0x007c,
+	0x82ff, 0x0040, 0x3705, 0x2011, 0x0040, 0x6018, 0xa080, 0x0002,
+	0x789a, 0x78a4, 0xa084, 0xffbf, 0xa205, 0x78a6, 0x788a, 0x6016,
+	0x78ec, 0xd08c, 0x00c0, 0x3718, 0x6004, 0xa084, 0xffef, 0x6006,
+	0x007c, 0x007e, 0x7000, 0xa086, 0x0003, 0x0040, 0x3722, 0x007f,
+	0x0078, 0x3725, 0x007f, 0x0078, 0x3767, 0xa684, 0x0020, 0x0040,
+	0x3767, 0x7888, 0xa084, 0x0040, 0x0040, 0x3767, 0x7bb8, 0xa384,
+	0x003f, 0x831b, 0x00c8, 0x3735, 0x8000, 0xa005, 0x0040, 0x374b,
+	0x831b, 0x00c8, 0x373e, 0x8001, 0x0040, 0x3763, 0xa684, 0x4000,
+	0x0040, 0x374b, 0x78b8, 0x801b, 0x00c8, 0x3747, 0x8000, 0xa084,
+	0x003f, 0x00c0, 0x3763, 0xa6b4, 0xbfff, 0x7e5a, 0x79d8, 0x7adc,
+	0x2001, 0x0001, 0xa108, 0x00c8, 0x3757, 0xa291, 0x0000, 0x79d2,
+	0x79da, 0x7ad6, 0x7ade, 0x1078, 0x4c41, 0x781b, 0x0064, 0x1078,
+	0x4ac6, 0x0078, 0x24fa, 0x781b, 0x0064, 0x0078, 0x24fa, 0x781b,
+	0x0065, 0x0078, 0x24fa, 0x1078, 0x37a3, 0x782b, 0x3008, 0x781b,
+	0x0065, 0x0078, 0x24fa, 0x1078, 0x378f, 0x782b, 0x3008, 0x781b,
+	0x0065, 0x0078, 0x24fa, 0x6827, 0x0002, 0x1078, 0x3797, 0x78e4,
+	0xa084, 0x0030, 0x0040, 0x2523, 0x78ec, 0xa084, 0x0003, 0x0040,
+	0x2523, 0x782b, 0x3008, 0x781b, 0x0065, 0x0078, 0x24fa, 0x2001,
+	0x0005, 0x0078, 0x37a5, 0x2001, 0x000c, 0x0078, 0x37a5, 0x2001,
+	0x0006, 0x0078, 0x37a5, 0x2001, 0x000d, 0x0078, 0x37a5, 0x2001,
+	0x0009, 0x0078, 0x37a5, 0x2001, 0x0007, 0x789b, 0x0010, 0x78aa,
+	0x789b, 0x0060, 0x78ab, 0x0001, 0xa6b5, 0x0004, 0x7e5a, 0x007c,
+	0x077e, 0x873f, 0xa7bc, 0x000f, 0x873b, 0x873b, 0x8703, 0xa0e0,
+	0x5480, 0xa7b8, 0x0020, 0x7f9a, 0x79a4, 0xa184, 0x000f, 0x0040,
+	0x37c9, 0xa184, 0xfff0, 0x78a6, 0x6012, 0x6004, 0xa085, 0x0008,
+	0x6006, 0x8738, 0x8738, 0x7f9a, 0x79a4, 0xa184, 0x0040, 0x0040,
+	0x37d9, 0xa184, 0xffbf, 0x78a6, 0x6016, 0x6004, 0xa085, 0x0010,
+	0x6006, 0x077f, 0x007c, 0x789b, 0x0010, 0x78ab, 0x0001, 0x78ab,
+	0x0002, 0x78ab, 0x0003, 0x7aaa, 0x789b, 0x0060, 0x78ab, 0x0004,
+	0x007c, 0x2021, 0x0000, 0x2029, 0x0032, 0x789b, 0x0010, 0x78ab,
+	0x0001, 0x78ab, 0x0003, 0x78ab, 0x0001, 0x7daa, 0x7caa, 0x789b,
+	0x0060, 0x78ab, 0x0005, 0x007c, 0x157e, 0x8007, 0xa084, 0x00ff,
+	0x8003, 0x8003, 0xa080, 0x0020, 0x789a, 0x79a4, 0xa18c, 0xfff0,
+	0x2001, 0x5246, 0x2004, 0xa082, 0x0028, 0x0040, 0x3817, 0x2021,
+	0x38a0, 0x2019, 0x0014, 0x20a9, 0x000c, 0x0078, 0x381d, 0x2021,
+	0x38ac, 0x2019, 0x0019, 0x20a9, 0x000d, 0x2011, 0x0064, 0x2404,
+	0xa084, 0xfff0, 0xa106, 0x0040, 0x382c, 0x8420, 0x2300, 0xa210,
+	0x0070, 0x382c, 0x0078, 0x381f, 0x157f, 0x007c, 0x157e, 0x2009,
+	0x5246, 0x210c, 0xa182, 0x0032, 0x0048, 0x3842, 0x0040, 0x3846,
+	0x2009, 0x3892, 0x2019, 0x0011, 0x20a9, 0x000e, 0x2011, 0x0032,
+	0x0078, 0x3858, 0xa182, 0x0028, 0x0040, 0x3850, 0x2009, 0x38a0,
+	0x2019, 0x0014, 0x20a9, 0x000c, 0x2011, 0x0064, 0x0078, 0x3858,
+	0x2009, 0x38ac, 0x2019, 0x0019, 0x20a9, 0x000d, 0x2011, 0x0064,
+	0x2200, 0xa502, 0x0040, 0x3868, 0x0048, 0x3868, 0x8108, 0x2300,
+	0xa210, 0x0070, 0x3865, 0x0078, 0x3858, 0x157f, 0xa006, 0x007c,
+	0x157f, 0xa582, 0x0064, 0x00c8, 0x3877, 0x7808, 0xa085, 0x0070,
+	0x780a, 0x7044, 0xa085, 0x0070, 0x7046, 0x0078, 0x3877, 0x78ec,
+	0xa084, 0x0300, 0x0040, 0x387f, 0x2104, 0x0078, 0x3890, 0x2104,
+	0xa09e, 0x1102, 0x00c0, 0x3890, 0x2001, 0x04fd, 0x2004, 0xa082,
+	0x0005, 0x0048, 0x388f, 0x2001, 0x1201, 0x0078, 0x3890, 0x2104,
+	0xa005, 0x007c, 0x1102, 0x3002, 0x3202, 0x4203, 0x4403, 0x5404,
+	0x5604, 0x6605, 0x6805, 0x7806, 0x7a06, 0x0c07, 0x0c07, 0x0e07,
+	0x3202, 0x4202, 0x5202, 0x6202, 0x7202, 0x6605, 0x7605, 0x7805,
+	0x7a05, 0x7c05, 0x7e05, 0x7f05, 0x2202, 0x3202, 0x4202, 0x5202,
+	0x5404, 0x6404, 0x7404, 0x7604, 0x7804, 0x7a04, 0x7c04, 0x7e04,
+	0x7f04, 0x789b, 0x0010, 0xa046, 0x007c, 0xa784, 0x0f00, 0x800b,
+	0xa784, 0x001f, 0x8003, 0x8003, 0x8003, 0x8003, 0xa105, 0xa0e0,
+	0x5500, 0x007c, 0x79d8, 0x7adc, 0x78d0, 0x801b, 0x00c8, 0x38d1,
+	0x8000, 0xa084, 0x003f, 0xa108, 0xa291, 0x0000, 0x007c, 0x0f7e,
+	0x2079, 0x0100, 0x2009, 0x5240, 0x2091, 0x8000, 0x2104, 0x0079,
+	0x38e1, 0x3917, 0x38eb, 0x38eb, 0x38eb, 0x38eb, 0x38eb, 0x38eb,
+	0x391b, 0x1078, 0x248c, 0x784b, 0x0004, 0x7848, 0xa084, 0x0004,
+	0x00c0, 0x38ed, 0x784b, 0x0008, 0x7848, 0xa084, 0x0008, 0x00c0,
+	0x38f4, 0x68b4, 0xa085, 0x4000, 0x68b6, 0x7858, 0xa085, 0x4000,
+	0x785a, 0x7830, 0xa084, 0x0080, 0x00c0, 0x3917, 0x0018, 0x3917,
+	0x681c, 0xa084, 0x0020, 0x00c0, 0x3915, 0x0e7e, 0x2071, 0x5240,
+	0x1078, 0x396a, 0x0e7f, 0x0078, 0x3917, 0x781b, 0x00ca, 0x2091,
+	0x8001, 0x0f7f, 0x007c, 0x70b3, 0x0000, 0x1078, 0x3b44, 0x0078,
+	0x3917, 0x0c7e, 0x6814, 0x8007, 0xa084, 0x000f, 0x8003, 0x8003,
+	0x8003, 0xa0e0, 0x5480, 0x6004, 0xa084, 0x000a, 0x00c0, 0x3954,
+	0x6108, 0xa194, 0xff00, 0x0040, 0x3954, 0xa18c, 0x00ff, 0x2001,
+	0x0019, 0xa106, 0x0040, 0x3943, 0x2001, 0x0032, 0xa106, 0x0040,
+	0x3947, 0x0078, 0x394b, 0x2009, 0x0020, 0x0078, 0x394d, 0x2009,
+	0x003f, 0x0078, 0x394d, 0x2011, 0x0000, 0x2100, 0xa205, 0x600a,
+	0x6004, 0xa085, 0x0002, 0x6006, 0x0c7f, 0x007c, 0x781b, 0x0065,
+	0x0078, 0x24fa, 0x782b, 0x3008, 0x781b, 0x0065, 0x0078, 0x24fa,
+	0x781b, 0x0058, 0x0078, 0x24fa, 0x782b, 0x3008, 0x781b, 0x0056,
+	0x0078, 0x24fa, 0x2009, 0x5220, 0x210c, 0xa186, 0x0000, 0x0040,
+	0x397e, 0xa186, 0x0001, 0x0040, 0x3981, 0x2009, 0x5238, 0x200b,
+	0x000b, 0x706f, 0x0001, 0x781b, 0x0048, 0x007c, 0x781b, 0x00c4,
+	0x007c, 0x2009, 0x5238, 0x200b, 0x000a, 0x007c, 0x2009, 0x5220,
+	0x210c, 0xa186, 0x0000, 0x0040, 0x39a1, 0xa186, 0x0001, 0x0040,
+	0x399b, 0x2009, 0x5238, 0x200b, 0x000b, 0x706f, 0x0001, 0x781b,
+	0x0048, 0x0078, 0x24fa, 0x2009, 0x5238, 0x200b, 0x000a, 0x0078,
+	0x24fa, 0x782b, 0x3008, 0x781b, 0x00c4, 0x0078, 0x24fa, 0x781b,
+	0x00ca, 0x0078, 0x24fa, 0x782b, 0x3008, 0x781b, 0x00ca, 0x0078,
+	0x24fa, 0x781b, 0x008f, 0x0078, 0x24fa, 0x782b, 0x3008, 0x781b,
+	0x008f, 0x0078, 0x24fa, 0x6818, 0xa084, 0x8000, 0x0040, 0x39c2,
+	0x681b, 0x001d, 0x706f, 0x0001, 0x781b, 0x0048, 0x0078, 0x24fa,
+	0x007e, 0x7830, 0xa084, 0x00c0, 0x00c0, 0x39de, 0x7808, 0xa084,
+	0xfffc, 0x780a, 0x0005, 0x0005, 0x0005, 0x0005, 0x78ec, 0xa084,
+	0x0021, 0x0040, 0x39de, 0x7044, 0x780a, 0xa005, 0x007f, 0x007c,
+	0x7044, 0xa085, 0x0002, 0x7046, 0x780a, 0x007c, 0x007e, 0x7830,
+	0xa084, 0x0040, 0x00c0, 0x39e7, 0x0098, 0x39f2, 0x007f, 0x789a,
+	0x78ac, 0x007c, 0x7808, 0xa084, 0xfffd, 0x780a, 0x0005, 0x0005,
+	0x0005, 0x0005, 0x78ec, 0xa084, 0x0021, 0x0040, 0x3a01, 0x0098,
+	0x39ff, 0x007f, 0x789a, 0x78ac, 0x007e, 0x7044, 0x780a, 0x007f,
+	0x007c, 0x78ec, 0xa084, 0x0002, 0x00c0, 0x4871, 0xa784, 0x007d,
+	0x00c0, 0x3a15, 0x2700, 0x1078, 0x248c, 0xa784, 0x0001, 0x00c0,
+	0x300c, 0xa784, 0x0070, 0x0040, 0x3a25, 0x0c7e, 0x2d60, 0x2f68,
+	0x1078, 0x2437, 0x2d78, 0x2c68, 0x0c7f, 0xa784, 0x0008, 0x0040,
+	0x3a32, 0x784b, 0x0008, 0x78ec, 0xa084, 0x0003, 0x0040, 0x2523,
+	0x0078, 0x3956, 0xa784, 0x0004, 0x0040, 0x3a65, 0x78b8, 0xa084,
+	0x4001, 0x0040, 0x3a65, 0x784b, 0x0008, 0x78ec, 0xa084, 0x0003,
+	0x0040, 0x2523, 0x78e4, 0xa084, 0x0007, 0xa086, 0x0001, 0x00c0,
+	0x3a65, 0x78c0, 0xa085, 0x4800, 0x2030, 0x7e5a, 0x781b, 0x00ca,
+	0x0078, 0x24fa, 0x784b, 0x0008, 0x6818, 0xa084, 0x8000, 0x0040,
+	0x3a61, 0x681b, 0x0015, 0xa684, 0x4000, 0x0040, 0x3a61, 0x681b,
+	0x0007, 0x1078, 0x396a, 0x0078, 0x24fa, 0x681b, 0x0003, 0x7858,
+	0xa084, 0x3f00, 0x681e, 0x682f, 0x0000, 0x6833, 0x0000, 0x784b,
+	0x0008, 0x78ec, 0xa084, 0x0003, 0x0040, 0x2a06, 0x0018, 0x24fa,
+	0x0078, 0x3773, 0x6b14, 0x8307, 0xa084, 0x000f, 0x8003, 0x8003,
+	0x8003, 0xa080, 0x5480, 0x2060, 0x2048, 0x7056, 0x6000, 0x705a,
+	0x6004, 0x705e, 0x2a60, 0x007c, 0x0079, 0x3a8e, 0x3a96, 0x3a97,
+	0x3a96, 0x3a99, 0x3a96, 0x3a96, 0x3a96, 0x3a9e, 0x007c, 0x1078,
+	0x34b8, 0x1078, 0x4887, 0x7038, 0x600a, 0x007c, 0x70a0, 0xa005,
+	0x0040, 0x3aab, 0x2068, 0x1078, 0x1bd3, 0x1078, 0x47fe, 0x1078,
+	0x4805, 0x70a3, 0x0000, 0x007c, 0x0e7e, 0x2091, 0x8000, 0x2071,
+	0x5240, 0x7000, 0xa086, 0x0007, 0x00c0, 0x3ac2, 0x6110, 0x70bc,
+	0xa106, 0x00c0, 0x3ac2, 0x0e7f, 0x1078, 0x1be0, 0x1078, 0x3ac8,
+	0xa006, 0x007c, 0x2091, 0x8001, 0x0e7f, 0xa085, 0x0001, 0x007c,
+	0x0f7e, 0x0e7e, 0x2071, 0x5240, 0x0078, 0x2297, 0x785b, 0x0000,
+	0x70af, 0x000e, 0x2009, 0x0100, 0x017e, 0x70a0, 0xa06d, 0x0040,
+	0x3add, 0x70a3, 0x0000, 0x0078, 0x3ae3, 0x70b3, 0x0000, 0x1078,
+	0x1c0c, 0x0040, 0x3ae9, 0x70ac, 0x6826, 0x1078, 0x3bc6, 0x0078,
+	0x3add, 0x017f, 0x157e, 0x0c7e, 0x0d7e, 0x20a9, 0x0008, 0x2061,
+	0x7610, 0x6000, 0xa105, 0x6002, 0x601c, 0xa06d, 0x0040, 0x3b01,
+	0x6800, 0x601e, 0x1078, 0x19ac, 0x6008, 0x8000, 0x600a, 0x0078,
+	0x3af4, 0x6018, 0xa06d, 0x0040, 0x3b0b, 0x6800, 0x601a, 0x1078,
+	0x19ac, 0x0078, 0x3b01, 0xace0, 0x0008, 0x0070, 0x3b11, 0x0078,
+	0x3af1, 0x709c, 0xa084, 0x8000, 0x0040, 0x3b18, 0x1078, 0x3c44,
+	0x0d7f, 0x0c7f, 0x157f, 0x007c, 0x127e, 0x2091, 0x2300, 0x6804,
+	0xa084, 0x000f, 0x0079, 0x3b24, 0x3b34, 0x3b34, 0x3b34, 0x3b34,
+	0x3b34, 0x3b34, 0x3b36, 0x3b3c, 0x3b34, 0x3b34, 0x3b34, 0x3b34,
+	0x3b34, 0x3b3e, 0x3b34, 0x3b36, 0x1078, 0x248c, 0x1078, 0x45d3,
+	0x1078, 0x19ac, 0x0078, 0x3b42, 0x6827, 0x000b, 0x1078, 0x45d3,
+	0x1078, 0x3bc6, 0x127f, 0x007c, 0x127e, 0x2091, 0x2300, 0x0098,
+	0x3b60, 0x7830, 0xa084, 0x00c0, 0x00c0, 0x3b60, 0x0d7e, 0x1078,
+	0x4812, 0x2d00, 0x682e, 0x2009, 0x0004, 0x2001, 0x0000, 0x6827,
+	0x0084, 0x1078, 0x47c7, 0x1078, 0x3bc6, 0x0d7f, 0x0078, 0x3b94,
+	0x7948, 0xa185, 0x4000, 0x784a, 0x0098, 0x3b69, 0x794a, 0x0078,
+	0x3b4e, 0x7828, 0xa086, 0x1834, 0x00c0, 0x3b72, 0xa185, 0x0004,
+	0x0078, 0x3b79, 0x7828, 0xa086, 0x1814, 0x00c0, 0x3b66, 0xa185,
+	0x000c, 0x784a, 0x789b, 0x000e, 0x78ab, 0x0002, 0x7858, 0xa084,
+	0x00ff, 0xa085, 0x0400, 0x785a, 0x70b4, 0xa080, 0x0091, 0x781a,
+	0x6827, 0x0284, 0x682c, 0x6836, 0x6830, 0x683a, 0x2009, 0x0004,
+	0x2001, 0x0000, 0x1078, 0x47c7, 0x127f, 0x007c, 0x0d7e, 0x6b14,
+	0x1078, 0x1c70, 0x0040, 0x3ba3, 0x2068, 0x6827, 0x0002, 0x1078,
+	0x3bc6, 0x0078, 0x3b98, 0x0d7f, 0x007c, 0x0d7e, 0x6b14, 0x6c28,
+	0xa4a4, 0x00ff, 0x1078, 0x1c1c, 0x0040, 0x3bb3, 0x2068, 0x6827,
+	0x0002, 0x1078, 0x3bc6, 0x0d7f, 0x007c, 0x0d7e, 0x6b14, 0xa39c,
+	0x00ff, 0x1078, 0x1c48, 0x0040, 0x3bc4, 0x2068, 0x6827, 0x0002,
+	0x1078, 0x3bc6, 0x0078, 0x3bb9, 0x0d7f, 0x007c, 0x0c7e, 0x6914,
+	0x1078, 0x3c3b, 0x6904, 0xa18c, 0x00ff, 0xa186, 0x0006, 0x0040,
+	0x3be1, 0xa186, 0x000d, 0x0040, 0x3c00, 0xa186, 0x0017, 0x00c0,
+	0x3bdd, 0x1078, 0x19ac, 0x0078, 0x3bdf, 0x1078, 0x1cde, 0x0c7f,
+	0x007c, 0x6004, 0x8001, 0x0048, 0x3bfe, 0x6006, 0x2009, 0x0000,
+	0xa684, 0x0001, 0x00c0, 0x3bee, 0xa18d, 0x8000, 0xa684, 0x0004,
+	0x0040, 0x3bf4, 0xa18d, 0x0002, 0x691e, 0x6823, 0x0000, 0x7104,
+	0x810f, 0x6818, 0xa105, 0x681a, 0x0078, 0x3bdd, 0x1078, 0x248c,
+	0x6018, 0xa005, 0x00c0, 0x3c0f, 0x6008, 0x8001, 0x0048, 0x3c0f,
+	0x600a, 0x601c, 0x6802, 0x2d00, 0x601e, 0x0078, 0x3c25, 0xac88,
+	0x0006, 0x2104, 0xa005, 0x0040, 0x3c18, 0x2008, 0x0078, 0x3c11,
+	0x6802, 0x2d0a, 0x6008, 0x8001, 0x0048, 0x3bdf, 0x600a, 0x6018,
+	0x2068, 0x6800, 0x601a, 0x0078, 0x3c09, 0x157e, 0x137e, 0x147e,
+	0x0c7e, 0x0d7e, 0x1078, 0x1989, 0x00c0, 0x3c30, 0x1078, 0x248c,
+	0x2da0, 0x137f, 0x20a9, 0x0031, 0x53a3, 0x0c7f, 0x147f, 0x137f,
+	0x157f, 0x0078, 0x3bdd, 0xa184, 0x001f, 0x8003, 0x8003, 0x8003,
+	0xa080, 0x7610, 0x2060, 0x007c, 0x2019, 0x5251, 0x2304, 0xa085,
+	0x0001, 0x201a, 0x2019, 0x0102, 0x2304, 0xa085, 0x0001, 0x201a,
+	0x007c, 0x2019, 0x5251, 0x2304, 0xa084, 0xfffe, 0x201a, 0x2019,
+	0x0102, 0x2304, 0xa084, 0xfffe, 0x201a, 0x007c, 0x7990, 0xa18c,
+	0xfff8, 0x7992, 0x70b4, 0xa080, 0x00d8, 0x781a, 0x0078, 0x24fa,
+	0x70a3, 0x0000, 0x7003, 0x0000, 0x7043, 0x0001, 0x7037, 0x0000,
+	0x0018, 0x24b1, 0x1078, 0x1c0c, 0x0040, 0x3c99, 0x2009, 0x520f,
+	0x200b, 0x0000, 0x68bc, 0x2060, 0x6100, 0xa184, 0x0300, 0x0040,
+	0x3c8d, 0x6827, 0x000e, 0xa084, 0x0200, 0x0040, 0x3c89, 0x6827,
+	0x0017, 0x1078, 0x3bc6, 0x0078, 0x3c68, 0x7000, 0xa086, 0x0007,
+	0x00c0, 0x3d0d, 0x2d00, 0x70a2, 0xad80, 0x000f, 0x7036, 0x0078,
+	0x3ca0, 0x7040, 0xa086, 0x0001, 0x0040, 0x2533, 0x0078, 0x24fa,
+	0x2031, 0x0000, 0x691c, 0xa184, 0x0002, 0x0040, 0x3ca9, 0xa6b5,
+	0x0004, 0xa184, 0x00c0, 0x8003, 0x8003, 0x8007, 0xa080, 0x3da6,
+	0x2004, 0xa635, 0x6820, 0xa084, 0x0400, 0x0040, 0x3cc1, 0x789b,
+	0x0018, 0x78ab, 0x0003, 0x789b, 0x0081, 0x78ab, 0x0001, 0xa6b5,
+	0x5000, 0x6820, 0xa084, 0x8000, 0x0040, 0x3ccf, 0xa6b5, 0x0400,
+	0x789b, 0x000e, 0x6824, 0x8007, 0x78aa, 0x0078, 0x3cef, 0x681c,
+	0xd0fc, 0x00c0, 0x3cdd, 0xa6b5, 0x0800, 0x6820, 0xd0c4, 0x0040,
+	0x3cef, 0xa6b5, 0x4000, 0x0078, 0x3cef, 0x6820, 0xd0c4, 0x0040,
+	0x3ce5, 0xa6b5, 0x4000, 0x0078, 0x3cef, 0x789b, 0x0018, 0x78ab,
+	0x0002, 0x789b, 0x0081, 0x78ab, 0x0001, 0xa6b5, 0x1000, 0xa684,
+	0x0200, 0x0040, 0x3d09, 0x682c, 0x78d2, 0x6830, 0x78d6, 0xa684,
+	0x0100, 0x0040, 0x3d07, 0x682c, 0xa084, 0x0001, 0x0040, 0x3d07,
+	0x7888, 0xa084, 0x0040, 0x0040, 0x3d07, 0xa6b5, 0x8000, 0x1078,
+	0x47f6, 0x7e5a, 0x6eb6, 0x0078, 0x4835, 0x1078, 0x39c8, 0x00c0,
+	0x3da0, 0x702c, 0x8004, 0x0048, 0x3d1b, 0x2019, 0x4f49, 0x1078,
+	0x2313, 0x702f, 0x0001, 0x2041, 0x0001, 0x2031, 0x1000, 0x789b,
+	0x0018, 0x6814, 0xa084, 0x001f, 0xa085, 0x0080, 0x78aa, 0x691c,
+	0xa184, 0x0002, 0x0040, 0x3d34, 0xa6b5, 0x0004, 0x78ab, 0x0020,
+	0x6828, 0x78aa, 0xa8c0, 0x0002, 0x681c, 0xd0f4, 0x0040, 0x3d3d,
+	0x2c50, 0x1078, 0x3a7a, 0x1078, 0x4702, 0x6820, 0xa084, 0x8000,
+	0x0040, 0x3d4b, 0xa6b5, 0x0400, 0x789b, 0x000e, 0x6824, 0x8007,
+	0x78aa, 0x0078, 0x3d52, 0x681c, 0xa084, 0x8000, 0x00c0, 0x3d52,
+	0xa6b5, 0x0800, 0x6820, 0xa084, 0x0100, 0x0040, 0x3d59, 0xa6b5,
+	0x4000, 0x681c, 0xa084, 0x00c0, 0x8003, 0x8003, 0x8007, 0xa080,
+	0x3da6, 0x2004, 0xa635, 0xa684, 0x0100, 0x0040, 0x3d73, 0x682c,
+	0xa084, 0x0001, 0x0040, 0x3d73, 0x7888, 0xa084, 0x0040, 0x0040,
+	0x3d73, 0xa6b5, 0x8000, 0x789b, 0x007e, 0x7eae, 0x6eb6, 0x6814,
+	0x8007, 0x78aa, 0x7882, 0x2810, 0x7aaa, 0x7830, 0xa084, 0x00c0,
+	0x00c0, 0x3da0, 0x0018, 0x3da0, 0x70b4, 0xa080, 0x00dd, 0x781a,
+	0x1078, 0x39e0, 0xa684, 0x0200, 0x0040, 0x3d94, 0x682c, 0x78d2,
+	0x6830, 0x78d6, 0x1078, 0x47f6, 0x2d00, 0x70a2, 0x704a, 0x6810,
+	0x70be, 0x7003, 0x0007, 0xad80, 0x000f, 0x7036, 0x0078, 0x24fa,
+	0x1078, 0x1bd3, 0x1078, 0x39e0, 0x0078, 0x24fa, 0x0000, 0x0300,
+	0x0200, 0x0000, 0x1078, 0x248c, 0x2300, 0x0079, 0x3daf, 0x3db2,
+	0x3db2, 0x3db4, 0x1078, 0x248c, 0x1078, 0x4805, 0x6924, 0xa184,
+	0x00ff, 0xa086, 0x000a, 0x0040, 0x3dc6, 0xa184, 0xff00, 0xa085,
+	0x000a, 0x6826, 0x1078, 0x1bd3, 0x0078, 0x3c68, 0x2001, 0x000a,
+	0x1078, 0x4797, 0x0078, 0x3c68, 0xa282, 0x0005, 0x0050, 0x3dd2,
+	0x1078, 0x248c, 0x7000, 0xa084, 0x0007, 0x10c0, 0x3a8c, 0x1078,
+	0x1989, 0x00c0, 0x3df4, 0x2069, 0xffff, 0xa684, 0x0004, 0x0040,
+	0x3de5, 0x2001, 0x2800, 0x0078, 0x3de7, 0x2001, 0x0800, 0x71b4,
+	0xa188, 0x0091, 0x789b, 0x000e, 0x8007, 0x78aa, 0x2031, 0x0400,
+	0x7e5a, 0x791a, 0x0078, 0x24fa, 0x6807, 0x0106, 0x680b, 0x0000,
+	0x689f, 0x0000, 0x6827, 0x0000, 0xa386, 0x0002, 0x00c0, 0x3e15,
+	0xa286, 0x0002, 0x00c0, 0x3e15, 0x78a0, 0xa005, 0x00c0, 0x3e15,
+	0xa484, 0x8000, 0x00c0, 0x3e15, 0x78e4, 0xa084, 0x0008, 0x0040,
+	0x3e15, 0xa6b5, 0x0008, 0x2019, 0x0000, 0x1078, 0x4217, 0x2d00,
+	0x70a2, 0x704a, 0x7003, 0x0007, 0x7037, 0x0000, 0x6824, 0xa084,
+	0x0080, 0x0040, 0x3e27, 0x1078, 0x42cd, 0x0078, 0x24fa, 0x2300,
+	0x0079, 0x3e2a, 0x3e2d, 0x3eae, 0x3ec7, 0x2200, 0x0079, 0x3e30,
+	0x3e35, 0x3e45, 0x3e6b, 0x3e77, 0x3e9a, 0x2029, 0x0001, 0xa026,
+	0x2011, 0x0000, 0x1078, 0x43f3, 0x0079, 0x3e3e, 0x3e43, 0x24fa,
+	0x3c68, 0x3e43, 0x3e43, 0x1078, 0x248c, 0x7990, 0xa18c, 0x0007,
+	0x00c0, 0x3e4c, 0x2009, 0x0008, 0x2011, 0x0001, 0xa684, 0x0004,
+	0x0040, 0x3e54, 0x2011, 0x0003, 0x2220, 0xa12a, 0x2011, 0x0001,
+	0x1078, 0x43f3, 0x0079, 0x3e5c, 0x3e61, 0x24fa, 0x3c68, 0x3e69,
+	0x3e63, 0x0078, 0x483b, 0x70ab, 0x3e67, 0x0078, 0x24fa, 0x0078,
+	0x3e61, 0x1078, 0x248c, 0xa684, 0x0010, 0x0040, 0x3e75, 0x1078,
+	0x429c, 0x0040, 0x3e75, 0x0078, 0x24fa, 0x0078, 0x430d, 0x6000,
+	0xa084, 0x0002, 0x0040, 0x3e94, 0x70b4, 0xa080, 0x00cd, 0x781a,
+	0x0d7e, 0x1078, 0x4812, 0x2d00, 0x682e, 0x6827, 0x0000, 0x1078,
+	0x3bc6, 0x0d7f, 0x1078, 0x19ac, 0x7003, 0x0000, 0x7037, 0x0000,
+	0x704b, 0x0000, 0x0078, 0x3c68, 0xa684, 0x0004, 0x00c0, 0x3e9a,
+	0x0078, 0x483b, 0x6000, 0xa084, 0x0004, 0x00c0, 0x3eac, 0x6000,
+	0xa084, 0x0001, 0x0040, 0x3eac, 0x70ab, 0x3eac, 0x2001, 0x0007,
+	0x1078, 0x478f, 0x0078, 0x4841, 0x0078, 0x483b, 0x2200, 0x0079,
+	0x3eb1, 0x3eb6, 0x3eb8, 0x3eb6, 0x3eb6, 0x3eb6, 0x1078, 0x248c,
+	0x70a7, 0x3ebc, 0x0078, 0x4847, 0x78e4, 0xa084, 0x0008, 0x00c0,
+	0x3eb8, 0x1078, 0x4781, 0x70ab, 0x3ec5, 0x0078, 0x483b, 0x2200,
+	0x0079, 0x3eca, 0x3ecf, 0x3ed1, 0x3ed1, 0x3ecf, 0x3ecf, 0x1078,
+	0x248c, 0x78e4, 0xa084, 0x0008, 0x0040, 0x3ee6, 0x70a7, 0x3eda,
+	0x0078, 0x4847, 0x2011, 0x0004, 0x1078, 0x43ed, 0x0079, 0x3ee0,
+	0x3ee6, 0x24fa, 0x3c68, 0x3ee6, 0x3ef0, 0x3ef4, 0x70ab, 0x3eee,
+	0x2001, 0x0003, 0x1078, 0x478f, 0x0078, 0x4841, 0x0078, 0x483b,
+	0x70ab, 0x3ee6, 0x0078, 0x24fa, 0x70ab, 0x3ef8, 0x0078, 0x24fa,
+	0x0078, 0x3eee, 0xa282, 0x0003, 0x0050, 0x3f00, 0x1078, 0x248c,
+	0xa386, 0x0002, 0x00c0, 0x3f19, 0xa286, 0x0002, 0x00c0, 0x3f1f,
+	0x78a0, 0xa005, 0x00c0, 0x3f1f, 0xa484, 0x8000, 0x00c0, 0x3f1f,
+	0x78e4, 0xa084, 0x0008, 0x0040, 0x3f19, 0xa6b5, 0x0008, 0x2019,
+	0x0000, 0xa684, 0x0008, 0x0040, 0x3f1f, 0x1078, 0x4279, 0x6810,
+	0x70be, 0x7003, 0x0007, 0x2300, 0x0079, 0x3f26, 0x3f29, 0x3f56,
+	0x3f5e, 0x2200, 0x0079, 0x3f2c, 0x3f31, 0x3f2f, 0x3f4a, 0x1078,
+	0x248c, 0x7990, 0xa1ac, 0x0007, 0xa026, 0x2011, 0x0001, 0x1078,
+	0x43f3, 0x0079, 0x3f3b, 0x3f40, 0x24fa, 0x3c68, 0x3f48, 0x3f42,
+	0x0078, 0x483b, 0x70ab, 0x3f46, 0x0078, 0x24fa, 0x0078, 0x3f40,
+	0x1078, 0x248c, 0xa684, 0x0010, 0x0040, 0x3f54, 0x1078, 0x429c,
+	0x0040, 0x3f54, 0x0078, 0x24fa, 0x0078, 0x430d, 0x2200, 0x0079,
+	0x3f59, 0x3f5c, 0x3f5c, 0x3f5c, 0x1078, 0x248c, 0x2200, 0x0079,
+	0x3f61, 0x3f64, 0x3f66, 0x3f66, 0x1078, 0x248c, 0x78e4, 0xa084,
+	0x0008, 0x0040, 0x3f7b, 0x70a7, 0x3f6f, 0x0078, 0x4847, 0x2011,
+	0x0004, 0x1078, 0x43ed, 0x0079, 0x3f75, 0x3f7b, 0x24fa, 0x3c68,
+	0x3f7b, 0x3f85, 0x3f89, 0x70ab, 0x3f83, 0x2001, 0x0003, 0x1078,
+	0x478f, 0x0078, 0x4841, 0x0078, 0x483b, 0x70ab, 0x3f7b, 0x0078,
+	0x24fa, 0x70ab, 0x3f8d, 0x0078, 0x24fa, 0x0078, 0x3f83, 0x2300,
+	0x0079, 0x3f92, 0x3f97, 0x3f99, 0x3f95, 0x1078, 0x248c, 0x70a4,
+	0x007a, 0x70a4, 0x007a, 0xa282, 0x0002, 0x0050, 0x3fa1, 0x1078,
+	0x248c, 0xa684, 0x0200, 0x0040, 0x3fab, 0x1078, 0x47fe, 0x1078,
+	0x43d5, 0x1078, 0x4805, 0x2300, 0x0079, 0x3fae, 0x3fb1, 0x3fd9,
+	0x403f, 0xad86, 0xffff, 0x0040, 0x3c68, 0xa286, 0x0001, 0x0040,
+	0x3fbb, 0x1078, 0x248c, 0xa684, 0x0200, 0x0040, 0x3fc3, 0x1078,
+	0x47fe, 0x1078, 0x4805, 0x2001, 0x0001, 0x1078, 0x4797, 0x78b8,
+	0xa084, 0xc001, 0x0040, 0x3fd5, 0x7848, 0xa085, 0x0008, 0x784a,
+	0x7848, 0xa084, 0x0008, 0x00c0, 0x3fd0, 0x7003, 0x0000, 0x0078,
+	0x3c68, 0x2200, 0x0079, 0x3fdc, 0x3fde, 0x400f, 0x70a7, 0x3fe2,
+	0x0078, 0x4847, 0x2011, 0x000d, 0x1078, 0x43ed, 0x0079, 0x3fe8,
+	0x3fef, 0x24fa, 0x3c68, 0x3ff7, 0x3fff, 0x4005, 0x4007, 0xa6b4,
+	0x00ff, 0xa6b5, 0x0400, 0x6eb6, 0x7e5a, 0x0078, 0x4835, 0xa6b4,
+	0x00ff, 0xa6b5, 0x0400, 0x6eb6, 0x7e5a, 0x0078, 0x4835, 0x70ab,
+	0x4003, 0x0078, 0x24fa, 0x0078, 0x3fef, 0x1078, 0x248c, 0x70ab,
+	0x400b, 0x0078, 0x24fa, 0x1078, 0x484d, 0x0078, 0x24fa, 0x70a7,
+	0x4013, 0x0078, 0x4847, 0x2011, 0x0012, 0x1078, 0x43ed, 0x0079,
+	0x4019, 0x401f, 0x24fa, 0x3c68, 0x402b, 0x4033, 0x4039, 0xa6b4,
+	0x00ff, 0xa6b5, 0x0400, 0x6eb6, 0x7e5a, 0x70b4, 0xa080, 0x00aa,
+	0x781a, 0x0078, 0x24fa, 0xa6b4, 0x00ff, 0xa6b5, 0x0400, 0x6eb6,
+	0x7e5a, 0x0078, 0x4835, 0x70ab, 0x4037, 0x0078, 0x24fa, 0x0078,
+	0x401f, 0x70ab, 0x403d, 0x0078, 0x24fa, 0x0078, 0x402b, 0xa286,
+	0x0001, 0x0040, 0x4045, 0x1078, 0x248c, 0x70a7, 0x4049, 0x0078,
+	0x4847, 0x2011, 0x0015, 0x1078, 0x43ed, 0x0079, 0x404f, 0x4054,
+	0x24fa, 0x3c68, 0x4062, 0x406e, 0xa6b4, 0x00ff, 0xa6b5, 0x0400,
+	0x6eb6, 0x7e5a, 0x783b, 0x1301, 0x70b4, 0xa080, 0x00b5, 0x781a,
+	0x0078, 0x24fa, 0xa6b4, 0x00ff, 0xa6b5, 0x0400, 0x6eb6, 0x7e5a,
+	0x70b4, 0xa080, 0x00aa, 0x781a, 0x0078, 0x24fa, 0x70ab, 0x4072,
+	0x0078, 0x24fa, 0x0078, 0x4054, 0xa282, 0x0003, 0x0050, 0x407a,
+	0x1078, 0x248c, 0x2300, 0x0079, 0x407d, 0x4080, 0x40b7, 0x4114,
+	0xa286, 0x0001, 0x0040, 0x4086, 0x1078, 0x248c, 0x6804, 0xa084,
+	0x00ff, 0xa086, 0x0006, 0x00c0, 0x4093, 0x1078, 0x3bc6, 0x7003,
+	0x0000, 0x0078, 0x3c68, 0x683b, 0x0000, 0x6837, 0x0000, 0xa684,
+	0x0200, 0x0040, 0x40a1, 0x1078, 0x47fe, 0x1078, 0x43d5, 0x1078,
+	0x4805, 0x2001, 0x0001, 0x1078, 0x4797, 0x78b8, 0xa084, 0xc001,
+	0x0040, 0x40b3, 0x7848, 0xa085, 0x0008, 0x784a, 0x7848, 0xa084,
+	0x0008, 0x00c0, 0x40ae, 0x7003, 0x0000, 0x0078, 0x3c68, 0x2200,
+	0x0079, 0x40ba, 0x40bc, 0x40ef, 0x70a7, 0x40c0, 0x0078, 0x4847,
+	0x2011, 0x000d, 0x1078, 0x43ed, 0x0079, 0x40c6, 0x40cd, 0x24fa,
+	0x3c68, 0x40d5, 0x40dd, 0x40e3, 0x40e5, 0xa6b4, 0x00ff, 0xa6b5,
+	0x0800, 0x6eb6, 0x7e5a, 0x0078, 0x4835, 0xa6b4, 0x00ff, 0xa6b5,
+	0x0800, 0x6eb6, 0x7e5a, 0x0078, 0x4835, 0x70ab, 0x40e1, 0x0078,
+	0x24fa, 0x0078, 0x40cd, 0x1078, 0x248c, 0x70ab, 0x40eb, 0x1078,
+	0x4805, 0x0078, 0x24fa, 0x1078, 0x484d, 0x0078, 0x24fa, 0x70a7,
+	0x40f3, 0x0078, 0x4847, 0x2011, 0x0005, 0x1078, 0x43ed, 0x0079,
+	0x40f9, 0x40fe, 0x24fa, 0x3c68, 0x4106, 0x410e, 0xa6b4, 0x00ff,
+	0xa6b5, 0x0800, 0x6eb6, 0x7e5a, 0x0078, 0x4835, 0xa6b4, 0x00ff,
+	0xa6b5, 0x0800, 0x6eb6, 0x7e5a, 0x0078, 0x4835, 0x70ab, 0x4112,
+	0x0078, 0x24fa, 0x0078, 0x40fe, 0xa286, 0x0001, 0x0040, 0x411a,
+	0x1078, 0x248c, 0x70a7, 0x411e, 0x0078, 0x4847, 0x2011, 0x0006,
+	0x1078, 0x43ed, 0x0079, 0x4124, 0x4129, 0x24fa, 0x3c68, 0x412f,
+	0x4139, 0xa6b5, 0x0800, 0x6eb6, 0x7e5a, 0x0078, 0x4835, 0xa6b4,
+	0x00ff, 0xa6b5, 0x0800, 0x6eb6, 0xa6b5, 0x4000, 0x7e5a, 0x0078,
+	0x4835, 0x70ab, 0x413d, 0x0078, 0x24fa, 0x0078, 0x4129, 0x2300,
+	0x0079, 0x4142, 0x4147, 0x4145, 0x4145, 0x1078, 0x248c, 0x1078,
+	0x248c, 0x2300, 0x71a8, 0xa005, 0x017a, 0x6810, 0x70be, 0xa282,
+	0x0003, 0x0050, 0x4155, 0x1078, 0x248c, 0x2300, 0x0079, 0x4158,
+	0x415b, 0x4169, 0x418b, 0xa684, 0x0200, 0x0040, 0x4163, 0x1078,
+	0x47fe, 0x1078, 0x4805, 0x2001, 0x0001, 0x1078, 0x4797, 0x0078,
+	0x24fa, 0xa296, 0x0002, 0x0040, 0x4172, 0x82ff, 0x0040, 0x4172,
+	0x1078, 0x248c, 0x70a7, 0x4176, 0x0078, 0x4847, 0x2011, 0x0018,
+	0x1078, 0x43ed, 0x0079, 0x417c, 0x4181, 0x24fa, 0x3c68, 0x4183,
+	0x4185, 0x0078, 0x4835, 0x0078, 0x4835, 0x70ab, 0x4189, 0x0078,
+	0x24fa, 0x0078, 0x4181, 0x2200, 0x0079, 0x418e, 0x4190, 0x41a9,
+	0x70a7, 0x4194, 0x0078, 0x4847, 0x2011, 0x0017, 0x1078, 0x43ed,
+	0x0079, 0x419a, 0x419f, 0x24fa, 0x3c68, 0x41a1, 0x41a3, 0x0078,
+	0x4835, 0x0078, 0x4835, 0x70ab, 0x41a7, 0x0078, 0x24fa, 0x0078,
+	0x419f, 0xa484, 0x8000, 0x00c0, 0x4205, 0xa684, 0x0100, 0x0040,
+	0x41b5, 0x1078, 0x47fe, 0x1078, 0x43d5, 0x78d8, 0x78d2, 0x78dc,
+	0x78d6, 0xa6b4, 0xefff, 0x7e5a, 0x70a7, 0x41c0, 0x0078, 0x4847,
+	0x2011, 0x000d, 0x1078, 0x43ed, 0x0079, 0x41c6, 0x41cd, 0x24fa,
+	0x3c68, 0x41cd, 0x41f3, 0x41f9, 0x41fb, 0x78d8, 0x79dc, 0xa105,
+	0x00c0, 0x41df, 0x78b8, 0xa084, 0x001f, 0x00c0, 0x41df, 0x70b3,
+	0x0000, 0x7858, 0xa084, 0xfdff, 0x785a, 0x0078, 0x4835, 0xa684,
+	0x0100, 0x0040, 0x41f1, 0x7848, 0xa085, 0x0008, 0x784a, 0x1078,
+	0x47bc, 0x682c, 0x78d2, 0x6830, 0x78d6, 0x70b3, 0x0000, 0x1078,
+	0x47f6, 0x0078, 0x4835, 0x70ab, 0x41f7, 0x0078, 0x24fa, 0x0078,
+	0x41cd, 0x1078, 0x248c, 0x70ab, 0x4201, 0x1078, 0x4805, 0x0078,
+	0x24fa, 0x1078, 0x484d, 0x0078, 0x24fa, 0x1078, 0x4805, 0x70ab,
+	0x420f, 0x2001, 0x0003, 0x1078, 0x478f, 0x0078, 0x4841, 0x1078,
+	0x47f6, 0x682c, 0x78d2, 0x6830, 0x78d6, 0x0078, 0x4835, 0x70b8,
+	0x6812, 0x70be, 0x8000, 0x70ba, 0x681b, 0x0000, 0xa684, 0x0008,
+	0x0040, 0x423a, 0x157e, 0x137e, 0x147e, 0x7890, 0x8004, 0x8004,
+	0x8004, 0x8004, 0xa084, 0x000f, 0x681a, 0x80ac, 0x789b, 0x0000,
+	0xaf80, 0x002b, 0x2098, 0xad80, 0x000b, 0x20a0, 0x53a5, 0x147f,
+	0x137f, 0x157f, 0xa6c4, 0x0f00, 0xa684, 0x0002, 0x00c0, 0x4249,
+	0x692c, 0x810d, 0x810d, 0x810d, 0xa184, 0x0007, 0x2008, 0x0078,
+	0x425c, 0x789b, 0x0010, 0x79ac, 0xa184, 0x0020, 0x0040, 0x425c,
+	0x017e, 0x2009, 0x0005, 0x2001, 0x3d00, 0x1078, 0x47c7, 0x6824,
+	0xa085, 0x003b, 0x6826, 0x017f, 0xa184, 0x001f, 0xa805, 0x6816,
+	0x1078, 0x3c3b, 0x68be, 0xa684, 0x0004, 0x0040, 0x426d, 0xa18c,
+	0xff00, 0x78a8, 0xa084, 0x00ff, 0xa105, 0x682a, 0xa6b4, 0x00ff,
+	0x6000, 0xa084, 0x0008, 0x0040, 0x4277, 0xa6b5, 0x4000, 0x6eb6,
+	0x007c, 0x157e, 0x137e, 0x147e, 0x6918, 0x7890, 0x8004, 0x8004,
+	0x8004, 0x8004, 0xa084, 0x000f, 0x007e, 0xa100, 0x681a, 0x007f,
+	0x8000, 0x8004, 0x0040, 0x4298, 0x20a8, 0x8104, 0xa080, 0x000b,
+	0xad00, 0x20a0, 0x789b, 0x0000, 0xaf80, 0x002b, 0x2098, 0x53a5,
+	0x147f, 0x137f, 0x157f, 0x007c, 0x682c, 0xa084, 0x0020, 0x00c0,
+	0x42a4, 0x620c, 0x0078, 0x42a5, 0x6210, 0x6b18, 0x2300, 0xa202,
+	0x0040, 0x42c5, 0x2018, 0xa382, 0x000e, 0x0048, 0x42b5, 0x0040,
+	0x42b5, 0x2019, 0x000e, 0x0078, 0x42b9, 0x7858, 0xa084, 0xffef,
+	0x785a, 0x783b, 0x1b01, 0x7893, 0x0000, 0x7ba2, 0x70b4, 0xa080,
+	0x008e, 0x781a, 0xa085, 0x0001, 0x007c, 0x7858, 0xa084, 0xffef,
+	0x785a, 0x7893, 0x0000, 0xa006, 0x007c, 0x6904, 0xa18c, 0x00ff,
+	0xa196, 0x0007, 0x0040, 0x42da, 0xa196, 0x000f, 0x0040, 0x42da,
+	0x6807, 0x0117, 0x6914, 0x1078, 0x3c3b, 0x6100, 0x8104, 0x00c8,
+	0x42f5, 0x601c, 0xa005, 0x0040, 0x42e9, 0x2001, 0x0800, 0x0078,
+	0x42f7, 0x0d7e, 0x6824, 0x007e, 0x1078, 0x4812, 0x007f, 0x6826,
+	0x2d00, 0x682e, 0x1078, 0x3bc6, 0x0d7f, 0x2001, 0x0200, 0x6924,
+	0xa18c, 0x00ff, 0xa10d, 0x6926, 0x8007, 0x789b, 0x000e, 0x78aa,
+	0x6820, 0xa085, 0x8000, 0x6822, 0x2031, 0x0400, 0x6eb6, 0x7e5a,
+	0x71b4, 0xa188, 0x0091, 0x791a, 0x007c, 0xa6c4, 0x0f00, 0xa684,
+	0x0002, 0x00c0, 0x4321, 0x692c, 0x810d, 0x810d, 0x810d, 0xa184,
+	0x0007, 0x2008, 0xa805, 0x6816, 0x1078, 0x3c3b, 0x68be, 0x0078,
+	0x4324, 0x6914, 0x1078, 0x3c3b, 0x6100, 0x8104, 0x00c8, 0x4382,
+	0xa184, 0x0300, 0x0040, 0x4330, 0x6807, 0x0117, 0x0078, 0x434e,
+	0x6004, 0xa005, 0x00c0, 0x4357, 0x6807, 0x0117, 0x601c, 0xa005,
+	0x00c0, 0x4344, 0x0d7e, 0x1078, 0x4812, 0x6827, 0x0034, 0x2d00,
+	0x682e, 0x1078, 0x3bc6, 0x0d7f, 0xa684, 0x0004, 0x0040, 0x434e,
+	0x2031, 0x0400, 0x2001, 0x2800, 0x0078, 0x4352, 0x2031, 0x0400,
+	0x2001, 0x0800, 0x71b4, 0xa188, 0x0091, 0x0078, 0x43b0, 0x6018,
+	0xa005, 0x00c0, 0x4344, 0x601c, 0xa005, 0x00c0, 0x4344, 0x689f,
+	0x0000, 0x6827, 0x003d, 0xa684, 0x0001, 0x0040, 0x43be, 0xd694,
+	0x00c0, 0x437b, 0x6100, 0xd1d4, 0x0040, 0x437b, 0x692c, 0xa18c,
+	0x00ff, 0x0040, 0x43be, 0xa186, 0x0003, 0x0040, 0x43be, 0xa186,
+	0x0012, 0x0040, 0x43be, 0xa6b5, 0x0800, 0x71b4, 0xa188, 0x00ae,
+	0x0078, 0x43b9, 0x6807, 0x0117, 0x2031, 0x0400, 0x692c, 0xa18c,
+	0x00ff, 0xa186, 0x0012, 0x00c0, 0x4393, 0x2001, 0x43cb, 0x2009,
+	0x0001, 0x0078, 0x43a4, 0xa186, 0x0003, 0x00c0, 0x439d, 0x2001,
+	0x43cc, 0x2009, 0x0012, 0x0078, 0x43a4, 0x2001, 0x0200, 0x71b4,
+	0xa188, 0x0091, 0x0078, 0x43b0, 0x1078, 0x47e1, 0x78a3, 0x0000,
+	0x681c, 0xa085, 0x0040, 0x681e, 0x71b4, 0xa188, 0x00da, 0xa006,
+	0x6826, 0x8007, 0x789b, 0x000e, 0x78aa, 0x6820, 0xa085, 0x8000,
+	0x6822, 0x6eb6, 0x7e5a, 0x791a, 0x0078, 0x24fa, 0x6eb6, 0x1078,
+	0x3bc6, 0x6810, 0x70be, 0x7003, 0x0007, 0x70a3, 0x0000, 0x704b,
+	0x0000, 0x0078, 0x24fa, 0x0023, 0x0070, 0x0005, 0x0000, 0x0a00,
+	0x0000, 0x0000, 0x0025, 0x0000, 0x0000, 0x683b, 0x0000, 0x6837,
+	0x0000, 0xa684, 0x0200, 0x0040, 0x43ec, 0x78b8, 0xa08c, 0x001f,
+	0xa084, 0x8000, 0x0040, 0x43e5, 0x8108, 0x78d8, 0xa100, 0x6836,
+	0x78dc, 0xa081, 0x0000, 0x683a, 0x007c, 0x7990, 0x810f, 0xa5ac,
+	0x0007, 0x2021, 0x0000, 0xa480, 0x0010, 0x789a, 0x79a8, 0xa18c,
+	0x00ff, 0xa184, 0x0080, 0x00c0, 0x441b, 0xa182, 0x0020, 0x00c8,
+	0x4439, 0xa182, 0x0012, 0x00c8, 0x4781, 0x2100, 0x1079, 0x4409,
+	0x007c, 0x4781, 0x45eb, 0x4781, 0x4781, 0x4446, 0x4449, 0x4483,
+	0x44b9, 0x44ed, 0x44f0, 0x4781, 0x4781, 0x44a4, 0x4514, 0x454e,
+	0x4781, 0x4781, 0x4574, 0xa184, 0x0020, 0x00c0, 0x45a8, 0xa18c,
+	0x001f, 0x6814, 0xa084, 0x001f, 0xa106, 0x0040, 0x4436, 0x70b4,
+	0xa080, 0x00cd, 0x781a, 0x2001, 0x0014, 0x1078, 0x4797, 0x1078,
+	0x4805, 0x7003, 0x0000, 0x2001, 0x0002, 0x007c, 0x2001, 0x0000,
+	0x007c, 0xa182, 0x0024, 0x00c8, 0x4781, 0xa184, 0x0003, 0x1079,
+	0x4409, 0x007c, 0x4781, 0x4781, 0x4781, 0x4781, 0x1078, 0x4781,
+	0x007c, 0x2200, 0x0079, 0x444c, 0x4577, 0x4577, 0x4470, 0x4470,
+	0x4470, 0x4470, 0x4470, 0x4470, 0x4470, 0x4470, 0x446e, 0x4470,
+	0x4465, 0x4470, 0x4470, 0x4470, 0x4470, 0x4470, 0x4478, 0x447b,
+	0x4577, 0x447b, 0x4470, 0x4470, 0x4470, 0x0c7e, 0x077e, 0x6f14,
+	0x1078, 0x37b0, 0x077f, 0x0c7f, 0x0078, 0x4470, 0x1078, 0x468e,
+	0x6827, 0x02b3, 0x2009, 0x000b, 0x2001, 0x4800, 0x0078, 0x45ab,
+	0x1078, 0x4773, 0x007c, 0x6827, 0x0093, 0x2009, 0x000b, 0x2001,
+	0x4800, 0x0078, 0x4593, 0x2d58, 0x6804, 0xa084, 0x00ff, 0xa086,
+	0x0006, 0x00c0, 0x448d, 0x6807, 0x0117, 0x6827, 0x0002, 0x1078,
+	0x4812, 0x6827, 0x0036, 0x6932, 0x2d00, 0x682e, 0x0d7e, 0x1078,
+	0x3b96, 0x1078, 0x45d3, 0x2b68, 0x1078, 0x3bc6, 0x0d7f, 0x1078,
+	0x3bc6, 0x2001, 0x0002, 0x007c, 0x1078, 0x45d3, 0x2001, 0x0017,
+	0x1078, 0x4797, 0x70a3, 0x0000, 0x2009, 0x5238, 0x200b, 0x0006,
+	0x70af, 0x0017, 0x2009, 0x0200, 0x1078, 0x3ad4, 0x2001, 0x0001,
+	0x007c, 0x2200, 0x0079, 0x44bc, 0x4577, 0x45a8, 0x45a8, 0x45a8,
+	0x44dd, 0x45ba, 0x44e5, 0x45ba, 0x45ba, 0x45bd, 0x45bd, 0x45c2,
+	0x45c2, 0x44d5, 0x44d5, 0x45a8, 0x45a8, 0x45ba, 0x45a8, 0x44e5,
+	0x4577, 0x44e5, 0x44e5, 0x44e5, 0x44e5, 0x6827, 0x0084, 0x2009,
+	0x000b, 0x2001, 0x4300, 0x0078, 0x45cc, 0x6827, 0x000d, 0x2009,
+	0x000b, 0x2001, 0x4300, 0x0078, 0x45ab, 0x6827, 0x0093, 0x2009,
+	0x000b, 0x2001, 0x4300, 0x0078, 0x4593, 0x2001, 0x0000, 0x007c,
+	0x2200, 0x0079, 0x44f3, 0x4577, 0x450c, 0x450c, 0x450c, 0x450c,
+	0x45ba, 0x45ba, 0x45ba, 0x45ba, 0x45ba, 0x45ba, 0x45ba, 0x45ba,
+	0x450c, 0x450c, 0x450c, 0x450c, 0x45ba, 0x450c, 0x450c, 0x45ba,
+	0x45ba, 0x45ba, 0x45ba, 0x4577, 0x6827, 0x0093, 0x2009, 0x000b,
+	0x2001, 0x4300, 0x0078, 0x4593, 0xa684, 0x0004, 0x00c0, 0x4528,
+	0x6804, 0xa084, 0x00ff, 0xa086, 0x0006, 0x00c0, 0x4781, 0x1078,
+	0x45d3, 0x6807, 0x0117, 0x1078, 0x3bc6, 0x2001, 0x0002, 0x007c,
+	0x6000, 0xa084, 0x0004, 0x0040, 0x4781, 0x2d58, 0x6804, 0xa084,
+	0x00ff, 0xa086, 0x0006, 0x00c0, 0x4537, 0x6807, 0x0117, 0x6827,
+	0x0002, 0x1078, 0x4812, 0x6827, 0x0036, 0x6932, 0x2d00, 0x682e,
+	0x0d7e, 0x1078, 0x3ba5, 0x1078, 0x45d3, 0x2b68, 0x1078, 0x3bc6,
+	0x0d7f, 0x1078, 0x3bc6, 0x2001, 0x0002, 0x007c, 0x6000, 0xa084,
+	0x0004, 0x0040, 0x4781, 0x6a04, 0xa294, 0x00ff, 0xa286, 0x0006,
+	0x00c0, 0x455c, 0x6807, 0x0117, 0x6827, 0x0002, 0x2d58, 0x1078,
+	0x4812, 0x6827, 0x0036, 0x6932, 0x2d00, 0x682e, 0x0d7e, 0x1078,
+	0x3bb5, 0x1078, 0x45d3, 0x2b68, 0x1078, 0x3bc6, 0x0d7f, 0x1078,
+	0x3bc6, 0x2001, 0x0002, 0x007c, 0x1078, 0x4781, 0x007c, 0x70b4,
+	0xa080, 0x00cd, 0x781a, 0x2001, 0x0001, 0x1078, 0x4797, 0x1078,
+	0x4805, 0x7003, 0x0000, 0x2001, 0x0002, 0x007c, 0x1078, 0x47c7,
+	0x1078, 0x47fe, 0x1078, 0x43d5, 0x1078, 0x42cd, 0x1078, 0x4805,
+	0x2001, 0x0001, 0x007c, 0x1078, 0x47c7, 0x1078, 0x47fe, 0x1078,
+	0x43d5, 0x70b4, 0xa080, 0x00cd, 0x781a, 0x2001, 0x0013, 0x1078,
+	0x4797, 0x1078, 0x4805, 0x7003, 0x0000, 0x2001, 0x0002, 0x007c,
+	0x1078, 0x4781, 0x007c, 0x1078, 0x47c7, 0x1078, 0x47fe, 0x1078,
+	0x43d5, 0x1078, 0x42cd, 0x1078, 0x4805, 0x1078, 0x484d, 0x2001,
+	0x0001, 0x007c, 0x2001, 0x0003, 0x007c, 0x1078, 0x468e, 0x2001,
+	0x0000, 0x007c, 0x0c7e, 0x077e, 0x6f14, 0x1078, 0x37b0, 0x077f,
+	0x0c7f, 0x2001, 0x0000, 0x007c, 0x1078, 0x47c7, 0x1078, 0x4781,
+	0x2001, 0x0006, 0x007c, 0x6904, 0xa18c, 0x00ff, 0xa186, 0x0007,
+	0x0040, 0x45de, 0xa186, 0x000f, 0x00c0, 0x45e2, 0x1078, 0x47fe,
+	0x1078, 0x43d5, 0x70b4, 0xa080, 0x00cd, 0x781a, 0x1078, 0x4805,
+	0x7003, 0x0000, 0x007c, 0x7aa8, 0xa294, 0x00ff, 0x78a8, 0xa084,
+	0x00ff, 0xa08a, 0x0004, 0x00c8, 0x4781, 0x1079, 0x45f8, 0x007c,
+	0x4781, 0x45fc, 0x4781, 0x4695, 0xa282, 0x0003, 0x0040, 0x4603,
+	0x1078, 0x4781, 0x007c, 0x7da8, 0xa5ac, 0x00ff, 0x7ca8, 0xa4a4,
+	0x00ff, 0x69b8, 0xa184, 0x0100, 0x0040, 0x4642, 0xa18c, 0xfeff,
+	0x69ba, 0x78a0, 0xa005, 0x00c0, 0x4642, 0xa4a4, 0x00ff, 0x0040,
+	0x4636, 0xa482, 0x000c, 0x0040, 0x461f, 0x00c8, 0x4629, 0x852b,
+	0x852b, 0x1078, 0x382e, 0x0040, 0x4629, 0x1078, 0x3627, 0x0078,
+	0x4638, 0x1078, 0x4760, 0x1078, 0x3652, 0x69b8, 0xa18d, 0x0100,
+	0x69ba, 0xa6b5, 0x1000, 0x7e5a, 0x0078, 0x463b, 0x1078, 0x3652,
+	0xa6b4, 0xefff, 0x7e5a, 0x70b4, 0xa080, 0x0091, 0x781a, 0x2001,
+	0x0001, 0x007c, 0x0c7e, 0x1078, 0x4682, 0x6200, 0xd2e4, 0x0040,
+	0x4673, 0x6208, 0x8217, 0xa294, 0x00ff, 0xa282, 0x000c, 0x0048,
+	0x4655, 0x0040, 0x4655, 0x2011, 0x000c, 0x2400, 0xa202, 0x00c8,
+	0x465a, 0x2220, 0x6208, 0xa294, 0x00ff, 0x701c, 0xa202, 0x00c8,
+	0x4662, 0x721c, 0x2200, 0xa502, 0x00c8, 0x4667, 0x2228, 0x1078,
+	0x4764, 0x852b, 0x852b, 0x1078, 0x382e, 0x0040, 0x4673, 0x1078,
+	0x362e, 0x0078, 0x4677, 0x1078, 0x4760, 0x1078, 0x3659, 0xa6b5,
+	0x1000, 0x7e5a, 0x70b4, 0xa080, 0x00b9, 0x781a, 0x2001, 0x0004,
+	0x0c7f, 0x007c, 0x007e, 0x6814, 0x8007, 0xa084, 0x000f, 0x8003,
+	0x8003, 0x8003, 0xa0e0, 0x5480, 0x007f, 0x007c, 0x0c7e, 0x1078,
+	0x4682, 0x1078, 0x3659, 0x0c7f, 0x007c, 0xa282, 0x0002, 0x00c0,
+	0x4781, 0x7aa8, 0xa294, 0x00ff, 0x69b8, 0xa184, 0x0200, 0x0040,
+	0x46cc, 0xa18c, 0xfdff, 0x69ba, 0x78a0, 0xa005, 0x00c0, 0x46cc,
+	0xa282, 0x0002, 0x00c8, 0x376b, 0x1078, 0x472a, 0x1078, 0x36f9,
+	0x1078, 0x3652, 0xa684, 0x0100, 0x0040, 0x46c2, 0x682c, 0xa084,
+	0x0001, 0x0040, 0x46c2, 0xc6fc, 0x7888, 0xa084, 0x0040, 0x0040,
+	0x46c2, 0xc6fd, 0xa6b5, 0x1000, 0x7e5a, 0x70b4, 0xa080, 0x0091,
+	0x781a, 0x2001, 0x0001, 0x007c, 0x0c7e, 0x1078, 0x4682, 0xa284,
+	0xfffe, 0x0040, 0x46d7, 0x2011, 0x0001, 0x0078, 0x46db, 0xa284,
+	0x0001, 0x0040, 0x46e1, 0x6100, 0xd1ec, 0x00c0, 0x46e1, 0x2011,
+	0x0000, 0x1078, 0x471c, 0x1078, 0x3700, 0x1078, 0x3659, 0xa684,
+	0x0100, 0x0040, 0x46f7, 0x682c, 0xa084, 0x0001, 0x0040, 0x46f7,
+	0xc6fc, 0x7888, 0xa084, 0x0040, 0x0040, 0x46f7, 0xc6fd, 0xa6b5,
+	0x1000, 0x7e5a, 0x70b4, 0xa080, 0x00b9, 0x781a, 0x2001, 0x0004,
+	0x0c7f, 0x007c, 0x0c7e, 0x2960, 0x6000, 0x2011, 0x0001, 0xa084,
+	0x2000, 0x00c0, 0x470d, 0x2011, 0x0000, 0x78ab, 0x0001, 0x78ab,
+	0x0002, 0x78ab, 0x0003, 0x7aaa, 0xa8c0, 0x0004, 0x68b8, 0xa085,
+	0x0200, 0x68ba, 0x0c7f, 0x007c, 0x789b, 0x0018, 0x78ab, 0x0001,
+	0x78ab, 0x0002, 0x78ab, 0x0003, 0x7aaa, 0x789b, 0x0081, 0x78ab,
+	0x0004, 0x007c, 0x0c7e, 0x7054, 0x2060, 0x6000, 0xa084, 0x1000,
+	0x00c0, 0x4738, 0x2029, 0x0032, 0x2021, 0x0000, 0x0078, 0x4758,
+	0x6508, 0xa5ac, 0x00ff, 0x7018, 0xa086, 0x0028, 0x00c0, 0x4748,
+	0xa582, 0x0019, 0x00c8, 0x474e, 0x2029, 0x0019, 0x0078, 0x474e,
+	0xa582, 0x000c, 0x00c8, 0x474e, 0x2029, 0x000c, 0x6408, 0x8427,
+	0xa4a4, 0x00ff, 0xa482, 0x000c, 0x0048, 0x4758, 0x2021, 0x000c,
+	0x1078, 0x4764, 0x68b8, 0xa085, 0x0100, 0x68ba, 0x0c7f, 0x007c,
+	0x2021, 0x0000, 0x2029, 0x0032, 0x789b, 0x0018, 0x78ab, 0x0001,
+	0x78ab, 0x0003, 0x78ab, 0x0001, 0x7daa, 0x7caa, 0x789b, 0x0081,
+	0x78ab, 0x0005, 0x007c, 0x2001, 0x0003, 0x1078, 0x478f, 0xa6b5,
+	0x1000, 0x7e5a, 0x70b4, 0xa080, 0x00b9, 0x781a, 0x2001, 0x0005,
+	0x007c, 0x2001, 0x0007, 0x1078, 0x478f, 0xa6b5, 0x1000, 0x7e5a,
+	0x70b4, 0xa080, 0x00b9, 0x781a, 0x2001, 0x0004, 0x007c, 0x789b,
+	0x0018, 0x78aa, 0x789b, 0x0081, 0x78ab, 0x0001, 0x007c, 0x6904,
+	0xa18c, 0x00ff, 0xa196, 0x0007, 0x0040, 0x47a5, 0xa196, 0x000f,
+	0x0040, 0x47a5, 0x1078, 0x19ac, 0x007c, 0x6924, 0xa194, 0x003f,
+	0x00c0, 0x47ae, 0xa18c, 0xffc0, 0xa105, 0x6826, 0x1078, 0x3bc6,
+	0x691c, 0xa184, 0x0100, 0x0040, 0x47bb, 0x6914, 0x1078, 0x3c3b,
+	0x6204, 0x8210, 0x6206, 0x007c, 0x692c, 0x6834, 0x682e, 0xa112,
+	0x6930, 0x6838, 0x6832, 0xa11b, 0xa200, 0xa301, 0x007c, 0x0c7e,
+	0xade0, 0x0018, 0x6003, 0x0070, 0x6106, 0x600b, 0x0000, 0x600f,
+	0x0a00, 0x6013, 0x0000, 0x6017, 0x0000, 0x8007, 0x601a, 0x601f,
+	0x0000, 0x6023, 0x0000, 0x0c7f, 0x6824, 0xa085, 0x0080, 0x6826,
+	0x007c, 0x157e, 0x137e, 0x147e, 0x2098, 0xaf80, 0x002d, 0x20a0,
+	0x81ac, 0x0040, 0x47ec, 0x53a6, 0xa184, 0x0001, 0x0040, 0x47f2,
+	0x3304, 0x78be, 0x147f, 0x137f, 0x157f, 0x007c, 0x70b0, 0xa005,
+	0x10c0, 0x248c, 0x70b3, 0x8000, 0x0078, 0x4b4b, 0x71b0, 0x81ff,
+	0x0040, 0x4804, 0x1078, 0x4c41, 0x007c, 0x71b0, 0x81ff, 0x0040,
+	0x4811, 0x7848, 0xa085, 0x0008, 0x784a, 0x70b3, 0x0000, 0x1078,
+	0x4887, 0x007c, 0x0c7e, 0x0d7e, 0x1078, 0x1989, 0x00c0, 0x481a,
+	0x1078, 0x248c, 0x0c7f, 0x157e, 0x137e, 0x147e, 0x2da0, 0x2c98,
+	0x20a9, 0x0031, 0x53a3, 0x147f, 0x137f, 0x157f, 0x6807, 0x010d,
+	0x680b, 0x0000, 0x7004, 0x8007, 0x681a, 0x6823, 0x0000, 0x681f,
+	0x0000, 0x689f, 0x0000, 0x0c7f, 0x007c, 0x70b4, 0xa080, 0x0091,
+	0x781a, 0x0078, 0x24fa, 0x70b4, 0xa080, 0x0081, 0x781a, 0x0078,
+	0x24fa, 0x70b4, 0xa080, 0x00b9, 0x781a, 0x0078, 0x24fa, 0x70b4,
+	0xa080, 0x00c3, 0x781a, 0x0078, 0x24fa, 0x6904, 0xa18c, 0x00ff,
+	0xa196, 0x0007, 0x0040, 0x485a, 0xa196, 0x000f, 0x0040, 0x485a,
+	0x6807, 0x0117, 0x6824, 0xa084, 0x00ff, 0xa085, 0x0200, 0x6826,
+	0x8007, 0x789b, 0x000e, 0x78aa, 0x6820, 0xa085, 0x8000, 0x6822,
+	0x2031, 0x0400, 0x6eb6, 0x7e5a, 0x71b4, 0xa188, 0x0091, 0x791a,
+	0x007c, 0x1078, 0x4805, 0x7848, 0xa085, 0x000c, 0x784a, 0x70b4,
+	0xa080, 0x00cd, 0x781a, 0x2009, 0x000b, 0x2001, 0x4400, 0x1078,
+	0x47c7, 0x2001, 0x0013, 0x1078, 0x4797, 0x0078, 0x3c68, 0x127e,
+	0x2091, 0x2200, 0x2049, 0x4887, 0x7000, 0x7204, 0xa205, 0x720c,
+	0xa215, 0x7008, 0xa084, 0xfff7, 0xa205, 0x0040, 0x4899, 0x0078,
+	0x489e, 0x7003, 0x0000, 0x127f, 0x2000, 0x007c, 0x7000, 0xa084,
+	0x0001, 0x00c0, 0x48cc, 0x7108, 0x8103, 0x00c8, 0x48ab, 0x1078,
+	0x49ce, 0x0078, 0x48a3, 0x700c, 0xa08c, 0x00ff, 0x0040, 0x48cc,
+	0x7004, 0x8004, 0x00c8, 0x48c3, 0x7014, 0xa005, 0x00c0, 0x48bf,
+	0x7010, 0xa005, 0x0040, 0x48c3, 0xa102, 0x00c8, 0x48a3, 0x7007,
+	0x0010, 0x0078, 0x48cc, 0x8aff, 0x0040, 0x48cc, 0x1078, 0x4c18,
+	0x00c0, 0x48c6, 0x0040, 0x48a3, 0x1078, 0x4957, 0x7003, 0x0000,
+	0x127f, 0x2000, 0x007c, 0x017e, 0x6104, 0xa18c, 0x00ff, 0xa186,
+	0x0007, 0x0040, 0x48df, 0xa18e, 0x000f, 0x00c0, 0x48e2, 0x6040,
+	0x0078, 0x48e3, 0x6428, 0x017f, 0x84ff, 0x0040, 0x490d, 0x2c70,
+	0x7004, 0xa0bc, 0x000f, 0xa7b8, 0x491d, 0x273c, 0x87fb, 0x00c0,
+	0x48fb, 0x0048, 0x48f5, 0x1078, 0x248c, 0x609c, 0xa075, 0x0040,
+	0x490d, 0x0078, 0x48e8, 0x2704, 0xae68, 0x6808, 0xa630, 0x680c,
+	0xa529, 0x8421, 0x0040, 0x490d, 0x8738, 0x2704, 0xa005, 0x00c0,
+	0x48fc, 0x709c, 0xa075, 0x00c0, 0x48e8, 0x007c, 0x0000, 0x0005,
+	0x0009, 0x000d, 0x0011, 0x0015, 0x0019, 0x001d, 0x0000, 0x0003,
+	0x0009, 0x000f, 0x0015, 0x001b, 0x0000, 0x0000, 0x4912, 0x490f,
+	0x0000, 0x0000, 0x8000, 0x0000, 0x4912, 0x0000, 0x491a, 0x4917,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x491a, 0x0000, 0x4915, 0x4915,
+	0x0000, 0x0000, 0x8000, 0x0000, 0x4915, 0x0000, 0x491b, 0x491b,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x491b, 0x127e, 0x2091, 0x2200,
+	0x2079, 0x5200, 0x2071, 0x0010, 0x7007, 0x000a, 0x7007, 0x0002,
+	0x7003, 0x0000, 0x2071, 0x0020, 0x7007, 0x000a, 0x7007, 0x0002,
+	0x7003, 0x0000, 0x2049, 0x0000, 0x127f, 0x2000, 0x007c, 0x2049,
+	0x4957, 0x2019, 0x0000, 0x7004, 0x8004, 0x00c8, 0x49aa, 0x7007,
+	0x0012, 0x7108, 0x7008, 0xa106, 0x00c0, 0x4961, 0xa184, 0x01e0,
+	0x0040, 0x496c, 0x1078, 0x248c, 0x2001, 0x04fd, 0x2004, 0xa082,
+	0x0005, 0x00c8, 0x4977, 0xa184, 0x4000, 0x00c0, 0x4961, 0xa19c,
+	0x300c, 0xa386, 0x2004, 0x0040, 0x4985, 0xa386, 0x0008, 0x0040,
+	0x4990, 0xa386, 0x200c, 0x00c0, 0x4961, 0x7200, 0x8204, 0x0048,
+	0x4990, 0x730c, 0xa384, 0x00ff, 0x0040, 0x4990, 0x1078, 0x248c,
+	0x7007, 0x0012, 0x7000, 0xa084, 0x0001, 0x00c0, 0x49aa, 0x7008,
+	0xa084, 0x01e0, 0x00c0, 0x49aa, 0x7310, 0x7014, 0xa305, 0x0040,
+	0x49aa, 0x710c, 0xa184, 0x0300, 0x00c0, 0x49aa, 0xa184, 0x00ff,
+	0x00c0, 0x4957, 0x7007, 0x0012, 0x7007, 0x0008, 0x7004, 0xa084,
+	0x0008, 0x00c0, 0x49ae, 0x7007, 0x0012, 0x7108, 0x8103, 0x0048,
+	0x49b3, 0x7003, 0x0000, 0x2049, 0x0000, 0x007c, 0x107e, 0x007e,
+	0x127e, 0x157e, 0x2091, 0x2200, 0x7108, 0x1078, 0x49ce, 0x157f,
+	0x127f, 0x2091, 0x8001, 0x007f, 0x107f, 0x007c, 0x7204, 0x7500,
+	0x730c, 0xa384, 0x0300, 0x00c0, 0x49f5, 0xa184, 0x01e0, 0x00c0,
+	0x4a19, 0x7108, 0xa184, 0x01e0, 0x00c0, 0x4a19, 0x2001, 0x04fd,
+	0x2004, 0xa082, 0x0005, 0x00c8, 0x49e9, 0xa184, 0x4000, 0x00c0,
+	0x49d9, 0xa184, 0x0007, 0x0079, 0x49ed, 0x49f7, 0x4a09, 0x49f5,
+	0x4a09, 0x49f5, 0x4a55, 0x49f5, 0x4a53, 0x1078, 0x248c, 0x7004,
+	0xa084, 0x0010, 0xa085, 0x0002, 0x7006, 0x8aff, 0x00c0, 0x4a04,
+	0x2049, 0x0000, 0x0078, 0x4a08, 0x1078, 0x4c18, 0x00c0, 0x4a04,
+	0x007c, 0x7004, 0xa084, 0x0010, 0xa085, 0x0002, 0x7006, 0x8aff,
+	0x00c0, 0x4a14, 0x0078, 0x4a18, 0x1078, 0x4c18, 0x00c0, 0x4a14,
+	0x007c, 0x7007, 0x0012, 0x7108, 0x00e0, 0x4a1c, 0x2091, 0x6000,
+	0x00e0, 0x4a20, 0x2091, 0x6000, 0x7007, 0x0012, 0x7007, 0x0008,
+	0x7004, 0xa084, 0x0008, 0x00c0, 0x4a28, 0x7007, 0x0012, 0x7108,
+	0x8103, 0x0048, 0x4a2d, 0x7003, 0x0000, 0x7000, 0xa005, 0x00c0,
+	0x4a41, 0x7004, 0xa005, 0x00c0, 0x4a41, 0x700c, 0xa005, 0x0040,
+	0x4a43, 0x0078, 0x4a24, 0x2049, 0x0000, 0x1078, 0x38d7, 0x6818,
+	0xa084, 0x8000, 0x0040, 0x4a4e, 0x681b, 0x0002, 0x007c, 0x1078,
+	0x248c, 0x1078, 0x248c, 0x1078, 0x4ab1, 0x7210, 0x7114, 0x700c,
+	0xa09c, 0x00ff, 0x2800, 0xa300, 0xa211, 0xa189, 0x0000, 0x1078,
+	0x4ab1, 0x2704, 0x2c58, 0xac60, 0x6308, 0x2200, 0xa322, 0x630c,
+	0x2100, 0xa31b, 0x2400, 0xa305, 0x0040, 0x4a78, 0x00c8, 0x4a78,
+	0x8412, 0x8210, 0x830a, 0xa189, 0x0000, 0x2b60, 0x0078, 0x4a5f,
+	0x2b60, 0x8a07, 0x007e, 0x6004, 0xa084, 0x0008, 0x0040, 0x4a84,
+	0xa7ba, 0x4917, 0x0078, 0x4a86, 0xa7ba, 0x490f, 0x007f, 0xa73d,
+	0x2c00, 0x6886, 0x6f8a, 0x6c92, 0x6b8e, 0x7007, 0x0012, 0x1078,
+	0x4957, 0x007c, 0x8738, 0x2704, 0xa005, 0x00c0, 0x4aa5, 0x609c,
+	0xa005, 0x0040, 0x4aae, 0x2060, 0x6004, 0xa084, 0x000f, 0xa080,
+	0x491d, 0x203c, 0x87fb, 0x1040, 0x248c, 0x8a51, 0x0040, 0x4aad,
+	0x7008, 0xa084, 0x0003, 0xa086, 0x0003, 0x007c, 0x2051, 0x0000,
+	0x007c, 0x8a50, 0x8739, 0x2704, 0xa004, 0x00c0, 0x4ac5, 0x6000,
+	0xa064, 0x00c0, 0x4abc, 0x2d60, 0x6004, 0xa084, 0x000f, 0xa080,
+	0x492d, 0x203c, 0x87fb, 0x1040, 0x248c, 0x007c, 0x127e, 0x0d7e,
+	0x2091, 0x2200, 0x0d7f, 0x6884, 0x2060, 0x6888, 0x6b8c, 0x6c90,
+	0x8057, 0xaad4, 0x00ff, 0xa084, 0x00ff, 0x007e, 0x6804, 0xa084,
+	0x0008, 0x007f, 0x0040, 0x4ae0, 0xa0b8, 0x4917, 0x0078, 0x4ae2,
+	0xa0b8, 0x490f, 0x7e08, 0xa6b5, 0x000c, 0x6904, 0xa18c, 0x00ff,
+	0xa186, 0x0007, 0x0040, 0x4af0, 0xa18e, 0x000f, 0x00c0, 0x4af9,
+	0x681c, 0xa084, 0x0040, 0x0040, 0x4b00, 0xa6b5, 0x0001, 0x0078,
+	0x4b00, 0x681c, 0xa084, 0x0040, 0x0040, 0x4b00, 0xa6b5, 0x0001,
+	0x7007, 0x0004, 0x7004, 0xa084, 0x0004, 0x00c0, 0x4b02, 0x2400,
+	0xa305, 0x00c0, 0x4b0d, 0x0078, 0x4b33, 0x2c58, 0x2704, 0x6104,
+	0xac60, 0x6000, 0xa400, 0x701a, 0x6004, 0xa301, 0x701e, 0xa184,
+	0x0008, 0x0040, 0x4b23, 0x6010, 0xa081, 0x0000, 0x7022, 0x6014,
+	0xa081, 0x0000, 0x7026, 0x6208, 0x2400, 0xa202, 0x7012, 0x620c,
+	0x2300, 0xa203, 0x7016, 0x7602, 0x7007, 0x0001, 0x2b60, 0x1078,
+	0x4a92, 0x0078, 0x4b35, 0x1078, 0x4c18, 0x00c0, 0x4b33, 0x127f,
+	0x2000, 0x007c, 0x127e, 0x0d7e, 0x2091, 0x2200, 0x0d7f, 0x7007,
+	0x0004, 0x7004, 0xa084, 0x0004, 0x00c0, 0x4b41, 0x7003, 0x0008,
+	0x127f, 0x2000, 0x007c, 0x127e, 0x0d7e, 0x2091, 0x2200, 0x0d7f,
+	0x2049, 0x4b4b, 0x7007, 0x0004, 0x7004, 0xa084, 0x0004, 0x00c0,
+	0x4b54, 0x7e08, 0xa6b5, 0x000c, 0x6904, 0xa18c, 0x00ff, 0xa186,
+	0x0007, 0x0040, 0x4b67, 0xa18e, 0x000f, 0x00c0, 0x4b72, 0x681c,
+	0xa084, 0x0040, 0x0040, 0x4b6e, 0xa6b5, 0x0001, 0x6840, 0x2050,
+	0x0078, 0x4b7b, 0x681c, 0xa084, 0x0020, 0x00c0, 0x4b79, 0xa6b5,
+	0x0001, 0x6828, 0x2050, 0x2d60, 0x6004, 0xa0bc, 0x000f, 0xa7b8,
+	0x491d, 0x273c, 0x87fb, 0x00c0, 0x4b8f, 0x0048, 0x4b89, 0x1078,
+	0x248c, 0x689c, 0xa065, 0x0040, 0x4b93, 0x0078, 0x4b7c, 0x1078,
+	0x4c18, 0x00c0, 0x4b8f, 0x127f, 0x2000, 0x007c, 0x127e, 0x007e,
+	0x017e, 0x0d7e, 0x2091, 0x2200, 0x0d7f, 0x037f, 0x047f, 0x7e08,
+	0xa6b5, 0x000c, 0x6904, 0xa18c, 0x00ff, 0xa186, 0x0007, 0x0040,
+	0x4bad, 0xa18e, 0x000f, 0x00c0, 0x4bb6, 0x681c, 0xa084, 0x0040,
+	0x0040, 0x4bbd, 0xa6b5, 0x0001, 0x0078, 0x4bbd, 0x681c, 0xa084,
+	0x0040, 0x0040, 0x4bbd, 0xa6b5, 0x0001, 0x2049, 0x4b96, 0x017e,
+	0x6904, 0xa18c, 0x00ff, 0xa186, 0x0007, 0x0040, 0x4bcb, 0xa18e,
+	0x000f, 0x00c0, 0x4bce, 0x6840, 0x0078, 0x4bcf, 0x6828, 0x017f,
+	0xa055, 0x0040, 0x4c15, 0x2d70, 0x2e60, 0x7004, 0xa0bc, 0x000f,
+	0xa7b8, 0x491d, 0x273c, 0x87fb, 0x00c0, 0x4be9, 0x0048, 0x4be2,
+	0x1078, 0x248c, 0x709c, 0xa075, 0x2060, 0x0040, 0x4c15, 0x0078,
+	0x4bd5, 0x2704, 0xae68, 0x6808, 0xa422, 0x680c, 0xa31b, 0x0048,
+	0x4c02, 0x8a51, 0x00c0, 0x4bf6, 0x1078, 0x248c, 0x8738, 0x2704,
+	0xa005, 0x00c0, 0x4bea, 0x709c, 0xa075, 0x2060, 0x0040, 0x4c15,
+	0x0078, 0x4bd5, 0x8422, 0x8420, 0x831a, 0xa399, 0x0000, 0x6908,
+	0x2400, 0xa122, 0x690c, 0x2300, 0xa11b, 0x00c8, 0x4c11, 0x1078,
+	0x248c, 0x2071, 0x0020, 0x0078, 0x4b00, 0x127f, 0x2000, 0x007c,
+	0x7008, 0xa084, 0x0003, 0xa086, 0x0003, 0x0040, 0x4c40, 0x2704,
+	0xac08, 0x2104, 0x701a, 0x8108, 0x2104, 0x701e, 0x8108, 0x2104,
+	0x7012, 0x8108, 0x2104, 0x7016, 0x6004, 0xa084, 0x0008, 0x0040,
+	0x4c37, 0x8108, 0x2104, 0x7022, 0x8108, 0x2104, 0x7026, 0x7602,
+	0x7004, 0xa084, 0x0010, 0xa085, 0x0001, 0x7006, 0x1078, 0x4a92,
+	0x007c, 0x127e, 0x007e, 0x0d7e, 0x2091, 0x2200, 0x2049, 0x4c41,
+	0x0d7f, 0x087f, 0x7108, 0xa184, 0x0003, 0x00c0, 0x4c6b, 0x017e,
+	0x6904, 0xa18c, 0x00ff, 0xa186, 0x0007, 0x0040, 0x4c5b, 0xa18e,
+	0x000f, 0x00c0, 0x4c5e, 0x6840, 0x0078, 0x4c5f, 0x6828, 0x017f,
+	0xa005, 0x0040, 0x4c79, 0x0078, 0x489e, 0x0020, 0x4c6b, 0x1078,
+	0x4a55, 0x0078, 0x4c79, 0x00a0, 0x4c72, 0x7108, 0x1078, 0x49ce,
+	0x0078, 0x4c4a, 0x7007, 0x0010, 0x00a0, 0x4c74, 0x7108, 0x1078,
+	0x49ce, 0x7008, 0xa086, 0x0008, 0x00c0, 0x4c4a, 0x7000, 0xa005,
+	0x00c0, 0x4c4a, 0x7003, 0x0000, 0x2049, 0x0000, 0x127f, 0x2000,
+	0x007c, 0x127e, 0x147e, 0x137e, 0x157e, 0x0c7e, 0x0d7e, 0x2091,
+	0x2200, 0x0d7f, 0x2049, 0x4c89, 0xad80, 0x0011, 0x20a0, 0x2099,
+	0x0031, 0x700c, 0xa084, 0x00ff, 0x682a, 0x7007, 0x0008, 0x7007,
+	0x0002, 0x7003, 0x0001, 0x0040, 0x4ca8, 0x8000, 0x80ac, 0x53a5,
+	0x7007, 0x0004, 0x7004, 0xa084, 0x0004, 0x00c0, 0x4caa, 0x0c7f,
+	0x2049, 0x0000, 0x7003, 0x0000, 0x157f, 0x137f, 0x147f, 0x127f,
+	0x2000, 0x007c, 0x2091, 0x6000, 0x2091, 0x8000, 0x78cc, 0xa005,
+	0x0040, 0x4cd1, 0x7994, 0x70d0, 0xa106, 0x00c0, 0x4cd1, 0x7804,
+	0xa005, 0x0040, 0x4cd1, 0x7807, 0x0000, 0x0068, 0x4cd1, 0x2091,
+	0x4080, 0x7820, 0x8001, 0x7822, 0x00c0, 0x4d2c, 0x7824, 0x7822,
+	0x2069, 0x5240, 0x6800, 0xa084, 0x0007, 0x0040, 0x4cef, 0xa086,
+	0x0002, 0x0040, 0x4cef, 0x6834, 0xa00d, 0x0040, 0x4cef, 0x2104,
+	0xa005, 0x0040, 0x4cef, 0x8001, 0x200a, 0x0040, 0x4dd4, 0x7848,
+	0xa005, 0x0040, 0x4cfd, 0x8001, 0x784a, 0x00c0, 0x4cfd, 0x2009,
+	0x0102, 0x6844, 0x200a, 0x1078, 0x226f, 0x6890, 0xa005, 0x0040,
+	0x4d09, 0x8001, 0x6892, 0x00c0, 0x4d09, 0x686f, 0x0000, 0x6873,
+	0x0001, 0x2061, 0x5500, 0x20a9, 0x0100, 0x2009, 0x0002, 0x6034,
+	0xa005, 0x0040, 0x4d1f, 0x8001, 0x6036, 0x00c0, 0x4d1f, 0x6010,
+	0xa005, 0x0040, 0x4d1f, 0x017e, 0x1078, 0x226f, 0x017f, 0xace0,
+	0x0010, 0x0070, 0x4d25, 0x0078, 0x4d0f, 0x8109, 0x0040, 0x4d2c,
+	0x20a9, 0x0100, 0x0078, 0x4d0f, 0x1078, 0x4d39, 0x1078, 0x4d5e,
+	0x2009, 0x5251, 0x2104, 0x2009, 0x0102, 0x200a, 0x2091, 0x8001,
+	0x007c, 0x7834, 0x8001, 0x7836, 0x00c0, 0x4d5d, 0x7838, 0x7836,
+	0x2091, 0x8000, 0x7844, 0xa005, 0x00c0, 0x4d48, 0x2001, 0x0101,
+	0x8001, 0x7846, 0xa080, 0x7500, 0x2040, 0x2004, 0xa065, 0x0040,
+	0x4d5d, 0x6024, 0xa005, 0x0040, 0x4d59, 0x8001, 0x6026, 0x0040,
+	0x4d8d, 0x6000, 0x2c40, 0x0078, 0x4d4e, 0x007c, 0x7828, 0x8001,
+	0x782a, 0x00c0, 0x4d8c, 0x782c, 0x782a, 0x7830, 0xa005, 0x00c0,
+	0x4d6b, 0x2001, 0x0200, 0x8001, 0x7832, 0x8003, 0x8003, 0x8003,
+	0x8003, 0xa090, 0x5500, 0xa298, 0x0002, 0x2304, 0xa084, 0x0008,
+	0x0040, 0x4d8c, 0xa290, 0x0009, 0x2204, 0xa005, 0x0040, 0x4d84,
+	0x8001, 0x2012, 0x00c0, 0x4d8c, 0x2304, 0xa084, 0xfff7, 0xa085,
+	0x0080, 0x201a, 0x1078, 0x226f, 0x007c, 0x2069, 0x5240, 0x6800,
+	0xa005, 0x0040, 0x4d97, 0x6848, 0xac06, 0x0040, 0x4dd4, 0x601b,
+	0x0006, 0x60b4, 0xa084, 0x3f00, 0x601e, 0x6020, 0xa084, 0x00ff,
+	0xa085, 0x0060, 0x6022, 0x6000, 0x2042, 0x6714, 0x6f82, 0x1078,
+	0x19c5, 0x6818, 0xa005, 0x0040, 0x4daf, 0x8001, 0x681a, 0x6808,
+	0xa084, 0xffef, 0x680a, 0x6810, 0x8001, 0x00d0, 0x4db9, 0x1078,
+	0x248c, 0x6812, 0x602f, 0x0000, 0x6033, 0x0000, 0x2c68, 0x1078,
+	0x1cdc, 0x2069, 0x5240, 0x7944, 0xa184, 0x0100, 0x2001, 0x0006,
+	0x686e, 0x00c0, 0x4dcf, 0x6986, 0x2001, 0x0004, 0x686e, 0x1078,
+	0x226a, 0x2091, 0x8001, 0x007c, 0x2069, 0x0100, 0x2009, 0x5240,
+	0x2104, 0xa084, 0x0007, 0x0040, 0x4e30, 0xa086, 0x0007, 0x00c0,
+	0x4dea, 0x0d7e, 0x2009, 0x5252, 0x216c, 0x1078, 0x3b1c, 0x0d7f,
+	0x0078, 0x4e30, 0x2009, 0x5252, 0x2164, 0x1078, 0x2437, 0x601b,
+	0x0006, 0x6858, 0xa084, 0x3f00, 0x601e, 0x6020, 0xa084, 0x00ff,
+	0xa085, 0x0048, 0x6022, 0x602f, 0x0000, 0x6033, 0x0000, 0x6830,
+	0xa084, 0x0040, 0x0040, 0x4e24, 0x684b, 0x0004, 0x20a9, 0x0014,
+	0x6848, 0xa084, 0x0004, 0x0040, 0x4e11, 0x0070, 0x4e11, 0x0078,
+	0x4e08, 0x684b, 0x0009, 0x20a9, 0x0014, 0x6848, 0xa084, 0x0001,
+	0x0040, 0x4e1e, 0x0070, 0x4e1e, 0x0078, 0x4e15, 0x20a9, 0x00fa,
+	0x0070, 0x4e24, 0x0078, 0x4e20, 0x6808, 0xa084, 0xfffd, 0x680a,
+	0x681b, 0x0048, 0x2009, 0x525b, 0x200b, 0x0007, 0x784c, 0x784a,
+	0x2091, 0x8001, 0x007c, 0x2079, 0x5200, 0x1078, 0x4e5e, 0x1078,
+	0x4e42, 0x1078, 0x4e50, 0x7833, 0x0000, 0x7847, 0x0000, 0x784b,
+	0x0000, 0x007c, 0x2019, 0x0003, 0x2011, 0x5246, 0x2204, 0xa086,
+	0x003c, 0x0040, 0x4e4d, 0x2019, 0x0002, 0x7b2a, 0x7b2e, 0x007c,
+	0x2019, 0x0039, 0x2011, 0x5246, 0x2204, 0xa086, 0x003c, 0x0040,
+	0x4e5b, 0x2019, 0x0027, 0x7b36, 0x7b3a, 0x007c, 0x2019, 0x3971,
+	0x2011, 0x5246, 0x2204, 0xa086, 0x003c, 0x0040, 0x4e69, 0x2019,
+	0x2626, 0x7b22, 0x7b26, 0x783f, 0x0000, 0x7843, 0x000a, 0x007c,
+	0x0020, 0x002b, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020,
+	0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020,
+	0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020,
+	0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020,
+	0x0000, 0x0020, 0x0000, 0x0014, 0x0014, 0x9849, 0x0014, 0x0014,
+	0x0014, 0x0014, 0x0014, 0x0014, 0x0014, 0x0080, 0x000f, 0x0000,
+	0x0201, 0x0604, 0x0c08, 0x2120, 0x4022, 0xf880, 0x0018, 0x300b,
+	0xa201, 0x0014, 0xa200, 0x0014, 0xa200, 0x0214, 0x0000, 0x006c,
+	0x0002, 0x0014, 0x98cd, 0x009e, 0x0093, 0xa202, 0x8838, 0x3806,
+	0x8839, 0x20c3, 0x0864, 0x9885, 0x28c1, 0x9cae, 0xa203, 0x300c,
+	0x2846, 0x8161, 0x846a, 0x8300, 0x1856, 0x883a, 0x9865, 0x28f2,
+	0x9c91, 0x9858, 0x300c, 0x28e1, 0x9c91, 0x2802, 0xa206, 0x64c3,
+	0x282e, 0xa207, 0x64a0, 0x6de0, 0x67a0, 0x6fc0, 0x1814, 0x883b,
+	0x7824, 0x68c1, 0x7864, 0x883e, 0x9879, 0x8576, 0x8677, 0x206b,
+	0x28c1, 0x9cae, 0x2044, 0x2103, 0x20a2, 0x2081, 0x9865, 0xa209,
+	0x2901, 0x988d, 0x0014, 0xa205, 0xa300, 0x1872, 0x879a, 0x883c,
+	0x1fe2, 0xc601, 0xa20a, 0x856e, 0x0704, 0x9c91, 0x0014, 0xa204,
+	0xa300, 0x3009, 0x19e2, 0xf864, 0x856e, 0x883f, 0x08e6, 0x9891,
+	0xf881, 0x988c, 0xc801, 0x0014, 0xf8c1, 0x0016, 0x85b2, 0x80f0,
+	0x9532, 0xfb02, 0x1de2, 0x0014, 0x8532, 0xf241, 0x0014, 0x1de2,
+	0x84a8, 0xd7a0, 0x1fe6, 0x0014, 0xa208, 0x6043, 0x8008, 0x1dc1,
+	0x0016, 0x8300, 0x8160, 0x842a, 0xf041, 0x3008, 0x84a8, 0x11d6,
+	0x7042, 0x20dd, 0x0011, 0x20d5, 0x8822, 0x0016, 0x8000, 0x2847,
+	0x1011, 0x98c0, 0x8000, 0xa000, 0x2802, 0x1011, 0x98c6, 0x9865,
+	0x283e, 0x1011, 0x98ca, 0xa20b, 0x0017, 0x300c, 0xa300, 0x1de2,
+	0xdb81, 0x0014, 0x0210, 0x98d7, 0x0014, 0x26e0, 0x873a, 0xfb02,
+	0x19f2, 0x1fe2, 0x0014, 0xa20d, 0x3806, 0x0210, 0x9cb3, 0x0704,
+	0x0000, 0x006c, 0x0002, 0x984f, 0x0014, 0x009e, 0x00a0, 0x0017,
+	0x60ff, 0x300c, 0x8720, 0xa211, 0x9cd0, 0x8772, 0x8837, 0x2101,
+	0x987a, 0x10d2, 0x78e2, 0x9cd3, 0x9859, 0xd984, 0xf0e2, 0xf0a1,
+	0x98cd, 0x0014, 0x8831, 0xd166, 0x8830, 0x800f, 0x9401, 0xb520,
+	0xc802, 0x8820, 0x987a, 0x2301, 0x987a, 0x10d2, 0x78e4, 0x9cd3,
+	0x8821, 0x8820, 0x9859, 0xf123, 0xf142, 0xf101, 0x98c6, 0x10d2,
+	0x70f6, 0x8832, 0x8203, 0x870c, 0xd99e, 0x6001, 0x0014, 0x6845,
+	0x0214, 0xa21b, 0x9cd0, 0x2001, 0x98c5, 0x8201, 0x1852, 0xd184,
+	0xd163, 0x8834, 0x8001, 0x988d, 0x3027, 0x84a8, 0x1a56, 0x8833,
+	0x0014, 0xa218, 0x6981, 0x9cbc, 0x6926, 0x6902, 0x1a34, 0x9899,
+	0x1a14, 0x7021, 0x0014, 0xa300, 0x6141, 0x6964, 0x8010, 0x8592,
+	0x8026, 0x84b9, 0x69e4, 0x8023, 0x16e1, 0x8001, 0x10f1, 0x6946,
+	0xa213, 0x1462, 0xa213, 0x8000, 0x16e1, 0x98b5, 0x6969, 0xa214,
+	0x61c2, 0x8002, 0x14e1, 0x8004, 0x16e1, 0x0101, 0x300a, 0x8827,
+	0x0014, 0xa217, 0x9cbc, 0x0014, 0xa300, 0x8181, 0x842a, 0x84a8,
+	0x1ce6, 0x882c, 0x0016, 0xa212, 0x9cd0, 0x10d2, 0x70e4, 0x0004,
+	0x8007, 0x9424, 0xcc1a, 0x9cd3, 0x98c5, 0x8827, 0x300a, 0x0013,
+	0x8000, 0x84a4, 0x0016, 0x11c2, 0x211e, 0x870e, 0xa21d, 0x0014,
+	0x878e, 0x0016, 0xa21c, 0x1035, 0x9891, 0xa210, 0xa000, 0x8010,
+	0x8592, 0x853b, 0xd044, 0x8022, 0x3807, 0x84bb, 0x98ea, 0x8021,
+	0x3807, 0x84b9, 0x300c, 0x817e, 0x872b, 0x8772, 0x9891, 0x0000,
+	0x0020, 0x002b, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020,
+	0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020,
+	0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020,
+	0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020,
+	0x0000, 0x0020, 0x0000, 0x0014, 0x0014, 0x9849, 0x0014, 0x0014,
+	0x98e2, 0x98cd, 0x0014, 0x0014, 0x0014, 0x0080, 0x0137, 0x0000,
+	0x0201, 0x0604, 0x0c08, 0x2120, 0x4022, 0xf880, 0x0018, 0x300b,
+	0xa201, 0x0014, 0xa200, 0x0014, 0xa200, 0x0214, 0xa202, 0x8838,
+	0x3806, 0x8839, 0x20c3, 0x0864, 0xa82f, 0x28c1, 0x9cae, 0xa203,
+	0x300c, 0x2846, 0x8161, 0x846a, 0x8300, 0x1856, 0x883a, 0xa804,
+	0x28f2, 0x9c91, 0xa8f4, 0x300c, 0x28e1, 0x9c91, 0x2802, 0xa206,
+	0x64c3, 0x282e, 0xa207, 0x64a0, 0x6de0, 0x67a0, 0x6fc0, 0x1814,
+	0x883b, 0x7824, 0x68c1, 0x7864, 0x883e, 0xa802, 0x8576, 0x8677,
+	0x206b, 0x28c1, 0x9cae, 0x2044, 0x2103, 0x20a2, 0x2081, 0xa8e4,
+	0xa209, 0x2901, 0xa809, 0x0014, 0xa205, 0xa300, 0x1872, 0x879a,
+	0x883c, 0x1fe2, 0xc601, 0xa20a, 0x856e, 0x0704, 0x9c91, 0x0014,
+	0xa204, 0xa300, 0x3009, 0x19e2, 0xf864, 0x856e, 0x883f, 0x08e6,
+	0xa8f7, 0xf881, 0xa8f0, 0xc801, 0x0014, 0xf8c1, 0x0016, 0x85b2,
+	0x80f0, 0x9532, 0xfb02, 0x1de2, 0x0014, 0x8532, 0xf241, 0x0014,
+	0x1de2, 0x84a8, 0xd7a0, 0x1fe6, 0x0014, 0xa208, 0x6043, 0x8008,
+	0x1dc1, 0x0016, 0x8300, 0x8160, 0x842a, 0xf041, 0x3008, 0x84a8,
+	0x11d6, 0x7042, 0x20dd, 0x0011, 0x20d5, 0x8822, 0x0016, 0x8000,
+	0x2847, 0x1011, 0xa8fc, 0x8000, 0xa000, 0x2802, 0x1011, 0xa8fd,
+	0xa89b, 0x283e, 0x1011, 0xa8fd, 0xa20b, 0x0017, 0x300c, 0xa300,
+	0x1de2, 0xdb81, 0x0014, 0x0210, 0xa801, 0x0014, 0x26e0, 0x873a,
+	0xfb02, 0x19f2, 0x1fe2, 0x0014, 0xa20d, 0x3806, 0x0210, 0x9cb3,
+	0x0704, 0x0017, 0x60ff, 0x300c, 0x8720, 0xa211, 0x9d63, 0x8772,
+	0x8837, 0x2101, 0xa821, 0x10d2, 0x78e2, 0x9d66, 0xa8fc, 0xd984,
+	0xf0e2, 0xf0a1, 0xa86c, 0x0014, 0x8831, 0xd166, 0x8830, 0x800f,
+	0x9401, 0xb520, 0xc802, 0x8820, 0xa80f, 0x2301, 0xa80d, 0x10d2,
+	0x78e4, 0x9d66, 0x8821, 0x8820, 0xa8e6, 0xf123, 0xf142, 0xf101,
+	0xa84f, 0x10d2, 0x70f6, 0x8832, 0x8203, 0x870c, 0xd99e, 0x6001,
+	0x0014, 0x6845, 0x0214, 0xa21b, 0x9d63, 0x2001, 0xa840, 0x8201,
+	0x1852, 0xd184, 0xd163, 0x8834, 0x8001, 0xa801, 0x3027, 0x84a8,
+	0x1a56, 0x8833, 0x0014, 0xa218, 0x6981, 0x9d4f, 0x6926, 0x6902,
+	0x1a34, 0xa801, 0x1a14, 0x7021, 0x0014, 0xa300, 0x6141, 0x6964,
+	0x8010, 0x8592, 0x8026, 0x84b9, 0x69e4, 0x8023, 0x16e1, 0x8001,
+	0x10f1, 0x6946, 0xa213, 0x1462, 0xa213, 0x8000, 0x16e1, 0xa807,
+	0x6969, 0xa214, 0x61c2, 0x8002, 0x14e1, 0x8004, 0x16e1, 0x0101,
+	0x300a, 0x8827, 0x0014, 0xa217, 0x9d4f, 0x0014, 0xa300, 0x8181,
+	0x842a, 0x84a8, 0x1ce6, 0x882c, 0x0016, 0xa212, 0x9d63, 0x10d2,
+	0x70e4, 0x0004, 0x8007, 0x9424, 0xcc1a, 0x9d66, 0xa8f8, 0x8827,
+	0x300a, 0x0013, 0x8000, 0x84a4, 0x0016, 0x11c2, 0x211e, 0x870e,
+	0xa21d, 0x0014, 0x878e, 0x0016, 0xa21c, 0x1035, 0xa8b4, 0xa210,
+	0x3807, 0x300c, 0x817e, 0x872b, 0x8772, 0xa8ad, 0x0000, 0x0d0c
 };
-static unsigned short   risc_code_length01 = 0x4057;
-
+static unsigned short risc_code_length01 = 0x4158;
diff --git a/drivers/scsi/ql12160_fw.h b/drivers/scsi/ql12160_fw.h
--- a/drivers/scsi/ql12160_fw.h
+++ b/drivers/scsi/ql12160_fw.h
@@ -22,19 +22,19 @@
  ************************************************************************/
 
 /*
- *	Firmware Version 10.04.32 (12:03 May 09, 2001)
+ *	Firmware Version 10.04.42 (15:44 Apr 18, 2003)
  */
 
 #ifdef UNIQUE_FW_NAME
-static unsigned char fw12160i_version_str[] = {10,4,32};
+static unsigned char fw12160i_version_str[] = {10,4,42};
 #else
-static unsigned char firmware_version[] = {10,4,32};
+static unsigned char firmware_version[] = {10,4,42};
 #endif
 
 #ifdef UNIQUE_FW_NAME
-#define fw12160i_VERSION_STRING "10.04.32"
+#define fw12160i_VERSION_STRING "10.04.42"
 #else
-#define FW_VERSION_STRING "10.04.32"
+#define FW_VERSION_STRING "10.04.42"
 #endif
 
 #ifdef UNIQUE_FW_NAME
@@ -48,7 +48,7 @@ static unsigned short fw12160i_code01[] 
 #else
 static unsigned short risc_code01[] = {
 #endif
-	0x0804, 0x1041, 0x0000, 0x35e6, 0x0000, 0x2043, 0x4f50, 0x5952,
+	0x0804, 0x1041, 0x0000, 0x36c9, 0x0000, 0x2043, 0x4f50, 0x5952,
 	0x4947, 0x4854, 0x2031, 0x3939, 0x312c, 0x3139, 0x3932, 0x2c31,
 	0x3939, 0x332c, 0x3139, 0x3934, 0x2051, 0x4c4f, 0x4749, 0x4320,
 	0x434f, 0x5250, 0x4f52, 0x4154, 0x494f, 0x4e00, 0x2049, 0x5350,
@@ -56,112 +56,112 @@ static unsigned short risc_code01[] = {
 	0x6572, 0x7369, 0x6f6e, 0x2031, 0x302e, 0x3034, 0x2020, 0x2043,
 	0x7573, 0x746f, 0x6d65, 0x7220, 0x4e6f, 0x2e20, 0x3030, 0x2050,
 	0x726f, 0x6475, 0x6374, 0x204e, 0x6f2e, 0x2020, 0x3030, 0x2020,
-	0x2400, 0x20c9, 0x8fff, 0x2071, 0x0200, 0x70a0, 0x70a2, 0x2001,
+	0x2400, 0x20c9, 0x90ff, 0x2071, 0x0200, 0x70a0, 0x70a2, 0x2001,
 	0x01ff, 0x2004, 0xd0fc, 0x1120, 0x2071, 0x0100, 0x70a0, 0x70a2,
 	0x20c1, 0x0020, 0x2089, 0x1221, 0x2071, 0x0010, 0x70c3, 0x0004,
 	0x70c7, 0x4953, 0x70cb, 0x5020, 0x70cf, 0x2020, 0x70d3, 0x000a,
 	0x2001, 0x04fd, 0x2004, 0x70d6, 0x2009, 0xfeff, 0x2130, 0x2128,
-	0xa1a2, 0x4600, 0x8424, 0x8424, 0x8424, 0x8424, 0x8424, 0x8424,
-	0xa192, 0x9000, 0x2009, 0x0000, 0x2001, 0x0032, 0x080c, 0x1de8,
-	0x2218, 0x2079, 0x4600, 0x2fa0, 0x2408, 0x2011, 0x0000, 0x20a9,
+	0xa1a2, 0x4700, 0x8424, 0x8424, 0x8424, 0x8424, 0x8424, 0x8424,
+	0xa192, 0x9100, 0x2009, 0x0000, 0x2001, 0x0032, 0x080c, 0x1e05,
+	0x2218, 0x2079, 0x4700, 0x2fa0, 0x2408, 0x2011, 0x0000, 0x20a9,
 	0x0040, 0x42a4, 0x8109, 0x1dd8, 0x2009, 0xff00, 0x3400, 0xa102,
 	0x0218, 0x0110, 0x20a8, 0x42a4, 0x781b, 0x0064, 0x7814, 0xc0cd,
-	0xc0d5, 0x7816, 0x2071, 0x0200, 0x00d6, 0x2069, 0x4640, 0x080c,
-	0x459a, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1130, 0x2069, 0x4680,
-	0x2071, 0x0100, 0x080c, 0x459a, 0x7814, 0xc0d4, 0x7816, 0x00de,
+	0xc0d5, 0x7816, 0x2071, 0x0200, 0x00d6, 0x2069, 0x4740, 0x080c,
+	0x465c, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1130, 0x2069, 0x4780,
+	0x2071, 0x0100, 0x080c, 0x465c, 0x7814, 0xc0d4, 0x7816, 0x00de,
 	0x7eca, 0x7cc2, 0x7bc6, 0x7867, 0x0000, 0x7800, 0xc08d, 0x7802,
 	0x2031, 0x0030, 0x78af, 0x0101, 0x7823, 0x0002, 0x7827, 0x0002,
-	0x2009, 0x0002, 0x2069, 0x4640, 0x681b, 0x0003, 0x6823, 0x0007,
+	0x2009, 0x0002, 0x2069, 0x4740, 0x681b, 0x0003, 0x6823, 0x0007,
 	0x6827, 0x00fa, 0x682b, 0x0008, 0x682f, 0x0028, 0x6837, 0x0006,
 	0x6833, 0x0008, 0x683b, 0x0000, 0x8109, 0x0500, 0x68cf, 0x000a,
-	0x68bf, 0x46c0, 0x2079, 0x4600, 0x68d3, 0x762d, 0x68c3, 0x4bc0,
-	0x68c7, 0x4ac0, 0x68cb, 0x8bc0, 0x68a7, 0x8e44, 0x68ab, 0x8e49,
-	0x68af, 0x8e44, 0x68b3, 0x8e44, 0x68a3, 0x0001, 0x2001, 0x01ff,
-	0x2004, 0xd0fc, 0x11c8, 0x2069, 0x4680, 0x0870, 0x68cf, 0x000a,
-	0x68bf, 0x48c0, 0x68d3, 0x7839, 0x68c3, 0x6bc0, 0x68c7, 0x4b40,
-	0x68cb, 0x8cd0, 0x68a7, 0x8e49, 0x68ab, 0x8e4e, 0x68af, 0x8e49,
-	0x68b3, 0x8e49, 0x68a3, 0x0001, 0x00e6, 0x2069, 0x4ac0, 0x2071,
+	0x68bf, 0x47c0, 0x2079, 0x4700, 0x68d3, 0x762d, 0x68c3, 0x4cc0,
+	0x68c7, 0x4bc0, 0x68cb, 0x8cc0, 0x68a7, 0x8f44, 0x68ab, 0x8f49,
+	0x68af, 0x8f44, 0x68b3, 0x8f44, 0x68a3, 0x0001, 0x2001, 0x01ff,
+	0x2004, 0xd0fc, 0x11c8, 0x2069, 0x4780, 0x0870, 0x68cf, 0x000a,
+	0x68bf, 0x49c0, 0x68d3, 0x7839, 0x68c3, 0x6cc0, 0x68c7, 0x4c40,
+	0x68cb, 0x8dd0, 0x68a7, 0x8f49, 0x68ab, 0x8f4e, 0x68af, 0x8f49,
+	0x68b3, 0x8f49, 0x68a3, 0x0001, 0x00e6, 0x2069, 0x4bc0, 0x2071,
 	0x0200, 0x70ec, 0xd0e4, 0x2019, 0x1809, 0x2021, 0x0009, 0x1120,
-	0x2019, 0x180c, 0x2021, 0x000c, 0x080c, 0x1d58, 0x2001, 0x01ff,
-	0x2004, 0xd0fc, 0x1188, 0x2069, 0x4b40, 0x2071, 0x0100, 0x70ec,
+	0x2019, 0x180c, 0x2021, 0x000c, 0x080c, 0x1d75, 0x2001, 0x01ff,
+	0x2004, 0xd0fc, 0x1188, 0x2069, 0x4c40, 0x2071, 0x0100, 0x70ec,
 	0xd0e4, 0x2019, 0x1809, 0x2021, 0x0009, 0x1120, 0x2019, 0x180c,
-	0x2021, 0x000c, 0x080c, 0x1d58, 0x00ee, 0x2011, 0x0002, 0x2069,
-	0x4bc0, 0x2009, 0x0002, 0x20a9, 0x0100, 0x6837, 0x0000, 0x680b,
+	0x2021, 0x000c, 0x080c, 0x1d75, 0x00ee, 0x2011, 0x0002, 0x2069,
+	0x4cc0, 0x2009, 0x0002, 0x20a9, 0x0100, 0x6837, 0x0000, 0x680b,
 	0x0040, 0x7bc8, 0xa386, 0xfeff, 0x1128, 0x6817, 0x0100, 0x681f,
 	0x0064, 0x0020, 0x6817, 0x0064, 0x681f, 0x0002, 0xade8, 0x0010,
 	0x1f04, 0x1135, 0x8109, 0x1d38, 0x2001, 0x01ff, 0x2004, 0xd0fc,
-	0x1128, 0x8211, 0x0118, 0x2069, 0x6bc0, 0x08d8, 0x080c, 0x22cf,
-	0x080c, 0x4015, 0x080c, 0x1b6d, 0x080c, 0x4553, 0x2091, 0x2200,
-	0x2079, 0x4600, 0x2071, 0x0050, 0x2091, 0x2400, 0x2079, 0x4600,
-	0x2071, 0x0020, 0x2091, 0x2600, 0x2079, 0x0200, 0x2071, 0x4640,
-	0x2091, 0x2800, 0x2079, 0x0100, 0x2071, 0x4680, 0x2091, 0x2000,
-	0x2079, 0x4600, 0x2071, 0x0010, 0x3200, 0xa085, 0x303d, 0x2090,
+	0x1128, 0x8211, 0x0118, 0x2069, 0x6cc0, 0x08d8, 0x080c, 0x22f6,
+	0x080c, 0x403d, 0x080c, 0x1b8c, 0x080c, 0x4615, 0x2091, 0x2200,
+	0x2079, 0x4700, 0x2071, 0x0050, 0x2091, 0x2400, 0x2079, 0x4700,
+	0x2071, 0x0020, 0x2091, 0x2600, 0x2079, 0x0200, 0x2071, 0x4740,
+	0x2091, 0x2800, 0x2079, 0x0100, 0x2071, 0x4780, 0x2091, 0x2000,
+	0x2079, 0x4700, 0x2071, 0x0010, 0x3200, 0xa085, 0x303d, 0x2090,
 	0x2071, 0x0010, 0x70c3, 0x0000, 0x1004, 0x118c, 0x70c0, 0xa086,
 	0x0002, 0x1110, 0x080c, 0x13ba, 0x2039, 0x0000, 0x080c, 0x12ab,
 	0x78ac, 0xa005, 0x1180, 0x0e04, 0x119a, 0x786c, 0xa065, 0x0110,
-	0x080c, 0x207a, 0x080c, 0x1e09, 0x0e04, 0x11af, 0x786c, 0xa065,
-	0x0110, 0x080c, 0x207a, 0x0e04, 0x11af, 0x2009, 0x4647, 0x2011,
-	0x4687, 0x2104, 0x220c, 0xa105, 0x0110, 0x080c, 0x1c7c, 0x2071,
-	0x4640, 0x70a0, 0xa005, 0x01e8, 0x744c, 0xa485, 0x0000, 0x01c8,
+	0x080c, 0x20a1, 0x080c, 0x1e26, 0x0e04, 0x11af, 0x786c, 0xa065,
+	0x0110, 0x080c, 0x20a1, 0x0e04, 0x11af, 0x2009, 0x4747, 0x2011,
+	0x4787, 0x2104, 0x220c, 0xa105, 0x0110, 0x080c, 0x1c9b, 0x2071,
+	0x4740, 0x70a0, 0xa005, 0x01e8, 0x744c, 0xa485, 0x0000, 0x01c8,
 	0x2079, 0x0200, 0x2091, 0x8000, 0x72d0, 0xa28c, 0x303d, 0x2190,
-	0x080c, 0x2720, 0x2091, 0x8000, 0x2091, 0x303d, 0x0e04, 0x11d1,
-	0x2079, 0x4600, 0x786c, 0xa065, 0x0120, 0x2071, 0x0010, 0x080c,
-	0x207a, 0x1d04, 0x11d9, 0x2079, 0x4600, 0x2071, 0x0010, 0x080c,
-	0x4370, 0x2071, 0x4680, 0x70a0, 0xa005, 0x0188, 0x704c, 0xa025,
+	0x080c, 0x274c, 0x2091, 0x8000, 0x2091, 0x303d, 0x0e04, 0x11d1,
+	0x2079, 0x4700, 0x786c, 0xa065, 0x0120, 0x2071, 0x0010, 0x080c,
+	0x20a1, 0x1d04, 0x11d9, 0x2079, 0x4700, 0x2071, 0x0010, 0x080c,
+	0x4429, 0x2071, 0x4780, 0x70a0, 0xa005, 0x0188, 0x704c, 0xa025,
 	0x0170, 0x2079, 0x0100, 0x2091, 0x8000, 0x72d0, 0xa28c, 0x303d,
-	0x2190, 0x080c, 0x2720, 0x2091, 0x8000, 0x2091, 0x303d, 0x2079,
-	0x4600, 0x2071, 0x0010, 0x0e04, 0x11fa, 0x786c, 0xa065, 0x0110,
-	0x080c, 0x207a, 0x1d04, 0x118e, 0x080c, 0x4370, 0x0804, 0x118e,
+	0x2190, 0x080c, 0x274c, 0x2091, 0x8000, 0x2091, 0x303d, 0x2079,
+	0x4700, 0x2071, 0x0010, 0x0e04, 0x11fa, 0x786c, 0xa065, 0x0110,
+	0x080c, 0x20a1, 0x1d04, 0x118e, 0x080c, 0x4429, 0x0804, 0x118e,
 	0x3c00, 0xa084, 0x0007, 0x0002, 0x120c, 0x120c, 0x120e, 0x120e,
-	0x1213, 0x1213, 0x1218, 0x1218, 0x080c, 0x254c, 0x2091, 0x2400,
-	0x080c, 0x40ad, 0x0005, 0x2091, 0x2200, 0x080c, 0x40ad, 0x0005,
-	0x2091, 0x2200, 0x080c, 0x40ad, 0x2091, 0x2400, 0x080c, 0x40ad,
+	0x1213, 0x1213, 0x1218, 0x1218, 0x080c, 0x2575, 0x2091, 0x2400,
+	0x080c, 0x40d5, 0x0005, 0x2091, 0x2200, 0x080c, 0x40d5, 0x0005,
+	0x2091, 0x2200, 0x080c, 0x40d5, 0x2091, 0x2400, 0x080c, 0x40d5,
 	0x0005, 0x1241, 0x1241, 0x1242, 0x1242, 0x124d, 0x124d, 0x124d,
 	0x124d, 0x1256, 0x1256, 0x1261, 0x1261, 0x124d, 0x124d, 0x124d,
 	0x124d, 0x1270, 0x1270, 0x1270, 0x1270, 0x1270, 0x1270, 0x1270,
 	0x1270, 0x1270, 0x1270, 0x1270, 0x1270, 0x1270, 0x1270, 0x1270,
 	0x1270, 0x0cf8, 0x0006, 0x0106, 0x0126, 0x2091, 0x2800, 0x080c,
-	0x2569, 0x012e, 0x010e, 0x000e, 0x000d, 0x0006, 0x0106, 0x0126,
+	0x2592, 0x012e, 0x010e, 0x000e, 0x000d, 0x0006, 0x0106, 0x0126,
 	0x080c, 0x1200, 0x012e, 0x010e, 0x000e, 0x000d, 0x0006, 0x0106,
-	0x0126, 0x2091, 0x2600, 0x080c, 0x2569, 0x012e, 0x010e, 0x000e,
-	0x000d, 0x0006, 0x0106, 0x0126, 0x2091, 0x2600, 0x080c, 0x2569,
-	0x2091, 0x2800, 0x080c, 0x2569, 0x012e, 0x010e, 0x000e, 0x000d,
-	0x0006, 0x0106, 0x0126, 0x00d6, 0x00e6, 0x00f6, 0x2079, 0x4600,
-	0x2071, 0x0200, 0x2069, 0x4640, 0x3d00, 0xd08c, 0x0130, 0x70ec,
-	0xa084, 0x1c00, 0x78e2, 0x080c, 0x459a, 0x3d00, 0xd084, 0x0150,
-	0x2069, 0x4680, 0x2071, 0x0100, 0x70ec, 0xa084, 0x1c00, 0x78e6,
-	0x080c, 0x459a, 0x080c, 0x24fd, 0x00fe, 0x00ee, 0x00de, 0x012e,
+	0x0126, 0x2091, 0x2600, 0x080c, 0x2592, 0x012e, 0x010e, 0x000e,
+	0x000d, 0x0006, 0x0106, 0x0126, 0x2091, 0x2600, 0x080c, 0x2592,
+	0x2091, 0x2800, 0x080c, 0x2592, 0x012e, 0x010e, 0x000e, 0x000d,
+	0x0006, 0x0106, 0x0126, 0x00d6, 0x00e6, 0x00f6, 0x2079, 0x4700,
+	0x2071, 0x0200, 0x2069, 0x4740, 0x3d00, 0xd08c, 0x0130, 0x70ec,
+	0xa084, 0x1c00, 0x78e2, 0x080c, 0x465c, 0x3d00, 0xd084, 0x0150,
+	0x2069, 0x4780, 0x2071, 0x0100, 0x70ec, 0xa084, 0x1c00, 0x78e6,
+	0x080c, 0x465c, 0x080c, 0x2526, 0x00fe, 0x00ee, 0x00de, 0x012e,
 	0x010e, 0x000e, 0x000d, 0x7008, 0x800b, 0x1240, 0x7007, 0x0002,
 	0xa08c, 0x01e0, 0x1120, 0xd09c, 0x0108, 0x0887, 0x0897, 0x70c3,
 	0x4002, 0x0804, 0x13bd, 0x0e04, 0x131e, 0x2061, 0x0000, 0x6018,
 	0xd084, 0x1904, 0x131e, 0x7828, 0xa005, 0x1120, 0x0004, 0x131f,
-	0x0804, 0x131e, 0xd0fc, 0x0130, 0x0006, 0x080c, 0x1b0a, 0x000e,
-	0x0150, 0x0028, 0x0006, 0x080c, 0x1aff, 0x000e, 0x0120, 0x2001,
-	0x4007, 0x0804, 0x13bc, 0x7910, 0xd0fc, 0x1128, 0x2061, 0x4640,
-	0xc19c, 0xc7fc, 0x0020, 0x2061, 0x4680, 0xc19d, 0xc7fd, 0x6060,
+	0x0804, 0x131e, 0xd0fc, 0x0130, 0x0006, 0x080c, 0x1b29, 0x000e,
+	0x0150, 0x0028, 0x0006, 0x080c, 0x1b1e, 0x000e, 0x0120, 0x2001,
+	0x4007, 0x0804, 0x13bc, 0x7910, 0xd0fc, 0x1128, 0x2061, 0x4740,
+	0xc19c, 0xc7fc, 0x0020, 0x2061, 0x4780, 0xc19d, 0xc7fd, 0x6060,
 	0xa005, 0x1904, 0x131e, 0x7912, 0x607e, 0x7828, 0xc0fc, 0xa086,
-	0x0018, 0x1120, 0x00c6, 0x080c, 0x1916, 0x00ce, 0x782b, 0x0000,
-	0x6078, 0xa065, 0x01e0, 0x00c6, 0x609c, 0x080c, 0x1bd4, 0x00ce,
-	0x609f, 0x0000, 0x080c, 0x1a41, 0x2009, 0x0018, 0x6087, 0x0103,
+	0x0018, 0x1120, 0x00c6, 0x080c, 0x1926, 0x00ce, 0x782b, 0x0000,
+	0x6078, 0xa065, 0x01e0, 0x00c6, 0x609c, 0x080c, 0x1bf3, 0x00ce,
+	0x609f, 0x0000, 0x080c, 0x1a60, 0x2009, 0x0018, 0x6087, 0x0103,
 	0x7810, 0x0006, 0x84ff, 0x1110, 0x85ff, 0x0110, 0xc0c5, 0x7812,
-	0x080c, 0x1b15, 0x000e, 0x7812, 0x1198, 0x080c, 0x1b60, 0x7810,
-	0xd09c, 0x1118, 0x2061, 0x4640, 0x0020, 0x2061, 0x4680, 0xc09c,
+	0x080c, 0x1b34, 0x000e, 0x7812, 0x1198, 0x080c, 0x1b7f, 0x7810,
+	0xd09c, 0x1118, 0x2061, 0x4740, 0x0020, 0x2061, 0x4780, 0xc09c,
 	0x7812, 0x607b, 0x0000, 0x60d0, 0xd0c4, 0x0130, 0xc0c4, 0x60d2,
 	0x2001, 0x4005, 0x0804, 0x13bc, 0x0804, 0x13ba, 0x0005, 0xa006,
 	0x70c2, 0x70c6, 0x70ca, 0x70ce, 0x70da, 0x70c0, 0xa03d, 0xa08a,
 	0x0040, 0x1a04, 0x136c, 0x0002, 0x13ba, 0x1408, 0x13d6, 0x143c,
-	0x1470, 0x1470, 0x13ce, 0x1a59, 0x147a, 0x13c8, 0x13da, 0x13db,
-	0x13dc, 0x13dd, 0x1a5d, 0x13c8, 0x1487, 0x14db, 0x1931, 0x1a53,
-	0x13de, 0x17ba, 0x17f0, 0x1822, 0x1868, 0x1777, 0x1784, 0x1797,
-	0x17a9, 0x15b0, 0x13c8, 0x150d, 0x1518, 0x1526, 0x1534, 0x154b,
-	0x1559, 0x155c, 0x156a, 0x1578, 0x1582, 0x1596, 0x15a2, 0x13c8,
-	0x13c8, 0x13c8, 0x13c8, 0x15bd, 0x15ce, 0x15e8, 0x161c, 0x1645,
-	0x1657, 0x165a, 0x1685, 0x16be, 0x16d0, 0x1745, 0x1755, 0x13c8,
-	0x13c8, 0x13c8, 0x13c8, 0x1767, 0x2100, 0xa08a, 0x0040, 0x1a04,
-	0x13c8, 0x0002, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x1a7f,
-	0x1a85, 0x13c8, 0x13c8, 0x13c8, 0x1a89, 0x1ac9, 0x13c8, 0x13c8,
-	0x13c8, 0x13c8, 0x1403, 0x146b, 0x1482, 0x14d6, 0x192c, 0x13c8,
-	0x13c8, 0x18fb, 0x13c8, 0x1acd, 0x1a71, 0x1a7b, 0x13c8, 0x13c8,
+	0x1470, 0x1470, 0x13ce, 0x1a78, 0x147a, 0x13c8, 0x13da, 0x13db,
+	0x13dc, 0x13dd, 0x1a7c, 0x13c8, 0x1487, 0x14db, 0x1941, 0x1a72,
+	0x13de, 0x17c8, 0x17fe, 0x1830, 0x1876, 0x1785, 0x1792, 0x17a5,
+	0x17b7, 0x15bf, 0x13c8, 0x150d, 0x1518, 0x1526, 0x1534, 0x154b,
+	0x1559, 0x155c, 0x156e, 0x157c, 0x1586, 0x15a5, 0x15b1, 0x13c8,
+	0x13c8, 0x13c8, 0x13c8, 0x15cc, 0x15dd, 0x15f7, 0x162b, 0x1654,
+	0x1666, 0x1669, 0x1693, 0x16cc, 0x16de, 0x1753, 0x1763, 0x13c8,
+	0x13c8, 0x13c8, 0x13c8, 0x1775, 0x2100, 0xa08a, 0x0040, 0x1a04,
+	0x13c8, 0x0002, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x1a9e,
+	0x1aa4, 0x13c8, 0x13c8, 0x13c8, 0x1aa8, 0x1ae8, 0x13c8, 0x13c8,
+	0x13c8, 0x13c8, 0x1403, 0x146b, 0x1482, 0x14d6, 0x193c, 0x13c8,
+	0x13c8, 0x190b, 0x13c8, 0x1aec, 0x1a90, 0x1a9a, 0x13c8, 0x13c8,
 	0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8,
 	0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8,
 	0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8,
@@ -191,7 +191,7 @@ static unsigned short risc_code01[] = {
 	0x0001, 0x7008, 0xd0fc, 0x0de8, 0xa084, 0x01e0, 0x0d48, 0x70c3,
 	0x4002, 0x0804, 0x13bd, 0x75d8, 0x74dc, 0x75da, 0x74de, 0x0878,
 	0x71c4, 0x70c8, 0x2114, 0xa79e, 0x0004, 0x1108, 0x200a, 0x72ca,
-	0x0804, 0x13b9, 0x70c7, 0x000a, 0x70cb, 0x0004, 0x70cf, 0x0020,
+	0x0804, 0x13b9, 0x70c7, 0x000a, 0x70cb, 0x0004, 0x70cf, 0x002a,
 	0x0804, 0x13ba, 0x75d8, 0x76dc, 0x75da, 0x76de, 0x0018, 0x2029,
 	0x0000, 0x2530, 0x70c4, 0x72c8, 0x73cc, 0x74d0, 0x70c6, 0x72ca,
 	0x73ce, 0x74d2, 0xa005, 0x05e8, 0xa40a, 0x0108, 0x1240, 0x8001,
@@ -211,1281 +211,1286 @@ static unsigned short risc_code01[] = {
 	0xc2c5, 0x7a12, 0x7c96, 0x78ac, 0xa084, 0xfcff, 0x78ae, 0x0018,
 	0x78ac, 0xc0c5, 0x78ae, 0x0804, 0x13ba, 0x2009, 0x0000, 0x786c,
 	0xa065, 0x0118, 0x8108, 0x6000, 0x0cd8, 0x7ac4, 0x0804, 0x13b8,
-	0x2009, 0x4648, 0x210c, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904,
-	0x13b9, 0x2011, 0x4688, 0x2214, 0x0804, 0x13b8, 0x2009, 0x4649,
+	0x2009, 0x4748, 0x210c, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904,
+	0x13b9, 0x2011, 0x4788, 0x2214, 0x0804, 0x13b8, 0x2009, 0x4749,
 	0x210c, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904, 0x13b9, 0x2011,
-	0x4689, 0x2214, 0x0804, 0x13b8, 0x2061, 0x4640, 0x6128, 0x622c,
+	0x4789, 0x2214, 0x0804, 0x13b8, 0x2061, 0x4740, 0x6128, 0x622c,
 	0x8214, 0x8214, 0x8214, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1148,
-	0x2061, 0x4680, 0x6328, 0x73da, 0x632c, 0x831c, 0x831c, 0x831c,
-	0x73de, 0x0804, 0x13b8, 0x2009, 0x464c, 0x210c, 0x2001, 0x01ff,
-	0x2004, 0xd0fc, 0x1904, 0x13b9, 0x2011, 0x468c, 0x2214, 0x0804,
-	0x13b8, 0x7918, 0x0804, 0x13b9, 0x2009, 0x0202, 0x210c, 0x2001,
-	0x01ff, 0x2004, 0xd0fc, 0x1904, 0x13b9, 0x2011, 0x0102, 0x2214,
-	0x0804, 0x13b8, 0x2009, 0x464d, 0x210c, 0x2001, 0x01ff, 0x2004,
-	0xd0fc, 0x1904, 0x13b9, 0x2011, 0x468d, 0x2214, 0x0804, 0x13b8,
-	0x7920, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904, 0x13b9, 0x7a24,
-	0x0804, 0x13b8, 0x2011, 0x4b40, 0x71c4, 0xd1fc, 0x1110, 0x2011,
-	0x4ac0, 0x8107, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xa268,
-	0x6a00, 0x6b08, 0x6c1c, 0x74da, 0x0804, 0x13b7, 0x77c4, 0x080c,
-	0x1b7b, 0x2091, 0x8000, 0x6b1c, 0x6a14, 0x2091, 0x8001, 0x2708,
-	0x0804, 0x13b7, 0x2061, 0x4640, 0x6118, 0x2001, 0x01ff, 0x2004,
-	0xd0fc, 0x1904, 0x13b9, 0x2061, 0x4680, 0x6218, 0x0804, 0x13b8,
-	0x77c4, 0x080c, 0x1b7b, 0x2091, 0x8000, 0x6908, 0x6a18, 0x6b10,
-	0x77da, 0x2091, 0x8001, 0x0804, 0x13b7, 0x71c4, 0x2110, 0xa294,
-	0x000f, 0xa282, 0x0010, 0x1a04, 0x13b3, 0x080c, 0x238b, 0xa384,
-	0x4000, 0x0110, 0xa295, 0x0020, 0x0804, 0x13b7, 0x71c4, 0x2100,
-	0xc0bc, 0xa082, 0x0010, 0x1a04, 0x13b3, 0xd1bc, 0x1120, 0x2011,
-	0x4648, 0x2204, 0x0020, 0x2011, 0x4688, 0x2204, 0xc0bd, 0x0006,
-	0x2100, 0xc0bc, 0x2012, 0x080c, 0x2331, 0x001e, 0x0804, 0x13b9,
-	0x71c4, 0x2021, 0x4649, 0x2404, 0x70c6, 0x2019, 0x0000, 0x0030,
-	0x71c8, 0x2021, 0x4689, 0x2404, 0x70ca, 0xc3fd, 0x2011, 0x1614,
-	0x20a9, 0x0008, 0x2204, 0xa106, 0x0138, 0x8210, 0x1f04, 0x15fa,
-	0x71c4, 0x72c8, 0x0804, 0x13b2, 0xa292, 0x1614, 0x0026, 0x2122,
-	0x001e, 0x080c, 0x2343, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1110,
-	0xd3fc, 0x09f0, 0x0804, 0x13ba, 0x03e8, 0x00fa, 0x01f4, 0x02ee,
-	0x0004, 0x0001, 0x0002, 0x0003, 0x2061, 0x4640, 0x6128, 0x622c,
-	0x8214, 0x8214, 0x8214, 0x70c4, 0x602a, 0x70c8, 0x8003, 0x8003,
-	0x8003, 0x602e, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x11a0, 0x0026,
-	0x0016, 0x2061, 0x4680, 0x6128, 0x622c, 0x8214, 0x8214, 0x8214,
-	0x70d8, 0x602a, 0x70dc, 0x8003, 0x8003, 0x8003, 0x602e, 0x71da,
-	0x72de, 0x001e, 0x002e, 0x0804, 0x13b8, 0x2061, 0x4640, 0x6130,
-	0x70c4, 0x6032, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904, 0x13b9,
-	0x2061, 0x4680, 0x6230, 0x70c8, 0x6032, 0x0804, 0x13b8, 0x7918,
-	0x0804, 0x13b9, 0x71c4, 0xa184, 0xf0cf, 0x0148, 0x2001, 0x01ff,
-	0x2004, 0xd0fc, 0x1904, 0x13b3, 0x72c8, 0x0804, 0x13b2, 0x0006,
-	0x2019, 0x0000, 0x080c, 0x237f, 0x2001, 0x01ff, 0x2004, 0xd0fc,
-	0x0118, 0x001e, 0x0804, 0x13b9, 0x71c8, 0xa184, 0xf0cf, 0x0128,
-	0x0006, 0x2110, 0x71c4, 0x0804, 0x13b2, 0x0006, 0xc3fd, 0x080c,
-	0x237f, 0x002e, 0x001e, 0x0804, 0x13b8, 0x71c4, 0xa182, 0x0010,
-	0x0248, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904, 0x13b3, 0x72c8,
-	0x0804, 0x13b2, 0x2011, 0x464d, 0x2204, 0x0006, 0x8104, 0x1208,
-	0x8108, 0x2112, 0x2019, 0x0000, 0x080c, 0x236c, 0x2001, 0x01ff,
-	0x2004, 0xd0fc, 0x0118, 0x001e, 0x0804, 0x13b9, 0x71c8, 0xa182,
-	0x0010, 0x0228, 0x0006, 0x2110, 0x71c4, 0x0804, 0x13b2, 0x2011,
-	0x468d, 0x2204, 0x0006, 0x8104, 0x1208, 0x8108, 0x2112, 0xc3fd,
-	0x080c, 0x236c, 0x002e, 0x001e, 0x0804, 0x13b8, 0x71c4, 0x72c8,
-	0xa184, 0xfffd, 0x1904, 0x13b2, 0xa284, 0xfffd, 0x1904, 0x13b2,
-	0x2100, 0x7920, 0x7822, 0x2200, 0x7a24, 0x7826, 0x0804, 0x13b8,
-	0x2011, 0x4b40, 0x71c4, 0xd1fc, 0x1110, 0x2011, 0x4ac0, 0x8107,
-	0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xa268, 0x72c8, 0x73cc,
-	0x74d8, 0x71c6, 0x6800, 0x70ca, 0x73ce, 0x74da, 0x2091, 0x8000,
-	0x6a02, 0xd2ac, 0x1118, 0x2021, 0x0000, 0x0090, 0xa484, 0x00ff,
-	0xa082, 0x0002, 0x1a04, 0x1741, 0x843f, 0xa7bc, 0x00ff, 0x0140,
-	0xa786, 0x0002, 0x1904, 0x1741, 0xa484, 0x00ff, 0x0904, 0x1741,
-	0x2061, 0x0200, 0xd1fc, 0x0110, 0x2061, 0x0100, 0x2029, 0x0009,
-	0x2031, 0x0062, 0x843f, 0xa7bc, 0x00ff, 0x0130, 0x8307, 0xa084,
-	0x00ff, 0x1110, 0xa73d, 0x1138, 0x2041, 0x0019, 0xa384, 0x00ff,
-	0xa082, 0x001a, 0x0210, 0xa4a4, 0x00ff, 0x8307, 0xa084, 0x00ff,
-	0x0188, 0xa842, 0x02f0, 0xa086, 0x0010, 0x1120, 0xa39c, 0x00ff,
-	0xa39d, 0x0f00, 0xa3bc, 0x00ff, 0x2500, 0xa702, 0x0290, 0x2600,
-	0xa702, 0x1278, 0x2039, 0x003a, 0x6804, 0xa705, 0x6806, 0x6b0a,
-	0x6b0c, 0x73ce, 0x681c, 0x70da, 0x6c1e, 0x2091, 0x8001, 0x0804,
-	0x13ba, 0x2091, 0x8001, 0x0804, 0x13b4, 0x77c4, 0x080c, 0x1b7b,
-	0x2091, 0x8000, 0x6a14, 0x6b1c, 0x2091, 0x8001, 0x70c8, 0x6816,
-	0x70cc, 0x681e, 0x2708, 0x0804, 0x13b7, 0x70c4, 0x2061, 0x4640,
-	0x6118, 0x601a, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904, 0x13b9,
-	0x70c8, 0x2061, 0x4680, 0x6218, 0x601a, 0x0804, 0x13b8, 0x71c4,
-	0x72c8, 0x73cc, 0xa182, 0x0010, 0x1a04, 0x13b3, 0x080c, 0x23af,
-	0xa384, 0x4000, 0x0110, 0xa295, 0x0020, 0x0804, 0x13b7, 0x77c4,
-	0x080c, 0x1b7b, 0x2091, 0x8000, 0x6a08, 0xc28d, 0x6a0a, 0x2091,
-	0x8001, 0x2708, 0x0804, 0x13b8, 0x77c4, 0x080c, 0x1b7b, 0x2091,
-	0x8000, 0x6a08, 0xa294, 0xfff9, 0x6a0a, 0x6804, 0xa005, 0x0110,
-	0x080c, 0x22ae, 0x2091, 0x8001, 0x2708, 0x0804, 0x13b8, 0x77c4,
-	0x080c, 0x1b7b, 0x2091, 0x8000, 0x6a08, 0xc295, 0x6a0a, 0x6804,
-	0xa005, 0x0110, 0x080c, 0x22ae, 0x2091, 0x8001, 0x2708, 0x0804,
-	0x13b8, 0x77c4, 0x2041, 0x0001, 0x2049, 0x0005, 0x2051, 0x0020,
-	0x2091, 0x8000, 0x080c, 0x1b93, 0x2091, 0x8001, 0x2708, 0x6a08,
-	0x0804, 0x13b8, 0x77c4, 0xd7fc, 0x0128, 0x080c, 0x1b0a, 0x0138,
-	0x0804, 0x13bc, 0x080c, 0x1aff, 0x0110, 0x0804, 0x13bc, 0x73c8,
-	0x72cc, 0x77c6, 0x73ca, 0x72ce, 0x080c, 0x1c0b, 0x11e8, 0x6818,
-	0xa005, 0x01a0, 0x2708, 0x0076, 0x080c, 0x23ce, 0x007e, 0x1170,
-	0x2001, 0x0015, 0xd7fc, 0x1118, 0x2061, 0x4640, 0x0018, 0xc0fd,
-	0x2061, 0x4680, 0x782a, 0x2091, 0x8001, 0x0005, 0x2091, 0x8001,
-	0x2001, 0x4005, 0x0804, 0x13bc, 0x2091, 0x8001, 0x0804, 0x13ba,
-	0x77c4, 0xd7fc, 0x0128, 0x080c, 0x1b0a, 0x0138, 0x0804, 0x13bc,
-	0x080c, 0x1aff, 0x0110, 0x0804, 0x13bc, 0x77c6, 0x2041, 0x0021,
-	0x2049, 0x0005, 0x2051, 0x0020, 0x2091, 0x8000, 0x080c, 0x1b93,
-	0x2009, 0x0016, 0xd7fc, 0x1118, 0x2061, 0x4640, 0x0018, 0x2061,
-	0x4680, 0xc1fd, 0x6063, 0x0003, 0x607b, 0x0000, 0x6772, 0x607f,
-	0x000f, 0x792a, 0x61d0, 0xc1c4, 0x61d2, 0x080c, 0x22ae, 0x2091,
-	0x8001, 0x0005, 0x77c8, 0x77ca, 0x77c4, 0x77c6, 0xd7fc, 0x0128,
-	0x080c, 0x1b0a, 0x0138, 0x0804, 0x13bc, 0x080c, 0x1aff, 0x0110,
-	0x0804, 0x13bc, 0xa7bc, 0xff00, 0x2091, 0x8000, 0x2009, 0x0017,
-	0xd7fc, 0x1118, 0x2061, 0x4640, 0x0018, 0x2061, 0x4680, 0xc1fd,
-	0x607b, 0x0000, 0x6063, 0x0002, 0x6772, 0x607f, 0x000f, 0x792a,
-	0x61d0, 0xc1c4, 0x61d2, 0x080c, 0x22ae, 0x2091, 0x8001, 0x2041,
-	0x0021, 0x2049, 0x0005, 0x2051, 0x0030, 0x2091, 0x8000, 0x70c8,
-	0xa005, 0x0118, 0x60d0, 0xc0fd, 0x60d2, 0x080c, 0x1b93, 0x70c8,
-	0x6836, 0x8738, 0xa784, 0x001f, 0x1dc0, 0x2091, 0x8001, 0x0005,
-	0x2019, 0x0000, 0x72c8, 0xd284, 0x0128, 0x080c, 0x1b0a, 0x0138,
-	0x0804, 0x13bc, 0x080c, 0x1aff, 0x0110, 0x0804, 0x13bc, 0x72c8,
-	0x72ca, 0x78ac, 0xa084, 0x0003, 0x1508, 0x2039, 0x0000, 0xd284,
-	0x0108, 0xc7fd, 0x2041, 0x0021, 0x2049, 0x0004, 0x2051, 0x0008,
-	0x080c, 0x1b7b, 0x2091, 0x8000, 0x6808, 0xc0d4, 0xa80d, 0x690a,
-	0x2091, 0x8001, 0x8738, 0xa784, 0x001f, 0x1d90, 0xa7bc, 0xff00,
-	0x873f, 0x8738, 0x873f, 0xa784, 0x0f00, 0x1d50, 0x2091, 0x8000,
+	0x2061, 0x4780, 0x6328, 0x73da, 0x632c, 0x831c, 0x831c, 0x831c,
+	0x73de, 0x0804, 0x13b8, 0x2009, 0x474c, 0x210c, 0x2001, 0x01ff,
+	0x2004, 0xd0fc, 0x1904, 0x13b9, 0x2011, 0x478c, 0x2214, 0x0804,
+	0x13b8, 0x7918, 0x0804, 0x13b9, 0x2009, 0x0202, 0x210c, 0xa18c,
+	0x0f30, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904, 0x13b9, 0x2011,
+	0x0102, 0x2214, 0xa294, 0x0f30, 0x0804, 0x13b8, 0x2009, 0x474d,
+	0x210c, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904, 0x13b9, 0x2011,
+	0x478d, 0x2214, 0x0804, 0x13b8, 0x7920, 0x2001, 0x01ff, 0x2004,
+	0xd0fc, 0x1904, 0x13b9, 0x7a24, 0x0804, 0x13b8, 0x2011, 0x4c40,
+	0x71c4, 0xd1fc, 0x1110, 0x2011, 0x4bc0, 0x8107, 0xa084, 0x000f,
+	0x8003, 0x8003, 0x8003, 0xa268, 0x6a00, 0x6b08, 0x6c1c, 0x74da,
+	0xd1fc, 0x1118, 0x2021, 0x023b, 0x0010, 0x2021, 0x013b, 0x2424,
+	0xa4a4, 0x1c00, 0x74de, 0x0804, 0x13b7, 0x77c4, 0x080c, 0x1b9a,
+	0x2091, 0x8000, 0x6b1c, 0x6a14, 0x2091, 0x8001, 0x2708, 0x0804,
+	0x13b7, 0x2061, 0x4740, 0x6118, 0x2001, 0x01ff, 0x2004, 0xd0fc,
+	0x1904, 0x13b9, 0x2061, 0x4780, 0x6218, 0x0804, 0x13b8, 0x77c4,
+	0x080c, 0x1b9a, 0x2091, 0x8000, 0x6908, 0x6a18, 0x6b10, 0x77da,
+	0x2091, 0x8001, 0x0804, 0x13b7, 0x71c4, 0x2110, 0xa294, 0x000f,
+	0xa282, 0x0010, 0x1a04, 0x13b3, 0x080c, 0x23b4, 0xa384, 0x4000,
+	0x0110, 0xa295, 0x0020, 0x0804, 0x13b7, 0x71c4, 0x2100, 0xc0bc,
+	0xa082, 0x0010, 0x1a04, 0x13b3, 0xd1bc, 0x1120, 0x2011, 0x4748,
+	0x2204, 0x0020, 0x2011, 0x4788, 0x2204, 0xc0bd, 0x0006, 0x2100,
+	0xc0bc, 0x2012, 0x080c, 0x2358, 0x001e, 0x0804, 0x13b9, 0x71c4,
+	0x2021, 0x4749, 0x2404, 0x70c6, 0x2019, 0x0000, 0x0030, 0x71c8,
+	0x2021, 0x4789, 0x2404, 0x70ca, 0xc3fd, 0x2011, 0x1623, 0x20a9,
+	0x0008, 0x2204, 0xa106, 0x0138, 0x8210, 0x1f04, 0x1609, 0x71c4,
+	0x72c8, 0x0804, 0x13b2, 0xa292, 0x1623, 0x0026, 0x2122, 0x001e,
+	0x080c, 0x236a, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1110, 0xd3fc,
+	0x09f0, 0x0804, 0x13ba, 0x03e8, 0x00fa, 0x01f4, 0x02ee, 0x0004,
+	0x0001, 0x0002, 0x0003, 0x2061, 0x4740, 0x6128, 0x622c, 0x8214,
+	0x8214, 0x8214, 0x70c4, 0x602a, 0x70c8, 0x8003, 0x8003, 0x8003,
+	0x602e, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x11a0, 0x0026, 0x0016,
+	0x2061, 0x4780, 0x6128, 0x622c, 0x8214, 0x8214, 0x8214, 0x70d8,
+	0x602a, 0x70dc, 0x8003, 0x8003, 0x8003, 0x602e, 0x71da, 0x72de,
+	0x001e, 0x002e, 0x0804, 0x13b8, 0x2061, 0x4740, 0x6130, 0x70c4,
+	0x6032, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904, 0x13b9, 0x2061,
+	0x4780, 0x6230, 0x70c8, 0x6032, 0x0804, 0x13b8, 0x7918, 0x0804,
+	0x13b9, 0x71c4, 0xa184, 0xf0cf, 0x0148, 0x2001, 0x01ff, 0x2004,
+	0xd0fc, 0x1904, 0x13b3, 0x72c8, 0x0804, 0x13b2, 0x2019, 0x0000,
+	0x080c, 0x23a6, 0x0036, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x0118,
+	0x001e, 0x0804, 0x13b9, 0x71c8, 0xa184, 0xf0cf, 0x0128, 0x000e,
+	0x2110, 0x71c4, 0x0804, 0x13b2, 0xc3fd, 0x080c, 0x23a6, 0x2310,
+	0x001e, 0x0804, 0x13b8, 0x71c4, 0xa182, 0x0010, 0x0248, 0x2001,
+	0x01ff, 0x2004, 0xd0fc, 0x1904, 0x13b3, 0x72c8, 0x0804, 0x13b2,
+	0x2011, 0x474d, 0x2204, 0x0006, 0x8104, 0x1208, 0x8108, 0x2112,
+	0x2019, 0x0000, 0x080c, 0x2393, 0x2001, 0x01ff, 0x2004, 0xd0fc,
+	0x0118, 0x001e, 0x0804, 0x13b9, 0x71c8, 0xa182, 0x0010, 0x0228,
+	0x0006, 0x2110, 0x71c4, 0x0804, 0x13b2, 0x2011, 0x478d, 0x2204,
+	0x0006, 0x8104, 0x1208, 0x8108, 0x2112, 0xc3fd, 0x080c, 0x2393,
+	0x002e, 0x001e, 0x0804, 0x13b8, 0x71c4, 0x72c8, 0xa184, 0xfffd,
+	0x1904, 0x13b2, 0xa284, 0xfffd, 0x1904, 0x13b2, 0x2100, 0x7920,
+	0x7822, 0x2200, 0x7a24, 0x7826, 0x0804, 0x13b8, 0x2011, 0x4c40,
+	0x71c4, 0xd1fc, 0x1110, 0x2011, 0x4bc0, 0x8107, 0xa084, 0x000f,
+	0x8003, 0x8003, 0x8003, 0xa268, 0x72c8, 0x73cc, 0x74d8, 0x71c6,
+	0x6800, 0x70ca, 0x73ce, 0x74da, 0x2091, 0x8000, 0x6a02, 0xd2ac,
+	0x1118, 0x2021, 0x0000, 0x0090, 0xa484, 0x00ff, 0xa082, 0x0002,
+	0x1a04, 0x174f, 0x843f, 0xa7bc, 0x00ff, 0x0140, 0xa786, 0x0002,
+	0x1904, 0x174f, 0xa484, 0x00ff, 0x0904, 0x174f, 0x2061, 0x0200,
+	0xd1fc, 0x0110, 0x2061, 0x0100, 0x2029, 0x0009, 0x2031, 0x0062,
+	0x843f, 0xa7bc, 0x00ff, 0x0130, 0x8307, 0xa084, 0x00ff, 0x1110,
+	0xa73d, 0x1138, 0x2041, 0x0019, 0xa384, 0x00ff, 0xa082, 0x001a,
+	0x0210, 0xa4a4, 0x00ff, 0x8307, 0xa084, 0x00ff, 0x0188, 0xa842,
+	0x02f0, 0xa086, 0x0010, 0x1120, 0xa39c, 0x00ff, 0xa39d, 0x0f00,
+	0xa3bc, 0x00ff, 0x2500, 0xa702, 0x0290, 0x2600, 0xa702, 0x1278,
+	0x2039, 0x003a, 0x6804, 0xa705, 0x6806, 0x6b0a, 0x6b0c, 0x73ce,
+	0x681c, 0x70da, 0x6c1e, 0x2091, 0x8001, 0x0804, 0x13ba, 0x2091,
+	0x8001, 0x0804, 0x13b4, 0x77c4, 0x080c, 0x1b9a, 0x2091, 0x8000,
+	0x6a14, 0x6b1c, 0x2091, 0x8001, 0x70c8, 0x6816, 0x70cc, 0x681e,
+	0x2708, 0x0804, 0x13b7, 0x70c4, 0x2061, 0x4740, 0x6118, 0x601a,
+	0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904, 0x13b9, 0x70c8, 0x2061,
+	0x4780, 0x6218, 0x601a, 0x0804, 0x13b8, 0x71c4, 0x72c8, 0x73cc,
+	0xa182, 0x0010, 0x1a04, 0x13b3, 0x080c, 0x23d8, 0xa384, 0x4000,
+	0x0110, 0xa295, 0x0020, 0x0804, 0x13b7, 0x77c4, 0x080c, 0x1b9a,
+	0x2091, 0x8000, 0x6a08, 0xc28d, 0x6a0a, 0x2091, 0x8001, 0x2708,
+	0x0804, 0x13b8, 0x77c4, 0x080c, 0x1b9a, 0x2091, 0x8000, 0x6a08,
+	0xa294, 0xfff9, 0x6a0a, 0x6804, 0xa005, 0x0110, 0x080c, 0x22d5,
+	0x2091, 0x8001, 0x2708, 0x0804, 0x13b8, 0x77c4, 0x080c, 0x1b9a,
+	0x2091, 0x8000, 0x6a08, 0xc295, 0x6a0a, 0x6804, 0xa005, 0x0110,
+	0x080c, 0x22d5, 0x2091, 0x8001, 0x2708, 0x0804, 0x13b8, 0x77c4,
+	0x2041, 0x0001, 0x2049, 0x0005, 0x2051, 0x0020, 0x2091, 0x8000,
+	0x080c, 0x1bb2, 0x2091, 0x8001, 0x2708, 0x6a08, 0x0804, 0x13b8,
+	0x77c4, 0xd7fc, 0x0128, 0x080c, 0x1b29, 0x0138, 0x0804, 0x13bc,
+	0x080c, 0x1b1e, 0x0110, 0x0804, 0x13bc, 0x73c8, 0x72cc, 0x77c6,
+	0x73ca, 0x72ce, 0x080c, 0x1c2a, 0x11e8, 0x6818, 0xa005, 0x01a0,
+	0x2708, 0x0076, 0x080c, 0x23f7, 0x007e, 0x1170, 0x2001, 0x0015,
+	0xd7fc, 0x1118, 0x2061, 0x4740, 0x0018, 0xc0fd, 0x2061, 0x4780,
+	0x782a, 0x2091, 0x8001, 0x0005, 0x2091, 0x8001, 0x2001, 0x4005,
+	0x0804, 0x13bc, 0x2091, 0x8001, 0x0804, 0x13ba, 0x77c4, 0xd7fc,
+	0x0128, 0x080c, 0x1b29, 0x0138, 0x0804, 0x13bc, 0x080c, 0x1b1e,
+	0x0110, 0x0804, 0x13bc, 0x77c6, 0x2041, 0x0021, 0x2049, 0x0005,
+	0x2051, 0x0020, 0x2091, 0x8000, 0x080c, 0x1bb2, 0x2009, 0x0016,
+	0xd7fc, 0x1118, 0x2061, 0x4740, 0x0018, 0x2061, 0x4780, 0xc1fd,
+	0x6063, 0x0003, 0x607b, 0x0000, 0x6772, 0x607f, 0x000f, 0x792a,
+	0x61d0, 0xc1c4, 0x61d2, 0x080c, 0x22d5, 0x2091, 0x8001, 0x0005,
+	0x77c8, 0x77ca, 0x77c4, 0x77c6, 0xd7fc, 0x0128, 0x080c, 0x1b29,
+	0x0138, 0x0804, 0x13bc, 0x080c, 0x1b1e, 0x0110, 0x0804, 0x13bc,
+	0xa7bc, 0xff00, 0x2091, 0x8000, 0x2009, 0x0017, 0xd7fc, 0x1118,
+	0x2061, 0x4740, 0x0018, 0x2061, 0x4780, 0xc1fd, 0x607b, 0x0000,
+	0x6063, 0x0002, 0x6772, 0x607f, 0x000f, 0x792a, 0x61d0, 0xc1c4,
+	0x61d2, 0x080c, 0x22d5, 0x2091, 0x8001, 0x2041, 0x0021, 0x2049,
+	0x0005, 0x2051, 0x0010, 0x2091, 0x8000, 0x70c8, 0xa005, 0x0118,
+	0x60d0, 0xc0fd, 0x60d2, 0x080c, 0x1bb2, 0x70c8, 0x6836, 0x8738,
+	0xa784, 0x001f, 0x1dc0, 0x2091, 0x8001, 0x0005, 0x2019, 0x0000,
+	0x72c8, 0xd284, 0x0128, 0x080c, 0x1b29, 0x0138, 0x0804, 0x13bc,
+	0x080c, 0x1b1e, 0x0110, 0x0804, 0x13bc, 0x72c8, 0x72ca, 0x78ac,
+	0xa084, 0x0003, 0x1518, 0x2039, 0x0000, 0xd284, 0x0108, 0xc7fd,
+	0x2041, 0x0021, 0x2049, 0x0004, 0x2051, 0x0008, 0x080c, 0x1b9a,
+	0x2091, 0x8000, 0x6808, 0xc0d4, 0xa80d, 0x690a, 0x6837, 0x0000,
+	0x2091, 0x8001, 0x8738, 0xa784, 0x001f, 0x1d80, 0xa7bc, 0xff00,
+	0x873f, 0x8738, 0x873f, 0xa784, 0x0f00, 0x1d40, 0x2091, 0x8000,
 	0x72c8, 0x2069, 0x0100, 0xd284, 0x1110, 0x2069, 0x0200, 0x6808,
 	0xa084, 0xfffd, 0x680a, 0x6830, 0xd0b4, 0x01b0, 0x684b, 0x0004,
-	0x20a9, 0x0014, 0x6848, 0xd094, 0x0110, 0x1f04, 0x18b2, 0x684b,
-	0x0009, 0x20a9, 0x0014, 0x6848, 0xd084, 0x0110, 0x1f04, 0x18bb,
-	0x20a9, 0x00fa, 0x1f04, 0x18c2, 0x2079, 0x4600, 0x2009, 0x0018,
-	0x72c8, 0xd284, 0x1118, 0x2061, 0x4640, 0x0018, 0x2061, 0x4680,
+	0x20a9, 0x0014, 0x6848, 0xd094, 0x0110, 0x1f04, 0x18c2, 0x684b,
+	0x0009, 0x20a9, 0x0014, 0x6848, 0xd084, 0x0110, 0x1f04, 0x18cb,
+	0x20a9, 0x00fa, 0x1f04, 0x18d2, 0x2079, 0x4700, 0x2009, 0x0018,
+	0x72c8, 0xd284, 0x1118, 0x2061, 0x4740, 0x0018, 0x2061, 0x4780,
 	0xc1fd, 0x607b, 0x0000, 0x792a, 0x6063, 0x0001, 0x607f, 0x000f,
 	0x60a3, 0x0000, 0x60a4, 0x60ae, 0x60b2, 0x60d0, 0xd0b4, 0x0160,
 	0xc0b4, 0x60d2, 0x00c6, 0x60b4, 0xa065, 0x6008, 0xc0d4, 0x600a,
 	0x6018, 0x8001, 0x601a, 0x00ce, 0x60d0, 0xa084, 0x7eff, 0x60d2,
 	0x78ac, 0xc08d, 0x78ae, 0x83ff, 0x0108, 0x0005, 0x681b, 0x0054,
-	0x2091, 0x8001, 0x0005, 0x73cc, 0x080c, 0x186a, 0x69ec, 0x6a48,
+	0x2091, 0x8001, 0x0005, 0x73cc, 0x080c, 0x1878, 0x69ec, 0x6a48,
 	0xa185, 0x1800, 0x684a, 0xa185, 0x0040, 0x68ee, 0x73cc, 0x2021,
-	0x0004, 0x20a9, 0x09ff, 0x1f04, 0x190b, 0x8421, 0x1dd0, 0x8319,
+	0x0004, 0x20a9, 0x09ff, 0x1f04, 0x191b, 0x8421, 0x1dd0, 0x8319,
 	0x1db0, 0x69ee, 0x6a4a, 0x2091, 0x8001, 0x0005, 0xd7fc, 0x1118,
-	0x2069, 0x4640, 0x0010, 0x2069, 0x4680, 0x71c4, 0x71c6, 0x6916,
+	0x2069, 0x4740, 0x0010, 0x2069, 0x4780, 0x71c4, 0x71c6, 0x6916,
 	0x81ff, 0x1110, 0x68a3, 0x0001, 0x78ac, 0xc08c, 0x78ae, 0xd084,
-	0x1110, 0x080c, 0x1c5b, 0x0005, 0x75d8, 0x74dc, 0x75da, 0x74de,
+	0x1110, 0x080c, 0x1c7a, 0x0005, 0x75d8, 0x74dc, 0x75da, 0x74de,
 	0x0010, 0xa02e, 0x2520, 0x71c4, 0x73c8, 0x72cc, 0x71c6, 0x73ca,
-	0x72ce, 0x2079, 0x4600, 0x7dde, 0x7cda, 0x7bd6, 0x7ad2, 0x080c,
-	0x1b58, 0x0904, 0x1a3d, 0x20a9, 0x0005, 0x20a1, 0x4614, 0x2091,
-	0x8000, 0x41a1, 0x2091, 0x8001, 0x2009, 0x0040, 0x080c, 0x1d24,
-	0x0120, 0x080c, 0x1b60, 0x0804, 0x1a3d, 0x6004, 0xa08c, 0x00ff,
-	0xa18e, 0x0009, 0x1120, 0x0006, 0x080c, 0x205f, 0x000e, 0xa084,
-	0xff00, 0x8007, 0x8009, 0x0904, 0x19e1, 0x00c6, 0x2c68, 0x080c,
-	0x1b58, 0x05a8, 0x2c00, 0x689e, 0x8109, 0x1dc0, 0x609f, 0x0000,
+	0x72ce, 0x2079, 0x4700, 0x7dde, 0x7cda, 0x7bd6, 0x7ad2, 0x080c,
+	0x1b77, 0x0904, 0x1a5c, 0x20a9, 0x0005, 0x20a1, 0x4714, 0x2091,
+	0x8000, 0x41a1, 0x2091, 0x8001, 0x2009, 0x0040, 0x080c, 0x1d41,
+	0x0120, 0x080c, 0x1b7f, 0x0804, 0x1a5c, 0x6004, 0xa08c, 0x00ff,
+	0xa18e, 0x0009, 0x1120, 0x0006, 0x080c, 0x2086, 0x000e, 0xa084,
+	0xff00, 0x8007, 0x8009, 0x0904, 0x19f1, 0x00c6, 0x2c68, 0x080c,
+	0x1b77, 0x05a8, 0x2c00, 0x689e, 0x8109, 0x1dc0, 0x609f, 0x0000,
 	0x00ce, 0x00c6, 0x7ddc, 0x7cd8, 0x7bd4, 0x7ad0, 0xa290, 0x0040,
 	0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x7dde, 0x7cda,
-	0x7bd6, 0x7ad2, 0x2c68, 0x689c, 0xa065, 0x0904, 0x19e0, 0x2009,
-	0x0040, 0x080c, 0x1d24, 0x15a0, 0x6004, 0xa084, 0x00ff, 0xa086,
-	0x0002, 0x1168, 0x6004, 0xa084, 0x00ff, 0xa086, 0x000a, 0x1120,
-	0x0016, 0x080c, 0x205c, 0x001e, 0x2d00, 0x6002, 0x0898, 0x00ce,
-	0x00c6, 0x609c, 0x080c, 0x1bd4, 0x00ce, 0x609f, 0x0000, 0x080c,
-	0x1a41, 0x2009, 0x0018, 0x6008, 0xc0cd, 0x600a, 0x6004, 0x6086,
+	0x7bd6, 0x7ad2, 0x2c68, 0x689c, 0xa065, 0x0904, 0x19f0, 0x2009,
+	0x0040, 0x080c, 0x1d41, 0x15a0, 0x6004, 0xa084, 0x00ff, 0xa086,
+	0x0002, 0x0150, 0x6004, 0xa084, 0x00ff, 0xa086, 0x000a, 0x1138,
+	0x0016, 0x080c, 0x2083, 0x001e, 0x2d00, 0x6002, 0x0898, 0x00ce,
+	0x00c6, 0x609c, 0x080c, 0x1bf3, 0x00ce, 0x609f, 0x0000, 0x080c,
+	0x1a60, 0x2009, 0x0018, 0x6008, 0xc0cd, 0x600a, 0x6004, 0x6086,
 	0x7810, 0x0006, 0x84ff, 0x1110, 0x85ff, 0x0110, 0xc0c5, 0x7812,
-	0x080c, 0x1b15, 0x000e, 0x7812, 0x080c, 0x1b60, 0x0804, 0x1a3d,
-	0x00ce, 0x00c6, 0x609c, 0x080c, 0x1bd4, 0x00ce, 0x609f, 0x0000,
-	0x080c, 0x1a41, 0x2009, 0x0018, 0x6087, 0x0103, 0x601b, 0x0003,
+	0x080c, 0x1b34, 0x000e, 0x7812, 0x080c, 0x1b7f, 0x0804, 0x1a5c,
+	0x00ce, 0x00c6, 0x609c, 0x080c, 0x1bf3, 0x00ce, 0x609f, 0x0000,
+	0x080c, 0x1a60, 0x2009, 0x0018, 0x6087, 0x0103, 0x601b, 0x0003,
 	0x7810, 0x0006, 0x84ff, 0x1110, 0x85ff, 0x0110, 0xc0c5, 0x7812,
-	0x080c, 0x1b15, 0x000e, 0x7812, 0x080c, 0x1b60, 0x0804, 0x1a3d,
-	0x00ce, 0x6114, 0xd1fc, 0x0120, 0x080c, 0x1b0a, 0x01f0, 0x0018,
-	0x080c, 0x1aff, 0x01d0, 0x080c, 0x1a41, 0x2009, 0x0018, 0x6087,
+	0x080c, 0x1b34, 0x000e, 0x7812, 0x080c, 0x1b7f, 0x0804, 0x1a5c,
+	0x00ce, 0x6114, 0xd1fc, 0x0120, 0x080c, 0x1b29, 0x01f0, 0x0018,
+	0x080c, 0x1b1e, 0x01d0, 0x080c, 0x1a60, 0x2009, 0x0018, 0x6087,
 	0x0103, 0x601b, 0x0021, 0x7810, 0x0006, 0x84ff, 0x1110, 0x85ff,
-	0x0110, 0xc0c5, 0x7812, 0x080c, 0x1b15, 0x000e, 0x7812, 0x080c,
-	0x1b60, 0x2001, 0x4007, 0x0804, 0x13bc, 0x74c4, 0x73c8, 0x72cc,
-	0x6014, 0x2091, 0x8000, 0x00e6, 0x2009, 0x0012, 0xd0fc, 0x1118,
-	0x2071, 0x4640, 0x0018, 0x2071, 0x4680, 0xc1fd, 0x792a, 0x7063,
-	0x0005, 0x71d0, 0xc1c4, 0x71d2, 0x7366, 0x726a, 0x746e, 0x7072,
-	0x7077, 0x0000, 0x2c00, 0x707a, 0xa02e, 0x2530, 0x611c, 0xa184,
-	0x0060, 0x0110, 0x080c, 0x3fc1, 0x00ee, 0x6596, 0x65a6, 0x669a,
-	0x66aa, 0x60af, 0x0000, 0x60b3, 0x0000, 0x6714, 0x6023, 0x0000,
-	0x080c, 0x22ae, 0x2091, 0x8001, 0x0005, 0x70c3, 0x4005, 0x0804,
-	0x13bd, 0x20a9, 0x0005, 0x2099, 0x4614, 0x2091, 0x8000, 0x530a,
-	0x2091, 0x8001, 0x2100, 0xa210, 0xa399, 0x0000, 0xa4a1, 0x0000,
-	0xa5a9, 0x0000, 0x0005, 0x71c4, 0x70c7, 0x0000, 0x791e, 0x0804,
-	0x13ba, 0x71c4, 0x71c6, 0x2168, 0x0010, 0x2069, 0x1000, 0x690c,
-	0xa016, 0x2d04, 0xa210, 0x8d68, 0x8109, 0x1dd8, 0xa285, 0x0000,
-	0x1118, 0x70c3, 0x4000, 0x0010, 0x70c3, 0x4003, 0x70ca, 0x0804,
-	0x13bd, 0x7964, 0x71c6, 0x71c4, 0xa182, 0x0003, 0x1a04, 0x13b3,
-	0x7966, 0x0804, 0x13ba, 0x7964, 0x71c6, 0x0804, 0x13ba, 0x7900,
-	0x71c6, 0x71c4, 0x7902, 0x0804, 0x13ba, 0x7900, 0x71c6, 0x0804,
-	0x13ba, 0x70c4, 0x2011, 0x0000, 0xa08c, 0x000d, 0x0160, 0x810c,
-	0x0230, 0x8210, 0x810c, 0x810c, 0x0210, 0x8210, 0x810c, 0x81ff,
-	0x1904, 0x13b4, 0x8210, 0x7a0e, 0xd28c, 0x0538, 0x7910, 0xc1cd,
-	0x7912, 0x2009, 0x0021, 0x2019, 0x0003, 0xd284, 0x01c0, 0x8108,
-	0x2019, 0x0041, 0x2011, 0x8e4e, 0x2312, 0x2019, 0x0042, 0x8210,
-	0x2312, 0x2019, 0x0043, 0x8210, 0x2312, 0x2019, 0x0046, 0x8210,
-	0x2312, 0x2019, 0x0047, 0x8210, 0x2312, 0x2019, 0x0006, 0x2011,
-	0x8e53, 0x2112, 0x2011, 0x8e73, 0x2312, 0x7904, 0x7806, 0x0804,
-	0x13b9, 0x7804, 0x70c6, 0x0804, 0x13ba, 0x71c4, 0xd1fc, 0x1118,
-	0x2011, 0x4ac0, 0x0010, 0x2011, 0x4b40, 0x8107, 0xa084, 0x000f,
-	0x8003, 0x8003, 0x8003, 0xa268, 0x2011, 0x0000, 0x6814, 0xd0fc,
-	0x0110, 0xa295, 0x0200, 0xd0b4, 0x0110, 0xa295, 0x0001, 0x6b0c,
-	0x6800, 0x70da, 0x0804, 0x13b7, 0x7814, 0xd0f4, 0x0130, 0x2001,
-	0x4007, 0x70db, 0x0000, 0xa005, 0x0048, 0xd0fc, 0x0130, 0x2001,
-	0x4007, 0x70db, 0x0001, 0xa005, 0x0008, 0xa006, 0x0005, 0x7814,
-	0xd0f4, 0x0130, 0x2001, 0x4007, 0x70db, 0x0000, 0xa005, 0x0008,
-	0xa006, 0x0005, 0x7814, 0xd0fc, 0x0130, 0x2001, 0x4007, 0x70db,
-	0x0001, 0xa005, 0x0008, 0xa006, 0x0005, 0x7112, 0x721a, 0x731e,
-	0x7810, 0xd0c4, 0x0110, 0x7422, 0x7526, 0xac80, 0x0001, 0x8108,
-	0x810c, 0x81a9, 0x8098, 0x20a1, 0x0030, 0x7003, 0x0000, 0x6084,
-	0x20a2, 0x53a6, 0x7007, 0x0001, 0x7974, 0xa184, 0xff00, 0x0140,
-	0x810f, 0x810c, 0x810c, 0x8004, 0x8004, 0x8007, 0xa100, 0x0018,
-	0x8107, 0x8004, 0x8004, 0x797c, 0xa108, 0x7a78, 0xa006, 0xa211,
-	0x7d10, 0xd5c4, 0x0120, 0x7b84, 0xa319, 0x7c80, 0xa421, 0x7008,
-	0xd0fc, 0x0de8, 0x7003, 0x0001, 0x7007, 0x0006, 0x711a, 0x721e,
-	0x7d10, 0xd5c4, 0x0110, 0x7322, 0x7426, 0xa084, 0x01e0, 0x0005,
-	0x7848, 0xa065, 0x0120, 0x2c04, 0x784a, 0x2063, 0x0000, 0x0005,
-	0x00f6, 0x2079, 0x4600, 0x7848, 0x2062, 0x2c00, 0xa005, 0x1110,
-	0x080c, 0x254c, 0x784a, 0x00fe, 0x0005, 0x2011, 0x9000, 0x7a4a,
-	0x7bc4, 0x8319, 0x0128, 0xa280, 0x0032, 0x2012, 0x2010, 0x0cc8,
-	0x2013, 0x0000, 0x0005, 0x0016, 0x0026, 0xd7fc, 0x1118, 0x2011,
-	0x4bc0, 0x0010, 0x2011, 0x6bc0, 0xa784, 0x0f00, 0x800b, 0xa784,
-	0x001f, 0x0120, 0x8003, 0x8003, 0x8003, 0x8003, 0xa105, 0xa268,
-	0x002e, 0x001e, 0x0005, 0x0c39, 0x2900, 0x682a, 0x2a00, 0x682e,
-	0x6808, 0xa084, 0xf9ef, 0xa80d, 0x690a, 0x00e6, 0xd7fc, 0x1128,
-	0x2009, 0x4652, 0x2071, 0x4640, 0x0020, 0x2009, 0x4692, 0x2071,
-	0x4680, 0x210c, 0x6804, 0xa005, 0x0148, 0xa116, 0x1138, 0x2060,
-	0x6000, 0x6806, 0x0016, 0x200b, 0x0000, 0x0018, 0x2009, 0x0000,
-	0x0016, 0x6804, 0xa065, 0x0178, 0x6000, 0x6806, 0x0421, 0x080c,
-	0x1d95, 0x6810, 0x7908, 0x8109, 0x790a, 0x8001, 0x6812, 0x1d88,
-	0x7910, 0xc1a5, 0x7912, 0x001e, 0x6902, 0x6906, 0x2d00, 0x2060,
-	0x080c, 0x2693, 0x00ee, 0x0005, 0xa065, 0x0160, 0x2008, 0x609c,
-	0xa005, 0x0128, 0x2062, 0x609f, 0x0000, 0xa065, 0x0cc0, 0x7848,
-	0x794a, 0x2062, 0x0005, 0x6007, 0x0103, 0x608f, 0x0000, 0x20a9,
-	0x001c, 0xac80, 0x0005, 0x20a0, 0x2001, 0x0000, 0x40a4, 0x6828,
-	0x601a, 0x682c, 0x6022, 0x0005, 0x00e6, 0xd7fc, 0x1128, 0x2071,
-	0x4640, 0x2031, 0x46c0, 0x0020, 0x2071, 0x4680, 0x2031, 0x48c0,
-	0x704c, 0xa08c, 0x0200, 0x1128, 0xa608, 0x2d0a, 0x8000, 0x704e,
-	0xa006, 0x00ee, 0x0005, 0x00f6, 0xd7fc, 0x1118, 0x2079, 0x4640,
-	0x0010, 0x2079, 0x4680, 0x080c, 0x1b7b, 0x2091, 0x8000, 0x6804,
-	0x780a, 0xa065, 0x05f0, 0x0030, 0x2c00, 0x780a, 0x2060, 0x6000,
-	0xa065, 0x05b8, 0x6010, 0xa306, 0x1db8, 0x600c, 0xa206, 0x1da0,
-	0x2c28, 0x7848, 0xac06, 0x1108, 0x0448, 0x6804, 0xac06, 0x1140,
-	0x6000, 0x2060, 0x6806, 0xa005, 0x1118, 0x6803, 0x0000, 0x0048,
-	0x6400, 0x7808, 0x2060, 0x6402, 0xa486, 0x0000, 0x1110, 0x2c00,
-	0x6802, 0x2560, 0x080c, 0x1be3, 0x601b, 0x0005, 0x6023, 0x0020,
-	0x00fe, 0x080c, 0x1d95, 0x00f6, 0x7908, 0x8109, 0x790a, 0x6810,
-	0x8001, 0x6812, 0x1118, 0x7810, 0xc0a5, 0x7812, 0x2001, 0xffff,
-	0xa005, 0x00fe, 0x0005, 0x0076, 0x2700, 0x2039, 0x0000, 0xd0fc,
-	0x0108, 0xc7fd, 0x2041, 0x0021, 0x2049, 0x0004, 0x2051, 0x0008,
-	0x2091, 0x8000, 0x080c, 0x1b93, 0x8738, 0xa784, 0x001f, 0x1dd0,
-	0xa7bc, 0xff00, 0x873f, 0x8738, 0x873f, 0xa784, 0x0f00, 0x1d90,
-	0x2091, 0x8001, 0x007e, 0x0005, 0x786c, 0x2009, 0x8e74, 0x210c,
-	0xa10d, 0x0118, 0xa065, 0x0804, 0x207a, 0x2061, 0x0000, 0x6018,
-	0xd084, 0x11b8, 0x7810, 0xd08c, 0x0130, 0xc08c, 0x7812, 0xc7fc,
-	0x2069, 0x4640, 0x0028, 0xc08d, 0x7812, 0x2069, 0x4680, 0xc7fd,
-	0x2091, 0x8000, 0x681c, 0x681f, 0x0000, 0x2091, 0x8001, 0xa005,
-	0x1108, 0x0005, 0xa08c, 0xfff0, 0x0110, 0x080c, 0x254c, 0x0002,
-	0x1cb8, 0x1cbb, 0x1cc1, 0x1cc5, 0x1cb9, 0x1cc9, 0x1cb9, 0x1cb9,
-	0x1cb9, 0x1ccf, 0x1cfb, 0x1cfe, 0x1d03, 0x1d0c, 0x1cb9, 0x1cb9,
-	0x0005, 0x080c, 0x254c, 0x080c, 0x1c5b, 0x2001, 0x8001, 0x0804,
-	0x1d15, 0x2001, 0x8003, 0x0804, 0x1d15, 0x2001, 0x8004, 0x0804,
-	0x1d15, 0x080c, 0x1c5b, 0x2001, 0x8006, 0x0804, 0x1d15, 0x2091,
-	0x8000, 0x0076, 0xd7fc, 0x1128, 0x2069, 0x4640, 0x2039, 0x0009,
-	0x0020, 0x2069, 0x4680, 0x2039, 0x0009, 0x6800, 0xa086, 0x0000,
-	0x0128, 0x000e, 0x6f1e, 0x2091, 0x8001, 0x0005, 0x6870, 0x007e,
-	0xa0bc, 0xff00, 0x2041, 0x0021, 0x2049, 0x0004, 0x2051, 0x0010,
-	0x080c, 0x1b93, 0x8738, 0xa784, 0x001f, 0x1dd0, 0x2091, 0x8001,
-	0x2001, 0x800a, 0x00d0, 0x2001, 0x800c, 0x00b8, 0x080c, 0x1c5b,
-	0x2001, 0x800d, 0x0090, 0xd7fc, 0x0110, 0x78e4, 0x0008, 0x78e0,
-	0x70c6, 0x2001, 0x800e, 0x0048, 0xd7fc, 0x0110, 0x78ec, 0x0008,
-	0x78e8, 0x70c6, 0x2001, 0x800f, 0x0000, 0x70c2, 0xd7fc, 0x1118,
-	0x70db, 0x0000, 0x0010, 0x70db, 0x0001, 0x2061, 0x0000, 0x601b,
-	0x0001, 0x2091, 0x4080, 0x0005, 0xac80, 0x0001, 0x81ff, 0x0518,
-	0x2099, 0x0030, 0x20a0, 0x700c, 0xa084, 0x07ff, 0x0100, 0x7018,
-	0x0006, 0x701c, 0x0006, 0x7020, 0x0006, 0x7024, 0x0006, 0x7112,
-	0x81ac, 0x721a, 0x731e, 0x7422, 0x7526, 0x7003, 0x0001, 0x7007,
-	0x0001, 0x7008, 0x800b, 0x1ee8, 0x7007, 0x0002, 0xa08c, 0x01e0,
-	0x1110, 0x53a5, 0xa006, 0x7003, 0x0000, 0x7007, 0x0004, 0x000e,
-	0x7026, 0x000e, 0x7022, 0x000e, 0x701e, 0x000e, 0x701a, 0x0005,
-	0x2011, 0x0020, 0x2009, 0x0010, 0x6b0a, 0x6c0e, 0x681f, 0x0201,
-	0x6803, 0xfd20, 0x6807, 0x0038, 0x6a1a, 0x2d00, 0xa0e8, 0x0008,
-	0xa290, 0x0004, 0x8109, 0x1d80, 0x0005, 0x70ec, 0xd0dc, 0x1520,
-	0x2029, 0x0001, 0x7814, 0xd0cc, 0x1160, 0x70ec, 0xd0e4, 0x2019,
-	0x0c0a, 0x2021, 0x000a, 0x1120, 0x2019, 0x0c0c, 0x2021, 0x000c,
-	0x0070, 0x70ec, 0xd0e4, 0x1128, 0x2019, 0x180c, 0x2021, 0x000c,
-	0x0030, 0x2019, 0x1809, 0x2021, 0x0009, 0xa5ad, 0x0200, 0x6b0a,
-	0x6c0e, 0x6d1e, 0x6807, 0x0038, 0x0005, 0x6004, 0x6086, 0x2c08,
-	0x2063, 0x0000, 0x7868, 0xa005, 0x796a, 0x0110, 0x2c02, 0x0008,
-	0x796e, 0x0005, 0x00c6, 0x2061, 0x4600, 0x6887, 0x0103, 0x2d08,
-	0x206b, 0x0000, 0x6068, 0xa005, 0x616a, 0x0110, 0x2d02, 0x0008,
-	0x616e, 0x00ce, 0x0005, 0x2091, 0x8000, 0x2c04, 0x786e, 0xa005,
-	0x1108, 0x786a, 0x2091, 0x8001, 0x609c, 0xa005, 0x0188, 0x00c6,
-	0x2060, 0x2008, 0x609c, 0xa005, 0x0138, 0x2062, 0x609f, 0x0000,
-	0xa065, 0x609c, 0xa005, 0x1dc8, 0x7848, 0x794a, 0x2062, 0x00ce,
-	0x7848, 0x2062, 0x609f, 0x0000, 0xac85, 0x0000, 0x1110, 0x080c,
-	0x254c, 0x784a, 0x0005, 0x20a9, 0x0010, 0xa006, 0x8004, 0x8086,
-	0x818e, 0x1208, 0xa200, 0x1f04, 0x1ddf, 0x8086, 0x818e, 0x0005,
-	0x0156, 0x20a9, 0x0010, 0xa005, 0x01b8, 0xa11a, 0x12a8, 0x8213,
-	0x818d, 0x0228, 0xa11a, 0x1220, 0x1f04, 0x1def, 0x0028, 0xa11a,
-	0x2308, 0x8210, 0x1f04, 0x1def, 0x0006, 0x3200, 0xa084, 0xefff,
-	0x2080, 0x000e, 0x015e, 0x0005, 0x0006, 0x3200, 0xa085, 0x1000,
-	0x0cb8, 0x7d74, 0x70d0, 0xa506, 0x0904, 0x1ebd, 0x7810, 0x2050,
-	0x080c, 0x1b58, 0x0904, 0x1ebd, 0xa046, 0x7970, 0x2500, 0x8000,
-	0xa112, 0x2009, 0x0040, 0x1208, 0x0030, 0x72d0, 0xa206, 0x0118,
-	0x8840, 0x2009, 0x0080, 0x00c6, 0x7112, 0x7007, 0x0001, 0x2099,
-	0x0030, 0x20a9, 0x0020, 0xac80, 0x0001, 0x20a0, 0x2061, 0x0000,
-	0x88ff, 0x0110, 0x080c, 0x1b58, 0x7008, 0xd0fc, 0x0de8, 0x7007,
-	0x0002, 0x2091, 0x8001, 0xa08c, 0x01e0, 0x1538, 0x53a5, 0x8cff,
-	0x1120, 0x88ff, 0x0904, 0x1eaa, 0x0050, 0x2c00, 0x788e, 0x20a9,
-	0x0020, 0xac80, 0x0001, 0x20a0, 0x53a5, 0x0804, 0x1eaa, 0xa046,
-	0x7218, 0x731c, 0xdac4, 0x0110, 0x7420, 0x7524, 0xa292, 0x0040,
-	0xa39b, 0x0000, 0xa4a3, 0x0000, 0xa5ab, 0x0000, 0x721a, 0x731e,
-	0xdac4, 0x0118, 0x7422, 0x7526, 0xa006, 0x7007, 0x0004, 0x0904,
-	0x1eaa, 0x8cff, 0x0110, 0x080c, 0x1b60, 0x00ce, 0x080c, 0x1b60,
-	0xa046, 0x7888, 0x8000, 0x788a, 0xa086, 0x0002, 0x01c0, 0x7a7c,
-	0x7b78, 0xdac4, 0x0110, 0x7c84, 0x7d80, 0x7974, 0x8107, 0x8004,
-	0x8004, 0xa210, 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000,
-	0x721a, 0x731e, 0xdac4, 0x0588, 0x7422, 0x7526, 0x0470, 0x6014,
-	0xd0fc, 0x1118, 0x2069, 0x4640, 0x0010, 0x2069, 0x4680, 0x2091,
-	0x8000, 0x681f, 0x0002, 0x88ff, 0x0120, 0xa046, 0x788c, 0x2060,
-	0x0c70, 0x788b, 0x0000, 0x78ac, 0xa085, 0x0003, 0x78ae, 0x2091,
-	0x8001, 0x0098, 0x00ce, 0x788b, 0x0000, 0x080c, 0x2035, 0x6004,
-	0xa084, 0x000f, 0x0059, 0x88ff, 0x0130, 0x788c, 0x2060, 0x6004,
-	0xa084, 0x000f, 0x0019, 0x0804, 0x1e09, 0x0005, 0x0002, 0x1ecf,
-	0x1eea, 0x1f03, 0x1ecf, 0x1f10, 0x1ee0, 0x1ecf, 0x1ecf, 0x1ecf,
-	0x1ee8, 0x1f01, 0x1ecf, 0x1ecf, 0x1ecf, 0x1ecf, 0x1ecf, 0x2039,
-	0x0400, 0x78bc, 0xa705, 0x78be, 0x6008, 0xa705, 0x600a, 0x080c,
-	0x1f4c, 0x609c, 0x78ba, 0x609f, 0x0000, 0x080c, 0x2021, 0x0005,
-	0x78bc, 0xd0c4, 0x0108, 0x0c58, 0x601c, 0xc0bd, 0x601e, 0x0030,
-	0x080c, 0x205f, 0x78bc, 0xd0c4, 0x0108, 0x0c08, 0x78bf, 0x0000,
-	0x6004, 0x8007, 0xa084, 0x00ff, 0x78b2, 0x8001, 0x0138, 0x080c,
-	0x1f4c, 0x0120, 0x78bc, 0xc0c5, 0x78be, 0x0010, 0x0804, 0x1f67,
-	0x0005, 0x080c, 0x205c, 0x78bc, 0xa08c, 0x0e00, 0x1110, 0xd0c4,
-	0x1108, 0x0828, 0x080c, 0x1f4c, 0x1110, 0x0804, 0x1f67, 0x0005,
-	0x78bc, 0xd0c4, 0x0110, 0x0804, 0x1ecf, 0x78bf, 0x0000, 0x6714,
-	0x2011, 0x0001, 0x22a8, 0x6018, 0xa084, 0x00ff, 0xa005, 0x0188,
-	0xa7bc, 0xff00, 0x20a9, 0x0020, 0xa08e, 0x0001, 0x0150, 0xa7bc,
-	0x8000, 0x2011, 0x0002, 0x20a9, 0x0100, 0xa08e, 0x0002, 0x0108,
-	0x00c0, 0x080c, 0x1b7b, 0x2d00, 0x2091, 0x8000, 0x682b, 0x0000,
-	0x682f, 0x0000, 0x6808, 0xa084, 0xffde, 0x680a, 0xade8, 0x0010,
-	0x2091, 0x8001, 0x1f04, 0x1f34, 0x8211, 0x0118, 0x20a9, 0x0100,
-	0x0c58, 0x080c, 0x1b60, 0x0005, 0x609f, 0x0000, 0x78b4, 0xa06d,
-	0x2c00, 0x78b6, 0x1110, 0x78ba, 0x0038, 0x689e, 0x2d00, 0x6002,
-	0x78b8, 0xad06, 0x1108, 0x6002, 0x78b0, 0x8001, 0x78b2, 0x1130,
-	0x78bc, 0xc0c4, 0x78be, 0x78b8, 0x2060, 0xa006, 0x0005, 0x00e6,
-	0xa02e, 0x2530, 0x7dba, 0x7db6, 0x65ae, 0x65b2, 0x601c, 0x60a2,
-	0x2048, 0xa984, 0xe1ff, 0x601e, 0xa984, 0x0060, 0x0110, 0x080c,
-	0x3fc1, 0x6596, 0x65a6, 0x669a, 0x66aa, 0x6714, 0x2071, 0x4680,
-	0xd7fc, 0x1110, 0x2071, 0x4640, 0xa784, 0x0f00, 0x800b, 0xa784,
-	0x001f, 0x0120, 0x8003, 0x8003, 0x8003, 0x8003, 0xa105, 0x71c0,
-	0xa168, 0x2700, 0x8007, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003,
-	0x71c4, 0xa100, 0x60c2, 0x2091, 0x8000, 0x7814, 0xd0c4, 0x0138,
-	0xd7fc, 0x1118, 0xd0f4, 0x1140, 0x0010, 0xd0fc, 0x1128, 0x6e08,
-	0xd684, 0x01f0, 0xd9fc, 0x11e0, 0x2091, 0x8001, 0x080c, 0x1be3,
-	0x2091, 0x8000, 0x080c, 0x1d95, 0x2091, 0x8001, 0x7814, 0xd0c4,
-	0x0904, 0x201f, 0xd7fc, 0x1120, 0xd0f4, 0x1130, 0x0804, 0x201f,
-	0xd0fc, 0x1110, 0x0804, 0x201f, 0x601b, 0x0021, 0x0804, 0x201f,
-	0x6024, 0xa096, 0x0001, 0x1110, 0x8000, 0x6026, 0x6a10, 0x6814,
-	0xa202, 0x0268, 0x0160, 0x2091, 0x8001, 0x2039, 0x0200, 0x609c,
-	0x78ba, 0x609f, 0x0000, 0x080c, 0x2021, 0x0804, 0x201f, 0x2c08,
-	0xd9fc, 0x01f0, 0x6800, 0xa065, 0x01d8, 0x6a04, 0x7000, 0xa084,
-	0x0002, 0x0168, 0x7048, 0xa206, 0x1150, 0x6b04, 0x2160, 0x2304,
-	0x6002, 0xa005, 0x1108, 0x6902, 0x2260, 0x6102, 0x0098, 0x2d00,
-	0x2060, 0x080c, 0x2693, 0x6e08, 0x2160, 0x6202, 0x6906, 0x0050,
-	0x6800, 0x6902, 0xa065, 0x0110, 0x6102, 0x0008, 0x6906, 0x2160,
-	0x6003, 0x0000, 0x2160, 0xd9fc, 0x0118, 0xa6b4, 0xfffc, 0x6e0a,
-	0x6810, 0x7d08, 0x8528, 0x7d0a, 0x8000, 0x6812, 0x2091, 0x8001,
-	0xd6b4, 0x0128, 0xa6b6, 0x0040, 0x6e0a, 0x080c, 0x1bf4, 0x00ee,
-	0x0005, 0x6008, 0xa705, 0x600a, 0x2091, 0x8000, 0x080c, 0x1d95,
-	0x2091, 0x8001, 0x78b8, 0xa065, 0x0128, 0x609c, 0x78ba, 0x609f,
-	0x0000, 0x0c78, 0x78b6, 0x78ba, 0x0005, 0x7970, 0x7874, 0x2818,
-	0xd384, 0x0118, 0x8000, 0xa112, 0x0220, 0x8000, 0xa112, 0x1278,
-	0xc384, 0x7a7c, 0x721a, 0x7a78, 0x721e, 0xdac4, 0x0120, 0x7a84,
-	0x7222, 0x7a80, 0x7226, 0xa006, 0xd384, 0x0108, 0x8000, 0x7876,
-	0x70d2, 0x781c, 0xa005, 0x0138, 0x8001, 0x781e, 0x1120, 0x0e04,
-	0x205b, 0x2091, 0x4080, 0x0005, 0x2039, 0x2071, 0x0010, 0x2039,
-	0x2077, 0x2704, 0xa005, 0x0160, 0xac00, 0x2068, 0x6908, 0x6810,
-	0x6912, 0x680a, 0x690c, 0x6814, 0x6916, 0x680e, 0x8738, 0x0c88,
-	0x0005, 0x0003, 0x0009, 0x000f, 0x0015, 0x001b, 0x0000, 0x0015,
-	0x001b, 0x0000, 0x2041, 0x0000, 0x780c, 0x0002, 0x2223, 0x21fe,
-	0x2082, 0x20f2, 0x2039, 0x8e74, 0x2734, 0x7d10, 0x00c0, 0x6084,
-	0xa086, 0x0103, 0x1904, 0x20dc, 0x6114, 0x6018, 0xa105, 0x0120,
-	0x86ff, 0x11d8, 0x0804, 0x20dc, 0x8603, 0xa080, 0x8e55, 0x620c,
-	0x2202, 0x8000, 0x6210, 0x2202, 0x080c, 0x1db3, 0x8630, 0xa68e,
-	0x000f, 0x0904, 0x215d, 0x786c, 0xa065, 0x1d08, 0x7808, 0xa602,
-	0x1220, 0xd5ac, 0x1110, 0x263a, 0x0005, 0xa682, 0x0003, 0x1a04,
-	0x215d, 0x2091, 0x8000, 0x2069, 0x0000, 0x6818, 0xd084, 0x11f8,
-	0x2011, 0x8e55, 0x2204, 0x70c6, 0x8210, 0x2204, 0x70ca, 0xd684,
-	0x1130, 0x8210, 0x2204, 0x70da, 0x8210, 0x2204, 0x70de, 0xa685,
-	0x8020, 0x70c2, 0x681b, 0x0001, 0x2091, 0x4080, 0x7810, 0xa084,
-	0xffcf, 0x7812, 0x2091, 0x8001, 0x203b, 0x0000, 0x0005, 0x7810,
-	0xc0ad, 0x7812, 0x0804, 0x215d, 0x263a, 0x080c, 0x2229, 0x1904,
-	0x2245, 0x786c, 0xa065, 0x1904, 0x2087, 0x2091, 0x8000, 0x7810,
-	0xa084, 0xffcf, 0x86ff, 0x0108, 0xc0ad, 0x7812, 0x2091, 0x8001,
-	0x0804, 0x2245, 0x2039, 0x8e74, 0x2734, 0x7d10, 0x00a0, 0x6084,
-	0xa086, 0x0103, 0x1904, 0x2147, 0x6114, 0x6018, 0xa105, 0x0120,
-	0x86ff, 0x11b8, 0x0804, 0x2147, 0xa680, 0x8e55, 0x620c, 0x2202,
-	0x080c, 0x1db3, 0x8630, 0xa68e, 0x001e, 0x0904, 0x215d, 0x786c,
-	0xa065, 0x1d28, 0x7808, 0xa602, 0x1220, 0xd5ac, 0x1110, 0x263a,
-	0x0005, 0xa682, 0x0006, 0x1a04, 0x215d, 0x2091, 0x8000, 0x2069,
-	0x0000, 0x6818, 0xd084, 0x11f8, 0x2011, 0x8e55, 0x2009, 0x8e4e,
-	0x26a8, 0x211c, 0x2204, 0x201a, 0x8108, 0x8210, 0x1f04, 0x2129,
-	0xa685, 0x8030, 0x70c2, 0x681b, 0x0001, 0x2091, 0x4080, 0x7810,
-	0xa084, 0xffcf, 0x7812, 0x2091, 0x8001, 0xa006, 0x2009, 0x8e75,
-	0x200a, 0x203a, 0x0005, 0x7810, 0xc0ad, 0x7812, 0x00b0, 0x263a,
-	0x080c, 0x2229, 0x1904, 0x2245, 0x786c, 0xa065, 0x1904, 0x20f7,
-	0x2091, 0x8000, 0x7810, 0xa084, 0xffcf, 0x86ff, 0x0108, 0xc0ad,
-	0x7812, 0x2091, 0x8001, 0x0804, 0x2245, 0x2091, 0x8000, 0x7007,
-	0x0004, 0x7994, 0x70d4, 0xa102, 0x0228, 0x0168, 0x7b90, 0xa302,
-	0x1150, 0x0010, 0x8002, 0x1138, 0x263a, 0x7810, 0xc0ad, 0x7812,
-	0x2091, 0x8001, 0x0005, 0xa184, 0xff00, 0x0140, 0x810f, 0x810c,
-	0x810c, 0x8004, 0x8004, 0x8007, 0xa100, 0x0018, 0x8107, 0x8004,
-	0x8004, 0x7a9c, 0xa210, 0x721a, 0x7a98, 0xa006, 0xa211, 0x721e,
-	0xd4c4, 0x0130, 0x7aa4, 0xa211, 0x7222, 0x7aa0, 0xa211, 0x7226,
-	0x20a1, 0x0030, 0x7003, 0x0000, 0x2009, 0x8e54, 0x260a, 0x8109,
-	0x2198, 0x2104, 0xd084, 0x0108, 0x8633, 0xa6b0, 0x0002, 0x26a8,
-	0x53a6, 0x8603, 0x7012, 0x7007, 0x0001, 0x7990, 0x7894, 0x8000,
-	0xa10a, 0x1208, 0xa006, 0x2028, 0x7974, 0xa184, 0xff00, 0x0140,
-	0x810f, 0x810c, 0x810c, 0x8004, 0x8004, 0x8007, 0xa100, 0x0018,
-	0x8107, 0x8004, 0x8004, 0x797c, 0xa108, 0x7a78, 0xa006, 0xa211,
-	0xd4c4, 0x0120, 0x7b84, 0xa319, 0x7c80, 0xa421, 0x7008, 0xd0fc,
-	0x0de8, 0xa084, 0x01e0, 0x01d0, 0x7d10, 0x2031, 0x8e54, 0x2634,
-	0x78a8, 0x8000, 0x78aa, 0xd08c, 0x1138, 0x7007, 0x0006, 0x7004,
-	0xd094, 0x1de8, 0x0804, 0x215f, 0x2069, 0x4647, 0x206b, 0x0003,
-	0x78ac, 0xa085, 0x0300, 0x78ae, 0xa006, 0x0048, 0x2030, 0x75d6,
-	0x2091, 0x4080, 0x7d96, 0x7d10, 0xa5ac, 0xffcf, 0x7d12, 0x2091,
-	0x8001, 0x78aa, 0x7007, 0x0006, 0x263a, 0x7003, 0x0001, 0x711a,
-	0x721e, 0xd5c4, 0x0110, 0x7322, 0x7426, 0x0005, 0x6084, 0xa086,
-	0x0103, 0x11d8, 0x6114, 0x6018, 0xa105, 0x11b8, 0x2069, 0x0000,
-	0x6818, 0xd084, 0x1190, 0x600c, 0x70c6, 0x6010, 0x70ca, 0x70c3,
-	0x8020, 0x681b, 0x0001, 0x2091, 0x4080, 0x080c, 0x1db3, 0x0e04,
-	0x221c, 0x786c, 0xa065, 0x1d10, 0x0005, 0x0059, 0x1530, 0x786c,
-	0xa065, 0x19e0, 0x0410, 0x0029, 0x1500, 0x786c, 0xa065, 0x1dd8,
-	0x00e0, 0x6084, 0xa086, 0x0103, 0x1168, 0x6018, 0xc0fc, 0x601a,
-	0xa086, 0x0004, 0x1138, 0x7804, 0xd0a4, 0x0120, 0x080c, 0x1db3,
-	0xa006, 0x0005, 0x0079, 0x1118, 0xa085, 0x0001, 0x0005, 0x00b9,
-	0x1110, 0x2041, 0x0001, 0x7d10, 0x0005, 0x88ff, 0x0110, 0x2091,
-	0x4080, 0x0005, 0x7b90, 0x7994, 0x70d4, 0xa102, 0x1118, 0xa385,
-	0x0000, 0x0005, 0x0210, 0xa302, 0x0005, 0x8002, 0x0005, 0xa184,
-	0xff00, 0x0140, 0x810f, 0x810c, 0x810c, 0x8004, 0x8004, 0x8007,
-	0xa100, 0x0018, 0x8107, 0x8004, 0x8004, 0x7a9c, 0x7b98, 0x7ca4,
-	0x7da0, 0xa210, 0xa006, 0xa319, 0xa421, 0xa529, 0x2009, 0x0018,
-	0x6028, 0xa005, 0x0110, 0x2009, 0x0040, 0x080c, 0x1b15, 0x01d0,
-	0x78a8, 0x8000, 0x78aa, 0xd08c, 0x1510, 0x6014, 0xd0fc, 0x1118,
-	0x2069, 0x4640, 0x0010, 0x2069, 0x4680, 0x2091, 0x8000, 0x681f,
-	0x0003, 0x78ab, 0x0000, 0x78ac, 0xa085, 0x0300, 0x78ae, 0x2091,
-	0x8001, 0x0068, 0x78ab, 0x0000, 0x080c, 0x1db3, 0x7990, 0x7894,
-	0x8000, 0xa10a, 0x1208, 0xa006, 0x7896, 0x70d6, 0xa006, 0x2071,
-	0x0010, 0x2091, 0x8001, 0x0005, 0xd7fc, 0x1118, 0x2009, 0x4658,
-	0x0010, 0x2009, 0x4698, 0x2091, 0x8000, 0x200a, 0x00f6, 0x2009,
-	0x4680, 0x2079, 0x0100, 0xd7fc, 0x1120, 0x2009, 0x4640, 0x2079,
-	0x0200, 0x2104, 0xa086, 0x0000, 0x1180, 0xd7fc, 0x1118, 0x2009,
-	0x4645, 0x0010, 0x2009, 0x4685, 0x2104, 0xa005, 0x1130, 0x7830,
-	0xa084, 0x00c0, 0x1110, 0x781b, 0x0052, 0x00fe, 0x0005, 0x2009,
-	0x0002, 0x2069, 0x4600, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904,
-	0x2324, 0x2071, 0x4680, 0x2079, 0x0100, 0x2021, 0x48bf, 0x784b,
-	0x000f, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x0118, 0x2019, 0x3e0f,
-	0x0030, 0x20a1, 0x012b, 0x2019, 0x3e0f, 0xd184, 0x0110, 0x20a1,
-	0x022b, 0x2304, 0xa005, 0x0140, 0x789a, 0x8318, 0x23ac, 0x8318,
-	0x2398, 0x53a6, 0x3318, 0x0ca8, 0x789b, 0x0000, 0x789b, 0x0020,
-	0x20a9, 0x0010, 0x78af, 0x0000, 0x78af, 0x2020, 0x1f04, 0x2302,
-	0x7003, 0x0000, 0x0016, 0xd18c, 0x2009, 0x0000, 0x0108, 0xc1bd,
-	0x080c, 0x2443, 0x001e, 0x7020, 0xa084, 0x000f, 0xa085, 0x6300,
-	0x7806, 0x780f, 0x9000, 0x7843, 0x00d8, 0x7853, 0x0090, 0x780b,
-	0x2f08, 0x7452, 0x704f, 0x0000, 0x8109, 0x0140, 0x2071, 0x4640,
-	0x2079, 0x0200, 0x2021, 0x46bf, 0x0804, 0x22df, 0x080c, 0x24fd,
-	0x0005, 0x0016, 0x2011, 0x0101, 0xd1bc, 0x1110, 0x2011, 0x0201,
-	0xa18c, 0x000f, 0x2204, 0xa084, 0xfff0, 0xa105, 0x2012, 0x001e,
-	0x080c, 0x2443, 0x0005, 0x2011, 0x0101, 0xd3fc, 0x1110, 0x2011,
-	0x0201, 0x20a9, 0x0009, 0x810b, 0x1f04, 0x234b, 0xa18c, 0x0e00,
-	0x2204, 0xa084, 0xf1ff, 0xa105, 0x2012, 0x0005, 0x2019, 0x0002,
-	0x2009, 0x0101, 0x20a9, 0x0005, 0x8213, 0x1f04, 0x235c, 0xa294,
-	0x00e0, 0x2104, 0xa084, 0xff1f, 0xa205, 0x200a, 0x8319, 0x0118,
-	0x2009, 0x0201, 0x0c78, 0x0005, 0x2011, 0x0101, 0xd3fc, 0x1110,
-	0x2011, 0x0201, 0x20a9, 0x000c, 0x810b, 0x1f04, 0x2374, 0xa18c,
-	0xf000, 0x2204, 0xa084, 0x0fff, 0xa105, 0x2012, 0x0005, 0x2011,
-	0x0102, 0xd3fc, 0x1110, 0x2011, 0x0202, 0x2204, 0xa084, 0xf0cf,
-	0xa105, 0x2012, 0x0005, 0x00c6, 0x2061, 0x0100, 0xd1bc, 0x1110,
-	0x2061, 0x0200, 0xc1bc, 0x8103, 0x8003, 0xa080, 0x0020, 0x609a,
-	0x62ac, 0x63ac, 0x00ce, 0x0005, 0x00c6, 0x2061, 0x0100, 0xd1bc,
-	0x1110, 0x2061, 0x0200, 0xc1bc, 0x8103, 0x8003, 0xa080, 0x0022,
-	0x609a, 0x60a4, 0xa084, 0xffdf, 0x60ae, 0x00ce, 0x0005, 0x00c6,
-	0x2061, 0x0100, 0xd1bc, 0x1110, 0x2061, 0x0200, 0xc1bc, 0x8103,
-	0x8003, 0xa080, 0x0020, 0x609a, 0x60a4, 0xa28c, 0x0020, 0x0118,
-	0xc2ac, 0xa39d, 0x4000, 0xc3ec, 0xd3b4, 0x1108, 0xc3ed, 0x62ae,
-	0x2010, 0x60a4, 0x63ae, 0x2018, 0x00ce, 0x0005, 0x2091, 0x8000,
-	0x00c6, 0x00e6, 0x6818, 0xa005, 0x0904, 0x2427, 0xd1fc, 0x0118,
-	0x2061, 0x8dd0, 0x0010, 0x2061, 0x8cc0, 0x080c, 0x242f, 0x0560,
-	0x20a9, 0x0101, 0xd1fc, 0x0118, 0x2061, 0x8cd0, 0x0010, 0x2061,
-	0x8bc0, 0x00c6, 0x080c, 0x242f, 0x0128, 0x00ce, 0x8c60, 0x1f04,
-	0x23e9, 0x04a8, 0x000e, 0xd1fc, 0x0128, 0xa082, 0x8cd0, 0x2071,
-	0x4680, 0x0020, 0xa082, 0x8bc0, 0x2071, 0x4640, 0x7076, 0x7172,
-	0x2138, 0x2001, 0x0004, 0x7062, 0x707f, 0x000f, 0x71d0, 0xc1c4,
-	0x71d2, 0x080c, 0x22a4, 0x00c0, 0xd1fc, 0x1118, 0x2071, 0x4640,
-	0x0010, 0x2071, 0x4680, 0x6020, 0xc0dd, 0x6022, 0x7172, 0x2138,
-	0x2c00, 0x707a, 0x2001, 0x0006, 0x7062, 0x707f, 0x000f, 0x71d0,
-	0xc1c4, 0x71d2, 0x080c, 0x22a4, 0x2001, 0x0000, 0x0010, 0x2001,
-	0x0001, 0x2091, 0x8001, 0xa005, 0x00ee, 0x00ce, 0x0005, 0x2c04,
-	0xa005, 0x0170, 0x2060, 0x6010, 0xa306, 0x1140, 0x600c, 0xa206,
-	0x1128, 0x6014, 0xa106, 0x1110, 0xa006, 0x0020, 0x6000, 0x0c80,
-	0xa085, 0x0001, 0x0005, 0x00f6, 0x00e6, 0x0016, 0x2079, 0x4680,
-	0x2071, 0x0100, 0xd1bc, 0x1120, 0x2079, 0x4640, 0x2071, 0x0200,
-	0x7920, 0xa18c, 0x000f, 0x70ec, 0xd0c4, 0x1110, 0x001e, 0x0060,
-	0x810b, 0x810b, 0x810b, 0x810b, 0x000e, 0xa18d, 0x0800, 0xd0bc,
-	0x1110, 0xa18d, 0x0f00, 0x2104, 0x00ee, 0x00fe, 0x0005, 0x2001,
-	0x4601, 0x2004, 0xd0ac, 0x1138, 0x68e4, 0xd0ac, 0x0120, 0xa084,
-	0x0006, 0x1108, 0x0009, 0x0005, 0x6014, 0x00e6, 0x0036, 0x2018,
-	0x2071, 0x4b40, 0xd0fc, 0x1110, 0x2071, 0x4ac0, 0x8007, 0xa084,
-	0x000f, 0x8003, 0x8003, 0x8003, 0xae70, 0x7004, 0xa084, 0x000a,
-	0x1904, 0x24fa, 0x7108, 0xa194, 0xff00, 0x0904, 0x24fa, 0xa18c,
-	0x00ff, 0x701c, 0xa084, 0xff00, 0x01c0, 0x7004, 0xa085, 0x003a,
-	0x7006, 0x2001, 0x0009, 0xa102, 0x16d8, 0x2001, 0x000a, 0xa102,
-	0x16d0, 0x2001, 0x000c, 0xa102, 0x16c8, 0x701c, 0xa084, 0x00ff,
-	0x701e, 0x7004, 0xa084, 0xffdf, 0x7006, 0x2001, 0x000a, 0xa106,
-	0x01a8, 0x2001, 0x000c, 0xa106, 0x01a0, 0x2001, 0x0012, 0xa106,
-	0x0198, 0x2001, 0x0014, 0xa106, 0x0190, 0x2001, 0x0019, 0xa106,
-	0x0188, 0x2001, 0x0032, 0xa106, 0x0180, 0x00d8, 0x2009, 0x000c,
-	0x00d0, 0x2009, 0x0012, 0x00b8, 0x2009, 0x0014, 0x00a0, 0x2009,
-	0x0019, 0x0088, 0x2009, 0x0020, 0x0070, 0x2009, 0x003f, 0x0058,
-	0x2009, 0x000a, 0x0040, 0x2009, 0x000c, 0x0028, 0x2009, 0x0019,
-	0x0010, 0x2011, 0x0000, 0x2100, 0xa205, 0x700a, 0x7004, 0xa085,
-	0x000a, 0x7006, 0x2071, 0x4600, 0x7004, 0xd0bc, 0x0158, 0xd3fc,
-	0x1120, 0x73ea, 0x2071, 0x4640, 0x0018, 0x73ee, 0x2071, 0x4680,
-	0x701f, 0x000d, 0x003e, 0x00ee, 0x0005, 0x2001, 0x01ff, 0x2004,
-	0xd0fc, 0x11d0, 0x2001, 0x04fd, 0x2004, 0xa082, 0x0005, 0x12a0,
-	0x2071, 0x0200, 0x71ec, 0xa18c, 0x1c00, 0x810f, 0x810c, 0x810c,
-	0x2079, 0x0100, 0x78ec, 0xa084, 0x1c00, 0x8007, 0x8004, 0x8004,
-	0xa105, 0xa08a, 0x0007, 0x0208, 0x0005, 0x0002, 0x254b, 0x2532,
-	0x254b, 0x2532, 0x2525, 0x253f, 0x2525, 0x7008, 0xa084, 0xc3ff,
-	0xa085, 0x3000, 0x700a, 0x7808, 0xa084, 0xc3ff, 0xa085, 0x3000,
-	0x780a, 0x0005, 0x7008, 0xa084, 0xc3ff, 0xa085, 0x2000, 0x700a,
-	0x7808, 0xa084, 0xc3ff, 0xa085, 0x2000, 0x780a, 0x0005, 0x7008,
-	0xa084, 0xc3ff, 0xa085, 0x0c00, 0x700a, 0x7808, 0xa084, 0xc3ff,
-	0xa085, 0x0c00, 0x780a, 0x0005, 0x0e04, 0x254c, 0x2091, 0x8000,
-	0x2071, 0x0000, 0x0006, 0x7018, 0xd084, 0x1de8, 0x000e, 0x2071,
-	0x0010, 0x70ca, 0x000e, 0x70c6, 0x70c3, 0x8002, 0x70db, 0x0a04,
-	0x70df, 0x0020, 0x2071, 0x0000, 0x701b, 0x0001, 0x2091, 0x4080,
-	0x0cf8, 0x7f3c, 0x7e58, 0x7c30, 0x7d38, 0x78a0, 0x708a, 0x758e,
-	0x7492, 0x7696, 0x779a, 0xa594, 0x003f, 0xd4f4, 0x0138, 0xd7bc,
-	0x1128, 0xa784, 0x007d, 0x1904, 0x3c74, 0x0871, 0xa49c, 0x000f,
-	0xa382, 0x0004, 0x0320, 0xa3a6, 0x0007, 0x1930, 0x2418, 0x8507,
-	0xa084, 0x000f, 0x0002, 0x2b49, 0x2c34, 0x2c72, 0x2ed8, 0x3256,
-	0x32ad, 0x3353, 0x33e2, 0x34b6, 0x3588, 0x259e, 0x259b, 0x2970,
-	0x2a56, 0x322a, 0x259b, 0x080c, 0x254c, 0x0005, 0xa006, 0x0038,
-	0x7808, 0xc08d, 0x780a, 0xa006, 0x7002, 0x704a, 0x7042, 0x70ce,
-	0x705c, 0xa005, 0x1904, 0x26ec, 0x7060, 0xa084, 0x0007, 0x0002,
-	0x25b8, 0x2626, 0x262e, 0x2637, 0x2640, 0x26d2, 0x2649, 0x2626,
-	0x7830, 0xd0bc, 0x1d10, 0x71d0, 0xd1bc, 0x19f8, 0xd1b4, 0x1904,
-	0x2603, 0x70a0, 0xa086, 0x0001, 0x09c0, 0x70b0, 0xa06d, 0x6800,
-	0xa065, 0xa055, 0x789b, 0x0080, 0x6b0c, 0x7baa, 0x6808, 0xa045,
-	0x6d10, 0x6804, 0xa06d, 0xa05d, 0xa886, 0x0001, 0x0118, 0x69bc,
-	0x7daa, 0x79aa, 0x68c0, 0xa04d, 0x6e1c, 0x2001, 0x0010, 0x0804,
-	0x281f, 0x705c, 0xa005, 0x1904, 0x259d, 0x00c6, 0x00d6, 0x70b0,
-	0xa06d, 0x6800, 0xa065, 0xa055, 0x789b, 0x0080, 0x6b0c, 0x7baa,
-	0x6808, 0xa045, 0x6d10, 0x6804, 0xa06d, 0xa05d, 0xa886, 0x0001,
-	0x0118, 0x69bc, 0x7daa, 0x79aa, 0x68c0, 0xa04d, 0x6e1c, 0x2001,
-	0x0020, 0x0804, 0x281f, 0x080c, 0x3c33, 0x1904, 0x259d, 0x781b,
-	0x0068, 0x70b8, 0xa06d, 0x68b4, 0x785a, 0x6894, 0x78d6, 0x78de,
-	0x6898, 0x78d2, 0x78da, 0x7808, 0xc08d, 0x780a, 0x68bc, 0x703e,
-	0xc1b4, 0x71d2, 0x70b4, 0xa065, 0x68c0, 0x7056, 0x7003, 0x0002,
-	0x2d00, 0x704a, 0xad80, 0x0009, 0x7042, 0x0005, 0x080c, 0x3c33,
-	0x1120, 0x781b, 0x0054, 0x7003, 0x0004, 0x0005, 0x080c, 0x3c33,
-	0x1128, 0x2011, 0x000c, 0x0419, 0x7003, 0x0004, 0x0005, 0x080c,
-	0x3c33, 0x1128, 0x2011, 0x0006, 0x00d1, 0x7003, 0x0004, 0x0005,
-	0x080c, 0x3c33, 0x1128, 0x2011, 0x000d, 0x0089, 0x7003, 0x0004,
-	0x0005, 0x080c, 0x3c33, 0x1150, 0x2011, 0x0006, 0x0041, 0x7078,
-	0x707b, 0x0000, 0x2068, 0x704a, 0x7003, 0x0004, 0x0005, 0x7170,
-	0xc1fc, 0x8107, 0x7882, 0x789b, 0x0080, 0xa286, 0x000c, 0x1120,
-	0x7aaa, 0x2001, 0x0001, 0x0098, 0xa18c, 0x001f, 0xa18d, 0x00c0,
-	0x79aa, 0xa286, 0x000d, 0x0120, 0x7aaa, 0x2001, 0x0002, 0x0038,
-	0x78ab, 0x0020, 0x7174, 0x79aa, 0x7aaa, 0x2001, 0x0004, 0x789b,
-	0x0060, 0x78aa, 0x785b, 0x0004, 0x781b, 0x0113, 0x080c, 0x3c46,
-	0x707f, 0x000f, 0x70d0, 0xd0b4, 0x0168, 0xc0b4, 0x70d2, 0x00c6,
-	0x70b4, 0xa065, 0x6008, 0xa084, 0xfbef, 0x600a, 0x6018, 0x8001,
-	0x601a, 0x00ce, 0x0005, 0x7014, 0xa005, 0x1138, 0x70d0, 0xd0b4,
-	0x0128, 0x70b4, 0xac06, 0x1110, 0x0c29, 0x0005, 0x0016, 0x71a0,
-	0xa186, 0x0001, 0x0528, 0x00d6, 0x0026, 0x2100, 0x2011, 0x0001,
-	0xa212, 0x70b0, 0x2068, 0x6800, 0xac06, 0x0120, 0x8211, 0x01b0,
-	0x00c9, 0x0cc8, 0x00c6, 0x2100, 0x2011, 0x0001, 0xa212, 0x70b0,
-	0x2068, 0x6800, 0x2060, 0x6008, 0xa084, 0xfbef, 0x600a, 0x8211,
-	0x0110, 0x0041, 0x0cb0, 0x70a3, 0x0001, 0x00ce, 0x002e, 0x00de,
-	0x001e, 0x0005, 0xade8, 0x0005, 0x70a8, 0xad06, 0x1110, 0x70a4,
-	0x2068, 0x0005, 0x080c, 0x3c33, 0x1904, 0x259d, 0x7078, 0x2068,
-	0x7770, 0x080c, 0x3b6f, 0x2c50, 0x080c, 0x3cce, 0x789b, 0x0080,
-	0x6814, 0xa084, 0x001f, 0xc0bd, 0x78aa, 0x6e1c, 0x2041, 0x0001,
-	0x2001, 0x0004, 0x0804, 0x2824, 0x080c, 0x3c33, 0x1904, 0x259d,
-	0x789b, 0x0080, 0x705c, 0x2068, 0x6f14, 0x70d0, 0xd0b4, 0x0168,
-	0xc0b4, 0x70d2, 0x00c6, 0x70b4, 0xa065, 0x6008, 0xa084, 0xfbef,
-	0x600a, 0x6018, 0x8001, 0x601a, 0x00ce, 0x080c, 0x3b6f, 0x2c50,
-	0x080c, 0x3cce, 0x6824, 0xa005, 0x0130, 0xa082, 0x0006, 0x0208,
-	0x0010, 0x6827, 0x0005, 0x6814, 0xa084, 0x001f, 0xc0bd, 0x78aa,
-	0x2031, 0x0020, 0x2041, 0x0001, 0x2001, 0x0003, 0x0804, 0x2824,
-	0xc28d, 0x72d2, 0x72bc, 0xa200, 0xa015, 0x7150, 0x8108, 0xa12a,
-	0x0208, 0x71bc, 0x2164, 0x6504, 0x85ff, 0x1170, 0x7152, 0x8421,
-	0x1da8, 0x70d0, 0xd08c, 0x0128, 0x70cc, 0xa005, 0x1110, 0x70cf,
-	0x000a, 0x0005, 0x2200, 0x0c90, 0x70d0, 0xc08c, 0x70d2, 0x70cf,
-	0x0000, 0x6034, 0xa005, 0x1db0, 0x6708, 0xa784, 0x073f, 0x01d0,
-	0xd7d4, 0x1d80, 0xa784, 0x0021, 0x1d68, 0xa784, 0x0002, 0x0130,
-	0xa784, 0x0004, 0x0d38, 0xa7bc, 0xfffb, 0x670a, 0xa784, 0x0218,
-	0x1d08, 0xa784, 0x0100, 0x0130, 0x6018, 0xa005, 0x19d8, 0xa7bc,
-	0xfeff, 0x670a, 0x2568, 0x6823, 0x0000, 0x6e1c, 0xa684, 0x000e,
-	0x6318, 0x0128, 0x601c, 0xa302, 0x0220, 0x0118, 0x0858, 0x83ff,
-	0x1948, 0x2d58, 0x2c50, 0x7152, 0xd7bc, 0x1120, 0x7028, 0x6022,
-	0x603a, 0x0010, 0xc7bc, 0x670a, 0x68c0, 0xa065, 0xa04d, 0x6100,
-	0x2a60, 0x2041, 0x0001, 0x6b14, 0xa39c, 0x001f, 0xa39d, 0x00c0,
-	0xd1fc, 0x0110, 0xd684, 0x0110, 0xa39c, 0xffbf, 0xd6a4, 0x0110,
-	0xa39d, 0x0020, 0xa684, 0x000e, 0x1904, 0x27d6, 0xc7a5, 0x670a,
-	0x2c00, 0x68c6, 0x77a0, 0xa786, 0x0001, 0x1178, 0x70d0, 0xd0b4,
-	0x1160, 0x7000, 0xa082, 0x0002, 0x1240, 0x7830, 0xd0bc, 0x1128,
-	0x789b, 0x0080, 0x7baa, 0x0804, 0x281d, 0x8739, 0x77a2, 0x2750,
-	0x77ac, 0xa7b0, 0x0005, 0x70a8, 0xa606, 0x1108, 0x76a4, 0x76ae,
-	0x2c3a, 0x8738, 0x2d3a, 0x8738, 0x283a, 0x8738, 0x233a, 0x8738,
-	0x253a, 0x7830, 0xd0bc, 0x0150, 0x2091, 0x8000, 0x2091, 0x303d,
-	0x70d0, 0xa084, 0x303d, 0x2091, 0x8000, 0x2090, 0xaad5, 0x0000,
-	0x0120, 0x8421, 0x2200, 0x1904, 0x2725, 0x0005, 0xd1dc, 0x0904,
-	0x37ce, 0x2029, 0x0020, 0xd69c, 0x1120, 0x8528, 0xd68c, 0x1108,
-	0x8528, 0x8840, 0x6f14, 0x610c, 0x8108, 0xa18c, 0x00ff, 0x70c8,
-	0xa160, 0x2c64, 0x8cff, 0x0188, 0x6014, 0xa706, 0x1dd0, 0x60b8,
-	0x8001, 0x60ba, 0x1d88, 0x2a60, 0x6008, 0xa085, 0x0100, 0x600a,
-	0x2200, 0x8421, 0x1904, 0x2725, 0x0005, 0x2a60, 0x610e, 0x69be,
-	0x2c00, 0x68c6, 0x8840, 0x6008, 0xc0d5, 0x600a, 0x77a0, 0xa786,
-	0x0001, 0x1904, 0x27ad, 0x70d0, 0xd0b4, 0x1904, 0x27ad, 0x7000,
-	0xa082, 0x0002, 0x1a04, 0x27ad, 0x7830, 0xd0bc, 0x1904, 0x27ad,
-	0x789b, 0x0080, 0x7baa, 0x7daa, 0x79aa, 0x2001, 0x0002, 0x0006,
-	0x6018, 0x8000, 0x601a, 0x0008, 0x0006, 0x2960, 0x6104, 0x2a60,
-	0x080c, 0x3ce1, 0x1590, 0xa184, 0x0018, 0x0180, 0xa184, 0x0010,
-	0x0118, 0x080c, 0x3977, 0x1548, 0xa184, 0x0008, 0x0138, 0x69a0,
-	0xa184, 0x0600, 0x1118, 0x080c, 0x3895, 0x00f8, 0x69a0, 0xa184,
-	0x1e00, 0x0528, 0xa184, 0x0800, 0x0178, 0x00c6, 0x2960, 0x6000,
-	0xa085, 0x2000, 0x6002, 0x6104, 0xa18d, 0x0010, 0x6106, 0x00ce,
-	0x080c, 0x3977, 0x1150, 0x69a0, 0xa184, 0x0200, 0x0118, 0x080c,
-	0x38da, 0x0018, 0xa184, 0x0400, 0x19f0, 0x69a0, 0xa184, 0x1000,
-	0x0130, 0x6914, 0xa18c, 0xff00, 0x810f, 0x080c, 0x239c, 0x002e,
-	0xa68c, 0x00e0, 0xa684, 0x0060, 0x0128, 0xa086, 0x0060, 0x1110,
-	0xa18d, 0x4000, 0xa18d, 0x0104, 0x69b6, 0x789b, 0x0060, 0x2800,
-	0x78aa, 0x6818, 0xc0fd, 0x681a, 0xd6bc, 0x0168, 0xc0fc, 0x7083,
-	0x0000, 0xa08a, 0x000d, 0x0328, 0xa08a, 0x000c, 0x7182, 0x2001,
-	0x000c, 0x800c, 0x7186, 0x78aa, 0x3518, 0x3340, 0x3428, 0x8000,
-	0x80ac, 0xaf80, 0x002b, 0x20a0, 0x789b, 0x0000, 0xad80, 0x000b,
-	0x2098, 0x53a6, 0x23a8, 0x2898, 0x25a0, 0xa286, 0x0020, 0x1508,
-	0x70d0, 0xc0b5, 0x70d2, 0x2c00, 0x70b6, 0x2d00, 0x70ba, 0x6814,
-	0xc0fc, 0x8007, 0x7882, 0xa286, 0x0002, 0x0904, 0x28f5, 0x70a0,
-	0x8000, 0x70a2, 0x74b0, 0xa498, 0x0005, 0x70a8, 0xa306, 0x1108,
-	0x73a4, 0x73b2, 0xa286, 0x0010, 0x0904, 0x259d, 0x00de, 0x00ce,
-	0x0005, 0x7000, 0xa005, 0x19e0, 0xa286, 0x0002, 0x1904, 0x290c,
-	0x080c, 0x3c33, 0x19a8, 0x6814, 0xc0fc, 0x8007, 0x7882, 0x2091,
-	0x8000, 0x781b, 0x0068, 0x68b4, 0x785a, 0x6894, 0x78d6, 0x78de,
-	0x6898, 0x78d2, 0x78da, 0x2091, 0x8001, 0x7808, 0xc08d, 0x780a,
-	0x0126, 0x00d6, 0x00c6, 0x70d0, 0xa084, 0x2e00, 0x2090, 0x00ce,
-	0x00de, 0x012e, 0x2900, 0x7056, 0x68bc, 0x703e, 0x7003, 0x0002,
-	0x2d00, 0x704a, 0xad80, 0x0009, 0x7042, 0x7830, 0xd0bc, 0x0140,
-	0x2091, 0x303d, 0x70d0, 0xa084, 0x303d, 0x2091, 0x8000, 0x2090,
-	0x70a0, 0xa005, 0x1108, 0x0005, 0x8421, 0x0de8, 0x724c, 0x70bc,
-	0xa200, 0xa015, 0x0804, 0x2725, 0xa286, 0x0010, 0x1560, 0x080c,
-	0x3c33, 0x1904, 0x28a0, 0x6814, 0xc0fc, 0x8007, 0x7882, 0x781b,
-	0x0068, 0x68b4, 0x785a, 0x6894, 0x78d6, 0x78de, 0x6898, 0x78d2,
-	0x78da, 0x7808, 0xc08d, 0x780a, 0x70a0, 0x8000, 0x70a2, 0x74b0,
-	0xa490, 0x0005, 0x70a8, 0xa206, 0x1108, 0x72a4, 0x72b2, 0x2900,
-	0x7056, 0x68bc, 0x703e, 0x7003, 0x0002, 0x2d00, 0x704a, 0xad80,
-	0x0009, 0x7042, 0x0005, 0x6bb4, 0xa39d, 0x2000, 0x7b5a, 0x6814,
-	0xc0fc, 0x8007, 0x7882, 0x6b94, 0x7bd6, 0x7bde, 0x6e98, 0x7ed2,
-	0x7eda, 0x781b, 0x0068, 0x2900, 0x7056, 0x7202, 0x7808, 0xc08d,
-	0x780a, 0x2300, 0xa605, 0x0170, 0x70d0, 0xa084, 0x2e00, 0xa086,
-	0x2600, 0x1118, 0x2009, 0x0000, 0x0010, 0x2009, 0x0001, 0xa284,
-	0x000f, 0x0023, 0xad80, 0x0009, 0x7042, 0x0005, 0x296e, 0x41d9,
-	0x41d9, 0x41c7, 0x41d9, 0x296e, 0x296e, 0x296e, 0x080c, 0x254c,
-	0x7808, 0xa084, 0xfffd, 0x780a, 0x00f6, 0x2079, 0x4600, 0x78ac,
-	0x00fe, 0xd084, 0x01b0, 0x7060, 0xa086, 0x0001, 0x0904, 0x2a32,
-	0x7060, 0xa086, 0x0005, 0x1158, 0x7078, 0x2068, 0x681b, 0x0004,
+	0x0110, 0xc0c5, 0x7812, 0x080c, 0x1b34, 0x000e, 0x7812, 0x080c,
+	0x1b7f, 0x2001, 0x4007, 0x0804, 0x13bc, 0x6104, 0xa18c, 0x00ff,
+	0xa186, 0x0005, 0x1118, 0x601c, 0xc0bd, 0x601e, 0x74c4, 0x73c8,
+	0x72cc, 0x6014, 0x2091, 0x8000, 0x00e6, 0x2009, 0x0012, 0xd0fc,
+	0x1118, 0x2071, 0x4740, 0x0018, 0x2071, 0x4780, 0xc1fd, 0x792a,
+	0x7063, 0x0005, 0x71d0, 0xc1c4, 0x71d2, 0x7366, 0x726a, 0x746e,
+	0x7072, 0x7077, 0x0000, 0x2c00, 0x707a, 0xa02e, 0x2530, 0x611c,
+	0xa184, 0x0060, 0x0110, 0x080c, 0x3fe9, 0x00ee, 0x6596, 0x65a6,
+	0x669a, 0x66aa, 0x60af, 0x0000, 0x60b3, 0x0000, 0x6714, 0x6023,
+	0x0000, 0x6024, 0xa096, 0x0001, 0x1110, 0x8000, 0x6026, 0x080c,
+	0x22d5, 0x2091, 0x8001, 0x0005, 0x70c3, 0x4005, 0x0804, 0x13bd,
+	0x20a9, 0x0005, 0x2099, 0x4714, 0x2091, 0x8000, 0x530a, 0x2091,
+	0x8001, 0x2100, 0xa210, 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9,
+	0x0000, 0x0005, 0x71c4, 0x70c7, 0x0000, 0x791e, 0x0804, 0x13ba,
+	0x71c4, 0x71c6, 0x2168, 0x0010, 0x2069, 0x1000, 0x690c, 0xa016,
+	0x2d04, 0xa210, 0x8d68, 0x8109, 0x1dd8, 0xa285, 0x0000, 0x1118,
+	0x70c3, 0x4000, 0x0010, 0x70c3, 0x4003, 0x70ca, 0x0804, 0x13bd,
+	0x7964, 0x71c6, 0x71c4, 0xa182, 0x0003, 0x1a04, 0x13b3, 0x7966,
+	0x0804, 0x13ba, 0x7964, 0x71c6, 0x0804, 0x13ba, 0x7900, 0x71c6,
+	0x71c4, 0x7902, 0x0804, 0x13ba, 0x7900, 0x71c6, 0x0804, 0x13ba,
+	0x70c4, 0x2011, 0x0000, 0xa08c, 0x000d, 0x0160, 0x810c, 0x0230,
+	0x8210, 0x810c, 0x810c, 0x0210, 0x8210, 0x810c, 0x81ff, 0x1904,
+	0x13b4, 0x8210, 0x7a0e, 0xd28c, 0x0538, 0x7910, 0xc1cd, 0x7912,
+	0x2009, 0x0021, 0x2019, 0x0003, 0xd284, 0x01c0, 0x8108, 0x2019,
+	0x0041, 0x2011, 0x8f4e, 0x2312, 0x2019, 0x0042, 0x8210, 0x2312,
+	0x2019, 0x0043, 0x8210, 0x2312, 0x2019, 0x0046, 0x8210, 0x2312,
+	0x2019, 0x0047, 0x8210, 0x2312, 0x2019, 0x0006, 0x2011, 0x8f53,
+	0x2112, 0x2011, 0x8f73, 0x2312, 0x7904, 0x7806, 0x0804, 0x13b9,
+	0x7804, 0x70c6, 0x0804, 0x13ba, 0x71c4, 0xd1fc, 0x1118, 0x2011,
+	0x4bc0, 0x0010, 0x2011, 0x4c40, 0x8107, 0xa084, 0x000f, 0x8003,
+	0x8003, 0x8003, 0xa268, 0x2011, 0x0000, 0x6814, 0xd0fc, 0x0110,
+	0xa295, 0x0200, 0xd0b4, 0x0110, 0xa295, 0x0001, 0x6b0c, 0x6800,
+	0x70da, 0x0804, 0x13b7, 0x7814, 0xd0f4, 0x0130, 0x2001, 0x4007,
+	0x70db, 0x0000, 0xa005, 0x0048, 0xd0fc, 0x0130, 0x2001, 0x4007,
+	0x70db, 0x0001, 0xa005, 0x0008, 0xa006, 0x0005, 0x7814, 0xd0f4,
+	0x0130, 0x2001, 0x4007, 0x70db, 0x0000, 0xa005, 0x0008, 0xa006,
+	0x0005, 0x7814, 0xd0fc, 0x0130, 0x2001, 0x4007, 0x70db, 0x0001,
+	0xa005, 0x0008, 0xa006, 0x0005, 0x7112, 0x721a, 0x731e, 0x7810,
+	0xd0c4, 0x0110, 0x7422, 0x7526, 0xac80, 0x0001, 0x8108, 0x810c,
+	0x81a9, 0x8098, 0x20a1, 0x0030, 0x7003, 0x0000, 0x6084, 0x20a2,
+	0x53a6, 0x7007, 0x0001, 0x7974, 0xa184, 0xff00, 0x0140, 0x810f,
+	0x810c, 0x810c, 0x8004, 0x8004, 0x8007, 0xa100, 0x0018, 0x8107,
+	0x8004, 0x8004, 0x797c, 0xa108, 0x7a78, 0xa006, 0xa211, 0x7d10,
+	0xd5c4, 0x0120, 0x7b84, 0xa319, 0x7c80, 0xa421, 0x7008, 0xd0fc,
+	0x0de8, 0x7003, 0x0001, 0x7007, 0x0006, 0x711a, 0x721e, 0x7d10,
+	0xd5c4, 0x0110, 0x7322, 0x7426, 0xa084, 0x01e0, 0x0005, 0x7848,
+	0xa065, 0x0120, 0x2c04, 0x784a, 0x2063, 0x0000, 0x0005, 0x00f6,
+	0x2079, 0x4700, 0x7848, 0x2062, 0x2c00, 0xa005, 0x1110, 0x080c,
+	0x2575, 0x784a, 0x00fe, 0x0005, 0x2011, 0x9100, 0x7a4a, 0x7bc4,
+	0x8319, 0x0128, 0xa280, 0x0032, 0x2012, 0x2010, 0x0cc8, 0x2013,
+	0x0000, 0x0005, 0x0016, 0x0026, 0xd7fc, 0x1118, 0x2011, 0x4cc0,
+	0x0010, 0x2011, 0x6cc0, 0xa784, 0x0f00, 0x800b, 0xa784, 0x001f,
+	0x0120, 0x8003, 0x8003, 0x8003, 0x8003, 0xa105, 0xa268, 0x002e,
+	0x001e, 0x0005, 0x0c39, 0x2900, 0x682a, 0x2a00, 0x682e, 0x6808,
+	0xa084, 0xf9ef, 0xa80d, 0x690a, 0x00e6, 0xd7fc, 0x1128, 0x2009,
+	0x4752, 0x2071, 0x4740, 0x0020, 0x2009, 0x4792, 0x2071, 0x4780,
+	0x210c, 0x6804, 0xa005, 0x0148, 0xa116, 0x1138, 0x2060, 0x6000,
+	0x6806, 0x0016, 0x200b, 0x0000, 0x0018, 0x2009, 0x0000, 0x0016,
+	0x6804, 0xa065, 0x0178, 0x6000, 0x6806, 0x0421, 0x080c, 0x1db2,
+	0x6810, 0x7908, 0x8109, 0x790a, 0x8001, 0x6812, 0x1d88, 0x7910,
+	0xc1a5, 0x7912, 0x001e, 0x6902, 0x6906, 0x2d00, 0x2060, 0x080c,
+	0x26bf, 0x00ee, 0x0005, 0xa065, 0x0160, 0x2008, 0x609c, 0xa005,
+	0x0128, 0x2062, 0x609f, 0x0000, 0xa065, 0x0cc0, 0x7848, 0x794a,
+	0x2062, 0x0005, 0x6007, 0x0103, 0x608f, 0x0000, 0x20a9, 0x001c,
+	0xac80, 0x0005, 0x20a0, 0x2001, 0x0000, 0x40a4, 0x6828, 0x601a,
+	0x682c, 0x6022, 0x0005, 0x00e6, 0xd7fc, 0x1128, 0x2071, 0x4740,
+	0x2031, 0x47c0, 0x0020, 0x2071, 0x4780, 0x2031, 0x49c0, 0x704c,
+	0xa08c, 0x0200, 0x1128, 0xa608, 0x2d0a, 0x8000, 0x704e, 0xa006,
+	0x00ee, 0x0005, 0x00f6, 0xd7fc, 0x1118, 0x2079, 0x4740, 0x0010,
+	0x2079, 0x4780, 0x080c, 0x1b9a, 0x2091, 0x8000, 0x6804, 0x780a,
+	0xa065, 0x05f0, 0x0030, 0x2c00, 0x780a, 0x2060, 0x6000, 0xa065,
+	0x05b8, 0x6010, 0xa306, 0x1db8, 0x600c, 0xa206, 0x1da0, 0x2c28,
+	0x7848, 0xac06, 0x1108, 0x0448, 0x6804, 0xac06, 0x1140, 0x6000,
+	0x2060, 0x6806, 0xa005, 0x1118, 0x6803, 0x0000, 0x0048, 0x6400,
+	0x7808, 0x2060, 0x6402, 0xa486, 0x0000, 0x1110, 0x2c00, 0x6802,
+	0x2560, 0x080c, 0x1c02, 0x601b, 0x0005, 0x6023, 0x0020, 0x00fe,
+	0x080c, 0x1db2, 0x00f6, 0x7908, 0x8109, 0x790a, 0x6810, 0x8001,
+	0x6812, 0x1118, 0x7810, 0xc0a5, 0x7812, 0x2001, 0xffff, 0xa005,
+	0x00fe, 0x0005, 0x0076, 0x2700, 0x2039, 0x0000, 0xd0fc, 0x0108,
+	0xc7fd, 0x2041, 0x0021, 0x2049, 0x0004, 0x2051, 0x0008, 0x2091,
+	0x8000, 0x080c, 0x1bb2, 0x8738, 0xa784, 0x001f, 0x1dd0, 0xa7bc,
+	0xff00, 0x873f, 0x8738, 0x873f, 0xa784, 0x0f00, 0x1d90, 0x2091,
+	0x8001, 0x007e, 0x0005, 0x786c, 0x2009, 0x8f74, 0x210c, 0xa10d,
+	0x0118, 0xa065, 0x0804, 0x20a1, 0x2061, 0x0000, 0x6018, 0xd084,
+	0x11b8, 0x7810, 0xd08c, 0x0130, 0xc08c, 0x7812, 0xc7fc, 0x2069,
+	0x4740, 0x0028, 0xc08d, 0x7812, 0x2069, 0x4780, 0xc7fd, 0x2091,
+	0x8000, 0x681c, 0x681f, 0x0000, 0x2091, 0x8001, 0xa005, 0x1108,
+	0x0005, 0xa08c, 0xfff0, 0x0110, 0x080c, 0x2575, 0x0002, 0x1cd7,
+	0x1cda, 0x1ce0, 0x1ce4, 0x1cd8, 0x1ce8, 0x1cd8, 0x1cd8, 0x1cd8,
+	0x1cee, 0x1d18, 0x1d1b, 0x1d20, 0x1d29, 0x1cd8, 0x1cd8, 0x0005,
+	0x080c, 0x2575, 0x080c, 0x1c7a, 0x2001, 0x8001, 0x0804, 0x1d32,
+	0x2001, 0x8003, 0x0804, 0x1d32, 0x2001, 0x8004, 0x0804, 0x1d32,
+	0x080c, 0x1c7a, 0x2001, 0x8006, 0x0804, 0x1d32, 0x2011, 0x800a,
+	0x2091, 0x8000, 0xd7fc, 0x1118, 0x2069, 0x4740, 0x0010, 0x2069,
+	0x4780, 0x2038, 0x6800, 0xa086, 0x0000, 0x0120, 0x6f1e, 0x2091,
+	0x8001, 0x0005, 0x0026, 0x6870, 0xa0bc, 0xff00, 0x2041, 0x0021,
+	0x2049, 0x0004, 0x2051, 0x0010, 0x080c, 0x1bb2, 0x8738, 0xa784,
+	0x001f, 0x1dd0, 0x2091, 0x8001, 0x000e, 0x6970, 0x71c6, 0x00d0,
+	0x2001, 0x800c, 0x00b8, 0x080c, 0x1c7a, 0x2001, 0x800d, 0x0090,
+	0xd7fc, 0x0110, 0x78e4, 0x0008, 0x78e0, 0x70c6, 0x2001, 0x800e,
+	0x0048, 0xd7fc, 0x0110, 0x78ec, 0x0008, 0x78e8, 0x70c6, 0x2001,
+	0x800f, 0x0000, 0x70c2, 0xd7fc, 0x1118, 0x70db, 0x0000, 0x0010,
+	0x70db, 0x0001, 0x2061, 0x0000, 0x601b, 0x0001, 0x2091, 0x4080,
+	0x0005, 0xac80, 0x0001, 0x81ff, 0x0518, 0x2099, 0x0030, 0x20a0,
+	0x700c, 0xa084, 0x07ff, 0x0100, 0x7018, 0x0006, 0x701c, 0x0006,
+	0x7020, 0x0006, 0x7024, 0x0006, 0x7112, 0x81ac, 0x721a, 0x731e,
+	0x7422, 0x7526, 0x7003, 0x0001, 0x7007, 0x0001, 0x7008, 0x800b,
+	0x1ee8, 0x7007, 0x0002, 0xa08c, 0x01e0, 0x1110, 0x53a5, 0xa006,
+	0x7003, 0x0000, 0x7007, 0x0004, 0x000e, 0x7026, 0x000e, 0x7022,
+	0x000e, 0x701e, 0x000e, 0x701a, 0x0005, 0x2011, 0x0020, 0x2009,
+	0x0010, 0x6b0a, 0x6c0e, 0x681f, 0x0201, 0x6803, 0xfd20, 0x6807,
+	0x0038, 0x6a1a, 0x2d00, 0xa0e8, 0x0008, 0xa290, 0x0004, 0x8109,
+	0x1d80, 0x0005, 0x70ec, 0xd0dc, 0x1520, 0x2029, 0x0001, 0x7814,
+	0xd0cc, 0x1160, 0x70ec, 0xd0e4, 0x2019, 0x0c0a, 0x2021, 0x000a,
+	0x1120, 0x2019, 0x0c0c, 0x2021, 0x000c, 0x0070, 0x70ec, 0xd0e4,
+	0x1128, 0x2019, 0x180c, 0x2021, 0x000c, 0x0030, 0x2019, 0x1809,
+	0x2021, 0x0009, 0xa5ad, 0x0200, 0x6b0a, 0x6c0e, 0x6d1e, 0x6807,
+	0x0038, 0x0005, 0x6004, 0x6086, 0x2c08, 0x2063, 0x0000, 0x7868,
+	0xa005, 0x796a, 0x0110, 0x2c02, 0x0008, 0x796e, 0x0005, 0x00c6,
+	0x2061, 0x4700, 0x6887, 0x0103, 0x2d08, 0x206b, 0x0000, 0x6068,
+	0xa005, 0x616a, 0x0110, 0x2d02, 0x0008, 0x616e, 0x00ce, 0x0005,
+	0x2091, 0x8000, 0x2c04, 0x786e, 0xa005, 0x1108, 0x786a, 0x2091,
+	0x8001, 0x609c, 0xa005, 0x0188, 0x00c6, 0x2060, 0x2008, 0x609c,
+	0xa005, 0x0138, 0x2062, 0x609f, 0x0000, 0xa065, 0x609c, 0xa005,
+	0x1dc8, 0x7848, 0x794a, 0x2062, 0x00ce, 0x7848, 0x2062, 0x609f,
+	0x0000, 0xac85, 0x0000, 0x1110, 0x080c, 0x2575, 0x784a, 0x0005,
+	0x20a9, 0x0010, 0xa006, 0x8004, 0x8086, 0x818e, 0x1208, 0xa200,
+	0x1f04, 0x1dfc, 0x8086, 0x818e, 0x0005, 0x0156, 0x20a9, 0x0010,
+	0xa005, 0x01b8, 0xa11a, 0x12a8, 0x8213, 0x818d, 0x0228, 0xa11a,
+	0x1220, 0x1f04, 0x1e0c, 0x0028, 0xa11a, 0x2308, 0x8210, 0x1f04,
+	0x1e0c, 0x0006, 0x3200, 0xa084, 0xefff, 0x2080, 0x000e, 0x015e,
+	0x0005, 0x0006, 0x3200, 0xa085, 0x1000, 0x0cb8, 0x7d74, 0x70d0,
+	0xa506, 0x0904, 0x1eda, 0x7810, 0x2050, 0x080c, 0x1b77, 0x0904,
+	0x1eda, 0xa046, 0x7970, 0x2500, 0x8000, 0xa112, 0x2009, 0x0040,
+	0x1208, 0x0030, 0x72d0, 0xa206, 0x0118, 0x8840, 0x2009, 0x0080,
+	0x00c6, 0x7112, 0x7007, 0x0001, 0x2099, 0x0030, 0x20a9, 0x0020,
+	0xac80, 0x0001, 0x20a0, 0x2061, 0x0000, 0x88ff, 0x0110, 0x080c,
+	0x1b77, 0x7008, 0xd0fc, 0x0de8, 0x7007, 0x0002, 0x2091, 0x8001,
+	0xa08c, 0x01e0, 0x1538, 0x53a5, 0x8cff, 0x1120, 0x88ff, 0x0904,
+	0x1ec7, 0x0050, 0x2c00, 0x788e, 0x20a9, 0x0020, 0xac80, 0x0001,
+	0x20a0, 0x53a5, 0x0804, 0x1ec7, 0xa046, 0x7218, 0x731c, 0xdac4,
+	0x0110, 0x7420, 0x7524, 0xa292, 0x0040, 0xa39b, 0x0000, 0xa4a3,
+	0x0000, 0xa5ab, 0x0000, 0x721a, 0x731e, 0xdac4, 0x0118, 0x7422,
+	0x7526, 0xa006, 0x7007, 0x0004, 0x0904, 0x1ec7, 0x8cff, 0x0110,
+	0x080c, 0x1b7f, 0x00ce, 0x080c, 0x1b7f, 0xa046, 0x7888, 0x8000,
+	0x788a, 0xa086, 0x0002, 0x01c0, 0x7a7c, 0x7b78, 0xdac4, 0x0110,
+	0x7c84, 0x7d80, 0x7974, 0x8107, 0x8004, 0x8004, 0xa210, 0xa399,
+	0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x721a, 0x731e, 0xdac4,
+	0x0588, 0x7422, 0x7526, 0x0470, 0x6014, 0xd0fc, 0x1118, 0x2069,
+	0x4740, 0x0010, 0x2069, 0x4780, 0x2091, 0x8000, 0x681f, 0x0002,
+	0x88ff, 0x0120, 0xa046, 0x788c, 0x2060, 0x0c70, 0x788b, 0x0000,
+	0x78ac, 0xa085, 0x0003, 0x78ae, 0x2091, 0x8001, 0x0098, 0x00ce,
+	0x788b, 0x0000, 0x080c, 0x205c, 0x6004, 0xa084, 0x000f, 0x0059,
+	0x88ff, 0x0130, 0x788c, 0x2060, 0x6004, 0xa084, 0x000f, 0x0019,
+	0x0804, 0x1e26, 0x0005, 0x0002, 0x1eec, 0x1f07, 0x1f20, 0x1eec,
+	0x1f2d, 0x1efd, 0x1eec, 0x1eec, 0x1eec, 0x1f05, 0x1f1e, 0x1eec,
+	0x1eec, 0x1eec, 0x1eec, 0x1eec, 0x2039, 0x0400, 0x78bc, 0xa705,
+	0x78be, 0x6008, 0xa705, 0x600a, 0x080c, 0x1f69, 0x609c, 0x78ba,
+	0x609f, 0x0000, 0x080c, 0x2048, 0x0005, 0x78bc, 0xd0c4, 0x0108,
+	0x0c58, 0x601c, 0xc0bd, 0x601e, 0x0030, 0x080c, 0x2086, 0x78bc,
+	0xd0c4, 0x0108, 0x0c08, 0x78bf, 0x0000, 0x6004, 0x8007, 0xa084,
+	0x00ff, 0x78b2, 0x8001, 0x0138, 0x080c, 0x1f69, 0x0120, 0x78bc,
+	0xc0c5, 0x78be, 0x0010, 0x0804, 0x1f84, 0x0005, 0x080c, 0x2083,
+	0x78bc, 0xa08c, 0x0e00, 0x1110, 0xd0c4, 0x1108, 0x0828, 0x080c,
+	0x1f69, 0x1110, 0x0804, 0x1f84, 0x0005, 0x78bc, 0xd0c4, 0x0110,
+	0x0804, 0x1eec, 0x78bf, 0x0000, 0x6714, 0x2011, 0x0001, 0x22a8,
+	0x6018, 0xa084, 0x00ff, 0xa005, 0x0188, 0xa7bc, 0xff00, 0x20a9,
+	0x0020, 0xa08e, 0x0001, 0x0150, 0xa7bc, 0x8000, 0x2011, 0x0002,
+	0x20a9, 0x0100, 0xa08e, 0x0002, 0x0108, 0x00c0, 0x080c, 0x1b9a,
+	0x2d00, 0x2091, 0x8000, 0x682b, 0x0000, 0x682f, 0x0000, 0x6808,
+	0xa084, 0xffde, 0x680a, 0xade8, 0x0010, 0x2091, 0x8001, 0x1f04,
+	0x1f51, 0x8211, 0x0118, 0x20a9, 0x0100, 0x0c58, 0x080c, 0x1b7f,
+	0x0005, 0x609f, 0x0000, 0x78b4, 0xa06d, 0x2c00, 0x78b6, 0x1110,
+	0x78ba, 0x0038, 0x689e, 0x2d00, 0x6002, 0x78b8, 0xad06, 0x1108,
+	0x6002, 0x78b0, 0x8001, 0x78b2, 0x1130, 0x78bc, 0xc0c4, 0x78be,
+	0x78b8, 0x2060, 0xa006, 0x0005, 0x00e6, 0xa02e, 0x2530, 0x7dba,
+	0x7db6, 0x65ae, 0x65b2, 0x601c, 0x60a2, 0x2048, 0xa984, 0xe1ff,
+	0x601e, 0xa984, 0x0060, 0x0160, 0x080c, 0x3fe9, 0x86ff, 0x1140,
+	0x85ff, 0x1130, 0x2039, 0x0800, 0x080c, 0x2048, 0x0804, 0x2046,
+	0x6596, 0x65a6, 0x669a, 0x66aa, 0x6714, 0x2071, 0x4780, 0xd7fc,
+	0x1110, 0x2071, 0x4740, 0xa784, 0x0f00, 0x800b, 0xa784, 0x001f,
+	0x0120, 0x8003, 0x8003, 0x8003, 0x8003, 0xa105, 0x71c0, 0xa168,
+	0x2700, 0x8007, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0x71c4,
+	0xa100, 0x60c2, 0x2091, 0x8000, 0x7814, 0xd0c4, 0x0138, 0xd7fc,
+	0x1118, 0xd0f4, 0x1140, 0x0010, 0xd0fc, 0x1128, 0x6e08, 0xd684,
+	0x01f0, 0xd9fc, 0x11e0, 0x2091, 0x8001, 0x080c, 0x1c02, 0x2091,
+	0x8000, 0x080c, 0x1db2, 0x2091, 0x8001, 0x7814, 0xd0c4, 0x0904,
+	0x2046, 0xd7fc, 0x1120, 0xd0f4, 0x1130, 0x0804, 0x2046, 0xd0fc,
+	0x1110, 0x0804, 0x2046, 0x601b, 0x0021, 0x0804, 0x2046, 0x6024,
+	0xa096, 0x0001, 0x1110, 0x8000, 0x6026, 0x6a10, 0x6814, 0xa202,
+	0x0268, 0x0160, 0x2091, 0x8001, 0x2039, 0x0200, 0x609c, 0x78ba,
+	0x609f, 0x0000, 0x080c, 0x2048, 0x0804, 0x2046, 0x2c08, 0xd9fc,
+	0x01f0, 0x6800, 0xa065, 0x01d8, 0x6a04, 0x7000, 0xa084, 0x0002,
+	0x0168, 0x7048, 0xa206, 0x1150, 0x6b04, 0x2160, 0x2304, 0x6002,
+	0xa005, 0x1108, 0x6902, 0x2260, 0x6102, 0x0098, 0x2d00, 0x2060,
+	0x080c, 0x26bf, 0x6e08, 0x2160, 0x6202, 0x6906, 0x0050, 0x6800,
+	0x6902, 0xa065, 0x0110, 0x6102, 0x0008, 0x6906, 0x2160, 0x6003,
+	0x0000, 0x2160, 0xd9fc, 0x0118, 0xa6b4, 0xfffc, 0x6e0a, 0x6810,
+	0x7d08, 0x8528, 0x7d0a, 0x8000, 0x6812, 0x2091, 0x8001, 0xd6b4,
+	0x0128, 0xa6b6, 0x0040, 0x6e0a, 0x080c, 0x1c13, 0x00ee, 0x0005,
+	0x6008, 0xa705, 0x600a, 0x2091, 0x8000, 0x080c, 0x1db2, 0x2091,
+	0x8001, 0x78b8, 0xa065, 0x0128, 0x609c, 0x78ba, 0x609f, 0x0000,
+	0x0c78, 0x78b6, 0x78ba, 0x0005, 0x7970, 0x7874, 0x2818, 0xd384,
+	0x0118, 0x8000, 0xa112, 0x0220, 0x8000, 0xa112, 0x1278, 0xc384,
+	0x7a7c, 0x721a, 0x7a78, 0x721e, 0xdac4, 0x0120, 0x7a84, 0x7222,
+	0x7a80, 0x7226, 0xa006, 0xd384, 0x0108, 0x8000, 0x7876, 0x70d2,
+	0x781c, 0xa005, 0x0138, 0x8001, 0x781e, 0x1120, 0x0e04, 0x2082,
+	0x2091, 0x4080, 0x0005, 0x2039, 0x2098, 0x0010, 0x2039, 0x209e,
+	0x2704, 0xa005, 0x0160, 0xac00, 0x2068, 0x6908, 0x6810, 0x6912,
+	0x680a, 0x690c, 0x6814, 0x6916, 0x680e, 0x8738, 0x0c88, 0x0005,
+	0x0003, 0x0009, 0x000f, 0x0015, 0x001b, 0x0000, 0x0015, 0x001b,
+	0x0000, 0x2041, 0x0000, 0x780c, 0x0002, 0x224a, 0x2225, 0x20a9,
+	0x2119, 0x2039, 0x8f74, 0x2734, 0x7d10, 0x00c0, 0x6084, 0xa086,
+	0x0103, 0x1904, 0x2103, 0x6114, 0x6018, 0xa105, 0x0120, 0x86ff,
+	0x11d8, 0x0804, 0x2103, 0x8603, 0xa080, 0x8f55, 0x620c, 0x2202,
+	0x8000, 0x6210, 0x2202, 0x080c, 0x1dd0, 0x8630, 0xa68e, 0x000f,
+	0x0904, 0x2184, 0x786c, 0xa065, 0x1d08, 0x7808, 0xa602, 0x1220,
+	0xd5ac, 0x1110, 0x263a, 0x0005, 0xa682, 0x0003, 0x1a04, 0x2184,
+	0x2091, 0x8000, 0x2069, 0x0000, 0x6818, 0xd084, 0x11f8, 0x2011,
+	0x8f55, 0x2204, 0x70c6, 0x8210, 0x2204, 0x70ca, 0xd684, 0x1130,
+	0x8210, 0x2204, 0x70da, 0x8210, 0x2204, 0x70de, 0xa685, 0x8020,
+	0x70c2, 0x681b, 0x0001, 0x2091, 0x4080, 0x7810, 0xa084, 0xffcf,
+	0x7812, 0x2091, 0x8001, 0x203b, 0x0000, 0x0005, 0x7810, 0xc0ad,
+	0x7812, 0x0804, 0x2184, 0x263a, 0x080c, 0x2250, 0x1904, 0x226c,
+	0x786c, 0xa065, 0x1904, 0x20ae, 0x2091, 0x8000, 0x7810, 0xa084,
+	0xffcf, 0x86ff, 0x0108, 0xc0ad, 0x7812, 0x2091, 0x8001, 0x0804,
+	0x226c, 0x2039, 0x8f74, 0x2734, 0x7d10, 0x00a0, 0x6084, 0xa086,
+	0x0103, 0x1904, 0x216e, 0x6114, 0x6018, 0xa105, 0x0120, 0x86ff,
+	0x11b8, 0x0804, 0x216e, 0xa680, 0x8f55, 0x620c, 0x2202, 0x080c,
+	0x1dd0, 0x8630, 0xa68e, 0x001e, 0x0904, 0x2184, 0x786c, 0xa065,
+	0x1d28, 0x7808, 0xa602, 0x1220, 0xd5ac, 0x1110, 0x263a, 0x0005,
+	0xa682, 0x0006, 0x1a04, 0x2184, 0x2091, 0x8000, 0x2069, 0x0000,
+	0x6818, 0xd084, 0x11f8, 0x2011, 0x8f55, 0x2009, 0x8f4e, 0x26a8,
+	0x211c, 0x2204, 0x201a, 0x8108, 0x8210, 0x1f04, 0x2150, 0xa685,
+	0x8030, 0x70c2, 0x681b, 0x0001, 0x2091, 0x4080, 0x7810, 0xa084,
+	0xffcf, 0x7812, 0x2091, 0x8001, 0xa006, 0x2009, 0x8f75, 0x200a,
+	0x203a, 0x0005, 0x7810, 0xc0ad, 0x7812, 0x00b0, 0x263a, 0x080c,
+	0x2250, 0x1904, 0x226c, 0x786c, 0xa065, 0x1904, 0x211e, 0x2091,
+	0x8000, 0x7810, 0xa084, 0xffcf, 0x86ff, 0x0108, 0xc0ad, 0x7812,
+	0x2091, 0x8001, 0x0804, 0x226c, 0x2091, 0x8000, 0x7007, 0x0004,
+	0x7994, 0x70d4, 0xa102, 0x0228, 0x0168, 0x7b90, 0xa302, 0x1150,
+	0x0010, 0x8002, 0x1138, 0x263a, 0x7810, 0xc0ad, 0x7812, 0x2091,
+	0x8001, 0x0005, 0xa184, 0xff00, 0x0140, 0x810f, 0x810c, 0x810c,
+	0x8004, 0x8004, 0x8007, 0xa100, 0x0018, 0x8107, 0x8004, 0x8004,
+	0x7a9c, 0xa210, 0x721a, 0x7a98, 0xa006, 0xa211, 0x721e, 0xd4c4,
+	0x0130, 0x7aa4, 0xa211, 0x7222, 0x7aa0, 0xa211, 0x7226, 0x20a1,
+	0x0030, 0x7003, 0x0000, 0x2009, 0x8f54, 0x260a, 0x8109, 0x2198,
+	0x2104, 0xd084, 0x0108, 0x8633, 0xa6b0, 0x0002, 0x26a8, 0x53a6,
+	0x8603, 0x7012, 0x7007, 0x0001, 0x7990, 0x7894, 0x8000, 0xa10a,
+	0x1208, 0xa006, 0x2028, 0x7974, 0xa184, 0xff00, 0x0140, 0x810f,
+	0x810c, 0x810c, 0x8004, 0x8004, 0x8007, 0xa100, 0x0018, 0x8107,
+	0x8004, 0x8004, 0x797c, 0xa108, 0x7a78, 0xa006, 0xa211, 0xd4c4,
+	0x0120, 0x7b84, 0xa319, 0x7c80, 0xa421, 0x7008, 0xd0fc, 0x0de8,
+	0xa084, 0x01e0, 0x01d0, 0x7d10, 0x2031, 0x8f54, 0x2634, 0x78a8,
+	0x8000, 0x78aa, 0xd08c, 0x1138, 0x7007, 0x0006, 0x7004, 0xd094,
+	0x1de8, 0x0804, 0x2186, 0x2069, 0x4747, 0x206b, 0x0003, 0x78ac,
+	0xa085, 0x0300, 0x78ae, 0xa006, 0x0048, 0x2030, 0x75d6, 0x2091,
+	0x4080, 0x7d96, 0x7d10, 0xa5ac, 0xffcf, 0x7d12, 0x2091, 0x8001,
+	0x78aa, 0x7007, 0x0006, 0x263a, 0x7003, 0x0001, 0x711a, 0x721e,
+	0xd5c4, 0x0110, 0x7322, 0x7426, 0x0005, 0x6084, 0xa086, 0x0103,
+	0x11d8, 0x6114, 0x6018, 0xa105, 0x11b8, 0x2069, 0x0000, 0x6818,
+	0xd084, 0x1190, 0x600c, 0x70c6, 0x6010, 0x70ca, 0x70c3, 0x8020,
+	0x681b, 0x0001, 0x2091, 0x4080, 0x080c, 0x1dd0, 0x0e04, 0x2243,
+	0x786c, 0xa065, 0x1d10, 0x0005, 0x0059, 0x1530, 0x786c, 0xa065,
+	0x19e0, 0x0410, 0x0029, 0x1500, 0x786c, 0xa065, 0x1dd8, 0x00e0,
+	0x6084, 0xa086, 0x0103, 0x1168, 0x6018, 0xc0fc, 0x601a, 0xa086,
+	0x0004, 0x1138, 0x7804, 0xd0a4, 0x0120, 0x080c, 0x1dd0, 0xa006,
+	0x0005, 0x0079, 0x1118, 0xa085, 0x0001, 0x0005, 0x00b9, 0x1110,
+	0x2041, 0x0001, 0x7d10, 0x0005, 0x88ff, 0x0110, 0x2091, 0x4080,
+	0x0005, 0x7b90, 0x7994, 0x70d4, 0xa102, 0x1118, 0xa385, 0x0000,
+	0x0005, 0x0210, 0xa302, 0x0005, 0x8002, 0x0005, 0xa184, 0xff00,
+	0x0140, 0x810f, 0x810c, 0x810c, 0x8004, 0x8004, 0x8007, 0xa100,
+	0x0018, 0x8107, 0x8004, 0x8004, 0x7a9c, 0x7b98, 0x7ca4, 0x7da0,
+	0xa210, 0xa006, 0xa319, 0xa421, 0xa529, 0x2009, 0x0018, 0x6028,
+	0xa005, 0x0110, 0x2009, 0x0040, 0x080c, 0x1b34, 0x01d0, 0x78a8,
+	0x8000, 0x78aa, 0xd08c, 0x1510, 0x6014, 0xd0fc, 0x1118, 0x2069,
+	0x4740, 0x0010, 0x2069, 0x4780, 0x2091, 0x8000, 0x681f, 0x0003,
+	0x78ab, 0x0000, 0x78ac, 0xa085, 0x0300, 0x78ae, 0x2091, 0x8001,
+	0x0068, 0x78ab, 0x0000, 0x080c, 0x1dd0, 0x7990, 0x7894, 0x8000,
+	0xa10a, 0x1208, 0xa006, 0x7896, 0x70d6, 0xa006, 0x2071, 0x0010,
+	0x2091, 0x8001, 0x0005, 0xd7fc, 0x1118, 0x2009, 0x4758, 0x0010,
+	0x2009, 0x4798, 0x2091, 0x8000, 0x200a, 0x00f6, 0x2009, 0x4780,
+	0x2079, 0x0100, 0xd7fc, 0x1120, 0x2009, 0x4740, 0x2079, 0x0200,
+	0x2104, 0xa086, 0x0000, 0x1180, 0xd7fc, 0x1118, 0x2009, 0x4745,
+	0x0010, 0x2009, 0x4785, 0x2104, 0xa005, 0x1130, 0x7830, 0xa084,
+	0x00c0, 0x1110, 0x781b, 0x0052, 0x00fe, 0x0005, 0x2009, 0x0002,
+	0x2069, 0x4700, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904, 0x234b,
+	0x2071, 0x4780, 0x2079, 0x0100, 0x2021, 0x49bf, 0x784b, 0x000f,
+	0x2001, 0x01ff, 0x2004, 0xd0fc, 0x0118, 0x2019, 0x3e37, 0x0030,
+	0x20a1, 0x012b, 0x2019, 0x3e37, 0xd184, 0x0110, 0x20a1, 0x022b,
+	0x2304, 0xa005, 0x0140, 0x789a, 0x8318, 0x23ac, 0x8318, 0x2398,
+	0x53a6, 0x3318, 0x0ca8, 0x789b, 0x0000, 0x789b, 0x0020, 0x20a9,
+	0x0010, 0x78af, 0x0000, 0x78af, 0x2020, 0x1f04, 0x2329, 0x7003,
+	0x0000, 0x0016, 0xd18c, 0x2009, 0x0000, 0x0108, 0xc1bd, 0x080c,
+	0x246c, 0x001e, 0x7020, 0xa084, 0x000f, 0xa085, 0x6300, 0x7806,
+	0x780f, 0x9000, 0x7843, 0x00d8, 0x7853, 0x0090, 0x780b, 0x2f08,
+	0x7452, 0x704f, 0x0000, 0x8109, 0x0140, 0x2071, 0x4740, 0x2079,
+	0x0200, 0x2021, 0x47bf, 0x0804, 0x2306, 0x080c, 0x2526, 0x0005,
+	0x0016, 0x2011, 0x0101, 0xd1bc, 0x1110, 0x2011, 0x0201, 0xa18c,
+	0x000f, 0x2204, 0xa084, 0xfff0, 0xa105, 0x2012, 0x001e, 0x080c,
+	0x246c, 0x0005, 0x2011, 0x0101, 0xd3fc, 0x1110, 0x2011, 0x0201,
+	0x20a9, 0x0009, 0x810b, 0x1f04, 0x2372, 0xa18c, 0x0e00, 0x2204,
+	0xa084, 0xf1ff, 0xa105, 0x2012, 0x0005, 0x2019, 0x0002, 0x2009,
+	0x0101, 0x20a9, 0x0005, 0x8213, 0x1f04, 0x2383, 0xa294, 0x00e0,
+	0x2104, 0xa084, 0xff1f, 0xa205, 0x200a, 0x8319, 0x0118, 0x2009,
+	0x0201, 0x0c78, 0x0005, 0x2011, 0x0101, 0xd3fc, 0x1110, 0x2011,
+	0x0201, 0x20a9, 0x000c, 0x810b, 0x1f04, 0x239b, 0xa18c, 0xf000,
+	0x2204, 0xa084, 0x0fff, 0xa105, 0x2012, 0x0005, 0x2011, 0x0102,
+	0xd3fc, 0x1110, 0x2011, 0x0202, 0x2204, 0xa09c, 0x0f30, 0xa084,
+	0xf0cf, 0xa105, 0x2012, 0x0005, 0x00c6, 0x2061, 0x0100, 0xd1bc,
+	0x1110, 0x2061, 0x0200, 0xc1bc, 0x8103, 0x8003, 0xa080, 0x0020,
+	0x609a, 0x62ac, 0x63ac, 0x00ce, 0x0005, 0x00c6, 0x2061, 0x0100,
+	0xd1bc, 0x1110, 0x2061, 0x0200, 0xc1bc, 0x8103, 0x8003, 0xa080,
+	0x0022, 0x609a, 0x60a4, 0xa084, 0xffdf, 0x60ae, 0x00ce, 0x0005,
+	0x00c6, 0x2061, 0x0100, 0xd1bc, 0x1110, 0x2061, 0x0200, 0xc1bc,
+	0x8103, 0x8003, 0xa080, 0x0020, 0x609a, 0x60a4, 0xa28c, 0x0020,
+	0x0118, 0xc2ac, 0xa39d, 0x4000, 0xc3ec, 0xd3b4, 0x1108, 0xc3ed,
+	0x62ae, 0x2010, 0x60a4, 0x63ae, 0x2018, 0x00ce, 0x0005, 0x2091,
+	0x8000, 0x00c6, 0x00e6, 0x6818, 0xa005, 0x0904, 0x2450, 0xd1fc,
+	0x0118, 0x2061, 0x8ed0, 0x0010, 0x2061, 0x8dc0, 0x080c, 0x2458,
+	0x0560, 0x20a9, 0x0101, 0xd1fc, 0x0118, 0x2061, 0x8dd0, 0x0010,
+	0x2061, 0x8cc0, 0x00c6, 0x080c, 0x2458, 0x0128, 0x00ce, 0x8c60,
+	0x1f04, 0x2412, 0x04a8, 0x000e, 0xd1fc, 0x0128, 0xa082, 0x8dd0,
+	0x2071, 0x4780, 0x0020, 0xa082, 0x8cc0, 0x2071, 0x4740, 0x7076,
+	0x7172, 0x2138, 0x2001, 0x0004, 0x7062, 0x707f, 0x000f, 0x71d0,
+	0xc1c4, 0x71d2, 0x080c, 0x22cb, 0x00c0, 0xd1fc, 0x1118, 0x2071,
+	0x4740, 0x0010, 0x2071, 0x4780, 0x6020, 0xc0dd, 0x6022, 0x7172,
+	0x2138, 0x2c00, 0x707a, 0x2001, 0x0006, 0x7062, 0x707f, 0x000f,
+	0x71d0, 0xc1c4, 0x71d2, 0x080c, 0x22cb, 0x2001, 0x0000, 0x0010,
+	0x2001, 0x0001, 0x2091, 0x8001, 0xa005, 0x00ee, 0x00ce, 0x0005,
+	0x2c04, 0xa005, 0x0170, 0x2060, 0x6010, 0xa306, 0x1140, 0x600c,
+	0xa206, 0x1128, 0x6014, 0xa106, 0x1110, 0xa006, 0x0020, 0x6000,
+	0x0c80, 0xa085, 0x0001, 0x0005, 0x00f6, 0x00e6, 0x0016, 0x2079,
+	0x4780, 0x2071, 0x0100, 0xd1bc, 0x1120, 0x2079, 0x4740, 0x2071,
+	0x0200, 0x7920, 0xa18c, 0x000f, 0x70ec, 0xd0c4, 0x1110, 0x001e,
+	0x0060, 0x810b, 0x810b, 0x810b, 0x810b, 0x000e, 0xa18d, 0x0800,
+	0xd0bc, 0x1110, 0xa18d, 0x0f00, 0x2104, 0x00ee, 0x00fe, 0x0005,
+	0x2001, 0x4701, 0x2004, 0xd0ac, 0x1138, 0x68e4, 0xd0ac, 0x0120,
+	0xa084, 0x0006, 0x1108, 0x0009, 0x0005, 0x6014, 0x00e6, 0x0036,
+	0x2018, 0x2071, 0x4c40, 0xd0fc, 0x1110, 0x2071, 0x4bc0, 0x8007,
+	0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xae70, 0x7004, 0xa084,
+	0x000a, 0x1904, 0x2523, 0x7108, 0xa194, 0xff00, 0x0904, 0x2523,
+	0xa18c, 0x00ff, 0x701c, 0xa084, 0xff00, 0x01c0, 0x7004, 0xa085,
+	0x003a, 0x7006, 0x2001, 0x0009, 0xa102, 0x16d8, 0x2001, 0x000a,
+	0xa102, 0x16d0, 0x2001, 0x000c, 0xa102, 0x16c8, 0x701c, 0xa084,
+	0x00ff, 0x701e, 0x7004, 0xa084, 0xffdf, 0x7006, 0x2001, 0x000a,
+	0xa106, 0x01a8, 0x2001, 0x000c, 0xa106, 0x01a0, 0x2001, 0x0012,
+	0xa106, 0x0198, 0x2001, 0x0014, 0xa106, 0x0190, 0x2001, 0x0019,
+	0xa106, 0x0188, 0x2001, 0x0032, 0xa106, 0x0180, 0x00d8, 0x2009,
+	0x000c, 0x00d0, 0x2009, 0x0012, 0x00b8, 0x2009, 0x0014, 0x00a0,
+	0x2009, 0x0019, 0x0088, 0x2009, 0x0020, 0x0070, 0x2009, 0x003f,
+	0x0058, 0x2009, 0x000a, 0x0040, 0x2009, 0x000c, 0x0028, 0x2009,
+	0x0019, 0x0010, 0x2011, 0x0000, 0x2100, 0xa205, 0x700a, 0x7004,
+	0xa085, 0x000a, 0x7006, 0x2071, 0x4700, 0x7004, 0xd0bc, 0x0158,
+	0xd3fc, 0x1120, 0x73ea, 0x2071, 0x4740, 0x0018, 0x73ee, 0x2071,
+	0x4780, 0x701f, 0x000d, 0x003e, 0x00ee, 0x0005, 0x2001, 0x01ff,
+	0x2004, 0xd0fc, 0x11d0, 0x2001, 0x04fd, 0x2004, 0xa082, 0x0005,
+	0x12a0, 0x2071, 0x0200, 0x71ec, 0xa18c, 0x1c00, 0x810f, 0x810c,
+	0x810c, 0x2079, 0x0100, 0x78ec, 0xa084, 0x1c00, 0x8007, 0x8004,
+	0x8004, 0xa105, 0xa08a, 0x0007, 0x0208, 0x0005, 0x0002, 0x2574,
+	0x255b, 0x2574, 0x255b, 0x254e, 0x2568, 0x254e, 0x7008, 0xa084,
+	0xc3ff, 0xa085, 0x3000, 0x700a, 0x7808, 0xa084, 0xc3ff, 0xa085,
+	0x3000, 0x780a, 0x0005, 0x7008, 0xa084, 0xc3ff, 0xa085, 0x2000,
+	0x700a, 0x7808, 0xa084, 0xc3ff, 0xa085, 0x2000, 0x780a, 0x0005,
+	0x7008, 0xa084, 0xc3ff, 0xa085, 0x0c00, 0x700a, 0x7808, 0xa084,
+	0xc3ff, 0xa085, 0x0c00, 0x780a, 0x0005, 0x0e04, 0x2575, 0x2091,
+	0x8000, 0x2071, 0x0000, 0x0006, 0x7018, 0xd084, 0x1de8, 0x000e,
+	0x2071, 0x0010, 0x70ca, 0x000e, 0x70c6, 0x70c3, 0x8002, 0x70db,
+	0x0a04, 0x70df, 0x002a, 0x2071, 0x0000, 0x701b, 0x0001, 0x2091,
+	0x4080, 0x0cf8, 0x7f3c, 0x7e58, 0x7c30, 0x7d38, 0x78a0, 0x708a,
+	0x758e, 0x7492, 0x7696, 0x779a, 0xa594, 0x003f, 0xd4f4, 0x0138,
+	0xd7bc, 0x1128, 0xa784, 0x007d, 0x1904, 0x3c9c, 0x0871, 0xa49c,
+	0x000f, 0xa382, 0x0004, 0x0320, 0xa3a6, 0x0007, 0x1930, 0x2418,
+	0x8507, 0xa084, 0x000f, 0x0002, 0x2b6c, 0x2c57, 0x2c95, 0x2efb,
+	0x3279, 0x32d0, 0x3376, 0x3405, 0x34d9, 0x35ab, 0x25c7, 0x25c4,
+	0x299e, 0x2a85, 0x324d, 0x25c4, 0x080c, 0x2575, 0x0005, 0xa006,
+	0x0038, 0x7808, 0xc08d, 0x780a, 0xa006, 0x7002, 0x704a, 0x7042,
+	0x70ce, 0x705c, 0xa005, 0x1904, 0x2718, 0x7060, 0xa084, 0x0007,
+	0x0002, 0x25e1, 0x2652, 0x265a, 0x2663, 0x266c, 0x26fe, 0x2675,
+	0x2652, 0x7830, 0xd0bc, 0x1d10, 0x71d0, 0xd1bc, 0x19f8, 0xd1b4,
+	0x1904, 0x262f, 0x70a0, 0xa086, 0x0001, 0x09c0, 0x7014, 0xa005,
+	0x19a8, 0x70b0, 0xa06d, 0x6800, 0xa065, 0xa055, 0x789b, 0x0080,
+	0x6b0c, 0x7baa, 0x6808, 0xa045, 0x6d10, 0x6804, 0xa06d, 0xa05d,
+	0xa886, 0x0001, 0x0118, 0x69bc, 0x7daa, 0x79aa, 0x68c0, 0xa04d,
+	0x6e1c, 0x2001, 0x0010, 0x0804, 0x284b, 0x705c, 0xa005, 0x1904,
+	0x25c6, 0x00c6, 0x00d6, 0x70b0, 0xa06d, 0x6800, 0xa065, 0xa055,
+	0x789b, 0x0080, 0x6b0c, 0x7baa, 0x6808, 0xa045, 0x6d10, 0x6804,
+	0xa06d, 0xa05d, 0xa886, 0x0001, 0x0118, 0x69bc, 0x7daa, 0x79aa,
+	0x68c0, 0xa04d, 0x6e1c, 0x2001, 0x0020, 0x0804, 0x284b, 0x080c,
+	0x3c5b, 0x1904, 0x25c6, 0x781b, 0x0068, 0x70b8, 0xa06d, 0x68b4,
+	0x785a, 0x6894, 0x78d6, 0x78de, 0x6898, 0x78d2, 0x78da, 0x7808,
+	0xc08d, 0x780a, 0x68bc, 0x703e, 0xc1b4, 0x71d2, 0x70b4, 0xa065,
+	0x68c0, 0x7056, 0x7003, 0x0002, 0x2d00, 0x704a, 0xad80, 0x0009,
+	0x7042, 0x0005, 0x080c, 0x3c5b, 0x1120, 0x781b, 0x0054, 0x7003,
+	0x0004, 0x0005, 0x080c, 0x3c5b, 0x1128, 0x2011, 0x000c, 0x0419,
+	0x7003, 0x0004, 0x0005, 0x080c, 0x3c5b, 0x1128, 0x2011, 0x0006,
+	0x00d1, 0x7003, 0x0004, 0x0005, 0x080c, 0x3c5b, 0x1128, 0x2011,
+	0x000d, 0x0089, 0x7003, 0x0004, 0x0005, 0x080c, 0x3c5b, 0x1150,
+	0x2011, 0x0006, 0x0041, 0x7078, 0x707b, 0x0000, 0x2068, 0x704a,
+	0x7003, 0x0004, 0x0005, 0x7170, 0xc1fc, 0x8107, 0x7882, 0x789b,
+	0x0080, 0xa286, 0x000c, 0x1120, 0x7aaa, 0x2001, 0x0001, 0x0098,
+	0xa18c, 0x001f, 0xa18d, 0x00c0, 0x79aa, 0xa286, 0x000d, 0x0120,
+	0x7aaa, 0x2001, 0x0002, 0x0038, 0x78ab, 0x0020, 0x7174, 0x79aa,
+	0x7aaa, 0x2001, 0x0004, 0x789b, 0x0060, 0x78aa, 0x785b, 0x0004,
+	0x781b, 0x0113, 0x080c, 0x3c6e, 0x707f, 0x000f, 0x70d0, 0xd0b4,
+	0x0168, 0xc0b4, 0x70d2, 0x00c6, 0x70b4, 0xa065, 0x6008, 0xa084,
+	0xfbef, 0x600a, 0x6018, 0x8001, 0x601a, 0x00ce, 0x0005, 0x7014,
+	0xa005, 0x1138, 0x70d0, 0xd0b4, 0x0128, 0x70b4, 0xac06, 0x1110,
+	0x0c29, 0x0005, 0x0016, 0x71a0, 0xa186, 0x0001, 0x0528, 0x00d6,
+	0x0026, 0x2100, 0x2011, 0x0001, 0xa212, 0x70b0, 0x2068, 0x6800,
+	0xac06, 0x0120, 0x8211, 0x01b0, 0x00c9, 0x0cc8, 0x00c6, 0x2100,
+	0x2011, 0x0001, 0xa212, 0x70b0, 0x2068, 0x6800, 0x2060, 0x6008,
+	0xa084, 0xfbef, 0x600a, 0x8211, 0x0110, 0x0041, 0x0cb0, 0x70a3,
+	0x0001, 0x00ce, 0x002e, 0x00de, 0x001e, 0x0005, 0xade8, 0x0005,
+	0x70a8, 0xad06, 0x1110, 0x70a4, 0x2068, 0x0005, 0x080c, 0x3c5b,
+	0x1904, 0x25c6, 0x7078, 0x2068, 0x7770, 0x080c, 0x3b95, 0x2c50,
+	0x080c, 0x3cf6, 0x789b, 0x0080, 0x6814, 0xa084, 0x001f, 0xc0bd,
+	0x78aa, 0x6e1c, 0x2041, 0x0001, 0x2001, 0x0004, 0x0804, 0x2850,
+	0x080c, 0x3c5b, 0x1904, 0x25c6, 0x789b, 0x0080, 0x705c, 0x2068,
+	0x6f14, 0x70d0, 0xd0b4, 0x0168, 0xc0b4, 0x70d2, 0x00c6, 0x70b4,
+	0xa065, 0x6008, 0xa084, 0xfbef, 0x600a, 0x6018, 0x8001, 0x601a,
+	0x00ce, 0x080c, 0x3b95, 0x2c50, 0x080c, 0x3cf6, 0x6824, 0xa005,
+	0x0130, 0xa082, 0x0006, 0x0208, 0x0010, 0x6827, 0x0005, 0x6814,
+	0xa084, 0x001f, 0xc0bd, 0x78aa, 0x2031, 0x0020, 0x2041, 0x0001,
+	0x2001, 0x0003, 0x0804, 0x2850, 0xc28d, 0x72d2, 0x72bc, 0xa200,
+	0xa015, 0x7150, 0x8108, 0xa12a, 0x0208, 0x71bc, 0x2164, 0x6504,
+	0x85ff, 0x1170, 0x7152, 0x8421, 0x1da8, 0x70d0, 0xd08c, 0x0128,
+	0x70cc, 0xa005, 0x1110, 0x70cf, 0x000a, 0x0005, 0x2200, 0x0c90,
+	0x70d0, 0xc08c, 0x70d2, 0x70cf, 0x0000, 0x6034, 0xa005, 0x1db0,
+	0x6708, 0xa784, 0x073f, 0x01d0, 0xd7d4, 0x1d80, 0xa784, 0x0021,
+	0x1d68, 0xa784, 0x0002, 0x0130, 0xa784, 0x0004, 0x0d38, 0xa7bc,
+	0xfffb, 0x670a, 0xa784, 0x0218, 0x1d08, 0xa784, 0x0100, 0x0130,
+	0x6018, 0xa005, 0x19d8, 0xa7bc, 0xfeff, 0x670a, 0x2568, 0x6823,
+	0x0000, 0x6e1c, 0xa684, 0x000e, 0x6318, 0x0128, 0x601c, 0xa302,
+	0x0220, 0x0118, 0x0858, 0x83ff, 0x1948, 0x2d58, 0x2c50, 0x7152,
+	0xd7bc, 0x1120, 0x7028, 0x6022, 0x603a, 0x0010, 0xc7bc, 0x670a,
+	0x68c0, 0xa065, 0xa04d, 0x6100, 0x2a60, 0x2041, 0x0001, 0x6b14,
+	0xa39c, 0x001f, 0xa39d, 0x00c0, 0xd1fc, 0x0110, 0xd684, 0x0110,
+	0xa39c, 0xffbf, 0xd6a4, 0x0110, 0xa39d, 0x0020, 0xa684, 0x000e,
+	0x1904, 0x2802, 0xc7a5, 0x670a, 0x2c00, 0x68c6, 0x77a0, 0xa786,
+	0x0001, 0x1178, 0x70d0, 0xd0b4, 0x1160, 0x7000, 0xa082, 0x0002,
+	0x1240, 0x7830, 0xd0bc, 0x1128, 0x789b, 0x0080, 0x7baa, 0x0804,
+	0x2849, 0x8739, 0x77a2, 0x2750, 0x77ac, 0xa7b0, 0x0005, 0x70a8,
+	0xa606, 0x1108, 0x76a4, 0x76ae, 0x2c3a, 0x8738, 0x2d3a, 0x8738,
+	0x283a, 0x8738, 0x233a, 0x8738, 0x253a, 0x7830, 0xd0bc, 0x0150,
+	0x2091, 0x8000, 0x2091, 0x303d, 0x70d0, 0xa084, 0x303d, 0x2091,
+	0x8000, 0x2090, 0xaad5, 0x0000, 0x0120, 0x8421, 0x2200, 0x1904,
+	0x2751, 0x0005, 0xd1dc, 0x0904, 0x37f1, 0x2029, 0x0020, 0xd69c,
+	0x1120, 0x8528, 0xd68c, 0x1108, 0x8528, 0x8840, 0x6f14, 0x610c,
+	0x8108, 0xa18c, 0x00ff, 0x70c8, 0xa160, 0x2c64, 0x8cff, 0x0188,
+	0x6014, 0xa706, 0x1dd0, 0x60b8, 0x8001, 0x60ba, 0x1d88, 0x2a60,
+	0x6008, 0xa085, 0x0100, 0x600a, 0x2200, 0x8421, 0x1904, 0x2751,
+	0x0005, 0x2a60, 0x610e, 0x69be, 0x2c00, 0x68c6, 0x8840, 0x6008,
+	0xc0d5, 0x600a, 0x77a0, 0xa786, 0x0001, 0x1904, 0x27d9, 0x70d0,
+	0xd0b4, 0x1904, 0x27d9, 0x7000, 0xa082, 0x0002, 0x1a04, 0x27d9,
+	0x7830, 0xd0bc, 0x1904, 0x27d9, 0x789b, 0x0080, 0x7baa, 0x7daa,
+	0x79aa, 0x2001, 0x0002, 0x0006, 0x6018, 0x8000, 0x601a, 0x0008,
+	0x0006, 0x2960, 0x6104, 0x2a60, 0x080c, 0x3d09, 0x1590, 0xa184,
+	0x0018, 0x0180, 0xa184, 0x0010, 0x0118, 0x080c, 0x399a, 0x1548,
+	0xa184, 0x0008, 0x0138, 0x69a0, 0xa184, 0x0600, 0x1118, 0x080c,
+	0x38b8, 0x00f8, 0x69a0, 0xa184, 0x1e00, 0x0528, 0xa184, 0x0800,
+	0x0178, 0x00c6, 0x2960, 0x6000, 0xa085, 0x2000, 0x6002, 0x6104,
+	0xa18d, 0x0010, 0x6106, 0x00ce, 0x080c, 0x399a, 0x1150, 0x69a0,
+	0xa184, 0x0200, 0x0118, 0x080c, 0x38fd, 0x0018, 0xa184, 0x0400,
+	0x19f0, 0x69a0, 0xa184, 0x1000, 0x0130, 0x6914, 0xa18c, 0xff00,
+	0x810f, 0x080c, 0x23c5, 0x002e, 0xa68c, 0x00e0, 0xa684, 0x0060,
+	0x0128, 0xa086, 0x0060, 0x1110, 0xa18d, 0x4000, 0xa18d, 0x0104,
+	0x69b6, 0x789b, 0x0060, 0x2800, 0x78aa, 0x6818, 0xc0fd, 0x681a,
+	0xd6bc, 0x0168, 0xc0fc, 0x7083, 0x0000, 0xa08a, 0x000d, 0x0328,
+	0xa08a, 0x000c, 0x7182, 0x2001, 0x000c, 0x800c, 0x7186, 0x78aa,
+	0x3518, 0x3340, 0x3428, 0x8000, 0x80ac, 0xaf80, 0x002b, 0x20a0,
+	0x789b, 0x0000, 0xad80, 0x000b, 0x2098, 0x53a6, 0x23a8, 0x2898,
+	0x25a0, 0xa286, 0x0020, 0x1508, 0x70d0, 0xc0b5, 0x70d2, 0x2c00,
+	0x70b6, 0x2d00, 0x70ba, 0x6814, 0xc0fc, 0x8007, 0x7882, 0xa286,
+	0x0002, 0x0904, 0x2921, 0x70a0, 0x8000, 0x70a2, 0x74b0, 0xa498,
+	0x0005, 0x70a8, 0xa306, 0x1108, 0x73a4, 0x73b2, 0xa286, 0x0010,
+	0x0904, 0x25c6, 0x00de, 0x00ce, 0x0005, 0x7000, 0xa005, 0x19e0,
+	0xa286, 0x0002, 0x1904, 0x2938, 0x080c, 0x3c5b, 0x19a8, 0x6814,
+	0xc0fc, 0x8007, 0x7882, 0x2091, 0x8000, 0x781b, 0x0068, 0x68b4,
+	0x785a, 0x6894, 0x78d6, 0x78de, 0x6898, 0x78d2, 0x78da, 0x2091,
+	0x8001, 0x7808, 0xc08d, 0x780a, 0x0126, 0x00d6, 0x00c6, 0x70d0,
+	0xa084, 0x2e00, 0x2090, 0x00ce, 0x00de, 0x012e, 0x2900, 0x7056,
+	0x68bc, 0x703e, 0x7003, 0x0002, 0x2d00, 0x704a, 0xad80, 0x0009,
+	0x7042, 0x7830, 0xd0bc, 0x0140, 0x2091, 0x303d, 0x70d0, 0xa084,
+	0x303d, 0x2091, 0x8000, 0x2090, 0x70a0, 0xa005, 0x1108, 0x0005,
+	0x8421, 0x0de8, 0x724c, 0x70bc, 0xa200, 0xa015, 0x0804, 0x2751,
+	0xa286, 0x0010, 0x1560, 0x080c, 0x3c5b, 0x1904, 0x28cc, 0x6814,
+	0xc0fc, 0x8007, 0x7882, 0x781b, 0x0068, 0x68b4, 0x785a, 0x6894,
+	0x78d6, 0x78de, 0x6898, 0x78d2, 0x78da, 0x7808, 0xc08d, 0x780a,
+	0x70a0, 0x8000, 0x70a2, 0x74b0, 0xa490, 0x0005, 0x70a8, 0xa206,
+	0x1108, 0x72a4, 0x72b2, 0x2900, 0x7056, 0x68bc, 0x703e, 0x7003,
+	0x0002, 0x2d00, 0x704a, 0xad80, 0x0009, 0x7042, 0x0005, 0x6bb4,
+	0xa39d, 0x2000, 0x7b5a, 0x6814, 0xc0fc, 0x8007, 0x7882, 0x6b94,
+	0x7bd6, 0x7bde, 0x6e98, 0x7ed2, 0x7eda, 0x781b, 0x0068, 0x2900,
+	0x7056, 0x7202, 0x7808, 0xc08d, 0x780a, 0x2300, 0xa605, 0x0170,
+	0x70d0, 0xa084, 0x2e00, 0xa086, 0x2600, 0x1118, 0x2009, 0x0000,
+	0x0010, 0x2009, 0x0001, 0xa284, 0x000f, 0x0033, 0xad80, 0x0009,
+	0x7042, 0x2d00, 0x704a, 0x0005, 0x299c, 0x4208, 0x4208, 0x41f6,
+	0x4208, 0x299c, 0x299c, 0x299c, 0x080c, 0x2575, 0x7808, 0xa084,
+	0xfffd, 0x780a, 0x00f6, 0x2079, 0x4700, 0x78ac, 0x00fe, 0xd084,
+	0x01c0, 0x7160, 0xa186, 0x0001, 0x0904, 0x2a61, 0xa186, 0x0007,
+	0x0170, 0xa186, 0x0005, 0x1158, 0x7078, 0x2068, 0x681b, 0x0004,
 	0x6817, 0x0000, 0x6820, 0xa084, 0x00ff, 0xc09d, 0x6822, 0x7063,
-	0x0000, 0x70a3, 0x0000, 0x70a4, 0x70ae, 0x70b2, 0x080c, 0x2682,
-	0x0156, 0x2011, 0x0004, 0x7160, 0xa186, 0x0001, 0x0160, 0xa186,
-	0x0007, 0x1118, 0x701f, 0x0005, 0x0030, 0x701f, 0x0001, 0x70d0,
-	0xc0c5, 0x70d2, 0x0000, 0x2001, 0x460a, 0x2004, 0xa084, 0x00ff,
-	0xa086, 0x0018, 0x0130, 0x7018, 0x7016, 0xa005, 0x1110, 0x70a3,
-	0x0001, 0x0066, 0x080c, 0x3f26, 0x20a9, 0x0010, 0x2039, 0x0000,
-	0x080c, 0x3a66, 0xa7b8, 0x0100, 0x1f04, 0x29c0, 0x006e, 0x7000,
-	0x0002, 0x29fd, 0x29db, 0x29db, 0x29d3, 0x29fd, 0x29fd, 0x29fd,
-	0x29d1, 0x080c, 0x254c, 0x705c, 0xa005, 0x0538, 0xad06, 0x1118,
-	0x6800, 0x705e, 0x0080, 0x6820, 0xd084, 0x1148, 0x6f14, 0x080c,
-	0x3b6f, 0x6008, 0xc0d4, 0x600a, 0x080c, 0x37a4, 0x0020, 0x7058,
-	0x2060, 0x6800, 0x6002, 0xa684, 0x5f00, 0x681e, 0x6818, 0xd0fc,
-	0x0108, 0x6a1a, 0x6817, 0x0000, 0x682b, 0x0000, 0x6820, 0xa084,
-	0x00ff, 0xc09d, 0x6822, 0x080c, 0x1da2, 0x2011, 0x0004, 0x74c8,
-	0xa4a0, 0x0100, 0x04b1, 0xaea0, 0x0017, 0x0499, 0x20a9, 0x0101,
-	0x74c8, 0x0479, 0x8420, 0x1f04, 0x2a09, 0x70c0, 0x2060, 0x2021,
-	0x0002, 0x20a9, 0x0100, 0x6110, 0x81ff, 0x0198, 0x6018, 0x0016,
-	0x0006, 0x2011, 0x4602, 0x220c, 0xa102, 0x2012, 0x000e, 0x001e,
-	0xa102, 0x0338, 0x6012, 0x1128, 0x2011, 0x4604, 0x2204, 0xc0a5,
-	0x2012, 0x601b, 0x0000, 0xace0, 0x0010, 0x1f04, 0x2a13, 0x8421,
-	0x1d00, 0x015e, 0x7063, 0x0000, 0x7003, 0x0000, 0x704b, 0x0000,
-	0x0005, 0x0046, 0x2404, 0xa005, 0x01a8, 0x2068, 0x6800, 0x0006,
-	0x6a1a, 0x6817, 0x0000, 0x682b, 0x0000, 0x68b4, 0xa084, 0x5f00,
-	0x681e, 0x6820, 0xa084, 0x00ff, 0xc09d, 0x6822, 0x080c, 0x1da2,
-	0x000e, 0x0c48, 0x004e, 0x2023, 0x0000, 0x0005, 0xa282, 0x0003,
-	0x0310, 0x080c, 0x254c, 0x2300, 0x0002, 0x2a60, 0x2add, 0x2af7,
-	0xa282, 0x0002, 0x0110, 0x080c, 0x254c, 0x7060, 0x7063, 0x0000,
-	0x707f, 0x0000, 0x0022, 0x77d0, 0xc7c5, 0x77d2, 0x0002, 0x2a77,
-	0x2a77, 0x2a79, 0x2ab1, 0x37d8, 0x2a77, 0x2ab1, 0x2a77, 0x080c,
-	0x254c, 0x7770, 0x080c, 0x3a66, 0x7770, 0xa7bc, 0x8f00, 0x080c,
-	0x3b6f, 0x6018, 0xa005, 0x0528, 0xd7fc, 0x1118, 0x2021, 0x8cc0,
-	0x0010, 0x2021, 0x8dd0, 0x2009, 0x0005, 0x2011, 0x0010, 0x080c,
-	0x2b11, 0x01b8, 0x0156, 0x20a9, 0x0101, 0xd7fc, 0x1118, 0x2021,
-	0x8bc0, 0x0010, 0x2021, 0x8cd0, 0x0046, 0x2009, 0x0005, 0x2011,
-	0x0010, 0x080c, 0x2b11, 0x004e, 0x0118, 0x8420, 0x1f04, 0x2a9c,
-	0x015e, 0x8738, 0xa784, 0x001f, 0x1990, 0x0804, 0x25a0, 0x0804,
-	0x25a0, 0x7770, 0x080c, 0x3b6f, 0x6018, 0xa005, 0x0520, 0xd7fc,
-	0x1118, 0x2021, 0x8cc0, 0x0010, 0x2021, 0x8dd0, 0x2009, 0x0005,
-	0x2011, 0x0020, 0x080c, 0x2b11, 0x01b0, 0x0156, 0x20a9, 0x0101,
-	0xd7fc, 0x1118, 0x2021, 0x8bc0, 0x0010, 0x2021, 0x8cd0, 0x0046,
-	0x2009, 0x0005, 0x2011, 0x0020, 0x04e1, 0x004e, 0x0118, 0x8420,
-	0x1f04, 0x2acf, 0x015e, 0x0804, 0x25a0, 0x2200, 0x0002, 0x2ae2,
-	0x2ae4, 0x2ae4, 0x080c, 0x254c, 0x2009, 0x0012, 0x7060, 0xa086,
-	0x0002, 0x0110, 0x2009, 0x000e, 0x6818, 0xd0fc, 0x0108, 0x691a,
-	0x7063, 0x0000, 0x70d0, 0xc0c5, 0x70d2, 0x0804, 0x3be5, 0x2200,
-	0x0002, 0x2afe, 0x2ae4, 0x2afc, 0x080c, 0x254c, 0x080c, 0x3f26,
-	0x7000, 0xa086, 0x0002, 0x1904, 0x375d, 0x080c, 0x37be, 0x6008,
-	0xa084, 0xfbef, 0x600a, 0x080c, 0x374f, 0x0904, 0x375d, 0x0804,
-	0x25a0, 0x2404, 0xa005, 0x0590, 0x2068, 0x2d04, 0x0006, 0x6814,
-	0xa706, 0x0118, 0x2d20, 0x000e, 0x0ca8, 0x000e, 0x2022, 0x691a,
+	0x0000, 0x70a3, 0x0000, 0x70a4, 0x70ae, 0x70b2, 0x080c, 0x26ae,
+	0x0156, 0x2011, 0x0004, 0x7160, 0xa186, 0x0001, 0x0158, 0xa186,
+	0x0007, 0x1118, 0x701f, 0x0005, 0x0010, 0x701f, 0x0001, 0x70d0,
+	0xc0c5, 0x70d2, 0x2001, 0x470a, 0x2004, 0xa084, 0x00ff, 0xa086,
+	0x0018, 0x0130, 0x7018, 0x7016, 0xa005, 0x1110, 0x70a3, 0x0001,
+	0x0066, 0x080c, 0x3f4e, 0x20a9, 0x0010, 0x2039, 0x0000, 0x080c,
+	0x3a8b, 0xa7b8, 0x0100, 0x1f04, 0x29ef, 0x006e, 0x7000, 0x0002,
+	0x2a2c, 0x2a0a, 0x2a0a, 0x2a02, 0x2a2c, 0x2a2c, 0x2a2c, 0x2a00,
+	0x080c, 0x2575, 0x705c, 0xa005, 0x0538, 0xad06, 0x1118, 0x6800,
+	0x705e, 0x0080, 0x6820, 0xd084, 0x1148, 0x6f14, 0x080c, 0x3b95,
+	0x6008, 0xc0d4, 0x600a, 0x080c, 0x37c7, 0x0020, 0x7058, 0x2060,
+	0x6800, 0x6002, 0xa684, 0x5f00, 0x681e, 0x6818, 0xd0fc, 0x0108,
+	0x6a1a, 0x6817, 0x0000, 0x682b, 0x0000, 0x6820, 0xa084, 0x00ff,
+	0xc09d, 0x6822, 0x080c, 0x1dbf, 0x2011, 0x0004, 0x74c8, 0xa4a0,
+	0x0100, 0x04b1, 0xaea0, 0x0017, 0x0499, 0x20a9, 0x0101, 0x74c8,
+	0x0479, 0x8420, 0x1f04, 0x2a38, 0x70c0, 0x2060, 0x2021, 0x0002,
+	0x20a9, 0x0100, 0x6110, 0x81ff, 0x0198, 0x6018, 0x0016, 0x0006,
+	0x2011, 0x4702, 0x220c, 0xa102, 0x2012, 0x000e, 0x001e, 0xa102,
+	0x0338, 0x6012, 0x1128, 0x2011, 0x4704, 0x2204, 0xc0a5, 0x2012,
+	0x601b, 0x0000, 0xace0, 0x0010, 0x1f04, 0x2a42, 0x8421, 0x1d00,
+	0x015e, 0x7063, 0x0000, 0x7003, 0x0000, 0x704b, 0x0000, 0x0005,
+	0x0046, 0x2404, 0xa005, 0x01a8, 0x2068, 0x6800, 0x0006, 0x6a1a,
 	0x6817, 0x0000, 0x682b, 0x0000, 0x68b4, 0xa084, 0x5f00, 0x681e,
-	0x6820, 0xa084, 0x00ff, 0xa205, 0x6822, 0x080c, 0x1da2, 0x2021,
-	0x4602, 0x241c, 0x8319, 0x2322, 0x6010, 0x8001, 0x6012, 0x1128,
-	0x2021, 0x4604, 0x2404, 0xc0a5, 0x2022, 0x6008, 0xa084, 0xf9ef,
-	0x600a, 0x080c, 0x269e, 0x080c, 0x37be, 0x0005, 0xa085, 0x0001,
-	0x0ce0, 0x2300, 0x0002, 0x2b50, 0x2b4e, 0x2bcb, 0x080c, 0x254c,
-	0x78e4, 0xa005, 0x17b0, 0x3208, 0xa18c, 0x0800, 0x0118, 0x0104,
-	0x259d, 0x0010, 0x0304, 0x259d, 0x2008, 0xa084, 0x0030, 0x1110,
-	0x0804, 0x322a, 0x78ec, 0xa084, 0x0003, 0x0dd0, 0x7884, 0xd0fc,
-	0x1118, 0xa184, 0x0007, 0x0090, 0xa184, 0x0007, 0xa086, 0x0004,
-	0x1118, 0x2001, 0x0000, 0x0050, 0xa184, 0x0007, 0xa086, 0x0005,
-	0x0118, 0xa184, 0x0007, 0x0010, 0x2001, 0x0001, 0x0002, 0x2bae,
-	0x2bb7, 0x2ba4, 0x2b87, 0x3c29, 0x3c29, 0x2b87, 0x2bc1, 0x080c,
-	0x254c, 0x7000, 0xa086, 0x0004, 0x1190, 0x7060, 0xa086, 0x0002,
-	0x1130, 0x2011, 0x0002, 0x2019, 0x0000, 0x0804, 0x2a56, 0x7060,
-	0xa086, 0x0006, 0x0db0, 0x7060, 0xa086, 0x0004, 0x0d90, 0x79e4,
-	0x2001, 0x0003, 0x0804, 0x2f18, 0x6818, 0xd0fc, 0x0110, 0x681b,
-	0x001d, 0x080c, 0x3a3c, 0x781b, 0x006e, 0x0005, 0x6818, 0xd0fc,
-	0x0110, 0x681b, 0x001d, 0x080c, 0x3a3c, 0x0804, 0x3c07, 0x6818,
-	0xd0fc, 0x0110, 0x681b, 0x001d, 0x080c, 0x3a3c, 0x781b, 0x00fa,
-	0x0005, 0x6818, 0xd0fc, 0x0110, 0x681b, 0x001d, 0x080c, 0x3a3c,
-	0x781b, 0x00cb, 0x0005, 0xa584, 0x000f, 0x11c0, 0x7000, 0x0002,
-	0x25a0, 0x2bd8, 0x2bda, 0x375d, 0x375d, 0x375d, 0x2bd8, 0x2bd8,
-	0x080c, 0x254c, 0x080c, 0x37be, 0x6008, 0xa084, 0xfbef, 0x600a,
-	0x080c, 0x374f, 0x0904, 0x375d, 0x0804, 0x25a0, 0x78e4, 0xa005,
-	0x1b04, 0x2b89, 0x3208, 0xa18c, 0x0800, 0x0118, 0x0104, 0x2b89,
-	0x0010, 0x0304, 0x2b89, 0x2008, 0xa084, 0x0030, 0x1118, 0x781b,
-	0x0068, 0x0005, 0x78ec, 0xa084, 0x0003, 0x0dc8, 0x7884, 0xd0fc,
-	0x1118, 0xa184, 0x0007, 0x0090, 0xa184, 0x0007, 0xa086, 0x0004,
-	0x1118, 0x2001, 0x0000, 0x0050, 0xa184, 0x0007, 0xa086, 0x0005,
-	0x0118, 0xa184, 0x0007, 0x0010, 0x2001, 0x0001, 0x0002, 0x2c26,
-	0x2c2a, 0x2c21, 0x2c1f, 0x3c29, 0x3c29, 0x2c1f, 0x3c23, 0x080c,
-	0x254c, 0x080c, 0x3a42, 0x781b, 0x006e, 0x0005, 0x080c, 0x3a42,
-	0x0804, 0x3c07, 0x080c, 0x3a42, 0x781b, 0x00fa, 0x0005, 0x080c,
-	0x3a42, 0x781b, 0x00cb, 0x0005, 0x2300, 0x0002, 0x2c3b, 0x2c39,
-	0x2c3d, 0x080c, 0x254c, 0x0804, 0x33e2, 0x681b, 0x0016, 0x78a3,
-	0x0000, 0x79e4, 0xa184, 0x0030, 0x0904, 0x33e2, 0x78ec, 0xa084,
-	0x0003, 0x0904, 0x33e2, 0xa184, 0x0100, 0x0d98, 0x7884, 0xd0fc,
+	0x6820, 0xa084, 0x00ff, 0xc09d, 0x6822, 0x080c, 0x1dbf, 0x000e,
+	0x0c48, 0x004e, 0x2023, 0x0000, 0x0005, 0xa282, 0x0003, 0x0310,
+	0x080c, 0x2575, 0x2300, 0x0002, 0x2a8f, 0x2b0c, 0x2b1a, 0xa282,
+	0x0002, 0x0110, 0x080c, 0x2575, 0x7060, 0x7063, 0x0000, 0x707f,
+	0x0000, 0x0022, 0x77d0, 0xc7c5, 0x77d2, 0x0002, 0x2aa6, 0x2aa6,
+	0x2aa8, 0x2ae0, 0x37fb, 0x2aa6, 0x2ae0, 0x2aa6, 0x080c, 0x2575,
+	0x7770, 0x080c, 0x3a8b, 0x7770, 0xa7bc, 0x8f00, 0x080c, 0x3b95,
+	0x6018, 0xa005, 0x0528, 0xd7fc, 0x1118, 0x2021, 0x8dc0, 0x0010,
+	0x2021, 0x8ed0, 0x2009, 0x0005, 0x2011, 0x0010, 0x080c, 0x2b34,
+	0x01b8, 0x0156, 0x20a9, 0x0101, 0xd7fc, 0x1118, 0x2021, 0x8cc0,
+	0x0010, 0x2021, 0x8dd0, 0x0046, 0x2009, 0x0005, 0x2011, 0x0010,
+	0x080c, 0x2b34, 0x004e, 0x0118, 0x8420, 0x1f04, 0x2acb, 0x015e,
+	0x8738, 0xa784, 0x001f, 0x1990, 0x0804, 0x25c9, 0x0804, 0x25c9,
+	0x7770, 0x080c, 0x3b95, 0x6018, 0xa005, 0x0520, 0xd7fc, 0x1118,
+	0x2021, 0x8dc0, 0x0010, 0x2021, 0x8ed0, 0x2009, 0x0005, 0x2011,
+	0x0020, 0x080c, 0x2b34, 0x01b0, 0x0156, 0x20a9, 0x0101, 0xd7fc,
+	0x1118, 0x2021, 0x8cc0, 0x0010, 0x2021, 0x8dd0, 0x0046, 0x2009,
+	0x0005, 0x2011, 0x0020, 0x0481, 0x004e, 0x0118, 0x8420, 0x1f04,
+	0x2afe, 0x015e, 0x0804, 0x25c9, 0x2200, 0x0002, 0x2b11, 0x2b13,
+	0x2b13, 0x080c, 0x2575, 0x7063, 0x0000, 0x70d0, 0xc0c5, 0x70d2,
+	0x0804, 0x25c9, 0x2200, 0x0002, 0x2b21, 0x2b13, 0x2b1f, 0x080c,
+	0x2575, 0x080c, 0x3f4e, 0x7000, 0xa086, 0x0002, 0x1904, 0x3780,
+	0x080c, 0x37e1, 0x6008, 0xa084, 0xfbef, 0x600a, 0x080c, 0x3772,
+	0x0904, 0x3780, 0x0804, 0x25c9, 0x2404, 0xa005, 0x0590, 0x2068,
+	0x2d04, 0x0006, 0x6814, 0xa706, 0x0118, 0x2d20, 0x000e, 0x0ca8,
+	0x000e, 0x2022, 0x691a, 0x6817, 0x0000, 0x682b, 0x0000, 0x68b4,
+	0xa084, 0x5f00, 0x681e, 0x6820, 0xa084, 0x00ff, 0xa205, 0x6822,
+	0x080c, 0x1dbf, 0x2021, 0x4702, 0x241c, 0x8319, 0x2322, 0x6010,
+	0x8001, 0x6012, 0x1128, 0x2021, 0x4704, 0x2404, 0xc0a5, 0x2022,
+	0x6008, 0xa084, 0xf9ef, 0x600a, 0x080c, 0x26ca, 0x080c, 0x37e1,
+	0x0005, 0xa085, 0x0001, 0x0ce0, 0x2300, 0x0002, 0x2b73, 0x2b71,
+	0x2bee, 0x080c, 0x2575, 0x78e4, 0xa005, 0x17b0, 0x3208, 0xa18c,
+	0x0800, 0x0118, 0x0104, 0x25c6, 0x0010, 0x0304, 0x25c6, 0x2008,
+	0xa084, 0x0030, 0x1110, 0x0804, 0x324d, 0x78ec, 0xa084, 0x0003,
+	0x0dd0, 0x7884, 0xd0fc, 0x1118, 0xa184, 0x0007, 0x0090, 0xa184,
+	0x0007, 0xa086, 0x0004, 0x1118, 0x2001, 0x0000, 0x0050, 0xa184,
+	0x0007, 0xa086, 0x0005, 0x0118, 0xa184, 0x0007, 0x0010, 0x2001,
+	0x0001, 0x0002, 0x2bd1, 0x2bda, 0x2bc7, 0x2baa, 0x3c4f, 0x3c4f,
+	0x2baa, 0x2be4, 0x080c, 0x2575, 0x7000, 0xa086, 0x0004, 0x1190,
+	0x7060, 0xa086, 0x0002, 0x1130, 0x2011, 0x0002, 0x2019, 0x0000,
+	0x0804, 0x2a85, 0x7060, 0xa086, 0x0006, 0x0db0, 0x7060, 0xa086,
+	0x0004, 0x0d90, 0x79e4, 0x2001, 0x0003, 0x0804, 0x2f3b, 0x6818,
+	0xd0fc, 0x0110, 0x681b, 0x001d, 0x080c, 0x3a61, 0x781b, 0x006e,
+	0x0005, 0x6818, 0xd0fc, 0x0110, 0x681b, 0x001d, 0x080c, 0x3a61,
+	0x0804, 0x3c2d, 0x6818, 0xd0fc, 0x0110, 0x681b, 0x001d, 0x080c,
+	0x3a61, 0x781b, 0x00fa, 0x0005, 0x6818, 0xd0fc, 0x0110, 0x681b,
+	0x001d, 0x080c, 0x3a61, 0x781b, 0x00cb, 0x0005, 0xa584, 0x000f,
+	0x11c0, 0x7000, 0x0002, 0x25c9, 0x2bfb, 0x2bfd, 0x3780, 0x3780,
+	0x3780, 0x2bfb, 0x2bfb, 0x080c, 0x2575, 0x080c, 0x37e1, 0x6008,
+	0xa084, 0xfbef, 0x600a, 0x080c, 0x3772, 0x0904, 0x3780, 0x0804,
+	0x25c9, 0x78e4, 0xa005, 0x1b04, 0x2bac, 0x3208, 0xa18c, 0x0800,
+	0x0118, 0x0104, 0x2bac, 0x0010, 0x0304, 0x2bac, 0x2008, 0xa084,
+	0x0030, 0x1118, 0x781b, 0x0068, 0x0005, 0x78ec, 0xa084, 0x0003,
+	0x0dc8, 0x7884, 0xd0fc, 0x1118, 0xa184, 0x0007, 0x0090, 0xa184,
+	0x0007, 0xa086, 0x0004, 0x1118, 0x2001, 0x0000, 0x0050, 0xa184,
+	0x0007, 0xa086, 0x0005, 0x0118, 0xa184, 0x0007, 0x0010, 0x2001,
+	0x0001, 0x0002, 0x2c49, 0x2c4d, 0x2c44, 0x2c42, 0x3c4f, 0x3c4f,
+	0x2c42, 0x3c49, 0x080c, 0x2575, 0x080c, 0x3a67, 0x781b, 0x006e,
+	0x0005, 0x080c, 0x3a67, 0x0804, 0x3c2d, 0x080c, 0x3a67, 0x781b,
+	0x00fa, 0x0005, 0x080c, 0x3a67, 0x781b, 0x00cb, 0x0005, 0x2300,
+	0x0002, 0x2c5e, 0x2c5c, 0x2c60, 0x080c, 0x2575, 0x0804, 0x3405,
+	0x681b, 0x0016, 0x78a3, 0x0000, 0x79e4, 0xa184, 0x0030, 0x0904,
+	0x3405, 0x78ec, 0xa084, 0x0003, 0x0904, 0x3405, 0xa184, 0x0100,
+	0x0d98, 0x7884, 0xd0fc, 0x1118, 0xa184, 0x0007, 0x0090, 0xa184,
+	0x0007, 0xa086, 0x0004, 0x1118, 0x2001, 0x0000, 0x0050, 0xa184,
+	0x0007, 0xa086, 0x0005, 0x0118, 0xa184, 0x0007, 0x0010, 0x2001,
+	0x0001, 0x0002, 0x2c92, 0x2c4d, 0x2bc7, 0x3c0b, 0x3c4f, 0x3c4f,
+	0x3c0b, 0x3c49, 0x080c, 0x3c17, 0x0005, 0xa282, 0x0005, 0x0310,
+	0x080c, 0x2575, 0x7898, 0x2040, 0x2300, 0x0002, 0x2ca1, 0x2ecb,
+	0x2ed5, 0x2200, 0x0002, 0x2cbd, 0x2caa, 0x2cbd, 0x2ca8, 0x2ead,
+	0x080c, 0x2575, 0x789b, 0x0018, 0x78a8, 0x2010, 0xa084, 0x00ff,
+	0xa082, 0x0020, 0x0a04, 0x3a30, 0xa08a, 0x0004, 0x1a04, 0x3a30,
+	0x0002, 0x3a30, 0x3a30, 0x3a30, 0x39e4, 0x789b, 0x0018, 0x79a8,
+	0xa184, 0x0080, 0x0148, 0x0804, 0x3a30, 0x7000, 0xa005, 0x1dd8,
+	0x2011, 0x0004, 0x0804, 0x35b7, 0xa184, 0x00ff, 0xa08a, 0x0010,
+	0x1a04, 0x3a30, 0x0002, 0x2ce5, 0x2ce3, 0x2cf7, 0x2cfb, 0x2da9,
+	0x3a30, 0x3a30, 0x2dab, 0x3a30, 0x3a30, 0x2ea9, 0x2ea9, 0x3a30,
+	0x3a30, 0x3a30, 0x2eab, 0x080c, 0x2575, 0xd6e4, 0x0140, 0x2001,
+	0x0300, 0x8000, 0x8000, 0x783a, 0x781b, 0x00c7, 0x0005, 0x6818,
+	0xd0fc, 0x0118, 0x681b, 0x001d, 0x0c90, 0x0804, 0x3c0b, 0x681b,
+	0x001d, 0x0804, 0x3a5b, 0x6920, 0x6922, 0xa684, 0x1800, 0x1904,
+	0x2d4c, 0x6820, 0xd084, 0x1904, 0x2d54, 0x6818, 0xa086, 0x0008,
+	0x1110, 0x681b, 0x0000, 0xd6d4, 0x0568, 0xd6bc, 0x0558, 0x7083,
+	0x0000, 0x6818, 0xa084, 0x003f, 0xa08a, 0x000d, 0x0718, 0xa08a,
+	0x000c, 0x7182, 0x2001, 0x000c, 0x800c, 0x7186, 0x789b, 0x0061,
+	0x78aa, 0x0156, 0x0136, 0x0146, 0x0016, 0x3208, 0xa18c, 0x0600,
+	0x0118, 0x20a1, 0x022b, 0x0010, 0x20a1, 0x012b, 0x001e, 0x789b,
+	0x0000, 0x8000, 0x80ac, 0xad80, 0x000b, 0x2098, 0x53a6, 0x014e,
+	0x013e, 0x015e, 0x6038, 0xa005, 0x1150, 0x681c, 0xa084, 0x000e,
+	0x0904, 0x3a5b, 0x080c, 0x3a6d, 0x782b, 0x3008, 0x0010, 0x8001,
+	0x603a, 0x781b, 0x0071, 0x0005, 0xd6e4, 0x0130, 0x781b, 0x0083,
+	0x0005, 0x781b, 0x0083, 0x0005, 0xa684, 0x0060, 0x0dd0, 0xd6dc,
+	0x0dc0, 0xd6fc, 0x01a0, 0xc6fc, 0x7e5a, 0x6eb6, 0x7adc, 0x79d8,
+	0x78d0, 0x8007, 0xa084, 0x007f, 0xa108, 0xa291, 0x0000, 0x6b98,
+	0x2100, 0xa302, 0x68b2, 0x6b94, 0x2200, 0xa303, 0x68ae, 0xd6f4,
+	0x0118, 0xc6f4, 0x7e5a, 0x6eb6, 0x7000, 0xa086, 0x0003, 0x1148,
+	0x0006, 0x080c, 0x3f4e, 0x080c, 0x4208, 0x000e, 0x781b, 0x0080,
+	0x0005, 0xa006, 0x080c, 0x42e8, 0x6ab0, 0x69ac, 0x6c98, 0x6b94,
+	0x2200, 0xa105, 0x0120, 0x2200, 0xa422, 0x2100, 0xa31b, 0x6caa,
+	0x7cd2, 0x7cda, 0x6ba6, 0x7bd6, 0x7bde, 0x2300, 0xa405, 0x1130,
+	0xc6f5, 0x7e5a, 0x6eb6, 0x781b, 0x0080, 0x0005, 0x781b, 0x0080,
+	0x2200, 0xa115, 0x1118, 0x080c, 0x4208, 0x0005, 0x080c, 0x4235,
+	0x0005, 0x080c, 0x2575, 0x0804, 0x2e3f, 0x00c6, 0x7054, 0x2060,
+	0x6920, 0xa18c, 0xecff, 0x6922, 0x6000, 0xa084, 0xcfdf, 0x6002,
+	0x080c, 0x3917, 0xa006, 0x2040, 0x2038, 0x080c, 0x39bf, 0x0804,
+	0x2e33, 0x00c6, 0x7054, 0x2060, 0x2c48, 0x7aa8, 0xa294, 0x00ff,
+	0xa286, 0x0004, 0x11d8, 0x6920, 0xd1e4, 0x1170, 0x2039, 0x0000,
+	0x2041, 0x0000, 0x2031, 0x0000, 0xa006, 0x2010, 0x080c, 0x391a,
+	0x080c, 0x39bf, 0x0804, 0x2e33, 0xa18c, 0xecff, 0x6922, 0x6104,
+	0xa18c, 0xffdd, 0x6106, 0x6000, 0xc0ac, 0x6002, 0xa286, 0x0003,
+	0x01d0, 0x6104, 0xa184, 0x0010, 0x0548, 0x080c, 0x3b91, 0x080c,
+	0x399a, 0x88ff, 0x0518, 0x00ce, 0x789b, 0x0060, 0x2800, 0x78aa,
+	0x7e58, 0xc695, 0x7e5a, 0xd6d4, 0x1118, 0x781b, 0x006e, 0x0005,
+	0x781b, 0x0082, 0x0005, 0x6920, 0xd1cc, 0x0130, 0xa18c, 0xfdff,
+	0x6922, 0x6000, 0xc0ec, 0x6002, 0x2039, 0x0000, 0x2041, 0x0000,
+	0x2031, 0x0000, 0xa006, 0x2010, 0x080c, 0x39bf, 0xa286, 0x0001,
+	0x0158, 0x6104, 0xa184, 0x0008, 0x01b0, 0x080c, 0x3b91, 0x080c,
+	0x38b8, 0x88ff, 0x1980, 0x0078, 0x6920, 0xd1c4, 0x0130, 0xa18c,
+	0xfeff, 0x6922, 0x6000, 0xc0e4, 0x6002, 0x2031, 0x0000, 0xa006,
+	0x2010, 0x080c, 0x391a, 0x00ce, 0x7e58, 0xd6d4, 0x1118, 0x781b,
+	0x0071, 0x0005, 0x781b, 0x0083, 0x0005, 0x0804, 0x3a57, 0x2808,
+	0x789b, 0x0080, 0x2019, 0x0080, 0x78a8, 0xa094, 0x00ff, 0xa286,
+	0x0001, 0x11b8, 0x2300, 0xa102, 0xa086, 0x0001, 0x0904, 0x2dad,
+	0x7ca8, 0xa4a4, 0x00ff, 0xa480, 0x0002, 0xa300, 0x2018, 0xa102,
+	0x0a04, 0x2dc1, 0x0904, 0x2dc1, 0x24a8, 0x7aa8, 0x1f04, 0x2e5d,
+	0x0c18, 0xa284, 0x00f0, 0xa082, 0x0020, 0x06b8, 0x2200, 0xa082,
+	0x0021, 0x1698, 0x7aa8, 0x8318, 0x8318, 0x2100, 0xa302, 0x0aa0,
+	0xa286, 0x0023, 0x0950, 0x681c, 0xa084, 0xfff1, 0x681e, 0x7e58,
+	0xa684, 0xfff1, 0xc0a5, 0x2030, 0x7e5a, 0x6008, 0xc0a5, 0x600a,
+	0x78a0, 0xa005, 0x0904, 0x2e34, 0x20a8, 0x7998, 0x789b, 0x0060,
+	0x78aa, 0x2011, 0x0080, 0x799a, 0x78a8, 0x7998, 0x7a9a, 0x78aa,
+	0x7a98, 0x1f04, 0x2e8b, 0xc695, 0x7e5a, 0xd6d4, 0x1118, 0x781b,
+	0x006e, 0x0005, 0x781b, 0x0082, 0x0005, 0x8318, 0x2100, 0xa302,
+	0x0a04, 0x2e44, 0xa284, 0x0080, 0x1904, 0x3a5b, 0x78a0, 0xa005,
+	0x08c8, 0x0804, 0x3a5b, 0x0804, 0x3a30, 0x7054, 0xa04d, 0x789b,
+	0x0018, 0x78a8, 0xa084, 0x00ff, 0xa08e, 0x0001, 0x0110, 0x080c,
+	0x2575, 0x7aa8, 0xa294, 0x00ff, 0x784b, 0x0008, 0x78a8, 0xa084,
+	0x00ff, 0xa08a, 0x0005, 0x1a04, 0x3a30, 0x0002, 0x3a30, 0x382f,
+	0x3a30, 0x394a, 0x3d59, 0xa282, 0x0000, 0x1110, 0x080c, 0x2575,
+	0x080c, 0x3a61, 0x781b, 0x0082, 0x0005, 0xa282, 0x0003, 0x1110,
+	0x080c, 0x2575, 0xd4fc, 0x11d0, 0x7060, 0xa005, 0x0110, 0x080c,
+	0x2575, 0x6f14, 0x7772, 0xa7bc, 0x8f00, 0x080c, 0x3b95, 0x6008,
+	0xa085, 0x0021, 0x600a, 0x8738, 0xa784, 0x001f, 0x1db0, 0x080c,
+	0x3a64, 0x7063, 0x0002, 0x701f, 0x0009, 0x0010, 0x080c, 0x3a70,
+	0x781b, 0x0082, 0x0005, 0xa282, 0x0004, 0x0310, 0x080c, 0x2575,
+	0x2300, 0x0002, 0x2f05, 0x309b, 0x30d7, 0xa286, 0x0003, 0x0598,
+	0x7200, 0x7cd8, 0x7ddc, 0x7fd0, 0x71d0, 0xd1b4, 0x0528, 0xd1bc,
+	0x1518, 0x2001, 0x4701, 0x2004, 0xd0c4, 0x11f0, 0x7868, 0xa084,
+	0x00ff, 0x11d0, 0xa282, 0x0002, 0x12b8, 0x00d6, 0x783b, 0x8300,
+	0x781b, 0x0059, 0x70b8, 0xa06d, 0x68b4, 0x785a, 0x6894, 0x78d6,
+	0x78de, 0x6898, 0x78d2, 0x78da, 0xc1b4, 0x71d2, 0x7003, 0x0030,
+	0x00de, 0x2001, 0x0000, 0x0058, 0x783b, 0x1300, 0x781b, 0x0057,
+	0x2001, 0x0000, 0x0020, 0x7200, 0x7cd8, 0x7ddc, 0x7fd0, 0x7046,
+	0x68a0, 0xd0ec, 0x0118, 0x6008, 0xc08d, 0x600a, 0xa284, 0x000f,
+	0x0002, 0x307c, 0x2f56, 0x2f53, 0x31a7, 0x3232, 0x25c9, 0x2f51,
+	0x2f51, 0x080c, 0x2575, 0x6008, 0xc0d4, 0x600a, 0xd6e4, 0x0120,
+	0x7044, 0xa086, 0x0014, 0x11e8, 0x080c, 0x3f4e, 0x2009, 0x0000,
+	0x6818, 0xd0fc, 0x0108, 0x7044, 0xa086, 0x0014, 0x0168, 0x6818,
+	0xa086, 0x0008, 0x1904, 0x303e, 0x7858, 0xd09c, 0x0904, 0x303e,
+	0x6820, 0xd0ac, 0x0904, 0x303e, 0x681b, 0x0014, 0x2009, 0x0002,
+	0x04a8, 0x7868, 0xa08c, 0x00ff, 0x0588, 0xa186, 0x0008, 0x1158,
+	0x6008, 0xc0a4, 0x600a, 0x080c, 0x3772, 0x0540, 0x080c, 0x37e1,
+	0x080c, 0x3f4e, 0x0060, 0xa186, 0x0028, 0x1500, 0x6018, 0xa005,
+	0x0d78, 0x8001, 0x0d68, 0x8001, 0x0d58, 0x601e, 0x0c48, 0x6820,
+	0xd084, 0x0904, 0x25c9, 0xc084, 0x6822, 0x080c, 0x26bf, 0x7058,
+	0x00c6, 0x2060, 0x6800, 0x6002, 0x00ce, 0x6004, 0x6802, 0xa005,
+	0x2d00, 0x1108, 0x6002, 0x6006, 0x0804, 0x25c9, 0x0016, 0x81ff,
+	0x15f0, 0x7000, 0xa086, 0x0030, 0x05d0, 0x71d0, 0xd1bc, 0x15b8,
+	0xd1b4, 0x11e8, 0x705c, 0xa005, 0x1590, 0x70a0, 0xa086, 0x0001,
+	0x0570, 0x7003, 0x0000, 0x0046, 0x0056, 0x0076, 0x0066, 0x00c6,
+	0x00d6, 0x080c, 0x25f1, 0x00de, 0x00ce, 0x006e, 0x007e, 0x005e,
+	0x004e, 0x71d0, 0xd1b4, 0x11d8, 0x7003, 0x0040, 0x00c0, 0x080c,
+	0x3c5b, 0x11a8, 0x781b, 0x0068, 0x00d6, 0x70b8, 0xa06d, 0x68b4,
+	0x785a, 0x6894, 0x78d6, 0x78de, 0x6898, 0x78d2, 0x78da, 0xc1b4,
+	0x71d2, 0x7003, 0x0030, 0x7808, 0xc08d, 0x780a, 0x00de, 0x080c,
+	0x30ff, 0x001e, 0x81ff, 0x0904, 0x303e, 0xa684, 0xdf00, 0x681e,
+	0x682b, 0x0000, 0x6f14, 0xa186, 0x0002, 0x1904, 0x303f, 0x6818,
+	0xa086, 0x0014, 0x1130, 0x2008, 0xd6e4, 0x0118, 0x7868, 0xa08c,
+	0x00ff, 0x080c, 0x3a7a, 0x080c, 0x26ca, 0x6820, 0xd0dc, 0x1578,
+	0x8717, 0xa294, 0x000f, 0x8213, 0x8213, 0x8213, 0xb284, 0x0600,
+	0x0118, 0xa290, 0x4bc0, 0x0010, 0xa290, 0x4c40, 0xa290, 0x0000,
+	0x221c, 0xd3c4, 0x0170, 0x6820, 0xd0e4, 0x0128, 0xa084, 0xefff,
+	0x6822, 0xc3ac, 0x2312, 0x8210, 0x2204, 0xa085, 0x0038, 0x2012,
+	0x8211, 0xd3d4, 0x0138, 0x68a0, 0xd0c4, 0x1120, 0x080c, 0x3167,
+	0x0804, 0x25c9, 0x6008, 0xc08d, 0x600a, 0x0008, 0x692a, 0x6916,
+	0x6818, 0xd0fc, 0x0110, 0x7044, 0x681a, 0xa68c, 0xdf00, 0x691e,
+	0x6410, 0x84ff, 0x0168, 0x2009, 0x4702, 0x2104, 0x8001, 0x200a,
+	0x8421, 0x6412, 0x1128, 0x2021, 0x4704, 0x2404, 0xc0a5, 0x2022,
+	0x6018, 0xa005, 0x0118, 0x8001, 0x601a, 0x1118, 0x6008, 0xc0a4,
+	0x600a, 0x6820, 0xd084, 0x1130, 0x6800, 0xa005, 0x1108, 0x6002,
+	0x6006, 0x0020, 0x7058, 0x2060, 0x6800, 0x6002, 0x2061, 0x4700,
+	0x6887, 0x0103, 0x2d08, 0x206b, 0x0000, 0x6068, 0xa005, 0x616a,
+	0x0110, 0x2d02, 0x0008, 0x616e, 0x7200, 0xa286, 0x0030, 0x0158,
+	0xa286, 0x0040, 0x1904, 0x25c9, 0x7003, 0x0002, 0x7048, 0x2068,
+	0x68c4, 0x2060, 0x0005, 0x7003, 0x0002, 0x70b8, 0xa06d, 0x68bc,
+	0x703e, 0x70b4, 0xa065, 0x68c0, 0x7056, 0x2d00, 0x704a, 0xad80,
+	0x0009, 0x7042, 0x0005, 0xa282, 0x0004, 0x0210, 0x080c, 0x2575,
+	0x2200, 0x0002, 0x30a6, 0x30b5, 0x30c1, 0x30b5, 0xa586, 0x1300,
+	0x0160, 0xa586, 0x8300, 0x1d90, 0x7003, 0x0000, 0x6018, 0x8001,
+	0x601a, 0x6008, 0xa084, 0xfbef, 0x600a, 0x7000, 0xa086, 0x0005,
+	0x0128, 0x080c, 0x3a61, 0x781b, 0x0082, 0x0005, 0x781b, 0x0083,
+	0x0005, 0x7890, 0x8007, 0x8001, 0xa084, 0x0007, 0xa080, 0x0018,
+	0x789a, 0x79a8, 0xa18c, 0x00ff, 0xa186, 0x0003, 0x0128, 0xa186,
+	0x0000, 0x0110, 0x0804, 0x3a30, 0x781b, 0x0083, 0x0005, 0x6820,
+	0xc095, 0x6822, 0x82ff, 0x1118, 0x080c, 0x3a61, 0x0030, 0x8211,
+	0x0110, 0x080c, 0x2575, 0x080c, 0x3a70, 0x781b, 0x0082, 0x0005,
+	0x080c, 0x3c6e, 0x7830, 0xa084, 0x00c0, 0x1170, 0x0016, 0x3208,
+	0xa18c, 0x0800, 0x001e, 0x0118, 0x0104, 0x30fc, 0x0010, 0x0304,
+	0x30fc, 0x791a, 0xa006, 0x0005, 0xa085, 0x0001, 0x0005, 0xa684,
+	0x0060, 0x1130, 0x682f, 0x0000, 0x6833, 0x0000, 0x0804, 0x3166,
+	0xd6dc, 0x1198, 0x68b4, 0xd0dc, 0x1180, 0x6998, 0x6a94, 0x692e,
+	0x6a32, 0x7044, 0xa005, 0x1130, 0x2200, 0xa105, 0x0904, 0x3f4e,
+	0x7047, 0x0015, 0x0804, 0x3f4e, 0x0005, 0xd6ac, 0x01f0, 0xd6f4,
+	0x0130, 0x682f, 0x0000, 0x6833, 0x0000, 0x0804, 0x3f4e, 0x68b4,
+	0xa084, 0x4000, 0xa635, 0xd6f4, 0x1da0, 0x7044, 0xa005, 0x1110,
+	0x7047, 0x0015, 0xd6dc, 0x1128, 0x68b4, 0xd0dc, 0x0110, 0x6ca8,
+	0x6da4, 0x6c2e, 0x6d32, 0x0804, 0x3f4e, 0xd6f4, 0x0130, 0x682f,
+	0x0000, 0x6833, 0x0000, 0x0804, 0x3f4e, 0x68b4, 0xa084, 0x4800,
+	0xa635, 0xd6f4, 0x1da0, 0x7044, 0xa005, 0x1110, 0x7047, 0x0015,
+	0x2408, 0x2510, 0x2700, 0x8007, 0xa084, 0x007f, 0xa108, 0xa291,
+	0x0000, 0x692e, 0x6a32, 0x2100, 0xa205, 0x1110, 0x0804, 0x3f4e,
+	0x7000, 0xa086, 0x0006, 0x0110, 0x0804, 0x3f4e, 0x0005, 0x6946,
+	0x6008, 0xc0cd, 0xd3cc, 0x0108, 0xc08d, 0x600a, 0x6818, 0x683a,
+	0x681b, 0x0006, 0x688f, 0x0000, 0x6893, 0x0000, 0x6a30, 0x692c,
+	0x6a3e, 0x6942, 0x682f, 0x0003, 0x6833, 0x0000, 0x6837, 0x0020,
+	0x6897, 0x0000, 0x689b, 0x0020, 0x7000, 0x0002, 0x25c9, 0x3196,
+	0x3190, 0x318e, 0x318e, 0x318e, 0x318e, 0x318e, 0x080c, 0x2575,
+	0x6820, 0xd084, 0x1118, 0x080c, 0x37c7, 0x0030, 0x7058, 0x2c50,
+	0x2060, 0x6800, 0x6002, 0x2a60, 0xaea0, 0x0017, 0x2404, 0xa005,
+	0x0110, 0x2020, 0x0cd8, 0x2d22, 0x206b, 0x0000, 0x0005, 0x080c,
+	0x37cd, 0x080c, 0x37e1, 0x6008, 0xc0cc, 0x600a, 0x682b, 0x0000,
+	0x789b, 0x000e, 0x6f14, 0x6938, 0x691a, 0x6944, 0x6916, 0x2009,
+	0x0000, 0xae86, 0x4740, 0x0110, 0x2009, 0x0001, 0x080c, 0x431f,
+	0xd6dc, 0x01c8, 0x691c, 0xc1ed, 0x691e, 0x6828, 0xa082, 0x000e,
+	0x0290, 0x6848, 0xa084, 0x000f, 0xa086, 0x000b, 0x1160, 0x685c,
+	0xa086, 0x0047, 0x1140, 0x2001, 0x4701, 0x2004, 0xd0ac, 0x1118,
+	0x2700, 0x080c, 0x249e, 0x6818, 0xd0fc, 0x0140, 0x681b, 0x0000,
+	0x7868, 0xa08c, 0x00ff, 0x0110, 0x681b, 0x001e, 0xaea0, 0x0017,
+	0x6800, 0x2022, 0x6a3c, 0x6940, 0x6a32, 0x692e, 0x68c0, 0x2060,
+	0x6000, 0xd0a4, 0x0580, 0x2041, 0x0021, 0x2049, 0x0005, 0x2051,
+	0x0020, 0x00d6, 0x00f6, 0x0156, 0x0146, 0x2079, 0x4700, 0x080c,
+	0x1bb2, 0x014e, 0x015e, 0x00fe, 0x70c8, 0x2010, 0x2009, 0x0101,
+	0x0026, 0x2204, 0xa06d, 0x0140, 0x6814, 0xa706, 0x0110, 0x6800,
+	0x0cc8, 0x6820, 0xc0d5, 0x6822, 0x002e, 0x8210, 0x8109, 0x1d80,
+	0x00de, 0x7063, 0x0003, 0x707b, 0x0000, 0x7772, 0x707f, 0x000f,
+	0x71d0, 0xc1c4, 0x71d2, 0x6818, 0xa086, 0x0002, 0x1138, 0x6817,
+	0x0000, 0x682b, 0x0000, 0x681c, 0xc0ec, 0x681e, 0x080c, 0x1dbf,
+	0x0804, 0x25c9, 0x7cd8, 0x7ddc, 0x7fd0, 0x080c, 0x30ff, 0x682b,
+	0x0000, 0x789b, 0x000e, 0x6f14, 0x080c, 0x3c72, 0xa08c, 0x00ff,
+	0x6916, 0x6818, 0xd0fc, 0x0110, 0x7044, 0x681a, 0xa68c, 0xdf00,
+	0x691e, 0x7063, 0x0000, 0x0804, 0x25c9, 0x7000, 0xa005, 0x1110,
+	0x0804, 0x25c9, 0xa006, 0x080c, 0x3f4e, 0x6920, 0xd1ac, 0x1110,
+	0x681b, 0x0014, 0xa68c, 0xdf00, 0x691e, 0x682b, 0x0000, 0x6820,
+	0xa084, 0x00ff, 0x6822, 0x7000, 0x0002, 0x25c9, 0x326f, 0x326f,
+	0x3272, 0x3272, 0x3272, 0x326d, 0x326d, 0x080c, 0x2575, 0x6818,
+	0x0804, 0x2f3b, 0x6008, 0xc0a4, 0x600a, 0x6817, 0x0000, 0x0804,
+	0x3795, 0x2300, 0x0002, 0x327e, 0x3280, 0x32ce, 0x080c, 0x2575,
+	0xd6fc, 0x1904, 0x2d5b, 0x7000, 0xa00d, 0x0002, 0x25c9, 0x3290,
+	0x3290, 0x32ba, 0x3290, 0x32cb, 0x328e, 0x328e, 0x080c, 0x2575,
+	0xa684, 0x0060, 0x0538, 0xa086, 0x0060, 0x1510, 0xc6ac, 0xc6f4,
+	0xc6ed, 0x7e5a, 0x6eb6, 0x681c, 0xc0ac, 0x681e, 0xa186, 0x0002,
+	0x0148, 0x080c, 0x3f4e, 0x69ac, 0x68b0, 0xa115, 0x0118, 0x080c,
+	0x4235, 0x0010, 0x080c, 0x4208, 0x781b, 0x0083, 0x71d0, 0xd1b4,
+	0x1904, 0x25c6, 0x70a0, 0xa086, 0x0001, 0x1904, 0x260d, 0x0005,
+	0xd6ec, 0x09f0, 0x6818, 0xd0fc, 0x0170, 0xd6f4, 0x1130, 0x681b,
+	0x0015, 0x781b, 0x0083, 0x0804, 0x25c6, 0x681b, 0x0007, 0x682f,
+	0x0000, 0x6833, 0x0000, 0x080c, 0x3c17, 0x0005, 0x080c, 0x2575,
+	0x2300, 0x0002, 0x32d7, 0x32f9, 0x3351, 0x080c, 0x2575, 0x7000,
+	0x0002, 0x32e1, 0x32e3, 0x32ea, 0x32e1, 0x32e1, 0x32e1, 0x32e1,
+	0x32e1, 0x080c, 0x2575, 0x69ac, 0x68b0, 0xa115, 0x0118, 0x080c,
+	0x4235, 0x0010, 0x080c, 0x4208, 0x681c, 0xc0b4, 0x681e, 0x70d0,
+	0xd0b4, 0x1904, 0x25c6, 0x70a0, 0xa086, 0x0001, 0x1904, 0x260d,
+	0x0005, 0xd6fc, 0x1904, 0x3341, 0x7000, 0xa00d, 0x0002, 0x25c9,
+	0x330f, 0x3309, 0x3339, 0x330f, 0x333e, 0x3307, 0x3307, 0x080c,
+	0x2575, 0x6894, 0x78d6, 0x78de, 0x6898, 0x78d2, 0x78da, 0xa684,
+	0x0060, 0x0538, 0xa086, 0x0060, 0x1510, 0xa6b4, 0xbfbf, 0xc6ed,
+	0x7e5a, 0x6eb6, 0xa186, 0x0002, 0x0148, 0x080c, 0x3f4e, 0x69ac,
+	0x68b0, 0xa115, 0x0118, 0x080c, 0x4235, 0x0010, 0x080c, 0x4208,
+	0x781b, 0x0083, 0x681c, 0xc0b4, 0x681e, 0x71d0, 0xd1b4, 0x1904,
+	0x25c6, 0x70a0, 0xa086, 0x0001, 0x1904, 0x260d, 0x0005, 0xd6ec,
+	0x09f0, 0x6818, 0xd0fc, 0x0110, 0x681b, 0x0007, 0x781b, 0x00fb,
+	0x0005, 0xc6fc, 0x7e5a, 0x7adc, 0x79d8, 0x6b98, 0x2100, 0xa302,
+	0x68b2, 0x6b94, 0x2200, 0xa303, 0x68ae, 0x79d2, 0x781b, 0x0083,
+	0x0005, 0xd6dc, 0x0130, 0x782b, 0x3009, 0x781b, 0x0083, 0x0804,
+	0x25c6, 0x7884, 0xc0ac, 0x7886, 0x78e4, 0xa084, 0x0008, 0x1150,
+	0xa484, 0x0200, 0x0108, 0xc6f5, 0xc6dd, 0x7e5a, 0x781b, 0x0083,
+	0x0804, 0x25c6, 0x6820, 0xc095, 0x6822, 0x080c, 0x3c02, 0xc6dd,
+	0x080c, 0x3a61, 0x781b, 0x0082, 0x0804, 0x25c6, 0x2300, 0x0002,
+	0x337b, 0x337d, 0x337f, 0x080c, 0x2575, 0x0804, 0x3a5b, 0x7d98,
+	0xd6d4, 0x15a8, 0x79e4, 0xd1ac, 0x0130, 0x78ec, 0xa084, 0x0003,
+	0x0110, 0x782b, 0x3009, 0x789b, 0x0060, 0x78ab, 0x0000, 0xa684,
+	0xfffb, 0x785a, 0x7d9a, 0x79e4, 0xd1ac, 0x0120, 0x78ec, 0xa084,
+	0x0003, 0x1120, 0x2001, 0x0014, 0x0804, 0x2f3b, 0x7884, 0xd0fc,
 	0x1118, 0xa184, 0x0007, 0x0090, 0xa184, 0x0007, 0xa086, 0x0004,
 	0x1118, 0x2001, 0x0000, 0x0050, 0xa184, 0x0007, 0xa086, 0x0005,
-	0x0118, 0xa184, 0x0007, 0x0010, 0x2001, 0x0001, 0x0002, 0x2c6f,
-	0x2c2a, 0x2ba4, 0x3be5, 0x3c29, 0x3c29, 0x3be5, 0x3c23, 0x080c,
-	0x3bf1, 0x0005, 0xa282, 0x0005, 0x0310, 0x080c, 0x254c, 0x7898,
-	0x2040, 0x2300, 0x0002, 0x2c7e, 0x2ea8, 0x2eb2, 0x2200, 0x0002,
-	0x2c9a, 0x2c87, 0x2c9a, 0x2c85, 0x2e8a, 0x080c, 0x254c, 0x789b,
-	0x0018, 0x78a8, 0x2010, 0xa084, 0x00ff, 0xa082, 0x0020, 0x0a04,
-	0x3a0b, 0xa08a, 0x0004, 0x1a04, 0x3a0b, 0x0002, 0x3a0b, 0x3a0b,
-	0x3a0b, 0x39c1, 0x789b, 0x0018, 0x79a8, 0xa184, 0x0080, 0x0148,
-	0x0804, 0x3a0b, 0x7000, 0xa005, 0x1dd8, 0x2011, 0x0004, 0x0804,
-	0x3594, 0xa184, 0x00ff, 0xa08a, 0x0010, 0x1a04, 0x3a0b, 0x0002,
-	0x2cc2, 0x2cc0, 0x2cd4, 0x2cd8, 0x2d86, 0x3a0b, 0x3a0b, 0x2d88,
-	0x3a0b, 0x3a0b, 0x2e86, 0x2e86, 0x3a0b, 0x3a0b, 0x3a0b, 0x2e88,
-	0x080c, 0x254c, 0xd6e4, 0x0140, 0x2001, 0x0300, 0x8000, 0x8000,
-	0x783a, 0x781b, 0x00c7, 0x0005, 0x6818, 0xd0fc, 0x0118, 0x681b,
-	0x001d, 0x0c90, 0x0804, 0x3be5, 0x681b, 0x001d, 0x0804, 0x3a36,
-	0x6920, 0x6922, 0xa684, 0x1800, 0x1904, 0x2d29, 0x6820, 0xd084,
-	0x1904, 0x2d31, 0x6818, 0xa086, 0x0008, 0x1110, 0x681b, 0x0000,
-	0xd6d4, 0x0568, 0xd6bc, 0x0558, 0x7083, 0x0000, 0x6818, 0xa084,
-	0x003f, 0xa08a, 0x000d, 0x0718, 0xa08a, 0x000c, 0x7182, 0x2001,
-	0x000c, 0x800c, 0x7186, 0x789b, 0x0061, 0x78aa, 0x0156, 0x0136,
-	0x0146, 0x0016, 0x3208, 0xa18c, 0x0600, 0x0118, 0x20a1, 0x022b,
-	0x0010, 0x20a1, 0x012b, 0x001e, 0x789b, 0x0000, 0x8000, 0x80ac,
-	0xad80, 0x000b, 0x2098, 0x53a6, 0x014e, 0x013e, 0x015e, 0x6038,
-	0xa005, 0x1150, 0x681c, 0xa084, 0x000e, 0x0904, 0x3a36, 0x080c,
-	0x3a48, 0x782b, 0x3008, 0x0010, 0x8001, 0x603a, 0x781b, 0x0071,
-	0x0005, 0xd6e4, 0x0130, 0x781b, 0x0083, 0x0005, 0x781b, 0x0083,
-	0x0005, 0xa684, 0x0060, 0x0dd0, 0xd6dc, 0x0dc0, 0xd6fc, 0x01a0,
-	0xc6fc, 0x7e5a, 0x6eb6, 0x7adc, 0x79d8, 0x78d0, 0x8007, 0xa084,
-	0x007f, 0xa108, 0xa291, 0x0000, 0x6b98, 0x2100, 0xa302, 0x68b2,
-	0x6b94, 0x2200, 0xa303, 0x68ae, 0xd6f4, 0x0118, 0xc6f4, 0x7e5a,
-	0x6eb6, 0x7000, 0xa086, 0x0003, 0x1148, 0x0006, 0x080c, 0x3f26,
-	0x080c, 0x41d9, 0x000e, 0x781b, 0x0080, 0x0005, 0xa006, 0x080c,
-	0x42b5, 0x6ab0, 0x69ac, 0x6c98, 0x6b94, 0x2200, 0xa105, 0x0120,
-	0x2200, 0xa422, 0x2100, 0xa31b, 0x6caa, 0x7cd2, 0x7cda, 0x6ba6,
-	0x7bd6, 0x7bde, 0x2300, 0xa405, 0x1130, 0xc6f5, 0x7e5a, 0x6eb6,
-	0x781b, 0x0080, 0x0005, 0x781b, 0x0080, 0x2200, 0xa115, 0x1118,
-	0x080c, 0x41d9, 0x0005, 0x080c, 0x4206, 0x0005, 0x080c, 0x254c,
-	0x0804, 0x2e1c, 0x00c6, 0x7054, 0x2060, 0x6920, 0xa18c, 0xecff,
-	0x6922, 0x6000, 0xa084, 0xcfdf, 0x6002, 0x080c, 0x38f4, 0xa006,
-	0x2040, 0x2038, 0x080c, 0x399c, 0x0804, 0x2e10, 0x00c6, 0x7054,
-	0x2060, 0x2c48, 0x7aa8, 0xa294, 0x00ff, 0xa286, 0x0004, 0x11d8,
-	0x6920, 0xd1e4, 0x1170, 0x2039, 0x0000, 0x2041, 0x0000, 0x2031,
-	0x0000, 0xa006, 0x2010, 0x080c, 0x38f7, 0x080c, 0x399c, 0x0804,
-	0x2e10, 0xa18c, 0xecff, 0x6922, 0x6104, 0xa18c, 0xffdd, 0x6106,
-	0x6000, 0xc0ac, 0x6002, 0xa286, 0x0003, 0x01d0, 0x6104, 0xa184,
-	0x0010, 0x0548, 0x080c, 0x3b6b, 0x080c, 0x3977, 0x88ff, 0x0518,
-	0x00ce, 0x789b, 0x0060, 0x2800, 0x78aa, 0x7e58, 0xc695, 0x7e5a,
-	0xd6d4, 0x1118, 0x781b, 0x006e, 0x0005, 0x781b, 0x0082, 0x0005,
-	0x6920, 0xd1cc, 0x0130, 0xa18c, 0xfdff, 0x6922, 0x6000, 0xc0ec,
-	0x6002, 0x2039, 0x0000, 0x2041, 0x0000, 0x2031, 0x0000, 0xa006,
-	0x2010, 0x080c, 0x399c, 0xa286, 0x0001, 0x0158, 0x6104, 0xa184,
-	0x0008, 0x01b0, 0x080c, 0x3b6b, 0x080c, 0x3895, 0x88ff, 0x1980,
-	0x0078, 0x6920, 0xd1c4, 0x0130, 0xa18c, 0xfeff, 0x6922, 0x6000,
-	0xc0e4, 0x6002, 0x2031, 0x0000, 0xa006, 0x2010, 0x080c, 0x38f7,
-	0x00ce, 0x7e58, 0xd6d4, 0x1118, 0x781b, 0x0071, 0x0005, 0x781b,
-	0x0083, 0x0005, 0x0804, 0x3a32, 0x2808, 0x789b, 0x0080, 0x2019,
-	0x0080, 0x78a8, 0xa094, 0x00ff, 0xa286, 0x0001, 0x11b8, 0x2300,
-	0xa102, 0xa086, 0x0001, 0x0904, 0x2d8a, 0x7ca8, 0xa4a4, 0x00ff,
-	0xa480, 0x0002, 0xa300, 0x2018, 0xa102, 0x0a04, 0x2d9e, 0x0904,
-	0x2d9e, 0x24a8, 0x7aa8, 0x1f04, 0x2e3a, 0x0c18, 0xa284, 0x00f0,
-	0xa082, 0x0020, 0x06b8, 0x2200, 0xa082, 0x0021, 0x1698, 0x7aa8,
-	0x8318, 0x8318, 0x2100, 0xa302, 0x0aa0, 0xa286, 0x0023, 0x0950,
-	0x681c, 0xa084, 0xfff1, 0x681e, 0x7e58, 0xa684, 0xfff1, 0xc0a5,
-	0x2030, 0x7e5a, 0x6008, 0xc0a5, 0x600a, 0x78a0, 0x8001, 0x0904,
-	0x2e10, 0x20a8, 0x7998, 0x789b, 0x0060, 0x78aa, 0x2011, 0x0080,
-	0x799a, 0x78a8, 0x7998, 0x7a9a, 0x78aa, 0x7a98, 0x1f04, 0x2e68,
-	0xc695, 0x7e5a, 0xd6d4, 0x1118, 0x781b, 0x006e, 0x0005, 0x781b,
-	0x0082, 0x0005, 0x8318, 0x2100, 0xa302, 0x0a04, 0x2e21, 0xa284,
-	0x0080, 0x1904, 0x3a36, 0x78a0, 0xa005, 0x08c8, 0x0804, 0x3a36,
-	0x0804, 0x3a0b, 0x7054, 0xa04d, 0x789b, 0x0018, 0x78a8, 0xa084,
-	0x00ff, 0xa08e, 0x0001, 0x0110, 0x080c, 0x254c, 0x7aa8, 0xa294,
-	0x00ff, 0x784b, 0x0008, 0x78a8, 0xa084, 0x00ff, 0xa08a, 0x0005,
-	0x1a04, 0x3a0b, 0x0002, 0x3a0b, 0x380c, 0x3a0b, 0x3927, 0x3d31,
-	0xa282, 0x0000, 0x1110, 0x080c, 0x254c, 0x080c, 0x3a3c, 0x781b,
-	0x0082, 0x0005, 0xa282, 0x0003, 0x1110, 0x080c, 0x254c, 0xd4fc,
-	0x11d0, 0x7060, 0xa005, 0x0110, 0x080c, 0x254c, 0x6f14, 0x7772,
-	0xa7bc, 0x8f00, 0x080c, 0x3b6f, 0x6008, 0xa085, 0x0021, 0x600a,
-	0x8738, 0xa784, 0x001f, 0x1db0, 0x080c, 0x3a3f, 0x7063, 0x0002,
-	0x701f, 0x0009, 0x0010, 0x080c, 0x3a4b, 0x781b, 0x0082, 0x0005,
-	0xa282, 0x0004, 0x0310, 0x080c, 0x254c, 0x2300, 0x0002, 0x2ee2,
-	0x3078, 0x30b4, 0xa286, 0x0003, 0x0598, 0x7200, 0x7cd8, 0x7ddc,
-	0x7fd0, 0x71d0, 0xd1b4, 0x0528, 0xd1bc, 0x1518, 0x2001, 0x4601,
-	0x2004, 0xd0c4, 0x11f0, 0x7868, 0xa084, 0x00ff, 0x11d0, 0xa282,
-	0x0002, 0x12b8, 0x00d6, 0x783b, 0x8300, 0x781b, 0x0059, 0x70b8,
-	0xa06d, 0x68b4, 0x785a, 0x6894, 0x78d6, 0x78de, 0x6898, 0x78d2,
-	0x78da, 0xc1b4, 0x71d2, 0x7003, 0x0030, 0x00de, 0x2001, 0x0000,
-	0x0058, 0x783b, 0x1300, 0x781b, 0x0057, 0x2001, 0x0000, 0x0020,
-	0x7200, 0x7cd8, 0x7ddc, 0x7fd0, 0x7046, 0x68a0, 0xd0ec, 0x0118,
-	0x6008, 0xc08d, 0x600a, 0xa284, 0x000f, 0x0002, 0x3059, 0x2f33,
-	0x2f30, 0x3184, 0x320f, 0x25a0, 0x2f2e, 0x2f2e, 0x080c, 0x254c,
-	0x6008, 0xc0d4, 0x600a, 0xd6e4, 0x0120, 0x7044, 0xa086, 0x0014,
-	0x11e8, 0x080c, 0x3f26, 0x2009, 0x0000, 0x6818, 0xd0fc, 0x0108,
-	0x7044, 0xa086, 0x0014, 0x0168, 0x6818, 0xa086, 0x0008, 0x1904,
-	0x301b, 0x7858, 0xd09c, 0x0904, 0x301b, 0x6820, 0xd0ac, 0x0904,
-	0x301b, 0x681b, 0x0014, 0x2009, 0x0002, 0x04a8, 0x7868, 0xa08c,
-	0x00ff, 0x0588, 0xa186, 0x0008, 0x1158, 0x6008, 0xc0a4, 0x600a,
-	0x080c, 0x374f, 0x0540, 0x080c, 0x37be, 0x080c, 0x3f26, 0x0060,
-	0xa186, 0x0028, 0x1500, 0x6018, 0xa005, 0x0d78, 0x8001, 0x0d68,
-	0x8001, 0x0d58, 0x601e, 0x0c48, 0x6820, 0xd084, 0x0904, 0x25a0,
-	0xc084, 0x6822, 0x080c, 0x2693, 0x7058, 0x00c6, 0x2060, 0x6800,
-	0x6002, 0x00ce, 0x6004, 0x6802, 0xa005, 0x2d00, 0x1108, 0x6002,
-	0x6006, 0x0804, 0x25a0, 0x0016, 0x81ff, 0x15f0, 0x7000, 0xa086,
-	0x0030, 0x05d0, 0x71d0, 0xd1bc, 0x15b8, 0xd1b4, 0x11e8, 0x705c,
-	0xa005, 0x1590, 0x70a0, 0xa086, 0x0001, 0x0570, 0x7003, 0x0000,
-	0x0046, 0x0056, 0x0076, 0x0066, 0x00c6, 0x00d6, 0x080c, 0x25c5,
-	0x00de, 0x00ce, 0x006e, 0x007e, 0x005e, 0x004e, 0x71d0, 0xd1b4,
-	0x11d8, 0x7003, 0x0040, 0x00c0, 0x080c, 0x3c33, 0x11a8, 0x781b,
-	0x0068, 0x00d6, 0x70b8, 0xa06d, 0x68b4, 0x785a, 0x6894, 0x78d6,
-	0x78de, 0x6898, 0x78d2, 0x78da, 0xc1b4, 0x71d2, 0x7003, 0x0030,
-	0x7808, 0xc08d, 0x780a, 0x00de, 0x080c, 0x30dc, 0x001e, 0x81ff,
-	0x0904, 0x301b, 0xa684, 0xdf00, 0x681e, 0x682b, 0x0000, 0x6f14,
-	0xa186, 0x0002, 0x1904, 0x301c, 0x6818, 0xa086, 0x0014, 0x1130,
-	0x2008, 0xd6e4, 0x0118, 0x7868, 0xa08c, 0x00ff, 0x080c, 0x3a55,
-	0x080c, 0x269e, 0x6820, 0xd0dc, 0x1578, 0x8717, 0xa294, 0x000f,
-	0x8213, 0x8213, 0x8213, 0xb284, 0x0600, 0x0118, 0xa290, 0x4ac0,
-	0x0010, 0xa290, 0x4b40, 0xa290, 0x0000, 0x221c, 0xd3c4, 0x0170,
-	0x6820, 0xd0e4, 0x0128, 0xa084, 0xefff, 0x6822, 0xc3ac, 0x2312,
-	0x8210, 0x2204, 0xa085, 0x0038, 0x2012, 0x8211, 0xd3d4, 0x0138,
-	0x68a0, 0xd0c4, 0x1120, 0x080c, 0x3144, 0x0804, 0x25a0, 0x6008,
-	0xc08d, 0x600a, 0x0008, 0x692a, 0x6916, 0x6818, 0xd0fc, 0x0110,
-	0x7044, 0x681a, 0xa68c, 0xdf00, 0x691e, 0x6410, 0x84ff, 0x0168,
-	0x2009, 0x4602, 0x2104, 0x8001, 0x200a, 0x8421, 0x6412, 0x1128,
-	0x2021, 0x4604, 0x2404, 0xc0a5, 0x2022, 0x6018, 0xa005, 0x0118,
-	0x8001, 0x601a, 0x1118, 0x6008, 0xc0a4, 0x600a, 0x6820, 0xd084,
-	0x1130, 0x6800, 0xa005, 0x1108, 0x6002, 0x6006, 0x0020, 0x7058,
-	0x2060, 0x6800, 0x6002, 0x2061, 0x4600, 0x6887, 0x0103, 0x2d08,
-	0x206b, 0x0000, 0x6068, 0xa005, 0x616a, 0x0110, 0x2d02, 0x0008,
-	0x616e, 0x7200, 0xa286, 0x0030, 0x0158, 0xa286, 0x0040, 0x1904,
-	0x25a0, 0x7003, 0x0002, 0x7048, 0x2068, 0x68c4, 0x2060, 0x0005,
-	0x7003, 0x0002, 0x70b8, 0xa06d, 0x68bc, 0x703e, 0x70b4, 0xa065,
-	0x68c0, 0x7056, 0x2d00, 0x704a, 0xad80, 0x0009, 0x7042, 0x0005,
-	0xa282, 0x0004, 0x0210, 0x080c, 0x254c, 0x2200, 0x0002, 0x3083,
-	0x3092, 0x309e, 0x3092, 0xa586, 0x1300, 0x0160, 0xa586, 0x8300,
-	0x1d90, 0x7003, 0x0000, 0x6018, 0x8001, 0x601a, 0x6008, 0xa084,
-	0xfbef, 0x600a, 0x7000, 0xa086, 0x0005, 0x0128, 0x080c, 0x3a3c,
-	0x781b, 0x0082, 0x0005, 0x781b, 0x0083, 0x0005, 0x7890, 0x8007,
-	0x8001, 0xa084, 0x0007, 0xa080, 0x0018, 0x789a, 0x79a8, 0xa18c,
-	0x00ff, 0xa186, 0x0003, 0x0128, 0xa186, 0x0000, 0x0110, 0x0804,
-	0x3a0b, 0x781b, 0x0083, 0x0005, 0x6820, 0xc095, 0x6822, 0x82ff,
-	0x1118, 0x080c, 0x3a3c, 0x0030, 0x8211, 0x0110, 0x080c, 0x254c,
-	0x080c, 0x3a4b, 0x781b, 0x0082, 0x0005, 0x080c, 0x3c46, 0x7830,
-	0xa084, 0x00c0, 0x1170, 0x0016, 0x3208, 0xa18c, 0x0800, 0x001e,
-	0x0118, 0x0104, 0x30d9, 0x0010, 0x0304, 0x30d9, 0x791a, 0xa006,
-	0x0005, 0xa085, 0x0001, 0x0005, 0xa684, 0x0060, 0x1130, 0x682f,
-	0x0000, 0x6833, 0x0000, 0x0804, 0x3143, 0xd6dc, 0x1198, 0x68b4,
-	0xd0dc, 0x1180, 0x6998, 0x6a94, 0x692e, 0x6a32, 0x7044, 0xa005,
-	0x1130, 0x2200, 0xa105, 0x0904, 0x3f26, 0x7047, 0x0015, 0x0804,
-	0x3f26, 0x0005, 0xd6ac, 0x01f0, 0xd6f4, 0x0130, 0x682f, 0x0000,
-	0x6833, 0x0000, 0x0804, 0x3f26, 0x68b4, 0xa084, 0x4000, 0xa635,
-	0xd6f4, 0x1da0, 0x7044, 0xa005, 0x1110, 0x7047, 0x0015, 0xd6dc,
-	0x1128, 0x68b4, 0xd0dc, 0x0110, 0x6ca8, 0x6da4, 0x6c2e, 0x6d32,
-	0x0804, 0x3f26, 0xd6f4, 0x0130, 0x682f, 0x0000, 0x6833, 0x0000,
-	0x0804, 0x3f26, 0x68b4, 0xa084, 0x4800, 0xa635, 0xd6f4, 0x1da0,
-	0x7044, 0xa005, 0x1110, 0x7047, 0x0015, 0x2408, 0x2510, 0x2700,
-	0x8007, 0xa084, 0x007f, 0xa108, 0xa291, 0x0000, 0x692e, 0x6a32,
-	0x2100, 0xa205, 0x1110, 0x0804, 0x3f26, 0x7000, 0xa086, 0x0006,
-	0x0110, 0x0804, 0x3f26, 0x0005, 0x6946, 0x6008, 0xc0cd, 0xd3cc,
-	0x0108, 0xc08d, 0x600a, 0x6818, 0x683a, 0x681b, 0x0006, 0x688f,
-	0x0000, 0x6893, 0x0000, 0x6a30, 0x692c, 0x6a3e, 0x6942, 0x682f,
-	0x0003, 0x6833, 0x0000, 0x6837, 0x0020, 0x6897, 0x0000, 0x689b,
-	0x0020, 0x7000, 0x0002, 0x25a0, 0x3173, 0x316d, 0x316b, 0x316b,
-	0x316b, 0x316b, 0x316b, 0x080c, 0x254c, 0x6820, 0xd084, 0x1118,
-	0x080c, 0x37a4, 0x0030, 0x7058, 0x2c50, 0x2060, 0x6800, 0x6002,
-	0x2a60, 0xaea0, 0x0017, 0x2404, 0xa005, 0x0110, 0x2020, 0x0cd8,
-	0x2d22, 0x206b, 0x0000, 0x0005, 0x080c, 0x37aa, 0x080c, 0x37be,
-	0x6008, 0xc0cc, 0x600a, 0x682b, 0x0000, 0x789b, 0x000e, 0x6f14,
-	0x6938, 0x691a, 0x6944, 0x6916, 0x2009, 0x0000, 0xae86, 0x4640,
-	0x0110, 0x2009, 0x0001, 0x080c, 0x42ec, 0xd6dc, 0x01c8, 0x691c,
-	0xc1ed, 0x691e, 0x6828, 0xa082, 0x000e, 0x0290, 0x6848, 0xa084,
-	0x000f, 0xa086, 0x000b, 0x1160, 0x685c, 0xa086, 0x0047, 0x1140,
-	0x2001, 0x4601, 0x2004, 0xd0ac, 0x1118, 0x2700, 0x080c, 0x2475,
-	0x6818, 0xd0fc, 0x0140, 0x681b, 0x0000, 0x7868, 0xa08c, 0x00ff,
-	0x0110, 0x681b, 0x001e, 0xaea0, 0x0017, 0x6800, 0x2022, 0x6a3c,
-	0x6940, 0x6a32, 0x692e, 0x68c0, 0x2060, 0x6000, 0xd0a4, 0x0580,
-	0x2041, 0x0021, 0x2049, 0x0005, 0x2051, 0x0020, 0x00d6, 0x00f6,
-	0x0156, 0x0146, 0x2079, 0x4600, 0x080c, 0x1b93, 0x014e, 0x015e,
-	0x00fe, 0x70c8, 0x2010, 0x2009, 0x0101, 0x0026, 0x2204, 0xa06d,
-	0x0140, 0x6814, 0xa706, 0x0110, 0x6800, 0x0cc8, 0x6820, 0xc0d5,
-	0x6822, 0x002e, 0x8210, 0x8109, 0x1d80, 0x00de, 0x7063, 0x0003,
-	0x707b, 0x0000, 0x7772, 0x707f, 0x000f, 0x71d0, 0xc1c4, 0x71d2,
-	0x6818, 0xa086, 0x0002, 0x1138, 0x6817, 0x0000, 0x682b, 0x0000,
-	0x681c, 0xc0ec, 0x681e, 0x080c, 0x1da2, 0x0804, 0x25a0, 0x7cd8,
-	0x7ddc, 0x7fd0, 0x080c, 0x30dc, 0x682b, 0x0000, 0x789b, 0x000e,
-	0x6f14, 0x080c, 0x3c4a, 0xa08c, 0x00ff, 0x6916, 0x6818, 0xd0fc,
-	0x0110, 0x7044, 0x681a, 0xa68c, 0xdf00, 0x691e, 0x7063, 0x0000,
-	0x0804, 0x25a0, 0x7000, 0xa005, 0x1110, 0x0804, 0x25a0, 0xa006,
-	0x080c, 0x3f26, 0x6920, 0xd1ac, 0x1110, 0x681b, 0x0014, 0xa68c,
-	0xdf00, 0x691e, 0x682b, 0x0000, 0x6820, 0xa084, 0x00ff, 0x6822,
-	0x7000, 0x0002, 0x25a0, 0x324c, 0x324c, 0x324f, 0x324f, 0x324f,
-	0x324a, 0x324a, 0x080c, 0x254c, 0x6818, 0x0804, 0x2f18, 0x6008,
-	0xc0a4, 0x600a, 0x6817, 0x0000, 0x0804, 0x3772, 0x2300, 0x0002,
-	0x325b, 0x325d, 0x32ab, 0x080c, 0x254c, 0xd6fc, 0x1904, 0x2d38,
-	0x7000, 0xa00d, 0x0002, 0x25a0, 0x326d, 0x326d, 0x3297, 0x326d,
-	0x32a8, 0x326b, 0x326b, 0x080c, 0x254c, 0xa684, 0x0060, 0x0538,
-	0xa086, 0x0060, 0x1510, 0xc6ac, 0xc6f4, 0xc6ed, 0x7e5a, 0x6eb6,
-	0x681c, 0xc0ac, 0x681e, 0xa186, 0x0002, 0x0148, 0x080c, 0x3f26,
-	0x69ac, 0x68b0, 0xa115, 0x0118, 0x080c, 0x4206, 0x0010, 0x080c,
-	0x41d9, 0x781b, 0x0083, 0x71d0, 0xd1b4, 0x1904, 0x259d, 0x70a0,
-	0xa086, 0x0001, 0x1904, 0x25e1, 0x0005, 0xd6ec, 0x09f0, 0x6818,
-	0xd0fc, 0x0170, 0xd6f4, 0x1130, 0x681b, 0x0015, 0x781b, 0x0083,
-	0x0804, 0x259d, 0x681b, 0x0007, 0x682f, 0x0000, 0x6833, 0x0000,
-	0x080c, 0x3bf1, 0x0005, 0x080c, 0x254c, 0x2300, 0x0002, 0x32b4,
-	0x32d6, 0x332e, 0x080c, 0x254c, 0x7000, 0x0002, 0x32be, 0x32c0,
-	0x32c7, 0x32be, 0x32be, 0x32be, 0x32be, 0x32be, 0x080c, 0x254c,
-	0x69ac, 0x68b0, 0xa115, 0x0118, 0x080c, 0x4206, 0x0010, 0x080c,
-	0x41d9, 0x681c, 0xc0b4, 0x681e, 0x70d0, 0xd0b4, 0x1904, 0x259d,
-	0x70a0, 0xa086, 0x0001, 0x1904, 0x25e1, 0x0005, 0xd6fc, 0x1904,
-	0x331e, 0x7000, 0xa00d, 0x0002, 0x25a0, 0x32ec, 0x32e6, 0x3316,
-	0x32ec, 0x331b, 0x32e4, 0x32e4, 0x080c, 0x254c, 0x6894, 0x78d6,
-	0x78de, 0x6898, 0x78d2, 0x78da, 0xa684, 0x0060, 0x0538, 0xa086,
-	0x0060, 0x1510, 0xa6b4, 0xbfbf, 0xc6ed, 0x7e5a, 0x6eb6, 0xa186,
-	0x0002, 0x0148, 0x080c, 0x3f26, 0x69ac, 0x68b0, 0xa115, 0x0118,
-	0x080c, 0x4206, 0x0010, 0x080c, 0x41d9, 0x781b, 0x0083, 0x681c,
-	0xc0b4, 0x681e, 0x71d0, 0xd1b4, 0x1904, 0x259d, 0x70a0, 0xa086,
-	0x0001, 0x1904, 0x25e1, 0x0005, 0xd6ec, 0x09f0, 0x6818, 0xd0fc,
-	0x0110, 0x681b, 0x0007, 0x781b, 0x00fb, 0x0005, 0xc6fc, 0x7e5a,
-	0x7adc, 0x79d8, 0x6b98, 0x2100, 0xa302, 0x68b2, 0x6b94, 0x2200,
-	0xa303, 0x68ae, 0x79d2, 0x781b, 0x0083, 0x0005, 0xd6dc, 0x0130,
-	0x782b, 0x3009, 0x781b, 0x0083, 0x0804, 0x259d, 0x7884, 0xc0ac,
-	0x7886, 0x78e4, 0xa084, 0x0008, 0x1150, 0xa484, 0x0200, 0x0108,
-	0xc6f5, 0xc6dd, 0x7e5a, 0x781b, 0x0083, 0x0804, 0x259d, 0x6820,
-	0xc095, 0x6822, 0x080c, 0x3bdc, 0xc6dd, 0x080c, 0x3a3c, 0x781b,
-	0x0082, 0x0804, 0x259d, 0x2300, 0x0002, 0x3358, 0x335a, 0x335c,
-	0x080c, 0x254c, 0x0804, 0x3a36, 0x7d98, 0xd6d4, 0x15a8, 0x79e4,
-	0xd1ac, 0x0130, 0x78ec, 0xa084, 0x0003, 0x0110, 0x782b, 0x3009,
-	0x789b, 0x0060, 0x78ab, 0x0000, 0xa684, 0xfffb, 0x785a, 0x7d9a,
-	0x79e4, 0xd1ac, 0x0120, 0x78ec, 0xa084, 0x0003, 0x1120, 0x2001,
-	0x0014, 0x0804, 0x2f18, 0x7884, 0xd0fc, 0x1118, 0xa184, 0x0007,
+	0x0118, 0xa184, 0x0007, 0x0010, 0x2001, 0x0001, 0x04c2, 0x7a90,
+	0xa294, 0x0007, 0x789b, 0x0060, 0x79a8, 0x81ff, 0x0568, 0x789b,
+	0x0080, 0x7ba8, 0xa384, 0x0001, 0x11d0, 0x7ba8, 0x7ba8, 0xa386,
+	0x0004, 0x1118, 0x2009, 0xffdf, 0x0058, 0xa386, 0x0001, 0x1118,
+	0x2009, 0xfff7, 0x0028, 0xa386, 0x0003, 0x1148, 0x2009, 0xffef,
+	0x00c6, 0x7054, 0x2060, 0x6004, 0xa104, 0x6006, 0x00ce, 0x789b,
+	0x0060, 0x78ab, 0x0000, 0xa684, 0xfffb, 0x785a, 0x782b, 0x3009,
+	0x6920, 0xa18c, 0xecff, 0x6922, 0x7d9a, 0x0804, 0x3c0b, 0x2bd1,
+	0x2bda, 0x33f9, 0x33ff, 0x33f7, 0x33f7, 0x3c0b, 0x3c0b, 0x080c,
+	0x2575, 0x6920, 0xa18c, 0xfcff, 0x6922, 0x0804, 0x3c11, 0x6920,
+	0xa18c, 0xfcff, 0x6922, 0x0804, 0x3c0b, 0x79e4, 0xa184, 0x0030,
+	0x0120, 0x78ec, 0xa084, 0x0003, 0x1570, 0x7000, 0xa086, 0x0004,
+	0x1190, 0x7060, 0xa086, 0x0002, 0x1130, 0x2011, 0x0002, 0x2019,
+	0x0000, 0x0804, 0x2a85, 0x7060, 0xa086, 0x0006, 0x0db0, 0x7060,
+	0xa086, 0x0004, 0x0d90, 0x7000, 0xa086, 0x0000, 0x0904, 0x25c6,
+	0x6920, 0xa184, 0x0420, 0x0128, 0xc1d4, 0x6922, 0x6818, 0x0804,
+	0x2f3b, 0x6818, 0xa08e, 0x0002, 0x0120, 0xc0fd, 0x681a, 0x2001,
+	0x0014, 0x0804, 0x2f3b, 0x7884, 0xd0fc, 0x1118, 0xa184, 0x0007,
 	0x0090, 0xa184, 0x0007, 0xa086, 0x0004, 0x1118, 0x2001, 0x0000,
 	0x0050, 0xa184, 0x0007, 0xa086, 0x0005, 0x0118, 0xa184, 0x0007,
-	0x0010, 0x2001, 0x0001, 0x04c2, 0x7a90, 0xa294, 0x0007, 0x789b,
-	0x0060, 0x79a8, 0x81ff, 0x0568, 0x789b, 0x0080, 0x7ba8, 0xa384,
-	0x0001, 0x11d0, 0x7ba8, 0x7ba8, 0xa386, 0x0004, 0x1118, 0x2009,
-	0xffdf, 0x0058, 0xa386, 0x0001, 0x1118, 0x2009, 0xfff7, 0x0028,
-	0xa386, 0x0003, 0x1148, 0x2009, 0xffef, 0x00c6, 0x7054, 0x2060,
-	0x6004, 0xa104, 0x6006, 0x00ce, 0x789b, 0x0060, 0x78ab, 0x0000,
-	0xa684, 0xfffb, 0x785a, 0x782b, 0x3009, 0x6920, 0xa18c, 0xecff,
-	0x6922, 0x7d9a, 0x0804, 0x3be5, 0x2bae, 0x2bb7, 0x33d6, 0x33dc,
-	0x33d4, 0x33d4, 0x3be5, 0x3be5, 0x080c, 0x254c, 0x6920, 0xa18c,
-	0xfcff, 0x6922, 0x0804, 0x3beb, 0x6920, 0xa18c, 0xfcff, 0x6922,
-	0x0804, 0x3be5, 0x79e4, 0xa184, 0x0030, 0x0120, 0x78ec, 0xa084,
-	0x0003, 0x1570, 0x7000, 0xa086, 0x0004, 0x1190, 0x7060, 0xa086,
-	0x0002, 0x1130, 0x2011, 0x0002, 0x2019, 0x0000, 0x0804, 0x2a56,
-	0x7060, 0xa086, 0x0006, 0x0db0, 0x7060, 0xa086, 0x0004, 0x0d90,
-	0x7000, 0xa086, 0x0000, 0x0904, 0x259d, 0x6920, 0xa184, 0x0420,
-	0x0128, 0xc1d4, 0x6922, 0x6818, 0x0804, 0x2f18, 0x6818, 0xa08e,
-	0x0002, 0x0120, 0xc0fd, 0x681a, 0x2001, 0x0014, 0x0804, 0x2f18,
-	0x7884, 0xd0fc, 0x1118, 0xa184, 0x0007, 0x0090, 0xa184, 0x0007,
-	0xa086, 0x0004, 0x1118, 0x2001, 0x0000, 0x0050, 0xa184, 0x0007,
-	0xa086, 0x0005, 0x0118, 0xa184, 0x0007, 0x0010, 0x2001, 0x0001,
-	0x0002, 0x3be5, 0x3be5, 0x3439, 0x3be5, 0x3c29, 0x3c29, 0x3be5,
-	0x3be5, 0xd6bc, 0x0570, 0x7180, 0x81ff, 0x0558, 0xa182, 0x000d,
-	0x1318, 0x7083, 0x0000, 0x0028, 0xa182, 0x000c, 0x7082, 0x2009,
-	0x000c, 0x789b, 0x0061, 0x79aa, 0x0156, 0x0136, 0x0146, 0x7084,
-	0x8114, 0xa210, 0x7286, 0xa080, 0x000b, 0xad00, 0x2098, 0xb284,
-	0x0600, 0x0118, 0x20a1, 0x022b, 0x0010, 0x20a1, 0x012b, 0x789b,
-	0x0000, 0x8108, 0x81ac, 0x53a6, 0x014e, 0x013e, 0x015e, 0x0804,
-	0x3beb, 0xd6d4, 0x1904, 0x34ac, 0x6820, 0xd084, 0x0904, 0x3beb,
-	0xa68c, 0x0060, 0xa684, 0x0060, 0x0120, 0xa086, 0x0060, 0x1108,
-	0xc1f5, 0xc194, 0x795a, 0x69b6, 0x789b, 0x0060, 0x78ab, 0x0000,
-	0x789b, 0x0061, 0x6818, 0xc0fd, 0x681a, 0x78aa, 0x8008, 0x810c,
-	0x0904, 0x37d3, 0xa18c, 0x00f8, 0x1904, 0x37d3, 0x0156, 0x0136,
-	0x0146, 0x0016, 0x20a1, 0x012b, 0x3208, 0xa18c, 0x0600, 0x0110,
-	0x20a1, 0x022b, 0x001e, 0x789b, 0x0000, 0x8000, 0x80ac, 0xad80,
-	0x000b, 0x2098, 0x53a6, 0x014e, 0x013e, 0x015e, 0x6814, 0xc0fc,
-	0x8007, 0x7882, 0x0804, 0x3beb, 0x6818, 0xd0fc, 0x0110, 0x681b,
-	0x0008, 0x080c, 0x3a3c, 0x781b, 0x00ed, 0x0005, 0x2300, 0x0002,
-	0x34bd, 0x357a, 0x34bb, 0x080c, 0x254c, 0x7cd8, 0x7ddc, 0x7fd0,
-	0x82ff, 0x1528, 0x7200, 0xa286, 0x0003, 0x0904, 0x2ee6, 0x71d0,
-	0xd1bc, 0x11f8, 0xd1b4, 0x01e8, 0x2001, 0x4601, 0x2004, 0xd0c4,
-	0x11c0, 0x00d6, 0x783b, 0x8800, 0x781b, 0x0059, 0x70b8, 0xa06d,
-	0x68b4, 0xc0a5, 0x785a, 0x6894, 0x78d6, 0x78de, 0x6898, 0x78d2,
-	0x78da, 0xc1b4, 0x71d2, 0x7003, 0x0030, 0x00de, 0x0030, 0x7200,
-	0x0020, 0x783b, 0x1800, 0x781b, 0x0057, 0xa284, 0x000f, 0x0002,
-	0x3565, 0x3522, 0x34fa, 0x2f15, 0x34f8, 0x3565, 0x34f8, 0x34f8,
-	0x080c, 0x254c, 0x681c, 0xd0ec, 0x0118, 0x6008, 0xc08d, 0x600a,
-	0x6920, 0xc185, 0x6922, 0x6800, 0x6006, 0xa005, 0x1108, 0x6002,
-	0x6008, 0xc0d4, 0x600a, 0x681c, 0xa084, 0x000e, 0x1120, 0x71c8,
-	0xa188, 0x0100, 0x0028, 0x7030, 0x68ba, 0x713c, 0x70c8, 0xa108,
-	0x2104, 0x6802, 0x2d0a, 0x715a, 0xd6dc, 0x1120, 0xc6fc, 0x6eb6,
-	0x0804, 0x3565, 0x6eb6, 0xa684, 0x0060, 0x1120, 0xa684, 0x7fff,
-	0x68b6, 0x04d8, 0xd6dc, 0x1150, 0xa684, 0x7fff, 0x68b6, 0x6894,
-	0x68a6, 0x6898, 0x68aa, 0x080c, 0x3f26, 0x0478, 0xd6ac, 0x0140,
-	0xa006, 0x080c, 0x3f26, 0x2408, 0x2510, 0x69aa, 0x6aa6, 0x0068,
-	0x2408, 0x2510, 0x2700, 0x8007, 0xa084, 0x007f, 0xa108, 0xa291,
-	0x0000, 0x69aa, 0x6aa6, 0x080c, 0x3f26, 0xd6fc, 0x01b0, 0xa684,
-	0x7fff, 0x68b6, 0x2510, 0x2408, 0xd6ac, 0x1138, 0x2700, 0x8007,
-	0xa084, 0x007f, 0xa108, 0xa291, 0x0000, 0x6b98, 0x2100, 0xa302,
-	0x68b2, 0x6b94, 0x2200, 0xa303, 0x68ae, 0x7000, 0xa086, 0x0030,
-	0x1904, 0x25a0, 0x7003, 0x0002, 0x70b8, 0xa06d, 0x68bc, 0x703e,
-	0x70b4, 0xa065, 0x68c0, 0x7056, 0x2d00, 0x704a, 0xad80, 0x0009,
-	0x7042, 0x0005, 0xa586, 0x8800, 0x1148, 0x7003, 0x0000, 0x6018,
-	0x8001, 0x601a, 0x6008, 0xa084, 0xfbef, 0x600a, 0x0804, 0x3a36,
-	0x7043, 0x0000, 0xa282, 0x0006, 0x0310, 0x080c, 0x254c, 0x2300,
-	0x0002, 0x3594, 0x35a5, 0x35af, 0x2200, 0x0002, 0x359c, 0x3a36,
-	0x359e, 0x359c, 0x35e0, 0x362e, 0x080c, 0x254c, 0x7a80, 0xa294,
-	0x0f00, 0x080c, 0x3682, 0x0804, 0x3a0b, 0x00c1, 0x0002, 0x3a36,
-	0x35ad, 0x35ad, 0x35e0, 0x35ad, 0x3a36, 0x080c, 0x254c, 0x0071,
-	0x0002, 0x35b9, 0x35b7, 0x35b7, 0x35b9, 0x35b7, 0x35b9, 0x080c,
-	0x254c, 0x080c, 0x3a4b, 0x781b, 0x0082, 0x0005, 0x7000, 0xa086,
-	0x0002, 0x1150, 0x080c, 0x37be, 0x0010, 0x080c, 0x3f26, 0x6008,
-	0xa084, 0xfbef, 0x600a, 0x0020, 0x7000, 0xa086, 0x0003, 0x0da8,
-	0x7003, 0x0005, 0x2001, 0x8de0, 0xae8e, 0x4640, 0x0110, 0x2001,
-	0x8e12, 0x2068, 0x704a, 0xad80, 0x0009, 0x7042, 0x2200, 0x0005,
-	0x7000, 0xa086, 0x0002, 0x1158, 0x70d0, 0xc0b5, 0x70d2, 0x2c00,
-	0x70b6, 0x2d00, 0x70ba, 0x0038, 0x080c, 0x3f26, 0x0020, 0x7000,
-	0xa086, 0x0003, 0x0dc8, 0x7003, 0x0001, 0x7a80, 0xa294, 0x0f00,
-	0x789b, 0x0018, 0x7ca8, 0xa484, 0x001f, 0xa215, 0x2069, 0x8cc0,
-	0xb284, 0x0600, 0x1118, 0xc2fd, 0x2069, 0x8dd0, 0x2d04, 0x2d08,
-	0x715a, 0xa06d, 0x0128, 0x6814, 0xa206, 0x0120, 0x6800, 0x0cb8,
-	0x080c, 0x3682, 0x6eb4, 0x7e5a, 0x6920, 0xa184, 0x0c00, 0x0904,
-	0x36a8, 0x7060, 0xa086, 0x0006, 0x1128, 0x7070, 0xa206, 0x1110,
-	0x7062, 0x707a, 0x681b, 0x0005, 0xc1ad, 0x681b, 0x0005, 0xc1ad,
-	0xc1d4, 0x6922, 0x080c, 0x3a42, 0x0804, 0x36a8, 0x7200, 0xa286,
-	0x0002, 0x1158, 0x70d0, 0xc0b5, 0x70d2, 0x2c00, 0x70b6, 0x2d00,
-	0x70ba, 0x0030, 0x080c, 0x3f26, 0x0018, 0xa286, 0x0003, 0x0dd0,
-	0x7003, 0x0001, 0x7a80, 0xa294, 0x0f00, 0x789b, 0x0018, 0x7ca8,
-	0xa484, 0x001f, 0xa215, 0xae86, 0x4640, 0x0108, 0xc2fd, 0x79a8,
-	0x79a8, 0xa18c, 0x00ff, 0x2118, 0x70c8, 0xa168, 0x2d04, 0x2d08,
-	0x715a, 0xa06d, 0x0128, 0x6814, 0xa206, 0x0118, 0x6800, 0x0cb8,
-	0x0409, 0x6eb4, 0x6920, 0xa184, 0x0c00, 0x0904, 0x36a8, 0xd0dc,
-	0x0178, 0x7060, 0xa086, 0x0004, 0x1140, 0x7070, 0xa206, 0x1128,
-	0x7074, 0xa306, 0x1110, 0x7062, 0x707a, 0x080c, 0x3a48, 0x0480,
-	0x681b, 0x0005, 0xc1ad, 0xc1d4, 0x6922, 0x080c, 0x3a42, 0x707b,
-	0x0000, 0x0430, 0x7003, 0x0005, 0xb284, 0x0600, 0x0118, 0x2001,
-	0x8de0, 0x0010, 0x2001, 0x8e12, 0x2068, 0x704a, 0x0156, 0x20a9,
-	0x0032, 0x2003, 0x0000, 0x8000, 0x1f04, 0x3691, 0x015e, 0xb284,
-	0x0600, 0x0110, 0xc2fc, 0x0008, 0xc2fd, 0x6a16, 0xad80, 0x0009,
-	0x7042, 0x68b7, 0x0700, 0x6823, 0x0800, 0x6827, 0x0003, 0x0005,
-	0xc6ec, 0xa6ac, 0x0060, 0x0904, 0x36ef, 0x6b98, 0x6c94, 0x69ac,
-	0x68b0, 0xa105, 0x11e0, 0x7bd2, 0x7bda, 0x7cd6, 0x7cde, 0xa586,
-	0x0060, 0x05c8, 0xd6f4, 0x1108, 0xc6ed, 0xa6b4, 0xb7ff, 0x7e5a,
-	0x2009, 0x0083, 0xd69c, 0x0128, 0x2009, 0x0082, 0x2019, 0x0000,
-	0x2320, 0x791a, 0xd6ec, 0x0588, 0x080c, 0x41d9, 0x0470, 0x68b0,
-	0xa31a, 0x2100, 0xa423, 0x2400, 0xa305, 0x01f8, 0x7bd2, 0x7bda,
-	0x7cd6, 0x7cde, 0x68b0, 0xd6f4, 0x1108, 0xc6ed, 0xc6f4, 0x7e5a,
-	0x2011, 0x0083, 0xd69c, 0x0128, 0x2011, 0x0082, 0x2019, 0x0000,
-	0x2320, 0x7a1a, 0xd6ec, 0x0188, 0x080c, 0x4206, 0x0070, 0x2019,
-	0x0000, 0x2320, 0x0010, 0xa6b4, 0xb7ff, 0x7e5a, 0x2009, 0x0083,
-	0xd69c, 0x0110, 0x2009, 0x0082, 0x791a, 0x68c0, 0x7056, 0x2d00,
-	0x704a, 0x68c4, 0x2060, 0x71d0, 0x2001, 0x4601, 0x2004, 0xd0c4,
-	0x15c8, 0x70d4, 0xa02d, 0x01b8, 0xd1bc, 0x0548, 0x7a80, 0xa294,
-	0x0f00, 0x70d8, 0xa206, 0x0118, 0x78e0, 0xa504, 0x1558, 0x70d6,
-	0xc1bc, 0x71d2, 0x0438, 0x2031, 0x0001, 0x852c, 0x0218, 0x8633,
-	0x8210, 0x0cd8, 0x0005, 0x7de0, 0xa594, 0xff00, 0x0130, 0x2011,
-	0x0008, 0x852f, 0x0c81, 0x8637, 0x0008, 0x0c69, 0x8217, 0x7880,
-	0xa084, 0x0f00, 0xa206, 0x0170, 0x72da, 0x76d6, 0x0058, 0x7a80,
-	0xa294, 0x0f00, 0x70d8, 0xa236, 0x0dc0, 0x78e0, 0xa534, 0x0da8,
-	0xc1bd, 0x71d2, 0xd1b4, 0x1904, 0x259d, 0x2300, 0xa405, 0x0904,
-	0x259d, 0x70a0, 0xa086, 0x0001, 0x1904, 0x25e1, 0x0005, 0x6020,
-	0xa005, 0x0150, 0x8001, 0x6022, 0x6008, 0xa085, 0x0008, 0x600a,
-	0x700f, 0x0100, 0x702c, 0x6026, 0x0005, 0xa006, 0x080c, 0x3f26,
-	0x7000, 0xa086, 0x0002, 0x0120, 0x7060, 0xa086, 0x0005, 0x1150,
-	0x682b, 0x0000, 0x6817, 0x0000, 0x681b, 0x0001, 0x6823, 0x0040,
-	0x681f, 0x0100, 0x7000, 0xa084, 0x000f, 0x0002, 0x25a0, 0x3783,
-	0x3780, 0x37a0, 0x378c, 0x25a0, 0x377e, 0x377e, 0x080c, 0x254c,
-	0x0449, 0x0411, 0x0028, 0x0431, 0x7058, 0x2060, 0x6800, 0x6002,
-	0x080c, 0x1da2, 0x0804, 0x25a0, 0x7060, 0x7063, 0x0000, 0x707f,
-	0x0000, 0x0002, 0x379c, 0x379c, 0x379a, 0x379a, 0x379a, 0x379c,
-	0x379a, 0x379c, 0x0804, 0x2a6b, 0x7063, 0x0000, 0x0804, 0x25a0,
-	0x681b, 0x0000, 0x0804, 0x3184, 0x6800, 0xa005, 0x1108, 0x6002,
-	0x6006, 0x0005, 0x6410, 0x84ff, 0x0168, 0x2009, 0x4602, 0x2104,
-	0x8001, 0x200a, 0x8421, 0x6412, 0x1128, 0x2021, 0x4604, 0x2404,
-	0xc0a5, 0x2022, 0x6008, 0xc0a4, 0x600a, 0x0005, 0x6018, 0xa005,
-	0x0110, 0x8001, 0x601a, 0x0005, 0x080c, 0x3c46, 0x681b, 0x0018,
-	0x0490, 0x080c, 0x3c46, 0x681b, 0x0019, 0x0468, 0x080c, 0x3c46,
-	0x681b, 0x001a, 0x0440, 0x080c, 0x3c46, 0x681b, 0x0003, 0x0418,
-	0x7770, 0x080c, 0x3b6f, 0x7174, 0xa18c, 0x00ff, 0x3210, 0xa294,
-	0x0600, 0x0118, 0xa1e8, 0x8bc0, 0x0010, 0xa1e8, 0x8cd0, 0x2d04,
-	0x2d08, 0x2068, 0xa005, 0x1118, 0x707a, 0x0804, 0x25a0, 0x6814,
-	0x7270, 0xa206, 0x0110, 0x6800, 0x0c98, 0x6800, 0x200a, 0x681b,
-	0x0005, 0x707b, 0x0000, 0x080c, 0x37aa, 0x6820, 0xd084, 0x1110,
-	0x080c, 0x37a4, 0x080c, 0x37be, 0x681f, 0x0000, 0x6823, 0x0020,
-	0x080c, 0x1da2, 0x0804, 0x25a0, 0xa282, 0x0003, 0x1904, 0x3a10,
-	0x7da8, 0xa5ac, 0x00ff, 0x7ea8, 0xa6b4, 0x00ff, 0x6920, 0xc1bd,
-	0x6922, 0xd1c4, 0x05b0, 0xc1c4, 0x6922, 0xa6b4, 0x00ff, 0x0530,
-	0xa682, 0x0018, 0x0218, 0x0110, 0x2031, 0x0018, 0xa686, 0x0010,
-	0x1108, 0x8630, 0x852b, 0x852b, 0x2041, 0x0000, 0x080c, 0x3ac9,
-	0x0118, 0x080c, 0x38f7, 0x00a0, 0x080c, 0x3a95, 0x080c, 0x38f4,
-	0x6920, 0xc1c5, 0x6922, 0x7e58, 0xc695, 0x7e5a, 0xd6d4, 0x1118,
-	0x781b, 0x006e, 0x0005, 0x781b, 0x0082, 0x0005, 0x080c, 0x38f4,
+	0x0010, 0x2001, 0x0001, 0x0002, 0x3c0b, 0x3c0b, 0x345c, 0x3c0b,
+	0x3c4f, 0x3c4f, 0x3c0b, 0x3c0b, 0xd6bc, 0x0570, 0x7180, 0x81ff,
+	0x0558, 0xa182, 0x000d, 0x1318, 0x7083, 0x0000, 0x0028, 0xa182,
+	0x000c, 0x7082, 0x2009, 0x000c, 0x789b, 0x0061, 0x79aa, 0x0156,
+	0x0136, 0x0146, 0x7084, 0x8114, 0xa210, 0x7286, 0xa080, 0x000b,
+	0xad00, 0x2098, 0xb284, 0x0600, 0x0118, 0x20a1, 0x022b, 0x0010,
+	0x20a1, 0x012b, 0x789b, 0x0000, 0x8108, 0x81ac, 0x53a6, 0x014e,
+	0x013e, 0x015e, 0x0804, 0x3c11, 0xd6d4, 0x1904, 0x34cf, 0x6820,
+	0xd084, 0x0904, 0x3c11, 0xa68c, 0x0060, 0xa684, 0x0060, 0x0120,
+	0xa086, 0x0060, 0x1108, 0xc1f5, 0xc194, 0x795a, 0x69b6, 0x789b,
+	0x0060, 0x78ab, 0x0000, 0x789b, 0x0061, 0x6818, 0xc0fd, 0x681a,
+	0x78aa, 0x8008, 0x810c, 0x0904, 0x37f6, 0xa18c, 0x00f8, 0x1904,
+	0x37f6, 0x0156, 0x0136, 0x0146, 0x0016, 0x20a1, 0x012b, 0x3208,
+	0xa18c, 0x0600, 0x0110, 0x20a1, 0x022b, 0x001e, 0x789b, 0x0000,
+	0x8000, 0x80ac, 0xad80, 0x000b, 0x2098, 0x53a6, 0x014e, 0x013e,
+	0x015e, 0x6814, 0xc0fc, 0x8007, 0x7882, 0x0804, 0x3c11, 0x6818,
+	0xd0fc, 0x0110, 0x681b, 0x0008, 0x080c, 0x3a61, 0x781b, 0x00ed,
+	0x0005, 0x2300, 0x0002, 0x34e0, 0x359d, 0x34de, 0x080c, 0x2575,
+	0x7cd8, 0x7ddc, 0x7fd0, 0x82ff, 0x1528, 0x7200, 0xa286, 0x0003,
+	0x0904, 0x2f09, 0x71d0, 0xd1bc, 0x11f8, 0xd1b4, 0x01e8, 0x2001,
+	0x4701, 0x2004, 0xd0c4, 0x11c0, 0x00d6, 0x783b, 0x8800, 0x781b,
+	0x0059, 0x70b8, 0xa06d, 0x68b4, 0xc0a5, 0x785a, 0x6894, 0x78d6,
+	0x78de, 0x6898, 0x78d2, 0x78da, 0xc1b4, 0x71d2, 0x7003, 0x0030,
+	0x00de, 0x0030, 0x7200, 0x0020, 0x783b, 0x1800, 0x781b, 0x0057,
+	0xa284, 0x000f, 0x0002, 0x3588, 0x3545, 0x351d, 0x2f38, 0x351b,
+	0x3588, 0x351b, 0x351b, 0x080c, 0x2575, 0x681c, 0xd0ec, 0x0118,
+	0x6008, 0xc08d, 0x600a, 0x6920, 0xc185, 0x6922, 0x6800, 0x6006,
+	0xa005, 0x1108, 0x6002, 0x6008, 0xc0d4, 0x600a, 0x681c, 0xa084,
+	0x000e, 0x1120, 0x71c8, 0xa188, 0x0100, 0x0028, 0x7030, 0x68ba,
+	0x713c, 0x70c8, 0xa108, 0x2104, 0x6802, 0x2d0a, 0x715a, 0xd6dc,
+	0x1120, 0xc6fc, 0x6eb6, 0x0804, 0x3588, 0x6eb6, 0xa684, 0x0060,
+	0x1120, 0xa684, 0x7fff, 0x68b6, 0x04d8, 0xd6dc, 0x1150, 0xa684,
+	0x7fff, 0x68b6, 0x6894, 0x68a6, 0x6898, 0x68aa, 0x080c, 0x3f4e,
+	0x0478, 0xd6ac, 0x0140, 0xa006, 0x080c, 0x3f4e, 0x2408, 0x2510,
+	0x69aa, 0x6aa6, 0x0068, 0x2408, 0x2510, 0x2700, 0x8007, 0xa084,
+	0x007f, 0xa108, 0xa291, 0x0000, 0x69aa, 0x6aa6, 0x080c, 0x3f4e,
+	0xd6fc, 0x01b0, 0xa684, 0x7fff, 0x68b6, 0x2510, 0x2408, 0xd6ac,
+	0x1138, 0x2700, 0x8007, 0xa084, 0x007f, 0xa108, 0xa291, 0x0000,
+	0x6b98, 0x2100, 0xa302, 0x68b2, 0x6b94, 0x2200, 0xa303, 0x68ae,
+	0x7000, 0xa086, 0x0030, 0x1904, 0x25c9, 0x7003, 0x0002, 0x70b8,
+	0xa06d, 0x68bc, 0x703e, 0x70b4, 0xa065, 0x68c0, 0x7056, 0x2d00,
+	0x704a, 0xad80, 0x0009, 0x7042, 0x0005, 0xa586, 0x8800, 0x1148,
+	0x7003, 0x0000, 0x6018, 0x8001, 0x601a, 0x6008, 0xa084, 0xfbef,
+	0x600a, 0x0804, 0x3a5b, 0x7043, 0x0000, 0xa282, 0x0006, 0x0310,
+	0x080c, 0x2575, 0x2300, 0x0002, 0x35b7, 0x35c8, 0x35d2, 0x2200,
+	0x0002, 0x35bf, 0x3a5b, 0x35c1, 0x35bf, 0x3603, 0x3651, 0x080c,
+	0x2575, 0x7a80, 0xa294, 0x0f00, 0x080c, 0x36a5, 0x0804, 0x3a30,
+	0x00c1, 0x0002, 0x3a5b, 0x35d0, 0x35d0, 0x3603, 0x35d0, 0x3a5b,
+	0x080c, 0x2575, 0x0071, 0x0002, 0x35dc, 0x35da, 0x35da, 0x35dc,
+	0x35da, 0x35dc, 0x080c, 0x2575, 0x080c, 0x3a70, 0x781b, 0x0082,
+	0x0005, 0x7000, 0xa086, 0x0002, 0x1150, 0x080c, 0x37e1, 0x0010,
+	0x080c, 0x3f4e, 0x6008, 0xa084, 0xfbef, 0x600a, 0x0020, 0x7000,
+	0xa086, 0x0003, 0x0da8, 0x7003, 0x0005, 0x2001, 0x8ee0, 0xae8e,
+	0x4740, 0x0110, 0x2001, 0x8f12, 0x2068, 0x704a, 0xad80, 0x0009,
+	0x7042, 0x2200, 0x0005, 0x7000, 0xa086, 0x0002, 0x1158, 0x70d0,
+	0xc0b5, 0x70d2, 0x2c00, 0x70b6, 0x2d00, 0x70ba, 0x0038, 0x080c,
+	0x3f4e, 0x0020, 0x7000, 0xa086, 0x0003, 0x0dc8, 0x7003, 0x0001,
+	0x7a80, 0xa294, 0x0f00, 0x789b, 0x0018, 0x7ca8, 0xa484, 0x001f,
+	0xa215, 0x2069, 0x8dc0, 0xb284, 0x0600, 0x1118, 0xc2fd, 0x2069,
+	0x8ed0, 0x2d04, 0x2d08, 0x715a, 0xa06d, 0x0128, 0x6814, 0xa206,
+	0x0120, 0x6800, 0x0cb8, 0x080c, 0x36a5, 0x6eb4, 0x7e5a, 0x6920,
+	0xa184, 0x0c00, 0x0904, 0x36cb, 0x7060, 0xa086, 0x0006, 0x1128,
+	0x7070, 0xa206, 0x1110, 0x7062, 0x707a, 0x681b, 0x0005, 0xc1ad,
+	0x681b, 0x0005, 0xc1ad, 0xc1d4, 0x6922, 0x080c, 0x3a67, 0x0804,
+	0x36cb, 0x7200, 0xa286, 0x0002, 0x1158, 0x70d0, 0xc0b5, 0x70d2,
+	0x2c00, 0x70b6, 0x2d00, 0x70ba, 0x0030, 0x080c, 0x3f4e, 0x0018,
+	0xa286, 0x0003, 0x0dd0, 0x7003, 0x0001, 0x7a80, 0xa294, 0x0f00,
+	0x789b, 0x0018, 0x7ca8, 0xa484, 0x001f, 0xa215, 0xae86, 0x4740,
+	0x0108, 0xc2fd, 0x79a8, 0x79a8, 0xa18c, 0x00ff, 0x2118, 0x70c8,
+	0xa168, 0x2d04, 0x2d08, 0x715a, 0xa06d, 0x0128, 0x6814, 0xa206,
+	0x0118, 0x6800, 0x0cb8, 0x0409, 0x6eb4, 0x6920, 0xa184, 0x0c00,
+	0x0904, 0x36cb, 0xd0dc, 0x0178, 0x7060, 0xa086, 0x0004, 0x1140,
+	0x7070, 0xa206, 0x1128, 0x7074, 0xa306, 0x1110, 0x7062, 0x707a,
+	0x080c, 0x3a6d, 0x0480, 0x681b, 0x0005, 0xc1ad, 0xc1d4, 0x6922,
+	0x080c, 0x3a67, 0x707b, 0x0000, 0x0430, 0x7003, 0x0005, 0xb284,
+	0x0600, 0x0118, 0x2001, 0x8ee0, 0x0010, 0x2001, 0x8f12, 0x2068,
+	0x704a, 0x0156, 0x20a9, 0x0032, 0x2003, 0x0000, 0x8000, 0x1f04,
+	0x36b4, 0x015e, 0xb284, 0x0600, 0x0110, 0xc2fc, 0x0008, 0xc2fd,
+	0x6a16, 0xad80, 0x0009, 0x7042, 0x68b7, 0x0700, 0x6823, 0x0800,
+	0x6827, 0x0003, 0x0005, 0xc6ec, 0xa6ac, 0x0060, 0x0904, 0x3712,
+	0x6b98, 0x6c94, 0x69ac, 0x68b0, 0xa105, 0x11e0, 0x7bd2, 0x7bda,
+	0x7cd6, 0x7cde, 0xa586, 0x0060, 0x05c8, 0xd6f4, 0x1108, 0xc6ed,
+	0xa6b4, 0xb7ff, 0x7e5a, 0x2009, 0x0083, 0xd69c, 0x0128, 0x2009,
+	0x0082, 0x2019, 0x0000, 0x2320, 0x791a, 0xd6ec, 0x0588, 0x080c,
+	0x4208, 0x0470, 0x68b0, 0xa31a, 0x2100, 0xa423, 0x2400, 0xa305,
+	0x01f8, 0x7bd2, 0x7bda, 0x7cd6, 0x7cde, 0x68b0, 0xd6f4, 0x1108,
+	0xc6ed, 0xc6f4, 0x7e5a, 0x2011, 0x0083, 0xd69c, 0x0128, 0x2011,
+	0x0082, 0x2019, 0x0000, 0x2320, 0x7a1a, 0xd6ec, 0x0188, 0x080c,
+	0x4235, 0x0070, 0x2019, 0x0000, 0x2320, 0x0010, 0xa6b4, 0xb7ff,
+	0x7e5a, 0x2009, 0x0083, 0xd69c, 0x0110, 0x2009, 0x0082, 0x791a,
+	0x68c0, 0x7056, 0x2d00, 0x704a, 0x68c4, 0x2060, 0x71d0, 0x2001,
+	0x4701, 0x2004, 0xd0c4, 0x15c8, 0x70d4, 0xa02d, 0x01b8, 0xd1bc,
+	0x0548, 0x7a80, 0xa294, 0x0f00, 0x70d8, 0xa206, 0x0118, 0x78e0,
+	0xa504, 0x1558, 0x70d6, 0xc1bc, 0x71d2, 0x0438, 0x2031, 0x0001,
+	0x852c, 0x0218, 0x8633, 0x8210, 0x0cd8, 0x0005, 0x7de0, 0xa594,
+	0xff00, 0x0130, 0x2011, 0x0008, 0x852f, 0x0c81, 0x8637, 0x0008,
+	0x0c69, 0x8217, 0x7880, 0xa084, 0x0f00, 0xa206, 0x0170, 0x72da,
+	0x76d6, 0x0058, 0x7a80, 0xa294, 0x0f00, 0x70d8, 0xa236, 0x0dc0,
+	0x78e0, 0xa534, 0x0da8, 0xc1bd, 0x71d2, 0xd1b4, 0x1904, 0x25c6,
+	0x2300, 0xa405, 0x0904, 0x25c6, 0x70a0, 0xa086, 0x0001, 0x1904,
+	0x260d, 0x0005, 0x6020, 0xa005, 0x0150, 0x8001, 0x6022, 0x6008,
+	0xa085, 0x0008, 0x600a, 0x700f, 0x0100, 0x702c, 0x6026, 0x0005,
+	0xa006, 0x080c, 0x3f4e, 0x7000, 0xa086, 0x0002, 0x0120, 0x7060,
+	0xa086, 0x0005, 0x1150, 0x682b, 0x0000, 0x6817, 0x0000, 0x681b,
+	0x0001, 0x6823, 0x0040, 0x681f, 0x0100, 0x7000, 0xa084, 0x000f,
+	0x0002, 0x25c9, 0x37a6, 0x37a3, 0x37c3, 0x37af, 0x25c9, 0x37a1,
+	0x37a1, 0x080c, 0x2575, 0x0449, 0x0411, 0x0028, 0x0431, 0x7058,
+	0x2060, 0x6800, 0x6002, 0x080c, 0x1dbf, 0x0804, 0x25c9, 0x7060,
+	0x7063, 0x0000, 0x707f, 0x0000, 0x0002, 0x37bf, 0x37bf, 0x37bd,
+	0x37bd, 0x37bd, 0x37bf, 0x37bd, 0x37bf, 0x0804, 0x2a9a, 0x7063,
+	0x0000, 0x0804, 0x25c9, 0x681b, 0x0000, 0x0804, 0x31a7, 0x6800,
+	0xa005, 0x1108, 0x6002, 0x6006, 0x0005, 0x6410, 0x84ff, 0x0168,
+	0x2009, 0x4702, 0x2104, 0x8001, 0x200a, 0x8421, 0x6412, 0x1128,
+	0x2021, 0x4704, 0x2404, 0xc0a5, 0x2022, 0x6008, 0xc0a4, 0x600a,
+	0x0005, 0x6018, 0xa005, 0x0110, 0x8001, 0x601a, 0x0005, 0x080c,
+	0x3c6e, 0x681b, 0x0018, 0x0490, 0x080c, 0x3c6e, 0x681b, 0x0019,
+	0x0468, 0x080c, 0x3c6e, 0x681b, 0x001a, 0x0440, 0x080c, 0x3c6e,
+	0x681b, 0x0003, 0x0418, 0x7770, 0x080c, 0x3b95, 0x7174, 0xa18c,
+	0x00ff, 0x3210, 0xa294, 0x0600, 0x0118, 0xa1e8, 0x8cc0, 0x0010,
+	0xa1e8, 0x8dd0, 0x2d04, 0x2d08, 0x2068, 0xa005, 0x1118, 0x707a,
+	0x0804, 0x25c9, 0x6814, 0x7270, 0xa206, 0x0110, 0x6800, 0x0c98,
+	0x6800, 0x200a, 0x681b, 0x0005, 0x707b, 0x0000, 0x080c, 0x37cd,
+	0x6820, 0xd084, 0x1110, 0x080c, 0x37c7, 0x080c, 0x37e1, 0x681f,
+	0x0000, 0x6823, 0x0020, 0x080c, 0x1dbf, 0x0804, 0x25c9, 0xa282,
+	0x0003, 0x1904, 0x3a35, 0x7da8, 0xa5ac, 0x00ff, 0x7ea8, 0xa6b4,
+	0x00ff, 0x6920, 0xc1bd, 0x6922, 0xd1c4, 0x05b0, 0xc1c4, 0x6922,
+	0xa6b4, 0x00ff, 0x0530, 0xa682, 0x0018, 0x0218, 0x0110, 0x2031,
+	0x0018, 0xa686, 0x0010, 0x1108, 0x8630, 0x852b, 0x852b, 0x2041,
+	0x0000, 0x080c, 0x3aee, 0x0118, 0x080c, 0x391a, 0x00a0, 0x080c,
+	0x3aba, 0x080c, 0x3917, 0x6920, 0xc1c5, 0x6922, 0x7e58, 0xc695,
+	0x7e5a, 0xd6d4, 0x1118, 0x781b, 0x006e, 0x0005, 0x781b, 0x0082,
+	0x0005, 0x080c, 0x3917, 0x7e58, 0xd6d4, 0x1118, 0x781b, 0x0071,
+	0x0005, 0x781b, 0x0083, 0x0005, 0x00c6, 0x7054, 0x2060, 0x6100,
+	0xd1e4, 0x0598, 0x6208, 0x8217, 0xa294, 0x00ff, 0xa282, 0x0018,
+	0x0218, 0x0110, 0x2011, 0x0018, 0x2600, 0xa202, 0x1208, 0x2230,
+	0xa686, 0x0010, 0x1108, 0x8630, 0x6208, 0xa294, 0x00ff, 0x78ec,
+	0xd0e4, 0x0130, 0xa282, 0x000a, 0x1240, 0x2011, 0x000a, 0x0028,
+	0xa282, 0x000c, 0x1210, 0x2011, 0x000c, 0x2200, 0xa502, 0x1208,
+	0x2228, 0x080c, 0x3abe, 0x852b, 0x852b, 0x2041, 0x0000, 0x080c,
+	0x3aee, 0x0118, 0x080c, 0x391a, 0x0020, 0x080c, 0x3aba, 0x080c,
+	0x3917, 0x7858, 0xc095, 0x785a, 0x00ce, 0x781b, 0x0082, 0x0005,
+	0x00c6, 0x2960, 0x6000, 0xd0e4, 0x1188, 0xd0b4, 0x1150, 0x6010,
+	0xa084, 0x000f, 0x1130, 0x6104, 0xa18c, 0xfff5, 0x6106, 0x00ce,
+	0x0005, 0x2011, 0x0032, 0x2019, 0x0000, 0x00f0, 0x68a0, 0xd0cc,
+	0x1dc0, 0x6208, 0xa294, 0x00ff, 0x78ec, 0xd0e4, 0x0130, 0xa282,
+	0x000b, 0x1218, 0x2011, 0x000a, 0x0028, 0xa282, 0x000c, 0x1210,
+	0x2011, 0x000c, 0x6308, 0x831f, 0xa39c, 0x00ff, 0xa382, 0x0018,
+	0x0218, 0x0110, 0x2019, 0x0018, 0x78ab, 0x0001, 0x78ab, 0x0003,
+	0x78ab, 0x0001, 0x7aaa, 0x7baa, 0xa8c0, 0x0005, 0x6820, 0xc0c5,
+	0x6822, 0x080c, 0x3a7a, 0x00ce, 0x0005, 0x00c6, 0x2960, 0x6104,
+	0xa18c, 0xfff5, 0x6106, 0x2011, 0x0032, 0x2019, 0x0000, 0x0000,
+	0x78ab, 0x0001, 0x78ab, 0x0003, 0x78ab, 0x0001, 0x7aaa, 0x7baa,
+	0xa8c0, 0x0005, 0x6820, 0xc0c5, 0x6822, 0x00ce, 0x0005, 0xa006,
+	0x2030, 0x2010, 0x00c6, 0x7154, 0x2160, 0x2018, 0x2008, 0xa084,
+	0xffe0, 0xa635, 0x7e86, 0x6018, 0x789a, 0x7eae, 0x6612, 0x78a4,
+	0xa084, 0x7770, 0xa18c, 0x000f, 0xa105, 0x2029, 0x4705, 0x252c,
+	0xd5cc, 0x0140, 0xd3a4, 0x0110, 0xa085, 0x0800, 0xd3fc, 0x0110,
+	0xa085, 0x8080, 0x78a6, 0x6016, 0x788a, 0xa6b4, 0x001f, 0x8637,
+	0x8204, 0x8004, 0xa605, 0x600e, 0x6004, 0xa084, 0xffd5, 0x6006,
+	0x00ce, 0x0005, 0xa282, 0x0002, 0x1904, 0x3a3f, 0x7aa8, 0x6920,
+	0xc1bd, 0x6922, 0xd1cc, 0x0568, 0xc1cc, 0x6922, 0xa294, 0x00ff,
+	0xa282, 0x0002, 0x1a04, 0x3a30, 0x080c, 0x39c1, 0x080c, 0x3917,
+	0xa980, 0x0001, 0x200c, 0x080c, 0x3b91, 0x080c, 0x38b8, 0x88ff,
+	0x0178, 0x789b, 0x0060, 0x2800, 0x78aa, 0x7e58, 0xc695, 0x7e5a,
+	0xd6d4, 0x1118, 0x781b, 0x006e, 0x0005, 0x781b, 0x0082, 0x0005,
 	0x7e58, 0xd6d4, 0x1118, 0x781b, 0x0071, 0x0005, 0x781b, 0x0083,
-	0x0005, 0x00c6, 0x7054, 0x2060, 0x6100, 0xd1e4, 0x0598, 0x6208,
-	0x8217, 0xa294, 0x00ff, 0xa282, 0x0018, 0x0218, 0x0110, 0x2011,
-	0x0018, 0x2600, 0xa202, 0x1208, 0x2230, 0xa686, 0x0010, 0x1108,
-	0x8630, 0x6208, 0xa294, 0x00ff, 0x78ec, 0xd0e4, 0x0130, 0xa282,
-	0x000a, 0x1240, 0x2011, 0x000a, 0x0028, 0xa282, 0x000c, 0x1210,
-	0x2011, 0x000c, 0x2200, 0xa502, 0x1208, 0x2228, 0x080c, 0x3a99,
-	0x852b, 0x852b, 0x2041, 0x0000, 0x080c, 0x3ac9, 0x0118, 0x080c,
-	0x38f7, 0x0020, 0x080c, 0x3a95, 0x080c, 0x38f4, 0x7858, 0xc095,
-	0x785a, 0x00ce, 0x781b, 0x0082, 0x0005, 0x00c6, 0x2960, 0x6000,
-	0xd0e4, 0x1188, 0xd0b4, 0x1150, 0x6010, 0xa084, 0x000f, 0x1130,
-	0x6104, 0xa18c, 0xfff5, 0x6106, 0x00ce, 0x0005, 0x2011, 0x0032,
-	0x2019, 0x0000, 0x00f0, 0x68a0, 0xd0cc, 0x1dc0, 0x6208, 0xa294,
-	0x00ff, 0x78ec, 0xd0e4, 0x0130, 0xa282, 0x000b, 0x1218, 0x2011,
-	0x000a, 0x0028, 0xa282, 0x000c, 0x1210, 0x2011, 0x000c, 0x6308,
-	0x831f, 0xa39c, 0x00ff, 0xa382, 0x0018, 0x0218, 0x0110, 0x2019,
-	0x0018, 0x78ab, 0x0001, 0x78ab, 0x0003, 0x78ab, 0x0001, 0x7aaa,
-	0x7baa, 0xa8c0, 0x0005, 0x6820, 0xc0c5, 0x6822, 0x080c, 0x3a55,
-	0x00ce, 0x0005, 0x00c6, 0x2960, 0x6104, 0xa18c, 0xfff5, 0x6106,
-	0x2011, 0x0032, 0x2019, 0x0000, 0x0000, 0x78ab, 0x0001, 0x78ab,
-	0x0003, 0x78ab, 0x0001, 0x7aaa, 0x7baa, 0xa8c0, 0x0005, 0x6820,
-	0xc0c5, 0x6822, 0x00ce, 0x0005, 0xa006, 0x2030, 0x2010, 0x00c6,
-	0x7154, 0x2160, 0x2018, 0x2008, 0xa084, 0xffe0, 0xa635, 0x7e86,
-	0x6018, 0x789a, 0x7eae, 0x6612, 0x78a4, 0xa084, 0x7770, 0xa18c,
-	0x000f, 0xa105, 0x2029, 0x4605, 0x252c, 0xd5cc, 0x0140, 0xd3a4,
-	0x0110, 0xa085, 0x0800, 0xd3fc, 0x0110, 0xa085, 0x8080, 0x78a6,
-	0x6016, 0x788a, 0xa6b4, 0x001f, 0x8637, 0x8204, 0x8004, 0xa605,
-	0x600e, 0x6004, 0xa084, 0xffd5, 0x6006, 0x00ce, 0x0005, 0xa282,
-	0x0002, 0x1904, 0x3a1a, 0x7aa8, 0x6920, 0xc1bd, 0x6922, 0xd1cc,
-	0x0568, 0xc1cc, 0x6922, 0xa294, 0x00ff, 0xa282, 0x0002, 0x1a04,
-	0x3a0b, 0x080c, 0x399e, 0x080c, 0x38f4, 0xa980, 0x0001, 0x200c,
-	0x080c, 0x3b6b, 0x080c, 0x3895, 0x88ff, 0x0178, 0x789b, 0x0060,
-	0x2800, 0x78aa, 0x7e58, 0xc695, 0x7e5a, 0xd6d4, 0x1118, 0x781b,
-	0x006e, 0x0005, 0x781b, 0x0082, 0x0005, 0x7e58, 0xd6d4, 0x1118,
-	0x781b, 0x0071, 0x0005, 0x781b, 0x0083, 0x0005, 0xa282, 0x0002,
-	0x1218, 0xa284, 0x0001, 0x0140, 0x7154, 0xa188, 0x0000, 0x210c,
-	0xd1ec, 0x1110, 0x2011, 0x0000, 0x080c, 0x3a87, 0x0479, 0x080c,
-	0x38f4, 0x7858, 0xc095, 0x785a, 0x781b, 0x0082, 0x0005, 0x00c6,
-	0x0026, 0x2960, 0x6000, 0x2011, 0x0001, 0xd0ec, 0x1158, 0xd0bc,
-	0x1138, 0x6014, 0xd0b4, 0x1120, 0xc1a4, 0x6106, 0xa006, 0x0088,
-	0x2011, 0x0000, 0x78ab, 0x0001, 0x78ab, 0x0002, 0x78ab, 0x0003,
-	0x7aaa, 0xa8c0, 0x0004, 0x080c, 0x3a55, 0x6820, 0xa085, 0x0200,
-	0x6822, 0x002e, 0x00ce, 0x0005, 0x8807, 0xa715, 0x00c6, 0x2009,
-	0x0000, 0x7054, 0x2060, 0x82ff, 0x0110, 0x2009, 0x0040, 0x6018,
-	0xa080, 0x0002, 0x789a, 0x78a4, 0xa084, 0xff9f, 0xa105, 0xc0ec,
-	0xd0b4, 0x1108, 0xc0ed, 0x6100, 0xd1f4, 0x0110, 0xa085, 0x0020,
-	0x78a6, 0x6016, 0x788a, 0x6004, 0xa084, 0xffef, 0x6006, 0x00ce,
-	0x0005, 0x0006, 0x7000, 0xa086, 0x0003, 0x0110, 0x000e, 0x0010,
-	0x000e, 0x0488, 0xd6ac, 0x0578, 0x7888, 0xa084, 0x0040, 0x0558,
-	0x7bb8, 0x8307, 0xa084, 0x007f, 0x1508, 0x8207, 0xa084, 0x00ff,
-	0xa09e, 0x0001, 0x1904, 0x3a32, 0xd6f4, 0x11d0, 0x79d8, 0x7adc,
-	0xa108, 0xa291, 0x0000, 0x79d2, 0x79da, 0x7ad6, 0x7ade, 0x080c,
-	0x42b5, 0x781b, 0x0080, 0xb284, 0x0600, 0x0118, 0x2001, 0x0000,
-	0x0010, 0x2001, 0x0001, 0x080c, 0x4172, 0x0005, 0x080c, 0x254c,
-	0x781b, 0x0080, 0x0005, 0x781b, 0x0083, 0x0005, 0x2039, 0x0000,
-	0x2041, 0x0000, 0x2031, 0x0000, 0xa006, 0x2010, 0x080c, 0x38f7,
-	0x080c, 0x399c, 0x7e58, 0x080c, 0x3a4e, 0x781b, 0x0082, 0x0005,
-	0x0cd1, 0x6820, 0xc0c4, 0x6822, 0x00c6, 0x7054, 0x2060, 0x080c,
-	0x3921, 0x00b0, 0x0c81, 0x6820, 0xc0cc, 0x6822, 0x00c6, 0x7054,
-	0x2060, 0x080c, 0x39bb, 0x0060, 0x0c31, 0x6820, 0xa084, 0xecff,
-	0x6822, 0x00c6, 0x7054, 0x2060, 0x6004, 0xa084, 0xffc5, 0x6006,
-	0x00ce, 0x0005, 0x0049, 0x781b, 0x0082, 0x0005, 0x6827, 0x0002,
-	0x0049, 0x781b, 0x0082, 0x0005, 0x2001, 0x0005, 0x0088, 0x2001,
-	0x000c, 0x0070, 0x6820, 0xc0d5, 0x6822, 0x2001, 0x0006, 0x0040,
-	0x2001, 0x000d, 0x0028, 0x2001, 0x0009, 0x0010, 0x2001, 0x0007,
-	0x789b, 0x007e, 0x78aa, 0xc69d, 0x7e5a, 0x70d0, 0xd0b4, 0x0168,
-	0xc0b4, 0x70d2, 0x00c6, 0x70b4, 0xa065, 0x6008, 0xa084, 0xfbef,
-	0x600a, 0x6018, 0x8001, 0x601a, 0x00ce, 0x0005, 0x0076, 0x873f,
-	0xa7bc, 0x000f, 0x873b, 0x873b, 0x8703, 0xa0e0, 0x4ac0, 0xae8e,
-	0x4640, 0x0110, 0xa0e0, 0x4b40, 0xa7b8, 0x0020, 0x7f9a, 0x79a4,
-	0xa184, 0x7fe0, 0x78ae, 0x6012, 0x79a4, 0xa184, 0x773f, 0x78a6,
-	0x6016, 0x6004, 0xa085, 0x0038, 0x6006, 0x007e, 0x0005, 0x789b,
-	0x0080, 0x78ab, 0x0001, 0x78ab, 0x0002, 0x78ab, 0x0003, 0x7aaa,
-	0x789b, 0x0060, 0x78ab, 0x0004, 0x0800, 0x2031, 0x0000, 0x2029,
-	0x0032, 0x789b, 0x0080, 0x78ab, 0x0001, 0x78ab, 0x0003, 0x78ab,
-	0x0001, 0x7daa, 0x7eaa, 0x789b, 0x0060, 0x78ab, 0x0005, 0x0804,
-	0x3a55, 0x0156, 0x8007, 0xa084, 0x00ff, 0x8003, 0x8003, 0xa080,
-	0x0020, 0x789a, 0x79a4, 0xa18c, 0xffe0, 0x2021, 0x3b54, 0x2019,
-	0x0011, 0x20a9, 0x000e, 0x2011, 0x0032, 0x2404, 0xa084, 0xffe0,
-	0xa106, 0x0128, 0x8420, 0x2300, 0xa210, 0x1f04, 0x3abd, 0x015e,
-	0x0005, 0x0156, 0x04f8, 0x2021, 0x3b62, 0x20a9, 0x0009, 0x2011,
-	0x0029, 0xa582, 0x0028, 0x0550, 0x8420, 0x95a9, 0x2011, 0x0033,
-	0xa582, 0x0033, 0x0618, 0x8420, 0x95a9, 0x2019, 0x000a, 0x2011,
-	0x0065, 0x2200, 0xa502, 0x02d0, 0x8420, 0x2300, 0xa210, 0x1f04,
-	0x3ae1, 0x015e, 0x0088, 0x2021, 0x3b54, 0x2019, 0x0011, 0x20a9,
-	0x000e, 0x2011, 0x0033, 0x2200, 0xa502, 0x0240, 0x8420, 0x2300,
-	0xa210, 0x1f04, 0x3af3, 0x015e, 0xa006, 0x0005, 0x8211, 0x015e,
-	0xa582, 0x0064, 0x1220, 0x7808, 0xa085, 0x0070, 0x780a, 0x2404,
-	0xa005, 0x0005, 0xa886, 0x0002, 0x01e8, 0x2021, 0x3b40, 0x20a9,
-	0x000d, 0x2011, 0x0028, 0xa582, 0x0028, 0x0d48, 0x8420, 0x2019,
-	0x0019, 0x2011, 0x0033, 0x2200, 0xa502, 0x0e00, 0x8420, 0x2300,
-	0xa210, 0x1f04, 0x3b1b, 0x015e, 0x2011, 0x0184, 0xa582, 0x0185,
-	0x0ab0, 0x0890, 0x2021, 0x3b4f, 0x20a9, 0x0003, 0x2011, 0x0024,
-	0xa586, 0x0024, 0x0960, 0x8420, 0x2011, 0x0028, 0xa586, 0x0028,
-	0x0930, 0x8420, 0x2019, 0x0019, 0x2011, 0x0033, 0x0804, 0x3af3,
-	0x1021, 0x2202, 0x3403, 0x4604, 0x5805, 0x6a06, 0x7c07, 0x4610,
-	0x4612, 0x5812, 0x5a12, 0x6a14, 0x6c14, 0x6e14, 0x7e17, 0x9021,
-	0xb002, 0xe204, 0xe210, 0xe210, 0x1209, 0x3002, 0x3202, 0x4203,
-	0x4403, 0x5404, 0x5604, 0x6605, 0x6805, 0x7806, 0x7a06, 0x0c07,
-	0x0c07, 0x0e07, 0x10e1, 0x330a, 0x5805, 0x5a05, 0x6a06, 0x6c06,
-	0x7c07, 0x7e07, 0x0e00, 0x789b, 0x0080, 0xa046, 0x0005, 0xa784,
-	0x0f00, 0x800b, 0xa784, 0x001f, 0x8003, 0x8003, 0x8003, 0x8003,
-	0xa105, 0xd7fc, 0x0118, 0xa0e0, 0x6bc0, 0x0010, 0xa0e0, 0x4bc0,
-	0x0005, 0x00e6, 0x00f6, 0xd084, 0x0138, 0x2079, 0x0100, 0x2009,
-	0x4680, 0x2071, 0x4680, 0x0030, 0x2009, 0x4640, 0x2079, 0x0200,
-	0x2071, 0x4640, 0x2091, 0x8000, 0x2104, 0xa084, 0x000f, 0x0002,
-	0x3ba2, 0x3ba2, 0x3ba2, 0x3ba2, 0x3ba2, 0x3ba2, 0x3ba0, 0x3ba0,
-	0x080c, 0x254c, 0x69b4, 0xc1f5, 0xa18c, 0xff9f, 0x69b6, 0xa005,
-	0x0580, 0x7858, 0xa084, 0xff9f, 0xa085, 0x6000, 0x785a, 0x7828,
-	0xa086, 0x1814, 0x1530, 0x784b, 0x0004, 0x7848, 0xa084, 0x0004,
-	0x1de0, 0x784b, 0x0008, 0x7848, 0xa084, 0x0008, 0x1de0, 0x7830,
-	0xd0bc, 0x11b8, 0xb284, 0x0800, 0x0118, 0x0104, 0x3bd9, 0x0010,
-	0x0304, 0x3bd9, 0x79e4, 0xa184, 0x0030, 0x0158, 0x78ec, 0xa084,
-	0x0003, 0x0138, 0x681c, 0xd0ac, 0x1110, 0x00d9, 0x0010, 0x781b,
-	0x00fb, 0x00fe, 0x00ee, 0x0005, 0x2001, 0x4601, 0x2004, 0xd0ac,
-	0x1118, 0x6814, 0x080c, 0x2475, 0x0005, 0x781b, 0x0083, 0x0005,
-	0x781b, 0x0082, 0x0005, 0x781b, 0x0071, 0x0005, 0x781b, 0x006e,
-	0x0005, 0x2009, 0x4619, 0x210c, 0xa186, 0x0000, 0x0150, 0xa186,
-	0x0001, 0x0150, 0x701f, 0x000b, 0x7063, 0x0001, 0x781b, 0x0054,
-	0x0005, 0x781b, 0x00f3, 0x0005, 0x701f, 0x000a, 0x0005, 0x2009,
-	0x4619, 0x210c, 0xa186, 0x0000, 0x0168, 0xa186, 0x0001, 0x0138,
-	0x701f, 0x000b, 0x7063, 0x0001, 0x781b, 0x0054, 0x0005, 0x701f,
-	0x000a, 0x0005, 0x781b, 0x00f2, 0x0005, 0x781b, 0x00fb, 0x0005,
-	0x781b, 0x00fa, 0x0005, 0x781b, 0x00cc, 0x0005, 0x781b, 0x00cb,
-	0x0005, 0x6818, 0xd0fc, 0x0110, 0x681b, 0x001d, 0x7063, 0x0001,
+	0x0005, 0xa282, 0x0002, 0x1218, 0xa284, 0x0001, 0x0140, 0x7154,
+	0xa188, 0x0000, 0x210c, 0xd1ec, 0x1110, 0x2011, 0x0000, 0x080c,
+	0x3aac, 0x0479, 0x080c, 0x3917, 0x7858, 0xc095, 0x785a, 0x781b,
+	0x0082, 0x0005, 0x00c6, 0x0026, 0x2960, 0x6000, 0x2011, 0x0001,
+	0xd0ec, 0x1158, 0xd0bc, 0x1138, 0x6014, 0xd0b4, 0x1120, 0xc1a4,
+	0x6106, 0xa006, 0x0088, 0x2011, 0x0000, 0x78ab, 0x0001, 0x78ab,
+	0x0002, 0x78ab, 0x0003, 0x7aaa, 0xa8c0, 0x0004, 0x080c, 0x3a7a,
+	0x6820, 0xa085, 0x0200, 0x6822, 0x002e, 0x00ce, 0x0005, 0x8807,
+	0xa715, 0x00c6, 0x2009, 0x0000, 0x7054, 0x2060, 0x82ff, 0x0110,
+	0x2009, 0x0040, 0x6018, 0xa080, 0x0002, 0x789a, 0x78a4, 0xa084,
+	0xff9f, 0xa105, 0xc0ec, 0xd0b4, 0x1108, 0xc0ed, 0x6100, 0xd1f4,
+	0x0110, 0xa085, 0x0020, 0x78a6, 0x6016, 0x788a, 0x6004, 0xa084,
+	0xffef, 0x6006, 0x00ce, 0x0005, 0x0006, 0x7000, 0xa086, 0x0003,
+	0x0110, 0x000e, 0x0010, 0x000e, 0x0498, 0xd6ac, 0x0588, 0x7888,
+	0xa084, 0x0040, 0x0568, 0x7bb8, 0x8307, 0xa084, 0x007f, 0x1518,
+	0x8207, 0xa084, 0x00ff, 0x0904, 0x3a57, 0xa09a, 0x0004, 0x1a04,
+	0x3a57, 0xd6f4, 0x11d0, 0x79d8, 0x7adc, 0xa108, 0xa291, 0x0000,
+	0x79d2, 0x79da, 0x7ad6, 0x7ade, 0x080c, 0x42e8, 0x781b, 0x0080,
+	0xb284, 0x0600, 0x0118, 0x2001, 0x0000, 0x0010, 0x2001, 0x0001,
+	0x080c, 0x419a, 0x0005, 0x080c, 0x2575, 0x781b, 0x0080, 0x0005,
+	0x781b, 0x0083, 0x0005, 0x2039, 0x0000, 0x2041, 0x0000, 0x2031,
+	0x0000, 0xa006, 0x2010, 0x080c, 0x391a, 0x080c, 0x39bf, 0x7e58,
+	0x080c, 0x3a73, 0x781b, 0x0082, 0x0005, 0x0cd1, 0x6820, 0xc0c4,
+	0x6822, 0x00c6, 0x7054, 0x2060, 0x080c, 0x3944, 0x00b0, 0x0c81,
+	0x6820, 0xc0cc, 0x6822, 0x00c6, 0x7054, 0x2060, 0x080c, 0x39de,
+	0x0060, 0x0c31, 0x6820, 0xa084, 0xecff, 0x6822, 0x00c6, 0x7054,
+	0x2060, 0x6004, 0xa084, 0xffc5, 0x6006, 0x00ce, 0x0005, 0x0049,
+	0x781b, 0x0082, 0x0005, 0x6827, 0x0002, 0x0049, 0x781b, 0x0082,
+	0x0005, 0x2001, 0x0005, 0x0088, 0x2001, 0x000c, 0x0070, 0x6820,
+	0xc0d5, 0x6822, 0x2001, 0x0006, 0x0040, 0x2001, 0x000d, 0x0028,
+	0x2001, 0x0009, 0x0010, 0x2001, 0x0007, 0x789b, 0x007e, 0x78aa,
+	0xc69d, 0x7e5a, 0x70d0, 0xd0b4, 0x0168, 0xc0b4, 0x70d2, 0x00c6,
+	0x70b4, 0xa065, 0x6008, 0xa084, 0xfbef, 0x600a, 0x6018, 0x8001,
+	0x601a, 0x00ce, 0x0005, 0x0076, 0x873f, 0xa7bc, 0x000f, 0x873b,
+	0x873b, 0x8703, 0xa0e0, 0x4bc0, 0xae8e, 0x4740, 0x0110, 0xa0e0,
+	0x4c40, 0xa7b8, 0x0020, 0x7f9a, 0x79a4, 0xa184, 0x7fe0, 0x78ae,
+	0x6012, 0x79a4, 0xa184, 0x773f, 0x78a6, 0x6016, 0x6004, 0xa085,
+	0x0038, 0x6006, 0x007e, 0x0005, 0x789b, 0x0080, 0x78ab, 0x0001,
+	0x78ab, 0x0002, 0x78ab, 0x0003, 0x7aaa, 0x789b, 0x0060, 0x78ab,
+	0x0004, 0x0800, 0x2031, 0x0000, 0x2029, 0x0032, 0x789b, 0x0080,
+	0x78ab, 0x0001, 0x78ab, 0x0003, 0x78ab, 0x0001, 0x7daa, 0x7eaa,
+	0x789b, 0x0060, 0x78ab, 0x0005, 0x0804, 0x3a7a, 0x0156, 0x8007,
+	0xa084, 0x00ff, 0x8003, 0x8003, 0xa080, 0x0020, 0x789a, 0x79a4,
+	0xa18c, 0xffe0, 0x2021, 0x3b7a, 0x2019, 0x0011, 0x20a9, 0x000e,
+	0x2011, 0x0032, 0x2404, 0xa084, 0xffe0, 0xa106, 0x0128, 0x8420,
+	0x2300, 0xa210, 0x1f04, 0x3ae2, 0x015e, 0x0005, 0x0156, 0x0804,
+	0x3b30, 0x2021, 0x3b88, 0x20a9, 0x0009, 0x2011, 0x0029, 0xa582,
+	0x0028, 0x0550, 0x8420, 0x95a9, 0x2011, 0x0033, 0xa582, 0x0033,
+	0x0618, 0x8420, 0x95a9, 0x2019, 0x000a, 0x2011, 0x0065, 0x2200,
+	0xa502, 0x02d0, 0x8420, 0x2300, 0xa210, 0x1f04, 0x3b07, 0x015e,
+	0x0088, 0x2021, 0x3b7a, 0x2019, 0x0011, 0x20a9, 0x000e, 0x2011,
+	0x0033, 0x2200, 0xa502, 0x0240, 0x8420, 0x2300, 0xa210, 0x1f04,
+	0x3b19, 0x015e, 0xa006, 0x0005, 0x8211, 0x015e, 0xa582, 0x0064,
+	0x1220, 0x7808, 0xa085, 0x0070, 0x780a, 0x2404, 0xa005, 0x0005,
+	0xa886, 0x0002, 0x01e8, 0x2021, 0x3b66, 0x20a9, 0x000d, 0x2011,
+	0x0028, 0xa582, 0x0028, 0x0d48, 0x8420, 0x2019, 0x0019, 0x2011,
+	0x0033, 0x2200, 0xa502, 0x0e00, 0x8420, 0x2300, 0xa210, 0x1f04,
+	0x3b41, 0x015e, 0x2011, 0x0184, 0xa582, 0x0185, 0x0ab0, 0x0890,
+	0x2021, 0x3b75, 0x20a9, 0x0003, 0x2011, 0x0024, 0xa586, 0x0024,
+	0x0960, 0x8420, 0x2011, 0x0028, 0xa586, 0x0028, 0x0930, 0x8420,
+	0x2019, 0x0019, 0x2011, 0x0033, 0x0804, 0x3b19, 0x1021, 0x2202,
+	0x3403, 0x4604, 0x5805, 0x6a06, 0x7c07, 0x4610, 0x4612, 0x5812,
+	0x5a12, 0x6a14, 0x6c14, 0x6e14, 0x7e17, 0x9021, 0xb002, 0xe204,
+	0xe210, 0xe210, 0x1209, 0x3002, 0x3202, 0x4203, 0x4403, 0x5404,
+	0x5604, 0x6605, 0x6805, 0x7806, 0x7a06, 0x0c07, 0x0c07, 0x0e07,
+	0x10e1, 0x330a, 0x5805, 0x5a05, 0x6a06, 0x6c06, 0x7c07, 0x7e07,
+	0x0e00, 0x789b, 0x0080, 0xa046, 0x0005, 0xa784, 0x0f00, 0x800b,
+	0xa784, 0x001f, 0x8003, 0x8003, 0x8003, 0x8003, 0xa105, 0xd7fc,
+	0x0118, 0xa0e0, 0x6cc0, 0x0010, 0xa0e0, 0x4cc0, 0x0005, 0x00e6,
+	0x00f6, 0xd084, 0x0138, 0x2079, 0x0100, 0x2009, 0x4780, 0x2071,
+	0x4780, 0x0030, 0x2009, 0x4740, 0x2079, 0x0200, 0x2071, 0x4740,
+	0x2091, 0x8000, 0x2104, 0xa084, 0x000f, 0x0002, 0x3bc8, 0x3bc8,
+	0x3bc8, 0x3bc8, 0x3bc8, 0x3bc8, 0x3bc6, 0x3bc6, 0x080c, 0x2575,
+	0x69b4, 0xc1f5, 0xa18c, 0xff9f, 0x69b6, 0xa005, 0x0580, 0x7858,
+	0xa084, 0xff9f, 0xa085, 0x6000, 0x785a, 0x7828, 0xa086, 0x1814,
+	0x1530, 0x784b, 0x0004, 0x7848, 0xa084, 0x0004, 0x1de0, 0x784b,
+	0x0008, 0x7848, 0xa084, 0x0008, 0x1de0, 0x7830, 0xd0bc, 0x11b8,
+	0xb284, 0x0800, 0x0118, 0x0104, 0x3bff, 0x0010, 0x0304, 0x3bff,
+	0x79e4, 0xa184, 0x0030, 0x0158, 0x78ec, 0xa084, 0x0003, 0x0138,
+	0x681c, 0xd0ac, 0x1110, 0x00d9, 0x0010, 0x781b, 0x00fb, 0x00fe,
+	0x00ee, 0x0005, 0x2001, 0x4701, 0x2004, 0xd0ac, 0x1118, 0x6814,
+	0x080c, 0x249e, 0x0005, 0x781b, 0x0083, 0x0005, 0x781b, 0x0082,
+	0x0005, 0x781b, 0x0071, 0x0005, 0x781b, 0x006e, 0x0005, 0x2009,
+	0x4719, 0x210c, 0xa186, 0x0000, 0x0150, 0xa186, 0x0001, 0x0150,
+	0x701f, 0x000b, 0x7063, 0x0001, 0x781b, 0x0054, 0x0005, 0x781b,
+	0x00f3, 0x0005, 0x701f, 0x000a, 0x0005, 0x2009, 0x4719, 0x210c,
+	0xa186, 0x0000, 0x0168, 0xa186, 0x0001, 0x0138, 0x701f, 0x000b,
+	0x7063, 0x0001, 0x781b, 0x0054, 0x0005, 0x701f, 0x000a, 0x0005,
+	0x781b, 0x00f2, 0x0005, 0x781b, 0x00fb, 0x0005, 0x781b, 0x00fa,
+	0x0005, 0x781b, 0x00cc, 0x0005, 0x781b, 0x00cb, 0x0005, 0x6818,
+	0xd0fc, 0x0110, 0x681b, 0x001d, 0x701f, 0x000b, 0x7063, 0x0001,
 	0x781b, 0x0054, 0x0005, 0x7830, 0xa084, 0x00c0, 0x1170, 0x7808,
 	0xc08c, 0x780a, 0xe000, 0xe000, 0xe000, 0xe000, 0x78ec, 0xa084,
 	0x0021, 0x0118, 0x7808, 0xc08d, 0x780a, 0x0005, 0x7808, 0xc08d,
 	0x780a, 0x0005, 0x7830, 0xa084, 0x0040, 0x1de0, 0xb284, 0x0800,
-	0x0118, 0x1104, 0x3c58, 0x0010, 0x1304, 0x3c58, 0x78ac, 0x0005,
+	0x0118, 0x1104, 0x3c80, 0x0010, 0x1304, 0x3c80, 0x78ac, 0x0005,
 	0x7808, 0xa084, 0xfffd, 0x780a, 0xe000, 0xe000, 0xe000, 0xe000,
 	0x78ec, 0xa084, 0x0021, 0x0140, 0xb284, 0x0800, 0x0118, 0x1104,
-	0x3c67, 0x0010, 0x1304, 0x3c6a, 0x78ac, 0x0006, 0x7808, 0xa085,
-	0x0002, 0x780a, 0x000e, 0x0005, 0xa784, 0x0001, 0x1904, 0x322a,
-	0xa784, 0x0070, 0x0140, 0x00c6, 0x2d60, 0x2f68, 0x080c, 0x2467,
+	0x3c8f, 0x0010, 0x1304, 0x3c92, 0x78ac, 0x0006, 0x7808, 0xa085,
+	0x0002, 0x780a, 0x000e, 0x0005, 0xa784, 0x0001, 0x1904, 0x324d,
+	0xa784, 0x0070, 0x0140, 0x00c6, 0x2d60, 0x2f68, 0x080c, 0x2490,
 	0x2d78, 0x2c68, 0x00ce, 0xa784, 0x0008, 0x0148, 0x784b, 0x0008,
-	0x78ec, 0xa084, 0x0003, 0x0904, 0x322a, 0x0804, 0x3be5, 0xa784,
+	0x78ec, 0xa084, 0x0003, 0x0904, 0x324d, 0x0804, 0x3c0b, 0xa784,
 	0x0004, 0x01c8, 0x78b8, 0xa084, 0x8000, 0x01a8, 0x784b, 0x0008,
-	0x78ec, 0xa084, 0x0003, 0x0904, 0x322a, 0x78e4, 0xa084, 0x0007,
+	0x78ec, 0xa084, 0x0003, 0x0904, 0x324d, 0x78e4, 0xa084, 0x0007,
 	0xa086, 0x0001, 0x1140, 0x78c0, 0xa685, 0x4800, 0x2030, 0x7e5a,
 	0x781b, 0x00fb, 0x0005, 0xa784, 0x0080, 0x0140, 0x7884, 0xd0fc,
-	0x0128, 0x080c, 0x3a32, 0x681b, 0x0022, 0x0005, 0x681b, 0x0003,
+	0x0128, 0x080c, 0x3a57, 0x681b, 0x0022, 0x0005, 0x681b, 0x0003,
 	0x7858, 0xa084, 0x5f00, 0x681e, 0x682f, 0x0000, 0x6833, 0x0000,
-	0x784b, 0x0008, 0x78ec, 0xa084, 0x0003, 0x0904, 0x2b89, 0xb284,
-	0x0800, 0x0110, 0x0104, 0x259d, 0x0304, 0x259d, 0x6b14, 0x8307,
+	0x784b, 0x0008, 0x78ec, 0xa084, 0x0003, 0x0904, 0x2bac, 0xb284,
+	0x0800, 0x0110, 0x0104, 0x25c6, 0x0304, 0x25c6, 0x6b14, 0x8307,
 	0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xd3fc, 0x0118, 0xa080,
-	0x4b40, 0x0010, 0xa080, 0x4ac0, 0x2060, 0x2048, 0x7056, 0x2a60,
-	0x0005, 0x00c6, 0x2960, 0x6000, 0xd0ac, 0x0904, 0x3d2f, 0x68a0,
-	0xd1ac, 0x1120, 0xa084, 0x0e00, 0x0904, 0x3d2d, 0x6108, 0x8117,
+	0x4c40, 0x0010, 0xa080, 0x4bc0, 0x2060, 0x2048, 0x7056, 0x2a60,
+	0x0005, 0x00c6, 0x2960, 0x6000, 0xd0ac, 0x0904, 0x3d57, 0x68a0,
+	0xd1ac, 0x1120, 0xa084, 0x0e00, 0x0904, 0x3d55, 0x6108, 0x8117,
 	0xa18c, 0x00ff, 0x631c, 0x832f, 0xd0dc, 0x0110, 0xa39d, 0x0001,
 	0xd0cc, 0x11c8, 0xa584, 0x00ff, 0x0138, 0x78ec, 0xd0e4, 0x0110,
 	0x8213, 0x00b8, 0x2029, 0x0000, 0xa182, 0x000c, 0x1290, 0x78ec,
@@ -1493,23 +1498,23 @@ static unsigned short risc_code01[] = {
 	0x2009, 0x000a, 0x0030, 0x2009, 0x0032, 0x2011, 0x0000, 0x2029,
 	0x0000, 0x78ab, 0x0001, 0x78ab, 0x0006, 0x78ab, 0x0004, 0x79aa,
 	0x78ab, 0x0000, 0x7aaa, 0x7baa, 0x7daa, 0xa8c0, 0x0008, 0x6820,
-	0xa085, 0x1000, 0x6822, 0x080c, 0x3a55, 0xa085, 0x0001, 0x00ce,
-	0x0005, 0xa282, 0x0006, 0x1904, 0x3a24, 0x7da8, 0x7eac, 0x8637,
+	0xa085, 0x1000, 0x6822, 0x080c, 0x3a7a, 0xa085, 0x0001, 0x00ce,
+	0x0005, 0xa282, 0x0006, 0x1904, 0x3a49, 0x7da8, 0x7eac, 0x8637,
 	0xa5ac, 0x00ff, 0xa6b4, 0x00ff, 0x7fac, 0x8747, 0xa7bc, 0x00ff,
-	0xa8c4, 0x00ff, 0x6920, 0xc1bd, 0x6922, 0xd1e4, 0x0904, 0x3da3,
-	0xa18c, 0xecff, 0x6922, 0xa782, 0x0002, 0x1a04, 0x39fe, 0xa6b4,
-	0x00ff, 0x0904, 0x3da0, 0xa682, 0x0031, 0x1a04, 0x39fe, 0xa582,
-	0x0009, 0x0a04, 0x39fe, 0xa882, 0x0003, 0x1a04, 0x39fe, 0xa886,
-	0x0002, 0x01d0, 0xa886, 0x0000, 0x1904, 0x39fe, 0x2001, 0x000c,
+	0xa8c4, 0x00ff, 0x6920, 0xc1bd, 0x6922, 0xd1e4, 0x0904, 0x3dcb,
+	0xa18c, 0xecff, 0x6922, 0xa782, 0x0002, 0x1a04, 0x3a23, 0xa6b4,
+	0x00ff, 0x0904, 0x3dc8, 0xa682, 0x0031, 0x1a04, 0x3a23, 0xa582,
+	0x0009, 0x0a04, 0x3a23, 0xa882, 0x0003, 0x1a04, 0x3a23, 0xa886,
+	0x0002, 0x01d0, 0xa886, 0x0000, 0x1904, 0x3a23, 0x2001, 0x000c,
 	0x79ec, 0xd1e4, 0x0110, 0x2001, 0x000a, 0xa502, 0x1290, 0x080c,
-	0x39fe, 0x00c6, 0x2960, 0x6004, 0xa085, 0x001a, 0x6006, 0x6000,
-	0xc0ac, 0x6002, 0x00ce, 0x0005, 0xa786, 0x0000, 0x0904, 0x39fe,
+	0x3a23, 0x00c6, 0x2960, 0x6004, 0xa085, 0x001a, 0x6006, 0x6000,
+	0xc0ac, 0x6002, 0x00ce, 0x0005, 0xa786, 0x0000, 0x0904, 0x3a23,
 	0x8634, 0xa682, 0x0018, 0x0228, 0x0120, 0x2031, 0x0018, 0x0804,
-	0x3df1, 0xa686, 0x0010, 0x1108, 0x8630, 0x852b, 0x852b, 0x080c,
-	0x3ac9, 0x0904, 0x39fe, 0x080c, 0x38f7, 0x080c, 0x399c, 0x7e58,
+	0x3e19, 0xa686, 0x0010, 0x1108, 0x8630, 0x852b, 0x852b, 0x080c,
+	0x3aee, 0x0904, 0x3a23, 0x080c, 0x391a, 0x080c, 0x39bf, 0x7e58,
 	0xd6d4, 0x1118, 0x781b, 0x0071, 0x0005, 0x781b, 0x0083, 0x0005,
-	0x080c, 0x38f4, 0x0c90, 0xa886, 0x0002, 0x1108, 0x8634, 0x7154,
-	0xa188, 0x0000, 0x210c, 0xd1ac, 0x0904, 0x39fe, 0xd1ec, 0x1120,
+	0x080c, 0x3917, 0x0c90, 0xa886, 0x0002, 0x1108, 0x8634, 0x7154,
+	0xa188, 0x0000, 0x210c, 0xd1ac, 0x0904, 0x3a23, 0xd1ec, 0x1120,
 	0x2039, 0x0000, 0x2041, 0x0000, 0xd1e4, 0x1120, 0x2031, 0x0000,
 	0x2041, 0x0000, 0xa782, 0x0002, 0x12c8, 0x621c, 0xa284, 0x00ff,
 	0xa706, 0x0110, 0x2039, 0x0000, 0xa605, 0x0190, 0x6108, 0x811f,
@@ -1517,11 +1522,11 @@ static unsigned short risc_code01[] = {
 	0xa086, 0x0201, 0x0160, 0xa886, 0x0000, 0x0168, 0x2039, 0x0000,
 	0x2041, 0x0000, 0x2031, 0x0000, 0xa006, 0x2010, 0x0070, 0xa284,
 	0xff00, 0x1108, 0x2040, 0xa184, 0x00ff, 0xa502, 0x0108, 0x2128,
-	0x852b, 0x852b, 0x080c, 0x3ac9, 0x0d58, 0x080c, 0x38f7, 0x080c,
-	0x399c, 0x789b, 0x0080, 0x78ab, 0x0001, 0x78ab, 0x0006, 0x78ab,
+	0x852b, 0x852b, 0x080c, 0x3aee, 0x0d58, 0x080c, 0x391a, 0x080c,
+	0x39bf, 0x789b, 0x0080, 0x78ab, 0x0001, 0x78ab, 0x0006, 0x78ab,
 	0x0004, 0x7daa, 0x78ab, 0x0000, 0x7eaa, 0x7faa, 0x2800, 0x78aa,
 	0x789b, 0x0060, 0x78ab, 0x0008, 0x6820, 0xc0e5, 0x6822, 0x080c,
-	0x3a55, 0x7858, 0xc095, 0x785a, 0x781b, 0x0082, 0x0005, 0x0020,
+	0x3a7a, 0x7858, 0xc095, 0x785a, 0x781b, 0x0082, 0x0005, 0x0020,
 	0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000,
 	0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000,
 	0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000,
@@ -1559,223 +1564,248 @@ static unsigned short risc_code01[] = {
 	0x20dd, 0x0011, 0x20d5, 0x8822, 0x0016, 0x0000, 0x0126, 0x70d0,
 	0xa084, 0x4c00, 0x8004, 0x2090, 0x7204, 0x7008, 0xc09c, 0xa205,
 	0x11a0, 0x720c, 0x82ff, 0x0128, 0x8aff, 0x1178, 0x7200, 0xd284,
-	0x1160, 0x7804, 0xd0cc, 0x0110, 0x080c, 0x4328, 0x7007, 0x0008,
+	0x1160, 0x7804, 0xd0cc, 0x0110, 0x080c, 0x435b, 0x7007, 0x0008,
 	0x7003, 0x0008, 0x012e, 0x2000, 0x0005, 0x7000, 0xa084, 0x0003,
 	0x7002, 0xc69c, 0xd084, 0x0588, 0x7108, 0xe000, 0x7008, 0xa106,
-	0x1dd8, 0xa184, 0x0003, 0x0904, 0x3fa2, 0xa184, 0x01e0, 0x1904,
-	0x3fa2, 0xd1f4, 0x1d88, 0xa184, 0x3000, 0xa086, 0x1000, 0x0d60,
+	0x1dd8, 0xa184, 0x0003, 0x0904, 0x3fca, 0xa184, 0x01e0, 0x1904,
+	0x3fca, 0xd1f4, 0x1d88, 0xa184, 0x3000, 0xa086, 0x1000, 0x0d60,
 	0x2011, 0x0180, 0x710c, 0x8211, 0x0130, 0x7008, 0xd0f4, 0x1d20,
 	0x700c, 0xa106, 0x0dc0, 0x7007, 0x0012, 0x7108, 0xe000, 0x7008,
 	0xa106, 0x1dd8, 0xa184, 0x0003, 0x0568, 0xd194, 0x0db0, 0xd1f4,
 	0x0548, 0x7007, 0x0002, 0x0880, 0x0428, 0x7108, 0xd1fc, 0x0130,
-	0x080c, 0x40ae, 0x8aff, 0x0904, 0x3f2c, 0x0cb8, 0x700c, 0xa08c,
+	0x080c, 0x40d6, 0x8aff, 0x0904, 0x3f54, 0x0cb8, 0x700c, 0xa08c,
 	0x07ff, 0x01e8, 0x7004, 0xd084, 0x0178, 0x7014, 0xa005, 0x1148,
 	0x7010, 0x7310, 0xa306, 0x1de0, 0x2300, 0xa005, 0x0128, 0xa102,
-	0x1e20, 0x7007, 0x0010, 0x0030, 0x8aff, 0x0148, 0x080c, 0x426b,
-	0x1de8, 0x09d8, 0x080c, 0x4034, 0x012e, 0x2000, 0x0005, 0x7204,
+	0x1e20, 0x7007, 0x0010, 0x0030, 0x8aff, 0x0148, 0x080c, 0x429a,
+	0x1de8, 0x09d8, 0x080c, 0x405c, 0x012e, 0x2000, 0x0005, 0x7204,
 	0x7108, 0xc19c, 0x8103, 0x1218, 0x7007, 0x0002, 0x0cc0, 0xa205,
-	0x1d88, 0x7007, 0x0008, 0x7003, 0x0008, 0x0006, 0x2001, 0x4601,
-	0x2004, 0xd0cc, 0x0110, 0x080c, 0x4328, 0x000e, 0x012e, 0x2000,
+	0x1d88, 0x7007, 0x0008, 0x7003, 0x0008, 0x0006, 0x2001, 0x4701,
+	0x2004, 0xd0cc, 0x0110, 0x080c, 0x435b, 0x000e, 0x012e, 0x2000,
 	0x0005, 0x6428, 0x84ff, 0x0508, 0x2c70, 0x7004, 0xa0bc, 0x000f,
-	0xa7b8, 0x3ff5, 0x273c, 0x87fb, 0x1148, 0x0210, 0x080c, 0x254c,
-	0x609c, 0xa075, 0x0190, 0x0c88, 0x2039, 0x3fea, 0x2704, 0xae68,
+	0xa7b8, 0x401d, 0x273c, 0x87fb, 0x1148, 0x0210, 0x080c, 0x2575,
+	0x609c, 0xa075, 0x0190, 0x0c88, 0x2039, 0x4012, 0x2704, 0xae68,
 	0x6808, 0xa630, 0x680c, 0xa529, 0x8421, 0x0138, 0x8738, 0x2704,
 	0xa005, 0x1da8, 0x709c, 0xa075, 0x1d00, 0x0005, 0x0000, 0x0005,
 	0x0009, 0x000d, 0x0011, 0x0015, 0x0019, 0x001d, 0x0000, 0x0003,
-	0x0009, 0x000f, 0x0015, 0x001b, 0x0000, 0x0000, 0x3fea, 0x3fe7,
-	0x0000, 0x0000, 0x8000, 0x0000, 0x3fea, 0x0000, 0x3ff2, 0x3fef,
-	0x0000, 0x0000, 0x0000, 0x0000, 0x3ff2, 0x0000, 0x3fed, 0x3fed,
-	0x0000, 0x0000, 0x8000, 0x0000, 0x3fed, 0x0000, 0x3ff3, 0x3ff3,
-	0x0000, 0x0000, 0x0000, 0x0000, 0x3ff3, 0x2079, 0x4600, 0x2071,
+	0x0009, 0x000f, 0x0015, 0x001b, 0x0000, 0x0000, 0x4012, 0x400f,
+	0x0000, 0x0000, 0x8000, 0x0000, 0x4012, 0x0000, 0x401a, 0x4017,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x401a, 0x0000, 0x4015, 0x4015,
+	0x0000, 0x0000, 0x8000, 0x0000, 0x4015, 0x0000, 0x401b, 0x401b,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x401b, 0x2079, 0x4700, 0x2071,
 	0x0010, 0x7007, 0x000a, 0x7007, 0x0002, 0x7003, 0x0001, 0x2009,
 	0x0002, 0x2071, 0x0050, 0x7007, 0x000a, 0x7007, 0x0002, 0x7003,
 	0x0000, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1128, 0x8109, 0x0118,
-	0x2071, 0x0020, 0x0c80, 0x0005, 0x7004, 0x8004, 0x1a04, 0x408a,
+	0x2071, 0x0020, 0x0c80, 0x0005, 0x7004, 0x8004, 0x1a04, 0x40b2,
 	0x7108, 0x7008, 0xa106, 0x1de0, 0xa184, 0x01e0, 0x0120, 0x080c,
-	0x40e6, 0x0804, 0x40aa, 0x7007, 0x0012, 0x2019, 0x0000, 0x7108,
-	0x7008, 0xa106, 0x1de0, 0xa184, 0x01e0, 0x0120, 0x080c, 0x40e6,
-	0x0804, 0x40aa, 0xa19c, 0x300c, 0xa386, 0x2004, 0x0190, 0xa386,
+	0x410e, 0x0804, 0x40d2, 0x7007, 0x0012, 0x2019, 0x0000, 0x7108,
+	0x7008, 0xa106, 0x1de0, 0xa184, 0x01e0, 0x0120, 0x080c, 0x410e,
+	0x0804, 0x40d2, 0xa19c, 0x300c, 0xa386, 0x2004, 0x0190, 0xa386,
 	0x0008, 0x01c0, 0x7004, 0xd084, 0x1148, 0x7108, 0x7008, 0xa106,
-	0x1de0, 0xa184, 0x0003, 0x0110, 0x0804, 0x40e6, 0xa386, 0x200c,
+	0x1de0, 0xa184, 0x0003, 0x0110, 0x0804, 0x410e, 0xa386, 0x200c,
 	0x19f0, 0x7200, 0x8204, 0x0230, 0x730c, 0xa384, 0x07ff, 0x0110,
-	0x080c, 0x254c, 0x7108, 0x7008, 0xa106, 0x1de0, 0xa184, 0x01e0,
-	0x0118, 0x080c, 0x40e6, 0x0470, 0x7007, 0x0012, 0x7000, 0xd084,
+	0x080c, 0x2575, 0x7108, 0x7008, 0xa106, 0x1de0, 0xa184, 0x01e0,
+	0x0118, 0x080c, 0x410e, 0x0470, 0x7007, 0x0012, 0x7000, 0xd084,
 	0x1148, 0x7310, 0x7014, 0xa305, 0x0128, 0x710c, 0xa184, 0x07ff,
-	0x1904, 0x4034, 0x7108, 0x7008, 0xa106, 0x1de0, 0xa184, 0x01e0,
-	0x0118, 0x080c, 0x40e6, 0x00b0, 0x7007, 0x0012, 0x7007, 0x0008,
+	0x1904, 0x405c, 0x7108, 0x7008, 0xa106, 0x1de0, 0xa184, 0x01e0,
+	0x0118, 0x080c, 0x410e, 0x00b0, 0x7007, 0x0012, 0x7007, 0x0008,
 	0x7004, 0xd09c, 0x1de8, 0x7108, 0x7008, 0xa106, 0x1de0, 0xa184,
-	0x01e0, 0x0118, 0x080c, 0x40e6, 0x0028, 0x7007, 0x0012, 0x7108,
+	0x01e0, 0x0118, 0x080c, 0x410e, 0x0028, 0x7007, 0x0012, 0x7108,
 	0x8103, 0x0e88, 0x7003, 0x0008, 0x0005, 0x7108, 0xa184, 0x01e0,
 	0x15a8, 0x7108, 0xa184, 0x01e0, 0x1588, 0xa184, 0x0007, 0x0002,
-	0x40c2, 0x40d0, 0x40c0, 0x40d0, 0x40c0, 0x4120, 0x40c0, 0x411e,
-	0x080c, 0x254c, 0x7004, 0xa084, 0x0010, 0xc08d, 0x7006, 0x8aff,
-	0x1118, 0x2049, 0x0000, 0x0005, 0x080c, 0x426b, 0x1de8, 0x0005,
+	0x40ea, 0x40f8, 0x40e8, 0x40f8, 0x40e8, 0x4148, 0x40e8, 0x4146,
+	0x080c, 0x2575, 0x7004, 0xa084, 0x0010, 0xc08d, 0x7006, 0x8aff,
+	0x1118, 0x2049, 0x0000, 0x0005, 0x080c, 0x429a, 0x1de8, 0x0005,
 	0x7004, 0xa084, 0x0010, 0xc08d, 0x7006, 0x7004, 0xd084, 0x1140,
 	0x7108, 0x7008, 0xa106, 0x1de0, 0xa184, 0x0003, 0x0108, 0x0030,
-	0x8aff, 0x0118, 0x080c, 0x426b, 0x1de8, 0x0005, 0x7007, 0x0012,
-	0x7108, 0x1d04, 0x40e9, 0x2091, 0x6000, 0x1d04, 0x40ed, 0x2091,
+	0x8aff, 0x0118, 0x080c, 0x429a, 0x1de8, 0x0005, 0x7007, 0x0012,
+	0x7108, 0x1d04, 0x4111, 0x2091, 0x6000, 0x1d04, 0x4115, 0x2091,
 	0x6000, 0x7007, 0x0012, 0x7007, 0x0008, 0x7004, 0xd09c, 0x1de8,
 	0x7007, 0x0012, 0x7108, 0xd1fc, 0x1dd8, 0x7003, 0x0000, 0x7000,
 	0xa005, 0x1130, 0x7004, 0xa005, 0x1118, 0x700c, 0xa005, 0x0108,
 	0x0c40, 0x2049, 0x0000, 0xb284, 0x0200, 0x0118, 0x2001, 0x0000,
-	0x0010, 0x2001, 0x0001, 0x080c, 0x3b81, 0x681b, 0x0002, 0x2051,
-	0x0000, 0x0005, 0x080c, 0x254c, 0x080c, 0x254c, 0x080c, 0x415f,
+	0x0010, 0x2001, 0x0001, 0x080c, 0x3ba7, 0x681b, 0x0002, 0x2051,
+	0x0000, 0x0005, 0x080c, 0x2575, 0x080c, 0x2575, 0x080c, 0x4187,
 	0x7210, 0x7114, 0x700c, 0xa09c, 0x07ff, 0x2800, 0xa300, 0xa211,
 	0xa189, 0x0000, 0x04a1, 0x2704, 0x2c58, 0xac60, 0x6308, 0x2200,
 	0xa322, 0x630c, 0x2100, 0xa31b, 0x2400, 0xa305, 0x0140, 0x1238,
 	0x8412, 0x8210, 0x830a, 0xa189, 0x0000, 0x2b60, 0x0c58, 0x2b60,
-	0x8a07, 0x0006, 0x6004, 0xd09c, 0x0118, 0xa7ba, 0x3fef, 0x0010,
-	0xa7ba, 0x3fe7, 0x000e, 0xa73d, 0x2c00, 0x6886, 0x6f8a, 0x6c92,
+	0x8a07, 0x0006, 0x6004, 0xd09c, 0x0118, 0xa7ba, 0x4017, 0x0010,
+	0xa7ba, 0x400f, 0x000e, 0xa73d, 0x2c00, 0x6886, 0x6f8a, 0x6c92,
 	0x6b8e, 0x7108, 0x7008, 0xa106, 0x1de0, 0xa184, 0x01e0, 0x0110,
-	0x080c, 0x40e6, 0x7007, 0x0012, 0x080c, 0x4034, 0x0005, 0x8a50,
+	0x080c, 0x410e, 0x7007, 0x0012, 0x080c, 0x405c, 0x0005, 0x8a50,
 	0x8739, 0x2704, 0xa004, 0x1168, 0x6000, 0xa064, 0x1108, 0x2d60,
-	0x6004, 0xa084, 0x000f, 0xa080, 0x4005, 0x203c, 0x87fb, 0x090c,
-	0x254c, 0x0005, 0x0126, 0x00d6, 0x70d0, 0xa084, 0x4c00, 0x8004,
+	0x6004, 0xa084, 0x000f, 0xa080, 0x402d, 0x203c, 0x87fb, 0x090c,
+	0x2575, 0x0005, 0x0126, 0x00d6, 0x70d0, 0xa084, 0x4c00, 0x8004,
 	0x2090, 0x00de, 0x6884, 0x2060, 0x6888, 0x6b8c, 0x6c90, 0x8057,
 	0xaad4, 0x00ff, 0xa084, 0x00ff, 0x0006, 0x6804, 0xa084, 0x0008,
-	0x000e, 0x0118, 0xa0b8, 0x3fef, 0x0010, 0xa0b8, 0x3fe7, 0xb284,
+	0x000e, 0x0118, 0xa0b8, 0x4017, 0x0010, 0xa0b8, 0x400f, 0xb284,
 	0x0200, 0x0110, 0x7e20, 0x0008, 0x7e24, 0xa6b5, 0x000c, 0x681c,
-	0xd0b4, 0x0108, 0xc685, 0x2400, 0xa305, 0x0518, 0x2c58, 0x2704,
-	0x6104, 0xac60, 0x6000, 0xa400, 0x701a, 0x6004, 0xa301, 0x701e,
-	0xd19c, 0x0140, 0x6010, 0xa081, 0x0000, 0x7022, 0x6014, 0xa081,
-	0x0000, 0x7026, 0x6208, 0x2400, 0xa202, 0x7012, 0x620c, 0x2300,
-	0xa203, 0x7016, 0x7602, 0x7007, 0x0001, 0x2b60, 0x080c, 0x4292,
-	0x0010, 0x080c, 0x426b, 0x1de8, 0x012e, 0x2000, 0x0005, 0x0126,
-	0x00d6, 0x70d0, 0xa084, 0x4c00, 0x8004, 0x2090, 0x00de, 0x7007,
-	0x0004, 0x7004, 0xd094, 0x1de8, 0x7003, 0x0008, 0x012e, 0x2000,
-	0x0005, 0x0126, 0x00d6, 0x70d0, 0xa084, 0x4c00, 0x8004, 0x2090,
-	0x00de, 0x7e20, 0xb284, 0x0200, 0x1108, 0x7e24, 0xa6b5, 0x000c,
-	0x681c, 0xd0ac, 0x1118, 0xc685, 0x7003, 0x0000, 0x6828, 0x2050,
-	0x2d60, 0x6004, 0xa0bc, 0x000f, 0xa7b8, 0x3ff5, 0x273c, 0x87fb,
-	0x1138, 0x0210, 0x080c, 0x254c, 0x689c, 0xa065, 0x0120, 0x0c88,
-	0x080c, 0x426b, 0x1de8, 0x012e, 0x2000, 0x0005, 0x0126, 0x0006,
-	0x0016, 0x00d6, 0x70d0, 0xa084, 0x4c00, 0x8004, 0x2090, 0x7e20,
-	0xb284, 0x0200, 0x1108, 0x7e24, 0x00de, 0x003e, 0x004e, 0xa6b5,
-	0x000c, 0x681c, 0xd0b4, 0x0128, 0xc685, 0x7003, 0x0000, 0x7007,
-	0x0004, 0x2049, 0x4206, 0x6828, 0xa055, 0x00d6, 0x0904, 0x4267,
-	0x2d70, 0x2e60, 0x7004, 0xa0bc, 0x000f, 0xa7b8, 0x3ff5, 0x273c,
-	0x87fb, 0x1140, 0x0210, 0x080c, 0x254c, 0x709c, 0xa075, 0x2060,
-	0x0570, 0x0c80, 0x2704, 0xae68, 0x6808, 0xa422, 0x680c, 0xa31b,
-	0x0268, 0x8a51, 0x1110, 0x080c, 0x254c, 0x8738, 0x2704, 0xa005,
-	0x1d90, 0x709c, 0xa075, 0x2060, 0x01d0, 0x08e0, 0x8422, 0x8420,
-	0x831a, 0xa399, 0x0000, 0x6908, 0x2400, 0xa122, 0x690c, 0x2300,
-	0xa11b, 0x1210, 0x080c, 0x254c, 0xb284, 0x0200, 0x0118, 0x2071,
-	0x0050, 0x0010, 0x2071, 0x0020, 0x00de, 0x0804, 0x419b, 0x00de,
-	0x012e, 0x2000, 0x0005, 0x7008, 0x0006, 0xa084, 0x01e0, 0x000e,
-	0x0110, 0xa006, 0x0005, 0xa084, 0x0003, 0xa086, 0x0003, 0x1108,
-	0x0005, 0x2704, 0xac78, 0x7800, 0x701a, 0x7804, 0x701e, 0x7808,
-	0x7012, 0x780c, 0x7016, 0x6004, 0xd09c, 0x0120, 0x7810, 0x7022,
-	0x7814, 0x7026, 0x7602, 0x7004, 0xa084, 0x0010, 0xc085, 0x7006,
-	0x2079, 0x4600, 0x8a51, 0x01e8, 0x8738, 0x2704, 0xa005, 0x1168,
-	0x609c, 0xa005, 0x01b8, 0x2060, 0x6004, 0xa084, 0x000f, 0xa080,
-	0x3ff5, 0x203c, 0x87fb, 0x090c, 0x254c, 0x7008, 0x0006, 0xa084,
-	0x01e0, 0x000e, 0x0110, 0xa006, 0x0028, 0xa084, 0x0003, 0xa086,
-	0x0003, 0x0005, 0x2051, 0x0000, 0x0005, 0x0126, 0x0006, 0x00d6,
-	0x70d0, 0xa084, 0x4c00, 0x8004, 0x2090, 0x00de, 0x008e, 0x7108,
-	0xa184, 0x0003, 0x1128, 0x6828, 0xa005, 0x0178, 0x0804, 0x3f45,
-	0x7108, 0xd1fc, 0x0118, 0x080c, 0x40ae, 0x0c88, 0x7007, 0x0010,
-	0x7108, 0xd1fc, 0x0de8, 0x080c, 0x40ae, 0x7008, 0xa086, 0x0008,
-	0x1d30, 0x7000, 0xa005, 0x1d18, 0x7003, 0x0000, 0x2049, 0x0000,
-	0x0006, 0x2001, 0x4601, 0x2004, 0xd0cc, 0x0110, 0x080c, 0x4328,
-	0x000e, 0x012e, 0x2000, 0x0005, 0x0126, 0x0146, 0x0136, 0x0156,
-	0x00c6, 0x00d6, 0x70d0, 0xa084, 0x4c00, 0x8004, 0x2090, 0x00de,
-	0x2049, 0x42ec, 0xad80, 0x0011, 0x20a0, 0xb284, 0x0200, 0x0118,
-	0x2099, 0x0032, 0x0010, 0x2099, 0x0031, 0x700c, 0xa084, 0x07ff,
-	0x682a, 0x7007, 0x0008, 0x7007, 0x0002, 0x7003, 0x0001, 0x0118,
-	0x8000, 0x80ac, 0x53a5, 0x700c, 0xa084, 0x07ff, 0x0130, 0x7007,
-	0x0004, 0x7004, 0xa084, 0x0004, 0x1de0, 0x00ce, 0x2049, 0x0000,
-	0x7003, 0x0000, 0x015e, 0x013e, 0x014e, 0x012e, 0x2000, 0x0005,
-	0x6814, 0xd0fc, 0x0904, 0x436b, 0x7000, 0xd084, 0x05e0, 0x7e24,
-	0xa6b5, 0x0004, 0x7007, 0x0004, 0x7004, 0xa084, 0x0004, 0x1de0,
-	0x7118, 0x0016, 0x711c, 0x0016, 0x7120, 0x0016, 0x7124, 0x0016,
-	0x701b, 0x0000, 0x701f, 0x3fff, 0x7023, 0x0000, 0x7027, 0x0000,
-	0x7013, 0x0004, 0x7017, 0x0000, 0x7602, 0x7007, 0x0001, 0x2001,
-	0xffff, 0x2009, 0x0031, 0x200a, 0x200a, 0x7108, 0x7008, 0xa106,
-	0x1de0, 0xd1fc, 0x0dd0, 0x002e, 0x7226, 0x002e, 0x7222, 0x002e,
-	0x721e, 0x002e, 0x721a, 0x7007, 0x0002, 0x7008, 0xa086, 0x0008,
-	0x0110, 0x0804, 0x40e6, 0x7007, 0x0004, 0x7003, 0x0000, 0x0005,
-	0x2091, 0x8000, 0x2091, 0x6000, 0x78ac, 0xa005, 0x1168, 0x7974,
-	0x70d0, 0xa106, 0x1148, 0x781c, 0xa005, 0x0130, 0x781f, 0x0000,
-	0x0e04, 0x4384, 0x2091, 0x4080, 0x2069, 0x4680, 0xd7fc, 0x1110,
-	0x2069, 0x4640, 0x6800, 0xa084, 0x000f, 0x1198, 0x68d0, 0xd0b4,
-	0x0180, 0xd0bc, 0x1170, 0x00f6, 0x2079, 0x0100, 0xd7fc, 0x1110,
-	0x2079, 0x0200, 0x7830, 0xa084, 0x00c0, 0x1110, 0x080c, 0x22ae,
-	0x00fe, 0x7830, 0x8001, 0x7832, 0x1904, 0x440b, 0x7834, 0x7832,
-	0x2061, 0x6bc0, 0x2069, 0x4680, 0xc7fd, 0x68cc, 0xa005, 0x0128,
-	0x8001, 0x68ce, 0x1110, 0x080c, 0x4577, 0x6800, 0xa084, 0x000f,
-	0x0168, 0xa086, 0x0001, 0x0150, 0x6840, 0xa00d, 0x0138, 0x2104,
-	0xa005, 0x0120, 0x8001, 0x200a, 0x0904, 0x4514, 0x6814, 0xa005,
-	0x01a8, 0x8001, 0x6816, 0x1190, 0x68a3, 0x0001, 0x00f6, 0xd7fc,
-	0x1118, 0x2079, 0x0200, 0x0010, 0x2079, 0x0100, 0x080c, 0x3c46,
-	0x00fe, 0x6860, 0xa005, 0x0110, 0x080c, 0x22ae, 0x687c, 0xa005,
-	0x0140, 0x8001, 0x687e, 0x1128, 0x6863, 0x0000, 0x68d0, 0xc0c5,
-	0x68d2, 0x68d0, 0xd0fc, 0x01b0, 0xc0fc, 0x68d2, 0x20a9, 0x0200,
-	0x6034, 0xa005, 0x0158, 0x8001, 0x6036, 0x68d0, 0xc0fd, 0x68d2,
-	0x1128, 0x6010, 0xa005, 0x0110, 0x080c, 0x22ae, 0xace0, 0x0010,
-	0x1f04, 0x43f0, 0xd7fc, 0x0138, 0x2061, 0x4bc0, 0x2069, 0x4640,
-	0xc7fc, 0x0804, 0x43ad, 0x0459, 0x7838, 0x8001, 0x783a, 0x11a0,
-	0x783c, 0x783a, 0x2061, 0x4bc0, 0x2069, 0x4640, 0xc7fc, 0x680c,
-	0xa005, 0x0110, 0x080c, 0x4487, 0xd7fc, 0x1130, 0x2061, 0x6bc0,
-	0x2069, 0x4680, 0xc7fd, 0x0c98, 0x7810, 0xd0cc, 0x0168, 0xd0ac,
-	0x1120, 0xd0a4, 0x0148, 0xc0ad, 0x7812, 0x2091, 0x8001, 0x0e04,
-	0x4433, 0x080c, 0x207a, 0x0005, 0x2091, 0x8001, 0x0005, 0x7840,
-	0x8001, 0x7842, 0x1904, 0x4486, 0x7844, 0x7842, 0x2069, 0x4640,
-	0xc7fc, 0x2079, 0x0200, 0x68d4, 0xa005, 0x0138, 0x7de0, 0xa504,
-	0x1120, 0x68d6, 0x68d0, 0xc0bc, 0x68d2, 0x2079, 0x4600, 0x6810,
-	0xa005, 0x1110, 0x2001, 0x0101, 0x8001, 0x6812, 0xd7fc, 0x0118,
-	0xa080, 0x8cd0, 0x0010, 0xa080, 0x8bc0, 0x2040, 0x2004, 0xa065,
-	0x01e0, 0x6024, 0xa005, 0x01b0, 0x8001, 0x6026, 0x1198, 0x6800,
-	0xa005, 0x0130, 0x6848, 0xac06, 0x1118, 0x080c, 0x4514, 0x0068,
-	0x6860, 0xa005, 0x0118, 0x6027, 0x0001, 0x0020, 0x080c, 0x44c8,
-	0x2804, 0x0c28, 0x6000, 0x2c40, 0x0c10, 0xd7fc, 0x1138, 0x2069,
-	0x4680, 0xc7fd, 0x2079, 0x0100, 0x0804, 0x4443, 0x0005, 0x2009,
-	0x0000, 0x20a9, 0x0200, 0x6008, 0xd09c, 0x0558, 0x6024, 0xa005,
-	0x0118, 0x8001, 0x6026, 0x0418, 0x6008, 0xc09c, 0xd084, 0x1110,
-	0xd0ac, 0x01c0, 0x600a, 0x6004, 0xa005, 0x01d8, 0x00d6, 0x00c6,
-	0x0016, 0x2068, 0x6010, 0x8001, 0x6012, 0x080c, 0x37a4, 0x2d00,
-	0x2c68, 0x2060, 0x080c, 0x1be3, 0x080c, 0x1d95, 0x001e, 0x00ce,
-	0x00de, 0x0038, 0xc0bd, 0x600a, 0xa18d, 0x0001, 0x0010, 0xa18d,
-	0x0100, 0xace0, 0x0010, 0x1f04, 0x448b, 0xa184, 0x0001, 0x0130,
-	0xa18c, 0xfffe, 0x690e, 0x080c, 0x22ae, 0x0008, 0x690e, 0x0005,
-	0x2c00, 0x687a, 0x6714, 0x6f72, 0x6017, 0x0000, 0x602b, 0x0000,
-	0x601b, 0x0006, 0x60b4, 0xa084, 0x5f00, 0x601e, 0x6020, 0xa084,
-	0x00ff, 0xa085, 0x0060, 0x6022, 0x6000, 0x2042, 0x6858, 0xac06,
-	0x1110, 0x2800, 0x685a, 0x080c, 0x1b7b, 0x6818, 0xa005, 0x0110,
-	0x8001, 0x681a, 0x6808, 0xc0a4, 0x680a, 0x6810, 0x7908, 0x8109,
-	0x790a, 0x8001, 0x1310, 0x080c, 0x254c, 0x6812, 0x1118, 0x7910,
-	0xc1a5, 0x7912, 0x602f, 0x0000, 0x6033, 0x0000, 0x2c68, 0x080c,
-	0x1da2, 0xd7fc, 0x1118, 0x2069, 0x4640, 0x0010, 0x2069, 0x4680,
-	0x6910, 0xa184, 0x0100, 0x2001, 0x0006, 0x1118, 0x6976, 0x2001,
-	0x0004, 0x080c, 0x22a4, 0x0005, 0x00d6, 0x6948, 0x2160, 0xd7fc,
-	0x1118, 0x2069, 0x0200, 0x0010, 0x2069, 0x0100, 0x080c, 0x2467,
-	0x601b, 0x0006, 0x6858, 0xa084, 0x5f00, 0x601e, 0x6020, 0xa084,
-	0x00ff, 0xa085, 0x0048, 0x6022, 0x602f, 0x0000, 0x6033, 0x0000,
-	0x6808, 0xa084, 0xfffd, 0x680a, 0x6830, 0xd0b4, 0x01b0, 0x684b,
-	0x0004, 0x20a9, 0x0014, 0x6848, 0xd094, 0x0110, 0x1f04, 0x453b,
-	0x684b, 0x0009, 0x20a9, 0x0014, 0x6848, 0xd084, 0x0110, 0x1f04,
-	0x4544, 0x20a9, 0x00fa, 0x1f04, 0x454b, 0x681b, 0x0054, 0x00de,
-	0x6863, 0x0007, 0x0005, 0x2079, 0x4600, 0x00e1, 0x0089, 0x00a9,
-	0x2009, 0x0002, 0x2069, 0x4680, 0x680f, 0x0000, 0x6813, 0x0000,
-	0x6817, 0x0000, 0x8109, 0x0118, 0x2069, 0x4640, 0x0ca8, 0x0005,
-	0x2019, 0x00a3, 0x7b3a, 0x7b3e, 0x0005, 0x2019, 0x0033, 0x7b42,
-	0x7b46, 0x0005, 0x2019, 0x32dd, 0x7b32, 0x7b36, 0x0005, 0x6a4c,
-	0xa285, 0x0000, 0x01f0, 0x6950, 0x6bbc, 0xa300, 0x00c6, 0x2164,
-	0x6304, 0x83ff, 0x1138, 0x8211, 0x0148, 0x8108, 0xa11a, 0x0eb8,
-	0x69bc, 0x0ca8, 0x68cf, 0x000a, 0x00ce, 0x0005, 0x694c, 0x6abc,
-	0x2264, 0x6008, 0xc0b5, 0x600a, 0x8210, 0x8109, 0x1dc8, 0x694e,
-	0x00ce, 0x0005, 0x1d04, 0x459a, 0x2091, 0x6000, 0x1d04, 0x459e,
-	0x2091, 0x6000, 0x70ec, 0xd0dc, 0x1118, 0xd0d4, 0x0190, 0x0098,
-	0xae8e, 0x0100, 0x0138, 0x7814, 0xc0f5, 0xc0c5, 0x7816, 0xd0d4,
-	0x1578, 0x0458, 0x7814, 0xc0fd, 0xc0c5, 0x7816, 0xd0d4, 0x1540,
-	0x0420, 0xd0e4, 0x0538, 0x1d04, 0x45bb, 0x2091, 0x6000, 0x2009,
-	0x000c, 0x1d04, 0x45c1, 0x2091, 0x6000, 0x8109, 0x1dd0, 0x70e4,
-	0xa084, 0x01ff, 0xa086, 0x01ff, 0x1110, 0x70ec, 0x08c8, 0xae8e,
-	0x0100, 0x0128, 0x7814, 0xc0f4, 0xd0fc, 0x1130, 0x0020, 0x7814,
-	0xc0fc, 0xd0f4, 0x1108, 0xc0c4, 0x7816, 0x7804, 0xd08c, 0x0110,
-	0x681f, 0x000c, 0x70a0, 0x70a2, 0x0005, 0x7c12
+	0xd0b4, 0x0108, 0xc685, 0x2400, 0xa305, 0x0550, 0x2c58, 0x2704,
+	0x6104, 0xac60, 0x6000, 0xa400, 0x2048, 0xa9cc, 0x0004, 0x0118,
+	0x080c, 0x43a3, 0x0400, 0x701a, 0x6004, 0xa301, 0x701e, 0xd19c,
+	0x0140, 0x6010, 0xa081, 0x0000, 0x7022, 0x6014, 0xa081, 0x0000,
+	0x7026, 0x6208, 0x2400, 0xa202, 0x7012, 0x620c, 0x2300, 0xa203,
+	0x7016, 0x7602, 0x7007, 0x0001, 0x2b60, 0x080c, 0x42c5, 0x0010,
+	0x080c, 0x429a, 0x1de8, 0x012e, 0x2000, 0x0005, 0x0126, 0x00d6,
+	0x70d0, 0xa084, 0x4c00, 0x8004, 0x2090, 0x00de, 0x7007, 0x0004,
+	0x7004, 0xd094, 0x1de8, 0x7003, 0x0008, 0x012e, 0x2000, 0x0005,
+	0x0126, 0x00d6, 0x70d0, 0xa084, 0x4c00, 0x8004, 0x2090, 0x00de,
+	0x7e20, 0xb284, 0x0200, 0x1108, 0x7e24, 0xa6b5, 0x000c, 0x681c,
+	0xd0ac, 0x1118, 0xc685, 0x7003, 0x0000, 0x6828, 0x2050, 0x2d60,
+	0x6004, 0xa0bc, 0x000f, 0xa7b8, 0x401d, 0x273c, 0x87fb, 0x1138,
+	0x0210, 0x080c, 0x2575, 0x689c, 0xa065, 0x0120, 0x0c88, 0x080c,
+	0x429a, 0x1de8, 0x012e, 0x2000, 0x0005, 0x0126, 0x0006, 0x0016,
+	0x00d6, 0x70d0, 0xa084, 0x4c00, 0x8004, 0x2090, 0x7e20, 0xb284,
+	0x0200, 0x1108, 0x7e24, 0x00de, 0x003e, 0x004e, 0xa6b5, 0x000c,
+	0x681c, 0xd0b4, 0x0128, 0xc685, 0x7003, 0x0000, 0x7007, 0x0004,
+	0x2049, 0x4235, 0x6828, 0xa055, 0x00d6, 0x0904, 0x4296, 0x2d70,
+	0x2e60, 0x7004, 0xa0bc, 0x000f, 0xa7b8, 0x401d, 0x273c, 0x87fb,
+	0x1140, 0x0210, 0x080c, 0x2575, 0x709c, 0xa075, 0x2060, 0x0570,
+	0x0c80, 0x2704, 0xae68, 0x6808, 0xa422, 0x680c, 0xa31b, 0x0268,
+	0x8a51, 0x1110, 0x080c, 0x2575, 0x8738, 0x2704, 0xa005, 0x1d90,
+	0x709c, 0xa075, 0x2060, 0x01d0, 0x08e0, 0x8422, 0x8420, 0x831a,
+	0xa399, 0x0000, 0x6908, 0x2400, 0xa122, 0x690c, 0x2300, 0xa11b,
+	0x1210, 0x080c, 0x2575, 0xb284, 0x0200, 0x0118, 0x2071, 0x0050,
+	0x0010, 0x2071, 0x0020, 0x00de, 0x0804, 0x41c3, 0x00de, 0x012e,
+	0x2000, 0x0005, 0x7008, 0x0006, 0xa084, 0x01e0, 0x000e, 0x0110,
+	0xa006, 0x0005, 0xa084, 0x0003, 0xa086, 0x0003, 0x1108, 0x0005,
+	0x2704, 0xac78, 0x7800, 0x2f08, 0xd094, 0x1904, 0x43a6, 0x701a,
+	0x7804, 0x701e, 0x7808, 0x7012, 0x780c, 0x7016, 0x6004, 0xd09c,
+	0x0120, 0x7810, 0x7022, 0x7814, 0x7026, 0x7602, 0x7004, 0xa084,
+	0x0010, 0xc085, 0x7006, 0x2079, 0x4700, 0x8a51, 0x01e8, 0x8738,
+	0x2704, 0xa005, 0x1168, 0x609c, 0xa005, 0x01b8, 0x2060, 0x6004,
+	0xa084, 0x000f, 0xa080, 0x401d, 0x203c, 0x87fb, 0x090c, 0x2575,
+	0x7008, 0x0006, 0xa084, 0x01e0, 0x000e, 0x0110, 0xa006, 0x0028,
+	0xa084, 0x0003, 0xa086, 0x0003, 0x0005, 0x2051, 0x0000, 0x0005,
+	0x0126, 0x0006, 0x00d6, 0x70d0, 0xa084, 0x4c00, 0x8004, 0x2090,
+	0x00de, 0x008e, 0x7108, 0xa184, 0x0003, 0x1128, 0x6828, 0xa005,
+	0x0178, 0x0804, 0x3f6d, 0x7108, 0xd1fc, 0x0118, 0x080c, 0x40d6,
+	0x0c88, 0x7007, 0x0010, 0x7108, 0xd1fc, 0x0de8, 0x080c, 0x40d6,
+	0x7008, 0xa086, 0x0008, 0x1d30, 0x7000, 0xa005, 0x1d18, 0x7003,
+	0x0000, 0x2049, 0x0000, 0x0006, 0x2001, 0x4701, 0x2004, 0xd0cc,
+	0x0110, 0x080c, 0x435b, 0x000e, 0x012e, 0x2000, 0x0005, 0x0126,
+	0x0146, 0x0136, 0x0156, 0x00c6, 0x00d6, 0x70d0, 0xa084, 0x4c00,
+	0x8004, 0x2090, 0x00de, 0x2049, 0x431f, 0xad80, 0x0011, 0x20a0,
+	0xb284, 0x0200, 0x0118, 0x2099, 0x0032, 0x0010, 0x2099, 0x0031,
+	0x700c, 0xa084, 0x07ff, 0x682a, 0x7007, 0x0008, 0x7007, 0x0002,
+	0x7003, 0x0001, 0x0118, 0x8000, 0x80ac, 0x53a5, 0x700c, 0xa084,
+	0x07ff, 0x0130, 0x7007, 0x0004, 0x7004, 0xa084, 0x0004, 0x1de0,
+	0x00ce, 0x2049, 0x0000, 0x7003, 0x0000, 0x015e, 0x013e, 0x014e,
+	0x012e, 0x2000, 0x0005, 0x6814, 0xd0fc, 0x0904, 0x439e, 0x7000,
+	0xd084, 0x05e0, 0x7e24, 0xa6b5, 0x0004, 0x7007, 0x0004, 0x7004,
+	0xa084, 0x0004, 0x1de0, 0x7118, 0x0016, 0x711c, 0x0016, 0x7120,
+	0x0016, 0x7124, 0x0016, 0x701b, 0x0000, 0x701f, 0x3fff, 0x7023,
+	0x0000, 0x7027, 0x0000, 0x7013, 0x0004, 0x7017, 0x0000, 0x7602,
+	0x7007, 0x0001, 0x2001, 0xffff, 0x2009, 0x0031, 0x200a, 0x200a,
+	0x7108, 0x7008, 0xa106, 0x1de0, 0xd1fc, 0x0dd0, 0x002e, 0x7226,
+	0x002e, 0x7222, 0x002e, 0x721e, 0x002e, 0x721a, 0x7007, 0x0002,
+	0x7008, 0xa086, 0x0008, 0x0110, 0x0804, 0x410e, 0x7007, 0x0004,
+	0x7003, 0x0000, 0x0005, 0x2049, 0x41c3, 0x0068, 0x7008, 0xa084,
+	0x0003, 0x0110, 0xa006, 0x0005, 0xa006, 0x2020, 0x2018, 0x2c58,
+	0x2160, 0x2049, 0x0000, 0x8b58, 0x6100, 0x2100, 0xa408, 0x711a,
+	0x6004, 0xa301, 0x701e, 0x0006, 0x2b04, 0xa084, 0x0008, 0x0150,
+	0x6010, 0xa081, 0x0000, 0x7022, 0x0006, 0x6014, 0xa081, 0x0000,
+	0x7026, 0x0006, 0xa184, 0x0007, 0x2011, 0x0008, 0xa22a, 0x6208,
+	0x2400, 0xa212, 0x0026, 0x620c, 0x2240, 0x2300, 0xa843, 0x002e,
+	0x88ff, 0x1170, 0x2500, 0xa202, 0x0108, 0x1250, 0x2220, 0x2041,
+	0x0000, 0x2b04, 0xd09c, 0x0110, 0x000e, 0x000e, 0x000e, 0x0450,
+	0x7512, 0x7017, 0x0000, 0x7602, 0xa986, 0x41c3, 0x1118, 0x7007,
+	0x0001, 0x0028, 0x7004, 0xa084, 0x0010, 0xc085, 0x7006, 0x2500,
+	0xa100, 0x701a, 0x2b04, 0xa084, 0x0008, 0x0110, 0x000e, 0x004e,
+	0x001e, 0xa189, 0x0000, 0x711e, 0x2b0c, 0xa18c, 0x0008, 0x0130,
+	0xa4a1, 0x0000, 0x7422, 0xa081, 0x0000, 0x7026, 0x2500, 0xa222,
+	0xa8c3, 0x0000, 0x7412, 0x2820, 0x7416, 0x7602, 0xa986, 0x41c3,
+	0x1118, 0x7007, 0x0001, 0x0028, 0x7004, 0xa084, 0x0010, 0xc085,
+	0x7006, 0x8b59, 0x2b60, 0x2079, 0x4700, 0x080c, 0x42c5, 0xa006,
+	0x0005, 0x2091, 0x8000, 0x2091, 0x6000, 0x78ac, 0xa005, 0x1168,
+	0x7974, 0x70d0, 0xa106, 0x1148, 0x781c, 0xa005, 0x0130, 0x781f,
+	0x0000, 0x0e04, 0x443d, 0x2091, 0x4080, 0x2069, 0x4780, 0xc7fd,
+	0x6800, 0xa084, 0x000f, 0x1198, 0x68d0, 0xd0b4, 0x0180, 0xd0bc,
+	0x1170, 0x00f6, 0x2079, 0x0100, 0xd7fc, 0x1110, 0x2079, 0x0200,
+	0x7830, 0xa084, 0x00c0, 0x1110, 0x080c, 0x22d5, 0x00fe, 0xd7fc,
+	0x0120, 0x2069, 0x4740, 0xc7fc, 0x0c18, 0x7830, 0x8001, 0x7832,
+	0x1904, 0x44c7, 0x7834, 0x7832, 0x2061, 0x6cc0, 0x2069, 0x4780,
+	0xc7fd, 0x68cc, 0xa005, 0x0128, 0x8001, 0x68ce, 0x1110, 0x080c,
+	0x4639, 0x6800, 0xa084, 0x000f, 0x0168, 0xa086, 0x0001, 0x0150,
+	0x6840, 0xa00d, 0x0138, 0x2104, 0xa005, 0x0120, 0x8001, 0x200a,
+	0x0904, 0x45d6, 0x6814, 0xa005, 0x01a8, 0x8001, 0x6816, 0x1190,
+	0x68a3, 0x0001, 0x00f6, 0xd7fc, 0x1118, 0x2079, 0x0200, 0x0010,
+	0x2079, 0x0100, 0x080c, 0x3c6e, 0x00fe, 0x6860, 0xa005, 0x0110,
+	0x080c, 0x22d5, 0x687c, 0xa005, 0x0140, 0x8001, 0x687e, 0x1128,
+	0x6863, 0x0000, 0x68d0, 0xc0c5, 0x68d2, 0x68d0, 0xd0fc, 0x01b0,
+	0xc0fc, 0x68d2, 0x20a9, 0x0200, 0x6034, 0xa005, 0x0158, 0x8001,
+	0x6036, 0x68d0, 0xc0fd, 0x68d2, 0x1128, 0x6010, 0xa005, 0x0110,
+	0x080c, 0x22d5, 0xace0, 0x0010, 0x1f04, 0x44ac, 0xd7fc, 0x0138,
+	0x2061, 0x4cc0, 0x2069, 0x4740, 0xc7fc, 0x0804, 0x4469, 0x0459,
+	0x7838, 0x8001, 0x783a, 0x11a0, 0x783c, 0x783a, 0x2061, 0x4cc0,
+	0x2069, 0x4740, 0xc7fc, 0x680c, 0xa005, 0x0110, 0x080c, 0x4543,
+	0xd7fc, 0x1130, 0x2061, 0x6cc0, 0x2069, 0x4780, 0xc7fd, 0x0c98,
+	0x7810, 0xd0cc, 0x0168, 0xd0ac, 0x1120, 0xd0a4, 0x0148, 0xc0ad,
+	0x7812, 0x2091, 0x8001, 0x0e04, 0x44ef, 0x080c, 0x20a1, 0x0005,
+	0x2091, 0x8001, 0x0005, 0x7840, 0x8001, 0x7842, 0x1904, 0x4542,
+	0x7844, 0x7842, 0x2069, 0x4740, 0xc7fc, 0x2079, 0x0200, 0x68d4,
+	0xa005, 0x0138, 0x7de0, 0xa504, 0x1120, 0x68d6, 0x68d0, 0xc0bc,
+	0x68d2, 0x2079, 0x4700, 0x6810, 0xa005, 0x1110, 0x2001, 0x0101,
+	0x8001, 0x6812, 0xd7fc, 0x0118, 0xa080, 0x8dd0, 0x0010, 0xa080,
+	0x8cc0, 0x2040, 0x2004, 0xa065, 0x01e0, 0x6024, 0xa005, 0x01b0,
+	0x8001, 0x6026, 0x1198, 0x6800, 0xa005, 0x0130, 0x6848, 0xac06,
+	0x1118, 0x080c, 0x45d6, 0x0068, 0x6860, 0xa005, 0x0118, 0x6027,
+	0x0001, 0x0020, 0x080c, 0x4584, 0x2804, 0x0c28, 0x6000, 0x2c40,
+	0x0c10, 0xd7fc, 0x1138, 0x2069, 0x4780, 0xc7fd, 0x2079, 0x0100,
+	0x0804, 0x44ff, 0x0005, 0x2009, 0x0000, 0x20a9, 0x0200, 0x6008,
+	0xd09c, 0x0558, 0x6024, 0xa005, 0x0118, 0x8001, 0x6026, 0x0418,
+	0x6008, 0xc09c, 0xd084, 0x1110, 0xd0ac, 0x01c0, 0x600a, 0x6004,
+	0xa005, 0x01d8, 0x00d6, 0x00c6, 0x0016, 0x2068, 0x6010, 0x8001,
+	0x6012, 0x080c, 0x37c7, 0x2d00, 0x2c68, 0x2060, 0x080c, 0x1c02,
+	0x080c, 0x1db2, 0x001e, 0x00ce, 0x00de, 0x0038, 0xc0bd, 0x600a,
+	0xa18d, 0x0001, 0x0010, 0xa18d, 0x0100, 0xace0, 0x0010, 0x1f04,
+	0x4547, 0xa184, 0x0001, 0x0130, 0xa18c, 0xfffe, 0x690e, 0x080c,
+	0x22d5, 0x0008, 0x690e, 0x0005, 0x2c00, 0x687a, 0x6714, 0x6f72,
+	0x6017, 0x0000, 0x602b, 0x0000, 0x601b, 0x0006, 0x60b4, 0xa084,
+	0x5f00, 0x601e, 0x6020, 0xa084, 0x00ff, 0xa085, 0x0060, 0x6022,
+	0x6000, 0x2042, 0x2069, 0x4780, 0xd7fc, 0x1110, 0x2069, 0x4740,
+	0x6858, 0xac06, 0x1110, 0x2800, 0x685a, 0x080c, 0x1b9a, 0x6818,
+	0xa005, 0x0110, 0x8001, 0x681a, 0x6808, 0xc0a4, 0x680a, 0x6810,
+	0x7908, 0x8109, 0x790a, 0x8001, 0x1310, 0x080c, 0x2575, 0x6812,
+	0x1118, 0x7910, 0xc1a5, 0x7912, 0x602f, 0x0000, 0x6033, 0x0000,
+	0x2c68, 0x080c, 0x1dbf, 0xd7fc, 0x1118, 0x2069, 0x4740, 0x0010,
+	0x2069, 0x4780, 0x6910, 0xa184, 0x0100, 0x2001, 0x0006, 0x1118,
+	0x6976, 0x2001, 0x0004, 0x080c, 0x22cb, 0x0005, 0x00d6, 0x6948,
+	0x2160, 0xd7fc, 0x1118, 0x2069, 0x0200, 0x0010, 0x2069, 0x0100,
+	0x080c, 0x2490, 0x601b, 0x0006, 0x6858, 0xa084, 0x5f00, 0x601e,
+	0x6020, 0xa084, 0x00ff, 0xa085, 0x0048, 0x6022, 0x602f, 0x0000,
+	0x6033, 0x0000, 0x6808, 0xa084, 0xfffd, 0x680a, 0x6830, 0xd0b4,
+	0x01b0, 0x684b, 0x0004, 0x20a9, 0x0014, 0x6848, 0xd094, 0x0110,
+	0x1f04, 0x45fd, 0x684b, 0x0009, 0x20a9, 0x0014, 0x6848, 0xd084,
+	0x0110, 0x1f04, 0x4606, 0x20a9, 0x00fa, 0x1f04, 0x460d, 0x681b,
+	0x0054, 0x00de, 0x6863, 0x0007, 0x0005, 0x2079, 0x4700, 0x00e1,
+	0x0089, 0x00a9, 0x2009, 0x0002, 0x2069, 0x4780, 0x680f, 0x0000,
+	0x6813, 0x0000, 0x6817, 0x0000, 0x8109, 0x0118, 0x2069, 0x4740,
+	0x0ca8, 0x0005, 0x2019, 0x00a3, 0x7b3a, 0x7b3e, 0x0005, 0x2019,
+	0x0033, 0x7b42, 0x7b46, 0x0005, 0x2019, 0x32dd, 0x7b32, 0x7b36,
+	0x0005, 0x6a4c, 0xa285, 0x0000, 0x01f0, 0x6950, 0x6bbc, 0xa300,
+	0x00c6, 0x2164, 0x6304, 0x83ff, 0x1138, 0x8211, 0x0148, 0x8108,
+	0xa11a, 0x0eb8, 0x69bc, 0x0ca8, 0x68cf, 0x000a, 0x00ce, 0x0005,
+	0x694c, 0x6abc, 0x2264, 0x6008, 0xc0b5, 0x600a, 0x8210, 0x8109,
+	0x1dc8, 0x694e, 0x00ce, 0x0005, 0x0016, 0x1d04, 0x465d, 0x2091,
+	0x6000, 0x1d04, 0x4661, 0x2091, 0x6000, 0x70ec, 0xd0dc, 0x1118,
+	0xd0d4, 0x0190, 0x00a0, 0xae8e, 0x0100, 0x0138, 0x7814, 0xc0f5,
+	0xc0c5, 0x7816, 0xd0d4, 0x1580, 0x0460, 0x7814, 0xc0fd, 0xc0c5,
+	0x7816, 0xd0d4, 0x1548, 0x0428, 0xd0e4, 0x0904, 0x46c4, 0x1d04,
+	0x467f, 0x2091, 0x6000, 0x2009, 0x000c, 0x1d04, 0x4685, 0x2091,
+	0x6000, 0x8109, 0x1dd0, 0x70e4, 0xa084, 0x01ff, 0xa086, 0x01ff,
+	0x1110, 0x70ec, 0x08c0, 0xae8e, 0x0100, 0x0128, 0x7814, 0xc0f4,
+	0xd0fc, 0x1130, 0x0020, 0x7814, 0xc0fc, 0xd0f4, 0x1108, 0xc0c4,
+	0x7816, 0x7804, 0xd08c, 0x0500, 0x00c6, 0x2061, 0x0000, 0x6018,
+	0xd084, 0x11b8, 0xae86, 0x0200, 0x00e6, 0x2071, 0x0010, 0x0120,
+	0x70db, 0x0001, 0x78e4, 0x0018, 0x70db, 0x0000, 0x78e0, 0x70c6,
+	0x70c3, 0x800e, 0x601b, 0x0001, 0x2091, 0x4080, 0x00ee, 0x00ce,
+	0x0018, 0x00ce, 0x681f, 0x000c, 0x001e, 0x70a0, 0x70a2, 0x0005,
+	0x0c26
 };
 #ifdef UNIQUE_FW_NAME
-static unsigned short   fw12160i_length01 = 0x35e6;
+static unsigned short fw12160i_length01 = 0x36c9;
 #else
-static unsigned short   risc_code_length01 = 0x35e6;
+static unsigned short risc_code_length01 = 0x36c9;
 #endif
+
diff --git a/drivers/scsi/ql1280_fw.h b/drivers/scsi/ql1280_fw.h
--- a/drivers/scsi/ql1280_fw.h
+++ b/drivers/scsi/ql1280_fw.h
@@ -23,25 +23,25 @@
 
 
 /*
- *	Firmware Version 8.15.00 (14:35 Aug 22, 2000)
+ *	Firmware Version 8.15.11 (10:20 Jan 02, 2002)
  */
 
 #ifdef UNIQUE_FW_NAME
-static unsigned char fw1280ei_version_str[] = {8,15,0};
+static unsigned char fw1280ei_version_str[] = {8,15,11};
 #else
-static unsigned char firmware_version[] = {8,15,0};
+static unsigned char firmware_version[] = {8,15,11};
 #endif
 
 #ifdef UNIQUE_FW_NAME
-#define fw1280ei_VERSION_STRING "8.15.00"
+#define fw1280ei_VERSION_STRING "8.15.11"
 #else
-#define FW_VERSION_STRING "8.15.00"
+#define FW_VERSION_STRING "8.15.11"
 #endif
 
 #ifdef UNIQUE_FW_NAME
-static unsigned short fw1280ei_addr01 = 0x1000;
+static unsigned short fw1280ei_addr01 = 0x1000 ;
 #else
-static unsigned short risc_code_addr01 = 0x1000;
+static unsigned short risc_code_addr01 = 0x1000 ;
 #endif
 
 #ifdef UNIQUE_FW_NAME
@@ -49,7 +49,7 @@ static unsigned short fw1280ei_code01[] 
 #else
 static unsigned short risc_code01[] = {
 #endif
-	0x0078, 0x1041, 0x0000, 0x3d3b, 0x0000, 0x2043, 0x4f50, 0x5952,
+	0x0078, 0x1041, 0x0000, 0x3e2e, 0x0000, 0x2043, 0x4f50, 0x5952,
 	0x4947, 0x4854, 0x2031, 0x3939, 0x312c, 0x3139, 0x3932, 0x2c31,
 	0x3939, 0x332c, 0x3139, 0x3934, 0x2051, 0x4c4f, 0x4749, 0x4320,
 	0x434f, 0x5250, 0x4f52, 0x4154, 0x494f, 0x4e00, 0x2049, 0x5350,
@@ -57,7 +57,7 @@ static unsigned short risc_code01[] = {
 	0x6572, 0x7369, 0x6f6e, 0x2030, 0x382e, 0x3135, 0x2020, 0x2043,
 	0x7573, 0x746f, 0x6d65, 0x7220, 0x4e6f, 0x2e20, 0x3030, 0x2050,
 	0x726f, 0x6475, 0x6374, 0x204e, 0x6f2e, 0x2020, 0x3030, 0x2020,
-	0x2400, 0x20c9, 0x97ff, 0x2001, 0x04fc, 0x2004, 0xa086, 0x1080,
+	0x2400, 0x20c9, 0x98ff, 0x2001, 0x04fc, 0x2004, 0xa086, 0x1080,
 	0x00c0, 0x1054, 0x2071, 0x0100, 0x70a0, 0x70a2, 0x20c1, 0x0010,
 	0x2089, 0x1374, 0x0078, 0x106d, 0x2001, 0x04fc, 0x2004, 0xa086,
 	0x1280, 0x00c0, 0x1069, 0x2071, 0x0200, 0x70a0, 0x70a2, 0x2071,
@@ -70,1660 +70,1670 @@ static unsigned short risc_code01[] = {
 	0xa286, 0xa5a5, 0x0040, 0x10a4, 0xa386, 0x000f, 0x0040, 0x10a0,
 	0x2c6a, 0x2a5a, 0x20c1, 0x0020, 0x2019, 0x000f, 0x0078, 0x1080,
 	0x2c6a, 0x2a5a, 0x0078, 0x10a2, 0x2c6a, 0x2a5a, 0x2130, 0x2128,
-	0xa1a2, 0x4e00, 0x8424, 0x8424, 0x8424, 0x8424, 0x8424, 0x8424,
-	0xa192, 0x9800, 0x2009, 0x0000, 0x2001, 0x0032, 0x1078, 0x207a,
-	0x2218, 0x2079, 0x4e00, 0x2fa0, 0x2408, 0x2011, 0x0000, 0x20a9,
+	0xa1a2, 0x4f00, 0x8424, 0x8424, 0x8424, 0x8424, 0x8424, 0x8424,
+	0xa192, 0x9900, 0x2009, 0x0000, 0x2001, 0x0032, 0x1078, 0x20c1,
+	0x2218, 0x2079, 0x4f00, 0x2fa0, 0x2408, 0x2011, 0x0000, 0x20a9,
 	0x0040, 0x42a4, 0x8109, 0x00c0, 0x10bf, 0x2009, 0xff00, 0x3400,
 	0xa102, 0x0048, 0x10cf, 0x0040, 0x10cf, 0x20a8, 0x42a4, 0x2001,
 	0x04fc, 0x2004, 0xa086, 0x1080, 0x00c0, 0x10e5, 0x2071, 0x0100,
-	0x0d7e, 0x2069, 0x4e40, 0x1078, 0x4cdd, 0x0d7f, 0x7810, 0xc0ed,
+	0x0d7e, 0x2069, 0x4f40, 0x1078, 0x4db0, 0x0d7f, 0x7810, 0xc0ed,
 	0x7812, 0x781b, 0x0064, 0x0078, 0x110a, 0x2001, 0x04fc, 0x2004,
 	0xa086, 0x1280, 0x00c0, 0x1105, 0x7814, 0xc0ed, 0xc0d5, 0x7816,
-	0x781b, 0x0064, 0x2071, 0x0200, 0x0d7e, 0x2069, 0x4e40, 0x1078,
-	0x4cdd, 0x2069, 0x4e80, 0x2071, 0x0100, 0x1078, 0x4cdd, 0x7814,
+	0x781b, 0x0064, 0x2071, 0x0200, 0x0d7e, 0x2069, 0x4f40, 0x1078,
+	0x4db0, 0x2069, 0x4f80, 0x2071, 0x0100, 0x1078, 0x4db0, 0x7814,
 	0xc0d4, 0x7816, 0x0d7f, 0x0078, 0x110a, 0x7814, 0xc0e5, 0x7816,
 	0x781b, 0x003c, 0x7eca, 0x7cc2, 0x7bc6, 0x7867, 0x0000, 0x7800,
 	0xc08d, 0x7802, 0x2031, 0x0030, 0x78af, 0x0101, 0x7823, 0x0002,
-	0x7827, 0x0002, 0x2009, 0x0002, 0x2069, 0x4e40, 0x681b, 0x0003,
+	0x7827, 0x0002, 0x2009, 0x0002, 0x2069, 0x4f40, 0x681b, 0x0003,
 	0x6823, 0x0007, 0x6827, 0x00fa, 0x682b, 0x0008, 0x682f, 0x0028,
 	0x6837, 0x0000, 0x683b, 0x0006, 0x6833, 0x0008, 0x683f, 0x0000,
-	0x8109, 0x0040, 0x115e, 0x68d3, 0x000a, 0x68c3, 0x4ec0, 0x2079,
-	0x4e00, 0x7814, 0xd0e4, 0x00c0, 0x1144, 0xd0ec, 0x00c0, 0x1148,
+	0x8109, 0x0040, 0x115e, 0x68d3, 0x000a, 0x68c3, 0x4fc0, 0x2079,
+	0x4f00, 0x7814, 0xd0e4, 0x00c0, 0x1144, 0xd0ec, 0x00c0, 0x1148,
 	0x68d7, 0x7329, 0x0078, 0x114a, 0x68d7, 0x730d, 0x0078, 0x114a,
-	0x68d7, 0x732d, 0x68c7, 0x53c0, 0x68cb, 0x52c0, 0x68cf, 0x93c0,
-	0x68ab, 0x9644, 0x68af, 0x9649, 0x68b3, 0x9644, 0x68b7, 0x9644,
-	0x68a7, 0x0001, 0x2069, 0x4e80, 0x0078, 0x111e, 0x68d3, 0x000a,
-	0x68c3, 0x50c0, 0x7814, 0xd0e4, 0x00c0, 0x116a, 0x68d7, 0x7439,
-	0x0078, 0x116c, 0x68d7, 0x7419, 0x68c7, 0x73c0, 0x68cb, 0x5340,
-	0x68cf, 0x94d0, 0x68ab, 0x9649, 0x68af, 0x964e, 0x68b3, 0x9649,
-	0x68b7, 0x9649, 0x68a7, 0x0001, 0x7810, 0xd0ec, 0x00c0, 0x11c2,
-	0x7814, 0xd0e4, 0x00c0, 0x11b4, 0x0e7e, 0x2069, 0x52c0, 0x2071,
+	0x68d7, 0x732d, 0x68c7, 0x54c0, 0x68cb, 0x53c0, 0x68cf, 0x94c0,
+	0x68ab, 0x9744, 0x68af, 0x9749, 0x68b3, 0x9744, 0x68b7, 0x9744,
+	0x68a7, 0x0001, 0x2069, 0x4f80, 0x0078, 0x111e, 0x68d3, 0x000a,
+	0x68c3, 0x51c0, 0x7814, 0xd0e4, 0x00c0, 0x116a, 0x68d7, 0x7439,
+	0x0078, 0x116c, 0x68d7, 0x7419, 0x68c7, 0x74c0, 0x68cb, 0x5440,
+	0x68cf, 0x95d0, 0x68ab, 0x9749, 0x68af, 0x974e, 0x68b3, 0x9749,
+	0x68b7, 0x9749, 0x68a7, 0x0001, 0x7810, 0xd0ec, 0x00c0, 0x11c2,
+	0x7814, 0xd0e4, 0x00c0, 0x11b4, 0x0e7e, 0x2069, 0x53c0, 0x2071,
 	0x0200, 0x70ec, 0xd0e4, 0x00c0, 0x1195, 0x2019, 0x0c0c, 0x2021,
-	0x000c, 0x1078, 0x2009, 0x0078, 0x119b, 0x2019, 0x0c0a, 0x2021,
-	0x000a, 0x1078, 0x2009, 0x2069, 0x5340, 0x2071, 0x0100, 0x70ec,
+	0x000c, 0x1078, 0x2050, 0x0078, 0x119b, 0x2019, 0x0c0a, 0x2021,
+	0x000a, 0x1078, 0x2050, 0x2069, 0x5440, 0x2071, 0x0100, 0x70ec,
 	0xd0e4, 0x00c0, 0x11ab, 0x2019, 0x0c0c, 0x2021, 0x000c, 0x1078,
-	0x2009, 0x0078, 0x11b1, 0x2019, 0x0c0a, 0x2021, 0x000a, 0x1078,
-	0x2009, 0x0e7f, 0x0078, 0x11db, 0x2019, 0x0c0c, 0x2021, 0x000c,
-	0x2069, 0x52c0, 0x1078, 0x2009, 0x2069, 0x5340, 0x1078, 0x2009,
-	0x0078, 0x11db, 0x2069, 0x52c0, 0x0e7e, 0x2071, 0x0100, 0x70ec,
+	0x2050, 0x0078, 0x11b1, 0x2019, 0x0c0a, 0x2021, 0x000a, 0x1078,
+	0x2050, 0x0e7f, 0x0078, 0x11db, 0x2019, 0x0c0c, 0x2021, 0x000c,
+	0x2069, 0x53c0, 0x1078, 0x2050, 0x2069, 0x5440, 0x1078, 0x2050,
+	0x0078, 0x11db, 0x2069, 0x53c0, 0x0e7e, 0x2071, 0x0100, 0x70ec,
 	0xd0e4, 0x00c0, 0x11d4, 0x2019, 0x0c0c, 0x2021, 0x000c, 0x1078,
-	0x2009, 0x0e7f, 0x0078, 0x11db, 0x2019, 0x0c0a, 0x2021, 0x000a,
-	0x1078, 0x2009, 0x0e7f, 0x2011, 0x0002, 0x2069, 0x53c0, 0x2009,
+	0x2050, 0x0e7f, 0x0078, 0x11db, 0x2019, 0x0c0a, 0x2021, 0x000a,
+	0x1078, 0x2050, 0x0e7f, 0x2011, 0x0002, 0x2069, 0x54c0, 0x2009,
 	0x0002, 0x20a9, 0x0100, 0x6837, 0x0000, 0x680b, 0x0040, 0x7bc8,
 	0xa386, 0xfeff, 0x00c0, 0x11f2, 0x6817, 0x0100, 0x681f, 0x0064,
 	0x0078, 0x11f6, 0x6817, 0x0064, 0x681f, 0x0002, 0xade8, 0x0010,
 	0x00f0, 0x11e3, 0x8109, 0x00c0, 0x11e1, 0x8211, 0x0040, 0x1204,
-	0x2069, 0x73c0, 0x0078, 0x11df, 0x1078, 0x265b, 0x1078, 0x468e,
-	0x1078, 0x1dd4, 0x1078, 0x4c6f, 0x2091, 0x2100, 0x2079, 0x4e00,
+	0x2069, 0x74c0, 0x0078, 0x11df, 0x1078, 0x26a2, 0x1078, 0x4712,
+	0x1078, 0x1e1b, 0x1078, 0x4d42, 0x2091, 0x2100, 0x2079, 0x4f00,
 	0x7810, 0xd0ec, 0x0040, 0x1218, 0x2071, 0x0020, 0x0078, 0x121a,
-	0x2071, 0x0050, 0x2091, 0x2200, 0x2079, 0x4e00, 0x2071, 0x0020,
-	0x2091, 0x2300, 0x2079, 0x4e00, 0x7810, 0xd0ec, 0x0040, 0x122c,
-	0x2079, 0x0100, 0x0078, 0x122e, 0x2079, 0x0200, 0x2071, 0x4e40,
-	0x2091, 0x2400, 0x2079, 0x0100, 0x2071, 0x4e80, 0x2091, 0x2000,
-	0x2079, 0x4e00, 0x2071, 0x0010, 0x3200, 0xa085, 0x303d, 0x2090,
+	0x2071, 0x0050, 0x2091, 0x2200, 0x2079, 0x4f00, 0x2071, 0x0020,
+	0x2091, 0x2300, 0x2079, 0x4f00, 0x7810, 0xd0ec, 0x0040, 0x122c,
+	0x2079, 0x0100, 0x0078, 0x122e, 0x2079, 0x0200, 0x2071, 0x4f40,
+	0x2091, 0x2400, 0x2079, 0x0100, 0x2071, 0x4f80, 0x2091, 0x2000,
+	0x2079, 0x4f00, 0x2071, 0x0010, 0x3200, 0xa085, 0x303d, 0x2090,
 	0x2071, 0x0010, 0x70c3, 0x0000, 0x0090, 0x124d, 0x70c0, 0xa086,
-	0x0002, 0x00c0, 0x124d, 0x1078, 0x15ba, 0x2039, 0x0000, 0x7810,
+	0x0002, 0x00c0, 0x124d, 0x1078, 0x15c1, 0x2039, 0x0000, 0x7810,
 	0xd0ec, 0x00c0, 0x12cf, 0x1078, 0x148e, 0x78ac, 0xa005, 0x00c0,
 	0x126b, 0x0068, 0x1261, 0x786c, 0xa065, 0x0040, 0x1261, 0x1078,
-	0x2395, 0x1078, 0x20a1, 0x0068, 0x1278, 0x786c, 0xa065, 0x0040,
-	0x126b, 0x1078, 0x2395, 0x0068, 0x1278, 0x2009, 0x4e47, 0x2011,
-	0x4e87, 0x2104, 0x220c, 0xa105, 0x0040, 0x1278, 0x1078, 0x1f0a,
-	0x2071, 0x4e40, 0x70a4, 0xa005, 0x0040, 0x129d, 0x7450, 0xa485,
+	0x23dc, 0x1078, 0x20e8, 0x0068, 0x1278, 0x786c, 0xa065, 0x0040,
+	0x126b, 0x1078, 0x23dc, 0x0068, 0x1278, 0x2009, 0x4f47, 0x2011,
+	0x4f87, 0x2104, 0x220c, 0xa105, 0x0040, 0x1278, 0x1078, 0x1f51,
+	0x2071, 0x4f40, 0x70a4, 0xa005, 0x0040, 0x129d, 0x7450, 0xa485,
 	0x0000, 0x0040, 0x129d, 0x2079, 0x0200, 0x2091, 0x8000, 0x72d4,
-	0xa28c, 0x303d, 0x2190, 0x1078, 0x2b6a, 0x2091, 0x8000, 0x2091,
-	0x303d, 0x0068, 0x129d, 0x2079, 0x4e00, 0x786c, 0xa065, 0x0040,
-	0x129d, 0x2071, 0x0010, 0x1078, 0x2395, 0x00e0, 0x12a5, 0x2079,
-	0x4e00, 0x2071, 0x0010, 0x1078, 0x4a43, 0x2071, 0x4e80, 0x70a4,
+	0xa28c, 0x303d, 0x2190, 0x1078, 0x2bb1, 0x2091, 0x8000, 0x2091,
+	0x303d, 0x0068, 0x129d, 0x2079, 0x4f00, 0x786c, 0xa065, 0x0040,
+	0x129d, 0x2071, 0x0010, 0x1078, 0x23dc, 0x00e0, 0x12a5, 0x2079,
+	0x4f00, 0x2071, 0x0010, 0x1078, 0x4b16, 0x2071, 0x4f80, 0x70a4,
 	0xa005, 0x0040, 0x12bd, 0x7050, 0xa025, 0x0040, 0x12bd, 0x2079,
 	0x0100, 0x2091, 0x8000, 0x72d4, 0xa28c, 0x303d, 0x2190, 0x1078,
-	0x2b6a, 0x2091, 0x8000, 0x2091, 0x303d, 0x2079, 0x4e00, 0x2071,
+	0x2bb1, 0x2091, 0x8000, 0x2091, 0x303d, 0x2079, 0x4f00, 0x2071,
 	0x0010, 0x0068, 0x12c9, 0x786c, 0xa065, 0x0040, 0x12c9, 0x1078,
-	0x2395, 0x00e0, 0x1253, 0x1078, 0x4a43, 0x0078, 0x1253, 0x1078,
+	0x23dc, 0x00e0, 0x1253, 0x1078, 0x4b16, 0x0078, 0x1253, 0x1078,
 	0x148e, 0x78ac, 0xa005, 0x00c0, 0x12e7, 0x0068, 0x12dd, 0x786c,
-	0xa065, 0x0040, 0x12dd, 0x1078, 0x2395, 0x1078, 0x20a1, 0x0068,
-	0x12f1, 0x786c, 0xa065, 0x0040, 0x12e7, 0x1078, 0x2395, 0x0068,
-	0x12f1, 0x2009, 0x4e47, 0x2104, 0xa005, 0x0040, 0x12f1, 0x1078,
-	0x1f0a, 0x2071, 0x4e40, 0x70a4, 0xa005, 0x0040, 0x130c, 0x7450,
+	0xa065, 0x0040, 0x12dd, 0x1078, 0x23dc, 0x1078, 0x20e8, 0x0068,
+	0x12f1, 0x786c, 0xa065, 0x0040, 0x12e7, 0x1078, 0x23dc, 0x0068,
+	0x12f1, 0x2009, 0x4f47, 0x2104, 0xa005, 0x0040, 0x12f1, 0x1078,
+	0x1f51, 0x2071, 0x4f40, 0x70a4, 0xa005, 0x0040, 0x130c, 0x7450,
 	0xa485, 0x0000, 0x0040, 0x130c, 0x2079, 0x0100, 0x2091, 0x8000,
-	0x72d4, 0xa28c, 0x303d, 0x2190, 0x1078, 0x2b6a, 0x2091, 0x8000,
-	0x2091, 0x303d, 0x2079, 0x4e00, 0x2071, 0x0010, 0x0068, 0x1316,
-	0x786c, 0xa065, 0x0040, 0x1316, 0x1078, 0x2395, 0x00e0, 0x12cf,
-	0x1078, 0x4a43, 0x0078, 0x12cf, 0x133c, 0x133c, 0x133e, 0x133e,
+	0x72d4, 0xa28c, 0x303d, 0x2190, 0x1078, 0x2bb1, 0x2091, 0x8000,
+	0x2091, 0x303d, 0x2079, 0x4f00, 0x2071, 0x0010, 0x0068, 0x1316,
+	0x786c, 0xa065, 0x0040, 0x1316, 0x1078, 0x23dc, 0x00e0, 0x12cf,
+	0x1078, 0x4b16, 0x0078, 0x12cf, 0x133c, 0x133c, 0x133e, 0x133e,
 	0x134b, 0x134b, 0x134b, 0x134b, 0x1356, 0x1356, 0x1363, 0x1363,
 	0x134b, 0x134b, 0x134b, 0x134b, 0x133c, 0x133c, 0x133e, 0x133e,
 	0x134b, 0x134b, 0x134b, 0x134b, 0x1356, 0x1356, 0x1363, 0x1363,
 	0x134b, 0x134b, 0x134b, 0x134b, 0x0078, 0x133c, 0x007e, 0x107e,
-	0x127e, 0x2091, 0x2400, 0x1078, 0x298a, 0x127f, 0x107f, 0x007f,
+	0x127e, 0x2091, 0x2400, 0x1078, 0x29d1, 0x127f, 0x107f, 0x007f,
 	0x2091, 0x8001, 0x007c, 0x007e, 0x107e, 0x127e, 0x1078, 0x13c8,
 	0x127f, 0x107f, 0x007f, 0x2091, 0x8001, 0x007c, 0x007e, 0x107e,
-	0x127e, 0x2091, 0x2300, 0x1078, 0x298a, 0x127f, 0x107f, 0x007f,
+	0x127e, 0x2091, 0x2300, 0x1078, 0x29d1, 0x127f, 0x107f, 0x007f,
 	0x2091, 0x8001, 0x007c, 0x007e, 0x107e, 0x127e, 0x2091, 0x2300,
-	0x1078, 0x298a, 0x2091, 0x2400, 0x1078, 0x298a, 0x127f, 0x107f,
+	0x1078, 0x29d1, 0x2091, 0x2400, 0x1078, 0x29d1, 0x127f, 0x107f,
 	0x007f, 0x2091, 0x8001, 0x007c, 0x1394, 0x1394, 0x1396, 0x1396,
 	0x13a3, 0x13a3, 0x13a3, 0x13a3, 0x13ae, 0x13ae, 0x1396, 0x1396,
 	0x13a3, 0x13a3, 0x13a3, 0x13a3, 0x13af, 0x13af, 0x13af, 0x13af,
 	0x13af, 0x13af, 0x13af, 0x13af, 0x13af, 0x13af, 0x13af, 0x13af,
 	0x13af, 0x13af, 0x13af, 0x13af, 0x0078, 0x1394, 0x007e, 0x107e,
-	0x127e, 0x2091, 0x2300, 0x1078, 0x298a, 0x127f, 0x107f, 0x007f,
+	0x127e, 0x2091, 0x2300, 0x1078, 0x29d1, 0x127f, 0x107f, 0x007f,
 	0x2091, 0x8001, 0x007c, 0x007e, 0x107e, 0x127e, 0x1078, 0x13d5,
 	0x127f, 0x107f, 0x007f, 0x2091, 0x8001, 0x007c, 0x007c, 0x107e,
 	0x127e, 0x0d7e, 0x0e7e, 0x0f7e, 0x007e, 0x2071, 0x0100, 0x2069,
-	0x4e40, 0x2079, 0x4e00, 0x70ec, 0xa084, 0x1c00, 0x78e2, 0x1078,
-	0x4cdd, 0x007f, 0x0f7f, 0x0e7f, 0x0d7f, 0x127f, 0x107f, 0x007c,
+	0x4f40, 0x2079, 0x4f00, 0x70ec, 0xa084, 0x1c00, 0x78e2, 0x1078,
+	0x4db0, 0x007f, 0x0f7f, 0x0e7f, 0x0d7f, 0x127f, 0x107f, 0x007c,
 	0x3c00, 0xa084, 0x0007, 0x0079, 0x13cd, 0x13de, 0x13de, 0x13e0,
 	0x13e0, 0x13e5, 0x13e5, 0x13ea, 0x13ea, 0x3c00, 0xa084, 0x0003,
-	0x0079, 0x13da, 0x13de, 0x13de, 0x13f3, 0x13f3, 0x1078, 0x296b,
-	0x2091, 0x2200, 0x1078, 0x4768, 0x007c, 0x2091, 0x2100, 0x1078,
-	0x4768, 0x007c, 0x2091, 0x2100, 0x1078, 0x4768, 0x2091, 0x2200,
-	0x1078, 0x4768, 0x007c, 0x2091, 0x2100, 0x1078, 0x4768, 0x007c,
+	0x0079, 0x13da, 0x13de, 0x13de, 0x13f3, 0x13f3, 0x1078, 0x29b2,
+	0x2091, 0x2200, 0x1078, 0x47ec, 0x007c, 0x2091, 0x2100, 0x1078,
+	0x47ec, 0x007c, 0x2091, 0x2100, 0x1078, 0x47ec, 0x2091, 0x2200,
+	0x1078, 0x47ec, 0x007c, 0x2091, 0x2100, 0x1078, 0x47ec, 0x007c,
 	0x1418, 0x1418, 0x141a, 0x141a, 0x1427, 0x1427, 0x1427, 0x1427,
 	0x1432, 0x1432, 0x143f, 0x143f, 0x1427, 0x1427, 0x1427, 0x1427,
 	0x1450, 0x1450, 0x1450, 0x1450, 0x1450, 0x1450, 0x1450, 0x1450,
 	0x1450, 0x1450, 0x1450, 0x1450, 0x1450, 0x1450, 0x1450, 0x1450,
 	0x0078, 0x1418, 0x007e, 0x107e, 0x127e, 0x2091, 0x2400, 0x1078,
-	0x298a, 0x127f, 0x107f, 0x007f, 0x2091, 0x8001, 0x007c, 0x007e,
+	0x29d1, 0x127f, 0x107f, 0x007f, 0x2091, 0x8001, 0x007c, 0x007e,
 	0x107e, 0x127e, 0x1078, 0x13c8, 0x127f, 0x107f, 0x007f, 0x2091,
 	0x8001, 0x007c, 0x007e, 0x107e, 0x127e, 0x2091, 0x2300, 0x1078,
-	0x298a, 0x127f, 0x107f, 0x007f, 0x2091, 0x8001, 0x007c, 0x007e,
-	0x107e, 0x127e, 0x2091, 0x2300, 0x1078, 0x298a, 0x2091, 0x2400,
-	0x1078, 0x298a, 0x127f, 0x107f, 0x007f, 0x2091, 0x8001, 0x007c,
-	0x007e, 0x107e, 0x127e, 0x0d7e, 0x0e7e, 0x0f7e, 0x2079, 0x4e00,
-	0x2071, 0x0200, 0x2069, 0x4e40, 0x3d00, 0xd08c, 0x0040, 0x1466,
-	0x70ec, 0xa084, 0x1c00, 0x78e2, 0x1078, 0x4cdd, 0x3d00, 0xd084,
-	0x0040, 0x1474, 0x2069, 0x4e80, 0x2071, 0x0100, 0x70ec, 0xa084,
-	0x1c00, 0x78e6, 0x1078, 0x4cdd, 0x0f7f, 0x0e7f, 0x0d7f, 0x127f,
+	0x29d1, 0x127f, 0x107f, 0x007f, 0x2091, 0x8001, 0x007c, 0x007e,
+	0x107e, 0x127e, 0x2091, 0x2300, 0x1078, 0x29d1, 0x2091, 0x2400,
+	0x1078, 0x29d1, 0x127f, 0x107f, 0x007f, 0x2091, 0x8001, 0x007c,
+	0x007e, 0x107e, 0x127e, 0x0d7e, 0x0e7e, 0x0f7e, 0x2079, 0x4f00,
+	0x2071, 0x0200, 0x2069, 0x4f40, 0x3d00, 0xd08c, 0x0040, 0x1466,
+	0x70ec, 0xa084, 0x1c00, 0x78e2, 0x1078, 0x4db0, 0x3d00, 0xd084,
+	0x0040, 0x1474, 0x2069, 0x4f80, 0x2071, 0x0100, 0x70ec, 0xa084,
+	0x1c00, 0x78e6, 0x1078, 0x4db0, 0x0f7f, 0x0e7f, 0x0d7f, 0x127f,
 	0x107f, 0x007f, 0x007c, 0x7008, 0x800b, 0x00c8, 0x1489, 0x7007,
 	0x0002, 0xa08c, 0x01e0, 0x00c0, 0x148a, 0xd09c, 0x0040, 0x1489,
-	0x087a, 0x097a, 0x70c3, 0x4002, 0x0078, 0x15bd, 0x0068, 0x1513,
-	0x2061, 0x0000, 0x6018, 0xd084, 0x00c0, 0x1513, 0x7828, 0xa005,
-	0x00c0, 0x149e, 0x0010, 0x1514, 0x0078, 0x1513, 0x7910, 0xd1f4,
-	0x0040, 0x14a6, 0x2001, 0x4007, 0x0078, 0x15bc, 0x7914, 0xd1ec,
-	0x0040, 0x14c1, 0xd0fc, 0x0040, 0x14b7, 0x007e, 0x1078, 0x1d64,
-	0x007f, 0x0040, 0x14c1, 0x2001, 0x4007, 0x0078, 0x15bc, 0x007e,
-	0x1078, 0x1d54, 0x007f, 0x0040, 0x14c1, 0x2001, 0x4007, 0x0078,
-	0x15bc, 0x7910, 0xd0fc, 0x00c0, 0x14cb, 0x2061, 0x4e40, 0xc19c,
-	0xc7fc, 0x0078, 0x14cf, 0x2061, 0x4e80, 0xc19d, 0xc7fd, 0x6064,
-	0xa005, 0x00c0, 0x1513, 0x7912, 0x6083, 0x0000, 0x7828, 0xc0fc,
-	0xa086, 0x0018, 0x00c0, 0x14e0, 0x0c7e, 0x1078, 0x1b5b, 0x0c7f,
-	0x782b, 0x0000, 0x607c, 0xa065, 0x0040, 0x14f9, 0x0c7e, 0x609c,
-	0x1078, 0x1e49, 0x0c7f, 0x609f, 0x0000, 0x1078, 0x1c84, 0x2009,
-	0x0018, 0x6087, 0x0103, 0x1078, 0x1d74, 0x00c0, 0x150d, 0x1078,
-	0x1dc6, 0x7810, 0xd09c, 0x00c0, 0x1501, 0x2061, 0x4e40, 0x0078,
-	0x1505, 0x2061, 0x4e80, 0xc09c, 0x7812, 0x607f, 0x0000, 0x60d4,
-	0xd0dc, 0x0040, 0x1511, 0xc0dc, 0x60d6, 0x2001, 0x4005, 0x0078,
-	0x15bc, 0x0078, 0x15ba, 0x007c, 0x7810, 0xd0f4, 0x0040, 0x151c,
-	0x2001, 0x4007, 0x0078, 0x15bc, 0xa006, 0x70c2, 0x70c6, 0x70ca,
-	0x70ce, 0x70da, 0x70c0, 0xa03d, 0xa08a, 0x0040, 0x00c8, 0x152a,
-	0x0079, 0x1531, 0x2100, 0xa08a, 0x0040, 0x00c8, 0x15c8, 0x0079,
-	0x1571, 0x15ba, 0x1610, 0x15d9, 0x1648, 0x1680, 0x1680, 0x15d0,
-	0x1c9c, 0x168b, 0x15c8, 0x15dd, 0x15df, 0x15e1, 0x15e3, 0x1ca1,
-	0x15c8, 0x1699, 0x16f6, 0x1b7b, 0x1c96, 0x15e5, 0x19c0, 0x1a02,
-	0x1a3d, 0x1a8e, 0x197b, 0x1988, 0x199c, 0x19af, 0x17cb, 0x15c8,
-	0x172d, 0x173a, 0x1746, 0x1752, 0x1768, 0x1774, 0x1777, 0x1783,
-	0x178f, 0x1797, 0x17b3, 0x17bf, 0x15c8, 0x15c8, 0x15c8, 0x15c8,
-	0x17d8, 0x17ea, 0x1806, 0x183c, 0x1864, 0x1874, 0x1877, 0x18a8,
-	0x18d9, 0x18eb, 0x194a, 0x195a, 0x15c8, 0x15c8, 0x15c8, 0x15c8,
-	0x196a, 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x1cc6, 0x1ccc,
-	0x15c8, 0x15c8, 0x15c8, 0x1cd0, 0x1d15, 0x15c8, 0x15c8, 0x15c8,
-	0x15c8, 0x160a, 0x167a, 0x1693, 0x16f0, 0x1b75, 0x15c8, 0x15c8,
-	0x1b3e, 0x15c8, 0x1d19, 0x1cb8, 0x1cc2, 0x15c8, 0x15c8, 0x15c8,
-	0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8,
-	0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8,
-	0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8,
-	0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8,
-	0x15c8, 0x72ca, 0x71c6, 0x2001, 0x4006, 0x0078, 0x15bc, 0x73ce,
-	0x72ca, 0x71c6, 0x2001, 0x4000, 0x70c2, 0x0068, 0x15bd, 0x2061,
-	0x0000, 0x601b, 0x0001, 0x2091, 0x5000, 0x2091, 0x4080, 0x007c,
-	0x70c3, 0x4001, 0x0078, 0x15bd, 0x70c3, 0x4006, 0x0078, 0x15bd,
-	0x2099, 0x0041, 0x20a1, 0x0041, 0x20a9, 0x0005, 0x53a3, 0x0078,
-	0x15ba, 0x70c4, 0x70c3, 0x0004, 0x007a, 0x0078, 0x15ba, 0x0078,
-	0x15ba, 0x0078, 0x15ba, 0x0078, 0x15ba, 0x2091, 0x8000, 0x70c3,
-	0x0004, 0x70c7, 0x4953, 0x70cb, 0x5020, 0x70cf, 0x2020, 0x70d3,
-	0x0008, 0x2001, 0x000f, 0x70d6, 0x2079, 0x0000, 0x781b, 0x0001,
-	0x2031, 0x0030, 0x2059, 0x1000, 0x2029, 0x041a, 0x2051, 0x0445,
-	0x2061, 0x0447, 0x20c1, 0x0020, 0x2091, 0x5000, 0x2091, 0x4080,
-	0x0078, 0x0418, 0x75d8, 0x74dc, 0x75da, 0x74de, 0x0078, 0x1613,
-	0x2029, 0x0000, 0x2520, 0x71d0, 0x72c8, 0x73cc, 0x70c4, 0x20a0,
-	0x2099, 0x0030, 0x7003, 0x0001, 0x7007, 0x0006, 0x731a, 0x721e,
-	0x7422, 0x7526, 0x2021, 0x0040, 0x81ff, 0x0040, 0x15ba, 0xa182,
-	0x0040, 0x00c8, 0x162d, 0x2120, 0xa006, 0x2008, 0x8403, 0x7012,
-	0x7007, 0x0004, 0x7007, 0x0001, 0x7008, 0xd0fc, 0x0040, 0x1634,
-	0x7007, 0x0002, 0xa084, 0x01e0, 0x0040, 0x1642, 0x70c3, 0x4002,
-	0x0078, 0x15bd, 0x24a8, 0x53a5, 0x0078, 0x1624, 0x0078, 0x15ba,
-	0x2029, 0x0000, 0x2520, 0x71d0, 0x72c8, 0x73cc, 0x70c4, 0x2098,
-	0x20a1, 0x0030, 0x7003, 0x0000, 0x7007, 0x0006, 0x731a, 0x721e,
-	0x7422, 0x7526, 0x2021, 0x0040, 0x7007, 0x0006, 0x81ff, 0x0040,
-	0x15ba, 0xa182, 0x0040, 0x00c8, 0x1667, 0x2120, 0xa006, 0x2008,
-	0x8403, 0x7012, 0x24a8, 0x53a6, 0x7007, 0x0001, 0x7008, 0xd0fc,
-	0x0040, 0x166e, 0xa084, 0x01e0, 0x0040, 0x165c, 0x70c3, 0x4002,
-	0x0078, 0x15bd, 0x75d8, 0x74dc, 0x75da, 0x74de, 0x0078, 0x164b,
-	0x71c4, 0x70c8, 0x2114, 0xa79e, 0x0004, 0x00c0, 0x1688, 0x200a,
-	0x72ca, 0x0078, 0x15b9, 0x70c7, 0x0008, 0x70cb, 0x000f, 0x70cf,
-	0x0000, 0x0078, 0x15ba, 0x75d8, 0x76dc, 0x75da, 0x76de, 0x0078,
-	0x169c, 0x2029, 0x0000, 0x2530, 0x70c4, 0x72c8, 0x73cc, 0x74d0,
-	0x70c6, 0x72ca, 0x73ce, 0x74d2, 0xa005, 0x0040, 0x16eb, 0xa40a,
-	0x0040, 0x16ac, 0x00c8, 0x16b5, 0x8001, 0x7872, 0xa084, 0xfc00,
-	0x0040, 0x16b9, 0x78ac, 0xc085, 0x78ae, 0x2001, 0x4005, 0x0078,
-	0x15bc, 0x7b7e, 0x7a7a, 0x7e86, 0x7d82, 0x7c76, 0xa48c, 0xff00,
-	0x0040, 0x16d1, 0x8407, 0x8004, 0x8004, 0x810c, 0x810c, 0x810f,
-	0xa118, 0xa291, 0x0000, 0xa6b1, 0x0000, 0xa581, 0x0000, 0x0078,
-	0x16db, 0x8407, 0x8004, 0x8004, 0xa318, 0xa291, 0x0000, 0xa6b1,
-	0x0000, 0xa581, 0x0000, 0x731a, 0x721e, 0x7622, 0x7026, 0xa605,
-	0x0040, 0x16e5, 0x7a10, 0xc2c5, 0x7a12, 0x78ac, 0xa084, 0xfffc,
-	0x78ae, 0x0078, 0x16ee, 0x78ac, 0xc085, 0x78ae, 0x0078, 0x15ba,
-	0x75d8, 0x76dc, 0x75da, 0x76de, 0x0078, 0x16f9, 0x2029, 0x0000,
-	0x2530, 0x70c4, 0x72c8, 0x73cc, 0x74d4, 0x70c6, 0x72ca, 0x73ce,
-	0x74d6, 0xa005, 0x0040, 0x1728, 0xa40a, 0x0040, 0x1709, 0x00c8,
-	0x15bc, 0x8001, 0x7892, 0xa084, 0xfc00, 0x0040, 0x1716, 0x78ac,
-	0xc0c5, 0x78ae, 0x2001, 0x4005, 0x0078, 0x15bc, 0x7a9a, 0x7b9e,
-	0x7da2, 0x7ea6, 0x2600, 0xa505, 0x0040, 0x1721, 0x7a10, 0xc2c5,
-	0x7a12, 0x7c96, 0x78ac, 0xa084, 0xfcff, 0x78ae, 0x0078, 0x172b,
-	0x78ac, 0xc0c5, 0x78ae, 0x0078, 0x15ba, 0x2009, 0x0000, 0x786c,
-	0xa065, 0x0040, 0x1737, 0x8108, 0x6000, 0x0078, 0x1730, 0x7ac4,
-	0x0078, 0x15b8, 0x2009, 0x4e48, 0x210c, 0x7810, 0xd0ec, 0x00c0,
-	0x15b9, 0x2011, 0x4e88, 0x2214, 0x0078, 0x15b8, 0x2009, 0x4e49,
-	0x210c, 0x7810, 0xd0ec, 0x00c0, 0x15b9, 0x2011, 0x4e89, 0x2214,
-	0x0078, 0x15b8, 0x2061, 0x4e40, 0x6128, 0x622c, 0x8214, 0x8214,
-	0x8214, 0x7810, 0xd0ec, 0x00c0, 0x1766, 0x2061, 0x4e80, 0x6328,
-	0x73da, 0x632c, 0x831c, 0x831c, 0x831c, 0x73de, 0x0078, 0x15b8,
-	0x2009, 0x4e4c, 0x210c, 0x7810, 0xd0ec, 0x00c0, 0x15b9, 0x2011,
-	0x4e8c, 0x2214, 0x0078, 0x15b8, 0x7918, 0x0078, 0x15b9, 0x2009,
-	0x4e4d, 0x210c, 0x7810, 0xd0ec, 0x00c0, 0x15b9, 0x2011, 0x4e8d,
-	0x2214, 0x0078, 0x15b8, 0x2009, 0x4e4e, 0x210c, 0x7810, 0xd0ec,
-	0x00c0, 0x15b9, 0x2011, 0x4e8e, 0x2214, 0x0078, 0x15b8, 0x7920,
-	0x7810, 0xd0ec, 0x00c0, 0x15b9, 0x7a24, 0x0078, 0x15b8, 0x71c4,
-	0xd1fc, 0x00c0, 0x179f, 0x2011, 0x52c0, 0x0078, 0x17a1, 0x2011,
-	0x5340, 0x8107, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xa268,
-	0x6a00, 0x6804, 0xd09c, 0x0040, 0x17b0, 0x6b08, 0x0078, 0x17b1,
-	0x6b0c, 0x0078, 0x15b7, 0x77c4, 0x1078, 0x1de4, 0x2091, 0x8000,
-	0x6b1c, 0x6a14, 0x2091, 0x8001, 0x2708, 0x0078, 0x15b7, 0x2061,
-	0x4e40, 0x6118, 0x7810, 0xd0ec, 0x00c0, 0x15b9, 0x2061, 0x4e80,
-	0x6218, 0x0078, 0x15b8, 0x77c4, 0x1078, 0x1de4, 0x2091, 0x8000,
-	0x6908, 0x6a18, 0x6b10, 0x77da, 0x2091, 0x8001, 0x0078, 0x15b7,
-	0x71c4, 0x2110, 0xa294, 0x000f, 0xa282, 0x0010, 0x00c8, 0x15b2,
-	0x1078, 0x277f, 0xa384, 0x4000, 0x0040, 0x17e8, 0xa295, 0x0020,
-	0x0078, 0x15b7, 0x71c4, 0x2100, 0xc0bc, 0xa082, 0x0010, 0x00c8,
-	0x15b2, 0xd1bc, 0x00c0, 0x17f9, 0x2011, 0x4e48, 0x2204, 0x0078,
-	0x17fd, 0x2011, 0x4e88, 0x2204, 0xc0bd, 0x007e, 0x2100, 0xc0bc,
-	0x2012, 0x1078, 0x26dc, 0x017f, 0x0078, 0x15b9, 0x71c4, 0x2021,
-	0x4e49, 0x2404, 0x70c6, 0x2019, 0x0000, 0x0078, 0x1815, 0x71c8,
-	0x2021, 0x4e89, 0x2404, 0x70ca, 0xc3fd, 0x2011, 0x1834, 0x20a9,
-	0x0008, 0x2204, 0xa106, 0x0040, 0x1824, 0x8210, 0x00f0, 0x1819,
-	0x71c4, 0x72c8, 0x0078, 0x15b1, 0xa292, 0x1834, 0x027e, 0x2122,
-	0x017f, 0x1078, 0x26fd, 0x7810, 0xd0ec, 0x00c0, 0x1832, 0xd3fc,
-	0x0040, 0x180f, 0x0078, 0x15ba, 0x03e8, 0x00fa, 0x01f4, 0x02ee,
-	0x0004, 0x0001, 0x0002, 0x0003, 0x2061, 0x4e40, 0x6128, 0x622c,
+	0x087a, 0x097a, 0x70c3, 0x4002, 0x0078, 0x15c4, 0x0068, 0x151a,
+	0x2061, 0x0000, 0x6018, 0xd084, 0x00c0, 0x151a, 0x7828, 0xa005,
+	0x00c0, 0x149e, 0x0010, 0x151b, 0x0078, 0x151a, 0x7910, 0xd1f4,
+	0x0040, 0x14a4, 0x0078, 0x14b9, 0x7914, 0xd1ec, 0x0040, 0x14bd,
+	0xd0fc, 0x0040, 0x14b3, 0x007e, 0x1078, 0x1dae, 0x007f, 0x0040,
+	0x14bd, 0x0078, 0x14b9, 0x007e, 0x1078, 0x1da1, 0x007f, 0x0040,
+	0x14bd, 0x2001, 0x4007, 0x0078, 0x15c3, 0x7910, 0xd0fc, 0x00c0,
+	0x14c7, 0x2061, 0x4f40, 0xc19c, 0xc7fc, 0x0078, 0x14cb, 0x2061,
+	0x4f80, 0xc19d, 0xc7fd, 0x6064, 0xa005, 0x00c0, 0x151a, 0x7912,
+	0x6082, 0x7828, 0xc0fc, 0xa086, 0x0018, 0x00c0, 0x14db, 0x0c7e,
+	0x1078, 0x1b85, 0x0c7f, 0x782b, 0x0000, 0x607c, 0xa065, 0x0040,
+	0x1500, 0x0c7e, 0x609c, 0x1078, 0x1e90, 0x0c7f, 0x609f, 0x0000,
+	0x1078, 0x1cd5, 0x2009, 0x0018, 0x6087, 0x0103, 0x7810, 0x007e,
+	0x84ff, 0x00c0, 0x14f6, 0x85ff, 0x0040, 0x14f8, 0xc0c5, 0x7812,
+	0x1078, 0x1dbb, 0x007f, 0x7812, 0x00c0, 0x1514, 0x1078, 0x1e0d,
+	0x7810, 0xd09c, 0x00c0, 0x1508, 0x2061, 0x4f40, 0x0078, 0x150c,
+	0x2061, 0x4f80, 0xc09c, 0x7812, 0x607f, 0x0000, 0x60d4, 0xd0dc,
+	0x0040, 0x1518, 0xc0dc, 0x60d6, 0x2001, 0x4005, 0x0078, 0x15c3,
+	0x0078, 0x15c1, 0x007c, 0x7810, 0xd0f4, 0x0040, 0x1523, 0x2001,
+	0x4007, 0x0078, 0x15c3, 0xa006, 0x70c2, 0x70c6, 0x70ca, 0x70ce,
+	0x70da, 0x70c0, 0xa03d, 0xa08a, 0x0040, 0x00c8, 0x1531, 0x0079,
+	0x1538, 0x2100, 0xa08a, 0x0040, 0x00c8, 0x15cf, 0x0079, 0x1578,
+	0x15c1, 0x1617, 0x15e0, 0x164f, 0x1687, 0x1687, 0x15d7, 0x1ced,
+	0x1692, 0x15cf, 0x15e4, 0x15e6, 0x15e8, 0x15ea, 0x1cf2, 0x15cf,
+	0x16a0, 0x16fd, 0x1ba5, 0x1ce7, 0x15ec, 0x19ea, 0x1a2c, 0x1a67,
+	0x1ab8, 0x19a5, 0x19b2, 0x19c6, 0x19d9, 0x17eb, 0x15cf, 0x1734,
+	0x1741, 0x174d, 0x1759, 0x176f, 0x177b, 0x177e, 0x178a, 0x1796,
+	0x179e, 0x17d3, 0x17df, 0x15cf, 0x15cf, 0x15cf, 0x15cf, 0x17f8,
+	0x180a, 0x1826, 0x185c, 0x1884, 0x1894, 0x1897, 0x18c8, 0x18f9,
+	0x190b, 0x1974, 0x1984, 0x15cf, 0x15cf, 0x15cf, 0x15cf, 0x1994,
+	0x15cf, 0x15cf, 0x15cf, 0x15cf, 0x15cf, 0x1d17, 0x1d1d, 0x15cf,
+	0x15cf, 0x15cf, 0x1d21, 0x1d66, 0x15cf, 0x15cf, 0x15cf, 0x15cf,
+	0x1611, 0x1681, 0x169a, 0x16f7, 0x1b9f, 0x15cf, 0x15cf, 0x1b68,
+	0x15cf, 0x1d6a, 0x1d09, 0x1d13, 0x15cf, 0x15cf, 0x15cf, 0x15cf,
+	0x15cf, 0x15cf, 0x15cf, 0x15cf, 0x15cf, 0x15cf, 0x15cf, 0x15cf,
+	0x15cf, 0x15cf, 0x15cf, 0x15cf, 0x15cf, 0x15cf, 0x15cf, 0x15cf,
+	0x15cf, 0x15cf, 0x15cf, 0x15cf, 0x15cf, 0x15cf, 0x15cf, 0x15cf,
+	0x15cf, 0x15cf, 0x15cf, 0x15cf, 0x15cf, 0x15cf, 0x15cf, 0x15cf,
+	0x72ca, 0x71c6, 0x2001, 0x4006, 0x0078, 0x15c3, 0x73ce, 0x72ca,
+	0x71c6, 0x2001, 0x4000, 0x70c2, 0x0068, 0x15c4, 0x2061, 0x0000,
+	0x601b, 0x0001, 0x2091, 0x5000, 0x2091, 0x4080, 0x007c, 0x70c3,
+	0x4001, 0x0078, 0x15c4, 0x70c3, 0x4006, 0x0078, 0x15c4, 0x2099,
+	0x0041, 0x20a1, 0x0041, 0x20a9, 0x0005, 0x53a3, 0x0078, 0x15c1,
+	0x70c4, 0x70c3, 0x0004, 0x007a, 0x0078, 0x15c1, 0x0078, 0x15c1,
+	0x0078, 0x15c1, 0x0078, 0x15c1, 0x2091, 0x8000, 0x70c3, 0x0004,
+	0x70c7, 0x4953, 0x70cb, 0x5020, 0x70cf, 0x2020, 0x70d3, 0x0008,
+	0x2001, 0x000f, 0x70d6, 0x2079, 0x0000, 0x781b, 0x0001, 0x2031,
+	0x0030, 0x2059, 0x1000, 0x2029, 0x041a, 0x2051, 0x0445, 0x2061,
+	0x0447, 0x20c1, 0x0020, 0x2091, 0x5000, 0x2091, 0x4080, 0x0078,
+	0x0418, 0x75d8, 0x74dc, 0x75da, 0x74de, 0x0078, 0x161a, 0x2029,
+	0x0000, 0x2520, 0x71d0, 0x72c8, 0x73cc, 0x70c4, 0x20a0, 0x2099,
+	0x0030, 0x7003, 0x0001, 0x7007, 0x0006, 0x731a, 0x721e, 0x7422,
+	0x7526, 0x2021, 0x0040, 0x81ff, 0x0040, 0x15c1, 0xa182, 0x0040,
+	0x00c8, 0x1634, 0x2120, 0xa006, 0x2008, 0x8403, 0x7012, 0x7007,
+	0x0004, 0x7007, 0x0001, 0x7008, 0xd0fc, 0x0040, 0x163b, 0x7007,
+	0x0002, 0xa084, 0x01e0, 0x0040, 0x1649, 0x70c3, 0x4002, 0x0078,
+	0x15c4, 0x24a8, 0x53a5, 0x0078, 0x162b, 0x0078, 0x15c1, 0x2029,
+	0x0000, 0x2520, 0x71d0, 0x72c8, 0x73cc, 0x70c4, 0x2098, 0x20a1,
+	0x0030, 0x7003, 0x0000, 0x7007, 0x0006, 0x731a, 0x721e, 0x7422,
+	0x7526, 0x2021, 0x0040, 0x7007, 0x0006, 0x81ff, 0x0040, 0x15c1,
+	0xa182, 0x0040, 0x00c8, 0x166e, 0x2120, 0xa006, 0x2008, 0x8403,
+	0x7012, 0x24a8, 0x53a6, 0x7007, 0x0001, 0x7008, 0xd0fc, 0x0040,
+	0x1675, 0xa084, 0x01e0, 0x0040, 0x1663, 0x70c3, 0x4002, 0x0078,
+	0x15c4, 0x75d8, 0x74dc, 0x75da, 0x74de, 0x0078, 0x1652, 0x71c4,
+	0x70c8, 0x2114, 0xa79e, 0x0004, 0x00c0, 0x168f, 0x200a, 0x72ca,
+	0x0078, 0x15c0, 0x70c7, 0x0008, 0x70cb, 0x000f, 0x70cf, 0x000b,
+	0x0078, 0x15c1, 0x75d8, 0x76dc, 0x75da, 0x76de, 0x0078, 0x16a3,
+	0x2029, 0x0000, 0x2530, 0x70c4, 0x72c8, 0x73cc, 0x74d0, 0x70c6,
+	0x72ca, 0x73ce, 0x74d2, 0xa005, 0x0040, 0x16f2, 0xa40a, 0x0040,
+	0x16b3, 0x00c8, 0x16bc, 0x8001, 0x7872, 0xa084, 0xfc00, 0x0040,
+	0x16c0, 0x78ac, 0xc085, 0x78ae, 0x2001, 0x4005, 0x0078, 0x15c3,
+	0x7b7e, 0x7a7a, 0x7e86, 0x7d82, 0x7c76, 0xa48c, 0xff00, 0x0040,
+	0x16d8, 0x8407, 0x8004, 0x8004, 0x810c, 0x810c, 0x810f, 0xa118,
+	0xa291, 0x0000, 0xa6b1, 0x0000, 0xa581, 0x0000, 0x0078, 0x16e2,
+	0x8407, 0x8004, 0x8004, 0xa318, 0xa291, 0x0000, 0xa6b1, 0x0000,
+	0xa581, 0x0000, 0x731a, 0x721e, 0x7622, 0x7026, 0xa605, 0x0040,
+	0x16ec, 0x7a10, 0xc2c5, 0x7a12, 0x78ac, 0xa084, 0xfffc, 0x78ae,
+	0x0078, 0x16f5, 0x78ac, 0xc085, 0x78ae, 0x0078, 0x15c1, 0x75d8,
+	0x76dc, 0x75da, 0x76de, 0x0078, 0x1700, 0x2029, 0x0000, 0x2530,
+	0x70c4, 0x72c8, 0x73cc, 0x74d4, 0x70c6, 0x72ca, 0x73ce, 0x74d6,
+	0xa005, 0x0040, 0x172f, 0xa40a, 0x0040, 0x1710, 0x00c8, 0x1719,
+	0x8001, 0x7892, 0xa084, 0xfc00, 0x0040, 0x171d, 0x78ac, 0xc0c5,
+	0x78ae, 0x2001, 0x4005, 0x0078, 0x15c3, 0x7a9a, 0x7b9e, 0x7da2,
+	0x7ea6, 0x2600, 0xa505, 0x0040, 0x1728, 0x7a10, 0xc2c5, 0x7a12,
+	0x7c96, 0x78ac, 0xa084, 0xfcff, 0x78ae, 0x0078, 0x1732, 0x78ac,
+	0xc0c5, 0x78ae, 0x0078, 0x15c1, 0x2009, 0x0000, 0x786c, 0xa065,
+	0x0040, 0x173e, 0x8108, 0x6000, 0x0078, 0x1737, 0x7ac4, 0x0078,
+	0x15bf, 0x2009, 0x4f48, 0x210c, 0x7810, 0xd0ec, 0x00c0, 0x15c0,
+	0x2011, 0x4f88, 0x2214, 0x0078, 0x15bf, 0x2009, 0x4f49, 0x210c,
+	0x7810, 0xd0ec, 0x00c0, 0x15c0, 0x2011, 0x4f89, 0x2214, 0x0078,
+	0x15bf, 0x2061, 0x4f40, 0x6128, 0x622c, 0x8214, 0x8214, 0x8214,
+	0x7810, 0xd0ec, 0x00c0, 0x176d, 0x2061, 0x4f80, 0x6328, 0x73da,
+	0x632c, 0x831c, 0x831c, 0x831c, 0x73de, 0x0078, 0x15bf, 0x2009,
+	0x4f4c, 0x210c, 0x7810, 0xd0ec, 0x00c0, 0x15c0, 0x2011, 0x4f8c,
+	0x2214, 0x0078, 0x15bf, 0x7918, 0x0078, 0x15c0, 0x2009, 0x4f4d,
+	0x210c, 0x7810, 0xd0ec, 0x00c0, 0x15c0, 0x2011, 0x4f8d, 0x2214,
+	0x0078, 0x15bf, 0x2009, 0x4f4e, 0x210c, 0x7810, 0xd0ec, 0x00c0,
+	0x15c0, 0x2011, 0x4f8e, 0x2214, 0x0078, 0x15bf, 0x7920, 0x7810,
+	0xd0ec, 0x00c0, 0x15c0, 0x7a24, 0x0078, 0x15bf, 0x71c4, 0xd1fc,
+	0x00c0, 0x17a6, 0x2011, 0x53c0, 0x0078, 0x17a8, 0x2011, 0x5440,
+	0x8107, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xa268, 0x6a00,
+	0x6804, 0xd09c, 0x0040, 0x17b7, 0x6b08, 0x0078, 0x17b8, 0x6b0c,
+	0xd1fc, 0x00c0, 0x17bf, 0x2021, 0x023b, 0x0078, 0x17c1, 0x2021,
+	0x013b, 0x2424, 0x7914, 0xd1e4, 0x0040, 0x17cd, 0xd4c4, 0x00c0,
+	0x17cc, 0xc4d5, 0x0078, 0x17cd, 0xc4dd, 0xa4a4, 0x1c00, 0x74de,
+	0x71c4, 0x0078, 0x15be, 0x77c4, 0x1078, 0x1e2b, 0x2091, 0x8000,
+	0x6b1c, 0x6a14, 0x2091, 0x8001, 0x2708, 0x0078, 0x15be, 0x2061,
+	0x4f40, 0x6118, 0x7810, 0xd0ec, 0x00c0, 0x15c0, 0x2061, 0x4f80,
+	0x6218, 0x0078, 0x15bf, 0x77c4, 0x1078, 0x1e2b, 0x2091, 0x8000,
+	0x6908, 0x6a18, 0x6b10, 0x77da, 0x2091, 0x8001, 0x0078, 0x15be,
+	0x71c4, 0x2110, 0xa294, 0x000f, 0xa282, 0x0010, 0x00c8, 0x15b9,
+	0x1078, 0x27c6, 0xa384, 0x4000, 0x0040, 0x1808, 0xa295, 0x0020,
+	0x0078, 0x15be, 0x71c4, 0x2100, 0xc0bc, 0xa082, 0x0010, 0x00c8,
+	0x15b9, 0xd1bc, 0x00c0, 0x1819, 0x2011, 0x4f48, 0x2204, 0x0078,
+	0x181d, 0x2011, 0x4f88, 0x2204, 0xc0bd, 0x007e, 0x2100, 0xc0bc,
+	0x2012, 0x1078, 0x2723, 0x017f, 0x0078, 0x15c0, 0x71c4, 0x2021,
+	0x4f49, 0x2404, 0x70c6, 0x2019, 0x0000, 0x0078, 0x1835, 0x71c8,
+	0x2021, 0x4f89, 0x2404, 0x70ca, 0xc3fd, 0x2011, 0x1854, 0x20a9,
+	0x0008, 0x2204, 0xa106, 0x0040, 0x1844, 0x8210, 0x00f0, 0x1839,
+	0x71c4, 0x72c8, 0x0078, 0x15b8, 0xa292, 0x1854, 0x027e, 0x2122,
+	0x017f, 0x1078, 0x2744, 0x7810, 0xd0ec, 0x00c0, 0x1852, 0xd3fc,
+	0x0040, 0x182f, 0x0078, 0x15c1, 0x03e8, 0x00fa, 0x01f4, 0x02ee,
+	0x0004, 0x0001, 0x0002, 0x0003, 0x2061, 0x4f40, 0x6128, 0x622c,
 	0x8214, 0x8214, 0x8214, 0x70c4, 0x602a, 0x70c8, 0x8003, 0x8003,
-	0x8003, 0x602e, 0x7810, 0xd0ec, 0x00c0, 0x1862, 0x027e, 0x017e,
-	0x2061, 0x4e80, 0x6128, 0x622c, 0x8214, 0x8214, 0x8214, 0x70d8,
+	0x8003, 0x602e, 0x7810, 0xd0ec, 0x00c0, 0x1882, 0x027e, 0x017e,
+	0x2061, 0x4f80, 0x6128, 0x622c, 0x8214, 0x8214, 0x8214, 0x70d8,
 	0x602a, 0x70dc, 0x8003, 0x8003, 0x8003, 0x602e, 0x71da, 0x72de,
-	0x017f, 0x027f, 0x0078, 0x15b8, 0x2061, 0x4e40, 0x6130, 0x70c4,
-	0x6032, 0x7810, 0xd0ec, 0x00c0, 0x15b9, 0x2061, 0x4e80, 0x6230,
-	0x70c8, 0x6032, 0x0078, 0x15b8, 0x7918, 0x0078, 0x15b9, 0x71c4,
-	0xa184, 0xffcf, 0x0040, 0x1883, 0x7810, 0xd0ec, 0x00c0, 0x15b2,
-	0x72c8, 0x0078, 0x15b1, 0x2011, 0x4e4d, 0x2204, 0x2112, 0x007e,
-	0x2019, 0x0000, 0x1078, 0x2764, 0x7810, 0xd0ec, 0x0040, 0x1893,
-	0x017f, 0x0078, 0x15b9, 0x71c8, 0xa184, 0xffcf, 0x0040, 0x189c,
-	0x2110, 0x71c4, 0x0078, 0x15b1, 0x2011, 0x4e8d, 0x2204, 0x2112,
-	0x007e, 0xc3fd, 0x1078, 0x2764, 0x027f, 0x017f, 0x0078, 0x15b8,
-	0x71c4, 0xa182, 0x0010, 0x0048, 0x18b4, 0x7810, 0xd0ec, 0x00c0,
-	0x15b2, 0x72c8, 0x0078, 0x15b1, 0x2011, 0x4e4e, 0x2204, 0x007e,
-	0x2112, 0x2019, 0x0000, 0x1078, 0x2742, 0x7810, 0xd0ec, 0x0040,
-	0x18c4, 0x017f, 0x0078, 0x15b9, 0x71c8, 0xa182, 0x0010, 0x0048,
-	0x18cd, 0x2110, 0x71c4, 0x0078, 0x15b1, 0x2011, 0x4e8e, 0x2204,
-	0x007e, 0x2112, 0xc3fd, 0x1078, 0x2742, 0x027f, 0x017f, 0x0078,
-	0x15b8, 0x71c4, 0x72c8, 0xa184, 0xfffd, 0x00c0, 0x15b1, 0xa284,
-	0xfffd, 0x00c0, 0x15b1, 0x2100, 0x7920, 0x7822, 0x2200, 0x7a24,
-	0x7826, 0x0078, 0x15b8, 0x71c4, 0xd1fc, 0x00c0, 0x18f3, 0x2011,
-	0x52c0, 0x0078, 0x18f5, 0x2011, 0x5340, 0x8107, 0xa084, 0x000f,
-	0x8003, 0x8003, 0x8003, 0xa268, 0x2019, 0x0000, 0x72c8, 0x2091,
-	0x8000, 0x6800, 0x007e, 0xa226, 0x0040, 0x191e, 0x6a02, 0xd4ec,
-	0x0040, 0x190b, 0xc3a5, 0xd4e4, 0x0040, 0x190f, 0xc39d, 0xd4f4,
-	0x0040, 0x191e, 0x810f, 0xd2f4, 0x0040, 0x191a, 0x1078, 0x27c1,
-	0x0078, 0x191e, 0x1078, 0x279f, 0x0078, 0x191e, 0x72cc, 0x6808,
-	0xa206, 0x0040, 0x1940, 0xa2a4, 0x00ff, 0x7814, 0xd0e4, 0x00c0,
-	0x1931, 0xa482, 0x0028, 0x0048, 0x193d, 0x0040, 0x193d, 0x0078,
-	0x1935, 0xa482, 0x0043, 0x0048, 0x193d, 0x71c4, 0x71c6, 0x027f,
-	0x72ca, 0x2091, 0x8001, 0x0078, 0x15b3, 0x6a0a, 0xa39d, 0x000a,
-	0x6804, 0xa305, 0x6806, 0x027f, 0x6b0c, 0x71c4, 0x2091, 0x8001,
-	0x0078, 0x15b7, 0x77c4, 0x1078, 0x1de4, 0x2091, 0x8000, 0x6a14,
-	0x6b1c, 0x2091, 0x8001, 0x70c8, 0x6816, 0x70cc, 0x681e, 0x2708,
-	0x0078, 0x15b7, 0x70c4, 0x2061, 0x4e40, 0x6118, 0x601a, 0x7810,
-	0xd0ec, 0x00c0, 0x15b9, 0x70c8, 0x2061, 0x4e80, 0x6218, 0x601a,
-	0x0078, 0x15b8, 0x71c4, 0x72c8, 0x73cc, 0xa182, 0x0010, 0x00c8,
-	0x15b2, 0x1078, 0x27e3, 0xa384, 0x4000, 0x0040, 0x1979, 0xa295,
-	0x0020, 0x0078, 0x15b7, 0x77c4, 0x1078, 0x1de4, 0x2091, 0x8000,
-	0x6a08, 0xc28d, 0x6a0a, 0x2091, 0x8001, 0x2708, 0x0078, 0x15b8,
-	0x77c4, 0x1078, 0x1de4, 0x2091, 0x8000, 0x6a08, 0xa294, 0xfff9,
-	0x6a0a, 0x6804, 0xa005, 0x0040, 0x1997, 0x1078, 0x2628, 0x2091,
-	0x8001, 0x2708, 0x0078, 0x15b8, 0x77c4, 0x1078, 0x1de4, 0x2091,
-	0x8000, 0x6a08, 0xc295, 0x6a0a, 0x6804, 0xa005, 0x0040, 0x19aa,
-	0x1078, 0x2628, 0x2091, 0x8001, 0x2708, 0x0078, 0x15b8, 0x77c4,
-	0x2041, 0x0001, 0x2049, 0x0005, 0x2051, 0x0020, 0x2091, 0x8000,
-	0x1078, 0x1dff, 0x2091, 0x8001, 0x2708, 0x6a08, 0x0078, 0x15b8,
-	0x77c4, 0x7814, 0xd0e4, 0x00c0, 0x19d4, 0xd7fc, 0x0040, 0x19ce,
-	0x1078, 0x1d64, 0x0040, 0x19d4, 0x0078, 0x15bc, 0x1078, 0x1d54,
-	0x0040, 0x19d4, 0x0078, 0x15bc, 0x73c8, 0x72cc, 0x77c6, 0x73ca,
-	0x72ce, 0x1078, 0x1e86, 0x00c0, 0x19fe, 0x6818, 0xa005, 0x0040,
-	0x19f8, 0x2708, 0x077e, 0x1078, 0x2813, 0x077f, 0x00c0, 0x19f8,
-	0x2001, 0x0015, 0xd7fc, 0x00c0, 0x19f1, 0x2061, 0x4e40, 0x0078,
-	0x19f4, 0xc0fd, 0x2061, 0x4e80, 0x782a, 0x2091, 0x8001, 0x007c,
-	0x2091, 0x8001, 0x2001, 0x4005, 0x0078, 0x15bc, 0x2091, 0x8001,
-	0x0078, 0x15ba, 0x77c4, 0x7814, 0xd0e4, 0x00c0, 0x1a16, 0xd7fc,
-	0x0040, 0x1a10, 0x1078, 0x1d64, 0x0040, 0x1a16, 0x0078, 0x15bc,
-	0x1078, 0x1d54, 0x0040, 0x1a16, 0x0078, 0x15bc, 0x77c6, 0x2041,
-	0x0021, 0x2049, 0x0005, 0x2051, 0x0020, 0x2091, 0x8000, 0x1078,
-	0x1dff, 0x2009, 0x0016, 0xd7fc, 0x00c0, 0x1a2a, 0x2061, 0x4e40,
-	0x0078, 0x1a2d, 0x2061, 0x4e80, 0xc1fd, 0x6067, 0x0003, 0x607f,
-	0x0000, 0x6776, 0x6083, 0x000f, 0x792a, 0x61d4, 0xc1dc, 0x61d6,
-	0x1078, 0x2628, 0x2091, 0x8001, 0x007c, 0x77c8, 0x77ca, 0x77c4,
-	0x77c6, 0x7814, 0xd0e4, 0x00c0, 0x1a54, 0xd7fc, 0x0040, 0x1a4e,
-	0x1078, 0x1d64, 0x0040, 0x1a54, 0x0078, 0x15bc, 0x1078, 0x1d54,
-	0x0040, 0x1a54, 0x0078, 0x15bc, 0xa7bc, 0xff00, 0x2091, 0x8000,
-	0x2009, 0x0017, 0xd7fc, 0x00c0, 0x1a61, 0x2061, 0x4e40, 0x0078,
-	0x1a64, 0x2061, 0x4e80, 0xc1fd, 0x607f, 0x0000, 0x6067, 0x0002,
-	0x6776, 0x6083, 0x000f, 0x792a, 0x61d4, 0xc1dc, 0x61d6, 0x1078,
-	0x2628, 0x2091, 0x8001, 0x2041, 0x0021, 0x2049, 0x0005, 0x2051,
-	0x0010, 0x2091, 0x8000, 0x70c8, 0xa005, 0x0040, 0x1a82, 0x60d4,
-	0xc0fd, 0x60d6, 0x1078, 0x1dff, 0x70c8, 0x6836, 0x8738, 0xa784,
-	0x001f, 0x00c0, 0x1a82, 0x2091, 0x8001, 0x007c, 0x2019, 0x0000,
-	0x7814, 0xd0e4, 0x00c0, 0x1aa4, 0x72c8, 0xd284, 0x0040, 0x1a9e,
-	0x1078, 0x1d64, 0x0040, 0x1aa4, 0x0078, 0x15bc, 0x1078, 0x1d54,
-	0x0040, 0x1aa4, 0x0078, 0x15bc, 0x72c8, 0x72ca, 0x78ac, 0xa084,
-	0x0003, 0x00c0, 0x1acf, 0x2039, 0x0000, 0xd284, 0x0040, 0x1ab1,
-	0xc7fd, 0x2041, 0x0021, 0x2049, 0x0004, 0x2051, 0x0008, 0x1078,
-	0x1de4, 0x2091, 0x8000, 0x6808, 0xc0d4, 0xa80d, 0x690a, 0x2091,
-	0x8001, 0x8738, 0xa784, 0x001f, 0x00c0, 0x1ab7, 0xa7bc, 0xff00,
-	0x873f, 0x8738, 0x873f, 0xa784, 0x0f00, 0x00c0, 0x1ab7, 0x2091,
-	0x8000, 0x72c8, 0xd284, 0x00c0, 0x1ae1, 0x7810, 0xd0ec, 0x0040,
-	0x1add, 0x2069, 0x0100, 0x0078, 0x1ae3, 0x2069, 0x0200, 0x0078,
-	0x1ae3, 0x2069, 0x0100, 0x6808, 0xa084, 0xfffd, 0x680a, 0x6830,
-	0xd0b4, 0x0040, 0x1b03, 0x684b, 0x0004, 0x20a9, 0x0014, 0x6848,
-	0xd094, 0x0040, 0x1af5, 0x00f0, 0x1aef, 0x684b, 0x0009, 0x20a9,
-	0x0014, 0x6848, 0xd084, 0x0040, 0x1aff, 0x00f0, 0x1af9, 0x20a9,
-	0x00fa, 0x00f0, 0x1b01, 0x2079, 0x4e00, 0x2009, 0x0018, 0x72c8,
-	0xd284, 0x00c0, 0x1b0f, 0x2061, 0x4e40, 0x0078, 0x1b12, 0x2061,
-	0x4e80, 0xc1fd, 0x607f, 0x0000, 0x792a, 0x6067, 0x0001, 0x6083,
-	0x000f, 0x60a7, 0x0000, 0x60a8, 0x60b2, 0x60b6, 0x60d4, 0xd0b4,
-	0x0040, 0x1b2e, 0xc0b4, 0x60d6, 0x0c7e, 0x60b8, 0xa065, 0x6008,
-	0xc0d4, 0x600a, 0x6018, 0x8001, 0x601a, 0x0c7f, 0x60d4, 0xa084,
-	0x77ff, 0x60d6, 0x78ac, 0xc08d, 0x78ae, 0x83ff, 0x0040, 0x1b39,
-	0x007c, 0x681b, 0x0047, 0x2091, 0x8001, 0x007c, 0x73cc, 0x1078,
-	0x1a90, 0x69ec, 0x6a48, 0xa185, 0x1800, 0x684a, 0xa185, 0x0040,
-	0x68ee, 0x73cc, 0x2021, 0x0004, 0x20a9, 0x09ff, 0x00f0, 0x1b4e,
-	0x8421, 0x00c0, 0x1b4c, 0x8319, 0x00c0, 0x1b4a, 0x69ee, 0x6a4a,
-	0x2091, 0x8001, 0x007c, 0xd7fc, 0x00c0, 0x1b62, 0x2069, 0x4e40,
-	0x0078, 0x1b64, 0x2069, 0x4e80, 0x71c4, 0x71c6, 0x6916, 0x81ff,
-	0x00c0, 0x1b6c, 0x68a7, 0x0001, 0x78ac, 0xc08c, 0x78ae, 0xd084,
-	0x00c0, 0x1b74, 0x1078, 0x1ee6, 0x007c, 0x75d8, 0x74dc, 0x75da,
-	0x74de, 0x0078, 0x1b7e, 0x2029, 0x0000, 0x2520, 0x71c4, 0x73c8,
-	0x72cc, 0x71c6, 0x73ca, 0x72ce, 0x2079, 0x4e00, 0x7dde, 0x7cda,
-	0x7bd6, 0x7ad2, 0x1078, 0x1dbd, 0x0040, 0x1c80, 0x20a9, 0x0005,
-	0x20a1, 0x4e14, 0x2091, 0x8000, 0x41a1, 0x2091, 0x8001, 0x2009,
-	0x0040, 0x1078, 0x1fd1, 0x0040, 0x1ba1, 0x1078, 0x1dc6, 0x0078,
-	0x1c80, 0x6004, 0xa08c, 0x00ff, 0xa18e, 0x0009, 0x00c0, 0x1bac,
-	0x007e, 0x1078, 0x2378, 0x007f, 0xa084, 0xff00, 0x8007, 0x8009,
-	0x0040, 0x1c20, 0x0c7e, 0x2c68, 0x1078, 0x1dbd, 0x0040, 0x1bf2,
-	0x2c00, 0x689e, 0x8109, 0x00c0, 0x1bb3, 0x609f, 0x0000, 0x0c7f,
-	0x0c7e, 0x7ddc, 0x7cd8, 0x7bd4, 0x7ad0, 0xa290, 0x0040, 0xa399,
-	0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x7dde, 0x7cda, 0x7bd6,
-	0x7ad2, 0x2c68, 0x689c, 0xa065, 0x0040, 0x1c1f, 0x2009, 0x0040,
-	0x1078, 0x1fd1, 0x00c0, 0x1c09, 0x6004, 0xa084, 0x00ff, 0xa086,
-	0x0002, 0x00c0, 0x1bf2, 0x6004, 0xa084, 0x00ff, 0xa086, 0x000a,
-	0x00c0, 0x1bee, 0x017e, 0x1078, 0x2374, 0x017f, 0x2d00, 0x6002,
-	0x0078, 0x1bc1, 0x0c7f, 0x0c7e, 0x609c, 0x1078, 0x1e49, 0x0c7f,
-	0x609f, 0x0000, 0x1078, 0x1c84, 0x2009, 0x0018, 0x6008, 0xc0cd,
-	0x600a, 0x6004, 0x6086, 0x1078, 0x1d74, 0x1078, 0x1dc6, 0x0078,
-	0x1c80, 0x0c7f, 0x0c7e, 0x609c, 0x1078, 0x1e49, 0x0c7f, 0x609f,
-	0x0000, 0x1078, 0x1c84, 0x2009, 0x0018, 0x6087, 0x0103, 0x601b,
-	0x0003, 0x1078, 0x1d74, 0x1078, 0x1dc6, 0x0078, 0x1c80, 0x0c7f,
-	0x7814, 0xd0e4, 0x00c0, 0x1c45, 0x6114, 0xd1fc, 0x0040, 0x1c2e,
-	0x1078, 0x1d64, 0x0040, 0x1c45, 0x0078, 0x1c32, 0x1078, 0x1d54,
-	0x0040, 0x1c45, 0x2029, 0x0000, 0x2520, 0x2009, 0x0018, 0x73c8,
-	0x72cc, 0x6087, 0x0103, 0x601b, 0x0021, 0x1078, 0x1d74, 0x1078,
-	0x1dc6, 0x2001, 0x4007, 0x0078, 0x15bc, 0x74c4, 0x73c8, 0x72cc,
-	0x6014, 0x2091, 0x8000, 0x0e7e, 0x2009, 0x0012, 0xd0fc, 0x00c0,
-	0x1c55, 0x2071, 0x4e40, 0x0078, 0x1c58, 0x2071, 0x4e80, 0xc1fd,
-	0x792a, 0x7067, 0x0005, 0x71d4, 0xc1dc, 0x71d6, 0x736a, 0x726e,
-	0x7472, 0x7076, 0x707b, 0x0000, 0x2c00, 0x707e, 0xa02e, 0x2530,
-	0x611c, 0xa184, 0x0060, 0x0040, 0x1c6f, 0x1078, 0x4632, 0x0e7f,
-	0x6596, 0x65a6, 0x669a, 0x66aa, 0x60af, 0x0000, 0x60b3, 0x0000,
-	0x6714, 0x6023, 0x0000, 0x1078, 0x2628, 0x2091, 0x8001, 0x007c,
-	0x70c3, 0x4005, 0x0078, 0x15bd, 0x20a9, 0x0005, 0x2099, 0x4e14,
-	0x2091, 0x8000, 0x530a, 0x2091, 0x8001, 0x2100, 0xa210, 0xa399,
-	0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x007c, 0x71c4, 0x70c7,
-	0x0000, 0x791e, 0x0078, 0x15ba, 0x71c4, 0x71c6, 0x2168, 0x0078,
-	0x1ca3, 0x2069, 0x1000, 0x690c, 0xa016, 0x2d04, 0xa210, 0x8d68,
-	0x8109, 0x00c0, 0x1ca5, 0xa285, 0x0000, 0x00c0, 0x1cb3, 0x70c3,
-	0x4000, 0x0078, 0x1cb5, 0x70c3, 0x4003, 0x70ca, 0x0078, 0x15bd,
-	0x7964, 0x71c6, 0x71c4, 0xa182, 0x0003, 0x00c8, 0x15b2, 0x7966,
-	0x0078, 0x15ba, 0x7964, 0x71c6, 0x0078, 0x15ba, 0x7900, 0x71c6,
-	0x71c4, 0x7902, 0x0078, 0x15ba, 0x7900, 0x71c6, 0x0078, 0x15ba,
-	0x70c4, 0x2011, 0x0000, 0xa08c, 0x000d, 0x0040, 0x1ce5, 0x810c,
-	0x0048, 0x1ce1, 0x8210, 0x810c, 0x810c, 0x0048, 0x1ce1, 0x8210,
-	0x810c, 0x81ff, 0x00c0, 0x15b3, 0x8210, 0x7a0e, 0xd28c, 0x0040,
-	0x1d11, 0x7910, 0xc1cd, 0x7912, 0x2009, 0x0021, 0x2019, 0x0003,
-	0xd284, 0x0040, 0x1d0b, 0x8108, 0x2019, 0x0041, 0x2011, 0x964e,
-	0x2312, 0x2019, 0x0042, 0x8210, 0x2312, 0x2019, 0x0043, 0x8210,
-	0x2312, 0x2019, 0x0046, 0x8210, 0x2312, 0x2019, 0x0047, 0x8210,
-	0x2312, 0x2019, 0x0006, 0x2011, 0x9653, 0x2112, 0x2011, 0x9673,
-	0x2312, 0x7904, 0x7806, 0x0078, 0x15b9, 0x7804, 0x70c6, 0x0078,
-	0x15ba, 0x71c4, 0xd1fc, 0x00c0, 0x1d21, 0x2011, 0x52c0, 0x0078,
-	0x1d23, 0x2011, 0x5340, 0x8107, 0xa084, 0x000f, 0x8003, 0x8003,
-	0x8003, 0xa268, 0x6a14, 0xd2b4, 0x0040, 0x1d32, 0x2011, 0x0001,
-	0x0078, 0x1d34, 0x2011, 0x0000, 0x6b0c, 0x6800, 0x70da, 0x0078,
-	0x15b7, 0x017e, 0x7814, 0xd0f4, 0x0040, 0x1d46, 0x2001, 0x4007,
-	0x70db, 0x0000, 0xa18d, 0x0001, 0x0078, 0x1d52, 0xd0fc, 0x0040,
-	0x1d51, 0x2001, 0x4007, 0x70db, 0x0001, 0xa18d, 0x0001, 0x0078,
-	0x1d52, 0xa006, 0x017f, 0x007c, 0x017e, 0x7814, 0xd0f4, 0x0040,
-	0x1d61, 0x2001, 0x4007, 0x70db, 0x0000, 0xa18d, 0x0001, 0x0078,
-	0x1d62, 0xa006, 0x017f, 0x007c, 0x017e, 0x7814, 0xd0fc, 0x0040,
-	0x1d71, 0x2001, 0x4007, 0x70db, 0x0001, 0xa18d, 0x0001, 0x0078,
-	0x1d72, 0xa006, 0x017f, 0x007c, 0x7112, 0x721a, 0x731e, 0x7810,
-	0xd0c4, 0x0040, 0x1d7d, 0x7422, 0x7526, 0xac80, 0x0001, 0x8108,
-	0x810c, 0x81a9, 0x8098, 0x20a1, 0x0030, 0x7003, 0x0000, 0x6084,
-	0x20a2, 0x53a6, 0x7007, 0x0001, 0x7974, 0xa184, 0xff00, 0x0040,
-	0x1d9a, 0x810f, 0x810c, 0x810c, 0x8004, 0x8004, 0x8007, 0xa100,
-	0x0078, 0x1d9d, 0x8107, 0x8004, 0x8004, 0x797c, 0xa108, 0x7a78,
-	0xa006, 0xa211, 0x7d10, 0xd5c4, 0x0040, 0x1daa, 0x7b84, 0xa319,
-	0x7c80, 0xa421, 0x7008, 0xd0fc, 0x0040, 0x1daa, 0x7003, 0x0001,
-	0x7007, 0x0006, 0x711a, 0x721e, 0x7d10, 0xd5c4, 0x0040, 0x1dba,
-	0x7322, 0x7426, 0xa084, 0x01e0, 0x007c, 0x7848, 0xa065, 0x0040,
-	0x1dc5, 0x2c04, 0x784a, 0x2063, 0x0000, 0x007c, 0x0f7e, 0x2079,
-	0x4e00, 0x7848, 0x2062, 0x2c00, 0xa005, 0x00c0, 0x1dd1, 0x1078,
-	0x296b, 0x784a, 0x0f7f, 0x007c, 0x2011, 0x9800, 0x7a4a, 0x7bc4,
-	0x8319, 0x0040, 0x1de1, 0xa280, 0x0032, 0x2012, 0x2010, 0x0078,
-	0x1dd8, 0x2013, 0x0000, 0x007c, 0x017e, 0x027e, 0xd7fc, 0x00c0,
-	0x1ded, 0x2011, 0x53c0, 0x0078, 0x1def, 0x2011, 0x73c0, 0xa784,
-	0x0f00, 0x800b, 0xa784, 0x001f, 0x0040, 0x1dfa, 0x8003, 0x8003,
-	0x8003, 0x8003, 0xa105, 0xa268, 0x027f, 0x017f, 0x007c, 0x1078,
-	0x1de4, 0x2900, 0x682a, 0x2a00, 0x682e, 0x6808, 0xa084, 0xf9ef,
-	0xa80d, 0x690a, 0x0e7e, 0xd7fc, 0x00c0, 0x1e14, 0x2009, 0x4e53,
-	0x2071, 0x4e40, 0x0078, 0x1e18, 0x2009, 0x4e93, 0x2071, 0x4e80,
-	0x210c, 0x6804, 0xa005, 0x0040, 0x1e28, 0xa116, 0x00c0, 0x1e28,
-	0x2060, 0x6000, 0x6806, 0x017e, 0x200b, 0x0000, 0x0078, 0x1e2b,
-	0x2009, 0x0000, 0x017e, 0x6804, 0xa065, 0x0040, 0x1e40, 0x6000,
-	0x6806, 0x1078, 0x1e5b, 0x1078, 0x201d, 0x6810, 0x7908, 0x8109,
-	0x790a, 0x8001, 0x6812, 0x00c0, 0x1e2b, 0x7910, 0xc1a5, 0x7912,
-	0x017f, 0x6902, 0x6906, 0x2d00, 0x2060, 0x1078, 0x2acc, 0x0e7f,
-	0x007c, 0xa065, 0x0040, 0x1e5a, 0x2008, 0x609c, 0xa005, 0x0040,
-	0x1e57, 0x2062, 0x609f, 0x0000, 0xa065, 0x0078, 0x1e4d, 0x7848,
-	0x794a, 0x2062, 0x007c, 0x6007, 0x0103, 0x608f, 0x0000, 0x20a9,
-	0x001c, 0xac80, 0x0005, 0x20a0, 0x2001, 0x0000, 0x40a4, 0x6828,
-	0x601a, 0x682c, 0x6022, 0x007c, 0x0e7e, 0xd7fc, 0x00c0, 0x1e76,
-	0x2071, 0x4e40, 0x2031, 0x4ec0, 0x0078, 0x1e7a, 0x2071, 0x4e80,
-	0x2031, 0x50c0, 0x7050, 0xa08c, 0x0200, 0x00c0, 0x1e84, 0xa608,
-	0x2d0a, 0x8000, 0x7052, 0xa006, 0x0e7f, 0x007c, 0x0f7e, 0xd7fc,
-	0x00c0, 0x1e8e, 0x2079, 0x4e40, 0x0078, 0x1e90, 0x2079, 0x4e80,
-	0x1078, 0x1de4, 0x2091, 0x8000, 0x6804, 0x780a, 0xa065, 0x0040,
-	0x1ee4, 0x0078, 0x1ea2, 0x2c00, 0x780a, 0x2060, 0x6000, 0xa065,
-	0x0040, 0x1ee4, 0x6010, 0xa306, 0x00c0, 0x1e9b, 0x600c, 0xa206,
-	0x00c0, 0x1e9b, 0x2c28, 0x784c, 0xac06, 0x00c0, 0x1eb1, 0x0078,
-	0x1ee1, 0x6804, 0xac06, 0x00c0, 0x1ebf, 0x6000, 0x2060, 0x6806,
-	0xa005, 0x00c0, 0x1ebf, 0x6803, 0x0000, 0x0078, 0x1ec9, 0x6400,
-	0x7808, 0x2060, 0x6402, 0xa486, 0x0000, 0x00c0, 0x1ec9, 0x2c00,
-	0x6802, 0x2560, 0x0f7f, 0x1078, 0x1e5b, 0x0f7e, 0x601b, 0x0005,
-	0x6023, 0x0020, 0x0f7f, 0x1078, 0x201d, 0x0f7e, 0x7908, 0x8109,
-	0x790a, 0x6810, 0x8001, 0x6812, 0x00c0, 0x1ee1, 0x7810, 0xc0a5,
-	0x7812, 0x2001, 0xffff, 0xa005, 0x0f7f, 0x007c, 0x077e, 0x2700,
-	0x2039, 0x0000, 0xd0fc, 0x0040, 0x1eee, 0xc7fd, 0x2041, 0x0021,
-	0x2049, 0x0004, 0x2051, 0x0008, 0x2091, 0x8000, 0x1078, 0x1dff,
-	0x8738, 0xa784, 0x001f, 0x00c0, 0x1ef6, 0xa7bc, 0xff00, 0x873f,
-	0x8738, 0x873f, 0xa784, 0x0f00, 0x00c0, 0x1ef6, 0x2091, 0x8001,
-	0x077f, 0x007c, 0x786c, 0x2009, 0x9674, 0x210c, 0xa10d, 0x0040,
-	0x1f14, 0xa065, 0x0078, 0x2395, 0x2061, 0x0000, 0x6018, 0xd084,
-	0x00c0, 0x1f34, 0x7810, 0xd08c, 0x0040, 0x1f25, 0xc08c, 0x7812,
-	0xc7fc, 0x2069, 0x4e40, 0x0078, 0x1f2a, 0xc08d, 0x7812, 0x2069,
-	0x4e80, 0xc7fd, 0x2091, 0x8000, 0x681c, 0x681f, 0x0000, 0x2091,
-	0x8001, 0xa005, 0x00c0, 0x1f35, 0x007c, 0xa08c, 0xfff0, 0x0040,
-	0x1f3b, 0x1078, 0x296b, 0x0079, 0x1f3d, 0x1f4d, 0x1f50, 0x1f56,
-	0x1f5a, 0x1f4e, 0x1f5e, 0x1f4e, 0x1f4e, 0x1f4e, 0x1f64, 0x1f95,
-	0x1f99, 0x1f9f, 0x1fb4, 0x1f4e, 0x1f4e, 0x007c, 0x1078, 0x296b,
-	0x1078, 0x1ee6, 0x2001, 0x8001, 0x0078, 0x1fc0, 0x2001, 0x8003,
-	0x0078, 0x1fc0, 0x2001, 0x8004, 0x0078, 0x1fc0, 0x1078, 0x1ee6,
-	0x2001, 0x8006, 0x0078, 0x1fc0, 0x2091, 0x8000, 0x077e, 0xd7fc,
-	0x00c0, 0x1f70, 0x2069, 0x4e40, 0x2039, 0x0009, 0x0078, 0x1f74,
-	0x2069, 0x4e80, 0x2039, 0x0009, 0x6800, 0xa086, 0x0000, 0x0040,
-	0x1f7e, 0x007f, 0x6f1e, 0x2091, 0x8001, 0x007c, 0x6874, 0x077f,
-	0xa0bc, 0xff00, 0x2041, 0x0021, 0x2049, 0x0004, 0x2051, 0x0010,
-	0x1078, 0x1dff, 0x8738, 0xa784, 0x001f, 0x00c0, 0x1f88, 0x2091,
-	0x8001, 0x2001, 0x800a, 0x0078, 0x1fc0, 0x2001, 0x800c, 0x0078,
-	0x1fc0, 0x1078, 0x1ee6, 0x2001, 0x800d, 0x0078, 0x1fc0, 0x7814,
-	0xd0e4, 0x00c0, 0x1fb2, 0xd0ec, 0x0040, 0x1fac, 0xd7fc, 0x0040,
-	0x1fac, 0x78e4, 0x0078, 0x1fad, 0x78e0, 0x70c6, 0x2001, 0x800e,
-	0x0078, 0x1fc0, 0x0078, 0x1f4e, 0xd7fc, 0x0040, 0x1fba, 0x78ec,
-	0x0078, 0x1fbb, 0x78e8, 0x70c6, 0x2001, 0x800f, 0x0078, 0x1fc0,
-	0x70c2, 0xd7fc, 0x00c0, 0x1fc8, 0x70db, 0x0000, 0x0078, 0x1fca,
-	0x70db, 0x0001, 0x2061, 0x0000, 0x601b, 0x0001, 0x2091, 0x4080,
-	0x007c, 0xac80, 0x0001, 0x81ff, 0x0040, 0x1ffc, 0x2099, 0x0030,
-	0x20a0, 0x700c, 0xa084, 0x03ff, 0x0040, 0x1fde, 0x7018, 0x007e,
-	0x701c, 0x007e, 0x7020, 0x007e, 0x7024, 0x007e, 0x7112, 0x81ac,
-	0x721a, 0x731e, 0x7422, 0x7526, 0x7003, 0x0001, 0x7007, 0x0001,
-	0x7008, 0x800b, 0x00c8, 0x1ff0, 0x7007, 0x0002, 0xa08c, 0x01e0,
-	0x00c0, 0x1ffc, 0x53a5, 0xa006, 0x7003, 0x0000, 0x7007, 0x0004,
-	0x007f, 0x7026, 0x007f, 0x7022, 0x007f, 0x701e, 0x007f, 0x701a,
-	0x007c, 0x2011, 0x0020, 0x2009, 0x0010, 0x6b0a, 0x6c0e, 0x6803,
-	0xfd00, 0x6807, 0x0018, 0x6a1a, 0x2d00, 0xa0e8, 0x0008, 0xa290,
-	0x0004, 0x8109, 0x00c0, 0x200d, 0x007c, 0x6004, 0x6086, 0x2c08,
-	0x2063, 0x0000, 0x7868, 0xa005, 0x796a, 0x0040, 0x202a, 0x2c02,
-	0x0078, 0x202b, 0x796e, 0x007c, 0x0c7e, 0x2061, 0x4e00, 0x6887,
-	0x0103, 0x2d08, 0x206b, 0x0000, 0x6068, 0xa005, 0x616a, 0x0040,
-	0x203c, 0x2d02, 0x0078, 0x203d, 0x616e, 0x0c7f, 0x007c, 0x2091,
-	0x8000, 0x2c04, 0x786e, 0xa005, 0x00c0, 0x2047, 0x786a, 0x2091,
-	0x8001, 0x609c, 0xa005, 0x0040, 0x2060, 0x0c7e, 0x2060, 0x2008,
-	0x609c, 0xa005, 0x0040, 0x205c, 0x2062, 0x609f, 0x0000, 0xa065,
-	0x609c, 0xa005, 0x00c0, 0x2054, 0x7848, 0x794a, 0x2062, 0x0c7f,
-	0x7848, 0x2062, 0x609f, 0x0000, 0xac85, 0x0000, 0x00c0, 0x206a,
-	0x1078, 0x296b, 0x784a, 0x007c, 0x20a9, 0x0010, 0xa006, 0x8004,
-	0x8086, 0x818e, 0x00c8, 0x2075, 0xa200, 0x00f0, 0x2070, 0x8086,
-	0x818e, 0x007c, 0x157e, 0x20a9, 0x0010, 0xa005, 0x0040, 0x209b,
-	0xa11a, 0x00c8, 0x209b, 0x8213, 0x818d, 0x0048, 0x208e, 0xa11a,
-	0x00c8, 0x208f, 0x00f0, 0x2083, 0x0078, 0x2093, 0xa11a, 0x2308,
-	0x8210, 0x00f0, 0x2083, 0x007e, 0x3200, 0xa084, 0xf7ff, 0x2080,
-	0x007f, 0x157f, 0x007c, 0x007e, 0x3200, 0xa085, 0x0800, 0x0078,
-	0x2097, 0x7d74, 0x70d0, 0xa506, 0x0040, 0x2187, 0x7810, 0x2050,
-	0x7800, 0xd08c, 0x0040, 0x20c3, 0xdaec, 0x0040, 0x20c3, 0x0e7e,
-	0x2091, 0x8000, 0x2071, 0x0020, 0x7004, 0xa005, 0x00c0, 0x20c0,
-	0x7008, 0x0e7f, 0xa086, 0x0008, 0x0040, 0x20c3, 0x0078, 0x2187,
-	0x0e7f, 0x0078, 0x2187, 0x1078, 0x1dbd, 0x0040, 0x2187, 0xa046,
-	0x7970, 0x2500, 0x8000, 0xa112, 0x2009, 0x0040, 0x00c8, 0x20d2,
-	0x0078, 0x20d9, 0x72d0, 0xa206, 0x0040, 0x20d9, 0x8840, 0x2009,
-	0x0080, 0x0c7e, 0x7112, 0x7007, 0x0001, 0x2099, 0x0030, 0x20a9,
-	0x0020, 0xac80, 0x0001, 0x20a0, 0x2061, 0x0000, 0x88ff, 0x0040,
-	0x20eb, 0x1078, 0x1dbd, 0x7008, 0xd0fc, 0x0040, 0x20eb, 0x7007,
-	0x0002, 0x2091, 0x8001, 0xa08c, 0x01e0, 0x00c0, 0x2122, 0x53a5,
-	0x8cff, 0x00c0, 0x2100, 0x88ff, 0x0040, 0x2171, 0x0078, 0x210a,
-	0x2c00, 0x788e, 0x20a9, 0x0020, 0xac80, 0x0001, 0x20a0, 0x53a5,
-	0x0078, 0x2171, 0xa046, 0x7218, 0x731c, 0xdac4, 0x0040, 0x2112,
-	0x7420, 0x7524, 0xa292, 0x0040, 0xa39b, 0x0000, 0xa4a3, 0x0000,
-	0xa5ab, 0x0000, 0x721a, 0x731e, 0xdac4, 0x0040, 0x2122, 0x7422,
-	0x7526, 0xa006, 0x7007, 0x0004, 0x0040, 0x2171, 0x8cff, 0x0040,
-	0x212b, 0x1078, 0x1dc6, 0x0c7f, 0x1078, 0x1dc6, 0xa046, 0x7888,
-	0x8000, 0x788a, 0xa086, 0x0002, 0x0040, 0x2151, 0x7a7c, 0x7b78,
-	0xdac4, 0x0040, 0x213d, 0x7c84, 0x7d80, 0x7974, 0x8107, 0x8004,
-	0x8004, 0xa210, 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000,
-	0x721a, 0x731e, 0xdac4, 0x0040, 0x2187, 0x7422, 0x7526, 0x0078,
-	0x2187, 0x6014, 0xd0fc, 0x00c0, 0x2159, 0x2069, 0x4e40, 0x0078,
-	0x215b, 0x2069, 0x4e80, 0x2091, 0x8000, 0x681f, 0x0002, 0x88ff,
-	0x0040, 0x2167, 0xa046, 0x788c, 0x2060, 0x0078, 0x2151, 0x788b,
-	0x0000, 0x78ac, 0xa085, 0x0003, 0x78ae, 0x2091, 0x8001, 0x0078,
-	0x2187, 0x0c7f, 0x788b, 0x0000, 0x1078, 0x2346, 0x6004, 0xa084,
-	0x000f, 0x1078, 0x2188, 0x88ff, 0x0040, 0x2185, 0x788c, 0x2060,
-	0x6004, 0xa084, 0x000f, 0x1078, 0x2188, 0x0078, 0x20a1, 0x007c,
-	0x0079, 0x218a, 0x219a, 0x21b8, 0x21d6, 0x219a, 0x21e7, 0x21ab,
-	0x219a, 0x219a, 0x219a, 0x21b6, 0x21d4, 0x219a, 0x219a, 0x219a,
-	0x219a, 0x219a, 0x2039, 0x0400, 0x78bc, 0xa705, 0x78be, 0x6008,
-	0xa705, 0x600a, 0x1078, 0x222a, 0x609c, 0x78ba, 0x609f, 0x0000,
-	0x1078, 0x2330, 0x007c, 0x78bc, 0xd0c4, 0x0040, 0x21b1, 0x0078,
-	0x219a, 0x601c, 0xc0bd, 0x601e, 0x0078, 0x21be, 0x1078, 0x2378,
-	0x78bc, 0xd0c4, 0x0040, 0x21be, 0x0078, 0x219a, 0x78bf, 0x0000,
-	0x6004, 0x8007, 0xa084, 0x00ff, 0x78b2, 0x8001, 0x0040, 0x21d1,
-	0x1078, 0x222a, 0x0040, 0x21d1, 0x78bc, 0xc0c5, 0x78be, 0x0078,
-	0x21d3, 0x0078, 0x2249, 0x007c, 0x1078, 0x2374, 0x78bc, 0xa08c,
-	0x0e00, 0x00c0, 0x21de, 0xd0c4, 0x00c0, 0x21e0, 0x0078, 0x219a,
-	0x1078, 0x222a, 0x00c0, 0x21e6, 0x0078, 0x2249, 0x007c, 0x78bc,
-	0xd0c4, 0x0040, 0x21ed, 0x0078, 0x219a, 0x78bf, 0x0000, 0x6714,
-	0x2011, 0x0001, 0x22a8, 0x6018, 0xa084, 0x00ff, 0xa005, 0x0040,
-	0x220d, 0xa7bc, 0xff00, 0x20a9, 0x0020, 0xa08e, 0x0001, 0x0040,
-	0x220d, 0xa7bc, 0x8000, 0x2011, 0x0002, 0x20a9, 0x0100, 0xa08e,
-	0x0002, 0x0040, 0x220d, 0x0078, 0x2227, 0x1078, 0x1de4, 0x2d00,
-	0x2091, 0x8000, 0x682b, 0x0000, 0x682f, 0x0000, 0x6808, 0xa084,
-	0xffde, 0x680a, 0xade8, 0x0010, 0x2091, 0x8001, 0x00f0, 0x2210,
-	0x8211, 0x0040, 0x2227, 0x20a9, 0x0100, 0x0078, 0x2210, 0x1078,
-	0x1dc6, 0x007c, 0x609f, 0x0000, 0x78b4, 0xa06d, 0x2c00, 0x78b6,
-	0x00c0, 0x2235, 0x78ba, 0x0078, 0x223d, 0x689e, 0x2d00, 0x6002,
-	0x78b8, 0xad06, 0x00c0, 0x223d, 0x6002, 0x78b0, 0x8001, 0x78b2,
-	0x00c0, 0x2248, 0x78bc, 0xc0c4, 0x78be, 0x78b8, 0x2060, 0xa006,
-	0x007c, 0x0e7e, 0xa02e, 0x2530, 0x7dba, 0x7db6, 0x65ae, 0x65b2,
-	0x601c, 0x60a2, 0x2048, 0xa984, 0xe1ff, 0x601e, 0xa984, 0x0060,
-	0x0040, 0x225c, 0x1078, 0x4632, 0x6596, 0x65a6, 0x669a, 0x66aa,
-	0x6714, 0x2071, 0x4e80, 0xd7fc, 0x00c0, 0x2268, 0x2071, 0x4e40,
-	0xa784, 0x0f00, 0x800b, 0xa784, 0x001f, 0x0040, 0x2273, 0x8003,
-	0x8003, 0x8003, 0x8003, 0xa105, 0x71c4, 0xa168, 0x2700, 0x8007,
-	0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0x71c8, 0xa100, 0x60c2,
-	0x2091, 0x8000, 0x7814, 0xd0c4, 0x0040, 0x2298, 0xd0ec, 0x0040,
-	0x2294, 0xd7fc, 0x00c0, 0x2291, 0xd0f4, 0x00c0, 0x229f, 0x0078,
-	0x2298, 0xd0fc, 0x00c0, 0x229f, 0x7810, 0xd0f4, 0x00c0, 0x229f,
-	0x6e08, 0xd684, 0x0040, 0x22c9, 0xd9fc, 0x00c0, 0x22c9, 0x2091,
-	0x8001, 0x1078, 0x1e5b, 0x2091, 0x8000, 0x1078, 0x201d, 0x2091,
-	0x8001, 0x7814, 0xd0e4, 0x00c0, 0x232e, 0x7814, 0xd0c4, 0x0040,
-	0x232e, 0xd0ec, 0x0040, 0x22c1, 0xd7fc, 0x00c0, 0x22bc, 0xd0f4,
-	0x00c0, 0x22c5, 0x0078, 0x232e, 0xd0fc, 0x00c0, 0x22c5, 0x0078,
-	0x232e, 0x7810, 0xd0f4, 0x0040, 0x232e, 0x601b, 0x0021, 0x0078,
-	0x232e, 0x6024, 0xa096, 0x0001, 0x00c0, 0x22d0, 0x8000, 0x6026,
-	0x6a10, 0x6814, 0xa202, 0x0048, 0x22e3, 0x0040, 0x22e3, 0x2091,
-	0x8001, 0x2039, 0x0200, 0x609c, 0x78ba, 0x609f, 0x0000, 0x1078,
-	0x2330, 0x0078, 0x232e, 0x2c08, 0xd9fc, 0x0040, 0x230b, 0x6800,
-	0xa065, 0x0040, 0x230b, 0x6a04, 0x7000, 0xa084, 0x0002, 0x0040,
-	0x2301, 0x704c, 0xa206, 0x00c0, 0x2301, 0x6b04, 0x2160, 0x2304,
-	0x6002, 0xa005, 0x00c0, 0x22fd, 0x6902, 0x2260, 0x6102, 0x0078,
-	0x2317, 0x2d00, 0x2060, 0x1078, 0x2acc, 0x6e08, 0x2160, 0x6202,
-	0x6906, 0x0078, 0x2317, 0x6800, 0x6902, 0xa065, 0x0040, 0x2313,
-	0x6102, 0x0078, 0x2314, 0x6906, 0x2160, 0x6003, 0x0000, 0x2160,
-	0xd9fc, 0x0040, 0x231e, 0xa6b4, 0xfffc, 0x6e0a, 0x6810, 0x7d08,
-	0x8528, 0x7d0a, 0x8000, 0x6812, 0x2091, 0x8001, 0xd6b4, 0x0040,
-	0x232e, 0xa6b6, 0x0040, 0x6e0a, 0x1078, 0x1e6c, 0x0e7f, 0x007c,
-	0x6008, 0xa705, 0x600a, 0x2091, 0x8000, 0x1078, 0x201d, 0x2091,
-	0x8001, 0x78b8, 0xa065, 0x0040, 0x2343, 0x609c, 0x78ba, 0x609f,
-	0x0000, 0x0078, 0x2330, 0x78b6, 0x78ba, 0x007c, 0x7970, 0x7874,
-	0x2818, 0xd384, 0x0040, 0x2350, 0x8000, 0xa112, 0x0048, 0x2355,
-	0x8000, 0xa112, 0x00c8, 0x2365, 0xc384, 0x7a7c, 0x721a, 0x7a78,
-	0x721e, 0xdac4, 0x0040, 0x2360, 0x7a84, 0x7222, 0x7a80, 0x7226,
-	0xa006, 0xd384, 0x0040, 0x2365, 0x8000, 0x7876, 0x70d2, 0x781c,
-	0xa005, 0x0040, 0x2373, 0x8001, 0x781e, 0x00c0, 0x2373, 0x0068,
-	0x2373, 0x2091, 0x4080, 0x007c, 0x2039, 0x238c, 0x0078, 0x237a,
-	0x2039, 0x2392, 0x2704, 0xa005, 0x0040, 0x238b, 0xac00, 0x2068,
-	0x6908, 0x6810, 0x6912, 0x680a, 0x690c, 0x6814, 0x6916, 0x680e,
-	0x8738, 0x0078, 0x237a, 0x007c, 0x0003, 0x0009, 0x000f, 0x0015,
-	0x001b, 0x0000, 0x0015, 0x001b, 0x0000, 0x2041, 0x0000, 0x780c,
-	0x0079, 0x239a, 0x256c, 0x253f, 0x239e, 0x2417, 0x2039, 0x9674,
-	0x2734, 0x7d10, 0x0078, 0x23be, 0x6084, 0xa086, 0x0103, 0x00c0,
-	0x2400, 0x6114, 0x6018, 0xa105, 0x0040, 0x23b3, 0x86ff, 0x00c0,
-	0x23cf, 0x0078, 0x2400, 0x8603, 0xa080, 0x9655, 0x620c, 0x2202,
-	0x8000, 0x6210, 0x2202, 0x1078, 0x203f, 0x8630, 0xa68e, 0x000f,
-	0x0040, 0x248b, 0x786c, 0xa065, 0x00c0, 0x23a4, 0x7808, 0xa602,
-	0x00c8, 0x23cf, 0xd5ac, 0x00c0, 0x23cf, 0x263a, 0x007c, 0xa682,
-	0x0003, 0x00c8, 0x248b, 0x2091, 0x8000, 0x2069, 0x0000, 0x6818,
-	0xd084, 0x00c0, 0x23fb, 0x2011, 0x9655, 0x2204, 0x70c6, 0x8210,
-	0x2204, 0x70ca, 0xd684, 0x00c0, 0x23eb, 0x8210, 0x2204, 0x70da,
-	0x8210, 0x2204, 0x70de, 0xa685, 0x8020, 0x70c2, 0x681b, 0x0001,
+	0x017f, 0x027f, 0x0078, 0x15bf, 0x2061, 0x4f40, 0x6130, 0x70c4,
+	0x6032, 0x7810, 0xd0ec, 0x00c0, 0x15c0, 0x2061, 0x4f80, 0x6230,
+	0x70c8, 0x6032, 0x0078, 0x15bf, 0x7918, 0x0078, 0x15c0, 0x71c4,
+	0xa184, 0xffcf, 0x0040, 0x18a3, 0x7810, 0xd0ec, 0x00c0, 0x15b9,
+	0x72c8, 0x0078, 0x15b8, 0x2011, 0x4f4d, 0x2204, 0x2112, 0x007e,
+	0x2019, 0x0000, 0x1078, 0x27ab, 0x7810, 0xd0ec, 0x0040, 0x18b3,
+	0x017f, 0x0078, 0x15c0, 0x71c8, 0xa184, 0xffcf, 0x0040, 0x18bc,
+	0x2110, 0x71c4, 0x0078, 0x15b8, 0x2011, 0x4f8d, 0x2204, 0x2112,
+	0x007e, 0xc3fd, 0x1078, 0x27ab, 0x027f, 0x017f, 0x0078, 0x15bf,
+	0x71c4, 0xa182, 0x0010, 0x0048, 0x18d4, 0x7810, 0xd0ec, 0x00c0,
+	0x15b9, 0x72c8, 0x0078, 0x15b8, 0x2011, 0x4f4e, 0x2204, 0x007e,
+	0x2112, 0x2019, 0x0000, 0x1078, 0x2789, 0x7810, 0xd0ec, 0x0040,
+	0x18e4, 0x017f, 0x0078, 0x15c0, 0x71c8, 0xa182, 0x0010, 0x0048,
+	0x18ed, 0x2110, 0x71c4, 0x0078, 0x15b8, 0x2011, 0x4f8e, 0x2204,
+	0x007e, 0x2112, 0xc3fd, 0x1078, 0x2789, 0x027f, 0x017f, 0x0078,
+	0x15bf, 0x71c4, 0x72c8, 0xa184, 0xfffd, 0x00c0, 0x15b8, 0xa284,
+	0xfffd, 0x00c0, 0x15b8, 0x2100, 0x7920, 0x7822, 0x2200, 0x7a24,
+	0x7826, 0x0078, 0x15bf, 0x71c4, 0xd1fc, 0x00c0, 0x1913, 0x2011,
+	0x53c0, 0x0078, 0x1915, 0x2011, 0x5440, 0x8107, 0xa084, 0x000f,
+	0x8003, 0x8003, 0x8003, 0xa268, 0x2019, 0x0000, 0x72c8, 0xd2bc,
+	0x0040, 0x1924, 0xa39d, 0x0010, 0xd2b4, 0x0040, 0x1929, 0xa39d,
+	0x0008, 0x2091, 0x8000, 0x6800, 0x007e, 0xa226, 0x0040, 0x1948,
+	0x6a02, 0xd4ec, 0x0040, 0x1935, 0xc3a5, 0xd4e4, 0x0040, 0x1939,
+	0xc39d, 0xd4f4, 0x0040, 0x1948, 0x810f, 0xd2f4, 0x0040, 0x1944,
+	0x1078, 0x2808, 0x0078, 0x1948, 0x1078, 0x27e6, 0x0078, 0x1948,
+	0x72cc, 0x6808, 0xa206, 0x0040, 0x196a, 0xa2a4, 0x00ff, 0x7814,
+	0xd0e4, 0x00c0, 0x195b, 0xa482, 0x0028, 0x0048, 0x1967, 0x0040,
+	0x1967, 0x0078, 0x195f, 0xa482, 0x0043, 0x0048, 0x1967, 0x71c4,
+	0x71c6, 0x027f, 0x72ca, 0x2091, 0x8001, 0x0078, 0x15ba, 0x6a0a,
+	0xa39d, 0x000a, 0x6804, 0xa305, 0x6806, 0x027f, 0x6b0c, 0x71c4,
+	0x2091, 0x8001, 0x0078, 0x15be, 0x77c4, 0x1078, 0x1e2b, 0x2091,
+	0x8000, 0x6a14, 0x6b1c, 0x2091, 0x8001, 0x70c8, 0x6816, 0x70cc,
+	0x681e, 0x2708, 0x0078, 0x15be, 0x70c4, 0x2061, 0x4f40, 0x6118,
+	0x601a, 0x7810, 0xd0ec, 0x00c0, 0x15c0, 0x70c8, 0x2061, 0x4f80,
+	0x6218, 0x601a, 0x0078, 0x15bf, 0x71c4, 0x72c8, 0x73cc, 0xa182,
+	0x0010, 0x00c8, 0x15b9, 0x1078, 0x282a, 0xa384, 0x4000, 0x0040,
+	0x19a3, 0xa295, 0x0020, 0x0078, 0x15be, 0x77c4, 0x1078, 0x1e2b,
+	0x2091, 0x8000, 0x6a08, 0xc28d, 0x6a0a, 0x2091, 0x8001, 0x2708,
+	0x0078, 0x15bf, 0x77c4, 0x1078, 0x1e2b, 0x2091, 0x8000, 0x6a08,
+	0xa294, 0xfff9, 0x6a0a, 0x6804, 0xa005, 0x0040, 0x19c1, 0x1078,
+	0x266f, 0x2091, 0x8001, 0x2708, 0x0078, 0x15bf, 0x77c4, 0x1078,
+	0x1e2b, 0x2091, 0x8000, 0x6a08, 0xc295, 0x6a0a, 0x6804, 0xa005,
+	0x0040, 0x19d4, 0x1078, 0x266f, 0x2091, 0x8001, 0x2708, 0x0078,
+	0x15bf, 0x77c4, 0x2041, 0x0001, 0x2049, 0x0005, 0x2051, 0x0020,
+	0x2091, 0x8000, 0x1078, 0x1e46, 0x2091, 0x8001, 0x2708, 0x6a08,
+	0x0078, 0x15bf, 0x77c4, 0x7814, 0xd0e4, 0x00c0, 0x19fe, 0xd7fc,
+	0x0040, 0x19f8, 0x1078, 0x1dae, 0x0040, 0x19fe, 0x0078, 0x15c3,
+	0x1078, 0x1da1, 0x0040, 0x19fe, 0x0078, 0x15c3, 0x73c8, 0x72cc,
+	0x77c6, 0x73ca, 0x72ce, 0x1078, 0x1ecd, 0x00c0, 0x1a28, 0x6818,
+	0xa005, 0x0040, 0x1a22, 0x2708, 0x077e, 0x1078, 0x285a, 0x077f,
+	0x00c0, 0x1a22, 0x2001, 0x0015, 0xd7fc, 0x00c0, 0x1a1b, 0x2061,
+	0x4f40, 0x0078, 0x1a1e, 0xc0fd, 0x2061, 0x4f80, 0x782a, 0x2091,
+	0x8001, 0x007c, 0x2091, 0x8001, 0x2001, 0x4005, 0x0078, 0x15c3,
+	0x2091, 0x8001, 0x0078, 0x15c1, 0x77c4, 0x7814, 0xd0e4, 0x00c0,
+	0x1a40, 0xd7fc, 0x0040, 0x1a3a, 0x1078, 0x1dae, 0x0040, 0x1a40,
+	0x0078, 0x15c3, 0x1078, 0x1da1, 0x0040, 0x1a40, 0x0078, 0x15c3,
+	0x77c6, 0x2041, 0x0021, 0x2049, 0x0005, 0x2051, 0x0020, 0x2091,
+	0x8000, 0x1078, 0x1e46, 0x2009, 0x0016, 0xd7fc, 0x00c0, 0x1a54,
+	0x2061, 0x4f40, 0x0078, 0x1a57, 0x2061, 0x4f80, 0xc1fd, 0x6067,
+	0x0003, 0x607f, 0x0000, 0x6776, 0x6083, 0x000f, 0x792a, 0x61d4,
+	0xc1dc, 0x61d6, 0x1078, 0x266f, 0x2091, 0x8001, 0x007c, 0x77c8,
+	0x77ca, 0x77c4, 0x77c6, 0x7814, 0xd0e4, 0x00c0, 0x1a7e, 0xd7fc,
+	0x0040, 0x1a78, 0x1078, 0x1dae, 0x0040, 0x1a7e, 0x0078, 0x15c3,
+	0x1078, 0x1da1, 0x0040, 0x1a7e, 0x0078, 0x15c3, 0xa7bc, 0xff00,
+	0x2091, 0x8000, 0x2009, 0x0017, 0xd7fc, 0x00c0, 0x1a8b, 0x2061,
+	0x4f40, 0x0078, 0x1a8e, 0x2061, 0x4f80, 0xc1fd, 0x607f, 0x0000,
+	0x6067, 0x0002, 0x6776, 0x6083, 0x000f, 0x792a, 0x61d4, 0xc1dc,
+	0x61d6, 0x1078, 0x266f, 0x2091, 0x8001, 0x2041, 0x0021, 0x2049,
+	0x0005, 0x2051, 0x0010, 0x2091, 0x8000, 0x70c8, 0xa005, 0x0040,
+	0x1aac, 0x60d4, 0xc0fd, 0x60d6, 0x1078, 0x1e46, 0x70c8, 0x6836,
+	0x8738, 0xa784, 0x001f, 0x00c0, 0x1aac, 0x2091, 0x8001, 0x007c,
+	0x2019, 0x0000, 0x7814, 0xd0e4, 0x00c0, 0x1ace, 0x72c8, 0xd284,
+	0x0040, 0x1ac8, 0x1078, 0x1dae, 0x0040, 0x1ace, 0x0078, 0x15c3,
+	0x1078, 0x1da1, 0x0040, 0x1ace, 0x0078, 0x15c3, 0x72c8, 0x72ca,
+	0x78ac, 0xa084, 0x0003, 0x00c0, 0x1af9, 0x2039, 0x0000, 0xd284,
+	0x0040, 0x1adb, 0xc7fd, 0x2041, 0x0021, 0x2049, 0x0004, 0x2051,
+	0x0008, 0x1078, 0x1e2b, 0x2091, 0x8000, 0x6808, 0xc0d4, 0xa80d,
+	0x690a, 0x2091, 0x8001, 0x8738, 0xa784, 0x001f, 0x00c0, 0x1ae1,
+	0xa7bc, 0xff00, 0x873f, 0x8738, 0x873f, 0xa784, 0x0f00, 0x00c0,
+	0x1ae1, 0x2091, 0x8000, 0x72c8, 0xd284, 0x00c0, 0x1b0b, 0x7810,
+	0xd0ec, 0x0040, 0x1b07, 0x2069, 0x0100, 0x0078, 0x1b0d, 0x2069,
+	0x0200, 0x0078, 0x1b0d, 0x2069, 0x0100, 0x6808, 0xa084, 0xfffd,
+	0x680a, 0x6830, 0xd0b4, 0x0040, 0x1b2d, 0x684b, 0x0004, 0x20a9,
+	0x0014, 0x6848, 0xd094, 0x0040, 0x1b1f, 0x00f0, 0x1b19, 0x684b,
+	0x0009, 0x20a9, 0x0014, 0x6848, 0xd084, 0x0040, 0x1b29, 0x00f0,
+	0x1b23, 0x20a9, 0x00fa, 0x00f0, 0x1b2b, 0x2079, 0x4f00, 0x2009,
+	0x0018, 0x72c8, 0xd284, 0x00c0, 0x1b39, 0x2061, 0x4f40, 0x0078,
+	0x1b3c, 0x2061, 0x4f80, 0xc1fd, 0x607f, 0x0000, 0x792a, 0x6067,
+	0x0001, 0x6083, 0x000f, 0x60a7, 0x0000, 0x60a8, 0x60b2, 0x60b6,
+	0x60d4, 0xd0b4, 0x0040, 0x1b58, 0xc0b4, 0x60d6, 0x0c7e, 0x60b8,
+	0xa065, 0x6008, 0xc0d4, 0x600a, 0x6018, 0x8001, 0x601a, 0x0c7f,
+	0x60d4, 0xa084, 0x77ff, 0x60d6, 0x78ac, 0xc08d, 0x78ae, 0x83ff,
+	0x0040, 0x1b63, 0x007c, 0x681b, 0x0047, 0x2091, 0x8001, 0x007c,
+	0x73cc, 0x1078, 0x1aba, 0x69ec, 0x6a48, 0xa185, 0x1800, 0x684a,
+	0xa185, 0x0040, 0x68ee, 0x73cc, 0x2021, 0x0004, 0x20a9, 0x09ff,
+	0x00f0, 0x1b78, 0x8421, 0x00c0, 0x1b76, 0x8319, 0x00c0, 0x1b74,
+	0x69ee, 0x6a4a, 0x2091, 0x8001, 0x007c, 0xd7fc, 0x00c0, 0x1b8c,
+	0x2069, 0x4f40, 0x0078, 0x1b8e, 0x2069, 0x4f80, 0x71c4, 0x71c6,
+	0x6916, 0x81ff, 0x00c0, 0x1b96, 0x68a7, 0x0001, 0x78ac, 0xc08c,
+	0x78ae, 0xd084, 0x00c0, 0x1b9e, 0x1078, 0x1f2d, 0x007c, 0x75d8,
+	0x74dc, 0x75da, 0x74de, 0x0078, 0x1ba7, 0xa02e, 0x2520, 0x71c4,
+	0x73c8, 0x72cc, 0x71c6, 0x73ca, 0x72ce, 0x2079, 0x4f00, 0x7dde,
+	0x7cda, 0x7bd6, 0x7ad2, 0x1078, 0x1e04, 0x0040, 0x1cd1, 0x20a9,
+	0x0005, 0x20a1, 0x4f14, 0x2091, 0x8000, 0x41a1, 0x2091, 0x8001,
+	0x2009, 0x0040, 0x1078, 0x2018, 0x0040, 0x1bca, 0x1078, 0x1e0d,
+	0x0078, 0x1cd1, 0x6004, 0xa08c, 0x00ff, 0xa18e, 0x0009, 0x00c0,
+	0x1bd5, 0x007e, 0x1078, 0x23bf, 0x007f, 0xa084, 0xff00, 0x8007,
+	0x8009, 0x0040, 0x1c61, 0x0c7e, 0x2c68, 0x1078, 0x1e04, 0x0040,
+	0x1c1b, 0x2c00, 0x689e, 0x8109, 0x00c0, 0x1bdc, 0x609f, 0x0000,
+	0x0c7f, 0x0c7e, 0x7ddc, 0x7cd8, 0x7bd4, 0x7ad0, 0xa290, 0x0040,
+	0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x7dde, 0x7cda,
+	0x7bd6, 0x7ad2, 0x2c68, 0x689c, 0xa065, 0x0040, 0x1c60, 0x2009,
+	0x0040, 0x1078, 0x2018, 0x00c0, 0x1c3e, 0x6004, 0xa084, 0x00ff,
+	0xa086, 0x0002, 0x00c0, 0x1c1b, 0x6004, 0xa084, 0x00ff, 0xa086,
+	0x000a, 0x00c0, 0x1c17, 0x017e, 0x1078, 0x23bb, 0x017f, 0x2d00,
+	0x6002, 0x0078, 0x1bea, 0x0c7f, 0x0c7e, 0x609c, 0x1078, 0x1e90,
+	0x0c7f, 0x609f, 0x0000, 0x1078, 0x1cd5, 0x2009, 0x0018, 0x6008,
+	0xc0cd, 0x600a, 0x6004, 0x6086, 0x7810, 0x007e, 0x84ff, 0x00c0,
+	0x1c34, 0x85ff, 0x0040, 0x1c36, 0xc0c5, 0x7812, 0x1078, 0x1dbb,
+	0x007f, 0x7812, 0x1078, 0x1e0d, 0x0078, 0x1cd1, 0x0c7f, 0x0c7e,
+	0x609c, 0x1078, 0x1e90, 0x0c7f, 0x609f, 0x0000, 0x1078, 0x1cd5,
+	0x2009, 0x0018, 0x6087, 0x0103, 0x601b, 0x0003, 0x7810, 0x007e,
+	0x84ff, 0x00c0, 0x1c56, 0x85ff, 0x0040, 0x1c58, 0xc0c5, 0x7812,
+	0x1078, 0x1dbb, 0x007f, 0x7812, 0x1078, 0x1e0d, 0x0078, 0x1cd1,
+	0x0c7f, 0x7814, 0xd0e4, 0x00c0, 0x1c8f, 0x6114, 0xd1fc, 0x0040,
+	0x1c6f, 0x1078, 0x1dae, 0x0040, 0x1c8f, 0x0078, 0x1c73, 0x1078,
+	0x1da1, 0x0040, 0x1c8f, 0x1078, 0x1cd5, 0x2009, 0x0018, 0x6087,
+	0x0103, 0x601b, 0x0021, 0x7810, 0x007e, 0x84ff, 0x00c0, 0x1c83,
+	0x85ff, 0x0040, 0x1c85, 0xc0c5, 0x7812, 0x1078, 0x1dbb, 0x007f,
+	0x7812, 0x1078, 0x1e0d, 0x2001, 0x4007, 0x0078, 0x15c3, 0x74c4,
+	0x73c8, 0x72cc, 0x6014, 0x2091, 0x8000, 0x0e7e, 0x2009, 0x0012,
+	0xd0fc, 0x00c0, 0x1c9f, 0x2071, 0x4f40, 0x0078, 0x1ca2, 0x2071,
+	0x4f80, 0xc1fd, 0x792a, 0x7067, 0x0005, 0x71d4, 0xc1dc, 0x71d6,
+	0x736a, 0x726e, 0x7472, 0x7076, 0x707b, 0x0000, 0x2c00, 0x707e,
+	0xa02e, 0x2530, 0x611c, 0xa184, 0x0060, 0x0040, 0x1cb9, 0x1078,
+	0x46b6, 0x0e7f, 0x6596, 0x65a6, 0x669a, 0x66aa, 0x60af, 0x0000,
+	0x60b3, 0x0000, 0x6714, 0x6023, 0x0000, 0x6024, 0xa096, 0x0001,
+	0x00c0, 0x1ccc, 0x8000, 0x6026, 0x1078, 0x266f, 0x2091, 0x8001,
+	0x007c, 0x70c3, 0x4005, 0x0078, 0x15c4, 0x20a9, 0x0005, 0x2099,
+	0x4f14, 0x2091, 0x8000, 0x530a, 0x2091, 0x8001, 0x2100, 0xa210,
+	0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x007c, 0x71c4,
+	0x70c7, 0x0000, 0x791e, 0x0078, 0x15c1, 0x71c4, 0x71c6, 0x2168,
+	0x0078, 0x1cf4, 0x2069, 0x1000, 0x690c, 0xa016, 0x2d04, 0xa210,
+	0x8d68, 0x8109, 0x00c0, 0x1cf6, 0xa285, 0x0000, 0x00c0, 0x1d04,
+	0x70c3, 0x4000, 0x0078, 0x1d06, 0x70c3, 0x4003, 0x70ca, 0x0078,
+	0x15c4, 0x7964, 0x71c6, 0x71c4, 0xa182, 0x0003, 0x00c8, 0x15b9,
+	0x7966, 0x0078, 0x15c1, 0x7964, 0x71c6, 0x0078, 0x15c1, 0x7900,
+	0x71c6, 0x71c4, 0x7902, 0x0078, 0x15c1, 0x7900, 0x71c6, 0x0078,
+	0x15c1, 0x70c4, 0x2011, 0x0000, 0xa08c, 0x000d, 0x0040, 0x1d36,
+	0x810c, 0x0048, 0x1d32, 0x8210, 0x810c, 0x810c, 0x0048, 0x1d32,
+	0x8210, 0x810c, 0x81ff, 0x00c0, 0x15ba, 0x8210, 0x7a0e, 0xd28c,
+	0x0040, 0x1d62, 0x7910, 0xc1cd, 0x7912, 0x2009, 0x0021, 0x2019,
+	0x0003, 0xd284, 0x0040, 0x1d5c, 0x8108, 0x2019, 0x0041, 0x2011,
+	0x974e, 0x2312, 0x2019, 0x0042, 0x8210, 0x2312, 0x2019, 0x0043,
+	0x8210, 0x2312, 0x2019, 0x0046, 0x8210, 0x2312, 0x2019, 0x0047,
+	0x8210, 0x2312, 0x2019, 0x0006, 0x2011, 0x9753, 0x2112, 0x2011,
+	0x9773, 0x2312, 0x7904, 0x7806, 0x0078, 0x15c0, 0x7804, 0x70c6,
+	0x0078, 0x15c1, 0x71c4, 0xd1fc, 0x00c0, 0x1d72, 0x2011, 0x53c0,
+	0x0078, 0x1d74, 0x2011, 0x5440, 0x8107, 0xa084, 0x000f, 0x8003,
+	0x8003, 0x8003, 0xa268, 0x6a14, 0xd2b4, 0x0040, 0x1d83, 0x2011,
+	0x0001, 0x0078, 0x1d85, 0x2011, 0x0000, 0x6b0c, 0x6800, 0x70da,
+	0x0078, 0x15be, 0x7814, 0xd0f4, 0x0040, 0x1d95, 0x2001, 0x4007,
+	0x70db, 0x0000, 0xa005, 0x0078, 0x1da0, 0xd0fc, 0x0040, 0x1d9f,
+	0x2001, 0x4007, 0x70db, 0x0001, 0xa005, 0x0078, 0x1da0, 0xa006,
+	0x007c, 0x7814, 0xd0f4, 0x0040, 0x1dac, 0x2001, 0x4007, 0x70db,
+	0x0000, 0xa005, 0x0078, 0x1dad, 0xa006, 0x007c, 0x7814, 0xd0fc,
+	0x0040, 0x1db9, 0x2001, 0x4007, 0x70db, 0x0001, 0xa005, 0x0078,
+	0x1dba, 0xa006, 0x007c, 0x7112, 0x721a, 0x731e, 0x7810, 0xd0c4,
+	0x0040, 0x1dc4, 0x7422, 0x7526, 0xac80, 0x0001, 0x8108, 0x810c,
+	0x81a9, 0x8098, 0x20a1, 0x0030, 0x7003, 0x0000, 0x6084, 0x20a2,
+	0x53a6, 0x7007, 0x0001, 0x7974, 0xa184, 0xff00, 0x0040, 0x1de1,
+	0x810f, 0x810c, 0x810c, 0x8004, 0x8004, 0x8007, 0xa100, 0x0078,
+	0x1de4, 0x8107, 0x8004, 0x8004, 0x797c, 0xa108, 0x7a78, 0xa006,
+	0xa211, 0x7d10, 0xd5c4, 0x0040, 0x1df1, 0x7b84, 0xa319, 0x7c80,
+	0xa421, 0x7008, 0xd0fc, 0x0040, 0x1df1, 0x7003, 0x0001, 0x7007,
+	0x0006, 0x711a, 0x721e, 0x7d10, 0xd5c4, 0x0040, 0x1e01, 0x7322,
+	0x7426, 0xa084, 0x01e0, 0x007c, 0x7848, 0xa065, 0x0040, 0x1e0c,
+	0x2c04, 0x784a, 0x2063, 0x0000, 0x007c, 0x0f7e, 0x2079, 0x4f00,
+	0x7848, 0x2062, 0x2c00, 0xa005, 0x00c0, 0x1e18, 0x1078, 0x29b2,
+	0x784a, 0x0f7f, 0x007c, 0x2011, 0x9900, 0x7a4a, 0x7bc4, 0x8319,
+	0x0040, 0x1e28, 0xa280, 0x0032, 0x2012, 0x2010, 0x0078, 0x1e1f,
+	0x2013, 0x0000, 0x007c, 0x017e, 0x027e, 0xd7fc, 0x00c0, 0x1e34,
+	0x2011, 0x54c0, 0x0078, 0x1e36, 0x2011, 0x74c0, 0xa784, 0x0f00,
+	0x800b, 0xa784, 0x001f, 0x0040, 0x1e41, 0x8003, 0x8003, 0x8003,
+	0x8003, 0xa105, 0xa268, 0x027f, 0x017f, 0x007c, 0x1078, 0x1e2b,
+	0x2900, 0x682a, 0x2a00, 0x682e, 0x6808, 0xa084, 0xf9ef, 0xa80d,
+	0x690a, 0x0e7e, 0xd7fc, 0x00c0, 0x1e5b, 0x2009, 0x4f53, 0x2071,
+	0x4f40, 0x0078, 0x1e5f, 0x2009, 0x4f93, 0x2071, 0x4f80, 0x210c,
+	0x6804, 0xa005, 0x0040, 0x1e6f, 0xa116, 0x00c0, 0x1e6f, 0x2060,
+	0x6000, 0x6806, 0x017e, 0x200b, 0x0000, 0x0078, 0x1e72, 0x2009,
+	0x0000, 0x017e, 0x6804, 0xa065, 0x0040, 0x1e87, 0x6000, 0x6806,
+	0x1078, 0x1ea2, 0x1078, 0x2064, 0x6810, 0x7908, 0x8109, 0x790a,
+	0x8001, 0x6812, 0x00c0, 0x1e72, 0x7910, 0xc1a5, 0x7912, 0x017f,
+	0x6902, 0x6906, 0x2d00, 0x2060, 0x1078, 0x2b13, 0x0e7f, 0x007c,
+	0xa065, 0x0040, 0x1ea1, 0x2008, 0x609c, 0xa005, 0x0040, 0x1e9e,
+	0x2062, 0x609f, 0x0000, 0xa065, 0x0078, 0x1e94, 0x7848, 0x794a,
+	0x2062, 0x007c, 0x6007, 0x0103, 0x608f, 0x0000, 0x20a9, 0x001c,
+	0xac80, 0x0005, 0x20a0, 0x2001, 0x0000, 0x40a4, 0x6828, 0x601a,
+	0x682c, 0x6022, 0x007c, 0x0e7e, 0xd7fc, 0x00c0, 0x1ebd, 0x2071,
+	0x4f40, 0x2031, 0x4fc0, 0x0078, 0x1ec1, 0x2071, 0x4f80, 0x2031,
+	0x51c0, 0x7050, 0xa08c, 0x0200, 0x00c0, 0x1ecb, 0xa608, 0x2d0a,
+	0x8000, 0x7052, 0xa006, 0x0e7f, 0x007c, 0x0f7e, 0xd7fc, 0x00c0,
+	0x1ed5, 0x2079, 0x4f40, 0x0078, 0x1ed7, 0x2079, 0x4f80, 0x1078,
+	0x1e2b, 0x2091, 0x8000, 0x6804, 0x780a, 0xa065, 0x0040, 0x1f2b,
+	0x0078, 0x1ee9, 0x2c00, 0x780a, 0x2060, 0x6000, 0xa065, 0x0040,
+	0x1f2b, 0x6010, 0xa306, 0x00c0, 0x1ee2, 0x600c, 0xa206, 0x00c0,
+	0x1ee2, 0x2c28, 0x784c, 0xac06, 0x00c0, 0x1ef8, 0x0078, 0x1f28,
+	0x6804, 0xac06, 0x00c0, 0x1f06, 0x6000, 0x2060, 0x6806, 0xa005,
+	0x00c0, 0x1f06, 0x6803, 0x0000, 0x0078, 0x1f10, 0x6400, 0x7808,
+	0x2060, 0x6402, 0xa486, 0x0000, 0x00c0, 0x1f10, 0x2c00, 0x6802,
+	0x2560, 0x0f7f, 0x1078, 0x1ea2, 0x0f7e, 0x601b, 0x0005, 0x6023,
+	0x0020, 0x0f7f, 0x1078, 0x2064, 0x0f7e, 0x7908, 0x8109, 0x790a,
+	0x6810, 0x8001, 0x6812, 0x00c0, 0x1f28, 0x7810, 0xc0a5, 0x7812,
+	0x2001, 0xffff, 0xa005, 0x0f7f, 0x007c, 0x077e, 0x2700, 0x2039,
+	0x0000, 0xd0fc, 0x0040, 0x1f35, 0xc7fd, 0x2041, 0x0021, 0x2049,
+	0x0004, 0x2051, 0x0008, 0x2091, 0x8000, 0x1078, 0x1e46, 0x8738,
+	0xa784, 0x001f, 0x00c0, 0x1f3d, 0xa7bc, 0xff00, 0x873f, 0x8738,
+	0x873f, 0xa784, 0x0f00, 0x00c0, 0x1f3d, 0x2091, 0x8001, 0x077f,
+	0x007c, 0x786c, 0x2009, 0x9774, 0x210c, 0xa10d, 0x0040, 0x1f5b,
+	0xa065, 0x0078, 0x23dc, 0x2061, 0x0000, 0x6018, 0xd084, 0x00c0,
+	0x1f7b, 0x7810, 0xd08c, 0x0040, 0x1f6c, 0xc08c, 0x7812, 0xc7fc,
+	0x2069, 0x4f40, 0x0078, 0x1f71, 0xc08d, 0x7812, 0x2069, 0x4f80,
+	0xc7fd, 0x2091, 0x8000, 0x681c, 0x681f, 0x0000, 0x2091, 0x8001,
+	0xa005, 0x00c0, 0x1f7c, 0x007c, 0xa08c, 0xfff0, 0x0040, 0x1f82,
+	0x1078, 0x29b2, 0x0079, 0x1f84, 0x1f94, 0x1f97, 0x1f9d, 0x1fa1,
+	0x1f95, 0x1fa5, 0x1f95, 0x1f95, 0x1f95, 0x1fab, 0x1fdc, 0x1fe0,
+	0x1fe6, 0x1ffb, 0x1f95, 0x1f95, 0x007c, 0x1078, 0x29b2, 0x1078,
+	0x1f2d, 0x2001, 0x8001, 0x0078, 0x2007, 0x2001, 0x8003, 0x0078,
+	0x2007, 0x2001, 0x8004, 0x0078, 0x2007, 0x1078, 0x1f2d, 0x2001,
+	0x8006, 0x0078, 0x2007, 0x2091, 0x8000, 0x077e, 0xd7fc, 0x00c0,
+	0x1fb7, 0x2069, 0x4f40, 0x2039, 0x0009, 0x0078, 0x1fbb, 0x2069,
+	0x4f80, 0x2039, 0x0009, 0x6800, 0xa086, 0x0000, 0x0040, 0x1fc5,
+	0x007f, 0x6f1e, 0x2091, 0x8001, 0x007c, 0x6874, 0x077f, 0xa0bc,
+	0xff00, 0x2041, 0x0021, 0x2049, 0x0004, 0x2051, 0x0010, 0x1078,
+	0x1e46, 0x8738, 0xa784, 0x001f, 0x00c0, 0x1fcf, 0x2091, 0x8001,
+	0x2001, 0x800a, 0x0078, 0x2007, 0x2001, 0x800c, 0x0078, 0x2007,
+	0x1078, 0x1f2d, 0x2001, 0x800d, 0x0078, 0x2007, 0x7814, 0xd0e4,
+	0x00c0, 0x1ff9, 0xd0ec, 0x0040, 0x1ff3, 0xd7fc, 0x0040, 0x1ff3,
+	0x78e4, 0x0078, 0x1ff4, 0x78e0, 0x70c6, 0x2001, 0x800e, 0x0078,
+	0x2007, 0x0078, 0x1f95, 0xd7fc, 0x0040, 0x2001, 0x78ec, 0x0078,
+	0x2002, 0x78e8, 0x70c6, 0x2001, 0x800f, 0x0078, 0x2007, 0x70c2,
+	0xd7fc, 0x00c0, 0x200f, 0x70db, 0x0000, 0x0078, 0x2011, 0x70db,
+	0x0001, 0x2061, 0x0000, 0x601b, 0x0001, 0x2091, 0x4080, 0x007c,
+	0xac80, 0x0001, 0x81ff, 0x0040, 0x2043, 0x2099, 0x0030, 0x20a0,
+	0x700c, 0xa084, 0x03ff, 0x0040, 0x2025, 0x7018, 0x007e, 0x701c,
+	0x007e, 0x7020, 0x007e, 0x7024, 0x007e, 0x7112, 0x81ac, 0x721a,
+	0x731e, 0x7422, 0x7526, 0x7003, 0x0001, 0x7007, 0x0001, 0x7008,
+	0x800b, 0x00c8, 0x2037, 0x7007, 0x0002, 0xa08c, 0x01e0, 0x00c0,
+	0x2043, 0x53a5, 0xa006, 0x7003, 0x0000, 0x7007, 0x0004, 0x007f,
+	0x7026, 0x007f, 0x7022, 0x007f, 0x701e, 0x007f, 0x701a, 0x007c,
+	0x2011, 0x0020, 0x2009, 0x0010, 0x6b0a, 0x6c0e, 0x6803, 0xfd00,
+	0x6807, 0x0018, 0x6a1a, 0x2d00, 0xa0e8, 0x0008, 0xa290, 0x0004,
+	0x8109, 0x00c0, 0x2054, 0x007c, 0x6004, 0x6086, 0x2c08, 0x2063,
+	0x0000, 0x7868, 0xa005, 0x796a, 0x0040, 0x2071, 0x2c02, 0x0078,
+	0x2072, 0x796e, 0x007c, 0x0c7e, 0x2061, 0x4f00, 0x6887, 0x0103,
+	0x2d08, 0x206b, 0x0000, 0x6068, 0xa005, 0x616a, 0x0040, 0x2083,
+	0x2d02, 0x0078, 0x2084, 0x616e, 0x0c7f, 0x007c, 0x2091, 0x8000,
+	0x2c04, 0x786e, 0xa005, 0x00c0, 0x208e, 0x786a, 0x2091, 0x8001,
+	0x609c, 0xa005, 0x0040, 0x20a7, 0x0c7e, 0x2060, 0x2008, 0x609c,
+	0xa005, 0x0040, 0x20a3, 0x2062, 0x609f, 0x0000, 0xa065, 0x609c,
+	0xa005, 0x00c0, 0x209b, 0x7848, 0x794a, 0x2062, 0x0c7f, 0x7848,
+	0x2062, 0x609f, 0x0000, 0xac85, 0x0000, 0x00c0, 0x20b1, 0x1078,
+	0x29b2, 0x784a, 0x007c, 0x20a9, 0x0010, 0xa006, 0x8004, 0x8086,
+	0x818e, 0x00c8, 0x20bc, 0xa200, 0x00f0, 0x20b7, 0x8086, 0x818e,
+	0x007c, 0x157e, 0x20a9, 0x0010, 0xa005, 0x0040, 0x20e2, 0xa11a,
+	0x00c8, 0x20e2, 0x8213, 0x818d, 0x0048, 0x20d5, 0xa11a, 0x00c8,
+	0x20d6, 0x00f0, 0x20ca, 0x0078, 0x20da, 0xa11a, 0x2308, 0x8210,
+	0x00f0, 0x20ca, 0x007e, 0x3200, 0xa084, 0xf7ff, 0x2080, 0x007f,
+	0x157f, 0x007c, 0x007e, 0x3200, 0xa085, 0x0800, 0x0078, 0x20de,
+	0x7d74, 0x70d0, 0xa506, 0x0040, 0x21ce, 0x7810, 0x2050, 0x7800,
+	0xd08c, 0x0040, 0x210a, 0xdaec, 0x0040, 0x210a, 0x0e7e, 0x2091,
+	0x8000, 0x2071, 0x0020, 0x7004, 0xa005, 0x00c0, 0x2107, 0x7008,
+	0x0e7f, 0xa086, 0x0008, 0x0040, 0x210a, 0x0078, 0x21ce, 0x0e7f,
+	0x0078, 0x21ce, 0x1078, 0x1e04, 0x0040, 0x21ce, 0xa046, 0x7970,
+	0x2500, 0x8000, 0xa112, 0x2009, 0x0040, 0x00c8, 0x2119, 0x0078,
+	0x2120, 0x72d0, 0xa206, 0x0040, 0x2120, 0x8840, 0x2009, 0x0080,
+	0x0c7e, 0x7112, 0x7007, 0x0001, 0x2099, 0x0030, 0x20a9, 0x0020,
+	0xac80, 0x0001, 0x20a0, 0x2061, 0x0000, 0x88ff, 0x0040, 0x2132,
+	0x1078, 0x1e04, 0x7008, 0xd0fc, 0x0040, 0x2132, 0x7007, 0x0002,
+	0x2091, 0x8001, 0xa08c, 0x01e0, 0x00c0, 0x2169, 0x53a5, 0x8cff,
+	0x00c0, 0x2147, 0x88ff, 0x0040, 0x21b8, 0x0078, 0x2151, 0x2c00,
+	0x788e, 0x20a9, 0x0020, 0xac80, 0x0001, 0x20a0, 0x53a5, 0x0078,
+	0x21b8, 0xa046, 0x7218, 0x731c, 0xdac4, 0x0040, 0x2159, 0x7420,
+	0x7524, 0xa292, 0x0040, 0xa39b, 0x0000, 0xa4a3, 0x0000, 0xa5ab,
+	0x0000, 0x721a, 0x731e, 0xdac4, 0x0040, 0x2169, 0x7422, 0x7526,
+	0xa006, 0x7007, 0x0004, 0x0040, 0x21b8, 0x8cff, 0x0040, 0x2172,
+	0x1078, 0x1e0d, 0x0c7f, 0x1078, 0x1e0d, 0xa046, 0x7888, 0x8000,
+	0x788a, 0xa086, 0x0002, 0x0040, 0x2198, 0x7a7c, 0x7b78, 0xdac4,
+	0x0040, 0x2184, 0x7c84, 0x7d80, 0x7974, 0x8107, 0x8004, 0x8004,
+	0xa210, 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x721a,
+	0x731e, 0xdac4, 0x0040, 0x21ce, 0x7422, 0x7526, 0x0078, 0x21ce,
+	0x6014, 0xd0fc, 0x00c0, 0x21a0, 0x2069, 0x4f40, 0x0078, 0x21a2,
+	0x2069, 0x4f80, 0x2091, 0x8000, 0x681f, 0x0002, 0x88ff, 0x0040,
+	0x21ae, 0xa046, 0x788c, 0x2060, 0x0078, 0x2198, 0x788b, 0x0000,
+	0x78ac, 0xa085, 0x0003, 0x78ae, 0x2091, 0x8001, 0x0078, 0x21ce,
+	0x0c7f, 0x788b, 0x0000, 0x1078, 0x238d, 0x6004, 0xa084, 0x000f,
+	0x1078, 0x21cf, 0x88ff, 0x0040, 0x21cc, 0x788c, 0x2060, 0x6004,
+	0xa084, 0x000f, 0x1078, 0x21cf, 0x0078, 0x20e8, 0x007c, 0x0079,
+	0x21d1, 0x21e1, 0x21ff, 0x221d, 0x21e1, 0x222e, 0x21f2, 0x21e1,
+	0x21e1, 0x21e1, 0x21fd, 0x221b, 0x21e1, 0x21e1, 0x21e1, 0x21e1,
+	0x21e1, 0x2039, 0x0400, 0x78bc, 0xa705, 0x78be, 0x6008, 0xa705,
+	0x600a, 0x1078, 0x2271, 0x609c, 0x78ba, 0x609f, 0x0000, 0x1078,
+	0x2377, 0x007c, 0x78bc, 0xd0c4, 0x0040, 0x21f8, 0x0078, 0x21e1,
+	0x601c, 0xc0bd, 0x601e, 0x0078, 0x2205, 0x1078, 0x23bf, 0x78bc,
+	0xd0c4, 0x0040, 0x2205, 0x0078, 0x21e1, 0x78bf, 0x0000, 0x6004,
+	0x8007, 0xa084, 0x00ff, 0x78b2, 0x8001, 0x0040, 0x2218, 0x1078,
+	0x2271, 0x0040, 0x2218, 0x78bc, 0xc0c5, 0x78be, 0x0078, 0x221a,
+	0x0078, 0x2290, 0x007c, 0x1078, 0x23bb, 0x78bc, 0xa08c, 0x0e00,
+	0x00c0, 0x2225, 0xd0c4, 0x00c0, 0x2227, 0x0078, 0x21e1, 0x1078,
+	0x2271, 0x00c0, 0x222d, 0x0078, 0x2290, 0x007c, 0x78bc, 0xd0c4,
+	0x0040, 0x2234, 0x0078, 0x21e1, 0x78bf, 0x0000, 0x6714, 0x2011,
+	0x0001, 0x22a8, 0x6018, 0xa084, 0x00ff, 0xa005, 0x0040, 0x2254,
+	0xa7bc, 0xff00, 0x20a9, 0x0020, 0xa08e, 0x0001, 0x0040, 0x2254,
+	0xa7bc, 0x8000, 0x2011, 0x0002, 0x20a9, 0x0100, 0xa08e, 0x0002,
+	0x0040, 0x2254, 0x0078, 0x226e, 0x1078, 0x1e2b, 0x2d00, 0x2091,
+	0x8000, 0x682b, 0x0000, 0x682f, 0x0000, 0x6808, 0xa084, 0xffde,
+	0x680a, 0xade8, 0x0010, 0x2091, 0x8001, 0x00f0, 0x2257, 0x8211,
+	0x0040, 0x226e, 0x20a9, 0x0100, 0x0078, 0x2257, 0x1078, 0x1e0d,
+	0x007c, 0x609f, 0x0000, 0x78b4, 0xa06d, 0x2c00, 0x78b6, 0x00c0,
+	0x227c, 0x78ba, 0x0078, 0x2284, 0x689e, 0x2d00, 0x6002, 0x78b8,
+	0xad06, 0x00c0, 0x2284, 0x6002, 0x78b0, 0x8001, 0x78b2, 0x00c0,
+	0x228f, 0x78bc, 0xc0c4, 0x78be, 0x78b8, 0x2060, 0xa006, 0x007c,
+	0x0e7e, 0xa02e, 0x2530, 0x7dba, 0x7db6, 0x65ae, 0x65b2, 0x601c,
+	0x60a2, 0x2048, 0xa984, 0xe1ff, 0x601e, 0xa984, 0x0060, 0x0040,
+	0x22a3, 0x1078, 0x46b6, 0x6596, 0x65a6, 0x669a, 0x66aa, 0x6714,
+	0x2071, 0x4f80, 0xd7fc, 0x00c0, 0x22af, 0x2071, 0x4f40, 0xa784,
+	0x0f00, 0x800b, 0xa784, 0x001f, 0x0040, 0x22ba, 0x8003, 0x8003,
+	0x8003, 0x8003, 0xa105, 0x71c4, 0xa168, 0x2700, 0x8007, 0xa084,
+	0x000f, 0x8003, 0x8003, 0x8003, 0x71c8, 0xa100, 0x60c2, 0x2091,
+	0x8000, 0x7814, 0xd0c4, 0x0040, 0x22df, 0xd0ec, 0x0040, 0x22db,
+	0xd7fc, 0x00c0, 0x22d8, 0xd0f4, 0x00c0, 0x22e6, 0x0078, 0x22df,
+	0xd0fc, 0x00c0, 0x22e6, 0x7810, 0xd0f4, 0x00c0, 0x22e6, 0x6e08,
+	0xd684, 0x0040, 0x2310, 0xd9fc, 0x00c0, 0x2310, 0x2091, 0x8001,
+	0x1078, 0x1ea2, 0x2091, 0x8000, 0x1078, 0x2064, 0x2091, 0x8001,
+	0x7814, 0xd0e4, 0x00c0, 0x2375, 0x7814, 0xd0c4, 0x0040, 0x2375,
+	0xd0ec, 0x0040, 0x2308, 0xd7fc, 0x00c0, 0x2303, 0xd0f4, 0x00c0,
+	0x230c, 0x0078, 0x2375, 0xd0fc, 0x00c0, 0x230c, 0x0078, 0x2375,
+	0x7810, 0xd0f4, 0x0040, 0x2375, 0x601b, 0x0021, 0x0078, 0x2375,
+	0x6024, 0xa096, 0x0001, 0x00c0, 0x2317, 0x8000, 0x6026, 0x6a10,
+	0x6814, 0xa202, 0x0048, 0x232a, 0x0040, 0x232a, 0x2091, 0x8001,
+	0x2039, 0x0200, 0x609c, 0x78ba, 0x609f, 0x0000, 0x1078, 0x2377,
+	0x0078, 0x2375, 0x2c08, 0xd9fc, 0x0040, 0x2352, 0x6800, 0xa065,
+	0x0040, 0x2352, 0x6a04, 0x7000, 0xa084, 0x0002, 0x0040, 0x2348,
+	0x704c, 0xa206, 0x00c0, 0x2348, 0x6b04, 0x2160, 0x2304, 0x6002,
+	0xa005, 0x00c0, 0x2344, 0x6902, 0x2260, 0x6102, 0x0078, 0x235e,
+	0x2d00, 0x2060, 0x1078, 0x2b13, 0x6e08, 0x2160, 0x6202, 0x6906,
+	0x0078, 0x235e, 0x6800, 0x6902, 0xa065, 0x0040, 0x235a, 0x6102,
+	0x0078, 0x235b, 0x6906, 0x2160, 0x6003, 0x0000, 0x2160, 0xd9fc,
+	0x0040, 0x2365, 0xa6b4, 0xfffc, 0x6e0a, 0x6810, 0x7d08, 0x8528,
+	0x7d0a, 0x8000, 0x6812, 0x2091, 0x8001, 0xd6b4, 0x0040, 0x2375,
+	0xa6b6, 0x0040, 0x6e0a, 0x1078, 0x1eb3, 0x0e7f, 0x007c, 0x6008,
+	0xa705, 0x600a, 0x2091, 0x8000, 0x1078, 0x2064, 0x2091, 0x8001,
+	0x78b8, 0xa065, 0x0040, 0x238a, 0x609c, 0x78ba, 0x609f, 0x0000,
+	0x0078, 0x2377, 0x78b6, 0x78ba, 0x007c, 0x7970, 0x7874, 0x2818,
+	0xd384, 0x0040, 0x2397, 0x8000, 0xa112, 0x0048, 0x239c, 0x8000,
+	0xa112, 0x00c8, 0x23ac, 0xc384, 0x7a7c, 0x721a, 0x7a78, 0x721e,
+	0xdac4, 0x0040, 0x23a7, 0x7a84, 0x7222, 0x7a80, 0x7226, 0xa006,
+	0xd384, 0x0040, 0x23ac, 0x8000, 0x7876, 0x70d2, 0x781c, 0xa005,
+	0x0040, 0x23ba, 0x8001, 0x781e, 0x00c0, 0x23ba, 0x0068, 0x23ba,
+	0x2091, 0x4080, 0x007c, 0x2039, 0x23d3, 0x0078, 0x23c1, 0x2039,
+	0x23d9, 0x2704, 0xa005, 0x0040, 0x23d2, 0xac00, 0x2068, 0x6908,
+	0x6810, 0x6912, 0x680a, 0x690c, 0x6814, 0x6916, 0x680e, 0x8738,
+	0x0078, 0x23c1, 0x007c, 0x0003, 0x0009, 0x000f, 0x0015, 0x001b,
+	0x0000, 0x0015, 0x001b, 0x0000, 0x2041, 0x0000, 0x780c, 0x0079,
+	0x23e1, 0x25b3, 0x2586, 0x23e5, 0x245e, 0x2039, 0x9774, 0x2734,
+	0x7d10, 0x0078, 0x2405, 0x6084, 0xa086, 0x0103, 0x00c0, 0x2447,
+	0x6114, 0x6018, 0xa105, 0x0040, 0x23fa, 0x86ff, 0x00c0, 0x2416,
+	0x0078, 0x2447, 0x8603, 0xa080, 0x9755, 0x620c, 0x2202, 0x8000,
+	0x6210, 0x2202, 0x1078, 0x2086, 0x8630, 0xa68e, 0x000f, 0x0040,
+	0x24d2, 0x786c, 0xa065, 0x00c0, 0x23eb, 0x7808, 0xa602, 0x00c8,
+	0x2416, 0xd5ac, 0x00c0, 0x2416, 0x263a, 0x007c, 0xa682, 0x0003,
+	0x00c8, 0x24d2, 0x2091, 0x8000, 0x2069, 0x0000, 0x6818, 0xd084,
+	0x00c0, 0x2442, 0x2011, 0x9755, 0x2204, 0x70c6, 0x8210, 0x2204,
+	0x70ca, 0xd684, 0x00c0, 0x2432, 0x8210, 0x2204, 0x70da, 0x8210,
+	0x2204, 0x70de, 0xa685, 0x8020, 0x70c2, 0x681b, 0x0001, 0x2091,
+	0x4080, 0x7810, 0xa084, 0xffcf, 0x7812, 0x2091, 0x8001, 0x203b,
+	0x0000, 0x007c, 0x7810, 0xc0ad, 0x7812, 0x0078, 0x24d2, 0x263a,
+	0x1078, 0x25bd, 0x00c0, 0x25e0, 0x786c, 0xa065, 0x00c0, 0x23eb,
+	0x2091, 0x8000, 0x7810, 0xa084, 0xffcf, 0x86ff, 0x0040, 0x2459,
+	0xc0ad, 0x7812, 0x2091, 0x8001, 0x0078, 0x25e0, 0x2039, 0x9774,
+	0x2734, 0x7d10, 0x0078, 0x247a, 0x6084, 0xa086, 0x0103, 0x00c0,
+	0x24bb, 0x6114, 0x6018, 0xa105, 0x0040, 0x2473, 0x86ff, 0x00c0,
+	0x248b, 0x0078, 0x24bb, 0xa680, 0x9755, 0x620c, 0x2202, 0x1078,
+	0x2086, 0x8630, 0xa68e, 0x001e, 0x0040, 0x24d2, 0x786c, 0xa065,
+	0x00c0, 0x2464, 0x7808, 0xa602, 0x00c8, 0x248b, 0xd5ac, 0x00c0,
+	0x248b, 0x263a, 0x007c, 0xa682, 0x0006, 0x00c8, 0x24d2, 0x2091,
+	0x8000, 0x2069, 0x0000, 0x6818, 0xd084, 0x00c0, 0x24b6, 0x2011,
+	0x9755, 0x2009, 0x974e, 0x26a8, 0x211c, 0x2204, 0x201a, 0x8108,
+	0x8210, 0x00f0, 0x249c, 0xa685, 0x8030, 0x70c2, 0x681b, 0x0001,
 	0x2091, 0x4080, 0x7810, 0xa084, 0xffcf, 0x7812, 0x2091, 0x8001,
-	0x203b, 0x0000, 0x007c, 0x7810, 0xc0ad, 0x7812, 0x0078, 0x248b,
-	0x263a, 0x1078, 0x2576, 0x00c0, 0x2599, 0x786c, 0xa065, 0x00c0,
-	0x23a4, 0x2091, 0x8000, 0x7810, 0xa084, 0xffcf, 0x86ff, 0x0040,
-	0x2412, 0xc0ad, 0x7812, 0x2091, 0x8001, 0x0078, 0x2599, 0x2039,
-	0x9674, 0x2734, 0x7d10, 0x0078, 0x2433, 0x6084, 0xa086, 0x0103,
-	0x00c0, 0x2474, 0x6114, 0x6018, 0xa105, 0x0040, 0x242c, 0x86ff,
-	0x00c0, 0x2444, 0x0078, 0x2474, 0xa680, 0x9655, 0x620c, 0x2202,
-	0x1078, 0x203f, 0x8630, 0xa68e, 0x001e, 0x0040, 0x248b, 0x786c,
-	0xa065, 0x00c0, 0x241d, 0x7808, 0xa602, 0x00c8, 0x2444, 0xd5ac,
-	0x00c0, 0x2444, 0x263a, 0x007c, 0xa682, 0x0006, 0x00c8, 0x248b,
-	0x2091, 0x8000, 0x2069, 0x0000, 0x6818, 0xd084, 0x00c0, 0x246f,
-	0x2011, 0x9655, 0x2009, 0x964e, 0x26a8, 0x211c, 0x2204, 0x201a,
-	0x8108, 0x8210, 0x00f0, 0x2455, 0xa685, 0x8030, 0x70c2, 0x681b,
-	0x0001, 0x2091, 0x4080, 0x7810, 0xa084, 0xffcf, 0x7812, 0x2091,
-	0x8001, 0xa006, 0x2009, 0x9675, 0x200a, 0x203a, 0x007c, 0x7810,
-	0xc0ad, 0x7812, 0x0078, 0x248b, 0x263a, 0x1078, 0x2576, 0x00c0,
-	0x2599, 0x786c, 0xa065, 0x00c0, 0x241d, 0x2091, 0x8000, 0x7810,
-	0xa084, 0xffcf, 0x86ff, 0x0040, 0x2486, 0xc0ad, 0x7812, 0x2091,
-	0x8001, 0x0078, 0x2599, 0x2091, 0x8000, 0x7007, 0x0004, 0x7994,
-	0x70d4, 0xa102, 0x0048, 0x249c, 0x0040, 0x24a6, 0x7b90, 0xa302,
-	0x00c0, 0x24a6, 0x0078, 0x249f, 0x8002, 0x00c0, 0x24a6, 0x263a,
-	0x7810, 0xc0ad, 0x7812, 0x2091, 0x8001, 0x007c, 0xa184, 0xff00,
-	0x0040, 0x24b3, 0x810f, 0x810c, 0x810c, 0x8004, 0x8004, 0x8007,
-	0xa100, 0x0078, 0x24b6, 0x8107, 0x8004, 0x8004, 0x7a9c, 0xa210,
-	0x721a, 0x7a98, 0xa006, 0xa211, 0x721e, 0xd4c4, 0x0040, 0x24c6,
-	0x7aa4, 0xa211, 0x7222, 0x7aa0, 0xa211, 0x7226, 0x20a1, 0x0030,
-	0x7003, 0x0000, 0x2009, 0x9654, 0x260a, 0x8109, 0x2198, 0x2104,
-	0xd084, 0x0040, 0x24d4, 0x8633, 0xa6b0, 0x0002, 0x26a8, 0x53a6,
-	0x8603, 0x7012, 0x7007, 0x0001, 0x7990, 0x7894, 0x8000, 0xa10a,
-	0x00c8, 0x24e3, 0xa006, 0x2028, 0x7974, 0xa184, 0xff00, 0x0040,
-	0x24f2, 0x810f, 0x810c, 0x810c, 0x8004, 0x8004, 0x8007, 0xa100,
-	0x0078, 0x24f5, 0x8107, 0x8004, 0x8004, 0x797c, 0xa108, 0x7a78,
-	0xa006, 0xa211, 0xd4c4, 0x0040, 0x2501, 0x7b84, 0xa319, 0x7c80,
-	0xa421, 0x7008, 0xd0fc, 0x0040, 0x2501, 0xa084, 0x01e0, 0x0040,
-	0x2526, 0x7d10, 0x2031, 0x9654, 0x2634, 0x78a8, 0x8000, 0x78aa,
-	0xd08c, 0x00c0, 0x251b, 0x7007, 0x0006, 0x7004, 0xd094, 0x00c0,
-	0x2515, 0x0078, 0x248d, 0x2069, 0x4e47, 0x206b, 0x0003, 0x78ac,
-	0xa085, 0x0300, 0x78ae, 0xa006, 0x0078, 0x252f, 0x2030, 0x75d6,
-	0x2091, 0x4080, 0x7d96, 0x7d10, 0xa5ac, 0xffcf, 0x7d12, 0x2091,
-	0x8001, 0x78aa, 0x7007, 0x0006, 0x263a, 0x7003, 0x0001, 0x711a,
-	0x721e, 0xd5c4, 0x0040, 0x253e, 0x7322, 0x7426, 0x007c, 0x6084,
-	0xa086, 0x0103, 0x00c0, 0x2562, 0x6114, 0x6018, 0xa105, 0x00c0,
-	0x2562, 0x2069, 0x0000, 0x6818, 0xd084, 0x00c0, 0x2562, 0x600c,
-	0x70c6, 0x6010, 0x70ca, 0x70c3, 0x8020, 0x681b, 0x0001, 0x2091,
-	0x4080, 0x1078, 0x203f, 0x0068, 0x2561, 0x786c, 0xa065, 0x00c0,
-	0x253f, 0x007c, 0x1078, 0x2576, 0x00c0, 0x2599, 0x786c, 0xa065,
-	0x00c0, 0x253f, 0x0078, 0x2599, 0x1078, 0x2576, 0x00c0, 0x2599,
-	0x786c, 0xa065, 0x00c0, 0x256c, 0x0078, 0x2599, 0x6084, 0xa086,
-	0x0103, 0x00c0, 0x258a, 0x6018, 0xc0fc, 0x601a, 0xa086, 0x0004,
-	0x00c0, 0x258a, 0x7804, 0xd0a4, 0x0040, 0x258a, 0x1078, 0x203f,
-	0xa006, 0x007c, 0x1078, 0x259f, 0x00c0, 0x2591, 0xa085, 0x0001,
-	0x007c, 0x1078, 0x25ae, 0x00c0, 0x2597, 0x2041, 0x0001, 0x7d10,
-	0x007c, 0x88ff, 0x0040, 0x259e, 0x2091, 0x4080, 0x007c, 0x7b90,
-	0x7994, 0x70d4, 0xa102, 0x00c0, 0x25a8, 0xa385, 0x0000, 0x007c,
-	0x0048, 0x25ac, 0xa302, 0x007c, 0x8002, 0x007c, 0x7810, 0xd0ec,
-	0x0040, 0x25c6, 0x0e7e, 0x2091, 0x8000, 0x2071, 0x0020, 0x7004,
-	0xa005, 0x00c0, 0x25c3, 0x7008, 0x0e7f, 0xa086, 0x0008, 0x0040,
-	0x25c6, 0x0078, 0x2617, 0x0e7f, 0x0078, 0x2617, 0xa184, 0xff00,
-	0x0040, 0x25d3, 0x810f, 0x810c, 0x810c, 0x8004, 0x8004, 0x8007,
-	0xa100, 0x0078, 0x25d6, 0x8107, 0x8004, 0x8004, 0x7a9c, 0x7b98,
-	0x7ca4, 0x7da0, 0xa210, 0xa006, 0xa319, 0xa421, 0xa529, 0x2009,
-	0x0018, 0x6028, 0xa005, 0x0040, 0x25e7, 0x2009, 0x0040, 0x1078,
-	0x1d74, 0x0040, 0x2609, 0x78a8, 0x8000, 0x78aa, 0xd08c, 0x00c0,
-	0x2617, 0x6014, 0xd0fc, 0x00c0, 0x25f9, 0x2069, 0x4e40, 0x0078,
-	0x25fb, 0x2069, 0x4e80, 0x2091, 0x8000, 0x681f, 0x0003, 0x78ab,
-	0x0000, 0x78ac, 0xa085, 0x0300, 0x78ae, 0x2091, 0x8001, 0x0078,
-	0x2617, 0x78ab, 0x0000, 0x1078, 0x203f, 0x7990, 0x7894, 0x8000,
-	0xa10a, 0x00c8, 0x2614, 0xa006, 0x7896, 0x70d6, 0xa006, 0x2071,
-	0x0010, 0x2091, 0x8001, 0x007c, 0xd7fc, 0x00c0, 0x2623, 0x2009,
-	0x4e59, 0x0078, 0x2625, 0x2009, 0x4e99, 0x2091, 0x8000, 0x200a,
-	0x0f7e, 0xd7fc, 0x00c0, 0x263c, 0x2009, 0x4e40, 0x2001, 0x4e04,
-	0x2004, 0xd0ec, 0x0040, 0x2638, 0x2079, 0x0100, 0x0078, 0x2640,
-	0x2079, 0x0200, 0x0078, 0x2640, 0x2009, 0x4e80, 0x2079, 0x0100,
-	0x2104, 0xa086, 0x0000, 0x00c0, 0x2659, 0xd7fc, 0x00c0, 0x264c,
-	0x2009, 0x4e45, 0x0078, 0x264e, 0x2009, 0x4e85, 0x2104, 0xa005,
-	0x00c0, 0x2659, 0x7830, 0xa084, 0x00c0, 0x00c0, 0x2659, 0x781b,
-	0x0045, 0x0f7f, 0x007c, 0x2009, 0x0002, 0x2069, 0x4e00, 0x6810,
-	0xd0ec, 0x00c0, 0x26c8, 0x2071, 0x4e80, 0x2079, 0x0100, 0x2021,
-	0x50bf, 0x784b, 0x000f, 0x2019, 0x4457, 0xd184, 0x0040, 0x267c,
-	0x6810, 0xd0ec, 0x0040, 0x2678, 0x20a1, 0x012b, 0x0078, 0x267e,
-	0x20a1, 0x022b, 0x0078, 0x267e, 0x20a1, 0x012b, 0x2304, 0xa005,
-	0x0040, 0x268b, 0x789a, 0x8318, 0x23ac, 0x8318, 0x2398, 0x53a6,
-	0x3318, 0x0078, 0x267e, 0x789b, 0x0020, 0x20a9, 0x0010, 0x6814,
-	0xd0e4, 0x0040, 0x269b, 0x78af, 0x0000, 0x78af, 0x9020, 0x00f0,
-	0x2693, 0x0078, 0x26a1, 0x78af, 0x0000, 0x78af, 0x8020, 0x00f0,
-	0x269b, 0x7003, 0x0000, 0x017e, 0xd18c, 0x2009, 0x0000, 0x0040,
-	0x26aa, 0xc1bd, 0x1078, 0x289b, 0x017f, 0x7020, 0xa084, 0x000f,
-	0x007e, 0x6814, 0xd0e4, 0x007f, 0x00c0, 0x26ba, 0xa085, 0x6340,
-	0x0078, 0x26bc, 0xa085, 0x62c0, 0x7806, 0x780f, 0x9200, 0x7843,
-	0x00d8, 0x7853, 0x0080, 0x780b, 0x0008, 0x7456, 0x7053, 0x0000,
-	0x8109, 0x0040, 0x26db, 0x2071, 0x4e40, 0x6810, 0xd0ec, 0x0040,
-	0x26d5, 0x2079, 0x0100, 0x0078, 0x26d7, 0x2079, 0x0200, 0x2021,
-	0x4ebf, 0x0078, 0x2669, 0x007c, 0x017e, 0xd1bc, 0x00c0, 0x26f0,
-	0x007e, 0x2001, 0x4e04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x26ec,
-	0x2011, 0x0101, 0x0078, 0x26f2, 0x2011, 0x0201, 0x0078, 0x26f2,
-	0x2011, 0x0101, 0xa18c, 0x000f, 0x2204, 0xa084, 0xfff0, 0xa105,
-	0x2012, 0x017f, 0x1078, 0x289b, 0x007c, 0xd3fc, 0x00c0, 0x2710,
-	0x007e, 0x2001, 0x4e04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x270c,
-	0x2011, 0x0101, 0x0078, 0x2712, 0x2011, 0x0201, 0x0078, 0x2712,
-	0x2011, 0x0101, 0x20a9, 0x0009, 0x810b, 0x00f0, 0x2714, 0xa18c,
-	0x0e00, 0x2204, 0xa084, 0xf1ff, 0xa105, 0x2012, 0x007c, 0x2019,
-	0x0002, 0x2001, 0x4e04, 0x2004, 0xd0ec, 0x0040, 0x272c, 0x8319,
-	0x2009, 0x0101, 0x0078, 0x272e, 0x2009, 0x0101, 0x20a9, 0x0005,
-	0x8213, 0x00f0, 0x2730, 0xa294, 0x00e0, 0x2104, 0xa084, 0xff1f,
-	0xa205, 0x200a, 0x8319, 0x0040, 0x2741, 0x2009, 0x0201, 0x0078,
-	0x272e, 0x007c, 0xd3fc, 0x00c0, 0x2755, 0x007e, 0x2001, 0x4e04,
-	0x2004, 0xd0ec, 0x007f, 0x0040, 0x2751, 0x2011, 0x0101, 0x0078,
-	0x2757, 0x2011, 0x0201, 0x0078, 0x2757, 0x2011, 0x0101, 0x20a9,
-	0x000c, 0x810b, 0x00f0, 0x2759, 0xa18c, 0xf000, 0x2204, 0xa084,
-	0x0fff, 0xa105, 0x2012, 0x007c, 0xd3fc, 0x00c0, 0x2777, 0x007e,
-	0x2001, 0x4e04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x2773, 0x2011,
-	0x0102, 0x0078, 0x2779, 0x2011, 0x0202, 0x0078, 0x2779, 0x2011,
-	0x0102, 0x2204, 0xa084, 0xffcf, 0xa105, 0x2012, 0x007c, 0x0c7e,
-	0xd1bc, 0x00c0, 0x2793, 0x007e, 0x2001, 0x4e04, 0x2004, 0xd0ec,
-	0x007f, 0x0040, 0x278f, 0x2061, 0x0100, 0x0078, 0x2795, 0x2061,
-	0x0200, 0x0078, 0x2795, 0x2061, 0x0100, 0xc1bc, 0x8103, 0x8003,
-	0xa080, 0x0020, 0x609a, 0x62ac, 0x63ac, 0x0c7f, 0x007c, 0x0c7e,
-	0xd1bc, 0x00c0, 0x27b3, 0x007e, 0x2001, 0x4e04, 0x2004, 0xd0ec,
-	0x007f, 0x0040, 0x27af, 0x2061, 0x0100, 0x0078, 0x27b5, 0x2061,
-	0x0200, 0x0078, 0x27b5, 0x2061, 0x0100, 0xc1bc, 0x8103, 0x8003,
-	0xa080, 0x0022, 0x609a, 0x60a4, 0xa084, 0xffdf, 0x60ae, 0x0c7f,
-	0x007c, 0x0c7e, 0xd1bc, 0x00c0, 0x27d5, 0x007e, 0x2001, 0x4e04,
-	0x2004, 0xd0ec, 0x007f, 0x0040, 0x27d1, 0x2061, 0x0100, 0x0078,
-	0x27d7, 0x2061, 0x0200, 0x0078, 0x27d7, 0x2061, 0x0100, 0xc1bc,
-	0x8103, 0x8003, 0xa080, 0x0022, 0x609a, 0x60a4, 0xa085, 0x0020,
-	0x60ae, 0x0c7f, 0x007c, 0x0c7e, 0xd1bc, 0x00c0, 0x27f7, 0x007e,
-	0x2001, 0x4e04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x27f3, 0x2061,
-	0x0100, 0x0078, 0x27f9, 0x2061, 0x0200, 0x0078, 0x27f9, 0x2061,
-	0x0100, 0xc1bc, 0x8103, 0x8003, 0xa080, 0x0020, 0x609a, 0x60a4,
-	0xa28c, 0x0020, 0x0040, 0x2807, 0xc2ac, 0xa39d, 0x4000, 0xc3fc,
-	0xd3b4, 0x00c0, 0x280c, 0xc3fd, 0x62ae, 0x2010, 0x60a4, 0x63ae,
-	0x2018, 0x0c7f, 0x007c, 0x2091, 0x8000, 0x0c7e, 0x0e7e, 0x6818,
-	0xa005, 0x0040, 0x2879, 0xd1fc, 0x0040, 0x2822, 0x2061, 0x95d0,
-	0x0078, 0x2824, 0x2061, 0x94c0, 0x1078, 0x2881, 0x0040, 0x285b,
-	0x20a9, 0x0101, 0xd1fc, 0x0040, 0x2831, 0x2061, 0x94d0, 0x0078,
-	0x2833, 0x2061, 0x93c0, 0x0c7e, 0x1078, 0x2881, 0x0040, 0x283e,
-	0x0c7f, 0x8c60, 0x00f0, 0x2833, 0x0078, 0x2879, 0x007f, 0xd1fc,
-	0x0040, 0x2848, 0xa082, 0x94d0, 0x2071, 0x4e80, 0x0078, 0x284c,
-	0xa082, 0x93c0, 0x2071, 0x4e40, 0x707a, 0x7176, 0x2138, 0x2001,
-	0x0004, 0x7066, 0x7083, 0x000f, 0x71d4, 0xc1dc, 0x71d6, 0x1078,
-	0x261c, 0x0078, 0x2875, 0xd1fc, 0x00c0, 0x2862, 0x2071, 0x4e40,
-	0x0078, 0x2864, 0x2071, 0x4e80, 0x6020, 0xc0dd, 0x6022, 0x7176,
-	0x2138, 0x2c00, 0x707e, 0x2001, 0x0006, 0x7066, 0x7083, 0x000f,
-	0x71d4, 0xc1dc, 0x71d6, 0x1078, 0x261c, 0x2001, 0x0000, 0x0078,
-	0x287b, 0x2001, 0x0001, 0x2091, 0x8001, 0xa005, 0x0e7f, 0x0c7f,
-	0x007c, 0x2c04, 0xa005, 0x0040, 0x2898, 0x2060, 0x6010, 0xa306,
-	0x00c0, 0x2895, 0x600c, 0xa206, 0x00c0, 0x2895, 0x6014, 0xa106,
-	0x00c0, 0x2895, 0xa006, 0x0078, 0x289a, 0x6000, 0x0078, 0x2882,
-	0xa085, 0x0001, 0x007c, 0x0f7e, 0x0e7e, 0x017e, 0xd1bc, 0x00c0,
-	0x28b3, 0x2079, 0x4e40, 0x007e, 0x2001, 0x4e04, 0x2004, 0xd0ec,
-	0x007f, 0x0040, 0x28af, 0x2071, 0x0100, 0x0078, 0x28b7, 0x2071,
-	0x0200, 0x0078, 0x28b7, 0x2079, 0x4e80, 0x2071, 0x0100, 0x7920,
-	0xa18c, 0x000f, 0x70ec, 0xd0c4, 0x00c0, 0x28c1, 0x017f, 0x0078,
-	0x28dc, 0x810b, 0x810b, 0x810b, 0x810b, 0x007f, 0xd0bc, 0x00c0,
-	0x28d9, 0x007e, 0x2001, 0x4e04, 0x2004, 0xd0ec, 0x007f, 0x0040,
-	0x28d5, 0xa18d, 0x0f00, 0x0078, 0x28db, 0xa18d, 0x0f00, 0x0078,
-	0x28db, 0xa18d, 0x0800, 0x2104, 0x0e7f, 0x0f7f, 0x007c, 0x0e7e,
-	0x2001, 0x4e01, 0x2004, 0xd0ac, 0x00c0, 0x295c, 0x68e4, 0xd0ac,
-	0x0040, 0x295c, 0xa084, 0x0006, 0x00c0, 0x295c, 0x6014, 0xd0fc,
-	0x00c0, 0x28f6, 0x2071, 0x52c0, 0x0078, 0x28f8, 0x2071, 0x5340,
-	0x8007, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xae70, 0x7004,
-	0xa084, 0x000a, 0x00c0, 0x295c, 0x7108, 0xa194, 0xff00, 0x0040,
-	0x295c, 0xa18c, 0x00ff, 0x2001, 0x000a, 0xa106, 0x0040, 0x292b,
-	0x2001, 0x000c, 0xa106, 0x0040, 0x292f, 0x2001, 0x0012, 0xa106,
-	0x0040, 0x2933, 0x2001, 0x0014, 0xa106, 0x0040, 0x2937, 0x2001,
-	0x0019, 0xa106, 0x0040, 0x293b, 0x2001, 0x0032, 0xa106, 0x0040,
-	0x293f, 0x0078, 0x2943, 0x2009, 0x000c, 0x0078, 0x2945, 0x2009,
-	0x0012, 0x0078, 0x2945, 0x2009, 0x0014, 0x0078, 0x2945, 0x2009,
-	0x0019, 0x0078, 0x2945, 0x2009, 0x0020, 0x0078, 0x2945, 0x2009,
-	0x003f, 0x0078, 0x2945, 0x2011, 0x0000, 0x2100, 0xa205, 0x700a,
-	0x2071, 0x4e00, 0x7004, 0xd0bc, 0x0040, 0x295c, 0x6014, 0xd0fc,
-	0x00c0, 0x2957, 0x70ea, 0x2071, 0x4e40, 0x0078, 0x295a, 0x70ee,
-	0x2071, 0x4e80, 0x701f, 0x000d, 0x0e7f, 0x007c, 0x2001, 0x4e05,
-	0x2004, 0xd0e4, 0x00c0, 0x296a, 0x7804, 0xa084, 0xff1f, 0xa085,
-	0x6340, 0x7806, 0x007c, 0x0068, 0x296b, 0x2091, 0x8000, 0x2071,
-	0x0000, 0x007e, 0x7018, 0xd084, 0x00c0, 0x2972, 0x007f, 0x2071,
-	0x0010, 0x70ca, 0x007f, 0x70c6, 0x70c3, 0x8002, 0x70db, 0x080f,
-	0x70df, 0x0000, 0x2071, 0x0000, 0x701b, 0x0001, 0x2091, 0x4080,
-	0x0078, 0x2988, 0x7f3c, 0x7e58, 0x7c30, 0x7d38, 0x78a0, 0x708e,
-	0x7592, 0x7496, 0x769a, 0x779e, 0xa594, 0x003f, 0xd4f4, 0x0040,
-	0x299f, 0xa784, 0x007d, 0x00c0, 0x43cd, 0x1078, 0x296b, 0xa49c,
-	0x000f, 0xa382, 0x0004, 0x0050, 0x29aa, 0xa3a6, 0x0007, 0x00c0,
-	0x296b, 0x2418, 0x8507, 0xa084, 0x000f, 0x0079, 0x29af, 0x3028,
-	0x3119, 0x3144, 0x33b6, 0x379f, 0x3819, 0x38ce, 0x395f, 0x3a4d,
-	0x3b3c, 0x29c2, 0x29bf, 0x2df9, 0x2f1c, 0x3770, 0x29bf, 0x1078,
-	0x296b, 0x007c, 0xa006, 0x0078, 0x29cc, 0x7808, 0xc08d, 0x780a,
-	0xa006, 0x7002, 0x704e, 0x7046, 0x70d2, 0x7060, 0xa005, 0x00c0,
-	0x2b32, 0x7064, 0xa084, 0x0007, 0x0079, 0x29d6, 0x29de, 0x2a51,
-	0x2a5a, 0x2a65, 0x2a70, 0x2b18, 0x2a7b, 0x2a51, 0x7830, 0xd0bc,
-	0x00c0, 0x29c1, 0x71d4, 0xd1bc, 0x00c0, 0x29c1, 0xd1b4, 0x00c0,
-	0x2a2e, 0x70a4, 0xa086, 0x0001, 0x0040, 0x29c1, 0x70b4, 0xa06d,
-	0x6800, 0xa065, 0xa055, 0x789b, 0x0010, 0x6b0c, 0x7baa, 0x6808,
-	0xa045, 0x6d10, 0x6804, 0xa06d, 0xa05d, 0xa886, 0x0001, 0x0040,
-	0x2a04, 0x69bc, 0x7daa, 0x79aa, 0x68c0, 0xa04d, 0x6e1c, 0x2001,
-	0x0010, 0x0078, 0x2c8c, 0x7060, 0xa005, 0x00c0, 0x29c1, 0x0c7e,
-	0x0d7e, 0x70b4, 0xa06d, 0x6800, 0xa065, 0xa055, 0x789b, 0x0010,
-	0x6b0c, 0x7baa, 0x6808, 0xa045, 0x6d10, 0x6804, 0xa06d, 0xa05d,
-	0xa886, 0x0001, 0x0040, 0x2a27, 0x69bc, 0x7daa, 0x79aa, 0x68c0,
-	0xa04d, 0x6e1c, 0x2001, 0x0020, 0x0078, 0x2c8c, 0x1078, 0x4360,
-	0x00c0, 0x29c1, 0x781b, 0x005b, 0x70bc, 0xa06d, 0x68b4, 0x785a,
-	0x6894, 0x78d6, 0x78de, 0x6898, 0x78d2, 0x78da, 0x7808, 0xc08d,
-	0x780a, 0x68bc, 0x7042, 0xc1b4, 0x71d6, 0x70b8, 0xa065, 0x68c0,
-	0x705a, 0x7003, 0x0002, 0x2d00, 0x704e, 0xad80, 0x0009, 0x7046,
-	0x007c, 0x1078, 0x4360, 0x00c0, 0x2a59, 0x781b, 0x0047, 0x7003,
-	0x0004, 0x007c, 0x1078, 0x4360, 0x00c0, 0x2a64, 0x2011, 0x000c,
-	0x1078, 0x2a8b, 0x7003, 0x0004, 0x007c, 0x1078, 0x4360, 0x00c0,
-	0x2a6f, 0x2011, 0x0006, 0x1078, 0x2a8b, 0x7003, 0x0004, 0x007c,
-	0x1078, 0x4360, 0x00c0, 0x2a7a, 0x2011, 0x000d, 0x1078, 0x2a8b,
-	0x7003, 0x0004, 0x007c, 0x1078, 0x4360, 0x00c0, 0x2a8a, 0x2011,
-	0x0006, 0x1078, 0x2a8b, 0x707c, 0x707f, 0x0000, 0x2068, 0x704e,
-	0x7003, 0x0001, 0x007c, 0x7174, 0xc1fc, 0x8107, 0x7882, 0x789b,
-	0x0010, 0xa286, 0x000c, 0x00c0, 0x2a9a, 0x7aaa, 0x2001, 0x0001,
-	0x0078, 0x2aaf, 0xa18c, 0x001f, 0xa18d, 0x00c0, 0x79aa, 0xa286,
-	0x000d, 0x0040, 0x2aa8, 0x7aaa, 0x2001, 0x0002, 0x0078, 0x2aaf,
-	0x78ab, 0x0020, 0x7178, 0x79aa, 0x7aaa, 0x2001, 0x0004, 0x789b,
-	0x0060, 0x78aa, 0x785b, 0x0004, 0x781b, 0x0116, 0x1078, 0x4383,
-	0x7083, 0x000f, 0x70d4, 0xd0b4, 0x0040, 0x2acb, 0xc0b4, 0x70d6,
-	0x0c7e, 0x70b8, 0xa065, 0x6008, 0xa084, 0xfbef, 0x600a, 0x6018,
-	0x8001, 0x601a, 0x0c7f, 0x007c, 0x7014, 0xa005, 0x00c0, 0x2ada,
-	0x70d4, 0xd0b4, 0x0040, 0x2adb, 0x70b8, 0xac06, 0x00c0, 0x2adb,
-	0x1078, 0x2aba, 0x007c, 0x017e, 0x71a4, 0xa186, 0x0001, 0x0040,
-	0x2b0d, 0x0d7e, 0x027e, 0x2100, 0x2011, 0x0001, 0xa212, 0x70b4,
-	0x2068, 0x6800, 0xac06, 0x0040, 0x2af4, 0x8211, 0x0040, 0x2b0b,
-	0x1078, 0x2b0f, 0x0078, 0x2ae9, 0x0c7e, 0x2100, 0x2011, 0x0001,
-	0xa212, 0x70b4, 0x2068, 0x6800, 0x2060, 0x6008, 0xa084, 0xfbef,
-	0x600a, 0x8211, 0x0040, 0x2b08, 0x1078, 0x2b0f, 0x0078, 0x2afb,
-	0x70a7, 0x0001, 0x0c7f, 0x027f, 0x0d7f, 0x017f, 0x007c, 0xade8,
-	0x0005, 0x70ac, 0xad06, 0x00c0, 0x2b17, 0x70a8, 0x2068, 0x007c,
-	0x1078, 0x4360, 0x00c0, 0x29c1, 0x707c, 0x2068, 0x7774, 0x1078,
-	0x41fe, 0x2c50, 0x1078, 0x4442, 0x789b, 0x0010, 0x6814, 0xa084,
-	0x001f, 0xc0bd, 0x78aa, 0x6e1c, 0x2041, 0x0001, 0x2001, 0x0004,
-	0x0078, 0x2c92, 0x1078, 0x4360, 0x00c0, 0x29c1, 0x789b, 0x0010,
-	0x7060, 0x2068, 0x6f14, 0x70d4, 0xd0b4, 0x0040, 0x2b4c, 0xc0b4,
-	0x70d6, 0x0c7e, 0x70b8, 0xa065, 0x6008, 0xa084, 0xfbef, 0x600a,
-	0x6018, 0x8001, 0x601a, 0x0c7f, 0x1078, 0x41fe, 0x2c50, 0x1078,
-	0x4442, 0x6824, 0xa005, 0x0040, 0x2b5d, 0xa082, 0x0006, 0x0048,
-	0x2b5b, 0x0078, 0x2b5d, 0x6827, 0x0005, 0x6814, 0xa084, 0x001f,
-	0xc0bd, 0x78aa, 0x2031, 0x0020, 0x2041, 0x0001, 0x2001, 0x0003,
-	0x0078, 0x2c92, 0xc28d, 0x72d6, 0x72c0, 0xa200, 0xa015, 0x7154,
-	0x8108, 0xa12a, 0x0048, 0x2b75, 0x71c0, 0x2164, 0x6504, 0x85ff,
-	0x00c0, 0x2b8c, 0x7156, 0x8421, 0x00c0, 0x2b70, 0x70d4, 0xd08c,
-	0x0040, 0x2b88, 0x70d0, 0xa005, 0x00c0, 0x2b88, 0x70d3, 0x000a,
-	0x007c, 0x2200, 0x0078, 0x2b7a, 0x70d4, 0xc08c, 0x70d6, 0x70d3,
-	0x0000, 0x6034, 0xa005, 0x00c0, 0x2b89, 0x6708, 0xa784, 0x073f,
-	0x0040, 0x2bbb, 0xd7d4, 0x00c0, 0x2b89, 0xa784, 0x0021, 0x00c0,
-	0x2b89, 0xa784, 0x0002, 0x0040, 0x2bac, 0xa784, 0x0004, 0x0040,
-	0x2b89, 0xa7bc, 0xfffb, 0x670a, 0xa784, 0x0218, 0x00c0, 0x2b89,
-	0xa784, 0x0100, 0x0040, 0x2bbb, 0x6018, 0xa005, 0x00c0, 0x2b89,
-	0xa7bc, 0xfeff, 0x670a, 0x2568, 0x6823, 0x0000, 0x6e1c, 0xa684,
-	0x000e, 0x6318, 0x0040, 0x2bcc, 0x601c, 0xa302, 0x0048, 0x2bcf,
-	0x0040, 0x2bcf, 0x0078, 0x2b89, 0x83ff, 0x00c0, 0x2b89, 0x2d58,
-	0x2c50, 0x7156, 0xd7bc, 0x00c0, 0x2bd8, 0x7028, 0x6022, 0x603a,
-	0xc7bc, 0x670a, 0x68c0, 0xa065, 0xa04d, 0x6100, 0x2a60, 0x2041,
-	0x0001, 0x6b14, 0xa39c, 0x001f, 0xa39d, 0x00c0, 0xd1fc, 0x0040,
-	0x2bec, 0xd684, 0x0040, 0x2bee, 0xa39c, 0xffbf, 0xd6a4, 0x0040,
-	0x2bf3, 0xa39d, 0x0020, 0xa684, 0x000e, 0x00c0, 0x2c3e, 0xc7a5,
-	0x670a, 0x2c00, 0x68c6, 0x77a4, 0xa786, 0x0001, 0x00c0, 0x2c12,
-	0x70d4, 0xd0b4, 0x00c0, 0x2c12, 0x7000, 0xa082, 0x0002, 0x00c8,
-	0x2c12, 0x7830, 0xd0bc, 0x00c0, 0x2c12, 0x789b, 0x0010, 0x7baa,
-	0x0078, 0x2c8a, 0x8739, 0x77a6, 0x2750, 0x77b0, 0xa7b0, 0x0005,
-	0x70ac, 0xa606, 0x00c0, 0x2c1d, 0x76a8, 0x76b2, 0x2c3a, 0x8738,
-	0x2d3a, 0x8738, 0x283a, 0x8738, 0x233a, 0x8738, 0x253a, 0x7830,
-	0xd0bc, 0x0040, 0x2c35, 0x2091, 0x8000, 0x2091, 0x303d, 0x70d4,
-	0xa084, 0x303d, 0x2091, 0x8000, 0x2090, 0xaad5, 0x0000, 0x0040,
-	0x2c3d, 0x8421, 0x2200, 0x00c0, 0x2b6f, 0x007c, 0xd1dc, 0x0040,
-	0x3e00, 0x2029, 0x0020, 0xd69c, 0x00c0, 0x2c4b, 0x8528, 0xd68c,
-	0x00c0, 0x2c4b, 0x8528, 0x8840, 0x6f14, 0x610c, 0x8108, 0xa18c,
-	0x00ff, 0x70cc, 0xa160, 0x2c64, 0x8cff, 0x0040, 0x2c6a, 0x6014,
-	0xa706, 0x00c0, 0x2c53, 0x60b8, 0x8001, 0x60ba, 0x00c0, 0x2c4e,
-	0x2a60, 0x6008, 0xa085, 0x0100, 0x600a, 0x2200, 0x8421, 0x00c0,
-	0x2b6f, 0x007c, 0x2a60, 0x610e, 0x69be, 0x2c00, 0x68c6, 0x8840,
-	0x6008, 0xc0d5, 0x600a, 0x77a4, 0xa786, 0x0001, 0x00c0, 0x2c12,
-	0x70d4, 0xd0b4, 0x00c0, 0x2c12, 0x7000, 0xa082, 0x0002, 0x00c8,
-	0x2c12, 0x7830, 0xd0bc, 0x00c0, 0x2c12, 0x789b, 0x0010, 0x7baa,
-	0x7daa, 0x79aa, 0x2001, 0x0002, 0x007e, 0x6018, 0x8000, 0x601a,
-	0x0078, 0x2c93, 0x007e, 0x2960, 0x6104, 0x2a60, 0xa184, 0x0018,
-	0x0040, 0x2caf, 0xa184, 0x0010, 0x0040, 0x2ca2, 0x1078, 0x4011,
-	0x00c0, 0x2cd4, 0xa184, 0x0008, 0x0040, 0x2caf, 0x69a0, 0xa184,
-	0x0600, 0x00c0, 0x2caf, 0x1078, 0x3ef5, 0x0078, 0x2cd4, 0x69a0,
-	0xa184, 0x1e00, 0x0040, 0x2cdf, 0xa184, 0x0800, 0x0040, 0x2cc8,
-	0x0c7e, 0x2960, 0x6000, 0xa085, 0x2000, 0x6002, 0x6104, 0xa18d,
-	0x0010, 0x6106, 0x0c7f, 0x1078, 0x4011, 0x00c0, 0x2cd4, 0x69a0,
-	0xa184, 0x0200, 0x0040, 0x2cd0, 0x1078, 0x3f54, 0x0078, 0x2cd4,
-	0xa184, 0x0400, 0x00c0, 0x2cab, 0x69a0, 0xa184, 0x1000, 0x0040,
-	0x2cdf, 0x6914, 0xa18c, 0xff00, 0x810f, 0x1078, 0x279f, 0x027f,
-	0xa68c, 0x00e0, 0xa684, 0x0060, 0x0040, 0x2cec, 0xa086, 0x0060,
-	0x00c0, 0x2cec, 0xa18d, 0x4000, 0xa18d, 0x0104, 0x69b6, 0x789b,
-	0x0060, 0x2800, 0x78aa, 0x6818, 0xc0fd, 0x681a, 0xd6bc, 0x0040,
-	0x2d07, 0xc0fc, 0x7087, 0x0000, 0xa08a, 0x000d, 0x0050, 0x2d05,
-	0xa08a, 0x000c, 0x7186, 0x2001, 0x000c, 0x800c, 0x718a, 0x78aa,
-	0x3518, 0x3340, 0x3428, 0x8000, 0x80ac, 0xaf80, 0x002b, 0x20a0,
-	0x789b, 0x0000, 0xad80, 0x000b, 0x2098, 0x53a6, 0x23a8, 0x2898,
-	0x25a0, 0xa286, 0x0020, 0x00c0, 0x2d3f, 0x70d4, 0xc0b5, 0x70d6,
-	0x2c00, 0x70ba, 0x2d00, 0x70be, 0x6814, 0xc0fc, 0x8007, 0x7882,
-	0xa286, 0x0002, 0x0040, 0x2d75, 0x70a4, 0x8000, 0x70a6, 0x74b4,
-	0xa498, 0x0005, 0x70ac, 0xa306, 0x00c0, 0x2d37, 0x73a8, 0x73b6,
-	0xa286, 0x0010, 0x0040, 0x29c1, 0x0d7f, 0x0c7f, 0x007c, 0x7000,
-	0xa005, 0x00c0, 0x2d1d, 0xa286, 0x0002, 0x00c0, 0x2d8f, 0x1078,
-	0x4360, 0x00c0, 0x2d1d, 0x6814, 0xc0fc, 0x8007, 0x7882, 0x2091,
-	0x8000, 0x781b, 0x005b, 0x68b4, 0x785a, 0x6894, 0x78d6, 0x78de,
-	0x6898, 0x78d2, 0x78da, 0x2091, 0x8001, 0x7808, 0xc08d, 0x780a,
-	0x127e, 0x0d7e, 0x0c7e, 0x70d4, 0xa084, 0x2700, 0x2090, 0x0c7f,
-	0x0d7f, 0x127f, 0x2900, 0x705a, 0x68bc, 0x7042, 0x7003, 0x0002,
-	0x2d00, 0x704e, 0xad80, 0x0009, 0x7046, 0x7830, 0xd0bc, 0x0040,
-	0x2d81, 0x2091, 0x303d, 0x70d4, 0xa084, 0x303d, 0x2091, 0x8000,
-	0x2090, 0x70a4, 0xa005, 0x00c0, 0x2d86, 0x007c, 0x8421, 0x0040,
-	0x2d85, 0x7250, 0x70c0, 0xa200, 0xa015, 0x0078, 0x2b6f, 0xa286,
-	0x0010, 0x00c0, 0x2dc0, 0x1078, 0x4360, 0x00c0, 0x2d1d, 0x6814,
-	0xc0fc, 0x8007, 0x7882, 0x781b, 0x005b, 0x68b4, 0x785a, 0x6894,
+	0xa006, 0x2009, 0x9775, 0x200a, 0x203a, 0x007c, 0x7810, 0xc0ad,
+	0x7812, 0x0078, 0x24d2, 0x263a, 0x1078, 0x25bd, 0x00c0, 0x25e0,
+	0x786c, 0xa065, 0x00c0, 0x2464, 0x2091, 0x8000, 0x7810, 0xa084,
+	0xffcf, 0x86ff, 0x0040, 0x24cd, 0xc0ad, 0x7812, 0x2091, 0x8001,
+	0x0078, 0x25e0, 0x2091, 0x8000, 0x7007, 0x0004, 0x7994, 0x70d4,
+	0xa102, 0x0048, 0x24e3, 0x0040, 0x24ed, 0x7b90, 0xa302, 0x00c0,
+	0x24ed, 0x0078, 0x24e6, 0x8002, 0x00c0, 0x24ed, 0x263a, 0x7810,
+	0xc0ad, 0x7812, 0x2091, 0x8001, 0x007c, 0xa184, 0xff00, 0x0040,
+	0x24fa, 0x810f, 0x810c, 0x810c, 0x8004, 0x8004, 0x8007, 0xa100,
+	0x0078, 0x24fd, 0x8107, 0x8004, 0x8004, 0x7a9c, 0xa210, 0x721a,
+	0x7a98, 0xa006, 0xa211, 0x721e, 0xd4c4, 0x0040, 0x250d, 0x7aa4,
+	0xa211, 0x7222, 0x7aa0, 0xa211, 0x7226, 0x20a1, 0x0030, 0x7003,
+	0x0000, 0x2009, 0x9754, 0x260a, 0x8109, 0x2198, 0x2104, 0xd084,
+	0x0040, 0x251b, 0x8633, 0xa6b0, 0x0002, 0x26a8, 0x53a6, 0x8603,
+	0x7012, 0x7007, 0x0001, 0x7990, 0x7894, 0x8000, 0xa10a, 0x00c8,
+	0x252a, 0xa006, 0x2028, 0x7974, 0xa184, 0xff00, 0x0040, 0x2539,
+	0x810f, 0x810c, 0x810c, 0x8004, 0x8004, 0x8007, 0xa100, 0x0078,
+	0x253c, 0x8107, 0x8004, 0x8004, 0x797c, 0xa108, 0x7a78, 0xa006,
+	0xa211, 0xd4c4, 0x0040, 0x2548, 0x7b84, 0xa319, 0x7c80, 0xa421,
+	0x7008, 0xd0fc, 0x0040, 0x2548, 0xa084, 0x01e0, 0x0040, 0x256d,
+	0x7d10, 0x2031, 0x9754, 0x2634, 0x78a8, 0x8000, 0x78aa, 0xd08c,
+	0x00c0, 0x2562, 0x7007, 0x0006, 0x7004, 0xd094, 0x00c0, 0x255c,
+	0x0078, 0x24d4, 0x2069, 0x4f47, 0x206b, 0x0003, 0x78ac, 0xa085,
+	0x0300, 0x78ae, 0xa006, 0x0078, 0x2576, 0x2030, 0x75d6, 0x2091,
+	0x4080, 0x7d96, 0x7d10, 0xa5ac, 0xffcf, 0x7d12, 0x2091, 0x8001,
+	0x78aa, 0x7007, 0x0006, 0x263a, 0x7003, 0x0001, 0x711a, 0x721e,
+	0xd5c4, 0x0040, 0x2585, 0x7322, 0x7426, 0x007c, 0x6084, 0xa086,
+	0x0103, 0x00c0, 0x25a9, 0x6114, 0x6018, 0xa105, 0x00c0, 0x25a9,
+	0x2069, 0x0000, 0x6818, 0xd084, 0x00c0, 0x25a9, 0x600c, 0x70c6,
+	0x6010, 0x70ca, 0x70c3, 0x8020, 0x681b, 0x0001, 0x2091, 0x4080,
+	0x1078, 0x2086, 0x0068, 0x25a8, 0x786c, 0xa065, 0x00c0, 0x2586,
+	0x007c, 0x1078, 0x25bd, 0x00c0, 0x25e0, 0x786c, 0xa065, 0x00c0,
+	0x2586, 0x0078, 0x25e0, 0x1078, 0x25bd, 0x00c0, 0x25e0, 0x786c,
+	0xa065, 0x00c0, 0x25b3, 0x0078, 0x25e0, 0x6084, 0xa086, 0x0103,
+	0x00c0, 0x25d1, 0x6018, 0xc0fc, 0x601a, 0xa086, 0x0004, 0x00c0,
+	0x25d1, 0x7804, 0xd0a4, 0x0040, 0x25d1, 0x1078, 0x2086, 0xa006,
+	0x007c, 0x1078, 0x25e6, 0x00c0, 0x25d8, 0xa085, 0x0001, 0x007c,
+	0x1078, 0x25f5, 0x00c0, 0x25de, 0x2041, 0x0001, 0x7d10, 0x007c,
+	0x88ff, 0x0040, 0x25e5, 0x2091, 0x4080, 0x007c, 0x7b90, 0x7994,
+	0x70d4, 0xa102, 0x00c0, 0x25ef, 0xa385, 0x0000, 0x007c, 0x0048,
+	0x25f3, 0xa302, 0x007c, 0x8002, 0x007c, 0x7810, 0xd0ec, 0x0040,
+	0x260d, 0x0e7e, 0x2091, 0x8000, 0x2071, 0x0020, 0x7004, 0xa005,
+	0x00c0, 0x260a, 0x7008, 0x0e7f, 0xa086, 0x0008, 0x0040, 0x260d,
+	0x0078, 0x265e, 0x0e7f, 0x0078, 0x265e, 0xa184, 0xff00, 0x0040,
+	0x261a, 0x810f, 0x810c, 0x810c, 0x8004, 0x8004, 0x8007, 0xa100,
+	0x0078, 0x261d, 0x8107, 0x8004, 0x8004, 0x7a9c, 0x7b98, 0x7ca4,
+	0x7da0, 0xa210, 0xa006, 0xa319, 0xa421, 0xa529, 0x2009, 0x0018,
+	0x6028, 0xa005, 0x0040, 0x262e, 0x2009, 0x0040, 0x1078, 0x1dbb,
+	0x0040, 0x2650, 0x78a8, 0x8000, 0x78aa, 0xd08c, 0x00c0, 0x265e,
+	0x6014, 0xd0fc, 0x00c0, 0x2640, 0x2069, 0x4f40, 0x0078, 0x2642,
+	0x2069, 0x4f80, 0x2091, 0x8000, 0x681f, 0x0003, 0x78ab, 0x0000,
+	0x78ac, 0xa085, 0x0300, 0x78ae, 0x2091, 0x8001, 0x0078, 0x265e,
+	0x78ab, 0x0000, 0x1078, 0x2086, 0x7990, 0x7894, 0x8000, 0xa10a,
+	0x00c8, 0x265b, 0xa006, 0x7896, 0x70d6, 0xa006, 0x2071, 0x0010,
+	0x2091, 0x8001, 0x007c, 0xd7fc, 0x00c0, 0x266a, 0x2009, 0x4f59,
+	0x0078, 0x266c, 0x2009, 0x4f99, 0x2091, 0x8000, 0x200a, 0x0f7e,
+	0xd7fc, 0x00c0, 0x2683, 0x2009, 0x4f40, 0x2001, 0x4f04, 0x2004,
+	0xd0ec, 0x0040, 0x267f, 0x2079, 0x0100, 0x0078, 0x2687, 0x2079,
+	0x0200, 0x0078, 0x2687, 0x2009, 0x4f80, 0x2079, 0x0100, 0x2104,
+	0xa086, 0x0000, 0x00c0, 0x26a0, 0xd7fc, 0x00c0, 0x2693, 0x2009,
+	0x4f45, 0x0078, 0x2695, 0x2009, 0x4f85, 0x2104, 0xa005, 0x00c0,
+	0x26a0, 0x7830, 0xa084, 0x00c0, 0x00c0, 0x26a0, 0x781b, 0x0045,
+	0x0f7f, 0x007c, 0x2009, 0x0002, 0x2069, 0x4f00, 0x6810, 0xd0ec,
+	0x00c0, 0x270f, 0x2071, 0x4f80, 0x2079, 0x0100, 0x2021, 0x51bf,
+	0x784b, 0x000f, 0x2019, 0x44a7, 0xd184, 0x0040, 0x26c3, 0x6810,
+	0xd0ec, 0x0040, 0x26bf, 0x20a1, 0x012b, 0x0078, 0x26c5, 0x20a1,
+	0x022b, 0x0078, 0x26c5, 0x20a1, 0x012b, 0x2304, 0xa005, 0x0040,
+	0x26d2, 0x789a, 0x8318, 0x23ac, 0x8318, 0x2398, 0x53a6, 0x3318,
+	0x0078, 0x26c5, 0x789b, 0x0020, 0x20a9, 0x0010, 0x6814, 0xd0e4,
+	0x0040, 0x26e2, 0x78af, 0x0000, 0x78af, 0x9020, 0x00f0, 0x26da,
+	0x0078, 0x26e8, 0x78af, 0x0000, 0x78af, 0x8020, 0x00f0, 0x26e2,
+	0x7003, 0x0000, 0x017e, 0xd18c, 0x2009, 0x0000, 0x0040, 0x26f1,
+	0xc1bd, 0x1078, 0x28e2, 0x017f, 0x7020, 0xa084, 0x000f, 0x007e,
+	0x6814, 0xd0e4, 0x007f, 0x00c0, 0x2701, 0xa085, 0x6340, 0x0078,
+	0x2703, 0xa085, 0x62c0, 0x7806, 0x780f, 0x9200, 0x7843, 0x00d8,
+	0x7853, 0x0080, 0x780b, 0x0008, 0x7456, 0x7053, 0x0000, 0x8109,
+	0x0040, 0x2722, 0x2071, 0x4f40, 0x6810, 0xd0ec, 0x0040, 0x271c,
+	0x2079, 0x0100, 0x0078, 0x271e, 0x2079, 0x0200, 0x2021, 0x4fbf,
+	0x0078, 0x26b0, 0x007c, 0x017e, 0xd1bc, 0x00c0, 0x2737, 0x007e,
+	0x2001, 0x4f04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x2733, 0x2011,
+	0x0101, 0x0078, 0x2739, 0x2011, 0x0201, 0x0078, 0x2739, 0x2011,
+	0x0101, 0xa18c, 0x000f, 0x2204, 0xa084, 0xfff0, 0xa105, 0x2012,
+	0x017f, 0x1078, 0x28e2, 0x007c, 0xd3fc, 0x00c0, 0x2757, 0x007e,
+	0x2001, 0x4f04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x2753, 0x2011,
+	0x0101, 0x0078, 0x2759, 0x2011, 0x0201, 0x0078, 0x2759, 0x2011,
+	0x0101, 0x20a9, 0x0009, 0x810b, 0x00f0, 0x275b, 0xa18c, 0x0e00,
+	0x2204, 0xa084, 0xf1ff, 0xa105, 0x2012, 0x007c, 0x2019, 0x0002,
+	0x2001, 0x4f04, 0x2004, 0xd0ec, 0x0040, 0x2773, 0x8319, 0x2009,
+	0x0101, 0x0078, 0x2775, 0x2009, 0x0101, 0x20a9, 0x0005, 0x8213,
+	0x00f0, 0x2777, 0xa294, 0x00e0, 0x2104, 0xa084, 0xff1f, 0xa205,
+	0x200a, 0x8319, 0x0040, 0x2788, 0x2009, 0x0201, 0x0078, 0x2775,
+	0x007c, 0xd3fc, 0x00c0, 0x279c, 0x007e, 0x2001, 0x4f04, 0x2004,
+	0xd0ec, 0x007f, 0x0040, 0x2798, 0x2011, 0x0101, 0x0078, 0x279e,
+	0x2011, 0x0201, 0x0078, 0x279e, 0x2011, 0x0101, 0x20a9, 0x000c,
+	0x810b, 0x00f0, 0x27a0, 0xa18c, 0xf000, 0x2204, 0xa084, 0x0fff,
+	0xa105, 0x2012, 0x007c, 0xd3fc, 0x00c0, 0x27be, 0x007e, 0x2001,
+	0x4f04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x27ba, 0x2011, 0x0102,
+	0x0078, 0x27c0, 0x2011, 0x0202, 0x0078, 0x27c0, 0x2011, 0x0102,
+	0x2204, 0xa084, 0xffcf, 0xa105, 0x2012, 0x007c, 0x0c7e, 0xd1bc,
+	0x00c0, 0x27da, 0x007e, 0x2001, 0x4f04, 0x2004, 0xd0ec, 0x007f,
+	0x0040, 0x27d6, 0x2061, 0x0100, 0x0078, 0x27dc, 0x2061, 0x0200,
+	0x0078, 0x27dc, 0x2061, 0x0100, 0xc1bc, 0x8103, 0x8003, 0xa080,
+	0x0020, 0x609a, 0x62ac, 0x63ac, 0x0c7f, 0x007c, 0x0c7e, 0xd1bc,
+	0x00c0, 0x27fa, 0x007e, 0x2001, 0x4f04, 0x2004, 0xd0ec, 0x007f,
+	0x0040, 0x27f6, 0x2061, 0x0100, 0x0078, 0x27fc, 0x2061, 0x0200,
+	0x0078, 0x27fc, 0x2061, 0x0100, 0xc1bc, 0x8103, 0x8003, 0xa080,
+	0x0022, 0x609a, 0x60a4, 0xa084, 0xffdf, 0x60ae, 0x0c7f, 0x007c,
+	0x0c7e, 0xd1bc, 0x00c0, 0x281c, 0x007e, 0x2001, 0x4f04, 0x2004,
+	0xd0ec, 0x007f, 0x0040, 0x2818, 0x2061, 0x0100, 0x0078, 0x281e,
+	0x2061, 0x0200, 0x0078, 0x281e, 0x2061, 0x0100, 0xc1bc, 0x8103,
+	0x8003, 0xa080, 0x0022, 0x609a, 0x60a4, 0xa085, 0x0020, 0x60ae,
+	0x0c7f, 0x007c, 0x0c7e, 0xd1bc, 0x00c0, 0x283e, 0x007e, 0x2001,
+	0x4f04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x283a, 0x2061, 0x0100,
+	0x0078, 0x2840, 0x2061, 0x0200, 0x0078, 0x2840, 0x2061, 0x0100,
+	0xc1bc, 0x8103, 0x8003, 0xa080, 0x0020, 0x609a, 0x60a4, 0xa28c,
+	0x0020, 0x0040, 0x284e, 0xc2ac, 0xa39d, 0x4000, 0xc3fc, 0xd3b4,
+	0x00c0, 0x2853, 0xc3fd, 0x62ae, 0x2010, 0x60a4, 0x63ae, 0x2018,
+	0x0c7f, 0x007c, 0x2091, 0x8000, 0x0c7e, 0x0e7e, 0x6818, 0xa005,
+	0x0040, 0x28c0, 0xd1fc, 0x0040, 0x2869, 0x2061, 0x96d0, 0x0078,
+	0x286b, 0x2061, 0x95c0, 0x1078, 0x28c8, 0x0040, 0x28a2, 0x20a9,
+	0x0101, 0xd1fc, 0x0040, 0x2878, 0x2061, 0x95d0, 0x0078, 0x287a,
+	0x2061, 0x94c0, 0x0c7e, 0x1078, 0x28c8, 0x0040, 0x2885, 0x0c7f,
+	0x8c60, 0x00f0, 0x287a, 0x0078, 0x28c0, 0x007f, 0xd1fc, 0x0040,
+	0x288f, 0xa082, 0x95d0, 0x2071, 0x4f80, 0x0078, 0x2893, 0xa082,
+	0x94c0, 0x2071, 0x4f40, 0x707a, 0x7176, 0x2138, 0x2001, 0x0004,
+	0x7066, 0x7083, 0x000f, 0x71d4, 0xc1dc, 0x71d6, 0x1078, 0x2663,
+	0x0078, 0x28bc, 0xd1fc, 0x00c0, 0x28a9, 0x2071, 0x4f40, 0x0078,
+	0x28ab, 0x2071, 0x4f80, 0x6020, 0xc0dd, 0x6022, 0x7176, 0x2138,
+	0x2c00, 0x707e, 0x2001, 0x0006, 0x7066, 0x7083, 0x000f, 0x71d4,
+	0xc1dc, 0x71d6, 0x1078, 0x2663, 0x2001, 0x0000, 0x0078, 0x28c2,
+	0x2001, 0x0001, 0x2091, 0x8001, 0xa005, 0x0e7f, 0x0c7f, 0x007c,
+	0x2c04, 0xa005, 0x0040, 0x28df, 0x2060, 0x6010, 0xa306, 0x00c0,
+	0x28dc, 0x600c, 0xa206, 0x00c0, 0x28dc, 0x6014, 0xa106, 0x00c0,
+	0x28dc, 0xa006, 0x0078, 0x28e1, 0x6000, 0x0078, 0x28c9, 0xa085,
+	0x0001, 0x007c, 0x0f7e, 0x0e7e, 0x017e, 0xd1bc, 0x00c0, 0x28fa,
+	0x2079, 0x4f40, 0x007e, 0x2001, 0x4f04, 0x2004, 0xd0ec, 0x007f,
+	0x0040, 0x28f6, 0x2071, 0x0100, 0x0078, 0x28fe, 0x2071, 0x0200,
+	0x0078, 0x28fe, 0x2079, 0x4f80, 0x2071, 0x0100, 0x7920, 0xa18c,
+	0x000f, 0x70ec, 0xd0c4, 0x00c0, 0x2908, 0x017f, 0x0078, 0x2923,
+	0x810b, 0x810b, 0x810b, 0x810b, 0x007f, 0xd0bc, 0x00c0, 0x2920,
+	0x007e, 0x2001, 0x4f04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x291c,
+	0xa18d, 0x0f00, 0x0078, 0x2922, 0xa18d, 0x0f00, 0x0078, 0x2922,
+	0xa18d, 0x0800, 0x2104, 0x0e7f, 0x0f7f, 0x007c, 0x0e7e, 0x2001,
+	0x4f01, 0x2004, 0xd0ac, 0x00c0, 0x29a3, 0x68e4, 0xd0ac, 0x0040,
+	0x29a3, 0xa084, 0x0006, 0x00c0, 0x29a3, 0x6014, 0xd0fc, 0x00c0,
+	0x293d, 0x2071, 0x53c0, 0x0078, 0x293f, 0x2071, 0x5440, 0x8007,
+	0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xae70, 0x7004, 0xa084,
+	0x000a, 0x00c0, 0x29a3, 0x7108, 0xa194, 0xff00, 0x0040, 0x29a3,
+	0xa18c, 0x00ff, 0x2001, 0x000a, 0xa106, 0x0040, 0x2972, 0x2001,
+	0x000c, 0xa106, 0x0040, 0x2976, 0x2001, 0x0012, 0xa106, 0x0040,
+	0x297a, 0x2001, 0x0014, 0xa106, 0x0040, 0x297e, 0x2001, 0x0019,
+	0xa106, 0x0040, 0x2982, 0x2001, 0x0032, 0xa106, 0x0040, 0x2986,
+	0x0078, 0x298a, 0x2009, 0x000c, 0x0078, 0x298c, 0x2009, 0x0012,
+	0x0078, 0x298c, 0x2009, 0x0014, 0x0078, 0x298c, 0x2009, 0x0019,
+	0x0078, 0x298c, 0x2009, 0x0020, 0x0078, 0x298c, 0x2009, 0x003f,
+	0x0078, 0x298c, 0x2011, 0x0000, 0x2100, 0xa205, 0x700a, 0x2071,
+	0x4f00, 0x7004, 0xd0bc, 0x0040, 0x29a3, 0x6014, 0xd0fc, 0x00c0,
+	0x299e, 0x70ea, 0x2071, 0x4f40, 0x0078, 0x29a1, 0x70ee, 0x2071,
+	0x4f80, 0x701f, 0x000d, 0x0e7f, 0x007c, 0x2001, 0x4f05, 0x2004,
+	0xd0e4, 0x00c0, 0x29b1, 0x7804, 0xa084, 0xff1f, 0xa085, 0x6340,
+	0x7806, 0x007c, 0x0068, 0x29b2, 0x2091, 0x8000, 0x2071, 0x0000,
+	0x007e, 0x7018, 0xd084, 0x00c0, 0x29b9, 0x007f, 0x2071, 0x0010,
+	0x70ca, 0x007f, 0x70c6, 0x70c3, 0x8002, 0x70db, 0x080f, 0x70df,
+	0x000b, 0x2071, 0x0000, 0x701b, 0x0001, 0x2091, 0x4080, 0x0078,
+	0x29cf, 0x7f3c, 0x7e58, 0x7c30, 0x7d38, 0x78a0, 0x708e, 0x7592,
+	0x7496, 0x769a, 0x779e, 0xa594, 0x003f, 0xd4f4, 0x0040, 0x29e6,
+	0xa784, 0x007d, 0x00c0, 0x441d, 0x1078, 0x29b2, 0xa49c, 0x000f,
+	0xa382, 0x0004, 0x0050, 0x29f1, 0xa3a6, 0x0007, 0x00c0, 0x29b2,
+	0x2418, 0x8507, 0xa084, 0x000f, 0x0079, 0x29f6, 0x3071, 0x3162,
+	0x318d, 0x33ff, 0x37e8, 0x3862, 0x3917, 0x39a8, 0x3a96, 0x3b85,
+	0x2a09, 0x2a06, 0x2e42, 0x2f65, 0x37b9, 0x2a06, 0x1078, 0x29b2,
+	0x007c, 0xa006, 0x0078, 0x2a13, 0x7808, 0xc08d, 0x780a, 0xa006,
+	0x7002, 0x704e, 0x7046, 0x70d2, 0x7060, 0xa005, 0x00c0, 0x2b79,
+	0x7064, 0xa084, 0x0007, 0x0079, 0x2a1d, 0x2a25, 0x2a98, 0x2aa1,
+	0x2aac, 0x2ab7, 0x2b5f, 0x2ac2, 0x2a98, 0x7830, 0xd0bc, 0x00c0,
+	0x2a08, 0x71d4, 0xd1bc, 0x00c0, 0x2a08, 0xd1b4, 0x00c0, 0x2a75,
+	0x70a4, 0xa086, 0x0001, 0x0040, 0x2a08, 0x70b4, 0xa06d, 0x6800,
+	0xa065, 0xa055, 0x789b, 0x0010, 0x6b0c, 0x7baa, 0x6808, 0xa045,
+	0x6d10, 0x6804, 0xa06d, 0xa05d, 0xa886, 0x0001, 0x0040, 0x2a4b,
+	0x69bc, 0x7daa, 0x79aa, 0x68c0, 0xa04d, 0x6e1c, 0x2001, 0x0010,
+	0x0078, 0x2cd3, 0x7060, 0xa005, 0x00c0, 0x2a08, 0x0c7e, 0x0d7e,
+	0x70b4, 0xa06d, 0x6800, 0xa065, 0xa055, 0x789b, 0x0010, 0x6b0c,
+	0x7baa, 0x6808, 0xa045, 0x6d10, 0x6804, 0xa06d, 0xa05d, 0xa886,
+	0x0001, 0x0040, 0x2a6e, 0x69bc, 0x7daa, 0x79aa, 0x68c0, 0xa04d,
+	0x6e1c, 0x2001, 0x0020, 0x0078, 0x2cd3, 0x1078, 0x43b0, 0x00c0,
+	0x2a08, 0x781b, 0x005b, 0x70bc, 0xa06d, 0x68b4, 0x785a, 0x6894,
 	0x78d6, 0x78de, 0x6898, 0x78d2, 0x78da, 0x7808, 0xc08d, 0x780a,
-	0x70a4, 0x8000, 0x70a6, 0x74b4, 0xa490, 0x0005, 0x70ac, 0xa206,
-	0x00c0, 0x2db3, 0x72a8, 0x72b6, 0x2900, 0x705a, 0x68bc, 0x7042,
+	0x68bc, 0x7042, 0xc1b4, 0x71d6, 0x70b8, 0xa065, 0x68c0, 0x705a,
 	0x7003, 0x0002, 0x2d00, 0x704e, 0xad80, 0x0009, 0x7046, 0x007c,
-	0x6bb4, 0xa39d, 0x2000, 0x7b5a, 0x6814, 0xc0fc, 0x8007, 0x7882,
-	0x6b94, 0x7bd6, 0x7bde, 0x6e98, 0x7ed2, 0x7eda, 0x781b, 0x005b,
-	0x2900, 0x705a, 0x7202, 0x7808, 0xc08d, 0x780a, 0x2300, 0xa605,
-	0x0040, 0x2deb, 0x70d4, 0xa084, 0x2700, 0xa086, 0x2300, 0x00c0,
-	0x2de5, 0x2009, 0x0000, 0x0078, 0x2de7, 0x2009, 0x0001, 0xa284,
-	0x000f, 0x1079, 0x2def, 0xad80, 0x0009, 0x7046, 0x007c, 0x2df7,
-	0x48bd, 0x48bd, 0x48aa, 0x48bd, 0x2df7, 0x2df7, 0x2df7, 0x1078,
-	0x296b, 0x7808, 0xa084, 0xfffd, 0x780a, 0x1078, 0x295e, 0x0f7e,
-	0x2079, 0x4e00, 0x78ac, 0x0f7f, 0xd084, 0x0040, 0x2e21, 0x7064,
-	0xa086, 0x0001, 0x00c0, 0x2e0f, 0x7066, 0x0078, 0x2ef8, 0x7064,
-	0xa086, 0x0005, 0x00c0, 0x2e1f, 0x707c, 0x2068, 0x681b, 0x0004,
-	0x6817, 0x0000, 0x6820, 0xa084, 0x00ff, 0xc09d, 0x6822, 0x7067,
-	0x0000, 0x70a7, 0x0000, 0x70a8, 0x70b2, 0x70b6, 0x1078, 0x2aba,
-	0x157e, 0x2011, 0x0004, 0x7164, 0xa186, 0x0001, 0x0040, 0x2e41,
-	0xa186, 0x0007, 0x00c0, 0x2e38, 0x701f, 0x0005, 0x0078, 0x2e41,
-	0x701f, 0x0001, 0x7067, 0x0000, 0x70d4, 0xc0dd, 0x70d6, 0x0078,
-	0x2e43, 0x7067, 0x0000, 0x2001, 0x4e0a, 0x2004, 0xa084, 0x00ff,
-	0xa086, 0x0018, 0x0040, 0x2e53, 0x7018, 0x7016, 0xa005, 0x00c0,
-	0x2e53, 0x70a7, 0x0001, 0x067e, 0x1078, 0x4586, 0x20a9, 0x0010,
-	0x2039, 0x0000, 0x1078, 0x40f8, 0xa7b8, 0x0100, 0x00f0, 0x2e5a,
-	0x067f, 0x7000, 0x0079, 0x2e64, 0x2e9e, 0x2e79, 0x2e79, 0x2e6e,
-	0x2e9e, 0x2e9e, 0x2e9e, 0x2e6c, 0x1078, 0x296b, 0x7060, 0xa005,
-	0x0040, 0x2e9e, 0xad06, 0x00c0, 0x2e79, 0x6800, 0x7062, 0x0078,
-	0x2e8b, 0x6820, 0xd084, 0x00c0, 0x2e87, 0x6f14, 0x1078, 0x41fe,
-	0x6008, 0xc0d4, 0x600a, 0x1078, 0x3dd0, 0x0078, 0x2e8b, 0x705c,
-	0x2060, 0x6800, 0x6002, 0xa684, 0x5f00, 0x681e, 0x6818, 0xd0fc,
-	0x0040, 0x2e93, 0x6a1a, 0x6817, 0x0000, 0x682b, 0x0000, 0x6820,
-	0xa084, 0x00ff, 0xc09d, 0x6822, 0x1078, 0x202c, 0xb284, 0x0400,
-	0x0040, 0x2ea6, 0x2021, 0x95d0, 0x0078, 0x2ea8, 0x2021, 0x94c0,
-	0x1078, 0x2efd, 0xb284, 0x0400, 0x0040, 0x2eb2, 0x2021, 0x4e98,
-	0x0078, 0x2eb4, 0x2021, 0x4e58, 0x1078, 0x2efd, 0x20a9, 0x0101,
-	0xb284, 0x0400, 0x0040, 0x2ec0, 0x2021, 0x94d0, 0x0078, 0x2ec2,
-	0x2021, 0x93c0, 0x1078, 0x2efd, 0x8420, 0x00f0, 0x2ec2, 0xb284,
-	0x0300, 0x0040, 0x2ecf, 0x2061, 0x53c0, 0x0078, 0x2ed1, 0x2061,
-	0x73c0, 0x2021, 0x0002, 0x20a9, 0x0100, 0x6110, 0x81ff, 0x0040,
-	0x2eee, 0x6018, 0x017e, 0x007e, 0x2011, 0x4e02, 0x220c, 0xa102,
-	0x2012, 0x007f, 0x017f, 0xa102, 0x0050, 0x2eee, 0x6012, 0x00c0,
-	0x2eee, 0x2011, 0x4e04, 0x2204, 0xc0a5, 0x2012, 0x601b, 0x0000,
-	0xace0, 0x0010, 0x00f0, 0x2ed5, 0x8421, 0x00c0, 0x2ed3, 0x157f,
-	0x7003, 0x0000, 0x704f, 0x0000, 0x007c, 0x047e, 0x2404, 0xa005,
-	0x0040, 0x2f18, 0x2068, 0x6800, 0x007e, 0x6a1a, 0x6817, 0x0000,
+	0x1078, 0x43b0, 0x00c0, 0x2aa0, 0x781b, 0x0047, 0x7003, 0x0004,
+	0x007c, 0x1078, 0x43b0, 0x00c0, 0x2aab, 0x2011, 0x000c, 0x1078,
+	0x2ad2, 0x7003, 0x0004, 0x007c, 0x1078, 0x43b0, 0x00c0, 0x2ab6,
+	0x2011, 0x0006, 0x1078, 0x2ad2, 0x7003, 0x0004, 0x007c, 0x1078,
+	0x43b0, 0x00c0, 0x2ac1, 0x2011, 0x000d, 0x1078, 0x2ad2, 0x7003,
+	0x0004, 0x007c, 0x1078, 0x43b0, 0x00c0, 0x2ad1, 0x2011, 0x0006,
+	0x1078, 0x2ad2, 0x707c, 0x707f, 0x0000, 0x2068, 0x704e, 0x7003,
+	0x0001, 0x007c, 0x7174, 0xc1fc, 0x8107, 0x7882, 0x789b, 0x0010,
+	0xa286, 0x000c, 0x00c0, 0x2ae1, 0x7aaa, 0x2001, 0x0001, 0x0078,
+	0x2af6, 0xa18c, 0x001f, 0xa18d, 0x00c0, 0x79aa, 0xa286, 0x000d,
+	0x0040, 0x2aef, 0x7aaa, 0x2001, 0x0002, 0x0078, 0x2af6, 0x78ab,
+	0x0020, 0x7178, 0x79aa, 0x7aaa, 0x2001, 0x0004, 0x789b, 0x0060,
+	0x78aa, 0x785b, 0x0004, 0x781b, 0x0116, 0x1078, 0x43d3, 0x7083,
+	0x000f, 0x70d4, 0xd0b4, 0x0040, 0x2b12, 0xc0b4, 0x70d6, 0x0c7e,
+	0x70b8, 0xa065, 0x6008, 0xa084, 0xfbef, 0x600a, 0x6018, 0x8001,
+	0x601a, 0x0c7f, 0x007c, 0x7014, 0xa005, 0x00c0, 0x2b21, 0x70d4,
+	0xd0b4, 0x0040, 0x2b22, 0x70b8, 0xac06, 0x00c0, 0x2b22, 0x1078,
+	0x2b01, 0x007c, 0x017e, 0x71a4, 0xa186, 0x0001, 0x0040, 0x2b54,
+	0x0d7e, 0x027e, 0x2100, 0x2011, 0x0001, 0xa212, 0x70b4, 0x2068,
+	0x6800, 0xac06, 0x0040, 0x2b3b, 0x8211, 0x0040, 0x2b52, 0x1078,
+	0x2b56, 0x0078, 0x2b30, 0x0c7e, 0x2100, 0x2011, 0x0001, 0xa212,
+	0x70b4, 0x2068, 0x6800, 0x2060, 0x6008, 0xa084, 0xfbef, 0x600a,
+	0x8211, 0x0040, 0x2b4f, 0x1078, 0x2b56, 0x0078, 0x2b42, 0x70a7,
+	0x0001, 0x0c7f, 0x027f, 0x0d7f, 0x017f, 0x007c, 0xade8, 0x0005,
+	0x70ac, 0xad06, 0x00c0, 0x2b5e, 0x70a8, 0x2068, 0x007c, 0x1078,
+	0x43b0, 0x00c0, 0x2a08, 0x707c, 0x2068, 0x7774, 0x1078, 0x424e,
+	0x2c50, 0x1078, 0x4492, 0x789b, 0x0010, 0x6814, 0xa084, 0x001f,
+	0xc0bd, 0x78aa, 0x6e1c, 0x2041, 0x0001, 0x2001, 0x0004, 0x0078,
+	0x2cd9, 0x1078, 0x43b0, 0x00c0, 0x2a08, 0x789b, 0x0010, 0x7060,
+	0x2068, 0x6f14, 0x70d4, 0xd0b4, 0x0040, 0x2b93, 0xc0b4, 0x70d6,
+	0x0c7e, 0x70b8, 0xa065, 0x6008, 0xa084, 0xfbef, 0x600a, 0x6018,
+	0x8001, 0x601a, 0x0c7f, 0x1078, 0x424e, 0x2c50, 0x1078, 0x4492,
+	0x6824, 0xa005, 0x0040, 0x2ba4, 0xa082, 0x0006, 0x0048, 0x2ba2,
+	0x0078, 0x2ba4, 0x6827, 0x0005, 0x6814, 0xa084, 0x001f, 0xc0bd,
+	0x78aa, 0x2031, 0x0020, 0x2041, 0x0001, 0x2001, 0x0003, 0x0078,
+	0x2cd9, 0xc28d, 0x72d6, 0x72c0, 0xa200, 0xa015, 0x7154, 0x8108,
+	0xa12a, 0x0048, 0x2bbc, 0x71c0, 0x2164, 0x6504, 0x85ff, 0x00c0,
+	0x2bd3, 0x7156, 0x8421, 0x00c0, 0x2bb7, 0x70d4, 0xd08c, 0x0040,
+	0x2bcf, 0x70d0, 0xa005, 0x00c0, 0x2bcf, 0x70d3, 0x000a, 0x007c,
+	0x2200, 0x0078, 0x2bc1, 0x70d4, 0xc08c, 0x70d6, 0x70d3, 0x0000,
+	0x6034, 0xa005, 0x00c0, 0x2bd0, 0x6708, 0xa784, 0x073f, 0x0040,
+	0x2c02, 0xd7d4, 0x00c0, 0x2bd0, 0xa784, 0x0021, 0x00c0, 0x2bd0,
+	0xa784, 0x0002, 0x0040, 0x2bf3, 0xa784, 0x0004, 0x0040, 0x2bd0,
+	0xa7bc, 0xfffb, 0x670a, 0xa784, 0x0218, 0x00c0, 0x2bd0, 0xa784,
+	0x0100, 0x0040, 0x2c02, 0x6018, 0xa005, 0x00c0, 0x2bd0, 0xa7bc,
+	0xfeff, 0x670a, 0x2568, 0x6823, 0x0000, 0x6e1c, 0xa684, 0x000e,
+	0x6318, 0x0040, 0x2c13, 0x601c, 0xa302, 0x0048, 0x2c16, 0x0040,
+	0x2c16, 0x0078, 0x2bd0, 0x83ff, 0x00c0, 0x2bd0, 0x2d58, 0x2c50,
+	0x7156, 0xd7bc, 0x00c0, 0x2c1f, 0x7028, 0x6022, 0x603a, 0xc7bc,
+	0x670a, 0x68c0, 0xa065, 0xa04d, 0x6100, 0x2a60, 0x2041, 0x0001,
+	0x6b14, 0xa39c, 0x001f, 0xa39d, 0x00c0, 0xd1fc, 0x0040, 0x2c33,
+	0xd684, 0x0040, 0x2c35, 0xa39c, 0xffbf, 0xd6a4, 0x0040, 0x2c3a,
+	0xa39d, 0x0020, 0xa684, 0x000e, 0x00c0, 0x2c85, 0xc7a5, 0x670a,
+	0x2c00, 0x68c6, 0x77a4, 0xa786, 0x0001, 0x00c0, 0x2c59, 0x70d4,
+	0xd0b4, 0x00c0, 0x2c59, 0x7000, 0xa082, 0x0002, 0x00c8, 0x2c59,
+	0x7830, 0xd0bc, 0x00c0, 0x2c59, 0x789b, 0x0010, 0x7baa, 0x0078,
+	0x2cd1, 0x8739, 0x77a6, 0x2750, 0x77b0, 0xa7b0, 0x0005, 0x70ac,
+	0xa606, 0x00c0, 0x2c64, 0x76a8, 0x76b2, 0x2c3a, 0x8738, 0x2d3a,
+	0x8738, 0x283a, 0x8738, 0x233a, 0x8738, 0x253a, 0x7830, 0xd0bc,
+	0x0040, 0x2c7c, 0x2091, 0x8000, 0x2091, 0x303d, 0x70d4, 0xa084,
+	0x303d, 0x2091, 0x8000, 0x2090, 0xaad5, 0x0000, 0x0040, 0x2c84,
+	0x8421, 0x2200, 0x00c0, 0x2bb6, 0x007c, 0xd1dc, 0x0040, 0x3e49,
+	0x2029, 0x0020, 0xd69c, 0x00c0, 0x2c92, 0x8528, 0xd68c, 0x00c0,
+	0x2c92, 0x8528, 0x8840, 0x6f14, 0x610c, 0x8108, 0xa18c, 0x00ff,
+	0x70cc, 0xa160, 0x2c64, 0x8cff, 0x0040, 0x2cb1, 0x6014, 0xa706,
+	0x00c0, 0x2c9a, 0x60b8, 0x8001, 0x60ba, 0x00c0, 0x2c95, 0x2a60,
+	0x6008, 0xa085, 0x0100, 0x600a, 0x2200, 0x8421, 0x00c0, 0x2bb6,
+	0x007c, 0x2a60, 0x610e, 0x69be, 0x2c00, 0x68c6, 0x8840, 0x6008,
+	0xc0d5, 0x600a, 0x77a4, 0xa786, 0x0001, 0x00c0, 0x2c59, 0x70d4,
+	0xd0b4, 0x00c0, 0x2c59, 0x7000, 0xa082, 0x0002, 0x00c8, 0x2c59,
+	0x7830, 0xd0bc, 0x00c0, 0x2c59, 0x789b, 0x0010, 0x7baa, 0x7daa,
+	0x79aa, 0x2001, 0x0002, 0x007e, 0x6018, 0x8000, 0x601a, 0x0078,
+	0x2cda, 0x007e, 0x2960, 0x6104, 0x2a60, 0xa184, 0x0018, 0x0040,
+	0x2cf6, 0xa184, 0x0010, 0x0040, 0x2ce9, 0x1078, 0x405e, 0x00c0,
+	0x2d1b, 0xa184, 0x0008, 0x0040, 0x2cf6, 0x69a0, 0xa184, 0x0600,
+	0x00c0, 0x2cf6, 0x1078, 0x3f3e, 0x0078, 0x2d1b, 0x69a0, 0xa184,
+	0x1e00, 0x0040, 0x2d26, 0xa184, 0x0800, 0x0040, 0x2d0f, 0x0c7e,
+	0x2960, 0x6000, 0xa085, 0x2000, 0x6002, 0x6104, 0xa18d, 0x0010,
+	0x6106, 0x0c7f, 0x1078, 0x405e, 0x00c0, 0x2d1b, 0x69a0, 0xa184,
+	0x0200, 0x0040, 0x2d17, 0x1078, 0x3fa1, 0x0078, 0x2d1b, 0xa184,
+	0x0400, 0x00c0, 0x2cf2, 0x69a0, 0xa184, 0x1000, 0x0040, 0x2d26,
+	0x6914, 0xa18c, 0xff00, 0x810f, 0x1078, 0x27e6, 0x027f, 0xa68c,
+	0x00e0, 0xa684, 0x0060, 0x0040, 0x2d33, 0xa086, 0x0060, 0x00c0,
+	0x2d33, 0xa18d, 0x4000, 0xa18d, 0x0104, 0x69b6, 0x789b, 0x0060,
+	0x2800, 0x78aa, 0x6818, 0xc0fd, 0x681a, 0xd6bc, 0x0040, 0x2d4e,
+	0xc0fc, 0x7087, 0x0000, 0xa08a, 0x000d, 0x0050, 0x2d4c, 0xa08a,
+	0x000c, 0x7186, 0x2001, 0x000c, 0x800c, 0x718a, 0x78aa, 0x3518,
+	0x3340, 0x3428, 0x8000, 0x80ac, 0xaf80, 0x002b, 0x20a0, 0x789b,
+	0x0000, 0xad80, 0x000b, 0x2098, 0x53a6, 0x23a8, 0x2898, 0x25a0,
+	0xa286, 0x0020, 0x00c0, 0x2d86, 0x70d4, 0xc0b5, 0x70d6, 0x2c00,
+	0x70ba, 0x2d00, 0x70be, 0x6814, 0xc0fc, 0x8007, 0x7882, 0xa286,
+	0x0002, 0x0040, 0x2dbc, 0x70a4, 0x8000, 0x70a6, 0x74b4, 0xa498,
+	0x0005, 0x70ac, 0xa306, 0x00c0, 0x2d7e, 0x73a8, 0x73b6, 0xa286,
+	0x0010, 0x0040, 0x2a08, 0x0d7f, 0x0c7f, 0x007c, 0x7000, 0xa005,
+	0x00c0, 0x2d64, 0xa286, 0x0002, 0x00c0, 0x2dd6, 0x1078, 0x43b0,
+	0x00c0, 0x2d64, 0x6814, 0xc0fc, 0x8007, 0x7882, 0x2091, 0x8000,
+	0x781b, 0x005b, 0x68b4, 0x785a, 0x6894, 0x78d6, 0x78de, 0x6898,
+	0x78d2, 0x78da, 0x2091, 0x8001, 0x7808, 0xc08d, 0x780a, 0x127e,
+	0x0d7e, 0x0c7e, 0x70d4, 0xa084, 0x2700, 0x2090, 0x0c7f, 0x0d7f,
+	0x127f, 0x2900, 0x705a, 0x68bc, 0x7042, 0x7003, 0x0002, 0x2d00,
+	0x704e, 0xad80, 0x0009, 0x7046, 0x7830, 0xd0bc, 0x0040, 0x2dc8,
+	0x2091, 0x303d, 0x70d4, 0xa084, 0x303d, 0x2091, 0x8000, 0x2090,
+	0x70a4, 0xa005, 0x00c0, 0x2dcd, 0x007c, 0x8421, 0x0040, 0x2dcc,
+	0x7250, 0x70c0, 0xa200, 0xa015, 0x0078, 0x2bb6, 0xa286, 0x0010,
+	0x00c0, 0x2e07, 0x1078, 0x43b0, 0x00c0, 0x2d64, 0x6814, 0xc0fc,
+	0x8007, 0x7882, 0x781b, 0x005b, 0x68b4, 0x785a, 0x6894, 0x78d6,
+	0x78de, 0x6898, 0x78d2, 0x78da, 0x7808, 0xc08d, 0x780a, 0x70a4,
+	0x8000, 0x70a6, 0x74b4, 0xa490, 0x0005, 0x70ac, 0xa206, 0x00c0,
+	0x2dfa, 0x72a8, 0x72b6, 0x2900, 0x705a, 0x68bc, 0x7042, 0x7003,
+	0x0002, 0x2d00, 0x704e, 0xad80, 0x0009, 0x7046, 0x007c, 0x6bb4,
+	0xa39d, 0x2000, 0x7b5a, 0x6814, 0xc0fc, 0x8007, 0x7882, 0x6b94,
+	0x7bd6, 0x7bde, 0x6e98, 0x7ed2, 0x7eda, 0x781b, 0x005b, 0x2900,
+	0x705a, 0x7202, 0x7808, 0xc08d, 0x780a, 0x2300, 0xa605, 0x0040,
+	0x2e32, 0x70d4, 0xa084, 0x2700, 0xa086, 0x2300, 0x00c0, 0x2e2c,
+	0x2009, 0x0000, 0x0078, 0x2e2e, 0x2009, 0x0001, 0xa284, 0x000f,
+	0x1079, 0x2e38, 0xad80, 0x0009, 0x7046, 0x2d00, 0x704e, 0x007c,
+	0x2e40, 0x493f, 0x493f, 0x492c, 0x493f, 0x2e40, 0x2e40, 0x2e40,
+	0x1078, 0x29b2, 0x7808, 0xa084, 0xfffd, 0x780a, 0x1078, 0x29a5,
+	0x0f7e, 0x2079, 0x4f00, 0x78ac, 0x0f7f, 0xd084, 0x0040, 0x2e6a,
+	0x7064, 0xa086, 0x0001, 0x00c0, 0x2e58, 0x7066, 0x0078, 0x2f41,
+	0x7064, 0xa086, 0x0005, 0x00c0, 0x2e68, 0x707c, 0x2068, 0x681b,
+	0x0004, 0x6817, 0x0000, 0x6820, 0xa084, 0x00ff, 0xc09d, 0x6822,
+	0x7067, 0x0000, 0x70a7, 0x0000, 0x70a8, 0x70b2, 0x70b6, 0x1078,
+	0x2b01, 0x157e, 0x2011, 0x0004, 0x7164, 0xa186, 0x0001, 0x0040,
+	0x2e8a, 0xa186, 0x0007, 0x00c0, 0x2e81, 0x701f, 0x0005, 0x0078,
+	0x2e8a, 0x701f, 0x0001, 0x7067, 0x0000, 0x70d4, 0xc0dd, 0x70d6,
+	0x0078, 0x2e8c, 0x7067, 0x0000, 0x2001, 0x4f0a, 0x2004, 0xa084,
+	0x00ff, 0xa086, 0x0018, 0x0040, 0x2e9c, 0x7018, 0x7016, 0xa005,
+	0x00c0, 0x2e9c, 0x70a7, 0x0001, 0x067e, 0x1078, 0x45d6, 0x20a9,
+	0x0010, 0x2039, 0x0000, 0x1078, 0x4148, 0xa7b8, 0x0100, 0x00f0,
+	0x2ea3, 0x067f, 0x7000, 0x0079, 0x2ead, 0x2ee7, 0x2ec2, 0x2ec2,
+	0x2eb7, 0x2ee7, 0x2ee7, 0x2ee7, 0x2eb5, 0x1078, 0x29b2, 0x7060,
+	0xa005, 0x0040, 0x2ee7, 0xad06, 0x00c0, 0x2ec2, 0x6800, 0x7062,
+	0x0078, 0x2ed4, 0x6820, 0xd084, 0x00c0, 0x2ed0, 0x6f14, 0x1078,
+	0x424e, 0x6008, 0xc0d4, 0x600a, 0x1078, 0x3e19, 0x0078, 0x2ed4,
+	0x705c, 0x2060, 0x6800, 0x6002, 0xa684, 0x5f00, 0x681e, 0x6818,
+	0xd0fc, 0x0040, 0x2edc, 0x6a1a, 0x6817, 0x0000, 0x682b, 0x0000,
+	0x6820, 0xa084, 0x00ff, 0xc09d, 0x6822, 0x1078, 0x2073, 0xb284,
+	0x0400, 0x0040, 0x2eef, 0x2021, 0x96d0, 0x0078, 0x2ef1, 0x2021,
+	0x95c0, 0x1078, 0x2f46, 0xb284, 0x0400, 0x0040, 0x2efb, 0x2021,
+	0x4f98, 0x0078, 0x2efd, 0x2021, 0x4f58, 0x1078, 0x2f46, 0x20a9,
+	0x0101, 0xb284, 0x0400, 0x0040, 0x2f09, 0x2021, 0x95d0, 0x0078,
+	0x2f0b, 0x2021, 0x94c0, 0x1078, 0x2f46, 0x8420, 0x00f0, 0x2f0b,
+	0xb284, 0x0300, 0x0040, 0x2f18, 0x2061, 0x54c0, 0x0078, 0x2f1a,
+	0x2061, 0x74c0, 0x2021, 0x0002, 0x20a9, 0x0100, 0x6110, 0x81ff,
+	0x0040, 0x2f37, 0x6018, 0x017e, 0x007e, 0x2011, 0x4f02, 0x220c,
+	0xa102, 0x2012, 0x007f, 0x017f, 0xa102, 0x0050, 0x2f37, 0x6012,
+	0x00c0, 0x2f37, 0x2011, 0x4f04, 0x2204, 0xc0a5, 0x2012, 0x601b,
+	0x0000, 0xace0, 0x0010, 0x00f0, 0x2f1e, 0x8421, 0x00c0, 0x2f1c,
+	0x157f, 0x7003, 0x0000, 0x704f, 0x0000, 0x007c, 0x047e, 0x2404,
+	0xa005, 0x0040, 0x2f61, 0x2068, 0x6800, 0x007e, 0x6a1a, 0x6817,
+	0x0000, 0x682b, 0x0000, 0x68b4, 0xa084, 0x5f00, 0x681e, 0x6820,
+	0xa084, 0x00ff, 0xc09d, 0x6822, 0x1078, 0x2073, 0x007f, 0x0078,
+	0x2f48, 0x047f, 0x2023, 0x0000, 0x007c, 0xa282, 0x0003, 0x0050,
+	0x2f6b, 0x1078, 0x29b2, 0x2300, 0x0079, 0x2f6e, 0x2f71, 0x2ffc,
+	0x3019, 0xa282, 0x0002, 0x0040, 0x2f77, 0x1078, 0x29b2, 0x7064,
+	0x7067, 0x0000, 0x7083, 0x0000, 0x0079, 0x2f7e, 0x2f86, 0x2f86,
+	0x2f88, 0x2fc8, 0x3e55, 0x2f86, 0x2fc8, 0x2f86, 0x1078, 0x29b2,
+	0x7774, 0x1078, 0x4148, 0x7774, 0xa7bc, 0x8f00, 0x1078, 0x424e,
+	0x6018, 0xa005, 0x0040, 0x2fbf, 0xd7fc, 0x00c0, 0x2f9b, 0x2021,
+	0x95c0, 0x0078, 0x2f9d, 0x2021, 0x96d0, 0x2009, 0x0005, 0x2011,
+	0x0010, 0x1078, 0x3034, 0x0040, 0x2fbf, 0x157e, 0x20a9, 0x0101,
+	0xd7fc, 0x00c0, 0x2faf, 0x2021, 0x94c0, 0x0078, 0x2fb1, 0x2021,
+	0x95d0, 0x047e, 0x2009, 0x0005, 0x2011, 0x0010, 0x1078, 0x3034,
+	0x047f, 0x0040, 0x2fbe, 0x8420, 0x00f0, 0x2fb1, 0x157f, 0x8738,
+	0xa784, 0x001f, 0x00c0, 0x2f8e, 0x0078, 0x2a0c, 0x0078, 0x2a0c,
+	0x7774, 0x1078, 0x424e, 0x6018, 0xa005, 0x0040, 0x2ffa, 0xd7fc,
+	0x00c0, 0x2fd6, 0x2021, 0x95c0, 0x0078, 0x2fd8, 0x2021, 0x96d0,
+	0x2009, 0x0005, 0x2011, 0x0020, 0x1078, 0x3034, 0x0040, 0x2ffa,
+	0x157e, 0x20a9, 0x0101, 0xd7fc, 0x00c0, 0x2fea, 0x2021, 0x94c0,
+	0x0078, 0x2fec, 0x2021, 0x95d0, 0x047e, 0x2009, 0x0005, 0x2011,
+	0x0020, 0x1078, 0x3034, 0x047f, 0x0040, 0x2ff9, 0x8420, 0x00f0,
+	0x2fec, 0x157f, 0x0078, 0x2a0c, 0x2200, 0x0079, 0x2fff, 0x3002,
+	0x3004, 0x3004, 0x1078, 0x29b2, 0x2009, 0x0012, 0x7064, 0xa086,
+	0x0002, 0x0040, 0x300d, 0x2009, 0x000e, 0x6818, 0xd0fc, 0x0040,
+	0x3012, 0x691a, 0x7067, 0x0000, 0x70d4, 0xc0dd, 0x70d6, 0x0078,
+	0x435d, 0x2200, 0x0079, 0x301c, 0x3021, 0x3004, 0x301f, 0x1078,
+	0x29b2, 0x1078, 0x45d6, 0x7000, 0xa086, 0x0002, 0x00c0, 0x3dc7,
+	0x1078, 0x3e36, 0x6008, 0xa084, 0xfbef, 0x600a, 0x1078, 0x3db8,
+	0x0040, 0x3dc7, 0x0078, 0x2a0c, 0x2404, 0xa005, 0x0040, 0x306d,
+	0x2068, 0x2d04, 0x007e, 0x6814, 0xa706, 0x0040, 0x3043, 0x2d20,
+	0x007f, 0x0078, 0x3035, 0x007f, 0x2022, 0x691a, 0x6817, 0x0000,
 	0x682b, 0x0000, 0x68b4, 0xa084, 0x5f00, 0x681e, 0x6820, 0xa084,
-	0x00ff, 0xc09d, 0x6822, 0x1078, 0x202c, 0x007f, 0x0078, 0x2eff,
-	0x047f, 0x2023, 0x0000, 0x007c, 0xa282, 0x0003, 0x0050, 0x2f22,
-	0x1078, 0x296b, 0x2300, 0x0079, 0x2f25, 0x2f28, 0x2fb3, 0x2fd0,
-	0xa282, 0x0002, 0x0040, 0x2f2e, 0x1078, 0x296b, 0x7064, 0x7067,
-	0x0000, 0x7083, 0x0000, 0x0079, 0x2f35, 0x2f3d, 0x2f3d, 0x2f3f,
-	0x2f7f, 0x3e0c, 0x2f3d, 0x2f7f, 0x2f3d, 0x1078, 0x296b, 0x7774,
-	0x1078, 0x40f8, 0x7774, 0xa7bc, 0x8f00, 0x1078, 0x41fe, 0x6018,
-	0xa005, 0x0040, 0x2f76, 0xd7fc, 0x00c0, 0x2f52, 0x2021, 0x94c0,
-	0x0078, 0x2f54, 0x2021, 0x95d0, 0x2009, 0x0005, 0x2011, 0x0010,
-	0x1078, 0x2feb, 0x0040, 0x2f76, 0x157e, 0x20a9, 0x0101, 0xd7fc,
-	0x00c0, 0x2f66, 0x2021, 0x93c0, 0x0078, 0x2f68, 0x2021, 0x94d0,
-	0x047e, 0x2009, 0x0005, 0x2011, 0x0010, 0x1078, 0x2feb, 0x047f,
-	0x0040, 0x2f75, 0x8420, 0x00f0, 0x2f68, 0x157f, 0x8738, 0xa784,
-	0x001f, 0x00c0, 0x2f45, 0x0078, 0x29c5, 0x0078, 0x29c5, 0x7774,
-	0x1078, 0x41fe, 0x6018, 0xa005, 0x0040, 0x2fb1, 0xd7fc, 0x00c0,
-	0x2f8d, 0x2021, 0x94c0, 0x0078, 0x2f8f, 0x2021, 0x95d0, 0x2009,
-	0x0005, 0x2011, 0x0020, 0x1078, 0x2feb, 0x0040, 0x2fb1, 0x157e,
-	0x20a9, 0x0101, 0xd7fc, 0x00c0, 0x2fa1, 0x2021, 0x93c0, 0x0078,
-	0x2fa3, 0x2021, 0x94d0, 0x047e, 0x2009, 0x0005, 0x2011, 0x0020,
-	0x1078, 0x2feb, 0x047f, 0x0040, 0x2fb0, 0x8420, 0x00f0, 0x2fa3,
-	0x157f, 0x0078, 0x29c5, 0x2200, 0x0079, 0x2fb6, 0x2fb9, 0x2fbb,
-	0x2fbb, 0x1078, 0x296b, 0x2009, 0x0012, 0x7064, 0xa086, 0x0002,
-	0x0040, 0x2fc4, 0x2009, 0x000e, 0x6818, 0xd0fc, 0x0040, 0x2fc9,
-	0x691a, 0x7067, 0x0000, 0x70d4, 0xc0dd, 0x70d6, 0x0078, 0x430d,
-	0x2200, 0x0079, 0x2fd3, 0x2fd8, 0x2fbb, 0x2fd6, 0x1078, 0x296b,
-	0x1078, 0x4586, 0x7000, 0xa086, 0x0002, 0x00c0, 0x3d7e, 0x1078,
-	0x3ded, 0x6008, 0xa084, 0xfbef, 0x600a, 0x1078, 0x3d6f, 0x0040,
-	0x3d7e, 0x0078, 0x29c5, 0x2404, 0xa005, 0x0040, 0x3024, 0x2068,
-	0x2d04, 0x007e, 0x6814, 0xa706, 0x0040, 0x2ffa, 0x2d20, 0x007f,
-	0x0078, 0x2fec, 0x007f, 0x2022, 0x691a, 0x6817, 0x0000, 0x682b,
-	0x0000, 0x68b4, 0xa084, 0x5f00, 0x681e, 0x6820, 0xa084, 0x00ff,
-	0xa205, 0x6822, 0x1078, 0x202c, 0x2021, 0x4e02, 0x241c, 0x8319,
-	0x2322, 0x6010, 0x8001, 0x6012, 0x00c0, 0x301b, 0x2021, 0x4e04,
-	0x2404, 0xc0a5, 0x2022, 0x6008, 0xa084, 0xf9ef, 0x600a, 0x1078,
-	0x2adb, 0x1078, 0x3ded, 0x007c, 0xa085, 0x0001, 0x0078, 0x3023,
-	0x2300, 0x0079, 0x302b, 0x3030, 0x302e, 0x30b0, 0x1078, 0x296b,
-	0x78e4, 0xa005, 0x00d0, 0x3066, 0x3208, 0x007e, 0x2001, 0x4e04,
-	0x2004, 0xd0ec, 0x007f, 0x0040, 0x3041, 0xa18c, 0x0300, 0x0078,
-	0x3043, 0xa18c, 0x0400, 0x0040, 0x3049, 0x0018, 0x29c1, 0x0078,
-	0x304b, 0x0028, 0x29c1, 0x2008, 0xa084, 0x0030, 0x00c0, 0x3052,
-	0x0078, 0x3770, 0x78ec, 0xa084, 0x0003, 0x0040, 0x3050, 0x2100,
-	0xa084, 0x0007, 0x0079, 0x305c, 0x3090, 0x309a, 0x3085, 0x3064,
-	0x4355, 0x4355, 0x3064, 0x30a5, 0x1078, 0x296b, 0x7000, 0xa086,
-	0x0004, 0x00c0, 0x3080, 0x7064, 0xa086, 0x0002, 0x00c0, 0x3076,
-	0x2011, 0x0002, 0x2019, 0x0000, 0x0078, 0x2f1c, 0x7064, 0xa086,
-	0x0006, 0x0040, 0x3070, 0x7064, 0xa086, 0x0004, 0x0040, 0x3070,
-	0x79e4, 0x2001, 0x0003, 0x0078, 0x33fa, 0x6818, 0xd0fc, 0x0040,
-	0x308b, 0x681b, 0x001d, 0x1078, 0x40c8, 0x781b, 0x0064, 0x007c,
-	0x6818, 0xd0fc, 0x0040, 0x3096, 0x681b, 0x001d, 0x1078, 0x40c8,
-	0x0078, 0x4331, 0x6818, 0xd0fc, 0x0040, 0x30a0, 0x681b, 0x001d,
-	0x1078, 0x40c8, 0x781b, 0x00f8, 0x007c, 0x6818, 0xd0fc, 0x0040,
-	0x30ab, 0x681b, 0x001d, 0x1078, 0x40c8, 0x781b, 0x00c8, 0x007c,
-	0xa584, 0x000f, 0x00c0, 0x30cf, 0x1078, 0x295e, 0x7000, 0x0079,
-	0x30b9, 0x29c5, 0x30c1, 0x30c3, 0x3d7e, 0x3d7e, 0x3d7e, 0x30c1,
-	0x30c1, 0x1078, 0x296b, 0x1078, 0x3ded, 0x6008, 0xa084, 0xfbef,
-	0x600a, 0x1078, 0x3d6f, 0x0040, 0x3d7e, 0x0078, 0x29c5, 0x78e4,
-	0xa005, 0x00d0, 0x3066, 0x3208, 0x007e, 0x2001, 0x4e04, 0x2004,
-	0xd0ec, 0x007f, 0x0040, 0x30e0, 0xa18c, 0x0300, 0x0078, 0x30e2,
-	0xa18c, 0x0400, 0x0040, 0x30e8, 0x0018, 0x3066, 0x0078, 0x30ea,
-	0x0028, 0x3066, 0x2008, 0xa084, 0x0030, 0x00c0, 0x30f2, 0x781b,
-	0x005b, 0x007c, 0x78ec, 0xa084, 0x0003, 0x0040, 0x30ef, 0x2100,
-	0xa184, 0x0007, 0x0079, 0x30fc, 0x310b, 0x310f, 0x3106, 0x3104,
-	0x4355, 0x4355, 0x3104, 0x434f, 0x1078, 0x296b, 0x1078, 0x40d0,
-	0x781b, 0x0064, 0x007c, 0x1078, 0x40d0, 0x0078, 0x4331, 0x1078,
-	0x40d0, 0x781b, 0x00f8, 0x007c, 0x1078, 0x40d0, 0x781b, 0x00c8,
-	0x007c, 0x2300, 0x0079, 0x311c, 0x3121, 0x311f, 0x3123, 0x1078,
-	0x296b, 0x0078, 0x395f, 0x681b, 0x0016, 0x78a3, 0x0000, 0x79e4,
-	0xa184, 0x0030, 0x0040, 0x395f, 0x78ec, 0xa084, 0x0003, 0x0040,
-	0x395f, 0xa184, 0x0100, 0x0040, 0x3127, 0xa184, 0x0007, 0x0079,
-	0x3139, 0x3141, 0x310f, 0x3085, 0x430d, 0x4355, 0x4355, 0x430d,
-	0x434f, 0x1078, 0x4319, 0x007c, 0xa282, 0x0005, 0x0050, 0x314a,
-	0x1078, 0x296b, 0x2300, 0x0079, 0x314d, 0x3150, 0x3380, 0x338b,
-	0x2200, 0x0079, 0x3153, 0x316d, 0x315a, 0x316d, 0x3158, 0x3363,
-	0x1078, 0x296b, 0x789b, 0x0018, 0x78a8, 0xa084, 0x00ff, 0xa082,
-	0x0020, 0x0048, 0x40b7, 0xa08a, 0x0004, 0x00c8, 0x40b7, 0x0079,
-	0x3169, 0x40b7, 0x40b7, 0x40b7, 0x4061, 0x789b, 0x0018, 0x79a8,
-	0xa184, 0x0080, 0x0040, 0x317e, 0x0078, 0x40b7, 0x7000, 0xa005,
-	0x00c0, 0x3174, 0x2011, 0x0004, 0x0078, 0x3b4a, 0xa184, 0x00ff,
-	0xa08a, 0x0010, 0x00c8, 0x40b7, 0x0079, 0x3186, 0x3198, 0x3196,
-	0x31ad, 0x31b1, 0x3284, 0x40b7, 0x40b7, 0x3286, 0x40b7, 0x40b7,
-	0x335f, 0x335f, 0x40b7, 0x40b7, 0x40b7, 0x3361, 0x1078, 0x296b,
-	0xd6e4, 0x0040, 0x31a3, 0x2001, 0x0300, 0x8000, 0x8000, 0x783a,
-	0x781b, 0x00c3, 0x007c, 0x6818, 0xd0fc, 0x0040, 0x31ab, 0x681b,
-	0x001d, 0x0078, 0x319b, 0x0078, 0x430d, 0x681b, 0x001d, 0x0078,
-	0x40c1, 0x6920, 0x6922, 0xa684, 0x1800, 0x00c0, 0x3216, 0x6820,
-	0xd084, 0x00c0, 0x321c, 0x6818, 0xa086, 0x0008, 0x00c0, 0x31c2,
-	0x681b, 0x0000, 0xd6d4, 0x0040, 0x3281, 0xd6bc, 0x0040, 0x3202,
-	0x7087, 0x0000, 0x6818, 0xa084, 0x003f, 0xa08a, 0x000d, 0x0050,
-	0x3202, 0xa08a, 0x000c, 0x7186, 0x2001, 0x000c, 0x800c, 0x718a,
-	0x789b, 0x0061, 0x78aa, 0x157e, 0x137e, 0x147e, 0x017e, 0x3208,
-	0xa18c, 0x0300, 0x0040, 0x31f4, 0x007e, 0x2001, 0x4e04, 0x2004,
-	0xd0ec, 0x007f, 0x0040, 0x31f0, 0x20a1, 0x012b, 0x0078, 0x31f6,
-	0x20a1, 0x022b, 0x0078, 0x31f6, 0x20a1, 0x012b, 0x017f, 0x789b,
-	0x0000, 0x8000, 0x80ac, 0xad80, 0x000b, 0x2098, 0x53a6, 0x147f,
-	0x137f, 0x157f, 0x6038, 0xa005, 0x00c0, 0x3211, 0x681c, 0xa084,
-	0x000e, 0x0040, 0x40c1, 0x1078, 0x40d7, 0x782b, 0x3008, 0x0078,
-	0x3213, 0x8001, 0x603a, 0x781b, 0x0067, 0x007c, 0xd6e4, 0x0040,
-	0x321c, 0x781b, 0x0079, 0x007c, 0xa684, 0x0060, 0x0040, 0x327e,
-	0xd6dc, 0x0040, 0x327e, 0xd6fc, 0x00c0, 0x3228, 0x0078, 0x323f,
-	0xc6fc, 0x7e5a, 0x6eb6, 0x7adc, 0x79d8, 0x78d0, 0x801b, 0x00c8,
-	0x3232, 0x8000, 0xa084, 0x003f, 0xa108, 0xa291, 0x0000, 0x6b98,
-	0x2100, 0xa302, 0x68b2, 0x6b94, 0x2200, 0xa303, 0x68ae, 0xd6f4,
-	0x0040, 0x3245, 0xc6f4, 0x7e5a, 0x6eb6, 0x7000, 0xa086, 0x0003,
-	0x00c0, 0x3253, 0x007e, 0x1078, 0x4586, 0x1078, 0x48bd, 0x007f,
-	0x781b, 0x0076, 0x007c, 0xa006, 0x1078, 0x49c3, 0x6ab0, 0x69ac,
-	0x6c98, 0x6b94, 0x2200, 0xa105, 0x0040, 0x3262, 0x2200, 0xa422,
-	0x2100, 0xa31b, 0x6caa, 0x7cd2, 0x7cda, 0x6ba6, 0x7bd6, 0x7bde,
-	0x2300, 0xa405, 0x00c0, 0x3272, 0xc6f5, 0x7e5a, 0x6eb6, 0x781b,
-	0x0076, 0x007c, 0x781b, 0x0076, 0x2200, 0xa115, 0x00c0, 0x327b,
-	0x1078, 0x48bd, 0x007c, 0x1078, 0x48f5, 0x007c, 0x781b, 0x0079,
-	0x007c, 0x781b, 0x0067, 0x007c, 0x1078, 0x296b, 0x0078, 0x32d2,
-	0x6920, 0xd1c4, 0x0040, 0x329b, 0xc1c4, 0x6922, 0x0c7e, 0x7058,
-	0x2060, 0x6000, 0xc0e4, 0x6002, 0x6004, 0xa084, 0xfff5, 0x6006,
-	0x0c7f, 0x0078, 0x32c6, 0xd1cc, 0x0040, 0x32c6, 0xc1cc, 0x6922,
-	0x0c7e, 0x7058, 0x2060, 0x6000, 0xc0ec, 0x6002, 0x6004, 0xc0a4,
-	0x6006, 0x2008, 0x2c48, 0x0c7f, 0xd19c, 0x0040, 0x32c6, 0x1078,
-	0x41fa, 0x1078, 0x3ef5, 0x88ff, 0x0040, 0x32c6, 0x789b, 0x0060,
-	0x2800, 0x78aa, 0x7e58, 0xc695, 0x7e5a, 0xd6d4, 0x00c0, 0x32c3,
-	0x781b, 0x0064, 0x007c, 0x781b, 0x0078, 0x007c, 0x7e58, 0xd6d4,
-	0x00c0, 0x32cd, 0x781b, 0x0067, 0x007c, 0x781b, 0x0079, 0x007c,
-	0x0078, 0x40bc, 0x2019, 0x0000, 0x7990, 0xa18c, 0x0007, 0x00c0,
-	0x32e0, 0x6820, 0xa084, 0x0100, 0x0040, 0x32d0, 0x2009, 0x0008,
-	0x789b, 0x0010, 0x78a8, 0xa094, 0x00ff, 0xa286, 0x0001, 0x00c0,
-	0x32fc, 0x2300, 0x7ca8, 0xa400, 0x2018, 0xa102, 0x0040, 0x32f4,
-	0x0048, 0x32f4, 0x0078, 0x32f6, 0x0078, 0x3288, 0x24a8, 0x7aa8,
-	0x00f0, 0x32f6, 0x0078, 0x32e2, 0xa284, 0x00f0, 0xa086, 0x0020,
-	0x00c0, 0x3350, 0x8318, 0x8318, 0x2300, 0xa102, 0x0040, 0x330c,
-	0x0048, 0x330c, 0x0078, 0x334d, 0xa286, 0x0023, 0x0040, 0x32d0,
-	0x681c, 0xa084, 0xfff1, 0x681e, 0x7e58, 0xa684, 0xfff1, 0xc0a5,
-	0x2030, 0x7e5a, 0x6008, 0xc0a5, 0x600a, 0x0c7e, 0x7058, 0x2060,
-	0x6004, 0x2008, 0x2c48, 0x0c7f, 0xd1a4, 0x0040, 0x332d, 0x1078,
-	0x41fa, 0x1078, 0x4011, 0x0078, 0x333b, 0x0c7e, 0x7058, 0x2060,
-	0x6004, 0x2008, 0x2c48, 0x0c7f, 0xd19c, 0x0040, 0x32c6, 0x1078,
-	0x41fa, 0x1078, 0x3ef5, 0x88ff, 0x0040, 0x32c6, 0x789b, 0x0060,
-	0x2800, 0x78aa, 0xc695, 0x7e5a, 0xd6d4, 0x00c0, 0x334a, 0x781b,
-	0x0064, 0x007c, 0x781b, 0x0078, 0x007c, 0x7aa8, 0x0078, 0x32e2,
-	0x8318, 0x2300, 0xa102, 0x0040, 0x3359, 0x0048, 0x3359, 0x0078,
-	0x32e2, 0xa284, 0x0080, 0x00c0, 0x40c1, 0x0078, 0x40bc, 0x0078,
-	0x40c1, 0x0078, 0x40b7, 0x7058, 0xa04d, 0x789b, 0x0018, 0x78a8,
-	0xa084, 0x00ff, 0xa08e, 0x0001, 0x0040, 0x3370, 0x1078, 0x296b,
-	0x7aa8, 0xa294, 0x00ff, 0x78a8, 0xa084, 0x00ff, 0xa08a, 0x0004,
-	0x00c8, 0x40b7, 0x0079, 0x337c, 0x40b7, 0x3e46, 0x40b7, 0x3fb9,
-	0xa282, 0x0000, 0x00c0, 0x3386, 0x1078, 0x296b, 0x1078, 0x40c8,
-	0x781b, 0x0078, 0x007c, 0xa282, 0x0003, 0x00c0, 0x3391, 0x1078,
-	0x296b, 0xd4fc, 0x00c0, 0x33b1, 0x7064, 0xa005, 0x0040, 0x339a,
-	0x1078, 0x296b, 0x6f14, 0x7776, 0xa7bc, 0x8f00, 0x1078, 0x41fe,
-	0x6008, 0xa085, 0x0021, 0x600a, 0x8738, 0xa784, 0x001f, 0x00c0,
-	0x339e, 0x1078, 0x40cc, 0x7067, 0x0002, 0x701f, 0x0009, 0x0078,
-	0x33b3, 0x1078, 0x40db, 0x781b, 0x0078, 0x007c, 0xa282, 0x0004,
-	0x0050, 0x33bc, 0x1078, 0x296b, 0x2300, 0x0079, 0x33bf, 0x33c2,
-	0x3582, 0x35c5, 0xa286, 0x0003, 0x0040, 0x33fa, 0x7200, 0x7cd8,
-	0x7ddc, 0x7fd0, 0x71d4, 0xd1bc, 0x00c0, 0x33f2, 0xd1b4, 0x0040,
-	0x33f2, 0x7868, 0xa084, 0x00ff, 0x00c0, 0x33f2, 0xa282, 0x0002,
-	0x00c8, 0x33f2, 0x0d7e, 0x783b, 0x8300, 0x781b, 0x004c, 0x70bc,
-	0xa06d, 0x68b4, 0x785a, 0x6894, 0x78d6, 0x78de, 0x6898, 0x78d2,
-	0x78da, 0xc1b4, 0x71d6, 0x7003, 0x0030, 0x0d7f, 0x2001, 0x0000,
-	0x0078, 0x33fe, 0x783b, 0x1300, 0x781b, 0x004a, 0x2001, 0x0000,
-	0x0078, 0x33fe, 0x7200, 0x7cd8, 0x7ddc, 0x7fd0, 0x704a, 0x68a0,
-	0xd0ec, 0x0040, 0x3406, 0x6008, 0xc08d, 0x600a, 0xa284, 0x000f,
-	0x0079, 0x340a, 0x3562, 0x3417, 0x3414, 0x36c8, 0x3754, 0x29c5,
-	0x3412, 0x3412, 0x1078, 0x296b, 0x6008, 0xc0d4, 0x600a, 0xd6e4,
-	0x0040, 0x341f, 0x7048, 0xa086, 0x0014, 0x00c0, 0x343f, 0x1078,
-	0x4586, 0x2009, 0x0000, 0x6818, 0xd0fc, 0x0040, 0x3428, 0x7048,
-	0xa086, 0x0014, 0x0040, 0x3439, 0x6818, 0xa086, 0x0008, 0x00c0,
-	0x351a, 0x7858, 0xd09c, 0x0040, 0x351a, 0x6820, 0xd0ac, 0x0040,
-	0x351a, 0x681b, 0x0014, 0x2009, 0x0002, 0x0078, 0x347e, 0x7868,
-	0xa08c, 0x00ff, 0x0040, 0x347e, 0xa186, 0x0008, 0x00c0, 0x3455,
-	0x6008, 0xc0a4, 0x600a, 0x1078, 0x3d6f, 0x0040, 0x347e, 0x1078,
-	0x3ded, 0x1078, 0x4586, 0x0078, 0x3466, 0xa186, 0x0028, 0x00c0,
-	0x347e, 0x6018, 0xa005, 0x0040, 0x3448, 0x8001, 0x0040, 0x3448,
-	0x8001, 0x0040, 0x3448, 0x601e, 0x0078, 0x3448, 0x6820, 0xd084,
-	0x0040, 0x29c5, 0xc084, 0x6822, 0x1078, 0x2acc, 0x705c, 0x0c7e,
-	0x2060, 0x6800, 0x6002, 0x0c7f, 0x6004, 0x6802, 0xa005, 0x2d00,
-	0x00c0, 0x347b, 0x6002, 0x6006, 0x0078, 0x29c5, 0x017e, 0x81ff,
-	0x00c0, 0x34c8, 0x7000, 0xa086, 0x0030, 0x0040, 0x34c8, 0x71d4,
-	0xd1bc, 0x00c0, 0x34c8, 0xd1b4, 0x00c0, 0x34af, 0x7060, 0xa005,
-	0x00c0, 0x34c8, 0x70a4, 0xa086, 0x0001, 0x0040, 0x34c8, 0x7003,
-	0x0000, 0x047e, 0x057e, 0x077e, 0x067e, 0x0c7e, 0x0d7e, 0x1078,
-	0x29ee, 0x0d7f, 0x0c7f, 0x067f, 0x077f, 0x057f, 0x047f, 0x71d4,
-	0xd1b4, 0x00c0, 0x34c8, 0x7003, 0x0040, 0x0078, 0x34c8, 0x1078,
-	0x4360, 0x00c0, 0x34c8, 0x781b, 0x005b, 0x0d7e, 0x70bc, 0xa06d,
-	0x68b4, 0x785a, 0x6894, 0x78d6, 0x78de, 0x6898, 0x78d2, 0x78da,
-	0xc1b4, 0x71d6, 0x7003, 0x0030, 0x7808, 0xc08d, 0x780a, 0x0d7f,
-	0x1078, 0x35ff, 0x017f, 0x81ff, 0x0040, 0x351a, 0xa684, 0xdf00,
-	0x681e, 0x682b, 0x0000, 0x6f14, 0xa186, 0x0002, 0x00c0, 0x351b,
-	0x6818, 0xa086, 0x0014, 0x00c0, 0x34e4, 0x2008, 0xd6e4, 0x0040,
-	0x34e4, 0x7868, 0xa08c, 0x00ff, 0x1078, 0x2aba, 0x1078, 0x2adb,
-	0x6820, 0xd0dc, 0x00c0, 0x351b, 0x8717, 0xa294, 0x000f, 0x8213,
-	0x8213, 0x8213, 0xb284, 0x0300, 0x0040, 0x34fa, 0xa290, 0x52c0,
-	0x0078, 0x34fc, 0xa290, 0x5340, 0xa290, 0x0000, 0x221c, 0xd3c4,
-	0x00c0, 0x3504, 0x0078, 0x350a, 0x8210, 0x2204, 0xa085, 0x0018,
-	0x2012, 0x8211, 0xd3d4, 0x0040, 0x3515, 0x68a0, 0xd0c4, 0x00c0,
-	0x3515, 0x1078, 0x3679, 0x0078, 0x29c5, 0x6008, 0xc08d, 0x600a,
-	0x0078, 0x351b, 0x692a, 0x6916, 0x6818, 0xd0fc, 0x0040, 0x3522,
-	0x7048, 0x681a, 0xa68c, 0xdf00, 0x691e, 0x6410, 0x84ff, 0x0040,
-	0x3537, 0x2009, 0x4e02, 0x2104, 0x8001, 0x200a, 0x8421, 0x6412,
-	0x00c0, 0x3537, 0x2021, 0x4e04, 0x2404, 0xc0a5, 0x2022, 0x6018,
-	0xa005, 0x0040, 0x353f, 0x8001, 0x601a, 0x00c0, 0x3542, 0x6008,
-	0xc0a4, 0x600a, 0x6820, 0xd084, 0x00c0, 0x354e, 0x6800, 0xa005,
-	0x00c0, 0x354b, 0x6002, 0x6006, 0x0078, 0x3552, 0x705c, 0x2060,
-	0x6800, 0x6002, 0x2061, 0x4e00, 0x6887, 0x0103, 0x2d08, 0x206b,
-	0x0000, 0x6068, 0xa005, 0x616a, 0x0040, 0x3561, 0x2d02, 0x0078,
-	0x3562, 0x616e, 0x7200, 0xa286, 0x0030, 0x0040, 0x3572, 0xa286,
-	0x0040, 0x00c0, 0x29c5, 0x7003, 0x0002, 0x704c, 0x2068, 0x68c4,
-	0x2060, 0x007c, 0x7003, 0x0002, 0x70bc, 0xa06d, 0x68bc, 0x7042,
-	0x70b8, 0xa065, 0x68c0, 0x705a, 0x2d00, 0x704e, 0xad80, 0x0009,
-	0x7046, 0x007c, 0xa282, 0x0004, 0x0048, 0x3588, 0x1078, 0x296b,
-	0x2200, 0x0079, 0x358b, 0x358f, 0x35a0, 0x35ad, 0x35a0, 0xa586,
-	0x1300, 0x0040, 0x35a0, 0xa586, 0x8300, 0x00c0, 0x3586, 0x7003,
-	0x0000, 0x6018, 0x8001, 0x601a, 0x6008, 0xa084, 0xfbef, 0x600a,
-	0x7000, 0xa086, 0x0005, 0x0040, 0x35aa, 0x1078, 0x40c8, 0x781b,
-	0x0078, 0x007c, 0x781b, 0x0079, 0x007c, 0x7890, 0x8007, 0x8001,
-	0xa084, 0x0007, 0xa080, 0x0018, 0x789a, 0x79a8, 0xa18c, 0x00ff,
-	0xa186, 0x0003, 0x0040, 0x35c2, 0xa186, 0x0000, 0x0040, 0x35c2,
-	0x0078, 0x40b7, 0x781b, 0x0079, 0x007c, 0x6820, 0xc095, 0x6822,
-	0x82ff, 0x00c0, 0x35cf, 0x1078, 0x40c8, 0x0078, 0x35d6, 0x8211,
-	0x0040, 0x35d4, 0x1078, 0x296b, 0x1078, 0x40db, 0x781b, 0x0078,
-	0x007c, 0x1078, 0x4383, 0x7830, 0xa084, 0x00c0, 0x00c0, 0x35fc,
-	0x017e, 0x3208, 0x007e, 0x2001, 0x4e04, 0x2004, 0xd0ec, 0x007f,
-	0x0040, 0x35ee, 0xa18c, 0x0300, 0x0078, 0x35f0, 0xa18c, 0x0400,
-	0x017f, 0x0040, 0x35f7, 0x0018, 0x35fc, 0x0078, 0x35f9, 0x0028,
-	0x35fc, 0x791a, 0xa006, 0x007c, 0xa085, 0x0001, 0x007c, 0xa684,
-	0x0060, 0x00c0, 0x3609, 0x682f, 0x0000, 0x6833, 0x0000, 0x0078,
-	0x3678, 0xd6dc, 0x00c0, 0x3621, 0x68b4, 0xd0dc, 0x00c0, 0x3621,
-	0x6998, 0x6a94, 0x692e, 0x6a32, 0x7048, 0xa005, 0x00c0, 0x361e,
-	0x2200, 0xa105, 0x0040, 0x4586, 0x704b, 0x0015, 0x0078, 0x4586,
-	0x007c, 0xd6ac, 0x0040, 0x3647, 0xd6f4, 0x0040, 0x362d, 0x682f,
-	0x0000, 0x6833, 0x0000, 0x0078, 0x4586, 0x68b4, 0xa084, 0x4000,
-	0xa635, 0xd6f4, 0x00c0, 0x3627, 0x7048, 0xa005, 0x00c0, 0x363a,
-	0x704b, 0x0015, 0xd6dc, 0x00c0, 0x3643, 0x68b4, 0xd0dc, 0x0040,
-	0x3643, 0x6ca8, 0x6da4, 0x6c2e, 0x6d32, 0x0078, 0x4586, 0xd6f4,
-	0x0040, 0x3650, 0x682f, 0x0000, 0x6833, 0x0000, 0x0078, 0x4586,
-	0x68b4, 0xa084, 0x4800, 0xa635, 0xd6f4, 0x00c0, 0x364a, 0x7048,
-	0xa005, 0x00c0, 0x365d, 0x704b, 0x0015, 0x2408, 0x2510, 0x2700,
-	0x80fb, 0x00c8, 0x3664, 0x8000, 0xa084, 0x003f, 0xa108, 0xa291,
-	0x0000, 0x692e, 0x6a32, 0x2100, 0xa205, 0x00c0, 0x3671, 0x0078,
-	0x4586, 0x7000, 0xa086, 0x0006, 0x0040, 0x3678, 0x0078, 0x4586,
-	0x007c, 0x6946, 0x6008, 0xc0cd, 0xd3cc, 0x0040, 0x3680, 0xc08d,
-	0x600a, 0x6818, 0x683a, 0x681b, 0x0006, 0x688f, 0x0000, 0x6893,
-	0x0000, 0x6a30, 0x692c, 0x6a3e, 0x6942, 0x682f, 0x0003, 0x6833,
-	0x0000, 0x6837, 0x0020, 0x6897, 0x0000, 0x689b, 0x0020, 0x7000,
-	0x0079, 0x369a, 0x29c5, 0x36ac, 0x36a4, 0x36a2, 0x36a2, 0x36a2,
-	0x36a2, 0x36a2, 0x1078, 0x296b, 0x6820, 0xd084, 0x00c0, 0x36ac,
-	0x1078, 0x3dd0, 0x0078, 0x36b2, 0x705c, 0x2c50, 0x2060, 0x6800,
-	0x6002, 0x2a60, 0x3208, 0xa18c, 0x0300, 0x0040, 0x36bb, 0x2021,
-	0x4e58, 0x0078, 0x36bd, 0x2021, 0x4e98, 0x2404, 0xa005, 0x0040,
-	0x36c4, 0x2020, 0x0078, 0x36bd, 0x2d22, 0x206b, 0x0000, 0x007c,
-	0x1078, 0x3dd7, 0x1078, 0x3ded, 0x6008, 0xc0cc, 0x600a, 0x682b,
-	0x0000, 0x789b, 0x000e, 0x6f14, 0x6938, 0x691a, 0x6944, 0x6916,
-	0x3208, 0xa18c, 0x0300, 0x0040, 0x36e1, 0x2009, 0x0000, 0x0078,
-	0x36e3, 0x2009, 0x0001, 0x1078, 0x49f8, 0xd6dc, 0x0040, 0x36eb,
-	0x691c, 0xc1ed, 0x691e, 0x6818, 0xd0fc, 0x0040, 0x36fa, 0x7868,
-	0xa08c, 0x00ff, 0x0040, 0x36f8, 0x681b, 0x001e, 0x0078, 0x36fa,
-	0x681b, 0x0000, 0xb284, 0x0300, 0x00c0, 0x3702, 0x2021, 0x4e98,
-	0x0078, 0x3704, 0x2021, 0x4e58, 0x6800, 0x2022, 0x6a3c, 0x6940,
-	0x6a32, 0x692e, 0x68c0, 0x2060, 0x6000, 0xd0a4, 0x0040, 0x3744,
-	0x2041, 0x0021, 0x2049, 0x0005, 0x2051, 0x0020, 0x0d7e, 0x0f7e,
-	0x157e, 0x147e, 0x2079, 0x4e00, 0x1078, 0x1dff, 0x147f, 0x157f,
-	0x0f7f, 0x70cc, 0x2010, 0x2009, 0x0101, 0x027e, 0x2204, 0xa06d,
-	0x0040, 0x3734, 0x6814, 0xa706, 0x0040, 0x3731, 0x6800, 0x0078,
-	0x3727, 0x6820, 0xc0d5, 0x6822, 0x027f, 0x8210, 0x8109, 0x00c0,
-	0x3725, 0x0d7f, 0x7067, 0x0003, 0x707f, 0x0000, 0x7776, 0x7083,
-	0x000f, 0x71d4, 0xc1dc, 0x71d6, 0x6818, 0xa086, 0x0002, 0x00c0,
-	0x3750, 0x6817, 0x0000, 0x682b, 0x0000, 0x681c, 0xc0ec, 0x681e,
-	0x1078, 0x202c, 0x0078, 0x29c5, 0x7cd8, 0x7ddc, 0x7fd0, 0x1078,
-	0x35ff, 0x682b, 0x0000, 0x789b, 0x000e, 0x6f14, 0x1078, 0x4387,
-	0xa08c, 0x00ff, 0x6916, 0x6818, 0xd0fc, 0x0040, 0x3769, 0x7048,
-	0x681a, 0xa68c, 0xdf00, 0x691e, 0x7067, 0x0000, 0x0078, 0x29c5,
-	0x7000, 0xa005, 0x00c0, 0x3776, 0x0078, 0x29c5, 0xa006, 0x1078,
-	0x4586, 0x6920, 0xd1ac, 0x00c0, 0x377f, 0x681b, 0x0014, 0xa68c,
-	0xdf00, 0x691e, 0x682b, 0x0000, 0x6820, 0xa084, 0x00ff, 0x6822,
-	0x7000, 0x0079, 0x378b, 0x29c5, 0x3795, 0x3795, 0x3798, 0x3798,
-	0x3798, 0x3793, 0x3793, 0x1078, 0x296b, 0x6818, 0x0078, 0x33fa,
-	0x6008, 0xc0a4, 0x600a, 0x6817, 0x0000, 0x0078, 0x3d95, 0x2300,
-	0x0079, 0x37a2, 0x37a5, 0x37a7, 0x3817, 0x1078, 0x296b, 0xd6fc,
-	0x00c0, 0x37fe, 0x7000, 0xa00d, 0x0079, 0x37ae, 0x29c5, 0x37b8,
-	0x37b8, 0x37e8, 0x37b8, 0x37fb, 0x37b6, 0x37b6, 0x1078, 0x296b,
-	0xa684, 0x0060, 0x0040, 0x37e8, 0xa086, 0x0060, 0x00c0, 0x37e5,
-	0xc6ac, 0xc6f4, 0xc6ed, 0x7e5a, 0x6eb6, 0x681c, 0xc0ac, 0x681e,
-	0xa186, 0x0002, 0x0040, 0x37d7, 0x1078, 0x4586, 0x69ac, 0x68b0,
-	0xa115, 0x0040, 0x37d7, 0x1078, 0x48f5, 0x0078, 0x37d9, 0x1078,
-	0x48bd, 0x781b, 0x0079, 0x71d4, 0xd1b4, 0x00c0, 0x29c1, 0x70a4,
-	0xa086, 0x0001, 0x00c0, 0x2a0b, 0x007c, 0xd6ec, 0x0040, 0x37c2,
-	0x6818, 0xd0fc, 0x0040, 0x37fb, 0xd6f4, 0x00c0, 0x37f5, 0x681b,
-	0x0015, 0x781b, 0x0079, 0x0078, 0x29c1, 0x681b, 0x0007, 0x682f,
-	0x0000, 0x6833, 0x0000, 0x1078, 0x4319, 0x007c, 0xc6fc, 0x7e5a,
-	0x7adc, 0x79d8, 0x78d0, 0x801b, 0x00c8, 0x3807, 0x8000, 0xa084,
-	0x003f, 0xa108, 0xa291, 0x0000, 0x6b98, 0x2100, 0xa302, 0x68b2,
-	0x6b94, 0x2200, 0xa303, 0x68ae, 0x781b, 0x0079, 0x007c, 0x1078,
-	0x296b, 0x2300, 0x0079, 0x381c, 0x3821, 0x3846, 0x38a6, 0x1078,
-	0x296b, 0x7000, 0x0079, 0x3824, 0x382c, 0x382e, 0x3837, 0x382c,
-	0x382c, 0x382c, 0x382c, 0x382c, 0x1078, 0x296b, 0x69ac, 0x68b0,
-	0xa115, 0x0040, 0x3837, 0x1078, 0x48f5, 0x0078, 0x3839, 0x1078,
-	0x48bd, 0x681c, 0xc0b4, 0x681e, 0x70d4, 0xd0b4, 0x00c0, 0x29c1,
-	0x70a4, 0xa086, 0x0001, 0x00c0, 0x2a0b, 0x007c, 0xd6fc, 0x00c0,
-	0x3896, 0x7000, 0xa00d, 0x0079, 0x384d, 0x29c5, 0x385d, 0x3857,
-	0x388d, 0x385d, 0x3893, 0x3855, 0x3855, 0x1078, 0x296b, 0x6894,
-	0x78d6, 0x78de, 0x6898, 0x78d2, 0x78da, 0xa684, 0x0060, 0x0040,
-	0x388d, 0xa086, 0x0060, 0x00c0, 0x388a, 0xa6b4, 0xbfbf, 0xc6ed,
-	0x7e5a, 0x6eb6, 0xa186, 0x0002, 0x0040, 0x3879, 0x1078, 0x4586,
-	0x69ac, 0x68b0, 0xa115, 0x0040, 0x3879, 0x1078, 0x48f5, 0x0078,
-	0x387b, 0x1078, 0x48bd, 0x781b, 0x0079, 0x681c, 0xc0b4, 0x681e,
-	0x71d4, 0xd1b4, 0x00c0, 0x29c1, 0x70a4, 0xa086, 0x0001, 0x00c0,
-	0x2a0b, 0x007c, 0xd6ec, 0x0040, 0x3867, 0x6818, 0xd0fc, 0x0040,
-	0x3893, 0x681b, 0x0007, 0x781b, 0x00f9, 0x007c, 0xc6fc, 0x7e5a,
-	0x7adc, 0x79d8, 0x6b98, 0x2100, 0xa302, 0x68b2, 0x6b94, 0x2200,
-	0xa303, 0x68ae, 0x79d2, 0x781b, 0x0079, 0x007c, 0xd6dc, 0x0040,
-	0x38af, 0x782b, 0x3009, 0x781b, 0x0079, 0x0078, 0x29c1, 0x7884,
-	0xc0ac, 0x7886, 0x78e4, 0xa084, 0x0008, 0x00c0, 0x38c2, 0xa484,
-	0x0200, 0x0040, 0x38bc, 0xc6f5, 0xc6dd, 0x7e5a, 0x781b, 0x0079,
-	0x0078, 0x29c1, 0x6820, 0xc095, 0x6822, 0x1078, 0x4292, 0xc6dd,
-	0x1078, 0x40c8, 0x781b, 0x0078, 0x0078, 0x29c1, 0x2300, 0x0079,
-	0x38d1, 0x38d4, 0x38d6, 0x38d8, 0x1078, 0x296b, 0x0078, 0x40c1,
-	0xd6d4, 0x00c0, 0x3913, 0x79e4, 0xd1ac, 0x0040, 0x38e6, 0x78ec,
-	0xa084, 0x0003, 0x0040, 0x38e6, 0x782b, 0x3009, 0x789b, 0x0060,
-	0x78ab, 0x0000, 0xa684, 0xfffb, 0x785a, 0x79e4, 0xd1ac, 0x0040,
-	0x38f6, 0x78ec, 0xa084, 0x0003, 0x00c0, 0x390f, 0x2001, 0x4e04,
-	0x2004, 0xd0e4, 0x00c0, 0x390b, 0x6820, 0xd0c4, 0x0040, 0x390b,
-	0x0c7e, 0x7058, 0x2060, 0x6004, 0xc09d, 0x6006, 0x6008, 0xa084,
-	0x00ff, 0x600a, 0x0c7f, 0x2001, 0x0014, 0x0078, 0x33fa, 0xa184,
-	0x0007, 0x0079, 0x3949, 0x7a90, 0xa294, 0x0007, 0x789b, 0x0060,
-	0x79a8, 0x81ff, 0x0040, 0x3947, 0x789b, 0x0010, 0x7ba8, 0xa384,
-	0x0001, 0x00c0, 0x393a, 0x7ba8, 0x7ba8, 0xa386, 0x0001, 0x00c0,
-	0x392d, 0x2009, 0xfff7, 0x0078, 0x3933, 0xa386, 0x0003, 0x00c0,
-	0x393a, 0x2009, 0xffef, 0x0c7e, 0x7058, 0x2060, 0x6004, 0xa104,
-	0x6006, 0x0c7f, 0x789b, 0x0060, 0x78ab, 0x0000, 0xa684, 0xfffb,
-	0x785a, 0x782b, 0x3009, 0x6920, 0xa18c, 0xfcff, 0x6922, 0x0078,
-	0x430d, 0x3090, 0x309a, 0x3953, 0x3959, 0x3951, 0x3951, 0x430d,
-	0x430d, 0x1078, 0x296b, 0x6920, 0xa18c, 0xfcff, 0x6922, 0x0078,
-	0x4313, 0x6920, 0xa18c, 0xfcff, 0x6922, 0x0078, 0x430d, 0x79e4,
-	0xa184, 0x0030, 0x0040, 0x3969, 0x78ec, 0xa084, 0x0003, 0x00c0,
-	0x399d, 0x7000, 0xa086, 0x0004, 0x00c0, 0x3983, 0x7064, 0xa086,
-	0x0002, 0x00c0, 0x3979, 0x2011, 0x0002, 0x2019, 0x0000, 0x0078,
-	0x2f1c, 0x7064, 0xa086, 0x0006, 0x0040, 0x3973, 0x7064, 0xa086,
-	0x0004, 0x0040, 0x3973, 0x7000, 0xa086, 0x0000, 0x0040, 0x29c1,
-	0x6920, 0xa184, 0x0420, 0x0040, 0x3992, 0xc1d4, 0x6922, 0x6818,
-	0x0078, 0x33fa, 0x6818, 0xa08e, 0x0002, 0x0040, 0x399b, 0xc0fd,
-	0x681a, 0x2001, 0x0014, 0x0078, 0x33fa, 0xa184, 0x0007, 0x0079,
-	0x39a1, 0x430d, 0x430d, 0x39a9, 0x430d, 0x4355, 0x4355, 0x430d,
-	0x430d, 0xd6bc, 0x0040, 0x39eb, 0x7184, 0x81ff, 0x0040, 0x39eb,
-	0xa182, 0x000d, 0x00d0, 0x39b8, 0x7087, 0x0000, 0x0078, 0x39bd,
-	0xa182, 0x000c, 0x7086, 0x2009, 0x000c, 0x789b, 0x0061, 0x79aa,
-	0x157e, 0x137e, 0x147e, 0x7088, 0x8114, 0xa210, 0x728a, 0xa080,
-	0x000b, 0xad00, 0x2098, 0xb284, 0x0300, 0x0040, 0x39df, 0x007e,
-	0x2001, 0x4e04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x39db, 0x20a1,
-	0x012b, 0x0078, 0x39e1, 0x20a1, 0x022b, 0x0078, 0x39e1, 0x20a1,
-	0x012b, 0x789b, 0x0000, 0x8108, 0x81ac, 0x53a6, 0x147f, 0x137f,
-	0x157f, 0x0078, 0x4313, 0xd6d4, 0x00c0, 0x3a3f, 0x6820, 0xd084,
-	0x0040, 0x4313, 0xa68c, 0x0060, 0xa684, 0x0060, 0x0040, 0x39fd,
-	0xa086, 0x0060, 0x00c0, 0x39fd, 0xc1f5, 0xc194, 0x795a, 0x69b6,
-	0x789b, 0x0060, 0x78ab, 0x0000, 0x789b, 0x0061, 0x6818, 0xc0fd,
-	0x681a, 0x78aa, 0x8008, 0x810c, 0x0040, 0x3e06, 0xa18c, 0x00f8,
-	0x00c0, 0x3e06, 0x157e, 0x137e, 0x147e, 0x017e, 0x3208, 0xa18c,
-	0x0300, 0x0040, 0x3a2b, 0x007e, 0x2001, 0x4e04, 0x2004, 0xd0ec,
-	0x007f, 0x0040, 0x3a27, 0x20a1, 0x012b, 0x0078, 0x3a2d, 0x20a1,
-	0x022b, 0x0078, 0x3a2d, 0x20a1, 0x012b, 0x017f, 0x789b, 0x0000,
-	0x8000, 0x80ac, 0xad80, 0x000b, 0x2098, 0x53a6, 0x147f, 0x137f,
-	0x157f, 0x6814, 0xc0fc, 0x8007, 0x7882, 0x0078, 0x4313, 0x6818,
-	0xd0fc, 0x0040, 0x3a45, 0x681b, 0x0008, 0x6820, 0xc0ad, 0x6822,
-	0x1078, 0x40d0, 0x781b, 0x00ea, 0x007c, 0x2300, 0x0079, 0x3a50,
-	0x3a55, 0x3b2d, 0x3a53, 0x1078, 0x296b, 0x7cd8, 0x7ddc, 0x7fd0,
-	0x82ff, 0x00c0, 0x3a7e, 0x7200, 0xa286, 0x0003, 0x0040, 0x33c7,
-	0x71d4, 0xd1bc, 0x00c0, 0x3a81, 0xd1b4, 0x0040, 0x3a81, 0x0d7e,
-	0x783b, 0x8800, 0x781b, 0x004c, 0x70bc, 0xa06d, 0x68b4, 0xc0a5,
-	0x785a, 0x6894, 0x78d6, 0x78de, 0x6898, 0x78d2, 0x78da, 0xc1b4,
-	0x71d6, 0x7003, 0x0030, 0x0d7f, 0x0078, 0x3a85, 0x7200, 0x0078,
-	0x3a85, 0x783b, 0x1800, 0x781b, 0x004a, 0xa284, 0x000f, 0x0079,
-	0x3a89, 0x3b18, 0x3ac7, 0x3a93, 0x33f6, 0x3a91, 0x3b18, 0x3a91,
-	0x3a91, 0x1078, 0x296b, 0x681c, 0xd0ec, 0x0040, 0x3a9a, 0x6008,
-	0xc08d, 0x600a, 0x6920, 0xc185, 0x6922, 0x6800, 0x6006, 0xa005,
-	0x00c0, 0x3aa3, 0x6002, 0x6008, 0xc0d4, 0x600a, 0x681c, 0xa084,
-	0x000e, 0x00c0, 0x3ab7, 0xb284, 0x0300, 0x0040, 0x3ab3, 0x2009,
-	0x94c0, 0x0078, 0x3abc, 0x2009, 0x95d0, 0x0078, 0x3abc, 0x7030,
-	0x68ba, 0x7140, 0x70cc, 0xa108, 0x2104, 0x6802, 0x2d0a, 0x715e,
-	0xd6dc, 0x00c0, 0x3ac7, 0xc6fc, 0x6eb6, 0x0078, 0x3b18, 0x6eb6,
-	0xa684, 0x0060, 0x00c0, 0x3ad1, 0xa684, 0x7fff, 0x68b6, 0x0078,
-	0x3b18, 0xd6dc, 0x00c0, 0x3adf, 0xa684, 0x7fff, 0x68b6, 0x6894,
-	0x68a6, 0x6898, 0x68aa, 0x1078, 0x4586, 0x0078, 0x3b18, 0xd6ac,
-	0x0040, 0x3aeb, 0xa006, 0x1078, 0x4586, 0x2408, 0x2510, 0x69aa,
-	0x6aa6, 0x0078, 0x3afb, 0x2408, 0x2510, 0x2700, 0x801b, 0x00c8,
-	0x3af2, 0x8000, 0xa084, 0x003f, 0xa108, 0xa291, 0x0000, 0x69aa,
-	0x6aa6, 0x1078, 0x4586, 0xd6fc, 0x0040, 0x3b18, 0xa684, 0x7fff,
-	0x68b6, 0x2510, 0x2408, 0xd6ac, 0x00c0, 0x3b10, 0x2700, 0x801b,
-	0x00c8, 0x3b0b, 0x8000, 0xa084, 0x003f, 0xa108, 0xa291, 0x0000,
+	0x00ff, 0xa205, 0x6822, 0x1078, 0x2073, 0x2021, 0x4f02, 0x241c,
+	0x8319, 0x2322, 0x6010, 0x8001, 0x6012, 0x00c0, 0x3064, 0x2021,
+	0x4f04, 0x2404, 0xc0a5, 0x2022, 0x6008, 0xa084, 0xf9ef, 0x600a,
+	0x1078, 0x2b22, 0x1078, 0x3e36, 0x007c, 0xa085, 0x0001, 0x0078,
+	0x306c, 0x2300, 0x0079, 0x3074, 0x3079, 0x3077, 0x30f9, 0x1078,
+	0x29b2, 0x78e4, 0xa005, 0x00d0, 0x30af, 0x3208, 0x007e, 0x2001,
+	0x4f04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x308a, 0xa18c, 0x0300,
+	0x0078, 0x308c, 0xa18c, 0x0400, 0x0040, 0x3092, 0x0018, 0x2a08,
+	0x0078, 0x3094, 0x0028, 0x2a08, 0x2008, 0xa084, 0x0030, 0x00c0,
+	0x309b, 0x0078, 0x37b9, 0x78ec, 0xa084, 0x0003, 0x0040, 0x3099,
+	0x2100, 0xa084, 0x0007, 0x0079, 0x30a5, 0x30d9, 0x30e3, 0x30ce,
+	0x30ad, 0x43a5, 0x43a5, 0x30ad, 0x30ee, 0x1078, 0x29b2, 0x7000,
+	0xa086, 0x0004, 0x00c0, 0x30c9, 0x7064, 0xa086, 0x0002, 0x00c0,
+	0x30bf, 0x2011, 0x0002, 0x2019, 0x0000, 0x0078, 0x2f65, 0x7064,
+	0xa086, 0x0006, 0x0040, 0x30b9, 0x7064, 0xa086, 0x0004, 0x0040,
+	0x30b9, 0x79e4, 0x2001, 0x0003, 0x0078, 0x3443, 0x6818, 0xd0fc,
+	0x0040, 0x30d4, 0x681b, 0x001d, 0x1078, 0x4118, 0x781b, 0x0064,
+	0x007c, 0x6818, 0xd0fc, 0x0040, 0x30df, 0x681b, 0x001d, 0x1078,
+	0x4118, 0x0078, 0x4381, 0x6818, 0xd0fc, 0x0040, 0x30e9, 0x681b,
+	0x001d, 0x1078, 0x4118, 0x781b, 0x00f8, 0x007c, 0x6818, 0xd0fc,
+	0x0040, 0x30f4, 0x681b, 0x001d, 0x1078, 0x4118, 0x781b, 0x00c8,
+	0x007c, 0xa584, 0x000f, 0x00c0, 0x3118, 0x1078, 0x29a5, 0x7000,
+	0x0079, 0x3102, 0x2a0c, 0x310a, 0x310c, 0x3dc7, 0x3dc7, 0x3dc7,
+	0x310a, 0x310a, 0x1078, 0x29b2, 0x1078, 0x3e36, 0x6008, 0xa084,
+	0xfbef, 0x600a, 0x1078, 0x3db8, 0x0040, 0x3dc7, 0x0078, 0x2a0c,
+	0x78e4, 0xa005, 0x00d0, 0x30af, 0x3208, 0x007e, 0x2001, 0x4f04,
+	0x2004, 0xd0ec, 0x007f, 0x0040, 0x3129, 0xa18c, 0x0300, 0x0078,
+	0x312b, 0xa18c, 0x0400, 0x0040, 0x3131, 0x0018, 0x30af, 0x0078,
+	0x3133, 0x0028, 0x30af, 0x2008, 0xa084, 0x0030, 0x00c0, 0x313b,
+	0x781b, 0x005b, 0x007c, 0x78ec, 0xa084, 0x0003, 0x0040, 0x3138,
+	0x2100, 0xa184, 0x0007, 0x0079, 0x3145, 0x3154, 0x3158, 0x314f,
+	0x314d, 0x43a5, 0x43a5, 0x314d, 0x439f, 0x1078, 0x29b2, 0x1078,
+	0x4120, 0x781b, 0x0064, 0x007c, 0x1078, 0x4120, 0x0078, 0x4381,
+	0x1078, 0x4120, 0x781b, 0x00f8, 0x007c, 0x1078, 0x4120, 0x781b,
+	0x00c8, 0x007c, 0x2300, 0x0079, 0x3165, 0x316a, 0x3168, 0x316c,
+	0x1078, 0x29b2, 0x0078, 0x39a8, 0x681b, 0x0016, 0x78a3, 0x0000,
+	0x79e4, 0xa184, 0x0030, 0x0040, 0x39a8, 0x78ec, 0xa084, 0x0003,
+	0x0040, 0x39a8, 0xa184, 0x0100, 0x0040, 0x3170, 0xa184, 0x0007,
+	0x0079, 0x3182, 0x318a, 0x3158, 0x30ce, 0x435d, 0x43a5, 0x43a5,
+	0x435d, 0x439f, 0x1078, 0x4369, 0x007c, 0xa282, 0x0005, 0x0050,
+	0x3193, 0x1078, 0x29b2, 0x2300, 0x0079, 0x3196, 0x3199, 0x33c9,
+	0x33d4, 0x2200, 0x0079, 0x319c, 0x31b6, 0x31a3, 0x31b6, 0x31a1,
+	0x33ac, 0x1078, 0x29b2, 0x789b, 0x0018, 0x78a8, 0xa084, 0x00ff,
+	0xa082, 0x0020, 0x0048, 0x4107, 0xa08a, 0x0004, 0x00c8, 0x4107,
+	0x0079, 0x31b2, 0x4107, 0x4107, 0x4107, 0x40b1, 0x789b, 0x0018,
+	0x79a8, 0xa184, 0x0080, 0x0040, 0x31c7, 0x0078, 0x4107, 0x7000,
+	0xa005, 0x00c0, 0x31bd, 0x2011, 0x0004, 0x0078, 0x3b93, 0xa184,
+	0x00ff, 0xa08a, 0x0010, 0x00c8, 0x4107, 0x0079, 0x31cf, 0x31e1,
+	0x31df, 0x31f6, 0x31fa, 0x32cd, 0x4107, 0x4107, 0x32cf, 0x4107,
+	0x4107, 0x33a8, 0x33a8, 0x4107, 0x4107, 0x4107, 0x33aa, 0x1078,
+	0x29b2, 0xd6e4, 0x0040, 0x31ec, 0x2001, 0x0300, 0x8000, 0x8000,
+	0x783a, 0x781b, 0x00c3, 0x007c, 0x6818, 0xd0fc, 0x0040, 0x31f4,
+	0x681b, 0x001d, 0x0078, 0x31e4, 0x0078, 0x435d, 0x681b, 0x001d,
+	0x0078, 0x4111, 0x6920, 0x6922, 0xa684, 0x1800, 0x00c0, 0x325f,
+	0x6820, 0xd084, 0x00c0, 0x3265, 0x6818, 0xa086, 0x0008, 0x00c0,
+	0x320b, 0x681b, 0x0000, 0xd6d4, 0x0040, 0x32ca, 0xd6bc, 0x0040,
+	0x324b, 0x7087, 0x0000, 0x6818, 0xa084, 0x003f, 0xa08a, 0x000d,
+	0x0050, 0x324b, 0xa08a, 0x000c, 0x7186, 0x2001, 0x000c, 0x800c,
+	0x718a, 0x789b, 0x0061, 0x78aa, 0x157e, 0x137e, 0x147e, 0x017e,
+	0x3208, 0xa18c, 0x0300, 0x0040, 0x323d, 0x007e, 0x2001, 0x4f04,
+	0x2004, 0xd0ec, 0x007f, 0x0040, 0x3239, 0x20a1, 0x012b, 0x0078,
+	0x323f, 0x20a1, 0x022b, 0x0078, 0x323f, 0x20a1, 0x012b, 0x017f,
+	0x789b, 0x0000, 0x8000, 0x80ac, 0xad80, 0x000b, 0x2098, 0x53a6,
+	0x147f, 0x137f, 0x157f, 0x6038, 0xa005, 0x00c0, 0x325a, 0x681c,
+	0xa084, 0x000e, 0x0040, 0x4111, 0x1078, 0x4127, 0x782b, 0x3008,
+	0x0078, 0x325c, 0x8001, 0x603a, 0x781b, 0x0067, 0x007c, 0xd6e4,
+	0x0040, 0x3265, 0x781b, 0x0079, 0x007c, 0xa684, 0x0060, 0x0040,
+	0x32c7, 0xd6dc, 0x0040, 0x32c7, 0xd6fc, 0x00c0, 0x3271, 0x0078,
+	0x3288, 0xc6fc, 0x7e5a, 0x6eb6, 0x7adc, 0x79d8, 0x78d0, 0x801b,
+	0x00c8, 0x327b, 0x8000, 0xa084, 0x003f, 0xa108, 0xa291, 0x0000,
 	0x6b98, 0x2100, 0xa302, 0x68b2, 0x6b94, 0x2200, 0xa303, 0x68ae,
-	0x7000, 0xa086, 0x0030, 0x00c0, 0x29c5, 0x7003, 0x0002, 0x70bc,
-	0xa06d, 0x68bc, 0x7042, 0x70b8, 0xa065, 0x68c0, 0x705a, 0x2d00,
-	0x704e, 0xad80, 0x0009, 0x7046, 0x007c, 0xa586, 0x8800, 0x00c0,
-	0x3b3a, 0x7003, 0x0000, 0x6018, 0x8001, 0x601a, 0x6008, 0xa084,
-	0xfbef, 0x600a, 0x0078, 0x40c1, 0x7047, 0x0000, 0xa282, 0x0006,
-	0x0050, 0x3b44, 0x1078, 0x296b, 0x2300, 0x0079, 0x3b47, 0x3b4a,
-	0x3b5c, 0x3b68, 0x2200, 0x0079, 0x3b4d, 0x3b53, 0x40c1, 0x3b55,
-	0x3b53, 0x3ba2, 0x3bf7, 0x1078, 0x296b, 0x7a80, 0xa294, 0x0f00,
-	0x1078, 0x3c81, 0x0078, 0x40b7, 0x1078, 0x3b79, 0x0079, 0x3b60,
-	0x40c1, 0x3b66, 0x3b66, 0x3ba2, 0x3b66, 0x40c1, 0x1078, 0x296b,
-	0x1078, 0x3b79, 0x0079, 0x3b6c, 0x3b74, 0x3b72, 0x3b72, 0x3b74,
-	0x3b72, 0x3b74, 0x1078, 0x296b, 0x1078, 0x40db, 0x781b, 0x0078,
-	0x007c, 0x7000, 0xa086, 0x0002, 0x00c0, 0x3b8a, 0x1078, 0x3ded,
-	0x0078, 0x3b84, 0x1078, 0x4586, 0x6008, 0xa084, 0xfbef, 0x600a,
-	0x0078, 0x3b8f, 0x7000, 0xa086, 0x0003, 0x0040, 0x3b82, 0x7003,
-	0x0005, 0xb284, 0x0300, 0x0040, 0x3b99, 0x2001, 0x95e0, 0x0078,
-	0x3b9b, 0x2001, 0x9612, 0x2068, 0x704e, 0xad80, 0x0009, 0x7046,
-	0x2200, 0x007c, 0x7000, 0xa086, 0x0002, 0x00c0, 0x3bb4, 0x70d4,
-	0xc0b5, 0x70d6, 0x2c00, 0x70ba, 0x2d00, 0x70be, 0x0078, 0x3bb9,
-	0x1078, 0x4586, 0x0078, 0x3bb9, 0x7000, 0xa086, 0x0003, 0x0040,
-	0x3bb0, 0x7003, 0x0001, 0x7a80, 0xa294, 0x0f00, 0x789b, 0x0018,
-	0x7ca8, 0xa484, 0x001f, 0xa215, 0x2069, 0x94c0, 0xb284, 0x0300,
-	0x00c0, 0x3bcd, 0xc2fd, 0x2069, 0x95d0, 0x2d04, 0x2d08, 0x715e,
-	0xa06d, 0x0040, 0x3bda, 0x6814, 0xa206, 0x0040, 0x3bdc, 0x6800,
-	0x0078, 0x3bce, 0x1078, 0x3c81, 0x6eb4, 0x7e5a, 0x6920, 0xa184,
-	0x0c00, 0x0040, 0x3cab, 0x7064, 0xa086, 0x0006, 0x00c0, 0x3bee,
-	0x7074, 0xa206, 0x00c0, 0x3bee, 0x7066, 0x707e, 0x681b, 0x0005,
-	0xc1ad, 0xc1d4, 0x6922, 0x1078, 0x40d0, 0x0078, 0x3cab, 0x7200,
-	0xa286, 0x0002, 0x00c0, 0x3c09, 0x70d4, 0xc0b5, 0x70d6, 0x2c00,
-	0x70ba, 0x2d00, 0x70be, 0x0078, 0x3c0d, 0x1078, 0x4586, 0x0078,
-	0x3c0d, 0xa286, 0x0003, 0x0040, 0x3c05, 0x7003, 0x0001, 0x7a80,
-	0xa294, 0x0f00, 0x789b, 0x0018, 0x7ca8, 0xa484, 0x001f, 0xa215,
-	0xb284, 0x0300, 0x00c0, 0x3c1d, 0xc2fd, 0x79a8, 0x79a8, 0xa18c,
-	0x00ff, 0x2118, 0x70cc, 0xa168, 0x2d04, 0x2d08, 0x715e, 0xa06d,
-	0x0040, 0x3c31, 0x6814, 0xa206, 0x0040, 0x3c5a, 0x6800, 0x0078,
-	0x3c25, 0x7003, 0x0005, 0xb284, 0x0300, 0x0040, 0x3c3b, 0x2001,
-	0x95e0, 0x0078, 0x3c3d, 0x2001, 0x9612, 0x2068, 0x704e, 0x157e,
-	0x20a9, 0x0032, 0x2003, 0x0000, 0x8000, 0x00f0, 0x3c42, 0x157f,
-	0xb284, 0x0300, 0x0040, 0x3c4f, 0xc2fc, 0x0078, 0x3c50, 0xc2fd,
-	0x6a16, 0xad80, 0x0009, 0x7046, 0x68b7, 0x0700, 0x6823, 0x0800,
-	0x6827, 0x0003, 0x6eb4, 0x6920, 0xa184, 0x0c00, 0x0040, 0x3cab,
-	0xd0dc, 0x0040, 0x3c76, 0x7064, 0xa086, 0x0004, 0x00c0, 0x3c72,
-	0x7074, 0xa206, 0x00c0, 0x3c72, 0x7078, 0xa306, 0x00c0, 0x3c72,
-	0x7066, 0x707e, 0x1078, 0x40d7, 0x0078, 0x3cab, 0x681b, 0x0005,
-	0xc1ad, 0xc1d4, 0x6922, 0x1078, 0x40d0, 0x707f, 0x0000, 0x0078,
-	0x3cab, 0x7003, 0x0005, 0xb284, 0x0300, 0x0040, 0x3c8b, 0x2001,
-	0x95e0, 0x0078, 0x3c8d, 0x2001, 0x9612, 0x2068, 0x704e, 0x157e,
-	0x20a9, 0x0032, 0x2003, 0x0000, 0x8000, 0x00f0, 0x3c92, 0x157f,
-	0xb284, 0x0300, 0x0040, 0x3c9f, 0xc2fc, 0x0078, 0x3ca0, 0xc2fd,
-	0x6a16, 0xad80, 0x0009, 0x7046, 0x68b7, 0x0700, 0x6823, 0x0800,
-	0x6827, 0x0003, 0x007c, 0xc6ec, 0xa6ac, 0x0060, 0x0040, 0x3cfd,
-	0x6b98, 0x6c94, 0x69ac, 0x68b0, 0xa105, 0x00c0, 0x3cd8, 0x7bd2,
-	0x7bda, 0x7cd6, 0x7cde, 0xa586, 0x0060, 0x0040, 0x3d02, 0xd6f4,
-	0x00c0, 0x3cc3, 0xc6ed, 0xa6b4, 0xb7ff, 0x7e5a, 0x2009, 0x0079,
-	0xd69c, 0x0040, 0x3cd0, 0x2009, 0x0078, 0x2019, 0x0000, 0x2320,
-	0x791a, 0xd6ec, 0x0040, 0x3d0d, 0x1078, 0x48bd, 0x0078, 0x3d0d,
-	0x68b0, 0xa31a, 0x2100, 0xa423, 0x2400, 0xa305, 0x0040, 0x3d04,
-	0x7bd2, 0x7bda, 0x7cd6, 0x7cde, 0x68b0, 0xd6f4, 0x00c0, 0x3ce9,
-	0xc6ed, 0xc6f4, 0x7e5a, 0x2011, 0x0079, 0xd69c, 0x0040, 0x3cf5,
-	0x2011, 0x0078, 0x2019, 0x0000, 0x2320, 0x7a1a, 0xd6ec, 0x0040,
-	0x3d0d, 0x1078, 0x48f5, 0x0078, 0x3d0d, 0x2019, 0x0000, 0x2320,
-	0x0078, 0x3d04, 0xa6b4, 0xb7ff, 0x7e5a, 0x2009, 0x0079, 0xd69c,
-	0x0040, 0x3d0c, 0x2009, 0x0078, 0x791a, 0x68c0, 0x705a, 0x2d00,
-	0x704e, 0x68c4, 0x2060, 0x71d4, 0x2001, 0x4e01, 0x2004, 0xd0c4,
-	0x00c0, 0x3d62, 0x70d8, 0xa02d, 0x0040, 0x3d3b, 0xd1bc, 0x0040,
-	0x3d55, 0x7a80, 0xa294, 0x0f00, 0x70dc, 0xa206, 0x0040, 0x3d2c,
-	0x78e0, 0xa504, 0x00c0, 0x3d62, 0x70da, 0xc1bc, 0x71d6, 0x0078,
-	0x3d62, 0x2031, 0x0001, 0x852c, 0x0048, 0x3d3a, 0x8633, 0x8210,
-	0x0078, 0x3d33, 0x007c, 0x7de0, 0xa594, 0xff00, 0x0040, 0x3d48,
-	0x2011, 0x0008, 0x852f, 0x1078, 0x3d31, 0x8637, 0x0078, 0x3d4a,
-	0x1078, 0x3d31, 0x8217, 0x7880, 0xa084, 0x0f00, 0xa206, 0x0040,
-	0x3d62, 0x72de, 0x76da, 0x0078, 0x3d62, 0x7a80, 0xa294, 0x0f00,
-	0x70dc, 0xa236, 0x0040, 0x3d52, 0x78e0, 0xa534, 0x0040, 0x3d52,
-	0xc1bd, 0x71d6, 0xd1b4, 0x00c0, 0x29c1, 0x2300, 0xa405, 0x0040,
-	0x29c1, 0x70a4, 0xa086, 0x0001, 0x00c0, 0x2a0b, 0x007c, 0x6020,
-	0xa005, 0x0040, 0x3d7d, 0x8001, 0x6022, 0x6008, 0xa085, 0x0008,
-	0x600a, 0x700f, 0x0100, 0x702c, 0x6026, 0x007c, 0xa006, 0x1078,
-	0x4586, 0x7000, 0xa086, 0x0002, 0x0040, 0x3d8b, 0x7064, 0xa086,
-	0x0005, 0x00c0, 0x3d95, 0x682b, 0x0000, 0x6817, 0x0000, 0x681b,
-	0x0001, 0x6823, 0x0040, 0x681f, 0x0100, 0x7000, 0xa084, 0x000f,
-	0x0079, 0x3d9a, 0x29c5, 0x3daa, 0x3da4, 0x3dcc, 0x3db4, 0x29c5,
-	0x3da2, 0x3da2, 0x1078, 0x296b, 0x1078, 0x3dd7, 0x1078, 0x3dd0,
-	0x0078, 0x3db0, 0x1078, 0x3dd7, 0x705c, 0x2060, 0x6800, 0x6002,
-	0x1078, 0x202c, 0x0078, 0x29c5, 0x7064, 0x7067, 0x0000, 0x7083,
-	0x0000, 0x0079, 0x3dbb, 0x3dc8, 0x3dc8, 0x3dc3, 0x3dc3, 0x3dc3,
-	0x3dc8, 0x3dc3, 0x3dc8, 0x77d4, 0xc7dd, 0x77d6, 0x0079, 0x2f35,
-	0x7067, 0x0000, 0x0078, 0x29c5, 0x681b, 0x0000, 0x0078, 0x36c8,
-	0x6800, 0xa005, 0x00c0, 0x3dd5, 0x6002, 0x6006, 0x007c, 0x6410,
-	0x84ff, 0x0040, 0x3de9, 0x2009, 0x4e02, 0x2104, 0x8001, 0x200a,
-	0x8421, 0x6412, 0x00c0, 0x3de9, 0x2021, 0x4e04, 0x2404, 0xc0a5,
-	0x2022, 0x6008, 0xc0a4, 0x600a, 0x007c, 0x6018, 0xa005, 0x0040,
-	0x3df3, 0x8001, 0x601a, 0x007c, 0x1078, 0x4383, 0x681b, 0x0018,
-	0x0078, 0x3e34, 0x1078, 0x4383, 0x681b, 0x0019, 0x0078, 0x3e34,
-	0x1078, 0x4383, 0x681b, 0x001a, 0x0078, 0x3e34, 0x1078, 0x4383,
-	0x681b, 0x0003, 0x0078, 0x3e34, 0x7774, 0x1078, 0x41fe, 0x7178,
-	0xa18c, 0x00ff, 0x3210, 0xa294, 0x0300, 0x0040, 0x3e1b, 0xa1e8,
-	0x93c0, 0x0078, 0x3e1d, 0xa1e8, 0x94d0, 0x2d04, 0x2d08, 0x2068,
-	0xa005, 0x00c0, 0x3e26, 0x707e, 0x0078, 0x29c5, 0x6814, 0x7274,
-	0xa206, 0x0040, 0x3e2e, 0x6800, 0x0078, 0x3e1e, 0x6800, 0x200a,
-	0x681b, 0x0005, 0x707f, 0x0000, 0x1078, 0x3dd7, 0x6820, 0xd084,
-	0x00c0, 0x3e3c, 0x1078, 0x3dd0, 0x1078, 0x3ded, 0x681f, 0x0000,
-	0x6823, 0x0020, 0x1078, 0x202c, 0x0078, 0x29c5, 0xa282, 0x0003,
-	0x00c0, 0x40b7, 0x7da8, 0xa5ac, 0x00ff, 0x7e5a, 0x7ea8, 0xa6b4,
-	0x00ff, 0x6920, 0xc1bd, 0x6922, 0xd1c4, 0x0040, 0x3ea1, 0xc1c4,
-	0x6922, 0xa6b4, 0x00ff, 0x0040, 0x3e8e, 0xa682, 0x000c, 0x0048,
-	0x3e65, 0x0040, 0x3e65, 0x2031, 0x000c, 0x2500, 0xa086, 0x000a,
-	0x0040, 0x3e6c, 0x852b, 0x852b, 0x1078, 0x4190, 0x0040, 0x3e74,
-	0x1078, 0x3f6f, 0x0078, 0x3e97, 0x1078, 0x414b, 0x0c7e, 0x2960,
-	0x6004, 0xa084, 0xfff5, 0x6006, 0x1078, 0x3fa5, 0x0c7f, 0x6920,
-	0xc1c5, 0x6922, 0x7e58, 0xc695, 0x7e5a, 0xd6d4, 0x00c0, 0x3e8b,
-	0x781b, 0x0064, 0x007c, 0x781b, 0x0078, 0x007c, 0x0c7e, 0x2960,
-	0x6004, 0xa084, 0xfff5, 0x6006, 0x1078, 0x3fa5, 0x0c7f, 0x7e58,
-	0xd6d4, 0x00c0, 0x3e9e, 0x781b, 0x0067, 0x007c, 0x781b, 0x0079,
-	0x007c, 0x0c7e, 0x7058, 0x2060, 0x6100, 0xd1e4, 0x0040, 0x3eea,
-	0x6208, 0x8217, 0xa294, 0x00ff, 0xa282, 0x000c, 0x0048, 0x3eb4,
-	0x0040, 0x3eb4, 0x2011, 0x000c, 0x2600, 0xa202, 0x00c8, 0x3eb9,
-	0x2230, 0x6208, 0xa294, 0x00ff, 0x2001, 0x4e05, 0x2004, 0xd0e4,
-	0x00c0, 0x3ece, 0x78ec, 0xd0e4, 0x0040, 0x3ece, 0xa282, 0x000a,
-	0x00c8, 0x3ed4, 0x2011, 0x000a, 0x0078, 0x3ed4, 0xa282, 0x000c,
-	0x00c8, 0x3ed4, 0x2011, 0x000c, 0x2200, 0xa502, 0x00c8, 0x3ed9,
-	0x2228, 0x1078, 0x414f, 0x2500, 0xa086, 0x000a, 0x0040, 0x3ee2,
-	0x852b, 0x852b, 0x1078, 0x4190, 0x0040, 0x3eea, 0x1078, 0x3f6f,
-	0x0078, 0x3eee, 0x1078, 0x414b, 0x1078, 0x3fa5, 0x7858, 0xc095,
-	0x785a, 0x0c7f, 0x781b, 0x0078, 0x007c, 0x0c7e, 0x2960, 0x6000,
-	0xd0e4, 0x00c0, 0x3f0b, 0xa084, 0x0040, 0x00c0, 0x3f05, 0x6104,
-	0xa18c, 0xfff5, 0x6106, 0x0c7f, 0x007c, 0x2011, 0x0032, 0x2019,
-	0x0000, 0x0078, 0x3f36, 0x68a0, 0xd0cc, 0x00c0, 0x3f05, 0x6208,
-	0xa294, 0x00ff, 0x2001, 0x4e05, 0x2004, 0xd0e4, 0x00c0, 0x3f24,
-	0x78ec, 0xd0e4, 0x0040, 0x3f24, 0xa282, 0x000b, 0x00c8, 0x3f24,
-	0x2011, 0x000a, 0x0078, 0x3f2a, 0xa282, 0x000c, 0x00c8, 0x3f2a,
-	0x2011, 0x000c, 0x6308, 0x831f, 0xa39c, 0x00ff, 0xa382, 0x000c,
-	0x0048, 0x3f36, 0x0040, 0x3f36, 0x2019, 0x000c, 0x78ab, 0x0001,
-	0x78ab, 0x0003, 0x78ab, 0x0001, 0x7aaa, 0x7baa, 0xa8c0, 0x0005,
-	0x6820, 0xc0c5, 0x6822, 0x70d4, 0xd0b4, 0x0040, 0x3f52, 0xc0b4,
-	0x70d6, 0x70b8, 0xa065, 0x6008, 0xa084, 0xfbef, 0x600a, 0x6018,
-	0x8001, 0x601a, 0x0c7f, 0x007c, 0x0c7e, 0x2960, 0x6104, 0xa18c,
-	0xfff5, 0x6106, 0x2011, 0x0032, 0x2019, 0x0000, 0x0078, 0x3f60,
-	0x78ab, 0x0001, 0x78ab, 0x0003, 0x78ab, 0x0001, 0x7aaa, 0x7baa,
-	0xa8c0, 0x0005, 0x6820, 0xc0c5, 0x6822, 0x0c7f, 0x007c, 0x0c7e,
-	0x7158, 0x2160, 0x2018, 0xa08c, 0x0020, 0x0040, 0x3f78, 0xc0ac,
-	0x2008, 0xa084, 0xfff0, 0xa635, 0x7e86, 0x6018, 0x789a, 0x7eae,
-	0x6612, 0x78a4, 0xa084, 0xfff0, 0xa18c, 0x000f, 0xa105, 0xc0f4,
-	0xa39c, 0x0020, 0x0040, 0x3f8e, 0xa085, 0x4000, 0xc0fc, 0xd0b4,
-	0x00c0, 0x3f93, 0xc0fd, 0x78a6, 0x6016, 0x788a, 0xa6b4, 0x000f,
-	0x8637, 0x8204, 0x8004, 0xa084, 0x00ff, 0xa605, 0x600e, 0x6004,
-	0xa084, 0xfff5, 0x6006, 0x0c7f, 0x007c, 0x0c7e, 0x7058, 0x2060,
-	0x6018, 0x789a, 0x78a4, 0xa084, 0xfff0, 0x78a6, 0x6012, 0x7884,
-	0xa084, 0xfff0, 0x7886, 0x600c, 0xa084, 0x00ff, 0x600e, 0x0c7f,
-	0x007c, 0xa282, 0x0002, 0x00c0, 0x40b7, 0x7aa8, 0x6920, 0xc1bd,
-	0x6922, 0xd1cc, 0x0040, 0x3ff4, 0xc1cc, 0x6922, 0xa294, 0x00ff,
-	0xa282, 0x0002, 0x00c8, 0x40b7, 0x1078, 0x4044, 0x1078, 0x3fa5,
-	0xa980, 0x0001, 0x200c, 0x1078, 0x41fa, 0x1078, 0x3ef5, 0x88ff,
-	0x0040, 0x3fea, 0x789b, 0x0060, 0x2800, 0x78aa, 0x7e58, 0xc695,
-	0x7e5a, 0xd6d4, 0x00c0, 0x3fe7, 0x781b, 0x0064, 0x007c, 0x781b,
-	0x0078, 0x007c, 0x7e58, 0xd6d4, 0x00c0, 0x3ff1, 0x781b, 0x0067,
-	0x007c, 0x781b, 0x0079, 0x007c, 0xa282, 0x0002, 0x00c8, 0x3ffc,
-	0xa284, 0x0001, 0x0040, 0x4005, 0x7158, 0xa188, 0x0000, 0x210c,
-	0xd1ec, 0x00c0, 0x4005, 0x2011, 0x0000, 0x1078, 0x412c, 0x1078,
-	0x4044, 0x1078, 0x3fa5, 0x7858, 0xc095, 0x785a, 0x781b, 0x0078,
-	0x007c, 0x0c7e, 0x027e, 0x2960, 0x6000, 0x2011, 0x0001, 0xd0ec,
-	0x00c0, 0x4025, 0xa084, 0x0080, 0x00c0, 0x4023, 0xc1a4, 0x6106,
-	0xa006, 0x0078, 0x4041, 0x2011, 0x0000, 0x78ab, 0x0001, 0x78ab,
+	0xd6f4, 0x0040, 0x328e, 0xc6f4, 0x7e5a, 0x6eb6, 0x7000, 0xa086,
+	0x0003, 0x00c0, 0x329c, 0x007e, 0x1078, 0x45d6, 0x1078, 0x493f,
+	0x007f, 0x781b, 0x0076, 0x007c, 0xa006, 0x1078, 0x4a44, 0x6ab0,
+	0x69ac, 0x6c98, 0x6b94, 0x2200, 0xa105, 0x0040, 0x32ab, 0x2200,
+	0xa422, 0x2100, 0xa31b, 0x6caa, 0x7cd2, 0x7cda, 0x6ba6, 0x7bd6,
+	0x7bde, 0x2300, 0xa405, 0x00c0, 0x32bb, 0xc6f5, 0x7e5a, 0x6eb6,
+	0x781b, 0x0076, 0x007c, 0x781b, 0x0076, 0x2200, 0xa115, 0x00c0,
+	0x32c4, 0x1078, 0x493f, 0x007c, 0x1078, 0x4977, 0x007c, 0x781b,
+	0x0079, 0x007c, 0x781b, 0x0067, 0x007c, 0x1078, 0x29b2, 0x0078,
+	0x331b, 0x6920, 0xd1c4, 0x0040, 0x32e4, 0xc1c4, 0x6922, 0x0c7e,
+	0x7058, 0x2060, 0x6000, 0xc0e4, 0x6002, 0x6004, 0xa084, 0xfff5,
+	0x6006, 0x0c7f, 0x0078, 0x330f, 0xd1cc, 0x0040, 0x330f, 0xc1cc,
+	0x6922, 0x0c7e, 0x7058, 0x2060, 0x6000, 0xc0ec, 0x6002, 0x6004,
+	0xc0a4, 0x6006, 0x2008, 0x2c48, 0x0c7f, 0xd19c, 0x0040, 0x330f,
+	0x1078, 0x424a, 0x1078, 0x3f3e, 0x88ff, 0x0040, 0x330f, 0x789b,
+	0x0060, 0x2800, 0x78aa, 0x7e58, 0xc695, 0x7e5a, 0xd6d4, 0x00c0,
+	0x330c, 0x781b, 0x0064, 0x007c, 0x781b, 0x0078, 0x007c, 0x7e58,
+	0xd6d4, 0x00c0, 0x3316, 0x781b, 0x0067, 0x007c, 0x781b, 0x0079,
+	0x007c, 0x0078, 0x410c, 0x2019, 0x0000, 0x7990, 0xa18c, 0x0007,
+	0x00c0, 0x3329, 0x6820, 0xa084, 0x0100, 0x0040, 0x3319, 0x2009,
+	0x0008, 0x789b, 0x0010, 0x78a8, 0xa094, 0x00ff, 0xa286, 0x0001,
+	0x00c0, 0x3345, 0x2300, 0x7ca8, 0xa400, 0x2018, 0xa102, 0x0040,
+	0x333d, 0x0048, 0x333d, 0x0078, 0x333f, 0x0078, 0x32d1, 0x24a8,
+	0x7aa8, 0x00f0, 0x333f, 0x0078, 0x332b, 0xa284, 0x00f0, 0xa086,
+	0x0020, 0x00c0, 0x3399, 0x8318, 0x8318, 0x2300, 0xa102, 0x0040,
+	0x3355, 0x0048, 0x3355, 0x0078, 0x3396, 0xa286, 0x0023, 0x0040,
+	0x3319, 0x681c, 0xa084, 0xfff1, 0x681e, 0x7e58, 0xa684, 0xfff1,
+	0xc0a5, 0x2030, 0x7e5a, 0x6008, 0xc0a5, 0x600a, 0x0c7e, 0x7058,
+	0x2060, 0x6004, 0x2008, 0x2c48, 0x0c7f, 0xd1a4, 0x0040, 0x3376,
+	0x1078, 0x424a, 0x1078, 0x405e, 0x0078, 0x3384, 0x0c7e, 0x7058,
+	0x2060, 0x6004, 0x2008, 0x2c48, 0x0c7f, 0xd19c, 0x0040, 0x330f,
+	0x1078, 0x424a, 0x1078, 0x3f3e, 0x88ff, 0x0040, 0x330f, 0x789b,
+	0x0060, 0x2800, 0x78aa, 0xc695, 0x7e5a, 0xd6d4, 0x00c0, 0x3393,
+	0x781b, 0x0064, 0x007c, 0x781b, 0x0078, 0x007c, 0x7aa8, 0x0078,
+	0x332b, 0x8318, 0x2300, 0xa102, 0x0040, 0x33a2, 0x0048, 0x33a2,
+	0x0078, 0x332b, 0xa284, 0x0080, 0x00c0, 0x4111, 0x0078, 0x410c,
+	0x0078, 0x4111, 0x0078, 0x4107, 0x7058, 0xa04d, 0x789b, 0x0018,
+	0x78a8, 0xa084, 0x00ff, 0xa08e, 0x0001, 0x0040, 0x33b9, 0x1078,
+	0x29b2, 0x7aa8, 0xa294, 0x00ff, 0x78a8, 0xa084, 0x00ff, 0xa08a,
+	0x0004, 0x00c8, 0x4107, 0x0079, 0x33c5, 0x4107, 0x3e8f, 0x4107,
+	0x4006, 0xa282, 0x0000, 0x00c0, 0x33cf, 0x1078, 0x29b2, 0x1078,
+	0x4118, 0x781b, 0x0078, 0x007c, 0xa282, 0x0003, 0x00c0, 0x33da,
+	0x1078, 0x29b2, 0xd4fc, 0x00c0, 0x33fa, 0x7064, 0xa005, 0x0040,
+	0x33e3, 0x1078, 0x29b2, 0x6f14, 0x7776, 0xa7bc, 0x8f00, 0x1078,
+	0x424e, 0x6008, 0xa085, 0x0021, 0x600a, 0x8738, 0xa784, 0x001f,
+	0x00c0, 0x33e7, 0x1078, 0x411c, 0x7067, 0x0002, 0x701f, 0x0009,
+	0x0078, 0x33fc, 0x1078, 0x412b, 0x781b, 0x0078, 0x007c, 0xa282,
+	0x0004, 0x0050, 0x3405, 0x1078, 0x29b2, 0x2300, 0x0079, 0x3408,
+	0x340b, 0x35cb, 0x360e, 0xa286, 0x0003, 0x0040, 0x3443, 0x7200,
+	0x7cd8, 0x7ddc, 0x7fd0, 0x71d4, 0xd1bc, 0x00c0, 0x343b, 0xd1b4,
+	0x0040, 0x343b, 0x7868, 0xa084, 0x00ff, 0x00c0, 0x343b, 0xa282,
+	0x0002, 0x00c8, 0x343b, 0x0d7e, 0x783b, 0x8300, 0x781b, 0x004c,
+	0x70bc, 0xa06d, 0x68b4, 0x785a, 0x6894, 0x78d6, 0x78de, 0x6898,
+	0x78d2, 0x78da, 0xc1b4, 0x71d6, 0x7003, 0x0030, 0x0d7f, 0x2001,
+	0x0000, 0x0078, 0x3447, 0x783b, 0x1300, 0x781b, 0x004a, 0x2001,
+	0x0000, 0x0078, 0x3447, 0x7200, 0x7cd8, 0x7ddc, 0x7fd0, 0x704a,
+	0x68a0, 0xd0ec, 0x0040, 0x344f, 0x6008, 0xc08d, 0x600a, 0xa284,
+	0x000f, 0x0079, 0x3453, 0x35ab, 0x3460, 0x345d, 0x3711, 0x379d,
+	0x2a0c, 0x345b, 0x345b, 0x1078, 0x29b2, 0x6008, 0xc0d4, 0x600a,
+	0xd6e4, 0x0040, 0x3468, 0x7048, 0xa086, 0x0014, 0x00c0, 0x3488,
+	0x1078, 0x45d6, 0x2009, 0x0000, 0x6818, 0xd0fc, 0x0040, 0x3471,
+	0x7048, 0xa086, 0x0014, 0x0040, 0x3482, 0x6818, 0xa086, 0x0008,
+	0x00c0, 0x3563, 0x7858, 0xd09c, 0x0040, 0x3563, 0x6820, 0xd0ac,
+	0x0040, 0x3563, 0x681b, 0x0014, 0x2009, 0x0002, 0x0078, 0x34c7,
+	0x7868, 0xa08c, 0x00ff, 0x0040, 0x34c7, 0xa186, 0x0008, 0x00c0,
+	0x349e, 0x6008, 0xc0a4, 0x600a, 0x1078, 0x3db8, 0x0040, 0x34c7,
+	0x1078, 0x3e36, 0x1078, 0x45d6, 0x0078, 0x34af, 0xa186, 0x0028,
+	0x00c0, 0x34c7, 0x6018, 0xa005, 0x0040, 0x3491, 0x8001, 0x0040,
+	0x3491, 0x8001, 0x0040, 0x3491, 0x601e, 0x0078, 0x3491, 0x6820,
+	0xd084, 0x0040, 0x2a0c, 0xc084, 0x6822, 0x1078, 0x2b13, 0x705c,
+	0x0c7e, 0x2060, 0x6800, 0x6002, 0x0c7f, 0x6004, 0x6802, 0xa005,
+	0x2d00, 0x00c0, 0x34c4, 0x6002, 0x6006, 0x0078, 0x2a0c, 0x017e,
+	0x81ff, 0x00c0, 0x3511, 0x7000, 0xa086, 0x0030, 0x0040, 0x3511,
+	0x71d4, 0xd1bc, 0x00c0, 0x3511, 0xd1b4, 0x00c0, 0x34f8, 0x7060,
+	0xa005, 0x00c0, 0x3511, 0x70a4, 0xa086, 0x0001, 0x0040, 0x3511,
+	0x7003, 0x0000, 0x047e, 0x057e, 0x077e, 0x067e, 0x0c7e, 0x0d7e,
+	0x1078, 0x2a35, 0x0d7f, 0x0c7f, 0x067f, 0x077f, 0x057f, 0x047f,
+	0x71d4, 0xd1b4, 0x00c0, 0x3511, 0x7003, 0x0040, 0x0078, 0x3511,
+	0x1078, 0x43b0, 0x00c0, 0x3511, 0x781b, 0x005b, 0x0d7e, 0x70bc,
+	0xa06d, 0x68b4, 0x785a, 0x6894, 0x78d6, 0x78de, 0x6898, 0x78d2,
+	0x78da, 0xc1b4, 0x71d6, 0x7003, 0x0030, 0x7808, 0xc08d, 0x780a,
+	0x0d7f, 0x1078, 0x3648, 0x017f, 0x81ff, 0x0040, 0x3563, 0xa684,
+	0xdf00, 0x681e, 0x682b, 0x0000, 0x6f14, 0xa186, 0x0002, 0x00c0,
+	0x3564, 0x6818, 0xa086, 0x0014, 0x00c0, 0x352d, 0x2008, 0xd6e4,
+	0x0040, 0x352d, 0x7868, 0xa08c, 0x00ff, 0x1078, 0x2b01, 0x1078,
+	0x2b22, 0x6820, 0xd0dc, 0x00c0, 0x3564, 0x8717, 0xa294, 0x000f,
+	0x8213, 0x8213, 0x8213, 0xb284, 0x0300, 0x0040, 0x3543, 0xa290,
+	0x53c0, 0x0078, 0x3545, 0xa290, 0x5440, 0xa290, 0x0000, 0x221c,
+	0xd3c4, 0x00c0, 0x354d, 0x0078, 0x3553, 0x8210, 0x2204, 0xa085,
+	0x0018, 0x2012, 0x8211, 0xd3d4, 0x0040, 0x355e, 0x68a0, 0xd0c4,
+	0x00c0, 0x355e, 0x1078, 0x36c2, 0x0078, 0x2a0c, 0x6008, 0xc08d,
+	0x600a, 0x0078, 0x3564, 0x692a, 0x6916, 0x6818, 0xd0fc, 0x0040,
+	0x356b, 0x7048, 0x681a, 0xa68c, 0xdf00, 0x691e, 0x6410, 0x84ff,
+	0x0040, 0x3580, 0x2009, 0x4f02, 0x2104, 0x8001, 0x200a, 0x8421,
+	0x6412, 0x00c0, 0x3580, 0x2021, 0x4f04, 0x2404, 0xc0a5, 0x2022,
+	0x6018, 0xa005, 0x0040, 0x3588, 0x8001, 0x601a, 0x00c0, 0x358b,
+	0x6008, 0xc0a4, 0x600a, 0x6820, 0xd084, 0x00c0, 0x3597, 0x6800,
+	0xa005, 0x00c0, 0x3594, 0x6002, 0x6006, 0x0078, 0x359b, 0x705c,
+	0x2060, 0x6800, 0x6002, 0x2061, 0x4f00, 0x6887, 0x0103, 0x2d08,
+	0x206b, 0x0000, 0x6068, 0xa005, 0x616a, 0x0040, 0x35aa, 0x2d02,
+	0x0078, 0x35ab, 0x616e, 0x7200, 0xa286, 0x0030, 0x0040, 0x35bb,
+	0xa286, 0x0040, 0x00c0, 0x2a0c, 0x7003, 0x0002, 0x704c, 0x2068,
+	0x68c4, 0x2060, 0x007c, 0x7003, 0x0002, 0x70bc, 0xa06d, 0x68bc,
+	0x7042, 0x70b8, 0xa065, 0x68c0, 0x705a, 0x2d00, 0x704e, 0xad80,
+	0x0009, 0x7046, 0x007c, 0xa282, 0x0004, 0x0048, 0x35d1, 0x1078,
+	0x29b2, 0x2200, 0x0079, 0x35d4, 0x35d8, 0x35e9, 0x35f6, 0x35e9,
+	0xa586, 0x1300, 0x0040, 0x35e9, 0xa586, 0x8300, 0x00c0, 0x35cf,
+	0x7003, 0x0000, 0x6018, 0x8001, 0x601a, 0x6008, 0xa084, 0xfbef,
+	0x600a, 0x7000, 0xa086, 0x0005, 0x0040, 0x35f3, 0x1078, 0x4118,
+	0x781b, 0x0078, 0x007c, 0x781b, 0x0079, 0x007c, 0x7890, 0x8007,
+	0x8001, 0xa084, 0x0007, 0xa080, 0x0018, 0x789a, 0x79a8, 0xa18c,
+	0x00ff, 0xa186, 0x0003, 0x0040, 0x360b, 0xa186, 0x0000, 0x0040,
+	0x360b, 0x0078, 0x4107, 0x781b, 0x0079, 0x007c, 0x6820, 0xc095,
+	0x6822, 0x82ff, 0x00c0, 0x3618, 0x1078, 0x4118, 0x0078, 0x361f,
+	0x8211, 0x0040, 0x361d, 0x1078, 0x29b2, 0x1078, 0x412b, 0x781b,
+	0x0078, 0x007c, 0x1078, 0x43d3, 0x7830, 0xa084, 0x00c0, 0x00c0,
+	0x3645, 0x017e, 0x3208, 0x007e, 0x2001, 0x4f04, 0x2004, 0xd0ec,
+	0x007f, 0x0040, 0x3637, 0xa18c, 0x0300, 0x0078, 0x3639, 0xa18c,
+	0x0400, 0x017f, 0x0040, 0x3640, 0x0018, 0x3645, 0x0078, 0x3642,
+	0x0028, 0x3645, 0x791a, 0xa006, 0x007c, 0xa085, 0x0001, 0x007c,
+	0xa684, 0x0060, 0x00c0, 0x3652, 0x682f, 0x0000, 0x6833, 0x0000,
+	0x0078, 0x36c1, 0xd6dc, 0x00c0, 0x366a, 0x68b4, 0xd0dc, 0x00c0,
+	0x366a, 0x6998, 0x6a94, 0x692e, 0x6a32, 0x7048, 0xa005, 0x00c0,
+	0x3667, 0x2200, 0xa105, 0x0040, 0x45d6, 0x704b, 0x0015, 0x0078,
+	0x45d6, 0x007c, 0xd6ac, 0x0040, 0x3690, 0xd6f4, 0x0040, 0x3676,
+	0x682f, 0x0000, 0x6833, 0x0000, 0x0078, 0x45d6, 0x68b4, 0xa084,
+	0x4000, 0xa635, 0xd6f4, 0x00c0, 0x3670, 0x7048, 0xa005, 0x00c0,
+	0x3683, 0x704b, 0x0015, 0xd6dc, 0x00c0, 0x368c, 0x68b4, 0xd0dc,
+	0x0040, 0x368c, 0x6ca8, 0x6da4, 0x6c2e, 0x6d32, 0x0078, 0x45d6,
+	0xd6f4, 0x0040, 0x3699, 0x682f, 0x0000, 0x6833, 0x0000, 0x0078,
+	0x45d6, 0x68b4, 0xa084, 0x4800, 0xa635, 0xd6f4, 0x00c0, 0x3693,
+	0x7048, 0xa005, 0x00c0, 0x36a6, 0x704b, 0x0015, 0x2408, 0x2510,
+	0x2700, 0x80fb, 0x00c8, 0x36ad, 0x8000, 0xa084, 0x003f, 0xa108,
+	0xa291, 0x0000, 0x692e, 0x6a32, 0x2100, 0xa205, 0x00c0, 0x36ba,
+	0x0078, 0x45d6, 0x7000, 0xa086, 0x0006, 0x0040, 0x36c1, 0x0078,
+	0x45d6, 0x007c, 0x6946, 0x6008, 0xc0cd, 0xd3cc, 0x0040, 0x36c9,
+	0xc08d, 0x600a, 0x6818, 0x683a, 0x681b, 0x0006, 0x688f, 0x0000,
+	0x6893, 0x0000, 0x6a30, 0x692c, 0x6a3e, 0x6942, 0x682f, 0x0003,
+	0x6833, 0x0000, 0x6837, 0x0020, 0x6897, 0x0000, 0x689b, 0x0020,
+	0x7000, 0x0079, 0x36e3, 0x2a0c, 0x36f5, 0x36ed, 0x36eb, 0x36eb,
+	0x36eb, 0x36eb, 0x36eb, 0x1078, 0x29b2, 0x6820, 0xd084, 0x00c0,
+	0x36f5, 0x1078, 0x3e19, 0x0078, 0x36fb, 0x705c, 0x2c50, 0x2060,
+	0x6800, 0x6002, 0x2a60, 0x3208, 0xa18c, 0x0300, 0x0040, 0x3704,
+	0x2021, 0x4f58, 0x0078, 0x3706, 0x2021, 0x4f98, 0x2404, 0xa005,
+	0x0040, 0x370d, 0x2020, 0x0078, 0x3706, 0x2d22, 0x206b, 0x0000,
+	0x007c, 0x1078, 0x3e20, 0x1078, 0x3e36, 0x6008, 0xc0cc, 0x600a,
+	0x682b, 0x0000, 0x789b, 0x000e, 0x6f14, 0x6938, 0x691a, 0x6944,
+	0x6916, 0x3208, 0xa18c, 0x0300, 0x0040, 0x372a, 0x2009, 0x0000,
+	0x0078, 0x372c, 0x2009, 0x0001, 0x1078, 0x4a81, 0xd6dc, 0x0040,
+	0x3734, 0x691c, 0xc1ed, 0x691e, 0x6818, 0xd0fc, 0x0040, 0x3743,
+	0x7868, 0xa08c, 0x00ff, 0x0040, 0x3741, 0x681b, 0x001e, 0x0078,
+	0x3743, 0x681b, 0x0000, 0xb284, 0x0300, 0x00c0, 0x374b, 0x2021,
+	0x4f98, 0x0078, 0x374d, 0x2021, 0x4f58, 0x6800, 0x2022, 0x6a3c,
+	0x6940, 0x6a32, 0x692e, 0x68c0, 0x2060, 0x6000, 0xd0a4, 0x0040,
+	0x378d, 0x2041, 0x0021, 0x2049, 0x0005, 0x2051, 0x0020, 0x0d7e,
+	0x0f7e, 0x157e, 0x147e, 0x2079, 0x4f00, 0x1078, 0x1e46, 0x147f,
+	0x157f, 0x0f7f, 0x70cc, 0x2010, 0x2009, 0x0101, 0x027e, 0x2204,
+	0xa06d, 0x0040, 0x377d, 0x6814, 0xa706, 0x0040, 0x377a, 0x6800,
+	0x0078, 0x3770, 0x6820, 0xc0d5, 0x6822, 0x027f, 0x8210, 0x8109,
+	0x00c0, 0x376e, 0x0d7f, 0x7067, 0x0003, 0x707f, 0x0000, 0x7776,
+	0x7083, 0x000f, 0x71d4, 0xc1dc, 0x71d6, 0x6818, 0xa086, 0x0002,
+	0x00c0, 0x3799, 0x6817, 0x0000, 0x682b, 0x0000, 0x681c, 0xc0ec,
+	0x681e, 0x1078, 0x2073, 0x0078, 0x2a0c, 0x7cd8, 0x7ddc, 0x7fd0,
+	0x1078, 0x3648, 0x682b, 0x0000, 0x789b, 0x000e, 0x6f14, 0x1078,
+	0x43d7, 0xa08c, 0x00ff, 0x6916, 0x6818, 0xd0fc, 0x0040, 0x37b2,
+	0x7048, 0x681a, 0xa68c, 0xdf00, 0x691e, 0x7067, 0x0000, 0x0078,
+	0x2a0c, 0x7000, 0xa005, 0x00c0, 0x37bf, 0x0078, 0x2a0c, 0xa006,
+	0x1078, 0x45d6, 0x6920, 0xd1ac, 0x00c0, 0x37c8, 0x681b, 0x0014,
+	0xa68c, 0xdf00, 0x691e, 0x682b, 0x0000, 0x6820, 0xa084, 0x00ff,
+	0x6822, 0x7000, 0x0079, 0x37d4, 0x2a0c, 0x37de, 0x37de, 0x37e1,
+	0x37e1, 0x37e1, 0x37dc, 0x37dc, 0x1078, 0x29b2, 0x6818, 0x0078,
+	0x3443, 0x6008, 0xc0a4, 0x600a, 0x6817, 0x0000, 0x0078, 0x3dde,
+	0x2300, 0x0079, 0x37eb, 0x37ee, 0x37f0, 0x3860, 0x1078, 0x29b2,
+	0xd6fc, 0x00c0, 0x3847, 0x7000, 0xa00d, 0x0079, 0x37f7, 0x2a0c,
+	0x3801, 0x3801, 0x3831, 0x3801, 0x3844, 0x37ff, 0x37ff, 0x1078,
+	0x29b2, 0xa684, 0x0060, 0x0040, 0x3831, 0xa086, 0x0060, 0x00c0,
+	0x382e, 0xc6ac, 0xc6f4, 0xc6ed, 0x7e5a, 0x6eb6, 0x681c, 0xc0ac,
+	0x681e, 0xa186, 0x0002, 0x0040, 0x3820, 0x1078, 0x45d6, 0x69ac,
+	0x68b0, 0xa115, 0x0040, 0x3820, 0x1078, 0x4977, 0x0078, 0x3822,
+	0x1078, 0x493f, 0x781b, 0x0079, 0x71d4, 0xd1b4, 0x00c0, 0x2a08,
+	0x70a4, 0xa086, 0x0001, 0x00c0, 0x2a52, 0x007c, 0xd6ec, 0x0040,
+	0x380b, 0x6818, 0xd0fc, 0x0040, 0x3844, 0xd6f4, 0x00c0, 0x383e,
+	0x681b, 0x0015, 0x781b, 0x0079, 0x0078, 0x2a08, 0x681b, 0x0007,
+	0x682f, 0x0000, 0x6833, 0x0000, 0x1078, 0x4369, 0x007c, 0xc6fc,
+	0x7e5a, 0x7adc, 0x79d8, 0x78d0, 0x801b, 0x00c8, 0x3850, 0x8000,
+	0xa084, 0x003f, 0xa108, 0xa291, 0x0000, 0x6b98, 0x2100, 0xa302,
+	0x68b2, 0x6b94, 0x2200, 0xa303, 0x68ae, 0x781b, 0x0079, 0x007c,
+	0x1078, 0x29b2, 0x2300, 0x0079, 0x3865, 0x386a, 0x388f, 0x38ef,
+	0x1078, 0x29b2, 0x7000, 0x0079, 0x386d, 0x3875, 0x3877, 0x3880,
+	0x3875, 0x3875, 0x3875, 0x3875, 0x3875, 0x1078, 0x29b2, 0x69ac,
+	0x68b0, 0xa115, 0x0040, 0x3880, 0x1078, 0x4977, 0x0078, 0x3882,
+	0x1078, 0x493f, 0x681c, 0xc0b4, 0x681e, 0x70d4, 0xd0b4, 0x00c0,
+	0x2a08, 0x70a4, 0xa086, 0x0001, 0x00c0, 0x2a52, 0x007c, 0xd6fc,
+	0x00c0, 0x38df, 0x7000, 0xa00d, 0x0079, 0x3896, 0x2a0c, 0x38a6,
+	0x38a0, 0x38d6, 0x38a6, 0x38dc, 0x389e, 0x389e, 0x1078, 0x29b2,
+	0x6894, 0x78d6, 0x78de, 0x6898, 0x78d2, 0x78da, 0xa684, 0x0060,
+	0x0040, 0x38d6, 0xa086, 0x0060, 0x00c0, 0x38d3, 0xa6b4, 0xbfbf,
+	0xc6ed, 0x7e5a, 0x6eb6, 0xa186, 0x0002, 0x0040, 0x38c2, 0x1078,
+	0x45d6, 0x69ac, 0x68b0, 0xa115, 0x0040, 0x38c2, 0x1078, 0x4977,
+	0x0078, 0x38c4, 0x1078, 0x493f, 0x781b, 0x0079, 0x681c, 0xc0b4,
+	0x681e, 0x71d4, 0xd1b4, 0x00c0, 0x2a08, 0x70a4, 0xa086, 0x0001,
+	0x00c0, 0x2a52, 0x007c, 0xd6ec, 0x0040, 0x38b0, 0x6818, 0xd0fc,
+	0x0040, 0x38dc, 0x681b, 0x0007, 0x781b, 0x00f9, 0x007c, 0xc6fc,
+	0x7e5a, 0x7adc, 0x79d8, 0x6b98, 0x2100, 0xa302, 0x68b2, 0x6b94,
+	0x2200, 0xa303, 0x68ae, 0x79d2, 0x781b, 0x0079, 0x007c, 0xd6dc,
+	0x0040, 0x38f8, 0x782b, 0x3009, 0x781b, 0x0079, 0x0078, 0x2a08,
+	0x7884, 0xc0ac, 0x7886, 0x78e4, 0xa084, 0x0008, 0x00c0, 0x390b,
+	0xa484, 0x0200, 0x0040, 0x3905, 0xc6f5, 0xc6dd, 0x7e5a, 0x781b,
+	0x0079, 0x0078, 0x2a08, 0x6820, 0xc095, 0x6822, 0x1078, 0x42e2,
+	0xc6dd, 0x1078, 0x4118, 0x781b, 0x0078, 0x0078, 0x2a08, 0x2300,
+	0x0079, 0x391a, 0x391d, 0x391f, 0x3921, 0x1078, 0x29b2, 0x0078,
+	0x4111, 0xd6d4, 0x00c0, 0x395c, 0x79e4, 0xd1ac, 0x0040, 0x392f,
+	0x78ec, 0xa084, 0x0003, 0x0040, 0x392f, 0x782b, 0x3009, 0x789b,
+	0x0060, 0x78ab, 0x0000, 0xa684, 0xfffb, 0x785a, 0x79e4, 0xd1ac,
+	0x0040, 0x393f, 0x78ec, 0xa084, 0x0003, 0x00c0, 0x3958, 0x2001,
+	0x4f04, 0x2004, 0xd0e4, 0x00c0, 0x3954, 0x6820, 0xd0c4, 0x0040,
+	0x3954, 0x0c7e, 0x7058, 0x2060, 0x6004, 0xc09d, 0x6006, 0x6008,
+	0xa084, 0x00ff, 0x600a, 0x0c7f, 0x2001, 0x0014, 0x0078, 0x3443,
+	0xa184, 0x0007, 0x0079, 0x3992, 0x7a90, 0xa294, 0x0007, 0x789b,
+	0x0060, 0x79a8, 0x81ff, 0x0040, 0x3990, 0x789b, 0x0010, 0x7ba8,
+	0xa384, 0x0001, 0x00c0, 0x3983, 0x7ba8, 0x7ba8, 0xa386, 0x0001,
+	0x00c0, 0x3976, 0x2009, 0xfff7, 0x0078, 0x397c, 0xa386, 0x0003,
+	0x00c0, 0x3983, 0x2009, 0xffef, 0x0c7e, 0x7058, 0x2060, 0x6004,
+	0xa104, 0x6006, 0x0c7f, 0x789b, 0x0060, 0x78ab, 0x0000, 0xa684,
+	0xfffb, 0x785a, 0x782b, 0x3009, 0x6920, 0xa18c, 0xfcff, 0x6922,
+	0x0078, 0x435d, 0x30d9, 0x30e3, 0x399c, 0x39a2, 0x399a, 0x399a,
+	0x435d, 0x435d, 0x1078, 0x29b2, 0x6920, 0xa18c, 0xfcff, 0x6922,
+	0x0078, 0x4363, 0x6920, 0xa18c, 0xfcff, 0x6922, 0x0078, 0x435d,
+	0x79e4, 0xa184, 0x0030, 0x0040, 0x39b2, 0x78ec, 0xa084, 0x0003,
+	0x00c0, 0x39e6, 0x7000, 0xa086, 0x0004, 0x00c0, 0x39cc, 0x7064,
+	0xa086, 0x0002, 0x00c0, 0x39c2, 0x2011, 0x0002, 0x2019, 0x0000,
+	0x0078, 0x2f65, 0x7064, 0xa086, 0x0006, 0x0040, 0x39bc, 0x7064,
+	0xa086, 0x0004, 0x0040, 0x39bc, 0x7000, 0xa086, 0x0000, 0x0040,
+	0x2a08, 0x6920, 0xa184, 0x0420, 0x0040, 0x39db, 0xc1d4, 0x6922,
+	0x6818, 0x0078, 0x3443, 0x6818, 0xa08e, 0x0002, 0x0040, 0x39e4,
+	0xc0fd, 0x681a, 0x2001, 0x0014, 0x0078, 0x3443, 0xa184, 0x0007,
+	0x0079, 0x39ea, 0x435d, 0x435d, 0x39f2, 0x435d, 0x43a5, 0x43a5,
+	0x435d, 0x435d, 0xd6bc, 0x0040, 0x3a34, 0x7184, 0x81ff, 0x0040,
+	0x3a34, 0xa182, 0x000d, 0x00d0, 0x3a01, 0x7087, 0x0000, 0x0078,
+	0x3a06, 0xa182, 0x000c, 0x7086, 0x2009, 0x000c, 0x789b, 0x0061,
+	0x79aa, 0x157e, 0x137e, 0x147e, 0x7088, 0x8114, 0xa210, 0x728a,
+	0xa080, 0x000b, 0xad00, 0x2098, 0xb284, 0x0300, 0x0040, 0x3a28,
+	0x007e, 0x2001, 0x4f04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x3a24,
+	0x20a1, 0x012b, 0x0078, 0x3a2a, 0x20a1, 0x022b, 0x0078, 0x3a2a,
+	0x20a1, 0x012b, 0x789b, 0x0000, 0x8108, 0x81ac, 0x53a6, 0x147f,
+	0x137f, 0x157f, 0x0078, 0x4363, 0xd6d4, 0x00c0, 0x3a88, 0x6820,
+	0xd084, 0x0040, 0x4363, 0xa68c, 0x0060, 0xa684, 0x0060, 0x0040,
+	0x3a46, 0xa086, 0x0060, 0x00c0, 0x3a46, 0xc1f5, 0xc194, 0x795a,
+	0x69b6, 0x789b, 0x0060, 0x78ab, 0x0000, 0x789b, 0x0061, 0x6818,
+	0xc0fd, 0x681a, 0x78aa, 0x8008, 0x810c, 0x0040, 0x3e4f, 0xa18c,
+	0x00f8, 0x00c0, 0x3e4f, 0x157e, 0x137e, 0x147e, 0x017e, 0x3208,
+	0xa18c, 0x0300, 0x0040, 0x3a74, 0x007e, 0x2001, 0x4f04, 0x2004,
+	0xd0ec, 0x007f, 0x0040, 0x3a70, 0x20a1, 0x012b, 0x0078, 0x3a76,
+	0x20a1, 0x022b, 0x0078, 0x3a76, 0x20a1, 0x012b, 0x017f, 0x789b,
+	0x0000, 0x8000, 0x80ac, 0xad80, 0x000b, 0x2098, 0x53a6, 0x147f,
+	0x137f, 0x157f, 0x6814, 0xc0fc, 0x8007, 0x7882, 0x0078, 0x4363,
+	0x6818, 0xd0fc, 0x0040, 0x3a8e, 0x681b, 0x0008, 0x6820, 0xc0ad,
+	0x6822, 0x1078, 0x4120, 0x781b, 0x00ea, 0x007c, 0x2300, 0x0079,
+	0x3a99, 0x3a9e, 0x3b76, 0x3a9c, 0x1078, 0x29b2, 0x7cd8, 0x7ddc,
+	0x7fd0, 0x82ff, 0x00c0, 0x3ac7, 0x7200, 0xa286, 0x0003, 0x0040,
+	0x3410, 0x71d4, 0xd1bc, 0x00c0, 0x3aca, 0xd1b4, 0x0040, 0x3aca,
+	0x0d7e, 0x783b, 0x8800, 0x781b, 0x004c, 0x70bc, 0xa06d, 0x68b4,
+	0xc0a5, 0x785a, 0x6894, 0x78d6, 0x78de, 0x6898, 0x78d2, 0x78da,
+	0xc1b4, 0x71d6, 0x7003, 0x0030, 0x0d7f, 0x0078, 0x3ace, 0x7200,
+	0x0078, 0x3ace, 0x783b, 0x1800, 0x781b, 0x004a, 0xa284, 0x000f,
+	0x0079, 0x3ad2, 0x3b61, 0x3b10, 0x3adc, 0x343f, 0x3ada, 0x3b61,
+	0x3ada, 0x3ada, 0x1078, 0x29b2, 0x681c, 0xd0ec, 0x0040, 0x3ae3,
+	0x6008, 0xc08d, 0x600a, 0x6920, 0xc185, 0x6922, 0x6800, 0x6006,
+	0xa005, 0x00c0, 0x3aec, 0x6002, 0x6008, 0xc0d4, 0x600a, 0x681c,
+	0xa084, 0x000e, 0x00c0, 0x3b00, 0xb284, 0x0300, 0x0040, 0x3afc,
+	0x2009, 0x95c0, 0x0078, 0x3b05, 0x2009, 0x96d0, 0x0078, 0x3b05,
+	0x7030, 0x68ba, 0x7140, 0x70cc, 0xa108, 0x2104, 0x6802, 0x2d0a,
+	0x715e, 0xd6dc, 0x00c0, 0x3b10, 0xc6fc, 0x6eb6, 0x0078, 0x3b61,
+	0x6eb6, 0xa684, 0x0060, 0x00c0, 0x3b1a, 0xa684, 0x7fff, 0x68b6,
+	0x0078, 0x3b61, 0xd6dc, 0x00c0, 0x3b28, 0xa684, 0x7fff, 0x68b6,
+	0x6894, 0x68a6, 0x6898, 0x68aa, 0x1078, 0x45d6, 0x0078, 0x3b61,
+	0xd6ac, 0x0040, 0x3b34, 0xa006, 0x1078, 0x45d6, 0x2408, 0x2510,
+	0x69aa, 0x6aa6, 0x0078, 0x3b44, 0x2408, 0x2510, 0x2700, 0x801b,
+	0x00c8, 0x3b3b, 0x8000, 0xa084, 0x003f, 0xa108, 0xa291, 0x0000,
+	0x69aa, 0x6aa6, 0x1078, 0x45d6, 0xd6fc, 0x0040, 0x3b61, 0xa684,
+	0x7fff, 0x68b6, 0x2510, 0x2408, 0xd6ac, 0x00c0, 0x3b59, 0x2700,
+	0x801b, 0x00c8, 0x3b54, 0x8000, 0xa084, 0x003f, 0xa108, 0xa291,
+	0x0000, 0x6b98, 0x2100, 0xa302, 0x68b2, 0x6b94, 0x2200, 0xa303,
+	0x68ae, 0x7000, 0xa086, 0x0030, 0x00c0, 0x2a0c, 0x7003, 0x0002,
+	0x70bc, 0xa06d, 0x68bc, 0x7042, 0x70b8, 0xa065, 0x68c0, 0x705a,
+	0x2d00, 0x704e, 0xad80, 0x0009, 0x7046, 0x007c, 0xa586, 0x8800,
+	0x00c0, 0x3b83, 0x7003, 0x0000, 0x6018, 0x8001, 0x601a, 0x6008,
+	0xa084, 0xfbef, 0x600a, 0x0078, 0x4111, 0x7047, 0x0000, 0xa282,
+	0x0006, 0x0050, 0x3b8d, 0x1078, 0x29b2, 0x2300, 0x0079, 0x3b90,
+	0x3b93, 0x3ba5, 0x3bb1, 0x2200, 0x0079, 0x3b96, 0x3b9c, 0x4111,
+	0x3b9e, 0x3b9c, 0x3beb, 0x3c40, 0x1078, 0x29b2, 0x7a80, 0xa294,
+	0x0f00, 0x1078, 0x3cca, 0x0078, 0x4107, 0x1078, 0x3bc2, 0x0079,
+	0x3ba9, 0x4111, 0x3baf, 0x3baf, 0x3beb, 0x3baf, 0x4111, 0x1078,
+	0x29b2, 0x1078, 0x3bc2, 0x0079, 0x3bb5, 0x3bbd, 0x3bbb, 0x3bbb,
+	0x3bbd, 0x3bbb, 0x3bbd, 0x1078, 0x29b2, 0x1078, 0x412b, 0x781b,
+	0x0078, 0x007c, 0x7000, 0xa086, 0x0002, 0x00c0, 0x3bd3, 0x1078,
+	0x3e36, 0x0078, 0x3bcd, 0x1078, 0x45d6, 0x6008, 0xa084, 0xfbef,
+	0x600a, 0x0078, 0x3bd8, 0x7000, 0xa086, 0x0003, 0x0040, 0x3bcb,
+	0x7003, 0x0005, 0xb284, 0x0300, 0x0040, 0x3be2, 0x2001, 0x96e0,
+	0x0078, 0x3be4, 0x2001, 0x9712, 0x2068, 0x704e, 0xad80, 0x0009,
+	0x7046, 0x2200, 0x007c, 0x7000, 0xa086, 0x0002, 0x00c0, 0x3bfd,
+	0x70d4, 0xc0b5, 0x70d6, 0x2c00, 0x70ba, 0x2d00, 0x70be, 0x0078,
+	0x3c02, 0x1078, 0x45d6, 0x0078, 0x3c02, 0x7000, 0xa086, 0x0003,
+	0x0040, 0x3bf9, 0x7003, 0x0001, 0x7a80, 0xa294, 0x0f00, 0x789b,
+	0x0018, 0x7ca8, 0xa484, 0x001f, 0xa215, 0x2069, 0x95c0, 0xb284,
+	0x0300, 0x00c0, 0x3c16, 0xc2fd, 0x2069, 0x96d0, 0x2d04, 0x2d08,
+	0x715e, 0xa06d, 0x0040, 0x3c23, 0x6814, 0xa206, 0x0040, 0x3c25,
+	0x6800, 0x0078, 0x3c17, 0x1078, 0x3cca, 0x6eb4, 0x7e5a, 0x6920,
+	0xa184, 0x0c00, 0x0040, 0x3cf4, 0x7064, 0xa086, 0x0006, 0x00c0,
+	0x3c37, 0x7074, 0xa206, 0x00c0, 0x3c37, 0x7066, 0x707e, 0x681b,
+	0x0005, 0xc1ad, 0xc1d4, 0x6922, 0x1078, 0x4120, 0x0078, 0x3cf4,
+	0x7200, 0xa286, 0x0002, 0x00c0, 0x3c52, 0x70d4, 0xc0b5, 0x70d6,
+	0x2c00, 0x70ba, 0x2d00, 0x70be, 0x0078, 0x3c56, 0x1078, 0x45d6,
+	0x0078, 0x3c56, 0xa286, 0x0003, 0x0040, 0x3c4e, 0x7003, 0x0001,
+	0x7a80, 0xa294, 0x0f00, 0x789b, 0x0018, 0x7ca8, 0xa484, 0x001f,
+	0xa215, 0xb284, 0x0300, 0x00c0, 0x3c66, 0xc2fd, 0x79a8, 0x79a8,
+	0xa18c, 0x00ff, 0x2118, 0x70cc, 0xa168, 0x2d04, 0x2d08, 0x715e,
+	0xa06d, 0x0040, 0x3c7a, 0x6814, 0xa206, 0x0040, 0x3ca3, 0x6800,
+	0x0078, 0x3c6e, 0x7003, 0x0005, 0xb284, 0x0300, 0x0040, 0x3c84,
+	0x2001, 0x96e0, 0x0078, 0x3c86, 0x2001, 0x9712, 0x2068, 0x704e,
+	0x157e, 0x20a9, 0x0032, 0x2003, 0x0000, 0x8000, 0x00f0, 0x3c8b,
+	0x157f, 0xb284, 0x0300, 0x0040, 0x3c98, 0xc2fc, 0x0078, 0x3c99,
+	0xc2fd, 0x6a16, 0xad80, 0x0009, 0x7046, 0x68b7, 0x0700, 0x6823,
+	0x0800, 0x6827, 0x0003, 0x6eb4, 0x6920, 0xa184, 0x0c00, 0x0040,
+	0x3cf4, 0xd0dc, 0x0040, 0x3cbf, 0x7064, 0xa086, 0x0004, 0x00c0,
+	0x3cbb, 0x7074, 0xa206, 0x00c0, 0x3cbb, 0x7078, 0xa306, 0x00c0,
+	0x3cbb, 0x7066, 0x707e, 0x1078, 0x4127, 0x0078, 0x3cf4, 0x681b,
+	0x0005, 0xc1ad, 0xc1d4, 0x6922, 0x1078, 0x4120, 0x707f, 0x0000,
+	0x0078, 0x3cf4, 0x7003, 0x0005, 0xb284, 0x0300, 0x0040, 0x3cd4,
+	0x2001, 0x96e0, 0x0078, 0x3cd6, 0x2001, 0x9712, 0x2068, 0x704e,
+	0x157e, 0x20a9, 0x0032, 0x2003, 0x0000, 0x8000, 0x00f0, 0x3cdb,
+	0x157f, 0xb284, 0x0300, 0x0040, 0x3ce8, 0xc2fc, 0x0078, 0x3ce9,
+	0xc2fd, 0x6a16, 0xad80, 0x0009, 0x7046, 0x68b7, 0x0700, 0x6823,
+	0x0800, 0x6827, 0x0003, 0x007c, 0xc6ec, 0xa6ac, 0x0060, 0x0040,
+	0x3d46, 0x6b98, 0x6c94, 0x69ac, 0x68b0, 0xa105, 0x00c0, 0x3d21,
+	0x7bd2, 0x7bda, 0x7cd6, 0x7cde, 0xa586, 0x0060, 0x0040, 0x3d4b,
+	0xd6f4, 0x00c0, 0x3d0c, 0xc6ed, 0xa6b4, 0xb7ff, 0x7e5a, 0x2009,
+	0x0079, 0xd69c, 0x0040, 0x3d19, 0x2009, 0x0078, 0x2019, 0x0000,
+	0x2320, 0x791a, 0xd6ec, 0x0040, 0x3d56, 0x1078, 0x493f, 0x0078,
+	0x3d56, 0x68b0, 0xa31a, 0x2100, 0xa423, 0x2400, 0xa305, 0x0040,
+	0x3d4d, 0x7bd2, 0x7bda, 0x7cd6, 0x7cde, 0x68b0, 0xd6f4, 0x00c0,
+	0x3d32, 0xc6ed, 0xc6f4, 0x7e5a, 0x2011, 0x0079, 0xd69c, 0x0040,
+	0x3d3e, 0x2011, 0x0078, 0x2019, 0x0000, 0x2320, 0x7a1a, 0xd6ec,
+	0x0040, 0x3d56, 0x1078, 0x4977, 0x0078, 0x3d56, 0x2019, 0x0000,
+	0x2320, 0x0078, 0x3d4d, 0xa6b4, 0xb7ff, 0x7e5a, 0x2009, 0x0079,
+	0xd69c, 0x0040, 0x3d55, 0x2009, 0x0078, 0x791a, 0x68c0, 0x705a,
+	0x2d00, 0x704e, 0x68c4, 0x2060, 0x71d4, 0x2001, 0x4f01, 0x2004,
+	0xd0c4, 0x00c0, 0x3dab, 0x70d8, 0xa02d, 0x0040, 0x3d84, 0xd1bc,
+	0x0040, 0x3d9e, 0x7a80, 0xa294, 0x0f00, 0x70dc, 0xa206, 0x0040,
+	0x3d75, 0x78e0, 0xa504, 0x00c0, 0x3dab, 0x70da, 0xc1bc, 0x71d6,
+	0x0078, 0x3dab, 0x2031, 0x0001, 0x852c, 0x0048, 0x3d83, 0x8633,
+	0x8210, 0x0078, 0x3d7c, 0x007c, 0x7de0, 0xa594, 0xff00, 0x0040,
+	0x3d91, 0x2011, 0x0008, 0x852f, 0x1078, 0x3d7a, 0x8637, 0x0078,
+	0x3d93, 0x1078, 0x3d7a, 0x8217, 0x7880, 0xa084, 0x0f00, 0xa206,
+	0x0040, 0x3dab, 0x72de, 0x76da, 0x0078, 0x3dab, 0x7a80, 0xa294,
+	0x0f00, 0x70dc, 0xa236, 0x0040, 0x3d9b, 0x78e0, 0xa534, 0x0040,
+	0x3d9b, 0xc1bd, 0x71d6, 0xd1b4, 0x00c0, 0x2a08, 0x2300, 0xa405,
+	0x0040, 0x2a08, 0x70a4, 0xa086, 0x0001, 0x00c0, 0x2a52, 0x007c,
+	0x6020, 0xa005, 0x0040, 0x3dc6, 0x8001, 0x6022, 0x6008, 0xa085,
+	0x0008, 0x600a, 0x700f, 0x0100, 0x702c, 0x6026, 0x007c, 0xa006,
+	0x1078, 0x45d6, 0x7000, 0xa086, 0x0002, 0x0040, 0x3dd4, 0x7064,
+	0xa086, 0x0005, 0x00c0, 0x3dde, 0x682b, 0x0000, 0x6817, 0x0000,
+	0x681b, 0x0001, 0x6823, 0x0040, 0x681f, 0x0100, 0x7000, 0xa084,
+	0x000f, 0x0079, 0x3de3, 0x2a0c, 0x3df3, 0x3ded, 0x3e15, 0x3dfd,
+	0x2a0c, 0x3deb, 0x3deb, 0x1078, 0x29b2, 0x1078, 0x3e20, 0x1078,
+	0x3e19, 0x0078, 0x3df9, 0x1078, 0x3e20, 0x705c, 0x2060, 0x6800,
+	0x6002, 0x1078, 0x2073, 0x0078, 0x2a0c, 0x7064, 0x7067, 0x0000,
+	0x7083, 0x0000, 0x0079, 0x3e04, 0x3e11, 0x3e11, 0x3e0c, 0x3e0c,
+	0x3e0c, 0x3e11, 0x3e0c, 0x3e11, 0x77d4, 0xc7dd, 0x77d6, 0x0079,
+	0x2f7e, 0x7067, 0x0000, 0x0078, 0x2a0c, 0x681b, 0x0000, 0x0078,
+	0x3711, 0x6800, 0xa005, 0x00c0, 0x3e1e, 0x6002, 0x6006, 0x007c,
+	0x6410, 0x84ff, 0x0040, 0x3e32, 0x2009, 0x4f02, 0x2104, 0x8001,
+	0x200a, 0x8421, 0x6412, 0x00c0, 0x3e32, 0x2021, 0x4f04, 0x2404,
+	0xc0a5, 0x2022, 0x6008, 0xc0a4, 0x600a, 0x007c, 0x6018, 0xa005,
+	0x0040, 0x3e3c, 0x8001, 0x601a, 0x007c, 0x1078, 0x43d3, 0x681b,
+	0x0018, 0x0078, 0x3e7d, 0x1078, 0x43d3, 0x681b, 0x0019, 0x0078,
+	0x3e7d, 0x1078, 0x43d3, 0x681b, 0x001a, 0x0078, 0x3e7d, 0x1078,
+	0x43d3, 0x681b, 0x0003, 0x0078, 0x3e7d, 0x7774, 0x1078, 0x424e,
+	0x7178, 0xa18c, 0x00ff, 0x3210, 0xa294, 0x0300, 0x0040, 0x3e64,
+	0xa1e8, 0x94c0, 0x0078, 0x3e66, 0xa1e8, 0x95d0, 0x2d04, 0x2d08,
+	0x2068, 0xa005, 0x00c0, 0x3e6f, 0x707e, 0x0078, 0x2a0c, 0x6814,
+	0x7274, 0xa206, 0x0040, 0x3e77, 0x6800, 0x0078, 0x3e67, 0x6800,
+	0x200a, 0x681b, 0x0005, 0x707f, 0x0000, 0x1078, 0x3e20, 0x6820,
+	0xd084, 0x00c0, 0x3e85, 0x1078, 0x3e19, 0x1078, 0x3e36, 0x681f,
+	0x0000, 0x6823, 0x0020, 0x1078, 0x2073, 0x0078, 0x2a0c, 0xa282,
+	0x0003, 0x00c0, 0x4107, 0x7da8, 0xa5ac, 0x00ff, 0x7e5a, 0x7ea8,
+	0xa6b4, 0x00ff, 0x6920, 0xc1bd, 0x6922, 0xd1c4, 0x0040, 0x3eea,
+	0xc1c4, 0x6922, 0xa6b4, 0x00ff, 0x0040, 0x3ed7, 0xa682, 0x000c,
+	0x0048, 0x3eae, 0x0040, 0x3eae, 0x2031, 0x000c, 0x2500, 0xa086,
+	0x000a, 0x0040, 0x3eb5, 0x852b, 0x852b, 0x1078, 0x41e0, 0x0040,
+	0x3ebd, 0x1078, 0x3fbc, 0x0078, 0x3ee0, 0x1078, 0x419b, 0x0c7e,
+	0x2960, 0x6004, 0xa084, 0xfff5, 0x6006, 0x1078, 0x3ff2, 0x0c7f,
+	0x6920, 0xc1c5, 0x6922, 0x7e58, 0xc695, 0x7e5a, 0xd6d4, 0x00c0,
+	0x3ed4, 0x781b, 0x0064, 0x007c, 0x781b, 0x0078, 0x007c, 0x0c7e,
+	0x2960, 0x6004, 0xa084, 0xfff5, 0x6006, 0x1078, 0x3ff2, 0x0c7f,
+	0x7e58, 0xd6d4, 0x00c0, 0x3ee7, 0x781b, 0x0067, 0x007c, 0x781b,
+	0x0079, 0x007c, 0x0c7e, 0x7058, 0x2060, 0x6100, 0xd1e4, 0x0040,
+	0x3f33, 0x6208, 0x8217, 0xa294, 0x00ff, 0xa282, 0x000c, 0x0048,
+	0x3efd, 0x0040, 0x3efd, 0x2011, 0x000c, 0x2600, 0xa202, 0x00c8,
+	0x3f02, 0x2230, 0x6208, 0xa294, 0x00ff, 0x2001, 0x4f05, 0x2004,
+	0xd0e4, 0x00c0, 0x3f17, 0x78ec, 0xd0e4, 0x0040, 0x3f17, 0xa282,
+	0x000a, 0x00c8, 0x3f1d, 0x2011, 0x000a, 0x0078, 0x3f1d, 0xa282,
+	0x000c, 0x00c8, 0x3f1d, 0x2011, 0x000c, 0x2200, 0xa502, 0x00c8,
+	0x3f22, 0x2228, 0x1078, 0x419f, 0x2500, 0xa086, 0x000a, 0x0040,
+	0x3f2b, 0x852b, 0x852b, 0x1078, 0x41e0, 0x0040, 0x3f33, 0x1078,
+	0x3fbc, 0x0078, 0x3f37, 0x1078, 0x419b, 0x1078, 0x3ff2, 0x7858,
+	0xc095, 0x785a, 0x0c7f, 0x781b, 0x0078, 0x007c, 0x0c7e, 0x2960,
+	0x6000, 0xd0e4, 0x00c0, 0x3f58, 0xd0b4, 0x00c0, 0x3f52, 0x6010,
+	0xa084, 0x000f, 0x00c0, 0x3f52, 0x6104, 0xa18c, 0xfff5, 0x6106,
+	0x0c7f, 0x007c, 0x2011, 0x0032, 0x2019, 0x0000, 0x0078, 0x3f83,
+	0x68a0, 0xd0cc, 0x00c0, 0x3f52, 0x6208, 0xa294, 0x00ff, 0x2001,
+	0x4f05, 0x2004, 0xd0e4, 0x00c0, 0x3f71, 0x78ec, 0xd0e4, 0x0040,
+	0x3f71, 0xa282, 0x000b, 0x00c8, 0x3f71, 0x2011, 0x000a, 0x0078,
+	0x3f77, 0xa282, 0x000c, 0x00c8, 0x3f77, 0x2011, 0x000c, 0x6308,
+	0x831f, 0xa39c, 0x00ff, 0xa382, 0x000c, 0x0048, 0x3f83, 0x0040,
+	0x3f83, 0x2019, 0x000c, 0x78ab, 0x0001, 0x78ab, 0x0003, 0x78ab,
+	0x0001, 0x7aaa, 0x7baa, 0xa8c0, 0x0005, 0x6820, 0xc0c5, 0x6822,
+	0x70d4, 0xd0b4, 0x0040, 0x3f9f, 0xc0b4, 0x70d6, 0x70b8, 0xa065,
+	0x6008, 0xa084, 0xfbef, 0x600a, 0x6018, 0x8001, 0x601a, 0x0c7f,
+	0x007c, 0x0c7e, 0x2960, 0x6104, 0xa18c, 0xfff5, 0x6106, 0x2011,
+	0x0032, 0x2019, 0x0000, 0x0078, 0x3fad, 0x78ab, 0x0001, 0x78ab,
+	0x0003, 0x78ab, 0x0001, 0x7aaa, 0x7baa, 0xa8c0, 0x0005, 0x6820,
+	0xc0c5, 0x6822, 0x0c7f, 0x007c, 0x0c7e, 0x7158, 0x2160, 0x2018,
+	0xa08c, 0x0020, 0x0040, 0x3fc5, 0xc0ac, 0x2008, 0xa084, 0xfff0,
+	0xa635, 0x7e86, 0x6018, 0x789a, 0x7eae, 0x6612, 0x78a4, 0xa084,
+	0xfff0, 0xa18c, 0x000f, 0xa105, 0xc0f4, 0xa39c, 0x0020, 0x0040,
+	0x3fdb, 0xa085, 0x4000, 0xc0fc, 0xd0b4, 0x00c0, 0x3fe0, 0xc0fd,
+	0x78a6, 0x6016, 0x788a, 0xa6b4, 0x000f, 0x8637, 0x8204, 0x8004,
+	0xa084, 0x00ff, 0xa605, 0x600e, 0x6004, 0xa084, 0xfff5, 0x6006,
+	0x0c7f, 0x007c, 0x0c7e, 0x7058, 0x2060, 0x6018, 0x789a, 0x78a4,
+	0xa084, 0xfff0, 0x78a6, 0x6012, 0x7884, 0xa084, 0xfff0, 0x7886,
+	0x600c, 0xa084, 0x00ff, 0x600e, 0x0c7f, 0x007c, 0xa282, 0x0002,
+	0x00c0, 0x4107, 0x7aa8, 0x6920, 0xc1bd, 0x6922, 0xd1cc, 0x0040,
+	0x4041, 0xc1cc, 0x6922, 0xa294, 0x00ff, 0xa282, 0x0002, 0x00c8,
+	0x4107, 0x1078, 0x4094, 0x1078, 0x3ff2, 0xa980, 0x0001, 0x200c,
+	0x1078, 0x424a, 0x1078, 0x3f3e, 0x88ff, 0x0040, 0x4037, 0x789b,
+	0x0060, 0x2800, 0x78aa, 0x7e58, 0xc695, 0x7e5a, 0xd6d4, 0x00c0,
+	0x4034, 0x781b, 0x0064, 0x007c, 0x781b, 0x0078, 0x007c, 0x7e58,
+	0xd6d4, 0x00c0, 0x403e, 0x781b, 0x0067, 0x007c, 0x781b, 0x0079,
+	0x007c, 0xa282, 0x0002, 0x00c8, 0x4049, 0xa284, 0x0001, 0x0040,
+	0x4052, 0x7158, 0xa188, 0x0000, 0x210c, 0xd1ec, 0x00c0, 0x4052,
+	0x2011, 0x0000, 0x1078, 0x417c, 0x1078, 0x4094, 0x1078, 0x3ff2,
+	0x7858, 0xc095, 0x785a, 0x781b, 0x0078, 0x007c, 0x0c7e, 0x027e,
+	0x2960, 0x6000, 0x2011, 0x0001, 0xd0ec, 0x00c0, 0x4075, 0xd0bc,
+	0x00c0, 0x4073, 0x6014, 0xd0b4, 0x00c0, 0x4073, 0xc1a4, 0x6106,
+	0xa006, 0x0078, 0x4091, 0x2011, 0x0000, 0x78ab, 0x0001, 0x78ab,
 	0x0002, 0x78ab, 0x0003, 0x7aaa, 0xa8c0, 0x0004, 0x70d4, 0xd0b4,
-	0x0040, 0x403d, 0xc0b4, 0x70d6, 0x70b8, 0xa065, 0x6008, 0xa084,
+	0x0040, 0x408d, 0xc0b4, 0x70d6, 0x70b8, 0xa065, 0x6008, 0xa084,
 	0xfbef, 0x600a, 0x6018, 0x8001, 0x601a, 0x6820, 0xa085, 0x0200,
 	0x6822, 0x027f, 0x0c7f, 0x007c, 0x0c7e, 0x7058, 0x2060, 0x82ff,
-	0x0040, 0x404c, 0x2011, 0x0040, 0x6018, 0xa080, 0x0002, 0x789a,
-	0x78a4, 0xa084, 0xffbf, 0xa205, 0xc0fc, 0xd0b4, 0x00c0, 0x4059,
+	0x0040, 0x409c, 0x2011, 0x0040, 0x6018, 0xa080, 0x0002, 0x789a,
+	0x78a4, 0xa084, 0xffbf, 0xa205, 0xc0fc, 0xd0b4, 0x00c0, 0x40a9,
 	0xc0fd, 0x78a6, 0x6016, 0x788a, 0x6004, 0xc0a4, 0x6006, 0x0c7f,
-	0x007c, 0x007e, 0x7000, 0xa086, 0x0003, 0x0040, 0x406a, 0x007f,
-	0x0078, 0x406d, 0x007f, 0x0078, 0x40b4, 0xd6ac, 0x0040, 0x40b4,
-	0x7888, 0xa084, 0x0040, 0x0040, 0x40b4, 0x7bb8, 0xa384, 0x003f,
-	0x831b, 0x00c8, 0x407c, 0x8000, 0xa005, 0x0040, 0x4091, 0x831b,
-	0x00c8, 0x4085, 0x8001, 0x0040, 0x40b1, 0xd6f4, 0x0040, 0x4091,
-	0x78b8, 0x801b, 0x00c8, 0x408d, 0x8000, 0xa084, 0x003f, 0x00c0,
-	0x40b1, 0xc6f4, 0x7e5a, 0x79d8, 0x7adc, 0x2001, 0x0001, 0xa108,
-	0x00c8, 0x409c, 0xa291, 0x0000, 0x79d2, 0x79da, 0x7ad6, 0x7ade,
-	0x1078, 0x49c3, 0x781b, 0x0076, 0xb284, 0x0300, 0x0040, 0x40ac,
-	0x2001, 0x0000, 0x0078, 0x40ae, 0x2001, 0x0001, 0x1078, 0x484b,
+	0x007c, 0x007e, 0x7000, 0xa086, 0x0003, 0x0040, 0x40ba, 0x007f,
+	0x0078, 0x40bd, 0x007f, 0x0078, 0x4104, 0xd6ac, 0x0040, 0x4104,
+	0x7888, 0xa084, 0x0040, 0x0040, 0x4104, 0x7bb8, 0xa384, 0x003f,
+	0x831b, 0x00c8, 0x40cc, 0x8000, 0xa005, 0x0040, 0x40e1, 0x831b,
+	0x00c8, 0x40d5, 0x8001, 0x0040, 0x4101, 0xd6f4, 0x0040, 0x40e1,
+	0x78b8, 0x801b, 0x00c8, 0x40dd, 0x8000, 0xa084, 0x003f, 0x00c0,
+	0x4101, 0xc6f4, 0x7e5a, 0x79d8, 0x7adc, 0x2001, 0x0001, 0xa108,
+	0x00c8, 0x40ec, 0xa291, 0x0000, 0x79d2, 0x79da, 0x7ad6, 0x7ade,
+	0x1078, 0x4a44, 0x781b, 0x0076, 0xb284, 0x0300, 0x0040, 0x40fc,
+	0x2001, 0x0000, 0x0078, 0x40fe, 0x2001, 0x0001, 0x1078, 0x48ce,
 	0x007c, 0x781b, 0x0076, 0x007c, 0x781b, 0x0079, 0x007c, 0x1078,
-	0x40df, 0x781b, 0x0078, 0x007c, 0x1078, 0x40c8, 0x781b, 0x0078,
-	0x007c, 0x6827, 0x0002, 0x1078, 0x40d0, 0x781b, 0x0078, 0x007c,
-	0x2001, 0x0005, 0x0078, 0x40e1, 0x2001, 0x000c, 0x0078, 0x40e1,
-	0x6820, 0xc0d5, 0x6822, 0x2001, 0x0006, 0x0078, 0x40e1, 0x2001,
-	0x000d, 0x0078, 0x40e1, 0x2001, 0x0009, 0x0078, 0x40e1, 0x2001,
+	0x412f, 0x781b, 0x0078, 0x007c, 0x1078, 0x4118, 0x781b, 0x0078,
+	0x007c, 0x6827, 0x0002, 0x1078, 0x4120, 0x781b, 0x0078, 0x007c,
+	0x2001, 0x0005, 0x0078, 0x4131, 0x2001, 0x000c, 0x0078, 0x4131,
+	0x6820, 0xc0d5, 0x6822, 0x2001, 0x0006, 0x0078, 0x4131, 0x2001,
+	0x000d, 0x0078, 0x4131, 0x2001, 0x0009, 0x0078, 0x4131, 0x2001,
 	0x0007, 0x789b, 0x007e, 0x78aa, 0xc69d, 0x7e5a, 0x70d4, 0xd0b4,
-	0x0040, 0x40f7, 0xc0b4, 0x70d6, 0x0c7e, 0x70b8, 0xa065, 0x6008,
+	0x0040, 0x4147, 0xc0b4, 0x70d6, 0x0c7e, 0x70b8, 0xa065, 0x6008,
 	0xa084, 0xfbef, 0x600a, 0x6018, 0x8001, 0x601a, 0x0c7f, 0x007c,
 	0x077e, 0x873f, 0xa7bc, 0x000f, 0x873b, 0x873b, 0x8703, 0x017e,
-	0xb28c, 0x0300, 0x0040, 0x4108, 0xa0e0, 0x52c0, 0x0078, 0x410a,
-	0xa0e0, 0x5340, 0x017f, 0xa7b8, 0x0020, 0x7f9a, 0x79a4, 0xa184,
-	0x000f, 0x0040, 0x411a, 0xa184, 0xfff0, 0x78a6, 0x6012, 0x6004,
+	0xb28c, 0x0300, 0x0040, 0x4158, 0xa0e0, 0x53c0, 0x0078, 0x415a,
+	0xa0e0, 0x5440, 0x017f, 0xa7b8, 0x0020, 0x7f9a, 0x79a4, 0xa184,
+	0x000f, 0x0040, 0x416a, 0xa184, 0xfff0, 0x78a6, 0x6012, 0x6004,
 	0xc09d, 0x6006, 0x8738, 0x8738, 0x7f9a, 0x79a4, 0xa184, 0x0040,
-	0x0040, 0x412a, 0xa184, 0xffbf, 0xc0fd, 0x78a6, 0x6016, 0x6004,
+	0x0040, 0x417a, 0xa184, 0xffbf, 0xc0fd, 0x78a6, 0x6016, 0x6004,
 	0xc0a5, 0x6006, 0x077f, 0x007c, 0x789b, 0x0010, 0x78ab, 0x0001,
 	0x78ab, 0x0002, 0x78ab, 0x0003, 0x7aaa, 0x789b, 0x0060, 0x78ab,
-	0x0004, 0x70d4, 0xd0b4, 0x0040, 0x414a, 0xc0b4, 0x70d6, 0x0c7e,
+	0x0004, 0x70d4, 0xd0b4, 0x0040, 0x419a, 0xc0b4, 0x70d6, 0x0c7e,
 	0x70b8, 0xa065, 0x6008, 0xa084, 0xfbef, 0x600a, 0x6018, 0x8001,
 	0x601a, 0x0c7f, 0x007c, 0x2031, 0x0000, 0x2029, 0x0032, 0x789b,
 	0x0010, 0x78ab, 0x0001, 0x78ab, 0x0003, 0x78ab, 0x0001, 0x7daa,
 	0x7eaa, 0x789b, 0x0060, 0x78ab, 0x0005, 0x70d4, 0xd0b4, 0x0040,
-	0x416e, 0xc0b4, 0x70d6, 0x0c7e, 0x70b8, 0xa065, 0x6008, 0xa084,
+	0x41be, 0xc0b4, 0x70d6, 0x0c7e, 0x70b8, 0xa065, 0x6008, 0xa084,
 	0xfbef, 0x600a, 0x6018, 0x8001, 0x601a, 0x0c7f, 0x007c, 0x157e,
 	0x8007, 0xa084, 0x00ff, 0x8003, 0x8003, 0xa080, 0x0020, 0x789a,
-	0x79a4, 0xa18c, 0xfff0, 0x2021, 0x41e3, 0x2019, 0x0011, 0x20a9,
+	0x79a4, 0xa18c, 0xfff0, 0x2021, 0x4233, 0x2019, 0x0011, 0x20a9,
 	0x000e, 0x2011, 0x0032, 0x2404, 0xa084, 0xfff0, 0xa106, 0x0040,
-	0x418e, 0x8420, 0x2300, 0xa210, 0x00f0, 0x4183, 0x157f, 0x007c,
-	0x157e, 0x2001, 0x4e05, 0x2004, 0xd0e4, 0x00c0, 0x41c1, 0x2021,
-	0x41f1, 0x20a9, 0x0009, 0x2011, 0x0028, 0xa582, 0x0019, 0x0040,
-	0x41d7, 0x0048, 0x41d7, 0x8420, 0x95a9, 0x2011, 0x0032, 0xa582,
-	0x0032, 0x0040, 0x41d7, 0x0048, 0x41d7, 0x8420, 0x95a9, 0x2019,
-	0x000a, 0x2011, 0x0064, 0x2200, 0xa502, 0x0040, 0x41d7, 0x0048,
-	0x41d7, 0x8420, 0x2300, 0xa210, 0x00f0, 0x41b3, 0x157f, 0x0078,
-	0x41d5, 0x2021, 0x41e3, 0x2019, 0x0011, 0x20a9, 0x000e, 0x2011,
-	0x0032, 0x2200, 0xa502, 0x0040, 0x41d7, 0x0048, 0x41d7, 0x8420,
-	0x2300, 0xa210, 0x00f0, 0x41c9, 0x157f, 0xa006, 0x007c, 0x157f,
-	0xa582, 0x0064, 0x00c8, 0x41e0, 0x7808, 0xa085, 0x0070, 0x780a,
+	0x41de, 0x8420, 0x2300, 0xa210, 0x00f0, 0x41d3, 0x157f, 0x007c,
+	0x157e, 0x2001, 0x4f05, 0x2004, 0xd0e4, 0x00c0, 0x4211, 0x2021,
+	0x4241, 0x20a9, 0x0009, 0x2011, 0x0028, 0xa582, 0x0019, 0x0040,
+	0x4227, 0x0048, 0x4227, 0x8420, 0x95a9, 0x2011, 0x0032, 0xa582,
+	0x0032, 0x0040, 0x4227, 0x0048, 0x4227, 0x8420, 0x95a9, 0x2019,
+	0x000a, 0x2011, 0x0064, 0x2200, 0xa502, 0x0040, 0x4227, 0x0048,
+	0x4227, 0x8420, 0x2300, 0xa210, 0x00f0, 0x4203, 0x157f, 0x0078,
+	0x4225, 0x2021, 0x4233, 0x2019, 0x0011, 0x20a9, 0x000e, 0x2011,
+	0x0032, 0x2200, 0xa502, 0x0040, 0x4227, 0x0048, 0x4227, 0x8420,
+	0x2300, 0xa210, 0x00f0, 0x4219, 0x157f, 0xa006, 0x007c, 0x157f,
+	0xa582, 0x0064, 0x00c8, 0x4230, 0x7808, 0xa085, 0x0070, 0x780a,
 	0x2404, 0xa005, 0x007c, 0x1209, 0x3002, 0x3202, 0x4203, 0x4403,
 	0x5404, 0x5604, 0x6605, 0x6805, 0x7806, 0x7a06, 0x0c07, 0x0c07,
 	0x0e07, 0x10e1, 0x330a, 0x5805, 0x5a05, 0x6a06, 0x6c06, 0x7c07,
 	0x7e07, 0x0e00, 0x789b, 0x0010, 0xa046, 0x007c, 0xa784, 0x0f00,
 	0x800b, 0xa784, 0x001f, 0x8003, 0x8003, 0x8003, 0x8003, 0xa105,
-	0xd7fc, 0x0040, 0x420f, 0xa0e0, 0x73c0, 0x0078, 0x4211, 0xa0e0,
-	0x53c0, 0x007c, 0x0e7e, 0x0f7e, 0xd084, 0x0040, 0x421f, 0x2079,
-	0x0100, 0x2009, 0x4e80, 0x2071, 0x4e80, 0x0078, 0x422f, 0x2009,
-	0x4e40, 0x2071, 0x4e40, 0x2001, 0x4e04, 0x2004, 0xd0ec, 0x0040,
-	0x422d, 0x2079, 0x0100, 0x0078, 0x422f, 0x2079, 0x0200, 0x2091,
-	0x8000, 0x2104, 0xa084, 0x000f, 0x0079, 0x4236, 0x4240, 0x4240,
-	0x4240, 0x4240, 0x4240, 0x4240, 0x423e, 0x423e, 0x1078, 0x296b,
-	0x69b4, 0xc1f5, 0xa18c, 0xff9f, 0x69b6, 0xa005, 0x0040, 0x428f,
+	0xd7fc, 0x0040, 0x425f, 0xa0e0, 0x74c0, 0x0078, 0x4261, 0xa0e0,
+	0x54c0, 0x007c, 0x0e7e, 0x0f7e, 0xd084, 0x0040, 0x426f, 0x2079,
+	0x0100, 0x2009, 0x4f80, 0x2071, 0x4f80, 0x0078, 0x427f, 0x2009,
+	0x4f40, 0x2071, 0x4f40, 0x2001, 0x4f04, 0x2004, 0xd0ec, 0x0040,
+	0x427d, 0x2079, 0x0100, 0x0078, 0x427f, 0x2079, 0x0200, 0x2091,
+	0x8000, 0x2104, 0xa084, 0x000f, 0x0079, 0x4286, 0x4290, 0x4290,
+	0x4290, 0x4290, 0x4290, 0x4290, 0x428e, 0x428e, 0x1078, 0x29b2,
+	0x69b4, 0xc1f5, 0xa18c, 0xff9f, 0x69b6, 0xa005, 0x0040, 0x42df,
 	0x7858, 0xa084, 0xff9f, 0xa085, 0x6000, 0x785a, 0x7828, 0xa086,
-	0x1814, 0x00c0, 0x428f, 0x784b, 0x0004, 0x7848, 0xa084, 0x0004,
-	0x00c0, 0x4255, 0x784b, 0x0008, 0x7848, 0xa084, 0x0008, 0x00c0,
-	0x425c, 0x7830, 0xd0bc, 0x00c0, 0x428f, 0x007e, 0x2001, 0x4e04,
-	0x2004, 0xd0ec, 0x007f, 0x0040, 0x4271, 0xb284, 0x0300, 0x0078,
-	0x4273, 0xb284, 0x0400, 0x0040, 0x4279, 0x0018, 0x428f, 0x0078,
-	0x427b, 0x0028, 0x428f, 0x79e4, 0xa184, 0x0030, 0x0040, 0x428f,
-	0x78ec, 0xa084, 0x0003, 0x0040, 0x428f, 0x681c, 0xd0ac, 0x00c0,
-	0x428d, 0x1078, 0x4319, 0x0078, 0x428f, 0x781b, 0x00f9, 0x0f7f,
-	0x0e7f, 0x007c, 0x0c7e, 0x2001, 0x4e01, 0x2004, 0xd0ac, 0x00c0,
-	0x430b, 0x6814, 0x8007, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003,
-	0xb28c, 0x0300, 0x0040, 0x42a8, 0xa0e0, 0x52c0, 0x0078, 0x42aa,
-	0xa0e0, 0x5340, 0x6004, 0xa084, 0x000a, 0x00c0, 0x430b, 0x6108,
-	0xa194, 0xff00, 0x0040, 0x430b, 0xa18c, 0x00ff, 0x2001, 0x000a,
-	0xa106, 0x0040, 0x42d6, 0x2001, 0x000c, 0xa106, 0x0040, 0x42da,
-	0x2001, 0x0012, 0xa106, 0x0040, 0x42de, 0x2001, 0x0014, 0xa106,
-	0x0040, 0x42e2, 0x2001, 0x0019, 0xa106, 0x0040, 0x42e6, 0x2001,
-	0x0032, 0xa106, 0x0040, 0x42ea, 0x0078, 0x42ee, 0x2009, 0x000c,
-	0x0078, 0x42f0, 0x2009, 0x0012, 0x0078, 0x42f0, 0x2009, 0x0014,
-	0x0078, 0x42f0, 0x2009, 0x0019, 0x0078, 0x42f0, 0x2009, 0x0020,
-	0x0078, 0x42f0, 0x2009, 0x003f, 0x0078, 0x42f0, 0x2011, 0x0000,
+	0x1814, 0x00c0, 0x42df, 0x784b, 0x0004, 0x7848, 0xa084, 0x0004,
+	0x00c0, 0x42a5, 0x784b, 0x0008, 0x7848, 0xa084, 0x0008, 0x00c0,
+	0x42ac, 0x7830, 0xd0bc, 0x00c0, 0x42df, 0x007e, 0x2001, 0x4f04,
+	0x2004, 0xd0ec, 0x007f, 0x0040, 0x42c1, 0xb284, 0x0300, 0x0078,
+	0x42c3, 0xb284, 0x0400, 0x0040, 0x42c9, 0x0018, 0x42df, 0x0078,
+	0x42cb, 0x0028, 0x42df, 0x79e4, 0xa184, 0x0030, 0x0040, 0x42df,
+	0x78ec, 0xa084, 0x0003, 0x0040, 0x42df, 0x681c, 0xd0ac, 0x00c0,
+	0x42dd, 0x1078, 0x4369, 0x0078, 0x42df, 0x781b, 0x00f9, 0x0f7f,
+	0x0e7f, 0x007c, 0x0c7e, 0x2001, 0x4f01, 0x2004, 0xd0ac, 0x00c0,
+	0x435b, 0x6814, 0x8007, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003,
+	0xb28c, 0x0300, 0x0040, 0x42f8, 0xa0e0, 0x53c0, 0x0078, 0x42fa,
+	0xa0e0, 0x5440, 0x6004, 0xa084, 0x000a, 0x00c0, 0x435b, 0x6108,
+	0xa194, 0xff00, 0x0040, 0x435b, 0xa18c, 0x00ff, 0x2001, 0x000a,
+	0xa106, 0x0040, 0x4326, 0x2001, 0x000c, 0xa106, 0x0040, 0x432a,
+	0x2001, 0x0012, 0xa106, 0x0040, 0x432e, 0x2001, 0x0014, 0xa106,
+	0x0040, 0x4332, 0x2001, 0x0019, 0xa106, 0x0040, 0x4336, 0x2001,
+	0x0032, 0xa106, 0x0040, 0x433a, 0x0078, 0x433e, 0x2009, 0x000c,
+	0x0078, 0x4340, 0x2009, 0x0012, 0x0078, 0x4340, 0x2009, 0x0014,
+	0x0078, 0x4340, 0x2009, 0x0019, 0x0078, 0x4340, 0x2009, 0x0020,
+	0x0078, 0x4340, 0x2009, 0x003f, 0x0078, 0x4340, 0x2011, 0x0000,
 	0x2100, 0xa205, 0x600a, 0x6004, 0xa085, 0x0002, 0x6006, 0x2061,
-	0x4e00, 0x6004, 0xd0bc, 0x0040, 0x430b, 0x6814, 0xd0fc, 0x00c0,
-	0x4306, 0x60ea, 0x2061, 0x4e40, 0x0078, 0x4309, 0x60ee, 0x2061,
-	0x4e80, 0x601f, 0x800f, 0x0c7f, 0x007c, 0x781b, 0x0079, 0x007c,
+	0x4f00, 0x6004, 0xd0bc, 0x0040, 0x435b, 0x6814, 0xd0fc, 0x00c0,
+	0x4356, 0x60ea, 0x2061, 0x4f40, 0x0078, 0x4359, 0x60ee, 0x2061,
+	0x4f80, 0x601f, 0x800f, 0x0c7f, 0x007c, 0x781b, 0x0079, 0x007c,
 	0x781b, 0x0078, 0x007c, 0x781b, 0x0067, 0x007c, 0x781b, 0x0064,
-	0x007c, 0x2009, 0x4e19, 0x210c, 0xa186, 0x0000, 0x0040, 0x432b,
-	0xa186, 0x0001, 0x0040, 0x432e, 0x701f, 0x000b, 0x7067, 0x0001,
+	0x007c, 0x2009, 0x4f19, 0x210c, 0xa186, 0x0000, 0x0040, 0x437b,
+	0xa186, 0x0001, 0x0040, 0x437e, 0x701f, 0x000b, 0x7067, 0x0001,
 	0x781b, 0x0047, 0x007c, 0x781b, 0x00f0, 0x007c, 0x701f, 0x000a,
-	0x007c, 0x2009, 0x4e19, 0x210c, 0xa186, 0x0000, 0x0040, 0x4346,
-	0xa186, 0x0001, 0x0040, 0x4343, 0x701f, 0x000b, 0x7067, 0x0001,
+	0x007c, 0x2009, 0x4f19, 0x210c, 0xa186, 0x0000, 0x0040, 0x4396,
+	0xa186, 0x0001, 0x0040, 0x4393, 0x701f, 0x000b, 0x7067, 0x0001,
 	0x781b, 0x0047, 0x007c, 0x701f, 0x000a, 0x007c, 0x781b, 0x00ef,
 	0x007c, 0x781b, 0x00f9, 0x007c, 0x781b, 0x00f8, 0x007c, 0x781b,
 	0x00c9, 0x007c, 0x781b, 0x00c8, 0x007c, 0x6818, 0xd0fc, 0x0040,
-	0x435b, 0x681b, 0x001d, 0x7067, 0x0001, 0x781b, 0x0047, 0x007c,
-	0x7830, 0xa084, 0x00c0, 0x00c0, 0x4382, 0x7808, 0xc08c, 0x780a,
+	0x43ab, 0x681b, 0x001d, 0x7067, 0x0001, 0x781b, 0x0047, 0x007c,
+	0x7830, 0xa084, 0x00c0, 0x00c0, 0x43d2, 0x7808, 0xc08c, 0x780a,
 	0x0005, 0x0005, 0x0005, 0x0005, 0x78ec, 0xa084, 0x0021, 0x00c0,
-	0x437f, 0x2001, 0x4e05, 0x2004, 0xd0e4, 0x00c0, 0x437d, 0x7804,
+	0x43cf, 0x2001, 0x4f05, 0x2004, 0xd0e4, 0x00c0, 0x43cd, 0x7804,
 	0xa084, 0xff1f, 0xa085, 0x00e0, 0x7806, 0xa006, 0x007c, 0x7808,
 	0xc08d, 0x780a, 0x007c, 0x7808, 0xc08d, 0x780a, 0x007c, 0x7830,
-	0xa084, 0x0040, 0x00c0, 0x4387, 0x2001, 0x4e04, 0x2004, 0xd0ec,
-	0x0040, 0x4396, 0xb284, 0x0300, 0x0078, 0x4398, 0xb284, 0x0400,
-	0x0040, 0x439e, 0x0098, 0x43a2, 0x0078, 0x43a0, 0x00a8, 0x43a2,
+	0xa084, 0x0040, 0x00c0, 0x43d7, 0x2001, 0x4f04, 0x2004, 0xd0ec,
+	0x0040, 0x43e6, 0xb284, 0x0300, 0x0078, 0x43e8, 0xb284, 0x0400,
+	0x0040, 0x43ee, 0x0098, 0x43f2, 0x0078, 0x43f0, 0x00a8, 0x43f2,
 	0x78ac, 0x007c, 0x7808, 0xa084, 0xfffd, 0x780a, 0x0005, 0x0005,
-	0x0005, 0x0005, 0x78ec, 0xa084, 0x0021, 0x0040, 0x43c5, 0x007e,
-	0x2001, 0x4e04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x43bb, 0xb284,
-	0x0300, 0x0078, 0x43bd, 0xb284, 0x0400, 0x0040, 0x43c3, 0x0098,
-	0x43bf, 0x0078, 0x43c5, 0x00a8, 0x43c3, 0x78ac, 0x007e, 0x7808,
+	0x0005, 0x0005, 0x78ec, 0xa084, 0x0021, 0x0040, 0x4415, 0x007e,
+	0x2001, 0x4f04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x440b, 0xb284,
+	0x0300, 0x0078, 0x440d, 0xb284, 0x0400, 0x0040, 0x4413, 0x0098,
+	0x440f, 0x0078, 0x4415, 0x00a8, 0x4413, 0x78ac, 0x007e, 0x7808,
 	0xa085, 0x0002, 0x780a, 0x007f, 0x007c, 0xa784, 0x0001, 0x00c0,
-	0x3770, 0xa784, 0x0070, 0x0040, 0x43dd, 0x0c7e, 0x2d60, 0x2f68,
-	0x1078, 0x28df, 0x2d78, 0x2c68, 0x0c7f, 0xa784, 0x0008, 0x0040,
-	0x43ea, 0x784b, 0x0008, 0x78ec, 0xa084, 0x0003, 0x0040, 0x3770,
-	0x0078, 0x430d, 0xa784, 0x0004, 0x0040, 0x4419, 0x78b8, 0xa084,
-	0x4001, 0x0040, 0x4419, 0x784b, 0x0008, 0x78ec, 0xa084, 0x0003,
-	0x0040, 0x3770, 0x78e4, 0xa084, 0x0007, 0xa086, 0x0001, 0x00c0,
-	0x4419, 0x78c0, 0xa685, 0x4800, 0x2030, 0x7e5a, 0x781b, 0x00f9,
-	0x007c, 0x784b, 0x0008, 0x6818, 0xd0fc, 0x0040, 0x4416, 0x681b,
-	0x0015, 0xd6f4, 0x0040, 0x4416, 0x681b, 0x0007, 0x1078, 0x4319,
+	0x37b9, 0xa784, 0x0070, 0x0040, 0x442d, 0x0c7e, 0x2d60, 0x2f68,
+	0x1078, 0x2926, 0x2d78, 0x2c68, 0x0c7f, 0xa784, 0x0008, 0x0040,
+	0x443a, 0x784b, 0x0008, 0x78ec, 0xa084, 0x0003, 0x0040, 0x37b9,
+	0x0078, 0x435d, 0xa784, 0x0004, 0x0040, 0x4469, 0x78b8, 0xa084,
+	0x4001, 0x0040, 0x4469, 0x784b, 0x0008, 0x78ec, 0xa084, 0x0003,
+	0x0040, 0x37b9, 0x78e4, 0xa084, 0x0007, 0xa086, 0x0001, 0x00c0,
+	0x4469, 0x78c0, 0xa685, 0x4800, 0x2030, 0x7e5a, 0x781b, 0x00f9,
+	0x007c, 0x784b, 0x0008, 0x6818, 0xd0fc, 0x0040, 0x4466, 0x681b,
+	0x0015, 0xd6f4, 0x0040, 0x4466, 0x681b, 0x0007, 0x1078, 0x4369,
 	0x007c, 0x681b, 0x0003, 0x7858, 0xa084, 0x3f00, 0x681e, 0x682f,
 	0x0000, 0x6833, 0x0000, 0x784b, 0x0008, 0x78ec, 0xa084, 0x0003,
-	0x0040, 0x3066, 0x007e, 0x2001, 0x4e04, 0x2004, 0xd0ec, 0x007f,
-	0x0040, 0x4436, 0xb284, 0x0300, 0x0078, 0x4438, 0xb284, 0x0400,
-	0x0040, 0x443e, 0x0018, 0x29c1, 0x0078, 0x4440, 0x0028, 0x29c1,
-	0x0078, 0x40bc, 0x6b14, 0x8307, 0xa084, 0x000f, 0x8003, 0x8003,
-	0x8003, 0xd3fc, 0x0040, 0x4450, 0xa080, 0x5340, 0x0078, 0x4452,
-	0xa080, 0x52c0, 0x2060, 0x2048, 0x705a, 0x2a60, 0x007c, 0x0020,
+	0x0040, 0x30af, 0x007e, 0x2001, 0x4f04, 0x2004, 0xd0ec, 0x007f,
+	0x0040, 0x4486, 0xb284, 0x0300, 0x0078, 0x4488, 0xb284, 0x0400,
+	0x0040, 0x448e, 0x0018, 0x2a08, 0x0078, 0x4490, 0x0028, 0x2a08,
+	0x0078, 0x410c, 0x6b14, 0x8307, 0xa084, 0x000f, 0x8003, 0x8003,
+	0x8003, 0xd3fc, 0x0040, 0x44a0, 0xa080, 0x5440, 0x0078, 0x44a2,
+	0xa080, 0x53c0, 0x2060, 0x2048, 0x705a, 0x2a60, 0x007c, 0x0020,
 	0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000,
 	0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000,
 	0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000,
@@ -1763,255 +1773,276 @@ static unsigned short risc_code01[] = {
 	0x0016, 0x7944, 0x8421, 0xa020, 0xa532, 0x84a1, 0x0016, 0x7944,
 	0x8421, 0xa0df, 0x9532, 0x84a1, 0x0016, 0x0000, 0x127e, 0x70d4,
 	0xa084, 0x4600, 0x8004, 0x2090, 0x7204, 0x7008, 0xc09c, 0xa205,
-	0x00c0, 0x45a2, 0x720c, 0x82ff, 0x0040, 0x459d, 0x8aff, 0x00c0,
-	0x45a2, 0x7200, 0xd284, 0x00c0, 0x45a2, 0x7003, 0x0008, 0x127f,
+	0x00c0, 0x4602, 0x720c, 0x82ff, 0x0040, 0x45ed, 0x8aff, 0x00c0,
+	0x4602, 0x7200, 0xd284, 0x00c0, 0x4602, 0x7804, 0xd0cc, 0x0040,
+	0x45f3, 0x1078, 0x4acc, 0x7023, 0x0000, 0x7027, 0x0000, 0x7000,
+	0xd084, 0x0040, 0x45fd, 0x7007, 0x0004, 0x7003, 0x0008, 0x127f,
 	0x2000, 0x007c, 0x7000, 0xa084, 0x0003, 0x7002, 0xc69c, 0xd084,
-	0x0040, 0x45e5, 0x7108, 0x0005, 0x7008, 0xa106, 0x00c0, 0x45aa,
-	0xa184, 0x0003, 0x0040, 0x4616, 0xa184, 0x01e0, 0x00c0, 0x4616,
-	0xd1f4, 0x00c0, 0x45aa, 0xa184, 0x3000, 0xa086, 0x1000, 0x0040,
-	0x45aa, 0x2011, 0x0180, 0x710c, 0x8211, 0x0040, 0x45cf, 0x7008,
-	0xd0f4, 0x00c0, 0x45aa, 0x700c, 0xa106, 0x0040, 0x45c4, 0x7007,
-	0x0012, 0x7108, 0x0005, 0x7008, 0xa106, 0x00c0, 0x45d1, 0xa184,
-	0x0003, 0x0040, 0x4616, 0xd194, 0x0040, 0x45d1, 0xd1f4, 0x0040,
-	0x4616, 0x7007, 0x0002, 0x0078, 0x45aa, 0x7108, 0xd1fc, 0x0040,
-	0x45f0, 0x1078, 0x4769, 0x8aff, 0x0040, 0x458c, 0x0078, 0x45e5,
-	0x700c, 0xa08c, 0x03ff, 0x0040, 0x461b, 0x7004, 0xd084, 0x0040,
-	0x460d, 0x7014, 0xa005, 0x00c0, 0x4609, 0x7010, 0x7310, 0xa306,
-	0x00c0, 0x45fd, 0x2300, 0xa005, 0x0040, 0x460d, 0xa102, 0x00c8,
-	0x45e5, 0x7007, 0x0010, 0x0078, 0x4616, 0x8aff, 0x0040, 0x461b,
-	0x1078, 0x4970, 0x00c0, 0x4610, 0x0040, 0x45e5, 0x1078, 0x46b4,
-	0x127f, 0x2000, 0x007c, 0x7204, 0x7108, 0xc19c, 0x8103, 0x00c8,
-	0x462a, 0x7007, 0x0002, 0x0078, 0x461b, 0x7003, 0x0008, 0x127f,
-	0x2000, 0x007c, 0xa205, 0x00c0, 0x4616, 0x7003, 0x0008, 0x127f,
-	0x2000, 0x007c, 0x6428, 0x84ff, 0x0040, 0x465e, 0x2c70, 0x7004,
-	0xa0bc, 0x000f, 0xa7b8, 0x466e, 0x273c, 0x87fb, 0x00c0, 0x464c,
-	0x0048, 0x4644, 0x1078, 0x296b, 0x609c, 0xa075, 0x0040, 0x465e,
-	0x0078, 0x4637, 0x2039, 0x4663, 0x2704, 0xae68, 0x6808, 0xa630,
-	0x680c, 0xa529, 0x8421, 0x0040, 0x465e, 0x8738, 0x2704, 0xa005,
-	0x00c0, 0x464d, 0x709c, 0xa075, 0x00c0, 0x4637, 0x007c, 0x0000,
-	0x0005, 0x0009, 0x000d, 0x0011, 0x0015, 0x0019, 0x001d, 0x0000,
-	0x0003, 0x0009, 0x000f, 0x0015, 0x001b, 0x0000, 0x0000, 0x4663,
-	0x4660, 0x0000, 0x0000, 0x8000, 0x0000, 0x4663, 0x0000, 0x466b,
-	0x4668, 0x0000, 0x0000, 0x0000, 0x0000, 0x466b, 0x0000, 0x4666,
-	0x4666, 0x0000, 0x0000, 0x8000, 0x0000, 0x4666, 0x0000, 0x466c,
-	0x466c, 0x0000, 0x0000, 0x0000, 0x0000, 0x466c, 0x2079, 0x4e00,
-	0x2071, 0x0010, 0x7007, 0x000a, 0x7007, 0x0002, 0x7003, 0x0001,
-	0x7810, 0xd0ec, 0x0040, 0x46a2, 0x2009, 0x0001, 0x2071, 0x0020,
-	0x0078, 0x46a6, 0x2009, 0x0002, 0x2071, 0x0050, 0x7007, 0x000a,
-	0x7007, 0x0002, 0x7003, 0x0000, 0x8109, 0x0040, 0x46b3, 0x2071,
-	0x0020, 0x0078, 0x46a6, 0x007c, 0x7004, 0x8004, 0x00c8, 0x473d,
-	0x7108, 0x7008, 0xa106, 0x00c0, 0x46b8, 0xa184, 0x01e0, 0x0040,
-	0x46c5, 0x1078, 0x47ac, 0x0078, 0x4765, 0x7007, 0x0012, 0x2019,
-	0x0000, 0x7108, 0x7008, 0xa106, 0x00c0, 0x46c9, 0xa184, 0x01e0,
-	0x0040, 0x46d6, 0x1078, 0x47ac, 0x0078, 0x4765, 0x7810, 0xd0ec,
-	0x0040, 0x46f0, 0x2001, 0x04fd, 0x2004, 0xa086, 0x0003, 0x00c0,
-	0x46f4, 0xa184, 0x4000, 0x0040, 0x46f8, 0xa382, 0x0003, 0x00c8,
-	0x46f8, 0xa184, 0x0004, 0x0040, 0x46c9, 0x8318, 0x0078, 0x46c9,
-	0x7814, 0xd0ec, 0x00c0, 0x46f8, 0xa184, 0x4000, 0x00c0, 0x46c9,
-	0xa19c, 0x300c, 0xa386, 0x2004, 0x0040, 0x4715, 0xa386, 0x0008,
-	0x0040, 0x4720, 0x7004, 0xd084, 0x00c0, 0x4711, 0x7108, 0x7008,
-	0xa106, 0x00c0, 0x4706, 0xa184, 0x0003, 0x0040, 0x4711, 0x0078,
-	0x47ac, 0xa386, 0x200c, 0x00c0, 0x46c9, 0x7200, 0x8204, 0x0048,
-	0x4720, 0x730c, 0xa384, 0x03ff, 0x0040, 0x4720, 0x1078, 0x296b,
-	0x7108, 0x7008, 0xa106, 0x00c0, 0x4720, 0xa184, 0x01e0, 0x0040,
-	0x472d, 0x1078, 0x47ac, 0x0078, 0x4765, 0x7007, 0x0012, 0x7000,
-	0xd084, 0x00c0, 0x473d, 0x7310, 0x7014, 0xa305, 0x0040, 0x473d,
-	0x710c, 0xa184, 0x03ff, 0x00c0, 0x46b4, 0x7108, 0x7008, 0xa106,
-	0x00c0, 0x473d, 0xa184, 0x01e0, 0x0040, 0x474a, 0x1078, 0x47ac,
-	0x0078, 0x4765, 0x7007, 0x0012, 0x7007, 0x0008, 0x7004, 0xd09c,
-	0x00c0, 0x474e, 0x7108, 0x7008, 0xa106, 0x00c0, 0x4752, 0xa184,
-	0x01e0, 0x0040, 0x475f, 0x1078, 0x47ac, 0x0078, 0x4765, 0x7007,
-	0x0012, 0x7108, 0x8103, 0x0048, 0x4752, 0x7003, 0x0008, 0x007c,
-	0x7108, 0xa184, 0x01e0, 0x00c0, 0x47ac, 0x7108, 0xa184, 0x01e0,
-	0x00c0, 0x47ac, 0xa184, 0x0007, 0x0079, 0x4776, 0x4780, 0x4790,
-	0x477e, 0x4790, 0x477e, 0x47ee, 0x477e, 0x47ec, 0x1078, 0x296b,
-	0x7004, 0xa084, 0x0010, 0xc08d, 0x7006, 0x8aff, 0x00c0, 0x478b,
-	0x2049, 0x0000, 0x007c, 0x1078, 0x4970, 0x00c0, 0x478b, 0x007c,
-	0x7004, 0xa084, 0x0010, 0xc08d, 0x7006, 0x7004, 0xd084, 0x00c0,
-	0x47a4, 0x7108, 0x7008, 0xa106, 0x00c0, 0x4799, 0xa184, 0x0003,
-	0x0040, 0x47a4, 0x0078, 0x47ac, 0x8aff, 0x0040, 0x47ab, 0x1078,
-	0x4970, 0x00c0, 0x47a7, 0x007c, 0x7007, 0x0012, 0x7108, 0x00e0,
-	0x47af, 0x2091, 0x6000, 0x00e0, 0x47b3, 0x2091, 0x6000, 0x7007,
-	0x0012, 0x7007, 0x0008, 0x7004, 0xd09c, 0x00c0, 0x47bb, 0x7007,
-	0x0012, 0x7108, 0xd1fc, 0x00c0, 0x47bf, 0x7003, 0x0000, 0x7000,
-	0xa005, 0x00c0, 0x47d3, 0x7004, 0xa005, 0x00c0, 0x47d3, 0x700c,
-	0xa005, 0x0040, 0x47d5, 0x0078, 0x47b7, 0x2049, 0x0000, 0xb284,
-	0x0100, 0x0040, 0x47df, 0x2001, 0x0000, 0x0078, 0x47e1, 0x2001,
-	0x0001, 0x1078, 0x4212, 0x681b, 0x0002, 0x2051, 0x0000, 0x007c,
-	0x1078, 0x296b, 0x1078, 0x296b, 0x1078, 0x4836, 0x7210, 0x7114,
-	0x700c, 0xa09c, 0x03ff, 0x2800, 0xa300, 0xa211, 0xa189, 0x0000,
-	0x1078, 0x4836, 0x2704, 0x2c58, 0xac60, 0x6308, 0x2200, 0xa322,
-	0x630c, 0x2100, 0xa31b, 0x2400, 0xa305, 0x0040, 0x4811, 0x00c8,
-	0x4811, 0x8412, 0x8210, 0x830a, 0xa189, 0x0000, 0x2b60, 0x0078,
-	0x47f8, 0x2b60, 0x8a07, 0x007e, 0x6004, 0xa084, 0x0008, 0x0040,
-	0x481d, 0xa7ba, 0x4668, 0x0078, 0x481f, 0xa7ba, 0x4660, 0x007f,
-	0xa73d, 0x2c00, 0x6886, 0x6f8a, 0x6c92, 0x6b8e, 0x7108, 0x7008,
-	0xa106, 0x00c0, 0x4826, 0xa184, 0x01e0, 0x0040, 0x4831, 0x1078,
-	0x47ac, 0x7007, 0x0012, 0x1078, 0x46b4, 0x007c, 0x8a50, 0x8739,
-	0x2704, 0xa004, 0x00c0, 0x484a, 0x6000, 0xa064, 0x00c0, 0x4841,
-	0x2d60, 0x6004, 0xa084, 0x000f, 0xa080, 0x467e, 0x203c, 0x87fb,
-	0x1040, 0x296b, 0x007c, 0x127e, 0x0d7e, 0x70d4, 0xa084, 0x4600,
-	0x8004, 0x2090, 0x0d7f, 0x6884, 0x2060, 0x6888, 0x6b8c, 0x6c90,
-	0x8057, 0xaad4, 0x00ff, 0xa084, 0x00ff, 0x007e, 0x6804, 0xa084,
-	0x0008, 0x007f, 0x0040, 0x4868, 0xa0b8, 0x4668, 0x0078, 0x486a,
-	0xa0b8, 0x4660, 0xb284, 0x0100, 0x0040, 0x4871, 0x7e20, 0x0078,
-	0x4872, 0x7e24, 0xa6b5, 0x000c, 0x681c, 0xd0b4, 0x0040, 0x4879,
-	0xc685, 0x2400, 0xa305, 0x0040, 0x48a3, 0x2c58, 0x2704, 0x6104,
-	0xac60, 0x6000, 0xa400, 0x701a, 0x6004, 0xa301, 0x701e, 0xa184,
-	0x0008, 0x0040, 0x4893, 0x6010, 0xa081, 0x0000, 0x7022, 0x6014,
-	0xa081, 0x0000, 0x7026, 0x6208, 0x2400, 0xa202, 0x7012, 0x620c,
-	0x2300, 0xa203, 0x7016, 0x7602, 0x7007, 0x0001, 0x2b60, 0x1078,
-	0x499b, 0x0078, 0x48a5, 0x1078, 0x4970, 0x00c0, 0x48a3, 0x127f,
-	0x2000, 0x007c, 0x127e, 0x0d7e, 0x70d4, 0xa084, 0x4600, 0x8004,
-	0x2090, 0x0d7f, 0x7007, 0x0004, 0x7004, 0xd094, 0x00c0, 0x48b4,
-	0x7003, 0x0008, 0x127f, 0x2000, 0x007c, 0x127e, 0x0d7e, 0x70d4,
-	0xa084, 0x4600, 0x8004, 0x007e, 0x2090, 0x007f, 0x0d7f, 0x7e20,
-	0xb284, 0x0100, 0x00c0, 0x48cd, 0x7e24, 0xa6b5, 0x000c, 0x681c,
-	0xd0ac, 0x00c0, 0x48d8, 0xc685, 0x7003, 0x0000, 0x7007, 0x0004,
-	0x6828, 0x2050, 0x2d60, 0x6004, 0xa0bc, 0x000f, 0xa7b8, 0x466e,
-	0x273c, 0x87fb, 0x00c0, 0x48ee, 0x0048, 0x48e8, 0x1078, 0x296b,
-	0x689c, 0xa065, 0x0040, 0x48f2, 0x0078, 0x48db, 0x1078, 0x4970,
-	0x00c0, 0x48ee, 0x127f, 0x2000, 0x007c, 0x127e, 0x007e, 0x017e,
+	0x0040, 0x465b, 0x7108, 0x0005, 0x7008, 0xa106, 0x00c0, 0x460a,
+	0xa184, 0x0003, 0x0040, 0x468c, 0xa184, 0x01e0, 0x00c0, 0x468c,
+	0xd1f4, 0x00c0, 0x460a, 0xa184, 0x3000, 0xa086, 0x1000, 0x0040,
+	0x460a, 0x2001, 0x4f05, 0x2004, 0xd0e4, 0x0040, 0x4637, 0x2011,
+	0x0180, 0x710c, 0x8211, 0x0040, 0x4645, 0x7008, 0xd0f4, 0x00c0,
+	0x460a, 0x700c, 0xa106, 0x0040, 0x462a, 0x0078, 0x4627, 0x2011,
+	0x0180, 0x710c, 0x8211, 0x0040, 0x4645, 0x7008, 0xd0f4, 0x00c0,
+	0x460a, 0x700c, 0xa106, 0x0040, 0x463a, 0x7007, 0x0012, 0x7108,
+	0x0005, 0x7008, 0xa106, 0x00c0, 0x4647, 0xa184, 0x0003, 0x0040,
+	0x468c, 0xd194, 0x0040, 0x4647, 0xd1f4, 0x0040, 0x468c, 0x7007,
+	0x0002, 0x0078, 0x460a, 0x7108, 0xd1fc, 0x0040, 0x4666, 0x1078,
+	0x47ed, 0x8aff, 0x0040, 0x45dc, 0x0078, 0x465b, 0x700c, 0xa08c,
+	0x03ff, 0x0040, 0x4691, 0x7004, 0xd084, 0x0040, 0x4683, 0x7014,
+	0xa005, 0x00c0, 0x467f, 0x7010, 0x7310, 0xa306, 0x00c0, 0x4673,
+	0x2300, 0xa005, 0x0040, 0x4683, 0xa102, 0x00c8, 0x465b, 0x7007,
+	0x0010, 0x0078, 0x468c, 0x8aff, 0x0040, 0x4691, 0x1078, 0x49f2,
+	0x00c0, 0x4686, 0x0040, 0x465b, 0x1078, 0x4738, 0x127f, 0x2000,
+	0x007c, 0x7204, 0x7108, 0xc19c, 0x8103, 0x00c8, 0x46a0, 0x7007,
+	0x0002, 0x0078, 0x4691, 0x7003, 0x0008, 0x127f, 0x2000, 0x007c,
+	0xa205, 0x00c0, 0x468c, 0x7023, 0x0000, 0x7027, 0x0000, 0x7003,
+	0x0008, 0x007e, 0x2001, 0x4f01, 0x2004, 0xd0cc, 0x0040, 0x46b2,
+	0x1078, 0x4acc, 0x007f, 0x127f, 0x2000, 0x007c, 0x6428, 0x84ff,
+	0x0040, 0x46e2, 0x2c70, 0x7004, 0xa0bc, 0x000f, 0xa7b8, 0x46f2,
+	0x273c, 0x87fb, 0x00c0, 0x46d0, 0x0048, 0x46c8, 0x1078, 0x29b2,
+	0x609c, 0xa075, 0x0040, 0x46e2, 0x0078, 0x46bb, 0x2039, 0x46e7,
+	0x2704, 0xae68, 0x6808, 0xa630, 0x680c, 0xa529, 0x8421, 0x0040,
+	0x46e2, 0x8738, 0x2704, 0xa005, 0x00c0, 0x46d1, 0x709c, 0xa075,
+	0x00c0, 0x46bb, 0x007c, 0x0000, 0x0005, 0x0009, 0x000d, 0x0011,
+	0x0015, 0x0019, 0x001d, 0x0000, 0x0003, 0x0009, 0x000f, 0x0015,
+	0x001b, 0x0000, 0x0000, 0x46e7, 0x46e4, 0x0000, 0x0000, 0x8000,
+	0x0000, 0x46e7, 0x0000, 0x46ef, 0x46ec, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x46ef, 0x0000, 0x46ea, 0x46ea, 0x0000, 0x0000, 0x8000,
+	0x0000, 0x46ea, 0x0000, 0x46f0, 0x46f0, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x46f0, 0x2079, 0x4f00, 0x2071, 0x0010, 0x7007, 0x000a,
+	0x7007, 0x0002, 0x7003, 0x0001, 0x7810, 0xd0ec, 0x0040, 0x4726,
+	0x2009, 0x0001, 0x2071, 0x0020, 0x0078, 0x472a, 0x2009, 0x0002,
+	0x2071, 0x0050, 0x7007, 0x000a, 0x7007, 0x0002, 0x7003, 0x0000,
+	0x8109, 0x0040, 0x4737, 0x2071, 0x0020, 0x0078, 0x472a, 0x007c,
+	0x7004, 0x8004, 0x00c8, 0x47c1, 0x7108, 0x7008, 0xa106, 0x00c0,
+	0x473c, 0xa184, 0x01e0, 0x0040, 0x4749, 0x1078, 0x4830, 0x0078,
+	0x47e9, 0x7007, 0x0012, 0x2019, 0x0000, 0x7108, 0x7008, 0xa106,
+	0x00c0, 0x474d, 0xa184, 0x01e0, 0x0040, 0x475a, 0x1078, 0x4830,
+	0x0078, 0x47e9, 0x7810, 0xd0ec, 0x0040, 0x4774, 0x2001, 0x04fd,
+	0x2004, 0xa086, 0x0003, 0x00c0, 0x4778, 0xa184, 0x4000, 0x0040,
+	0x477c, 0xa382, 0x0003, 0x00c8, 0x477c, 0xa184, 0x0004, 0x0040,
+	0x474d, 0x8318, 0x0078, 0x474d, 0x7814, 0xd0ec, 0x00c0, 0x477c,
+	0xa184, 0x4000, 0x00c0, 0x474d, 0xa19c, 0x300c, 0xa386, 0x2004,
+	0x0040, 0x4799, 0xa386, 0x0008, 0x0040, 0x47a4, 0x7004, 0xd084,
+	0x00c0, 0x4795, 0x7108, 0x7008, 0xa106, 0x00c0, 0x478a, 0xa184,
+	0x0003, 0x0040, 0x4795, 0x0078, 0x4830, 0xa386, 0x200c, 0x00c0,
+	0x474d, 0x7200, 0x8204, 0x0048, 0x47a4, 0x730c, 0xa384, 0x03ff,
+	0x0040, 0x47a4, 0x1078, 0x29b2, 0x7108, 0x7008, 0xa106, 0x00c0,
+	0x47a4, 0xa184, 0x01e0, 0x0040, 0x47b1, 0x1078, 0x4830, 0x0078,
+	0x47e9, 0x7007, 0x0012, 0x7000, 0xd084, 0x00c0, 0x47c1, 0x7310,
+	0x7014, 0xa305, 0x0040, 0x47c1, 0x710c, 0xa184, 0x03ff, 0x00c0,
+	0x4738, 0x7108, 0x7008, 0xa106, 0x00c0, 0x47c1, 0xa184, 0x01e0,
+	0x0040, 0x47ce, 0x1078, 0x4830, 0x0078, 0x47e9, 0x7007, 0x0012,
+	0x7007, 0x0008, 0x7004, 0xd09c, 0x00c0, 0x47d2, 0x7108, 0x7008,
+	0xa106, 0x00c0, 0x47d6, 0xa184, 0x01e0, 0x0040, 0x47e3, 0x1078,
+	0x4830, 0x0078, 0x47e9, 0x7007, 0x0012, 0x7108, 0x8103, 0x0048,
+	0x47d6, 0x7003, 0x0008, 0x007c, 0x7108, 0xa184, 0x01e0, 0x00c0,
+	0x4830, 0x7108, 0xa184, 0x01e0, 0x00c0, 0x4830, 0xa184, 0x0007,
+	0x0079, 0x47fa, 0x4804, 0x4814, 0x4802, 0x4814, 0x4802, 0x4872,
+	0x4802, 0x4870, 0x1078, 0x29b2, 0x7004, 0xa084, 0x0010, 0xc08d,
+	0x7006, 0x8aff, 0x00c0, 0x480f, 0x2049, 0x0000, 0x007c, 0x1078,
+	0x49f2, 0x00c0, 0x480f, 0x007c, 0x7004, 0xa084, 0x0010, 0xc08d,
+	0x7006, 0x7004, 0xd084, 0x00c0, 0x4828, 0x7108, 0x7008, 0xa106,
+	0x00c0, 0x481d, 0xa184, 0x0003, 0x0040, 0x4828, 0x0078, 0x4830,
+	0x8aff, 0x0040, 0x482f, 0x1078, 0x49f2, 0x00c0, 0x482b, 0x007c,
+	0x7007, 0x0012, 0x7108, 0x00e0, 0x4833, 0x2091, 0x6000, 0x00e0,
+	0x4837, 0x2091, 0x6000, 0x7007, 0x0012, 0x7007, 0x0008, 0x7004,
+	0xd09c, 0x00c0, 0x483f, 0x7007, 0x0012, 0x7108, 0xd1fc, 0x00c0,
+	0x4843, 0x7003, 0x0000, 0x7000, 0xa005, 0x00c0, 0x4857, 0x7004,
+	0xa005, 0x00c0, 0x4857, 0x700c, 0xa005, 0x0040, 0x4859, 0x0078,
+	0x483b, 0x2049, 0x0000, 0xb284, 0x0100, 0x0040, 0x4863, 0x2001,
+	0x0000, 0x0078, 0x4865, 0x2001, 0x0001, 0x1078, 0x4262, 0x681b,
+	0x0002, 0x2051, 0x0000, 0x007c, 0x1078, 0x29b2, 0x1078, 0x29b2,
+	0x1078, 0x48b9, 0x7210, 0x7114, 0x700c, 0xa09c, 0x03ff, 0x2800,
+	0xa300, 0xa211, 0xa189, 0x0000, 0x1078, 0x48b9, 0x2704, 0x2c58,
+	0xac60, 0x6308, 0x2200, 0xa322, 0x630c, 0x2100, 0xa31b, 0x2400,
+	0xa305, 0x0040, 0x4895, 0x00c8, 0x4895, 0x8412, 0x8210, 0x830a,
+	0xa189, 0x0000, 0x2b60, 0x0078, 0x487c, 0x2b60, 0x8a07, 0x007e,
+	0x6004, 0xd09c, 0x0040, 0x48a0, 0xa7ba, 0x46ec, 0x0078, 0x48a2,
+	0xa7ba, 0x46e4, 0x007f, 0xa73d, 0x2c00, 0x6886, 0x6f8a, 0x6c92,
+	0x6b8e, 0x7108, 0x7008, 0xa106, 0x00c0, 0x48a9, 0xa184, 0x01e0,
+	0x0040, 0x48b4, 0x1078, 0x4830, 0x7007, 0x0012, 0x1078, 0x4738,
+	0x007c, 0x8a50, 0x8739, 0x2704, 0xa004, 0x00c0, 0x48cd, 0x6000,
+	0xa064, 0x00c0, 0x48c4, 0x2d60, 0x6004, 0xa084, 0x000f, 0xa080,
+	0x4702, 0x203c, 0x87fb, 0x1040, 0x29b2, 0x007c, 0x127e, 0x0d7e,
+	0x70d4, 0xa084, 0x4600, 0x8004, 0x2090, 0x0d7f, 0x6884, 0x2060,
+	0x6888, 0x6b8c, 0x6c90, 0x8057, 0xaad4, 0x00ff, 0xa084, 0x00ff,
+	0x007e, 0x6804, 0xa084, 0x0008, 0x007f, 0x0040, 0x48eb, 0xa0b8,
+	0x46ec, 0x0078, 0x48ed, 0xa0b8, 0x46e4, 0xb284, 0x0100, 0x0040,
+	0x48f4, 0x7e20, 0x0078, 0x48f5, 0x7e24, 0xa6b5, 0x000c, 0x681c,
+	0xd0b4, 0x0040, 0x48fc, 0xc685, 0x2400, 0xa305, 0x0040, 0x4925,
+	0x2c58, 0x2704, 0x6104, 0xac60, 0x6000, 0xa400, 0x701a, 0x6004,
+	0xa301, 0x701e, 0xd19c, 0x0040, 0x4915, 0x6010, 0xa081, 0x0000,
+	0x7022, 0x6014, 0xa081, 0x0000, 0x7026, 0x6208, 0x2400, 0xa202,
+	0x7012, 0x620c, 0x2300, 0xa203, 0x7016, 0x7602, 0x7007, 0x0001,
+	0x2b60, 0x1078, 0x4a1c, 0x0078, 0x4927, 0x1078, 0x49f2, 0x00c0,
+	0x4925, 0x127f, 0x2000, 0x007c, 0x127e, 0x0d7e, 0x70d4, 0xa084,
+	0x4600, 0x8004, 0x2090, 0x0d7f, 0x7007, 0x0004, 0x7004, 0xd094,
+	0x00c0, 0x4936, 0x7003, 0x0008, 0x127f, 0x2000, 0x007c, 0x127e,
 	0x0d7e, 0x70d4, 0xa084, 0x4600, 0x8004, 0x007e, 0x2090, 0x007f,
-	0x7e20, 0xb284, 0x0100, 0x00c0, 0x4906, 0x7e24, 0x0d7f, 0x037f,
-	0x047f, 0xa6b5, 0x000c, 0x681c, 0xd0b4, 0x0040, 0x4914, 0xc685,
-	0x7003, 0x0000, 0x7007, 0x0004, 0x2049, 0x48f5, 0x6828, 0xa055,
-	0x0d7e, 0x0040, 0x496c, 0x2d70, 0x2e60, 0x7004, 0xa0bc, 0x000f,
-	0xa7b8, 0x466e, 0x273c, 0x87fb, 0x00c0, 0x4931, 0x0048, 0x492a,
-	0x1078, 0x296b, 0x709c, 0xa075, 0x2060, 0x0040, 0x496c, 0x0078,
-	0x491d, 0x2704, 0xae68, 0x6808, 0xa422, 0x680c, 0xa31b, 0x0048,
-	0x494a, 0x8a51, 0x00c0, 0x493e, 0x1078, 0x296b, 0x8738, 0x2704,
-	0xa005, 0x00c0, 0x4932, 0x709c, 0xa075, 0x2060, 0x0040, 0x496c,
-	0x0078, 0x491d, 0x8422, 0x8420, 0x831a, 0xa399, 0x0000, 0x6908,
-	0x2400, 0xa122, 0x690c, 0x2300, 0xa11b, 0x00c8, 0x4959, 0x1078,
-	0x296b, 0xb284, 0x0100, 0x0040, 0x4967, 0x2001, 0x4e04, 0x2004,
-	0xd0ec, 0x00c0, 0x4967, 0x2071, 0x0050, 0x0078, 0x4969, 0x2071,
-	0x0020, 0x0d7f, 0x0078, 0x4879, 0x0d7f, 0x127f, 0x2000, 0x007c,
-	0x7008, 0x007e, 0xa084, 0x01e0, 0x007f, 0x0040, 0x4979, 0xa006,
-	0x007c, 0xa084, 0x0003, 0xa086, 0x0003, 0x00c0, 0x4980, 0x007c,
-	0x2704, 0xac78, 0x7800, 0x701a, 0x7804, 0x701e, 0x7808, 0x7012,
-	0x780c, 0x7016, 0x6004, 0xa084, 0x0008, 0x0040, 0x4993, 0x7810,
-	0x7022, 0x7814, 0x7026, 0x7602, 0x7004, 0xa084, 0x0010, 0xc085,
-	0x7006, 0x2079, 0x4e00, 0x8a51, 0x0040, 0x49bf, 0x8738, 0x2704,
-	0xa005, 0x00c0, 0x49b1, 0x609c, 0xa005, 0x0040, 0x49c0, 0x2060,
-	0x6004, 0xa084, 0x000f, 0xa080, 0x466e, 0x203c, 0x87fb, 0x1040,
-	0x296b, 0x7008, 0x007e, 0xa084, 0x01e0, 0x007f, 0x0040, 0x49bb,
-	0xa006, 0x0078, 0x49c0, 0xa084, 0x0003, 0xa086, 0x0003, 0x007c,
-	0x2051, 0x0000, 0x007c, 0x127e, 0x007e, 0x0d7e, 0x70d4, 0xa084,
-	0x4600, 0x8004, 0x2090, 0x0d7f, 0x087f, 0x7108, 0xa184, 0x0003,
-	0x00c0, 0x49d8, 0x6828, 0xa005, 0x0040, 0x49e8, 0x0078, 0x45a2,
-	0x7108, 0xd1fc, 0x0040, 0x49e0, 0x1078, 0x4769, 0x0078, 0x49cd,
-	0x7007, 0x0010, 0x7108, 0xd1fc, 0x0040, 0x49e2, 0x1078, 0x4769,
-	0x7008, 0xa086, 0x0008, 0x00c0, 0x49cd, 0x7000, 0xa005, 0x00c0,
-	0x49cd, 0x7003, 0x0000, 0x2049, 0x0000, 0x127f, 0x2000, 0x007c,
-	0x127e, 0x147e, 0x137e, 0x157e, 0x0c7e, 0x0d7e, 0x70d4, 0xa084,
-	0x4600, 0x8004, 0x2090, 0x0d7f, 0x2049, 0x49f8, 0xad80, 0x0011,
-	0x20a0, 0xb284, 0x0100, 0x0040, 0x4a1b, 0x2001, 0x4e04, 0x2004,
-	0xd0ec, 0x0040, 0x4a17, 0x2099, 0x0031, 0x0078, 0x4a1d, 0x2099,
-	0x0032, 0x0078, 0x4a1d, 0x2099, 0x0031, 0x700c, 0xa084, 0x03ff,
-	0x682a, 0x7007, 0x0008, 0x7007, 0x0002, 0x7003, 0x0001, 0x0040,
-	0x4a2c, 0x8000, 0x80ac, 0x53a5, 0x700c, 0xa084, 0x03ff, 0x0040,
-	0x4a38, 0x7007, 0x0004, 0x7004, 0xa084, 0x0004, 0x00c0, 0x4a33,
-	0x0c7f, 0x2049, 0x0000, 0x7003, 0x0000, 0x157f, 0x137f, 0x147f,
-	0x127f, 0x2000, 0x007c, 0x2091, 0x8000, 0x2091, 0x6000, 0x78ac,
-	0xa005, 0x00c0, 0x4a5a, 0x7974, 0x70d0, 0xa106, 0x00c0, 0x4a5a,
-	0x781c, 0xa005, 0x0040, 0x4a5a, 0x781f, 0x0000, 0x0068, 0x4a5a,
-	0x2091, 0x4080, 0x7830, 0x8001, 0x7832, 0x00c0, 0x4ae2, 0x7834,
-	0x7832, 0x7810, 0xd0ec, 0x00c0, 0x4adb, 0x2061, 0x73c0, 0x2069,
-	0x4e80, 0xc7fd, 0x68d0, 0xa005, 0x0040, 0x4a74, 0x8001, 0x68d2,
-	0x00c0, 0x4a74, 0x1078, 0x4cb0, 0x6800, 0xa084, 0x000f, 0x0040,
-	0x4a89, 0xa086, 0x0001, 0x0040, 0x4a89, 0x6844, 0xa00d, 0x0040,
-	0x4a89, 0x2104, 0xa005, 0x0040, 0x4a89, 0x8001, 0x200a, 0x0040,
-	0x4c23, 0x6814, 0xa005, 0x0040, 0x4aae, 0x8001, 0x6816, 0x00c0,
-	0x4aae, 0x68a7, 0x0001, 0x0f7e, 0xd7fc, 0x00c0, 0x4aa3, 0x7810,
-	0xd0ec, 0x0040, 0x4a9f, 0x2079, 0x0100, 0x0078, 0x4aa5, 0x2079,
-	0x0200, 0x0078, 0x4aa5, 0x2079, 0x0100, 0x1078, 0x4383, 0x0f7f,
-	0x6864, 0xa005, 0x0040, 0x4aae, 0x1078, 0x2628, 0x6880, 0xa005,
-	0x0040, 0x4abb, 0x8001, 0x6882, 0x00c0, 0x4abb, 0x6867, 0x0000,
-	0x68d4, 0xc0dd, 0x68d6, 0x68d4, 0xd0fc, 0x0040, 0x4ad8, 0xc0fc,
-	0x68d6, 0x20a9, 0x0200, 0x6034, 0xa005, 0x0040, 0x4ad4, 0x8001,
-	0x6036, 0x68d4, 0xc0fd, 0x68d6, 0x00c0, 0x4ad4, 0x6010, 0xa005,
-	0x0040, 0x4ad4, 0x1078, 0x2628, 0xace0, 0x0010, 0x00f0, 0x4ac3,
-	0xd7fc, 0x0040, 0x4ae2, 0x2061, 0x53c0, 0x2069, 0x4e40, 0xc7fc,
-	0x0078, 0x4a6a, 0x1078, 0x4b1e, 0x7838, 0x8001, 0x783a, 0x00c0,
-	0x4b04, 0x783c, 0x783a, 0x2061, 0x53c0, 0x2069, 0x4e40, 0xc7fc,
-	0x680c, 0xa005, 0x0040, 0x4af6, 0x1078, 0x4b88, 0xd7fc, 0x00c0,
-	0x4b04, 0x7810, 0xd0ec, 0x00c0, 0x4b04, 0x2061, 0x73c0, 0x2069,
-	0x4e80, 0xc7fd, 0x0078, 0x4af0, 0x7814, 0xd0e4, 0x00c0, 0x4b08,
-	0x7810, 0xd0cc, 0x0040, 0x4b1b, 0xd0ac, 0x00c0, 0x4b14, 0xd0a4,
-	0x0040, 0x4b1b, 0xc0ad, 0x7812, 0x2091, 0x8001, 0x0068, 0x4b1a,
-	0x1078, 0x2395, 0x007c, 0x2091, 0x8001, 0x007c, 0x7840, 0x8001,
-	0x7842, 0x00c0, 0x4b87, 0x7844, 0x7842, 0x2069, 0x4e40, 0xc7fc,
-	0x7810, 0x2079, 0x0200, 0xd0ec, 0x0040, 0x4b30, 0x2079, 0x0100,
-	0x68d8, 0xa005, 0x0040, 0x4b3c, 0x7de0, 0xa504, 0x00c0, 0x4b3c,
-	0x68da, 0x68d4, 0xc0bc, 0x68d6, 0x2079, 0x4e00, 0x6810, 0xa005,
-	0x00c0, 0x4b44, 0x2001, 0x0101, 0x8001, 0x6812, 0xd7fc, 0x0040,
-	0x4b4d, 0xa080, 0x94d0, 0x0078, 0x4b4f, 0xa080, 0x93c0, 0x2040,
-	0x2004, 0xa065, 0x0040, 0x4b79, 0x6024, 0xa005, 0x0040, 0x4b75,
-	0x8001, 0x6026, 0x00c0, 0x4b75, 0x6800, 0xa005, 0x0040, 0x4b68,
-	0x684c, 0xac06, 0x00c0, 0x4b68, 0x1078, 0x4c23, 0x0078, 0x4b79,
-	0x6864, 0xa005, 0x0040, 0x4b70, 0x6027, 0x0001, 0x0078, 0x4b75,
-	0x1078, 0x4bd6, 0x2804, 0x0078, 0x4b51, 0x6000, 0x2c40, 0x0078,
-	0x4b51, 0xd7fc, 0x00c0, 0x4b87, 0x7810, 0xd0ec, 0x00c0, 0x4b87,
-	0x2069, 0x4e80, 0xc7fd, 0x2079, 0x0100, 0x0078, 0x4b30, 0x007c,
-	0x2009, 0x0000, 0x20a9, 0x0200, 0x6008, 0xd09c, 0x0040, 0x4bc2,
-	0x6024, 0xa005, 0x0040, 0x4b98, 0x8001, 0x6026, 0x0078, 0x4bc0,
-	0x6008, 0xc09c, 0xd084, 0x00c0, 0x4ba0, 0xd0ac, 0x0040, 0x4bba,
-	0x600a, 0x6004, 0xa005, 0x0040, 0x4bc2, 0x0d7e, 0x0c7e, 0x017e,
-	0x2068, 0x6010, 0x8001, 0x6012, 0x1078, 0x3dd0, 0x2d00, 0x2c68,
-	0x2060, 0x1078, 0x1e5b, 0x1078, 0x201d, 0x017f, 0x0c7f, 0x0d7f,
-	0x0078, 0x4bc2, 0xc0bd, 0x600a, 0xa18d, 0x0001, 0x0078, 0x4bc2,
-	0xa18d, 0x0100, 0xace0, 0x0010, 0x00f0, 0x4b8c, 0xa184, 0x0001,
-	0x0040, 0x4bd1, 0xa18c, 0xfffe, 0x690e, 0x1078, 0x2628, 0x0078,
-	0x4bd2, 0x690e, 0x007c, 0x00c0, 0x4bd2, 0x786c, 0x2c00, 0x687e,
-	0x6714, 0x6f76, 0x6017, 0x0000, 0x602b, 0x0000, 0x601b, 0x0006,
-	0x60b4, 0xa084, 0x3f00, 0x601e, 0x6020, 0xa084, 0x00ff, 0xa085,
-	0x0060, 0x6022, 0x6000, 0x2042, 0x1078, 0x1de4, 0x6818, 0xa005,
-	0x0040, 0x4bf4, 0x8001, 0x681a, 0x6808, 0xc0a4, 0x680a, 0x6810,
-	0x7908, 0x8109, 0x790a, 0x8001, 0x00d0, 0x4c00, 0x1078, 0x296b,
-	0x6812, 0x00c0, 0x4c06, 0x7910, 0xc1a5, 0x7912, 0x602f, 0x0000,
-	0x6033, 0x0000, 0x2c68, 0x1078, 0x202c, 0xd7fc, 0x00c0, 0x4c14,
-	0x2069, 0x4e40, 0x0078, 0x4c16, 0x2069, 0x4e80, 0x6910, 0xa184,
-	0x0100, 0x2001, 0x0006, 0x00c0, 0x4c20, 0x697a, 0x2001, 0x0004,
-	0x1078, 0x261c, 0x007c, 0x0d7e, 0x694c, 0x2160, 0xd7fc, 0x00c0,
-	0x4c35, 0x7810, 0xd0ec, 0x0040, 0x4c31, 0x2069, 0x0100, 0x0078,
-	0x4c37, 0x2069, 0x0200, 0x0078, 0x4c37, 0x2069, 0x0100, 0x1078,
-	0x28df, 0x601b, 0x0006, 0x6858, 0xa084, 0x3f00, 0x601e, 0x6020,
-	0xa084, 0x00ff, 0xa085, 0x0048, 0x6022, 0x602f, 0x0000, 0x6033,
-	0x0000, 0x6808, 0xa084, 0xfffd, 0x680a, 0x6830, 0xd0b4, 0x0040,
-	0x4c69, 0x684b, 0x0004, 0x20a9, 0x0014, 0x6848, 0xd094, 0x0040,
-	0x4c5b, 0x00f0, 0x4c55, 0x684b, 0x0009, 0x20a9, 0x0014, 0x6848,
-	0xd084, 0x0040, 0x4c65, 0x00f0, 0x4c5f, 0x20a9, 0x00fa, 0x00f0,
-	0x4c67, 0x681b, 0x0047, 0x0d7f, 0x6867, 0x0007, 0x007c, 0x2079,
-	0x4e00, 0x1078, 0x4ca3, 0x1078, 0x4c89, 0x1078, 0x4c96, 0x2009,
-	0x0002, 0x2069, 0x4e80, 0x680f, 0x0000, 0x6813, 0x0000, 0x6817,
-	0x0000, 0x8109, 0x0040, 0x4c88, 0x2069, 0x4e40, 0x0078, 0x4c7b,
-	0x007c, 0x7810, 0xd0ec, 0x0040, 0x4c91, 0x2019, 0x00cc, 0x0078,
-	0x4c93, 0x2019, 0x007b, 0x7b3a, 0x7b3e, 0x007c, 0x7814, 0xd0e4,
-	0x00c0, 0x4c9e, 0x2019, 0x0040, 0x0078, 0x4ca0, 0x2019, 0x0026,
-	0x7b42, 0x7b46, 0x007c, 0x7814, 0xd0e4, 0x00c0, 0x4cab, 0x2019,
-	0x3f94, 0x0078, 0x4cad, 0x2019, 0x2624, 0x7b32, 0x7b36, 0x007c,
-	0x6a50, 0xa285, 0x0000, 0x0040, 0x4cdc, 0x6954, 0x6bc0, 0xa300,
-	0x0c7e, 0x2164, 0x6304, 0x83ff, 0x00c0, 0x4cc8, 0x8211, 0x0040,
-	0x4ccc, 0x8108, 0xa11a, 0x0048, 0x4cb9, 0x69c0, 0x0078, 0x4cb9,
-	0x68d3, 0x000a, 0x0c7f, 0x007c, 0x6950, 0x6ac0, 0x2264, 0x602b,
-	0x0000, 0x602f, 0x0000, 0x6008, 0xc0b5, 0x600a, 0x8210, 0x8109,
-	0x00c0, 0x4cce, 0x6952, 0x0c7f, 0x007c, 0x00e0, 0x4cdd, 0x2091,
-	0x6000, 0x00e0, 0x4ce1, 0x2091, 0x6000, 0x70ec, 0xd0dc, 0x00c0,
-	0x4cee, 0xd0d4, 0x0040, 0x4d17, 0x0078, 0x4d1a, 0x2008, 0x7810,
-	0xd0ec, 0x0040, 0x4d01, 0xd1c4, 0x00c0, 0x4d39, 0x7814, 0xc0c5,
-	0x7816, 0x7810, 0xc0f5, 0x7812, 0xd0ec, 0x0040, 0x4d35, 0x0078,
-	0x4d31, 0xae8e, 0x0100, 0x0040, 0x4d0e, 0x7814, 0xc0f5, 0xc0c5,
-	0x7816, 0xd0d4, 0x00c0, 0x4d35, 0x0078, 0x4d31, 0x7814, 0xc0fd,
-	0xc0c5, 0x7816, 0xd0d4, 0x00c0, 0x4d35, 0x0078, 0x4d31, 0xd0e4,
-	0x0040, 0x4d37, 0x00e0, 0x4d1a, 0x2091, 0x6000, 0x2009, 0x000c,
-	0x00e0, 0x4d20, 0x2091, 0x6000, 0x8109, 0x00c0, 0x4d20, 0x70e4,
-	0xa084, 0x01ff, 0xa086, 0x01ff, 0x00c0, 0x4d31, 0x70ec, 0x0078,
-	0x4cee, 0x7804, 0xd08c, 0x0040, 0x4d37, 0x681f, 0x000c, 0x70a0,
-	0x70a2, 0x007c, 0x205b
+	0x0d7f, 0x7e20, 0xb284, 0x0100, 0x00c0, 0x494f, 0x7e24, 0xa6b5,
+	0x000c, 0x681c, 0xd0ac, 0x00c0, 0x495a, 0xc685, 0x7003, 0x0000,
+	0x7007, 0x0004, 0x6828, 0x2050, 0x2d60, 0x6004, 0xa0bc, 0x000f,
+	0xa7b8, 0x46f2, 0x273c, 0x87fb, 0x00c0, 0x4970, 0x0048, 0x496a,
+	0x1078, 0x29b2, 0x689c, 0xa065, 0x0040, 0x4974, 0x0078, 0x495d,
+	0x1078, 0x49f2, 0x00c0, 0x4970, 0x127f, 0x2000, 0x007c, 0x127e,
+	0x007e, 0x017e, 0x0d7e, 0x70d4, 0xa084, 0x4600, 0x8004, 0x007e,
+	0x2090, 0x007f, 0x7e20, 0xb284, 0x0100, 0x00c0, 0x4988, 0x7e24,
+	0x0d7f, 0x037f, 0x047f, 0xa6b5, 0x000c, 0x681c, 0xd0b4, 0x0040,
+	0x4996, 0xc685, 0x7003, 0x0000, 0x7007, 0x0004, 0x2049, 0x4977,
+	0x6828, 0xa055, 0x0d7e, 0x0040, 0x49ee, 0x2d70, 0x2e60, 0x7004,
+	0xa0bc, 0x000f, 0xa7b8, 0x46f2, 0x273c, 0x87fb, 0x00c0, 0x49b3,
+	0x0048, 0x49ac, 0x1078, 0x29b2, 0x709c, 0xa075, 0x2060, 0x0040,
+	0x49ee, 0x0078, 0x499f, 0x2704, 0xae68, 0x6808, 0xa422, 0x680c,
+	0xa31b, 0x0048, 0x49cc, 0x8a51, 0x00c0, 0x49c0, 0x1078, 0x29b2,
+	0x8738, 0x2704, 0xa005, 0x00c0, 0x49b4, 0x709c, 0xa075, 0x2060,
+	0x0040, 0x49ee, 0x0078, 0x499f, 0x8422, 0x8420, 0x831a, 0xa399,
+	0x0000, 0x6908, 0x2400, 0xa122, 0x690c, 0x2300, 0xa11b, 0x00c8,
+	0x49db, 0x1078, 0x29b2, 0xb284, 0x0100, 0x0040, 0x49e9, 0x2001,
+	0x4f04, 0x2004, 0xd0ec, 0x00c0, 0x49e9, 0x2071, 0x0050, 0x0078,
+	0x49eb, 0x2071, 0x0020, 0x0d7f, 0x0078, 0x48fc, 0x0d7f, 0x127f,
+	0x2000, 0x007c, 0x7008, 0x007e, 0xa084, 0x01e0, 0x007f, 0x0040,
+	0x49fb, 0xa006, 0x007c, 0xa084, 0x0003, 0xa086, 0x0003, 0x00c0,
+	0x4a02, 0x007c, 0x2704, 0xac78, 0x7800, 0x701a, 0x7804, 0x701e,
+	0x7808, 0x7012, 0x780c, 0x7016, 0x6004, 0xd09c, 0x0040, 0x4a14,
+	0x7810, 0x7022, 0x7814, 0x7026, 0x7602, 0x7004, 0xa084, 0x0010,
+	0xc085, 0x7006, 0x2079, 0x4f00, 0x8738, 0x8a51, 0x0040, 0x4a40,
+	0x2704, 0xa005, 0x00c0, 0x4a32, 0x609c, 0xa005, 0x0040, 0x4a41,
+	0x2060, 0x6004, 0xa084, 0x000f, 0xa080, 0x46f2, 0x203c, 0x87fb,
+	0x1040, 0x29b2, 0x7008, 0x007e, 0xa084, 0x01e0, 0x007f, 0x0040,
+	0x4a3c, 0xa006, 0x0078, 0x4a41, 0xa084, 0x0003, 0xa086, 0x0003,
+	0x007c, 0x2051, 0x0000, 0x007c, 0x127e, 0x007e, 0x0d7e, 0x70d4,
+	0xa084, 0x4600, 0x8004, 0x2090, 0x0d7f, 0x087f, 0x7108, 0xa184,
+	0x0003, 0x00c0, 0x4a59, 0x6828, 0xa005, 0x0040, 0x4a69, 0x0078,
+	0x4602, 0x7108, 0xd1fc, 0x0040, 0x4a61, 0x1078, 0x47ed, 0x0078,
+	0x4a4e, 0x7007, 0x0010, 0x7108, 0xd1fc, 0x0040, 0x4a63, 0x1078,
+	0x47ed, 0x7008, 0xa086, 0x0008, 0x00c0, 0x4a4e, 0x7000, 0xa005,
+	0x00c0, 0x4a4e, 0x7003, 0x0000, 0x2049, 0x0000, 0x007e, 0x7804,
+	0xd0cc, 0x0040, 0x4a7d, 0x1078, 0x4acc, 0x007f, 0x127f, 0x2000,
+	0x007c, 0x127e, 0x147e, 0x137e, 0x157e, 0x0c7e, 0x0d7e, 0x70d4,
+	0xa084, 0x4600, 0x8004, 0x2090, 0x0d7f, 0x2049, 0x4a81, 0xad80,
+	0x0011, 0x20a0, 0xb284, 0x0100, 0x0040, 0x4aa4, 0x2001, 0x4f04,
+	0x2004, 0xd0ec, 0x0040, 0x4aa0, 0x2099, 0x0031, 0x0078, 0x4aa6,
+	0x2099, 0x0032, 0x0078, 0x4aa6, 0x2099, 0x0031, 0x700c, 0xa084,
+	0x03ff, 0x682a, 0x7007, 0x0008, 0x7007, 0x0002, 0x7003, 0x0001,
+	0x0040, 0x4ab5, 0x8000, 0x80ac, 0x53a5, 0x700c, 0xa084, 0x03ff,
+	0x0040, 0x4ac1, 0x7007, 0x0004, 0x7004, 0xa084, 0x0004, 0x00c0,
+	0x4abc, 0x0c7f, 0x2049, 0x0000, 0x7003, 0x0000, 0x157f, 0x137f,
+	0x147f, 0x127f, 0x2000, 0x007c, 0x6814, 0xd0fc, 0x0040, 0x4b11,
+	0x7000, 0xd084, 0x0040, 0x4b11, 0x7e24, 0xa6b5, 0x0004, 0x7007,
+	0x0004, 0x7004, 0xa084, 0x0004, 0x00c0, 0x4ad9, 0x7118, 0x017e,
+	0x711c, 0x017e, 0x7120, 0x017e, 0x7124, 0x017e, 0xa00e, 0x711a,
+	0x701f, 0x3fff, 0x7122, 0x7126, 0x7013, 0x0004, 0x7116, 0x7602,
+	0x7007, 0x0001, 0x2001, 0xffff, 0x2009, 0x0031, 0x200a, 0x200a,
+	0x7108, 0x7008, 0xa106, 0x00c0, 0x4af8, 0xd1fc, 0x0040, 0x4af8,
+	0x027f, 0x7226, 0x027f, 0x7222, 0x027f, 0x721e, 0x027f, 0x721a,
+	0x7007, 0x0002, 0x7008, 0xa086, 0x0008, 0x0040, 0x4b11, 0x0078,
+	0x4830, 0x7007, 0x0004, 0x7003, 0x0000, 0x007c, 0x2091, 0x8000,
+	0x2091, 0x6000, 0x78ac, 0xa005, 0x00c0, 0x4b2d, 0x7974, 0x70d0,
+	0xa106, 0x00c0, 0x4b2d, 0x781c, 0xa005, 0x0040, 0x4b2d, 0x781f,
+	0x0000, 0x0068, 0x4b2d, 0x2091, 0x4080, 0x7830, 0x8001, 0x7832,
+	0x00c0, 0x4bb5, 0x7834, 0x7832, 0x7810, 0xd0ec, 0x00c0, 0x4bae,
+	0x2061, 0x74c0, 0x2069, 0x4f80, 0xc7fd, 0x68d0, 0xa005, 0x0040,
+	0x4b47, 0x8001, 0x68d2, 0x00c0, 0x4b47, 0x1078, 0x4d83, 0x6800,
+	0xa084, 0x000f, 0x0040, 0x4b5c, 0xa086, 0x0001, 0x0040, 0x4b5c,
+	0x6844, 0xa00d, 0x0040, 0x4b5c, 0x2104, 0xa005, 0x0040, 0x4b5c,
+	0x8001, 0x200a, 0x0040, 0x4cf6, 0x6814, 0xa005, 0x0040, 0x4b81,
+	0x8001, 0x6816, 0x00c0, 0x4b81, 0x68a7, 0x0001, 0x0f7e, 0xd7fc,
+	0x00c0, 0x4b76, 0x7810, 0xd0ec, 0x0040, 0x4b72, 0x2079, 0x0100,
+	0x0078, 0x4b78, 0x2079, 0x0200, 0x0078, 0x4b78, 0x2079, 0x0100,
+	0x1078, 0x43d3, 0x0f7f, 0x6864, 0xa005, 0x0040, 0x4b81, 0x1078,
+	0x266f, 0x6880, 0xa005, 0x0040, 0x4b8e, 0x8001, 0x6882, 0x00c0,
+	0x4b8e, 0x6867, 0x0000, 0x68d4, 0xc0dd, 0x68d6, 0x68d4, 0xd0fc,
+	0x0040, 0x4bab, 0xc0fc, 0x68d6, 0x20a9, 0x0200, 0x6034, 0xa005,
+	0x0040, 0x4ba7, 0x8001, 0x6036, 0x68d4, 0xc0fd, 0x68d6, 0x00c0,
+	0x4ba7, 0x6010, 0xa005, 0x0040, 0x4ba7, 0x1078, 0x266f, 0xace0,
+	0x0010, 0x00f0, 0x4b96, 0xd7fc, 0x0040, 0x4bb5, 0x2061, 0x54c0,
+	0x2069, 0x4f40, 0xc7fc, 0x0078, 0x4b3d, 0x1078, 0x4bf1, 0x7838,
+	0x8001, 0x783a, 0x00c0, 0x4bd7, 0x783c, 0x783a, 0x2061, 0x54c0,
+	0x2069, 0x4f40, 0xc7fc, 0x680c, 0xa005, 0x0040, 0x4bc9, 0x1078,
+	0x4c5b, 0xd7fc, 0x00c0, 0x4bd7, 0x7810, 0xd0ec, 0x00c0, 0x4bd7,
+	0x2061, 0x74c0, 0x2069, 0x4f80, 0xc7fd, 0x0078, 0x4bc3, 0x7814,
+	0xd0e4, 0x00c0, 0x4bdb, 0x7810, 0xd0cc, 0x0040, 0x4bee, 0xd0ac,
+	0x00c0, 0x4be7, 0xd0a4, 0x0040, 0x4bee, 0xc0ad, 0x7812, 0x2091,
+	0x8001, 0x0068, 0x4bed, 0x1078, 0x23dc, 0x007c, 0x2091, 0x8001,
+	0x007c, 0x7840, 0x8001, 0x7842, 0x00c0, 0x4c5a, 0x7844, 0x7842,
+	0x2069, 0x4f40, 0xc7fc, 0x7810, 0x2079, 0x0200, 0xd0ec, 0x0040,
+	0x4c03, 0x2079, 0x0100, 0x68d8, 0xa005, 0x0040, 0x4c0f, 0x7de0,
+	0xa504, 0x00c0, 0x4c0f, 0x68da, 0x68d4, 0xc0bc, 0x68d6, 0x2079,
+	0x4f00, 0x6810, 0xa005, 0x00c0, 0x4c17, 0x2001, 0x0101, 0x8001,
+	0x6812, 0xd7fc, 0x0040, 0x4c20, 0xa080, 0x95d0, 0x0078, 0x4c22,
+	0xa080, 0x94c0, 0x2040, 0x2004, 0xa065, 0x0040, 0x4c4c, 0x6024,
+	0xa005, 0x0040, 0x4c48, 0x8001, 0x6026, 0x00c0, 0x4c48, 0x6800,
+	0xa005, 0x0040, 0x4c3b, 0x684c, 0xac06, 0x00c0, 0x4c3b, 0x1078,
+	0x4cf6, 0x0078, 0x4c4c, 0x6864, 0xa005, 0x0040, 0x4c43, 0x6027,
+	0x0001, 0x0078, 0x4c48, 0x1078, 0x4ca9, 0x2804, 0x0078, 0x4c24,
+	0x6000, 0x2c40, 0x0078, 0x4c24, 0xd7fc, 0x00c0, 0x4c5a, 0x7810,
+	0xd0ec, 0x00c0, 0x4c5a, 0x2069, 0x4f80, 0xc7fd, 0x2079, 0x0100,
+	0x0078, 0x4c03, 0x007c, 0x2009, 0x0000, 0x20a9, 0x0200, 0x6008,
+	0xd09c, 0x0040, 0x4c95, 0x6024, 0xa005, 0x0040, 0x4c6b, 0x8001,
+	0x6026, 0x0078, 0x4c93, 0x6008, 0xc09c, 0xd084, 0x00c0, 0x4c73,
+	0xd0ac, 0x0040, 0x4c8d, 0x600a, 0x6004, 0xa005, 0x0040, 0x4c95,
+	0x0d7e, 0x0c7e, 0x017e, 0x2068, 0x6010, 0x8001, 0x6012, 0x1078,
+	0x3e19, 0x2d00, 0x2c68, 0x2060, 0x1078, 0x1ea2, 0x1078, 0x2064,
+	0x017f, 0x0c7f, 0x0d7f, 0x0078, 0x4c95, 0xc0bd, 0x600a, 0xa18d,
+	0x0001, 0x0078, 0x4c95, 0xa18d, 0x0100, 0xace0, 0x0010, 0x00f0,
+	0x4c5f, 0xa184, 0x0001, 0x0040, 0x4ca4, 0xa18c, 0xfffe, 0x690e,
+	0x1078, 0x266f, 0x0078, 0x4ca5, 0x690e, 0x007c, 0x00c0, 0x4ca5,
+	0x786c, 0x2c00, 0x687e, 0x6714, 0x6f76, 0x6017, 0x0000, 0x602b,
+	0x0000, 0x601b, 0x0006, 0x60b4, 0xa084, 0x3f00, 0x601e, 0x6020,
+	0xa084, 0x00ff, 0xa085, 0x0060, 0x6022, 0x6000, 0x2042, 0x1078,
+	0x1e2b, 0x6818, 0xa005, 0x0040, 0x4cc7, 0x8001, 0x681a, 0x6808,
+	0xc0a4, 0x680a, 0x6810, 0x7908, 0x8109, 0x790a, 0x8001, 0x00d0,
+	0x4cd3, 0x1078, 0x29b2, 0x6812, 0x00c0, 0x4cd9, 0x7910, 0xc1a5,
+	0x7912, 0x602f, 0x0000, 0x6033, 0x0000, 0x2c68, 0x1078, 0x2073,
+	0xd7fc, 0x00c0, 0x4ce7, 0x2069, 0x4f40, 0x0078, 0x4ce9, 0x2069,
+	0x4f80, 0x6910, 0xa184, 0x0100, 0x2001, 0x0006, 0x00c0, 0x4cf3,
+	0x697a, 0x2001, 0x0004, 0x1078, 0x2663, 0x007c, 0x0d7e, 0x694c,
+	0x2160, 0xd7fc, 0x00c0, 0x4d08, 0x7810, 0xd0ec, 0x0040, 0x4d04,
+	0x2069, 0x0100, 0x0078, 0x4d0a, 0x2069, 0x0200, 0x0078, 0x4d0a,
+	0x2069, 0x0100, 0x1078, 0x2926, 0x601b, 0x0006, 0x6858, 0xa084,
+	0x3f00, 0x601e, 0x6020, 0xa084, 0x00ff, 0xa085, 0x0048, 0x6022,
+	0x602f, 0x0000, 0x6033, 0x0000, 0x6808, 0xa084, 0xfffd, 0x680a,
+	0x6830, 0xd0b4, 0x0040, 0x4d3c, 0x684b, 0x0004, 0x20a9, 0x0014,
+	0x6848, 0xd094, 0x0040, 0x4d2e, 0x00f0, 0x4d28, 0x684b, 0x0009,
+	0x20a9, 0x0014, 0x6848, 0xd084, 0x0040, 0x4d38, 0x00f0, 0x4d32,
+	0x20a9, 0x00fa, 0x00f0, 0x4d3a, 0x681b, 0x0047, 0x0d7f, 0x6867,
+	0x0007, 0x007c, 0x2079, 0x4f00, 0x1078, 0x4d76, 0x1078, 0x4d5c,
+	0x1078, 0x4d69, 0x2009, 0x0002, 0x2069, 0x4f80, 0x680f, 0x0000,
+	0x6813, 0x0000, 0x6817, 0x0000, 0x8109, 0x0040, 0x4d5b, 0x2069,
+	0x4f40, 0x0078, 0x4d4e, 0x007c, 0x7810, 0xd0ec, 0x0040, 0x4d64,
+	0x2019, 0x00cc, 0x0078, 0x4d66, 0x2019, 0x007b, 0x7b3a, 0x7b3e,
+	0x007c, 0x7814, 0xd0e4, 0x00c0, 0x4d71, 0x2019, 0x0040, 0x0078,
+	0x4d73, 0x2019, 0x0026, 0x7b42, 0x7b46, 0x007c, 0x7814, 0xd0e4,
+	0x00c0, 0x4d7e, 0x2019, 0x3f94, 0x0078, 0x4d80, 0x2019, 0x2624,
+	0x7b32, 0x7b36, 0x007c, 0x6a50, 0xa285, 0x0000, 0x0040, 0x4daf,
+	0x6954, 0x6bc0, 0xa300, 0x0c7e, 0x2164, 0x6304, 0x83ff, 0x00c0,
+	0x4d9b, 0x8211, 0x0040, 0x4d9f, 0x8108, 0xa11a, 0x0048, 0x4d8c,
+	0x69c0, 0x0078, 0x4d8c, 0x68d3, 0x000a, 0x0c7f, 0x007c, 0x6950,
+	0x6ac0, 0x2264, 0x602b, 0x0000, 0x602f, 0x0000, 0x6008, 0xc0b5,
+	0x600a, 0x8210, 0x8109, 0x00c0, 0x4da1, 0x6952, 0x0c7f, 0x007c,
+	0x00e0, 0x4db0, 0x2091, 0x6000, 0x00e0, 0x4db4, 0x2091, 0x6000,
+	0x70ec, 0xd0dc, 0x00c0, 0x4dc1, 0xd0d4, 0x0040, 0x4dea, 0x0078,
+	0x4ded, 0x2008, 0x7810, 0xd0ec, 0x0040, 0x4dd4, 0xd1c4, 0x00c0,
+	0x4e0e, 0x7814, 0xc0c5, 0x7816, 0x7810, 0xc0f5, 0x7812, 0xd0ec,
+	0x0040, 0x4e0a, 0x0078, 0x4e06, 0xae8e, 0x0100, 0x0040, 0x4de1,
+	0x7814, 0xc0f5, 0xc0c5, 0x7816, 0xd0d4, 0x00c0, 0x4e0a, 0x0078,
+	0x4e06, 0x7814, 0xc0fd, 0xc0c5, 0x7816, 0xd0d4, 0x00c0, 0x4e0a,
+	0x0078, 0x4e06, 0xd0e4, 0x0040, 0x4e0c, 0x00e0, 0x4ded, 0x2091,
+	0x6000, 0x2009, 0x000c, 0x00e0, 0x4df3, 0x2091, 0x6000, 0x8109,
+	0x00c0, 0x4df3, 0x70e4, 0xa084, 0x01ff, 0xa086, 0x01ff, 0x00c0,
+	0x4e04, 0x70ec, 0x0078, 0x4dc1, 0x1078, 0x4e0f, 0x7804, 0xd08c,
+	0x0040, 0x4e0c, 0x681f, 0x000c, 0x70a0, 0x70a2, 0x007c, 0x7910,
+	0xd1ec, 0x0040, 0x4e19, 0x7814, 0xc0c4, 0xc1f4, 0x7912, 0x0078,
+	0x4e2b, 0xae8e, 0x0100, 0x0040, 0x4e25, 0x7814, 0xc0f4, 0xd0fc,
+	0x00c0, 0x4e2b, 0xc0c4, 0x0078, 0x4e2b, 0x7814, 0xc0fc, 0xd0f4,
+	0x00c0, 0x4e2b, 0xc0c4, 0x7816, 0x007c, 0x14e3
 };
 #ifdef UNIQUE_FW_NAME
-static unsigned short   fw1280ei_length01 = 0x3d3b;
+static unsigned short fw1280ei_length01 = 0x3e2e;
 #else
-static unsigned short   risc_code_length01 = 0x3d3b;
+static unsigned short risc_code_length01 = 0x3e2e;
 #endif
+
diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c
--- a/drivers/scsi/qla1280.c
+++ b/drivers/scsi/qla1280.c
@@ -1098,7 +1098,13 @@ qla1280_error_action(struct scsi_cmnd *c
 static int
 qla1280_eh_abort(struct scsi_cmnd * cmd)
 {
-	return qla1280_error_action(cmd, ABORT_COMMAND);
+	int rc;
+
+	spin_lock_irq(cmd->device->host->host_lock);
+	rc = qla1280_error_action(cmd, ABORT_COMMAND);
+	spin_unlock_irq(cmd->device->host->host_lock);
+
+	return rc;
 }
 
 /**************************************************************************
@@ -1108,7 +1114,13 @@ qla1280_eh_abort(struct scsi_cmnd * cmd)
 static int
 qla1280_eh_device_reset(struct scsi_cmnd *cmd)
 {
-	return qla1280_error_action(cmd, DEVICE_RESET);
+	int rc;
+
+	spin_lock_irq(cmd->device->host->host_lock);
+	rc = qla1280_error_action(cmd, DEVICE_RESET);
+	spin_unlock_irq(cmd->device->host->host_lock);
+
+	return rc;
 }
 
 /**************************************************************************
@@ -1118,7 +1130,13 @@ qla1280_eh_device_reset(struct scsi_cmnd
 static int
 qla1280_eh_bus_reset(struct scsi_cmnd *cmd)
 {
-	return qla1280_error_action(cmd, BUS_RESET);
+	int rc;
+
+	spin_lock_irq(cmd->device->host->host_lock);
+	rc = qla1280_error_action(cmd, BUS_RESET);
+	spin_unlock_irq(cmd->device->host->host_lock);
+
+	return rc;
 }
 
 /**************************************************************************
@@ -1128,7 +1146,13 @@ qla1280_eh_bus_reset(struct scsi_cmnd *c
 static int
 qla1280_eh_adapter_reset(struct scsi_cmnd *cmd)
 {
-	return qla1280_error_action(cmd, ADAPTER_RESET);
+	int rc;
+
+	spin_lock_irq(cmd->device->host->host_lock);
+	rc = qla1280_error_action(cmd, ADAPTER_RESET);
+	spin_unlock_irq(cmd->device->host->host_lock);
+
+	return rc;
 }
 
 static int
@@ -2829,7 +2853,7 @@ qla1280_bus_reset(struct scsi_qla_host *
 		ha->bus_settings[bus].failed_reset_count++;
 	} else {
 		spin_unlock_irq(HOST_LOCK);
-		schedule_timeout(reset_delay * HZ);
+		ssleep(reset_delay);
 		spin_lock_irq(HOST_LOCK);
 
 		ha->bus_settings[bus].scsi_bus_dead = 0;
@@ -4038,11 +4062,10 @@ qla1280_status_entry(struct scsi_qla_hos
 			scsi_status, handle);
 	}
 
-	/* Target busy */
-	if (scsi_status & SS_BUSY_CONDITION &&
-	    scsi_status != SS_RESERVE_CONFLICT) {
-		CMD_RESULT(cmd) =
-			DID_BUS_BUSY << 16 | (scsi_status & 0xff);
+	/* Target busy or queue full */
+	if ((scsi_status & 0xFF) == SAM_STAT_TASK_SET_FULL ||
+	    (scsi_status & 0xFF) == SAM_STAT_BUSY) {
+		CMD_RESULT(cmd) = scsi_status & 0xff;
 	} else {
 
 		/* Save ISP completion status */
diff --git a/drivers/scsi/qla2xxx/Kconfig b/drivers/scsi/qla2xxx/Kconfig
--- a/drivers/scsi/qla2xxx/Kconfig
+++ b/drivers/scsi/qla2xxx/Kconfig
@@ -7,6 +7,7 @@ config SCSI_QLA21XX
 	tristate "QLogic ISP2100 host adapter family support"
 	depends on SCSI_QLA2XXX
         select SCSI_FC_ATTRS
+	select FW_LOADER
 	---help---
 	This driver supports the QLogic 21xx (ISP2100) host adapter family.
 
@@ -14,6 +15,7 @@ config SCSI_QLA22XX
 	tristate "QLogic ISP2200 host adapter family support"
 	depends on SCSI_QLA2XXX
         select SCSI_FC_ATTRS
+	select FW_LOADER
 	---help---
 	This driver supports the QLogic 22xx (ISP2200) host adapter family.
 
@@ -21,6 +23,7 @@ config SCSI_QLA2300
 	tristate "QLogic ISP2300 host adapter family support"
 	depends on SCSI_QLA2XXX
         select SCSI_FC_ATTRS
+	select FW_LOADER
 	---help---
 	This driver supports the QLogic 2300 (ISP2300 and ISP2312) host
 	adapter family.
@@ -29,6 +32,7 @@ config SCSI_QLA2322
 	tristate "QLogic ISP2322 host adapter family support"
 	depends on SCSI_QLA2XXX
         select SCSI_FC_ATTRS
+	select FW_LOADER
 	---help---
 	This driver supports the QLogic 2322 (ISP2322) host adapter family.
 
@@ -36,6 +40,16 @@ config SCSI_QLA6312
 	tristate "QLogic ISP63xx host adapter family support"
 	depends on SCSI_QLA2XXX
         select SCSI_FC_ATTRS
+	select FW_LOADER
 	---help---
 	This driver supports the QLogic 63xx (ISP6312 and ISP6322) host
 	adapter family.
+
+config SCSI_QLA24XX
+	tristate "QLogic ISP24xx host adapter family support"
+	depends on SCSI_QLA2XXX
+	select SCSI_FC_ATTRS
+	select FW_LOADER
+	---help---
+	This driver supports the QLogic 24xx (ISP2422 and ISP2432) host
+	adapter family.
diff --git a/drivers/scsi/qla2xxx/Makefile b/drivers/scsi/qla2xxx/Makefile
--- a/drivers/scsi/qla2xxx/Makefile
+++ b/drivers/scsi/qla2xxx/Makefile
@@ -14,3 +14,4 @@ obj-$(CONFIG_SCSI_QLA22XX) += qla2xxx.o 
 obj-$(CONFIG_SCSI_QLA2300) += qla2xxx.o qla2300.o
 obj-$(CONFIG_SCSI_QLA2322) += qla2xxx.o qla2322.o
 obj-$(CONFIG_SCSI_QLA6312) += qla2xxx.o qla6312.o
+obj-$(CONFIG_SCSI_QLA24XX) += qla2xxx.o
diff --git a/drivers/scsi/qla2xxx/ql2100.c b/drivers/scsi/qla2xxx/ql2100.c
--- a/drivers/scsi/qla2xxx/ql2100.c
+++ b/drivers/scsi/qla2xxx/ql2100.c
@@ -1,7 +1,7 @@
 /*
  * QLogic ISP2100 device driver for Linux 2.6.x
  * Copyright (C) 2003 Christoph Hellwig.
- * Copyright (C) 2003-2004 QLogic Corporation (www.qlogic.com)
+ * Copyright (C) 2003-2005 QLogic Corporation (www.qlogic.com)
  *
  * Released under GPL v2.
  */
diff --git a/drivers/scsi/qla2xxx/ql2100_fw.c b/drivers/scsi/qla2xxx/ql2100_fw.c
--- a/drivers/scsi/qla2xxx/ql2100_fw.c
+++ b/drivers/scsi/qla2xxx/ql2100_fw.c
@@ -2,7 +2,7 @@
  *                  QLOGIC LINUX SOFTWARE
  *
  * QLogic ISP2x00 device driver for Linux 2.6.x
- * Copyright (C) 2003-2004 QLogic Corporation
+ * Copyright (C) 2003-2005 QLogic Corporation
  * (www.qlogic.com)
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -18,7 +18,7 @@
  *************************************************************************/
 
 /*
- *	Firmware Version 1.19.24 (14:02 Jul 16, 2002)
+ *	Firmware Version 1.19.25 (13:12 Dec 10, 2003)
  */
 
 #ifdef UNIQUE_FW_NAME
@@ -28,15 +28,15 @@ unsigned short risc_code_version = 1*102
 #endif
 
 #ifdef UNIQUE_FW_NAME
-unsigned char fw2100tp_version_str[] = {1,19,24};
+unsigned char fw2100tp_version_str[] = {1,19,25};
 #else
-unsigned char firmware_version[] = {1,19,24};
+unsigned char firmware_version[] = {1,19,25};
 #endif
 
 #ifdef UNIQUE_FW_NAME
-#define fw2100tp_VERSION_STRING "1.19.24"
+#define fw2100tp_VERSION_STRING "1.19.25"
 #else
-#define FW_VERSION_STRING "1.19.24"
+#define FW_VERSION_STRING "1.19.25"
 #endif
 
 #ifdef UNIQUE_FW_NAME
@@ -50,7 +50,7 @@ unsigned short fw2100tp_code01[] = { 
 #else
 unsigned short risc_code01[] = { 
 #endif
-	0x0078, 0x102d, 0x0000, 0x95f1, 0x0000, 0x0001, 0x0013, 0x0018,
+	0x0078, 0x102d, 0x0000, 0x9601, 0x0000, 0x0001, 0x0013, 0x0019,
 	0x0017, 0x2043, 0x4f50, 0x5952, 0x4947, 0x4854, 0x2032, 0x3030,
 	0x3120, 0x514c, 0x4f47, 0x4943, 0x2043, 0x4f52, 0x504f, 0x5241,
 	0x5449, 0x4f4e, 0x2049, 0x5350, 0x3231, 0x3030, 0x2046, 0x6972,
@@ -60,16 +60,16 @@ unsigned short risc_code01[] = { 
 	0x20c1, 0x0020, 0x2c2c, 0x2d34, 0x2762, 0x236a, 0x2c24, 0x2d04,
 	0x266a, 0x2562, 0xa406, 0x00c0, 0x1052, 0x20c1, 0x0021, 0x2c2c,
 	0x2362, 0x2c04, 0x2562, 0xa306, 0x0040, 0x1052, 0x20c1, 0x0020,
-	0x2039, 0x8fff, 0x20a1, 0xad00, 0x2708, 0x810d, 0x810d, 0x810d,
+	0x2039, 0x8fff, 0x20a1, 0xae00, 0x2708, 0x810d, 0x810d, 0x810d,
 	0x810d, 0xa18c, 0x000f, 0x2001, 0x000a, 0xa112, 0xa00e, 0x21a8,
 	0x41a4, 0x3400, 0x8211, 0x00c0, 0x105f, 0x2708, 0x3400, 0xa102,
 	0x0040, 0x106f, 0x0048, 0x106f, 0x20a8, 0xa00e, 0x41a4, 0x20a1,
-	0xa5f1, 0x2009, 0x0000, 0x20a9, 0x070f, 0x41a4, 0x3400, 0x20c9,
-	0xaaff, 0x2059, 0x0000, 0x2b78, 0x7823, 0x0004, 0x2089, 0x25c7,
-	0x2051, 0xa600, 0x2a70, 0x7762, 0xa786, 0x8fff, 0x0040, 0x1092,
-	0x705f, 0xcd00, 0x705b, 0xccf1, 0x7067, 0x0200, 0x706b, 0x0200,
-	0x0078, 0x109a, 0x705b, 0xbd01, 0x7067, 0x0100, 0x706b, 0x0100,
-	0x705f, 0xbd00, 0x1078, 0x12df, 0x1078, 0x13ca, 0x1078, 0x1577,
+	0xa601, 0x2009, 0x0000, 0x20a9, 0x07ff, 0x41a4, 0x3400, 0x20c9,
+	0xabff, 0x2059, 0x0000, 0x2b78, 0x7823, 0x0004, 0x2089, 0x25c7,
+	0x2051, 0xa700, 0x2a70, 0x7762, 0xa786, 0x8fff, 0x0040, 0x1092,
+	0x705f, 0xce00, 0x705b, 0xcdf1, 0x7067, 0x0200, 0x706b, 0x0200,
+	0x0078, 0x109a, 0x705b, 0xbe01, 0x7067, 0x0100, 0x706b, 0x0100,
+	0x705f, 0xbe00, 0x1078, 0x12df, 0x1078, 0x13ca, 0x1078, 0x1577,
 	0x1078, 0x1ce9, 0x1078, 0x42ec, 0x1078, 0x76bf, 0x1078, 0x1355,
 	0x1078, 0x2ac0, 0x1078, 0x4e93, 0x1078, 0x49a3, 0x1078, 0x594a,
 	0x1078, 0x2263, 0x1078, 0x5c43, 0x1078, 0x5485, 0x1078, 0x2162,
@@ -87,15 +87,15 @@ unsigned short risc_code01[] = { 
 	0xa005, 0x00c0, 0x1198, 0x2011, 0x41dc, 0x1078, 0x5a45, 0x1078,
 	0x1adf, 0x780f, 0x00ff, 0x7840, 0xa084, 0xfffb, 0x7842, 0x2011,
 	0x8010, 0x73c4, 0x1078, 0x361b, 0x2001, 0xffff, 0x1078, 0x5ae6,
-	0x723c, 0xc284, 0x723e, 0x2001, 0xa60c, 0x2014, 0xc2ac, 0x2202,
-	0x1078, 0x6f9f, 0x2011, 0x0004, 0x1078, 0x8d1b, 0x1078, 0x489e,
+	0x723c, 0xc284, 0x723e, 0x2001, 0xa70c, 0x2014, 0xc2ac, 0x2202,
+	0x1078, 0x6f9f, 0x2011, 0x0004, 0x1078, 0x8d2b, 0x1078, 0x489e,
 	0x1078, 0x42d4, 0x0040, 0x1144, 0x7087, 0x0001, 0x70bf, 0x0000,
 	0x1078, 0x3c9e, 0x0078, 0x1198, 0x1078, 0x4967, 0x0040, 0x114d,
-	0x7a0c, 0xc2b4, 0x7a0e, 0x0078, 0x1159, 0x1078, 0x90a6, 0x70cc,
+	0x7a0c, 0xc2b4, 0x7a0e, 0x0078, 0x1159, 0x1078, 0x90b6, 0x70cc,
 	0xd09c, 0x00c0, 0x1159, 0x7098, 0xa005, 0x0040, 0x1159, 0x1078,
-	0x42b8, 0x70d7, 0x0000, 0x70d3, 0x0000, 0x72cc, 0x2079, 0xa652,
+	0x42b8, 0x70d7, 0x0000, 0x70d3, 0x0000, 0x72cc, 0x2079, 0xa752,
 	0x7804, 0xd0ac, 0x0040, 0x1165, 0xc295, 0x72ce, 0xa296, 0x0004,
-	0x0040, 0x1186, 0x2011, 0x0001, 0x1078, 0x8d1b, 0x7093, 0x0000,
+	0x0040, 0x1186, 0x2011, 0x0001, 0x1078, 0x8d2b, 0x7093, 0x0000,
 	0x7097, 0xffff, 0x7003, 0x0002, 0x0f7f, 0x1078, 0x2677, 0x2011,
 	0x0005, 0x1078, 0x70e0, 0x1078, 0x62d1, 0x0c7e, 0x2061, 0x0100,
 	0x60e3, 0x0008, 0x0c7f, 0x127f, 0x0078, 0x119a, 0x7093, 0x0000,
@@ -103,7 +103,7 @@ unsigned short risc_code01[] = { 
 	0x1078, 0x62d1, 0x0c7e, 0x2061, 0x0100, 0x60e3, 0x0008, 0x0c7f,
 	0x0f7f, 0x127f, 0x007c, 0x0c7e, 0x20a9, 0x0082, 0x2009, 0x007e,
 	0x017e, 0x027e, 0x037e, 0x2110, 0x027e, 0x2019, 0x0029, 0x1078,
-	0x73d0, 0x027f, 0x1078, 0xa4f1, 0x037f, 0x027f, 0x017f, 0x1078,
+	0x73d0, 0x027f, 0x1078, 0xa501, 0x037f, 0x027f, 0x017f, 0x1078,
 	0x298e, 0x8108, 0x00f0, 0x11a0, 0x0c7f, 0x706f, 0x0000, 0x7070,
 	0xa084, 0x00ff, 0x7072, 0x709b, 0x0000, 0x007c, 0x127e, 0x2091,
 	0x8000, 0x7000, 0xa086, 0x0002, 0x00c0, 0x1244, 0x7094, 0xa086,
@@ -114,13 +114,13 @@ unsigned short risc_code01[] = { 
 	0x27f7, 0x1078, 0x62d1, 0x70cc, 0xd094, 0x00c0, 0x1244, 0x2011,
 	0x0001, 0x2019, 0x0000, 0x1078, 0x282f, 0x1078, 0x62d1, 0x0078,
 	0x1244, 0x70d4, 0xa005, 0x00c0, 0x1244, 0x7090, 0xa005, 0x00c0,
-	0x1244, 0x1078, 0x4967, 0x00c0, 0x1244, 0x2001, 0xa653, 0x2004,
+	0x1244, 0x1078, 0x4967, 0x00c0, 0x1244, 0x2001, 0xa753, 0x2004,
 	0xd0ac, 0x0040, 0x1227, 0x157e, 0x0c7e, 0x20a9, 0x007f, 0x2009,
 	0x0000, 0x017e, 0x1078, 0x45c4, 0x00c0, 0x121a, 0x6000, 0xd0ec,
 	0x00c0, 0x1222, 0x017f, 0x8108, 0x00f0, 0x1211, 0x0c7f, 0x157f,
 	0x0078, 0x1227, 0x017f, 0x0c7f, 0x157f, 0x0078, 0x1244, 0x7003,
 	0x0003, 0x7097, 0xffff, 0x2001, 0x0000, 0x1078, 0x24e8, 0x1078,
-	0x3699, 0x2001, 0xa8b2, 0x2004, 0xa086, 0x0005, 0x00c0, 0x123c,
+	0x3699, 0x2001, 0xa9b2, 0x2004, 0xa086, 0x0005, 0x00c0, 0x123c,
 	0x2011, 0x0000, 0x1078, 0x70e0, 0x2011, 0x0000, 0x1078, 0x70ea,
 	0x1078, 0x62d1, 0x1078, 0x639b, 0x127f, 0x007c, 0x017e, 0x0f7e,
 	0x127e, 0x2091, 0x8000, 0x2079, 0x0100, 0x2009, 0x00f7, 0x1078,
@@ -137,51 +137,51 @@ unsigned short risc_code01[] = { 
 	0x00f0, 0x129f, 0x7853, 0x1400, 0x7843, 0x0090, 0x7843, 0x0010,
 	0x2019, 0x61a8, 0x7854, 0x0005, 0x0005, 0xd08c, 0x0040, 0x12b4,
 	0x7824, 0xd0ac, 0x00c0, 0x12ca, 0x8319, 0x00c0, 0x12aa, 0x2009,
-	0xa632, 0x2104, 0x8000, 0x200a, 0xa084, 0xfff0, 0x0040, 0x12c4,
+	0xa732, 0x2104, 0x8000, 0x200a, 0xa084, 0xfff0, 0x0040, 0x12c4,
 	0x200b, 0x0000, 0x1078, 0x2588, 0x2001, 0x0001, 0x1078, 0x24e8,
-	0x0078, 0x12d3, 0x2001, 0xa632, 0x2003, 0x0000, 0x7828, 0xc09d,
+	0x0078, 0x12d3, 0x2001, 0xa732, 0x2003, 0x0000, 0x7828, 0xc09d,
 	0x782a, 0x7827, 0x0048, 0x7853, 0x0400, 0x157f, 0x037f, 0x007f,
 	0x127f, 0x0f7f, 0x017f, 0x007c, 0x007c, 0x007c, 0x007c, 0x2a70,
-	0x2061, 0xa8ad, 0x2063, 0x0001, 0x6007, 0x0013, 0x600b, 0x0018,
+	0x2061, 0xa9ad, 0x2063, 0x0001, 0x6007, 0x0013, 0x600b, 0x0019,
 	0x600f, 0x0017, 0x2009, 0x0100, 0x2104, 0xa082, 0x0002, 0x0048,
 	0x12f5, 0x7053, 0xffff, 0x0078, 0x12f7, 0x7053, 0x0000, 0x7057,
-	0xffff, 0x706f, 0x0000, 0x7073, 0x0000, 0x1078, 0x90a6, 0x2061,
-	0xa88d, 0x6003, 0x0909, 0x6007, 0x0000, 0x600b, 0x8800, 0x600f,
+	0xffff, 0x706f, 0x0000, 0x7073, 0x0000, 0x1078, 0x90b6, 0x2061,
+	0xa98d, 0x6003, 0x0909, 0x6007, 0x0000, 0x600b, 0x8800, 0x600f,
 	0x0200, 0x6013, 0x00ff, 0x6017, 0x0003, 0x601b, 0x0000, 0x601f,
-	0x07d0, 0x2061, 0xa895, 0x6003, 0x8000, 0x6007, 0x0000, 0x600b,
+	0x07d0, 0x2061, 0xa995, 0x6003, 0x8000, 0x6007, 0x0000, 0x600b,
 	0x0000, 0x600f, 0x0200, 0x6013, 0x00ff, 0x6017, 0x0000, 0x601b,
-	0x0001, 0x601f, 0x0000, 0x2061, 0xa8a5, 0x6003, 0x514c, 0x6007,
-	0x4f47, 0x600b, 0x4943, 0x600f, 0x2020, 0x2001, 0xa626, 0x2003,
+	0x0001, 0x601f, 0x0000, 0x2061, 0xa9a5, 0x6003, 0x514c, 0x6007,
+	0x4f47, 0x600b, 0x4943, 0x600f, 0x2020, 0x2001, 0xa726, 0x2003,
 	0x0000, 0x007c, 0x2091, 0x8000, 0x0068, 0x1334, 0x007e, 0x017e,
 	0x2079, 0x0000, 0x7818, 0xd084, 0x00c0, 0x133a, 0x017f, 0x792e,
 	0x007f, 0x782a, 0x007f, 0x7826, 0x3900, 0x783a, 0x7823, 0x8002,
-	0x781b, 0x0001, 0x2091, 0x5000, 0x2091, 0x4080, 0x2079, 0xa600,
-	0x7803, 0x0005, 0x0078, 0x1352, 0x007c, 0x2071, 0xa600, 0x715c,
+	0x781b, 0x0001, 0x2091, 0x5000, 0x2091, 0x4080, 0x2079, 0xa700,
+	0x7803, 0x0005, 0x0078, 0x1352, 0x007c, 0x2071, 0xa700, 0x715c,
 	0x712e, 0x2021, 0x0001, 0xa190, 0x002d, 0xa298, 0x002d, 0x0048,
 	0x136b, 0x7060, 0xa302, 0x00c8, 0x136b, 0x220a, 0x2208, 0x2310,
 	0x8420, 0x0078, 0x135d, 0x200b, 0x0000, 0x74aa, 0x74ae, 0x007c,
-	0x0e7e, 0x127e, 0x2091, 0x8000, 0x2071, 0xa600, 0x70ac, 0xa0ea,
+	0x0e7e, 0x127e, 0x2091, 0x8000, 0x2071, 0xa700, 0x70ac, 0xa0ea,
 	0x0010, 0x00c8, 0x137e, 0xa06e, 0x0078, 0x1388, 0x8001, 0x70ae,
 	0x702c, 0x2068, 0x2d04, 0x702e, 0x206b, 0x0000, 0x6807, 0x0000,
-	0x127f, 0x0e7f, 0x007c, 0x0e7e, 0x2071, 0xa600, 0x127e, 0x2091,
+	0x127f, 0x0e7f, 0x007c, 0x0e7e, 0x2071, 0xa700, 0x127e, 0x2091,
 	0x8000, 0x70ac, 0x8001, 0x00c8, 0x1398, 0xa06e, 0x0078, 0x13a1,
 	0x70ae, 0x702c, 0x2068, 0x2d04, 0x702e, 0x206b, 0x0000, 0x6807,
 	0x0000, 0x127f, 0x0e7f, 0x007c, 0x0e7e, 0x127e, 0x2091, 0x8000,
-	0x2071, 0xa600, 0x702c, 0x206a, 0x2d00, 0x702e, 0x70ac, 0x8000,
+	0x2071, 0xa700, 0x702c, 0x206a, 0x2d00, 0x702e, 0x70ac, 0x8000,
 	0x70ae, 0x127f, 0x0e7f, 0x007c, 0x8dff, 0x0040, 0x13c0, 0x6804,
 	0x6807, 0x0000, 0x007e, 0x1078, 0x13a4, 0x0d7f, 0x0078, 0x13b4,
-	0x007c, 0x0e7e, 0x2071, 0xa600, 0x70ac, 0xa08a, 0x0010, 0xa00d,
-	0x0e7f, 0x007c, 0x0e7e, 0x2071, 0xa8d6, 0x7007, 0x0000, 0x701b,
+	0x007c, 0x0e7e, 0x2071, 0xa700, 0x70ac, 0xa08a, 0x0010, 0xa00d,
+	0x0e7f, 0x007c, 0x0e7e, 0x2071, 0xa9d6, 0x7007, 0x0000, 0x701b,
 	0x0000, 0x701f, 0x0000, 0x2071, 0x0000, 0x7010, 0xa085, 0x8004,
 	0x7012, 0x0e7f, 0x007c, 0x127e, 0x2091, 0x8000, 0x0e7e, 0x2270,
-	0x700b, 0x0000, 0x2071, 0xa8d6, 0x7018, 0xa088, 0xa8df, 0x220a,
+	0x700b, 0x0000, 0x2071, 0xa9d6, 0x7018, 0xa088, 0xa9df, 0x220a,
 	0x8000, 0xa084, 0x0007, 0x701a, 0x7004, 0xa005, 0x00c0, 0x13f6,
 	0x0f7e, 0x2079, 0x0010, 0x1078, 0x1408, 0x0f7f, 0x0e7f, 0x127f,
-	0x007c, 0x0e7e, 0x2071, 0xa8d6, 0x7004, 0xa005, 0x00c0, 0x1406,
+	0x007c, 0x0e7e, 0x2071, 0xa9d6, 0x7004, 0xa005, 0x00c0, 0x1406,
 	0x0f7e, 0x2079, 0x0010, 0x1078, 0x1408, 0x0f7f, 0x0e7f, 0x007c,
 	0x7000, 0x0079, 0x140b, 0x140f, 0x1479, 0x1496, 0x1496, 0x7018,
 	0x711c, 0xa106, 0x00c0, 0x1417, 0x7007, 0x0000, 0x007c, 0x0d7e,
-	0xa180, 0xa8df, 0x2004, 0x700a, 0x2068, 0x8108, 0xa18c, 0x0007,
+	0xa180, 0xa9df, 0x2004, 0x700a, 0x2068, 0x8108, 0xa18c, 0x0007,
 	0x711e, 0x7803, 0x0026, 0x6824, 0x7832, 0x6828, 0x7836, 0x682c,
 	0x783a, 0x6830, 0x783e, 0x6810, 0x700e, 0x680c, 0x7016, 0x6804,
 	0x0d7f, 0xd084, 0x0040, 0x1439, 0x7007, 0x0001, 0x1078, 0x143e,
@@ -193,16 +193,16 @@ unsigned short risc_code01[] = { 
 	0x2011, 0x0040, 0xa182, 0x0040, 0x00c8, 0x1468, 0x2110, 0xa006,
 	0x700e, 0x22a8, 0x53a6, 0x8203, 0x7822, 0x7803, 0x0020, 0x3300,
 	0x7016, 0x7803, 0x0001, 0x157f, 0x147f, 0x137f, 0x027f, 0x017f,
-	0x007c, 0x137e, 0x147e, 0x157e, 0x2099, 0xa6fa, 0x20a1, 0x0018,
+	0x007c, 0x137e, 0x147e, 0x157e, 0x2099, 0xa7fa, 0x20a1, 0x0018,
 	0x20a9, 0x0008, 0x53a3, 0x7803, 0x0020, 0x127e, 0x2091, 0x8000,
 	0x7803, 0x0041, 0x7007, 0x0003, 0x7000, 0xc084, 0x7002, 0x700b,
-	0xa6f5, 0x127f, 0x157f, 0x147f, 0x137f, 0x007c, 0x137e, 0x147e,
-	0x157e, 0x2001, 0xa729, 0x209c, 0x20a1, 0x0014, 0x7803, 0x0026,
-	0x2001, 0xa72a, 0x20ac, 0x53a6, 0x2099, 0xa72b, 0x20a1, 0x0018,
+	0xa7f5, 0x127f, 0x157f, 0x147f, 0x137f, 0x007c, 0x137e, 0x147e,
+	0x157e, 0x2001, 0xa829, 0x209c, 0x20a1, 0x0014, 0x7803, 0x0026,
+	0x2001, 0xa82a, 0x20ac, 0x53a6, 0x2099, 0xa82b, 0x20a1, 0x0018,
 	0x20a9, 0x0008, 0x53a3, 0x7803, 0x0020, 0x127e, 0x2091, 0x8000,
 	0x7803, 0x0001, 0x7007, 0x0004, 0x7000, 0xc08c, 0x7002, 0x700b,
-	0xa726, 0x127f, 0x157f, 0x147f, 0x137f, 0x007c, 0x017e, 0x0e7e,
-	0x2071, 0xa8d6, 0x0f7e, 0x2079, 0x0010, 0x7904, 0x7803, 0x0002,
+	0xa826, 0x127f, 0x157f, 0x147f, 0x137f, 0x007c, 0x017e, 0x0e7e,
+	0x2071, 0xa9d6, 0x0f7e, 0x2079, 0x0010, 0x7904, 0x7803, 0x0002,
 	0xd1fc, 0x0040, 0x14d0, 0xa18c, 0x0700, 0x7004, 0x1079, 0x14d4,
 	0x0f7f, 0x0e7f, 0x017f, 0x007c, 0x1408, 0x14dc, 0x1509, 0x1531,
 	0x1564, 0x14da, 0x0078, 0x14da, 0xa18c, 0x0700, 0x00c0, 0x1502,
@@ -217,16 +217,16 @@ unsigned short risc_code01[] = { 
 	0x2068, 0x7830, 0x6826, 0x7834, 0x682a, 0x7838, 0x682e, 0x783c,
 	0x6832, 0x680b, 0x0100, 0x0d7f, 0x7007, 0x0000, 0x1078, 0x1408,
 	0x007c, 0xa18c, 0x0700, 0x00c0, 0x155e, 0x137e, 0x147e, 0x157e,
-	0x2001, 0xa6f8, 0x2004, 0xa080, 0x000d, 0x20a0, 0x2099, 0x0014,
-	0x7803, 0x0040, 0x20a9, 0x0020, 0x53a5, 0x2001, 0xa6fa, 0x2004,
-	0xd0bc, 0x0040, 0x1554, 0x2001, 0xa703, 0x2004, 0xa080, 0x000d,
+	0x2001, 0xa7f8, 0x2004, 0xa080, 0x000d, 0x20a0, 0x2099, 0x0014,
+	0x7803, 0x0040, 0x20a9, 0x0020, 0x53a5, 0x2001, 0xa7fa, 0x2004,
+	0xd0bc, 0x0040, 0x1554, 0x2001, 0xa803, 0x2004, 0xa080, 0x000d,
 	0x20a0, 0x20a9, 0x0020, 0x53a5, 0x157f, 0x147f, 0x137f, 0x7007,
 	0x0000, 0x1078, 0x4f8c, 0x1078, 0x1408, 0x007c, 0x2011, 0x8003,
 	0x1078, 0x361b, 0x0078, 0x1562, 0xa18c, 0x0700, 0x00c0, 0x1571,
-	0x2001, 0xa728, 0x2003, 0x0100, 0x7007, 0x0000, 0x1078, 0x1408,
+	0x2001, 0xa828, 0x2003, 0x0100, 0x7007, 0x0000, 0x1078, 0x1408,
 	0x007c, 0x2011, 0x8004, 0x1078, 0x361b, 0x0078, 0x1575, 0x127e,
-	0x2091, 0x2100, 0x2079, 0x0030, 0x2071, 0xa8e7, 0x7803, 0x0004,
-	0x7003, 0x0000, 0x700f, 0xa8ed, 0x7013, 0xa8ed, 0x780f, 0x0076,
+	0x2091, 0x2100, 0x2079, 0x0030, 0x2071, 0xa9e7, 0x7803, 0x0004,
+	0x7003, 0x0000, 0x700f, 0xa9ed, 0x7013, 0xa9ed, 0x780f, 0x0076,
 	0x7803, 0x0004, 0x127f, 0x007c, 0x6934, 0xa184, 0x0007, 0x0079,
 	0x1591, 0x1599, 0x15df, 0x1599, 0x1599, 0x1599, 0x15c4, 0x15a8,
 	0x159d, 0xa085, 0x0001, 0x0078, 0x15f9, 0x684c, 0xd0bc, 0x0040,
@@ -249,7 +249,7 @@ unsigned short risc_code01[] = { 
 	0x2091, 0x2100, 0x027f, 0x037f, 0x047f, 0x7000, 0xa005, 0x00c0,
 	0x1630, 0x7206, 0x2001, 0x1651, 0x007e, 0x2260, 0x0078, 0x17e0,
 	0x710c, 0x220a, 0x8108, 0x230a, 0x8108, 0x240a, 0x8108, 0xa182,
-	0xa908, 0x0048, 0x163d, 0x2009, 0xa8ed, 0x710e, 0x7010, 0xa102,
+	0xaa08, 0x0048, 0x163d, 0x2009, 0xa9ed, 0x710e, 0x7010, 0xa102,
 	0xa082, 0x0009, 0x0040, 0x1648, 0xa080, 0x001b, 0x00c0, 0x164b,
 	0x2009, 0x0138, 0x200a, 0x7000, 0xa005, 0x00c0, 0x1651, 0x1078,
 	0x17c1, 0x127f, 0x007c, 0x127e, 0x027e, 0x037e, 0x0c7e, 0x007e,
@@ -285,7 +285,7 @@ unsigned short risc_code01[] = { 
 	0x6810, 0xa300, 0x6812, 0x6814, 0xa201, 0x6816, 0x7803, 0x0004,
 	0x7003, 0x0000, 0x6100, 0xa18e, 0x0004, 0x00c0, 0x1753, 0x2009,
 	0x0048, 0x1078, 0x775c, 0x0c7f, 0x0d7f, 0x127f, 0x007c, 0x0f7e,
-	0x0e7e, 0x027e, 0x037e, 0x047e, 0x057e, 0x2071, 0xa8e7, 0x7000,
+	0x0e7e, 0x027e, 0x037e, 0x047e, 0x057e, 0x2071, 0xa9e7, 0x7000,
 	0xa086, 0x0000, 0x0040, 0x17ba, 0x7004, 0xac06, 0x00c0, 0x17ab,
 	0x2079, 0x0030, 0x7000, 0xa086, 0x0003, 0x0040, 0x17ab, 0x7804,
 	0xd0fc, 0x00c0, 0x17a7, 0x20e1, 0x6000, 0x2011, 0x0032, 0x2001,
@@ -295,12 +295,12 @@ unsigned short risc_code01[] = { 
 	0x178d, 0x7803, 0x0002, 0x7803, 0x0009, 0x7003, 0x0003, 0x7007,
 	0x0000, 0x057f, 0x027f, 0x2001, 0x015d, 0x2003, 0x0000, 0x2001,
 	0x0160, 0x2502, 0x2001, 0x0138, 0x2202, 0x0078, 0x17ab, 0x1078,
-	0x1913, 0x0078, 0x175f, 0x157e, 0x20a9, 0x0009, 0x2009, 0xa8ed,
+	0x1913, 0x0078, 0x175f, 0x157e, 0x20a9, 0x0009, 0x2009, 0xa9ed,
 	0x2104, 0xac06, 0x00c0, 0x17b5, 0x200a, 0xa188, 0x0003, 0x00f0,
 	0x17b0, 0x157f, 0x057f, 0x047f, 0x037f, 0x027f, 0x0e7f, 0x0f7f,
 	0x007c, 0x700c, 0x7110, 0xa106, 0x00c0, 0x17c9, 0x7003, 0x0000,
 	0x007c, 0x2104, 0x7006, 0x2060, 0x8108, 0x211c, 0x8108, 0x2124,
-	0x8108, 0xa182, 0xa908, 0x0048, 0x17d7, 0x2009, 0xa8ed, 0x7112,
+	0x8108, 0xa182, 0xaa08, 0x0048, 0x17d7, 0x2009, 0xa9ed, 0x7112,
 	0x700c, 0xa106, 0x00c0, 0x17e0, 0x2001, 0x0138, 0x2003, 0x0008,
 	0x8cff, 0x00c0, 0x17e7, 0x1078, 0x1b4d, 0x0078, 0x1854, 0x6010,
 	0x2068, 0x2d58, 0x6828, 0xa406, 0x00c0, 0x17f2, 0x682c, 0xa306,
@@ -309,7 +309,7 @@ unsigned short risc_code01[] = { 
 	0x6034, 0xa303, 0x0040, 0x1806, 0x00c8, 0x1818, 0x643a, 0x6336,
 	0x6c2a, 0x6b2e, 0x047e, 0x037e, 0x2400, 0x6c7c, 0xa402, 0x6812,
 	0x2300, 0x6b80, 0xa303, 0x6816, 0x037f, 0x047f, 0x0078, 0x181c,
-	0x1078, 0x9053, 0x0040, 0x17e3, 0x2001, 0xa674, 0x2004, 0xd0b4,
+	0x1078, 0x9063, 0x0040, 0x17e3, 0x2001, 0xa774, 0x2004, 0xd0b4,
 	0x00c0, 0x182b, 0x6018, 0x2004, 0xd0bc, 0x00c0, 0x182b, 0x6817,
 	0x7fff, 0x6813, 0xffff, 0x1078, 0x208a, 0x00c0, 0x17e3, 0x0c7e,
 	0x7004, 0x2060, 0x6024, 0xc0d4, 0x6026, 0x0c7f, 0x684c, 0xd0f4,
@@ -337,9 +337,9 @@ unsigned short risc_code01[] = { 
 	0xa201, 0x682e, 0x2300, 0x6b10, 0xa302, 0x6812, 0x2200, 0x6a14,
 	0xa203, 0x6816, 0x1078, 0x2026, 0x007c, 0x1078, 0x1332, 0x1078,
 	0x1c97, 0x7004, 0x2060, 0x0d7e, 0x6010, 0x2068, 0x7003, 0x0000,
-	0x1078, 0x1af4, 0x1078, 0x8d06, 0x0040, 0x190c, 0x6808, 0x8001,
+	0x1078, 0x1af4, 0x1078, 0x8d16, 0x0040, 0x190c, 0x6808, 0x8001,
 	0x680a, 0x697c, 0x6912, 0x6980, 0x6916, 0x682b, 0xffff, 0x682f,
-	0xffff, 0x6850, 0xc0bd, 0x6852, 0x0d7f, 0x1078, 0x8a01, 0x0078,
+	0xffff, 0x6850, 0xc0bd, 0x6852, 0x0d7f, 0x1078, 0x8a11, 0x0078,
 	0x1adb, 0x1078, 0x1332, 0x127e, 0x2091, 0x2100, 0x007e, 0x017e,
 	0x2b68, 0x6818, 0x2060, 0x7904, 0x7803, 0x0002, 0xa184, 0x0700,
 	0x00c0, 0x18ef, 0xa184, 0x0003, 0xa086, 0x0003, 0x0040, 0x1911,
@@ -361,7 +361,7 @@ unsigned short risc_code01[] = { 
 	0x19a7, 0x7004, 0x2060, 0x2009, 0x0048, 0x1078, 0x775c, 0x7000,
 	0xa086, 0x0004, 0x0040, 0x1adb, 0x7003, 0x0000, 0x1078, 0x17c1,
 	0x0078, 0x1adb, 0x057e, 0x7d0c, 0xd5bc, 0x00c0, 0x19b9, 0x1078,
-	0xa57e, 0x057f, 0x1078, 0x1af4, 0x0f7e, 0x7004, 0x2078, 0x1078,
+	0xa58e, 0x057f, 0x1078, 0x1af4, 0x0f7e, 0x7004, 0x2078, 0x1078,
 	0x4963, 0x0040, 0x19c6, 0x7824, 0xc0f5, 0x7826, 0x0f7f, 0x682b,
 	0xffff, 0x682f, 0xffff, 0x6808, 0x8001, 0x680a, 0x697c, 0x6912,
 	0x6980, 0x6916, 0x0078, 0x1adb, 0x7004, 0x0c7e, 0x2060, 0x6024,
@@ -388,7 +388,7 @@ unsigned short risc_code01[] = { 
 	0x680c, 0xa213, 0x7810, 0xa100, 0x7812, 0x690c, 0x7814, 0xa101,
 	0x7816, 0x0078, 0x1a8f, 0x6810, 0x2008, 0xa31a, 0x6814, 0xa213,
 	0x7810, 0xa100, 0x7812, 0x6914, 0x7814, 0xa101, 0x7816, 0x0f7f,
-	0x0d7f, 0x0078, 0x196d, 0x057e, 0x7d0c, 0x1078, 0xa57e, 0x057f,
+	0x0d7f, 0x0078, 0x196d, 0x057e, 0x7d0c, 0x1078, 0xa58e, 0x057f,
 	0x1078, 0x1af4, 0x0f7e, 0x7004, 0x2078, 0x1078, 0x4963, 0x0040,
 	0x1aa4, 0x7824, 0xc0f5, 0x7826, 0x0f7f, 0x682b, 0xffff, 0x682f,
 	0xffff, 0x6808, 0x8001, 0x680a, 0x697c, 0x6912, 0x6980, 0x6916,
@@ -399,11 +399,11 @@ unsigned short risc_code01[] = { 
 	0xa005, 0x0040, 0x1ac5, 0x2068, 0x6808, 0x8000, 0x680a, 0x6c28,
 	0x6b2c, 0x1078, 0x17e0, 0x017f, 0x007f, 0x127f, 0x007c, 0x127e,
 	0x2091, 0x2100, 0x7000, 0xa086, 0x0003, 0x00c0, 0x1af2, 0x700c,
-	0x7110, 0xa106, 0x0040, 0x1af2, 0x20e1, 0x9028, 0x700f, 0xa8ed,
-	0x7013, 0xa8ed, 0x127f, 0x007c, 0x0c7e, 0x1078, 0x1b22, 0x20e1,
+	0x7110, 0xa106, 0x0040, 0x1af2, 0x20e1, 0x9028, 0x700f, 0xa9ed,
+	0x7013, 0xa9ed, 0x127f, 0x007c, 0x0c7e, 0x1078, 0x1b22, 0x20e1,
 	0x9028, 0x700c, 0x7110, 0xa106, 0x0040, 0x1b19, 0x2104, 0xa005,
 	0x0040, 0x1b08, 0x2060, 0x6010, 0x2060, 0x6008, 0x8001, 0x600a,
-	0xa188, 0x0003, 0xa182, 0xa908, 0x0048, 0x1b10, 0x2009, 0xa8ed,
+	0xa188, 0x0003, 0xa182, 0xaa08, 0x0048, 0x1b10, 0x2009, 0xa9ed,
 	0x7112, 0x700c, 0xa106, 0x00c0, 0x1af9, 0x2011, 0x0008, 0x0078,
 	0x1af9, 0x2001, 0x015d, 0x2003, 0x0000, 0x2001, 0x0138, 0x2202,
 	0x0c7f, 0x007c, 0x2001, 0x0138, 0x2014, 0x2003, 0x0000, 0x2021,
@@ -415,7 +415,7 @@ unsigned short risc_code01[] = { 
 	0x1b55, 0x780c, 0xd0a4, 0x0040, 0x1b5b, 0x1078, 0x1af4, 0xa085,
 	0x0001, 0x0078, 0x1b5d, 0x1078, 0x1b92, 0x007c, 0x0e7e, 0x2071,
 	0x0200, 0x7808, 0xa084, 0xf000, 0xa10d, 0x1078, 0x1b22, 0x2019,
-	0x5000, 0x8319, 0x0040, 0x1b7c, 0x2001, 0xa908, 0x2004, 0xa086,
+	0x5000, 0x8319, 0x0040, 0x1b7c, 0x2001, 0xaa08, 0x2004, 0xa086,
 	0x0000, 0x0040, 0x1b7c, 0x2001, 0x0021, 0xd0fc, 0x0040, 0x1b69,
 	0x1078, 0x1eaa, 0x0078, 0x1b67, 0x20e1, 0x7000, 0x7324, 0x7420,
 	0x7028, 0x7028, 0x7426, 0x7037, 0x0001, 0x810f, 0x712e, 0x702f,
@@ -447,7 +447,7 @@ unsigned short risc_code01[] = { 
 	0x6004, 0x7836, 0xa006, 0x783a, 0x783e, 0x0078, 0x1c65, 0x6010,
 	0x7822, 0x686e, 0x6014, 0x7826, 0x6872, 0x6000, 0x7832, 0x6004,
 	0x7836, 0x6008, 0x783a, 0x600c, 0x783e, 0x7803, 0x0011, 0x0c7f,
-	0x0d7f, 0x007c, 0x0f7e, 0x0e7e, 0x017e, 0x027e, 0x2071, 0xa8e7,
+	0x0d7f, 0x007c, 0x0f7e, 0x0e7e, 0x017e, 0x027e, 0x2071, 0xa9e7,
 	0x2079, 0x0030, 0x2011, 0x0050, 0x7000, 0xa086, 0x0000, 0x0040,
 	0x1c92, 0x8211, 0x0040, 0x1c90, 0x2001, 0x0005, 0x2004, 0xd08c,
 	0x0040, 0x1c79, 0x7904, 0xa18c, 0x0780, 0x017e, 0x1078, 0x1913,
@@ -455,7 +455,7 @@ unsigned short risc_code01[] = { 
 	0xa085, 0x0001, 0x027f, 0x017f, 0x0e7f, 0x0f7f, 0x007c, 0x7803,
 	0x0004, 0x2009, 0x0064, 0x7804, 0xd0ac, 0x0040, 0x1ce8, 0x8109,
 	0x00c0, 0x1c9b, 0x2009, 0x0100, 0x210c, 0xa18a, 0x0003, 0x1048,
-	0x1332, 0x1078, 0x1fca, 0x0e7e, 0x0f7e, 0x2071, 0xa8d6, 0x2079,
+	0x1332, 0x1078, 0x1fca, 0x0e7e, 0x0f7e, 0x2071, 0xa9d6, 0x2079,
 	0x0010, 0x7004, 0xa086, 0x0000, 0x0040, 0x1ce0, 0x7800, 0x007e,
 	0x7820, 0x007e, 0x7830, 0x007e, 0x7834, 0x007e, 0x7838, 0x007e,
 	0x783c, 0x007e, 0x7803, 0x0004, 0x7823, 0x0000, 0x0005, 0x0005,
@@ -463,7 +463,7 @@ unsigned short risc_code01[] = { 
 	0x007f, 0x783e, 0x007f, 0x783a, 0x007f, 0x7836, 0x007f, 0x7832,
 	0x007f, 0x7822, 0x007f, 0x7802, 0x0f7f, 0x0e7f, 0x0078, 0x1ce6,
 	0x0f7f, 0x0e7f, 0x7804, 0xd0ac, 0x10c0, 0x1332, 0x1078, 0x639b,
-	0x007c, 0x0e7e, 0x2071, 0xa908, 0x7003, 0x0000, 0x0e7f, 0x007c,
+	0x007c, 0x0e7e, 0x2071, 0xaa08, 0x7003, 0x0000, 0x0e7f, 0x007c,
 	0x0d7e, 0xa280, 0x0004, 0x206c, 0x694c, 0xd1dc, 0x00c0, 0x1d6b,
 	0x6934, 0xa184, 0x0007, 0x0079, 0x1cfd, 0x1d05, 0x1d56, 0x1d05,
 	0x1d05, 0x1d05, 0x1d3b, 0x1d18, 0x1d07, 0x1078, 0x1332, 0x684c,
@@ -480,7 +480,7 @@ unsigned short risc_code01[] = { 
 	0x0040, 0x18ed, 0x6958, 0xa006, 0x682e, 0x682a, 0x2d00, 0x681a,
 	0x6834, 0xa084, 0x000f, 0xa080, 0x206a, 0x2004, 0x6832, 0x6926,
 	0x684c, 0xc0dd, 0x684e, 0x0d7f, 0x007c, 0x0f7e, 0x2079, 0x0020,
-	0x7804, 0xd0fc, 0x10c0, 0x1eaa, 0x0e7e, 0x0d7e, 0x2071, 0xa908,
+	0x7804, 0xd0fc, 0x10c0, 0x1eaa, 0x0e7e, 0x0d7e, 0x2071, 0xaa08,
 	0x7000, 0xa005, 0x00c0, 0x1df0, 0x0c7e, 0x7206, 0xa280, 0x0004,
 	0x205c, 0x7004, 0x2068, 0x7803, 0x0004, 0x6818, 0x0d7e, 0x2068,
 	0x686c, 0x7812, 0x6890, 0x0f7e, 0x20e1, 0x9040, 0x2079, 0x0200,
@@ -515,12 +515,12 @@ unsigned short risc_code01[] = { 
 	0x1e72, 0xa006, 0x027f, 0x037f, 0x047f, 0x057f, 0x067f, 0x077f,
 	0x007c, 0x1078, 0x1332, 0x027e, 0x2001, 0x0105, 0x2003, 0x0010,
 	0x20e1, 0x9040, 0x7803, 0x0004, 0x7003, 0x0000, 0x7004, 0x2060,
-	0x0d7e, 0x6010, 0x2068, 0x1078, 0x8d06, 0x0040, 0x1e92, 0x6850,
-	0xc0bd, 0x6852, 0x0d7f, 0x0c7e, 0x1078, 0x8a01, 0x0c7f, 0x2001,
-	0xa8c0, 0x2004, 0xac06, 0x00c0, 0x1ea7, 0x20e1, 0x9040, 0x1078,
+	0x0d7e, 0x6010, 0x2068, 0x1078, 0x8d16, 0x0040, 0x1e92, 0x6850,
+	0xc0bd, 0x6852, 0x0d7f, 0x0c7e, 0x1078, 0x8a11, 0x0c7f, 0x2001,
+	0xa9c0, 0x2004, 0xac06, 0x00c0, 0x1ea7, 0x20e1, 0x9040, 0x1078,
 	0x738a, 0x2011, 0x0000, 0x1078, 0x70ea, 0x1078, 0x639b, 0x027f,
 	0x0078, 0x1f76, 0x127e, 0x2091, 0x2200, 0x007e, 0x017e, 0x0f7e,
-	0x0e7e, 0x0d7e, 0x0c7e, 0x2079, 0x0020, 0x2071, 0xa908, 0x2b68,
+	0x0e7e, 0x0d7e, 0x0c7e, 0x2079, 0x0020, 0x2071, 0xaa08, 0x2b68,
 	0x6818, 0x2060, 0x7904, 0x7803, 0x0002, 0xa184, 0x0700, 0x00c0,
 	0x1e7b, 0x7000, 0x0079, 0x1ec4, 0x1f76, 0x1ec8, 0x1f43, 0x1f74,
 	0x8001, 0x7002, 0xd19c, 0x00c0, 0x1edc, 0x8aff, 0x0040, 0x1efb,
@@ -546,26 +546,26 @@ unsigned short risc_code01[] = { 
 	0xa213, 0x0078, 0x1f6f, 0x6810, 0xa31a, 0x6814, 0xa213, 0x0d7f,
 	0x0078, 0x1eec, 0x0078, 0x1eec, 0x1078, 0x1332, 0x0c7f, 0x0d7f,
 	0x0e7f, 0x0f7f, 0x017f, 0x007f, 0x127f, 0x007c, 0x0f7e, 0x0e7e,
-	0x2071, 0xa908, 0x7000, 0xa086, 0x0000, 0x0040, 0x1fc7, 0x2079,
+	0x2071, 0xaa08, 0x7000, 0xa086, 0x0000, 0x0040, 0x1fc7, 0x2079,
 	0x0020, 0x017e, 0x2009, 0x0207, 0x210c, 0xd194, 0x0040, 0x1fa4,
 	0x2009, 0x020c, 0x210c, 0xa184, 0x0003, 0x0040, 0x1fa4, 0x1078,
-	0xa5d2, 0x2001, 0x0133, 0x2004, 0xa005, 0x1040, 0x1332, 0x20e1,
+	0xa5e2, 0x2001, 0x0133, 0x2004, 0xa005, 0x1040, 0x1332, 0x20e1,
 	0x9040, 0x2001, 0x020c, 0x2102, 0x2009, 0x0206, 0x2104, 0x2009,
 	0x0203, 0x210c, 0xa106, 0x00c0, 0x1faf, 0x20e1, 0x9040, 0x7804,
 	0xd0fc, 0x0040, 0x1f8a, 0x1078, 0x1eaa, 0x7000, 0xa086, 0x0000,
 	0x00c0, 0x1f8a, 0x017f, 0x7803, 0x0004, 0x7804, 0xd0ac, 0x00c0,
 	0x1fbd, 0x20e1, 0x9040, 0x7803, 0x0002, 0x7003, 0x0000, 0x0e7f,
 	0x0f7f, 0x007c, 0x027e, 0x0c7e, 0x0d7e, 0x0e7e, 0x0f7e, 0x2071,
-	0xa908, 0x2079, 0x0020, 0x7000, 0xa086, 0x0000, 0x0040, 0x2003,
-	0x7004, 0x2060, 0x6010, 0x2068, 0x1078, 0x8d06, 0x0040, 0x1fed,
+	0xaa08, 0x2079, 0x0020, 0x7000, 0xa086, 0x0000, 0x0040, 0x2003,
+	0x7004, 0x2060, 0x6010, 0x2068, 0x1078, 0x8d16, 0x0040, 0x1fed,
 	0x6850, 0xc0b5, 0x6852, 0x680c, 0x7a1c, 0xa206, 0x00c0, 0x1fed,
 	0x6808, 0x7a18, 0xa206, 0x0040, 0x2009, 0x2001, 0x0105, 0x2003,
 	0x0010, 0x20e1, 0x9040, 0x7803, 0x0004, 0x7003, 0x0000, 0x7004,
-	0x2060, 0x1078, 0x8a01, 0x20e1, 0x9040, 0x1078, 0x738a, 0x2011,
+	0x2060, 0x1078, 0x8a11, 0x20e1, 0x9040, 0x1078, 0x738a, 0x2011,
 	0x0000, 0x1078, 0x70ea, 0x0f7f, 0x0e7f, 0x0d7f, 0x0c7f, 0x027f,
 	0x007c, 0x6810, 0x6a14, 0xa205, 0x00c0, 0x1fed, 0x684c, 0xc0dc,
 	0x684e, 0x2c10, 0x1078, 0x1cf0, 0x2001, 0x0105, 0x2003, 0x0010,
-	0x20e1, 0x9040, 0x7803, 0x0004, 0x7003, 0x0000, 0x2069, 0xa8b1,
+	0x20e1, 0x9040, 0x7803, 0x0004, 0x7003, 0x0000, 0x2069, 0xa9b1,
 	0x6833, 0x0000, 0x683f, 0x0000, 0x0078, 0x2003, 0x8840, 0x2804,
 	0xa005, 0x00c0, 0x203a, 0x6004, 0xa005, 0x0040, 0x203c, 0x681a,
 	0x2060, 0x6034, 0xa084, 0x000f, 0xa080, 0x206a, 0x2044, 0x88ff,
@@ -583,7 +583,7 @@ unsigned short risc_code01[] = { 
 	0xa055, 0x0040, 0x212d, 0x2d60, 0x6034, 0xa0cc, 0x000f, 0xa9c0,
 	0x206a, 0xa986, 0x0007, 0x0040, 0x20a5, 0xa986, 0x000e, 0x0040,
 	0x20a5, 0xa986, 0x000f, 0x00c0, 0x20a9, 0x605c, 0xa422, 0x6060,
-	0xa31a, 0x2804, 0xa045, 0x00c0, 0x20b7, 0x0050, 0x20b1, 0x0078,
+	0xa31b, 0x2804, 0xa045, 0x00c0, 0x20b7, 0x0050, 0x20b1, 0x0078,
 	0x212d, 0x6004, 0xa065, 0x0040, 0x212d, 0x0078, 0x2094, 0x2804,
 	0xa005, 0x0040, 0x20d5, 0xac68, 0xd99c, 0x00c0, 0x20c5, 0x6808,
 	0xa422, 0x680c, 0xa31b, 0x0078, 0x20c9, 0x6810, 0xa422, 0x6814,
@@ -607,7 +607,7 @@ unsigned short risc_code01[] = { 
 	0x007c, 0x1078, 0x1eaa, 0x1078, 0x14be, 0x007c, 0x1078, 0x1913,
 	0x1078, 0x14be, 0x007c, 0x1078, 0x1913, 0x1078, 0x1eaa, 0x1078,
 	0x14be, 0x007c, 0x127e, 0x2091, 0x2300, 0x2079, 0x0200, 0x2071,
-	0xab80, 0x2069, 0xa600, 0x2009, 0x0004, 0x7912, 0x7817, 0x0004,
+	0xac80, 0x2069, 0xa700, 0x2009, 0x0004, 0x7912, 0x7817, 0x0004,
 	0x1078, 0x251f, 0x781b, 0x0002, 0x20e1, 0x8700, 0x127f, 0x007c,
 	0x127e, 0x2091, 0x2300, 0x781c, 0xa084, 0x0007, 0x0079, 0x2180,
 	0x21a4, 0x2188, 0x218c, 0x2190, 0x2196, 0x219a, 0x219e, 0x21a2,
@@ -615,18 +615,18 @@ unsigned short risc_code01[] = { 
 	0x1078, 0x548e, 0x1078, 0x54da, 0x0078, 0x21a4, 0x1078, 0x21a6,
 	0x0078, 0x21a4, 0x1078, 0x21a6, 0x0078, 0x21a4, 0x1078, 0x21a6,
 	0x0078, 0x21a4, 0x1078, 0x21a6, 0x127f, 0x007c, 0x007e, 0x017e,
-	0x027e, 0x1078, 0xa5d2, 0x7930, 0xa184, 0x0003, 0x0040, 0x21c9,
-	0x2001, 0xa8c0, 0x2004, 0xa005, 0x0040, 0x21c5, 0x2001, 0x0133,
-	0x2004, 0xa005, 0x1040, 0x1332, 0x0c7e, 0x2001, 0xa8c0, 0x2064,
-	0x1078, 0x8a01, 0x0c7f, 0x0078, 0x21f2, 0x20e1, 0x9040, 0x0078,
+	0x027e, 0x1078, 0xa5e2, 0x7930, 0xa184, 0x0003, 0x0040, 0x21c9,
+	0x2001, 0xa9c0, 0x2004, 0xa005, 0x0040, 0x21c5, 0x2001, 0x0133,
+	0x2004, 0xa005, 0x1040, 0x1332, 0x0c7e, 0x2001, 0xa9c0, 0x2064,
+	0x1078, 0x8a11, 0x0c7f, 0x0078, 0x21f2, 0x20e1, 0x9040, 0x0078,
 	0x21f2, 0xa184, 0x0030, 0x0040, 0x21da, 0x6a00, 0xa286, 0x0003,
 	0x00c0, 0x21d4, 0x0078, 0x21d6, 0x1078, 0x4224, 0x20e1, 0x9010,
 	0x0078, 0x21f2, 0xa184, 0x00c0, 0x0040, 0x21ec, 0x0e7e, 0x037e,
-	0x047e, 0x057e, 0x2071, 0xa8e7, 0x1078, 0x1af4, 0x057f, 0x047f,
+	0x047e, 0x057e, 0x2071, 0xa9e7, 0x1078, 0x1af4, 0x057f, 0x047f,
 	0x037f, 0x0e7f, 0x0078, 0x21f2, 0xa184, 0x0300, 0x0040, 0x21f2,
 	0x20e1, 0x9020, 0x7932, 0x027f, 0x017f, 0x007f, 0x007c, 0x017e,
-	0x0e7e, 0x0f7e, 0x2071, 0xa600, 0x7128, 0x2001, 0xa890, 0x2102,
-	0x2001, 0xa898, 0x2102, 0xa182, 0x0211, 0x00c8, 0x220b, 0x2009,
+	0x0e7e, 0x0f7e, 0x2071, 0xa700, 0x7128, 0x2001, 0xa990, 0x2102,
+	0x2001, 0xa998, 0x2102, 0xa182, 0x0211, 0x00c8, 0x220b, 0x2009,
 	0x0008, 0x0078, 0x2235, 0xa182, 0x0259, 0x00c8, 0x2213, 0x2009,
 	0x0007, 0x0078, 0x2235, 0xa182, 0x02c1, 0x00c8, 0x221b, 0x2009,
 	0x0006, 0x0078, 0x2235, 0xa182, 0x0349, 0x00c8, 0x2223, 0x2009,
@@ -634,12 +634,12 @@ unsigned short risc_code01[] = { 
 	0x0004, 0x0078, 0x2235, 0xa182, 0x0581, 0x00c8, 0x2233, 0x2009,
 	0x0003, 0x0078, 0x2235, 0x2009, 0x0002, 0x2079, 0x0200, 0x7912,
 	0x7817, 0x0004, 0x1078, 0x251f, 0x0f7f, 0x0e7f, 0x017f, 0x007c,
-	0x127e, 0x2091, 0x2200, 0x2061, 0x0100, 0x2071, 0xa600, 0x6024,
+	0x127e, 0x2091, 0x2200, 0x2061, 0x0100, 0x2071, 0xa700, 0x6024,
 	0x6026, 0x6053, 0x0030, 0x6033, 0x00ef, 0x60e7, 0x0000, 0x60eb,
 	0x00ef, 0x60e3, 0x0008, 0x604b, 0xf7f7, 0x6043, 0x0000, 0x602f,
 	0x0080, 0x602f, 0x0000, 0x6007, 0x0eaf, 0x600f, 0x00ff, 0x602b,
-	0x002f, 0x127f, 0x007c, 0x2001, 0xa630, 0x2003, 0x0000, 0x2001,
-	0xa62f, 0x2003, 0x0001, 0x007c, 0x127e, 0x2091, 0x2200, 0x007e,
+	0x002f, 0x127f, 0x007c, 0x2001, 0xa730, 0x2003, 0x0000, 0x2001,
+	0xa72f, 0x2003, 0x0001, 0x007c, 0x127e, 0x2091, 0x2200, 0x007e,
 	0x017e, 0x027e, 0x6124, 0xa184, 0x002c, 0x00c0, 0x227b, 0xa184,
 	0x0007, 0x0079, 0x2281, 0xa195, 0x0004, 0xa284, 0x0007, 0x0079,
 	0x2281, 0x22ad, 0x2289, 0x228d, 0x2291, 0x2297, 0x229b, 0x22a1,
@@ -655,38 +655,38 @@ unsigned short risc_code01[] = { 
 	0x703c, 0xd084, 0x00c0, 0x22dd, 0xc085, 0x703e, 0x037e, 0x2418,
 	0x2011, 0x8016, 0x1078, 0x361b, 0x037f, 0xa196, 0xff00, 0x0040,
 	0x231f, 0x6030, 0xa084, 0x00ff, 0x810f, 0xa116, 0x0040, 0x231f,
-	0x7130, 0xd184, 0x00c0, 0x231f, 0x2011, 0xa653, 0x2214, 0xd2ec,
-	0x0040, 0x22fa, 0xc18d, 0x7132, 0x2011, 0xa653, 0x2214, 0xd2ac,
+	0x7130, 0xd184, 0x00c0, 0x231f, 0x2011, 0xa753, 0x2214, 0xd2ec,
+	0x0040, 0x22fa, 0xc18d, 0x7132, 0x2011, 0xa753, 0x2214, 0xd2ac,
 	0x00c0, 0x231f, 0x6240, 0xa294, 0x0010, 0x0040, 0x2306, 0x6248,
 	0xa294, 0xff00, 0xa296, 0xff00, 0x0040, 0x231f, 0x7030, 0xd08c,
-	0x0040, 0x2371, 0x7034, 0xd08c, 0x00c0, 0x2316, 0x2001, 0xa60c,
+	0x0040, 0x2371, 0x7034, 0xd08c, 0x00c0, 0x2316, 0x2001, 0xa70c,
 	0x200c, 0xd1ac, 0x00c0, 0x2371, 0xc1ad, 0x2102, 0x037e, 0x73c4,
 	0x2011, 0x8013, 0x1078, 0x361b, 0x037f, 0x0078, 0x2371, 0x7034,
-	0xd08c, 0x00c0, 0x232b, 0x2001, 0xa60c, 0x200c, 0xd1ac, 0x00c0,
+	0xd08c, 0x00c0, 0x232b, 0x2001, 0xa70c, 0x200c, 0xd1ac, 0x00c0,
 	0x2371, 0xc1ad, 0x2102, 0x037e, 0x73c4, 0x2011, 0x8013, 0x1078,
-	0x361b, 0x037f, 0x7130, 0xc185, 0x7132, 0x2011, 0xa653, 0x220c,
+	0x361b, 0x037f, 0x7130, 0xc185, 0x7132, 0x2011, 0xa753, 0x220c,
 	0xd1a4, 0x0040, 0x2355, 0x017e, 0x2009, 0x0001, 0x2011, 0x0100,
-	0x1078, 0x5bf1, 0x2019, 0x000e, 0x1078, 0xa195, 0xa484, 0x00ff,
+	0x1078, 0x5bf1, 0x2019, 0x000e, 0x1078, 0xa1a5, 0xa484, 0x00ff,
 	0xa080, 0x29c0, 0x200c, 0xa18c, 0xff00, 0x810f, 0x8127, 0xa006,
-	0x2009, 0x000e, 0x1078, 0xa21d, 0x017f, 0xd1ac, 0x00c0, 0x2362,
+	0x2009, 0x000e, 0x1078, 0xa22d, 0x017f, 0xd1ac, 0x00c0, 0x2362,
 	0x017e, 0x2009, 0x0000, 0x2019, 0x0004, 0x1078, 0x284f, 0x017f,
 	0x0078, 0x2371, 0x157e, 0x20a9, 0x007f, 0x2009, 0x0000, 0x1078,
 	0x45c4, 0x00c0, 0x236d, 0x1078, 0x42f8, 0x8108, 0x00f0, 0x2367,
-	0x157f, 0x0c7f, 0x047f, 0x0f7e, 0x2079, 0xa8c4, 0x783c, 0xa086,
+	0x157f, 0x0c7f, 0x047f, 0x0f7e, 0x2079, 0xa9c4, 0x783c, 0xa086,
 	0x0000, 0x0040, 0x2383, 0x6027, 0x0004, 0x783f, 0x0000, 0x2079,
 	0x0140, 0x7803, 0x0000, 0x0f7f, 0x2011, 0x0003, 0x1078, 0x70e0,
 	0x2011, 0x0002, 0x1078, 0x70ea, 0x1078, 0x6fc4, 0x037e, 0x2019,
 	0x0000, 0x1078, 0x7058, 0x037f, 0x60e3, 0x0000, 0x017f, 0x2001,
-	0xa600, 0x2014, 0xa296, 0x0004, 0x00c0, 0x23a4, 0xd19c, 0x00c0,
-	0x23ac, 0x6228, 0xc29d, 0x622a, 0x2003, 0x0001, 0x2001, 0xa622,
+	0xa700, 0x2014, 0xa296, 0x0004, 0x00c0, 0x23a4, 0xd19c, 0x00c0,
+	0x23ac, 0x6228, 0xc29d, 0x622a, 0x2003, 0x0001, 0x2001, 0xa722,
 	0x2003, 0x0000, 0x6027, 0x0020, 0xd194, 0x0040, 0x2490, 0x0f7e,
-	0x2079, 0xa8c4, 0x783c, 0xa086, 0x0001, 0x00c0, 0x23d0, 0x017e,
+	0x2079, 0xa9c4, 0x783c, 0xa086, 0x0001, 0x00c0, 0x23d0, 0x017e,
 	0x6027, 0x0004, 0x783f, 0x0000, 0x2079, 0x0140, 0x7803, 0x1000,
-	0x7803, 0x0000, 0x2079, 0xa8b1, 0x7807, 0x0000, 0x7833, 0x0000,
+	0x7803, 0x0000, 0x2079, 0xa9b1, 0x7807, 0x0000, 0x7833, 0x0000,
 	0x1078, 0x62d1, 0x1078, 0x639b, 0x017f, 0x0f7f, 0x0078, 0x2490,
-	0x0f7f, 0x017e, 0x3900, 0xa082, 0xa9e3, 0x00c8, 0x23db, 0x017e,
+	0x0f7f, 0x017e, 0x3900, 0xa082, 0xaae3, 0x00c8, 0x23db, 0x017e,
 	0x1078, 0x747a, 0x017f, 0x6220, 0xd2b4, 0x0040, 0x2446, 0x1078,
-	0x5acb, 0x1078, 0x6e0f, 0x6027, 0x0004, 0x0f7e, 0x2019, 0xa8ba,
+	0x5acb, 0x1078, 0x6e0f, 0x6027, 0x0004, 0x0f7e, 0x2019, 0xa9ba,
 	0x2304, 0xa07d, 0x0040, 0x241c, 0x7804, 0xa086, 0x0032, 0x00c0,
 	0x241c, 0x0d7e, 0x0c7e, 0x0e7e, 0x2069, 0x0140, 0x618c, 0x6288,
 	0x7818, 0x608e, 0x7808, 0x608a, 0x6043, 0x0002, 0x2001, 0x0003,
@@ -695,18 +695,18 @@ unsigned short risc_code01[] = { 
 	0x2070, 0x7037, 0x0103, 0x2f60, 0x1078, 0x772d, 0x0e7f, 0x0c7f,
 	0x0d7f, 0x0f7f, 0x017f, 0x007c, 0x0f7f, 0x0d7e, 0x2069, 0x0140,
 	0x6804, 0xa084, 0x4000, 0x0040, 0x2429, 0x6803, 0x1000, 0x6803,
-	0x0000, 0x0d7f, 0x0c7e, 0x2061, 0xa8b1, 0x6028, 0xa09a, 0x00c8,
+	0x0000, 0x0d7f, 0x0c7e, 0x2061, 0xa9b1, 0x6028, 0xa09a, 0x00c8,
 	0x00c8, 0x2439, 0x8000, 0x602a, 0x0c7f, 0x1078, 0x6e01, 0x0078,
-	0x248f, 0x2019, 0xa8ba, 0x2304, 0xa065, 0x0040, 0x2443, 0x2009,
+	0x248f, 0x2019, 0xa9ba, 0x2304, 0xa065, 0x0040, 0x2443, 0x2009,
 	0x0027, 0x1078, 0x775c, 0x0c7f, 0x0078, 0x248f, 0xd2bc, 0x0040,
 	0x248f, 0x1078, 0x5ad8, 0x6017, 0x0010, 0x6027, 0x0004, 0x0d7e,
 	0x2069, 0x0140, 0x6804, 0xa084, 0x4000, 0x0040, 0x245b, 0x6803,
-	0x1000, 0x6803, 0x0000, 0x0d7f, 0x0c7e, 0x2061, 0xa8b1, 0x6044,
+	0x1000, 0x6803, 0x0000, 0x0d7f, 0x0c7e, 0x2061, 0xa9b1, 0x6044,
 	0xa09a, 0x00c8, 0x00c8, 0x247e, 0x8000, 0x6046, 0x603c, 0x0c7f,
 	0xa005, 0x0040, 0x248f, 0x2009, 0x07d0, 0x1078, 0x5ad0, 0xa080,
 	0x0007, 0x2004, 0xa086, 0x0006, 0x00c0, 0x247a, 0x6017, 0x0012,
 	0x0078, 0x248f, 0x6017, 0x0016, 0x0078, 0x248f, 0x037e, 0x2019,
-	0x0001, 0x1078, 0x7058, 0x037f, 0x2019, 0xa8c0, 0x2304, 0xa065,
+	0x0001, 0x1078, 0x7058, 0x037f, 0x2019, 0xa9c0, 0x2304, 0xa065,
 	0x0040, 0x248e, 0x2009, 0x004f, 0x1078, 0x775c, 0x0c7f, 0x017f,
 	0xd19c, 0x0040, 0x24e4, 0x7034, 0xd0ac, 0x00c0, 0x24c1, 0x017e,
 	0x157e, 0x6027, 0x0008, 0x602f, 0x0020, 0x20a9, 0x000a, 0x00f0,
@@ -717,12 +717,12 @@ unsigned short risc_code01[] = { 
 	0x0008, 0x017e, 0x6028, 0xc09c, 0x602a, 0x2011, 0x0003, 0x1078,
 	0x70e0, 0x2011, 0x0002, 0x1078, 0x70ea, 0x1078, 0x6fc4, 0x037e,
 	0x2019, 0x0000, 0x1078, 0x7058, 0x037f, 0x60e3, 0x0000, 0x1078,
-	0xa5ad, 0x1078, 0xa5cb, 0x2001, 0xa600, 0x2003, 0x0004, 0x6027,
+	0xa5bd, 0x1078, 0xa5db, 0x2001, 0xa700, 0x2003, 0x0004, 0x6027,
 	0x0008, 0x1078, 0x1246, 0x017f, 0xa18c, 0xffd0, 0x6126, 0x007c,
 	0x007e, 0x017e, 0x027e, 0x0e7e, 0x0f7e, 0x127e, 0x2091, 0x8000,
-	0x2071, 0xa600, 0x71bc, 0x70be, 0xa116, 0x0040, 0x2518, 0x81ff,
+	0x2071, 0xa700, 0x71bc, 0x70be, 0xa116, 0x0040, 0x2518, 0x81ff,
 	0x0040, 0x2500, 0x2011, 0x8011, 0x1078, 0x361b, 0x0078, 0x2518,
-	0x2011, 0x8012, 0x1078, 0x361b, 0x2001, 0xa672, 0x2004, 0xd0fc,
+	0x2011, 0x8012, 0x1078, 0x361b, 0x2001, 0xa772, 0x2004, 0xd0fc,
 	0x00c0, 0x2518, 0x037e, 0x0c7e, 0x1078, 0x6f9f, 0x2061, 0x0100,
 	0x2019, 0x0028, 0x2009, 0x0000, 0x1078, 0x284f, 0x0c7f, 0x037f,
 	0x127f, 0x0f7f, 0x0e7f, 0x027f, 0x017f, 0x007f, 0x007c, 0x0c7e,
@@ -735,7 +735,7 @@ unsigned short risc_code01[] = { 
 	0x2130, 0xa094, 0xff00, 0x00c0, 0x2558, 0x81ff, 0x0040, 0x255c,
 	0x1078, 0x5761, 0x0078, 0x2563, 0xa080, 0x29c0, 0x200c, 0xa18c,
 	0xff00, 0x810f, 0xa006, 0x007c, 0xa080, 0x29c0, 0x200c, 0xa18c,
-	0x00ff, 0x007c, 0x0c7e, 0x2061, 0xa600, 0x6030, 0x0040, 0x2573,
+	0x00ff, 0x007c, 0x0c7e, 0x2061, 0xa700, 0x6030, 0x0040, 0x2573,
 	0xc09d, 0x0078, 0x2574, 0xc09c, 0x6032, 0x0c7f, 0x007c, 0x007e,
 	0x157e, 0x0f7e, 0x2079, 0x0100, 0x20a9, 0x000a, 0x7854, 0xd08c,
 	0x00c0, 0x2584, 0x00f0, 0x257e, 0x0f7f, 0x157f, 0x007f, 0x007c,
@@ -775,7 +775,7 @@ unsigned short risc_code01[] = { 
 	0x2772, 0xd094, 0x0040, 0x2698, 0x7097, 0xffff, 0x0078, 0x2772,
 	0x2001, 0x010c, 0x203c, 0x7284, 0xd284, 0x0040, 0x2701, 0xd28c,
 	0x00c0, 0x2701, 0x037e, 0x7394, 0xa38e, 0xffff, 0x0040, 0x26ab,
-	0x83ff, 0x00c0, 0x26ad, 0x2019, 0x0001, 0x8314, 0xa2e0, 0xacc0,
+	0x83ff, 0x00c0, 0x26ad, 0x2019, 0x0001, 0x8314, 0xa2e0, 0xadc0,
 	0x2c04, 0xa38c, 0x0001, 0x0040, 0x26ba, 0xa084, 0xff00, 0x8007,
 	0x0078, 0x26bc, 0xa084, 0x00ff, 0xa70e, 0x0040, 0x26f6, 0xa08e,
 	0x0000, 0x0040, 0x26f6, 0xa08e, 0x00ff, 0x00c0, 0x26d3, 0x7230,
@@ -804,13 +804,13 @@ unsigned short risc_code01[] = { 
 	0x7097, 0x0001, 0x2009, 0x007e, 0x1078, 0x455c, 0x00c0, 0x2789,
 	0x1078, 0x28c4, 0x1078, 0x27b9, 0x0040, 0x2789, 0x70cc, 0xc0bd,
 	0x70ce, 0x017f, 0x0c7f, 0x007c, 0x017e, 0x077e, 0x0d7e, 0x0c7e,
-	0x2c68, 0x2001, 0xa657, 0x2004, 0xa084, 0x00ff, 0x6842, 0x1078,
+	0x2c68, 0x2001, 0xa757, 0x2004, 0xa084, 0x00ff, 0x6842, 0x1078,
 	0x76c7, 0x0040, 0x27b4, 0x2d00, 0x601a, 0x601f, 0x0001, 0x2001,
 	0x0000, 0x1078, 0x44ee, 0x2001, 0x0000, 0x1078, 0x4502, 0x127e,
 	0x2091, 0x8000, 0x7090, 0x8000, 0x7092, 0x127f, 0x2009, 0x0004,
 	0x1078, 0x775c, 0xa085, 0x0001, 0x0c7f, 0x0d7f, 0x077f, 0x017f,
-	0x007c, 0x017e, 0x077e, 0x0d7e, 0x0c7e, 0x2c68, 0x2001, 0xa657,
-	0x2004, 0xa084, 0x00ff, 0x6842, 0x1078, 0x9187, 0x0040, 0x27f2,
+	0x007c, 0x017e, 0x077e, 0x0d7e, 0x0c7e, 0x2c68, 0x2001, 0xa757,
+	0x2004, 0xa084, 0x00ff, 0x6842, 0x1078, 0x9197, 0x0040, 0x27f2,
 	0x2d00, 0x601a, 0x6800, 0xc0c4, 0x6802, 0x68a0, 0xa086, 0x007e,
 	0x0040, 0x27db, 0x6804, 0xa084, 0x00ff, 0xa086, 0x0006, 0x00c0,
 	0x27db, 0x1078, 0x2880, 0x601f, 0x0001, 0x2001, 0x0000, 0x1078,
@@ -836,44 +836,44 @@ unsigned short risc_code01[] = { 
 	0x1078, 0x119b, 0x027f, 0x037f, 0x067f, 0x0c7f, 0x0e7f, 0x007c,
 	0x0e7e, 0x0c7e, 0x037e, 0x027e, 0x017e, 0x6218, 0x2270, 0x72a0,
 	0x027e, 0x2019, 0x0029, 0x1078, 0x5f01, 0x077e, 0x2039, 0x0000,
-	0x1078, 0x5e0a, 0x2c08, 0x1078, 0x9f8b, 0x077f, 0x017f, 0x2e60,
+	0x1078, 0x5e0a, 0x2c08, 0x1078, 0x9f9b, 0x077f, 0x017f, 0x2e60,
 	0x1078, 0x47e9, 0x6210, 0x6314, 0x1078, 0x42f8, 0x6212, 0x6316,
 	0x017f, 0x027f, 0x037f, 0x0c7f, 0x0e7f, 0x007c, 0x0e7e, 0x007e,
 	0x6018, 0xa080, 0x0028, 0x2004, 0xd0bc, 0x00c0, 0x28ba, 0x2071,
-	0xa600, 0x7090, 0xa005, 0x0040, 0x28b7, 0x8001, 0x7092, 0x007f,
-	0x0e7f, 0x007c, 0x2071, 0xa600, 0x70d4, 0xa005, 0x0040, 0x28b7,
+	0xa700, 0x7090, 0xa005, 0x0040, 0x28b7, 0x8001, 0x7092, 0x007f,
+	0x0e7f, 0x007c, 0x2071, 0xa700, 0x70d4, 0xa005, 0x0040, 0x28b7,
 	0x8001, 0x70d6, 0x0078, 0x28b7, 0x6000, 0xc08c, 0x6002, 0x007c,
 	0x0f7e, 0x0e7e, 0x0c7e, 0x037e, 0x027e, 0x017e, 0x157e, 0x2178,
 	0x81ff, 0x00c0, 0x28d7, 0x20a9, 0x0001, 0x0078, 0x28f2, 0x2001,
-	0xa653, 0x2004, 0xd0c4, 0x0040, 0x28ee, 0xd0a4, 0x0040, 0x28ee,
+	0xa753, 0x2004, 0xd0c4, 0x0040, 0x28ee, 0xd0a4, 0x0040, 0x28ee,
 	0x047e, 0x6018, 0xa080, 0x0028, 0x2024, 0xa4a4, 0x00ff, 0x8427,
-	0xa006, 0x2009, 0x002d, 0x1078, 0xa21d, 0x047f, 0x20a9, 0x00ff,
+	0xa006, 0x2009, 0x002d, 0x1078, 0xa22d, 0x047f, 0x20a9, 0x00ff,
 	0x2011, 0x0000, 0x027e, 0xa28e, 0x007e, 0x0040, 0x2936, 0xa28e,
 	0x007f, 0x0040, 0x2936, 0xa28e, 0x0080, 0x0040, 0x2936, 0xa288,
-	0xa735, 0x210c, 0x81ff, 0x0040, 0x2936, 0x8fff, 0x1040, 0x2942,
+	0xa835, 0x210c, 0x81ff, 0x0040, 0x2936, 0x8fff, 0x1040, 0x2942,
 	0x0c7e, 0x2160, 0x2001, 0x0001, 0x1078, 0x4972, 0x0c7f, 0x2019,
 	0x0029, 0x1078, 0x5f01, 0x077e, 0x2039, 0x0000, 0x1078, 0x5e0a,
 	0x0c7e, 0x027e, 0x2160, 0x6204, 0xa294, 0x00ff, 0xa286, 0x0006,
 	0x00c0, 0x2926, 0x6007, 0x0404, 0x0078, 0x292b, 0x2001, 0x0004,
 	0x8007, 0xa215, 0x6206, 0x027f, 0x0c7f, 0x017e, 0x2c08, 0x1078,
-	0x9f8b, 0x017f, 0x077f, 0x2160, 0x1078, 0x47e9, 0x027f, 0x8210,
+	0x9f9b, 0x017f, 0x077f, 0x2160, 0x1078, 0x47e9, 0x027f, 0x8210,
 	0x00f0, 0x28f2, 0x157f, 0x017f, 0x027f, 0x037f, 0x0c7f, 0x0e7f,
-	0x0f7f, 0x007c, 0x047e, 0x027e, 0x017e, 0x2001, 0xa653, 0x2004,
+	0x0f7f, 0x007c, 0x047e, 0x027e, 0x017e, 0x2001, 0xa753, 0x2004,
 	0xd0c4, 0x0040, 0x2955, 0xd0a4, 0x0040, 0x2955, 0xa006, 0x2220,
-	0x8427, 0x2009, 0x0029, 0x1078, 0xa21d, 0x017f, 0x027f, 0x047f,
+	0x8427, 0x2009, 0x0029, 0x1078, 0xa22d, 0x017f, 0x027f, 0x047f,
 	0x007c, 0x017e, 0x027e, 0x037e, 0x0c7e, 0x7284, 0x82ff, 0x0040,
-	0x2987, 0xa290, 0xa653, 0x2214, 0xd2ac, 0x00c0, 0x2987, 0x2100,
+	0x2987, 0xa290, 0xa753, 0x2214, 0xd2ac, 0x00c0, 0x2987, 0x2100,
 	0x1078, 0x2564, 0x81ff, 0x0040, 0x2989, 0x2019, 0x0001, 0x8314,
-	0xa2e0, 0xacc0, 0x2c04, 0xd384, 0x0040, 0x297b, 0xa084, 0xff00,
+	0xa2e0, 0xadc0, 0x2c04, 0xd384, 0x0040, 0x297b, 0xa084, 0xff00,
 	0x8007, 0x0078, 0x297d, 0xa084, 0x00ff, 0xa116, 0x0040, 0x2989,
 	0xa096, 0x00ff, 0x0040, 0x2987, 0x8318, 0x0078, 0x296f, 0xa085,
 	0x0001, 0x0c7f, 0x037f, 0x027f, 0x017f, 0x007c, 0x017e, 0x0c7e,
 	0x127e, 0x2091, 0x8000, 0x017e, 0x027e, 0x037e, 0x2110, 0x027e,
-	0x2019, 0x0029, 0x1078, 0x73d0, 0x027f, 0x1078, 0xa4f1, 0x037f,
-	0x027f, 0x017f, 0xa180, 0xa735, 0x2004, 0xa065, 0x0040, 0x29b7,
-	0x017e, 0x0c7e, 0x1078, 0x9187, 0x017f, 0x1040, 0x1332, 0x611a,
+	0x2019, 0x0029, 0x1078, 0x73d0, 0x027f, 0x1078, 0xa501, 0x037f,
+	0x027f, 0x017f, 0xa180, 0xa835, 0x2004, 0xa065, 0x0040, 0x29b7,
+	0x017e, 0x0c7e, 0x1078, 0x9197, 0x017f, 0x1040, 0x1332, 0x611a,
 	0x1078, 0x2880, 0x1078, 0x772d, 0x017f, 0x1078, 0x457f, 0x127f,
-	0x0c7f, 0x017f, 0x007c, 0x2001, 0xa633, 0x2004, 0xd0cc, 0x007c,
+	0x0c7f, 0x017f, 0x007c, 0x2001, 0xa733, 0x2004, 0xd0cc, 0x007c,
 	0x7eef, 0x7de8, 0x7ce4, 0x80e2, 0x7be1, 0x80e0, 0x80dc, 0x80da,
 	0x7ad9, 0x80d6, 0x80d5, 0x80d4, 0x80d3, 0x80d2, 0x80d1, 0x79ce,
 	0x78cd, 0x80cc, 0x80cb, 0x80ca, 0x80c9, 0x80c7, 0x80c6, 0x77c5,
@@ -906,14 +906,14 @@ unsigned short risc_code01[] = { 
 	0x0100, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x0000,
 	0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
 	0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
-	0x2071, 0xa682, 0x7003, 0x0002, 0xa006, 0x7012, 0x7016, 0x703a,
-	0x703e, 0x7033, 0xa692, 0x7037, 0xa692, 0x7007, 0x0001, 0x2061,
-	0xa6d2, 0x6003, 0x0002, 0x007c, 0x0090, 0x2ae7, 0x0068, 0x2ae7,
-	0x2071, 0xa682, 0x2b78, 0x7818, 0xd084, 0x00c0, 0x2ae7, 0x2a60,
+	0x2071, 0xa782, 0x7003, 0x0002, 0xa006, 0x7012, 0x7016, 0x703a,
+	0x703e, 0x7033, 0xa792, 0x7037, 0xa792, 0x7007, 0x0001, 0x2061,
+	0xa7d2, 0x6003, 0x0002, 0x007c, 0x0090, 0x2ae7, 0x0068, 0x2ae7,
+	0x2071, 0xa782, 0x2b78, 0x7818, 0xd084, 0x00c0, 0x2ae7, 0x2a60,
 	0x7820, 0xa08e, 0x0069, 0x00c0, 0x2bd7, 0x0079, 0x2b6b, 0x007c,
-	0x2071, 0xa682, 0x7004, 0x0079, 0x2aed, 0x2af1, 0x2af2, 0x2afc,
+	0x2071, 0xa782, 0x7004, 0x0079, 0x2aed, 0x2af1, 0x2af2, 0x2afc,
 	0x2b0e, 0x007c, 0x0090, 0x2afb, 0x0068, 0x2afb, 0x2b78, 0x7818,
-	0xd084, 0x0040, 0x2b1a, 0x007c, 0x2b78, 0x2061, 0xa6d2, 0x6008,
+	0xd084, 0x0040, 0x2b1a, 0x007c, 0x2b78, 0x2061, 0xa7d2, 0x6008,
 	0xa08e, 0x0100, 0x0040, 0x2b09, 0xa086, 0x0200, 0x0040, 0x2bcf,
 	0x007c, 0x7014, 0x2068, 0x2a60, 0x7018, 0x007a, 0x7010, 0x2068,
 	0x6834, 0xa086, 0x0103, 0x0040, 0x2b16, 0x007c, 0x2a60, 0x2b78,
@@ -948,30 +948,30 @@ unsigned short risc_code01[] = { 
 	0x2bad, 0x7924, 0x2114, 0x0078, 0x2bad, 0x2099, 0x0009, 0x20a1,
 	0x0009, 0x20a9, 0x0007, 0x53a3, 0x7924, 0x7a28, 0x7b2c, 0x0078,
 	0x2bad, 0x7824, 0x2060, 0x0078, 0x2c21, 0x2009, 0x0001, 0x2011,
-	0x0013, 0x2019, 0x0018, 0x783b, 0x0017, 0x0078, 0x2bad, 0x7d38,
+	0x0013, 0x2019, 0x0019, 0x783b, 0x0017, 0x0078, 0x2bad, 0x7d38,
 	0x7c3c, 0x0078, 0x2be1, 0x7d38, 0x7c3c, 0x0078, 0x2bed, 0x2061,
 	0x1000, 0x610c, 0xa006, 0x2c14, 0xa200, 0x8c60, 0x8109, 0x00c0,
 	0x2c23, 0x2010, 0xa005, 0x0040, 0x2bad, 0x0078, 0x2bd3, 0x2069,
-	0xa652, 0x7824, 0x7930, 0xa11a, 0x00c8, 0x2bdb, 0x8019, 0x0040,
+	0xa752, 0x7824, 0x7930, 0xa11a, 0x00c8, 0x2bdb, 0x8019, 0x0040,
 	0x2bdb, 0x684a, 0x6942, 0x782c, 0x6852, 0x7828, 0x6856, 0xa006,
-	0x685a, 0x685e, 0x1078, 0x4eae, 0x0078, 0x2bad, 0x2069, 0xa652,
+	0x685a, 0x685e, 0x1078, 0x4eae, 0x0078, 0x2bad, 0x2069, 0xa752,
 	0x7824, 0x7934, 0xa11a, 0x00c8, 0x2bdb, 0x8019, 0x0040, 0x2bdb,
 	0x684e, 0x6946, 0x782c, 0x6862, 0x7828, 0x6866, 0xa006, 0x686a,
 	0x686e, 0x1078, 0x4a3e, 0x0078, 0x2bad, 0xa02e, 0x2520, 0x81ff,
 	0x00c0, 0x2bd7, 0x7924, 0x7b28, 0x7a2c, 0x20a9, 0x0005, 0x20a1,
-	0xa689, 0x41a1, 0x1078, 0x35ba, 0x0040, 0x2bd7, 0x2009, 0x0020,
+	0xa789, 0x41a1, 0x1078, 0x35ba, 0x0040, 0x2bd7, 0x2009, 0x0020,
 	0x1078, 0x3604, 0x701b, 0x2c75, 0x007c, 0x6834, 0x2008, 0xa084,
 	0x00ff, 0xa096, 0x0011, 0x0040, 0x2c85, 0xa096, 0x0019, 0x0040,
 	0x2c85, 0xa096, 0x0015, 0x00c0, 0x2bd7, 0x810f, 0xa18c, 0x00ff,
 	0x0040, 0x2bd7, 0x710e, 0x700c, 0x8001, 0x0040, 0x2cb6, 0x700e,
-	0x1078, 0x35ba, 0x0040, 0x2bd7, 0x2009, 0x0020, 0x2061, 0xa6d2,
+	0x1078, 0x35ba, 0x0040, 0x2bd7, 0x2009, 0x0020, 0x2061, 0xa7d2,
 	0x6224, 0x6328, 0x642c, 0x6530, 0xa290, 0x0040, 0xa399, 0x0000,
 	0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x1078, 0x3604, 0x701b, 0x2ca9,
 	0x007c, 0x6834, 0xa084, 0x00ff, 0xa096, 0x0002, 0x0040, 0x2cb4,
 	0xa096, 0x000a, 0x00c0, 0x2bd7, 0x0078, 0x2c8b, 0x7010, 0x2068,
 	0x6838, 0xc0fd, 0x683a, 0x1078, 0x4431, 0x00c0, 0x2cc4, 0x7007,
 	0x0003, 0x701b, 0x2cc6, 0x007c, 0x1078, 0x4b51, 0x127e, 0x2091,
-	0x8000, 0x20a9, 0x0005, 0x2099, 0xa689, 0x530a, 0x2100, 0xa210,
+	0x8000, 0x20a9, 0x0005, 0x2099, 0xa789, 0x530a, 0x2100, 0xa210,
 	0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0xad80, 0x000d,
 	0x2009, 0x0020, 0x127f, 0x0078, 0x3608, 0x61a4, 0x7824, 0x60a6,
 	0x0078, 0x2bad, 0x2091, 0x8000, 0x7823, 0x4000, 0x7827, 0x4953,
@@ -984,13 +984,13 @@ unsigned short risc_code01[] = { 
 	0x00c0, 0x2bdb, 0x7e38, 0xa684, 0x3fff, 0xa082, 0x4000, 0x0048,
 	0x2d23, 0x0078, 0x2bdb, 0x7c28, 0x7d2c, 0x1078, 0x47a4, 0xd28c,
 	0x00c0, 0x2d2e, 0x1078, 0x4736, 0x0078, 0x2d30, 0x1078, 0x4772,
-	0x00c0, 0x2d5a, 0x2061, 0xad00, 0x127e, 0x2091, 0x8000, 0x6000,
+	0x00c0, 0x2d5a, 0x2061, 0xae00, 0x127e, 0x2091, 0x8000, 0x6000,
 	0xa086, 0x0000, 0x0040, 0x2d48, 0x6010, 0xa06d, 0x0040, 0x2d48,
 	0x683c, 0xa406, 0x00c0, 0x2d48, 0x6840, 0xa506, 0x0040, 0x2d53,
-	0x127f, 0xace0, 0x0010, 0x2001, 0xa616, 0x2004, 0xac02, 0x00c8,
-	0x2bd7, 0x0078, 0x2d34, 0x1078, 0x8a01, 0x127f, 0x0040, 0x2bd7,
+	0x127f, 0xace0, 0x0010, 0x2001, 0xa716, 0x2004, 0xac02, 0x00c8,
+	0x2bd7, 0x0078, 0x2d34, 0x1078, 0x8a11, 0x127f, 0x0040, 0x2bd7,
 	0x0078, 0x2bad, 0xa00e, 0x2001, 0x0005, 0x1078, 0x4b51, 0x127e,
-	0x2091, 0x8000, 0x1078, 0x8f85, 0x1078, 0x4a73, 0x127f, 0x0078,
+	0x2091, 0x8000, 0x1078, 0x8f95, 0x1078, 0x4a73, 0x127f, 0x0078,
 	0x2bad, 0x81ff, 0x00c0, 0x2bd7, 0x1078, 0x35d2, 0x0040, 0x2bdb,
 	0x1078, 0x4673, 0x0040, 0x2bd7, 0x1078, 0x47b2, 0x0040, 0x2bd7,
 	0x0078, 0x2bad, 0x81ff, 0x00c0, 0x2bd7, 0x1078, 0x35e4, 0x0040,
@@ -1013,32 +1013,32 @@ unsigned short risc_code01[] = { 
 	0x47a4, 0x0078, 0x2bad, 0x1078, 0x35d2, 0x0040, 0x2bdb, 0x1078,
 	0x4673, 0x0040, 0x2bd7, 0x62a0, 0x2019, 0x0005, 0x0c7e, 0x1078,
 	0x47e9, 0x0c7f, 0x1078, 0x5f01, 0x077e, 0x2039, 0x0000, 0x1078,
-	0x5e0a, 0x2009, 0x0000, 0x1078, 0x9f8b, 0x077f, 0x1078, 0x47a4,
+	0x5e0a, 0x2009, 0x0000, 0x1078, 0x9f9b, 0x077f, 0x1078, 0x47a4,
 	0x0078, 0x2bad, 0x1078, 0x35d2, 0x0040, 0x2bdb, 0x1078, 0x47a4,
-	0x2208, 0x0078, 0x2bad, 0x157e, 0x0d7e, 0x0e7e, 0x2069, 0xa714,
+	0x2208, 0x0078, 0x2bad, 0x157e, 0x0d7e, 0x0e7e, 0x2069, 0xa814,
 	0x6810, 0x6914, 0xa10a, 0x00c8, 0x2e37, 0x2009, 0x0000, 0x6816,
-	0x2011, 0x0000, 0x2019, 0x0000, 0x20a9, 0x00ff, 0x2069, 0xa735,
+	0x2011, 0x0000, 0x2019, 0x0000, 0x20a9, 0x00ff, 0x2069, 0xa835,
 	0x2d04, 0xa075, 0x0040, 0x2e4c, 0x704c, 0x1078, 0x2e56, 0xa210,
 	0x7080, 0x1078, 0x2e56, 0xa318, 0x8d68, 0x00f0, 0x2e40, 0x2300,
 	0xa218, 0x0e7f, 0x0d7f, 0x157f, 0x0078, 0x2bad, 0x0f7e, 0x017e,
 	0xa07d, 0x0040, 0x2e65, 0x2001, 0x0000, 0x8000, 0x2f0c, 0x81ff,
 	0x0040, 0x2e65, 0x2178, 0x0078, 0x2e5d, 0x017f, 0x0f7f, 0x007c,
-	0x2069, 0xa714, 0x6910, 0x62a8, 0x0078, 0x2bad, 0x81ff, 0x00c0,
+	0x2069, 0xa814, 0x6910, 0x62a8, 0x0078, 0x2bad, 0x81ff, 0x00c0,
 	0x2bd7, 0x6150, 0xa190, 0x29c0, 0x2214, 0xa294, 0x00ff, 0x6070,
 	0xa084, 0xff00, 0xa215, 0x636c, 0x67cc, 0xd79c, 0x0040, 0x2e84,
 	0x2031, 0x0001, 0x0078, 0x2e86, 0x2031, 0x0000, 0x7e3a, 0x7f3e,
-	0x0078, 0x2bad, 0x6140, 0x6244, 0x2019, 0xa8a2, 0x231c, 0x0078,
+	0x0078, 0x2bad, 0x6140, 0x6244, 0x2019, 0xa9a2, 0x231c, 0x0078,
 	0x2bad, 0x127e, 0x2091, 0x8000, 0x6134, 0x6338, 0xa006, 0x2010,
 	0x127f, 0x0078, 0x2bad, 0x1078, 0x35e4, 0x0040, 0x2bdb, 0x6244,
 	0x6338, 0x0078, 0x2bad, 0x6140, 0x6244, 0x7824, 0x6042, 0x7b28,
-	0x6346, 0x2069, 0xa652, 0x831f, 0xa305, 0x6816, 0x782c, 0x2069,
-	0xa8a2, 0x2d1c, 0x206a, 0x0078, 0x2bad, 0x017e, 0x127e, 0x2091,
+	0x6346, 0x2069, 0xa752, 0x831f, 0xa305, 0x6816, 0x782c, 0x2069,
+	0xa9a2, 0x2d1c, 0x206a, 0x0078, 0x2bad, 0x017e, 0x127e, 0x2091,
 	0x8000, 0x7824, 0x6036, 0xd094, 0x0040, 0x2ec8, 0x7828, 0xa085,
-	0x0001, 0x2009, 0xa8ab, 0x200a, 0x2001, 0xffff, 0x1078, 0x5ae6,
+	0x0001, 0x2009, 0xa9ab, 0x200a, 0x2001, 0xffff, 0x1078, 0x5ae6,
 	0x782c, 0x603a, 0x127f, 0x017f, 0x0078, 0x2bad, 0x1078, 0x35e4,
 	0x0040, 0x2bdb, 0x7828, 0xa00d, 0x0040, 0x2bdb, 0x782c, 0xa005,
 	0x0040, 0x2bdb, 0x6244, 0x6146, 0x6338, 0x603a, 0x0078, 0x2bad,
-	0x2001, 0xa600, 0x2004, 0xa086, 0x0003, 0x00c0, 0x2bd7, 0x0c7e,
+	0x2001, 0xa700, 0x2004, 0xa086, 0x0003, 0x00c0, 0x2bd7, 0x0c7e,
 	0x2061, 0x0100, 0x7924, 0x810f, 0xa18c, 0x00ff, 0xa196, 0x00ff,
 	0x00c0, 0x2ef7, 0x6030, 0xa085, 0xff00, 0x0078, 0x2f06, 0xa182,
 	0x007f, 0x00c8, 0x2f30, 0xa188, 0x29c0, 0x210c, 0xa18c, 0x00ff,
@@ -1049,7 +1049,7 @@ unsigned short risc_code01[] = { 
 	0x683a, 0x701b, 0x2f8e, 0x2d00, 0x6012, 0x2009, 0x0032, 0x1078,
 	0x775c, 0x127f, 0x0c7f, 0x007c, 0x127f, 0x0c7f, 0x0078, 0x2bd7,
 	0x0c7f, 0x0078, 0x2bdb, 0x1078, 0x772d, 0x0078, 0x2f2c, 0x2001,
-	0xa600, 0x2004, 0xa086, 0x0003, 0x00c0, 0x2bd7, 0x0c7e, 0x2061,
+	0xa700, 0x2004, 0xa086, 0x0003, 0x00c0, 0x2bd7, 0x0c7e, 0x2061,
 	0x0100, 0x7924, 0x810f, 0xa18c, 0x00ff, 0xa196, 0x00ff, 0x00c0,
 	0x2f4e, 0x6030, 0xa085, 0xff00, 0x0078, 0x2f5d, 0xa182, 0x007f,
 	0x00c8, 0x2f87, 0xa188, 0x29c0, 0x210c, 0xa18c, 0x00ff, 0x6030,
@@ -1060,21 +1060,21 @@ unsigned short risc_code01[] = { 
 	0x701b, 0x2f8e, 0x2d00, 0x6012, 0x2009, 0x0032, 0x1078, 0x775c,
 	0x127f, 0x0c7f, 0x007c, 0x127f, 0x0c7f, 0x0078, 0x2bd7, 0x0c7f,
 	0x0078, 0x2bdb, 0x1078, 0x772d, 0x0078, 0x2f83, 0x6830, 0xa086,
-	0x0100, 0x0040, 0x2bd7, 0x0078, 0x2bad, 0x2061, 0xa933, 0x127e,
+	0x0100, 0x0040, 0x2bd7, 0x0078, 0x2bad, 0x2061, 0xaa33, 0x127e,
 	0x2091, 0x8000, 0x6000, 0xd084, 0x0040, 0x2fa6, 0x6104, 0x6208,
-	0x2019, 0xa612, 0x231c, 0x127f, 0x0078, 0x2bad, 0x127f, 0x0078,
+	0x2019, 0xa712, 0x231c, 0x127f, 0x0078, 0x2bad, 0x127f, 0x0078,
 	0x2bdb, 0x81ff, 0x00c0, 0x2bd7, 0x127e, 0x2091, 0x8000, 0x6248,
 	0x6064, 0xa202, 0x0048, 0x2fbd, 0xa085, 0x0001, 0x1078, 0x256a,
 	0x1078, 0x3c9e, 0x127f, 0x0078, 0x2bad, 0x127f, 0x0078, 0x2bdb,
-	0x127e, 0x2091, 0x8000, 0x20a9, 0x0012, 0x2001, 0xa640, 0x20a0,
+	0x127e, 0x2091, 0x8000, 0x20a9, 0x0012, 0x2001, 0xa740, 0x20a0,
 	0xa006, 0x40a4, 0x127f, 0x0078, 0x2bad, 0x7d38, 0x7c3c, 0x0078,
 	0x2c5f, 0x7824, 0xa09c, 0x00ff, 0xa39a, 0x0003, 0x00c8, 0x2bd7,
 	0x6250, 0xa084, 0xff00, 0x8007, 0xa206, 0x00c0, 0x2fe9, 0x2001,
-	0xa640, 0x2009, 0x000c, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0078,
+	0xa740, 0x2009, 0x000c, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0078,
 	0x3608, 0x81ff, 0x00c0, 0x2bd7, 0x1078, 0x35e4, 0x0040, 0x2bdb,
 	0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x00c0, 0x2bd7, 0x0c7e,
 	0x1078, 0x35ba, 0x0c7f, 0x0040, 0x2bd7, 0x6837, 0x0000, 0x6838,
-	0xc0fd, 0x683a, 0x1078, 0x8e4a, 0x0040, 0x2bd7, 0x7007, 0x0003,
+	0xc0fd, 0x683a, 0x1078, 0x8e5a, 0x0040, 0x2bd7, 0x7007, 0x0003,
 	0x701b, 0x300b, 0x007c, 0x6830, 0xa086, 0x0100, 0x0040, 0x2bd7,
 	0xad80, 0x000e, 0x2009, 0x000c, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38,
 	0x0078, 0x3608, 0x1078, 0x35ba, 0x0040, 0x2bd7, 0x1078, 0x42dd,
@@ -1095,10 +1095,10 @@ unsigned short risc_code01[] = { 
 	0x2bdb, 0x6804, 0xd0fc, 0x0040, 0x30c2, 0x1078, 0x35ba, 0x0040,
 	0x2bd7, 0x2009, 0x0014, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0xa290,
 	0x0038, 0xa399, 0x0000, 0x1078, 0x3604, 0x701b, 0x30a8, 0x007c,
-	0xade8, 0x000d, 0x20a9, 0x0014, 0x2d98, 0x2069, 0xa66e, 0x2da0,
-	0x53a3, 0x7010, 0xa0e8, 0x000d, 0x2001, 0xa672, 0x200c, 0xd1e4,
+	0xade8, 0x000d, 0x20a9, 0x0014, 0x2d98, 0x2069, 0xa76e, 0x2da0,
+	0x53a3, 0x7010, 0xa0e8, 0x000d, 0x2001, 0xa772, 0x200c, 0xd1e4,
 	0x0040, 0x30c2, 0x0c7e, 0x2061, 0x0100, 0x6004, 0xa085, 0x0b00,
-	0x6006, 0x0c7f, 0x20a9, 0x001c, 0x2d98, 0x2069, 0xa652, 0x2da0,
+	0x6006, 0x0c7f, 0x20a9, 0x001c, 0x2d98, 0x2069, 0xa752, 0x2da0,
 	0x53a3, 0x6814, 0xa08c, 0x00ff, 0x6142, 0x8007, 0xa084, 0x00ff,
 	0x6046, 0x1078, 0x4eae, 0x1078, 0x49ce, 0x1078, 0x4a3e, 0x6000,
 	0xa086, 0x0000, 0x00c0, 0x314d, 0x6808, 0x602a, 0x1078, 0x21f7,
@@ -1116,28 +1116,28 @@ unsigned short risc_code01[] = { 
 	0x3819, 0x0040, 0x313d, 0x1078, 0x256a, 0x60c0, 0xa005, 0x0040,
 	0x3149, 0x6003, 0x0001, 0x2091, 0x301d, 0x1078, 0x4224, 0x0078,
 	0x314d, 0x6003, 0x0004, 0x2091, 0x301d, 0x0078, 0x2bad, 0x6000,
-	0xa086, 0x0000, 0x0040, 0x2bd7, 0x2069, 0xa652, 0x7830, 0x6842,
+	0xa086, 0x0000, 0x0040, 0x2bd7, 0x2069, 0xa752, 0x7830, 0x6842,
 	0x7834, 0x6846, 0x6804, 0xd0fc, 0x0040, 0x3162, 0x2009, 0x0030,
 	0x0078, 0x3164, 0x2009, 0x001c, 0x2d00, 0x7a2c, 0x7b28, 0x7c3c,
 	0x7d38, 0x0078, 0x3608, 0xa006, 0x1078, 0x256a, 0x81ff, 0x00c0,
 	0x2bd7, 0x1078, 0x42dd, 0x1078, 0x4224, 0x0078, 0x2bad, 0x81ff,
 	0x00c0, 0x2bd7, 0x6184, 0x81ff, 0x0040, 0x3191, 0x703f, 0x0000,
-	0x2001, 0xacc0, 0x2009, 0x0040, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38,
+	0x2001, 0xadc0, 0x2009, 0x0040, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38,
 	0x127e, 0x2091, 0x8000, 0x1078, 0x3608, 0x701b, 0x2baa, 0x127f,
-	0x007c, 0x703f, 0x0001, 0x0d7e, 0x2069, 0xacc0, 0x20a9, 0x0040,
-	0x20a1, 0xacc0, 0x2019, 0xffff, 0x43a4, 0x6550, 0xa588, 0x29c0,
+	0x007c, 0x703f, 0x0001, 0x0d7e, 0x2069, 0xadc0, 0x20a9, 0x0040,
+	0x20a1, 0xadc0, 0x2019, 0xffff, 0x43a4, 0x6550, 0xa588, 0x29c0,
 	0x210c, 0xa18c, 0x00ff, 0x216a, 0xa00e, 0x2011, 0x0002, 0x2100,
 	0xa506, 0x0040, 0x31c3, 0x1078, 0x45c4, 0x00c0, 0x31c3, 0x6014,
-	0x821c, 0x0048, 0x31bb, 0xa398, 0xacc0, 0xa085, 0xff00, 0x8007,
-	0x201a, 0x0078, 0x31c2, 0xa398, 0xacc0, 0x2324, 0xa4a4, 0xff00,
+	0x821c, 0x0048, 0x31bb, 0xa398, 0xadc0, 0xa085, 0xff00, 0x8007,
+	0x201a, 0x0078, 0x31c2, 0xa398, 0xadc0, 0x2324, 0xa4a4, 0xff00,
 	0xa405, 0x201a, 0x8210, 0x8108, 0xa182, 0x0080, 0x00c8, 0x31ca,
 	0x0078, 0x31a7, 0x8201, 0x8007, 0x2d0c, 0xa105, 0x206a, 0x0d7f,
-	0x20a9, 0x0040, 0x20a1, 0xacc0, 0x2099, 0xacc0, 0x1078, 0x4281,
+	0x20a9, 0x0040, 0x20a1, 0xadc0, 0x2099, 0xadc0, 0x1078, 0x4281,
 	0x0078, 0x3180, 0x1078, 0x35e4, 0x0040, 0x2bdb, 0x0c7e, 0x1078,
 	0x35ba, 0x0c7f, 0x00c0, 0x31e8, 0x2009, 0x0002, 0x0078, 0x2bd7,
-	0x2001, 0xa653, 0x2004, 0xd0b4, 0x0040, 0x320f, 0x6000, 0xd08c,
+	0x2001, 0xa753, 0x2004, 0xd0b4, 0x0040, 0x320f, 0x6000, 0xd08c,
 	0x00c0, 0x320f, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x00c0,
-	0x320f, 0x6837, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x1078, 0x8e9e,
+	0x320f, 0x6837, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x1078, 0x8eae,
 	0x00c0, 0x3206, 0x2009, 0x0003, 0x0078, 0x2bd7, 0x7007, 0x0003,
 	0x701b, 0x320b, 0x007c, 0x1078, 0x35e4, 0x0040, 0x2bdb, 0x20a9,
 	0x002b, 0x2c98, 0xade8, 0x0002, 0x2da0, 0x53a3, 0x20a9, 0x0004,
@@ -1150,7 +1150,7 @@ unsigned short risc_code01[] = { 
 	0x0040, 0x2bdb, 0x1078, 0x482f, 0x0040, 0x2bd7, 0x2019, 0x0004,
 	0x1078, 0x47d3, 0x7924, 0x810f, 0x7a28, 0x1078, 0x3259, 0x0078,
 	0x2bad, 0xa186, 0x00ff, 0x0040, 0x3261, 0x1078, 0x3271, 0x0078,
-	0x3270, 0x2029, 0x007e, 0x2061, 0xa600, 0x6450, 0x2400, 0xa506,
+	0x3270, 0x2029, 0x007e, 0x2061, 0xa700, 0x6450, 0x2400, 0xa506,
 	0x0040, 0x326d, 0x2508, 0x1078, 0x3271, 0x8529, 0x00c8, 0x3266,
 	0x007c, 0x1078, 0x45c4, 0x00c0, 0x327c, 0x2200, 0x8003, 0x800b,
 	0x810b, 0xa108, 0x1078, 0x5a52, 0x007c, 0x81ff, 0x00c0, 0x2bd7,
@@ -1158,7 +1158,7 @@ unsigned short risc_code01[] = { 
 	0x1078, 0x47c8, 0x0078, 0x2bad, 0x81ff, 0x00c0, 0x2bd7, 0x1078,
 	0x35d2, 0x0040, 0x2bdb, 0x1078, 0x4673, 0x0040, 0x2bd7, 0x1078,
 	0x47b2, 0x0078, 0x2bad, 0x6100, 0x0078, 0x2bad, 0x1078, 0x35e4,
-	0x0040, 0x2bdb, 0x2001, 0xa600, 0x2004, 0xa086, 0x0003, 0x00c0,
+	0x0040, 0x2bdb, 0x2001, 0xa700, 0x2004, 0xa086, 0x0003, 0x00c0,
 	0x2bd7, 0x0d7e, 0xace8, 0x000a, 0x7924, 0xd184, 0x0040, 0x32b2,
 	0xace8, 0x0006, 0x680c, 0x8007, 0x783e, 0x6808, 0x8007, 0x783a,
 	0x6b04, 0x831f, 0x6a00, 0x8217, 0x0d7f, 0x6100, 0xa18c, 0x0200,
@@ -1167,7 +1167,7 @@ unsigned short risc_code01[] = { 
 	0x42dd, 0x7828, 0xa08a, 0x1000, 0x00c8, 0x2bdb, 0x7924, 0xa18c,
 	0xff00, 0x810f, 0xa186, 0x00ff, 0x0040, 0x32e5, 0xa182, 0x007f,
 	0x00c8, 0x2bdb, 0x2100, 0x1078, 0x2564, 0x027e, 0x0c7e, 0x127e,
-	0x2091, 0x8000, 0x2061, 0xa8c4, 0x601b, 0x0000, 0x601f, 0x0000,
+	0x2091, 0x8000, 0x2061, 0xa9c4, 0x601b, 0x0000, 0x601f, 0x0000,
 	0x2011, 0x0003, 0x1078, 0x70e0, 0x2011, 0x0002, 0x1078, 0x70ea,
 	0x1078, 0x6fc4, 0x037e, 0x2019, 0x0000, 0x1078, 0x7058, 0x037f,
 	0x2061, 0x0100, 0x6030, 0xa084, 0x00ff, 0x810f, 0xa105, 0x604a,
@@ -1201,7 +1201,7 @@ unsigned short risc_code01[] = { 
 	0x6853, 0x0000, 0x684f, 0x0020, 0x685b, 0x0001, 0x810b, 0x697e,
 	0x6883, 0x0000, 0x6a86, 0x6b8a, 0x6c8e, 0x6d92, 0x6996, 0x689b,
 	0x0000, 0x0c7f, 0x0d7f, 0x6837, 0x0000, 0x6838, 0xc0fd, 0x683a,
-	0x6823, 0x0000, 0x6804, 0x2068, 0x1078, 0x8e66, 0x00c0, 0x3404,
+	0x6823, 0x0000, 0x6804, 0x2068, 0x1078, 0x8e76, 0x00c0, 0x3404,
 	0x2009, 0x0003, 0x0078, 0x2bd7, 0x7007, 0x0003, 0x701b, 0x340f,
 	0x007c, 0x0c7f, 0x0d7f, 0x2009, 0x0002, 0x0078, 0x2bd7, 0x6820,
 	0xa086, 0x8001, 0x00c0, 0x2bad, 0x2009, 0x0004, 0x0078, 0x2bd7,
@@ -1223,7 +1223,7 @@ unsigned short risc_code01[] = { 
 	0x2610, 0x0078, 0x349b, 0xa0c6, 0x4009, 0x00c0, 0x3499, 0x0078,
 	0x349b, 0x2001, 0x4006, 0x2020, 0x0078, 0x2baf, 0x2d00, 0x7022,
 	0x017e, 0x0b7e, 0x0c7e, 0x0e7e, 0x2c70, 0x1078, 0x76c7, 0x0040,
-	0x34e4, 0x2d00, 0x601a, 0x2001, 0xa657, 0x2004, 0xa084, 0x00ff,
+	0x34e4, 0x2d00, 0x601a, 0x2001, 0xa757, 0x2004, 0xa084, 0x00ff,
 	0x6842, 0x2e58, 0x0e7f, 0x0e7e, 0x0c7e, 0x1078, 0x35ba, 0x0c7f,
 	0x2b70, 0x00c0, 0x34c5, 0x1078, 0x772d, 0x0e7f, 0x0c7f, 0x0b7f,
 	0x017f, 0x2009, 0x0002, 0x0078, 0x2bd7, 0x6837, 0x0000, 0x2d00,
@@ -1237,7 +1237,7 @@ unsigned short risc_code01[] = { 
 	0x2bd7, 0x2009, 0x0000, 0x1078, 0x489b, 0x00c0, 0x3508, 0xc185,
 	0x6000, 0xd0bc, 0x0040, 0x350d, 0xc18d, 0x0078, 0x2bad, 0x0e7e,
 	0x0d7e, 0x2029, 0x0000, 0x2021, 0x0080, 0x20a9, 0x007f, 0x2071,
-	0xa7b5, 0x2e04, 0xa005, 0x00c0, 0x3524, 0x2100, 0xa406, 0x00c0,
+	0xa8b5, 0x2e04, 0xa005, 0x00c0, 0x3524, 0x2100, 0xa406, 0x00c0,
 	0x3555, 0x2428, 0x0078, 0x3555, 0x2068, 0x6f10, 0x2700, 0xa306,
 	0x00c0, 0x3546, 0x6e14, 0x2600, 0xa206, 0x00c0, 0x3546, 0x2400,
 	0xa106, 0x00c0, 0x3542, 0x2d60, 0xd884, 0x0040, 0x356a, 0x6004,
@@ -1255,7 +1255,7 @@ unsigned short risc_code01[] = { 
 	0x3592, 0x007c, 0x6830, 0xa086, 0x0100, 0x0040, 0x2bd7, 0x0078,
 	0x2bad, 0x7924, 0xa18c, 0xff00, 0x810f, 0xa182, 0x0080, 0x0048,
 	0x2bdb, 0xa182, 0x00ff, 0x00c8, 0x2bdb, 0x127e, 0x2091, 0x8000,
-	0x1078, 0x8d4b, 0x00c0, 0x35b7, 0xa190, 0xa735, 0x2204, 0xa065,
+	0x1078, 0x8d5b, 0x00c0, 0x35b7, 0xa190, 0xa835, 0x2204, 0xa065,
 	0x0040, 0x35b7, 0x1078, 0x42f8, 0x127f, 0x0078, 0x2bad, 0x127f,
 	0x0078, 0x2bd7, 0x1078, 0x138b, 0x0040, 0x35d1, 0xa006, 0x6802,
 	0x7010, 0xa005, 0x00c0, 0x35c9, 0x2d00, 0x7012, 0x7016, 0x0078,
@@ -1267,41 +1267,41 @@ unsigned short risc_code01[] = { 
 	0x0048, 0x35f3, 0xa066, 0x8cff, 0x007c, 0x017e, 0x7110, 0x81ff,
 	0x0040, 0x3600, 0x2168, 0x6904, 0x1078, 0x13a4, 0x0078, 0x35f7,
 	0x7112, 0x7116, 0x017f, 0x007c, 0x2031, 0x0001, 0x0078, 0x360a,
-	0x2031, 0x0000, 0x2061, 0xa6d2, 0x6606, 0x6112, 0x600e, 0x6226,
+	0x2031, 0x0000, 0x2061, 0xa7d2, 0x6606, 0x6112, 0x600e, 0x6226,
 	0x632a, 0x642e, 0x6532, 0x2c10, 0x1078, 0x13db, 0x7007, 0x0002,
 	0x701b, 0x2bad, 0x007c, 0x0f7e, 0x127e, 0x2091, 0x8000, 0x2079,
-	0x0000, 0x2001, 0xa690, 0x2004, 0xa005, 0x00c0, 0x3636, 0x0068,
+	0x0000, 0x2001, 0xa790, 0x2004, 0xa005, 0x00c0, 0x3636, 0x0068,
 	0x3636, 0x7818, 0xd084, 0x00c0, 0x3636, 0x7a22, 0x7b26, 0x7c2a,
 	0x781b, 0x0001, 0x2091, 0x4080, 0x0078, 0x365b, 0x017e, 0x0c7e,
-	0x0e7e, 0x2071, 0xa682, 0x7138, 0xa182, 0x0008, 0x0048, 0x3644,
+	0x0e7e, 0x2071, 0xa782, 0x7138, 0xa182, 0x0008, 0x0048, 0x3644,
 	0x7030, 0x2060, 0x0078, 0x3655, 0x7030, 0xa0e0, 0x0008, 0xac82,
-	0xa6d2, 0x0048, 0x364d, 0x2061, 0xa692, 0x2c00, 0x7032, 0x81ff,
+	0xa7d2, 0x0048, 0x364d, 0x2061, 0xa792, 0x2c00, 0x7032, 0x81ff,
 	0x00c0, 0x3653, 0x7036, 0x8108, 0x713a, 0x2262, 0x6306, 0x640a,
 	0x0e7f, 0x0c7f, 0x017f, 0x127f, 0x0f7f, 0x007c, 0x0e7e, 0x2071,
-	0xa682, 0x7038, 0xa005, 0x0040, 0x3697, 0x127e, 0x2091, 0x8000,
+	0xa782, 0x7038, 0xa005, 0x0040, 0x3697, 0x127e, 0x2091, 0x8000,
 	0x0068, 0x3696, 0x0f7e, 0x2079, 0x0000, 0x7818, 0xd084, 0x00c0,
 	0x3695, 0x0c7e, 0x7034, 0x2060, 0x2c04, 0x7822, 0x6004, 0x7826,
 	0x6008, 0x782a, 0x781b, 0x0001, 0x2091, 0x4080, 0x7038, 0x8001,
-	0x703a, 0xa005, 0x00c0, 0x368b, 0x7033, 0xa692, 0x7037, 0xa692,
-	0x0c7f, 0x0078, 0x3695, 0xac80, 0x0008, 0xa0fa, 0xa6d2, 0x0048,
-	0x3693, 0x2001, 0xa692, 0x7036, 0x0c7f, 0x0f7f, 0x127f, 0x0e7f,
-	0x007c, 0x027e, 0x2001, 0xa653, 0x2004, 0xd0c4, 0x0040, 0x36a4,
+	0x703a, 0xa005, 0x00c0, 0x368b, 0x7033, 0xa792, 0x7037, 0xa792,
+	0x0c7f, 0x0078, 0x3695, 0xac80, 0x0008, 0xa0fa, 0xa7d2, 0x0048,
+	0x3693, 0x2001, 0xa792, 0x7036, 0x0c7f, 0x0f7f, 0x127f, 0x0e7f,
+	0x007c, 0x027e, 0x2001, 0xa753, 0x2004, 0xd0c4, 0x0040, 0x36a4,
 	0x2011, 0x8014, 0x1078, 0x361b, 0x027f, 0x007c, 0x81ff, 0x00c0,
 	0x2bd7, 0x127e, 0x2091, 0x8000, 0x6030, 0xc08d, 0xc085, 0xc0ac,
 	0x6032, 0x1078, 0x4224, 0x127f, 0x0078, 0x2bad, 0x81ff, 0x00c0,
-	0x2bd7, 0x6000, 0xa086, 0x0003, 0x00c0, 0x2bd7, 0x2001, 0xa653,
+	0x2bd7, 0x6000, 0xa086, 0x0003, 0x00c0, 0x2bd7, 0x2001, 0xa753,
 	0x2004, 0xd0ac, 0x00c0, 0x2bd7, 0x1078, 0x35e4, 0x0040, 0x2bdb,
 	0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x00c0, 0x36d3, 0x7828,
 	0xa005, 0x0040, 0x2bad, 0x0c7e, 0x1078, 0x35ba, 0x0c7f, 0x0040,
 	0x2bd7, 0x6837, 0x0000, 0x6833, 0x0000, 0x6838, 0xc0fd, 0x683a,
-	0x1078, 0x8f12, 0x0040, 0x2bd7, 0x7007, 0x0003, 0x701b, 0x36e9,
+	0x1078, 0x8f22, 0x0040, 0x2bd7, 0x7007, 0x0003, 0x701b, 0x36e9,
 	0x007c, 0x6830, 0xa086, 0x0100, 0x0040, 0x2bd7, 0x0078, 0x2bad,
-	0x2001, 0xa600, 0x2004, 0xa086, 0x0003, 0x00c0, 0x2bd7, 0x7f24,
+	0x2001, 0xa700, 0x2004, 0xa086, 0x0003, 0x00c0, 0x2bd7, 0x7f24,
 	0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x1078, 0x35ba, 0x0040, 0x2bd7,
 	0x2009, 0x0000, 0x2031, 0x0000, 0x7023, 0x0000, 0x702f, 0x0000,
 	0xad80, 0x0005, 0x7026, 0x20a0, 0x1078, 0x45c4, 0x00c0, 0x376d,
 	0x6004, 0xa0c4, 0x00ff, 0xa8c6, 0x0006, 0x0040, 0x371d, 0xa0c4,
-	0xff00, 0xa8c6, 0x0600, 0x00c0, 0x376d, 0x2001, 0xa653, 0x2004,
+	0xff00, 0xa8c6, 0x0600, 0x00c0, 0x376d, 0x2001, 0xa753, 0x2004,
 	0xd0ac, 0x00c0, 0x372a, 0x1078, 0x489b, 0x00c0, 0x372a, 0xd79c,
 	0x0040, 0x376d, 0xd794, 0x00c0, 0x3730, 0xd784, 0x0040, 0x373c,
 	0xac80, 0x0006, 0x2098, 0x3400, 0x20a9, 0x0004, 0x53a3, 0x1078,
@@ -1316,11 +1316,11 @@ unsigned short risc_code01[] = { 
 	0x007e, 0x0040, 0x3788, 0xd794, 0x0040, 0x3782, 0xa686, 0x0020,
 	0x0078, 0x3784, 0xa686, 0x0028, 0x0040, 0x3791, 0x0078, 0x370c,
 	0x86ff, 0x00c0, 0x378f, 0x7120, 0x810b, 0x0078, 0x2bad, 0x702f,
-	0x0001, 0x711e, 0x7020, 0xa600, 0x7022, 0x772a, 0x2061, 0xa6d2,
+	0x0001, 0x711e, 0x7020, 0xa600, 0x7022, 0x772a, 0x2061, 0xa7d2,
 	0x6007, 0x0000, 0x6612, 0x7024, 0x600e, 0x6226, 0x632a, 0x642e,
 	0x6532, 0x2c10, 0x1078, 0x13db, 0x7007, 0x0002, 0x701b, 0x37a9,
 	0x007c, 0x702c, 0xa005, 0x00c0, 0x37bb, 0x711c, 0x7024, 0x20a0,
-	0x7728, 0x2031, 0x0000, 0x2061, 0xa6d2, 0x6224, 0x6328, 0x642c,
+	0x7728, 0x2031, 0x0000, 0x2061, 0xa7d2, 0x6224, 0x6328, 0x642c,
 	0x6530, 0x0078, 0x370c, 0x7120, 0x810b, 0x0078, 0x2bad, 0x2029,
 	0x007e, 0x7924, 0x7a28, 0x7b2c, 0x7c38, 0xa184, 0xff00, 0x8007,
 	0xa0e2, 0x0020, 0x0048, 0x2bdb, 0xa502, 0x0048, 0x2bdb, 0xa184,
@@ -1332,27 +1332,27 @@ unsigned short risc_code01[] = { 
 	0x0020, 0x0048, 0x2bdb, 0xa502, 0x0048, 0x2bdb, 0xa484, 0xff00,
 	0x8007, 0xa0e2, 0x0020, 0x0048, 0x2bdb, 0xa502, 0x0048, 0x2bdb,
 	0xa484, 0x00ff, 0xa0e2, 0x0020, 0x0048, 0x2bdb, 0xa502, 0x0048,
-	0x2bdb, 0x2061, 0xa8a5, 0x6102, 0x6206, 0x630a, 0x640e, 0x0078,
-	0x2bad, 0x007e, 0x2001, 0xa653, 0x2004, 0xd0cc, 0x007f, 0x007c,
-	0x007e, 0x2001, 0xa672, 0x2004, 0xd0bc, 0x007f, 0x007c, 0x6164,
+	0x2bdb, 0x2061, 0xa9a5, 0x6102, 0x6206, 0x630a, 0x640e, 0x0078,
+	0x2bad, 0x007e, 0x2001, 0xa753, 0x2004, 0xd0cc, 0x007f, 0x007c,
+	0x007e, 0x2001, 0xa772, 0x2004, 0xd0bc, 0x007f, 0x007c, 0x6164,
 	0x7a24, 0x6300, 0x82ff, 0x00c0, 0x3830, 0x7926, 0x0078, 0x2bad,
 	0x83ff, 0x00c0, 0x2bdb, 0x2001, 0xfff0, 0xa200, 0x00c8, 0x2bdb,
 	0x2019, 0xffff, 0x6068, 0xa302, 0xa200, 0x0048, 0x2bdb, 0x7926,
-	0x6266, 0x0078, 0x2bad, 0x2001, 0xa600, 0x2004, 0xa086, 0x0003,
+	0x6266, 0x0078, 0x2bad, 0x2001, 0xa700, 0x2004, 0xa086, 0x0003,
 	0x00c0, 0x2bd7, 0x7c28, 0x7d24, 0x7e38, 0x7f2c, 0x1078, 0x35ba,
 	0x0040, 0x2bd7, 0x2009, 0x0000, 0x2019, 0x0000, 0x7023, 0x0000,
-	0x702f, 0x0000, 0xad80, 0x0003, 0x7026, 0x20a0, 0xa1e0, 0xa735,
+	0x702f, 0x0000, 0xad80, 0x0003, 0x7026, 0x20a0, 0xa1e0, 0xa835,
 	0x2c64, 0x8cff, 0x0040, 0x387d, 0x6004, 0xa084, 0x00ff, 0xa086,
 	0x0006, 0x0040, 0x3872, 0x6004, 0xa084, 0xff00, 0xa086, 0x0600,
 	0x00c0, 0x387d, 0x6014, 0x20a2, 0x94a0, 0x6010, 0x8007, 0xa105,
 	0x8007, 0x20a2, 0x94a0, 0xa398, 0x0002, 0x8108, 0xa182, 0x00ff,
 	0x0040, 0x3888, 0xa386, 0x002a, 0x0040, 0x3891, 0x0078, 0x385e,
 	0x83ff, 0x00c0, 0x388f, 0x7120, 0x810c, 0x0078, 0x2bad, 0x702f,
-	0x0001, 0x711e, 0x7020, 0xa300, 0x7022, 0x2061, 0xa6d2, 0x6007,
+	0x0001, 0x711e, 0x7020, 0xa300, 0x7022, 0x2061, 0xa7d2, 0x6007,
 	0x0000, 0x6312, 0x7024, 0x600e, 0x6426, 0x652a, 0x662e, 0x6732,
 	0x2c10, 0x1078, 0x13db, 0x7007, 0x0002, 0x701b, 0x38a8, 0x007c,
 	0x702c, 0xa005, 0x00c0, 0x38b9, 0x711c, 0x7024, 0x20a0, 0x2019,
-	0x0000, 0x2061, 0xa6d2, 0x6424, 0x6528, 0x662c, 0x6730, 0x0078,
+	0x0000, 0x2061, 0xa7d2, 0x6424, 0x6528, 0x662c, 0x6730, 0x0078,
 	0x385e, 0x7120, 0x810c, 0x0078, 0x2bad, 0x81ff, 0x00c0, 0x2bd7,
 	0x60cc, 0xd09c, 0x0040, 0x2bd7, 0x1078, 0x35ba, 0x0040, 0x2bd7,
 	0x7924, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x1078, 0x3604, 0x701b,
@@ -1363,11 +1363,11 @@ unsigned short risc_code01[] = { 
 	0x6612, 0x6516, 0x6e18, 0x0c7e, 0x1078, 0x35ba, 0x0040, 0x3910,
 	0x1078, 0x35ba, 0x0040, 0x3910, 0x0c7f, 0x0d7f, 0x6837, 0x0000,
 	0x6838, 0xc0fd, 0x683a, 0x6823, 0x0000, 0x6804, 0x2068, 0x1078,
-	0x8e82, 0x0040, 0x2bd7, 0x7007, 0x0003, 0x701b, 0x3913, 0x007c,
+	0x8e92, 0x0040, 0x2bd7, 0x7007, 0x0003, 0x701b, 0x3913, 0x007c,
 	0x0d7f, 0x0078, 0x2bd7, 0x7120, 0x1078, 0x298e, 0x6820, 0xa086,
 	0x8001, 0x0040, 0x2bd7, 0x2d00, 0x701e, 0x6804, 0xa080, 0x0002,
 	0x007e, 0x20a9, 0x002a, 0x2098, 0x20a0, 0x1078, 0x4281, 0x007f,
-	0xade8, 0x000d, 0x6a08, 0x6b0c, 0x6c10, 0x6d14, 0x2061, 0xa6d2,
+	0xade8, 0x000d, 0x6a08, 0x6b0c, 0x6c10, 0x6d14, 0x2061, 0xa7d2,
 	0x6007, 0x0000, 0x6e00, 0x6f28, 0xa7c6, 0x7000, 0x00c0, 0x393a,
 	0x0078, 0x393e, 0xa7c6, 0x7100, 0x00c0, 0x3946, 0xa6c2, 0x0004,
 	0x0048, 0x2bdb, 0x2009, 0x0004, 0x0078, 0x3608, 0xa7c6, 0x7200,
@@ -1376,8 +1376,8 @@ unsigned short risc_code01[] = { 
 	0x7007, 0x0002, 0x701b, 0x395d, 0x007c, 0x701c, 0x2068, 0x6804,
 	0xa080, 0x0001, 0x2004, 0xa080, 0x0002, 0x007e, 0x20a9, 0x002a,
 	0x2098, 0x20a0, 0x1078, 0x4281, 0x007f, 0x2009, 0x002a, 0x2061,
-	0xa6d2, 0x6224, 0x6328, 0x642c, 0x6530, 0x0078, 0x3608, 0x81ff,
-	0x00c0, 0x2bd7, 0x792c, 0x2001, 0xa89d, 0x2102, 0x1078, 0x35d2,
+	0xa7d2, 0x6224, 0x6328, 0x642c, 0x6530, 0x0078, 0x3608, 0x81ff,
+	0x00c0, 0x2bd7, 0x792c, 0x2001, 0xa99d, 0x2102, 0x1078, 0x35d2,
 	0x0040, 0x2bdb, 0x1078, 0x4673, 0x0040, 0x2bd7, 0x127e, 0x2091,
 	0x8000, 0x1078, 0x47de, 0x127f, 0x0078, 0x2bad, 0x7824, 0xd08c,
 	0x00c0, 0x3995, 0xd084, 0x0040, 0x31da, 0x1078, 0x35e4, 0x0040,
@@ -1385,22 +1385,22 @@ unsigned short risc_code01[] = { 
 	0x0002, 0x0078, 0x2bd7, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006,
 	0x0040, 0x39b0, 0xa08e, 0x0004, 0x0040, 0x39b0, 0xa08e, 0x0005,
 	0x00c0, 0x39dd, 0x7824, 0xd08c, 0x0040, 0x39bb, 0x6000, 0xc08c,
-	0x6002, 0x0078, 0x39c5, 0x2001, 0xa653, 0x2004, 0xd0b4, 0x0040,
+	0x6002, 0x0078, 0x39c5, 0x2001, 0xa753, 0x2004, 0xd0b4, 0x0040,
 	0x320f, 0x6000, 0xd08c, 0x00c0, 0x320f, 0x6837, 0x0000, 0x6838,
-	0xc0fd, 0x683a, 0x1078, 0x8e9e, 0x00c0, 0x39d2, 0x2009, 0x0003,
+	0xc0fd, 0x683a, 0x1078, 0x8eae, 0x00c0, 0x39d2, 0x2009, 0x0003,
 	0x0078, 0x2bd7, 0x7007, 0x0003, 0x701b, 0x39d7, 0x007c, 0x1078,
-	0x35e4, 0x0040, 0x2bdb, 0x0078, 0x320f, 0x2009, 0xa62f, 0x210c,
+	0x35e4, 0x0040, 0x2bdb, 0x0078, 0x320f, 0x2009, 0xa72f, 0x210c,
 	0x81ff, 0x0040, 0x39e7, 0x2009, 0x0001, 0x0078, 0x2bd7, 0x2001,
-	0xa600, 0x2004, 0xa086, 0x0003, 0x0040, 0x39f2, 0x2009, 0x0007,
-	0x0078, 0x2bd7, 0x2001, 0xa653, 0x2004, 0xd0ac, 0x0040, 0x39fc,
+	0xa700, 0x2004, 0xa086, 0x0003, 0x0040, 0x39f2, 0x2009, 0x0007,
+	0x0078, 0x2bd7, 0x2001, 0xa753, 0x2004, 0xd0ac, 0x0040, 0x39fc,
 	0x2009, 0x0008, 0x0078, 0x2bd7, 0x609c, 0xd0a4, 0x00c0, 0x3a03,
 	0xd0ac, 0x00c0, 0x320f, 0x6837, 0x0000, 0x6833, 0x0000, 0x6838,
-	0xc0fd, 0x683a, 0x1078, 0x8f12, 0x00c0, 0x3a12, 0x2009, 0x0003,
+	0xc0fd, 0x683a, 0x1078, 0x8f22, 0x00c0, 0x3a12, 0x2009, 0x0003,
 	0x0078, 0x2bd7, 0x7007, 0x0003, 0x701b, 0x3a17, 0x007c, 0x6830,
 	0xa086, 0x0100, 0x00c0, 0x3a20, 0x2009, 0x0004, 0x0078, 0x2bd7,
 	0x1078, 0x35e4, 0x0040, 0x2bdb, 0x0078, 0x39b2, 0x81ff, 0x2009,
 	0x0001, 0x00c0, 0x2bd7, 0x6000, 0xa086, 0x0003, 0x2009, 0x0007,
-	0x00c0, 0x2bd7, 0x2001, 0xa653, 0x2004, 0xd0ac, 0x2009, 0x0008,
+	0x00c0, 0x2bd7, 0x2001, 0xa753, 0x2004, 0xd0ac, 0x2009, 0x0008,
 	0x00c0, 0x2bd7, 0x1078, 0x35e4, 0x0040, 0x2bdb, 0x6004, 0xa084,
 	0x00ff, 0xa086, 0x0006, 0x2009, 0x0009, 0x00c0, 0x2bd7, 0x0c7e,
 	0x1078, 0x35ba, 0x0c7f, 0x2009, 0x0002, 0x0040, 0x2bd7, 0x6837,
@@ -1408,7 +1408,7 @@ unsigned short risc_code01[] = { 
 	0xff00, 0xa18c, 0x00ff, 0xa006, 0x82ff, 0x00c0, 0x3a65, 0xc0ed,
 	0x6952, 0x792c, 0x6956, 0x0078, 0x3a6e, 0xa28e, 0x0100, 0x00c0,
 	0x2bdb, 0xc0e5, 0x6853, 0x0000, 0x6857, 0x0000, 0x683e, 0x1078,
-	0x90bd, 0x2009, 0x0003, 0x0040, 0x2bd7, 0x7007, 0x0003, 0x701b,
+	0x90cd, 0x2009, 0x0003, 0x0040, 0x2bd7, 0x7007, 0x0003, 0x701b,
 	0x3a7a, 0x007c, 0x6830, 0xa086, 0x0100, 0x2009, 0x0004, 0x0040,
 	0x2bd7, 0x0078, 0x2bad, 0x81ff, 0x2009, 0x0001, 0x00c0, 0x2bd7,
 	0x6000, 0xa086, 0x0003, 0x2009, 0x0007, 0x00c0, 0x2bd7, 0x1078,
@@ -1421,10 +1421,10 @@ unsigned short risc_code01[] = { 
 	0x00c0, 0x3ac4, 0x0078, 0x3ac7, 0x0d7f, 0x00c0, 0x2bdb, 0x0d7f,
 	0x6837, 0x0000, 0x6833, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x0c7e,
 	0x1078, 0x35e4, 0x00c0, 0x3ad7, 0x0c7f, 0x0078, 0x2bdb, 0x1078,
-	0x9119, 0x2009, 0x0003, 0x0c7f, 0x0040, 0x2bd7, 0x7007, 0x0003,
+	0x9129, 0x2009, 0x0003, 0x0c7f, 0x0040, 0x2bd7, 0x7007, 0x0003,
 	0x701b, 0x3ae3, 0x007c, 0x6830, 0xa086, 0x0100, 0x2009, 0x0004,
 	0x0040, 0x2bd7, 0x0078, 0x2bad, 0x127e, 0x0c7e, 0x0e7e, 0x2061,
-	0x0100, 0x2071, 0xa600, 0x6044, 0xd0a4, 0x00c0, 0x3b15, 0xd084,
+	0x0100, 0x2071, 0xa700, 0x6044, 0xd0a4, 0x00c0, 0x3b15, 0xd084,
 	0x0040, 0x3afe, 0x1078, 0x3c75, 0x0078, 0x3b11, 0xd08c, 0x0040,
 	0x3b05, 0x1078, 0x3b8c, 0x0078, 0x3b11, 0xd094, 0x0040, 0x3b0c,
 	0x1078, 0x3b60, 0x0078, 0x3b11, 0xd09c, 0x0040, 0x3b11, 0x1078,
@@ -1436,7 +1436,7 @@ unsigned short risc_code01[] = { 
 	0x00c0, 0x3b45, 0x6240, 0xa294, 0x0010, 0x0040, 0x3b45, 0x2009,
 	0x00f7, 0x1078, 0x42a1, 0x0078, 0x3b5f, 0x6043, 0x0040, 0x6043,
 	0x0000, 0x7077, 0x0000, 0x708f, 0x0001, 0x70b3, 0x0000, 0x70cf,
-	0x0000, 0x2009, 0xacc0, 0x200b, 0x0000, 0x7087, 0x0000, 0x707b,
+	0x0000, 0x2009, 0xadc0, 0x200b, 0x0000, 0x7087, 0x0000, 0x707b,
 	0x000f, 0x2009, 0x000f, 0x2011, 0x41d5, 0x1078, 0x5add, 0x007c,
 	0x157e, 0x7078, 0xa005, 0x00c0, 0x3b8a, 0x2011, 0x41d5, 0x1078,
 	0x5a45, 0x6040, 0xa094, 0x0010, 0xa285, 0x0020, 0x6042, 0x20a9,
@@ -1447,30 +1447,30 @@ unsigned short risc_code01[] = { 
 	0x3b95, 0x1079, 0x3b98, 0x0078, 0x3b97, 0x1078, 0x1332, 0x007c,
 	0x3b9b, 0x3bea, 0x3c74, 0x0f7e, 0x707f, 0x0001, 0x20e1, 0xa000,
 	0x20e1, 0x8700, 0x1078, 0x21f7, 0x20e1, 0x9080, 0x20e1, 0x4000,
-	0x2079, 0xab00, 0x207b, 0x2200, 0x7807, 0x00ef, 0x780b, 0x0000,
+	0x2079, 0xac00, 0x207b, 0x2200, 0x7807, 0x00ef, 0x780b, 0x0000,
 	0x780f, 0x00ef, 0x7813, 0x0138, 0x7817, 0x0000, 0x781b, 0x0000,
 	0x781f, 0x0000, 0x7823, 0xffff, 0x7827, 0xffff, 0x782b, 0x0000,
-	0x782f, 0x0000, 0x2079, 0xab0c, 0x207b, 0x1101, 0x7807, 0x0000,
-	0x2099, 0xa605, 0x20a1, 0xab0e, 0x20a9, 0x0004, 0x53a3, 0x2079,
-	0xab12, 0x207b, 0x0000, 0x7807, 0x0000, 0x2099, 0xab00, 0x20a1,
+	0x782f, 0x0000, 0x2079, 0xac0c, 0x207b, 0x1101, 0x7807, 0x0000,
+	0x2099, 0xa705, 0x20a1, 0xac0e, 0x20a9, 0x0004, 0x53a3, 0x2079,
+	0xac12, 0x207b, 0x0000, 0x7807, 0x0000, 0x2099, 0xac00, 0x20a1,
 	0x020b, 0x20a9, 0x0014, 0x53a6, 0x60c3, 0x000c, 0x600f, 0x0000,
 	0x1078, 0x420b, 0x0f7f, 0x7083, 0x0000, 0x6043, 0x0008, 0x6043,
 	0x0000, 0x007c, 0x0d7e, 0x7080, 0x7083, 0x0000, 0xa025, 0x0040,
 	0x3c5e, 0x6020, 0xd0b4, 0x00c0, 0x3c5c, 0x718c, 0x81ff, 0x0040,
 	0x3c4b, 0xa486, 0x000c, 0x00c0, 0x3c56, 0xa480, 0x0018, 0x8004,
-	0x20a8, 0x2011, 0xab80, 0x2019, 0xab00, 0x220c, 0x2304, 0xa106,
+	0x20a8, 0x2011, 0xac80, 0x2019, 0xac00, 0x220c, 0x2304, 0xa106,
 	0x00c0, 0x3c22, 0x8210, 0x8318, 0x00f0, 0x3c05, 0x6043, 0x0004,
 	0x608b, 0xbc94, 0x608f, 0xf0f0, 0x6043, 0x0006, 0x707f, 0x0002,
 	0x708b, 0x0002, 0x2009, 0x07d0, 0x2011, 0x41dc, 0x1078, 0x5add,
-	0x0078, 0x3c5c, 0x2069, 0xab80, 0x6930, 0xa18e, 0x1101, 0x00c0,
+	0x0078, 0x3c5c, 0x2069, 0xac80, 0x6930, 0xa18e, 0x1101, 0x00c0,
 	0x3c56, 0x6834, 0xa005, 0x00c0, 0x3c56, 0x6900, 0xa18c, 0x00ff,
-	0x00c0, 0x3c36, 0x6804, 0xa005, 0x0040, 0x3c4b, 0x2011, 0xab8e,
-	0x2019, 0xa605, 0x20a9, 0x0004, 0x220c, 0x2304, 0xa102, 0x0048,
+	0x00c0, 0x3c36, 0x6804, 0xa005, 0x0040, 0x3c4b, 0x2011, 0xac8e,
+	0x2019, 0xa705, 0x20a9, 0x0004, 0x220c, 0x2304, 0xa102, 0x0048,
 	0x3c49, 0x00c0, 0x3c56, 0x8210, 0x8318, 0x00f0, 0x3c3c, 0x0078,
 	0x3c56, 0x708f, 0x0000, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099,
-	0xab80, 0x20a1, 0x020b, 0x20a9, 0x0014, 0x53a6, 0x6043, 0x0008,
+	0xac80, 0x20a1, 0x020b, 0x20a9, 0x0014, 0x53a6, 0x6043, 0x0008,
 	0x6043, 0x0000, 0x0078, 0x3c5e, 0x0d7f, 0x007c, 0x6020, 0xd0b4,
-	0x00c0, 0x3c5c, 0x60c3, 0x000c, 0x2011, 0xa8bb, 0x2013, 0x0000,
+	0x00c0, 0x3c5c, 0x60c3, 0x000c, 0x2011, 0xa9bb, 0x2013, 0x0000,
 	0x7083, 0x0000, 0x20e1, 0x9080, 0x60a3, 0x0056, 0x60a7, 0x9575,
 	0x1078, 0x6e06, 0x0078, 0x3c5c, 0x007c, 0x7088, 0xa08a, 0x001d,
 	0x00c8, 0x3c7e, 0x1079, 0x3c81, 0x0078, 0x3c80, 0x1078, 0x1332,
@@ -1478,11 +1478,11 @@ unsigned short risc_code01[] = { 
 	0x3dbc, 0x3de8, 0x3e10, 0x3e53, 0x3e7d, 0x3e9f, 0x3eb5, 0x3edb,
 	0x3eee, 0x3ef7, 0x3f2b, 0x3f57, 0x3f83, 0x3faf, 0x3fe5, 0x4030,
 	0x405f, 0x4081, 0x40c3, 0x40e9, 0x4102, 0x4103, 0x0c7e, 0x2061,
-	0xa600, 0x6003, 0x0007, 0x2061, 0x0100, 0x6004, 0xa084, 0xfff9,
+	0xa700, 0x6003, 0x0007, 0x2061, 0x0100, 0x6004, 0xa084, 0xfff9,
 	0x6006, 0x0c7f, 0x007c, 0x608b, 0xbc94, 0x608f, 0xf0f0, 0x6043,
 	0x0002, 0x708b, 0x0001, 0x2009, 0x07d0, 0x2011, 0x41dc, 0x1078,
 	0x5add, 0x007c, 0x0f7e, 0x7080, 0xa086, 0x0014, 0x00c0, 0x3ce7,
-	0x6043, 0x0000, 0x6020, 0xd0b4, 0x00c0, 0x3ce7, 0x2079, 0xab80,
+	0x6043, 0x0000, 0x6020, 0xd0b4, 0x00c0, 0x3ce7, 0x2079, 0xac80,
 	0x7a30, 0xa296, 0x1102, 0x00c0, 0x3ce5, 0x7834, 0xa005, 0x00c0,
 	0x3ce5, 0x7a38, 0xd2fc, 0x0040, 0x3cdb, 0x70b0, 0xa005, 0x00c0,
 	0x3cdb, 0x70b3, 0x0001, 0x2011, 0x41dc, 0x1078, 0x5a45, 0x708b,
@@ -1492,61 +1492,61 @@ unsigned short risc_code01[] = { 
 	0x000a, 0x20a3, 0x0000, 0x00f0, 0x3cf9, 0x60c3, 0x0014, 0x1078,
 	0x420b, 0x007c, 0x0f7e, 0x7080, 0xa005, 0x0040, 0x3d2c, 0x2011,
 	0x41dc, 0x1078, 0x5a45, 0xa086, 0x0014, 0x00c0, 0x3d2a, 0x2079,
-	0xab80, 0x7a30, 0xa296, 0x1102, 0x00c0, 0x3d2a, 0x7834, 0xa005,
+	0xac80, 0x7a30, 0xa296, 0x1102, 0x00c0, 0x3d2a, 0x7834, 0xa005,
 	0x00c0, 0x3d2a, 0x7a38, 0xd2fc, 0x0040, 0x3d24, 0x70b0, 0xa005,
 	0x00c0, 0x3d24, 0x70b3, 0x0001, 0x708b, 0x0004, 0x1078, 0x3d2e,
 	0x0078, 0x3d2c, 0x1078, 0x4224, 0x0f7f, 0x007c, 0x708b, 0x0005,
 	0x1078, 0x4289, 0x20a3, 0x1103, 0x20a3, 0x0000, 0x3430, 0x2011,
-	0xab8e, 0x1078, 0x42d4, 0x00c0, 0x3d4c, 0x7074, 0xa005, 0x00c0,
+	0xac8e, 0x1078, 0x42d4, 0x00c0, 0x3d4c, 0x7074, 0xa005, 0x00c0,
 	0x3d4c, 0x7150, 0xa186, 0xffff, 0x0040, 0x3d4c, 0x1078, 0x419d,
 	0x0040, 0x3d4c, 0x1078, 0x42b8, 0x20a9, 0x0008, 0x2298, 0x26a0,
 	0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014, 0x1078,
 	0x420b, 0x007c, 0x0f7e, 0x7080, 0xa005, 0x0040, 0x3d84, 0x2011,
 	0x41dc, 0x1078, 0x5a45, 0xa086, 0x0014, 0x00c0, 0x3d82, 0x2079,
-	0xab80, 0x7a30, 0xa296, 0x1103, 0x00c0, 0x3d82, 0x7834, 0xa005,
+	0xac80, 0x7a30, 0xa296, 0x1103, 0x00c0, 0x3d82, 0x7834, 0xa005,
 	0x00c0, 0x3d82, 0x7a38, 0xd2fc, 0x0040, 0x3d7c, 0x70b0, 0xa005,
 	0x00c0, 0x3d7c, 0x70b3, 0x0001, 0x708b, 0x0006, 0x1078, 0x3d86,
 	0x0078, 0x3d84, 0x1078, 0x4224, 0x0f7f, 0x007c, 0x708b, 0x0007,
 	0x1078, 0x4289, 0x20a3, 0x1104, 0x20a3, 0x0000, 0x3430, 0x2011,
-	0xab8e, 0x1078, 0x42d4, 0x00c0, 0x3dae, 0x7074, 0xa005, 0x00c0,
+	0xac8e, 0x1078, 0x42d4, 0x00c0, 0x3dae, 0x7074, 0xa005, 0x00c0,
 	0x3dae, 0x7154, 0xa186, 0xffff, 0x0040, 0x3dae, 0xa180, 0x29c0,
 	0x200c, 0xa18c, 0xff00, 0x810f, 0x1078, 0x419d, 0x0040, 0x3dae,
 	0x1078, 0x3820, 0x0040, 0x3dae, 0x1078, 0x256a, 0x20a9, 0x0008,
 	0x2298, 0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3,
 	0x0014, 0x1078, 0x420b, 0x007c, 0x0f7e, 0x7080, 0xa005, 0x0040,
 	0x3de6, 0x2011, 0x41dc, 0x1078, 0x5a45, 0xa086, 0x0014, 0x00c0,
-	0x3de4, 0x2079, 0xab80, 0x7a30, 0xa296, 0x1104, 0x00c0, 0x3de4,
+	0x3de4, 0x2079, 0xac80, 0x7a30, 0xa296, 0x1104, 0x00c0, 0x3de4,
 	0x7834, 0xa005, 0x00c0, 0x3de4, 0x7a38, 0xd2fc, 0x0040, 0x3dde,
 	0x70b0, 0xa005, 0x00c0, 0x3dde, 0x70b3, 0x0001, 0x708b, 0x0008,
 	0x1078, 0x3de8, 0x0078, 0x3de6, 0x1078, 0x4224, 0x0f7f, 0x007c,
 	0x708b, 0x0009, 0x1078, 0x4289, 0x20a3, 0x1105, 0x20a3, 0x0100,
 	0x3430, 0x1078, 0x42d4, 0x00c0, 0x3e01, 0x7074, 0xa005, 0x00c0,
 	0x3e01, 0x1078, 0x4104, 0x00c0, 0x3e0b, 0xa085, 0x0001, 0x1078,
-	0x256a, 0x20a9, 0x0008, 0x2099, 0xab8e, 0x26a0, 0x53a6, 0x20a3,
+	0x256a, 0x20a9, 0x0008, 0x2099, 0xac8e, 0x26a0, 0x53a6, 0x20a3,
 	0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014, 0x1078, 0x420b, 0x007c,
 	0x0f7e, 0x7080, 0xa005, 0x0040, 0x3e51, 0x2011, 0x41dc, 0x1078,
-	0x5a45, 0xa086, 0x0014, 0x00c0, 0x3e4f, 0x2079, 0xab80, 0x7a30,
+	0x5a45, 0xa086, 0x0014, 0x00c0, 0x3e4f, 0x2079, 0xac80, 0x7a30,
 	0xa296, 0x1105, 0x00c0, 0x3e4f, 0x7834, 0x2011, 0x0100, 0xa21e,
 	0x00c0, 0x3e3a, 0x7a38, 0xd2fc, 0x0040, 0x3e34, 0x70b0, 0xa005,
 	0x00c0, 0x3e34, 0x70b3, 0x0001, 0x708b, 0x000a, 0x1078, 0x3e53,
 	0x0078, 0x3e51, 0xa005, 0x00c0, 0x3e4f, 0x7a38, 0xd2fc, 0x0040,
 	0x3e47, 0x70b0, 0xa005, 0x00c0, 0x3e47, 0x70b3, 0x0001, 0x7087,
 	0x0000, 0x708b, 0x000e, 0x1078, 0x3edb, 0x0078, 0x3e51, 0x1078,
-	0x4224, 0x0f7f, 0x007c, 0x708b, 0x000b, 0x2011, 0xab0e, 0x22a0,
+	0x4224, 0x0f7f, 0x007c, 0x708b, 0x000b, 0x2011, 0xac0e, 0x22a0,
 	0x20a9, 0x0040, 0x2019, 0xffff, 0x43a4, 0x20a9, 0x0002, 0x2009,
 	0x0000, 0x41a4, 0x1078, 0x4289, 0x20a3, 0x1106, 0x20a3, 0x0000,
 	0x1078, 0x42d4, 0x0040, 0x3e70, 0x2013, 0x0000, 0x0078, 0x3e74,
 	0x6030, 0xa085, 0x0100, 0x2012, 0x2298, 0x20a9, 0x0042, 0x53a6,
 	0x60c3, 0x0084, 0x1078, 0x420b, 0x007c, 0x0f7e, 0x7080, 0xa005,
 	0x0040, 0x3e9d, 0x2011, 0x41dc, 0x1078, 0x5a45, 0xa086, 0x0084,
-	0x00c0, 0x3e9b, 0x2079, 0xab80, 0x7a30, 0xa296, 0x1106, 0x00c0,
+	0x00c0, 0x3e9b, 0x2079, 0xac80, 0x7a30, 0xa296, 0x1106, 0x00c0,
 	0x3e9b, 0x7834, 0xa005, 0x00c0, 0x3e9b, 0x708b, 0x000c, 0x1078,
 	0x3e9f, 0x0078, 0x3e9d, 0x1078, 0x4224, 0x0f7f, 0x007c, 0x708b,
 	0x000d, 0x1078, 0x4289, 0x20a3, 0x1107, 0x20a3, 0x0000, 0x2099,
-	0xab8e, 0x20a9, 0x0040, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000,
+	0xac8e, 0x20a9, 0x0040, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000,
 	0x60c3, 0x0084, 0x1078, 0x420b, 0x007c, 0x0f7e, 0x7080, 0xa005,
 	0x0040, 0x3ed9, 0x2011, 0x41dc, 0x1078, 0x5a45, 0xa086, 0x0084,
-	0x00c0, 0x3ed7, 0x2079, 0xab80, 0x7a30, 0xa296, 0x1107, 0x00c0,
+	0x00c0, 0x3ed7, 0x2079, 0xac80, 0x7a30, 0xa296, 0x1107, 0x00c0,
 	0x3ed7, 0x7834, 0xa005, 0x00c0, 0x3ed7, 0x7087, 0x0001, 0x1078,
 	0x427b, 0x708b, 0x000e, 0x1078, 0x3edb, 0x0078, 0x3ed9, 0x1078,
 	0x4224, 0x0f7f, 0x007c, 0x708b, 0x000f, 0x7083, 0x0000, 0x608b,
@@ -1556,70 +1556,70 @@ unsigned short risc_code01[] = { 
 	0x0011, 0x1078, 0x42d4, 0x00c0, 0x3f14, 0x716c, 0x81ff, 0x0040,
 	0x3f14, 0x2009, 0x0000, 0x7070, 0xa084, 0x00ff, 0x1078, 0x254d,
 	0xa186, 0x007e, 0x0040, 0x3f14, 0xa186, 0x0080, 0x0040, 0x3f14,
-	0x2011, 0xab8e, 0x1078, 0x419d, 0x20e1, 0x9080, 0x20e1, 0x4000,
-	0x2099, 0xab80, 0x20a1, 0x020b, 0x7480, 0xa480, 0x0018, 0xa080,
+	0x2011, 0xac8e, 0x1078, 0x419d, 0x20e1, 0x9080, 0x20e1, 0x4000,
+	0x2099, 0xac80, 0x20a1, 0x020b, 0x7480, 0xa480, 0x0018, 0xa080,
 	0x0007, 0xa084, 0x03f8, 0x8004, 0x20a8, 0x53a6, 0x60c3, 0x0014,
 	0x1078, 0x420b, 0x007c, 0x0f7e, 0x7080, 0xa005, 0x0040, 0x3f55,
 	0x2011, 0x41dc, 0x1078, 0x5a45, 0xa086, 0x0014, 0x00c0, 0x3f53,
-	0x2079, 0xab80, 0x7a30, 0xa296, 0x1103, 0x00c0, 0x3f53, 0x7834,
+	0x2079, 0xac80, 0x7a30, 0xa296, 0x1103, 0x00c0, 0x3f53, 0x7834,
 	0xa005, 0x00c0, 0x3f53, 0x7a38, 0xd2fc, 0x0040, 0x3f4d, 0x70b0,
 	0xa005, 0x00c0, 0x3f4d, 0x70b3, 0x0001, 0x708b, 0x0012, 0x1078,
 	0x3f57, 0x0078, 0x3f55, 0x1078, 0x4224, 0x0f7f, 0x007c, 0x708b,
 	0x0013, 0x1078, 0x4295, 0x20a3, 0x1103, 0x20a3, 0x0000, 0x3430,
-	0x2011, 0xab8e, 0x1078, 0x42d4, 0x00c0, 0x3f75, 0x7074, 0xa005,
+	0x2011, 0xac8e, 0x1078, 0x42d4, 0x00c0, 0x3f75, 0x7074, 0xa005,
 	0x00c0, 0x3f75, 0x7150, 0xa186, 0xffff, 0x0040, 0x3f75, 0x1078,
 	0x419d, 0x0040, 0x3f75, 0x1078, 0x42b8, 0x20a9, 0x0008, 0x2298,
 	0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014,
 	0x1078, 0x420b, 0x007c, 0x0f7e, 0x7080, 0xa005, 0x0040, 0x3fad,
 	0x2011, 0x41dc, 0x1078, 0x5a45, 0xa086, 0x0014, 0x00c0, 0x3fab,
-	0x2079, 0xab80, 0x7a30, 0xa296, 0x1104, 0x00c0, 0x3fab, 0x7834,
+	0x2079, 0xac80, 0x7a30, 0xa296, 0x1104, 0x00c0, 0x3fab, 0x7834,
 	0xa005, 0x00c0, 0x3fab, 0x7a38, 0xd2fc, 0x0040, 0x3fa5, 0x70b0,
 	0xa005, 0x00c0, 0x3fa5, 0x70b3, 0x0001, 0x708b, 0x0014, 0x1078,
 	0x3faf, 0x0078, 0x3fad, 0x1078, 0x4224, 0x0f7f, 0x007c, 0x708b,
 	0x0015, 0x1078, 0x4295, 0x20a3, 0x1104, 0x20a3, 0x0000, 0x3430,
-	0x2011, 0xab8e, 0x1078, 0x42d4, 0x00c0, 0x3fd7, 0x7074, 0xa005,
+	0x2011, 0xac8e, 0x1078, 0x42d4, 0x00c0, 0x3fd7, 0x7074, 0xa005,
 	0x00c0, 0x3fd7, 0x7154, 0xa186, 0xffff, 0x0040, 0x3fd7, 0xa180,
 	0x29c0, 0x200c, 0xa18c, 0xff00, 0x810f, 0x1078, 0x419d, 0x0040,
 	0x3fd7, 0x1078, 0x3820, 0x0040, 0x3fd7, 0x1078, 0x256a, 0x20a9,
 	0x0008, 0x2298, 0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000,
 	0x60c3, 0x0014, 0x1078, 0x420b, 0x007c, 0x0f7e, 0x7080, 0xa005,
 	0x0040, 0x402e, 0x2011, 0x41dc, 0x1078, 0x5a45, 0xa086, 0x0014,
-	0x00c0, 0x402c, 0x2079, 0xab80, 0x7a30, 0xa296, 0x1105, 0x00c0,
+	0x00c0, 0x402c, 0x2079, 0xac80, 0x7a30, 0xa296, 0x1105, 0x00c0,
 	0x402c, 0x7834, 0x2011, 0x0100, 0xa21e, 0x00c0, 0x400b, 0x7a38,
 	0xd2fc, 0x0040, 0x4009, 0x70b0, 0xa005, 0x00c0, 0x4009, 0x70b3,
 	0x0001, 0x0078, 0x401a, 0xa005, 0x00c0, 0x402c, 0x7a38, 0xd2fc,
 	0x0040, 0x4018, 0x70b0, 0xa005, 0x00c0, 0x4018, 0x70b3, 0x0001,
-	0x7087, 0x0000, 0x7a38, 0xd2f4, 0x0040, 0x4026, 0x2001, 0xa674,
+	0x7087, 0x0000, 0x7a38, 0xd2f4, 0x0040, 0x4026, 0x2001, 0xa774,
 	0x2004, 0xd0a4, 0x00c0, 0x4026, 0x70cf, 0x0008, 0x708b, 0x0016,
 	0x1078, 0x4030, 0x0078, 0x402e, 0x1078, 0x4224, 0x0f7f, 0x007c,
-	0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099, 0xab80, 0x20a1, 0x020b,
-	0x20a9, 0x000e, 0x53a6, 0x3430, 0x2011, 0xab8e, 0x708b, 0x0017,
+	0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099, 0xac80, 0x20a1, 0x020b,
+	0x20a9, 0x000e, 0x53a6, 0x3430, 0x2011, 0xac8e, 0x708b, 0x0017,
 	0x1078, 0x42d4, 0x00c0, 0x4050, 0x7074, 0xa005, 0x00c0, 0x4050,
 	0x1078, 0x4104, 0x00c0, 0x405a, 0xa085, 0x0001, 0x1078, 0x256a,
-	0x20a9, 0x0008, 0x2099, 0xab8e, 0x26a0, 0x53a6, 0x20a3, 0x0000,
+	0x20a9, 0x0008, 0x2099, 0xac8e, 0x26a0, 0x53a6, 0x20a3, 0x0000,
 	0x20a3, 0x0000, 0x60c3, 0x0014, 0x1078, 0x420b, 0x007c, 0x0f7e,
 	0x7080, 0xa005, 0x0040, 0x407f, 0x2011, 0x41dc, 0x1078, 0x5a45,
-	0xa086, 0x0084, 0x00c0, 0x407d, 0x2079, 0xab80, 0x7a30, 0xa296,
+	0xa086, 0x0084, 0x00c0, 0x407d, 0x2079, 0xac80, 0x7a30, 0xa296,
 	0x1106, 0x00c0, 0x407d, 0x7834, 0xa005, 0x00c0, 0x407d, 0x708b,
 	0x0018, 0x1078, 0x4081, 0x0078, 0x407f, 0x1078, 0x4224, 0x0f7f,
 	0x007c, 0x708b, 0x0019, 0x1078, 0x4295, 0x20a3, 0x1106, 0x20a3,
-	0x0000, 0x3430, 0x2099, 0xab8e, 0x2039, 0xab0e, 0x27a0, 0x20a9,
+	0x0000, 0x3430, 0x2099, 0xac8e, 0x2039, 0xac0e, 0x27a0, 0x20a9,
 	0x0040, 0x53a3, 0x1078, 0x42d4, 0x00c0, 0x40b5, 0x2728, 0x2514,
 	0x8207, 0xa084, 0x00ff, 0x8000, 0x2018, 0xa294, 0x00ff, 0x8007,
-	0xa205, 0x202a, 0x6030, 0x2310, 0x8214, 0xa2a0, 0xab0e, 0x2414,
+	0xa205, 0x202a, 0x6030, 0x2310, 0x8214, 0xa2a0, 0xac0e, 0x2414,
 	0xa38c, 0x0001, 0x0040, 0x40b0, 0xa294, 0xff00, 0x0078, 0x40b3,
 	0xa294, 0x00ff, 0x8007, 0xa215, 0x2222, 0x2798, 0x26a0, 0x20a9,
 	0x0040, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0084,
 	0x1078, 0x420b, 0x007c, 0x0f7e, 0x7080, 0xa005, 0x0040, 0x40e7,
 	0x2011, 0x41dc, 0x1078, 0x5a45, 0xa086, 0x0084, 0x00c0, 0x40e5,
-	0x2079, 0xab80, 0x7a30, 0xa296, 0x1107, 0x00c0, 0x40e5, 0x7834,
+	0x2079, 0xac80, 0x7a30, 0xa296, 0x1107, 0x00c0, 0x40e5, 0x7834,
 	0xa005, 0x00c0, 0x40e5, 0x7087, 0x0001, 0x1078, 0x427b, 0x708b,
 	0x001a, 0x1078, 0x40e9, 0x0078, 0x40e7, 0x1078, 0x4224, 0x0f7f,
 	0x007c, 0x708b, 0x001b, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099,
-	0xab80, 0x20a1, 0x020b, 0x7480, 0xa480, 0x0018, 0xa080, 0x0007,
+	0xac80, 0x20a1, 0x020b, 0x7480, 0xa480, 0x0018, 0xa080, 0x0007,
 	0xa084, 0x03f8, 0x8004, 0x20a8, 0x53a6, 0x60c3, 0x0084, 0x1078,
-	0x420b, 0x007c, 0x007c, 0x007c, 0x087e, 0x097e, 0x2029, 0xa653,
-	0x252c, 0x20a9, 0x0008, 0x2041, 0xab0e, 0x28a0, 0x2099, 0xab8e,
+	0x420b, 0x007c, 0x007c, 0x007c, 0x087e, 0x097e, 0x2029, 0xa753,
+	0x252c, 0x20a9, 0x0008, 0x2041, 0xac0e, 0x28a0, 0x2099, 0xac8e,
 	0x53a3, 0x20a9, 0x0008, 0x2011, 0x0007, 0xd5d4, 0x0040, 0x411a,
 	0x2011, 0x0000, 0x2800, 0xa200, 0x200c, 0xa1a6, 0xffff, 0x00c0,
 	0x412c, 0xd5d4, 0x0040, 0x4127, 0x8210, 0x0078, 0x4128, 0x8211,
@@ -1644,44 +1644,44 @@ unsigned short risc_code01[] = { 
 	0x8423, 0x8319, 0x00c0, 0x41b8, 0xa238, 0x2704, 0xa42c, 0x00c0,
 	0x41d4, 0xa405, 0x203a, 0x7152, 0xa1a0, 0x29c0, 0x242c, 0xa5ac,
 	0x00ff, 0x6532, 0x60e7, 0x0000, 0x65ea, 0x706f, 0x0000, 0x7572,
-	0x7077, 0x0001, 0xa084, 0x0000, 0x007c, 0x0e7e, 0x2071, 0xa600,
+	0x7077, 0x0001, 0xa084, 0x0000, 0x007c, 0x0e7e, 0x2071, 0xa700,
 	0x707b, 0x0000, 0x0e7f, 0x007c, 0x0e7e, 0x0f7e, 0x2001, 0x0002,
 	0x1078, 0x5ae6, 0x2079, 0x0100, 0x2071, 0x0140, 0x1078, 0x6e0f,
 	0x7004, 0xa084, 0x4000, 0x0040, 0x41f1, 0x7003, 0x1000, 0x7003,
-	0x0000, 0x127e, 0x2091, 0x8000, 0x2071, 0xa622, 0x2073, 0x0000,
+	0x0000, 0x127e, 0x2091, 0x8000, 0x2071, 0xa722, 0x2073, 0x0000,
 	0x7840, 0x027e, 0x017e, 0x2009, 0x00f7, 0x1078, 0x42a1, 0x017f,
 	0xa094, 0x0010, 0xa285, 0x0080, 0x7842, 0x7a42, 0x027f, 0x127f,
-	0x0f7f, 0x0e7f, 0x007c, 0x127e, 0x2091, 0x8000, 0x2011, 0xa8bb,
+	0x0f7f, 0x0e7f, 0x007c, 0x127e, 0x2091, 0x8000, 0x2011, 0xa9bb,
 	0x2013, 0x0000, 0x7083, 0x0000, 0x127f, 0x20e1, 0x9080, 0x60a3,
 	0x0056, 0x60a7, 0x9575, 0x1078, 0x6e06, 0x2009, 0x07d0, 0x2011,
 	0x41dc, 0x1078, 0x5add, 0x007c, 0x017e, 0x027e, 0x0c7e, 0x127e,
 	0x2091, 0x8000, 0x2011, 0x0003, 0x1078, 0x70e0, 0x2011, 0x0002,
 	0x1078, 0x70ea, 0x1078, 0x6fc4, 0x037e, 0x2019, 0x0000, 0x1078,
-	0x7058, 0x037f, 0x2009, 0x00f7, 0x1078, 0x42a1, 0x2061, 0xa8c4,
-	0x601b, 0x0000, 0x601f, 0x0000, 0x2061, 0xa600, 0x6003, 0x0001,
+	0x7058, 0x037f, 0x2009, 0x00f7, 0x1078, 0x42a1, 0x2061, 0xa9c4,
+	0x601b, 0x0000, 0x601f, 0x0000, 0x2061, 0xa700, 0x6003, 0x0001,
 	0x2061, 0x0100, 0x6043, 0x0090, 0x6043, 0x0010, 0x2009, 0x002d,
 	0x2011, 0x4259, 0x1078, 0x5a38, 0x127f, 0x0c7f, 0x027f, 0x017f,
 	0x007c, 0x0e7e, 0x007e, 0x127e, 0x2091, 0x8000, 0x2001, 0x0001,
 	0x1078, 0x5ae6, 0x2071, 0x0100, 0x1078, 0x6e0f, 0x2071, 0x0140,
 	0x7004, 0xa084, 0x4000, 0x0040, 0x4271, 0x7003, 0x1000, 0x7003,
 	0x0000, 0x2001, 0x0001, 0x1078, 0x24e8, 0x1078, 0x4224, 0x127f,
-	0x007f, 0x0e7f, 0x007c, 0x20a9, 0x0040, 0x20a1, 0xacc0, 0x2099,
-	0xab8e, 0x3304, 0x8007, 0x20a2, 0x9398, 0x94a0, 0x00f0, 0x4281,
-	0x007c, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099, 0xab00, 0x20a1,
+	0x007f, 0x0e7f, 0x007c, 0x20a9, 0x0040, 0x20a1, 0xadc0, 0x2099,
+	0xac8e, 0x3304, 0x8007, 0x20a2, 0x9398, 0x94a0, 0x00f0, 0x4281,
+	0x007c, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099, 0xac00, 0x20a1,
 	0x020b, 0x20a9, 0x000c, 0x53a6, 0x007c, 0x20e1, 0x9080, 0x20e1,
-	0x4000, 0x2099, 0xab80, 0x20a1, 0x020b, 0x20a9, 0x000c, 0x53a6,
-	0x007c, 0x0c7e, 0x007e, 0x2061, 0x0100, 0x810f, 0x2001, 0xa62f,
+	0x4000, 0x2099, 0xac80, 0x20a1, 0x020b, 0x20a9, 0x000c, 0x53a6,
+	0x007c, 0x0c7e, 0x007e, 0x2061, 0x0100, 0x810f, 0x2001, 0xa72f,
 	0x2004, 0xa005, 0x00c0, 0x42b2, 0x6030, 0xa084, 0x00ff, 0xa105,
 	0x0078, 0x42b4, 0xa185, 0x00f7, 0x604a, 0x007f, 0x0c7f, 0x007c,
-	0x017e, 0x047e, 0x2001, 0xa653, 0x2004, 0xd0a4, 0x0040, 0x42cb,
-	0xa006, 0x2020, 0x2009, 0x002a, 0x1078, 0xa21d, 0x2001, 0xa60c,
+	0x017e, 0x047e, 0x2001, 0xa753, 0x2004, 0xd0a4, 0x0040, 0x42cb,
+	0xa006, 0x2020, 0x2009, 0x002a, 0x1078, 0xa22d, 0x2001, 0xa70c,
 	0x200c, 0xc195, 0x2102, 0x2019, 0x002a, 0x2009, 0x0000, 0x1078,
-	0x284f, 0x047f, 0x017f, 0x007c, 0x007e, 0x2001, 0xa60c, 0x2004,
+	0x284f, 0x047f, 0x017f, 0x007c, 0x007e, 0x2001, 0xa70c, 0x2004,
 	0xd09c, 0x0040, 0x42db, 0x007f, 0x007c, 0x007e, 0x017e, 0x127e,
 	0x2091, 0x8000, 0x2001, 0x0101, 0x200c, 0xa18d, 0x0006, 0x2102,
 	0x127f, 0x017f, 0x007f, 0x007c, 0x157e, 0x20a9, 0x00ff, 0x2009,
-	0xa735, 0xa006, 0x200a, 0x8108, 0x00f0, 0x42f2, 0x157f, 0x007c,
-	0x0d7e, 0x037e, 0x157e, 0x137e, 0x147e, 0x2069, 0xa652, 0xa006,
+	0xa835, 0xa006, 0x200a, 0x8108, 0x00f0, 0x42f2, 0x157f, 0x007c,
+	0x0d7e, 0x037e, 0x157e, 0x137e, 0x147e, 0x2069, 0xa752, 0xa006,
 	0x6002, 0x6007, 0x0707, 0x600a, 0x600e, 0x6012, 0xa198, 0x29c0,
 	0x231c, 0xa39c, 0x00ff, 0x6316, 0x20a9, 0x0004, 0xac98, 0x0006,
 	0x23a0, 0x40a4, 0x20a9, 0x0004, 0xac98, 0x000a, 0x23a0, 0x40a4,
@@ -1694,11 +1694,11 @@ unsigned short risc_code01[] = { 
 	0x6046, 0x6814, 0xa084, 0x00ff, 0x6042, 0x147f, 0x137f, 0x157f,
 	0x037f, 0x0d7f, 0x007c, 0x127e, 0x2091, 0x8000, 0x6944, 0x6e48,
 	0xa684, 0x3fff, 0xa082, 0x4000, 0x00c8, 0x4424, 0xa18c, 0xff00,
-	0x810f, 0xa182, 0x00ff, 0x00c8, 0x442a, 0x2001, 0xa60c, 0x2004,
-	0xa084, 0x0003, 0x0040, 0x4385, 0x2001, 0xa60c, 0x2004, 0xd084,
-	0x00c0, 0x4405, 0xa188, 0xa735, 0x2104, 0xa065, 0x0040, 0x4405,
+	0x810f, 0xa182, 0x00ff, 0x00c8, 0x442a, 0x2001, 0xa70c, 0x2004,
+	0xa084, 0x0003, 0x0040, 0x4385, 0x2001, 0xa70c, 0x2004, 0xd084,
+	0x00c0, 0x4405, 0xa188, 0xa835, 0x2104, 0xa065, 0x0040, 0x4405,
 	0x6004, 0xa084, 0x00ff, 0xa08e, 0x0006, 0x00c0, 0x4405, 0x6000,
-	0xd0c4, 0x0040, 0x4405, 0x0078, 0x4392, 0xa188, 0xa735, 0x2104,
+	0xd0c4, 0x0040, 0x4405, 0x0078, 0x4392, 0xa188, 0xa835, 0x2104,
 	0xa065, 0x0040, 0x43e9, 0x6004, 0xa084, 0x00ff, 0xa08e, 0x0006,
 	0x00c0, 0x43ef, 0x60a4, 0xa00d, 0x0040, 0x439a, 0x1078, 0x4817,
 	0x0040, 0x43e3, 0x60a8, 0xa00d, 0x0040, 0x43b4, 0x1078, 0x486a,
@@ -1714,7 +1714,7 @@ unsigned short risc_code01[] = { 
 	0x442e, 0x2001, 0x0028, 0x2009, 0x0000, 0x0078, 0x442e, 0xa082,
 	0x0006, 0x00c8, 0x4405, 0x60a0, 0xd0bc, 0x00c0, 0x4401, 0x6100,
 	0xd1fc, 0x0040, 0x4392, 0x2001, 0x0029, 0x2009, 0x1000, 0x0078,
-	0x442e, 0x2001, 0x0028, 0x0078, 0x4420, 0x2009, 0xa60c, 0x210c,
+	0x442e, 0x2001, 0x0028, 0x0078, 0x4420, 0x2009, 0xa70c, 0x210c,
 	0xd18c, 0x0040, 0x440f, 0x2001, 0x0004, 0x0078, 0x4420, 0xd184,
 	0x0040, 0x4416, 0x2001, 0x0004, 0x0078, 0x4420, 0x2001, 0x0029,
 	0x6100, 0xd1fc, 0x0040, 0x4420, 0x2009, 0x1000, 0x0078, 0x442e,
@@ -1722,7 +1722,7 @@ unsigned short risc_code01[] = { 
 	0x0078, 0x442e, 0x2001, 0x0029, 0x2009, 0x0000, 0xa005, 0x127f,
 	0x007c, 0x6944, 0x6e48, 0xa684, 0x3fff, 0xa082, 0x4000, 0x00c8,
 	0x447e, 0xa18c, 0xff00, 0x810f, 0xa182, 0x00ff, 0x00c8, 0x4464,
-	0xa188, 0xa735, 0x2104, 0xa065, 0x0040, 0x4464, 0x6004, 0xa084,
+	0xa188, 0xa835, 0x2104, 0xa065, 0x0040, 0x4464, 0x6004, 0xa084,
 	0x00ff, 0xa08e, 0x0006, 0x00c0, 0x446a, 0x684c, 0xd0ec, 0x0040,
 	0x4457, 0x1078, 0x46e7, 0x1078, 0x4484, 0x0078, 0x445f, 0x1078,
 	0x4484, 0x684c, 0xd0fc, 0x0040, 0x445f, 0x1078, 0x46d6, 0x1078,
@@ -1734,7 +1734,7 @@ unsigned short risc_code01[] = { 
 	0xa00d, 0x0040, 0x4492, 0x2d00, 0x200a, 0x6803, 0x0000, 0x6052,
 	0x127f, 0x007c, 0x2d00, 0x6052, 0x604e, 0x6803, 0x0000, 0x0078,
 	0x4490, 0x127e, 0x2091, 0x8000, 0x604c, 0xa005, 0x0040, 0x44af,
-	0x0e7e, 0x2071, 0xa8b1, 0x7004, 0xa086, 0x0002, 0x0040, 0x44b6,
+	0x0e7e, 0x2071, 0xa9b1, 0x7004, 0xa086, 0x0002, 0x0040, 0x44b6,
 	0x0e7f, 0x604c, 0x6802, 0x2d00, 0x604e, 0x127f, 0x007c, 0x2d00,
 	0x6052, 0x604e, 0x6803, 0x0000, 0x0078, 0x44ad, 0x701c, 0xac06,
 	0x00c0, 0x44a8, 0x604c, 0x2070, 0x7000, 0x6802, 0x2d00, 0x7002,
@@ -1748,38 +1748,38 @@ unsigned short risc_code01[] = { 
 	0x44fc, 0xc285, 0x0078, 0x44fd, 0xc284, 0x6202, 0x027f, 0x0c7f,
 	0x127f, 0x007c, 0x127e, 0x0c7e, 0x2091, 0x8000, 0x6218, 0x2260,
 	0x6204, 0x007e, 0xa086, 0x0006, 0x00c0, 0x4521, 0x609c, 0xd0ac,
-	0x0040, 0x4521, 0x2001, 0xa653, 0x2004, 0xd0a4, 0x0040, 0x4521,
+	0x0040, 0x4521, 0x2001, 0xa753, 0x2004, 0xd0a4, 0x0040, 0x4521,
 	0xa284, 0xff00, 0x8007, 0xa086, 0x0007, 0x00c0, 0x4521, 0x2011,
 	0x0600, 0x007f, 0xa294, 0xff00, 0xa215, 0x6206, 0x007e, 0xa086,
 	0x0006, 0x00c0, 0x4531, 0x6290, 0x82ff, 0x00c0, 0x4531, 0x1078,
 	0x1332, 0x007f, 0x0c7f, 0x127f, 0x007c, 0x127e, 0x0c7e, 0x2091,
 	0x8000, 0x6218, 0x2260, 0x6204, 0x007e, 0xa086, 0x0006, 0x00c0,
-	0x4553, 0x609c, 0xd0a4, 0x0040, 0x4553, 0x2001, 0xa653, 0x2004,
+	0x4553, 0x609c, 0xd0a4, 0x0040, 0x4553, 0x2001, 0xa753, 0x2004,
 	0xd0ac, 0x00c0, 0x4553, 0xa284, 0x00ff, 0xa086, 0x0007, 0x00c0,
 	0x4553, 0x2011, 0x0006, 0x007f, 0xa294, 0x00ff, 0x8007, 0xa215,
 	0x6206, 0x0c7f, 0x127f, 0x007c, 0x027e, 0xa182, 0x00ff, 0x0048,
-	0x4565, 0xa085, 0x0001, 0x0078, 0x457d, 0xa190, 0xa735, 0x2204,
+	0x4565, 0xa085, 0x0001, 0x0078, 0x457d, 0xa190, 0xa835, 0x2204,
 	0xa065, 0x00c0, 0x457c, 0x017e, 0x0d7e, 0x1078, 0x1370, 0x2d60,
 	0x0d7f, 0x017f, 0x0040, 0x4561, 0x2c00, 0x2012, 0x60a7, 0x0000,
 	0x60ab, 0x0000, 0x1078, 0x42f8, 0xa006, 0x027f, 0x007c, 0x127e,
 	0x2091, 0x8000, 0x027e, 0xa182, 0x00ff, 0x0048, 0x458b, 0xa085,
-	0x0001, 0x0078, 0x45c1, 0x0d7e, 0xa190, 0xa735, 0x2204, 0xa06d,
+	0x0001, 0x0078, 0x45c1, 0x0d7e, 0xa190, 0xa835, 0x2204, 0xa06d,
 	0x0040, 0x45bf, 0x2013, 0x0000, 0x0d7e, 0x0c7e, 0x2d60, 0x60a4,
 	0xa06d, 0x0040, 0x459d, 0x1078, 0x13a4, 0x60a8, 0xa06d, 0x0040,
 	0x45a3, 0x1078, 0x13a4, 0x0c7f, 0x0d7f, 0x0d7e, 0x0c7e, 0x68ac,
 	0x2060, 0x8cff, 0x0040, 0x45bb, 0x600c, 0x007e, 0x6010, 0x2068,
-	0x1078, 0x8d06, 0x0040, 0x45b6, 0x1078, 0x13b4, 0x1078, 0x772d,
+	0x1078, 0x8d16, 0x0040, 0x45b6, 0x1078, 0x13b4, 0x1078, 0x772d,
 	0x0c7f, 0x0078, 0x45a9, 0x0c7f, 0x0d7f, 0x1078, 0x13a4, 0x0d7f,
 	0xa006, 0x027f, 0x127f, 0x007c, 0x017e, 0xa182, 0x00ff, 0x0048,
-	0x45cd, 0xa085, 0x0001, 0x0078, 0x45d4, 0xa188, 0xa735, 0x2104,
+	0x45cd, 0xa085, 0x0001, 0x0078, 0x45d4, 0xa188, 0xa835, 0x2104,
 	0xa065, 0x0040, 0x45c9, 0xa006, 0x017f, 0x007c, 0x0d7e, 0x157e,
 	0x137e, 0x147e, 0x600b, 0x0000, 0x600f, 0x0000, 0x6000, 0xc08c,
-	0x6002, 0x2069, 0xab8e, 0x6808, 0x605e, 0x6810, 0x6062, 0x6138,
-	0xa10a, 0x0048, 0x45ec, 0x603a, 0x6814, 0x6066, 0x2099, 0xab96,
-	0xac88, 0x000a, 0x21a0, 0x20a9, 0x0004, 0x53a3, 0x2099, 0xab9a,
-	0xac88, 0x0006, 0x21a0, 0x20a9, 0x0004, 0x53a3, 0x2069, 0xabae,
+	0x6002, 0x2069, 0xac8e, 0x6808, 0x605e, 0x6810, 0x6062, 0x6138,
+	0xa10a, 0x0048, 0x45ec, 0x603a, 0x6814, 0x6066, 0x2099, 0xac96,
+	0xac88, 0x000a, 0x21a0, 0x20a9, 0x0004, 0x53a3, 0x2099, 0xac9a,
+	0xac88, 0x0006, 0x21a0, 0x20a9, 0x0004, 0x53a3, 0x2069, 0xacae,
 	0x6808, 0x606a, 0x690c, 0x616e, 0x6810, 0x6072, 0x6818, 0x6076,
-	0x60a0, 0xa086, 0x007e, 0x00c0, 0x4611, 0x2069, 0xab8e, 0x690c,
+	0x60a0, 0xa086, 0x007e, 0x00c0, 0x4611, 0x2069, 0xac8e, 0x690c,
 	0x616e, 0xa182, 0x0211, 0x00c8, 0x4619, 0x2009, 0x0008, 0x0078,
 	0x4643, 0xa182, 0x0259, 0x00c8, 0x4621, 0x2009, 0x0007, 0x0078,
 	0x4643, 0xa182, 0x02c1, 0x00c8, 0x4629, 0x2009, 0x0006, 0x0078,
@@ -1787,9 +1787,9 @@ unsigned short risc_code01[] = { 
 	0x4643, 0xa182, 0x0421, 0x00c8, 0x4639, 0x2009, 0x0004, 0x0078,
 	0x4643, 0xa182, 0x0581, 0x00c8, 0x4641, 0x2009, 0x0003, 0x0078,
 	0x4643, 0x2009, 0x0002, 0x6192, 0x147f, 0x137f, 0x157f, 0x0d7f,
-	0x007c, 0x017e, 0x027e, 0x0e7e, 0x2071, 0xab8d, 0x2e04, 0x6896,
-	0x2071, 0xab8e, 0x7004, 0x689a, 0x701c, 0x689e, 0x6a00, 0x2009,
-	0xa672, 0x210c, 0xd0bc, 0x0040, 0x4663, 0xd1ec, 0x0040, 0x4663,
+	0x007c, 0x017e, 0x027e, 0x0e7e, 0x2071, 0xac8d, 0x2e04, 0x6896,
+	0x2071, 0xac8e, 0x7004, 0x689a, 0x701c, 0x689e, 0x6a00, 0x2009,
+	0xa772, 0x210c, 0xd0bc, 0x0040, 0x4663, 0xd1ec, 0x0040, 0x4663,
 	0xc2ad, 0x0078, 0x4664, 0xc2ac, 0xd0c4, 0x0040, 0x466d, 0xd1e4,
 	0x0040, 0x466d, 0xc2bd, 0x0078, 0x466e, 0xc2bc, 0x6a02, 0x0e7f,
 	0x027f, 0x017f, 0x007c, 0x0d7e, 0x127e, 0x2091, 0x8000, 0x60a4,
@@ -1832,17 +1832,17 @@ unsigned short risc_code01[] = { 
 	0x6282, 0x0078, 0x479e, 0xa180, 0x0000, 0x2202, 0x82ff, 0x00c0,
 	0x47a3, 0x6186, 0x8dff, 0x007c, 0xa016, 0x1078, 0x4810, 0x00c0,
 	0x47ab, 0x2011, 0x0001, 0x1078, 0x4863, 0x00c0, 0x47b1, 0xa295,
-	0x0002, 0x007c, 0x1078, 0x489b, 0x0040, 0x47ba, 0x1078, 0x8dca,
+	0x0002, 0x007c, 0x1078, 0x489b, 0x0040, 0x47ba, 0x1078, 0x8dda,
 	0x0078, 0x47bc, 0xa085, 0x0001, 0x007c, 0x1078, 0x489b, 0x0040,
-	0x47c5, 0x1078, 0x8d62, 0x0078, 0x47c7, 0xa085, 0x0001, 0x007c,
-	0x1078, 0x489b, 0x0040, 0x47d0, 0x1078, 0x8dac, 0x0078, 0x47d2,
+	0x47c5, 0x1078, 0x8d72, 0x0078, 0x47c7, 0xa085, 0x0001, 0x007c,
+	0x1078, 0x489b, 0x0040, 0x47d0, 0x1078, 0x8dbc, 0x0078, 0x47d2,
 	0xa085, 0x0001, 0x007c, 0x1078, 0x489b, 0x0040, 0x47db, 0x1078,
-	0x8d7e, 0x0078, 0x47dd, 0xa085, 0x0001, 0x007c, 0x1078, 0x489b,
-	0x0040, 0x47e6, 0x1078, 0x8de8, 0x0078, 0x47e8, 0xa085, 0x0001,
+	0x8d8e, 0x0078, 0x47dd, 0xa085, 0x0001, 0x007c, 0x1078, 0x489b,
+	0x0040, 0x47e6, 0x1078, 0x8df8, 0x0078, 0x47e8, 0xa085, 0x0001,
 	0x007c, 0x127e, 0x007e, 0x0d7e, 0x2091, 0x8000, 0x6080, 0xa06d,
 	0x0040, 0x4808, 0x6800, 0x007e, 0x6837, 0x0103, 0x6b4a, 0x6847,
-	0x0000, 0x1078, 0x8f7d, 0x007e, 0x6000, 0xd0fc, 0x0040, 0x4802,
-	0x1078, 0xa4ed, 0x007f, 0x1078, 0x4a73, 0x007f, 0x0078, 0x47ef,
+	0x0000, 0x1078, 0x8f8d, 0x007e, 0x6000, 0xd0fc, 0x0040, 0x4802,
+	0x1078, 0xa4fd, 0x007f, 0x1078, 0x4a73, 0x007f, 0x0078, 0x47ef,
 	0x6083, 0x0000, 0x6087, 0x0000, 0x0d7f, 0x007f, 0x127f, 0x007c,
 	0x60a4, 0xa00d, 0x00c0, 0x4817, 0xa085, 0x0001, 0x007c, 0x0e7e,
 	0x2170, 0x7000, 0xa005, 0x00c0, 0x482c, 0x20a9, 0x0010, 0xae88,
@@ -1863,77 +1863,77 @@ unsigned short risc_code01[] = { 
 	0x8001, 0x6856, 0x0078, 0x4898, 0x1078, 0x13a4, 0x60ab, 0x0000,
 	0x0d7f, 0x127f, 0x007c, 0x609c, 0xd0a4, 0x007c, 0x0f7e, 0x71b0,
 	0x81ff, 0x00c0, 0x48b9, 0x71cc, 0xd19c, 0x0040, 0x48b9, 0x2001,
-	0x007e, 0xa080, 0xa735, 0x2004, 0xa07d, 0x0040, 0x48b9, 0x7804,
+	0x007e, 0xa080, 0xa835, 0x2004, 0xa07d, 0x0040, 0x48b9, 0x7804,
 	0xa084, 0x00ff, 0xa086, 0x0006, 0x00c0, 0x48b9, 0x7800, 0xc0ed,
-	0x7802, 0x2079, 0xa652, 0x7804, 0xd0a4, 0x0040, 0x48df, 0x157e,
+	0x7802, 0x2079, 0xa752, 0x7804, 0xd0a4, 0x0040, 0x48df, 0x157e,
 	0x0c7e, 0x20a9, 0x007f, 0x2009, 0x0000, 0x017e, 0x1078, 0x45c4,
 	0x00c0, 0x48d9, 0x6004, 0xa084, 0xff00, 0x8007, 0xa096, 0x0004,
 	0x0040, 0x48d6, 0xa086, 0x0006, 0x00c0, 0x48d9, 0x6000, 0xc0ed,
 	0x6002, 0x017f, 0x8108, 0x00f0, 0x48c5, 0x0c7f, 0x157f, 0x1078,
-	0x4967, 0x0040, 0x48e8, 0x2001, 0xa8a1, 0x200c, 0x0078, 0x48f0,
-	0x2079, 0xa652, 0x7804, 0xd0a4, 0x0040, 0x48f4, 0x2009, 0x07d0,
+	0x4967, 0x0040, 0x48e8, 0x2001, 0xa9a1, 0x200c, 0x0078, 0x48f0,
+	0x2079, 0xa752, 0x7804, 0xd0a4, 0x0040, 0x48f4, 0x2009, 0x07d0,
 	0x2011, 0x48f6, 0x1078, 0x5add, 0x0f7f, 0x007c, 0x2011, 0x48f6,
-	0x1078, 0x5a45, 0x1078, 0x4967, 0x0040, 0x491e, 0x2001, 0xa7b3,
-	0x2004, 0xa080, 0x0000, 0x200c, 0xc1ec, 0x2102, 0x2001, 0xa653,
+	0x1078, 0x5a45, 0x1078, 0x4967, 0x0040, 0x491e, 0x2001, 0xa8b3,
+	0x2004, 0xa080, 0x0000, 0x200c, 0xc1ec, 0x2102, 0x2001, 0xa753,
 	0x2004, 0xd0a4, 0x0040, 0x4912, 0x2009, 0x07d0, 0x2011, 0x48f6,
-	0x1078, 0x5add, 0x0e7e, 0x2071, 0xa600, 0x706f, 0x0000, 0x7073,
+	0x1078, 0x5add, 0x0e7e, 0x2071, 0xa700, 0x706f, 0x0000, 0x7073,
 	0x0000, 0x1078, 0x2677, 0x0e7f, 0x0078, 0x4956, 0x157e, 0x0c7e,
 	0x20a9, 0x007f, 0x2009, 0x0000, 0x017e, 0x1078, 0x45c4, 0x00c0,
 	0x4950, 0x6000, 0xd0ec, 0x0040, 0x4950, 0x047e, 0x62a0, 0xa294,
-	0x00ff, 0x8227, 0xa006, 0x2009, 0x0029, 0x1078, 0xa21d, 0x6000,
+	0x00ff, 0x8227, 0xa006, 0x2009, 0x0029, 0x1078, 0xa22d, 0x6000,
 	0xc0e5, 0xc0ec, 0x6002, 0x6004, 0xa084, 0x00ff, 0xa085, 0x0700,
 	0x6006, 0x2019, 0x0029, 0x1078, 0x5f01, 0x077e, 0x2039, 0x0000,
-	0x1078, 0x5e0a, 0x2009, 0x0000, 0x1078, 0x9f8b, 0x077f, 0x047f,
+	0x1078, 0x5e0a, 0x2009, 0x0000, 0x1078, 0x9f9b, 0x077f, 0x047f,
 	0x017f, 0x8108, 0x00f0, 0x4924, 0x0c7f, 0x157f, 0x007c, 0x0c7e,
 	0x6018, 0x2060, 0x6000, 0xc0ec, 0x6002, 0x0c7f, 0x007c, 0x7818,
 	0x2004, 0xd0ac, 0x007c, 0x7818, 0x2004, 0xd0bc, 0x007c, 0x0f7e,
-	0x2001, 0xa7b3, 0x2004, 0xa07d, 0x0040, 0x4970, 0x7800, 0xd0ec,
+	0x2001, 0xa8b3, 0x2004, 0xa07d, 0x0040, 0x4970, 0x7800, 0xd0ec,
 	0x0f7f, 0x007c, 0x127e, 0x027e, 0x2091, 0x8000, 0x007e, 0x62a0,
-	0xa290, 0xa735, 0x2204, 0xac06, 0x10c0, 0x1332, 0x007f, 0x6200,
+	0xa290, 0xa835, 0x2204, 0xac06, 0x10c0, 0x1332, 0x007f, 0x6200,
 	0xa005, 0x0040, 0x4986, 0xc2fd, 0x0078, 0x4987, 0xc2fc, 0x6202,
-	0x027f, 0x127f, 0x007c, 0x2011, 0xa633, 0x2204, 0xd0cc, 0x0040,
-	0x4998, 0x2001, 0xa89f, 0x200c, 0x2011, 0x4999, 0x1078, 0x5add,
-	0x007c, 0x2011, 0x4999, 0x1078, 0x5a45, 0x2011, 0xa633, 0x2204,
-	0xc0cc, 0x2012, 0x007c, 0x2071, 0xa714, 0x7003, 0x0001, 0x7007,
+	0x027f, 0x127f, 0x007c, 0x2011, 0xa733, 0x2204, 0xd0cc, 0x0040,
+	0x4998, 0x2001, 0xa99f, 0x200c, 0x2011, 0x4999, 0x1078, 0x5add,
+	0x007c, 0x2011, 0x4999, 0x1078, 0x5a45, 0x2011, 0xa733, 0x2204,
+	0xc0cc, 0x2012, 0x007c, 0x2071, 0xa814, 0x7003, 0x0001, 0x7007,
 	0x0000, 0x7013, 0x0000, 0x7017, 0x0000, 0x701b, 0x0000, 0x701f,
 	0x0000, 0x700b, 0x0000, 0x704b, 0x0001, 0x704f, 0x0000, 0x705b,
-	0x0020, 0x705f, 0x0040, 0x707f, 0x0000, 0x2071, 0xa87d, 0x7003,
-	0xa714, 0x7007, 0x0000, 0x700b, 0x0000, 0x700f, 0xa85d, 0x7013,
+	0x0020, 0x705f, 0x0040, 0x707f, 0x0000, 0x2071, 0xa97d, 0x7003,
+	0xa814, 0x7007, 0x0000, 0x700b, 0x0000, 0x700f, 0xa95d, 0x7013,
 	0x0020, 0x7017, 0x0040, 0x7037, 0x0000, 0x007c, 0x017e, 0x0e7e,
-	0x2071, 0xa835, 0xa00e, 0x7186, 0x718a, 0x7097, 0x0001, 0x2001,
-	0xa653, 0x2004, 0xd0fc, 0x00c0, 0x49e8, 0x2001, 0xa653, 0x2004,
+	0x2071, 0xa935, 0xa00e, 0x7186, 0x718a, 0x7097, 0x0001, 0x2001,
+	0xa753, 0x2004, 0xd0fc, 0x00c0, 0x49e8, 0x2001, 0xa753, 0x2004,
 	0xa00e, 0xd09c, 0x0040, 0x49e5, 0x8108, 0x7102, 0x0078, 0x4a3b,
-	0x2001, 0xa672, 0x200c, 0xa184, 0x000f, 0x2009, 0xa673, 0x210c,
+	0x2001, 0xa772, 0x200c, 0xa184, 0x000f, 0x2009, 0xa773, 0x210c,
 	0x0079, 0x49f2, 0x49dd, 0x4a13, 0x4a1b, 0x4a26, 0x4a2c, 0x49dd,
 	0x49dd, 0x49dd, 0x4a02, 0x49dd, 0x49dd, 0x49dd, 0x49dd, 0x49dd,
 	0x49dd, 0x49dd, 0x7003, 0x0004, 0x137e, 0x147e, 0x157e, 0x2099,
-	0xa676, 0x20a1, 0xa886, 0x20a9, 0x0004, 0x53a3, 0x157f, 0x147f,
+	0xa776, 0x20a1, 0xa986, 0x20a9, 0x0004, 0x53a3, 0x157f, 0x147f,
 	0x137f, 0x0078, 0x4a3b, 0x708f, 0x0005, 0x7007, 0x0122, 0x2001,
 	0x0002, 0x0078, 0x4a21, 0x708f, 0x0002, 0x7007, 0x0121, 0x2001,
 	0x0003, 0x7002, 0x7097, 0x0001, 0x0078, 0x4a38, 0x7007, 0x0122,
 	0x2001, 0x0002, 0x0078, 0x4a30, 0x7007, 0x0121, 0x2001, 0x0003,
 	0x7002, 0xa006, 0x7096, 0x708e, 0xa184, 0xff00, 0x8007, 0x709a,
 	0xa184, 0x00ff, 0x7092, 0x0e7f, 0x017f, 0x007c, 0x0e7e, 0x2071,
-	0xa714, 0x684c, 0xa005, 0x00c0, 0x4a4c, 0x7028, 0xc085, 0x702a,
+	0xa814, 0x684c, 0xa005, 0x00c0, 0x4a4c, 0x7028, 0xc085, 0x702a,
 	0xa085, 0x0001, 0x0078, 0x4a71, 0x6a60, 0x7236, 0x6b64, 0x733a,
 	0x6868, 0x703e, 0x7076, 0x686c, 0x7042, 0x707a, 0x684c, 0x702e,
 	0x6844, 0x7032, 0x2009, 0x000d, 0x200a, 0x700b, 0x0000, 0x8007,
 	0x8006, 0x8006, 0xa08c, 0x003f, 0xa084, 0xffc0, 0xa210, 0x2100,
 	0xa319, 0x726e, 0x7372, 0x7028, 0xc084, 0x702a, 0x7007, 0x0001,
 	0xa006, 0x0e7f, 0x007c, 0x0e7e, 0x027e, 0x6838, 0xd0fc, 0x00c0,
-	0x4ac9, 0x6804, 0xa00d, 0x0040, 0x4a8f, 0x0d7e, 0x2071, 0xa600,
+	0x4ac9, 0x6804, 0xa00d, 0x0040, 0x4a8f, 0x0d7e, 0x2071, 0xa700,
 	0xa016, 0x702c, 0x2168, 0x6904, 0x206a, 0x8210, 0x2d00, 0x81ff,
 	0x00c0, 0x4a82, 0x702e, 0x70ac, 0xa200, 0x70ae, 0x0d7f, 0x2071,
-	0xa714, 0x701c, 0xa005, 0x00c0, 0x4adb, 0x0068, 0x4ad9, 0x2071,
-	0xa835, 0x7200, 0x82ff, 0x0040, 0x4ad9, 0x6934, 0xa186, 0x0103,
+	0xa814, 0x701c, 0xa005, 0x00c0, 0x4adb, 0x0068, 0x4ad9, 0x2071,
+	0xa935, 0x7200, 0x82ff, 0x0040, 0x4ad9, 0x6934, 0xa186, 0x0103,
 	0x00c0, 0x4aec, 0x6948, 0x6844, 0xa105, 0x00c0, 0x4acc, 0x2009,
 	0x8020, 0x2200, 0x0079, 0x4aac, 0x4ad9, 0x4ab1, 0x4b09, 0x4b17,
 	0x4ad9, 0x2071, 0x0000, 0x7018, 0xd084, 0x00c0, 0x4ad9, 0x7122,
 	0x683c, 0x7026, 0x6840, 0x702a, 0x701b, 0x0001, 0x2091, 0x4080,
-	0x2071, 0xa600, 0x702c, 0x206a, 0x2d00, 0x702e, 0x70ac, 0x8000,
+	0x2071, 0xa700, 0x702c, 0x206a, 0x2d00, 0x702e, 0x70ac, 0x8000,
 	0x70ae, 0x027f, 0x0e7f, 0x007c, 0x6844, 0xa086, 0x0100, 0x00c0,
 	0x4ad9, 0x6868, 0xa005, 0x00c0, 0x4ad9, 0x2009, 0x8020, 0x0078,
-	0x4aa9, 0x2071, 0xa714, 0x2d08, 0x206b, 0x0000, 0x7010, 0x8000,
+	0x4aa9, 0x2071, 0xa814, 0x2d08, 0x206b, 0x0000, 0x7010, 0x8000,
 	0x7012, 0x7018, 0xa06d, 0x711a, 0x0040, 0x4ae9, 0x6902, 0x0078,
 	0x4aea, 0x711e, 0x0078, 0x4ac9, 0xa18c, 0x00ff, 0xa186, 0x0017,
 	0x0040, 0x4afa, 0xa186, 0x001e, 0x0040, 0x4afa, 0xa18e, 0x001f,
@@ -1944,95 +1944,95 @@ unsigned short risc_code01[] = { 
 	0x8008, 0xa092, 0x000f, 0x00c8, 0x4ad9, 0x7186, 0xae90, 0x0003,
 	0x8003, 0xa210, 0x683c, 0x2012, 0x8210, 0x6840, 0x2012, 0x7088,
 	0xa10a, 0x0048, 0x4ac0, 0x718c, 0x7084, 0xa10a, 0x0048, 0x4ac0,
-	0x2071, 0x0000, 0x7018, 0xd084, 0x00c0, 0x4ac0, 0x2071, 0xa835,
+	0x2071, 0x0000, 0x7018, 0xd084, 0x00c0, 0x4ac0, 0x2071, 0xa935,
 	0x7000, 0xa086, 0x0002, 0x00c0, 0x4b47, 0x1078, 0x4dc3, 0x2071,
 	0x0000, 0x701b, 0x0001, 0x2091, 0x4080, 0x0078, 0x4ac0, 0x1078,
 	0x4dee, 0x2071, 0x0000, 0x701b, 0x0001, 0x2091, 0x4080, 0x0078,
 	0x4ac0, 0x007e, 0x684c, 0x007e, 0x6837, 0x0103, 0x20a9, 0x001c,
 	0xad80, 0x0011, 0x20a0, 0x2001, 0x0000, 0x40a4, 0x007f, 0xa084,
-	0x00ff, 0x684e, 0x007f, 0x684a, 0x6952, 0x007c, 0x2071, 0xa714,
+	0x00ff, 0x684e, 0x007f, 0x684a, 0x6952, 0x007c, 0x2071, 0xa814,
 	0x7004, 0x0079, 0x4b6b, 0x4b75, 0x4b86, 0x4d94, 0x4d95, 0x4dbc,
 	0x4dc2, 0x4b76, 0x4d82, 0x4d23, 0x4da5, 0x007c, 0x127e, 0x2091,
 	0x8000, 0x0068, 0x4b85, 0x2009, 0x000d, 0x7030, 0x200a, 0x2091,
-	0x4080, 0x7007, 0x0001, 0x700b, 0x0000, 0x127f, 0x2069, 0xa8c4,
+	0x4080, 0x7007, 0x0001, 0x700b, 0x0000, 0x127f, 0x2069, 0xa9c4,
 	0x6844, 0xa005, 0x0050, 0x4bae, 0x00c0, 0x4bae, 0x127e, 0x2091,
-	0x8000, 0x2069, 0x0000, 0x6934, 0x2001, 0xa720, 0x2004, 0xa10a,
+	0x8000, 0x2069, 0x0000, 0x6934, 0x2001, 0xa820, 0x2004, 0xa10a,
 	0x0040, 0x4ba9, 0x0068, 0x4bad, 0x2069, 0x0000, 0x6818, 0xd084,
 	0x00c0, 0x4bad, 0x2009, 0x8040, 0x6922, 0x681b, 0x0001, 0x2091,
-	0x4080, 0x2069, 0xa8c4, 0x6847, 0xffff, 0x127f, 0x2069, 0xa600,
-	0x6848, 0x6964, 0xa102, 0x2069, 0xa835, 0x688a, 0x6984, 0x701c,
+	0x4080, 0x2069, 0xa9c4, 0x6847, 0xffff, 0x127f, 0x2069, 0xa700,
+	0x6848, 0x6964, 0xa102, 0x2069, 0xa935, 0x688a, 0x6984, 0x701c,
 	0xa06d, 0x0040, 0x4bc0, 0x81ff, 0x0040, 0x4c08, 0x0078, 0x4bd6,
-	0x81ff, 0x0040, 0x4cda, 0x2071, 0xa835, 0x7184, 0x7088, 0xa10a,
-	0x00c8, 0x4bd6, 0x7190, 0x2071, 0xa8c4, 0x7040, 0xa005, 0x0040,
-	0x4bd6, 0x00d0, 0x4cda, 0x7142, 0x0078, 0x4cda, 0x2071, 0xa835,
+	0x81ff, 0x0040, 0x4cda, 0x2071, 0xa935, 0x7184, 0x7088, 0xa10a,
+	0x00c8, 0x4bd6, 0x7190, 0x2071, 0xa9c4, 0x7040, 0xa005, 0x0040,
+	0x4bd6, 0x00d0, 0x4cda, 0x7142, 0x0078, 0x4cda, 0x2071, 0xa935,
 	0x718c, 0x127e, 0x2091, 0x8000, 0x7084, 0xa10a, 0x0048, 0x4cf7,
 	0x0068, 0x4c8c, 0x2071, 0x0000, 0x7018, 0xd084, 0x00c0, 0x4c8c,
-	0x2001, 0xffff, 0x2071, 0xa8c4, 0x7042, 0x2071, 0xa835, 0x7000,
+	0x2001, 0xffff, 0x2071, 0xa9c4, 0x7042, 0x2071, 0xa935, 0x7000,
 	0xa086, 0x0002, 0x00c0, 0x4bfe, 0x1078, 0x4dc3, 0x2071, 0x0000,
 	0x701b, 0x0001, 0x2091, 0x4080, 0x0078, 0x4c8c, 0x1078, 0x4dee,
 	0x2071, 0x0000, 0x701b, 0x0001, 0x2091, 0x4080, 0x0078, 0x4c8c,
-	0x2071, 0xa835, 0x7000, 0xa005, 0x0040, 0x4cb9, 0x6934, 0xa186,
+	0x2071, 0xa935, 0x7000, 0xa005, 0x0040, 0x4cb9, 0x6934, 0xa186,
 	0x0103, 0x00c0, 0x4c8f, 0x684c, 0xd0bc, 0x00c0, 0x4cb9, 0x6948,
-	0x6844, 0xa105, 0x00c0, 0x4cac, 0x2009, 0x8020, 0x2071, 0xa835,
+	0x6844, 0xa105, 0x00c0, 0x4cac, 0x2009, 0x8020, 0x2071, 0xa935,
 	0x7000, 0x0079, 0x4c23, 0x4cb9, 0x4c71, 0x4c49, 0x4c5b, 0x4c28,
-	0x137e, 0x147e, 0x157e, 0x2099, 0xa676, 0x20a1, 0xa886, 0x20a9,
-	0x0004, 0x53a3, 0x157f, 0x147f, 0x137f, 0x2071, 0xa87d, 0xad80,
+	0x137e, 0x147e, 0x157e, 0x2099, 0xa776, 0x20a1, 0xa986, 0x20a9,
+	0x0004, 0x53a3, 0x157f, 0x147f, 0x137f, 0x2071, 0xa97d, 0xad80,
 	0x000f, 0x700e, 0x7013, 0x0002, 0x7007, 0x0002, 0x700b, 0x0000,
-	0x2e10, 0x1078, 0x13db, 0x2071, 0xa714, 0x7007, 0x0009, 0x0078,
+	0x2e10, 0x1078, 0x13db, 0x2071, 0xa814, 0x7007, 0x0009, 0x0078,
 	0x4cda, 0x7084, 0x8008, 0xa092, 0x001e, 0x00c8, 0x4cda, 0xae90,
-	0x0003, 0xa210, 0x683c, 0x2012, 0x7186, 0x2071, 0xa714, 0x1078,
+	0x0003, 0xa210, 0x683c, 0x2012, 0x7186, 0x2071, 0xa814, 0x1078,
 	0x4e4c, 0x0078, 0x4cda, 0x7084, 0x8008, 0xa092, 0x000f, 0x00c8,
 	0x4cda, 0xae90, 0x0003, 0x8003, 0xa210, 0x683c, 0x2012, 0x8210,
-	0x6840, 0x2012, 0x7186, 0x2071, 0xa714, 0x1078, 0x4e4c, 0x0078,
+	0x6840, 0x2012, 0x7186, 0x2071, 0xa814, 0x1078, 0x4e4c, 0x0078,
 	0x4cda, 0x127e, 0x2091, 0x8000, 0x0068, 0x4c8c, 0x2071, 0x0000,
 	0x7018, 0xd084, 0x00c0, 0x4c8c, 0x7122, 0x683c, 0x7026, 0x6840,
-	0x702a, 0x701b, 0x0001, 0x2091, 0x4080, 0x127f, 0x2071, 0xa714,
+	0x702a, 0x701b, 0x0001, 0x2091, 0x4080, 0x127f, 0x2071, 0xa814,
 	0x1078, 0x4e4c, 0x0078, 0x4cda, 0x127f, 0x0078, 0x4cda, 0xa18c,
 	0x00ff, 0xa186, 0x0017, 0x0040, 0x4c9d, 0xa186, 0x001e, 0x0040,
 	0x4c9d, 0xa18e, 0x001f, 0x00c0, 0x4cb9, 0x684c, 0xd0cc, 0x0040,
 	0x4cb9, 0x6850, 0xa084, 0x00ff, 0xa086, 0x0001, 0x00c0, 0x4cb9,
 	0x2009, 0x8021, 0x0078, 0x4c1e, 0x6844, 0xa086, 0x0100, 0x00c0,
 	0x4cb9, 0x6868, 0xa005, 0x00c0, 0x4cb9, 0x2009, 0x8020, 0x0078,
-	0x4c1e, 0x2071, 0xa714, 0x1078, 0x4e60, 0x0040, 0x4cda, 0x2071,
-	0xa714, 0x700f, 0x0001, 0x6934, 0xa184, 0x00ff, 0xa086, 0x0003,
+	0x4c1e, 0x2071, 0xa814, 0x1078, 0x4e60, 0x0040, 0x4cda, 0x2071,
+	0xa814, 0x700f, 0x0001, 0x6934, 0xa184, 0x00ff, 0xa086, 0x0003,
 	0x00c0, 0x4cd1, 0x810f, 0xa18c, 0x00ff, 0x8101, 0x0040, 0x4cd1,
 	0x710e, 0x7007, 0x0003, 0x1078, 0x4e80, 0x7050, 0xa086, 0x0100,
-	0x0040, 0x4d95, 0x127e, 0x2091, 0x8000, 0x2071, 0xa714, 0x7008,
+	0x0040, 0x4d95, 0x127e, 0x2091, 0x8000, 0x2071, 0xa814, 0x7008,
 	0xa086, 0x0001, 0x00c0, 0x4cf5, 0x0068, 0x4cf5, 0x2009, 0x000d,
 	0x7030, 0x200a, 0x2091, 0x4080, 0x700b, 0x0000, 0x7004, 0xa086,
 	0x0006, 0x00c0, 0x4cf5, 0x7007, 0x0001, 0x127f, 0x007c, 0x2071,
-	0xa714, 0x1078, 0x4e60, 0x0040, 0x4d20, 0x2071, 0xa835, 0x7084,
-	0x700a, 0x20a9, 0x0020, 0x2099, 0xa836, 0x20a1, 0xa85d, 0x53a3,
-	0x7087, 0x0000, 0x2071, 0xa714, 0x2069, 0xa87d, 0x706c, 0x6826,
+	0xa814, 0x1078, 0x4e60, 0x0040, 0x4d20, 0x2071, 0xa935, 0x7084,
+	0x700a, 0x20a9, 0x0020, 0x2099, 0xa936, 0x20a1, 0xa95d, 0x53a3,
+	0x7087, 0x0000, 0x2071, 0xa814, 0x2069, 0xa97d, 0x706c, 0x6826,
 	0x7070, 0x682a, 0x7074, 0x682e, 0x7078, 0x6832, 0x2d10, 0x1078,
-	0x13db, 0x7007, 0x0008, 0x2001, 0xffff, 0x2071, 0xa8c4, 0x7042,
-	0x127f, 0x0078, 0x4cda, 0x2069, 0xa87d, 0x6808, 0xa08e, 0x0000,
+	0x13db, 0x7007, 0x0008, 0x2001, 0xffff, 0x2071, 0xa9c4, 0x7042,
+	0x127f, 0x0078, 0x4cda, 0x2069, 0xa97d, 0x6808, 0xa08e, 0x0000,
 	0x0040, 0x4d81, 0xa08e, 0x0200, 0x0040, 0x4d7f, 0xa08e, 0x0100,
 	0x00c0, 0x4d81, 0x127e, 0x2091, 0x8000, 0x0068, 0x4d7c, 0x2069,
 	0x0000, 0x6818, 0xd084, 0x00c0, 0x4d7c, 0x702c, 0x7130, 0x8108,
 	0xa102, 0x0048, 0x4d4a, 0xa00e, 0x7034, 0x706e, 0x7038, 0x7072,
 	0x0078, 0x4d54, 0x706c, 0xa080, 0x0040, 0x706e, 0x00c8, 0x4d54,
 	0x7070, 0xa081, 0x0000, 0x7072, 0x7132, 0x6936, 0x700b, 0x0000,
-	0x2001, 0xa85a, 0x2004, 0xa005, 0x00c0, 0x4d73, 0x6934, 0x2069,
-	0xa835, 0x689c, 0x699e, 0x2069, 0xa8c4, 0xa102, 0x00c0, 0x4d6c,
-	0x6844, 0xa005, 0x00d0, 0x4d7a, 0x2001, 0xa85b, 0x200c, 0x810d,
+	0x2001, 0xa95a, 0x2004, 0xa005, 0x00c0, 0x4d73, 0x6934, 0x2069,
+	0xa935, 0x689c, 0x699e, 0x2069, 0xa9c4, 0xa102, 0x00c0, 0x4d6c,
+	0x6844, 0xa005, 0x00d0, 0x4d7a, 0x2001, 0xa95b, 0x200c, 0x810d,
 	0x6946, 0x0078, 0x4d7a, 0x2009, 0x8040, 0x6922, 0x681b, 0x0001,
 	0x2091, 0x4080, 0x7007, 0x0001, 0x127f, 0x0078, 0x4d81, 0x7007,
 	0x0005, 0x007c, 0x701c, 0xa06d, 0x0040, 0x4d93, 0x1078, 0x4e60,
 	0x0040, 0x4d93, 0x7007, 0x0003, 0x1078, 0x4e80, 0x7050, 0xa086,
 	0x0100, 0x0040, 0x4d95, 0x007c, 0x007c, 0x7050, 0xa09e, 0x0100,
 	0x00c0, 0x4d9e, 0x7007, 0x0004, 0x0078, 0x4dbc, 0xa086, 0x0200,
-	0x00c0, 0x4da4, 0x7007, 0x0005, 0x007c, 0x2001, 0xa87f, 0x2004,
+	0x00c0, 0x4da4, 0x7007, 0x0005, 0x007c, 0x2001, 0xa97f, 0x2004,
 	0xa08e, 0x0100, 0x00c0, 0x4db1, 0x7007, 0x0001, 0x1078, 0x4e4c,
 	0x007c, 0xa08e, 0x0000, 0x0040, 0x4db0, 0xa08e, 0x0200, 0x00c0,
 	0x4db0, 0x7007, 0x0005, 0x007c, 0x1078, 0x4e16, 0x7006, 0x1078,
-	0x4e4c, 0x007c, 0x007c, 0x0e7e, 0x157e, 0x2071, 0xa835, 0x7184,
+	0x4e4c, 0x007c, 0x007c, 0x0e7e, 0x157e, 0x2071, 0xa935, 0x7184,
 	0x81ff, 0x0040, 0x4deb, 0xa006, 0x7086, 0xae80, 0x0003, 0x2071,
 	0x0000, 0x21a8, 0x2014, 0x7226, 0x8000, 0x0070, 0x4de8, 0x2014,
 	0x722a, 0x8000, 0x0070, 0x4de8, 0x2014, 0x722e, 0x8000, 0x0070,
 	0x4de8, 0x2014, 0x723a, 0x8000, 0x0070, 0x4de8, 0x2014, 0x723e,
 	0xa180, 0x8030, 0x7022, 0x157f, 0x0e7f, 0x007c, 0x0e7e, 0x157e,
-	0x2071, 0xa835, 0x7184, 0x81ff, 0x0040, 0x4e13, 0xa006, 0x7086,
+	0x2071, 0xa935, 0x7184, 0x81ff, 0x0040, 0x4e13, 0xa006, 0x7086,
 	0xae80, 0x0003, 0x2071, 0x0000, 0x21a8, 0x2014, 0x7226, 0x8000,
 	0x2014, 0x722a, 0x8000, 0x0070, 0x4e0c, 0x2014, 0x723a, 0x8000,
 	0x2014, 0x723e, 0x0078, 0x4e10, 0x2001, 0x8020, 0x0078, 0x4e12,
@@ -2051,18 +2051,18 @@ unsigned short risc_code01[] = { 
 	0x8319, 0x7130, 0xa102, 0x00c0, 0x4e79, 0x2300, 0xa005, 0x0078,
 	0x4e7f, 0x0048, 0x4e7e, 0xa302, 0x0078, 0x4e7f, 0x8002, 0x007c,
 	0x2d00, 0x7026, 0xa080, 0x000d, 0x7056, 0x7053, 0x0000, 0x127e,
-	0x2091, 0x8000, 0x2009, 0xa8d6, 0x2104, 0xc08d, 0x200a, 0x127f,
-	0x1078, 0x13f9, 0x007c, 0x2071, 0xa6e2, 0x7003, 0x0000, 0x7007,
+	0x2091, 0x8000, 0x2009, 0xa9d6, 0x2104, 0xc08d, 0x200a, 0x127f,
+	0x1078, 0x13f9, 0x007c, 0x2071, 0xa7e2, 0x7003, 0x0000, 0x7007,
 	0x0000, 0x700f, 0x0000, 0x702b, 0x0001, 0x704f, 0x0000, 0x7053,
 	0x0001, 0x705f, 0x0020, 0x7063, 0x0040, 0x7083, 0x0000, 0x708b,
 	0x0000, 0x708f, 0x0001, 0x70bf, 0x0000, 0x007c, 0x0e7e, 0x2071,
-	0xa6e2, 0x6848, 0xa005, 0x00c0, 0x4ebc, 0x7028, 0xc085, 0x702a,
+	0xa7e2, 0x6848, 0xa005, 0x00c0, 0x4ebc, 0x7028, 0xc085, 0x702a,
 	0xa085, 0x0001, 0x0078, 0x4ee1, 0x6a50, 0x7236, 0x6b54, 0x733a,
 	0x6858, 0x703e, 0x707a, 0x685c, 0x7042, 0x707e, 0x6848, 0x702e,
 	0x6840, 0x7032, 0x2009, 0x000c, 0x200a, 0x8007, 0x8006, 0x8006,
 	0xa08c, 0x003f, 0xa084, 0xffc0, 0xa210, 0x2100, 0xa319, 0x7272,
 	0x7376, 0x7028, 0xc084, 0x702a, 0x7007, 0x0001, 0x700f, 0x0000,
-	0xa006, 0x0e7f, 0x007c, 0x2b78, 0x2071, 0xa6e2, 0x7004, 0x1079,
+	0xa006, 0x0e7f, 0x007c, 0x2b78, 0x2071, 0xa7e2, 0x7004, 0x1079,
 	0x4f41, 0x700c, 0x0079, 0x4eec, 0x4ef1, 0x4ee6, 0x4ee6, 0x4ee6,
 	0x4ee6, 0x007c, 0x700c, 0x0079, 0x4ef5, 0x4efa, 0x4f3f, 0x4f3f,
 	0x4f40, 0x4f40, 0x7830, 0x7930, 0xa106, 0x0040, 0x4f04, 0x7830,
@@ -2070,7 +2070,7 @@ unsigned short risc_code01[] = { 
 	0x00c8, 0x4f0c, 0x712c, 0xa10a, 0xa18a, 0x0002, 0x00c8, 0x4f2b,
 	0x1078, 0x1370, 0x0040, 0x4f2a, 0x2d00, 0x705a, 0x7063, 0x0040,
 	0x2001, 0x0003, 0x7057, 0x0000, 0x127e, 0x007e, 0x2091, 0x8000,
-	0x2009, 0xa8d6, 0x2104, 0xc085, 0x200a, 0x007f, 0x700e, 0x127f,
+	0x2009, 0xa9d6, 0x2104, 0xc085, 0x200a, 0x007f, 0x700e, 0x127f,
 	0x1078, 0x13f9, 0x007c, 0x1078, 0x1370, 0x0040, 0x4f2a, 0x2d00,
 	0x705a, 0x1078, 0x1370, 0x00c0, 0x4f37, 0x0078, 0x4f16, 0x2d00,
 	0x7086, 0x7063, 0x0080, 0x2001, 0x0004, 0x0078, 0x4f1a, 0x007c,
@@ -2083,7 +2083,7 @@ unsigned short risc_code01[] = { 
 	0x700e, 0x1078, 0x5464, 0x7058, 0x2068, 0x7084, 0x705a, 0x6803,
 	0x0000, 0x6807, 0x0000, 0x6834, 0xa084, 0x00ff, 0xa08a, 0x0020,
 	0x00c8, 0x4f86, 0x1079, 0x4fa1, 0x127f, 0x007c, 0x127f, 0x1078,
-	0x501f, 0x007c, 0x007c, 0x007c, 0x0e7e, 0x2071, 0xa6e2, 0x700c,
+	0x501f, 0x007c, 0x007c, 0x007c, 0x0e7e, 0x2071, 0xa7e2, 0x700c,
 	0x0079, 0x4f92, 0x4f97, 0x4f97, 0x4f97, 0x4f99, 0x4f9d, 0x0e7f,
 	0x007c, 0x700f, 0x0001, 0x0078, 0x4f9f, 0x700f, 0x0002, 0x0e7f,
 	0x007c, 0x501f, 0x501f, 0x503b, 0x501f, 0x5171, 0x501f, 0x501f,
@@ -2114,7 +2114,7 @@ unsigned short risc_code01[] = { 
 	0x7016, 0x701a, 0x704b, 0x513a, 0x007c, 0x684c, 0xa084, 0x00c0,
 	0xa086, 0x00c0, 0x00c0, 0x5078, 0x7007, 0x0001, 0x0078, 0x5373,
 	0x2d00, 0x7016, 0x701a, 0x20a9, 0x0004, 0xa080, 0x0024, 0x2098,
-	0x20a1, 0xa70d, 0x53a3, 0x6858, 0x7012, 0xa082, 0x0401, 0x00c8,
+	0x20a1, 0xa80d, 0x53a3, 0x6858, 0x7012, 0xa082, 0x0401, 0x00c8,
 	0x5049, 0x6884, 0xa08a, 0x0002, 0x00c8, 0x5049, 0x82ff, 0x00c0,
 	0x509a, 0x6888, 0x698c, 0xa105, 0x0040, 0x509a, 0x2001, 0x510a,
 	0x0078, 0x509d, 0xa280, 0x5100, 0x2004, 0x70c6, 0x7010, 0xa015,
@@ -2137,9 +2137,9 @@ unsigned short risc_code01[] = { 
 	0x7812, 0x7004, 0x7806, 0x7000, 0x7802, 0x7e0e, 0x7f0a, 0x8109,
 	0x0040, 0x5130, 0xaef2, 0x0004, 0xaffa, 0x0006, 0x0078, 0x511d,
 	0x6004, 0xa065, 0x00c0, 0x5117, 0x067f, 0x077f, 0x0c7f, 0x0e7f,
-	0x0f7f, 0x007c, 0x2009, 0xa62f, 0x210c, 0x81ff, 0x00c0, 0x5155,
+	0x0f7f, 0x007c, 0x2009, 0xa72f, 0x210c, 0x81ff, 0x00c0, 0x5155,
 	0x6838, 0xa084, 0x00ff, 0x683a, 0x1078, 0x4353, 0x00c0, 0x5149,
-	0x007c, 0x1078, 0x4b51, 0x127e, 0x2091, 0x8000, 0x1078, 0x8f7d,
+	0x007c, 0x1078, 0x4b51, 0x127e, 0x2091, 0x8000, 0x1078, 0x8f8d,
 	0x1078, 0x4a73, 0x127f, 0x0078, 0x5148, 0x2001, 0x0028, 0x2009,
 	0x0000, 0x0078, 0x5149, 0x7018, 0x6802, 0x2d08, 0x2068, 0x6906,
 	0x711a, 0x7010, 0x8001, 0x7012, 0x0040, 0x516a, 0x7007, 0x0006,
@@ -2149,12 +2149,12 @@ unsigned short risc_code01[] = { 
 	0x2009, 0x0000, 0x20a9, 0x00ff, 0xa096, 0x0002, 0x0040, 0x519a,
 	0xa005, 0x00c0, 0x51ad, 0x6944, 0x810f, 0xa18c, 0x00ff, 0x1078,
 	0x45c4, 0x00c0, 0x51ad, 0x067e, 0x6e50, 0x1078, 0x46b3, 0x067f,
-	0x0078, 0x51ad, 0x047e, 0x2011, 0xa60c, 0x2224, 0xc484, 0xc48c,
+	0x0078, 0x51ad, 0x047e, 0x2011, 0xa70c, 0x2224, 0xc484, 0xc48c,
 	0x2412, 0x047f, 0x0c7e, 0x1078, 0x45c4, 0x00c0, 0x51a9, 0x1078,
 	0x4852, 0x8108, 0x00f0, 0x51a3, 0x0c7f, 0x684c, 0xd084, 0x00c0,
 	0x51b4, 0x1078, 0x13a4, 0x007c, 0x127e, 0x2091, 0x8000, 0x1078,
 	0x4a73, 0x127f, 0x007c, 0x127e, 0x2091, 0x8000, 0x7007, 0x0001,
-	0x2001, 0xa653, 0x2004, 0xd0a4, 0x0040, 0x51ff, 0x2061, 0xa933,
+	0x2001, 0xa753, 0x2004, 0xd0a4, 0x0040, 0x51ff, 0x2061, 0xaa33,
 	0x6100, 0xd184, 0x0040, 0x51df, 0x6858, 0xa084, 0x00ff, 0x00c0,
 	0x5202, 0x6000, 0xd084, 0x0040, 0x51ff, 0x6004, 0xa005, 0x00c0,
 	0x5205, 0x6003, 0x0000, 0x600b, 0x0000, 0x0078, 0x51fc, 0x2011,
@@ -2163,8 +2163,8 @@ unsigned short risc_code01[] = { 
 	0x8007, 0xa084, 0x00ff, 0x0040, 0x51ff, 0x600a, 0x6858, 0x8000,
 	0x00c0, 0x51fb, 0xc28d, 0x6202, 0x127f, 0x0078, 0x5453, 0x127f,
 	0x0078, 0x544b, 0x127f, 0x0078, 0x5443, 0x127f, 0x0078, 0x5447,
-	0x127e, 0x2091, 0x8000, 0x7007, 0x0001, 0x2001, 0xa653, 0x2004,
-	0xd0a4, 0x0040, 0x525e, 0x2061, 0xa933, 0x6000, 0xd084, 0x0040,
+	0x127e, 0x2091, 0x8000, 0x7007, 0x0001, 0x2001, 0xa753, 0x2004,
+	0xd0a4, 0x0040, 0x525e, 0x2061, 0xaa33, 0x6000, 0xd084, 0x0040,
 	0x525e, 0x6204, 0x6308, 0xd08c, 0x00c0, 0x5250, 0x6c48, 0xa484,
 	0x0003, 0x0040, 0x5236, 0x6958, 0xa18c, 0x00ff, 0x8001, 0x00c0,
 	0x522f, 0x2100, 0xa210, 0x0048, 0x525b, 0x0078, 0x5236, 0x8001,
@@ -2174,34 +2174,34 @@ unsigned short risc_code01[] = { 
 	0xa082, 0x0004, 0x00c0, 0x525b, 0x2100, 0xa31a, 0x0048, 0x525b,
 	0x6860, 0xa005, 0x0040, 0x5256, 0x8000, 0x6016, 0x6206, 0x630a,
 	0x127f, 0x0078, 0x5453, 0x127f, 0x0078, 0x544f, 0x127f, 0x0078,
-	0x544b, 0x127e, 0x2091, 0x8000, 0x7007, 0x0001, 0x2061, 0xa933,
+	0x544b, 0x127e, 0x2091, 0x8000, 0x7007, 0x0001, 0x2061, 0xaa33,
 	0x6300, 0xd38c, 0x00c0, 0x5271, 0x6308, 0x8318, 0x0048, 0x5274,
 	0x630a, 0x127f, 0x0078, 0x5461, 0x127f, 0x0078, 0x544f, 0x127e,
 	0x0c7e, 0x2091, 0x8000, 0x7007, 0x0001, 0x684c, 0xd0ac, 0x0040,
-	0x528b, 0x0c7e, 0x2061, 0xa933, 0x6000, 0xa084, 0xfcff, 0x6002,
+	0x528b, 0x0c7e, 0x2061, 0xaa33, 0x6000, 0xa084, 0xfcff, 0x6002,
 	0x0c7f, 0x0078, 0x52ba, 0x6858, 0xa005, 0x0040, 0x52d1, 0x685c,
-	0xa065, 0x0040, 0x52cd, 0x2001, 0xa62f, 0x2004, 0xa005, 0x0040,
-	0x529d, 0x1078, 0x8ec6, 0x0078, 0x52ab, 0x6013, 0x0400, 0x6037,
+	0xa065, 0x0040, 0x52cd, 0x2001, 0xa72f, 0x2004, 0xa005, 0x0040,
+	0x529d, 0x1078, 0x8ed6, 0x0078, 0x52ab, 0x6013, 0x0400, 0x6037,
 	0x0000, 0x694c, 0xd1a4, 0x0040, 0x52a7, 0x6950, 0x6136, 0x2009,
 	0x0041, 0x1078, 0x775c, 0x6958, 0xa18c, 0xff00, 0xa186, 0x2000,
 	0x00c0, 0x52ba, 0x027e, 0x2009, 0x0000, 0x2011, 0xfdff, 0x1078,
-	0x5bf1, 0x027f, 0x684c, 0xd0c4, 0x0040, 0x52c9, 0x2061, 0xa933,
+	0x5bf1, 0x027f, 0x684c, 0xd0c4, 0x0040, 0x52c9, 0x2061, 0xaa33,
 	0x6000, 0xd08c, 0x00c0, 0x52c9, 0x6008, 0x8000, 0x0048, 0x52cd,
 	0x600a, 0x0c7f, 0x127f, 0x0078, 0x5453, 0x0c7f, 0x127f, 0x0078,
 	0x544b, 0x6954, 0xa186, 0x0045, 0x0040, 0x5306, 0xa186, 0x002a,
-	0x00c0, 0x52e1, 0x2001, 0xa60c, 0x200c, 0xc194, 0x2102, 0x0078,
+	0x00c0, 0x52e1, 0x2001, 0xa70c, 0x200c, 0xc194, 0x2102, 0x0078,
 	0x52ba, 0xa186, 0x0020, 0x0040, 0x52fa, 0xa186, 0x0029, 0x0040,
 	0x52ed, 0xa186, 0x002d, 0x00c0, 0x52cd, 0x6944, 0xa18c, 0xff00,
 	0x810f, 0x1078, 0x45c4, 0x00c0, 0x52ba, 0x6000, 0xc0e4, 0x6002,
 	0x0078, 0x52ba, 0x685c, 0xa065, 0x0040, 0x52cd, 0x6007, 0x0024,
-	0x2001, 0xa8a3, 0x2004, 0x6016, 0x0078, 0x52ba, 0x685c, 0xa065,
-	0x0040, 0x52cd, 0x0e7e, 0x6860, 0xa075, 0x2001, 0xa62f, 0x2004,
-	0xa005, 0x0040, 0x531e, 0x1078, 0x8ec6, 0x8eff, 0x0040, 0x531b,
-	0x2e60, 0x1078, 0x8ec6, 0x0e7f, 0x0078, 0x52ba, 0x6024, 0xc0dc,
+	0x2001, 0xa9a3, 0x2004, 0x6016, 0x0078, 0x52ba, 0x685c, 0xa065,
+	0x0040, 0x52cd, 0x0e7e, 0x6860, 0xa075, 0x2001, 0xa72f, 0x2004,
+	0xa005, 0x0040, 0x531e, 0x1078, 0x8ed6, 0x8eff, 0x0040, 0x531b,
+	0x2e60, 0x1078, 0x8ed6, 0x0e7f, 0x0078, 0x52ba, 0x6024, 0xc0dc,
 	0xc0d5, 0x6026, 0x2e60, 0x6007, 0x003a, 0x6870, 0xa005, 0x0040,
 	0x532f, 0x6007, 0x003b, 0x6874, 0x602a, 0x6878, 0x6012, 0x6003,
 	0x0001, 0x1078, 0x5d8a, 0x1078, 0x62d1, 0x0e7f, 0x0078, 0x52ba,
-	0x2061, 0xa933, 0x6000, 0xd084, 0x0040, 0x5352, 0xd08c, 0x00c0,
+	0x2061, 0xaa33, 0x6000, 0xd084, 0x0040, 0x5352, 0xd08c, 0x00c0,
 	0x5461, 0x2091, 0x8000, 0x6204, 0x8210, 0x0048, 0x534c, 0x6206,
 	0x2091, 0x8001, 0x0078, 0x5461, 0x2091, 0x8001, 0x6853, 0x0016,
 	0x0078, 0x545a, 0x6853, 0x0007, 0x0078, 0x545a, 0x6834, 0x8007,
@@ -2209,10 +2209,10 @@ unsigned short risc_code01[] = { 
 	0x2030, 0x8001, 0x00c0, 0x536a, 0x7007, 0x0001, 0x1078, 0x5373,
 	0x0078, 0x5372, 0x7007, 0x0006, 0x7012, 0x2d00, 0x7016, 0x701a,
 	0x704b, 0x5373, 0x007c, 0x0e7e, 0x127e, 0x2091, 0x8000, 0xa03e,
-	0x2009, 0xa62f, 0x210c, 0x81ff, 0x00c0, 0x53ff, 0x2009, 0xa60c,
-	0x210c, 0xd194, 0x00c0, 0x5431, 0x6848, 0x2070, 0xae82, 0xad00,
-	0x0048, 0x53ef, 0x2001, 0xa616, 0x2004, 0xae02, 0x00c8, 0x53ef,
-	0x2061, 0xa933, 0x6100, 0xa184, 0x0301, 0xa086, 0x0001, 0x00c0,
+	0x2009, 0xa72f, 0x210c, 0x81ff, 0x00c0, 0x53ff, 0x2009, 0xa70c,
+	0x210c, 0xd194, 0x00c0, 0x5431, 0x6848, 0x2070, 0xae82, 0xae00,
+	0x0048, 0x53ef, 0x2001, 0xa716, 0x2004, 0xae02, 0x00c8, 0x53ef,
+	0x2061, 0xaa33, 0x6100, 0xa184, 0x0301, 0xa086, 0x0001, 0x00c0,
 	0x53d2, 0x711c, 0xa186, 0x0006, 0x00c0, 0x53da, 0x7018, 0xa005,
 	0x0040, 0x53ff, 0x2004, 0xd0e4, 0x00c0, 0x542b, 0x7024, 0xd0dc,
 	0x00c0, 0x5435, 0x6853, 0x0000, 0x6803, 0x0000, 0x2d08, 0x7010,
@@ -2226,14 +2226,14 @@ unsigned short risc_code01[] = { 
 	0x0007, 0x00c0, 0x53ef, 0x6853, 0x0002, 0x0078, 0x542d, 0x6853,
 	0x0008, 0x0078, 0x542d, 0x6853, 0x000e, 0x0078, 0x542d, 0x6853,
 	0x0017, 0x0078, 0x542d, 0x6853, 0x0035, 0x0078, 0x542d, 0x2001,
-	0xa672, 0x2004, 0xd0fc, 0x0040, 0x5427, 0x6848, 0x2070, 0xae82,
-	0xad00, 0x0048, 0x5427, 0x6058, 0xae02, 0x00c8, 0x5427, 0x711c,
+	0xa772, 0x2004, 0xd0fc, 0x0040, 0x5427, 0x6848, 0x2070, 0xae82,
+	0xae00, 0x0048, 0x5427, 0x6058, 0xae02, 0x00c8, 0x5427, 0x711c,
 	0xa186, 0x0006, 0x00c0, 0x5427, 0x7018, 0xa005, 0x0040, 0x5427,
 	0x2004, 0xd0bc, 0x0040, 0x5427, 0x2039, 0x0001, 0x7000, 0xa086,
 	0x0007, 0x00c0, 0x537e, 0x7003, 0x0002, 0x0078, 0x537e, 0x6853,
 	0x0028, 0x0078, 0x542d, 0x6853, 0x0029, 0x127f, 0x0e7f, 0x0078,
 	0x545a, 0x6853, 0x002a, 0x0078, 0x542d, 0x6853, 0x0045, 0x0078,
-	0x542d, 0x2e60, 0x2019, 0x0002, 0x6017, 0x0014, 0x1078, 0x9dc7,
+	0x542d, 0x2e60, 0x2019, 0x0002, 0x6017, 0x0014, 0x1078, 0x9dd7,
 	0x127f, 0x0e7f, 0x007c, 0x2009, 0x003e, 0x0078, 0x5455, 0x2009,
 	0x0004, 0x0078, 0x5455, 0x2009, 0x0006, 0x0078, 0x5455, 0x2009,
 	0x0016, 0x0078, 0x5455, 0x2009, 0x0001, 0x6854, 0xa084, 0xff00,
@@ -2250,22 +2250,22 @@ unsigned short risc_code01[] = { 
 	0xa184, 0xff00, 0x8007, 0xa086, 0x0008, 0x00c0, 0x54d3, 0x1078,
 	0x29bb, 0x00c0, 0x54d3, 0x1078, 0x56b2, 0x0078, 0x54ce, 0x20e1,
 	0x0004, 0x3d60, 0xd1bc, 0x00c0, 0x54be, 0x3e60, 0xac84, 0x000f,
-	0x00c0, 0x54d3, 0xac82, 0xad00, 0x0048, 0x54d3, 0x6858, 0xac02,
+	0x00c0, 0x54d3, 0xac82, 0xae00, 0x0048, 0x54d3, 0x6858, 0xac02,
 	0x00c8, 0x54d3, 0x2009, 0x0047, 0x1078, 0x775c, 0x7a1c, 0xd284,
 	0x00c0, 0x548e, 0x007c, 0xa016, 0x1078, 0x15fa, 0x0078, 0x54ce,
 	0x0078, 0x54d3, 0x781c, 0xd08c, 0x0040, 0x5502, 0x157e, 0x137e,
 	0x147e, 0x20e1, 0x3000, 0x3d20, 0x3e28, 0xa584, 0x0076, 0x00c0,
 	0x5518, 0xa484, 0x7000, 0xa086, 0x1000, 0x00c0, 0x5507, 0x1078,
 	0x554e, 0x0040, 0x5518, 0x20e1, 0x3000, 0x7828, 0x7828, 0x1078,
-	0x556c, 0x147f, 0x137f, 0x157f, 0x2009, 0xa8b9, 0x2104, 0xa005,
+	0x556c, 0x147f, 0x137f, 0x157f, 0x2009, 0xa9b9, 0x2104, 0xa005,
 	0x00c0, 0x5503, 0x007c, 0x1078, 0x62d1, 0x0078, 0x5502, 0xa484,
 	0x7000, 0x00c0, 0x5518, 0x1078, 0x554e, 0x0040, 0x552c, 0x7000,
 	0xa084, 0xff00, 0xa086, 0x8100, 0x0040, 0x54f3, 0x0078, 0x552c,
-	0x1078, 0xa54f, 0xd5a4, 0x0040, 0x5528, 0x047e, 0x1078, 0x1b22,
+	0x1078, 0xa55f, 0xd5a4, 0x0040, 0x5528, 0x047e, 0x1078, 0x1b22,
 	0x047f, 0x20e1, 0x9010, 0x2001, 0x0138, 0x2202, 0x0078, 0x5530,
 	0x1078, 0x554e, 0x6883, 0x0000, 0x20e1, 0x3000, 0x7828, 0x7828,
 	0x1078, 0x5537, 0x147f, 0x137f, 0x157f, 0x0078, 0x5502, 0x2001,
-	0xa60e, 0x2004, 0xd08c, 0x0040, 0x554d, 0x2001, 0xa600, 0x2004,
+	0xa70e, 0x2004, 0xd08c, 0x0040, 0x554d, 0x2001, 0xa700, 0x2004,
 	0xa086, 0x0003, 0x00c0, 0x554d, 0x027e, 0x037e, 0x2011, 0x8048,
 	0x2518, 0x1078, 0x361b, 0x037f, 0x027f, 0x007c, 0xa484, 0x01ff,
 	0x6882, 0xa005, 0x0040, 0x5560, 0xa080, 0x001f, 0xa084, 0x03f8,
@@ -2300,12 +2300,12 @@ unsigned short risc_code01[] = { 
 	0xff00, 0xa18e, 0x5300, 0x00c0, 0x5641, 0x2009, 0x002a, 0x0078,
 	0x5676, 0xa08e, 0x0f00, 0x00c0, 0x5649, 0x2009, 0x0020, 0x0078,
 	0x5676, 0xa08e, 0x5300, 0x00c0, 0x564f, 0x0078, 0x566c, 0xa08e,
-	0x6104, 0x00c0, 0x566c, 0x2011, 0xab8d, 0x8208, 0x2204, 0xa082,
+	0x6104, 0x00c0, 0x566c, 0x2011, 0xac8d, 0x8208, 0x2204, 0xa082,
 	0x0004, 0x20a8, 0x95ac, 0x95ac, 0x2011, 0x8015, 0x211c, 0x8108,
 	0x047e, 0x2124, 0x1078, 0x361b, 0x047f, 0x8108, 0x00f0, 0x565c,
 	0x2009, 0x0023, 0x0078, 0x5676, 0xa08e, 0x6000, 0x00c0, 0x5674,
 	0x2009, 0x003f, 0x0078, 0x5676, 0x2009, 0x001d, 0x017e, 0x2011,
-	0xab83, 0x2204, 0x8211, 0x220c, 0x1078, 0x254d, 0x00c0, 0x56ac,
+	0xac83, 0x2204, 0x8211, 0x220c, 0x1078, 0x254d, 0x00c0, 0x56ac,
 	0x1078, 0x455c, 0x00c0, 0x56ac, 0x6612, 0x6516, 0x86ff, 0x0040,
 	0x569c, 0x017f, 0x017e, 0xa186, 0x0017, 0x00c0, 0x569c, 0x686c,
 	0xa606, 0x00c0, 0x569c, 0x6870, 0xa506, 0xa084, 0xff00, 0x00c0,
@@ -2319,7 +2319,7 @@ unsigned short risc_code01[] = { 
 	0xa08e, 0x0100, 0x00c0, 0x570d, 0x7034, 0xa005, 0x00c0, 0x570d,
 	0x2009, 0x0016, 0x1078, 0x775c, 0x0078, 0x570d, 0xa28e, 0x0032,
 	0x00c0, 0x570d, 0x7030, 0xa08e, 0x1400, 0x00c0, 0x570d, 0x2009,
-	0x0038, 0x017e, 0x2011, 0xab83, 0x2204, 0x8211, 0x220c, 0x1078,
+	0x0038, 0x017e, 0x2011, 0xac83, 0x2204, 0x8211, 0x220c, 0x1078,
 	0x254d, 0x00c0, 0x570c, 0x1078, 0x455c, 0x00c0, 0x570c, 0x6612,
 	0x6516, 0x0c7e, 0x1078, 0x76c7, 0x0040, 0x570b, 0x017f, 0x611a,
 	0x601f, 0x0004, 0x7120, 0x610a, 0x017f, 0x1078, 0x775c, 0x1078,
@@ -2339,7 +2339,7 @@ unsigned short risc_code01[] = { 
 	0x0078, 0x57b5, 0xa596, 0xfffe, 0x00c0, 0x577a, 0x2009, 0x007e,
 	0x0078, 0x57b5, 0xa596, 0xfffc, 0x00c0, 0x5782, 0x2009, 0x0080,
 	0x0078, 0x57b5, 0x2011, 0x0000, 0x2021, 0x0081, 0x20a9, 0x007e,
-	0x2071, 0xa7b6, 0x2e1c, 0x83ff, 0x00c0, 0x5794, 0x82ff, 0x00c0,
+	0x2071, 0xa8b6, 0x2e1c, 0x83ff, 0x00c0, 0x5794, 0x82ff, 0x00c0,
 	0x57a9, 0x2410, 0x0078, 0x57a9, 0x2368, 0x6f10, 0x007e, 0x2100,
 	0xa706, 0x007f, 0x6b14, 0x00c0, 0x57a3, 0xa346, 0x00c0, 0x57a3,
 	0x2408, 0x0078, 0x57b5, 0x87ff, 0x00c0, 0x57a9, 0x83ff, 0x0040,
@@ -2348,10 +2348,10 @@ unsigned short risc_code01[] = { 
 	0x047f, 0x007c, 0xa084, 0x0007, 0x0079, 0x57bf, 0x007c, 0x57c7,
 	0x57c7, 0x57c7, 0x5933, 0x57c7, 0x57c8, 0x57e1, 0x5858, 0x007c,
 	0x7110, 0xd1bc, 0x0040, 0x57e0, 0x7120, 0x2160, 0xac8c, 0x000f,
-	0x00c0, 0x57e0, 0xac8a, 0xad00, 0x0048, 0x57e0, 0x6858, 0xac02,
+	0x00c0, 0x57e0, 0xac8a, 0xae00, 0x0048, 0x57e0, 0x6858, 0xac02,
 	0x00c8, 0x57e0, 0x7124, 0x610a, 0x2009, 0x0046, 0x1078, 0x775c,
 	0x007c, 0x0c7e, 0xa484, 0x01ff, 0x0040, 0x5833, 0x7110, 0xd1bc,
-	0x00c0, 0x5833, 0x2011, 0xab83, 0x2204, 0x8211, 0x220c, 0x1078,
+	0x00c0, 0x5833, 0x2011, 0xac83, 0x2204, 0x8211, 0x220c, 0x1078,
 	0x254d, 0x00c0, 0x5833, 0x1078, 0x455c, 0x00c0, 0x5833, 0x6612,
 	0x6516, 0x6000, 0xd0ec, 0x00c0, 0x5833, 0x6204, 0xa294, 0xff00,
 	0x8217, 0xa286, 0x0006, 0x00c0, 0x5818, 0x0c7e, 0x1078, 0x76c7,
@@ -2360,13 +2360,13 @@ unsigned short risc_code01[] = { 
 	0x0c7e, 0x1078, 0x76c7, 0x017f, 0x0040, 0x5833, 0x611a, 0x601f,
 	0x0004, 0x7120, 0x610a, 0xa286, 0x0004, 0x00c0, 0x582b, 0x6007,
 	0x0005, 0x0078, 0x582d, 0x6007, 0x0001, 0x6003, 0x0001, 0x1078,
-	0x5dd7, 0x1078, 0x62d1, 0x0c7f, 0x007c, 0x2001, 0xa60d, 0x2004,
+	0x5dd7, 0x1078, 0x62d1, 0x0c7f, 0x007c, 0x2001, 0xa70d, 0x2004,
 	0xd0ec, 0x0040, 0x583f, 0x2011, 0x8049, 0x1078, 0x361b, 0x0c7e,
-	0x1078, 0x9187, 0x017f, 0x0040, 0x5833, 0x611a, 0x601f, 0x0006,
+	0x1078, 0x9197, 0x017f, 0x0040, 0x5833, 0x611a, 0x601f, 0x0006,
 	0x7120, 0x610a, 0x7130, 0x6122, 0x6013, 0x0300, 0x6003, 0x0001,
 	0x6007, 0x0041, 0x1078, 0x5d8a, 0x1078, 0x62d1, 0x0078, 0x5833,
 	0x7110, 0xd1bc, 0x0040, 0x5870, 0x7020, 0x2060, 0xac84, 0x000f,
-	0x00c0, 0x5870, 0xac82, 0xad00, 0x0048, 0x5870, 0x6858, 0xac02,
+	0x00c0, 0x5870, 0xac82, 0xae00, 0x0048, 0x5870, 0x6858, 0xac02,
 	0x00c8, 0x5870, 0x7124, 0x610a, 0x2009, 0x0045, 0x1078, 0x775c,
 	0x007c, 0x007e, 0x1078, 0x29bb, 0x007f, 0x00c0, 0x5887, 0x7110,
 	0xa18c, 0xff00, 0x810f, 0xa18e, 0x0000, 0x00c0, 0x5887, 0xa084,
@@ -2390,15 +2390,15 @@ unsigned short risc_code01[] = { 
 	0x610a, 0x2009, 0x0089, 0x1078, 0x775c, 0x007c, 0x7110, 0xd1bc,
 	0x0040, 0x591c, 0x1078, 0x591d, 0x0040, 0x591c, 0x7124, 0x610a,
 	0x2009, 0x008a, 0x1078, 0x775c, 0x007c, 0x7020, 0x2060, 0xac84,
-	0x000f, 0x00c0, 0x5930, 0xac82, 0xad00, 0x0048, 0x5930, 0x2001,
-	0xa616, 0x2004, 0xac02, 0x00c8, 0x5930, 0xa085, 0x0001, 0x007c,
+	0x000f, 0x00c0, 0x5930, 0xac82, 0xae00, 0x0048, 0x5930, 0x2001,
+	0xa716, 0x2004, 0xac02, 0x00c8, 0x5930, 0xa085, 0x0001, 0x007c,
 	0xa006, 0x0078, 0x592f, 0x7110, 0xd1bc, 0x00c0, 0x5949, 0x7024,
-	0x2060, 0xac84, 0x000f, 0x00c0, 0x5949, 0xac82, 0xad00, 0x0048,
+	0x2060, 0xac84, 0x000f, 0x00c0, 0x5949, 0xac82, 0xae00, 0x0048,
 	0x5949, 0x6858, 0xac02, 0x00c8, 0x5949, 0x2009, 0x0051, 0x1078,
-	0x775c, 0x007c, 0x2071, 0xa8c4, 0x7003, 0x0003, 0x700f, 0x0361,
-	0xa006, 0x701a, 0x7012, 0x7017, 0xad00, 0x7007, 0x0000, 0x7026,
+	0x775c, 0x007c, 0x2071, 0xa9c4, 0x7003, 0x0003, 0x700f, 0x0361,
+	0xa006, 0x701a, 0x7012, 0x7017, 0xae00, 0x7007, 0x0000, 0x7026,
 	0x702b, 0x6e1c, 0x7032, 0x7037, 0x6e70, 0x703b, 0x0002, 0x703f,
-	0x0000, 0x7043, 0xffff, 0x7047, 0xffff, 0x007c, 0x2071, 0xa8c4,
+	0x0000, 0x7043, 0xffff, 0x7047, 0xffff, 0x007c, 0x2071, 0xa9c4,
 	0x00e0, 0x5a32, 0x2091, 0x6000, 0x700c, 0x8001, 0x700e, 0x00c0,
 	0x59de, 0x700f, 0x0361, 0x7007, 0x0001, 0x127e, 0x2091, 0x8000,
 	0x7138, 0x8109, 0x713a, 0x00c0, 0x59dc, 0x703b, 0x0002, 0x2009,
@@ -2406,11 +2406,11 @@ unsigned short risc_code01[] = { 
 	0x0001, 0x00c0, 0x59b9, 0x0d7e, 0x2069, 0x0140, 0x6804, 0xa084,
 	0x4000, 0x0040, 0x5997, 0x6803, 0x1000, 0x0078, 0x599e, 0x6804,
 	0xa084, 0x1000, 0x0040, 0x599e, 0x6803, 0x0100, 0x6803, 0x0000,
-	0x703f, 0x0000, 0x2069, 0xa8b1, 0x6804, 0xa082, 0x0006, 0x00c0,
+	0x703f, 0x0000, 0x2069, 0xa9b1, 0x6804, 0xa082, 0x0006, 0x00c0,
 	0x59ab, 0x6807, 0x0000, 0x6830, 0xa082, 0x0003, 0x00c0, 0x59b2,
 	0x6833, 0x0000, 0x1078, 0x62d1, 0x1078, 0x639b, 0x0d7f, 0x0078,
-	0x59dc, 0x0d7e, 0x2069, 0xa600, 0x6948, 0x6864, 0xa102, 0x00c8,
-	0x59db, 0x2069, 0xa8b1, 0x6804, 0xa086, 0x0000, 0x00c0, 0x59db,
+	0x59dc, 0x0d7e, 0x2069, 0xa700, 0x6948, 0x6864, 0xa102, 0x00c8,
+	0x59db, 0x2069, 0xa9b1, 0x6804, 0xa086, 0x0000, 0x00c0, 0x59db,
 	0x6830, 0xa086, 0x0000, 0x00c0, 0x59db, 0x703f, 0x0001, 0x6807,
 	0x0006, 0x6833, 0x0003, 0x2069, 0x0100, 0x6830, 0x689e, 0x2069,
 	0x0140, 0x6803, 0x0600, 0x0d7f, 0x0078, 0x59e1, 0x127e, 0x2091,
@@ -2425,45 +2425,45 @@ unsigned short risc_code01[] = { 
 	0x7018, 0xa00d, 0x0040, 0x5a31, 0x7008, 0x8001, 0x700a, 0x00c0,
 	0x5a31, 0x700b, 0x0009, 0x8109, 0x711a, 0x00c0, 0x5a31, 0x701c,
 	0x107a, 0x127f, 0x7004, 0x0079, 0x5a35, 0x5a5c, 0x5a5d, 0x5a79,
-	0x0e7e, 0x2071, 0xa8c4, 0x7018, 0xa005, 0x00c0, 0x5a43, 0x711a,
+	0x0e7e, 0x2071, 0xa9c4, 0x7018, 0xa005, 0x00c0, 0x5a43, 0x711a,
 	0x721e, 0x700b, 0x0009, 0x0e7f, 0x007c, 0x0e7e, 0x007e, 0x2071,
-	0xa8c4, 0x701c, 0xa206, 0x00c0, 0x5a4f, 0x701a, 0x701e, 0x007f,
-	0x0e7f, 0x007c, 0x0e7e, 0x2071, 0xa8c4, 0x6088, 0xa102, 0x0048,
+	0xa9c4, 0x701c, 0xa206, 0x00c0, 0x5a4f, 0x701a, 0x701e, 0x007f,
+	0x0e7f, 0x007c, 0x0e7e, 0x2071, 0xa9c4, 0x6088, 0xa102, 0x0048,
 	0x5a5a, 0x618a, 0x0e7f, 0x007c, 0x007c, 0x7110, 0x1078, 0x45c4,
 	0x00c0, 0x5a6f, 0x6088, 0x8001, 0x0048, 0x5a6f, 0x608a, 0x00c0,
 	0x5a6f, 0x127e, 0x2091, 0x8000, 0x1078, 0x62d1, 0x127f, 0x8108,
 	0xa182, 0x00ff, 0x0048, 0x5a77, 0xa00e, 0x7007, 0x0002, 0x7112,
 	0x007c, 0x7014, 0x2060, 0x127e, 0x2091, 0x8000, 0x603c, 0xa005,
-	0x0040, 0x5a88, 0x8001, 0x603e, 0x00c0, 0x5a88, 0x1078, 0x8f9c,
+	0x0040, 0x5a88, 0x8001, 0x603e, 0x00c0, 0x5a88, 0x1078, 0x8fac,
 	0x6014, 0xa005, 0x0040, 0x5ab2, 0x8001, 0x6016, 0x00c0, 0x5ab2,
 	0x611c, 0xa186, 0x0003, 0x0040, 0x5a99, 0xa186, 0x0006, 0x00c0,
 	0x5ab0, 0x6010, 0x2068, 0x6854, 0xa08a, 0x199a, 0x0048, 0x5ab0,
 	0xa082, 0x1999, 0x6856, 0xa08a, 0x199a, 0x0048, 0x5aa9, 0x2001,
 	0x1999, 0x8003, 0x800b, 0x810b, 0xa108, 0x6116, 0x0078, 0x5ab2,
-	0x1078, 0x8abe, 0x127f, 0xac88, 0x0010, 0x7116, 0x2001, 0xcd00,
-	0xa102, 0x0048, 0x5abf, 0x7017, 0xad00, 0x7007, 0x0000, 0x007c,
-	0x0e7e, 0x2071, 0xa8c4, 0x7027, 0x07d0, 0x7023, 0x0009, 0x703b,
-	0x0002, 0x0e7f, 0x007c, 0x2001, 0xa8cd, 0x2003, 0x0000, 0x007c,
-	0x0e7e, 0x2071, 0xa8c4, 0x7132, 0x702f, 0x0009, 0x0e7f, 0x007c,
-	0x2011, 0xa8d0, 0x2013, 0x0000, 0x007c, 0x0e7e, 0x2071, 0xa8c4,
+	0x1078, 0x8ace, 0x127f, 0xac88, 0x0010, 0x7116, 0x2001, 0xce00,
+	0xa102, 0x0048, 0x5abf, 0x7017, 0xae00, 0x7007, 0x0000, 0x007c,
+	0x0e7e, 0x2071, 0xa9c4, 0x7027, 0x07d0, 0x7023, 0x0009, 0x703b,
+	0x0002, 0x0e7f, 0x007c, 0x2001, 0xa9cd, 0x2003, 0x0000, 0x007c,
+	0x0e7e, 0x2071, 0xa9c4, 0x7132, 0x702f, 0x0009, 0x0e7f, 0x007c,
+	0x2011, 0xa9d0, 0x2013, 0x0000, 0x007c, 0x0e7e, 0x2071, 0xa9c4,
 	0x711a, 0x721e, 0x700b, 0x0009, 0x0e7f, 0x007c, 0x027e, 0x0e7e,
-	0x0f7e, 0x2079, 0xa600, 0x7a34, 0xd294, 0x0040, 0x5b15, 0x2071,
-	0xa8ac, 0x2e14, 0xa0fe, 0x0000, 0x0040, 0x5b02, 0xa0fe, 0x0001,
+	0x0f7e, 0x2079, 0xa700, 0x7a34, 0xd294, 0x0040, 0x5b15, 0x2071,
+	0xa9ac, 0x2e14, 0xa0fe, 0x0000, 0x0040, 0x5b02, 0xa0fe, 0x0001,
 	0x0040, 0x5b06, 0xa0fe, 0x0002, 0x00c0, 0x5b11, 0xa292, 0x0085,
 	0x0078, 0x5b08, 0xa292, 0x0005, 0x0078, 0x5b08, 0xa292, 0x0002,
 	0x2272, 0x0040, 0x5b0d, 0x00c8, 0x5b15, 0x2011, 0x8037, 0x1078,
-	0x361b, 0x2011, 0xa8ab, 0x2204, 0x2072, 0x0f7f, 0x0e7f, 0x027f,
-	0x007c, 0x0c7e, 0x2061, 0xa933, 0x0c7f, 0x007c, 0xa184, 0x000f,
-	0x8003, 0x8003, 0x8003, 0xa080, 0xa933, 0x2060, 0x007c, 0x6854,
+	0x361b, 0x2011, 0xa9ab, 0x2204, 0x2072, 0x0f7f, 0x0e7f, 0x027f,
+	0x007c, 0x0c7e, 0x2061, 0xaa33, 0x0c7f, 0x007c, 0xa184, 0x000f,
+	0x8003, 0x8003, 0x8003, 0xa080, 0xaa33, 0x2060, 0x007c, 0x6854,
 	0xa08a, 0x199a, 0x0048, 0x5b2e, 0x2001, 0x1999, 0xa005, 0x00c0,
-	0x5b3d, 0x0c7e, 0x2061, 0xa933, 0x6014, 0x0c7f, 0xa005, 0x00c0,
+	0x5b3d, 0x0c7e, 0x2061, 0xaa33, 0x6014, 0x0c7f, 0xa005, 0x00c0,
 	0x5b42, 0x2001, 0x001e, 0x0078, 0x5b42, 0xa08e, 0xffff, 0x00c0,
 	0x5b42, 0xa006, 0x8003, 0x800b, 0x810b, 0xa108, 0x6116, 0x684c,
 	0xa08c, 0x00c0, 0xa18e, 0x00c0, 0x0040, 0x5b9e, 0xd0b4, 0x00c0,
 	0x5b59, 0xd0bc, 0x00c0, 0x5b8b, 0x2009, 0x0006, 0x1078, 0x5bc3,
 	0x007c, 0xd0fc, 0x0040, 0x5b64, 0xa084, 0x0003, 0x0040, 0x5b64,
 	0xa086, 0x0003, 0x00c0, 0x5bbc, 0x6024, 0xd0d4, 0x0040, 0x5b6e,
-	0xc0d4, 0x6026, 0x6860, 0x602a, 0x685c, 0x602e, 0x2009, 0xa674,
+	0xc0d4, 0x6026, 0x6860, 0x602a, 0x685c, 0x602e, 0x2009, 0xa774,
 	0x2104, 0xd084, 0x0040, 0x5b83, 0x6118, 0xa188, 0x0027, 0x2104,
 	0xd08c, 0x00c0, 0x5b83, 0x87ff, 0x00c0, 0x5b82, 0x2009, 0x0042,
 	0x1078, 0x775c, 0x007c, 0x87ff, 0x00c0, 0x5b8a, 0x2009, 0x0043,
@@ -2477,10 +2477,10 @@ unsigned short risc_code01[] = { 
 	0x007c, 0x2009, 0x0001, 0x0d7e, 0x6010, 0xa0ec, 0xf000, 0x0040,
 	0x5bef, 0x2068, 0x6952, 0x6800, 0x6012, 0xa186, 0x0001, 0x00c0,
 	0x5be5, 0x694c, 0xa18c, 0x8100, 0xa18e, 0x8100, 0x00c0, 0x5be5,
-	0x0c7e, 0x2061, 0xa933, 0x6200, 0xd28c, 0x00c0, 0x5be4, 0x6204,
+	0x0c7e, 0x2061, 0xaa33, 0x6200, 0xd28c, 0x00c0, 0x5be4, 0x6204,
 	0x8210, 0x0048, 0x5be4, 0x6206, 0x0c7f, 0x1078, 0x4a73, 0x6010,
 	0xa06d, 0x077e, 0x2039, 0x0000, 0x10c0, 0x5b27, 0x077f, 0x0d7f,
-	0x007c, 0x157e, 0x0c7e, 0x2061, 0xa933, 0x6000, 0x81ff, 0x0040,
+	0x007c, 0x157e, 0x0c7e, 0x2061, 0xaa33, 0x6000, 0x81ff, 0x0040,
 	0x5bfc, 0xa205, 0x0078, 0x5bfd, 0xa204, 0x6002, 0x0c7f, 0x157f,
 	0x007c, 0x6800, 0xd08c, 0x00c0, 0x5c0d, 0x6808, 0xa005, 0x0040,
 	0x5c0d, 0x8001, 0x680a, 0xa085, 0x0001, 0x007c, 0x20a9, 0x0010,
@@ -2490,8 +2490,8 @@ unsigned short risc_code01[] = { 
 	0x5c30, 0xa11a, 0x00c8, 0x5c31, 0x00f0, 0x5c25, 0x0078, 0x5c35,
 	0xa11a, 0x2308, 0x8210, 0x00f0, 0x5c25, 0x007e, 0x3200, 0xa084,
 	0xf7ff, 0x2080, 0x007f, 0x157f, 0x007c, 0x007e, 0x3200, 0xa085,
-	0x0800, 0x0078, 0x5c39, 0x127e, 0x2091, 0x2200, 0x2079, 0xa8b1,
-	0x127f, 0x0d7e, 0x2069, 0xa8b1, 0x6803, 0x0005, 0x2069, 0x0004,
+	0x0800, 0x0078, 0x5c39, 0x127e, 0x2091, 0x2200, 0x2079, 0xa9b1,
+	0x127f, 0x0d7e, 0x2069, 0xa9b1, 0x6803, 0x0005, 0x2069, 0x0004,
 	0x2d04, 0xa085, 0x8001, 0x206a, 0x0d7f, 0x007c, 0x0c7e, 0x6027,
 	0x0001, 0x7804, 0xa084, 0x0007, 0x0079, 0x5c5e, 0x5c68, 0x5c8d,
 	0x5ce8, 0x5c6e, 0x5c8d, 0x5c68, 0x5c66, 0x5c66, 0x1078, 0x1332,
@@ -2503,18 +2503,18 @@ unsigned short risc_code01[] = { 
 	0x007e, 0x2011, 0x0209, 0x20e1, 0x4000, 0x2214, 0x007f, 0x20e0,
 	0x82ff, 0x0040, 0x5cab, 0x62c0, 0x82ff, 0x00c0, 0x5cab, 0x782b,
 	0x0000, 0x7824, 0xa065, 0x1040, 0x1332, 0x2009, 0x0013, 0x1078,
-	0x775c, 0x0c7f, 0x007c, 0x3900, 0xa082, 0xa9e3, 0x00c8, 0x5cb2,
+	0x775c, 0x0c7f, 0x007c, 0x3900, 0xa082, 0xaae3, 0x00c8, 0x5cb2,
 	0x1078, 0x747a, 0x0c7e, 0x7824, 0xa065, 0x1040, 0x1332, 0x7804,
 	0xa086, 0x0004, 0x0040, 0x5d2d, 0x7828, 0xa092, 0x2710, 0x00c8,
 	0x5cc8, 0x8000, 0x782a, 0x0c7f, 0x1078, 0x6e01, 0x0078, 0x5ca9,
-	0x6104, 0xa186, 0x0003, 0x00c0, 0x5cdf, 0x0e7e, 0x2071, 0xa600,
+	0x6104, 0xa186, 0x0003, 0x00c0, 0x5cdf, 0x0e7e, 0x2071, 0xa700,
 	0x70d8, 0x0e7f, 0xd08c, 0x0040, 0x5cdf, 0x0c7e, 0x0e7e, 0x2061,
-	0x0100, 0x2071, 0xa600, 0x1078, 0x4224, 0x0e7f, 0x0c7f, 0x1078,
-	0xa5c4, 0x2009, 0x0014, 0x1078, 0x775c, 0x0c7f, 0x0078, 0x5ca9,
-	0x2001, 0xa8cd, 0x2003, 0x0000, 0x62c0, 0x82ff, 0x00c0, 0x5cfc,
+	0x0100, 0x2071, 0xa700, 0x1078, 0x4224, 0x0e7f, 0x0c7f, 0x1078,
+	0xa5d4, 0x2009, 0x0014, 0x1078, 0x775c, 0x0c7f, 0x0078, 0x5ca9,
+	0x2001, 0xa9cd, 0x2003, 0x0000, 0x62c0, 0x82ff, 0x00c0, 0x5cfc,
 	0x782b, 0x0000, 0x7824, 0xa065, 0x1040, 0x1332, 0x2009, 0x0013,
 	0x1078, 0x77b3, 0x0c7f, 0x007c, 0x0c7e, 0x0d7e, 0x3900, 0xa082,
-	0xa9e3, 0x00c8, 0x5d05, 0x1078, 0x747a, 0x7824, 0xa005, 0x1040,
+	0xaae3, 0x00c8, 0x5d05, 0x1078, 0x747a, 0x7824, 0xa005, 0x1040,
 	0x1332, 0x781c, 0xa06d, 0x1040, 0x1332, 0x6800, 0xc0dc, 0x6802,
 	0x7924, 0x2160, 0x1078, 0x772d, 0x693c, 0x81ff, 0x1040, 0x1332,
 	0x8109, 0x693e, 0x6854, 0xa015, 0x0040, 0x5d21, 0x7a1e, 0x0078,
@@ -2525,30 +2525,30 @@ unsigned short risc_code01[] = { 
 	0x0c7f, 0x1078, 0x62d1, 0x0078, 0x5ca9, 0x0c7e, 0x6027, 0x0002,
 	0x62c8, 0x82ff, 0x00c0, 0x5d61, 0x62c4, 0x82ff, 0x00c0, 0x5d61,
 	0x793c, 0xa1e5, 0x0000, 0x0040, 0x5d5b, 0x2009, 0x0049, 0x1078,
-	0x775c, 0x0c7f, 0x007c, 0x2011, 0xa8d0, 0x2013, 0x0000, 0x0078,
-	0x5d59, 0x3908, 0xa192, 0xa9e3, 0x00c8, 0x5d68, 0x1078, 0x747a,
+	0x775c, 0x0c7f, 0x007c, 0x2011, 0xa9d0, 0x2013, 0x0000, 0x0078,
+	0x5d59, 0x3908, 0xa192, 0xaae3, 0x00c8, 0x5d68, 0x1078, 0x747a,
 	0x6017, 0x0010, 0x793c, 0x81ff, 0x0040, 0x5d5b, 0x7944, 0xa192,
 	0x7530, 0x00c8, 0x5d85, 0x8108, 0x7946, 0x793c, 0xa188, 0x0007,
 	0x210c, 0xa18e, 0x0006, 0x00c0, 0x5d81, 0x6017, 0x0012, 0x0078,
 	0x5d59, 0x6017, 0x0016, 0x0078, 0x5d59, 0x7848, 0xc085, 0x784a,
 	0x0078, 0x5d59, 0x007e, 0x017e, 0x0c7e, 0x127e, 0x2091, 0x8000,
-	0x600f, 0x0000, 0x2c08, 0x2061, 0xa8b1, 0x6020, 0x8000, 0x6022,
+	0x600f, 0x0000, 0x2c08, 0x2061, 0xa9b1, 0x6020, 0x8000, 0x6022,
 	0x6010, 0xa005, 0x0040, 0x5da5, 0xa080, 0x0003, 0x2102, 0x6112,
 	0x127f, 0x0c7f, 0x017f, 0x007f, 0x007c, 0x6116, 0x6112, 0x0078,
-	0x5da0, 0x0d7e, 0x2069, 0xa8b1, 0x6000, 0xd0d4, 0x0040, 0x5dbe,
+	0x5da0, 0x0d7e, 0x2069, 0xa9b1, 0x6000, 0xd0d4, 0x0040, 0x5dbe,
 	0x6820, 0x8000, 0x6822, 0xa086, 0x0001, 0x00c0, 0x5db9, 0x2c00,
 	0x681e, 0x6804, 0xa084, 0x0007, 0x0079, 0x62d9, 0xc0d5, 0x6002,
 	0x6818, 0xa005, 0x0040, 0x5dd0, 0x6056, 0x605b, 0x0000, 0x007e,
-	0x2c00, 0x681a, 0x0d7f, 0x685a, 0x2069, 0xa8b1, 0x0078, 0x5db0,
+	0x2c00, 0x681a, 0x0d7f, 0x685a, 0x2069, 0xa9b1, 0x0078, 0x5db0,
 	0x6056, 0x605a, 0x2c00, 0x681a, 0x681e, 0x0078, 0x5db0, 0x007e,
 	0x017e, 0x0c7e, 0x127e, 0x2091, 0x8000, 0x600f, 0x0000, 0x2c08,
-	0x2061, 0xa8b1, 0x6020, 0x8000, 0x6022, 0x6008, 0xa005, 0x0040,
+	0x2061, 0xa9b1, 0x6020, 0x8000, 0x6022, 0x6008, 0xa005, 0x0040,
 	0x5df2, 0xa080, 0x0003, 0x2102, 0x610a, 0x127f, 0x0c7f, 0x017f,
 	0x007f, 0x007c, 0x610e, 0x610a, 0x0078, 0x5ded, 0x0c7e, 0x600f,
-	0x0000, 0x2c08, 0x2061, 0xa8b1, 0x6034, 0xa005, 0x0040, 0x5e06,
+	0x0000, 0x2c08, 0x2061, 0xa9b1, 0x6034, 0xa005, 0x0040, 0x5e06,
 	0xa080, 0x0003, 0x2102, 0x6136, 0x0c7f, 0x007c, 0x613a, 0x6136,
 	0x0078, 0x5e04, 0x0f7e, 0x0e7e, 0x0d7e, 0x0c7e, 0x067e, 0x057e,
-	0x037e, 0x027e, 0x017e, 0x007e, 0x127e, 0xa02e, 0x2071, 0xa8b1,
+	0x037e, 0x027e, 0x017e, 0x007e, 0x127e, 0xa02e, 0x2071, 0xa9b1,
 	0x7638, 0x2660, 0x2678, 0x2091, 0x8000, 0x8cff, 0x0040, 0x5e8c,
 	0x6018, 0xa080, 0x0028, 0x2004, 0xa206, 0x00c0, 0x5e87, 0x87ff,
 	0x0040, 0x5e2e, 0x6020, 0xa106, 0x00c0, 0x5e87, 0x703c, 0xac06,
@@ -2558,31 +2558,31 @@ unsigned short risc_code01[] = { 
 	0x660c, 0x763a, 0x7034, 0xac36, 0x00c0, 0x5e58, 0x2c00, 0xaf36,
 	0x0040, 0x5e56, 0x2f00, 0x7036, 0x0078, 0x5e58, 0x7037, 0x0000,
 	0x660c, 0x067e, 0x2c00, 0xaf06, 0x0040, 0x5e61, 0x7e0e, 0x0078,
-	0x5e62, 0x2678, 0x600f, 0x0000, 0x1078, 0x8d06, 0x0040, 0x5e82,
+	0x5e62, 0x2678, 0x600f, 0x0000, 0x1078, 0x8d16, 0x0040, 0x5e82,
 	0x6010, 0x2068, 0x601c, 0xa086, 0x0003, 0x00c0, 0x5e9d, 0x6837,
 	0x0103, 0x6b4a, 0x6847, 0x0000, 0x017e, 0x037e, 0x077e, 0x1078,
-	0x8f7d, 0x1078, 0xa4e2, 0x1078, 0x4a73, 0x077f, 0x037f, 0x017f,
-	0x1078, 0x8eb9, 0x1078, 0x8ec6, 0x0c7f, 0x0078, 0x5e1d, 0x2c78,
+	0x8f8d, 0x1078, 0xa4f2, 0x1078, 0x4a73, 0x077f, 0x037f, 0x017f,
+	0x1078, 0x8ec9, 0x1078, 0x8ed6, 0x0c7f, 0x0078, 0x5e1d, 0x2c78,
 	0x600c, 0x2060, 0x0078, 0x5e1d, 0x85ff, 0x0040, 0x5e91, 0x1078,
 	0x639b, 0x127f, 0x007f, 0x017f, 0x027f, 0x037f, 0x057f, 0x067f,
 	0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f, 0x007c, 0x601c, 0xa086, 0x0006,
-	0x00c0, 0x5e6f, 0x017e, 0x037e, 0x077e, 0x1078, 0xa4e2, 0x1078,
-	0xa1ca, 0x077f, 0x037f, 0x017f, 0x0078, 0x5e82, 0x007e, 0x067e,
+	0x00c0, 0x5e6f, 0x017e, 0x037e, 0x077e, 0x1078, 0xa4f2, 0x1078,
+	0xa1da, 0x077f, 0x037f, 0x017f, 0x0078, 0x5e82, 0x007e, 0x067e,
 	0x0c7e, 0x0d7e, 0x0f7e, 0x2031, 0x0000, 0x127e, 0x2091, 0x8000,
-	0x2079, 0xa8b1, 0x7838, 0xa065, 0x0040, 0x5eef, 0x600c, 0x007e,
+	0x2079, 0xa9b1, 0x7838, 0xa065, 0x0040, 0x5eef, 0x600c, 0x007e,
 	0x600f, 0x0000, 0x783c, 0xac06, 0x00c0, 0x5ed6, 0x037e, 0x2019,
 	0x0001, 0x1078, 0x7058, 0x7833, 0x0000, 0x783f, 0x0000, 0x7843,
-	0x0000, 0x7847, 0x0000, 0x784b, 0x0000, 0x037f, 0x1078, 0x8d06,
+	0x0000, 0x7847, 0x0000, 0x784b, 0x0000, 0x037f, 0x1078, 0x8d16,
 	0x0040, 0x5eea, 0x6010, 0x2068, 0x601c, 0xa086, 0x0003, 0x00c0,
 	0x5ef8, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x1078, 0x4a73,
-	0x1078, 0x8eb9, 0x1078, 0x8ec6, 0x007f, 0x0078, 0x5ebb, 0x7e3a,
+	0x1078, 0x8ec9, 0x1078, 0x8ed6, 0x007f, 0x0078, 0x5ebb, 0x7e3a,
 	0x7e36, 0x127f, 0x0f7f, 0x0d7f, 0x0c7f, 0x067f, 0x007f, 0x007c,
-	0x601c, 0xa086, 0x0006, 0x00c0, 0x5ee1, 0x1078, 0xa1ca, 0x0078,
+	0x601c, 0xa086, 0x0006, 0x00c0, 0x5ee1, 0x1078, 0xa1da, 0x0078,
 	0x5eea, 0x017e, 0x027e, 0x087e, 0x2041, 0x0000, 0x1078, 0x5f1b,
 	0x1078, 0x5fdb, 0x087f, 0x027f, 0x017f, 0x007c, 0x0f7e, 0x127e,
-	0x2079, 0xa8b1, 0x2091, 0x8000, 0x1078, 0x6076, 0x1078, 0x60ec,
+	0x2079, 0xa9b1, 0x2091, 0x8000, 0x1078, 0x6076, 0x1078, 0x60ec,
 	0x127f, 0x0f7f, 0x007c, 0x0f7e, 0x0e7e, 0x0d7e, 0x0c7e, 0x067e,
-	0x017e, 0x007e, 0x127e, 0x2091, 0x8000, 0x2071, 0xa8b1, 0x7614,
+	0x017e, 0x007e, 0x127e, 0x2091, 0x8000, 0x2071, 0xa9b1, 0x7614,
 	0x2660, 0x2678, 0x8cff, 0x0040, 0x5fb5, 0x6018, 0xa080, 0x0028,
 	0x2004, 0xa206, 0x00c0, 0x5fb0, 0x88ff, 0x0040, 0x5f3b, 0x6020,
 	0xa106, 0x00c0, 0x5fb0, 0x7024, 0xac06, 0x00c0, 0x5f6b, 0x2069,
@@ -2595,19 +2595,19 @@ unsigned short risc_code01[] = { 
 	0x7616, 0x7010, 0xac36, 0x00c0, 0x5f7f, 0x2c00, 0xaf36, 0x0040,
 	0x5f7d, 0x2f00, 0x7012, 0x0078, 0x5f7f, 0x7013, 0x0000, 0x660c,
 	0x067e, 0x2c00, 0xaf06, 0x0040, 0x5f88, 0x7e0e, 0x0078, 0x5f89,
-	0x2678, 0x600f, 0x0000, 0x6010, 0x2068, 0x1078, 0x8d06, 0x0040,
+	0x2678, 0x600f, 0x0000, 0x6010, 0x2068, 0x1078, 0x8d16, 0x0040,
 	0x5fa9, 0x601c, 0xa086, 0x0003, 0x00c0, 0x5fbe, 0x6837, 0x0103,
-	0x6b4a, 0x6847, 0x0000, 0x017e, 0x037e, 0x087e, 0x1078, 0x8f7d,
-	0x1078, 0xa4e2, 0x1078, 0x4a73, 0x087f, 0x037f, 0x017f, 0x1078,
-	0x8eb9, 0x1078, 0x8ec6, 0x1078, 0x7233, 0x0c7f, 0x0078, 0x5f2a,
+	0x6b4a, 0x6847, 0x0000, 0x017e, 0x037e, 0x087e, 0x1078, 0x8f8d,
+	0x1078, 0xa4f2, 0x1078, 0x4a73, 0x087f, 0x037f, 0x017f, 0x1078,
+	0x8ec9, 0x1078, 0x8ed6, 0x1078, 0x7233, 0x0c7f, 0x0078, 0x5f2a,
 	0x2c78, 0x600c, 0x2060, 0x0078, 0x5f2a, 0x127f, 0x007f, 0x017f,
 	0x067f, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f, 0x007c, 0x601c, 0xa086,
-	0x0006, 0x00c0, 0x5fcf, 0x017e, 0x037e, 0x087e, 0x1078, 0xa4e2,
-	0x1078, 0xa1ca, 0x087f, 0x037f, 0x017f, 0x0078, 0x5fa9, 0x601c,
+	0x0006, 0x00c0, 0x5fcf, 0x017e, 0x037e, 0x087e, 0x1078, 0xa4f2,
+	0x1078, 0xa1da, 0x087f, 0x037f, 0x017f, 0x0078, 0x5fa9, 0x601c,
 	0xa086, 0x0002, 0x00c0, 0x5fa9, 0x6004, 0xa086, 0x0085, 0x0040,
 	0x5f96, 0x0078, 0x5fa9, 0x0c7e, 0x007e, 0x127e, 0x2091, 0x8000,
-	0xa280, 0xa735, 0x2004, 0xa065, 0x0040, 0x6072, 0x0f7e, 0x0e7e,
-	0x0d7e, 0x067e, 0x2071, 0xa8b1, 0x6654, 0x7018, 0xac06, 0x00c0,
+	0xa280, 0xa835, 0x2004, 0xa065, 0x0040, 0x6072, 0x0f7e, 0x0e7e,
+	0x0d7e, 0x067e, 0x2071, 0xa9b1, 0x6654, 0x7018, 0xac06, 0x00c0,
 	0x5ff2, 0x761a, 0x701c, 0xac06, 0x00c0, 0x5ffe, 0x86ff, 0x00c0,
 	0x5ffd, 0x7018, 0x701e, 0x0078, 0x5ffe, 0x761e, 0x6058, 0xa07d,
 	0x0040, 0x6003, 0x7e56, 0xa6ed, 0x0000, 0x0040, 0x6009, 0x2f00,
@@ -2619,10 +2619,10 @@ unsigned short risc_code01[] = { 
 	0x037e, 0x2069, 0x0140, 0x6b04, 0xa384, 0x1000, 0x0040, 0x603c,
 	0x6803, 0x0100, 0x6803, 0x0000, 0x2069, 0x0100, 0x6824, 0xd084,
 	0x0040, 0x6044, 0x6827, 0x0001, 0x037f, 0x0d7f, 0x0c7e, 0x603c,
-	0xa005, 0x0040, 0x604d, 0x8001, 0x603e, 0x2660, 0x1078, 0x8ec6,
+	0xa005, 0x0040, 0x604d, 0x8001, 0x603e, 0x2660, 0x1078, 0x8ed6,
 	0x0c7f, 0x0078, 0x605c, 0x0d7f, 0x0c7e, 0x2660, 0x6003, 0x0009,
 	0x630a, 0x0c7f, 0x0078, 0x6011, 0x8dff, 0x0040, 0x606a, 0x6837,
-	0x0103, 0x6b4a, 0x6847, 0x0000, 0x1078, 0x8f7d, 0x1078, 0xa4e2,
+	0x0103, 0x6b4a, 0x6847, 0x0000, 0x1078, 0x8f8d, 0x1078, 0xa4f2,
 	0x1078, 0x4a73, 0x1078, 0x7233, 0x0078, 0x6011, 0x067f, 0x0d7f,
 	0x0e7f, 0x0f7f, 0x127f, 0x007f, 0x0c7f, 0x007c, 0x007e, 0x067e,
 	0x0c7e, 0x0d7e, 0x2031, 0x0000, 0x7814, 0xa065, 0x0040, 0x60d0,
@@ -2633,11 +2633,11 @@ unsigned short risc_code01[] = { 
 	0x6803, 0x0100, 0x6803, 0x0000, 0x2069, 0x0100, 0x6824, 0xd084,
 	0x0040, 0x60ac, 0x6827, 0x0001, 0x037f, 0x0078, 0x60b5, 0x6003,
 	0x0009, 0x630a, 0x2c30, 0x0078, 0x60cd, 0x6010, 0x2068, 0x1078,
-	0x8d06, 0x0040, 0x60c9, 0x601c, 0xa086, 0x0003, 0x00c0, 0x60d7,
+	0x8d16, 0x0040, 0x60c9, 0x601c, 0xa086, 0x0003, 0x00c0, 0x60d7,
 	0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x1078, 0x4a73, 0x1078,
-	0x8eb9, 0x1078, 0x8ec6, 0x1078, 0x7233, 0x007f, 0x0078, 0x607d,
+	0x8ec9, 0x1078, 0x8ed6, 0x1078, 0x7233, 0x007f, 0x0078, 0x607d,
 	0x7e16, 0x7e12, 0x0d7f, 0x0c7f, 0x067f, 0x007f, 0x007c, 0x601c,
-	0xa086, 0x0006, 0x00c0, 0x60e0, 0x1078, 0xa1ca, 0x0078, 0x60c9,
+	0xa086, 0x0006, 0x00c0, 0x60e0, 0x1078, 0xa1da, 0x0078, 0x60c9,
 	0x601c, 0xa086, 0x0002, 0x00c0, 0x60c9, 0x6004, 0xa086, 0x0085,
 	0x0040, 0x60c0, 0x0078, 0x60c9, 0x007e, 0x067e, 0x0c7e, 0x0d7e,
 	0x7818, 0xa065, 0x0040, 0x615a, 0x6054, 0x007e, 0x6057, 0x0000,
@@ -2649,14 +2649,14 @@ unsigned short risc_code01[] = { 
 	0x6b04, 0xa384, 0x1000, 0x0040, 0x6129, 0x6803, 0x0100, 0x6803,
 	0x0000, 0x2069, 0x0100, 0x6824, 0xd084, 0x0040, 0x6131, 0x6827,
 	0x0001, 0x037f, 0x0d7f, 0x0c7e, 0x603c, 0xa005, 0x0040, 0x613a,
-	0x8001, 0x603e, 0x2660, 0x1078, 0x8ec6, 0x0c7f, 0x0078, 0x6149,
+	0x8001, 0x603e, 0x2660, 0x1078, 0x8ed6, 0x0c7f, 0x0078, 0x6149,
 	0x0d7f, 0x0c7e, 0x2660, 0x6003, 0x0009, 0x630a, 0x0c7f, 0x0078,
 	0x60fe, 0x8dff, 0x0040, 0x6153, 0x6837, 0x0103, 0x6b4a, 0x6847,
 	0x0000, 0x1078, 0x4a73, 0x1078, 0x7233, 0x0078, 0x60fe, 0x007f,
 	0x0078, 0x60f1, 0x781e, 0x781a, 0x0d7f, 0x0c7f, 0x067f, 0x007f,
 	0x007c, 0x0e7e, 0x0d7e, 0x067e, 0x6000, 0xd0dc, 0x0040, 0x6181,
 	0x604c, 0xa06d, 0x0040, 0x6181, 0x6848, 0xa606, 0x00c0, 0x6181,
-	0x2071, 0xa8b1, 0x7024, 0xa035, 0x0040, 0x6181, 0xa080, 0x0004,
+	0x2071, 0xa9b1, 0x7024, 0xa035, 0x0040, 0x6181, 0xa080, 0x0004,
 	0x2004, 0xad06, 0x00c0, 0x6181, 0x6000, 0xc0dc, 0x6002, 0x1078,
 	0x6185, 0x067f, 0x0d7f, 0x0e7f, 0x007c, 0x0f7e, 0x2079, 0x0100,
 	0x78c0, 0xa005, 0x00c0, 0x6194, 0x0c7e, 0x2660, 0x6003, 0x0009,
@@ -2666,9 +2666,9 @@ unsigned short risc_code01[] = { 
 	0x2079, 0x0100, 0x7824, 0xd084, 0x0040, 0x61b0, 0x7827, 0x0001,
 	0x1078, 0x7378, 0x037f, 0x1078, 0x44d3, 0x0c7e, 0x603c, 0xa005,
 	0x0040, 0x61bc, 0x8001, 0x603e, 0x2660, 0x1078, 0x772d, 0x0c7f,
-	0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x1078, 0x8f7d, 0x1078,
+	0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x1078, 0x8f8d, 0x1078,
 	0x4a73, 0x1078, 0x7233, 0x0f7f, 0x007c, 0x0e7e, 0x0c7e, 0x2071,
-	0xa8b1, 0x7004, 0xa084, 0x0007, 0x0079, 0x61d6, 0x61e0, 0x61e3,
+	0xa9b1, 0x7004, 0xa084, 0x0007, 0x0079, 0x61d6, 0x61e0, 0x61e3,
 	0x61fc, 0x6218, 0x6262, 0x61e0, 0x61e0, 0x61de, 0x1078, 0x1332,
 	0x0c7f, 0x0e7f, 0x007c, 0x7024, 0xa065, 0x0040, 0x61f1, 0x7020,
 	0x8001, 0x7022, 0x600c, 0xa015, 0x0040, 0x61f8, 0x7216, 0x600f,
@@ -2689,18 +2689,18 @@ unsigned short risc_code01[] = { 
 	0x0e7f, 0x007c, 0x7024, 0xa065, 0x0040, 0x626f, 0x1078, 0x7233,
 	0x600c, 0xa015, 0x0040, 0x6276, 0x720e, 0x600f, 0x0000, 0x1078,
 	0x7378, 0x7027, 0x0000, 0x0c7f, 0x0e7f, 0x007c, 0x720e, 0x720a,
-	0x0078, 0x626f, 0x0d7e, 0x2069, 0xa8b1, 0x6830, 0xa084, 0x0003,
+	0x0078, 0x626f, 0x0d7e, 0x2069, 0xa9b1, 0x6830, 0xa084, 0x0003,
 	0x0079, 0x6282, 0x6288, 0x628a, 0x62b4, 0x6288, 0x1078, 0x1332,
 	0x0d7f, 0x007c, 0x0c7e, 0x6840, 0xa086, 0x0001, 0x0040, 0x62aa,
 	0x683c, 0xa065, 0x0040, 0x629b, 0x600c, 0xa015, 0x0040, 0x62a6,
 	0x6a3a, 0x600f, 0x0000, 0x6833, 0x0000, 0x683f, 0x0000, 0x2011,
-	0xa8d0, 0x2013, 0x0000, 0x0c7f, 0x0d7f, 0x007c, 0x683a, 0x6836,
+	0xa9d0, 0x2013, 0x0000, 0x0c7f, 0x0d7f, 0x007c, 0x683a, 0x6836,
 	0x0078, 0x629b, 0x6843, 0x0000, 0x6838, 0xa065, 0x0040, 0x629b,
 	0x6003, 0x0003, 0x0078, 0x629b, 0x0c7e, 0x6843, 0x0000, 0x6847,
 	0x0000, 0x684b, 0x0000, 0x683c, 0xa065, 0x0040, 0x62ce, 0x600c,
 	0xa015, 0x0040, 0x62ca, 0x6a3a, 0x600f, 0x0000, 0x683f, 0x0000,
 	0x0078, 0x62ce, 0x683f, 0x0000, 0x683a, 0x6836, 0x0c7f, 0x0d7f,
-	0x007c, 0x0d7e, 0x2069, 0xa8b1, 0x6804, 0xa084, 0x0007, 0x0079,
+	0x007c, 0x0d7e, 0x2069, 0xa9b1, 0x6804, 0xa084, 0x0007, 0x0079,
 	0x62d9, 0x62e3, 0x638a, 0x638a, 0x638a, 0x638a, 0x638c, 0x638a,
 	0x62e1, 0x1078, 0x1332, 0x6820, 0xa005, 0x00c0, 0x62e9, 0x0d7f,
 	0x007c, 0x0c7e, 0x680c, 0xa065, 0x0040, 0x62f8, 0x6807, 0x0004,
@@ -2725,7 +2725,7 @@ unsigned short risc_code01[] = { 
 	0x0f7f, 0x0e7f, 0x0c7f, 0x0d7f, 0x007c, 0x037f, 0x0e7f, 0x0c7f,
 	0x0078, 0x6383, 0x0d7f, 0x007c, 0x0c7e, 0x680c, 0xa065, 0x0040,
 	0x6398, 0x6807, 0x0004, 0x6826, 0x682b, 0x0000, 0x1078, 0x63d4,
-	0x0c7f, 0x0d7f, 0x007c, 0x0f7e, 0x0d7e, 0x2069, 0xa8b1, 0x6830,
+	0x0c7f, 0x0d7f, 0x007c, 0x0f7e, 0x0d7e, 0x2069, 0xa9b1, 0x6830,
 	0xa086, 0x0000, 0x00c0, 0x63bb, 0x6838, 0xa07d, 0x0040, 0x63bb,
 	0x6833, 0x0001, 0x683e, 0x6847, 0x0000, 0x684b, 0x0000, 0x127e,
 	0x0f7e, 0x2091, 0x2200, 0x027f, 0x1078, 0x1d6d, 0x00c0, 0x63be,
@@ -2763,42 +2763,42 @@ unsigned short risc_code01[] = { 
 	0x20a2, 0x6814, 0x20a2, 0x6818, 0x20a2, 0x681c, 0x20a2, 0x60c3,
 	0x0010, 0x1078, 0x6dfb, 0x0d7f, 0x007c, 0x6030, 0x609a, 0x1078,
 	0x6dfb, 0x007c, 0x20a1, 0x020b, 0x1078, 0x6731, 0x20a3, 0x5200,
-	0x20a3, 0x0000, 0x0d7e, 0x2069, 0xa652, 0x6804, 0xd084, 0x0040,
+	0x20a3, 0x0000, 0x0d7e, 0x2069, 0xa752, 0x6804, 0xd084, 0x0040,
 	0x64dc, 0x6828, 0x20a3, 0x0000, 0x017e, 0x1078, 0x2564, 0x21a2,
 	0x017f, 0x0d7f, 0x0078, 0x64e1, 0x0d7f, 0x20a3, 0x0000, 0x20a3,
-	0x0000, 0x20a9, 0x0004, 0x2099, 0xa605, 0x53a6, 0x20a9, 0x0004,
-	0x2099, 0xa601, 0x53a6, 0x7818, 0xa080, 0x0028, 0x2004, 0xa082,
-	0x007f, 0x0048, 0x64fb, 0x2001, 0xa61b, 0x20a6, 0x2001, 0xa61c,
+	0x0000, 0x20a9, 0x0004, 0x2099, 0xa705, 0x53a6, 0x20a9, 0x0004,
+	0x2099, 0xa701, 0x53a6, 0x7818, 0xa080, 0x0028, 0x2004, 0xa082,
+	0x007f, 0x0048, 0x64fb, 0x2001, 0xa71b, 0x20a6, 0x2001, 0xa71c,
 	0x20a6, 0x0078, 0x6501, 0x20a3, 0x0000, 0x6030, 0xa084, 0x00ff,
 	0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x001c, 0x1078,
 	0x6dfb, 0x007c, 0x20a1, 0x020b, 0x1078, 0x6731, 0x20a3, 0x0500,
 	0x20a3, 0x0000, 0x7818, 0xa080, 0x0028, 0x2004, 0xa082, 0x007f,
-	0x0048, 0x6522, 0x2001, 0xa61b, 0x20a6, 0x2001, 0xa61c, 0x20a6,
+	0x0048, 0x6522, 0x2001, 0xa71b, 0x20a6, 0x2001, 0xa71c, 0x20a6,
 	0x0078, 0x6528, 0x20a3, 0x0000, 0x6030, 0xa084, 0x00ff, 0x20a2,
-	0x20a9, 0x0004, 0x2099, 0xa605, 0x53a6, 0x60c3, 0x0010, 0x1078,
+	0x20a9, 0x0004, 0x2099, 0xa705, 0x53a6, 0x60c3, 0x0010, 0x1078,
 	0x6dfb, 0x007c, 0x20a1, 0x020b, 0x1078, 0x6731, 0x0c7e, 0x7818,
 	0x2060, 0x2001, 0x0000, 0x1078, 0x4972, 0x0c7f, 0x7818, 0xa080,
 	0x0028, 0x2004, 0xa086, 0x007e, 0x00c0, 0x654d, 0x20a3, 0x0400,
 	0x620c, 0xc2b4, 0x620e, 0x0078, 0x654f, 0x20a3, 0x0300, 0x20a3,
 	0x0000, 0x7818, 0xa080, 0x0028, 0x2004, 0xa086, 0x007e, 0x00c0,
-	0x659c, 0x2099, 0xa88d, 0x33a6, 0x9398, 0x33a6, 0x9398, 0x3304,
+	0x659c, 0x2099, 0xa98d, 0x33a6, 0x9398, 0x33a6, 0x9398, 0x3304,
 	0xa084, 0x3fff, 0x20a2, 0x9398, 0x33a6, 0x20a3, 0x0000, 0x20a3,
 	0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a9, 0x0004, 0x2099,
-	0xa605, 0x53a6, 0x20a9, 0x0004, 0x2099, 0xa601, 0x53a6, 0x20a9,
-	0x0010, 0x20a3, 0x0000, 0x00f0, 0x6579, 0x2099, 0xa895, 0x3304,
-	0xc0dd, 0x20a2, 0x2001, 0xa672, 0x2004, 0xd0e4, 0x0040, 0x6594,
+	0xa705, 0x53a6, 0x20a9, 0x0004, 0x2099, 0xa701, 0x53a6, 0x20a9,
+	0x0010, 0x20a3, 0x0000, 0x00f0, 0x6579, 0x2099, 0xa995, 0x3304,
+	0xc0dd, 0x20a2, 0x2001, 0xa772, 0x2004, 0xd0e4, 0x0040, 0x6594,
 	0x20a3, 0x0000, 0x20a3, 0x0000, 0x9398, 0x9398, 0x9398, 0x33a6,
 	0x20a9, 0x0004, 0x0078, 0x6596, 0x20a9, 0x0007, 0x20a3, 0x0000,
-	0x00f0, 0x6596, 0x0078, 0x65bc, 0x2099, 0xa88d, 0x20a9, 0x0008,
-	0x53a6, 0x20a9, 0x0004, 0x2099, 0xa605, 0x53a6, 0x20a9, 0x0004,
-	0x2099, 0xa601, 0x53a6, 0x20a9, 0x0008, 0x20a3, 0x0000, 0x00f0,
+	0x00f0, 0x6596, 0x0078, 0x65bc, 0x2099, 0xa98d, 0x20a9, 0x0008,
+	0x53a6, 0x20a9, 0x0004, 0x2099, 0xa705, 0x53a6, 0x20a9, 0x0004,
+	0x2099, 0xa701, 0x53a6, 0x20a9, 0x0008, 0x20a3, 0x0000, 0x00f0,
 	0x65ad, 0x20a9, 0x0008, 0x20a3, 0x0000, 0x00f0, 0x65b3, 0x2099,
-	0xa895, 0x20a9, 0x0008, 0x53a6, 0x20a9, 0x0008, 0x20a3, 0x0000,
+	0xa995, 0x20a9, 0x0008, 0x53a6, 0x20a9, 0x0008, 0x20a3, 0x0000,
 	0x00f0, 0x65be, 0x20a9, 0x000a, 0x20a3, 0x0000, 0x00f0, 0x65c4,
 	0x60c3, 0x0074, 0x1078, 0x6dfb, 0x007c, 0x20a1, 0x020b, 0x1078,
 	0x6731, 0x20a3, 0x2010, 0x20a3, 0x0014, 0x20a3, 0x0800, 0x20a3,
 	0x2000, 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x0f7e,
-	0x2079, 0xa652, 0x7904, 0x0f7f, 0xd1ac, 0x00c0, 0x65e9, 0xa085,
+	0x2079, 0xa752, 0x7904, 0x0f7f, 0xd1ac, 0x00c0, 0x65e9, 0xa085,
 	0x0020, 0xd1a4, 0x0040, 0x65ee, 0xa085, 0x0010, 0xa085, 0x0002,
 	0x0d7e, 0x0078, 0x66b7, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000,
 	0x60c3, 0x0014, 0x1078, 0x6dfb, 0x007c, 0x20a1, 0x020b, 0x1078,
@@ -2821,11 +2821,11 @@ unsigned short risc_code01[] = { 
 	0x6998, 0xa184, 0xc000, 0x00c0, 0x6690, 0xd1ec, 0x0040, 0x668c,
 	0x20a3, 0x2100, 0x0078, 0x6696, 0x20a3, 0x0100, 0x0078, 0x6696,
 	0x20a3, 0x0400, 0x0078, 0x6696, 0x20a3, 0x0700, 0xa006, 0x20a2,
-	0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x0f7e, 0x2079, 0xa652, 0x7904,
+	0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x0f7e, 0x2079, 0xa752, 0x7904,
 	0x0f7f, 0xd1ac, 0x00c0, 0x66a6, 0xa085, 0x0020, 0xd1a4, 0x0040,
-	0x66ab, 0xa085, 0x0010, 0x2009, 0xa674, 0x210c, 0xd184, 0x0040,
+	0x66ab, 0xa085, 0x0010, 0x2009, 0xa774, 0x210c, 0xd184, 0x0040,
 	0x66b5, 0x699c, 0xd18c, 0x0040, 0x66b7, 0xa085, 0x0002, 0x027e,
-	0x2009, 0xa672, 0x210c, 0xd1e4, 0x0040, 0x66c5, 0xc0c5, 0xa094,
+	0x2009, 0xa772, 0x210c, 0xd1e4, 0x0040, 0x66c5, 0xc0c5, 0xa094,
 	0x0030, 0xa296, 0x0010, 0x0040, 0x66cf, 0xd1ec, 0x0040, 0x66cf,
 	0xa094, 0x0030, 0xa296, 0x0010, 0x0040, 0x66cf, 0xc0bd, 0x027f,
 	0x20a2, 0x20a2, 0x20a2, 0x60c3, 0x0014, 0x1078, 0x6dfb, 0x0d7f,
@@ -2846,24 +2846,24 @@ unsigned short risc_code01[] = { 
 	0xfffe, 0x0078, 0x6780, 0xa286, 0x007f, 0x00c0, 0x6757, 0x0d7e,
 	0xa385, 0x00ff, 0x20a2, 0x20a3, 0xfffd, 0x0078, 0x676e, 0xd2bc,
 	0x0040, 0x6776, 0xa286, 0x0080, 0x0d7e, 0x00c0, 0x6766, 0xa385,
-	0x00ff, 0x20a2, 0x20a3, 0xfffc, 0x0078, 0x676e, 0xa2e8, 0xa735,
-	0x2d6c, 0x6810, 0xa305, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xa61b,
+	0x00ff, 0x20a2, 0x20a3, 0xfffc, 0x0078, 0x676e, 0xa2e8, 0xa835,
+	0x2d6c, 0x6810, 0xa305, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xa71b,
 	0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x6784, 0x0d7e, 0xa2e8,
-	0xa735, 0x2d6c, 0x6810, 0xa305, 0x20a2, 0x6814, 0x20a2, 0x0d7f,
+	0xa835, 0x2d6c, 0x6810, 0xa305, 0x20a2, 0x6814, 0x20a2, 0x0d7f,
 	0x20a3, 0x0000, 0x6230, 0x22a2, 0xa485, 0x0029, 0x20a2, 0x047f,
 	0x037f, 0x20a3, 0x0000, 0x1078, 0x6dea, 0x22a2, 0x20a3, 0x0000,
 	0x2fa2, 0x20a3, 0xffff, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x027f,
 	0x007c, 0x027e, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x20a3, 0x02ff,
-	0x2011, 0xfffc, 0x22a2, 0x0d7e, 0x2069, 0xa61b, 0x2da6, 0x8d68,
+	0x2011, 0xfffc, 0x22a2, 0x0d7e, 0x2069, 0xa71b, 0x2da6, 0x8d68,
 	0x2da6, 0x0d7f, 0x20a3, 0x2029, 0x20a3, 0x0000, 0x0078, 0x678b,
 	0x20a3, 0x0100, 0x20a3, 0x0000, 0x20a3, 0xfc02, 0x20a3, 0x0000,
 	0x007c, 0x027e, 0x037e, 0x047e, 0x2019, 0x3300, 0x2021, 0x0800,
 	0x0078, 0x67c9, 0x027e, 0x037e, 0x047e, 0x2019, 0x2300, 0x2021,
 	0x0100, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028,
-	0x2004, 0xa092, 0x007e, 0x0048, 0x67e6, 0x0d7e, 0xa0e8, 0xa735,
-	0x2d6c, 0x6810, 0xa305, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xa61b,
+	0x2004, 0xa092, 0x007e, 0x0048, 0x67e6, 0x0d7e, 0xa0e8, 0xa835,
+	0x2d6c, 0x6810, 0xa305, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xa71b,
 	0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x67f4, 0x0d7e, 0xa0e8,
-	0xa735, 0x2d6c, 0x6810, 0xa305, 0x20a2, 0x6814, 0x20a2, 0x0d7f,
+	0xa835, 0x2d6c, 0x6810, 0xa305, 0x20a2, 0x6814, 0x20a2, 0x0d7f,
 	0x20a3, 0x0000, 0x6230, 0x22a2, 0xa485, 0x0098, 0x20a2, 0x20a3,
 	0x0000, 0x047f, 0x037f, 0x1078, 0x6dea, 0x22a2, 0x20a3, 0x0000,
 	0x7a08, 0x22a2, 0x2fa2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x027f,
@@ -2883,23 +2883,23 @@ unsigned short risc_code01[] = { 
 	0x0000, 0x20a3, 0x0000, 0x60c3, 0x0004, 0x1078, 0x6dfb, 0x147f,
 	0x007c, 0x027e, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080,
 	0x0028, 0x2004, 0xa092, 0x007e, 0x0048, 0x6898, 0x0d7e, 0xa0e8,
-	0xa735, 0x2d6c, 0x6810, 0xa085, 0x8100, 0x20a2, 0x6814, 0x20a2,
-	0x2069, 0xa61b, 0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x68a7,
-	0x0d7e, 0xa0e8, 0xa735, 0x2d6c, 0x6810, 0xa085, 0x8100, 0x20a2,
+	0xa835, 0x2d6c, 0x6810, 0xa085, 0x8100, 0x20a2, 0x6814, 0x20a2,
+	0x2069, 0xa71b, 0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x68a7,
+	0x0d7e, 0xa0e8, 0xa835, 0x2d6c, 0x6810, 0xa085, 0x8100, 0x20a2,
 	0x6814, 0x20a2, 0x0d7f, 0x20a3, 0x0000, 0x6230, 0x22a2, 0x20a3,
 	0x0009, 0x20a3, 0x0000, 0x0078, 0x678b, 0x027e, 0x20e1, 0x9080,
 	0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2004, 0xa092, 0x007e,
-	0x0048, 0x68cc, 0x0d7e, 0xa0e8, 0xa735, 0x2d6c, 0x6810, 0xa085,
-	0x8400, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xa61b, 0x2da6, 0x8d68,
-	0x2da6, 0x0d7f, 0x0078, 0x68db, 0x0d7e, 0xa0e8, 0xa735, 0x2d6c,
+	0x0048, 0x68cc, 0x0d7e, 0xa0e8, 0xa835, 0x2d6c, 0x6810, 0xa085,
+	0x8400, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xa71b, 0x2da6, 0x8d68,
+	0x2da6, 0x0d7f, 0x0078, 0x68db, 0x0d7e, 0xa0e8, 0xa835, 0x2d6c,
 	0x6810, 0xa085, 0x8400, 0x20a2, 0x6814, 0x20a2, 0x0d7f, 0x20a3,
 	0x0000, 0x6230, 0x22a2, 0x20a3, 0x0099, 0x20a3, 0x0000, 0x1078,
 	0x6dea, 0x22a2, 0x20a3, 0x0000, 0x7a08, 0x22a2, 0x7a10, 0x22a2,
 	0x20a3, 0x0000, 0x20a3, 0x0000, 0x027f, 0x007c, 0x027e, 0x20e1,
 	0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2004, 0xa092,
-	0x007e, 0x0048, 0x690d, 0x0d7e, 0xa0e8, 0xa735, 0x2d6c, 0x6810,
-	0xa085, 0x8500, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xa61b, 0x2da6,
-	0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x691c, 0x0d7e, 0xa0e8, 0xa735,
+	0x007e, 0x0048, 0x690d, 0x0d7e, 0xa0e8, 0xa835, 0x2d6c, 0x6810,
+	0xa085, 0x8500, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xa71b, 0x2da6,
+	0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x691c, 0x0d7e, 0xa0e8, 0xa835,
 	0x2d6c, 0x6810, 0xa085, 0x8500, 0x20a2, 0x6814, 0x20a2, 0x0d7f,
 	0x20a3, 0x0000, 0x6230, 0x22a2, 0x20a3, 0x0099, 0x20a3, 0x0000,
 	0x0078, 0x68df, 0x0c7e, 0x0f7e, 0x2c78, 0x7804, 0xa08a, 0x0040,
@@ -2921,15 +2921,15 @@ unsigned short risc_code01[] = { 
 	0x69a6, 0x20a3, 0x0000, 0x2230, 0x0078, 0x69a8, 0x6a80, 0x6e7c,
 	0x20a9, 0x0008, 0xad80, 0x0017, 0x200c, 0x810f, 0x21a2, 0x8000,
 	0x00f0, 0x69ac, 0x22a2, 0x26a2, 0x60c3, 0x0020, 0x20e1, 0x9080,
-	0x6014, 0xa084, 0x0004, 0xa085, 0x0009, 0x6016, 0x2001, 0xa8cd,
-	0x2003, 0x07d0, 0x2001, 0xa8cc, 0x2003, 0x0009, 0x2001, 0xa8d2,
+	0x6014, 0xa084, 0x0004, 0xa085, 0x0009, 0x6016, 0x2001, 0xa9cd,
+	0x2003, 0x07d0, 0x2001, 0xa9cc, 0x2003, 0x0009, 0x2001, 0xa9d2,
 	0x2003, 0x0002, 0x1078, 0x158c, 0x147f, 0x157f, 0x0d7f, 0x007c,
 	0x20e1, 0x9080, 0x20e1, 0x4000, 0x7a18, 0xa280, 0x0023, 0x2014,
 	0x8210, 0xa294, 0x00ff, 0x2202, 0x8217, 0x7818, 0xa080, 0x0028,
-	0x2004, 0xd0bc, 0x0040, 0x69f6, 0x0d7e, 0xa0e8, 0xa735, 0x2d6c,
-	0x6810, 0xa085, 0x0600, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xa61b,
+	0x2004, 0xd0bc, 0x0040, 0x69f6, 0x0d7e, 0xa0e8, 0xa835, 0x2d6c,
+	0x6810, 0xa085, 0x0600, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xa71b,
 	0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x6a05, 0x0d7e, 0xa0e8,
-	0xa735, 0x2d6c, 0x6810, 0xa085, 0x0600, 0x20a2, 0x6814, 0x20a2,
+	0xa835, 0x2d6c, 0x6810, 0xa085, 0x0600, 0x20a2, 0x6814, 0x20a2,
 	0x0d7f, 0x20a3, 0x0000, 0x6130, 0x21a2, 0x20a3, 0x0829, 0x20a3,
 	0x0000, 0x22a2, 0x20a3, 0x0000, 0x2fa2, 0x20a3, 0xffff, 0x20a3,
 	0x0000, 0x20a3, 0x0000, 0x007c, 0x0d7e, 0x157e, 0x137e, 0x147e,
@@ -2938,9 +2938,9 @@ unsigned short risc_code01[] = { 
 	0x20a2, 0x20a2, 0x20a2, 0x60c3, 0x000c, 0x1078, 0x6dfb, 0x147f,
 	0x137f, 0x157f, 0x0d7f, 0x007c, 0x027e, 0x20e1, 0x9080, 0x20e1,
 	0x4000, 0x7818, 0xa080, 0x0028, 0x2004, 0xd0bc, 0x0040, 0x6a52,
-	0x0d7e, 0xa0e8, 0xa735, 0x2d6c, 0x6810, 0xa085, 0x0500, 0x20a2,
-	0x6814, 0x20a2, 0x2069, 0xa61b, 0x2da6, 0x8d68, 0x2da6, 0x0d7f,
-	0x0078, 0x6a61, 0x0d7e, 0xa0e8, 0xa735, 0x2d6c, 0x6810, 0xa085,
+	0x0d7e, 0xa0e8, 0xa835, 0x2d6c, 0x6810, 0xa085, 0x0500, 0x20a2,
+	0x6814, 0x20a2, 0x2069, 0xa71b, 0x2da6, 0x8d68, 0x2da6, 0x0d7f,
+	0x0078, 0x6a61, 0x0d7e, 0xa0e8, 0xa835, 0x2d6c, 0x6810, 0xa085,
 	0x0500, 0x20a2, 0x6814, 0x20a2, 0x0d7f, 0x20a3, 0x0000, 0x6230,
 	0x22a2, 0x20a3, 0x0889, 0x20a3, 0x0000, 0x1078, 0x6dea, 0x22a2,
 	0x20a3, 0x0000, 0x7a08, 0x22a2, 0x2fa2, 0x20a3, 0x0000, 0x20a3,
@@ -2964,10 +2964,10 @@ unsigned short risc_code01[] = { 
 	0x201c, 0x831f, 0x23a2, 0x8000, 0x00f0, 0x6af8, 0x157f, 0x22a2,
 	0x22a2, 0x22a2, 0xa184, 0x0003, 0x0040, 0x6b46, 0x20a1, 0x020b,
 	0x20e1, 0x9080, 0x20e1, 0x4000, 0x007e, 0x7818, 0xa080, 0x0028,
-	0x2004, 0xd0bc, 0x0040, 0x6b26, 0x0d7e, 0xa0e8, 0xa735, 0x2d6c,
-	0x6810, 0xa085, 0x0700, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xa61b,
+	0x2004, 0xd0bc, 0x0040, 0x6b26, 0x0d7e, 0xa0e8, 0xa835, 0x2d6c,
+	0x6810, 0xa085, 0x0700, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xa71b,
 	0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x6b35, 0x0d7e, 0xa0e8,
-	0xa735, 0x2d6c, 0x6810, 0xa085, 0x0700, 0x20a2, 0x6814, 0x20a2,
+	0xa835, 0x2d6c, 0x6810, 0xa085, 0x0700, 0x20a2, 0x6814, 0x20a2,
 	0x0d7f, 0x20a3, 0x0000, 0x6230, 0x22a2, 0x007f, 0x7b24, 0xd3cc,
 	0x0040, 0x6b3e, 0x20a3, 0x0889, 0x0078, 0x6b40, 0x20a3, 0x0898,
 	0x20a2, 0x1078, 0x6dea, 0x22a2, 0x20a3, 0x0000, 0x61c2, 0x037f,
@@ -2991,10 +2991,10 @@ unsigned short risc_code01[] = { 
 	0x2021, 0x0800, 0x007e, 0x7824, 0xd0cc, 0x007f, 0x0040, 0x6bd9,
 	0xc4e5, 0x24a2, 0x047f, 0x22a2, 0x20a2, 0x037f, 0x0078, 0x6b8c,
 	0x027e, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028,
-	0x2004, 0xd0bc, 0x0040, 0x6bfe, 0x0d7e, 0xa0e8, 0xa735, 0x2d6c,
-	0x6810, 0xa085, 0x0700, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xa61b,
+	0x2004, 0xd0bc, 0x0040, 0x6bfe, 0x0d7e, 0xa0e8, 0xa835, 0x2d6c,
+	0x6810, 0xa085, 0x0700, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xa71b,
 	0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x6c0d, 0x0d7e, 0xa0e8,
-	0xa735, 0x2d6c, 0x6810, 0xa085, 0x0700, 0x20a2, 0x6814, 0x20a2,
+	0xa835, 0x2d6c, 0x6810, 0xa085, 0x0700, 0x20a2, 0x6814, 0x20a2,
 	0x0d7f, 0x20a3, 0x0000, 0x6230, 0x22a2, 0x7824, 0xd0cc, 0x0040,
 	0x6c15, 0x20a3, 0x0889, 0x0078, 0x6c17, 0x20a3, 0x0898, 0x20a3,
 	0x0000, 0x1078, 0x6dea, 0x22a2, 0x20a3, 0x0000, 0x7a08, 0x22a2,
@@ -3004,20 +3004,20 @@ unsigned short risc_code01[] = { 
 	0x0d7f, 0x007c, 0x6c42, 0x6c42, 0x6c44, 0x6c42, 0x6c42, 0x6c42,
 	0x6c69, 0x6c42, 0x1078, 0x1332, 0x7910, 0xa18c, 0xf8ff, 0xa18d,
 	0x0600, 0x7912, 0x20a1, 0x020b, 0x2009, 0x0003, 0x1078, 0x6c73,
-	0x0d7e, 0x2069, 0xa652, 0x6804, 0xd0bc, 0x0040, 0x6c5e, 0x682c,
+	0x0d7e, 0x2069, 0xa752, 0x6804, 0xd0bc, 0x0040, 0x6c5e, 0x682c,
 	0xa084, 0x00ff, 0x8007, 0x20a2, 0x0078, 0x6c60, 0x20a3, 0x3f00,
 	0x0d7f, 0x22a2, 0x22a2, 0x22a2, 0x60c3, 0x0001, 0x1078, 0x6dfb,
 	0x007c, 0x20a1, 0x020b, 0x2009, 0x0003, 0x1078, 0x6c73, 0x20a3,
 	0x7f00, 0x0078, 0x6c61, 0x027e, 0x20e1, 0x9080, 0x20e1, 0x4000,
 	0x7818, 0xa080, 0x0028, 0x2004, 0xd0bc, 0x0040, 0x6c91, 0x0d7e,
-	0xa0e8, 0xa735, 0x2d6c, 0x6810, 0xa085, 0x0100, 0x20a2, 0x6814,
-	0x20a2, 0x2069, 0xa61b, 0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078,
-	0x6ca0, 0x0d7e, 0xa0e8, 0xa735, 0x2d6c, 0x6810, 0xa085, 0x0100,
+	0xa0e8, 0xa835, 0x2d6c, 0x6810, 0xa085, 0x0100, 0x20a2, 0x6814,
+	0x20a2, 0x2069, 0xa71b, 0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078,
+	0x6ca0, 0x0d7e, 0xa0e8, 0xa835, 0x2d6c, 0x6810, 0xa085, 0x0100,
 	0x20a2, 0x6814, 0x20a2, 0x0d7f, 0x20a3, 0x0000, 0x6230, 0x22a2,
 	0x20a3, 0x0888, 0xa18d, 0x0008, 0x21a2, 0x1078, 0x6dea, 0x22a2,
 	0x20a3, 0x0000, 0x7a08, 0x22a2, 0x2fa2, 0x20a3, 0x0000, 0x20a3,
 	0x0000, 0x027f, 0x007c, 0x0e7e, 0x0d7e, 0x0c7e, 0x057e, 0x047e,
-	0x037e, 0x2061, 0x0100, 0x2071, 0xa600, 0x6130, 0x7818, 0x2068,
+	0x037e, 0x2061, 0x0100, 0x2071, 0xa700, 0x6130, 0x7818, 0x2068,
 	0x68a0, 0x2028, 0xd0bc, 0x00c0, 0x6cca, 0x6910, 0x6a14, 0x6430,
 	0x0078, 0x6cce, 0x6910, 0x6a14, 0x736c, 0x7470, 0x781c, 0xa086,
 	0x0006, 0x0040, 0x6d2d, 0xd5bc, 0x0040, 0x6cde, 0xa185, 0x0100,
@@ -3056,7 +3056,7 @@ unsigned short risc_code01[] = { 
 	0x00ff, 0x0078, 0x6ddd, 0x2011, 0x0000, 0x629e, 0x7824, 0xd0cc,
 	0x0040, 0x6de6, 0x6017, 0x0016, 0x0078, 0x6d1a, 0x6017, 0x0012,
 	0x0078, 0x6d1a, 0x7a18, 0xa280, 0x0023, 0x2014, 0x8210, 0xa294,
-	0x00ff, 0x2202, 0x8217, 0x007c, 0x0d7e, 0x2069, 0xa8b1, 0x6843,
+	0x00ff, 0x2202, 0x8217, 0x007c, 0x0d7e, 0x2069, 0xa9b1, 0x6843,
 	0x0001, 0x0d7f, 0x007c, 0x20e1, 0x9080, 0x60a3, 0x0056, 0x60a7,
 	0x9575, 0x1078, 0x6e06, 0x1078, 0x5ac0, 0x007c, 0x007e, 0x6014,
 	0xa084, 0x0004, 0xa085, 0x0009, 0x6016, 0x007f, 0x007c, 0x007e,
@@ -3064,26 +3064,26 @@ unsigned short risc_code01[] = { 
 	0x6016, 0x0c7f, 0x007f, 0x007c, 0x0c7e, 0x0d7e, 0x017e, 0x027e,
 	0x2061, 0x0100, 0x2069, 0x0140, 0x6904, 0xa194, 0x4000, 0x0040,
 	0x6e59, 0x1078, 0x6e0f, 0x6803, 0x1000, 0x6803, 0x0000, 0x0c7e,
-	0x2061, 0xa8b1, 0x6128, 0xa192, 0x00c8, 0x00c8, 0x6e44, 0x8108,
+	0x2061, 0xa9b1, 0x6128, 0xa192, 0x00c8, 0x00c8, 0x6e44, 0x8108,
 	0x612a, 0x6124, 0x0c7f, 0x81ff, 0x0040, 0x6e54, 0x1078, 0x5ac0,
 	0x1078, 0x6e06, 0x0078, 0x6e54, 0x6124, 0xa1e5, 0x0000, 0x0040,
-	0x6e51, 0x1078, 0xa5c4, 0x1078, 0x5acb, 0x2009, 0x0014, 0x1078,
+	0x6e51, 0x1078, 0xa5d4, 0x1078, 0x5acb, 0x2009, 0x0014, 0x1078,
 	0x775c, 0x0c7f, 0x0078, 0x6e54, 0x027f, 0x017f, 0x0d7f, 0x0c7f,
-	0x007c, 0x2001, 0xa8cd, 0x2004, 0xa005, 0x00c0, 0x6e54, 0x0c7e,
-	0x2061, 0xa8b1, 0x6128, 0xa192, 0x0003, 0x00c8, 0x6e44, 0x8108,
+	0x007c, 0x2001, 0xa9cd, 0x2004, 0xa005, 0x00c0, 0x6e54, 0x0c7e,
+	0x2061, 0xa9b1, 0x6128, 0xa192, 0x0003, 0x00c8, 0x6e44, 0x8108,
 	0x612a, 0x0c7f, 0x1078, 0x5ac0, 0x1078, 0x4224, 0x0078, 0x6e54,
 	0x0c7e, 0x0d7e, 0x0e7e, 0x017e, 0x027e, 0x1078, 0x5ad8, 0x2071,
-	0xa8b1, 0x713c, 0x81ff, 0x0040, 0x6e9a, 0x2061, 0x0100, 0x2069,
+	0xa9b1, 0x713c, 0x81ff, 0x0040, 0x6e9a, 0x2061, 0x0100, 0x2069,
 	0x0140, 0x6904, 0xa194, 0x4000, 0x0040, 0x6ea0, 0x6803, 0x1000,
 	0x6803, 0x0000, 0x037e, 0x2019, 0x0001, 0x1078, 0x7058, 0x037f,
-	0x713c, 0x2160, 0x1078, 0xa5c4, 0x2009, 0x004a, 0x1078, 0x775c,
+	0x713c, 0x2160, 0x1078, 0xa5d4, 0x2009, 0x004a, 0x1078, 0x775c,
 	0x0078, 0x6e9a, 0x027f, 0x017f, 0x0e7f, 0x0d7f, 0x0c7f, 0x007c,
-	0x0078, 0x6e8a, 0x0e7e, 0x2071, 0xa8b1, 0x7048, 0xd084, 0x0040,
+	0x0078, 0x6e8a, 0x0e7e, 0x2071, 0xa9b1, 0x7048, 0xd084, 0x0040,
 	0x6ebc, 0x713c, 0x81ff, 0x0040, 0x6ebc, 0x2071, 0x0100, 0xa188,
 	0x0007, 0x210c, 0xa18e, 0x0006, 0x00c0, 0x6eba, 0x7017, 0x0012,
 	0x0078, 0x6ebc, 0x7017, 0x0016, 0x0e7f, 0x007c, 0x0e7e, 0x0d7e,
 	0x0c7e, 0x067e, 0x057e, 0x047e, 0x007e, 0x127e, 0x2091, 0x8000,
-	0x6018, 0x2068, 0x6ca0, 0x2071, 0xa8b1, 0x7018, 0x2068, 0x8dff,
+	0x6018, 0x2068, 0x6ca0, 0x2071, 0xa9b1, 0x7018, 0x2068, 0x8dff,
 	0x0040, 0x6ee6, 0x68a0, 0xa406, 0x0040, 0x6eda, 0x6854, 0x2068,
 	0x0078, 0x6ecf, 0x6010, 0x2060, 0x643c, 0x6540, 0x6648, 0x2d60,
 	0x1078, 0x4736, 0x0040, 0x6ee6, 0xa085, 0x0001, 0x127f, 0x007f,
@@ -3096,8 +3096,8 @@ unsigned short risc_code01[] = { 
 	0x1078, 0x6731, 0x20a3, 0x0f00, 0x20a3, 0x0000, 0x20a3, 0x0000,
 	0x7808, 0x20a2, 0x60c3, 0x0008, 0x1078, 0x6dfb, 0x147f, 0x157f,
 	0x007c, 0x157e, 0x147e, 0x20a1, 0x020b, 0x1078, 0x67c2, 0x20a3,
-	0x0200, 0x20a3, 0x0000, 0x20a9, 0x0006, 0x2011, 0xa640, 0x2019,
-	0xa641, 0x23a6, 0x22a6, 0xa398, 0x0002, 0xa290, 0x0002, 0x00f0,
+	0x0200, 0x20a3, 0x0000, 0x20a9, 0x0006, 0x2011, 0xa740, 0x2019,
+	0xa741, 0x23a6, 0x22a6, 0xa398, 0x0002, 0xa290, 0x0002, 0x00f0,
 	0x6f39, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x001c, 0x1078,
 	0x6dfb, 0x147f, 0x157f, 0x007c, 0x157e, 0x147e, 0x017e, 0x027e,
 	0x20a1, 0x020b, 0x1078, 0x6799, 0x1078, 0x67b0, 0x7810, 0xa080,
@@ -3110,13 +3110,13 @@ unsigned short risc_code01[] = { 
 	0x1078, 0x6731, 0x7810, 0xa080, 0x0000, 0x2004, 0xa080, 0x0017,
 	0x2098, 0x7808, 0xa088, 0x0002, 0x21a8, 0x53a6, 0x8003, 0x60c2,
 	0x1078, 0x6dfb, 0x027f, 0x017f, 0x147f, 0x157f, 0x007c, 0x0e7e,
-	0x0c7e, 0x007e, 0x127e, 0x2091, 0x8000, 0x2071, 0xa8b1, 0x700c,
-	0x2060, 0x8cff, 0x0040, 0x6fbb, 0x1078, 0x8f00, 0x00c0, 0x6fb2,
+	0x0c7e, 0x007e, 0x127e, 0x2091, 0x8000, 0x2071, 0xa9b1, 0x700c,
+	0x2060, 0x8cff, 0x0040, 0x6fbb, 0x1078, 0x8f10, 0x00c0, 0x6fb2,
 	0x1078, 0x7c83, 0x600c, 0x007e, 0x1078, 0x772d, 0x1078, 0x7233,
 	0x0c7f, 0x0078, 0x6fa9, 0x700f, 0x0000, 0x700b, 0x0000, 0x127f,
 	0x007f, 0x0c7f, 0x0e7f, 0x007c, 0x127e, 0x157e, 0x0f7e, 0x0e7e,
 	0x0d7e, 0x0c7e, 0x027e, 0x017e, 0x007e, 0x2091, 0x8000, 0x2069,
-	0x0100, 0x2079, 0x0140, 0x2071, 0xa8b1, 0x7024, 0x2060, 0x8cff,
+	0x0100, 0x2079, 0x0140, 0x2071, 0xa9b1, 0x7024, 0x2060, 0x8cff,
 	0x0040, 0x7014, 0x1078, 0x6e0f, 0x68c3, 0x0000, 0x1078, 0x5acb,
 	0x2009, 0x0013, 0x1078, 0x775c, 0x20a9, 0x01f4, 0x6824, 0xd094,
 	0x0040, 0x6ff7, 0x6827, 0x0004, 0x7804, 0xa084, 0x4000, 0x0040,
@@ -3124,7 +3124,7 @@ unsigned short risc_code01[] = { 
 	0x0040, 0x6ffe, 0x6827, 0x0001, 0x0078, 0x7000, 0x00f0, 0x6fe6,
 	0x7804, 0xa084, 0x1000, 0x0040, 0x7009, 0x7803, 0x0100, 0x7803,
 	0x0000, 0x6824, 0x007f, 0x017f, 0x027f, 0x0c7f, 0x0d7f, 0x0e7f,
-	0x0f7f, 0x157f, 0x127f, 0x007c, 0x2001, 0xa600, 0x2004, 0xa096,
+	0x0f7f, 0x157f, 0x127f, 0x007c, 0x2001, 0xa700, 0x2004, 0xa096,
 	0x0001, 0x0040, 0x704e, 0xa096, 0x0004, 0x0040, 0x704e, 0x1078,
 	0x5acb, 0x6817, 0x0008, 0x68c3, 0x0000, 0x2011, 0x41dc, 0x1078,
 	0x5a45, 0x20a9, 0x01f4, 0x6824, 0xd094, 0x0040, 0x703c, 0x6827,
@@ -3135,13 +3135,13 @@ unsigned short risc_code01[] = { 
 	0x027f, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f, 0x157f, 0x127f, 0x007c,
 	0x127e, 0x157e, 0x0f7e, 0x0e7e, 0x0d7e, 0x0c7e, 0x027e, 0x017e,
 	0x007e, 0x2091, 0x8000, 0x2069, 0x0100, 0x2079, 0x0140, 0x2071,
-	0xa8b1, 0x703c, 0x2060, 0x8cff, 0x0040, 0x70d6, 0x68af, 0x95f5,
+	0xa9b1, 0x703c, 0x2060, 0x8cff, 0x0040, 0x70d6, 0x68af, 0x95f5,
 	0x6817, 0x0010, 0x2009, 0x00fa, 0x8109, 0x00c0, 0x7074, 0x68c7,
 	0x0000, 0x68cb, 0x0008, 0x1078, 0x5ad8, 0x1078, 0x1f7e, 0x047e,
 	0x057e, 0x2009, 0x017f, 0x212c, 0x200b, 0x00a5, 0x2021, 0x0169,
 	0x2404, 0xa084, 0x000f, 0xa086, 0x0004, 0x00c0, 0x70a5, 0x68c7,
 	0x0000, 0x68cb, 0x0008, 0x0e7e, 0x0f7e, 0x2079, 0x0020, 0x2071,
-	0xa908, 0x6814, 0xa084, 0x0004, 0xa085, 0x0012, 0x6816, 0x7803,
+	0xaa08, 0x6814, 0xa084, 0x0004, 0xa085, 0x0012, 0x6816, 0x7803,
 	0x0008, 0x7003, 0x0000, 0x0f7f, 0x0e7f, 0x250a, 0x057f, 0x047f,
 	0xa39d, 0x0000, 0x00c0, 0x70b0, 0x2009, 0x0049, 0x1078, 0x775c,
 	0x20a9, 0x03e8, 0x6824, 0xd094, 0x0040, 0x70c3, 0x6827, 0x0004,
@@ -3150,16 +3150,16 @@ unsigned short risc_code01[] = { 
 	0x0078, 0x70cc, 0x00f0, 0x70b2, 0x7804, 0xa084, 0x1000, 0x0040,
 	0x70d5, 0x7803, 0x0100, 0x7803, 0x0000, 0x6824, 0x007f, 0x017f,
 	0x027f, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f, 0x157f, 0x127f, 0x007c,
-	0x0d7e, 0x127e, 0x2091, 0x8000, 0x2069, 0xa8b1, 0x6a06, 0x127f,
-	0x0d7f, 0x007c, 0x0d7e, 0x127e, 0x2091, 0x8000, 0x2069, 0xa8b1,
+	0x0d7e, 0x127e, 0x2091, 0x8000, 0x2069, 0xa9b1, 0x6a06, 0x127f,
+	0x0d7f, 0x007c, 0x0d7e, 0x127e, 0x2091, 0x8000, 0x2069, 0xa9b1,
 	0x6a32, 0x127f, 0x0d7f, 0x007c, 0x0f7e, 0x0e7e, 0x0c7e, 0x067e,
-	0x007e, 0x127e, 0x2071, 0xa8b1, 0x7614, 0x2660, 0x2678, 0x2091,
+	0x007e, 0x127e, 0x2071, 0xa9b1, 0x7614, 0x2660, 0x2678, 0x2091,
 	0x8000, 0x8cff, 0x0040, 0x7134, 0x601c, 0xa206, 0x00c0, 0x712f,
 	0x7014, 0xac36, 0x00c0, 0x710e, 0x660c, 0x7616, 0x7010, 0xac36,
 	0x00c0, 0x711c, 0x2c00, 0xaf36, 0x0040, 0x711a, 0x2f00, 0x7012,
 	0x0078, 0x711c, 0x7013, 0x0000, 0x660c, 0x067e, 0x2c00, 0xaf06,
 	0x0040, 0x7125, 0x7e0e, 0x0078, 0x7126, 0x2678, 0x600f, 0x0000,
-	0x1078, 0x8ec6, 0x1078, 0x7233, 0x0c7f, 0x0078, 0x7101, 0x2c78,
+	0x1078, 0x8ed6, 0x1078, 0x7233, 0x0c7f, 0x0078, 0x7101, 0x2c78,
 	0x600c, 0x2060, 0x0078, 0x7101, 0x127f, 0x007f, 0x067f, 0x0c7f,
 	0x0e7f, 0x0f7f, 0x007c, 0x157e, 0x147e, 0x20a1, 0x020b, 0x1078,
 	0x69d0, 0x7810, 0x20a2, 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2,
@@ -3192,11 +3192,11 @@ unsigned short risc_code01[] = { 
 	0x6088, 0x628c, 0x608b, 0xbc91, 0x618e, 0x6043, 0x0001, 0x6043,
 	0x0000, 0x608a, 0x628e, 0x6a04, 0xa294, 0x4000, 0x00c0, 0x7223,
 	0x027f, 0x0d7f, 0x007f, 0x157f, 0x2009, 0x017f, 0x200b, 0x0000,
-	0x0c7f, 0x127f, 0x007c, 0x0e7e, 0x2071, 0xa8b1, 0x7020, 0xa005,
+	0x0c7f, 0x127f, 0x007c, 0x0e7e, 0x2071, 0xa9b1, 0x7020, 0xa005,
 	0x0040, 0x723c, 0x8001, 0x7022, 0x0e7f, 0x007c, 0x20a9, 0x0008,
 	0x20a2, 0x00f0, 0x7240, 0x20a2, 0x20a2, 0x007c, 0x0f7e, 0x0e7e,
 	0x0d7e, 0x0c7e, 0x077e, 0x067e, 0x007e, 0x127e, 0x2091, 0x8000,
-	0x2071, 0xa8b1, 0x7614, 0x2660, 0x2678, 0x2039, 0x0001, 0x87ff,
+	0x2071, 0xa9b1, 0x7614, 0x2660, 0x2678, 0x2039, 0x0001, 0x87ff,
 	0x0040, 0x72e2, 0x8cff, 0x0040, 0x72e2, 0x601c, 0xa086, 0x0006,
 	0x00c0, 0x72dd, 0x88ff, 0x0040, 0x726d, 0x2800, 0xac06, 0x00c0,
 	0x72dd, 0x2039, 0x0000, 0x0078, 0x7278, 0x6018, 0xa206, 0x00c0,
@@ -3211,13 +3211,13 @@ unsigned short risc_code01[] = { 
 	0x00c0, 0x72bc, 0x2c00, 0xaf36, 0x0040, 0x72ba, 0x2f00, 0x7012,
 	0x0078, 0x72bc, 0x7013, 0x0000, 0x660c, 0x067e, 0x2c00, 0xaf06,
 	0x0040, 0x72c5, 0x7e0e, 0x0078, 0x72c6, 0x2678, 0x89ff, 0x00c0,
-	0x72d5, 0x600f, 0x0000, 0x6010, 0x2068, 0x1078, 0x8d06, 0x0040,
-	0x72d3, 0x1078, 0xa1ca, 0x1078, 0x8ec6, 0x1078, 0x7233, 0x88ff,
+	0x72d5, 0x600f, 0x0000, 0x6010, 0x2068, 0x1078, 0x8d16, 0x0040,
+	0x72d3, 0x1078, 0xa1da, 0x1078, 0x8ed6, 0x1078, 0x7233, 0x88ff,
 	0x00c0, 0x72ec, 0x0c7f, 0x0078, 0x7257, 0x2c78, 0x600c, 0x2060,
 	0x0078, 0x7257, 0xa006, 0x127f, 0x007f, 0x067f, 0x077f, 0x0c7f,
 	0x0d7f, 0x0e7f, 0x0f7f, 0x007c, 0x6017, 0x0000, 0x0c7f, 0xa8c5,
 	0x0001, 0x0078, 0x72e3, 0x0f7e, 0x0e7e, 0x0d7e, 0x0c7e, 0x067e,
-	0x027e, 0x007e, 0x127e, 0x2091, 0x8000, 0x2071, 0xa8b1, 0x7638,
+	0x027e, 0x007e, 0x127e, 0x2091, 0x8000, 0x2071, 0xa9b1, 0x7638,
 	0x2660, 0x2678, 0x8cff, 0x0040, 0x7367, 0x601c, 0xa086, 0x0006,
 	0x00c0, 0x7362, 0x87ff, 0x0040, 0x7313, 0x2700, 0xac06, 0x00c0,
 	0x7362, 0x0078, 0x731e, 0x6018, 0xa206, 0x00c0, 0x7362, 0x85ff,
@@ -3228,15 +3228,15 @@ unsigned short risc_code01[] = { 
 	0x7034, 0xac36, 0x00c0, 0x7346, 0x2c00, 0xaf36, 0x0040, 0x7344,
 	0x2f00, 0x7036, 0x0078, 0x7346, 0x7037, 0x0000, 0x660c, 0x067e,
 	0x2c00, 0xaf06, 0x0040, 0x734f, 0x7e0e, 0x0078, 0x7350, 0x2678,
-	0x600f, 0x0000, 0x6010, 0x2068, 0x1078, 0x8d06, 0x0040, 0x735a,
-	0x1078, 0xa1ca, 0x1078, 0x8ec6, 0x87ff, 0x00c0, 0x7371, 0x0c7f,
+	0x600f, 0x0000, 0x6010, 0x2068, 0x1078, 0x8d16, 0x0040, 0x735a,
+	0x1078, 0xa1da, 0x1078, 0x8ed6, 0x87ff, 0x00c0, 0x7371, 0x0c7f,
 	0x0078, 0x7302, 0x2c78, 0x600c, 0x2060, 0x0078, 0x7302, 0xa006,
 	0x127f, 0x007f, 0x027f, 0x067f, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f,
 	0x007c, 0x6017, 0x0000, 0x0c7f, 0xa7bd, 0x0001, 0x0078, 0x7368,
-	0x0e7e, 0x2071, 0xa8b1, 0x2001, 0xa600, 0x2004, 0xa086, 0x0002,
+	0x0e7e, 0x2071, 0xa9b1, 0x2001, 0xa700, 0x2004, 0xa086, 0x0002,
 	0x00c0, 0x7386, 0x7007, 0x0005, 0x0078, 0x7388, 0x7007, 0x0000,
 	0x0e7f, 0x007c, 0x0f7e, 0x0e7e, 0x0c7e, 0x067e, 0x027e, 0x007e,
-	0x127e, 0x2091, 0x8000, 0x2071, 0xa8b1, 0x2c10, 0x7638, 0x2660,
+	0x127e, 0x2091, 0x8000, 0x2071, 0xa9b1, 0x2c10, 0x7638, 0x2660,
 	0x2678, 0x8cff, 0x0040, 0x73c8, 0x2200, 0xac06, 0x00c0, 0x73c3,
 	0x7038, 0xac36, 0x00c0, 0x73a6, 0x660c, 0x763a, 0x7034, 0xac36,
 	0x00c0, 0x73b4, 0x2c00, 0xaf36, 0x0040, 0x73b2, 0x2f00, 0x7036,
@@ -3245,7 +3245,7 @@ unsigned short risc_code01[] = { 
 	0x0001, 0x0078, 0x73c8, 0x2c78, 0x600c, 0x2060, 0x0078, 0x7399,
 	0x127f, 0x007f, 0x027f, 0x067f, 0x0c7f, 0x0e7f, 0x0f7f, 0x007c,
 	0x0f7e, 0x0e7e, 0x0d7e, 0x0c7e, 0x067e, 0x007e, 0x127e, 0x2091,
-	0x8000, 0x2071, 0xa8b1, 0x760c, 0x2660, 0x2678, 0x8cff, 0x0040,
+	0x8000, 0x2071, 0xa9b1, 0x760c, 0x2660, 0x2678, 0x8cff, 0x0040,
 	0x7469, 0x6018, 0xa080, 0x0028, 0x2004, 0xa206, 0x00c0, 0x7464,
 	0x7024, 0xac06, 0x00c0, 0x740f, 0x2069, 0x0100, 0x68c0, 0xa005,
 	0x0040, 0x743d, 0x1078, 0x6e0f, 0x68c3, 0x0000, 0x1078, 0x7378,
@@ -3256,39 +3256,39 @@ unsigned short risc_code01[] = { 
 	0x7423, 0x2c00, 0xaf36, 0x0040, 0x7421, 0x2f00, 0x700a, 0x0078,
 	0x7423, 0x700b, 0x0000, 0x660c, 0x067e, 0x2c00, 0xaf06, 0x0040,
 	0x742c, 0x7e0e, 0x0078, 0x742d, 0x2678, 0x600f, 0x0000, 0x1078,
-	0x8eec, 0x00c0, 0x7441, 0x1078, 0x28a6, 0x1078, 0x8f00, 0x00c0,
+	0x8efc, 0x00c0, 0x7441, 0x1078, 0x28a6, 0x1078, 0x8f10, 0x00c0,
 	0x745d, 0x1078, 0x7c83, 0x0078, 0x745d, 0x1078, 0x7378, 0x0078,
-	0x740f, 0x1078, 0x8f00, 0x00c0, 0x7449, 0x1078, 0x7c83, 0x0078,
-	0x745d, 0x6010, 0x2068, 0x1078, 0x8d06, 0x0040, 0x745d, 0x601c,
+	0x740f, 0x1078, 0x8f10, 0x00c0, 0x7449, 0x1078, 0x7c83, 0x0078,
+	0x745d, 0x6010, 0x2068, 0x1078, 0x8d16, 0x0040, 0x745d, 0x601c,
 	0xa086, 0x0003, 0x00c0, 0x7471, 0x6837, 0x0103, 0x6b4a, 0x6847,
-	0x0000, 0x1078, 0x4a73, 0x1078, 0x8eb9, 0x1078, 0x8ec6, 0x1078,
+	0x0000, 0x1078, 0x4a73, 0x1078, 0x8ec9, 0x1078, 0x8ed6, 0x1078,
 	0x7233, 0x0c7f, 0x0078, 0x73de, 0x2c78, 0x600c, 0x2060, 0x0078,
 	0x73de, 0x127f, 0x007f, 0x067f, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f,
-	0x007c, 0x601c, 0xa086, 0x0006, 0x00c0, 0x745d, 0x1078, 0xa1ca,
+	0x007c, 0x601c, 0xa086, 0x0006, 0x00c0, 0x745d, 0x1078, 0xa1da,
 	0x0078, 0x745d, 0x037e, 0x157e, 0x137e, 0x147e, 0x3908, 0xa006,
 	0xa190, 0x0020, 0x221c, 0xa39e, 0x2676, 0x00c0, 0x748b, 0x8210,
 	0x8000, 0x0078, 0x7482, 0xa005, 0x0040, 0x7497, 0x20a9, 0x0020,
 	0x2198, 0x8211, 0xa282, 0x0020, 0x20c8, 0x20a0, 0x53a3, 0x147f,
 	0x137f, 0x157f, 0x037f, 0x007c, 0x0d7e, 0x20a1, 0x020b, 0x1078,
 	0x67c2, 0x20a3, 0x0200, 0x20a3, 0x0014, 0x60c3, 0x0014, 0x20a3,
-	0x0000, 0x20a3, 0x0000, 0x2099, 0xa8a5, 0x20a9, 0x0004, 0x53a6,
+	0x0000, 0x20a3, 0x0000, 0x2099, 0xa9a5, 0x20a9, 0x0004, 0x53a6,
 	0x20a3, 0x0004, 0x20a3, 0x7878, 0x20a3, 0x0000, 0x20a3, 0x0000,
 	0x1078, 0x6dfb, 0x0d7f, 0x007c, 0x20a1, 0x020b, 0x1078, 0x67c2,
 	0x20a3, 0x0214, 0x20a3, 0x0018, 0x20a3, 0x0800, 0x7810, 0xa084,
 	0xff00, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000,
 	0x20a3, 0x0000, 0x7810, 0xa084, 0x00ff, 0x20a2, 0x7828, 0x20a2,
 	0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0018, 0x1078, 0x6dfb,
-	0x007c, 0x0d7e, 0x017e, 0x2f68, 0x2009, 0x0035, 0x1078, 0x91bc,
+	0x007c, 0x0d7e, 0x017e, 0x2f68, 0x2009, 0x0035, 0x1078, 0x91cc,
 	0x00c0, 0x7551, 0x20a1, 0x020b, 0x1078, 0x6731, 0x20a3, 0x1300,
 	0x20a3, 0x0000, 0x7828, 0x2068, 0x681c, 0xa086, 0x0003, 0x0040,
 	0x752d, 0x7818, 0xa080, 0x0028, 0x2014, 0xa286, 0x007e, 0x00c0,
 	0x7507, 0x20a3, 0x00ff, 0x20a3, 0xfffe, 0x0078, 0x7542, 0xa286,
 	0x007f, 0x00c0, 0x7511, 0x20a3, 0x00ff, 0x20a3, 0xfffd, 0x0078,
 	0x7542, 0xd2bc, 0x0040, 0x7527, 0xa286, 0x0080, 0x00c0, 0x751e,
-	0x20a3, 0x00ff, 0x20a3, 0xfffc, 0x0078, 0x7542, 0xa2e8, 0xa735,
+	0x20a3, 0x00ff, 0x20a3, 0xfffc, 0x0078, 0x7542, 0xa2e8, 0xa835,
 	0x2d6c, 0x6810, 0x20a2, 0x6814, 0x20a2, 0x0078, 0x7542, 0x20a3,
 	0x0000, 0x6098, 0x20a2, 0x0078, 0x7542, 0x7818, 0xa080, 0x0028,
-	0x2004, 0xa082, 0x007e, 0x0048, 0x753e, 0x0d7e, 0x2069, 0xa61b,
+	0x2004, 0xa082, 0x007e, 0x0048, 0x753e, 0x0d7e, 0x2069, 0xa71b,
 	0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x7542, 0x20a3, 0x0000,
 	0x6030, 0x20a2, 0x7834, 0x20a2, 0x7838, 0x20a2, 0x20a3, 0x0000,
 	0x20a3, 0x0000, 0x60c3, 0x000c, 0x1078, 0x6dfb, 0x017f, 0x0d7f,
@@ -3316,8 +3316,8 @@ unsigned short risc_code01[] = { 
 	0x1078, 0x6dfb, 0x027f, 0x0d7f, 0x007c, 0x037e, 0x047e, 0x057e,
 	0x067e, 0x20a1, 0x020b, 0x1078, 0x67c2, 0xa006, 0x20a3, 0x0200,
 	0x20a2, 0x7934, 0x21a2, 0x7938, 0x21a2, 0x7818, 0xa080, 0x0028,
-	0x2004, 0xa092, 0x007e, 0x0048, 0x7623, 0x0d7e, 0x2069, 0xa61b,
-	0x2d2c, 0x8d68, 0x2d34, 0xa0e8, 0xa735, 0x2d6c, 0x6b10, 0x6c14,
+	0x2004, 0xa092, 0x007e, 0x0048, 0x7623, 0x0d7e, 0x2069, 0xa71b,
+	0x2d2c, 0x8d68, 0x2d34, 0xa0e8, 0xa835, 0x2d6c, 0x6b10, 0x6c14,
 	0x0d7f, 0x0078, 0x7629, 0x2019, 0x0000, 0x6498, 0x2029, 0x0000,
 	0x6630, 0x7828, 0xa080, 0x0007, 0x2004, 0xa086, 0x0003, 0x00c0,
 	0x7637, 0x25a2, 0x26a2, 0x23a2, 0x24a2, 0x0078, 0x763b, 0x23a2,
@@ -3332,33 +3332,33 @@ unsigned short risc_code01[] = { 
 	0x20a2, 0x60c3, 0x0008, 0x1078, 0x6dfb, 0x007c, 0x147e, 0x20a1,
 	0x020b, 0x1078, 0x7689, 0x60c3, 0x0000, 0x1078, 0x6dfb, 0x147f,
 	0x007c, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028,
-	0x2004, 0xd0bc, 0x0040, 0x76a6, 0x0d7e, 0xa0e8, 0xa735, 0x2d6c,
-	0x6810, 0xa085, 0x0300, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xa61b,
+	0x2004, 0xd0bc, 0x0040, 0x76a6, 0x0d7e, 0xa0e8, 0xa835, 0x2d6c,
+	0x6810, 0xa085, 0x0300, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xa71b,
 	0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x76ae, 0x20a3, 0x0300,
 	0x6298, 0x22a2, 0x20a3, 0x0000, 0x6230, 0x22a2, 0x20a3, 0x0819,
 	0x20a3, 0x0000, 0x1078, 0x6dea, 0x22a2, 0x20a3, 0x0000, 0x2fa2,
 	0x7a08, 0x22a2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x007c, 0x2061,
-	0xad00, 0x2a70, 0x7064, 0x704a, 0x704f, 0xad00, 0x007c, 0x0e7e,
-	0x127e, 0x2071, 0xa600, 0x2091, 0x8000, 0x7548, 0xa582, 0x0010,
+	0xae00, 0x2a70, 0x7064, 0x704a, 0x704f, 0xae00, 0x007c, 0x0e7e,
+	0x127e, 0x2071, 0xa700, 0x2091, 0x8000, 0x7548, 0xa582, 0x0010,
 	0x0048, 0x76f9, 0x704c, 0x2060, 0x6000, 0xa086, 0x0000, 0x0040,
 	0x76e5, 0xace0, 0x0010, 0x7058, 0xac02, 0x00c8, 0x76e1, 0x0078,
-	0x76d4, 0x2061, 0xad00, 0x0078, 0x76d4, 0x6003, 0x0008, 0x8529,
+	0x76d4, 0x2061, 0xae00, 0x0078, 0x76d4, 0x6003, 0x0008, 0x8529,
 	0x754a, 0xaca8, 0x0010, 0x7058, 0xa502, 0x00c8, 0x76f5, 0x754e,
-	0xa085, 0x0001, 0x127f, 0x0e7f, 0x007c, 0x704f, 0xad00, 0x0078,
-	0x76f0, 0xa006, 0x0078, 0x76f2, 0x0e7e, 0x2071, 0xa600, 0x7548,
+	0xa085, 0x0001, 0x127f, 0x0e7f, 0x007c, 0x704f, 0xae00, 0x0078,
+	0x76f0, 0xa006, 0x0078, 0x76f2, 0x0e7e, 0x2071, 0xa700, 0x7548,
 	0xa582, 0x0010, 0x0048, 0x772a, 0x704c, 0x2060, 0x6000, 0xa086,
 	0x0000, 0x0040, 0x7717, 0xace0, 0x0010, 0x7058, 0xac02, 0x00c8,
-	0x7713, 0x0078, 0x7706, 0x2061, 0xad00, 0x0078, 0x7706, 0x6003,
+	0x7713, 0x0078, 0x7706, 0x2061, 0xae00, 0x0078, 0x7706, 0x6003,
 	0x0008, 0x8529, 0x754a, 0xaca8, 0x0010, 0x7058, 0xa502, 0x00c8,
-	0x7726, 0x754e, 0xa085, 0x0001, 0x0e7f, 0x007c, 0x704f, 0xad00,
-	0x0078, 0x7722, 0xa006, 0x0078, 0x7724, 0xac82, 0xad00, 0x1048,
-	0x1332, 0x2001, 0xa616, 0x2004, 0xac02, 0x10c8, 0x1332, 0xa006,
+	0x7726, 0x754e, 0xa085, 0x0001, 0x0e7f, 0x007c, 0x704f, 0xae00,
+	0x0078, 0x7722, 0xa006, 0x0078, 0x7724, 0xac82, 0xae00, 0x1048,
+	0x1332, 0x2001, 0xa716, 0x2004, 0xac02, 0x10c8, 0x1332, 0xa006,
 	0x6006, 0x600a, 0x600e, 0x6012, 0x6016, 0x601a, 0x601f, 0x0000,
 	0x6003, 0x0000, 0x6022, 0x6026, 0x602a, 0x602e, 0x6032, 0x6036,
-	0x603a, 0x603e, 0x2061, 0xa600, 0x6048, 0x8000, 0x604a, 0xa086,
+	0x603a, 0x603e, 0x2061, 0xa700, 0x6048, 0x8000, 0x604a, 0xa086,
 	0x0001, 0x0040, 0x7754, 0x007c, 0x127e, 0x2091, 0x8000, 0x1078,
 	0x62d1, 0x127f, 0x0078, 0x7753, 0x601c, 0xa084, 0x000f, 0x0079,
-	0x7761, 0x776a, 0x777b, 0x7797, 0x77b3, 0x920e, 0x922a, 0x9246,
+	0x7761, 0x776a, 0x777b, 0x7797, 0x77b3, 0x921e, 0x923a, 0x9256,
 	0x776a, 0x777b, 0xa186, 0x0013, 0x00c0, 0x7773, 0x1078, 0x61cd,
 	0x1078, 0x62d1, 0x007c, 0xa18e, 0x0047, 0x00c0, 0x777a, 0xa016,
 	0x1078, 0x15fa, 0x007c, 0x067e, 0x6000, 0xa0b2, 0x0010, 0x10c8,
@@ -3366,18 +3366,18 @@ unsigned short risc_code01[] = { 
 	0x7795, 0x7d36, 0x77cf, 0x7795, 0x7795, 0x7a92, 0x80f6, 0x7795,
 	0x7795, 0x7795, 0x7795, 0x7795, 0x7795, 0x1078, 0x1332, 0x067e,
 	0x6000, 0xa0b2, 0x0010, 0x10c8, 0x1332, 0x1079, 0x77a1, 0x067f,
-	0x007c, 0x77b1, 0x87c3, 0x77b1, 0x77b1, 0x77b1, 0x77b1, 0x77b1,
-	0x77b1, 0x8766, 0x8951, 0x77b1, 0x87f3, 0x8879, 0x87f3, 0x8879,
+	0x007c, 0x77b1, 0x87d3, 0x77b1, 0x77b1, 0x77b1, 0x77b1, 0x77b1,
+	0x77b1, 0x8776, 0x8961, 0x77b1, 0x8803, 0x8889, 0x8803, 0x8889,
 	0x77b1, 0x1078, 0x1332, 0x067e, 0x6000, 0xa0b2, 0x0010, 0x10c8,
 	0x1332, 0x1079, 0x77bd, 0x067f, 0x007c, 0x77cd, 0x813d, 0x820e,
-	0x8368, 0x84e4, 0x77cd, 0x77cd, 0x77cd, 0x8116, 0x870e, 0x8712,
-	0x77cd, 0x77cd, 0x77cd, 0x77cd, 0x8742, 0x1078, 0x1332, 0xa1b6,
+	0x8372, 0x84f1, 0x77cd, 0x77cd, 0x77cd, 0x8116, 0x871e, 0x8722,
+	0x77cd, 0x77cd, 0x77cd, 0x77cd, 0x8752, 0x1078, 0x1332, 0xa1b6,
 	0x0015, 0x00c0, 0x77d7, 0x1078, 0x772d, 0x0078, 0x77dd, 0xa1b6,
 	0x0016, 0x10c0, 0x1332, 0x1078, 0x772d, 0x007c, 0x20a9, 0x000e,
 	0x2e98, 0x6010, 0x20a0, 0x53a3, 0x20a9, 0x0006, 0x3310, 0x3420,
 	0x9398, 0x94a0, 0x3318, 0x3428, 0x222e, 0x2326, 0xa290, 0x0002,
 	0xa5a8, 0x0002, 0xa398, 0x0002, 0xa4a0, 0x0002, 0x00f0, 0x77ec,
-	0x0e7e, 0x1078, 0x8d06, 0x0040, 0x7803, 0x6010, 0x2070, 0x7007,
+	0x0e7e, 0x1078, 0x8d16, 0x0040, 0x7803, 0x6010, 0x2070, 0x7007,
 	0x0000, 0x7037, 0x0103, 0x0e7f, 0x1078, 0x772d, 0x007c, 0x0d7e,
 	0x037e, 0x7330, 0xa386, 0x0200, 0x00c0, 0x7814, 0x6018, 0x2068,
 	0x6813, 0x00ff, 0x6817, 0xfffd, 0x6010, 0xa005, 0x0040, 0x781e,
@@ -3387,8 +3387,8 @@ unsigned short risc_code01[] = { 
 	0x6010, 0xa080, 0x0001, 0x2004, 0xa080, 0x0002, 0x20a0, 0x53a3,
 	0x0e7e, 0x6010, 0x2004, 0x2070, 0x7037, 0x0103, 0x0e7f, 0x1078,
 	0x772d, 0x017f, 0x007c, 0x0e7e, 0x0d7e, 0x603f, 0x0000, 0x2c68,
-	0x017e, 0x2009, 0x0035, 0x1078, 0x91bc, 0x017f, 0x00c0, 0x785f,
-	0x027e, 0x6228, 0x2268, 0x027f, 0x2071, 0xab8c, 0x6b1c, 0xa386,
+	0x017e, 0x2009, 0x0035, 0x1078, 0x91cc, 0x017f, 0x00c0, 0x785f,
+	0x027e, 0x6228, 0x2268, 0x027f, 0x2071, 0xac8c, 0x6b1c, 0xa386,
 	0x0003, 0x0040, 0x7863, 0xa386, 0x0006, 0x0040, 0x7867, 0x1078,
 	0x772d, 0x0078, 0x7869, 0x1078, 0x786c, 0x0078, 0x7869, 0x1078,
 	0x7938, 0x0d7f, 0x0e7f, 0x007c, 0x0f7e, 0x6810, 0x2078, 0xa186,
@@ -3398,31 +3398,31 @@ unsigned short risc_code01[] = { 
 	0x0040, 0x78db, 0x0078, 0x7934, 0x6808, 0xa086, 0xffff, 0x00c0,
 	0x7921, 0x784c, 0xa084, 0x0060, 0xa086, 0x0020, 0x00c0, 0x78a2,
 	0x797c, 0x7810, 0xa106, 0x00c0, 0x7921, 0x7980, 0x7814, 0xa106,
-	0x00c0, 0x7921, 0x1078, 0x8eb9, 0x6830, 0x7852, 0x784c, 0xc0dc,
+	0x00c0, 0x7921, 0x1078, 0x8ec9, 0x6830, 0x7852, 0x784c, 0xc0dc,
 	0xc0f4, 0xc0d4, 0x784e, 0x027e, 0xa00e, 0x6a14, 0x2001, 0x000a,
 	0x1078, 0x5c1c, 0x7854, 0xa20a, 0x0048, 0x78b7, 0x8011, 0x7a56,
-	0x82ff, 0x027f, 0x00c0, 0x78c3, 0x0c7e, 0x2d60, 0x1078, 0x8ae0,
+	0x82ff, 0x027f, 0x00c0, 0x78c3, 0x0c7e, 0x2d60, 0x1078, 0x8af0,
 	0x0c7f, 0x0078, 0x7934, 0x0c7e, 0x0d7e, 0x2f68, 0x6838, 0xd0fc,
 	0x00c0, 0x78ce, 0x1078, 0x4353, 0x0078, 0x78d0, 0x1078, 0x4431,
 	0x0d7f, 0x0c7f, 0x00c0, 0x7921, 0x0c7e, 0x2d60, 0x1078, 0x772d,
-	0x0c7f, 0x0078, 0x7934, 0x0c7e, 0x1078, 0x9187, 0x0040, 0x78f1,
+	0x0c7f, 0x0078, 0x7934, 0x0c7e, 0x1078, 0x9197, 0x0040, 0x78f1,
 	0x6013, 0x0000, 0x6818, 0x601a, 0x601f, 0x0003, 0x6904, 0x0c7e,
 	0x2d60, 0x1078, 0x772d, 0x0c7f, 0x1078, 0x775c, 0x0c7f, 0x0078,
-	0x7934, 0x2001, 0xa8a4, 0x2004, 0x683e, 0x0c7f, 0x0078, 0x7934,
+	0x7934, 0x2001, 0xa9a4, 0x2004, 0x683e, 0x0c7f, 0x0078, 0x7934,
 	0x7008, 0xa086, 0x000b, 0x00c0, 0x7912, 0x6018, 0x200c, 0xc1bc,
 	0x2102, 0x0c7e, 0x2d60, 0x7853, 0x0003, 0x6007, 0x0085, 0x6003,
 	0x000b, 0x601f, 0x0002, 0x1078, 0x5d8a, 0x1078, 0x62d1, 0x0c7f,
 	0x0078, 0x7934, 0x700c, 0xa086, 0x2a00, 0x00c0, 0x7921, 0x2001,
-	0xa8a4, 0x2004, 0x683e, 0x0078, 0x7934, 0x1078, 0x7953, 0x0078,
+	0xa9a4, 0x2004, 0x683e, 0x0078, 0x7934, 0x1078, 0x7953, 0x0078,
 	0x7936, 0x8fff, 0x1040, 0x1332, 0x0c7e, 0x0d7e, 0x2d60, 0x2f68,
-	0x6837, 0x0103, 0x684b, 0x0003, 0x1078, 0x89cf, 0x1078, 0x8eb9,
-	0x1078, 0x8ec6, 0x0d7f, 0x0c7f, 0x1078, 0x772d, 0x0f7f, 0x007c,
-	0xa186, 0x0015, 0x00c0, 0x7942, 0x2001, 0xa8a4, 0x2004, 0x683e,
+	0x6837, 0x0103, 0x684b, 0x0003, 0x1078, 0x89df, 0x1078, 0x8ec9,
+	0x1078, 0x8ed6, 0x0d7f, 0x0c7f, 0x1078, 0x772d, 0x0f7f, 0x007c,
+	0xa186, 0x0015, 0x00c0, 0x7942, 0x2001, 0xa9a4, 0x2004, 0x683e,
 	0x0078, 0x7950, 0xa18e, 0x0016, 0x00c0, 0x7952, 0x0c7e, 0x2d00,
-	0x2060, 0x1078, 0xa495, 0x1078, 0x5bc1, 0x1078, 0x772d, 0x0c7f,
+	0x2060, 0x1078, 0xa4a5, 0x1078, 0x5bc1, 0x1078, 0x772d, 0x0c7f,
 	0x1078, 0x772d, 0x007c, 0x027e, 0x037e, 0x047e, 0x7228, 0x7c80,
-	0x7b7c, 0xd2f4, 0x0040, 0x7962, 0x2001, 0xa8a4, 0x2004, 0x683e,
-	0x0078, 0x79c6, 0x0c7e, 0x2d60, 0x1078, 0x89f3, 0x0c7f, 0x6804,
+	0x7b7c, 0xd2f4, 0x0040, 0x7962, 0x2001, 0xa9a4, 0x2004, 0x683e,
+	0x0078, 0x79c6, 0x0c7e, 0x2d60, 0x1078, 0x8a03, 0x0c7f, 0x6804,
 	0xa086, 0x0050, 0x00c0, 0x797a, 0x0c7e, 0x2d00, 0x2060, 0x6003,
 	0x0001, 0x6007, 0x0050, 0x1078, 0x5d8a, 0x1078, 0x62d1, 0x0c7f,
 	0x0078, 0x79c6, 0x6800, 0xa086, 0x000f, 0x0040, 0x799c, 0x8fff,
@@ -3434,21 +3434,21 @@ unsigned short risc_code01[] = { 
 	0x784c, 0xd0f4, 0x00c0, 0x799c, 0x0078, 0x798f, 0xd2ec, 0x00c0,
 	0x799c, 0x7024, 0xa306, 0x00c0, 0x79b9, 0x7020, 0xa406, 0x0040,
 	0x799c, 0x7020, 0x6836, 0x7024, 0x683a, 0x2001, 0x0005, 0x682e,
-	0x1078, 0x8ff0, 0x1078, 0x62d1, 0x0078, 0x79c8, 0x1078, 0x772d,
+	0x1078, 0x9000, 0x1078, 0x62d1, 0x0078, 0x79c8, 0x1078, 0x772d,
 	0x047f, 0x037f, 0x027f, 0x007c, 0x0e7e, 0x0d7e, 0x027e, 0x6034,
 	0x2068, 0x6a1c, 0xa286, 0x0007, 0x0040, 0x7a35, 0xa286, 0x0002,
 	0x0040, 0x7a35, 0xa286, 0x0000, 0x0040, 0x7a35, 0x6808, 0x6338,
-	0xa306, 0x00c0, 0x7a35, 0x2071, 0xab8c, 0xa186, 0x0015, 0x0040,
+	0xa306, 0x00c0, 0x7a35, 0x2071, 0xac8c, 0xa186, 0x0015, 0x0040,
 	0x7a2f, 0xa18e, 0x0016, 0x00c0, 0x7a02, 0x6030, 0xa084, 0x00ff,
 	0xa086, 0x0001, 0x00c0, 0x7a02, 0x700c, 0xa086, 0x2a00, 0x00c0,
 	0x7a02, 0x6034, 0xa080, 0x0009, 0x200c, 0xc1dd, 0xc1f5, 0x2102,
 	0x0078, 0x7a2f, 0x0c7e, 0x6034, 0x2060, 0x6104, 0xa186, 0x004b,
 	0x0040, 0x7a22, 0xa186, 0x004c, 0x0040, 0x7a22, 0xa186, 0x004d,
 	0x0040, 0x7a22, 0xa186, 0x004e, 0x0040, 0x7a22, 0xa186, 0x0052,
-	0x0040, 0x7a22, 0x6010, 0x2068, 0x1078, 0x8d06, 0x1040, 0x1332,
+	0x0040, 0x7a22, 0x6010, 0x2068, 0x1078, 0x8d16, 0x1040, 0x1332,
 	0x6853, 0x0003, 0x6007, 0x0085, 0x6003, 0x000b, 0x601f, 0x0002,
 	0x1078, 0x5d8a, 0x1078, 0x62d1, 0x0c7f, 0x0078, 0x7a35, 0x6034,
-	0x2068, 0x2001, 0xa8a4, 0x2004, 0x683e, 0x1078, 0x772d, 0x027f,
+	0x2068, 0x2001, 0xa9a4, 0x2004, 0x683e, 0x1078, 0x772d, 0x027f,
 	0x0d7f, 0x0e7f, 0x007c, 0x0d7e, 0x20a9, 0x000e, 0x2e98, 0x6010,
 	0x20a0, 0x53a3, 0xa1b6, 0x0015, 0x00c0, 0x7a73, 0x6018, 0x2068,
 	0x157e, 0x037e, 0x027e, 0xae90, 0x000c, 0xa290, 0x0004, 0x20a9,
@@ -3477,25 +3477,25 @@ unsigned short risc_code01[] = { 
 	0x6004, 0xa0b2, 0x0044, 0x10c8, 0x1332, 0xa1b6, 0x0013, 0x00c0,
 	0x7b10, 0xa0b2, 0x0040, 0x00c8, 0x7c79, 0x2008, 0x0079, 0x7bbf,
 	0xa1b6, 0x0027, 0x00c0, 0x7b7c, 0x1078, 0x61cd, 0x6004, 0x1078,
-	0x8eec, 0x0040, 0x7b2d, 0x1078, 0x8f00, 0x0040, 0x7b74, 0xa08e,
+	0x8efc, 0x0040, 0x7b2d, 0x1078, 0x8f10, 0x0040, 0x7b74, 0xa08e,
 	0x0021, 0x0040, 0x7b78, 0xa08e, 0x0022, 0x0040, 0x7b74, 0xa08e,
 	0x003d, 0x0040, 0x7b78, 0x0078, 0x7b6f, 0x1078, 0x28a6, 0x2001,
 	0x0007, 0x1078, 0x4502, 0x6018, 0xa080, 0x0028, 0x200c, 0x1078,
-	0x7c83, 0xa186, 0x007e, 0x00c0, 0x7b42, 0x2001, 0xa633, 0x2014,
+	0x7c83, 0xa186, 0x007e, 0x00c0, 0x7b42, 0x2001, 0xa733, 0x2014,
 	0xc285, 0x2202, 0x017e, 0x027e, 0x037e, 0x2110, 0x027e, 0x2019,
-	0x0028, 0x1078, 0x73d0, 0x027f, 0x1078, 0xa4f1, 0x037f, 0x027f,
+	0x0028, 0x1078, 0x73d0, 0x027f, 0x1078, 0xa501, 0x037f, 0x027f,
 	0x017f, 0x017e, 0x027e, 0x037e, 0x2110, 0x2019, 0x0028, 0x1078,
 	0x5f01, 0x077e, 0x2039, 0x0000, 0x1078, 0x5e0a, 0x0c7e, 0x6018,
 	0xa065, 0x0040, 0x7b65, 0x1078, 0x47e9, 0x0c7f, 0x2c08, 0x1078,
-	0x9f8b, 0x077f, 0x037f, 0x027f, 0x017f, 0x1078, 0x457f, 0x1078,
+	0x9f9b, 0x077f, 0x037f, 0x027f, 0x017f, 0x1078, 0x457f, 0x1078,
 	0x772d, 0x1078, 0x62d1, 0x007c, 0x1078, 0x7c83, 0x0078, 0x7b6f,
 	0x1078, 0x7ca6, 0x0078, 0x7b6f, 0xa186, 0x0014, 0x00c0, 0x7b73,
-	0x1078, 0x61cd, 0x1078, 0x2880, 0x1078, 0x8eec, 0x00c0, 0x7b9b,
+	0x1078, 0x61cd, 0x1078, 0x2880, 0x1078, 0x8efc, 0x00c0, 0x7b9b,
 	0x1078, 0x28a6, 0x6018, 0xa080, 0x0028, 0x200c, 0x1078, 0x7c83,
-	0xa186, 0x007e, 0x00c0, 0x7b99, 0x2001, 0xa633, 0x200c, 0xc185,
-	0x2102, 0x0078, 0x7b6f, 0x1078, 0x8f00, 0x00c0, 0x7ba3, 0x1078,
+	0xa186, 0x007e, 0x00c0, 0x7b99, 0x2001, 0xa733, 0x200c, 0xc185,
+	0x2102, 0x0078, 0x7b6f, 0x1078, 0x8f10, 0x00c0, 0x7ba3, 0x1078,
 	0x7c83, 0x0078, 0x7b6f, 0x6004, 0xa08e, 0x0032, 0x00c0, 0x7bb4,
-	0x0e7e, 0x0f7e, 0x2071, 0xa682, 0x2079, 0x0000, 0x1078, 0x2bd7,
+	0x0e7e, 0x0f7e, 0x2071, 0xa782, 0x2079, 0x0000, 0x1078, 0x2bd7,
 	0x0f7f, 0x0e7f, 0x0078, 0x7b6f, 0x6004, 0xa08e, 0x0021, 0x0040,
 	0x7b9f, 0xa08e, 0x0022, 0x1040, 0x7c83, 0x0078, 0x7b6f, 0x7c01,
 	0x7c03, 0x7c07, 0x7c0b, 0x7c0f, 0x7c13, 0x7bff, 0x7bff, 0x7bff,
@@ -3509,20 +3509,20 @@ unsigned short risc_code01[] = { 
 	0x1332, 0x0078, 0x7c29, 0x2001, 0x000b, 0x0078, 0x7c36, 0x2001,
 	0x0003, 0x0078, 0x7c36, 0x2001, 0x0005, 0x0078, 0x7c36, 0x2001,
 	0x0001, 0x0078, 0x7c36, 0x2001, 0x0009, 0x0078, 0x7c36, 0x1078,
-	0x61cd, 0x6003, 0x0005, 0x2001, 0xa8a4, 0x2004, 0x603e, 0x1078,
+	0x61cd, 0x6003, 0x0005, 0x2001, 0xa9a4, 0x2004, 0x603e, 0x1078,
 	0x62d1, 0x0078, 0x7c35, 0x0078, 0x7c29, 0x0078, 0x7c29, 0x1078,
 	0x4502, 0x0078, 0x7c6e, 0x1078, 0x61cd, 0x6003, 0x0004, 0x2001,
-	0xa8a2, 0x2004, 0x6016, 0x1078, 0x62d1, 0x007c, 0x1078, 0x4502,
-	0x1078, 0x61cd, 0x2001, 0xa8a4, 0x2004, 0x603e, 0x6003, 0x0002,
-	0x037e, 0x2019, 0xa65d, 0x2304, 0xa084, 0xff00, 0x00c0, 0x7c4d,
-	0x2019, 0xa8a2, 0x231c, 0x0078, 0x7c56, 0x8007, 0xa09a, 0x0004,
+	0xa9a2, 0x2004, 0x6016, 0x1078, 0x62d1, 0x007c, 0x1078, 0x4502,
+	0x1078, 0x61cd, 0x2001, 0xa9a4, 0x2004, 0x603e, 0x6003, 0x0002,
+	0x037e, 0x2019, 0xa75d, 0x2304, 0xa084, 0xff00, 0x00c0, 0x7c4d,
+	0x2019, 0xa9a2, 0x231c, 0x0078, 0x7c56, 0x8007, 0xa09a, 0x0004,
 	0x0048, 0x7c48, 0x8003, 0x801b, 0x831b, 0xa318, 0x6316, 0x037f,
-	0x1078, 0x62d1, 0x0078, 0x7c35, 0x0e7e, 0x0f7e, 0x2071, 0xa682,
+	0x1078, 0x62d1, 0x0078, 0x7c35, 0x0e7e, 0x0f7e, 0x2071, 0xa782,
 	0x2079, 0x0000, 0x1078, 0x2bd7, 0x0f7f, 0x0e7f, 0x1078, 0x61cd,
 	0x1078, 0x772d, 0x1078, 0x62d1, 0x0078, 0x7c35, 0x1078, 0x61cd,
-	0x6003, 0x0002, 0x2001, 0xa8a2, 0x2004, 0x6016, 0x1078, 0x62d1,
+	0x6003, 0x0002, 0x2001, 0xa9a2, 0x2004, 0x6016, 0x1078, 0x62d1,
 	0x007c, 0x2600, 0x2008, 0x0079, 0x7c7d, 0x7c81, 0x7c81, 0x7c81,
-	0x7c6e, 0x1078, 0x1332, 0x0e7e, 0x1078, 0x8d06, 0x0040, 0x7c9f,
+	0x7c6e, 0x1078, 0x1332, 0x0e7e, 0x1078, 0x8d16, 0x0040, 0x7c9f,
 	0x6010, 0x2070, 0x7038, 0xd0fc, 0x0040, 0x7c9f, 0x7007, 0x0000,
 	0x017e, 0x6004, 0xa08e, 0x0021, 0x0040, 0x7ca1, 0xa08e, 0x003d,
 	0x0040, 0x7ca1, 0x017f, 0x7037, 0x0103, 0x7033, 0x0100, 0x0e7f,
@@ -3530,10 +3530,10 @@ unsigned short risc_code01[] = { 
 	0x0004, 0x2e74, 0x7000, 0x2070, 0x7037, 0x0103, 0x7023, 0x8001,
 	0x0e7f, 0x007c, 0x0d7e, 0x6618, 0x2668, 0x6804, 0xa084, 0x00ff,
 	0x0d7f, 0xa0b2, 0x000c, 0x10c8, 0x1332, 0x6604, 0xa6b6, 0x0043,
-	0x00c0, 0x7cc6, 0x1078, 0x9134, 0x0078, 0x7d25, 0x6604, 0xa6b6,
-	0x0033, 0x00c0, 0x7ccf, 0x1078, 0x90d8, 0x0078, 0x7d25, 0x6604,
-	0xa6b6, 0x0028, 0x00c0, 0x7cd8, 0x1078, 0x8f2f, 0x0078, 0x7d25,
-	0x6604, 0xa6b6, 0x0029, 0x00c0, 0x7ce1, 0x1078, 0x8f49, 0x0078,
+	0x00c0, 0x7cc6, 0x1078, 0x9144, 0x0078, 0x7d25, 0x6604, 0xa6b6,
+	0x0033, 0x00c0, 0x7ccf, 0x1078, 0x90e8, 0x0078, 0x7d25, 0x6604,
+	0xa6b6, 0x0028, 0x00c0, 0x7cd8, 0x1078, 0x8f3f, 0x0078, 0x7d25,
+	0x6604, 0xa6b6, 0x0029, 0x00c0, 0x7ce1, 0x1078, 0x8f59, 0x0078,
 	0x7d25, 0x6604, 0xa6b6, 0x001f, 0x00c0, 0x7cea, 0x1078, 0x77de,
 	0x0078, 0x7d25, 0x6604, 0xa6b6, 0x0000, 0x00c0, 0x7cf3, 0x1078,
 	0x7a3b, 0x0078, 0x7d25, 0x6604, 0xa6b6, 0x0022, 0x00c0, 0x7cfc,
@@ -3548,31 +3548,31 @@ unsigned short risc_code01[] = { 
 	0x0040, 0x7d42, 0x20e1, 0x0005, 0x3d18, 0x3e20, 0x2c10, 0x1078,
 	0x15fa, 0x007c, 0x0e7e, 0xacf0, 0x0004, 0x2e74, 0x7000, 0x2070,
 	0x7037, 0x0103, 0x0e7f, 0x1078, 0x772d, 0x007c, 0x0005, 0x0005,
-	0x007c, 0x0e7e, 0x2071, 0xa600, 0x7080, 0xa086, 0x0074, 0x00c0,
-	0x7d85, 0x1078, 0x9f5f, 0x00c0, 0x7d77, 0x0d7e, 0x6018, 0x2068,
+	0x007c, 0x0e7e, 0x2071, 0xa700, 0x7080, 0xa086, 0x0074, 0x00c0,
+	0x7d85, 0x1078, 0x9f6f, 0x00c0, 0x7d77, 0x0d7e, 0x6018, 0x2068,
 	0x7030, 0xd08c, 0x0040, 0x7d6a, 0x6800, 0xd0bc, 0x0040, 0x7d6a,
 	0xc0c5, 0x6802, 0x1078, 0x7d89, 0x0d7f, 0x2001, 0x0006, 0x1078,
 	0x4502, 0x1078, 0x28a6, 0x1078, 0x772d, 0x0078, 0x7d87, 0x2001,
 	0x000a, 0x1078, 0x4502, 0x1078, 0x28a6, 0x6003, 0x0001, 0x6007,
 	0x0001, 0x1078, 0x5dd7, 0x0078, 0x7d87, 0x1078, 0x7dff, 0x0e7f,
 	0x007c, 0x6800, 0xd084, 0x0040, 0x7d9b, 0x2001, 0x0000, 0x1078,
-	0x44ee, 0x2069, 0xa652, 0x6804, 0xd0a4, 0x0040, 0x7d9b, 0x2001,
-	0x0006, 0x1078, 0x4535, 0x007c, 0x0d7e, 0x2011, 0xa620, 0x2204,
+	0x44ee, 0x2069, 0xa752, 0x6804, 0xd0a4, 0x0040, 0x7d9b, 0x2001,
+	0x0006, 0x1078, 0x4535, 0x007c, 0x0d7e, 0x2011, 0xa720, 0x2204,
 	0xa086, 0x0074, 0x00c0, 0x7dfb, 0x6018, 0x2068, 0x6aa0, 0xa286,
 	0x007e, 0x00c0, 0x7daf, 0x1078, 0x7f9b, 0x0078, 0x7dfd, 0x1078,
 	0x7f91, 0x6018, 0x2068, 0xa080, 0x0028, 0x2014, 0xa286, 0x0080,
 	0x00c0, 0x7dd3, 0x6813, 0x00ff, 0x6817, 0xfffc, 0x6010, 0xa005,
 	0x0040, 0x7dc9, 0x2068, 0x6807, 0x0000, 0x6837, 0x0103, 0x6833,
 	0x0200, 0x2001, 0x0006, 0x1078, 0x4502, 0x1078, 0x28a6, 0x1078,
-	0x772d, 0x0078, 0x7dfd, 0x0e7e, 0x2071, 0xa633, 0x2e04, 0xd09c,
-	0x0040, 0x7dee, 0x2071, 0xab80, 0x7108, 0x720c, 0xa18c, 0x00ff,
+	0x772d, 0x0078, 0x7dfd, 0x0e7e, 0x2071, 0xa733, 0x2e04, 0xd09c,
+	0x0040, 0x7dee, 0x2071, 0xac80, 0x7108, 0x720c, 0xa18c, 0x00ff,
 	0x00c0, 0x7de6, 0xa284, 0xff00, 0x0040, 0x7dee, 0x6018, 0x2070,
 	0x70a0, 0xd0bc, 0x00c0, 0x7dee, 0x7112, 0x7216, 0x0e7f, 0x2001,
 	0x0004, 0x1078, 0x4502, 0x6003, 0x0001, 0x6007, 0x0003, 0x1078,
 	0x5dd7, 0x0078, 0x7dfd, 0x1078, 0x7dff, 0x0d7f, 0x007c, 0x2001,
-	0x0007, 0x1078, 0x4502, 0x2001, 0xa600, 0x2004, 0xa086, 0x0003,
+	0x0007, 0x1078, 0x4502, 0x2001, 0xa700, 0x2004, 0xa086, 0x0003,
 	0x00c0, 0x7e0e, 0x2001, 0x0007, 0x1078, 0x4535, 0x1078, 0x28a6,
-	0x1078, 0x772d, 0x007c, 0x0e7e, 0x2071, 0xa600, 0x7080, 0xa086,
+	0x1078, 0x772d, 0x007c, 0x0e7e, 0x2071, 0xa700, 0x7080, 0xa086,
 	0x0014, 0x00c0, 0x7e51, 0x7000, 0xa086, 0x0003, 0x00c0, 0x7e26,
 	0x6010, 0xa005, 0x00c0, 0x7e26, 0x1078, 0x3699, 0x0d7e, 0x6018,
 	0x2068, 0x1078, 0x4649, 0x1078, 0x7d89, 0x0d7f, 0x1078, 0x8043,
@@ -3581,9 +3581,9 @@ unsigned short risc_code01[] = { 
 	0xa005, 0x0040, 0x7e4a, 0x2070, 0x7007, 0x0000, 0x7037, 0x0103,
 	0x7033, 0x0200, 0x0e7f, 0x1078, 0x28a6, 0x1078, 0x772d, 0x0078,
 	0x7e55, 0x1078, 0x7c83, 0x1078, 0x7dff, 0x0e7f, 0x007c, 0x2011,
-	0xa620, 0x2204, 0xa086, 0x0014, 0x00c0, 0x7e6a, 0x2001, 0x0002,
+	0xa720, 0x2204, 0xa086, 0x0014, 0x00c0, 0x7e6a, 0x2001, 0x0002,
 	0x1078, 0x4502, 0x6003, 0x0001, 0x6007, 0x0001, 0x1078, 0x5dd7,
-	0x0078, 0x7e6c, 0x1078, 0x7dff, 0x007c, 0x2011, 0xa620, 0x2204,
+	0x0078, 0x7e6c, 0x1078, 0x7dff, 0x007c, 0x2011, 0xa720, 0x2204,
 	0xa086, 0x0004, 0x00c0, 0x7e7c, 0x2001, 0x0007, 0x1078, 0x4502,
 	0x1078, 0x772d, 0x0078, 0x7e7e, 0x1078, 0x7dff, 0x007c, 0x7d4e,
 	0x7e97, 0x7d4e, 0x7ed2, 0x7d4e, 0x7f44, 0x7e8b, 0x7d4e, 0x7d4e,
@@ -3591,25 +3591,25 @@ unsigned short risc_code01[] = { 
 	0xa6b6, 0x001e, 0x00c0, 0x7e96, 0x1078, 0x772d, 0x007c, 0x0d7e,
 	0x0c7e, 0x1078, 0x7f7f, 0x00c0, 0x7ead, 0x2001, 0x0000, 0x1078,
 	0x44ee, 0x2001, 0x0002, 0x1078, 0x4502, 0x6003, 0x0001, 0x6007,
-	0x0002, 0x1078, 0x5dd7, 0x0078, 0x7ecf, 0x2009, 0xab8e, 0x2104,
+	0x0002, 0x1078, 0x5dd7, 0x0078, 0x7ecf, 0x2009, 0xac8e, 0x2104,
 	0xa086, 0x0009, 0x00c0, 0x7ec2, 0x6018, 0x2068, 0x6840, 0xa084,
 	0x00ff, 0xa005, 0x0040, 0x7ecd, 0x8001, 0x6842, 0x6017, 0x000a,
-	0x0078, 0x7ecf, 0x2009, 0xab8f, 0x2104, 0xa084, 0xff00, 0xa086,
+	0x0078, 0x7ecf, 0x2009, 0xac8f, 0x2104, 0xa084, 0xff00, 0xa086,
 	0x1900, 0x00c0, 0x7ecd, 0x0078, 0x7ea1, 0x1078, 0x7dff, 0x0c7f,
 	0x0d7f, 0x007c, 0x1078, 0x7f8e, 0x00c0, 0x7ee6, 0x2001, 0x0000,
 	0x1078, 0x44ee, 0x2001, 0x0002, 0x1078, 0x4502, 0x6003, 0x0001,
 	0x6007, 0x0002, 0x1078, 0x5dd7, 0x0078, 0x7f12, 0x1078, 0x7c83,
-	0x2009, 0xab8e, 0x2134, 0xa6b4, 0x00ff, 0xa686, 0x0005, 0x0040,
-	0x7f13, 0xa686, 0x000b, 0x0040, 0x7f10, 0x2009, 0xab8f, 0x2104,
+	0x2009, 0xac8e, 0x2134, 0xa6b4, 0x00ff, 0xa686, 0x0005, 0x0040,
+	0x7f13, 0xa686, 0x000b, 0x0040, 0x7f10, 0x2009, 0xac8f, 0x2104,
 	0xa084, 0xff00, 0x00c0, 0x7f00, 0xa686, 0x0009, 0x0040, 0x7f13,
 	0xa086, 0x1900, 0x00c0, 0x7f10, 0xa686, 0x0009, 0x0040, 0x7f13,
 	0x2001, 0x0004, 0x1078, 0x4502, 0x1078, 0x772d, 0x0078, 0x7f12,
-	0x1078, 0x7dff, 0x007c, 0x0d7e, 0x6010, 0x2068, 0x1078, 0x8d06,
+	0x1078, 0x7dff, 0x007c, 0x0d7e, 0x6010, 0x2068, 0x1078, 0x8d16,
 	0x0040, 0x7f21, 0x6838, 0xd0fc, 0x0040, 0x7f21, 0x0d7f, 0x0078,
 	0x7f10, 0x6018, 0x2068, 0x6840, 0xa084, 0x00ff, 0xa005, 0x0040,
 	0x7f32, 0x8001, 0x6842, 0x6017, 0x000a, 0x6007, 0x0016, 0x0d7f,
 	0x0078, 0x7f12, 0x68a0, 0xa086, 0x007e, 0x00c0, 0x7f3f, 0x0e7e,
-	0x2071, 0xa600, 0x1078, 0x42b8, 0x0e7f, 0x0078, 0x7f41, 0x1078,
+	0x2071, 0xa700, 0x1078, 0x42b8, 0x0e7f, 0x0078, 0x7f41, 0x1078,
 	0x2880, 0x0d7f, 0x0078, 0x7f10, 0x1078, 0x7f8e, 0x00c0, 0x7f54,
 	0x2001, 0x0004, 0x1078, 0x4502, 0x6003, 0x0001, 0x6007, 0x0003,
 	0x1078, 0x5dd7, 0x0078, 0x7f58, 0x1078, 0x7c83, 0x1078, 0x7dff,
@@ -3618,56 +3618,56 @@ unsigned short risc_code01[] = { 
 	0x7f6b, 0x1078, 0x7dff, 0x007c, 0x1078, 0x7f8e, 0x00c0, 0x7f7c,
 	0x2001, 0x000a, 0x1078, 0x4502, 0x6003, 0x0001, 0x6007, 0x0001,
 	0x1078, 0x5dd7, 0x0078, 0x7f7e, 0x1078, 0x7dff, 0x007c, 0x2009,
-	0xab8e, 0x2104, 0xa086, 0x0003, 0x00c0, 0x7f8d, 0x2009, 0xab8f,
+	0xac8e, 0x2104, 0xa086, 0x0003, 0x00c0, 0x7f8d, 0x2009, 0xac8f,
 	0x2104, 0xa084, 0xff00, 0xa086, 0x2a00, 0x007c, 0xa085, 0x0001,
 	0x007c, 0x0c7e, 0x017e, 0xac88, 0x0006, 0x2164, 0x1078, 0x45d6,
 	0x017f, 0x0c7f, 0x007c, 0x0f7e, 0x0e7e, 0x0d7e, 0x037e, 0x017e,
-	0x6018, 0x2068, 0x2071, 0xa633, 0x2e04, 0xa085, 0x0003, 0x2072,
-	0x1078, 0x8014, 0x0040, 0x7fd9, 0x2009, 0xa633, 0x2104, 0xc0cd,
-	0x200a, 0x2001, 0xa653, 0x2004, 0xd0a4, 0x0040, 0x7fc2, 0xa006,
-	0x2020, 0x2009, 0x002a, 0x1078, 0xa21d, 0x2001, 0xa60c, 0x200c,
+	0x6018, 0x2068, 0x2071, 0xa733, 0x2e04, 0xa085, 0x0003, 0x2072,
+	0x1078, 0x8014, 0x0040, 0x7fd9, 0x2009, 0xa733, 0x2104, 0xc0cd,
+	0x200a, 0x2001, 0xa753, 0x2004, 0xd0a4, 0x0040, 0x7fc2, 0xa006,
+	0x2020, 0x2009, 0x002a, 0x1078, 0xa22d, 0x2001, 0xa70c, 0x200c,
 	0xc195, 0x2102, 0x2019, 0x002a, 0x2009, 0x0001, 0x1078, 0x284f,
-	0x2071, 0xa600, 0x1078, 0x2677, 0x0c7e, 0x157e, 0x20a9, 0x0081,
+	0x2071, 0xa700, 0x1078, 0x2677, 0x0c7e, 0x157e, 0x20a9, 0x0081,
 	0x2009, 0x007f, 0x1078, 0x298e, 0x8108, 0x00f0, 0x7fd2, 0x157f,
 	0x0c7f, 0x1078, 0x7f91, 0x6813, 0x00ff, 0x6817, 0xfffe, 0x2071,
-	0xab80, 0x2079, 0x0100, 0x2e04, 0xa084, 0x00ff, 0x2069, 0xa61b,
-	0x206a, 0x78e6, 0x007e, 0x8e70, 0x2e04, 0x2069, 0xa61c, 0x206a,
-	0x78ea, 0xa084, 0xff00, 0x017f, 0xa105, 0x2009, 0xa626, 0x200a,
-	0x2069, 0xab8e, 0x2071, 0xa89e, 0x6810, 0x2072, 0x6814, 0x7006,
-	0x6818, 0x700a, 0x681c, 0x700e, 0x1078, 0x906e, 0x2001, 0x0006,
+	0xac80, 0x2079, 0x0100, 0x2e04, 0xa084, 0x00ff, 0x2069, 0xa71b,
+	0x206a, 0x78e6, 0x007e, 0x8e70, 0x2e04, 0x2069, 0xa71c, 0x206a,
+	0x78ea, 0xa084, 0xff00, 0x017f, 0xa105, 0x2009, 0xa726, 0x200a,
+	0x2069, 0xac8e, 0x2071, 0xa99e, 0x6810, 0x2072, 0x6814, 0x7006,
+	0x6818, 0x700a, 0x681c, 0x700e, 0x1078, 0x907e, 0x2001, 0x0006,
 	0x1078, 0x4502, 0x1078, 0x28a6, 0x1078, 0x772d, 0x017f, 0x037f,
 	0x0d7f, 0x0e7f, 0x0f7f, 0x007c, 0x027e, 0x037e, 0x0e7e, 0x157e,
-	0x2019, 0xa626, 0x231c, 0x83ff, 0x0040, 0x803e, 0x2071, 0xab80,
+	0x2019, 0xa726, 0x231c, 0x83ff, 0x0040, 0x803e, 0x2071, 0xac80,
 	0x2e14, 0xa294, 0x00ff, 0x7004, 0xa084, 0xff00, 0xa205, 0xa306,
-	0x00c0, 0x803e, 0x2011, 0xab96, 0xad98, 0x000a, 0x20a9, 0x0004,
-	0x1078, 0x80de, 0x00c0, 0x803e, 0x2011, 0xab9a, 0xad98, 0x0006,
+	0x00c0, 0x803e, 0x2011, 0xac96, 0xad98, 0x000a, 0x20a9, 0x0004,
+	0x1078, 0x80de, 0x00c0, 0x803e, 0x2011, 0xac9a, 0xad98, 0x0006,
 	0x20a9, 0x0004, 0x1078, 0x80de, 0x00c0, 0x803e, 0x157f, 0x0e7f,
-	0x037f, 0x027f, 0x007c, 0x0e7e, 0x2071, 0xab8c, 0x7004, 0xa086,
+	0x037f, 0x027f, 0x007c, 0x0e7e, 0x2071, 0xac8c, 0x7004, 0xa086,
 	0x0014, 0x00c0, 0x8066, 0x7008, 0xa086, 0x0800, 0x00c0, 0x8066,
 	0x700c, 0xd0ec, 0x0040, 0x8064, 0xa084, 0x0f00, 0xa086, 0x0100,
 	0x00c0, 0x8064, 0x7024, 0xd0a4, 0x00c0, 0x8061, 0xd0ac, 0x0040,
 	0x8064, 0xa006, 0x0078, 0x8066, 0xa085, 0x0001, 0x0e7f, 0x007c,
 	0x0e7e, 0x0d7e, 0x0c7e, 0x077e, 0x057e, 0x047e, 0x027e, 0x007e,
-	0x127e, 0x2091, 0x8000, 0x2029, 0xa8ba, 0x252c, 0x2021, 0xa8c0,
-	0x2424, 0x2061, 0xad00, 0x2071, 0xa600, 0x7248, 0x7064, 0xa202,
-	0x00c8, 0x80cc, 0x1078, 0xa242, 0x0040, 0x80c4, 0x671c, 0xa786,
+	0x127e, 0x2091, 0x8000, 0x2029, 0xa9ba, 0x252c, 0x2021, 0xa9c0,
+	0x2424, 0x2061, 0xae00, 0x2071, 0xa700, 0x7248, 0x7064, 0xa202,
+	0x00c8, 0x80cc, 0x1078, 0xa252, 0x0040, 0x80c4, 0x671c, 0xa786,
 	0x0001, 0x0040, 0x80c4, 0xa786, 0x0007, 0x0040, 0x80c4, 0x2500,
 	0xac06, 0x0040, 0x80c4, 0x2400, 0xac06, 0x0040, 0x80c4, 0x0c7e,
 	0x6000, 0xa086, 0x0004, 0x00c0, 0x809f, 0x1078, 0x1757, 0xa786,
-	0x0008, 0x00c0, 0x80ae, 0x1078, 0x8f00, 0x00c0, 0x80ae, 0x0c7f,
-	0x1078, 0x7c83, 0x1078, 0x8ec6, 0x0078, 0x80c4, 0x6010, 0x2068,
-	0x1078, 0x8d06, 0x0040, 0x80c1, 0xa786, 0x0003, 0x00c0, 0x80d6,
+	0x0008, 0x00c0, 0x80ae, 0x1078, 0x8f10, 0x00c0, 0x80ae, 0x0c7f,
+	0x1078, 0x7c83, 0x1078, 0x8ed6, 0x0078, 0x80c4, 0x6010, 0x2068,
+	0x1078, 0x8d16, 0x0040, 0x80c1, 0xa786, 0x0003, 0x00c0, 0x80d6,
 	0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x1078, 0x4a73, 0x1078,
-	0x8eb9, 0x1078, 0x8ec6, 0x0c7f, 0xace0, 0x0010, 0x7058, 0xac02,
+	0x8ec9, 0x1078, 0x8ed6, 0x0c7f, 0xace0, 0x0010, 0x7058, 0xac02,
 	0x00c8, 0x80cc, 0x0078, 0x807d, 0x127f, 0x007f, 0x027f, 0x047f,
 	0x057f, 0x077f, 0x0c7f, 0x0d7f, 0x0e7f, 0x007c, 0xa786, 0x0006,
-	0x00c0, 0x80b8, 0x1078, 0xa1ca, 0x0078, 0x80c1, 0x220c, 0x2304,
+	0x00c0, 0x80b8, 0x1078, 0xa1da, 0x0078, 0x80c1, 0x220c, 0x2304,
 	0xa106, 0x00c0, 0x80e9, 0x8210, 0x8318, 0x00f0, 0x80de, 0xa006,
 	0x007c, 0x2304, 0xa102, 0x0048, 0x80f1, 0x2001, 0x0001, 0x0078,
 	0x80f3, 0x2001, 0x0000, 0xa18d, 0x0001, 0x007c, 0x6004, 0xa08a,
-	0x0044, 0x10c8, 0x1332, 0x1078, 0x8eec, 0x0040, 0x8105, 0x1078,
-	0x8f00, 0x0040, 0x8112, 0x0078, 0x810b, 0x1078, 0x28a6, 0x1078,
-	0x8f00, 0x0040, 0x8112, 0x1078, 0x61cd, 0x1078, 0x772d, 0x1078,
+	0x0044, 0x10c8, 0x1332, 0x1078, 0x8efc, 0x0040, 0x8105, 0x1078,
+	0x8f10, 0x0040, 0x8112, 0x0078, 0x810b, 0x1078, 0x28a6, 0x1078,
+	0x8f10, 0x0040, 0x8112, 0x1078, 0x61cd, 0x1078, 0x772d, 0x1078,
 	0x62d1, 0x007c, 0x1078, 0x7c83, 0x0078, 0x810b, 0xa182, 0x0040,
 	0x0079, 0x811a, 0x812d, 0x812d, 0x812d, 0x812d, 0x812d, 0x812d,
 	0x812d, 0x812d, 0x812d, 0x812d, 0x812d, 0x812f, 0x812f, 0x812f,
@@ -3676,9 +3676,9 @@ unsigned short risc_code01[] = { 
 	0x8000, 0x1078, 0x62d1, 0x127f, 0x007c, 0xa186, 0x0013, 0x00c0,
 	0x8146, 0x6004, 0xa082, 0x0040, 0x0079, 0x81d1, 0xa186, 0x0027,
 	0x00c0, 0x8168, 0x1078, 0x61cd, 0x1078, 0x2880, 0x0d7e, 0x6110,
-	0x2168, 0x1078, 0x8d06, 0x0040, 0x8162, 0x6837, 0x0103, 0x684b,
+	0x2168, 0x1078, 0x8d16, 0x0040, 0x8162, 0x6837, 0x0103, 0x684b,
 	0x0029, 0x6847, 0x0000, 0x694c, 0xc1c5, 0x694e, 0x1078, 0x4a73,
-	0x1078, 0x8eb9, 0x0d7f, 0x1078, 0x772d, 0x1078, 0x62d1, 0x007c,
+	0x1078, 0x8ec9, 0x0d7f, 0x1078, 0x772d, 0x1078, 0x62d1, 0x007c,
 	0xa186, 0x0014, 0x00c0, 0x8171, 0x6004, 0xa082, 0x0040, 0x0079,
 	0x8199, 0xa186, 0x0046, 0x0040, 0x817d, 0xa186, 0x0045, 0x0040,
 	0x817d, 0xa186, 0x0047, 0x10c0, 0x1332, 0x2001, 0x0109, 0x2004,
@@ -3688,1171 +3688,1173 @@ unsigned short risc_code01[] = { 
 	0x007c, 0x81ae, 0x81ac, 0x81ac, 0x81ac, 0x81ac, 0x81ac, 0x81ac,
 	0x81ac, 0x81ac, 0x81ac, 0x81ac, 0x81ca, 0x81ca, 0x81ca, 0x81ca,
 	0x81ac, 0x81ca, 0x81ac, 0x81ca, 0x1078, 0x1332, 0x1078, 0x61cd,
-	0x0d7e, 0x6110, 0x2168, 0x1078, 0x8d06, 0x0040, 0x81c4, 0x6837,
+	0x0d7e, 0x6110, 0x2168, 0x1078, 0x8d16, 0x0040, 0x81c4, 0x6837,
 	0x0103, 0x684b, 0x0006, 0x6847, 0x0000, 0x6850, 0xc0ec, 0x6852,
-	0x1078, 0x4a73, 0x1078, 0x8eb9, 0x0d7f, 0x1078, 0x772d, 0x1078,
+	0x1078, 0x4a73, 0x1078, 0x8ec9, 0x0d7f, 0x1078, 0x772d, 0x1078,
 	0x62d1, 0x007c, 0x1078, 0x61cd, 0x1078, 0x772d, 0x1078, 0x62d1,
 	0x007c, 0x81e6, 0x81e4, 0x81e4, 0x81e4, 0x81e4, 0x81e4, 0x81e4,
 	0x81e4, 0x81e4, 0x81e4, 0x81e4, 0x81f8, 0x81f8, 0x81f8, 0x81f8,
 	0x81e4, 0x8207, 0x81e4, 0x81f8, 0x1078, 0x1332, 0x1078, 0x61cd,
-	0x2001, 0xa8a4, 0x2004, 0x603e, 0x6003, 0x0002, 0x1078, 0x62d1,
+	0x2001, 0xa9a4, 0x2004, 0x603e, 0x6003, 0x0002, 0x1078, 0x62d1,
 	0x6010, 0xa088, 0x0013, 0x2104, 0xa085, 0x0400, 0x200a, 0x007c,
-	0x1078, 0x61cd, 0x2001, 0xa8a2, 0x2004, 0x6016, 0x2001, 0xa8a4,
+	0x1078, 0x61cd, 0x2001, 0xa9a2, 0x2004, 0x6016, 0x2001, 0xa9a4,
 	0x2004, 0x603e, 0x6003, 0x000f, 0x1078, 0x62d1, 0x007c, 0x1078,
 	0x61cd, 0x1078, 0x772d, 0x1078, 0x62d1, 0x007c, 0xa182, 0x0040,
 	0x0079, 0x8212, 0x8225, 0x8225, 0x8225, 0x8225, 0x8225, 0x8227,
-	0x8327, 0x8359, 0x8225, 0x8225, 0x8225, 0x8225, 0x8225, 0x8225,
+	0x8331, 0x8363, 0x8225, 0x8225, 0x8225, 0x8225, 0x8225, 0x8225,
 	0x8225, 0x8225, 0x8225, 0x8225, 0x8225, 0x1078, 0x1332, 0x0e7e,
-	0x0d7e, 0x603f, 0x0000, 0x2071, 0xab80, 0x7124, 0x610a, 0x2071,
-	0xab8c, 0x6110, 0x2168, 0x7614, 0xa6b4, 0x0fff, 0x86ff, 0x0040,
-	0x82e9, 0xa68c, 0x0c00, 0x0040, 0x825e, 0x0f7e, 0x2c78, 0x1078,
-	0x4963, 0x0f7f, 0x0040, 0x825a, 0x684c, 0xd0ac, 0x0040, 0x825a,
-	0x6024, 0xd0dc, 0x00c0, 0x825a, 0x6850, 0xd0bc, 0x00c0, 0x825a,
-	0x7318, 0x6814, 0xa306, 0x00c0, 0x8301, 0x731c, 0x6810, 0xa306,
-	0x00c0, 0x8301, 0x7318, 0x6b62, 0x731c, 0x6b5e, 0xa68c, 0x00ff,
-	0xa186, 0x0002, 0x0040, 0x8291, 0xa186, 0x0028, 0x00c0, 0x826e,
-	0x1078, 0x8eda, 0x684b, 0x001c, 0x0078, 0x8293, 0xd6dc, 0x0040,
-	0x828a, 0x684b, 0x0015, 0x684c, 0xd0ac, 0x0040, 0x8288, 0x6914,
-	0x6a10, 0x2100, 0xa205, 0x0040, 0x8288, 0x7018, 0xa106, 0x00c0,
-	0x8285, 0x701c, 0xa206, 0x0040, 0x8288, 0x6962, 0x6a5e, 0xc6dc,
-	0x0078, 0x8293, 0xd6d4, 0x0040, 0x8291, 0x684b, 0x0007, 0x0078,
-	0x8293, 0x684b, 0x0000, 0x6837, 0x0103, 0x6e46, 0xa01e, 0xd6c4,
-	0x0040, 0x82bc, 0xa686, 0x0100, 0x00c0, 0x82a7, 0x2001, 0xab99,
-	0x2004, 0xa005, 0x00c0, 0x82a7, 0xc6c4, 0x0078, 0x8236, 0x7328,
-	0x732c, 0x6b56, 0x83ff, 0x0040, 0x82bc, 0xa38a, 0x0009, 0x0048,
-	0x82b3, 0x2019, 0x0008, 0x037e, 0x2308, 0x2019, 0xab98, 0xad90,
-	0x0019, 0x1078, 0x89e2, 0x037f, 0xd6cc, 0x0040, 0x8317, 0x7124,
-	0x695a, 0x81ff, 0x0040, 0x8317, 0xa192, 0x0021, 0x00c8, 0x82d5,
-	0x2071, 0xab98, 0x831c, 0x2300, 0xae18, 0xad90, 0x001d, 0x1078,
-	0x89e2, 0x1078, 0x91f4, 0x0078, 0x8317, 0x6838, 0xd0fc, 0x0040,
-	0x82de, 0x2009, 0x0020, 0x695a, 0x0078, 0x82c8, 0x0f7e, 0x2d78,
-	0x1078, 0x897a, 0x0f7f, 0x1078, 0x91f4, 0x1078, 0x89cf, 0x0078,
-	0x8319, 0x0f7e, 0x2c78, 0x1078, 0x4963, 0x0f7f, 0x0040, 0x8307,
-	0x684c, 0xd0ac, 0x0040, 0x8307, 0x6024, 0xd0dc, 0x00c0, 0x8307,
-	0x6850, 0xd0bc, 0x00c0, 0x8307, 0x6810, 0x6914, 0xa105, 0x0040,
-	0x8307, 0x1078, 0x8fbf, 0x0d7f, 0x0e7f, 0x0078, 0x8326, 0x684b,
-	0x0000, 0x6837, 0x0103, 0x6e46, 0x684c, 0xd0ac, 0x0040, 0x8317,
-	0x6810, 0x6914, 0xa115, 0x0040, 0x8317, 0x1078, 0x84d5, 0x1078,
-	0x4a73, 0x6218, 0x2268, 0x6a3c, 0x8211, 0x6a3e, 0x1078, 0x8f89,
-	0x0d7f, 0x0e7f, 0x00c0, 0x8326, 0x1078, 0x772d, 0x007c, 0x0f7e,
-	0x6003, 0x0003, 0x2079, 0xab8c, 0x7c04, 0x7b00, 0x7e0c, 0x7d08,
-	0x6010, 0x2078, 0x784c, 0xd0ac, 0x0040, 0x833e, 0x6003, 0x0002,
-	0x0f7f, 0x007c, 0x2130, 0x2228, 0x0078, 0x834a, 0x2400, 0x797c,
-	0xa10a, 0x2300, 0x7a80, 0xa213, 0x2600, 0xa102, 0x2500, 0xa203,
-	0x0048, 0x833a, 0x7c12, 0x7b16, 0x7e0a, 0x7d0e, 0x0f7f, 0x603f,
-	0x0000, 0x2c10, 0x1078, 0x1cf0, 0x1078, 0x5df6, 0x1078, 0x639b,
-	0x007c, 0x2001, 0xa8a4, 0x2004, 0x603e, 0x6003, 0x0004, 0x6110,
-	0x20e1, 0x0005, 0x3d18, 0x3e20, 0x2c10, 0x1078, 0x15fa, 0x007c,
-	0xa182, 0x0040, 0x0079, 0x836c, 0x837f, 0x837f, 0x837f, 0x837f,
-	0x837f, 0x8381, 0x8424, 0x837f, 0x837f, 0x843a, 0x84ab, 0x837f,
-	0x837f, 0x837f, 0x837f, 0x84ba, 0x837f, 0x837f, 0x837f, 0x1078,
-	0x1332, 0x077e, 0x0f7e, 0x0e7e, 0x0d7e, 0x2071, 0xab8c, 0x6110,
-	0x2178, 0x7614, 0xa6b4, 0x0fff, 0x7e46, 0x7f4c, 0xc7e5, 0x7f4e,
-	0x6218, 0x2268, 0x6a3c, 0x8211, 0x6a3e, 0x86ff, 0x0040, 0x841f,
-	0xa694, 0xff00, 0xa284, 0x0c00, 0x0040, 0x83a2, 0x7018, 0x7862,
-	0x701c, 0x785e, 0xa284, 0x0300, 0x0040, 0x841f, 0x1078, 0x138b,
-	0x1040, 0x1332, 0x2d00, 0x784a, 0x7f4c, 0xc7cd, 0x7f4e, 0x6837,
-	0x0103, 0x7838, 0x683a, 0x783c, 0x683e, 0x7840, 0x6842, 0x6e46,
-	0xa68c, 0x0c00, 0x0040, 0x83c0, 0x7318, 0x6b62, 0x731c, 0x6b5e,
-	0xa68c, 0x00ff, 0xa186, 0x0002, 0x0040, 0x83dc, 0xa186, 0x0028,
-	0x00c0, 0x83ce, 0x684b, 0x001c, 0x0078, 0x83de, 0xd6dc, 0x0040,
-	0x83d5, 0x684b, 0x0015, 0x0078, 0x83de, 0xd6d4, 0x0040, 0x83dc,
-	0x684b, 0x0007, 0x0078, 0x83de, 0x684b, 0x0000, 0x6f4e, 0x7850,
-	0x6852, 0x7854, 0x6856, 0xa01e, 0xd6c4, 0x0040, 0x83fc, 0x7328,
-	0x732c, 0x6b56, 0x83ff, 0x0040, 0x83fc, 0xa38a, 0x0009, 0x0048,
-	0x83f3, 0x2019, 0x0008, 0x037e, 0x2308, 0x2019, 0xab98, 0xad90,
-	0x0019, 0x1078, 0x89e2, 0x037f, 0xd6cc, 0x0040, 0x841f, 0x7124,
-	0x695a, 0x81ff, 0x0040, 0x841f, 0xa192, 0x0021, 0x00c8, 0x8413,
-	0x2071, 0xab98, 0x831c, 0x2300, 0xae18, 0xad90, 0x001d, 0x1078,
-	0x89e2, 0x0078, 0x841f, 0x7838, 0xd0fc, 0x0040, 0x841c, 0x2009,
-	0x0020, 0x695a, 0x0078, 0x8408, 0x2d78, 0x1078, 0x897a, 0x0d7f,
-	0x0e7f, 0x0f7f, 0x077f, 0x007c, 0x0f7e, 0x6003, 0x0003, 0x2079,
-	0xab8c, 0x7c04, 0x7b00, 0x7e0c, 0x7d08, 0x6010, 0x2078, 0x7c12,
-	0x7b16, 0x7e0a, 0x7d0e, 0x0f7f, 0x2c10, 0x1078, 0x1cf0, 0x1078,
-	0x6df4, 0x007c, 0x0d7e, 0x0f7e, 0x2c78, 0x1078, 0x4963, 0x0f7f,
-	0x0040, 0x8446, 0x2001, 0xa8a4, 0x2004, 0x603e, 0x6003, 0x0002,
-	0x1078, 0x627a, 0x1078, 0x639b, 0x6110, 0x2168, 0x694c, 0xd1e4,
-	0x0040, 0x84a9, 0xd1cc, 0x0040, 0x8480, 0x6948, 0x6838, 0xd0fc,
-	0x0040, 0x8478, 0x017e, 0x684c, 0x007e, 0x6850, 0x007e, 0xad90,
-	0x000d, 0xa198, 0x000d, 0x2009, 0x0020, 0x157e, 0x21a8, 0x2304,
-	0x2012, 0x8318, 0x8210, 0x00f0, 0x8467, 0x157f, 0x007f, 0x6852,
-	0x007f, 0x684e, 0x017f, 0x2168, 0x1078, 0x13b4, 0x0078, 0x84a3,
-	0x017e, 0x1078, 0x13b4, 0x0d7f, 0x1078, 0x89cf, 0x0078, 0x84a3,
-	0x6837, 0x0103, 0x6944, 0xa184, 0x00ff, 0xa0b6, 0x0002, 0x0040,
-	0x849f, 0xa086, 0x0028, 0x00c0, 0x8491, 0x684b, 0x001c, 0x0078,
-	0x84a1, 0xd1dc, 0x0040, 0x8498, 0x684b, 0x0015, 0x0078, 0x84a1,
-	0xd1d4, 0x0040, 0x849f, 0x684b, 0x0007, 0x0078, 0x84a1, 0x684b,
-	0x0000, 0x1078, 0x4a73, 0x1078, 0x8f89, 0x00c0, 0x84a9, 0x1078,
-	0x772d, 0x0d7f, 0x007c, 0x2019, 0x0001, 0x1078, 0x7058, 0x6003,
-	0x0002, 0x2001, 0xa8a4, 0x2004, 0x603e, 0x1078, 0x627a, 0x1078,
-	0x639b, 0x007c, 0x1078, 0x627a, 0x1078, 0x2880, 0x0d7e, 0x6110,
-	0x2168, 0x1078, 0x8d06, 0x0040, 0x84cf, 0x6837, 0x0103, 0x684b,
-	0x0029, 0x6847, 0x0000, 0x1078, 0x4a73, 0x1078, 0x8eb9, 0x0d7f,
-	0x1078, 0x772d, 0x1078, 0x639b, 0x007c, 0x684b, 0x0015, 0xd1fc,
-	0x0040, 0x84e1, 0x684b, 0x0007, 0x8002, 0x8000, 0x810a, 0xa189,
-	0x0000, 0x6962, 0x685e, 0x007c, 0xa182, 0x0040, 0x0079, 0x84e8,
-	0x84fb, 0x84fb, 0x84fb, 0x84fb, 0x84fb, 0x84fd, 0x84fb, 0x85d0,
-	0x85dc, 0x84fb, 0x84fb, 0x84fb, 0x84fb, 0x84fb, 0x84fb, 0x84fb,
-	0x84fb, 0x84fb, 0x84fb, 0x1078, 0x1332, 0x077e, 0x0f7e, 0x0e7e,
-	0x0d7e, 0x2071, 0xab8c, 0x6110, 0x2178, 0x7614, 0xa6b4, 0x0fff,
-	0x0f7e, 0x2c78, 0x1078, 0x4963, 0x0f7f, 0x0040, 0x851b, 0xa684,
-	0x00ff, 0x00c0, 0x851b, 0x6024, 0xd0f4, 0x0040, 0x851b, 0x1078,
-	0x8fbf, 0x0078, 0x85cb, 0x7e46, 0x7f4c, 0xc7e5, 0x7f4e, 0x6218,
-	0x2268, 0x6a3c, 0x8211, 0x6a3e, 0x86ff, 0x0040, 0x85c0, 0xa694,
-	0xff00, 0xa284, 0x0c00, 0x0040, 0x8531, 0x7018, 0x7862, 0x701c,
-	0x785e, 0xa284, 0x0300, 0x0040, 0x85bd, 0xa686, 0x0100, 0x00c0,
-	0x8543, 0x2001, 0xab99, 0x2004, 0xa005, 0x00c0, 0x8543, 0xc6c4,
-	0x7e46, 0x0078, 0x8524, 0x1078, 0x138b, 0x1040, 0x1332, 0x2d00,
+	0x0d7e, 0x603f, 0x0000, 0x2071, 0xac80, 0x7124, 0x610a, 0x2071,
+	0xac8c, 0x6110, 0x2168, 0x7614, 0xa6b4, 0x0fff, 0x86ff, 0x0040,
+	0x82f0, 0xa68c, 0x0c00, 0x0040, 0x8265, 0x0f7e, 0x2c78, 0x1078,
+	0x4963, 0x0f7f, 0x0040, 0x8261, 0x684c, 0xd0ac, 0x0040, 0x8261,
+	0x6024, 0xd0dc, 0x00c0, 0x8261, 0x6850, 0xd0bc, 0x00c0, 0x8261,
+	0x7318, 0x6814, 0xa306, 0x00c0, 0x8308, 0x731c, 0x6810, 0xa31e,
+	0x0040, 0x8261, 0xd6d4, 0x0040, 0x8308, 0x6b14, 0xa305, 0x00c0,
+	0x8308, 0x7318, 0x6b62, 0x731c, 0x6b5e, 0xa68c, 0x00ff, 0xa186,
+	0x0002, 0x0040, 0x8298, 0xa186, 0x0028, 0x00c0, 0x8275, 0x1078,
+	0x8eea, 0x684b, 0x001c, 0x0078, 0x829a, 0xd6dc, 0x0040, 0x8291,
+	0x684b, 0x0015, 0x684c, 0xd0ac, 0x0040, 0x828f, 0x6914, 0x6a10,
+	0x2100, 0xa205, 0x0040, 0x828f, 0x7018, 0xa106, 0x00c0, 0x828c,
+	0x701c, 0xa206, 0x0040, 0x828f, 0x6962, 0x6a5e, 0xc6dc, 0x0078,
+	0x829a, 0xd6d4, 0x0040, 0x8298, 0x684b, 0x0007, 0x0078, 0x829a,
+	0x684b, 0x0000, 0x6837, 0x0103, 0x6e46, 0xa01e, 0xd6c4, 0x0040,
+	0x82c3, 0xa686, 0x0100, 0x00c0, 0x82ae, 0x2001, 0xac99, 0x2004,
+	0xa005, 0x00c0, 0x82ae, 0xc6c4, 0x0078, 0x8236, 0x7328, 0x732c,
+	0x6b56, 0x83ff, 0x0040, 0x82c3, 0xa38a, 0x0009, 0x0048, 0x82ba,
+	0x2019, 0x0008, 0x037e, 0x2308, 0x2019, 0xac98, 0xad90, 0x0019,
+	0x1078, 0x89f2, 0x037f, 0xd6cc, 0x0040, 0x831e, 0x7124, 0x695a,
+	0x81ff, 0x0040, 0x831e, 0xa192, 0x0021, 0x00c8, 0x82dc, 0x2071,
+	0xac98, 0x831c, 0x2300, 0xae18, 0xad90, 0x001d, 0x1078, 0x89f2,
+	0x1078, 0x9204, 0x0078, 0x831e, 0x6838, 0xd0fc, 0x0040, 0x82e5,
+	0x2009, 0x0020, 0x695a, 0x0078, 0x82cf, 0x0f7e, 0x2d78, 0x1078,
+	0x898a, 0x0f7f, 0x1078, 0x9204, 0x1078, 0x89df, 0x0078, 0x8320,
+	0x0f7e, 0x2c78, 0x1078, 0x4963, 0x0f7f, 0x0040, 0x830e, 0x684c,
+	0xd0ac, 0x0040, 0x830e, 0x6024, 0xd0dc, 0x00c0, 0x830e, 0x6850,
+	0xd0bc, 0x00c0, 0x830e, 0x6810, 0x6914, 0xa105, 0x0040, 0x830e,
+	0x1078, 0x8fcf, 0x0d7f, 0x0e7f, 0x0078, 0x8330, 0x684b, 0x0000,
+	0x6837, 0x0103, 0x6e46, 0x684c, 0xd0ac, 0x0040, 0x831e, 0x6810,
+	0x6914, 0xa115, 0x0040, 0x831e, 0x1078, 0x84e2, 0x1078, 0x4a73,
+	0x6218, 0x2268, 0x6a3c, 0x82ff, 0x0040, 0x8328, 0x8211, 0x6a3e,
+	0x1078, 0x8f99, 0x0d7f, 0x0e7f, 0x00c0, 0x8330, 0x1078, 0x772d,
+	0x007c, 0x0f7e, 0x6003, 0x0003, 0x2079, 0xac8c, 0x7c04, 0x7b00,
+	0x7e0c, 0x7d08, 0x6010, 0x2078, 0x784c, 0xd0ac, 0x0040, 0x8348,
+	0x6003, 0x0002, 0x0f7f, 0x007c, 0x2130, 0x2228, 0x0078, 0x8354,
+	0x2400, 0x797c, 0xa10a, 0x2300, 0x7a80, 0xa213, 0x2600, 0xa102,
+	0x2500, 0xa203, 0x0048, 0x8344, 0x7c12, 0x7b16, 0x7e0a, 0x7d0e,
+	0x0f7f, 0x603f, 0x0000, 0x2c10, 0x1078, 0x1cf0, 0x1078, 0x5df6,
+	0x1078, 0x639b, 0x007c, 0x2001, 0xa9a4, 0x2004, 0x603e, 0x6003,
+	0x0004, 0x6110, 0x20e1, 0x0005, 0x3d18, 0x3e20, 0x2c10, 0x1078,
+	0x15fa, 0x007c, 0xa182, 0x0040, 0x0079, 0x8376, 0x8389, 0x8389,
+	0x8389, 0x8389, 0x8389, 0x838b, 0x8431, 0x8389, 0x8389, 0x8447,
+	0x84b8, 0x8389, 0x8389, 0x8389, 0x8389, 0x84c7, 0x8389, 0x8389,
+	0x8389, 0x1078, 0x1332, 0x077e, 0x0f7e, 0x0e7e, 0x0d7e, 0x2071,
+	0xac8c, 0x6110, 0x2178, 0x7614, 0xa6b4, 0x0fff, 0x7e46, 0x7f4c,
+	0xc7e5, 0x7f4e, 0x6218, 0x2268, 0x6a3c, 0x82ff, 0x0040, 0x83a2,
+	0x8211, 0x6a3e, 0x86ff, 0x0040, 0x842c, 0xa694, 0xff00, 0xa284,
+	0x0c00, 0x0040, 0x83af, 0x7018, 0x7862, 0x701c, 0x785e, 0xa284,
+	0x0300, 0x0040, 0x842c, 0x1078, 0x138b, 0x1040, 0x1332, 0x2d00,
+	0x784a, 0x7f4c, 0xc7cd, 0x7f4e, 0x6837, 0x0103, 0x7838, 0x683a,
+	0x783c, 0x683e, 0x7840, 0x6842, 0x6e46, 0xa68c, 0x0c00, 0x0040,
+	0x83cd, 0x7318, 0x6b62, 0x731c, 0x6b5e, 0xa68c, 0x00ff, 0xa186,
+	0x0002, 0x0040, 0x83e9, 0xa186, 0x0028, 0x00c0, 0x83db, 0x684b,
+	0x001c, 0x0078, 0x83eb, 0xd6dc, 0x0040, 0x83e2, 0x684b, 0x0015,
+	0x0078, 0x83eb, 0xd6d4, 0x0040, 0x83e9, 0x684b, 0x0007, 0x0078,
+	0x83eb, 0x684b, 0x0000, 0x6f4e, 0x7850, 0x6852, 0x7854, 0x6856,
+	0xa01e, 0xd6c4, 0x0040, 0x8409, 0x7328, 0x732c, 0x6b56, 0x83ff,
+	0x0040, 0x8409, 0xa38a, 0x0009, 0x0048, 0x8400, 0x2019, 0x0008,
+	0x037e, 0x2308, 0x2019, 0xac98, 0xad90, 0x0019, 0x1078, 0x89f2,
+	0x037f, 0xd6cc, 0x0040, 0x842c, 0x7124, 0x695a, 0x81ff, 0x0040,
+	0x842c, 0xa192, 0x0021, 0x00c8, 0x8420, 0x2071, 0xac98, 0x831c,
+	0x2300, 0xae18, 0xad90, 0x001d, 0x1078, 0x89f2, 0x0078, 0x842c,
+	0x7838, 0xd0fc, 0x0040, 0x8429, 0x2009, 0x0020, 0x695a, 0x0078,
+	0x8415, 0x2d78, 0x1078, 0x898a, 0x0d7f, 0x0e7f, 0x0f7f, 0x077f,
+	0x007c, 0x0f7e, 0x6003, 0x0003, 0x2079, 0xac8c, 0x7c04, 0x7b00,
+	0x7e0c, 0x7d08, 0x6010, 0x2078, 0x7c12, 0x7b16, 0x7e0a, 0x7d0e,
+	0x0f7f, 0x2c10, 0x1078, 0x1cf0, 0x1078, 0x6df4, 0x007c, 0x0d7e,
+	0x0f7e, 0x2c78, 0x1078, 0x4963, 0x0f7f, 0x0040, 0x8453, 0x2001,
+	0xa9a4, 0x2004, 0x603e, 0x6003, 0x0002, 0x1078, 0x627a, 0x1078,
+	0x639b, 0x6110, 0x2168, 0x694c, 0xd1e4, 0x0040, 0x84b6, 0xd1cc,
+	0x0040, 0x848d, 0x6948, 0x6838, 0xd0fc, 0x0040, 0x8485, 0x017e,
+	0x684c, 0x007e, 0x6850, 0x007e, 0xad90, 0x000d, 0xa198, 0x000d,
+	0x2009, 0x0020, 0x157e, 0x21a8, 0x2304, 0x2012, 0x8318, 0x8210,
+	0x00f0, 0x8474, 0x157f, 0x007f, 0x6852, 0x007f, 0x684e, 0x017f,
+	0x2168, 0x1078, 0x13b4, 0x0078, 0x84b0, 0x017e, 0x1078, 0x13b4,
+	0x0d7f, 0x1078, 0x89df, 0x0078, 0x84b0, 0x6837, 0x0103, 0x6944,
+	0xa184, 0x00ff, 0xa0b6, 0x0002, 0x0040, 0x84ac, 0xa086, 0x0028,
+	0x00c0, 0x849e, 0x684b, 0x001c, 0x0078, 0x84ae, 0xd1dc, 0x0040,
+	0x84a5, 0x684b, 0x0015, 0x0078, 0x84ae, 0xd1d4, 0x0040, 0x84ac,
+	0x684b, 0x0007, 0x0078, 0x84ae, 0x684b, 0x0000, 0x1078, 0x4a73,
+	0x1078, 0x8f99, 0x00c0, 0x84b6, 0x1078, 0x772d, 0x0d7f, 0x007c,
+	0x2019, 0x0001, 0x1078, 0x7058, 0x6003, 0x0002, 0x2001, 0xa9a4,
+	0x2004, 0x603e, 0x1078, 0x627a, 0x1078, 0x639b, 0x007c, 0x1078,
+	0x627a, 0x1078, 0x2880, 0x0d7e, 0x6110, 0x2168, 0x1078, 0x8d16,
+	0x0040, 0x84dc, 0x6837, 0x0103, 0x684b, 0x0029, 0x6847, 0x0000,
+	0x1078, 0x4a73, 0x1078, 0x8ec9, 0x0d7f, 0x1078, 0x772d, 0x1078,
+	0x639b, 0x007c, 0x684b, 0x0015, 0xd1fc, 0x0040, 0x84ee, 0x684b,
+	0x0007, 0x8002, 0x8000, 0x810a, 0xa189, 0x0000, 0x6962, 0x685e,
+	0x007c, 0xa182, 0x0040, 0x0079, 0x84f5, 0x8508, 0x8508, 0x8508,
+	0x8508, 0x8508, 0x850a, 0x8508, 0x85e0, 0x85ec, 0x8508, 0x8508,
+	0x8508, 0x8508, 0x8508, 0x8508, 0x8508, 0x8508, 0x8508, 0x8508,
+	0x1078, 0x1332, 0x077e, 0x0f7e, 0x0e7e, 0x0d7e, 0x2071, 0xac8c,
+	0x6110, 0x2178, 0x7614, 0xa6b4, 0x0fff, 0x0f7e, 0x2c78, 0x1078,
+	0x4963, 0x0f7f, 0x0040, 0x8528, 0xa684, 0x00ff, 0x00c0, 0x8528,
+	0x6024, 0xd0f4, 0x0040, 0x8528, 0x1078, 0x8fcf, 0x0078, 0x85db,
+	0x7e46, 0x7f4c, 0xc7e5, 0x7f4e, 0x6218, 0x2268, 0x6a3c, 0x82ff,
+	0x0040, 0x8534, 0x8211, 0x6a3e, 0x86ff, 0x0040, 0x85d0, 0xa694,
+	0xff00, 0xa284, 0x0c00, 0x0040, 0x8541, 0x7018, 0x7862, 0x701c,
+	0x785e, 0xa284, 0x0300, 0x0040, 0x85cd, 0xa686, 0x0100, 0x00c0,
+	0x8553, 0x2001, 0xac99, 0x2004, 0xa005, 0x00c0, 0x8553, 0xc6c4,
+	0x7e46, 0x0078, 0x8534, 0x1078, 0x138b, 0x1040, 0x1332, 0x2d00,
 	0x784a, 0x7f4c, 0xa7bd, 0x0200, 0x7f4e, 0x6837, 0x0103, 0x7838,
 	0x683a, 0x783c, 0x683e, 0x7840, 0x6842, 0x6e46, 0xa68c, 0x0c00,
-	0x0040, 0x855e, 0x7318, 0x6b62, 0x731c, 0x6b5e, 0xa68c, 0x00ff,
-	0xa186, 0x0002, 0x0040, 0x857a, 0xa186, 0x0028, 0x00c0, 0x856c,
-	0x684b, 0x001c, 0x0078, 0x857c, 0xd6dc, 0x0040, 0x8573, 0x684b,
-	0x0015, 0x0078, 0x857c, 0xd6d4, 0x0040, 0x857a, 0x684b, 0x0007,
-	0x0078, 0x857c, 0x684b, 0x0000, 0x6f4e, 0x7850, 0x6852, 0x7854,
-	0x6856, 0xa01e, 0xd6c4, 0x0040, 0x859a, 0x7328, 0x732c, 0x6b56,
-	0x83ff, 0x0040, 0x859a, 0xa38a, 0x0009, 0x0048, 0x8591, 0x2019,
-	0x0008, 0x037e, 0x2308, 0x2019, 0xab98, 0xad90, 0x0019, 0x1078,
-	0x89e2, 0x037f, 0xd6cc, 0x0040, 0x85bd, 0x7124, 0x695a, 0x81ff,
-	0x0040, 0x85bd, 0xa192, 0x0021, 0x00c8, 0x85b1, 0x2071, 0xab98,
-	0x831c, 0x2300, 0xae18, 0xad90, 0x001d, 0x1078, 0x89e2, 0x0078,
-	0x85bd, 0x7838, 0xd0fc, 0x0040, 0x85ba, 0x2009, 0x0020, 0x695a,
-	0x0078, 0x85a6, 0x2d78, 0x1078, 0x897a, 0xd6dc, 0x00c0, 0x85c3,
-	0xa006, 0x0078, 0x85c9, 0x2001, 0x0001, 0x2071, 0xab8c, 0x7218,
+	0x0040, 0x856e, 0x7318, 0x6b62, 0x731c, 0x6b5e, 0xa68c, 0x00ff,
+	0xa186, 0x0002, 0x0040, 0x858a, 0xa186, 0x0028, 0x00c0, 0x857c,
+	0x684b, 0x001c, 0x0078, 0x858c, 0xd6dc, 0x0040, 0x8583, 0x684b,
+	0x0015, 0x0078, 0x858c, 0xd6d4, 0x0040, 0x858a, 0x684b, 0x0007,
+	0x0078, 0x858c, 0x684b, 0x0000, 0x6f4e, 0x7850, 0x6852, 0x7854,
+	0x6856, 0xa01e, 0xd6c4, 0x0040, 0x85aa, 0x7328, 0x732c, 0x6b56,
+	0x83ff, 0x0040, 0x85aa, 0xa38a, 0x0009, 0x0048, 0x85a1, 0x2019,
+	0x0008, 0x037e, 0x2308, 0x2019, 0xac98, 0xad90, 0x0019, 0x1078,
+	0x89f2, 0x037f, 0xd6cc, 0x0040, 0x85cd, 0x7124, 0x695a, 0x81ff,
+	0x0040, 0x85cd, 0xa192, 0x0021, 0x00c8, 0x85c1, 0x2071, 0xac98,
+	0x831c, 0x2300, 0xae18, 0xad90, 0x001d, 0x1078, 0x89f2, 0x0078,
+	0x85cd, 0x7838, 0xd0fc, 0x0040, 0x85ca, 0x2009, 0x0020, 0x695a,
+	0x0078, 0x85b6, 0x2d78, 0x1078, 0x898a, 0xd6dc, 0x00c0, 0x85d3,
+	0xa006, 0x0078, 0x85d9, 0x2001, 0x0001, 0x2071, 0xac8c, 0x7218,
 	0x731c, 0x1078, 0x1653, 0x0d7f, 0x0e7f, 0x0f7f, 0x077f, 0x007c,
-	0x2001, 0xa8a4, 0x2004, 0x603e, 0x20e1, 0x0005, 0x3d18, 0x3e20,
-	0x2c10, 0x1078, 0x15fa, 0x007c, 0x2001, 0xa8a4, 0x2004, 0x603e,
+	0x2001, 0xa9a4, 0x2004, 0x603e, 0x20e1, 0x0005, 0x3d18, 0x3e20,
+	0x2c10, 0x1078, 0x15fa, 0x007c, 0x2001, 0xa9a4, 0x2004, 0x603e,
 	0x0d7e, 0x6003, 0x0002, 0x6110, 0x2168, 0x694c, 0xd1e4, 0x0040,
-	0x870c, 0x603f, 0x0000, 0x0f7e, 0x2c78, 0x1078, 0x4963, 0x0f7f,
-	0x0040, 0x8622, 0x6814, 0x6910, 0xa115, 0x0040, 0x8622, 0x6a60,
-	0xa206, 0x00c0, 0x85ff, 0x685c, 0xa106, 0x0040, 0x8622, 0x684c,
+	0x871c, 0x603f, 0x0000, 0x0f7e, 0x2c78, 0x1078, 0x4963, 0x0f7f,
+	0x0040, 0x8632, 0x6814, 0x6910, 0xa115, 0x0040, 0x8632, 0x6a60,
+	0xa206, 0x00c0, 0x860f, 0x685c, 0xa106, 0x0040, 0x8632, 0x684c,
 	0xc0e4, 0x684e, 0x6847, 0x0000, 0x6863, 0x0000, 0x685f, 0x0000,
-	0x6024, 0xd0f4, 0x00c0, 0x8617, 0x697c, 0x6810, 0xa102, 0x603a,
+	0x6024, 0xd0f4, 0x00c0, 0x8627, 0x697c, 0x6810, 0xa102, 0x603a,
 	0x6980, 0x6814, 0xa103, 0x6036, 0x6024, 0xc0f5, 0x6026, 0x0d7e,
-	0x6018, 0x2068, 0x683c, 0x8000, 0x683e, 0x0d7f, 0x1078, 0x8fbf,
-	0x0078, 0x870c, 0x694c, 0xd1cc, 0x0040, 0x86d1, 0x6948, 0x6838,
-	0xd0fc, 0x0040, 0x8689, 0x017e, 0x684c, 0x007e, 0x6850, 0x007e,
+	0x6018, 0x2068, 0x683c, 0x8000, 0x683e, 0x0d7f, 0x1078, 0x8fcf,
+	0x0078, 0x871c, 0x694c, 0xd1cc, 0x0040, 0x86e1, 0x6948, 0x6838,
+	0xd0fc, 0x0040, 0x8699, 0x017e, 0x684c, 0x007e, 0x6850, 0x007e,
 	0x0f7e, 0x2178, 0x7944, 0xa184, 0x00ff, 0xa0b6, 0x0002, 0x0040,
-	0x865c, 0xa086, 0x0028, 0x00c0, 0x8643, 0x684b, 0x001c, 0x784b,
-	0x001c, 0x0078, 0x8667, 0xd1dc, 0x0040, 0x8653, 0x684b, 0x0015,
-	0x784b, 0x0015, 0x1078, 0x916c, 0x0040, 0x8651, 0x7944, 0xc1dc,
-	0x7946, 0x0078, 0x8667, 0xd1d4, 0x0040, 0x865c, 0x684b, 0x0007,
-	0x784b, 0x0007, 0x0078, 0x8667, 0x684c, 0xd0ac, 0x0040, 0x8667,
-	0x6810, 0x6914, 0xa115, 0x0040, 0x8667, 0x1078, 0x84d5, 0x6848,
+	0x866c, 0xa086, 0x0028, 0x00c0, 0x8653, 0x684b, 0x001c, 0x784b,
+	0x001c, 0x0078, 0x8677, 0xd1dc, 0x0040, 0x8663, 0x684b, 0x0015,
+	0x784b, 0x0015, 0x1078, 0x917c, 0x0040, 0x8661, 0x7944, 0xc1dc,
+	0x7946, 0x0078, 0x8677, 0xd1d4, 0x0040, 0x866c, 0x684b, 0x0007,
+	0x784b, 0x0007, 0x0078, 0x8677, 0x684c, 0xd0ac, 0x0040, 0x8677,
+	0x6810, 0x6914, 0xa115, 0x0040, 0x8677, 0x1078, 0x84e2, 0x6848,
 	0x784a, 0x6860, 0x7862, 0x685c, 0x785e, 0xad90, 0x000d, 0xaf98,
 	0x000d, 0x2009, 0x0020, 0x157e, 0x21a8, 0x2304, 0x2012, 0x8318,
-	0x8210, 0x00f0, 0x8675, 0x157f, 0x0f7f, 0x007f, 0x6852, 0x007f,
-	0x684e, 0x1078, 0x91f4, 0x017f, 0x2168, 0x1078, 0x13b4, 0x0078,
-	0x8706, 0x017e, 0x0f7e, 0x2178, 0x7944, 0xa184, 0x00ff, 0xa0b6,
-	0x0002, 0x0040, 0x86b6, 0xa086, 0x0028, 0x00c0, 0x869d, 0x684b,
-	0x001c, 0x784b, 0x001c, 0x0078, 0x86c1, 0xd1dc, 0x0040, 0x86ad,
-	0x684b, 0x0015, 0x784b, 0x0015, 0x1078, 0x916c, 0x0040, 0x86ab,
-	0x7944, 0xc1dc, 0x7946, 0x0078, 0x86c1, 0xd1d4, 0x0040, 0x86b6,
-	0x684b, 0x0007, 0x784b, 0x0007, 0x0078, 0x86c1, 0x684c, 0xd0ac,
-	0x0040, 0x86c1, 0x6810, 0x6914, 0xa115, 0x0040, 0x86c1, 0x1078,
-	0x84d5, 0x6860, 0x7862, 0x685c, 0x785e, 0x684c, 0x784e, 0x0f7f,
-	0x1078, 0x13b4, 0x0d7f, 0x1078, 0x91f4, 0x1078, 0x89cf, 0x0078,
-	0x8706, 0x6837, 0x0103, 0x6944, 0xa184, 0x00ff, 0xa0b6, 0x0002,
-	0x0040, 0x86f7, 0xa086, 0x0028, 0x00c0, 0x86e2, 0x684b, 0x001c,
-	0x0078, 0x8704, 0xd1dc, 0x0040, 0x86f0, 0x684b, 0x0015, 0x1078,
-	0x916c, 0x0040, 0x86ee, 0x6944, 0xc1dc, 0x6946, 0x0078, 0x8704,
-	0xd1d4, 0x0040, 0x86f7, 0x684b, 0x0007, 0x0078, 0x8704, 0x684b,
-	0x0000, 0x684c, 0xd0ac, 0x0040, 0x8704, 0x6810, 0x6914, 0xa115,
-	0x0040, 0x8704, 0x1078, 0x84d5, 0x1078, 0x4a73, 0x1078, 0x8f89,
-	0x00c0, 0x870c, 0x1078, 0x772d, 0x0d7f, 0x007c, 0x1078, 0x61cd,
-	0x0078, 0x8714, 0x1078, 0x627a, 0x1078, 0x8d06, 0x0040, 0x8733,
-	0x0d7e, 0x6110, 0x2168, 0x6837, 0x0103, 0x2009, 0xa60c, 0x210c,
-	0xd18c, 0x00c0, 0x873e, 0xd184, 0x00c0, 0x873a, 0x6108, 0x694a,
-	0xa18e, 0x0029, 0x00c0, 0x872e, 0x1078, 0xa4e2, 0x6847, 0x0000,
+	0x8210, 0x00f0, 0x8685, 0x157f, 0x0f7f, 0x007f, 0x6852, 0x007f,
+	0x684e, 0x1078, 0x9204, 0x017f, 0x2168, 0x1078, 0x13b4, 0x0078,
+	0x8716, 0x017e, 0x0f7e, 0x2178, 0x7944, 0xa184, 0x00ff, 0xa0b6,
+	0x0002, 0x0040, 0x86c6, 0xa086, 0x0028, 0x00c0, 0x86ad, 0x684b,
+	0x001c, 0x784b, 0x001c, 0x0078, 0x86d1, 0xd1dc, 0x0040, 0x86bd,
+	0x684b, 0x0015, 0x784b, 0x0015, 0x1078, 0x917c, 0x0040, 0x86bb,
+	0x7944, 0xc1dc, 0x7946, 0x0078, 0x86d1, 0xd1d4, 0x0040, 0x86c6,
+	0x684b, 0x0007, 0x784b, 0x0007, 0x0078, 0x86d1, 0x684c, 0xd0ac,
+	0x0040, 0x86d1, 0x6810, 0x6914, 0xa115, 0x0040, 0x86d1, 0x1078,
+	0x84e2, 0x6860, 0x7862, 0x685c, 0x785e, 0x684c, 0x784e, 0x0f7f,
+	0x1078, 0x13b4, 0x0d7f, 0x1078, 0x9204, 0x1078, 0x89df, 0x0078,
+	0x8716, 0x6837, 0x0103, 0x6944, 0xa184, 0x00ff, 0xa0b6, 0x0002,
+	0x0040, 0x8707, 0xa086, 0x0028, 0x00c0, 0x86f2, 0x684b, 0x001c,
+	0x0078, 0x8714, 0xd1dc, 0x0040, 0x8700, 0x684b, 0x0015, 0x1078,
+	0x917c, 0x0040, 0x86fe, 0x6944, 0xc1dc, 0x6946, 0x0078, 0x8714,
+	0xd1d4, 0x0040, 0x8707, 0x684b, 0x0007, 0x0078, 0x8714, 0x684b,
+	0x0000, 0x684c, 0xd0ac, 0x0040, 0x8714, 0x6810, 0x6914, 0xa115,
+	0x0040, 0x8714, 0x1078, 0x84e2, 0x1078, 0x4a73, 0x1078, 0x8f99,
+	0x00c0, 0x871c, 0x1078, 0x772d, 0x0d7f, 0x007c, 0x1078, 0x61cd,
+	0x0078, 0x8724, 0x1078, 0x627a, 0x1078, 0x8d16, 0x0040, 0x8743,
+	0x0d7e, 0x6110, 0x2168, 0x6837, 0x0103, 0x2009, 0xa70c, 0x210c,
+	0xd18c, 0x00c0, 0x874e, 0xd184, 0x00c0, 0x874a, 0x6108, 0x694a,
+	0xa18e, 0x0029, 0x00c0, 0x873e, 0x1078, 0xa4f2, 0x6847, 0x0000,
 	0x1078, 0x4a73, 0x0d7f, 0x1078, 0x772d, 0x1078, 0x62d1, 0x1078,
-	0x639b, 0x007c, 0x684b, 0x0004, 0x0078, 0x872e, 0x684b, 0x0004,
-	0x0078, 0x872e, 0xa182, 0x0040, 0x0079, 0x8746, 0x8759, 0x8759,
-	0x8759, 0x8759, 0x8759, 0x875b, 0x8759, 0x875e, 0x8759, 0x8759,
-	0x8759, 0x8759, 0x8759, 0x8759, 0x8759, 0x8759, 0x8759, 0x8759,
-	0x8759, 0x1078, 0x1332, 0x1078, 0x772d, 0x007c, 0x007e, 0x027e,
+	0x639b, 0x007c, 0x684b, 0x0004, 0x0078, 0x873e, 0x684b, 0x0004,
+	0x0078, 0x873e, 0xa182, 0x0040, 0x0079, 0x8756, 0x8769, 0x8769,
+	0x8769, 0x8769, 0x8769, 0x876b, 0x8769, 0x876e, 0x8769, 0x8769,
+	0x8769, 0x8769, 0x8769, 0x8769, 0x8769, 0x8769, 0x8769, 0x8769,
+	0x8769, 0x1078, 0x1332, 0x1078, 0x772d, 0x007c, 0x007e, 0x027e,
 	0xa016, 0x1078, 0x15fa, 0x027f, 0x007f, 0x007c, 0xa182, 0x0085,
-	0x0079, 0x876a, 0x8773, 0x8771, 0x8771, 0x877f, 0x8771, 0x8771,
-	0x8771, 0x1078, 0x1332, 0x6003, 0x0001, 0x6106, 0x1078, 0x5d8a,
+	0x0079, 0x877a, 0x8783, 0x8781, 0x8781, 0x878f, 0x8781, 0x8781,
+	0x8781, 0x1078, 0x1332, 0x6003, 0x0001, 0x6106, 0x1078, 0x5d8a,
 	0x127e, 0x2091, 0x8000, 0x1078, 0x62d1, 0x127f, 0x007c, 0x027e,
-	0x057e, 0x0d7e, 0x0e7e, 0x2071, 0xab80, 0x7224, 0x6212, 0x7220,
-	0x1078, 0x8cf2, 0x0040, 0x87a4, 0x2268, 0x6800, 0xa086, 0x0000,
-	0x0040, 0x87a4, 0x6018, 0x6d18, 0xa52e, 0x00c0, 0x87a4, 0x0c7e,
-	0x2d60, 0x1078, 0x89f3, 0x0c7f, 0x0040, 0x87a4, 0x6803, 0x0002,
-	0x6007, 0x0086, 0x0078, 0x87a6, 0x6007, 0x0087, 0x6003, 0x0001,
+	0x057e, 0x0d7e, 0x0e7e, 0x2071, 0xac80, 0x7224, 0x6212, 0x7220,
+	0x1078, 0x8d02, 0x0040, 0x87b4, 0x2268, 0x6800, 0xa086, 0x0000,
+	0x0040, 0x87b4, 0x6018, 0x6d18, 0xa52e, 0x00c0, 0x87b4, 0x0c7e,
+	0x2d60, 0x1078, 0x8a03, 0x0c7f, 0x0040, 0x87b4, 0x6803, 0x0002,
+	0x6007, 0x0086, 0x0078, 0x87b6, 0x6007, 0x0087, 0x6003, 0x0001,
 	0x1078, 0x5d8a, 0x1078, 0x62d1, 0x0f7e, 0x2278, 0x1078, 0x4963,
-	0x0f7f, 0x0040, 0x87be, 0x6824, 0xd0ec, 0x0040, 0x87be, 0x0c7e,
-	0x2260, 0x603f, 0x0000, 0x1078, 0x8fbf, 0x0c7f, 0x0e7f, 0x0d7f,
-	0x057f, 0x027f, 0x007c, 0xa186, 0x0013, 0x00c0, 0x87d4, 0x6004,
+	0x0f7f, 0x0040, 0x87ce, 0x6824, 0xd0ec, 0x0040, 0x87ce, 0x0c7e,
+	0x2260, 0x603f, 0x0000, 0x1078, 0x8fcf, 0x0c7f, 0x0e7f, 0x0d7f,
+	0x057f, 0x027f, 0x007c, 0xa186, 0x0013, 0x00c0, 0x87e4, 0x6004,
 	0xa08a, 0x0085, 0x1048, 0x1332, 0xa08a, 0x008c, 0x10c8, 0x1332,
-	0xa082, 0x0085, 0x0079, 0x87e3, 0xa186, 0x0027, 0x0040, 0x87dc,
-	0xa186, 0x0014, 0x10c0, 0x1332, 0x1078, 0x61cd, 0x1078, 0x8ec6,
-	0x1078, 0x62d1, 0x007c, 0x87ea, 0x87ec, 0x87ec, 0x87ea, 0x87ea,
-	0x87ea, 0x87ea, 0x1078, 0x1332, 0x1078, 0x61cd, 0x1078, 0x8ec6,
-	0x1078, 0x62d1, 0x007c, 0xa186, 0x0013, 0x00c0, 0x87fd, 0x6004,
-	0xa082, 0x0085, 0x2008, 0x0078, 0x8838, 0xa186, 0x0027, 0x00c0,
-	0x8820, 0x1078, 0x61cd, 0x1078, 0x2880, 0x0d7e, 0x6010, 0x2068,
-	0x1078, 0x8d06, 0x0040, 0x8816, 0x6837, 0x0103, 0x6847, 0x0000,
-	0x684b, 0x0029, 0x1078, 0x4a73, 0x1078, 0x8eb9, 0x0d7f, 0x1078,
-	0x772d, 0x1078, 0x62d1, 0x007c, 0x1078, 0x7773, 0x0078, 0x881b,
-	0xa186, 0x0014, 0x00c0, 0x881c, 0x1078, 0x61cd, 0x0d7e, 0x6010,
-	0x2068, 0x1078, 0x8d06, 0x0040, 0x8816, 0x6837, 0x0103, 0x6847,
-	0x0000, 0x684b, 0x0006, 0x6850, 0xc0ec, 0x6852, 0x0078, 0x8812,
-	0x0079, 0x883a, 0x8843, 0x8841, 0x8841, 0x8841, 0x8841, 0x8841,
-	0x885e, 0x1078, 0x1332, 0x1078, 0x61cd, 0x6030, 0xa08c, 0xff00,
-	0x810f, 0xa186, 0x0039, 0x0040, 0x8851, 0xa186, 0x0035, 0x00c0,
-	0x8855, 0x2001, 0xa8a2, 0x0078, 0x8857, 0x2001, 0xa8a3, 0x2004,
+	0xa082, 0x0085, 0x0079, 0x87f3, 0xa186, 0x0027, 0x0040, 0x87ec,
+	0xa186, 0x0014, 0x10c0, 0x1332, 0x1078, 0x61cd, 0x1078, 0x8ed6,
+	0x1078, 0x62d1, 0x007c, 0x87fa, 0x87fc, 0x87fc, 0x87fa, 0x87fa,
+	0x87fa, 0x87fa, 0x1078, 0x1332, 0x1078, 0x61cd, 0x1078, 0x8ed6,
+	0x1078, 0x62d1, 0x007c, 0xa186, 0x0013, 0x00c0, 0x880d, 0x6004,
+	0xa082, 0x0085, 0x2008, 0x0078, 0x8848, 0xa186, 0x0027, 0x00c0,
+	0x8830, 0x1078, 0x61cd, 0x1078, 0x2880, 0x0d7e, 0x6010, 0x2068,
+	0x1078, 0x8d16, 0x0040, 0x8826, 0x6837, 0x0103, 0x6847, 0x0000,
+	0x684b, 0x0029, 0x1078, 0x4a73, 0x1078, 0x8ec9, 0x0d7f, 0x1078,
+	0x772d, 0x1078, 0x62d1, 0x007c, 0x1078, 0x7773, 0x0078, 0x882b,
+	0xa186, 0x0014, 0x00c0, 0x882c, 0x1078, 0x61cd, 0x0d7e, 0x6010,
+	0x2068, 0x1078, 0x8d16, 0x0040, 0x8826, 0x6837, 0x0103, 0x6847,
+	0x0000, 0x684b, 0x0006, 0x6850, 0xc0ec, 0x6852, 0x0078, 0x8822,
+	0x0079, 0x884a, 0x8853, 0x8851, 0x8851, 0x8851, 0x8851, 0x8851,
+	0x886e, 0x1078, 0x1332, 0x1078, 0x61cd, 0x6030, 0xa08c, 0xff00,
+	0x810f, 0xa186, 0x0039, 0x0040, 0x8861, 0xa186, 0x0035, 0x00c0,
+	0x8865, 0x2001, 0xa9a2, 0x0078, 0x8867, 0x2001, 0xa9a3, 0x2004,
 	0x6016, 0x6003, 0x000c, 0x1078, 0x62d1, 0x007c, 0x1078, 0x61cd,
-	0x6030, 0xa08c, 0xff00, 0x810f, 0xa186, 0x0039, 0x0040, 0x886c,
-	0xa186, 0x0035, 0x00c0, 0x8870, 0x2001, 0xa8a2, 0x0078, 0x8872,
-	0x2001, 0xa8a3, 0x2004, 0x6016, 0x6003, 0x000e, 0x1078, 0x62d1,
-	0x007c, 0xa182, 0x008c, 0x00c8, 0x8883, 0xa182, 0x0085, 0x0048,
-	0x8883, 0x0079, 0x8886, 0x1078, 0x7773, 0x007c, 0x888d, 0x888d,
-	0x888d, 0x888d, 0x888f, 0x88ec, 0x888d, 0x1078, 0x1332, 0x0f7e,
-	0x2c78, 0x1078, 0x4963, 0x0f7f, 0x0040, 0x88a2, 0x6030, 0xa08c,
-	0xff00, 0x810f, 0xa186, 0x0039, 0x0040, 0x8903, 0xa186, 0x0035,
-	0x0040, 0x8903, 0x0d7e, 0x1078, 0x8d06, 0x00c0, 0x88ab, 0x1078,
-	0x8eb9, 0x0078, 0x88ce, 0x6010, 0x2068, 0x684c, 0xd0e4, 0x00c0,
-	0x88b3, 0x1078, 0x8eb9, 0x6837, 0x0103, 0x6850, 0xd0b4, 0x0040,
-	0x88bf, 0x684b, 0x0006, 0xc0ec, 0x6852, 0x0078, 0x88ca, 0xd0bc,
-	0x0040, 0x88c6, 0x684b, 0x0002, 0x0078, 0x88ca, 0x684b, 0x0005,
-	0x1078, 0x8f85, 0x6847, 0x0000, 0x1078, 0x4a73, 0x2c68, 0x1078,
-	0x76c7, 0x0040, 0x88e7, 0x6003, 0x0001, 0x6007, 0x001e, 0x2009,
-	0xab8e, 0x210c, 0x6136, 0x2009, 0xab8f, 0x210c, 0x613a, 0x6918,
+	0x6030, 0xa08c, 0xff00, 0x810f, 0xa186, 0x0039, 0x0040, 0x887c,
+	0xa186, 0x0035, 0x00c0, 0x8880, 0x2001, 0xa9a2, 0x0078, 0x8882,
+	0x2001, 0xa9a3, 0x2004, 0x6016, 0x6003, 0x000e, 0x1078, 0x62d1,
+	0x007c, 0xa182, 0x008c, 0x00c8, 0x8893, 0xa182, 0x0085, 0x0048,
+	0x8893, 0x0079, 0x8896, 0x1078, 0x7773, 0x007c, 0x889d, 0x889d,
+	0x889d, 0x889d, 0x889f, 0x88fc, 0x889d, 0x1078, 0x1332, 0x0f7e,
+	0x2c78, 0x1078, 0x4963, 0x0f7f, 0x0040, 0x88b2, 0x6030, 0xa08c,
+	0xff00, 0x810f, 0xa186, 0x0039, 0x0040, 0x8913, 0xa186, 0x0035,
+	0x0040, 0x8913, 0x0d7e, 0x1078, 0x8d16, 0x00c0, 0x88bb, 0x1078,
+	0x8ec9, 0x0078, 0x88de, 0x6010, 0x2068, 0x684c, 0xd0e4, 0x00c0,
+	0x88c3, 0x1078, 0x8ec9, 0x6837, 0x0103, 0x6850, 0xd0b4, 0x0040,
+	0x88cf, 0x684b, 0x0006, 0xc0ec, 0x6852, 0x0078, 0x88da, 0xd0bc,
+	0x0040, 0x88d6, 0x684b, 0x0002, 0x0078, 0x88da, 0x684b, 0x0005,
+	0x1078, 0x8f95, 0x6847, 0x0000, 0x1078, 0x4a73, 0x2c68, 0x1078,
+	0x76c7, 0x0040, 0x88f7, 0x6003, 0x0001, 0x6007, 0x001e, 0x2009,
+	0xac8e, 0x210c, 0x6136, 0x2009, 0xac8f, 0x210c, 0x613a, 0x6918,
 	0x611a, 0x6920, 0x6122, 0x601f, 0x0001, 0x1078, 0x5d8a, 0x2d60,
 	0x1078, 0x772d, 0x0d7f, 0x007c, 0x0f7e, 0x2c78, 0x1078, 0x4963,
-	0x0f7f, 0x0040, 0x8929, 0x6030, 0xa08c, 0xff00, 0x810f, 0xa186,
-	0x0035, 0x0040, 0x8903, 0xa186, 0x001e, 0x0040, 0x8903, 0xa186,
-	0x0039, 0x00c0, 0x8929, 0x0d7e, 0x2c68, 0x1078, 0x91bc, 0x00c0,
-	0x894d, 0x1078, 0x76c7, 0x0040, 0x8926, 0x6106, 0x6003, 0x0001,
+	0x0f7f, 0x0040, 0x8939, 0x6030, 0xa08c, 0xff00, 0x810f, 0xa186,
+	0x0035, 0x0040, 0x8913, 0xa186, 0x001e, 0x0040, 0x8913, 0xa186,
+	0x0039, 0x00c0, 0x8939, 0x0d7e, 0x2c68, 0x1078, 0x91cc, 0x00c0,
+	0x895d, 0x1078, 0x76c7, 0x0040, 0x8936, 0x6106, 0x6003, 0x0001,
 	0x601f, 0x0001, 0x6918, 0x611a, 0x6928, 0x612a, 0x692c, 0x612e,
 	0x6930, 0xa18c, 0x00ff, 0x6132, 0x6934, 0x6136, 0x6938, 0x613a,
 	0x6920, 0x6122, 0x1078, 0x5d8a, 0x1078, 0x62d1, 0x2d60, 0x0078,
-	0x894d, 0x0d7e, 0x6010, 0x2068, 0x1078, 0x8d06, 0x0040, 0x894d,
-	0x6837, 0x0103, 0x6850, 0xd0b4, 0x0040, 0x893c, 0xc0ec, 0x6852,
-	0x684b, 0x0006, 0x0078, 0x8947, 0xd0bc, 0x0040, 0x8943, 0x684b,
-	0x0002, 0x0078, 0x8947, 0x684b, 0x0005, 0x1078, 0x8f85, 0x6847,
-	0x0000, 0x1078, 0x4a73, 0x1078, 0x8eb9, 0x0d7f, 0x1078, 0x772d,
-	0x007c, 0x017e, 0x0d7e, 0x6010, 0x2068, 0x1078, 0x8d06, 0x0040,
-	0x8961, 0x6837, 0x0103, 0x684b, 0x0028, 0x6847, 0x0000, 0x1078,
-	0x4a73, 0x0d7f, 0x017f, 0xa186, 0x0013, 0x0040, 0x8973, 0xa186,
-	0x0014, 0x0040, 0x8973, 0xa186, 0x0027, 0x0040, 0x8973, 0x1078,
-	0x7773, 0x0078, 0x8979, 0x1078, 0x61cd, 0x1078, 0x8ec6, 0x1078,
+	0x895d, 0x0d7e, 0x6010, 0x2068, 0x1078, 0x8d16, 0x0040, 0x895d,
+	0x6837, 0x0103, 0x6850, 0xd0b4, 0x0040, 0x894c, 0xc0ec, 0x6852,
+	0x684b, 0x0006, 0x0078, 0x8957, 0xd0bc, 0x0040, 0x8953, 0x684b,
+	0x0002, 0x0078, 0x8957, 0x684b, 0x0005, 0x1078, 0x8f95, 0x6847,
+	0x0000, 0x1078, 0x4a73, 0x1078, 0x8ec9, 0x0d7f, 0x1078, 0x772d,
+	0x007c, 0x017e, 0x0d7e, 0x6010, 0x2068, 0x1078, 0x8d16, 0x0040,
+	0x8971, 0x6837, 0x0103, 0x684b, 0x0028, 0x6847, 0x0000, 0x1078,
+	0x4a73, 0x0d7f, 0x017f, 0xa186, 0x0013, 0x0040, 0x8983, 0xa186,
+	0x0014, 0x0040, 0x8983, 0xa186, 0x0027, 0x0040, 0x8983, 0x1078,
+	0x7773, 0x0078, 0x8989, 0x1078, 0x61cd, 0x1078, 0x8ed6, 0x1078,
 	0x62d1, 0x007c, 0x057e, 0x067e, 0x0d7e, 0x0f7e, 0x2029, 0x0001,
-	0xa182, 0x0101, 0x00c8, 0x8986, 0x0078, 0x8988, 0x2009, 0x0100,
-	0x2130, 0x2069, 0xab98, 0x831c, 0x2300, 0xad18, 0x2009, 0x0020,
-	0xaf90, 0x001d, 0x1078, 0x89e2, 0xa6b2, 0x0020, 0x7804, 0xa06d,
-	0x0040, 0x899c, 0x1078, 0x13b4, 0x1078, 0x138b, 0x0040, 0x89c6,
+	0xa182, 0x0101, 0x00c8, 0x8996, 0x0078, 0x8998, 0x2009, 0x0100,
+	0x2130, 0x2069, 0xac98, 0x831c, 0x2300, 0xad18, 0x2009, 0x0020,
+	0xaf90, 0x001d, 0x1078, 0x89f2, 0xa6b2, 0x0020, 0x7804, 0xa06d,
+	0x0040, 0x89ac, 0x1078, 0x13b4, 0x1078, 0x138b, 0x0040, 0x89d6,
 	0x8528, 0x6837, 0x0110, 0x683b, 0x0000, 0x2d20, 0x7c06, 0xa68a,
-	0x003d, 0x00c8, 0x89b2, 0x2608, 0xad90, 0x000f, 0x1078, 0x89e2,
-	0x0078, 0x89c6, 0xa6b2, 0x003c, 0x2009, 0x003c, 0x2d78, 0xad90,
-	0x000f, 0x1078, 0x89e2, 0x0078, 0x899c, 0x0f7f, 0x852f, 0xa5ad,
-	0x0003, 0x7d36, 0xa5ac, 0x0000, 0x0078, 0x89cb, 0x0f7f, 0x852f,
+	0x003d, 0x00c8, 0x89c2, 0x2608, 0xad90, 0x000f, 0x1078, 0x89f2,
+	0x0078, 0x89d6, 0xa6b2, 0x003c, 0x2009, 0x003c, 0x2d78, 0xad90,
+	0x000f, 0x1078, 0x89f2, 0x0078, 0x89ac, 0x0f7f, 0x852f, 0xa5ad,
+	0x0003, 0x7d36, 0xa5ac, 0x0000, 0x0078, 0x89db, 0x0f7f, 0x852f,
 	0xa5ad, 0x0003, 0x7d36, 0x0d7f, 0x067f, 0x057f, 0x007c, 0x0f7e,
-	0x8dff, 0x0040, 0x89e0, 0x6804, 0xa07d, 0x0040, 0x89de, 0x6807,
-	0x0000, 0x1078, 0x4a73, 0x2f68, 0x0078, 0x89d3, 0x1078, 0x4a73,
-	0x0f7f, 0x007c, 0x157e, 0xa184, 0x0001, 0x0040, 0x89e8, 0x8108,
+	0x8dff, 0x0040, 0x89f0, 0x6804, 0xa07d, 0x0040, 0x89ee, 0x6807,
+	0x0000, 0x1078, 0x4a73, 0x2f68, 0x0078, 0x89e3, 0x1078, 0x4a73,
+	0x0f7f, 0x007c, 0x157e, 0xa184, 0x0001, 0x0040, 0x89f8, 0x8108,
 	0x810c, 0x21a8, 0x2304, 0x8007, 0x2012, 0x8318, 0x8210, 0x00f0,
-	0x89ea, 0x157f, 0x007c, 0x067e, 0x127e, 0x2091, 0x8000, 0x2031,
-	0x0001, 0x601c, 0xa084, 0x000f, 0x1079, 0x8a0f, 0x127f, 0x067f,
+	0x89fa, 0x157f, 0x007c, 0x067e, 0x127e, 0x2091, 0x8000, 0x2031,
+	0x0001, 0x601c, 0xa084, 0x000f, 0x1079, 0x8a1f, 0x127f, 0x067f,
 	0x007c, 0x127e, 0x2091, 0x8000, 0x067e, 0x2031, 0x0000, 0x601c,
-	0xa084, 0x000f, 0x1079, 0x8a0f, 0x067f, 0x127f, 0x007c, 0x8a29,
-	0x8a17, 0x8a24, 0x8a45, 0x8a17, 0x8a24, 0x8a45, 0x8a24, 0x1078,
-	0x1332, 0x037e, 0x2019, 0x0010, 0x1078, 0x9dc7, 0x601f, 0x0006,
+	0xa084, 0x000f, 0x1079, 0x8a1f, 0x067f, 0x127f, 0x007c, 0x8a39,
+	0x8a27, 0x8a34, 0x8a55, 0x8a27, 0x8a34, 0x8a55, 0x8a34, 0x1078,
+	0x1332, 0x037e, 0x2019, 0x0010, 0x1078, 0x9dd7, 0x601f, 0x0006,
 	0x6003, 0x0007, 0x037f, 0x007c, 0xa006, 0x007c, 0xa085, 0x0001,
-	0x007c, 0x0d7e, 0x86ff, 0x00c0, 0x8a40, 0x6010, 0x2068, 0x1078,
-	0x8d06, 0x0040, 0x8a42, 0xa00e, 0x2001, 0x0005, 0x1078, 0x4b51,
-	0x1078, 0x8f85, 0x1078, 0x4a73, 0x1078, 0x772d, 0xa085, 0x0001,
-	0x0d7f, 0x007c, 0xa006, 0x0078, 0x8a40, 0x6000, 0xa08a, 0x0010,
-	0x10c8, 0x1332, 0x1079, 0x8a4d, 0x007c, 0x8a5d, 0x8a82, 0x8a5f,
-	0x8aa5, 0x8a7e, 0x8a5d, 0x8a24, 0x8a29, 0x8a29, 0x8a24, 0x8a24,
-	0x8a24, 0x8a24, 0x8a24, 0x8a24, 0x8a24, 0x1078, 0x1332, 0x86ff,
-	0x00c0, 0x8a7b, 0x601c, 0xa086, 0x0006, 0x0040, 0x8a7b, 0x0d7e,
-	0x6010, 0x2068, 0x1078, 0x8d06, 0x0040, 0x8a70, 0x1078, 0x8f85,
+	0x007c, 0x0d7e, 0x86ff, 0x00c0, 0x8a50, 0x6010, 0x2068, 0x1078,
+	0x8d16, 0x0040, 0x8a52, 0xa00e, 0x2001, 0x0005, 0x1078, 0x4b51,
+	0x1078, 0x8f95, 0x1078, 0x4a73, 0x1078, 0x772d, 0xa085, 0x0001,
+	0x0d7f, 0x007c, 0xa006, 0x0078, 0x8a50, 0x6000, 0xa08a, 0x0010,
+	0x10c8, 0x1332, 0x1079, 0x8a5d, 0x007c, 0x8a6d, 0x8a92, 0x8a6f,
+	0x8ab5, 0x8a8e, 0x8a6d, 0x8a34, 0x8a39, 0x8a39, 0x8a34, 0x8a34,
+	0x8a34, 0x8a34, 0x8a34, 0x8a34, 0x8a34, 0x1078, 0x1332, 0x86ff,
+	0x00c0, 0x8a8b, 0x601c, 0xa086, 0x0006, 0x0040, 0x8a8b, 0x0d7e,
+	0x6010, 0x2068, 0x1078, 0x8d16, 0x0040, 0x8a80, 0x1078, 0x8f95,
 	0x0d7f, 0x6007, 0x0085, 0x6003, 0x000b, 0x601f, 0x0002, 0x1078,
 	0x5d8a, 0x1078, 0x62d1, 0xa085, 0x0001, 0x007c, 0x1078, 0x1757,
-	0x0078, 0x8a5f, 0x0e7e, 0x2071, 0xa8b1, 0x7024, 0xac06, 0x00c0,
-	0x8a8b, 0x1078, 0x6fc4, 0x601c, 0xa084, 0x000f, 0xa086, 0x0006,
-	0x00c0, 0x8a9d, 0x087e, 0x097e, 0x2049, 0x0001, 0x2c40, 0x1078,
-	0x7246, 0x097f, 0x087f, 0x0078, 0x8a9f, 0x1078, 0x6ebe, 0x0e7f,
-	0x00c0, 0x8a5f, 0x1078, 0x8a24, 0x007c, 0x037e, 0x0e7e, 0x2071,
-	0xa8b1, 0x703c, 0xac06, 0x00c0, 0x8ab5, 0x2019, 0x0000, 0x1078,
-	0x7058, 0x0e7f, 0x037f, 0x0078, 0x8a5f, 0x1078, 0x738a, 0x0e7f,
-	0x037f, 0x00c0, 0x8a5f, 0x1078, 0x8a24, 0x007c, 0x0c7e, 0x601c,
-	0xa084, 0x000f, 0x1079, 0x8ac6, 0x0c7f, 0x007c, 0x8ad5, 0x8b47,
-	0x8c7f, 0x8ae0, 0x8ec6, 0x8ad5, 0x9db8, 0x772d, 0x8b47, 0x1078,
-	0x8f00, 0x00c0, 0x8ad5, 0x1078, 0x7c83, 0x007c, 0x1078, 0x61cd,
+	0x0078, 0x8a6f, 0x0e7e, 0x2071, 0xa9b1, 0x7024, 0xac06, 0x00c0,
+	0x8a9b, 0x1078, 0x6fc4, 0x601c, 0xa084, 0x000f, 0xa086, 0x0006,
+	0x00c0, 0x8aad, 0x087e, 0x097e, 0x2049, 0x0001, 0x2c40, 0x1078,
+	0x7246, 0x097f, 0x087f, 0x0078, 0x8aaf, 0x1078, 0x6ebe, 0x0e7f,
+	0x00c0, 0x8a6f, 0x1078, 0x8a34, 0x007c, 0x037e, 0x0e7e, 0x2071,
+	0xa9b1, 0x703c, 0xac06, 0x00c0, 0x8ac5, 0x2019, 0x0000, 0x1078,
+	0x7058, 0x0e7f, 0x037f, 0x0078, 0x8a6f, 0x1078, 0x738a, 0x0e7f,
+	0x037f, 0x00c0, 0x8a6f, 0x1078, 0x8a34, 0x007c, 0x0c7e, 0x601c,
+	0xa084, 0x000f, 0x1079, 0x8ad6, 0x0c7f, 0x007c, 0x8ae5, 0x8b57,
+	0x8c8f, 0x8af0, 0x8ed6, 0x8ae5, 0x9dc8, 0x772d, 0x8b57, 0x1078,
+	0x8f10, 0x00c0, 0x8ae5, 0x1078, 0x7c83, 0x007c, 0x1078, 0x61cd,
 	0x1078, 0x62d1, 0x1078, 0x772d, 0x007c, 0x6017, 0x0001, 0x007c,
-	0x1078, 0x8d06, 0x0040, 0x8ae8, 0x6010, 0xa080, 0x0019, 0x2c02,
-	0x6000, 0xa08a, 0x0010, 0x10c8, 0x1332, 0x1079, 0x8af0, 0x007c,
-	0x8b00, 0x8b02, 0x8b24, 0x8b36, 0x8b43, 0x8b00, 0x8ad5, 0x8ad5,
-	0x8ad5, 0x8b36, 0x8b36, 0x8b00, 0x8b00, 0x8b00, 0x8b00, 0x8b40,
+	0x1078, 0x8d16, 0x0040, 0x8af8, 0x6010, 0xa080, 0x0019, 0x2c02,
+	0x6000, 0xa08a, 0x0010, 0x10c8, 0x1332, 0x1079, 0x8b00, 0x007c,
+	0x8b10, 0x8b12, 0x8b34, 0x8b46, 0x8b53, 0x8b10, 0x8ae5, 0x8ae5,
+	0x8ae5, 0x8b46, 0x8b46, 0x8b10, 0x8b10, 0x8b10, 0x8b10, 0x8b50,
 	0x1078, 0x1332, 0x0e7e, 0x6010, 0x2070, 0x7050, 0xc0b5, 0x7052,
-	0x2071, 0xa8b1, 0x7024, 0xac06, 0x0040, 0x8b20, 0x1078, 0x6ebe,
-	0x6007, 0x0085, 0x6003, 0x000b, 0x601f, 0x0002, 0x2001, 0xa8a3,
+	0x2071, 0xa9b1, 0x7024, 0xac06, 0x0040, 0x8b30, 0x1078, 0x6ebe,
+	0x6007, 0x0085, 0x6003, 0x000b, 0x601f, 0x0002, 0x2001, 0xa9a3,
 	0x2004, 0x6016, 0x1078, 0x5d8a, 0x1078, 0x62d1, 0x0e7f, 0x007c,
-	0x6017, 0x0001, 0x0078, 0x8b1e, 0x0d7e, 0x6010, 0x2068, 0x6850,
+	0x6017, 0x0001, 0x0078, 0x8b2e, 0x0d7e, 0x6010, 0x2068, 0x6850,
 	0xc0b5, 0x6852, 0x0d7f, 0x6007, 0x0085, 0x6003, 0x000b, 0x601f,
 	0x0002, 0x1078, 0x5d8a, 0x1078, 0x62d1, 0x007c, 0x0d7e, 0x6017,
 	0x0001, 0x6010, 0x2068, 0x6850, 0xc0b5, 0x6852, 0x0d7f, 0x007c,
-	0x1078, 0x772d, 0x007c, 0x1078, 0x1757, 0x0078, 0x8b24, 0x6000,
-	0xa08a, 0x0010, 0x10c8, 0x1332, 0x1079, 0x8b4f, 0x007c, 0x8b5f,
-	0x8add, 0x8b61, 0x8b5f, 0x8b61, 0x8b61, 0x8ad6, 0x8b5f, 0x8acf,
-	0x8acf, 0x8b5f, 0x8b5f, 0x8b5f, 0x8b5f, 0x8b5f, 0x8b5f, 0x1078,
+	0x1078, 0x772d, 0x007c, 0x1078, 0x1757, 0x0078, 0x8b34, 0x6000,
+	0xa08a, 0x0010, 0x10c8, 0x1332, 0x1079, 0x8b5f, 0x007c, 0x8b6f,
+	0x8aed, 0x8b71, 0x8b6f, 0x8b71, 0x8b71, 0x8ae6, 0x8b6f, 0x8adf,
+	0x8adf, 0x8b6f, 0x8b6f, 0x8b6f, 0x8b6f, 0x8b6f, 0x8b6f, 0x1078,
 	0x1332, 0x0d7e, 0x6018, 0x2068, 0x6804, 0xa084, 0x00ff, 0x0d7f,
-	0xa08a, 0x000c, 0x10c8, 0x1332, 0x1079, 0x8b6f, 0x007c, 0x8b7b,
-	0x8c23, 0x8b7d, 0x8bbd, 0x8b7d, 0x8bbd, 0x8b7d, 0x8b8a, 0x8b7b,
-	0x8bbd, 0x8b7b, 0x8ba7, 0x1078, 0x1332, 0x6004, 0xa08e, 0x0016,
-	0x0040, 0x8bb8, 0xa08e, 0x0004, 0x0040, 0x8bb8, 0xa08e, 0x0002,
-	0x0040, 0x8bb8, 0x6004, 0x1078, 0x8f00, 0x0040, 0x8c3e, 0xa08e,
-	0x0021, 0x0040, 0x8c42, 0xa08e, 0x0022, 0x0040, 0x8c3e, 0xa08e,
-	0x003d, 0x0040, 0x8c42, 0xa08e, 0x0039, 0x0040, 0x8c46, 0xa08e,
-	0x0035, 0x0040, 0x8c46, 0xa08e, 0x001e, 0x0040, 0x8bba, 0xa08e,
-	0x0001, 0x00c0, 0x8bb6, 0x0d7e, 0x6018, 0x2068, 0x6804, 0xa084,
-	0x00ff, 0x0d7f, 0xa086, 0x0006, 0x0040, 0x8bb8, 0x1078, 0x2880,
-	0x1078, 0x7c83, 0x1078, 0x8ec6, 0x007c, 0x0c7e, 0x0d7e, 0x6104,
-	0xa186, 0x0016, 0x0040, 0x8c13, 0xa186, 0x0002, 0x00c0, 0x8be6,
-	0x6018, 0x2068, 0x68a0, 0xd0bc, 0x00c0, 0x8c6a, 0x6840, 0xa084,
-	0x00ff, 0xa005, 0x0040, 0x8be6, 0x8001, 0x6842, 0x6013, 0x0000,
-	0x601f, 0x0007, 0x6017, 0x0398, 0x1078, 0x76c7, 0x0040, 0x8be6,
-	0x2d00, 0x601a, 0x601f, 0x0001, 0x0078, 0x8c13, 0x0d7f, 0x0c7f,
-	0x6004, 0xa08e, 0x0002, 0x00c0, 0x8c04, 0x6018, 0xa080, 0x0028,
-	0x2004, 0xa086, 0x007e, 0x00c0, 0x8c04, 0x2009, 0xa633, 0x2104,
-	0xc085, 0x200a, 0x0e7e, 0x2071, 0xa600, 0x1078, 0x42b8, 0x0e7f,
-	0x1078, 0x7c83, 0x0078, 0x8c08, 0x1078, 0x7c83, 0x1078, 0x2880,
+	0xa08a, 0x000c, 0x10c8, 0x1332, 0x1079, 0x8b7f, 0x007c, 0x8b8b,
+	0x8c33, 0x8b8d, 0x8bcd, 0x8b8d, 0x8bcd, 0x8b8d, 0x8b9a, 0x8b8b,
+	0x8bcd, 0x8b8b, 0x8bb7, 0x1078, 0x1332, 0x6004, 0xa08e, 0x0016,
+	0x0040, 0x8bc8, 0xa08e, 0x0004, 0x0040, 0x8bc8, 0xa08e, 0x0002,
+	0x0040, 0x8bc8, 0x6004, 0x1078, 0x8f10, 0x0040, 0x8c4e, 0xa08e,
+	0x0021, 0x0040, 0x8c52, 0xa08e, 0x0022, 0x0040, 0x8c4e, 0xa08e,
+	0x003d, 0x0040, 0x8c52, 0xa08e, 0x0039, 0x0040, 0x8c56, 0xa08e,
+	0x0035, 0x0040, 0x8c56, 0xa08e, 0x001e, 0x0040, 0x8bca, 0xa08e,
+	0x0001, 0x00c0, 0x8bc6, 0x0d7e, 0x6018, 0x2068, 0x6804, 0xa084,
+	0x00ff, 0x0d7f, 0xa086, 0x0006, 0x0040, 0x8bc8, 0x1078, 0x2880,
+	0x1078, 0x7c83, 0x1078, 0x8ed6, 0x007c, 0x0c7e, 0x0d7e, 0x6104,
+	0xa186, 0x0016, 0x0040, 0x8c23, 0xa186, 0x0002, 0x00c0, 0x8bf6,
+	0x6018, 0x2068, 0x68a0, 0xd0bc, 0x00c0, 0x8c7a, 0x6840, 0xa084,
+	0x00ff, 0xa005, 0x0040, 0x8bf6, 0x8001, 0x6842, 0x6013, 0x0000,
+	0x601f, 0x0007, 0x6017, 0x0398, 0x1078, 0x76c7, 0x0040, 0x8bf6,
+	0x2d00, 0x601a, 0x601f, 0x0001, 0x0078, 0x8c23, 0x0d7f, 0x0c7f,
+	0x6004, 0xa08e, 0x0002, 0x00c0, 0x8c14, 0x6018, 0xa080, 0x0028,
+	0x2004, 0xa086, 0x007e, 0x00c0, 0x8c14, 0x2009, 0xa733, 0x2104,
+	0xc085, 0x200a, 0x0e7e, 0x2071, 0xa700, 0x1078, 0x42b8, 0x0e7f,
+	0x1078, 0x7c83, 0x0078, 0x8c18, 0x1078, 0x7c83, 0x1078, 0x2880,
 	0x0e7e, 0x127e, 0x2091, 0x8000, 0x1078, 0x28a6, 0x127f, 0x0e7f,
-	0x1078, 0x8ec6, 0x007c, 0x2001, 0x0002, 0x1078, 0x4502, 0x6003,
+	0x1078, 0x8ed6, 0x007c, 0x2001, 0x0002, 0x1078, 0x4502, 0x6003,
 	0x0001, 0x6007, 0x0002, 0x1078, 0x5dd7, 0x1078, 0x62d1, 0x0d7f,
-	0x0c7f, 0x0078, 0x8c12, 0x0c7e, 0x0d7e, 0x6104, 0xa186, 0x0016,
-	0x0040, 0x8c13, 0x6018, 0x2068, 0x6840, 0xa084, 0x00ff, 0xa005,
-	0x0040, 0x8be6, 0x8001, 0x6842, 0x6003, 0x0001, 0x1078, 0x5dd7,
-	0x1078, 0x62d1, 0x0d7f, 0x0c7f, 0x0078, 0x8c12, 0x1078, 0x7c83,
-	0x0078, 0x8bba, 0x1078, 0x7ca6, 0x0078, 0x8bba, 0x0d7e, 0x2c68,
-	0x6104, 0x1078, 0x91bc, 0x0d7f, 0x0040, 0x8c52, 0x1078, 0x772d,
-	0x0078, 0x8c69, 0x6004, 0x8007, 0x6130, 0xa18c, 0x00ff, 0xa105,
+	0x0c7f, 0x0078, 0x8c22, 0x0c7e, 0x0d7e, 0x6104, 0xa186, 0x0016,
+	0x0040, 0x8c23, 0x6018, 0x2068, 0x6840, 0xa084, 0x00ff, 0xa005,
+	0x0040, 0x8bf6, 0x8001, 0x6842, 0x6003, 0x0001, 0x1078, 0x5dd7,
+	0x1078, 0x62d1, 0x0d7f, 0x0c7f, 0x0078, 0x8c22, 0x1078, 0x7c83,
+	0x0078, 0x8bca, 0x1078, 0x7ca6, 0x0078, 0x8bca, 0x0d7e, 0x2c68,
+	0x6104, 0x1078, 0x91cc, 0x0d7f, 0x0040, 0x8c62, 0x1078, 0x772d,
+	0x0078, 0x8c79, 0x6004, 0x8007, 0x6130, 0xa18c, 0x00ff, 0xa105,
 	0x6032, 0x6007, 0x0085, 0x6003, 0x000b, 0x601f, 0x0002, 0x6038,
-	0x600a, 0x2001, 0xa8a3, 0x2004, 0x6016, 0x1078, 0x5d8a, 0x1078,
+	0x600a, 0x2001, 0xa9a3, 0x2004, 0x6016, 0x1078, 0x5d8a, 0x1078,
 	0x62d1, 0x007c, 0x0d7f, 0x0c7f, 0x1078, 0x7c83, 0x1078, 0x2880,
 	0x0e7e, 0x127e, 0x2091, 0x8000, 0x1078, 0x28a6, 0x6013, 0x0000,
 	0x601f, 0x0007, 0x6017, 0x0398, 0x127f, 0x0e7f, 0x007c, 0x6000,
-	0xa08a, 0x0010, 0x10c8, 0x1332, 0x1079, 0x8c87, 0x007c, 0x8c97,
-	0x8c97, 0x8c97, 0x8c97, 0x8c97, 0x8c97, 0x8c97, 0x8c97, 0x8c97,
-	0x8ad5, 0x8c97, 0x8add, 0x8c99, 0x8add, 0x8ca7, 0x8c97, 0x1078,
-	0x1332, 0x6004, 0xa086, 0x008b, 0x0040, 0x8ca7, 0x6007, 0x008b,
+	0xa08a, 0x0010, 0x10c8, 0x1332, 0x1079, 0x8c97, 0x007c, 0x8ca7,
+	0x8ca7, 0x8ca7, 0x8ca7, 0x8ca7, 0x8ca7, 0x8ca7, 0x8ca7, 0x8ca7,
+	0x8ae5, 0x8ca7, 0x8aed, 0x8ca9, 0x8aed, 0x8cb7, 0x8ca7, 0x1078,
+	0x1332, 0x6004, 0xa086, 0x008b, 0x0040, 0x8cb7, 0x6007, 0x008b,
 	0x6003, 0x000d, 0x1078, 0x5d8a, 0x1078, 0x62d1, 0x007c, 0x1078,
-	0x8eb9, 0x1078, 0x8d06, 0x0040, 0x8cdf, 0x1078, 0x2880, 0x0d7e,
-	0x1078, 0x8d06, 0x0040, 0x8cc1, 0x6010, 0x2068, 0x6837, 0x0103,
+	0x8ec9, 0x1078, 0x8d16, 0x0040, 0x8cef, 0x1078, 0x2880, 0x0d7e,
+	0x1078, 0x8d16, 0x0040, 0x8cd1, 0x6010, 0x2068, 0x6837, 0x0103,
 	0x684b, 0x0006, 0x6847, 0x0000, 0x6850, 0xc0ed, 0x6852, 0x1078,
-	0x4a73, 0x2c68, 0x1078, 0x76c7, 0x0040, 0x8ccf, 0x6818, 0x601a,
-	0x0c7e, 0x2d60, 0x1078, 0x8ec6, 0x0c7f, 0x0078, 0x8cd0, 0x2d60,
+	0x4a73, 0x2c68, 0x1078, 0x76c7, 0x0040, 0x8cdf, 0x6818, 0x601a,
+	0x0c7e, 0x2d60, 0x1078, 0x8ed6, 0x0c7f, 0x0078, 0x8ce0, 0x2d60,
 	0x0d7f, 0x6013, 0x0000, 0x601f, 0x0001, 0x6007, 0x0001, 0x6003,
-	0x0001, 0x1078, 0x5dd7, 0x1078, 0x62d1, 0x0078, 0x8cf1, 0x6030,
-	0xa08c, 0xff00, 0x810f, 0xa186, 0x0039, 0x0040, 0x8ceb, 0xa186,
-	0x0035, 0x00c0, 0x8cef, 0x1078, 0x2880, 0x0078, 0x8cc1, 0x1078,
-	0x8ec6, 0x007c, 0xa284, 0x000f, 0x00c0, 0x8d03, 0xa282, 0xad00,
-	0x0048, 0x8d03, 0x2001, 0xa616, 0x2004, 0xa202, 0x00c8, 0x8d03,
-	0xa085, 0x0001, 0x007c, 0xa006, 0x0078, 0x8d02, 0x027e, 0x0e7e,
-	0x2071, 0xa600, 0x6210, 0x705c, 0xa202, 0x0048, 0x8d18, 0x7060,
-	0xa202, 0x00c8, 0x8d18, 0xa085, 0x0001, 0x0e7f, 0x027f, 0x007c,
-	0xa006, 0x0078, 0x8d15, 0x0e7e, 0x0c7e, 0x037e, 0x007e, 0x127e,
-	0x2091, 0x8000, 0x2061, 0xad00, 0x2071, 0xa600, 0x7348, 0x7064,
-	0xa302, 0x00c8, 0x8d45, 0x601c, 0xa206, 0x00c0, 0x8d3d, 0x1078,
-	0x902b, 0x0040, 0x8d3d, 0x1078, 0x8f00, 0x00c0, 0x8d39, 0x1078,
+	0x0001, 0x1078, 0x5dd7, 0x1078, 0x62d1, 0x0078, 0x8d01, 0x6030,
+	0xa08c, 0xff00, 0x810f, 0xa186, 0x0039, 0x0040, 0x8cfb, 0xa186,
+	0x0035, 0x00c0, 0x8cff, 0x1078, 0x2880, 0x0078, 0x8cd1, 0x1078,
+	0x8ed6, 0x007c, 0xa284, 0x000f, 0x00c0, 0x8d13, 0xa282, 0xae00,
+	0x0048, 0x8d13, 0x2001, 0xa716, 0x2004, 0xa202, 0x00c8, 0x8d13,
+	0xa085, 0x0001, 0x007c, 0xa006, 0x0078, 0x8d12, 0x027e, 0x0e7e,
+	0x2071, 0xa700, 0x6210, 0x705c, 0xa202, 0x0048, 0x8d28, 0x7060,
+	0xa202, 0x00c8, 0x8d28, 0xa085, 0x0001, 0x0e7f, 0x027f, 0x007c,
+	0xa006, 0x0078, 0x8d25, 0x0e7e, 0x0c7e, 0x037e, 0x007e, 0x127e,
+	0x2091, 0x8000, 0x2061, 0xae00, 0x2071, 0xa700, 0x7348, 0x7064,
+	0xa302, 0x00c8, 0x8d55, 0x601c, 0xa206, 0x00c0, 0x8d4d, 0x1078,
+	0x903b, 0x0040, 0x8d4d, 0x1078, 0x8f10, 0x00c0, 0x8d49, 0x1078,
 	0x7c83, 0x0c7e, 0x1078, 0x772d, 0x0c7f, 0xace0, 0x0010, 0x7058,
-	0xac02, 0x00c8, 0x8d45, 0x0078, 0x8d26, 0x127f, 0x007f, 0x037f,
-	0x0c7f, 0x0e7f, 0x007c, 0x0e7e, 0x0c7e, 0x017e, 0xa188, 0xa735,
-	0x210c, 0x81ff, 0x0040, 0x8d59, 0x2061, 0xa9b3, 0x611a, 0x1078,
-	0x2880, 0xa006, 0x0078, 0x8d5e, 0xa085, 0x0001, 0x017f, 0x0c7f,
+	0xac02, 0x00c8, 0x8d55, 0x0078, 0x8d36, 0x127f, 0x007f, 0x037f,
+	0x0c7f, 0x0e7f, 0x007c, 0x0e7e, 0x0c7e, 0x017e, 0xa188, 0xa835,
+	0x210c, 0x81ff, 0x0040, 0x8d69, 0x2061, 0xaab3, 0x611a, 0x1078,
+	0x2880, 0xa006, 0x0078, 0x8d6e, 0xa085, 0x0001, 0x017f, 0x0c7f,
 	0x0e7f, 0x007c, 0x0c7e, 0x057e, 0x127e, 0x2091, 0x8000, 0x0c7e,
-	0x1078, 0x76c7, 0x057f, 0x0040, 0x8d7b, 0x6612, 0x651a, 0x601f,
+	0x1078, 0x76c7, 0x057f, 0x0040, 0x8d8b, 0x6612, 0x651a, 0x601f,
 	0x0003, 0x2009, 0x004b, 0x1078, 0x775c, 0xa085, 0x0001, 0x127f,
-	0x057f, 0x0c7f, 0x007c, 0xa006, 0x0078, 0x8d77, 0x0c7e, 0x057e,
+	0x057f, 0x0c7f, 0x007c, 0xa006, 0x0078, 0x8d87, 0x0c7e, 0x057e,
 	0x127e, 0x2091, 0x8000, 0x62a0, 0x0c7e, 0x1078, 0x76c7, 0x057f,
-	0x0040, 0x8da9, 0x6013, 0x0000, 0x651a, 0x601f, 0x0003, 0x0c7e,
+	0x0040, 0x8db9, 0x6013, 0x0000, 0x651a, 0x601f, 0x0003, 0x0c7e,
 	0x2560, 0x1078, 0x47e9, 0x0c7f, 0x1078, 0x5f01, 0x077e, 0x2039,
-	0x0000, 0x1078, 0x5e0a, 0x2c08, 0x1078, 0x9f8b, 0x077f, 0x2009,
+	0x0000, 0x1078, 0x5e0a, 0x2c08, 0x1078, 0x9f9b, 0x077f, 0x2009,
 	0x004c, 0x1078, 0x775c, 0xa085, 0x0001, 0x127f, 0x057f, 0x0c7f,
-	0x007c, 0xa006, 0x0078, 0x8da5, 0x0f7e, 0x0c7e, 0x047e, 0x0c7e,
-	0x1078, 0x76c7, 0x2c78, 0x0c7f, 0x0040, 0x8dc6, 0x7e12, 0x2c00,
-	0x781a, 0x781f, 0x0003, 0x2021, 0x0005, 0x1078, 0x8e11, 0x2f60,
+	0x007c, 0xa006, 0x0078, 0x8db5, 0x0f7e, 0x0c7e, 0x047e, 0x0c7e,
+	0x1078, 0x76c7, 0x2c78, 0x0c7f, 0x0040, 0x8dd6, 0x7e12, 0x2c00,
+	0x781a, 0x781f, 0x0003, 0x2021, 0x0005, 0x1078, 0x8e21, 0x2f60,
 	0x2009, 0x004d, 0x1078, 0x775c, 0xa085, 0x0001, 0x047f, 0x0c7f,
 	0x0f7f, 0x007c, 0x0f7e, 0x0c7e, 0x047e, 0x0c7e, 0x1078, 0x76c7,
-	0x2c78, 0x0c7f, 0x0040, 0x8de4, 0x7e12, 0x2c00, 0x781a, 0x781f,
-	0x0003, 0x2021, 0x0005, 0x1078, 0x8e11, 0x2f60, 0x2009, 0x004e,
+	0x2c78, 0x0c7f, 0x0040, 0x8df4, 0x7e12, 0x2c00, 0x781a, 0x781f,
+	0x0003, 0x2021, 0x0005, 0x1078, 0x8e21, 0x2f60, 0x2009, 0x004e,
 	0x1078, 0x775c, 0xa085, 0x0001, 0x047f, 0x0c7f, 0x0f7f, 0x007c,
 	0x0f7e, 0x0c7e, 0x047e, 0x0c7e, 0x1078, 0x76c7, 0x2c78, 0x0c7f,
-	0x0040, 0x8e0d, 0x7e12, 0x2c00, 0x781a, 0x781f, 0x0003, 0x2021,
-	0x0004, 0x1078, 0x8e11, 0x2001, 0xa89d, 0x2004, 0xd0fc, 0x0040,
-	0x8e06, 0x2f60, 0x1078, 0x772d, 0x0078, 0x8e0b, 0x2f60, 0x2009,
+	0x0040, 0x8e1d, 0x7e12, 0x2c00, 0x781a, 0x781f, 0x0003, 0x2021,
+	0x0004, 0x1078, 0x8e21, 0x2001, 0xa99d, 0x2004, 0xd0fc, 0x0040,
+	0x8e16, 0x2f60, 0x1078, 0x772d, 0x0078, 0x8e1b, 0x2f60, 0x2009,
 	0x0052, 0x1078, 0x775c, 0xa085, 0x0001, 0x047f, 0x0c7f, 0x0f7f,
 	0x007c, 0x097e, 0x077e, 0x127e, 0x2091, 0x8000, 0x1078, 0x4775,
-	0x0040, 0x8e1e, 0x2001, 0x8e16, 0x0078, 0x8e24, 0x1078, 0x4739,
-	0x0040, 0x8e2d, 0x2001, 0x8e1e, 0x007e, 0xa00e, 0x2400, 0x1078,
+	0x0040, 0x8e2e, 0x2001, 0x8e26, 0x0078, 0x8e34, 0x1078, 0x4739,
+	0x0040, 0x8e3d, 0x2001, 0x8e2e, 0x007e, 0xa00e, 0x2400, 0x1078,
 	0x4b51, 0x1078, 0x4a73, 0x007f, 0x007a, 0x2418, 0x1078, 0x6161,
 	0x62a0, 0x087e, 0x2041, 0x0001, 0x2039, 0x0001, 0x2608, 0x1078,
-	0x5f1b, 0x087f, 0x1078, 0x5e0a, 0x2f08, 0x2648, 0x1078, 0x9f8b,
+	0x5f1b, 0x087f, 0x1078, 0x5e0a, 0x2f08, 0x2648, 0x1078, 0x9f9b,
 	0x613c, 0x81ff, 0x1040, 0x5fdb, 0x1078, 0x62d1, 0x127f, 0x077f,
 	0x097f, 0x007c, 0x0c7e, 0x127e, 0x2091, 0x8000, 0x0c7e, 0x1078,
-	0x76c7, 0x017f, 0x0040, 0x8e63, 0x660a, 0x611a, 0x601f, 0x0001,
+	0x76c7, 0x017f, 0x0040, 0x8e73, 0x660a, 0x611a, 0x601f, 0x0001,
 	0x2d00, 0x6012, 0x2009, 0x001f, 0x1078, 0x775c, 0xa085, 0x0001,
-	0x127f, 0x0c7f, 0x007c, 0xa006, 0x0078, 0x8e60, 0x0c7e, 0x127e,
-	0x2091, 0x8000, 0x0c7e, 0x1078, 0x76c7, 0x017f, 0x0040, 0x8e7f,
+	0x127f, 0x0c7f, 0x007c, 0xa006, 0x0078, 0x8e70, 0x0c7e, 0x127e,
+	0x2091, 0x8000, 0x0c7e, 0x1078, 0x76c7, 0x017f, 0x0040, 0x8e8f,
 	0x660a, 0x611a, 0x601f, 0x0008, 0x2d00, 0x6012, 0x2009, 0x0021,
 	0x1078, 0x775c, 0xa085, 0x0001, 0x127f, 0x0c7f, 0x007c, 0xa006,
-	0x0078, 0x8e7c, 0x0c7e, 0x127e, 0x2091, 0x8000, 0x0c7e, 0x1078,
-	0x76c7, 0x017f, 0x0040, 0x8e9b, 0x660a, 0x611a, 0x601f, 0x0001,
+	0x0078, 0x8e8c, 0x0c7e, 0x127e, 0x2091, 0x8000, 0x0c7e, 0x1078,
+	0x76c7, 0x017f, 0x0040, 0x8eab, 0x660a, 0x611a, 0x601f, 0x0001,
 	0x2d00, 0x6012, 0x2009, 0x003d, 0x1078, 0x775c, 0xa085, 0x0001,
-	0x127f, 0x0c7f, 0x007c, 0xa006, 0x0078, 0x8e98, 0x0c7e, 0x127e,
-	0x2091, 0x8000, 0x0c7e, 0x1078, 0x76c7, 0x017f, 0x0040, 0x8eb6,
+	0x127f, 0x0c7f, 0x007c, 0xa006, 0x0078, 0x8ea8, 0x0c7e, 0x127e,
+	0x2091, 0x8000, 0x0c7e, 0x1078, 0x76c7, 0x017f, 0x0040, 0x8ec6,
 	0x611a, 0x601f, 0x0001, 0x2d00, 0x6012, 0x2009, 0x0000, 0x1078,
 	0x775c, 0xa085, 0x0001, 0x127f, 0x0c7f, 0x007c, 0xa006, 0x0078,
-	0x8eb3, 0x027e, 0x0d7e, 0x6218, 0x2268, 0x6a3c, 0x82ff, 0x0040,
-	0x8ec3, 0x8211, 0x6a3e, 0x0d7f, 0x027f, 0x007c, 0x007e, 0x6000,
-	0xa086, 0x0000, 0x0040, 0x8ed8, 0x6013, 0x0000, 0x601f, 0x0007,
-	0x2001, 0xa8a3, 0x2004, 0x6016, 0x1078, 0xa495, 0x603f, 0x0000,
-	0x007f, 0x007c, 0x067e, 0x0c7e, 0x0d7e, 0x2031, 0xa653, 0x2634,
-	0xd6e4, 0x0040, 0x8ee8, 0x6618, 0x2660, 0x6e48, 0x1078, 0x46e7,
+	0x8ec3, 0x027e, 0x0d7e, 0x6218, 0x2268, 0x6a3c, 0x82ff, 0x0040,
+	0x8ed3, 0x8211, 0x6a3e, 0x0d7f, 0x027f, 0x007c, 0x007e, 0x6000,
+	0xa086, 0x0000, 0x0040, 0x8ee8, 0x6013, 0x0000, 0x601f, 0x0007,
+	0x2001, 0xa9a3, 0x2004, 0x6016, 0x1078, 0xa4a5, 0x603f, 0x0000,
+	0x007f, 0x007c, 0x067e, 0x0c7e, 0x0d7e, 0x2031, 0xa753, 0x2634,
+	0xd6e4, 0x0040, 0x8ef8, 0x6618, 0x2660, 0x6e48, 0x1078, 0x46e7,
 	0x0d7f, 0x0c7f, 0x067f, 0x007c, 0x007e, 0x017e, 0x6004, 0xa08e,
-	0x0002, 0x0040, 0x8efd, 0xa08e, 0x0003, 0x0040, 0x8efd, 0xa08e,
-	0x0004, 0x0040, 0x8efd, 0xa085, 0x0001, 0x017f, 0x007f, 0x007c,
-	0x007e, 0x0d7e, 0x6010, 0xa06d, 0x0040, 0x8f0d, 0x6838, 0xd0fc,
-	0x0040, 0x8f0d, 0xa006, 0x0078, 0x8f0f, 0xa085, 0x0001, 0x0d7f,
+	0x0002, 0x0040, 0x8f0d, 0xa08e, 0x0003, 0x0040, 0x8f0d, 0xa08e,
+	0x0004, 0x0040, 0x8f0d, 0xa085, 0x0001, 0x017f, 0x007f, 0x007c,
+	0x007e, 0x0d7e, 0x6010, 0xa06d, 0x0040, 0x8f1d, 0x6838, 0xd0fc,
+	0x0040, 0x8f1d, 0xa006, 0x0078, 0x8f1f, 0xa085, 0x0001, 0x0d7f,
 	0x007f, 0x007c, 0x0c7e, 0x127e, 0x2091, 0x8000, 0x0c7e, 0x1078,
-	0x76c7, 0x017f, 0x0040, 0x8f2c, 0x611a, 0x601f, 0x0001, 0x2d00,
+	0x76c7, 0x017f, 0x0040, 0x8f3c, 0x611a, 0x601f, 0x0001, 0x2d00,
 	0x6012, 0x1078, 0x2880, 0x2009, 0x0028, 0x1078, 0x775c, 0xa085,
-	0x0001, 0x127f, 0x0c7f, 0x007c, 0xa006, 0x0078, 0x8f29, 0xa186,
-	0x0015, 0x00c0, 0x8f44, 0x2011, 0xa620, 0x2204, 0xa086, 0x0074,
-	0x00c0, 0x8f44, 0x1078, 0x7f91, 0x6003, 0x0001, 0x6007, 0x0029,
-	0x1078, 0x5dd7, 0x0078, 0x8f48, 0x1078, 0x7c83, 0x1078, 0x772d,
-	0x007c, 0xa186, 0x0016, 0x00c0, 0x8f53, 0x2001, 0x0004, 0x1078,
-	0x4502, 0x0078, 0x8f74, 0xa186, 0x0015, 0x00c0, 0x8f78, 0x2011,
-	0xa620, 0x2204, 0xa086, 0x0014, 0x00c0, 0x8f78, 0x0d7e, 0x6018,
-	0x2068, 0x1078, 0x4649, 0x0d7f, 0x1078, 0x8043, 0x00c0, 0x8f78,
-	0x0d7e, 0x6018, 0x2068, 0x6890, 0x0d7f, 0xa005, 0x0040, 0x8f78,
-	0x2001, 0x0006, 0x1078, 0x4502, 0x1078, 0x77f8, 0x0078, 0x8f7c,
+	0x0001, 0x127f, 0x0c7f, 0x007c, 0xa006, 0x0078, 0x8f39, 0xa186,
+	0x0015, 0x00c0, 0x8f54, 0x2011, 0xa720, 0x2204, 0xa086, 0x0074,
+	0x00c0, 0x8f54, 0x1078, 0x7f91, 0x6003, 0x0001, 0x6007, 0x0029,
+	0x1078, 0x5dd7, 0x0078, 0x8f58, 0x1078, 0x7c83, 0x1078, 0x772d,
+	0x007c, 0xa186, 0x0016, 0x00c0, 0x8f63, 0x2001, 0x0004, 0x1078,
+	0x4502, 0x0078, 0x8f84, 0xa186, 0x0015, 0x00c0, 0x8f88, 0x2011,
+	0xa720, 0x2204, 0xa086, 0x0014, 0x00c0, 0x8f88, 0x0d7e, 0x6018,
+	0x2068, 0x1078, 0x4649, 0x0d7f, 0x1078, 0x8043, 0x00c0, 0x8f88,
+	0x0d7e, 0x6018, 0x2068, 0x6890, 0x0d7f, 0xa005, 0x0040, 0x8f88,
+	0x2001, 0x0006, 0x1078, 0x4502, 0x1078, 0x77f8, 0x0078, 0x8f8c,
 	0x1078, 0x7c83, 0x1078, 0x772d, 0x007c, 0x6848, 0xa086, 0x0005,
-	0x00c0, 0x8f84, 0x1078, 0x8f85, 0x007c, 0x6850, 0xc0ad, 0x6852,
-	0x007c, 0x0e7e, 0x2071, 0xab8c, 0x7014, 0xd0e4, 0x0040, 0x8f9a,
+	0x00c0, 0x8f94, 0x1078, 0x8f95, 0x007c, 0x6850, 0xc0ad, 0x6852,
+	0x007c, 0x0e7e, 0x2071, 0xac8c, 0x7014, 0xd0e4, 0x0040, 0x8faa,
 	0x6013, 0x0000, 0x6003, 0x0001, 0x6007, 0x0050, 0x1078, 0x5d8a,
 	0x1078, 0x62d1, 0x0e7f, 0x007c, 0x0c7e, 0x0f7e, 0x2c78, 0x1078,
-	0x4963, 0x0f7f, 0x0040, 0x8fa9, 0x601c, 0xa084, 0x000f, 0x1079,
-	0x8fab, 0x0c7f, 0x007c, 0x8ad5, 0x8fb6, 0x8fb9, 0x8fbc, 0xa25d,
-	0xa279, 0xa27c, 0x8ad5, 0x8ad5, 0x1078, 0x1332, 0x0005, 0x0005,
-	0x007c, 0x0005, 0x0005, 0x007c, 0x1078, 0x8fbf, 0x007c, 0x0f7e,
-	0x2c78, 0x1078, 0x4963, 0x0040, 0x8fee, 0x1078, 0x76c7, 0x00c0,
-	0x8fcf, 0x2001, 0xa8a4, 0x2004, 0x783e, 0x0078, 0x8fee, 0x7818,
-	0x601a, 0x781c, 0xa086, 0x0003, 0x0040, 0x8fdc, 0x7808, 0x6036,
-	0x2f00, 0x603a, 0x0078, 0x8fe0, 0x7808, 0x603a, 0x2f00, 0x6036,
+	0x4963, 0x0f7f, 0x0040, 0x8fb9, 0x601c, 0xa084, 0x000f, 0x1079,
+	0x8fbb, 0x0c7f, 0x007c, 0x8ae5, 0x8fc6, 0x8fc9, 0x8fcc, 0xa26d,
+	0xa289, 0xa28c, 0x8ae5, 0x8ae5, 0x1078, 0x1332, 0x0005, 0x0005,
+	0x007c, 0x0005, 0x0005, 0x007c, 0x1078, 0x8fcf, 0x007c, 0x0f7e,
+	0x2c78, 0x1078, 0x4963, 0x0040, 0x8ffe, 0x1078, 0x76c7, 0x00c0,
+	0x8fdf, 0x2001, 0xa9a4, 0x2004, 0x783e, 0x0078, 0x8ffe, 0x7818,
+	0x601a, 0x781c, 0xa086, 0x0003, 0x0040, 0x8fec, 0x7808, 0x6036,
+	0x2f00, 0x603a, 0x0078, 0x8ff0, 0x7808, 0x603a, 0x2f00, 0x6036,
 	0x602a, 0x601f, 0x0001, 0x6007, 0x0035, 0x6003, 0x0001, 0x7920,
 	0x6122, 0x1078, 0x5d8a, 0x1078, 0x62d1, 0x2f60, 0x0f7f, 0x007c,
-	0x017e, 0x0f7e, 0x682c, 0x6032, 0xa08e, 0x0001, 0x0040, 0x9001,
-	0xa086, 0x0005, 0x0040, 0x9005, 0xa006, 0x602a, 0x602e, 0x0078,
-	0x9016, 0x6824, 0xc0f4, 0xc0d5, 0x6826, 0x6810, 0x2078, 0x787c,
-	0x6938, 0xa102, 0x7880, 0x6934, 0xa103, 0x00c8, 0x8ffc, 0x6834,
+	0x017e, 0x0f7e, 0x682c, 0x6032, 0xa08e, 0x0001, 0x0040, 0x9011,
+	0xa086, 0x0005, 0x0040, 0x9015, 0xa006, 0x602a, 0x602e, 0x0078,
+	0x9026, 0x6824, 0xc0f4, 0xc0d5, 0x6826, 0x6810, 0x2078, 0x787c,
+	0x6938, 0xa102, 0x7880, 0x6934, 0xa103, 0x00c8, 0x900c, 0x6834,
 	0x602a, 0x6838, 0xa084, 0xfffc, 0x683a, 0x602e, 0x2d00, 0x6036,
 	0x6808, 0x603a, 0x6918, 0x611a, 0x6920, 0x6122, 0x601f, 0x0001,
 	0x6007, 0x0039, 0x6003, 0x0001, 0x1078, 0x5d8a, 0x6803, 0x0002,
 	0x0f7f, 0x017f, 0x007c, 0x007e, 0x017e, 0x6004, 0xa08e, 0x0034,
-	0x0040, 0x9050, 0xa08e, 0x0035, 0x0040, 0x9050, 0xa08e, 0x0036,
-	0x0040, 0x9050, 0xa08e, 0x0037, 0x0040, 0x9050, 0xa08e, 0x0038,
-	0x0040, 0x9050, 0xa08e, 0x0039, 0x0040, 0x9050, 0xa08e, 0x003a,
-	0x0040, 0x9050, 0xa08e, 0x003b, 0x0040, 0x9050, 0xa085, 0x0001,
+	0x0040, 0x9060, 0xa08e, 0x0035, 0x0040, 0x9060, 0xa08e, 0x0036,
+	0x0040, 0x9060, 0xa08e, 0x0037, 0x0040, 0x9060, 0xa08e, 0x0038,
+	0x0040, 0x9060, 0xa08e, 0x0039, 0x0040, 0x9060, 0xa08e, 0x003a,
+	0x0040, 0x9060, 0xa08e, 0x003b, 0x0040, 0x9060, 0xa085, 0x0001,
 	0x017f, 0x007f, 0x007c, 0x0f7e, 0x2c78, 0x1078, 0x4963, 0x00c0,
-	0x905d, 0xa085, 0x0001, 0x0078, 0x906c, 0x6024, 0xd0f4, 0x00c0,
-	0x906b, 0xc0f5, 0x6026, 0x6010, 0x2078, 0x7828, 0x603a, 0x782c,
+	0x906d, 0xa085, 0x0001, 0x0078, 0x907c, 0x6024, 0xd0f4, 0x00c0,
+	0x907b, 0xc0f5, 0x6026, 0x6010, 0x2078, 0x7828, 0x603a, 0x782c,
 	0x6036, 0x1078, 0x1757, 0xa006, 0x0f7f, 0x007c, 0x007e, 0x017e,
-	0x027e, 0x037e, 0x0e7e, 0x2001, 0xa89e, 0x200c, 0x8000, 0x2014,
-	0x2001, 0x0032, 0x1078, 0x5c1c, 0x2001, 0xa8a2, 0x82ff, 0x00c0,
-	0x9083, 0x2011, 0x0014, 0x2202, 0x2001, 0xa8a0, 0x200c, 0x8000,
-	0x2014, 0x2071, 0xa88d, 0x711a, 0x721e, 0x2001, 0x0064, 0x1078,
-	0x5c1c, 0x2001, 0xa8a3, 0x82ff, 0x00c0, 0x9098, 0x2011, 0x0014,
-	0x2202, 0x2009, 0xa8a4, 0xa280, 0x000a, 0x200a, 0x1078, 0x498b,
+	0x027e, 0x037e, 0x0e7e, 0x2001, 0xa99e, 0x200c, 0x8000, 0x2014,
+	0x2001, 0x0032, 0x1078, 0x5c1c, 0x2001, 0xa9a2, 0x82ff, 0x00c0,
+	0x9093, 0x2011, 0x0014, 0x2202, 0x2001, 0xa9a0, 0x200c, 0x8000,
+	0x2014, 0x2071, 0xa98d, 0x711a, 0x721e, 0x2001, 0x0064, 0x1078,
+	0x5c1c, 0x2001, 0xa9a3, 0x82ff, 0x00c0, 0x90a8, 0x2011, 0x0014,
+	0x2202, 0x2009, 0xa9a4, 0xa280, 0x000a, 0x200a, 0x1078, 0x498b,
 	0x0e7f, 0x037f, 0x027f, 0x017f, 0x007f, 0x007c, 0x007e, 0x0e7e,
-	0x2001, 0xa8a2, 0x2003, 0x0028, 0x2001, 0xa8a3, 0x2003, 0x0014,
-	0x2071, 0xa88d, 0x701b, 0x0000, 0x701f, 0x07d0, 0x2001, 0xa8a4,
+	0x2001, 0xa9a2, 0x2003, 0x0028, 0x2001, 0xa9a3, 0x2003, 0x0014,
+	0x2071, 0xa98d, 0x701b, 0x0000, 0x701f, 0x07d0, 0x2001, 0xa9a4,
 	0x2003, 0x001e, 0x0e7f, 0x007f, 0x007c, 0x0c7e, 0x127e, 0x2091,
-	0x8000, 0x0c7e, 0x1078, 0x76c7, 0x017f, 0x0040, 0x90d5, 0x611a,
+	0x8000, 0x0c7e, 0x1078, 0x76c7, 0x017f, 0x0040, 0x90e5, 0x611a,
 	0x601f, 0x0001, 0x2d00, 0x6012, 0x2009, 0x0033, 0x1078, 0x775c,
-	0xa085, 0x0001, 0x127f, 0x0c7f, 0x007c, 0xa006, 0x0078, 0x90d2,
-	0x0d7e, 0x0e7e, 0x0f7e, 0x2071, 0xa600, 0xa186, 0x0015, 0x00c0,
-	0x9107, 0x7080, 0xa086, 0x0018, 0x00c0, 0x9107, 0x6010, 0x2068,
-	0x6a3c, 0xd2e4, 0x00c0, 0x90fb, 0x2c78, 0x1078, 0x6490, 0x0040,
-	0x910f, 0x706c, 0x6a50, 0xa206, 0x00c0, 0x9103, 0x7070, 0x6a54,
-	0xa206, 0x00c0, 0x9103, 0x6218, 0xa290, 0x0028, 0x2214, 0x2009,
-	0x0000, 0x1078, 0x28c8, 0x1078, 0x77f8, 0x0078, 0x910b, 0x1078,
+	0xa085, 0x0001, 0x127f, 0x0c7f, 0x007c, 0xa006, 0x0078, 0x90e2,
+	0x0d7e, 0x0e7e, 0x0f7e, 0x2071, 0xa700, 0xa186, 0x0015, 0x00c0,
+	0x9117, 0x7080, 0xa086, 0x0018, 0x00c0, 0x9117, 0x6010, 0x2068,
+	0x6a3c, 0xd2e4, 0x00c0, 0x910b, 0x2c78, 0x1078, 0x6490, 0x0040,
+	0x911f, 0x706c, 0x6a50, 0xa206, 0x00c0, 0x9113, 0x7070, 0x6a54,
+	0xa206, 0x00c0, 0x9113, 0x6218, 0xa290, 0x0028, 0x2214, 0x2009,
+	0x0000, 0x1078, 0x28c8, 0x1078, 0x77f8, 0x0078, 0x911b, 0x1078,
 	0x7c83, 0x1078, 0x772d, 0x0f7f, 0x0e7f, 0x0d7f, 0x007c, 0x7050,
-	0xa080, 0x29c0, 0x2004, 0x6a54, 0xa206, 0x0040, 0x90fb, 0x0078,
-	0x9103, 0x0c7e, 0x127e, 0x2091, 0x8000, 0x0c7e, 0x1078, 0x76c7,
-	0x017f, 0x0040, 0x9131, 0x611a, 0x601f, 0x0001, 0x2d00, 0x6012,
+	0xa080, 0x29c0, 0x2004, 0x6a54, 0xa206, 0x0040, 0x910b, 0x0078,
+	0x9113, 0x0c7e, 0x127e, 0x2091, 0x8000, 0x0c7e, 0x1078, 0x76c7,
+	0x017f, 0x0040, 0x9141, 0x611a, 0x601f, 0x0001, 0x2d00, 0x6012,
 	0x2009, 0x0043, 0x1078, 0x775c, 0xa085, 0x0001, 0x127f, 0x0c7f,
-	0x007c, 0xa006, 0x0078, 0x912e, 0x0d7e, 0x0e7e, 0x0f7e, 0x2071,
-	0xa600, 0xa186, 0x0015, 0x00c0, 0x915a, 0x7080, 0xa086, 0x0004,
-	0x00c0, 0x915a, 0x6010, 0xa0e8, 0x000f, 0x2c78, 0x1078, 0x6490,
-	0x0040, 0x9162, 0x706c, 0x6a08, 0xa206, 0x00c0, 0x9156, 0x7070,
-	0x6a0c, 0xa206, 0x00c0, 0x9156, 0x1078, 0x2880, 0x1078, 0x77f8,
-	0x0078, 0x915e, 0x1078, 0x7c83, 0x1078, 0x772d, 0x0f7f, 0x0e7f,
+	0x007c, 0xa006, 0x0078, 0x913e, 0x0d7e, 0x0e7e, 0x0f7e, 0x2071,
+	0xa700, 0xa186, 0x0015, 0x00c0, 0x916a, 0x7080, 0xa086, 0x0004,
+	0x00c0, 0x916a, 0x6010, 0xa0e8, 0x000f, 0x2c78, 0x1078, 0x6490,
+	0x0040, 0x9172, 0x706c, 0x6a08, 0xa206, 0x00c0, 0x9166, 0x7070,
+	0x6a0c, 0xa206, 0x00c0, 0x9166, 0x1078, 0x2880, 0x1078, 0x77f8,
+	0x0078, 0x916e, 0x1078, 0x7c83, 0x1078, 0x772d, 0x0f7f, 0x0e7f,
 	0x0d7f, 0x007c, 0x7050, 0xa080, 0x29c0, 0x2004, 0x6a0c, 0xa206,
-	0x0040, 0x9154, 0x0078, 0x9156, 0x017e, 0x027e, 0x684c, 0xd0ac,
-	0x0040, 0x9184, 0x6914, 0x6a10, 0x2100, 0xa205, 0x0040, 0x9184,
-	0x6860, 0xa106, 0x00c0, 0x9180, 0x685c, 0xa206, 0x0040, 0x9184,
+	0x0040, 0x9164, 0x0078, 0x9166, 0x017e, 0x027e, 0x684c, 0xd0ac,
+	0x0040, 0x9194, 0x6914, 0x6a10, 0x2100, 0xa205, 0x0040, 0x9194,
+	0x6860, 0xa106, 0x00c0, 0x9190, 0x685c, 0xa206, 0x0040, 0x9194,
 	0x6962, 0x6a5e, 0xa085, 0x0001, 0x027f, 0x017f, 0x007c, 0x0e7e,
-	0x127e, 0x2071, 0xa600, 0x2091, 0x8000, 0x7548, 0xa582, 0x0001,
-	0x0048, 0x91b9, 0x704c, 0x2060, 0x6000, 0xa086, 0x0000, 0x0040,
-	0x91a5, 0xace0, 0x0010, 0x7058, 0xac02, 0x00c8, 0x91a1, 0x0078,
-	0x9194, 0x2061, 0xad00, 0x0078, 0x9194, 0x6003, 0x0008, 0x8529,
-	0x754a, 0xaca8, 0x0010, 0x7058, 0xa502, 0x00c8, 0x91b5, 0x754e,
-	0xa085, 0x0001, 0x127f, 0x0e7f, 0x007c, 0x704f, 0xad00, 0x0078,
-	0x91b0, 0xa006, 0x0078, 0x91b2, 0x0c7e, 0x027e, 0x017e, 0xa186,
-	0x0035, 0x0040, 0x91c6, 0x6a34, 0x0078, 0x91c7, 0x6a28, 0x1078,
-	0x8cf2, 0x0040, 0x91f0, 0x2260, 0x611c, 0xa186, 0x0003, 0x0040,
-	0x91d5, 0xa186, 0x0006, 0x00c0, 0x91ec, 0x6834, 0xa206, 0x0040,
-	0x91e4, 0x6838, 0xa206, 0x00c0, 0x91ec, 0x6108, 0x6834, 0xa106,
-	0x00c0, 0x91ec, 0x0078, 0x91e9, 0x6008, 0x6938, 0xa106, 0x00c0,
-	0x91ec, 0x6018, 0x6918, 0xa106, 0x017f, 0x027f, 0x0c7f, 0x007c,
-	0xa085, 0x0001, 0x0078, 0x91ec, 0x6944, 0xd1cc, 0x0040, 0x920d,
-	0xa18c, 0x00ff, 0xa18e, 0x0002, 0x00c0, 0x920d, 0xad88, 0x001e,
-	0x210c, 0xa18c, 0x0f00, 0x810f, 0xa18e, 0x0001, 0x00c0, 0x920d,
-	0x6810, 0x6914, 0xa115, 0x10c0, 0x84d5, 0x007c, 0x067e, 0x6000,
-	0xa0b2, 0x0010, 0x10c8, 0x1332, 0x1079, 0x9218, 0x067f, 0x007c,
-	0x9228, 0x96df, 0x97fb, 0x9228, 0x9228, 0x9228, 0x9228, 0x9228,
-	0x9262, 0x988e, 0x9228, 0x9228, 0x9228, 0x9228, 0x9228, 0x9228,
+	0x127e, 0x2071, 0xa700, 0x2091, 0x8000, 0x7548, 0xa582, 0x0001,
+	0x0048, 0x91c9, 0x704c, 0x2060, 0x6000, 0xa086, 0x0000, 0x0040,
+	0x91b5, 0xace0, 0x0010, 0x7058, 0xac02, 0x00c8, 0x91b1, 0x0078,
+	0x91a4, 0x2061, 0xae00, 0x0078, 0x91a4, 0x6003, 0x0008, 0x8529,
+	0x754a, 0xaca8, 0x0010, 0x7058, 0xa502, 0x00c8, 0x91c5, 0x754e,
+	0xa085, 0x0001, 0x127f, 0x0e7f, 0x007c, 0x704f, 0xae00, 0x0078,
+	0x91c0, 0xa006, 0x0078, 0x91c2, 0x0c7e, 0x027e, 0x017e, 0xa186,
+	0x0035, 0x0040, 0x91d6, 0x6a34, 0x0078, 0x91d7, 0x6a28, 0x1078,
+	0x8d02, 0x0040, 0x9200, 0x2260, 0x611c, 0xa186, 0x0003, 0x0040,
+	0x91e5, 0xa186, 0x0006, 0x00c0, 0x91fc, 0x6834, 0xa206, 0x0040,
+	0x91f4, 0x6838, 0xa206, 0x00c0, 0x91fc, 0x6108, 0x6834, 0xa106,
+	0x00c0, 0x91fc, 0x0078, 0x91f9, 0x6008, 0x6938, 0xa106, 0x00c0,
+	0x91fc, 0x6018, 0x6918, 0xa106, 0x017f, 0x027f, 0x0c7f, 0x007c,
+	0xa085, 0x0001, 0x0078, 0x91fc, 0x6944, 0xd1cc, 0x0040, 0x921d,
+	0xa18c, 0x00ff, 0xa18e, 0x0002, 0x00c0, 0x921d, 0xad88, 0x001e,
+	0x210c, 0xa18c, 0x0f00, 0x810f, 0xa18e, 0x0001, 0x00c0, 0x921d,
+	0x6810, 0x6914, 0xa115, 0x10c0, 0x84e2, 0x007c, 0x067e, 0x6000,
+	0xa0b2, 0x0010, 0x10c8, 0x1332, 0x1079, 0x9228, 0x067f, 0x007c,
+	0x9238, 0x96ef, 0x980b, 0x9238, 0x9238, 0x9238, 0x9238, 0x9238,
+	0x9272, 0x989e, 0x9238, 0x9238, 0x9238, 0x9238, 0x9238, 0x9238,
 	0x1078, 0x1332, 0x067e, 0x6000, 0xa0b2, 0x0010, 0x10c8, 0x1332,
-	0x1079, 0x9234, 0x067f, 0x007c, 0x9244, 0x9d53, 0x9244, 0x9244,
-	0x9244, 0x9244, 0x9244, 0x9244, 0x9d11, 0x9da1, 0x9244, 0xa3b0,
-	0xa3e4, 0xa3b0, 0xa3e4, 0x9244, 0x1078, 0x1332, 0x067e, 0x6000,
-	0xa0b2, 0x0010, 0x10c8, 0x1332, 0x1079, 0x9250, 0x067f, 0x007c,
-	0x9260, 0x99eb, 0x9ac7, 0x9af5, 0x9b70, 0x9260, 0x9c76, 0x9c1e,
-	0x989a, 0x9ce5, 0x9cfb, 0x9260, 0x9260, 0x9260, 0x9260, 0x9260,
+	0x1079, 0x9244, 0x067f, 0x007c, 0x9254, 0x9d63, 0x9254, 0x9254,
+	0x9254, 0x9254, 0x9254, 0x9254, 0x9d21, 0x9db1, 0x9254, 0xa3c0,
+	0xa3f4, 0xa3c0, 0xa3f4, 0x9254, 0x1078, 0x1332, 0x067e, 0x6000,
+	0xa0b2, 0x0010, 0x10c8, 0x1332, 0x1079, 0x9260, 0x067f, 0x007c,
+	0x9270, 0x99fb, 0x9ad7, 0x9b05, 0x9b80, 0x9270, 0x9c86, 0x9c2e,
+	0x98aa, 0x9cf5, 0x9d0b, 0x9270, 0x9270, 0x9270, 0x9270, 0x9270,
 	0x1078, 0x1332, 0xa1b2, 0x0044, 0x10c8, 0x1332, 0x2100, 0x0079,
-	0x9269, 0x92a9, 0x9498, 0x92a9, 0x92a9, 0x92a9, 0x94a0, 0x92a9,
-	0x92a9, 0x92a9, 0x92a9, 0x92a9, 0x92a9, 0x92a9, 0x92a9, 0x92a9,
-	0x92a9, 0x92a9, 0x92a9, 0x92a9, 0x92a9, 0x92a9, 0x92a9, 0x92a9,
-	0x92ab, 0x9311, 0x9320, 0x9377, 0x9396, 0x9415, 0x9485, 0x92a9,
-	0x92a9, 0x94a4, 0x92a9, 0x92a9, 0x94b7, 0x94c2, 0x92a9, 0x92a9,
-	0x92a9, 0x92a9, 0x92a9, 0x94fa, 0x92a9, 0x92a9, 0x9509, 0x92a9,
-	0x92a9, 0x92a9, 0x92a9, 0x92a9, 0x92a9, 0x9522, 0x92a9, 0x92a9,
-	0x92a9, 0x95af, 0x92a9, 0x92a9, 0x92a9, 0x92a9, 0x92a9, 0x92a9,
-	0x9629, 0x1078, 0x1332, 0x1078, 0x4967, 0x00c0, 0x92bb, 0x2001,
-	0xa633, 0x2004, 0xd0cc, 0x00c0, 0x92bb, 0xa084, 0x0009, 0xa086,
-	0x0008, 0x00c0, 0x92c3, 0x6007, 0x0009, 0x602b, 0x0009, 0x6013,
-	0x0000, 0x0078, 0x9493, 0x1078, 0x4957, 0x0e7e, 0x0c7e, 0x037e,
+	0x9279, 0x92b9, 0x94a8, 0x92b9, 0x92b9, 0x92b9, 0x94b0, 0x92b9,
+	0x92b9, 0x92b9, 0x92b9, 0x92b9, 0x92b9, 0x92b9, 0x92b9, 0x92b9,
+	0x92b9, 0x92b9, 0x92b9, 0x92b9, 0x92b9, 0x92b9, 0x92b9, 0x92b9,
+	0x92bb, 0x9321, 0x9330, 0x9387, 0x93a6, 0x9425, 0x9495, 0x92b9,
+	0x92b9, 0x94b4, 0x92b9, 0x92b9, 0x94c7, 0x94d2, 0x92b9, 0x92b9,
+	0x92b9, 0x92b9, 0x92b9, 0x950a, 0x92b9, 0x92b9, 0x9519, 0x92b9,
+	0x92b9, 0x92b9, 0x92b9, 0x92b9, 0x92b9, 0x9532, 0x92b9, 0x92b9,
+	0x92b9, 0x95bf, 0x92b9, 0x92b9, 0x92b9, 0x92b9, 0x92b9, 0x92b9,
+	0x9639, 0x1078, 0x1332, 0x1078, 0x4967, 0x00c0, 0x92cb, 0x2001,
+	0xa733, 0x2004, 0xd0cc, 0x00c0, 0x92cb, 0xa084, 0x0009, 0xa086,
+	0x0008, 0x00c0, 0x92d3, 0x6007, 0x0009, 0x602b, 0x0009, 0x6013,
+	0x0000, 0x0078, 0x94a3, 0x1078, 0x4957, 0x0e7e, 0x0c7e, 0x037e,
 	0x027e, 0x017e, 0x6218, 0x2270, 0x72a0, 0x027e, 0x2019, 0x0029,
 	0x1078, 0x5f01, 0x077e, 0x2039, 0x0000, 0x1078, 0x5e0a, 0x2c08,
-	0x1078, 0x9f8b, 0x077f, 0x017f, 0x2e60, 0x1078, 0x47e9, 0x017f,
+	0x1078, 0x9f9b, 0x077f, 0x017f, 0x2e60, 0x1078, 0x47e9, 0x017f,
 	0x027f, 0x037f, 0x0c7f, 0x0e7f, 0x6618, 0x0c7e, 0x2660, 0x1078,
 	0x45d6, 0x0c7f, 0xa6b0, 0x0001, 0x2634, 0xa684, 0x00ff, 0xa082,
-	0x0006, 0x0048, 0x9303, 0x1078, 0x9ebf, 0x00c0, 0x9371, 0x1078,
-	0x9e50, 0x00c0, 0x92ff, 0x6007, 0x0008, 0x0078, 0x9493, 0x6007,
-	0x0009, 0x0078, 0x9493, 0x1078, 0xa09f, 0x0040, 0x930d, 0x1078,
-	0x9ebf, 0x0040, 0x92f7, 0x0078, 0x9371, 0x6013, 0x1900, 0x0078,
-	0x92ff, 0x1078, 0x29bb, 0x00c0, 0x9664, 0x6106, 0x1078, 0x9e05,
-	0x6007, 0x0006, 0x0078, 0x9493, 0x6007, 0x0007, 0x0078, 0x9493,
-	0x1078, 0xa41c, 0x00c0, 0x9664, 0x1078, 0x29bb, 0x00c0, 0x9664,
+	0x0006, 0x0048, 0x9313, 0x1078, 0x9ecf, 0x00c0, 0x9381, 0x1078,
+	0x9e60, 0x00c0, 0x930f, 0x6007, 0x0008, 0x0078, 0x94a3, 0x6007,
+	0x0009, 0x0078, 0x94a3, 0x1078, 0xa0af, 0x0040, 0x931d, 0x1078,
+	0x9ecf, 0x0040, 0x9307, 0x0078, 0x9381, 0x6013, 0x1900, 0x0078,
+	0x930f, 0x1078, 0x29bb, 0x00c0, 0x9674, 0x6106, 0x1078, 0x9e15,
+	0x6007, 0x0006, 0x0078, 0x94a3, 0x6007, 0x0007, 0x0078, 0x94a3,
+	0x1078, 0xa42c, 0x00c0, 0x9674, 0x1078, 0x29bb, 0x00c0, 0x9674,
 	0x0d7e, 0x6618, 0x2668, 0x6e04, 0xa684, 0x00ff, 0xa082, 0x0006,
-	0x00c8, 0x9336, 0x2001, 0x0001, 0x1078, 0x44ee, 0xa6b4, 0xff00,
-	0x8637, 0xa686, 0x0006, 0x0040, 0x9353, 0xa686, 0x0004, 0x0040,
-	0x9353, 0x6e04, 0xa6b4, 0x00ff, 0xa686, 0x0006, 0x0040, 0x9353,
-	0xa686, 0x0004, 0x0040, 0x9353, 0xa686, 0x0005, 0x0040, 0x9353,
-	0x0d7f, 0x0078, 0x9371, 0x1078, 0x9f25, 0x00c0, 0x936c, 0xa686,
-	0x0006, 0x00c0, 0x9365, 0x027e, 0x6218, 0xa290, 0x0028, 0x2214,
+	0x00c8, 0x9346, 0x2001, 0x0001, 0x1078, 0x44ee, 0xa6b4, 0xff00,
+	0x8637, 0xa686, 0x0006, 0x0040, 0x9363, 0xa686, 0x0004, 0x0040,
+	0x9363, 0x6e04, 0xa6b4, 0x00ff, 0xa686, 0x0006, 0x0040, 0x9363,
+	0xa686, 0x0004, 0x0040, 0x9363, 0xa686, 0x0005, 0x0040, 0x9363,
+	0x0d7f, 0x0078, 0x9381, 0x1078, 0x9f35, 0x00c0, 0x937c, 0xa686,
+	0x0006, 0x00c0, 0x9375, 0x027e, 0x6218, 0xa290, 0x0028, 0x2214,
 	0x2009, 0x0000, 0x1078, 0x28c8, 0x027f, 0x1078, 0x4649, 0x6007,
-	0x000a, 0x0d7f, 0x0078, 0x9493, 0x6007, 0x000b, 0x0d7f, 0x0078,
-	0x9493, 0x1078, 0x2880, 0x6007, 0x0001, 0x0078, 0x9493, 0x1078,
-	0xa41c, 0x00c0, 0x9664, 0x1078, 0x29bb, 0x00c0, 0x9664, 0x6618,
-	0x0d7e, 0x2668, 0x6e04, 0x0d7f, 0xa686, 0x0707, 0x0040, 0x9371,
+	0x000a, 0x0d7f, 0x0078, 0x94a3, 0x6007, 0x000b, 0x0d7f, 0x0078,
+	0x94a3, 0x1078, 0x2880, 0x6007, 0x0001, 0x0078, 0x94a3, 0x1078,
+	0xa42c, 0x00c0, 0x9674, 0x1078, 0x29bb, 0x00c0, 0x9674, 0x6618,
+	0x0d7e, 0x2668, 0x6e04, 0x0d7f, 0xa686, 0x0707, 0x0040, 0x9381,
 	0x027e, 0x6218, 0xa290, 0x0028, 0x2214, 0x2009, 0x0000, 0x1078,
-	0x28c8, 0x027f, 0x6007, 0x000c, 0x0078, 0x9493, 0x1078, 0x4967,
-	0x00c0, 0x93a3, 0x2001, 0xa633, 0x2004, 0xa084, 0x0009, 0xa086,
-	0x0008, 0x00c0, 0x93ab, 0x6007, 0x0009, 0x602b, 0x0009, 0x6013,
-	0x0000, 0x0078, 0x9493, 0x1078, 0x4957, 0x6618, 0xa6b0, 0x0001,
-	0x2634, 0xa684, 0x00ff, 0xa082, 0x0006, 0x0048, 0x93ef, 0xa6b4,
-	0xff00, 0x8637, 0xa686, 0x0004, 0x0040, 0x93c2, 0xa686, 0x0006,
-	0x00c0, 0x9371, 0x1078, 0x9f34, 0x00c0, 0x93ca, 0x6007, 0x000e,
-	0x0078, 0x9493, 0x047e, 0x6418, 0xa4a0, 0x0028, 0x2424, 0xa4a4,
+	0x28c8, 0x027f, 0x6007, 0x000c, 0x0078, 0x94a3, 0x1078, 0x4967,
+	0x00c0, 0x93b3, 0x2001, 0xa733, 0x2004, 0xa084, 0x0009, 0xa086,
+	0x0008, 0x00c0, 0x93bb, 0x6007, 0x0009, 0x602b, 0x0009, 0x6013,
+	0x0000, 0x0078, 0x94a3, 0x1078, 0x4957, 0x6618, 0xa6b0, 0x0001,
+	0x2634, 0xa684, 0x00ff, 0xa082, 0x0006, 0x0048, 0x93ff, 0xa6b4,
+	0xff00, 0x8637, 0xa686, 0x0004, 0x0040, 0x93d2, 0xa686, 0x0006,
+	0x00c0, 0x9381, 0x1078, 0x9f44, 0x00c0, 0x93da, 0x6007, 0x000e,
+	0x0078, 0x94a3, 0x047e, 0x6418, 0xa4a0, 0x0028, 0x2424, 0xa4a4,
 	0x00ff, 0x8427, 0x047e, 0x1078, 0x2880, 0x047f, 0x017e, 0xa006,
-	0x2009, 0xa653, 0x210c, 0xd1a4, 0x0040, 0x93e9, 0x2009, 0x0029,
-	0x1078, 0xa21d, 0x6018, 0x0d7e, 0x2068, 0x6800, 0xc0e5, 0x6802,
-	0x0d7f, 0x017f, 0x047f, 0x6007, 0x0001, 0x0078, 0x9493, 0x2001,
+	0x2009, 0xa753, 0x210c, 0xd1a4, 0x0040, 0x93f9, 0x2009, 0x0029,
+	0x1078, 0xa22d, 0x6018, 0x0d7e, 0x2068, 0x6800, 0xc0e5, 0x6802,
+	0x0d7f, 0x017f, 0x047f, 0x6007, 0x0001, 0x0078, 0x94a3, 0x2001,
 	0x0001, 0x1078, 0x44ee, 0x157e, 0x017e, 0x027e, 0x037e, 0x20a9,
-	0x0004, 0x2019, 0xa605, 0x2011, 0xab90, 0x1078, 0x80de, 0x037f,
-	0x027f, 0x017f, 0x157f, 0xa005, 0x0040, 0x940f, 0xa6b4, 0xff00,
-	0x8637, 0xa686, 0x0006, 0x0040, 0x93c2, 0x0078, 0x9371, 0x6013,
-	0x1900, 0x6007, 0x0009, 0x0078, 0x9493, 0x1078, 0x4967, 0x00c0,
-	0x9422, 0x2001, 0xa633, 0x2004, 0xa084, 0x0009, 0xa086, 0x0008,
-	0x00c0, 0x942a, 0x6007, 0x0009, 0x602b, 0x0009, 0x6013, 0x0000,
-	0x0078, 0x9493, 0x1078, 0x4957, 0x6618, 0xa6b0, 0x0001, 0x2634,
-	0xa684, 0x00ff, 0xa082, 0x0006, 0x0048, 0x9472, 0xa6b4, 0xff00,
-	0x8637, 0xa686, 0x0004, 0x0040, 0x9441, 0xa686, 0x0006, 0x00c0,
-	0x9371, 0x1078, 0x9f5f, 0x00c0, 0x944d, 0x1078, 0x9e50, 0x00c0,
-	0x944d, 0x6007, 0x0010, 0x0078, 0x9493, 0x047e, 0x6418, 0xa4a0,
+	0x0004, 0x2019, 0xa705, 0x2011, 0xac90, 0x1078, 0x80de, 0x037f,
+	0x027f, 0x017f, 0x157f, 0xa005, 0x0040, 0x941f, 0xa6b4, 0xff00,
+	0x8637, 0xa686, 0x0006, 0x0040, 0x93d2, 0x0078, 0x9381, 0x6013,
+	0x1900, 0x6007, 0x0009, 0x0078, 0x94a3, 0x1078, 0x4967, 0x00c0,
+	0x9432, 0x2001, 0xa733, 0x2004, 0xa084, 0x0009, 0xa086, 0x0008,
+	0x00c0, 0x943a, 0x6007, 0x0009, 0x602b, 0x0009, 0x6013, 0x0000,
+	0x0078, 0x94a3, 0x1078, 0x4957, 0x6618, 0xa6b0, 0x0001, 0x2634,
+	0xa684, 0x00ff, 0xa082, 0x0006, 0x0048, 0x9482, 0xa6b4, 0xff00,
+	0x8637, 0xa686, 0x0004, 0x0040, 0x9451, 0xa686, 0x0006, 0x00c0,
+	0x9381, 0x1078, 0x9f6f, 0x00c0, 0x945d, 0x1078, 0x9e60, 0x00c0,
+	0x945d, 0x6007, 0x0010, 0x0078, 0x94a3, 0x047e, 0x6418, 0xa4a0,
 	0x0028, 0x2424, 0xa4a4, 0x00ff, 0x8427, 0x047e, 0x1078, 0x2880,
-	0x047f, 0x017e, 0xa006, 0x2009, 0xa653, 0x210c, 0xd1a4, 0x0040,
-	0x946c, 0x2009, 0x0029, 0x1078, 0xa21d, 0x6018, 0x0d7e, 0x2068,
+	0x047f, 0x017e, 0xa006, 0x2009, 0xa753, 0x210c, 0xd1a4, 0x0040,
+	0x947c, 0x2009, 0x0029, 0x1078, 0xa22d, 0x6018, 0x0d7e, 0x2068,
 	0x6800, 0xc0e5, 0x6802, 0x0d7f, 0x017f, 0x047f, 0x6007, 0x0001,
-	0x0078, 0x9493, 0x1078, 0xa09f, 0x0040, 0x947f, 0xa6b4, 0xff00,
-	0x8637, 0xa686, 0x0006, 0x0040, 0x9441, 0x0078, 0x9371, 0x6013,
-	0x1900, 0x6007, 0x0009, 0x0078, 0x9493, 0x1078, 0x29bb, 0x00c0,
-	0x9664, 0x1078, 0xa41c, 0x00c0, 0x9664, 0x1078, 0x9667, 0x00c0,
-	0x9371, 0x6007, 0x0012, 0x6003, 0x0001, 0x1078, 0x5dd7, 0x007c,
-	0x6007, 0x0001, 0x6003, 0x0001, 0x1078, 0x5dd7, 0x0078, 0x9497,
-	0x6007, 0x0005, 0x0078, 0x949a, 0x1078, 0xa41c, 0x00c0, 0x9664,
-	0x1078, 0x29bb, 0x00c0, 0x9664, 0x1078, 0x9667, 0x00c0, 0x9371,
+	0x0078, 0x94a3, 0x1078, 0xa0af, 0x0040, 0x948f, 0xa6b4, 0xff00,
+	0x8637, 0xa686, 0x0006, 0x0040, 0x9451, 0x0078, 0x9381, 0x6013,
+	0x1900, 0x6007, 0x0009, 0x0078, 0x94a3, 0x1078, 0x29bb, 0x00c0,
+	0x9674, 0x1078, 0xa42c, 0x00c0, 0x9674, 0x1078, 0x9677, 0x00c0,
+	0x9381, 0x6007, 0x0012, 0x6003, 0x0001, 0x1078, 0x5dd7, 0x007c,
+	0x6007, 0x0001, 0x6003, 0x0001, 0x1078, 0x5dd7, 0x0078, 0x94a7,
+	0x6007, 0x0005, 0x0078, 0x94aa, 0x1078, 0xa42c, 0x00c0, 0x9674,
+	0x1078, 0x29bb, 0x00c0, 0x9674, 0x1078, 0x9677, 0x00c0, 0x9381,
 	0x6007, 0x0020, 0x6003, 0x0001, 0x1078, 0x5dd7, 0x007c, 0x1078,
-	0x29bb, 0x00c0, 0x9664, 0x6007, 0x0023, 0x6003, 0x0001, 0x1078,
-	0x5dd7, 0x007c, 0x1078, 0xa41c, 0x00c0, 0x9664, 0x1078, 0x29bb,
-	0x00c0, 0x9664, 0x1078, 0x9667, 0x00c0, 0x9371, 0x017e, 0x027e,
-	0x2011, 0xab90, 0x2214, 0x2c08, 0xa006, 0x1078, 0xa1e6, 0x00c0,
-	0x94e9, 0x2160, 0x6007, 0x0026, 0x6013, 0x1700, 0x2011, 0xab89,
-	0x2214, 0xa296, 0xffff, 0x00c0, 0x94f3, 0x6007, 0x0025, 0x0078,
-	0x94f3, 0x6004, 0xa086, 0x0024, 0x00c0, 0x94f0, 0x1078, 0x772d,
+	0x29bb, 0x00c0, 0x9674, 0x6007, 0x0023, 0x6003, 0x0001, 0x1078,
+	0x5dd7, 0x007c, 0x1078, 0xa42c, 0x00c0, 0x9674, 0x1078, 0x29bb,
+	0x00c0, 0x9674, 0x1078, 0x9677, 0x00c0, 0x9381, 0x017e, 0x027e,
+	0x2011, 0xac90, 0x2214, 0x2c08, 0xa006, 0x1078, 0xa1f6, 0x00c0,
+	0x94f9, 0x2160, 0x6007, 0x0026, 0x6013, 0x1700, 0x2011, 0xac89,
+	0x2214, 0xa296, 0xffff, 0x00c0, 0x9503, 0x6007, 0x0025, 0x0078,
+	0x9503, 0x6004, 0xa086, 0x0024, 0x00c0, 0x9500, 0x1078, 0x772d,
 	0x2160, 0x6007, 0x0025, 0x6003, 0x0001, 0x1078, 0x5dd7, 0x027f,
-	0x017f, 0x007c, 0x1078, 0x29bb, 0x00c0, 0x9664, 0x6106, 0x1078,
-	0x9687, 0x6007, 0x002b, 0x0078, 0x9493, 0x6007, 0x002c, 0x0078,
-	0x9493, 0x1078, 0xa41c, 0x00c0, 0x9664, 0x1078, 0x29bb, 0x00c0,
-	0x9664, 0x1078, 0x9667, 0x00c0, 0x9371, 0x6106, 0x1078, 0x968c,
-	0x00c0, 0x951e, 0x6007, 0x002e, 0x0078, 0x9493, 0x6007, 0x002f,
-	0x0078, 0x9493, 0x1078, 0x29bb, 0x00c0, 0x9664, 0x0e7e, 0x0d7e,
+	0x017f, 0x007c, 0x1078, 0x29bb, 0x00c0, 0x9674, 0x6106, 0x1078,
+	0x9697, 0x6007, 0x002b, 0x0078, 0x94a3, 0x6007, 0x002c, 0x0078,
+	0x94a3, 0x1078, 0xa42c, 0x00c0, 0x9674, 0x1078, 0x29bb, 0x00c0,
+	0x9674, 0x1078, 0x9677, 0x00c0, 0x9381, 0x6106, 0x1078, 0x969c,
+	0x00c0, 0x952e, 0x6007, 0x002e, 0x0078, 0x94a3, 0x6007, 0x002f,
+	0x0078, 0x94a3, 0x1078, 0x29bb, 0x00c0, 0x9674, 0x0e7e, 0x0d7e,
 	0x0c7e, 0x6018, 0xa080, 0x0001, 0x200c, 0xa184, 0x00ff, 0xa086,
-	0x0006, 0x0040, 0x953f, 0xa184, 0xff00, 0x8007, 0xa086, 0x0006,
-	0x0040, 0x953f, 0x0c7f, 0x0d7f, 0x0e7f, 0x0078, 0x9498, 0x2001,
-	0xa672, 0x2004, 0xd0e4, 0x0040, 0x95ab, 0x2071, 0xab8c, 0x7010,
-	0x6036, 0x7014, 0x603a, 0x7108, 0x720c, 0x2001, 0xa653, 0x2004,
-	0xd0a4, 0x0040, 0x955d, 0x6018, 0x2068, 0x6810, 0xa106, 0x00c0,
-	0x955d, 0x6814, 0xa206, 0x0040, 0x9581, 0x2001, 0xa653, 0x2004,
-	0xd0ac, 0x00c0, 0x959f, 0x2069, 0xa600, 0x6870, 0xa206, 0x00c0,
-	0x959f, 0x686c, 0xa106, 0x00c0, 0x959f, 0x7210, 0x1078, 0x8cf2,
-	0x0040, 0x95a5, 0x1078, 0xa28e, 0x0040, 0x95a5, 0x622a, 0x6007,
+	0x0006, 0x0040, 0x954f, 0xa184, 0xff00, 0x8007, 0xa086, 0x0006,
+	0x0040, 0x954f, 0x0c7f, 0x0d7f, 0x0e7f, 0x0078, 0x94a8, 0x2001,
+	0xa772, 0x2004, 0xd0e4, 0x0040, 0x95bb, 0x2071, 0xac8c, 0x7010,
+	0x6036, 0x7014, 0x603a, 0x7108, 0x720c, 0x2001, 0xa753, 0x2004,
+	0xd0a4, 0x0040, 0x956d, 0x6018, 0x2068, 0x6810, 0xa106, 0x00c0,
+	0x956d, 0x6814, 0xa206, 0x0040, 0x9591, 0x2001, 0xa753, 0x2004,
+	0xd0ac, 0x00c0, 0x95af, 0x2069, 0xa700, 0x6870, 0xa206, 0x00c0,
+	0x95af, 0x686c, 0xa106, 0x00c0, 0x95af, 0x7210, 0x1078, 0x8d02,
+	0x0040, 0x95b5, 0x1078, 0xa29e, 0x0040, 0x95b5, 0x622a, 0x6007,
 	0x0036, 0x6003, 0x0001, 0x1078, 0x5d8a, 0x0c7f, 0x0d7f, 0x0e7f,
-	0x007c, 0x7214, 0xa286, 0xffff, 0x0040, 0x9593, 0x1078, 0x8cf2,
-	0x0040, 0x95a5, 0xa280, 0x0002, 0x2004, 0x7110, 0xa106, 0x00c0,
-	0x95a5, 0x0078, 0x956e, 0x7210, 0x2c08, 0xa085, 0x0001, 0x1078,
-	0xa1e6, 0x2c10, 0x2160, 0x0040, 0x95a5, 0x0078, 0x956e, 0x6007,
-	0x0037, 0x6013, 0x1500, 0x0078, 0x9579, 0x6007, 0x0037, 0x6013,
-	0x1700, 0x0078, 0x9579, 0x6007, 0x0012, 0x0078, 0x9579, 0x1078,
-	0x29bb, 0x00c0, 0x9664, 0x6018, 0xa080, 0x0001, 0x2004, 0xa084,
-	0xff00, 0x8007, 0xa086, 0x0006, 0x00c0, 0x9498, 0x0e7e, 0x0d7e,
-	0x0c7e, 0x2001, 0xa672, 0x2004, 0xd0e4, 0x0040, 0x9621, 0x2069,
-	0xa600, 0x2071, 0xab8c, 0x7008, 0x6036, 0x720c, 0x623a, 0xa286,
-	0xffff, 0x00c0, 0x95de, 0x7208, 0x0c7e, 0x2c08, 0xa085, 0x0001,
-	0x1078, 0xa1e6, 0x2c10, 0x0c7f, 0x0040, 0x9615, 0x1078, 0x8cf2,
-	0x0040, 0x9615, 0x0c7e, 0x027e, 0x2260, 0x1078, 0x89f3, 0x027f,
+	0x007c, 0x7214, 0xa286, 0xffff, 0x0040, 0x95a3, 0x1078, 0x8d02,
+	0x0040, 0x95b5, 0xa280, 0x0002, 0x2004, 0x7110, 0xa106, 0x00c0,
+	0x95b5, 0x0078, 0x957e, 0x7210, 0x2c08, 0xa085, 0x0001, 0x1078,
+	0xa1f6, 0x2c10, 0x2160, 0x0040, 0x95b5, 0x0078, 0x957e, 0x6007,
+	0x0037, 0x6013, 0x1500, 0x0078, 0x9589, 0x6007, 0x0037, 0x6013,
+	0x1700, 0x0078, 0x9589, 0x6007, 0x0012, 0x0078, 0x9589, 0x1078,
+	0x29bb, 0x00c0, 0x9674, 0x6018, 0xa080, 0x0001, 0x2004, 0xa084,
+	0xff00, 0x8007, 0xa086, 0x0006, 0x00c0, 0x94a8, 0x0e7e, 0x0d7e,
+	0x0c7e, 0x2001, 0xa772, 0x2004, 0xd0e4, 0x0040, 0x9631, 0x2069,
+	0xa700, 0x2071, 0xac8c, 0x7008, 0x6036, 0x720c, 0x623a, 0xa286,
+	0xffff, 0x00c0, 0x95ee, 0x7208, 0x0c7e, 0x2c08, 0xa085, 0x0001,
+	0x1078, 0xa1f6, 0x2c10, 0x0c7f, 0x0040, 0x9625, 0x1078, 0x8d02,
+	0x0040, 0x9625, 0x0c7e, 0x027e, 0x2260, 0x1078, 0x8a03, 0x027f,
 	0x0c7f, 0x7118, 0xa18c, 0xff00, 0x810f, 0xa186, 0x0001, 0x0040,
-	0x95ff, 0xa186, 0x0005, 0x0040, 0x95f9, 0xa186, 0x0007, 0x00c0,
-	0x9609, 0xa280, 0x0004, 0x2004, 0xa005, 0x0040, 0x9609, 0x057e,
-	0x7510, 0x7614, 0x1078, 0xa2a3, 0x057f, 0x0c7f, 0x0d7f, 0x0e7f,
+	0x960f, 0xa186, 0x0005, 0x0040, 0x9609, 0xa186, 0x0007, 0x00c0,
+	0x9619, 0xa280, 0x0004, 0x2004, 0xa005, 0x0040, 0x9619, 0x057e,
+	0x7510, 0x7614, 0x1078, 0xa2b3, 0x057f, 0x0c7f, 0x0d7f, 0x0e7f,
 	0x007c, 0x6007, 0x003b, 0x602b, 0x0009, 0x6013, 0x2a00, 0x6003,
-	0x0001, 0x1078, 0x5d8a, 0x0078, 0x9605, 0x6007, 0x003b, 0x602b,
+	0x0001, 0x1078, 0x5d8a, 0x0078, 0x9615, 0x6007, 0x003b, 0x602b,
 	0x0009, 0x6013, 0x1700, 0x6003, 0x0001, 0x1078, 0x5d8a, 0x0078,
-	0x9605, 0x6007, 0x003b, 0x602b, 0x000b, 0x6013, 0x0000, 0x0078,
-	0x9579, 0x0e7e, 0x027e, 0x1078, 0x4967, 0x0040, 0x965e, 0x1078,
-	0x4957, 0x1078, 0xa4a9, 0x00c0, 0x965c, 0x2071, 0xa600, 0x70cc,
+	0x9615, 0x6007, 0x003b, 0x602b, 0x000b, 0x6013, 0x0000, 0x0078,
+	0x9589, 0x0e7e, 0x027e, 0x1078, 0x4967, 0x0040, 0x966e, 0x1078,
+	0x4957, 0x1078, 0xa4b9, 0x00c0, 0x966c, 0x2071, 0xa700, 0x70cc,
 	0xc085, 0x70ce, 0x0f7e, 0x2079, 0x0100, 0x7298, 0xa284, 0x00ff,
 	0x706e, 0x78e6, 0xa284, 0xff00, 0x7270, 0xa205, 0x7072, 0x78ea,
-	0x0f7f, 0x70d7, 0x0000, 0x2001, 0xa653, 0x2004, 0xd0a4, 0x0040,
-	0x9655, 0x2011, 0xa8ca, 0x2013, 0x07d0, 0xd0ac, 0x00c0, 0x965e,
-	0x1078, 0x2677, 0x0078, 0x965e, 0x1078, 0xa4d9, 0x027f, 0x0e7f,
-	0x1078, 0x772d, 0x0078, 0x9497, 0x1078, 0x772d, 0x007c, 0x0d7e,
+	0x0f7f, 0x70d7, 0x0000, 0x2001, 0xa753, 0x2004, 0xd0a4, 0x0040,
+	0x9665, 0x2011, 0xa9ca, 0x2013, 0x07d0, 0xd0ac, 0x00c0, 0x966e,
+	0x1078, 0x2677, 0x0078, 0x966e, 0x1078, 0xa4e9, 0x027f, 0x0e7f,
+	0x1078, 0x772d, 0x0078, 0x94a7, 0x1078, 0x772d, 0x007c, 0x0d7e,
 	0x067e, 0x6618, 0x2668, 0x6e04, 0xa6b4, 0xff00, 0x8637, 0xa686,
-	0x0006, 0x0040, 0x9684, 0xa686, 0x0004, 0x0040, 0x9684, 0x6e04,
-	0xa6b4, 0x00ff, 0xa686, 0x0006, 0x0040, 0x9684, 0xa686, 0x0004,
-	0x0040, 0x9684, 0xa085, 0x0001, 0x067f, 0x0d7f, 0x007c, 0x0d7e,
-	0x1078, 0x96bb, 0x0d7f, 0x007c, 0x0d7e, 0x1078, 0x96ca, 0x00c0,
-	0x96b4, 0x680c, 0xa08c, 0xff00, 0x6820, 0xa084, 0x00ff, 0xa115,
-	0x6212, 0x6824, 0x602a, 0xd1e4, 0x0040, 0x96a2, 0x2009, 0x0001,
-	0x0078, 0x96b0, 0xd1ec, 0x0040, 0x96b4, 0x6920, 0xa18c, 0x00ff,
-	0x6824, 0x1078, 0x254d, 0x00c0, 0x96b4, 0x2110, 0x2009, 0x0000,
-	0x1078, 0x28c8, 0x0078, 0x96b8, 0xa085, 0x0001, 0x0078, 0x96b9,
-	0xa006, 0x0d7f, 0x007c, 0x2069, 0xab8d, 0x6800, 0xa082, 0x0010,
-	0x00c8, 0x96c8, 0x6013, 0x0000, 0xa085, 0x0001, 0x0078, 0x96c9,
-	0xa006, 0x007c, 0x6013, 0x0000, 0x2069, 0xab8c, 0x6808, 0xa084,
-	0xff00, 0xa086, 0x0800, 0x00c0, 0x96de, 0x6800, 0xa084, 0x00ff,
-	0xa08e, 0x0014, 0x0040, 0x96de, 0xa08e, 0x0010, 0x007c, 0x6004,
-	0xa0b2, 0x0044, 0x10c8, 0x1332, 0xa1b6, 0x0013, 0x00c0, 0x96eb,
-	0x2008, 0x0079, 0x96fe, 0xa1b6, 0x0027, 0x0040, 0x96f3, 0xa1b6,
+	0x0006, 0x0040, 0x9694, 0xa686, 0x0004, 0x0040, 0x9694, 0x6e04,
+	0xa6b4, 0x00ff, 0xa686, 0x0006, 0x0040, 0x9694, 0xa686, 0x0004,
+	0x0040, 0x9694, 0xa085, 0x0001, 0x067f, 0x0d7f, 0x007c, 0x0d7e,
+	0x1078, 0x96cb, 0x0d7f, 0x007c, 0x0d7e, 0x1078, 0x96da, 0x00c0,
+	0x96c4, 0x680c, 0xa08c, 0xff00, 0x6820, 0xa084, 0x00ff, 0xa115,
+	0x6212, 0x6824, 0x602a, 0xd1e4, 0x0040, 0x96b2, 0x2009, 0x0001,
+	0x0078, 0x96c0, 0xd1ec, 0x0040, 0x96c4, 0x6920, 0xa18c, 0x00ff,
+	0x6824, 0x1078, 0x254d, 0x00c0, 0x96c4, 0x2110, 0x2009, 0x0000,
+	0x1078, 0x28c8, 0x0078, 0x96c8, 0xa085, 0x0001, 0x0078, 0x96c9,
+	0xa006, 0x0d7f, 0x007c, 0x2069, 0xac8d, 0x6800, 0xa082, 0x0010,
+	0x00c8, 0x96d8, 0x6013, 0x0000, 0xa085, 0x0001, 0x0078, 0x96d9,
+	0xa006, 0x007c, 0x6013, 0x0000, 0x2069, 0xac8c, 0x6808, 0xa084,
+	0xff00, 0xa086, 0x0800, 0x00c0, 0x96ee, 0x6800, 0xa084, 0x00ff,
+	0xa08e, 0x0014, 0x0040, 0x96ee, 0xa08e, 0x0010, 0x007c, 0x6004,
+	0xa0b2, 0x0044, 0x10c8, 0x1332, 0xa1b6, 0x0013, 0x00c0, 0x96fb,
+	0x2008, 0x0079, 0x970e, 0xa1b6, 0x0027, 0x0040, 0x9703, 0xa1b6,
 	0x0014, 0x10c0, 0x1332, 0x2001, 0x0007, 0x1078, 0x4535, 0x1078,
-	0x61cd, 0x1078, 0x8ec6, 0x1078, 0x62d1, 0x007c, 0x973e, 0x9740,
-	0x973e, 0x973e, 0x973e, 0x9740, 0x974c, 0x97d6, 0x9799, 0x97d6,
-	0x97ad, 0x97d6, 0x974c, 0x97d6, 0x97ce, 0x97d6, 0x97ce, 0x97d6,
-	0x97d6, 0x973e, 0x973e, 0x973e, 0x973e, 0x973e, 0x973e, 0x973e,
-	0x973e, 0x973e, 0x973e, 0x973e, 0x9740, 0x973e, 0x97d6, 0x973e,
-	0x973e, 0x97d6, 0x973e, 0x97d6, 0x97d6, 0x973e, 0x973e, 0x973e,
-	0x973e, 0x97d6, 0x97d6, 0x973e, 0x97d6, 0x97d6, 0x973e, 0x973e,
-	0x973e, 0x973e, 0x973e, 0x9740, 0x97d6, 0x97d6, 0x973e, 0x973e,
-	0x97d6, 0x97d6, 0x973e, 0x973e, 0x973e, 0x973e, 0x1078, 0x1332,
-	0x1078, 0x61cd, 0x2001, 0xa8a2, 0x2004, 0x6016, 0x6003, 0x0002,
-	0x1078, 0x62d1, 0x0078, 0x97dc, 0x0f7e, 0x2079, 0xa652, 0x7804,
-	0x0f7f, 0xd0ac, 0x00c0, 0x97d6, 0x2001, 0x0000, 0x1078, 0x44ee,
-	0x6018, 0xa080, 0x0004, 0x2004, 0xa086, 0x00ff, 0x0040, 0x97d6,
-	0x0c7e, 0x6018, 0x2060, 0x6000, 0xd0f4, 0x00c0, 0x9770, 0x6010,
-	0xa005, 0x0040, 0x9770, 0x0c7f, 0x1078, 0x3699, 0x0078, 0x97d6,
-	0x0c7f, 0x2001, 0xa600, 0x2004, 0xa086, 0x0002, 0x00c0, 0x977f,
-	0x0f7e, 0x2079, 0xa600, 0x7890, 0x8000, 0x7892, 0x0f7f, 0x2001,
+	0x61cd, 0x1078, 0x8ed6, 0x1078, 0x62d1, 0x007c, 0x974e, 0x9750,
+	0x974e, 0x974e, 0x974e, 0x9750, 0x975c, 0x97e6, 0x97a9, 0x97e6,
+	0x97bd, 0x97e6, 0x975c, 0x97e6, 0x97de, 0x97e6, 0x97de, 0x97e6,
+	0x97e6, 0x974e, 0x974e, 0x974e, 0x974e, 0x974e, 0x974e, 0x974e,
+	0x974e, 0x974e, 0x974e, 0x974e, 0x9750, 0x974e, 0x97e6, 0x974e,
+	0x974e, 0x97e6, 0x974e, 0x97e6, 0x97e6, 0x974e, 0x974e, 0x974e,
+	0x974e, 0x97e6, 0x97e6, 0x974e, 0x97e6, 0x97e6, 0x974e, 0x974e,
+	0x974e, 0x974e, 0x974e, 0x9750, 0x97e6, 0x97e6, 0x974e, 0x974e,
+	0x97e6, 0x97e6, 0x974e, 0x974e, 0x974e, 0x974e, 0x1078, 0x1332,
+	0x1078, 0x61cd, 0x2001, 0xa9a2, 0x2004, 0x6016, 0x6003, 0x0002,
+	0x1078, 0x62d1, 0x0078, 0x97ec, 0x0f7e, 0x2079, 0xa752, 0x7804,
+	0x0f7f, 0xd0ac, 0x00c0, 0x97e6, 0x2001, 0x0000, 0x1078, 0x44ee,
+	0x6018, 0xa080, 0x0004, 0x2004, 0xa086, 0x00ff, 0x0040, 0x97e6,
+	0x0c7e, 0x6018, 0x2060, 0x6000, 0xd0f4, 0x00c0, 0x9780, 0x6010,
+	0xa005, 0x0040, 0x9780, 0x0c7f, 0x1078, 0x3699, 0x0078, 0x97e6,
+	0x0c7f, 0x2001, 0xa700, 0x2004, 0xa086, 0x0002, 0x00c0, 0x978f,
+	0x0f7e, 0x2079, 0xa700, 0x7890, 0x8000, 0x7892, 0x0f7f, 0x2001,
 	0x0002, 0x1078, 0x4502, 0x1078, 0x61cd, 0x601f, 0x0001, 0x6003,
 	0x0001, 0x6007, 0x0002, 0x1078, 0x5dd7, 0x1078, 0x62d1, 0x0c7e,
 	0x6118, 0x2160, 0x2009, 0x0001, 0x1078, 0x5a52, 0x0c7f, 0x0078,
-	0x97dc, 0x6618, 0x0d7e, 0x2668, 0x6e04, 0x0d7f, 0xa6b4, 0xff00,
-	0x8637, 0xa686, 0x0006, 0x0040, 0x97d6, 0xa686, 0x0004, 0x0040,
-	0x97d6, 0x2001, 0x0004, 0x0078, 0x97d4, 0x2001, 0xa600, 0x2004,
-	0xa086, 0x0003, 0x00c0, 0x97b6, 0x1078, 0x3699, 0x2001, 0x0006,
-	0x1078, 0x97dd, 0x6618, 0x0d7e, 0x2668, 0x6e04, 0x0d7f, 0xa6b4,
-	0xff00, 0x8637, 0xa686, 0x0006, 0x0040, 0x97d6, 0x2001, 0x0006,
-	0x0078, 0x97d4, 0x2001, 0x0004, 0x0078, 0x97d4, 0x2001, 0x0006,
-	0x1078, 0x97dd, 0x0078, 0x97d6, 0x1078, 0x4535, 0x1078, 0x61cd,
+	0x97ec, 0x6618, 0x0d7e, 0x2668, 0x6e04, 0x0d7f, 0xa6b4, 0xff00,
+	0x8637, 0xa686, 0x0006, 0x0040, 0x97e6, 0xa686, 0x0004, 0x0040,
+	0x97e6, 0x2001, 0x0004, 0x0078, 0x97e4, 0x2001, 0xa700, 0x2004,
+	0xa086, 0x0003, 0x00c0, 0x97c6, 0x1078, 0x3699, 0x2001, 0x0006,
+	0x1078, 0x97ed, 0x6618, 0x0d7e, 0x2668, 0x6e04, 0x0d7f, 0xa6b4,
+	0xff00, 0x8637, 0xa686, 0x0006, 0x0040, 0x97e6, 0x2001, 0x0006,
+	0x0078, 0x97e4, 0x2001, 0x0004, 0x0078, 0x97e4, 0x2001, 0x0006,
+	0x1078, 0x97ed, 0x0078, 0x97e6, 0x1078, 0x4535, 0x1078, 0x61cd,
 	0x1078, 0x772d, 0x1078, 0x62d1, 0x007c, 0x017e, 0x0d7e, 0x6118,
-	0x2168, 0x6900, 0xd184, 0x0040, 0x97f8, 0x6104, 0xa18e, 0x000a,
-	0x00c0, 0x97f0, 0x699c, 0xd1a4, 0x00c0, 0x97f0, 0x2001, 0x0007,
+	0x2168, 0x6900, 0xd184, 0x0040, 0x9808, 0x6104, 0xa18e, 0x000a,
+	0x00c0, 0x9800, 0x699c, 0xd1a4, 0x00c0, 0x9800, 0x2001, 0x0007,
 	0x1078, 0x4502, 0x2001, 0x0000, 0x1078, 0x44ee, 0x1078, 0x28a6,
 	0x0d7f, 0x017f, 0x007c, 0x0d7e, 0x6618, 0x2668, 0x6804, 0xa084,
 	0xff00, 0x8007, 0x0d7f, 0xa0b2, 0x000c, 0x10c8, 0x1332, 0xa1b6,
-	0x0015, 0x00c0, 0x980f, 0x1079, 0x9816, 0x0078, 0x9815, 0xa1b6,
-	0x0016, 0x10c0, 0x1332, 0x1079, 0x9822, 0x007c, 0x7d4e, 0x7d4e,
-	0x7d4e, 0x7d4e, 0x7d4e, 0x7d4e, 0x9877, 0x982e, 0x7d4e, 0x7d4e,
+	0x0015, 0x00c0, 0x981f, 0x1079, 0x9826, 0x0078, 0x9825, 0xa1b6,
+	0x0016, 0x10c0, 0x1332, 0x1079, 0x9832, 0x007c, 0x7d4e, 0x7d4e,
+	0x7d4e, 0x7d4e, 0x7d4e, 0x7d4e, 0x9887, 0x983e, 0x7d4e, 0x7d4e,
 	0x7d4e, 0x7d4e, 0x7d4e, 0x7d4e, 0x7d4e, 0x7d4e, 0x7d4e, 0x7d4e,
-	0x9877, 0x987f, 0x7d4e, 0x7d4e, 0x7d4e, 0x7d4e, 0x0f7e, 0x2079,
-	0xa652, 0x7804, 0xd0ac, 0x00c0, 0x9855, 0x6018, 0xa07d, 0x0040,
-	0x9855, 0x7800, 0xd0f4, 0x00c0, 0x9841, 0x7810, 0xa005, 0x00c0,
-	0x9855, 0x2001, 0x0000, 0x1078, 0x44ee, 0x2001, 0x0002, 0x1078,
+	0x9887, 0x988f, 0x7d4e, 0x7d4e, 0x7d4e, 0x7d4e, 0x0f7e, 0x2079,
+	0xa752, 0x7804, 0xd0ac, 0x00c0, 0x9865, 0x6018, 0xa07d, 0x0040,
+	0x9865, 0x7800, 0xd0f4, 0x00c0, 0x9851, 0x7810, 0xa005, 0x00c0,
+	0x9865, 0x2001, 0x0000, 0x1078, 0x44ee, 0x2001, 0x0002, 0x1078,
 	0x4502, 0x601f, 0x0001, 0x6003, 0x0001, 0x6007, 0x0002, 0x1078,
-	0x5dd7, 0x1078, 0x62d1, 0x0078, 0x9875, 0x2011, 0xab83, 0x2204,
-	0x8211, 0x220c, 0x1078, 0x254d, 0x00c0, 0x9875, 0x0c7e, 0x1078,
-	0x45c4, 0x0040, 0x9868, 0x0c7f, 0x1078, 0x772d, 0x0078, 0x9875,
+	0x5dd7, 0x1078, 0x62d1, 0x0078, 0x9885, 0x2011, 0xac83, 0x2204,
+	0x8211, 0x220c, 0x1078, 0x254d, 0x00c0, 0x9885, 0x0c7e, 0x1078,
+	0x45c4, 0x0040, 0x9878, 0x0c7f, 0x1078, 0x772d, 0x0078, 0x9885,
 	0x6010, 0x007e, 0x6014, 0x007e, 0x1078, 0x42f8, 0x007f, 0x6016,
 	0x007f, 0x6012, 0x0c7f, 0x1078, 0x772d, 0x0f7f, 0x007c, 0x6604,
-	0xa6b6, 0x001e, 0x00c0, 0x987e, 0x1078, 0x772d, 0x007c, 0x1078,
-	0x7f8e, 0x00c0, 0x988b, 0x6003, 0x0001, 0x6007, 0x0001, 0x1078,
-	0x5dd7, 0x0078, 0x988d, 0x1078, 0x772d, 0x007c, 0x6004, 0xa08a,
-	0x0044, 0x10c8, 0x1332, 0x1078, 0x61cd, 0x1078, 0x8ec6, 0x1078,
-	0x62d1, 0x007c, 0xa182, 0x0040, 0x0079, 0x989e, 0x98b1, 0x98b1,
-	0x98b1, 0x98b1, 0x98b3, 0x98b1, 0x98b1, 0x98b1, 0x98b1, 0x98b1,
-	0x98b1, 0x98b1, 0x98b1, 0x98b1, 0x98b1, 0x98b1, 0x98b1, 0x98b1,
-	0x98b1, 0x1078, 0x1332, 0x0d7e, 0x0e7e, 0x0f7e, 0x157e, 0x047e,
-	0x027e, 0x6218, 0xa280, 0x002b, 0x2004, 0xa005, 0x0040, 0x98c4,
-	0x2021, 0x0000, 0x1078, 0xa472, 0x6106, 0x2071, 0xab80, 0x7444,
-	0xa4a4, 0xff00, 0x0040, 0x991b, 0xa486, 0x2000, 0x00c0, 0x98d6,
+	0xa6b6, 0x001e, 0x00c0, 0x988e, 0x1078, 0x772d, 0x007c, 0x1078,
+	0x7f8e, 0x00c0, 0x989b, 0x6003, 0x0001, 0x6007, 0x0001, 0x1078,
+	0x5dd7, 0x0078, 0x989d, 0x1078, 0x772d, 0x007c, 0x6004, 0xa08a,
+	0x0044, 0x10c8, 0x1332, 0x1078, 0x61cd, 0x1078, 0x8ed6, 0x1078,
+	0x62d1, 0x007c, 0xa182, 0x0040, 0x0079, 0x98ae, 0x98c1, 0x98c1,
+	0x98c1, 0x98c1, 0x98c3, 0x98c1, 0x98c1, 0x98c1, 0x98c1, 0x98c1,
+	0x98c1, 0x98c1, 0x98c1, 0x98c1, 0x98c1, 0x98c1, 0x98c1, 0x98c1,
+	0x98c1, 0x1078, 0x1332, 0x0d7e, 0x0e7e, 0x0f7e, 0x157e, 0x047e,
+	0x027e, 0x6218, 0xa280, 0x002b, 0x2004, 0xa005, 0x0040, 0x98d4,
+	0x2021, 0x0000, 0x1078, 0xa482, 0x6106, 0x2071, 0xac80, 0x7444,
+	0xa4a4, 0xff00, 0x0040, 0x992b, 0xa486, 0x2000, 0x00c0, 0x98e6,
 	0x2009, 0x0001, 0x2011, 0x0200, 0x1078, 0x5bf1, 0x1078, 0x138b,
 	0x1040, 0x1332, 0x6003, 0x0007, 0x2d00, 0x6837, 0x010d, 0x6803,
 	0x0000, 0x683b, 0x0000, 0x6c5a, 0x2c00, 0x685e, 0x6008, 0x68b2,
 	0x6018, 0x2078, 0x78a0, 0x8007, 0x7130, 0x694a, 0x017e, 0xa084,
 	0xff00, 0x6846, 0x684f, 0x0000, 0x6857, 0x0036, 0x1078, 0x4a73,
-	0x017f, 0xa486, 0x2000, 0x00c0, 0x9903, 0x2019, 0x0017, 0x1078,
-	0xa195, 0x0078, 0x997d, 0xa486, 0x0400, 0x00c0, 0x990d, 0x2019,
-	0x0002, 0x1078, 0xa146, 0x0078, 0x997d, 0xa486, 0x0200, 0x00c0,
-	0x9913, 0x1078, 0xa12b, 0xa486, 0x1000, 0x00c0, 0x9919, 0x1078,
-	0xa17a, 0x0078, 0x997d, 0x2069, 0xa933, 0x6a00, 0xd284, 0x0040,
-	0x99e7, 0xa284, 0x0300, 0x00c0, 0x99df, 0x6804, 0xa005, 0x0040,
-	0x99c5, 0x2d78, 0x6003, 0x0007, 0x1078, 0x1370, 0x0040, 0x9984,
-	0x7800, 0xd08c, 0x00c0, 0x9937, 0x7804, 0x8001, 0x7806, 0x6013,
+	0x017f, 0xa486, 0x2000, 0x00c0, 0x9913, 0x2019, 0x0017, 0x1078,
+	0xa1a5, 0x0078, 0x998d, 0xa486, 0x0400, 0x00c0, 0x991d, 0x2019,
+	0x0002, 0x1078, 0xa156, 0x0078, 0x998d, 0xa486, 0x0200, 0x00c0,
+	0x9923, 0x1078, 0xa13b, 0xa486, 0x1000, 0x00c0, 0x9929, 0x1078,
+	0xa18a, 0x0078, 0x998d, 0x2069, 0xaa33, 0x6a00, 0xd284, 0x0040,
+	0x99f7, 0xa284, 0x0300, 0x00c0, 0x99ef, 0x6804, 0xa005, 0x0040,
+	0x99d5, 0x2d78, 0x6003, 0x0007, 0x1078, 0x1370, 0x0040, 0x9994,
+	0x7800, 0xd08c, 0x00c0, 0x9947, 0x7804, 0x8001, 0x7806, 0x6013,
 	0x0000, 0x6803, 0x0000, 0x6837, 0x0116, 0x683b, 0x0000, 0x6008,
 	0x68b2, 0x2c00, 0x684a, 0x6018, 0x2078, 0x78a0, 0x8007, 0x7130,
 	0x6986, 0x6846, 0x7928, 0x698a, 0x792c, 0x698e, 0x7930, 0x6992,
 	0x7934, 0x6996, 0x6853, 0x003d, 0x7244, 0xa294, 0x0003, 0xa286,
-	0x0002, 0x00c0, 0x995f, 0x684f, 0x0040, 0x0078, 0x9969, 0xa286,
-	0x0001, 0x00c0, 0x9967, 0x684f, 0x0080, 0x0078, 0x9969, 0x684f,
-	0x0000, 0x20a9, 0x000a, 0x2001, 0xab90, 0xad90, 0x0015, 0x200c,
-	0x810f, 0x2112, 0x8000, 0x8210, 0x00f0, 0x996f, 0x200c, 0x6982,
+	0x0002, 0x00c0, 0x996f, 0x684f, 0x0040, 0x0078, 0x9979, 0xa286,
+	0x0001, 0x00c0, 0x9977, 0x684f, 0x0080, 0x0078, 0x9979, 0x684f,
+	0x0000, 0x20a9, 0x000a, 0x2001, 0xac90, 0xad90, 0x0015, 0x200c,
+	0x810f, 0x2112, 0x8000, 0x8210, 0x00f0, 0x997f, 0x200c, 0x6982,
 	0x8000, 0x200c, 0x697e, 0x1078, 0x4a73, 0x027f, 0x047f, 0x157f,
-	0x0f7f, 0x0e7f, 0x0d7f, 0x007c, 0x2001, 0xa60e, 0x2004, 0xd084,
-	0x0040, 0x998e, 0x1078, 0x138b, 0x00c0, 0x9930, 0x6013, 0x0100,
+	0x0f7f, 0x0e7f, 0x0d7f, 0x007c, 0x2001, 0xa70e, 0x2004, 0xd084,
+	0x0040, 0x999e, 0x1078, 0x138b, 0x00c0, 0x9940, 0x6013, 0x0100,
 	0x6003, 0x0001, 0x6007, 0x0041, 0x1078, 0x5d8a, 0x1078, 0x62d1,
-	0x0078, 0x997d, 0x2069, 0xab92, 0x2d04, 0xa084, 0xff00, 0xa086,
-	0x1200, 0x00c0, 0x99b9, 0x2069, 0xab80, 0x686c, 0xa084, 0x00ff,
+	0x0078, 0x998d, 0x2069, 0xac92, 0x2d04, 0xa084, 0xff00, 0xa086,
+	0x1200, 0x00c0, 0x99c9, 0x2069, 0xac80, 0x686c, 0xa084, 0x00ff,
 	0x017e, 0x6110, 0xa18c, 0x0700, 0xa10d, 0x6112, 0x017f, 0x6003,
 	0x0001, 0x6007, 0x0043, 0x1078, 0x5d8a, 0x1078, 0x62d1, 0x0078,
-	0x997d, 0x6013, 0x0200, 0x6003, 0x0001, 0x6007, 0x0041, 0x1078,
-	0x5d8a, 0x1078, 0x62d1, 0x0078, 0x997d, 0x2001, 0xa60d, 0x2004,
-	0xd0ec, 0x0040, 0x99cf, 0x2011, 0x8049, 0x1078, 0x361b, 0x6013,
-	0x0300, 0x0078, 0x99d5, 0x6013, 0x0100, 0x6003, 0x0001, 0x6007,
-	0x0041, 0x1078, 0x5d8a, 0x1078, 0x62d1, 0x0078, 0x997d, 0x6013,
-	0x0500, 0x0078, 0x99d5, 0x6013, 0x0600, 0x0078, 0x999a, 0x6013,
-	0x0200, 0x0078, 0x999a, 0xa186, 0x0013, 0x00c0, 0x99fd, 0x6004,
+	0x998d, 0x6013, 0x0200, 0x6003, 0x0001, 0x6007, 0x0041, 0x1078,
+	0x5d8a, 0x1078, 0x62d1, 0x0078, 0x998d, 0x2001, 0xa70d, 0x2004,
+	0xd0ec, 0x0040, 0x99df, 0x2011, 0x8049, 0x1078, 0x361b, 0x6013,
+	0x0300, 0x0078, 0x99e5, 0x6013, 0x0100, 0x6003, 0x0001, 0x6007,
+	0x0041, 0x1078, 0x5d8a, 0x1078, 0x62d1, 0x0078, 0x998d, 0x6013,
+	0x0500, 0x0078, 0x99e5, 0x6013, 0x0600, 0x0078, 0x99aa, 0x6013,
+	0x0200, 0x0078, 0x99aa, 0xa186, 0x0013, 0x00c0, 0x9a0d, 0x6004,
 	0xa08a, 0x0040, 0x1048, 0x1332, 0xa08a, 0x0053, 0x10c8, 0x1332,
-	0xa082, 0x0040, 0x2008, 0x0079, 0x9a82, 0xa186, 0x0051, 0x0040,
-	0x9a0a, 0xa186, 0x0047, 0x00c0, 0x9a23, 0x6004, 0xa086, 0x0041,
-	0x0040, 0x9a31, 0x2001, 0x0109, 0x2004, 0xd084, 0x0040, 0x9a31,
+	0xa082, 0x0040, 0x2008, 0x0079, 0x9a92, 0xa186, 0x0051, 0x0040,
+	0x9a1a, 0xa186, 0x0047, 0x00c0, 0x9a33, 0x6004, 0xa086, 0x0041,
+	0x0040, 0x9a41, 0x2001, 0x0109, 0x2004, 0xd084, 0x0040, 0x9a41,
 	0x127e, 0x2091, 0x2200, 0x007e, 0x017e, 0x027e, 0x1078, 0x5c56,
 	0x027f, 0x017f, 0x007f, 0x127f, 0x6000, 0xa086, 0x0002, 0x00c0,
-	0x9a31, 0x0078, 0x9ac7, 0xa186, 0x0027, 0x0040, 0x9a2b, 0xa186,
+	0x9a41, 0x0078, 0x9ad7, 0xa186, 0x0027, 0x0040, 0x9a3b, 0xa186,
 	0x0014, 0x10c0, 0x1332, 0x6004, 0xa082, 0x0040, 0x2008, 0x0079,
-	0x9a34, 0x1078, 0x7773, 0x007c, 0x9a47, 0x9a49, 0x9a49, 0x9a71,
-	0x9a47, 0x9a47, 0x9a47, 0x9a47, 0x9a47, 0x9a47, 0x9a47, 0x9a47,
-	0x9a47, 0x9a47, 0x9a47, 0x9a47, 0x9a47, 0x9a47, 0x9a47, 0x1078,
+	0x9a44, 0x1078, 0x7773, 0x007c, 0x9a57, 0x9a59, 0x9a59, 0x9a81,
+	0x9a57, 0x9a57, 0x9a57, 0x9a57, 0x9a57, 0x9a57, 0x9a57, 0x9a57,
+	0x9a57, 0x9a57, 0x9a57, 0x9a57, 0x9a57, 0x9a57, 0x9a57, 0x1078,
 	0x1332, 0x1078, 0x61cd, 0x1078, 0x62d1, 0x037e, 0x0d7e, 0x6010,
-	0xa06d, 0x0040, 0x9a6e, 0xad84, 0xf000, 0x0040, 0x9a6e, 0x6003,
-	0x0002, 0x6018, 0x2004, 0xd0bc, 0x00c0, 0x9a6e, 0x2019, 0x0004,
-	0x1078, 0xa1ca, 0x6013, 0x0000, 0x6014, 0xa005, 0x00c0, 0x9a6c,
-	0x2001, 0xa8a3, 0x2004, 0x6016, 0x6003, 0x0007, 0x0d7f, 0x037f,
-	0x007c, 0x0d7e, 0x1078, 0x61cd, 0x1078, 0x62d1, 0x1078, 0x8d06,
-	0x0040, 0x9a7e, 0x6010, 0x2068, 0x1078, 0x13a4, 0x1078, 0x8ec6,
-	0x0d7f, 0x007c, 0x9a95, 0x9ab4, 0x9a9e, 0x9ac1, 0x9a95, 0x9a95,
-	0x9a95, 0x9a95, 0x9a95, 0x9a95, 0x9a95, 0x9a95, 0x9a95, 0x9a95,
-	0x9a95, 0x9a95, 0x9a95, 0x9a95, 0x9a95, 0x1078, 0x1332, 0x6010,
+	0xa06d, 0x0040, 0x9a7e, 0xad84, 0xf000, 0x0040, 0x9a7e, 0x6003,
+	0x0002, 0x6018, 0x2004, 0xd0bc, 0x00c0, 0x9a7e, 0x2019, 0x0004,
+	0x1078, 0xa1da, 0x6013, 0x0000, 0x6014, 0xa005, 0x00c0, 0x9a7c,
+	0x2001, 0xa9a3, 0x2004, 0x6016, 0x6003, 0x0007, 0x0d7f, 0x037f,
+	0x007c, 0x0d7e, 0x1078, 0x61cd, 0x1078, 0x62d1, 0x1078, 0x8d16,
+	0x0040, 0x9a8e, 0x6010, 0x2068, 0x1078, 0x13a4, 0x1078, 0x8ed6,
+	0x0d7f, 0x007c, 0x9aa5, 0x9ac4, 0x9aae, 0x9ad1, 0x9aa5, 0x9aa5,
+	0x9aa5, 0x9aa5, 0x9aa5, 0x9aa5, 0x9aa5, 0x9aa5, 0x9aa5, 0x9aa5,
+	0x9aa5, 0x9aa5, 0x9aa5, 0x9aa5, 0x9aa5, 0x1078, 0x1332, 0x6010,
 	0xa088, 0x0013, 0x2104, 0xa085, 0x0400, 0x200a, 0x1078, 0x61cd,
-	0x6010, 0xa080, 0x0013, 0x2004, 0xd0b4, 0x0040, 0x9aaf, 0x6003,
-	0x0007, 0x2009, 0x0043, 0x1078, 0x775c, 0x0078, 0x9ab1, 0x6003,
-	0x0002, 0x1078, 0x62d1, 0x007c, 0x1078, 0x61cd, 0x1078, 0xa423,
-	0x00c0, 0x9abe, 0x1078, 0x5bc1, 0x1078, 0x772d, 0x1078, 0x62d1,
-	0x007c, 0x1078, 0x61cd, 0x2009, 0x0041, 0x0078, 0x9c1e, 0xa182,
-	0x0040, 0x0079, 0x9acb, 0x9ade, 0x9ae0, 0x9ade, 0x9ade, 0x9ade,
-	0x9ade, 0x9ade, 0x9ae1, 0x9ade, 0x9ade, 0x9ade, 0x9ade, 0x9ade,
-	0x9ade, 0x9ade, 0x9ade, 0x9ade, 0x9aec, 0x9ade, 0x1078, 0x1332,
+	0x6010, 0xa080, 0x0013, 0x2004, 0xd0b4, 0x0040, 0x9abf, 0x6003,
+	0x0007, 0x2009, 0x0043, 0x1078, 0x775c, 0x0078, 0x9ac1, 0x6003,
+	0x0002, 0x1078, 0x62d1, 0x007c, 0x1078, 0x61cd, 0x1078, 0xa433,
+	0x00c0, 0x9ace, 0x1078, 0x5bc1, 0x1078, 0x772d, 0x1078, 0x62d1,
+	0x007c, 0x1078, 0x61cd, 0x2009, 0x0041, 0x0078, 0x9c2e, 0xa182,
+	0x0040, 0x0079, 0x9adb, 0x9aee, 0x9af0, 0x9aee, 0x9aee, 0x9aee,
+	0x9aee, 0x9aee, 0x9af1, 0x9aee, 0x9aee, 0x9aee, 0x9aee, 0x9aee,
+	0x9aee, 0x9aee, 0x9aee, 0x9aee, 0x9afc, 0x9aee, 0x1078, 0x1332,
 	0x007c, 0x6003, 0x0004, 0x6110, 0x20e1, 0x0005, 0x3d18, 0x3e20,
 	0x2c10, 0x1078, 0x15fa, 0x007c, 0x0d7e, 0x1078, 0x5bc1, 0x0d7f,
-	0x1078, 0xa495, 0x1078, 0x772d, 0x007c, 0xa182, 0x0040, 0x0079,
-	0x9af9, 0x9b0c, 0x9b0c, 0x9b0c, 0x9b0c, 0x9b0c, 0x9b0c, 0x9b0c,
-	0x9b0e, 0x9b0c, 0x9b11, 0x9b3c, 0x9b0c, 0x9b0c, 0x9b0c, 0x9b0c,
-	0x9b3c, 0x9b0c, 0x9b0c, 0x9b0c, 0x1078, 0x1332, 0x1078, 0x7773,
+	0x1078, 0xa4a5, 0x1078, 0x772d, 0x007c, 0xa182, 0x0040, 0x0079,
+	0x9b09, 0x9b1c, 0x9b1c, 0x9b1c, 0x9b1c, 0x9b1c, 0x9b1c, 0x9b1c,
+	0x9b1e, 0x9b1c, 0x9b21, 0x9b4c, 0x9b1c, 0x9b1c, 0x9b1c, 0x9b1c,
+	0x9b4c, 0x9b1c, 0x9b1c, 0x9b1c, 0x1078, 0x1332, 0x1078, 0x7773,
 	0x007c, 0x1078, 0x627a, 0x1078, 0x639b, 0x6010, 0x0d7e, 0x2068,
-	0x684c, 0xd0fc, 0x0040, 0x9b27, 0xa08c, 0x0003, 0xa18e, 0x0002,
-	0x0040, 0x9b2f, 0x2009, 0x0041, 0x0d7f, 0x0078, 0x9c1e, 0x6003,
+	0x684c, 0xd0fc, 0x0040, 0x9b37, 0xa08c, 0x0003, 0xa18e, 0x0002,
+	0x0040, 0x9b3f, 0x2009, 0x0041, 0x0d7f, 0x0078, 0x9c2e, 0x6003,
 	0x0007, 0x6017, 0x0000, 0x1078, 0x5bc1, 0x0d7f, 0x007c, 0x1078,
-	0xa423, 0x0040, 0x9b35, 0x0d7f, 0x007c, 0x1078, 0x5bc1, 0x1078,
-	0x772d, 0x0d7f, 0x0078, 0x9b2e, 0x037e, 0x1078, 0x627a, 0x1078,
+	0xa433, 0x0040, 0x9b45, 0x0d7f, 0x007c, 0x1078, 0x5bc1, 0x1078,
+	0x772d, 0x0d7f, 0x0078, 0x9b3e, 0x037e, 0x1078, 0x627a, 0x1078,
 	0x639b, 0x6010, 0x0d7e, 0x2068, 0x6018, 0x2004, 0xd0bc, 0x0040,
-	0x9b5c, 0x684c, 0xa084, 0x0003, 0xa086, 0x0002, 0x0040, 0x9b58,
+	0x9b6c, 0x684c, 0xa084, 0x0003, 0xa086, 0x0002, 0x0040, 0x9b68,
 	0x687c, 0x632c, 0xa31a, 0x632e, 0x6880, 0x6328, 0xa31b, 0x632a,
-	0x6003, 0x0002, 0x0078, 0x9b6d, 0x2019, 0x0004, 0x1078, 0xa1ca,
-	0x6014, 0xa005, 0x00c0, 0x9b69, 0x2001, 0xa8a3, 0x2004, 0x8003,
+	0x6003, 0x0002, 0x0078, 0x9b7d, 0x2019, 0x0004, 0x1078, 0xa1da,
+	0x6014, 0xa005, 0x00c0, 0x9b79, 0x2001, 0xa9a3, 0x2004, 0x8003,
 	0x6016, 0x6013, 0x0000, 0x6003, 0x0007, 0x0d7f, 0x037f, 0x007c,
-	0xa186, 0x0013, 0x00c0, 0x9b7e, 0x6004, 0xa086, 0x0042, 0x10c0,
+	0xa186, 0x0013, 0x00c0, 0x9b8e, 0x6004, 0xa086, 0x0042, 0x10c0,
 	0x1332, 0x1078, 0x61cd, 0x1078, 0x62d1, 0x007c, 0xa186, 0x0027,
-	0x0040, 0x9b86, 0xa186, 0x0014, 0x00c0, 0x9b96, 0x6004, 0xa086,
+	0x0040, 0x9b96, 0xa186, 0x0014, 0x00c0, 0x9ba6, 0x6004, 0xa086,
 	0x0042, 0x10c0, 0x1332, 0x2001, 0x0007, 0x1078, 0x4535, 0x1078,
-	0x61cd, 0x1078, 0x8ec6, 0x1078, 0x62d1, 0x007c, 0xa182, 0x0040,
-	0x0079, 0x9b9a, 0x9bad, 0x9bad, 0x9bad, 0x9bad, 0x9bad, 0x9bad,
-	0x9bad, 0x9baf, 0x9bbb, 0x9bad, 0x9bad, 0x9bad, 0x9bad, 0x9bad,
-	0x9bad, 0x9bad, 0x9bad, 0x9bad, 0x9bad, 0x1078, 0x1332, 0x037e,
+	0x61cd, 0x1078, 0x8ed6, 0x1078, 0x62d1, 0x007c, 0xa182, 0x0040,
+	0x0079, 0x9baa, 0x9bbd, 0x9bbd, 0x9bbd, 0x9bbd, 0x9bbd, 0x9bbd,
+	0x9bbd, 0x9bbf, 0x9bcb, 0x9bbd, 0x9bbd, 0x9bbd, 0x9bbd, 0x9bbd,
+	0x9bbd, 0x9bbd, 0x9bbd, 0x9bbd, 0x9bbd, 0x1078, 0x1332, 0x037e,
 	0x047e, 0x20e1, 0x0005, 0x3d18, 0x3e20, 0x2c10, 0x1078, 0x15fa,
 	0x047f, 0x037f, 0x007c, 0x6010, 0x0d7e, 0x2068, 0x6810, 0x6a14,
-	0x6118, 0x210c, 0xd1bc, 0x0040, 0x9bda, 0x6124, 0xd1f4, 0x00c0,
-	0x9bda, 0x007e, 0x047e, 0x057e, 0x6c7c, 0xa422, 0x6d80, 0x2200,
+	0x6118, 0x210c, 0xd1bc, 0x0040, 0x9bea, 0x6124, 0xd1f4, 0x00c0,
+	0x9bea, 0x007e, 0x047e, 0x057e, 0x6c7c, 0xa422, 0x6d80, 0x2200,
 	0xa52b, 0x602c, 0xa420, 0x642e, 0x6028, 0xa529, 0x652a, 0x057f,
-	0x047f, 0x007f, 0xa20d, 0x00c0, 0x9bee, 0x684c, 0xd0fc, 0x0040,
-	0x9be6, 0x2009, 0x0041, 0x0d7f, 0x0078, 0x9c1e, 0x6003, 0x0007,
+	0x047f, 0x007f, 0xa20d, 0x00c0, 0x9bfe, 0x684c, 0xd0fc, 0x0040,
+	0x9bf6, 0x2009, 0x0041, 0x0d7f, 0x0078, 0x9c2e, 0x6003, 0x0007,
 	0x6017, 0x0000, 0x1078, 0x5bc1, 0x0d7f, 0x007c, 0x007e, 0x0f7e,
-	0x2c78, 0x1078, 0x4963, 0x0f7f, 0x007f, 0x0040, 0x9bfb, 0x6003,
-	0x0002, 0x0d7f, 0x007c, 0x2009, 0xa60d, 0x210c, 0xd19c, 0x0040,
-	0x9c05, 0x6003, 0x0007, 0x0078, 0x9c07, 0x6003, 0x0006, 0x1078,
-	0x9c0d, 0x1078, 0x5bc3, 0x0d7f, 0x007c, 0xd2fc, 0x0040, 0x9c19,
+	0x2c78, 0x1078, 0x4963, 0x0f7f, 0x007f, 0x0040, 0x9c0b, 0x6003,
+	0x0002, 0x0d7f, 0x007c, 0x2009, 0xa70d, 0x210c, 0xd19c, 0x0040,
+	0x9c15, 0x6003, 0x0007, 0x0078, 0x9c17, 0x6003, 0x0006, 0x1078,
+	0x9c1d, 0x1078, 0x5bc3, 0x0d7f, 0x007c, 0xd2fc, 0x0040, 0x9c29,
 	0x8002, 0x8000, 0x8212, 0xa291, 0x0000, 0x2009, 0x0009, 0x0078,
-	0x9c1b, 0x2009, 0x0015, 0x6a6a, 0x6866, 0x007c, 0xa182, 0x0040,
-	0x0048, 0x9c24, 0x0079, 0x9c31, 0xa186, 0x0013, 0x0040, 0x9c2c,
+	0x9c2b, 0x2009, 0x0015, 0x6a6a, 0x6866, 0x007c, 0xa182, 0x0040,
+	0x0048, 0x9c34, 0x0079, 0x9c41, 0xa186, 0x0013, 0x0040, 0x9c3c,
 	0xa186, 0x0014, 0x10c0, 0x1332, 0x6024, 0xd0dc, 0x1040, 0x1332,
-	0x007c, 0x9c44, 0x9c4b, 0x9c57, 0x9c63, 0x9c44, 0x9c44, 0x9c44,
-	0x9c72, 0x9c44, 0x9c46, 0x9c46, 0x9c44, 0x9c44, 0x9c44, 0x9c44,
-	0x9c44, 0x9c44, 0x9c44, 0x9c44, 0x1078, 0x1332, 0x6024, 0xd0dc,
+	0x007c, 0x9c54, 0x9c5b, 0x9c67, 0x9c73, 0x9c54, 0x9c54, 0x9c54,
+	0x9c82, 0x9c54, 0x9c56, 0x9c56, 0x9c54, 0x9c54, 0x9c54, 0x9c54,
+	0x9c54, 0x9c54, 0x9c54, 0x9c54, 0x1078, 0x1332, 0x6024, 0xd0dc,
 	0x1040, 0x1332, 0x007c, 0x6003, 0x0001, 0x6106, 0x1078, 0x5d8a,
 	0x127e, 0x2091, 0x8000, 0x1078, 0x62d1, 0x127f, 0x007c, 0x6003,
 	0x0001, 0x6106, 0x1078, 0x5d8a, 0x127e, 0x2091, 0x8000, 0x1078,
 	0x62d1, 0x127f, 0x007c, 0x6003, 0x0003, 0x6106, 0x2c10, 0x1078,
 	0x1cf0, 0x127e, 0x2091, 0x8000, 0x1078, 0x5df6, 0x1078, 0x639b,
 	0x127f, 0x007c, 0xa016, 0x1078, 0x15fa, 0x007c, 0x127e, 0x2091,
-	0x8000, 0x037e, 0x0d7e, 0xa182, 0x0040, 0x1079, 0x9c83, 0x0d7f,
-	0x037f, 0x127f, 0x007c, 0x9c93, 0x9c95, 0x9caa, 0x9cc9, 0x9c93,
-	0x9c93, 0x9c93, 0x9ce1, 0x9c93, 0x9c93, 0x9c93, 0x9c93, 0x9c93,
-	0x9c93, 0x9c93, 0x9c93, 0x1078, 0x1332, 0x6010, 0x2068, 0x684c,
-	0xd0fc, 0x0040, 0x9cbf, 0xa09c, 0x0003, 0xa39e, 0x0003, 0x0040,
-	0x9cbf, 0x6003, 0x0001, 0x6106, 0x1078, 0x5d8a, 0x1078, 0x62d1,
-	0x0078, 0x9ce4, 0x6010, 0x2068, 0x684c, 0xd0fc, 0x0040, 0x9cbf,
-	0xa09c, 0x0003, 0xa39e, 0x0003, 0x0040, 0x9cbf, 0x6003, 0x0001,
-	0x6106, 0x1078, 0x5d8a, 0x1078, 0x62d1, 0x0078, 0x9ce4, 0x6013,
-	0x0000, 0x6017, 0x0000, 0x2019, 0x0004, 0x1078, 0xa1ca, 0x0078,
-	0x9ce4, 0x6010, 0x2068, 0x684c, 0xd0fc, 0x0040, 0x9cbf, 0xa09c,
-	0x0003, 0xa39e, 0x0003, 0x0040, 0x9cbf, 0x6003, 0x0003, 0x6106,
+	0x8000, 0x037e, 0x0d7e, 0xa182, 0x0040, 0x1079, 0x9c93, 0x0d7f,
+	0x037f, 0x127f, 0x007c, 0x9ca3, 0x9ca5, 0x9cba, 0x9cd9, 0x9ca3,
+	0x9ca3, 0x9ca3, 0x9cf1, 0x9ca3, 0x9ca3, 0x9ca3, 0x9ca3, 0x9ca3,
+	0x9ca3, 0x9ca3, 0x9ca3, 0x1078, 0x1332, 0x6010, 0x2068, 0x684c,
+	0xd0fc, 0x0040, 0x9ccf, 0xa09c, 0x0003, 0xa39e, 0x0003, 0x0040,
+	0x9ccf, 0x6003, 0x0001, 0x6106, 0x1078, 0x5d8a, 0x1078, 0x62d1,
+	0x0078, 0x9cf4, 0x6010, 0x2068, 0x684c, 0xd0fc, 0x0040, 0x9ccf,
+	0xa09c, 0x0003, 0xa39e, 0x0003, 0x0040, 0x9ccf, 0x6003, 0x0001,
+	0x6106, 0x1078, 0x5d8a, 0x1078, 0x62d1, 0x0078, 0x9cf4, 0x6013,
+	0x0000, 0x6017, 0x0000, 0x2019, 0x0004, 0x1078, 0xa1da, 0x0078,
+	0x9cf4, 0x6010, 0x2068, 0x684c, 0xd0fc, 0x0040, 0x9ccf, 0xa09c,
+	0x0003, 0xa39e, 0x0003, 0x0040, 0x9ccf, 0x6003, 0x0003, 0x6106,
 	0x2c10, 0x1078, 0x1cf0, 0x1078, 0x5df6, 0x1078, 0x639b, 0x0078,
-	0x9ce4, 0xa016, 0x1078, 0x15fa, 0x007c, 0x1078, 0x61cd, 0x6110,
-	0x81ff, 0x0040, 0x9cf6, 0x0d7e, 0x2168, 0x1078, 0xa4e2, 0x037e,
-	0x2019, 0x0029, 0x1078, 0xa1ca, 0x037f, 0x0d7f, 0x1078, 0x8ec6,
+	0x9cf4, 0xa016, 0x1078, 0x15fa, 0x007c, 0x1078, 0x61cd, 0x6110,
+	0x81ff, 0x0040, 0x9d06, 0x0d7e, 0x2168, 0x1078, 0xa4f2, 0x037e,
+	0x2019, 0x0029, 0x1078, 0xa1da, 0x037f, 0x0d7f, 0x1078, 0x8ed6,
 	0x1078, 0x62d1, 0x007c, 0x1078, 0x627a, 0x6110, 0x81ff, 0x0040,
-	0x9d0c, 0x0d7e, 0x2168, 0x1078, 0xa4e2, 0x037e, 0x2019, 0x0029,
-	0x1078, 0xa1ca, 0x037f, 0x0d7f, 0x1078, 0x8ec6, 0x1078, 0x639b,
-	0x007c, 0xa182, 0x0085, 0x0079, 0x9d15, 0x9d1e, 0x9d1c, 0x9d1c,
-	0x9d2a, 0x9d1c, 0x9d1c, 0x9d1c, 0x1078, 0x1332, 0x6003, 0x000b,
+	0x9d1c, 0x0d7e, 0x2168, 0x1078, 0xa4f2, 0x037e, 0x2019, 0x0029,
+	0x1078, 0xa1da, 0x037f, 0x0d7f, 0x1078, 0x8ed6, 0x1078, 0x639b,
+	0x007c, 0xa182, 0x0085, 0x0079, 0x9d25, 0x9d2e, 0x9d2c, 0x9d2c,
+	0x9d3a, 0x9d2c, 0x9d2c, 0x9d2c, 0x1078, 0x1332, 0x6003, 0x000b,
 	0x6106, 0x1078, 0x5d8a, 0x127e, 0x2091, 0x8000, 0x1078, 0x62d1,
-	0x127f, 0x007c, 0x027e, 0x0e7e, 0x1078, 0xa41c, 0x0040, 0x9d34,
-	0x1078, 0x772d, 0x0078, 0x9d50, 0x2071, 0xab80, 0x7224, 0x6212,
-	0x7220, 0x1078, 0xa069, 0x0040, 0x9d41, 0x6007, 0x0086, 0x0078,
-	0x9d4a, 0x6007, 0x0087, 0x7224, 0xa296, 0xffff, 0x00c0, 0x9d4a,
+	0x127f, 0x007c, 0x027e, 0x0e7e, 0x1078, 0xa42c, 0x0040, 0x9d44,
+	0x1078, 0x772d, 0x0078, 0x9d60, 0x2071, 0xac80, 0x7224, 0x6212,
+	0x7220, 0x1078, 0xa079, 0x0040, 0x9d51, 0x6007, 0x0086, 0x0078,
+	0x9d5a, 0x6007, 0x0087, 0x7224, 0xa296, 0xffff, 0x00c0, 0x9d5a,
 	0x6007, 0x0086, 0x6003, 0x0001, 0x1078, 0x5d8a, 0x1078, 0x62d1,
-	0x0e7f, 0x027f, 0x007c, 0xa186, 0x0013, 0x00c0, 0x9d64, 0x6004,
+	0x0e7f, 0x027f, 0x007c, 0xa186, 0x0013, 0x00c0, 0x9d74, 0x6004,
 	0xa08a, 0x0085, 0x1048, 0x1332, 0xa08a, 0x008c, 0x10c8, 0x1332,
-	0xa082, 0x0085, 0x0079, 0x9d7b, 0xa186, 0x0027, 0x0040, 0x9d70,
-	0xa186, 0x0014, 0x0040, 0x9d70, 0x1078, 0x7773, 0x0078, 0x9d7a,
-	0x2001, 0x0007, 0x1078, 0x4535, 0x1078, 0x61cd, 0x1078, 0x8ec6,
-	0x1078, 0x62d1, 0x007c, 0x9d82, 0x9d84, 0x9d84, 0x9d82, 0x9d82,
-	0x9d82, 0x9d82, 0x1078, 0x1332, 0x1078, 0x61cd, 0x1078, 0x8ec6,
+	0xa082, 0x0085, 0x0079, 0x9d8b, 0xa186, 0x0027, 0x0040, 0x9d80,
+	0xa186, 0x0014, 0x0040, 0x9d80, 0x1078, 0x7773, 0x0078, 0x9d8a,
+	0x2001, 0x0007, 0x1078, 0x4535, 0x1078, 0x61cd, 0x1078, 0x8ed6,
+	0x1078, 0x62d1, 0x007c, 0x9d92, 0x9d94, 0x9d94, 0x9d92, 0x9d92,
+	0x9d92, 0x9d92, 0x1078, 0x1332, 0x1078, 0x61cd, 0x1078, 0x8ed6,
 	0x1078, 0x62d1, 0x007c, 0xa182, 0x0085, 0x1048, 0x1332, 0xa182,
-	0x008c, 0x10c8, 0x1332, 0xa182, 0x0085, 0x0079, 0x9d97, 0x9d9e,
-	0x9d9e, 0x9d9e, 0x9da0, 0x9d9e, 0x9d9e, 0x9d9e, 0x1078, 0x1332,
-	0x007c, 0xa186, 0x0013, 0x0040, 0x9db1, 0xa186, 0x0014, 0x0040,
-	0x9db1, 0xa186, 0x0027, 0x0040, 0x9db1, 0x1078, 0x7773, 0x0078,
-	0x9db7, 0x1078, 0x61cd, 0x1078, 0x8ec6, 0x1078, 0x62d1, 0x007c,
-	0x037e, 0x1078, 0xa495, 0x603f, 0x0000, 0x2019, 0x000b, 0x1078,
-	0x9dc7, 0x601f, 0x0006, 0x6003, 0x0007, 0x037f, 0x007c, 0x127e,
+	0x008c, 0x10c8, 0x1332, 0xa182, 0x0085, 0x0079, 0x9da7, 0x9dae,
+	0x9dae, 0x9dae, 0x9db0, 0x9dae, 0x9dae, 0x9dae, 0x1078, 0x1332,
+	0x007c, 0xa186, 0x0013, 0x0040, 0x9dc1, 0xa186, 0x0014, 0x0040,
+	0x9dc1, 0xa186, 0x0027, 0x0040, 0x9dc1, 0x1078, 0x7773, 0x0078,
+	0x9dc7, 0x1078, 0x61cd, 0x1078, 0x8ed6, 0x1078, 0x62d1, 0x007c,
+	0x037e, 0x1078, 0xa4a5, 0x603f, 0x0000, 0x2019, 0x000b, 0x1078,
+	0x9dd7, 0x601f, 0x0006, 0x6003, 0x0007, 0x037f, 0x007c, 0x127e,
 	0x037e, 0x2091, 0x8000, 0x087e, 0x2c40, 0x097e, 0x2049, 0x0000,
-	0x1078, 0x7246, 0x097f, 0x087f, 0x00c0, 0x9e02, 0x077e, 0x2c38,
-	0x1078, 0x72f3, 0x077f, 0x00c0, 0x9e02, 0x6000, 0xa086, 0x0000,
-	0x0040, 0x9e02, 0x601c, 0xa086, 0x0007, 0x0040, 0x9e02, 0x0d7e,
-	0x6000, 0xa086, 0x0004, 0x00c0, 0x9df3, 0x1078, 0xa495, 0x601f,
-	0x0007, 0x1078, 0x1757, 0x6010, 0x2068, 0x1078, 0x8d06, 0x0040,
-	0x9dfb, 0x1078, 0xa1ca, 0x0d7f, 0x6013, 0x0000, 0x1078, 0xa495,
+	0x1078, 0x7246, 0x097f, 0x087f, 0x00c0, 0x9e12, 0x077e, 0x2c38,
+	0x1078, 0x72f3, 0x077f, 0x00c0, 0x9e12, 0x6000, 0xa086, 0x0000,
+	0x0040, 0x9e12, 0x601c, 0xa086, 0x0007, 0x0040, 0x9e12, 0x0d7e,
+	0x6000, 0xa086, 0x0004, 0x00c0, 0x9e03, 0x1078, 0xa4a5, 0x601f,
+	0x0007, 0x1078, 0x1757, 0x6010, 0x2068, 0x1078, 0x8d16, 0x0040,
+	0x9e0b, 0x1078, 0xa1da, 0x0d7f, 0x6013, 0x0000, 0x1078, 0xa4a5,
 	0x601f, 0x0007, 0x037f, 0x127f, 0x007c, 0x0f7e, 0x0c7e, 0x037e,
-	0x157e, 0x2079, 0xab80, 0x7938, 0x783c, 0x1078, 0x254d, 0x00c0,
-	0x9e49, 0x017e, 0x0c7e, 0x1078, 0x45c4, 0x00c0, 0x9e49, 0x017f,
+	0x157e, 0x2079, 0xac80, 0x7938, 0x783c, 0x1078, 0x254d, 0x00c0,
+	0x9e59, 0x017e, 0x0c7e, 0x1078, 0x45c4, 0x00c0, 0x9e59, 0x017f,
 	0x027f, 0x027e, 0x017e, 0x2019, 0x0029, 0x1078, 0x73d0, 0x1078,
 	0x5f01, 0x077e, 0x2039, 0x0000, 0x1078, 0x5e0a, 0x077f, 0x017f,
-	0x077e, 0x2039, 0x0000, 0x1078, 0x9f8b, 0x077f, 0x1078, 0x47e9,
+	0x077e, 0x2039, 0x0000, 0x1078, 0x9f9b, 0x077f, 0x1078, 0x47e9,
 	0x027e, 0x6204, 0xa294, 0xff00, 0x8217, 0xa286, 0x0006, 0x0040,
-	0x9e3d, 0xa286, 0x0004, 0x00c0, 0x9e40, 0x62a0, 0x1078, 0x2942,
+	0x9e4d, 0xa286, 0x0004, 0x00c0, 0x9e50, 0x62a0, 0x1078, 0x2942,
 	0x027f, 0x017f, 0x1078, 0x42f8, 0x6612, 0x6516, 0xa006, 0x0078,
-	0x9e4b, 0x0c7f, 0x017f, 0x157f, 0x037f, 0x0c7f, 0x0f7f, 0x007c,
-	0x0c7e, 0x0d7e, 0x0e7e, 0x017e, 0x2009, 0xa620, 0x2104, 0xa086,
-	0x0074, 0x00c0, 0x9eb3, 0x2069, 0xab8e, 0x690c, 0xa182, 0x0100,
-	0x0048, 0x9ea3, 0x6908, 0xa184, 0x8000, 0x0040, 0x9eaf, 0x6018,
-	0x2070, 0x7010, 0xa084, 0x00ff, 0x0040, 0x9e72, 0x7000, 0xd0f4,
-	0x0040, 0x9e76, 0xa184, 0x0800, 0x0040, 0x9eaf, 0x6910, 0xa18a,
-	0x0001, 0x0048, 0x9ea7, 0x6914, 0x2069, 0xabae, 0x6904, 0x81ff,
-	0x00c0, 0x9e9b, 0x690c, 0xa182, 0x0100, 0x0048, 0x9ea3, 0x6908,
-	0x81ff, 0x00c0, 0x9e9f, 0x6910, 0xa18a, 0x0001, 0x0048, 0x9ea7,
-	0x6918, 0xa18a, 0x0001, 0x0048, 0x9eaf, 0x0078, 0x9eb9, 0x6013,
-	0x0100, 0x0078, 0x9eb5, 0x6013, 0x0300, 0x0078, 0x9eb5, 0x6013,
-	0x0500, 0x0078, 0x9eb5, 0x6013, 0x0700, 0x0078, 0x9eb5, 0x6013,
-	0x0900, 0x0078, 0x9eb5, 0x6013, 0x0b00, 0x0078, 0x9eb5, 0x6013,
-	0x0f00, 0x0078, 0x9eb5, 0x6013, 0x2d00, 0xa085, 0x0001, 0x0078,
-	0x9eba, 0xa006, 0x017f, 0x0e7f, 0x0d7f, 0x0c7f, 0x007c, 0x0c7e,
+	0x9e5b, 0x0c7f, 0x017f, 0x157f, 0x037f, 0x0c7f, 0x0f7f, 0x007c,
+	0x0c7e, 0x0d7e, 0x0e7e, 0x017e, 0x2009, 0xa720, 0x2104, 0xa086,
+	0x0074, 0x00c0, 0x9ec3, 0x2069, 0xac8e, 0x690c, 0xa182, 0x0100,
+	0x0048, 0x9eb3, 0x6908, 0xa184, 0x8000, 0x0040, 0x9ebf, 0x6018,
+	0x2070, 0x7010, 0xa084, 0x00ff, 0x0040, 0x9e82, 0x7000, 0xd0f4,
+	0x0040, 0x9e86, 0xa184, 0x0800, 0x0040, 0x9ebf, 0x6910, 0xa18a,
+	0x0001, 0x0048, 0x9eb7, 0x6914, 0x2069, 0xacae, 0x6904, 0x81ff,
+	0x00c0, 0x9eab, 0x690c, 0xa182, 0x0100, 0x0048, 0x9eb3, 0x6908,
+	0x81ff, 0x00c0, 0x9eaf, 0x6910, 0xa18a, 0x0001, 0x0048, 0x9eb7,
+	0x6918, 0xa18a, 0x0001, 0x0048, 0x9ebf, 0x0078, 0x9ec9, 0x6013,
+	0x0100, 0x0078, 0x9ec5, 0x6013, 0x0300, 0x0078, 0x9ec5, 0x6013,
+	0x0500, 0x0078, 0x9ec5, 0x6013, 0x0700, 0x0078, 0x9ec5, 0x6013,
+	0x0900, 0x0078, 0x9ec5, 0x6013, 0x0b00, 0x0078, 0x9ec5, 0x6013,
+	0x0f00, 0x0078, 0x9ec5, 0x6013, 0x2d00, 0xa085, 0x0001, 0x0078,
+	0x9eca, 0xa006, 0x017f, 0x0e7f, 0x0d7f, 0x0c7f, 0x007c, 0x0c7e,
 	0x0d7e, 0x027e, 0x037e, 0x157e, 0x6218, 0x2268, 0x6b04, 0xa394,
-	0x00ff, 0xa286, 0x0006, 0x0040, 0x9ee3, 0xa286, 0x0004, 0x0040,
-	0x9ee3, 0xa394, 0xff00, 0x8217, 0xa286, 0x0006, 0x0040, 0x9ee3,
-	0xa286, 0x0004, 0x0040, 0x9ee3, 0x0c7e, 0x2d60, 0x1078, 0x45d6,
-	0x0c7f, 0x0078, 0x9f1e, 0x2011, 0xab96, 0xad98, 0x000a, 0x20a9,
-	0x0004, 0x1078, 0x80de, 0x00c0, 0x9f1f, 0x2011, 0xab9a, 0xad98,
-	0x0006, 0x20a9, 0x0004, 0x1078, 0x80de, 0x00c0, 0x9f1f, 0x047e,
-	0x017e, 0x6aa0, 0xa294, 0x00ff, 0x8227, 0xa006, 0x2009, 0xa653,
-	0x210c, 0xd1a4, 0x0040, 0x9f0b, 0x2009, 0x0029, 0x1078, 0xa21d,
+	0x00ff, 0xa286, 0x0006, 0x0040, 0x9ef3, 0xa286, 0x0004, 0x0040,
+	0x9ef3, 0xa394, 0xff00, 0x8217, 0xa286, 0x0006, 0x0040, 0x9ef3,
+	0xa286, 0x0004, 0x0040, 0x9ef3, 0x0c7e, 0x2d60, 0x1078, 0x45d6,
+	0x0c7f, 0x0078, 0x9f2e, 0x2011, 0xac96, 0xad98, 0x000a, 0x20a9,
+	0x0004, 0x1078, 0x80de, 0x00c0, 0x9f2f, 0x2011, 0xac9a, 0xad98,
+	0x0006, 0x20a9, 0x0004, 0x1078, 0x80de, 0x00c0, 0x9f2f, 0x047e,
+	0x017e, 0x6aa0, 0xa294, 0x00ff, 0x8227, 0xa006, 0x2009, 0xa753,
+	0x210c, 0xd1a4, 0x0040, 0x9f1b, 0x2009, 0x0029, 0x1078, 0xa22d,
 	0x6800, 0xc0e5, 0x6802, 0x2019, 0x0029, 0x1078, 0x5f01, 0x077e,
-	0x2039, 0x0000, 0x1078, 0x5e0a, 0x2c08, 0x1078, 0x9f8b, 0x077f,
+	0x2039, 0x0000, 0x1078, 0x5e0a, 0x2c08, 0x1078, 0x9f9b, 0x077f,
 	0x2001, 0x0007, 0x1078, 0x4535, 0x017f, 0x047f, 0xa006, 0x157f,
-	0x037f, 0x027f, 0x0d7f, 0x0c7f, 0x007c, 0x0d7e, 0x2069, 0xab8e,
-	0x6800, 0xa086, 0x0800, 0x0040, 0x9f31, 0x6013, 0x0000, 0x0078,
-	0x9f32, 0xa006, 0x0d7f, 0x007c, 0x0c7e, 0x0f7e, 0x017e, 0x027e,
-	0x037e, 0x157e, 0x2079, 0xab8c, 0x7930, 0x7834, 0x1078, 0x254d,
-	0x00c0, 0x9f58, 0x1078, 0x45c4, 0x00c0, 0x9f58, 0x2011, 0xab90,
-	0xac98, 0x000a, 0x20a9, 0x0004, 0x1078, 0x80de, 0x00c0, 0x9f58,
-	0x2011, 0xab94, 0xac98, 0x0006, 0x20a9, 0x0004, 0x1078, 0x80de,
+	0x037f, 0x027f, 0x0d7f, 0x0c7f, 0x007c, 0x0d7e, 0x2069, 0xac8e,
+	0x6800, 0xa086, 0x0800, 0x0040, 0x9f41, 0x6013, 0x0000, 0x0078,
+	0x9f42, 0xa006, 0x0d7f, 0x007c, 0x0c7e, 0x0f7e, 0x017e, 0x027e,
+	0x037e, 0x157e, 0x2079, 0xac8c, 0x7930, 0x7834, 0x1078, 0x254d,
+	0x00c0, 0x9f68, 0x1078, 0x45c4, 0x00c0, 0x9f68, 0x2011, 0xac90,
+	0xac98, 0x000a, 0x20a9, 0x0004, 0x1078, 0x80de, 0x00c0, 0x9f68,
+	0x2011, 0xac94, 0xac98, 0x0006, 0x20a9, 0x0004, 0x1078, 0x80de,
 	0x157f, 0x037f, 0x027f, 0x017f, 0x0f7f, 0x0c7f, 0x007c, 0x0c7e,
-	0x007e, 0x017e, 0x027e, 0x037e, 0x157e, 0x2011, 0xab83, 0x2204,
-	0x8211, 0x220c, 0x1078, 0x254d, 0x00c0, 0x9f84, 0x1078, 0x45c4,
-	0x00c0, 0x9f84, 0x2011, 0xab96, 0xac98, 0x000a, 0x20a9, 0x0004,
-	0x1078, 0x80de, 0x00c0, 0x9f84, 0x2011, 0xab9a, 0xac98, 0x0006,
+	0x007e, 0x017e, 0x027e, 0x037e, 0x157e, 0x2011, 0xac83, 0x2204,
+	0x8211, 0x220c, 0x1078, 0x254d, 0x00c0, 0x9f94, 0x1078, 0x45c4,
+	0x00c0, 0x9f94, 0x2011, 0xac96, 0xac98, 0x000a, 0x20a9, 0x0004,
+	0x1078, 0x80de, 0x00c0, 0x9f94, 0x2011, 0xac9a, 0xac98, 0x0006,
 	0x20a9, 0x0004, 0x1078, 0x80de, 0x157f, 0x037f, 0x027f, 0x017f,
 	0x007f, 0x0c7f, 0x007c, 0x0e7e, 0x0c7e, 0x087e, 0x077e, 0x067e,
 	0x057e, 0x047e, 0x027e, 0x127e, 0x2091, 0x8000, 0x2740, 0x2029,
-	0xa8ba, 0x252c, 0x2021, 0xa8c0, 0x2424, 0x2061, 0xad00, 0x2071,
-	0xa600, 0x7648, 0x7064, 0x81ff, 0x0040, 0x9fb2, 0x007e, 0xa186,
-	0xa9b3, 0x007f, 0x0040, 0x9fb2, 0x8001, 0xa602, 0x00c8, 0xa01c,
-	0x0078, 0x9fb5, 0xa606, 0x0040, 0xa01c, 0x2100, 0xac06, 0x0040,
-	0xa012, 0x1078, 0xa242, 0x0040, 0xa012, 0x671c, 0xa786, 0x0001,
-	0x0040, 0xa037, 0xa786, 0x0004, 0x0040, 0xa037, 0xa786, 0x0007,
-	0x0040, 0xa012, 0x2500, 0xac06, 0x0040, 0xa012, 0x2400, 0xac06,
-	0x0040, 0xa012, 0x1078, 0xa256, 0x00c0, 0xa012, 0x88ff, 0x0040,
-	0x9fdd, 0x6020, 0xa906, 0x00c0, 0xa012, 0x0d7e, 0x6000, 0xa086,
-	0x0004, 0x00c0, 0x9fe7, 0x017e, 0x1078, 0x1757, 0x017f, 0xa786,
-	0x0008, 0x00c0, 0x9ff6, 0x1078, 0x8f00, 0x00c0, 0x9ff6, 0x1078,
-	0x7c83, 0x0d7f, 0x1078, 0x8ec6, 0x0078, 0xa012, 0x6010, 0x2068,
-	0x1078, 0x8d06, 0x0040, 0xa00f, 0xa786, 0x0003, 0x00c0, 0xa026,
-	0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x1078, 0xa4e2, 0x017e,
-	0x1078, 0x8f7d, 0x1078, 0x4a73, 0x017f, 0x1078, 0x8eb9, 0x0d7f,
-	0x1078, 0x8ec6, 0xace0, 0x0010, 0x2001, 0xa616, 0x2004, 0xac02,
-	0x00c8, 0xa01c, 0x0078, 0x9f9f, 0x127f, 0x027f, 0x047f, 0x057f,
+	0xa9ba, 0x252c, 0x2021, 0xa9c0, 0x2424, 0x2061, 0xae00, 0x2071,
+	0xa700, 0x7648, 0x7064, 0x81ff, 0x0040, 0x9fc2, 0x007e, 0xa186,
+	0xaab3, 0x007f, 0x0040, 0x9fc2, 0x8001, 0xa602, 0x00c8, 0xa02c,
+	0x0078, 0x9fc5, 0xa606, 0x0040, 0xa02c, 0x2100, 0xac06, 0x0040,
+	0xa022, 0x1078, 0xa252, 0x0040, 0xa022, 0x671c, 0xa786, 0x0001,
+	0x0040, 0xa047, 0xa786, 0x0004, 0x0040, 0xa047, 0xa786, 0x0007,
+	0x0040, 0xa022, 0x2500, 0xac06, 0x0040, 0xa022, 0x2400, 0xac06,
+	0x0040, 0xa022, 0x1078, 0xa266, 0x00c0, 0xa022, 0x88ff, 0x0040,
+	0x9fed, 0x6020, 0xa906, 0x00c0, 0xa022, 0x0d7e, 0x6000, 0xa086,
+	0x0004, 0x00c0, 0x9ff7, 0x017e, 0x1078, 0x1757, 0x017f, 0xa786,
+	0x0008, 0x00c0, 0xa006, 0x1078, 0x8f10, 0x00c0, 0xa006, 0x1078,
+	0x7c83, 0x0d7f, 0x1078, 0x8ed6, 0x0078, 0xa022, 0x6010, 0x2068,
+	0x1078, 0x8d16, 0x0040, 0xa01f, 0xa786, 0x0003, 0x00c0, 0xa036,
+	0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x1078, 0xa4f2, 0x017e,
+	0x1078, 0x8f8d, 0x1078, 0x4a73, 0x017f, 0x1078, 0x8ec9, 0x0d7f,
+	0x1078, 0x8ed6, 0xace0, 0x0010, 0x2001, 0xa716, 0x2004, 0xac02,
+	0x00c8, 0xa02c, 0x0078, 0x9faf, 0x127f, 0x027f, 0x047f, 0x057f,
 	0x067f, 0x077f, 0x087f, 0x0c7f, 0x0e7f, 0x007c, 0xa786, 0x0006,
-	0x00c0, 0xa000, 0xa386, 0x0005, 0x0040, 0xa034, 0x1078, 0xa4e2,
-	0x1078, 0xa1ca, 0x0078, 0xa00f, 0x0d7f, 0x0078, 0xa012, 0x1078,
-	0xa256, 0x00c0, 0xa012, 0x81ff, 0x0040, 0xa012, 0xa180, 0x0001,
-	0x2004, 0xa086, 0x0018, 0x0040, 0xa04c, 0xa180, 0x0001, 0x2004,
-	0xa086, 0x002d, 0x00c0, 0xa012, 0x6000, 0xa086, 0x0002, 0x00c0,
-	0xa012, 0x1078, 0x8eec, 0x0040, 0xa05d, 0x1078, 0x8f00, 0x00c0,
-	0xa012, 0x1078, 0x7c83, 0x0078, 0xa065, 0x1078, 0x28a6, 0x1078,
-	0x8f00, 0x00c0, 0xa065, 0x1078, 0x7c83, 0x1078, 0x8ec6, 0x0078,
-	0xa012, 0x0c7e, 0x0e7e, 0x017e, 0x2c08, 0x2170, 0xa006, 0x1078,
-	0xa1e6, 0x017f, 0x0040, 0xa079, 0x601c, 0xa084, 0x000f, 0x1079,
-	0xa07c, 0x0e7f, 0x0c7f, 0x007c, 0xa084, 0xa084, 0xa084, 0xa084,
-	0xa084, 0xa084, 0xa086, 0xa084, 0xa006, 0x007c, 0x047e, 0x017e,
+	0x00c0, 0xa010, 0xa386, 0x0005, 0x0040, 0xa044, 0x1078, 0xa4f2,
+	0x1078, 0xa1da, 0x0078, 0xa01f, 0x0d7f, 0x0078, 0xa022, 0x1078,
+	0xa266, 0x00c0, 0xa022, 0x81ff, 0x0040, 0xa022, 0xa180, 0x0001,
+	0x2004, 0xa086, 0x0018, 0x0040, 0xa05c, 0xa180, 0x0001, 0x2004,
+	0xa086, 0x002d, 0x00c0, 0xa022, 0x6000, 0xa086, 0x0002, 0x00c0,
+	0xa022, 0x1078, 0x8efc, 0x0040, 0xa06d, 0x1078, 0x8f10, 0x00c0,
+	0xa022, 0x1078, 0x7c83, 0x0078, 0xa075, 0x1078, 0x28a6, 0x1078,
+	0x8f10, 0x00c0, 0xa075, 0x1078, 0x7c83, 0x1078, 0x8ed6, 0x0078,
+	0xa022, 0x0c7e, 0x0e7e, 0x017e, 0x2c08, 0x2170, 0xa006, 0x1078,
+	0xa1f6, 0x017f, 0x0040, 0xa089, 0x601c, 0xa084, 0x000f, 0x1079,
+	0xa08c, 0x0e7f, 0x0c7f, 0x007c, 0xa094, 0xa094, 0xa094, 0xa094,
+	0xa094, 0xa094, 0xa096, 0xa094, 0xa006, 0x007c, 0x047e, 0x017e,
 	0x7018, 0xa080, 0x0028, 0x2024, 0xa4a4, 0x00ff, 0x8427, 0x2c00,
-	0x2009, 0x0020, 0x1078, 0xa21d, 0x017f, 0x047f, 0x037e, 0x2019,
-	0x0002, 0x1078, 0x9dc7, 0x037f, 0xa085, 0x0001, 0x007c, 0x2001,
+	0x2009, 0x0020, 0x1078, 0xa22d, 0x017f, 0x047f, 0x037e, 0x2019,
+	0x0002, 0x1078, 0x9dd7, 0x037f, 0xa085, 0x0001, 0x007c, 0x2001,
 	0x0001, 0x1078, 0x44ee, 0x157e, 0x017e, 0x027e, 0x037e, 0x20a9,
-	0x0004, 0x2019, 0xa605, 0x2011, 0xab96, 0x1078, 0x80de, 0x037f,
+	0x0004, 0x2019, 0xa705, 0x2011, 0xac96, 0x1078, 0x80de, 0x037f,
 	0x027f, 0x017f, 0x157f, 0xa005, 0x007c, 0x0f7e, 0x0e7e, 0x0c7e,
 	0x087e, 0x077e, 0x067e, 0x027e, 0x127e, 0x2091, 0x8000, 0x2740,
-	0x2061, 0xad00, 0x2079, 0x0001, 0x8fff, 0x0040, 0xa11d, 0x2071,
-	0xa600, 0x7648, 0x7064, 0x8001, 0xa602, 0x00c8, 0xa11d, 0x88ff,
-	0x0040, 0xa0d8, 0x2800, 0xac06, 0x00c0, 0xa113, 0x2079, 0x0000,
-	0x1078, 0xa242, 0x0040, 0xa113, 0x2400, 0xac06, 0x0040, 0xa113,
-	0x671c, 0xa786, 0x0006, 0x00c0, 0xa113, 0xa786, 0x0007, 0x0040,
-	0xa113, 0x88ff, 0x00c0, 0xa0f7, 0x6018, 0xa206, 0x00c0, 0xa113,
-	0x85ff, 0x0040, 0xa0f7, 0x6020, 0xa106, 0x00c0, 0xa113, 0x0d7e,
-	0x6000, 0xa086, 0x0004, 0x00c0, 0xa103, 0x1078, 0xa495, 0x601f,
-	0x0007, 0x1078, 0x1757, 0x6010, 0x2068, 0x1078, 0x8d06, 0x0040,
-	0xa10d, 0x047e, 0x1078, 0xa1ca, 0x047f, 0x0d7f, 0x1078, 0x8ec6,
-	0x88ff, 0x00c0, 0xa127, 0xace0, 0x0010, 0x2001, 0xa616, 0x2004,
-	0xac02, 0x00c8, 0xa11d, 0x0078, 0xa0c4, 0xa006, 0x127f, 0x027f,
+	0x2061, 0xae00, 0x2079, 0x0001, 0x8fff, 0x0040, 0xa12d, 0x2071,
+	0xa700, 0x7648, 0x7064, 0x8001, 0xa602, 0x00c8, 0xa12d, 0x88ff,
+	0x0040, 0xa0e8, 0x2800, 0xac06, 0x00c0, 0xa123, 0x2079, 0x0000,
+	0x1078, 0xa252, 0x0040, 0xa123, 0x2400, 0xac06, 0x0040, 0xa123,
+	0x671c, 0xa786, 0x0006, 0x00c0, 0xa123, 0xa786, 0x0007, 0x0040,
+	0xa123, 0x88ff, 0x00c0, 0xa107, 0x6018, 0xa206, 0x00c0, 0xa123,
+	0x85ff, 0x0040, 0xa107, 0x6020, 0xa106, 0x00c0, 0xa123, 0x0d7e,
+	0x6000, 0xa086, 0x0004, 0x00c0, 0xa113, 0x1078, 0xa4a5, 0x601f,
+	0x0007, 0x1078, 0x1757, 0x6010, 0x2068, 0x1078, 0x8d16, 0x0040,
+	0xa11d, 0x047e, 0x1078, 0xa1da, 0x047f, 0x0d7f, 0x1078, 0x8ed6,
+	0x88ff, 0x00c0, 0xa137, 0xace0, 0x0010, 0x2001, 0xa716, 0x2004,
+	0xac02, 0x00c8, 0xa12d, 0x0078, 0xa0d4, 0xa006, 0x127f, 0x027f,
 	0x067f, 0x077f, 0x087f, 0x0c7f, 0x0e7f, 0x0f7f, 0x007c, 0xa8c5,
-	0x0001, 0x0078, 0xa11e, 0x077e, 0x057e, 0x087e, 0x2041, 0x0000,
+	0x0001, 0x0078, 0xa12e, 0x077e, 0x057e, 0x087e, 0x2041, 0x0000,
 	0x2029, 0x0001, 0x2c20, 0x2019, 0x0002, 0x6218, 0x097e, 0x2049,
 	0x0000, 0x1078, 0x7246, 0x097f, 0x087f, 0x2039, 0x0000, 0x1078,
-	0x72f3, 0x1078, 0xa0b5, 0x057f, 0x077f, 0x007c, 0x027e, 0x047e,
+	0x72f3, 0x1078, 0xa0c5, 0x057f, 0x077f, 0x007c, 0x027e, 0x047e,
 	0x057e, 0x077e, 0x0c7e, 0x157e, 0x2c20, 0x2128, 0x20a9, 0x007f,
-	0x2009, 0x0000, 0x017e, 0x037e, 0x1078, 0x45c4, 0x00c0, 0xa16e,
+	0x2009, 0x0000, 0x017e, 0x037e, 0x1078, 0x45c4, 0x00c0, 0xa17e,
 	0x2c10, 0x057e, 0x087e, 0x2041, 0x0000, 0x2508, 0x2029, 0x0001,
 	0x097e, 0x2049, 0x0000, 0x1078, 0x7246, 0x097f, 0x087f, 0x2039,
-	0x0000, 0x1078, 0x72f3, 0x1078, 0xa0b5, 0x057f, 0x037f, 0x017f,
-	0x8108, 0x00f0, 0xa152, 0x157f, 0x0c7f, 0x077f, 0x057f, 0x047f,
+	0x0000, 0x1078, 0x72f3, 0x1078, 0xa0c5, 0x057f, 0x037f, 0x017f,
+	0x8108, 0x00f0, 0xa162, 0x157f, 0x0c7f, 0x077f, 0x057f, 0x047f,
 	0x027f, 0x007c, 0x077e, 0x057e, 0x6218, 0x087e, 0x2041, 0x0000,
 	0x2029, 0x0001, 0x2019, 0x0048, 0x097e, 0x2049, 0x0000, 0x1078,
 	0x7246, 0x097f, 0x087f, 0x2039, 0x0000, 0x1078, 0x72f3, 0x2c20,
-	0x1078, 0xa0b5, 0x057f, 0x077f, 0x007c, 0x027e, 0x047e, 0x057e,
+	0x1078, 0xa0c5, 0x057f, 0x077f, 0x007c, 0x027e, 0x047e, 0x057e,
 	0x077e, 0x0c7e, 0x157e, 0x2c20, 0x20a9, 0x007f, 0x2009, 0x0000,
-	0x017e, 0x037e, 0x1078, 0x45c4, 0x00c0, 0xa1be, 0x2c10, 0x087e,
-	0x2041, 0x0000, 0x2828, 0x047e, 0x2021, 0x0001, 0x1078, 0xa472,
+	0x017e, 0x037e, 0x1078, 0x45c4, 0x00c0, 0xa1ce, 0x2c10, 0x087e,
+	0x2041, 0x0000, 0x2828, 0x047e, 0x2021, 0x0001, 0x1078, 0xa482,
 	0x047f, 0x097e, 0x2049, 0x0000, 0x1078, 0x7246, 0x097f, 0x087f,
-	0x2039, 0x0000, 0x1078, 0x72f3, 0x1078, 0xa0b5, 0x037f, 0x017f,
-	0x8108, 0x00f0, 0xa1a0, 0x157f, 0x0c7f, 0x077f, 0x057f, 0x047f,
-	0x027f, 0x007c, 0x017e, 0x0f7e, 0xad82, 0xcd00, 0x0048, 0xa1e3,
-	0xad82, 0xffff, 0x00c8, 0xa1e3, 0x6800, 0xa07d, 0x0040, 0xa1e0,
-	0x6803, 0x0000, 0x6b52, 0x1078, 0x4a73, 0x2f68, 0x0078, 0xa1d4,
+	0x2039, 0x0000, 0x1078, 0x72f3, 0x1078, 0xa0c5, 0x037f, 0x017f,
+	0x8108, 0x00f0, 0xa1b0, 0x157f, 0x0c7f, 0x077f, 0x057f, 0x047f,
+	0x027f, 0x007c, 0x017e, 0x0f7e, 0xad82, 0xce00, 0x0048, 0xa1f3,
+	0xad82, 0xffff, 0x00c8, 0xa1f3, 0x6800, 0xa07d, 0x0040, 0xa1f0,
+	0x6803, 0x0000, 0x6b52, 0x1078, 0x4a73, 0x2f68, 0x0078, 0xa1e4,
 	0x6b52, 0x1078, 0x4a73, 0x0f7f, 0x017f, 0x007c, 0x0e7e, 0x047e,
-	0x037e, 0x2061, 0xad00, 0xa005, 0x00c0, 0xa1f6, 0x2071, 0xa600,
-	0x7448, 0x7064, 0x8001, 0xa402, 0x00c8, 0xa218, 0x2100, 0xac06,
-	0x0040, 0xa20a, 0x6000, 0xa086, 0x0000, 0x0040, 0xa20a, 0x6008,
-	0xa206, 0x00c0, 0xa20a, 0x6018, 0xa1a0, 0x0006, 0x2424, 0xa406,
-	0x0040, 0xa214, 0xace0, 0x0010, 0x2001, 0xa616, 0x2004, 0xac02,
-	0x00c8, 0xa218, 0x0078, 0xa1f6, 0xa085, 0x0001, 0x0078, 0xa219,
+	0x037e, 0x2061, 0xae00, 0xa005, 0x00c0, 0xa206, 0x2071, 0xa700,
+	0x7448, 0x7064, 0x8001, 0xa402, 0x00c8, 0xa228, 0x2100, 0xac06,
+	0x0040, 0xa21a, 0x6000, 0xa086, 0x0000, 0x0040, 0xa21a, 0x6008,
+	0xa206, 0x00c0, 0xa21a, 0x6018, 0xa1a0, 0x0006, 0x2424, 0xa406,
+	0x0040, 0xa224, 0xace0, 0x0010, 0x2001, 0xa716, 0x2004, 0xac02,
+	0x00c8, 0xa228, 0x0078, 0xa206, 0xa085, 0x0001, 0x0078, 0xa229,
 	0xa006, 0x037f, 0x047f, 0x0e7f, 0x007c, 0x0d7e, 0x007e, 0x1078,
 	0x138b, 0x007f, 0x1040, 0x1332, 0x6837, 0x010d, 0x685e, 0x027e,
-	0x2010, 0x1078, 0x8cf2, 0x2001, 0x0000, 0x0040, 0xa233, 0x2200,
+	0x2010, 0x1078, 0x8d02, 0x2001, 0x0000, 0x0040, 0xa243, 0x2200,
 	0xa080, 0x0008, 0x2004, 0x027f, 0x684a, 0x6956, 0x6c46, 0x684f,
 	0x0000, 0xa006, 0x68b2, 0x6802, 0x683a, 0x685a, 0x1078, 0x4a73,
-	0x0d7f, 0x007c, 0x6700, 0xa786, 0x0000, 0x0040, 0xa255, 0xa786,
-	0x0001, 0x0040, 0xa255, 0xa786, 0x000a, 0x0040, 0xa255, 0xa786,
-	0x0009, 0x0040, 0xa255, 0xa085, 0x0001, 0x007c, 0x0e7e, 0x6018,
+	0x0d7f, 0x007c, 0x6700, 0xa786, 0x0000, 0x0040, 0xa265, 0xa786,
+	0x0001, 0x0040, 0xa265, 0xa786, 0x000a, 0x0040, 0xa265, 0xa786,
+	0x0009, 0x0040, 0xa265, 0xa085, 0x0001, 0x007c, 0x0e7e, 0x6018,
 	0x2070, 0x70a0, 0xa206, 0x0e7f, 0x007c, 0x017e, 0x6004, 0xa08e,
-	0x001e, 0x00c0, 0xa277, 0x8007, 0x6130, 0xa18c, 0x00ff, 0xa105,
+	0x001e, 0x00c0, 0xa287, 0x8007, 0x6130, 0xa18c, 0x00ff, 0xa105,
 	0x6032, 0x6007, 0x0085, 0x6003, 0x000b, 0x601f, 0x0005, 0x2001,
-	0xa8a3, 0x2004, 0x6016, 0x1078, 0x5d8a, 0x1078, 0x62d1, 0x017f,
-	0x007c, 0x0005, 0x0005, 0x007c, 0x6024, 0xd0e4, 0x0040, 0xa28d,
-	0xd0cc, 0x0040, 0xa287, 0x1078, 0x8fbf, 0x0078, 0xa28d, 0x1078,
-	0xa495, 0x1078, 0x5bc1, 0x1078, 0x772d, 0x007c, 0xa280, 0x0007,
-	0x2004, 0xa084, 0x000f, 0x0079, 0xa295, 0xa29e, 0xa29e, 0xa29e,
-	0xa2a0, 0xa29e, 0xa2a0, 0xa2a0, 0xa29e, 0xa2a0, 0xa006, 0x007c,
+	0xa9a3, 0x2004, 0x6016, 0x1078, 0x5d8a, 0x1078, 0x62d1, 0x017f,
+	0x007c, 0x0005, 0x0005, 0x007c, 0x6024, 0xd0e4, 0x0040, 0xa29d,
+	0xd0cc, 0x0040, 0xa297, 0x1078, 0x8fcf, 0x0078, 0xa29d, 0x1078,
+	0xa4a5, 0x1078, 0x5bc1, 0x1078, 0x772d, 0x007c, 0xa280, 0x0007,
+	0x2004, 0xa084, 0x000f, 0x0079, 0xa2a5, 0xa2ae, 0xa2ae, 0xa2ae,
+	0xa2b0, 0xa2ae, 0xa2b0, 0xa2b0, 0xa2ae, 0xa2b0, 0xa006, 0x007c,
 	0xa085, 0x0001, 0x007c, 0xa280, 0x0007, 0x2004, 0xa084, 0x000f,
-	0x0079, 0xa2aa, 0xa2b3, 0xa2b3, 0xa2b3, 0xa2b3, 0xa2b3, 0xa2b3,
-	0xa2be, 0xa2b3, 0xa2b3, 0x6007, 0x003b, 0x602b, 0x0009, 0x6013,
+	0x0079, 0xa2ba, 0xa2c3, 0xa2c3, 0xa2c3, 0xa2c3, 0xa2c3, 0xa2c3,
+	0xa2ce, 0xa2c3, 0xa2c3, 0x6007, 0x003b, 0x602b, 0x0009, 0x6013,
 	0x2a00, 0x6003, 0x0001, 0x1078, 0x5d8a, 0x007c, 0x0c7e, 0x2260,
-	0x1078, 0xa495, 0x603f, 0x0000, 0x6024, 0xc0f4, 0xc0cc, 0x6026,
-	0x0c7f, 0x0d7e, 0x2268, 0xa186, 0x0007, 0x00c0, 0xa31f, 0x6810,
-	0xa005, 0x0040, 0xa2dc, 0xa080, 0x0013, 0x2004, 0xd0fc, 0x00c0,
-	0xa2dc, 0x0d7f, 0x0078, 0xa2b3, 0x6007, 0x003a, 0x6003, 0x0001,
+	0x1078, 0xa4a5, 0x603f, 0x0000, 0x6024, 0xc0f4, 0xc0cc, 0x6026,
+	0x0c7f, 0x0d7e, 0x2268, 0xa186, 0x0007, 0x00c0, 0xa32f, 0x6810,
+	0xa005, 0x0040, 0xa2ec, 0xa080, 0x0013, 0x2004, 0xd0fc, 0x00c0,
+	0xa2ec, 0x0d7f, 0x0078, 0xa2c3, 0x6007, 0x003a, 0x6003, 0x0001,
 	0x1078, 0x5d8a, 0x1078, 0x62d1, 0x0c7e, 0x2d60, 0x6100, 0xa186,
-	0x0002, 0x00c0, 0xa3ad, 0x6010, 0xa005, 0x00c0, 0xa2f6, 0x6000,
-	0xa086, 0x0007, 0x10c0, 0x1332, 0x0078, 0xa3ad, 0xa08c, 0xf000,
-	0x00c0, 0xa302, 0x0078, 0xa302, 0x2068, 0x6800, 0xa005, 0x00c0,
-	0xa2fc, 0x2d00, 0xa080, 0x0013, 0x2004, 0xa084, 0x0003, 0xa086,
-	0x0002, 0x00c0, 0xa31b, 0x6010, 0x2068, 0x684c, 0xc0dc, 0xc0f4,
+	0x0002, 0x00c0, 0xa3bd, 0x6010, 0xa005, 0x00c0, 0xa306, 0x6000,
+	0xa086, 0x0007, 0x10c0, 0x1332, 0x0078, 0xa3bd, 0xa08c, 0xf000,
+	0x00c0, 0xa312, 0x0078, 0xa312, 0x2068, 0x6800, 0xa005, 0x00c0,
+	0xa30c, 0x2d00, 0xa080, 0x0013, 0x2004, 0xa084, 0x0003, 0xa086,
+	0x0002, 0x00c0, 0xa32b, 0x6010, 0x2068, 0x684c, 0xc0dc, 0xc0f4,
 	0x684e, 0x6850, 0xc0f4, 0xc0fc, 0x6852, 0x2009, 0x0043, 0x1078,
-	0x9c1e, 0x0078, 0xa3ad, 0x2009, 0x0041, 0x0078, 0xa3a7, 0xa186,
-	0x0005, 0x00c0, 0xa366, 0x6810, 0xa080, 0x0013, 0x2004, 0xd0bc,
-	0x00c0, 0xa32d, 0x0d7f, 0x0078, 0xa2b3, 0xd0b4, 0x0040, 0xa335,
-	0xd0fc, 0x1040, 0x1332, 0x0078, 0xa2cf, 0x6007, 0x003a, 0x6003,
+	0x9c2e, 0x0078, 0xa3bd, 0x2009, 0x0041, 0x0078, 0xa3b7, 0xa186,
+	0x0005, 0x00c0, 0xa376, 0x6810, 0xa080, 0x0013, 0x2004, 0xd0bc,
+	0x00c0, 0xa33d, 0x0d7f, 0x0078, 0xa2c3, 0xd0b4, 0x0040, 0xa345,
+	0xd0fc, 0x1040, 0x1332, 0x0078, 0xa2df, 0x6007, 0x003a, 0x6003,
 	0x0001, 0x1078, 0x5d8a, 0x1078, 0x62d1, 0x0c7e, 0x2d60, 0x6100,
-	0xa186, 0x0002, 0x0040, 0xa348, 0xa186, 0x0004, 0x00c0, 0xa3ad,
-	0x2071, 0xa8e7, 0x7000, 0xa086, 0x0003, 0x00c0, 0xa355, 0x7004,
-	0xac06, 0x00c0, 0xa355, 0x7003, 0x0000, 0x6810, 0xa080, 0x0013,
+	0xa186, 0x0002, 0x0040, 0xa358, 0xa186, 0x0004, 0x00c0, 0xa3bd,
+	0x2071, 0xa9e7, 0x7000, 0xa086, 0x0003, 0x00c0, 0xa365, 0x7004,
+	0xac06, 0x00c0, 0xa365, 0x7003, 0x0000, 0x6810, 0xa080, 0x0013,
 	0x200c, 0xc1f4, 0xc1dc, 0x2102, 0x8000, 0x200c, 0xc1f4, 0xc1fc,
-	0xc1bc, 0x2102, 0x2009, 0x0042, 0x0078, 0xa3a7, 0x037e, 0x0d7e,
+	0xc1bc, 0x2102, 0x2009, 0x0042, 0x0078, 0xa3b7, 0x037e, 0x0d7e,
 	0x0d7e, 0x1078, 0x138b, 0x037f, 0x1040, 0x1332, 0x6837, 0x010d,
 	0x6803, 0x0000, 0x683b, 0x0000, 0x685b, 0x0000, 0x6b5e, 0x6857,
 	0x0045, 0x2c00, 0x6862, 0x6034, 0x6872, 0x2360, 0x6024, 0xc0dd,
 	0x6026, 0x6018, 0xa080, 0x0028, 0x2004, 0xa084, 0x00ff, 0x8007,
 	0x6320, 0x6b4a, 0x6846, 0x684f, 0x0000, 0x6d6a, 0x6e66, 0x686f,
 	0x0001, 0x1078, 0x4a73, 0x2019, 0x0045, 0x6008, 0x2068, 0x1078,
-	0x9dc7, 0x2d00, 0x600a, 0x601f, 0x0006, 0x6003, 0x0007, 0x6017,
-	0x0000, 0x603f, 0x0000, 0x0d7f, 0x037f, 0x0078, 0xa3ae, 0x603f,
-	0x0000, 0x6003, 0x0007, 0x1078, 0x9c1e, 0x0c7f, 0x0d7f, 0x007c,
-	0xa186, 0x0013, 0x00c0, 0xa3ba, 0x6004, 0xa082, 0x0085, 0x2008,
-	0x0079, 0xa3d4, 0xa186, 0x0027, 0x00c0, 0xa3cd, 0x1078, 0x61cd,
-	0x037e, 0x0d7e, 0x6010, 0x2068, 0x2019, 0x0004, 0x1078, 0xa1ca,
+	0x9dd7, 0x2d00, 0x600a, 0x601f, 0x0006, 0x6003, 0x0007, 0x6017,
+	0x0000, 0x603f, 0x0000, 0x0d7f, 0x037f, 0x0078, 0xa3be, 0x603f,
+	0x0000, 0x6003, 0x0007, 0x1078, 0x9c2e, 0x0c7f, 0x0d7f, 0x007c,
+	0xa186, 0x0013, 0x00c0, 0xa3ca, 0x6004, 0xa082, 0x0085, 0x2008,
+	0x0079, 0xa3e4, 0xa186, 0x0027, 0x00c0, 0xa3dd, 0x1078, 0x61cd,
+	0x037e, 0x0d7e, 0x6010, 0x2068, 0x2019, 0x0004, 0x1078, 0xa1da,
 	0x0d7f, 0x037f, 0x1078, 0x62d1, 0x007c, 0xa186, 0x0014, 0x0040,
-	0xa3be, 0x1078, 0x7773, 0x007c, 0xa3dd, 0xa3db, 0xa3db, 0xa3db,
-	0xa3db, 0xa3db, 0xa3dd, 0x1078, 0x1332, 0x1078, 0x61cd, 0x6003,
-	0x000c, 0x1078, 0x62d1, 0x007c, 0xa182, 0x008c, 0x00c8, 0xa3ee,
-	0xa182, 0x0085, 0x0048, 0xa3ee, 0x0079, 0xa3f1, 0x1078, 0x7773,
-	0x007c, 0xa3f8, 0xa3f8, 0xa3f8, 0xa3f8, 0xa3fa, 0xa419, 0xa3f8,
-	0x1078, 0x1332, 0x0d7e, 0x2c68, 0x1078, 0x76c7, 0x0040, 0xa414,
-	0x6003, 0x0001, 0x6007, 0x001e, 0x2009, 0xab8e, 0x210c, 0x6136,
-	0x2009, 0xab8f, 0x210c, 0x613a, 0x600b, 0xffff, 0x6918, 0x611a,
+	0xa3ce, 0x1078, 0x7773, 0x007c, 0xa3ed, 0xa3eb, 0xa3eb, 0xa3eb,
+	0xa3eb, 0xa3eb, 0xa3ed, 0x1078, 0x1332, 0x1078, 0x61cd, 0x6003,
+	0x000c, 0x1078, 0x62d1, 0x007c, 0xa182, 0x008c, 0x00c8, 0xa3fe,
+	0xa182, 0x0085, 0x0048, 0xa3fe, 0x0079, 0xa401, 0x1078, 0x7773,
+	0x007c, 0xa408, 0xa408, 0xa408, 0xa408, 0xa40a, 0xa429, 0xa408,
+	0x1078, 0x1332, 0x0d7e, 0x2c68, 0x1078, 0x76c7, 0x0040, 0xa424,
+	0x6003, 0x0001, 0x6007, 0x001e, 0x2009, 0xac8e, 0x210c, 0x6136,
+	0x2009, 0xac8f, 0x210c, 0x613a, 0x600b, 0xffff, 0x6918, 0x611a,
 	0x601f, 0x0004, 0x1078, 0x5d8a, 0x2d60, 0x1078, 0x772d, 0x0d7f,
 	0x007c, 0x1078, 0x772d, 0x007c, 0x0e7e, 0x6018, 0x2070, 0x7000,
-	0xd0ec, 0x0e7f, 0x007c, 0x6010, 0xa08c, 0xf000, 0x0040, 0xa471,
-	0xa080, 0x0013, 0x200c, 0xd1ec, 0x0040, 0xa471, 0x2001, 0xa672,
-	0x2004, 0xd0ec, 0x0040, 0xa471, 0x6003, 0x0002, 0x6024, 0xc0e5,
-	0x6026, 0xd1ac, 0x0040, 0xa44f, 0x0f7e, 0x2c78, 0x1078, 0x495f,
-	0x0f7f, 0x0040, 0xa44f, 0x2001, 0xa8a4, 0x2004, 0x603e, 0x2009,
-	0xa672, 0x210c, 0xd1f4, 0x00c0, 0xa46f, 0x0078, 0xa461, 0x2009,
-	0xa672, 0x210c, 0xd1f4, 0x0040, 0xa45b, 0x6024, 0xc0e4, 0x6026,
-	0xa006, 0x0078, 0xa471, 0x2001, 0xa8a4, 0x200c, 0x8103, 0xa100,
-	0x603e, 0x6018, 0xa088, 0x002b, 0x2104, 0xa005, 0x0040, 0xa46c,
-	0xa088, 0x0003, 0x0078, 0xa464, 0x2c0a, 0x600f, 0x0000, 0xa085,
+	0xd0ec, 0x0e7f, 0x007c, 0x6010, 0xa08c, 0xf000, 0x0040, 0xa481,
+	0xa080, 0x0013, 0x200c, 0xd1ec, 0x0040, 0xa481, 0x2001, 0xa772,
+	0x2004, 0xd0ec, 0x0040, 0xa481, 0x6003, 0x0002, 0x6024, 0xc0e5,
+	0x6026, 0xd1ac, 0x0040, 0xa45f, 0x0f7e, 0x2c78, 0x1078, 0x495f,
+	0x0f7f, 0x0040, 0xa45f, 0x2001, 0xa9a4, 0x2004, 0x603e, 0x2009,
+	0xa772, 0x210c, 0xd1f4, 0x00c0, 0xa47f, 0x0078, 0xa471, 0x2009,
+	0xa772, 0x210c, 0xd1f4, 0x0040, 0xa46b, 0x6024, 0xc0e4, 0x6026,
+	0xa006, 0x0078, 0xa481, 0x2001, 0xa9a4, 0x200c, 0x8103, 0xa100,
+	0x603e, 0x6018, 0xa088, 0x002b, 0x2104, 0xa005, 0x0040, 0xa47c,
+	0xa088, 0x0003, 0x0078, 0xa474, 0x2c0a, 0x600f, 0x0000, 0xa085,
 	0x0001, 0x007c, 0x017e, 0x0c7e, 0x0e7e, 0x6120, 0xa2f0, 0x002b,
-	0x2e04, 0x2060, 0x8cff, 0x0040, 0xa491, 0x84ff, 0x00c0, 0xa484,
-	0x6020, 0xa106, 0x00c0, 0xa48c, 0x600c, 0x2072, 0x1078, 0x5bc1,
-	0x1078, 0x772d, 0x0078, 0xa48e, 0xacf0, 0x0003, 0x2e64, 0x0078,
-	0xa47a, 0x0e7f, 0x0c7f, 0x017f, 0x007c, 0x0d7e, 0x6018, 0xa0e8,
-	0x002b, 0x2d04, 0xa005, 0x0040, 0xa4a7, 0xac06, 0x0040, 0xa4a5,
-	0x2d04, 0xa0e8, 0x0003, 0x0078, 0xa499, 0x600c, 0x206a, 0x0d7f,
-	0x007c, 0x027e, 0x037e, 0x157e, 0x2011, 0xa626, 0x2204, 0xa084,
-	0x00ff, 0x2019, 0xab8e, 0x2334, 0xa636, 0x00c0, 0xa4d5, 0x8318,
-	0x2334, 0x2204, 0xa084, 0xff00, 0xa636, 0x00c0, 0xa4d5, 0x2011,
-	0xab90, 0x6018, 0xa098, 0x000a, 0x20a9, 0x0004, 0x1078, 0x80de,
-	0x00c0, 0xa4d5, 0x2011, 0xab94, 0x6018, 0xa098, 0x0006, 0x20a9,
-	0x0004, 0x1078, 0x80de, 0x00c0, 0xa4d5, 0x157f, 0x037f, 0x027f,
-	0x007c, 0x0e7e, 0x2071, 0xa600, 0x1078, 0x42b8, 0x1078, 0x2677,
+	0x2e04, 0x2060, 0x8cff, 0x0040, 0xa4a1, 0x84ff, 0x00c0, 0xa494,
+	0x6020, 0xa106, 0x00c0, 0xa49c, 0x600c, 0x2072, 0x1078, 0x5bc1,
+	0x1078, 0x772d, 0x0078, 0xa49e, 0xacf0, 0x0003, 0x2e64, 0x0078,
+	0xa48a, 0x0e7f, 0x0c7f, 0x017f, 0x007c, 0x0d7e, 0x6018, 0xa0e8,
+	0x002b, 0x2d04, 0xa005, 0x0040, 0xa4b7, 0xac06, 0x0040, 0xa4b5,
+	0x2d04, 0xa0e8, 0x0003, 0x0078, 0xa4a9, 0x600c, 0x206a, 0x0d7f,
+	0x007c, 0x027e, 0x037e, 0x157e, 0x2011, 0xa726, 0x2204, 0xa084,
+	0x00ff, 0x2019, 0xac8e, 0x2334, 0xa636, 0x00c0, 0xa4e5, 0x8318,
+	0x2334, 0x2204, 0xa084, 0xff00, 0xa636, 0x00c0, 0xa4e5, 0x2011,
+	0xac90, 0x6018, 0xa098, 0x000a, 0x20a9, 0x0004, 0x1078, 0x80de,
+	0x00c0, 0xa4e5, 0x2011, 0xac94, 0x6018, 0xa098, 0x0006, 0x20a9,
+	0x0004, 0x1078, 0x80de, 0x00c0, 0xa4e5, 0x157f, 0x037f, 0x027f,
+	0x007c, 0x0e7e, 0x2071, 0xa700, 0x1078, 0x42b8, 0x1078, 0x2677,
 	0x0e7f, 0x007c, 0x0e7e, 0x6018, 0x2070, 0x7000, 0xd0fc, 0x0040,
-	0xa4eb, 0x1078, 0xa4ed, 0x0e7f, 0x007c, 0x6850, 0xc0e5, 0x6852,
+	0xa4fb, 0x1078, 0xa4fd, 0x0e7f, 0x007c, 0x6850, 0xc0e5, 0x6852,
 	0x007c, 0x0e7e, 0x0c7e, 0x077e, 0x067e, 0x057e, 0x047e, 0x027e,
-	0x017e, 0x127e, 0x2091, 0x8000, 0x2029, 0xa8ba, 0x252c, 0x2021,
-	0xa8c0, 0x2424, 0x2061, 0xad00, 0x2071, 0xa600, 0x7648, 0x7064,
-	0xa606, 0x0040, 0xa545, 0x671c, 0xa786, 0x0001, 0x0040, 0xa514,
-	0xa786, 0x0008, 0x00c0, 0xa53b, 0x2500, 0xac06, 0x0040, 0xa53b,
-	0x2400, 0xac06, 0x0040, 0xa53b, 0x1078, 0xa242, 0x0040, 0xa53b,
-	0x1078, 0xa256, 0x00c0, 0xa53b, 0x6000, 0xa086, 0x0004, 0x00c0,
-	0xa52d, 0x017e, 0x1078, 0x1757, 0x017f, 0x1078, 0x8eec, 0x00c0,
-	0xa533, 0x1078, 0x28a6, 0x1078, 0x8f00, 0x00c0, 0xa539, 0x1078,
-	0x7c83, 0x1078, 0x8ec6, 0xace0, 0x0010, 0x2001, 0xa616, 0x2004,
-	0xac02, 0x00c8, 0xa545, 0x0078, 0xa504, 0x127f, 0x017f, 0x027f,
+	0x017e, 0x127e, 0x2091, 0x8000, 0x2029, 0xa9ba, 0x252c, 0x2021,
+	0xa9c0, 0x2424, 0x2061, 0xae00, 0x2071, 0xa700, 0x7648, 0x7064,
+	0xa606, 0x0040, 0xa555, 0x671c, 0xa786, 0x0001, 0x0040, 0xa524,
+	0xa786, 0x0008, 0x00c0, 0xa54b, 0x2500, 0xac06, 0x0040, 0xa54b,
+	0x2400, 0xac06, 0x0040, 0xa54b, 0x1078, 0xa252, 0x0040, 0xa54b,
+	0x1078, 0xa266, 0x00c0, 0xa54b, 0x6000, 0xa086, 0x0004, 0x00c0,
+	0xa53d, 0x017e, 0x1078, 0x1757, 0x017f, 0x1078, 0x8efc, 0x00c0,
+	0xa543, 0x1078, 0x28a6, 0x1078, 0x8f10, 0x00c0, 0xa549, 0x1078,
+	0x7c83, 0x1078, 0x8ed6, 0xace0, 0x0010, 0x2001, 0xa716, 0x2004,
+	0xac02, 0x00c8, 0xa555, 0x0078, 0xa514, 0x127f, 0x017f, 0x027f,
 	0x047f, 0x057f, 0x067f, 0x077f, 0x0c7f, 0x0e7f, 0x007c, 0x127e,
-	0x007e, 0x0e7e, 0x017e, 0x2091, 0x8000, 0x2071, 0xa640, 0xd5a4,
-	0x0040, 0xa55d, 0x7034, 0x8000, 0x7036, 0xd5b4, 0x0040, 0xa563,
-	0x7030, 0x8000, 0x7032, 0xd5ac, 0x0040, 0xa579, 0x2500, 0xa084,
-	0x0007, 0xa08e, 0x0003, 0x0040, 0xa579, 0xa08e, 0x0004, 0x0040,
-	0xa579, 0xa08e, 0x0005, 0x0040, 0xa579, 0x2071, 0xa64a, 0x1078,
-	0xa5ba, 0x017f, 0x0e7f, 0x007f, 0x127f, 0x007c, 0x127e, 0x007e,
-	0x0e7e, 0x017e, 0x2091, 0x8000, 0x2071, 0xa640, 0xd5a4, 0x0040,
-	0xa58c, 0x7034, 0x8000, 0x7036, 0xd5b4, 0x0040, 0xa592, 0x7030,
-	0x8000, 0x7032, 0xd5ac, 0x0040, 0xa5a8, 0x2500, 0xa084, 0x0007,
-	0xa08e, 0x0003, 0x0040, 0xa5a8, 0xa08e, 0x0004, 0x0040, 0xa5a8,
-	0xa08e, 0x0005, 0x0040, 0xa5a8, 0x2071, 0xa64a, 0x1078, 0xa5ba,
+	0x007e, 0x0e7e, 0x017e, 0x2091, 0x8000, 0x2071, 0xa740, 0xd5a4,
+	0x0040, 0xa56d, 0x7034, 0x8000, 0x7036, 0xd5b4, 0x0040, 0xa573,
+	0x7030, 0x8000, 0x7032, 0xd5ac, 0x0040, 0xa589, 0x2500, 0xa084,
+	0x0007, 0xa08e, 0x0003, 0x0040, 0xa589, 0xa08e, 0x0004, 0x0040,
+	0xa589, 0xa08e, 0x0005, 0x0040, 0xa589, 0x2071, 0xa74a, 0x1078,
+	0xa5ca, 0x017f, 0x0e7f, 0x007f, 0x127f, 0x007c, 0x127e, 0x007e,
+	0x0e7e, 0x017e, 0x2091, 0x8000, 0x2071, 0xa740, 0xd5a4, 0x0040,
+	0xa59c, 0x7034, 0x8000, 0x7036, 0xd5b4, 0x0040, 0xa5a2, 0x7030,
+	0x8000, 0x7032, 0xd5ac, 0x0040, 0xa5b8, 0x2500, 0xa084, 0x0007,
+	0xa08e, 0x0003, 0x0040, 0xa5b8, 0xa08e, 0x0004, 0x0040, 0xa5b8,
+	0xa08e, 0x0005, 0x0040, 0xa5b8, 0x2071, 0xa74a, 0x1078, 0xa5ca,
 	0x017f, 0x0e7f, 0x007f, 0x127f, 0x007c, 0x127e, 0x007e, 0x0e7e,
-	0x2091, 0x8000, 0x2071, 0xa642, 0x1078, 0xa5ba, 0x0e7f, 0x007f,
-	0x127f, 0x007c, 0x2e04, 0x8000, 0x2072, 0x00c8, 0xa5c3, 0x8e70,
-	0x2e04, 0x8000, 0x2072, 0x007c, 0x0e7e, 0x2071, 0xa640, 0x1078,
-	0xa5ba, 0x0e7f, 0x007c, 0x0e7e, 0x2071, 0xa644, 0x1078, 0xa5ba,
+	0x2091, 0x8000, 0x2071, 0xa742, 0x1078, 0xa5ca, 0x0e7f, 0x007f,
+	0x127f, 0x007c, 0x2e04, 0x8000, 0x2072, 0x00c8, 0xa5d3, 0x8e70,
+	0x2e04, 0x8000, 0x2072, 0x007c, 0x0e7e, 0x2071, 0xa740, 0x1078,
+	0xa5ca, 0x0e7f, 0x007c, 0x0e7e, 0x2071, 0xa744, 0x1078, 0xa5ca,
 	0x0e7f, 0x007c, 0x127e, 0x007e, 0x0e7e, 0x2091, 0x8000, 0x2071,
-	0xa640, 0x7044, 0x8000, 0x7046, 0x0e7f, 0x007f, 0x127f, 0x007c,
+	0xa740, 0x7044, 0x8000, 0x7046, 0x0e7f, 0x007f, 0x127f, 0x007c,
 	0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
 	0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000,
-	0xa50c
+	0x4811
 };
 #ifdef UNIQUE_FW_NAME
-unsigned short fw2100tp_length01 = 0x95f1;
+unsigned short fw2100tp_length01 = 0x9601;
 #else
-unsigned short risc_code_length01 = 0x95f1;
+unsigned short risc_code_length01 = 0x9601;
 #endif
 
diff --git a/drivers/scsi/qla2xxx/ql2200.c b/drivers/scsi/qla2xxx/ql2200.c
--- a/drivers/scsi/qla2xxx/ql2200.c
+++ b/drivers/scsi/qla2xxx/ql2200.c
@@ -1,7 +1,7 @@
 /*
  * QLogic ISP2200 device driver for Linux 2.6.x
  * Copyright (C) 2003 Christoph Hellwig.
- * Copyright (C) 2003-2004 QLogic Corporation (www.qlogic.com)
+ * Copyright (C) 2003-2005 QLogic Corporation (www.qlogic.com)
  *
  * Released under GPL v2.
  */
diff --git a/drivers/scsi/qla2xxx/ql2200_fw.c b/drivers/scsi/qla2xxx/ql2200_fw.c
--- a/drivers/scsi/qla2xxx/ql2200_fw.c
+++ b/drivers/scsi/qla2xxx/ql2200_fw.c
@@ -2,7 +2,7 @@
  *                  QLOGIC LINUX SOFTWARE
  *
  * QLogic ISP2x00 device driver for Linux 2.6.x
- * Copyright (C) 2003-2004 QLogic Corporation
+ * Copyright (C) 2003-2005 QLogic Corporation
  * (www.qlogic.com)
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -18,7 +18,7 @@
  *************************************************************************/
 
 /*
- *	Firmware Version 2.02.06 (08:46 Jun 26, 2003)
+ *	Firmware Version 2.02.08 (17:06 Mar 22, 2005)
  */
 
 #ifdef UNIQUE_FW_NAME
@@ -28,15 +28,15 @@ unsigned short risc_code_version = 2*102
 #endif
 
 #ifdef UNIQUE_FW_NAME
-unsigned char fw2200tp_version_str[] = {2,2,6};
+unsigned char fw2200tp_version_str[] = {2,2,8};
 #else
-unsigned char firmware_version[] = {2,2,6};
+unsigned char firmware_version[] = {2,2,8};
 #endif
 
 #ifdef UNIQUE_FW_NAME
-#define fw2200tp_VERSION_STRING "2.02.06"
+#define fw2200tp_VERSION_STRING "2.02.08"
 #else
-#define FW_VERSION_STRING "2.02.06"
+#define FW_VERSION_STRING "2.02.08"
 #endif
 
 #ifdef UNIQUE_FW_NAME
@@ -50,5272 +50,5296 @@ unsigned short fw2200tp_code01[] = { 
 #else
 unsigned short risc_code01[] = { 
 #endif
-	0x0470, 0x0000, 0x0000, 0xa46f, 0x0000, 0x0002, 0x0002, 0x0006,
+	0x0470, 0x0000, 0x0000, 0xa52b, 0x0000, 0x0002, 0x0002, 0x0008,
 	0x0017, 0x2043, 0x4f50, 0x5952, 0x4947, 0x4854, 0x2032, 0x3030,
 	0x3120, 0x514c, 0x4f47, 0x4943, 0x2043, 0x4f52, 0x504f, 0x5241,
 	0x5449, 0x4f4e, 0x2049, 0x5350, 0x3232, 0x3030, 0x2046, 0x6972,
 	0x6d77, 0x6172, 0x6520, 0x2056, 0x6572, 0x7369, 0x6f6e, 0x2030,
-	0x322e, 0x3032, 0x2e30, 0x3620, 0x2020, 0x2020, 0x2400, 0x20c1,
-	0x0005, 0x2001, 0x017f, 0x2003, 0x0000, 0x20c9, 0xbaff, 0x2091,
-	0x2000, 0x2059, 0x0000, 0x2b78, 0x7823, 0x0004, 0x2089, 0x296a,
-	0x2051, 0xb500, 0x2a70, 0x2029, 0xed00, 0x2031, 0xffff, 0x2039,
-	0xece9, 0x2021, 0x0200, 0x0804, 0x1468, 0x20a1, 0xb46f, 0xa00e,
-	0x20a9, 0x0891, 0x41a4, 0x3400, 0x7562, 0x7666, 0x775e, 0x746a,
-	0x746e, 0x20a1, 0xbd00, 0x7164, 0x810d, 0x810d, 0x810d, 0x810d,
+	0x322e, 0x3032, 0x2e30, 0x3820, 0x2020, 0x2020, 0x2400, 0x20c1,
+	0x0005, 0x2001, 0x017f, 0x2003, 0x0000, 0x20c9, 0xbbff, 0x2091,
+	0x2000, 0x2059, 0x0000, 0x2b78, 0x7823, 0x0004, 0x2089, 0x299f,
+	0x2051, 0xb600, 0x2a70, 0x2029, 0xee00, 0x2031, 0xffff, 0x2039,
+	0xede9, 0x2021, 0x0200, 0x0804, 0x146d, 0x20a1, 0xb52b, 0xa00e,
+	0x20a9, 0x08d5, 0x41a4, 0x3400, 0x7562, 0x7666, 0x775e, 0x746a,
+	0x746e, 0x20a1, 0xbe00, 0x7164, 0x810d, 0x810d, 0x810d, 0x810d,
 	0xa18c, 0x000f, 0x2001, 0x000b, 0xa112, 0xa00e, 0x21a8, 0x41a4,
 	0x3400, 0x8211, 0x1dd8, 0x7164, 0x3400, 0xa102, 0x0120, 0x0218,
-	0x20a8, 0xa00e, 0x41a4, 0x3800, 0xd08c, 0x01d8, 0x2009, 0xb500,
+	0x20a8, 0xa00e, 0x41a4, 0x3800, 0xd08c, 0x01d8, 0x2009, 0xb600,
 	0x810d, 0x810d, 0x810d, 0x810d, 0xa18c, 0x000f, 0x2001, 0x0001,
 	0xa112, 0x20a1, 0x1000, 0xa00e, 0x21a8, 0x41a4, 0x8211, 0x1de0,
-	0x2009, 0xb500, 0x3400, 0xa102, 0x0120, 0x0218, 0x20a8, 0xa00e,
-	0x41a4, 0x080c, 0x1411, 0x080c, 0x1632, 0x080c, 0x17cf, 0x080c,
-	0x1fa2, 0x080c, 0x4bff, 0x080c, 0x85bf, 0x080c, 0x15bb, 0x080c,
-	0x2ec4, 0x080c, 0x5d8a, 0x080c, 0x5341, 0x080c, 0x68ce, 0x080c,
-	0x2510, 0x080c, 0x6b61, 0x080c, 0x63bb, 0x080c, 0x23ca, 0x080c,
-	0x24de, 0x2091, 0x3009, 0x7823, 0x0000, 0x1004, 0x10c5, 0x7820,
+	0x2009, 0xb600, 0x3400, 0xa102, 0x0120, 0x0218, 0x20a8, 0xa00e,
+	0x41a4, 0x080c, 0x1416, 0x080c, 0x1637, 0x080c, 0x17d4, 0x080c,
+	0x1fbe, 0x080c, 0x4c72, 0x080c, 0x8646, 0x080c, 0x15c0, 0x080c,
+	0x2ef9, 0x080c, 0x5dfc, 0x080c, 0x53b3, 0x080c, 0x6940, 0x080c,
+	0x2545, 0x080c, 0x6bd3, 0x080c, 0x642d, 0x080c, 0x23ff, 0x080c,
+	0x2513, 0x2091, 0x3009, 0x7823, 0x0000, 0x1004, 0x10c5, 0x7820,
 	0xa086, 0x0002, 0x1150, 0x7823, 0x4000, 0x0e04, 0x10bd, 0x781b,
 	0x0001, 0x2091, 0x5000, 0x2091, 0x4080, 0x2a70, 0x7003, 0x0000,
-	0x2a70, 0x7000, 0xa08e, 0x0003, 0x1158, 0x080c, 0x3f08, 0x080c,
-	0x2eeb, 0x080c, 0x5dd8, 0x080c, 0x54f0, 0x080c, 0x68f9, 0x0c80,
-	0x000b, 0x0c98, 0x10e4, 0x10e5, 0x1210, 0x10e2, 0x12dd, 0x140e,
-	0x140f, 0x1410, 0x080c, 0x1515, 0x0005, 0x0126, 0x00f6, 0x2091,
-	0x8000, 0x7000, 0xa086, 0x0001, 0x1904, 0x11ed, 0x080c, 0x1588,
-	0x080c, 0x5acf, 0x0150, 0x080c, 0x5af5, 0x15c0, 0x2079, 0x0100,
-	0x7828, 0xa085, 0x1800, 0x782a, 0x0488, 0x080c, 0x5a07, 0x7000,
-	0xa086, 0x0001, 0x1904, 0x11ed, 0x708c, 0xa086, 0x0028, 0x1904,
-	0x11ed, 0x2001, 0x0161, 0x2003, 0x0001, 0x2079, 0x0100, 0x7827,
-	0xffff, 0x7a28, 0xa295, 0x1e2f, 0x7a2a, 0x2011, 0x59a2, 0x080c,
-	0x699c, 0x2011, 0x5995, 0x080c, 0x6a5c, 0x2011, 0x59e4, 0x080c,
-	0x699c, 0x2011, 0x4adc, 0x080c, 0x699c, 0x2011, 0x8030, 0x2019,
-	0x0000, 0x708b, 0x0000, 0x080c, 0x1de9, 0x00e8, 0x080c, 0x448f,
-	0x2079, 0x0100, 0x7844, 0xa005, 0x1904, 0x11ed, 0x2011, 0x4adc,
-	0x080c, 0x699c, 0x2011, 0x59e4, 0x080c, 0x699c, 0x080c, 0x1de9,
-	0x2001, 0xb78d, 0x2004, 0x780e, 0x7840, 0xa084, 0xfffb, 0x7842,
-	0x2011, 0x8010, 0x73cc, 0x080c, 0x3ecc, 0x723c, 0xc284, 0x723e,
-	0x2001, 0xb50c, 0x200c, 0xc1ac, 0x2102, 0x080c, 0x7f35, 0x2011,
-	0x0004, 0x080c, 0x9c60, 0x080c, 0x524d, 0x080c, 0x5acf, 0x0158,
-	0x080c, 0x4be8, 0x0140, 0x708b, 0x0001, 0x70c7, 0x0000, 0x080c,
-	0x462c, 0x0804, 0x11ed, 0x080c, 0x5309, 0x0120, 0x7a0c, 0xc2b4,
-	0x7a0e, 0x0060, 0x7073, 0x0000, 0x080c, 0xa008, 0x70d4, 0xd09c,
-	0x1128, 0x70a0, 0xa005, 0x0110, 0x080c, 0x4bc6, 0x70df, 0x0000,
-	0x70db, 0x0000, 0x72d4, 0x080c, 0x5acf, 0x1178, 0x2011, 0x0000,
-	0x0016, 0x080c, 0x28eb, 0x2019, 0xb78f, 0x211a, 0x001e, 0x7053,
-	0xffff, 0x7057, 0x00ef, 0x7077, 0x0000, 0x2079, 0xb552, 0x7804,
-	0xd0ac, 0x0108, 0xc295, 0x72d6, 0x080c, 0x5acf, 0x0118, 0xa296,
-	0x0004, 0x0548, 0x2011, 0x0001, 0x080c, 0x9c60, 0x709b, 0x0000,
-	0x709f, 0xffff, 0x7003, 0x0002, 0x2079, 0x0100, 0x7827, 0x0003,
-	0x7828, 0xa085, 0x0003, 0x782a, 0x00fe, 0x080c, 0x2ab8, 0x2011,
-	0x0005, 0x080c, 0x8075, 0x080c, 0x7173, 0x080c, 0x5acf, 0x0148,
-	0x00c6, 0x2061, 0x0100, 0x0016, 0x080c, 0x28eb, 0x61e2, 0x001e,
-	0x00ce, 0x012e, 0x0420, 0x709b, 0x0000, 0x709f, 0xffff, 0x7003,
-	0x0002, 0x00f6, 0x2079, 0x0100, 0x7827, 0x0003, 0x7828, 0xa085,
-	0x0003, 0x782a, 0x00fe, 0x2011, 0x0005, 0x080c, 0x8075, 0x080c,
-	0x7173, 0x080c, 0x5acf, 0x0148, 0x00c6, 0x2061, 0x0100, 0x0016,
-	0x080c, 0x28eb, 0x61e2, 0x001e, 0x00ce, 0x00fe, 0x012e, 0x0005,
-	0x00c6, 0x080c, 0x5acf, 0x1118, 0x20a9, 0x0100, 0x0010, 0x20a9,
-	0x0082, 0x080c, 0x5acf, 0x1118, 0x2009, 0x0000, 0x0010, 0x2009,
-	0x007e, 0x080c, 0x2d97, 0x8108, 0x1f04, 0x1201, 0x00ce, 0x7073,
-	0x0000, 0x7074, 0xa084, 0x00ff, 0x7076, 0x70a3, 0x0000, 0x0005,
-	0x0126, 0x2091, 0x8000, 0x7000, 0xa086, 0x0002, 0x1904, 0x12db,
-	0x709c, 0xa086, 0xffff, 0x0130, 0x080c, 0x2ab8, 0x080c, 0x7173,
-	0x0804, 0x12db, 0x70d4, 0xd0ac, 0x1110, 0xd09c, 0x0540, 0xd084,
-	0x0530, 0x0006, 0x0016, 0x2001, 0x0103, 0x2009, 0xb78d, 0x210c,
-	0x2102, 0x001e, 0x000e, 0xd08c, 0x01d0, 0x70d8, 0xa086, 0xffff,
-	0x0190, 0x080c, 0x2c17, 0x080c, 0x7173, 0x70d4, 0xd094, 0x1904,
-	0x12db, 0x2011, 0x0001, 0x2019, 0x0000, 0x080c, 0x2c4f, 0x080c,
-	0x7173, 0x0804, 0x12db, 0x70dc, 0xa005, 0x1904, 0x12db, 0x7098,
-	0xa005, 0x1904, 0x12db, 0x70d4, 0xd0a4, 0x0118, 0xd0b4, 0x0904,
-	0x12db, 0x080c, 0x5309, 0x1904, 0x12db, 0x2001, 0xb553, 0x2004,
-	0xd0ac, 0x01c8, 0x0156, 0x00c6, 0x20a9, 0x007f, 0x2009, 0x0000,
-	0x0016, 0x080c, 0x4fa9, 0x1118, 0x6000, 0xd0ec, 0x1138, 0x001e,
-	0x8108, 0x1f04, 0x1268, 0x00ce, 0x015e, 0x0028, 0x001e, 0x00ce,
-	0x015e, 0x0804, 0x12db, 0x0006, 0x0016, 0x2001, 0x0103, 0x2009,
-	0xb78d, 0x210c, 0x2102, 0x001e, 0x000e, 0x71a8, 0x81ff, 0x11b0,
-	0xa006, 0x2009, 0x0200, 0x20a9, 0x0002, 0x20a1, 0xb7de, 0x40a1,
-	0x2009, 0x0700, 0x20a9, 0x0002, 0x20a1, 0xb7ce, 0x40a1, 0x7070,
-	0x8007, 0x7174, 0x810f, 0x20a9, 0x0002, 0x40a1, 0x20a1, 0xb7d2,
-	0x2009, 0x0000, 0x080c, 0x14fb, 0x2001, 0x0000, 0x810f, 0x20a9,
-	0x0002, 0x40a1, 0x7030, 0xc08c, 0x7032, 0x7003, 0x0003, 0x709f,
-	0xffff, 0x080c, 0x1581, 0xa006, 0x080c, 0x27c3, 0x080c, 0x3f3e,
-	0x00f6, 0x2079, 0x0100, 0x080c, 0x5af5, 0x0150, 0x080c, 0x5acf,
-	0x7828, 0x0118, 0xa084, 0xe1ff, 0x0010, 0xa084, 0xffdf, 0x782a,
-	0x00fe, 0x2001, 0xb7e1, 0x2004, 0xa086, 0x0005, 0x1120, 0x2011,
-	0x0000, 0x080c, 0x8075, 0x2011, 0x0000, 0x080c, 0x807f, 0x080c,
-	0x7173, 0x080c, 0x7230, 0x012e, 0x0005, 0x0016, 0x0046, 0x00f6,
-	0x0126, 0x2091, 0x8000, 0x2079, 0x0100, 0x2009, 0xb534, 0x2104,
-	0xa005, 0x1110, 0x080c, 0x2917, 0x2009, 0x00f7, 0x080c, 0x4baf,
-	0x7940, 0xa18c, 0x0010, 0x7942, 0x7924, 0xd1b4, 0x0110, 0x7827,
-	0x0040, 0xd19c, 0x0110, 0x7827, 0x0008, 0x0006, 0x0036, 0x0156,
-	0x7954, 0xd1ac, 0x1904, 0x134b, 0x080c, 0x5ae1, 0x0158, 0x080c,
-	0x5af5, 0x1128, 0x2001, 0xb79e, 0x2003, 0x0000, 0x0070, 0x080c,
-	0x5ad7, 0x0dc0, 0x2001, 0xb79e, 0x2003, 0xaaaa, 0x2001, 0xb79f,
-	0x2003, 0x0001, 0x080c, 0x5a07, 0x0058, 0x080c, 0x5acf, 0x0140,
-	0x2009, 0x00f8, 0x080c, 0x4baf, 0x7843, 0x0090, 0x7843, 0x0010,
-	0x20a9, 0x09c4, 0x7820, 0xd09c, 0x1138, 0x080c, 0x5acf, 0x0138,
-	0x7824, 0xd0ac, 0x1904, 0x13f5, 0x1f04, 0x132a, 0x0070, 0x7824,
-	0x080c, 0x5aeb, 0x0118, 0xd0ac, 0x1904, 0x13f5, 0xa084, 0x1800,
-	0x0d98, 0x7003, 0x0001, 0x0804, 0x13f5, 0x2001, 0x0001, 0x080c,
-	0x27c3, 0x0804, 0x1404, 0x7850, 0xa084, 0x0180, 0x7852, 0x782f,
-	0x0020, 0x20a9, 0x0046, 0x1d04, 0x1353, 0x080c, 0x6a44, 0x1f04,
-	0x1353, 0x7850, 0xa084, 0x0180, 0xa085, 0x0400, 0x7852, 0x782f,
-	0x0000, 0x080c, 0x5ae1, 0x0158, 0x080c, 0x5af5, 0x1128, 0x2001,
-	0xb79e, 0x2003, 0x0000, 0x0070, 0x080c, 0x5ad7, 0x0dc0, 0x2001,
-	0xb79e, 0x2003, 0xaaaa, 0x2001, 0xb79f, 0x2003, 0x0001, 0x080c,
-	0x5a07, 0x0020, 0x2009, 0x00f8, 0x080c, 0x4baf, 0x20a9, 0x000e,
-	0xe000, 0x1f04, 0x1380, 0x7850, 0xa084, 0x0180, 0xa085, 0x1400,
-	0x7852, 0x080c, 0x5acf, 0x0120, 0x7843, 0x0090, 0x7843, 0x0010,
-	0x2021, 0xe678, 0x2019, 0xea60, 0x7820, 0xd09c, 0x1558, 0x080c,
-	0x5acf, 0x05d8, 0x7824, 0xd0ac, 0x1904, 0x13f5, 0x080c, 0x5af5,
-	0x1508, 0x0046, 0x2021, 0x0190, 0x8421, 0x1df0, 0x004e, 0x8421,
-	0x11c8, 0x7827, 0x0048, 0x20a9, 0x01f4, 0x1d04, 0x13ad, 0x080c,
-	0x6a44, 0x1f04, 0x13ad, 0x7824, 0xa084, 0x0068, 0x15c8, 0x2001,
-	0xb79e, 0x2003, 0xaaaa, 0x2001, 0xb79f, 0x2003, 0x0001, 0x7003,
-	0x0001, 0x0498, 0x1d04, 0x13c6, 0x080c, 0x6a44, 0x8319, 0x1960,
-	0x2009, 0xb534, 0x2104, 0x8000, 0x200a, 0xa084, 0xfff0, 0x0120,
-	0x200b, 0x0000, 0x080c, 0x2917, 0x00d8, 0x080c, 0x5ae1, 0x1140,
-	0xa4a2, 0x0064, 0x1128, 0x080c, 0x5aa6, 0x7003, 0x0001, 0x00a8,
-	0x7827, 0x1800, 0xe000, 0xe000, 0x7824, 0x080c, 0x5aeb, 0x0110,
-	0xd0ac, 0x1158, 0xa084, 0x1800, 0x09a8, 0x7003, 0x0001, 0x0028,
-	0x2001, 0x0001, 0x080c, 0x27c3, 0x0048, 0x2001, 0xb534, 0x2003,
-	0x0000, 0x7827, 0x0048, 0x7828, 0xc09d, 0x782a, 0x7850, 0xa084,
-	0x0180, 0xa085, 0x0400, 0x7852, 0x015e, 0x003e, 0x000e, 0x080c,
-	0x1558, 0x012e, 0x00fe, 0x004e, 0x001e, 0x0005, 0x0005, 0x0005,
-	0x0005, 0x2a70, 0x2061, 0xb7c1, 0x2063, 0x0002, 0x6007, 0x0002,
-	0x600b, 0x0006, 0x600f, 0x0017, 0x2001, 0xb79e, 0x2003, 0x0000,
-	0x708b, 0x0000, 0x2009, 0x0100, 0x2104, 0xa082, 0x0002, 0x0218,
-	0x7053, 0xffff, 0x0010, 0x7053, 0x0000, 0x705b, 0xffff, 0x7073,
-	0x0000, 0x7077, 0x0000, 0x080c, 0xa008, 0x2061, 0xb78e, 0x6003,
-	0x0909, 0x6007, 0x0000, 0x600b, 0x8800, 0x600f, 0x0200, 0x6013,
-	0x00ff, 0x6017, 0x000f, 0x601b, 0x0000, 0x601f, 0x07d0, 0x2061,
-	0xb796, 0x6003, 0x8000, 0x6007, 0x0000, 0x600b, 0x0000, 0x600f,
-	0x0200, 0x6013, 0x00ff, 0x6017, 0x0000, 0x601b, 0x0001, 0x601f,
-	0x0000, 0x2061, 0xb7b9, 0x6003, 0x514c, 0x6007, 0x4f47, 0x600b,
-	0x4943, 0x600f, 0x2020, 0x2001, 0xb528, 0x2003, 0x0000, 0x0005,
-	0x04a0, 0x2011, 0x0000, 0x81ff, 0x0570, 0xa186, 0x0001, 0x1148,
-	0x2031, 0x8fff, 0x2039, 0xd501, 0x2021, 0x0100, 0x2029, 0xd500,
-	0x00e8, 0xa186, 0x0002, 0x1118, 0x2011, 0x0000, 0x00b8, 0xa186,
-	0x0005, 0x1118, 0x2011, 0x0001, 0x0088, 0xa186, 0x0009, 0x1118,
-	0x2011, 0x0002, 0x0058, 0xa186, 0x000a, 0x1118, 0x2011, 0x0002,
-	0x0028, 0xa186, 0x0055, 0x1110, 0x2011, 0x0003, 0x3800, 0xa084,
-	0xfffc, 0xa205, 0x20c0, 0x0804, 0x104d, 0xa00e, 0x2011, 0x0003,
-	0x2019, 0x14a4, 0x0804, 0x14f5, 0x2019, 0xaaaa, 0x2061, 0xffff,
-	0x2c14, 0x2362, 0xe000, 0xe000, 0x2c04, 0xa306, 0x2262, 0x1110,
-	0xc1b5, 0xc1a5, 0x2011, 0x0000, 0x2019, 0x14b7, 0x04f0, 0x2019,
-	0xaaaa, 0x2061, 0xffff, 0x2c14, 0x2362, 0xe000, 0xe000, 0x2c1c,
-	0x2061, 0x7fff, 0xe000, 0xe000, 0x2c04, 0x2061, 0xffff, 0x2262,
-	0xa306, 0x0110, 0xc18d, 0x0008, 0xc185, 0x2011, 0x0002, 0x2019,
-	0x14d2, 0x0418, 0x2061, 0xffff, 0x2019, 0xaaaa, 0x2c14, 0x2362,
-	0xe000, 0xe000, 0x2c04, 0x2262, 0xa306, 0x1180, 0x2c14, 0x2362,
-	0xe000, 0xe000, 0x2c1c, 0x2061, 0x7fff, 0x2c04, 0x2061, 0xffff,
-	0x2262, 0xa306, 0x1110, 0xc195, 0x0008, 0xc19d, 0x2011, 0x0001,
-	0x2019, 0x14f3, 0x0010, 0x0804, 0x1469, 0x3800, 0xa084, 0xfffc,
-	0xa205, 0x20c0, 0x0837, 0x2011, 0x0000, 0x080c, 0x4fa9, 0x1178,
-	0x6004, 0xa0c4, 0x00ff, 0xa8c6, 0x0006, 0x0128, 0xa0c4, 0xff00,
-	0xa8c6, 0x0600, 0x1120, 0xa186, 0x0080, 0x0108, 0x8210, 0x8108,
-	0xa186, 0x0100, 0x1d50, 0x2208, 0x0005, 0x2091, 0x8000, 0x0e04,
-	0x1517, 0x0006, 0x0016, 0x2079, 0x0000, 0x7818, 0xd084, 0x1de8,
-	0x001e, 0x792e, 0x000e, 0x782a, 0x000e, 0x7826, 0x3900, 0x783a,
-	0x7823, 0x8002, 0x781b, 0x0001, 0x2091, 0x5000, 0x0126, 0x0156,
-	0x0146, 0x20a9, 0x0010, 0x20a1, 0xb90c, 0x2091, 0x2000, 0x40a1,
-	0x20a9, 0x0010, 0x2091, 0x2200, 0x40a1, 0x20a9, 0x0010, 0x2091,
-	0x2400, 0x40a1, 0x20a9, 0x0010, 0x2091, 0x2600, 0x40a1, 0x20a9,
-	0x0010, 0x2091, 0x2800, 0x40a1, 0x014e, 0x015e, 0x012e, 0x2079,
-	0xb500, 0x7803, 0x0005, 0x2091, 0x4080, 0x04c9, 0x0cf8, 0x0005,
-	0x0006, 0x080c, 0x15a3, 0x1518, 0x00f6, 0x2079, 0xb524, 0x2f04,
-	0x8000, 0x207a, 0xa082, 0x000f, 0x0258, 0xa006, 0x207a, 0x2079,
-	0xb526, 0x2f04, 0xa084, 0x0001, 0xa086, 0x0001, 0x207a, 0x0070,
-	0x2079, 0xb526, 0x2f7c, 0x8fff, 0x1128, 0x2001, 0x0c03, 0x2003,
-	0x0040, 0x0020, 0x2001, 0x0c03, 0x2003, 0x00c0, 0x00fe, 0x000e,
-	0x0005, 0x0409, 0x1120, 0x2001, 0x0c03, 0x2003, 0x0080, 0x0005,
-	0x00d1, 0x1120, 0x2001, 0x0c03, 0x2003, 0x0040, 0x0005, 0x0006,
-	0x0091, 0x1178, 0x2001, 0x0c03, 0x2003, 0x0040, 0x2009, 0x0fff,
-	0x00a1, 0x2001, 0x0c03, 0x2003, 0x0080, 0x2009, 0x0fff, 0x0069,
-	0x0c88, 0x000e, 0x0005, 0x00c6, 0x2061, 0x0c00, 0x2c04, 0xa084,
-	0x00ff, 0xa086, 0x00aa, 0x00ce, 0x0005, 0x0156, 0x0126, 0xa18c,
-	0x0fff, 0x21a8, 0x1d04, 0x15b2, 0x2091, 0x6000, 0x1f04, 0x15b2,
-	0x012e, 0x015e, 0x0005, 0x2071, 0xb500, 0x7160, 0x712e, 0x2021,
-	0x0001, 0xa190, 0x0030, 0xa298, 0x0030, 0x0240, 0x7064, 0xa302,
-	0x1228, 0x220a, 0x2208, 0x2310, 0x8420, 0x0ca8, 0x3800, 0xd08c,
-	0x0148, 0x7064, 0xa086, 0xb500, 0x0128, 0x7067, 0xb500, 0x2011,
-	0x1000, 0x0c48, 0x200b, 0x0000, 0x74b2, 0x74b6, 0x0005, 0x00e6,
-	0x0126, 0x2091, 0x8000, 0x2071, 0xb500, 0x70b4, 0xa0ea, 0x0010,
-	0x0268, 0x8001, 0x70b6, 0x702c, 0x2068, 0x2d04, 0x702e, 0x206b,
-	0x0000, 0x6807, 0x0000, 0x012e, 0x00ee, 0x0005, 0xa06e, 0x0cd8,
-	0x00e6, 0x2071, 0xb500, 0x0126, 0x2091, 0x8000, 0x70b4, 0x8001,
-	0x0260, 0x70b6, 0x702c, 0x2068, 0x2d04, 0x702e, 0x206b, 0x0000,
-	0x6807, 0x0000, 0x012e, 0x00ee, 0x0005, 0xa06e, 0x0cd8, 0x00e6,
-	0x0126, 0x2091, 0x8000, 0x2071, 0xb500, 0x702c, 0x206a, 0x2d00,
-	0x702e, 0x70b4, 0x8000, 0x70b6, 0x012e, 0x00ee, 0x0005, 0x8dff,
-	0x0138, 0x6804, 0x6807, 0x0000, 0x0006, 0x0c49, 0x00de, 0x0cb8,
-	0x0005, 0x00e6, 0x2071, 0xb500, 0x70b4, 0xa08a, 0x0010, 0xa00d,
-	0x00ee, 0x0005, 0x00e6, 0x2071, 0xb812, 0x7007, 0x0000, 0x701b,
-	0x0000, 0x701f, 0x0000, 0x2071, 0x0000, 0x7010, 0xa085, 0x8004,
-	0x7012, 0x00ee, 0x0005, 0x0126, 0x2091, 0x8000, 0x00e6, 0x2270,
-	0x700b, 0x0000, 0x2071, 0xb812, 0x7018, 0xa088, 0xb81b, 0x220a,
-	0x8000, 0xa084, 0x0007, 0x701a, 0x7004, 0xa005, 0x1128, 0x00f6,
-	0x2079, 0x0010, 0x0089, 0x00fe, 0x00ee, 0x012e, 0x0005, 0x00e6,
-	0x2071, 0xb812, 0x7004, 0xa005, 0x1128, 0x00f6, 0x2079, 0x0010,
-	0x0019, 0x00fe, 0x00ee, 0x0005, 0x7000, 0x0002, 0x1672, 0x16d6,
-	0x16f3, 0x16f3, 0x7018, 0x711c, 0xa106, 0x1118, 0x7007, 0x0000,
-	0x0005, 0x00d6, 0xa180, 0xb81b, 0x2004, 0x700a, 0x2068, 0x8108,
-	0xa18c, 0x0007, 0x711e, 0x7803, 0x0026, 0x6824, 0x7832, 0x6828,
-	0x7836, 0x682c, 0x783a, 0x6830, 0x783e, 0x6810, 0x700e, 0x680c,
-	0x7016, 0x6804, 0x00de, 0xd084, 0x0120, 0x7007, 0x0001, 0x0029,
-	0x0005, 0x7007, 0x0002, 0x00b1, 0x0005, 0x0016, 0x0026, 0x710c,
-	0x2011, 0x0040, 0xa182, 0x0040, 0x1210, 0x2110, 0xa006, 0x700e,
-	0x7212, 0x8203, 0x7822, 0x7803, 0x0020, 0x7803, 0x0041, 0x002e,
-	0x001e, 0x0005, 0x0016, 0x0026, 0x0136, 0x0146, 0x0156, 0x7014,
-	0x2098, 0x20a1, 0x0014, 0x7803, 0x0026, 0x710c, 0x2011, 0x0040,
-	0xa182, 0x0040, 0x1210, 0x2110, 0xa006, 0x700e, 0x22a8, 0x53a6,
-	0x8203, 0x7822, 0x7803, 0x0020, 0x3300, 0x7016, 0x7803, 0x0001,
-	0x015e, 0x014e, 0x013e, 0x002e, 0x001e, 0x0005, 0x0136, 0x0146,
-	0x0156, 0x2099, 0xb5fa, 0x20a1, 0x0018, 0x20a9, 0x0008, 0x53a3,
-	0x7803, 0x0020, 0x0126, 0x2091, 0x8000, 0x7803, 0x0041, 0x7007,
-	0x0003, 0x7000, 0xc084, 0x7002, 0x700b, 0xb5f5, 0x012e, 0x015e,
-	0x014e, 0x013e, 0x0005, 0x0136, 0x0146, 0x0156, 0x2001, 0xb629,
-	0x209c, 0x20a1, 0x0014, 0x7803, 0x0026, 0x2001, 0xb62a, 0x20ac,
-	0x53a6, 0x2099, 0xb62b, 0x20a1, 0x0018, 0x20a9, 0x0008, 0x53a3,
-	0x7803, 0x0020, 0x0126, 0x2091, 0x8000, 0x7803, 0x0001, 0x7007,
-	0x0004, 0x7000, 0xc08c, 0x7002, 0x700b, 0xb626, 0x012e, 0x015e,
-	0x014e, 0x013e, 0x0005, 0x0016, 0x00e6, 0x2071, 0xb812, 0x00f6,
-	0x2079, 0x0010, 0x7904, 0x7803, 0x0002, 0xd1fc, 0x0120, 0xa18c,
-	0x0700, 0x7004, 0x0023, 0x00fe, 0x00ee, 0x001e, 0x0005, 0x166c,
-	0x1736, 0x1764, 0x178e, 0x17be, 0x1735, 0x0cf8, 0xa18c, 0x0700,
-	0x1528, 0x0136, 0x0146, 0x0156, 0x7014, 0x20a0, 0x2099, 0x0014,
-	0x7803, 0x0040, 0x7010, 0x20a8, 0x53a5, 0x3400, 0x7016, 0x015e,
-	0x014e, 0x013e, 0x700c, 0xa005, 0x0570, 0x7830, 0x7832, 0x7834,
-	0x7836, 0x080c, 0x169d, 0x0005, 0x7008, 0xa080, 0x0002, 0x2003,
-	0x0100, 0x7007, 0x0000, 0x080c, 0x166c, 0x0005, 0x7008, 0xa080,
-	0x0002, 0x2003, 0x0200, 0x0ca8, 0xa18c, 0x0700, 0x1150, 0x700c,
-	0xa005, 0x0188, 0x7830, 0x7832, 0x7834, 0x7836, 0x080c, 0x16b2,
-	0x0005, 0x7008, 0xa080, 0x0002, 0x2003, 0x0200, 0x7007, 0x0000,
-	0x080c, 0x166c, 0x0005, 0x00d6, 0x7008, 0x2068, 0x7830, 0x6826,
-	0x7834, 0x682a, 0x7838, 0x682e, 0x783c, 0x6832, 0x680b, 0x0100,
-	0x00de, 0x7007, 0x0000, 0x080c, 0x166c, 0x0005, 0xa18c, 0x0700,
-	0x1540, 0x0136, 0x0146, 0x0156, 0x2001, 0xb5f8, 0x2004, 0xa080,
-	0x000d, 0x20a0, 0x2099, 0x0014, 0x7803, 0x0040, 0x20a9, 0x0020,
-	0x53a5, 0x2001, 0xb5fa, 0x2004, 0xd0bc, 0x0148, 0x2001, 0xb603,
-	0x2004, 0xa080, 0x000d, 0x20a0, 0x20a9, 0x0020, 0x53a5, 0x015e,
-	0x014e, 0x013e, 0x7007, 0x0000, 0x080c, 0x5e6f, 0x080c, 0x166c,
-	0x0005, 0x2011, 0x8003, 0x080c, 0x3ecc, 0x0cf8, 0xa18c, 0x0700,
-	0x1148, 0x2001, 0xb628, 0x2003, 0x0100, 0x7007, 0x0000, 0x080c,
-	0x166c, 0x0005, 0x2011, 0x8004, 0x080c, 0x3ecc, 0x0cf8, 0x0126,
-	0x2091, 0x2200, 0x2079, 0x0030, 0x2071, 0xb823, 0x7003, 0x0000,
-	0x700f, 0xb82f, 0x7013, 0xb82f, 0x780f, 0x00f6, 0x7803, 0x0004,
-	0x012e, 0x0005, 0x6934, 0xa184, 0x0007, 0x0002, 0x17ee, 0x182c,
-	0x17ee, 0x17ee, 0x17ee, 0x1814, 0x17fb, 0x17f2, 0xa085, 0x0001,
-	0x0804, 0x1846, 0x684c, 0xd0bc, 0x0dc8, 0x6860, 0x682e, 0x685c,
-	0x682a, 0x6858, 0x04c8, 0xa18c, 0x00ff, 0xa186, 0x001e, 0x1d70,
-	0x684c, 0xd0bc, 0x0d58, 0x6860, 0x682e, 0x685c, 0x682a, 0x6804,
-	0x681a, 0xa080, 0x000d, 0x2004, 0xa084, 0x000f, 0xa080, 0x22e5,
-	0x2005, 0x6832, 0x6858, 0x0440, 0xa18c, 0x00ff, 0xa186, 0x0015,
-	0x19a8, 0x684c, 0xd0ac, 0x0990, 0x6804, 0x681a, 0xa080, 0x000d,
-	0x2004, 0xa084, 0x000f, 0xa080, 0x22e5, 0x2005, 0x6832, 0xa006,
-	0x682e, 0x682a, 0x6858, 0x0080, 0x684c, 0xd0ac, 0x0904, 0x17ee,
-	0xa006, 0x682e, 0x682a, 0x6858, 0xa18c, 0x000f, 0xa188, 0x22e5,
-	0x210d, 0x6932, 0x2d08, 0x691a, 0x6826, 0x684c, 0xc0dd, 0x684e,
-	0xa006, 0x680a, 0x697c, 0x6912, 0x6980, 0x6916, 0x0005, 0x684c,
-	0xd0ac, 0x090c, 0x1515, 0x6833, 0x22e2, 0x2d08, 0x691a, 0x6858,
-	0x8001, 0x6826, 0x684c, 0xc0dd, 0x684e, 0xa006, 0x680a, 0x682e,
-	0x682a, 0x697c, 0x6912, 0x6980, 0x6916, 0x0005, 0x20e1, 0x0007,
-	0x20e1, 0x2000, 0x2001, 0x020a, 0x2004, 0x82ff, 0x01e8, 0xa280,
-	0x0004, 0x00d6, 0x206c, 0x684c, 0xd0dc, 0x1190, 0xa280, 0x0007,
-	0x2004, 0xa086, 0x000a, 0x1110, 0x0891, 0x0010, 0x080c, 0x17e2,
-	0x0138, 0x00de, 0xa280, 0x0000, 0x2003, 0x0002, 0xa016, 0x0020,
-	0x6808, 0x8000, 0x680a, 0x00de, 0x0126, 0x0046, 0x0036, 0x0026,
-	0x2091, 0x2200, 0x002e, 0x003e, 0x004e, 0x7000, 0xa005, 0x01d0,
-	0x710c, 0x220a, 0x8108, 0x230a, 0x8108, 0x240a, 0x8108, 0xa182,
-	0xb84a, 0x0210, 0x2009, 0xb82f, 0x710e, 0x7010, 0xa102, 0xa082,
-	0x0009, 0x0118, 0xa080, 0x001b, 0x1118, 0x2009, 0x0138, 0x200a,
-	0x012e, 0x0005, 0x7206, 0x2001, 0x18a8, 0x0006, 0x2260, 0x0804,
-	0x19d5, 0x0126, 0x0026, 0x0036, 0x00c6, 0x0006, 0x2091, 0x2200,
-	0x000e, 0x004e, 0x003e, 0x002e, 0x00d6, 0x00c6, 0x2460, 0x6110,
-	0x2168, 0x6a62, 0x6b5e, 0xa005, 0x0904, 0x190a, 0x6808, 0xa005,
-	0x0904, 0x1941, 0x7000, 0xa005, 0x1108, 0x0488, 0x700c, 0x7110,
-	0xa106, 0x1904, 0x1949, 0x7004, 0xa406, 0x1548, 0x2001, 0x0005,
-	0x2004, 0xd08c, 0x0168, 0x0046, 0x080c, 0x1b06, 0x004e, 0x2460,
-	0x6010, 0xa080, 0x0002, 0x2004, 0xa005, 0x0904, 0x1941, 0x0c10,
-	0x2001, 0x0207, 0x2004, 0xd09c, 0x1d48, 0x7804, 0xa084, 0x6000,
-	0x0120, 0xa086, 0x6000, 0x0108, 0x0c08, 0x7818, 0x6812, 0x781c,
-	0x6816, 0x7803, 0x0004, 0x7003, 0x0000, 0x7004, 0x2060, 0x6100,
-	0xa18e, 0x0004, 0x1904, 0x1949, 0x2009, 0x0048, 0x080c, 0x864c,
-	0x0804, 0x1949, 0x6808, 0xa005, 0x05a0, 0x7000, 0xa005, 0x0588,
-	0x700c, 0x7110, 0xa106, 0x1118, 0x7004, 0xa406, 0x1550, 0x2001,
-	0x0005, 0x2004, 0xd08c, 0x0160, 0x0046, 0x080c, 0x1b06, 0x004e,
-	0x2460, 0x6010, 0xa080, 0x0002, 0x2004, 0xa005, 0x01d0, 0x0c28,
-	0x2001, 0x0207, 0x2004, 0xd09c, 0x1d50, 0x2001, 0x0005, 0x2004,
-	0xd08c, 0x1d50, 0x7804, 0xa084, 0x6000, 0x0118, 0xa086, 0x6000,
-	0x19f0, 0x7818, 0x6812, 0x781c, 0x6816, 0x7803, 0x0004, 0x7003,
-	0x0000, 0x6100, 0xa18e, 0x0004, 0x1120, 0x2009, 0x0048, 0x080c,
-	0x864c, 0x00ce, 0x00de, 0x012e, 0x0005, 0x00f6, 0x00e6, 0x0026,
-	0x0036, 0x0046, 0x0056, 0x2071, 0xb823, 0x7000, 0xa086, 0x0000,
-	0x0904, 0x19b3, 0x7004, 0xac06, 0x1904, 0x19a5, 0x2079, 0x0030,
-	0x7000, 0xa086, 0x0003, 0x0904, 0x19a5, 0x7804, 0xd0fc, 0x15c8,
-	0x20e1, 0x6000, 0x2011, 0x0032, 0x2001, 0x0208, 0x200c, 0x2001,
-	0x0209, 0x2004, 0xa106, 0x1d88, 0x8211, 0x1db0, 0x7804, 0xd0fc,
-	0x1540, 0x080c, 0x1e6e, 0x0026, 0x0056, 0x7803, 0x0004, 0x7804,
-	0xd0ac, 0x1de8, 0x7803, 0x0002, 0x7803, 0x0009, 0x7003, 0x0003,
-	0x7007, 0x0000, 0x005e, 0x002e, 0x2001, 0x015d, 0x2003, 0x0000,
-	0x080c, 0x5acf, 0x1138, 0x0066, 0x2031, 0x0001, 0x080c, 0x5b51,
-	0x006e, 0x0058, 0x2001, 0x0160, 0x2502, 0x2001, 0x0138, 0x2202,
-	0x0020, 0x080c, 0x1b06, 0x0804, 0x1955, 0x0156, 0x20a9, 0x0009,
-	0x2009, 0xb82f, 0x2104, 0xac06, 0x1108, 0x200a, 0xa188, 0x0003,
-	0x1f04, 0x19aa, 0x015e, 0x005e, 0x004e, 0x003e, 0x002e, 0x00ee,
-	0x00fe, 0x0005, 0x700c, 0x7110, 0xa106, 0x0904, 0x1a49, 0x2104,
-	0x7006, 0x2060, 0x8108, 0x211c, 0x8108, 0x2124, 0x8108, 0xa182,
-	0xb84a, 0x0210, 0x2009, 0xb82f, 0x7112, 0x700c, 0xa106, 0x1128,
-	0x080c, 0x28eb, 0x2001, 0x0138, 0x2102, 0x8cff, 0x0598, 0x6010,
-	0x2068, 0x2d58, 0x6828, 0xa406, 0x1590, 0x682c, 0xa306, 0x1578,
-	0x7004, 0x2060, 0x6020, 0xc0d4, 0x6022, 0x684c, 0xd0f4, 0x0128,
-	0x6817, 0xffff, 0x6813, 0xffff, 0x00e8, 0x6850, 0xd0f4, 0x1130,
-	0x7803, 0x0004, 0x6810, 0x781a, 0x6814, 0x781e, 0x6824, 0x2050,
-	0x6818, 0x2060, 0x6830, 0x2040, 0x6034, 0xa0cc, 0x000f, 0x2009,
-	0x0011, 0x080c, 0x1a4c, 0x0120, 0x2009, 0x0001, 0x080c, 0x1a4c,
-	0x2d58, 0x0005, 0x080c, 0x1ddd, 0x0904, 0x19ba, 0x0cd0, 0x6020,
-	0xd0f4, 0x11e0, 0xd0d4, 0x01b8, 0x6038, 0xa402, 0x6034, 0xa303,
-	0x0108, 0x1288, 0x643a, 0x6336, 0x6c2a, 0x6b2e, 0x0046, 0x0036,
-	0x2400, 0x6c7c, 0xa402, 0x6812, 0x2300, 0x6b80, 0xa303, 0x6816,
-	0x003e, 0x004e, 0x0018, 0x080c, 0x9f9a, 0x09e0, 0x601c, 0xa08e,
-	0x0008, 0x0904, 0x19e0, 0xa08e, 0x000a, 0x0904, 0x19e0, 0x2001,
-	0xb574, 0x2004, 0xd0b4, 0x1140, 0x6018, 0x2004, 0xd0bc, 0x1120,
-	0x6817, 0x7fff, 0x6813, 0xffff, 0x080c, 0x2305, 0x1918, 0x0804,
-	0x19e0, 0x7003, 0x0000, 0x0005, 0x8aff, 0x0904, 0x1ae0, 0xa03e,
-	0x2730, 0xc9fc, 0x6850, 0xd0fc, 0x11b8, 0xd0f4, 0x1528, 0x00d6,
-	0x2805, 0xac68, 0x2900, 0x0002, 0x1a9e, 0x1a82, 0x1a82, 0x1a9e,
-	0x1a9e, 0x1a96, 0x1a9e, 0x1a82, 0x1a9e, 0x1a87, 0x1a87, 0x1a9e,
-	0x1a9e, 0x1a9e, 0x1a8e, 0x1a87, 0x7803, 0x0004, 0xc0fc, 0x6852,
-	0x6b6c, 0x6a70, 0x6d1c, 0x6c20, 0x00d6, 0xd99c, 0x0550, 0x2805,
-	0xac68, 0x6f08, 0x6e0c, 0x0430, 0xc0f4, 0x6852, 0x6b6c, 0x6a70,
-	0x00d6, 0x0468, 0x6b08, 0x6a0c, 0x6d00, 0x6c04, 0x00d0, 0x6b10,
-	0x6a14, 0x6d00, 0x6c04, 0x6f08, 0x6e0c, 0x00a0, 0x00de, 0x00d6,
-	0x6834, 0xa084, 0x00ff, 0xa086, 0x001e, 0x1140, 0x00de, 0x080c,
-	0x22a7, 0x1904, 0x1a4c, 0xa00e, 0x0804, 0x1ae0, 0x00de, 0x080c,
-	0x1515, 0xc9fd, 0x7b22, 0x7a26, 0x7d32, 0x7c36, 0x7f3a, 0x7e3e,
-	0x7316, 0x721a, 0x751e, 0x7422, 0x7726, 0x762a, 0x7902, 0x7100,
-	0x8108, 0x7102, 0x00de, 0x6828, 0xa300, 0x682a, 0x682c, 0xa201,
-	0x682e, 0x8109, 0x2d08, 0x1500, 0xd9fc, 0x0160, 0xc9fc, 0x080c,
-	0x22a7, 0x01e8, 0x2805, 0xac68, 0x6800, 0xa506, 0x11c0, 0x6804,
-	0xa406, 0x00a8, 0xc9fc, 0x080c, 0x22a7, 0x0188, 0x2805, 0xac68,
-	0x6800, 0xa506, 0x1160, 0x6804, 0xa406, 0x1148, 0x6808, 0xa706,
-	0x1130, 0x680c, 0xa606, 0x0018, 0xc9fc, 0x080c, 0x22a7, 0x2168,
-	0x0005, 0x080c, 0x1515, 0x080c, 0x1f55, 0x7004, 0x2060, 0x00d6,
-	0x6010, 0x2068, 0x7003, 0x0000, 0x080c, 0x1dfe, 0x080c, 0x9c5a,
-	0x0170, 0x6808, 0x8001, 0x680a, 0x697c, 0x6912, 0x6980, 0x6916,
-	0x682b, 0xffff, 0x682f, 0xffff, 0x6850, 0xc0bd, 0x6852, 0x00de,
-	0x080c, 0x992a, 0x0804, 0x1d2b, 0x080c, 0x1515, 0x0126, 0x2091,
-	0x2200, 0x0006, 0x0016, 0x2b68, 0x6818, 0x2060, 0x7904, 0x7803,
-	0x0002, 0xa184, 0x0700, 0x1978, 0xa184, 0x0003, 0xa086, 0x0003,
-	0x0d58, 0x7000, 0x0002, 0x1b23, 0x1b29, 0x1c3a, 0x1d06, 0x1d1a,
-	0x1b23, 0x1b23, 0x1b23, 0x7804, 0xd09c, 0x1904, 0x1d2b, 0x080c,
-	0x1515, 0x8001, 0x7002, 0xd1bc, 0x11a0, 0xd19c, 0x1904, 0x1bbe,
-	0xd1dc, 0x1178, 0x8aff, 0x0904, 0x1bbe, 0x2009, 0x0001, 0x080c,
-	0x1a4c, 0x0904, 0x1d2b, 0x2009, 0x0001, 0x080c, 0x1a4c, 0x0804,
-	0x1d2b, 0x7803, 0x0004, 0x7003, 0x0000, 0xd1bc, 0x1904, 0x1b9e,
-	0x0026, 0x0036, 0x7c20, 0x7d24, 0x7e30, 0x7f34, 0x7818, 0x6812,
-	0x781c, 0x6816, 0x2001, 0x0201, 0x2004, 0xa005, 0x0140, 0x7808,
-	0xd0ec, 0x1128, 0x7803, 0x0009, 0x7003, 0x0004, 0x0010, 0x080c,
-	0x1d2f, 0x6b28, 0x6a2c, 0x2400, 0x686e, 0xa31a, 0x2500, 0x6872,
-	0xa213, 0x6b2a, 0x6a2e, 0x00c6, 0x7004, 0x2060, 0x6020, 0xd0f4,
-	0x1110, 0x633a, 0x6236, 0x00ce, 0x003e, 0x002e, 0x6e1e, 0x6f22,
-	0x2500, 0xa405, 0x0128, 0x080c, 0x22bd, 0x6850, 0xc0fd, 0x6852,
-	0x2a00, 0x6826, 0x2c00, 0x681a, 0x2800, 0x6832, 0x6808, 0x8001,
-	0x680a, 0x1148, 0x684c, 0xd0e4, 0x0130, 0x7004, 0x2060, 0x2009,
-	0x0048, 0x080c, 0x864c, 0x7000, 0xa086, 0x0004, 0x0904, 0x1d2b,
-	0x7003, 0x0000, 0x080c, 0x19ba, 0x0804, 0x1d2b, 0x0056, 0x7d0c,
-	0xd5bc, 0x1110, 0x080c, 0xb407, 0x005e, 0x080c, 0x1dfe, 0x00f6,
-	0x7004, 0x2078, 0x080c, 0x5305, 0x0118, 0x7820, 0xc0f5, 0x7822,
-	0x00fe, 0x682b, 0xffff, 0x682f, 0xffff, 0x6808, 0x8001, 0x680a,
-	0x697c, 0x791a, 0x6980, 0x791e, 0x0804, 0x1d2b, 0x7004, 0x00c6,
-	0x2060, 0x6020, 0x00ce, 0xd0f4, 0x0120, 0x6808, 0x8001, 0x680a,
-	0x04c0, 0x7818, 0x6812, 0x7a1c, 0x6a16, 0xd19c, 0x0160, 0xa205,
-	0x0150, 0x7004, 0xa080, 0x0007, 0x2004, 0xa084, 0xfffd, 0xa086,
-	0x0008, 0x1904, 0x1b41, 0x684c, 0xc0f5, 0x684e, 0x7814, 0xa005,
-	0x1520, 0x7003, 0x0000, 0x6808, 0x8001, 0x680a, 0x01a0, 0x7004,
-	0x2060, 0x601c, 0xa086, 0x000a, 0x11a0, 0x0156, 0x20a9, 0x0009,
-	0x2009, 0xb82f, 0x2104, 0xac06, 0x1108, 0x200a, 0xa188, 0x0003,
-	0x1f04, 0x1bf2, 0x015e, 0x7004, 0x2060, 0x2009, 0x0048, 0x080c,
-	0x864c, 0x080c, 0x19ba, 0x0804, 0x1d2b, 0x7818, 0x6812, 0x781c,
-	0x6816, 0x7814, 0x7908, 0xa18c, 0x0fff, 0xa192, 0x0841, 0x1a04,
-	0x1ae3, 0xa188, 0x0007, 0x8114, 0x8214, 0x8214, 0xa10a, 0x8104,
-	0x8004, 0x8004, 0xa20a, 0x810b, 0x810b, 0x810b, 0x080c, 0x1e99,
-	0x7803, 0x0004, 0x780f, 0xffff, 0x7803, 0x0001, 0x7804, 0xd0fc,
-	0x0de8, 0x7803, 0x0002, 0x7803, 0x0004, 0x780f, 0x00f6, 0x7004,
-	0x7007, 0x0000, 0x2060, 0x2009, 0x0048, 0x080c, 0x864c, 0x080c,
-	0x1eef, 0x0838, 0x8001, 0x7002, 0xd194, 0x01b0, 0x7804, 0xd0fc,
-	0x1904, 0x1cd6, 0xd09c, 0x0138, 0x7804, 0xd0fc, 0x1904, 0x1cd6,
-	0xd09c, 0x1904, 0x1cda, 0x8aff, 0x0904, 0x1d2b, 0x2009, 0x0001,
-	0x080c, 0x1a4c, 0x0804, 0x1d2b, 0xa184, 0x0888, 0x1148, 0x8aff,
-	0x0904, 0x1d2b, 0x2009, 0x0001, 0x080c, 0x1a4c, 0x0804, 0x1d2b,
-	0x7818, 0x6812, 0x7a1c, 0x6a16, 0xa205, 0x0904, 0x1bdb, 0x7803,
-	0x0004, 0x7003, 0x0000, 0xd1bc, 0x1904, 0x1cb8, 0x6834, 0xa084,
-	0x00ff, 0xa086, 0x0029, 0x1118, 0xd19c, 0x1904, 0x1bdb, 0x0026,
-	0x0036, 0x7c20, 0x7d24, 0x7e30, 0x7f34, 0x7818, 0x6812, 0x781c,
-	0x6816, 0x2001, 0x0201, 0x2004, 0xa005, 0x0140, 0x7808, 0xd0ec,
-	0x1128, 0x7803, 0x0009, 0x7003, 0x0004, 0x0020, 0x0016, 0x080c,
-	0x1d2f, 0x001e, 0x6b28, 0x6a2c, 0x080c, 0x22bd, 0x00d6, 0x2805,
-	0xac68, 0x6034, 0xd09c, 0x1128, 0x6808, 0xa31a, 0x680c, 0xa213,
-	0x0020, 0x6810, 0xa31a, 0x6814, 0xa213, 0x00de, 0xd194, 0x0904,
-	0x1b63, 0x2a00, 0x6826, 0x2c00, 0x681a, 0x2800, 0x6832, 0x6808,
-	0x8001, 0x680a, 0x6b2a, 0x6a2e, 0x003e, 0x002e, 0x0804, 0x1c01,
-	0x0056, 0x7d0c, 0x080c, 0xb407, 0x005e, 0x080c, 0x1dfe, 0x00f6,
-	0x7004, 0x2078, 0x080c, 0x5305, 0x0118, 0x7820, 0xc0f5, 0x7822,
-	0x00fe, 0x682b, 0xffff, 0x682f, 0xffff, 0x6808, 0x8001, 0x680a,
-	0x697c, 0x791a, 0x6980, 0x791e, 0x0804, 0x1d2b, 0x7804, 0xd09c,
-	0x0904, 0x1b0e, 0x7c20, 0x7824, 0xa405, 0x1904, 0x1b0e, 0x7818,
-	0x6812, 0x7c1c, 0x6c16, 0xa405, 0x1120, 0x7803, 0x0002, 0x0804,
-	0x1bdb, 0x751c, 0x7420, 0x7724, 0x7628, 0x7014, 0xa528, 0x7018,
-	0xa421, 0xa7b9, 0x0000, 0xa6b1, 0x0000, 0x7830, 0xa506, 0x1150,
-	0x7834, 0xa406, 0x1138, 0x7838, 0xa706, 0x1120, 0x783c, 0xa606,
-	0x0904, 0x1b0e, 0x7803, 0x0002, 0x0804, 0x1c67, 0x7803, 0x0004,
-	0x7003, 0x0000, 0x7004, 0xa00d, 0x0150, 0x6808, 0x8001, 0x680a,
-	0x1130, 0x7004, 0x2060, 0x2009, 0x0048, 0x080c, 0x864c, 0x080c,
-	0x19ba, 0x0088, 0x7803, 0x0004, 0x7003, 0x0000, 0x7004, 0x2060,
-	0x6010, 0xa005, 0x0da0, 0x2068, 0x6808, 0x8000, 0x680a, 0x6c28,
-	0x6b2c, 0x080c, 0x19d5, 0x001e, 0x000e, 0x012e, 0x0005, 0x700c,
-	0x7110, 0xa106, 0x0904, 0x1dd1, 0x7004, 0x0016, 0x210c, 0xa106,
-	0x001e, 0x0904, 0x1dd1, 0x00d6, 0x00c6, 0x216c, 0x2d00, 0xa005,
-	0x0904, 0x1dcf, 0x681c, 0xa086, 0x0008, 0x0904, 0x1dcf, 0x6820,
-	0xd0d4, 0x1904, 0x1dcf, 0x6810, 0x2068, 0x6850, 0xd0fc, 0x05a8,
-	0x8108, 0x2104, 0x6b2c, 0xa306, 0x1904, 0x1dcf, 0x8108, 0x2104,
-	0x6a28, 0xa206, 0x1904, 0x1dcf, 0x6850, 0xc0fc, 0xc0f5, 0x6852,
-	0x686c, 0x7822, 0x7016, 0x6870, 0x7826, 0x701a, 0x681c, 0x7832,
-	0x701e, 0x6820, 0x7836, 0x7022, 0x6818, 0x2060, 0x6034, 0xd09c,
-	0x0168, 0x6830, 0x2005, 0x00d6, 0xac68, 0x6808, 0x783a, 0x7026,
-	0x680c, 0x783e, 0x702a, 0x00de, 0x0804, 0x1dc9, 0xa006, 0x783a,
-	0x783e, 0x7026, 0x702a, 0x0804, 0x1dc9, 0x8108, 0x2104, 0xa005,
-	0x1904, 0x1dcf, 0x6b2c, 0xa306, 0x1904, 0x1dcf, 0x8108, 0x2104,
-	0xa005, 0x15e8, 0x6a28, 0xa206, 0x15d0, 0x6850, 0xc0f5, 0x6852,
-	0x6830, 0x2005, 0x6918, 0xa160, 0xa180, 0x000d, 0x2004, 0xd09c,
-	0x11a0, 0x6008, 0x7822, 0x7016, 0x686e, 0x600c, 0x7826, 0x701a,
-	0x6872, 0x6000, 0x7832, 0x701e, 0x6004, 0x7836, 0x7022, 0xa006,
-	0x783a, 0x783e, 0x7026, 0x702a, 0x00a0, 0x6010, 0x7822, 0x7016,
-	0x686e, 0x6014, 0x7826, 0x701a, 0x6872, 0x6000, 0x7832, 0x701e,
-	0x6004, 0x7836, 0x7022, 0x6008, 0x783a, 0x7026, 0x600c, 0x783e,
-	0x702a, 0x6810, 0x781a, 0x6814, 0x781e, 0x7803, 0x0011, 0x00ce,
-	0x00de, 0x0005, 0x2011, 0x0201, 0x2009, 0x003c, 0x2204, 0xa005,
-	0x1118, 0x8109, 0x1dd8, 0x0005, 0x0005, 0x0ca1, 0x0118, 0x780c,
-	0xd0a4, 0x0120, 0x00d9, 0xa085, 0x0001, 0x0010, 0x080c, 0x1eef,
-	0x0005, 0x0126, 0x2091, 0x2200, 0x7000, 0xa086, 0x0003, 0x1160,
-	0x700c, 0x7110, 0xa106, 0x0140, 0x080c, 0x295c, 0x20e1, 0x9028,
-	0x700f, 0xb82f, 0x7013, 0xb82f, 0x012e, 0x0005, 0x00c6, 0x080c,
-	0x5acf, 0x11b8, 0x2001, 0x0160, 0x2003, 0x0000, 0x2001, 0x0138,
-	0x2003, 0x0000, 0x2011, 0x00c8, 0xe000, 0xe000, 0x8211, 0x1de0,
-	0x04b1, 0x0066, 0x2031, 0x0000, 0x080c, 0x5b51, 0x006e, 0x00ce,
-	0x0005, 0x080c, 0x1e6e, 0x080c, 0x295c, 0x20e1, 0x9028, 0x700c,
-	0x7110, 0xa106, 0x01c0, 0x2104, 0xa005, 0x0130, 0x2060, 0x6010,
-	0x2060, 0x6008, 0x8001, 0x600a, 0xa188, 0x0003, 0xa182, 0xb84a,
-	0x0210, 0x2009, 0xb82f, 0x7112, 0x700c, 0xa106, 0x1d40, 0x080c,
-	0x28eb, 0x2110, 0x0c20, 0x2001, 0x015d, 0x2003, 0x0000, 0x2001,
-	0x0160, 0x2502, 0x2001, 0x0138, 0x2202, 0x00ce, 0x0005, 0x080c,
-	0x295c, 0x20e1, 0x9028, 0x2001, 0x015d, 0x2003, 0x0000, 0x00e6,
-	0x00c6, 0x0016, 0x2071, 0xb823, 0x700c, 0x7110, 0xa106, 0x0190,
-	0x2104, 0xa005, 0x0130, 0x2060, 0x6010, 0x2060, 0x6008, 0x8001,
-	0x600a, 0xa188, 0x0003, 0xa182, 0xb84a, 0x0210, 0x2009, 0xb82f,
-	0x7112, 0x0c50, 0x001e, 0x00ce, 0x00ee, 0x0005, 0x2001, 0x0138,
-	0x2014, 0x2003, 0x0000, 0x2001, 0x0160, 0x202c, 0x2003, 0x0000,
-	0x080c, 0x5acf, 0x1148, 0x2021, 0x0002, 0x1d04, 0x1e7d, 0x2091,
-	0x6000, 0x8421, 0x1dd0, 0x0005, 0x2021, 0xb015, 0x2001, 0x0141,
-	0x201c, 0xd3dc, 0x1168, 0x2001, 0x0109, 0x201c, 0xa39c, 0x0048,
-	0x1138, 0x2001, 0x0111, 0x201c, 0x83ff, 0x1110, 0x8421, 0x1d70,
-	0x0005, 0x00e6, 0x2071, 0x0200, 0x7808, 0xa084, 0xf000, 0xa10d,
-	0x0869, 0x2001, 0x0105, 0x2004, 0xa084, 0x0003, 0x1130, 0x2001,
-	0xb84a, 0x2004, 0xa086, 0x0000, 0x0548, 0xa026, 0x2019, 0xf000,
-	0x8319, 0x1148, 0x2001, 0x012b, 0x2003, 0x95f5, 0x2001, 0x0129,
-	0x2003, 0x95f5, 0x00d8, 0x2001, 0x0105, 0x2004, 0xa084, 0x0003,
-	0x1130, 0x2001, 0xb84a, 0x2004, 0xa086, 0x0000, 0x0178, 0x2001,
-	0x0132, 0x2004, 0xa436, 0x0110, 0x2020, 0x0c00, 0x2001, 0x0021,
-	0x2004, 0xd0fc, 0x09e8, 0x080c, 0x214a, 0x08c0, 0x20e1, 0x7000,
-	0x7324, 0x7420, 0x7028, 0x7028, 0x7426, 0x7037, 0x0001, 0x810f,
-	0x712e, 0x702f, 0x0100, 0x7037, 0x0008, 0x7326, 0x7422, 0x2001,
-	0x0160, 0x2502, 0x2001, 0x0138, 0x2202, 0x00ee, 0x0005, 0x0026,
-	0x2001, 0x015d, 0x2003, 0x0000, 0x7908, 0xa18c, 0x0fff, 0xa182,
-	0x0ffd, 0x0210, 0x2009, 0x0000, 0xa190, 0x0007, 0xa294, 0x1ff8,
-	0x8214, 0x8214, 0x8214, 0x2001, 0x020a, 0x82ff, 0x0140, 0x20e1,
-	0x6000, 0x200c, 0x200c, 0x200c, 0x200c, 0x8211, 0x1dd0, 0x20e1,
-	0x7000, 0x200c, 0x200c, 0x7003, 0x0000, 0x20e1, 0x6000, 0x2001,
-	0x0208, 0x200c, 0x2001, 0x0209, 0x2004, 0xa106, 0x0158, 0x080c,
-	0x1dd2, 0x0130, 0x7908, 0xd1ec, 0x1128, 0x790c, 0xd1a4, 0x0960,
-	0x080c, 0x1dfe, 0xa006, 0x002e, 0x0005, 0x00f6, 0x00e6, 0x0016,
-	0x0026, 0x2071, 0xb823, 0x2079, 0x0030, 0x2011, 0x0050, 0x7000,
-	0xa086, 0x0000, 0x01a8, 0x8211, 0x0188, 0x2001, 0x0005, 0x2004,
-	0xd08c, 0x0dc8, 0x7904, 0xa18c, 0x0780, 0x0016, 0x080c, 0x1b06,
-	0x001e, 0x81ff, 0x1118, 0x2011, 0x0050, 0x0c48, 0xa085, 0x0001,
-	0x002e, 0x001e, 0x00ee, 0x00fe, 0x0005, 0x7803, 0x0004, 0x2009,
-	0x0064, 0x7804, 0xd0ac, 0x0904, 0x1fa1, 0x8109, 0x1dd0, 0x2009,
-	0x0100, 0x210c, 0xa18a, 0x0003, 0x0a0c, 0x1515, 0x080c, 0x2251,
-	0x00e6, 0x00f6, 0x2071, 0xb812, 0x2079, 0x0010, 0x7004, 0xa086,
-	0x0000, 0x0538, 0x7800, 0x0006, 0x7820, 0x0006, 0x7830, 0x0006,
-	0x7834, 0x0006, 0x7838, 0x0006, 0x783c, 0x0006, 0x7803, 0x0004,
-	0xe000, 0xe000, 0x2079, 0x0030, 0x7804, 0xd0ac, 0x190c, 0x1515,
-	0x2079, 0x0010, 0x000e, 0x783e, 0x000e, 0x783a, 0x000e, 0x7836,
-	0x000e, 0x7832, 0x000e, 0x7822, 0x000e, 0x7802, 0x00fe, 0x00ee,
-	0x0030, 0x00fe, 0x00ee, 0x7804, 0xd0ac, 0x190c, 0x1515, 0x080c,
-	0x7230, 0x0005, 0x00e6, 0x2071, 0xb84a, 0x7003, 0x0000, 0x00ee,
-	0x0005, 0x00d6, 0xa280, 0x0004, 0x206c, 0x694c, 0xd1dc, 0x1904,
-	0x201f, 0x6934, 0xa184, 0x0007, 0x0002, 0x1fbd, 0x200a, 0x1fbd,
-	0x1fbd, 0x1fbd, 0x1ff1, 0x1fd0, 0x1fbf, 0x080c, 0x1515, 0x684c,
-	0xd0b4, 0x0904, 0x2107, 0x6860, 0x682e, 0x6816, 0x685c, 0x682a,
-	0x6812, 0x687c, 0x680a, 0x6880, 0x680e, 0x6958, 0x0804, 0x2012,
-	0x6834, 0xa084, 0x00ff, 0xa086, 0x001e, 0x1d38, 0x684c, 0xd0b4,
-	0x0904, 0x2107, 0x6860, 0x682e, 0x6816, 0x685c, 0x682a, 0x6812,
-	0x687c, 0x680a, 0x6880, 0x680e, 0x6804, 0x681a, 0xa080, 0x000d,
-	0x2004, 0xa084, 0x000f, 0xa080, 0x22e5, 0x2005, 0x6832, 0x6958,
-	0x0450, 0xa18c, 0x00ff, 0xa186, 0x0015, 0x1548, 0x684c, 0xd0b4,
-	0x0904, 0x2107, 0x6804, 0x681a, 0xa080, 0x000d, 0x2004, 0xa084,
-	0x000f, 0xa080, 0x22e5, 0x2005, 0x6832, 0x6958, 0xa006, 0x682e,
-	0x682a, 0x0088, 0x684c, 0xd0b4, 0x0904, 0x1ae1, 0x6958, 0xa006,
-	0x682e, 0x682a, 0x2d00, 0x681a, 0x6834, 0xa084, 0x000f, 0xa080,
-	0x22e5, 0x2005, 0x6832, 0x6926, 0x684c, 0xc0dd, 0x684e, 0x00de,
-	0x0005, 0x00f6, 0x2079, 0x0020, 0x7804, 0xd0fc, 0x190c, 0x214a,
-	0x00e6, 0x00d6, 0x2071, 0xb84a, 0x7000, 0xa005, 0x1904, 0x2087,
-	0x00c6, 0x7206, 0xa280, 0x0004, 0x205c, 0x7004, 0x2068, 0x7803,
-	0x0004, 0x6818, 0x00d6, 0x2068, 0x686c, 0x7812, 0x6890, 0x00f6,
-	0x20e1, 0x9040, 0x2079, 0x0200, 0x781a, 0x2079, 0x0100, 0x8004,
-	0x78d6, 0x00fe, 0x00de, 0x2b68, 0x6824, 0x2050, 0x6818, 0x2060,
-	0x6830, 0x2040, 0x6034, 0xa0cc, 0x000f, 0x6908, 0x791a, 0x7116,
-	0x680c, 0x781e, 0x701a, 0xa006, 0x700e, 0x7012, 0x7004, 0x692c,
-	0x6814, 0xa106, 0x1120, 0x6928, 0x6810, 0xa106, 0x0158, 0x0036,
-	0x0046, 0x6b14, 0x6c10, 0x080c, 0x2305, 0x004e, 0x003e, 0x0110,
-	0x00ce, 0x00a8, 0x8aff, 0x1120, 0x00ce, 0xa085, 0x0001, 0x0078,
-	0x0126, 0x2091, 0x8000, 0x2079, 0x0020, 0x2009, 0x0001, 0x0059,
-	0x0118, 0x2009, 0x0001, 0x0039, 0x012e, 0x00ce, 0xa006, 0x00de,
-	0x00ee, 0x00fe, 0x0005, 0x0076, 0x0066, 0x0056, 0x0046, 0x0036,
-	0x0026, 0x8aff, 0x0904, 0x2100, 0x700c, 0x7214, 0xa23a, 0x7010,
-	0x7218, 0xa203, 0x0a04, 0x20ff, 0xa705, 0x0904, 0x20ff, 0xa03e,
-	0x2730, 0x6850, 0xd0fc, 0x11a8, 0x00d6, 0x2805, 0xac68, 0x2900,
-	0x0002, 0x20e2, 0x20c7, 0x20c7, 0x20e2, 0x20e2, 0x20db, 0x20e2,
-	0x20c7, 0x20e2, 0x20cc, 0x20cc, 0x20e2, 0x20e2, 0x20e2, 0x20d3,
-	0x20cc, 0xc0fc, 0x6852, 0x6b6c, 0x6a70, 0x6d1c, 0x6c20, 0xd99c,
-	0x0528, 0x00d6, 0x2805, 0xac68, 0x6f08, 0x6e0c, 0x00f0, 0x6b08,
-	0x6a0c, 0x6d00, 0x6c04, 0x00c8, 0x6b10, 0x6a14, 0x6d00, 0x6c04,
-	0x6f08, 0x6e0c, 0x0090, 0x00de, 0x00d6, 0x6834, 0xa084, 0x00ff,
-	0xa086, 0x001e, 0x1138, 0x00de, 0x080c, 0x22a7, 0x1904, 0x2091,
-	0xa00e, 0x00f0, 0x00de, 0x080c, 0x1515, 0x00de, 0x7b22, 0x7a26,
-	0x7d32, 0x7c36, 0x7f3a, 0x7e3e, 0x7902, 0x7000, 0x8000, 0x7002,
-	0x6828, 0xa300, 0x682a, 0x682c, 0xa201, 0x682e, 0x700c, 0xa300,
-	0x700e, 0x7010, 0xa201, 0x7012, 0x080c, 0x22a7, 0x0008, 0xa006,
-	0x002e, 0x003e, 0x004e, 0x005e, 0x006e, 0x007e, 0x0005, 0x080c,
-	0x1515, 0x0026, 0x2001, 0x0105, 0x2003, 0x0010, 0x20e1, 0x9040,
-	0x7803, 0x0004, 0x7003, 0x0000, 0x7004, 0x2060, 0x00d6, 0x6010,
-	0x2068, 0x080c, 0x9c5a, 0x0118, 0x6850, 0xc0bd, 0x6852, 0x601c,
-	0xa086, 0x0006, 0x1180, 0x2061, 0x0100, 0x62c8, 0x2001, 0x00fa,
-	0x8001, 0x1df0, 0x60c8, 0xa206, 0x1dc0, 0x60c4, 0x686a, 0x60c8,
-	0x6866, 0x7004, 0x2060, 0x00de, 0x00c6, 0x080c, 0x992a, 0x00ce,
-	0x2001, 0xb7ef, 0x2004, 0xac06, 0x1150, 0x20e1, 0x9040, 0x080c,
-	0x825d, 0x2011, 0x0000, 0x080c, 0x807f, 0x080c, 0x7230, 0x002e,
-	0x0804, 0x2204, 0x0126, 0x2091, 0x2400, 0x0006, 0x0016, 0x00f6,
-	0x00e6, 0x00d6, 0x00c6, 0x2079, 0x0020, 0x2071, 0xb84a, 0x2b68,
-	0x6818, 0x2060, 0x7904, 0x7803, 0x0002, 0xa184, 0x0700, 0x1904,
-	0x2109, 0x7000, 0x0002, 0x2204, 0x2167, 0x21d7, 0x2202, 0x8001,
-	0x7002, 0xd19c, 0x1170, 0x8aff, 0x05d0, 0x2009, 0x0001, 0x080c,
-	0x208b, 0x0904, 0x2204, 0x2009, 0x0001, 0x080c, 0x208b, 0x0804,
-	0x2204, 0x7803, 0x0004, 0xd194, 0x0148, 0x6850, 0xc0fc, 0x6852,
-	0x8aff, 0x11d8, 0x684c, 0xc0f5, 0x684e, 0x00b8, 0x0026, 0x0036,
-	0x6b28, 0x6a2c, 0x7820, 0x686e, 0xa31a, 0x7824, 0x6872, 0xa213,
-	0x7830, 0x681e, 0x7834, 0x6822, 0x6b2a, 0x6a2e, 0x003e, 0x002e,
-	0x080c, 0x22bd, 0x6850, 0xc0fd, 0x6852, 0x2a00, 0x6826, 0x2c00,
-	0x681a, 0x2800, 0x6832, 0x7003, 0x0000, 0x0804, 0x2204, 0x00f6,
-	0x0026, 0x781c, 0x0006, 0x7818, 0x0006, 0x2079, 0x0100, 0x7a14,
-	0xa284, 0x0184, 0xa085, 0x0012, 0x7816, 0x0036, 0x2019, 0x1000,
-	0x8319, 0x090c, 0x1515, 0x7820, 0xd0bc, 0x1dd0, 0x003e, 0x79c8,
-	0x000e, 0xa102, 0x001e, 0x0006, 0x0016, 0x79c4, 0x000e, 0xa103,
-	0x78c6, 0x000e, 0x78ca, 0xa284, 0x0184, 0xa085, 0x0012, 0x7816,
-	0x002e, 0x00fe, 0x7803, 0x0008, 0x7003, 0x0000, 0x0468, 0x8001,
-	0x7002, 0xd194, 0x0168, 0x7804, 0xd0fc, 0x1904, 0x215a, 0xd19c,
-	0x11f8, 0x8aff, 0x0508, 0x2009, 0x0001, 0x080c, 0x208b, 0x00e0,
-	0x0026, 0x0036, 0x6b28, 0x6a2c, 0x080c, 0x22bd, 0x00d6, 0x2805,
-	0xac68, 0x6034, 0xd09c, 0x1128, 0x6808, 0xa31a, 0x680c, 0xa213,
-	0x0020, 0x6810, 0xa31a, 0x6814, 0xa213, 0x00de, 0x0804, 0x218a,
-	0x0804, 0x2186, 0x080c, 0x1515, 0x00ce, 0x00de, 0x00ee, 0x00fe,
-	0x001e, 0x000e, 0x012e, 0x0005, 0x00f6, 0x00e6, 0x2071, 0xb84a,
-	0x7000, 0xa086, 0x0000, 0x05d0, 0x2079, 0x0020, 0x0016, 0x2009,
-	0x0207, 0x210c, 0xd194, 0x0198, 0x2009, 0x020c, 0x210c, 0xa184,
-	0x0003, 0x0168, 0x080c, 0xb450, 0x2001, 0x0133, 0x2004, 0xa005,
-	0x090c, 0x1515, 0x20e1, 0x9040, 0x2001, 0x020c, 0x2102, 0x2009,
-	0x0206, 0x2104, 0x2009, 0x0203, 0x210c, 0xa106, 0x1110, 0x20e1,
-	0x9040, 0x7804, 0xd0fc, 0x09d8, 0x080c, 0x214a, 0x7000, 0xa086,
-	0x0000, 0x19a8, 0x001e, 0x7803, 0x0004, 0x7804, 0xd0ac, 0x1de8,
-	0x20e1, 0x9040, 0x7803, 0x0002, 0x7003, 0x0000, 0x00ee, 0x00fe,
-	0x0005, 0x0026, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2071, 0xb84a,
-	0x2079, 0x0020, 0x7000, 0xa086, 0x0000, 0x0540, 0x7004, 0x2060,
-	0x6010, 0x2068, 0x080c, 0x9c5a, 0x0158, 0x6850, 0xc0b5, 0x6852,
-	0x680c, 0x7a1c, 0xa206, 0x1120, 0x6808, 0x7a18, 0xa206, 0x01e0,
-	0x2001, 0x0105, 0x2003, 0x0010, 0x20e1, 0x9040, 0x7803, 0x0004,
-	0x7003, 0x0000, 0x7004, 0x2060, 0x080c, 0x992a, 0x20e1, 0x9040,
-	0x080c, 0x825d, 0x2011, 0x0000, 0x080c, 0x807f, 0x00fe, 0x00ee,
-	0x00de, 0x00ce, 0x002e, 0x0005, 0x6810, 0x6a14, 0xa205, 0x1d00,
-	0x684c, 0xc0dc, 0x684e, 0x2c10, 0x080c, 0x1fa9, 0x2001, 0x0105,
-	0x2003, 0x0010, 0x20e1, 0x9040, 0x7803, 0x0004, 0x7003, 0x0000,
-	0x2069, 0xb7e0, 0x6833, 0x0000, 0x683f, 0x0000, 0x08f8, 0x8840,
-	0x2805, 0xa005, 0x1170, 0x6004, 0xa005, 0x0168, 0x681a, 0x2060,
-	0x6034, 0xa084, 0x000f, 0xa080, 0x22e5, 0x2045, 0x88ff, 0x090c,
-	0x1515, 0x8a51, 0x0005, 0x2050, 0x0005, 0x8a50, 0x8841, 0x2805,
-	0xa005, 0x1190, 0x2c00, 0xad06, 0x0120, 0x6000, 0xa005, 0x1108,
-	0x2d00, 0x2060, 0x681a, 0x6034, 0xa084, 0x000f, 0xa080, 0x22f5,
-	0x2045, 0x88ff, 0x090c, 0x1515, 0x0005, 0x0000, 0x0011, 0x0015,
-	0x0019, 0x001d, 0x0021, 0x0025, 0x0029, 0x0000, 0x000f, 0x0015,
-	0x001b, 0x0021, 0x0027, 0x0000, 0x0000, 0x0000, 0x22da, 0x22d6,
-	0x0000, 0x0000, 0x22e4, 0x0000, 0x22da, 0x0000, 0x22e1, 0x22de,
-	0x0000, 0x0000, 0x0000, 0x22e4, 0x22e1, 0x0000, 0x22dc, 0x22dc,
-	0x0000, 0x0000, 0x22e4, 0x0000, 0x22dc, 0x0000, 0x22e2, 0x22e2,
-	0x0000, 0x0000, 0x0000, 0x22e4, 0x22e2, 0x00a6, 0x0096, 0x0086,
-	0x6b2e, 0x6c2a, 0x6858, 0xa055, 0x0904, 0x2396, 0x2d60, 0x6034,
-	0xa0cc, 0x000f, 0xa9c0, 0x22e5, 0xa986, 0x0007, 0x0130, 0xa986,
-	0x000e, 0x0118, 0xa986, 0x000f, 0x1120, 0x605c, 0xa422, 0x6060,
-	0xa31b, 0x2805, 0xa045, 0x1140, 0x0310, 0x0804, 0x2396, 0x6004,
-	0xa065, 0x0904, 0x2396, 0x0c18, 0x2805, 0xa005, 0x01a8, 0xac68,
-	0xd99c, 0x1128, 0x6808, 0xa422, 0x680c, 0xa31b, 0x0020, 0x6810,
-	0xa422, 0x6814, 0xa31b, 0x0620, 0x2300, 0xa405, 0x0150, 0x8a51,
-	0x0904, 0x2396, 0x8840, 0x0c40, 0x6004, 0xa065, 0x0904, 0x2396,
-	0x0830, 0x8a51, 0x0904, 0x2396, 0x8840, 0x2805, 0xa005, 0x1158,
-	0x6004, 0xa065, 0x0904, 0x2396, 0x6034, 0xa0cc, 0x000f, 0xa9c0,
-	0x22e5, 0x2805, 0x2040, 0x2b68, 0x6850, 0xc0fc, 0x6852, 0x0458,
-	0x8422, 0x8420, 0x831a, 0xa399, 0x0000, 0x00d6, 0x2b68, 0x6c6e,
-	0x6b72, 0x00de, 0xd99c, 0x1168, 0x6908, 0x2400, 0xa122, 0x690c,
-	0x2300, 0xa11b, 0x0a0c, 0x1515, 0x6800, 0xa420, 0x6804, 0xa319,
-	0x0060, 0x6910, 0x2400, 0xa122, 0x6914, 0x2300, 0xa11b, 0x0a0c,
-	0x1515, 0x6800, 0xa420, 0x6804, 0xa319, 0x2b68, 0x6c1e, 0x6b22,
-	0x6850, 0xc0fd, 0x6852, 0x2c00, 0x681a, 0x2800, 0x6832, 0x2a00,
-	0x6826, 0x000e, 0x000e, 0x000e, 0xa006, 0x0028, 0x008e, 0x009e,
-	0x00ae, 0xa085, 0x0001, 0x0005, 0x2001, 0x0005, 0x2004, 0xa084,
-	0x0007, 0x0002, 0x23aa, 0x23ab, 0x23ae, 0x23b1, 0x23b6, 0x23b9,
-	0x23be, 0x23c3, 0x0005, 0x080c, 0x214a, 0x0005, 0x080c, 0x1b06,
-	0x0005, 0x080c, 0x1b06, 0x080c, 0x214a, 0x0005, 0x080c, 0x171b,
-	0x0005, 0x080c, 0x214a, 0x080c, 0x171b, 0x0005, 0x080c, 0x1b06,
-	0x080c, 0x171b, 0x0005, 0x080c, 0x1b06, 0x080c, 0x214a, 0x080c,
-	0x171b, 0x0005, 0x0126, 0x2091, 0x2600, 0x2079, 0x0200, 0x2071,
-	0xbb80, 0x2069, 0xb500, 0x080c, 0x24c0, 0x080c, 0x24b0, 0x2009,
-	0x0004, 0x7912, 0x7817, 0x0004, 0x080c, 0x27f8, 0x781b, 0x0002,
-	0x20e1, 0x9080, 0x20e1, 0x4000, 0x20a9, 0x0080, 0x782f, 0x0000,
-	0x1f04, 0x23e6, 0x20e1, 0x9080, 0x783b, 0x001f, 0x20e1, 0x8700,
-	0x012e, 0x0005, 0x0126, 0x2091, 0x2600, 0x781c, 0xd0a4, 0x190c,
-	0x24ad, 0xa084, 0x0007, 0x0002, 0x2416, 0x2404, 0x2407, 0x240a,
-	0x240f, 0x2411, 0x2413, 0x2415, 0x080c, 0x63c4, 0x0078, 0x080c,
-	0x6403, 0x0060, 0x080c, 0x63c4, 0x080c, 0x6403, 0x0038, 0x0041,
-	0x0028, 0x0031, 0x0018, 0x0021, 0x0008, 0x0011, 0x012e, 0x0005,
-	0x0006, 0x0016, 0x0026, 0x080c, 0xb450, 0x7930, 0xa184, 0x0003,
-	0x01b0, 0x2001, 0xb7ef, 0x2004, 0xa005, 0x0170, 0x2001, 0x0133,
-	0x2004, 0xa005, 0x090c, 0x1515, 0x00c6, 0x2001, 0xb7ef, 0x2064,
-	0x080c, 0x992a, 0x00ce, 0x04b8, 0x20e1, 0x9040, 0x04a0, 0xa184,
-	0x0030, 0x01e0, 0x6a00, 0xa286, 0x0003, 0x1108, 0x00a0, 0x080c,
-	0x5acf, 0x1178, 0x2001, 0xb79f, 0x2003, 0x0001, 0x2001, 0xb500,
-	0x2003, 0x0001, 0xa085, 0x0001, 0x080c, 0x5b13, 0x080c, 0x5a07,
-	0x0010, 0x080c, 0x4b1f, 0x080c, 0x24b0, 0x00a8, 0xa184, 0x00c0,
-	0x0168, 0x00e6, 0x0036, 0x0046, 0x0056, 0x2071, 0xb823, 0x080c,
-	0x1dfe, 0x005e, 0x004e, 0x003e, 0x00ee, 0x0028, 0xa184, 0x0300,
-	0x0110, 0x20e1, 0x9020, 0x7932, 0x002e, 0x001e, 0x000e, 0x0005,
-	0x0016, 0x00e6, 0x00f6, 0x2071, 0xb500, 0x7128, 0x2001, 0xb791,
-	0x2102, 0x2001, 0xb799, 0x2102, 0xa182, 0x0211, 0x1218, 0x2009,
-	0x0008, 0x0400, 0xa182, 0x0259, 0x1218, 0x2009, 0x0007, 0x00d0,
-	0xa182, 0x02c1, 0x1218, 0x2009, 0x0006, 0x00a0, 0xa182, 0x0349,
-	0x1218, 0x2009, 0x0005, 0x0070, 0xa182, 0x0421, 0x1218, 0x2009,
-	0x0004, 0x0040, 0xa182, 0x0581, 0x1218, 0x2009, 0x0003, 0x0010,
-	0x2009, 0x0002, 0x2079, 0x0200, 0x7912, 0x7817, 0x0004, 0x080c,
-	0x27f8, 0x00fe, 0x00ee, 0x001e, 0x0005, 0x7938, 0x080c, 0x1515,
-	0x00e6, 0x0026, 0x2071, 0x0200, 0x20e1, 0x1000, 0x7220, 0x7028,
-	0x7020, 0xa206, 0x0de0, 0x20e1, 0x9010, 0x002e, 0x00ee, 0x0005,
-	0x20e1, 0xa000, 0x7837, 0x0001, 0x782f, 0x0000, 0x782f, 0x0000,
-	0x782f, 0x0000, 0x782f, 0x0000, 0x7837, 0x0005, 0x20a9, 0x0210,
-	0x7830, 0xd0bc, 0x1110, 0x1f04, 0x24d0, 0x7837, 0x0001, 0x7837,
-	0x0000, 0xe000, 0xe000, 0x20e1, 0xa000, 0x0005, 0x0126, 0x2091,
-	0x2800, 0x2061, 0x0100, 0x2071, 0xb500, 0x6024, 0x6026, 0x6053,
-	0x0030, 0x080c, 0x2837, 0x6050, 0xa084, 0xfe7f, 0x6052, 0x2009,
-	0x00ef, 0x6132, 0x6136, 0x080c, 0x2847, 0x60e7, 0x0000, 0x61ea,
-	0x60e3, 0x0008, 0x604b, 0xf7f7, 0x6043, 0x0000, 0x602f, 0x0080,
-	0x602f, 0x0000, 0x6007, 0x0e9f, 0x601b, 0x001e, 0x600f, 0x00ff,
-	0x2001, 0xb78d, 0x2003, 0x00ff, 0x602b, 0x002f, 0x012e, 0x0005,
-	0x2001, 0xb532, 0x2003, 0x0000, 0x2001, 0xb531, 0x2003, 0x0001,
-	0x0005, 0x0126, 0x2091, 0x2800, 0x0006, 0x0016, 0x0026, 0x6124,
-	0xa184, 0x1e2c, 0x1118, 0xa184, 0x0007, 0x002a, 0xa195, 0x0004,
-	0xa284, 0x0007, 0x0002, 0x254d, 0x2533, 0x2536, 0x2539, 0x253e,
-	0x2540, 0x2544, 0x2548, 0x080c, 0x6b74, 0x00b8, 0x080c, 0x6c4f,
-	0x00a0, 0x080c, 0x6c4f, 0x080c, 0x6b74, 0x0078, 0x0099, 0x0068,
-	0x080c, 0x6b74, 0x0079, 0x0048, 0x080c, 0x6c4f, 0x0059, 0x0028,
-	0x080c, 0x6c4f, 0x080c, 0x6b74, 0x0029, 0x002e, 0x001e, 0x000e,
-	0x012e, 0x0005, 0x6124, 0x6028, 0xd09c, 0x0118, 0xd19c, 0x1904,
-	0x2766, 0x080c, 0x5acf, 0x0578, 0x7000, 0xa086, 0x0003, 0x0198,
-	0x6024, 0xa084, 0x1800, 0x0178, 0x080c, 0x5af5, 0x0118, 0x080c,
-	0x5ae1, 0x1148, 0x6027, 0x0020, 0x6043, 0x0000, 0x2001, 0xb79e,
-	0x2003, 0xaaaa, 0x0458, 0x080c, 0x5af5, 0x15d0, 0x6024, 0xa084,
-	0x1800, 0x1108, 0x04a8, 0x2001, 0xb79e, 0x2003, 0xaaaa, 0x2001,
-	0xb79f, 0x2003, 0x0001, 0x2001, 0xb500, 0x2003, 0x0001, 0x080c,
-	0x5a07, 0x0804, 0x2766, 0xd1ac, 0x1518, 0x6024, 0xd0dc, 0x1170,
-	0xd0e4, 0x1188, 0xd0d4, 0x11a0, 0xd0cc, 0x0130, 0x708c, 0xa086,
-	0x0028, 0x1110, 0x080c, 0x5c5e, 0x0804, 0x2766, 0x2001, 0xb79f,
-	0x2003, 0x0000, 0x0048, 0x2001, 0xb79f, 0x2003, 0x0002, 0x0020,
-	0x080c, 0x5bd1, 0x0804, 0x2766, 0x080c, 0x5d03, 0x0804, 0x2766,
-	0xd1ac, 0x0904, 0x26ae, 0x080c, 0x5acf, 0x11d8, 0x6027, 0x0020,
-	0x0006, 0x0026, 0x0036, 0x080c, 0x5aeb, 0x1170, 0x2001, 0xb79f,
-	0x2003, 0x0001, 0x2001, 0xb500, 0x2003, 0x0001, 0x080c, 0x5a07,
-	0x003e, 0x002e, 0x000e, 0x0005, 0x003e, 0x002e, 0x000e, 0x080c,
-	0x5aa6, 0x0016, 0x0046, 0x00c6, 0x644c, 0xa486, 0xf0f0, 0x1138,
-	0x2061, 0x0100, 0x644a, 0x6043, 0x0090, 0x6043, 0x0010, 0x74ce,
-	0xa48c, 0xff00, 0x7034, 0xd084, 0x0178, 0xa186, 0xf800, 0x1160,
-	0x703c, 0xd084, 0x1148, 0xc085, 0x703e, 0x0036, 0x2418, 0x2011,
-	0x8016, 0x080c, 0x3ecc, 0x003e, 0xa196, 0xff00, 0x05b8, 0x7054,
-	0xa084, 0x00ff, 0x810f, 0xa116, 0x0588, 0x7130, 0xd184, 0x1570,
-	0x2011, 0xb553, 0x2214, 0xd2ec, 0x0138, 0xc18d, 0x7132, 0x2011,
-	0xb553, 0x2214, 0xd2ac, 0x1510, 0x6240, 0xa294, 0x0010, 0x0130,
-	0x6248, 0xa294, 0xff00, 0xa296, 0xff00, 0x01c0, 0x7030, 0xd08c,
-	0x0904, 0x267b, 0x7034, 0xd08c, 0x1140, 0x2001, 0xb50c, 0x200c,
-	0xd1ac, 0x1904, 0x267b, 0xc1ad, 0x2102, 0x0036, 0x73cc, 0x2011,
-	0x8013, 0x080c, 0x3ecc, 0x003e, 0x0804, 0x267b, 0x7034, 0xd08c,
-	0x1140, 0x2001, 0xb50c, 0x200c, 0xd1ac, 0x1904, 0x267b, 0xc1ad,
-	0x2102, 0x0036, 0x73cc, 0x2011, 0x8013, 0x080c, 0x3ecc, 0x003e,
-	0x7130, 0xc185, 0x7132, 0x2011, 0xb553, 0x220c, 0xd1a4, 0x01d0,
-	0x0016, 0x2009, 0x0001, 0x2011, 0x0100, 0x080c, 0x6b1a, 0x2019,
-	0x000e, 0x080c, 0xb065, 0xa484, 0x00ff, 0xa080, 0x2dc4, 0x200d,
-	0xa18c, 0xff00, 0x810f, 0x8127, 0xa006, 0x2009, 0x000e, 0x080c,
-	0xb0e8, 0x001e, 0xd1ac, 0x1148, 0x0016, 0x2009, 0x0000, 0x2019,
-	0x0004, 0x080c, 0x2c6f, 0x001e, 0x0070, 0x0156, 0x20a9, 0x007f,
-	0x2009, 0x0000, 0x080c, 0x4fa9, 0x1110, 0x080c, 0x4c0b, 0x8108,
-	0x1f04, 0x2672, 0x015e, 0x00ce, 0x004e, 0x2011, 0x0003, 0x080c,
-	0x8075, 0x2011, 0x0002, 0x080c, 0x807f, 0x080c, 0x7f59, 0x0036,
-	0x2019, 0x0000, 0x080c, 0x7fe4, 0x003e, 0x60e3, 0x0000, 0x001e,
-	0x2001, 0xb500, 0x2014, 0xa296, 0x0004, 0x1128, 0xd19c, 0x11b0,
-	0x6228, 0xc29d, 0x622a, 0x2003, 0x0001, 0x2001, 0xb523, 0x2003,
-	0x0000, 0x6027, 0x0020, 0x080c, 0x5af5, 0x1140, 0x0016, 0x2009,
-	0x07d0, 0x2011, 0x59e4, 0x080c, 0x6a22, 0x001e, 0xd194, 0x0904,
-	0x2766, 0x0016, 0x6220, 0xd2b4, 0x0904, 0x2717, 0x080c, 0x6a10,
-	0x080c, 0x7d7a, 0x6027, 0x0004, 0x00f6, 0x2019, 0xb7e9, 0x2304,
-	0xa07d, 0x0570, 0x7804, 0xa086, 0x0032, 0x1550, 0x00d6, 0x00c6,
-	0x00e6, 0x2069, 0x0140, 0x618c, 0x6288, 0x7818, 0x608e, 0x7808,
-	0x608a, 0x6043, 0x0002, 0x2001, 0x0003, 0x8001, 0x1df0, 0x6043,
-	0x0000, 0x6803, 0x1000, 0x6803, 0x0000, 0x618e, 0x628a, 0x080c,
-	0x7090, 0x080c, 0x7173, 0x7810, 0x2070, 0x7037, 0x0103, 0x2f60,
-	0x080c, 0x861d, 0x00ee, 0x00ce, 0x00de, 0x00fe, 0x001e, 0x0005,
-	0x00fe, 0x00d6, 0x2069, 0x0140, 0x6804, 0xa084, 0x4000, 0x0120,
-	0x6803, 0x1000, 0x6803, 0x0000, 0x00de, 0x00c6, 0x2061, 0xb7e0,
-	0x6028, 0xa09a, 0x00c8, 0x1238, 0x8000, 0x602a, 0x00ce, 0x080c,
-	0x7d6d, 0x0804, 0x2765, 0x2019, 0xb7e9, 0x2304, 0xa065, 0x0120,
-	0x2009, 0x0027, 0x080c, 0x864c, 0x00ce, 0x0804, 0x2765, 0xd2bc,
-	0x0904, 0x2765, 0x080c, 0x6a1d, 0x6014, 0xa084, 0x0184, 0xa085,
-	0x0010, 0x6016, 0x6027, 0x0004, 0x00d6, 0x2069, 0x0140, 0x6804,
-	0xa084, 0x4000, 0x0120, 0x6803, 0x1000, 0x6803, 0x0000, 0x00de,
-	0x00c6, 0x2061, 0xb7e0, 0x6044, 0xa09a, 0x00c8, 0x12f0, 0x8000,
-	0x6046, 0x603c, 0x00ce, 0xa005, 0x0540, 0x2009, 0x07d0, 0x080c,
-	0x6a15, 0xa080, 0x0007, 0x2004, 0xa086, 0x0006, 0x1138, 0x6114,
-	0xa18c, 0x0184, 0xa18d, 0x0012, 0x6116, 0x00b8, 0x6114, 0xa18c,
-	0x0184, 0xa18d, 0x0016, 0x6116, 0x0080, 0x0036, 0x2019, 0x0001,
-	0x080c, 0x7fe4, 0x003e, 0x2019, 0xb7ef, 0x2304, 0xa065, 0x0120,
-	0x2009, 0x004f, 0x080c, 0x864c, 0x00ce, 0x001e, 0xd19c, 0x0904,
-	0x27bf, 0x7034, 0xd0ac, 0x1560, 0x0016, 0x0156, 0x6027, 0x0008,
-	0x602f, 0x0020, 0x20a9, 0x0006, 0x1d04, 0x2774, 0x2091, 0x6000,
-	0x1f04, 0x2774, 0x602f, 0x0000, 0x6150, 0xa185, 0x1400, 0x6052,
-	0x20a9, 0x0366, 0x1d04, 0x2782, 0x2091, 0x6000, 0x6020, 0xd09c,
-	0x1130, 0x015e, 0x6152, 0x001e, 0x6027, 0x0008, 0x0480, 0x080c,
-	0x2907, 0x1f04, 0x2782, 0x015e, 0x6152, 0x001e, 0x6027, 0x0008,
-	0x0016, 0x6028, 0xc09c, 0x602a, 0x2011, 0x0003, 0x080c, 0x8075,
-	0x2011, 0x0002, 0x080c, 0x807f, 0x080c, 0x7f59, 0x0036, 0x2019,
-	0x0000, 0x080c, 0x7fe4, 0x003e, 0x60e3, 0x0000, 0x080c, 0xb42f,
-	0x080c, 0xb44a, 0xa085, 0x0001, 0x080c, 0x5b13, 0x2001, 0xb500,
-	0x2003, 0x0004, 0x6027, 0x0008, 0x080c, 0x12dd, 0x001e, 0xa18c,
-	0xffd0, 0x6126, 0x0005, 0x0006, 0x0016, 0x0026, 0x00e6, 0x00f6,
-	0x0126, 0x2091, 0x8000, 0x2071, 0xb500, 0x71c4, 0x70c6, 0xa116,
-	0x0500, 0x81ff, 0x0128, 0x2011, 0x8011, 0x080c, 0x3ecc, 0x00c8,
-	0x2011, 0x8012, 0x080c, 0x3ecc, 0x2001, 0xb572, 0x2004, 0xd0fc,
-	0x1180, 0x0036, 0x00c6, 0x080c, 0x2892, 0x080c, 0x7f35, 0x2061,
-	0x0100, 0x2019, 0x0028, 0x2009, 0x0000, 0x080c, 0x2c6f, 0x00ce,
-	0x003e, 0x012e, 0x00fe, 0x00ee, 0x002e, 0x001e, 0x000e, 0x0005,
-	0x00c6, 0x00f6, 0x0006, 0x0026, 0x2061, 0x0100, 0xa190, 0x280b,
-	0x2205, 0x60f2, 0x2011, 0x2818, 0x2205, 0x60ee, 0x002e, 0x000e,
-	0x00fe, 0x00ce, 0x0005, 0x0840, 0x0840, 0x0840, 0x0580, 0x0420,
-	0x0348, 0x02c0, 0x0258, 0x0210, 0x01a8, 0x01a8, 0x01a8, 0x01a8,
-	0x0140, 0x00f8, 0x00d0, 0x00b0, 0x00a0, 0x2028, 0xa18c, 0x00ff,
-	0x2130, 0xa094, 0xff00, 0x1110, 0x81ff, 0x0118, 0x080c, 0x66b1,
-	0x0038, 0xa080, 0x2dc4, 0x200d, 0xa18c, 0xff00, 0x810f, 0xa006,
-	0x0005, 0xa080, 0x2dc4, 0x200d, 0xa18c, 0x00ff, 0x0005, 0x00d6,
-	0x2069, 0x0140, 0x2001, 0xb515, 0x2003, 0x00ef, 0x20a9, 0x0010,
-	0xa006, 0x6852, 0x6856, 0x1f04, 0x2842, 0x00de, 0x0005, 0x0006,
-	0x00d6, 0x0026, 0x2069, 0x0140, 0x2001, 0xb515, 0x2102, 0x8114,
-	0x8214, 0x8214, 0x8214, 0x20a9, 0x0010, 0x6853, 0x0000, 0xa006,
-	0x82ff, 0x1128, 0xa184, 0x000f, 0xa080, 0xb45e, 0x2005, 0x6856,
-	0x8211, 0x1f04, 0x2857, 0x002e, 0x00de, 0x000e, 0x0005, 0x00c6,
-	0x2061, 0xb500, 0x6030, 0x0110, 0xc09d, 0x0008, 0xc09c, 0x6032,
-	0x00ce, 0x0005, 0x0156, 0x00d6, 0x0026, 0x0016, 0x0006, 0x2069,
-	0x0140, 0x6980, 0xa116, 0x0180, 0xa112, 0x1230, 0x8212, 0x8210,
-	0x22a8, 0x2001, 0x0402, 0x0018, 0x22a8, 0x2001, 0x0404, 0x680e,
-	0x1f04, 0x2887, 0x680f, 0x0000, 0x000e, 0x001e, 0x002e, 0x00de,
-	0x015e, 0x0005, 0x2001, 0xb553, 0x2004, 0xd0c4, 0x0150, 0xd0a4,
-	0x0140, 0xa006, 0x0046, 0x2020, 0x2009, 0x002e, 0x080c, 0xb0e8,
-	0x004e, 0x0005, 0x00f6, 0x0016, 0x0026, 0x2079, 0x0140, 0x78c4,
-	0xd0dc, 0x0548, 0xa084, 0x0700, 0xa08e, 0x0300, 0x1520, 0x2011,
-	0x0000, 0x2009, 0x0002, 0x2300, 0xa080, 0x0020, 0x2018, 0x2300,
-	0x080c, 0x6b40, 0x2011, 0x0030, 0x2200, 0x8007, 0xa085, 0x004c,
-	0x78c2, 0x2009, 0x0204, 0x210c, 0x2200, 0xa100, 0x2009, 0x0138,
-	0x200a, 0x080c, 0x5acf, 0x1118, 0x2009, 0xb78f, 0x200a, 0x002e,
-	0x001e, 0x00fe, 0x0005, 0x78c3, 0x0000, 0x0cc8, 0x0126, 0x2091,
-	0x2800, 0x0006, 0x0016, 0x0026, 0x2001, 0x0170, 0x200c, 0x8000,
-	0x2014, 0xa184, 0x0003, 0x0110, 0x0804, 0x1b04, 0x002e, 0x001e,
-	0x000e, 0x012e, 0x0005, 0x0006, 0x2001, 0x0100, 0x2004, 0xa082,
-	0x0005, 0x000e, 0x0268, 0x2001, 0x0170, 0x200c, 0xa18c, 0x00ff,
-	0xa18e, 0x004c, 0x1128, 0x200c, 0xa18c, 0xff00, 0x810f, 0x0010,
-	0x2009, 0x0000, 0x2001, 0x0204, 0x2004, 0xa108, 0x0005, 0x0006,
-	0x0156, 0x00f6, 0x2079, 0x0100, 0x20a9, 0x000a, 0x7854, 0xd08c,
-	0x1110, 0x1f04, 0x290e, 0x00fe, 0x015e, 0x000e, 0x0005, 0x0016,
-	0x00c6, 0x0006, 0x2061, 0x0100, 0x6030, 0x0006, 0x6048, 0x0006,
-	0x60e4, 0x0006, 0x60e8, 0x0006, 0x6050, 0x0006, 0x60f0, 0x0006,
-	0x60ec, 0x0006, 0x600c, 0x0006, 0x6004, 0x0006, 0x6028, 0x0006,
-	0x60e0, 0x0006, 0x602f, 0x0100, 0x602f, 0x0000, 0xe000, 0xe000,
-	0xe000, 0xe000, 0x602f, 0x0040, 0x602f, 0x0000, 0x000e, 0x60e2,
-	0x000e, 0x602a, 0x000e, 0x6006, 0x000e, 0x600e, 0x000e, 0x60ee,
-	0x000e, 0x60f2, 0x000e, 0x6052, 0x000e, 0x60ea, 0x000e, 0x60e6,
-	0x000e, 0x604a, 0x000e, 0x6032, 0x6036, 0x2008, 0x080c, 0x2847,
-	0x000e, 0x00ce, 0x001e, 0x0005, 0x2009, 0x0171, 0x2104, 0xd0dc,
-	0x0140, 0x2009, 0x0170, 0x2104, 0x200b, 0x0080, 0xe000, 0xe000,
-	0x200a, 0x0005, 0x29fa, 0x29fe, 0x2a02, 0x2a08, 0x2a0e, 0x2a14,
-	0x2a1a, 0x2a22, 0x2a2a, 0x2a30, 0x2a36, 0x2a3e, 0x2a46, 0x2a4e,
-	0x2a56, 0x2a60, 0x2aad, 0x2aad, 0x2aad, 0x2aad, 0x2aad, 0x2aad,
-	0x2aad, 0x2aad, 0x2aad, 0x2aad, 0x2aad, 0x2aad, 0x2aad, 0x2aad,
-	0x2aad, 0x2aad, 0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a,
-	0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a,
-	0x2a6a, 0x2a6a, 0x2aad, 0x2aad, 0x2aad, 0x2aad, 0x2aad, 0x2aad,
-	0x2aad, 0x2aad, 0x2aad, 0x2aad, 0x2aad, 0x2aad, 0x2aad, 0x2aad,
-	0x2aad, 0x2aad, 0x2a6c, 0x2a6c, 0x2a72, 0x2a72, 0x2a79, 0x2a79,
-	0x2a80, 0x2a80, 0x2a89, 0x2a89, 0x2a90, 0x2a90, 0x2a99, 0x2a99,
-	0x2aa2, 0x2aa2, 0x2aad, 0x2aad, 0x2aad, 0x2aad, 0x2aad, 0x2aad,
-	0x2aad, 0x2aad, 0x2aad, 0x2aad, 0x2aad, 0x2aad, 0x2aad, 0x2aad,
-	0x2aad, 0x2aad, 0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a,
-	0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a,
-	0x2a6a, 0x2a6a, 0x2aad, 0x2aad, 0x2aad, 0x2aad, 0x2aad, 0x2aad,
-	0x2aad, 0x2aad, 0x2aad, 0x2aad, 0x2aad, 0x2aad, 0x2aad, 0x2aad,
-	0x2aad, 0x2aad, 0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a,
-	0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a, 0x2a6a,
-	0x2a6a, 0x2a6a, 0x0106, 0x0006, 0x0804, 0x2ab5, 0x0106, 0x0006,
-	0x0804, 0x2ab5, 0x0106, 0x0006, 0x080c, 0x2519, 0x0804, 0x2ab5,
-	0x0106, 0x0006, 0x080c, 0x2519, 0x0804, 0x2ab5, 0x0106, 0x0006,
-	0x080c, 0x239c, 0x0804, 0x2ab5, 0x0106, 0x0006, 0x080c, 0x239c,
-	0x0804, 0x2ab5, 0x0106, 0x0006, 0x080c, 0x2519, 0x080c, 0x239c,
-	0x0804, 0x2ab5, 0x0106, 0x0006, 0x080c, 0x2519, 0x080c, 0x239c,
-	0x0804, 0x2ab5, 0x0106, 0x0006, 0x080c, 0x23f2, 0x0804, 0x2ab5,
-	0x0106, 0x0006, 0x080c, 0x23f2, 0x0804, 0x2ab5, 0x0106, 0x0006,
-	0x080c, 0x2519, 0x080c, 0x23f2, 0x0804, 0x2ab5, 0x0106, 0x0006,
-	0x080c, 0x2519, 0x080c, 0x23f2, 0x0804, 0x2ab5, 0x0106, 0x0006,
-	0x080c, 0x239c, 0x080c, 0x23f2, 0x0804, 0x2ab5, 0x0106, 0x0006,
-	0x080c, 0x239c, 0x080c, 0x23f2, 0x0804, 0x2ab5, 0x0106, 0x0006,
-	0x080c, 0x2519, 0x080c, 0x239c, 0x080c, 0x23f2, 0x0804, 0x2ab5,
-	0x0106, 0x0006, 0x080c, 0x2519, 0x080c, 0x239c, 0x080c, 0x23f2,
-	0x0804, 0x2ab5, 0xe000, 0x0cf0, 0x0106, 0x0006, 0x080c, 0x28d6,
-	0x0804, 0x2ab5, 0x0106, 0x0006, 0x080c, 0x28d6, 0x080c, 0x2519,
-	0x04e0, 0x0106, 0x0006, 0x080c, 0x28d6, 0x080c, 0x239c, 0x04a8,
-	0x0106, 0x0006, 0x080c, 0x28d6, 0x080c, 0x2519, 0x080c, 0x239c,
-	0x0460, 0x0106, 0x0006, 0x080c, 0x28d6, 0x080c, 0x23f2, 0x0428,
-	0x0106, 0x0006, 0x080c, 0x28d6, 0x080c, 0x2519, 0x080c, 0x23f2,
-	0x00e0, 0x0106, 0x0006, 0x080c, 0x28d6, 0x080c, 0x239c, 0x080c,
-	0x23f2, 0x0098, 0x0106, 0x0006, 0x080c, 0x28d6, 0x080c, 0x2519,
-	0x080c, 0x239c, 0x080c, 0x23f2, 0x0040, 0x20d1, 0x0000, 0x20d1,
-	0x0001, 0x20d1, 0x0000, 0x080c, 0x1515, 0x000e, 0x010e, 0x000d,
-	0x00c6, 0x0026, 0x0046, 0x2021, 0x0000, 0x080c, 0x5309, 0x1904,
-	0x2b95, 0x72d4, 0x2001, 0xb79e, 0x2004, 0xa005, 0x1110, 0xd29c,
-	0x0148, 0xd284, 0x1138, 0xd2bc, 0x1904, 0x2b95, 0x080c, 0x2b99,
-	0x0804, 0x2b95, 0xd2cc, 0x1904, 0x2b95, 0x080c, 0x5acf, 0x1120,
-	0x709f, 0xffff, 0x0804, 0x2b95, 0xd294, 0x0120, 0x709f, 0xffff,
-	0x0804, 0x2b95, 0x2001, 0xb515, 0x203c, 0x7288, 0xd284, 0x0904,
-	0x2b37, 0xd28c, 0x1904, 0x2b37, 0x0036, 0x739c, 0xa38e, 0xffff,
-	0x1110, 0x2019, 0x0001, 0x8314, 0xa2e0, 0xbcc0, 0x2c04, 0xa38c,
-	0x0001, 0x0120, 0xa084, 0xff00, 0x8007, 0x0010, 0xa084, 0x00ff,
-	0xa70e, 0x0560, 0xa08e, 0x0000, 0x0548, 0xa08e, 0x00ff, 0x1150,
-	0x7230, 0xd284, 0x1538, 0x7288, 0xc28d, 0x728a, 0x709f, 0xffff,
-	0x003e, 0x0428, 0x2009, 0x0000, 0x080c, 0x281d, 0x080c, 0x4f4d,
-	0x11b8, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x1150, 0x7030,
-	0xd08c, 0x0118, 0x6000, 0xd0bc, 0x0120, 0x080c, 0x2bac, 0x0140,
-	0x0028, 0x080c, 0x2cdd, 0x080c, 0x2bda, 0x0110, 0x8318, 0x0818,
-	0x739e, 0x0010, 0x709f, 0xffff, 0x003e, 0x0804, 0x2b95, 0xa780,
-	0x2dc4, 0x203d, 0xa7bc, 0xff00, 0x873f, 0x2041, 0x007e, 0x709c,
-	0xa096, 0xffff, 0x1120, 0x2009, 0x0000, 0x28a8, 0x0050, 0xa812,
-	0x0220, 0x2008, 0xa802, 0x20a8, 0x0020, 0x709f, 0xffff, 0x0804,
-	0x2b95, 0x2700, 0x0156, 0x0016, 0xa106, 0x05a0, 0xc484, 0x080c,
-	0x4fa9, 0x0120, 0x080c, 0x4f4d, 0x15a8, 0x0008, 0xc485, 0x6004,
-	0xa084, 0x00ff, 0xa086, 0x0006, 0x1130, 0x7030, 0xd08c, 0x01e8,
-	0x6000, 0xd0bc, 0x11d0, 0x7288, 0xd28c, 0x0188, 0x6004, 0xa084,
-	0x00ff, 0xa082, 0x0006, 0x02b0, 0xd484, 0x1118, 0x080c, 0x4f6c,
-	0x0028, 0x080c, 0x2d6a, 0x0170, 0x080c, 0x2d97, 0x0058, 0x080c,
-	0x2cdd, 0x080c, 0x2bda, 0x0170, 0x0028, 0x080c, 0x2d6a, 0x0110,
-	0x0419, 0x0140, 0x001e, 0x8108, 0x015e, 0x1f04, 0x2b51, 0x709f,
-	0xffff, 0x0018, 0x001e, 0x015e, 0x719e, 0x004e, 0x002e, 0x00ce,
-	0x0005, 0x00c6, 0x0016, 0x709f, 0x0001, 0x2009, 0x007e, 0x080c,
-	0x4f4d, 0x1138, 0x080c, 0x2cdd, 0x04a9, 0x0118, 0x70d4, 0xc0bd,
-	0x70d6, 0x001e, 0x00ce, 0x0005, 0x0016, 0x0076, 0x00d6, 0x00c6,
-	0x2c68, 0x2001, 0xb557, 0x2004, 0xa084, 0x00ff, 0x6842, 0x080c,
-	0x9ed6, 0x01d8, 0x2d00, 0x601a, 0x080c, 0xa027, 0x601f, 0x0001,
-	0x2001, 0x0000, 0x080c, 0x4eeb, 0x2001, 0x0000, 0x080c, 0x4efd,
-	0x0126, 0x2091, 0x8000, 0x7098, 0x8000, 0x709a, 0x012e, 0x2009,
-	0x0004, 0x080c, 0x864c, 0xa085, 0x0001, 0x00ce, 0x00de, 0x007e,
-	0x001e, 0x0005, 0x0016, 0x0076, 0x00d6, 0x00c6, 0x2c68, 0x2001,
-	0xb557, 0x2004, 0xa084, 0x00ff, 0x6842, 0x080c, 0x9ed6, 0x0550,
-	0x2d00, 0x601a, 0x6800, 0xc0c4, 0x6802, 0x68a0, 0xa086, 0x007e,
-	0x0140, 0x6804, 0xa084, 0x00ff, 0xa086, 0x0006, 0x1110, 0x080c,
-	0x2c9c, 0x080c, 0xa027, 0x601f, 0x0001, 0x2001, 0x0000, 0x080c,
-	0x4eeb, 0x2001, 0x0002, 0x080c, 0x4efd, 0x0126, 0x2091, 0x8000,
-	0x7098, 0x8000, 0x709a, 0x012e, 0x2009, 0x0002, 0x080c, 0x864c,
-	0xa085, 0x0001, 0x00ce, 0x00de, 0x007e, 0x001e, 0x0005, 0x00c6,
-	0x0026, 0x2009, 0x0080, 0x080c, 0x4f4d, 0x1120, 0x0031, 0x0110,
-	0x70db, 0xffff, 0x002e, 0x00ce, 0x0005, 0x0016, 0x0076, 0x00d6,
-	0x00c6, 0x2c68, 0x080c, 0x85c7, 0x01e8, 0x2d00, 0x601a, 0x080c,
-	0xa027, 0x601f, 0x0001, 0x2001, 0x0000, 0x080c, 0x4eeb, 0x2001,
-	0x0002, 0x080c, 0x4efd, 0x0126, 0x2091, 0x8000, 0x080c, 0x2c9c,
-	0x70dc, 0x8000, 0x70de, 0x012e, 0x2009, 0x0002, 0x080c, 0x864c,
-	0xa085, 0x0001, 0x00ce, 0x00de, 0x007e, 0x001e, 0x0005, 0x00c6,
-	0x00d6, 0x0126, 0x2091, 0x8000, 0x2009, 0x007f, 0x080c, 0x4f4d,
-	0x1190, 0x2c68, 0x080c, 0x85c7, 0x0170, 0x2d00, 0x601a, 0x6312,
-	0x601f, 0x0001, 0x620a, 0x080c, 0xa027, 0x2009, 0x0022, 0x080c,
-	0x864c, 0xa085, 0x0001, 0x012e, 0x00de, 0x00ce, 0x0005, 0x00e6,
-	0x00c6, 0x0066, 0x0036, 0x0026, 0x080c, 0x6e01, 0x080c, 0x6da4,
-	0x080c, 0x906f, 0x2130, 0x81ff, 0x0128, 0x20a9, 0x007e, 0x2009,
-	0x0000, 0x0020, 0x20a9, 0x007f, 0x2009, 0x0000, 0x0016, 0x080c,
-	0x4fa9, 0x1120, 0x080c, 0x51aa, 0x080c, 0x4c0b, 0x001e, 0x8108,
-	0x1f04, 0x2c86, 0x86ff, 0x1110, 0x080c, 0x11f0, 0x002e, 0x003e,
-	0x006e, 0x00ce, 0x00ee, 0x0005, 0x00e6, 0x00c6, 0x0036, 0x0026,
-	0x0016, 0x6218, 0x2270, 0x72a0, 0x0026, 0x2019, 0x0029, 0x080c,
-	0x6df5, 0x0076, 0x2039, 0x0000, 0x080c, 0x6d02, 0x2c08, 0x080c,
-	0xae82, 0x007e, 0x001e, 0x2e60, 0x080c, 0x51aa, 0x6210, 0x6314,
-	0x080c, 0x4c0b, 0x6212, 0x6316, 0x001e, 0x002e, 0x003e, 0x00ce,
-	0x00ee, 0x0005, 0x00e6, 0x0006, 0x6018, 0xa080, 0x0028, 0x2004,
-	0xa086, 0x0080, 0x0150, 0x2071, 0xb500, 0x7098, 0xa005, 0x0110,
-	0x8001, 0x709a, 0x000e, 0x00ee, 0x0005, 0x2071, 0xb500, 0x70dc,
-	0xa005, 0x0dc0, 0x8001, 0x70de, 0x0ca8, 0x6000, 0xc08c, 0x6002,
-	0x0005, 0x00f6, 0x00e6, 0x00c6, 0x0036, 0x0026, 0x0016, 0x0156,
-	0x2178, 0x81ff, 0x1118, 0x20a9, 0x0001, 0x0098, 0x2001, 0xb553,
-	0x2004, 0xd0c4, 0x0150, 0xd0a4, 0x0140, 0xa006, 0x0046, 0x2020,
-	0x2009, 0x002d, 0x080c, 0xb0e8, 0x004e, 0x20a9, 0x00ff, 0x2011,
-	0x0000, 0x0026, 0xa28e, 0x007e, 0x0904, 0x2d49, 0xa28e, 0x007f,
-	0x0904, 0x2d49, 0xa28e, 0x0080, 0x05e0, 0xa288, 0xb635, 0x210c,
-	0x81ff, 0x05b8, 0x8fff, 0x1148, 0x2001, 0xb7be, 0x0006, 0x2003,
-	0x0001, 0x04d9, 0x000e, 0x2003, 0x0000, 0x00c6, 0x2160, 0x2001,
-	0x0001, 0x080c, 0x5313, 0x00ce, 0x2019, 0x0029, 0x080c, 0x6df5,
-	0x0076, 0x2039, 0x0000, 0x080c, 0x6d02, 0x00c6, 0x0026, 0x2160,
-	0x6204, 0xa294, 0x00ff, 0xa286, 0x0006, 0x1118, 0x6007, 0x0404,
-	0x0028, 0x2001, 0x0004, 0x8007, 0xa215, 0x6206, 0x002e, 0x00ce,
-	0x0016, 0x2c08, 0x080c, 0xae82, 0x001e, 0x007e, 0x2160, 0x080c,
-	0x51aa, 0x002e, 0x8210, 0x1f04, 0x2d01, 0x015e, 0x001e, 0x002e,
-	0x003e, 0x00ce, 0x00ee, 0x00fe, 0x0005, 0x0046, 0x0026, 0x0016,
-	0x2001, 0xb553, 0x2004, 0xd0c4, 0x0148, 0xd0a4, 0x0138, 0xa006,
-	0x2220, 0x8427, 0x2009, 0x0029, 0x080c, 0xb0e8, 0x001e, 0x002e,
-	0x004e, 0x0005, 0x0016, 0x0026, 0x0036, 0x00c6, 0x7288, 0x82ff,
-	0x01f8, 0x2011, 0xb553, 0x2214, 0xd2ac, 0x11d0, 0x2100, 0x080c,
-	0x2831, 0x81ff, 0x01b8, 0x2019, 0x0001, 0x8314, 0xa2e0, 0xbcc0,
-	0x2c04, 0xd384, 0x0120, 0xa084, 0xff00, 0x8007, 0x0010, 0xa084,
-	0x00ff, 0xa116, 0x0138, 0xa096, 0x00ff, 0x0110, 0x8318, 0x0c68,
-	0xa085, 0x0001, 0x00ce, 0x003e, 0x002e, 0x001e, 0x0005, 0x0016,
-	0x00c6, 0x0126, 0x2091, 0x8000, 0x0016, 0x0026, 0x0036, 0x2110,
-	0x0026, 0x2019, 0x0029, 0x080c, 0x8299, 0x002e, 0x080c, 0xb38d,
-	0x003e, 0x002e, 0x001e, 0xa180, 0xb635, 0x2004, 0xa065, 0x0158,
-	0x0016, 0x00c6, 0x2061, 0xb8f4, 0x001e, 0x611a, 0x080c, 0x2c9c,
-	0x001e, 0x080c, 0x4f6c, 0x012e, 0x00ce, 0x001e, 0x0005, 0x2001,
-	0xb535, 0x2004, 0xd0cc, 0x0005, 0x7eef, 0x7de8, 0x7ce4, 0x80e2,
-	0x7be1, 0x80e0, 0x80dc, 0x80da, 0x7ad9, 0x80d6, 0x80d5, 0x80d4,
-	0x80d3, 0x80d2, 0x80d1, 0x79ce, 0x78cd, 0x80cc, 0x80cb, 0x80ca,
-	0x80c9, 0x80c7, 0x80c6, 0x77c5, 0x76c3, 0x80bc, 0x80ba, 0x75b9,
-	0x80b6, 0x74b5, 0x73b4, 0x72b3, 0x80b2, 0x80b1, 0x80ae, 0x71ad,
-	0x80ac, 0x70ab, 0x6faa, 0x6ea9, 0x80a7, 0x6da6, 0x6ca5, 0x6ba3,
-	0x6a9f, 0x699e, 0x689d, 0x809b, 0x8098, 0x6797, 0x6690, 0x658f,
-	0x6488, 0x6384, 0x6282, 0x8081, 0x8080, 0x617c, 0x607a, 0x8079,
-	0x5f76, 0x8075, 0x8074, 0x8073, 0x8072, 0x8071, 0x806e, 0x5e6d,
-	0x806c, 0x5d6b, 0x5c6a, 0x5b69, 0x8067, 0x5a66, 0x5965, 0x5863,
-	0x575c, 0x565a, 0x5559, 0x8056, 0x8055, 0x5454, 0x5353, 0x5252,
-	0x5151, 0x504e, 0x4f4d, 0x804c, 0x804b, 0x4e4a, 0x4d49, 0x8047,
-	0x4c46, 0x8045, 0x8043, 0x803c, 0x803a, 0x8039, 0x8036, 0x4b35,
-	0x8034, 0x4a33, 0x4932, 0x4831, 0x802e, 0x472d, 0x462c, 0x452b,
-	0x442a, 0x4329, 0x4227, 0x8026, 0x8025, 0x4123, 0x401f, 0x3f1e,
-	0x3e1d, 0x3d1b, 0x3c18, 0x8017, 0x8010, 0x3b0f, 0x3a08, 0x8004,
-	0x3902, 0x8001, 0x8000, 0x8000, 0x3800, 0x3700, 0x3600, 0x8000,
-	0x3500, 0x8000, 0x8000, 0x8000, 0x3400, 0x8000, 0x8000, 0x8000,
-	0x8000, 0x8000, 0x8000, 0x3300, 0x3200, 0x8000, 0x8000, 0x8000,
-	0x8000, 0x8000, 0x8000, 0x3100, 0x3000, 0x8000, 0x8000, 0x2f00,
-	0x8000, 0x2e00, 0x2d00, 0x2c00, 0x8000, 0x8000, 0x8000, 0x2b00,
-	0x8000, 0x2a00, 0x2900, 0x2800, 0x8000, 0x2700, 0x2600, 0x2500,
-	0x2400, 0x2300, 0x2200, 0x8000, 0x8000, 0x2100, 0x2000, 0x1f00,
-	0x1e00, 0x1d00, 0x1c00, 0x8000, 0x8000, 0x1b00, 0x1a00, 0x8000,
-	0x1900, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x1800,
-	0x8000, 0x1700, 0x1600, 0x1500, 0x8000, 0x1400, 0x1300, 0x1200,
-	0x1100, 0x1000, 0x0f00, 0x8000, 0x8000, 0x0e00, 0x0d00, 0x0c00,
-	0x0b00, 0x0a00, 0x0900, 0x8000, 0x8000, 0x0800, 0x0700, 0x8000,
-	0x0600, 0x8000, 0x8000, 0x8000, 0x0500, 0x0400, 0x0300, 0x8000,
-	0x0200, 0x8000, 0x8000, 0x8000, 0x0100, 0x8000, 0x8000, 0x8000,
-	0x8000, 0x8000, 0x8000, 0x0000, 0x8000, 0x8000, 0x8000, 0x8000,
+	0x2a70, 0x7000, 0xa08e, 0x0003, 0x1158, 0x080c, 0x3f4f, 0x080c,
+	0x2f20, 0x080c, 0x5e4a, 0x080c, 0x5562, 0x080c, 0x696b, 0x0c80,
+	0x000b, 0x0c98, 0x10e4, 0x10e5, 0x1215, 0x10e2, 0x12e2, 0x1413,
+	0x1414, 0x1415, 0x080c, 0x151a, 0x0005, 0x0126, 0x00f6, 0x2091,
+	0x8000, 0x7000, 0xa086, 0x0001, 0x1904, 0x11f2, 0x080c, 0x158d,
+	0x080c, 0x5b41, 0x0150, 0x080c, 0x5b67, 0x15c0, 0x2079, 0x0100,
+	0x7828, 0xa085, 0x1800, 0x782a, 0x0488, 0x080c, 0x5a79, 0x7000,
+	0xa086, 0x0001, 0x1904, 0x11f2, 0x708c, 0xa086, 0x0028, 0x1904,
+	0x11f2, 0x2001, 0x0161, 0x2003, 0x0001, 0x2079, 0x0100, 0x7827,
+	0xffff, 0x7a28, 0xa295, 0x1e2f, 0x7a2a, 0x2011, 0x5a14, 0x080c,
+	0x6a0e, 0x2011, 0x5a07, 0x080c, 0x6ace, 0x2011, 0x5a56, 0x080c,
+	0x6a0e, 0x2011, 0x4b23, 0x080c, 0x6a0e, 0x2011, 0x8030, 0x2019,
+	0x0000, 0x708b, 0x0000, 0x080c, 0x1e05, 0x00e8, 0x080c, 0x44d6,
+	0x2079, 0x0100, 0x7844, 0xa005, 0x1904, 0x11f2, 0x2011, 0x4b23,
+	0x080c, 0x6a0e, 0x2011, 0x5a56, 0x080c, 0x6a0e, 0x080c, 0x1e05,
+	0x2001, 0xb88d, 0x2004, 0x780e, 0x7840, 0xa084, 0xfffb, 0x7842,
+	0x2011, 0x8010, 0x73cc, 0x080c, 0x3f13, 0x723c, 0xc284, 0x723e,
+	0x2001, 0xb60c, 0x200c, 0xc1ac, 0x2102, 0x080c, 0x7fbc, 0x2011,
+	0x0004, 0x080c, 0x9d1c, 0x080c, 0x52bf, 0x080c, 0x5b41, 0x0158,
+	0x080c, 0x4c4a, 0x0140, 0x708b, 0x0001, 0x70c7, 0x0000, 0x080c,
+	0x4673, 0x0804, 0x11f2, 0x080c, 0x537b, 0x0120, 0x7a0c, 0xc2b4,
+	0x7a0e, 0x0060, 0x7073, 0x0000, 0x080c, 0xa0c4, 0x70d4, 0xd09c,
+	0x1128, 0x70a0, 0xa005, 0x0110, 0x080c, 0x4c28, 0x70df, 0x0000,
+	0x70db, 0x0000, 0x72d4, 0x080c, 0x5b41, 0x1180, 0x2011, 0x0000,
+	0x0016, 0x080c, 0x2920, 0x2019, 0xb88f, 0x211a, 0x001e, 0x7053,
+	0xffff, 0x7057, 0x00ef, 0x7077, 0x0000, 0x0020, 0x2019, 0xb88f,
+	0x201b, 0x0000, 0x2079, 0xb652, 0x7804, 0xd0ac, 0x0108, 0xc295,
+	0x72d6, 0x080c, 0x5b41, 0x0118, 0xa296, 0x0004, 0x0548, 0x2011,
+	0x0001, 0x080c, 0x9d1c, 0x709b, 0x0000, 0x709f, 0xffff, 0x7003,
+	0x0002, 0x2079, 0x0100, 0x7827, 0x0003, 0x7828, 0xa085, 0x0003,
+	0x782a, 0x00fe, 0x080c, 0x2aed, 0x2011, 0x0005, 0x080c, 0x80fc,
+	0x080c, 0x71e5, 0x080c, 0x5b41, 0x0148, 0x00c6, 0x2061, 0x0100,
+	0x0016, 0x080c, 0x2920, 0x61e2, 0x001e, 0x00ce, 0x012e, 0x0420,
+	0x709b, 0x0000, 0x709f, 0xffff, 0x7003, 0x0002, 0x00f6, 0x2079,
+	0x0100, 0x7827, 0x0003, 0x7828, 0xa085, 0x0003, 0x782a, 0x00fe,
+	0x2011, 0x0005, 0x080c, 0x80fc, 0x080c, 0x71e5, 0x080c, 0x5b41,
+	0x0148, 0x00c6, 0x2061, 0x0100, 0x0016, 0x080c, 0x2920, 0x61e2,
+	0x001e, 0x00ce, 0x00fe, 0x012e, 0x0005, 0x00c6, 0x080c, 0x5b41,
+	0x1118, 0x20a9, 0x0100, 0x0010, 0x20a9, 0x0082, 0x080c, 0x5b41,
+	0x1118, 0x2009, 0x0000, 0x0010, 0x2009, 0x007e, 0x080c, 0x2dcc,
+	0x8108, 0x1f04, 0x1206, 0x00ce, 0x7073, 0x0000, 0x7074, 0xa084,
+	0x00ff, 0x7076, 0x70a3, 0x0000, 0x0005, 0x0126, 0x2091, 0x8000,
+	0x7000, 0xa086, 0x0002, 0x1904, 0x12e0, 0x709c, 0xa086, 0xffff,
+	0x0130, 0x080c, 0x2aed, 0x080c, 0x71e5, 0x0804, 0x12e0, 0x70d4,
+	0xd0ac, 0x1110, 0xd09c, 0x0540, 0xd084, 0x0530, 0x0006, 0x0016,
+	0x2001, 0x0103, 0x2009, 0xb88d, 0x210c, 0x2102, 0x001e, 0x000e,
+	0xd08c, 0x01d0, 0x70d8, 0xa086, 0xffff, 0x0190, 0x080c, 0x2c4c,
+	0x080c, 0x71e5, 0x70d4, 0xd094, 0x1904, 0x12e0, 0x2011, 0x0001,
+	0x2019, 0x0000, 0x080c, 0x2c84, 0x080c, 0x71e5, 0x0804, 0x12e0,
+	0x70dc, 0xa005, 0x1904, 0x12e0, 0x7098, 0xa005, 0x1904, 0x12e0,
+	0x70d4, 0xd0a4, 0x0118, 0xd0b4, 0x0904, 0x12e0, 0x080c, 0x537b,
+	0x1904, 0x12e0, 0x2001, 0xb653, 0x2004, 0xd0ac, 0x01c8, 0x0156,
+	0x00c6, 0x20a9, 0x007f, 0x2009, 0x0000, 0x0016, 0x080c, 0x501b,
+	0x1118, 0x6000, 0xd0ec, 0x1138, 0x001e, 0x8108, 0x1f04, 0x126d,
+	0x00ce, 0x015e, 0x0028, 0x001e, 0x00ce, 0x015e, 0x0804, 0x12e0,
+	0x0006, 0x0016, 0x2001, 0x0103, 0x2009, 0xb88d, 0x210c, 0x2102,
+	0x001e, 0x000e, 0x71a8, 0x81ff, 0x11b0, 0xa006, 0x2009, 0x0200,
+	0x20a9, 0x0002, 0x20a1, 0xb8df, 0x40a1, 0x2009, 0x0700, 0x20a9,
+	0x0002, 0x20a1, 0xb8cf, 0x40a1, 0x7070, 0x8007, 0x7174, 0x810f,
+	0x20a9, 0x0002, 0x40a1, 0x20a1, 0xb8d3, 0x2009, 0x0000, 0x080c,
+	0x1500, 0x2001, 0x0000, 0x810f, 0x20a9, 0x0002, 0x40a1, 0x7030,
+	0xc08c, 0x7032, 0x7003, 0x0003, 0x709f, 0xffff, 0x080c, 0x1586,
+	0xa006, 0x080c, 0x27f8, 0x080c, 0x3f85, 0x00f6, 0x2079, 0x0100,
+	0x080c, 0x5b67, 0x0150, 0x080c, 0x5b41, 0x7828, 0x0118, 0xa084,
+	0xe1ff, 0x0010, 0xa084, 0xffdf, 0x782a, 0x00fe, 0x2001, 0xb8e2,
+	0x2004, 0xa086, 0x0005, 0x1120, 0x2011, 0x0000, 0x080c, 0x80fc,
+	0x2011, 0x0000, 0x080c, 0x8106, 0x080c, 0x71e5, 0x080c, 0x72a2,
+	0x012e, 0x0005, 0x0016, 0x0046, 0x00f6, 0x0126, 0x2091, 0x8000,
+	0x2079, 0x0100, 0x2009, 0xb634, 0x2104, 0xa005, 0x1110, 0x080c,
+	0x294c, 0x2009, 0x00f7, 0x080c, 0x4c11, 0x7940, 0xa18c, 0x0010,
+	0x7942, 0x7924, 0xd1b4, 0x0110, 0x7827, 0x0040, 0xd19c, 0x0110,
+	0x7827, 0x0008, 0x0006, 0x0036, 0x0156, 0x7954, 0xd1ac, 0x1904,
+	0x1350, 0x080c, 0x5b53, 0x0158, 0x080c, 0x5b67, 0x1128, 0x2001,
+	0xb89e, 0x2003, 0x0000, 0x0070, 0x080c, 0x5b49, 0x0dc0, 0x2001,
+	0xb89e, 0x2003, 0xaaaa, 0x2001, 0xb89f, 0x2003, 0x0001, 0x080c,
+	0x5a79, 0x0058, 0x080c, 0x5b41, 0x0140, 0x2009, 0x00f8, 0x080c,
+	0x4c11, 0x7843, 0x0090, 0x7843, 0x0010, 0x20a9, 0x09c4, 0x7820,
+	0xd09c, 0x1138, 0x080c, 0x5b41, 0x0138, 0x7824, 0xd0ac, 0x1904,
+	0x13fa, 0x1f04, 0x132f, 0x0070, 0x7824, 0x080c, 0x5b5d, 0x0118,
+	0xd0ac, 0x1904, 0x13fa, 0xa084, 0x1800, 0x0d98, 0x7003, 0x0001,
+	0x0804, 0x13fa, 0x2001, 0x0001, 0x080c, 0x27f8, 0x0804, 0x1409,
+	0x7850, 0xa084, 0x0180, 0x7852, 0x782f, 0x0020, 0x20a9, 0x0046,
+	0x1d04, 0x1358, 0x080c, 0x6ab6, 0x1f04, 0x1358, 0x7850, 0xa084,
+	0x0180, 0xa085, 0x0400, 0x7852, 0x782f, 0x0000, 0x080c, 0x5b53,
+	0x0158, 0x080c, 0x5b67, 0x1128, 0x2001, 0xb89e, 0x2003, 0x0000,
+	0x0070, 0x080c, 0x5b49, 0x0dc0, 0x2001, 0xb89e, 0x2003, 0xaaaa,
+	0x2001, 0xb89f, 0x2003, 0x0001, 0x080c, 0x5a79, 0x0020, 0x2009,
+	0x00f8, 0x080c, 0x4c11, 0x20a9, 0x000e, 0xe000, 0x1f04, 0x1385,
+	0x7850, 0xa084, 0x0180, 0xa085, 0x1400, 0x7852, 0x080c, 0x5b41,
+	0x0120, 0x7843, 0x0090, 0x7843, 0x0010, 0x2021, 0xe678, 0x2019,
+	0xea60, 0x7820, 0xd09c, 0x1558, 0x080c, 0x5b41, 0x05d8, 0x7824,
+	0xd0ac, 0x1904, 0x13fa, 0x080c, 0x5b67, 0x1508, 0x0046, 0x2021,
+	0x0190, 0x8421, 0x1df0, 0x004e, 0x8421, 0x11c8, 0x7827, 0x0048,
+	0x20a9, 0x01f4, 0x1d04, 0x13b2, 0x080c, 0x6ab6, 0x1f04, 0x13b2,
+	0x7824, 0xa084, 0x0068, 0x15c8, 0x2001, 0xb89e, 0x2003, 0xaaaa,
+	0x2001, 0xb89f, 0x2003, 0x0001, 0x7003, 0x0001, 0x0498, 0x1d04,
+	0x13cb, 0x080c, 0x6ab6, 0x8319, 0x1960, 0x2009, 0xb634, 0x2104,
+	0x8000, 0x200a, 0xa084, 0xfff0, 0x0120, 0x200b, 0x0000, 0x080c,
+	0x294c, 0x00d8, 0x080c, 0x5b53, 0x1140, 0xa4a2, 0x0064, 0x1128,
+	0x080c, 0x5b18, 0x7003, 0x0001, 0x00a8, 0x7827, 0x1800, 0xe000,
+	0xe000, 0x7824, 0x080c, 0x5b5d, 0x0110, 0xd0ac, 0x1158, 0xa084,
+	0x1800, 0x09a8, 0x7003, 0x0001, 0x0028, 0x2001, 0x0001, 0x080c,
+	0x27f8, 0x0048, 0x2001, 0xb634, 0x2003, 0x0000, 0x7827, 0x0048,
+	0x7828, 0xc09d, 0x782a, 0x7850, 0xa084, 0x0180, 0xa085, 0x0400,
+	0x7852, 0x015e, 0x003e, 0x000e, 0x080c, 0x155d, 0x012e, 0x00fe,
+	0x004e, 0x001e, 0x0005, 0x0005, 0x0005, 0x0005, 0x2a70, 0x2061,
+	0xb8c2, 0x2063, 0x0002, 0x6007, 0x0002, 0x600b, 0x0008, 0x600f,
+	0x0017, 0x2001, 0xb89e, 0x2003, 0x0000, 0x708b, 0x0000, 0x2009,
+	0x0100, 0x2104, 0xa082, 0x0002, 0x0218, 0x7053, 0xffff, 0x0010,
+	0x7053, 0x0000, 0x705b, 0xffff, 0x7073, 0x0000, 0x7077, 0x0000,
+	0x080c, 0xa0c4, 0x2061, 0xb88e, 0x6003, 0x0909, 0x6007, 0x0000,
+	0x600b, 0x8800, 0x600f, 0x0200, 0x6013, 0x00ff, 0x6017, 0x000f,
+	0x601b, 0x0000, 0x601f, 0x07d0, 0x2061, 0xb896, 0x6003, 0x8000,
+	0x6007, 0x0000, 0x600b, 0x0000, 0x600f, 0x0200, 0x6013, 0x00ff,
+	0x6017, 0x0000, 0x601b, 0x0001, 0x601f, 0x0000, 0x2061, 0xb8b9,
+	0x6003, 0x514c, 0x6007, 0x4f47, 0x600b, 0x4943, 0x600f, 0x2020,
+	0x2001, 0xb628, 0x2003, 0x0000, 0x0005, 0x04a0, 0x2011, 0x0000,
+	0x81ff, 0x0570, 0xa186, 0x0001, 0x1148, 0x2031, 0x8fff, 0x2039,
+	0xd601, 0x2021, 0x0100, 0x2029, 0xd600, 0x00e8, 0xa186, 0x0002,
+	0x1118, 0x2011, 0x0000, 0x00b8, 0xa186, 0x0005, 0x1118, 0x2011,
+	0x0001, 0x0088, 0xa186, 0x0009, 0x1118, 0x2011, 0x0002, 0x0058,
+	0xa186, 0x000a, 0x1118, 0x2011, 0x0002, 0x0028, 0xa186, 0x0055,
+	0x1110, 0x2011, 0x0003, 0x3800, 0xa084, 0xfffc, 0xa205, 0x20c0,
+	0x0804, 0x104d, 0xa00e, 0x2011, 0x0003, 0x2019, 0x14a9, 0x0804,
+	0x14fa, 0x2019, 0xaaaa, 0x2061, 0xffff, 0x2c14, 0x2362, 0xe000,
+	0xe000, 0x2c04, 0xa306, 0x2262, 0x1110, 0xc1b5, 0xc1a5, 0x2011,
+	0x0000, 0x2019, 0x14bc, 0x04f0, 0x2019, 0xaaaa, 0x2061, 0xffff,
+	0x2c14, 0x2362, 0xe000, 0xe000, 0x2c1c, 0x2061, 0x7fff, 0xe000,
+	0xe000, 0x2c04, 0x2061, 0xffff, 0x2262, 0xa306, 0x0110, 0xc18d,
+	0x0008, 0xc185, 0x2011, 0x0002, 0x2019, 0x14d7, 0x0418, 0x2061,
+	0xffff, 0x2019, 0xaaaa, 0x2c14, 0x2362, 0xe000, 0xe000, 0x2c04,
+	0x2262, 0xa306, 0x1180, 0x2c14, 0x2362, 0xe000, 0xe000, 0x2c1c,
+	0x2061, 0x7fff, 0x2c04, 0x2061, 0xffff, 0x2262, 0xa306, 0x1110,
+	0xc195, 0x0008, 0xc19d, 0x2011, 0x0001, 0x2019, 0x14f8, 0x0010,
+	0x0804, 0x146e, 0x3800, 0xa084, 0xfffc, 0xa205, 0x20c0, 0x0837,
+	0x2011, 0x0000, 0x080c, 0x501b, 0x1178, 0x6004, 0xa0c4, 0x00ff,
+	0xa8c6, 0x0006, 0x0128, 0xa0c4, 0xff00, 0xa8c6, 0x0600, 0x1120,
+	0xa186, 0x0080, 0x0108, 0x8210, 0x8108, 0xa186, 0x0100, 0x1d50,
+	0x2208, 0x0005, 0x2091, 0x8000, 0x0e04, 0x151c, 0x0006, 0x0016,
+	0x2079, 0x0000, 0x7818, 0xd084, 0x1de8, 0x001e, 0x792e, 0x000e,
+	0x782a, 0x000e, 0x7826, 0x3900, 0x783a, 0x7823, 0x8002, 0x781b,
+	0x0001, 0x2091, 0x5000, 0x0126, 0x0156, 0x0146, 0x20a9, 0x0010,
+	0x20a1, 0xba0d, 0x2091, 0x2000, 0x40a1, 0x20a9, 0x0010, 0x2091,
+	0x2200, 0x40a1, 0x20a9, 0x0010, 0x2091, 0x2400, 0x40a1, 0x20a9,
+	0x0010, 0x2091, 0x2600, 0x40a1, 0x20a9, 0x0010, 0x2091, 0x2800,
+	0x40a1, 0x014e, 0x015e, 0x012e, 0x2079, 0xb600, 0x7803, 0x0005,
+	0x2091, 0x4080, 0x04c9, 0x0cf8, 0x0005, 0x0006, 0x080c, 0x15a8,
+	0x1518, 0x00f6, 0x2079, 0xb624, 0x2f04, 0x8000, 0x207a, 0xa082,
+	0x000f, 0x0258, 0xa006, 0x207a, 0x2079, 0xb626, 0x2f04, 0xa084,
+	0x0001, 0xa086, 0x0001, 0x207a, 0x0070, 0x2079, 0xb626, 0x2f7c,
+	0x8fff, 0x1128, 0x2001, 0x0c03, 0x2003, 0x0040, 0x0020, 0x2001,
+	0x0c03, 0x2003, 0x00c0, 0x00fe, 0x000e, 0x0005, 0x0409, 0x1120,
+	0x2001, 0x0c03, 0x2003, 0x0080, 0x0005, 0x00d1, 0x1120, 0x2001,
+	0x0c03, 0x2003, 0x0040, 0x0005, 0x0006, 0x0091, 0x1178, 0x2001,
+	0x0c03, 0x2003, 0x0040, 0x2009, 0x0fff, 0x00a1, 0x2001, 0x0c03,
+	0x2003, 0x0080, 0x2009, 0x0fff, 0x0069, 0x0c88, 0x000e, 0x0005,
+	0x00c6, 0x2061, 0x0c00, 0x2c04, 0xa084, 0x00ff, 0xa086, 0x00aa,
+	0x00ce, 0x0005, 0x0156, 0x0126, 0xa18c, 0x0fff, 0x21a8, 0x1d04,
+	0x15b7, 0x2091, 0x6000, 0x1f04, 0x15b7, 0x012e, 0x015e, 0x0005,
+	0x2071, 0xb600, 0x7160, 0x712e, 0x2021, 0x0001, 0xa190, 0x0030,
+	0xa298, 0x0030, 0x0240, 0x7064, 0xa302, 0x1228, 0x220a, 0x2208,
+	0x2310, 0x8420, 0x0ca8, 0x3800, 0xd08c, 0x0148, 0x7064, 0xa086,
+	0xb600, 0x0128, 0x7067, 0xb600, 0x2011, 0x1000, 0x0c48, 0x200b,
+	0x0000, 0x74b2, 0x74b6, 0x0005, 0x00e6, 0x0126, 0x2091, 0x8000,
+	0x2071, 0xb600, 0x70b4, 0xa0ea, 0x0010, 0x0268, 0x8001, 0x70b6,
+	0x702c, 0x2068, 0x2d04, 0x702e, 0x206b, 0x0000, 0x6807, 0x0000,
+	0x012e, 0x00ee, 0x0005, 0xa06e, 0x0cd8, 0x00e6, 0x2071, 0xb600,
+	0x0126, 0x2091, 0x8000, 0x70b4, 0x8001, 0x0260, 0x70b6, 0x702c,
+	0x2068, 0x2d04, 0x702e, 0x206b, 0x0000, 0x6807, 0x0000, 0x012e,
+	0x00ee, 0x0005, 0xa06e, 0x0cd8, 0x00e6, 0x0126, 0x2091, 0x8000,
+	0x2071, 0xb600, 0x702c, 0x206a, 0x2d00, 0x702e, 0x70b4, 0x8000,
+	0x70b6, 0x012e, 0x00ee, 0x0005, 0x8dff, 0x0138, 0x6804, 0x6807,
+	0x0000, 0x0006, 0x0c49, 0x00de, 0x0cb8, 0x0005, 0x00e6, 0x2071,
+	0xb600, 0x70b4, 0xa08a, 0x0010, 0xa00d, 0x00ee, 0x0005, 0x00e6,
+	0x2071, 0xb913, 0x7007, 0x0000, 0x701b, 0x0000, 0x701f, 0x0000,
+	0x2071, 0x0000, 0x7010, 0xa085, 0x8004, 0x7012, 0x00ee, 0x0005,
+	0x0126, 0x2091, 0x8000, 0x00e6, 0x2270, 0x700b, 0x0000, 0x2071,
+	0xb913, 0x7018, 0xa088, 0xb91c, 0x220a, 0x8000, 0xa084, 0x0007,
+	0x701a, 0x7004, 0xa005, 0x1128, 0x00f6, 0x2079, 0x0010, 0x0089,
+	0x00fe, 0x00ee, 0x012e, 0x0005, 0x00e6, 0x2071, 0xb913, 0x7004,
+	0xa005, 0x1128, 0x00f6, 0x2079, 0x0010, 0x0019, 0x00fe, 0x00ee,
+	0x0005, 0x7000, 0x0002, 0x1677, 0x16db, 0x16f8, 0x16f8, 0x7018,
+	0x711c, 0xa106, 0x1118, 0x7007, 0x0000, 0x0005, 0x00d6, 0xa180,
+	0xb91c, 0x2004, 0x700a, 0x2068, 0x8108, 0xa18c, 0x0007, 0x711e,
+	0x7803, 0x0026, 0x6824, 0x7832, 0x6828, 0x7836, 0x682c, 0x783a,
+	0x6830, 0x783e, 0x6810, 0x700e, 0x680c, 0x7016, 0x6804, 0x00de,
+	0xd084, 0x0120, 0x7007, 0x0001, 0x0029, 0x0005, 0x7007, 0x0002,
+	0x00b1, 0x0005, 0x0016, 0x0026, 0x710c, 0x2011, 0x0040, 0xa182,
+	0x0040, 0x1210, 0x2110, 0xa006, 0x700e, 0x7212, 0x8203, 0x7822,
+	0x7803, 0x0020, 0x7803, 0x0041, 0x002e, 0x001e, 0x0005, 0x0016,
+	0x0026, 0x0136, 0x0146, 0x0156, 0x7014, 0x2098, 0x20a1, 0x0014,
+	0x7803, 0x0026, 0x710c, 0x2011, 0x0040, 0xa182, 0x0040, 0x1210,
+	0x2110, 0xa006, 0x700e, 0x22a8, 0x53a6, 0x8203, 0x7822, 0x7803,
+	0x0020, 0x3300, 0x7016, 0x7803, 0x0001, 0x015e, 0x014e, 0x013e,
+	0x002e, 0x001e, 0x0005, 0x0136, 0x0146, 0x0156, 0x2099, 0xb6fa,
+	0x20a1, 0x0018, 0x20a9, 0x0008, 0x53a3, 0x7803, 0x0020, 0x0126,
+	0x2091, 0x8000, 0x7803, 0x0041, 0x7007, 0x0003, 0x7000, 0xc084,
+	0x7002, 0x700b, 0xb6f5, 0x012e, 0x015e, 0x014e, 0x013e, 0x0005,
+	0x0136, 0x0146, 0x0156, 0x2001, 0xb729, 0x209c, 0x20a1, 0x0014,
+	0x7803, 0x0026, 0x2001, 0xb72a, 0x20ac, 0x53a6, 0x2099, 0xb72b,
+	0x20a1, 0x0018, 0x20a9, 0x0008, 0x53a3, 0x7803, 0x0020, 0x0126,
+	0x2091, 0x8000, 0x7803, 0x0001, 0x7007, 0x0004, 0x7000, 0xc08c,
+	0x7002, 0x700b, 0xb726, 0x012e, 0x015e, 0x014e, 0x013e, 0x0005,
+	0x0016, 0x00e6, 0x2071, 0xb913, 0x00f6, 0x2079, 0x0010, 0x7904,
+	0x7803, 0x0002, 0xd1fc, 0x0120, 0xa18c, 0x0700, 0x7004, 0x0023,
+	0x00fe, 0x00ee, 0x001e, 0x0005, 0x1671, 0x173b, 0x1769, 0x1793,
+	0x17c3, 0x173a, 0x0cf8, 0xa18c, 0x0700, 0x1528, 0x0136, 0x0146,
+	0x0156, 0x7014, 0x20a0, 0x2099, 0x0014, 0x7803, 0x0040, 0x7010,
+	0x20a8, 0x53a5, 0x3400, 0x7016, 0x015e, 0x014e, 0x013e, 0x700c,
+	0xa005, 0x0570, 0x7830, 0x7832, 0x7834, 0x7836, 0x080c, 0x16a2,
+	0x0005, 0x7008, 0xa080, 0x0002, 0x2003, 0x0100, 0x7007, 0x0000,
+	0x080c, 0x1671, 0x0005, 0x7008, 0xa080, 0x0002, 0x2003, 0x0200,
+	0x0ca8, 0xa18c, 0x0700, 0x1150, 0x700c, 0xa005, 0x0188, 0x7830,
+	0x7832, 0x7834, 0x7836, 0x080c, 0x16b7, 0x0005, 0x7008, 0xa080,
+	0x0002, 0x2003, 0x0200, 0x7007, 0x0000, 0x080c, 0x1671, 0x0005,
+	0x00d6, 0x7008, 0x2068, 0x7830, 0x6826, 0x7834, 0x682a, 0x7838,
+	0x682e, 0x783c, 0x6832, 0x680b, 0x0100, 0x00de, 0x7007, 0x0000,
+	0x080c, 0x1671, 0x0005, 0xa18c, 0x0700, 0x1540, 0x0136, 0x0146,
+	0x0156, 0x2001, 0xb6f8, 0x2004, 0xa080, 0x000d, 0x20a0, 0x2099,
+	0x0014, 0x7803, 0x0040, 0x20a9, 0x0020, 0x53a5, 0x2001, 0xb6fa,
+	0x2004, 0xd0bc, 0x0148, 0x2001, 0xb703, 0x2004, 0xa080, 0x000d,
+	0x20a0, 0x20a9, 0x0020, 0x53a5, 0x015e, 0x014e, 0x013e, 0x7007,
+	0x0000, 0x080c, 0x5ee1, 0x080c, 0x1671, 0x0005, 0x2011, 0x8003,
+	0x080c, 0x3f13, 0x0cf8, 0xa18c, 0x0700, 0x1148, 0x2001, 0xb728,
+	0x2003, 0x0100, 0x7007, 0x0000, 0x080c, 0x1671, 0x0005, 0x2011,
+	0x8004, 0x080c, 0x3f13, 0x0cf8, 0x0126, 0x2091, 0x2200, 0x2079,
+	0x0030, 0x2071, 0xb924, 0x7003, 0x0000, 0x700f, 0xb930, 0x7013,
+	0xb930, 0x780f, 0x00f6, 0x7803, 0x0004, 0x012e, 0x0005, 0x6934,
+	0xa184, 0x0007, 0x0002, 0x17f3, 0x1831, 0x17f3, 0x17f3, 0x17f3,
+	0x1819, 0x1800, 0x17f7, 0xa085, 0x0001, 0x0804, 0x184b, 0x684c,
+	0xd0bc, 0x0dc8, 0x6860, 0x682e, 0x685c, 0x682a, 0x6858, 0x04c8,
+	0xa18c, 0x00ff, 0xa186, 0x001e, 0x1d70, 0x684c, 0xd0bc, 0x0d58,
+	0x6860, 0x682e, 0x685c, 0x682a, 0x6804, 0x681a, 0xa080, 0x000d,
+	0x2004, 0xa084, 0x000f, 0xa080, 0x2308, 0x2005, 0x6832, 0x6858,
+	0x0440, 0xa18c, 0x00ff, 0xa186, 0x0015, 0x19a8, 0x684c, 0xd0ac,
+	0x0990, 0x6804, 0x681a, 0xa080, 0x000d, 0x2004, 0xa084, 0x000f,
+	0xa080, 0x2308, 0x2005, 0x6832, 0xa006, 0x682e, 0x682a, 0x6858,
+	0x0080, 0x684c, 0xd0ac, 0x0904, 0x17f3, 0xa006, 0x682e, 0x682a,
+	0x6858, 0xa18c, 0x000f, 0xa188, 0x2308, 0x210d, 0x6932, 0x2d08,
+	0x691a, 0x6826, 0x684c, 0xc0dd, 0x684e, 0xa006, 0x680a, 0x697c,
+	0x6912, 0x6980, 0x6916, 0x0005, 0x684c, 0xd0ac, 0x090c, 0x151a,
+	0x6833, 0x2305, 0x2d08, 0x691a, 0x6858, 0x8001, 0x6826, 0x684c,
+	0xc0dd, 0x684e, 0xa006, 0x680a, 0x682e, 0x682a, 0x697c, 0x6912,
+	0x6980, 0x6916, 0x0005, 0x20e1, 0x0007, 0x20e1, 0x2000, 0x2001,
+	0x020a, 0x2004, 0x82ff, 0x01e8, 0xa280, 0x0004, 0x00d6, 0x206c,
+	0x684c, 0xd0dc, 0x1190, 0xa280, 0x0007, 0x2004, 0xa086, 0x000a,
+	0x1110, 0x0891, 0x0010, 0x080c, 0x17e7, 0x0138, 0x00de, 0xa280,
+	0x0000, 0x2003, 0x0002, 0xa016, 0x0020, 0x6808, 0x8000, 0x680a,
+	0x00de, 0x0126, 0x0046, 0x0036, 0x0026, 0x2091, 0x2200, 0x002e,
+	0x003e, 0x004e, 0x7000, 0xa005, 0x01d0, 0x710c, 0x220a, 0x8108,
+	0x230a, 0x8108, 0x240a, 0x8108, 0xa182, 0xb94b, 0x0210, 0x2009,
+	0xb930, 0x710e, 0x7010, 0xa102, 0xa082, 0x0009, 0x0118, 0xa080,
+	0x001b, 0x1118, 0x2009, 0x0138, 0x200a, 0x012e, 0x0005, 0x7206,
+	0x2001, 0x18ad, 0x0006, 0x2260, 0x0804, 0x19da, 0x0126, 0x0026,
+	0x0036, 0x00c6, 0x0006, 0x2091, 0x2200, 0x000e, 0x004e, 0x003e,
+	0x002e, 0x00d6, 0x00c6, 0x2460, 0x6110, 0x2168, 0x6a62, 0x6b5e,
+	0xa005, 0x0904, 0x190f, 0x6808, 0xa005, 0x0904, 0x1946, 0x7000,
+	0xa005, 0x1108, 0x0488, 0x700c, 0x7110, 0xa106, 0x1904, 0x194e,
+	0x7004, 0xa406, 0x1548, 0x2001, 0x0005, 0x2004, 0xd08c, 0x0168,
+	0x0046, 0x080c, 0x1b22, 0x004e, 0x2460, 0x6010, 0xa080, 0x0002,
+	0x2004, 0xa005, 0x0904, 0x1946, 0x0c10, 0x2001, 0x0207, 0x2004,
+	0xd09c, 0x1d48, 0x7804, 0xa084, 0x6000, 0x0120, 0xa086, 0x6000,
+	0x0108, 0x0c08, 0x7818, 0x6812, 0x781c, 0x6816, 0x7803, 0x0004,
+	0x7003, 0x0000, 0x7004, 0x2060, 0x6100, 0xa18e, 0x0004, 0x1904,
+	0x194e, 0x2009, 0x0048, 0x080c, 0x86d3, 0x0804, 0x194e, 0x6808,
+	0xa005, 0x05a0, 0x7000, 0xa005, 0x0588, 0x700c, 0x7110, 0xa106,
+	0x1118, 0x7004, 0xa406, 0x1550, 0x2001, 0x0005, 0x2004, 0xd08c,
+	0x0160, 0x0046, 0x080c, 0x1b22, 0x004e, 0x2460, 0x6010, 0xa080,
+	0x0002, 0x2004, 0xa005, 0x01d0, 0x0c28, 0x2001, 0x0207, 0x2004,
+	0xd09c, 0x1d50, 0x2001, 0x0005, 0x2004, 0xd08c, 0x1d50, 0x7804,
+	0xa084, 0x6000, 0x0118, 0xa086, 0x6000, 0x19f0, 0x7818, 0x6812,
+	0x781c, 0x6816, 0x7803, 0x0004, 0x7003, 0x0000, 0x6100, 0xa18e,
+	0x0004, 0x1120, 0x2009, 0x0048, 0x080c, 0x86d3, 0x00ce, 0x00de,
+	0x012e, 0x0005, 0x00f6, 0x00e6, 0x0026, 0x0036, 0x0046, 0x0056,
+	0x2071, 0xb924, 0x7000, 0xa086, 0x0000, 0x0904, 0x19b8, 0x7004,
+	0xac06, 0x1904, 0x19aa, 0x2079, 0x0030, 0x7000, 0xa086, 0x0003,
+	0x0904, 0x19aa, 0x7804, 0xd0fc, 0x15c8, 0x20e1, 0x6000, 0x2011,
+	0x0032, 0x2001, 0x0208, 0x200c, 0x2001, 0x0209, 0x2004, 0xa106,
+	0x1d88, 0x8211, 0x1db0, 0x7804, 0xd0fc, 0x1540, 0x080c, 0x1e8a,
+	0x0026, 0x0056, 0x7803, 0x0004, 0x7804, 0xd0ac, 0x1de8, 0x7803,
+	0x0002, 0x7803, 0x0009, 0x7003, 0x0003, 0x7007, 0x0000, 0x005e,
+	0x002e, 0x2001, 0x015d, 0x2003, 0x0000, 0x080c, 0x5b41, 0x1138,
+	0x0066, 0x2031, 0x0001, 0x080c, 0x5bc3, 0x006e, 0x0058, 0x2001,
+	0x0160, 0x2502, 0x2001, 0x0138, 0x2202, 0x0020, 0x080c, 0x1b22,
+	0x0804, 0x195a, 0x0156, 0x20a9, 0x0009, 0x2009, 0xb930, 0x2104,
+	0xac06, 0x1108, 0x200a, 0xa188, 0x0003, 0x1f04, 0x19af, 0x015e,
+	0x005e, 0x004e, 0x003e, 0x002e, 0x00ee, 0x00fe, 0x0005, 0x700c,
+	0x7110, 0xa106, 0x0904, 0x1a4e, 0x2104, 0x7006, 0x2060, 0x8108,
+	0x211c, 0x8108, 0x2124, 0x8108, 0xa182, 0xb94b, 0x0210, 0x2009,
+	0xb930, 0x7112, 0x700c, 0xa106, 0x1128, 0x080c, 0x2920, 0x2001,
+	0x0138, 0x2102, 0x8cff, 0x0598, 0x6010, 0x2068, 0x2d58, 0x6828,
+	0xa406, 0x1590, 0x682c, 0xa306, 0x1578, 0x7004, 0x2060, 0x6020,
+	0xc0d4, 0x6022, 0x684c, 0xd0f4, 0x0128, 0x6817, 0xffff, 0x6813,
+	0xffff, 0x00e8, 0x6850, 0xd0f4, 0x1130, 0x7803, 0x0004, 0x6810,
+	0x781a, 0x6814, 0x781e, 0x6824, 0x2050, 0x6818, 0x2060, 0x6830,
+	0x2040, 0x6034, 0xa0cc, 0x000f, 0x2009, 0x0011, 0x080c, 0x1a51,
+	0x0120, 0x2009, 0x0001, 0x080c, 0x1a51, 0x2d58, 0x0005, 0x080c,
+	0x1df9, 0x0904, 0x19bf, 0x0cd0, 0x6020, 0xd0f4, 0x11e0, 0xd0d4,
+	0x01b8, 0x6038, 0xa402, 0x6034, 0xa303, 0x0108, 0x1288, 0x643a,
+	0x6336, 0x6c2a, 0x6b2e, 0x0046, 0x0036, 0x2400, 0x6c7c, 0xa402,
+	0x6812, 0x2300, 0x6b80, 0xa303, 0x6816, 0x003e, 0x004e, 0x0018,
+	0x080c, 0xa056, 0x09e0, 0x601c, 0xa08e, 0x0008, 0x0904, 0x19e5,
+	0xa08e, 0x000a, 0x0904, 0x19e5, 0x2001, 0xb674, 0x2004, 0xd0b4,
+	0x1140, 0x6018, 0x2004, 0xd0bc, 0x1120, 0x6817, 0x7fff, 0x6813,
+	0xffff, 0x080c, 0x2328, 0x1918, 0x0804, 0x19e5, 0x7003, 0x0000,
+	0x0005, 0x8aff, 0x0904, 0x1afc, 0xa03e, 0x2730, 0xc9fc, 0x6850,
+	0xd0fc, 0x11b8, 0xd0f4, 0x1588, 0x00d6, 0x2805, 0xac68, 0x2900,
+	0x0002, 0x1aba, 0x1a93, 0x1a93, 0x1aba, 0x1aba, 0x1ab2, 0x1aba,
+	0x1a93, 0x1aba, 0x1a9b, 0x1a9b, 0x1aba, 0x1aba, 0x1aba, 0x1aaa,
+	0x1a9b, 0x7803, 0x0004, 0xc0fc, 0x6852, 0x6b6c, 0x6a70, 0x6d1c,
+	0x6c20, 0x00d6, 0xd99c, 0x0140, 0x2805, 0xac68, 0x6f08, 0x6e0c,
+	0x080c, 0x23ed, 0x0120, 0x04d0, 0x080c, 0x23ed, 0x15b0, 0x6850,
+	0xc0fd, 0x6852, 0x00de, 0xa006, 0x0005, 0xc0f4, 0x6852, 0x6b6c,
+	0x6a70, 0x00d6, 0x04c0, 0x6b08, 0x6a0c, 0x6d00, 0x6c04, 0x080c,
+	0x23ed, 0x0d80, 0x0410, 0x6b10, 0x6a14, 0x6d00, 0x6c04, 0x6f08,
+	0x6e0c, 0x080c, 0x23ed, 0x0d30, 0x00c8, 0x6d00, 0x6c04, 0x6f08,
+	0x6e0c, 0x00a0, 0x00de, 0x00d6, 0x6834, 0xa084, 0x00ff, 0xa086,
+	0x001e, 0x1140, 0x00de, 0x080c, 0x22ca, 0x1904, 0x1a51, 0xa00e,
+	0x0804, 0x1afc, 0x00de, 0x080c, 0x151a, 0xc9fd, 0x7b22, 0x7a26,
+	0x7d32, 0x7c36, 0x7f3a, 0x7e3e, 0x7316, 0x721a, 0x751e, 0x7422,
+	0x7726, 0x762a, 0x7902, 0x7100, 0x8108, 0x7102, 0x00de, 0x6828,
+	0xa300, 0x682a, 0x682c, 0xa201, 0x682e, 0x8109, 0x2d08, 0x1500,
+	0xd9fc, 0x0160, 0xc9fc, 0x080c, 0x22ca, 0x01e8, 0x2805, 0xac68,
+	0x6800, 0xa506, 0x11c0, 0x6804, 0xa406, 0x00a8, 0xc9fc, 0x080c,
+	0x22ca, 0x0188, 0x2805, 0xac68, 0x6800, 0xa506, 0x1160, 0x6804,
+	0xa406, 0x1148, 0x6808, 0xa706, 0x1130, 0x680c, 0xa606, 0x0018,
+	0xc9fc, 0x080c, 0x22ca, 0x2168, 0x0005, 0x080c, 0x151a, 0x080c,
+	0x1f71, 0x7004, 0x2060, 0x00d6, 0x6010, 0x2068, 0x7003, 0x0000,
+	0x080c, 0x1e1a, 0x080c, 0x9d16, 0x0170, 0x6808, 0x8001, 0x680a,
+	0x697c, 0x6912, 0x6980, 0x6916, 0x682b, 0xffff, 0x682f, 0xffff,
+	0x6850, 0xc0bd, 0x6852, 0x00de, 0x080c, 0x99e6, 0x0804, 0x1d47,
+	0x080c, 0x151a, 0x0126, 0x2091, 0x2200, 0x0006, 0x0016, 0x2b68,
+	0x6818, 0x2060, 0x7904, 0x7803, 0x0002, 0xa184, 0x0700, 0x1978,
+	0xa184, 0x0003, 0xa086, 0x0003, 0x0d58, 0x7000, 0x0002, 0x1b3f,
+	0x1b45, 0x1c56, 0x1d22, 0x1d36, 0x1b3f, 0x1b3f, 0x1b3f, 0x7804,
+	0xd09c, 0x1904, 0x1d47, 0x080c, 0x151a, 0x8001, 0x7002, 0xd1bc,
+	0x11a0, 0xd19c, 0x1904, 0x1bda, 0xd1dc, 0x1178, 0x8aff, 0x0904,
+	0x1bda, 0x2009, 0x0001, 0x080c, 0x1a51, 0x0904, 0x1d47, 0x2009,
+	0x0001, 0x080c, 0x1a51, 0x0804, 0x1d47, 0x7803, 0x0004, 0x7003,
+	0x0000, 0xd1bc, 0x1904, 0x1bba, 0x0026, 0x0036, 0x7c20, 0x7d24,
+	0x7e30, 0x7f34, 0x7818, 0x6812, 0x781c, 0x6816, 0x2001, 0x0201,
+	0x2004, 0xa005, 0x0140, 0x7808, 0xd0ec, 0x1128, 0x7803, 0x0009,
+	0x7003, 0x0004, 0x0010, 0x080c, 0x1d4b, 0x6b28, 0x6a2c, 0x2400,
+	0x686e, 0xa31a, 0x2500, 0x6872, 0xa213, 0x6b2a, 0x6a2e, 0x00c6,
+	0x7004, 0x2060, 0x6020, 0xd0f4, 0x1110, 0x633a, 0x6236, 0x00ce,
+	0x003e, 0x002e, 0x6e1e, 0x6f22, 0x2500, 0xa405, 0x0128, 0x080c,
+	0x22e0, 0x6850, 0xc0fd, 0x6852, 0x2a00, 0x6826, 0x2c00, 0x681a,
+	0x2800, 0x6832, 0x6808, 0x8001, 0x680a, 0x1148, 0x684c, 0xd0e4,
+	0x0130, 0x7004, 0x2060, 0x2009, 0x0048, 0x080c, 0x86d3, 0x7000,
+	0xa086, 0x0004, 0x0904, 0x1d47, 0x7003, 0x0000, 0x080c, 0x19bf,
+	0x0804, 0x1d47, 0x0056, 0x7d0c, 0xd5bc, 0x1110, 0x080c, 0xb4c3,
+	0x005e, 0x080c, 0x1e1a, 0x00f6, 0x7004, 0x2078, 0x080c, 0x5377,
+	0x0118, 0x7820, 0xc0f5, 0x7822, 0x00fe, 0x682b, 0xffff, 0x682f,
+	0xffff, 0x6808, 0x8001, 0x680a, 0x697c, 0x791a, 0x6980, 0x791e,
+	0x0804, 0x1d47, 0x7004, 0x00c6, 0x2060, 0x6020, 0x00ce, 0xd0f4,
+	0x0120, 0x6808, 0x8001, 0x680a, 0x04c0, 0x7818, 0x6812, 0x7a1c,
+	0x6a16, 0xd19c, 0x0160, 0xa205, 0x0150, 0x7004, 0xa080, 0x0007,
+	0x2004, 0xa084, 0xfffd, 0xa086, 0x0008, 0x1904, 0x1b5d, 0x684c,
+	0xc0f5, 0x684e, 0x7814, 0xa005, 0x1520, 0x7003, 0x0000, 0x6808,
+	0x8001, 0x680a, 0x01a0, 0x7004, 0x2060, 0x601c, 0xa086, 0x000a,
+	0x11a0, 0x0156, 0x20a9, 0x0009, 0x2009, 0xb930, 0x2104, 0xac06,
+	0x1108, 0x200a, 0xa188, 0x0003, 0x1f04, 0x1c0e, 0x015e, 0x7004,
+	0x2060, 0x2009, 0x0048, 0x080c, 0x86d3, 0x080c, 0x19bf, 0x0804,
+	0x1d47, 0x7818, 0x6812, 0x781c, 0x6816, 0x7814, 0x7908, 0xa18c,
+	0x0fff, 0xa192, 0x0841, 0x1a04, 0x1aff, 0xa188, 0x0007, 0x8114,
+	0x8214, 0x8214, 0xa10a, 0x8104, 0x8004, 0x8004, 0xa20a, 0x810b,
+	0x810b, 0x810b, 0x080c, 0x1eb5, 0x7803, 0x0004, 0x780f, 0xffff,
+	0x7803, 0x0001, 0x7804, 0xd0fc, 0x0de8, 0x7803, 0x0002, 0x7803,
+	0x0004, 0x780f, 0x00f6, 0x7004, 0x7007, 0x0000, 0x2060, 0x2009,
+	0x0048, 0x080c, 0x86d3, 0x080c, 0x1f0b, 0x0838, 0x8001, 0x7002,
+	0xd194, 0x01b0, 0x7804, 0xd0fc, 0x1904, 0x1cf2, 0xd09c, 0x0138,
+	0x7804, 0xd0fc, 0x1904, 0x1cf2, 0xd09c, 0x1904, 0x1cf6, 0x8aff,
+	0x0904, 0x1d47, 0x2009, 0x0001, 0x080c, 0x1a51, 0x0804, 0x1d47,
+	0xa184, 0x0888, 0x1148, 0x8aff, 0x0904, 0x1d47, 0x2009, 0x0001,
+	0x080c, 0x1a51, 0x0804, 0x1d47, 0x7818, 0x6812, 0x7a1c, 0x6a16,
+	0xa205, 0x0904, 0x1bf7, 0x7803, 0x0004, 0x7003, 0x0000, 0xd1bc,
+	0x1904, 0x1cd4, 0x6834, 0xa084, 0x00ff, 0xa086, 0x0029, 0x1118,
+	0xd19c, 0x1904, 0x1bf7, 0x0026, 0x0036, 0x7c20, 0x7d24, 0x7e30,
+	0x7f34, 0x7818, 0x6812, 0x781c, 0x6816, 0x2001, 0x0201, 0x2004,
+	0xa005, 0x0140, 0x7808, 0xd0ec, 0x1128, 0x7803, 0x0009, 0x7003,
+	0x0004, 0x0020, 0x0016, 0x080c, 0x1d4b, 0x001e, 0x6b28, 0x6a2c,
+	0x080c, 0x22e0, 0x00d6, 0x2805, 0xac68, 0x6034, 0xd09c, 0x1128,
+	0x6808, 0xa31a, 0x680c, 0xa213, 0x0020, 0x6810, 0xa31a, 0x6814,
+	0xa213, 0x00de, 0xd194, 0x0904, 0x1b7f, 0x2a00, 0x6826, 0x2c00,
+	0x681a, 0x2800, 0x6832, 0x6808, 0x8001, 0x680a, 0x6b2a, 0x6a2e,
+	0x003e, 0x002e, 0x0804, 0x1c1d, 0x0056, 0x7d0c, 0x080c, 0xb4c3,
+	0x005e, 0x080c, 0x1e1a, 0x00f6, 0x7004, 0x2078, 0x080c, 0x5377,
+	0x0118, 0x7820, 0xc0f5, 0x7822, 0x00fe, 0x682b, 0xffff, 0x682f,
+	0xffff, 0x6808, 0x8001, 0x680a, 0x697c, 0x791a, 0x6980, 0x791e,
+	0x0804, 0x1d47, 0x7804, 0xd09c, 0x0904, 0x1b2a, 0x7c20, 0x7824,
+	0xa405, 0x1904, 0x1b2a, 0x7818, 0x6812, 0x7c1c, 0x6c16, 0xa405,
+	0x1120, 0x7803, 0x0002, 0x0804, 0x1bf7, 0x751c, 0x7420, 0x7724,
+	0x7628, 0x7014, 0xa528, 0x7018, 0xa421, 0xa7b9, 0x0000, 0xa6b1,
+	0x0000, 0x7830, 0xa506, 0x1150, 0x7834, 0xa406, 0x1138, 0x7838,
+	0xa706, 0x1120, 0x783c, 0xa606, 0x0904, 0x1b2a, 0x7803, 0x0002,
+	0x0804, 0x1c83, 0x7803, 0x0004, 0x7003, 0x0000, 0x7004, 0xa00d,
+	0x0150, 0x6808, 0x8001, 0x680a, 0x1130, 0x7004, 0x2060, 0x2009,
+	0x0048, 0x080c, 0x86d3, 0x080c, 0x19bf, 0x0088, 0x7803, 0x0004,
+	0x7003, 0x0000, 0x7004, 0x2060, 0x6010, 0xa005, 0x0da0, 0x2068,
+	0x6808, 0x8000, 0x680a, 0x6c28, 0x6b2c, 0x080c, 0x19da, 0x001e,
+	0x000e, 0x012e, 0x0005, 0x700c, 0x7110, 0xa106, 0x0904, 0x1ded,
+	0x7004, 0x0016, 0x210c, 0xa106, 0x001e, 0x0904, 0x1ded, 0x00d6,
+	0x00c6, 0x216c, 0x2d00, 0xa005, 0x0904, 0x1deb, 0x681c, 0xa086,
+	0x0008, 0x0904, 0x1deb, 0x6820, 0xd0d4, 0x1904, 0x1deb, 0x6810,
+	0x2068, 0x6850, 0xd0fc, 0x05a8, 0x8108, 0x2104, 0x6b2c, 0xa306,
+	0x1904, 0x1deb, 0x8108, 0x2104, 0x6a28, 0xa206, 0x1904, 0x1deb,
+	0x6850, 0xc0fc, 0xc0f5, 0x6852, 0x686c, 0x7822, 0x7016, 0x6870,
+	0x7826, 0x701a, 0x681c, 0x7832, 0x701e, 0x6820, 0x7836, 0x7022,
+	0x6818, 0x2060, 0x6034, 0xd09c, 0x0168, 0x6830, 0x2005, 0x00d6,
+	0xac68, 0x6808, 0x783a, 0x7026, 0x680c, 0x783e, 0x702a, 0x00de,
+	0x0804, 0x1de5, 0xa006, 0x783a, 0x783e, 0x7026, 0x702a, 0x0804,
+	0x1de5, 0x8108, 0x2104, 0xa005, 0x1904, 0x1deb, 0x6b2c, 0xa306,
+	0x1904, 0x1deb, 0x8108, 0x2104, 0xa005, 0x15e8, 0x6a28, 0xa206,
+	0x15d0, 0x6850, 0xc0f5, 0x6852, 0x6830, 0x2005, 0x6918, 0xa160,
+	0xa180, 0x000d, 0x2004, 0xd09c, 0x11a0, 0x6008, 0x7822, 0x7016,
+	0x686e, 0x600c, 0x7826, 0x701a, 0x6872, 0x6000, 0x7832, 0x701e,
+	0x6004, 0x7836, 0x7022, 0xa006, 0x783a, 0x783e, 0x7026, 0x702a,
+	0x00a0, 0x6010, 0x7822, 0x7016, 0x686e, 0x6014, 0x7826, 0x701a,
+	0x6872, 0x6000, 0x7832, 0x701e, 0x6004, 0x7836, 0x7022, 0x6008,
+	0x783a, 0x7026, 0x600c, 0x783e, 0x702a, 0x6810, 0x781a, 0x6814,
+	0x781e, 0x7803, 0x0011, 0x00ce, 0x00de, 0x0005, 0x2011, 0x0201,
+	0x2009, 0x003c, 0x2204, 0xa005, 0x1118, 0x8109, 0x1dd8, 0x0005,
+	0x0005, 0x0ca1, 0x0118, 0x780c, 0xd0a4, 0x0120, 0x00d9, 0xa085,
+	0x0001, 0x0010, 0x080c, 0x1f0b, 0x0005, 0x0126, 0x2091, 0x2200,
+	0x7000, 0xa086, 0x0003, 0x1160, 0x700c, 0x7110, 0xa106, 0x0140,
+	0x080c, 0x2991, 0x20e1, 0x9028, 0x700f, 0xb930, 0x7013, 0xb930,
+	0x012e, 0x0005, 0x00c6, 0x080c, 0x5b41, 0x11b8, 0x2001, 0x0160,
+	0x2003, 0x0000, 0x2001, 0x0138, 0x2003, 0x0000, 0x2011, 0x00c8,
+	0xe000, 0xe000, 0x8211, 0x1de0, 0x04b1, 0x0066, 0x2031, 0x0000,
+	0x080c, 0x5bc3, 0x006e, 0x00ce, 0x0005, 0x080c, 0x1e8a, 0x080c,
+	0x2991, 0x20e1, 0x9028, 0x700c, 0x7110, 0xa106, 0x01c0, 0x2104,
+	0xa005, 0x0130, 0x2060, 0x6010, 0x2060, 0x6008, 0x8001, 0x600a,
+	0xa188, 0x0003, 0xa182, 0xb94b, 0x0210, 0x2009, 0xb930, 0x7112,
+	0x700c, 0xa106, 0x1d40, 0x080c, 0x2920, 0x2110, 0x0c20, 0x2001,
+	0x015d, 0x2003, 0x0000, 0x2001, 0x0160, 0x2502, 0x2001, 0x0138,
+	0x2202, 0x00ce, 0x0005, 0x080c, 0x2991, 0x20e1, 0x9028, 0x2001,
+	0x015d, 0x2003, 0x0000, 0x00e6, 0x00c6, 0x0016, 0x2071, 0xb924,
+	0x700c, 0x7110, 0xa106, 0x0190, 0x2104, 0xa005, 0x0130, 0x2060,
+	0x6010, 0x2060, 0x6008, 0x8001, 0x600a, 0xa188, 0x0003, 0xa182,
+	0xb94b, 0x0210, 0x2009, 0xb930, 0x7112, 0x0c50, 0x001e, 0x00ce,
+	0x00ee, 0x0005, 0x2001, 0x0138, 0x2014, 0x2003, 0x0000, 0x2001,
+	0x0160, 0x202c, 0x2003, 0x0000, 0x080c, 0x5b41, 0x1148, 0x2021,
+	0x0002, 0x1d04, 0x1e99, 0x2091, 0x6000, 0x8421, 0x1dd0, 0x0005,
+	0x2021, 0xb015, 0x2001, 0x0141, 0x201c, 0xd3dc, 0x1168, 0x2001,
+	0x0109, 0x201c, 0xa39c, 0x0048, 0x1138, 0x2001, 0x0111, 0x201c,
+	0x83ff, 0x1110, 0x8421, 0x1d70, 0x0005, 0x00e6, 0x2071, 0x0200,
+	0x7808, 0xa084, 0xf000, 0xa10d, 0x0869, 0x2001, 0x0105, 0x2004,
+	0xa084, 0x0003, 0x1130, 0x2001, 0xb94b, 0x2004, 0xa086, 0x0000,
+	0x0548, 0xa026, 0x2019, 0xf000, 0x8319, 0x1148, 0x2001, 0x012b,
+	0x2003, 0x95f5, 0x2001, 0x0129, 0x2003, 0x95f5, 0x00d8, 0x2001,
+	0x0105, 0x2004, 0xa084, 0x0003, 0x1130, 0x2001, 0xb94b, 0x2004,
+	0xa086, 0x0000, 0x0178, 0x2001, 0x0132, 0x2004, 0xa436, 0x0110,
+	0x2020, 0x0c00, 0x2001, 0x0021, 0x2004, 0xd0fc, 0x09e8, 0x080c,
+	0x216d, 0x08c0, 0x20e1, 0x7000, 0x7324, 0x7420, 0x7028, 0x7028,
+	0x7426, 0x7037, 0x0001, 0x810f, 0x712e, 0x702f, 0x0100, 0x7037,
+	0x0008, 0x7326, 0x7422, 0x2001, 0x0160, 0x2502, 0x2001, 0x0138,
+	0x2202, 0x00ee, 0x0005, 0x0026, 0x2001, 0x015d, 0x2003, 0x0000,
+	0x7908, 0xa18c, 0x0fff, 0xa182, 0x0ffd, 0x0210, 0x2009, 0x0000,
+	0xa190, 0x0007, 0xa294, 0x1ff8, 0x8214, 0x8214, 0x8214, 0x2001,
+	0x020a, 0x82ff, 0x0140, 0x20e1, 0x6000, 0x200c, 0x200c, 0x200c,
+	0x200c, 0x8211, 0x1dd0, 0x20e1, 0x7000, 0x200c, 0x200c, 0x7003,
+	0x0000, 0x20e1, 0x6000, 0x2001, 0x0208, 0x200c, 0x2001, 0x0209,
+	0x2004, 0xa106, 0x0158, 0x080c, 0x1dee, 0x0130, 0x7908, 0xd1ec,
+	0x1128, 0x790c, 0xd1a4, 0x0960, 0x080c, 0x1e1a, 0xa006, 0x002e,
+	0x0005, 0x00f6, 0x00e6, 0x0016, 0x0026, 0x2071, 0xb924, 0x2079,
+	0x0030, 0x2011, 0x0050, 0x7000, 0xa086, 0x0000, 0x01a8, 0x8211,
+	0x0188, 0x2001, 0x0005, 0x2004, 0xd08c, 0x0dc8, 0x7904, 0xa18c,
+	0x0780, 0x0016, 0x080c, 0x1b22, 0x001e, 0x81ff, 0x1118, 0x2011,
+	0x0050, 0x0c48, 0xa085, 0x0001, 0x002e, 0x001e, 0x00ee, 0x00fe,
+	0x0005, 0x7803, 0x0004, 0x2009, 0x0064, 0x7804, 0xd0ac, 0x0904,
+	0x1fbd, 0x8109, 0x1dd0, 0x2009, 0x0100, 0x210c, 0xa18a, 0x0003,
+	0x0a0c, 0x151a, 0x080c, 0x2274, 0x00e6, 0x00f6, 0x2071, 0xb913,
+	0x2079, 0x0010, 0x7004, 0xa086, 0x0000, 0x0538, 0x7800, 0x0006,
+	0x7820, 0x0006, 0x7830, 0x0006, 0x7834, 0x0006, 0x7838, 0x0006,
+	0x783c, 0x0006, 0x7803, 0x0004, 0xe000, 0xe000, 0x2079, 0x0030,
+	0x7804, 0xd0ac, 0x190c, 0x151a, 0x2079, 0x0010, 0x000e, 0x783e,
+	0x000e, 0x783a, 0x000e, 0x7836, 0x000e, 0x7832, 0x000e, 0x7822,
+	0x000e, 0x7802, 0x00fe, 0x00ee, 0x0030, 0x00fe, 0x00ee, 0x7804,
+	0xd0ac, 0x190c, 0x151a, 0x080c, 0x72a2, 0x0005, 0x00e6, 0x2071,
+	0xb94b, 0x7003, 0x0000, 0x00ee, 0x0005, 0x00d6, 0xa280, 0x0004,
+	0x206c, 0x694c, 0xd1dc, 0x1904, 0x203b, 0x6934, 0xa184, 0x0007,
+	0x0002, 0x1fd9, 0x2026, 0x1fd9, 0x1fd9, 0x1fd9, 0x200d, 0x1fec,
+	0x1fdb, 0x080c, 0x151a, 0x684c, 0xd0b4, 0x0904, 0x212a, 0x6860,
+	0x682e, 0x6816, 0x685c, 0x682a, 0x6812, 0x687c, 0x680a, 0x6880,
+	0x680e, 0x6958, 0x0804, 0x202e, 0x6834, 0xa084, 0x00ff, 0xa086,
+	0x001e, 0x1d38, 0x684c, 0xd0b4, 0x0904, 0x212a, 0x6860, 0x682e,
+	0x6816, 0x685c, 0x682a, 0x6812, 0x687c, 0x680a, 0x6880, 0x680e,
+	0x6804, 0x681a, 0xa080, 0x000d, 0x2004, 0xa084, 0x000f, 0xa080,
+	0x2308, 0x2005, 0x6832, 0x6958, 0x0450, 0xa18c, 0x00ff, 0xa186,
+	0x0015, 0x1548, 0x684c, 0xd0b4, 0x0904, 0x212a, 0x6804, 0x681a,
+	0xa080, 0x000d, 0x2004, 0xa084, 0x000f, 0xa080, 0x2308, 0x2005,
+	0x6832, 0x6958, 0xa006, 0x682e, 0x682a, 0x0088, 0x684c, 0xd0b4,
+	0x0904, 0x1afd, 0x6958, 0xa006, 0x682e, 0x682a, 0x2d00, 0x681a,
+	0x6834, 0xa084, 0x000f, 0xa080, 0x2308, 0x2005, 0x6832, 0x6926,
+	0x684c, 0xc0dd, 0x684e, 0x00de, 0x0005, 0x00f6, 0x2079, 0x0020,
+	0x7804, 0xd0fc, 0x190c, 0x216d, 0x00e6, 0x00d6, 0x2071, 0xb94b,
+	0x7000, 0xa005, 0x1904, 0x20aa, 0x00c6, 0x7206, 0xa280, 0x0004,
+	0x205c, 0x7004, 0x2068, 0x7803, 0x0004, 0x6818, 0x00d6, 0x2068,
+	0x686c, 0x7812, 0x6890, 0x00f6, 0x20e1, 0x9040, 0x2079, 0x0200,
+	0x781a, 0x2079, 0x0100, 0x8004, 0x78d6, 0x00fe, 0x00de, 0x2b68,
+	0x6824, 0x2050, 0x6818, 0x2060, 0x6830, 0x2040, 0x6034, 0xa0cc,
+	0x000f, 0x6908, 0x791a, 0x7116, 0x680c, 0x781e, 0x701a, 0xa006,
+	0x700e, 0x7012, 0x7004, 0x692c, 0x6814, 0xa106, 0x1120, 0x6928,
+	0x6810, 0xa106, 0x0190, 0x2001, 0xb674, 0x2004, 0xd0cc, 0x0110,
+	0x00ce, 0x0400, 0x0036, 0x0046, 0x6b14, 0x6c10, 0x080c, 0x2328,
+	0x004e, 0x003e, 0x0110, 0x00ce, 0x00a8, 0x8aff, 0x1120, 0x00ce,
+	0xa085, 0x0001, 0x0078, 0x0126, 0x2091, 0x8000, 0x2079, 0x0020,
+	0x2009, 0x0001, 0x0059, 0x0118, 0x2009, 0x0001, 0x0039, 0x012e,
+	0x00ce, 0xa006, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x0076, 0x0066,
+	0x0056, 0x0046, 0x0036, 0x0026, 0x8aff, 0x0904, 0x2123, 0x700c,
+	0x7214, 0xa23a, 0x7010, 0x7218, 0xa203, 0x0a04, 0x2122, 0xa705,
+	0x0904, 0x2122, 0xa03e, 0x2730, 0x6850, 0xd0fc, 0x11a8, 0x00d6,
+	0x2805, 0xac68, 0x2900, 0x0002, 0x2105, 0x20ea, 0x20ea, 0x2105,
+	0x2105, 0x20fe, 0x2105, 0x20ea, 0x2105, 0x20ef, 0x20ef, 0x2105,
+	0x2105, 0x2105, 0x20f6, 0x20ef, 0xc0fc, 0x6852, 0x6b6c, 0x6a70,
+	0x6d1c, 0x6c20, 0xd99c, 0x0528, 0x00d6, 0x2805, 0xac68, 0x6f08,
+	0x6e0c, 0x00f0, 0x6b08, 0x6a0c, 0x6d00, 0x6c04, 0x00c8, 0x6b10,
+	0x6a14, 0x6d00, 0x6c04, 0x6f08, 0x6e0c, 0x0090, 0x00de, 0x00d6,
+	0x6834, 0xa084, 0x00ff, 0xa086, 0x001e, 0x1138, 0x00de, 0x080c,
+	0x22ca, 0x1904, 0x20b4, 0xa00e, 0x00f0, 0x00de, 0x080c, 0x151a,
+	0x00de, 0x7b22, 0x7a26, 0x7d32, 0x7c36, 0x7f3a, 0x7e3e, 0x7902,
+	0x7000, 0x8000, 0x7002, 0x6828, 0xa300, 0x682a, 0x682c, 0xa201,
+	0x682e, 0x700c, 0xa300, 0x700e, 0x7010, 0xa201, 0x7012, 0x080c,
+	0x22ca, 0x0008, 0xa006, 0x002e, 0x003e, 0x004e, 0x005e, 0x006e,
+	0x007e, 0x0005, 0x080c, 0x151a, 0x0026, 0x2001, 0x0105, 0x2003,
+	0x0010, 0x20e1, 0x9040, 0x7803, 0x0004, 0x7003, 0x0000, 0x7004,
+	0x2060, 0x00d6, 0x6010, 0x2068, 0x080c, 0x9d16, 0x0118, 0x6850,
+	0xc0bd, 0x6852, 0x601c, 0xa086, 0x0006, 0x1180, 0x2061, 0x0100,
+	0x62c8, 0x2001, 0x00fa, 0x8001, 0x1df0, 0x60c8, 0xa206, 0x1dc0,
+	0x60c4, 0x686a, 0x60c8, 0x6866, 0x7004, 0x2060, 0x00de, 0x00c6,
+	0x080c, 0x99e6, 0x00ce, 0x2001, 0xb8f0, 0x2004, 0xac06, 0x1150,
+	0x20e1, 0x9040, 0x080c, 0x82e4, 0x2011, 0x0000, 0x080c, 0x8106,
+	0x080c, 0x72a2, 0x002e, 0x0804, 0x2227, 0x0126, 0x2091, 0x2400,
+	0x0006, 0x0016, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x2079, 0x0020,
+	0x2071, 0xb94b, 0x2b68, 0x6818, 0x2060, 0x7904, 0x7803, 0x0002,
+	0xa184, 0x0700, 0x1904, 0x212c, 0x7000, 0x0002, 0x2227, 0x218a,
+	0x21fa, 0x2225, 0x8001, 0x7002, 0xd19c, 0x1170, 0x8aff, 0x05d0,
+	0x2009, 0x0001, 0x080c, 0x20ae, 0x0904, 0x2227, 0x2009, 0x0001,
+	0x080c, 0x20ae, 0x0804, 0x2227, 0x7803, 0x0004, 0xd194, 0x0148,
+	0x6850, 0xc0fc, 0x6852, 0x8aff, 0x11d8, 0x684c, 0xc0f5, 0x684e,
+	0x00b8, 0x0026, 0x0036, 0x6b28, 0x6a2c, 0x7820, 0x686e, 0xa31a,
+	0x7824, 0x6872, 0xa213, 0x7830, 0x681e, 0x7834, 0x6822, 0x6b2a,
+	0x6a2e, 0x003e, 0x002e, 0x080c, 0x22e0, 0x6850, 0xc0fd, 0x6852,
+	0x2a00, 0x6826, 0x2c00, 0x681a, 0x2800, 0x6832, 0x7003, 0x0000,
+	0x0804, 0x2227, 0x00f6, 0x0026, 0x781c, 0x0006, 0x7818, 0x0006,
+	0x2079, 0x0100, 0x7a14, 0xa284, 0x0184, 0xa085, 0x0012, 0x7816,
+	0x0036, 0x2019, 0x1000, 0x8319, 0x090c, 0x151a, 0x7820, 0xd0bc,
+	0x1dd0, 0x003e, 0x79c8, 0x000e, 0xa102, 0x001e, 0x0006, 0x0016,
+	0x79c4, 0x000e, 0xa103, 0x78c6, 0x000e, 0x78ca, 0xa284, 0x0184,
+	0xa085, 0x0012, 0x7816, 0x002e, 0x00fe, 0x7803, 0x0008, 0x7003,
+	0x0000, 0x0468, 0x8001, 0x7002, 0xd194, 0x0168, 0x7804, 0xd0fc,
+	0x1904, 0x217d, 0xd19c, 0x11f8, 0x8aff, 0x0508, 0x2009, 0x0001,
+	0x080c, 0x20ae, 0x00e0, 0x0026, 0x0036, 0x6b28, 0x6a2c, 0x080c,
+	0x22e0, 0x00d6, 0x2805, 0xac68, 0x6034, 0xd09c, 0x1128, 0x6808,
+	0xa31a, 0x680c, 0xa213, 0x0020, 0x6810, 0xa31a, 0x6814, 0xa213,
+	0x00de, 0x0804, 0x21ad, 0x0804, 0x21a9, 0x080c, 0x151a, 0x00ce,
+	0x00de, 0x00ee, 0x00fe, 0x001e, 0x000e, 0x012e, 0x0005, 0x00f6,
+	0x00e6, 0x2071, 0xb94b, 0x7000, 0xa086, 0x0000, 0x05d0, 0x2079,
+	0x0020, 0x0016, 0x2009, 0x0207, 0x210c, 0xd194, 0x0198, 0x2009,
+	0x020c, 0x210c, 0xa184, 0x0003, 0x0168, 0x080c, 0xb50c, 0x2001,
+	0x0133, 0x2004, 0xa005, 0x090c, 0x151a, 0x20e1, 0x9040, 0x2001,
+	0x020c, 0x2102, 0x2009, 0x0206, 0x2104, 0x2009, 0x0203, 0x210c,
+	0xa106, 0x1110, 0x20e1, 0x9040, 0x7804, 0xd0fc, 0x09d8, 0x080c,
+	0x216d, 0x7000, 0xa086, 0x0000, 0x19a8, 0x001e, 0x7803, 0x0004,
+	0x7804, 0xd0ac, 0x1de8, 0x20e1, 0x9040, 0x7803, 0x0002, 0x7003,
+	0x0000, 0x00ee, 0x00fe, 0x0005, 0x0026, 0x00c6, 0x00d6, 0x00e6,
+	0x00f6, 0x2071, 0xb94b, 0x2079, 0x0020, 0x7000, 0xa086, 0x0000,
+	0x0540, 0x7004, 0x2060, 0x6010, 0x2068, 0x080c, 0x9d16, 0x0158,
+	0x6850, 0xc0b5, 0x6852, 0x680c, 0x7a1c, 0xa206, 0x1120, 0x6808,
+	0x7a18, 0xa206, 0x01e0, 0x2001, 0x0105, 0x2003, 0x0010, 0x20e1,
+	0x9040, 0x7803, 0x0004, 0x7003, 0x0000, 0x7004, 0x2060, 0x080c,
+	0x99e6, 0x20e1, 0x9040, 0x080c, 0x82e4, 0x2011, 0x0000, 0x080c,
+	0x8106, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x002e, 0x0005, 0x6810,
+	0x6a14, 0xa205, 0x1d00, 0x684c, 0xc0dc, 0x684e, 0x2c10, 0x080c,
+	0x1fc5, 0x2001, 0x0105, 0x2003, 0x0010, 0x20e1, 0x9040, 0x7803,
+	0x0004, 0x7003, 0x0000, 0x2069, 0xb8e1, 0x6833, 0x0000, 0x683f,
+	0x0000, 0x08f8, 0x8840, 0x2805, 0xa005, 0x1170, 0x6004, 0xa005,
+	0x0168, 0x681a, 0x2060, 0x6034, 0xa084, 0x000f, 0xa080, 0x2308,
+	0x2045, 0x88ff, 0x090c, 0x151a, 0x8a51, 0x0005, 0x2050, 0x0005,
+	0x8a50, 0x8841, 0x2805, 0xa005, 0x1190, 0x2c00, 0xad06, 0x0120,
+	0x6000, 0xa005, 0x1108, 0x2d00, 0x2060, 0x681a, 0x6034, 0xa084,
+	0x000f, 0xa080, 0x2318, 0x2045, 0x88ff, 0x090c, 0x151a, 0x0005,
+	0x0000, 0x0011, 0x0015, 0x0019, 0x001d, 0x0021, 0x0025, 0x0029,
+	0x0000, 0x000f, 0x0015, 0x001b, 0x0021, 0x0027, 0x0000, 0x0000,
+	0x0000, 0x22fd, 0x22f9, 0x0000, 0x0000, 0x2307, 0x0000, 0x22fd,
+	0x0000, 0x2304, 0x2301, 0x0000, 0x0000, 0x0000, 0x2307, 0x2304,
+	0x0000, 0x22ff, 0x22ff, 0x0000, 0x0000, 0x2307, 0x0000, 0x22ff,
+	0x0000, 0x2305, 0x2305, 0x0000, 0x0000, 0x0000, 0x2307, 0x2305,
+	0x00a6, 0x0096, 0x0086, 0x6b2e, 0x6c2a, 0x6858, 0xa055, 0x0904,
+	0x23b9, 0x2d60, 0x6034, 0xa0cc, 0x000f, 0xa9c0, 0x2308, 0xa986,
+	0x0007, 0x0130, 0xa986, 0x000e, 0x0118, 0xa986, 0x000f, 0x1120,
+	0x605c, 0xa422, 0x6060, 0xa31b, 0x2805, 0xa045, 0x1140, 0x0310,
+	0x0804, 0x23b9, 0x6004, 0xa065, 0x0904, 0x23b9, 0x0c18, 0x2805,
+	0xa005, 0x01a8, 0xac68, 0xd99c, 0x1128, 0x6808, 0xa422, 0x680c,
+	0xa31b, 0x0020, 0x6810, 0xa422, 0x6814, 0xa31b, 0x0620, 0x2300,
+	0xa405, 0x0150, 0x8a51, 0x0904, 0x23b9, 0x8840, 0x0c40, 0x6004,
+	0xa065, 0x0904, 0x23b9, 0x0830, 0x8a51, 0x0904, 0x23b9, 0x8840,
+	0x2805, 0xa005, 0x1158, 0x6004, 0xa065, 0x0904, 0x23b9, 0x6034,
+	0xa0cc, 0x000f, 0xa9c0, 0x2308, 0x2805, 0x2040, 0x2b68, 0x6850,
+	0xc0fc, 0x6852, 0x0458, 0x8422, 0x8420, 0x831a, 0xa399, 0x0000,
+	0x00d6, 0x2b68, 0x6c6e, 0x6b72, 0x00de, 0xd99c, 0x1168, 0x6908,
+	0x2400, 0xa122, 0x690c, 0x2300, 0xa11b, 0x0a0c, 0x151a, 0x6800,
+	0xa420, 0x6804, 0xa319, 0x0060, 0x6910, 0x2400, 0xa122, 0x6914,
+	0x2300, 0xa11b, 0x0a0c, 0x151a, 0x6800, 0xa420, 0x6804, 0xa319,
+	0x2b68, 0x6c1e, 0x6b22, 0x6850, 0xc0fd, 0x6852, 0x2c00, 0x681a,
+	0x2800, 0x6832, 0x2a00, 0x6826, 0x000e, 0x000e, 0x000e, 0xa006,
+	0x0028, 0x008e, 0x009e, 0x00ae, 0xa085, 0x0001, 0x0005, 0x2001,
+	0x0005, 0x2004, 0xa084, 0x0007, 0x0002, 0x23cd, 0x23ce, 0x23d1,
+	0x23d4, 0x23d9, 0x23dc, 0x23e1, 0x23e6, 0x0005, 0x080c, 0x216d,
+	0x0005, 0x080c, 0x1b22, 0x0005, 0x080c, 0x1b22, 0x080c, 0x216d,
+	0x0005, 0x080c, 0x1720, 0x0005, 0x080c, 0x216d, 0x080c, 0x1720,
+	0x0005, 0x080c, 0x1b22, 0x080c, 0x1720, 0x0005, 0x080c, 0x1b22,
+	0x080c, 0x216d, 0x080c, 0x1720, 0x0005, 0x0006, 0x7000, 0xa086,
+	0x0001, 0x1158, 0x701c, 0xa506, 0x1140, 0x7020, 0xa406, 0x1128,
+	0x7024, 0xa706, 0x1110, 0x7028, 0xa606, 0x000e, 0x0005, 0x0126,
+	0x2091, 0x2600, 0x2079, 0x0200, 0x2071, 0xbc80, 0x2069, 0xb600,
+	0x080c, 0x24f5, 0x080c, 0x24e5, 0x2009, 0x0004, 0x7912, 0x7817,
+	0x0004, 0x080c, 0x282d, 0x781b, 0x0002, 0x20e1, 0x9080, 0x20e1,
+	0x4000, 0x20a9, 0x0080, 0x782f, 0x0000, 0x1f04, 0x241b, 0x20e1,
+	0x9080, 0x783b, 0x001f, 0x20e1, 0x8700, 0x012e, 0x0005, 0x0126,
+	0x2091, 0x2600, 0x781c, 0xd0a4, 0x190c, 0x24e2, 0xa084, 0x0007,
+	0x0002, 0x244b, 0x2439, 0x243c, 0x243f, 0x2444, 0x2446, 0x2448,
+	0x244a, 0x080c, 0x6436, 0x0078, 0x080c, 0x6475, 0x0060, 0x080c,
+	0x6436, 0x080c, 0x6475, 0x0038, 0x0041, 0x0028, 0x0031, 0x0018,
+	0x0021, 0x0008, 0x0011, 0x012e, 0x0005, 0x0006, 0x0016, 0x0026,
+	0x080c, 0xb50c, 0x7930, 0xa184, 0x0003, 0x01b0, 0x2001, 0xb8f0,
+	0x2004, 0xa005, 0x0170, 0x2001, 0x0133, 0x2004, 0xa005, 0x090c,
+	0x151a, 0x00c6, 0x2001, 0xb8f0, 0x2064, 0x080c, 0x99e6, 0x00ce,
+	0x04b8, 0x20e1, 0x9040, 0x04a0, 0xa184, 0x0030, 0x01e0, 0x6a00,
+	0xa286, 0x0003, 0x1108, 0x00a0, 0x080c, 0x5b41, 0x1178, 0x2001,
+	0xb89f, 0x2003, 0x0001, 0x2001, 0xb600, 0x2003, 0x0001, 0xa085,
+	0x0001, 0x080c, 0x5b85, 0x080c, 0x5a79, 0x0010, 0x080c, 0x4b7b,
+	0x080c, 0x24e5, 0x00a8, 0xa184, 0x00c0, 0x0168, 0x00e6, 0x0036,
+	0x0046, 0x0056, 0x2071, 0xb924, 0x080c, 0x1e1a, 0x005e, 0x004e,
+	0x003e, 0x00ee, 0x0028, 0xa184, 0x0300, 0x0110, 0x20e1, 0x9020,
+	0x7932, 0x002e, 0x001e, 0x000e, 0x0005, 0x0016, 0x00e6, 0x00f6,
+	0x2071, 0xb600, 0x7128, 0x2001, 0xb891, 0x2102, 0x2001, 0xb899,
+	0x2102, 0xa182, 0x0211, 0x1218, 0x2009, 0x0008, 0x0400, 0xa182,
+	0x0259, 0x1218, 0x2009, 0x0007, 0x00d0, 0xa182, 0x02c1, 0x1218,
+	0x2009, 0x0006, 0x00a0, 0xa182, 0x0349, 0x1218, 0x2009, 0x0005,
+	0x0070, 0xa182, 0x0421, 0x1218, 0x2009, 0x0004, 0x0040, 0xa182,
+	0x0581, 0x1218, 0x2009, 0x0003, 0x0010, 0x2009, 0x0002, 0x2079,
+	0x0200, 0x7912, 0x7817, 0x0004, 0x080c, 0x282d, 0x00fe, 0x00ee,
+	0x001e, 0x0005, 0x7938, 0x080c, 0x151a, 0x00e6, 0x0026, 0x2071,
+	0x0200, 0x20e1, 0x1000, 0x7220, 0x7028, 0x7020, 0xa206, 0x0de0,
+	0x20e1, 0x9010, 0x002e, 0x00ee, 0x0005, 0x20e1, 0xa000, 0x7837,
+	0x0001, 0x782f, 0x0000, 0x782f, 0x0000, 0x782f, 0x0000, 0x782f,
+	0x0000, 0x7837, 0x0005, 0x20a9, 0x0210, 0x7830, 0xd0bc, 0x1110,
+	0x1f04, 0x2505, 0x7837, 0x0001, 0x7837, 0x0000, 0xe000, 0xe000,
+	0x20e1, 0xa000, 0x0005, 0x0126, 0x2091, 0x2800, 0x2061, 0x0100,
+	0x2071, 0xb600, 0x6024, 0x6026, 0x6053, 0x0030, 0x080c, 0x286c,
+	0x6050, 0xa084, 0xfe7f, 0x6052, 0x2009, 0x00ef, 0x6132, 0x6136,
+	0x080c, 0x287c, 0x60e7, 0x0000, 0x61ea, 0x60e3, 0x0008, 0x604b,
+	0xf7f7, 0x6043, 0x0000, 0x602f, 0x0080, 0x602f, 0x0000, 0x6007,
+	0x0e9f, 0x601b, 0x001e, 0x600f, 0x00ff, 0x2001, 0xb88d, 0x2003,
+	0x00ff, 0x602b, 0x002f, 0x012e, 0x0005, 0x2001, 0xb632, 0x2003,
+	0x0000, 0x2001, 0xb631, 0x2003, 0x0001, 0x0005, 0x0126, 0x2091,
+	0x2800, 0x0006, 0x0016, 0x0026, 0x6124, 0xa184, 0x1e2c, 0x1118,
+	0xa184, 0x0007, 0x002a, 0xa195, 0x0004, 0xa284, 0x0007, 0x0002,
+	0x2582, 0x2568, 0x256b, 0x256e, 0x2573, 0x2575, 0x2579, 0x257d,
+	0x080c, 0x6be6, 0x00b8, 0x080c, 0x6cc1, 0x00a0, 0x080c, 0x6cc1,
+	0x080c, 0x6be6, 0x0078, 0x0099, 0x0068, 0x080c, 0x6be6, 0x0079,
+	0x0048, 0x080c, 0x6cc1, 0x0059, 0x0028, 0x080c, 0x6cc1, 0x080c,
+	0x6be6, 0x0029, 0x002e, 0x001e, 0x000e, 0x012e, 0x0005, 0x6124,
+	0x6028, 0xd09c, 0x0118, 0xd19c, 0x1904, 0x279b, 0x080c, 0x5b41,
+	0x0578, 0x7000, 0xa086, 0x0003, 0x0198, 0x6024, 0xa084, 0x1800,
+	0x0178, 0x080c, 0x5b67, 0x0118, 0x080c, 0x5b53, 0x1148, 0x6027,
+	0x0020, 0x6043, 0x0000, 0x2001, 0xb89e, 0x2003, 0xaaaa, 0x0458,
+	0x080c, 0x5b67, 0x15d0, 0x6024, 0xa084, 0x1800, 0x1108, 0x04a8,
+	0x2001, 0xb89e, 0x2003, 0xaaaa, 0x2001, 0xb89f, 0x2003, 0x0001,
+	0x2001, 0xb600, 0x2003, 0x0001, 0x080c, 0x5a79, 0x0804, 0x279b,
+	0xd1ac, 0x1518, 0x6024, 0xd0dc, 0x1170, 0xd0e4, 0x1188, 0xd0d4,
+	0x11a0, 0xd0cc, 0x0130, 0x708c, 0xa086, 0x0028, 0x1110, 0x080c,
+	0x5cd0, 0x0804, 0x279b, 0x2001, 0xb89f, 0x2003, 0x0000, 0x0048,
+	0x2001, 0xb89f, 0x2003, 0x0002, 0x0020, 0x080c, 0x5c43, 0x0804,
+	0x279b, 0x080c, 0x5d75, 0x0804, 0x279b, 0xd1ac, 0x0904, 0x26e3,
+	0x080c, 0x5b41, 0x11d8, 0x6027, 0x0020, 0x0006, 0x0026, 0x0036,
+	0x080c, 0x5b5d, 0x1170, 0x2001, 0xb89f, 0x2003, 0x0001, 0x2001,
+	0xb600, 0x2003, 0x0001, 0x080c, 0x5a79, 0x003e, 0x002e, 0x000e,
+	0x0005, 0x003e, 0x002e, 0x000e, 0x080c, 0x5b18, 0x0016, 0x0046,
+	0x00c6, 0x644c, 0xa486, 0xf0f0, 0x1138, 0x2061, 0x0100, 0x644a,
+	0x6043, 0x0090, 0x6043, 0x0010, 0x74ce, 0xa48c, 0xff00, 0x7034,
+	0xd084, 0x0178, 0xa186, 0xf800, 0x1160, 0x703c, 0xd084, 0x1148,
+	0xc085, 0x703e, 0x0036, 0x2418, 0x2011, 0x8016, 0x080c, 0x3f13,
+	0x003e, 0xa196, 0xff00, 0x05b8, 0x7054, 0xa084, 0x00ff, 0x810f,
+	0xa116, 0x0588, 0x7130, 0xd184, 0x1570, 0x2011, 0xb653, 0x2214,
+	0xd2ec, 0x0138, 0xc18d, 0x7132, 0x2011, 0xb653, 0x2214, 0xd2ac,
+	0x1510, 0x6240, 0xa294, 0x0010, 0x0130, 0x6248, 0xa294, 0xff00,
+	0xa296, 0xff00, 0x01c0, 0x7030, 0xd08c, 0x0904, 0x26b0, 0x7034,
+	0xd08c, 0x1140, 0x2001, 0xb60c, 0x200c, 0xd1ac, 0x1904, 0x26b0,
+	0xc1ad, 0x2102, 0x0036, 0x73cc, 0x2011, 0x8013, 0x080c, 0x3f13,
+	0x003e, 0x0804, 0x26b0, 0x7034, 0xd08c, 0x1140, 0x2001, 0xb60c,
+	0x200c, 0xd1ac, 0x1904, 0x26b0, 0xc1ad, 0x2102, 0x0036, 0x73cc,
+	0x2011, 0x8013, 0x080c, 0x3f13, 0x003e, 0x7130, 0xc185, 0x7132,
+	0x2011, 0xb653, 0x220c, 0xd1a4, 0x01d0, 0x0016, 0x2009, 0x0001,
+	0x2011, 0x0100, 0x080c, 0x6b8c, 0x2019, 0x000e, 0x080c, 0xb121,
+	0xa484, 0x00ff, 0xa080, 0x2df9, 0x200d, 0xa18c, 0xff00, 0x810f,
+	0x8127, 0xa006, 0x2009, 0x000e, 0x080c, 0xb1a4, 0x001e, 0xd1ac,
+	0x1148, 0x0016, 0x2009, 0x0000, 0x2019, 0x0004, 0x080c, 0x2ca4,
+	0x001e, 0x0070, 0x0156, 0x20a9, 0x007f, 0x2009, 0x0000, 0x080c,
+	0x501b, 0x1110, 0x080c, 0x4c7e, 0x8108, 0x1f04, 0x26a7, 0x015e,
+	0x00ce, 0x004e, 0x2011, 0x0003, 0x080c, 0x80fc, 0x2011, 0x0002,
+	0x080c, 0x8106, 0x080c, 0x7fe0, 0x0036, 0x2019, 0x0000, 0x080c,
+	0x806b, 0x003e, 0x60e3, 0x0000, 0x001e, 0x2001, 0xb600, 0x2014,
+	0xa296, 0x0004, 0x1128, 0xd19c, 0x11b0, 0x6228, 0xc29d, 0x622a,
+	0x2003, 0x0001, 0x2001, 0xb623, 0x2003, 0x0000, 0x6027, 0x0020,
+	0x080c, 0x5b67, 0x1140, 0x0016, 0x2009, 0x07d0, 0x2011, 0x5a56,
+	0x080c, 0x6a94, 0x001e, 0xd194, 0x0904, 0x279b, 0x0016, 0x6220,
+	0xd2b4, 0x0904, 0x274c, 0x080c, 0x6a82, 0x080c, 0x7df3, 0x6027,
+	0x0004, 0x00f6, 0x2019, 0xb8ea, 0x2304, 0xa07d, 0x0570, 0x7804,
+	0xa086, 0x0032, 0x1550, 0x00d6, 0x00c6, 0x00e6, 0x2069, 0x0140,
+	0x618c, 0x6288, 0x7818, 0x608e, 0x7808, 0x608a, 0x6043, 0x0002,
+	0x2001, 0x0003, 0x8001, 0x1df0, 0x6043, 0x0000, 0x6803, 0x1000,
+	0x6803, 0x0000, 0x618e, 0x628a, 0x080c, 0x7102, 0x080c, 0x71e5,
+	0x7810, 0x2070, 0x7037, 0x0103, 0x2f60, 0x080c, 0x86a4, 0x00ee,
+	0x00ce, 0x00de, 0x00fe, 0x001e, 0x0005, 0x00fe, 0x00d6, 0x2069,
+	0x0140, 0x6804, 0xa084, 0x4000, 0x0120, 0x6803, 0x1000, 0x6803,
+	0x0000, 0x00de, 0x00c6, 0x2061, 0xb8e1, 0x6028, 0xa09a, 0x00c8,
+	0x1238, 0x8000, 0x602a, 0x00ce, 0x080c, 0x7de6, 0x0804, 0x279a,
+	0x2019, 0xb8ea, 0x2304, 0xa065, 0x0120, 0x2009, 0x0027, 0x080c,
+	0x86d3, 0x00ce, 0x0804, 0x279a, 0xd2bc, 0x0904, 0x279a, 0x080c,
+	0x6a8f, 0x6014, 0xa084, 0x0184, 0xa085, 0x0010, 0x6016, 0x6027,
+	0x0004, 0x00d6, 0x2069, 0x0140, 0x6804, 0xa084, 0x4000, 0x0120,
+	0x6803, 0x1000, 0x6803, 0x0000, 0x00de, 0x00c6, 0x2061, 0xb8e1,
+	0x6044, 0xa09a, 0x00c8, 0x12f0, 0x8000, 0x6046, 0x603c, 0x00ce,
+	0xa005, 0x0540, 0x2009, 0x07d0, 0x080c, 0x6a87, 0xa080, 0x0007,
+	0x2004, 0xa086, 0x0006, 0x1138, 0x6114, 0xa18c, 0x0184, 0xa18d,
+	0x0012, 0x6116, 0x00b8, 0x6114, 0xa18c, 0x0184, 0xa18d, 0x0016,
+	0x6116, 0x0080, 0x0036, 0x2019, 0x0001, 0x080c, 0x806b, 0x003e,
+	0x2019, 0xb8f0, 0x2304, 0xa065, 0x0120, 0x2009, 0x004f, 0x080c,
+	0x86d3, 0x00ce, 0x001e, 0xd19c, 0x0904, 0x27f4, 0x7034, 0xd0ac,
+	0x1560, 0x0016, 0x0156, 0x6027, 0x0008, 0x602f, 0x0020, 0x20a9,
+	0x0006, 0x1d04, 0x27a9, 0x2091, 0x6000, 0x1f04, 0x27a9, 0x602f,
+	0x0000, 0x6150, 0xa185, 0x1400, 0x6052, 0x20a9, 0x0366, 0x1d04,
+	0x27b7, 0x2091, 0x6000, 0x6020, 0xd09c, 0x1130, 0x015e, 0x6152,
+	0x001e, 0x6027, 0x0008, 0x0480, 0x080c, 0x293c, 0x1f04, 0x27b7,
+	0x015e, 0x6152, 0x001e, 0x6027, 0x0008, 0x0016, 0x6028, 0xc09c,
+	0x602a, 0x2011, 0x0003, 0x080c, 0x80fc, 0x2011, 0x0002, 0x080c,
+	0x8106, 0x080c, 0x7fe0, 0x0036, 0x2019, 0x0000, 0x080c, 0x806b,
+	0x003e, 0x60e3, 0x0000, 0x080c, 0xb4eb, 0x080c, 0xb506, 0xa085,
+	0x0001, 0x080c, 0x5b85, 0x2001, 0xb600, 0x2003, 0x0004, 0x6027,
+	0x0008, 0x080c, 0x12e2, 0x001e, 0xa18c, 0xffd0, 0x6126, 0x0005,
+	0x0006, 0x0016, 0x0026, 0x00e6, 0x00f6, 0x0126, 0x2091, 0x8000,
+	0x2071, 0xb600, 0x71c4, 0x70c6, 0xa116, 0x0500, 0x81ff, 0x0128,
+	0x2011, 0x8011, 0x080c, 0x3f13, 0x00c8, 0x2011, 0x8012, 0x080c,
+	0x3f13, 0x2001, 0xb672, 0x2004, 0xd0fc, 0x1180, 0x0036, 0x00c6,
+	0x080c, 0x28c7, 0x080c, 0x7fbc, 0x2061, 0x0100, 0x2019, 0x0028,
+	0x2009, 0x0000, 0x080c, 0x2ca4, 0x00ce, 0x003e, 0x012e, 0x00fe,
+	0x00ee, 0x002e, 0x001e, 0x000e, 0x0005, 0x00c6, 0x00f6, 0x0006,
+	0x0026, 0x2061, 0x0100, 0xa190, 0x2840, 0x2205, 0x60f2, 0x2011,
+	0x284d, 0x2205, 0x60ee, 0x002e, 0x000e, 0x00fe, 0x00ce, 0x0005,
+	0x0840, 0x0840, 0x0840, 0x0580, 0x0420, 0x0348, 0x02c0, 0x0258,
+	0x0210, 0x01a8, 0x01a8, 0x01a8, 0x01a8, 0x0140, 0x00f8, 0x00d0,
+	0x00b0, 0x00a0, 0x2028, 0xa18c, 0x00ff, 0x2130, 0xa094, 0xff00,
+	0x1110, 0x81ff, 0x0118, 0x080c, 0x6723, 0x0038, 0xa080, 0x2df9,
+	0x200d, 0xa18c, 0xff00, 0x810f, 0xa006, 0x0005, 0xa080, 0x2df9,
+	0x200d, 0xa18c, 0x00ff, 0x0005, 0x00d6, 0x2069, 0x0140, 0x2001,
+	0xb615, 0x2003, 0x00ef, 0x20a9, 0x0010, 0xa006, 0x6852, 0x6856,
+	0x1f04, 0x2877, 0x00de, 0x0005, 0x0006, 0x00d6, 0x0026, 0x2069,
+	0x0140, 0x2001, 0xb615, 0x2102, 0x8114, 0x8214, 0x8214, 0x8214,
+	0x20a9, 0x0010, 0x6853, 0x0000, 0xa006, 0x82ff, 0x1128, 0xa184,
+	0x000f, 0xa080, 0xb51a, 0x2005, 0x6856, 0x8211, 0x1f04, 0x288c,
+	0x002e, 0x00de, 0x000e, 0x0005, 0x00c6, 0x2061, 0xb600, 0x6030,
+	0x0110, 0xc09d, 0x0008, 0xc09c, 0x6032, 0x00ce, 0x0005, 0x0156,
+	0x00d6, 0x0026, 0x0016, 0x0006, 0x2069, 0x0140, 0x6980, 0xa116,
+	0x0180, 0xa112, 0x1230, 0x8212, 0x8210, 0x22a8, 0x2001, 0x0402,
+	0x0018, 0x22a8, 0x2001, 0x0404, 0x680e, 0x1f04, 0x28bc, 0x680f,
+	0x0000, 0x000e, 0x001e, 0x002e, 0x00de, 0x015e, 0x0005, 0x2001,
+	0xb653, 0x2004, 0xd0c4, 0x0150, 0xd0a4, 0x0140, 0xa006, 0x0046,
+	0x2020, 0x2009, 0x002e, 0x080c, 0xb1a4, 0x004e, 0x0005, 0x00f6,
+	0x0016, 0x0026, 0x2079, 0x0140, 0x78c4, 0xd0dc, 0x0548, 0xa084,
+	0x0700, 0xa08e, 0x0300, 0x1520, 0x2011, 0x0000, 0x2009, 0x0002,
+	0x2300, 0xa080, 0x0020, 0x2018, 0x2300, 0x080c, 0x6bb2, 0x2011,
+	0x0030, 0x2200, 0x8007, 0xa085, 0x004c, 0x78c2, 0x2009, 0x0204,
+	0x210c, 0x2200, 0xa100, 0x2009, 0x0138, 0x200a, 0x080c, 0x5b41,
+	0x1118, 0x2009, 0xb88f, 0x200a, 0x002e, 0x001e, 0x00fe, 0x0005,
+	0x78c3, 0x0000, 0x0cc8, 0x0126, 0x2091, 0x2800, 0x0006, 0x0016,
+	0x0026, 0x2001, 0x0170, 0x200c, 0x8000, 0x2014, 0xa184, 0x0003,
+	0x0110, 0x0804, 0x1b20, 0x002e, 0x001e, 0x000e, 0x012e, 0x0005,
+	0x0006, 0x2001, 0x0100, 0x2004, 0xa082, 0x0005, 0x000e, 0x0268,
+	0x2001, 0x0170, 0x200c, 0xa18c, 0x00ff, 0xa18e, 0x004c, 0x1128,
+	0x200c, 0xa18c, 0xff00, 0x810f, 0x0010, 0x2009, 0x0000, 0x2001,
+	0x0204, 0x2004, 0xa108, 0x0005, 0x0006, 0x0156, 0x00f6, 0x2079,
+	0x0100, 0x20a9, 0x000a, 0x7854, 0xd08c, 0x1110, 0x1f04, 0x2943,
+	0x00fe, 0x015e, 0x000e, 0x0005, 0x0016, 0x00c6, 0x0006, 0x2061,
+	0x0100, 0x6030, 0x0006, 0x6048, 0x0006, 0x60e4, 0x0006, 0x60e8,
+	0x0006, 0x6050, 0x0006, 0x60f0, 0x0006, 0x60ec, 0x0006, 0x600c,
+	0x0006, 0x6004, 0x0006, 0x6028, 0x0006, 0x60e0, 0x0006, 0x602f,
+	0x0100, 0x602f, 0x0000, 0xe000, 0xe000, 0xe000, 0xe000, 0x602f,
+	0x0040, 0x602f, 0x0000, 0x000e, 0x60e2, 0x000e, 0x602a, 0x000e,
+	0x6006, 0x000e, 0x600e, 0x000e, 0x60ee, 0x000e, 0x60f2, 0x000e,
+	0x6052, 0x000e, 0x60ea, 0x000e, 0x60e6, 0x000e, 0x604a, 0x000e,
+	0x6032, 0x6036, 0x2008, 0x080c, 0x287c, 0x000e, 0x00ce, 0x001e,
+	0x0005, 0x2009, 0x0171, 0x2104, 0xd0dc, 0x0140, 0x2009, 0x0170,
+	0x2104, 0x200b, 0x0080, 0xe000, 0xe000, 0x200a, 0x0005, 0x2a2f,
+	0x2a33, 0x2a37, 0x2a3d, 0x2a43, 0x2a49, 0x2a4f, 0x2a57, 0x2a5f,
+	0x2a65, 0x2a6b, 0x2a73, 0x2a7b, 0x2a83, 0x2a8b, 0x2a95, 0x2ae2,
+	0x2ae2, 0x2ae2, 0x2ae2, 0x2ae2, 0x2ae2, 0x2ae2, 0x2ae2, 0x2ae2,
+	0x2ae2, 0x2ae2, 0x2ae2, 0x2ae2, 0x2ae2, 0x2ae2, 0x2ae2, 0x2a9f,
+	0x2a9f, 0x2a9f, 0x2a9f, 0x2a9f, 0x2a9f, 0x2a9f, 0x2a9f, 0x2a9f,
+	0x2a9f, 0x2a9f, 0x2a9f, 0x2a9f, 0x2a9f, 0x2a9f, 0x2a9f, 0x2ae2,
+	0x2ae2, 0x2ae2, 0x2ae2, 0x2ae2, 0x2ae2, 0x2ae2, 0x2ae2, 0x2ae2,
+	0x2ae2, 0x2ae2, 0x2ae2, 0x2ae2, 0x2ae2, 0x2ae2, 0x2ae2, 0x2aa1,
+	0x2aa1, 0x2aa7, 0x2aa7, 0x2aae, 0x2aae, 0x2ab5, 0x2ab5, 0x2abe,
+	0x2abe, 0x2ac5, 0x2ac5, 0x2ace, 0x2ace, 0x2ad7, 0x2ad7, 0x2ae2,
+	0x2ae2, 0x2ae2, 0x2ae2, 0x2ae2, 0x2ae2, 0x2ae2, 0x2ae2, 0x2ae2,
+	0x2ae2, 0x2ae2, 0x2ae2, 0x2ae2, 0x2ae2, 0x2ae2, 0x2ae2, 0x2a9f,
+	0x2a9f, 0x2a9f, 0x2a9f, 0x2a9f, 0x2a9f, 0x2a9f, 0x2a9f, 0x2a9f,
+	0x2a9f, 0x2a9f, 0x2a9f, 0x2a9f, 0x2a9f, 0x2a9f, 0x2a9f, 0x2ae2,
+	0x2ae2, 0x2ae2, 0x2ae2, 0x2ae2, 0x2ae2, 0x2ae2, 0x2ae2, 0x2ae2,
+	0x2ae2, 0x2ae2, 0x2ae2, 0x2ae2, 0x2ae2, 0x2ae2, 0x2ae2, 0x2a9f,
+	0x2a9f, 0x2a9f, 0x2a9f, 0x2a9f, 0x2a9f, 0x2a9f, 0x2a9f, 0x2a9f,
+	0x2a9f, 0x2a9f, 0x2a9f, 0x2a9f, 0x2a9f, 0x2a9f, 0x2a9f, 0x0106,
+	0x0006, 0x0804, 0x2aea, 0x0106, 0x0006, 0x0804, 0x2aea, 0x0106,
+	0x0006, 0x080c, 0x254e, 0x0804, 0x2aea, 0x0106, 0x0006, 0x080c,
+	0x254e, 0x0804, 0x2aea, 0x0106, 0x0006, 0x080c, 0x23bf, 0x0804,
+	0x2aea, 0x0106, 0x0006, 0x080c, 0x23bf, 0x0804, 0x2aea, 0x0106,
+	0x0006, 0x080c, 0x254e, 0x080c, 0x23bf, 0x0804, 0x2aea, 0x0106,
+	0x0006, 0x080c, 0x254e, 0x080c, 0x23bf, 0x0804, 0x2aea, 0x0106,
+	0x0006, 0x080c, 0x2427, 0x0804, 0x2aea, 0x0106, 0x0006, 0x080c,
+	0x2427, 0x0804, 0x2aea, 0x0106, 0x0006, 0x080c, 0x254e, 0x080c,
+	0x2427, 0x0804, 0x2aea, 0x0106, 0x0006, 0x080c, 0x254e, 0x080c,
+	0x2427, 0x0804, 0x2aea, 0x0106, 0x0006, 0x080c, 0x23bf, 0x080c,
+	0x2427, 0x0804, 0x2aea, 0x0106, 0x0006, 0x080c, 0x23bf, 0x080c,
+	0x2427, 0x0804, 0x2aea, 0x0106, 0x0006, 0x080c, 0x254e, 0x080c,
+	0x23bf, 0x080c, 0x2427, 0x0804, 0x2aea, 0x0106, 0x0006, 0x080c,
+	0x254e, 0x080c, 0x23bf, 0x080c, 0x2427, 0x0804, 0x2aea, 0xe000,
+	0x0cf0, 0x0106, 0x0006, 0x080c, 0x290b, 0x0804, 0x2aea, 0x0106,
+	0x0006, 0x080c, 0x290b, 0x080c, 0x254e, 0x04e0, 0x0106, 0x0006,
+	0x080c, 0x290b, 0x080c, 0x23bf, 0x04a8, 0x0106, 0x0006, 0x080c,
+	0x290b, 0x080c, 0x254e, 0x080c, 0x23bf, 0x0460, 0x0106, 0x0006,
+	0x080c, 0x290b, 0x080c, 0x2427, 0x0428, 0x0106, 0x0006, 0x080c,
+	0x290b, 0x080c, 0x254e, 0x080c, 0x2427, 0x00e0, 0x0106, 0x0006,
+	0x080c, 0x290b, 0x080c, 0x23bf, 0x080c, 0x2427, 0x0098, 0x0106,
+	0x0006, 0x080c, 0x290b, 0x080c, 0x254e, 0x080c, 0x23bf, 0x080c,
+	0x2427, 0x0040, 0x20d1, 0x0000, 0x20d1, 0x0001, 0x20d1, 0x0000,
+	0x080c, 0x151a, 0x000e, 0x010e, 0x000d, 0x00c6, 0x0026, 0x0046,
+	0x2021, 0x0000, 0x080c, 0x537b, 0x1904, 0x2bca, 0x72d4, 0x2001,
+	0xb89e, 0x2004, 0xa005, 0x1110, 0xd29c, 0x0148, 0xd284, 0x1138,
+	0xd2bc, 0x1904, 0x2bca, 0x080c, 0x2bce, 0x0804, 0x2bca, 0xd2cc,
+	0x1904, 0x2bca, 0x080c, 0x5b41, 0x1120, 0x709f, 0xffff, 0x0804,
+	0x2bca, 0xd294, 0x0120, 0x709f, 0xffff, 0x0804, 0x2bca, 0x2001,
+	0xb615, 0x203c, 0x7288, 0xd284, 0x0904, 0x2b6c, 0xd28c, 0x1904,
+	0x2b6c, 0x0036, 0x739c, 0xa38e, 0xffff, 0x1110, 0x2019, 0x0001,
+	0x8314, 0xa2e0, 0xbdc0, 0x2c04, 0xa38c, 0x0001, 0x0120, 0xa084,
+	0xff00, 0x8007, 0x0010, 0xa084, 0x00ff, 0xa70e, 0x0560, 0xa08e,
+	0x0000, 0x0548, 0xa08e, 0x00ff, 0x1150, 0x7230, 0xd284, 0x1538,
+	0x7288, 0xc28d, 0x728a, 0x709f, 0xffff, 0x003e, 0x0428, 0x2009,
+	0x0000, 0x080c, 0x2852, 0x080c, 0x4fbf, 0x11b8, 0x6004, 0xa084,
+	0x00ff, 0xa086, 0x0006, 0x1150, 0x7030, 0xd08c, 0x0118, 0x6000,
+	0xd0bc, 0x0120, 0x080c, 0x2be1, 0x0140, 0x0028, 0x080c, 0x2d12,
+	0x080c, 0x2c0f, 0x0110, 0x8318, 0x0818, 0x739e, 0x0010, 0x709f,
+	0xffff, 0x003e, 0x0804, 0x2bca, 0xa780, 0x2df9, 0x203d, 0xa7bc,
+	0xff00, 0x873f, 0x2041, 0x007e, 0x709c, 0xa096, 0xffff, 0x1120,
+	0x2009, 0x0000, 0x28a8, 0x0050, 0xa812, 0x0220, 0x2008, 0xa802,
+	0x20a8, 0x0020, 0x709f, 0xffff, 0x0804, 0x2bca, 0x2700, 0x0156,
+	0x0016, 0xa106, 0x05a0, 0xc484, 0x080c, 0x501b, 0x0120, 0x080c,
+	0x4fbf, 0x15a8, 0x0008, 0xc485, 0x6004, 0xa084, 0x00ff, 0xa086,
+	0x0006, 0x1130, 0x7030, 0xd08c, 0x01e8, 0x6000, 0xd0bc, 0x11d0,
+	0x7288, 0xd28c, 0x0188, 0x6004, 0xa084, 0x00ff, 0xa082, 0x0006,
+	0x02b0, 0xd484, 0x1118, 0x080c, 0x4fde, 0x0028, 0x080c, 0x2d9f,
+	0x0170, 0x080c, 0x2dcc, 0x0058, 0x080c, 0x2d12, 0x080c, 0x2c0f,
+	0x0170, 0x0028, 0x080c, 0x2d9f, 0x0110, 0x0419, 0x0140, 0x001e,
+	0x8108, 0x015e, 0x1f04, 0x2b86, 0x709f, 0xffff, 0x0018, 0x001e,
+	0x015e, 0x719e, 0x004e, 0x002e, 0x00ce, 0x0005, 0x00c6, 0x0016,
+	0x709f, 0x0001, 0x2009, 0x007e, 0x080c, 0x4fbf, 0x1138, 0x080c,
+	0x2d12, 0x04a9, 0x0118, 0x70d4, 0xc0bd, 0x70d6, 0x001e, 0x00ce,
+	0x0005, 0x0016, 0x0076, 0x00d6, 0x00c6, 0x2c68, 0x2001, 0xb657,
+	0x2004, 0xa084, 0x00ff, 0x6842, 0x080c, 0x9f92, 0x01d8, 0x2d00,
+	0x601a, 0x080c, 0xa0e3, 0x601f, 0x0001, 0x2001, 0x0000, 0x080c,
+	0x4f5d, 0x2001, 0x0000, 0x080c, 0x4f6f, 0x0126, 0x2091, 0x8000,
+	0x7098, 0x8000, 0x709a, 0x012e, 0x2009, 0x0004, 0x080c, 0x86d3,
+	0xa085, 0x0001, 0x00ce, 0x00de, 0x007e, 0x001e, 0x0005, 0x0016,
+	0x0076, 0x00d6, 0x00c6, 0x2c68, 0x2001, 0xb657, 0x2004, 0xa084,
+	0x00ff, 0x6842, 0x080c, 0x9f92, 0x0550, 0x2d00, 0x601a, 0x6800,
+	0xc0c4, 0x6802, 0x68a0, 0xa086, 0x007e, 0x0140, 0x6804, 0xa084,
+	0x00ff, 0xa086, 0x0006, 0x1110, 0x080c, 0x2cd1, 0x080c, 0xa0e3,
+	0x601f, 0x0001, 0x2001, 0x0000, 0x080c, 0x4f5d, 0x2001, 0x0002,
+	0x080c, 0x4f6f, 0x0126, 0x2091, 0x8000, 0x7098, 0x8000, 0x709a,
+	0x012e, 0x2009, 0x0002, 0x080c, 0x86d3, 0xa085, 0x0001, 0x00ce,
+	0x00de, 0x007e, 0x001e, 0x0005, 0x00c6, 0x0026, 0x2009, 0x0080,
+	0x080c, 0x4fbf, 0x1120, 0x0031, 0x0110, 0x70db, 0xffff, 0x002e,
+	0x00ce, 0x0005, 0x0016, 0x0076, 0x00d6, 0x00c6, 0x2c68, 0x080c,
+	0x864e, 0x01e8, 0x2d00, 0x601a, 0x080c, 0xa0e3, 0x601f, 0x0001,
+	0x2001, 0x0000, 0x080c, 0x4f5d, 0x2001, 0x0002, 0x080c, 0x4f6f,
+	0x0126, 0x2091, 0x8000, 0x080c, 0x2cd1, 0x70dc, 0x8000, 0x70de,
+	0x012e, 0x2009, 0x0002, 0x080c, 0x86d3, 0xa085, 0x0001, 0x00ce,
+	0x00de, 0x007e, 0x001e, 0x0005, 0x00c6, 0x00d6, 0x0126, 0x2091,
+	0x8000, 0x2009, 0x007f, 0x080c, 0x4fbf, 0x1190, 0x2c68, 0x080c,
+	0x864e, 0x0170, 0x2d00, 0x601a, 0x6312, 0x601f, 0x0001, 0x620a,
+	0x080c, 0xa0e3, 0x2009, 0x0022, 0x080c, 0x86d3, 0xa085, 0x0001,
+	0x012e, 0x00de, 0x00ce, 0x0005, 0x00e6, 0x00c6, 0x0066, 0x0036,
+	0x0026, 0x080c, 0x6e73, 0x080c, 0x6e16, 0x080c, 0x90fb, 0x2130,
+	0x81ff, 0x0128, 0x20a9, 0x007e, 0x2009, 0x0000, 0x0020, 0x20a9,
+	0x007f, 0x2009, 0x0000, 0x0016, 0x080c, 0x501b, 0x1120, 0x080c,
+	0x521c, 0x080c, 0x4c7e, 0x001e, 0x8108, 0x1f04, 0x2cbb, 0x86ff,
+	0x1110, 0x080c, 0x11f5, 0x002e, 0x003e, 0x006e, 0x00ce, 0x00ee,
+	0x0005, 0x00e6, 0x00c6, 0x0036, 0x0026, 0x0016, 0x6218, 0x2270,
+	0x72a0, 0x0026, 0x2019, 0x0029, 0x080c, 0x6e67, 0x0076, 0x2039,
+	0x0000, 0x080c, 0x6d74, 0x2c08, 0x080c, 0xaf3e, 0x007e, 0x001e,
+	0x2e60, 0x080c, 0x521c, 0x6210, 0x6314, 0x080c, 0x4c7e, 0x6212,
+	0x6316, 0x001e, 0x002e, 0x003e, 0x00ce, 0x00ee, 0x0005, 0x00e6,
+	0x0006, 0x6018, 0xa080, 0x0028, 0x2004, 0xa086, 0x0080, 0x0150,
+	0x2071, 0xb600, 0x7098, 0xa005, 0x0110, 0x8001, 0x709a, 0x000e,
+	0x00ee, 0x0005, 0x2071, 0xb600, 0x70dc, 0xa005, 0x0dc0, 0x8001,
+	0x70de, 0x0ca8, 0x6000, 0xc08c, 0x6002, 0x0005, 0x00f6, 0x00e6,
+	0x00c6, 0x0036, 0x0026, 0x0016, 0x0156, 0x2178, 0x81ff, 0x1118,
+	0x20a9, 0x0001, 0x0098, 0x2001, 0xb653, 0x2004, 0xd0c4, 0x0150,
+	0xd0a4, 0x0140, 0xa006, 0x0046, 0x2020, 0x2009, 0x002d, 0x080c,
+	0xb1a4, 0x004e, 0x20a9, 0x00ff, 0x2011, 0x0000, 0x0026, 0xa28e,
+	0x007e, 0x0904, 0x2d7e, 0xa28e, 0x007f, 0x0904, 0x2d7e, 0xa28e,
+	0x0080, 0x05e0, 0xa288, 0xb735, 0x210c, 0x81ff, 0x05b8, 0x8fff,
+	0x1148, 0x2001, 0xb8be, 0x0006, 0x2003, 0x0001, 0x04d9, 0x000e,
+	0x2003, 0x0000, 0x00c6, 0x2160, 0x2001, 0x0001, 0x080c, 0x5385,
+	0x00ce, 0x2019, 0x0029, 0x080c, 0x6e67, 0x0076, 0x2039, 0x0000,
+	0x080c, 0x6d74, 0x00c6, 0x0026, 0x2160, 0x6204, 0xa294, 0x00ff,
+	0xa286, 0x0006, 0x1118, 0x6007, 0x0404, 0x0028, 0x2001, 0x0004,
+	0x8007, 0xa215, 0x6206, 0x002e, 0x00ce, 0x0016, 0x2c08, 0x080c,
+	0xaf3e, 0x001e, 0x007e, 0x2160, 0x080c, 0x521c, 0x002e, 0x8210,
+	0x1f04, 0x2d36, 0x015e, 0x001e, 0x002e, 0x003e, 0x00ce, 0x00ee,
+	0x00fe, 0x0005, 0x0046, 0x0026, 0x0016, 0x2001, 0xb653, 0x2004,
+	0xd0c4, 0x0148, 0xd0a4, 0x0138, 0xa006, 0x2220, 0x8427, 0x2009,
+	0x0029, 0x080c, 0xb1a4, 0x001e, 0x002e, 0x004e, 0x0005, 0x0016,
+	0x0026, 0x0036, 0x00c6, 0x7288, 0x82ff, 0x01f8, 0x2011, 0xb653,
+	0x2214, 0xd2ac, 0x11d0, 0x2100, 0x080c, 0x2866, 0x81ff, 0x01b8,
+	0x2019, 0x0001, 0x8314, 0xa2e0, 0xbdc0, 0x2c04, 0xd384, 0x0120,
+	0xa084, 0xff00, 0x8007, 0x0010, 0xa084, 0x00ff, 0xa116, 0x0138,
+	0xa096, 0x00ff, 0x0110, 0x8318, 0x0c68, 0xa085, 0x0001, 0x00ce,
+	0x003e, 0x002e, 0x001e, 0x0005, 0x0016, 0x00c6, 0x0126, 0x2091,
+	0x8000, 0x0016, 0x0026, 0x0036, 0x2110, 0x0026, 0x2019, 0x0029,
+	0x080c, 0x8320, 0x002e, 0x080c, 0xb449, 0x003e, 0x002e, 0x001e,
+	0xa180, 0xb735, 0x2004, 0xa065, 0x0158, 0x0016, 0x00c6, 0x2061,
+	0xb9f5, 0x001e, 0x611a, 0x080c, 0x2cd1, 0x001e, 0x080c, 0x4fde,
+	0x012e, 0x00ce, 0x001e, 0x0005, 0x2001, 0xb635, 0x2004, 0xd0cc,
+	0x0005, 0x7eef, 0x7de8, 0x7ce4, 0x80e2, 0x7be1, 0x80e0, 0x80dc,
+	0x80da, 0x7ad9, 0x80d6, 0x80d5, 0x80d4, 0x80d3, 0x80d2, 0x80d1,
+	0x79ce, 0x78cd, 0x80cc, 0x80cb, 0x80ca, 0x80c9, 0x80c7, 0x80c6,
+	0x77c5, 0x76c3, 0x80bc, 0x80ba, 0x75b9, 0x80b6, 0x74b5, 0x73b4,
+	0x72b3, 0x80b2, 0x80b1, 0x80ae, 0x71ad, 0x80ac, 0x70ab, 0x6faa,
+	0x6ea9, 0x80a7, 0x6da6, 0x6ca5, 0x6ba3, 0x6a9f, 0x699e, 0x689d,
+	0x809b, 0x8098, 0x6797, 0x6690, 0x658f, 0x6488, 0x6384, 0x6282,
+	0x8081, 0x8080, 0x617c, 0x607a, 0x8079, 0x5f76, 0x8075, 0x8074,
+	0x8073, 0x8072, 0x8071, 0x806e, 0x5e6d, 0x806c, 0x5d6b, 0x5c6a,
+	0x5b69, 0x8067, 0x5a66, 0x5965, 0x5863, 0x575c, 0x565a, 0x5559,
+	0x8056, 0x8055, 0x5454, 0x5353, 0x5252, 0x5151, 0x504e, 0x4f4d,
+	0x804c, 0x804b, 0x4e4a, 0x4d49, 0x8047, 0x4c46, 0x8045, 0x8043,
+	0x803c, 0x803a, 0x8039, 0x8036, 0x4b35, 0x8034, 0x4a33, 0x4932,
+	0x4831, 0x802e, 0x472d, 0x462c, 0x452b, 0x442a, 0x4329, 0x4227,
+	0x8026, 0x8025, 0x4123, 0x401f, 0x3f1e, 0x3e1d, 0x3d1b, 0x3c18,
+	0x8017, 0x8010, 0x3b0f, 0x3a08, 0x8004, 0x3902, 0x8001, 0x8000,
+	0x8000, 0x3800, 0x3700, 0x3600, 0x8000, 0x3500, 0x8000, 0x8000,
+	0x8000, 0x3400, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
+	0x3300, 0x3200, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
+	0x3100, 0x3000, 0x8000, 0x8000, 0x2f00, 0x8000, 0x2e00, 0x2d00,
+	0x2c00, 0x8000, 0x8000, 0x8000, 0x2b00, 0x8000, 0x2a00, 0x2900,
+	0x2800, 0x8000, 0x2700, 0x2600, 0x2500, 0x2400, 0x2300, 0x2200,
+	0x8000, 0x8000, 0x2100, 0x2000, 0x1f00, 0x1e00, 0x1d00, 0x1c00,
+	0x8000, 0x8000, 0x1b00, 0x1a00, 0x8000, 0x1900, 0x8000, 0x8000,
+	0x8000, 0x8000, 0x8000, 0x8000, 0x1800, 0x8000, 0x1700, 0x1600,
+	0x1500, 0x8000, 0x1400, 0x1300, 0x1200, 0x1100, 0x1000, 0x0f00,
+	0x8000, 0x8000, 0x0e00, 0x0d00, 0x0c00, 0x0b00, 0x0a00, 0x0900,
+	0x8000, 0x8000, 0x0800, 0x0700, 0x8000, 0x0600, 0x8000, 0x8000,
+	0x8000, 0x0500, 0x0400, 0x0300, 0x8000, 0x0200, 0x8000, 0x8000,
+	0x8000, 0x0100, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
+	0x0000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
 	0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
-	0x8000, 0x8000, 0x8000, 0x8000, 0x2071, 0xb582, 0x7003, 0x0002,
-	0xa006, 0x7012, 0x7016, 0x703a, 0x703e, 0x7033, 0xb592, 0x7037,
-	0xb592, 0x7007, 0x0001, 0x2061, 0xb5d2, 0x6003, 0x0002, 0x0005,
-	0x1004, 0x2eea, 0x0e04, 0x2eea, 0x2071, 0xb582, 0x2b78, 0x7818,
-	0xd084, 0x1140, 0x2a60, 0x7820, 0xa08e, 0x0069, 0x1904, 0x2fcf,
-	0x0804, 0x2f68, 0x0005, 0x2071, 0xb582, 0x7004, 0x0002, 0x2ef3,
-	0x2ef4, 0x2efd, 0x2f0e, 0x0005, 0x1004, 0x2efc, 0x0e04, 0x2efc,
-	0x2b78, 0x7818, 0xd084, 0x01e8, 0x0005, 0x2b78, 0x2061, 0xb5d2,
-	0x6008, 0xa08e, 0x0100, 0x0128, 0xa086, 0x0200, 0x0904, 0x2fc9,
-	0x0005, 0x7014, 0x2068, 0x2a60, 0x7018, 0x0807, 0x7010, 0x2068,
-	0x6834, 0xa086, 0x0103, 0x0108, 0x0005, 0x2a60, 0x2b78, 0x7018,
-	0x0807, 0x2a60, 0x7820, 0xa08a, 0x0040, 0x1210, 0x61c4, 0x0042,
-	0x2100, 0xa08a, 0x003f, 0x1a04, 0x2fc6, 0x61c4, 0x0804, 0x2f68,
-	0x2faa, 0x2fd5, 0x2fdd, 0x2fe1, 0x2fe9, 0x2fef, 0x2ff3, 0x2fff,
-	0x3002, 0x300c, 0x300f, 0x2fc6, 0x2fc6, 0x2fc6, 0x3012, 0x2fc6,
-	0x3021, 0x3038, 0x304f, 0x30c9, 0x30ce, 0x30f7, 0x3148, 0x3159,
-	0x3178, 0x31b0, 0x31ba, 0x31c7, 0x31da, 0x31fb, 0x3204, 0x323a,
-	0x3240, 0x2fc6, 0x3269, 0x2fc6, 0x2fc6, 0x2fc6, 0x2fc6, 0x2fc6,
-	0x3270, 0x327a, 0x2fc6, 0x2fc6, 0x2fc6, 0x2fc6, 0x2fc6, 0x2fc6,
-	0x2fc6, 0x2fc6, 0x3282, 0x2fc6, 0x2fc6, 0x2fc6, 0x2fc6, 0x2fc6,
-	0x3294, 0x329e, 0x2fc6, 0x2fc6, 0x2fc6, 0x2fc6, 0x2fc6, 0x2fc6,
-	0x0002, 0x32c8, 0x331c, 0x3377, 0x3391, 0x2fc6, 0x33c2, 0x37f5,
-	0x4233, 0x2fc6, 0x2fc6, 0x2fc6, 0x2fc6, 0x2fc6, 0x2fc6, 0x2fc6,
-	0x2fc6, 0x300c, 0x300f, 0x37f7, 0x2fc6, 0x3804, 0x42cc, 0x4327,
-	0x438b, 0x2fc6, 0x43ee, 0x4418, 0x4437, 0x4469, 0x2fc6, 0x2fc6,
-	0x2fc6, 0x3808, 0x39ad, 0x39c7, 0x39e5, 0x3a46, 0x3aa6, 0x3ab1,
-	0x3ae9, 0x3af8, 0x3b07, 0x3b0a, 0x3b2d, 0x3b79, 0x3bef, 0x3bfc,
-	0x3cfd, 0x3e23, 0x3e4c, 0x3f4a, 0x3f6c, 0x3f78, 0x3fb1, 0x4075,
-	0x2fc6, 0x2fc6, 0x2fc6, 0x2fc6, 0x40dd, 0x40f8, 0x416a, 0x421c,
-	0x713c, 0x0000, 0x2021, 0x4000, 0x080c, 0x3ea9, 0x0126, 0x2091,
-	0x8000, 0x0e04, 0x2fb6, 0x7818, 0xd084, 0x0110, 0x012e, 0x0cb0,
-	0x7c22, 0x7926, 0x7a2a, 0x7b2e, 0x781b, 0x0001, 0x2091, 0x4080,
-	0x7007, 0x0001, 0x2091, 0x5000, 0x012e, 0x0005, 0x2021, 0x4001,
-	0x0c18, 0x2021, 0x4002, 0x0c00, 0x2021, 0x4003, 0x08e8, 0x2021,
-	0x4005, 0x08d0, 0x2021, 0x4006, 0x08b8, 0xa02e, 0x2520, 0x7b28,
-	0x7a2c, 0x7824, 0x7930, 0x0804, 0x3eb6, 0x7823, 0x0004, 0x7824,
-	0x0807, 0xa02e, 0x2520, 0x7b28, 0x7a2c, 0x7824, 0x7930, 0x0804,
-	0x3eb9, 0x7924, 0x7828, 0x2114, 0x200a, 0x0804, 0x2faa, 0x7924,
-	0x2114, 0x0804, 0x2faa, 0x2099, 0x0009, 0x20a1, 0x0009, 0x20a9,
-	0x0007, 0x53a3, 0x7924, 0x7a28, 0x7b2c, 0x0804, 0x2faa, 0x7824,
-	0x2060, 0x0090, 0x2009, 0x0002, 0x2011, 0x0002, 0x2019, 0x0006,
-	0x783b, 0x0017, 0x0804, 0x2faa, 0x7d38, 0x7c3c, 0x0840, 0x7d38,
-	0x7c3c, 0x0888, 0x2061, 0x1000, 0xe10c, 0xa006, 0x2c15, 0xa200,
-	0x8c60, 0x8109, 0x1dd8, 0x2010, 0xa005, 0x0904, 0x2faa, 0x0804,
-	0x2fcc, 0x2069, 0xb552, 0x7824, 0x7930, 0xa11a, 0x1a04, 0x2fd2,
-	0x8019, 0x0904, 0x2fd2, 0x684a, 0x6942, 0x782c, 0x6852, 0x7828,
-	0x6856, 0xa006, 0x685a, 0x685e, 0x080c, 0x5da5, 0x0804, 0x2faa,
-	0x2069, 0xb552, 0x7824, 0x7934, 0xa11a, 0x1a04, 0x2fd2, 0x8019,
-	0x0904, 0x2fd2, 0x684e, 0x6946, 0x782c, 0x6862, 0x7828, 0x6866,
-	0xa006, 0x686a, 0x686e, 0x080c, 0x53d5, 0x0804, 0x2faa, 0xa02e,
-	0x2520, 0x81ff, 0x1904, 0x2fcf, 0x7924, 0x7b28, 0x7a2c, 0x20a9,
-	0x0005, 0x20a1, 0xb589, 0x41a1, 0x080c, 0x3e75, 0x0904, 0x2fcf,
-	0x2009, 0x0020, 0x080c, 0x3eb6, 0x701b, 0x3067, 0x0005, 0x6834,
-	0x2008, 0xa084, 0x00ff, 0xa096, 0x0011, 0x0138, 0xa096, 0x0019,
-	0x0120, 0xa096, 0x0015, 0x1904, 0x2fcf, 0x810f, 0xa18c, 0x00ff,
-	0x0904, 0x2fcf, 0x710e, 0x700c, 0x8001, 0x0528, 0x700e, 0x080c,
-	0x3e75, 0x0904, 0x2fcf, 0x2009, 0x0020, 0x2061, 0xb5d2, 0x6224,
-	0x6328, 0x642c, 0x6530, 0xa290, 0x0040, 0xa399, 0x0000, 0xa4a1,
-	0x0000, 0xa5a9, 0x0000, 0x080c, 0x3eb6, 0x701b, 0x3098, 0x0005,
-	0x6834, 0xa084, 0x00ff, 0xa096, 0x0002, 0x0120, 0xa096, 0x000a,
-	0x1904, 0x2fcf, 0x08c0, 0x7010, 0x2068, 0x6838, 0xc0fd, 0x683a,
-	0x080c, 0x4e49, 0x1128, 0x7007, 0x0003, 0x701b, 0x30b2, 0x0005,
-	0x080c, 0x54db, 0x0126, 0x2091, 0x8000, 0x20a9, 0x0005, 0x2099,
-	0xb589, 0x530a, 0x2100, 0xa210, 0xa399, 0x0000, 0xa4a1, 0x0000,
-	0xa5a9, 0x0000, 0xad80, 0x000d, 0x2009, 0x0020, 0x012e, 0x0804,
-	0x3eb9, 0x61ac, 0x7824, 0x60ae, 0x0804, 0x2faa, 0x2091, 0x8000,
-	0x7823, 0x4000, 0x7827, 0x4953, 0x782b, 0x5020, 0x782f, 0x2020,
-	0x2009, 0x017f, 0x2104, 0x7832, 0x3f00, 0x7836, 0x2061, 0x0100,
-	0x6200, 0x2061, 0x0200, 0x603c, 0x8007, 0xa205, 0x783a, 0x2009,
-	0x04fd, 0x2104, 0x783e, 0x781b, 0x0001, 0x2091, 0x5000, 0x2091,
-	0x4080, 0x2071, 0x0010, 0x20c1, 0x00f0, 0x0804, 0x0427, 0x81ff,
-	0x1904, 0x2fcf, 0x7924, 0x810f, 0xa18c, 0x00ff, 0x080c, 0x4fa9,
-	0x1904, 0x2fd2, 0x7e38, 0xa684, 0x3fff, 0xa082, 0x4000, 0x0210,
-	0x0804, 0x2fd2, 0x7c28, 0x7d2c, 0x080c, 0x5171, 0xd28c, 0x1118,
-	0x080c, 0x511a, 0x0010, 0x080c, 0x514a, 0x1518, 0x2061, 0xbd00,
-	0x0126, 0x2091, 0x8000, 0x6000, 0xa086, 0x0000, 0x0148, 0x6010,
-	0xa06d, 0x0130, 0x683c, 0xa406, 0x1118, 0x6840, 0xa506, 0x0150,
-	0x012e, 0xace0, 0x0018, 0x2001, 0xb517, 0x2004, 0xac02, 0x1a04,
-	0x2fcf, 0x0c30, 0x080c, 0x992a, 0x012e, 0x0904, 0x2fcf, 0x0804,
-	0x2faa, 0xa00e, 0x2001, 0x0005, 0x080c, 0x54db, 0x0126, 0x2091,
-	0x8000, 0x080c, 0x9ed2, 0x080c, 0x5408, 0x012e, 0x0804, 0x2faa,
-	0x81ff, 0x1904, 0x2fcf, 0x080c, 0x3e8a, 0x0904, 0x2fd2, 0x080c,
-	0x506f, 0x0904, 0x2fcf, 0x080c, 0x517d, 0x0904, 0x2fcf, 0x0804,
-	0x2faa, 0x81ff, 0x1904, 0x2fcf, 0x080c, 0x3e9a, 0x0904, 0x2fd2,
-	0x080c, 0x51e9, 0x0904, 0x2fcf, 0x2019, 0x0005, 0x7924, 0x080c,
-	0x5198, 0x0904, 0x2fcf, 0x7828, 0xa08a, 0x1000, 0x1a04, 0x2fd2,
-	0x8003, 0x800b, 0x810b, 0xa108, 0x080c, 0x69a8, 0x0804, 0x2faa,
-	0x0126, 0x2091, 0x8000, 0x81ff, 0x0118, 0x2009, 0x0001, 0x0450,
-	0x2029, 0x00ff, 0x6450, 0x2400, 0xa506, 0x01f8, 0x2508, 0x080c,
-	0x4fa9, 0x11d8, 0x080c, 0x51e9, 0x1128, 0x2009, 0x0002, 0x62b4,
-	0x2518, 0x00c0, 0x2019, 0x0004, 0xa00e, 0x080c, 0x5198, 0x1118,
-	0x2009, 0x0006, 0x0078, 0x7824, 0xa08a, 0x1000, 0x1270, 0x8003,
-	0x800b, 0x810b, 0xa108, 0x080c, 0x69a8, 0x8529, 0x1ae0, 0x012e,
-	0x0804, 0x2faa, 0x012e, 0x0804, 0x2fcf, 0x012e, 0x0804, 0x2fd2,
-	0x080c, 0x3e8a, 0x0904, 0x2fd2, 0x080c, 0x50d5, 0x080c, 0x5171,
-	0x0804, 0x2faa, 0x81ff, 0x1904, 0x2fcf, 0x080c, 0x3e8a, 0x0904,
-	0x2fd2, 0x080c, 0x50c6, 0x080c, 0x5171, 0x0804, 0x2faa, 0x81ff,
-	0x1904, 0x2fcf, 0x080c, 0x3e8a, 0x0904, 0x2fd2, 0x080c, 0x514c,
-	0x0904, 0x2fcf, 0x080c, 0x4e8d, 0x080c, 0x5113, 0x080c, 0x5171,
-	0x0804, 0x2faa, 0x080c, 0x3e8a, 0x0904, 0x2fd2, 0x080c, 0x506f,
-	0x0904, 0x2fcf, 0x62a0, 0x2019, 0x0005, 0x00c6, 0x080c, 0x51aa,
-	0x2061, 0x0000, 0x080c, 0x6df5, 0x0076, 0x2039, 0x0000, 0x080c,
-	0x6d02, 0x2009, 0x0000, 0x080c, 0xae82, 0x007e, 0x00ce, 0x080c,
-	0x5171, 0x0804, 0x2faa, 0x080c, 0x3e8a, 0x0904, 0x2fd2, 0x080c,
-	0x5171, 0x2208, 0x0804, 0x2faa, 0x0156, 0x00d6, 0x00e6, 0x2069,
-	0xb614, 0x6810, 0x6914, 0xa10a, 0x1210, 0x2009, 0x0000, 0x6816,
-	0x2011, 0x0000, 0x2019, 0x0000, 0x20a9, 0x007e, 0x2069, 0xb635,
-	0x2d04, 0xa075, 0x0130, 0x704c, 0x0071, 0xa210, 0x7080, 0x0059,
-	0xa318, 0x8d68, 0x1f04, 0x3218, 0x2300, 0xa218, 0x00ee, 0x00de,
-	0x015e, 0x0804, 0x2faa, 0x00f6, 0x0016, 0xa07d, 0x0140, 0x2001,
-	0x0000, 0x8000, 0x2f0c, 0x81ff, 0x0110, 0x2178, 0x0cd0, 0x001e,
-	0x00fe, 0x0005, 0x2069, 0xb614, 0x6910, 0x62b0, 0x0804, 0x2faa,
-	0x81ff, 0x1904, 0x2fcf, 0x6150, 0xa190, 0x2dc4, 0x2215, 0xa294,
-	0x00ff, 0x6370, 0x83ff, 0x0108, 0x6274, 0x67d4, 0xd79c, 0x0118,
-	0x2031, 0x0001, 0x0090, 0xd7ac, 0x0118, 0x2031, 0x0003, 0x0068,
-	0xd7a4, 0x0118, 0x2031, 0x0002, 0x0040, 0x080c, 0x5acf, 0x1118,
-	0x2031, 0x0004, 0x0010, 0x2031, 0x0000, 0x7e3a, 0x7f3e, 0x0804,
-	0x2faa, 0x6140, 0x6244, 0x2019, 0xb7b6, 0x231c, 0x0804, 0x2faa,
-	0x0126, 0x2091, 0x8000, 0x6134, 0xa006, 0x2010, 0x6338, 0x012e,
-	0x0804, 0x2faa, 0x080c, 0x3e9a, 0x0904, 0x2fd2, 0x6244, 0x6338,
-	0x0804, 0x2faa, 0x6140, 0x6244, 0x7824, 0x6042, 0x7b28, 0x6346,
-	0x2069, 0xb552, 0x831f, 0xa305, 0x6816, 0x782c, 0x2069, 0xb7b6,
-	0x2d1c, 0x206a, 0x0804, 0x2faa, 0x0126, 0x2091, 0x8000, 0x7824,
-	0x6036, 0x782c, 0x603a, 0x012e, 0x0804, 0x2faa, 0x7838, 0xa005,
-	0x01a8, 0x7828, 0xa025, 0x0904, 0x2fd2, 0x782c, 0xa02d, 0x0904,
-	0x2fd2, 0xa00e, 0x080c, 0x4fa9, 0x1120, 0x6244, 0x6338, 0x6446,
-	0x653a, 0xa186, 0x00ff, 0x0190, 0x8108, 0x0ca0, 0x080c, 0x3e9a,
-	0x0904, 0x2fd2, 0x7828, 0xa00d, 0x0904, 0x2fd2, 0x782c, 0xa005,
-	0x0904, 0x2fd2, 0x6244, 0x6146, 0x6338, 0x603a, 0x0804, 0x2faa,
-	0x2001, 0xb500, 0x2004, 0xa086, 0x0003, 0x1904, 0x2fcf, 0x00c6,
-	0x2061, 0x0100, 0x7924, 0x810f, 0xa18c, 0x00ff, 0xa196, 0x00ff,
-	0x1130, 0x2001, 0xb515, 0x2004, 0xa085, 0xff00, 0x0078, 0xa182,
-	0x007f, 0x16a0, 0xa188, 0x2dc4, 0x210d, 0xa18c, 0x00ff, 0x2001,
-	0xb515, 0x2004, 0xa116, 0x0550, 0x810f, 0xa105, 0x0126, 0x2091,
-	0x8000, 0x0006, 0x080c, 0x85c7, 0x000e, 0x01e0, 0x601a, 0x600b,
-	0xbc09, 0x601f, 0x0001, 0x080c, 0x3e75, 0x01d8, 0x6837, 0x0000,
-	0x7007, 0x0003, 0x6833, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x701b,
-	0x3370, 0x2d00, 0x6012, 0x2009, 0x0032, 0x080c, 0x864c, 0x012e,
-	0x00ce, 0x0005, 0x012e, 0x00ce, 0x0804, 0x2fcf, 0x00ce, 0x0804,
-	0x2fd2, 0x080c, 0x861d, 0x0cb0, 0x2001, 0xb500, 0x2004, 0xa086,
-	0x0003, 0x1904, 0x2fcf, 0x00c6, 0x2061, 0x0100, 0x7924, 0x810f,
-	0xa18c, 0x00ff, 0xa196, 0x00ff, 0x1130, 0x2001, 0xb515, 0x2004,
-	0xa085, 0xff00, 0x0078, 0xa182, 0x007f, 0x16a0, 0xa188, 0x2dc4,
-	0x210d, 0xa18c, 0x00ff, 0x2001, 0xb515, 0x2004, 0xa116, 0x0550,
-	0x810f, 0xa105, 0x0126, 0x2091, 0x8000, 0x0006, 0x080c, 0x85c7,
-	0x000e, 0x01e0, 0x601a, 0x600b, 0xbc05, 0x601f, 0x0001, 0x080c,
-	0x3e75, 0x01d8, 0x6837, 0x0000, 0x7007, 0x0003, 0x6833, 0x0000,
-	0x6838, 0xc0fd, 0x683a, 0x701b, 0x3370, 0x2d00, 0x6012, 0x2009,
-	0x0032, 0x080c, 0x864c, 0x012e, 0x00ce, 0x0005, 0x012e, 0x00ce,
-	0x0804, 0x2fcf, 0x00ce, 0x0804, 0x2fd2, 0x080c, 0x861d, 0x0cb0,
-	0x6830, 0xa086, 0x0100, 0x0904, 0x2fcf, 0x0804, 0x2faa, 0x2061,
-	0xb874, 0x0126, 0x2091, 0x8000, 0x6000, 0xd084, 0x0178, 0x6104,
-	0x6208, 0x2a60, 0x6068, 0x783a, 0x60b4, 0x783e, 0x60b0, 0x2019,
-	0x0072, 0x201a, 0x6348, 0x012e, 0x0804, 0x2faa, 0xa00e, 0x2110,
-	0x0c80, 0x81ff, 0x1904, 0x2fcf, 0x080c, 0x5acf, 0x0904, 0x2fcf,
-	0x0126, 0x2091, 0x8000, 0x6248, 0x6068, 0xa202, 0x0248, 0xa085,
-	0x0001, 0x080c, 0x2867, 0x080c, 0x462c, 0x012e, 0x0804, 0x2faa,
-	0x012e, 0x0804, 0x2fd2, 0x0006, 0x0016, 0x00c6, 0x00e6, 0x2001,
-	0xb7bf, 0x2070, 0x2061, 0xb552, 0x6008, 0x2072, 0x2009, 0x0000,
-	0x2011, 0x1000, 0x080c, 0x6b40, 0x7206, 0x00ee, 0x00ce, 0x001e,
-	0x000e, 0x0005, 0x0126, 0x2091, 0x8000, 0x7824, 0xa084, 0x0007,
-	0x0002, 0x33d4, 0x33dd, 0x33e4, 0x33d1, 0x33d1, 0x33d1, 0x33d1,
-	0x33d1, 0x012e, 0x0804, 0x2fd2, 0x2009, 0x0114, 0x2104, 0xa085,
-	0x0800, 0x200a, 0x080c, 0x354f, 0x0070, 0x2009, 0x010b, 0x200b,
-	0x0010, 0x080c, 0x354f, 0x0038, 0x81ff, 0x0128, 0x012e, 0x2021,
-	0x400b, 0x0804, 0x2fac, 0x0086, 0x0096, 0x00a6, 0x00b6, 0x00c6,
-	0x00d6, 0x00e6, 0x00f6, 0x080c, 0x33ab, 0x2009, 0x0101, 0x210c,
-	0x0016, 0x2001, 0x0138, 0x200c, 0x2003, 0x0001, 0x0016, 0x2001,
-	0x007a, 0x2034, 0x2001, 0x007b, 0x202c, 0xa006, 0x2048, 0x2050,
-	0x2058, 0x080c, 0x379a, 0x080c, 0x36fe, 0xa03e, 0x2720, 0x00f6,
-	0x00e6, 0x00c6, 0x2d60, 0x2071, 0xb84a, 0x2079, 0x0020, 0x00d6,
-	0x2069, 0x0000, 0x6824, 0xd0b4, 0x0140, 0x2001, 0x007d, 0x2004,
-	0x783e, 0x2001, 0x007c, 0x2004, 0x783a, 0x00de, 0x2011, 0x0001,
-	0x080c, 0x36aa, 0x080c, 0x36aa, 0x00ce, 0x00ee, 0x00fe, 0x080c,
-	0x35f5, 0x080c, 0x36d2, 0x080c, 0x364f, 0x080c, 0x35b4, 0x080c,
-	0x35e5, 0x00f6, 0x2079, 0x0100, 0x7824, 0xd094, 0x0530, 0x7814,
-	0xa084, 0x0184, 0xa085, 0x0010, 0x7816, 0x2079, 0x0140, 0x080c,
-	0x352d, 0x1110, 0x00fe, 0x0430, 0x7804, 0xd0dc, 0x0dc0, 0x2079,
-	0x0100, 0x7827, 0x0086, 0x7814, 0xa084, 0x0184, 0xa085, 0x0032,
-	0x7816, 0x080c, 0x352d, 0x1110, 0x00fe, 0x00a0, 0x7824, 0xd0bc,
-	0x0dc0, 0x7827, 0x0080, 0xa026, 0x7c16, 0x7824, 0xd0ac, 0x0130,
-	0x8b58, 0x080c, 0x3537, 0x00fe, 0x0804, 0x34f7, 0x00fe, 0x080c,
-	0x352d, 0x1150, 0x8948, 0x2001, 0x007a, 0x2602, 0x2001, 0x007b,
-	0x2502, 0x080c, 0x3537, 0x0088, 0x87ff, 0x0140, 0x2001, 0x0201,
-	0x2004, 0xa005, 0x1904, 0x3431, 0x8739, 0x0038, 0x2001, 0xb823,
-	0x2004, 0xa086, 0x0000, 0x1904, 0x3431, 0x2001, 0x0033, 0x2003,
-	0x00f6, 0x8631, 0x1208, 0x8529, 0x2500, 0xa605, 0x0904, 0x34f7,
-	0x7824, 0xd0bc, 0x0128, 0x2900, 0xaa05, 0xab05, 0x1904, 0x34f7,
-	0x6033, 0x000d, 0x2001, 0x0030, 0x2003, 0x0004, 0x7824, 0xd0ac,
-	0x1148, 0x2001, 0xb823, 0x2003, 0x0003, 0x2001, 0x0030, 0x2003,
-	0x0009, 0x0040, 0x6027, 0x0001, 0x2001, 0x0075, 0x2004, 0xa005,
-	0x0108, 0x6026, 0x2c00, 0x601a, 0x20e1, 0x9040, 0x2d00, 0x681a,
-	0x6833, 0x000d, 0x7824, 0xd0a4, 0x1180, 0x6827, 0x0000, 0x00c6,
-	0x20a9, 0x0004, 0x2061, 0x0020, 0x6003, 0x0008, 0x2001, 0x0203,
-	0x2004, 0x1f04, 0x34cc, 0x00ce, 0x0040, 0x6827, 0x0001, 0x2001,
-	0x0074, 0x2004, 0xa005, 0x0108, 0x6826, 0x00f6, 0x00c6, 0x2079,
-	0x0100, 0x2061, 0x0020, 0x7827, 0x0002, 0x2001, 0x0072, 0x2004,
-	0xa084, 0xfff8, 0x601a, 0x0006, 0x2001, 0x0073, 0x2004, 0x601e,
-	0x78c6, 0x000e, 0x78ca, 0x00ce, 0x00fe, 0x0804, 0x340f, 0x2061,
-	0x0100, 0x6027, 0x0002, 0x001e, 0x61e2, 0x001e, 0x6106, 0x7824,
-	0xa084, 0x0003, 0xa086, 0x0002, 0x0188, 0x20e1, 0x9028, 0x6050,
-	0xa084, 0xf7ef, 0x6052, 0x602f, 0x0000, 0x602c, 0xc0ac, 0x602e,
-	0x604b, 0xf7f7, 0x6043, 0x0090, 0x6043, 0x0010, 0x2908, 0x2a10,
-	0x2b18, 0x2b00, 0xaa05, 0xa905, 0x00fe, 0x00ee, 0x00de, 0x00ce,
-	0x00be, 0x00ae, 0x009e, 0x008e, 0x1118, 0x012e, 0x0804, 0x2faa,
-	0x012e, 0x2021, 0x400c, 0x0804, 0x2fac, 0xa085, 0x0001, 0x1d04,
-	0x3536, 0x2091, 0x6000, 0x8420, 0xa486, 0x0064, 0x0005, 0x2001,
-	0x0105, 0x2003, 0x0010, 0x2001, 0x0030, 0x2003, 0x0004, 0x2001,
-	0x0020, 0x2003, 0x0004, 0x2001, 0xb823, 0x2003, 0x0000, 0x2001,
-	0xb84a, 0x2003, 0x0000, 0x20e1, 0xf000, 0xa026, 0x0005, 0x00f6,
-	0x2079, 0x0100, 0x2001, 0xb515, 0x200c, 0x7932, 0x7936, 0x080c,
-	0x2847, 0x7850, 0xa084, 0x0980, 0xa085, 0x0030, 0x7852, 0x2019,
-	0x01f4, 0x8319, 0x1df0, 0xa084, 0x0980, 0x7852, 0x782c, 0xc0ad,
-	0x782e, 0x20a9, 0x0046, 0x1d04, 0x356b, 0x2091, 0x6000, 0x1f04,
-	0x356b, 0x7850, 0xa085, 0x0400, 0x7852, 0x2001, 0x0009, 0x2004,
-	0xa084, 0x0003, 0xa086, 0x0001, 0x1118, 0x782c, 0xc0ac, 0x782e,
-	0x784b, 0xf7f7, 0x7843, 0x0090, 0x7843, 0x0010, 0x20a9, 0x000e,
-	0xe000, 0x1f04, 0x3588, 0x7850, 0xa085, 0x1400, 0x7852, 0x2019,
-	0x61a8, 0x7854, 0xe000, 0xe000, 0xd08c, 0x1110, 0x8319, 0x1dc8,
-	0x7827, 0x0048, 0x7850, 0xa085, 0x0400, 0x7852, 0x7843, 0x0040,
-	0x2019, 0x01f4, 0xe000, 0xe000, 0x8319, 0x1de0, 0x2001, 0x0140,
-	0x2003, 0x0100, 0x7827, 0x0020, 0x7843, 0x0000, 0x2003, 0x0000,
-	0x7827, 0x0048, 0x00fe, 0x0005, 0x7824, 0xd0ac, 0x11c8, 0x00f6,
-	0x00e6, 0x2071, 0xb823, 0x2079, 0x0030, 0x2001, 0x0201, 0x2004,
-	0xa005, 0x0160, 0x7000, 0xa086, 0x0000, 0x1140, 0x0051, 0xd0bc,
-	0x0108, 0x8738, 0x7003, 0x0003, 0x7803, 0x0019, 0x00ee, 0x00fe,
-	0x0005, 0x780c, 0xa08c, 0x0070, 0x0178, 0x2009, 0x007a, 0x260a,
-	0x2009, 0x007b, 0x250a, 0xd0b4, 0x0108, 0x8a50, 0xd0ac, 0x0108,
-	0x8948, 0xd0a4, 0x0108, 0x8b58, 0x0005, 0x00f6, 0x2079, 0x0200,
-	0x781c, 0xd084, 0x0140, 0x20e1, 0x0007, 0x20e1, 0x2000, 0x2001,
-	0x020a, 0x2004, 0x0ca8, 0x00fe, 0x0005, 0x00e6, 0x2071, 0x0100,
-	0x2001, 0xb7c0, 0x2004, 0x70e2, 0x2009, 0xb515, 0x210c, 0x716e,
-	0x7063, 0x0100, 0x7166, 0x719e, 0x706b, 0x0000, 0x7073, 0x0809,
-	0x7077, 0x0008, 0x7078, 0xa080, 0x0100, 0x707a, 0x7080, 0x8000,
-	0x7082, 0x7087, 0xaaaa, 0xa006, 0x708a, 0x708e, 0x707e, 0x70d6,
-	0x70ab, 0x0036, 0x70af, 0x95d5, 0x7027, 0x0080, 0x7014, 0xa084,
-	0x0184, 0xa085, 0x0032, 0x7016, 0x080c, 0x36d2, 0x080c, 0x352d,
-	0x1110, 0x8421, 0x0028, 0x7024, 0xd0bc, 0x0db0, 0x7027, 0x0080,
-	0x00f6, 0x00e6, 0x2071, 0xb823, 0x2079, 0x0030, 0x00d6, 0x2069,
-	0x0000, 0x6824, 0xd0b4, 0x0120, 0x683c, 0x783e, 0x6838, 0x783a,
-	0x00de, 0x2011, 0x0011, 0x080c, 0x36aa, 0x2011, 0x0001, 0x080c,
-	0x36aa, 0x00ee, 0x00fe, 0x7017, 0x0000, 0x00ee, 0x0005, 0x00f6,
-	0x00e6, 0x2071, 0xb823, 0x2079, 0x0030, 0x7904, 0xd1fc, 0x0904,
-	0x36a7, 0x7803, 0x0002, 0xa026, 0xd19c, 0x1904, 0x36a3, 0x7000,
-	0x0002, 0x36a7, 0x3665, 0x3689, 0x36a3, 0xd1bc, 0x1150, 0xd1dc,
-	0x1150, 0x8001, 0x7002, 0x2011, 0x0001, 0x04e1, 0x05c0, 0x04d1,
-	0x04b0, 0x780f, 0x0000, 0x7820, 0x7924, 0x7803, 0x0004, 0x7822,
-	0x7926, 0x2001, 0x0201, 0x200c, 0x81ff, 0x0de8, 0x080c, 0x35d1,
-	0x2009, 0x0001, 0x7808, 0xd0ec, 0x0110, 0x2009, 0x0011, 0x7902,
-	0x00f0, 0x8001, 0x7002, 0xa184, 0x0880, 0x1138, 0x7804, 0xd0fc,
-	0x1940, 0x2011, 0x0001, 0x00b1, 0x0090, 0x6030, 0xa092, 0x0004,
-	0xa086, 0x0009, 0x1120, 0x6000, 0x601a, 0x2011, 0x0025, 0x6232,
-	0xd1dc, 0x1988, 0x0870, 0x7803, 0x0004, 0x7003, 0x0000, 0x00ee,
-	0x00fe, 0x0005, 0x6024, 0xa005, 0x0520, 0x8001, 0x6026, 0x6018,
-	0x6130, 0xa140, 0x2804, 0x7832, 0x8840, 0x2804, 0x7836, 0x8840,
-	0x2804, 0x7822, 0x8840, 0x2804, 0x7826, 0x8840, 0x7a02, 0x7000,
-	0x8000, 0x7002, 0x6018, 0xa802, 0xa08a, 0x0029, 0x1138, 0x6018,
-	0xa080, 0x0001, 0x2004, 0x601a, 0x2001, 0x000d, 0x6032, 0xa085,
-	0x0001, 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x2071, 0xb84a, 0x2079,
-	0x0020, 0x7904, 0xd1fc, 0x01f0, 0x7803, 0x0002, 0x2d60, 0xa026,
-	0x7000, 0x0002, 0x36fa, 0x36e5, 0x36f1, 0x8001, 0x7002, 0xd19c,
-	0x1188, 0x2011, 0x0001, 0x080c, 0x36aa, 0x0160, 0x080c, 0x36aa,
-	0x0048, 0x8001, 0x7002, 0x7804, 0xd0fc, 0x1d30, 0x2011, 0x0001,
-	0x080c, 0x36aa, 0x00ce, 0x00ee, 0x00fe, 0x0005, 0x00f6, 0x00e6,
-	0x00c6, 0x2061, 0x0200, 0x2001, 0xb7c0, 0x2004, 0x601a, 0x2061,
-	0x0100, 0x2001, 0xb7bf, 0x2004, 0x60ce, 0x6004, 0xc0ac, 0xa085,
-	0x0200, 0x6006, 0x2001, 0x0074, 0x2004, 0xa005, 0x01f8, 0x2038,
-	0x2001, 0x0076, 0x2024, 0x2001, 0x0077, 0x201c, 0x080c, 0x3e75,
-	0x6833, 0x000d, 0x6f26, 0x2d00, 0x681a, 0xa78a, 0x0007, 0x0220,
-	0x2138, 0x2009, 0x0007, 0x0010, 0x2708, 0xa03e, 0x6818, 0xa080,
-	0x000d, 0x04b1, 0x1d90, 0x2d00, 0x681a, 0x0088, 0x080c, 0x3e75,
-	0x6833, 0x000d, 0x2070, 0x6827, 0x0001, 0x2d00, 0x681a, 0x2001,
-	0x0076, 0x2004, 0x2072, 0x2001, 0x0077, 0x2004, 0x7006, 0x2061,
-	0x0020, 0x2079, 0x0100, 0x2001, 0xb7bf, 0x2004, 0x6012, 0x20e1,
-	0x9040, 0x2001, 0x0072, 0x2004, 0xa084, 0xfff8, 0x700a, 0x601a,
-	0x0006, 0x2001, 0x0073, 0x2004, 0x700e, 0x601e, 0x78c6, 0x000e,
-	0x78ca, 0xa006, 0x603a, 0x603e, 0x00ce, 0x00ee, 0x00fe, 0x0005,
-	0x00e6, 0x2071, 0x0010, 0x20a0, 0x2099, 0x0014, 0x7003, 0x0026,
-	0x7432, 0x7336, 0xa006, 0x703a, 0x703e, 0x810b, 0x810b, 0x21a8,
-	0x810b, 0x7122, 0x7003, 0x0041, 0x7004, 0xd0fc, 0x0de8, 0x7003,
-	0x0002, 0x7003, 0x0040, 0x53a5, 0x7430, 0x7334, 0x87ff, 0x0180,
-	0x00c6, 0x00d6, 0x2d60, 0x00c6, 0x080c, 0x3e75, 0x00ce, 0x6018,
-	0x2070, 0x2d00, 0x7006, 0x601a, 0x00de, 0x00ce, 0xa085, 0x0001,
-	0x00ee, 0x0005, 0x00e6, 0x2001, 0x0075, 0x2004, 0xa005, 0x0508,
-	0x2038, 0x2001, 0x0078, 0x2024, 0x2001, 0x0079, 0x201c, 0x080c,
-	0x3e75, 0x2d60, 0x6833, 0x000d, 0x6f26, 0x2d00, 0x681a, 0xa78a,
-	0x0007, 0x0220, 0x2138, 0x2009, 0x0007, 0x0010, 0x2708, 0xa03e,
-	0x6818, 0xa080, 0x000d, 0x080c, 0x3768, 0x1d88, 0x2d00, 0x681a,
-	0x00e0, 0x080c, 0x3e75, 0x2d60, 0x6033, 0x000d, 0x2070, 0x6027,
-	0x0001, 0x2c00, 0x601a, 0x2001, 0x0078, 0x2004, 0x2072, 0x2001,
-	0x0079, 0x2004, 0x7006, 0x2001, 0x0072, 0x2004, 0xa084, 0xfff8,
-	0x700a, 0x2001, 0x0073, 0x2004, 0x700e, 0x2001, 0x0030, 0x2003,
-	0x0004, 0x7824, 0xd0ac, 0x1178, 0x2001, 0x0101, 0x200c, 0xc1ed,
-	0x2102, 0x6027, 0x0000, 0x2001, 0xb823, 0x2003, 0x0003, 0x2001,
-	0x0030, 0x2003, 0x0009, 0x00ee, 0x0005, 0x0804, 0x2faa, 0x0126,
-	0x2091, 0x8000, 0x20a9, 0x0012, 0x2001, 0xb540, 0x20a0, 0xa006,
-	0x40a4, 0x012e, 0x0804, 0x2faa, 0x7d38, 0x7c3c, 0x0804, 0x3051,
-	0x080c, 0x3e75, 0x0904, 0x2fcf, 0x080c, 0x5acf, 0x0110, 0x080c,
-	0x4bf0, 0x2009, 0x001c, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x080c,
-	0x3eb6, 0x701b, 0x381c, 0x0005, 0xade8, 0x000d, 0x6800, 0xa005,
-	0x0904, 0x2fd2, 0x6804, 0xd0ac, 0x0118, 0xd0a4, 0x0904, 0x2fd2,
-	0xd094, 0x00c6, 0x2061, 0x0100, 0x6104, 0x0138, 0x6200, 0xa292,
-	0x0005, 0x0218, 0xa18c, 0xffdf, 0x0010, 0xa18d, 0x0020, 0x6106,
-	0x00ce, 0xd08c, 0x00c6, 0x2061, 0x0100, 0x6104, 0x0118, 0xa18d,
-	0x0010, 0x0010, 0xa18c, 0xffef, 0x6106, 0x00ce, 0x2009, 0x0100,
-	0x210c, 0xa18a, 0x0002, 0x0268, 0xd084, 0x0158, 0x6a28, 0xa28a,
-	0x007f, 0x1a04, 0x2fd2, 0xa288, 0x2dc4, 0x210d, 0xa18c, 0x00ff,
-	0x615a, 0xd0dc, 0x0130, 0x6828, 0xa08a, 0x007f, 0x1a04, 0x2fd2,
-	0x6052, 0x6808, 0xa08a, 0x0100, 0x0a04, 0x2fd2, 0xa08a, 0x0841,
-	0x1a04, 0x2fd2, 0xa084, 0x0007, 0x1904, 0x2fd2, 0x680c, 0xa005,
-	0x0904, 0x2fd2, 0x6810, 0xa005, 0x0904, 0x2fd2, 0x6848, 0x6940,
-	0xa10a, 0x1a04, 0x2fd2, 0x8001, 0x0904, 0x2fd2, 0x684c, 0x6944,
-	0xa10a, 0x1a04, 0x2fd2, 0x8001, 0x0904, 0x2fd2, 0x6804, 0xd0fc,
-	0x0560, 0x080c, 0x3e75, 0x0904, 0x2fcf, 0x2009, 0x0014, 0x7a2c,
-	0x7b28, 0x7c3c, 0x7d38, 0xa290, 0x0038, 0xa399, 0x0000, 0x080c,
-	0x3eb6, 0x701b, 0x389c, 0x0005, 0xade8, 0x000d, 0x20a9, 0x0014,
-	0x2d98, 0x2069, 0xb56e, 0x2da0, 0x53a3, 0x7010, 0xa0e8, 0x000d,
-	0x2001, 0xb572, 0x200c, 0xd1e4, 0x0140, 0x00c6, 0x2061, 0x0100,
-	0x6004, 0xa085, 0x0b00, 0x6006, 0x00ce, 0x2009, 0xb7b1, 0x200b,
-	0x0000, 0x2001, 0xb574, 0x2004, 0xd0ac, 0x0158, 0x7824, 0x200a,
-	0x2009, 0x017f, 0x200a, 0x3200, 0xa084, 0x003f, 0xa085, 0x3020,
-	0x2090, 0x20a9, 0x001c, 0x2d98, 0x2069, 0xb552, 0x2da0, 0x53a3,
-	0x6814, 0xa08c, 0x00ff, 0x6142, 0x8007, 0xa084, 0x00ff, 0x6046,
-	0x080c, 0x5da5, 0x080c, 0x536c, 0x080c, 0x53d5, 0x6000, 0xa086,
-	0x0000, 0x1904, 0x3997, 0x6808, 0x602a, 0x080c, 0x2470, 0x0006,
-	0x2001, 0x0100, 0x2004, 0xa082, 0x0005, 0x000e, 0x0268, 0x2009,
-	0x0170, 0x200b, 0x0080, 0xe000, 0xe000, 0x200b, 0x0000, 0x0036,
-	0x6b08, 0x080c, 0x28a2, 0x003e, 0x6818, 0x691c, 0x6a20, 0x6b24,
-	0x8007, 0x810f, 0x8217, 0x831f, 0x6016, 0x611a, 0x621e, 0x6322,
-	0x6c04, 0xd4f4, 0x0148, 0x6830, 0x6934, 0x6a38, 0x6b3c, 0x8007,
-	0x810f, 0x8217, 0x831f, 0x0010, 0xa084, 0xf0ff, 0x6006, 0x610a,
-	0x620e, 0x6312, 0x8007, 0x810f, 0x8217, 0x831f, 0x20a9, 0x0004,
-	0x20a1, 0xb7c6, 0x40a1, 0x080c, 0x6a68, 0x6904, 0xd1fc, 0x0520,
-	0x00c6, 0x2009, 0x0000, 0x20a9, 0x0001, 0x6b70, 0xd384, 0x01c8,
-	0x0020, 0x839d, 0x12b0, 0x3508, 0x8109, 0x080c, 0x635c, 0x6878,
-	0x6016, 0x6874, 0x2008, 0xa084, 0xff00, 0x8007, 0x600a, 0xa184,
-	0x00ff, 0x6006, 0x8108, 0x1118, 0x6003, 0x0003, 0x0010, 0x6003,
-	0x0001, 0x1f04, 0x3931, 0x00ce, 0x2069, 0xb552, 0x2001, 0xb79e,
-	0x6a80, 0xa294, 0x0030, 0xa28e, 0x0000, 0x0170, 0xa28e, 0x0010,
-	0x0118, 0xa28e, 0x0020, 0x0140, 0x2003, 0xaaaa, 0x080c, 0x28eb,
-	0x2001, 0xb78f, 0x2102, 0x0008, 0x2102, 0x00c6, 0x2061, 0x0100,
-	0x602f, 0x0040, 0x602f, 0x0000, 0x00ce, 0x080c, 0x5acf, 0x0128,
-	0x080c, 0x40cf, 0x0110, 0x080c, 0x2867, 0x60c8, 0xa005, 0x01d0,
-	0x6003, 0x0001, 0x2009, 0x397d, 0x00e0, 0x080c, 0x5acf, 0x1178,
-	0x2011, 0x59a2, 0x080c, 0x699c, 0x2011, 0x5995, 0x080c, 0x6a5c,
-	0x2001, 0xb79f, 0x2003, 0x0000, 0x080c, 0x5a07, 0x0040, 0x080c,
-	0x4b1f, 0x0028, 0x6003, 0x0004, 0x2009, 0x3997, 0x0010, 0x0804,
-	0x2faa, 0x2001, 0x0100, 0x2004, 0xa082, 0x0005, 0x0258, 0x2001,
-	0x0170, 0x2004, 0xa084, 0x00ff, 0xa086, 0x004c, 0x1118, 0x2091,
-	0x309d, 0x0817, 0x2091, 0x301d, 0x0817, 0x6000, 0xa086, 0x0000,
-	0x0904, 0x2fcf, 0x2069, 0xb552, 0x7830, 0x6842, 0x7834, 0x6846,
-	0x6804, 0xd0fc, 0x0118, 0x2009, 0x0030, 0x0010, 0x2009, 0x001c,
-	0x2d00, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0804, 0x3eb9, 0xa006,
-	0x080c, 0x2867, 0x81ff, 0x1904, 0x2fcf, 0x080c, 0x5acf, 0x1178,
-	0x2001, 0xb79f, 0x2003, 0x0001, 0x2001, 0xb500, 0x2003, 0x0001,
-	0xa085, 0x0001, 0x080c, 0x5b13, 0x080c, 0x5a07, 0x0020, 0x080c,
-	0x4bf0, 0x080c, 0x4b1f, 0x0804, 0x2faa, 0x81ff, 0x1904, 0x2fcf,
-	0x080c, 0x5acf, 0x1110, 0x0804, 0x2fcf, 0x6188, 0x81ff, 0x0198,
-	0x703f, 0x0000, 0x2001, 0xbcc0, 0x2009, 0x0040, 0x7a2c, 0x7b28,
-	0x7c3c, 0x7d38, 0x0126, 0x2091, 0x8000, 0x080c, 0x3eb9, 0x701b,
-	0x2fa8, 0x012e, 0x0005, 0x703f, 0x0001, 0x00d6, 0x2069, 0xbcc0,
-	0x20a9, 0x0040, 0x20a1, 0xbcc0, 0x2019, 0xffff, 0x43a4, 0x6550,
-	0xa588, 0x2dc4, 0x210d, 0xa18c, 0x00ff, 0x216a, 0xa00e, 0x2011,
-	0x0002, 0x2100, 0xa506, 0x01a8, 0x080c, 0x4fa9, 0x1190, 0x6014,
-	0x821c, 0x0238, 0xa398, 0xbcc0, 0xa085, 0xff00, 0x8007, 0x201a,
-	0x0038, 0xa398, 0xbcc0, 0x2324, 0xa4a4, 0xff00, 0xa405, 0x201a,
-	0x8210, 0x8108, 0xa182, 0x0080, 0x1208, 0x0c18, 0x8201, 0x8007,
-	0x2d0c, 0xa105, 0x206a, 0x00de, 0x20a9, 0x0040, 0x20a1, 0xbcc0,
-	0x2099, 0xbcc0, 0x080c, 0x4b8f, 0x0804, 0x39f2, 0x080c, 0x3e9a,
-	0x0904, 0x2fd2, 0x00c6, 0x080c, 0x3e75, 0x00ce, 0x1120, 0x2009,
-	0x0002, 0x0804, 0x2fcf, 0x2001, 0xb553, 0x2004, 0xd0b4, 0x0550,
-	0x7824, 0xa084, 0xff00, 0xa08e, 0x7e00, 0x0520, 0xa08e, 0x7f00,
-	0x0508, 0xa08e, 0x8000, 0x01f0, 0x6000, 0xd08c, 0x11d8, 0x6004,
-	0xa084, 0x00ff, 0xa086, 0x0006, 0x11a8, 0x6837, 0x0000, 0x6838,
-	0xc0fd, 0x683a, 0x080c, 0x9dda, 0x1120, 0x2009, 0x0003, 0x0804,
-	0x2fcf, 0x7007, 0x0003, 0x701b, 0x3a7e, 0x0005, 0x080c, 0x3e9a,
-	0x0904, 0x2fd2, 0x20a9, 0x002b, 0x2c98, 0xade8, 0x0002, 0x2da0,
-	0x53a3, 0x20a9, 0x0004, 0xac80, 0x0006, 0x2098, 0xad80, 0x0006,
-	0x20a0, 0x080c, 0x4b8f, 0x20a9, 0x0004, 0xac80, 0x000a, 0x2098,
-	0xad80, 0x000a, 0x20a0, 0x080c, 0x4b8f, 0x2d00, 0x2009, 0x002b,
-	0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0804, 0x3eb9, 0x81ff, 0x1904,
-	0x2fcf, 0x080c, 0x3e8a, 0x0904, 0x2fd2, 0x080c, 0x5186, 0x0804,
-	0x2faa, 0x81ff, 0x1904, 0x2fcf, 0x7828, 0xa08a, 0x1000, 0x1a04,
-	0x2fd2, 0x080c, 0x3e9a, 0x0904, 0x2fd2, 0x080c, 0x51e9, 0x0904,
-	0x2fcf, 0x2019, 0x0004, 0xa00e, 0x080c, 0x5198, 0x7924, 0x810f,
-	0x7a28, 0x0011, 0x0804, 0x2faa, 0xa186, 0x00ff, 0x0110, 0x0071,
-	0x0060, 0x2029, 0x007e, 0x2061, 0xb500, 0x6450, 0x2400, 0xa506,
-	0x0110, 0x2508, 0x0019, 0x8529, 0x1ec8, 0x0005, 0x080c, 0x4fa9,
-	0x1138, 0x2200, 0x8003, 0x800b, 0x810b, 0xa108, 0x080c, 0x69a8,
-	0x0005, 0x81ff, 0x1904, 0x2fcf, 0x080c, 0x3e8a, 0x0904, 0x2fd2,
-	0x080c, 0x506f, 0x0904, 0x2fcf, 0x080c, 0x518f, 0x0804, 0x2faa,
-	0x81ff, 0x1904, 0x2fcf, 0x080c, 0x3e8a, 0x0904, 0x2fd2, 0x080c,
-	0x506f, 0x0904, 0x2fcf, 0x080c, 0x517d, 0x0804, 0x2faa, 0x6100,
-	0x0804, 0x2faa, 0x080c, 0x3e9a, 0x0904, 0x2fd2, 0x2001, 0xb500,
-	0x2004, 0xa086, 0x0003, 0x1904, 0x2fcf, 0x00d6, 0xace8, 0x000a,
-	0x7924, 0xd184, 0x0110, 0xace8, 0x0006, 0x680c, 0x8007, 0x783e,
-	0x6808, 0x8007, 0x783a, 0x6b04, 0x831f, 0x6a00, 0x8217, 0x00de,
-	0x6100, 0xa18c, 0x0200, 0x0804, 0x2faa, 0x7824, 0xa09c, 0x0003,
-	0xd0b4, 0x1160, 0xa39a, 0x0003, 0x1a04, 0x2fcf, 0x6250, 0xa294,
-	0x00ff, 0xa084, 0xff00, 0x8007, 0xa206, 0x1150, 0x2001, 0xb540,
-	0x2009, 0x000c, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0804, 0x3eb9,
-	0x81ff, 0x1904, 0x2fcf, 0x080c, 0x3e9a, 0x0904, 0x2fd2, 0x6004,
-	0xa084, 0x00ff, 0xa086, 0x0006, 0x1904, 0x2fcf, 0x00c6, 0x080c,
-	0x3e75, 0x00ce, 0x0904, 0x2fcf, 0x6837, 0x0000, 0x6838, 0xc0fd,
-	0x683a, 0x080c, 0x9d86, 0x0904, 0x2fcf, 0x7007, 0x0003, 0x701b,
-	0x3b6a, 0x0005, 0x6830, 0xa086, 0x0100, 0x0904, 0x2fcf, 0xad80,
-	0x000e, 0x2009, 0x000c, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0804,
-	0x3eb9, 0xa006, 0x080c, 0x2867, 0x7824, 0xa084, 0x00ff, 0xa086,
-	0x00ff, 0x0118, 0x81ff, 0x1904, 0x2fcf, 0x080c, 0x5acf, 0x0110,
-	0x080c, 0x4bf0, 0x7828, 0xa08a, 0x1000, 0x1a04, 0x2fd2, 0x7924,
-	0xa18c, 0xff00, 0x810f, 0xa186, 0x00ff, 0x0138, 0xa182, 0x007f,
-	0x1a04, 0x2fd2, 0x2100, 0x080c, 0x2831, 0x0026, 0x00c6, 0x0126,
-	0x2091, 0x8000, 0x2061, 0xb7f3, 0x601b, 0x0000, 0x601f, 0x0000,
-	0x080c, 0x5acf, 0x1178, 0x2001, 0xb79f, 0x2003, 0x0001, 0x2001,
-	0xb500, 0x2003, 0x0001, 0xa085, 0x0001, 0x080c, 0x5b13, 0x080c,
-	0x5a07, 0x0420, 0x2011, 0x0003, 0x080c, 0x8075, 0x2011, 0x0002,
-	0x080c, 0x807f, 0x080c, 0x7f59, 0x0036, 0x2019, 0x0000, 0x080c,
-	0x7fe4, 0x003e, 0x2061, 0x0100, 0x2001, 0xb515, 0x2004, 0xa084,
-	0x00ff, 0x810f, 0xa105, 0x604a, 0x6043, 0x0090, 0x6043, 0x0010,
-	0x2009, 0x002d, 0x2011, 0x4b54, 0x080c, 0x6a22, 0x7924, 0xa18c,
-	0xff00, 0x810f, 0x080c, 0x5acf, 0x1110, 0x2009, 0x00ff, 0x7a28,
-	0x080c, 0x3acc, 0x012e, 0x00ce, 0x002e, 0x0804, 0x2faa, 0x7924,
-	0xa18c, 0xff00, 0x810f, 0x00c6, 0x080c, 0x4f4d, 0x2c08, 0x00ce,
-	0x1904, 0x2fd2, 0x0804, 0x2faa, 0x81ff, 0x0120, 0x2009, 0x0001,
-	0x0804, 0x2fcf, 0x60d4, 0xd0ac, 0x1130, 0xd09c, 0x1120, 0x2009,
-	0x0005, 0x0804, 0x2fcf, 0x080c, 0x3e75, 0x1120, 0x2009, 0x0002,
-	0x0804, 0x2fcf, 0x7924, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x080c,
-	0x3eb6, 0x701b, 0x3c1c, 0x0005, 0x2009, 0x0080, 0x080c, 0x4fa9,
-	0x1130, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x0120, 0x2021,
-	0x400a, 0x0804, 0x2fac, 0x00d6, 0xade8, 0x000d, 0x6900, 0x6a08,
-	0x6b0c, 0x6c10, 0x6d14, 0x6e18, 0x6820, 0xa0be, 0x0100, 0x0904,
-	0x3c93, 0xa0be, 0x0112, 0x0904, 0x3c93, 0xa0be, 0x0113, 0x0904,
-	0x3c93, 0xa0be, 0x0114, 0x0904, 0x3c93, 0xa0be, 0x0117, 0x0904,
-	0x3c93, 0xa0be, 0x011a, 0x0904, 0x3c93, 0xa0be, 0x011c, 0x0904,
-	0x3c93, 0xa0be, 0x0121, 0x05b0, 0xa0be, 0x0131, 0x0598, 0xa0be,
-	0x0171, 0x05c8, 0xa0be, 0x0173, 0x05b0, 0xa0be, 0x01a1, 0x1120,
-	0x6830, 0x8007, 0x6832, 0x04a8, 0xa0be, 0x0212, 0x0540, 0xa0be,
-	0x0213, 0x0528, 0xa0be, 0x0214, 0x01b0, 0xa0be, 0x0217, 0x0168,
-	0xa0be, 0x021a, 0x1120, 0x6838, 0x8007, 0x683a, 0x00e0, 0xa0be,
-	0x0300, 0x01c8, 0x00de, 0x0804, 0x2fd2, 0xad80, 0x0010, 0x20a9,
-	0x0007, 0x080c, 0x3cd9, 0xad80, 0x000e, 0x20a9, 0x0001, 0x080c,
-	0x3cd9, 0x0048, 0xad80, 0x000c, 0x080c, 0x3ce7, 0x0050, 0xad80,
-	0x000e, 0x080c, 0x3ce7, 0xad80, 0x000c, 0x20a9, 0x0001, 0x080c,
-	0x3cd9, 0x00c6, 0x080c, 0x3e75, 0x0568, 0x6838, 0xc0fd, 0x683a,
-	0x6837, 0x0119, 0x6853, 0x0000, 0x684f, 0x0020, 0x685b, 0x0001,
-	0x810b, 0x697e, 0x6883, 0x0000, 0x6a86, 0x6b8a, 0x6c8e, 0x6d92,
-	0x6996, 0x689b, 0x0000, 0x00ce, 0x00de, 0x6837, 0x0000, 0x6838,
-	0xc0fd, 0x683a, 0x6823, 0x0000, 0x6804, 0x2068, 0x080c, 0x9da2,
-	0x1120, 0x2009, 0x0003, 0x0804, 0x2fcf, 0x7007, 0x0003, 0x701b,
-	0x3cd0, 0x0005, 0x00ce, 0x00de, 0x2009, 0x0002, 0x0804, 0x2fcf,
-	0x6820, 0xa086, 0x8001, 0x1904, 0x2faa, 0x2009, 0x0004, 0x0804,
-	0x2fcf, 0x0016, 0x2008, 0x2044, 0x8000, 0x204c, 0x8000, 0x290a,
-	0x8108, 0x280a, 0x8108, 0x1f04, 0x3cdb, 0x001e, 0x0005, 0x0016,
-	0x00a6, 0x00b6, 0x2008, 0x2044, 0x8000, 0x204c, 0x8000, 0x2054,
-	0x8000, 0x205c, 0x2b0a, 0x8108, 0x2a0a, 0x8108, 0x290a, 0x8108,
-	0x280a, 0x00be, 0x00ae, 0x001e, 0x0005, 0x81ff, 0x0120, 0x2009,
-	0x0001, 0x0804, 0x2fcf, 0x60d4, 0xd0ac, 0x1130, 0xd09c, 0x1120,
-	0x2009, 0x0005, 0x0804, 0x2fcf, 0x7924, 0x2140, 0xa18c, 0xff00,
-	0x810f, 0x60d4, 0xd0ac, 0x1120, 0xa182, 0x0080, 0x0a04, 0x2fd2,
-	0xa182, 0x00ff, 0x1a04, 0x2fd2, 0x7a2c, 0x7b28, 0x6070, 0xa306,
-	0x1140, 0x6074, 0xa24e, 0x0904, 0x2fd2, 0xa9cc, 0xff00, 0x0904,
-	0x2fd2, 0x00c6, 0x080c, 0x3dc5, 0x2c68, 0x00ce, 0x0530, 0xa0c6,
-	0x4000, 0x1178, 0x00c6, 0x0006, 0x2d60, 0xa00e, 0x080c, 0x524a,
+	0x8000, 0x2071, 0xb682, 0x7003, 0x0002, 0xa006, 0x7012, 0x7016,
+	0x703a, 0x703e, 0x7033, 0xb692, 0x7037, 0xb692, 0x7007, 0x0001,
+	0x2061, 0xb6d2, 0x6003, 0x0002, 0x0005, 0x1004, 0x2f1f, 0x0e04,
+	0x2f1f, 0x2071, 0xb682, 0x2b78, 0x7818, 0xd084, 0x1140, 0x2a60,
+	0x7820, 0xa08e, 0x0069, 0x1904, 0x3004, 0x0804, 0x2f9d, 0x0005,
+	0x2071, 0xb682, 0x7004, 0x0002, 0x2f28, 0x2f29, 0x2f32, 0x2f43,
+	0x0005, 0x1004, 0x2f31, 0x0e04, 0x2f31, 0x2b78, 0x7818, 0xd084,
+	0x01e8, 0x0005, 0x2b78, 0x2061, 0xb6d2, 0x6008, 0xa08e, 0x0100,
+	0x0128, 0xa086, 0x0200, 0x0904, 0x2ffe, 0x0005, 0x7014, 0x2068,
+	0x2a60, 0x7018, 0x0807, 0x7010, 0x2068, 0x6834, 0xa086, 0x0103,
+	0x0108, 0x0005, 0x2a60, 0x2b78, 0x7018, 0x0807, 0x2a60, 0x7820,
+	0xa08a, 0x0040, 0x1210, 0x61c4, 0x0042, 0x2100, 0xa08a, 0x003f,
+	0x1a04, 0x2ffb, 0x61c4, 0x0804, 0x2f9d, 0x2fdf, 0x300a, 0x3012,
+	0x3016, 0x301e, 0x3024, 0x3028, 0x3034, 0x3037, 0x3041, 0x3044,
+	0x2ffb, 0x2ffb, 0x2ffb, 0x3047, 0x2ffb, 0x3056, 0x306d, 0x3084,
+	0x30fe, 0x3103, 0x312c, 0x317d, 0x318e, 0x31ad, 0x31e5, 0x31ef,
+	0x31fc, 0x320f, 0x3230, 0x3239, 0x326f, 0x3275, 0x2ffb, 0x329e,
+	0x2ffb, 0x2ffb, 0x2ffb, 0x2ffb, 0x2ffb, 0x32a5, 0x32af, 0x2ffb,
+	0x2ffb, 0x2ffb, 0x2ffb, 0x2ffb, 0x2ffb, 0x2ffb, 0x2ffb, 0x32b7,
+	0x2ffb, 0x2ffb, 0x2ffb, 0x2ffb, 0x2ffb, 0x32c9, 0x32d3, 0x2ffb,
+	0x2ffb, 0x2ffb, 0x2ffb, 0x2ffb, 0x2ffb, 0x0002, 0x32fd, 0x3351,
+	0x33ac, 0x33c6, 0x2ffb, 0x33f7, 0x382a, 0x427a, 0x2ffb, 0x2ffb,
+	0x2ffb, 0x2ffb, 0x2ffb, 0x2ffb, 0x2ffb, 0x2ffb, 0x3041, 0x3044,
+	0x382c, 0x2ffb, 0x3839, 0x4313, 0x436e, 0x43d2, 0x2ffb, 0x4435,
+	0x445f, 0x447e, 0x44b0, 0x2ffb, 0x2ffb, 0x2ffb, 0x383d, 0x39e2,
+	0x39fc, 0x3a26, 0x3a87, 0x3ae7, 0x3af2, 0x3b2a, 0x3b39, 0x3b48,
+	0x3b4b, 0x3b6e, 0x3bba, 0x3c34, 0x3c41, 0x3d42, 0x3e6a, 0x3e93,
+	0x3f91, 0x3fb3, 0x3fbf, 0x3ff8, 0x40bc, 0x2ffb, 0x2ffb, 0x2ffb,
+	0x2ffb, 0x4124, 0x413f, 0x41b1, 0x4263, 0x713c, 0x0000, 0x2021,
+	0x4000, 0x080c, 0x3ef0, 0x0126, 0x2091, 0x8000, 0x0e04, 0x2feb,
+	0x7818, 0xd084, 0x0110, 0x012e, 0x0cb0, 0x7c22, 0x7926, 0x7a2a,
+	0x7b2e, 0x781b, 0x0001, 0x2091, 0x4080, 0x7007, 0x0001, 0x2091,
+	0x5000, 0x012e, 0x0005, 0x2021, 0x4001, 0x0c18, 0x2021, 0x4002,
+	0x0c00, 0x2021, 0x4003, 0x08e8, 0x2021, 0x4005, 0x08d0, 0x2021,
+	0x4006, 0x08b8, 0xa02e, 0x2520, 0x7b28, 0x7a2c, 0x7824, 0x7930,
+	0x0804, 0x3efd, 0x7823, 0x0004, 0x7824, 0x0807, 0xa02e, 0x2520,
+	0x7b28, 0x7a2c, 0x7824, 0x7930, 0x0804, 0x3f00, 0x7924, 0x7828,
+	0x2114, 0x200a, 0x0804, 0x2fdf, 0x7924, 0x2114, 0x0804, 0x2fdf,
+	0x2099, 0x0009, 0x20a1, 0x0009, 0x20a9, 0x0007, 0x53a3, 0x7924,
+	0x7a28, 0x7b2c, 0x0804, 0x2fdf, 0x7824, 0x2060, 0x0090, 0x2009,
+	0x0002, 0x2011, 0x0002, 0x2019, 0x0008, 0x783b, 0x0017, 0x0804,
+	0x2fdf, 0x7d38, 0x7c3c, 0x0840, 0x7d38, 0x7c3c, 0x0888, 0x2061,
+	0x1000, 0xe10c, 0xa006, 0x2c15, 0xa200, 0x8c60, 0x8109, 0x1dd8,
+	0x2010, 0xa005, 0x0904, 0x2fdf, 0x0804, 0x3001, 0x2069, 0xb652,
+	0x7824, 0x7930, 0xa11a, 0x1a04, 0x3007, 0x8019, 0x0904, 0x3007,
+	0x684a, 0x6942, 0x782c, 0x6852, 0x7828, 0x6856, 0xa006, 0x685a,
+	0x685e, 0x080c, 0x5e17, 0x0804, 0x2fdf, 0x2069, 0xb652, 0x7824,
+	0x7934, 0xa11a, 0x1a04, 0x3007, 0x8019, 0x0904, 0x3007, 0x684e,
+	0x6946, 0x782c, 0x6862, 0x7828, 0x6866, 0xa006, 0x686a, 0x686e,
+	0x080c, 0x5447, 0x0804, 0x2fdf, 0xa02e, 0x2520, 0x81ff, 0x1904,
+	0x3004, 0x7924, 0x7b28, 0x7a2c, 0x20a9, 0x0005, 0x20a1, 0xb689,
+	0x41a1, 0x080c, 0x3ebc, 0x0904, 0x3004, 0x2009, 0x0020, 0x080c,
+	0x3efd, 0x701b, 0x309c, 0x0005, 0x6834, 0x2008, 0xa084, 0x00ff,
+	0xa096, 0x0011, 0x0138, 0xa096, 0x0019, 0x0120, 0xa096, 0x0015,
+	0x1904, 0x3004, 0x810f, 0xa18c, 0x00ff, 0x0904, 0x3004, 0x710e,
+	0x700c, 0x8001, 0x0528, 0x700e, 0x080c, 0x3ebc, 0x0904, 0x3004,
+	0x2009, 0x0020, 0x2061, 0xb6d2, 0x6224, 0x6328, 0x642c, 0x6530,
+	0xa290, 0x0040, 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000,
+	0x080c, 0x3efd, 0x701b, 0x30cd, 0x0005, 0x6834, 0xa084, 0x00ff,
+	0xa096, 0x0002, 0x0120, 0xa096, 0x000a, 0x1904, 0x3004, 0x08c0,
+	0x7010, 0x2068, 0x6838, 0xc0fd, 0x683a, 0x080c, 0x4ebb, 0x1128,
+	0x7007, 0x0003, 0x701b, 0x30e7, 0x0005, 0x080c, 0x554d, 0x0126,
+	0x2091, 0x8000, 0x20a9, 0x0005, 0x2099, 0xb689, 0x530a, 0x2100,
+	0xa210, 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0xad80,
+	0x000d, 0x2009, 0x0020, 0x012e, 0x0804, 0x3f00, 0x61ac, 0x7824,
+	0x60ae, 0x0804, 0x2fdf, 0x2091, 0x8000, 0x7823, 0x4000, 0x7827,
+	0x4953, 0x782b, 0x5020, 0x782f, 0x2020, 0x2009, 0x017f, 0x2104,
+	0x7832, 0x3f00, 0x7836, 0x2061, 0x0100, 0x6200, 0x2061, 0x0200,
+	0x603c, 0x8007, 0xa205, 0x783a, 0x2009, 0x04fd, 0x2104, 0x783e,
+	0x781b, 0x0001, 0x2091, 0x5000, 0x2091, 0x4080, 0x2071, 0x0010,
+	0x20c1, 0x00f0, 0x0804, 0x0427, 0x81ff, 0x1904, 0x3004, 0x7924,
+	0x810f, 0xa18c, 0x00ff, 0x080c, 0x501b, 0x1904, 0x3007, 0x7e38,
+	0xa684, 0x3fff, 0xa082, 0x4000, 0x0210, 0x0804, 0x3007, 0x7c28,
+	0x7d2c, 0x080c, 0x51e3, 0xd28c, 0x1118, 0x080c, 0x518c, 0x0010,
+	0x080c, 0x51bc, 0x1518, 0x2061, 0xbe00, 0x0126, 0x2091, 0x8000,
+	0x6000, 0xa086, 0x0000, 0x0148, 0x6010, 0xa06d, 0x0130, 0x683c,
+	0xa406, 0x1118, 0x6840, 0xa506, 0x0150, 0x012e, 0xace0, 0x0018,
+	0x2001, 0xb617, 0x2004, 0xac02, 0x1a04, 0x3004, 0x0c30, 0x080c,
+	0x99e6, 0x012e, 0x0904, 0x3004, 0x0804, 0x2fdf, 0xa00e, 0x2001,
+	0x0005, 0x080c, 0x554d, 0x0126, 0x2091, 0x8000, 0x080c, 0x9f8e,
+	0x080c, 0x547a, 0x012e, 0x0804, 0x2fdf, 0x81ff, 0x1904, 0x3004,
+	0x080c, 0x3ed1, 0x0904, 0x3007, 0x080c, 0x50e1, 0x0904, 0x3004,
+	0x080c, 0x51ef, 0x0904, 0x3004, 0x0804, 0x2fdf, 0x81ff, 0x1904,
+	0x3004, 0x080c, 0x3ee1, 0x0904, 0x3007, 0x080c, 0x525b, 0x0904,
+	0x3004, 0x2019, 0x0005, 0x7924, 0x080c, 0x520a, 0x0904, 0x3004,
+	0x7828, 0xa08a, 0x1000, 0x1a04, 0x3007, 0x8003, 0x800b, 0x810b,
+	0xa108, 0x080c, 0x6a1a, 0x0804, 0x2fdf, 0x0126, 0x2091, 0x8000,
+	0x81ff, 0x0118, 0x2009, 0x0001, 0x0450, 0x2029, 0x00ff, 0x6450,
+	0x2400, 0xa506, 0x01f8, 0x2508, 0x080c, 0x501b, 0x11d8, 0x080c,
+	0x525b, 0x1128, 0x2009, 0x0002, 0x62b4, 0x2518, 0x00c0, 0x2019,
+	0x0004, 0xa00e, 0x080c, 0x520a, 0x1118, 0x2009, 0x0006, 0x0078,
+	0x7824, 0xa08a, 0x1000, 0x1270, 0x8003, 0x800b, 0x810b, 0xa108,
+	0x080c, 0x6a1a, 0x8529, 0x1ae0, 0x012e, 0x0804, 0x2fdf, 0x012e,
+	0x0804, 0x3004, 0x012e, 0x0804, 0x3007, 0x080c, 0x3ed1, 0x0904,
+	0x3007, 0x080c, 0x5147, 0x080c, 0x51e3, 0x0804, 0x2fdf, 0x81ff,
+	0x1904, 0x3004, 0x080c, 0x3ed1, 0x0904, 0x3007, 0x080c, 0x5138,
+	0x080c, 0x51e3, 0x0804, 0x2fdf, 0x81ff, 0x1904, 0x3004, 0x080c,
+	0x3ed1, 0x0904, 0x3007, 0x080c, 0x51be, 0x0904, 0x3004, 0x080c,
+	0x4eff, 0x080c, 0x5185, 0x080c, 0x51e3, 0x0804, 0x2fdf, 0x080c,
+	0x3ed1, 0x0904, 0x3007, 0x080c, 0x50e1, 0x0904, 0x3004, 0x62a0,
+	0x2019, 0x0005, 0x00c6, 0x080c, 0x521c, 0x2061, 0x0000, 0x080c,
+	0x6e67, 0x0076, 0x2039, 0x0000, 0x080c, 0x6d74, 0x2009, 0x0000,
+	0x080c, 0xaf3e, 0x007e, 0x00ce, 0x080c, 0x51e3, 0x0804, 0x2fdf,
+	0x080c, 0x3ed1, 0x0904, 0x3007, 0x080c, 0x51e3, 0x2208, 0x0804,
+	0x2fdf, 0x0156, 0x00d6, 0x00e6, 0x2069, 0xb714, 0x6810, 0x6914,
+	0xa10a, 0x1210, 0x2009, 0x0000, 0x6816, 0x2011, 0x0000, 0x2019,
+	0x0000, 0x20a9, 0x007e, 0x2069, 0xb735, 0x2d04, 0xa075, 0x0130,
+	0x704c, 0x0071, 0xa210, 0x7080, 0x0059, 0xa318, 0x8d68, 0x1f04,
+	0x324d, 0x2300, 0xa218, 0x00ee, 0x00de, 0x015e, 0x0804, 0x2fdf,
+	0x00f6, 0x0016, 0xa07d, 0x0140, 0x2001, 0x0000, 0x8000, 0x2f0c,
+	0x81ff, 0x0110, 0x2178, 0x0cd0, 0x001e, 0x00fe, 0x0005, 0x2069,
+	0xb714, 0x6910, 0x62b0, 0x0804, 0x2fdf, 0x81ff, 0x1904, 0x3004,
+	0x6150, 0xa190, 0x2df9, 0x2215, 0xa294, 0x00ff, 0x6370, 0x83ff,
+	0x0108, 0x6274, 0x67d4, 0xd79c, 0x0118, 0x2031, 0x0001, 0x0090,
+	0xd7ac, 0x0118, 0x2031, 0x0003, 0x0068, 0xd7a4, 0x0118, 0x2031,
+	0x0002, 0x0040, 0x080c, 0x5b41, 0x1118, 0x2031, 0x0004, 0x0010,
+	0x2031, 0x0000, 0x7e3a, 0x7f3e, 0x0804, 0x2fdf, 0x6140, 0x6244,
+	0x2019, 0xb8b6, 0x231c, 0x0804, 0x2fdf, 0x0126, 0x2091, 0x8000,
+	0x6134, 0xa006, 0x2010, 0x6338, 0x012e, 0x0804, 0x2fdf, 0x080c,
+	0x3ee1, 0x0904, 0x3007, 0x6244, 0x6338, 0x0804, 0x2fdf, 0x6140,
+	0x6244, 0x7824, 0x6042, 0x7b28, 0x6346, 0x2069, 0xb652, 0x831f,
+	0xa305, 0x6816, 0x782c, 0x2069, 0xb8b6, 0x2d1c, 0x206a, 0x0804,
+	0x2fdf, 0x0126, 0x2091, 0x8000, 0x7824, 0x6036, 0x782c, 0x603a,
+	0x012e, 0x0804, 0x2fdf, 0x7838, 0xa005, 0x01a8, 0x7828, 0xa025,
+	0x0904, 0x3007, 0x782c, 0xa02d, 0x0904, 0x3007, 0xa00e, 0x080c,
+	0x501b, 0x1120, 0x6244, 0x6338, 0x6446, 0x653a, 0xa186, 0x00ff,
+	0x0190, 0x8108, 0x0ca0, 0x080c, 0x3ee1, 0x0904, 0x3007, 0x7828,
+	0xa00d, 0x0904, 0x3007, 0x782c, 0xa005, 0x0904, 0x3007, 0x6244,
+	0x6146, 0x6338, 0x603a, 0x0804, 0x2fdf, 0x2001, 0xb600, 0x2004,
+	0xa086, 0x0003, 0x1904, 0x3004, 0x00c6, 0x2061, 0x0100, 0x7924,
+	0x810f, 0xa18c, 0x00ff, 0xa196, 0x00ff, 0x1130, 0x2001, 0xb615,
+	0x2004, 0xa085, 0xff00, 0x0078, 0xa182, 0x007f, 0x16a0, 0xa188,
+	0x2df9, 0x210d, 0xa18c, 0x00ff, 0x2001, 0xb615, 0x2004, 0xa116,
+	0x0550, 0x810f, 0xa105, 0x0126, 0x2091, 0x8000, 0x0006, 0x080c,
+	0x864e, 0x000e, 0x01e0, 0x601a, 0x600b, 0xbc09, 0x601f, 0x0001,
+	0x080c, 0x3ebc, 0x01d8, 0x6837, 0x0000, 0x7007, 0x0003, 0x6833,
+	0x0000, 0x6838, 0xc0fd, 0x683a, 0x701b, 0x33a5, 0x2d00, 0x6012,
+	0x2009, 0x0032, 0x080c, 0x86d3, 0x012e, 0x00ce, 0x0005, 0x012e,
+	0x00ce, 0x0804, 0x3004, 0x00ce, 0x0804, 0x3007, 0x080c, 0x86a4,
+	0x0cb0, 0x2001, 0xb600, 0x2004, 0xa086, 0x0003, 0x1904, 0x3004,
+	0x00c6, 0x2061, 0x0100, 0x7924, 0x810f, 0xa18c, 0x00ff, 0xa196,
+	0x00ff, 0x1130, 0x2001, 0xb615, 0x2004, 0xa085, 0xff00, 0x0078,
+	0xa182, 0x007f, 0x16a0, 0xa188, 0x2df9, 0x210d, 0xa18c, 0x00ff,
+	0x2001, 0xb615, 0x2004, 0xa116, 0x0550, 0x810f, 0xa105, 0x0126,
+	0x2091, 0x8000, 0x0006, 0x080c, 0x864e, 0x000e, 0x01e0, 0x601a,
+	0x600b, 0xbc05, 0x601f, 0x0001, 0x080c, 0x3ebc, 0x01d8, 0x6837,
+	0x0000, 0x7007, 0x0003, 0x6833, 0x0000, 0x6838, 0xc0fd, 0x683a,
+	0x701b, 0x33a5, 0x2d00, 0x6012, 0x2009, 0x0032, 0x080c, 0x86d3,
+	0x012e, 0x00ce, 0x0005, 0x012e, 0x00ce, 0x0804, 0x3004, 0x00ce,
+	0x0804, 0x3007, 0x080c, 0x86a4, 0x0cb0, 0x6830, 0xa086, 0x0100,
+	0x0904, 0x3004, 0x0804, 0x2fdf, 0x2061, 0xb975, 0x0126, 0x2091,
+	0x8000, 0x6000, 0xd084, 0x0178, 0x6104, 0x6208, 0x2a60, 0x6068,
+	0x783a, 0x60b4, 0x783e, 0x60b0, 0x2019, 0x0072, 0x201a, 0x6348,
+	0x012e, 0x0804, 0x2fdf, 0xa00e, 0x2110, 0x0c80, 0x81ff, 0x1904,
+	0x3004, 0x080c, 0x5b41, 0x0904, 0x3004, 0x0126, 0x2091, 0x8000,
+	0x6248, 0x6068, 0xa202, 0x0248, 0xa085, 0x0001, 0x080c, 0x289c,
+	0x080c, 0x4673, 0x012e, 0x0804, 0x2fdf, 0x012e, 0x0804, 0x3007,
+	0x0006, 0x0016, 0x00c6, 0x00e6, 0x2001, 0xb8c0, 0x2070, 0x2061,
+	0xb652, 0x6008, 0x2072, 0x2009, 0x0000, 0x2011, 0x1000, 0x080c,
+	0x6bb2, 0x7206, 0x00ee, 0x00ce, 0x001e, 0x000e, 0x0005, 0x0126,
+	0x2091, 0x8000, 0x7824, 0xa084, 0x0007, 0x0002, 0x3409, 0x3412,
+	0x3419, 0x3406, 0x3406, 0x3406, 0x3406, 0x3406, 0x012e, 0x0804,
+	0x3007, 0x2009, 0x0114, 0x2104, 0xa085, 0x0800, 0x200a, 0x080c,
+	0x3584, 0x0070, 0x2009, 0x010b, 0x200b, 0x0010, 0x080c, 0x3584,
+	0x0038, 0x81ff, 0x0128, 0x012e, 0x2021, 0x400b, 0x0804, 0x2fe1,
+	0x0086, 0x0096, 0x00a6, 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6,
+	0x080c, 0x33e0, 0x2009, 0x0101, 0x210c, 0x0016, 0x2001, 0x0138,
+	0x200c, 0x2003, 0x0001, 0x0016, 0x2001, 0x007a, 0x2034, 0x2001,
+	0x007b, 0x202c, 0xa006, 0x2048, 0x2050, 0x2058, 0x080c, 0x37cf,
+	0x080c, 0x3733, 0xa03e, 0x2720, 0x00f6, 0x00e6, 0x00c6, 0x2d60,
+	0x2071, 0xb94b, 0x2079, 0x0020, 0x00d6, 0x2069, 0x0000, 0x6824,
+	0xd0b4, 0x0140, 0x2001, 0x007d, 0x2004, 0x783e, 0x2001, 0x007c,
+	0x2004, 0x783a, 0x00de, 0x2011, 0x0001, 0x080c, 0x36df, 0x080c,
+	0x36df, 0x00ce, 0x00ee, 0x00fe, 0x080c, 0x362a, 0x080c, 0x3707,
+	0x080c, 0x3684, 0x080c, 0x35e9, 0x080c, 0x361a, 0x00f6, 0x2079,
+	0x0100, 0x7824, 0xd094, 0x0530, 0x7814, 0xa084, 0x0184, 0xa085,
+	0x0010, 0x7816, 0x2079, 0x0140, 0x080c, 0x3562, 0x1110, 0x00fe,
+	0x0430, 0x7804, 0xd0dc, 0x0dc0, 0x2079, 0x0100, 0x7827, 0x0086,
+	0x7814, 0xa084, 0x0184, 0xa085, 0x0032, 0x7816, 0x080c, 0x3562,
+	0x1110, 0x00fe, 0x00a0, 0x7824, 0xd0bc, 0x0dc0, 0x7827, 0x0080,
+	0xa026, 0x7c16, 0x7824, 0xd0ac, 0x0130, 0x8b58, 0x080c, 0x356c,
+	0x00fe, 0x0804, 0x352c, 0x00fe, 0x080c, 0x3562, 0x1150, 0x8948,
+	0x2001, 0x007a, 0x2602, 0x2001, 0x007b, 0x2502, 0x080c, 0x356c,
+	0x0088, 0x87ff, 0x0140, 0x2001, 0x0201, 0x2004, 0xa005, 0x1904,
+	0x3466, 0x8739, 0x0038, 0x2001, 0xb924, 0x2004, 0xa086, 0x0000,
+	0x1904, 0x3466, 0x2001, 0x0033, 0x2003, 0x00f6, 0x8631, 0x1208,
+	0x8529, 0x2500, 0xa605, 0x0904, 0x352c, 0x7824, 0xd0bc, 0x0128,
+	0x2900, 0xaa05, 0xab05, 0x1904, 0x352c, 0x6033, 0x000d, 0x2001,
+	0x0030, 0x2003, 0x0004, 0x7824, 0xd0ac, 0x1148, 0x2001, 0xb924,
+	0x2003, 0x0003, 0x2001, 0x0030, 0x2003, 0x0009, 0x0040, 0x6027,
+	0x0001, 0x2001, 0x0075, 0x2004, 0xa005, 0x0108, 0x6026, 0x2c00,
+	0x601a, 0x20e1, 0x9040, 0x2d00, 0x681a, 0x6833, 0x000d, 0x7824,
+	0xd0a4, 0x1180, 0x6827, 0x0000, 0x00c6, 0x20a9, 0x0004, 0x2061,
+	0x0020, 0x6003, 0x0008, 0x2001, 0x0203, 0x2004, 0x1f04, 0x3501,
+	0x00ce, 0x0040, 0x6827, 0x0001, 0x2001, 0x0074, 0x2004, 0xa005,
+	0x0108, 0x6826, 0x00f6, 0x00c6, 0x2079, 0x0100, 0x2061, 0x0020,
+	0x7827, 0x0002, 0x2001, 0x0072, 0x2004, 0xa084, 0xfff8, 0x601a,
+	0x0006, 0x2001, 0x0073, 0x2004, 0x601e, 0x78c6, 0x000e, 0x78ca,
+	0x00ce, 0x00fe, 0x0804, 0x3444, 0x2061, 0x0100, 0x6027, 0x0002,
+	0x001e, 0x61e2, 0x001e, 0x6106, 0x7824, 0xa084, 0x0003, 0xa086,
+	0x0002, 0x0188, 0x20e1, 0x9028, 0x6050, 0xa084, 0xf7ef, 0x6052,
+	0x602f, 0x0000, 0x602c, 0xc0ac, 0x602e, 0x604b, 0xf7f7, 0x6043,
+	0x0090, 0x6043, 0x0010, 0x2908, 0x2a10, 0x2b18, 0x2b00, 0xaa05,
+	0xa905, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x00ae, 0x009e,
+	0x008e, 0x1118, 0x012e, 0x0804, 0x2fdf, 0x012e, 0x2021, 0x400c,
+	0x0804, 0x2fe1, 0xa085, 0x0001, 0x1d04, 0x356b, 0x2091, 0x6000,
+	0x8420, 0xa486, 0x0064, 0x0005, 0x2001, 0x0105, 0x2003, 0x0010,
+	0x2001, 0x0030, 0x2003, 0x0004, 0x2001, 0x0020, 0x2003, 0x0004,
+	0x2001, 0xb924, 0x2003, 0x0000, 0x2001, 0xb94b, 0x2003, 0x0000,
+	0x20e1, 0xf000, 0xa026, 0x0005, 0x00f6, 0x2079, 0x0100, 0x2001,
+	0xb615, 0x200c, 0x7932, 0x7936, 0x080c, 0x287c, 0x7850, 0xa084,
+	0x0980, 0xa085, 0x0030, 0x7852, 0x2019, 0x01f4, 0x8319, 0x1df0,
+	0xa084, 0x0980, 0x7852, 0x782c, 0xc0ad, 0x782e, 0x20a9, 0x0046,
+	0x1d04, 0x35a0, 0x2091, 0x6000, 0x1f04, 0x35a0, 0x7850, 0xa085,
+	0x0400, 0x7852, 0x2001, 0x0009, 0x2004, 0xa084, 0x0003, 0xa086,
+	0x0001, 0x1118, 0x782c, 0xc0ac, 0x782e, 0x784b, 0xf7f7, 0x7843,
+	0x0090, 0x7843, 0x0010, 0x20a9, 0x000e, 0xe000, 0x1f04, 0x35bd,
+	0x7850, 0xa085, 0x1400, 0x7852, 0x2019, 0x61a8, 0x7854, 0xe000,
+	0xe000, 0xd08c, 0x1110, 0x8319, 0x1dc8, 0x7827, 0x0048, 0x7850,
+	0xa085, 0x0400, 0x7852, 0x7843, 0x0040, 0x2019, 0x01f4, 0xe000,
+	0xe000, 0x8319, 0x1de0, 0x2001, 0x0140, 0x2003, 0x0100, 0x7827,
+	0x0020, 0x7843, 0x0000, 0x2003, 0x0000, 0x7827, 0x0048, 0x00fe,
+	0x0005, 0x7824, 0xd0ac, 0x11c8, 0x00f6, 0x00e6, 0x2071, 0xb924,
+	0x2079, 0x0030, 0x2001, 0x0201, 0x2004, 0xa005, 0x0160, 0x7000,
+	0xa086, 0x0000, 0x1140, 0x0051, 0xd0bc, 0x0108, 0x8738, 0x7003,
+	0x0003, 0x7803, 0x0019, 0x00ee, 0x00fe, 0x0005, 0x780c, 0xa08c,
+	0x0070, 0x0178, 0x2009, 0x007a, 0x260a, 0x2009, 0x007b, 0x250a,
+	0xd0b4, 0x0108, 0x8a50, 0xd0ac, 0x0108, 0x8948, 0xd0a4, 0x0108,
+	0x8b58, 0x0005, 0x00f6, 0x2079, 0x0200, 0x781c, 0xd084, 0x0140,
+	0x20e1, 0x0007, 0x20e1, 0x2000, 0x2001, 0x020a, 0x2004, 0x0ca8,
+	0x00fe, 0x0005, 0x00e6, 0x2071, 0x0100, 0x2001, 0xb8c1, 0x2004,
+	0x70e2, 0x2009, 0xb615, 0x210c, 0x716e, 0x7063, 0x0100, 0x7166,
+	0x719e, 0x706b, 0x0000, 0x7073, 0x0809, 0x7077, 0x0008, 0x7078,
+	0xa080, 0x0100, 0x707a, 0x7080, 0x8000, 0x7082, 0x7087, 0xaaaa,
+	0xa006, 0x708a, 0x708e, 0x707e, 0x70d6, 0x70ab, 0x0036, 0x70af,
+	0x95d5, 0x7027, 0x0080, 0x7014, 0xa084, 0x0184, 0xa085, 0x0032,
+	0x7016, 0x080c, 0x3707, 0x080c, 0x3562, 0x1110, 0x8421, 0x0028,
+	0x7024, 0xd0bc, 0x0db0, 0x7027, 0x0080, 0x00f6, 0x00e6, 0x2071,
+	0xb924, 0x2079, 0x0030, 0x00d6, 0x2069, 0x0000, 0x6824, 0xd0b4,
+	0x0120, 0x683c, 0x783e, 0x6838, 0x783a, 0x00de, 0x2011, 0x0011,
+	0x080c, 0x36df, 0x2011, 0x0001, 0x080c, 0x36df, 0x00ee, 0x00fe,
+	0x7017, 0x0000, 0x00ee, 0x0005, 0x00f6, 0x00e6, 0x2071, 0xb924,
+	0x2079, 0x0030, 0x7904, 0xd1fc, 0x0904, 0x36dc, 0x7803, 0x0002,
+	0xa026, 0xd19c, 0x1904, 0x36d8, 0x7000, 0x0002, 0x36dc, 0x369a,
+	0x36be, 0x36d8, 0xd1bc, 0x1150, 0xd1dc, 0x1150, 0x8001, 0x7002,
+	0x2011, 0x0001, 0x04e1, 0x05c0, 0x04d1, 0x04b0, 0x780f, 0x0000,
+	0x7820, 0x7924, 0x7803, 0x0004, 0x7822, 0x7926, 0x2001, 0x0201,
+	0x200c, 0x81ff, 0x0de8, 0x080c, 0x3606, 0x2009, 0x0001, 0x7808,
+	0xd0ec, 0x0110, 0x2009, 0x0011, 0x7902, 0x00f0, 0x8001, 0x7002,
+	0xa184, 0x0880, 0x1138, 0x7804, 0xd0fc, 0x1940, 0x2011, 0x0001,
+	0x00b1, 0x0090, 0x6030, 0xa092, 0x0004, 0xa086, 0x0009, 0x1120,
+	0x6000, 0x601a, 0x2011, 0x0025, 0x6232, 0xd1dc, 0x1988, 0x0870,
+	0x7803, 0x0004, 0x7003, 0x0000, 0x00ee, 0x00fe, 0x0005, 0x6024,
+	0xa005, 0x0520, 0x8001, 0x6026, 0x6018, 0x6130, 0xa140, 0x2804,
+	0x7832, 0x8840, 0x2804, 0x7836, 0x8840, 0x2804, 0x7822, 0x8840,
+	0x2804, 0x7826, 0x8840, 0x7a02, 0x7000, 0x8000, 0x7002, 0x6018,
+	0xa802, 0xa08a, 0x0029, 0x1138, 0x6018, 0xa080, 0x0001, 0x2004,
+	0x601a, 0x2001, 0x000d, 0x6032, 0xa085, 0x0001, 0x0005, 0x00f6,
+	0x00e6, 0x00c6, 0x2071, 0xb94b, 0x2079, 0x0020, 0x7904, 0xd1fc,
+	0x01f0, 0x7803, 0x0002, 0x2d60, 0xa026, 0x7000, 0x0002, 0x372f,
+	0x371a, 0x3726, 0x8001, 0x7002, 0xd19c, 0x1188, 0x2011, 0x0001,
+	0x080c, 0x36df, 0x0160, 0x080c, 0x36df, 0x0048, 0x8001, 0x7002,
+	0x7804, 0xd0fc, 0x1d30, 0x2011, 0x0001, 0x080c, 0x36df, 0x00ce,
+	0x00ee, 0x00fe, 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x2061, 0x0200,
+	0x2001, 0xb8c1, 0x2004, 0x601a, 0x2061, 0x0100, 0x2001, 0xb8c0,
+	0x2004, 0x60ce, 0x6004, 0xc0ac, 0xa085, 0x0200, 0x6006, 0x2001,
+	0x0074, 0x2004, 0xa005, 0x01f8, 0x2038, 0x2001, 0x0076, 0x2024,
+	0x2001, 0x0077, 0x201c, 0x080c, 0x3ebc, 0x6833, 0x000d, 0x6f26,
+	0x2d00, 0x681a, 0xa78a, 0x0007, 0x0220, 0x2138, 0x2009, 0x0007,
+	0x0010, 0x2708, 0xa03e, 0x6818, 0xa080, 0x000d, 0x04b1, 0x1d90,
+	0x2d00, 0x681a, 0x0088, 0x080c, 0x3ebc, 0x6833, 0x000d, 0x2070,
+	0x6827, 0x0001, 0x2d00, 0x681a, 0x2001, 0x0076, 0x2004, 0x2072,
+	0x2001, 0x0077, 0x2004, 0x7006, 0x2061, 0x0020, 0x2079, 0x0100,
+	0x2001, 0xb8c0, 0x2004, 0x6012, 0x20e1, 0x9040, 0x2001, 0x0072,
+	0x2004, 0xa084, 0xfff8, 0x700a, 0x601a, 0x0006, 0x2001, 0x0073,
+	0x2004, 0x700e, 0x601e, 0x78c6, 0x000e, 0x78ca, 0xa006, 0x603a,
+	0x603e, 0x00ce, 0x00ee, 0x00fe, 0x0005, 0x00e6, 0x2071, 0x0010,
+	0x20a0, 0x2099, 0x0014, 0x7003, 0x0026, 0x7432, 0x7336, 0xa006,
+	0x703a, 0x703e, 0x810b, 0x810b, 0x21a8, 0x810b, 0x7122, 0x7003,
+	0x0041, 0x7004, 0xd0fc, 0x0de8, 0x7003, 0x0002, 0x7003, 0x0040,
+	0x53a5, 0x7430, 0x7334, 0x87ff, 0x0180, 0x00c6, 0x00d6, 0x2d60,
+	0x00c6, 0x080c, 0x3ebc, 0x00ce, 0x6018, 0x2070, 0x2d00, 0x7006,
+	0x601a, 0x00de, 0x00ce, 0xa085, 0x0001, 0x00ee, 0x0005, 0x00e6,
+	0x2001, 0x0075, 0x2004, 0xa005, 0x0508, 0x2038, 0x2001, 0x0078,
+	0x2024, 0x2001, 0x0079, 0x201c, 0x080c, 0x3ebc, 0x2d60, 0x6833,
+	0x000d, 0x6f26, 0x2d00, 0x681a, 0xa78a, 0x0007, 0x0220, 0x2138,
+	0x2009, 0x0007, 0x0010, 0x2708, 0xa03e, 0x6818, 0xa080, 0x000d,
+	0x080c, 0x379d, 0x1d88, 0x2d00, 0x681a, 0x00e0, 0x080c, 0x3ebc,
+	0x2d60, 0x6033, 0x000d, 0x2070, 0x6027, 0x0001, 0x2c00, 0x601a,
+	0x2001, 0x0078, 0x2004, 0x2072, 0x2001, 0x0079, 0x2004, 0x7006,
+	0x2001, 0x0072, 0x2004, 0xa084, 0xfff8, 0x700a, 0x2001, 0x0073,
+	0x2004, 0x700e, 0x2001, 0x0030, 0x2003, 0x0004, 0x7824, 0xd0ac,
+	0x1178, 0x2001, 0x0101, 0x200c, 0xc1ed, 0x2102, 0x6027, 0x0000,
+	0x2001, 0xb924, 0x2003, 0x0003, 0x2001, 0x0030, 0x2003, 0x0009,
+	0x00ee, 0x0005, 0x0804, 0x2fdf, 0x0126, 0x2091, 0x8000, 0x20a9,
+	0x0012, 0x2001, 0xb640, 0x20a0, 0xa006, 0x40a4, 0x012e, 0x0804,
+	0x2fdf, 0x7d38, 0x7c3c, 0x0804, 0x3086, 0x080c, 0x3ebc, 0x0904,
+	0x3004, 0x080c, 0x5b41, 0x0110, 0x080c, 0x4c52, 0x2009, 0x001c,
+	0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x080c, 0x3efd, 0x701b, 0x3851,
+	0x0005, 0xade8, 0x000d, 0x6800, 0xa005, 0x0904, 0x3007, 0x6804,
+	0xd0ac, 0x0118, 0xd0a4, 0x0904, 0x3007, 0xd094, 0x00c6, 0x2061,
+	0x0100, 0x6104, 0x0138, 0x6200, 0xa292, 0x0005, 0x0218, 0xa18c,
+	0xffdf, 0x0010, 0xa18d, 0x0020, 0x6106, 0x00ce, 0xd08c, 0x00c6,
+	0x2061, 0x0100, 0x6104, 0x0118, 0xa18d, 0x0010, 0x0010, 0xa18c,
+	0xffef, 0x6106, 0x00ce, 0x2009, 0x0100, 0x210c, 0xa18a, 0x0002,
+	0x0268, 0xd084, 0x0158, 0x6a28, 0xa28a, 0x007f, 0x1a04, 0x3007,
+	0xa288, 0x2df9, 0x210d, 0xa18c, 0x00ff, 0x615a, 0xd0dc, 0x0130,
+	0x6828, 0xa08a, 0x007f, 0x1a04, 0x3007, 0x6052, 0x6808, 0xa08a,
+	0x0100, 0x0a04, 0x3007, 0xa08a, 0x0841, 0x1a04, 0x3007, 0xa084,
+	0x0007, 0x1904, 0x3007, 0x680c, 0xa005, 0x0904, 0x3007, 0x6810,
+	0xa005, 0x0904, 0x3007, 0x6848, 0x6940, 0xa10a, 0x1a04, 0x3007,
+	0x8001, 0x0904, 0x3007, 0x684c, 0x6944, 0xa10a, 0x1a04, 0x3007,
+	0x8001, 0x0904, 0x3007, 0x6804, 0xd0fc, 0x0560, 0x080c, 0x3ebc,
+	0x0904, 0x3004, 0x2009, 0x0014, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38,
+	0xa290, 0x0038, 0xa399, 0x0000, 0x080c, 0x3efd, 0x701b, 0x38d1,
+	0x0005, 0xade8, 0x000d, 0x20a9, 0x0014, 0x2d98, 0x2069, 0xb66e,
+	0x2da0, 0x53a3, 0x7010, 0xa0e8, 0x000d, 0x2001, 0xb672, 0x200c,
+	0xd1e4, 0x0140, 0x00c6, 0x2061, 0x0100, 0x6004, 0xa085, 0x0b00,
+	0x6006, 0x00ce, 0x2009, 0xb8b1, 0x200b, 0x0000, 0x2001, 0xb674,
+	0x2004, 0xd0ac, 0x0158, 0x7824, 0x200a, 0x2009, 0x017f, 0x200a,
+	0x3200, 0xa084, 0x003f, 0xa085, 0x3020, 0x2090, 0x20a9, 0x001c,
+	0x2d98, 0x2069, 0xb652, 0x2da0, 0x53a3, 0x6814, 0xa08c, 0x00ff,
+	0x6142, 0x8007, 0xa084, 0x00ff, 0x6046, 0x080c, 0x5e17, 0x080c,
+	0x53de, 0x080c, 0x5447, 0x6000, 0xa086, 0x0000, 0x1904, 0x39cc,
+	0x6808, 0x602a, 0x080c, 0x24a5, 0x0006, 0x2001, 0x0100, 0x2004,
+	0xa082, 0x0005, 0x000e, 0x0268, 0x2009, 0x0170, 0x200b, 0x0080,
+	0xe000, 0xe000, 0x200b, 0x0000, 0x0036, 0x6b08, 0x080c, 0x28d7,
+	0x003e, 0x6818, 0x691c, 0x6a20, 0x6b24, 0x8007, 0x810f, 0x8217,
+	0x831f, 0x6016, 0x611a, 0x621e, 0x6322, 0x6c04, 0xd4f4, 0x0148,
+	0x6830, 0x6934, 0x6a38, 0x6b3c, 0x8007, 0x810f, 0x8217, 0x831f,
+	0x0010, 0xa084, 0xf0ff, 0x6006, 0x610a, 0x620e, 0x6312, 0x8007,
+	0x810f, 0x8217, 0x831f, 0x20a9, 0x0004, 0x20a1, 0xb8c7, 0x40a1,
+	0x080c, 0x6ada, 0x6904, 0xd1fc, 0x0520, 0x00c6, 0x2009, 0x0000,
+	0x20a9, 0x0001, 0x6b70, 0xd384, 0x01c8, 0x0020, 0x839d, 0x12b0,
+	0x3508, 0x8109, 0x080c, 0x63ce, 0x6878, 0x6016, 0x6874, 0x2008,
+	0xa084, 0xff00, 0x8007, 0x600a, 0xa184, 0x00ff, 0x6006, 0x8108,
+	0x1118, 0x6003, 0x0003, 0x0010, 0x6003, 0x0001, 0x1f04, 0x3966,
+	0x00ce, 0x2069, 0xb652, 0x2001, 0xb89e, 0x6a80, 0xa294, 0x0030,
+	0xa28e, 0x0000, 0x0170, 0xa28e, 0x0010, 0x0118, 0xa28e, 0x0020,
+	0x0140, 0x2003, 0xaaaa, 0x080c, 0x2920, 0x2001, 0xb88f, 0x2102,
+	0x0008, 0x2102, 0x00c6, 0x2061, 0x0100, 0x602f, 0x0040, 0x602f,
+	0x0000, 0x00ce, 0x080c, 0x5b41, 0x0128, 0x080c, 0x4116, 0x0110,
+	0x080c, 0x289c, 0x60c8, 0xa005, 0x01d0, 0x6003, 0x0001, 0x2009,
+	0x39b2, 0x00e0, 0x080c, 0x5b41, 0x1178, 0x2011, 0x5a14, 0x080c,
+	0x6a0e, 0x2011, 0x5a07, 0x080c, 0x6ace, 0x2001, 0xb89f, 0x2003,
+	0x0000, 0x080c, 0x5a79, 0x0040, 0x080c, 0x4b7b, 0x0028, 0x6003,
+	0x0004, 0x2009, 0x39cc, 0x0010, 0x0804, 0x2fdf, 0x2001, 0x0100,
+	0x2004, 0xa082, 0x0005, 0x0258, 0x2001, 0x0170, 0x2004, 0xa084,
+	0x00ff, 0xa086, 0x004c, 0x1118, 0x2091, 0x309d, 0x0817, 0x2091,
+	0x301d, 0x0817, 0x6000, 0xa086, 0x0000, 0x0904, 0x3004, 0x2069,
+	0xb652, 0x7830, 0x6842, 0x7834, 0x6846, 0x6804, 0xd0fc, 0x0118,
+	0x2009, 0x0030, 0x0010, 0x2009, 0x001c, 0x2d00, 0x7a2c, 0x7b28,
+	0x7c3c, 0x7d38, 0x0804, 0x3f00, 0xa006, 0x080c, 0x289c, 0x81ff,
+	0x1904, 0x3004, 0x080c, 0x5b41, 0x1178, 0x2001, 0xb89f, 0x2003,
+	0x0001, 0x2001, 0xb600, 0x2003, 0x0001, 0xa085, 0x0001, 0x080c,
+	0x5b85, 0x080c, 0x5a79, 0x0080, 0x0016, 0x2009, 0xffff, 0x8109,
+	0x0130, 0x2001, 0xb8e2, 0x2004, 0xa086, 0x0000, 0x1dc0, 0x001e,
+	0x080c, 0x4c52, 0x080c, 0x4b7b, 0x0804, 0x2fdf, 0x81ff, 0x1904,
+	0x3004, 0x080c, 0x5b41, 0x1110, 0x0804, 0x3004, 0x6188, 0x81ff,
+	0x0198, 0x703f, 0x0000, 0x2001, 0xbdc0, 0x2009, 0x0040, 0x7a2c,
+	0x7b28, 0x7c3c, 0x7d38, 0x0126, 0x2091, 0x8000, 0x080c, 0x3f00,
+	0x701b, 0x2fdd, 0x012e, 0x0005, 0x703f, 0x0001, 0x00d6, 0x2069,
+	0xbdc0, 0x20a9, 0x0040, 0x20a1, 0xbdc0, 0x2019, 0xffff, 0x43a4,
+	0x6550, 0xa588, 0x2df9, 0x210d, 0xa18c, 0x00ff, 0x216a, 0xa00e,
+	0x2011, 0x0002, 0x2100, 0xa506, 0x01a8, 0x080c, 0x501b, 0x1190,
+	0x6014, 0x821c, 0x0238, 0xa398, 0xbdc0, 0xa085, 0xff00, 0x8007,
+	0x201a, 0x0038, 0xa398, 0xbdc0, 0x2324, 0xa4a4, 0xff00, 0xa405,
+	0x201a, 0x8210, 0x8108, 0xa182, 0x0080, 0x1208, 0x0c18, 0x8201,
+	0x8007, 0x2d0c, 0xa105, 0x206a, 0x00de, 0x20a9, 0x0040, 0x20a1,
+	0xbdc0, 0x2099, 0xbdc0, 0x080c, 0x4bf1, 0x0804, 0x3a33, 0x080c,
+	0x3ee1, 0x0904, 0x3007, 0x00c6, 0x080c, 0x3ebc, 0x00ce, 0x1120,
+	0x2009, 0x0002, 0x0804, 0x3004, 0x2001, 0xb653, 0x2004, 0xd0b4,
+	0x0550, 0x7824, 0xa084, 0xff00, 0xa08e, 0x7e00, 0x0520, 0xa08e,
+	0x7f00, 0x0508, 0xa08e, 0x8000, 0x01f0, 0x6000, 0xd08c, 0x11d8,
+	0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x11a8, 0x6837, 0x0000,
+	0x6838, 0xc0fd, 0x683a, 0x080c, 0x9e96, 0x1120, 0x2009, 0x0003,
+	0x0804, 0x3004, 0x7007, 0x0003, 0x701b, 0x3abf, 0x0005, 0x080c,
+	0x3ee1, 0x0904, 0x3007, 0x20a9, 0x002b, 0x2c98, 0xade8, 0x0002,
+	0x2da0, 0x53a3, 0x20a9, 0x0004, 0xac80, 0x0006, 0x2098, 0xad80,
+	0x0006, 0x20a0, 0x080c, 0x4bf1, 0x20a9, 0x0004, 0xac80, 0x000a,
+	0x2098, 0xad80, 0x000a, 0x20a0, 0x080c, 0x4bf1, 0x2d00, 0x2009,
+	0x002b, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0804, 0x3f00, 0x81ff,
+	0x1904, 0x3004, 0x080c, 0x3ed1, 0x0904, 0x3007, 0x080c, 0x51f8,
+	0x0804, 0x2fdf, 0x81ff, 0x1904, 0x3004, 0x7828, 0xa08a, 0x1000,
+	0x1a04, 0x3007, 0x080c, 0x3ee1, 0x0904, 0x3007, 0x080c, 0x525b,
+	0x0904, 0x3004, 0x2019, 0x0004, 0xa00e, 0x080c, 0x520a, 0x7924,
+	0x810f, 0x7a28, 0x0011, 0x0804, 0x2fdf, 0xa186, 0x00ff, 0x0110,
+	0x0071, 0x0060, 0x2029, 0x007e, 0x2061, 0xb600, 0x6450, 0x2400,
+	0xa506, 0x0110, 0x2508, 0x0019, 0x8529, 0x1ec8, 0x0005, 0x080c,
+	0x501b, 0x1138, 0x2200, 0x8003, 0x800b, 0x810b, 0xa108, 0x080c,
+	0x6a1a, 0x0005, 0x81ff, 0x1904, 0x3004, 0x080c, 0x3ed1, 0x0904,
+	0x3007, 0x080c, 0x50e1, 0x0904, 0x3004, 0x080c, 0x5201, 0x0804,
+	0x2fdf, 0x81ff, 0x1904, 0x3004, 0x080c, 0x3ed1, 0x0904, 0x3007,
+	0x080c, 0x50e1, 0x0904, 0x3004, 0x080c, 0x51ef, 0x0804, 0x2fdf,
+	0x6100, 0x0804, 0x2fdf, 0x080c, 0x3ee1, 0x0904, 0x3007, 0x2001,
+	0xb600, 0x2004, 0xa086, 0x0003, 0x1904, 0x3004, 0x00d6, 0xace8,
+	0x000a, 0x7924, 0xd184, 0x0110, 0xace8, 0x0006, 0x680c, 0x8007,
+	0x783e, 0x6808, 0x8007, 0x783a, 0x6b04, 0x831f, 0x6a00, 0x8217,
+	0x00de, 0x6100, 0xa18c, 0x0200, 0x0804, 0x2fdf, 0x7824, 0xa09c,
+	0x0003, 0xd0b4, 0x1160, 0xa39a, 0x0003, 0x1a04, 0x3004, 0x6250,
+	0xa294, 0x00ff, 0xa084, 0xff00, 0x8007, 0xa206, 0x1150, 0x2001,
+	0xb640, 0x2009, 0x000c, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0804,
+	0x3f00, 0x81ff, 0x1904, 0x3004, 0x080c, 0x3ee1, 0x0904, 0x3007,
+	0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x1904, 0x3004, 0x00c6,
+	0x080c, 0x3ebc, 0x00ce, 0x0904, 0x3004, 0x6837, 0x0000, 0x6838,
+	0xc0fd, 0x683a, 0x080c, 0x9e42, 0x0904, 0x3004, 0x7007, 0x0003,
+	0x701b, 0x3bab, 0x0005, 0x6830, 0xa086, 0x0100, 0x0904, 0x3004,
+	0xad80, 0x000e, 0x2009, 0x000c, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38,
+	0x0804, 0x3f00, 0xa006, 0x080c, 0x289c, 0x7824, 0xa084, 0x00ff,
+	0xa086, 0x00ff, 0x0118, 0x81ff, 0x1904, 0x3004, 0x080c, 0x5b41,
+	0x0110, 0x080c, 0x4c52, 0x7828, 0xa08a, 0x1000, 0x1a04, 0x3007,
+	0x7924, 0xa18c, 0xff00, 0x810f, 0xa186, 0x00ff, 0x0138, 0xa182,
+	0x007f, 0x1a04, 0x3007, 0x2100, 0x080c, 0x2866, 0x0026, 0x00c6,
+	0x0126, 0x2091, 0x8000, 0x2061, 0xb8f4, 0x601b, 0x0000, 0x601f,
+	0x0000, 0x080c, 0x5b41, 0x1178, 0x2001, 0xb89f, 0x2003, 0x0001,
+	0x2001, 0xb600, 0x2003, 0x0001, 0xa085, 0x0001, 0x080c, 0x5b85,
+	0x080c, 0x5a79, 0x0440, 0x2011, 0x0003, 0x080c, 0x80fc, 0x2011,
+	0x0002, 0x080c, 0x8106, 0x080c, 0x7fe0, 0x0036, 0x2019, 0x0000,
+	0x080c, 0x806b, 0x003e, 0x2061, 0x0100, 0x2001, 0xb615, 0x2004,
+	0xa084, 0x00ff, 0x810f, 0xa105, 0x604a, 0x6043, 0x0090, 0x6043,
+	0x0010, 0x2009, 0xb8bf, 0x200b, 0x0000, 0x2009, 0x002d, 0x2011,
+	0x4bb4, 0x080c, 0x6a94, 0x7924, 0xa18c, 0xff00, 0x810f, 0x080c,
+	0x5b41, 0x1110, 0x2009, 0x00ff, 0x7a28, 0x080c, 0x3b0d, 0x012e,
+	0x00ce, 0x002e, 0x0804, 0x2fdf, 0x7924, 0xa18c, 0xff00, 0x810f,
+	0x00c6, 0x080c, 0x4fbf, 0x2c08, 0x00ce, 0x1904, 0x3007, 0x0804,
+	0x2fdf, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x3004, 0x60d4,
+	0xd0ac, 0x1130, 0xd09c, 0x1120, 0x2009, 0x0005, 0x0804, 0x3004,
+	0x080c, 0x3ebc, 0x1120, 0x2009, 0x0002, 0x0804, 0x3004, 0x7924,
+	0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x080c, 0x3efd, 0x701b, 0x3c61,
+	0x0005, 0x2009, 0x0080, 0x080c, 0x501b, 0x1130, 0x6004, 0xa084,
+	0x00ff, 0xa086, 0x0006, 0x0120, 0x2021, 0x400a, 0x0804, 0x2fe1,
+	0x00d6, 0xade8, 0x000d, 0x6900, 0x6a08, 0x6b0c, 0x6c10, 0x6d14,
+	0x6e18, 0x6820, 0xa0be, 0x0100, 0x0904, 0x3cd8, 0xa0be, 0x0112,
+	0x0904, 0x3cd8, 0xa0be, 0x0113, 0x0904, 0x3cd8, 0xa0be, 0x0114,
+	0x0904, 0x3cd8, 0xa0be, 0x0117, 0x0904, 0x3cd8, 0xa0be, 0x011a,
+	0x0904, 0x3cd8, 0xa0be, 0x011c, 0x0904, 0x3cd8, 0xa0be, 0x0121,
+	0x05b0, 0xa0be, 0x0131, 0x0598, 0xa0be, 0x0171, 0x05c8, 0xa0be,
+	0x0173, 0x05b0, 0xa0be, 0x01a1, 0x1120, 0x6830, 0x8007, 0x6832,
+	0x04a8, 0xa0be, 0x0212, 0x0540, 0xa0be, 0x0213, 0x0528, 0xa0be,
+	0x0214, 0x01b0, 0xa0be, 0x0217, 0x0168, 0xa0be, 0x021a, 0x1120,
+	0x6838, 0x8007, 0x683a, 0x00e0, 0xa0be, 0x0300, 0x01c8, 0x00de,
+	0x0804, 0x3007, 0xad80, 0x0010, 0x20a9, 0x0007, 0x080c, 0x3d1e,
+	0xad80, 0x000e, 0x20a9, 0x0001, 0x080c, 0x3d1e, 0x0048, 0xad80,
+	0x000c, 0x080c, 0x3d2c, 0x0050, 0xad80, 0x000e, 0x080c, 0x3d2c,
+	0xad80, 0x000c, 0x20a9, 0x0001, 0x080c, 0x3d1e, 0x00c6, 0x080c,
+	0x3ebc, 0x0568, 0x6838, 0xc0fd, 0x683a, 0x6837, 0x0119, 0x6853,
+	0x0000, 0x684f, 0x0020, 0x685b, 0x0001, 0x810b, 0x697e, 0x6883,
+	0x0000, 0x6a86, 0x6b8a, 0x6c8e, 0x6d92, 0x6996, 0x689b, 0x0000,
+	0x00ce, 0x00de, 0x6837, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x6823,
+	0x0000, 0x6804, 0x2068, 0x080c, 0x9e5e, 0x1120, 0x2009, 0x0003,
+	0x0804, 0x3004, 0x7007, 0x0003, 0x701b, 0x3d15, 0x0005, 0x00ce,
+	0x00de, 0x2009, 0x0002, 0x0804, 0x3004, 0x6820, 0xa086, 0x8001,
+	0x1904, 0x2fdf, 0x2009, 0x0004, 0x0804, 0x3004, 0x0016, 0x2008,
+	0x2044, 0x8000, 0x204c, 0x8000, 0x290a, 0x8108, 0x280a, 0x8108,
+	0x1f04, 0x3d20, 0x001e, 0x0005, 0x0016, 0x00a6, 0x00b6, 0x2008,
+	0x2044, 0x8000, 0x204c, 0x8000, 0x2054, 0x8000, 0x205c, 0x2b0a,
+	0x8108, 0x2a0a, 0x8108, 0x290a, 0x8108, 0x280a, 0x00be, 0x00ae,
+	0x001e, 0x0005, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x3004,
+	0x60d4, 0xd0ac, 0x1130, 0xd09c, 0x1120, 0x2009, 0x0005, 0x0804,
+	0x3004, 0x7924, 0x2140, 0xa18c, 0xff00, 0x810f, 0x60d4, 0xd0ac,
+	0x1120, 0xa182, 0x0080, 0x0a04, 0x3007, 0xa182, 0x00ff, 0x1a04,
+	0x3007, 0x7a2c, 0x7b28, 0x6070, 0xa306, 0x1140, 0x6074, 0xa24e,
+	0x0904, 0x3007, 0xa9cc, 0xff00, 0x0904, 0x3007, 0x0126, 0x2091,
+	0x8000, 0x00c6, 0x080c, 0x3e0c, 0x2c68, 0x00ce, 0x0538, 0xa0c6,
+	0x4000, 0x1178, 0x00c6, 0x0006, 0x2d60, 0xa00e, 0x080c, 0x52bc,
 	0x1108, 0xc185, 0x6000, 0xd0bc, 0x0108, 0xc18d, 0x000e, 0x00ce,
 	0x0088, 0xa0c6, 0x4007, 0x1110, 0x2408, 0x0060, 0xa0c6, 0x4008,
 	0x1118, 0x2708, 0x2610, 0x0030, 0xa0c6, 0x4009, 0x1108, 0x0010,
-	0x2001, 0x4006, 0x2020, 0x0804, 0x2fac, 0x2d00, 0x7022, 0x0016,
-	0x00b6, 0x00c6, 0x00e6, 0x2c70, 0x080c, 0x85c7, 0x05d8, 0x2d00,
-	0x601a, 0x080c, 0xa027, 0x2e58, 0x00ee, 0x00e6, 0x00c6, 0x080c,
-	0x3e75, 0x00ce, 0x2b70, 0x1150, 0x080c, 0x861d, 0x00ee, 0x00ce,
-	0x00be, 0x001e, 0x2009, 0x0002, 0x0804, 0x2fcf, 0x6837, 0x0000,
-	0x683b, 0x0000, 0x2d00, 0x6012, 0x6833, 0x0000, 0x6838, 0xc0fd,
-	0xd88c, 0x0108, 0xc0f5, 0x683a, 0x0126, 0x2091, 0x8000, 0x080c,
-	0x2c9c, 0x012e, 0x601f, 0x0001, 0x2001, 0x0000, 0x080c, 0x4eeb,
-	0x2001, 0x0002, 0x080c, 0x4efd, 0x2009, 0x0002, 0x080c, 0x864c,
-	0xa085, 0x0001, 0x00ee, 0x00ce, 0x00be, 0x001e, 0x1120, 0x2009,
-	0x0003, 0x0804, 0x2fcf, 0x7007, 0x0003, 0x701b, 0x3da8, 0x0005,
-	0x6830, 0xa086, 0x0100, 0x7020, 0x2060, 0x1138, 0x2009, 0x0004,
-	0x6204, 0xa294, 0x00ff, 0x0804, 0x2fcf, 0x2009, 0x0000, 0x6838,
-	0xd0f4, 0x1904, 0x2faa, 0x080c, 0x524a, 0x1108, 0xc185, 0x6000,
-	0xd0bc, 0x0108, 0xc18d, 0x0804, 0x2faa, 0x00e6, 0x00d6, 0xa02e,
-	0x2001, 0xb535, 0x2004, 0xd0ac, 0x0130, 0xa026, 0x20a9, 0x00ff,
-	0x2071, 0xb635, 0x0030, 0x2021, 0x0080, 0x20a9, 0x007f, 0x2071,
-	0xb6b5, 0x2e04, 0xa005, 0x1130, 0x2100, 0xa406, 0x1570, 0x2428,
-	0xc5fd, 0x0458, 0x2068, 0x6f10, 0x2700, 0xa306, 0x11b0, 0x6e14,
-	0x2600, 0xa206, 0x1190, 0x2400, 0xa106, 0x1160, 0x2d60, 0xd884,
-	0x0568, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x1538, 0x2001,
-	0x4000, 0x0428, 0x2001, 0x4007, 0x0410, 0x2400, 0xa106, 0x1168,
-	0x6e14, 0x87ff, 0x1138, 0x86ff, 0x09d0, 0x2001, 0xb535, 0x2004,
-	0xd0ac, 0x19a8, 0x2001, 0x4008, 0x0090, 0x8420, 0x8e70, 0x1f04,
-	0x3dd9, 0x85ff, 0x1130, 0x2001, 0x4009, 0x0048, 0x2001, 0x0001,
-	0x0030, 0x080c, 0x4f4d, 0x1dd0, 0x6312, 0x6216, 0xa006, 0xa005,
-	0x00de, 0x00ee, 0x0005, 0x81ff, 0x1904, 0x2fcf, 0x080c, 0x3e75,
-	0x0904, 0x2fcf, 0x6837, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x7824,
-	0xa005, 0x0904, 0x2fd2, 0xa096, 0x00ff, 0x0120, 0xa092, 0x0004,
-	0x1a04, 0x2fd2, 0x2010, 0x2d18, 0x080c, 0x2c4f, 0x0904, 0x2fcf,
-	0x7007, 0x0003, 0x701b, 0x3e45, 0x0005, 0x6830, 0xa086, 0x0100,
-	0x0904, 0x2fcf, 0x0804, 0x2faa, 0x7924, 0xa18c, 0xff00, 0x810f,
-	0x60d4, 0xd0ac, 0x1120, 0xa182, 0x0080, 0x0a04, 0x2fd2, 0xa182,
-	0x00ff, 0x1a04, 0x2fd2, 0x0126, 0x2091, 0x8000, 0x080c, 0x9c8a,
-	0x1188, 0xa190, 0xb635, 0x2204, 0xa065, 0x0160, 0x080c, 0x4c0b,
-	0x2001, 0xb535, 0x2004, 0xd0ac, 0x0110, 0x6017, 0x0000, 0x012e,
-	0x0804, 0x2faa, 0x012e, 0x0804, 0x2fcf, 0x080c, 0x15f8, 0x0188,
-	0xa006, 0x6802, 0x7010, 0xa005, 0x1120, 0x2d00, 0x7012, 0x7016,
-	0x0030, 0x7014, 0x6802, 0x2060, 0x2d00, 0x6006, 0x7016, 0xad80,
-	0x000d, 0x0005, 0x7924, 0x810f, 0xa18c, 0x00ff, 0x080c, 0x4fa9,
-	0x1130, 0x7e28, 0xa684, 0x3fff, 0xa082, 0x4000, 0x0208, 0xa066,
-	0x8cff, 0x0005, 0x7e24, 0x860f, 0xa18c, 0x00ff, 0x080c, 0x4fa9,
-	0x1128, 0xa6b4, 0x00ff, 0xa682, 0x4000, 0x0208, 0xa066, 0x8cff,
-	0x0005, 0x0016, 0x7110, 0x81ff, 0x0128, 0x2168, 0x6904, 0x080c,
-	0x160f, 0x0cc8, 0x7112, 0x7116, 0x001e, 0x0005, 0x2031, 0x0001,
-	0x0010, 0x2031, 0x0000, 0x2061, 0xb5d2, 0x6606, 0x6112, 0x600e,
-	0x6226, 0x632a, 0x642e, 0x6532, 0x2c10, 0x080c, 0x1643, 0x7007,
-	0x0002, 0x701b, 0x2faa, 0x0005, 0x00f6, 0x0126, 0x2091, 0x8000,
-	0x2079, 0x0000, 0x2001, 0xb590, 0x2004, 0xa005, 0x1168, 0x0e04,
-	0x3ee4, 0x7818, 0xd084, 0x1140, 0x7a22, 0x7b26, 0x7c2a, 0x781b,
-	0x0001, 0x2091, 0x4080, 0x0408, 0x0016, 0x00c6, 0x00e6, 0x2071,
-	0xb582, 0x7138, 0xa182, 0x0010, 0x0218, 0x7030, 0x2060, 0x0078,
-	0x7030, 0xa0e0, 0x0004, 0xac82, 0xb5d2, 0x0210, 0x2061, 0xb592,
-	0x2c00, 0x7032, 0x81ff, 0x1108, 0x7036, 0x8108, 0x713a, 0x2262,
-	0x6306, 0x640a, 0x00ee, 0x00ce, 0x001e, 0x012e, 0x00fe, 0x0005,
-	0x00e6, 0x2071, 0xb582, 0x7038, 0xa005, 0x0570, 0x0126, 0x2091,
-	0x8000, 0x0e04, 0x3f3b, 0x00f6, 0x2079, 0x0000, 0x7818, 0xd084,
-	0x1508, 0x00c6, 0x7034, 0x2060, 0x2c04, 0x7822, 0x6004, 0x7826,
-	0x6008, 0x782a, 0x781b, 0x0001, 0x2091, 0x4080, 0x7038, 0x8001,
-	0x703a, 0xa005, 0x1130, 0x7033, 0xb592, 0x7037, 0xb592, 0x00ce,
-	0x0048, 0xac80, 0x0004, 0xa0fa, 0xb5d2, 0x0210, 0x2001, 0xb592,
-	0x7036, 0x00ce, 0x00fe, 0x012e, 0x00ee, 0x0005, 0x0026, 0x2001,
-	0xb553, 0x2004, 0xd0c4, 0x0120, 0x2011, 0x8014, 0x080c, 0x3ecc,
-	0x002e, 0x0005, 0x81ff, 0x1904, 0x2fcf, 0x0126, 0x2091, 0x8000,
-	0x6030, 0xc08d, 0xc085, 0xc0ac, 0x6032, 0x080c, 0x5acf, 0x1178,
-	0x2001, 0xb79f, 0x2003, 0x0001, 0x2001, 0xb500, 0x2003, 0x0001,
-	0xa085, 0x0001, 0x080c, 0x5b13, 0x080c, 0x5a07, 0x0010, 0x080c,
-	0x4b1f, 0x012e, 0x0804, 0x2faa, 0x7824, 0x2008, 0xa18c, 0xfffd,
-	0x1128, 0x61e0, 0xa10d, 0x61e2, 0x0804, 0x2faa, 0x0804, 0x2fd2,
-	0x81ff, 0x1904, 0x2fcf, 0x6000, 0xa086, 0x0003, 0x1904, 0x2fcf,
-	0x2001, 0xb553, 0x2004, 0xd0ac, 0x1904, 0x2fcf, 0x080c, 0x3e9a,
-	0x0904, 0x2fd2, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x1120,
-	0x7828, 0xa005, 0x0904, 0x2faa, 0x00c6, 0x080c, 0x3e75, 0x00ce,
-	0x0904, 0x2fcf, 0x6837, 0x0000, 0x6833, 0x0000, 0x6838, 0xc0fd,
-	0x683a, 0x080c, 0x9e6b, 0x0904, 0x2fcf, 0x7007, 0x0003, 0x701b,
-	0x3faa, 0x0005, 0x6830, 0xa086, 0x0100, 0x0904, 0x2fcf, 0x0804,
-	0x2faa, 0x2001, 0xb500, 0x2004, 0xa086, 0x0003, 0x1904, 0x2fcf,
-	0x7f24, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x080c, 0x3e75, 0x0904,
-	0x2fcf, 0x2009, 0x0000, 0x2031, 0x0000, 0x7023, 0x0000, 0x702f,
-	0x0000, 0xad80, 0x0005, 0x7026, 0x20a0, 0x080c, 0x4fa9, 0x1904,
-	0x4024, 0x6004, 0xa0c4, 0x00ff, 0xa8c6, 0x0006, 0x0130, 0xa0c4,
-	0xff00, 0xa8c6, 0x0600, 0x1904, 0x4024, 0x2001, 0xb553, 0x2004,
-	0xd0ac, 0x1128, 0x080c, 0x524a, 0x1110, 0xd79c, 0x05e8, 0xd794,
-	0x1110, 0xd784, 0x0158, 0xac80, 0x0006, 0x2098, 0x3400, 0x20a9,
-	0x0004, 0x53a3, 0x080c, 0x3ce7, 0xd794, 0x0148, 0xac80, 0x000a,
-	0x2098, 0x3400, 0x20a9, 0x0004, 0x53a3, 0x080c, 0x3ce7, 0x21a2,
-	0xd794, 0x01d8, 0xac80, 0x0000, 0x2098, 0x94a0, 0x20a9, 0x0002,
-	0x53a3, 0xac80, 0x0003, 0x20a6, 0x94a0, 0xac80, 0x0004, 0x2098,
-	0x3400, 0x20a9, 0x0002, 0x53a3, 0x080c, 0x3cd9, 0xac80, 0x0026,
-	0x2098, 0x20a9, 0x0002, 0x53a3, 0x0008, 0x94a0, 0xd794, 0x0110,
-	0xa6b0, 0x000b, 0xa6b0, 0x0005, 0x8108, 0x2001, 0xb535, 0x2004,
-	0xd0ac, 0x0118, 0xa186, 0x0100, 0x0040, 0xd78c, 0x0120, 0xa186,
-	0x0100, 0x0170, 0x0018, 0xa186, 0x007e, 0x0150, 0xd794, 0x0118,
-	0xa686, 0x0020, 0x0010, 0xa686, 0x0028, 0x0150, 0x0804, 0x3fcd,
-	0x86ff, 0x1120, 0x7120, 0x810b, 0x0804, 0x2faa, 0x702f, 0x0001,
-	0x711e, 0x7020, 0xa600, 0x7022, 0x772a, 0x2061, 0xb5d2, 0x6007,
-	0x0000, 0x6612, 0x7024, 0x600e, 0x6226, 0x632a, 0x642e, 0x6532,
-	0x2c10, 0x080c, 0x1643, 0x7007, 0x0002, 0x701b, 0x4060, 0x0005,
-	0x702c, 0xa005, 0x1170, 0x711c, 0x7024, 0x20a0, 0x7728, 0x2031,
-	0x0000, 0x2061, 0xb5d2, 0x6224, 0x6328, 0x642c, 0x6530, 0x0804,
-	0x3fcd, 0x7120, 0x810b, 0x0804, 0x2faa, 0x2029, 0x007e, 0x7924,
-	0x7a28, 0x7b2c, 0x7c38, 0xa184, 0xff00, 0x8007, 0xa0e2, 0x0020,
-	0x0a04, 0x2fd2, 0xa502, 0x0a04, 0x2fd2, 0xa184, 0x00ff, 0xa0e2,
-	0x0020, 0x0a04, 0x2fd2, 0xa502, 0x0a04, 0x2fd2, 0xa284, 0xff00,
-	0x8007, 0xa0e2, 0x0020, 0x0a04, 0x2fd2, 0xa502, 0x0a04, 0x2fd2,
-	0xa284, 0x00ff, 0xa0e2, 0x0020, 0x0a04, 0x2fd2, 0xa502, 0x0a04,
-	0x2fd2, 0xa384, 0xff00, 0x8007, 0xa0e2, 0x0020, 0x0a04, 0x2fd2,
-	0xa502, 0x0a04, 0x2fd2, 0xa384, 0x00ff, 0xa0e2, 0x0020, 0x0a04,
-	0x2fd2, 0xa502, 0x0a04, 0x2fd2, 0xa484, 0xff00, 0x8007, 0xa0e2,
-	0x0020, 0x0a04, 0x2fd2, 0xa502, 0x0a04, 0x2fd2, 0xa484, 0x00ff,
-	0xa0e2, 0x0020, 0x0a04, 0x2fd2, 0xa502, 0x0a04, 0x2fd2, 0x2061,
-	0xb7b9, 0x6102, 0x6206, 0x630a, 0x640e, 0x0804, 0x2faa, 0x0006,
-	0x2001, 0xb553, 0x2004, 0xd0cc, 0x000e, 0x0005, 0x0006, 0x2001,
-	0xb572, 0x2004, 0xd0bc, 0x000e, 0x0005, 0x6168, 0x7a24, 0x6300,
-	0x82ff, 0x1118, 0x7926, 0x0804, 0x2faa, 0x83ff, 0x1904, 0x2fd2,
-	0x2001, 0xfff0, 0xa200, 0x1a04, 0x2fd2, 0x2019, 0xffff, 0x606c,
-	0xa302, 0xa200, 0x0a04, 0x2fd2, 0x7926, 0x626a, 0x0804, 0x2faa,
-	0x2001, 0xb500, 0x2004, 0xa086, 0x0003, 0x1904, 0x2fcf, 0x7c28,
-	0x7d24, 0x7e38, 0x7f2c, 0x080c, 0x3e75, 0x0904, 0x2fcf, 0x2009,
-	0x0000, 0x2019, 0x0000, 0x7023, 0x0000, 0x702f, 0x0000, 0xad80,
-	0x0003, 0x7026, 0x20a0, 0xa1e0, 0xb635, 0x2c64, 0x8cff, 0x01b8,
-	0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x0130, 0x6004, 0xa084,
-	0xff00, 0xa086, 0x0600, 0x1158, 0x6014, 0x20a2, 0x94a0, 0x6010,
-	0x8007, 0xa105, 0x8007, 0x20a2, 0x94a0, 0xa398, 0x0002, 0x8108,
-	0xa182, 0x00ff, 0x0120, 0xa386, 0x002a, 0x0148, 0x08e0, 0x83ff,
-	0x1120, 0x7120, 0x810c, 0x0804, 0x2faa, 0x702f, 0x0001, 0x711e,
-	0x7020, 0xa300, 0x7022, 0x2061, 0xb5d2, 0x6007, 0x0000, 0x6312,
-	0x7024, 0x600e, 0x6426, 0x652a, 0x662e, 0x6732, 0x2c10, 0x080c,
-	0x1643, 0x7007, 0x0002, 0x701b, 0x4156, 0x0005, 0x702c, 0xa005,
-	0x1168, 0x711c, 0x7024, 0x20a0, 0x2019, 0x0000, 0x2061, 0xb5d2,
-	0x6424, 0x6528, 0x662c, 0x6730, 0x0804, 0x4113, 0x7120, 0x810c,
-	0x0804, 0x2faa, 0x81ff, 0x1904, 0x2fcf, 0x60d4, 0xd0ac, 0x1118,
-	0xd09c, 0x0904, 0x2fcf, 0x080c, 0x3e75, 0x0904, 0x2fcf, 0x7924,
-	0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x080c, 0x3eb6, 0x701b, 0x4181,
-	0x0005, 0x00d6, 0xade8, 0x000d, 0x6828, 0xa0be, 0x7000, 0x0148,
-	0xa0be, 0x7100, 0x0130, 0xa0be, 0x7200, 0x0118, 0x00de, 0x0804,
-	0x2fd2, 0x6820, 0x6924, 0x080c, 0x281d, 0x1510, 0x080c, 0x4f4d,
-	0x11f8, 0x7122, 0x6612, 0x6516, 0x6e18, 0x00c6, 0x080c, 0x3e75,
-	0x01b8, 0x080c, 0x3e75, 0x01a0, 0x00ce, 0x00de, 0x6837, 0x0000,
-	0x6838, 0xc0fd, 0x683a, 0x6823, 0x0000, 0x6804, 0x2068, 0x080c,
-	0x9dbe, 0x0904, 0x2fcf, 0x7007, 0x0003, 0x701b, 0x41bb, 0x0005,
-	0x00de, 0x0804, 0x2fcf, 0x7120, 0x080c, 0x2d97, 0x6820, 0xa086,
-	0x8001, 0x0904, 0x2fcf, 0x2d00, 0x701e, 0x6804, 0xa080, 0x0002,
-	0x0006, 0x20a9, 0x002a, 0x2098, 0x20a0, 0x080c, 0x4b8f, 0x000e,
-	0xade8, 0x000d, 0x6a08, 0x6b0c, 0x6c10, 0x6d14, 0x2061, 0xb5d2,
-	0x6007, 0x0000, 0x6e00, 0x6f28, 0xa7c6, 0x7000, 0x1108, 0x0018,
-	0xa7c6, 0x7100, 0x1140, 0xa6c2, 0x0004, 0x0a04, 0x2fd2, 0x2009,
-	0x0004, 0x0804, 0x3eb9, 0xa7c6, 0x7200, 0x1904, 0x2fd2, 0xa6c2,
-	0x0054, 0x0a04, 0x2fd2, 0x600e, 0x6013, 0x002a, 0x6226, 0x632a,
-	0x642e, 0x6532, 0x2c10, 0x080c, 0x1643, 0x7007, 0x0002, 0x701b,
-	0x4202, 0x0005, 0x701c, 0x2068, 0x6804, 0xa080, 0x0001, 0x2004,
-	0xa080, 0x0002, 0x0006, 0x20a9, 0x002a, 0x2098, 0x20a0, 0x080c,
-	0x4b8f, 0x000e, 0x2009, 0x002a, 0x2061, 0xb5d2, 0x6224, 0x6328,
-	0x642c, 0x6530, 0x0804, 0x3eb9, 0x81ff, 0x1904, 0x2fcf, 0x792c,
-	0x2001, 0xb7a0, 0x2102, 0x080c, 0x3e8a, 0x0904, 0x2fd2, 0x080c,
-	0x506f, 0x0904, 0x2fcf, 0x0126, 0x2091, 0x8000, 0x080c, 0x51a1,
-	0x012e, 0x0804, 0x2faa, 0x7824, 0xd08c, 0x1118, 0xd084, 0x0904,
-	0x3a46, 0x080c, 0x3e9a, 0x0904, 0x2fd2, 0x00c6, 0x080c, 0x3e75,
-	0x00ce, 0x1120, 0x2009, 0x0002, 0x0804, 0x2fcf, 0x6004, 0xa084,
-	0x00ff, 0xa086, 0x0006, 0x0128, 0xa08e, 0x0004, 0x0110, 0xa08e,
-	0x0005, 0x15b8, 0x7824, 0xd08c, 0x0120, 0x6000, 0xc08c, 0x6002,
-	0x0030, 0x2001, 0xb553, 0x2004, 0xd0b4, 0x0904, 0x3a82, 0x7824,
-	0xa084, 0xff00, 0xa08e, 0x7e00, 0x0904, 0x3a82, 0xa08e, 0x7f00,
-	0x0904, 0x3a82, 0xa08e, 0x8000, 0x0904, 0x3a82, 0x6000, 0xd08c,
-	0x1904, 0x3a82, 0x6837, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x080c,
-	0x9dda, 0x1120, 0x2009, 0x0003, 0x0804, 0x2fcf, 0x7007, 0x0003,
-	0x701b, 0x4283, 0x0005, 0x080c, 0x3e9a, 0x0904, 0x2fd2, 0x0804,
-	0x3a82, 0x2009, 0xb531, 0x210c, 0x81ff, 0x0120, 0x2009, 0x0001,
-	0x0804, 0x2fcf, 0x2001, 0xb500, 0x2004, 0xa086, 0x0003, 0x0120,
-	0x2009, 0x0007, 0x0804, 0x2fcf, 0x2001, 0xb553, 0x2004, 0xd0ac,
-	0x0120, 0x2009, 0x0008, 0x0804, 0x2fcf, 0x609c, 0xd0a4, 0x1118,
-	0xd0ac, 0x1904, 0x3a82, 0x6837, 0x0000, 0x6833, 0x0000, 0x6838,
-	0xc0fd, 0x683a, 0x080c, 0x9e6b, 0x1120, 0x2009, 0x0003, 0x0804,
-	0x2fcf, 0x7007, 0x0003, 0x701b, 0x42be, 0x0005, 0x6830, 0xa086,
-	0x0100, 0x1120, 0x2009, 0x0004, 0x0804, 0x2fcf, 0x080c, 0x3e9a,
-	0x0904, 0x2fd2, 0x0804, 0x4252, 0x81ff, 0x2009, 0x0001, 0x1904,
-	0x2fcf, 0x6000, 0xa086, 0x0003, 0x2009, 0x0007, 0x1904, 0x2fcf,
-	0x2001, 0xb553, 0x2004, 0xd0ac, 0x2009, 0x0008, 0x1904, 0x2fcf,
-	0x080c, 0x3e9a, 0x0904, 0x2fd2, 0x6004, 0xa084, 0x00ff, 0xa086,
-	0x0006, 0x2009, 0x0009, 0x1904, 0x2fcf, 0x00c6, 0x080c, 0x3e75,
-	0x00ce, 0x2009, 0x0002, 0x0904, 0x2fcf, 0x6837, 0x0000, 0x6833,
-	0x0000, 0x6838, 0xc0fd, 0x683a, 0x7928, 0xa194, 0xff00, 0xa18c,
-	0x00ff, 0xa006, 0x82ff, 0x1128, 0xc0ed, 0x6952, 0x792c, 0x6956,
-	0x0048, 0xa28e, 0x0100, 0x1904, 0x2fd2, 0xc0e5, 0x6853, 0x0000,
-	0x6857, 0x0000, 0x683e, 0x080c, 0xa028, 0x2009, 0x0003, 0x0904,
-	0x2fcf, 0x7007, 0x0003, 0x701b, 0x431e, 0x0005, 0x6830, 0xa086,
-	0x0100, 0x2009, 0x0004, 0x0904, 0x2fcf, 0x0804, 0x2faa, 0x81ff,
-	0x2009, 0x0001, 0x1904, 0x2fcf, 0x6000, 0xa086, 0x0003, 0x2009,
-	0x0007, 0x1904, 0x2fcf, 0x080c, 0x3e9a, 0x0904, 0x2fd2, 0x6004,
-	0xa084, 0x00ff, 0xa086, 0x0006, 0x2009, 0x0009, 0x1904, 0x2fcf,
-	0x00c6, 0x080c, 0x3e75, 0x00ce, 0x2009, 0x0002, 0x0904, 0x2fcf,
-	0xad80, 0x000f, 0x2009, 0x0008, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38,
-	0x080c, 0x3eb6, 0x701b, 0x4355, 0x0005, 0x00d6, 0xade8, 0x000f,
-	0x6800, 0xa086, 0x0500, 0x1140, 0x6804, 0xa005, 0x1128, 0x6808,
-	0xa084, 0xff00, 0x1108, 0x0018, 0x00de, 0x1904, 0x2fd2, 0x00de,
-	0x6837, 0x0000, 0x6833, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x00c6,
-	0x080c, 0x3e9a, 0x1118, 0x00ce, 0x0804, 0x2fd2, 0x080c, 0xa077,
-	0x2009, 0x0003, 0x00ce, 0x0904, 0x2fcf, 0x7007, 0x0003, 0x701b,
-	0x4382, 0x0005, 0x6830, 0xa086, 0x0100, 0x2009, 0x0004, 0x0904,
-	0x2fcf, 0x0804, 0x2faa, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804,
-	0x2fcf, 0x6000, 0xa086, 0x0003, 0x0120, 0x2009, 0x0007, 0x0804,
-	0x2fcf, 0x7e24, 0x860f, 0xa18c, 0x00ff, 0xa6b4, 0x00ff, 0x080c,
-	0x4fa9, 0x1904, 0x2fd2, 0xa186, 0x007f, 0x0150, 0x6004, 0xa084,
-	0x00ff, 0xa086, 0x0006, 0x0120, 0x2009, 0x0009, 0x0804, 0x2fcf,
-	0x00c6, 0x080c, 0x3e75, 0x00ce, 0x1120, 0x2009, 0x0002, 0x0804,
-	0x2fcf, 0x6837, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x2001, 0x0100,
-	0x8007, 0x680a, 0x080c, 0x9df5, 0x1120, 0x2009, 0x0003, 0x0804,
-	0x2fcf, 0x7007, 0x0003, 0x701b, 0x43ce, 0x0005, 0x6808, 0x8007,
-	0xa086, 0x0100, 0x1120, 0x2009, 0x0004, 0x0804, 0x2fcf, 0x68b0,
-	0x6836, 0x6810, 0x8007, 0xa084, 0x00ff, 0x800c, 0x6814, 0x8007,
-	0xa084, 0x00ff, 0x8004, 0xa080, 0x0002, 0xa108, 0xad80, 0x0004,
-	0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0804, 0x3eb9, 0x080c, 0x3e75,
-	0x1120, 0x2009, 0x0002, 0x0804, 0x2fcf, 0x7924, 0xa194, 0xff00,
-	0xa18c, 0x00ff, 0x8217, 0x82ff, 0x0110, 0x0804, 0x2fd2, 0x2009,
-	0x001a, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x080c, 0x3eb6, 0x701b,
-	0x440a, 0x0005, 0x2001, 0xb52a, 0x2003, 0x0001, 0xad80, 0x000d,
-	0x2098, 0x20a9, 0x001a, 0x20a1, 0xb7c6, 0x53a3, 0x0804, 0x2faa,
-	0x080c, 0x3e75, 0x1120, 0x2009, 0x0002, 0x0804, 0x2fcf, 0x7924,
-	0xa194, 0xff00, 0xa18c, 0x00ff, 0x8217, 0x82ff, 0x0110, 0x0804,
-	0x2fd2, 0x2099, 0xb7c6, 0x20a0, 0x20a9, 0x001a, 0x53a3, 0x2009,
-	0x001a, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0804, 0x3eb9, 0x7824,
-	0xa08a, 0x1000, 0x1a04, 0x2fd2, 0x0126, 0x2091, 0x8000, 0x8003,
-	0x800b, 0x810b, 0xa108, 0x00c6, 0x2061, 0xb7f3, 0x6142, 0x00ce,
-	0x012e, 0x0804, 0x2faa, 0x00c6, 0x080c, 0x5acf, 0x1188, 0x2001,
-	0xb79f, 0x2003, 0x0001, 0x2001, 0xb500, 0x2003, 0x0001, 0xa085,
-	0x0001, 0x080c, 0x5b13, 0x080c, 0x5a07, 0x080c, 0x1515, 0x0038,
-	0x2061, 0xb500, 0x6030, 0xc09d, 0x6032, 0x080c, 0x4b1f, 0x00ce,
-	0x0005, 0x0126, 0x2091, 0x8000, 0x00c6, 0x2061, 0xb7f3, 0x7924,
-	0x6152, 0x614e, 0x6057, 0x0000, 0x604b, 0x0009, 0x7838, 0x606a,
-	0x783c, 0x6066, 0x7828, 0x6062, 0x782c, 0x605e, 0x2061, 0xb7a1,
-	0x2001, 0xb808, 0x600e, 0x6013, 0x0001, 0x6017, 0x0002, 0x6007,
-	0x0000, 0x6037, 0x0000, 0x00ce, 0x012e, 0x0804, 0x2faa, 0x0126,
-	0x00c6, 0x00e6, 0x2061, 0x0100, 0x2071, 0xb500, 0x6044, 0xd0a4,
-	0x11b0, 0xd084, 0x0118, 0x080c, 0x4606, 0x0068, 0xd08c, 0x0118,
-	0x080c, 0x4527, 0x0040, 0xd094, 0x0118, 0x080c, 0x44f8, 0x0018,
-	0xd09c, 0x0108, 0x0061, 0x00ee, 0x00ce, 0x012e, 0x0005, 0x0016,
-	0x6128, 0xd19c, 0x1110, 0xc19d, 0x612a, 0x001e, 0x0ca0, 0x624c,
-	0xa286, 0xf0f0, 0x1150, 0x6048, 0xa086, 0xf0f0, 0x0130, 0x624a,
-	0x6043, 0x0090, 0x6043, 0x0010, 0x0490, 0xa294, 0xff00, 0xa296,
-	0xf700, 0x0178, 0x7134, 0xd1a4, 0x1160, 0x6240, 0xa295, 0x0100,
-	0x6242, 0xa294, 0x0010, 0x0128, 0x2009, 0x00f7, 0x080c, 0x4baf,
-	0x00f0, 0x6040, 0xa084, 0x0010, 0xa085, 0x0140, 0x6042, 0x6043,
-	0x0000, 0x707b, 0x0000, 0x7097, 0x0001, 0x70bb, 0x0000, 0x70d7,
-	0x0000, 0x2009, 0xbcc0, 0x200b, 0x0000, 0x708b, 0x0000, 0x707f,
-	0x000a, 0x2009, 0x000a, 0x2011, 0x4ad5, 0x080c, 0x6a22, 0x0005,
-	0x0156, 0x2001, 0xb574, 0x2004, 0xd08c, 0x0110, 0x7053, 0xffff,
-	0x707c, 0xa005, 0x1510, 0x2011, 0x4ad5, 0x080c, 0x699c, 0x6040,
-	0xa094, 0x0010, 0xa285, 0x0020, 0x6042, 0x20a9, 0x00c8, 0x6044,
-	0xd08c, 0x1168, 0x1f04, 0x450f, 0x6242, 0x708f, 0x0000, 0x6040,
-	0xa094, 0x0010, 0xa285, 0x0080, 0x6042, 0x6242, 0x0030, 0x6242,
-	0x708f, 0x0000, 0x7083, 0x0000, 0x0000, 0x015e, 0x0005, 0x7080,
-	0xa08a, 0x0003, 0x1210, 0x0023, 0x0010, 0x080c, 0x1515, 0x0005,
-	0x4533, 0x4583, 0x4605, 0x00f6, 0x7083, 0x0001, 0x20e1, 0xa000,
-	0xe000, 0x20e1, 0x8700, 0x080c, 0x2470, 0x20e1, 0x9080, 0x20e1,
-	0x4000, 0x2079, 0xbb00, 0x207b, 0x2200, 0x7807, 0x00ef, 0x780b,
-	0x0000, 0x780f, 0x00ef, 0x7813, 0x0138, 0x7817, 0x0000, 0x781b,
-	0x0000, 0x781f, 0x0000, 0x7823, 0xffff, 0x7827, 0xffff, 0x782b,
-	0x0000, 0x782f, 0x0000, 0x2079, 0xbb0c, 0x207b, 0x1101, 0x7807,
-	0x0000, 0x2099, 0xb505, 0x20a1, 0xbb0e, 0x20a9, 0x0004, 0x53a3,
-	0x2079, 0xbb12, 0x207b, 0x0000, 0x7807, 0x0000, 0x2099, 0xbb00,
-	0x20a1, 0x020b, 0x20a9, 0x0014, 0x53a6, 0x60c3, 0x000c, 0x600f,
-	0x0000, 0x080c, 0x4b06, 0x00fe, 0x7087, 0x0000, 0x6043, 0x0008,
-	0x6043, 0x0000, 0x0005, 0x00d6, 0x7084, 0x7087, 0x0000, 0xa025,
-	0x0904, 0x45ed, 0x6020, 0xd0b4, 0x1904, 0x45eb, 0x7194, 0x81ff,
-	0x0904, 0x45db, 0xa486, 0x000c, 0x1904, 0x45e6, 0xa480, 0x0018,
-	0x8004, 0x20a8, 0x2011, 0xbb80, 0x2019, 0xbb00, 0x220c, 0x2304,
-	0xa106, 0x11b8, 0x8210, 0x8318, 0x1f04, 0x459e, 0x6043, 0x0004,
-	0x608b, 0xbc94, 0x608f, 0xf0f0, 0x6043, 0x0006, 0x7083, 0x0002,
-	0x708f, 0x0002, 0x2009, 0x07d0, 0x2011, 0x4adc, 0x080c, 0x6a22,
-	0x0490, 0x2069, 0xbb80, 0x6930, 0xa18e, 0x1101, 0x1538, 0x6834,
-	0xa005, 0x1520, 0x6900, 0xa18c, 0x00ff, 0x1118, 0x6804, 0xa005,
-	0x0190, 0x2011, 0xbb8e, 0x2019, 0xb505, 0x20a9, 0x0004, 0x220c,
-	0x2304, 0xa102, 0x0230, 0x1190, 0x8210, 0x8318, 0x1f04, 0x45cf,
-	0x0068, 0x7097, 0x0000, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099,
-	0xbb80, 0x20a1, 0x020b, 0x20a9, 0x0014, 0x53a6, 0x6043, 0x0008,
-	0x6043, 0x0000, 0x0010, 0x00de, 0x0005, 0x6040, 0xa085, 0x0100,
-	0x6042, 0x6020, 0xd0b4, 0x1db8, 0x60c3, 0x000c, 0x2011, 0xb7ea,
-	0x2013, 0x0000, 0x7087, 0x0000, 0x20e1, 0x9080, 0x60a3, 0x0056,
-	0x60a7, 0x9575, 0x080c, 0x7d71, 0x0c30, 0x0005, 0x708c, 0xa08a,
-	0x001d, 0x1210, 0x0023, 0x0010, 0x080c, 0x1515, 0x0005, 0x4639,
-	0x4648, 0x4670, 0x4689, 0x46ad, 0x46d5, 0x46f9, 0x472a, 0x474e,
-	0x4776, 0x47ad, 0x47d5, 0x47f1, 0x4807, 0x4827, 0x483a, 0x4842,
-	0x4872, 0x4896, 0x48be, 0x48e2, 0x4913, 0x4950, 0x497f, 0x499b,
-	0x49da, 0x49fa, 0x4a13, 0x4a14, 0x00c6, 0x2061, 0xb500, 0x6003,
-	0x0007, 0x2061, 0x0100, 0x6004, 0xa084, 0xfff9, 0x6006, 0x00ce,
-	0x0005, 0x608b, 0xbc94, 0x608f, 0xf0f0, 0x6043, 0x0002, 0x708f,
-	0x0001, 0x2009, 0x07d0, 0x2011, 0x4adc, 0x080c, 0x6a22, 0x0005,
-	0x00f6, 0x7084, 0xa086, 0x0014, 0x1508, 0x6043, 0x0000, 0x6020,
-	0xd0b4, 0x11e0, 0x2079, 0xbb80, 0x7a30, 0xa296, 0x1102, 0x11a0,
-	0x7834, 0xa005, 0x1188, 0x7a38, 0xd2fc, 0x0128, 0x70b8, 0xa005,
-	0x1110, 0x70bb, 0x0001, 0x2011, 0x4adc, 0x080c, 0x699c, 0x708f,
-	0x0010, 0x080c, 0x4842, 0x0010, 0x080c, 0x4b1f, 0x00fe, 0x0005,
-	0x708f, 0x0003, 0x6043, 0x0004, 0x2011, 0x4adc, 0x080c, 0x699c,
-	0x080c, 0x4b97, 0x20a3, 0x1102, 0x20a3, 0x0000, 0x20a9, 0x000a,
-	0x20a3, 0x0000, 0x1f04, 0x4680, 0x60c3, 0x0014, 0x080c, 0x4b06,
-	0x0005, 0x00f6, 0x7084, 0xa005, 0x01f0, 0x2011, 0x4adc, 0x080c,
-	0x699c, 0xa086, 0x0014, 0x11a8, 0x2079, 0xbb80, 0x7a30, 0xa296,
-	0x1102, 0x1178, 0x7834, 0xa005, 0x1160, 0x7a38, 0xd2fc, 0x0128,
-	0x70b8, 0xa005, 0x1110, 0x70bb, 0x0001, 0x708f, 0x0004, 0x0029,
-	0x0010, 0x080c, 0x4b1f, 0x00fe, 0x0005, 0x708f, 0x0005, 0x080c,
-	0x4b97, 0x20a3, 0x1103, 0x20a3, 0x0000, 0x3430, 0x2011, 0xbb8e,
-	0x080c, 0x4be8, 0x1160, 0x7078, 0xa005, 0x1148, 0x7150, 0xa186,
-	0xffff, 0x0128, 0x080c, 0x4aa0, 0x0110, 0x080c, 0x4bc6, 0x20a9,
+	0x2001, 0x4006, 0x2020, 0x012e, 0x0804, 0x2fe1, 0x2d00, 0x7022,
+	0x0016, 0x00b6, 0x00c6, 0x00e6, 0x2c70, 0x080c, 0x864e, 0x05c0,
+	0x2d00, 0x601a, 0x080c, 0xa0e3, 0x2e58, 0x00ee, 0x00e6, 0x00c6,
+	0x080c, 0x3ebc, 0x00ce, 0x2b70, 0x1158, 0x080c, 0x86a4, 0x00ee,
+	0x00ce, 0x00be, 0x001e, 0x012e, 0x2009, 0x0002, 0x0804, 0x3004,
+	0x6837, 0x0000, 0x683b, 0x0000, 0x2d00, 0x6012, 0x6833, 0x0000,
+	0x6838, 0xc0fd, 0xd88c, 0x0108, 0xc0f5, 0x683a, 0x080c, 0x2cd1,
+	0x601f, 0x0001, 0x2001, 0x0000, 0x080c, 0x4f5d, 0x2001, 0x0002,
+	0x080c, 0x4f6f, 0x2009, 0x0002, 0x080c, 0x86d3, 0xa085, 0x0001,
+	0x00ee, 0x00ce, 0x00be, 0x001e, 0x012e, 0x1120, 0x2009, 0x0003,
+	0x0804, 0x3004, 0x7007, 0x0003, 0x701b, 0x3def, 0x0005, 0x6830,
+	0xa086, 0x0100, 0x7020, 0x2060, 0x1138, 0x2009, 0x0004, 0x6204,
+	0xa294, 0x00ff, 0x0804, 0x3004, 0x2009, 0x0000, 0x6838, 0xd0f4,
+	0x1904, 0x2fdf, 0x080c, 0x52bc, 0x1108, 0xc185, 0x6000, 0xd0bc,
+	0x0108, 0xc18d, 0x0804, 0x2fdf, 0x00e6, 0x00d6, 0xa02e, 0x2001,
+	0xb635, 0x2004, 0xd0ac, 0x0130, 0xa026, 0x20a9, 0x00ff, 0x2071,
+	0xb735, 0x0030, 0x2021, 0x0080, 0x20a9, 0x007f, 0x2071, 0xb7b5,
+	0x2e04, 0xa005, 0x1130, 0x2100, 0xa406, 0x1570, 0x2428, 0xc5fd,
+	0x0458, 0x2068, 0x6f10, 0x2700, 0xa306, 0x11b0, 0x6e14, 0x2600,
+	0xa206, 0x1190, 0x2400, 0xa106, 0x1160, 0x2d60, 0xd884, 0x0568,
+	0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x1538, 0x2001, 0x4000,
+	0x0428, 0x2001, 0x4007, 0x0410, 0x2400, 0xa106, 0x1168, 0x6e14,
+	0x87ff, 0x1138, 0x86ff, 0x09d0, 0x2001, 0xb635, 0x2004, 0xd0ac,
+	0x19a8, 0x2001, 0x4008, 0x0090, 0x8420, 0x8e70, 0x1f04, 0x3e20,
+	0x85ff, 0x1130, 0x2001, 0x4009, 0x0048, 0x2001, 0x0001, 0x0030,
+	0x080c, 0x4fbf, 0x1dd0, 0x6312, 0x6216, 0xa006, 0xa005, 0x00de,
+	0x00ee, 0x0005, 0x81ff, 0x1904, 0x3004, 0x080c, 0x3ebc, 0x0904,
+	0x3004, 0x6837, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x7824, 0xa005,
+	0x0904, 0x3007, 0xa096, 0x00ff, 0x0120, 0xa092, 0x0004, 0x1a04,
+	0x3007, 0x2010, 0x2d18, 0x080c, 0x2c84, 0x0904, 0x3004, 0x7007,
+	0x0003, 0x701b, 0x3e8c, 0x0005, 0x6830, 0xa086, 0x0100, 0x0904,
+	0x3004, 0x0804, 0x2fdf, 0x7924, 0xa18c, 0xff00, 0x810f, 0x60d4,
+	0xd0ac, 0x1120, 0xa182, 0x0080, 0x0a04, 0x3007, 0xa182, 0x00ff,
+	0x1a04, 0x3007, 0x0126, 0x2091, 0x8000, 0x080c, 0x9d46, 0x1188,
+	0xa190, 0xb735, 0x2204, 0xa065, 0x0160, 0x080c, 0x4c7e, 0x2001,
+	0xb635, 0x2004, 0xd0ac, 0x0110, 0x6017, 0x0000, 0x012e, 0x0804,
+	0x2fdf, 0x012e, 0x0804, 0x3004, 0x080c, 0x15fd, 0x0188, 0xa006,
+	0x6802, 0x7010, 0xa005, 0x1120, 0x2d00, 0x7012, 0x7016, 0x0030,
+	0x7014, 0x6802, 0x2060, 0x2d00, 0x6006, 0x7016, 0xad80, 0x000d,
+	0x0005, 0x7924, 0x810f, 0xa18c, 0x00ff, 0x080c, 0x501b, 0x1130,
+	0x7e28, 0xa684, 0x3fff, 0xa082, 0x4000, 0x0208, 0xa066, 0x8cff,
+	0x0005, 0x7e24, 0x860f, 0xa18c, 0x00ff, 0x080c, 0x501b, 0x1128,
+	0xa6b4, 0x00ff, 0xa682, 0x4000, 0x0208, 0xa066, 0x8cff, 0x0005,
+	0x0016, 0x7110, 0x81ff, 0x0128, 0x2168, 0x6904, 0x080c, 0x1614,
+	0x0cc8, 0x7112, 0x7116, 0x001e, 0x0005, 0x2031, 0x0001, 0x0010,
+	0x2031, 0x0000, 0x2061, 0xb6d2, 0x6606, 0x6112, 0x600e, 0x6226,
+	0x632a, 0x642e, 0x6532, 0x2c10, 0x080c, 0x1648, 0x7007, 0x0002,
+	0x701b, 0x2fdf, 0x0005, 0x00f6, 0x0126, 0x2091, 0x8000, 0x2079,
+	0x0000, 0x2001, 0xb690, 0x2004, 0xa005, 0x1168, 0x0e04, 0x3f2b,
+	0x7818, 0xd084, 0x1140, 0x7a22, 0x7b26, 0x7c2a, 0x781b, 0x0001,
+	0x2091, 0x4080, 0x0408, 0x0016, 0x00c6, 0x00e6, 0x2071, 0xb682,
+	0x7138, 0xa182, 0x0010, 0x0218, 0x7030, 0x2060, 0x0078, 0x7030,
+	0xa0e0, 0x0004, 0xac82, 0xb6d2, 0x0210, 0x2061, 0xb692, 0x2c00,
+	0x7032, 0x81ff, 0x1108, 0x7036, 0x8108, 0x713a, 0x2262, 0x6306,
+	0x640a, 0x00ee, 0x00ce, 0x001e, 0x012e, 0x00fe, 0x0005, 0x00e6,
+	0x2071, 0xb682, 0x7038, 0xa005, 0x0570, 0x0126, 0x2091, 0x8000,
+	0x0e04, 0x3f82, 0x00f6, 0x2079, 0x0000, 0x7818, 0xd084, 0x1508,
+	0x00c6, 0x7034, 0x2060, 0x2c04, 0x7822, 0x6004, 0x7826, 0x6008,
+	0x782a, 0x781b, 0x0001, 0x2091, 0x4080, 0x7038, 0x8001, 0x703a,
+	0xa005, 0x1130, 0x7033, 0xb692, 0x7037, 0xb692, 0x00ce, 0x0048,
+	0xac80, 0x0004, 0xa0fa, 0xb6d2, 0x0210, 0x2001, 0xb692, 0x7036,
+	0x00ce, 0x00fe, 0x012e, 0x00ee, 0x0005, 0x0026, 0x2001, 0xb653,
+	0x2004, 0xd0c4, 0x0120, 0x2011, 0x8014, 0x080c, 0x3f13, 0x002e,
+	0x0005, 0x81ff, 0x1904, 0x3004, 0x0126, 0x2091, 0x8000, 0x6030,
+	0xc08d, 0xc085, 0xc0ac, 0x6032, 0x080c, 0x5b41, 0x1178, 0x2001,
+	0xb89f, 0x2003, 0x0001, 0x2001, 0xb600, 0x2003, 0x0001, 0xa085,
+	0x0001, 0x080c, 0x5b85, 0x080c, 0x5a79, 0x0010, 0x080c, 0x4b7b,
+	0x012e, 0x0804, 0x2fdf, 0x7824, 0x2008, 0xa18c, 0xfffd, 0x1128,
+	0x61e0, 0xa10d, 0x61e2, 0x0804, 0x2fdf, 0x0804, 0x3007, 0x81ff,
+	0x1904, 0x3004, 0x6000, 0xa086, 0x0003, 0x1904, 0x3004, 0x2001,
+	0xb653, 0x2004, 0xd0ac, 0x1904, 0x3004, 0x080c, 0x3ee1, 0x0904,
+	0x3007, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x1120, 0x7828,
+	0xa005, 0x0904, 0x2fdf, 0x00c6, 0x080c, 0x3ebc, 0x00ce, 0x0904,
+	0x3004, 0x6837, 0x0000, 0x6833, 0x0000, 0x6838, 0xc0fd, 0x683a,
+	0x080c, 0x9f27, 0x0904, 0x3004, 0x7007, 0x0003, 0x701b, 0x3ff1,
+	0x0005, 0x6830, 0xa086, 0x0100, 0x0904, 0x3004, 0x0804, 0x2fdf,
+	0x2001, 0xb600, 0x2004, 0xa086, 0x0003, 0x1904, 0x3004, 0x7f24,
+	0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x080c, 0x3ebc, 0x0904, 0x3004,
+	0x2009, 0x0000, 0x2031, 0x0000, 0x7023, 0x0000, 0x702f, 0x0000,
+	0xad80, 0x0005, 0x7026, 0x20a0, 0x080c, 0x501b, 0x1904, 0x406b,
+	0x6004, 0xa0c4, 0x00ff, 0xa8c6, 0x0006, 0x0130, 0xa0c4, 0xff00,
+	0xa8c6, 0x0600, 0x1904, 0x406b, 0x2001, 0xb653, 0x2004, 0xd0ac,
+	0x1128, 0x080c, 0x52bc, 0x1110, 0xd79c, 0x05e8, 0xd794, 0x1110,
+	0xd784, 0x0158, 0xac80, 0x0006, 0x2098, 0x3400, 0x20a9, 0x0004,
+	0x53a3, 0x080c, 0x3d2c, 0xd794, 0x0148, 0xac80, 0x000a, 0x2098,
+	0x3400, 0x20a9, 0x0004, 0x53a3, 0x080c, 0x3d2c, 0x21a2, 0xd794,
+	0x01d8, 0xac80, 0x0000, 0x2098, 0x94a0, 0x20a9, 0x0002, 0x53a3,
+	0xac80, 0x0003, 0x20a6, 0x94a0, 0xac80, 0x0004, 0x2098, 0x3400,
+	0x20a9, 0x0002, 0x53a3, 0x080c, 0x3d1e, 0xac80, 0x0026, 0x2098,
+	0x20a9, 0x0002, 0x53a3, 0x0008, 0x94a0, 0xd794, 0x0110, 0xa6b0,
+	0x000b, 0xa6b0, 0x0005, 0x8108, 0x2001, 0xb635, 0x2004, 0xd0ac,
+	0x0118, 0xa186, 0x0100, 0x0040, 0xd78c, 0x0120, 0xa186, 0x0100,
+	0x0170, 0x0018, 0xa186, 0x007e, 0x0150, 0xd794, 0x0118, 0xa686,
+	0x0020, 0x0010, 0xa686, 0x0028, 0x0150, 0x0804, 0x4014, 0x86ff,
+	0x1120, 0x7120, 0x810b, 0x0804, 0x2fdf, 0x702f, 0x0001, 0x711e,
+	0x7020, 0xa600, 0x7022, 0x772a, 0x2061, 0xb6d2, 0x6007, 0x0000,
+	0x6612, 0x7024, 0x600e, 0x6226, 0x632a, 0x642e, 0x6532, 0x2c10,
+	0x080c, 0x1648, 0x7007, 0x0002, 0x701b, 0x40a7, 0x0005, 0x702c,
+	0xa005, 0x1170, 0x711c, 0x7024, 0x20a0, 0x7728, 0x2031, 0x0000,
+	0x2061, 0xb6d2, 0x6224, 0x6328, 0x642c, 0x6530, 0x0804, 0x4014,
+	0x7120, 0x810b, 0x0804, 0x2fdf, 0x2029, 0x007e, 0x7924, 0x7a28,
+	0x7b2c, 0x7c38, 0xa184, 0xff00, 0x8007, 0xa0e2, 0x0020, 0x0a04,
+	0x3007, 0xa502, 0x0a04, 0x3007, 0xa184, 0x00ff, 0xa0e2, 0x0020,
+	0x0a04, 0x3007, 0xa502, 0x0a04, 0x3007, 0xa284, 0xff00, 0x8007,
+	0xa0e2, 0x0020, 0x0a04, 0x3007, 0xa502, 0x0a04, 0x3007, 0xa284,
+	0x00ff, 0xa0e2, 0x0020, 0x0a04, 0x3007, 0xa502, 0x0a04, 0x3007,
+	0xa384, 0xff00, 0x8007, 0xa0e2, 0x0020, 0x0a04, 0x3007, 0xa502,
+	0x0a04, 0x3007, 0xa384, 0x00ff, 0xa0e2, 0x0020, 0x0a04, 0x3007,
+	0xa502, 0x0a04, 0x3007, 0xa484, 0xff00, 0x8007, 0xa0e2, 0x0020,
+	0x0a04, 0x3007, 0xa502, 0x0a04, 0x3007, 0xa484, 0x00ff, 0xa0e2,
+	0x0020, 0x0a04, 0x3007, 0xa502, 0x0a04, 0x3007, 0x2061, 0xb8b9,
+	0x6102, 0x6206, 0x630a, 0x640e, 0x0804, 0x2fdf, 0x0006, 0x2001,
+	0xb653, 0x2004, 0xd0cc, 0x000e, 0x0005, 0x0006, 0x2001, 0xb672,
+	0x2004, 0xd0bc, 0x000e, 0x0005, 0x6168, 0x7a24, 0x6300, 0x82ff,
+	0x1118, 0x7926, 0x0804, 0x2fdf, 0x83ff, 0x1904, 0x3007, 0x2001,
+	0xfff0, 0xa200, 0x1a04, 0x3007, 0x2019, 0xffff, 0x606c, 0xa302,
+	0xa200, 0x0a04, 0x3007, 0x7926, 0x626a, 0x0804, 0x2fdf, 0x2001,
+	0xb600, 0x2004, 0xa086, 0x0003, 0x1904, 0x3004, 0x7c28, 0x7d24,
+	0x7e38, 0x7f2c, 0x080c, 0x3ebc, 0x0904, 0x3004, 0x2009, 0x0000,
+	0x2019, 0x0000, 0x7023, 0x0000, 0x702f, 0x0000, 0xad80, 0x0003,
+	0x7026, 0x20a0, 0xa1e0, 0xb735, 0x2c64, 0x8cff, 0x01b8, 0x6004,
+	0xa084, 0x00ff, 0xa086, 0x0006, 0x0130, 0x6004, 0xa084, 0xff00,
+	0xa086, 0x0600, 0x1158, 0x6014, 0x20a2, 0x94a0, 0x6010, 0x8007,
+	0xa105, 0x8007, 0x20a2, 0x94a0, 0xa398, 0x0002, 0x8108, 0xa182,
+	0x00ff, 0x0120, 0xa386, 0x002a, 0x0148, 0x08e0, 0x83ff, 0x1120,
+	0x7120, 0x810c, 0x0804, 0x2fdf, 0x702f, 0x0001, 0x711e, 0x7020,
+	0xa300, 0x7022, 0x2061, 0xb6d2, 0x6007, 0x0000, 0x6312, 0x7024,
+	0x600e, 0x6426, 0x652a, 0x662e, 0x6732, 0x2c10, 0x080c, 0x1648,
+	0x7007, 0x0002, 0x701b, 0x419d, 0x0005, 0x702c, 0xa005, 0x1168,
+	0x711c, 0x7024, 0x20a0, 0x2019, 0x0000, 0x2061, 0xb6d2, 0x6424,
+	0x6528, 0x662c, 0x6730, 0x0804, 0x415a, 0x7120, 0x810c, 0x0804,
+	0x2fdf, 0x81ff, 0x1904, 0x3004, 0x60d4, 0xd0ac, 0x1118, 0xd09c,
+	0x0904, 0x3004, 0x080c, 0x3ebc, 0x0904, 0x3004, 0x7924, 0x7a2c,
+	0x7b28, 0x7c3c, 0x7d38, 0x080c, 0x3efd, 0x701b, 0x41c8, 0x0005,
+	0x00d6, 0xade8, 0x000d, 0x6828, 0xa0be, 0x7000, 0x0148, 0xa0be,
+	0x7100, 0x0130, 0xa0be, 0x7200, 0x0118, 0x00de, 0x0804, 0x3007,
+	0x6820, 0x6924, 0x080c, 0x2852, 0x1510, 0x080c, 0x4fbf, 0x11f8,
+	0x7122, 0x6612, 0x6516, 0x6e18, 0x00c6, 0x080c, 0x3ebc, 0x01b8,
+	0x080c, 0x3ebc, 0x01a0, 0x00ce, 0x00de, 0x6837, 0x0000, 0x6838,
+	0xc0fd, 0x683a, 0x6823, 0x0000, 0x6804, 0x2068, 0x080c, 0x9e7a,
+	0x0904, 0x3004, 0x7007, 0x0003, 0x701b, 0x4202, 0x0005, 0x00de,
+	0x0804, 0x3004, 0x7120, 0x080c, 0x2dcc, 0x6820, 0xa086, 0x8001,
+	0x0904, 0x3004, 0x2d00, 0x701e, 0x6804, 0xa080, 0x0002, 0x0006,
+	0x20a9, 0x002a, 0x2098, 0x20a0, 0x080c, 0x4bf1, 0x000e, 0xade8,
+	0x000d, 0x6a08, 0x6b0c, 0x6c10, 0x6d14, 0x2061, 0xb6d2, 0x6007,
+	0x0000, 0x6e00, 0x6f28, 0xa7c6, 0x7000, 0x1108, 0x0018, 0xa7c6,
+	0x7100, 0x1140, 0xa6c2, 0x0004, 0x0a04, 0x3007, 0x2009, 0x0004,
+	0x0804, 0x3f00, 0xa7c6, 0x7200, 0x1904, 0x3007, 0xa6c2, 0x0054,
+	0x0a04, 0x3007, 0x600e, 0x6013, 0x002a, 0x6226, 0x632a, 0x642e,
+	0x6532, 0x2c10, 0x080c, 0x1648, 0x7007, 0x0002, 0x701b, 0x4249,
+	0x0005, 0x701c, 0x2068, 0x6804, 0xa080, 0x0001, 0x2004, 0xa080,
+	0x0002, 0x0006, 0x20a9, 0x002a, 0x2098, 0x20a0, 0x080c, 0x4bf1,
+	0x000e, 0x2009, 0x002a, 0x2061, 0xb6d2, 0x6224, 0x6328, 0x642c,
+	0x6530, 0x0804, 0x3f00, 0x81ff, 0x1904, 0x3004, 0x792c, 0x2001,
+	0xb8a0, 0x2102, 0x080c, 0x3ed1, 0x0904, 0x3007, 0x080c, 0x50e1,
+	0x0904, 0x3004, 0x0126, 0x2091, 0x8000, 0x080c, 0x5213, 0x012e,
+	0x0804, 0x2fdf, 0x7824, 0xd08c, 0x1118, 0xd084, 0x0904, 0x3a87,
+	0x080c, 0x3ee1, 0x0904, 0x3007, 0x00c6, 0x080c, 0x3ebc, 0x00ce,
+	0x1120, 0x2009, 0x0002, 0x0804, 0x3004, 0x6004, 0xa084, 0x00ff,
+	0xa086, 0x0006, 0x0128, 0xa08e, 0x0004, 0x0110, 0xa08e, 0x0005,
+	0x15b8, 0x7824, 0xd08c, 0x0120, 0x6000, 0xc08c, 0x6002, 0x0030,
+	0x2001, 0xb653, 0x2004, 0xd0b4, 0x0904, 0x3ac3, 0x7824, 0xa084,
+	0xff00, 0xa08e, 0x7e00, 0x0904, 0x3ac3, 0xa08e, 0x7f00, 0x0904,
+	0x3ac3, 0xa08e, 0x8000, 0x0904, 0x3ac3, 0x6000, 0xd08c, 0x1904,
+	0x3ac3, 0x6837, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x080c, 0x9e96,
+	0x1120, 0x2009, 0x0003, 0x0804, 0x3004, 0x7007, 0x0003, 0x701b,
+	0x42ca, 0x0005, 0x080c, 0x3ee1, 0x0904, 0x3007, 0x0804, 0x3ac3,
+	0x2009, 0xb631, 0x210c, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804,
+	0x3004, 0x2001, 0xb600, 0x2004, 0xa086, 0x0003, 0x0120, 0x2009,
+	0x0007, 0x0804, 0x3004, 0x2001, 0xb653, 0x2004, 0xd0ac, 0x0120,
+	0x2009, 0x0008, 0x0804, 0x3004, 0x609c, 0xd0a4, 0x1118, 0xd0ac,
+	0x1904, 0x3ac3, 0x6837, 0x0000, 0x6833, 0x0000, 0x6838, 0xc0fd,
+	0x683a, 0x080c, 0x9f27, 0x1120, 0x2009, 0x0003, 0x0804, 0x3004,
+	0x7007, 0x0003, 0x701b, 0x4305, 0x0005, 0x6830, 0xa086, 0x0100,
+	0x1120, 0x2009, 0x0004, 0x0804, 0x3004, 0x080c, 0x3ee1, 0x0904,
+	0x3007, 0x0804, 0x4299, 0x81ff, 0x2009, 0x0001, 0x1904, 0x3004,
+	0x6000, 0xa086, 0x0003, 0x2009, 0x0007, 0x1904, 0x3004, 0x2001,
+	0xb653, 0x2004, 0xd0ac, 0x2009, 0x0008, 0x1904, 0x3004, 0x080c,
+	0x3ee1, 0x0904, 0x3007, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006,
+	0x2009, 0x0009, 0x1904, 0x3004, 0x00c6, 0x080c, 0x3ebc, 0x00ce,
+	0x2009, 0x0002, 0x0904, 0x3004, 0x6837, 0x0000, 0x6833, 0x0000,
+	0x6838, 0xc0fd, 0x683a, 0x7928, 0xa194, 0xff00, 0xa18c, 0x00ff,
+	0xa006, 0x82ff, 0x1128, 0xc0ed, 0x6952, 0x792c, 0x6956, 0x0048,
+	0xa28e, 0x0100, 0x1904, 0x3007, 0xc0e5, 0x6853, 0x0000, 0x6857,
+	0x0000, 0x683e, 0x080c, 0xa0e4, 0x2009, 0x0003, 0x0904, 0x3004,
+	0x7007, 0x0003, 0x701b, 0x4365, 0x0005, 0x6830, 0xa086, 0x0100,
+	0x2009, 0x0004, 0x0904, 0x3004, 0x0804, 0x2fdf, 0x81ff, 0x2009,
+	0x0001, 0x1904, 0x3004, 0x6000, 0xa086, 0x0003, 0x2009, 0x0007,
+	0x1904, 0x3004, 0x080c, 0x3ee1, 0x0904, 0x3007, 0x6004, 0xa084,
+	0x00ff, 0xa086, 0x0006, 0x2009, 0x0009, 0x1904, 0x3004, 0x00c6,
+	0x080c, 0x3ebc, 0x00ce, 0x2009, 0x0002, 0x0904, 0x3004, 0xad80,
+	0x000f, 0x2009, 0x0008, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x080c,
+	0x3efd, 0x701b, 0x439c, 0x0005, 0x00d6, 0xade8, 0x000f, 0x6800,
+	0xa086, 0x0500, 0x1140, 0x6804, 0xa005, 0x1128, 0x6808, 0xa084,
+	0xff00, 0x1108, 0x0018, 0x00de, 0x1904, 0x3007, 0x00de, 0x6837,
+	0x0000, 0x6833, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x00c6, 0x080c,
+	0x3ee1, 0x1118, 0x00ce, 0x0804, 0x3007, 0x080c, 0xa133, 0x2009,
+	0x0003, 0x00ce, 0x0904, 0x3004, 0x7007, 0x0003, 0x701b, 0x43c9,
+	0x0005, 0x6830, 0xa086, 0x0100, 0x2009, 0x0004, 0x0904, 0x3004,
+	0x0804, 0x2fdf, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x3004,
+	0x6000, 0xa086, 0x0003, 0x0120, 0x2009, 0x0007, 0x0804, 0x3004,
+	0x7e24, 0x860f, 0xa18c, 0x00ff, 0xa6b4, 0x00ff, 0x080c, 0x501b,
+	0x1904, 0x3007, 0xa186, 0x007f, 0x0150, 0x6004, 0xa084, 0x00ff,
+	0xa086, 0x0006, 0x0120, 0x2009, 0x0009, 0x0804, 0x3004, 0x00c6,
+	0x080c, 0x3ebc, 0x00ce, 0x1120, 0x2009, 0x0002, 0x0804, 0x3004,
+	0x6837, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x2001, 0x0100, 0x8007,
+	0x680a, 0x080c, 0x9eb1, 0x1120, 0x2009, 0x0003, 0x0804, 0x3004,
+	0x7007, 0x0003, 0x701b, 0x4415, 0x0005, 0x6808, 0x8007, 0xa086,
+	0x0100, 0x1120, 0x2009, 0x0004, 0x0804, 0x3004, 0x68b0, 0x6836,
+	0x6810, 0x8007, 0xa084, 0x00ff, 0x800c, 0x6814, 0x8007, 0xa084,
+	0x00ff, 0x8004, 0xa080, 0x0002, 0xa108, 0xad80, 0x0004, 0x7a2c,
+	0x7b28, 0x7c3c, 0x7d38, 0x0804, 0x3f00, 0x080c, 0x3ebc, 0x1120,
+	0x2009, 0x0002, 0x0804, 0x3004, 0x7924, 0xa194, 0xff00, 0xa18c,
+	0x00ff, 0x8217, 0x82ff, 0x0110, 0x0804, 0x3007, 0x2009, 0x001a,
+	0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x080c, 0x3efd, 0x701b, 0x4451,
+	0x0005, 0x2001, 0xb62a, 0x2003, 0x0001, 0xad80, 0x000d, 0x2098,
+	0x20a9, 0x001a, 0x20a1, 0xb8c7, 0x53a3, 0x0804, 0x2fdf, 0x080c,
+	0x3ebc, 0x1120, 0x2009, 0x0002, 0x0804, 0x3004, 0x7924, 0xa194,
+	0xff00, 0xa18c, 0x00ff, 0x8217, 0x82ff, 0x0110, 0x0804, 0x3007,
+	0x2099, 0xb8c7, 0x20a0, 0x20a9, 0x001a, 0x53a3, 0x2009, 0x001a,
+	0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0804, 0x3f00, 0x7824, 0xa08a,
+	0x1000, 0x1a04, 0x3007, 0x0126, 0x2091, 0x8000, 0x8003, 0x800b,
+	0x810b, 0xa108, 0x00c6, 0x2061, 0xb8f4, 0x6142, 0x00ce, 0x012e,
+	0x0804, 0x2fdf, 0x00c6, 0x080c, 0x5b41, 0x1188, 0x2001, 0xb89f,
+	0x2003, 0x0001, 0x2001, 0xb600, 0x2003, 0x0001, 0xa085, 0x0001,
+	0x080c, 0x5b85, 0x080c, 0x5a79, 0x080c, 0x151a, 0x0038, 0x2061,
+	0xb600, 0x6030, 0xc09d, 0x6032, 0x080c, 0x4b7b, 0x00ce, 0x0005,
+	0x0126, 0x2091, 0x8000, 0x00c6, 0x2061, 0xb8f4, 0x7924, 0x6152,
+	0x614e, 0x6057, 0x0000, 0x604b, 0x0009, 0x7838, 0x606a, 0x783c,
+	0x6066, 0x7828, 0x6062, 0x782c, 0x605e, 0x2061, 0xb8a1, 0x2001,
+	0xb909, 0x600e, 0x6013, 0x0001, 0x6017, 0x0002, 0x6007, 0x0000,
+	0x6037, 0x0000, 0x00ce, 0x012e, 0x0804, 0x2fdf, 0x0126, 0x00c6,
+	0x00e6, 0x2061, 0x0100, 0x2071, 0xb600, 0x6044, 0xd0a4, 0x11b0,
+	0xd084, 0x0118, 0x080c, 0x464d, 0x0068, 0xd08c, 0x0118, 0x080c,
+	0x456e, 0x0040, 0xd094, 0x0118, 0x080c, 0x453f, 0x0018, 0xd09c,
+	0x0108, 0x0061, 0x00ee, 0x00ce, 0x012e, 0x0005, 0x0016, 0x6128,
+	0xd19c, 0x1110, 0xc19d, 0x612a, 0x001e, 0x0ca0, 0x624c, 0xa286,
+	0xf0f0, 0x1150, 0x6048, 0xa086, 0xf0f0, 0x0130, 0x624a, 0x6043,
+	0x0090, 0x6043, 0x0010, 0x0490, 0xa294, 0xff00, 0xa296, 0xf700,
+	0x0178, 0x7134, 0xd1a4, 0x1160, 0x6240, 0xa295, 0x0100, 0x6242,
+	0xa294, 0x0010, 0x0128, 0x2009, 0x00f7, 0x080c, 0x4c11, 0x00f0,
+	0x6040, 0xa084, 0x0010, 0xa085, 0x0140, 0x6042, 0x6043, 0x0000,
+	0x707b, 0x0000, 0x7097, 0x0001, 0x70bb, 0x0000, 0x70d7, 0x0000,
+	0x2009, 0xbdc0, 0x200b, 0x0000, 0x708b, 0x0000, 0x707f, 0x000a,
+	0x2009, 0x000a, 0x2011, 0x4b1c, 0x080c, 0x6a94, 0x0005, 0x0156,
+	0x2001, 0xb674, 0x2004, 0xd08c, 0x0110, 0x7053, 0xffff, 0x707c,
+	0xa005, 0x1510, 0x2011, 0x4b1c, 0x080c, 0x6a0e, 0x6040, 0xa094,
+	0x0010, 0xa285, 0x0020, 0x6042, 0x20a9, 0x00c8, 0x6044, 0xd08c,
+	0x1168, 0x1f04, 0x4556, 0x6242, 0x708f, 0x0000, 0x6040, 0xa094,
+	0x0010, 0xa285, 0x0080, 0x6042, 0x6242, 0x0030, 0x6242, 0x708f,
+	0x0000, 0x7083, 0x0000, 0x0000, 0x015e, 0x0005, 0x7080, 0xa08a,
+	0x0003, 0x1210, 0x0023, 0x0010, 0x080c, 0x151a, 0x0005, 0x457a,
+	0x45ca, 0x464c, 0x00f6, 0x7083, 0x0001, 0x20e1, 0xa000, 0xe000,
+	0x20e1, 0x8700, 0x080c, 0x24a5, 0x20e1, 0x9080, 0x20e1, 0x4000,
+	0x2079, 0xbc00, 0x207b, 0x2200, 0x7807, 0x00ef, 0x780b, 0x0000,
+	0x780f, 0x00ef, 0x7813, 0x0138, 0x7817, 0x0000, 0x781b, 0x0000,
+	0x781f, 0x0000, 0x7823, 0xffff, 0x7827, 0xffff, 0x782b, 0x0000,
+	0x782f, 0x0000, 0x2079, 0xbc0c, 0x207b, 0x1101, 0x7807, 0x0000,
+	0x2099, 0xb605, 0x20a1, 0xbc0e, 0x20a9, 0x0004, 0x53a3, 0x2079,
+	0xbc12, 0x207b, 0x0000, 0x7807, 0x0000, 0x2099, 0xbc00, 0x20a1,
+	0x020b, 0x20a9, 0x0014, 0x53a6, 0x60c3, 0x000c, 0x600f, 0x0000,
+	0x080c, 0x4b55, 0x00fe, 0x7087, 0x0000, 0x6043, 0x0008, 0x6043,
+	0x0000, 0x0005, 0x00d6, 0x7084, 0x7087, 0x0000, 0xa025, 0x0904,
+	0x4634, 0x6020, 0xd0b4, 0x1904, 0x4632, 0x7194, 0x81ff, 0x0904,
+	0x4622, 0xa486, 0x000c, 0x1904, 0x462d, 0xa480, 0x0018, 0x8004,
+	0x20a8, 0x2011, 0xbc80, 0x2019, 0xbc00, 0x220c, 0x2304, 0xa106,
+	0x11b8, 0x8210, 0x8318, 0x1f04, 0x45e5, 0x6043, 0x0004, 0x608b,
+	0xbc94, 0x608f, 0xf0f0, 0x6043, 0x0006, 0x7083, 0x0002, 0x708f,
+	0x0002, 0x2009, 0x07d0, 0x2011, 0x4b23, 0x080c, 0x6a94, 0x0490,
+	0x2069, 0xbc80, 0x6930, 0xa18e, 0x1101, 0x1538, 0x6834, 0xa005,
+	0x1520, 0x6900, 0xa18c, 0x00ff, 0x1118, 0x6804, 0xa005, 0x0190,
+	0x2011, 0xbc8e, 0x2019, 0xb605, 0x20a9, 0x0004, 0x220c, 0x2304,
+	0xa102, 0x0230, 0x1190, 0x8210, 0x8318, 0x1f04, 0x4616, 0x0068,
+	0x7097, 0x0000, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099, 0xbc80,
+	0x20a1, 0x020b, 0x20a9, 0x0014, 0x53a6, 0x6043, 0x0008, 0x6043,
+	0x0000, 0x0010, 0x00de, 0x0005, 0x6040, 0xa085, 0x0100, 0x6042,
+	0x6020, 0xd0b4, 0x1db8, 0x60c3, 0x000c, 0x2011, 0xb8eb, 0x2013,
+	0x0000, 0x7087, 0x0000, 0x20e1, 0x9080, 0x60a3, 0x0056, 0x60a7,
+	0x9575, 0x080c, 0x7dea, 0x0c30, 0x0005, 0x708c, 0xa08a, 0x001d,
+	0x1210, 0x0023, 0x0010, 0x080c, 0x151a, 0x0005, 0x4680, 0x468f,
+	0x46b7, 0x46d0, 0x46f4, 0x471c, 0x4740, 0x4771, 0x4795, 0x47bd,
+	0x47f4, 0x481c, 0x4838, 0x484e, 0x486e, 0x4881, 0x4889, 0x48b9,
+	0x48dd, 0x4905, 0x4929, 0x495a, 0x4997, 0x49c6, 0x49e2, 0x4a21,
+	0x4a41, 0x4a5a, 0x4a5b, 0x00c6, 0x2061, 0xb600, 0x6003, 0x0007,
+	0x2061, 0x0100, 0x6004, 0xa084, 0xfff9, 0x6006, 0x00ce, 0x0005,
+	0x608b, 0xbc94, 0x608f, 0xf0f0, 0x6043, 0x0002, 0x708f, 0x0001,
+	0x2009, 0x07d0, 0x2011, 0x4b23, 0x080c, 0x6a94, 0x0005, 0x00f6,
+	0x7084, 0xa086, 0x0014, 0x1508, 0x6043, 0x0000, 0x6020, 0xd0b4,
+	0x11e0, 0x2079, 0xbc80, 0x7a30, 0xa296, 0x1102, 0x11a0, 0x7834,
+	0xa005, 0x1188, 0x7a38, 0xd2fc, 0x0128, 0x70b8, 0xa005, 0x1110,
+	0x70bb, 0x0001, 0x2011, 0x4b23, 0x080c, 0x6a0e, 0x708f, 0x0010,
+	0x080c, 0x4889, 0x0010, 0x080c, 0x4b7b, 0x00fe, 0x0005, 0x708f,
+	0x0003, 0x6043, 0x0004, 0x2011, 0x4b23, 0x080c, 0x6a0e, 0x080c,
+	0x4bf9, 0x20a3, 0x1102, 0x20a3, 0x0000, 0x20a9, 0x000a, 0x20a3,
+	0x0000, 0x1f04, 0x46c7, 0x60c3, 0x0014, 0x080c, 0x4b55, 0x0005,
+	0x00f6, 0x7084, 0xa005, 0x01f0, 0x2011, 0x4b23, 0x080c, 0x6a0e,
+	0xa086, 0x0014, 0x11a8, 0x2079, 0xbc80, 0x7a30, 0xa296, 0x1102,
+	0x1178, 0x7834, 0xa005, 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70b8,
+	0xa005, 0x1110, 0x70bb, 0x0001, 0x708f, 0x0004, 0x0029, 0x0010,
+	0x080c, 0x4b7b, 0x00fe, 0x0005, 0x708f, 0x0005, 0x080c, 0x4bf9,
+	0x20a3, 0x1103, 0x20a3, 0x0000, 0x3430, 0x2011, 0xbc8e, 0x080c,
+	0x4c4a, 0x1160, 0x7078, 0xa005, 0x1148, 0x7150, 0xa186, 0xffff,
+	0x0128, 0x080c, 0x4ae7, 0x0110, 0x080c, 0x4c28, 0x20a9, 0x0008,
+	0x2298, 0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3,
+	0x0014, 0x080c, 0x4b55, 0x0005, 0x00f6, 0x7084, 0xa005, 0x01f0,
+	0x2011, 0x4b23, 0x080c, 0x6a0e, 0xa086, 0x0014, 0x11a8, 0x2079,
+	0xbc80, 0x7a30, 0xa296, 0x1103, 0x1178, 0x7834, 0xa005, 0x1160,
+	0x7a38, 0xd2fc, 0x0128, 0x70b8, 0xa005, 0x1110, 0x70bb, 0x0001,
+	0x708f, 0x0006, 0x0029, 0x0010, 0x080c, 0x4b7b, 0x00fe, 0x0005,
+	0x708f, 0x0007, 0x080c, 0x4bf9, 0x20a3, 0x1104, 0x20a3, 0x0000,
+	0x3430, 0x2011, 0xbc8e, 0x080c, 0x4c4a, 0x11a8, 0x7078, 0xa005,
+	0x1190, 0x7158, 0xa186, 0xffff, 0x0170, 0xa180, 0x2df9, 0x200d,
+	0xa18c, 0xff00, 0x810f, 0x080c, 0x4ae7, 0x0128, 0x080c, 0x411d,
+	0x0110, 0x080c, 0x289c, 0x20a9, 0x0008, 0x2298, 0x26a0, 0x53a6,
+	0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014, 0x080c, 0x4b55,
+	0x0005, 0x00f6, 0x7084, 0xa005, 0x01f0, 0x2011, 0x4b23, 0x080c,
+	0x6a0e, 0xa086, 0x0014, 0x11a8, 0x2079, 0xbc80, 0x7a30, 0xa296,
+	0x1104, 0x1178, 0x7834, 0xa005, 0x1160, 0x7a38, 0xd2fc, 0x0128,
+	0x70b8, 0xa005, 0x1110, 0x70bb, 0x0001, 0x708f, 0x0008, 0x0029,
+	0x0010, 0x080c, 0x4b7b, 0x00fe, 0x0005, 0x708f, 0x0009, 0x080c,
+	0x4bf9, 0x20a3, 0x1105, 0x20a3, 0x0100, 0x3430, 0x080c, 0x4c4a,
+	0x1150, 0x7078, 0xa005, 0x1138, 0x080c, 0x4a5c, 0x1170, 0xa085,
+	0x0001, 0x080c, 0x289c, 0x20a9, 0x0008, 0x2099, 0xbc8e, 0x26a0,
+	0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014, 0x080c,
+	0x4b55, 0x0010, 0x080c, 0x4673, 0x0005, 0x00f6, 0x7084, 0xa005,
+	0x0588, 0x2011, 0x4b23, 0x080c, 0x6a0e, 0xa086, 0x0014, 0x1540,
+	0x2079, 0xbc80, 0x7a30, 0xa296, 0x1105, 0x1510, 0x7834, 0x2011,
+	0x0100, 0xa21e, 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70b8, 0xa005,
+	0x1110, 0x70bb, 0x0001, 0x708f, 0x000a, 0x00b1, 0x0098, 0xa005,
+	0x1178, 0x7a38, 0xd2fc, 0x0128, 0x70b8, 0xa005, 0x1110, 0x70bb,
+	0x0001, 0x708b, 0x0000, 0x708f, 0x000e, 0x080c, 0x486e, 0x0010,
+	0x080c, 0x4b7b, 0x00fe, 0x0005, 0x708f, 0x000b, 0x2011, 0xbc0e,
+	0x22a0, 0x20a9, 0x0040, 0x2019, 0xffff, 0x43a4, 0x20a9, 0x0002,
+	0x2009, 0x0000, 0x41a4, 0x080c, 0x4bf9, 0x20a3, 0x1106, 0x20a3,
+	0x0000, 0x080c, 0x4c4a, 0x0118, 0x2013, 0x0000, 0x0020, 0x7054,
+	0xa085, 0x0100, 0x2012, 0x2298, 0x20a9, 0x0042, 0x53a6, 0x60c3,
+	0x0084, 0x080c, 0x4b55, 0x0005, 0x00f6, 0x7084, 0xa005, 0x01b0,
+	0x2011, 0x4b23, 0x080c, 0x6a0e, 0xa086, 0x0084, 0x1168, 0x2079,
+	0xbc80, 0x7a30, 0xa296, 0x1106, 0x1138, 0x7834, 0xa005, 0x1120,
+	0x708f, 0x000c, 0x0029, 0x0010, 0x080c, 0x4b7b, 0x00fe, 0x0005,
+	0x708f, 0x000d, 0x080c, 0x4bf9, 0x20a3, 0x1107, 0x20a3, 0x0000,
+	0x2099, 0xbc8e, 0x20a9, 0x0040, 0x53a6, 0x20a3, 0x0000, 0x20a3,
+	0x0000, 0x60c3, 0x0084, 0x080c, 0x4b55, 0x0005, 0x00f6, 0x7084,
+	0xa005, 0x01d0, 0x2011, 0x4b23, 0x080c, 0x6a0e, 0xa086, 0x0084,
+	0x1188, 0x2079, 0xbc80, 0x7a30, 0xa296, 0x1107, 0x1158, 0x7834,
+	0xa005, 0x1140, 0x708b, 0x0001, 0x080c, 0x4beb, 0x708f, 0x000e,
+	0x0029, 0x0010, 0x080c, 0x4b7b, 0x00fe, 0x0005, 0x708f, 0x000f,
+	0x7087, 0x0000, 0x608b, 0xbc85, 0x608f, 0xb5b5, 0x6043, 0x0005,
+	0x6043, 0x0004, 0x2009, 0x07d0, 0x2011, 0x4b23, 0x080c, 0x6a02,
+	0x0005, 0x7084, 0xa005, 0x0120, 0x2011, 0x4b23, 0x080c, 0x6a0e,
+	0x0005, 0x708f, 0x0011, 0x080c, 0x4c4a, 0x11a0, 0x7170, 0x81ff,
+	0x0188, 0x2009, 0x0000, 0x7074, 0xa084, 0x00ff, 0x080c, 0x2852,
+	0xa186, 0x007e, 0x0138, 0xa186, 0x0080, 0x0120, 0x2011, 0xbc8e,
+	0x080c, 0x4ae7, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099, 0xbc80,
+	0x20a1, 0x020b, 0x7484, 0xa480, 0x0018, 0xa080, 0x0007, 0xa084,
+	0x03f8, 0x8004, 0x20a8, 0x53a6, 0x60c3, 0x0014, 0x080c, 0x4b55,
+	0x0005, 0x00f6, 0x7084, 0xa005, 0x01f0, 0x2011, 0x4b23, 0x080c,
+	0x6a0e, 0xa086, 0x0014, 0x11a8, 0x2079, 0xbc80, 0x7a30, 0xa296,
+	0x1103, 0x1178, 0x7834, 0xa005, 0x1160, 0x7a38, 0xd2fc, 0x0128,
+	0x70b8, 0xa005, 0x1110, 0x70bb, 0x0001, 0x708f, 0x0012, 0x0029,
+	0x0010, 0x080c, 0x4b7b, 0x00fe, 0x0005, 0x708f, 0x0013, 0x080c,
+	0x4c05, 0x20a3, 0x1103, 0x20a3, 0x0000, 0x3430, 0x2011, 0xbc8e,
+	0x080c, 0x4c4a, 0x1160, 0x7078, 0xa005, 0x1148, 0x7150, 0xa186,
+	0xffff, 0x0128, 0x080c, 0x4ae7, 0x0110, 0x080c, 0x4c28, 0x20a9,
 	0x0008, 0x2298, 0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000,
-	0x60c3, 0x0014, 0x080c, 0x4b06, 0x0005, 0x00f6, 0x7084, 0xa005,
-	0x01f0, 0x2011, 0x4adc, 0x080c, 0x699c, 0xa086, 0x0014, 0x11a8,
-	0x2079, 0xbb80, 0x7a30, 0xa296, 0x1103, 0x1178, 0x7834, 0xa005,
+	0x60c3, 0x0014, 0x080c, 0x4b55, 0x0005, 0x00f6, 0x7084, 0xa005,
+	0x01f0, 0x2011, 0x4b23, 0x080c, 0x6a0e, 0xa086, 0x0014, 0x11a8,
+	0x2079, 0xbc80, 0x7a30, 0xa296, 0x1104, 0x1178, 0x7834, 0xa005,
 	0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70b8, 0xa005, 0x1110, 0x70bb,
-	0x0001, 0x708f, 0x0006, 0x0029, 0x0010, 0x080c, 0x4b1f, 0x00fe,
-	0x0005, 0x708f, 0x0007, 0x080c, 0x4b97, 0x20a3, 0x1104, 0x20a3,
-	0x0000, 0x3430, 0x2011, 0xbb8e, 0x080c, 0x4be8, 0x11a8, 0x7078,
-	0xa005, 0x1190, 0x7158, 0xa186, 0xffff, 0x0170, 0xa180, 0x2dc4,
-	0x200d, 0xa18c, 0xff00, 0x810f, 0x080c, 0x4aa0, 0x0128, 0x080c,
-	0x40d6, 0x0110, 0x080c, 0x2867, 0x20a9, 0x0008, 0x2298, 0x26a0,
+	0x0001, 0x708f, 0x0014, 0x0029, 0x0010, 0x080c, 0x4b7b, 0x00fe,
+	0x0005, 0x708f, 0x0015, 0x080c, 0x4c05, 0x20a3, 0x1104, 0x20a3,
+	0x0000, 0x3430, 0x2011, 0xbc8e, 0x080c, 0x4c4a, 0x11a8, 0x7078,
+	0xa005, 0x1190, 0x7158, 0xa186, 0xffff, 0x0170, 0xa180, 0x2df9,
+	0x200d, 0xa18c, 0xff00, 0x810f, 0x080c, 0x4ae7, 0x0128, 0x080c,
+	0x411d, 0x0110, 0x080c, 0x289c, 0x20a9, 0x0008, 0x2298, 0x26a0,
 	0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014, 0x080c,
-	0x4b06, 0x0005, 0x00f6, 0x7084, 0xa005, 0x01f0, 0x2011, 0x4adc,
-	0x080c, 0x699c, 0xa086, 0x0014, 0x11a8, 0x2079, 0xbb80, 0x7a30,
-	0xa296, 0x1104, 0x1178, 0x7834, 0xa005, 0x1160, 0x7a38, 0xd2fc,
-	0x0128, 0x70b8, 0xa005, 0x1110, 0x70bb, 0x0001, 0x708f, 0x0008,
-	0x0029, 0x0010, 0x080c, 0x4b1f, 0x00fe, 0x0005, 0x708f, 0x0009,
-	0x080c, 0x4b97, 0x20a3, 0x1105, 0x20a3, 0x0100, 0x3430, 0x080c,
-	0x4be8, 0x1150, 0x7078, 0xa005, 0x1138, 0x080c, 0x4a15, 0x1170,
-	0xa085, 0x0001, 0x080c, 0x2867, 0x20a9, 0x0008, 0x2099, 0xbb8e,
+	0x4b55, 0x0005, 0x00f6, 0x7084, 0xa005, 0x05b8, 0x2011, 0x4b23,
+	0x080c, 0x6a0e, 0xa086, 0x0014, 0x1570, 0x2079, 0xbc80, 0x7a30,
+	0xa296, 0x1105, 0x1540, 0x7834, 0x2011, 0x0100, 0xa21e, 0x1148,
+	0x7a38, 0xd2fc, 0x0128, 0x70b8, 0xa005, 0x1110, 0x70bb, 0x0001,
+	0x0060, 0xa005, 0x11c0, 0x7a38, 0xd2fc, 0x0128, 0x70b8, 0xa005,
+	0x1110, 0x70bb, 0x0001, 0x708b, 0x0000, 0x7a38, 0xd2f4, 0x0138,
+	0x2001, 0xb674, 0x2004, 0xd0a4, 0x1110, 0x70d7, 0x0008, 0x708f,
+	0x0016, 0x0029, 0x0010, 0x080c, 0x4b7b, 0x00fe, 0x0005, 0x20e1,
+	0x9080, 0x20e1, 0x4000, 0x2099, 0xbc80, 0x20a1, 0x020b, 0x20a9,
+	0x000e, 0x53a6, 0x3430, 0x2011, 0xbc8e, 0x708f, 0x0017, 0x080c,
+	0x4c4a, 0x1150, 0x7078, 0xa005, 0x1138, 0x080c, 0x4a5c, 0x1170,
+	0xa085, 0x0001, 0x080c, 0x289c, 0x20a9, 0x0008, 0x2099, 0xbc8e,
 	0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014,
-	0x080c, 0x4b06, 0x0010, 0x080c, 0x462c, 0x0005, 0x00f6, 0x7084,
-	0xa005, 0x0588, 0x2011, 0x4adc, 0x080c, 0x699c, 0xa086, 0x0014,
-	0x1540, 0x2079, 0xbb80, 0x7a30, 0xa296, 0x1105, 0x1510, 0x7834,
-	0x2011, 0x0100, 0xa21e, 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70b8,
-	0xa005, 0x1110, 0x70bb, 0x0001, 0x708f, 0x000a, 0x00b1, 0x0098,
-	0xa005, 0x1178, 0x7a38, 0xd2fc, 0x0128, 0x70b8, 0xa005, 0x1110,
-	0x70bb, 0x0001, 0x708b, 0x0000, 0x708f, 0x000e, 0x080c, 0x4827,
-	0x0010, 0x080c, 0x4b1f, 0x00fe, 0x0005, 0x708f, 0x000b, 0x2011,
-	0xbb0e, 0x22a0, 0x20a9, 0x0040, 0x2019, 0xffff, 0x43a4, 0x20a9,
-	0x0002, 0x2009, 0x0000, 0x41a4, 0x080c, 0x4b97, 0x20a3, 0x1106,
-	0x20a3, 0x0000, 0x080c, 0x4be8, 0x0118, 0x2013, 0x0000, 0x0020,
-	0x7054, 0xa085, 0x0100, 0x2012, 0x2298, 0x20a9, 0x0042, 0x53a6,
-	0x60c3, 0x0084, 0x080c, 0x4b06, 0x0005, 0x00f6, 0x7084, 0xa005,
-	0x01b0, 0x2011, 0x4adc, 0x080c, 0x699c, 0xa086, 0x0084, 0x1168,
-	0x2079, 0xbb80, 0x7a30, 0xa296, 0x1106, 0x1138, 0x7834, 0xa005,
-	0x1120, 0x708f, 0x000c, 0x0029, 0x0010, 0x080c, 0x4b1f, 0x00fe,
-	0x0005, 0x708f, 0x000d, 0x080c, 0x4b97, 0x20a3, 0x1107, 0x20a3,
-	0x0000, 0x2099, 0xbb8e, 0x20a9, 0x0040, 0x53a6, 0x20a3, 0x0000,
-	0x20a3, 0x0000, 0x60c3, 0x0084, 0x080c, 0x4b06, 0x0005, 0x00f6,
-	0x7084, 0xa005, 0x01d0, 0x2011, 0x4adc, 0x080c, 0x699c, 0xa086,
-	0x0084, 0x1188, 0x2079, 0xbb80, 0x7a30, 0xa296, 0x1107, 0x1158,
-	0x7834, 0xa005, 0x1140, 0x708b, 0x0001, 0x080c, 0x4b89, 0x708f,
-	0x000e, 0x0029, 0x0010, 0x080c, 0x4b1f, 0x00fe, 0x0005, 0x708f,
-	0x000f, 0x7087, 0x0000, 0x608b, 0xbc85, 0x608f, 0xb5b5, 0x6043,
-	0x0005, 0x6043, 0x0004, 0x2009, 0x07d0, 0x2011, 0x4adc, 0x080c,
-	0x6990, 0x0005, 0x7084, 0xa005, 0x0120, 0x2011, 0x4adc, 0x080c,
-	0x699c, 0x0005, 0x708f, 0x0011, 0x080c, 0x4be8, 0x11a0, 0x7170,
-	0x81ff, 0x0188, 0x2009, 0x0000, 0x7074, 0xa084, 0x00ff, 0x080c,
-	0x281d, 0xa186, 0x007e, 0x0138, 0xa186, 0x0080, 0x0120, 0x2011,
-	0xbb8e, 0x080c, 0x4aa0, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099,
-	0xbb80, 0x20a1, 0x020b, 0x7484, 0xa480, 0x0018, 0xa080, 0x0007,
-	0xa084, 0x03f8, 0x8004, 0x20a8, 0x53a6, 0x60c3, 0x0014, 0x080c,
-	0x4b06, 0x0005, 0x00f6, 0x7084, 0xa005, 0x01f0, 0x2011, 0x4adc,
-	0x080c, 0x699c, 0xa086, 0x0014, 0x11a8, 0x2079, 0xbb80, 0x7a30,
-	0xa296, 0x1103, 0x1178, 0x7834, 0xa005, 0x1160, 0x7a38, 0xd2fc,
-	0x0128, 0x70b8, 0xa005, 0x1110, 0x70bb, 0x0001, 0x708f, 0x0012,
-	0x0029, 0x0010, 0x080c, 0x4b1f, 0x00fe, 0x0005, 0x708f, 0x0013,
-	0x080c, 0x4ba3, 0x20a3, 0x1103, 0x20a3, 0x0000, 0x3430, 0x2011,
-	0xbb8e, 0x080c, 0x4be8, 0x1160, 0x7078, 0xa005, 0x1148, 0x7150,
-	0xa186, 0xffff, 0x0128, 0x080c, 0x4aa0, 0x0110, 0x080c, 0x4bc6,
-	0x20a9, 0x0008, 0x2298, 0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3,
-	0x0000, 0x60c3, 0x0014, 0x080c, 0x4b06, 0x0005, 0x00f6, 0x7084,
-	0xa005, 0x01f0, 0x2011, 0x4adc, 0x080c, 0x699c, 0xa086, 0x0014,
-	0x11a8, 0x2079, 0xbb80, 0x7a30, 0xa296, 0x1104, 0x1178, 0x7834,
-	0xa005, 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70b8, 0xa005, 0x1110,
-	0x70bb, 0x0001, 0x708f, 0x0014, 0x0029, 0x0010, 0x080c, 0x4b1f,
-	0x00fe, 0x0005, 0x708f, 0x0015, 0x080c, 0x4ba3, 0x20a3, 0x1104,
-	0x20a3, 0x0000, 0x3430, 0x2011, 0xbb8e, 0x080c, 0x4be8, 0x11a8,
-	0x7078, 0xa005, 0x1190, 0x7158, 0xa186, 0xffff, 0x0170, 0xa180,
-	0x2dc4, 0x200d, 0xa18c, 0xff00, 0x810f, 0x080c, 0x4aa0, 0x0128,
-	0x080c, 0x40d6, 0x0110, 0x080c, 0x2867, 0x20a9, 0x0008, 0x2298,
-	0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014,
-	0x080c, 0x4b06, 0x0005, 0x00f6, 0x7084, 0xa005, 0x05b8, 0x2011,
-	0x4adc, 0x080c, 0x699c, 0xa086, 0x0014, 0x1570, 0x2079, 0xbb80,
-	0x7a30, 0xa296, 0x1105, 0x1540, 0x7834, 0x2011, 0x0100, 0xa21e,
-	0x1148, 0x7a38, 0xd2fc, 0x0128, 0x70b8, 0xa005, 0x1110, 0x70bb,
-	0x0001, 0x0060, 0xa005, 0x11c0, 0x7a38, 0xd2fc, 0x0128, 0x70b8,
-	0xa005, 0x1110, 0x70bb, 0x0001, 0x708b, 0x0000, 0x7a38, 0xd2f4,
-	0x0138, 0x2001, 0xb574, 0x2004, 0xd0a4, 0x1110, 0x70d7, 0x0008,
-	0x708f, 0x0016, 0x0029, 0x0010, 0x080c, 0x4b1f, 0x00fe, 0x0005,
-	0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099, 0xbb80, 0x20a1, 0x020b,
-	0x20a9, 0x000e, 0x53a6, 0x3430, 0x2011, 0xbb8e, 0x708f, 0x0017,
-	0x080c, 0x4be8, 0x1150, 0x7078, 0xa005, 0x1138, 0x080c, 0x4a15,
-	0x1170, 0xa085, 0x0001, 0x080c, 0x2867, 0x20a9, 0x0008, 0x2099,
-	0xbb8e, 0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3,
-	0x0014, 0x080c, 0x4b06, 0x0010, 0x080c, 0x462c, 0x0005, 0x00f6,
-	0x7084, 0xa005, 0x01b0, 0x2011, 0x4adc, 0x080c, 0x699c, 0xa086,
-	0x0084, 0x1168, 0x2079, 0xbb80, 0x7a30, 0xa296, 0x1106, 0x1138,
-	0x7834, 0xa005, 0x1120, 0x708f, 0x0018, 0x0029, 0x0010, 0x080c,
-	0x4b1f, 0x00fe, 0x0005, 0x708f, 0x0019, 0x080c, 0x4ba3, 0x20a3,
-	0x1106, 0x20a3, 0x0000, 0x3430, 0x2099, 0xbb8e, 0x2039, 0xbb0e,
-	0x27a0, 0x20a9, 0x0040, 0x53a3, 0x080c, 0x4be8, 0x11e8, 0x2728,
-	0x2514, 0x8207, 0xa084, 0x00ff, 0x8000, 0x2018, 0xa294, 0x00ff,
-	0x8007, 0xa205, 0x202a, 0x7054, 0x2310, 0x8214, 0xa2a0, 0xbb0e,
-	0x2414, 0xa38c, 0x0001, 0x0118, 0xa294, 0xff00, 0x0018, 0xa294,
-	0x00ff, 0x8007, 0xa215, 0x2222, 0x2798, 0x26a0, 0x20a9, 0x0040,
-	0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0084, 0x080c,
-	0x4b06, 0x0005, 0x00f6, 0x7084, 0xa005, 0x01d0, 0x2011, 0x4adc,
-	0x080c, 0x699c, 0xa086, 0x0084, 0x1188, 0x2079, 0xbb80, 0x7a30,
-	0xa296, 0x1107, 0x1158, 0x7834, 0xa005, 0x1140, 0x708b, 0x0001,
-	0x080c, 0x4b89, 0x708f, 0x001a, 0x0029, 0x0010, 0x080c, 0x4b1f,
-	0x00fe, 0x0005, 0x708f, 0x001b, 0x20e1, 0x9080, 0x20e1, 0x4000,
-	0x2099, 0xbb80, 0x20a1, 0x020b, 0x7484, 0xa480, 0x0018, 0xa080,
-	0x0007, 0xa084, 0x03f8, 0x8004, 0x20a8, 0x53a6, 0x60c3, 0x0084,
-	0x080c, 0x4b06, 0x0005, 0x0005, 0x0005, 0x0086, 0x0096, 0x2029,
-	0xb553, 0x252c, 0x20a9, 0x0008, 0x2041, 0xbb0e, 0x28a0, 0x2099,
-	0xbb8e, 0x53a3, 0x20a9, 0x0008, 0x2011, 0x0007, 0xd5d4, 0x0110,
-	0x2011, 0x0000, 0x2800, 0xa200, 0x200c, 0xa1a6, 0xffff, 0x1148,
-	0xd5d4, 0x0110, 0x8210, 0x0008, 0x8211, 0x1f04, 0x4a2a, 0x0804,
-	0x4a98, 0x82ff, 0x1160, 0xd5d4, 0x0120, 0xa1a6, 0x3fff, 0x0d90,
-	0x0020, 0xa1a6, 0x3fff, 0x0904, 0x4a98, 0xa18d, 0xc000, 0x20a9,
-	0x0010, 0x2019, 0x0001, 0xd5d4, 0x0110, 0x2019, 0x0010, 0x2120,
-	0xd5d4, 0x0110, 0x8423, 0x0008, 0x8424, 0x1240, 0xd5d4, 0x0110,
-	0x8319, 0x0008, 0x8318, 0x1f04, 0x4a50, 0x04d0, 0x23a8, 0x2021,
-	0x0001, 0x8426, 0x8425, 0x1f04, 0x4a62, 0x2328, 0x8529, 0xa2be,
-	0x0007, 0x0158, 0x0006, 0x2039, 0x0007, 0x2200, 0xa73a, 0x000e,
-	0x27a8, 0xa5a8, 0x0010, 0x1f04, 0x4a71, 0x7552, 0xa5c8, 0x2dc4,
-	0x292d, 0xa5ac, 0x00ff, 0x7576, 0x6532, 0x6536, 0x0016, 0x2508,
-	0x080c, 0x2847, 0x001e, 0x60e7, 0x0000, 0x65ea, 0x2018, 0x2304,
-	0xa405, 0x201a, 0x707b, 0x0001, 0x26a0, 0x2898, 0x20a9, 0x0008,
-	0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0xa085, 0x0001, 0x0028,
-	0xa006, 0x0018, 0xa006, 0x080c, 0x1515, 0x009e, 0x008e, 0x0005,
-	0x2118, 0x2021, 0x0000, 0x2001, 0x0007, 0xa39a, 0x0010, 0x0218,
-	0x8420, 0x8001, 0x0cd0, 0x2118, 0x84ff, 0x0120, 0xa39a, 0x0010,
-	0x8421, 0x1de0, 0x2021, 0x0001, 0x83ff, 0x0118, 0x8423, 0x8319,
-	0x1de8, 0xa238, 0x2704, 0xa42c, 0x11b8, 0xa405, 0x203a, 0x7152,
-	0xa1a0, 0x2dc4, 0x242d, 0xa5ac, 0x00ff, 0x7576, 0x6532, 0x6536,
-	0x0016, 0x2508, 0x080c, 0x2847, 0x001e, 0x60e7, 0x0000, 0x65ea,
-	0x707b, 0x0001, 0xa084, 0x0000, 0x0005, 0x00e6, 0x2071, 0xb500,
-	0x707f, 0x0000, 0x00ee, 0x0005, 0x00e6, 0x00f6, 0x2079, 0x0100,
-	0x2071, 0x0140, 0x080c, 0x7d7a, 0x7004, 0xa084, 0x4000, 0x0120,
-	0x7003, 0x1000, 0x7003, 0x0000, 0x0126, 0x2091, 0x8000, 0x2071,
-	0xb523, 0x2073, 0x0000, 0x7840, 0x0026, 0x0016, 0x2009, 0x00f7,
-	0x080c, 0x4baf, 0x001e, 0xa094, 0x0010, 0xa285, 0x0080, 0x7842,
-	0x7a42, 0x002e, 0x012e, 0x00fe, 0x00ee, 0x0005, 0x0126, 0x2091,
-	0x8000, 0x2011, 0xb7ea, 0x2013, 0x0000, 0x7087, 0x0000, 0x012e,
-	0x20e1, 0x9080, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x080c, 0x7d71,
-	0x2009, 0x07d0, 0x2011, 0x4adc, 0x080c, 0x6a22, 0x0005, 0x0016,
-	0x0026, 0x00c6, 0x0126, 0x2091, 0x8000, 0x2011, 0x0003, 0x080c,
-	0x8075, 0x2011, 0x0002, 0x080c, 0x807f, 0x080c, 0x7f59, 0x0036,
-	0x2019, 0x0000, 0x080c, 0x7fe4, 0x003e, 0x2009, 0x00f7, 0x080c,
-	0x4baf, 0x2061, 0xb7f3, 0x601b, 0x0000, 0x601f, 0x0000, 0x2061,
-	0xb500, 0x6003, 0x0001, 0x2061, 0x0100, 0x6043, 0x0090, 0x6043,
-	0x0010, 0x2009, 0x002d, 0x2011, 0x4b54, 0x080c, 0x6990, 0x012e,
+	0x080c, 0x4b55, 0x0010, 0x080c, 0x4673, 0x0005, 0x00f6, 0x7084,
+	0xa005, 0x01b0, 0x2011, 0x4b23, 0x080c, 0x6a0e, 0xa086, 0x0084,
+	0x1168, 0x2079, 0xbc80, 0x7a30, 0xa296, 0x1106, 0x1138, 0x7834,
+	0xa005, 0x1120, 0x708f, 0x0018, 0x0029, 0x0010, 0x080c, 0x4b7b,
+	0x00fe, 0x0005, 0x708f, 0x0019, 0x080c, 0x4c05, 0x20a3, 0x1106,
+	0x20a3, 0x0000, 0x3430, 0x2099, 0xbc8e, 0x2039, 0xbc0e, 0x27a0,
+	0x20a9, 0x0040, 0x53a3, 0x080c, 0x4c4a, 0x11e8, 0x2728, 0x2514,
+	0x8207, 0xa084, 0x00ff, 0x8000, 0x2018, 0xa294, 0x00ff, 0x8007,
+	0xa205, 0x202a, 0x7054, 0x2310, 0x8214, 0xa2a0, 0xbc0e, 0x2414,
+	0xa38c, 0x0001, 0x0118, 0xa294, 0xff00, 0x0018, 0xa294, 0x00ff,
+	0x8007, 0xa215, 0x2222, 0x2798, 0x26a0, 0x20a9, 0x0040, 0x53a6,
+	0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0084, 0x080c, 0x4b55,
+	0x0005, 0x00f6, 0x7084, 0xa005, 0x01d0, 0x2011, 0x4b23, 0x080c,
+	0x6a0e, 0xa086, 0x0084, 0x1188, 0x2079, 0xbc80, 0x7a30, 0xa296,
+	0x1107, 0x1158, 0x7834, 0xa005, 0x1140, 0x708b, 0x0001, 0x080c,
+	0x4beb, 0x708f, 0x001a, 0x0029, 0x0010, 0x080c, 0x4b7b, 0x00fe,
+	0x0005, 0x708f, 0x001b, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099,
+	0xbc80, 0x20a1, 0x020b, 0x7484, 0xa480, 0x0018, 0xa080, 0x0007,
+	0xa084, 0x03f8, 0x8004, 0x20a8, 0x53a6, 0x60c3, 0x0084, 0x080c,
+	0x4b55, 0x0005, 0x0005, 0x0005, 0x0086, 0x0096, 0x2029, 0xb653,
+	0x252c, 0x20a9, 0x0008, 0x2041, 0xbc0e, 0x28a0, 0x2099, 0xbc8e,
+	0x53a3, 0x20a9, 0x0008, 0x2011, 0x0007, 0xd5d4, 0x0110, 0x2011,
+	0x0000, 0x2800, 0xa200, 0x200c, 0xa1a6, 0xffff, 0x1148, 0xd5d4,
+	0x0110, 0x8210, 0x0008, 0x8211, 0x1f04, 0x4a71, 0x0804, 0x4adf,
+	0x82ff, 0x1160, 0xd5d4, 0x0120, 0xa1a6, 0x3fff, 0x0d90, 0x0020,
+	0xa1a6, 0x3fff, 0x0904, 0x4adf, 0xa18d, 0xc000, 0x20a9, 0x0010,
+	0x2019, 0x0001, 0xd5d4, 0x0110, 0x2019, 0x0010, 0x2120, 0xd5d4,
+	0x0110, 0x8423, 0x0008, 0x8424, 0x1240, 0xd5d4, 0x0110, 0x8319,
+	0x0008, 0x8318, 0x1f04, 0x4a97, 0x04d0, 0x23a8, 0x2021, 0x0001,
+	0x8426, 0x8425, 0x1f04, 0x4aa9, 0x2328, 0x8529, 0xa2be, 0x0007,
+	0x0158, 0x0006, 0x2039, 0x0007, 0x2200, 0xa73a, 0x000e, 0x27a8,
+	0xa5a8, 0x0010, 0x1f04, 0x4ab8, 0x7552, 0xa5c8, 0x2df9, 0x292d,
+	0xa5ac, 0x00ff, 0x7576, 0x6532, 0x6536, 0x0016, 0x2508, 0x080c,
+	0x287c, 0x001e, 0x60e7, 0x0000, 0x65ea, 0x2018, 0x2304, 0xa405,
+	0x201a, 0x707b, 0x0001, 0x26a0, 0x2898, 0x20a9, 0x0008, 0x53a6,
+	0x20a3, 0x0000, 0x20a3, 0x0000, 0xa085, 0x0001, 0x0028, 0xa006,
+	0x0018, 0xa006, 0x080c, 0x151a, 0x009e, 0x008e, 0x0005, 0x2118,
+	0x2021, 0x0000, 0x2001, 0x0007, 0xa39a, 0x0010, 0x0218, 0x8420,
+	0x8001, 0x0cd0, 0x2118, 0x84ff, 0x0120, 0xa39a, 0x0010, 0x8421,
+	0x1de0, 0x2021, 0x0001, 0x83ff, 0x0118, 0x8423, 0x8319, 0x1de8,
+	0xa238, 0x2704, 0xa42c, 0x11b8, 0xa405, 0x203a, 0x7152, 0xa1a0,
+	0x2df9, 0x242d, 0xa5ac, 0x00ff, 0x7576, 0x6532, 0x6536, 0x0016,
+	0x2508, 0x080c, 0x287c, 0x001e, 0x60e7, 0x0000, 0x65ea, 0x707b,
+	0x0001, 0xa084, 0x0000, 0x0005, 0x00e6, 0x2071, 0xb600, 0x707f,
+	0x0000, 0x00ee, 0x0005, 0x00e6, 0x00f6, 0x2079, 0x0100, 0x2071,
+	0x0140, 0x080c, 0x4c61, 0x080c, 0x7df3, 0x7004, 0xa084, 0x4000,
+	0x0120, 0x7003, 0x1000, 0x7003, 0x0000, 0x0126, 0x2091, 0x8000,
+	0x2071, 0xb623, 0x2073, 0x0000, 0x7840, 0x0026, 0x0016, 0x2009,
+	0x00f7, 0x080c, 0x4c11, 0x001e, 0xa094, 0x0010, 0xa285, 0x0080,
+	0x7842, 0x7a42, 0x2009, 0x1388, 0x2011, 0x5a14, 0x080c, 0x6a94,
+	0x002e, 0x012e, 0x00fe, 0x00ee, 0x0005, 0x0126, 0x2091, 0x8000,
+	0x2011, 0xb8eb, 0x2013, 0x0000, 0x7087, 0x0000, 0x012e, 0x20e1,
+	0x9080, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x080c, 0x7dea, 0x6144,
+	0xd184, 0x0120, 0x718c, 0xa18d, 0x2000, 0x0018, 0x7180, 0xa18d,
+	0x1000, 0x2011, 0xb8bf, 0x2112, 0x2009, 0x07d0, 0x2011, 0x4b23,
+	0x080c, 0x6a94, 0x0005, 0x0016, 0x0026, 0x00c6, 0x0126, 0x2091,
+	0x8000, 0x2011, 0x0003, 0x080c, 0x80fc, 0x2011, 0x0002, 0x080c,
+	0x8106, 0x080c, 0x7fe0, 0x0036, 0x2019, 0x0000, 0x080c, 0x806b,
+	0x003e, 0x2009, 0x00f7, 0x080c, 0x4c11, 0x2061, 0xb8f4, 0x601b,
+	0x0000, 0x601f, 0x0000, 0x2061, 0xb600, 0x6003, 0x0001, 0x2061,
+	0x0100, 0x6043, 0x0090, 0x6043, 0x0010, 0x2009, 0xb8bf, 0x200b,
+	0x0000, 0x2009, 0x002d, 0x2011, 0x4bb4, 0x080c, 0x6a02, 0x012e,
 	0x00ce, 0x002e, 0x001e, 0x0005, 0x00e6, 0x0006, 0x0126, 0x2091,
-	0x8000, 0x2071, 0x0100, 0x080c, 0x7d7a, 0x2071, 0x0140, 0x7004,
-	0xa084, 0x4000, 0x0120, 0x7003, 0x1000, 0x7003, 0x0000, 0x080c,
-	0x5ad7, 0x01a8, 0x080c, 0x5af5, 0x1190, 0x2001, 0xb79e, 0x2003,
-	0xaaaa, 0x0016, 0x080c, 0x28eb, 0x2001, 0xb78f, 0x2102, 0x001e,
-	0x2001, 0xb79f, 0x2003, 0x0000, 0x080c, 0x5a07, 0x0030, 0x2001,
-	0x0001, 0x080c, 0x27c3, 0x080c, 0x4b1f, 0x012e, 0x000e, 0x00ee,
-	0x0005, 0x20a9, 0x0040, 0x20a1, 0xbcc0, 0x2099, 0xbb8e, 0x3304,
-	0x8007, 0x20a2, 0x9398, 0x94a0, 0x1f04, 0x4b8f, 0x0005, 0x20e1,
-	0x9080, 0x20e1, 0x4000, 0x2099, 0xbb00, 0x20a1, 0x020b, 0x20a9,
-	0x000c, 0x53a6, 0x0005, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099,
-	0xbb80, 0x20a1, 0x020b, 0x20a9, 0x000c, 0x53a6, 0x0005, 0x00c6,
-	0x0006, 0x2061, 0x0100, 0x810f, 0x2001, 0xb531, 0x2004, 0xa005,
-	0x1138, 0x2001, 0xb515, 0x2004, 0xa084, 0x00ff, 0xa105, 0x0010,
-	0xa185, 0x00f7, 0x604a, 0x000e, 0x00ce, 0x0005, 0x0016, 0x0046,
-	0x2001, 0xb553, 0x2004, 0xd0a4, 0x0158, 0xa006, 0x2020, 0x2009,
-	0x002a, 0x080c, 0xb0e8, 0x2001, 0xb50c, 0x200c, 0xc195, 0x2102,
-	0x2019, 0x002a, 0x2009, 0x0000, 0x080c, 0x2c6f, 0x004e, 0x001e,
-	0x0005, 0x080c, 0x4b1f, 0x708f, 0x0000, 0x7087, 0x0000, 0x0005,
-	0x0006, 0x2001, 0xb50c, 0x2004, 0xd09c, 0x0100, 0x000e, 0x0005,
-	0x0006, 0x0016, 0x0126, 0x2091, 0x8000, 0x2001, 0x0101, 0x200c,
-	0xa18d, 0x0006, 0x2102, 0x012e, 0x001e, 0x000e, 0x0005, 0x0156,
-	0x20a9, 0x00ff, 0x2009, 0xb635, 0xa006, 0x200a, 0x8108, 0x1f04,
-	0x4c05, 0x015e, 0x0005, 0x00d6, 0x0036, 0x0156, 0x0136, 0x0146,
-	0x2069, 0xb552, 0xa006, 0x6002, 0x6007, 0x0707, 0x600a, 0x600e,
-	0x6012, 0xa198, 0x2dc4, 0x231d, 0xa39c, 0x00ff, 0x6316, 0x20a9,
-	0x0004, 0xac98, 0x0006, 0x23a0, 0x40a4, 0x20a9, 0x0004, 0xac98,
-	0x000a, 0x23a0, 0x40a4, 0x603e, 0x6042, 0x604e, 0x6052, 0x6056,
-	0x605a, 0x605e, 0x6062, 0x6066, 0x606a, 0x606e, 0x6072, 0x6076,
-	0x607a, 0x607e, 0x6082, 0x6086, 0x608a, 0x608e, 0x6092, 0x6096,
-	0x609a, 0x609e, 0x60ae, 0x61a2, 0x00d6, 0x60a4, 0xa06d, 0x0110,
-	0x080c, 0x160f, 0x60a7, 0x0000, 0x60a8, 0xa06d, 0x0110, 0x080c,
-	0x160f, 0x60ab, 0x0000, 0x00de, 0xa006, 0x604a, 0x6810, 0x603a,
-	0x680c, 0x6046, 0x6814, 0xa084, 0x00ff, 0x6042, 0x014e, 0x013e,
-	0x015e, 0x003e, 0x00de, 0x0005, 0x0126, 0x2091, 0x8000, 0x6944,
-	0x6e48, 0xa684, 0x3fff, 0xa082, 0x4000, 0x1a04, 0x4d1a, 0xa18c,
-	0xff00, 0x810f, 0xa182, 0x00ff, 0x1a04, 0x4d1f, 0x2001, 0xb50c,
-	0x2004, 0xa084, 0x0003, 0x01c0, 0x2001, 0xb50c, 0x2004, 0xd084,
-	0x1904, 0x4d02, 0xa188, 0xb635, 0x2104, 0xa065, 0x0904, 0x4d02,
-	0x6004, 0xa084, 0x00ff, 0xa08e, 0x0006, 0x1904, 0x4d02, 0x6000,
-	0xd0c4, 0x0904, 0x4d02, 0x0068, 0xa188, 0xb635, 0x2104, 0xa065,
-	0x0904, 0x4ce6, 0x6004, 0xa084, 0x00ff, 0xa08e, 0x0006, 0x1904,
-	0x4ceb, 0x60a4, 0xa00d, 0x0118, 0x080c, 0x51d4, 0x05d0, 0x60a8,
-	0xa00d, 0x0188, 0x080c, 0x521f, 0x1170, 0x694c, 0xd1fc, 0x1118,
-	0x080c, 0x4ede, 0x0448, 0x080c, 0x4e8d, 0x694c, 0xd1ec, 0x1520,
-	0x080c, 0x50c6, 0x0408, 0x694c, 0xa184, 0xa000, 0x0178, 0xd1ec,
-	0x0140, 0xd1fc, 0x0118, 0x080c, 0x50d5, 0x0028, 0x080c, 0x50d5,
-	0x0028, 0xd1fc, 0x0118, 0x080c, 0x4e8d, 0x0070, 0x6050, 0xa00d,
-	0x0130, 0x2d00, 0x200a, 0x6803, 0x0000, 0x6052, 0x0028, 0x2d00,
-	0x6052, 0x604e, 0x6803, 0x0000, 0x080c, 0x6caa, 0xa006, 0x012e,
-	0x0005, 0x2001, 0x0005, 0x2009, 0x0000, 0x04e8, 0x2001, 0x0028,
-	0x2009, 0x0000, 0x04c0, 0xa082, 0x0006, 0x12a0, 0x2001, 0xb535,
-	0x2004, 0xd0ac, 0x1160, 0x60a0, 0xd0bc, 0x1148, 0x6100, 0xd1fc,
-	0x0904, 0x4ca1, 0x2001, 0x0029, 0x2009, 0x1000, 0x0420, 0x2001,
-	0x0028, 0x00a8, 0x2009, 0xb50c, 0x210c, 0xd18c, 0x0118, 0x2001,
-	0x0004, 0x0068, 0xd184, 0x0118, 0x2001, 0x0004, 0x0040, 0x2001,
-	0x0029, 0x6100, 0xd1fc, 0x0118, 0x2009, 0x1000, 0x0060, 0x2009,
-	0x0000, 0x0048, 0x2001, 0x0029, 0x2009, 0x0000, 0x0020, 0x2001,
-	0x0029, 0x2009, 0x0000, 0xa005, 0x012e, 0x0005, 0x00e6, 0x0126,
-	0x2091, 0x8000, 0x6844, 0x8007, 0xa084, 0x00ff, 0x2008, 0xa182,
-	0x00ff, 0x1a04, 0x4d79, 0xa188, 0xb635, 0x2104, 0xa065, 0x01c0,
-	0x6004, 0xa084, 0x00ff, 0xa08e, 0x0006, 0x11a8, 0x2c70, 0x080c,
-	0x85c7, 0x05e8, 0x2e00, 0x601a, 0x2d00, 0x6012, 0x600b, 0xffff,
-	0x601f, 0x000a, 0x2009, 0x0003, 0x080c, 0x864c, 0xa006, 0x0460,
-	0x2001, 0x0028, 0x0440, 0xa082, 0x0006, 0x1298, 0x2001, 0xb535,
-	0x2004, 0xd0ac, 0x1158, 0x60a0, 0xd0bc, 0x1140, 0x6100, 0xd1fc,
-	0x09e8, 0x2001, 0x0029, 0x2009, 0x1000, 0x00a8, 0x2001, 0x0028,
-	0x0090, 0x2009, 0xb50c, 0x210c, 0xd18c, 0x0118, 0x2001, 0x0004,
-	0x0050, 0xd184, 0x0118, 0x2001, 0x0004, 0x0028, 0x2001, 0x0029,
-	0x0010, 0x2001, 0x0029, 0xa005, 0x012e, 0x00ee, 0x0005, 0x2001,
-	0x002c, 0x0cc8, 0x00f6, 0x00e6, 0x0126, 0x2091, 0x8000, 0x2011,
-	0x0000, 0x2079, 0xb500, 0x6944, 0xa18c, 0xff00, 0x810f, 0xa182,
-	0x00ff, 0x1a04, 0x4e44, 0x080c, 0x4fa9, 0x11a0, 0x6004, 0xa084,
-	0x00ff, 0xa082, 0x0006, 0x1270, 0x6864, 0xa0c6, 0x006f, 0x0150,
-	0x2001, 0xb535, 0x2004, 0xd0ac, 0x1904, 0x4e2d, 0x60a0, 0xd0bc,
-	0x1904, 0x4e2d, 0x6864, 0xa0c6, 0x006f, 0x0118, 0x2008, 0x0804,
-	0x4df6, 0x6968, 0x2140, 0xa18c, 0xff00, 0x810f, 0x78d4, 0xd0ac,
-	0x1118, 0xa182, 0x0080, 0x06d0, 0xa182, 0x00ff, 0x16b8, 0x6a70,
-	0x6b6c, 0x7870, 0xa306, 0x1160, 0x7874, 0xa24e, 0x1118, 0x2208,
-	0x2310, 0x0460, 0xa9cc, 0xff00, 0x1118, 0x2208, 0x2310, 0x0430,
-	0x080c, 0x3dc5, 0x2c70, 0x0550, 0x2009, 0x0000, 0x2011, 0x0000,
-	0xa0c6, 0x4000, 0x1160, 0x0006, 0x2e60, 0x080c, 0x524a, 0x1108,
-	0xc185, 0x7000, 0xd0bc, 0x0108, 0xc18d, 0x000e, 0x0088, 0xa0c6,
-	0x4007, 0x1110, 0x2408, 0x0060, 0xa0c6, 0x4008, 0x1118, 0x2708,
-	0x2610, 0x0030, 0xa0c6, 0x4009, 0x1108, 0x0010, 0x2001, 0x4006,
-	0x6866, 0x696a, 0x6a6e, 0x2001, 0x0030, 0x0450, 0x080c, 0x85c7,
-	0x1138, 0x2001, 0x4005, 0x2009, 0x0003, 0x2011, 0x0000, 0x0c80,
-	0x2e00, 0x601a, 0x080c, 0xa027, 0x2d00, 0x6012, 0x601f, 0x0001,
-	0x6838, 0xd88c, 0x0108, 0xc0f5, 0x683a, 0x0126, 0x2091, 0x8000,
-	0x080c, 0x2c9c, 0x012e, 0x2001, 0x0000, 0x080c, 0x4eeb, 0x2001,
-	0x0002, 0x080c, 0x4efd, 0x2009, 0x0002, 0x080c, 0x864c, 0xa006,
-	0xa005, 0x012e, 0x00ee, 0x00fe, 0x0005, 0x2001, 0x0028, 0x2009,
-	0x0000, 0x0cb0, 0x2009, 0xb50c, 0x210c, 0xd18c, 0x0118, 0x2001,
-	0x0004, 0x0038, 0xd184, 0x0118, 0x2001, 0x0004, 0x0010, 0x2001,
-	0x0029, 0x2009, 0x0000, 0x0c20, 0x2001, 0x0029, 0x2009, 0x0000,
-	0x08f8, 0x6944, 0x6e48, 0xa684, 0x3fff, 0xa082, 0x4000, 0x16b8,
-	0xa18c, 0xff00, 0x810f, 0xa182, 0x00ff, 0x12e0, 0xa188, 0xb635,
-	0x2104, 0xa065, 0x01b8, 0x6004, 0xa084, 0x00ff, 0xa08e, 0x0006,
-	0x11b0, 0x684c, 0xd0ec, 0x0120, 0x080c, 0x50d5, 0x0431, 0x0030,
-	0x0421, 0x684c, 0xd0fc, 0x0110, 0x080c, 0x50c6, 0x080c, 0x5113,
-	0xa006, 0x00c8, 0x2001, 0x0028, 0x2009, 0x0000, 0x00a0, 0xa082,
-	0x0006, 0x1240, 0x6100, 0xd1fc, 0x0d20, 0x2001, 0x0029, 0x2009,
-	0x1000, 0x0048, 0x2001, 0x0029, 0x2009, 0x0000, 0x0020, 0x2001,
-	0x0029, 0x2009, 0x0000, 0xa005, 0x0005, 0x0126, 0x2091, 0x8000,
-	0x6050, 0xa00d, 0x0138, 0x2d00, 0x200a, 0x6803, 0x0000, 0x6052,
-	0x012e, 0x0005, 0x2d00, 0x6052, 0x604e, 0x6803, 0x0000, 0x0cc0,
-	0x0126, 0x2091, 0x8000, 0x604c, 0xa005, 0x0170, 0x00e6, 0x2071,
-	0xb7e0, 0x7004, 0xa086, 0x0002, 0x0168, 0x00ee, 0x604c, 0x6802,
-	0x2d00, 0x604e, 0x012e, 0x0005, 0x2d00, 0x6052, 0x604e, 0x6803,
-	0x0000, 0x0cc0, 0x701c, 0xac06, 0x1d80, 0x604c, 0x2070, 0x7000,
-	0x6802, 0x2d00, 0x7002, 0x00ee, 0x012e, 0x0005, 0x0126, 0x2091,
-	0x8000, 0x604c, 0xa06d, 0x0130, 0x6800, 0xa005, 0x1108, 0x6052,
-	0x604e, 0xad05, 0x012e, 0x0005, 0x604c, 0xa06d, 0x0130, 0x6800,
-	0xa005, 0x1108, 0x6052, 0x604e, 0xad05, 0x0005, 0x6803, 0x0000,
-	0x6084, 0xa00d, 0x0120, 0x2d00, 0x200a, 0x6086, 0x0005, 0x2d00,
-	0x6086, 0x6082, 0x0cd8, 0x0126, 0x00c6, 0x0026, 0x2091, 0x8000,
-	0x6218, 0x2260, 0x6200, 0xa005, 0x0110, 0xc285, 0x0008, 0xc284,
-	0x6202, 0x002e, 0x00ce, 0x012e, 0x0005, 0x0126, 0x00c6, 0x2091,
-	0x8000, 0x6218, 0x2260, 0x6204, 0x0006, 0xa086, 0x0006, 0x1180,
-	0x609c, 0xd0ac, 0x0168, 0x2001, 0xb553, 0x2004, 0xd0a4, 0x0140,
-	0xa284, 0xff00, 0x8007, 0xa086, 0x0007, 0x1110, 0x2011, 0x0600,
-	0x000e, 0xa294, 0xff00, 0xa215, 0x6206, 0x0006, 0xa086, 0x0006,
-	0x1128, 0x6290, 0x82ff, 0x1110, 0x080c, 0x1515, 0x000e, 0x00ce,
-	0x012e, 0x0005, 0x0126, 0x00c6, 0x2091, 0x8000, 0x6218, 0x2260,
-	0x6204, 0x0006, 0xa086, 0x0006, 0x1178, 0x609c, 0xd0a4, 0x0160,
-	0x2001, 0xb553, 0x2004, 0xd0ac, 0x1138, 0xa284, 0x00ff, 0xa086,
-	0x0007, 0x1110, 0x2011, 0x0006, 0x000e, 0xa294, 0x00ff, 0x8007,
-	0xa215, 0x6206, 0x00ce, 0x012e, 0x0005, 0x0026, 0xa182, 0x00ff,
-	0x0218, 0xa085, 0x0001, 0x00b0, 0xa190, 0xb635, 0x2204, 0xa065,
-	0x1180, 0x0016, 0x00d6, 0x080c, 0x15df, 0x2d60, 0x00de, 0x001e,
-	0x0d80, 0x2c00, 0x2012, 0x60a7, 0x0000, 0x60ab, 0x0000, 0x080c,
-	0x4c0b, 0xa006, 0x002e, 0x0005, 0x0126, 0x2091, 0x8000, 0x0026,
-	0xa182, 0x00ff, 0x0218, 0xa085, 0x0001, 0x0480, 0x00d6, 0xa190,
-	0xb635, 0x2204, 0xa06d, 0x0540, 0x2013, 0x0000, 0x00d6, 0x00c6,
-	0x2d60, 0x60a4, 0xa06d, 0x0110, 0x080c, 0x160f, 0x60a8, 0xa06d,
-	0x0110, 0x080c, 0x160f, 0x00ce, 0x00de, 0x00d6, 0x00c6, 0x68ac,
-	0x2060, 0x8cff, 0x0168, 0x600c, 0x0006, 0x6010, 0x2068, 0x080c,
-	0x9c5a, 0x0110, 0x080c, 0x161f, 0x080c, 0x861d, 0x00ce, 0x0c88,
-	0x00ce, 0x00de, 0x080c, 0x160f, 0x00de, 0xa006, 0x002e, 0x012e,
-	0x0005, 0x0016, 0xa182, 0x00ff, 0x0218, 0xa085, 0x0001, 0x0030,
-	0xa188, 0xb635, 0x2104, 0xa065, 0x0dc0, 0xa006, 0x001e, 0x0005,
-	0x00d6, 0x0156, 0x0136, 0x0146, 0x600b, 0x0000, 0x600f, 0x0000,
-	0x6000, 0xc08c, 0x6002, 0x080c, 0x5acf, 0x1558, 0x60a0, 0xa086,
-	0x007e, 0x2069, 0xbb90, 0x0130, 0x2001, 0xb535, 0x2004, 0xd0ac,
-	0x1500, 0x0098, 0x2d04, 0xd0e4, 0x01e0, 0x00d6, 0x2069, 0xbb8e,
-	0x00c6, 0x2061, 0xb7b2, 0x6810, 0x2062, 0x6814, 0x6006, 0x6818,
-	0x600a, 0x681c, 0x600e, 0x00ce, 0x00de, 0x8d69, 0x2d04, 0x2069,
-	0x0140, 0xa005, 0x1110, 0x2001, 0x0001, 0x6886, 0x2069, 0xb500,
-	0x68a6, 0x2069, 0xbb8e, 0x6808, 0x605e, 0x6810, 0x6062, 0x6138,
-	0xa10a, 0x0208, 0x603a, 0x6814, 0x6066, 0x2099, 0xbb96, 0xac88,
-	0x000a, 0x21a0, 0x20a9, 0x0004, 0x53a3, 0x2099, 0xbb9a, 0xac88,
-	0x0006, 0x21a0, 0x20a9, 0x0004, 0x53a3, 0x2069, 0xbbae, 0x6808,
-	0x606a, 0x690c, 0x616e, 0x6810, 0x6072, 0x6818, 0x6076, 0x60a0,
-	0xa086, 0x007e, 0x1120, 0x2069, 0xbb8e, 0x690c, 0x616e, 0xa182,
-	0x0211, 0x1218, 0x2009, 0x0008, 0x0400, 0xa182, 0x0259, 0x1218,
-	0x2009, 0x0007, 0x00d0, 0xa182, 0x02c1, 0x1218, 0x2009, 0x0006,
-	0x00a0, 0xa182, 0x0349, 0x1218, 0x2009, 0x0005, 0x0070, 0xa182,
-	0x0421, 0x1218, 0x2009, 0x0004, 0x0040, 0xa182, 0x0581, 0x1218,
-	0x2009, 0x0003, 0x0010, 0x2009, 0x0002, 0x6192, 0x014e, 0x013e,
-	0x015e, 0x00de, 0x0005, 0x0016, 0x0026, 0x00e6, 0x2071, 0xbb8d,
-	0x2e04, 0x6896, 0x2071, 0xbb8e, 0x7004, 0x689a, 0x701c, 0x689e,
-	0x6a00, 0x2009, 0xb572, 0x210c, 0xd0bc, 0x0120, 0xd1ec, 0x0110,
-	0xc2ad, 0x0008, 0xc2ac, 0xd0c4, 0x0120, 0xd1e4, 0x0110, 0xc2bd,
-	0x0008, 0xc2bc, 0x6a02, 0x00ee, 0x002e, 0x001e, 0x0005, 0x00d6,
-	0x0126, 0x2091, 0x8000, 0x60a4, 0xa06d, 0x01c0, 0x6900, 0x81ff,
-	0x1540, 0x6a04, 0xa282, 0x0010, 0x1648, 0xad88, 0x0004, 0x20a9,
-	0x0010, 0x2104, 0xa086, 0xffff, 0x0128, 0x8108, 0x1f04, 0x5081,
-	0x080c, 0x1515, 0x260a, 0x8210, 0x6a06, 0x0098, 0x080c, 0x15f8,
-	0x01a8, 0x2d00, 0x60a6, 0x6803, 0x0000, 0xad88, 0x0004, 0x20a9,
-	0x0010, 0x200b, 0xffff, 0x8108, 0x1f04, 0x5099, 0x6807, 0x0001,
-	0x6e12, 0xa085, 0x0001, 0x012e, 0x00de, 0x0005, 0xa006, 0x0cd8,
-	0x0126, 0x2091, 0x8000, 0x00d6, 0x60a4, 0xa00d, 0x01a0, 0x2168,
-	0x6800, 0xa005, 0x1160, 0x080c, 0x51d4, 0x1168, 0x200b, 0xffff,
-	0x6804, 0xa08a, 0x0002, 0x0218, 0x8001, 0x6806, 0x0020, 0x080c,
-	0x160f, 0x60a7, 0x0000, 0x00de, 0x012e, 0x0005, 0x0126, 0x2091,
-	0x8000, 0x080c, 0x5232, 0x0010, 0x080c, 0x4e8d, 0x080c, 0x514c,
-	0x1dd8, 0x080c, 0x5113, 0x012e, 0x0005, 0x00d6, 0x0126, 0x2091,
-	0x8000, 0x60a8, 0xa06d, 0x01c0, 0x6950, 0x81ff, 0x1540, 0x6a54,
-	0xa282, 0x0010, 0x1670, 0xad88, 0x0018, 0x20a9, 0x0010, 0x2104,
-	0xa086, 0xffff, 0x0128, 0x8108, 0x1f04, 0x50e7, 0x080c, 0x1515,
-	0x260a, 0x8210, 0x6a56, 0x0098, 0x080c, 0x15f8, 0x01d0, 0x2d00,
-	0x60aa, 0x6853, 0x0000, 0xad88, 0x0018, 0x20a9, 0x0010, 0x200b,
-	0xffff, 0x8108, 0x1f04, 0x50ff, 0x6857, 0x0001, 0x6e62, 0x0010,
-	0x080c, 0x4ede, 0x0089, 0x1de0, 0xa085, 0x0001, 0x012e, 0x00de,
-	0x0005, 0xa006, 0x0cd8, 0x0126, 0x2091, 0x8000, 0x080c, 0x6caa,
-	0x012e, 0x0005, 0xa01e, 0x0010, 0x2019, 0x0001, 0xa00e, 0x0126,
-	0x2091, 0x8000, 0x604c, 0x2068, 0x6000, 0xd0dc, 0x1170, 0x8dff,
-	0x01f8, 0x83ff, 0x0120, 0x6848, 0xa606, 0x0158, 0x0030, 0x683c,
-	0xa406, 0x1118, 0x6840, 0xa506, 0x0120, 0x2d08, 0x6800, 0x2068,
-	0x0c70, 0x080c, 0x811e, 0x6a00, 0x604c, 0xad06, 0x1110, 0x624e,
-	0x0018, 0xa180, 0x0000, 0x2202, 0x82ff, 0x1110, 0x6152, 0x8dff,
-	0x012e, 0x0005, 0xa01e, 0x0010, 0x2019, 0x0001, 0xa00e, 0x6080,
-	0x2068, 0x8dff, 0x01e8, 0x83ff, 0x0120, 0x6848, 0xa606, 0x0158,
+	0x8000, 0x080c, 0x4c61, 0x2071, 0x0100, 0x080c, 0x7df3, 0x2071,
+	0x0140, 0x7004, 0xa084, 0x4000, 0x0120, 0x7003, 0x1000, 0x7003,
+	0x0000, 0x080c, 0x5b49, 0x01a8, 0x080c, 0x5b67, 0x1190, 0x2001,
+	0xb89e, 0x2003, 0xaaaa, 0x0016, 0x080c, 0x2920, 0x2001, 0xb88f,
+	0x2102, 0x001e, 0x2001, 0xb89f, 0x2003, 0x0000, 0x080c, 0x5a79,
+	0x0030, 0x2001, 0x0001, 0x080c, 0x27f8, 0x080c, 0x4b7b, 0x012e,
+	0x000e, 0x00ee, 0x0005, 0x20a9, 0x0040, 0x20a1, 0xbdc0, 0x2099,
+	0xbc8e, 0x3304, 0x8007, 0x20a2, 0x9398, 0x94a0, 0x1f04, 0x4bf1,
+	0x0005, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099, 0xbc00, 0x20a1,
+	0x020b, 0x20a9, 0x000c, 0x53a6, 0x0005, 0x20e1, 0x9080, 0x20e1,
+	0x4000, 0x2099, 0xbc80, 0x20a1, 0x020b, 0x20a9, 0x000c, 0x53a6,
+	0x0005, 0x00c6, 0x0006, 0x2061, 0x0100, 0x810f, 0x2001, 0xb631,
+	0x2004, 0xa005, 0x1138, 0x2001, 0xb615, 0x2004, 0xa084, 0x00ff,
+	0xa105, 0x0010, 0xa185, 0x00f7, 0x604a, 0x000e, 0x00ce, 0x0005,
+	0x0016, 0x0046, 0x2001, 0xb653, 0x2004, 0xd0a4, 0x0158, 0xa006,
+	0x2020, 0x2009, 0x002a, 0x080c, 0xb1a4, 0x2001, 0xb60c, 0x200c,
+	0xc195, 0x2102, 0x2019, 0x002a, 0x2009, 0x0000, 0x080c, 0x2ca4,
+	0x004e, 0x001e, 0x0005, 0x080c, 0x4b7b, 0x708f, 0x0000, 0x7087,
+	0x0000, 0x0005, 0x0006, 0x2001, 0xb60c, 0x2004, 0xd09c, 0x0100,
+	0x000e, 0x0005, 0x0006, 0x0016, 0x0126, 0x2091, 0x8000, 0x2001,
+	0x0101, 0x200c, 0xa18d, 0x0006, 0x2102, 0x012e, 0x001e, 0x000e,
+	0x0005, 0x2001, 0xb60d, 0x2004, 0xd0bc, 0x0158, 0x0026, 0x0036,
+	0x2011, 0x8017, 0x2001, 0xb8bf, 0x201c, 0x080c, 0x3f13, 0x003e,
+	0x002e, 0x0005, 0x0156, 0x20a9, 0x00ff, 0x2009, 0xb735, 0xa006,
+	0x200a, 0x8108, 0x1f04, 0x4c78, 0x015e, 0x0005, 0x00d6, 0x0036,
+	0x0156, 0x0136, 0x0146, 0x2069, 0xb652, 0xa006, 0x6002, 0x6007,
+	0x0707, 0x600a, 0x600e, 0x6012, 0xa198, 0x2df9, 0x231d, 0xa39c,
+	0x00ff, 0x6316, 0x20a9, 0x0004, 0xac98, 0x0006, 0x23a0, 0x40a4,
+	0x20a9, 0x0004, 0xac98, 0x000a, 0x23a0, 0x40a4, 0x603e, 0x6042,
+	0x604e, 0x6052, 0x6056, 0x605a, 0x605e, 0x6062, 0x6066, 0x606a,
+	0x606e, 0x6072, 0x6076, 0x607a, 0x607e, 0x6082, 0x6086, 0x608a,
+	0x608e, 0x6092, 0x6096, 0x609a, 0x609e, 0x60ae, 0x61a2, 0x00d6,
+	0x60a4, 0xa06d, 0x0110, 0x080c, 0x1614, 0x60a7, 0x0000, 0x60a8,
+	0xa06d, 0x0110, 0x080c, 0x1614, 0x60ab, 0x0000, 0x00de, 0xa006,
+	0x604a, 0x6810, 0x603a, 0x680c, 0x6046, 0x6814, 0xa084, 0x00ff,
+	0x6042, 0x014e, 0x013e, 0x015e, 0x003e, 0x00de, 0x0005, 0x0126,
+	0x2091, 0x8000, 0x6944, 0x6e48, 0xa684, 0x3fff, 0xa082, 0x4000,
+	0x1a04, 0x4d8c, 0xa18c, 0xff00, 0x810f, 0xa182, 0x00ff, 0x1a04,
+	0x4d91, 0x2001, 0xb60c, 0x2004, 0xa084, 0x0003, 0x01c0, 0x2001,
+	0xb60c, 0x2004, 0xd084, 0x1904, 0x4d74, 0xa188, 0xb735, 0x2104,
+	0xa065, 0x0904, 0x4d74, 0x6004, 0xa084, 0x00ff, 0xa08e, 0x0006,
+	0x1904, 0x4d74, 0x6000, 0xd0c4, 0x0904, 0x4d74, 0x0068, 0xa188,
+	0xb735, 0x2104, 0xa065, 0x0904, 0x4d59, 0x6004, 0xa084, 0x00ff,
+	0xa08e, 0x0006, 0x1904, 0x4d5e, 0x60a4, 0xa00d, 0x0118, 0x080c,
+	0x5246, 0x05d0, 0x60a8, 0xa00d, 0x0188, 0x080c, 0x5291, 0x1170,
+	0x694c, 0xd1fc, 0x1118, 0x080c, 0x4f50, 0x0448, 0x080c, 0x4eff,
+	0x694c, 0xd1ec, 0x1520, 0x080c, 0x5138, 0x0408, 0x694c, 0xa184,
+	0xa000, 0x0178, 0xd1ec, 0x0140, 0xd1fc, 0x0118, 0x080c, 0x5147,
+	0x0028, 0x080c, 0x5147, 0x0028, 0xd1fc, 0x0118, 0x080c, 0x4eff,
+	0x0070, 0x6050, 0xa00d, 0x0130, 0x2d00, 0x200a, 0x6803, 0x0000,
+	0x6052, 0x0028, 0x2d00, 0x6052, 0x604e, 0x6803, 0x0000, 0x080c,
+	0x6d1c, 0xa006, 0x012e, 0x0005, 0x2001, 0x0005, 0x2009, 0x0000,
+	0x04e0, 0x2001, 0x0028, 0x2009, 0x0000, 0x04b8, 0xa082, 0x0006,
+	0x1298, 0x2001, 0xb635, 0x2004, 0xd0ac, 0x1158, 0x60a0, 0xd0bc,
+	0x1140, 0x6100, 0xd1fc, 0x0128, 0x2001, 0x0029, 0x2009, 0x1000,
+	0x0420, 0x2001, 0x0028, 0x00a8, 0x2009, 0xb60c, 0x210c, 0xd18c,
+	0x0118, 0x2001, 0x0004, 0x0068, 0xd184, 0x0118, 0x2001, 0x0004,
+	0x0040, 0x2001, 0x0029, 0x6100, 0xd1fc, 0x0118, 0x2009, 0x1000,
+	0x0060, 0x2009, 0x0000, 0x0048, 0x2001, 0x0029, 0x2009, 0x0000,
+	0x0020, 0x2001, 0x0029, 0x2009, 0x0000, 0xa005, 0x012e, 0x0005,
+	0x00e6, 0x0126, 0x2091, 0x8000, 0x6844, 0x8007, 0xa084, 0x00ff,
+	0x2008, 0xa182, 0x00ff, 0x1a04, 0x4deb, 0xa188, 0xb735, 0x2104,
+	0xa065, 0x01c0, 0x6004, 0xa084, 0x00ff, 0xa08e, 0x0006, 0x11a8,
+	0x2c70, 0x080c, 0x864e, 0x05e8, 0x2e00, 0x601a, 0x2d00, 0x6012,
+	0x600b, 0xffff, 0x601f, 0x000a, 0x2009, 0x0003, 0x080c, 0x86d3,
+	0xa006, 0x0460, 0x2001, 0x0028, 0x0440, 0xa082, 0x0006, 0x1298,
+	0x2001, 0xb635, 0x2004, 0xd0ac, 0x1158, 0x60a0, 0xd0bc, 0x1140,
+	0x6100, 0xd1fc, 0x09e8, 0x2001, 0x0029, 0x2009, 0x1000, 0x00a8,
+	0x2001, 0x0028, 0x0090, 0x2009, 0xb60c, 0x210c, 0xd18c, 0x0118,
+	0x2001, 0x0004, 0x0050, 0xd184, 0x0118, 0x2001, 0x0004, 0x0028,
+	0x2001, 0x0029, 0x0010, 0x2001, 0x0029, 0xa005, 0x012e, 0x00ee,
+	0x0005, 0x2001, 0x002c, 0x0cc8, 0x00f6, 0x00e6, 0x0126, 0x2091,
+	0x8000, 0x2011, 0x0000, 0x2079, 0xb600, 0x6944, 0xa18c, 0xff00,
+	0x810f, 0xa182, 0x00ff, 0x1a04, 0x4eb6, 0x080c, 0x501b, 0x11a0,
+	0x6004, 0xa084, 0x00ff, 0xa082, 0x0006, 0x1270, 0x6864, 0xa0c6,
+	0x006f, 0x0150, 0x2001, 0xb635, 0x2004, 0xd0ac, 0x1904, 0x4e9f,
+	0x60a0, 0xd0bc, 0x1904, 0x4e9f, 0x6864, 0xa0c6, 0x006f, 0x0118,
+	0x2008, 0x0804, 0x4e68, 0x6968, 0x2140, 0xa18c, 0xff00, 0x810f,
+	0x78d4, 0xd0ac, 0x1118, 0xa182, 0x0080, 0x06d0, 0xa182, 0x00ff,
+	0x16b8, 0x6a70, 0x6b6c, 0x7870, 0xa306, 0x1160, 0x7874, 0xa24e,
+	0x1118, 0x2208, 0x2310, 0x0460, 0xa9cc, 0xff00, 0x1118, 0x2208,
+	0x2310, 0x0430, 0x080c, 0x3e0c, 0x2c70, 0x0550, 0x2009, 0x0000,
+	0x2011, 0x0000, 0xa0c6, 0x4000, 0x1160, 0x0006, 0x2e60, 0x080c,
+	0x52bc, 0x1108, 0xc185, 0x7000, 0xd0bc, 0x0108, 0xc18d, 0x000e,
+	0x0088, 0xa0c6, 0x4007, 0x1110, 0x2408, 0x0060, 0xa0c6, 0x4008,
+	0x1118, 0x2708, 0x2610, 0x0030, 0xa0c6, 0x4009, 0x1108, 0x0010,
+	0x2001, 0x4006, 0x6866, 0x696a, 0x6a6e, 0x2001, 0x0030, 0x0450,
+	0x080c, 0x864e, 0x1138, 0x2001, 0x4005, 0x2009, 0x0003, 0x2011,
+	0x0000, 0x0c80, 0x2e00, 0x601a, 0x080c, 0xa0e3, 0x2d00, 0x6012,
+	0x601f, 0x0001, 0x6838, 0xd88c, 0x0108, 0xc0f5, 0x683a, 0x0126,
+	0x2091, 0x8000, 0x080c, 0x2cd1, 0x012e, 0x2001, 0x0000, 0x080c,
+	0x4f5d, 0x2001, 0x0002, 0x080c, 0x4f6f, 0x2009, 0x0002, 0x080c,
+	0x86d3, 0xa006, 0xa005, 0x012e, 0x00ee, 0x00fe, 0x0005, 0x2001,
+	0x0028, 0x2009, 0x0000, 0x0cb0, 0x2009, 0xb60c, 0x210c, 0xd18c,
+	0x0118, 0x2001, 0x0004, 0x0038, 0xd184, 0x0118, 0x2001, 0x0004,
+	0x0010, 0x2001, 0x0029, 0x2009, 0x0000, 0x0c20, 0x2001, 0x0029,
+	0x2009, 0x0000, 0x08f8, 0x6944, 0x6e48, 0xa684, 0x3fff, 0xa082,
+	0x4000, 0x16b8, 0xa18c, 0xff00, 0x810f, 0xa182, 0x00ff, 0x12e0,
+	0xa188, 0xb735, 0x2104, 0xa065, 0x01b8, 0x6004, 0xa084, 0x00ff,
+	0xa08e, 0x0006, 0x11b0, 0x684c, 0xd0ec, 0x0120, 0x080c, 0x5147,
+	0x0431, 0x0030, 0x0421, 0x684c, 0xd0fc, 0x0110, 0x080c, 0x5138,
+	0x080c, 0x5185, 0xa006, 0x00c8, 0x2001, 0x0028, 0x2009, 0x0000,
+	0x00a0, 0xa082, 0x0006, 0x1240, 0x6100, 0xd1fc, 0x0d20, 0x2001,
+	0x0029, 0x2009, 0x1000, 0x0048, 0x2001, 0x0029, 0x2009, 0x0000,
+	0x0020, 0x2001, 0x0029, 0x2009, 0x0000, 0xa005, 0x0005, 0x0126,
+	0x2091, 0x8000, 0x6050, 0xa00d, 0x0138, 0x2d00, 0x200a, 0x6803,
+	0x0000, 0x6052, 0x012e, 0x0005, 0x2d00, 0x6052, 0x604e, 0x6803,
+	0x0000, 0x0cc0, 0x0126, 0x2091, 0x8000, 0x604c, 0xa005, 0x0170,
+	0x00e6, 0x2071, 0xb8e1, 0x7004, 0xa086, 0x0002, 0x0168, 0x00ee,
+	0x604c, 0x6802, 0x2d00, 0x604e, 0x012e, 0x0005, 0x2d00, 0x6052,
+	0x604e, 0x6803, 0x0000, 0x0cc0, 0x701c, 0xac06, 0x1d80, 0x604c,
+	0x2070, 0x7000, 0x6802, 0x2d00, 0x7002, 0x00ee, 0x012e, 0x0005,
+	0x0126, 0x2091, 0x8000, 0x604c, 0xa06d, 0x0130, 0x6800, 0xa005,
+	0x1108, 0x6052, 0x604e, 0xad05, 0x012e, 0x0005, 0x604c, 0xa06d,
+	0x0130, 0x6800, 0xa005, 0x1108, 0x6052, 0x604e, 0xad05, 0x0005,
+	0x6803, 0x0000, 0x6084, 0xa00d, 0x0120, 0x2d00, 0x200a, 0x6086,
+	0x0005, 0x2d00, 0x6086, 0x6082, 0x0cd8, 0x0126, 0x00c6, 0x0026,
+	0x2091, 0x8000, 0x6218, 0x2260, 0x6200, 0xa005, 0x0110, 0xc285,
+	0x0008, 0xc284, 0x6202, 0x002e, 0x00ce, 0x012e, 0x0005, 0x0126,
+	0x00c6, 0x2091, 0x8000, 0x6218, 0x2260, 0x6204, 0x0006, 0xa086,
+	0x0006, 0x1180, 0x609c, 0xd0ac, 0x0168, 0x2001, 0xb653, 0x2004,
+	0xd0a4, 0x0140, 0xa284, 0xff00, 0x8007, 0xa086, 0x0007, 0x1110,
+	0x2011, 0x0600, 0x000e, 0xa294, 0xff00, 0xa215, 0x6206, 0x0006,
+	0xa086, 0x0006, 0x1128, 0x6290, 0x82ff, 0x1110, 0x080c, 0x151a,
+	0x000e, 0x00ce, 0x012e, 0x0005, 0x0126, 0x00c6, 0x2091, 0x8000,
+	0x6218, 0x2260, 0x6204, 0x0006, 0xa086, 0x0006, 0x1178, 0x609c,
+	0xd0a4, 0x0160, 0x2001, 0xb653, 0x2004, 0xd0ac, 0x1138, 0xa284,
+	0x00ff, 0xa086, 0x0007, 0x1110, 0x2011, 0x0006, 0x000e, 0xa294,
+	0x00ff, 0x8007, 0xa215, 0x6206, 0x00ce, 0x012e, 0x0005, 0x0026,
+	0xa182, 0x00ff, 0x0218, 0xa085, 0x0001, 0x00b0, 0xa190, 0xb735,
+	0x2204, 0xa065, 0x1180, 0x0016, 0x00d6, 0x080c, 0x15e4, 0x2d60,
+	0x00de, 0x001e, 0x0d80, 0x2c00, 0x2012, 0x60a7, 0x0000, 0x60ab,
+	0x0000, 0x080c, 0x4c7e, 0xa006, 0x002e, 0x0005, 0x0126, 0x2091,
+	0x8000, 0x0026, 0xa182, 0x00ff, 0x0218, 0xa085, 0x0001, 0x0480,
+	0x00d6, 0xa190, 0xb735, 0x2204, 0xa06d, 0x0540, 0x2013, 0x0000,
+	0x00d6, 0x00c6, 0x2d60, 0x60a4, 0xa06d, 0x0110, 0x080c, 0x1614,
+	0x60a8, 0xa06d, 0x0110, 0x080c, 0x1614, 0x00ce, 0x00de, 0x00d6,
+	0x00c6, 0x68ac, 0x2060, 0x8cff, 0x0168, 0x600c, 0x0006, 0x6010,
+	0x2068, 0x080c, 0x9d16, 0x0110, 0x080c, 0x1624, 0x080c, 0x86a4,
+	0x00ce, 0x0c88, 0x00ce, 0x00de, 0x080c, 0x1614, 0x00de, 0xa006,
+	0x002e, 0x012e, 0x0005, 0x0016, 0xa182, 0x00ff, 0x0218, 0xa085,
+	0x0001, 0x0030, 0xa188, 0xb735, 0x2104, 0xa065, 0x0dc0, 0xa006,
+	0x001e, 0x0005, 0x00d6, 0x0156, 0x0136, 0x0146, 0x600b, 0x0000,
+	0x600f, 0x0000, 0x6000, 0xc08c, 0x6002, 0x080c, 0x5b41, 0x1558,
+	0x60a0, 0xa086, 0x007e, 0x2069, 0xbc90, 0x0130, 0x2001, 0xb635,
+	0x2004, 0xd0ac, 0x1500, 0x0098, 0x2d04, 0xd0e4, 0x01e0, 0x00d6,
+	0x2069, 0xbc8e, 0x00c6, 0x2061, 0xb8b2, 0x6810, 0x2062, 0x6814,
+	0x6006, 0x6818, 0x600a, 0x681c, 0x600e, 0x00ce, 0x00de, 0x8d69,
+	0x2d04, 0x2069, 0x0140, 0xa005, 0x1110, 0x2001, 0x0001, 0x6886,
+	0x2069, 0xb600, 0x68a6, 0x2069, 0xbc8e, 0x6808, 0x605e, 0x6810,
+	0x6062, 0x6138, 0xa10a, 0x0208, 0x603a, 0x6814, 0x6066, 0x2099,
+	0xbc96, 0xac88, 0x000a, 0x21a0, 0x20a9, 0x0004, 0x53a3, 0x2099,
+	0xbc9a, 0xac88, 0x0006, 0x21a0, 0x20a9, 0x0004, 0x53a3, 0x2069,
+	0xbcae, 0x6808, 0x606a, 0x690c, 0x616e, 0x6810, 0x6072, 0x6818,
+	0x6076, 0x60a0, 0xa086, 0x007e, 0x1120, 0x2069, 0xbc8e, 0x690c,
+	0x616e, 0xa182, 0x0211, 0x1218, 0x2009, 0x0008, 0x0400, 0xa182,
+	0x0259, 0x1218, 0x2009, 0x0007, 0x00d0, 0xa182, 0x02c1, 0x1218,
+	0x2009, 0x0006, 0x00a0, 0xa182, 0x0349, 0x1218, 0x2009, 0x0005,
+	0x0070, 0xa182, 0x0421, 0x1218, 0x2009, 0x0004, 0x0040, 0xa182,
+	0x0581, 0x1218, 0x2009, 0x0003, 0x0010, 0x2009, 0x0002, 0x6192,
+	0x014e, 0x013e, 0x015e, 0x00de, 0x0005, 0x0016, 0x0026, 0x00e6,
+	0x2071, 0xbc8d, 0x2e04, 0x6896, 0x2071, 0xbc8e, 0x7004, 0x689a,
+	0x701c, 0x689e, 0x6a00, 0x2009, 0xb672, 0x210c, 0xd0bc, 0x0120,
+	0xd1ec, 0x0110, 0xc2ad, 0x0008, 0xc2ac, 0xd0c4, 0x0120, 0xd1e4,
+	0x0110, 0xc2bd, 0x0008, 0xc2bc, 0x6a02, 0x00ee, 0x002e, 0x001e,
+	0x0005, 0x00d6, 0x0126, 0x2091, 0x8000, 0x60a4, 0xa06d, 0x01c0,
+	0x6900, 0x81ff, 0x1540, 0x6a04, 0xa282, 0x0010, 0x1648, 0xad88,
+	0x0004, 0x20a9, 0x0010, 0x2104, 0xa086, 0xffff, 0x0128, 0x8108,
+	0x1f04, 0x50f3, 0x080c, 0x151a, 0x260a, 0x8210, 0x6a06, 0x0098,
+	0x080c, 0x15fd, 0x01a8, 0x2d00, 0x60a6, 0x6803, 0x0000, 0xad88,
+	0x0004, 0x20a9, 0x0010, 0x200b, 0xffff, 0x8108, 0x1f04, 0x510b,
+	0x6807, 0x0001, 0x6e12, 0xa085, 0x0001, 0x012e, 0x00de, 0x0005,
+	0xa006, 0x0cd8, 0x0126, 0x2091, 0x8000, 0x00d6, 0x60a4, 0xa00d,
+	0x01a0, 0x2168, 0x6800, 0xa005, 0x1160, 0x080c, 0x5246, 0x1168,
+	0x200b, 0xffff, 0x6804, 0xa08a, 0x0002, 0x0218, 0x8001, 0x6806,
+	0x0020, 0x080c, 0x1614, 0x60a7, 0x0000, 0x00de, 0x012e, 0x0005,
+	0x0126, 0x2091, 0x8000, 0x080c, 0x52a4, 0x0010, 0x080c, 0x4eff,
+	0x080c, 0x51be, 0x1dd8, 0x080c, 0x5185, 0x012e, 0x0005, 0x00d6,
+	0x0126, 0x2091, 0x8000, 0x60a8, 0xa06d, 0x01c0, 0x6950, 0x81ff,
+	0x1540, 0x6a54, 0xa282, 0x0010, 0x1670, 0xad88, 0x0018, 0x20a9,
+	0x0010, 0x2104, 0xa086, 0xffff, 0x0128, 0x8108, 0x1f04, 0x5159,
+	0x080c, 0x151a, 0x260a, 0x8210, 0x6a56, 0x0098, 0x080c, 0x15fd,
+	0x01d0, 0x2d00, 0x60aa, 0x6853, 0x0000, 0xad88, 0x0018, 0x20a9,
+	0x0010, 0x200b, 0xffff, 0x8108, 0x1f04, 0x5171, 0x6857, 0x0001,
+	0x6e62, 0x0010, 0x080c, 0x4f50, 0x0089, 0x1de0, 0xa085, 0x0001,
+	0x012e, 0x00de, 0x0005, 0xa006, 0x0cd8, 0x0126, 0x2091, 0x8000,
+	0x080c, 0x6d1c, 0x012e, 0x0005, 0xa01e, 0x0010, 0x2019, 0x0001,
+	0xa00e, 0x0126, 0x2091, 0x8000, 0x604c, 0x2068, 0x6000, 0xd0dc,
+	0x1170, 0x8dff, 0x01f8, 0x83ff, 0x0120, 0x6848, 0xa606, 0x0158,
 	0x0030, 0x683c, 0xa406, 0x1118, 0x6840, 0xa506, 0x0120, 0x2d08,
-	0x6800, 0x2068, 0x0c70, 0x6a00, 0x6080, 0xad06, 0x1110, 0x6282,
-	0x0018, 0xa180, 0x0000, 0x2202, 0x82ff, 0x1110, 0x6186, 0x8dff,
-	0x0005, 0xa016, 0x080c, 0x51ce, 0x1110, 0x2011, 0x0001, 0x080c,
-	0x5219, 0x1110, 0xa295, 0x0002, 0x0005, 0x080c, 0x524a, 0x0118,
-	0x080c, 0x9d0f, 0x0010, 0xa085, 0x0001, 0x0005, 0x080c, 0x524a,
-	0x0118, 0x080c, 0x9c9f, 0x0010, 0xa085, 0x0001, 0x0005, 0x080c,
-	0x524a, 0x0118, 0x080c, 0x9cf2, 0x0010, 0xa085, 0x0001, 0x0005,
-	0x080c, 0x524a, 0x0118, 0x080c, 0x9cbb, 0x0010, 0xa085, 0x0001,
-	0x0005, 0x080c, 0x524a, 0x0118, 0x080c, 0x9d2b, 0x0010, 0xa085,
-	0x0001, 0x0005, 0x0126, 0x0006, 0x00d6, 0x2091, 0x8000, 0x6080,
-	0xa06d, 0x01a0, 0x6800, 0x0006, 0x6837, 0x0103, 0x6b4a, 0x6847,
-	0x0000, 0x080c, 0x9ecc, 0x0006, 0x6000, 0xd0fc, 0x0110, 0x080c,
-	0xb389, 0x000e, 0x080c, 0x5408, 0x000e, 0x0c50, 0x6083, 0x0000,
-	0x6087, 0x0000, 0x00de, 0x000e, 0x012e, 0x0005, 0x60a4, 0xa00d,
-	0x1118, 0xa085, 0x0001, 0x0005, 0x00e6, 0x2170, 0x7000, 0xa005,
-	0x1168, 0x20a9, 0x0010, 0xae88, 0x0004, 0x2104, 0xa606, 0x0130,
-	0x8108, 0x1f04, 0x51dd, 0xa085, 0x0001, 0x0008, 0xa006, 0x00ee,
-	0x0005, 0x00d6, 0x0126, 0x2091, 0x8000, 0x60a4, 0xa06d, 0x1128,
-	0x080c, 0x15f8, 0x01a0, 0x2d00, 0x60a6, 0x6803, 0x0001, 0x6807,
-	0x0000, 0xad88, 0x0004, 0x20a9, 0x0010, 0x200b, 0xffff, 0x8108,
-	0x1f04, 0x51fd, 0xa085, 0x0001, 0x012e, 0x00de, 0x0005, 0xa006,
-	0x0cd8, 0x00d6, 0x0126, 0x2091, 0x8000, 0x60a4, 0xa06d, 0x0130,
-	0x60a7, 0x0000, 0x080c, 0x160f, 0xa085, 0x0001, 0x012e, 0x00de,
-	0x0005, 0x60a8, 0xa00d, 0x1118, 0xa085, 0x0001, 0x0005, 0x00e6,
-	0x2170, 0x7050, 0xa005, 0x1160, 0x20a9, 0x0010, 0xae88, 0x0018,
-	0x2104, 0xa606, 0x0128, 0x8108, 0x1f04, 0x5228, 0xa085, 0x0001,
-	0x00ee, 0x0005, 0x0126, 0x2091, 0x8000, 0x0c19, 0x1188, 0x200b,
-	0xffff, 0x00d6, 0x60a8, 0x2068, 0x6854, 0xa08a, 0x0002, 0x0218,
-	0x8001, 0x6856, 0x0020, 0x080c, 0x160f, 0x60ab, 0x0000, 0x00de,
-	0x012e, 0x0005, 0x609c, 0xd0a4, 0x0005, 0x00f6, 0x080c, 0x5acf,
-	0x01b0, 0x71b8, 0x81ff, 0x1198, 0x71d4, 0xd19c, 0x0180, 0x2001,
-	0x007e, 0xa080, 0xb635, 0x2004, 0xa07d, 0x0148, 0x7804, 0xa084,
-	0x00ff, 0xa086, 0x0006, 0x1118, 0x7800, 0xc0ed, 0x7802, 0x2079,
-	0xb552, 0x7804, 0xd0a4, 0x01e8, 0x0156, 0x00c6, 0x20a9, 0x007f,
-	0x2009, 0x0000, 0x0016, 0x080c, 0x4fa9, 0x1168, 0x6004, 0xa084,
-	0xff00, 0x8007, 0xa096, 0x0004, 0x0118, 0xa086, 0x0006, 0x1118,
-	0x6000, 0xc0ed, 0x6002, 0x001e, 0x8108, 0x1f04, 0x5272, 0x00ce,
-	0x015e, 0x080c, 0x5309, 0x0120, 0x2001, 0xb7b5, 0x200c, 0x0038,
-	0x2079, 0xb552, 0x7804, 0xd0a4, 0x0130, 0x2009, 0x07d0, 0x2011,
-	0x529d, 0x080c, 0x6a22, 0x00fe, 0x0005, 0x2011, 0x529d, 0x080c,
-	0x699c, 0x080c, 0x5309, 0x01f0, 0x2001, 0xb6b3, 0x2004, 0xa080,
-	0x0000, 0x200c, 0xc1ec, 0x2102, 0x2001, 0xb553, 0x2004, 0xd0a4,
-	0x0130, 0x2009, 0x07d0, 0x2011, 0x529d, 0x080c, 0x6a22, 0x00e6,
-	0x2071, 0xb500, 0x7073, 0x0000, 0x7077, 0x0000, 0x080c, 0x2ab8,
-	0x00ee, 0x04b0, 0x0156, 0x00c6, 0x20a9, 0x007f, 0x2009, 0x0000,
-	0x0016, 0x080c, 0x4fa9, 0x1530, 0x6000, 0xd0ec, 0x0518, 0x0046,
-	0x62a0, 0xa294, 0x00ff, 0x8227, 0xa006, 0x2009, 0x0029, 0x080c,
-	0xb0e8, 0x6000, 0xc0e5, 0xc0ec, 0x6002, 0x6004, 0xa084, 0x00ff,
-	0xa085, 0x0700, 0x6006, 0x2019, 0x0029, 0x080c, 0x6df5, 0x0076,
-	0x2039, 0x0000, 0x080c, 0x6d02, 0x2009, 0x0000, 0x080c, 0xae82,
-	0x007e, 0x004e, 0x001e, 0x8108, 0x1f04, 0x52c8, 0x00ce, 0x015e,
-	0x0005, 0x00c6, 0x6018, 0x2060, 0x6000, 0xc0ec, 0x6002, 0x00ce,
-	0x0005, 0x7818, 0x2004, 0xd0ac, 0x0005, 0x7818, 0x2004, 0xd0bc,
-	0x0005, 0x00f6, 0x2001, 0xb6b3, 0x2004, 0xa07d, 0x0110, 0x7800,
-	0xd0ec, 0x00fe, 0x0005, 0x0126, 0x0026, 0x2091, 0x8000, 0x0006,
-	0x62a0, 0xa290, 0xb635, 0x2204, 0xac06, 0x190c, 0x1515, 0x000e,
-	0x6200, 0xa005, 0x0110, 0xc2fd, 0x0008, 0xc2fc, 0x6202, 0x002e,
-	0x012e, 0x0005, 0x2011, 0xb535, 0x2204, 0xd0cc, 0x0138, 0x2001,
-	0xb7b3, 0x200c, 0x2011, 0x5337, 0x080c, 0x6a22, 0x0005, 0x2011,
-	0x5337, 0x080c, 0x699c, 0x2011, 0xb535, 0x2204, 0xc0cc, 0x2012,
-	0x0005, 0x2071, 0xb614, 0x7003, 0x0001, 0x7007, 0x0000, 0x7013,
-	0x0000, 0x7017, 0x0000, 0x701b, 0x0000, 0x701f, 0x0000, 0x700b,
-	0x0000, 0x704b, 0x0001, 0x704f, 0x0000, 0x705b, 0x0020, 0x705f,
-	0x0040, 0x707f, 0x0000, 0x2071, 0xb77d, 0x7003, 0xb614, 0x7007,
-	0x0000, 0x700b, 0x0000, 0x700f, 0xb75d, 0x7013, 0x0020, 0x7017,
-	0x0040, 0x7037, 0x0000, 0x0005, 0x0016, 0x00e6, 0x2071, 0xb735,
-	0xa00e, 0x7186, 0x718a, 0x7097, 0x0001, 0x2001, 0xb553, 0x2004,
-	0xd0fc, 0x1150, 0x2001, 0xb553, 0x2004, 0xa00e, 0xd09c, 0x0108,
-	0x8108, 0x7102, 0x0804, 0x53d2, 0x2001, 0xb572, 0x200c, 0xa184,
-	0x000f, 0x2009, 0xb573, 0x210c, 0x0002, 0x537a, 0x53ad, 0x53b4,
-	0x53be, 0x53c3, 0x537a, 0x537a, 0x537a, 0x539d, 0x537a, 0x537a,
-	0x537a, 0x537a, 0x537a, 0x537a, 0x537a, 0x7003, 0x0004, 0x0136,
-	0x0146, 0x0156, 0x2099, 0xb576, 0x20a1, 0xb786, 0x20a9, 0x0004,
-	0x53a3, 0x015e, 0x014e, 0x013e, 0x0428, 0x708f, 0x0005, 0x7007,
-	0x0122, 0x2001, 0x0002, 0x0030, 0x708f, 0x0002, 0x7007, 0x0121,
-	0x2001, 0x0003, 0x7002, 0x7097, 0x0001, 0x0088, 0x7007, 0x0122,
-	0x2001, 0x0002, 0x0020, 0x7007, 0x0121, 0x2001, 0x0003, 0x7002,
-	0xa006, 0x7096, 0x708e, 0xa184, 0xff00, 0x8007, 0x709a, 0xa184,
-	0x00ff, 0x7092, 0x00ee, 0x001e, 0x0005, 0x00e6, 0x2071, 0xb614,
-	0x684c, 0xa005, 0x1130, 0x7028, 0xc085, 0x702a, 0xa085, 0x0001,
-	0x0428, 0x6a60, 0x7236, 0x6b64, 0x733a, 0x6868, 0x703e, 0x7076,
-	0x686c, 0x7042, 0x707a, 0x684c, 0x702e, 0x6844, 0x7032, 0x2009,
-	0x000d, 0x200a, 0x700b, 0x0000, 0x8007, 0x8006, 0x8006, 0xa08c,
-	0x003f, 0xa084, 0xffc0, 0xa210, 0x2100, 0xa319, 0x726e, 0x7372,
-	0x7028, 0xc084, 0x702a, 0x7007, 0x0001, 0xa006, 0x00ee, 0x0005,
-	0x0156, 0x00e6, 0x0026, 0x6838, 0xd0fc, 0x1904, 0x5461, 0x6804,
-	0xa00d, 0x0188, 0x00d6, 0x2071, 0xb500, 0xa016, 0x702c, 0x2168,
-	0x6904, 0x206a, 0x8210, 0x2d00, 0x81ff, 0x1dc8, 0x702e, 0x70b4,
-	0xa200, 0x70b6, 0x00de, 0x2071, 0xb614, 0x701c, 0xa005, 0x1904,
-	0x5471, 0x20a9, 0x0032, 0x0f04, 0x546f, 0x0e04, 0x542b, 0x2071,
-	0xb735, 0x7200, 0x82ff, 0x05d8, 0x6934, 0xa186, 0x0103, 0x1904,
-	0x547f, 0x6948, 0x6844, 0xa105, 0x1540, 0x2009, 0x8020, 0x2200,
-	0x0002, 0x546f, 0x5446, 0x5497, 0x54a3, 0x546f, 0x2071, 0x0000,
-	0x20a9, 0x0032, 0x0f04, 0x546f, 0x7018, 0xd084, 0x1dd8, 0x7122,
-	0x683c, 0x7026, 0x6840, 0x702a, 0x701b, 0x0001, 0x2091, 0x4080,
-	0x2071, 0xb500, 0x702c, 0x206a, 0x2d00, 0x702e, 0x70b4, 0x8000,
-	0x70b6, 0x002e, 0x00ee, 0x015e, 0x0005, 0x6844, 0xa086, 0x0100,
-	0x1130, 0x6868, 0xa005, 0x1118, 0x2009, 0x8020, 0x0880, 0x2071,
-	0xb614, 0x2d08, 0x206b, 0x0000, 0x7010, 0x8000, 0x7012, 0x7018,
-	0xa06d, 0x711a, 0x0110, 0x6902, 0x0008, 0x711e, 0x0c10, 0xa18c,
+	0x6800, 0x2068, 0x0c70, 0x080c, 0x81a5, 0x6a00, 0x604c, 0xad06,
+	0x1110, 0x624e, 0x0018, 0xa180, 0x0000, 0x2202, 0x82ff, 0x1110,
+	0x6152, 0x8dff, 0x012e, 0x0005, 0xa01e, 0x0010, 0x2019, 0x0001,
+	0xa00e, 0x6080, 0x2068, 0x8dff, 0x01e8, 0x83ff, 0x0120, 0x6848,
+	0xa606, 0x0158, 0x0030, 0x683c, 0xa406, 0x1118, 0x6840, 0xa506,
+	0x0120, 0x2d08, 0x6800, 0x2068, 0x0c70, 0x6a00, 0x6080, 0xad06,
+	0x1110, 0x6282, 0x0018, 0xa180, 0x0000, 0x2202, 0x82ff, 0x1110,
+	0x6186, 0x8dff, 0x0005, 0xa016, 0x080c, 0x5240, 0x1110, 0x2011,
+	0x0001, 0x080c, 0x528b, 0x1110, 0xa295, 0x0002, 0x0005, 0x080c,
+	0x52bc, 0x0118, 0x080c, 0x9dcb, 0x0010, 0xa085, 0x0001, 0x0005,
+	0x080c, 0x52bc, 0x0118, 0x080c, 0x9d5b, 0x0010, 0xa085, 0x0001,
+	0x0005, 0x080c, 0x52bc, 0x0118, 0x080c, 0x9dae, 0x0010, 0xa085,
+	0x0001, 0x0005, 0x080c, 0x52bc, 0x0118, 0x080c, 0x9d77, 0x0010,
+	0xa085, 0x0001, 0x0005, 0x080c, 0x52bc, 0x0118, 0x080c, 0x9de7,
+	0x0010, 0xa085, 0x0001, 0x0005, 0x0126, 0x0006, 0x00d6, 0x2091,
+	0x8000, 0x6080, 0xa06d, 0x01a0, 0x6800, 0x0006, 0x6837, 0x0103,
+	0x6b4a, 0x6847, 0x0000, 0x080c, 0x9f88, 0x0006, 0x6000, 0xd0fc,
+	0x0110, 0x080c, 0xb445, 0x000e, 0x080c, 0x547a, 0x000e, 0x0c50,
+	0x6083, 0x0000, 0x6087, 0x0000, 0x00de, 0x000e, 0x012e, 0x0005,
+	0x60a4, 0xa00d, 0x1118, 0xa085, 0x0001, 0x0005, 0x00e6, 0x2170,
+	0x7000, 0xa005, 0x1168, 0x20a9, 0x0010, 0xae88, 0x0004, 0x2104,
+	0xa606, 0x0130, 0x8108, 0x1f04, 0x524f, 0xa085, 0x0001, 0x0008,
+	0xa006, 0x00ee, 0x0005, 0x00d6, 0x0126, 0x2091, 0x8000, 0x60a4,
+	0xa06d, 0x1128, 0x080c, 0x15fd, 0x01a0, 0x2d00, 0x60a6, 0x6803,
+	0x0001, 0x6807, 0x0000, 0xad88, 0x0004, 0x20a9, 0x0010, 0x200b,
+	0xffff, 0x8108, 0x1f04, 0x526f, 0xa085, 0x0001, 0x012e, 0x00de,
+	0x0005, 0xa006, 0x0cd8, 0x00d6, 0x0126, 0x2091, 0x8000, 0x60a4,
+	0xa06d, 0x0130, 0x60a7, 0x0000, 0x080c, 0x1614, 0xa085, 0x0001,
+	0x012e, 0x00de, 0x0005, 0x60a8, 0xa00d, 0x1118, 0xa085, 0x0001,
+	0x0005, 0x00e6, 0x2170, 0x7050, 0xa005, 0x1160, 0x20a9, 0x0010,
+	0xae88, 0x0018, 0x2104, 0xa606, 0x0128, 0x8108, 0x1f04, 0x529a,
+	0xa085, 0x0001, 0x00ee, 0x0005, 0x0126, 0x2091, 0x8000, 0x0c19,
+	0x1188, 0x200b, 0xffff, 0x00d6, 0x60a8, 0x2068, 0x6854, 0xa08a,
+	0x0002, 0x0218, 0x8001, 0x6856, 0x0020, 0x080c, 0x1614, 0x60ab,
+	0x0000, 0x00de, 0x012e, 0x0005, 0x609c, 0xd0a4, 0x0005, 0x00f6,
+	0x080c, 0x5b41, 0x01b0, 0x71b8, 0x81ff, 0x1198, 0x71d4, 0xd19c,
+	0x0180, 0x2001, 0x007e, 0xa080, 0xb735, 0x2004, 0xa07d, 0x0148,
+	0x7804, 0xa084, 0x00ff, 0xa086, 0x0006, 0x1118, 0x7800, 0xc0ed,
+	0x7802, 0x2079, 0xb652, 0x7804, 0xd0a4, 0x01e8, 0x0156, 0x00c6,
+	0x20a9, 0x007f, 0x2009, 0x0000, 0x0016, 0x080c, 0x501b, 0x1168,
+	0x6004, 0xa084, 0xff00, 0x8007, 0xa096, 0x0004, 0x0118, 0xa086,
+	0x0006, 0x1118, 0x6000, 0xc0ed, 0x6002, 0x001e, 0x8108, 0x1f04,
+	0x52e4, 0x00ce, 0x015e, 0x080c, 0x537b, 0x0120, 0x2001, 0xb8b5,
+	0x200c, 0x0038, 0x2079, 0xb652, 0x7804, 0xd0a4, 0x0130, 0x2009,
+	0x07d0, 0x2011, 0x530f, 0x080c, 0x6a94, 0x00fe, 0x0005, 0x2011,
+	0x530f, 0x080c, 0x6a0e, 0x080c, 0x537b, 0x01f0, 0x2001, 0xb7b3,
+	0x2004, 0xa080, 0x0000, 0x200c, 0xc1ec, 0x2102, 0x2001, 0xb653,
+	0x2004, 0xd0a4, 0x0130, 0x2009, 0x07d0, 0x2011, 0x530f, 0x080c,
+	0x6a94, 0x00e6, 0x2071, 0xb600, 0x7073, 0x0000, 0x7077, 0x0000,
+	0x080c, 0x2aed, 0x00ee, 0x04b0, 0x0156, 0x00c6, 0x20a9, 0x007f,
+	0x2009, 0x0000, 0x0016, 0x080c, 0x501b, 0x1530, 0x6000, 0xd0ec,
+	0x0518, 0x0046, 0x62a0, 0xa294, 0x00ff, 0x8227, 0xa006, 0x2009,
+	0x0029, 0x080c, 0xb1a4, 0x6000, 0xc0e5, 0xc0ec, 0x6002, 0x6004,
+	0xa084, 0x00ff, 0xa085, 0x0700, 0x6006, 0x2019, 0x0029, 0x080c,
+	0x6e67, 0x0076, 0x2039, 0x0000, 0x080c, 0x6d74, 0x2009, 0x0000,
+	0x080c, 0xaf3e, 0x007e, 0x004e, 0x001e, 0x8108, 0x1f04, 0x533a,
+	0x00ce, 0x015e, 0x0005, 0x00c6, 0x6018, 0x2060, 0x6000, 0xc0ec,
+	0x6002, 0x00ce, 0x0005, 0x7818, 0x2004, 0xd0ac, 0x0005, 0x7818,
+	0x2004, 0xd0bc, 0x0005, 0x00f6, 0x2001, 0xb7b3, 0x2004, 0xa07d,
+	0x0110, 0x7800, 0xd0ec, 0x00fe, 0x0005, 0x0126, 0x0026, 0x2091,
+	0x8000, 0x0006, 0x62a0, 0xa290, 0xb735, 0x2204, 0xac06, 0x190c,
+	0x151a, 0x000e, 0x6200, 0xa005, 0x0110, 0xc2fd, 0x0008, 0xc2fc,
+	0x6202, 0x002e, 0x012e, 0x0005, 0x2011, 0xb635, 0x2204, 0xd0cc,
+	0x0138, 0x2001, 0xb8b3, 0x200c, 0x2011, 0x53a9, 0x080c, 0x6a94,
+	0x0005, 0x2011, 0x53a9, 0x080c, 0x6a0e, 0x2011, 0xb635, 0x2204,
+	0xc0cc, 0x2012, 0x0005, 0x2071, 0xb714, 0x7003, 0x0001, 0x7007,
+	0x0000, 0x7013, 0x0000, 0x7017, 0x0000, 0x701b, 0x0000, 0x701f,
+	0x0000, 0x700b, 0x0000, 0x704b, 0x0001, 0x704f, 0x0000, 0x705b,
+	0x0020, 0x705f, 0x0040, 0x707f, 0x0000, 0x2071, 0xb87d, 0x7003,
+	0xb714, 0x7007, 0x0000, 0x700b, 0x0000, 0x700f, 0xb85d, 0x7013,
+	0x0020, 0x7017, 0x0040, 0x7037, 0x0000, 0x0005, 0x0016, 0x00e6,
+	0x2071, 0xb835, 0xa00e, 0x7186, 0x718a, 0x7097, 0x0001, 0x2001,
+	0xb653, 0x2004, 0xd0fc, 0x1150, 0x2001, 0xb653, 0x2004, 0xa00e,
+	0xd09c, 0x0108, 0x8108, 0x7102, 0x0804, 0x5444, 0x2001, 0xb672,
+	0x200c, 0xa184, 0x000f, 0x2009, 0xb673, 0x210c, 0x0002, 0x53ec,
+	0x541f, 0x5426, 0x5430, 0x5435, 0x53ec, 0x53ec, 0x53ec, 0x540f,
+	0x53ec, 0x53ec, 0x53ec, 0x53ec, 0x53ec, 0x53ec, 0x53ec, 0x7003,
+	0x0004, 0x0136, 0x0146, 0x0156, 0x2099, 0xb676, 0x20a1, 0xb886,
+	0x20a9, 0x0004, 0x53a3, 0x015e, 0x014e, 0x013e, 0x0428, 0x708f,
+	0x0005, 0x7007, 0x0122, 0x2001, 0x0002, 0x0030, 0x708f, 0x0002,
+	0x7007, 0x0121, 0x2001, 0x0003, 0x7002, 0x7097, 0x0001, 0x0088,
+	0x7007, 0x0122, 0x2001, 0x0002, 0x0020, 0x7007, 0x0121, 0x2001,
+	0x0003, 0x7002, 0xa006, 0x7096, 0x708e, 0xa184, 0xff00, 0x8007,
+	0x709a, 0xa184, 0x00ff, 0x7092, 0x00ee, 0x001e, 0x0005, 0x00e6,
+	0x2071, 0xb714, 0x684c, 0xa005, 0x1130, 0x7028, 0xc085, 0x702a,
+	0xa085, 0x0001, 0x0428, 0x6a60, 0x7236, 0x6b64, 0x733a, 0x6868,
+	0x703e, 0x7076, 0x686c, 0x7042, 0x707a, 0x684c, 0x702e, 0x6844,
+	0x7032, 0x2009, 0x000d, 0x200a, 0x700b, 0x0000, 0x8007, 0x8006,
+	0x8006, 0xa08c, 0x003f, 0xa084, 0xffc0, 0xa210, 0x2100, 0xa319,
+	0x726e, 0x7372, 0x7028, 0xc084, 0x702a, 0x7007, 0x0001, 0xa006,
+	0x00ee, 0x0005, 0x0156, 0x00e6, 0x0026, 0x6838, 0xd0fc, 0x1904,
+	0x54d3, 0x6804, 0xa00d, 0x0188, 0x00d6, 0x2071, 0xb600, 0xa016,
+	0x702c, 0x2168, 0x6904, 0x206a, 0x8210, 0x2d00, 0x81ff, 0x1dc8,
+	0x702e, 0x70b4, 0xa200, 0x70b6, 0x00de, 0x2071, 0xb714, 0x701c,
+	0xa005, 0x1904, 0x54e3, 0x20a9, 0x0032, 0x0f04, 0x54e1, 0x0e04,
+	0x549d, 0x2071, 0xb835, 0x7200, 0x82ff, 0x05d8, 0x6934, 0xa186,
+	0x0103, 0x1904, 0x54f1, 0x6948, 0x6844, 0xa105, 0x1540, 0x2009,
+	0x8020, 0x2200, 0x0002, 0x54e1, 0x54b8, 0x5509, 0x5515, 0x54e1,
+	0x2071, 0x0000, 0x20a9, 0x0032, 0x0f04, 0x54e1, 0x7018, 0xd084,
+	0x1dd8, 0x7122, 0x683c, 0x7026, 0x6840, 0x702a, 0x701b, 0x0001,
+	0x2091, 0x4080, 0x2071, 0xb600, 0x702c, 0x206a, 0x2d00, 0x702e,
+	0x70b4, 0x8000, 0x70b6, 0x002e, 0x00ee, 0x015e, 0x0005, 0x6844,
+	0xa086, 0x0100, 0x1130, 0x6868, 0xa005, 0x1118, 0x2009, 0x8020,
+	0x0880, 0x2071, 0xb714, 0x2d08, 0x206b, 0x0000, 0x7010, 0x8000,
+	0x7012, 0x7018, 0xa06d, 0x711a, 0x0110, 0x6902, 0x0008, 0x711e,
+	0x0c10, 0xa18c, 0x00ff, 0xa186, 0x0017, 0x0130, 0xa186, 0x001e,
+	0x0118, 0xa18e, 0x001f, 0x1d28, 0x684c, 0xd0cc, 0x0d10, 0x6850,
+	0xa084, 0x00ff, 0xa086, 0x0001, 0x19e0, 0x2009, 0x8021, 0x0804,
+	0x54b1, 0x7084, 0x8008, 0xa092, 0x001e, 0x1a98, 0x7186, 0xae90,
+	0x0003, 0xa210, 0x683c, 0x2012, 0x0078, 0x7084, 0x8008, 0xa092,
+	0x000f, 0x1a38, 0x7186, 0xae90, 0x0003, 0x8003, 0xa210, 0x683c,
+	0x2012, 0x8210, 0x6840, 0x2012, 0x7088, 0xa10a, 0x0a04, 0x54ca,
+	0x718c, 0x7084, 0xa10a, 0x0a04, 0x54ca, 0x2071, 0x0000, 0x7018,
+	0xd084, 0x1904, 0x54ca, 0x2071, 0xb835, 0x7000, 0xa086, 0x0002,
+	0x1150, 0x080c, 0x5794, 0x2071, 0x0000, 0x701b, 0x0001, 0x2091,
+	0x4080, 0x0804, 0x54ca, 0x080c, 0x57be, 0x2071, 0x0000, 0x701b,
+	0x0001, 0x2091, 0x4080, 0x0804, 0x54ca, 0x0006, 0x684c, 0x0006,
+	0x6837, 0x0103, 0x20a9, 0x001c, 0xad80, 0x0011, 0x20a0, 0x2001,
+	0x0000, 0x40a4, 0x000e, 0xa084, 0x00ff, 0x684e, 0x000e, 0x684a,
+	0x6952, 0x0005, 0x2071, 0xb714, 0x7004, 0x0002, 0x5570, 0x5581,
+	0x577f, 0x5780, 0x578d, 0x5793, 0x5571, 0x5770, 0x5706, 0x575c,
+	0x0005, 0x0126, 0x2091, 0x8000, 0x0e04, 0x5580, 0x2009, 0x000d,
+	0x7030, 0x200a, 0x2091, 0x4080, 0x7007, 0x0001, 0x700b, 0x0000,
+	0x012e, 0x2069, 0xb8f4, 0x683c, 0xa005, 0x03f8, 0x11f0, 0x0126,
+	0x2091, 0x8000, 0x2069, 0x0000, 0x6934, 0x2001, 0xb720, 0x2004,
+	0xa10a, 0x0170, 0x0e04, 0x55a4, 0x2069, 0x0000, 0x6818, 0xd084,
+	0x1158, 0x2009, 0x8040, 0x6922, 0x681b, 0x0001, 0x2091, 0x4080,
+	0x2069, 0xb8f4, 0x683f, 0xffff, 0x012e, 0x2069, 0xb600, 0x6848,
+	0x6968, 0xa102, 0x2069, 0xb835, 0x688a, 0x6984, 0x701c, 0xa06d,
+	0x0120, 0x81ff, 0x0904, 0x55fa, 0x00a0, 0x81ff, 0x0904, 0x56c0,
+	0x2071, 0xb835, 0x7184, 0x7088, 0xa10a, 0x1258, 0x7190, 0x2071,
+	0xb8f4, 0x7038, 0xa005, 0x0128, 0x1b04, 0x56c0, 0x713a, 0x0804,
+	0x56c0, 0x2071, 0xb835, 0x718c, 0x0126, 0x2091, 0x8000, 0x7084,
+	0xa10a, 0x0a04, 0x56db, 0x0e04, 0x567c, 0x2071, 0x0000, 0x7018,
+	0xd084, 0x1904, 0x567c, 0x2001, 0xffff, 0x2071, 0xb8f4, 0x703a,
+	0x2071, 0xb835, 0x7000, 0xa086, 0x0002, 0x1150, 0x080c, 0x5794,
+	0x2071, 0x0000, 0x701b, 0x0001, 0x2091, 0x4080, 0x0804, 0x567c,
+	0x080c, 0x57be, 0x2071, 0x0000, 0x701b, 0x0001, 0x2091, 0x4080,
+	0x0804, 0x567c, 0x2071, 0xb835, 0x7000, 0xa005, 0x0904, 0x56a2,
+	0x6934, 0xa186, 0x0103, 0x1904, 0x567f, 0x684c, 0xd0bc, 0x1904,
+	0x56a2, 0x6948, 0x6844, 0xa105, 0x1904, 0x5697, 0x2009, 0x8020,
+	0x2071, 0xb835, 0x7000, 0x0002, 0x56a2, 0x5662, 0x563a, 0x564c,
+	0x5619, 0x0136, 0x0146, 0x0156, 0x2099, 0xb676, 0x20a1, 0xb886,
+	0x20a9, 0x0004, 0x53a3, 0x015e, 0x014e, 0x013e, 0x2071, 0xb87d,
+	0xad80, 0x000f, 0x700e, 0x7013, 0x0002, 0x7007, 0x0002, 0x700b,
+	0x0000, 0x2e10, 0x080c, 0x1648, 0x2071, 0xb714, 0x7007, 0x0009,
+	0x0804, 0x56c0, 0x7084, 0x8008, 0xa092, 0x001e, 0x1a04, 0x56c0,
+	0xae90, 0x0003, 0xa210, 0x683c, 0x2012, 0x7186, 0x2071, 0xb714,
+	0x080c, 0x5815, 0x0804, 0x56c0, 0x7084, 0x8008, 0xa092, 0x000f,
+	0x1a04, 0x56c0, 0xae90, 0x0003, 0x8003, 0xa210, 0x683c, 0x2012,
+	0x8210, 0x6840, 0x2012, 0x7186, 0x2071, 0xb714, 0x080c, 0x5815,
+	0x0804, 0x56c0, 0x0126, 0x2091, 0x8000, 0x0e04, 0x567c, 0x2071,
+	0x0000, 0x7018, 0xd084, 0x1180, 0x7122, 0x683c, 0x7026, 0x6840,
+	0x702a, 0x701b, 0x0001, 0x2091, 0x4080, 0x012e, 0x2071, 0xb714,
+	0x080c, 0x5815, 0x0804, 0x56c0, 0x012e, 0x0804, 0x56c0, 0xa18c,
 	0x00ff, 0xa186, 0x0017, 0x0130, 0xa186, 0x001e, 0x0118, 0xa18e,
-	0x001f, 0x1d28, 0x684c, 0xd0cc, 0x0d10, 0x6850, 0xa084, 0x00ff,
-	0xa086, 0x0001, 0x19e0, 0x2009, 0x8021, 0x0804, 0x543f, 0x7084,
-	0x8008, 0xa092, 0x001e, 0x1a98, 0x7186, 0xae90, 0x0003, 0xa210,
-	0x683c, 0x2012, 0x0078, 0x7084, 0x8008, 0xa092, 0x000f, 0x1a38,
-	0x7186, 0xae90, 0x0003, 0x8003, 0xa210, 0x683c, 0x2012, 0x8210,
-	0x6840, 0x2012, 0x7088, 0xa10a, 0x0a04, 0x5458, 0x718c, 0x7084,
-	0xa10a, 0x0a04, 0x5458, 0x2071, 0x0000, 0x7018, 0xd084, 0x1904,
-	0x5458, 0x2071, 0xb735, 0x7000, 0xa086, 0x0002, 0x1150, 0x080c,
-	0x5722, 0x2071, 0x0000, 0x701b, 0x0001, 0x2091, 0x4080, 0x0804,
-	0x5458, 0x080c, 0x574c, 0x2071, 0x0000, 0x701b, 0x0001, 0x2091,
-	0x4080, 0x0804, 0x5458, 0x0006, 0x684c, 0x0006, 0x6837, 0x0103,
-	0x20a9, 0x001c, 0xad80, 0x0011, 0x20a0, 0x2001, 0x0000, 0x40a4,
-	0x000e, 0xa084, 0x00ff, 0x684e, 0x000e, 0x684a, 0x6952, 0x0005,
-	0x2071, 0xb614, 0x7004, 0x0002, 0x54fe, 0x550f, 0x570d, 0x570e,
-	0x571b, 0x5721, 0x54ff, 0x56fe, 0x5694, 0x56ea, 0x0005, 0x0126,
-	0x2091, 0x8000, 0x0e04, 0x550e, 0x2009, 0x000d, 0x7030, 0x200a,
-	0x2091, 0x4080, 0x7007, 0x0001, 0x700b, 0x0000, 0x012e, 0x2069,
-	0xb7f3, 0x683c, 0xa005, 0x03f8, 0x11f0, 0x0126, 0x2091, 0x8000,
-	0x2069, 0x0000, 0x6934, 0x2001, 0xb620, 0x2004, 0xa10a, 0x0170,
-	0x0e04, 0x5532, 0x2069, 0x0000, 0x6818, 0xd084, 0x1158, 0x2009,
-	0x8040, 0x6922, 0x681b, 0x0001, 0x2091, 0x4080, 0x2069, 0xb7f3,
-	0x683f, 0xffff, 0x012e, 0x2069, 0xb500, 0x6848, 0x6968, 0xa102,
-	0x2069, 0xb735, 0x688a, 0x6984, 0x701c, 0xa06d, 0x0120, 0x81ff,
-	0x0904, 0x5588, 0x00a0, 0x81ff, 0x0904, 0x564e, 0x2071, 0xb735,
-	0x7184, 0x7088, 0xa10a, 0x1258, 0x7190, 0x2071, 0xb7f3, 0x7038,
-	0xa005, 0x0128, 0x1b04, 0x564e, 0x713a, 0x0804, 0x564e, 0x2071,
-	0xb735, 0x718c, 0x0126, 0x2091, 0x8000, 0x7084, 0xa10a, 0x0a04,
-	0x5669, 0x0e04, 0x560a, 0x2071, 0x0000, 0x7018, 0xd084, 0x1904,
-	0x560a, 0x2001, 0xffff, 0x2071, 0xb7f3, 0x703a, 0x2071, 0xb735,
-	0x7000, 0xa086, 0x0002, 0x1150, 0x080c, 0x5722, 0x2071, 0x0000,
-	0x701b, 0x0001, 0x2091, 0x4080, 0x0804, 0x560a, 0x080c, 0x574c,
-	0x2071, 0x0000, 0x701b, 0x0001, 0x2091, 0x4080, 0x0804, 0x560a,
-	0x2071, 0xb735, 0x7000, 0xa005, 0x0904, 0x5630, 0x6934, 0xa186,
-	0x0103, 0x1904, 0x560d, 0x684c, 0xd0bc, 0x1904, 0x5630, 0x6948,
-	0x6844, 0xa105, 0x1904, 0x5625, 0x2009, 0x8020, 0x2071, 0xb735,
-	0x7000, 0x0002, 0x5630, 0x55f0, 0x55c8, 0x55da, 0x55a7, 0x0136,
-	0x0146, 0x0156, 0x2099, 0xb576, 0x20a1, 0xb786, 0x20a9, 0x0004,
-	0x53a3, 0x015e, 0x014e, 0x013e, 0x2071, 0xb77d, 0xad80, 0x000f,
-	0x700e, 0x7013, 0x0002, 0x7007, 0x0002, 0x700b, 0x0000, 0x2e10,
-	0x080c, 0x1643, 0x2071, 0xb614, 0x7007, 0x0009, 0x0804, 0x564e,
-	0x7084, 0x8008, 0xa092, 0x001e, 0x1a04, 0x564e, 0xae90, 0x0003,
-	0xa210, 0x683c, 0x2012, 0x7186, 0x2071, 0xb614, 0x080c, 0x57a3,
-	0x0804, 0x564e, 0x7084, 0x8008, 0xa092, 0x000f, 0x1a04, 0x564e,
-	0xae90, 0x0003, 0x8003, 0xa210, 0x683c, 0x2012, 0x8210, 0x6840,
-	0x2012, 0x7186, 0x2071, 0xb614, 0x080c, 0x57a3, 0x0804, 0x564e,
-	0x0126, 0x2091, 0x8000, 0x0e04, 0x560a, 0x2071, 0x0000, 0x7018,
-	0xd084, 0x1180, 0x7122, 0x683c, 0x7026, 0x6840, 0x702a, 0x701b,
-	0x0001, 0x2091, 0x4080, 0x012e, 0x2071, 0xb614, 0x080c, 0x57a3,
-	0x0804, 0x564e, 0x012e, 0x0804, 0x564e, 0xa18c, 0x00ff, 0xa186,
-	0x0017, 0x0130, 0xa186, 0x001e, 0x0118, 0xa18e, 0x001f, 0x11c0,
-	0x684c, 0xd0cc, 0x01a8, 0x6850, 0xa084, 0x00ff, 0xa086, 0x0001,
-	0x1178, 0x2009, 0x8021, 0x0804, 0x559e, 0x6844, 0xa086, 0x0100,
-	0x1138, 0x6868, 0xa005, 0x1120, 0x2009, 0x8020, 0x0804, 0x559e,
-	0x2071, 0xb614, 0x080c, 0x57b5, 0x01c8, 0x2071, 0xb614, 0x700f,
-	0x0001, 0x6934, 0xa184, 0x00ff, 0xa086, 0x0003, 0x1130, 0x810f,
-	0xa18c, 0x00ff, 0x8101, 0x0108, 0x710e, 0x7007, 0x0003, 0x080c,
-	0x57ce, 0x7050, 0xa086, 0x0100, 0x0904, 0x570e, 0x0126, 0x2091,
-	0x8000, 0x2071, 0xb614, 0x7008, 0xa086, 0x0001, 0x1180, 0x0e04,
-	0x5667, 0x2009, 0x000d, 0x7030, 0x200a, 0x2091, 0x4080, 0x700b,
-	0x0000, 0x7004, 0xa086, 0x0006, 0x1110, 0x7007, 0x0001, 0x012e,
-	0x0005, 0x2071, 0xb614, 0x080c, 0x57b5, 0x0518, 0x2071, 0xb735,
-	0x7084, 0x700a, 0x20a9, 0x0020, 0x2099, 0xb736, 0x20a1, 0xb75d,
-	0x53a3, 0x7087, 0x0000, 0x2071, 0xb614, 0x2069, 0xb77d, 0x706c,
-	0x6826, 0x7070, 0x682a, 0x7074, 0x682e, 0x7078, 0x6832, 0x2d10,
-	0x080c, 0x1643, 0x7007, 0x0008, 0x2001, 0xffff, 0x2071, 0xb7f3,
-	0x703a, 0x012e, 0x0804, 0x564e, 0x2069, 0xb77d, 0x6808, 0xa08e,
-	0x0000, 0x0904, 0x56e9, 0xa08e, 0x0200, 0x0904, 0x56e7, 0xa08e,
-	0x0100, 0x1904, 0x56e9, 0x0126, 0x2091, 0x8000, 0x0e04, 0x56e5,
-	0x2069, 0x0000, 0x6818, 0xd084, 0x15c0, 0x702c, 0x7130, 0x8108,
-	0xa102, 0x0230, 0xa00e, 0x7034, 0x706e, 0x7038, 0x7072, 0x0048,
-	0x706c, 0xa080, 0x0040, 0x706e, 0x1220, 0x7070, 0xa081, 0x0000,
-	0x7072, 0x7132, 0x6936, 0x700b, 0x0000, 0x2001, 0xb75a, 0x2004,
-	0xa005, 0x1190, 0x6934, 0x2069, 0xb735, 0x689c, 0x699e, 0x2069,
-	0xb7f3, 0xa102, 0x1118, 0x683c, 0xa005, 0x1368, 0x2001, 0xb75b,
-	0x200c, 0x810d, 0x693e, 0x0038, 0x2009, 0x8040, 0x6922, 0x681b,
-	0x0001, 0x2091, 0x4080, 0x7007, 0x0001, 0x012e, 0x0010, 0x7007,
-	0x0005, 0x0005, 0x2001, 0xb77f, 0x2004, 0xa08e, 0x0100, 0x1128,
-	0x7007, 0x0001, 0x080c, 0x57a3, 0x0005, 0xa08e, 0x0000, 0x0de0,
-	0xa08e, 0x0200, 0x1dc8, 0x7007, 0x0005, 0x0005, 0x701c, 0xa06d,
-	0x0158, 0x080c, 0x57b5, 0x0140, 0x7007, 0x0003, 0x080c, 0x57ce,
-	0x7050, 0xa086, 0x0100, 0x0110, 0x0005, 0x0005, 0x7050, 0xa09e,
-	0x0100, 0x1118, 0x7007, 0x0004, 0x0030, 0xa086, 0x0200, 0x1110,
-	0x7007, 0x0005, 0x0005, 0x080c, 0x5771, 0x7006, 0x080c, 0x57a3,
-	0x0005, 0x0005, 0x00e6, 0x0156, 0x2071, 0xb735, 0x7184, 0x81ff,
-	0x0500, 0xa006, 0x7086, 0xae80, 0x0003, 0x2071, 0x0000, 0x21a8,
-	0x2014, 0x7226, 0x8000, 0x0f04, 0x5746, 0x2014, 0x722a, 0x8000,
-	0x0f04, 0x5746, 0x2014, 0x722e, 0x8000, 0x0f04, 0x5746, 0x2014,
-	0x723a, 0x8000, 0x0f04, 0x5746, 0x2014, 0x723e, 0xa180, 0x8030,
-	0x7022, 0x015e, 0x00ee, 0x0005, 0x00e6, 0x0156, 0x2071, 0xb735,
-	0x7184, 0x81ff, 0x01d8, 0xa006, 0x7086, 0xae80, 0x0003, 0x2071,
-	0x0000, 0x21a8, 0x2014, 0x7226, 0x8000, 0x2014, 0x722a, 0x8000,
-	0x0f04, 0x5768, 0x2014, 0x723a, 0x8000, 0x2014, 0x723e, 0x0018,
-	0x2001, 0x8020, 0x0010, 0x2001, 0x8042, 0x7022, 0x015e, 0x00ee,
-	0x0005, 0x702c, 0x7130, 0x8108, 0xa102, 0x0230, 0xa00e, 0x7034,
-	0x706e, 0x7038, 0x7072, 0x0048, 0x706c, 0xa080, 0x0040, 0x706e,
-	0x1220, 0x7070, 0xa081, 0x0000, 0x7072, 0x7132, 0x700c, 0x8001,
-	0x700e, 0x1180, 0x0126, 0x2091, 0x8000, 0x0e04, 0x579d, 0x2001,
-	0x000d, 0x2102, 0x2091, 0x4080, 0x2001, 0x0001, 0x700b, 0x0000,
-	0x012e, 0x0005, 0x2001, 0x0007, 0x0005, 0x2001, 0x0006, 0x700b,
-	0x0001, 0x012e, 0x0005, 0x701c, 0xa06d, 0x0170, 0x0126, 0x2091,
-	0x8000, 0x7010, 0x8001, 0x7012, 0x2d04, 0x701e, 0xa005, 0x1108,
-	0x701a, 0x012e, 0x080c, 0x160f, 0x0005, 0x2019, 0x000d, 0x2304,
-	0x230c, 0xa10e, 0x0130, 0x2304, 0x230c, 0xa10e, 0x0110, 0xa006,
-	0x0060, 0x732c, 0x8319, 0x7130, 0xa102, 0x1118, 0x2300, 0xa005,
-	0x0020, 0x0210, 0xa302, 0x0008, 0x8002, 0x0005, 0x2d00, 0x7026,
-	0xa080, 0x000d, 0x7056, 0x7053, 0x0000, 0x0126, 0x2091, 0x8000,
-	0x2009, 0xb812, 0x2104, 0xc08d, 0x200a, 0x012e, 0x080c, 0x165f,
-	0x0005, 0x708c, 0xa08a, 0x0029, 0x1220, 0xa082, 0x001d, 0x0033,
-	0x0010, 0x080c, 0x1515, 0x6027, 0x1e00, 0x0005, 0x58dc, 0x5857,
-	0x586f, 0x58ac, 0x58cd, 0x5907, 0x5919, 0x586f, 0x58f3, 0x57fb,
-	0x5829, 0x57fa, 0x0005, 0x00d6, 0x2069, 0x0200, 0x6804, 0xa005,
-	0x1180, 0x6808, 0xa005, 0x1518, 0x708f, 0x0028, 0x2069, 0xb7c5,
-	0x2d04, 0x7002, 0x080c, 0x5bd1, 0x6028, 0xa085, 0x0600, 0x602a,
-	0x00b0, 0x708f, 0x0028, 0x2069, 0xb7c5, 0x2d04, 0x7002, 0x6028,
+	0x001f, 0x11c0, 0x684c, 0xd0cc, 0x01a8, 0x6850, 0xa084, 0x00ff,
+	0xa086, 0x0001, 0x1178, 0x2009, 0x8021, 0x0804, 0x5610, 0x6844,
+	0xa086, 0x0100, 0x1138, 0x6868, 0xa005, 0x1120, 0x2009, 0x8020,
+	0x0804, 0x5610, 0x2071, 0xb714, 0x080c, 0x5827, 0x01c8, 0x2071,
+	0xb714, 0x700f, 0x0001, 0x6934, 0xa184, 0x00ff, 0xa086, 0x0003,
+	0x1130, 0x810f, 0xa18c, 0x00ff, 0x8101, 0x0108, 0x710e, 0x7007,
+	0x0003, 0x080c, 0x5840, 0x7050, 0xa086, 0x0100, 0x0904, 0x5780,
+	0x0126, 0x2091, 0x8000, 0x2071, 0xb714, 0x7008, 0xa086, 0x0001,
+	0x1180, 0x0e04, 0x56d9, 0x2009, 0x000d, 0x7030, 0x200a, 0x2091,
+	0x4080, 0x700b, 0x0000, 0x7004, 0xa086, 0x0006, 0x1110, 0x7007,
+	0x0001, 0x012e, 0x0005, 0x2071, 0xb714, 0x080c, 0x5827, 0x0518,
+	0x2071, 0xb835, 0x7084, 0x700a, 0x20a9, 0x0020, 0x2099, 0xb836,
+	0x20a1, 0xb85d, 0x53a3, 0x7087, 0x0000, 0x2071, 0xb714, 0x2069,
+	0xb87d, 0x706c, 0x6826, 0x7070, 0x682a, 0x7074, 0x682e, 0x7078,
+	0x6832, 0x2d10, 0x080c, 0x1648, 0x7007, 0x0008, 0x2001, 0xffff,
+	0x2071, 0xb8f4, 0x703a, 0x012e, 0x0804, 0x56c0, 0x2069, 0xb87d,
+	0x6808, 0xa08e, 0x0000, 0x0904, 0x575b, 0xa08e, 0x0200, 0x0904,
+	0x5759, 0xa08e, 0x0100, 0x1904, 0x575b, 0x0126, 0x2091, 0x8000,
+	0x0e04, 0x5757, 0x2069, 0x0000, 0x6818, 0xd084, 0x15c0, 0x702c,
+	0x7130, 0x8108, 0xa102, 0x0230, 0xa00e, 0x7034, 0x706e, 0x7038,
+	0x7072, 0x0048, 0x706c, 0xa080, 0x0040, 0x706e, 0x1220, 0x7070,
+	0xa081, 0x0000, 0x7072, 0x7132, 0x6936, 0x700b, 0x0000, 0x2001,
+	0xb85a, 0x2004, 0xa005, 0x1190, 0x6934, 0x2069, 0xb835, 0x689c,
+	0x699e, 0x2069, 0xb8f4, 0xa102, 0x1118, 0x683c, 0xa005, 0x1368,
+	0x2001, 0xb85b, 0x200c, 0x810d, 0x693e, 0x0038, 0x2009, 0x8040,
+	0x6922, 0x681b, 0x0001, 0x2091, 0x4080, 0x7007, 0x0001, 0x012e,
+	0x0010, 0x7007, 0x0005, 0x0005, 0x2001, 0xb87f, 0x2004, 0xa08e,
+	0x0100, 0x1128, 0x7007, 0x0001, 0x080c, 0x5815, 0x0005, 0xa08e,
+	0x0000, 0x0de0, 0xa08e, 0x0200, 0x1dc8, 0x7007, 0x0005, 0x0005,
+	0x701c, 0xa06d, 0x0158, 0x080c, 0x5827, 0x0140, 0x7007, 0x0003,
+	0x080c, 0x5840, 0x7050, 0xa086, 0x0100, 0x0110, 0x0005, 0x0005,
+	0x7050, 0xa09e, 0x0100, 0x1118, 0x7007, 0x0004, 0x0030, 0xa086,
+	0x0200, 0x1110, 0x7007, 0x0005, 0x0005, 0x080c, 0x57e3, 0x7006,
+	0x080c, 0x5815, 0x0005, 0x0005, 0x00e6, 0x0156, 0x2071, 0xb835,
+	0x7184, 0x81ff, 0x0500, 0xa006, 0x7086, 0xae80, 0x0003, 0x2071,
+	0x0000, 0x21a8, 0x2014, 0x7226, 0x8000, 0x0f04, 0x57b8, 0x2014,
+	0x722a, 0x8000, 0x0f04, 0x57b8, 0x2014, 0x722e, 0x8000, 0x0f04,
+	0x57b8, 0x2014, 0x723a, 0x8000, 0x0f04, 0x57b8, 0x2014, 0x723e,
+	0xa180, 0x8030, 0x7022, 0x015e, 0x00ee, 0x0005, 0x00e6, 0x0156,
+	0x2071, 0xb835, 0x7184, 0x81ff, 0x01d8, 0xa006, 0x7086, 0xae80,
+	0x0003, 0x2071, 0x0000, 0x21a8, 0x2014, 0x7226, 0x8000, 0x2014,
+	0x722a, 0x8000, 0x0f04, 0x57da, 0x2014, 0x723a, 0x8000, 0x2014,
+	0x723e, 0x0018, 0x2001, 0x8020, 0x0010, 0x2001, 0x8042, 0x7022,
+	0x015e, 0x00ee, 0x0005, 0x702c, 0x7130, 0x8108, 0xa102, 0x0230,
+	0xa00e, 0x7034, 0x706e, 0x7038, 0x7072, 0x0048, 0x706c, 0xa080,
+	0x0040, 0x706e, 0x1220, 0x7070, 0xa081, 0x0000, 0x7072, 0x7132,
+	0x700c, 0x8001, 0x700e, 0x1180, 0x0126, 0x2091, 0x8000, 0x0e04,
+	0x580f, 0x2001, 0x000d, 0x2102, 0x2091, 0x4080, 0x2001, 0x0001,
+	0x700b, 0x0000, 0x012e, 0x0005, 0x2001, 0x0007, 0x0005, 0x2001,
+	0x0006, 0x700b, 0x0001, 0x012e, 0x0005, 0x701c, 0xa06d, 0x0170,
+	0x0126, 0x2091, 0x8000, 0x7010, 0x8001, 0x7012, 0x2d04, 0x701e,
+	0xa005, 0x1108, 0x701a, 0x012e, 0x080c, 0x1614, 0x0005, 0x2019,
+	0x000d, 0x2304, 0x230c, 0xa10e, 0x0130, 0x2304, 0x230c, 0xa10e,
+	0x0110, 0xa006, 0x0060, 0x732c, 0x8319, 0x7130, 0xa102, 0x1118,
+	0x2300, 0xa005, 0x0020, 0x0210, 0xa302, 0x0008, 0x8002, 0x0005,
+	0x2d00, 0x7026, 0xa080, 0x000d, 0x7056, 0x7053, 0x0000, 0x0126,
+	0x2091, 0x8000, 0x2009, 0xb913, 0x2104, 0xc08d, 0x200a, 0x012e,
+	0x080c, 0x1664, 0x0005, 0x708c, 0xa08a, 0x0029, 0x1220, 0xa082,
+	0x001d, 0x0033, 0x0010, 0x080c, 0x151a, 0x6027, 0x1e00, 0x0005,
+	0x594e, 0x58c9, 0x58e1, 0x591e, 0x593f, 0x5979, 0x598b, 0x58e1,
+	0x5965, 0x586d, 0x589b, 0x586c, 0x0005, 0x00d6, 0x2069, 0x0200,
+	0x6804, 0xa005, 0x1180, 0x6808, 0xa005, 0x1518, 0x708f, 0x0028,
+	0x2069, 0xb8c6, 0x2d04, 0x7002, 0x080c, 0x5c43, 0x6028, 0xa085,
+	0x0600, 0x602a, 0x00b0, 0x708f, 0x0028, 0x2069, 0xb8c6, 0x2d04,
+	0x7002, 0x6028, 0xa085, 0x0600, 0x602a, 0x00e6, 0x0036, 0x0046,
+	0x0056, 0x2071, 0xb924, 0x080c, 0x1e1a, 0x005e, 0x004e, 0x003e,
+	0x00ee, 0x00de, 0x0005, 0x00d6, 0x2069, 0x0200, 0x6804, 0xa005,
+	0x1180, 0x6808, 0xa005, 0x1518, 0x708f, 0x0028, 0x2069, 0xb8c6,
+	0x2d04, 0x7002, 0x080c, 0x5cd0, 0x6028, 0xa085, 0x0600, 0x602a,
+	0x00b0, 0x708f, 0x0028, 0x2069, 0xb8c6, 0x2d04, 0x7002, 0x6028,
 	0xa085, 0x0600, 0x602a, 0x00e6, 0x0036, 0x0046, 0x0056, 0x2071,
-	0xb823, 0x080c, 0x1dfe, 0x005e, 0x004e, 0x003e, 0x00ee, 0x00de,
-	0x0005, 0x00d6, 0x2069, 0x0200, 0x6804, 0xa005, 0x1180, 0x6808,
-	0xa005, 0x1518, 0x708f, 0x0028, 0x2069, 0xb7c5, 0x2d04, 0x7002,
-	0x080c, 0x5c5e, 0x6028, 0xa085, 0x0600, 0x602a, 0x00b0, 0x708f,
-	0x0028, 0x2069, 0xb7c5, 0x2d04, 0x7002, 0x6028, 0xa085, 0x0600,
-	0x602a, 0x00e6, 0x0036, 0x0046, 0x0056, 0x2071, 0xb823, 0x080c,
-	0x1dfe, 0x005e, 0x004e, 0x003e, 0x00ee, 0x00de, 0x0005, 0x6803,
-	0x0090, 0x6124, 0xd1e4, 0x1190, 0x080c, 0x5984, 0xd1d4, 0x1160,
-	0xd1dc, 0x1138, 0xd1cc, 0x0150, 0x708f, 0x0020, 0x080c, 0x5984,
+	0xb924, 0x080c, 0x1e1a, 0x005e, 0x004e, 0x003e, 0x00ee, 0x00de,
+	0x0005, 0x6803, 0x0090, 0x6124, 0xd1e4, 0x1190, 0x080c, 0x59f6,
+	0xd1d4, 0x1160, 0xd1dc, 0x1138, 0xd1cc, 0x0150, 0x708f, 0x0020,
+	0x080c, 0x59f6, 0x0028, 0x708f, 0x001d, 0x0010, 0x708f, 0x001f,
+	0x0005, 0x6803, 0x0088, 0x6124, 0xd1cc, 0x1590, 0xd1dc, 0x1568,
+	0xd1e4, 0x1540, 0xa184, 0x1e00, 0x1580, 0x60e3, 0x0001, 0x600c,
+	0xc0b4, 0x600e, 0x080c, 0x5b71, 0x080c, 0x24e5, 0x0156, 0x6803,
+	0x0100, 0x20a9, 0x0014, 0x6804, 0xd0dc, 0x1118, 0x1f04, 0x58fb,
+	0x0048, 0x20a9, 0x0014, 0x6803, 0x0080, 0x6804, 0xd0d4, 0x1130,
+	0x1f04, 0x5905, 0x080c, 0x5b92, 0x015e, 0x0078, 0x015e, 0x708f,
+	0x0028, 0x0058, 0x708f, 0x001e, 0x0040, 0x708f, 0x001d, 0x0028,
+	0x708f, 0x0020, 0x0010, 0x708f, 0x001f, 0x0005, 0x60e3, 0x0001,
+	0x600c, 0xc0b4, 0x600e, 0x080c, 0x5b71, 0x080c, 0x24e5, 0x6803,
+	0x0080, 0x6124, 0xd1d4, 0x1180, 0xd1dc, 0x1158, 0xd1e4, 0x1130,
+	0xa184, 0x1e00, 0x1158, 0x708f, 0x0028, 0x0040, 0x708f, 0x001e,
 	0x0028, 0x708f, 0x001d, 0x0010, 0x708f, 0x001f, 0x0005, 0x6803,
-	0x0088, 0x6124, 0xd1cc, 0x1590, 0xd1dc, 0x1568, 0xd1e4, 0x1540,
-	0xa184, 0x1e00, 0x1580, 0x60e3, 0x0001, 0x600c, 0xc0b4, 0x600e,
-	0x080c, 0x5aff, 0x080c, 0x24b0, 0x0156, 0x6803, 0x0100, 0x20a9,
-	0x0014, 0x6804, 0xd0dc, 0x1118, 0x1f04, 0x5889, 0x0048, 0x20a9,
-	0x0014, 0x6803, 0x0080, 0x6804, 0xd0d4, 0x1130, 0x1f04, 0x5893,
-	0x080c, 0x5b20, 0x015e, 0x0078, 0x015e, 0x708f, 0x0028, 0x0058,
-	0x708f, 0x001e, 0x0040, 0x708f, 0x001d, 0x0028, 0x708f, 0x0020,
-	0x0010, 0x708f, 0x001f, 0x0005, 0x60e3, 0x0001, 0x600c, 0xc0b4,
-	0x600e, 0x080c, 0x5aff, 0x080c, 0x24b0, 0x6803, 0x0080, 0x6124,
-	0xd1d4, 0x1180, 0xd1dc, 0x1158, 0xd1e4, 0x1130, 0xa184, 0x1e00,
-	0x1158, 0x708f, 0x0028, 0x0040, 0x708f, 0x001e, 0x0028, 0x708f,
-	0x001d, 0x0010, 0x708f, 0x001f, 0x0005, 0x6803, 0x00a0, 0x6124,
-	0xd1dc, 0x1138, 0xd1e4, 0x0138, 0x080c, 0x1e47, 0x708f, 0x001e,
-	0x0010, 0x708f, 0x001d, 0x0005, 0x080c, 0x59f6, 0x6124, 0xd1dc,
-	0x1188, 0x080c, 0x5984, 0x0016, 0x080c, 0x1e47, 0x001e, 0xd1d4,
-	0x1128, 0xd1e4, 0x0138, 0x708f, 0x001e, 0x0020, 0x708f, 0x001f,
-	0x080c, 0x5984, 0x0005, 0x6803, 0x00a0, 0x6124, 0xd1d4, 0x1160,
-	0xd1cc, 0x1150, 0xd1dc, 0x1128, 0xd1e4, 0x0140, 0x708f, 0x001e,
-	0x0028, 0x708f, 0x001d, 0x0010, 0x708f, 0x0021, 0x0005, 0x080c,
-	0x59f6, 0x6124, 0xd1d4, 0x1150, 0xd1dc, 0x1128, 0xd1e4, 0x0140,
-	0x708f, 0x001e, 0x0028, 0x708f, 0x001d, 0x0010, 0x708f, 0x001f,
-	0x0005, 0x6803, 0x0090, 0x6124, 0xd1d4, 0x1178, 0xd1cc, 0x1150,
-	0xd1dc, 0x1128, 0xd1e4, 0x0158, 0x708f, 0x001e, 0x0040, 0x708f,
-	0x001d, 0x0028, 0x708f, 0x0020, 0x0010, 0x708f, 0x001f, 0x0005,
-	0x0016, 0x00c6, 0x00d6, 0x00e6, 0x0126, 0x2061, 0x0100, 0x2069,
-	0x0140, 0x2071, 0xb500, 0x2091, 0x8000, 0x080c, 0x5acf, 0x11e8,
-	0x2001, 0xb50c, 0x200c, 0xd1b4, 0x01c0, 0xc1b4, 0x2102, 0x6027,
-	0x0200, 0xe000, 0xe000, 0x6024, 0xd0cc, 0x0158, 0x6803, 0x00a0,
-	0x2001, 0xb79f, 0x2003, 0x0001, 0x2001, 0xb500, 0x2003, 0x0001,
-	0x0428, 0x6028, 0xc0cd, 0x602a, 0x0408, 0x080c, 0x5aeb, 0x0150,
-	0x080c, 0x5ae1, 0x1138, 0x2001, 0x0001, 0x080c, 0x27c3, 0x080c,
-	0x5aa6, 0x00a0, 0x080c, 0x59f3, 0x0178, 0x2001, 0x0001, 0x080c,
-	0x27c3, 0x708c, 0xa086, 0x001e, 0x0120, 0x708c, 0xa086, 0x0022,
-	0x1118, 0x708f, 0x0025, 0x0010, 0x708f, 0x0021, 0x012e, 0x00ee,
-	0x00de, 0x00ce, 0x001e, 0x0005, 0x0026, 0x2011, 0x5995, 0x080c,
-	0x6a5c, 0x002e, 0x0016, 0x0026, 0x2009, 0x0064, 0x2011, 0x5995,
-	0x080c, 0x6a53, 0x002e, 0x001e, 0x0005, 0x00e6, 0x00f6, 0x0016,
-	0x080c, 0x7d7a, 0x2071, 0xb500, 0x080c, 0x5930, 0x001e, 0x00fe,
-	0x00ee, 0x0005, 0x0016, 0x0026, 0x0036, 0x00c6, 0x00d6, 0x00e6,
-	0x00f6, 0x0126, 0x080c, 0x7d7a, 0x2061, 0x0100, 0x2069, 0x0140,
-	0x2071, 0xb500, 0x2091, 0x8000, 0x6028, 0xc09c, 0x602a, 0x2011,
-	0x0003, 0x080c, 0x8075, 0x2011, 0x0002, 0x080c, 0x807f, 0x080c,
-	0x7f59, 0x080c, 0x6a10, 0x0036, 0x2019, 0x0000, 0x080c, 0x7fe4,
-	0x003e, 0x60e3, 0x0000, 0x080c, 0xb42f, 0x080c, 0xb44a, 0x2001,
-	0xb500, 0x2003, 0x0004, 0x6027, 0x0008, 0x080c, 0x12dd, 0x2001,
-	0x0001, 0x080c, 0x27c3, 0x012e, 0x00fe, 0x00ee, 0x00de, 0x00ce,
-	0x003e, 0x002e, 0x001e, 0x0005, 0x2001, 0xb500, 0x2004, 0xa086,
-	0x0004, 0x0140, 0x2001, 0xb79e, 0x2003, 0xaaaa, 0x2001, 0xb79f,
-	0x2003, 0x0000, 0x0005, 0x6020, 0xd09c, 0x0005, 0x6800, 0xa086,
-	0x00c0, 0x0160, 0x6803, 0x00c0, 0x0156, 0x20a9, 0x002d, 0x1d04,
-	0x59ff, 0x2091, 0x6000, 0x1f04, 0x59ff, 0x015e, 0x0005, 0x00c6,
-	0x00d6, 0x00e6, 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0xb500,
-	0x2001, 0xb79f, 0x200c, 0xa186, 0x0000, 0x0158, 0xa186, 0x0001,
-	0x0158, 0xa186, 0x0002, 0x0158, 0xa186, 0x0003, 0x0158, 0x0804,
-	0x5a94, 0x708f, 0x0022, 0x0040, 0x708f, 0x0021, 0x0028, 0x708f,
-	0x0023, 0x0020, 0x708f, 0x0024, 0x6043, 0x0000, 0x60e3, 0x0000,
-	0x6887, 0x0001, 0x2001, 0x0001, 0x080c, 0x2872, 0x0026, 0x2011,
-	0x0003, 0x080c, 0x8075, 0x2011, 0x0002, 0x080c, 0x807f, 0x080c,
-	0x7f59, 0x0036, 0x2019, 0x0000, 0x080c, 0x7fe4, 0x003e, 0x002e,
-	0x7000, 0xa08e, 0x0004, 0x0118, 0x602b, 0x0028, 0x0010, 0x602b,
-	0x0020, 0x0156, 0x0126, 0x2091, 0x8000, 0x20a9, 0x0005, 0x6024,
-	0xd0ac, 0x0120, 0x012e, 0x015e, 0x0804, 0x5aa2, 0x6800, 0xa084,
-	0x00a0, 0xc0bd, 0x6802, 0x6904, 0xd1d4, 0x1130, 0x6803, 0x0100,
-	0x1f04, 0x5a57, 0x080c, 0x5b20, 0x012e, 0x015e, 0x080c, 0x5ae1,
-	0x01a8, 0x6044, 0xa005, 0x0168, 0x6050, 0x0006, 0xa085, 0x0020,
-	0x6052, 0x080c, 0x5b20, 0xa006, 0x8001, 0x1df0, 0x000e, 0x6052,
-	0x0028, 0x6804, 0xd0d4, 0x1110, 0x080c, 0x5b20, 0x0016, 0x0026,
-	0x2009, 0x00c8, 0x2011, 0x59a2, 0x080c, 0x6a22, 0x002e, 0x001e,
-	0x2001, 0xb79f, 0x2003, 0x0004, 0x080c, 0x57e1, 0x080c, 0x5ae1,
-	0x0148, 0x6804, 0xd0d4, 0x1130, 0xd0dc, 0x1100, 0x2001, 0xb79f,
-	0x2003, 0x0000, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x00c6, 0x00d6,
-	0x00e6, 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0xb500, 0x2001,
-	0xb79e, 0x2003, 0x0000, 0x2001, 0xb78f, 0x2003, 0x0000, 0x708f,
-	0x0000, 0x60e3, 0x0000, 0x6887, 0x0000, 0x2001, 0x0000, 0x080c,
-	0x2872, 0x6803, 0x0000, 0x6043, 0x0090, 0x6043, 0x0010, 0x6027,
-	0xffff, 0x602b, 0x182f, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x0006,
-	0x2001, 0xb79e, 0x2004, 0xa086, 0xaaaa, 0x000e, 0x0005, 0x0006,
-	0x2001, 0xb572, 0x2004, 0xa084, 0x0030, 0xa086, 0x0000, 0x000e,
-	0x0005, 0x0006, 0x2001, 0xb572, 0x2004, 0xa084, 0x0030, 0xa086,
-	0x0030, 0x000e, 0x0005, 0x0006, 0x2001, 0xb572, 0x2004, 0xa084,
-	0x0030, 0xa086, 0x0010, 0x000e, 0x0005, 0x0006, 0x2001, 0xb572,
-	0x2004, 0xa084, 0x0030, 0xa086, 0x0020, 0x000e, 0x0005, 0x2001,
-	0xb50c, 0x2004, 0xd0a4, 0x0170, 0x080c, 0x2892, 0x0036, 0x0016,
-	0x2009, 0x0000, 0x2019, 0x0028, 0x080c, 0x2c6f, 0x001e, 0x003e,
-	0xa006, 0x0009, 0x0005, 0x00e6, 0x2071, 0xb50c, 0x2e04, 0x0118,
-	0xa085, 0x0010, 0x0010, 0xa084, 0xffef, 0x2072, 0x00ee, 0x0005,
-	0x6050, 0x0006, 0x60f0, 0x0006, 0x60ec, 0x0006, 0x600c, 0x0006,
-	0x6004, 0x0006, 0x6028, 0x0006, 0x602f, 0x0100, 0x602f, 0x0000,
-	0x602f, 0x0040, 0x602f, 0x0000, 0x000e, 0x602a, 0x000e, 0x6006,
-	0x000e, 0x600e, 0x000e, 0x60ee, 0x000e, 0x60f2, 0x60e3, 0x0000,
-	0x6887, 0x0001, 0x2001, 0x0001, 0x080c, 0x2872, 0x6800, 0xa084,
-	0x00a0, 0xc0bd, 0x6802, 0x6803, 0x00a0, 0x000e, 0x6052, 0x6050,
-	0x0005, 0x0156, 0x0016, 0x0026, 0x0036, 0x00c6, 0x00d6, 0x00e6,
-	0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0xb500, 0x6020, 0xa084,
-	0x0080, 0x0138, 0x2001, 0xb50c, 0x200c, 0xc1bd, 0x2102, 0x0804,
-	0x5bc9, 0x2001, 0xb50c, 0x200c, 0xc1bc, 0x2102, 0x6028, 0xa084,
-	0xe1ff, 0x602a, 0x6027, 0x0200, 0x6803, 0x0090, 0x20a9, 0x0384,
-	0x6024, 0xd0cc, 0x1508, 0x1d04, 0x5b78, 0x2091, 0x6000, 0x1f04,
-	0x5b78, 0x2011, 0x0003, 0x080c, 0x8075, 0x2011, 0x0002, 0x080c,
-	0x807f, 0x080c, 0x7f59, 0x2019, 0x0000, 0x080c, 0x7fe4, 0x6803,
-	0x00a0, 0x2001, 0xb79f, 0x2003, 0x0001, 0x2001, 0xb500, 0x2003,
-	0x0001, 0xa085, 0x0001, 0x0468, 0x86ff, 0x1120, 0x080c, 0x1e47,
-	0x080c, 0x24b0, 0x60e3, 0x0000, 0x2001, 0xb78f, 0x2004, 0x080c,
-	0x2872, 0x60e2, 0x6803, 0x0080, 0x20a9, 0x0384, 0x6027, 0x1e00,
-	0x2009, 0x1e00, 0xe000, 0x6024, 0xa10c, 0x0138, 0x1d04, 0x5bae,
-	0x2091, 0x6000, 0x1f04, 0x5bae, 0x0820, 0x6028, 0xa085, 0x1e00,
-	0x602a, 0x70a4, 0xa005, 0x1118, 0x6887, 0x0001, 0x0008, 0x6886,
-	0xa006, 0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e, 0x001e, 0x015e,
-	0x0005, 0x0156, 0x0016, 0x0026, 0x0036, 0x00c6, 0x00d6, 0x00e6,
-	0x2061, 0x0100, 0x2071, 0xb500, 0x2069, 0x0140, 0x6020, 0xa084,
-	0x00c0, 0x0120, 0x6884, 0xa005, 0x1904, 0x5c25, 0x6803, 0x0088,
-	0x60e3, 0x0000, 0x6887, 0x0000, 0x2001, 0x0000, 0x080c, 0x2872,
-	0x2069, 0x0200, 0x6804, 0xa005, 0x1118, 0x6808, 0xa005, 0x01c0,
-	0x6028, 0xa084, 0xfbff, 0x602a, 0x6027, 0x0400, 0x2069, 0xb7c5,
-	0x7000, 0x206a, 0x708f, 0x0026, 0x7003, 0x0001, 0x20a9, 0x0002,
-	0x1d04, 0x5c08, 0x2091, 0x6000, 0x1f04, 0x5c08, 0x0804, 0x5c56,
-	0x2069, 0x0140, 0x20a9, 0x0384, 0x6027, 0x1e00, 0x2009, 0x1e00,
-	0xe000, 0x6024, 0xa10c, 0x0520, 0xa084, 0x1a00, 0x1508, 0x1d04,
-	0x5c14, 0x2091, 0x6000, 0x1f04, 0x5c14, 0x2011, 0x0003, 0x080c,
-	0x8075, 0x2011, 0x0002, 0x080c, 0x807f, 0x080c, 0x7f59, 0x2019,
-	0x0000, 0x080c, 0x7fe4, 0x6803, 0x00a0, 0x2001, 0xb79f, 0x2003,
-	0x0001, 0x2001, 0xb500, 0x2003, 0x0001, 0xa085, 0x0001, 0x00b0,
-	0x080c, 0x24b0, 0x6803, 0x0080, 0x2069, 0x0140, 0x60e3, 0x0000,
-	0x70a4, 0xa005, 0x1118, 0x6887, 0x0001, 0x0008, 0x6886, 0x2001,
-	0xb78f, 0x2004, 0x080c, 0x2872, 0x60e2, 0xa006, 0x00ee, 0x00de,
-	0x00ce, 0x003e, 0x002e, 0x001e, 0x015e, 0x0005, 0x0156, 0x0016,
-	0x0026, 0x0036, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2071,
-	0xb500, 0x6020, 0xa084, 0x00c0, 0x01e0, 0x2011, 0x0003, 0x080c,
-	0x8075, 0x2011, 0x0002, 0x080c, 0x807f, 0x080c, 0x7f59, 0x2019,
-	0x0000, 0x080c, 0x7fe4, 0x2069, 0x0140, 0x6803, 0x00a0, 0x2001,
-	0xb79f, 0x2003, 0x0001, 0x2001, 0xb500, 0x2003, 0x0001, 0x0804,
-	0x5cfb, 0x2001, 0xb50c, 0x200c, 0xd1b4, 0x1160, 0xc1b5, 0x2102,
-	0x080c, 0x598a, 0x2069, 0x0140, 0x080c, 0x24b0, 0x6803, 0x0080,
-	0x60e3, 0x0000, 0x2069, 0x0200, 0x6804, 0xa005, 0x1118, 0x6808,
-	0xa005, 0x01c0, 0x6028, 0xa084, 0xfdff, 0x602a, 0x6027, 0x0200,
-	0x2069, 0xb7c5, 0x7000, 0x206a, 0x708f, 0x0027, 0x7003, 0x0001,
-	0x20a9, 0x0002, 0x1d04, 0x5cb2, 0x2091, 0x6000, 0x1f04, 0x5cb2,
-	0x0804, 0x5cfb, 0x6027, 0x1e00, 0x2009, 0x1e00, 0xe000, 0x6024,
-	0xa10c, 0x01c8, 0xa084, 0x1c00, 0x11b0, 0x1d04, 0x5cba, 0x0006,
-	0x0016, 0x00c6, 0x00d6, 0x00e6, 0x080c, 0x68f9, 0x00ee, 0x00de,
-	0x00ce, 0x001e, 0x000e, 0x00e6, 0x2071, 0xb7f3, 0x7018, 0x00ee,
-	0xa005, 0x1d00, 0x0500, 0x0026, 0x2011, 0x59a2, 0x080c, 0x699c,
-	0x2011, 0x5995, 0x080c, 0x6a5c, 0x002e, 0x2069, 0x0140, 0x60e3,
-	0x0000, 0x70a4, 0xa005, 0x1118, 0x6887, 0x0001, 0x0008, 0x6886,
-	0x2001, 0xb78f, 0x2004, 0x080c, 0x2872, 0x60e2, 0x2001, 0xb50c,
-	0x200c, 0xc1b4, 0x2102, 0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e,
-	0x001e, 0x015e, 0x0005, 0x0156, 0x0016, 0x0026, 0x0036, 0x0046,
-	0x00c6, 0x00e6, 0x2061, 0x0100, 0x2071, 0xb500, 0x7130, 0xd184,
-	0x1180, 0x2011, 0xb553, 0x2214, 0xd2ec, 0x0138, 0xc18d, 0x7132,
-	0x2011, 0xb553, 0x2214, 0xd2ac, 0x1120, 0x7030, 0xd08c, 0x0904,
-	0x5d68, 0x7130, 0xc185, 0x7132, 0x2011, 0xb553, 0x220c, 0xd1a4,
-	0x0530, 0x0016, 0x2019, 0x000e, 0x080c, 0xb065, 0x0156, 0x20a9,
-	0x007f, 0x2009, 0x0000, 0xa186, 0x007e, 0x01a0, 0xa186, 0x0080,
-	0x0188, 0x080c, 0x4fa9, 0x1170, 0x8127, 0xa006, 0x0016, 0x2009,
-	0x000e, 0x080c, 0xb0e8, 0x2009, 0x0001, 0x2011, 0x0100, 0x080c,
-	0x6b1a, 0x001e, 0x8108, 0x1f04, 0x5d33, 0x015e, 0x001e, 0xd1ac,
-	0x1148, 0x0016, 0x2009, 0x0000, 0x2019, 0x0004, 0x080c, 0x2c6f,
-	0x001e, 0x0070, 0x0156, 0x20a9, 0x007f, 0x2009, 0x0000, 0x080c,
-	0x4fa9, 0x1110, 0x080c, 0x4c0b, 0x8108, 0x1f04, 0x5d5f, 0x015e,
-	0x080c, 0x1e47, 0x2011, 0x0003, 0x080c, 0x8075, 0x2011, 0x0002,
-	0x080c, 0x807f, 0x080c, 0x7f59, 0x0036, 0x2019, 0x0000, 0x080c,
-	0x7fe4, 0x003e, 0x60e3, 0x0000, 0x2001, 0xb500, 0x2003, 0x0001,
-	0x080c, 0x5a07, 0x00ee, 0x00ce, 0x004e, 0x003e, 0x002e, 0x001e,
-	0x015e, 0x0005, 0x2071, 0xb5e2, 0x7003, 0x0000, 0x7007, 0x0000,
-	0x700f, 0x0000, 0x702b, 0x0001, 0x704f, 0x0000, 0x7053, 0x0001,
-	0x705f, 0x0020, 0x7063, 0x0040, 0x7083, 0x0000, 0x708b, 0x0000,
-	0x708f, 0x0001, 0x70bf, 0x0000, 0x0005, 0x00e6, 0x2071, 0xb5e2,
-	0x6848, 0xa005, 0x1130, 0x7028, 0xc085, 0x702a, 0xa085, 0x0001,
-	0x0428, 0x6a50, 0x7236, 0x6b54, 0x733a, 0x6858, 0x703e, 0x707a,
-	0x685c, 0x7042, 0x707e, 0x6848, 0x702e, 0x6840, 0x7032, 0x2009,
-	0x000c, 0x200a, 0x8007, 0x8006, 0x8006, 0xa08c, 0x003f, 0xa084,
-	0xffc0, 0xa210, 0x2100, 0xa319, 0x7272, 0x7376, 0x7028, 0xc084,
-	0x702a, 0x7007, 0x0001, 0x700f, 0x0000, 0xa006, 0x00ee, 0x0005,
-	0x2b78, 0x2071, 0xb5e2, 0x7004, 0x0043, 0x700c, 0x0002, 0x5de4,
-	0x5ddb, 0x5ddb, 0x5ddb, 0x5ddb, 0x0005, 0x5e3a, 0x5e3b, 0x5e6d,
-	0x5e6e, 0x5e38, 0x5ebc, 0x5ec1, 0x5ef2, 0x5ef3, 0x5f0e, 0x5f0f,
-	0x5f10, 0x5f11, 0x5f12, 0x5f13, 0x5fc9, 0x5ff0, 0x700c, 0x0002,
-	0x5dfd, 0x5e38, 0x5e38, 0x5e39, 0x5e39, 0x7830, 0x7930, 0xa106,
-	0x0120, 0x7830, 0x7930, 0xa106, 0x1510, 0x7030, 0xa10a, 0x01f8,
-	0x1210, 0x712c, 0xa10a, 0xa18a, 0x0002, 0x12d0, 0x080c, 0x15df,
-	0x01b0, 0x2d00, 0x705a, 0x7063, 0x0040, 0x2001, 0x0003, 0x7057,
-	0x0000, 0x0126, 0x0006, 0x2091, 0x8000, 0x2009, 0xb812, 0x2104,
-	0xc085, 0x200a, 0x000e, 0x700e, 0x012e, 0x080c, 0x165f, 0x0005,
-	0x080c, 0x15df, 0x0de0, 0x2d00, 0x705a, 0x080c, 0x15df, 0x1108,
-	0x0c10, 0x2d00, 0x7086, 0x7063, 0x0080, 0x2001, 0x0004, 0x08f8,
-	0x0005, 0x0005, 0x0005, 0x700c, 0x0002, 0x5e42, 0x5e45, 0x5e53,
-	0x5e6c, 0x5e6c, 0x080c, 0x5df6, 0x0005, 0x0126, 0x8001, 0x700e,
-	0x7058, 0x0006, 0x080c, 0x6343, 0x0120, 0x2091, 0x8000, 0x080c,
-	0x5df6, 0x00de, 0x0048, 0x0126, 0x8001, 0x700e, 0x080c, 0x6343,
+	0x00a0, 0x6124, 0xd1dc, 0x1138, 0xd1e4, 0x0138, 0x080c, 0x1e63,
+	0x708f, 0x001e, 0x0010, 0x708f, 0x001d, 0x0005, 0x080c, 0x5a68,
+	0x6124, 0xd1dc, 0x1188, 0x080c, 0x59f6, 0x0016, 0x080c, 0x1e63,
+	0x001e, 0xd1d4, 0x1128, 0xd1e4, 0x0138, 0x708f, 0x001e, 0x0020,
+	0x708f, 0x001f, 0x080c, 0x59f6, 0x0005, 0x6803, 0x00a0, 0x6124,
+	0xd1d4, 0x1160, 0xd1cc, 0x1150, 0xd1dc, 0x1128, 0xd1e4, 0x0140,
+	0x708f, 0x001e, 0x0028, 0x708f, 0x001d, 0x0010, 0x708f, 0x0021,
+	0x0005, 0x080c, 0x5a68, 0x6124, 0xd1d4, 0x1150, 0xd1dc, 0x1128,
+	0xd1e4, 0x0140, 0x708f, 0x001e, 0x0028, 0x708f, 0x001d, 0x0010,
+	0x708f, 0x001f, 0x0005, 0x6803, 0x0090, 0x6124, 0xd1d4, 0x1178,
+	0xd1cc, 0x1150, 0xd1dc, 0x1128, 0xd1e4, 0x0158, 0x708f, 0x001e,
+	0x0040, 0x708f, 0x001d, 0x0028, 0x708f, 0x0020, 0x0010, 0x708f,
+	0x001f, 0x0005, 0x0016, 0x00c6, 0x00d6, 0x00e6, 0x0126, 0x2061,
+	0x0100, 0x2069, 0x0140, 0x2071, 0xb600, 0x2091, 0x8000, 0x080c,
+	0x5b41, 0x11e8, 0x2001, 0xb60c, 0x200c, 0xd1b4, 0x01c0, 0xc1b4,
+	0x2102, 0x6027, 0x0200, 0xe000, 0xe000, 0x6024, 0xd0cc, 0x0158,
+	0x6803, 0x00a0, 0x2001, 0xb89f, 0x2003, 0x0001, 0x2001, 0xb600,
+	0x2003, 0x0001, 0x0428, 0x6028, 0xc0cd, 0x602a, 0x0408, 0x080c,
+	0x5b5d, 0x0150, 0x080c, 0x5b53, 0x1138, 0x2001, 0x0001, 0x080c,
+	0x27f8, 0x080c, 0x5b18, 0x00a0, 0x080c, 0x5a65, 0x0178, 0x2001,
+	0x0001, 0x080c, 0x27f8, 0x708c, 0xa086, 0x001e, 0x0120, 0x708c,
+	0xa086, 0x0022, 0x1118, 0x708f, 0x0025, 0x0010, 0x708f, 0x0021,
+	0x012e, 0x00ee, 0x00de, 0x00ce, 0x001e, 0x0005, 0x0026, 0x2011,
+	0x5a07, 0x080c, 0x6ace, 0x002e, 0x0016, 0x0026, 0x2009, 0x0064,
+	0x2011, 0x5a07, 0x080c, 0x6ac5, 0x002e, 0x001e, 0x0005, 0x00e6,
+	0x00f6, 0x0016, 0x080c, 0x7df3, 0x2071, 0xb600, 0x080c, 0x59a2,
+	0x001e, 0x00fe, 0x00ee, 0x0005, 0x0016, 0x0026, 0x0036, 0x00c6,
+	0x00d6, 0x00e6, 0x00f6, 0x0126, 0x080c, 0x7df3, 0x2061, 0x0100,
+	0x2069, 0x0140, 0x2071, 0xb600, 0x2091, 0x8000, 0x6028, 0xc09c,
+	0x602a, 0x2011, 0x0003, 0x080c, 0x80fc, 0x2011, 0x0002, 0x080c,
+	0x8106, 0x080c, 0x7fe0, 0x080c, 0x6a82, 0x0036, 0x2019, 0x0000,
+	0x080c, 0x806b, 0x003e, 0x60e3, 0x0000, 0x080c, 0xb4eb, 0x080c,
+	0xb506, 0x2001, 0xb600, 0x2003, 0x0004, 0x6027, 0x0008, 0x080c,
+	0x12e2, 0x2001, 0x0001, 0x080c, 0x27f8, 0x012e, 0x00fe, 0x00ee,
+	0x00de, 0x00ce, 0x003e, 0x002e, 0x001e, 0x0005, 0x2001, 0xb600,
+	0x2004, 0xa086, 0x0004, 0x0140, 0x2001, 0xb89e, 0x2003, 0xaaaa,
+	0x2001, 0xb89f, 0x2003, 0x0000, 0x0005, 0x6020, 0xd09c, 0x0005,
+	0x6800, 0xa086, 0x00c0, 0x0160, 0x6803, 0x00c0, 0x0156, 0x20a9,
+	0x002d, 0x1d04, 0x5a71, 0x2091, 0x6000, 0x1f04, 0x5a71, 0x015e,
+	0x0005, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2069, 0x0140,
+	0x2071, 0xb600, 0x2001, 0xb89f, 0x200c, 0xa186, 0x0000, 0x0158,
+	0xa186, 0x0001, 0x0158, 0xa186, 0x0002, 0x0158, 0xa186, 0x0003,
+	0x0158, 0x0804, 0x5b06, 0x708f, 0x0022, 0x0040, 0x708f, 0x0021,
+	0x0028, 0x708f, 0x0023, 0x0020, 0x708f, 0x0024, 0x6043, 0x0000,
+	0x60e3, 0x0000, 0x6887, 0x0001, 0x2001, 0x0001, 0x080c, 0x28a7,
+	0x0026, 0x2011, 0x0003, 0x080c, 0x80fc, 0x2011, 0x0002, 0x080c,
+	0x8106, 0x080c, 0x7fe0, 0x0036, 0x2019, 0x0000, 0x080c, 0x806b,
+	0x003e, 0x002e, 0x7000, 0xa08e, 0x0004, 0x0118, 0x602b, 0x0028,
+	0x0010, 0x602b, 0x0020, 0x0156, 0x0126, 0x2091, 0x8000, 0x20a9,
+	0x0005, 0x6024, 0xd0ac, 0x0120, 0x012e, 0x015e, 0x0804, 0x5b14,
+	0x6800, 0xa084, 0x00a0, 0xc0bd, 0x6802, 0x6904, 0xd1d4, 0x1130,
+	0x6803, 0x0100, 0x1f04, 0x5ac9, 0x080c, 0x5b92, 0x012e, 0x015e,
+	0x080c, 0x5b53, 0x01a8, 0x6044, 0xa005, 0x0168, 0x6050, 0x0006,
+	0xa085, 0x0020, 0x6052, 0x080c, 0x5b92, 0xa006, 0x8001, 0x1df0,
+	0x000e, 0x6052, 0x0028, 0x6804, 0xd0d4, 0x1110, 0x080c, 0x5b92,
+	0x0016, 0x0026, 0x2009, 0x00c8, 0x2011, 0x5a14, 0x080c, 0x6a94,
+	0x002e, 0x001e, 0x2001, 0xb89f, 0x2003, 0x0004, 0x080c, 0x5853,
+	0x080c, 0x5b53, 0x0148, 0x6804, 0xd0d4, 0x1130, 0xd0dc, 0x1100,
+	0x2001, 0xb89f, 0x2003, 0x0000, 0x00ee, 0x00de, 0x00ce, 0x0005,
+	0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2069, 0x0140, 0x2071,
+	0xb600, 0x2001, 0xb89e, 0x2003, 0x0000, 0x2001, 0xb88f, 0x2003,
+	0x0000, 0x708f, 0x0000, 0x60e3, 0x0000, 0x6887, 0x0000, 0x2001,
+	0x0000, 0x080c, 0x28a7, 0x6803, 0x0000, 0x6043, 0x0090, 0x6043,
+	0x0010, 0x6027, 0xffff, 0x602b, 0x182f, 0x00ee, 0x00de, 0x00ce,
+	0x0005, 0x0006, 0x2001, 0xb89e, 0x2004, 0xa086, 0xaaaa, 0x000e,
+	0x0005, 0x0006, 0x2001, 0xb672, 0x2004, 0xa084, 0x0030, 0xa086,
+	0x0000, 0x000e, 0x0005, 0x0006, 0x2001, 0xb672, 0x2004, 0xa084,
+	0x0030, 0xa086, 0x0030, 0x000e, 0x0005, 0x0006, 0x2001, 0xb672,
+	0x2004, 0xa084, 0x0030, 0xa086, 0x0010, 0x000e, 0x0005, 0x0006,
+	0x2001, 0xb672, 0x2004, 0xa084, 0x0030, 0xa086, 0x0020, 0x000e,
+	0x0005, 0x2001, 0xb60c, 0x2004, 0xd0a4, 0x0170, 0x080c, 0x28c7,
+	0x0036, 0x0016, 0x2009, 0x0000, 0x2019, 0x0028, 0x080c, 0x2ca4,
+	0x001e, 0x003e, 0xa006, 0x0009, 0x0005, 0x00e6, 0x2071, 0xb60c,
+	0x2e04, 0x0118, 0xa085, 0x0010, 0x0010, 0xa084, 0xffef, 0x2072,
+	0x00ee, 0x0005, 0x6050, 0x0006, 0x60f0, 0x0006, 0x60ec, 0x0006,
+	0x600c, 0x0006, 0x6004, 0x0006, 0x6028, 0x0006, 0x602f, 0x0100,
+	0x602f, 0x0000, 0x602f, 0x0040, 0x602f, 0x0000, 0x000e, 0x602a,
+	0x000e, 0x6006, 0x000e, 0x600e, 0x000e, 0x60ee, 0x000e, 0x60f2,
+	0x60e3, 0x0000, 0x6887, 0x0001, 0x2001, 0x0001, 0x080c, 0x28a7,
+	0x6800, 0xa084, 0x00a0, 0xc0bd, 0x6802, 0x6803, 0x00a0, 0x000e,
+	0x6052, 0x6050, 0x0005, 0x0156, 0x0016, 0x0026, 0x0036, 0x00c6,
+	0x00d6, 0x00e6, 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0xb600,
+	0x6020, 0xa084, 0x0080, 0x0138, 0x2001, 0xb60c, 0x200c, 0xc1bd,
+	0x2102, 0x0804, 0x5c3b, 0x2001, 0xb60c, 0x200c, 0xc1bc, 0x2102,
+	0x6028, 0xa084, 0xe1ff, 0x602a, 0x6027, 0x0200, 0x6803, 0x0090,
+	0x20a9, 0x0384, 0x6024, 0xd0cc, 0x1508, 0x1d04, 0x5bea, 0x2091,
+	0x6000, 0x1f04, 0x5bea, 0x2011, 0x0003, 0x080c, 0x80fc, 0x2011,
+	0x0002, 0x080c, 0x8106, 0x080c, 0x7fe0, 0x2019, 0x0000, 0x080c,
+	0x806b, 0x6803, 0x00a0, 0x2001, 0xb89f, 0x2003, 0x0001, 0x2001,
+	0xb600, 0x2003, 0x0001, 0xa085, 0x0001, 0x0468, 0x86ff, 0x1120,
+	0x080c, 0x1e63, 0x080c, 0x24e5, 0x60e3, 0x0000, 0x2001, 0xb88f,
+	0x2004, 0x080c, 0x28a7, 0x60e2, 0x6803, 0x0080, 0x20a9, 0x0384,
+	0x6027, 0x1e00, 0x2009, 0x1e00, 0xe000, 0x6024, 0xa10c, 0x0138,
+	0x1d04, 0x5c20, 0x2091, 0x6000, 0x1f04, 0x5c20, 0x0820, 0x6028,
+	0xa085, 0x1e00, 0x602a, 0x70a4, 0xa005, 0x1118, 0x6887, 0x0001,
+	0x0008, 0x6886, 0xa006, 0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e,
+	0x001e, 0x015e, 0x0005, 0x0156, 0x0016, 0x0026, 0x0036, 0x00c6,
+	0x00d6, 0x00e6, 0x2061, 0x0100, 0x2071, 0xb600, 0x2069, 0x0140,
+	0x6020, 0xa084, 0x00c0, 0x0120, 0x6884, 0xa005, 0x1904, 0x5c97,
+	0x6803, 0x0088, 0x60e3, 0x0000, 0x6887, 0x0000, 0x2001, 0x0000,
+	0x080c, 0x28a7, 0x2069, 0x0200, 0x6804, 0xa005, 0x1118, 0x6808,
+	0xa005, 0x01c0, 0x6028, 0xa084, 0xfbff, 0x602a, 0x6027, 0x0400,
+	0x2069, 0xb8c6, 0x7000, 0x206a, 0x708f, 0x0026, 0x7003, 0x0001,
+	0x20a9, 0x0002, 0x1d04, 0x5c7a, 0x2091, 0x6000, 0x1f04, 0x5c7a,
+	0x0804, 0x5cc8, 0x2069, 0x0140, 0x20a9, 0x0384, 0x6027, 0x1e00,
+	0x2009, 0x1e00, 0xe000, 0x6024, 0xa10c, 0x0520, 0xa084, 0x1a00,
+	0x1508, 0x1d04, 0x5c86, 0x2091, 0x6000, 0x1f04, 0x5c86, 0x2011,
+	0x0003, 0x080c, 0x80fc, 0x2011, 0x0002, 0x080c, 0x8106, 0x080c,
+	0x7fe0, 0x2019, 0x0000, 0x080c, 0x806b, 0x6803, 0x00a0, 0x2001,
+	0xb89f, 0x2003, 0x0001, 0x2001, 0xb600, 0x2003, 0x0001, 0xa085,
+	0x0001, 0x00b0, 0x080c, 0x24e5, 0x6803, 0x0080, 0x2069, 0x0140,
+	0x60e3, 0x0000, 0x70a4, 0xa005, 0x1118, 0x6887, 0x0001, 0x0008,
+	0x6886, 0x2001, 0xb88f, 0x2004, 0x080c, 0x28a7, 0x60e2, 0xa006,
+	0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e, 0x001e, 0x015e, 0x0005,
+	0x0156, 0x0016, 0x0026, 0x0036, 0x00c6, 0x00d6, 0x00e6, 0x2061,
+	0x0100, 0x2071, 0xb600, 0x6020, 0xa084, 0x00c0, 0x01e0, 0x2011,
+	0x0003, 0x080c, 0x80fc, 0x2011, 0x0002, 0x080c, 0x8106, 0x080c,
+	0x7fe0, 0x2019, 0x0000, 0x080c, 0x806b, 0x2069, 0x0140, 0x6803,
+	0x00a0, 0x2001, 0xb89f, 0x2003, 0x0001, 0x2001, 0xb600, 0x2003,
+	0x0001, 0x0804, 0x5d6d, 0x2001, 0xb60c, 0x200c, 0xd1b4, 0x1160,
+	0xc1b5, 0x2102, 0x080c, 0x59fc, 0x2069, 0x0140, 0x080c, 0x24e5,
+	0x6803, 0x0080, 0x60e3, 0x0000, 0x2069, 0x0200, 0x6804, 0xa005,
+	0x1118, 0x6808, 0xa005, 0x01c0, 0x6028, 0xa084, 0xfdff, 0x602a,
+	0x6027, 0x0200, 0x2069, 0xb8c6, 0x7000, 0x206a, 0x708f, 0x0027,
+	0x7003, 0x0001, 0x20a9, 0x0002, 0x1d04, 0x5d24, 0x2091, 0x6000,
+	0x1f04, 0x5d24, 0x0804, 0x5d6d, 0x6027, 0x1e00, 0x2009, 0x1e00,
+	0xe000, 0x6024, 0xa10c, 0x01c8, 0xa084, 0x1c00, 0x11b0, 0x1d04,
+	0x5d2c, 0x0006, 0x0016, 0x00c6, 0x00d6, 0x00e6, 0x080c, 0x696b,
+	0x00ee, 0x00de, 0x00ce, 0x001e, 0x000e, 0x00e6, 0x2071, 0xb8f4,
+	0x7018, 0x00ee, 0xa005, 0x1d00, 0x0500, 0x0026, 0x2011, 0x5a14,
+	0x080c, 0x6a0e, 0x2011, 0x5a07, 0x080c, 0x6ace, 0x002e, 0x2069,
+	0x0140, 0x60e3, 0x0000, 0x70a4, 0xa005, 0x1118, 0x6887, 0x0001,
+	0x0008, 0x6886, 0x2001, 0xb88f, 0x2004, 0x080c, 0x28a7, 0x60e2,
+	0x2001, 0xb60c, 0x200c, 0xc1b4, 0x2102, 0x00ee, 0x00de, 0x00ce,
+	0x003e, 0x002e, 0x001e, 0x015e, 0x0005, 0x0156, 0x0016, 0x0026,
+	0x0036, 0x0046, 0x00c6, 0x00e6, 0x2061, 0x0100, 0x2071, 0xb600,
+	0x7130, 0xd184, 0x1180, 0x2011, 0xb653, 0x2214, 0xd2ec, 0x0138,
+	0xc18d, 0x7132, 0x2011, 0xb653, 0x2214, 0xd2ac, 0x1120, 0x7030,
+	0xd08c, 0x0904, 0x5dda, 0x7130, 0xc185, 0x7132, 0x2011, 0xb653,
+	0x220c, 0xd1a4, 0x0530, 0x0016, 0x2019, 0x000e, 0x080c, 0xb121,
+	0x0156, 0x20a9, 0x007f, 0x2009, 0x0000, 0xa186, 0x007e, 0x01a0,
+	0xa186, 0x0080, 0x0188, 0x080c, 0x501b, 0x1170, 0x8127, 0xa006,
+	0x0016, 0x2009, 0x000e, 0x080c, 0xb1a4, 0x2009, 0x0001, 0x2011,
+	0x0100, 0x080c, 0x6b8c, 0x001e, 0x8108, 0x1f04, 0x5da5, 0x015e,
+	0x001e, 0xd1ac, 0x1148, 0x0016, 0x2009, 0x0000, 0x2019, 0x0004,
+	0x080c, 0x2ca4, 0x001e, 0x0070, 0x0156, 0x20a9, 0x007f, 0x2009,
+	0x0000, 0x080c, 0x501b, 0x1110, 0x080c, 0x4c7e, 0x8108, 0x1f04,
+	0x5dd1, 0x015e, 0x080c, 0x1e63, 0x2011, 0x0003, 0x080c, 0x80fc,
+	0x2011, 0x0002, 0x080c, 0x8106, 0x080c, 0x7fe0, 0x0036, 0x2019,
+	0x0000, 0x080c, 0x806b, 0x003e, 0x60e3, 0x0000, 0x2001, 0xb600,
+	0x2003, 0x0001, 0x080c, 0x5a79, 0x00ee, 0x00ce, 0x004e, 0x003e,
+	0x002e, 0x001e, 0x015e, 0x0005, 0x2071, 0xb6e2, 0x7003, 0x0000,
+	0x7007, 0x0000, 0x700f, 0x0000, 0x702b, 0x0001, 0x704f, 0x0000,
+	0x7053, 0x0001, 0x705f, 0x0020, 0x7063, 0x0040, 0x7083, 0x0000,
+	0x708b, 0x0000, 0x708f, 0x0001, 0x70bf, 0x0000, 0x0005, 0x00e6,
+	0x2071, 0xb6e2, 0x6848, 0xa005, 0x1130, 0x7028, 0xc085, 0x702a,
+	0xa085, 0x0001, 0x0428, 0x6a50, 0x7236, 0x6b54, 0x733a, 0x6858,
+	0x703e, 0x707a, 0x685c, 0x7042, 0x707e, 0x6848, 0x702e, 0x6840,
+	0x7032, 0x2009, 0x000c, 0x200a, 0x8007, 0x8006, 0x8006, 0xa08c,
+	0x003f, 0xa084, 0xffc0, 0xa210, 0x2100, 0xa319, 0x7272, 0x7376,
+	0x7028, 0xc084, 0x702a, 0x7007, 0x0001, 0x700f, 0x0000, 0xa006,
+	0x00ee, 0x0005, 0x2b78, 0x2071, 0xb6e2, 0x7004, 0x0043, 0x700c,
+	0x0002, 0x5e56, 0x5e4d, 0x5e4d, 0x5e4d, 0x5e4d, 0x0005, 0x5eac,
+	0x5ead, 0x5edf, 0x5ee0, 0x5eaa, 0x5f2e, 0x5f33, 0x5f64, 0x5f65,
+	0x5f80, 0x5f81, 0x5f82, 0x5f83, 0x5f84, 0x5f85, 0x603b, 0x6062,
+	0x700c, 0x0002, 0x5e6f, 0x5eaa, 0x5eaa, 0x5eab, 0x5eab, 0x7830,
+	0x7930, 0xa106, 0x0120, 0x7830, 0x7930, 0xa106, 0x1510, 0x7030,
+	0xa10a, 0x01f8, 0x1210, 0x712c, 0xa10a, 0xa18a, 0x0002, 0x12d0,
+	0x080c, 0x15e4, 0x01b0, 0x2d00, 0x705a, 0x7063, 0x0040, 0x2001,
+	0x0003, 0x7057, 0x0000, 0x0126, 0x0006, 0x2091, 0x8000, 0x2009,
+	0xb913, 0x2104, 0xc085, 0x200a, 0x000e, 0x700e, 0x012e, 0x080c,
+	0x1664, 0x0005, 0x080c, 0x15e4, 0x0de0, 0x2d00, 0x705a, 0x080c,
+	0x15e4, 0x1108, 0x0c10, 0x2d00, 0x7086, 0x7063, 0x0080, 0x2001,
+	0x0004, 0x08f8, 0x0005, 0x0005, 0x0005, 0x700c, 0x0002, 0x5eb4,
+	0x5eb7, 0x5ec5, 0x5ede, 0x5ede, 0x080c, 0x5e68, 0x0005, 0x0126,
+	0x8001, 0x700e, 0x7058, 0x0006, 0x080c, 0x63b5, 0x0120, 0x2091,
+	0x8000, 0x080c, 0x5e68, 0x00de, 0x0048, 0x0126, 0x8001, 0x700e,
+	0x080c, 0x63b5, 0x7058, 0x2068, 0x7084, 0x705a, 0x6803, 0x0000,
+	0x6807, 0x0000, 0x6834, 0xa084, 0x00ff, 0xa08a, 0x003a, 0x1218,
+	0x00db, 0x012e, 0x0005, 0x012e, 0x080c, 0x5f86, 0x0005, 0x0005,
+	0x0005, 0x00e6, 0x2071, 0xb6e2, 0x700c, 0x0002, 0x5eeb, 0x5eeb,
+	0x5eeb, 0x5eed, 0x5ef0, 0x00ee, 0x0005, 0x700f, 0x0001, 0x0010,
+	0x700f, 0x0002, 0x00ee, 0x0005, 0x5f86, 0x5f86, 0x5fa2, 0x5f86,
+	0x611f, 0x5f86, 0x5f86, 0x5f86, 0x5f86, 0x5f86, 0x5fa2, 0x6161,
+	0x61a4, 0x61ed, 0x6201, 0x5f86, 0x5f86, 0x5fbe, 0x5fa2, 0x5f86,
+	0x5f86, 0x6018, 0x62ad, 0x62c8, 0x5f86, 0x5fbe, 0x5f86, 0x5f86,
+	0x5f86, 0x5f86, 0x600e, 0x62c8, 0x5f86, 0x5f86, 0x5f86, 0x5f86,
+	0x5f86, 0x5f86, 0x5f86, 0x5f86, 0x5f86, 0x5fd2, 0x5f86, 0x5f86,
+	0x5f86, 0x5f86, 0x5f86, 0x5f86, 0x5f86, 0x5f86, 0x5f86, 0x63d3,
+	0x5f86, 0x5f86, 0x5f86, 0x5f86, 0x5f86, 0x5fe7, 0x7020, 0x2068,
+	0x080c, 0x1614, 0x0005, 0x700c, 0x0002, 0x5f3a, 0x5f3d, 0x5f4b,
+	0x5f63, 0x5f63, 0x080c, 0x5e68, 0x0005, 0x0126, 0x8001, 0x700e,
+	0x7058, 0x0006, 0x080c, 0x63b5, 0x0120, 0x2091, 0x8000, 0x080c,
+	0x5e68, 0x00de, 0x0048, 0x0126, 0x8001, 0x700e, 0x080c, 0x63b5,
 	0x7058, 0x2068, 0x7084, 0x705a, 0x6803, 0x0000, 0x6807, 0x0000,
-	0x6834, 0xa084, 0x00ff, 0xa08a, 0x003a, 0x1218, 0x00db, 0x012e,
-	0x0005, 0x012e, 0x080c, 0x5f14, 0x0005, 0x0005, 0x0005, 0x00e6,
-	0x2071, 0xb5e2, 0x700c, 0x0002, 0x5e79, 0x5e79, 0x5e79, 0x5e7b,
-	0x5e7e, 0x00ee, 0x0005, 0x700f, 0x0001, 0x0010, 0x700f, 0x0002,
-	0x00ee, 0x0005, 0x5f14, 0x5f14, 0x5f30, 0x5f14, 0x60ad, 0x5f14,
-	0x5f14, 0x5f14, 0x5f14, 0x5f14, 0x5f30, 0x60ef, 0x6132, 0x617b,
-	0x618f, 0x5f14, 0x5f14, 0x5f4c, 0x5f30, 0x5f14, 0x5f14, 0x5fa6,
-	0x623b, 0x6256, 0x5f14, 0x5f4c, 0x5f14, 0x5f14, 0x5f14, 0x5f14,
-	0x5f9c, 0x6256, 0x5f14, 0x5f14, 0x5f14, 0x5f14, 0x5f14, 0x5f14,
-	0x5f14, 0x5f14, 0x5f14, 0x5f60, 0x5f14, 0x5f14, 0x5f14, 0x5f14,
-	0x5f14, 0x5f14, 0x5f14, 0x5f14, 0x5f14, 0x6361, 0x5f14, 0x5f14,
-	0x5f14, 0x5f14, 0x5f14, 0x5f75, 0x7020, 0x2068, 0x080c, 0x160f,
-	0x0005, 0x700c, 0x0002, 0x5ec8, 0x5ecb, 0x5ed9, 0x5ef1, 0x5ef1,
-	0x080c, 0x5df6, 0x0005, 0x0126, 0x8001, 0x700e, 0x7058, 0x0006,
-	0x080c, 0x6343, 0x0120, 0x2091, 0x8000, 0x080c, 0x5df6, 0x00de,
-	0x0048, 0x0126, 0x8001, 0x700e, 0x080c, 0x6343, 0x7058, 0x2068,
-	0x7084, 0x705a, 0x6803, 0x0000, 0x6807, 0x0000, 0x6834, 0xa084,
-	0x00ff, 0xa08a, 0x001a, 0x1218, 0x003b, 0x012e, 0x0005, 0x012e,
-	0x0419, 0x0005, 0x0005, 0x0005, 0x5f14, 0x5f30, 0x6099, 0x5f14,
-	0x5f30, 0x5f14, 0x5f30, 0x5f30, 0x5f14, 0x5f30, 0x6099, 0x5f30,
-	0x5f30, 0x5f30, 0x5f30, 0x5f30, 0x5f14, 0x5f30, 0x6099, 0x5f14,
-	0x5f14, 0x5f30, 0x5f14, 0x5f14, 0x5f14, 0x5f30, 0x0005, 0x0005,
-	0x0005, 0x0005, 0x0005, 0x0005, 0x7007, 0x0001, 0x6838, 0xa084,
-	0x00ff, 0xc0d5, 0x683a, 0x0126, 0x2091, 0x8000, 0x080c, 0x5408,
-	0x012e, 0x0005, 0x7007, 0x0001, 0x6838, 0xa084, 0x00ff, 0xc0e5,
-	0x683a, 0x0126, 0x2091, 0x8000, 0x080c, 0x5408, 0x012e, 0x0005,
-	0x7007, 0x0001, 0x6838, 0xa084, 0x00ff, 0xc0ed, 0x683a, 0x0126,
-	0x2091, 0x8000, 0x080c, 0x5408, 0x012e, 0x0005, 0x7007, 0x0001,
-	0x6838, 0xa084, 0x00ff, 0xc0dd, 0x683a, 0x0126, 0x2091, 0x8000,
-	0x080c, 0x5408, 0x012e, 0x0005, 0x6834, 0x8007, 0xa084, 0x00ff,
-	0x0988, 0x8001, 0x1120, 0x7007, 0x0001, 0x0804, 0x6059, 0x7007,
-	0x0006, 0x7012, 0x2d00, 0x7016, 0x701a, 0x704b, 0x6059, 0x0005,
-	0x6834, 0x8007, 0xa084, 0x00ff, 0x0904, 0x5f22, 0x8001, 0x1120,
-	0x7007, 0x0001, 0x0804, 0x6076, 0x7007, 0x0006, 0x7012, 0x2d00,
-	0x7016, 0x701a, 0x704b, 0x6076, 0x0005, 0x6834, 0x8007, 0xa084,
-	0x00ff, 0xa086, 0x0001, 0x1904, 0x5f22, 0x7007, 0x0001, 0x2009,
-	0xb531, 0x210c, 0x81ff, 0x11a8, 0x6838, 0xa084, 0x00ff, 0x683a,
-	0x6853, 0x0000, 0x080c, 0x4d82, 0x1108, 0x0005, 0x0126, 0x2091,
-	0x8000, 0x6837, 0x0139, 0x684a, 0x6952, 0x080c, 0x5408, 0x012e,
-	0x0ca0, 0x2001, 0x0028, 0x0c90, 0x684c, 0xa084, 0x00c0, 0xa086,
-	0x00c0, 0x1120, 0x7007, 0x0001, 0x0804, 0x626e, 0x2d00, 0x7016,
-	0x701a, 0x20a9, 0x0004, 0xa080, 0x0024, 0x2098, 0x20a1, 0xb60d,
-	0x53a3, 0x6858, 0x7012, 0xa082, 0x0401, 0x1a04, 0x5f3e, 0x6a84,
-	0xa28a, 0x0002, 0x1a04, 0x5f3e, 0x82ff, 0x1138, 0x6888, 0x698c,
-	0xa105, 0x0118, 0x2001, 0x602c, 0x0018, 0xa280, 0x6022, 0x2005,
-	0x70c6, 0x7010, 0xa015, 0x0904, 0x600e, 0x080c, 0x15df, 0x1118,
-	0x7007, 0x000f, 0x0005, 0x2d00, 0x7022, 0x70c4, 0x2060, 0x2c05,
-	0x6836, 0xe004, 0xad00, 0x7096, 0xe008, 0xa20a, 0x1210, 0xa00e,
-	0x2200, 0x7112, 0xe20c, 0x8003, 0x800b, 0xa296, 0x0004, 0x0108,
-	0xa108, 0x719a, 0x810b, 0x719e, 0xae90, 0x0022, 0x080c, 0x1643,
-	0x7090, 0xa08e, 0x0100, 0x0170, 0xa086, 0x0200, 0x0118, 0x7007,
-	0x0010, 0x0005, 0x7020, 0x2068, 0x080c, 0x160f, 0x7014, 0x2068,
-	0x0804, 0x5f3e, 0x7020, 0x2068, 0x7018, 0x6802, 0x6807, 0x0000,
-	0x2d08, 0x2068, 0x6906, 0x711a, 0x0804, 0x5fc9, 0x7014, 0x2068,
-	0x7007, 0x0001, 0x6884, 0xa005, 0x1128, 0x6888, 0x698c, 0xa105,
-	0x0108, 0x00b1, 0x6834, 0xa084, 0x00ff, 0xa086, 0x001e, 0x0904,
-	0x626e, 0x04b8, 0x6024, 0x6028, 0x0002, 0x0011, 0x0007, 0x0004,
-	0x000a, 0x000f, 0x0005, 0x0006, 0x000a, 0x0011, 0x0005, 0x0004,
-	0x00f6, 0x00e6, 0x00c6, 0x0076, 0x0066, 0x6f88, 0x6e8c, 0x6804,
-	0x2060, 0xacf0, 0x0021, 0xacf8, 0x0027, 0x2009, 0x0005, 0x700c,
-	0x7816, 0x7008, 0x7812, 0x7004, 0x7806, 0x7000, 0x7802, 0x7e0e,
-	0x7f0a, 0x8109, 0x0128, 0xaef2, 0x0004, 0xaffa, 0x0006, 0x0c78,
-	0x6004, 0xa065, 0x1d30, 0x006e, 0x007e, 0x00ce, 0x00ee, 0x00fe,
-	0x0005, 0x2009, 0xb531, 0x210c, 0x81ff, 0x1198, 0x6838, 0xa084,
-	0x00ff, 0x683a, 0x080c, 0x4c64, 0x1108, 0x0005, 0x080c, 0x54db,
-	0x0126, 0x2091, 0x8000, 0x080c, 0x9ecc, 0x080c, 0x5408, 0x012e,
-	0x0ca0, 0x2001, 0x0028, 0x2009, 0x0000, 0x0c80, 0x2009, 0xb531,
-	0x210c, 0x81ff, 0x11b0, 0x6858, 0xa005, 0x01c0, 0x6838, 0xa084,
-	0x00ff, 0x683a, 0x6853, 0x0000, 0x080c, 0x4d26, 0x1108, 0x0005,
-	0x0126, 0x2091, 0x8000, 0x684a, 0x6952, 0x080c, 0x5408, 0x012e,
-	0x0cb0, 0x2001, 0x0028, 0x2009, 0x0000, 0x0c90, 0x2001, 0x0000,
-	0x0c78, 0x7018, 0x6802, 0x2d08, 0x2068, 0x6906, 0x711a, 0x7010,
-	0x8001, 0x7012, 0x0118, 0x7007, 0x0006, 0x0030, 0x7014, 0x2068,
-	0x7007, 0x0001, 0x7048, 0x080f, 0x0005, 0x7007, 0x0001, 0x6944,
-	0x810f, 0xa18c, 0x00ff, 0x6848, 0xa084, 0x00ff, 0x20a9, 0x0001,
-	0xa096, 0x0001, 0x01b0, 0x2009, 0x0000, 0x20a9, 0x00ff, 0xa096,
-	0x0002, 0x0178, 0xa005, 0x11f0, 0x6944, 0x810f, 0xa18c, 0x00ff,
-	0x080c, 0x4fa9, 0x11b8, 0x0066, 0x6e50, 0x080c, 0x50a8, 0x006e,
-	0x0088, 0x0046, 0x2011, 0xb50c, 0x2224, 0xc484, 0x2412, 0x004e,
-	0x00c6, 0x080c, 0x4fa9, 0x1110, 0x080c, 0x5209, 0x8108, 0x1f04,
-	0x60d9, 0x00ce, 0x684c, 0xd084, 0x1118, 0x080c, 0x160f, 0x0005,
-	0x0126, 0x2091, 0x8000, 0x080c, 0x5408, 0x012e, 0x0005, 0x0126,
-	0x2091, 0x8000, 0x7007, 0x0001, 0x2001, 0xb553, 0x2004, 0xd0a4,
-	0x0580, 0x2061, 0xb874, 0x6100, 0xd184, 0x0178, 0x6858, 0xa084,
-	0x00ff, 0x1550, 0x6000, 0xd084, 0x0520, 0x6004, 0xa005, 0x1538,
-	0x6003, 0x0000, 0x600b, 0x0000, 0x00c8, 0x2011, 0x0001, 0x6860,
-	0xa005, 0x1110, 0x2001, 0x001e, 0x8000, 0x6016, 0x6858, 0xa084,
-	0x00ff, 0x0178, 0x6006, 0x6858, 0x8007, 0xa084, 0x00ff, 0x0148,
-	0x600a, 0x6858, 0x8000, 0x1108, 0xc28d, 0x6202, 0x012e, 0x0804,
-	0x6332, 0x012e, 0x0804, 0x632c, 0x012e, 0x0804, 0x6326, 0x012e,
-	0x0804, 0x6329, 0x0126, 0x2091, 0x8000, 0x7007, 0x0001, 0x2001,
-	0xb553, 0x2004, 0xd0a4, 0x05e0, 0x2061, 0xb874, 0x6000, 0xd084,
-	0x05b8, 0x6204, 0x6308, 0xd08c, 0x1530, 0x6c48, 0xa484, 0x0003,
-	0x0170, 0x6958, 0xa18c, 0x00ff, 0x8001, 0x1120, 0x2100, 0xa210,
-	0x0620, 0x0028, 0x8001, 0x1508, 0x2100, 0xa212, 0x02f0, 0xa484,
-	0x000c, 0x0188, 0x6958, 0x810f, 0xa18c, 0x00ff, 0xa082, 0x0004,
-	0x1120, 0x2100, 0xa318, 0x0288, 0x0030, 0xa082, 0x0004, 0x1168,
-	0x2100, 0xa31a, 0x0250, 0x6860, 0xa005, 0x0110, 0x8000, 0x6016,
-	0x6206, 0x630a, 0x012e, 0x0804, 0x6332, 0x012e, 0x0804, 0x632f,
-	0x012e, 0x0804, 0x632c, 0x0126, 0x2091, 0x8000, 0x7007, 0x0001,
-	0x2061, 0xb874, 0x6300, 0xd38c, 0x1120, 0x6308, 0x8318, 0x0220,
-	0x630a, 0x012e, 0x0804, 0x6340, 0x012e, 0x0804, 0x632f, 0x0126,
-	0x00c6, 0x2091, 0x8000, 0x7007, 0x0001, 0x684c, 0xd0ac, 0x0148,
-	0x00c6, 0x2061, 0xb874, 0x6000, 0xa084, 0xfcff, 0x6002, 0x00ce,
-	0x0448, 0x6858, 0xa005, 0x05d0, 0x685c, 0xa065, 0x0598, 0x2001,
-	0xb531, 0x2004, 0xa005, 0x0118, 0x080c, 0x9e1d, 0x0068, 0x6013,
-	0x0400, 0x6057, 0x0000, 0x694c, 0xd1a4, 0x0110, 0x6950, 0x6156,
-	0x2009, 0x0041, 0x080c, 0x864c, 0x6958, 0xa18c, 0xff00, 0xa186,
-	0x2000, 0x1140, 0x0026, 0x2009, 0x0000, 0x2011, 0xfdff, 0x080c,
-	0x6b1a, 0x002e, 0x684c, 0xd0c4, 0x0148, 0x2061, 0xb874, 0x6000,
-	0xd08c, 0x1120, 0x6008, 0x8000, 0x0208, 0x600a, 0x00ce, 0x012e,
-	0x0804, 0x6332, 0x00ce, 0x012e, 0x0804, 0x632c, 0x6954, 0xa186,
-	0x002e, 0x0d40, 0xa186, 0x002d, 0x0d28, 0xa186, 0x0045, 0x0528,
-	0xa186, 0x002a, 0x1130, 0x2001, 0xb50c, 0x200c, 0xc194, 0x2102,
-	0x08c8, 0xa186, 0x0020, 0x0170, 0xa186, 0x0029, 0x1d18, 0x6944,
-	0xa18c, 0xff00, 0x810f, 0x080c, 0x4fa9, 0x1960, 0x6000, 0xc0e4,
-	0x6002, 0x0840, 0x685c, 0xa065, 0x09a8, 0x6007, 0x0024, 0x2001,
-	0xb7b6, 0x2004, 0x6016, 0x0804, 0x61ca, 0x685c, 0xa065, 0x0950,
-	0x00e6, 0x6860, 0xa075, 0x2001, 0xb531, 0x2004, 0xa005, 0x0150,
-	0x080c, 0x9e1d, 0x8eff, 0x0118, 0x2e60, 0x080c, 0x9e1d, 0x00ee,
-	0x0804, 0x61ca, 0x6020, 0xc0dc, 0xc0d5, 0x6022, 0x2e60, 0x6007,
-	0x003a, 0x6870, 0xa005, 0x0130, 0x6007, 0x003b, 0x6874, 0x602a,
-	0x6878, 0x6012, 0x6003, 0x0001, 0x080c, 0x6c8d, 0x080c, 0x7173,
-	0x00ee, 0x0804, 0x61ca, 0x2061, 0xb874, 0x6000, 0xd084, 0x0190,
-	0xd08c, 0x1904, 0x6340, 0x0126, 0x2091, 0x8000, 0x6204, 0x8210,
-	0x0220, 0x6206, 0x012e, 0x0804, 0x6340, 0x012e, 0x6853, 0x0016,
-	0x0804, 0x6339, 0x6853, 0x0007, 0x0804, 0x6339, 0x6834, 0x8007,
-	0xa084, 0x00ff, 0x1118, 0x080c, 0x5f22, 0x0078, 0x2030, 0x8001,
-	0x1120, 0x7007, 0x0001, 0x0051, 0x0040, 0x7007, 0x0006, 0x7012,
-	0x2d00, 0x7016, 0x701a, 0x704b, 0x626e, 0x0005, 0x00e6, 0x0126,
-	0x2091, 0x8000, 0xa03e, 0x2009, 0xb531, 0x210c, 0x81ff, 0x1904,
-	0x62ec, 0x2009, 0xb50c, 0x210c, 0xd194, 0x1904, 0x6316, 0x6848,
-	0x2070, 0xae82, 0xbd00, 0x0a04, 0x62e0, 0x2001, 0xb517, 0x2004,
-	0xae02, 0x1a04, 0x62e0, 0x711c, 0xa186, 0x0006, 0x1904, 0x62cf,
-	0x7018, 0xa005, 0x0904, 0x62ec, 0x2004, 0xd0e4, 0x1904, 0x6311,
-	0x2061, 0xb874, 0x6100, 0xa184, 0x0301, 0xa086, 0x0001, 0x1550,
-	0x7020, 0xd0dc, 0x1904, 0x6319, 0x6853, 0x0000, 0x6803, 0x0000,
-	0x2d08, 0x7010, 0xa005, 0x1158, 0x7112, 0x684c, 0xd0f4, 0x1904,
-	0x631c, 0x2e60, 0x080c, 0x6a76, 0x012e, 0x00ee, 0x0005, 0x2068,
-	0x6800, 0xa005, 0x1de0, 0x6902, 0x2168, 0x684c, 0xd0f4, 0x1904,
-	0x631c, 0x012e, 0x00ee, 0x0005, 0x012e, 0x00ee, 0x6853, 0x0006,
-	0x0804, 0x6339, 0xd184, 0x0dc0, 0xd1c4, 0x11a8, 0x00b8, 0x6944,
-	0xa18c, 0xff00, 0x810f, 0x080c, 0x4fa9, 0x15d8, 0x6000, 0xd0e4,
-	0x15c0, 0x711c, 0xa186, 0x0007, 0x1118, 0x6853, 0x0002, 0x0498,
-	0x6853, 0x0008, 0x0480, 0x6853, 0x000e, 0x0468, 0x6853, 0x0017,
-	0x0450, 0x6853, 0x0035, 0x0438, 0x2001, 0xb572, 0x2004, 0xd0fc,
-	0x01e8, 0x6848, 0x2070, 0xae82, 0xbd00, 0x02c0, 0x605c, 0xae02,
-	0x12a8, 0x711c, 0xa186, 0x0006, 0x1188, 0x7018, 0xa005, 0x0170,
-	0x2004, 0xd0bc, 0x0158, 0x2039, 0x0001, 0x7000, 0xa086, 0x0007,
-	0x1904, 0x6279, 0x7003, 0x0002, 0x0804, 0x6279, 0x6853, 0x0028,
-	0x0010, 0x6853, 0x0029, 0x012e, 0x00ee, 0x0418, 0x6853, 0x002a,
-	0x0cd0, 0x6853, 0x0045, 0x0cb8, 0x2e60, 0x2019, 0x0002, 0x6017,
-	0x0014, 0x080c, 0xace0, 0x012e, 0x00ee, 0x0005, 0x2009, 0x003e,
-	0x0058, 0x2009, 0x0004, 0x0040, 0x2009, 0x0006, 0x0028, 0x2009,
-	0x0016, 0x0010, 0x2009, 0x0001, 0x6854, 0xa084, 0xff00, 0xa105,
-	0x6856, 0x0126, 0x2091, 0x8000, 0x080c, 0x5408, 0x012e, 0x0005,
-	0x080c, 0x160f, 0x0005, 0x702c, 0x7130, 0x8108, 0xa102, 0x0230,
-	0xa00e, 0x7034, 0x7072, 0x7038, 0x7076, 0x0058, 0x7070, 0xa080,
-	0x0040, 0x7072, 0x1230, 0x7074, 0xa081, 0x0000, 0x7076, 0xa085,
-	0x0001, 0x7932, 0x7132, 0x0005, 0x00d6, 0x080c, 0x6a6d, 0x00de,
-	0x0005, 0x00d6, 0x00c6, 0x0036, 0x0026, 0x0016, 0x7007, 0x0001,
-	0x6a44, 0xa282, 0x0004, 0x1a04, 0x63ac, 0xd284, 0x0170, 0x6a4c,
-	0xa290, 0xb635, 0x2204, 0xa065, 0x6004, 0x05e0, 0x8007, 0xa084,
-	0x00ff, 0xa084, 0x0006, 0x1108, 0x04a8, 0x2c10, 0x080c, 0x85c7,
-	0x1118, 0x080c, 0x9ed6, 0x05a0, 0x621a, 0x6844, 0x0002, 0x638b,
-	0x6390, 0x6393, 0x6399, 0x2019, 0x0002, 0x080c, 0xb065, 0x0060,
-	0x080c, 0xaffc, 0x0048, 0x2019, 0x0002, 0x6950, 0x080c, 0xb017,
-	0x0018, 0x6950, 0x080c, 0xaffc, 0x080c, 0x861d, 0x6857, 0x0000,
-	0x0126, 0x2091, 0x8000, 0x080c, 0x5408, 0x012e, 0x001e, 0x002e,
-	0x003e, 0x00ce, 0x00de, 0x0005, 0x6857, 0x0006, 0x0c88, 0x6857,
-	0x0002, 0x0c70, 0x6857, 0x0005, 0x0c58, 0x6857, 0x0004, 0x0c40,
-	0x6857, 0x0007, 0x0c28, 0x00d6, 0x2011, 0x0004, 0x2204, 0xa085,
-	0x8002, 0x2012, 0x00de, 0x0005, 0x20e1, 0x0002, 0x3d08, 0x20e1,
-	0x2000, 0x3d00, 0xa084, 0x7000, 0x0118, 0xa086, 0x1000, 0x1570,
-	0x20e1, 0x0000, 0x3d00, 0xa094, 0xff00, 0x8217, 0xa084, 0xf000,
-	0xa086, 0x3000, 0x1160, 0xa184, 0xff00, 0x8007, 0xa086, 0x0008,
-	0x11e8, 0x080c, 0x2dbf, 0x11d0, 0x080c, 0x6603, 0x0098, 0x20e1,
-	0x0004, 0x3d60, 0xd1bc, 0x1108, 0x3e60, 0xac84, 0x0007, 0x1170,
-	0xac82, 0xbd00, 0x0258, 0x685c, 0xac02, 0x1240, 0x2009, 0x0047,
-	0x080c, 0x864c, 0x7a1c, 0xd284, 0x1938, 0x0005, 0xa016, 0x080c,
-	0x185e, 0x0cc0, 0x0cd8, 0x781c, 0xd08c, 0x0500, 0x0156, 0x0136,
-	0x0146, 0x20e1, 0x3000, 0x3d20, 0x3e28, 0xa584, 0x0076, 0x1538,
-	0xa484, 0x7000, 0xa086, 0x1000, 0x11a8, 0x080c, 0x647e, 0x01f8,
-	0x20e1, 0x3000, 0x7828, 0x7828, 0x080c, 0x649a, 0x014e, 0x013e,
-	0x015e, 0x2009, 0xb7e8, 0x2104, 0xa005, 0x1108, 0x0005, 0x080c,
-	0x7173, 0x0ce0, 0xa484, 0x7000, 0x1548, 0x080c, 0x647e, 0x01d8,
-	0x7000, 0xa084, 0xff00, 0xa086, 0x8100, 0x0d10, 0x00a0, 0xd5a4,
-	0x0178, 0x0056, 0x0046, 0x080c, 0x1e6e, 0x080c, 0x24b0, 0x2001,
-	0x0160, 0x2502, 0x2001, 0x0138, 0x2202, 0x004e, 0x005e, 0x0048,
-	0x04a9, 0x6887, 0x0000, 0x080c, 0xb3df, 0x20e1, 0x3000, 0x7828,
-	0x7828, 0x00b9, 0x014e, 0x013e, 0x015e, 0x0880, 0x0439, 0x1130,
-	0x7000, 0xa084, 0xff00, 0xa086, 0x8100, 0x1d68, 0x080c, 0xb3df,
-	0x20e1, 0x3000, 0x7828, 0x7828, 0x0056, 0x080c, 0x6874, 0x005e,
-	0x0c40, 0x2001, 0xb50e, 0x2004, 0xd08c, 0x0178, 0x2001, 0xb500,
-	0x2004, 0xa086, 0x0003, 0x1148, 0x0026, 0x0036, 0x2011, 0x8048,
-	0x2518, 0x080c, 0x3ecc, 0x003e, 0x002e, 0x0005, 0xa484, 0x01ff,
-	0x6886, 0xa005, 0x0160, 0xa080, 0x001f, 0xa084, 0x03f8, 0x80ac,
-	0x20e1, 0x1000, 0x2ea0, 0x2099, 0x020a, 0x53a5, 0x0005, 0x20a9,
-	0x000c, 0x20e1, 0x1000, 0x2ea0, 0x2099, 0x020a, 0x53a5, 0xa085,
-	0x0001, 0x0ca0, 0x7000, 0xa084, 0xff00, 0xa08c, 0xf000, 0x8007,
-	0xa196, 0x0000, 0x1118, 0x0804, 0x6708, 0x0005, 0xa196, 0x2000,
-	0x1148, 0x6900, 0xa18e, 0x0001, 0x1118, 0x080c, 0x448f, 0x0ca8,
-	0x0039, 0x0c98, 0xa196, 0x8000, 0x1d80, 0x080c, 0x67b4, 0x0c68,
-	0x00c6, 0x6a84, 0x82ff, 0x0904, 0x65fd, 0x7110, 0xa18c, 0xff00,
-	0x810f, 0xa196, 0x0001, 0x0120, 0xa196, 0x0023, 0x1904, 0x65fd,
-	0xa08e, 0x0023, 0x1570, 0x080c, 0x684f, 0x0904, 0x65fd, 0x7124,
-	0x610a, 0x7030, 0xa08e, 0x0200, 0x1150, 0x7034, 0xa005, 0x1904,
-	0x65fd, 0x2009, 0x0015, 0x080c, 0x864c, 0x0804, 0x65fd, 0xa08e,
-	0x0214, 0x0118, 0xa08e, 0x0210, 0x1130, 0x2009, 0x0015, 0x080c,
-	0x864c, 0x0804, 0x65fd, 0xa08e, 0x0100, 0x1904, 0x65fd, 0x7034,
-	0xa005, 0x1904, 0x65fd, 0x2009, 0x0016, 0x080c, 0x864c, 0x0804,
-	0x65fd, 0xa08e, 0x0022, 0x1904, 0x65fd, 0x7030, 0xa08e, 0x0300,
-	0x1580, 0x68d4, 0xd0a4, 0x0528, 0xc0b5, 0x68d6, 0x7100, 0xa18c,
-	0x00ff, 0x6972, 0x7004, 0x6876, 0x00f6, 0x2079, 0x0100, 0x79e6,
-	0x78ea, 0x0006, 0xa084, 0x00ff, 0x0016, 0x2008, 0x080c, 0x2847,
-	0x7932, 0x7936, 0x001e, 0x000e, 0x00fe, 0x080c, 0x281d, 0x6952,
-	0x703c, 0x00e6, 0x2071, 0x0140, 0x7086, 0x2071, 0xb500, 0x70a6,
-	0x00ee, 0x7034, 0xa005, 0x1904, 0x65fd, 0x2009, 0x0017, 0x0804,
-	0x65c3, 0xa08e, 0x0400, 0x1158, 0x7034, 0xa005, 0x1904, 0x65fd,
-	0x68d4, 0xc0a5, 0x68d6, 0x2009, 0x0030, 0x0804, 0x65c3, 0xa08e,
-	0x0500, 0x1140, 0x7034, 0xa005, 0x1904, 0x65fd, 0x2009, 0x0018,
-	0x0804, 0x65c3, 0xa08e, 0x2010, 0x1120, 0x2009, 0x0019, 0x0804,
-	0x65c3, 0xa08e, 0x2110, 0x1120, 0x2009, 0x001a, 0x0804, 0x65c3,
-	0xa08e, 0x5200, 0x1140, 0x7034, 0xa005, 0x1904, 0x65fd, 0x2009,
-	0x001b, 0x0804, 0x65c3, 0xa08e, 0x5000, 0x1140, 0x7034, 0xa005,
-	0x1904, 0x65fd, 0x2009, 0x001c, 0x0804, 0x65c3, 0xa08e, 0x1300,
-	0x1120, 0x2009, 0x0034, 0x0804, 0x65c3, 0xa08e, 0x1200, 0x1140,
-	0x7034, 0xa005, 0x1904, 0x65fd, 0x2009, 0x0024, 0x0804, 0x65c3,
-	0xa08c, 0xff00, 0xa18e, 0x2400, 0x1118, 0x2009, 0x002d, 0x04d8,
-	0xa08c, 0xff00, 0xa18e, 0x5300, 0x1118, 0x2009, 0x002a, 0x0498,
-	0xa08e, 0x0f00, 0x1118, 0x2009, 0x0020, 0x0468, 0xa08e, 0x5300,
-	0x1108, 0x00d8, 0xa08e, 0x6104, 0x11c0, 0x2011, 0xbb8d, 0x8208,
-	0x2204, 0xa082, 0x0004, 0x20a8, 0x95ac, 0x95ac, 0x2011, 0x8015,
-	0x211c, 0x8108, 0x0046, 0x2124, 0x080c, 0x3ecc, 0x004e, 0x8108,
-	0x1f04, 0x65a6, 0x2009, 0x0023, 0x0070, 0xa08e, 0x6000, 0x1118,
-	0x2009, 0x003f, 0x0040, 0xa08e, 0x7800, 0x1118, 0x2009, 0x0045,
-	0x0010, 0x2009, 0x001d, 0x0016, 0x2011, 0xbb83, 0x2204, 0x8211,
-	0x220c, 0x080c, 0x281d, 0x1598, 0x080c, 0x4f4d, 0x1580, 0x6612,
-	0x6516, 0x86ff, 0x01e8, 0x001e, 0x0016, 0xa186, 0x0017, 0x1158,
-	0x6870, 0xa606, 0x11a8, 0x6874, 0xa506, 0xa084, 0xff00, 0x1180,
-	0x6000, 0xc0f5, 0x6002, 0xa186, 0x0046, 0x1150, 0x6870, 0xa606,
-	0x1138, 0x6874, 0xa506, 0xa084, 0xff00, 0x1110, 0x001e, 0x0068,
-	0x00c6, 0x080c, 0x85c7, 0x0168, 0x001e, 0x611a, 0x601f, 0x0004,
-	0x7120, 0x610a, 0x001e, 0x080c, 0x864c, 0x00ce, 0x0005, 0x001e,
-	0x0ce0, 0x00ce, 0x0ce0, 0x00c6, 0x0046, 0x080c, 0x6657, 0x1904,
-	0x6654, 0xa28e, 0x0033, 0x11e8, 0x080c, 0x684f, 0x0904, 0x6654,
-	0x7124, 0x610a, 0x7030, 0xa08e, 0x0200, 0x1140, 0x7034, 0xa005,
-	0x15d8, 0x2009, 0x0015, 0x080c, 0x864c, 0x04b0, 0xa08e, 0x0100,
-	0x1598, 0x7034, 0xa005, 0x1580, 0x2009, 0x0016, 0x080c, 0x864c,
-	0x0458, 0xa28e, 0x0032, 0x1540, 0x7030, 0xa08e, 0x1400, 0x1520,
-	0x2009, 0x0038, 0x0016, 0x2011, 0xbb83, 0x2204, 0x8211, 0x220c,
-	0x080c, 0x281d, 0x11c0, 0x080c, 0x4f4d, 0x11a8, 0x6612, 0x6516,
-	0x00c6, 0x080c, 0x85c7, 0x0170, 0x001e, 0x611a, 0x080c, 0xa027,
-	0x601f, 0x0004, 0x7120, 0x610a, 0x001e, 0x080c, 0x864c, 0x080c,
-	0x7173, 0x0010, 0x00ce, 0x001e, 0x004e, 0x00ce, 0x0005, 0x00f6,
-	0x00d6, 0x0026, 0x0016, 0x0136, 0x0146, 0x0156, 0x3c00, 0x0006,
-	0x2079, 0x0030, 0x2069, 0x0200, 0x080c, 0x1f2d, 0x1590, 0x080c,
-	0x1dd2, 0x05e0, 0x04f1, 0x1130, 0x7908, 0xa18c, 0x1fff, 0xa182,
-	0x0011, 0x1688, 0x20a9, 0x000c, 0x20e1, 0x0000, 0x2ea0, 0x2099,
-	0x020a, 0x53a5, 0x20e1, 0x2000, 0x2001, 0x020a, 0x2004, 0x7a0c,
-	0x7808, 0xa080, 0x0007, 0xa084, 0x1ff8, 0x0419, 0x1120, 0xa08a,
-	0x0140, 0x1a0c, 0x1515, 0x80ac, 0x20e1, 0x6000, 0x2099, 0x020a,
-	0x53a5, 0x20e1, 0x7000, 0x6828, 0x6828, 0x7803, 0x0004, 0xa294,
-	0x0070, 0x000e, 0x20e0, 0x015e, 0x014e, 0x013e, 0x001e, 0x002e,
-	0x00de, 0x00fe, 0x0005, 0xa016, 0x080c, 0x185e, 0xa085, 0x0001,
-	0x0c80, 0x0006, 0x2001, 0x0111, 0x2004, 0xa084, 0x0003, 0x000e,
-	0x0005, 0x0046, 0x00e6, 0x00d6, 0x2028, 0x2130, 0xa696, 0x00ff,
-	0x1198, 0xa596, 0xfffd, 0x1120, 0x2009, 0x007f, 0x0804, 0x6703,
-	0xa596, 0xfffe, 0x1118, 0x2009, 0x007e, 0x04e8, 0xa596, 0xfffc,
-	0x1118, 0x2009, 0x0080, 0x04b8, 0x2011, 0x0000, 0x2019, 0xb535,
-	0x231c, 0xd3ac, 0x0138, 0x2021, 0x0000, 0x20a9, 0x00ff, 0x2071,
-	0xb635, 0x0030, 0x2021, 0x0081, 0x20a9, 0x007e, 0x2071, 0xb6b6,
-	0x2e1c, 0x83ff, 0x1128, 0x82ff, 0x1198, 0x2410, 0xc2fd, 0x0080,
-	0x2368, 0x6f10, 0x0006, 0x2100, 0xa706, 0x000e, 0x6b14, 0x1120,
-	0xa346, 0x1110, 0x2408, 0x0078, 0x87ff, 0x1110, 0x83ff, 0x0d58,
-	0x8420, 0x8e70, 0x1f04, 0x66e0, 0x82ff, 0x1118, 0xa085, 0x0001,
-	0x0018, 0xc2fc, 0x2208, 0xa006, 0x00de, 0x00ee, 0x004e, 0x0005,
-	0xa084, 0x0007, 0x000a, 0x0005, 0x6714, 0x6714, 0x6714, 0x6861,
-	0x6714, 0x6715, 0x672a, 0x679f, 0x0005, 0x7110, 0xd1bc, 0x0188,
-	0x7120, 0x2160, 0xac8c, 0x0007, 0x1160, 0xac8a, 0xbd00, 0x0248,
-	0x685c, 0xac02, 0x1230, 0x7124, 0x610a, 0x2009, 0x0046, 0x080c,
-	0x864c, 0x0005, 0x00c6, 0xa484, 0x01ff, 0x0904, 0x677d, 0x7110,
-	0xd1bc, 0x1904, 0x677d, 0x2011, 0xbb83, 0x2204, 0x8211, 0x220c,
-	0x080c, 0x281d, 0x1904, 0x677d, 0x080c, 0x4f4d, 0x15f0, 0x6612,
-	0x6516, 0x6000, 0xd0ec, 0x15c8, 0x6204, 0xa294, 0xff00, 0x8217,
-	0xa286, 0x0006, 0x0148, 0x6204, 0xa294, 0x00ff, 0xa286, 0x0006,
-	0x11a0, 0xa295, 0x0600, 0x6206, 0x00c6, 0x080c, 0x85c7, 0x001e,
-	0x0530, 0x611a, 0x601f, 0x0006, 0x7120, 0x610a, 0x7130, 0x6152,
-	0x2009, 0x0044, 0x080c, 0x864c, 0x00c0, 0x00c6, 0x080c, 0x85c7,
-	0x001e, 0x0198, 0x611a, 0x601f, 0x0004, 0x7120, 0x610a, 0xa286,
-	0x0004, 0x1118, 0x6007, 0x0005, 0x0010, 0x6007, 0x0001, 0x6003,
-	0x0001, 0x080c, 0x6cd3, 0x080c, 0x7173, 0x00ce, 0x0005, 0x2001,
-	0xb50d, 0x2004, 0xd0ec, 0x0120, 0x2011, 0x8049, 0x080c, 0x3ecc,
-	0x00c6, 0x080c, 0x9ed6, 0x001e, 0x0d80, 0x611a, 0x601f, 0x0006,
-	0x7120, 0x610a, 0x7130, 0x6152, 0x6013, 0x0300, 0x6003, 0x0001,
-	0x6007, 0x0041, 0x080c, 0x6c8d, 0x080c, 0x7173, 0x08f0, 0x7110,
-	0xd1bc, 0x0188, 0x7020, 0x2060, 0xac84, 0x0007, 0x1160, 0xac82,
-	0xbd00, 0x0248, 0x685c, 0xac02, 0x1230, 0x7124, 0x610a, 0x2009,
-	0x0045, 0x080c, 0x864c, 0x0005, 0x0006, 0x080c, 0x2dbf, 0x000e,
-	0x1168, 0x7110, 0xa18c, 0xff00, 0x810f, 0xa18e, 0x0000, 0x1130,
-	0xa084, 0x000f, 0xa08a, 0x0006, 0x1208, 0x000b, 0x0005, 0x67cd,
-	0x67ce, 0x67cd, 0x67cd, 0x6837, 0x6843, 0x0005, 0x7110, 0xd1bc,
-	0x0120, 0x702c, 0xd084, 0x0904, 0x6836, 0x700c, 0x7108, 0x080c,
-	0x281d, 0x1904, 0x6836, 0x080c, 0x4f4d, 0x1904, 0x6836, 0x6612,
-	0x6516, 0x6204, 0x7110, 0xd1bc, 0x01f8, 0xa28c, 0x00ff, 0xa186,
-	0x0004, 0x0118, 0xa186, 0x0006, 0x15c8, 0x00c6, 0x080c, 0x684f,
-	0x00ce, 0x0904, 0x6836, 0x00c6, 0x080c, 0x85c7, 0x001e, 0x05f0,
-	0x611a, 0x080c, 0xa027, 0x601f, 0x0002, 0x7120, 0x610a, 0x2009,
-	0x0088, 0x080c, 0x864c, 0x0490, 0xa28c, 0x00ff, 0xa186, 0x0006,
-	0x0160, 0xa186, 0x0004, 0x0148, 0xa294, 0xff00, 0x8217, 0xa286,
-	0x0004, 0x0118, 0xa286, 0x0006, 0x1188, 0x00c6, 0x080c, 0x85c7,
-	0x001e, 0x01e0, 0x611a, 0x080c, 0xa027, 0x601f, 0x0005, 0x7120,
-	0x610a, 0x2009, 0x0088, 0x080c, 0x864c, 0x0080, 0x00c6, 0x080c,
-	0x85c7, 0x001e, 0x0158, 0x611a, 0x080c, 0xa027, 0x601f, 0x0004,
-	0x7120, 0x610a, 0x2009, 0x0001, 0x080c, 0x864c, 0x0005, 0x7110,
-	0xd1bc, 0x0140, 0x00a1, 0x0130, 0x7124, 0x610a, 0x2009, 0x0089,
-	0x080c, 0x864c, 0x0005, 0x7110, 0xd1bc, 0x0140, 0x0041, 0x0130,
-	0x7124, 0x610a, 0x2009, 0x008a, 0x080c, 0x864c, 0x0005, 0x7020,
-	0x2060, 0xac84, 0x0007, 0x1158, 0xac82, 0xbd00, 0x0240, 0x2001,
-	0xb517, 0x2004, 0xac02, 0x1218, 0xa085, 0x0001, 0x0005, 0xa006,
-	0x0ce8, 0x7110, 0xd1bc, 0x1178, 0x7024, 0x2060, 0xac84, 0x0007,
-	0x1150, 0xac82, 0xbd00, 0x0238, 0x685c, 0xac02, 0x1220, 0x2009,
-	0x0051, 0x080c, 0x864c, 0x0005, 0x2031, 0x0105, 0x0069, 0x0005,
-	0x2031, 0x0206, 0x0049, 0x0005, 0x2031, 0x0207, 0x0029, 0x0005,
-	0x2031, 0x0213, 0x0009, 0x0005, 0x00c6, 0x00d6, 0x00f6, 0x7000,
-	0xa084, 0xf000, 0xa086, 0xc000, 0x05b0, 0x080c, 0x85c7, 0x0598,
-	0x0066, 0x00c6, 0x0046, 0x2011, 0xbb83, 0x2204, 0x8211, 0x220c,
-	0x080c, 0x281d, 0x1580, 0x080c, 0x4f4d, 0x1568, 0x6612, 0x6516,
-	0x2c00, 0x004e, 0x00ce, 0x601a, 0x080c, 0xa027, 0x080c, 0x15f8,
-	0x01f0, 0x2d00, 0x6056, 0x6803, 0x0000, 0x6837, 0x0000, 0x6c3a,
-	0xadf8, 0x000f, 0x20a9, 0x000e, 0x2fa0, 0x2e98, 0x53a3, 0x006e,
-	0x6612, 0x6007, 0x003e, 0x601f, 0x0001, 0x6003, 0x0001, 0x080c,
-	0x6cd3, 0x080c, 0x7173, 0x00fe, 0x00de, 0x00ce, 0x0005, 0x080c,
-	0x861d, 0x006e, 0x0cc0, 0x004e, 0x00ce, 0x0cc8, 0x2071, 0xb7f3,
-	0x7003, 0x0003, 0x700f, 0x0361, 0xa006, 0x701a, 0x7076, 0x7012,
-	0x7017, 0xbd00, 0x7007, 0x0000, 0x7026, 0x702b, 0x7d91, 0x7032,
-	0x7037, 0x7df1, 0x703b, 0xffff, 0x703f, 0xffff, 0x7042, 0x7047,
-	0x444b, 0x704a, 0x705b, 0x6a2b, 0x2001, 0xb7a1, 0x2003, 0x0003,
-	0x2001, 0xb7a3, 0x2003, 0x0100, 0x3a00, 0xa084, 0x0005, 0x706e,
-	0x0005, 0x2071, 0xb7f3, 0x1d04, 0x698b, 0x2091, 0x6000, 0x700c,
-	0x8001, 0x700e, 0x1518, 0x700f, 0x0361, 0x7007, 0x0001, 0x0126,
-	0x2091, 0x8000, 0x7040, 0xa00d, 0x0128, 0x8109, 0x7142, 0x1110,
-	0x7044, 0x080f, 0x00c6, 0x2061, 0xb500, 0x6034, 0x00ce, 0xd0cc,
-	0x0180, 0x3a00, 0xa084, 0x0005, 0x726c, 0xa216, 0x0150, 0x706e,
-	0x2011, 0x8043, 0x2018, 0x080c, 0x3ecc, 0x0018, 0x0126, 0x2091,
-	0x8000, 0x7024, 0xa00d, 0x0188, 0x7020, 0x8001, 0x7022, 0x1168,
-	0x7023, 0x0009, 0x8109, 0x7126, 0xa186, 0x03e8, 0x1110, 0x7028,
-	0x080f, 0x81ff, 0x1110, 0x7028, 0x080f, 0x7030, 0xa00d, 0x0180,
-	0x702c, 0x8001, 0x702e, 0x1160, 0x702f, 0x0009, 0x8109, 0x7132,
-	0x0128, 0xa184, 0x007f, 0x090c, 0x7e36, 0x0010, 0x7034, 0x080f,
-	0x7038, 0xa005, 0x0118, 0x0310, 0x8001, 0x703a, 0x703c, 0xa005,
-	0x0118, 0x0310, 0x8001, 0x703e, 0x704c, 0xa00d, 0x0168, 0x7048,
-	0x8001, 0x704a, 0x1148, 0x704b, 0x0009, 0x8109, 0x714e, 0x1120,
-	0x7150, 0x714e, 0x7058, 0x080f, 0x7018, 0xa00d, 0x01d8, 0x0016,
-	0x7074, 0xa00d, 0x0158, 0x7070, 0x8001, 0x7072, 0x1138, 0x7073,
-	0x0009, 0x8109, 0x7176, 0x1110, 0x7078, 0x080f, 0x001e, 0x7008,
-	0x8001, 0x700a, 0x1138, 0x700b, 0x0009, 0x8109, 0x711a, 0x1110,
-	0x701c, 0x080f, 0x012e, 0x7004, 0x0002, 0x69b1, 0x69b2, 0x69ca,
-	0x00e6, 0x2071, 0xb7f3, 0x7018, 0xa005, 0x1120, 0x711a, 0x721e,
-	0x700b, 0x0009, 0x00ee, 0x0005, 0x00e6, 0x0006, 0x2071, 0xb7f3,
-	0x701c, 0xa206, 0x1110, 0x701a, 0x701e, 0x000e, 0x00ee, 0x0005,
-	0x00e6, 0x2071, 0xb7f3, 0x6088, 0xa102, 0x0208, 0x618a, 0x00ee,
-	0x0005, 0x0005, 0x7110, 0x080c, 0x4fa9, 0x1158, 0x6088, 0x8001,
-	0x0240, 0x608a, 0x1130, 0x0126, 0x2091, 0x8000, 0x080c, 0x7173,
-	0x012e, 0x8108, 0xa182, 0x00ff, 0x0218, 0xa00e, 0x7007, 0x0002,
-	0x7112, 0x0005, 0x7014, 0x2060, 0x0126, 0x2091, 0x8000, 0x603c,
-	0xa005, 0x0128, 0x8001, 0x603e, 0x1110, 0x080c, 0x9f15, 0x6014,
-	0xa005, 0x0500, 0x8001, 0x6016, 0x11e8, 0x611c, 0xa186, 0x0003,
-	0x0118, 0xa186, 0x0006, 0x11a0, 0x6010, 0x2068, 0x6854, 0xa08a,
-	0x199a, 0x0270, 0xa082, 0x1999, 0x6856, 0xa08a, 0x199a, 0x0210,
-	0x2001, 0x1999, 0x8003, 0x800b, 0x810b, 0xa108, 0x6116, 0x0010,
-	0x080c, 0x99e5, 0x012e, 0xac88, 0x0018, 0x7116, 0x2001, 0xed00,
-	0xa102, 0x0220, 0x7017, 0xbd00, 0x7007, 0x0000, 0x0005, 0x00e6,
-	0x2071, 0xb7f3, 0x7027, 0x07d0, 0x7023, 0x0009, 0x00ee, 0x0005,
-	0x2001, 0xb7fc, 0x2003, 0x0000, 0x0005, 0x00e6, 0x2071, 0xb7f3,
-	0x7132, 0x702f, 0x0009, 0x00ee, 0x0005, 0x2011, 0xb7ff, 0x2013,
-	0x0000, 0x0005, 0x00e6, 0x2071, 0xb7f3, 0x711a, 0x721e, 0x700b,
-	0x0009, 0x00ee, 0x0005, 0x00c6, 0x0026, 0x7054, 0x8000, 0x7056,
-	0x2061, 0xb7a1, 0x6008, 0xa086, 0x0000, 0x0158, 0x7068, 0x6032,
-	0x7064, 0x602e, 0x7060, 0x602a, 0x705c, 0x6026, 0x2c10, 0x080c,
-	0x1643, 0x002e, 0x00ce, 0x0005, 0x0006, 0x0016, 0x00c6, 0x00d6,
-	0x00e6, 0x00f6, 0x080c, 0x68f9, 0x00fe, 0x00ee, 0x00de, 0x00ce,
-	0x001e, 0x000e, 0x0005, 0x00e6, 0x2071, 0xb7f3, 0x7176, 0x727a,
-	0x7073, 0x0009, 0x00ee, 0x0005, 0x00e6, 0x0006, 0x2071, 0xb7f3,
-	0x7078, 0xa206, 0x1110, 0x7076, 0x707a, 0x000e, 0x00ee, 0x0005,
-	0x00c6, 0x2061, 0xb874, 0x00ce, 0x0005, 0xa184, 0x000f, 0x8003,
-	0x8003, 0x8003, 0xa080, 0xb874, 0x2060, 0x0005, 0x6854, 0xa08a,
-	0x199a, 0x0210, 0x2001, 0x1999, 0xa005, 0x1150, 0x00c6, 0x2061,
-	0xb874, 0x6014, 0x00ce, 0xa005, 0x1138, 0x2001, 0x001e, 0x0020,
-	0xa08e, 0xffff, 0x1108, 0xa006, 0x8003, 0x800b, 0x810b, 0xa108,
-	0x6116, 0x684c, 0xa08c, 0x00c0, 0xa18e, 0x00c0, 0x05e8, 0xd0b4,
-	0x1138, 0xd0bc, 0x1550, 0x2009, 0x0006, 0x080c, 0x6af1, 0x0005,
-	0xd0fc, 0x0138, 0xa084, 0x0003, 0x0120, 0xa086, 0x0003, 0x1904,
-	0x6aeb, 0x6020, 0xd0d4, 0x0130, 0xc0d4, 0x6022, 0x6860, 0x602a,
-	0x685c, 0x602e, 0x2009, 0xb574, 0x2104, 0xd084, 0x0138, 0x87ff,
-	0x1120, 0x2009, 0x0042, 0x080c, 0x864c, 0x0005, 0x87ff, 0x1120,
-	0x2009, 0x0043, 0x080c, 0x864c, 0x0005, 0xd0fc, 0x0130, 0xa084,
-	0x0003, 0x0118, 0xa086, 0x0003, 0x11f0, 0x87ff, 0x1120, 0x2009,
-	0x0042, 0x080c, 0x864c, 0x0005, 0xd0fc, 0x0160, 0xa084, 0x0003,
-	0xa08e, 0x0002, 0x0148, 0x87ff, 0x1120, 0x2009, 0x0041, 0x080c,
-	0x864c, 0x0005, 0x0061, 0x0ce8, 0x87ff, 0x1dd8, 0x2009, 0x0043,
-	0x080c, 0x864c, 0x0cb0, 0x2009, 0x0004, 0x0019, 0x0005, 0x2009,
-	0x0001, 0x00d6, 0x6010, 0xa0ec, 0xf000, 0x0510, 0x2068, 0x6952,
-	0x6800, 0x6012, 0xa186, 0x0001, 0x1188, 0x694c, 0xa18c, 0x8100,
-	0xa18e, 0x8100, 0x1158, 0x00c6, 0x2061, 0xb874, 0x6200, 0xd28c,
-	0x1120, 0x6204, 0x8210, 0x0208, 0x6206, 0x00ce, 0x080c, 0x5408,
-	0x6010, 0xa06d, 0x0076, 0x2039, 0x0000, 0x190c, 0x6a76, 0x007e,
-	0x00de, 0x0005, 0x0156, 0x00c6, 0x2061, 0xb874, 0x6000, 0x81ff,
-	0x0110, 0xa205, 0x0008, 0xa204, 0x6002, 0x00ce, 0x015e, 0x0005,
-	0x6800, 0xd08c, 0x1138, 0x6808, 0xa005, 0x0120, 0x8001, 0x680a,
-	0xa085, 0x0001, 0x0005, 0x20a9, 0x0010, 0xa006, 0x8004, 0x8086,
-	0x818e, 0x1208, 0xa200, 0x1f04, 0x6b37, 0x8086, 0x818e, 0x0005,
-	0x0156, 0x20a9, 0x0010, 0xa005, 0x01b8, 0xa11a, 0x12a8, 0x8213,
-	0x818d, 0x0228, 0xa11a, 0x1220, 0x1f04, 0x6b47, 0x0028, 0xa11a,
-	0x2308, 0x8210, 0x1f04, 0x6b47, 0x0006, 0x3200, 0xa084, 0xefff,
-	0x2080, 0x000e, 0x015e, 0x0005, 0x0006, 0x3200, 0xa085, 0x1000,
-	0x0cb8, 0x0126, 0x2091, 0x2800, 0x2079, 0xb7e0, 0x012e, 0x00d6,
-	0x2069, 0xb7e0, 0x6803, 0x0005, 0x2069, 0x0004, 0x2d04, 0xa085,
-	0x8001, 0x206a, 0x00de, 0x0005, 0x00c6, 0x6027, 0x0001, 0x7804,
-	0xa084, 0x0007, 0x0002, 0x6b85, 0x6ba6, 0x6bf9, 0x6b8b, 0x6ba6,
-	0x6b85, 0x6b83, 0x6b83, 0x080c, 0x1515, 0x080c, 0x6a10, 0x080c,
-	0x7173, 0x00ce, 0x0005, 0x62c0, 0x82ff, 0x1110, 0x00ce, 0x0005,
-	0x2011, 0x4adc, 0x080c, 0x699c, 0x7828, 0xa092, 0x00c8, 0x1228,
-	0x8000, 0x782a, 0x080c, 0x4b16, 0x0c88, 0x080c, 0x4adc, 0x7807,
-	0x0003, 0x7827, 0x0000, 0x782b, 0x0000, 0x0c40, 0x080c, 0x6a10,
-	0x3c00, 0x0006, 0x2011, 0x0209, 0x20e1, 0x4000, 0x2214, 0x000e,
-	0x20e0, 0x82ff, 0x0178, 0x62c0, 0x82ff, 0x1160, 0x782b, 0x0000,
-	0x7824, 0xa065, 0x090c, 0x1515, 0x2009, 0x0013, 0x080c, 0x864c,
-	0x00ce, 0x0005, 0x3900, 0xa082, 0xb92c, 0x1210, 0x080c, 0x8332,
-	0x00c6, 0x7824, 0xa065, 0x090c, 0x1515, 0x7804, 0xa086, 0x0004,
-	0x0904, 0x6c39, 0x7828, 0xa092, 0x2710, 0x1230, 0x8000, 0x782a,
-	0x00ce, 0x080c, 0x7d6d, 0x0c20, 0x6104, 0xa186, 0x0003, 0x1188,
-	0x00e6, 0x2071, 0xb500, 0x70e0, 0x00ee, 0xd08c, 0x0150, 0x00c6,
-	0x00e6, 0x2061, 0x0100, 0x2071, 0xb500, 0x080c, 0x4b1f, 0x00ee,
-	0x00ce, 0x080c, 0xb444, 0x2009, 0x0014, 0x080c, 0x864c, 0x00ce,
-	0x0838, 0x2001, 0xb7fc, 0x2003, 0x0000, 0x62c0, 0x82ff, 0x1160,
-	0x782b, 0x0000, 0x7824, 0xa065, 0x090c, 0x1515, 0x2009, 0x0013,
-	0x080c, 0x86a0, 0x00ce, 0x0005, 0x00c6, 0x00d6, 0x3900, 0xa082,
-	0xb92c, 0x1210, 0x080c, 0x8332, 0x7824, 0xa005, 0x090c, 0x1515,
-	0x781c, 0xa06d, 0x090c, 0x1515, 0x6800, 0xc0dc, 0x6802, 0x7924,
-	0x2160, 0x080c, 0x861d, 0x693c, 0x81ff, 0x090c, 0x1515, 0x8109,
-	0x693e, 0x6854, 0xa015, 0x0110, 0x7a1e, 0x0010, 0x7918, 0x791e,
-	0x7807, 0x0000, 0x7827, 0x0000, 0x00de, 0x00ce, 0x080c, 0x7173,
-	0x0888, 0x6104, 0xa186, 0x0002, 0x0128, 0xa186, 0x0004, 0x0110,
-	0x0804, 0x6bd2, 0x7808, 0xac06, 0x0904, 0x6bd2, 0x080c, 0x7090,
-	0x080c, 0x6cd3, 0x00ce, 0x080c, 0x7173, 0x0804, 0x6bc0, 0x00c6,
-	0x6027, 0x0002, 0x62c8, 0x60c4, 0xa205, 0x1178, 0x793c, 0xa1e5,
-	0x0000, 0x0130, 0x2009, 0x0049, 0x080c, 0x864c, 0x00ce, 0x0005,
-	0x2011, 0xb7ff, 0x2013, 0x0000, 0x0cc8, 0x3908, 0xa192, 0xb92c,
-	0x1210, 0x080c, 0x8332, 0x793c, 0x81ff, 0x0d90, 0x7944, 0xa192,
-	0x7530, 0x12b8, 0x8108, 0x7946, 0x793c, 0xa188, 0x0007, 0x210c,
-	0xa18e, 0x0006, 0x1138, 0x6014, 0xa084, 0x0184, 0xa085, 0x0012,
-	0x6016, 0x08e0, 0x6014, 0xa084, 0x0184, 0xa085, 0x0016, 0x6016,
-	0x08a8, 0x7848, 0xc085, 0x784a, 0x0888, 0x0006, 0x0016, 0x00c6,
-	0x0126, 0x2091, 0x8000, 0x600f, 0x0000, 0x2c08, 0x2061, 0xb7e0,
-	0x6020, 0x8000, 0x6022, 0x6010, 0xa005, 0x0148, 0xa080, 0x0003,
-	0x2102, 0x6112, 0x012e, 0x00ce, 0x001e, 0x000e, 0x0005, 0x6116,
-	0x6112, 0x0cc0, 0x00d6, 0x2069, 0xb7e0, 0x6000, 0xd0d4, 0x0168,
-	0x6820, 0x8000, 0x6822, 0xa086, 0x0001, 0x1110, 0x2c00, 0x681e,
-	0x6804, 0xa084, 0x0007, 0x0804, 0x7179, 0xc0d5, 0x6002, 0x6818,
-	0xa005, 0x0158, 0x6056, 0x605b, 0x0000, 0x0006, 0x2c00, 0x681a,
-	0x00de, 0x685a, 0x2069, 0xb7e0, 0x0c18, 0x6056, 0x605a, 0x2c00,
-	0x681a, 0x681e, 0x08e8, 0x0006, 0x0016, 0x00c6, 0x0126, 0x2091,
-	0x8000, 0x600f, 0x0000, 0x2c08, 0x2061, 0xb7e0, 0x6020, 0x8000,
-	0x6022, 0x6008, 0xa005, 0x0148, 0xa080, 0x0003, 0x2102, 0x610a,
-	0x012e, 0x00ce, 0x001e, 0x000e, 0x0005, 0x610e, 0x610a, 0x0cc0,
-	0x00c6, 0x600f, 0x0000, 0x2c08, 0x2061, 0xb7e0, 0x6034, 0xa005,
-	0x0130, 0xa080, 0x0003, 0x2102, 0x6136, 0x00ce, 0x0005, 0x613a,
-	0x6136, 0x0cd8, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0076, 0x0066,
-	0x0056, 0x0036, 0x0026, 0x0016, 0x0006, 0x0126, 0xa02e, 0x2071,
-	0xb7e0, 0x7638, 0x2660, 0x2678, 0x2091, 0x8000, 0x8cff, 0x0904,
-	0x6d7b, 0x6018, 0xa080, 0x0028, 0x2004, 0xa206, 0x1904, 0x6d76,
-	0x87ff, 0x0120, 0x6050, 0xa106, 0x1904, 0x6d76, 0x703c, 0xac06,
-	0x1190, 0x0036, 0x2019, 0x0001, 0x080c, 0x7fe4, 0x7033, 0x0000,
-	0x703f, 0x0000, 0x7043, 0x0000, 0x7047, 0x0000, 0x704b, 0x0000,
-	0x003e, 0x2029, 0x0001, 0x7038, 0xac36, 0x1110, 0x660c, 0x763a,
-	0x7034, 0xac36, 0x1140, 0x2c00, 0xaf36, 0x0118, 0x2f00, 0x7036,
-	0x0010, 0x7037, 0x0000, 0x660c, 0x0066, 0x2c00, 0xaf06, 0x0110,
-	0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0x080c, 0x9c5a, 0x01c8,
-	0x6010, 0x2068, 0x601c, 0xa086, 0x0003, 0x1580, 0x6837, 0x0103,
-	0x6b4a, 0x6847, 0x0000, 0x0016, 0x0036, 0x0076, 0x080c, 0x9ecc,
-	0x080c, 0xb380, 0x080c, 0x5408, 0x007e, 0x003e, 0x001e, 0x080c,
-	0x9e11, 0x080c, 0x9e1d, 0x00ce, 0x0804, 0x6d16, 0x2c78, 0x600c,
-	0x2060, 0x0804, 0x6d16, 0x85ff, 0x0120, 0x0036, 0x080c, 0x7230,
-	0x003e, 0x012e, 0x000e, 0x001e, 0x002e, 0x003e, 0x005e, 0x006e,
-	0x007e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x601c, 0xa086,
-	0x0006, 0x1158, 0x0016, 0x0036, 0x0076, 0x080c, 0xb380, 0x080c,
-	0xb099, 0x007e, 0x003e, 0x001e, 0x08a0, 0x601c, 0xa086, 0x000a,
-	0x0904, 0x6d60, 0x0804, 0x6d5e, 0x0006, 0x0066, 0x00c6, 0x00d6,
-	0x00f6, 0x2031, 0x0000, 0x0126, 0x2091, 0x8000, 0x2079, 0xb7e0,
-	0x7838, 0xa065, 0x0568, 0x600c, 0x0006, 0x600f, 0x0000, 0x783c,
-	0xac06, 0x1180, 0x0036, 0x2019, 0x0001, 0x080c, 0x7fe4, 0x7833,
-	0x0000, 0x783f, 0x0000, 0x7843, 0x0000, 0x7847, 0x0000, 0x784b,
-	0x0000, 0x003e, 0x080c, 0x9c5a, 0x0178, 0x6010, 0x2068, 0x601c,
-	0xa086, 0x0003, 0x11b0, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000,
-	0x080c, 0x5408, 0x080c, 0x9e11, 0x080c, 0x9e1d, 0x000e, 0x0888,
-	0x7e3a, 0x7e36, 0x012e, 0x00fe, 0x00de, 0x00ce, 0x006e, 0x000e,
-	0x0005, 0x601c, 0xa086, 0x0006, 0x1118, 0x080c, 0xb099, 0x0c60,
-	0x601c, 0xa086, 0x000a, 0x0d08, 0x08f0, 0x0016, 0x0026, 0x0086,
-	0x2041, 0x0000, 0x0099, 0x080c, 0x6ec3, 0x008e, 0x002e, 0x001e,
-	0x0005, 0x00f6, 0x0126, 0x2079, 0xb7e0, 0x2091, 0x8000, 0x080c,
-	0x6f50, 0x080c, 0x6fc2, 0x012e, 0x00fe, 0x0005, 0x00f6, 0x00e6,
-	0x00d6, 0x00c6, 0x0066, 0x0016, 0x0006, 0x0126, 0x2091, 0x8000,
-	0x2071, 0xb7e0, 0x7614, 0x2660, 0x2678, 0x8cff, 0x0904, 0x6e99,
-	0x6018, 0xa080, 0x0028, 0x2004, 0xa206, 0x1904, 0x6e94, 0x88ff,
-	0x0120, 0x6050, 0xa106, 0x1904, 0x6e94, 0x7024, 0xac06, 0x1538,
-	0x2069, 0x0100, 0x68c0, 0xa005, 0x01f0, 0x080c, 0x6a10, 0x080c,
-	0x7d7a, 0x68c3, 0x0000, 0x080c, 0x824d, 0x7027, 0x0000, 0x0036,
-	0x2069, 0x0140, 0x6b04, 0xa384, 0x1000, 0x0120, 0x6803, 0x0100,
-	0x6803, 0x0000, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827,
-	0x0001, 0x003e, 0x0020, 0x6003, 0x0009, 0x630a, 0x04e8, 0x7014,
-	0xac36, 0x1110, 0x660c, 0x7616, 0x7010, 0xac36, 0x1140, 0x2c00,
-	0xaf36, 0x0118, 0x2f00, 0x7012, 0x0010, 0x7013, 0x0000, 0x660c,
-	0x0066, 0x2c00, 0xaf06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f,
-	0x0000, 0x6010, 0x2068, 0x080c, 0x9c5a, 0x01b8, 0x601c, 0xa086,
-	0x0003, 0x1540, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x0016,
-	0x0036, 0x0086, 0x080c, 0x9ecc, 0x080c, 0xb380, 0x080c, 0x5408,
-	0x008e, 0x003e, 0x001e, 0x080c, 0x9e11, 0x080c, 0x9e1d, 0x080c,
-	0x811e, 0x00ce, 0x0804, 0x6e1d, 0x2c78, 0x600c, 0x2060, 0x0804,
-	0x6e1d, 0x012e, 0x000e, 0x001e, 0x006e, 0x00ce, 0x00de, 0x00ee,
-	0x00fe, 0x0005, 0x601c, 0xa086, 0x0006, 0x1158, 0x0016, 0x0036,
-	0x0086, 0x080c, 0xb380, 0x080c, 0xb099, 0x008e, 0x003e, 0x001e,
-	0x08e0, 0x601c, 0xa086, 0x0002, 0x1128, 0x6004, 0xa086, 0x0085,
-	0x0908, 0x0898, 0x601c, 0xa086, 0x0005, 0x1978, 0x6004, 0xa086,
-	0x0085, 0x0d20, 0x0850, 0x00c6, 0x0006, 0x0126, 0x2091, 0x8000,
-	0xa280, 0xb635, 0x2004, 0xa065, 0x0904, 0x6f4c, 0x00f6, 0x00e6,
-	0x00d6, 0x0066, 0x2071, 0xb7e0, 0x6654, 0x7018, 0xac06, 0x1108,
-	0x761a, 0x701c, 0xac06, 0x1130, 0x86ff, 0x1118, 0x7018, 0x701e,
-	0x0008, 0x761e, 0x6058, 0xa07d, 0x0108, 0x7e56, 0xa6ed, 0x0000,
-	0x0110, 0x2f00, 0x685a, 0x6057, 0x0000, 0x605b, 0x0000, 0x6000,
-	0xc0d4, 0xc0dc, 0x6002, 0x080c, 0x4ed4, 0x0904, 0x6f48, 0x7624,
-	0x86ff, 0x05e8, 0xa680, 0x0004, 0x2004, 0xad06, 0x15c0, 0x00d6,
-	0x2069, 0x0100, 0x68c0, 0xa005, 0x0548, 0x080c, 0x6a10, 0x080c,
-	0x7d7a, 0x68c3, 0x0000, 0x080c, 0x824d, 0x7027, 0x0000, 0x0036,
-	0x2069, 0x0140, 0x6b04, 0xa384, 0x1000, 0x0120, 0x6803, 0x0100,
-	0x6803, 0x0000, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827,
-	0x0001, 0x003e, 0x00de, 0x00c6, 0x603c, 0xa005, 0x0110, 0x8001,
-	0x603e, 0x2660, 0x080c, 0x9e1d, 0x00ce, 0x0048, 0x00de, 0x00c6,
-	0x2660, 0x6003, 0x0009, 0x630a, 0x00ce, 0x0804, 0x6ef3, 0x8dff,
-	0x0158, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x080c, 0x9ecc,
-	0x080c, 0xb380, 0x080c, 0x5408, 0x080c, 0x811e, 0x0804, 0x6ef3,
-	0x006e, 0x00de, 0x00ee, 0x00fe, 0x012e, 0x000e, 0x00ce, 0x0005,
-	0x0006, 0x0066, 0x00c6, 0x00d6, 0x2031, 0x0000, 0x7814, 0xa065,
-	0x0904, 0x6fa2, 0x600c, 0x0006, 0x600f, 0x0000, 0x7824, 0xac06,
-	0x1540, 0x2069, 0x0100, 0x68c0, 0xa005, 0x01f0, 0x080c, 0x6a10,
-	0x080c, 0x7d7a, 0x68c3, 0x0000, 0x080c, 0x824d, 0x7827, 0x0000,
-	0x0036, 0x2069, 0x0140, 0x6b04, 0xa384, 0x1000, 0x0120, 0x6803,
-	0x0100, 0x6803, 0x0000, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110,
-	0x6827, 0x0001, 0x003e, 0x0028, 0x6003, 0x0009, 0x630a, 0x2c30,
-	0x00b0, 0x6010, 0x2068, 0x080c, 0x9c5a, 0x0168, 0x601c, 0xa086,
-	0x0003, 0x11b8, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x080c,
-	0x5408, 0x080c, 0x9e11, 0x080c, 0x9e1d, 0x080c, 0x811e, 0x000e,
-	0x0804, 0x6f57, 0x7e16, 0x7e12, 0x00de, 0x00ce, 0x006e, 0x000e,
-	0x0005, 0x601c, 0xa086, 0x0006, 0x1118, 0x080c, 0xb099, 0x0c58,
-	0x601c, 0xa086, 0x0002, 0x1128, 0x6004, 0xa086, 0x0085, 0x09d0,
-	0x0c10, 0x601c, 0xa086, 0x0005, 0x19f0, 0x6004, 0xa086, 0x0085,
-	0x0d60, 0x08c8, 0x0006, 0x0066, 0x00c6, 0x00d6, 0x7818, 0xa065,
-	0x0904, 0x7028, 0x6054, 0x0006, 0x6057, 0x0000, 0x605b, 0x0000,
-	0x6000, 0xc0d4, 0xc0dc, 0x6002, 0x080c, 0x4ed4, 0x0904, 0x7025,
-	0x7e24, 0x86ff, 0x05e8, 0xa680, 0x0004, 0x2004, 0xad06, 0x15c0,
-	0x00d6, 0x2069, 0x0100, 0x68c0, 0xa005, 0x0548, 0x080c, 0x6a10,
-	0x080c, 0x7d7a, 0x68c3, 0x0000, 0x080c, 0x824d, 0x7827, 0x0000,
-	0x0036, 0x2069, 0x0140, 0x6b04, 0xa384, 0x1000, 0x0120, 0x6803,
-	0x0100, 0x6803, 0x0000, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110,
-	0x6827, 0x0001, 0x003e, 0x00de, 0x00c6, 0x603c, 0xa005, 0x0110,
-	0x8001, 0x603e, 0x2660, 0x080c, 0x9e1d, 0x00ce, 0x0048, 0x00de,
-	0x00c6, 0x2660, 0x6003, 0x0009, 0x630a, 0x00ce, 0x0804, 0x6fd4,
-	0x8dff, 0x0138, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x080c,
-	0x5408, 0x080c, 0x811e, 0x0804, 0x6fd4, 0x000e, 0x0804, 0x6fc7,
-	0x781e, 0x781a, 0x00de, 0x00ce, 0x006e, 0x000e, 0x0005, 0x00e6,
-	0x00d6, 0x0066, 0x6000, 0xd0dc, 0x01a0, 0x604c, 0xa06d, 0x0188,
-	0x6848, 0xa606, 0x1170, 0x2071, 0xb7e0, 0x7024, 0xa035, 0x0148,
-	0xa080, 0x0004, 0x2004, 0xad06, 0x1120, 0x6000, 0xc0dc, 0x6002,
-	0x0021, 0x006e, 0x00de, 0x00ee, 0x0005, 0x00f6, 0x2079, 0x0100,
-	0x78c0, 0xa005, 0x1138, 0x00c6, 0x2660, 0x6003, 0x0009, 0x630a,
-	0x00ce, 0x04a0, 0x080c, 0x7d7a, 0x78c3, 0x0000, 0x080c, 0x824d,
-	0x7027, 0x0000, 0x0036, 0x2079, 0x0140, 0x7b04, 0xa384, 0x1000,
-	0x0120, 0x7803, 0x0100, 0x7803, 0x0000, 0x2079, 0x0100, 0x7824,
-	0xd084, 0x0110, 0x7827, 0x0001, 0x080c, 0x824d, 0x003e, 0x080c,
-	0x4ed4, 0x00c6, 0x603c, 0xa005, 0x0110, 0x8001, 0x603e, 0x2660,
-	0x080c, 0x861d, 0x00ce, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000,
-	0x080c, 0x9ecc, 0x080c, 0x5408, 0x080c, 0x811e, 0x00fe, 0x0005,
-	0x00e6, 0x00c6, 0x2071, 0xb7e0, 0x7004, 0xa084, 0x0007, 0x0002,
-	0x70a2, 0x70a5, 0x70bb, 0x70d4, 0x7111, 0x70a2, 0x70a0, 0x70a0,
-	0x080c, 0x1515, 0x00ce, 0x00ee, 0x0005, 0x7024, 0xa065, 0x0148,
-	0x7020, 0x8001, 0x7022, 0x600c, 0xa015, 0x0150, 0x7216, 0x600f,
-	0x0000, 0x7007, 0x0000, 0x7027, 0x0000, 0x00ce, 0x00ee, 0x0005,
-	0x7216, 0x7212, 0x0cb0, 0x6018, 0x2060, 0x080c, 0x4ed4, 0x6000,
-	0xc0dc, 0x6002, 0x7020, 0x8001, 0x7022, 0x0120, 0x6054, 0xa015,
-	0x0140, 0x721e, 0x7007, 0x0000, 0x7027, 0x0000, 0x00ce, 0x00ee,
-	0x0005, 0x7218, 0x721e, 0x0cb0, 0x7024, 0xa065, 0x05b8, 0x700c,
-	0xac06, 0x1160, 0x080c, 0x811e, 0x600c, 0xa015, 0x0120, 0x720e,
-	0x600f, 0x0000, 0x0448, 0x720e, 0x720a, 0x0430, 0x7014, 0xac06,
-	0x1160, 0x080c, 0x811e, 0x600c, 0xa015, 0x0120, 0x7216, 0x600f,
-	0x0000, 0x00d0, 0x7216, 0x7212, 0x00b8, 0x601c, 0xa086, 0x0003,
-	0x1198, 0x6018, 0x2060, 0x080c, 0x4ed4, 0x6000, 0xc0dc, 0x6002,
-	0x080c, 0x811e, 0x701c, 0xa065, 0x0138, 0x6054, 0xa015, 0x0110,
-	0x721e, 0x0010, 0x7218, 0x721e, 0x7027, 0x0000, 0x00ce, 0x00ee,
-	0x0005, 0x7024, 0xa065, 0x0140, 0x080c, 0x811e, 0x600c, 0xa015,
-	0x0150, 0x720e, 0x600f, 0x0000, 0x080c, 0x824d, 0x7027, 0x0000,
-	0x00ce, 0x00ee, 0x0005, 0x720e, 0x720a, 0x0cb0, 0x00d6, 0x2069,
-	0xb7e0, 0x6830, 0xa084, 0x0003, 0x0002, 0x7133, 0x7135, 0x7159,
-	0x7131, 0x080c, 0x1515, 0x00de, 0x0005, 0x00c6, 0x6840, 0xa086,
-	0x0001, 0x01b8, 0x683c, 0xa065, 0x0130, 0x600c, 0xa015, 0x0170,
-	0x6a3a, 0x600f, 0x0000, 0x6833, 0x0000, 0x683f, 0x0000, 0x2011,
-	0xb7ff, 0x2013, 0x0000, 0x00ce, 0x00de, 0x0005, 0x683a, 0x6836,
-	0x0c90, 0x6843, 0x0000, 0x6838, 0xa065, 0x0d68, 0x6003, 0x0003,
-	0x0c50, 0x00c6, 0x6843, 0x0000, 0x6847, 0x0000, 0x684b, 0x0000,
-	0x683c, 0xa065, 0x0168, 0x600c, 0xa015, 0x0130, 0x6a3a, 0x600f,
-	0x0000, 0x683f, 0x0000, 0x0020, 0x683f, 0x0000, 0x683a, 0x6836,
-	0x00ce, 0x00de, 0x0005, 0x00d6, 0x2069, 0xb7e0, 0x6804, 0xa084,
-	0x0007, 0x0002, 0x7184, 0x7220, 0x7220, 0x7220, 0x7220, 0x7222,
-	0x7182, 0x7182, 0x080c, 0x1515, 0x6820, 0xa005, 0x1110, 0x00de,
-	0x0005, 0x00c6, 0x680c, 0xa065, 0x0150, 0x6807, 0x0004, 0x6826,
-	0x682b, 0x0000, 0x080c, 0x7272, 0x00ce, 0x00de, 0x0005, 0x6814,
-	0xa065, 0x0150, 0x6807, 0x0001, 0x6826, 0x682b, 0x0000, 0x080c,
-	0x7272, 0x00ce, 0x00de, 0x0005, 0x00e6, 0x0036, 0x6a1c, 0xa2f5,
-	0x0000, 0x0904, 0x721c, 0x704c, 0xa00d, 0x0118, 0x7088, 0xa005,
-	0x01a0, 0x7054, 0xa075, 0x0120, 0xa20e, 0x0904, 0x721c, 0x0028,
-	0x6818, 0xa20e, 0x0904, 0x721c, 0x2070, 0x704c, 0xa00d, 0x0d88,
-	0x7088, 0xa005, 0x1d70, 0x2e00, 0x681e, 0x733c, 0x7038, 0xa302,
-	0x1e40, 0x080c, 0x85f4, 0x0904, 0x721c, 0x8318, 0x733e, 0x6112,
-	0x2e10, 0x621a, 0xa180, 0x0014, 0x2004, 0xa084, 0x00ff, 0x605a,
-	0xa180, 0x0014, 0x2003, 0x0000, 0xa180, 0x0015, 0x2004, 0xa08a,
-	0x199a, 0x0210, 0x2001, 0x1999, 0x8003, 0x801b, 0x831b, 0xa318,
-	0x6316, 0x003e, 0x00f6, 0x2c78, 0x71a0, 0x2001, 0xb535, 0x2004,
-	0xd0ac, 0x1110, 0xd1bc, 0x0150, 0x7100, 0xd1f4, 0x0120, 0x7114,
-	0xa18c, 0x00ff, 0x0040, 0x2009, 0x0000, 0x0028, 0xa1e0, 0x2dc4,
-	0x2c0d, 0xa18c, 0x00ff, 0x2061, 0x0100, 0x619a, 0x080c, 0x78a2,
-	0x7300, 0xc3dd, 0x7302, 0x6807, 0x0002, 0x2f18, 0x6b26, 0x682b,
-	0x0000, 0x781f, 0x0003, 0x7803, 0x0001, 0x7807, 0x0040, 0x00fe,
-	0x00ee, 0x00ce, 0x00de, 0x0005, 0x003e, 0x00ee, 0x00ce, 0x0cd0,
-	0x00de, 0x0005, 0x00c6, 0x680c, 0xa065, 0x0138, 0x6807, 0x0004,
-	0x6826, 0x682b, 0x0000, 0x080c, 0x7272, 0x00ce, 0x00de, 0x0005,
-	0x00f6, 0x00d6, 0x2069, 0xb7e0, 0x6830, 0xa086, 0x0000, 0x11d0,
-	0x2001, 0xb50c, 0x200c, 0xd1bc, 0x1560, 0x6838, 0xa07d, 0x0190,
-	0x6833, 0x0001, 0x683e, 0x6847, 0x0000, 0x684b, 0x0000, 0x0126,
-	0x00f6, 0x2091, 0x2400, 0x002e, 0x080c, 0x2021, 0x1130, 0x012e,
-	0x080c, 0x7beb, 0x00de, 0x00fe, 0x0005, 0x012e, 0xe000, 0x6843,
-	0x0000, 0x7803, 0x0002, 0x780c, 0xa015, 0x0140, 0x6a3a, 0x780f,
-	0x0000, 0x6833, 0x0000, 0x683f, 0x0000, 0x0c60, 0x683a, 0x6836,
-	0x0cc0, 0xc1bc, 0x2102, 0x0066, 0x2031, 0x0001, 0x080c, 0x5b51,
-	0x006e, 0x0858, 0x601c, 0xa084, 0x000f, 0x000b, 0x0005, 0x7280,
-	0x7285, 0x7743, 0x785f, 0x7285, 0x7743, 0x785f, 0x7280, 0x7285,
-	0x080c, 0x7090, 0x080c, 0x7173, 0x0005, 0x0156, 0x0136, 0x0146,
-	0x00c6, 0x00f6, 0x6004, 0xa08a, 0x0080, 0x1a0c, 0x1515, 0x6118,
-	0x2178, 0x79a0, 0x2011, 0xb535, 0x2214, 0xd2ac, 0x1110, 0xd1bc,
-	0x0150, 0x7900, 0xd1f4, 0x0120, 0x7914, 0xa18c, 0x00ff, 0x0040,
-	0x2009, 0x0000, 0x0028, 0xa1f8, 0x2dc4, 0x2f0d, 0xa18c, 0x00ff,
-	0x2c78, 0x2061, 0x0100, 0x619a, 0xa08a, 0x0040, 0x1a04, 0x72f9,
-	0x0033, 0x00fe, 0x00ce, 0x014e, 0x013e, 0x015e, 0x0005, 0x73a8,
-	0x73f3, 0x7420, 0x74ed, 0x751b, 0x7523, 0x7549, 0x755a, 0x756b,
-	0x7573, 0x7589, 0x7573, 0x75ea, 0x755a, 0x760b, 0x7613, 0x756b,
-	0x7613, 0x7624, 0x72f7, 0x72f7, 0x72f7, 0x72f7, 0x72f7, 0x72f7,
-	0x72f7, 0x72f7, 0x72f7, 0x72f7, 0x72f7, 0x7e85, 0x7eaa, 0x7ebf,
-	0x7ee2, 0x7f03, 0x7549, 0x72f7, 0x7549, 0x7573, 0x72f7, 0x7420,
-	0x74ed, 0x72f7, 0x834f, 0x7573, 0x72f7, 0x836f, 0x7573, 0x72f7,
-	0x756b, 0x73a1, 0x730c, 0x72f7, 0x8394, 0x8409, 0x84e0, 0x72f7,
-	0x84f1, 0x7544, 0x850d, 0x72f7, 0x7f18, 0x8568, 0x72f7, 0x080c,
-	0x1515, 0x2100, 0x0033, 0x00fe, 0x00ce, 0x014e, 0x013e, 0x015e,
-	0x0005, 0x730a, 0x730a, 0x730a, 0x7340, 0x735e, 0x7374, 0x730a,
-	0x730a, 0x730a, 0x080c, 0x1515, 0x00d6, 0x20a1, 0x020b, 0x080c,
-	0x7641, 0x7810, 0x2068, 0x20a3, 0x2414, 0x20a3, 0x0018, 0x20a3,
-	0x0800, 0x683c, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3,
-	0x0000, 0x20a3, 0x0000, 0x6850, 0x20a2, 0x6854, 0x20a2, 0x20a3,
-	0x0000, 0x20a3, 0x0000, 0x60c3, 0x0018, 0x080c, 0x7d67, 0x00de,
-	0x0005, 0x00d6, 0x7818, 0x2068, 0x68a0, 0x2069, 0xb500, 0x6ad4,
-	0xd2ac, 0x1110, 0xd0bc, 0x0110, 0xa085, 0x0001, 0x00de, 0x0005,
-	0x00d6, 0x20a1, 0x020b, 0x080c, 0x7641, 0x20a3, 0x0500, 0x20a3,
-	0x0000, 0x7810, 0xa0e8, 0x000f, 0x6808, 0x20a2, 0x680c, 0x20a2,
-	0x6810, 0x20a2, 0x6814, 0x20a2, 0x6818, 0x20a2, 0x681c, 0x20a2,
-	0x60c3, 0x0010, 0x080c, 0x7d67, 0x00de, 0x0005, 0x0156, 0x0146,
-	0x20a1, 0x020b, 0x080c, 0x7641, 0x20a3, 0x7800, 0x20a3, 0x0000,
-	0x7808, 0x8007, 0x20a2, 0x20a3, 0x0000, 0x60c3, 0x0008, 0x080c,
-	0x7d67, 0x014e, 0x015e, 0x0005, 0x0156, 0x0146, 0x20a1, 0x020b,
-	0x080c, 0x76dd, 0x20a3, 0x0200, 0x20a3, 0x0000, 0x20a3, 0xdf10,
-	0x20a3, 0x0034, 0x2099, 0xb505, 0x20a9, 0x0004, 0x53a6, 0x2099,
-	0xb501, 0x20a9, 0x0004, 0x53a6, 0x2099, 0xb7c6, 0x20a9, 0x001a,
-	0x3304, 0x8007, 0x20a2, 0x9398, 0x1f04, 0x7390, 0x20a3, 0x0000,
-	0x20a3, 0x0000, 0x60c3, 0x004c, 0x080c, 0x7d67, 0x014e, 0x015e,
-	0x0005, 0x2001, 0xb515, 0x2004, 0x609a, 0x080c, 0x7d67, 0x0005,
-	0x20a1, 0x020b, 0x080c, 0x7641, 0x20a3, 0x5200, 0x20a3, 0x0000,
-	0x00d6, 0x2069, 0xb552, 0x6804, 0xd084, 0x0150, 0x6828, 0x20a3,
-	0x0000, 0x0016, 0x080c, 0x2831, 0x21a2, 0x001e, 0x00de, 0x0028,
-	0x00de, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a9, 0x0004, 0x2099,
-	0xb505, 0x53a6, 0x20a9, 0x0004, 0x2099, 0xb501, 0x53a6, 0x2001,
-	0xb535, 0x2004, 0xd0ac, 0x1138, 0x7818, 0xa080, 0x0028, 0x2004,
-	0xa082, 0x007f, 0x0238, 0x2001, 0xb51c, 0x20a6, 0x2001, 0xb51d,
-	0x20a6, 0x0040, 0x20a3, 0x0000, 0x2001, 0xb515, 0x2004, 0xa084,
-	0x00ff, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x001c,
-	0x080c, 0x7d67, 0x0005, 0x20a1, 0x020b, 0x080c, 0x7641, 0x20a3,
-	0x0500, 0x20a3, 0x0000, 0x2001, 0xb535, 0x2004, 0xd0ac, 0x1138,
-	0x7818, 0xa080, 0x0028, 0x2004, 0xa082, 0x007f, 0x0238, 0x2001,
-	0xb51c, 0x20a6, 0x2001, 0xb51d, 0x20a6, 0x0040, 0x20a3, 0x0000,
-	0x2001, 0xb515, 0x2004, 0xa084, 0x00ff, 0x20a2, 0x20a9, 0x0004,
-	0x2099, 0xb505, 0x53a6, 0x60c3, 0x0010, 0x080c, 0x7d67, 0x0005,
-	0x20a1, 0x020b, 0x080c, 0x7641, 0x00c6, 0x7818, 0x2060, 0x2001,
-	0x0000, 0x080c, 0x5313, 0x00ce, 0x7818, 0xa080, 0x0028, 0x2004,
-	0xa086, 0x007e, 0x1130, 0x20a3, 0x0400, 0x620c, 0xc2b4, 0x620e,
-	0x0010, 0x20a3, 0x0300, 0x20a3, 0x0000, 0x7818, 0xa080, 0x0028,
-	0x2004, 0xa086, 0x007e, 0x1904, 0x74af, 0x2001, 0xb535, 0x2004,
-	0xd0a4, 0x01c8, 0x2099, 0xb78e, 0x33a6, 0x9398, 0x20a3, 0x0000,
-	0x9398, 0x3304, 0xa084, 0x2000, 0x20a2, 0x9398, 0x33a6, 0x9398,
-	0x20a3, 0x0000, 0x9398, 0x2001, 0x2710, 0x20a2, 0x9398, 0x33a6,
-	0x9398, 0x33a6, 0x00d0, 0x2099, 0xb78e, 0x33a6, 0x9398, 0x33a6,
-	0x9398, 0x3304, 0x080c, 0x5acf, 0x1118, 0xa084, 0x37ff, 0x0010,
-	0xa084, 0x3fff, 0x20a2, 0x9398, 0x33a6, 0x20a3, 0x0000, 0x20a3,
-	0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a9, 0x0004, 0x2099,
-	0xb505, 0x53a6, 0x20a9, 0x0004, 0x2099, 0xb501, 0x53a6, 0x20a9,
-	0x0008, 0x20a3, 0x0000, 0x1f04, 0x7489, 0x20a9, 0x0008, 0x20a3,
-	0x0000, 0x1f04, 0x748f, 0x2099, 0xb796, 0x3304, 0xc0dd, 0x20a2,
-	0x2001, 0xb572, 0x2004, 0xd0e4, 0x0158, 0x20a3, 0x0000, 0x20a3,
-	0x0000, 0x9398, 0x9398, 0x9398, 0x33a6, 0x20a9, 0x0004, 0x0010,
-	0x20a9, 0x0007, 0x20a3, 0x0000, 0x1f04, 0x74aa, 0x0468, 0x2001,
-	0xb535, 0x2004, 0xd0a4, 0x0140, 0x2001, 0xb78f, 0x2004, 0x60e3,
-	0x0000, 0x080c, 0x2872, 0x60e2, 0x2099, 0xb78e, 0x20a9, 0x0008,
-	0x53a6, 0x20a9, 0x0004, 0x2099, 0xb505, 0x53a6, 0x20a9, 0x0004,
-	0x2099, 0xb501, 0x53a6, 0x20a9, 0x0008, 0x20a3, 0x0000, 0x1f04,
-	0x74cd, 0x20a9, 0x0008, 0x20a3, 0x0000, 0x1f04, 0x74d3, 0x2099,
-	0xb796, 0x20a9, 0x0008, 0x53a6, 0x20a9, 0x0008, 0x20a3, 0x0000,
-	0x1f04, 0x74de, 0x20a9, 0x000a, 0x20a3, 0x0000, 0x1f04, 0x74e4,
-	0x60c3, 0x0074, 0x080c, 0x7d67, 0x0005, 0x20a1, 0x020b, 0x080c,
-	0x7641, 0x20a3, 0x2010, 0x20a3, 0x0014, 0x20a3, 0x0800, 0x20a3,
-	0x2000, 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x00f6,
-	0x2079, 0xb552, 0x7904, 0x00fe, 0xd1ac, 0x1110, 0xa085, 0x0020,
-	0xd1a4, 0x0110, 0xa085, 0x0010, 0xa085, 0x0002, 0x00d6, 0x0804,
-	0x75cc, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014,
-	0x080c, 0x7d67, 0x0005, 0x20a1, 0x020b, 0x080c, 0x7641, 0x20a3,
-	0x5000, 0x0804, 0x743b, 0x20a1, 0x020b, 0x080c, 0x7641, 0x20a3,
-	0x2110, 0x20a3, 0x0014, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3,
+	0x6834, 0xa084, 0x00ff, 0xa08a, 0x001a, 0x1218, 0x003b, 0x012e,
+	0x0005, 0x012e, 0x0419, 0x0005, 0x0005, 0x0005, 0x5f86, 0x5fa2,
+	0x610b, 0x5f86, 0x5fa2, 0x5f86, 0x5fa2, 0x5fa2, 0x5f86, 0x5fa2,
+	0x610b, 0x5fa2, 0x5fa2, 0x5fa2, 0x5fa2, 0x5fa2, 0x5f86, 0x5fa2,
+	0x610b, 0x5f86, 0x5f86, 0x5fa2, 0x5f86, 0x5f86, 0x5f86, 0x5fa2,
+	0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x7007, 0x0001,
+	0x6838, 0xa084, 0x00ff, 0xc0d5, 0x683a, 0x0126, 0x2091, 0x8000,
+	0x080c, 0x547a, 0x012e, 0x0005, 0x7007, 0x0001, 0x6838, 0xa084,
+	0x00ff, 0xc0e5, 0x683a, 0x0126, 0x2091, 0x8000, 0x080c, 0x547a,
+	0x012e, 0x0005, 0x7007, 0x0001, 0x6838, 0xa084, 0x00ff, 0xc0ed,
+	0x683a, 0x0126, 0x2091, 0x8000, 0x080c, 0x547a, 0x012e, 0x0005,
+	0x7007, 0x0001, 0x6838, 0xa084, 0x00ff, 0xc0dd, 0x683a, 0x0126,
+	0x2091, 0x8000, 0x080c, 0x547a, 0x012e, 0x0005, 0x6834, 0x8007,
+	0xa084, 0x00ff, 0x0988, 0x8001, 0x1120, 0x7007, 0x0001, 0x0804,
+	0x60cb, 0x7007, 0x0006, 0x7012, 0x2d00, 0x7016, 0x701a, 0x704b,
+	0x60cb, 0x0005, 0x6834, 0x8007, 0xa084, 0x00ff, 0x0904, 0x5f94,
+	0x8001, 0x1120, 0x7007, 0x0001, 0x0804, 0x60e8, 0x7007, 0x0006,
+	0x7012, 0x2d00, 0x7016, 0x701a, 0x704b, 0x60e8, 0x0005, 0x6834,
+	0x8007, 0xa084, 0x00ff, 0xa086, 0x0001, 0x1904, 0x5f94, 0x7007,
+	0x0001, 0x2009, 0xb631, 0x210c, 0x81ff, 0x11a8, 0x6838, 0xa084,
+	0x00ff, 0x683a, 0x6853, 0x0000, 0x080c, 0x4df4, 0x1108, 0x0005,
+	0x0126, 0x2091, 0x8000, 0x6837, 0x0139, 0x684a, 0x6952, 0x080c,
+	0x547a, 0x012e, 0x0ca0, 0x2001, 0x0028, 0x0c90, 0x684c, 0xa084,
+	0x00c0, 0xa086, 0x00c0, 0x1120, 0x7007, 0x0001, 0x0804, 0x62e0,
+	0x2d00, 0x7016, 0x701a, 0x20a9, 0x0004, 0xa080, 0x0024, 0x2098,
+	0x20a1, 0xb70d, 0x53a3, 0x6858, 0x7012, 0xa082, 0x0401, 0x1a04,
+	0x5fb0, 0x6a84, 0xa28a, 0x0002, 0x1a04, 0x5fb0, 0x82ff, 0x1138,
+	0x6888, 0x698c, 0xa105, 0x0118, 0x2001, 0x609e, 0x0018, 0xa280,
+	0x6094, 0x2005, 0x70c6, 0x7010, 0xa015, 0x0904, 0x6080, 0x080c,
+	0x15e4, 0x1118, 0x7007, 0x000f, 0x0005, 0x2d00, 0x7022, 0x70c4,
+	0x2060, 0x2c05, 0x6836, 0xe004, 0xad00, 0x7096, 0xe008, 0xa20a,
+	0x1210, 0xa00e, 0x2200, 0x7112, 0xe20c, 0x8003, 0x800b, 0xa296,
+	0x0004, 0x0108, 0xa108, 0x719a, 0x810b, 0x719e, 0xae90, 0x0022,
+	0x080c, 0x1648, 0x7090, 0xa08e, 0x0100, 0x0170, 0xa086, 0x0200,
+	0x0118, 0x7007, 0x0010, 0x0005, 0x7020, 0x2068, 0x080c, 0x1614,
+	0x7014, 0x2068, 0x0804, 0x5fb0, 0x7020, 0x2068, 0x7018, 0x6802,
+	0x6807, 0x0000, 0x2d08, 0x2068, 0x6906, 0x711a, 0x0804, 0x603b,
+	0x7014, 0x2068, 0x7007, 0x0001, 0x6884, 0xa005, 0x1128, 0x6888,
+	0x698c, 0xa105, 0x0108, 0x00b1, 0x6834, 0xa084, 0x00ff, 0xa086,
+	0x001e, 0x0904, 0x62e0, 0x04b8, 0x6096, 0x609a, 0x0002, 0x0011,
+	0x0007, 0x0004, 0x000a, 0x000f, 0x0005, 0x0006, 0x000a, 0x0011,
+	0x0005, 0x0004, 0x00f6, 0x00e6, 0x00c6, 0x0076, 0x0066, 0x6f88,
+	0x6e8c, 0x6804, 0x2060, 0xacf0, 0x0021, 0xacf8, 0x0027, 0x2009,
+	0x0005, 0x700c, 0x7816, 0x7008, 0x7812, 0x7004, 0x7806, 0x7000,
+	0x7802, 0x7e0e, 0x7f0a, 0x8109, 0x0128, 0xaef2, 0x0004, 0xaffa,
+	0x0006, 0x0c78, 0x6004, 0xa065, 0x1d30, 0x006e, 0x007e, 0x00ce,
+	0x00ee, 0x00fe, 0x0005, 0x2009, 0xb631, 0x210c, 0x81ff, 0x1198,
+	0x6838, 0xa084, 0x00ff, 0x683a, 0x080c, 0x4cd7, 0x1108, 0x0005,
+	0x080c, 0x554d, 0x0126, 0x2091, 0x8000, 0x080c, 0x9f88, 0x080c,
+	0x547a, 0x012e, 0x0ca0, 0x2001, 0x0028, 0x2009, 0x0000, 0x0c80,
+	0x2009, 0xb631, 0x210c, 0x81ff, 0x11b0, 0x6858, 0xa005, 0x01c0,
+	0x6838, 0xa084, 0x00ff, 0x683a, 0x6853, 0x0000, 0x080c, 0x4d98,
+	0x1108, 0x0005, 0x0126, 0x2091, 0x8000, 0x684a, 0x6952, 0x080c,
+	0x547a, 0x012e, 0x0cb0, 0x2001, 0x0028, 0x2009, 0x0000, 0x0c90,
+	0x2001, 0x0000, 0x0c78, 0x7018, 0x6802, 0x2d08, 0x2068, 0x6906,
+	0x711a, 0x7010, 0x8001, 0x7012, 0x0118, 0x7007, 0x0006, 0x0030,
+	0x7014, 0x2068, 0x7007, 0x0001, 0x7048, 0x080f, 0x0005, 0x7007,
+	0x0001, 0x6944, 0x810f, 0xa18c, 0x00ff, 0x6848, 0xa084, 0x00ff,
+	0x20a9, 0x0001, 0xa096, 0x0001, 0x01b0, 0x2009, 0x0000, 0x20a9,
+	0x00ff, 0xa096, 0x0002, 0x0178, 0xa005, 0x11f0, 0x6944, 0x810f,
+	0xa18c, 0x00ff, 0x080c, 0x501b, 0x11b8, 0x0066, 0x6e50, 0x080c,
+	0x511a, 0x006e, 0x0088, 0x0046, 0x2011, 0xb60c, 0x2224, 0xc484,
+	0x2412, 0x004e, 0x00c6, 0x080c, 0x501b, 0x1110, 0x080c, 0x527b,
+	0x8108, 0x1f04, 0x614b, 0x00ce, 0x684c, 0xd084, 0x1118, 0x080c,
+	0x1614, 0x0005, 0x0126, 0x2091, 0x8000, 0x080c, 0x547a, 0x012e,
+	0x0005, 0x0126, 0x2091, 0x8000, 0x7007, 0x0001, 0x2001, 0xb653,
+	0x2004, 0xd0a4, 0x0580, 0x2061, 0xb975, 0x6100, 0xd184, 0x0178,
+	0x6858, 0xa084, 0x00ff, 0x1550, 0x6000, 0xd084, 0x0520, 0x6004,
+	0xa005, 0x1538, 0x6003, 0x0000, 0x600b, 0x0000, 0x00c8, 0x2011,
+	0x0001, 0x6860, 0xa005, 0x1110, 0x2001, 0x001e, 0x8000, 0x6016,
+	0x6858, 0xa084, 0x00ff, 0x0178, 0x6006, 0x6858, 0x8007, 0xa084,
+	0x00ff, 0x0148, 0x600a, 0x6858, 0x8000, 0x1108, 0xc28d, 0x6202,
+	0x012e, 0x0804, 0x63a4, 0x012e, 0x0804, 0x639e, 0x012e, 0x0804,
+	0x6398, 0x012e, 0x0804, 0x639b, 0x0126, 0x2091, 0x8000, 0x7007,
+	0x0001, 0x2001, 0xb653, 0x2004, 0xd0a4, 0x05e0, 0x2061, 0xb975,
+	0x6000, 0xd084, 0x05b8, 0x6204, 0x6308, 0xd08c, 0x1530, 0x6c48,
+	0xa484, 0x0003, 0x0170, 0x6958, 0xa18c, 0x00ff, 0x8001, 0x1120,
+	0x2100, 0xa210, 0x0620, 0x0028, 0x8001, 0x1508, 0x2100, 0xa212,
+	0x02f0, 0xa484, 0x000c, 0x0188, 0x6958, 0x810f, 0xa18c, 0x00ff,
+	0xa082, 0x0004, 0x1120, 0x2100, 0xa318, 0x0288, 0x0030, 0xa082,
+	0x0004, 0x1168, 0x2100, 0xa31a, 0x0250, 0x6860, 0xa005, 0x0110,
+	0x8000, 0x6016, 0x6206, 0x630a, 0x012e, 0x0804, 0x63a4, 0x012e,
+	0x0804, 0x63a1, 0x012e, 0x0804, 0x639e, 0x0126, 0x2091, 0x8000,
+	0x7007, 0x0001, 0x2061, 0xb975, 0x6300, 0xd38c, 0x1120, 0x6308,
+	0x8318, 0x0220, 0x630a, 0x012e, 0x0804, 0x63b2, 0x012e, 0x0804,
+	0x63a1, 0x0126, 0x00c6, 0x2091, 0x8000, 0x7007, 0x0001, 0x684c,
+	0xd0ac, 0x0148, 0x00c6, 0x2061, 0xb975, 0x6000, 0xa084, 0xfcff,
+	0x6002, 0x00ce, 0x0448, 0x6858, 0xa005, 0x05d0, 0x685c, 0xa065,
+	0x0598, 0x2001, 0xb631, 0x2004, 0xa005, 0x0118, 0x080c, 0x9ed9,
+	0x0068, 0x6013, 0x0400, 0x6057, 0x0000, 0x694c, 0xd1a4, 0x0110,
+	0x6950, 0x6156, 0x2009, 0x0041, 0x080c, 0x86d3, 0x6958, 0xa18c,
+	0xff00, 0xa186, 0x2000, 0x1140, 0x0026, 0x2009, 0x0000, 0x2011,
+	0xfdff, 0x080c, 0x6b8c, 0x002e, 0x684c, 0xd0c4, 0x0148, 0x2061,
+	0xb975, 0x6000, 0xd08c, 0x1120, 0x6008, 0x8000, 0x0208, 0x600a,
+	0x00ce, 0x012e, 0x0804, 0x63a4, 0x00ce, 0x012e, 0x0804, 0x639e,
+	0x6954, 0xa186, 0x002e, 0x0d40, 0xa186, 0x002d, 0x0d28, 0xa186,
+	0x0045, 0x0528, 0xa186, 0x002a, 0x1130, 0x2001, 0xb60c, 0x200c,
+	0xc194, 0x2102, 0x08c8, 0xa186, 0x0020, 0x0170, 0xa186, 0x0029,
+	0x1d18, 0x6944, 0xa18c, 0xff00, 0x810f, 0x080c, 0x501b, 0x1960,
+	0x6000, 0xc0e4, 0x6002, 0x0840, 0x685c, 0xa065, 0x09a8, 0x6007,
+	0x0024, 0x2001, 0xb8b6, 0x2004, 0x6016, 0x0804, 0x623c, 0x685c,
+	0xa065, 0x0950, 0x00e6, 0x6860, 0xa075, 0x2001, 0xb631, 0x2004,
+	0xa005, 0x0150, 0x080c, 0x9ed9, 0x8eff, 0x0118, 0x2e60, 0x080c,
+	0x9ed9, 0x00ee, 0x0804, 0x623c, 0x6020, 0xc0dc, 0xc0d5, 0x6022,
+	0x2e60, 0x6007, 0x003a, 0x6870, 0xa005, 0x0130, 0x6007, 0x003b,
+	0x6874, 0x602a, 0x6878, 0x6012, 0x6003, 0x0001, 0x080c, 0x6cff,
+	0x080c, 0x71e5, 0x00ee, 0x0804, 0x623c, 0x2061, 0xb975, 0x6000,
+	0xd084, 0x0190, 0xd08c, 0x1904, 0x63b2, 0x0126, 0x2091, 0x8000,
+	0x6204, 0x8210, 0x0220, 0x6206, 0x012e, 0x0804, 0x63b2, 0x012e,
+	0x6853, 0x0016, 0x0804, 0x63ab, 0x6853, 0x0007, 0x0804, 0x63ab,
+	0x6834, 0x8007, 0xa084, 0x00ff, 0x1118, 0x080c, 0x5f94, 0x0078,
+	0x2030, 0x8001, 0x1120, 0x7007, 0x0001, 0x0051, 0x0040, 0x7007,
+	0x0006, 0x7012, 0x2d00, 0x7016, 0x701a, 0x704b, 0x62e0, 0x0005,
+	0x00e6, 0x0126, 0x2091, 0x8000, 0xa03e, 0x2009, 0xb631, 0x210c,
+	0x81ff, 0x1904, 0x635e, 0x2009, 0xb60c, 0x210c, 0xd194, 0x1904,
+	0x6388, 0x6848, 0x2070, 0xae82, 0xbe00, 0x0a04, 0x6352, 0x2001,
+	0xb617, 0x2004, 0xae02, 0x1a04, 0x6352, 0x711c, 0xa186, 0x0006,
+	0x1904, 0x6341, 0x7018, 0xa005, 0x0904, 0x635e, 0x2004, 0xd0e4,
+	0x1904, 0x6383, 0x2061, 0xb975, 0x6100, 0xa184, 0x0301, 0xa086,
+	0x0001, 0x1550, 0x7020, 0xd0dc, 0x1904, 0x638b, 0x6853, 0x0000,
+	0x6803, 0x0000, 0x2d08, 0x7010, 0xa005, 0x1158, 0x7112, 0x684c,
+	0xd0f4, 0x1904, 0x638e, 0x2e60, 0x080c, 0x6ae8, 0x012e, 0x00ee,
+	0x0005, 0x2068, 0x6800, 0xa005, 0x1de0, 0x6902, 0x2168, 0x684c,
+	0xd0f4, 0x1904, 0x638e, 0x012e, 0x00ee, 0x0005, 0x012e, 0x00ee,
+	0x6853, 0x0006, 0x0804, 0x63ab, 0xd184, 0x0dc0, 0xd1c4, 0x11a8,
+	0x00b8, 0x6944, 0xa18c, 0xff00, 0x810f, 0x080c, 0x501b, 0x15d8,
+	0x6000, 0xd0e4, 0x15c0, 0x711c, 0xa186, 0x0007, 0x1118, 0x6853,
+	0x0002, 0x0498, 0x6853, 0x0008, 0x0480, 0x6853, 0x000e, 0x0468,
+	0x6853, 0x0017, 0x0450, 0x6853, 0x0035, 0x0438, 0x2001, 0xb672,
+	0x2004, 0xd0fc, 0x01e8, 0x6848, 0x2070, 0xae82, 0xbe00, 0x02c0,
+	0x605c, 0xae02, 0x12a8, 0x711c, 0xa186, 0x0006, 0x1188, 0x7018,
+	0xa005, 0x0170, 0x2004, 0xd0bc, 0x0158, 0x2039, 0x0001, 0x7000,
+	0xa086, 0x0007, 0x1904, 0x62eb, 0x7003, 0x0002, 0x0804, 0x62eb,
+	0x6853, 0x0028, 0x0010, 0x6853, 0x0029, 0x012e, 0x00ee, 0x0418,
+	0x6853, 0x002a, 0x0cd0, 0x6853, 0x0045, 0x0cb8, 0x2e60, 0x2019,
+	0x0002, 0x6017, 0x0014, 0x080c, 0xad9c, 0x012e, 0x00ee, 0x0005,
+	0x2009, 0x003e, 0x0058, 0x2009, 0x0004, 0x0040, 0x2009, 0x0006,
+	0x0028, 0x2009, 0x0016, 0x0010, 0x2009, 0x0001, 0x6854, 0xa084,
+	0xff00, 0xa105, 0x6856, 0x0126, 0x2091, 0x8000, 0x080c, 0x547a,
+	0x012e, 0x0005, 0x080c, 0x1614, 0x0005, 0x702c, 0x7130, 0x8108,
+	0xa102, 0x0230, 0xa00e, 0x7034, 0x7072, 0x7038, 0x7076, 0x0058,
+	0x7070, 0xa080, 0x0040, 0x7072, 0x1230, 0x7074, 0xa081, 0x0000,
+	0x7076, 0xa085, 0x0001, 0x7932, 0x7132, 0x0005, 0x00d6, 0x080c,
+	0x6adf, 0x00de, 0x0005, 0x00d6, 0x00c6, 0x0036, 0x0026, 0x0016,
+	0x7007, 0x0001, 0x6a44, 0xa282, 0x0004, 0x1a04, 0x641e, 0xd284,
+	0x0170, 0x6a4c, 0xa290, 0xb735, 0x2204, 0xa065, 0x6004, 0x05e0,
+	0x8007, 0xa084, 0x00ff, 0xa084, 0x0006, 0x1108, 0x04a8, 0x2c10,
+	0x080c, 0x864e, 0x1118, 0x080c, 0x9f92, 0x05a0, 0x621a, 0x6844,
+	0x0002, 0x63fd, 0x6402, 0x6405, 0x640b, 0x2019, 0x0002, 0x080c,
+	0xb121, 0x0060, 0x080c, 0xb0b8, 0x0048, 0x2019, 0x0002, 0x6950,
+	0x080c, 0xb0d3, 0x0018, 0x6950, 0x080c, 0xb0b8, 0x080c, 0x86a4,
+	0x6857, 0x0000, 0x0126, 0x2091, 0x8000, 0x080c, 0x547a, 0x012e,
+	0x001e, 0x002e, 0x003e, 0x00ce, 0x00de, 0x0005, 0x6857, 0x0006,
+	0x0c88, 0x6857, 0x0002, 0x0c70, 0x6857, 0x0005, 0x0c58, 0x6857,
+	0x0004, 0x0c40, 0x6857, 0x0007, 0x0c28, 0x00d6, 0x2011, 0x0004,
+	0x2204, 0xa085, 0x8002, 0x2012, 0x00de, 0x0005, 0x20e1, 0x0002,
+	0x3d08, 0x20e1, 0x2000, 0x3d00, 0xa084, 0x7000, 0x0118, 0xa086,
+	0x1000, 0x1570, 0x20e1, 0x0000, 0x3d00, 0xa094, 0xff00, 0x8217,
+	0xa084, 0xf000, 0xa086, 0x3000, 0x1160, 0xa184, 0xff00, 0x8007,
+	0xa086, 0x0008, 0x11e8, 0x080c, 0x2df4, 0x11d0, 0x080c, 0x6675,
+	0x0098, 0x20e1, 0x0004, 0x3d60, 0xd1bc, 0x1108, 0x3e60, 0xac84,
+	0x0007, 0x1170, 0xac82, 0xbe00, 0x0258, 0x685c, 0xac02, 0x1240,
+	0x2009, 0x0047, 0x080c, 0x86d3, 0x7a1c, 0xd284, 0x1938, 0x0005,
+	0xa016, 0x080c, 0x1863, 0x0cc0, 0x0cd8, 0x781c, 0xd08c, 0x0500,
+	0x0156, 0x0136, 0x0146, 0x20e1, 0x3000, 0x3d20, 0x3e28, 0xa584,
+	0x0076, 0x1538, 0xa484, 0x7000, 0xa086, 0x1000, 0x11a8, 0x080c,
+	0x64f0, 0x01f8, 0x20e1, 0x3000, 0x7828, 0x7828, 0x080c, 0x650c,
+	0x014e, 0x013e, 0x015e, 0x2009, 0xb8e9, 0x2104, 0xa005, 0x1108,
+	0x0005, 0x080c, 0x71e5, 0x0ce0, 0xa484, 0x7000, 0x1548, 0x080c,
+	0x64f0, 0x01d8, 0x7000, 0xa084, 0xff00, 0xa086, 0x8100, 0x0d10,
+	0x00a0, 0xd5a4, 0x0178, 0x0056, 0x0046, 0x080c, 0x1e8a, 0x080c,
+	0x24e5, 0x2001, 0x0160, 0x2502, 0x2001, 0x0138, 0x2202, 0x004e,
+	0x005e, 0x0048, 0x04a9, 0x6887, 0x0000, 0x080c, 0xb49b, 0x20e1,
+	0x3000, 0x7828, 0x7828, 0x00b9, 0x014e, 0x013e, 0x015e, 0x0880,
+	0x0439, 0x1130, 0x7000, 0xa084, 0xff00, 0xa086, 0x8100, 0x1d68,
+	0x080c, 0xb49b, 0x20e1, 0x3000, 0x7828, 0x7828, 0x0056, 0x080c,
+	0x68e6, 0x005e, 0x0c40, 0x2001, 0xb60e, 0x2004, 0xd08c, 0x0178,
+	0x2001, 0xb600, 0x2004, 0xa086, 0x0003, 0x1148, 0x0026, 0x0036,
+	0x2011, 0x8048, 0x2518, 0x080c, 0x3f13, 0x003e, 0x002e, 0x0005,
+	0xa484, 0x01ff, 0x6886, 0xa005, 0x0160, 0xa080, 0x001f, 0xa084,
+	0x03f8, 0x80ac, 0x20e1, 0x1000, 0x2ea0, 0x2099, 0x020a, 0x53a5,
+	0x0005, 0x20a9, 0x000c, 0x20e1, 0x1000, 0x2ea0, 0x2099, 0x020a,
+	0x53a5, 0xa085, 0x0001, 0x0ca0, 0x7000, 0xa084, 0xff00, 0xa08c,
+	0xf000, 0x8007, 0xa196, 0x0000, 0x1118, 0x0804, 0x677a, 0x0005,
+	0xa196, 0x2000, 0x1148, 0x6900, 0xa18e, 0x0001, 0x1118, 0x080c,
+	0x44d6, 0x0ca8, 0x0039, 0x0c98, 0xa196, 0x8000, 0x1d80, 0x080c,
+	0x6826, 0x0c68, 0x00c6, 0x6a84, 0x82ff, 0x0904, 0x666f, 0x7110,
+	0xa18c, 0xff00, 0x810f, 0xa196, 0x0001, 0x0120, 0xa196, 0x0023,
+	0x1904, 0x666f, 0xa08e, 0x0023, 0x1570, 0x080c, 0x68c1, 0x0904,
+	0x666f, 0x7124, 0x610a, 0x7030, 0xa08e, 0x0200, 0x1150, 0x7034,
+	0xa005, 0x1904, 0x666f, 0x2009, 0x0015, 0x080c, 0x86d3, 0x0804,
+	0x666f, 0xa08e, 0x0214, 0x0118, 0xa08e, 0x0210, 0x1130, 0x2009,
+	0x0015, 0x080c, 0x86d3, 0x0804, 0x666f, 0xa08e, 0x0100, 0x1904,
+	0x666f, 0x7034, 0xa005, 0x1904, 0x666f, 0x2009, 0x0016, 0x080c,
+	0x86d3, 0x0804, 0x666f, 0xa08e, 0x0022, 0x1904, 0x666f, 0x7030,
+	0xa08e, 0x0300, 0x1580, 0x68d4, 0xd0a4, 0x0528, 0xc0b5, 0x68d6,
+	0x7100, 0xa18c, 0x00ff, 0x6972, 0x7004, 0x6876, 0x00f6, 0x2079,
+	0x0100, 0x79e6, 0x78ea, 0x0006, 0xa084, 0x00ff, 0x0016, 0x2008,
+	0x080c, 0x287c, 0x7932, 0x7936, 0x001e, 0x000e, 0x00fe, 0x080c,
+	0x2852, 0x6952, 0x703c, 0x00e6, 0x2071, 0x0140, 0x7086, 0x2071,
+	0xb600, 0x70a6, 0x00ee, 0x7034, 0xa005, 0x1904, 0x666f, 0x2009,
+	0x0017, 0x0804, 0x6635, 0xa08e, 0x0400, 0x1158, 0x7034, 0xa005,
+	0x1904, 0x666f, 0x68d4, 0xc0a5, 0x68d6, 0x2009, 0x0030, 0x0804,
+	0x6635, 0xa08e, 0x0500, 0x1140, 0x7034, 0xa005, 0x1904, 0x666f,
+	0x2009, 0x0018, 0x0804, 0x6635, 0xa08e, 0x2010, 0x1120, 0x2009,
+	0x0019, 0x0804, 0x6635, 0xa08e, 0x2110, 0x1120, 0x2009, 0x001a,
+	0x0804, 0x6635, 0xa08e, 0x5200, 0x1140, 0x7034, 0xa005, 0x1904,
+	0x666f, 0x2009, 0x001b, 0x0804, 0x6635, 0xa08e, 0x5000, 0x1140,
+	0x7034, 0xa005, 0x1904, 0x666f, 0x2009, 0x001c, 0x0804, 0x6635,
+	0xa08e, 0x1300, 0x1120, 0x2009, 0x0034, 0x0804, 0x6635, 0xa08e,
+	0x1200, 0x1140, 0x7034, 0xa005, 0x1904, 0x666f, 0x2009, 0x0024,
+	0x0804, 0x6635, 0xa08c, 0xff00, 0xa18e, 0x2400, 0x1118, 0x2009,
+	0x002d, 0x04d8, 0xa08c, 0xff00, 0xa18e, 0x5300, 0x1118, 0x2009,
+	0x002a, 0x0498, 0xa08e, 0x0f00, 0x1118, 0x2009, 0x0020, 0x0468,
+	0xa08e, 0x5300, 0x1108, 0x00d8, 0xa08e, 0x6104, 0x11c0, 0x2011,
+	0xbc8d, 0x8208, 0x2204, 0xa082, 0x0004, 0x20a8, 0x95ac, 0x95ac,
+	0x2011, 0x8015, 0x211c, 0x8108, 0x0046, 0x2124, 0x080c, 0x3f13,
+	0x004e, 0x8108, 0x1f04, 0x6618, 0x2009, 0x0023, 0x0070, 0xa08e,
+	0x6000, 0x1118, 0x2009, 0x003f, 0x0040, 0xa08e, 0x7800, 0x1118,
+	0x2009, 0x0045, 0x0010, 0x2009, 0x001d, 0x0016, 0x2011, 0xbc83,
+	0x2204, 0x8211, 0x220c, 0x080c, 0x2852, 0x1598, 0x080c, 0x4fbf,
+	0x1580, 0x6612, 0x6516, 0x86ff, 0x01e8, 0x001e, 0x0016, 0xa186,
+	0x0017, 0x1158, 0x6870, 0xa606, 0x11a8, 0x6874, 0xa506, 0xa084,
+	0xff00, 0x1180, 0x6000, 0xc0f5, 0x6002, 0xa186, 0x0046, 0x1150,
+	0x6870, 0xa606, 0x1138, 0x6874, 0xa506, 0xa084, 0xff00, 0x1110,
+	0x001e, 0x0068, 0x00c6, 0x080c, 0x864e, 0x0168, 0x001e, 0x611a,
+	0x601f, 0x0004, 0x7120, 0x610a, 0x001e, 0x080c, 0x86d3, 0x00ce,
+	0x0005, 0x001e, 0x0ce0, 0x00ce, 0x0ce0, 0x00c6, 0x0046, 0x080c,
+	0x66c9, 0x1904, 0x66c6, 0xa28e, 0x0033, 0x11e8, 0x080c, 0x68c1,
+	0x0904, 0x66c6, 0x7124, 0x610a, 0x7030, 0xa08e, 0x0200, 0x1140,
+	0x7034, 0xa005, 0x15d8, 0x2009, 0x0015, 0x080c, 0x86d3, 0x04b0,
+	0xa08e, 0x0100, 0x1598, 0x7034, 0xa005, 0x1580, 0x2009, 0x0016,
+	0x080c, 0x86d3, 0x0458, 0xa28e, 0x0032, 0x1540, 0x7030, 0xa08e,
+	0x1400, 0x1520, 0x2009, 0x0038, 0x0016, 0x2011, 0xbc83, 0x2204,
+	0x8211, 0x220c, 0x080c, 0x2852, 0x11c0, 0x080c, 0x4fbf, 0x11a8,
+	0x6612, 0x6516, 0x00c6, 0x080c, 0x864e, 0x0170, 0x001e, 0x611a,
+	0x080c, 0xa0e3, 0x601f, 0x0004, 0x7120, 0x610a, 0x001e, 0x080c,
+	0x86d3, 0x080c, 0x71e5, 0x0010, 0x00ce, 0x001e, 0x004e, 0x00ce,
+	0x0005, 0x00f6, 0x00d6, 0x0026, 0x0016, 0x0136, 0x0146, 0x0156,
+	0x3c00, 0x0006, 0x2079, 0x0030, 0x2069, 0x0200, 0x080c, 0x1f49,
+	0x1590, 0x080c, 0x1dee, 0x05e0, 0x04f1, 0x1130, 0x7908, 0xa18c,
+	0x1fff, 0xa182, 0x0011, 0x1688, 0x20a9, 0x000c, 0x20e1, 0x0000,
+	0x2ea0, 0x2099, 0x020a, 0x53a5, 0x20e1, 0x2000, 0x2001, 0x020a,
+	0x2004, 0x7a0c, 0x7808, 0xa080, 0x0007, 0xa084, 0x1ff8, 0x0419,
+	0x1120, 0xa08a, 0x0140, 0x1a0c, 0x151a, 0x80ac, 0x20e1, 0x6000,
+	0x2099, 0x020a, 0x53a5, 0x20e1, 0x7000, 0x6828, 0x6828, 0x7803,
+	0x0004, 0xa294, 0x0070, 0x000e, 0x20e0, 0x015e, 0x014e, 0x013e,
+	0x001e, 0x002e, 0x00de, 0x00fe, 0x0005, 0xa016, 0x080c, 0x1863,
+	0xa085, 0x0001, 0x0c80, 0x0006, 0x2001, 0x0111, 0x2004, 0xa084,
+	0x0003, 0x000e, 0x0005, 0x0046, 0x00e6, 0x00d6, 0x2028, 0x2130,
+	0xa696, 0x00ff, 0x1198, 0xa596, 0xfffd, 0x1120, 0x2009, 0x007f,
+	0x0804, 0x6775, 0xa596, 0xfffe, 0x1118, 0x2009, 0x007e, 0x04e8,
+	0xa596, 0xfffc, 0x1118, 0x2009, 0x0080, 0x04b8, 0x2011, 0x0000,
+	0x2019, 0xb635, 0x231c, 0xd3ac, 0x0138, 0x2021, 0x0000, 0x20a9,
+	0x00ff, 0x2071, 0xb735, 0x0030, 0x2021, 0x0081, 0x20a9, 0x007e,
+	0x2071, 0xb7b6, 0x2e1c, 0x83ff, 0x1128, 0x82ff, 0x1198, 0x2410,
+	0xc2fd, 0x0080, 0x2368, 0x6f10, 0x0006, 0x2100, 0xa706, 0x000e,
+	0x6b14, 0x1120, 0xa346, 0x1110, 0x2408, 0x0078, 0x87ff, 0x1110,
+	0x83ff, 0x0d58, 0x8420, 0x8e70, 0x1f04, 0x6752, 0x82ff, 0x1118,
+	0xa085, 0x0001, 0x0018, 0xc2fc, 0x2208, 0xa006, 0x00de, 0x00ee,
+	0x004e, 0x0005, 0xa084, 0x0007, 0x000a, 0x0005, 0x6786, 0x6786,
+	0x6786, 0x68d3, 0x6786, 0x6787, 0x679c, 0x6811, 0x0005, 0x7110,
+	0xd1bc, 0x0188, 0x7120, 0x2160, 0xac8c, 0x0007, 0x1160, 0xac8a,
+	0xbe00, 0x0248, 0x685c, 0xac02, 0x1230, 0x7124, 0x610a, 0x2009,
+	0x0046, 0x080c, 0x86d3, 0x0005, 0x00c6, 0xa484, 0x01ff, 0x0904,
+	0x67ef, 0x7110, 0xd1bc, 0x1904, 0x67ef, 0x2011, 0xbc83, 0x2204,
+	0x8211, 0x220c, 0x080c, 0x2852, 0x1904, 0x67ef, 0x080c, 0x4fbf,
+	0x15f0, 0x6612, 0x6516, 0x6000, 0xd0ec, 0x15c8, 0x6204, 0xa294,
+	0xff00, 0x8217, 0xa286, 0x0006, 0x0148, 0x6204, 0xa294, 0x00ff,
+	0xa286, 0x0006, 0x11a0, 0xa295, 0x0600, 0x6206, 0x00c6, 0x080c,
+	0x864e, 0x001e, 0x0530, 0x611a, 0x601f, 0x0006, 0x7120, 0x610a,
+	0x7130, 0x6152, 0x2009, 0x0044, 0x080c, 0x86d3, 0x00c0, 0x00c6,
+	0x080c, 0x864e, 0x001e, 0x0198, 0x611a, 0x601f, 0x0004, 0x7120,
+	0x610a, 0xa286, 0x0004, 0x1118, 0x6007, 0x0005, 0x0010, 0x6007,
+	0x0001, 0x6003, 0x0001, 0x080c, 0x6d45, 0x080c, 0x71e5, 0x00ce,
+	0x0005, 0x2001, 0xb60d, 0x2004, 0xd0ec, 0x0120, 0x2011, 0x8049,
+	0x080c, 0x3f13, 0x00c6, 0x080c, 0x9f92, 0x001e, 0x0d80, 0x611a,
+	0x601f, 0x0006, 0x7120, 0x610a, 0x7130, 0x6152, 0x6013, 0x0300,
+	0x6003, 0x0001, 0x6007, 0x0041, 0x080c, 0x6cff, 0x080c, 0x71e5,
+	0x08f0, 0x7110, 0xd1bc, 0x0188, 0x7020, 0x2060, 0xac84, 0x0007,
+	0x1160, 0xac82, 0xbe00, 0x0248, 0x685c, 0xac02, 0x1230, 0x7124,
+	0x610a, 0x2009, 0x0045, 0x080c, 0x86d3, 0x0005, 0x0006, 0x080c,
+	0x2df4, 0x000e, 0x1168, 0x7110, 0xa18c, 0xff00, 0x810f, 0xa18e,
+	0x0000, 0x1130, 0xa084, 0x000f, 0xa08a, 0x0006, 0x1208, 0x000b,
+	0x0005, 0x683f, 0x6840, 0x683f, 0x683f, 0x68a9, 0x68b5, 0x0005,
+	0x7110, 0xd1bc, 0x0120, 0x702c, 0xd084, 0x0904, 0x68a8, 0x700c,
+	0x7108, 0x080c, 0x2852, 0x1904, 0x68a8, 0x080c, 0x4fbf, 0x1904,
+	0x68a8, 0x6612, 0x6516, 0x6204, 0x7110, 0xd1bc, 0x01f8, 0xa28c,
+	0x00ff, 0xa186, 0x0004, 0x0118, 0xa186, 0x0006, 0x15c8, 0x00c6,
+	0x080c, 0x68c1, 0x00ce, 0x0904, 0x68a8, 0x00c6, 0x080c, 0x864e,
+	0x001e, 0x05f0, 0x611a, 0x080c, 0xa0e3, 0x601f, 0x0002, 0x7120,
+	0x610a, 0x2009, 0x0088, 0x080c, 0x86d3, 0x0490, 0xa28c, 0x00ff,
+	0xa186, 0x0006, 0x0160, 0xa186, 0x0004, 0x0148, 0xa294, 0xff00,
+	0x8217, 0xa286, 0x0004, 0x0118, 0xa286, 0x0006, 0x1188, 0x00c6,
+	0x080c, 0x864e, 0x001e, 0x01e0, 0x611a, 0x080c, 0xa0e3, 0x601f,
+	0x0005, 0x7120, 0x610a, 0x2009, 0x0088, 0x080c, 0x86d3, 0x0080,
+	0x00c6, 0x080c, 0x864e, 0x001e, 0x0158, 0x611a, 0x080c, 0xa0e3,
+	0x601f, 0x0004, 0x7120, 0x610a, 0x2009, 0x0001, 0x080c, 0x86d3,
+	0x0005, 0x7110, 0xd1bc, 0x0140, 0x00a1, 0x0130, 0x7124, 0x610a,
+	0x2009, 0x0089, 0x080c, 0x86d3, 0x0005, 0x7110, 0xd1bc, 0x0140,
+	0x0041, 0x0130, 0x7124, 0x610a, 0x2009, 0x008a, 0x080c, 0x86d3,
+	0x0005, 0x7020, 0x2060, 0xac84, 0x0007, 0x1158, 0xac82, 0xbe00,
+	0x0240, 0x2001, 0xb617, 0x2004, 0xac02, 0x1218, 0xa085, 0x0001,
+	0x0005, 0xa006, 0x0ce8, 0x7110, 0xd1bc, 0x1178, 0x7024, 0x2060,
+	0xac84, 0x0007, 0x1150, 0xac82, 0xbe00, 0x0238, 0x685c, 0xac02,
+	0x1220, 0x2009, 0x0051, 0x080c, 0x86d3, 0x0005, 0x2031, 0x0105,
+	0x0069, 0x0005, 0x2031, 0x0206, 0x0049, 0x0005, 0x2031, 0x0207,
+	0x0029, 0x0005, 0x2031, 0x0213, 0x0009, 0x0005, 0x00c6, 0x00d6,
+	0x00f6, 0x7000, 0xa084, 0xf000, 0xa086, 0xc000, 0x05b0, 0x080c,
+	0x864e, 0x0598, 0x0066, 0x00c6, 0x0046, 0x2011, 0xbc83, 0x2204,
+	0x8211, 0x220c, 0x080c, 0x2852, 0x1580, 0x080c, 0x4fbf, 0x1568,
+	0x6612, 0x6516, 0x2c00, 0x004e, 0x00ce, 0x601a, 0x080c, 0xa0e3,
+	0x080c, 0x15fd, 0x01f0, 0x2d00, 0x6056, 0x6803, 0x0000, 0x6837,
+	0x0000, 0x6c3a, 0xadf8, 0x000f, 0x20a9, 0x000e, 0x2fa0, 0x2e98,
+	0x53a3, 0x006e, 0x6612, 0x6007, 0x003e, 0x601f, 0x0001, 0x6003,
+	0x0001, 0x080c, 0x6d45, 0x080c, 0x71e5, 0x00fe, 0x00de, 0x00ce,
+	0x0005, 0x080c, 0x86a4, 0x006e, 0x0cc0, 0x004e, 0x00ce, 0x0cc8,
+	0x2071, 0xb8f4, 0x7003, 0x0003, 0x700f, 0x0361, 0xa006, 0x701a,
+	0x7076, 0x7012, 0x7017, 0xbe00, 0x7007, 0x0000, 0x7026, 0x702b,
+	0x7e0a, 0x7032, 0x7037, 0x7e6a, 0x703b, 0xffff, 0x703f, 0xffff,
+	0x7042, 0x7047, 0x4492, 0x704a, 0x705b, 0x6a9d, 0x2001, 0xb8a1,
+	0x2003, 0x0003, 0x2001, 0xb8a3, 0x2003, 0x0100, 0x3a00, 0xa084,
+	0x0005, 0x706e, 0x0005, 0x2071, 0xb8f4, 0x1d04, 0x69fd, 0x2091,
+	0x6000, 0x700c, 0x8001, 0x700e, 0x1518, 0x700f, 0x0361, 0x7007,
+	0x0001, 0x0126, 0x2091, 0x8000, 0x7040, 0xa00d, 0x0128, 0x8109,
+	0x7142, 0x1110, 0x7044, 0x080f, 0x00c6, 0x2061, 0xb600, 0x6034,
+	0x00ce, 0xd0cc, 0x0180, 0x3a00, 0xa084, 0x0005, 0x726c, 0xa216,
+	0x0150, 0x706e, 0x2011, 0x8043, 0x2018, 0x080c, 0x3f13, 0x0018,
+	0x0126, 0x2091, 0x8000, 0x7024, 0xa00d, 0x0188, 0x7020, 0x8001,
+	0x7022, 0x1168, 0x7023, 0x0009, 0x8109, 0x7126, 0xa186, 0x03e8,
+	0x1110, 0x7028, 0x080f, 0x81ff, 0x1110, 0x7028, 0x080f, 0x7030,
+	0xa00d, 0x0180, 0x702c, 0x8001, 0x702e, 0x1160, 0x702f, 0x0009,
+	0x8109, 0x7132, 0x0128, 0xa184, 0x007f, 0x090c, 0x7eaf, 0x0010,
+	0x7034, 0x080f, 0x7038, 0xa005, 0x0118, 0x0310, 0x8001, 0x703a,
+	0x703c, 0xa005, 0x0118, 0x0310, 0x8001, 0x703e, 0x704c, 0xa00d,
+	0x0168, 0x7048, 0x8001, 0x704a, 0x1148, 0x704b, 0x0009, 0x8109,
+	0x714e, 0x1120, 0x7150, 0x714e, 0x7058, 0x080f, 0x7018, 0xa00d,
+	0x01d8, 0x0016, 0x7074, 0xa00d, 0x0158, 0x7070, 0x8001, 0x7072,
+	0x1138, 0x7073, 0x0009, 0x8109, 0x7176, 0x1110, 0x7078, 0x080f,
+	0x001e, 0x7008, 0x8001, 0x700a, 0x1138, 0x700b, 0x0009, 0x8109,
+	0x711a, 0x1110, 0x701c, 0x080f, 0x012e, 0x7004, 0x0002, 0x6a23,
+	0x6a24, 0x6a3c, 0x00e6, 0x2071, 0xb8f4, 0x7018, 0xa005, 0x1120,
+	0x711a, 0x721e, 0x700b, 0x0009, 0x00ee, 0x0005, 0x00e6, 0x0006,
+	0x2071, 0xb8f4, 0x701c, 0xa206, 0x1110, 0x701a, 0x701e, 0x000e,
+	0x00ee, 0x0005, 0x00e6, 0x2071, 0xb8f4, 0x6088, 0xa102, 0x0208,
+	0x618a, 0x00ee, 0x0005, 0x0005, 0x7110, 0x080c, 0x501b, 0x1158,
+	0x6088, 0x8001, 0x0240, 0x608a, 0x1130, 0x0126, 0x2091, 0x8000,
+	0x080c, 0x71e5, 0x012e, 0x8108, 0xa182, 0x00ff, 0x0218, 0xa00e,
+	0x7007, 0x0002, 0x7112, 0x0005, 0x7014, 0x2060, 0x0126, 0x2091,
+	0x8000, 0x603c, 0xa005, 0x0128, 0x8001, 0x603e, 0x1110, 0x080c,
+	0x9fd1, 0x6014, 0xa005, 0x0500, 0x8001, 0x6016, 0x11e8, 0x611c,
+	0xa186, 0x0003, 0x0118, 0xa186, 0x0006, 0x11a0, 0x6010, 0x2068,
+	0x6854, 0xa08a, 0x199a, 0x0270, 0xa082, 0x1999, 0x6856, 0xa08a,
+	0x199a, 0x0210, 0x2001, 0x1999, 0x8003, 0x800b, 0x810b, 0xa108,
+	0x6116, 0x0010, 0x080c, 0x9aa1, 0x012e, 0xac88, 0x0018, 0x7116,
+	0x2001, 0xee00, 0xa102, 0x0220, 0x7017, 0xbe00, 0x7007, 0x0000,
+	0x0005, 0x00e6, 0x2071, 0xb8f4, 0x7027, 0x07d0, 0x7023, 0x0009,
+	0x00ee, 0x0005, 0x2001, 0xb8fd, 0x2003, 0x0000, 0x0005, 0x00e6,
+	0x2071, 0xb8f4, 0x7132, 0x702f, 0x0009, 0x00ee, 0x0005, 0x2011,
+	0xb900, 0x2013, 0x0000, 0x0005, 0x00e6, 0x2071, 0xb8f4, 0x711a,
+	0x721e, 0x700b, 0x0009, 0x00ee, 0x0005, 0x00c6, 0x0026, 0x7054,
+	0x8000, 0x7056, 0x2061, 0xb8a1, 0x6008, 0xa086, 0x0000, 0x0158,
+	0x7068, 0x6032, 0x7064, 0x602e, 0x7060, 0x602a, 0x705c, 0x6026,
+	0x2c10, 0x080c, 0x1648, 0x002e, 0x00ce, 0x0005, 0x0006, 0x0016,
+	0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x080c, 0x696b, 0x00fe, 0x00ee,
+	0x00de, 0x00ce, 0x001e, 0x000e, 0x0005, 0x00e6, 0x2071, 0xb8f4,
+	0x7176, 0x727a, 0x7073, 0x0009, 0x00ee, 0x0005, 0x00e6, 0x0006,
+	0x2071, 0xb8f4, 0x7078, 0xa206, 0x1110, 0x7076, 0x707a, 0x000e,
+	0x00ee, 0x0005, 0x00c6, 0x2061, 0xb975, 0x00ce, 0x0005, 0xa184,
+	0x000f, 0x8003, 0x8003, 0x8003, 0xa080, 0xb975, 0x2060, 0x0005,
+	0x6854, 0xa08a, 0x199a, 0x0210, 0x2001, 0x1999, 0xa005, 0x1150,
+	0x00c6, 0x2061, 0xb975, 0x6014, 0x00ce, 0xa005, 0x1138, 0x2001,
+	0x001e, 0x0020, 0xa08e, 0xffff, 0x1108, 0xa006, 0x8003, 0x800b,
+	0x810b, 0xa108, 0x6116, 0x684c, 0xa08c, 0x00c0, 0xa18e, 0x00c0,
+	0x05e8, 0xd0b4, 0x1138, 0xd0bc, 0x1550, 0x2009, 0x0006, 0x080c,
+	0x6b63, 0x0005, 0xd0fc, 0x0138, 0xa084, 0x0003, 0x0120, 0xa086,
+	0x0003, 0x1904, 0x6b5d, 0x6020, 0xd0d4, 0x0130, 0xc0d4, 0x6022,
+	0x6860, 0x602a, 0x685c, 0x602e, 0x2009, 0xb674, 0x2104, 0xd084,
+	0x0138, 0x87ff, 0x1120, 0x2009, 0x0042, 0x080c, 0x86d3, 0x0005,
+	0x87ff, 0x1120, 0x2009, 0x0043, 0x080c, 0x86d3, 0x0005, 0xd0fc,
+	0x0130, 0xa084, 0x0003, 0x0118, 0xa086, 0x0003, 0x11f0, 0x87ff,
+	0x1120, 0x2009, 0x0042, 0x080c, 0x86d3, 0x0005, 0xd0fc, 0x0160,
+	0xa084, 0x0003, 0xa08e, 0x0002, 0x0148, 0x87ff, 0x1120, 0x2009,
+	0x0041, 0x080c, 0x86d3, 0x0005, 0x0061, 0x0ce8, 0x87ff, 0x1dd8,
+	0x2009, 0x0043, 0x080c, 0x86d3, 0x0cb0, 0x2009, 0x0004, 0x0019,
+	0x0005, 0x2009, 0x0001, 0x00d6, 0x6010, 0xa0ec, 0xf000, 0x0510,
+	0x2068, 0x6952, 0x6800, 0x6012, 0xa186, 0x0001, 0x1188, 0x694c,
+	0xa18c, 0x8100, 0xa18e, 0x8100, 0x1158, 0x00c6, 0x2061, 0xb975,
+	0x6200, 0xd28c, 0x1120, 0x6204, 0x8210, 0x0208, 0x6206, 0x00ce,
+	0x080c, 0x547a, 0x6010, 0xa06d, 0x0076, 0x2039, 0x0000, 0x190c,
+	0x6ae8, 0x007e, 0x00de, 0x0005, 0x0156, 0x00c6, 0x2061, 0xb975,
+	0x6000, 0x81ff, 0x0110, 0xa205, 0x0008, 0xa204, 0x6002, 0x00ce,
+	0x015e, 0x0005, 0x6800, 0xd08c, 0x1138, 0x6808, 0xa005, 0x0120,
+	0x8001, 0x680a, 0xa085, 0x0001, 0x0005, 0x20a9, 0x0010, 0xa006,
+	0x8004, 0x8086, 0x818e, 0x1208, 0xa200, 0x1f04, 0x6ba9, 0x8086,
+	0x818e, 0x0005, 0x0156, 0x20a9, 0x0010, 0xa005, 0x01b8, 0xa11a,
+	0x12a8, 0x8213, 0x818d, 0x0228, 0xa11a, 0x1220, 0x1f04, 0x6bb9,
+	0x0028, 0xa11a, 0x2308, 0x8210, 0x1f04, 0x6bb9, 0x0006, 0x3200,
+	0xa084, 0xefff, 0x2080, 0x000e, 0x015e, 0x0005, 0x0006, 0x3200,
+	0xa085, 0x1000, 0x0cb8, 0x0126, 0x2091, 0x2800, 0x2079, 0xb8e1,
+	0x012e, 0x00d6, 0x2069, 0xb8e1, 0x6803, 0x0005, 0x2069, 0x0004,
+	0x2d04, 0xa085, 0x8001, 0x206a, 0x00de, 0x0005, 0x00c6, 0x6027,
+	0x0001, 0x7804, 0xa084, 0x0007, 0x0002, 0x6bf7, 0x6c18, 0x6c6b,
+	0x6bfd, 0x6c18, 0x6bf7, 0x6bf5, 0x6bf5, 0x080c, 0x151a, 0x080c,
+	0x6a82, 0x080c, 0x71e5, 0x00ce, 0x0005, 0x62c0, 0x82ff, 0x1110,
+	0x00ce, 0x0005, 0x2011, 0x4b23, 0x080c, 0x6a0e, 0x7828, 0xa092,
+	0x00c8, 0x1228, 0x8000, 0x782a, 0x080c, 0x4b65, 0x0c88, 0x080c,
+	0x4b23, 0x7807, 0x0003, 0x7827, 0x0000, 0x782b, 0x0000, 0x0c40,
+	0x080c, 0x6a82, 0x3c00, 0x0006, 0x2011, 0x0209, 0x20e1, 0x4000,
+	0x2214, 0x000e, 0x20e0, 0x82ff, 0x0178, 0x62c0, 0x82ff, 0x1160,
+	0x782b, 0x0000, 0x7824, 0xa065, 0x090c, 0x151a, 0x2009, 0x0013,
+	0x080c, 0x86d3, 0x00ce, 0x0005, 0x3900, 0xa082, 0xba2d, 0x1210,
+	0x080c, 0x83b9, 0x00c6, 0x7824, 0xa065, 0x090c, 0x151a, 0x7804,
+	0xa086, 0x0004, 0x0904, 0x6cab, 0x7828, 0xa092, 0x2710, 0x1230,
+	0x8000, 0x782a, 0x00ce, 0x080c, 0x7de6, 0x0c20, 0x6104, 0xa186,
+	0x0003, 0x1188, 0x00e6, 0x2071, 0xb600, 0x70e0, 0x00ee, 0xd08c,
+	0x0150, 0x00c6, 0x00e6, 0x2061, 0x0100, 0x2071, 0xb600, 0x080c,
+	0x4b7b, 0x00ee, 0x00ce, 0x080c, 0xb500, 0x2009, 0x0014, 0x080c,
+	0x86d3, 0x00ce, 0x0838, 0x2001, 0xb8fd, 0x2003, 0x0000, 0x62c0,
+	0x82ff, 0x1160, 0x782b, 0x0000, 0x7824, 0xa065, 0x090c, 0x151a,
+	0x2009, 0x0013, 0x080c, 0x872c, 0x00ce, 0x0005, 0x00c6, 0x00d6,
+	0x3900, 0xa082, 0xba2d, 0x1210, 0x080c, 0x83b9, 0x7824, 0xa005,
+	0x090c, 0x151a, 0x781c, 0xa06d, 0x090c, 0x151a, 0x6800, 0xc0dc,
+	0x6802, 0x7924, 0x2160, 0x080c, 0x86a4, 0x693c, 0x81ff, 0x090c,
+	0x151a, 0x8109, 0x693e, 0x6854, 0xa015, 0x0110, 0x7a1e, 0x0010,
+	0x7918, 0x791e, 0x7807, 0x0000, 0x7827, 0x0000, 0x00de, 0x00ce,
+	0x080c, 0x71e5, 0x0888, 0x6104, 0xa186, 0x0002, 0x0128, 0xa186,
+	0x0004, 0x0110, 0x0804, 0x6c44, 0x7808, 0xac06, 0x0904, 0x6c44,
+	0x080c, 0x7102, 0x080c, 0x6d45, 0x00ce, 0x080c, 0x71e5, 0x0804,
+	0x6c32, 0x00c6, 0x6027, 0x0002, 0x62c8, 0x60c4, 0xa205, 0x1178,
+	0x793c, 0xa1e5, 0x0000, 0x0130, 0x2009, 0x0049, 0x080c, 0x86d3,
+	0x00ce, 0x0005, 0x2011, 0xb900, 0x2013, 0x0000, 0x0cc8, 0x3908,
+	0xa192, 0xba2d, 0x1210, 0x080c, 0x83b9, 0x793c, 0x81ff, 0x0d90,
+	0x7944, 0xa192, 0x7530, 0x12b8, 0x8108, 0x7946, 0x793c, 0xa188,
+	0x0007, 0x210c, 0xa18e, 0x0006, 0x1138, 0x6014, 0xa084, 0x0184,
+	0xa085, 0x0012, 0x6016, 0x08e0, 0x6014, 0xa084, 0x0184, 0xa085,
+	0x0016, 0x6016, 0x08a8, 0x7848, 0xc085, 0x784a, 0x0888, 0x0006,
+	0x0016, 0x00c6, 0x0126, 0x2091, 0x8000, 0x600f, 0x0000, 0x2c08,
+	0x2061, 0xb8e1, 0x6020, 0x8000, 0x6022, 0x6010, 0xa005, 0x0148,
+	0xa080, 0x0003, 0x2102, 0x6112, 0x012e, 0x00ce, 0x001e, 0x000e,
+	0x0005, 0x6116, 0x6112, 0x0cc0, 0x00d6, 0x2069, 0xb8e1, 0x6000,
+	0xd0d4, 0x0168, 0x6820, 0x8000, 0x6822, 0xa086, 0x0001, 0x1110,
+	0x2c00, 0x681e, 0x6804, 0xa084, 0x0007, 0x0804, 0x71eb, 0xc0d5,
+	0x6002, 0x6818, 0xa005, 0x0158, 0x6056, 0x605b, 0x0000, 0x0006,
+	0x2c00, 0x681a, 0x00de, 0x685a, 0x2069, 0xb8e1, 0x0c18, 0x6056,
+	0x605a, 0x2c00, 0x681a, 0x681e, 0x08e8, 0x0006, 0x0016, 0x00c6,
+	0x0126, 0x2091, 0x8000, 0x600f, 0x0000, 0x2c08, 0x2061, 0xb8e1,
+	0x6020, 0x8000, 0x6022, 0x6008, 0xa005, 0x0148, 0xa080, 0x0003,
+	0x2102, 0x610a, 0x012e, 0x00ce, 0x001e, 0x000e, 0x0005, 0x610e,
+	0x610a, 0x0cc0, 0x00c6, 0x600f, 0x0000, 0x2c08, 0x2061, 0xb8e1,
+	0x6034, 0xa005, 0x0130, 0xa080, 0x0003, 0x2102, 0x6136, 0x00ce,
+	0x0005, 0x613a, 0x6136, 0x0cd8, 0x00f6, 0x00e6, 0x00d6, 0x00c6,
+	0x0076, 0x0066, 0x0056, 0x0036, 0x0026, 0x0016, 0x0006, 0x0126,
+	0xa02e, 0x2071, 0xb8e1, 0x7638, 0x2660, 0x2678, 0x2091, 0x8000,
+	0x8cff, 0x0904, 0x6ded, 0x6018, 0xa080, 0x0028, 0x2004, 0xa206,
+	0x1904, 0x6de8, 0x87ff, 0x0120, 0x6050, 0xa106, 0x1904, 0x6de8,
+	0x703c, 0xac06, 0x1190, 0x0036, 0x2019, 0x0001, 0x080c, 0x806b,
+	0x7033, 0x0000, 0x703f, 0x0000, 0x7043, 0x0000, 0x7047, 0x0000,
+	0x704b, 0x0000, 0x003e, 0x2029, 0x0001, 0x7038, 0xac36, 0x1110,
+	0x660c, 0x763a, 0x7034, 0xac36, 0x1140, 0x2c00, 0xaf36, 0x0118,
+	0x2f00, 0x7036, 0x0010, 0x7037, 0x0000, 0x660c, 0x0066, 0x2c00,
+	0xaf06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0x080c,
+	0x9d16, 0x01c8, 0x6010, 0x2068, 0x601c, 0xa086, 0x0003, 0x1580,
+	0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x0016, 0x0036, 0x0076,
+	0x080c, 0x9f88, 0x080c, 0xb43c, 0x080c, 0x547a, 0x007e, 0x003e,
+	0x001e, 0x080c, 0x9ecd, 0x080c, 0x9ed9, 0x00ce, 0x0804, 0x6d88,
+	0x2c78, 0x600c, 0x2060, 0x0804, 0x6d88, 0x85ff, 0x0120, 0x0036,
+	0x080c, 0x72a2, 0x003e, 0x012e, 0x000e, 0x001e, 0x002e, 0x003e,
+	0x005e, 0x006e, 0x007e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x0005,
+	0x601c, 0xa086, 0x0006, 0x1158, 0x0016, 0x0036, 0x0076, 0x080c,
+	0xb43c, 0x080c, 0xb155, 0x007e, 0x003e, 0x001e, 0x08a0, 0x601c,
+	0xa086, 0x000a, 0x0904, 0x6dd2, 0x0804, 0x6dd0, 0x0006, 0x0066,
+	0x00c6, 0x00d6, 0x00f6, 0x2031, 0x0000, 0x0126, 0x2091, 0x8000,
+	0x2079, 0xb8e1, 0x7838, 0xa065, 0x0568, 0x600c, 0x0006, 0x600f,
+	0x0000, 0x783c, 0xac06, 0x1180, 0x0036, 0x2019, 0x0001, 0x080c,
+	0x806b, 0x7833, 0x0000, 0x783f, 0x0000, 0x7843, 0x0000, 0x7847,
+	0x0000, 0x784b, 0x0000, 0x003e, 0x080c, 0x9d16, 0x0178, 0x6010,
+	0x2068, 0x601c, 0xa086, 0x0003, 0x11b0, 0x6837, 0x0103, 0x6b4a,
+	0x6847, 0x0000, 0x080c, 0x547a, 0x080c, 0x9ecd, 0x080c, 0x9ed9,
+	0x000e, 0x0888, 0x7e3a, 0x7e36, 0x012e, 0x00fe, 0x00de, 0x00ce,
+	0x006e, 0x000e, 0x0005, 0x601c, 0xa086, 0x0006, 0x1118, 0x080c,
+	0xb155, 0x0c60, 0x601c, 0xa086, 0x000a, 0x0d08, 0x08f0, 0x0016,
+	0x0026, 0x0086, 0x2041, 0x0000, 0x0099, 0x080c, 0x6f35, 0x008e,
+	0x002e, 0x001e, 0x0005, 0x00f6, 0x0126, 0x2079, 0xb8e1, 0x2091,
+	0x8000, 0x080c, 0x6fc2, 0x080c, 0x7034, 0x012e, 0x00fe, 0x0005,
+	0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0016, 0x0006, 0x0126,
+	0x2091, 0x8000, 0x2071, 0xb8e1, 0x7614, 0x2660, 0x2678, 0x8cff,
+	0x0904, 0x6f0b, 0x6018, 0xa080, 0x0028, 0x2004, 0xa206, 0x1904,
+	0x6f06, 0x88ff, 0x0120, 0x6050, 0xa106, 0x1904, 0x6f06, 0x7024,
+	0xac06, 0x1538, 0x2069, 0x0100, 0x68c0, 0xa005, 0x01f0, 0x080c,
+	0x6a82, 0x080c, 0x7df3, 0x68c3, 0x0000, 0x080c, 0x82d4, 0x7027,
+	0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0xa384, 0x1000, 0x0120,
+	0x6803, 0x0100, 0x6803, 0x0000, 0x2069, 0x0100, 0x6824, 0xd084,
+	0x0110, 0x6827, 0x0001, 0x003e, 0x0020, 0x6003, 0x0009, 0x630a,
+	0x04e8, 0x7014, 0xac36, 0x1110, 0x660c, 0x7616, 0x7010, 0xac36,
+	0x1140, 0x2c00, 0xaf36, 0x0118, 0x2f00, 0x7012, 0x0010, 0x7013,
+	0x0000, 0x660c, 0x0066, 0x2c00, 0xaf06, 0x0110, 0x7e0e, 0x0008,
+	0x2678, 0x600f, 0x0000, 0x6010, 0x2068, 0x080c, 0x9d16, 0x01b8,
+	0x601c, 0xa086, 0x0003, 0x1540, 0x6837, 0x0103, 0x6b4a, 0x6847,
+	0x0000, 0x0016, 0x0036, 0x0086, 0x080c, 0x9f88, 0x080c, 0xb43c,
+	0x080c, 0x547a, 0x008e, 0x003e, 0x001e, 0x080c, 0x9ecd, 0x080c,
+	0x9ed9, 0x080c, 0x81a5, 0x00ce, 0x0804, 0x6e8f, 0x2c78, 0x600c,
+	0x2060, 0x0804, 0x6e8f, 0x012e, 0x000e, 0x001e, 0x006e, 0x00ce,
+	0x00de, 0x00ee, 0x00fe, 0x0005, 0x601c, 0xa086, 0x0006, 0x1158,
+	0x0016, 0x0036, 0x0086, 0x080c, 0xb43c, 0x080c, 0xb155, 0x008e,
+	0x003e, 0x001e, 0x08e0, 0x601c, 0xa086, 0x0002, 0x1128, 0x6004,
+	0xa086, 0x0085, 0x0908, 0x0898, 0x601c, 0xa086, 0x0005, 0x1978,
+	0x6004, 0xa086, 0x0085, 0x0d20, 0x0850, 0x00c6, 0x0006, 0x0126,
+	0x2091, 0x8000, 0xa280, 0xb735, 0x2004, 0xa065, 0x0904, 0x6fbe,
+	0x00f6, 0x00e6, 0x00d6, 0x0066, 0x2071, 0xb8e1, 0x6654, 0x7018,
+	0xac06, 0x1108, 0x761a, 0x701c, 0xac06, 0x1130, 0x86ff, 0x1118,
+	0x7018, 0x701e, 0x0008, 0x761e, 0x6058, 0xa07d, 0x0108, 0x7e56,
+	0xa6ed, 0x0000, 0x0110, 0x2f00, 0x685a, 0x6057, 0x0000, 0x605b,
+	0x0000, 0x6000, 0xc0d4, 0xc0dc, 0x6002, 0x080c, 0x4f46, 0x0904,
+	0x6fba, 0x7624, 0x86ff, 0x05e8, 0xa680, 0x0004, 0x2004, 0xad06,
+	0x15c0, 0x00d6, 0x2069, 0x0100, 0x68c0, 0xa005, 0x0548, 0x080c,
+	0x6a82, 0x080c, 0x7df3, 0x68c3, 0x0000, 0x080c, 0x82d4, 0x7027,
+	0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0xa384, 0x1000, 0x0120,
+	0x6803, 0x0100, 0x6803, 0x0000, 0x2069, 0x0100, 0x6824, 0xd084,
+	0x0110, 0x6827, 0x0001, 0x003e, 0x00de, 0x00c6, 0x603c, 0xa005,
+	0x0110, 0x8001, 0x603e, 0x2660, 0x080c, 0x9ed9, 0x00ce, 0x0048,
+	0x00de, 0x00c6, 0x2660, 0x6003, 0x0009, 0x630a, 0x00ce, 0x0804,
+	0x6f65, 0x8dff, 0x0158, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000,
+	0x080c, 0x9f88, 0x080c, 0xb43c, 0x080c, 0x547a, 0x080c, 0x81a5,
+	0x0804, 0x6f65, 0x006e, 0x00de, 0x00ee, 0x00fe, 0x012e, 0x000e,
+	0x00ce, 0x0005, 0x0006, 0x0066, 0x00c6, 0x00d6, 0x2031, 0x0000,
+	0x7814, 0xa065, 0x0904, 0x7014, 0x600c, 0x0006, 0x600f, 0x0000,
+	0x7824, 0xac06, 0x1540, 0x2069, 0x0100, 0x68c0, 0xa005, 0x01f0,
+	0x080c, 0x6a82, 0x080c, 0x7df3, 0x68c3, 0x0000, 0x080c, 0x82d4,
+	0x7827, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0xa384, 0x1000,
+	0x0120, 0x6803, 0x0100, 0x6803, 0x0000, 0x2069, 0x0100, 0x6824,
+	0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x0028, 0x6003, 0x0009,
+	0x630a, 0x2c30, 0x00b0, 0x6010, 0x2068, 0x080c, 0x9d16, 0x0168,
+	0x601c, 0xa086, 0x0003, 0x11b8, 0x6837, 0x0103, 0x6b4a, 0x6847,
+	0x0000, 0x080c, 0x547a, 0x080c, 0x9ecd, 0x080c, 0x9ed9, 0x080c,
+	0x81a5, 0x000e, 0x0804, 0x6fc9, 0x7e16, 0x7e12, 0x00de, 0x00ce,
+	0x006e, 0x000e, 0x0005, 0x601c, 0xa086, 0x0006, 0x1118, 0x080c,
+	0xb155, 0x0c58, 0x601c, 0xa086, 0x0002, 0x1128, 0x6004, 0xa086,
+	0x0085, 0x09d0, 0x0c10, 0x601c, 0xa086, 0x0005, 0x19f0, 0x6004,
+	0xa086, 0x0085, 0x0d60, 0x08c8, 0x0006, 0x0066, 0x00c6, 0x00d6,
+	0x7818, 0xa065, 0x0904, 0x709a, 0x6054, 0x0006, 0x6057, 0x0000,
+	0x605b, 0x0000, 0x6000, 0xc0d4, 0xc0dc, 0x6002, 0x080c, 0x4f46,
+	0x0904, 0x7097, 0x7e24, 0x86ff, 0x05e8, 0xa680, 0x0004, 0x2004,
+	0xad06, 0x15c0, 0x00d6, 0x2069, 0x0100, 0x68c0, 0xa005, 0x0548,
+	0x080c, 0x6a82, 0x080c, 0x7df3, 0x68c3, 0x0000, 0x080c, 0x82d4,
+	0x7827, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0xa384, 0x1000,
+	0x0120, 0x6803, 0x0100, 0x6803, 0x0000, 0x2069, 0x0100, 0x6824,
+	0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x00de, 0x00c6, 0x603c,
+	0xa005, 0x0110, 0x8001, 0x603e, 0x2660, 0x080c, 0x9ed9, 0x00ce,
+	0x0048, 0x00de, 0x00c6, 0x2660, 0x6003, 0x0009, 0x630a, 0x00ce,
+	0x0804, 0x7046, 0x8dff, 0x0138, 0x6837, 0x0103, 0x6b4a, 0x6847,
+	0x0000, 0x080c, 0x547a, 0x080c, 0x81a5, 0x0804, 0x7046, 0x000e,
+	0x0804, 0x7039, 0x781e, 0x781a, 0x00de, 0x00ce, 0x006e, 0x000e,
+	0x0005, 0x00e6, 0x00d6, 0x0066, 0x6000, 0xd0dc, 0x01a0, 0x604c,
+	0xa06d, 0x0188, 0x6848, 0xa606, 0x1170, 0x2071, 0xb8e1, 0x7024,
+	0xa035, 0x0148, 0xa080, 0x0004, 0x2004, 0xad06, 0x1120, 0x6000,
+	0xc0dc, 0x6002, 0x0021, 0x006e, 0x00de, 0x00ee, 0x0005, 0x00f6,
+	0x2079, 0x0100, 0x78c0, 0xa005, 0x1138, 0x00c6, 0x2660, 0x6003,
+	0x0009, 0x630a, 0x00ce, 0x04a0, 0x080c, 0x7df3, 0x78c3, 0x0000,
+	0x080c, 0x82d4, 0x7027, 0x0000, 0x0036, 0x2079, 0x0140, 0x7b04,
+	0xa384, 0x1000, 0x0120, 0x7803, 0x0100, 0x7803, 0x0000, 0x2079,
+	0x0100, 0x7824, 0xd084, 0x0110, 0x7827, 0x0001, 0x080c, 0x82d4,
+	0x003e, 0x080c, 0x4f46, 0x00c6, 0x603c, 0xa005, 0x0110, 0x8001,
+	0x603e, 0x2660, 0x080c, 0x86a4, 0x00ce, 0x6837, 0x0103, 0x6b4a,
+	0x6847, 0x0000, 0x080c, 0x9f88, 0x080c, 0x547a, 0x080c, 0x81a5,
+	0x00fe, 0x0005, 0x00e6, 0x00c6, 0x2071, 0xb8e1, 0x7004, 0xa084,
+	0x0007, 0x0002, 0x7114, 0x7117, 0x712d, 0x7146, 0x7183, 0x7114,
+	0x7112, 0x7112, 0x080c, 0x151a, 0x00ce, 0x00ee, 0x0005, 0x7024,
+	0xa065, 0x0148, 0x7020, 0x8001, 0x7022, 0x600c, 0xa015, 0x0150,
+	0x7216, 0x600f, 0x0000, 0x7007, 0x0000, 0x7027, 0x0000, 0x00ce,
+	0x00ee, 0x0005, 0x7216, 0x7212, 0x0cb0, 0x6018, 0x2060, 0x080c,
+	0x4f46, 0x6000, 0xc0dc, 0x6002, 0x7020, 0x8001, 0x7022, 0x0120,
+	0x6054, 0xa015, 0x0140, 0x721e, 0x7007, 0x0000, 0x7027, 0x0000,
+	0x00ce, 0x00ee, 0x0005, 0x7218, 0x721e, 0x0cb0, 0x7024, 0xa065,
+	0x05b8, 0x700c, 0xac06, 0x1160, 0x080c, 0x81a5, 0x600c, 0xa015,
+	0x0120, 0x720e, 0x600f, 0x0000, 0x0448, 0x720e, 0x720a, 0x0430,
+	0x7014, 0xac06, 0x1160, 0x080c, 0x81a5, 0x600c, 0xa015, 0x0120,
+	0x7216, 0x600f, 0x0000, 0x00d0, 0x7216, 0x7212, 0x00b8, 0x601c,
+	0xa086, 0x0003, 0x1198, 0x6018, 0x2060, 0x080c, 0x4f46, 0x6000,
+	0xc0dc, 0x6002, 0x080c, 0x81a5, 0x701c, 0xa065, 0x0138, 0x6054,
+	0xa015, 0x0110, 0x721e, 0x0010, 0x7218, 0x721e, 0x7027, 0x0000,
+	0x00ce, 0x00ee, 0x0005, 0x7024, 0xa065, 0x0140, 0x080c, 0x81a5,
+	0x600c, 0xa015, 0x0150, 0x720e, 0x600f, 0x0000, 0x080c, 0x82d4,
+	0x7027, 0x0000, 0x00ce, 0x00ee, 0x0005, 0x720e, 0x720a, 0x0cb0,
+	0x00d6, 0x2069, 0xb8e1, 0x6830, 0xa084, 0x0003, 0x0002, 0x71a5,
+	0x71a7, 0x71cb, 0x71a3, 0x080c, 0x151a, 0x00de, 0x0005, 0x00c6,
+	0x6840, 0xa086, 0x0001, 0x01b8, 0x683c, 0xa065, 0x0130, 0x600c,
+	0xa015, 0x0170, 0x6a3a, 0x600f, 0x0000, 0x6833, 0x0000, 0x683f,
+	0x0000, 0x2011, 0xb900, 0x2013, 0x0000, 0x00ce, 0x00de, 0x0005,
+	0x683a, 0x6836, 0x0c90, 0x6843, 0x0000, 0x6838, 0xa065, 0x0d68,
+	0x6003, 0x0003, 0x0c50, 0x00c6, 0x6843, 0x0000, 0x6847, 0x0000,
+	0x684b, 0x0000, 0x683c, 0xa065, 0x0168, 0x600c, 0xa015, 0x0130,
+	0x6a3a, 0x600f, 0x0000, 0x683f, 0x0000, 0x0020, 0x683f, 0x0000,
+	0x683a, 0x6836, 0x00ce, 0x00de, 0x0005, 0x00d6, 0x2069, 0xb8e1,
+	0x6804, 0xa084, 0x0007, 0x0002, 0x71f6, 0x7292, 0x7292, 0x7292,
+	0x7292, 0x7294, 0x71f4, 0x71f4, 0x080c, 0x151a, 0x6820, 0xa005,
+	0x1110, 0x00de, 0x0005, 0x00c6, 0x680c, 0xa065, 0x0150, 0x6807,
+	0x0004, 0x6826, 0x682b, 0x0000, 0x080c, 0x72e4, 0x00ce, 0x00de,
+	0x0005, 0x6814, 0xa065, 0x0150, 0x6807, 0x0001, 0x6826, 0x682b,
+	0x0000, 0x080c, 0x72e4, 0x00ce, 0x00de, 0x0005, 0x00e6, 0x0036,
+	0x6a1c, 0xa2f5, 0x0000, 0x0904, 0x728e, 0x704c, 0xa00d, 0x0118,
+	0x7088, 0xa005, 0x01a0, 0x7054, 0xa075, 0x0120, 0xa20e, 0x0904,
+	0x728e, 0x0028, 0x6818, 0xa20e, 0x0904, 0x728e, 0x2070, 0x704c,
+	0xa00d, 0x0d88, 0x7088, 0xa005, 0x1d70, 0x2e00, 0x681e, 0x733c,
+	0x7038, 0xa302, 0x1e40, 0x080c, 0x867b, 0x0904, 0x728e, 0x8318,
+	0x733e, 0x6112, 0x2e10, 0x621a, 0xa180, 0x0014, 0x2004, 0xa084,
+	0x00ff, 0x605a, 0xa180, 0x0014, 0x2003, 0x0000, 0xa180, 0x0015,
+	0x2004, 0xa08a, 0x199a, 0x0210, 0x2001, 0x1999, 0x8003, 0x801b,
+	0x831b, 0xa318, 0x6316, 0x003e, 0x00f6, 0x2c78, 0x71a0, 0x2001,
+	0xb635, 0x2004, 0xd0ac, 0x1110, 0xd1bc, 0x0150, 0x7100, 0xd1f4,
+	0x0120, 0x7114, 0xa18c, 0x00ff, 0x0040, 0x2009, 0x0000, 0x0028,
+	0xa1e0, 0x2df9, 0x2c0d, 0xa18c, 0x00ff, 0x2061, 0x0100, 0x619a,
+	0x080c, 0x7914, 0x7300, 0xc3dd, 0x7302, 0x6807, 0x0002, 0x2f18,
+	0x6b26, 0x682b, 0x0000, 0x781f, 0x0003, 0x7803, 0x0001, 0x7807,
+	0x0040, 0x00fe, 0x00ee, 0x00ce, 0x00de, 0x0005, 0x003e, 0x00ee,
+	0x00ce, 0x0cd0, 0x00de, 0x0005, 0x00c6, 0x680c, 0xa065, 0x0138,
+	0x6807, 0x0004, 0x6826, 0x682b, 0x0000, 0x080c, 0x72e4, 0x00ce,
+	0x00de, 0x0005, 0x00f6, 0x00d6, 0x2069, 0xb8e1, 0x6830, 0xa086,
+	0x0000, 0x11d0, 0x2001, 0xb60c, 0x200c, 0xd1bc, 0x1560, 0x6838,
+	0xa07d, 0x0190, 0x6833, 0x0001, 0x683e, 0x6847, 0x0000, 0x684b,
+	0x0000, 0x0126, 0x00f6, 0x2091, 0x2400, 0x002e, 0x080c, 0x203d,
+	0x1130, 0x012e, 0x080c, 0x7c5d, 0x00de, 0x00fe, 0x0005, 0x012e,
+	0xe000, 0x6843, 0x0000, 0x7803, 0x0002, 0x780c, 0xa015, 0x0140,
+	0x6a3a, 0x780f, 0x0000, 0x6833, 0x0000, 0x683f, 0x0000, 0x0c60,
+	0x683a, 0x6836, 0x0cc0, 0xc1bc, 0x2102, 0x0066, 0x2031, 0x0001,
+	0x080c, 0x5bc3, 0x006e, 0x0858, 0x601c, 0xa084, 0x000f, 0x000b,
+	0x0005, 0x72f2, 0x72f7, 0x77b5, 0x78d1, 0x72f7, 0x77b5, 0x78d1,
+	0x72f2, 0x72f7, 0x080c, 0x7102, 0x080c, 0x71e5, 0x0005, 0x0156,
+	0x0136, 0x0146, 0x00c6, 0x00f6, 0x6004, 0xa08a, 0x0080, 0x1a0c,
+	0x151a, 0x6118, 0x2178, 0x79a0, 0x2011, 0xb635, 0x2214, 0xd2ac,
+	0x1110, 0xd1bc, 0x0150, 0x7900, 0xd1f4, 0x0120, 0x7914, 0xa18c,
+	0x00ff, 0x0040, 0x2009, 0x0000, 0x0028, 0xa1f8, 0x2df9, 0x2f0d,
+	0xa18c, 0x00ff, 0x2c78, 0x2061, 0x0100, 0x619a, 0xa08a, 0x0040,
+	0x1a04, 0x736b, 0x0033, 0x00fe, 0x00ce, 0x014e, 0x013e, 0x015e,
+	0x0005, 0x741a, 0x7465, 0x7492, 0x755f, 0x758d, 0x7595, 0x75bb,
+	0x75cc, 0x75dd, 0x75e5, 0x75fb, 0x75e5, 0x765c, 0x75cc, 0x767d,
+	0x7685, 0x75dd, 0x7685, 0x7696, 0x7369, 0x7369, 0x7369, 0x7369,
+	0x7369, 0x7369, 0x7369, 0x7369, 0x7369, 0x7369, 0x7369, 0x7efe,
+	0x7f23, 0x7f46, 0x7f69, 0x7f8a, 0x75bb, 0x7369, 0x75bb, 0x75e5,
+	0x7369, 0x7492, 0x755f, 0x7369, 0x83d6, 0x75e5, 0x7369, 0x83f6,
+	0x75e5, 0x7369, 0x75dd, 0x7413, 0x737e, 0x7369, 0x841b, 0x8490,
+	0x8567, 0x7369, 0x8578, 0x75b6, 0x8594, 0x7369, 0x7f9f, 0x85ef,
+	0x7369, 0x080c, 0x151a, 0x2100, 0x0033, 0x00fe, 0x00ce, 0x014e,
+	0x013e, 0x015e, 0x0005, 0x737c, 0x737c, 0x737c, 0x73b2, 0x73d0,
+	0x73e6, 0x737c, 0x737c, 0x737c, 0x080c, 0x151a, 0x00d6, 0x20a1,
+	0x020b, 0x080c, 0x76b3, 0x7810, 0x2068, 0x20a3, 0x2414, 0x20a3,
+	0x0018, 0x20a3, 0x0800, 0x683c, 0x20a2, 0x20a3, 0x0000, 0x20a3,
+	0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x6850, 0x20a2, 0x6854,
+	0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0018, 0x080c,
+	0x7de0, 0x00de, 0x0005, 0x00d6, 0x7818, 0x2068, 0x68a0, 0x2069,
+	0xb600, 0x6ad4, 0xd2ac, 0x1110, 0xd0bc, 0x0110, 0xa085, 0x0001,
+	0x00de, 0x0005, 0x00d6, 0x20a1, 0x020b, 0x080c, 0x76b3, 0x20a3,
+	0x0500, 0x20a3, 0x0000, 0x7810, 0xa0e8, 0x000f, 0x6808, 0x20a2,
+	0x680c, 0x20a2, 0x6810, 0x20a2, 0x6814, 0x20a2, 0x6818, 0x20a2,
+	0x681c, 0x20a2, 0x60c3, 0x0010, 0x080c, 0x7de0, 0x00de, 0x0005,
+	0x0156, 0x0146, 0x20a1, 0x020b, 0x080c, 0x76b3, 0x20a3, 0x7800,
+	0x20a3, 0x0000, 0x7808, 0x8007, 0x20a2, 0x20a3, 0x0000, 0x60c3,
+	0x0008, 0x080c, 0x7de0, 0x014e, 0x015e, 0x0005, 0x0156, 0x0146,
+	0x20a1, 0x020b, 0x080c, 0x774f, 0x20a3, 0x0200, 0x20a3, 0x0000,
+	0x20a3, 0xdf10, 0x20a3, 0x0034, 0x2099, 0xb605, 0x20a9, 0x0004,
+	0x53a6, 0x2099, 0xb601, 0x20a9, 0x0004, 0x53a6, 0x2099, 0xb8c7,
+	0x20a9, 0x001a, 0x3304, 0x8007, 0x20a2, 0x9398, 0x1f04, 0x7402,
+	0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x004c, 0x080c, 0x7de0,
+	0x014e, 0x015e, 0x0005, 0x2001, 0xb615, 0x2004, 0x609a, 0x080c,
+	0x7de0, 0x0005, 0x20a1, 0x020b, 0x080c, 0x76b3, 0x20a3, 0x5200,
+	0x20a3, 0x0000, 0x00d6, 0x2069, 0xb652, 0x6804, 0xd084, 0x0150,
+	0x6828, 0x20a3, 0x0000, 0x0016, 0x080c, 0x2866, 0x21a2, 0x001e,
+	0x00de, 0x0028, 0x00de, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a9,
+	0x0004, 0x2099, 0xb605, 0x53a6, 0x20a9, 0x0004, 0x2099, 0xb601,
+	0x53a6, 0x2001, 0xb635, 0x2004, 0xd0ac, 0x1138, 0x7818, 0xa080,
+	0x0028, 0x2004, 0xa082, 0x007f, 0x0238, 0x2001, 0xb61c, 0x20a6,
+	0x2001, 0xb61d, 0x20a6, 0x0040, 0x20a3, 0x0000, 0x2001, 0xb615,
+	0x2004, 0xa084, 0x00ff, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000,
+	0x60c3, 0x001c, 0x080c, 0x7de0, 0x0005, 0x20a1, 0x020b, 0x080c,
+	0x76b3, 0x20a3, 0x0500, 0x20a3, 0x0000, 0x2001, 0xb635, 0x2004,
+	0xd0ac, 0x1138, 0x7818, 0xa080, 0x0028, 0x2004, 0xa082, 0x007f,
+	0x0238, 0x2001, 0xb61c, 0x20a6, 0x2001, 0xb61d, 0x20a6, 0x0040,
+	0x20a3, 0x0000, 0x2001, 0xb615, 0x2004, 0xa084, 0x00ff, 0x20a2,
+	0x20a9, 0x0004, 0x2099, 0xb605, 0x53a6, 0x60c3, 0x0010, 0x080c,
+	0x7de0, 0x0005, 0x20a1, 0x020b, 0x080c, 0x76b3, 0x00c6, 0x7818,
+	0x2060, 0x2001, 0x0000, 0x080c, 0x5385, 0x00ce, 0x7818, 0xa080,
+	0x0028, 0x2004, 0xa086, 0x007e, 0x1130, 0x20a3, 0x0400, 0x620c,
+	0xc2b4, 0x620e, 0x0010, 0x20a3, 0x0300, 0x20a3, 0x0000, 0x7818,
+	0xa080, 0x0028, 0x2004, 0xa086, 0x007e, 0x1904, 0x7521, 0x2001,
+	0xb635, 0x2004, 0xd0a4, 0x01c8, 0x2099, 0xb88e, 0x33a6, 0x9398,
+	0x20a3, 0x0000, 0x9398, 0x3304, 0xa084, 0x2000, 0x20a2, 0x9398,
+	0x33a6, 0x9398, 0x20a3, 0x0000, 0x9398, 0x2001, 0x2710, 0x20a2,
+	0x9398, 0x33a6, 0x9398, 0x33a6, 0x00d0, 0x2099, 0xb88e, 0x33a6,
+	0x9398, 0x33a6, 0x9398, 0x3304, 0x080c, 0x5b41, 0x1118, 0xa084,
+	0x37ff, 0x0010, 0xa084, 0x3fff, 0x20a2, 0x9398, 0x33a6, 0x20a3,
+	0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a9,
+	0x0004, 0x2099, 0xb605, 0x53a6, 0x20a9, 0x0004, 0x2099, 0xb601,
+	0x53a6, 0x20a9, 0x0008, 0x20a3, 0x0000, 0x1f04, 0x74fb, 0x20a9,
+	0x0008, 0x20a3, 0x0000, 0x1f04, 0x7501, 0x2099, 0xb896, 0x3304,
+	0xc0dd, 0x20a2, 0x2001, 0xb672, 0x2004, 0xd0e4, 0x0158, 0x20a3,
+	0x0000, 0x20a3, 0x0000, 0x9398, 0x9398, 0x9398, 0x33a6, 0x20a9,
+	0x0004, 0x0010, 0x20a9, 0x0007, 0x20a3, 0x0000, 0x1f04, 0x751c,
+	0x0468, 0x2001, 0xb635, 0x2004, 0xd0a4, 0x0140, 0x2001, 0xb88f,
+	0x2004, 0x60e3, 0x0000, 0x080c, 0x28a7, 0x60e2, 0x2099, 0xb88e,
+	0x20a9, 0x0008, 0x53a6, 0x20a9, 0x0004, 0x2099, 0xb605, 0x53a6,
+	0x20a9, 0x0004, 0x2099, 0xb601, 0x53a6, 0x20a9, 0x0008, 0x20a3,
+	0x0000, 0x1f04, 0x753f, 0x20a9, 0x0008, 0x20a3, 0x0000, 0x1f04,
+	0x7545, 0x2099, 0xb896, 0x20a9, 0x0008, 0x53a6, 0x20a9, 0x0008,
+	0x20a3, 0x0000, 0x1f04, 0x7550, 0x20a9, 0x000a, 0x20a3, 0x0000,
+	0x1f04, 0x7556, 0x60c3, 0x0074, 0x080c, 0x7de0, 0x0005, 0x20a1,
+	0x020b, 0x080c, 0x76b3, 0x20a3, 0x2010, 0x20a3, 0x0014, 0x20a3,
+	0x0800, 0x20a3, 0x2000, 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2,
+	0x20a2, 0x00f6, 0x2079, 0xb652, 0x7904, 0x00fe, 0xd1ac, 0x1110,
+	0xa085, 0x0020, 0xd1a4, 0x0110, 0xa085, 0x0010, 0xa085, 0x0002,
+	0x00d6, 0x0804, 0x763e, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000,
+	0x60c3, 0x0014, 0x080c, 0x7de0, 0x0005, 0x20a1, 0x020b, 0x080c,
+	0x76b3, 0x20a3, 0x5000, 0x0804, 0x74ad, 0x20a1, 0x020b, 0x080c,
+	0x76b3, 0x20a3, 0x2110, 0x20a3, 0x0014, 0x20a3, 0x0000, 0x20a3,
 	0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3,
-	0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3,
-	0x0014, 0x080c, 0x7d67, 0x0005, 0x20a1, 0x020b, 0x080c, 0x76d5,
-	0x0020, 0x20a1, 0x020b, 0x080c, 0x76dd, 0x20a3, 0x0200, 0x20a3,
-	0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0004, 0x080c,
-	0x7d67, 0x0005, 0x20a1, 0x020b, 0x080c, 0x76dd, 0x20a3, 0x0100,
-	0x20a3, 0x0000, 0x20a3, 0x0003, 0x20a3, 0x2a00, 0x60c3, 0x0008,
-	0x080c, 0x7d67, 0x0005, 0x20a1, 0x020b, 0x080c, 0x76dd, 0x20a3,
-	0x0200, 0x0804, 0x743b, 0x20a1, 0x020b, 0x080c, 0x76dd, 0x20a3,
-	0x0100, 0x20a3, 0x0000, 0x7828, 0xa005, 0x0110, 0x20a2, 0x0010,
-	0x20a3, 0x0003, 0x7810, 0x20a2, 0x60c3, 0x0008, 0x080c, 0x7d67,
-	0x0005, 0x00d6, 0x20a1, 0x020b, 0x080c, 0x76dd, 0x20a3, 0x0210,
-	0x20a3, 0x0014, 0x20a3, 0x0800, 0x7818, 0x2068, 0x6894, 0xa086,
-	0x0014, 0x1198, 0x699c, 0xa184, 0x0030, 0x0190, 0x6998, 0xa184,
-	0xc000, 0x1140, 0xd1ec, 0x0118, 0x20a3, 0x2100, 0x0058, 0x20a3,
-	0x0100, 0x0040, 0x20a3, 0x0400, 0x0028, 0x20a3, 0x0700, 0x0010,
-	0x700f, 0x0800, 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a2,
-	0x00f6, 0x2079, 0xb552, 0x7904, 0x00fe, 0xd1ac, 0x1110, 0xa085,
-	0x0020, 0xd1a4, 0x0110, 0xa085, 0x0010, 0x2009, 0xb574, 0x210c,
-	0xd184, 0x1110, 0xa085, 0x0002, 0x0026, 0x2009, 0xb572, 0x210c,
-	0xd1e4, 0x0130, 0xc0c5, 0xa094, 0x0030, 0xa296, 0x0010, 0x0140,
-	0xd1ec, 0x0130, 0xa094, 0x0030, 0xa296, 0x0010, 0x0108, 0xc0bd,
-	0x002e, 0x20a2, 0x20a2, 0x20a2, 0x60c3, 0x0014, 0x080c, 0x7d67,
-	0x00de, 0x0005, 0x20a1, 0x020b, 0x080c, 0x76dd, 0x20a3, 0x0210,
-	0x20a3, 0x0014, 0x20a3, 0x0000, 0x20a3, 0x0100, 0x20a3, 0x0000,
+	0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3,
+	0x0000, 0x60c3, 0x0014, 0x080c, 0x7de0, 0x0005, 0x20a1, 0x020b,
+	0x080c, 0x7747, 0x0020, 0x20a1, 0x020b, 0x080c, 0x774f, 0x20a3,
+	0x0200, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3,
+	0x0004, 0x080c, 0x7de0, 0x0005, 0x20a1, 0x020b, 0x080c, 0x774f,
+	0x20a3, 0x0100, 0x20a3, 0x0000, 0x20a3, 0x0003, 0x20a3, 0x2a00,
+	0x60c3, 0x0008, 0x080c, 0x7de0, 0x0005, 0x20a1, 0x020b, 0x080c,
+	0x774f, 0x20a3, 0x0200, 0x0804, 0x74ad, 0x20a1, 0x020b, 0x080c,
+	0x774f, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x7828, 0xa005, 0x0110,
+	0x20a2, 0x0010, 0x20a3, 0x0003, 0x7810, 0x20a2, 0x60c3, 0x0008,
+	0x080c, 0x7de0, 0x0005, 0x00d6, 0x20a1, 0x020b, 0x080c, 0x774f,
+	0x20a3, 0x0210, 0x20a3, 0x0014, 0x20a3, 0x0800, 0x7818, 0x2068,
+	0x6894, 0xa086, 0x0014, 0x1198, 0x699c, 0xa184, 0x0030, 0x0190,
+	0x6998, 0xa184, 0xc000, 0x1140, 0xd1ec, 0x0118, 0x20a3, 0x2100,
+	0x0058, 0x20a3, 0x0100, 0x0040, 0x20a3, 0x0400, 0x0028, 0x20a3,
+	0x0700, 0x0010, 0x700f, 0x0800, 0xa006, 0x20a2, 0x20a2, 0x20a2,
+	0x20a2, 0x20a2, 0x00f6, 0x2079, 0xb652, 0x7904, 0x00fe, 0xd1ac,
+	0x1110, 0xa085, 0x0020, 0xd1a4, 0x0110, 0xa085, 0x0010, 0x2009,
+	0xb674, 0x210c, 0xd184, 0x1110, 0xa085, 0x0002, 0x0026, 0x2009,
+	0xb672, 0x210c, 0xd1e4, 0x0130, 0xc0c5, 0xa094, 0x0030, 0xa296,
+	0x0010, 0x0140, 0xd1ec, 0x0130, 0xa094, 0x0030, 0xa296, 0x0010,
+	0x0108, 0xc0bd, 0x002e, 0x20a2, 0x20a2, 0x20a2, 0x60c3, 0x0014,
+	0x080c, 0x7de0, 0x00de, 0x0005, 0x20a1, 0x020b, 0x080c, 0x774f,
+	0x20a3, 0x0210, 0x20a3, 0x0014, 0x20a3, 0x0000, 0x20a3, 0x0100,
+	0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000,
 	0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000,
-	0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014,
-	0x080c, 0x7d67, 0x0005, 0x20a1, 0x020b, 0x080c, 0x76dd, 0x20a3,
-	0x0200, 0x0804, 0x73ae, 0x20a1, 0x020b, 0x080c, 0x76dd, 0x20a3,
-	0x0100, 0x20a3, 0x0000, 0x20a3, 0x0003, 0x20a3, 0x2a00, 0x60c3,
-	0x0008, 0x080c, 0x7d67, 0x0005, 0x20e1, 0x9080, 0x20e1, 0x4000,
-	0x20a1, 0x020b, 0x080c, 0x76dd, 0x20a3, 0x0100, 0x20a3, 0x0000,
-	0x20a3, 0x000b, 0x20a3, 0x0000, 0x60c3, 0x0008, 0x080c, 0x7d67,
-	0x0005, 0x0026, 0x0036, 0x0046, 0x2019, 0x3200, 0x2021, 0x0800,
-	0x0038, 0x0026, 0x0036, 0x0046, 0x2019, 0x2200, 0x2021, 0x0100,
-	0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2014,
-	0xa286, 0x007e, 0x11a0, 0xa385, 0x00ff, 0x20a2, 0x20a3, 0xfffe,
-	0x20a3, 0x0000, 0x2011, 0xb515, 0x2214, 0x2001, 0xb79e, 0x2004,
-	0xa005, 0x0118, 0x2011, 0xb51d, 0x2214, 0x22a2, 0x04d0, 0xa286,
-	0x007f, 0x1138, 0x00d6, 0xa385, 0x00ff, 0x20a2, 0x20a3, 0xfffd,
-	0x00c8, 0x2001, 0xb535, 0x2004, 0xd0ac, 0x1110, 0xd2bc, 0x01c8,
-	0xa286, 0x0080, 0x00d6, 0x1130, 0xa385, 0x00ff, 0x20a2, 0x20a3,
-	0xfffc, 0x0040, 0xa2e8, 0xb635, 0x2d6c, 0x6810, 0xa305, 0x20a2,
-	0x6814, 0x20a2, 0x2069, 0xb51c, 0x2da6, 0x8d68, 0x2da6, 0x00de,
-	0x0080, 0x00d6, 0xa2e8, 0xb635, 0x2d6c, 0x6810, 0xa305, 0x20a2,
-	0x6814, 0x20a2, 0x00de, 0x20a3, 0x0000, 0x2011, 0xb515, 0x2214,
-	0x22a2, 0xa485, 0x0029, 0x20a2, 0x004e, 0x003e, 0x20a3, 0x0000,
-	0x080c, 0x7d56, 0x22a2, 0x20a3, 0x0000, 0x2fa2, 0x20a3, 0xffff,
-	0x20a3, 0x0000, 0x20a3, 0x0000, 0x002e, 0x0005, 0x0026, 0x20e1,
-	0x9080, 0x20e1, 0x4000, 0x20a3, 0x02ff, 0x2011, 0xfffc, 0x22a2,
-	0x00d6, 0x2069, 0xb51c, 0x2da6, 0x8d68, 0x2da6, 0x00de, 0x20a3,
-	0x2029, 0x20a3, 0x0000, 0x08e0, 0x20a3, 0x0100, 0x20a3, 0x0000,
-	0x20a3, 0xfc02, 0x20a3, 0x0000, 0x0005, 0x0026, 0x0036, 0x0046,
-	0x2019, 0x3300, 0x2021, 0x0800, 0x0038, 0x0026, 0x0036, 0x0046,
-	0x2019, 0x2300, 0x2021, 0x0100, 0x20e1, 0x9080, 0x20e1, 0x4000,
-	0x7818, 0xa080, 0x0028, 0x2004, 0x2011, 0xb535, 0x2214, 0xd2ac,
-	0x1118, 0xa092, 0x007e, 0x02d8, 0x00d6, 0xa0e8, 0xb635, 0x2d6c,
-	0x6810, 0xa305, 0x20a2, 0x6814, 0x20a2, 0x6810, 0xa005, 0x1140,
-	0x6814, 0xa005, 0x1128, 0x20a3, 0x00ff, 0x20a3, 0xfffe, 0x0028,
-	0x2069, 0xb51c, 0x2da6, 0x8d68, 0x2da6, 0x00de, 0x0080, 0x00d6,
-	0xa0e8, 0xb635, 0x2d6c, 0x6810, 0xa305, 0x20a2, 0x6814, 0x20a2,
-	0x00de, 0x20a3, 0x0000, 0x2011, 0xb515, 0x2214, 0x22a2, 0xa485,
-	0x0098, 0x20a2, 0x20a3, 0x0000, 0x004e, 0x003e, 0x080c, 0x7d56,
-	0x22a2, 0x20a3, 0x0000, 0x7a08, 0x22a2, 0x2fa2, 0x20a3, 0x0000,
-	0x20a3, 0x0000, 0x002e, 0x0005, 0x080c, 0x7d56, 0x22a2, 0x20a3,
-	0x0000, 0x7a08, 0x22a2, 0x7810, 0x20a2, 0x20a3, 0x0000, 0x20a3,
-	0x0000, 0x002e, 0x0005, 0x00c6, 0x00f6, 0x6004, 0xa08a, 0x0085,
-	0x0a0c, 0x1515, 0xa08a, 0x008c, 0x1a0c, 0x1515, 0x6118, 0x2178,
-	0x79a0, 0x2011, 0xb535, 0x2214, 0xd2ac, 0x1110, 0xd1bc, 0x0150,
-	0x7900, 0xd1f4, 0x0120, 0x7914, 0xa18c, 0x00ff, 0x0040, 0x2009,
-	0x0000, 0x0028, 0xa1f8, 0x2dc4, 0x2f0d, 0xa18c, 0x00ff, 0x2c78,
-	0x2061, 0x0100, 0x619a, 0xa082, 0x0085, 0x001b, 0x00fe, 0x00ce,
-	0x0005, 0x777a, 0x7784, 0x779f, 0x7778, 0x7778, 0x7778, 0x777a,
-	0x080c, 0x1515, 0x0146, 0x20a1, 0x020b, 0x04a1, 0x60c3, 0x0000,
-	0x080c, 0x7d67, 0x014e, 0x0005, 0x0146, 0x20a1, 0x020b, 0x080c,
-	0x77eb, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x7808, 0x20a2, 0x7810,
-	0x20a2, 0x20a3, 0x0000, 0x20a3, 0xffff, 0x20a3, 0x0000, 0x20a3,
-	0x0000, 0x60c3, 0x000c, 0x080c, 0x7d67, 0x014e, 0x0005, 0x0146,
-	0x20a1, 0x020b, 0x080c, 0x7825, 0x20a3, 0x0003, 0x20a3, 0x0300,
-	0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0004, 0x080c, 0x7d67,
-	0x014e, 0x0005, 0x0026, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818,
-	0xa080, 0x0028, 0x2004, 0x2011, 0xb535, 0x2214, 0xd2ac, 0x1118,
-	0xa092, 0x007e, 0x0288, 0x00d6, 0xa0e8, 0xb635, 0x2d6c, 0x6810,
-	0xa085, 0x8100, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xb51c, 0x2da6,
-	0x8d68, 0x2da6, 0x00de, 0x0088, 0x00d6, 0xa0e8, 0xb635, 0x2d6c,
-	0x6810, 0xa085, 0x8100, 0x20a2, 0x6814, 0x20a2, 0x00de, 0x20a3,
-	0x0000, 0x2011, 0xb515, 0x2214, 0x22a2, 0x20a3, 0x0009, 0x20a3,
-	0x0000, 0x0804, 0x76a8, 0x0026, 0x20e1, 0x9080, 0x20e1, 0x4000,
-	0x7818, 0xa080, 0x0028, 0x2004, 0x2011, 0xb535, 0x2214, 0xd2ac,
-	0x1118, 0xa092, 0x007e, 0x0288, 0x00d6, 0xa0e8, 0xb635, 0x2d6c,
-	0x6810, 0xa085, 0x8400, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xb51c,
-	0x2da6, 0x8d68, 0x2da6, 0x00de, 0x0088, 0x00d6, 0xa0e8, 0xb635,
-	0x2d6c, 0x6810, 0xa085, 0x8400, 0x20a2, 0x6814, 0x20a2, 0x00de,
-	0x20a3, 0x0000, 0x2011, 0xb515, 0x2214, 0x22a2, 0x2001, 0x0099,
-	0x20a2, 0x20a3, 0x0000, 0x0804, 0x7734, 0x0026, 0x20e1, 0x9080,
-	0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2004, 0x2011, 0xb535,
+	0x60c3, 0x0014, 0x080c, 0x7de0, 0x0005, 0x20a1, 0x020b, 0x080c,
+	0x774f, 0x20a3, 0x0200, 0x0804, 0x7420, 0x20a1, 0x020b, 0x080c,
+	0x774f, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x20a3, 0x0003, 0x20a3,
+	0x2a00, 0x60c3, 0x0008, 0x080c, 0x7de0, 0x0005, 0x20e1, 0x9080,
+	0x20e1, 0x4000, 0x20a1, 0x020b, 0x080c, 0x774f, 0x20a3, 0x0100,
+	0x20a3, 0x0000, 0x20a3, 0x000b, 0x20a3, 0x0000, 0x60c3, 0x0008,
+	0x080c, 0x7de0, 0x0005, 0x0026, 0x0036, 0x0046, 0x2019, 0x3200,
+	0x2021, 0x0800, 0x0038, 0x0026, 0x0036, 0x0046, 0x2019, 0x2200,
+	0x2021, 0x0100, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080,
+	0x0028, 0x2014, 0xa286, 0x007e, 0x11a0, 0xa385, 0x00ff, 0x20a2,
+	0x20a3, 0xfffe, 0x20a3, 0x0000, 0x2011, 0xb615, 0x2214, 0x2001,
+	0xb89e, 0x2004, 0xa005, 0x0118, 0x2011, 0xb61d, 0x2214, 0x22a2,
+	0x04d0, 0xa286, 0x007f, 0x1138, 0x00d6, 0xa385, 0x00ff, 0x20a2,
+	0x20a3, 0xfffd, 0x00c8, 0x2001, 0xb635, 0x2004, 0xd0ac, 0x1110,
+	0xd2bc, 0x01c8, 0xa286, 0x0080, 0x00d6, 0x1130, 0xa385, 0x00ff,
+	0x20a2, 0x20a3, 0xfffc, 0x0040, 0xa2e8, 0xb735, 0x2d6c, 0x6810,
+	0xa305, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xb61c, 0x2da6, 0x8d68,
+	0x2da6, 0x00de, 0x0080, 0x00d6, 0xa2e8, 0xb735, 0x2d6c, 0x6810,
+	0xa305, 0x20a2, 0x6814, 0x20a2, 0x00de, 0x20a3, 0x0000, 0x2011,
+	0xb615, 0x2214, 0x22a2, 0xa485, 0x0029, 0x20a2, 0x004e, 0x003e,
+	0x20a3, 0x0000, 0x080c, 0x7dcf, 0x22a2, 0x20a3, 0x0000, 0x2fa2,
+	0x20a3, 0xffff, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x002e, 0x0005,
+	0x0026, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x20a3, 0x02ff, 0x2011,
+	0xfffc, 0x22a2, 0x00d6, 0x2069, 0xb61c, 0x2da6, 0x8d68, 0x2da6,
+	0x00de, 0x20a3, 0x2029, 0x20a3, 0x0000, 0x08e0, 0x20a3, 0x0100,
+	0x20a3, 0x0000, 0x20a3, 0xfc02, 0x20a3, 0x0000, 0x0005, 0x0026,
+	0x0036, 0x0046, 0x2019, 0x3300, 0x2021, 0x0800, 0x0038, 0x0026,
+	0x0036, 0x0046, 0x2019, 0x2300, 0x2021, 0x0100, 0x20e1, 0x9080,
+	0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2004, 0x2011, 0xb635,
+	0x2214, 0xd2ac, 0x1118, 0xa092, 0x007e, 0x02d8, 0x00d6, 0xa0e8,
+	0xb735, 0x2d6c, 0x6810, 0xa305, 0x20a2, 0x6814, 0x20a2, 0x6810,
+	0xa005, 0x1140, 0x6814, 0xa005, 0x1128, 0x20a3, 0x00ff, 0x20a3,
+	0xfffe, 0x0028, 0x2069, 0xb61c, 0x2da6, 0x8d68, 0x2da6, 0x00de,
+	0x0080, 0x00d6, 0xa0e8, 0xb735, 0x2d6c, 0x6810, 0xa305, 0x20a2,
+	0x6814, 0x20a2, 0x00de, 0x20a3, 0x0000, 0x2011, 0xb615, 0x2214,
+	0x22a2, 0xa485, 0x0098, 0x20a2, 0x20a3, 0x0000, 0x004e, 0x003e,
+	0x080c, 0x7dcf, 0x22a2, 0x20a3, 0x0000, 0x7a08, 0x22a2, 0x2fa2,
+	0x20a3, 0x0000, 0x20a3, 0x0000, 0x002e, 0x0005, 0x080c, 0x7dcf,
+	0x22a2, 0x20a3, 0x0000, 0x7a08, 0x22a2, 0x7810, 0x20a2, 0x20a3,
+	0x0000, 0x20a3, 0x0000, 0x002e, 0x0005, 0x00c6, 0x00f6, 0x6004,
+	0xa08a, 0x0085, 0x0a0c, 0x151a, 0xa08a, 0x008c, 0x1a0c, 0x151a,
+	0x6118, 0x2178, 0x79a0, 0x2011, 0xb635, 0x2214, 0xd2ac, 0x1110,
+	0xd1bc, 0x0150, 0x7900, 0xd1f4, 0x0120, 0x7914, 0xa18c, 0x00ff,
+	0x0040, 0x2009, 0x0000, 0x0028, 0xa1f8, 0x2df9, 0x2f0d, 0xa18c,
+	0x00ff, 0x2c78, 0x2061, 0x0100, 0x619a, 0xa082, 0x0085, 0x001b,
+	0x00fe, 0x00ce, 0x0005, 0x77ec, 0x77f6, 0x7811, 0x77ea, 0x77ea,
+	0x77ea, 0x77ec, 0x080c, 0x151a, 0x0146, 0x20a1, 0x020b, 0x04a1,
+	0x60c3, 0x0000, 0x080c, 0x7de0, 0x014e, 0x0005, 0x0146, 0x20a1,
+	0x020b, 0x080c, 0x785d, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x7808,
+	0x20a2, 0x7810, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0xffff, 0x20a3,
+	0x0000, 0x20a3, 0x0000, 0x60c3, 0x000c, 0x080c, 0x7de0, 0x014e,
+	0x0005, 0x0146, 0x20a1, 0x020b, 0x080c, 0x7897, 0x20a3, 0x0003,
+	0x20a3, 0x0300, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0004,
+	0x080c, 0x7de0, 0x014e, 0x0005, 0x0026, 0x20e1, 0x9080, 0x20e1,
+	0x4000, 0x7818, 0xa080, 0x0028, 0x2004, 0x2011, 0xb635, 0x2214,
+	0xd2ac, 0x1118, 0xa092, 0x007e, 0x0288, 0x00d6, 0xa0e8, 0xb735,
+	0x2d6c, 0x6810, 0xa085, 0x8100, 0x20a2, 0x6814, 0x20a2, 0x2069,
+	0xb61c, 0x2da6, 0x8d68, 0x2da6, 0x00de, 0x0088, 0x00d6, 0xa0e8,
+	0xb735, 0x2d6c, 0x6810, 0xa085, 0x8100, 0x20a2, 0x6814, 0x20a2,
+	0x00de, 0x20a3, 0x0000, 0x2011, 0xb615, 0x2214, 0x22a2, 0x20a3,
+	0x0009, 0x20a3, 0x0000, 0x0804, 0x771a, 0x0026, 0x20e1, 0x9080,
+	0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2004, 0x2011, 0xb635,
 	0x2214, 0xd2ac, 0x1118, 0xa092, 0x007e, 0x0288, 0x00d6, 0xa0e8,
-	0xb635, 0x2d6c, 0x6810, 0xa085, 0x8500, 0x20a2, 0x6814, 0x20a2,
-	0x2069, 0xb51c, 0x2da6, 0x8d68, 0x2da6, 0x00de, 0x0088, 0x00d6,
-	0xa0e8, 0xb635, 0x2d6c, 0x6810, 0xa085, 0x8500, 0x20a2, 0x6814,
-	0x20a2, 0x00de, 0x20a3, 0x0000, 0x2011, 0xb515, 0x2214, 0x22a2,
-	0x2001, 0x0099, 0x20a2, 0x20a3, 0x0000, 0x0804, 0x7734, 0x00c6,
-	0x00f6, 0x2c78, 0x7804, 0xa08a, 0x0040, 0x0a0c, 0x1515, 0xa08a,
-	0x0053, 0x1a0c, 0x1515, 0x7918, 0x2160, 0x61a0, 0x2011, 0xb535,
-	0x2214, 0xd2ac, 0x1110, 0xd1bc, 0x0150, 0x6100, 0xd1f4, 0x0120,
-	0x6114, 0xa18c, 0x00ff, 0x0040, 0x2009, 0x0000, 0x0028, 0xa1e0,
-	0x2dc4, 0x2c0d, 0xa18c, 0x00ff, 0x2061, 0x0100, 0x619a, 0xa082,
-	0x0040, 0x001b, 0x00fe, 0x00ce, 0x0005, 0x78a2, 0x79ae, 0x794b,
-	0x7b60, 0x78a0, 0x78a0, 0x78a0, 0x78a0, 0x78a0, 0x78a0, 0x78a0,
-	0x80d7, 0x80e7, 0x80f7, 0x8107, 0x78a0, 0x851e, 0x78a0, 0x80c6,
-	0x080c, 0x1515, 0x00d6, 0x0156, 0x0146, 0x780b, 0xffff, 0x20a1,
-	0x020b, 0x080c, 0x7902, 0x7910, 0x2168, 0x6948, 0x7952, 0x21a2,
-	0xa016, 0x22a2, 0x22a2, 0x22a2, 0x694c, 0xa184, 0x000f, 0x1118,
-	0x2001, 0x0005, 0x0040, 0xd184, 0x0118, 0x2001, 0x0004, 0x0018,
-	0xa084, 0x0006, 0x8004, 0x0016, 0x2008, 0x7858, 0xa084, 0x00ff,
-	0x8007, 0xa105, 0x001e, 0x20a2, 0xd1ac, 0x0118, 0x20a3, 0x0002,
-	0x0048, 0xd1b4, 0x0118, 0x20a3, 0x0001, 0x0020, 0x20a3, 0x0000,
-	0x2230, 0x0010, 0x6a80, 0x6e7c, 0x20a9, 0x0008, 0x0136, 0xad88,
-	0x0017, 0x2198, 0x20a1, 0x021b, 0x53a6, 0x013e, 0x20a1, 0x020b,
-	0x22a2, 0x26a2, 0x60c3, 0x0020, 0x20e1, 0x9080, 0x6014, 0xa084,
-	0x0004, 0xa085, 0x0009, 0x6016, 0x2001, 0xb7fc, 0x2003, 0x07d0,
-	0x2001, 0xb7fb, 0x2003, 0x0009, 0x080c, 0x17e2, 0x014e, 0x015e,
-	0x00de, 0x0005, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7a18, 0xa280,
-	0x0023, 0x2014, 0x8210, 0xa294, 0x00ff, 0x2202, 0x8217, 0x7818,
-	0xa080, 0x0028, 0x2004, 0x2019, 0xb535, 0x231c, 0xd3ac, 0x1110,
-	0xd0bc, 0x0188, 0x00d6, 0xa0e8, 0xb635, 0x2d6c, 0x6810, 0xa085,
-	0x0600, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xb51c, 0x2da6, 0x8d68,
-	0x2da6, 0x00de, 0x0088, 0x00d6, 0xa0e8, 0xb635, 0x2d6c, 0x6810,
-	0xa085, 0x0600, 0x20a2, 0x6814, 0x20a2, 0x00de, 0x20a3, 0x0000,
-	0x2009, 0xb515, 0x210c, 0x21a2, 0x20a3, 0x0829, 0x20a3, 0x0000,
-	0x22a2, 0x20a3, 0x0000, 0x2fa2, 0x20a3, 0xffff, 0x20a3, 0x0000,
-	0x20a3, 0x0000, 0x0005, 0x00d6, 0x0156, 0x0136, 0x0146, 0x20a1,
-	0x020b, 0x00c1, 0x7810, 0x2068, 0x6860, 0x20a2, 0x685c, 0x20a2,
-	0x6880, 0x20a2, 0x687c, 0x20a2, 0xa006, 0x20a2, 0x20a2, 0x20a2,
-	0x20a2, 0x60c3, 0x000c, 0x080c, 0x7d67, 0x014e, 0x013e, 0x015e,
-	0x00de, 0x0005, 0x0026, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818,
-	0xa080, 0x0028, 0x2004, 0x2011, 0xb535, 0x2214, 0xd2ac, 0x1110,
-	0xd0bc, 0x0188, 0x00d6, 0xa0e8, 0xb635, 0x2d6c, 0x6810, 0xa085,
-	0x0500, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xb51c, 0x2da6, 0x8d68,
-	0x2da6, 0x00de, 0x0088, 0x00d6, 0xa0e8, 0xb635, 0x2d6c, 0x6810,
-	0xa085, 0x0500, 0x20a2, 0x6814, 0x20a2, 0x00de, 0x20a3, 0x0000,
-	0x2011, 0xb515, 0x2214, 0x22a2, 0x20a3, 0x0889, 0x20a3, 0x0000,
-	0x080c, 0x7d56, 0x22a2, 0x20a3, 0x0000, 0x7a08, 0x22a2, 0x2fa2,
-	0x20a3, 0x0000, 0x20a3, 0x0000, 0x002e, 0x0005, 0x00d6, 0x0156,
-	0x0136, 0x0146, 0x7810, 0xa0ec, 0xf000, 0x0168, 0xa06d, 0x080c,
-	0x5301, 0x0148, 0x684c, 0xa084, 0x2020, 0xa086, 0x2020, 0x1118,
-	0x7820, 0xc0cd, 0x7822, 0x20a1, 0x020b, 0x080c, 0x7b16, 0xa016,
-	0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x7810, 0xa084, 0xf000,
-	0x1130, 0x7810, 0xa084, 0x0700, 0x8007, 0x0043, 0x0010, 0xa006,
-	0x002b, 0x014e, 0x013e, 0x015e, 0x00de, 0x0005, 0x79e8, 0x7a7d,
-	0x7a8d, 0x7abf, 0x7ad2, 0x7aed, 0x7af6, 0x79e6, 0x080c, 0x1515,
-	0x0016, 0x0036, 0x694c, 0xa18c, 0x0003, 0x0118, 0xa186, 0x0003,
-	0x1170, 0x6b78, 0x7820, 0xd0cc, 0x0108, 0xc3e5, 0x23a2, 0x6868,
-	0x20a2, 0x6864, 0x20a2, 0x003e, 0x001e, 0x0804, 0x7ac9, 0xa186,
-	0x0001, 0x190c, 0x1515, 0x6b78, 0x7820, 0xd0cc, 0x0108, 0xc3e5,
-	0x23a2, 0x6868, 0x20a2, 0x6864, 0x20a2, 0x22a2, 0x6874, 0x20a2,
-	0x22a2, 0x687c, 0x20a2, 0x2009, 0x0018, 0xa384, 0x0300, 0x0904,
-	0x7a77, 0xd3c4, 0x0110, 0x687c, 0xa108, 0xd3cc, 0x0110, 0x6874,
-	0xa108, 0x0156, 0x20a9, 0x000d, 0xad80, 0x0020, 0x201c, 0x831f,
-	0x23a2, 0x8000, 0x1f04, 0x7a26, 0x015e, 0x22a2, 0x22a2, 0x22a2,
-	0xa184, 0x0003, 0x0904, 0x7a77, 0x20a1, 0x020b, 0x20e1, 0x9080,
-	0x20e1, 0x4000, 0x0006, 0x7818, 0xa080, 0x0028, 0x2004, 0x2011,
-	0xb535, 0x2214, 0xd2ac, 0x1110, 0xd0bc, 0x0188, 0x00d6, 0xa0e8,
-	0xb635, 0x2d6c, 0x6810, 0xa085, 0x0700, 0x20a2, 0x6814, 0x20a2,
-	0x2069, 0xb51c, 0x2da6, 0x8d68, 0x2da6, 0x00de, 0x0088, 0x00d6,
-	0xa0e8, 0xb635, 0x2d6c, 0x6810, 0xa085, 0x0700, 0x20a2, 0x6814,
-	0x20a2, 0x00de, 0x20a3, 0x0000, 0x2011, 0xb515, 0x2214, 0x22a2,
-	0x000e, 0x7b20, 0xd3cc, 0x0118, 0x20a3, 0x0889, 0x0010, 0x20a3,
-	0x0898, 0x20a2, 0x080c, 0x7d56, 0x22a2, 0x20a3, 0x0000, 0x61c2,
-	0x003e, 0x001e, 0x080c, 0x7d67, 0x0005, 0x2011, 0x0008, 0x2001,
-	0xb50d, 0x2004, 0xd0f4, 0x0110, 0x2011, 0x0028, 0x7820, 0xd0cc,
-	0x0108, 0xc2e5, 0x22a2, 0xa016, 0x04d0, 0x2011, 0x0302, 0x0016,
-	0x0036, 0x7828, 0x792c, 0xa11d, 0x0108, 0xc2dd, 0x7b20, 0xd3cc,
-	0x0108, 0xc2e5, 0x22a2, 0x20a2, 0x21a2, 0x003e, 0x001e, 0xa016,
-	0x22a2, 0x20a3, 0x0012, 0x22a2, 0x20a3, 0x0008, 0x22a2, 0x22a2,
-	0x22a2, 0x22a2, 0x20a3, 0x7000, 0x20a3, 0x0500, 0x22a2, 0x20a3,
-	0x000a, 0x22a2, 0x22a2, 0x20a3, 0x2500, 0x22a2, 0x22a2, 0x22a2,
-	0x22a2, 0x22a2, 0x60c3, 0x0032, 0x080c, 0x7d67, 0x0005, 0x2011,
-	0x0028, 0x7820, 0xd0cc, 0x0108, 0xc2e5, 0x22a2, 0xa016, 0x22a2,
-	0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x60c3, 0x0018, 0x080c,
-	0x7d67, 0x0005, 0x2011, 0x0100, 0x7820, 0xd0cc, 0x0108, 0xc2e5,
-	0x22a2, 0xa016, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x20a3,
-	0x0008, 0x22a2, 0x7854, 0xa084, 0x00ff, 0x20a2, 0x22a2, 0x22a2,
-	0x60c3, 0x0020, 0x080c, 0x7d67, 0x0005, 0x2011, 0x0008, 0x7820,
-	0xd0cc, 0x0108, 0xc2e5, 0x22a2, 0xa016, 0x0888, 0x0036, 0x7b10,
-	0xa384, 0xff00, 0x7812, 0xa384, 0x00ff, 0x8001, 0x1138, 0x7820,
-	0xd0cc, 0x0108, 0xc2e5, 0x22a2, 0x003e, 0x0808, 0x0046, 0x2021,
-	0x0800, 0x0006, 0x7820, 0xd0cc, 0x000e, 0x0108, 0xc4e5, 0x24a2,
-	0x004e, 0x22a2, 0x20a2, 0x003e, 0x0804, 0x7ac9, 0x0026, 0x20e1,
-	0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2004, 0x2011,
-	0xb535, 0x2214, 0xd2ac, 0x1110, 0xd0bc, 0x0188, 0x00d6, 0xa0e8,
-	0xb635, 0x2d6c, 0x6810, 0xa085, 0x0700, 0x20a2, 0x6814, 0x20a2,
-	0x2069, 0xb51c, 0x2da6, 0x8d68, 0x2da6, 0x00de, 0x0088, 0x00d6,
-	0xa0e8, 0xb635, 0x2d6c, 0x6810, 0xa085, 0x0700, 0x20a2, 0x6814,
-	0x20a2, 0x00de, 0x20a3, 0x0000, 0x2011, 0xb515, 0x2214, 0x22a2,
-	0x7820, 0xd0cc, 0x0118, 0x20a3, 0x0889, 0x0010, 0x20a3, 0x0898,
-	0x20a3, 0x0000, 0x080c, 0x7d56, 0x22a2, 0x20a3, 0x0000, 0x7a08,
+	0xb735, 0x2d6c, 0x6810, 0xa085, 0x8400, 0x20a2, 0x6814, 0x20a2,
+	0x2069, 0xb61c, 0x2da6, 0x8d68, 0x2da6, 0x00de, 0x0088, 0x00d6,
+	0xa0e8, 0xb735, 0x2d6c, 0x6810, 0xa085, 0x8400, 0x20a2, 0x6814,
+	0x20a2, 0x00de, 0x20a3, 0x0000, 0x2011, 0xb615, 0x2214, 0x22a2,
+	0x2001, 0x0099, 0x20a2, 0x20a3, 0x0000, 0x0804, 0x77a6, 0x0026,
+	0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2004,
+	0x2011, 0xb635, 0x2214, 0xd2ac, 0x1118, 0xa092, 0x007e, 0x0288,
+	0x00d6, 0xa0e8, 0xb735, 0x2d6c, 0x6810, 0xa085, 0x8500, 0x20a2,
+	0x6814, 0x20a2, 0x2069, 0xb61c, 0x2da6, 0x8d68, 0x2da6, 0x00de,
+	0x0088, 0x00d6, 0xa0e8, 0xb735, 0x2d6c, 0x6810, 0xa085, 0x8500,
+	0x20a2, 0x6814, 0x20a2, 0x00de, 0x20a3, 0x0000, 0x2011, 0xb615,
+	0x2214, 0x22a2, 0x2001, 0x0099, 0x20a2, 0x20a3, 0x0000, 0x0804,
+	0x77a6, 0x00c6, 0x00f6, 0x2c78, 0x7804, 0xa08a, 0x0040, 0x0a0c,
+	0x151a, 0xa08a, 0x0053, 0x1a0c, 0x151a, 0x7918, 0x2160, 0x61a0,
+	0x2011, 0xb635, 0x2214, 0xd2ac, 0x1110, 0xd1bc, 0x0150, 0x6100,
+	0xd1f4, 0x0120, 0x6114, 0xa18c, 0x00ff, 0x0040, 0x2009, 0x0000,
+	0x0028, 0xa1e0, 0x2df9, 0x2c0d, 0xa18c, 0x00ff, 0x2061, 0x0100,
+	0x619a, 0xa082, 0x0040, 0x001b, 0x00fe, 0x00ce, 0x0005, 0x7914,
+	0x7a20, 0x79bd, 0x7bd2, 0x7912, 0x7912, 0x7912, 0x7912, 0x7912,
+	0x7912, 0x7912, 0x815e, 0x816e, 0x817e, 0x818e, 0x7912, 0x85a5,
+	0x7912, 0x814d, 0x080c, 0x151a, 0x00d6, 0x0156, 0x0146, 0x780b,
+	0xffff, 0x20a1, 0x020b, 0x080c, 0x7974, 0x7910, 0x2168, 0x6948,
+	0x7952, 0x21a2, 0xa016, 0x22a2, 0x22a2, 0x22a2, 0x694c, 0xa184,
+	0x000f, 0x1118, 0x2001, 0x0005, 0x0040, 0xd184, 0x0118, 0x2001,
+	0x0004, 0x0018, 0xa084, 0x0006, 0x8004, 0x0016, 0x2008, 0x7858,
+	0xa084, 0x00ff, 0x8007, 0xa105, 0x001e, 0x20a2, 0xd1ac, 0x0118,
+	0x20a3, 0x0002, 0x0048, 0xd1b4, 0x0118, 0x20a3, 0x0001, 0x0020,
+	0x20a3, 0x0000, 0x2230, 0x0010, 0x6a80, 0x6e7c, 0x20a9, 0x0008,
+	0x0136, 0xad88, 0x0017, 0x2198, 0x20a1, 0x021b, 0x53a6, 0x013e,
+	0x20a1, 0x020b, 0x22a2, 0x26a2, 0x60c3, 0x0020, 0x20e1, 0x9080,
+	0x6014, 0xa084, 0x0004, 0xa085, 0x0009, 0x6016, 0x2001, 0xb8fd,
+	0x2003, 0x07d0, 0x2001, 0xb8fc, 0x2003, 0x0009, 0x080c, 0x17e7,
+	0x014e, 0x015e, 0x00de, 0x0005, 0x20e1, 0x9080, 0x20e1, 0x4000,
+	0x7a18, 0xa280, 0x0023, 0x2014, 0x8210, 0xa294, 0x00ff, 0x2202,
+	0x8217, 0x7818, 0xa080, 0x0028, 0x2004, 0x2019, 0xb635, 0x231c,
+	0xd3ac, 0x1110, 0xd0bc, 0x0188, 0x00d6, 0xa0e8, 0xb735, 0x2d6c,
+	0x6810, 0xa085, 0x0600, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xb61c,
+	0x2da6, 0x8d68, 0x2da6, 0x00de, 0x0088, 0x00d6, 0xa0e8, 0xb735,
+	0x2d6c, 0x6810, 0xa085, 0x0600, 0x20a2, 0x6814, 0x20a2, 0x00de,
+	0x20a3, 0x0000, 0x2009, 0xb615, 0x210c, 0x21a2, 0x20a3, 0x0829,
+	0x20a3, 0x0000, 0x22a2, 0x20a3, 0x0000, 0x2fa2, 0x20a3, 0xffff,
+	0x20a3, 0x0000, 0x20a3, 0x0000, 0x0005, 0x00d6, 0x0156, 0x0136,
+	0x0146, 0x20a1, 0x020b, 0x00c1, 0x7810, 0x2068, 0x6860, 0x20a2,
+	0x685c, 0x20a2, 0x6880, 0x20a2, 0x687c, 0x20a2, 0xa006, 0x20a2,
+	0x20a2, 0x20a2, 0x20a2, 0x60c3, 0x000c, 0x080c, 0x7de0, 0x014e,
+	0x013e, 0x015e, 0x00de, 0x0005, 0x0026, 0x20e1, 0x9080, 0x20e1,
+	0x4000, 0x7818, 0xa080, 0x0028, 0x2004, 0x2011, 0xb635, 0x2214,
+	0xd2ac, 0x1110, 0xd0bc, 0x0188, 0x00d6, 0xa0e8, 0xb735, 0x2d6c,
+	0x6810, 0xa085, 0x0500, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xb61c,
+	0x2da6, 0x8d68, 0x2da6, 0x00de, 0x0088, 0x00d6, 0xa0e8, 0xb735,
+	0x2d6c, 0x6810, 0xa085, 0x0500, 0x20a2, 0x6814, 0x20a2, 0x00de,
+	0x20a3, 0x0000, 0x2011, 0xb615, 0x2214, 0x22a2, 0x20a3, 0x0889,
+	0x20a3, 0x0000, 0x080c, 0x7dcf, 0x22a2, 0x20a3, 0x0000, 0x7a08,
 	0x22a2, 0x2fa2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x002e, 0x0005,
-	0x00d6, 0x0156, 0x0136, 0x0146, 0x0016, 0x0036, 0x7810, 0xa084,
-	0x0700, 0x8007, 0x003b, 0x003e, 0x001e, 0x014e, 0x013e, 0x015e,
-	0x00de, 0x0005, 0x7b7a, 0x7b7a, 0x7b7c, 0x7b7a, 0x7b7a, 0x7b7a,
-	0x7b9e, 0x7b7a, 0x080c, 0x1515, 0x7910, 0xa18c, 0xf8ff, 0xa18d,
-	0x0600, 0x7912, 0x20a1, 0x020b, 0x2009, 0x0003, 0x00f9, 0x00d6,
-	0x2069, 0xb552, 0x6804, 0xd0bc, 0x0130, 0x682c, 0xa084, 0x00ff,
-	0x8007, 0x20a2, 0x0010, 0x20a3, 0x3f00, 0x00de, 0x22a2, 0x22a2,
-	0x22a2, 0x60c3, 0x0001, 0x080c, 0x7d67, 0x0005, 0x20a1, 0x020b,
-	0x2009, 0x0003, 0x0019, 0x20a3, 0x7f00, 0x0c80, 0x0026, 0x20e1,
-	0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2004, 0x2011,
-	0xb535, 0x2214, 0xd2ac, 0x1110, 0xd0bc, 0x0188, 0x00d6, 0xa0e8,
-	0xb635, 0x2d6c, 0x6810, 0xa085, 0x0100, 0x20a2, 0x6814, 0x20a2,
-	0x2069, 0xb51c, 0x2da6, 0x8d68, 0x2da6, 0x00de, 0x0088, 0x00d6,
-	0xa0e8, 0xb635, 0x2d6c, 0x6810, 0xa085, 0x0100, 0x20a2, 0x6814,
-	0x20a2, 0x00de, 0x20a3, 0x0000, 0x2011, 0xb515, 0x2214, 0x22a2,
-	0x20a3, 0x0888, 0xa18d, 0x0008, 0x21a2, 0x080c, 0x7d56, 0x22a2,
-	0x20a3, 0x0000, 0x7a08, 0x22a2, 0x2fa2, 0x20a3, 0x0000, 0x20a3,
-	0x0000, 0x002e, 0x0005, 0x00e6, 0x00d6, 0x00c6, 0x0056, 0x0046,
-	0x0036, 0x2061, 0x0100, 0x2071, 0xb500, 0x7154, 0x7818, 0x2068,
-	0x68a0, 0x2028, 0x76d4, 0xd6ac, 0x1130, 0xd0bc, 0x1120, 0x6910,
-	0x6a14, 0x7454, 0x0020, 0x6910, 0x6a14, 0x7370, 0x7474, 0x781c,
-	0xa0be, 0x0006, 0x0904, 0x7ca1, 0xa0be, 0x000a, 0x15e8, 0xa185,
-	0x0200, 0x6062, 0x6266, 0x636a, 0x646e, 0x6073, 0x2029, 0x6077,
-	0x0000, 0x688c, 0x8000, 0xa084, 0x00ff, 0x688e, 0x8007, 0x607a,
-	0x607f, 0x0000, 0x2f00, 0x6082, 0x7808, 0x6086, 0x7810, 0x2070,
-	0x7014, 0x608a, 0x7010, 0x608e, 0x700c, 0x60c6, 0x7008, 0x60ca,
-	0x686c, 0x60ce, 0x60af, 0x95d5, 0x60d7, 0x0000, 0x609f, 0x0000,
-	0x080c, 0x85b9, 0x2009, 0x07d0, 0x60c4, 0xa084, 0xfff0, 0xa005,
-	0x0110, 0x2009, 0x1b58, 0x080c, 0x6a15, 0x003e, 0x004e, 0x005e,
-	0x00ce, 0x00de, 0x00ee, 0x0005, 0x70d4, 0xd0ac, 0x1110, 0xd5bc,
-	0x0138, 0xa185, 0x0100, 0x6062, 0x6266, 0x636a, 0x646e, 0x0038,
-	0xa185, 0x0100, 0x6062, 0x6266, 0x606b, 0x0000, 0x646e, 0x6073,
-	0x0809, 0x6077, 0x0008, 0x688c, 0x8000, 0xa084, 0x00ff, 0x688e,
+	0x00d6, 0x0156, 0x0136, 0x0146, 0x7810, 0xa0ec, 0xf000, 0x0168,
+	0xa06d, 0x080c, 0x5373, 0x0148, 0x684c, 0xa084, 0x2020, 0xa086,
+	0x2020, 0x1118, 0x7820, 0xc0cd, 0x7822, 0x20a1, 0x020b, 0x080c,
+	0x7b88, 0xa016, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x7810,
+	0xa084, 0xf000, 0x1130, 0x7810, 0xa084, 0x0700, 0x8007, 0x0043,
+	0x0010, 0xa006, 0x002b, 0x014e, 0x013e, 0x015e, 0x00de, 0x0005,
+	0x7a5a, 0x7aef, 0x7aff, 0x7b31, 0x7b44, 0x7b5f, 0x7b68, 0x7a58,
+	0x080c, 0x151a, 0x0016, 0x0036, 0x694c, 0xa18c, 0x0003, 0x0118,
+	0xa186, 0x0003, 0x1170, 0x6b78, 0x7820, 0xd0cc, 0x0108, 0xc3e5,
+	0x23a2, 0x6868, 0x20a2, 0x6864, 0x20a2, 0x003e, 0x001e, 0x0804,
+	0x7b3b, 0xa186, 0x0001, 0x190c, 0x151a, 0x6b78, 0x7820, 0xd0cc,
+	0x0108, 0xc3e5, 0x23a2, 0x6868, 0x20a2, 0x6864, 0x20a2, 0x22a2,
+	0x6874, 0x20a2, 0x22a2, 0x687c, 0x20a2, 0x2009, 0x0018, 0xa384,
+	0x0300, 0x0904, 0x7ae9, 0xd3c4, 0x0110, 0x687c, 0xa108, 0xd3cc,
+	0x0110, 0x6874, 0xa108, 0x0156, 0x20a9, 0x000d, 0xad80, 0x0020,
+	0x201c, 0x831f, 0x23a2, 0x8000, 0x1f04, 0x7a98, 0x015e, 0x22a2,
+	0x22a2, 0x22a2, 0xa184, 0x0003, 0x0904, 0x7ae9, 0x20a1, 0x020b,
+	0x20e1, 0x9080, 0x20e1, 0x4000, 0x0006, 0x7818, 0xa080, 0x0028,
+	0x2004, 0x2011, 0xb635, 0x2214, 0xd2ac, 0x1110, 0xd0bc, 0x0188,
+	0x00d6, 0xa0e8, 0xb735, 0x2d6c, 0x6810, 0xa085, 0x0700, 0x20a2,
+	0x6814, 0x20a2, 0x2069, 0xb61c, 0x2da6, 0x8d68, 0x2da6, 0x00de,
+	0x0088, 0x00d6, 0xa0e8, 0xb735, 0x2d6c, 0x6810, 0xa085, 0x0700,
+	0x20a2, 0x6814, 0x20a2, 0x00de, 0x20a3, 0x0000, 0x2011, 0xb615,
+	0x2214, 0x22a2, 0x000e, 0x7b20, 0xd3cc, 0x0118, 0x20a3, 0x0889,
+	0x0010, 0x20a3, 0x0898, 0x20a2, 0x080c, 0x7dcf, 0x22a2, 0x20a3,
+	0x0000, 0x61c2, 0x003e, 0x001e, 0x080c, 0x7de0, 0x0005, 0x2011,
+	0x0008, 0x2001, 0xb60d, 0x2004, 0xd0f4, 0x0110, 0x2011, 0x0028,
+	0x7820, 0xd0cc, 0x0108, 0xc2e5, 0x22a2, 0xa016, 0x04d0, 0x2011,
+	0x0302, 0x0016, 0x0036, 0x7828, 0x792c, 0xa11d, 0x0108, 0xc2dd,
+	0x7b20, 0xd3cc, 0x0108, 0xc2e5, 0x22a2, 0x20a2, 0x21a2, 0x003e,
+	0x001e, 0xa016, 0x22a2, 0x20a3, 0x0012, 0x22a2, 0x20a3, 0x0008,
+	0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x20a3, 0x7000, 0x20a3, 0x0500,
+	0x22a2, 0x20a3, 0x000a, 0x22a2, 0x22a2, 0x20a3, 0x2500, 0x22a2,
+	0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x60c3, 0x0032, 0x080c, 0x7de0,
+	0x0005, 0x2011, 0x0028, 0x7820, 0xd0cc, 0x0108, 0xc2e5, 0x22a2,
+	0xa016, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x60c3,
+	0x0018, 0x080c, 0x7de0, 0x0005, 0x2011, 0x0100, 0x7820, 0xd0cc,
+	0x0108, 0xc2e5, 0x22a2, 0xa016, 0x22a2, 0x22a2, 0x22a2, 0x22a2,
+	0x22a2, 0x20a3, 0x0008, 0x22a2, 0x7854, 0xa084, 0x00ff, 0x20a2,
+	0x22a2, 0x22a2, 0x60c3, 0x0020, 0x080c, 0x7de0, 0x0005, 0x2011,
+	0x0008, 0x7820, 0xd0cc, 0x0108, 0xc2e5, 0x22a2, 0xa016, 0x0888,
+	0x0036, 0x7b10, 0xa384, 0xff00, 0x7812, 0xa384, 0x00ff, 0x8001,
+	0x1138, 0x7820, 0xd0cc, 0x0108, 0xc2e5, 0x22a2, 0x003e, 0x0808,
+	0x0046, 0x2021, 0x0800, 0x0006, 0x7820, 0xd0cc, 0x000e, 0x0108,
+	0xc4e5, 0x24a2, 0x004e, 0x22a2, 0x20a2, 0x003e, 0x0804, 0x7b3b,
+	0x0026, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028,
+	0x2004, 0x2011, 0xb635, 0x2214, 0xd2ac, 0x1110, 0xd0bc, 0x0188,
+	0x00d6, 0xa0e8, 0xb735, 0x2d6c, 0x6810, 0xa085, 0x0700, 0x20a2,
+	0x6814, 0x20a2, 0x2069, 0xb61c, 0x2da6, 0x8d68, 0x2da6, 0x00de,
+	0x0088, 0x00d6, 0xa0e8, 0xb735, 0x2d6c, 0x6810, 0xa085, 0x0700,
+	0x20a2, 0x6814, 0x20a2, 0x00de, 0x20a3, 0x0000, 0x2011, 0xb615,
+	0x2214, 0x22a2, 0x7820, 0xd0cc, 0x0118, 0x20a3, 0x0889, 0x0010,
+	0x20a3, 0x0898, 0x20a3, 0x0000, 0x080c, 0x7dcf, 0x22a2, 0x20a3,
+	0x0000, 0x7a08, 0x22a2, 0x2fa2, 0x20a3, 0x0000, 0x20a3, 0x0000,
+	0x002e, 0x0005, 0x00d6, 0x0156, 0x0136, 0x0146, 0x0016, 0x0036,
+	0x7810, 0xa084, 0x0700, 0x8007, 0x003b, 0x003e, 0x001e, 0x014e,
+	0x013e, 0x015e, 0x00de, 0x0005, 0x7bec, 0x7bec, 0x7bee, 0x7bec,
+	0x7bec, 0x7bec, 0x7c10, 0x7bec, 0x080c, 0x151a, 0x7910, 0xa18c,
+	0xf8ff, 0xa18d, 0x0600, 0x7912, 0x20a1, 0x020b, 0x2009, 0x0003,
+	0x00f9, 0x00d6, 0x2069, 0xb652, 0x6804, 0xd0bc, 0x0130, 0x682c,
+	0xa084, 0x00ff, 0x8007, 0x20a2, 0x0010, 0x20a3, 0x3f00, 0x00de,
+	0x22a2, 0x22a2, 0x22a2, 0x60c3, 0x0001, 0x080c, 0x7de0, 0x0005,
+	0x20a1, 0x020b, 0x2009, 0x0003, 0x0019, 0x20a3, 0x7f00, 0x0c80,
+	0x0026, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028,
+	0x2004, 0x2011, 0xb635, 0x2214, 0xd2ac, 0x1110, 0xd0bc, 0x0188,
+	0x00d6, 0xa0e8, 0xb735, 0x2d6c, 0x6810, 0xa085, 0x0100, 0x20a2,
+	0x6814, 0x20a2, 0x2069, 0xb61c, 0x2da6, 0x8d68, 0x2da6, 0x00de,
+	0x0088, 0x00d6, 0xa0e8, 0xb735, 0x2d6c, 0x6810, 0xa085, 0x0100,
+	0x20a2, 0x6814, 0x20a2, 0x00de, 0x20a3, 0x0000, 0x2011, 0xb615,
+	0x2214, 0x22a2, 0x20a3, 0x0888, 0xa18d, 0x0008, 0x21a2, 0x080c,
+	0x7dcf, 0x22a2, 0x20a3, 0x0000, 0x7a08, 0x22a2, 0x2fa2, 0x20a3,
+	0x0000, 0x20a3, 0x0000, 0x002e, 0x0005, 0x00e6, 0x00d6, 0x00c6,
+	0x0056, 0x0046, 0x0036, 0x2061, 0x0100, 0x2071, 0xb600, 0x7154,
+	0x7818, 0x2068, 0x68a0, 0x2028, 0x76d4, 0xd6ac, 0x1130, 0xd0bc,
+	0x1120, 0x6910, 0x6a14, 0x7454, 0x0020, 0x6910, 0x6a14, 0x7370,
+	0x7474, 0x781c, 0xa0be, 0x0006, 0x0904, 0x7d1a, 0xa0be, 0x000a,
+	0x15e8, 0xa185, 0x0200, 0x6062, 0x6266, 0x636a, 0x646e, 0x6073,
+	0x2029, 0x6077, 0x0000, 0x688c, 0x8000, 0xa084, 0x00ff, 0x688e,
 	0x8007, 0x607a, 0x607f, 0x0000, 0x2f00, 0x6082, 0x7808, 0x6086,
 	0x7810, 0x2070, 0x7014, 0x608a, 0x7010, 0x608e, 0x700c, 0x60c6,
 	0x7008, 0x60ca, 0x686c, 0x60ce, 0x60af, 0x95d5, 0x60d7, 0x0000,
-	0xa582, 0x0080, 0x0248, 0x6a00, 0xd2f4, 0x0120, 0x6a14, 0xa294,
-	0x00ff, 0x0010, 0x2011, 0x0000, 0x629e, 0x080c, 0x85b9, 0x2009,
-	0x07d0, 0x60c4, 0xa084, 0xfff0, 0xa005, 0x0110, 0x2009, 0x1b58,
-	0x080c, 0x6a15, 0x003e, 0x004e, 0x005e, 0x00ce, 0x00de, 0x00ee,
-	0x0005, 0x7810, 0x2070, 0x704c, 0xa084, 0x0003, 0xa086, 0x0002,
-	0x0904, 0x7cf7, 0x2001, 0xb535, 0x2004, 0xd0ac, 0x1110, 0xd5bc,
-	0x0138, 0xa185, 0x0100, 0x6062, 0x6266, 0x636a, 0x646e, 0x0038,
-	0xa185, 0x0100, 0x6062, 0x6266, 0x606b, 0x0000, 0x646e, 0x6073,
-	0x0880, 0x6077, 0x0008, 0x688c, 0x8000, 0xa084, 0x00ff, 0x688e,
-	0x8007, 0x607a, 0x7834, 0x607e, 0x2f00, 0x6086, 0x7808, 0x6082,
-	0x7060, 0x608a, 0x705c, 0x608e, 0x7080, 0x60c6, 0x707c, 0x60ca,
-	0x707c, 0x792c, 0xa108, 0x792e, 0x7080, 0x7928, 0xa109, 0x792a,
-	0x686c, 0x60ce, 0x60af, 0x95d5, 0x60d7, 0x0000, 0xa582, 0x0080,
-	0x0248, 0x6a00, 0xd2f4, 0x0120, 0x6a14, 0xa294, 0x00ff, 0x0010,
-	0x2011, 0x0000, 0x629e, 0x080c, 0x85b6, 0x0804, 0x7c8f, 0x2001,
-	0xb535, 0x2004, 0xd0ac, 0x1110, 0xd5bc, 0x0138, 0xa185, 0x0700,
-	0x6062, 0x6266, 0x636a, 0x646e, 0x0038, 0xa185, 0x0700, 0x6062,
-	0x6266, 0x606b, 0x0000, 0x646e, 0x080c, 0x5301, 0x0180, 0x00d6,
-	0x7810, 0xa06d, 0x684c, 0x00de, 0xa084, 0x2020, 0xa086, 0x2020,
-	0x1130, 0x7820, 0xc0cd, 0x7822, 0x6073, 0x0889, 0x0010, 0x6073,
-	0x0898, 0x6077, 0x0000, 0x688c, 0x8000, 0xa084, 0x00ff, 0x688e,
-	0x8007, 0x607a, 0x607f, 0x0000, 0x2f00, 0x6086, 0x7808, 0x6082,
-	0x7014, 0x608a, 0x7010, 0x608e, 0x700c, 0x60c6, 0x7008, 0x60ca,
-	0x686c, 0x60ce, 0x60af, 0x95d5, 0x60d7, 0x0000, 0xa582, 0x0080,
-	0x0248, 0x6a00, 0xd2f4, 0x0120, 0x6a14, 0xa294, 0x00ff, 0x0010,
-	0x2011, 0x0000, 0x629e, 0x7820, 0xd0cc, 0x0120, 0x080c, 0x85b9,
-	0x0804, 0x7c8f, 0x080c, 0x85b6, 0x0804, 0x7c8f, 0x7a18, 0xa280,
-	0x0023, 0x2014, 0x8210, 0xa294, 0x00ff, 0x2202, 0x8217, 0x0005,
-	0x00d6, 0x2069, 0xb7e0, 0x6843, 0x0001, 0x00de, 0x0005, 0x20e1,
-	0x9080, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x0019, 0x080c, 0x6a07,
-	0x0005, 0x0006, 0x6014, 0xa084, 0x0004, 0xa085, 0x0009, 0x6016,
-	0x000e, 0x0005, 0x0016, 0x00c6, 0x0006, 0x2061, 0x0100, 0x61a4,
-	0x60a7, 0x95f5, 0x6014, 0xa084, 0x0004, 0xa085, 0x0008, 0x6016,
-	0x000e, 0xe000, 0xe000, 0xe000, 0xe000, 0x61a6, 0x00ce, 0x001e,
-	0x0005, 0x00c6, 0x00d6, 0x0016, 0x0026, 0x2061, 0x0100, 0x2069,
-	0x0140, 0x080c, 0x5acf, 0x1198, 0x2001, 0xb7fc, 0x2004, 0xa005,
-	0x15b8, 0x0066, 0x2031, 0x0001, 0x080c, 0x5b51, 0x006e, 0x1118,
-	0x080c, 0x6a07, 0x0468, 0x00c6, 0x2061, 0xb7e0, 0x00d8, 0x6904,
-	0xa194, 0x4000, 0x0550, 0x0831, 0x6803, 0x1000, 0x6803, 0x0000,
-	0x00c6, 0x2061, 0xb7e0, 0x6128, 0xa192, 0x00c8, 0x1258, 0x8108,
-	0x612a, 0x6124, 0x00ce, 0x81ff, 0x0198, 0x080c, 0x6a07, 0x080c,
-	0x7d71, 0x0070, 0x6124, 0xa1e5, 0x0000, 0x0140, 0x080c, 0xb444,
-	0x080c, 0x6a10, 0x2009, 0x0014, 0x080c, 0x864c, 0x00ce, 0x0000,
-	0x002e, 0x001e, 0x00de, 0x00ce, 0x0005, 0x2001, 0xb7fc, 0x2004,
-	0xa005, 0x1db0, 0x00c6, 0x2061, 0xb7e0, 0x6128, 0xa192, 0x0003,
-	0x1e08, 0x8108, 0x612a, 0x00ce, 0x080c, 0x6a07, 0x080c, 0x4b1f,
-	0x0c38, 0x00c6, 0x00d6, 0x00e6, 0x0016, 0x0026, 0x080c, 0x6a1d,
-	0x2071, 0xb7e0, 0x713c, 0x81ff, 0x0590, 0x2061, 0x0100, 0x2069,
-	0x0140, 0x080c, 0x5acf, 0x11a8, 0x0036, 0x2019, 0x0002, 0x080c,
-	0x7fe4, 0x003e, 0x713c, 0x2160, 0x080c, 0xb444, 0x2009, 0x004a,
-	0x080c, 0x864c, 0x0066, 0x2031, 0x0001, 0x080c, 0x5b51, 0x006e,
-	0x00b0, 0x6904, 0xa194, 0x4000, 0x01c0, 0x6803, 0x1000, 0x6803,
-	0x0000, 0x0036, 0x2019, 0x0001, 0x080c, 0x7fe4, 0x003e, 0x713c,
-	0x2160, 0x080c, 0xb444, 0x2009, 0x004a, 0x080c, 0x864c, 0x002e,
-	0x001e, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x0c58, 0x0026, 0x00e6,
-	0x2071, 0xb7e0, 0x7048, 0xd084, 0x01c0, 0x713c, 0x81ff, 0x01a8,
-	0x2071, 0x0100, 0xa188, 0x0007, 0x2114, 0xa28e, 0x0006, 0x1138,
-	0x7014, 0xa084, 0x0184, 0xa085, 0x0012, 0x7016, 0x0030, 0x7014,
-	0xa084, 0x0184, 0xa085, 0x0016, 0x7016, 0x00ee, 0x002e, 0x0005,
-	0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0056, 0x0046, 0x0006, 0x0126,
-	0x2091, 0x8000, 0x6018, 0x2068, 0x6ca0, 0x2071, 0xb7e0, 0x7018,
-	0x2068, 0x8dff, 0x0188, 0x68a0, 0xa406, 0x0118, 0x6854, 0x2068,
-	0x0cc0, 0x6010, 0x2060, 0x643c, 0x6540, 0x6648, 0x2d60, 0x080c,
-	0x511a, 0x0110, 0xa085, 0x0001, 0x012e, 0x000e, 0x004e, 0x005e,
-	0x006e, 0x00ce, 0x00de, 0x00ee, 0x0005, 0x20a1, 0x020b, 0x080c,
-	0x7641, 0x20a3, 0x1200, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x781c,
-	0xa086, 0x0004, 0x1110, 0x6098, 0x0018, 0x2001, 0xb515, 0x2004,
-	0x20a2, 0x7834, 0x20a2, 0x7838, 0x20a2, 0x20a9, 0x0010, 0xa006,
-	0x20a2, 0x1f04, 0x7ea0, 0x20a2, 0x20a2, 0x60c3, 0x002c, 0x080c,
-	0x7d67, 0x0005, 0x0156, 0x0146, 0x20a1, 0x020b, 0x080c, 0x7641,
-	0x20a3, 0x0f00, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x7808, 0x20a2,
-	0x60c3, 0x0008, 0x080c, 0x7d67, 0x014e, 0x015e, 0x0005, 0x0156,
-	0x0146, 0x20a1, 0x020b, 0x080c, 0x76dd, 0x20a3, 0x0200, 0x20a3,
-	0x0000, 0x20a9, 0x0006, 0x2011, 0xb540, 0x2019, 0xb541, 0x23a6,
-	0x22a6, 0xa398, 0x0002, 0xa290, 0x0002, 0x1f04, 0x7ecf, 0x20a3,
-	0x0000, 0x20a3, 0x0000, 0x60c3, 0x001c, 0x080c, 0x7d67, 0x014e,
-	0x015e, 0x0005, 0x0156, 0x0146, 0x0016, 0x0026, 0x20a1, 0x020b,
-	0x080c, 0x76b6, 0x080c, 0x76cc, 0x7810, 0xa080, 0x0000, 0x2004,
-	0xa080, 0x0015, 0x2098, 0x7808, 0xa088, 0x0002, 0x21a8, 0x53a6,
-	0xa080, 0x0004, 0x8003, 0x60c2, 0x080c, 0x7d67, 0x002e, 0x001e,
-	0x014e, 0x015e, 0x0005, 0x0156, 0x0146, 0x20a1, 0x020b, 0x080c,
-	0x7641, 0x20a3, 0x6200, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x7808,
-	0x20a2, 0x60c3, 0x0008, 0x080c, 0x7d67, 0x014e, 0x015e, 0x0005,
-	0x0156, 0x0146, 0x0016, 0x0026, 0x20a1, 0x020b, 0x080c, 0x7641,
-	0x7810, 0xa080, 0x0000, 0x2004, 0xa080, 0x0017, 0x2098, 0x7808,
-	0xa088, 0x0002, 0x21a8, 0x53a6, 0x8003, 0x60c2, 0x080c, 0x7d67,
-	0x002e, 0x001e, 0x014e, 0x015e, 0x0005, 0x00e6, 0x00c6, 0x0006,
-	0x0126, 0x2091, 0x8000, 0x2071, 0xb7e0, 0x700c, 0x2060, 0x8cff,
-	0x0178, 0x080c, 0x9e58, 0x1110, 0x080c, 0x8c19, 0x600c, 0x0006,
-	0x080c, 0xa01f, 0x080c, 0x861d, 0x080c, 0x811e, 0x00ce, 0x0c78,
-	0x700f, 0x0000, 0x700b, 0x0000, 0x012e, 0x000e, 0x00ce, 0x00ee,
-	0x0005, 0x0126, 0x0156, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0026,
-	0x0016, 0x0006, 0x2091, 0x8000, 0x2069, 0x0100, 0x2079, 0x0140,
-	0x2071, 0xb7e0, 0x7024, 0x2060, 0x8cff, 0x05a0, 0x080c, 0x7d7a,
-	0x68c3, 0x0000, 0x080c, 0x6a10, 0x2009, 0x0013, 0x080c, 0x864c,
-	0x20a9, 0x01f4, 0x6824, 0xd094, 0x0158, 0x6827, 0x0004, 0x7804,
-	0xa084, 0x4000, 0x01a0, 0x7803, 0x1000, 0x7803, 0x0000, 0x0078,
-	0xd084, 0x0118, 0x6827, 0x0001, 0x0010, 0x1f04, 0x7f7a, 0x7804,
-	0xa084, 0x1000, 0x0120, 0x7803, 0x0100, 0x7803, 0x0000, 0x6824,
-	0x000e, 0x001e, 0x002e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x015e,
-	0x012e, 0x0005, 0x2001, 0xb500, 0x2004, 0xa096, 0x0001, 0x0590,
-	0xa096, 0x0004, 0x0578, 0x080c, 0x6a10, 0x6814, 0xa084, 0x0001,
-	0x0110, 0x68a7, 0x95f5, 0x6817, 0x0008, 0x68c3, 0x0000, 0x2011,
-	0x4adc, 0x080c, 0x699c, 0x20a9, 0x01f4, 0x6824, 0xd094, 0x0158,
-	0x6827, 0x0004, 0x7804, 0xa084, 0x4000, 0x01a0, 0x7803, 0x1000,
-	0x7803, 0x0000, 0x0078, 0xd084, 0x0118, 0x6827, 0x0001, 0x0010,
-	0x1f04, 0x7fbd, 0x7804, 0xa084, 0x1000, 0x0120, 0x7803, 0x0100,
-	0x7803, 0x0000, 0x000e, 0x001e, 0x002e, 0x00ce, 0x00de, 0x00ee,
-	0x00fe, 0x015e, 0x012e, 0x0005, 0x0126, 0x0156, 0x00f6, 0x00e6,
-	0x00d6, 0x00c6, 0x0026, 0x0016, 0x0006, 0x2091, 0x8000, 0x2069,
-	0x0100, 0x2079, 0x0140, 0x2071, 0xb7e0, 0x703c, 0x2060, 0x8cff,
-	0x0904, 0x806b, 0xa386, 0x0002, 0x1128, 0x6814, 0xa084, 0x0002,
-	0x0904, 0x806b, 0x68af, 0x95f5, 0x6817, 0x0010, 0x2009, 0x00fa,
-	0x8109, 0x1df0, 0x68c7, 0x0000, 0x68cb, 0x0008, 0x080c, 0x6a1d,
-	0x080c, 0x220c, 0x0046, 0x2009, 0x017f, 0x200b, 0x00a5, 0x2021,
-	0x0169, 0x2404, 0xa084, 0x000f, 0xa086, 0x0004, 0x1500, 0x68af,
-	0x95f5, 0x68c7, 0x0000, 0x68cb, 0x0008, 0x00e6, 0x00f6, 0x2079,
-	0x0020, 0x2071, 0xb84a, 0x6814, 0xa084, 0x0184, 0xa085, 0x0012,
-	0x6816, 0x7803, 0x0008, 0x7003, 0x0000, 0x00fe, 0x00ee, 0xa386,
-	0x0002, 0x1128, 0x7884, 0xa005, 0x1110, 0x7887, 0x0001, 0x2001,
-	0xb7b1, 0x2004, 0x200a, 0x004e, 0xa39d, 0x0000, 0x1120, 0x2009,
-	0x0049, 0x080c, 0x864c, 0x20a9, 0x03e8, 0x6824, 0xd094, 0x0158,
-	0x6827, 0x0004, 0x7804, 0xa084, 0x4000, 0x01a0, 0x7803, 0x1000,
-	0x7803, 0x0000, 0x0078, 0xd08c, 0x0118, 0x6827, 0x0002, 0x0010,
-	0x1f04, 0x804d, 0x7804, 0xa084, 0x1000, 0x0120, 0x7803, 0x0100,
-	0x7803, 0x0000, 0x6824, 0x000e, 0x001e, 0x002e, 0x00ce, 0x00de,
-	0x00ee, 0x00fe, 0x015e, 0x012e, 0x0005, 0x00d6, 0x0126, 0x2091,
-	0x8000, 0x2069, 0xb7e0, 0x6a06, 0x012e, 0x00de, 0x0005, 0x00d6,
-	0x0126, 0x2091, 0x8000, 0x2069, 0xb7e0, 0x6a32, 0x012e, 0x00de,
-	0x0005, 0x00f6, 0x00e6, 0x00c6, 0x0066, 0x0006, 0x0126, 0x2071,
-	0xb7e0, 0x7614, 0x2660, 0x2678, 0x2091, 0x8000, 0x8cff, 0x0538,
-	0x601c, 0xa206, 0x1500, 0x7014, 0xac36, 0x1110, 0x660c, 0x7616,
-	0x7010, 0xac36, 0x1140, 0x2c00, 0xaf36, 0x0118, 0x2f00, 0x7012,
-	0x0010, 0x7013, 0x0000, 0x660c, 0x0066, 0x2c00, 0xaf06, 0x0110,
-	0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0x080c, 0x9e1d, 0x080c,
-	0x811e, 0x00ce, 0x08d8, 0x2c78, 0x600c, 0x2060, 0x08b8, 0x012e,
-	0x000e, 0x006e, 0x00ce, 0x00ee, 0x00fe, 0x0005, 0x0156, 0x0146,
-	0x20a1, 0x020b, 0x080c, 0x7902, 0x7810, 0x20a2, 0xa006, 0x20a2,
-	0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x1000, 0x0804, 0x8116, 0x0156,
-	0x0146, 0x20a1, 0x020b, 0x080c, 0x7902, 0x7810, 0x20a2, 0xa006,
-	0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x4000, 0x0478, 0x0156,
-	0x0146, 0x20a1, 0x020b, 0x080c, 0x7902, 0x7810, 0x20a2, 0xa006,
-	0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x2000, 0x00f8, 0x0156,
-	0x0146, 0x20a1, 0x020b, 0x080c, 0x7902, 0x7810, 0x20a2, 0xa006,
-	0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x0400, 0x0078, 0x0156,
-	0x0146, 0x20a1, 0x020b, 0x080c, 0x7902, 0x7810, 0x20a2, 0xa006,
-	0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x0200, 0x0089, 0x60c3,
-	0x0020, 0x080c, 0x7d67, 0x014e, 0x015e, 0x0005, 0x00e6, 0x2071,
-	0xb7e0, 0x7020, 0xa005, 0x0110, 0x8001, 0x7022, 0x00ee, 0x0005,
-	0x20a9, 0x0008, 0x20a2, 0x1f04, 0x812a, 0x20a2, 0x20a2, 0x0005,
-	0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0076, 0x0066, 0x0006, 0x0126,
-	0x2091, 0x8000, 0x2071, 0xb7e0, 0x7614, 0x2660, 0x2678, 0x2039,
-	0x0001, 0x87ff, 0x0904, 0x81c6, 0x8cff, 0x0904, 0x81c6, 0x601c,
-	0xa086, 0x0006, 0x1904, 0x81c1, 0x88ff, 0x0138, 0x2800, 0xac06,
-	0x1904, 0x81c1, 0x2039, 0x0000, 0x0050, 0x6018, 0xa206, 0x1904,
-	0x81c1, 0x85ff, 0x0120, 0x6050, 0xa106, 0x1904, 0x81c1, 0x7024,
-	0xac06, 0x1598, 0x2069, 0x0100, 0x68c0, 0xa005, 0x1160, 0x6824,
-	0xd084, 0x0148, 0x6827, 0x0001, 0x080c, 0x6a10, 0x080c, 0x824d,
-	0x7027, 0x0000, 0x0410, 0x080c, 0x6a10, 0x6820, 0xd0b4, 0x0110,
-	0x68a7, 0x95f5, 0x6817, 0x0008, 0x68c3, 0x0000, 0x080c, 0x824d,
-	0x7027, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0xa384, 0x1000,
-	0x0120, 0x6803, 0x0100, 0x6803, 0x0000, 0x2069, 0x0100, 0x6824,
-	0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x7014, 0xac36, 0x1110,
-	0x660c, 0x7616, 0x7010, 0xac36, 0x1140, 0x2c00, 0xaf36, 0x0118,
-	0x2f00, 0x7012, 0x0010, 0x7013, 0x0000, 0x660c, 0x0066, 0x2c00,
-	0xaf06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x89ff, 0x1158, 0x600f,
-	0x0000, 0x6010, 0x2068, 0x080c, 0x9c5a, 0x0110, 0x080c, 0xb099,
-	0x080c, 0x9e1d, 0x080c, 0x811e, 0x88ff, 0x1190, 0x00ce, 0x0804,
-	0x8141, 0x2c78, 0x600c, 0x2060, 0x0804, 0x8141, 0xa006, 0x012e,
-	0x000e, 0x006e, 0x007e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x0005,
-	0x6017, 0x0000, 0x00ce, 0xa8c5, 0x0001, 0x0c88, 0x00f6, 0x00e6,
-	0x00d6, 0x00c6, 0x0066, 0x0026, 0x0006, 0x0126, 0x2091, 0x8000,
-	0x2071, 0xb7e0, 0x7638, 0x2660, 0x2678, 0x8cff, 0x0904, 0x823d,
-	0x601c, 0xa086, 0x0006, 0x1904, 0x8238, 0x87ff, 0x0128, 0x2700,
-	0xac06, 0x1904, 0x8238, 0x0048, 0x6018, 0xa206, 0x1904, 0x8238,
-	0x85ff, 0x0118, 0x6050, 0xa106, 0x15d8, 0x703c, 0xac06, 0x1180,
-	0x0036, 0x2019, 0x0001, 0x080c, 0x7fe4, 0x7033, 0x0000, 0x703f,
-	0x0000, 0x7043, 0x0000, 0x7047, 0x0000, 0x704b, 0x0000, 0x003e,
+	0x609f, 0x0000, 0x080c, 0x8640, 0x2009, 0x07d0, 0x60c4, 0xa084,
+	0xfff0, 0xa005, 0x0110, 0x2009, 0x1b58, 0x080c, 0x6a87, 0x003e,
+	0x004e, 0x005e, 0x00ce, 0x00de, 0x00ee, 0x0005, 0x70d4, 0xd0ac,
+	0x1110, 0xd5bc, 0x0138, 0xa185, 0x0100, 0x6062, 0x6266, 0x636a,
+	0x646e, 0x0038, 0xa185, 0x0100, 0x6062, 0x6266, 0x606b, 0x0000,
+	0x646e, 0x6073, 0x0809, 0x6077, 0x0008, 0x688c, 0x8000, 0xa084,
+	0x00ff, 0x688e, 0x8007, 0x607a, 0x607f, 0x0000, 0x2f00, 0x6082,
+	0x7808, 0x6086, 0x7810, 0x2070, 0x7014, 0x608a, 0x7010, 0x608e,
+	0x700c, 0x60c6, 0x7008, 0x60ca, 0x792c, 0xa108, 0x792e, 0x700c,
+	0x7928, 0xa109, 0x792a, 0x686c, 0x60ce, 0x60af, 0x95d5, 0x60d7,
+	0x0000, 0xa582, 0x0080, 0x0248, 0x6a00, 0xd2f4, 0x0120, 0x6a14,
+	0xa294, 0x00ff, 0x0010, 0x2011, 0x0000, 0x629e, 0x080c, 0x8640,
+	0x2009, 0x07d0, 0x60c4, 0xa084, 0xfff0, 0xa005, 0x0110, 0x2009,
+	0x1b58, 0x080c, 0x6a87, 0x003e, 0x004e, 0x005e, 0x00ce, 0x00de,
+	0x00ee, 0x0005, 0x7810, 0x2070, 0x704c, 0xa084, 0x0003, 0xa086,
+	0x0002, 0x0904, 0x7d70, 0x2001, 0xb635, 0x2004, 0xd0ac, 0x1110,
+	0xd5bc, 0x0138, 0xa185, 0x0100, 0x6062, 0x6266, 0x636a, 0x646e,
+	0x0038, 0xa185, 0x0100, 0x6062, 0x6266, 0x606b, 0x0000, 0x646e,
+	0x6073, 0x0880, 0x6077, 0x0008, 0x688c, 0x8000, 0xa084, 0x00ff,
+	0x688e, 0x8007, 0x607a, 0x7834, 0x607e, 0x2f00, 0x6086, 0x7808,
+	0x6082, 0x7060, 0x608a, 0x705c, 0x608e, 0x7080, 0x60c6, 0x707c,
+	0x60ca, 0x707c, 0x792c, 0xa108, 0x792e, 0x7080, 0x7928, 0xa109,
+	0x792a, 0x686c, 0x60ce, 0x60af, 0x95d5, 0x60d7, 0x0000, 0xa582,
+	0x0080, 0x0248, 0x6a00, 0xd2f4, 0x0120, 0x6a14, 0xa294, 0x00ff,
+	0x0010, 0x2011, 0x0000, 0x629e, 0x080c, 0x863d, 0x0804, 0x7d08,
+	0x2001, 0xb635, 0x2004, 0xd0ac, 0x1110, 0xd5bc, 0x0138, 0xa185,
+	0x0700, 0x6062, 0x6266, 0x636a, 0x646e, 0x0038, 0xa185, 0x0700,
+	0x6062, 0x6266, 0x606b, 0x0000, 0x646e, 0x080c, 0x5373, 0x0180,
+	0x00d6, 0x7810, 0xa06d, 0x684c, 0x00de, 0xa084, 0x2020, 0xa086,
+	0x2020, 0x1130, 0x7820, 0xc0cd, 0x7822, 0x6073, 0x0889, 0x0010,
+	0x6073, 0x0898, 0x6077, 0x0000, 0x688c, 0x8000, 0xa084, 0x00ff,
+	0x688e, 0x8007, 0x607a, 0x607f, 0x0000, 0x2f00, 0x6086, 0x7808,
+	0x6082, 0x7014, 0x608a, 0x7010, 0x608e, 0x700c, 0x60c6, 0x7008,
+	0x60ca, 0x686c, 0x60ce, 0x60af, 0x95d5, 0x60d7, 0x0000, 0xa582,
+	0x0080, 0x0248, 0x6a00, 0xd2f4, 0x0120, 0x6a14, 0xa294, 0x00ff,
+	0x0010, 0x2011, 0x0000, 0x629e, 0x7820, 0xd0cc, 0x0120, 0x080c,
+	0x8640, 0x0804, 0x7d08, 0x080c, 0x863d, 0x0804, 0x7d08, 0x7a18,
+	0xa280, 0x0023, 0x2014, 0x8210, 0xa294, 0x00ff, 0x2202, 0x8217,
+	0x0005, 0x00d6, 0x2069, 0xb8e1, 0x6843, 0x0001, 0x00de, 0x0005,
+	0x20e1, 0x9080, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x0019, 0x080c,
+	0x6a79, 0x0005, 0x0006, 0x6014, 0xa084, 0x0004, 0xa085, 0x0009,
+	0x6016, 0x000e, 0x0005, 0x0016, 0x00c6, 0x0006, 0x2061, 0x0100,
+	0x61a4, 0x60a7, 0x95f5, 0x6014, 0xa084, 0x0004, 0xa085, 0x0008,
+	0x6016, 0x000e, 0xe000, 0xe000, 0xe000, 0xe000, 0x61a6, 0x00ce,
+	0x001e, 0x0005, 0x00c6, 0x00d6, 0x0016, 0x0026, 0x2061, 0x0100,
+	0x2069, 0x0140, 0x080c, 0x5b41, 0x1198, 0x2001, 0xb8fd, 0x2004,
+	0xa005, 0x15b8, 0x0066, 0x2031, 0x0001, 0x080c, 0x5bc3, 0x006e,
+	0x1118, 0x080c, 0x6a79, 0x0468, 0x00c6, 0x2061, 0xb8e1, 0x00d8,
+	0x6904, 0xa194, 0x4000, 0x0550, 0x0831, 0x6803, 0x1000, 0x6803,
+	0x0000, 0x00c6, 0x2061, 0xb8e1, 0x6128, 0xa192, 0x00c8, 0x1258,
+	0x8108, 0x612a, 0x6124, 0x00ce, 0x81ff, 0x0198, 0x080c, 0x6a79,
+	0x080c, 0x7dea, 0x0070, 0x6124, 0xa1e5, 0x0000, 0x0140, 0x080c,
+	0xb500, 0x080c, 0x6a82, 0x2009, 0x0014, 0x080c, 0x86d3, 0x00ce,
+	0x0000, 0x002e, 0x001e, 0x00de, 0x00ce, 0x0005, 0x2001, 0xb8fd,
+	0x2004, 0xa005, 0x1db0, 0x00c6, 0x2061, 0xb8e1, 0x6128, 0xa192,
+	0x0003, 0x1e08, 0x8108, 0x612a, 0x00ce, 0x080c, 0x6a79, 0x080c,
+	0x4b7b, 0x0c38, 0x00c6, 0x00d6, 0x00e6, 0x0016, 0x0026, 0x080c,
+	0x6a8f, 0x2071, 0xb8e1, 0x713c, 0x81ff, 0x0590, 0x2061, 0x0100,
+	0x2069, 0x0140, 0x080c, 0x5b41, 0x11a8, 0x0036, 0x2019, 0x0002,
+	0x080c, 0x806b, 0x003e, 0x713c, 0x2160, 0x080c, 0xb500, 0x2009,
+	0x004a, 0x080c, 0x86d3, 0x0066, 0x2031, 0x0001, 0x080c, 0x5bc3,
+	0x006e, 0x00b0, 0x6904, 0xa194, 0x4000, 0x01c0, 0x6803, 0x1000,
+	0x6803, 0x0000, 0x0036, 0x2019, 0x0001, 0x080c, 0x806b, 0x003e,
+	0x713c, 0x2160, 0x080c, 0xb500, 0x2009, 0x004a, 0x080c, 0x86d3,
+	0x002e, 0x001e, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x0c58, 0x0026,
+	0x00e6, 0x2071, 0xb8e1, 0x7048, 0xd084, 0x01c0, 0x713c, 0x81ff,
+	0x01a8, 0x2071, 0x0100, 0xa188, 0x0007, 0x2114, 0xa28e, 0x0006,
+	0x1138, 0x7014, 0xa084, 0x0184, 0xa085, 0x0012, 0x7016, 0x0030,
+	0x7014, 0xa084, 0x0184, 0xa085, 0x0016, 0x7016, 0x00ee, 0x002e,
+	0x0005, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0056, 0x0046, 0x0006,
+	0x0126, 0x2091, 0x8000, 0x6018, 0x2068, 0x6ca0, 0x2071, 0xb8e1,
+	0x7018, 0x2068, 0x8dff, 0x0188, 0x68a0, 0xa406, 0x0118, 0x6854,
+	0x2068, 0x0cc0, 0x6010, 0x2060, 0x643c, 0x6540, 0x6648, 0x2d60,
+	0x080c, 0x518c, 0x0110, 0xa085, 0x0001, 0x012e, 0x000e, 0x004e,
+	0x005e, 0x006e, 0x00ce, 0x00de, 0x00ee, 0x0005, 0x20a1, 0x020b,
+	0x080c, 0x76b3, 0x20a3, 0x1200, 0x20a3, 0x0000, 0x20a3, 0x0000,
+	0x781c, 0xa086, 0x0004, 0x1110, 0x6098, 0x0018, 0x2001, 0xb615,
+	0x2004, 0x20a2, 0x7834, 0x20a2, 0x7838, 0x20a2, 0x20a9, 0x0010,
+	0xa006, 0x20a2, 0x1f04, 0x7f19, 0x20a2, 0x20a2, 0x60c3, 0x002c,
+	0x080c, 0x7de0, 0x0005, 0x0156, 0x0146, 0x20a1, 0x020b, 0x080c,
+	0x76b3, 0x20a3, 0x0f00, 0x20a3, 0x0000, 0x7808, 0xd09c, 0x1150,
+	0x20a3, 0x0000, 0x20a2, 0x60c3, 0x0008, 0x080c, 0x7de0, 0x014e,
+	0x015e, 0x0005, 0x00d6, 0x7818, 0xa06d, 0x090c, 0x151a, 0x6810,
+	0xa084, 0x00ff, 0x20a2, 0x6814, 0x00de, 0x0c60, 0x0156, 0x0146,
+	0x20a1, 0x020b, 0x080c, 0x774f, 0x20a3, 0x0200, 0x20a3, 0x0000,
+	0x20a9, 0x0006, 0x2011, 0xb640, 0x2019, 0xb641, 0x23a6, 0x22a6,
+	0xa398, 0x0002, 0xa290, 0x0002, 0x1f04, 0x7f56, 0x20a3, 0x0000,
+	0x20a3, 0x0000, 0x60c3, 0x001c, 0x080c, 0x7de0, 0x014e, 0x015e,
+	0x0005, 0x0156, 0x0146, 0x0016, 0x0026, 0x20a1, 0x020b, 0x080c,
+	0x7728, 0x080c, 0x773e, 0x7810, 0xa080, 0x0000, 0x2004, 0xa080,
+	0x0015, 0x2098, 0x7808, 0xa088, 0x0002, 0x21a8, 0x53a6, 0xa080,
+	0x0004, 0x8003, 0x60c2, 0x080c, 0x7de0, 0x002e, 0x001e, 0x014e,
+	0x015e, 0x0005, 0x0156, 0x0146, 0x20a1, 0x020b, 0x080c, 0x76b3,
+	0x20a3, 0x6200, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x7808, 0x20a2,
+	0x60c3, 0x0008, 0x080c, 0x7de0, 0x014e, 0x015e, 0x0005, 0x0156,
+	0x0146, 0x0016, 0x0026, 0x20a1, 0x020b, 0x080c, 0x76b3, 0x7810,
+	0xa080, 0x0000, 0x2004, 0xa080, 0x0017, 0x2098, 0x7808, 0xa088,
+	0x0002, 0x21a8, 0x53a6, 0x8003, 0x60c2, 0x080c, 0x7de0, 0x002e,
+	0x001e, 0x014e, 0x015e, 0x0005, 0x00e6, 0x00c6, 0x0006, 0x0126,
+	0x2091, 0x8000, 0x2071, 0xb8e1, 0x700c, 0x2060, 0x8cff, 0x0178,
+	0x080c, 0x9f14, 0x1110, 0x080c, 0x8ca5, 0x600c, 0x0006, 0x080c,
+	0xa0db, 0x080c, 0x86a4, 0x080c, 0x81a5, 0x00ce, 0x0c78, 0x700f,
+	0x0000, 0x700b, 0x0000, 0x012e, 0x000e, 0x00ce, 0x00ee, 0x0005,
+	0x0126, 0x0156, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0026, 0x0016,
+	0x0006, 0x2091, 0x8000, 0x2069, 0x0100, 0x2079, 0x0140, 0x2071,
+	0xb8e1, 0x7024, 0x2060, 0x8cff, 0x05a0, 0x080c, 0x7df3, 0x68c3,
+	0x0000, 0x080c, 0x6a82, 0x2009, 0x0013, 0x080c, 0x86d3, 0x20a9,
+	0x01f4, 0x6824, 0xd094, 0x0158, 0x6827, 0x0004, 0x7804, 0xa084,
+	0x4000, 0x01a0, 0x7803, 0x1000, 0x7803, 0x0000, 0x0078, 0xd084,
+	0x0118, 0x6827, 0x0001, 0x0010, 0x1f04, 0x8001, 0x7804, 0xa084,
+	0x1000, 0x0120, 0x7803, 0x0100, 0x7803, 0x0000, 0x6824, 0x000e,
+	0x001e, 0x002e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x015e, 0x012e,
+	0x0005, 0x2001, 0xb600, 0x2004, 0xa096, 0x0001, 0x0590, 0xa096,
+	0x0004, 0x0578, 0x080c, 0x6a82, 0x6814, 0xa084, 0x0001, 0x0110,
+	0x68a7, 0x95f5, 0x6817, 0x0008, 0x68c3, 0x0000, 0x2011, 0x4b23,
+	0x080c, 0x6a0e, 0x20a9, 0x01f4, 0x6824, 0xd094, 0x0158, 0x6827,
+	0x0004, 0x7804, 0xa084, 0x4000, 0x01a0, 0x7803, 0x1000, 0x7803,
+	0x0000, 0x0078, 0xd084, 0x0118, 0x6827, 0x0001, 0x0010, 0x1f04,
+	0x8044, 0x7804, 0xa084, 0x1000, 0x0120, 0x7803, 0x0100, 0x7803,
+	0x0000, 0x000e, 0x001e, 0x002e, 0x00ce, 0x00de, 0x00ee, 0x00fe,
+	0x015e, 0x012e, 0x0005, 0x0126, 0x0156, 0x00f6, 0x00e6, 0x00d6,
+	0x00c6, 0x0026, 0x0016, 0x0006, 0x2091, 0x8000, 0x2069, 0x0100,
+	0x2079, 0x0140, 0x2071, 0xb8e1, 0x703c, 0x2060, 0x8cff, 0x0904,
+	0x80f2, 0xa386, 0x0002, 0x1128, 0x6814, 0xa084, 0x0002, 0x0904,
+	0x80f2, 0x68af, 0x95f5, 0x6817, 0x0010, 0x2009, 0x00fa, 0x8109,
+	0x1df0, 0x68c7, 0x0000, 0x68cb, 0x0008, 0x080c, 0x6a8f, 0x080c,
+	0x222f, 0x0046, 0x2009, 0x017f, 0x200b, 0x00a5, 0x2021, 0x0169,
+	0x2404, 0xa084, 0x000f, 0xa086, 0x0004, 0x1500, 0x68af, 0x95f5,
+	0x68c7, 0x0000, 0x68cb, 0x0008, 0x00e6, 0x00f6, 0x2079, 0x0020,
+	0x2071, 0xb94b, 0x6814, 0xa084, 0x0184, 0xa085, 0x0012, 0x6816,
+	0x7803, 0x0008, 0x7003, 0x0000, 0x00fe, 0x00ee, 0xa386, 0x0002,
+	0x1128, 0x7884, 0xa005, 0x1110, 0x7887, 0x0001, 0x2001, 0xb8b1,
+	0x2004, 0x200a, 0x004e, 0xa39d, 0x0000, 0x1120, 0x2009, 0x0049,
+	0x080c, 0x86d3, 0x20a9, 0x03e8, 0x6824, 0xd094, 0x0158, 0x6827,
+	0x0004, 0x7804, 0xa084, 0x4000, 0x01a0, 0x7803, 0x1000, 0x7803,
+	0x0000, 0x0078, 0xd08c, 0x0118, 0x6827, 0x0002, 0x0010, 0x1f04,
+	0x80d4, 0x7804, 0xa084, 0x1000, 0x0120, 0x7803, 0x0100, 0x7803,
+	0x0000, 0x6824, 0x000e, 0x001e, 0x002e, 0x00ce, 0x00de, 0x00ee,
+	0x00fe, 0x015e, 0x012e, 0x0005, 0x00d6, 0x0126, 0x2091, 0x8000,
+	0x2069, 0xb8e1, 0x6a06, 0x012e, 0x00de, 0x0005, 0x00d6, 0x0126,
+	0x2091, 0x8000, 0x2069, 0xb8e1, 0x6a32, 0x012e, 0x00de, 0x0005,
+	0x00f6, 0x00e6, 0x00c6, 0x0066, 0x0006, 0x0126, 0x2071, 0xb8e1,
+	0x7614, 0x2660, 0x2678, 0x2091, 0x8000, 0x8cff, 0x0538, 0x601c,
+	0xa206, 0x1500, 0x7014, 0xac36, 0x1110, 0x660c, 0x7616, 0x7010,
+	0xac36, 0x1140, 0x2c00, 0xaf36, 0x0118, 0x2f00, 0x7012, 0x0010,
+	0x7013, 0x0000, 0x660c, 0x0066, 0x2c00, 0xaf06, 0x0110, 0x7e0e,
+	0x0008, 0x2678, 0x600f, 0x0000, 0x080c, 0x9ed9, 0x080c, 0x81a5,
+	0x00ce, 0x08d8, 0x2c78, 0x600c, 0x2060, 0x08b8, 0x012e, 0x000e,
+	0x006e, 0x00ce, 0x00ee, 0x00fe, 0x0005, 0x0156, 0x0146, 0x20a1,
+	0x020b, 0x080c, 0x7974, 0x7810, 0x20a2, 0xa006, 0x20a2, 0x20a2,
+	0x20a2, 0x20a2, 0x20a3, 0x1000, 0x0804, 0x819d, 0x0156, 0x0146,
+	0x20a1, 0x020b, 0x080c, 0x7974, 0x7810, 0x20a2, 0xa006, 0x20a2,
+	0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x4000, 0x0478, 0x0156, 0x0146,
+	0x20a1, 0x020b, 0x080c, 0x7974, 0x7810, 0x20a2, 0xa006, 0x20a2,
+	0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x2000, 0x00f8, 0x0156, 0x0146,
+	0x20a1, 0x020b, 0x080c, 0x7974, 0x7810, 0x20a2, 0xa006, 0x20a2,
+	0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x0400, 0x0078, 0x0156, 0x0146,
+	0x20a1, 0x020b, 0x080c, 0x7974, 0x7810, 0x20a2, 0xa006, 0x20a2,
+	0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x0200, 0x0089, 0x60c3, 0x0020,
+	0x080c, 0x7de0, 0x014e, 0x015e, 0x0005, 0x00e6, 0x2071, 0xb8e1,
+	0x7020, 0xa005, 0x0110, 0x8001, 0x7022, 0x00ee, 0x0005, 0x20a9,
+	0x0008, 0x20a2, 0x1f04, 0x81b1, 0x20a2, 0x20a2, 0x0005, 0x00f6,
+	0x00e6, 0x00d6, 0x00c6, 0x0076, 0x0066, 0x0006, 0x0126, 0x2091,
+	0x8000, 0x2071, 0xb8e1, 0x7614, 0x2660, 0x2678, 0x2039, 0x0001,
+	0x87ff, 0x0904, 0x824d, 0x8cff, 0x0904, 0x824d, 0x601c, 0xa086,
+	0x0006, 0x1904, 0x8248, 0x88ff, 0x0138, 0x2800, 0xac06, 0x1904,
+	0x8248, 0x2039, 0x0000, 0x0050, 0x6018, 0xa206, 0x1904, 0x8248,
+	0x85ff, 0x0120, 0x6050, 0xa106, 0x1904, 0x8248, 0x7024, 0xac06,
+	0x1598, 0x2069, 0x0100, 0x68c0, 0xa005, 0x1160, 0x6824, 0xd084,
+	0x0148, 0x6827, 0x0001, 0x080c, 0x6a82, 0x080c, 0x82d4, 0x7027,
+	0x0000, 0x0410, 0x080c, 0x6a82, 0x6820, 0xd0b4, 0x0110, 0x68a7,
+	0x95f5, 0x6817, 0x0008, 0x68c3, 0x0000, 0x080c, 0x82d4, 0x7027,
+	0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0xa384, 0x1000, 0x0120,
+	0x6803, 0x0100, 0x6803, 0x0000, 0x2069, 0x0100, 0x6824, 0xd084,
+	0x0110, 0x6827, 0x0001, 0x003e, 0x7014, 0xac36, 0x1110, 0x660c,
+	0x7616, 0x7010, 0xac36, 0x1140, 0x2c00, 0xaf36, 0x0118, 0x2f00,
+	0x7012, 0x0010, 0x7013, 0x0000, 0x660c, 0x0066, 0x2c00, 0xaf06,
+	0x0110, 0x7e0e, 0x0008, 0x2678, 0x89ff, 0x1158, 0x600f, 0x0000,
+	0x6010, 0x2068, 0x080c, 0x9d16, 0x0110, 0x080c, 0xb155, 0x080c,
+	0x9ed9, 0x080c, 0x81a5, 0x88ff, 0x1190, 0x00ce, 0x0804, 0x81c8,
+	0x2c78, 0x600c, 0x2060, 0x0804, 0x81c8, 0xa006, 0x012e, 0x000e,
+	0x006e, 0x007e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x6017,
+	0x0000, 0x00ce, 0xa8c5, 0x0001, 0x0c88, 0x00f6, 0x00e6, 0x00d6,
+	0x00c6, 0x0066, 0x0026, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071,
+	0xb8e1, 0x7638, 0x2660, 0x2678, 0x8cff, 0x0904, 0x82c4, 0x601c,
+	0xa086, 0x0006, 0x1904, 0x82bf, 0x87ff, 0x0128, 0x2700, 0xac06,
+	0x1904, 0x82bf, 0x0048, 0x6018, 0xa206, 0x1904, 0x82bf, 0x85ff,
+	0x0118, 0x6050, 0xa106, 0x15d8, 0x703c, 0xac06, 0x1180, 0x0036,
+	0x2019, 0x0001, 0x080c, 0x806b, 0x7033, 0x0000, 0x703f, 0x0000,
+	0x7043, 0x0000, 0x7047, 0x0000, 0x704b, 0x0000, 0x003e, 0x7038,
+	0xac36, 0x1110, 0x660c, 0x763a, 0x7034, 0xac36, 0x1140, 0x2c00,
+	0xaf36, 0x0118, 0x2f00, 0x7036, 0x0010, 0x7037, 0x0000, 0x660c,
+	0x0066, 0x2c00, 0xaf06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f,
+	0x0000, 0x6010, 0x2068, 0x080c, 0x9d16, 0x0110, 0x080c, 0xb155,
+	0x080c, 0x9ed9, 0x87ff, 0x1190, 0x00ce, 0x0804, 0x826c, 0x2c78,
+	0x600c, 0x2060, 0x0804, 0x826c, 0xa006, 0x012e, 0x000e, 0x002e,
+	0x006e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x6017, 0x0000,
+	0x00ce, 0xa7bd, 0x0001, 0x0c88, 0x00e6, 0x2071, 0xb8e1, 0x2001,
+	0xb600, 0x2004, 0xa086, 0x0002, 0x1118, 0x7007, 0x0005, 0x0010,
+	0x7007, 0x0000, 0x00ee, 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x0066,
+	0x0026, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0xb8e1, 0x2c10,
+	0x7638, 0x2660, 0x2678, 0x8cff, 0x0518, 0x2200, 0xac06, 0x11e0,
 	0x7038, 0xac36, 0x1110, 0x660c, 0x763a, 0x7034, 0xac36, 0x1140,
 	0x2c00, 0xaf36, 0x0118, 0x2f00, 0x7036, 0x0010, 0x7037, 0x0000,
-	0x660c, 0x0066, 0x2c00, 0xaf06, 0x0110, 0x7e0e, 0x0008, 0x2678,
-	0x600f, 0x0000, 0x6010, 0x2068, 0x080c, 0x9c5a, 0x0110, 0x080c,
-	0xb099, 0x080c, 0x9e1d, 0x87ff, 0x1190, 0x00ce, 0x0804, 0x81e5,
-	0x2c78, 0x600c, 0x2060, 0x0804, 0x81e5, 0xa006, 0x012e, 0x000e,
-	0x002e, 0x006e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x6017,
-	0x0000, 0x00ce, 0xa7bd, 0x0001, 0x0c88, 0x00e6, 0x2071, 0xb7e0,
-	0x2001, 0xb500, 0x2004, 0xa086, 0x0002, 0x1118, 0x7007, 0x0005,
-	0x0010, 0x7007, 0x0000, 0x00ee, 0x0005, 0x00f6, 0x00e6, 0x00c6,
-	0x0066, 0x0026, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0xb7e0,
-	0x2c10, 0x7638, 0x2660, 0x2678, 0x8cff, 0x0518, 0x2200, 0xac06,
-	0x11e0, 0x7038, 0xac36, 0x1110, 0x660c, 0x763a, 0x7034, 0xac36,
-	0x1140, 0x2c00, 0xaf36, 0x0118, 0x2f00, 0x7036, 0x0010, 0x7037,
-	0x0000, 0x660c, 0x2c00, 0xaf06, 0x0110, 0x7e0e, 0x0008, 0x2678,
-	0x600f, 0x0000, 0xa085, 0x0001, 0x0020, 0x2c78, 0x600c, 0x2060,
-	0x08d8, 0x012e, 0x000e, 0x002e, 0x006e, 0x00ce, 0x00ee, 0x00fe,
-	0x0005, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0006, 0x0126,
-	0x2091, 0x8000, 0x2071, 0xb7e0, 0x760c, 0x2660, 0x2678, 0x8cff,
-	0x0904, 0x8323, 0x6018, 0xa080, 0x0028, 0x2004, 0xa206, 0x1904,
-	0x831e, 0x7024, 0xac06, 0x1508, 0x2069, 0x0100, 0x68c0, 0xa005,
-	0x0904, 0x82fa, 0x080c, 0x7d7a, 0x68c3, 0x0000, 0x080c, 0x824d,
-	0x7027, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0xa384, 0x1000,
-	0x0120, 0x6803, 0x0100, 0x6803, 0x0000, 0x2069, 0x0100, 0x6824,
-	0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x700c, 0xac36, 0x1110,
-	0x660c, 0x760e, 0x7008, 0xac36, 0x1140, 0x2c00, 0xaf36, 0x0118,
-	0x2f00, 0x700a, 0x0010, 0x700b, 0x0000, 0x660c, 0x0066, 0x2c00,
-	0xaf06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0x080c,
-	0x9e47, 0x1158, 0x080c, 0x2cc2, 0x080c, 0x9e58, 0x11f0, 0x080c,
-	0x8c19, 0x00d8, 0x080c, 0x824d, 0x08c0, 0x080c, 0x9e58, 0x1118,
-	0x080c, 0x8c19, 0x0090, 0x6010, 0x2068, 0x080c, 0x9c5a, 0x0168,
-	0x601c, 0xa086, 0x0003, 0x11f8, 0x6837, 0x0103, 0x6b4a, 0x6847,
-	0x0000, 0x080c, 0x5408, 0x080c, 0x9e11, 0x080c, 0xa01f, 0x080c,
-	0x9e1d, 0x080c, 0x811e, 0x00ce, 0x0804, 0x82a7, 0x2c78, 0x600c,
-	0x2060, 0x0804, 0x82a7, 0x012e, 0x000e, 0x006e, 0x00ce, 0x00de,
-	0x00ee, 0x00fe, 0x0005, 0x601c, 0xa086, 0x0006, 0x1d30, 0x080c,
-	0xb099, 0x0c18, 0x0036, 0x0156, 0x0136, 0x0146, 0x3908, 0xa006,
-	0xa190, 0x0020, 0x221c, 0xa39e, 0x2ab7, 0x1118, 0x8210, 0x8000,
-	0x0cc8, 0xa005, 0x0138, 0x20a9, 0x0020, 0x2198, 0xa110, 0x22a0,
-	0x22c8, 0x53a3, 0x014e, 0x013e, 0x015e, 0x003e, 0x0005, 0x00d6,
-	0x20a1, 0x020b, 0x080c, 0x76dd, 0x20a3, 0x0200, 0x20a3, 0x0014,
-	0x60c3, 0x0014, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x2099, 0xb7b9,
-	0x20a9, 0x0004, 0x53a6, 0x20a3, 0x0004, 0x20a3, 0x7878, 0x20a3,
-	0x0000, 0x20a3, 0x0000, 0x080c, 0x7d67, 0x00de, 0x0005, 0x20a1,
-	0x020b, 0x080c, 0x76dd, 0x20a3, 0x0214, 0x20a3, 0x0018, 0x20a3,
-	0x0800, 0x7810, 0xa084, 0xff00, 0x20a2, 0x20a3, 0x0000, 0x20a3,
-	0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x7810, 0xa084, 0x00ff,
-	0x20a2, 0x7828, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3,
-	0x0018, 0x080c, 0x7d67, 0x0005, 0x00d6, 0x0016, 0x2f68, 0x2009,
-	0x0035, 0x080c, 0xa10a, 0x1904, 0x8402, 0x20a1, 0x020b, 0x080c,
-	0x7641, 0x20a3, 0x1300, 0x20a3, 0x0000, 0x7828, 0x2068, 0x681c,
-	0xa086, 0x0003, 0x0580, 0x7818, 0xa080, 0x0028, 0x2014, 0x2001,
-	0xb535, 0x2004, 0xd0ac, 0x11d0, 0xa286, 0x007e, 0x1128, 0x20a3,
-	0x00ff, 0x20a3, 0xfffe, 0x04b8, 0xa286, 0x007f, 0x1128, 0x20a3,
-	0x00ff, 0x20a3, 0xfffd, 0x0478, 0xd2bc, 0x0180, 0xa286, 0x0080,
-	0x1128, 0x20a3, 0x00ff, 0x20a3, 0xfffc, 0x0428, 0xa2e8, 0xb635,
-	0x2d6c, 0x6810, 0x20a2, 0x6814, 0x20a2, 0x00e8, 0x20a3, 0x0000,
-	0x6098, 0x20a2, 0x00c0, 0x2001, 0xb535, 0x2004, 0xd0ac, 0x1138,
-	0x7818, 0xa080, 0x0028, 0x2004, 0xa082, 0x007e, 0x0240, 0x00d6,
-	0x2069, 0xb51c, 0x2da6, 0x8d68, 0x2da6, 0x00de, 0x0020, 0x20a3,
-	0x0000, 0x6034, 0x20a2, 0x7834, 0x20a2, 0x7838, 0x20a2, 0x20a3,
-	0x0000, 0x20a3, 0x0000, 0x60c3, 0x000c, 0x080c, 0x7d67, 0x001e,
-	0x00de, 0x0005, 0x7817, 0x0001, 0x7803, 0x0006, 0x001e, 0x00de,
-	0x0005, 0x00d6, 0x0026, 0x7928, 0x2168, 0x691c, 0xa186, 0x0006,
-	0x01c0, 0xa186, 0x0003, 0x0904, 0x8478, 0xa186, 0x0005, 0x0904,
-	0x8461, 0xa186, 0x0004, 0x05b8, 0xa186, 0x0008, 0x0904, 0x8469,
-	0x7807, 0x0037, 0x7813, 0x1700, 0x080c, 0x84e0, 0x002e, 0x00de,
-	0x0005, 0x080c, 0x849c, 0x2009, 0x4000, 0x6800, 0x0002, 0x8442,
-	0x844d, 0x8444, 0x844d, 0x8449, 0x8442, 0x8442, 0x844d, 0x844d,
-	0x844d, 0x844d, 0x8442, 0x8442, 0x8442, 0x8442, 0x8442, 0x844d,
-	0x8442, 0x844d, 0x080c, 0x1515, 0x6820, 0xd0e4, 0x0110, 0xd0cc,
-	0x0110, 0xa00e, 0x0010, 0x2009, 0x2000, 0x6828, 0x20a2, 0x682c,
-	0x20a2, 0x0804, 0x8492, 0x080c, 0x849c, 0x20a3, 0x0000, 0x20a3,
-	0x0000, 0x2009, 0x4000, 0x6a00, 0xa286, 0x0002, 0x1108, 0xa00e,
-	0x0488, 0x04d1, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x2009, 0x4000,
-	0x0448, 0x0491, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x2009, 0x4000,
-	0xa286, 0x0005, 0x0118, 0xa286, 0x0002, 0x1108, 0xa00e, 0x00d0,
-	0x0419, 0x6810, 0x2068, 0x697c, 0x6810, 0xa112, 0x6980, 0x6814,
-	0xa103, 0x20a2, 0x22a2, 0x7928, 0xa180, 0x0000, 0x2004, 0xa08e,
-	0x0002, 0x0130, 0xa08e, 0x0004, 0x0118, 0x2009, 0x4000, 0x0010,
-	0x2009, 0x0000, 0x21a2, 0x20a3, 0x0000, 0x60c3, 0x0018, 0x080c,
-	0x7d67, 0x002e, 0x00de, 0x0005, 0x0036, 0x0046, 0x0056, 0x0066,
-	0x20a1, 0x020b, 0x080c, 0x76dd, 0xa006, 0x20a3, 0x0200, 0x20a2,
-	0x7934, 0x21a2, 0x7938, 0x21a2, 0x7818, 0xa080, 0x0028, 0x2004,
-	0x2011, 0xb535, 0x2214, 0xd2ac, 0x1118, 0xa092, 0x007e, 0x0268,
-	0x00d6, 0x2069, 0xb51c, 0x2d2c, 0x8d68, 0x2d34, 0xa0e8, 0xb635,
-	0x2d6c, 0x6b10, 0x6c14, 0x00de, 0x0030, 0x2019, 0x0000, 0x6498,
-	0x2029, 0x0000, 0x6634, 0x7828, 0xa080, 0x0007, 0x2004, 0xa086,
-	0x0003, 0x1128, 0x25a2, 0x26a2, 0x23a2, 0x24a2, 0x0020, 0x23a2,
-	0x24a2, 0x25a2, 0x26a2, 0x006e, 0x005e, 0x004e, 0x003e, 0x0005,
-	0x20a1, 0x020b, 0x080c, 0x76dd, 0x20a3, 0x0100, 0x20a3, 0x0000,
-	0x20a3, 0x0009, 0x7810, 0x20a2, 0x60c3, 0x0008, 0x080c, 0x7d67,
-	0x0005, 0x20a1, 0x020b, 0x080c, 0x7639, 0x20a3, 0x1400, 0x20a3,
-	0x0000, 0x7834, 0x20a2, 0x7838, 0x20a2, 0x7828, 0x20a2, 0x782c,
-	0x20a2, 0x7830, 0xa084, 0x00ff, 0x8007, 0x20a2, 0x20a3, 0x0000,
-	0x60c3, 0x0010, 0x080c, 0x7d67, 0x0005, 0x20a1, 0x020b, 0x080c,
-	0x76d5, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x7828, 0x20a2, 0x7810,
-	0x20a2, 0x60c3, 0x0008, 0x080c, 0x7d67, 0x0005, 0x0146, 0x20a1,
-	0x020b, 0x0031, 0x60c3, 0x0000, 0x080c, 0x7d67, 0x014e, 0x0005,
-	0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2004,
-	0x2011, 0xb535, 0x2214, 0xd2ac, 0x1110, 0xd0bc, 0x0188, 0x00d6,
-	0xa0e8, 0xb635, 0x2d6c, 0x6810, 0xa085, 0x0300, 0x20a2, 0x6814,
-	0x20a2, 0x2069, 0xb51c, 0x2da6, 0x8d68, 0x2da6, 0x00de, 0x0078,
-	0x00d6, 0xa0e8, 0xb635, 0x2d6c, 0x6810, 0xa085, 0x0300, 0x20a2,
-	0x6814, 0x20a2, 0x00de, 0x20a3, 0x0000, 0x6234, 0x22a2, 0x20a3,
-	0x0819, 0x20a3, 0x0000, 0x080c, 0x7d56, 0x22a2, 0x20a3, 0x0000,
-	0x2fa2, 0x7a08, 0x22a2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x0005,
-	0x20a1, 0x020b, 0x0079, 0x7910, 0x21a2, 0x20a3, 0x0000, 0x60c3,
-	0x0000, 0x20e1, 0x9080, 0x60a7, 0x9575, 0x080c, 0x7d71, 0x080c,
-	0x6a07, 0x0005, 0x0156, 0x0136, 0x0036, 0x00d6, 0x00e6, 0x20e1,
-	0x9080, 0x20e1, 0x4000, 0x7854, 0x2068, 0xadf0, 0x000f, 0x7210,
-	0xa296, 0x00c0, 0xa294, 0xfffd, 0x7212, 0x7214, 0xa294, 0x0300,
-	0x7216, 0x7100, 0xa194, 0x00ff, 0x7308, 0xa384, 0x00ff, 0xa08d,
-	0xc200, 0x7102, 0xa384, 0xff00, 0xa215, 0x720a, 0x7004, 0x720c,
-	0x700e, 0x7206, 0x20a9, 0x000a, 0x2e98, 0x53a6, 0x60a3, 0x0035,
-	0x6a38, 0xa294, 0x7000, 0xa286, 0x3000, 0x0110, 0x60a3, 0x0037,
-	0x00ee, 0x00de, 0x003e, 0x013e, 0x015e, 0x0005, 0x2009, 0x0092,
-	0x0010, 0x2009, 0x0096, 0x60ab, 0x0036, 0x6116, 0x0005, 0x2061,
-	0xbd00, 0x2a70, 0x7068, 0x704a, 0x704f, 0xbd00, 0x0005, 0x00e6,
-	0x0126, 0x2071, 0xb500, 0x2091, 0x8000, 0x7548, 0xa582, 0x0010,
-	0x0608, 0x704c, 0x2060, 0x6000, 0xa086, 0x0000, 0x0148, 0xace0,
-	0x0018, 0x705c, 0xac02, 0x1208, 0x0cb0, 0x2061, 0xbd00, 0x0c98,
-	0x6003, 0x0008, 0x8529, 0x754a, 0xaca8, 0x0018, 0x705c, 0xa502,
-	0x1230, 0x754e, 0xa085, 0x0001, 0x012e, 0x00ee, 0x0005, 0x704f,
-	0xbd00, 0x0cc0, 0xa006, 0x0cc0, 0x00e6, 0x2071, 0xb500, 0x7548,
-	0xa582, 0x0010, 0x0600, 0x704c, 0x2060, 0x6000, 0xa086, 0x0000,
-	0x0148, 0xace0, 0x0018, 0x705c, 0xac02, 0x1208, 0x0cb0, 0x2061,
-	0xbd00, 0x0c98, 0x6003, 0x0008, 0x8529, 0x754a, 0xaca8, 0x0018,
-	0x705c, 0xa502, 0x1228, 0x754e, 0xa085, 0x0001, 0x00ee, 0x0005,
-	0x704f, 0xbd00, 0x0cc8, 0xa006, 0x0cc8, 0xac82, 0xbd00, 0x0a0c,
-	0x1515, 0x2001, 0xb517, 0x2004, 0xac02, 0x1a0c, 0x1515, 0xa006,
-	0x6006, 0x600a, 0x600e, 0x6012, 0x6016, 0x601a, 0x601f, 0x0000,
-	0x6003, 0x0000, 0x6052, 0x6056, 0x6022, 0x6026, 0x602a, 0x602e,
-	0x6032, 0x6036, 0x603a, 0x603e, 0x2061, 0xb500, 0x6048, 0x8000,
-	0x604a, 0xa086, 0x0001, 0x0108, 0x0005, 0x0126, 0x2091, 0x8000,
-	0x080c, 0x7173, 0x012e, 0x0cc0, 0x601c, 0xa084, 0x000f, 0x0002,
-	0x865b, 0x866a, 0x8685, 0x86a0, 0xa152, 0xa16d, 0xa188, 0x865b,
-	0x866a, 0x865b, 0x86bb, 0xa186, 0x0013, 0x1128, 0x080c, 0x7090,
-	0x080c, 0x7173, 0x0005, 0xa18e, 0x0047, 0x1118, 0xa016, 0x080c,
-	0x185e, 0x0005, 0x0066, 0x6000, 0xa0b2, 0x0010, 0x1a0c, 0x1515,
-	0x0013, 0x006e, 0x0005, 0x8683, 0x8a9b, 0x8c53, 0x8683, 0x8cc8,
-	0x8779, 0x8683, 0x8683, 0x8a2d, 0x90ef, 0x8683, 0x8683, 0x8683,
-	0x8683, 0x8683, 0x8683, 0x080c, 0x1515, 0x0066, 0x6000, 0xa0b2,
-	0x0010, 0x1a0c, 0x1515, 0x0013, 0x006e, 0x0005, 0x869e, 0x9722,
-	0x869e, 0x869e, 0x869e, 0x869e, 0x869e, 0x869e, 0x96cd, 0x988e,
-	0x869e, 0x974f, 0x97c6, 0x974f, 0x97c6, 0x869e, 0x080c, 0x1515,
-	0x0066, 0x6000, 0xa0b2, 0x0010, 0x1a0c, 0x1515, 0x0013, 0x006e,
-	0x0005, 0x86b9, 0x9130, 0x91fa, 0x9335, 0x9491, 0x86b9, 0x86b9,
-	0x86b9, 0x910a, 0x967d, 0x9680, 0x86b9, 0x86b9, 0x86b9, 0x86b9,
-	0x96aa, 0x080c, 0x1515, 0x0066, 0x6000, 0xa0b2, 0x0010, 0x1a0c,
-	0x1515, 0x0013, 0x006e, 0x0005, 0x86d4, 0x86d4, 0x86d4, 0x8702,
-	0x874f, 0x86d4, 0x86d4, 0x86d4, 0x86d6, 0x86d4, 0x86d4, 0x86d4,
-	0x86d4, 0x86d4, 0x86d4, 0x86d4, 0x080c, 0x1515, 0xa186, 0x0003,
-	0x190c, 0x1515, 0x00d6, 0x6003, 0x0003, 0x6106, 0x6010, 0x2068,
-	0x684f, 0x0040, 0x687c, 0x680a, 0x6880, 0x680e, 0x6813, 0x0000,
-	0x6817, 0x0000, 0x6854, 0xa092, 0x199a, 0x0210, 0x2001, 0x1999,
-	0x8003, 0x8013, 0x8213, 0xa210, 0x6216, 0x00de, 0x2c10, 0x080c,
-	0x1fa9, 0x080c, 0x6cf0, 0x0126, 0x2091, 0x8000, 0x080c, 0x7230,
-	0x012e, 0x0005, 0xa182, 0x0047, 0x0002, 0x870e, 0x870e, 0x8710,
-	0x8729, 0x870e, 0x870e, 0x870e, 0x870e, 0x873b, 0x080c, 0x1515,
-	0x00d6, 0x0016, 0x080c, 0x7126, 0x080c, 0x7230, 0x6003, 0x0004,
-	0x6110, 0x2168, 0x684f, 0x0020, 0x685c, 0x685a, 0x6874, 0x687e,
-	0x6878, 0x6882, 0x6897, 0x0000, 0x689b, 0x0000, 0x001e, 0x00de,
-	0x0005, 0x080c, 0x7126, 0x00d6, 0x6110, 0x2168, 0x080c, 0x9c5a,
-	0x0120, 0x684b, 0x0006, 0x080c, 0x5408, 0x00de, 0x080c, 0x861d,
-	0x080c, 0x7230, 0x0005, 0x080c, 0x7126, 0x080c, 0x2c9c, 0x00d6,
-	0x6110, 0x2168, 0x080c, 0x9c5a, 0x0120, 0x684b, 0x0029, 0x080c,
-	0x5408, 0x00de, 0x080c, 0x861d, 0x080c, 0x7230, 0x0005, 0xa182,
-	0x0047, 0x0002, 0x875d, 0x876c, 0x875b, 0x875b, 0x875b, 0x875b,
-	0x875b, 0x875b, 0x875b, 0x080c, 0x1515, 0x00d6, 0x6010, 0x2068,
-	0x684c, 0xc0f4, 0x684e, 0x00de, 0x20e1, 0x0005, 0x3d18, 0x3e20,
-	0x2c10, 0x080c, 0x185e, 0x0005, 0x00d6, 0x6110, 0x2168, 0x684b,
-	0x0000, 0x6853, 0x0000, 0x080c, 0x5408, 0x00de, 0x080c, 0x861d,
-	0x0005, 0xa1b6, 0x0015, 0x1118, 0x080c, 0x861d, 0x0030, 0xa1b6,
-	0x0016, 0x190c, 0x1515, 0x080c, 0x861d, 0x0005, 0x20a9, 0x000e,
-	0x2e98, 0x6010, 0x20a0, 0x53a3, 0x20a9, 0x0006, 0x3310, 0x3420,
-	0x9398, 0x94a0, 0x3318, 0x3428, 0x222e, 0x2326, 0xa290, 0x0002,
-	0xa5a8, 0x0002, 0xa398, 0x0002, 0xa4a0, 0x0002, 0x1f04, 0x8794,
-	0x00e6, 0x080c, 0x9c5a, 0x0130, 0x6010, 0x2070, 0x7007, 0x0000,
-	0x7037, 0x0103, 0x00ee, 0x080c, 0x861d, 0x0005, 0x00d6, 0x0036,
-	0x7330, 0xa386, 0x0200, 0x1130, 0x6018, 0x2068, 0x6813, 0x00ff,
-	0x6817, 0xfffd, 0x6010, 0xa005, 0x0130, 0x2068, 0x6807, 0x0000,
-	0x6837, 0x0103, 0x6b32, 0x080c, 0x861d, 0x003e, 0x00de, 0x0005,
-	0x0016, 0x20a9, 0x002a, 0xae80, 0x000c, 0x2098, 0x6010, 0xa080,
-	0x0002, 0x20a0, 0x53a3, 0x20a9, 0x002a, 0x6010, 0xa080, 0x0001,
-	0x2004, 0xa080, 0x0002, 0x20a0, 0x53a3, 0x00e6, 0x6010, 0x2004,
-	0x2070, 0x7037, 0x0103, 0x00ee, 0x080c, 0x861d, 0x001e, 0x0005,
-	0x0016, 0x2009, 0x0000, 0x7030, 0xa086, 0x0100, 0x0140, 0x7038,
-	0xa084, 0x00ff, 0x800c, 0x703c, 0xa084, 0x00ff, 0x8004, 0xa080,
-	0x0004, 0xa108, 0x21a8, 0xae80, 0x000c, 0x2098, 0x6010, 0xa080,
-	0x0002, 0x20a0, 0x080c, 0x4b8f, 0x00e6, 0x080c, 0x9c5a, 0x0140,
-	0x6010, 0x2070, 0x7007, 0x0000, 0x7034, 0x70b2, 0x7037, 0x0103,
-	0x00ee, 0x080c, 0x861d, 0x001e, 0x0005, 0x00e6, 0x00d6, 0x603f,
-	0x0000, 0x2c68, 0x0016, 0x2009, 0x0035, 0x080c, 0xa10a, 0x001e,
-	0x1168, 0x0026, 0x6228, 0x2268, 0x002e, 0x2071, 0xbb8c, 0x6b1c,
-	0xa386, 0x0003, 0x0130, 0xa386, 0x0006, 0x0128, 0x080c, 0x861d,
-	0x0020, 0x0031, 0x0010, 0x080c, 0x88f6, 0x00de, 0x00ee, 0x0005,
-	0x00f6, 0x6810, 0x2078, 0xa186, 0x0015, 0x0904, 0x88dd, 0xa18e,
-	0x0016, 0x1904, 0x88f4, 0x700c, 0xa08c, 0xff00, 0xa186, 0x1700,
-	0x0120, 0xa186, 0x0300, 0x1904, 0x88bc, 0x8fff, 0x1138, 0x6800,
-	0xa086, 0x000f, 0x0904, 0x88a0, 0x0804, 0x88f2, 0x6808, 0xa086,
-	0xffff, 0x1904, 0x88df, 0x784c, 0xa084, 0x0060, 0xa086, 0x0020,
-	0x1150, 0x797c, 0x7810, 0xa106, 0x1904, 0x88df, 0x7980, 0x7814,
-	0xa106, 0x1904, 0x88df, 0x080c, 0x9e11, 0x6858, 0x7852, 0x784c,
-	0xc0dc, 0xc0f4, 0xc0d4, 0x784e, 0x0026, 0xa00e, 0x6a14, 0x2001,
-	0x000a, 0x080c, 0x6b40, 0x7854, 0xa20a, 0x0208, 0x8011, 0x7a56,
-	0x82ff, 0x002e, 0x1138, 0x00c6, 0x2d60, 0x080c, 0x9a09, 0x00ce,
-	0x0804, 0x88f2, 0x00c6, 0x00d6, 0x2f68, 0x6838, 0xd0fc, 0x1118,
-	0x080c, 0x4c64, 0x0010, 0x080c, 0x4e49, 0x00de, 0x00ce, 0x1904,
-	0x88df, 0x00c6, 0x2d60, 0x080c, 0x861d, 0x00ce, 0x0804, 0x88f2,
-	0x00c6, 0x080c, 0x9ed6, 0x0190, 0x6013, 0x0000, 0x6818, 0x601a,
-	0x080c, 0xa027, 0x601f, 0x0003, 0x6904, 0x00c6, 0x2d60, 0x080c,
-	0x861d, 0x00ce, 0x080c, 0x864c, 0x00ce, 0x04e0, 0x2001, 0xb7b8,
-	0x2004, 0x683e, 0x00ce, 0x04b0, 0x7008, 0xa086, 0x000b, 0x11a0,
-	0x6018, 0x200c, 0xc1bc, 0x2102, 0x00c6, 0x2d60, 0x7853, 0x0003,
-	0x6007, 0x0085, 0x6003, 0x000b, 0x601f, 0x0002, 0x080c, 0x6c8d,
-	0x080c, 0x7173, 0x00ce, 0x00f0, 0x700c, 0xa086, 0x2a00, 0x1138,
-	0x2001, 0xb7b8, 0x2004, 0x683e, 0x00a8, 0x0481, 0x00a8, 0x8fff,
-	0x090c, 0x1515, 0x00c6, 0x00d6, 0x2d60, 0x2f68, 0x6837, 0x0103,
-	0x684b, 0x0003, 0x080c, 0x98fd, 0x080c, 0x9e11, 0x080c, 0x9e1d,
-	0x00de, 0x00ce, 0x080c, 0x861d, 0x00fe, 0x0005, 0xa186, 0x0015,
-	0x1128, 0x2001, 0xb7b8, 0x2004, 0x683e, 0x0068, 0xa18e, 0x0016,
-	0x1160, 0x00c6, 0x2d00, 0x2060, 0x080c, 0xb33a, 0x080c, 0x6aef,
-	0x080c, 0x861d, 0x00ce, 0x080c, 0x861d, 0x0005, 0x0026, 0x0036,
-	0x0046, 0x7228, 0x7c80, 0x7b7c, 0xd2f4, 0x0130, 0x2001, 0xb7b8,
-	0x2004, 0x683e, 0x0804, 0x8970, 0x00c6, 0x2d60, 0x080c, 0x991d,
-	0x00ce, 0x6804, 0xa086, 0x0050, 0x1168, 0x00c6, 0x2d00, 0x2060,
-	0x6003, 0x0001, 0x6007, 0x0050, 0x080c, 0x6c8d, 0x080c, 0x7173,
-	0x00ce, 0x04f0, 0x6800, 0xa086, 0x000f, 0x01c8, 0x8fff, 0x090c,
-	0x1515, 0x6820, 0xd0dc, 0x1198, 0x6800, 0xa086, 0x0004, 0x1198,
-	0x784c, 0xd0ac, 0x0180, 0x784c, 0xc0dc, 0xc0f4, 0x784e, 0x7850,
-	0xc0f4, 0xc0fc, 0x7852, 0x2001, 0x0001, 0x682e, 0x00e0, 0x2001,
-	0x0007, 0x682e, 0x00c0, 0x784c, 0xd0b4, 0x1130, 0xd0ac, 0x0db8,
-	0x784c, 0xd0f4, 0x1da0, 0x0c38, 0xd2ec, 0x1d88, 0x7024, 0xa306,
-	0x1118, 0x7020, 0xa406, 0x0d58, 0x7020, 0x6836, 0x7024, 0x683a,
-	0x2001, 0x0005, 0x682e, 0x080c, 0x9f63, 0x080c, 0x7173, 0x0010,
-	0x080c, 0x861d, 0x004e, 0x003e, 0x002e, 0x0005, 0x00e6, 0x00d6,
-	0x0026, 0x6034, 0x2068, 0x6a1c, 0xa286, 0x0007, 0x0904, 0x89d4,
-	0xa286, 0x0002, 0x0904, 0x89d4, 0xa286, 0x0000, 0x0904, 0x89d4,
-	0x6808, 0x6338, 0xa306, 0x1904, 0x89d4, 0x2071, 0xbb8c, 0xa186,
-	0x0015, 0x05e0, 0xa18e, 0x0016, 0x1190, 0x6030, 0xa084, 0x00ff,
-	0xa086, 0x0001, 0x1160, 0x700c, 0xa086, 0x2a00, 0x1140, 0x6034,
-	0xa080, 0x0008, 0x200c, 0xc1dd, 0xc1f5, 0x2102, 0x0438, 0x00c6,
-	0x6034, 0x2060, 0x6104, 0xa186, 0x004b, 0x01a0, 0xa186, 0x004c,
-	0x0188, 0xa186, 0x004d, 0x0170, 0xa186, 0x004e, 0x0158, 0xa186,
-	0x0052, 0x0140, 0x6010, 0x2068, 0x080c, 0x9c5a, 0x090c, 0x1515,
-	0x6853, 0x0003, 0x6007, 0x0085, 0x6003, 0x000b, 0x601f, 0x0002,
-	0x080c, 0x6c8d, 0x080c, 0x7173, 0x00ce, 0x0030, 0x6034, 0x2070,
-	0x2001, 0xb7b8, 0x2004, 0x703e, 0x080c, 0x861d, 0x002e, 0x00de,
-	0x00ee, 0x0005, 0x00d6, 0x20a9, 0x000e, 0x2e98, 0x6010, 0x20a0,
-	0x53a3, 0xa1b6, 0x0015, 0x1558, 0x6018, 0x2068, 0x0156, 0x0036,
-	0x0026, 0xae90, 0x000c, 0xa290, 0x0004, 0x20a9, 0x0004, 0xad98,
-	0x000a, 0x080c, 0x90da, 0x002e, 0x003e, 0x015e, 0x11d8, 0x0156,
-	0x0036, 0x0026, 0xae90, 0x000c, 0xa290, 0x0008, 0x20a9, 0x0004,
-	0xad98, 0x0006, 0x080c, 0x90da, 0x002e, 0x003e, 0x015e, 0x1150,
-	0x7038, 0x680a, 0x703c, 0x680e, 0x6800, 0xc08d, 0x6802, 0x00de,
-	0x0804, 0x87a0, 0x080c, 0x2c9c, 0x00c6, 0x080c, 0x85c7, 0x2f00,
-	0x601a, 0x6013, 0x0000, 0x601f, 0x0001, 0x6007, 0x0001, 0x6003,
-	0x0001, 0x2001, 0x0007, 0x080c, 0x4efd, 0x080c, 0x4f2a, 0x080c,
-	0x6cd3, 0x080c, 0x7173, 0x00ce, 0x0c10, 0x2100, 0xa1b2, 0x0080,
-	0x1a0c, 0x1515, 0xa1b2, 0x0040, 0x1a04, 0x8a91, 0x0002, 0x8a85,
-	0x8a79, 0x8a85, 0x8a85, 0x8a85, 0x8a85, 0x8a77, 0x8a77, 0x8a77,
-	0x8a77, 0x8a77, 0x8a77, 0x8a77, 0x8a77, 0x8a77, 0x8a77, 0x8a77,
-	0x8a77, 0x8a77, 0x8a77, 0x8a77, 0x8a77, 0x8a77, 0x8a77, 0x8a77,
-	0x8a77, 0x8a77, 0x8a77, 0x8a77, 0x8a77, 0x8a77, 0x8a85, 0x8a77,
-	0x8a85, 0x8a85, 0x8a77, 0x8a77, 0x8a77, 0x8a77, 0x8a77, 0x8a85,
-	0x8a77, 0x8a77, 0x8a77, 0x8a77, 0x8a77, 0x8a77, 0x8a77, 0x8a77,
-	0x8a77, 0x8a85, 0x8a85, 0x8a77, 0x8a77, 0x8a77, 0x8a77, 0x8a77,
-	0x8a77, 0x8a77, 0x8a77, 0x8a77, 0x8a85, 0x8a77, 0x8a77, 0x080c,
-	0x1515, 0x6003, 0x0001, 0x6106, 0x080c, 0x6cd3, 0x0126, 0x2091,
-	0x8000, 0x080c, 0x7173, 0x012e, 0x0005, 0x6003, 0x0001, 0x6106,
-	0x080c, 0x6cd3, 0x0126, 0x2091, 0x8000, 0x080c, 0x7173, 0x012e,
-	0x0005, 0x2600, 0x0002, 0x8a85, 0x8a85, 0x8a99, 0x8a85, 0x8a85,
-	0x8a99, 0x080c, 0x1515, 0x6004, 0xa0b2, 0x0080, 0x1a0c, 0x1515,
-	0xa1b6, 0x0013, 0x0904, 0x8b4b, 0xa1b6, 0x0027, 0x1904, 0x8b11,
-	0x080c, 0x7090, 0x6004, 0x080c, 0x9e47, 0x0190, 0x080c, 0x9e58,
-	0x0904, 0x8b0b, 0xa08e, 0x0021, 0x0904, 0x8b0e, 0xa08e, 0x0022,
-	0x0904, 0x8b0b, 0xa08e, 0x003d, 0x0904, 0x8b0e, 0x0804, 0x8b04,
-	0x080c, 0x2cc2, 0x2001, 0x0007, 0x080c, 0x4efd, 0x6018, 0xa080,
-	0x0028, 0x200c, 0x080c, 0x8c19, 0xa186, 0x007e, 0x1148, 0x2001,
-	0xb535, 0x2014, 0xc285, 0x080c, 0x5acf, 0x1108, 0xc2ad, 0x2202,
-	0x0016, 0x0026, 0x0036, 0x2110, 0x0026, 0x2019, 0x0028, 0x080c,
-	0x8299, 0x002e, 0x080c, 0xb38d, 0x003e, 0x002e, 0x001e, 0x0016,
-	0x0026, 0x0036, 0x2110, 0x2019, 0x0028, 0x080c, 0x6df5, 0x0076,
-	0x2039, 0x0000, 0x080c, 0x6d02, 0x00c6, 0x6018, 0xa065, 0x0110,
-	0x080c, 0x51aa, 0x00ce, 0x2c08, 0x080c, 0xae82, 0x007e, 0x003e,
-	0x002e, 0x001e, 0x080c, 0x4f6c, 0x080c, 0xa01f, 0x080c, 0x861d,
-	0x080c, 0x7173, 0x0005, 0x080c, 0x8c19, 0x0cb0, 0x080c, 0x8c47,
-	0x0c98, 0xa186, 0x0014, 0x1db0, 0x080c, 0x7090, 0x080c, 0x2c9c,
-	0x080c, 0x9e47, 0x1188, 0x080c, 0x2cc2, 0x6018, 0xa080, 0x0028,
-	0x200c, 0x080c, 0x8c19, 0xa186, 0x007e, 0x1128, 0x2001, 0xb535,
-	0x200c, 0xc185, 0x2102, 0x08c0, 0x080c, 0x9e58, 0x1118, 0x080c,
-	0x8c19, 0x0890, 0x6004, 0xa08e, 0x0032, 0x1158, 0x00e6, 0x00f6,
-	0x2071, 0xb582, 0x2079, 0x0000, 0x080c, 0x2fcf, 0x00fe, 0x00ee,
-	0x0818, 0x6004, 0xa08e, 0x0021, 0x0d50, 0xa08e, 0x0022, 0x090c,
-	0x8c19, 0x0804, 0x8b04, 0xa0b2, 0x0040, 0x1a04, 0x8c0e, 0x2008,
-	0x0002, 0x8b93, 0x8b94, 0x8b97, 0x8b9a, 0x8b9d, 0x8ba0, 0x8b91,
-	0x8b91, 0x8b91, 0x8b91, 0x8b91, 0x8b91, 0x8b91, 0x8b91, 0x8b91,
-	0x8b91, 0x8b91, 0x8b91, 0x8b91, 0x8b91, 0x8b91, 0x8b91, 0x8b91,
-	0x8b91, 0x8b91, 0x8b91, 0x8b91, 0x8b91, 0x8b91, 0x8b91, 0x8ba3,
-	0x8bb2, 0x8b91, 0x8bb4, 0x8bb2, 0x8b91, 0x8b91, 0x8b91, 0x8b91,
-	0x8b91, 0x8bb2, 0x8bb2, 0x8b91, 0x8b91, 0x8b91, 0x8b91, 0x8b91,
-	0x8b91, 0x8b91, 0x8b91, 0x8bee, 0x8bb2, 0x8b91, 0x8bae, 0x8b91,
-	0x8b91, 0x8b91, 0x8baf, 0x8b91, 0x8b91, 0x8b91, 0x8bb2, 0x8be5,
-	0x8b91, 0x080c, 0x1515, 0x00f0, 0x2001, 0x000b, 0x0460, 0x2001,
-	0x0003, 0x0448, 0x2001, 0x0005, 0x0430, 0x2001, 0x0001, 0x0418,
-	0x2001, 0x0009, 0x0400, 0x080c, 0x7090, 0x6003, 0x0005, 0x2001,
-	0xb7b8, 0x2004, 0x603e, 0x080c, 0x7173, 0x00a0, 0x0018, 0x0010,
-	0x080c, 0x4efd, 0x0804, 0x8bff, 0x080c, 0x7090, 0x2001, 0xb7b6,
-	0x2004, 0x6016, 0x2001, 0xb7b8, 0x2004, 0x603e, 0x6003, 0x0004,
-	0x080c, 0x7173, 0x0005, 0x080c, 0x4efd, 0x080c, 0x7090, 0x6003,
-	0x0002, 0x2001, 0xb7b8, 0x2004, 0x603e, 0x0036, 0x2019, 0xb55d,
-	0x2304, 0xa084, 0xff00, 0x1120, 0x2001, 0xb7b6, 0x201c, 0x0040,
-	0x8007, 0xa09a, 0x0004, 0x0ec0, 0x8003, 0x801b, 0x831b, 0xa318,
-	0x6316, 0x003e, 0x080c, 0x7173, 0x08e8, 0x080c, 0x7090, 0x080c,
-	0xa01f, 0x080c, 0x861d, 0x080c, 0x7173, 0x08a0, 0x00e6, 0x00f6,
-	0x2071, 0xb582, 0x2079, 0x0000, 0x080c, 0x2fcf, 0x00fe, 0x00ee,
-	0x080c, 0x7090, 0x080c, 0x861d, 0x080c, 0x7173, 0x0818, 0x080c,
-	0x7090, 0x2001, 0xb7b8, 0x2004, 0x603e, 0x6003, 0x0002, 0x2001,
-	0xb7b6, 0x2004, 0x6016, 0x080c, 0x7173, 0x0005, 0x2600, 0x2008,
-	0x0002, 0x8c17, 0x8c17, 0x8c17, 0x8bff, 0x8bff, 0x8c17, 0x080c,
-	0x1515, 0x00e6, 0x0026, 0x0016, 0x080c, 0x9c5a, 0x0508, 0x6010,
-	0x2070, 0x7034, 0xa086, 0x0139, 0x1148, 0x2001, 0x0030, 0x2009,
-	0x0000, 0x2011, 0x4005, 0x080c, 0xa0d6, 0x0090, 0x7038, 0xd0fc,
-	0x0178, 0x7007, 0x0000, 0x0016, 0x6004, 0xa08e, 0x0021, 0x0160,
-	0xa08e, 0x003d, 0x0148, 0x001e, 0x7037, 0x0103, 0x7033, 0x0100,
-	0x001e, 0x002e, 0x00ee, 0x0005, 0x001e, 0x0009, 0x0cc8, 0x00e6,
-	0xacf0, 0x0004, 0x2e74, 0x7000, 0x2070, 0x7037, 0x0103, 0x7023,
-	0x8001, 0x00ee, 0x0005, 0x00d6, 0x6618, 0x2668, 0x6804, 0xa084,
-	0x00ff, 0x00de, 0xa0b2, 0x000c, 0x1a0c, 0x1515, 0x6604, 0xa6b6,
-	0x0043, 0x1120, 0x080c, 0xa092, 0x0804, 0x8cb8, 0x6604, 0xa6b6,
-	0x0033, 0x1120, 0x080c, 0xa042, 0x0804, 0x8cb8, 0x6604, 0xa6b6,
-	0x0028, 0x1120, 0x080c, 0x9e88, 0x0804, 0x8cb8, 0x6604, 0xa6b6,
-	0x0029, 0x1118, 0x080c, 0x9e9f, 0x04d8, 0x6604, 0xa6b6, 0x001f,
-	0x1118, 0x080c, 0x8786, 0x04a0, 0x6604, 0xa6b6, 0x0000, 0x1118,
-	0x080c, 0x89da, 0x0468, 0x6604, 0xa6b6, 0x0022, 0x1118, 0x080c,
-	0x87ae, 0x0430, 0x6604, 0xa6b6, 0x0035, 0x1118, 0x080c, 0x8815,
-	0x00f8, 0x6604, 0xa6b6, 0x0039, 0x1118, 0x080c, 0x8976, 0x00c0,
-	0x6604, 0xa6b6, 0x003d, 0x1118, 0x080c, 0x87c8, 0x0088, 0x6604,
-	0xa6b6, 0x0044, 0x1118, 0x080c, 0x87e8, 0x0050, 0xa1b6, 0x0015,
-	0x1110, 0x0053, 0x0028, 0xa1b6, 0x0016, 0x1118, 0x0804, 0x8e7c,
-	0x0005, 0x080c, 0x8663, 0x0ce0, 0x8cdf, 0x8ce2, 0x8cdf, 0x8d24,
-	0x8cdf, 0x8e09, 0x8e8a, 0x8cdf, 0x8cdf, 0x8e58, 0x8cdf, 0x8e6c,
-	0xa1b6, 0x0048, 0x0140, 0x20e1, 0x0005, 0x3d18, 0x3e20, 0x2c10,
-	0x080c, 0x185e, 0x0005, 0x00e6, 0xacf0, 0x0004, 0x2e74, 0x7000,
-	0x2070, 0x7037, 0x0103, 0x00ee, 0x080c, 0x861d, 0x0005, 0xe000,
-	0xe000, 0x0005, 0x00e6, 0x2071, 0xb500, 0x7084, 0xa086, 0x0074,
-	0x1530, 0x080c, 0xae59, 0x11b0, 0x00d6, 0x6018, 0x2068, 0x7030,
-	0xd08c, 0x0128, 0x6800, 0xd0bc, 0x0110, 0xc0c5, 0x6802, 0x00d9,
-	0x00de, 0x2001, 0x0006, 0x080c, 0x4efd, 0x080c, 0x2cc2, 0x080c,
-	0x861d, 0x0078, 0x2001, 0x000a, 0x080c, 0x4efd, 0x080c, 0x2cc2,
-	0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x6cd3, 0x0010, 0x080c,
-	0x8df6, 0x00ee, 0x0005, 0x6800, 0xd084, 0x0168, 0x2001, 0x0000,
-	0x080c, 0x4eeb, 0x2069, 0xb552, 0x6804, 0xd0a4, 0x0120, 0x2001,
-	0x0006, 0x080c, 0x4f2a, 0x0005, 0x00d6, 0x2011, 0xb521, 0x2204,
-	0xa086, 0x0074, 0x1904, 0x8df3, 0x6018, 0x2068, 0x6aa0, 0xa286,
-	0x007e, 0x1120, 0x080c, 0x8fa2, 0x0804, 0x8d92, 0x080c, 0x8f98,
-	0x6018, 0x2068, 0xa080, 0x0028, 0x2014, 0xa286, 0x0080, 0x11c0,
-	0x6813, 0x00ff, 0x6817, 0xfffc, 0x6010, 0xa005, 0x0138, 0x2068,
-	0x6807, 0x0000, 0x6837, 0x0103, 0x6833, 0x0200, 0x2001, 0x0006,
-	0x080c, 0x4efd, 0x080c, 0x2cc2, 0x080c, 0x861d, 0x0804, 0x8df4,
-	0x00e6, 0x2071, 0xb535, 0x2e04, 0xd09c, 0x0188, 0x2071, 0xbb80,
-	0x7108, 0x720c, 0xa18c, 0x00ff, 0x1118, 0xa284, 0xff00, 0x0138,
-	0x6018, 0x2070, 0x70a0, 0xd0bc, 0x1110, 0x7112, 0x7216, 0x00ee,
-	0x6010, 0xa005, 0x0198, 0x2068, 0x6838, 0xd0f4, 0x0178, 0x6834,
-	0xa084, 0x00ff, 0xa086, 0x0039, 0x1958, 0x2001, 0x0000, 0x2009,
-	0x0000, 0x2011, 0x4000, 0x080c, 0xa0d6, 0x0840, 0x2001, 0x0004,
-	0x080c, 0x4efd, 0x6003, 0x0001, 0x6007, 0x0003, 0x080c, 0x6cd3,
-	0x0804, 0x8df4, 0x685c, 0xd0e4, 0x01d8, 0x080c, 0x9fd2, 0x080c,
-	0x5acf, 0x0118, 0xd0dc, 0x1904, 0x8d4e, 0x2011, 0xb535, 0x2204,
-	0xc0ad, 0x2012, 0x2001, 0xb78f, 0x2004, 0x00f6, 0x2079, 0x0100,
-	0x78e3, 0x0000, 0x080c, 0x2872, 0x78e2, 0x00fe, 0x0804, 0x8d4e,
-	0x080c, 0xa008, 0x2011, 0xb535, 0x2204, 0xc0a5, 0x2012, 0x0006,
-	0x080c, 0xaf7b, 0x000e, 0x1904, 0x8d4e, 0xc0b5, 0x2012, 0x2001,
-	0x0006, 0x080c, 0x4efd, 0x2001, 0x0000, 0x080c, 0x4eeb, 0x00c6,
-	0x2009, 0x00ef, 0x00f6, 0x2079, 0x0100, 0x79ea, 0x7932, 0x7936,
-	0x00fe, 0x080c, 0x2847, 0x00f6, 0x2079, 0xb500, 0x7976, 0x2100,
-	0x2009, 0x0000, 0x080c, 0x281d, 0x7952, 0x00fe, 0x8108, 0x080c,
-	0x4f4d, 0x2c00, 0x00ce, 0x1904, 0x8d4e, 0x601a, 0x2001, 0x0002,
-	0x080c, 0x4efd, 0x601f, 0x0001, 0x6003, 0x0001, 0x6007, 0x0002,
-	0x080c, 0x6cd3, 0x0008, 0x0011, 0x00de, 0x0005, 0x2001, 0x0007,
-	0x080c, 0x4efd, 0x2001, 0xb500, 0x2004, 0xa086, 0x0003, 0x1120,
-	0x2001, 0x0007, 0x080c, 0x4f2a, 0x080c, 0x2cc2, 0x080c, 0x861d,
-	0x0005, 0x00e6, 0x0026, 0x0016, 0x2071, 0xb500, 0x7084, 0xa086,
-	0x0014, 0x15f0, 0x7000, 0xa086, 0x0003, 0x1128, 0x6010, 0xa005,
-	0x1110, 0x080c, 0x3f3e, 0x00d6, 0x6018, 0x2068, 0x080c, 0x504b,
-	0x080c, 0x8d13, 0x00de, 0x080c, 0x9051, 0x1550, 0x00d6, 0x6018,
-	0x2068, 0x6890, 0x00de, 0xa005, 0x0518, 0x2001, 0x0006, 0x080c,
-	0x4efd, 0x00e6, 0x6010, 0xa075, 0x01a8, 0x7034, 0xa084, 0x00ff,
-	0xa086, 0x0039, 0x1148, 0x2001, 0x0000, 0x2009, 0x0000, 0x2011,
-	0x4000, 0x080c, 0xa0d6, 0x0030, 0x7007, 0x0000, 0x7037, 0x0103,
-	0x7033, 0x0200, 0x00ee, 0x080c, 0x2cc2, 0x080c, 0x861d, 0x0020,
-	0x080c, 0x8c19, 0x080c, 0x8df6, 0x001e, 0x002e, 0x00ee, 0x0005,
-	0x2011, 0xb521, 0x2204, 0xa086, 0x0014, 0x1158, 0x2001, 0x0002,
-	0x080c, 0x4efd, 0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x6cd3,
-	0x0010, 0x080c, 0x8df6, 0x0005, 0x2011, 0xb521, 0x2204, 0xa086,
-	0x0004, 0x1138, 0x2001, 0x0007, 0x080c, 0x4efd, 0x080c, 0x861d,
-	0x0010, 0x080c, 0x8df6, 0x0005, 0x000b, 0x0005, 0x8cdf, 0x8e95,
-	0x8cdf, 0x8ec9, 0x8cdf, 0x8f54, 0x8e8a, 0x8cdf, 0x8cdf, 0x8f67,
-	0x8cdf, 0x8f77, 0x6604, 0xa686, 0x0003, 0x0904, 0x8e09, 0xa6b6,
-	0x001e, 0x1110, 0x080c, 0x861d, 0x0005, 0x00d6, 0x00c6, 0x080c,
-	0x8f87, 0x1178, 0x2001, 0x0000, 0x080c, 0x4eeb, 0x2001, 0x0002,
-	0x080c, 0x4efd, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x6cd3,
-	0x00e8, 0x2009, 0xbb8e, 0x2104, 0xa086, 0x0009, 0x1160, 0x6018,
-	0x2068, 0x6840, 0xa084, 0x00ff, 0xa005, 0x0170, 0x8001, 0x6842,
-	0x6017, 0x000a, 0x0058, 0x2009, 0xbb8f, 0x2104, 0xa084, 0xff00,
-	0xa086, 0x1900, 0x1108, 0x08d0, 0x080c, 0x8df6, 0x00ce, 0x00de,
-	0x0005, 0x0026, 0x2011, 0x0000, 0x080c, 0x8f95, 0x00d6, 0x2069,
-	0xb79e, 0x2d04, 0xa005, 0x0168, 0x6018, 0x2068, 0x68a0, 0xa086,
-	0x007e, 0x1138, 0x2069, 0xb51d, 0x2d04, 0x8000, 0x206a, 0x00de,
-	0x0010, 0x00de, 0x0078, 0x2001, 0x0000, 0x080c, 0x4eeb, 0x2001,
-	0x0002, 0x080c, 0x4efd, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c,
-	0x6cd3, 0x0480, 0x00d6, 0x6010, 0x2068, 0x080c, 0x9c5a, 0x00de,
-	0x0108, 0x6a34, 0x080c, 0x8c19, 0x2009, 0xbb8e, 0x2134, 0xa6b4,
-	0x00ff, 0xa686, 0x0005, 0x0500, 0xa686, 0x000b, 0x01c8, 0x2009,
-	0xbb8f, 0x2104, 0xa084, 0xff00, 0x1118, 0xa686, 0x0009, 0x01a0,
-	0xa086, 0x1900, 0x1168, 0xa686, 0x0009, 0x0170, 0x2001, 0x0004,
-	0x080c, 0x4efd, 0x2001, 0x0028, 0x6016, 0x6007, 0x004b, 0x0010,
-	0x080c, 0x8df6, 0x002e, 0x0005, 0x00d6, 0xa286, 0x0139, 0x0160,
-	0x6010, 0x2068, 0x080c, 0x9c5a, 0x0148, 0x6834, 0xa086, 0x0139,
-	0x0118, 0x6838, 0xd0fc, 0x0110, 0x00de, 0x0c50, 0x6018, 0x2068,
-	0x6840, 0xa084, 0x00ff, 0xa005, 0x0140, 0x8001, 0x6842, 0x6017,
-	0x000a, 0x6007, 0x0016, 0x00de, 0x08e8, 0x68a0, 0xa086, 0x007e,
-	0x1138, 0x00e6, 0x2071, 0xb500, 0x080c, 0x4bc6, 0x00ee, 0x0010,
-	0x080c, 0x2c9c, 0x00de, 0x0860, 0x080c, 0x8f95, 0x1158, 0x2001,
-	0x0004, 0x080c, 0x4efd, 0x6003, 0x0001, 0x6007, 0x0003, 0x080c,
-	0x6cd3, 0x0020, 0x080c, 0x8c19, 0x080c, 0x8df6, 0x0005, 0x0469,
-	0x1158, 0x2001, 0x0008, 0x080c, 0x4efd, 0x6003, 0x0001, 0x6007,
-	0x0005, 0x080c, 0x6cd3, 0x0010, 0x080c, 0x8df6, 0x0005, 0x00e9,
-	0x1158, 0x2001, 0x000a, 0x080c, 0x4efd, 0x6003, 0x0001, 0x6007,
-	0x0001, 0x080c, 0x6cd3, 0x0010, 0x080c, 0x8df6, 0x0005, 0x2009,
-	0xbb8e, 0x2104, 0xa086, 0x0003, 0x1138, 0x2009, 0xbb8f, 0x2104,
-	0xa084, 0xff00, 0xa086, 0x2a00, 0x0005, 0xa085, 0x0001, 0x0005,
-	0x00c6, 0x0016, 0xac88, 0x0006, 0x2164, 0x080c, 0x4fb8, 0x001e,
-	0x00ce, 0x0005, 0x00f6, 0x00e6, 0x00d6, 0x0036, 0x0016, 0x6018,
-	0x2068, 0x2071, 0xb535, 0x2e04, 0xa085, 0x0003, 0x2072, 0x080c,
-	0x9026, 0x0560, 0x2009, 0xb535, 0x2104, 0xc0cd, 0x200a, 0x2001,
-	0xb553, 0x2004, 0xd0a4, 0x0158, 0xa006, 0x2020, 0x2009, 0x002a,
-	0x080c, 0xb0e8, 0x2001, 0xb50c, 0x200c, 0xc195, 0x2102, 0x2019,
-	0x002a, 0x2009, 0x0001, 0x080c, 0x2c6f, 0x2071, 0xb500, 0x080c,
-	0x2ab8, 0x00c6, 0x0156, 0x20a9, 0x0081, 0x2009, 0x007f, 0x080c,
-	0x2d97, 0x8108, 0x1f04, 0x8fd7, 0x015e, 0x00ce, 0x080c, 0x8f98,
-	0x6813, 0x00ff, 0x6817, 0xfffe, 0x2071, 0xbb80, 0x2079, 0x0100,
-	0x2e04, 0xa084, 0x00ff, 0x2069, 0xb51c, 0x206a, 0x78e6, 0x0006,
-	0x8e70, 0x2e04, 0x2069, 0xb51d, 0x206a, 0x78ea, 0x7832, 0x7836,
-	0x2010, 0xa084, 0xff00, 0x001e, 0xa105, 0x2009, 0xb528, 0x200a,
-	0x2200, 0xa084, 0x00ff, 0x2008, 0x080c, 0x2847, 0x080c, 0x5acf,
-	0x0170, 0x2069, 0xbb8e, 0x2071, 0xb7b2, 0x6810, 0x2072, 0x6814,
-	0x7006, 0x6818, 0x700a, 0x681c, 0x700e, 0x080c, 0x9fd2, 0x0040,
-	0x2001, 0x0006, 0x080c, 0x4efd, 0x080c, 0x2cc2, 0x080c, 0x861d,
-	0x001e, 0x003e, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x0026, 0x0036,
-	0x00e6, 0x0156, 0x2019, 0xb528, 0x231c, 0x83ff, 0x01e8, 0x2071,
-	0xbb80, 0x2e14, 0xa294, 0x00ff, 0x7004, 0xa084, 0xff00, 0xa205,
-	0xa306, 0x1190, 0x2011, 0xbb96, 0xad98, 0x000a, 0x20a9, 0x0004,
-	0x080c, 0x90da, 0x1148, 0x2011, 0xbb9a, 0xad98, 0x0006, 0x20a9,
-	0x0004, 0x080c, 0x90da, 0x1100, 0x015e, 0x00ee, 0x003e, 0x002e,
-	0x0005, 0x00e6, 0x2071, 0xbb8c, 0x7004, 0xa086, 0x0014, 0x11a8,
-	0x7008, 0xa086, 0x0800, 0x1188, 0x700c, 0xd0ec, 0x0160, 0xa084,
-	0x0f00, 0xa086, 0x0100, 0x1138, 0x7024, 0xd0a4, 0x1110, 0xd0ac,
-	0x0110, 0xa006, 0x0010, 0xa085, 0x0001, 0x00ee, 0x0005, 0x00e6,
-	0x00d6, 0x00c6, 0x0076, 0x0056, 0x0046, 0x0026, 0x0006, 0x0126,
-	0x2091, 0x8000, 0x2029, 0xb7e9, 0x252c, 0x2021, 0xb7ef, 0x2424,
-	0x2061, 0xbd00, 0x2071, 0xb500, 0x7248, 0x7068, 0xa202, 0x16f0,
-	0x080c, 0xb110, 0x05a0, 0x671c, 0xa786, 0x0001, 0x0580, 0xa786,
-	0x0007, 0x0568, 0x2500, 0xac06, 0x0550, 0x2400, 0xac06, 0x0538,
-	0x00c6, 0x6000, 0xa086, 0x0004, 0x1110, 0x080c, 0x194d, 0xa786,
-	0x0008, 0x1148, 0x080c, 0x9e58, 0x1130, 0x00ce, 0x080c, 0x8c19,
-	0x080c, 0x9e1d, 0x00a0, 0x6010, 0x2068, 0x080c, 0x9c5a, 0x0160,
-	0xa786, 0x0003, 0x11e8, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000,
-	0x080c, 0x5408, 0x080c, 0x9e11, 0x080c, 0x9e1d, 0x00ce, 0xace0,
-	0x0018, 0x705c, 0xac02, 0x1210, 0x0804, 0x9084, 0x012e, 0x000e,
-	0x002e, 0x004e, 0x005e, 0x007e, 0x00ce, 0x00de, 0x00ee, 0x0005,
-	0xa786, 0x0006, 0x1118, 0x080c, 0xb099, 0x0c30, 0xa786, 0x000a,
-	0x09e0, 0x08c8, 0x220c, 0x2304, 0xa106, 0x1130, 0x8210, 0x8318,
-	0x1f04, 0x90da, 0xa006, 0x0005, 0x2304, 0xa102, 0x0218, 0x2001,
-	0x0001, 0x0010, 0x2001, 0x0000, 0xa18d, 0x0001, 0x0005, 0x6004,
-	0xa08a, 0x0080, 0x1a0c, 0x1515, 0x080c, 0x9e47, 0x0120, 0x080c,
-	0x9e58, 0x0168, 0x0028, 0x080c, 0x2cc2, 0x080c, 0x9e58, 0x0138,
-	0x080c, 0x7090, 0x080c, 0x861d, 0x080c, 0x7173, 0x0005, 0x080c,
-	0x8c19, 0x0cb0, 0xa182, 0x0040, 0x0002, 0x9120, 0x9120, 0x9120,
-	0x9120, 0x9120, 0x9120, 0x9120, 0x9120, 0x9120, 0x9120, 0x9120,
-	0x9122, 0x9122, 0x9122, 0x9122, 0x9120, 0x9120, 0x9120, 0x9122,
-	0x080c, 0x1515, 0x600b, 0xffff, 0x6003, 0x0001, 0x6106, 0x080c,
-	0x6c8d, 0x0126, 0x2091, 0x8000, 0x080c, 0x7173, 0x012e, 0x0005,
-	0xa186, 0x0013, 0x1128, 0x6004, 0xa082, 0x0040, 0x0804, 0x91bc,
-	0xa186, 0x0027, 0x11e8, 0x080c, 0x7090, 0x080c, 0x2c9c, 0x00d6,
-	0x6110, 0x2168, 0x080c, 0x9c5a, 0x0168, 0x6837, 0x0103, 0x684b,
-	0x0029, 0x6847, 0x0000, 0x694c, 0xc1c5, 0x694e, 0x080c, 0x5408,
-	0x080c, 0x9e11, 0x00de, 0x080c, 0x861d, 0x080c, 0x7173, 0x0005,
-	0xa186, 0x0014, 0x1120, 0x6004, 0xa082, 0x0040, 0x0428, 0xa186,
-	0x0046, 0x0138, 0xa186, 0x0045, 0x0120, 0xa186, 0x0047, 0x190c,
-	0x1515, 0x2001, 0x0109, 0x2004, 0xd084, 0x0198, 0x0126, 0x2091,
-	0x2800, 0x0006, 0x0016, 0x0026, 0x080c, 0x6b74, 0x002e, 0x001e,
-	0x000e, 0x012e, 0xe000, 0x6000, 0xa086, 0x0002, 0x1110, 0x0804,
-	0x91fa, 0x080c, 0x8663, 0x0005, 0x0002, 0x919a, 0x9198, 0x9198,
-	0x9198, 0x9198, 0x9198, 0x9198, 0x9198, 0x9198, 0x9198, 0x9198,
-	0x91b5, 0x91b5, 0x91b5, 0x91b5, 0x9198, 0x91b5, 0x9198, 0x91b5,
-	0x080c, 0x1515, 0x080c, 0x7090, 0x00d6, 0x6110, 0x2168, 0x080c,
-	0x9c5a, 0x0168, 0x6837, 0x0103, 0x684b, 0x0006, 0x6847, 0x0000,
-	0x6850, 0xc0ec, 0x6852, 0x080c, 0x5408, 0x080c, 0x9e11, 0x00de,
-	0x080c, 0x861d, 0x080c, 0x7173, 0x0005, 0x080c, 0x7090, 0x080c,
-	0x861d, 0x080c, 0x7173, 0x0005, 0x0002, 0x91d2, 0x91d0, 0x91d0,
-	0x91d0, 0x91d0, 0x91d0, 0x91d0, 0x91d0, 0x91d0, 0x91d0, 0x91d0,
-	0x91e4, 0x91e4, 0x91e4, 0x91e4, 0x91d0, 0x91f3, 0x91d0, 0x91e4,
-	0x080c, 0x1515, 0x080c, 0x7090, 0x2001, 0xb7b8, 0x2004, 0x603e,
-	0x6003, 0x0002, 0x080c, 0x7173, 0x6010, 0xa088, 0x0013, 0x2104,
-	0xa085, 0x0400, 0x200a, 0x0005, 0x080c, 0x7090, 0x2001, 0xb7b6,
-	0x2004, 0x6016, 0x2001, 0xb7b8, 0x2004, 0x603e, 0x6003, 0x000f,
-	0x080c, 0x7173, 0x0005, 0x080c, 0x7090, 0x080c, 0x861d, 0x080c,
-	0x7173, 0x0005, 0xa182, 0x0040, 0x0002, 0x9210, 0x9210, 0x9210,
-	0x9210, 0x9210, 0x9212, 0x92f7, 0x9326, 0x9210, 0x9210, 0x9210,
-	0x9210, 0x9210, 0x9210, 0x9210, 0x9210, 0x9210, 0x9210, 0x9210,
-	0x080c, 0x1515, 0x00e6, 0x00d6, 0x603f, 0x0000, 0x2071, 0xbb80,
-	0x7124, 0x610a, 0x2071, 0xbb8c, 0x6110, 0x2168, 0x7614, 0xa6b4,
-	0x0fff, 0x86ff, 0x0904, 0x92c0, 0xa68c, 0x0c00, 0x0518, 0x00f6,
-	0x2c78, 0x080c, 0x5305, 0x00fe, 0x01c8, 0x684c, 0xd0ac, 0x01b0,
-	0x6020, 0xd0dc, 0x1198, 0x6850, 0xd0bc, 0x1180, 0x7318, 0x6814,
-	0xa306, 0x1904, 0x92d3, 0x731c, 0x6810, 0xa31e, 0x0138, 0xd6d4,
-	0x0904, 0x92d3, 0x6b14, 0xa305, 0x1904, 0x92d3, 0x7318, 0x6b62,
-	0x731c, 0x6b5e, 0xa68c, 0x00ff, 0xa186, 0x0002, 0x0518, 0xa186,
-	0x0028, 0x1128, 0x080c, 0x9e36, 0x684b, 0x001c, 0x00e8, 0xd6dc,
-	0x01a0, 0x684b, 0x0015, 0x684c, 0xd0ac, 0x0170, 0x6914, 0x6a10,
-	0x2100, 0xa205, 0x0148, 0x7018, 0xa106, 0x1118, 0x701c, 0xa206,
-	0x0118, 0x6962, 0x6a5e, 0xc6dc, 0x0038, 0xd6d4, 0x0118, 0x684b,
-	0x0007, 0x0010, 0x684b, 0x0000, 0x6837, 0x0103, 0x6e46, 0xa01e,
-	0xd6c4, 0x01f0, 0xa686, 0x0100, 0x1140, 0x2001, 0xbb99, 0x2004,
-	0xa005, 0x1118, 0xc6c4, 0x0804, 0x9221, 0x7328, 0x732c, 0x6b56,
-	0x83ff, 0x0170, 0xa38a, 0x0009, 0x0210, 0x2019, 0x0008, 0x0036,
-	0x2308, 0x2019, 0xbb98, 0xad90, 0x0019, 0x080c, 0x990d, 0x003e,
-	0xd6cc, 0x0904, 0x92e6, 0x7124, 0x695a, 0x81ff, 0x0904, 0x92e6,
-	0xa192, 0x0021, 0x1260, 0x2071, 0xbb98, 0x831c, 0x2300, 0xae18,
-	0xad90, 0x001d, 0x080c, 0x990d, 0x080c, 0xa137, 0x04b8, 0x6838,
-	0xd0fc, 0x0120, 0x2009, 0x0020, 0x695a, 0x0c68, 0x00f6, 0x2d78,
-	0x080c, 0x98b2, 0x00fe, 0x080c, 0xa137, 0x080c, 0x98fd, 0x0440,
-	0x00f6, 0x2c78, 0x080c, 0x5305, 0x00fe, 0x0190, 0x684c, 0xd0ac,
-	0x0178, 0x6020, 0xd0dc, 0x1160, 0x6850, 0xd0bc, 0x1148, 0x6810,
-	0x6914, 0xa105, 0x0128, 0x080c, 0x9f35, 0x00de, 0x00ee, 0x00f0,
-	0x684b, 0x0000, 0x6837, 0x0103, 0x6e46, 0x684c, 0xd0ac, 0x0130,
-	0x6810, 0x6914, 0xa115, 0x0110, 0x080c, 0x9483, 0x080c, 0x5408,
-	0x6218, 0x2268, 0x6a3c, 0x82ff, 0x0110, 0x8211, 0x6a3e, 0x080c,
-	0x9f03, 0x00de, 0x00ee, 0x1110, 0x080c, 0x861d, 0x0005, 0x00f6,
-	0x6003, 0x0003, 0x2079, 0xbb8c, 0x7c04, 0x7b00, 0x7e0c, 0x7d08,
-	0x6010, 0x2078, 0x784c, 0xd0ac, 0x0138, 0x6003, 0x0002, 0x00fe,
-	0x0005, 0x2130, 0x2228, 0x0058, 0x2400, 0x797c, 0xa10a, 0x2300,
-	0x7a80, 0xa213, 0x2600, 0xa102, 0x2500, 0xa203, 0x0e90, 0x7c12,
-	0x7b16, 0x7e0a, 0x7d0e, 0x00fe, 0x603f, 0x0000, 0x2c10, 0x080c,
-	0x1fa9, 0x080c, 0x6cf0, 0x080c, 0x7230, 0x0005, 0x2001, 0xb7b8,
-	0x2004, 0x603e, 0x6003, 0x0004, 0x6110, 0x20e1, 0x0005, 0x3d18,
-	0x3e20, 0x2c10, 0x080c, 0x185e, 0x0005, 0xa182, 0x0040, 0x0002,
-	0x934b, 0x934b, 0x934b, 0x934b, 0x934b, 0x934d, 0x93e0, 0x934b,
-	0x934b, 0x93f6, 0x945a, 0x934b, 0x934b, 0x934b, 0x934b, 0x9469,
-	0x934b, 0x934b, 0x934b, 0x080c, 0x1515, 0x0076, 0x00f6, 0x00e6,
-	0x00d6, 0x2071, 0xbb8c, 0x6110, 0x2178, 0x7614, 0xa6b4, 0x0fff,
+	0x660c, 0x2c00, 0xaf06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f,
+	0x0000, 0xa085, 0x0001, 0x0020, 0x2c78, 0x600c, 0x2060, 0x08d8,
+	0x012e, 0x000e, 0x002e, 0x006e, 0x00ce, 0x00ee, 0x00fe, 0x0005,
+	0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0006, 0x0126, 0x2091,
+	0x8000, 0x2071, 0xb8e1, 0x760c, 0x2660, 0x2678, 0x8cff, 0x0904,
+	0x83aa, 0x6018, 0xa080, 0x0028, 0x2004, 0xa206, 0x1904, 0x83a5,
+	0x7024, 0xac06, 0x1508, 0x2069, 0x0100, 0x68c0, 0xa005, 0x0904,
+	0x8381, 0x080c, 0x7df3, 0x68c3, 0x0000, 0x080c, 0x82d4, 0x7027,
+	0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0xa384, 0x1000, 0x0120,
+	0x6803, 0x0100, 0x6803, 0x0000, 0x2069, 0x0100, 0x6824, 0xd084,
+	0x0110, 0x6827, 0x0001, 0x003e, 0x700c, 0xac36, 0x1110, 0x660c,
+	0x760e, 0x7008, 0xac36, 0x1140, 0x2c00, 0xaf36, 0x0118, 0x2f00,
+	0x700a, 0x0010, 0x700b, 0x0000, 0x660c, 0x0066, 0x2c00, 0xaf06,
+	0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0x080c, 0x9f03,
+	0x1158, 0x080c, 0x2cf7, 0x080c, 0x9f14, 0x11f0, 0x080c, 0x8ca5,
+	0x00d8, 0x080c, 0x82d4, 0x08c0, 0x080c, 0x9f14, 0x1118, 0x080c,
+	0x8ca5, 0x0090, 0x6010, 0x2068, 0x080c, 0x9d16, 0x0168, 0x601c,
+	0xa086, 0x0003, 0x11f8, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000,
+	0x080c, 0x547a, 0x080c, 0x9ecd, 0x080c, 0xa0db, 0x080c, 0x9ed9,
+	0x080c, 0x81a5, 0x00ce, 0x0804, 0x832e, 0x2c78, 0x600c, 0x2060,
+	0x0804, 0x832e, 0x012e, 0x000e, 0x006e, 0x00ce, 0x00de, 0x00ee,
+	0x00fe, 0x0005, 0x601c, 0xa086, 0x0006, 0x1d30, 0x080c, 0xb155,
+	0x0c18, 0x0036, 0x0156, 0x0136, 0x0146, 0x3908, 0xa006, 0xa190,
+	0x0020, 0x221c, 0xa39e, 0x2aec, 0x1118, 0x8210, 0x8000, 0x0cc8,
+	0xa005, 0x0138, 0x20a9, 0x0020, 0x2198, 0xa110, 0x22a0, 0x22c8,
+	0x53a3, 0x014e, 0x013e, 0x015e, 0x003e, 0x0005, 0x00d6, 0x20a1,
+	0x020b, 0x080c, 0x774f, 0x20a3, 0x0200, 0x20a3, 0x0014, 0x60c3,
+	0x0014, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x2099, 0xb8b9, 0x20a9,
+	0x0004, 0x53a6, 0x20a3, 0x0004, 0x20a3, 0x7878, 0x20a3, 0x0000,
+	0x20a3, 0x0000, 0x080c, 0x7de0, 0x00de, 0x0005, 0x20a1, 0x020b,
+	0x080c, 0x774f, 0x20a3, 0x0214, 0x20a3, 0x0018, 0x20a3, 0x0800,
+	0x7810, 0xa084, 0xff00, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000,
+	0x20a3, 0x0000, 0x20a3, 0x0000, 0x7810, 0xa084, 0x00ff, 0x20a2,
+	0x7828, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0018,
+	0x080c, 0x7de0, 0x0005, 0x00d6, 0x0016, 0x2f68, 0x2009, 0x0035,
+	0x080c, 0xa1c6, 0x1904, 0x8489, 0x20a1, 0x020b, 0x080c, 0x76b3,
+	0x20a3, 0x1300, 0x20a3, 0x0000, 0x7828, 0x2068, 0x681c, 0xa086,
+	0x0003, 0x0580, 0x7818, 0xa080, 0x0028, 0x2014, 0x2001, 0xb635,
+	0x2004, 0xd0ac, 0x11d0, 0xa286, 0x007e, 0x1128, 0x20a3, 0x00ff,
+	0x20a3, 0xfffe, 0x04b8, 0xa286, 0x007f, 0x1128, 0x20a3, 0x00ff,
+	0x20a3, 0xfffd, 0x0478, 0xd2bc, 0x0180, 0xa286, 0x0080, 0x1128,
+	0x20a3, 0x00ff, 0x20a3, 0xfffc, 0x0428, 0xa2e8, 0xb735, 0x2d6c,
+	0x6810, 0x20a2, 0x6814, 0x20a2, 0x00e8, 0x20a3, 0x0000, 0x6098,
+	0x20a2, 0x00c0, 0x2001, 0xb635, 0x2004, 0xd0ac, 0x1138, 0x7818,
+	0xa080, 0x0028, 0x2004, 0xa082, 0x007e, 0x0240, 0x00d6, 0x2069,
+	0xb61c, 0x2da6, 0x8d68, 0x2da6, 0x00de, 0x0020, 0x20a3, 0x0000,
+	0x6034, 0x20a2, 0x7834, 0x20a2, 0x7838, 0x20a2, 0x20a3, 0x0000,
+	0x20a3, 0x0000, 0x60c3, 0x000c, 0x080c, 0x7de0, 0x001e, 0x00de,
+	0x0005, 0x7817, 0x0001, 0x7803, 0x0006, 0x001e, 0x00de, 0x0005,
+	0x00d6, 0x0026, 0x7928, 0x2168, 0x691c, 0xa186, 0x0006, 0x01c0,
+	0xa186, 0x0003, 0x0904, 0x84ff, 0xa186, 0x0005, 0x0904, 0x84e8,
+	0xa186, 0x0004, 0x05b8, 0xa186, 0x0008, 0x0904, 0x84f0, 0x7807,
+	0x0037, 0x7813, 0x1700, 0x080c, 0x8567, 0x002e, 0x00de, 0x0005,
+	0x080c, 0x8523, 0x2009, 0x4000, 0x6800, 0x0002, 0x84c9, 0x84d4,
+	0x84cb, 0x84d4, 0x84d0, 0x84c9, 0x84c9, 0x84d4, 0x84d4, 0x84d4,
+	0x84d4, 0x84c9, 0x84c9, 0x84c9, 0x84c9, 0x84c9, 0x84d4, 0x84c9,
+	0x84d4, 0x080c, 0x151a, 0x6820, 0xd0e4, 0x0110, 0xd0cc, 0x0110,
+	0xa00e, 0x0010, 0x2009, 0x2000, 0x6828, 0x20a2, 0x682c, 0x20a2,
+	0x0804, 0x8519, 0x080c, 0x8523, 0x20a3, 0x0000, 0x20a3, 0x0000,
+	0x2009, 0x4000, 0x6a00, 0xa286, 0x0002, 0x1108, 0xa00e, 0x0488,
+	0x04d1, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x2009, 0x4000, 0x0448,
+	0x0491, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x2009, 0x4000, 0xa286,
+	0x0005, 0x0118, 0xa286, 0x0002, 0x1108, 0xa00e, 0x00d0, 0x0419,
+	0x6810, 0x2068, 0x697c, 0x6810, 0xa112, 0x6980, 0x6814, 0xa103,
+	0x20a2, 0x22a2, 0x7928, 0xa180, 0x0000, 0x2004, 0xa08e, 0x0002,
+	0x0130, 0xa08e, 0x0004, 0x0118, 0x2009, 0x4000, 0x0010, 0x2009,
+	0x0000, 0x21a2, 0x20a3, 0x0000, 0x60c3, 0x0018, 0x080c, 0x7de0,
+	0x002e, 0x00de, 0x0005, 0x0036, 0x0046, 0x0056, 0x0066, 0x20a1,
+	0x020b, 0x080c, 0x774f, 0xa006, 0x20a3, 0x0200, 0x20a2, 0x7934,
+	0x21a2, 0x7938, 0x21a2, 0x7818, 0xa080, 0x0028, 0x2004, 0x2011,
+	0xb635, 0x2214, 0xd2ac, 0x1118, 0xa092, 0x007e, 0x0268, 0x00d6,
+	0x2069, 0xb61c, 0x2d2c, 0x8d68, 0x2d34, 0xa0e8, 0xb735, 0x2d6c,
+	0x6b10, 0x6c14, 0x00de, 0x0030, 0x2019, 0x0000, 0x6498, 0x2029,
+	0x0000, 0x6634, 0x7828, 0xa080, 0x0007, 0x2004, 0xa086, 0x0003,
+	0x1128, 0x25a2, 0x26a2, 0x23a2, 0x24a2, 0x0020, 0x23a2, 0x24a2,
+	0x25a2, 0x26a2, 0x006e, 0x005e, 0x004e, 0x003e, 0x0005, 0x20a1,
+	0x020b, 0x080c, 0x774f, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x20a3,
+	0x0009, 0x7810, 0x20a2, 0x60c3, 0x0008, 0x080c, 0x7de0, 0x0005,
+	0x20a1, 0x020b, 0x080c, 0x76ab, 0x20a3, 0x1400, 0x20a3, 0x0000,
+	0x7834, 0x20a2, 0x7838, 0x20a2, 0x7828, 0x20a2, 0x782c, 0x20a2,
+	0x7830, 0xa084, 0x00ff, 0x8007, 0x20a2, 0x20a3, 0x0000, 0x60c3,
+	0x0010, 0x080c, 0x7de0, 0x0005, 0x20a1, 0x020b, 0x080c, 0x7747,
+	0x20a3, 0x0100, 0x20a3, 0x0000, 0x7828, 0x20a2, 0x7810, 0x20a2,
+	0x60c3, 0x0008, 0x080c, 0x7de0, 0x0005, 0x0146, 0x20a1, 0x020b,
+	0x0031, 0x60c3, 0x0000, 0x080c, 0x7de0, 0x014e, 0x0005, 0x20e1,
+	0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2004, 0x2011,
+	0xb635, 0x2214, 0xd2ac, 0x1110, 0xd0bc, 0x0188, 0x00d6, 0xa0e8,
+	0xb735, 0x2d6c, 0x6810, 0xa085, 0x0300, 0x20a2, 0x6814, 0x20a2,
+	0x2069, 0xb61c, 0x2da6, 0x8d68, 0x2da6, 0x00de, 0x0078, 0x00d6,
+	0xa0e8, 0xb735, 0x2d6c, 0x6810, 0xa085, 0x0300, 0x20a2, 0x6814,
+	0x20a2, 0x00de, 0x20a3, 0x0000, 0x6234, 0x22a2, 0x20a3, 0x0819,
+	0x20a3, 0x0000, 0x080c, 0x7dcf, 0x22a2, 0x20a3, 0x0000, 0x2fa2,
+	0x7a08, 0x22a2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x0005, 0x20a1,
+	0x020b, 0x0079, 0x7910, 0x21a2, 0x20a3, 0x0000, 0x60c3, 0x0000,
+	0x20e1, 0x9080, 0x60a7, 0x9575, 0x080c, 0x7dea, 0x080c, 0x6a79,
+	0x0005, 0x0156, 0x0136, 0x0036, 0x00d6, 0x00e6, 0x20e1, 0x9080,
+	0x20e1, 0x4000, 0x7854, 0x2068, 0xadf0, 0x000f, 0x7210, 0xa296,
+	0x00c0, 0xa294, 0xfffd, 0x7212, 0x7214, 0xa294, 0x0300, 0x7216,
+	0x7100, 0xa194, 0x00ff, 0x7308, 0xa384, 0x00ff, 0xa08d, 0xc200,
+	0x7102, 0xa384, 0xff00, 0xa215, 0x720a, 0x7004, 0x720c, 0x700e,
+	0x7206, 0x20a9, 0x000a, 0x2e98, 0x53a6, 0x60a3, 0x0035, 0x6a38,
+	0xa294, 0x7000, 0xa286, 0x3000, 0x0110, 0x60a3, 0x0037, 0x00ee,
+	0x00de, 0x003e, 0x013e, 0x015e, 0x0005, 0x2009, 0x0092, 0x0010,
+	0x2009, 0x0096, 0x60ab, 0x0036, 0x6116, 0x0005, 0x2061, 0xbe00,
+	0x2a70, 0x7068, 0x704a, 0x704f, 0xbe00, 0x0005, 0x00e6, 0x0126,
+	0x2071, 0xb600, 0x2091, 0x8000, 0x7548, 0xa582, 0x0010, 0x0608,
+	0x704c, 0x2060, 0x6000, 0xa086, 0x0000, 0x0148, 0xace0, 0x0018,
+	0x705c, 0xac02, 0x1208, 0x0cb0, 0x2061, 0xbe00, 0x0c98, 0x6003,
+	0x0008, 0x8529, 0x754a, 0xaca8, 0x0018, 0x705c, 0xa502, 0x1230,
+	0x754e, 0xa085, 0x0001, 0x012e, 0x00ee, 0x0005, 0x704f, 0xbe00,
+	0x0cc0, 0xa006, 0x0cc0, 0x00e6, 0x2071, 0xb600, 0x7548, 0xa582,
+	0x0010, 0x0600, 0x704c, 0x2060, 0x6000, 0xa086, 0x0000, 0x0148,
+	0xace0, 0x0018, 0x705c, 0xac02, 0x1208, 0x0cb0, 0x2061, 0xbe00,
+	0x0c98, 0x6003, 0x0008, 0x8529, 0x754a, 0xaca8, 0x0018, 0x705c,
+	0xa502, 0x1228, 0x754e, 0xa085, 0x0001, 0x00ee, 0x0005, 0x704f,
+	0xbe00, 0x0cc8, 0xa006, 0x0cc8, 0xac82, 0xbe00, 0x0a0c, 0x151a,
+	0x2001, 0xb617, 0x2004, 0xac02, 0x1a0c, 0x151a, 0xa006, 0x6006,
+	0x600a, 0x600e, 0x6012, 0x6016, 0x601a, 0x601f, 0x0000, 0x6003,
+	0x0000, 0x6052, 0x6056, 0x6022, 0x6026, 0x602a, 0x602e, 0x6032,
+	0x6036, 0x603a, 0x603e, 0x2061, 0xb600, 0x6048, 0x8000, 0x604a,
+	0xa086, 0x0001, 0x0108, 0x0005, 0x0126, 0x2091, 0x8000, 0x080c,
+	0x71e5, 0x012e, 0x0cc0, 0x601c, 0xa084, 0x000f, 0x0002, 0x86e7,
+	0x86f6, 0x8711, 0x872c, 0xa20e, 0xa229, 0xa244, 0x86e7, 0x86f6,
+	0x86e7, 0x8747, 0x86e7, 0x86e7, 0x86e7, 0x86e7, 0x86e7, 0xa186,
+	0x0013, 0x1128, 0x080c, 0x7102, 0x080c, 0x71e5, 0x0005, 0xa18e,
+	0x0047, 0x1118, 0xa016, 0x080c, 0x1863, 0x0005, 0x0066, 0x6000,
+	0xa0b2, 0x0010, 0x1a0c, 0x151a, 0x0013, 0x006e, 0x0005, 0x870f,
+	0x8b27, 0x8cdf, 0x870f, 0x8d54, 0x8805, 0x870f, 0x870f, 0x8ab9,
+	0x917b, 0x870f, 0x870f, 0x870f, 0x870f, 0x870f, 0x870f, 0x080c,
+	0x151a, 0x0066, 0x6000, 0xa0b2, 0x0010, 0x1a0c, 0x151a, 0x0013,
+	0x006e, 0x0005, 0x872a, 0x97de, 0x872a, 0x872a, 0x872a, 0x872a,
+	0x872a, 0x872a, 0x9789, 0x994a, 0x872a, 0x980b, 0x9882, 0x980b,
+	0x9882, 0x872a, 0x080c, 0x151a, 0x0066, 0x6000, 0xa0b2, 0x0010,
+	0x1a0c, 0x151a, 0x0013, 0x006e, 0x0005, 0x8745, 0x91bc, 0x9286,
+	0x93c4, 0x954d, 0x8745, 0x8745, 0x8745, 0x9196, 0x9739, 0x973c,
+	0x8745, 0x8745, 0x8745, 0x8745, 0x9766, 0x080c, 0x151a, 0x0066,
+	0x6000, 0xa0b2, 0x0010, 0x1a0c, 0x151a, 0x0013, 0x006e, 0x0005,
+	0x8760, 0x8760, 0x8760, 0x878e, 0x87db, 0x8760, 0x8760, 0x8760,
+	0x8762, 0x8760, 0x8760, 0x8760, 0x8760, 0x8760, 0x8760, 0x8760,
+	0x080c, 0x151a, 0xa186, 0x0003, 0x190c, 0x151a, 0x00d6, 0x6003,
+	0x0003, 0x6106, 0x6010, 0x2068, 0x684f, 0x0040, 0x687c, 0x680a,
+	0x6880, 0x680e, 0x6813, 0x0000, 0x6817, 0x0000, 0x6854, 0xa092,
+	0x199a, 0x0210, 0x2001, 0x1999, 0x8003, 0x8013, 0x8213, 0xa210,
+	0x6216, 0x00de, 0x2c10, 0x080c, 0x1fc5, 0x080c, 0x6d62, 0x0126,
+	0x2091, 0x8000, 0x080c, 0x72a2, 0x012e, 0x0005, 0xa182, 0x0047,
+	0x0002, 0x879a, 0x879a, 0x879c, 0x87b5, 0x879a, 0x879a, 0x879a,
+	0x879a, 0x87c7, 0x080c, 0x151a, 0x00d6, 0x0016, 0x080c, 0x7198,
+	0x080c, 0x72a2, 0x6003, 0x0004, 0x6110, 0x2168, 0x684f, 0x0020,
+	0x685c, 0x685a, 0x6874, 0x687e, 0x6878, 0x6882, 0x6897, 0x0000,
+	0x689b, 0x0000, 0x001e, 0x00de, 0x0005, 0x080c, 0x7198, 0x00d6,
+	0x6110, 0x2168, 0x080c, 0x9d16, 0x0120, 0x684b, 0x0006, 0x080c,
+	0x547a, 0x00de, 0x080c, 0x86a4, 0x080c, 0x72a2, 0x0005, 0x080c,
+	0x7198, 0x080c, 0x2cd1, 0x00d6, 0x6110, 0x2168, 0x080c, 0x9d16,
+	0x0120, 0x684b, 0x0029, 0x080c, 0x547a, 0x00de, 0x080c, 0x86a4,
+	0x080c, 0x72a2, 0x0005, 0xa182, 0x0047, 0x0002, 0x87e9, 0x87f8,
+	0x87e7, 0x87e7, 0x87e7, 0x87e7, 0x87e7, 0x87e7, 0x87e7, 0x080c,
+	0x151a, 0x00d6, 0x6010, 0x2068, 0x684c, 0xc0f4, 0x684e, 0x00de,
+	0x20e1, 0x0005, 0x3d18, 0x3e20, 0x2c10, 0x080c, 0x1863, 0x0005,
+	0x00d6, 0x6110, 0x2168, 0x684b, 0x0000, 0x6853, 0x0000, 0x080c,
+	0x547a, 0x00de, 0x080c, 0x86a4, 0x0005, 0xa1b6, 0x0015, 0x1118,
+	0x080c, 0x86a4, 0x0030, 0xa1b6, 0x0016, 0x190c, 0x151a, 0x080c,
+	0x86a4, 0x0005, 0x20a9, 0x000e, 0x2e98, 0x6010, 0x20a0, 0x53a3,
+	0x20a9, 0x0006, 0x3310, 0x3420, 0x9398, 0x94a0, 0x3318, 0x3428,
+	0x222e, 0x2326, 0xa290, 0x0002, 0xa5a8, 0x0002, 0xa398, 0x0002,
+	0xa4a0, 0x0002, 0x1f04, 0x8820, 0x00e6, 0x080c, 0x9d16, 0x0130,
+	0x6010, 0x2070, 0x7007, 0x0000, 0x7037, 0x0103, 0x00ee, 0x080c,
+	0x86a4, 0x0005, 0x00d6, 0x0036, 0x7330, 0xa386, 0x0200, 0x1130,
+	0x6018, 0x2068, 0x6813, 0x00ff, 0x6817, 0xfffd, 0x6010, 0xa005,
+	0x0130, 0x2068, 0x6807, 0x0000, 0x6837, 0x0103, 0x6b32, 0x080c,
+	0x86a4, 0x003e, 0x00de, 0x0005, 0x0016, 0x20a9, 0x002a, 0xae80,
+	0x000c, 0x2098, 0x6010, 0xa080, 0x0002, 0x20a0, 0x53a3, 0x20a9,
+	0x002a, 0x6010, 0xa080, 0x0001, 0x2004, 0xa080, 0x0002, 0x20a0,
+	0x53a3, 0x00e6, 0x6010, 0x2004, 0x2070, 0x7037, 0x0103, 0x00ee,
+	0x080c, 0x86a4, 0x001e, 0x0005, 0x0016, 0x2009, 0x0000, 0x7030,
+	0xa086, 0x0100, 0x0140, 0x7038, 0xa084, 0x00ff, 0x800c, 0x703c,
+	0xa084, 0x00ff, 0x8004, 0xa080, 0x0004, 0xa108, 0x21a8, 0xae80,
+	0x000c, 0x2098, 0x6010, 0xa080, 0x0002, 0x20a0, 0x080c, 0x4bf1,
+	0x00e6, 0x080c, 0x9d16, 0x0140, 0x6010, 0x2070, 0x7007, 0x0000,
+	0x7034, 0x70b2, 0x7037, 0x0103, 0x00ee, 0x080c, 0x86a4, 0x001e,
+	0x0005, 0x00e6, 0x00d6, 0x603f, 0x0000, 0x2c68, 0x0016, 0x2009,
+	0x0035, 0x080c, 0xa1c6, 0x001e, 0x1168, 0x0026, 0x6228, 0x2268,
+	0x002e, 0x2071, 0xbc8c, 0x6b1c, 0xa386, 0x0003, 0x0130, 0xa386,
+	0x0006, 0x0128, 0x080c, 0x86a4, 0x0020, 0x0031, 0x0010, 0x080c,
+	0x8982, 0x00de, 0x00ee, 0x0005, 0x00f6, 0x6810, 0x2078, 0xa186,
+	0x0015, 0x0904, 0x8969, 0xa18e, 0x0016, 0x1904, 0x8980, 0x700c,
+	0xa08c, 0xff00, 0xa186, 0x1700, 0x0120, 0xa186, 0x0300, 0x1904,
+	0x8948, 0x8fff, 0x1138, 0x6800, 0xa086, 0x000f, 0x0904, 0x892c,
+	0x0804, 0x897e, 0x6808, 0xa086, 0xffff, 0x1904, 0x896b, 0x784c,
+	0xa084, 0x0060, 0xa086, 0x0020, 0x1150, 0x797c, 0x7810, 0xa106,
+	0x1904, 0x896b, 0x7980, 0x7814, 0xa106, 0x1904, 0x896b, 0x080c,
+	0x9ecd, 0x6858, 0x7852, 0x784c, 0xc0dc, 0xc0f4, 0xc0d4, 0x784e,
+	0x0026, 0xa00e, 0x6a14, 0x2001, 0x000a, 0x080c, 0x6bb2, 0x7854,
+	0xa20a, 0x0208, 0x8011, 0x7a56, 0x82ff, 0x002e, 0x1138, 0x00c6,
+	0x2d60, 0x080c, 0x9ac5, 0x00ce, 0x0804, 0x897e, 0x00c6, 0x00d6,
+	0x2f68, 0x6838, 0xd0fc, 0x1118, 0x080c, 0x4cd7, 0x0010, 0x080c,
+	0x4ebb, 0x00de, 0x00ce, 0x1904, 0x896b, 0x00c6, 0x2d60, 0x080c,
+	0x86a4, 0x00ce, 0x0804, 0x897e, 0x00c6, 0x080c, 0x9f92, 0x0190,
+	0x6013, 0x0000, 0x6818, 0x601a, 0x080c, 0xa0e3, 0x601f, 0x0003,
+	0x6904, 0x00c6, 0x2d60, 0x080c, 0x86a4, 0x00ce, 0x080c, 0x86d3,
+	0x00ce, 0x04e0, 0x2001, 0xb8b8, 0x2004, 0x683e, 0x00ce, 0x04b0,
+	0x7008, 0xa086, 0x000b, 0x11a0, 0x6018, 0x200c, 0xc1bc, 0x2102,
+	0x00c6, 0x2d60, 0x784b, 0x0003, 0x6007, 0x0085, 0x6003, 0x000b,
+	0x601f, 0x0002, 0x080c, 0x6cff, 0x080c, 0x71e5, 0x00ce, 0x00f0,
+	0x700c, 0xa086, 0x2a00, 0x1138, 0x2001, 0xb8b8, 0x2004, 0x683e,
+	0x00a8, 0x0481, 0x00a8, 0x8fff, 0x090c, 0x151a, 0x00c6, 0x00d6,
+	0x2d60, 0x2f68, 0x6837, 0x0103, 0x684b, 0x0003, 0x080c, 0x99b9,
+	0x080c, 0x9ecd, 0x080c, 0x9ed9, 0x00de, 0x00ce, 0x080c, 0x86a4,
+	0x00fe, 0x0005, 0xa186, 0x0015, 0x1128, 0x2001, 0xb8b8, 0x2004,
+	0x683e, 0x0068, 0xa18e, 0x0016, 0x1160, 0x00c6, 0x2d00, 0x2060,
+	0x080c, 0xb3f6, 0x080c, 0x6b61, 0x080c, 0x86a4, 0x00ce, 0x080c,
+	0x86a4, 0x0005, 0x0026, 0x0036, 0x0046, 0x7228, 0x7c80, 0x7b7c,
+	0xd2f4, 0x0130, 0x2001, 0xb8b8, 0x2004, 0x683e, 0x0804, 0x89fc,
+	0x00c6, 0x2d60, 0x080c, 0x99d9, 0x00ce, 0x6804, 0xa086, 0x0050,
+	0x1168, 0x00c6, 0x2d00, 0x2060, 0x6003, 0x0001, 0x6007, 0x0050,
+	0x080c, 0x6cff, 0x080c, 0x71e5, 0x00ce, 0x04f0, 0x6800, 0xa086,
+	0x000f, 0x01c8, 0x8fff, 0x090c, 0x151a, 0x6820, 0xd0dc, 0x1198,
+	0x6800, 0xa086, 0x0004, 0x1198, 0x784c, 0xd0ac, 0x0180, 0x784c,
+	0xc0dc, 0xc0f4, 0x784e, 0x7850, 0xc0f4, 0xc0fc, 0x7852, 0x2001,
+	0x0001, 0x682e, 0x00e0, 0x2001, 0x0007, 0x682e, 0x00c0, 0x784c,
+	0xd0b4, 0x1130, 0xd0ac, 0x0db8, 0x784c, 0xd0f4, 0x1da0, 0x0c38,
+	0xd2ec, 0x1d88, 0x7024, 0xa306, 0x1118, 0x7020, 0xa406, 0x0d58,
+	0x7020, 0x6836, 0x7024, 0x683a, 0x2001, 0x0005, 0x682e, 0x080c,
+	0xa01f, 0x080c, 0x71e5, 0x0010, 0x080c, 0x86a4, 0x004e, 0x003e,
+	0x002e, 0x0005, 0x00e6, 0x00d6, 0x0026, 0x6034, 0x2068, 0x6a1c,
+	0xa286, 0x0007, 0x0904, 0x8a60, 0xa286, 0x0002, 0x0904, 0x8a60,
+	0xa286, 0x0000, 0x0904, 0x8a60, 0x6808, 0x6338, 0xa306, 0x1904,
+	0x8a60, 0x2071, 0xbc8c, 0xa186, 0x0015, 0x05e0, 0xa18e, 0x0016,
+	0x1190, 0x6030, 0xa084, 0x00ff, 0xa086, 0x0001, 0x1160, 0x700c,
+	0xa086, 0x2a00, 0x1140, 0x6034, 0xa080, 0x0008, 0x200c, 0xc1dd,
+	0xc1f5, 0x2102, 0x0438, 0x00c6, 0x6034, 0x2060, 0x6104, 0xa186,
+	0x004b, 0x01a0, 0xa186, 0x004c, 0x0188, 0xa186, 0x004d, 0x0170,
+	0xa186, 0x004e, 0x0158, 0xa186, 0x0052, 0x0140, 0x6010, 0x2068,
+	0x080c, 0x9d16, 0x090c, 0x151a, 0x684b, 0x0003, 0x6007, 0x0085,
+	0x6003, 0x000b, 0x601f, 0x0002, 0x080c, 0x6cff, 0x080c, 0x71e5,
+	0x00ce, 0x0030, 0x6034, 0x2070, 0x2001, 0xb8b8, 0x2004, 0x703e,
+	0x080c, 0x86a4, 0x002e, 0x00de, 0x00ee, 0x0005, 0x00d6, 0x20a9,
+	0x000e, 0x2e98, 0x6010, 0x20a0, 0x53a3, 0xa1b6, 0x0015, 0x1558,
+	0x6018, 0x2068, 0x0156, 0x0036, 0x0026, 0xae90, 0x000c, 0xa290,
+	0x0004, 0x20a9, 0x0004, 0xad98, 0x000a, 0x080c, 0x9166, 0x002e,
+	0x003e, 0x015e, 0x11d8, 0x0156, 0x0036, 0x0026, 0xae90, 0x000c,
+	0xa290, 0x0008, 0x20a9, 0x0004, 0xad98, 0x0006, 0x080c, 0x9166,
+	0x002e, 0x003e, 0x015e, 0x1150, 0x7038, 0x680a, 0x703c, 0x680e,
+	0x6800, 0xc08d, 0x6802, 0x00de, 0x0804, 0x882c, 0x080c, 0x2cd1,
+	0x00c6, 0x080c, 0x864e, 0x2f00, 0x601a, 0x6013, 0x0000, 0x601f,
+	0x0001, 0x6007, 0x0001, 0x6003, 0x0001, 0x2001, 0x0007, 0x080c,
+	0x4f6f, 0x080c, 0x4f9c, 0x080c, 0x6d45, 0x080c, 0x71e5, 0x00ce,
+	0x0c10, 0x2100, 0xa1b2, 0x0080, 0x1a0c, 0x151a, 0xa1b2, 0x0040,
+	0x1a04, 0x8b1d, 0x0002, 0x8b11, 0x8b05, 0x8b11, 0x8b11, 0x8b11,
+	0x8b11, 0x8b03, 0x8b03, 0x8b03, 0x8b03, 0x8b03, 0x8b03, 0x8b03,
+	0x8b03, 0x8b03, 0x8b03, 0x8b03, 0x8b03, 0x8b03, 0x8b03, 0x8b03,
+	0x8b03, 0x8b03, 0x8b03, 0x8b03, 0x8b03, 0x8b03, 0x8b03, 0x8b03,
+	0x8b03, 0x8b03, 0x8b11, 0x8b03, 0x8b11, 0x8b11, 0x8b03, 0x8b03,
+	0x8b03, 0x8b03, 0x8b03, 0x8b11, 0x8b03, 0x8b03, 0x8b03, 0x8b03,
+	0x8b03, 0x8b03, 0x8b03, 0x8b03, 0x8b03, 0x8b11, 0x8b11, 0x8b03,
+	0x8b03, 0x8b03, 0x8b03, 0x8b03, 0x8b03, 0x8b03, 0x8b03, 0x8b03,
+	0x8b11, 0x8b03, 0x8b03, 0x080c, 0x151a, 0x6003, 0x0001, 0x6106,
+	0x080c, 0x6d45, 0x0126, 0x2091, 0x8000, 0x080c, 0x71e5, 0x012e,
+	0x0005, 0x6003, 0x0001, 0x6106, 0x080c, 0x6d45, 0x0126, 0x2091,
+	0x8000, 0x080c, 0x71e5, 0x012e, 0x0005, 0x2600, 0x0002, 0x8b11,
+	0x8b11, 0x8b25, 0x8b11, 0x8b11, 0x8b25, 0x080c, 0x151a, 0x6004,
+	0xa0b2, 0x0080, 0x1a0c, 0x151a, 0xa1b6, 0x0013, 0x0904, 0x8bd7,
+	0xa1b6, 0x0027, 0x1904, 0x8b9d, 0x080c, 0x7102, 0x6004, 0x080c,
+	0x9f03, 0x0190, 0x080c, 0x9f14, 0x0904, 0x8b97, 0xa08e, 0x0021,
+	0x0904, 0x8b9a, 0xa08e, 0x0022, 0x0904, 0x8b97, 0xa08e, 0x003d,
+	0x0904, 0x8b9a, 0x0804, 0x8b90, 0x080c, 0x2cf7, 0x2001, 0x0007,
+	0x080c, 0x4f6f, 0x6018, 0xa080, 0x0028, 0x200c, 0x080c, 0x8ca5,
+	0xa186, 0x007e, 0x1148, 0x2001, 0xb635, 0x2014, 0xc285, 0x080c,
+	0x5b41, 0x1108, 0xc2ad, 0x2202, 0x0016, 0x0026, 0x0036, 0x2110,
+	0x0026, 0x2019, 0x0028, 0x080c, 0x8320, 0x002e, 0x080c, 0xb449,
+	0x003e, 0x002e, 0x001e, 0x0016, 0x0026, 0x0036, 0x2110, 0x2019,
+	0x0028, 0x080c, 0x6e67, 0x0076, 0x2039, 0x0000, 0x080c, 0x6d74,
+	0x00c6, 0x6018, 0xa065, 0x0110, 0x080c, 0x521c, 0x00ce, 0x2c08,
+	0x080c, 0xaf3e, 0x007e, 0x003e, 0x002e, 0x001e, 0x080c, 0x4fde,
+	0x080c, 0xa0db, 0x080c, 0x86a4, 0x080c, 0x71e5, 0x0005, 0x080c,
+	0x8ca5, 0x0cb0, 0x080c, 0x8cd3, 0x0c98, 0xa186, 0x0014, 0x1db0,
+	0x080c, 0x7102, 0x080c, 0x2cd1, 0x080c, 0x9f03, 0x1188, 0x080c,
+	0x2cf7, 0x6018, 0xa080, 0x0028, 0x200c, 0x080c, 0x8ca5, 0xa186,
+	0x007e, 0x1128, 0x2001, 0xb635, 0x200c, 0xc185, 0x2102, 0x08c0,
+	0x080c, 0x9f14, 0x1118, 0x080c, 0x8ca5, 0x0890, 0x6004, 0xa08e,
+	0x0032, 0x1158, 0x00e6, 0x00f6, 0x2071, 0xb682, 0x2079, 0x0000,
+	0x080c, 0x3004, 0x00fe, 0x00ee, 0x0818, 0x6004, 0xa08e, 0x0021,
+	0x0d50, 0xa08e, 0x0022, 0x090c, 0x8ca5, 0x0804, 0x8b90, 0xa0b2,
+	0x0040, 0x1a04, 0x8c9a, 0x2008, 0x0002, 0x8c1f, 0x8c20, 0x8c23,
+	0x8c26, 0x8c29, 0x8c2c, 0x8c1d, 0x8c1d, 0x8c1d, 0x8c1d, 0x8c1d,
+	0x8c1d, 0x8c1d, 0x8c1d, 0x8c1d, 0x8c1d, 0x8c1d, 0x8c1d, 0x8c1d,
+	0x8c1d, 0x8c1d, 0x8c1d, 0x8c1d, 0x8c1d, 0x8c1d, 0x8c1d, 0x8c1d,
+	0x8c1d, 0x8c1d, 0x8c1d, 0x8c2f, 0x8c3e, 0x8c1d, 0x8c40, 0x8c3e,
+	0x8c1d, 0x8c1d, 0x8c1d, 0x8c1d, 0x8c1d, 0x8c3e, 0x8c3e, 0x8c1d,
+	0x8c1d, 0x8c1d, 0x8c1d, 0x8c1d, 0x8c1d, 0x8c1d, 0x8c1d, 0x8c7a,
+	0x8c3e, 0x8c1d, 0x8c3a, 0x8c1d, 0x8c1d, 0x8c1d, 0x8c3b, 0x8c1d,
+	0x8c1d, 0x8c1d, 0x8c3e, 0x8c71, 0x8c1d, 0x080c, 0x151a, 0x00f0,
+	0x2001, 0x000b, 0x0460, 0x2001, 0x0003, 0x0448, 0x2001, 0x0005,
+	0x0430, 0x2001, 0x0001, 0x0418, 0x2001, 0x0009, 0x0400, 0x080c,
+	0x7102, 0x6003, 0x0005, 0x2001, 0xb8b8, 0x2004, 0x603e, 0x080c,
+	0x71e5, 0x00a0, 0x0018, 0x0010, 0x080c, 0x4f6f, 0x0804, 0x8c8b,
+	0x080c, 0x7102, 0x2001, 0xb8b6, 0x2004, 0x6016, 0x2001, 0xb8b8,
+	0x2004, 0x603e, 0x6003, 0x0004, 0x080c, 0x71e5, 0x0005, 0x080c,
+	0x4f6f, 0x080c, 0x7102, 0x6003, 0x0002, 0x2001, 0xb8b8, 0x2004,
+	0x603e, 0x0036, 0x2019, 0xb65d, 0x2304, 0xa084, 0xff00, 0x1120,
+	0x2001, 0xb8b6, 0x201c, 0x0040, 0x8007, 0xa09a, 0x0004, 0x0ec0,
+	0x8003, 0x801b, 0x831b, 0xa318, 0x6316, 0x003e, 0x080c, 0x71e5,
+	0x08e8, 0x080c, 0x7102, 0x080c, 0xa0db, 0x080c, 0x86a4, 0x080c,
+	0x71e5, 0x08a0, 0x00e6, 0x00f6, 0x2071, 0xb682, 0x2079, 0x0000,
+	0x080c, 0x3004, 0x00fe, 0x00ee, 0x080c, 0x7102, 0x080c, 0x86a4,
+	0x080c, 0x71e5, 0x0818, 0x080c, 0x7102, 0x2001, 0xb8b8, 0x2004,
+	0x603e, 0x6003, 0x0002, 0x2001, 0xb8b6, 0x2004, 0x6016, 0x080c,
+	0x71e5, 0x0005, 0x2600, 0x2008, 0x0002, 0x8ca3, 0x8ca3, 0x8ca3,
+	0x8c8b, 0x8c8b, 0x8ca3, 0x080c, 0x151a, 0x00e6, 0x0026, 0x0016,
+	0x080c, 0x9d16, 0x0508, 0x6010, 0x2070, 0x7034, 0xa086, 0x0139,
+	0x1148, 0x2001, 0x0030, 0x2009, 0x0000, 0x2011, 0x4005, 0x080c,
+	0xa192, 0x0090, 0x7038, 0xd0fc, 0x0178, 0x7007, 0x0000, 0x0016,
+	0x6004, 0xa08e, 0x0021, 0x0160, 0xa08e, 0x003d, 0x0148, 0x001e,
+	0x7037, 0x0103, 0x7033, 0x0100, 0x001e, 0x002e, 0x00ee, 0x0005,
+	0x001e, 0x0009, 0x0cc8, 0x00e6, 0xacf0, 0x0004, 0x2e74, 0x7000,
+	0x2070, 0x7037, 0x0103, 0x7023, 0x8001, 0x00ee, 0x0005, 0x00d6,
+	0x6618, 0x2668, 0x6804, 0xa084, 0x00ff, 0x00de, 0xa0b2, 0x000c,
+	0x1a0c, 0x151a, 0x6604, 0xa6b6, 0x0043, 0x1120, 0x080c, 0xa14e,
+	0x0804, 0x8d44, 0x6604, 0xa6b6, 0x0033, 0x1120, 0x080c, 0xa0fe,
+	0x0804, 0x8d44, 0x6604, 0xa6b6, 0x0028, 0x1120, 0x080c, 0x9f44,
+	0x0804, 0x8d44, 0x6604, 0xa6b6, 0x0029, 0x1118, 0x080c, 0x9f5b,
+	0x04d8, 0x6604, 0xa6b6, 0x001f, 0x1118, 0x080c, 0x8812, 0x04a0,
+	0x6604, 0xa6b6, 0x0000, 0x1118, 0x080c, 0x8a66, 0x0468, 0x6604,
+	0xa6b6, 0x0022, 0x1118, 0x080c, 0x883a, 0x0430, 0x6604, 0xa6b6,
+	0x0035, 0x1118, 0x080c, 0x88a1, 0x00f8, 0x6604, 0xa6b6, 0x0039,
+	0x1118, 0x080c, 0x8a02, 0x00c0, 0x6604, 0xa6b6, 0x003d, 0x1118,
+	0x080c, 0x8854, 0x0088, 0x6604, 0xa6b6, 0x0044, 0x1118, 0x080c,
+	0x8874, 0x0050, 0xa1b6, 0x0015, 0x1110, 0x0053, 0x0028, 0xa1b6,
+	0x0016, 0x1118, 0x0804, 0x8f08, 0x0005, 0x080c, 0x86ef, 0x0ce0,
+	0x8d6b, 0x8d6e, 0x8d6b, 0x8db0, 0x8d6b, 0x8e95, 0x8f16, 0x8d6b,
+	0x8d6b, 0x8ee4, 0x8d6b, 0x8ef8, 0xa1b6, 0x0048, 0x0140, 0x20e1,
+	0x0005, 0x3d18, 0x3e20, 0x2c10, 0x080c, 0x1863, 0x0005, 0x00e6,
+	0xacf0, 0x0004, 0x2e74, 0x7000, 0x2070, 0x7037, 0x0103, 0x00ee,
+	0x080c, 0x86a4, 0x0005, 0xe000, 0xe000, 0x0005, 0x00e6, 0x2071,
+	0xb600, 0x7084, 0xa086, 0x0074, 0x1530, 0x080c, 0xaf15, 0x11b0,
+	0x00d6, 0x6018, 0x2068, 0x7030, 0xd08c, 0x0128, 0x6800, 0xd0bc,
+	0x0110, 0xc0c5, 0x6802, 0x00d9, 0x00de, 0x2001, 0x0006, 0x080c,
+	0x4f6f, 0x080c, 0x2cf7, 0x080c, 0x86a4, 0x0078, 0x2001, 0x000a,
+	0x080c, 0x4f6f, 0x080c, 0x2cf7, 0x6003, 0x0001, 0x6007, 0x0001,
+	0x080c, 0x6d45, 0x0010, 0x080c, 0x8e82, 0x00ee, 0x0005, 0x6800,
+	0xd084, 0x0168, 0x2001, 0x0000, 0x080c, 0x4f5d, 0x2069, 0xb652,
+	0x6804, 0xd0a4, 0x0120, 0x2001, 0x0006, 0x080c, 0x4f9c, 0x0005,
+	0x00d6, 0x2011, 0xb621, 0x2204, 0xa086, 0x0074, 0x1904, 0x8e7f,
+	0x6018, 0x2068, 0x6aa0, 0xa286, 0x007e, 0x1120, 0x080c, 0x902e,
+	0x0804, 0x8e1e, 0x080c, 0x9024, 0x6018, 0x2068, 0xa080, 0x0028,
+	0x2014, 0xa286, 0x0080, 0x11c0, 0x6813, 0x00ff, 0x6817, 0xfffc,
+	0x6010, 0xa005, 0x0138, 0x2068, 0x6807, 0x0000, 0x6837, 0x0103,
+	0x6833, 0x0200, 0x2001, 0x0006, 0x080c, 0x4f6f, 0x080c, 0x2cf7,
+	0x080c, 0x86a4, 0x0804, 0x8e80, 0x00e6, 0x2071, 0xb635, 0x2e04,
+	0xd09c, 0x0188, 0x2071, 0xbc80, 0x7108, 0x720c, 0xa18c, 0x00ff,
+	0x1118, 0xa284, 0xff00, 0x0138, 0x6018, 0x2070, 0x70a0, 0xd0bc,
+	0x1110, 0x7112, 0x7216, 0x00ee, 0x6010, 0xa005, 0x0198, 0x2068,
+	0x6838, 0xd0f4, 0x0178, 0x6834, 0xa084, 0x00ff, 0xa086, 0x0039,
+	0x1958, 0x2001, 0x0000, 0x2009, 0x0000, 0x2011, 0x4000, 0x080c,
+	0xa192, 0x0840, 0x2001, 0x0004, 0x080c, 0x4f6f, 0x6003, 0x0001,
+	0x6007, 0x0003, 0x080c, 0x6d45, 0x0804, 0x8e80, 0x685c, 0xd0e4,
+	0x01d8, 0x080c, 0xa08e, 0x080c, 0x5b41, 0x0118, 0xd0dc, 0x1904,
+	0x8dda, 0x2011, 0xb635, 0x2204, 0xc0ad, 0x2012, 0x2001, 0xb88f,
+	0x2004, 0x00f6, 0x2079, 0x0100, 0x78e3, 0x0000, 0x080c, 0x28a7,
+	0x78e2, 0x00fe, 0x0804, 0x8dda, 0x080c, 0xa0c4, 0x2011, 0xb635,
+	0x2204, 0xc0a5, 0x2012, 0x0006, 0x080c, 0xb037, 0x000e, 0x1904,
+	0x8dda, 0xc0b5, 0x2012, 0x2001, 0x0006, 0x080c, 0x4f6f, 0x2001,
+	0x0000, 0x080c, 0x4f5d, 0x00c6, 0x2009, 0x00ef, 0x00f6, 0x2079,
+	0x0100, 0x79ea, 0x7932, 0x7936, 0x00fe, 0x080c, 0x287c, 0x00f6,
+	0x2079, 0xb600, 0x7976, 0x2100, 0x2009, 0x0000, 0x080c, 0x2852,
+	0x7952, 0x00fe, 0x8108, 0x080c, 0x4fbf, 0x2c00, 0x00ce, 0x1904,
+	0x8dda, 0x601a, 0x2001, 0x0002, 0x080c, 0x4f6f, 0x601f, 0x0001,
+	0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x6d45, 0x0008, 0x0011,
+	0x00de, 0x0005, 0x2001, 0x0007, 0x080c, 0x4f6f, 0x2001, 0xb600,
+	0x2004, 0xa086, 0x0003, 0x1120, 0x2001, 0x0007, 0x080c, 0x4f9c,
+	0x080c, 0x2cf7, 0x080c, 0x86a4, 0x0005, 0x00e6, 0x0026, 0x0016,
+	0x2071, 0xb600, 0x7084, 0xa086, 0x0014, 0x15f0, 0x7000, 0xa086,
+	0x0003, 0x1128, 0x6010, 0xa005, 0x1110, 0x080c, 0x3f85, 0x00d6,
+	0x6018, 0x2068, 0x080c, 0x50bd, 0x080c, 0x8d9f, 0x00de, 0x080c,
+	0x90dd, 0x1550, 0x00d6, 0x6018, 0x2068, 0x6890, 0x00de, 0xa005,
+	0x0518, 0x2001, 0x0006, 0x080c, 0x4f6f, 0x00e6, 0x6010, 0xa075,
+	0x01a8, 0x7034, 0xa084, 0x00ff, 0xa086, 0x0039, 0x1148, 0x2001,
+	0x0000, 0x2009, 0x0000, 0x2011, 0x4000, 0x080c, 0xa192, 0x0030,
+	0x7007, 0x0000, 0x7037, 0x0103, 0x7033, 0x0200, 0x00ee, 0x080c,
+	0x2cf7, 0x080c, 0x86a4, 0x0020, 0x080c, 0x8ca5, 0x080c, 0x8e82,
+	0x001e, 0x002e, 0x00ee, 0x0005, 0x2011, 0xb621, 0x2204, 0xa086,
+	0x0014, 0x1158, 0x2001, 0x0002, 0x080c, 0x4f6f, 0x6003, 0x0001,
+	0x6007, 0x0001, 0x080c, 0x6d45, 0x0010, 0x080c, 0x8e82, 0x0005,
+	0x2011, 0xb621, 0x2204, 0xa086, 0x0004, 0x1138, 0x2001, 0x0007,
+	0x080c, 0x4f6f, 0x080c, 0x86a4, 0x0010, 0x080c, 0x8e82, 0x0005,
+	0x000b, 0x0005, 0x8d6b, 0x8f21, 0x8d6b, 0x8f55, 0x8d6b, 0x8fe0,
+	0x8f16, 0x8d6b, 0x8d6b, 0x8ff3, 0x8d6b, 0x9003, 0x6604, 0xa686,
+	0x0003, 0x0904, 0x8e95, 0xa6b6, 0x001e, 0x1110, 0x080c, 0x86a4,
+	0x0005, 0x00d6, 0x00c6, 0x080c, 0x9013, 0x1178, 0x2001, 0x0000,
+	0x080c, 0x4f5d, 0x2001, 0x0002, 0x080c, 0x4f6f, 0x6003, 0x0001,
+	0x6007, 0x0002, 0x080c, 0x6d45, 0x00e8, 0x2009, 0xbc8e, 0x2104,
+	0xa086, 0x0009, 0x1160, 0x6018, 0x2068, 0x6840, 0xa084, 0x00ff,
+	0xa005, 0x0170, 0x8001, 0x6842, 0x6017, 0x000a, 0x0058, 0x2009,
+	0xbc8f, 0x2104, 0xa084, 0xff00, 0xa086, 0x1900, 0x1108, 0x08d0,
+	0x080c, 0x8e82, 0x00ce, 0x00de, 0x0005, 0x0026, 0x2011, 0x0000,
+	0x080c, 0x9021, 0x00d6, 0x2069, 0xb89e, 0x2d04, 0xa005, 0x0168,
+	0x6018, 0x2068, 0x68a0, 0xa086, 0x007e, 0x1138, 0x2069, 0xb61d,
+	0x2d04, 0x8000, 0x206a, 0x00de, 0x0010, 0x00de, 0x0078, 0x2001,
+	0x0000, 0x080c, 0x4f5d, 0x2001, 0x0002, 0x080c, 0x4f6f, 0x6003,
+	0x0001, 0x6007, 0x0002, 0x080c, 0x6d45, 0x0480, 0x00d6, 0x6010,
+	0x2068, 0x080c, 0x9d16, 0x00de, 0x0108, 0x6a34, 0x080c, 0x8ca5,
+	0x2009, 0xbc8e, 0x2134, 0xa6b4, 0x00ff, 0xa686, 0x0005, 0x0500,
+	0xa686, 0x000b, 0x01c8, 0x2009, 0xbc8f, 0x2104, 0xa084, 0xff00,
+	0x1118, 0xa686, 0x0009, 0x01a0, 0xa086, 0x1900, 0x1168, 0xa686,
+	0x0009, 0x0170, 0x2001, 0x0004, 0x080c, 0x4f6f, 0x2001, 0x0028,
+	0x6016, 0x6007, 0x004b, 0x0010, 0x080c, 0x8e82, 0x002e, 0x0005,
+	0x00d6, 0xa286, 0x0139, 0x0160, 0x6010, 0x2068, 0x080c, 0x9d16,
+	0x0148, 0x6834, 0xa086, 0x0139, 0x0118, 0x6838, 0xd0fc, 0x0110,
+	0x00de, 0x0c50, 0x6018, 0x2068, 0x6840, 0xa084, 0x00ff, 0xa005,
+	0x0140, 0x8001, 0x6842, 0x6017, 0x000a, 0x6007, 0x0016, 0x00de,
+	0x08e8, 0x68a0, 0xa086, 0x007e, 0x1138, 0x00e6, 0x2071, 0xb600,
+	0x080c, 0x4c28, 0x00ee, 0x0010, 0x080c, 0x2cd1, 0x00de, 0x0860,
+	0x080c, 0x9021, 0x1158, 0x2001, 0x0004, 0x080c, 0x4f6f, 0x6003,
+	0x0001, 0x6007, 0x0003, 0x080c, 0x6d45, 0x0020, 0x080c, 0x8ca5,
+	0x080c, 0x8e82, 0x0005, 0x0469, 0x1158, 0x2001, 0x0008, 0x080c,
+	0x4f6f, 0x6003, 0x0001, 0x6007, 0x0005, 0x080c, 0x6d45, 0x0010,
+	0x080c, 0x8e82, 0x0005, 0x00e9, 0x1158, 0x2001, 0x000a, 0x080c,
+	0x4f6f, 0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x6d45, 0x0010,
+	0x080c, 0x8e82, 0x0005, 0x2009, 0xbc8e, 0x2104, 0xa086, 0x0003,
+	0x1138, 0x2009, 0xbc8f, 0x2104, 0xa084, 0xff00, 0xa086, 0x2a00,
+	0x0005, 0xa085, 0x0001, 0x0005, 0x00c6, 0x0016, 0xac88, 0x0006,
+	0x2164, 0x080c, 0x502a, 0x001e, 0x00ce, 0x0005, 0x00f6, 0x00e6,
+	0x00d6, 0x0036, 0x0016, 0x6018, 0x2068, 0x2071, 0xb635, 0x2e04,
+	0xa085, 0x0003, 0x2072, 0x080c, 0x90b2, 0x0560, 0x2009, 0xb635,
+	0x2104, 0xc0cd, 0x200a, 0x2001, 0xb653, 0x2004, 0xd0a4, 0x0158,
+	0xa006, 0x2020, 0x2009, 0x002a, 0x080c, 0xb1a4, 0x2001, 0xb60c,
+	0x200c, 0xc195, 0x2102, 0x2019, 0x002a, 0x2009, 0x0001, 0x080c,
+	0x2ca4, 0x2071, 0xb600, 0x080c, 0x2aed, 0x00c6, 0x0156, 0x20a9,
+	0x0081, 0x2009, 0x007f, 0x080c, 0x2dcc, 0x8108, 0x1f04, 0x9063,
+	0x015e, 0x00ce, 0x080c, 0x9024, 0x6813, 0x00ff, 0x6817, 0xfffe,
+	0x2071, 0xbc80, 0x2079, 0x0100, 0x2e04, 0xa084, 0x00ff, 0x2069,
+	0xb61c, 0x206a, 0x78e6, 0x0006, 0x8e70, 0x2e04, 0x2069, 0xb61d,
+	0x206a, 0x78ea, 0x7832, 0x7836, 0x2010, 0xa084, 0xff00, 0x001e,
+	0xa105, 0x2009, 0xb628, 0x200a, 0x2200, 0xa084, 0x00ff, 0x2008,
+	0x080c, 0x287c, 0x080c, 0x5b41, 0x0170, 0x2069, 0xbc8e, 0x2071,
+	0xb8b2, 0x6810, 0x2072, 0x6814, 0x7006, 0x6818, 0x700a, 0x681c,
+	0x700e, 0x080c, 0xa08e, 0x0040, 0x2001, 0x0006, 0x080c, 0x4f6f,
+	0x080c, 0x2cf7, 0x080c, 0x86a4, 0x001e, 0x003e, 0x00de, 0x00ee,
+	0x00fe, 0x0005, 0x0026, 0x0036, 0x00e6, 0x0156, 0x2019, 0xb628,
+	0x231c, 0x83ff, 0x01e8, 0x2071, 0xbc80, 0x2e14, 0xa294, 0x00ff,
+	0x7004, 0xa084, 0xff00, 0xa205, 0xa306, 0x1190, 0x2011, 0xbc96,
+	0xad98, 0x000a, 0x20a9, 0x0004, 0x080c, 0x9166, 0x1148, 0x2011,
+	0xbc9a, 0xad98, 0x0006, 0x20a9, 0x0004, 0x080c, 0x9166, 0x1100,
+	0x015e, 0x00ee, 0x003e, 0x002e, 0x0005, 0x00e6, 0x2071, 0xbc8c,
+	0x7004, 0xa086, 0x0014, 0x11a8, 0x7008, 0xa086, 0x0800, 0x1188,
+	0x700c, 0xd0ec, 0x0160, 0xa084, 0x0f00, 0xa086, 0x0100, 0x1138,
+	0x7024, 0xd0a4, 0x1110, 0xd0ac, 0x0110, 0xa006, 0x0010, 0xa085,
+	0x0001, 0x00ee, 0x0005, 0x00e6, 0x00d6, 0x00c6, 0x0076, 0x0056,
+	0x0046, 0x0026, 0x0006, 0x0126, 0x2091, 0x8000, 0x2029, 0xb8ea,
+	0x252c, 0x2021, 0xb8f0, 0x2424, 0x2061, 0xbe00, 0x2071, 0xb600,
+	0x7248, 0x7068, 0xa202, 0x16f0, 0x080c, 0xb1cc, 0x05a0, 0x671c,
+	0xa786, 0x0001, 0x0580, 0xa786, 0x0007, 0x0568, 0x2500, 0xac06,
+	0x0550, 0x2400, 0xac06, 0x0538, 0x00c6, 0x6000, 0xa086, 0x0004,
+	0x1110, 0x080c, 0x1952, 0xa786, 0x0008, 0x1148, 0x080c, 0x9f14,
+	0x1130, 0x00ce, 0x080c, 0x8ca5, 0x080c, 0x9ed9, 0x00a0, 0x6010,
+	0x2068, 0x080c, 0x9d16, 0x0160, 0xa786, 0x0003, 0x11e8, 0x6837,
+	0x0103, 0x6b4a, 0x6847, 0x0000, 0x080c, 0x547a, 0x080c, 0x9ecd,
+	0x080c, 0x9ed9, 0x00ce, 0xace0, 0x0018, 0x705c, 0xac02, 0x1210,
+	0x0804, 0x9110, 0x012e, 0x000e, 0x002e, 0x004e, 0x005e, 0x007e,
+	0x00ce, 0x00de, 0x00ee, 0x0005, 0xa786, 0x0006, 0x1118, 0x080c,
+	0xb155, 0x0c30, 0xa786, 0x000a, 0x09e0, 0x08c8, 0x220c, 0x2304,
+	0xa106, 0x1130, 0x8210, 0x8318, 0x1f04, 0x9166, 0xa006, 0x0005,
+	0x2304, 0xa102, 0x0218, 0x2001, 0x0001, 0x0010, 0x2001, 0x0000,
+	0xa18d, 0x0001, 0x0005, 0x6004, 0xa08a, 0x0080, 0x1a0c, 0x151a,
+	0x080c, 0x9f03, 0x0120, 0x080c, 0x9f14, 0x0168, 0x0028, 0x080c,
+	0x2cf7, 0x080c, 0x9f14, 0x0138, 0x080c, 0x7102, 0x080c, 0x86a4,
+	0x080c, 0x71e5, 0x0005, 0x080c, 0x8ca5, 0x0cb0, 0xa182, 0x0040,
+	0x0002, 0x91ac, 0x91ac, 0x91ac, 0x91ac, 0x91ac, 0x91ac, 0x91ac,
+	0x91ac, 0x91ac, 0x91ac, 0x91ac, 0x91ae, 0x91ae, 0x91ae, 0x91ae,
+	0x91ac, 0x91ac, 0x91ac, 0x91ae, 0x080c, 0x151a, 0x600b, 0xffff,
+	0x6003, 0x0001, 0x6106, 0x080c, 0x6cff, 0x0126, 0x2091, 0x8000,
+	0x080c, 0x71e5, 0x012e, 0x0005, 0xa186, 0x0013, 0x1128, 0x6004,
+	0xa082, 0x0040, 0x0804, 0x9248, 0xa186, 0x0027, 0x11e8, 0x080c,
+	0x7102, 0x080c, 0x2cd1, 0x00d6, 0x6110, 0x2168, 0x080c, 0x9d16,
+	0x0168, 0x6837, 0x0103, 0x684b, 0x0029, 0x6847, 0x0000, 0x694c,
+	0xc1c5, 0x694e, 0x080c, 0x547a, 0x080c, 0x9ecd, 0x00de, 0x080c,
+	0x86a4, 0x080c, 0x71e5, 0x0005, 0xa186, 0x0014, 0x1120, 0x6004,
+	0xa082, 0x0040, 0x0428, 0xa186, 0x0046, 0x0138, 0xa186, 0x0045,
+	0x0120, 0xa186, 0x0047, 0x190c, 0x151a, 0x2001, 0x0109, 0x2004,
+	0xd084, 0x0198, 0x0126, 0x2091, 0x2800, 0x0006, 0x0016, 0x0026,
+	0x080c, 0x6be6, 0x002e, 0x001e, 0x000e, 0x012e, 0xe000, 0x6000,
+	0xa086, 0x0002, 0x1110, 0x0804, 0x9286, 0x080c, 0x86ef, 0x0005,
+	0x0002, 0x9226, 0x9224, 0x9224, 0x9224, 0x9224, 0x9224, 0x9224,
+	0x9224, 0x9224, 0x9224, 0x9224, 0x9241, 0x9241, 0x9241, 0x9241,
+	0x9224, 0x9241, 0x9224, 0x9241, 0x080c, 0x151a, 0x080c, 0x7102,
+	0x00d6, 0x6110, 0x2168, 0x080c, 0x9d16, 0x0168, 0x6837, 0x0103,
+	0x684b, 0x0006, 0x6847, 0x0000, 0x6850, 0xc0ec, 0x6852, 0x080c,
+	0x547a, 0x080c, 0x9ecd, 0x00de, 0x080c, 0x86a4, 0x080c, 0x71e5,
+	0x0005, 0x080c, 0x7102, 0x080c, 0x86a4, 0x080c, 0x71e5, 0x0005,
+	0x0002, 0x925e, 0x925c, 0x925c, 0x925c, 0x925c, 0x925c, 0x925c,
+	0x925c, 0x925c, 0x925c, 0x925c, 0x9270, 0x9270, 0x9270, 0x9270,
+	0x925c, 0x927f, 0x925c, 0x9270, 0x080c, 0x151a, 0x080c, 0x7102,
+	0x2001, 0xb8b8, 0x2004, 0x603e, 0x6003, 0x0002, 0x080c, 0x71e5,
+	0x6010, 0xa088, 0x0013, 0x2104, 0xa085, 0x0400, 0x200a, 0x0005,
+	0x080c, 0x7102, 0x2001, 0xb8b6, 0x2004, 0x6016, 0x2001, 0xb8b8,
+	0x2004, 0x603e, 0x6003, 0x000f, 0x080c, 0x71e5, 0x0005, 0x080c,
+	0x7102, 0x080c, 0x86a4, 0x080c, 0x71e5, 0x0005, 0xa182, 0x0040,
+	0x0002, 0x929c, 0x929c, 0x929c, 0x929c, 0x929c, 0x929e, 0x9386,
+	0x93b5, 0x929c, 0x929c, 0x929c, 0x929c, 0x929c, 0x929c, 0x929c,
+	0x929c, 0x929c, 0x929c, 0x929c, 0x080c, 0x151a, 0x00e6, 0x00d6,
+	0x603f, 0x0000, 0x2071, 0xbc80, 0x7124, 0x610a, 0x2071, 0xbc8c,
+	0x6110, 0x2168, 0x7614, 0xa6b4, 0x0fff, 0x86ff, 0x0904, 0x934c,
+	0xa68c, 0x0c00, 0x0518, 0x00f6, 0x2c78, 0x080c, 0x5377, 0x00fe,
+	0x01c8, 0x684c, 0xd0ac, 0x01b0, 0x6020, 0xd0dc, 0x1198, 0x6850,
+	0xd0bc, 0x1180, 0x7318, 0x6814, 0xa306, 0x1904, 0x935f, 0x731c,
+	0x6810, 0xa31e, 0x0138, 0xd6d4, 0x0904, 0x935f, 0x6b14, 0xa305,
+	0x1904, 0x935f, 0x7318, 0x6b62, 0x731c, 0x6b5e, 0xa68c, 0x00ff,
+	0xa186, 0x0002, 0x0518, 0xa186, 0x0028, 0x1128, 0x080c, 0x9ef2,
+	0x684b, 0x001c, 0x00e8, 0xd6dc, 0x01a0, 0x684b, 0x0015, 0x684c,
+	0xd0ac, 0x0170, 0x6914, 0x6a10, 0x2100, 0xa205, 0x0148, 0x7018,
+	0xa106, 0x1118, 0x701c, 0xa206, 0x0118, 0x6962, 0x6a5e, 0xc6dc,
+	0x0038, 0xd6d4, 0x0118, 0x684b, 0x0007, 0x0010, 0x684b, 0x0000,
+	0x6837, 0x0103, 0x6e46, 0xa01e, 0xd6c4, 0x01f0, 0xa686, 0x0100,
+	0x1140, 0x2001, 0xbc99, 0x2004, 0xa005, 0x1118, 0xc6c4, 0x0804,
+	0x92ad, 0x7328, 0x732c, 0x6b56, 0x83ff, 0x0170, 0xa38a, 0x0009,
+	0x0210, 0x2019, 0x0008, 0x0036, 0x2308, 0x2019, 0xbc98, 0xad90,
+	0x0019, 0x080c, 0x99c9, 0x003e, 0xd6cc, 0x0904, 0x9375, 0x7124,
+	0x695a, 0x81ff, 0x0904, 0x9375, 0xa192, 0x0021, 0x1260, 0x2071,
+	0xbc98, 0x831c, 0x2300, 0xae18, 0xad90, 0x001d, 0x080c, 0x99c9,
+	0x080c, 0xa1f3, 0x04d0, 0x6838, 0xd0fc, 0x0120, 0x2009, 0x0020,
+	0x695a, 0x0c68, 0x00f6, 0x2d78, 0x080c, 0x996e, 0x00fe, 0x080c,
+	0xa1f3, 0x080c, 0x99b9, 0x0458, 0x00f6, 0x2c78, 0x080c, 0x5377,
+	0x00fe, 0x0190, 0x684c, 0xd0ac, 0x0178, 0x6020, 0xd0dc, 0x1160,
+	0x6850, 0xd0bc, 0x1148, 0x6810, 0x6914, 0xa105, 0x0128, 0x080c,
+	0x9ff1, 0x00de, 0x00ee, 0x0408, 0x684b, 0x0000, 0x6837, 0x0103,
+	0x6e46, 0x080c, 0x9523, 0x1148, 0x684c, 0xd0ac, 0x0130, 0x6810,
+	0x6914, 0xa115, 0x0110, 0x080c, 0x953f, 0x080c, 0x547a, 0x6218,
+	0x2268, 0x6a3c, 0x82ff, 0x0110, 0x8211, 0x6a3e, 0x080c, 0x9fbf,
+	0x00de, 0x00ee, 0x1110, 0x080c, 0x86a4, 0x0005, 0x00f6, 0x6003,
+	0x0003, 0x2079, 0xbc8c, 0x7c04, 0x7b00, 0x7e0c, 0x7d08, 0x6010,
+	0x2078, 0x784c, 0xd0ac, 0x0138, 0x6003, 0x0002, 0x00fe, 0x0005,
+	0x2130, 0x2228, 0x0058, 0x2400, 0x797c, 0xa10a, 0x2300, 0x7a80,
+	0xa213, 0x2600, 0xa102, 0x2500, 0xa203, 0x0e90, 0x7c12, 0x7b16,
+	0x7e0a, 0x7d0e, 0x00fe, 0x603f, 0x0000, 0x2c10, 0x080c, 0x1fc5,
+	0x080c, 0x6d62, 0x080c, 0x72a2, 0x0005, 0x2001, 0xb8b8, 0x2004,
+	0x603e, 0x6003, 0x0004, 0x6110, 0x20e1, 0x0005, 0x3d18, 0x3e20,
+	0x2c10, 0x080c, 0x1863, 0x0005, 0xa182, 0x0040, 0x0002, 0x93da,
+	0x93da, 0x93da, 0x93da, 0x93da, 0x93dc, 0x946f, 0x93da, 0x93da,
+	0x9485, 0x94eb, 0x93da, 0x93da, 0x93da, 0x93da, 0x9509, 0x93da,
+	0x93da, 0x93da, 0x080c, 0x151a, 0x0076, 0x00f6, 0x00e6, 0x00d6,
+	0x2071, 0xbc8c, 0x6110, 0x2178, 0x7614, 0xa6b4, 0x0fff, 0x7e46,
+	0x7f4c, 0xc7e5, 0x7f4e, 0x6218, 0x2268, 0x6a3c, 0x82ff, 0x0110,
+	0x8211, 0x6a3e, 0x86ff, 0x0904, 0x946a, 0xa694, 0xff00, 0xa284,
+	0x0c00, 0x0120, 0x7018, 0x7862, 0x701c, 0x785e, 0xa284, 0x0300,
+	0x0904, 0x946a, 0x080c, 0x15fd, 0x090c, 0x151a, 0x2d00, 0x784a,
+	0x7f4c, 0xc7cd, 0x7f4e, 0x6837, 0x0103, 0x7838, 0x683a, 0x783c,
+	0x683e, 0x7840, 0x6842, 0x6e46, 0xa68c, 0x0c00, 0x0120, 0x7318,
+	0x6b62, 0x731c, 0x6b5e, 0xa68c, 0x00ff, 0xa186, 0x0002, 0x0180,
+	0xa186, 0x0028, 0x1118, 0x684b, 0x001c, 0x0060, 0xd6dc, 0x0118,
+	0x684b, 0x0015, 0x0038, 0xd6d4, 0x0118, 0x684b, 0x0007, 0x0010,
+	0x684b, 0x0000, 0x6f4e, 0x7850, 0x6852, 0x7854, 0x6856, 0xa01e,
+	0xd6c4, 0x0198, 0x7328, 0x732c, 0x6b56, 0x83ff, 0x0170, 0xa38a,
+	0x0009, 0x0210, 0x2019, 0x0008, 0x0036, 0x2308, 0x2019, 0xbc98,
+	0xad90, 0x0019, 0x080c, 0x99c9, 0x003e, 0xd6cc, 0x01d8, 0x7124,
+	0x695a, 0x81ff, 0x01b8, 0xa192, 0x0021, 0x1250, 0x2071, 0xbc98,
+	0x831c, 0x2300, 0xae18, 0xad90, 0x001d, 0x080c, 0x99c9, 0x0050,
+	0x7838, 0xd0fc, 0x0120, 0x2009, 0x0020, 0x695a, 0x0c78, 0x2d78,
+	0x080c, 0x996e, 0x00de, 0x00ee, 0x00fe, 0x007e, 0x0005, 0x00f6,
+	0x6003, 0x0003, 0x2079, 0xbc8c, 0x7c04, 0x7b00, 0x7e0c, 0x7d08,
+	0x6010, 0x2078, 0x7c12, 0x7b16, 0x7e0a, 0x7d0e, 0x00fe, 0x2c10,
+	0x080c, 0x1fc5, 0x080c, 0x7dd9, 0x0005, 0x00d6, 0x00f6, 0x2c78,
+	0x080c, 0x5377, 0x00fe, 0x0120, 0x2001, 0xb8b8, 0x2004, 0x603e,
+	0x6003, 0x0002, 0x080c, 0x7198, 0x080c, 0x72a2, 0x6110, 0x2168,
+	0x694c, 0xd1e4, 0x0904, 0x94e9, 0xd1cc, 0x0540, 0x6948, 0x6838,
+	0xd0fc, 0x01e8, 0x0016, 0x684c, 0x0006, 0x6850, 0x0006, 0xad90,
+	0x000d, 0xa198, 0x000d, 0x2009, 0x0020, 0x0156, 0x21a8, 0x2304,
+	0x2012, 0x8318, 0x8210, 0x1f04, 0x94af, 0x015e, 0x000e, 0x6852,
+	0x000e, 0x684e, 0x001e, 0x2168, 0x080c, 0x1624, 0x0428, 0x0016,
+	0x080c, 0x1624, 0x00de, 0x080c, 0x99b9, 0x00f0, 0x6837, 0x0103,
+	0x6944, 0xa184, 0x00ff, 0xa0b6, 0x0002, 0x0180, 0xa086, 0x0028,
+	0x1118, 0x684b, 0x001c, 0x0070, 0xd1dc, 0x0118, 0x684b, 0x0015,
+	0x0048, 0xd1d4, 0x0118, 0x684b, 0x0007, 0x0020, 0x684b, 0x0000,
+	0x080c, 0x9523, 0x080c, 0x547a, 0x080c, 0x9fbf, 0x1110, 0x080c,
+	0x86a4, 0x00de, 0x0005, 0x2019, 0x0001, 0x080c, 0x806b, 0x6003,
+	0x0002, 0x00d6, 0x6010, 0x2068, 0x080c, 0x9d16, 0x0140, 0x6808,
+	0x612c, 0xa10a, 0x612e, 0x680c, 0x6128, 0xa10b, 0x612a, 0x00de,
+	0x2001, 0xb8b8, 0x2004, 0x603e, 0x080c, 0x7198, 0x080c, 0x72a2,
+	0x0005, 0x080c, 0x7198, 0x080c, 0x2cd1, 0x00d6, 0x6110, 0x2168,
+	0x080c, 0x9d16, 0x0150, 0x6837, 0x0103, 0x684b, 0x0029, 0x6847,
+	0x0000, 0x080c, 0x547a, 0x080c, 0x9ecd, 0x00de, 0x080c, 0x86a4,
+	0x080c, 0x72a2, 0x0005, 0x684c, 0xd0b4, 0x01c0, 0x602c, 0x697c,
+	0xa112, 0x6028, 0x6980, 0xa10b, 0x2100, 0xa205, 0x0168, 0x684b,
+	0x0015, 0xd1fc, 0x0138, 0x684b, 0x0007, 0x8212, 0x8210, 0x810a,
+	0xa189, 0x0000, 0x6962, 0x6a5e, 0xa085, 0x0001, 0x0005, 0x684b,
+	0x0015, 0xd1fc, 0x0138, 0x684b, 0x0007, 0x8002, 0x8000, 0x810a,
+	0xa189, 0x0000, 0x6962, 0x685e, 0x0005, 0xa182, 0x0040, 0x0002,
+	0x9563, 0x9563, 0x9563, 0x9563, 0x9563, 0x9565, 0x9563, 0x9620,
+	0x962c, 0x9563, 0x9563, 0x9563, 0x9563, 0x9563, 0x9563, 0x9563,
+	0x9563, 0x9563, 0x9563, 0x080c, 0x151a, 0x0076, 0x00f6, 0x00e6,
+	0x00d6, 0x2071, 0xbc8c, 0x6110, 0x2178, 0x7614, 0xa6b4, 0x0fff,
+	0x00f6, 0x2c78, 0x080c, 0x5377, 0x00fe, 0x0150, 0xa684, 0x00ff,
+	0x1138, 0x6020, 0xd0f4, 0x0120, 0x080c, 0x9ff1, 0x0804, 0x961b,
 	0x7e46, 0x7f4c, 0xc7e5, 0x7f4e, 0x6218, 0x2268, 0x6a3c, 0x82ff,
-	0x0110, 0x8211, 0x6a3e, 0x86ff, 0x0904, 0x93db, 0xa694, 0xff00,
+	0x0110, 0x8211, 0x6a3e, 0x86ff, 0x0904, 0x9611, 0xa694, 0xff00,
 	0xa284, 0x0c00, 0x0120, 0x7018, 0x7862, 0x701c, 0x785e, 0xa284,
-	0x0300, 0x0904, 0x93db, 0x080c, 0x15f8, 0x090c, 0x1515, 0x2d00,
-	0x784a, 0x7f4c, 0xc7cd, 0x7f4e, 0x6837, 0x0103, 0x7838, 0x683a,
-	0x783c, 0x683e, 0x7840, 0x6842, 0x6e46, 0xa68c, 0x0c00, 0x0120,
-	0x7318, 0x6b62, 0x731c, 0x6b5e, 0xa68c, 0x00ff, 0xa186, 0x0002,
-	0x0180, 0xa186, 0x0028, 0x1118, 0x684b, 0x001c, 0x0060, 0xd6dc,
-	0x0118, 0x684b, 0x0015, 0x0038, 0xd6d4, 0x0118, 0x684b, 0x0007,
-	0x0010, 0x684b, 0x0000, 0x6f4e, 0x7850, 0x6852, 0x7854, 0x6856,
-	0xa01e, 0xd6c4, 0x0198, 0x7328, 0x732c, 0x6b56, 0x83ff, 0x0170,
-	0xa38a, 0x0009, 0x0210, 0x2019, 0x0008, 0x0036, 0x2308, 0x2019,
-	0xbb98, 0xad90, 0x0019, 0x080c, 0x990d, 0x003e, 0xd6cc, 0x01d8,
-	0x7124, 0x695a, 0x81ff, 0x01b8, 0xa192, 0x0021, 0x1250, 0x2071,
-	0xbb98, 0x831c, 0x2300, 0xae18, 0xad90, 0x001d, 0x080c, 0x990d,
-	0x0050, 0x7838, 0xd0fc, 0x0120, 0x2009, 0x0020, 0x695a, 0x0c78,
-	0x2d78, 0x080c, 0x98b2, 0x00de, 0x00ee, 0x00fe, 0x007e, 0x0005,
-	0x00f6, 0x6003, 0x0003, 0x2079, 0xbb8c, 0x7c04, 0x7b00, 0x7e0c,
-	0x7d08, 0x6010, 0x2078, 0x7c12, 0x7b16, 0x7e0a, 0x7d0e, 0x00fe,
-	0x2c10, 0x080c, 0x1fa9, 0x080c, 0x7d60, 0x0005, 0x00d6, 0x00f6,
-	0x2c78, 0x080c, 0x5305, 0x00fe, 0x0120, 0x2001, 0xb7b8, 0x2004,
-	0x603e, 0x6003, 0x0002, 0x080c, 0x7126, 0x080c, 0x7230, 0x6110,
-	0x2168, 0x694c, 0xd1e4, 0x0904, 0x9458, 0xd1cc, 0x0540, 0x6948,
-	0x6838, 0xd0fc, 0x01e8, 0x0016, 0x684c, 0x0006, 0x6850, 0x0006,
-	0xad90, 0x000d, 0xa198, 0x000d, 0x2009, 0x0020, 0x0156, 0x21a8,
-	0x2304, 0x2012, 0x8318, 0x8210, 0x1f04, 0x9420, 0x015e, 0x000e,
-	0x6852, 0x000e, 0x684e, 0x001e, 0x2168, 0x080c, 0x161f, 0x0418,
-	0x0016, 0x080c, 0x161f, 0x00de, 0x080c, 0x98fd, 0x00e0, 0x6837,
-	0x0103, 0x6944, 0xa184, 0x00ff, 0xa0b6, 0x0002, 0x0180, 0xa086,
-	0x0028, 0x1118, 0x684b, 0x001c, 0x0060, 0xd1dc, 0x0118, 0x684b,
-	0x0015, 0x0038, 0xd1d4, 0x0118, 0x684b, 0x0007, 0x0010, 0x684b,
-	0x0000, 0x080c, 0x5408, 0x080c, 0x9f03, 0x1110, 0x080c, 0x861d,
-	0x00de, 0x0005, 0x2019, 0x0001, 0x080c, 0x7fe4, 0x6003, 0x0002,
-	0x2001, 0xb7b8, 0x2004, 0x603e, 0x080c, 0x7126, 0x080c, 0x7230,
-	0x0005, 0x080c, 0x7126, 0x080c, 0x2c9c, 0x00d6, 0x6110, 0x2168,
-	0x080c, 0x9c5a, 0x0150, 0x6837, 0x0103, 0x684b, 0x0029, 0x6847,
-	0x0000, 0x080c, 0x5408, 0x080c, 0x9e11, 0x00de, 0x080c, 0x861d,
-	0x080c, 0x7230, 0x0005, 0x684b, 0x0015, 0xd1fc, 0x0138, 0x684b,
-	0x0007, 0x8002, 0x8000, 0x810a, 0xa189, 0x0000, 0x6962, 0x685e,
-	0x0005, 0xa182, 0x0040, 0x0002, 0x94a7, 0x94a7, 0x94a7, 0x94a7,
-	0x94a7, 0x94a9, 0x94a7, 0x9564, 0x9570, 0x94a7, 0x94a7, 0x94a7,
-	0x94a7, 0x94a7, 0x94a7, 0x94a7, 0x94a7, 0x94a7, 0x94a7, 0x080c,
-	0x1515, 0x0076, 0x00f6, 0x00e6, 0x00d6, 0x2071, 0xbb8c, 0x6110,
-	0x2178, 0x7614, 0xa6b4, 0x0fff, 0x00f6, 0x2c78, 0x080c, 0x5305,
-	0x00fe, 0x0150, 0xa684, 0x00ff, 0x1138, 0x6020, 0xd0f4, 0x0120,
-	0x080c, 0x9f35, 0x0804, 0x955f, 0x7e46, 0x7f4c, 0xc7e5, 0x7f4e,
-	0x6218, 0x2268, 0x6a3c, 0x82ff, 0x0110, 0x8211, 0x6a3e, 0x86ff,
-	0x0904, 0x9555, 0xa694, 0xff00, 0xa284, 0x0c00, 0x0120, 0x7018,
-	0x7862, 0x701c, 0x785e, 0xa284, 0x0300, 0x0904, 0x9553, 0xa686,
-	0x0100, 0x1140, 0x2001, 0xbb99, 0x2004, 0xa005, 0x1118, 0xc6c4,
-	0x7e46, 0x0c28, 0x080c, 0x15f8, 0x090c, 0x1515, 0x2d00, 0x784a,
-	0x7f4c, 0xa7bd, 0x0200, 0x7f4e, 0x6837, 0x0103, 0x7838, 0x683a,
-	0x783c, 0x683e, 0x7840, 0x6842, 0x6e46, 0xa68c, 0x0c00, 0x0120,
-	0x7318, 0x6b62, 0x731c, 0x6b5e, 0xa68c, 0x00ff, 0xa186, 0x0002,
-	0x0180, 0xa186, 0x0028, 0x1118, 0x684b, 0x001c, 0x0060, 0xd6dc,
-	0x0118, 0x684b, 0x0015, 0x0038, 0xd6d4, 0x0118, 0x684b, 0x0007,
-	0x0010, 0x684b, 0x0000, 0x6f4e, 0x7850, 0x6852, 0x7854, 0x6856,
-	0xa01e, 0xd6c4, 0x0198, 0x7328, 0x732c, 0x6b56, 0x83ff, 0x0170,
-	0xa38a, 0x0009, 0x0210, 0x2019, 0x0008, 0x0036, 0x2308, 0x2019,
-	0xbb98, 0xad90, 0x0019, 0x080c, 0x990d, 0x003e, 0xd6cc, 0x01d8,
-	0x7124, 0x695a, 0x81ff, 0x01b8, 0xa192, 0x0021, 0x1250, 0x2071,
-	0xbb98, 0x831c, 0x2300, 0xae18, 0xad90, 0x001d, 0x080c, 0x990d,
-	0x0050, 0x7838, 0xd0fc, 0x0120, 0x2009, 0x0020, 0x695a, 0x0c78,
-	0x2d78, 0x080c, 0x98b2, 0xd6dc, 0x1110, 0xa006, 0x0030, 0x2001,
-	0x0001, 0x2071, 0xbb8c, 0x7218, 0x731c, 0x080c, 0x18b1, 0x00de,
-	0x00ee, 0x00fe, 0x007e, 0x0005, 0x2001, 0xb7b8, 0x2004, 0x603e,
-	0x20e1, 0x0005, 0x3d18, 0x3e20, 0x2c10, 0x080c, 0x185e, 0x0005,
-	0x2001, 0xb7b8, 0x2004, 0x603e, 0x00d6, 0x6003, 0x0002, 0x6110,
-	0x2168, 0x694c, 0xd1e4, 0x0904, 0x967b, 0x603f, 0x0000, 0x00f6,
-	0x2c78, 0x080c, 0x5305, 0x00fe, 0x0560, 0x6814, 0x6910, 0xa115,
-	0x0540, 0x6a60, 0xa206, 0x1118, 0x685c, 0xa106, 0x0510, 0x684c,
-	0xc0e4, 0x684e, 0x6847, 0x0000, 0x6863, 0x0000, 0x685f, 0x0000,
-	0x6020, 0xd0f4, 0x1158, 0x697c, 0x6810, 0xa102, 0x603a, 0x6980,
-	0x6814, 0xa103, 0x6036, 0x6020, 0xc0f5, 0x6022, 0x00d6, 0x6018,
-	0x2068, 0x683c, 0x8000, 0x683e, 0x00de, 0x080c, 0x9f35, 0x0804,
-	0x967b, 0x694c, 0xd1cc, 0x0904, 0x964b, 0x6948, 0x6838, 0xd0fc,
-	0x0904, 0x960e, 0x0016, 0x684c, 0x0006, 0x6850, 0x0006, 0x00f6,
-	0x2178, 0x7944, 0xa184, 0x00ff, 0xa0b6, 0x0002, 0x01e0, 0xa086,
-	0x0028, 0x1128, 0x684b, 0x001c, 0x784b, 0x001c, 0x00e8, 0xd1dc,
-	0x0158, 0x684b, 0x0015, 0x784b, 0x0015, 0x080c, 0xa0bf, 0x0118,
-	0x7944, 0xc1dc, 0x7946, 0x0080, 0xd1d4, 0x0128, 0x684b, 0x0007,
-	0x784b, 0x0007, 0x0048, 0x684c, 0xd0ac, 0x0130, 0x6810, 0x6914,
-	0xa115, 0x0110, 0x080c, 0x9483, 0x6848, 0x784a, 0x6860, 0x7862,
-	0x685c, 0x785e, 0xad90, 0x000d, 0xaf98, 0x000d, 0x2009, 0x0020,
-	0x0156, 0x21a8, 0x2304, 0x2012, 0x8318, 0x8210, 0x1f04, 0x95fa,
-	0x015e, 0x00fe, 0x000e, 0x6852, 0x000e, 0x684e, 0x080c, 0xa137,
-	0x001e, 0x2168, 0x080c, 0x161f, 0x0804, 0x9676, 0x0016, 0x00f6,
-	0x2178, 0x7944, 0xa184, 0x00ff, 0xa0b6, 0x0002, 0x01e0, 0xa086,
-	0x0028, 0x1128, 0x684b, 0x001c, 0x784b, 0x001c, 0x00e8, 0xd1dc,
-	0x0158, 0x684b, 0x0015, 0x784b, 0x0015, 0x080c, 0xa0bf, 0x0118,
-	0x7944, 0xc1dc, 0x7946, 0x0080, 0xd1d4, 0x0128, 0x684b, 0x0007,
-	0x784b, 0x0007, 0x0048, 0x684c, 0xd0ac, 0x0130, 0x6810, 0x6914,
-	0xa115, 0x0110, 0x080c, 0x9483, 0x6860, 0x7862, 0x685c, 0x785e,
-	0x684c, 0x784e, 0x00fe, 0x080c, 0x161f, 0x00de, 0x080c, 0xa137,
-	0x080c, 0x98fd, 0x0458, 0x6837, 0x0103, 0x6944, 0xa184, 0x00ff,
-	0xa0b6, 0x0002, 0x01b0, 0xa086, 0x0028, 0x1118, 0x684b, 0x001c,
-	0x00d8, 0xd1dc, 0x0148, 0x684b, 0x0015, 0x080c, 0xa0bf, 0x0118,
-	0x6944, 0xc1dc, 0x6946, 0x0080, 0xd1d4, 0x0118, 0x684b, 0x0007,
-	0x0058, 0x684b, 0x0000, 0x684c, 0xd0ac, 0x0130, 0x6810, 0x6914,
-	0xa115, 0x0110, 0x080c, 0x9483, 0x080c, 0x5408, 0x080c, 0x9f03,
-	0x1110, 0x080c, 0x861d, 0x00de, 0x0005, 0x080c, 0x7090, 0x0010,
-	0x080c, 0x7126, 0x080c, 0x9c5a, 0x01c0, 0x00d6, 0x6110, 0x2168,
-	0x6837, 0x0103, 0x2009, 0xb50c, 0x210c, 0xd18c, 0x11c0, 0xd184,
-	0x1198, 0x6108, 0x694a, 0xa18e, 0x0029, 0x1110, 0x080c, 0xb380,
-	0x6847, 0x0000, 0x080c, 0x5408, 0x00de, 0x080c, 0x861d, 0x080c,
-	0x7173, 0x080c, 0x7230, 0x0005, 0x684b, 0x0004, 0x0c88, 0x684b,
-	0x0004, 0x0c70, 0xa182, 0x0040, 0x0002, 0x96c0, 0x96c0, 0x96c0,
-	0x96c0, 0x96c0, 0x96c2, 0x96c0, 0x96c5, 0x96c0, 0x96c0, 0x96c0,
-	0x96c0, 0x96c0, 0x96c0, 0x96c0, 0x96c0, 0x96c0, 0x96c0, 0x96c0,
-	0x080c, 0x1515, 0x080c, 0x861d, 0x0005, 0x0006, 0x0026, 0xa016,
-	0x080c, 0x185e, 0x002e, 0x000e, 0x0005, 0xa182, 0x0085, 0x0002,
-	0x96d9, 0x96d7, 0x96d7, 0x96e5, 0x96d7, 0x96d7, 0x96d7, 0x080c,
-	0x1515, 0x6003, 0x0001, 0x6106, 0x080c, 0x6c8d, 0x0126, 0x2091,
-	0x8000, 0x080c, 0x7173, 0x012e, 0x0005, 0x0026, 0x0056, 0x00d6,
-	0x00e6, 0x2071, 0xbb80, 0x7224, 0x6212, 0x7220, 0x080c, 0x9c4a,
-	0x01a0, 0x2268, 0x6800, 0xa086, 0x0000, 0x0178, 0x6018, 0x6d18,
-	0xa52e, 0x1158, 0x00c6, 0x2d60, 0x080c, 0x991d, 0x00ce, 0x0128,
-	0x6803, 0x0002, 0x6007, 0x0086, 0x0010, 0x6007, 0x0087, 0x6003,
-	0x0001, 0x080c, 0x6c8d, 0x080c, 0x7173, 0x00f6, 0x2278, 0x080c,
-	0x5305, 0x00fe, 0x0150, 0x6820, 0xd0ec, 0x0138, 0x00c6, 0x2260,
-	0x603f, 0x0000, 0x080c, 0x9f35, 0x00ce, 0x00ee, 0x00de, 0x005e,
-	0x002e, 0x0005, 0xa186, 0x0013, 0x1160, 0x6004, 0xa08a, 0x0085,
-	0x0a0c, 0x1515, 0xa08a, 0x008c, 0x1a0c, 0x1515, 0xa082, 0x0085,
-	0x0072, 0xa186, 0x0027, 0x0120, 0xa186, 0x0014, 0x190c, 0x1515,
-	0x080c, 0x7090, 0x080c, 0x9e1d, 0x080c, 0x7173, 0x0005, 0x9746,
-	0x9748, 0x9748, 0x9746, 0x9746, 0x9746, 0x9746, 0x080c, 0x1515,
-	0x080c, 0x7090, 0x080c, 0x9e1d, 0x080c, 0x7173, 0x0005, 0xa186,
-	0x0013, 0x1128, 0x6004, 0xa082, 0x0085, 0x2008, 0x04a8, 0xa186,
-	0x0027, 0x11e8, 0x080c, 0x7090, 0x080c, 0x2c9c, 0x00d6, 0x6010,
-	0x2068, 0x080c, 0x9c5a, 0x0150, 0x6837, 0x0103, 0x6847, 0x0000,
-	0x684b, 0x0029, 0x080c, 0x5408, 0x080c, 0x9e11, 0x00de, 0x080c,
-	0x861d, 0x080c, 0x7173, 0x0005, 0x080c, 0x8663, 0x0ce0, 0xa186,
-	0x0014, 0x1dd0, 0x080c, 0x7090, 0x00d6, 0x6010, 0x2068, 0x080c,
-	0x9c5a, 0x0d60, 0x6837, 0x0103, 0x6847, 0x0000, 0x684b, 0x0006,
-	0x6850, 0xc0ec, 0x6852, 0x08f0, 0x0002, 0x9796, 0x9794, 0x9794,
-	0x9794, 0x9794, 0x9794, 0x97ae, 0x080c, 0x1515, 0x080c, 0x7090,
-	0x6030, 0xa08c, 0xff00, 0x810f, 0xa186, 0x0039, 0x0118, 0xa186,
-	0x0035, 0x1118, 0x2001, 0xb7b6, 0x0010, 0x2001, 0xb7b7, 0x2004,
-	0x6016, 0x6003, 0x000c, 0x080c, 0x7173, 0x0005, 0x080c, 0x7090,
+	0x0300, 0x0904, 0x960f, 0xa686, 0x0100, 0x1140, 0x2001, 0xbc99,
+	0x2004, 0xa005, 0x1118, 0xc6c4, 0x7e46, 0x0c28, 0x080c, 0x15fd,
+	0x090c, 0x151a, 0x2d00, 0x784a, 0x7f4c, 0xa7bd, 0x0200, 0x7f4e,
+	0x6837, 0x0103, 0x7838, 0x683a, 0x783c, 0x683e, 0x7840, 0x6842,
+	0x6e46, 0xa68c, 0x0c00, 0x0120, 0x7318, 0x6b62, 0x731c, 0x6b5e,
+	0xa68c, 0x00ff, 0xa186, 0x0002, 0x0180, 0xa186, 0x0028, 0x1118,
+	0x684b, 0x001c, 0x0060, 0xd6dc, 0x0118, 0x684b, 0x0015, 0x0038,
+	0xd6d4, 0x0118, 0x684b, 0x0007, 0x0010, 0x684b, 0x0000, 0x6f4e,
+	0x7850, 0x6852, 0x7854, 0x6856, 0xa01e, 0xd6c4, 0x0198, 0x7328,
+	0x732c, 0x6b56, 0x83ff, 0x0170, 0xa38a, 0x0009, 0x0210, 0x2019,
+	0x0008, 0x0036, 0x2308, 0x2019, 0xbc98, 0xad90, 0x0019, 0x080c,
+	0x99c9, 0x003e, 0xd6cc, 0x01d8, 0x7124, 0x695a, 0x81ff, 0x01b8,
+	0xa192, 0x0021, 0x1250, 0x2071, 0xbc98, 0x831c, 0x2300, 0xae18,
+	0xad90, 0x001d, 0x080c, 0x99c9, 0x0050, 0x7838, 0xd0fc, 0x0120,
+	0x2009, 0x0020, 0x695a, 0x0c78, 0x2d78, 0x080c, 0x996e, 0xd6dc,
+	0x1110, 0xa006, 0x0030, 0x2001, 0x0001, 0x2071, 0xbc8c, 0x7218,
+	0x731c, 0x080c, 0x18b6, 0x00de, 0x00ee, 0x00fe, 0x007e, 0x0005,
+	0x2001, 0xb8b8, 0x2004, 0x603e, 0x20e1, 0x0005, 0x3d18, 0x3e20,
+	0x2c10, 0x080c, 0x1863, 0x0005, 0x2001, 0xb8b8, 0x2004, 0x603e,
+	0x00d6, 0x6003, 0x0002, 0x6110, 0x2168, 0x694c, 0xd1e4, 0x0904,
+	0x9737, 0x603f, 0x0000, 0x00f6, 0x2c78, 0x080c, 0x5377, 0x00fe,
+	0x0560, 0x6814, 0x6910, 0xa115, 0x0540, 0x6a60, 0xa206, 0x1118,
+	0x685c, 0xa106, 0x0510, 0x684c, 0xc0e4, 0x684e, 0x6847, 0x0000,
+	0x6863, 0x0000, 0x685f, 0x0000, 0x6020, 0xd0f4, 0x1158, 0x697c,
+	0x6810, 0xa102, 0x603a, 0x6980, 0x6814, 0xa103, 0x6036, 0x6020,
+	0xc0f5, 0x6022, 0x00d6, 0x6018, 0x2068, 0x683c, 0x8000, 0x683e,
+	0x00de, 0x080c, 0x9ff1, 0x0804, 0x9737, 0x694c, 0xd1cc, 0x0904,
+	0x9707, 0x6948, 0x6838, 0xd0fc, 0x0904, 0x96ca, 0x0016, 0x684c,
+	0x0006, 0x6850, 0x0006, 0x00f6, 0x2178, 0x7944, 0xa184, 0x00ff,
+	0xa0b6, 0x0002, 0x01e0, 0xa086, 0x0028, 0x1128, 0x684b, 0x001c,
+	0x784b, 0x001c, 0x00e8, 0xd1dc, 0x0158, 0x684b, 0x0015, 0x784b,
+	0x0015, 0x080c, 0xa17b, 0x0118, 0x7944, 0xc1dc, 0x7946, 0x0080,
+	0xd1d4, 0x0128, 0x684b, 0x0007, 0x784b, 0x0007, 0x0048, 0x684c,
+	0xd0ac, 0x0130, 0x6810, 0x6914, 0xa115, 0x0110, 0x080c, 0x953f,
+	0x6848, 0x784a, 0x6860, 0x7862, 0x685c, 0x785e, 0xad90, 0x000d,
+	0xaf98, 0x000d, 0x2009, 0x0020, 0x0156, 0x21a8, 0x2304, 0x2012,
+	0x8318, 0x8210, 0x1f04, 0x96b6, 0x015e, 0x00fe, 0x000e, 0x6852,
+	0x000e, 0x684e, 0x080c, 0xa1f3, 0x001e, 0x2168, 0x080c, 0x1624,
+	0x0804, 0x9732, 0x0016, 0x00f6, 0x2178, 0x7944, 0xa184, 0x00ff,
+	0xa0b6, 0x0002, 0x01e0, 0xa086, 0x0028, 0x1128, 0x684b, 0x001c,
+	0x784b, 0x001c, 0x00e8, 0xd1dc, 0x0158, 0x684b, 0x0015, 0x784b,
+	0x0015, 0x080c, 0xa17b, 0x0118, 0x7944, 0xc1dc, 0x7946, 0x0080,
+	0xd1d4, 0x0128, 0x684b, 0x0007, 0x784b, 0x0007, 0x0048, 0x684c,
+	0xd0ac, 0x0130, 0x6810, 0x6914, 0xa115, 0x0110, 0x080c, 0x953f,
+	0x6860, 0x7862, 0x685c, 0x785e, 0x684c, 0x784e, 0x00fe, 0x080c,
+	0x1624, 0x00de, 0x080c, 0xa1f3, 0x080c, 0x99b9, 0x0458, 0x6837,
+	0x0103, 0x6944, 0xa184, 0x00ff, 0xa0b6, 0x0002, 0x01b0, 0xa086,
+	0x0028, 0x1118, 0x684b, 0x001c, 0x00d8, 0xd1dc, 0x0148, 0x684b,
+	0x0015, 0x080c, 0xa17b, 0x0118, 0x6944, 0xc1dc, 0x6946, 0x0080,
+	0xd1d4, 0x0118, 0x684b, 0x0007, 0x0058, 0x684b, 0x0000, 0x684c,
+	0xd0ac, 0x0130, 0x6810, 0x6914, 0xa115, 0x0110, 0x080c, 0x953f,
+	0x080c, 0x547a, 0x080c, 0x9fbf, 0x1110, 0x080c, 0x86a4, 0x00de,
+	0x0005, 0x080c, 0x7102, 0x0010, 0x080c, 0x7198, 0x080c, 0x9d16,
+	0x01c0, 0x00d6, 0x6110, 0x2168, 0x6837, 0x0103, 0x2009, 0xb60c,
+	0x210c, 0xd18c, 0x11c0, 0xd184, 0x1198, 0x6108, 0x694a, 0xa18e,
+	0x0029, 0x1110, 0x080c, 0xb43c, 0x6847, 0x0000, 0x080c, 0x547a,
+	0x00de, 0x080c, 0x86a4, 0x080c, 0x71e5, 0x080c, 0x72a2, 0x0005,
+	0x684b, 0x0004, 0x0c88, 0x684b, 0x0004, 0x0c70, 0xa182, 0x0040,
+	0x0002, 0x977c, 0x977c, 0x977c, 0x977c, 0x977c, 0x977e, 0x977c,
+	0x9781, 0x977c, 0x977c, 0x977c, 0x977c, 0x977c, 0x977c, 0x977c,
+	0x977c, 0x977c, 0x977c, 0x977c, 0x080c, 0x151a, 0x080c, 0x86a4,
+	0x0005, 0x0006, 0x0026, 0xa016, 0x080c, 0x1863, 0x002e, 0x000e,
+	0x0005, 0xa182, 0x0085, 0x0002, 0x9795, 0x9793, 0x9793, 0x97a1,
+	0x9793, 0x9793, 0x9793, 0x080c, 0x151a, 0x6003, 0x0001, 0x6106,
+	0x080c, 0x6cff, 0x0126, 0x2091, 0x8000, 0x080c, 0x71e5, 0x012e,
+	0x0005, 0x0026, 0x0056, 0x00d6, 0x00e6, 0x2071, 0xbc80, 0x7224,
+	0x6212, 0x7220, 0x080c, 0x9d06, 0x01a0, 0x2268, 0x6800, 0xa086,
+	0x0000, 0x0178, 0x6018, 0x6d18, 0xa52e, 0x1158, 0x00c6, 0x2d60,
+	0x080c, 0x99d9, 0x00ce, 0x0128, 0x6803, 0x0002, 0x6007, 0x0086,
+	0x0010, 0x6007, 0x0087, 0x6003, 0x0001, 0x080c, 0x6cff, 0x080c,
+	0x71e5, 0x00f6, 0x2278, 0x080c, 0x5377, 0x00fe, 0x0150, 0x6820,
+	0xd0ec, 0x0138, 0x00c6, 0x2260, 0x603f, 0x0000, 0x080c, 0x9ff1,
+	0x00ce, 0x00ee, 0x00de, 0x005e, 0x002e, 0x0005, 0xa186, 0x0013,
+	0x1160, 0x6004, 0xa08a, 0x0085, 0x0a0c, 0x151a, 0xa08a, 0x008c,
+	0x1a0c, 0x151a, 0xa082, 0x0085, 0x0072, 0xa186, 0x0027, 0x0120,
+	0xa186, 0x0014, 0x190c, 0x151a, 0x080c, 0x7102, 0x080c, 0x9ed9,
+	0x080c, 0x71e5, 0x0005, 0x9802, 0x9804, 0x9804, 0x9802, 0x9802,
+	0x9802, 0x9802, 0x080c, 0x151a, 0x080c, 0x7102, 0x080c, 0x9ed9,
+	0x080c, 0x71e5, 0x0005, 0xa186, 0x0013, 0x1128, 0x6004, 0xa082,
+	0x0085, 0x2008, 0x04a8, 0xa186, 0x0027, 0x11e8, 0x080c, 0x7102,
+	0x080c, 0x2cd1, 0x00d6, 0x6010, 0x2068, 0x080c, 0x9d16, 0x0150,
+	0x6837, 0x0103, 0x6847, 0x0000, 0x684b, 0x0029, 0x080c, 0x547a,
+	0x080c, 0x9ecd, 0x00de, 0x080c, 0x86a4, 0x080c, 0x71e5, 0x0005,
+	0x080c, 0x86ef, 0x0ce0, 0xa186, 0x0014, 0x1dd0, 0x080c, 0x7102,
+	0x00d6, 0x6010, 0x2068, 0x080c, 0x9d16, 0x0d60, 0x6837, 0x0103,
+	0x6847, 0x0000, 0x684b, 0x0006, 0x6850, 0xc0ec, 0x6852, 0x08f0,
+	0x0002, 0x9852, 0x9850, 0x9850, 0x9850, 0x9850, 0x9850, 0x986a,
+	0x080c, 0x151a, 0x080c, 0x7102, 0x6030, 0xa08c, 0xff00, 0x810f,
+	0xa186, 0x0039, 0x0118, 0xa186, 0x0035, 0x1118, 0x2001, 0xb8b6,
+	0x0010, 0x2001, 0xb8b7, 0x2004, 0x6016, 0x6003, 0x000c, 0x080c,
+	0x71e5, 0x0005, 0x080c, 0x7102, 0x6030, 0xa08c, 0xff00, 0x810f,
+	0xa186, 0x0039, 0x0118, 0xa186, 0x0035, 0x1118, 0x2001, 0xb8b6,
+	0x0010, 0x2001, 0xb8b7, 0x2004, 0x6016, 0x6003, 0x000e, 0x080c,
+	0x71e5, 0x0005, 0xa182, 0x008c, 0x1220, 0xa182, 0x0085, 0x0208,
+	0x001a, 0x080c, 0x86ef, 0x0005, 0x9893, 0x9893, 0x9893, 0x9893,
+	0x9895, 0x98ee, 0x9893, 0x080c, 0x151a, 0x00d6, 0x00f6, 0x2c78,
+	0x080c, 0x5377, 0x00fe, 0x0168, 0x6030, 0xa08c, 0xff00, 0x810f,
+	0xa186, 0x0039, 0x0118, 0xa186, 0x0035, 0x1118, 0x00de, 0x0804,
+	0x9901, 0x080c, 0x9d16, 0x1118, 0x080c, 0x9ecd, 0x00f0, 0x6010,
+	0x2068, 0x684c, 0xd0e4, 0x1110, 0x080c, 0x9ecd, 0x6837, 0x0103,
+	0x6850, 0xd0b4, 0x0128, 0x684b, 0x0006, 0xc0ec, 0x6852, 0x0048,
+	0xd0bc, 0x0118, 0x684b, 0x0002, 0x0020, 0x684b, 0x0005, 0x080c,
+	0x9f8e, 0x6847, 0x0000, 0x080c, 0x547a, 0x2c68, 0x080c, 0x864e,
+	0x01c0, 0x6003, 0x0001, 0x6007, 0x001e, 0x600b, 0xffff, 0x2009,
+	0xbc8e, 0x210c, 0x6136, 0x2009, 0xbc8f, 0x210c, 0x613a, 0x6918,
+	0x611a, 0x080c, 0xa0e3, 0x6950, 0x6152, 0x601f, 0x0001, 0x080c,
+	0x6cff, 0x2d60, 0x080c, 0x86a4, 0x00de, 0x0005, 0x00f6, 0x2c78,
+	0x080c, 0x5377, 0x00fe, 0x0598, 0x6030, 0xa08c, 0xff00, 0x810f,
+	0xa186, 0x0035, 0x0130, 0xa186, 0x001e, 0x0118, 0xa186, 0x0039,
+	0x1530, 0x00d6, 0x2c68, 0x080c, 0xa1c6, 0x1904, 0x9946, 0x080c,
+	0x864e, 0x01d8, 0x6106, 0x6003, 0x0001, 0x601f, 0x0001, 0x6918,
+	0x611a, 0x6928, 0x612a, 0x692c, 0x612e, 0x6930, 0xa18c, 0x00ff,
+	0x6132, 0x6934, 0x6136, 0x6938, 0x613a, 0x6950, 0x6152, 0x080c,
+	0xa0e3, 0x080c, 0x6cff, 0x080c, 0x71e5, 0x2d60, 0x00f8, 0x00d6,
+	0x6010, 0x2068, 0x080c, 0x9d16, 0x01c8, 0x6837, 0x0103, 0x6850,
+	0xd0b4, 0x0128, 0xc0ec, 0x6852, 0x684b, 0x0006, 0x0048, 0xd0bc,
+	0x0118, 0x684b, 0x0002, 0x0020, 0x684b, 0x0005, 0x080c, 0x9f8e,
+	0x6847, 0x0000, 0x080c, 0x547a, 0x080c, 0x9ecd, 0x00de, 0x080c,
+	0x86a4, 0x0005, 0x0016, 0x00d6, 0x6010, 0x2068, 0x080c, 0x9d16,
+	0x0140, 0x6837, 0x0103, 0x684b, 0x0028, 0x6847, 0x0000, 0x080c,
+	0x547a, 0x00de, 0x001e, 0xa186, 0x0013, 0x0148, 0xa186, 0x0014,
+	0x0130, 0xa186, 0x0027, 0x0118, 0x080c, 0x86ef, 0x0030, 0x080c,
+	0x7102, 0x080c, 0x9ed9, 0x080c, 0x71e5, 0x0005, 0x0056, 0x0066,
+	0x00d6, 0x00f6, 0x2029, 0x0001, 0xa182, 0x0101, 0x1208, 0x0010,
+	0x2009, 0x0100, 0x2130, 0x2069, 0xbc98, 0x831c, 0x2300, 0xad18,
+	0x2009, 0x0020, 0xaf90, 0x001d, 0x080c, 0x99c9, 0xa6b2, 0x0020,
+	0x7804, 0xa06d, 0x0110, 0x080c, 0x1624, 0x080c, 0x15fd, 0x0500,
+	0x8528, 0x6837, 0x0110, 0x683b, 0x0000, 0x2d20, 0x7c06, 0xa68a,
+	0x003d, 0x1228, 0x2608, 0xad90, 0x000f, 0x0459, 0x0088, 0xa6b2,
+	0x003c, 0x2009, 0x003c, 0x2d78, 0xad90, 0x000f, 0x0411, 0x0c28,
+	0x00fe, 0x852f, 0xa5ad, 0x0003, 0x7d36, 0xa5ac, 0x0000, 0x0028,
+	0x00fe, 0x852f, 0xa5ad, 0x0003, 0x7d36, 0x00de, 0x006e, 0x005e,
+	0x0005, 0x00f6, 0x8dff, 0x0158, 0x6804, 0xa07d, 0x0130, 0x6807,
+	0x0000, 0x080c, 0x547a, 0x2f68, 0x0cb8, 0x080c, 0x547a, 0x00fe,
+	0x0005, 0x0156, 0xa184, 0x0001, 0x0108, 0x8108, 0x810c, 0x21a8,
+	0x2304, 0x8007, 0x2012, 0x8318, 0x8210, 0x1f04, 0x99d0, 0x015e,
+	0x0005, 0x0066, 0x0126, 0x2091, 0x8000, 0x2031, 0x0001, 0x601c,
+	0xa084, 0x000f, 0x0083, 0x012e, 0x006e, 0x0005, 0x0126, 0x2091,
+	0x8000, 0x0066, 0x2031, 0x0000, 0x601c, 0xa084, 0x000f, 0x001b,
+	0x006e, 0x012e, 0x0005, 0x9a10, 0x9a10, 0x9a0b, 0x9a32, 0x99fe,
+	0x9a0b, 0x9a32, 0x9a0b, 0x9a0b, 0x99fe, 0x9a0b, 0x080c, 0x151a,
+	0x0036, 0x2019, 0x0010, 0x080c, 0xad9c, 0x601f, 0x0006, 0x6003,
+	0x0007, 0x003e, 0x0005, 0xa006, 0x0005, 0xa085, 0x0001, 0x0005,
+	0x00d6, 0x86ff, 0x11d8, 0x6010, 0x2068, 0x080c, 0x9d16, 0x01c0,
+	0x6834, 0xa086, 0x0139, 0x1128, 0x684b, 0x0005, 0x6853, 0x0000,
+	0x0028, 0xa00e, 0x2001, 0x0005, 0x080c, 0x554d, 0x080c, 0x9f8e,
+	0x080c, 0x547a, 0x080c, 0x86a4, 0xa085, 0x0001, 0x00de, 0x0005,
+	0xa006, 0x0ce0, 0x6000, 0xa08a, 0x0010, 0x1a0c, 0x151a, 0x000b,
+	0x0005, 0x9a49, 0x9a6a, 0x9a4b, 0x9a89, 0x9a67, 0x9a49, 0x9a0b,
+	0x9a10, 0x9a10, 0x9a0b, 0x9a0b, 0x9a0b, 0x9a0b, 0x9a0b, 0x9a0b,
+	0x9a0b, 0x080c, 0x151a, 0x86ff, 0x11b8, 0x601c, 0xa086, 0x0006,
+	0x0198, 0x00d6, 0x6010, 0x2068, 0x080c, 0x9d16, 0x0110, 0x080c,
+	0x9f8e, 0x00de, 0x6007, 0x0085, 0x6003, 0x000b, 0x601f, 0x0002,
+	0x080c, 0x6cff, 0x080c, 0x71e5, 0xa085, 0x0001, 0x0005, 0x080c,
+	0x1952, 0x0c08, 0x00e6, 0x2071, 0xb8e1, 0x7024, 0xac06, 0x1110,
+	0x080c, 0x7fe0, 0x601c, 0xa084, 0x000f, 0xa086, 0x0006, 0x1150,
+	0x0086, 0x0096, 0x2049, 0x0001, 0x2c40, 0x080c, 0x81b7, 0x009e,
+	0x008e, 0x0010, 0x080c, 0x7ed1, 0x00ee, 0x1928, 0x080c, 0x9a0b,
+	0x0005, 0x0036, 0x00e6, 0x2071, 0xb8e1, 0x703c, 0xac06, 0x1140,
+	0x2019, 0x0000, 0x080c, 0x806b, 0x00ee, 0x003e, 0x0804, 0x9a4b,
+	0x080c, 0x82e4, 0x00ee, 0x003e, 0x1904, 0x9a4b, 0x080c, 0x9a0b,
+	0x0005, 0x00c6, 0x601c, 0xa084, 0x000f, 0x0013, 0x00ce, 0x0005,
+	0x9aba, 0x9b27, 0x9c75, 0x9ac5, 0x9ed9, 0x9aba, 0xad8e, 0xa20a,
+	0x9b27, 0x9ab3, 0x9ce0, 0x080c, 0x151a, 0x080c, 0x9f14, 0x1110,
+	0x080c, 0x8ca5, 0x0005, 0x080c, 0x7102, 0x080c, 0x71e5, 0x080c,
+	0x86a4, 0x0005, 0x6017, 0x0001, 0x0005, 0x080c, 0x9d16, 0x0120,
+	0x6010, 0xa080, 0x0019, 0x2c02, 0x6000, 0xa08a, 0x0010, 0x1a0c,
+	0x151a, 0x000b, 0x0005, 0x9ae3, 0x9ae5, 0x9b05, 0x9b17, 0x9b24,
+	0x9ae3, 0x9aba, 0x9aba, 0x9aba, 0x9b17, 0x9b17, 0x9ae3, 0x9ae3,
+	0x9ae3, 0x9ae3, 0x9b21, 0x080c, 0x151a, 0x00e6, 0x6010, 0x2070,
+	0x7050, 0xc0b5, 0x7052, 0x2071, 0xb8e1, 0x7024, 0xac06, 0x0190,
+	0x080c, 0x7ed1, 0x6007, 0x0085, 0x6003, 0x000b, 0x601f, 0x0002,
+	0x2001, 0xb8b7, 0x2004, 0x6016, 0x080c, 0x6cff, 0x080c, 0x71e5,
+	0x00ee, 0x0005, 0x6017, 0x0001, 0x0cd8, 0x00d6, 0x6010, 0x2068,
+	0x6850, 0xc0b5, 0x6852, 0x00de, 0x6007, 0x0085, 0x6003, 0x000b,
+	0x601f, 0x0002, 0x080c, 0x6cff, 0x080c, 0x71e5, 0x0005, 0x00d6,
+	0x6017, 0x0001, 0x6010, 0x2068, 0x6850, 0xc0b5, 0x6852, 0x00de,
+	0x0005, 0x080c, 0x86a4, 0x0005, 0x080c, 0x1952, 0x08f0, 0x6000,
+	0xa08a, 0x0010, 0x1a0c, 0x151a, 0x000b, 0x0005, 0x9b3e, 0x9ac2,
+	0x9b40, 0x9b3e, 0x9b40, 0x9b40, 0x9abb, 0x9b3e, 0x9ab5, 0x9ab5,
+	0x9b3e, 0x9b3e, 0x9b3e, 0x9b3e, 0x9b3e, 0x9b3e, 0x080c, 0x151a,
+	0x00d6, 0x6018, 0x2068, 0x6804, 0xa084, 0x00ff, 0x00de, 0xa08a,
+	0x000c, 0x1a0c, 0x151a, 0x000b, 0x0005, 0x9b59, 0x9c1b, 0x9b5b,
+	0x9b99, 0x9b5b, 0x9b99, 0x9b5b, 0x9b69, 0x9b59, 0x9b99, 0x9b59,
+	0x9b85, 0x080c, 0x151a, 0x6004, 0xa08e, 0x0016, 0x05a8, 0xa08e,
+	0x0004, 0x0590, 0xa08e, 0x0002, 0x0578, 0xa08e, 0x004b, 0x0904,
+	0x9c17, 0x6004, 0x080c, 0x9f14, 0x0904, 0x9c34, 0xa08e, 0x0021,
+	0x0904, 0x9c38, 0xa08e, 0x0022, 0x0904, 0x9c34, 0xa08e, 0x003d,
+	0x0904, 0x9c38, 0xa08e, 0x0039, 0x0904, 0x9c3c, 0xa08e, 0x0035,
+	0x0904, 0x9c3c, 0xa08e, 0x001e, 0x0188, 0xa08e, 0x0001, 0x1150,
+	0x00d6, 0x6018, 0x2068, 0x6804, 0xa084, 0x00ff, 0x00de, 0xa086,
+	0x0006, 0x0110, 0x080c, 0x2cd1, 0x080c, 0x8ca5, 0x080c, 0x9ed9,
+	0x0005, 0x00c6, 0x00d6, 0x6104, 0xa186, 0x0016, 0x0904, 0x9c08,
+	0xa186, 0x0002, 0x15d8, 0x2001, 0xb635, 0x2004, 0xd08c, 0x1198,
+	0x080c, 0x5b41, 0x1180, 0x2001, 0xb89f, 0x2003, 0x0001, 0x2001,
+	0xb600, 0x2003, 0x0001, 0xa085, 0x0001, 0x080c, 0x5b85, 0x080c,
+	0x5a79, 0x0804, 0x9c5e, 0x6018, 0x2068, 0x2001, 0xb635, 0x2004,
+	0xd0ac, 0x1904, 0x9c5e, 0x68a0, 0xd0bc, 0x1904, 0x9c5e, 0x6840,
+	0xa084, 0x00ff, 0xa005, 0x0190, 0x8001, 0x6842, 0x6013, 0x0000,
+	0x601f, 0x0007, 0x6017, 0x0398, 0x603f, 0x0000, 0x080c, 0x864e,
+	0x0128, 0x2d00, 0x601a, 0x601f, 0x0001, 0x0450, 0x00de, 0x00ce,
+	0x6004, 0xa08e, 0x0002, 0x11a8, 0x6018, 0xa080, 0x0028, 0x2004,
+	0xa086, 0x007e, 0x1170, 0x2009, 0xb635, 0x2104, 0xc085, 0x200a,
+	0x00e6, 0x2071, 0xb600, 0x080c, 0x4c28, 0x00ee, 0x080c, 0x8ca5,
+	0x0020, 0x080c, 0x8ca5, 0x080c, 0x2cd1, 0x00e6, 0x0126, 0x2091,
+	0x8000, 0x080c, 0x2cf7, 0x012e, 0x00ee, 0x080c, 0x9ed9, 0x0005,
+	0x2001, 0x0002, 0x080c, 0x4f6f, 0x6003, 0x0001, 0x6007, 0x0002,
+	0x080c, 0x6d45, 0x080c, 0x71e5, 0x00de, 0x00ce, 0x0c80, 0x080c,
+	0x2cf7, 0x0804, 0x9b94, 0x00c6, 0x00d6, 0x6104, 0xa186, 0x0016,
+	0x0d38, 0x6018, 0x2068, 0x6840, 0xa084, 0x00ff, 0xa005, 0x0904,
+	0x9bde, 0x8001, 0x6842, 0x6003, 0x0001, 0x080c, 0x6d45, 0x080c,
+	0x71e5, 0x00de, 0x00ce, 0x0898, 0x080c, 0x8ca5, 0x0804, 0x9b96,
+	0x080c, 0x8cd3, 0x0804, 0x9b96, 0x00d6, 0x2c68, 0x6104, 0x080c,
+	0xa1c6, 0x00de, 0x0118, 0x080c, 0x86a4, 0x00b8, 0x6004, 0x8007,
+	0x6130, 0xa18c, 0x00ff, 0xa105, 0x6032, 0x6007, 0x0085, 0x6003,
+	0x000b, 0x601f, 0x0002, 0x6038, 0x600a, 0x2001, 0xb8b7, 0x2004,
+	0x6016, 0x080c, 0x6cff, 0x080c, 0x71e5, 0x0005, 0x00de, 0x00ce,
+	0x080c, 0x8ca5, 0x080c, 0x2cd1, 0x00e6, 0x0126, 0x2091, 0x8000,
+	0x080c, 0x2cf7, 0x6013, 0x0000, 0x601f, 0x0007, 0x6017, 0x0398,
+	0x603f, 0x0000, 0x012e, 0x00ee, 0x0005, 0x6000, 0xa08a, 0x0010,
+	0x1a0c, 0x151a, 0x000b, 0x0005, 0x9c8c, 0x9c8c, 0x9c8c, 0x9c8c,
+	0x9c8c, 0x9c8c, 0x9c8c, 0x9c8c, 0x9c8c, 0x9aba, 0x9c8c, 0x9ac2,
+	0x9c8e, 0x9ac2, 0x9c9b, 0x9c8c, 0x080c, 0x151a, 0x6004, 0xa086,
+	0x008b, 0x0148, 0x6007, 0x008b, 0x6003, 0x000d, 0x080c, 0x6cff,
+	0x080c, 0x71e5, 0x0005, 0x080c, 0x9ecd, 0x080c, 0x9d16, 0x0580,
+	0x080c, 0x2cd1, 0x00d6, 0x080c, 0x9d16, 0x0168, 0x6010, 0x2068,
+	0x6837, 0x0103, 0x684b, 0x0006, 0x6847, 0x0000, 0x6850, 0xc0ed,
+	0x6852, 0x080c, 0x547a, 0x2c68, 0x080c, 0x864e, 0x0150, 0x6818,
+	0x601a, 0x080c, 0xa0e3, 0x00c6, 0x2d60, 0x080c, 0x9ed9, 0x00ce,
+	0x0008, 0x2d60, 0x00de, 0x6013, 0x0000, 0x601f, 0x0001, 0x6007,
+	0x0001, 0x6003, 0x0001, 0x080c, 0x6d45, 0x080c, 0x71e5, 0x0078,
 	0x6030, 0xa08c, 0xff00, 0x810f, 0xa186, 0x0039, 0x0118, 0xa186,
-	0x0035, 0x1118, 0x2001, 0xb7b6, 0x0010, 0x2001, 0xb7b7, 0x2004,
-	0x6016, 0x6003, 0x000e, 0x080c, 0x7173, 0x0005, 0xa182, 0x008c,
-	0x1220, 0xa182, 0x0085, 0x0208, 0x001a, 0x080c, 0x8663, 0x0005,
-	0x97d7, 0x97d7, 0x97d7, 0x97d7, 0x97d9, 0x9832, 0x97d7, 0x080c,
-	0x1515, 0x00d6, 0x00f6, 0x2c78, 0x080c, 0x5305, 0x00fe, 0x0168,
-	0x6030, 0xa08c, 0xff00, 0x810f, 0xa186, 0x0039, 0x0118, 0xa186,
-	0x0035, 0x1118, 0x00de, 0x0804, 0x9845, 0x080c, 0x9c5a, 0x1118,
-	0x080c, 0x9e11, 0x00f0, 0x6010, 0x2068, 0x684c, 0xd0e4, 0x1110,
-	0x080c, 0x9e11, 0x6837, 0x0103, 0x6850, 0xd0b4, 0x0128, 0x684b,
-	0x0006, 0xc0ec, 0x6852, 0x0048, 0xd0bc, 0x0118, 0x684b, 0x0002,
-	0x0020, 0x684b, 0x0005, 0x080c, 0x9ed2, 0x6847, 0x0000, 0x080c,
-	0x5408, 0x2c68, 0x080c, 0x85c7, 0x01c0, 0x6003, 0x0001, 0x6007,
-	0x001e, 0x600b, 0xffff, 0x2009, 0xbb8e, 0x210c, 0x6136, 0x2009,
-	0xbb8f, 0x210c, 0x613a, 0x6918, 0x611a, 0x080c, 0xa027, 0x6950,
-	0x6152, 0x601f, 0x0001, 0x080c, 0x6c8d, 0x2d60, 0x080c, 0x861d,
-	0x00de, 0x0005, 0x00f6, 0x2c78, 0x080c, 0x5305, 0x00fe, 0x0598,
-	0x6030, 0xa08c, 0xff00, 0x810f, 0xa186, 0x0035, 0x0130, 0xa186,
-	0x001e, 0x0118, 0xa186, 0x0039, 0x1530, 0x00d6, 0x2c68, 0x080c,
-	0xa10a, 0x1904, 0x988a, 0x080c, 0x85c7, 0x01d8, 0x6106, 0x6003,
-	0x0001, 0x601f, 0x0001, 0x6918, 0x611a, 0x6928, 0x612a, 0x692c,
-	0x612e, 0x6930, 0xa18c, 0x00ff, 0x6132, 0x6934, 0x6136, 0x6938,
-	0x613a, 0x6950, 0x6152, 0x080c, 0xa027, 0x080c, 0x6c8d, 0x080c,
-	0x7173, 0x2d60, 0x00f8, 0x00d6, 0x6010, 0x2068, 0x080c, 0x9c5a,
-	0x01c8, 0x6837, 0x0103, 0x6850, 0xd0b4, 0x0128, 0xc0ec, 0x6852,
-	0x684b, 0x0006, 0x0048, 0xd0bc, 0x0118, 0x684b, 0x0002, 0x0020,
-	0x684b, 0x0005, 0x080c, 0x9ed2, 0x6847, 0x0000, 0x080c, 0x5408,
-	0x080c, 0x9e11, 0x00de, 0x080c, 0x861d, 0x0005, 0x0016, 0x00d6,
-	0x6010, 0x2068, 0x080c, 0x9c5a, 0x0140, 0x6837, 0x0103, 0x684b,
-	0x0028, 0x6847, 0x0000, 0x080c, 0x5408, 0x00de, 0x001e, 0xa186,
-	0x0013, 0x0148, 0xa186, 0x0014, 0x0130, 0xa186, 0x0027, 0x0118,
-	0x080c, 0x8663, 0x0030, 0x080c, 0x7090, 0x080c, 0x9e1d, 0x080c,
-	0x7173, 0x0005, 0x0056, 0x0066, 0x00d6, 0x00f6, 0x2029, 0x0001,
-	0xa182, 0x0101, 0x1208, 0x0010, 0x2009, 0x0100, 0x2130, 0x2069,
-	0xbb98, 0x831c, 0x2300, 0xad18, 0x2009, 0x0020, 0xaf90, 0x001d,
-	0x080c, 0x990d, 0xa6b2, 0x0020, 0x7804, 0xa06d, 0x0110, 0x080c,
-	0x161f, 0x080c, 0x15f8, 0x0500, 0x8528, 0x6837, 0x0110, 0x683b,
-	0x0000, 0x2d20, 0x7c06, 0xa68a, 0x003d, 0x1228, 0x2608, 0xad90,
-	0x000f, 0x0459, 0x0088, 0xa6b2, 0x003c, 0x2009, 0x003c, 0x2d78,
-	0xad90, 0x000f, 0x0411, 0x0c28, 0x00fe, 0x852f, 0xa5ad, 0x0003,
-	0x7d36, 0xa5ac, 0x0000, 0x0028, 0x00fe, 0x852f, 0xa5ad, 0x0003,
-	0x7d36, 0x00de, 0x006e, 0x005e, 0x0005, 0x00f6, 0x8dff, 0x0158,
-	0x6804, 0xa07d, 0x0130, 0x6807, 0x0000, 0x080c, 0x5408, 0x2f68,
-	0x0cb8, 0x080c, 0x5408, 0x00fe, 0x0005, 0x0156, 0xa184, 0x0001,
-	0x0108, 0x8108, 0x810c, 0x21a8, 0x2304, 0x8007, 0x2012, 0x8318,
-	0x8210, 0x1f04, 0x9914, 0x015e, 0x0005, 0x0066, 0x0126, 0x2091,
-	0x8000, 0x2031, 0x0001, 0x601c, 0xa084, 0x000f, 0x0083, 0x012e,
-	0x006e, 0x0005, 0x0126, 0x2091, 0x8000, 0x0066, 0x2031, 0x0000,
-	0x601c, 0xa084, 0x000f, 0x001b, 0x006e, 0x012e, 0x0005, 0x9954,
-	0x9954, 0x994f, 0x9976, 0x9942, 0x994f, 0x9976, 0x994f, 0x994f,
-	0x9942, 0x994f, 0x080c, 0x1515, 0x0036, 0x2019, 0x0010, 0x080c,
-	0xace0, 0x601f, 0x0006, 0x6003, 0x0007, 0x003e, 0x0005, 0xa006,
-	0x0005, 0xa085, 0x0001, 0x0005, 0x00d6, 0x86ff, 0x11d8, 0x6010,
-	0x2068, 0x080c, 0x9c5a, 0x01c0, 0x6834, 0xa086, 0x0139, 0x1128,
-	0x684b, 0x0005, 0x6853, 0x0000, 0x0028, 0xa00e, 0x2001, 0x0005,
-	0x080c, 0x54db, 0x080c, 0x9ed2, 0x080c, 0x5408, 0x080c, 0x861d,
-	0xa085, 0x0001, 0x00de, 0x0005, 0xa006, 0x0ce0, 0x6000, 0xa08a,
-	0x0010, 0x1a0c, 0x1515, 0x000b, 0x0005, 0x998d, 0x99ae, 0x998f,
-	0x99cd, 0x99ab, 0x998d, 0x994f, 0x9954, 0x9954, 0x994f, 0x994f,
-	0x994f, 0x994f, 0x994f, 0x994f, 0x994f, 0x080c, 0x1515, 0x86ff,
-	0x11b8, 0x601c, 0xa086, 0x0006, 0x0198, 0x00d6, 0x6010, 0x2068,
-	0x080c, 0x9c5a, 0x0110, 0x080c, 0x9ed2, 0x00de, 0x6007, 0x0085,
-	0x6003, 0x000b, 0x601f, 0x0002, 0x080c, 0x6c8d, 0x080c, 0x7173,
-	0xa085, 0x0001, 0x0005, 0x080c, 0x194d, 0x0c08, 0x00e6, 0x2071,
-	0xb7e0, 0x7024, 0xac06, 0x1110, 0x080c, 0x7f59, 0x601c, 0xa084,
-	0x000f, 0xa086, 0x0006, 0x1150, 0x0086, 0x0096, 0x2049, 0x0001,
-	0x2c40, 0x080c, 0x8130, 0x009e, 0x008e, 0x0010, 0x080c, 0x7e58,
-	0x00ee, 0x1928, 0x080c, 0x994f, 0x0005, 0x0036, 0x00e6, 0x2071,
-	0xb7e0, 0x703c, 0xac06, 0x1140, 0x2019, 0x0000, 0x080c, 0x7fe4,
-	0x00ee, 0x003e, 0x0804, 0x998f, 0x080c, 0x825d, 0x00ee, 0x003e,
-	0x1904, 0x998f, 0x080c, 0x994f, 0x0005, 0x00c6, 0x601c, 0xa084,
-	0x000f, 0x0013, 0x00ce, 0x0005, 0x99fe, 0x9a6b, 0x9bb9, 0x9a09,
-	0x9e1d, 0x99fe, 0xacd2, 0xa14e, 0x9a6b, 0x99f7, 0x9c24, 0x080c,
-	0x1515, 0x080c, 0x9e58, 0x1110, 0x080c, 0x8c19, 0x0005, 0x080c,
-	0x7090, 0x080c, 0x7173, 0x080c, 0x861d, 0x0005, 0x6017, 0x0001,
-	0x0005, 0x080c, 0x9c5a, 0x0120, 0x6010, 0xa080, 0x0019, 0x2c02,
-	0x6000, 0xa08a, 0x0010, 0x1a0c, 0x1515, 0x000b, 0x0005, 0x9a27,
-	0x9a29, 0x9a49, 0x9a5b, 0x9a68, 0x9a27, 0x99fe, 0x99fe, 0x99fe,
-	0x9a5b, 0x9a5b, 0x9a27, 0x9a27, 0x9a27, 0x9a27, 0x9a65, 0x080c,
-	0x1515, 0x00e6, 0x6010, 0x2070, 0x7050, 0xc0b5, 0x7052, 0x2071,
-	0xb7e0, 0x7024, 0xac06, 0x0190, 0x080c, 0x7e58, 0x6007, 0x0085,
-	0x6003, 0x000b, 0x601f, 0x0002, 0x2001, 0xb7b7, 0x2004, 0x6016,
-	0x080c, 0x6c8d, 0x080c, 0x7173, 0x00ee, 0x0005, 0x6017, 0x0001,
-	0x0cd8, 0x00d6, 0x6010, 0x2068, 0x6850, 0xc0b5, 0x6852, 0x00de,
-	0x6007, 0x0085, 0x6003, 0x000b, 0x601f, 0x0002, 0x080c, 0x6c8d,
-	0x080c, 0x7173, 0x0005, 0x00d6, 0x6017, 0x0001, 0x6010, 0x2068,
-	0x6850, 0xc0b5, 0x6852, 0x00de, 0x0005, 0x080c, 0x861d, 0x0005,
-	0x080c, 0x194d, 0x08f0, 0x6000, 0xa08a, 0x0010, 0x1a0c, 0x1515,
-	0x000b, 0x0005, 0x9a82, 0x9a06, 0x9a84, 0x9a82, 0x9a84, 0x9a84,
-	0x99ff, 0x9a82, 0x99f9, 0x99f9, 0x9a82, 0x9a82, 0x9a82, 0x9a82,
-	0x9a82, 0x9a82, 0x080c, 0x1515, 0x00d6, 0x6018, 0x2068, 0x6804,
-	0xa084, 0x00ff, 0x00de, 0xa08a, 0x000c, 0x1a0c, 0x1515, 0x000b,
-	0x0005, 0x9a9d, 0x9b5f, 0x9a9f, 0x9add, 0x9a9f, 0x9add, 0x9a9f,
-	0x9aad, 0x9a9d, 0x9add, 0x9a9d, 0x9ac9, 0x080c, 0x1515, 0x6004,
-	0xa08e, 0x0016, 0x05a8, 0xa08e, 0x0004, 0x0590, 0xa08e, 0x0002,
-	0x0578, 0xa08e, 0x004b, 0x0904, 0x9b5b, 0x6004, 0x080c, 0x9e58,
-	0x0904, 0x9b78, 0xa08e, 0x0021, 0x0904, 0x9b7c, 0xa08e, 0x0022,
-	0x0904, 0x9b78, 0xa08e, 0x003d, 0x0904, 0x9b7c, 0xa08e, 0x0039,
-	0x0904, 0x9b80, 0xa08e, 0x0035, 0x0904, 0x9b80, 0xa08e, 0x001e,
-	0x0188, 0xa08e, 0x0001, 0x1150, 0x00d6, 0x6018, 0x2068, 0x6804,
-	0xa084, 0x00ff, 0x00de, 0xa086, 0x0006, 0x0110, 0x080c, 0x2c9c,
-	0x080c, 0x8c19, 0x080c, 0x9e1d, 0x0005, 0x00c6, 0x00d6, 0x6104,
-	0xa186, 0x0016, 0x0904, 0x9b4c, 0xa186, 0x0002, 0x15d8, 0x2001,
-	0xb535, 0x2004, 0xd08c, 0x1198, 0x080c, 0x5acf, 0x1180, 0x2001,
-	0xb79f, 0x2003, 0x0001, 0x2001, 0xb500, 0x2003, 0x0001, 0xa085,
-	0x0001, 0x080c, 0x5b13, 0x080c, 0x5a07, 0x0804, 0x9ba2, 0x6018,
-	0x2068, 0x2001, 0xb535, 0x2004, 0xd0ac, 0x1904, 0x9ba2, 0x68a0,
-	0xd0bc, 0x1904, 0x9ba2, 0x6840, 0xa084, 0x00ff, 0xa005, 0x0190,
-	0x8001, 0x6842, 0x6013, 0x0000, 0x601f, 0x0007, 0x6017, 0x0398,
-	0x603f, 0x0000, 0x080c, 0x85c7, 0x0128, 0x2d00, 0x601a, 0x601f,
-	0x0001, 0x0450, 0x00de, 0x00ce, 0x6004, 0xa08e, 0x0002, 0x11a8,
-	0x6018, 0xa080, 0x0028, 0x2004, 0xa086, 0x007e, 0x1170, 0x2009,
-	0xb535, 0x2104, 0xc085, 0x200a, 0x00e6, 0x2071, 0xb500, 0x080c,
-	0x4bc6, 0x00ee, 0x080c, 0x8c19, 0x0020, 0x080c, 0x8c19, 0x080c,
-	0x2c9c, 0x00e6, 0x0126, 0x2091, 0x8000, 0x080c, 0x2cc2, 0x012e,
-	0x00ee, 0x080c, 0x9e1d, 0x0005, 0x2001, 0x0002, 0x080c, 0x4efd,
-	0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x6cd3, 0x080c, 0x7173,
-	0x00de, 0x00ce, 0x0c80, 0x080c, 0x2cc2, 0x0804, 0x9ad8, 0x00c6,
-	0x00d6, 0x6104, 0xa186, 0x0016, 0x0d38, 0x6018, 0x2068, 0x6840,
-	0xa084, 0x00ff, 0xa005, 0x0904, 0x9b22, 0x8001, 0x6842, 0x6003,
-	0x0001, 0x080c, 0x6cd3, 0x080c, 0x7173, 0x00de, 0x00ce, 0x0898,
-	0x080c, 0x8c19, 0x0804, 0x9ada, 0x080c, 0x8c47, 0x0804, 0x9ada,
-	0x00d6, 0x2c68, 0x6104, 0x080c, 0xa10a, 0x00de, 0x0118, 0x080c,
-	0x861d, 0x00b8, 0x6004, 0x8007, 0x6130, 0xa18c, 0x00ff, 0xa105,
-	0x6032, 0x6007, 0x0085, 0x6003, 0x000b, 0x601f, 0x0002, 0x6038,
-	0x600a, 0x2001, 0xb7b7, 0x2004, 0x6016, 0x080c, 0x6c8d, 0x080c,
-	0x7173, 0x0005, 0x00de, 0x00ce, 0x080c, 0x8c19, 0x080c, 0x2c9c,
-	0x00e6, 0x0126, 0x2091, 0x8000, 0x080c, 0x2cc2, 0x6013, 0x0000,
-	0x601f, 0x0007, 0x6017, 0x0398, 0x603f, 0x0000, 0x012e, 0x00ee,
-	0x0005, 0x6000, 0xa08a, 0x0010, 0x1a0c, 0x1515, 0x000b, 0x0005,
-	0x9bd0, 0x9bd0, 0x9bd0, 0x9bd0, 0x9bd0, 0x9bd0, 0x9bd0, 0x9bd0,
-	0x9bd0, 0x99fe, 0x9bd0, 0x9a06, 0x9bd2, 0x9a06, 0x9bdf, 0x9bd0,
-	0x080c, 0x1515, 0x6004, 0xa086, 0x008b, 0x0148, 0x6007, 0x008b,
-	0x6003, 0x000d, 0x080c, 0x6c8d, 0x080c, 0x7173, 0x0005, 0x080c,
-	0x9e11, 0x080c, 0x9c5a, 0x0580, 0x080c, 0x2c9c, 0x00d6, 0x080c,
-	0x9c5a, 0x0168, 0x6010, 0x2068, 0x6837, 0x0103, 0x684b, 0x0006,
-	0x6847, 0x0000, 0x6850, 0xc0ed, 0x6852, 0x080c, 0x5408, 0x2c68,
-	0x080c, 0x85c7, 0x0150, 0x6818, 0x601a, 0x080c, 0xa027, 0x00c6,
-	0x2d60, 0x080c, 0x9e1d, 0x00ce, 0x0008, 0x2d60, 0x00de, 0x6013,
-	0x0000, 0x601f, 0x0001, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c,
-	0x6cd3, 0x080c, 0x7173, 0x0078, 0x6030, 0xa08c, 0xff00, 0x810f,
-	0xa186, 0x0039, 0x0118, 0xa186, 0x0035, 0x1118, 0x080c, 0x2c9c,
-	0x08b0, 0x080c, 0x9e1d, 0x0005, 0x6000, 0xa08a, 0x0010, 0x1a0c,
-	0x1515, 0x000b, 0x0005, 0x9c3b, 0x9c3b, 0x9c3b, 0x9c3d, 0x9c3d,
-	0x9c3b, 0x9c3b, 0x9c3b, 0x9c3b, 0x9c3b, 0x9c3b, 0x9c3b, 0x9c3b,
-	0x9c3b, 0x9c3b, 0x9c3b, 0x080c, 0x1515, 0x080c, 0x825d, 0x190c,
-	0x1515, 0x6110, 0x2168, 0x684b, 0x0006, 0x080c, 0x5408, 0x080c,
-	0x861d, 0x0005, 0xa284, 0x0007, 0x1158, 0xa282, 0xbd00, 0x0240,
-	0x2001, 0xb517, 0x2004, 0xa202, 0x1218, 0xa085, 0x0001, 0x0005,
-	0xa006, 0x0ce8, 0x0026, 0x6210, 0xa294, 0xf000, 0x002e, 0x0005,
-	0x00e6, 0x00c6, 0x0036, 0x0006, 0x0126, 0x2091, 0x8000, 0x2061,
-	0xbd00, 0x2071, 0xb500, 0x7348, 0x7068, 0xa302, 0x12a8, 0x601c,
-	0xa206, 0x1160, 0x080c, 0x9fb2, 0x0148, 0x080c, 0x9e58, 0x1110,
-	0x080c, 0x8c19, 0x00c6, 0x080c, 0x861d, 0x00ce, 0xace0, 0x0018,
-	0x705c, 0xac02, 0x1208, 0x0c38, 0x012e, 0x000e, 0x003e, 0x00ce,
-	0x00ee, 0x0005, 0x00e6, 0x00c6, 0x0016, 0xa188, 0xb635, 0x210c,
-	0x81ff, 0x0128, 0x2061, 0xb8f4, 0x611a, 0x080c, 0x2c9c, 0xa006,
-	0x0010, 0xa085, 0x0001, 0x001e, 0x00ce, 0x00ee, 0x0005, 0x00c6,
-	0x0056, 0x0126, 0x2091, 0x8000, 0x00c6, 0x080c, 0x85c7, 0x005e,
-	0x0180, 0x6612, 0x651a, 0x080c, 0xa027, 0x601f, 0x0003, 0x2009,
-	0x004b, 0x080c, 0x864c, 0xa085, 0x0001, 0x012e, 0x005e, 0x00ce,
-	0x0005, 0xa006, 0x0cd0, 0x00c6, 0x0056, 0x0126, 0x2091, 0x8000,
-	0x62a0, 0x00c6, 0x080c, 0x9ed6, 0x005e, 0x0550, 0x6013, 0x0000,
-	0x651a, 0x080c, 0xa027, 0x601f, 0x0003, 0x0016, 0x00c6, 0x2560,
-	0x080c, 0x51aa, 0x00ce, 0x080c, 0x6df5, 0x0076, 0x2039, 0x0000,
-	0x080c, 0x6d02, 0x2c08, 0x080c, 0xae82, 0x007e, 0x001e, 0xd184,
-	0x0128, 0x080c, 0x861d, 0xa085, 0x0001, 0x0030, 0x2009, 0x004c,
-	0x080c, 0x864c, 0xa085, 0x0001, 0x012e, 0x005e, 0x00ce, 0x0005,
-	0xa006, 0x0cd0, 0x00f6, 0x00c6, 0x0046, 0x00c6, 0x080c, 0x85c7,
-	0x2c78, 0x00ce, 0x0180, 0x7e12, 0x2c00, 0x781a, 0x781f, 0x0003,
-	0x2021, 0x0005, 0x080c, 0x9d50, 0x2f60, 0x2009, 0x004d, 0x080c,
-	0x864c, 0xa085, 0x0001, 0x004e, 0x00ce, 0x00fe, 0x0005, 0x00f6,
-	0x00c6, 0x0046, 0x00c6, 0x080c, 0x85c7, 0x2c78, 0x00ce, 0x0178,
-	0x7e12, 0x2c00, 0x781a, 0x781f, 0x0003, 0x2021, 0x0005, 0x0481,
-	0x2f60, 0x2009, 0x004e, 0x080c, 0x864c, 0xa085, 0x0001, 0x004e,
+	0x0035, 0x1118, 0x080c, 0x2cd1, 0x08b0, 0x080c, 0x9ed9, 0x0005,
+	0x6000, 0xa08a, 0x0010, 0x1a0c, 0x151a, 0x000b, 0x0005, 0x9cf7,
+	0x9cf7, 0x9cf7, 0x9cf9, 0x9cf9, 0x9cf7, 0x9cf7, 0x9cf7, 0x9cf7,
+	0x9cf7, 0x9cf7, 0x9cf7, 0x9cf7, 0x9cf7, 0x9cf7, 0x9cf7, 0x080c,
+	0x151a, 0x080c, 0x82e4, 0x190c, 0x151a, 0x6110, 0x2168, 0x684b,
+	0x0006, 0x080c, 0x547a, 0x080c, 0x86a4, 0x0005, 0xa284, 0x0007,
+	0x1158, 0xa282, 0xbe00, 0x0240, 0x2001, 0xb617, 0x2004, 0xa202,
+	0x1218, 0xa085, 0x0001, 0x0005, 0xa006, 0x0ce8, 0x0026, 0x6210,
+	0xa294, 0xf000, 0x002e, 0x0005, 0x00e6, 0x00c6, 0x0036, 0x0006,
+	0x0126, 0x2091, 0x8000, 0x2061, 0xbe00, 0x2071, 0xb600, 0x7348,
+	0x7068, 0xa302, 0x12a8, 0x601c, 0xa206, 0x1160, 0x080c, 0xa06e,
+	0x0148, 0x080c, 0x9f14, 0x1110, 0x080c, 0x8ca5, 0x00c6, 0x080c,
+	0x86a4, 0x00ce, 0xace0, 0x0018, 0x705c, 0xac02, 0x1208, 0x0c38,
+	0x012e, 0x000e, 0x003e, 0x00ce, 0x00ee, 0x0005, 0x00e6, 0x00c6,
+	0x0016, 0xa188, 0xb735, 0x210c, 0x81ff, 0x0128, 0x2061, 0xb9f5,
+	0x611a, 0x080c, 0x2cd1, 0xa006, 0x0010, 0xa085, 0x0001, 0x001e,
+	0x00ce, 0x00ee, 0x0005, 0x00c6, 0x0056, 0x0126, 0x2091, 0x8000,
+	0x00c6, 0x080c, 0x864e, 0x005e, 0x0180, 0x6612, 0x651a, 0x080c,
+	0xa0e3, 0x601f, 0x0003, 0x2009, 0x004b, 0x080c, 0x86d3, 0xa085,
+	0x0001, 0x012e, 0x005e, 0x00ce, 0x0005, 0xa006, 0x0cd0, 0x00c6,
+	0x0056, 0x0126, 0x2091, 0x8000, 0x62a0, 0x00c6, 0x080c, 0x9f92,
+	0x005e, 0x0550, 0x6013, 0x0000, 0x651a, 0x080c, 0xa0e3, 0x601f,
+	0x0003, 0x0016, 0x00c6, 0x2560, 0x080c, 0x521c, 0x00ce, 0x080c,
+	0x6e67, 0x0076, 0x2039, 0x0000, 0x080c, 0x6d74, 0x2c08, 0x080c,
+	0xaf3e, 0x007e, 0x001e, 0xd184, 0x0128, 0x080c, 0x86a4, 0xa085,
+	0x0001, 0x0030, 0x2009, 0x004c, 0x080c, 0x86d3, 0xa085, 0x0001,
+	0x012e, 0x005e, 0x00ce, 0x0005, 0xa006, 0x0cd0, 0x00f6, 0x00c6,
+	0x0046, 0x00c6, 0x080c, 0x864e, 0x2c78, 0x00ce, 0x0180, 0x7e12,
+	0x2c00, 0x781a, 0x781f, 0x0003, 0x2021, 0x0005, 0x080c, 0x9e0c,
+	0x2f60, 0x2009, 0x004d, 0x080c, 0x86d3, 0xa085, 0x0001, 0x004e,
 	0x00ce, 0x00fe, 0x0005, 0x00f6, 0x00c6, 0x0046, 0x00c6, 0x080c,
-	0x85c7, 0x2c78, 0x00ce, 0x01c0, 0x7e12, 0x2c00, 0x781a, 0x781f,
-	0x0003, 0x2021, 0x0004, 0x00a1, 0x2001, 0xb7a0, 0x2004, 0xd0fc,
-	0x0120, 0x2f60, 0x080c, 0x861d, 0x0028, 0x2f60, 0x2009, 0x0052,
-	0x080c, 0x864c, 0xa085, 0x0001, 0x004e, 0x00ce, 0x00fe, 0x0005,
-	0x0096, 0x0076, 0x0126, 0x2091, 0x8000, 0x080c, 0x514c, 0x0118,
-	0x2001, 0x9d55, 0x0028, 0x080c, 0x511c, 0x0158, 0x2001, 0x9d5b,
-	0x0006, 0xa00e, 0x2400, 0x080c, 0x54db, 0x080c, 0x5408, 0x000e,
-	0x0807, 0x2418, 0x080c, 0x702f, 0x62a0, 0x0086, 0x2041, 0x0001,
-	0x2039, 0x0001, 0x2608, 0x080c, 0x6e0e, 0x008e, 0x080c, 0x6d02,
-	0x2f08, 0x2648, 0x080c, 0xae82, 0x613c, 0x81ff, 0x090c, 0x6ec3,
-	0x080c, 0x7173, 0x012e, 0x007e, 0x009e, 0x0005, 0x00c6, 0x0126,
-	0x2091, 0x8000, 0x00c6, 0x080c, 0x85c7, 0x001e, 0x0188, 0x660a,
-	0x611a, 0x080c, 0xa027, 0x601f, 0x0001, 0x2d00, 0x6012, 0x2009,
-	0x001f, 0x080c, 0x864c, 0xa085, 0x0001, 0x012e, 0x00ce, 0x0005,
-	0xa006, 0x0cd8, 0x00c6, 0x0126, 0x2091, 0x8000, 0x00c6, 0x080c,
-	0x85c7, 0x001e, 0x0188, 0x660a, 0x611a, 0x080c, 0xa027, 0x601f,
-	0x0008, 0x2d00, 0x6012, 0x2009, 0x0021, 0x080c, 0x864c, 0xa085,
+	0x864e, 0x2c78, 0x00ce, 0x0178, 0x7e12, 0x2c00, 0x781a, 0x781f,
+	0x0003, 0x2021, 0x0005, 0x0481, 0x2f60, 0x2009, 0x004e, 0x080c,
+	0x86d3, 0xa085, 0x0001, 0x004e, 0x00ce, 0x00fe, 0x0005, 0x00f6,
+	0x00c6, 0x0046, 0x00c6, 0x080c, 0x864e, 0x2c78, 0x00ce, 0x01c0,
+	0x7e12, 0x2c00, 0x781a, 0x781f, 0x0003, 0x2021, 0x0004, 0x00a1,
+	0x2001, 0xb8a0, 0x2004, 0xd0fc, 0x0120, 0x2f60, 0x080c, 0x86a4,
+	0x0028, 0x2f60, 0x2009, 0x0052, 0x080c, 0x86d3, 0xa085, 0x0001,
+	0x004e, 0x00ce, 0x00fe, 0x0005, 0x0096, 0x0076, 0x0126, 0x2091,
+	0x8000, 0x080c, 0x51be, 0x0118, 0x2001, 0x9e11, 0x0028, 0x080c,
+	0x518e, 0x0158, 0x2001, 0x9e17, 0x0006, 0xa00e, 0x2400, 0x080c,
+	0x554d, 0x080c, 0x547a, 0x000e, 0x0807, 0x2418, 0x080c, 0x70a1,
+	0x62a0, 0x0086, 0x2041, 0x0001, 0x2039, 0x0001, 0x2608, 0x080c,
+	0x6e80, 0x008e, 0x080c, 0x6d74, 0x2f08, 0x2648, 0x080c, 0xaf3e,
+	0x613c, 0x81ff, 0x090c, 0x6f35, 0x080c, 0x71e5, 0x012e, 0x007e,
+	0x009e, 0x0005, 0x00c6, 0x0126, 0x2091, 0x8000, 0x00c6, 0x080c,
+	0x864e, 0x001e, 0x0188, 0x660a, 0x611a, 0x080c, 0xa0e3, 0x601f,
+	0x0001, 0x2d00, 0x6012, 0x2009, 0x001f, 0x080c, 0x86d3, 0xa085,
 	0x0001, 0x012e, 0x00ce, 0x0005, 0xa006, 0x0cd8, 0x00c6, 0x0126,
-	0x2091, 0x8000, 0x00c6, 0x080c, 0x85c7, 0x001e, 0x0188, 0x660a,
-	0x611a, 0x080c, 0xa027, 0x601f, 0x0001, 0x2d00, 0x6012, 0x2009,
-	0x003d, 0x080c, 0x864c, 0xa085, 0x0001, 0x012e, 0x00ce, 0x0005,
+	0x2091, 0x8000, 0x00c6, 0x080c, 0x864e, 0x001e, 0x0188, 0x660a,
+	0x611a, 0x080c, 0xa0e3, 0x601f, 0x0008, 0x2d00, 0x6012, 0x2009,
+	0x0021, 0x080c, 0x86d3, 0xa085, 0x0001, 0x012e, 0x00ce, 0x0005,
 	0xa006, 0x0cd8, 0x00c6, 0x0126, 0x2091, 0x8000, 0x00c6, 0x080c,
-	0x9ed6, 0x001e, 0x0180, 0x611a, 0x080c, 0xa027, 0x601f, 0x0001,
-	0x2d00, 0x6012, 0x2009, 0x0000, 0x080c, 0x864c, 0xa085, 0x0001,
-	0x012e, 0x00ce, 0x0005, 0xa006, 0x0cd8, 0x00c6, 0x0126, 0x2091,
-	0x8000, 0x00c6, 0x080c, 0x85c7, 0x001e, 0x0188, 0x660a, 0x611a,
-	0x080c, 0xa027, 0x601f, 0x0001, 0x2d00, 0x6012, 0x2009, 0x0044,
-	0x080c, 0x864c, 0xa085, 0x0001, 0x012e, 0x00ce, 0x0005, 0xa006,
-	0x0cd8, 0x0026, 0x00d6, 0x6218, 0x2268, 0x6a3c, 0x82ff, 0x0110,
-	0x8211, 0x6a3e, 0x00de, 0x002e, 0x0005, 0x0006, 0x6000, 0xa086,
-	0x0000, 0x0190, 0x6013, 0x0000, 0x601f, 0x0007, 0x2001, 0xb7b6,
-	0x2004, 0x0006, 0xa082, 0x0051, 0x000e, 0x0208, 0x8004, 0x6016,
-	0x080c, 0xb33a, 0x603f, 0x0000, 0x000e, 0x0005, 0x0066, 0x00c6,
-	0x00d6, 0x2031, 0xb553, 0x2634, 0xd6e4, 0x0128, 0x6618, 0x2660,
-	0x6e48, 0x080c, 0x50d5, 0x00de, 0x00ce, 0x006e, 0x0005, 0x0006,
-	0x0016, 0x6004, 0xa08e, 0x0002, 0x0140, 0xa08e, 0x0003, 0x0128,
-	0xa08e, 0x0004, 0x0110, 0xa085, 0x0001, 0x001e, 0x000e, 0x0005,
-	0x0006, 0x00d6, 0x6010, 0xa06d, 0x0148, 0x6834, 0xa086, 0x0139,
-	0x0138, 0x6838, 0xd0fc, 0x0110, 0xa006, 0x0010, 0xa085, 0x0001,
-	0x00de, 0x000e, 0x0005, 0x00c6, 0x0126, 0x2091, 0x8000, 0x00c6,
-	0x080c, 0x85c7, 0x001e, 0x0190, 0x611a, 0x080c, 0xa027, 0x601f,
-	0x0001, 0x2d00, 0x6012, 0x080c, 0x2c9c, 0x2009, 0x0028, 0x080c,
-	0x864c, 0xa085, 0x0001, 0x012e, 0x00ce, 0x0005, 0xa006, 0x0cd8,
-	0xa186, 0x0015, 0x1178, 0x2011, 0xb521, 0x2204, 0xa086, 0x0074,
-	0x1148, 0x080c, 0x8f98, 0x6003, 0x0001, 0x6007, 0x0029, 0x080c,
-	0x6cd3, 0x0020, 0x080c, 0x8c19, 0x080c, 0x861d, 0x0005, 0xa186,
-	0x0016, 0x1128, 0x2001, 0x0004, 0x080c, 0x4efd, 0x00e8, 0xa186,
-	0x0015, 0x11e8, 0x2011, 0xb521, 0x2204, 0xa086, 0x0014, 0x11b8,
-	0x00d6, 0x6018, 0x2068, 0x080c, 0x504b, 0x00de, 0x080c, 0x9051,
-	0x1170, 0x00d6, 0x6018, 0x2068, 0x6890, 0x00de, 0xa005, 0x0138,
-	0x2001, 0x0006, 0x080c, 0x4efd, 0x080c, 0x87a0, 0x0020, 0x080c,
-	0x8c19, 0x080c, 0x861d, 0x0005, 0x6848, 0xa086, 0x0005, 0x1108,
-	0x0009, 0x0005, 0x6850, 0xc0ad, 0x6852, 0x0005, 0x00e6, 0x0126,
-	0x2071, 0xb500, 0x2091, 0x8000, 0x7548, 0xa582, 0x0001, 0x0608,
-	0x704c, 0x2060, 0x6000, 0xa086, 0x0000, 0x0148, 0xace0, 0x0018,
-	0x705c, 0xac02, 0x1208, 0x0cb0, 0x2061, 0xbd00, 0x0c98, 0x6003,
-	0x0008, 0x8529, 0x754a, 0xaca8, 0x0018, 0x705c, 0xa502, 0x1230,
-	0x754e, 0xa085, 0x0001, 0x012e, 0x00ee, 0x0005, 0x704f, 0xbd00,
-	0x0cc0, 0xa006, 0x0cc0, 0x00e6, 0x2071, 0xbb8c, 0x7014, 0xd0e4,
-	0x0150, 0x6013, 0x0000, 0x6003, 0x0001, 0x6007, 0x0050, 0x080c,
-	0x6c8d, 0x080c, 0x7173, 0x00ee, 0x0005, 0x00c6, 0x00f6, 0x2c78,
-	0x080c, 0x5305, 0x00fe, 0x0120, 0x601c, 0xa084, 0x000f, 0x0013,
-	0x00ce, 0x0005, 0x99fe, 0x9f2d, 0x9f30, 0x9f33, 0xb127, 0xb142,
-	0xb145, 0x99fe, 0x99fe, 0x080c, 0x1515, 0xe000, 0xe000, 0x0005,
-	0xe000, 0xe000, 0x0005, 0x0009, 0x0005, 0x00f6, 0x2c78, 0x080c,
-	0x5305, 0x0538, 0x080c, 0x85c7, 0x1128, 0x2001, 0xb7b8, 0x2004,
-	0x783e, 0x00f8, 0x7818, 0x601a, 0x080c, 0xa027, 0x781c, 0xa086,
-	0x0003, 0x0128, 0x7808, 0x6036, 0x2f00, 0x603a, 0x0020, 0x7808,
-	0x603a, 0x2f00, 0x6036, 0x602a, 0x601f, 0x0001, 0x6007, 0x0035,
-	0x6003, 0x0001, 0x7950, 0x6152, 0x080c, 0x6c8d, 0x080c, 0x7173,
-	0x2f60, 0x00fe, 0x0005, 0x0016, 0x00f6, 0x682c, 0x6032, 0xa08e,
-	0x0001, 0x0138, 0xa086, 0x0005, 0x0140, 0xa006, 0x602a, 0x602e,
-	0x00a0, 0x6820, 0xc0f4, 0xc0d5, 0x6822, 0x6810, 0x2078, 0x787c,
-	0x6938, 0xa102, 0x7880, 0x6934, 0xa103, 0x1e78, 0x6834, 0x602a,
-	0x6838, 0xa084, 0xfffc, 0x683a, 0x602e, 0x2d00, 0x6036, 0x6808,
-	0x603a, 0x6918, 0x611a, 0x6950, 0x6152, 0x601f, 0x0001, 0x6007,
-	0x0039, 0x6003, 0x0001, 0x080c, 0x6c8d, 0x6803, 0x0002, 0x00fe,
-	0x001e, 0x0005, 0x00f6, 0x2c78, 0x080c, 0x5305, 0x1118, 0xa085,
-	0x0001, 0x0070, 0x6020, 0xd0f4, 0x1150, 0xc0f5, 0x6022, 0x6010,
-	0x2078, 0x7828, 0x603a, 0x782c, 0x6036, 0x080c, 0x194d, 0xa006,
-	0x00fe, 0x0005, 0x0006, 0x0016, 0x6004, 0xa08e, 0x0034, 0x01b8,
-	0xa08e, 0x0035, 0x01a0, 0xa08e, 0x0036, 0x0188, 0xa08e, 0x0037,
-	0x0170, 0xa08e, 0x0038, 0x0158, 0xa08e, 0x0039, 0x0140, 0xa08e,
-	0x003a, 0x0128, 0xa08e, 0x003b, 0x0110, 0xa085, 0x0001, 0x001e,
-	0x000e, 0x0005, 0x0006, 0x0016, 0x0026, 0x0036, 0x00e6, 0x2001,
-	0xb7b2, 0x200c, 0x8000, 0x2014, 0x2001, 0x0032, 0x080c, 0x6b40,
-	0x2001, 0xb7b6, 0x82ff, 0x1110, 0x2011, 0x0014, 0x2202, 0x2001,
-	0xb7b4, 0x200c, 0x8000, 0x2014, 0x2071, 0xb78e, 0x711a, 0x721e,
-	0x2001, 0x0064, 0x080c, 0x6b40, 0x2001, 0xb7b7, 0x82ff, 0x1110,
-	0x2011, 0x0014, 0x2202, 0x2009, 0xb7b8, 0xa280, 0x000a, 0x200a,
-	0x080c, 0x532a, 0x00ee, 0x003e, 0x002e, 0x001e, 0x000e, 0x0005,
-	0x0006, 0x00e6, 0x2001, 0xb7b6, 0x2003, 0x0028, 0x2001, 0xb7b7,
-	0x2003, 0x0014, 0x2071, 0xb78e, 0x701b, 0x0000, 0x701f, 0x07d0,
-	0x2001, 0xb7b8, 0x2003, 0x001e, 0x00ee, 0x000e, 0x0005, 0x00d6,
-	0x6054, 0xa06d, 0x0110, 0x080c, 0x160f, 0x00de, 0x0005, 0x0005,
-	0x00c6, 0x0126, 0x2091, 0x8000, 0x00c6, 0x080c, 0x85c7, 0x001e,
-	0x0178, 0x611a, 0x0ca1, 0x601f, 0x0001, 0x2d00, 0x6012, 0x2009,
-	0x0033, 0x080c, 0x864c, 0xa085, 0x0001, 0x012e, 0x00ce, 0x0005,
-	0xa006, 0x0cd8, 0x00d6, 0x00e6, 0x00f6, 0x2071, 0xb500, 0xa186,
-	0x0015, 0x1500, 0x7084, 0xa086, 0x0018, 0x11e0, 0x6010, 0x2068,
-	0x6a3c, 0xd2e4, 0x1160, 0x2c78, 0x080c, 0x7331, 0x01d8, 0x7070,
-	0x6a50, 0xa206, 0x1160, 0x7074, 0x6a54, 0xa206, 0x1140, 0x6218,
-	0xa290, 0x0028, 0x2214, 0x2009, 0x0000, 0x080c, 0x2ce1, 0x080c,
-	0x87a0, 0x0020, 0x080c, 0x8c19, 0x080c, 0x861d, 0x00fe, 0x00ee,
-	0x00de, 0x0005, 0x7054, 0x6a54, 0xa206, 0x0d48, 0x0c80, 0x00c6,
-	0x0126, 0x2091, 0x8000, 0x00c6, 0x080c, 0x85c7, 0x001e, 0x0180,
-	0x611a, 0x080c, 0xa027, 0x601f, 0x0001, 0x2d00, 0x6012, 0x2009,
-	0x0043, 0x080c, 0x864c, 0xa085, 0x0001, 0x012e, 0x00ce, 0x0005,
-	0xa006, 0x0cd8, 0x00d6, 0x00e6, 0x00f6, 0x2071, 0xb500, 0xa186,
-	0x0015, 0x11c0, 0x7084, 0xa086, 0x0004, 0x11a0, 0x6010, 0xa0e8,
-	0x000f, 0x2c78, 0x080c, 0x7331, 0x01a8, 0x7070, 0x6a08, 0xa206,
-	0x1130, 0x7074, 0x6a0c, 0xa206, 0x1110, 0x080c, 0x2c9c, 0x080c,
-	0x87a0, 0x0020, 0x080c, 0x8c19, 0x080c, 0x861d, 0x00fe, 0x00ee,
-	0x00de, 0x0005, 0x7054, 0x6a0c, 0xa206, 0x0d78, 0x0c80, 0x0016,
-	0x0026, 0x684c, 0xd0ac, 0x0178, 0x6914, 0x6a10, 0x2100, 0xa205,
-	0x0150, 0x6860, 0xa106, 0x1118, 0x685c, 0xa206, 0x0120, 0x6962,
-	0x6a5e, 0xa085, 0x0001, 0x002e, 0x001e, 0x0005, 0x00d6, 0x0036,
-	0x6310, 0x2368, 0x684a, 0x6952, 0xa29e, 0x4000, 0x11a0, 0x00c6,
-	0x6318, 0x2360, 0x2009, 0x0000, 0x6838, 0xd0f4, 0x1140, 0x080c,
-	0x524a, 0x1108, 0xc185, 0x6000, 0xd0bc, 0x0108, 0xc18d, 0x6a66,
-	0x696a, 0x00ce, 0x0080, 0x6a66, 0x3918, 0xa398, 0x0006, 0x231c,
-	0x686b, 0x0004, 0x6b72, 0x00c6, 0x6318, 0x2360, 0x6004, 0xa084,
-	0x00ff, 0x686e, 0x00ce, 0x080c, 0x5408, 0x6013, 0x0000, 0x003e,
-	0x00de, 0x0005, 0x00c6, 0x0026, 0x0016, 0xa186, 0x0035, 0x0110,
-	0x6a34, 0x0008, 0x6a28, 0x080c, 0x9c4a, 0x01f0, 0x2260, 0x611c,
-	0xa186, 0x0003, 0x0118, 0xa186, 0x0006, 0x1190, 0x6834, 0xa206,
-	0x0140, 0x6838, 0xa206, 0x1160, 0x6108, 0x6834, 0xa106, 0x1140,
-	0x0020, 0x6008, 0x6938, 0xa106, 0x1118, 0x6018, 0x6918, 0xa106,
-	0x001e, 0x002e, 0x00ce, 0x0005, 0xa085, 0x0001, 0x0cc8, 0x6944,
-	0xd1cc, 0x0198, 0xa18c, 0x00ff, 0xa18e, 0x0002, 0x1170, 0xad88,
-	0x001e, 0x210c, 0xa18c, 0x0f00, 0x810f, 0xa18e, 0x0001, 0x1128,
-	0x6810, 0x6914, 0xa115, 0x190c, 0x9483, 0x0005, 0x080c, 0x861d,
-	0x0804, 0x7173, 0x0066, 0x6000, 0xa0b2, 0x0010, 0x1a0c, 0x1515,
-	0x0013, 0x006e, 0x0005, 0xa16b, 0xa646, 0xa76c, 0xa16b, 0xa16b,
-	0xa16b, 0xa16b, 0xa16b, 0xa1a3, 0xa7f0, 0xa16b, 0xa16b, 0xa16b,
-	0xa16b, 0xa16b, 0xa16b, 0x080c, 0x1515, 0x0066, 0x6000, 0xa0b2,
-	0x0010, 0x1a0c, 0x1515, 0x0013, 0x006e, 0x0005, 0xa186, 0xac77,
-	0xa186, 0xa186, 0xa186, 0xa186, 0xa186, 0xa186, 0xac39, 0xacbf,
-	0xa186, 0xb26c, 0xb29c, 0xb26c, 0xb29c, 0xa186, 0x080c, 0x1515,
-	0x0066, 0x6000, 0xa0b2, 0x0010, 0x1a0c, 0x1515, 0x0013, 0x006e,
-	0x0005, 0xa1a1, 0xa940, 0xaa0d, 0xaa3a, 0xaabe, 0xa1a1, 0xabab,
-	0xab56, 0xa7fc, 0xac0f, 0xac24, 0xa1a1, 0xa1a1, 0xa1a1, 0xa1a1,
-	0xa1a1, 0x080c, 0x1515, 0xa1b2, 0x0080, 0x1a0c, 0x1515, 0x2100,
-	0xa1b2, 0x0040, 0x1a04, 0xa5ba, 0x0002, 0xa1ed, 0xa3b8, 0xa1ed,
-	0xa1ed, 0xa1ed, 0xa3bf, 0xa1ed, 0xa1ed, 0xa1ed, 0xa1ed, 0xa1ed,
-	0xa1ed, 0xa1ed, 0xa1ed, 0xa1ed, 0xa1ed, 0xa1ed, 0xa1ed, 0xa1ed,
-	0xa1ed, 0xa1ed, 0xa1ed, 0xa1ed, 0xa1ef, 0xa24d, 0xa25c, 0xa2aa,
-	0xa2c8, 0xa346, 0xa3a5, 0xa1ed, 0xa1ed, 0xa3c2, 0xa1ed, 0xa1ed,
-	0xa3d5, 0xa3e0, 0xa1ed, 0xa1ed, 0xa1ed, 0xa1ed, 0xa1ed, 0xa46b,
-	0xa1ed, 0xa1ed, 0xa47e, 0xa1ed, 0xa1ed, 0xa436, 0xa1ed, 0xa1ed,
-	0xa1ed, 0xa496, 0xa1ed, 0xa1ed, 0xa1ed, 0xa510, 0xa1ed, 0xa1ed,
-	0xa1ed, 0xa1ed, 0xa1ed, 0xa1ed, 0xa581, 0x080c, 0x1515, 0x080c,
-	0x5309, 0x1150, 0x2001, 0xb535, 0x2004, 0xd0cc, 0x1128, 0xa084,
-	0x0009, 0xa086, 0x0008, 0x1140, 0x6007, 0x0009, 0x602b, 0x0009,
-	0x6013, 0x0000, 0x0804, 0xa3b3, 0x080c, 0x52f9, 0x00e6, 0x00c6,
-	0x0036, 0x0026, 0x0016, 0x6218, 0x2270, 0x72a0, 0x0026, 0x2019,
-	0x0029, 0x080c, 0x6df5, 0x0076, 0x2039, 0x0000, 0x080c, 0x6d02,
-	0x2c08, 0x080c, 0xae82, 0x007e, 0x001e, 0x2e60, 0x080c, 0x51aa,
-	0x001e, 0x002e, 0x003e, 0x00ce, 0x00ee, 0x6618, 0x00c6, 0x2660,
-	0x080c, 0x4fb8, 0x00ce, 0xa6b0, 0x0001, 0x2634, 0xa684, 0x00ff,
-	0xa082, 0x0006, 0x0278, 0x080c, 0xadc6, 0x1904, 0xa2a4, 0x080c,
-	0xad66, 0x1120, 0x6007, 0x0008, 0x0804, 0xa3b3, 0x6007, 0x0009,
-	0x0804, 0xa3b3, 0x080c, 0xaf7b, 0x0128, 0x080c, 0xadc6, 0x0d78,
-	0x0804, 0xa2a4, 0x6013, 0x1900, 0x0c88, 0x080c, 0x2dbf, 0x1904,
-	0xa5b7, 0x6106, 0x080c, 0xad20, 0x6007, 0x0006, 0x0804, 0xa3b3,
-	0x6007, 0x0007, 0x0804, 0xa3b3, 0x080c, 0xb2d0, 0x1904, 0xa5b7,
-	0x080c, 0x2dbf, 0x1904, 0xa5b7, 0x00d6, 0x6618, 0x2668, 0x6e04,
-	0xa684, 0x00ff, 0xa082, 0x0006, 0x1220, 0x2001, 0x0001, 0x080c,
-	0x4eeb, 0xa6b4, 0xff00, 0x8637, 0xa686, 0x0006, 0x0188, 0xa686,
-	0x0004, 0x0170, 0x6e04, 0xa6b4, 0x00ff, 0xa686, 0x0006, 0x0140,
-	0xa686, 0x0004, 0x0128, 0xa686, 0x0005, 0x0110, 0x00de, 0x00e0,
-	0x080c, 0xae24, 0x11a0, 0xa686, 0x0006, 0x1150, 0x0026, 0x6218,
-	0xa290, 0x0028, 0x2214, 0x2009, 0x0000, 0x080c, 0x2ce1, 0x002e,
-	0x080c, 0x504b, 0x6007, 0x000a, 0x00de, 0x0804, 0xa3b3, 0x6007,
-	0x000b, 0x00de, 0x0804, 0xa3b3, 0x080c, 0x2c9c, 0x6007, 0x0001,
-	0x0804, 0xa3b3, 0x080c, 0xb2d0, 0x1904, 0xa5b7, 0x080c, 0x2dbf,
-	0x1904, 0xa5b7, 0x6618, 0x00d6, 0x2668, 0x6e04, 0x00de, 0xa686,
-	0x0707, 0x0d50, 0x0026, 0x6218, 0xa290, 0x0028, 0x2214, 0x2009,
-	0x0000, 0x080c, 0x2ce1, 0x002e, 0x6007, 0x000c, 0x0804, 0xa3b3,
-	0x080c, 0x5309, 0x1140, 0x2001, 0xb535, 0x2004, 0xa084, 0x0009,
-	0xa086, 0x0008, 0x1110, 0x0804, 0xa1fc, 0x080c, 0x52f9, 0x6618,
-	0xa6b0, 0x0001, 0x2634, 0xa684, 0x00ff, 0xa082, 0x0006, 0x06e8,
-	0x1138, 0x0026, 0x2001, 0x0006, 0x080c, 0x4f2a, 0x002e, 0x0050,
-	0xa6b4, 0xff00, 0x8637, 0xa686, 0x0004, 0x0120, 0xa686, 0x0006,
-	0x1904, 0xa2a4, 0x080c, 0xae31, 0x1120, 0x6007, 0x000e, 0x0804,
-	0xa3b3, 0x0046, 0x6418, 0xa4a0, 0x0028, 0x2424, 0xa4a4, 0x00ff,
-	0x8427, 0x0046, 0x080c, 0x2c9c, 0x004e, 0x0016, 0xa006, 0x2009,
-	0xb553, 0x210c, 0xd1a4, 0x0158, 0x2009, 0x0029, 0x080c, 0xb0e8,
-	0x6018, 0x00d6, 0x2068, 0x6800, 0xc0e5, 0x6802, 0x00de, 0x001e,
-	0x004e, 0x6007, 0x0001, 0x0804, 0xa3b3, 0x2001, 0x0001, 0x080c,
-	0x4eeb, 0x0156, 0x0016, 0x0026, 0x0036, 0x20a9, 0x0004, 0x2019,
-	0xb505, 0x2011, 0xbb90, 0x080c, 0x90da, 0x003e, 0x002e, 0x001e,
-	0x015e, 0xa005, 0x0168, 0xa6b4, 0xff00, 0x8637, 0xa682, 0x0004,
-	0x0a04, 0xa2a4, 0xa682, 0x0007, 0x0a04, 0xa2f2, 0x0804, 0xa2a4,
-	0x6013, 0x1900, 0x6007, 0x0009, 0x0804, 0xa3b3, 0x080c, 0x5309,
-	0x1140, 0x2001, 0xb535, 0x2004, 0xa084, 0x0009, 0xa086, 0x0008,
-	0x1110, 0x0804, 0xa1fc, 0x080c, 0x52f9, 0x6618, 0xa6b0, 0x0001,
-	0x2634, 0xa684, 0x00ff, 0xa082, 0x0006, 0x06b8, 0xa6b4, 0xff00,
-	0x8637, 0xa686, 0x0004, 0x0120, 0xa686, 0x0006, 0x1904, 0xa2a4,
-	0x080c, 0xae59, 0x1138, 0x080c, 0xad66, 0x1120, 0x6007, 0x0010,
-	0x0804, 0xa3b3, 0x0046, 0x6418, 0xa4a0, 0x0028, 0x2424, 0xa4a4,
-	0x00ff, 0x8427, 0x0046, 0x080c, 0x2c9c, 0x004e, 0x0016, 0xa006,
-	0x2009, 0xb553, 0x210c, 0xd1a4, 0x0158, 0x2009, 0x0029, 0x080c,
-	0xb0e8, 0x6018, 0x00d6, 0x2068, 0x6800, 0xc0e5, 0x6802, 0x00de,
-	0x001e, 0x004e, 0x6007, 0x0001, 0x00f0, 0x080c, 0xaf7b, 0x0140,
-	0xa6b4, 0xff00, 0x8637, 0xa686, 0x0006, 0x0950, 0x0804, 0xa2a4,
-	0x6013, 0x1900, 0x6007, 0x0009, 0x0070, 0x080c, 0x2dbf, 0x1904,
-	0xa5b7, 0x080c, 0xb2d0, 0x1904, 0xa5b7, 0x080c, 0xa5df, 0x1904,
-	0xa2a4, 0x6007, 0x0012, 0x6003, 0x0001, 0x080c, 0x6cd3, 0x0005,
-	0x6007, 0x0001, 0x6003, 0x0001, 0x080c, 0x6cd3, 0x0cc0, 0x6007,
-	0x0005, 0x0cc0, 0x080c, 0xb2d0, 0x1904, 0xa5b7, 0x080c, 0x2dbf,
-	0x1904, 0xa5b7, 0x080c, 0xa5df, 0x1904, 0xa2a4, 0x6007, 0x0020,
-	0x6003, 0x0001, 0x080c, 0x6cd3, 0x0005, 0x080c, 0x2dbf, 0x1904,
-	0xa5b7, 0x6007, 0x0023, 0x6003, 0x0001, 0x080c, 0x6cd3, 0x0005,
-	0x080c, 0xb2d0, 0x1904, 0xa5b7, 0x080c, 0x2dbf, 0x1904, 0xa5b7,
-	0x080c, 0xa5df, 0x1904, 0xa2a4, 0x0016, 0x0026, 0x2011, 0xbb91,
-	0x2214, 0xa286, 0xffff, 0x0190, 0x2c08, 0x080c, 0x9c4a, 0x01e0,
-	0x2260, 0x2011, 0xbb90, 0x2214, 0x6008, 0xa206, 0x11a8, 0x6018,
-	0xa190, 0x0006, 0x2214, 0xa206, 0x01e8, 0x0070, 0x2011, 0xbb90,
-	0x2214, 0x2c08, 0xa006, 0x080c, 0xb0ba, 0x11a0, 0x2011, 0xbb91,
-	0x2214, 0xa286, 0xffff, 0x01c0, 0x2160, 0x6007, 0x0026, 0x6013,
-	0x1700, 0x2011, 0xbb89, 0x2214, 0xa296, 0xffff, 0x1180, 0x6007,
-	0x0025, 0x0068, 0x601c, 0xa086, 0x0007, 0x1d70, 0x6004, 0xa086,
-	0x0024, 0x1110, 0x080c, 0x861d, 0x2160, 0x6007, 0x0025, 0x6003,
-	0x0001, 0x080c, 0x6cd3, 0x002e, 0x001e, 0x0005, 0x2001, 0x0001,
-	0x080c, 0x4eeb, 0x0156, 0x0016, 0x0026, 0x0036, 0x20a9, 0x0004,
-	0x2019, 0xb505, 0x2011, 0xbb96, 0x080c, 0x90da, 0x003e, 0x002e,
-	0x001e, 0x015e, 0x0120, 0x6007, 0x0031, 0x0804, 0xa3b3, 0x080c,
-	0x8df6, 0x080c, 0x5acf, 0x11b0, 0x0006, 0x0026, 0x0036, 0x080c,
-	0x5aeb, 0x1158, 0x2001, 0xb79f, 0x2003, 0x0001, 0x2001, 0xb500,
-	0x2003, 0x0001, 0x080c, 0x5a07, 0x0010, 0x080c, 0x5aa6, 0x003e,
-	0x002e, 0x000e, 0x0005, 0x080c, 0x2dbf, 0x1904, 0xa5b7, 0x080c,
-	0xa5df, 0x1904, 0xa2a4, 0x6106, 0x080c, 0xa5fb, 0x6007, 0x002b,
-	0x0804, 0xa3b3, 0x6007, 0x002c, 0x0804, 0xa3b3, 0x080c, 0xb2d0,
-	0x1904, 0xa5b7, 0x080c, 0x2dbf, 0x1904, 0xa5b7, 0x080c, 0xa5df,
-	0x1904, 0xa2a4, 0x6106, 0x080c, 0xa5ff, 0x1120, 0x6007, 0x002e,
-	0x0804, 0xa3b3, 0x6007, 0x002f, 0x0804, 0xa3b3, 0x080c, 0x2dbf,
-	0x1904, 0xa5b7, 0x00e6, 0x00d6, 0x00c6, 0x6018, 0xa080, 0x0001,
-	0x200c, 0xa184, 0x00ff, 0xa086, 0x0006, 0x0158, 0xa184, 0xff00,
-	0x8007, 0xa086, 0x0006, 0x0128, 0x00ce, 0x00de, 0x00ee, 0x0804,
-	0xa3b8, 0x2001, 0xb572, 0x2004, 0xd0e4, 0x0904, 0xa50d, 0x2071,
-	0xbb8c, 0x7010, 0x6036, 0x7014, 0x603a, 0x7108, 0x720c, 0x2001,
-	0xb553, 0x2004, 0xd0a4, 0x0140, 0x6018, 0x2068, 0x6810, 0xa106,
-	0x1118, 0x6814, 0xa206, 0x01f8, 0x2001, 0xb553, 0x2004, 0xd0ac,
-	0x1590, 0x2069, 0xb500, 0x6874, 0xa206, 0x1568, 0x6870, 0xa106,
-	0x1550, 0x7210, 0x080c, 0x9c4a, 0x0558, 0x080c, 0xb154, 0x0540,
-	0x622a, 0x6007, 0x0036, 0x6003, 0x0001, 0x080c, 0x6c8d, 0x00ce,
-	0x00de, 0x00ee, 0x0005, 0x7214, 0xa286, 0xffff, 0x0150, 0x080c,
-	0x9c4a, 0x01b0, 0xa280, 0x0002, 0x2004, 0x7110, 0xa106, 0x1180,
-	0x0c08, 0x7210, 0x2c08, 0xa085, 0x0001, 0x080c, 0xb0ba, 0x2c10,
-	0x2160, 0x0130, 0x08b8, 0x6007, 0x0037, 0x6013, 0x1500, 0x08d8,
-	0x6007, 0x0037, 0x6013, 0x1700, 0x08b0, 0x6007, 0x0012, 0x0898,
-	0x080c, 0x2dbf, 0x1904, 0xa5b7, 0x6018, 0xa080, 0x0001, 0x2004,
-	0xa084, 0xff00, 0x8007, 0xa086, 0x0006, 0x1904, 0xa3b8, 0x00e6,
-	0x00d6, 0x00c6, 0x2001, 0xb572, 0x2004, 0xd0e4, 0x0904, 0xa579,
-	0x2069, 0xb500, 0x2071, 0xbb8c, 0x7008, 0x6036, 0x720c, 0x623a,
-	0xa286, 0xffff, 0x1150, 0x7208, 0x00c6, 0x2c08, 0xa085, 0x0001,
-	0x080c, 0xb0ba, 0x2c10, 0x00ce, 0x0588, 0x080c, 0x9c4a, 0x0570,
-	0x00c6, 0x0026, 0x2260, 0x080c, 0x991d, 0x002e, 0x00ce, 0x7118,
-	0xa18c, 0xff00, 0x810f, 0xa186, 0x0001, 0x0158, 0xa186, 0x0005,
-	0x0118, 0xa186, 0x0007, 0x1178, 0xa280, 0x0004, 0x2004, 0xa005,
-	0x0150, 0x0056, 0x7510, 0x7614, 0x080c, 0xb16b, 0x005e, 0x00ce,
-	0x00de, 0x00ee, 0x0005, 0x6007, 0x003b, 0x602b, 0x0009, 0x6013,
-	0x2a00, 0x6003, 0x0001, 0x080c, 0x6c8d, 0x0c88, 0x6007, 0x003b,
-	0x602b, 0x0009, 0x6013, 0x1700, 0x6003, 0x0001, 0x080c, 0x6c8d,
-	0x0c30, 0x6007, 0x003b, 0x602b, 0x000b, 0x6013, 0x0000, 0x0804,
-	0xa4e3, 0x00e6, 0x0026, 0x080c, 0x5309, 0x0558, 0x080c, 0x52f9,
-	0x080c, 0xb34b, 0x1520, 0x2071, 0xb500, 0x70d4, 0xc085, 0x70d6,
-	0x00f6, 0x2079, 0x0100, 0x72a0, 0xa284, 0x00ff, 0x7072, 0x78e6,
-	0xa284, 0xff00, 0x7274, 0xa205, 0x7076, 0x78ea, 0x00fe, 0x70df,
-	0x0000, 0x2001, 0xb553, 0x2004, 0xd0a4, 0x0120, 0x2011, 0xb7f9,
-	0x2013, 0x07d0, 0xd0ac, 0x1128, 0x080c, 0x2ab8, 0x0010, 0x080c,
-	0xb377, 0x002e, 0x00ee, 0x080c, 0x861d, 0x0804, 0xa3b7, 0x080c,
-	0x861d, 0x0005, 0x2600, 0x0002, 0xa5c5, 0xa5c5, 0xa5c5, 0xa5c5,
-	0xa5c5, 0xa5c7, 0xa5c5, 0xa5c5, 0xa5c5, 0x080c, 0x1515, 0x080c,
-	0xb2d0, 0x1d68, 0x080c, 0x2dbf, 0x1d50, 0x0089, 0x1138, 0x6007,
-	0x0045, 0x6003, 0x0001, 0x080c, 0x6cd3, 0x0005, 0x080c, 0x2c9c,
-	0x6007, 0x0001, 0x6003, 0x0001, 0x080c, 0x6cd3, 0x0005, 0x00d6,
-	0x0066, 0x6618, 0x2668, 0x6e04, 0xa6b4, 0xff00, 0x8637, 0xa686,
-	0x0006, 0x0170, 0xa686, 0x0004, 0x0158, 0x6e04, 0xa6b4, 0x00ff,
-	0xa686, 0x0006, 0x0128, 0xa686, 0x0004, 0x0110, 0xa085, 0x0001,
-	0x006e, 0x00de, 0x0005, 0x00d6, 0x0449, 0x00de, 0x0005, 0x00d6,
-	0x0491, 0x11f0, 0x680c, 0xa08c, 0xff00, 0x6820, 0xa084, 0x00ff,
-	0xa115, 0x6212, 0x6824, 0x602a, 0xd1e4, 0x0118, 0x2009, 0x0001,
-	0x0060, 0xd1ec, 0x0168, 0x6920, 0xa18c, 0x00ff, 0x6824, 0x080c,
-	0x281d, 0x1130, 0x2110, 0x2009, 0x0000, 0x080c, 0x2ce1, 0x0018,
-	0xa085, 0x0001, 0x0008, 0xa006, 0x00de, 0x0005, 0x2069, 0xbb8d,
-	0x6800, 0xa082, 0x0010, 0x1228, 0x6013, 0x0000, 0xa085, 0x0001,
-	0x0008, 0xa006, 0x0005, 0x6013, 0x0000, 0x2069, 0xbb8c, 0x6808,
-	0xa084, 0xff00, 0xa086, 0x0800, 0x1140, 0x6800, 0xa084, 0x00ff,
-	0xa08e, 0x0014, 0x0110, 0xa08e, 0x0010, 0x0005, 0x6004, 0xa0b2,
-	0x0080, 0x1a0c, 0x1515, 0xa1b6, 0x0013, 0x1130, 0x2008, 0xa1b2,
-	0x0040, 0x1a04, 0xa746, 0x0092, 0xa1b6, 0x0027, 0x0120, 0xa1b6,
-	0x0014, 0x190c, 0x1515, 0x2001, 0x0007, 0x080c, 0x4f2a, 0x080c,
-	0x7090, 0x080c, 0x9e1d, 0x080c, 0x7173, 0x0005, 0xa6a6, 0xa6a8,
-	0xa6a6, 0xa6a6, 0xa6a6, 0xa6a8, 0xa6ba, 0xa73f, 0xa70a, 0xa73f,
-	0xa71b, 0xa73f, 0xa6ba, 0xa73f, 0xa737, 0xa73f, 0xa737, 0xa73f,
-	0xa73f, 0xa6a6, 0xa6a6, 0xa6a6, 0xa6a6, 0xa6a6, 0xa6a6, 0xa6a6,
-	0xa6a6, 0xa6a6, 0xa6a6, 0xa6a6, 0xa6a8, 0xa6a6, 0xa73f, 0xa6a6,
-	0xa6a6, 0xa73f, 0xa6a6, 0xa73c, 0xa73f, 0xa6a6, 0xa6a6, 0xa6a6,
-	0xa6a6, 0xa73f, 0xa73f, 0xa6a6, 0xa73f, 0xa73f, 0xa6a6, 0xa6b4,
-	0xa6a6, 0xa6a6, 0xa6a6, 0xa6a6, 0xa73b, 0xa73f, 0xa6a6, 0xa6a6,
-	0xa73f, 0xa73f, 0xa6a6, 0xa6a6, 0xa6a6, 0xa6a6, 0x080c, 0x1515,
-	0x080c, 0x7090, 0x2001, 0xb7b6, 0x2004, 0x6016, 0x6003, 0x0002,
-	0x080c, 0x7173, 0x0804, 0xa745, 0x2001, 0x0000, 0x080c, 0x4eeb,
-	0x0804, 0xa73f, 0x00f6, 0x2079, 0xb552, 0x7804, 0x00fe, 0xd0ac,
-	0x1904, 0xa73f, 0x2001, 0x0000, 0x080c, 0x4eeb, 0x6018, 0xa080,
-	0x0004, 0x2004, 0xa086, 0x00ff, 0x1140, 0x00f6, 0x2079, 0xb500,
-	0x7898, 0x8000, 0x789a, 0x00fe, 0x00e0, 0x00c6, 0x6018, 0x2060,
-	0x6000, 0xd0f4, 0x1140, 0x6010, 0xa005, 0x0128, 0x00ce, 0x080c,
-	0x3f3e, 0x0804, 0xa73f, 0x00ce, 0x2001, 0xb500, 0x2004, 0xa086,
-	0x0002, 0x1138, 0x00f6, 0x2079, 0xb500, 0x7898, 0x8000, 0x789a,
-	0x00fe, 0x2001, 0x0002, 0x080c, 0x4efd, 0x080c, 0x7090, 0x601f,
-	0x0001, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x6cd3, 0x080c,
-	0x7173, 0x00c6, 0x6118, 0x2160, 0x2009, 0x0001, 0x080c, 0x69a8,
-	0x00ce, 0x04d8, 0x6618, 0x00d6, 0x2668, 0x6e04, 0x00de, 0xa6b4,
-	0xff00, 0x8637, 0xa686, 0x0006, 0x0550, 0xa686, 0x0004, 0x0538,
-	0x2001, 0x0004, 0x0410, 0x2001, 0xb500, 0x2004, 0xa086, 0x0003,
-	0x1110, 0x080c, 0x3f3e, 0x2001, 0x0006, 0x04a1, 0x6618, 0x00d6,
+	0x864e, 0x001e, 0x0188, 0x660a, 0x611a, 0x080c, 0xa0e3, 0x601f,
+	0x0001, 0x2d00, 0x6012, 0x2009, 0x003d, 0x080c, 0x86d3, 0xa085,
+	0x0001, 0x012e, 0x00ce, 0x0005, 0xa006, 0x0cd8, 0x00c6, 0x0126,
+	0x2091, 0x8000, 0x00c6, 0x080c, 0x9f92, 0x001e, 0x0180, 0x611a,
+	0x080c, 0xa0e3, 0x601f, 0x0001, 0x2d00, 0x6012, 0x2009, 0x0000,
+	0x080c, 0x86d3, 0xa085, 0x0001, 0x012e, 0x00ce, 0x0005, 0xa006,
+	0x0cd8, 0x00c6, 0x0126, 0x2091, 0x8000, 0x00c6, 0x080c, 0x864e,
+	0x001e, 0x0188, 0x660a, 0x611a, 0x080c, 0xa0e3, 0x601f, 0x0001,
+	0x2d00, 0x6012, 0x2009, 0x0044, 0x080c, 0x86d3, 0xa085, 0x0001,
+	0x012e, 0x00ce, 0x0005, 0xa006, 0x0cd8, 0x0026, 0x00d6, 0x6218,
+	0x2268, 0x6a3c, 0x82ff, 0x0110, 0x8211, 0x6a3e, 0x00de, 0x002e,
+	0x0005, 0x0006, 0x6000, 0xa086, 0x0000, 0x0190, 0x6013, 0x0000,
+	0x601f, 0x0007, 0x2001, 0xb8b6, 0x2004, 0x0006, 0xa082, 0x0051,
+	0x000e, 0x0208, 0x8004, 0x6016, 0x080c, 0xb3f6, 0x603f, 0x0000,
+	0x000e, 0x0005, 0x0066, 0x00c6, 0x00d6, 0x2031, 0xb653, 0x2634,
+	0xd6e4, 0x0128, 0x6618, 0x2660, 0x6e48, 0x080c, 0x5147, 0x00de,
+	0x00ce, 0x006e, 0x0005, 0x0006, 0x0016, 0x6004, 0xa08e, 0x0002,
+	0x0140, 0xa08e, 0x0003, 0x0128, 0xa08e, 0x0004, 0x0110, 0xa085,
+	0x0001, 0x001e, 0x000e, 0x0005, 0x0006, 0x00d6, 0x6010, 0xa06d,
+	0x0148, 0x6834, 0xa086, 0x0139, 0x0138, 0x6838, 0xd0fc, 0x0110,
+	0xa006, 0x0010, 0xa085, 0x0001, 0x00de, 0x000e, 0x0005, 0x00c6,
+	0x0126, 0x2091, 0x8000, 0x00c6, 0x080c, 0x864e, 0x001e, 0x0190,
+	0x611a, 0x080c, 0xa0e3, 0x601f, 0x0001, 0x2d00, 0x6012, 0x080c,
+	0x2cd1, 0x2009, 0x0028, 0x080c, 0x86d3, 0xa085, 0x0001, 0x012e,
+	0x00ce, 0x0005, 0xa006, 0x0cd8, 0xa186, 0x0015, 0x1178, 0x2011,
+	0xb621, 0x2204, 0xa086, 0x0074, 0x1148, 0x080c, 0x9024, 0x6003,
+	0x0001, 0x6007, 0x0029, 0x080c, 0x6d45, 0x0020, 0x080c, 0x8ca5,
+	0x080c, 0x86a4, 0x0005, 0xa186, 0x0016, 0x1128, 0x2001, 0x0004,
+	0x080c, 0x4f6f, 0x00e8, 0xa186, 0x0015, 0x11e8, 0x2011, 0xb621,
+	0x2204, 0xa086, 0x0014, 0x11b8, 0x00d6, 0x6018, 0x2068, 0x080c,
+	0x50bd, 0x00de, 0x080c, 0x90dd, 0x1170, 0x00d6, 0x6018, 0x2068,
+	0x6890, 0x00de, 0xa005, 0x0138, 0x2001, 0x0006, 0x080c, 0x4f6f,
+	0x080c, 0x882c, 0x0020, 0x080c, 0x8ca5, 0x080c, 0x86a4, 0x0005,
+	0x6848, 0xa086, 0x0005, 0x1108, 0x0009, 0x0005, 0x6850, 0xc0ad,
+	0x6852, 0x0005, 0x00e6, 0x0126, 0x2071, 0xb600, 0x2091, 0x8000,
+	0x7548, 0xa582, 0x0001, 0x0608, 0x704c, 0x2060, 0x6000, 0xa086,
+	0x0000, 0x0148, 0xace0, 0x0018, 0x705c, 0xac02, 0x1208, 0x0cb0,
+	0x2061, 0xbe00, 0x0c98, 0x6003, 0x0008, 0x8529, 0x754a, 0xaca8,
+	0x0018, 0x705c, 0xa502, 0x1230, 0x754e, 0xa085, 0x0001, 0x012e,
+	0x00ee, 0x0005, 0x704f, 0xbe00, 0x0cc0, 0xa006, 0x0cc0, 0x00e6,
+	0x2071, 0xbc8c, 0x7014, 0xd0e4, 0x0150, 0x6013, 0x0000, 0x6003,
+	0x0001, 0x6007, 0x0050, 0x080c, 0x6cff, 0x080c, 0x71e5, 0x00ee,
+	0x0005, 0x00c6, 0x00f6, 0x2c78, 0x080c, 0x5377, 0x00fe, 0x0120,
+	0x601c, 0xa084, 0x000f, 0x0013, 0x00ce, 0x0005, 0x9aba, 0x9fe9,
+	0x9fec, 0x9fef, 0xb1e3, 0xb1fe, 0xb201, 0x9aba, 0x9aba, 0x080c,
+	0x151a, 0xe000, 0xe000, 0x0005, 0xe000, 0xe000, 0x0005, 0x0009,
+	0x0005, 0x00f6, 0x2c78, 0x080c, 0x5377, 0x0538, 0x080c, 0x864e,
+	0x1128, 0x2001, 0xb8b8, 0x2004, 0x783e, 0x00f8, 0x7818, 0x601a,
+	0x080c, 0xa0e3, 0x781c, 0xa086, 0x0003, 0x0128, 0x7808, 0x6036,
+	0x2f00, 0x603a, 0x0020, 0x7808, 0x603a, 0x2f00, 0x6036, 0x602a,
+	0x601f, 0x0001, 0x6007, 0x0035, 0x6003, 0x0001, 0x7950, 0x6152,
+	0x080c, 0x6cff, 0x080c, 0x71e5, 0x2f60, 0x00fe, 0x0005, 0x0016,
+	0x00f6, 0x682c, 0x6032, 0xa08e, 0x0001, 0x0138, 0xa086, 0x0005,
+	0x0140, 0xa006, 0x602a, 0x602e, 0x00a0, 0x6820, 0xc0f4, 0xc0d5,
+	0x6822, 0x6810, 0x2078, 0x787c, 0x6938, 0xa102, 0x7880, 0x6934,
+	0xa103, 0x1e78, 0x6834, 0x602a, 0x6838, 0xa084, 0xfffc, 0x683a,
+	0x602e, 0x2d00, 0x6036, 0x6808, 0x603a, 0x6918, 0x611a, 0x6950,
+	0x6152, 0x601f, 0x0001, 0x6007, 0x0039, 0x6003, 0x0001, 0x080c,
+	0x6cff, 0x6803, 0x0002, 0x00fe, 0x001e, 0x0005, 0x00f6, 0x2c78,
+	0x080c, 0x5377, 0x1118, 0xa085, 0x0001, 0x0070, 0x6020, 0xd0f4,
+	0x1150, 0xc0f5, 0x6022, 0x6010, 0x2078, 0x7828, 0x603a, 0x782c,
+	0x6036, 0x080c, 0x1952, 0xa006, 0x00fe, 0x0005, 0x0006, 0x0016,
+	0x6004, 0xa08e, 0x0034, 0x01b8, 0xa08e, 0x0035, 0x01a0, 0xa08e,
+	0x0036, 0x0188, 0xa08e, 0x0037, 0x0170, 0xa08e, 0x0038, 0x0158,
+	0xa08e, 0x0039, 0x0140, 0xa08e, 0x003a, 0x0128, 0xa08e, 0x003b,
+	0x0110, 0xa085, 0x0001, 0x001e, 0x000e, 0x0005, 0x0006, 0x0016,
+	0x0026, 0x0036, 0x00e6, 0x2001, 0xb8b2, 0x200c, 0x8000, 0x2014,
+	0x2001, 0x0032, 0x080c, 0x6bb2, 0x2001, 0xb8b6, 0x82ff, 0x1110,
+	0x2011, 0x0014, 0x2202, 0x2001, 0xb8b4, 0x200c, 0x8000, 0x2014,
+	0x2071, 0xb88e, 0x711a, 0x721e, 0x2001, 0x0064, 0x080c, 0x6bb2,
+	0x2001, 0xb8b7, 0x82ff, 0x1110, 0x2011, 0x0014, 0x2202, 0x2009,
+	0xb8b8, 0xa280, 0x000a, 0x200a, 0x080c, 0x539c, 0x00ee, 0x003e,
+	0x002e, 0x001e, 0x000e, 0x0005, 0x0006, 0x00e6, 0x2001, 0xb8b6,
+	0x2003, 0x0028, 0x2001, 0xb8b7, 0x2003, 0x0014, 0x2071, 0xb88e,
+	0x701b, 0x0000, 0x701f, 0x07d0, 0x2001, 0xb8b8, 0x2003, 0x001e,
+	0x00ee, 0x000e, 0x0005, 0x00d6, 0x6054, 0xa06d, 0x0110, 0x080c,
+	0x1614, 0x00de, 0x0005, 0x0005, 0x00c6, 0x0126, 0x2091, 0x8000,
+	0x00c6, 0x080c, 0x864e, 0x001e, 0x0178, 0x611a, 0x0ca1, 0x601f,
+	0x0001, 0x2d00, 0x6012, 0x2009, 0x0033, 0x080c, 0x86d3, 0xa085,
+	0x0001, 0x012e, 0x00ce, 0x0005, 0xa006, 0x0cd8, 0x00d6, 0x00e6,
+	0x00f6, 0x2071, 0xb600, 0xa186, 0x0015, 0x1500, 0x7084, 0xa086,
+	0x0018, 0x11e0, 0x6010, 0x2068, 0x6a3c, 0xd2e4, 0x1160, 0x2c78,
+	0x080c, 0x73a3, 0x01d8, 0x7070, 0x6a50, 0xa206, 0x1160, 0x7074,
+	0x6a54, 0xa206, 0x1140, 0x6218, 0xa290, 0x0028, 0x2214, 0x2009,
+	0x0000, 0x080c, 0x2d16, 0x080c, 0x882c, 0x0020, 0x080c, 0x8ca5,
+	0x080c, 0x86a4, 0x00fe, 0x00ee, 0x00de, 0x0005, 0x7054, 0x6a54,
+	0xa206, 0x0d48, 0x0c80, 0x00c6, 0x0126, 0x2091, 0x8000, 0x00c6,
+	0x080c, 0x864e, 0x001e, 0x0180, 0x611a, 0x080c, 0xa0e3, 0x601f,
+	0x0001, 0x2d00, 0x6012, 0x2009, 0x0043, 0x080c, 0x86d3, 0xa085,
+	0x0001, 0x012e, 0x00ce, 0x0005, 0xa006, 0x0cd8, 0x00d6, 0x00e6,
+	0x00f6, 0x2071, 0xb600, 0xa186, 0x0015, 0x11c0, 0x7084, 0xa086,
+	0x0004, 0x11a0, 0x6010, 0xa0e8, 0x000f, 0x2c78, 0x080c, 0x73a3,
+	0x01a8, 0x7070, 0x6a08, 0xa206, 0x1130, 0x7074, 0x6a0c, 0xa206,
+	0x1110, 0x080c, 0x2cd1, 0x080c, 0x882c, 0x0020, 0x080c, 0x8ca5,
+	0x080c, 0x86a4, 0x00fe, 0x00ee, 0x00de, 0x0005, 0x7054, 0x6a0c,
+	0xa206, 0x0d78, 0x0c80, 0x0016, 0x0026, 0x684c, 0xd0ac, 0x0178,
+	0x6914, 0x6a10, 0x2100, 0xa205, 0x0150, 0x6860, 0xa106, 0x1118,
+	0x685c, 0xa206, 0x0120, 0x6962, 0x6a5e, 0xa085, 0x0001, 0x002e,
+	0x001e, 0x0005, 0x00d6, 0x0036, 0x6310, 0x2368, 0x684a, 0x6952,
+	0xa29e, 0x4000, 0x11a0, 0x00c6, 0x6318, 0x2360, 0x2009, 0x0000,
+	0x6838, 0xd0f4, 0x1140, 0x080c, 0x52bc, 0x1108, 0xc185, 0x6000,
+	0xd0bc, 0x0108, 0xc18d, 0x6a66, 0x696a, 0x00ce, 0x0080, 0x6a66,
+	0x3918, 0xa398, 0x0006, 0x231c, 0x686b, 0x0004, 0x6b72, 0x00c6,
+	0x6318, 0x2360, 0x6004, 0xa084, 0x00ff, 0x686e, 0x00ce, 0x080c,
+	0x547a, 0x6013, 0x0000, 0x003e, 0x00de, 0x0005, 0x00c6, 0x0026,
+	0x0016, 0xa186, 0x0035, 0x0110, 0x6a34, 0x0008, 0x6a28, 0x080c,
+	0x9d06, 0x01f0, 0x2260, 0x611c, 0xa186, 0x0003, 0x0118, 0xa186,
+	0x0006, 0x1190, 0x6834, 0xa206, 0x0140, 0x6838, 0xa206, 0x1160,
+	0x6108, 0x6834, 0xa106, 0x1140, 0x0020, 0x6008, 0x6938, 0xa106,
+	0x1118, 0x6018, 0x6918, 0xa106, 0x001e, 0x002e, 0x00ce, 0x0005,
+	0xa085, 0x0001, 0x0cc8, 0x6944, 0xd1cc, 0x0198, 0xa18c, 0x00ff,
+	0xa18e, 0x0002, 0x1170, 0xad88, 0x001e, 0x210c, 0xa18c, 0x0f00,
+	0x810f, 0xa18e, 0x0001, 0x1128, 0x6810, 0x6914, 0xa115, 0x190c,
+	0x953f, 0x0005, 0x080c, 0x86a4, 0x0804, 0x71e5, 0x0066, 0x6000,
+	0xa0b2, 0x0010, 0x1a0c, 0x151a, 0x0013, 0x006e, 0x0005, 0xa227,
+	0xa702, 0xa828, 0xa227, 0xa227, 0xa227, 0xa227, 0xa227, 0xa25f,
+	0xa8ac, 0xa227, 0xa227, 0xa227, 0xa227, 0xa227, 0xa227, 0x080c,
+	0x151a, 0x0066, 0x6000, 0xa0b2, 0x0010, 0x1a0c, 0x151a, 0x0013,
+	0x006e, 0x0005, 0xa242, 0xad33, 0xa242, 0xa242, 0xa242, 0xa242,
+	0xa242, 0xa242, 0xacf5, 0xad7b, 0xa242, 0xb328, 0xb358, 0xb328,
+	0xb358, 0xa242, 0x080c, 0x151a, 0x0066, 0x6000, 0xa0b2, 0x0010,
+	0x1a0c, 0x151a, 0x0013, 0x006e, 0x0005, 0xa25d, 0xa9fc, 0xaac9,
+	0xaaf6, 0xab7a, 0xa25d, 0xac67, 0xac12, 0xa8b8, 0xaccb, 0xace0,
+	0xa25d, 0xa25d, 0xa25d, 0xa25d, 0xa25d, 0x080c, 0x151a, 0xa1b2,
+	0x0080, 0x1a0c, 0x151a, 0x2100, 0xa1b2, 0x0040, 0x1a04, 0xa676,
+	0x0002, 0xa2a9, 0xa474, 0xa2a9, 0xa2a9, 0xa2a9, 0xa47b, 0xa2a9,
+	0xa2a9, 0xa2a9, 0xa2a9, 0xa2a9, 0xa2a9, 0xa2a9, 0xa2a9, 0xa2a9,
+	0xa2a9, 0xa2a9, 0xa2a9, 0xa2a9, 0xa2a9, 0xa2a9, 0xa2a9, 0xa2a9,
+	0xa2ab, 0xa309, 0xa318, 0xa366, 0xa384, 0xa402, 0xa461, 0xa2a9,
+	0xa2a9, 0xa47e, 0xa2a9, 0xa2a9, 0xa491, 0xa49c, 0xa2a9, 0xa2a9,
+	0xa2a9, 0xa2a9, 0xa2a9, 0xa527, 0xa2a9, 0xa2a9, 0xa53a, 0xa2a9,
+	0xa2a9, 0xa4f2, 0xa2a9, 0xa2a9, 0xa2a9, 0xa552, 0xa2a9, 0xa2a9,
+	0xa2a9, 0xa5cc, 0xa2a9, 0xa2a9, 0xa2a9, 0xa2a9, 0xa2a9, 0xa2a9,
+	0xa63d, 0x080c, 0x151a, 0x080c, 0x537b, 0x1150, 0x2001, 0xb635,
+	0x2004, 0xd0cc, 0x1128, 0xa084, 0x0009, 0xa086, 0x0008, 0x1140,
+	0x6007, 0x0009, 0x602b, 0x0009, 0x6013, 0x0000, 0x0804, 0xa46f,
+	0x080c, 0x536b, 0x00e6, 0x00c6, 0x0036, 0x0026, 0x0016, 0x6218,
+	0x2270, 0x72a0, 0x0026, 0x2019, 0x0029, 0x080c, 0x6e67, 0x0076,
+	0x2039, 0x0000, 0x080c, 0x6d74, 0x2c08, 0x080c, 0xaf3e, 0x007e,
+	0x001e, 0x2e60, 0x080c, 0x521c, 0x001e, 0x002e, 0x003e, 0x00ce,
+	0x00ee, 0x6618, 0x00c6, 0x2660, 0x080c, 0x502a, 0x00ce, 0xa6b0,
+	0x0001, 0x2634, 0xa684, 0x00ff, 0xa082, 0x0006, 0x0278, 0x080c,
+	0xae82, 0x1904, 0xa360, 0x080c, 0xae22, 0x1120, 0x6007, 0x0008,
+	0x0804, 0xa46f, 0x6007, 0x0009, 0x0804, 0xa46f, 0x080c, 0xb037,
+	0x0128, 0x080c, 0xae82, 0x0d78, 0x0804, 0xa360, 0x6013, 0x1900,
+	0x0c88, 0x080c, 0x2df4, 0x1904, 0xa673, 0x6106, 0x080c, 0xaddc,
+	0x6007, 0x0006, 0x0804, 0xa46f, 0x6007, 0x0007, 0x0804, 0xa46f,
+	0x080c, 0xb38c, 0x1904, 0xa673, 0x080c, 0x2df4, 0x1904, 0xa673,
+	0x00d6, 0x6618, 0x2668, 0x6e04, 0xa684, 0x00ff, 0xa082, 0x0006,
+	0x1220, 0x2001, 0x0001, 0x080c, 0x4f5d, 0xa6b4, 0xff00, 0x8637,
+	0xa686, 0x0006, 0x0188, 0xa686, 0x0004, 0x0170, 0x6e04, 0xa6b4,
+	0x00ff, 0xa686, 0x0006, 0x0140, 0xa686, 0x0004, 0x0128, 0xa686,
+	0x0005, 0x0110, 0x00de, 0x00e0, 0x080c, 0xaee0, 0x11a0, 0xa686,
+	0x0006, 0x1150, 0x0026, 0x6218, 0xa290, 0x0028, 0x2214, 0x2009,
+	0x0000, 0x080c, 0x2d16, 0x002e, 0x080c, 0x50bd, 0x6007, 0x000a,
+	0x00de, 0x0804, 0xa46f, 0x6007, 0x000b, 0x00de, 0x0804, 0xa46f,
+	0x080c, 0x2cd1, 0x6007, 0x0001, 0x0804, 0xa46f, 0x080c, 0xb38c,
+	0x1904, 0xa673, 0x080c, 0x2df4, 0x1904, 0xa673, 0x6618, 0x00d6,
+	0x2668, 0x6e04, 0x00de, 0xa686, 0x0707, 0x0d50, 0x0026, 0x6218,
+	0xa290, 0x0028, 0x2214, 0x2009, 0x0000, 0x080c, 0x2d16, 0x002e,
+	0x6007, 0x000c, 0x0804, 0xa46f, 0x080c, 0x537b, 0x1140, 0x2001,
+	0xb635, 0x2004, 0xa084, 0x0009, 0xa086, 0x0008, 0x1110, 0x0804,
+	0xa2b8, 0x080c, 0x536b, 0x6618, 0xa6b0, 0x0001, 0x2634, 0xa684,
+	0x00ff, 0xa082, 0x0006, 0x06e8, 0x1138, 0x0026, 0x2001, 0x0006,
+	0x080c, 0x4f9c, 0x002e, 0x0050, 0xa6b4, 0xff00, 0x8637, 0xa686,
+	0x0004, 0x0120, 0xa686, 0x0006, 0x1904, 0xa360, 0x080c, 0xaeed,
+	0x1120, 0x6007, 0x000e, 0x0804, 0xa46f, 0x0046, 0x6418, 0xa4a0,
+	0x0028, 0x2424, 0xa4a4, 0x00ff, 0x8427, 0x0046, 0x080c, 0x2cd1,
+	0x004e, 0x0016, 0xa006, 0x2009, 0xb653, 0x210c, 0xd1a4, 0x0158,
+	0x2009, 0x0029, 0x080c, 0xb1a4, 0x6018, 0x00d6, 0x2068, 0x6800,
+	0xc0e5, 0x6802, 0x00de, 0x001e, 0x004e, 0x6007, 0x0001, 0x0804,
+	0xa46f, 0x2001, 0x0001, 0x080c, 0x4f5d, 0x0156, 0x0016, 0x0026,
+	0x0036, 0x20a9, 0x0004, 0x2019, 0xb605, 0x2011, 0xbc90, 0x080c,
+	0x9166, 0x003e, 0x002e, 0x001e, 0x015e, 0xa005, 0x0168, 0xa6b4,
+	0xff00, 0x8637, 0xa682, 0x0004, 0x0a04, 0xa360, 0xa682, 0x0007,
+	0x0a04, 0xa3ae, 0x0804, 0xa360, 0x6013, 0x1900, 0x6007, 0x0009,
+	0x0804, 0xa46f, 0x080c, 0x537b, 0x1140, 0x2001, 0xb635, 0x2004,
+	0xa084, 0x0009, 0xa086, 0x0008, 0x1110, 0x0804, 0xa2b8, 0x080c,
+	0x536b, 0x6618, 0xa6b0, 0x0001, 0x2634, 0xa684, 0x00ff, 0xa082,
+	0x0006, 0x06b8, 0xa6b4, 0xff00, 0x8637, 0xa686, 0x0004, 0x0120,
+	0xa686, 0x0006, 0x1904, 0xa360, 0x080c, 0xaf15, 0x1138, 0x080c,
+	0xae22, 0x1120, 0x6007, 0x0010, 0x0804, 0xa46f, 0x0046, 0x6418,
+	0xa4a0, 0x0028, 0x2424, 0xa4a4, 0x00ff, 0x8427, 0x0046, 0x080c,
+	0x2cd1, 0x004e, 0x0016, 0xa006, 0x2009, 0xb653, 0x210c, 0xd1a4,
+	0x0158, 0x2009, 0x0029, 0x080c, 0xb1a4, 0x6018, 0x00d6, 0x2068,
+	0x6800, 0xc0e5, 0x6802, 0x00de, 0x001e, 0x004e, 0x6007, 0x0001,
+	0x00f0, 0x080c, 0xb037, 0x0140, 0xa6b4, 0xff00, 0x8637, 0xa686,
+	0x0006, 0x0950, 0x0804, 0xa360, 0x6013, 0x1900, 0x6007, 0x0009,
+	0x0070, 0x080c, 0x2df4, 0x1904, 0xa673, 0x080c, 0xb38c, 0x1904,
+	0xa673, 0x080c, 0xa69b, 0x1904, 0xa360, 0x6007, 0x0012, 0x6003,
+	0x0001, 0x080c, 0x6d45, 0x0005, 0x6007, 0x0001, 0x6003, 0x0001,
+	0x080c, 0x6d45, 0x0cc0, 0x6007, 0x0005, 0x0cc0, 0x080c, 0xb38c,
+	0x1904, 0xa673, 0x080c, 0x2df4, 0x1904, 0xa673, 0x080c, 0xa69b,
+	0x1904, 0xa360, 0x6007, 0x0020, 0x6003, 0x0001, 0x080c, 0x6d45,
+	0x0005, 0x080c, 0x2df4, 0x1904, 0xa673, 0x6007, 0x0023, 0x6003,
+	0x0001, 0x080c, 0x6d45, 0x0005, 0x080c, 0xb38c, 0x1904, 0xa673,
+	0x080c, 0x2df4, 0x1904, 0xa673, 0x080c, 0xa69b, 0x1904, 0xa360,
+	0x0016, 0x0026, 0x2011, 0xbc91, 0x2214, 0xa286, 0xffff, 0x0190,
+	0x2c08, 0x080c, 0x9d06, 0x01e0, 0x2260, 0x2011, 0xbc90, 0x2214,
+	0x6008, 0xa206, 0x11a8, 0x6018, 0xa190, 0x0006, 0x2214, 0xa206,
+	0x01e8, 0x0070, 0x2011, 0xbc90, 0x2214, 0x2c08, 0xa006, 0x080c,
+	0xb176, 0x11a0, 0x2011, 0xbc91, 0x2214, 0xa286, 0xffff, 0x01c0,
+	0x2160, 0x6007, 0x0026, 0x6013, 0x1700, 0x2011, 0xbc89, 0x2214,
+	0xa296, 0xffff, 0x1180, 0x6007, 0x0025, 0x0068, 0x601c, 0xa086,
+	0x0007, 0x1d70, 0x6004, 0xa086, 0x0024, 0x1110, 0x080c, 0x86a4,
+	0x2160, 0x6007, 0x0025, 0x6003, 0x0001, 0x080c, 0x6d45, 0x002e,
+	0x001e, 0x0005, 0x2001, 0x0001, 0x080c, 0x4f5d, 0x0156, 0x0016,
+	0x0026, 0x0036, 0x20a9, 0x0004, 0x2019, 0xb605, 0x2011, 0xbc96,
+	0x080c, 0x9166, 0x003e, 0x002e, 0x001e, 0x015e, 0x0120, 0x6007,
+	0x0031, 0x0804, 0xa46f, 0x080c, 0x8e82, 0x080c, 0x5b41, 0x11b0,
+	0x0006, 0x0026, 0x0036, 0x080c, 0x5b5d, 0x1158, 0x2001, 0xb89f,
+	0x2003, 0x0001, 0x2001, 0xb600, 0x2003, 0x0001, 0x080c, 0x5a79,
+	0x0010, 0x080c, 0x5b18, 0x003e, 0x002e, 0x000e, 0x0005, 0x080c,
+	0x2df4, 0x1904, 0xa673, 0x080c, 0xa69b, 0x1904, 0xa360, 0x6106,
+	0x080c, 0xa6b7, 0x6007, 0x002b, 0x0804, 0xa46f, 0x6007, 0x002c,
+	0x0804, 0xa46f, 0x080c, 0xb38c, 0x1904, 0xa673, 0x080c, 0x2df4,
+	0x1904, 0xa673, 0x080c, 0xa69b, 0x1904, 0xa360, 0x6106, 0x080c,
+	0xa6bb, 0x1120, 0x6007, 0x002e, 0x0804, 0xa46f, 0x6007, 0x002f,
+	0x0804, 0xa46f, 0x080c, 0x2df4, 0x1904, 0xa673, 0x00e6, 0x00d6,
+	0x00c6, 0x6018, 0xa080, 0x0001, 0x200c, 0xa184, 0x00ff, 0xa086,
+	0x0006, 0x0158, 0xa184, 0xff00, 0x8007, 0xa086, 0x0006, 0x0128,
+	0x00ce, 0x00de, 0x00ee, 0x0804, 0xa474, 0x2001, 0xb672, 0x2004,
+	0xd0e4, 0x0904, 0xa5c9, 0x2071, 0xbc8c, 0x7010, 0x6036, 0x7014,
+	0x603a, 0x7108, 0x720c, 0x2001, 0xb653, 0x2004, 0xd0a4, 0x0140,
+	0x6018, 0x2068, 0x6810, 0xa106, 0x1118, 0x6814, 0xa206, 0x01f8,
+	0x2001, 0xb653, 0x2004, 0xd0ac, 0x1590, 0x2069, 0xb600, 0x6874,
+	0xa206, 0x1568, 0x6870, 0xa106, 0x1550, 0x7210, 0x080c, 0x9d06,
+	0x0558, 0x080c, 0xb210, 0x0540, 0x622a, 0x6007, 0x0036, 0x6003,
+	0x0001, 0x080c, 0x6cff, 0x00ce, 0x00de, 0x00ee, 0x0005, 0x7214,
+	0xa286, 0xffff, 0x0150, 0x080c, 0x9d06, 0x01b0, 0xa280, 0x0002,
+	0x2004, 0x7110, 0xa106, 0x1180, 0x0c08, 0x7210, 0x2c08, 0xa085,
+	0x0001, 0x080c, 0xb176, 0x2c10, 0x2160, 0x0130, 0x08b8, 0x6007,
+	0x0037, 0x6013, 0x1500, 0x08d8, 0x6007, 0x0037, 0x6013, 0x1700,
+	0x08b0, 0x6007, 0x0012, 0x0898, 0x080c, 0x2df4, 0x1904, 0xa673,
+	0x6018, 0xa080, 0x0001, 0x2004, 0xa084, 0xff00, 0x8007, 0xa086,
+	0x0006, 0x1904, 0xa474, 0x00e6, 0x00d6, 0x00c6, 0x2001, 0xb672,
+	0x2004, 0xd0e4, 0x0904, 0xa635, 0x2069, 0xb600, 0x2071, 0xbc8c,
+	0x7008, 0x6036, 0x720c, 0x623a, 0xa286, 0xffff, 0x1150, 0x7208,
+	0x00c6, 0x2c08, 0xa085, 0x0001, 0x080c, 0xb176, 0x2c10, 0x00ce,
+	0x0588, 0x080c, 0x9d06, 0x0570, 0x00c6, 0x0026, 0x2260, 0x080c,
+	0x99d9, 0x002e, 0x00ce, 0x7118, 0xa18c, 0xff00, 0x810f, 0xa186,
+	0x0001, 0x0158, 0xa186, 0x0005, 0x0118, 0xa186, 0x0007, 0x1178,
+	0xa280, 0x0004, 0x2004, 0xa005, 0x0150, 0x0056, 0x7510, 0x7614,
+	0x080c, 0xb227, 0x005e, 0x00ce, 0x00de, 0x00ee, 0x0005, 0x6007,
+	0x003b, 0x602b, 0x0009, 0x6013, 0x2a00, 0x6003, 0x0001, 0x080c,
+	0x6cff, 0x0c88, 0x6007, 0x003b, 0x602b, 0x0009, 0x6013, 0x1700,
+	0x6003, 0x0001, 0x080c, 0x6cff, 0x0c30, 0x6007, 0x003b, 0x602b,
+	0x000b, 0x6013, 0x0000, 0x0804, 0xa59f, 0x00e6, 0x0026, 0x080c,
+	0x537b, 0x0558, 0x080c, 0x536b, 0x080c, 0xb407, 0x1520, 0x2071,
+	0xb600, 0x70d4, 0xc085, 0x70d6, 0x00f6, 0x2079, 0x0100, 0x72a0,
+	0xa284, 0x00ff, 0x7072, 0x78e6, 0xa284, 0xff00, 0x7274, 0xa205,
+	0x7076, 0x78ea, 0x00fe, 0x70df, 0x0000, 0x2001, 0xb653, 0x2004,
+	0xd0a4, 0x0120, 0x2011, 0xb8fa, 0x2013, 0x07d0, 0xd0ac, 0x1128,
+	0x080c, 0x2aed, 0x0010, 0x080c, 0xb433, 0x002e, 0x00ee, 0x080c,
+	0x86a4, 0x0804, 0xa473, 0x080c, 0x86a4, 0x0005, 0x2600, 0x0002,
+	0xa681, 0xa681, 0xa681, 0xa681, 0xa681, 0xa683, 0xa681, 0xa681,
+	0xa681, 0x080c, 0x151a, 0x080c, 0xb38c, 0x1d68, 0x080c, 0x2df4,
+	0x1d50, 0x0089, 0x1138, 0x6007, 0x0045, 0x6003, 0x0001, 0x080c,
+	0x6d45, 0x0005, 0x080c, 0x2cd1, 0x6007, 0x0001, 0x6003, 0x0001,
+	0x080c, 0x6d45, 0x0005, 0x00d6, 0x0066, 0x6618, 0x2668, 0x6e04,
+	0xa6b4, 0xff00, 0x8637, 0xa686, 0x0006, 0x0170, 0xa686, 0x0004,
+	0x0158, 0x6e04, 0xa6b4, 0x00ff, 0xa686, 0x0006, 0x0128, 0xa686,
+	0x0004, 0x0110, 0xa085, 0x0001, 0x006e, 0x00de, 0x0005, 0x00d6,
+	0x0449, 0x00de, 0x0005, 0x00d6, 0x0491, 0x11f0, 0x680c, 0xa08c,
+	0xff00, 0x6820, 0xa084, 0x00ff, 0xa115, 0x6212, 0x6824, 0x602a,
+	0xd1e4, 0x0118, 0x2009, 0x0001, 0x0060, 0xd1ec, 0x0168, 0x6920,
+	0xa18c, 0x00ff, 0x6824, 0x080c, 0x2852, 0x1130, 0x2110, 0x2009,
+	0x0000, 0x080c, 0x2d16, 0x0018, 0xa085, 0x0001, 0x0008, 0xa006,
+	0x00de, 0x0005, 0x2069, 0xbc8d, 0x6800, 0xa082, 0x0010, 0x1228,
+	0x6013, 0x0000, 0xa085, 0x0001, 0x0008, 0xa006, 0x0005, 0x6013,
+	0x0000, 0x2069, 0xbc8c, 0x6808, 0xa084, 0xff00, 0xa086, 0x0800,
+	0x1140, 0x6800, 0xa084, 0x00ff, 0xa08e, 0x0014, 0x0110, 0xa08e,
+	0x0010, 0x0005, 0x6004, 0xa0b2, 0x0080, 0x1a0c, 0x151a, 0xa1b6,
+	0x0013, 0x1130, 0x2008, 0xa1b2, 0x0040, 0x1a04, 0xa802, 0x0092,
+	0xa1b6, 0x0027, 0x0120, 0xa1b6, 0x0014, 0x190c, 0x151a, 0x2001,
+	0x0007, 0x080c, 0x4f9c, 0x080c, 0x7102, 0x080c, 0x9ed9, 0x080c,
+	0x71e5, 0x0005, 0xa762, 0xa764, 0xa762, 0xa762, 0xa762, 0xa764,
+	0xa776, 0xa7fb, 0xa7c6, 0xa7fb, 0xa7d7, 0xa7fb, 0xa776, 0xa7fb,
+	0xa7f3, 0xa7fb, 0xa7f3, 0xa7fb, 0xa7fb, 0xa762, 0xa762, 0xa762,
+	0xa762, 0xa762, 0xa762, 0xa762, 0xa762, 0xa762, 0xa762, 0xa762,
+	0xa764, 0xa762, 0xa7fb, 0xa762, 0xa762, 0xa7fb, 0xa762, 0xa7f8,
+	0xa7fb, 0xa762, 0xa762, 0xa762, 0xa762, 0xa7fb, 0xa7fb, 0xa762,
+	0xa7fb, 0xa7fb, 0xa762, 0xa770, 0xa762, 0xa762, 0xa762, 0xa762,
+	0xa7f7, 0xa7fb, 0xa762, 0xa762, 0xa7fb, 0xa7fb, 0xa762, 0xa762,
+	0xa762, 0xa762, 0x080c, 0x151a, 0x080c, 0x7102, 0x2001, 0xb8b6,
+	0x2004, 0x6016, 0x6003, 0x0002, 0x080c, 0x71e5, 0x0804, 0xa801,
+	0x2001, 0x0000, 0x080c, 0x4f5d, 0x0804, 0xa7fb, 0x00f6, 0x2079,
+	0xb652, 0x7804, 0x00fe, 0xd0ac, 0x1904, 0xa7fb, 0x2001, 0x0000,
+	0x080c, 0x4f5d, 0x6018, 0xa080, 0x0004, 0x2004, 0xa086, 0x00ff,
+	0x1140, 0x00f6, 0x2079, 0xb600, 0x7898, 0x8000, 0x789a, 0x00fe,
+	0x00e0, 0x00c6, 0x6018, 0x2060, 0x6000, 0xd0f4, 0x1140, 0x6010,
+	0xa005, 0x0128, 0x00ce, 0x080c, 0x3f85, 0x0804, 0xa7fb, 0x00ce,
+	0x2001, 0xb600, 0x2004, 0xa086, 0x0002, 0x1138, 0x00f6, 0x2079,
+	0xb600, 0x7898, 0x8000, 0x789a, 0x00fe, 0x2001, 0x0002, 0x080c,
+	0x4f6f, 0x080c, 0x7102, 0x601f, 0x0001, 0x6003, 0x0001, 0x6007,
+	0x0002, 0x080c, 0x6d45, 0x080c, 0x71e5, 0x00c6, 0x6118, 0x2160,
+	0x2009, 0x0001, 0x080c, 0x6a1a, 0x00ce, 0x04d8, 0x6618, 0x00d6,
 	0x2668, 0x6e04, 0x00de, 0xa6b4, 0xff00, 0x8637, 0xa686, 0x0006,
-	0x0170, 0x2001, 0x0006, 0x0048, 0x2001, 0x0004, 0x0030, 0x2001,
-	0x0006, 0x0401, 0x0020, 0x0018, 0x0010, 0x080c, 0x4f2a, 0x080c,
-	0x7090, 0x080c, 0x861d, 0x080c, 0x7173, 0x0005, 0x2600, 0x0002,
-	0xa751, 0xa751, 0xa751, 0xa751, 0xa751, 0xa753, 0xa751, 0xa751,
-	0xa751, 0x080c, 0x1515, 0x080c, 0x7090, 0x080c, 0x861d, 0x080c,
-	0x7173, 0x0005, 0x0016, 0x00d6, 0x6118, 0x2168, 0x6900, 0xd184,
-	0x0140, 0x080c, 0x4efd, 0x2001, 0x0000, 0x080c, 0x4eeb, 0x080c,
-	0x2cc2, 0x00de, 0x001e, 0x0005, 0x00d6, 0x6618, 0x2668, 0x6804,
-	0xa084, 0xff00, 0x8007, 0x00de, 0xa0b2, 0x000c, 0x1a0c, 0x1515,
-	0xa1b6, 0x0015, 0x1110, 0x003b, 0x0028, 0xa1b6, 0x0016, 0x190c,
-	0x1515, 0x006b, 0x0005, 0x8cdf, 0x8cdf, 0x8cdf, 0x8cdf, 0x8cdf,
-	0x8cdf, 0xa7dc, 0xa79b, 0x8cdf, 0x8cdf, 0x8cdf, 0x8cdf, 0x8cdf,
-	0x8cdf, 0x8cdf, 0x8cdf, 0x8cdf, 0x8cdf, 0xa7dc, 0xa7e3, 0x8cdf,
-	0x8cdf, 0x8cdf, 0x8cdf, 0x00f6, 0x2079, 0xb552, 0x7804, 0xd0ac,
-	0x11e0, 0x6018, 0xa07d, 0x01c8, 0x7800, 0xd0f4, 0x1118, 0x7810,
-	0xa005, 0x1198, 0x2001, 0x0000, 0x080c, 0x4eeb, 0x2001, 0x0002,
-	0x080c, 0x4efd, 0x601f, 0x0001, 0x6003, 0x0001, 0x6007, 0x0002,
-	0x080c, 0x6cd3, 0x080c, 0x7173, 0x00e8, 0x2011, 0xbb83, 0x2204,
-	0x8211, 0x220c, 0x080c, 0x281d, 0x11a8, 0x00c6, 0x080c, 0x4fa9,
-	0x0120, 0x00ce, 0x080c, 0x861d, 0x0068, 0x6010, 0x0006, 0x6014,
-	0x0006, 0x080c, 0x4c0b, 0x000e, 0x6016, 0x000e, 0x6012, 0x00ce,
-	0x080c, 0x861d, 0x00fe, 0x0005, 0x6604, 0xa6b6, 0x001e, 0x1110,
-	0x080c, 0x861d, 0x0005, 0x080c, 0x8f95, 0x1138, 0x6003, 0x0001,
-	0x6007, 0x0001, 0x080c, 0x6cd3, 0x0010, 0x080c, 0x861d, 0x0005,
-	0x6004, 0xa08a, 0x0080, 0x1a0c, 0x1515, 0x080c, 0x7090, 0x080c,
-	0x9e1d, 0x080c, 0x7173, 0x0005, 0xa182, 0x0040, 0x0002, 0xa812,
-	0xa812, 0xa812, 0xa812, 0xa814, 0xa812, 0xa812, 0xa812, 0xa812,
-	0xa812, 0xa812, 0xa812, 0xa812, 0xa812, 0xa812, 0xa812, 0xa812,
-	0xa812, 0xa812, 0x080c, 0x1515, 0x00d6, 0x00e6, 0x00f6, 0x0156,
-	0x0046, 0x0026, 0x6218, 0xa280, 0x002b, 0x2004, 0xa005, 0x0120,
-	0x2021, 0x0000, 0x080c, 0xb31c, 0x6106, 0x2071, 0xbb80, 0x7444,
-	0xa4a4, 0xff00, 0x0904, 0xa878, 0xa486, 0x2000, 0x1130, 0x2009,
-	0x0001, 0x2011, 0x0200, 0x080c, 0x6b1a, 0x080c, 0x15f8, 0x090c,
-	0x1515, 0x6003, 0x0007, 0x2d00, 0x6837, 0x010d, 0x6803, 0x0000,
-	0x683b, 0x0000, 0x6c5a, 0x2c00, 0x685e, 0x6008, 0x68b2, 0x6018,
-	0x2078, 0x78a0, 0x8007, 0x7130, 0x694a, 0x0016, 0xa084, 0xff00,
-	0x6846, 0x684f, 0x0000, 0x6853, 0x0000, 0x6857, 0x0036, 0x080c,
-	0x5408, 0x001e, 0xa486, 0x2000, 0x1130, 0x2019, 0x0017, 0x080c,
-	0xb065, 0x0804, 0xa8d5, 0xa486, 0x0400, 0x1130, 0x2019, 0x0002,
-	0x080c, 0xb017, 0x0804, 0xa8d5, 0xa486, 0x0200, 0x1110, 0x080c,
-	0xaffc, 0xa486, 0x1000, 0x1110, 0x080c, 0xb04a, 0x0804, 0xa8d5,
-	0x2069, 0xb874, 0x6a00, 0xd284, 0x0904, 0xa93c, 0xa284, 0x0300,
-	0x1904, 0xa935, 0x6804, 0xa005, 0x0904, 0xa91d, 0x2d78, 0x6003,
-	0x0007, 0x080c, 0x15df, 0x0904, 0xa8dc, 0x7800, 0xd08c, 0x1118,
-	0x7804, 0x8001, 0x7806, 0x6013, 0x0000, 0x6803, 0x0000, 0x6837,
-	0x0116, 0x683b, 0x0000, 0x6008, 0x68b2, 0x2c00, 0x684a, 0x6018,
-	0x2078, 0x78a0, 0x8007, 0x7130, 0x6986, 0x6846, 0x7928, 0x698a,
-	0x792c, 0x698e, 0x7930, 0x6992, 0x7934, 0x6996, 0x6853, 0x003d,
-	0x7244, 0xa294, 0x0003, 0xa286, 0x0002, 0x1118, 0x684f, 0x0040,
-	0x0040, 0xa286, 0x0001, 0x1118, 0x684f, 0x0080, 0x0010, 0x684f,
-	0x0000, 0x20a9, 0x000a, 0x2001, 0xbb90, 0xad90, 0x0015, 0x200c,
-	0x810f, 0x2112, 0x8000, 0x8210, 0x1f04, 0xa8c7, 0x200c, 0x6982,
-	0x8000, 0x200c, 0x697e, 0x080c, 0x5408, 0x002e, 0x004e, 0x015e,
-	0x00fe, 0x00ee, 0x00de, 0x0005, 0x2001, 0xb50e, 0x2004, 0xd084,
-	0x0120, 0x080c, 0x15f8, 0x1904, 0xa88d, 0x6013, 0x0100, 0x6003,
-	0x0001, 0x6007, 0x0041, 0x080c, 0x6c8d, 0x080c, 0x7173, 0x0c28,
-	0x2069, 0xbb92, 0x2d04, 0xa084, 0xff00, 0xa086, 0x1200, 0x11a8,
-	0x2069, 0xbb80, 0x686c, 0xa084, 0x00ff, 0x0016, 0x6110, 0xa18c,
-	0x0700, 0xa10d, 0x6112, 0x001e, 0x6003, 0x0001, 0x6007, 0x0043,
-	0x080c, 0x6c8d, 0x080c, 0x7173, 0x0840, 0x6868, 0x602a, 0x686c,
-	0x602e, 0x6013, 0x0200, 0x6003, 0x0001, 0x6007, 0x0041, 0x080c,
-	0x6c8d, 0x080c, 0x7173, 0x0804, 0xa8d5, 0x2001, 0xb50d, 0x2004,
-	0xd0ec, 0x0120, 0x2011, 0x8049, 0x080c, 0x3ecc, 0x6013, 0x0300,
-	0x0010, 0x6013, 0x0100, 0x6003, 0x0001, 0x6007, 0x0041, 0x080c,
-	0x6c8d, 0x080c, 0x7173, 0x0804, 0xa8d5, 0x6013, 0x0500, 0x0c98,
-	0x6013, 0x0600, 0x0804, 0xa8f0, 0x6013, 0x0200, 0x0804, 0xa8f0,
-	0xa186, 0x0013, 0x1170, 0x6004, 0xa08a, 0x0040, 0x0a0c, 0x1515,
-	0xa08a, 0x0053, 0x1a0c, 0x1515, 0xa082, 0x0040, 0x2008, 0x0804,
-	0xa9ca, 0xa186, 0x0051, 0x0138, 0xa186, 0x0047, 0x11d8, 0x6004,
-	0xa086, 0x0041, 0x0518, 0x2001, 0x0109, 0x2004, 0xd084, 0x01f0,
-	0x0126, 0x2091, 0x2800, 0x0006, 0x0016, 0x0026, 0x080c, 0x6b74,
-	0x002e, 0x001e, 0x000e, 0x012e, 0x6000, 0xa086, 0x0002, 0x1170,
-	0x0804, 0xaa0d, 0xa186, 0x0027, 0x0120, 0xa186, 0x0014, 0x190c,
-	0x1515, 0x6004, 0xa082, 0x0040, 0x2008, 0x001a, 0x080c, 0x8663,
-	0x0005, 0xa994, 0xa996, 0xa996, 0xa9ba, 0xa994, 0xa994, 0xa994,
-	0xa994, 0xa994, 0xa994, 0xa994, 0xa994, 0xa994, 0xa994, 0xa994,
-	0xa994, 0xa994, 0xa994, 0xa994, 0x080c, 0x1515, 0x080c, 0x7090,
-	0x080c, 0x7173, 0x0036, 0x00d6, 0x6010, 0xa06d, 0x01c0, 0xad84,
-	0xf000, 0x01a8, 0x6003, 0x0002, 0x6018, 0x2004, 0xd0bc, 0x1178,
-	0x2019, 0x0004, 0x080c, 0xb099, 0x6013, 0x0000, 0x6014, 0xa005,
-	0x1120, 0x2001, 0xb7b7, 0x2004, 0x6016, 0x6003, 0x0007, 0x00de,
-	0x003e, 0x0005, 0x00d6, 0x080c, 0x7090, 0x080c, 0x7173, 0x080c,
-	0x9c5a, 0x0120, 0x6010, 0x2068, 0x080c, 0x160f, 0x080c, 0x9e1d,
-	0x00de, 0x0005, 0x0002, 0xa9de, 0xa9fb, 0xa9e7, 0xaa07, 0xa9de,
-	0xa9de, 0xa9de, 0xa9de, 0xa9de, 0xa9de, 0xa9de, 0xa9de, 0xa9de,
-	0xa9de, 0xa9de, 0xa9de, 0xa9de, 0xa9de, 0xa9de, 0x080c, 0x1515,
-	0x6010, 0xa088, 0x0013, 0x2104, 0xa085, 0x0400, 0x200a, 0x080c,
-	0x7090, 0x6010, 0xa080, 0x0013, 0x2004, 0xd0b4, 0x0138, 0x6003,
-	0x0007, 0x2009, 0x0043, 0x080c, 0x864c, 0x0010, 0x6003, 0x0002,
-	0x080c, 0x7173, 0x0005, 0x080c, 0x7090, 0x080c, 0xb2d7, 0x1120,
-	0x080c, 0x6aef, 0x080c, 0x861d, 0x080c, 0x7173, 0x0005, 0x080c,
-	0x7090, 0x2009, 0x0041, 0x0804, 0xab56, 0xa182, 0x0040, 0x0002,
-	0xaa23, 0xaa25, 0xaa23, 0xaa23, 0xaa23, 0xaa23, 0xaa23, 0xaa26,
-	0xaa23, 0xaa23, 0xaa23, 0xaa23, 0xaa23, 0xaa23, 0xaa23, 0xaa23,
-	0xaa23, 0xaa31, 0xaa23, 0x080c, 0x1515, 0x0005, 0x6003, 0x0004,
-	0x6110, 0x20e1, 0x0005, 0x3d18, 0x3e20, 0x2c10, 0x080c, 0x185e,
-	0x0005, 0x00d6, 0x080c, 0x6aef, 0x00de, 0x080c, 0xb33a, 0x080c,
-	0x861d, 0x0005, 0xa182, 0x0040, 0x0002, 0xaa50, 0xaa50, 0xaa50,
-	0xaa50, 0xaa50, 0xaa50, 0xaa50, 0xaa52, 0xaa50, 0xaa55, 0xaa8e,
-	0xaa50, 0xaa50, 0xaa50, 0xaa50, 0xaa8e, 0xaa50, 0xaa50, 0xaa50,
-	0x080c, 0x1515, 0x080c, 0x8663, 0x0005, 0x2001, 0xb572, 0x2004,
-	0xd0e4, 0x0158, 0x2001, 0x0100, 0x2004, 0xa082, 0x0005, 0x0228,
-	0x2001, 0x011f, 0x2004, 0x6036, 0x0010, 0x6037, 0x0000, 0x080c,
-	0x7126, 0x080c, 0x7230, 0x6010, 0x00d6, 0x2068, 0x684c, 0xd0fc,
-	0x0150, 0xa08c, 0x0003, 0xa18e, 0x0002, 0x0168, 0x2009, 0x0041,
-	0x00de, 0x0804, 0xab56, 0x6003, 0x0007, 0x6017, 0x0000, 0x080c,
-	0x6aef, 0x00de, 0x0005, 0x080c, 0xb2d7, 0x0110, 0x00de, 0x0005,
-	0x080c, 0x6aef, 0x080c, 0x861d, 0x00de, 0x0ca0, 0x0036, 0x080c,
-	0x7126, 0x080c, 0x7230, 0x6010, 0x00d6, 0x2068, 0x6018, 0x2004,
-	0xd0bc, 0x0188, 0x684c, 0xa084, 0x0003, 0xa086, 0x0002, 0x0140,
-	0x687c, 0x632c, 0xa31a, 0x632e, 0x6880, 0x6328, 0xa31b, 0x632a,
-	0x6003, 0x0002, 0x0080, 0x2019, 0x0004, 0x080c, 0xb099, 0x6014,
-	0xa005, 0x1128, 0x2001, 0xb7b7, 0x2004, 0x8003, 0x6016, 0x6013,
-	0x0000, 0x6003, 0x0007, 0x00de, 0x003e, 0x0005, 0xa186, 0x0013,
-	0x1150, 0x6004, 0xa086, 0x0042, 0x190c, 0x1515, 0x080c, 0x7090,
-	0x080c, 0x7173, 0x0005, 0xa186, 0x0027, 0x0118, 0xa186, 0x0014,
-	0x1180, 0x6004, 0xa086, 0x0042, 0x190c, 0x1515, 0x2001, 0x0007,
-	0x080c, 0x4f2a, 0x080c, 0x7090, 0x080c, 0x9e1d, 0x080c, 0x7173,
-	0x0005, 0xa182, 0x0040, 0x0002, 0xaaf7, 0xaaf7, 0xaaf7, 0xaaf7,
-	0xaaf7, 0xaaf7, 0xaaf7, 0xaaf9, 0xab05, 0xaaf7, 0xaaf7, 0xaaf7,
-	0xaaf7, 0xaaf7, 0xaaf7, 0xaaf7, 0xaaf7, 0xaaf7, 0xaaf7, 0x080c,
-	0x1515, 0x0036, 0x0046, 0x20e1, 0x0005, 0x3d18, 0x3e20, 0x2c10,
-	0x080c, 0x185e, 0x004e, 0x003e, 0x0005, 0x6010, 0x00d6, 0x2068,
-	0x6810, 0x6a14, 0x0006, 0x0046, 0x0056, 0x6c7c, 0xa422, 0x6d80,
-	0x2200, 0xa52b, 0x602c, 0xa420, 0x642e, 0x6028, 0xa529, 0x652a,
-	0x005e, 0x004e, 0x000e, 0xa20d, 0x1178, 0x684c, 0xd0fc, 0x0120,
-	0x2009, 0x0041, 0x00de, 0x0490, 0x6003, 0x0007, 0x6017, 0x0000,
-	0x080c, 0x6aef, 0x00de, 0x0005, 0x0006, 0x00f6, 0x2c78, 0x080c,
-	0x5305, 0x00fe, 0x000e, 0x0120, 0x6003, 0x0002, 0x00de, 0x0005,
-	0x2009, 0xb50d, 0x210c, 0xd19c, 0x0118, 0x6003, 0x0007, 0x0010,
-	0x6003, 0x0006, 0x0021, 0x080c, 0x6af1, 0x00de, 0x0005, 0xd2fc,
-	0x0140, 0x8002, 0x8000, 0x8212, 0xa291, 0x0000, 0x2009, 0x0009,
-	0x0010, 0x2009, 0x0015, 0x6a6a, 0x6866, 0x0005, 0xa182, 0x0040,
-	0x0208, 0x0062, 0xa186, 0x0013, 0x0120, 0xa186, 0x0014, 0x190c,
-	0x1515, 0x6020, 0xd0dc, 0x090c, 0x1515, 0x0005, 0xab79, 0xab80,
-	0xab8c, 0xab98, 0xab79, 0xab79, 0xab79, 0xaba7, 0xab79, 0xab7b,
-	0xab7b, 0xab79, 0xab79, 0xab79, 0xab79, 0xab7b, 0xab79, 0xab7b,
-	0xab79, 0x080c, 0x1515, 0x6020, 0xd0dc, 0x090c, 0x1515, 0x0005,
-	0x6003, 0x0001, 0x6106, 0x080c, 0x6c8d, 0x0126, 0x2091, 0x8000,
-	0x080c, 0x7173, 0x012e, 0x0005, 0x6003, 0x0001, 0x6106, 0x080c,
-	0x6c8d, 0x0126, 0x2091, 0x8000, 0x080c, 0x7173, 0x012e, 0x0005,
-	0x6003, 0x0003, 0x6106, 0x2c10, 0x080c, 0x1fa9, 0x0126, 0x2091,
-	0x8000, 0x080c, 0x6cf0, 0x080c, 0x7230, 0x012e, 0x0005, 0xa016,
-	0x080c, 0x185e, 0x0005, 0x0126, 0x2091, 0x8000, 0x0036, 0x00d6,
-	0xa182, 0x0040, 0x0023, 0x00de, 0x003e, 0x012e, 0x0005, 0xabc7,
-	0xabc9, 0xabdb, 0xabf6, 0xabc7, 0xabc7, 0xabc7, 0xac0b, 0xabc7,
-	0xabc7, 0xabc7, 0xabc7, 0xabc7, 0xabc7, 0xabc7, 0xabc7, 0x080c,
-	0x1515, 0x6010, 0x2068, 0x684c, 0xd0fc, 0x01f8, 0xa09c, 0x0003,
-	0xa39e, 0x0003, 0x01d0, 0x6003, 0x0001, 0x6106, 0x080c, 0x6c8d,
-	0x080c, 0x7173, 0x0498, 0x6010, 0x2068, 0x684c, 0xd0fc, 0x0168,
-	0xa09c, 0x0003, 0xa39e, 0x0003, 0x0140, 0x6003, 0x0001, 0x6106,
-	0x080c, 0x6c8d, 0x080c, 0x7173, 0x0408, 0x6013, 0x0000, 0x6017,
-	0x0000, 0x2019, 0x0004, 0x080c, 0xb099, 0x00c0, 0x6010, 0x2068,
-	0x684c, 0xd0fc, 0x0d90, 0xa09c, 0x0003, 0xa39e, 0x0003, 0x0d68,
-	0x6003, 0x0003, 0x6106, 0x2c10, 0x080c, 0x1fa9, 0x080c, 0x6cf0,
-	0x080c, 0x7230, 0x0018, 0xa016, 0x080c, 0x185e, 0x0005, 0x080c,
-	0x7090, 0x6110, 0x81ff, 0x0158, 0x00d6, 0x2168, 0x080c, 0xb380,
-	0x0036, 0x2019, 0x0029, 0x080c, 0xb099, 0x003e, 0x00de, 0x080c,
-	0x9e1d, 0x080c, 0x7173, 0x0005, 0x080c, 0x7126, 0x6110, 0x81ff,
-	0x0158, 0x00d6, 0x2168, 0x080c, 0xb380, 0x0036, 0x2019, 0x0029,
-	0x080c, 0xb099, 0x003e, 0x00de, 0x080c, 0x9e1d, 0x080c, 0x7230,
-	0x0005, 0xa182, 0x0085, 0x0002, 0xac45, 0xac43, 0xac43, 0xac51,
-	0xac43, 0xac43, 0xac43, 0x080c, 0x1515, 0x6003, 0x000b, 0x6106,
-	0x080c, 0x6c8d, 0x0126, 0x2091, 0x8000, 0x080c, 0x7173, 0x012e,
-	0x0005, 0x0026, 0x00e6, 0x080c, 0xb2d0, 0x0118, 0x080c, 0x861d,
-	0x00d8, 0x2071, 0xbb80, 0x7224, 0x6212, 0x7220, 0x080c, 0xaf47,
-	0x0118, 0x6007, 0x0086, 0x0040, 0x6007, 0x0087, 0x7224, 0xa296,
-	0xffff, 0x1110, 0x6007, 0x0086, 0x6003, 0x0001, 0x080c, 0x6c8d,
-	0x080c, 0x7173, 0x080c, 0x7230, 0x00ee, 0x002e, 0x0005, 0xa186,
-	0x0013, 0x1160, 0x6004, 0xa08a, 0x0085, 0x0a0c, 0x1515, 0xa08a,
-	0x008c, 0x1a0c, 0x1515, 0xa082, 0x0085, 0x00a2, 0xa186, 0x0027,
-	0x0130, 0xa186, 0x0014, 0x0118, 0x080c, 0x8663, 0x0050, 0x2001,
-	0x0007, 0x080c, 0x4f2a, 0x080c, 0x7090, 0x080c, 0x9e1d, 0x080c,
-	0x7173, 0x0005, 0xaca1, 0xaca3, 0xaca3, 0xaca1, 0xaca1, 0xaca1,
-	0xaca1, 0x080c, 0x1515, 0x080c, 0x7090, 0x080c, 0x9e1d, 0x080c,
-	0x7173, 0x0005, 0xa182, 0x0085, 0x0a0c, 0x1515, 0xa182, 0x008c,
-	0x1a0c, 0x1515, 0xa182, 0x0085, 0x0002, 0xacbc, 0xacbc, 0xacbc,
-	0xacbe, 0xacbc, 0xacbc, 0xacbc, 0x080c, 0x1515, 0x0005, 0xa186,
-	0x0013, 0x0148, 0xa186, 0x0014, 0x0130, 0xa186, 0x0027, 0x0118,
-	0x080c, 0x8663, 0x0030, 0x080c, 0x7090, 0x080c, 0x9e1d, 0x080c,
-	0x7173, 0x0005, 0x0036, 0x080c, 0xb33a, 0x603f, 0x0000, 0x2019,
-	0x000b, 0x0031, 0x601f, 0x0006, 0x6003, 0x0007, 0x003e, 0x0005,
-	0x0126, 0x0036, 0x2091, 0x8000, 0x0086, 0x2c40, 0x0096, 0x2049,
-	0x0000, 0x080c, 0x8130, 0x009e, 0x008e, 0x1578, 0x0076, 0x2c38,
-	0x080c, 0x81d6, 0x007e, 0x1548, 0x6000, 0xa086, 0x0000, 0x0528,
-	0x601c, 0xa086, 0x0007, 0x0508, 0x00d6, 0x6000, 0xa086, 0x0004,
-	0x1150, 0x080c, 0xb33a, 0x601f, 0x0007, 0x2001, 0xb7b6, 0x2004,
-	0x6016, 0x080c, 0x194d, 0x6010, 0x2068, 0x080c, 0x9c5a, 0x0110,
-	0x080c, 0xb099, 0x00de, 0x6013, 0x0000, 0x080c, 0xb33a, 0x601f,
-	0x0007, 0x2001, 0xb7b6, 0x2004, 0x6016, 0x003e, 0x012e, 0x0005,
-	0x00f6, 0x00c6, 0x0036, 0x0156, 0x2079, 0xbb80, 0x7938, 0x783c,
-	0x080c, 0x281d, 0x15b0, 0x0016, 0x00c6, 0x080c, 0x4fa9, 0x1578,
-	0x001e, 0x002e, 0x0026, 0x0016, 0x2019, 0x0029, 0x080c, 0x8299,
-	0x080c, 0x6df5, 0x0076, 0x2039, 0x0000, 0x080c, 0x6d02, 0x007e,
-	0x001e, 0x0076, 0x2039, 0x0000, 0x080c, 0xae82, 0x007e, 0x080c,
-	0x51aa, 0x0026, 0x6204, 0xa294, 0xff00, 0x8217, 0xa286, 0x0006,
-	0x0118, 0xa286, 0x0004, 0x1118, 0x62a0, 0x080c, 0x2d55, 0x002e,
-	0x001e, 0x080c, 0x4c0b, 0x6612, 0x6516, 0xa006, 0x0010, 0x00ce,
-	0x001e, 0x015e, 0x003e, 0x00ce, 0x00fe, 0x0005, 0x00c6, 0x00d6,
-	0x00e6, 0x0016, 0x2009, 0xb521, 0x2104, 0xa086, 0x0074, 0x1904,
-	0xadbb, 0x2069, 0xbb8e, 0x690c, 0xa182, 0x0100, 0x06c0, 0x6908,
-	0xa184, 0x8000, 0x05e8, 0x2001, 0xb79e, 0x2004, 0xa005, 0x1160,
-	0x6018, 0x2070, 0x7010, 0xa084, 0x00ff, 0x0118, 0x7000, 0xd0f4,
-	0x0118, 0xa184, 0x0800, 0x0560, 0x6910, 0xa18a, 0x0001, 0x0610,
-	0x6914, 0x2069, 0xbbae, 0x6904, 0x81ff, 0x1198, 0x690c, 0xa182,
-	0x0100, 0x02a8, 0x6908, 0x81ff, 0x1178, 0x6910, 0xa18a, 0x0001,
-	0x0288, 0x6918, 0xa18a, 0x0001, 0x0298, 0x00d0, 0x6013, 0x0100,
-	0x00a0, 0x6013, 0x0300, 0x0088, 0x6013, 0x0500, 0x0070, 0x6013,
-	0x0700, 0x0058, 0x6013, 0x0900, 0x0040, 0x6013, 0x0b00, 0x0028,
-	0x6013, 0x0f00, 0x0010, 0x6013, 0x2d00, 0xa085, 0x0001, 0x0008,
-	0xa006, 0x001e, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x00c6, 0x00d6,
-	0x0026, 0x0036, 0x0156, 0x6218, 0x2268, 0x6b04, 0xa394, 0x00ff,
-	0xa286, 0x0006, 0x0190, 0xa286, 0x0004, 0x0178, 0xa394, 0xff00,
-	0x8217, 0xa286, 0x0006, 0x0148, 0xa286, 0x0004, 0x0130, 0x00c6,
-	0x2d60, 0x080c, 0x4fb8, 0x00ce, 0x04c0, 0x2011, 0xbb96, 0xad98,
-	0x000a, 0x20a9, 0x0004, 0x080c, 0x90da, 0x1580, 0x2011, 0xbb9a,
-	0xad98, 0x0006, 0x20a9, 0x0004, 0x080c, 0x90da, 0x1538, 0x0046,
-	0x0016, 0x6aa0, 0xa294, 0x00ff, 0x8227, 0xa006, 0x2009, 0xb553,
-	0x210c, 0xd1a4, 0x0138, 0x2009, 0x0029, 0x080c, 0xb0e8, 0x6800,
-	0xc0e5, 0x6802, 0x2019, 0x0029, 0x080c, 0x6df5, 0x0076, 0x2039,
-	0x0000, 0x080c, 0x6d02, 0x2c08, 0x080c, 0xae82, 0x007e, 0x2001,
-	0x0007, 0x080c, 0x4f2a, 0x001e, 0x004e, 0xa006, 0x015e, 0x003e,
-	0x002e, 0x00de, 0x00ce, 0x0005, 0x00d6, 0x2069, 0xbb8e, 0x6800,
-	0xa086, 0x0800, 0x0118, 0x6013, 0x0000, 0x0008, 0xa006, 0x00de,
-	0x0005, 0x00c6, 0x00f6, 0x0016, 0x0026, 0x0036, 0x0156, 0x2079,
-	0xbb8c, 0x7930, 0x7834, 0x080c, 0x281d, 0x11a0, 0x080c, 0x4fa9,
-	0x1188, 0x2011, 0xbb90, 0xac98, 0x000a, 0x20a9, 0x0004, 0x080c,
-	0x90da, 0x1140, 0x2011, 0xbb94, 0xac98, 0x0006, 0x20a9, 0x0004,
-	0x080c, 0x90da, 0x015e, 0x003e, 0x002e, 0x001e, 0x00fe, 0x00ce,
-	0x0005, 0x00c6, 0x0006, 0x0016, 0x0026, 0x0036, 0x0156, 0x2011,
-	0xbb83, 0x2204, 0x8211, 0x220c, 0x080c, 0x281d, 0x11a0, 0x080c,
-	0x4fa9, 0x1188, 0x2011, 0xbb96, 0xac98, 0x000a, 0x20a9, 0x0004,
-	0x080c, 0x90da, 0x1140, 0x2011, 0xbb9a, 0xac98, 0x0006, 0x20a9,
-	0x0004, 0x080c, 0x90da, 0x015e, 0x003e, 0x002e, 0x001e, 0x000e,
-	0x00ce, 0x0005, 0x00e6, 0x00c6, 0x0086, 0x0076, 0x0066, 0x0056,
-	0x0046, 0x0026, 0x0126, 0x2091, 0x8000, 0x2740, 0x2029, 0xb7e9,
-	0x252c, 0x2021, 0xb7ef, 0x2424, 0x2061, 0xbd00, 0x2071, 0xb500,
-	0x7648, 0x7068, 0x81ff, 0x0150, 0x0006, 0xa186, 0xb8f4, 0x000e,
-	0x0128, 0x8001, 0xa602, 0x1a04, 0xaf03, 0x0018, 0xa606, 0x0904,
-	0xaf03, 0x2100, 0xac06, 0x0904, 0xaefa, 0x080c, 0xb110, 0x0904,
-	0xaefa, 0x671c, 0xa786, 0x0001, 0x0904, 0xaf1e, 0xa786, 0x0004,
-	0x0904, 0xaf1e, 0xa786, 0x0007, 0x05e8, 0x2500, 0xac06, 0x05d0,
-	0x2400, 0xac06, 0x05b8, 0x080c, 0xb120, 0x15a0, 0x88ff, 0x0118,
-	0x6050, 0xa906, 0x1578, 0x00d6, 0x6000, 0xa086, 0x0004, 0x1120,
-	0x0016, 0x080c, 0x194d, 0x001e, 0xa786, 0x0008, 0x1148, 0x080c,
-	0x9e58, 0x1130, 0x080c, 0x8c19, 0x00de, 0x080c, 0x9e1d, 0x00d0,
-	0x6010, 0x2068, 0x080c, 0x9c5a, 0x0190, 0xa786, 0x0003, 0x1528,
-	0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x080c, 0xb380, 0x0016,
-	0x080c, 0x9ecc, 0x080c, 0x5408, 0x001e, 0x080c, 0x9e11, 0x00de,
-	0x080c, 0x9e1d, 0xace0, 0x0018, 0x2001, 0xb517, 0x2004, 0xac02,
-	0x1210, 0x0804, 0xae96, 0x012e, 0x002e, 0x004e, 0x005e, 0x006e,
-	0x007e, 0x008e, 0x00ce, 0x00ee, 0x0005, 0xa786, 0x0006, 0x1150,
-	0xa386, 0x0005, 0x0128, 0x080c, 0xb380, 0x080c, 0xb099, 0x08f8,
-	0x00de, 0x0c00, 0xa786, 0x000a, 0x0968, 0x0850, 0x080c, 0xb120,
-	0x19c8, 0x81ff, 0x09b8, 0xa180, 0x0001, 0x2004, 0xa086, 0x0018,
-	0x0130, 0xa180, 0x0001, 0x2004, 0xa086, 0x002d, 0x1958, 0x6000,
-	0xa086, 0x0002, 0x1938, 0x080c, 0x9e47, 0x0130, 0x080c, 0x9e58,
-	0x1908, 0x080c, 0x8c19, 0x0038, 0x080c, 0x2cc2, 0x080c, 0x9e58,
-	0x1110, 0x080c, 0x8c19, 0x080c, 0x9e1d, 0x0804, 0xaefa, 0x00c6,
-	0x00e6, 0x0016, 0x2c08, 0x2170, 0xa006, 0x080c, 0xb0ba, 0x001e,
-	0x0120, 0x601c, 0xa084, 0x000f, 0x001b, 0x00ee, 0x00ce, 0x0005,
-	0xaf60, 0xaf60, 0xaf60, 0xaf60, 0xaf60, 0xaf60, 0xaf62, 0xaf60,
-	0xa006, 0x0005, 0x0046, 0x0016, 0x7018, 0xa080, 0x0028, 0x2024,
-	0xa4a4, 0x00ff, 0x8427, 0x2c00, 0x2009, 0x0020, 0x080c, 0xb0e8,
-	0x001e, 0x004e, 0x0036, 0x2019, 0x0002, 0x080c, 0xace0, 0x003e,
-	0xa085, 0x0001, 0x0005, 0x2001, 0x0001, 0x080c, 0x4eeb, 0x0156,
-	0x0016, 0x0026, 0x0036, 0x20a9, 0x0004, 0x2019, 0xb505, 0x2011,
-	0xbb96, 0x080c, 0x90da, 0x003e, 0x002e, 0x001e, 0x015e, 0xa005,
-	0x0005, 0x00f6, 0x00e6, 0x00c6, 0x0086, 0x0076, 0x0066, 0x0026,
-	0x0126, 0x2091, 0x8000, 0x2740, 0x2061, 0xbd00, 0x2079, 0x0001,
-	0x8fff, 0x0904, 0xafef, 0x2071, 0xb500, 0x7648, 0x7068, 0x8001,
-	0xa602, 0x1a04, 0xafef, 0x88ff, 0x0128, 0x2800, 0xac06, 0x15b0,
-	0x2079, 0x0000, 0x080c, 0xb110, 0x0588, 0x2400, 0xac06, 0x0570,
-	0x671c, 0xa786, 0x0006, 0x1550, 0xa786, 0x0007, 0x0538, 0x88ff,
-	0x1140, 0x6018, 0xa206, 0x1510, 0x85ff, 0x0118, 0x6050, 0xa106,
-	0x11e8, 0x00d6, 0x6000, 0xa086, 0x0004, 0x1150, 0x080c, 0xb33a,
-	0x601f, 0x0007, 0x2001, 0xb7b6, 0x2004, 0x6016, 0x080c, 0x194d,
-	0x6010, 0x2068, 0x080c, 0x9c5a, 0x0120, 0x0046, 0x080c, 0xb099,
-	0x004e, 0x00de, 0x080c, 0x9e1d, 0x88ff, 0x1198, 0xace0, 0x0018,
-	0x2001, 0xb517, 0x2004, 0xac02, 0x1210, 0x0804, 0xafa0, 0xa006,
-	0x012e, 0x002e, 0x006e, 0x007e, 0x008e, 0x00ce, 0x00ee, 0x00fe,
-	0x0005, 0xa8c5, 0x0001, 0x0ca0, 0x0076, 0x0056, 0x0086, 0x2041,
-	0x0000, 0x2029, 0x0001, 0x2c20, 0x2019, 0x0002, 0x6218, 0x0096,
-	0x2049, 0x0000, 0x080c, 0x8130, 0x009e, 0x008e, 0x2039, 0x0000,
-	0x080c, 0x81d6, 0x080c, 0xaf91, 0x005e, 0x007e, 0x0005, 0x0026,
-	0x0046, 0x0056, 0x0076, 0x00c6, 0x0156, 0x2c20, 0x2128, 0x20a9,
-	0x007f, 0x2009, 0x0000, 0x0016, 0x0036, 0x080c, 0x4fa9, 0x11b0,
-	0x2c10, 0x0056, 0x0086, 0x2041, 0x0000, 0x2508, 0x2029, 0x0001,
-	0x0096, 0x2049, 0x0000, 0x080c, 0x8130, 0x009e, 0x008e, 0x2039,
-	0x0000, 0x080c, 0x81d6, 0x080c, 0xaf91, 0x005e, 0x003e, 0x001e,
-	0x8108, 0x1f04, 0xb023, 0x015e, 0x00ce, 0x007e, 0x005e, 0x004e,
-	0x002e, 0x0005, 0x0076, 0x0056, 0x6218, 0x0086, 0x2041, 0x0000,
-	0x2029, 0x0001, 0x2019, 0x0048, 0x0096, 0x2049, 0x0000, 0x080c,
-	0x8130, 0x009e, 0x008e, 0x2039, 0x0000, 0x080c, 0x81d6, 0x2c20,
-	0x080c, 0xaf91, 0x005e, 0x007e, 0x0005, 0x0026, 0x0046, 0x0056,
-	0x0076, 0x00c6, 0x0156, 0x2c20, 0x20a9, 0x007f, 0x2009, 0x0000,
-	0x0016, 0x0036, 0x080c, 0x4fa9, 0x11c0, 0x2c10, 0x0086, 0x2041,
-	0x0000, 0x2828, 0x0046, 0x2021, 0x0001, 0x080c, 0xb31c, 0x004e,
-	0x0096, 0x2049, 0x0000, 0x080c, 0x8130, 0x009e, 0x008e, 0x2039,
-	0x0000, 0x080c, 0x81d6, 0x080c, 0xaf91, 0x003e, 0x001e, 0x8108,
-	0x1f04, 0xb070, 0x015e, 0x00ce, 0x007e, 0x005e, 0x004e, 0x002e,
-	0x0005, 0x0016, 0x00f6, 0x3800, 0xd08c, 0x0130, 0xad82, 0x1000,
-	0x02b0, 0xad82, 0xb500, 0x0230, 0xad82, 0xed00, 0x0280, 0xad82,
-	0xffff, 0x1268, 0x6800, 0xa07d, 0x0138, 0x6803, 0x0000, 0x6b52,
-	0x080c, 0x5408, 0x2f68, 0x0cb0, 0x6b52, 0x080c, 0x5408, 0x00fe,
-	0x001e, 0x0005, 0x00e6, 0x0046, 0x0036, 0x2061, 0xbd00, 0xa005,
-	0x1138, 0x2071, 0xb500, 0x7448, 0x7068, 0x8001, 0xa402, 0x12d8,
-	0x2100, 0xac06, 0x0168, 0x6000, 0xa086, 0x0000, 0x0148, 0x6008,
-	0xa206, 0x1130, 0x6018, 0xa1a0, 0x0006, 0x2424, 0xa406, 0x0140,
-	0xace0, 0x0018, 0x2001, 0xb517, 0x2004, 0xac02, 0x1220, 0x0c40,
-	0xa085, 0x0001, 0x0008, 0xa006, 0x003e, 0x004e, 0x00ee, 0x0005,
-	0x00d6, 0x0006, 0x080c, 0x15f8, 0x000e, 0x090c, 0x1515, 0x6837,
-	0x010d, 0x685e, 0x0026, 0x2010, 0x080c, 0x9c4a, 0x2001, 0x0000,
-	0x0120, 0x2200, 0xa080, 0x0014, 0x2004, 0x002e, 0x684a, 0x6956,
-	0x6c46, 0x684f, 0x0000, 0x2001, 0xb7be, 0x2004, 0x6852, 0xa006,
-	0x68b2, 0x6802, 0x683a, 0x685a, 0x080c, 0x5408, 0x00de, 0x0005,
-	0x6700, 0xa786, 0x0000, 0x0158, 0xa786, 0x0001, 0x0140, 0xa786,
-	0x000a, 0x0128, 0xa786, 0x0009, 0x0110, 0xa085, 0x0001, 0x0005,
-	0x00e6, 0x6018, 0x2070, 0x70a0, 0xa206, 0x00ee, 0x0005, 0x0016,
-	0x6004, 0xa08e, 0x001e, 0x11a0, 0x8007, 0x6130, 0xa18c, 0x00ff,
-	0xa105, 0x6032, 0x6007, 0x0085, 0x6003, 0x000b, 0x601f, 0x0005,
-	0x2001, 0xb7b7, 0x2004, 0x6016, 0x080c, 0x6c8d, 0x080c, 0x7173,
-	0x001e, 0x0005, 0xe000, 0xe000, 0x0005, 0x6020, 0xd0e4, 0x0158,
-	0xd0cc, 0x0118, 0x080c, 0x9f35, 0x0030, 0x080c, 0xb33a, 0x080c,
-	0x6aef, 0x080c, 0x861d, 0x0005, 0xa280, 0x0007, 0x2004, 0xa084,
-	0x000f, 0x0002, 0xb163, 0xb163, 0xb163, 0xb168, 0xb163, 0xb165,
-	0xb165, 0xb163, 0xb165, 0xa006, 0x0005, 0x00c6, 0x2260, 0x00ce,
-	0xa085, 0x0001, 0x0005, 0xa280, 0x0007, 0x2004, 0xa084, 0x000f,
-	0x0002, 0xb17a, 0xb17a, 0xb17a, 0xb17a, 0xb17a, 0xb17a, 0xb185,
-	0xb17a, 0xb17a, 0x6007, 0x003b, 0x602b, 0x0009, 0x6013, 0x2a00,
-	0x6003, 0x0001, 0x080c, 0x6c8d, 0x0005, 0x00c6, 0x2260, 0x080c,
-	0xb33a, 0x603f, 0x0000, 0x6020, 0xc0f4, 0xc0cc, 0x6022, 0x6037,
-	0x0000, 0x00ce, 0x00d6, 0x2268, 0xa186, 0x0007, 0x1904, 0xb1e0,
-	0x6810, 0xa005, 0x0138, 0xa080, 0x0013, 0x2004, 0xd0fc, 0x1110,
-	0x00de, 0x08c0, 0x6007, 0x003a, 0x6003, 0x0001, 0x080c, 0x6c8d,
-	0x080c, 0x7173, 0x00c6, 0x2d60, 0x6100, 0xa186, 0x0002, 0x1904,
-	0xb269, 0x6010, 0xa005, 0x1138, 0x6000, 0xa086, 0x0007, 0x190c,
-	0x1515, 0x0804, 0xb269, 0xa08c, 0xf000, 0x1130, 0x0028, 0x2068,
-	0x6800, 0xa005, 0x1de0, 0x2d00, 0xa080, 0x0013, 0x2004, 0xa084,
-	0x0003, 0xa086, 0x0002, 0x1180, 0x6010, 0x2068, 0x684c, 0xc0dc,
-	0xc0f4, 0x684e, 0x6850, 0xc0f4, 0xc0fc, 0x6852, 0x2009, 0x0043,
-	0x080c, 0xab56, 0x0804, 0xb269, 0x2009, 0x0041, 0x0804, 0xb263,
-	0xa186, 0x0005, 0x15f0, 0x6810, 0xa080, 0x0013, 0x2004, 0xd0bc,
-	0x1118, 0x00de, 0x0804, 0xb17a, 0xd0b4, 0x0128, 0xd0fc, 0x090c,
-	0x1515, 0x0804, 0xb198, 0x6007, 0x003a, 0x6003, 0x0001, 0x080c,
-	0x6c8d, 0x080c, 0x7173, 0x00c6, 0x2d60, 0x6100, 0xa186, 0x0002,
-	0x0120, 0xa186, 0x0004, 0x1904, 0xb269, 0x2071, 0xb823, 0x7000,
-	0xa086, 0x0003, 0x1128, 0x7004, 0xac06, 0x1110, 0x7003, 0x0000,
-	0x6810, 0xa080, 0x0013, 0x200c, 0xc1f4, 0xc1dc, 0x2102, 0x8000,
-	0x200c, 0xc1f4, 0xc1fc, 0xc1bc, 0x2102, 0x2009, 0x0042, 0x0804,
-	0xb263, 0x0036, 0x00d6, 0x00d6, 0x080c, 0x15f8, 0x003e, 0x090c,
-	0x1515, 0x6837, 0x010d, 0x6803, 0x0000, 0x683b, 0x0000, 0x685b,
-	0x0000, 0x6b5e, 0x6857, 0x0045, 0x2c00, 0x6862, 0x6034, 0x6872,
-	0x2360, 0x6020, 0xc0dd, 0x6022, 0x6018, 0xa080, 0x0028, 0x2004,
-	0xa084, 0x00ff, 0x8007, 0x6350, 0x6b4a, 0x6846, 0x684f, 0x0000,
-	0x6853, 0x0000, 0x6d6a, 0x6e66, 0x686f, 0x0001, 0x080c, 0x5408,
-	0x2019, 0x0045, 0x6008, 0x2068, 0x080c, 0xace0, 0x2d00, 0x600a,
-	0x601f, 0x0006, 0x6003, 0x0007, 0x6017, 0x0000, 0x603f, 0x0000,
-	0x00de, 0x003e, 0x0038, 0x603f, 0x0000, 0x6003, 0x0007, 0x080c,
-	0xab56, 0x00ce, 0x00de, 0x0005, 0xa186, 0x0013, 0x1128, 0x6004,
-	0xa082, 0x0085, 0x2008, 0x00c2, 0xa186, 0x0027, 0x1178, 0x080c,
-	0x7090, 0x0036, 0x00d6, 0x6010, 0x2068, 0x2019, 0x0004, 0x080c,
-	0xb099, 0x00de, 0x003e, 0x080c, 0x7173, 0x0005, 0xa186, 0x0014,
-	0x0d70, 0x080c, 0x8663, 0x0005, 0xb295, 0xb293, 0xb293, 0xb293,
-	0xb293, 0xb293, 0xb295, 0x080c, 0x1515, 0x080c, 0x7090, 0x6003,
-	0x000c, 0x080c, 0x7173, 0x0005, 0xa182, 0x008c, 0x1220, 0xa182,
-	0x0085, 0x0208, 0x001a, 0x080c, 0x8663, 0x0005, 0xb2ad, 0xb2ad,
-	0xb2ad, 0xb2ad, 0xb2af, 0xb2cd, 0xb2ad, 0x080c, 0x1515, 0x00d6,
-	0x2c68, 0x080c, 0x85c7, 0x01a0, 0x6003, 0x0001, 0x6007, 0x001e,
-	0x2009, 0xbb8e, 0x210c, 0x6136, 0x2009, 0xbb8f, 0x210c, 0x613a,
-	0x600b, 0xffff, 0x6918, 0x611a, 0x601f, 0x0004, 0x080c, 0x6c8d,
-	0x2d60, 0x080c, 0x861d, 0x00de, 0x0005, 0x080c, 0x861d, 0x0005,
-	0x00e6, 0x6018, 0x2070, 0x7000, 0xd0ec, 0x00ee, 0x0005, 0x6010,
-	0xa08c, 0xf000, 0x0904, 0xb31b, 0xa080, 0x0013, 0x200c, 0xd1ec,
-	0x05d0, 0x2001, 0xb572, 0x2004, 0xd0ec, 0x05a8, 0x6003, 0x0002,
-	0x6020, 0xc0e5, 0x6022, 0xd1ac, 0x0180, 0x00f6, 0x2c78, 0x080c,
-	0x5301, 0x00fe, 0x0150, 0x2001, 0xb7b8, 0x2004, 0x603e, 0x2009,
-	0xb572, 0x210c, 0xd1f4, 0x11e8, 0x0080, 0x2009, 0xb572, 0x210c,
-	0xd1f4, 0x0128, 0x6020, 0xc0e4, 0x6022, 0xa006, 0x00a0, 0x2001,
-	0xb7b8, 0x200c, 0x8103, 0xa100, 0x603e, 0x6018, 0xa088, 0x002b,
-	0x2104, 0xa005, 0x0118, 0xa088, 0x0003, 0x0cd0, 0x2c0a, 0x600f,
-	0x0000, 0xa085, 0x0001, 0x0005, 0x0016, 0x00c6, 0x00e6, 0x6150,
-	0xa2f0, 0x002b, 0x2e04, 0x2060, 0x8cff, 0x0180, 0x84ff, 0x1118,
-	0x6050, 0xa106, 0x1138, 0x600c, 0x2072, 0x080c, 0x6aef, 0x080c,
-	0x861d, 0x0010, 0xacf0, 0x0003, 0x2e64, 0x0c70, 0x00ee, 0x00ce,
-	0x001e, 0x0005, 0x00d6, 0x6018, 0xa0e8, 0x002b, 0x2d04, 0xa005,
-	0x0140, 0xac06, 0x0120, 0x2d04, 0xa0e8, 0x0003, 0x0cb8, 0x600c,
-	0x206a, 0x00de, 0x0005, 0x0026, 0x0036, 0x0156, 0x2011, 0xb528,
-	0x2204, 0xa084, 0x00ff, 0x2019, 0xbb8e, 0x2334, 0xa636, 0x11d8,
-	0x8318, 0x2334, 0x2204, 0xa084, 0xff00, 0xa636, 0x11a0, 0x2011,
-	0xbb90, 0x6018, 0xa098, 0x000a, 0x20a9, 0x0004, 0x080c, 0x90da,
-	0x1150, 0x2011, 0xbb94, 0x6018, 0xa098, 0x0006, 0x20a9, 0x0004,
-	0x080c, 0x90da, 0x1100, 0x015e, 0x003e, 0x002e, 0x0005, 0x00e6,
-	0x2071, 0xb500, 0x080c, 0x4bc6, 0x080c, 0x2ab8, 0x00ee, 0x0005,
-	0x00e6, 0x6018, 0x2070, 0x7000, 0xd0fc, 0x0108, 0x0011, 0x00ee,
-	0x0005, 0x6850, 0xc0e5, 0x6852, 0x0005, 0x00e6, 0x00c6, 0x0076,
-	0x0066, 0x0056, 0x0046, 0x0026, 0x0016, 0x0126, 0x2091, 0x8000,
-	0x2029, 0xb7e9, 0x252c, 0x2021, 0xb7ef, 0x2424, 0x2061, 0xbd00,
-	0x2071, 0xb500, 0x7648, 0x7068, 0xa606, 0x0578, 0x671c, 0xa786,
-	0x0001, 0x0118, 0xa786, 0x0008, 0x1500, 0x2500, 0xac06, 0x01e8,
-	0x2400, 0xac06, 0x01d0, 0x080c, 0xb110, 0x01b8, 0x080c, 0xb120,
-	0x11a0, 0x6000, 0xa086, 0x0004, 0x1120, 0x0016, 0x080c, 0x194d,
-	0x001e, 0x080c, 0x9e47, 0x1110, 0x080c, 0x2cc2, 0x080c, 0x9e58,
-	0x1110, 0x080c, 0x8c19, 0x080c, 0x9e1d, 0xace0, 0x0018, 0x2001,
-	0xb517, 0x2004, 0xac02, 0x1208, 0x0858, 0x012e, 0x001e, 0x002e,
-	0x004e, 0x005e, 0x006e, 0x007e, 0x00ce, 0x00ee, 0x0005, 0x0126,
-	0x0006, 0x00e6, 0x0016, 0x2091, 0x8000, 0x2071, 0xb540, 0xd5a4,
-	0x0118, 0x7034, 0x8000, 0x7036, 0xd5b4, 0x0118, 0x7030, 0x8000,
-	0x7032, 0xd5ac, 0x0178, 0x2500, 0xa084, 0x0007, 0xa08e, 0x0003,
-	0x0148, 0xa08e, 0x0004, 0x0130, 0xa08e, 0x0005, 0x0118, 0x2071,
-	0xb54a, 0x04c9, 0x001e, 0x00ee, 0x000e, 0x012e, 0x0005, 0x0126,
-	0x0006, 0x00e6, 0x0016, 0x2091, 0x8000, 0x2071, 0xb540, 0xd5a4,
-	0x0118, 0x7034, 0x8000, 0x7036, 0xd5b4, 0x0118, 0x7030, 0x8000,
-	0x7032, 0xd5ac, 0x0178, 0x2500, 0xa084, 0x0007, 0xa08e, 0x0003,
-	0x0148, 0xa08e, 0x0004, 0x0130, 0xa08e, 0x0005, 0x0118, 0x2071,
-	0xb54a, 0x0089, 0x001e, 0x00ee, 0x000e, 0x012e, 0x0005, 0x0126,
-	0x0006, 0x00e6, 0x2091, 0x8000, 0x2071, 0xb542, 0x0021, 0x00ee,
-	0x000e, 0x012e, 0x0005, 0x2e04, 0x8000, 0x2072, 0x1220, 0x8e70,
-	0x2e04, 0x8000, 0x2072, 0x0005, 0x00e6, 0x2071, 0xb540, 0x0c99,
-	0x00ee, 0x0005, 0x00e6, 0x2071, 0xb544, 0x0c69, 0x00ee, 0x0005,
-	0x0126, 0x0006, 0x00e6, 0x2091, 0x8000, 0x2071, 0xb540, 0x7044,
-	0x8000, 0x7046, 0x00ee, 0x000e, 0x012e, 0x0005, 0x0001, 0x0002,
-	0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100, 0x0200,
-	0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000, 0x2440
+	0x0550, 0xa686, 0x0004, 0x0538, 0x2001, 0x0004, 0x0410, 0x2001,
+	0xb600, 0x2004, 0xa086, 0x0003, 0x1110, 0x080c, 0x3f85, 0x2001,
+	0x0006, 0x04a1, 0x6618, 0x00d6, 0x2668, 0x6e04, 0x00de, 0xa6b4,
+	0xff00, 0x8637, 0xa686, 0x0006, 0x0170, 0x2001, 0x0006, 0x0048,
+	0x2001, 0x0004, 0x0030, 0x2001, 0x0006, 0x0401, 0x0020, 0x0018,
+	0x0010, 0x080c, 0x4f9c, 0x080c, 0x7102, 0x080c, 0x86a4, 0x080c,
+	0x71e5, 0x0005, 0x2600, 0x0002, 0xa80d, 0xa80d, 0xa80d, 0xa80d,
+	0xa80d, 0xa80f, 0xa80d, 0xa80d, 0xa80d, 0x080c, 0x151a, 0x080c,
+	0x7102, 0x080c, 0x86a4, 0x080c, 0x71e5, 0x0005, 0x0016, 0x00d6,
+	0x6118, 0x2168, 0x6900, 0xd184, 0x0140, 0x080c, 0x4f6f, 0x2001,
+	0x0000, 0x080c, 0x4f5d, 0x080c, 0x2cf7, 0x00de, 0x001e, 0x0005,
+	0x00d6, 0x6618, 0x2668, 0x6804, 0xa084, 0xff00, 0x8007, 0x00de,
+	0xa0b2, 0x000c, 0x1a0c, 0x151a, 0xa1b6, 0x0015, 0x1110, 0x003b,
+	0x0028, 0xa1b6, 0x0016, 0x190c, 0x151a, 0x006b, 0x0005, 0x8d6b,
+	0x8d6b, 0x8d6b, 0x8d6b, 0x8d6b, 0x8d6b, 0xa898, 0xa857, 0x8d6b,
+	0x8d6b, 0x8d6b, 0x8d6b, 0x8d6b, 0x8d6b, 0x8d6b, 0x8d6b, 0x8d6b,
+	0x8d6b, 0xa898, 0xa89f, 0x8d6b, 0x8d6b, 0x8d6b, 0x8d6b, 0x00f6,
+	0x2079, 0xb652, 0x7804, 0xd0ac, 0x11e0, 0x6018, 0xa07d, 0x01c8,
+	0x7800, 0xd0f4, 0x1118, 0x7810, 0xa005, 0x1198, 0x2001, 0x0000,
+	0x080c, 0x4f5d, 0x2001, 0x0002, 0x080c, 0x4f6f, 0x601f, 0x0001,
+	0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x6d45, 0x080c, 0x71e5,
+	0x00e8, 0x2011, 0xbc83, 0x2204, 0x8211, 0x220c, 0x080c, 0x2852,
+	0x11a8, 0x00c6, 0x080c, 0x501b, 0x0120, 0x00ce, 0x080c, 0x86a4,
+	0x0068, 0x6010, 0x0006, 0x6014, 0x0006, 0x080c, 0x4c7e, 0x000e,
+	0x6016, 0x000e, 0x6012, 0x00ce, 0x080c, 0x86a4, 0x00fe, 0x0005,
+	0x6604, 0xa6b6, 0x001e, 0x1110, 0x080c, 0x86a4, 0x0005, 0x080c,
+	0x9021, 0x1138, 0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x6d45,
+	0x0010, 0x080c, 0x86a4, 0x0005, 0x6004, 0xa08a, 0x0080, 0x1a0c,
+	0x151a, 0x080c, 0x7102, 0x080c, 0x9ed9, 0x080c, 0x71e5, 0x0005,
+	0xa182, 0x0040, 0x0002, 0xa8ce, 0xa8ce, 0xa8ce, 0xa8ce, 0xa8d0,
+	0xa8ce, 0xa8ce, 0xa8ce, 0xa8ce, 0xa8ce, 0xa8ce, 0xa8ce, 0xa8ce,
+	0xa8ce, 0xa8ce, 0xa8ce, 0xa8ce, 0xa8ce, 0xa8ce, 0x080c, 0x151a,
+	0x00d6, 0x00e6, 0x00f6, 0x0156, 0x0046, 0x0026, 0x6218, 0xa280,
+	0x002b, 0x2004, 0xa005, 0x0120, 0x2021, 0x0000, 0x080c, 0xb3d8,
+	0x6106, 0x2071, 0xbc80, 0x7444, 0xa4a4, 0xff00, 0x0904, 0xa934,
+	0xa486, 0x2000, 0x1130, 0x2009, 0x0001, 0x2011, 0x0200, 0x080c,
+	0x6b8c, 0x080c, 0x15fd, 0x090c, 0x151a, 0x6003, 0x0007, 0x2d00,
+	0x6837, 0x010d, 0x6803, 0x0000, 0x683b, 0x0000, 0x6c5a, 0x2c00,
+	0x685e, 0x6008, 0x68b2, 0x6018, 0x2078, 0x78a0, 0x8007, 0x7130,
+	0x694a, 0x0016, 0xa084, 0xff00, 0x6846, 0x684f, 0x0000, 0x6853,
+	0x0000, 0x6857, 0x0036, 0x080c, 0x547a, 0x001e, 0xa486, 0x2000,
+	0x1130, 0x2019, 0x0017, 0x080c, 0xb121, 0x0804, 0xa991, 0xa486,
+	0x0400, 0x1130, 0x2019, 0x0002, 0x080c, 0xb0d3, 0x0804, 0xa991,
+	0xa486, 0x0200, 0x1110, 0x080c, 0xb0b8, 0xa486, 0x1000, 0x1110,
+	0x080c, 0xb106, 0x0804, 0xa991, 0x2069, 0xb975, 0x6a00, 0xd284,
+	0x0904, 0xa9f8, 0xa284, 0x0300, 0x1904, 0xa9f1, 0x6804, 0xa005,
+	0x0904, 0xa9d9, 0x2d78, 0x6003, 0x0007, 0x080c, 0x15e4, 0x0904,
+	0xa998, 0x7800, 0xd08c, 0x1118, 0x7804, 0x8001, 0x7806, 0x6013,
+	0x0000, 0x6803, 0x0000, 0x6837, 0x0116, 0x683b, 0x0000, 0x6008,
+	0x68b2, 0x2c00, 0x684a, 0x6018, 0x2078, 0x78a0, 0x8007, 0x7130,
+	0x6986, 0x6846, 0x7928, 0x698a, 0x792c, 0x698e, 0x7930, 0x6992,
+	0x7934, 0x6996, 0x6853, 0x003d, 0x7244, 0xa294, 0x0003, 0xa286,
+	0x0002, 0x1118, 0x684f, 0x0040, 0x0040, 0xa286, 0x0001, 0x1118,
+	0x684f, 0x0080, 0x0010, 0x684f, 0x0000, 0x20a9, 0x000a, 0x2001,
+	0xbc90, 0xad90, 0x0015, 0x200c, 0x810f, 0x2112, 0x8000, 0x8210,
+	0x1f04, 0xa983, 0x200c, 0x6982, 0x8000, 0x200c, 0x697e, 0x080c,
+	0x547a, 0x002e, 0x004e, 0x015e, 0x00fe, 0x00ee, 0x00de, 0x0005,
+	0x2001, 0xb60e, 0x2004, 0xd084, 0x0120, 0x080c, 0x15fd, 0x1904,
+	0xa949, 0x6013, 0x0100, 0x6003, 0x0001, 0x6007, 0x0041, 0x080c,
+	0x6cff, 0x080c, 0x71e5, 0x0c28, 0x2069, 0xbc92, 0x2d04, 0xa084,
+	0xff00, 0xa086, 0x1200, 0x11a8, 0x2069, 0xbc80, 0x686c, 0xa084,
+	0x00ff, 0x0016, 0x6110, 0xa18c, 0x0700, 0xa10d, 0x6112, 0x001e,
+	0x6003, 0x0001, 0x6007, 0x0043, 0x080c, 0x6cff, 0x080c, 0x71e5,
+	0x0840, 0x6868, 0x602a, 0x686c, 0x602e, 0x6013, 0x0200, 0x6003,
+	0x0001, 0x6007, 0x0041, 0x080c, 0x6cff, 0x080c, 0x71e5, 0x0804,
+	0xa991, 0x2001, 0xb60d, 0x2004, 0xd0ec, 0x0120, 0x2011, 0x8049,
+	0x080c, 0x3f13, 0x6013, 0x0300, 0x0010, 0x6013, 0x0100, 0x6003,
+	0x0001, 0x6007, 0x0041, 0x080c, 0x6cff, 0x080c, 0x71e5, 0x0804,
+	0xa991, 0x6013, 0x0500, 0x0c98, 0x6013, 0x0600, 0x0804, 0xa9ac,
+	0x6013, 0x0200, 0x0804, 0xa9ac, 0xa186, 0x0013, 0x1170, 0x6004,
+	0xa08a, 0x0040, 0x0a0c, 0x151a, 0xa08a, 0x0053, 0x1a0c, 0x151a,
+	0xa082, 0x0040, 0x2008, 0x0804, 0xaa86, 0xa186, 0x0051, 0x0138,
+	0xa186, 0x0047, 0x11d8, 0x6004, 0xa086, 0x0041, 0x0518, 0x2001,
+	0x0109, 0x2004, 0xd084, 0x01f0, 0x0126, 0x2091, 0x2800, 0x0006,
+	0x0016, 0x0026, 0x080c, 0x6be6, 0x002e, 0x001e, 0x000e, 0x012e,
+	0x6000, 0xa086, 0x0002, 0x1170, 0x0804, 0xaac9, 0xa186, 0x0027,
+	0x0120, 0xa186, 0x0014, 0x190c, 0x151a, 0x6004, 0xa082, 0x0040,
+	0x2008, 0x001a, 0x080c, 0x86ef, 0x0005, 0xaa50, 0xaa52, 0xaa52,
+	0xaa76, 0xaa50, 0xaa50, 0xaa50, 0xaa50, 0xaa50, 0xaa50, 0xaa50,
+	0xaa50, 0xaa50, 0xaa50, 0xaa50, 0xaa50, 0xaa50, 0xaa50, 0xaa50,
+	0x080c, 0x151a, 0x080c, 0x7102, 0x080c, 0x71e5, 0x0036, 0x00d6,
+	0x6010, 0xa06d, 0x01c0, 0xad84, 0xf000, 0x01a8, 0x6003, 0x0002,
+	0x6018, 0x2004, 0xd0bc, 0x1178, 0x2019, 0x0004, 0x080c, 0xb155,
+	0x6013, 0x0000, 0x6014, 0xa005, 0x1120, 0x2001, 0xb8b7, 0x2004,
+	0x6016, 0x6003, 0x0007, 0x00de, 0x003e, 0x0005, 0x00d6, 0x080c,
+	0x7102, 0x080c, 0x71e5, 0x080c, 0x9d16, 0x0120, 0x6010, 0x2068,
+	0x080c, 0x1614, 0x080c, 0x9ed9, 0x00de, 0x0005, 0x0002, 0xaa9a,
+	0xaab7, 0xaaa3, 0xaac3, 0xaa9a, 0xaa9a, 0xaa9a, 0xaa9a, 0xaa9a,
+	0xaa9a, 0xaa9a, 0xaa9a, 0xaa9a, 0xaa9a, 0xaa9a, 0xaa9a, 0xaa9a,
+	0xaa9a, 0xaa9a, 0x080c, 0x151a, 0x6010, 0xa088, 0x0013, 0x2104,
+	0xa085, 0x0400, 0x200a, 0x080c, 0x7102, 0x6010, 0xa080, 0x0013,
+	0x2004, 0xd0b4, 0x0138, 0x6003, 0x0007, 0x2009, 0x0043, 0x080c,
+	0x86d3, 0x0010, 0x6003, 0x0002, 0x080c, 0x71e5, 0x0005, 0x080c,
+	0x7102, 0x080c, 0xb393, 0x1120, 0x080c, 0x6b61, 0x080c, 0x86a4,
+	0x080c, 0x71e5, 0x0005, 0x080c, 0x7102, 0x2009, 0x0041, 0x0804,
+	0xac12, 0xa182, 0x0040, 0x0002, 0xaadf, 0xaae1, 0xaadf, 0xaadf,
+	0xaadf, 0xaadf, 0xaadf, 0xaae2, 0xaadf, 0xaadf, 0xaadf, 0xaadf,
+	0xaadf, 0xaadf, 0xaadf, 0xaadf, 0xaadf, 0xaaed, 0xaadf, 0x080c,
+	0x151a, 0x0005, 0x6003, 0x0004, 0x6110, 0x20e1, 0x0005, 0x3d18,
+	0x3e20, 0x2c10, 0x080c, 0x1863, 0x0005, 0x00d6, 0x080c, 0x6b61,
+	0x00de, 0x080c, 0xb3f6, 0x080c, 0x86a4, 0x0005, 0xa182, 0x0040,
+	0x0002, 0xab0c, 0xab0c, 0xab0c, 0xab0c, 0xab0c, 0xab0c, 0xab0c,
+	0xab0e, 0xab0c, 0xab11, 0xab4a, 0xab0c, 0xab0c, 0xab0c, 0xab0c,
+	0xab4a, 0xab0c, 0xab0c, 0xab0c, 0x080c, 0x151a, 0x080c, 0x86ef,
+	0x0005, 0x2001, 0xb672, 0x2004, 0xd0e4, 0x0158, 0x2001, 0x0100,
+	0x2004, 0xa082, 0x0005, 0x0228, 0x2001, 0x011f, 0x2004, 0x6036,
+	0x0010, 0x6037, 0x0000, 0x080c, 0x7198, 0x080c, 0x72a2, 0x6010,
+	0x00d6, 0x2068, 0x684c, 0xd0fc, 0x0150, 0xa08c, 0x0003, 0xa18e,
+	0x0002, 0x0168, 0x2009, 0x0041, 0x00de, 0x0804, 0xac12, 0x6003,
+	0x0007, 0x6017, 0x0000, 0x080c, 0x6b61, 0x00de, 0x0005, 0x080c,
+	0xb393, 0x0110, 0x00de, 0x0005, 0x080c, 0x6b61, 0x080c, 0x86a4,
+	0x00de, 0x0ca0, 0x0036, 0x080c, 0x7198, 0x080c, 0x72a2, 0x6010,
+	0x00d6, 0x2068, 0x6018, 0x2004, 0xd0bc, 0x0188, 0x684c, 0xa084,
+	0x0003, 0xa086, 0x0002, 0x0140, 0x687c, 0x632c, 0xa31a, 0x632e,
+	0x6880, 0x6328, 0xa31b, 0x632a, 0x6003, 0x0002, 0x0080, 0x2019,
+	0x0004, 0x080c, 0xb155, 0x6014, 0xa005, 0x1128, 0x2001, 0xb8b7,
+	0x2004, 0x8003, 0x6016, 0x6013, 0x0000, 0x6003, 0x0007, 0x00de,
+	0x003e, 0x0005, 0xa186, 0x0013, 0x1150, 0x6004, 0xa086, 0x0042,
+	0x190c, 0x151a, 0x080c, 0x7102, 0x080c, 0x71e5, 0x0005, 0xa186,
+	0x0027, 0x0118, 0xa186, 0x0014, 0x1180, 0x6004, 0xa086, 0x0042,
+	0x190c, 0x151a, 0x2001, 0x0007, 0x080c, 0x4f9c, 0x080c, 0x7102,
+	0x080c, 0x9ed9, 0x080c, 0x71e5, 0x0005, 0xa182, 0x0040, 0x0002,
+	0xabb3, 0xabb3, 0xabb3, 0xabb3, 0xabb3, 0xabb3, 0xabb3, 0xabb5,
+	0xabc1, 0xabb3, 0xabb3, 0xabb3, 0xabb3, 0xabb3, 0xabb3, 0xabb3,
+	0xabb3, 0xabb3, 0xabb3, 0x080c, 0x151a, 0x0036, 0x0046, 0x20e1,
+	0x0005, 0x3d18, 0x3e20, 0x2c10, 0x080c, 0x1863, 0x004e, 0x003e,
+	0x0005, 0x6010, 0x00d6, 0x2068, 0x6810, 0x6a14, 0x0006, 0x0046,
+	0x0056, 0x6c7c, 0xa422, 0x6d80, 0x2200, 0xa52b, 0x602c, 0xa420,
+	0x642e, 0x6028, 0xa529, 0x652a, 0x005e, 0x004e, 0x000e, 0xa20d,
+	0x1178, 0x684c, 0xd0fc, 0x0120, 0x2009, 0x0041, 0x00de, 0x0490,
+	0x6003, 0x0007, 0x6017, 0x0000, 0x080c, 0x6b61, 0x00de, 0x0005,
+	0x0006, 0x00f6, 0x2c78, 0x080c, 0x5377, 0x00fe, 0x000e, 0x0120,
+	0x6003, 0x0002, 0x00de, 0x0005, 0x2009, 0xb60d, 0x210c, 0xd19c,
+	0x0118, 0x6003, 0x0007, 0x0010, 0x6003, 0x0006, 0x0021, 0x080c,
+	0x6b63, 0x00de, 0x0005, 0xd2fc, 0x0140, 0x8002, 0x8000, 0x8212,
+	0xa291, 0x0000, 0x2009, 0x0009, 0x0010, 0x2009, 0x0015, 0x6a6a,
+	0x6866, 0x0005, 0xa182, 0x0040, 0x0208, 0x0062, 0xa186, 0x0013,
+	0x0120, 0xa186, 0x0014, 0x190c, 0x151a, 0x6020, 0xd0dc, 0x090c,
+	0x151a, 0x0005, 0xac35, 0xac3c, 0xac48, 0xac54, 0xac35, 0xac35,
+	0xac35, 0xac63, 0xac35, 0xac37, 0xac37, 0xac35, 0xac35, 0xac35,
+	0xac35, 0xac37, 0xac35, 0xac37, 0xac35, 0x080c, 0x151a, 0x6020,
+	0xd0dc, 0x090c, 0x151a, 0x0005, 0x6003, 0x0001, 0x6106, 0x080c,
+	0x6cff, 0x0126, 0x2091, 0x8000, 0x080c, 0x71e5, 0x012e, 0x0005,
+	0x6003, 0x0001, 0x6106, 0x080c, 0x6cff, 0x0126, 0x2091, 0x8000,
+	0x080c, 0x71e5, 0x012e, 0x0005, 0x6003, 0x0003, 0x6106, 0x2c10,
+	0x080c, 0x1fc5, 0x0126, 0x2091, 0x8000, 0x080c, 0x6d62, 0x080c,
+	0x72a2, 0x012e, 0x0005, 0xa016, 0x080c, 0x1863, 0x0005, 0x0126,
+	0x2091, 0x8000, 0x0036, 0x00d6, 0xa182, 0x0040, 0x0023, 0x00de,
+	0x003e, 0x012e, 0x0005, 0xac83, 0xac85, 0xac97, 0xacb2, 0xac83,
+	0xac83, 0xac83, 0xacc7, 0xac83, 0xac83, 0xac83, 0xac83, 0xac83,
+	0xac83, 0xac83, 0xac83, 0x080c, 0x151a, 0x6010, 0x2068, 0x684c,
+	0xd0fc, 0x01f8, 0xa09c, 0x0003, 0xa39e, 0x0003, 0x01d0, 0x6003,
+	0x0001, 0x6106, 0x080c, 0x6cff, 0x080c, 0x71e5, 0x0498, 0x6010,
+	0x2068, 0x684c, 0xd0fc, 0x0168, 0xa09c, 0x0003, 0xa39e, 0x0003,
+	0x0140, 0x6003, 0x0001, 0x6106, 0x080c, 0x6cff, 0x080c, 0x71e5,
+	0x0408, 0x6013, 0x0000, 0x6017, 0x0000, 0x2019, 0x0004, 0x080c,
+	0xb155, 0x00c0, 0x6010, 0x2068, 0x684c, 0xd0fc, 0x0d90, 0xa09c,
+	0x0003, 0xa39e, 0x0003, 0x0d68, 0x6003, 0x0003, 0x6106, 0x2c10,
+	0x080c, 0x1fc5, 0x080c, 0x6d62, 0x080c, 0x72a2, 0x0018, 0xa016,
+	0x080c, 0x1863, 0x0005, 0x080c, 0x7102, 0x6110, 0x81ff, 0x0158,
+	0x00d6, 0x2168, 0x080c, 0xb43c, 0x0036, 0x2019, 0x0029, 0x080c,
+	0xb155, 0x003e, 0x00de, 0x080c, 0x9ed9, 0x080c, 0x71e5, 0x0005,
+	0x080c, 0x7198, 0x6110, 0x81ff, 0x0158, 0x00d6, 0x2168, 0x080c,
+	0xb43c, 0x0036, 0x2019, 0x0029, 0x080c, 0xb155, 0x003e, 0x00de,
+	0x080c, 0x9ed9, 0x080c, 0x72a2, 0x0005, 0xa182, 0x0085, 0x0002,
+	0xad01, 0xacff, 0xacff, 0xad0d, 0xacff, 0xacff, 0xacff, 0x080c,
+	0x151a, 0x6003, 0x000b, 0x6106, 0x080c, 0x6cff, 0x0126, 0x2091,
+	0x8000, 0x080c, 0x71e5, 0x012e, 0x0005, 0x0026, 0x00e6, 0x080c,
+	0xb38c, 0x0118, 0x080c, 0x86a4, 0x00d8, 0x2071, 0xbc80, 0x7224,
+	0x6212, 0x7220, 0x080c, 0xb003, 0x0118, 0x6007, 0x0086, 0x0040,
+	0x6007, 0x0087, 0x7224, 0xa296, 0xffff, 0x1110, 0x6007, 0x0086,
+	0x6003, 0x0001, 0x080c, 0x6cff, 0x080c, 0x71e5, 0x080c, 0x72a2,
+	0x00ee, 0x002e, 0x0005, 0xa186, 0x0013, 0x1160, 0x6004, 0xa08a,
+	0x0085, 0x0a0c, 0x151a, 0xa08a, 0x008c, 0x1a0c, 0x151a, 0xa082,
+	0x0085, 0x00a2, 0xa186, 0x0027, 0x0130, 0xa186, 0x0014, 0x0118,
+	0x080c, 0x86ef, 0x0050, 0x2001, 0x0007, 0x080c, 0x4f9c, 0x080c,
+	0x7102, 0x080c, 0x9ed9, 0x080c, 0x71e5, 0x0005, 0xad5d, 0xad5f,
+	0xad5f, 0xad5d, 0xad5d, 0xad5d, 0xad5d, 0x080c, 0x151a, 0x080c,
+	0x7102, 0x080c, 0x9ed9, 0x080c, 0x71e5, 0x0005, 0xa182, 0x0085,
+	0x0a0c, 0x151a, 0xa182, 0x008c, 0x1a0c, 0x151a, 0xa182, 0x0085,
+	0x0002, 0xad78, 0xad78, 0xad78, 0xad7a, 0xad78, 0xad78, 0xad78,
+	0x080c, 0x151a, 0x0005, 0xa186, 0x0013, 0x0148, 0xa186, 0x0014,
+	0x0130, 0xa186, 0x0027, 0x0118, 0x080c, 0x86ef, 0x0030, 0x080c,
+	0x7102, 0x080c, 0x9ed9, 0x080c, 0x71e5, 0x0005, 0x0036, 0x080c,
+	0xb3f6, 0x603f, 0x0000, 0x2019, 0x000b, 0x0031, 0x601f, 0x0006,
+	0x6003, 0x0007, 0x003e, 0x0005, 0x0126, 0x0036, 0x2091, 0x8000,
+	0x0086, 0x2c40, 0x0096, 0x2049, 0x0000, 0x080c, 0x81b7, 0x009e,
+	0x008e, 0x1578, 0x0076, 0x2c38, 0x080c, 0x825d, 0x007e, 0x1548,
+	0x6000, 0xa086, 0x0000, 0x0528, 0x601c, 0xa086, 0x0007, 0x0508,
+	0x00d6, 0x6000, 0xa086, 0x0004, 0x1150, 0x080c, 0xb3f6, 0x601f,
+	0x0007, 0x2001, 0xb8b6, 0x2004, 0x6016, 0x080c, 0x1952, 0x6010,
+	0x2068, 0x080c, 0x9d16, 0x0110, 0x080c, 0xb155, 0x00de, 0x6013,
+	0x0000, 0x080c, 0xb3f6, 0x601f, 0x0007, 0x2001, 0xb8b6, 0x2004,
+	0x6016, 0x003e, 0x012e, 0x0005, 0x00f6, 0x00c6, 0x0036, 0x0156,
+	0x2079, 0xbc80, 0x7938, 0x783c, 0x080c, 0x2852, 0x15b0, 0x0016,
+	0x00c6, 0x080c, 0x501b, 0x1578, 0x001e, 0x002e, 0x0026, 0x0016,
+	0x2019, 0x0029, 0x080c, 0x8320, 0x080c, 0x6e67, 0x0076, 0x2039,
+	0x0000, 0x080c, 0x6d74, 0x007e, 0x001e, 0x0076, 0x2039, 0x0000,
+	0x080c, 0xaf3e, 0x007e, 0x080c, 0x521c, 0x0026, 0x6204, 0xa294,
+	0xff00, 0x8217, 0xa286, 0x0006, 0x0118, 0xa286, 0x0004, 0x1118,
+	0x62a0, 0x080c, 0x2d8a, 0x002e, 0x001e, 0x080c, 0x4c7e, 0x6612,
+	0x6516, 0xa006, 0x0010, 0x00ce, 0x001e, 0x015e, 0x003e, 0x00ce,
+	0x00fe, 0x0005, 0x00c6, 0x00d6, 0x00e6, 0x0016, 0x2009, 0xb621,
+	0x2104, 0xa086, 0x0074, 0x1904, 0xae77, 0x2069, 0xbc8e, 0x690c,
+	0xa182, 0x0100, 0x06c0, 0x6908, 0xa184, 0x8000, 0x05e8, 0x2001,
+	0xb89e, 0x2004, 0xa005, 0x1160, 0x6018, 0x2070, 0x7010, 0xa084,
+	0x00ff, 0x0118, 0x7000, 0xd0f4, 0x0118, 0xa184, 0x0800, 0x0560,
+	0x6910, 0xa18a, 0x0001, 0x0610, 0x6914, 0x2069, 0xbcae, 0x6904,
+	0x81ff, 0x1198, 0x690c, 0xa182, 0x0100, 0x02a8, 0x6908, 0x81ff,
+	0x1178, 0x6910, 0xa18a, 0x0001, 0x0288, 0x6918, 0xa18a, 0x0001,
+	0x0298, 0x00d0, 0x6013, 0x0100, 0x00a0, 0x6013, 0x0300, 0x0088,
+	0x6013, 0x0500, 0x0070, 0x6013, 0x0700, 0x0058, 0x6013, 0x0900,
+	0x0040, 0x6013, 0x0b00, 0x0028, 0x6013, 0x0f00, 0x0010, 0x6013,
+	0x2d00, 0xa085, 0x0001, 0x0008, 0xa006, 0x001e, 0x00ee, 0x00de,
+	0x00ce, 0x0005, 0x00c6, 0x00d6, 0x0026, 0x0036, 0x0156, 0x6218,
+	0x2268, 0x6b04, 0xa394, 0x00ff, 0xa286, 0x0006, 0x0190, 0xa286,
+	0x0004, 0x0178, 0xa394, 0xff00, 0x8217, 0xa286, 0x0006, 0x0148,
+	0xa286, 0x0004, 0x0130, 0x00c6, 0x2d60, 0x080c, 0x502a, 0x00ce,
+	0x04c0, 0x2011, 0xbc96, 0xad98, 0x000a, 0x20a9, 0x0004, 0x080c,
+	0x9166, 0x1580, 0x2011, 0xbc9a, 0xad98, 0x0006, 0x20a9, 0x0004,
+	0x080c, 0x9166, 0x1538, 0x0046, 0x0016, 0x6aa0, 0xa294, 0x00ff,
+	0x8227, 0xa006, 0x2009, 0xb653, 0x210c, 0xd1a4, 0x0138, 0x2009,
+	0x0029, 0x080c, 0xb1a4, 0x6800, 0xc0e5, 0x6802, 0x2019, 0x0029,
+	0x080c, 0x6e67, 0x0076, 0x2039, 0x0000, 0x080c, 0x6d74, 0x2c08,
+	0x080c, 0xaf3e, 0x007e, 0x2001, 0x0007, 0x080c, 0x4f9c, 0x001e,
+	0x004e, 0xa006, 0x015e, 0x003e, 0x002e, 0x00de, 0x00ce, 0x0005,
+	0x00d6, 0x2069, 0xbc8e, 0x6800, 0xa086, 0x0800, 0x0118, 0x6013,
+	0x0000, 0x0008, 0xa006, 0x00de, 0x0005, 0x00c6, 0x00f6, 0x0016,
+	0x0026, 0x0036, 0x0156, 0x2079, 0xbc8c, 0x7930, 0x7834, 0x080c,
+	0x2852, 0x11a0, 0x080c, 0x501b, 0x1188, 0x2011, 0xbc90, 0xac98,
+	0x000a, 0x20a9, 0x0004, 0x080c, 0x9166, 0x1140, 0x2011, 0xbc94,
+	0xac98, 0x0006, 0x20a9, 0x0004, 0x080c, 0x9166, 0x015e, 0x003e,
+	0x002e, 0x001e, 0x00fe, 0x00ce, 0x0005, 0x00c6, 0x0006, 0x0016,
+	0x0026, 0x0036, 0x0156, 0x2011, 0xbc83, 0x2204, 0x8211, 0x220c,
+	0x080c, 0x2852, 0x11a0, 0x080c, 0x501b, 0x1188, 0x2011, 0xbc96,
+	0xac98, 0x000a, 0x20a9, 0x0004, 0x080c, 0x9166, 0x1140, 0x2011,
+	0xbc9a, 0xac98, 0x0006, 0x20a9, 0x0004, 0x080c, 0x9166, 0x015e,
+	0x003e, 0x002e, 0x001e, 0x000e, 0x00ce, 0x0005, 0x00e6, 0x00c6,
+	0x0086, 0x0076, 0x0066, 0x0056, 0x0046, 0x0026, 0x0126, 0x2091,
+	0x8000, 0x2740, 0x2029, 0xb8ea, 0x252c, 0x2021, 0xb8f0, 0x2424,
+	0x2061, 0xbe00, 0x2071, 0xb600, 0x7648, 0x7068, 0x81ff, 0x0150,
+	0x0006, 0xa186, 0xb9f5, 0x000e, 0x0128, 0x8001, 0xa602, 0x1a04,
+	0xafbf, 0x0018, 0xa606, 0x0904, 0xafbf, 0x2100, 0xac06, 0x0904,
+	0xafb6, 0x080c, 0xb1cc, 0x0904, 0xafb6, 0x671c, 0xa786, 0x0001,
+	0x0904, 0xafda, 0xa786, 0x0004, 0x0904, 0xafda, 0xa786, 0x0007,
+	0x05e8, 0x2500, 0xac06, 0x05d0, 0x2400, 0xac06, 0x05b8, 0x080c,
+	0xb1dc, 0x15a0, 0x88ff, 0x0118, 0x6050, 0xa906, 0x1578, 0x00d6,
+	0x6000, 0xa086, 0x0004, 0x1120, 0x0016, 0x080c, 0x1952, 0x001e,
+	0xa786, 0x0008, 0x1148, 0x080c, 0x9f14, 0x1130, 0x080c, 0x8ca5,
+	0x00de, 0x080c, 0x9ed9, 0x00d0, 0x6010, 0x2068, 0x080c, 0x9d16,
+	0x0190, 0xa786, 0x0003, 0x1528, 0x6837, 0x0103, 0x6b4a, 0x6847,
+	0x0000, 0x080c, 0xb43c, 0x0016, 0x080c, 0x9f88, 0x080c, 0x547a,
+	0x001e, 0x080c, 0x9ecd, 0x00de, 0x080c, 0x9ed9, 0xace0, 0x0018,
+	0x2001, 0xb617, 0x2004, 0xac02, 0x1210, 0x0804, 0xaf52, 0x012e,
+	0x002e, 0x004e, 0x005e, 0x006e, 0x007e, 0x008e, 0x00ce, 0x00ee,
+	0x0005, 0xa786, 0x0006, 0x1150, 0xa386, 0x0005, 0x0128, 0x080c,
+	0xb43c, 0x080c, 0xb155, 0x08f8, 0x00de, 0x0c00, 0xa786, 0x000a,
+	0x0968, 0x0850, 0x080c, 0xb1dc, 0x19c8, 0x81ff, 0x09b8, 0xa180,
+	0x0001, 0x2004, 0xa086, 0x0018, 0x0130, 0xa180, 0x0001, 0x2004,
+	0xa086, 0x002d, 0x1958, 0x6000, 0xa086, 0x0002, 0x1938, 0x080c,
+	0x9f03, 0x0130, 0x080c, 0x9f14, 0x1908, 0x080c, 0x8ca5, 0x0038,
+	0x080c, 0x2cf7, 0x080c, 0x9f14, 0x1110, 0x080c, 0x8ca5, 0x080c,
+	0x9ed9, 0x0804, 0xafb6, 0x00c6, 0x00e6, 0x0016, 0x2c08, 0x2170,
+	0xa006, 0x080c, 0xb176, 0x001e, 0x0120, 0x601c, 0xa084, 0x000f,
+	0x001b, 0x00ee, 0x00ce, 0x0005, 0xb01c, 0xb01c, 0xb01c, 0xb01c,
+	0xb01c, 0xb01c, 0xb01e, 0xb01c, 0xa006, 0x0005, 0x0046, 0x0016,
+	0x7018, 0xa080, 0x0028, 0x2024, 0xa4a4, 0x00ff, 0x8427, 0x2c00,
+	0x2009, 0x0020, 0x080c, 0xb1a4, 0x001e, 0x004e, 0x0036, 0x2019,
+	0x0002, 0x080c, 0xad9c, 0x003e, 0xa085, 0x0001, 0x0005, 0x2001,
+	0x0001, 0x080c, 0x4f5d, 0x0156, 0x0016, 0x0026, 0x0036, 0x20a9,
+	0x0004, 0x2019, 0xb605, 0x2011, 0xbc96, 0x080c, 0x9166, 0x003e,
+	0x002e, 0x001e, 0x015e, 0xa005, 0x0005, 0x00f6, 0x00e6, 0x00c6,
+	0x0086, 0x0076, 0x0066, 0x0026, 0x0126, 0x2091, 0x8000, 0x2740,
+	0x2061, 0xbe00, 0x2079, 0x0001, 0x8fff, 0x0904, 0xb0ab, 0x2071,
+	0xb600, 0x7648, 0x7068, 0x8001, 0xa602, 0x1a04, 0xb0ab, 0x88ff,
+	0x0128, 0x2800, 0xac06, 0x15b0, 0x2079, 0x0000, 0x080c, 0xb1cc,
+	0x0588, 0x2400, 0xac06, 0x0570, 0x671c, 0xa786, 0x0006, 0x1550,
+	0xa786, 0x0007, 0x0538, 0x88ff, 0x1140, 0x6018, 0xa206, 0x1510,
+	0x85ff, 0x0118, 0x6050, 0xa106, 0x11e8, 0x00d6, 0x6000, 0xa086,
+	0x0004, 0x1150, 0x080c, 0xb3f6, 0x601f, 0x0007, 0x2001, 0xb8b6,
+	0x2004, 0x6016, 0x080c, 0x1952, 0x6010, 0x2068, 0x080c, 0x9d16,
+	0x0120, 0x0046, 0x080c, 0xb155, 0x004e, 0x00de, 0x080c, 0x9ed9,
+	0x88ff, 0x1198, 0xace0, 0x0018, 0x2001, 0xb617, 0x2004, 0xac02,
+	0x1210, 0x0804, 0xb05c, 0xa006, 0x012e, 0x002e, 0x006e, 0x007e,
+	0x008e, 0x00ce, 0x00ee, 0x00fe, 0x0005, 0xa8c5, 0x0001, 0x0ca0,
+	0x0076, 0x0056, 0x0086, 0x2041, 0x0000, 0x2029, 0x0001, 0x2c20,
+	0x2019, 0x0002, 0x6218, 0x0096, 0x2049, 0x0000, 0x080c, 0x81b7,
+	0x009e, 0x008e, 0x2039, 0x0000, 0x080c, 0x825d, 0x080c, 0xb04d,
+	0x005e, 0x007e, 0x0005, 0x0026, 0x0046, 0x0056, 0x0076, 0x00c6,
+	0x0156, 0x2c20, 0x2128, 0x20a9, 0x007f, 0x2009, 0x0000, 0x0016,
+	0x0036, 0x080c, 0x501b, 0x11b0, 0x2c10, 0x0056, 0x0086, 0x2041,
+	0x0000, 0x2508, 0x2029, 0x0001, 0x0096, 0x2049, 0x0000, 0x080c,
+	0x81b7, 0x009e, 0x008e, 0x2039, 0x0000, 0x080c, 0x825d, 0x080c,
+	0xb04d, 0x005e, 0x003e, 0x001e, 0x8108, 0x1f04, 0xb0df, 0x015e,
+	0x00ce, 0x007e, 0x005e, 0x004e, 0x002e, 0x0005, 0x0076, 0x0056,
+	0x6218, 0x0086, 0x2041, 0x0000, 0x2029, 0x0001, 0x2019, 0x0048,
+	0x0096, 0x2049, 0x0000, 0x080c, 0x81b7, 0x009e, 0x008e, 0x2039,
+	0x0000, 0x080c, 0x825d, 0x2c20, 0x080c, 0xb04d, 0x005e, 0x007e,
+	0x0005, 0x0026, 0x0046, 0x0056, 0x0076, 0x00c6, 0x0156, 0x2c20,
+	0x20a9, 0x007f, 0x2009, 0x0000, 0x0016, 0x0036, 0x080c, 0x501b,
+	0x11c0, 0x2c10, 0x0086, 0x2041, 0x0000, 0x2828, 0x0046, 0x2021,
+	0x0001, 0x080c, 0xb3d8, 0x004e, 0x0096, 0x2049, 0x0000, 0x080c,
+	0x81b7, 0x009e, 0x008e, 0x2039, 0x0000, 0x080c, 0x825d, 0x080c,
+	0xb04d, 0x003e, 0x001e, 0x8108, 0x1f04, 0xb12c, 0x015e, 0x00ce,
+	0x007e, 0x005e, 0x004e, 0x002e, 0x0005, 0x0016, 0x00f6, 0x3800,
+	0xd08c, 0x0130, 0xad82, 0x1000, 0x02b0, 0xad82, 0xb600, 0x0230,
+	0xad82, 0xee00, 0x0280, 0xad82, 0xffff, 0x1268, 0x6800, 0xa07d,
+	0x0138, 0x6803, 0x0000, 0x6b52, 0x080c, 0x547a, 0x2f68, 0x0cb0,
+	0x6b52, 0x080c, 0x547a, 0x00fe, 0x001e, 0x0005, 0x00e6, 0x0046,
+	0x0036, 0x2061, 0xbe00, 0xa005, 0x1138, 0x2071, 0xb600, 0x7448,
+	0x7068, 0x8001, 0xa402, 0x12d8, 0x2100, 0xac06, 0x0168, 0x6000,
+	0xa086, 0x0000, 0x0148, 0x6008, 0xa206, 0x1130, 0x6018, 0xa1a0,
+	0x0006, 0x2424, 0xa406, 0x0140, 0xace0, 0x0018, 0x2001, 0xb617,
+	0x2004, 0xac02, 0x1220, 0x0c40, 0xa085, 0x0001, 0x0008, 0xa006,
+	0x003e, 0x004e, 0x00ee, 0x0005, 0x00d6, 0x0006, 0x080c, 0x15fd,
+	0x000e, 0x090c, 0x151a, 0x6837, 0x010d, 0x685e, 0x0026, 0x2010,
+	0x080c, 0x9d06, 0x2001, 0x0000, 0x0120, 0x2200, 0xa080, 0x0014,
+	0x2004, 0x002e, 0x684a, 0x6956, 0x6c46, 0x684f, 0x0000, 0x2001,
+	0xb8be, 0x2004, 0x6852, 0xa006, 0x68b2, 0x6802, 0x683a, 0x685a,
+	0x080c, 0x547a, 0x00de, 0x0005, 0x6700, 0xa786, 0x0000, 0x0158,
+	0xa786, 0x0001, 0x0140, 0xa786, 0x000a, 0x0128, 0xa786, 0x0009,
+	0x0110, 0xa085, 0x0001, 0x0005, 0x00e6, 0x6018, 0x2070, 0x70a0,
+	0xa206, 0x00ee, 0x0005, 0x0016, 0x6004, 0xa08e, 0x001e, 0x11a0,
+	0x8007, 0x6130, 0xa18c, 0x00ff, 0xa105, 0x6032, 0x6007, 0x0085,
+	0x6003, 0x000b, 0x601f, 0x0005, 0x2001, 0xb8b7, 0x2004, 0x6016,
+	0x080c, 0x6cff, 0x080c, 0x71e5, 0x001e, 0x0005, 0xe000, 0xe000,
+	0x0005, 0x6020, 0xd0e4, 0x0158, 0xd0cc, 0x0118, 0x080c, 0x9ff1,
+	0x0030, 0x080c, 0xb3f6, 0x080c, 0x6b61, 0x080c, 0x86a4, 0x0005,
+	0xa280, 0x0007, 0x2004, 0xa084, 0x000f, 0x0002, 0xb21f, 0xb21f,
+	0xb21f, 0xb224, 0xb21f, 0xb221, 0xb221, 0xb21f, 0xb221, 0xa006,
+	0x0005, 0x00c6, 0x2260, 0x00ce, 0xa085, 0x0001, 0x0005, 0xa280,
+	0x0007, 0x2004, 0xa084, 0x000f, 0x0002, 0xb236, 0xb236, 0xb236,
+	0xb236, 0xb236, 0xb236, 0xb241, 0xb236, 0xb236, 0x6007, 0x003b,
+	0x602b, 0x0009, 0x6013, 0x2a00, 0x6003, 0x0001, 0x080c, 0x6cff,
+	0x0005, 0x00c6, 0x2260, 0x080c, 0xb3f6, 0x603f, 0x0000, 0x6020,
+	0xc0f4, 0xc0cc, 0x6022, 0x6037, 0x0000, 0x00ce, 0x00d6, 0x2268,
+	0xa186, 0x0007, 0x1904, 0xb29c, 0x6810, 0xa005, 0x0138, 0xa080,
+	0x0013, 0x2004, 0xd0fc, 0x1110, 0x00de, 0x08c0, 0x6007, 0x003a,
+	0x6003, 0x0001, 0x080c, 0x6cff, 0x080c, 0x71e5, 0x00c6, 0x2d60,
+	0x6100, 0xa186, 0x0002, 0x1904, 0xb325, 0x6010, 0xa005, 0x1138,
+	0x6000, 0xa086, 0x0007, 0x190c, 0x151a, 0x0804, 0xb325, 0xa08c,
+	0xf000, 0x1130, 0x0028, 0x2068, 0x6800, 0xa005, 0x1de0, 0x2d00,
+	0xa080, 0x0013, 0x2004, 0xa084, 0x0003, 0xa086, 0x0002, 0x1180,
+	0x6010, 0x2068, 0x684c, 0xc0dc, 0xc0f4, 0x684e, 0x6850, 0xc0f4,
+	0xc0fc, 0x6852, 0x2009, 0x0043, 0x080c, 0xac12, 0x0804, 0xb325,
+	0x2009, 0x0041, 0x0804, 0xb31f, 0xa186, 0x0005, 0x15f0, 0x6810,
+	0xa080, 0x0013, 0x2004, 0xd0bc, 0x1118, 0x00de, 0x0804, 0xb236,
+	0xd0b4, 0x0128, 0xd0fc, 0x090c, 0x151a, 0x0804, 0xb254, 0x6007,
+	0x003a, 0x6003, 0x0001, 0x080c, 0x6cff, 0x080c, 0x71e5, 0x00c6,
+	0x2d60, 0x6100, 0xa186, 0x0002, 0x0120, 0xa186, 0x0004, 0x1904,
+	0xb325, 0x2071, 0xb924, 0x7000, 0xa086, 0x0003, 0x1128, 0x7004,
+	0xac06, 0x1110, 0x7003, 0x0000, 0x6810, 0xa080, 0x0013, 0x200c,
+	0xc1f4, 0xc1dc, 0x2102, 0x8000, 0x200c, 0xc1f4, 0xc1fc, 0xc1bc,
+	0x2102, 0x2009, 0x0042, 0x0804, 0xb31f, 0x0036, 0x00d6, 0x00d6,
+	0x080c, 0x15fd, 0x003e, 0x090c, 0x151a, 0x6837, 0x010d, 0x6803,
+	0x0000, 0x683b, 0x0000, 0x685b, 0x0000, 0x6b5e, 0x6857, 0x0045,
+	0x2c00, 0x6862, 0x6034, 0x6872, 0x2360, 0x6020, 0xc0dd, 0x6022,
+	0x6018, 0xa080, 0x0028, 0x2004, 0xa084, 0x00ff, 0x8007, 0x6350,
+	0x6b4a, 0x6846, 0x684f, 0x0000, 0x6853, 0x0000, 0x6d6a, 0x6e66,
+	0x686f, 0x0001, 0x080c, 0x547a, 0x2019, 0x0045, 0x6008, 0x2068,
+	0x080c, 0xad9c, 0x2d00, 0x600a, 0x601f, 0x0006, 0x6003, 0x0007,
+	0x6017, 0x0000, 0x603f, 0x0000, 0x00de, 0x003e, 0x0038, 0x603f,
+	0x0000, 0x6003, 0x0007, 0x080c, 0xac12, 0x00ce, 0x00de, 0x0005,
+	0xa186, 0x0013, 0x1128, 0x6004, 0xa082, 0x0085, 0x2008, 0x00c2,
+	0xa186, 0x0027, 0x1178, 0x080c, 0x7102, 0x0036, 0x00d6, 0x6010,
+	0x2068, 0x2019, 0x0004, 0x080c, 0xb155, 0x00de, 0x003e, 0x080c,
+	0x71e5, 0x0005, 0xa186, 0x0014, 0x0d70, 0x080c, 0x86ef, 0x0005,
+	0xb351, 0xb34f, 0xb34f, 0xb34f, 0xb34f, 0xb34f, 0xb351, 0x080c,
+	0x151a, 0x080c, 0x7102, 0x6003, 0x000c, 0x080c, 0x71e5, 0x0005,
+	0xa182, 0x008c, 0x1220, 0xa182, 0x0085, 0x0208, 0x001a, 0x080c,
+	0x86ef, 0x0005, 0xb369, 0xb369, 0xb369, 0xb369, 0xb36b, 0xb389,
+	0xb369, 0x080c, 0x151a, 0x00d6, 0x2c68, 0x080c, 0x864e, 0x01a0,
+	0x6003, 0x0001, 0x6007, 0x001e, 0x2009, 0xbc8e, 0x210c, 0x6136,
+	0x2009, 0xbc8f, 0x210c, 0x613a, 0x600b, 0xffff, 0x6918, 0x611a,
+	0x601f, 0x0004, 0x080c, 0x6cff, 0x2d60, 0x080c, 0x86a4, 0x00de,
+	0x0005, 0x080c, 0x86a4, 0x0005, 0x00e6, 0x6018, 0x2070, 0x7000,
+	0xd0ec, 0x00ee, 0x0005, 0x6010, 0xa08c, 0xf000, 0x0904, 0xb3d7,
+	0xa080, 0x0013, 0x200c, 0xd1ec, 0x05d0, 0x2001, 0xb672, 0x2004,
+	0xd0ec, 0x05a8, 0x6003, 0x0002, 0x6020, 0xc0e5, 0x6022, 0xd1ac,
+	0x0180, 0x00f6, 0x2c78, 0x080c, 0x5373, 0x00fe, 0x0150, 0x2001,
+	0xb8b8, 0x2004, 0x603e, 0x2009, 0xb672, 0x210c, 0xd1f4, 0x11e8,
+	0x0080, 0x2009, 0xb672, 0x210c, 0xd1f4, 0x0128, 0x6020, 0xc0e4,
+	0x6022, 0xa006, 0x00a0, 0x2001, 0xb8b8, 0x200c, 0x8103, 0xa100,
+	0x603e, 0x6018, 0xa088, 0x002b, 0x2104, 0xa005, 0x0118, 0xa088,
+	0x0003, 0x0cd0, 0x2c0a, 0x600f, 0x0000, 0xa085, 0x0001, 0x0005,
+	0x0016, 0x00c6, 0x00e6, 0x6150, 0xa2f0, 0x002b, 0x2e04, 0x2060,
+	0x8cff, 0x0180, 0x84ff, 0x1118, 0x6050, 0xa106, 0x1138, 0x600c,
+	0x2072, 0x080c, 0x6b61, 0x080c, 0x86a4, 0x0010, 0xacf0, 0x0003,
+	0x2e64, 0x0c70, 0x00ee, 0x00ce, 0x001e, 0x0005, 0x00d6, 0x6018,
+	0xa0e8, 0x002b, 0x2d04, 0xa005, 0x0140, 0xac06, 0x0120, 0x2d04,
+	0xa0e8, 0x0003, 0x0cb8, 0x600c, 0x206a, 0x00de, 0x0005, 0x0026,
+	0x0036, 0x0156, 0x2011, 0xb628, 0x2204, 0xa084, 0x00ff, 0x2019,
+	0xbc8e, 0x2334, 0xa636, 0x11d8, 0x8318, 0x2334, 0x2204, 0xa084,
+	0xff00, 0xa636, 0x11a0, 0x2011, 0xbc90, 0x6018, 0xa098, 0x000a,
+	0x20a9, 0x0004, 0x080c, 0x9166, 0x1150, 0x2011, 0xbc94, 0x6018,
+	0xa098, 0x0006, 0x20a9, 0x0004, 0x080c, 0x9166, 0x1100, 0x015e,
+	0x003e, 0x002e, 0x0005, 0x00e6, 0x2071, 0xb600, 0x080c, 0x4c28,
+	0x080c, 0x2aed, 0x00ee, 0x0005, 0x00e6, 0x6018, 0x2070, 0x7000,
+	0xd0fc, 0x0108, 0x0011, 0x00ee, 0x0005, 0x6850, 0xc0e5, 0x6852,
+	0x0005, 0x00e6, 0x00c6, 0x0076, 0x0066, 0x0056, 0x0046, 0x0026,
+	0x0016, 0x0126, 0x2091, 0x8000, 0x2029, 0xb8ea, 0x252c, 0x2021,
+	0xb8f0, 0x2424, 0x2061, 0xbe00, 0x2071, 0xb600, 0x7648, 0x7068,
+	0xa606, 0x0578, 0x671c, 0xa786, 0x0001, 0x0118, 0xa786, 0x0008,
+	0x1500, 0x2500, 0xac06, 0x01e8, 0x2400, 0xac06, 0x01d0, 0x080c,
+	0xb1cc, 0x01b8, 0x080c, 0xb1dc, 0x11a0, 0x6000, 0xa086, 0x0004,
+	0x1120, 0x0016, 0x080c, 0x1952, 0x001e, 0x080c, 0x9f03, 0x1110,
+	0x080c, 0x2cf7, 0x080c, 0x9f14, 0x1110, 0x080c, 0x8ca5, 0x080c,
+	0x9ed9, 0xace0, 0x0018, 0x2001, 0xb617, 0x2004, 0xac02, 0x1208,
+	0x0858, 0x012e, 0x001e, 0x002e, 0x004e, 0x005e, 0x006e, 0x007e,
+	0x00ce, 0x00ee, 0x0005, 0x0126, 0x0006, 0x00e6, 0x0016, 0x2091,
+	0x8000, 0x2071, 0xb640, 0xd5a4, 0x0118, 0x7034, 0x8000, 0x7036,
+	0xd5b4, 0x0118, 0x7030, 0x8000, 0x7032, 0xd5ac, 0x0178, 0x2500,
+	0xa084, 0x0007, 0xa08e, 0x0003, 0x0148, 0xa08e, 0x0004, 0x0130,
+	0xa08e, 0x0005, 0x0118, 0x2071, 0xb64a, 0x04c9, 0x001e, 0x00ee,
+	0x000e, 0x012e, 0x0005, 0x0126, 0x0006, 0x00e6, 0x0016, 0x2091,
+	0x8000, 0x2071, 0xb640, 0xd5a4, 0x0118, 0x7034, 0x8000, 0x7036,
+	0xd5b4, 0x0118, 0x7030, 0x8000, 0x7032, 0xd5ac, 0x0178, 0x2500,
+	0xa084, 0x0007, 0xa08e, 0x0003, 0x0148, 0xa08e, 0x0004, 0x0130,
+	0xa08e, 0x0005, 0x0118, 0x2071, 0xb64a, 0x0089, 0x001e, 0x00ee,
+	0x000e, 0x012e, 0x0005, 0x0126, 0x0006, 0x00e6, 0x2091, 0x8000,
+	0x2071, 0xb642, 0x0021, 0x00ee, 0x000e, 0x012e, 0x0005, 0x2e04,
+	0x8000, 0x2072, 0x1220, 0x8e70, 0x2e04, 0x8000, 0x2072, 0x0005,
+	0x00e6, 0x2071, 0xb640, 0x0c99, 0x00ee, 0x0005, 0x00e6, 0x2071,
+	0xb644, 0x0c69, 0x00ee, 0x0005, 0x0126, 0x0006, 0x00e6, 0x2091,
+	0x8000, 0x2071, 0xb640, 0x7044, 0x8000, 0x7046, 0x00ee, 0x000e,
+	0x012e, 0x0005, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020,
+	0x0040, 0x0080, 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000,
+	0x4000, 0x8000, 0xdb06
 };
 #ifdef UNIQUE_FW_NAME
-unsigned short fw2200tp_length01 = 0xa46f;
+unsigned short fw2200tp_length01 = 0xa52b;
 #else
-unsigned short risc_code_length01 = 0xa46f;
+unsigned short risc_code_length01 = 0xa52b;
 #endif
 
diff --git a/drivers/scsi/qla2xxx/ql2300.c b/drivers/scsi/qla2xxx/ql2300.c
--- a/drivers/scsi/qla2xxx/ql2300.c
+++ b/drivers/scsi/qla2xxx/ql2300.c
@@ -1,7 +1,7 @@
 /*
  * QLogic ISP2300 device driver for Linux 2.6.x
  * Copyright (C) 2003 Christoph Hellwig.
- * Copyright (C) 2003-2004 QLogic Corporation (www.qlogic.com)
+ * Copyright (C) 2003-2005 QLogic Corporation (www.qlogic.com)
  *
  * Released under GPL v2.
  */
diff --git a/drivers/scsi/qla2xxx/ql2300_fw.c b/drivers/scsi/qla2xxx/ql2300_fw.c
--- a/drivers/scsi/qla2xxx/ql2300_fw.c
+++ b/drivers/scsi/qla2xxx/ql2300_fw.c
@@ -2,7 +2,7 @@
  *                  QLOGIC LINUX SOFTWARE
  *
  * QLogic ISP2x00 device driver for Linux 2.6.x
- * Copyright (C) 2003 QLogic Corporation
+ * Copyright (C) 2005 QLogic Corporation
  * (www.qlogic.com)
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -18,7 +18,7 @@
  ******************************************************************************/
 
 /*
- *	Firmware Version 3.03.08 (10:02 Nov 12, 2004)
+ *	Firmware Version 3.03.15 (10:03 May 26, 2005)
  */
 
 #ifdef UNIQUE_FW_NAME
@@ -28,15 +28,15 @@ unsigned short risc_code_version = 3*102
 #endif
 
 #ifdef UNIQUE_FW_NAME
-unsigned char fw2300ipx_version_str[] = {3, 3, 8};
+unsigned char fw2300ipx_version_str[] = {3, 3,15};
 #else
-unsigned char firmware_version[] = {3, 3, 8};
+unsigned char firmware_version[] = {3, 3,15};
 #endif
 
 #ifdef UNIQUE_FW_NAME
-#define fw2300ipx_VERSION_STRING "3.03.08"
+#define fw2300ipx_VERSION_STRING "3.03.15"
 #else
-#define FW_VERSION_STRING "3.03.08"
+#define FW_VERSION_STRING "3.03.15"
 #endif
 
 #ifdef UNIQUE_FW_NAME
@@ -50,12 +50,12 @@ unsigned short fw2300ipx_code01[] = { 
 #else
 unsigned short risc_code01[] = { 
 #endif
-	0x0470, 0x0000, 0x0000, 0xeb57, 0x0000, 0x0003, 0x0003, 0x0008,
+	0x0470, 0x0000, 0x0000, 0xed9d, 0x0000, 0x0003, 0x0003, 0x000f,
 	0x0137, 0x2043, 0x4f50, 0x5952, 0x4947, 0x4854, 0x2032, 0x3030,
 	0x3120, 0x514c, 0x4f47, 0x4943, 0x2043, 0x4f52, 0x504f, 0x5241,
 	0x5449, 0x4f4e, 0x2049, 0x5350, 0x3233, 0x3030, 0x2046, 0x6972,
 	0x6d77, 0x6172, 0x6520, 0x2056, 0x6572, 0x7369, 0x6f6e, 0x2030,
-	0x332e, 0x3033, 0x2e30, 0x3820, 0x2020, 0x2020, 0x2400, 0x20a9,
+	0x332e, 0x3033, 0x2e31, 0x3520, 0x2020, 0x2020, 0x2400, 0x20a9,
 	0x000f, 0x2001, 0x0000, 0x400f, 0x2091, 0x2200, 0x20a9, 0x000f,
 	0x2001, 0x0000, 0x400f, 0x2091, 0x2400, 0x20a9, 0x000f, 0x2001,
 	0x0000, 0x400f, 0x2091, 0x2600, 0x20a9, 0x000f, 0x2001, 0x0000,
@@ -64,1815 +64,1825 @@ unsigned short risc_code01[] = { 
 	0x2c00, 0x20a9, 0x000f, 0x2001, 0x0000, 0x400f, 0x2091, 0x2e00,
 	0x20a9, 0x000f, 0x2001, 0x0000, 0x400f, 0x2091, 0x2000, 0x2001,
 	0x0000, 0x20c1, 0x0004, 0x20c9, 0x1bff, 0x2059, 0x0000, 0x2b78,
-	0x7883, 0x0004, 0x2089, 0x2d88, 0x2051, 0x1800, 0x2a70, 0x20e1,
-	0x0001, 0x20e9, 0x0001, 0x2009, 0x0000, 0x080c, 0x0e51, 0x2029,
+	0x7883, 0x0004, 0x2089, 0x2db5, 0x2051, 0x1800, 0x2a70, 0x20e1,
+	0x0001, 0x20e9, 0x0001, 0x2009, 0x0000, 0x080c, 0x0e52, 0x2029,
 	0x4d00, 0x2031, 0xffff, 0x2039, 0x4cd0, 0x2021, 0x0200, 0x20e9,
 	0x0001, 0x20a1, 0x0000, 0x20a9, 0x0800, 0x900e, 0x4104, 0x20e9,
 	0x0001, 0x20a1, 0x1000, 0x900e, 0x2001, 0x0cc0, 0x9084, 0x0fff,
 	0x20a8, 0x4104, 0x2001, 0x0000, 0x9086, 0x0000, 0x0120, 0x21a8,
 	0x4104, 0x8001, 0x1de0, 0x756e, 0x7672, 0x776a, 0x7476, 0x747a,
-	0x00e6, 0x2071, 0x1aca, 0x2472, 0x00ee, 0x20a1, 0x1cd0, 0x7170,
+	0x00e6, 0x2071, 0x1ad2, 0x2472, 0x00ee, 0x20a1, 0x1cd0, 0x7170,
 	0x810d, 0x810d, 0x810d, 0x810d, 0x918c, 0x000f, 0x2001, 0x0001,
 	0x9112, 0x900e, 0x21a8, 0x4104, 0x8211, 0x1de0, 0x7170, 0x3400,
 	0x8001, 0x9102, 0x0120, 0x0218, 0x20a8, 0x900e, 0x4104, 0x2009,
 	0x1800, 0x810d, 0x810d, 0x810d, 0x810d, 0x810d, 0x918c, 0x001f,
 	0x2001, 0x0001, 0x9112, 0x20e9, 0x0001, 0x20a1, 0x0800, 0x900e,
-	0x20a9, 0x0800, 0x4104, 0x8211, 0x1dd8, 0x080c, 0x0f17, 0x080c,
-	0x60bb, 0x080c, 0xaed9, 0x080c, 0x10ce, 0x080c, 0x12ed, 0x080c,
-	0x1be2, 0x080c, 0x0d69, 0x080c, 0x1053, 0x080c, 0x3484, 0x080c,
-	0x7738, 0x080c, 0x6a30, 0x080c, 0x87b3, 0x080c, 0x84e7, 0x080c,
-	0x24b6, 0x080c, 0x9057, 0x080c, 0x7e03, 0x080c, 0x22ef, 0x080c,
-	0x2423, 0x080c, 0x24ab, 0x2091, 0x3009, 0x7883, 0x0000, 0x1004,
+	0x20a9, 0x0800, 0x4104, 0x8211, 0x1dd8, 0x080c, 0x0f26, 0x080c,
+	0x612f, 0x080c, 0xb07d, 0x080c, 0x10dd, 0x080c, 0x12fc, 0x080c,
+	0x1bf8, 0x080c, 0x0d57, 0x080c, 0x1062, 0x080c, 0x34b1, 0x080c,
+	0x785c, 0x080c, 0x6ab0, 0x080c, 0x892f, 0x080c, 0x8610, 0x080c,
+	0x24d0, 0x080c, 0x91db, 0x080c, 0x7f2c, 0x080c, 0x2309, 0x080c,
+	0x243d, 0x080c, 0x24c5, 0x2091, 0x3009, 0x7883, 0x0000, 0x1004,
 	0x091f, 0x7880, 0x9086, 0x0002, 0x1190, 0x7883, 0x4000, 0x7837,
 	0x4000, 0x7833, 0x0010, 0x0e04, 0x0913, 0x2091, 0x5000, 0x2091,
-	0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x119b, 0x2071,
+	0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11aa, 0x2071,
 	0x1800, 0x7003, 0x0000, 0x2071, 0x1800, 0x7000, 0x908e, 0x0003,
-	0x1178, 0x080c, 0x4c44, 0x080c, 0x34ab, 0x080c, 0x77a9, 0x080c,
-	0x6f61, 0x080c, 0x8896, 0x080c, 0x8510, 0x080c, 0x2cf2, 0x0c58,
-	0x000b, 0x0c78, 0x0944, 0x0945, 0x0ae7, 0x0942, 0x0bae, 0x0d68,
-	0x0d68, 0x0d68, 0x080c, 0x0dd5, 0x0005, 0x0126, 0x00f6, 0x2091,
-	0x8000, 0x7000, 0x9086, 0x0001, 0x1904, 0x0aba, 0x080c, 0x576c,
-	0x1130, 0x0026, 0x2011, 0x0080, 0x080c, 0x0edf, 0x002e, 0x080c,
-	0x743e, 0x0150, 0x080c, 0x7461, 0x15a0, 0x2079, 0x0100, 0x7828,
-	0x9085, 0x1800, 0x782a, 0x0468, 0x080c, 0x736a, 0x7000, 0x9086,
-	0x0001, 0x1904, 0x0aba, 0x7098, 0x9086, 0x0028, 0x1904, 0x0aba,
-	0x080c, 0x84d0, 0x080c, 0x84c2, 0x2001, 0x0161, 0x2003, 0x0001,
-	0x2079, 0x0100, 0x7827, 0xffff, 0x7a28, 0x9295, 0x5e2f, 0x7a2a,
-	0x2011, 0x72ce, 0x080c, 0x85b0, 0x2011, 0x72c1, 0x080c, 0x868a,
-	0x2011, 0x5f16, 0x080c, 0x85b0, 0x2011, 0x8030, 0x901e, 0x7396,
-	0x04d0, 0x080c, 0x57c3, 0x2079, 0x0100, 0x7844, 0x9005, 0x1904,
-	0x0aba, 0x2011, 0x5f16, 0x080c, 0x85b0, 0x2011, 0x72ce, 0x080c,
-	0x85b0, 0x2011, 0x72c1, 0x080c, 0x868a, 0x2001, 0x0265, 0x2001,
-	0x0205, 0x2003, 0x0000, 0x7840, 0x9084, 0xfffb, 0x7842, 0x2001,
-	0x19a5, 0x2004, 0x9005, 0x1140, 0x00c6, 0x2061, 0x0100, 0x080c,
-	0x6063, 0x00ce, 0x0804, 0x0aba, 0x780f, 0x006b, 0x7a28, 0x080c,
-	0x7446, 0x0118, 0x9295, 0x5e2f, 0x0010, 0x9295, 0x402f, 0x7a2a,
-	0x2011, 0x8010, 0x73d8, 0x2001, 0x19a6, 0x2003, 0x0001, 0x080c,
-	0x2b97, 0x080c, 0x4b7f, 0x7248, 0xc284, 0x724a, 0x2001, 0x180c,
-	0x200c, 0xc1ac, 0xc1cc, 0x2102, 0x080c, 0xa613, 0x2011, 0x0004,
-	0x080c, 0xcc96, 0x080c, 0x68bc, 0x080c, 0x743e, 0x1120, 0x080c,
-	0x2bdb, 0x02e0, 0x0400, 0x080c, 0x606a, 0x0140, 0x7097, 0x0001,
-	0x70d3, 0x0000, 0x080c, 0x5990, 0x0804, 0x0aba, 0x080c, 0x575d,
-	0xd094, 0x0188, 0x2011, 0x180c, 0x2204, 0xc0cd, 0x2012, 0x080c,
-	0x5761, 0xd0d4, 0x1118, 0x080c, 0x2bdb, 0x1270, 0x2011, 0x180c,
-	0x2204, 0xc0bc, 0x00a8, 0x080c, 0x5761, 0xd0d4, 0x1db8, 0x2011,
-	0x180c, 0x2204, 0xc0bd, 0x0060, 0x2011, 0x180c, 0x2204, 0xc0bd,
-	0x2012, 0x080c, 0x6a04, 0x1128, 0xd0a4, 0x0118, 0x2204, 0xc0fd,
-	0x2012, 0x080c, 0x69ca, 0x0120, 0x7a0c, 0xc2b4, 0x7a0e, 0x00a8,
-	0x707f, 0x0000, 0x080c, 0x743e, 0x1130, 0x70b0, 0x9005, 0x1168,
-	0x080c, 0xd0d9, 0x0050, 0x080c, 0xd0d9, 0x70dc, 0xd09c, 0x1128,
-	0x70b0, 0x9005, 0x0110, 0x080c, 0x6040, 0x70e7, 0x0000, 0x70e3,
-	0x0000, 0x70a7, 0x0000, 0x080c, 0x2be3, 0x0228, 0x2011, 0x0101,
-	0x2204, 0xc0c4, 0x2012, 0x72dc, 0x080c, 0x743e, 0x1178, 0x9016,
-	0x0016, 0x080c, 0x2994, 0x2019, 0x196c, 0x211a, 0x001e, 0x705f,
-	0xffff, 0x7063, 0x00ef, 0x7083, 0x0000, 0x0020, 0x2019, 0x196c,
-	0x201b, 0x0000, 0x2079, 0x1847, 0x7804, 0xd0ac, 0x0108, 0xc295,
-	0x72de, 0x080c, 0x743e, 0x0118, 0x9296, 0x0004, 0x0548, 0x2011,
-	0x0001, 0x080c, 0xcc96, 0x70ab, 0x0000, 0x70af, 0xffff, 0x7003,
-	0x0002, 0x2079, 0x0100, 0x7827, 0x0003, 0x7828, 0x9085, 0x0003,
-	0x782a, 0x00fe, 0x080c, 0x2ff5, 0x2011, 0x0005, 0x080c, 0xa722,
-	0x080c, 0x9763, 0x080c, 0x743e, 0x0148, 0x00c6, 0x2061, 0x0100,
-	0x0016, 0x080c, 0x2994, 0x61e2, 0x001e, 0x00ce, 0x012e, 0x0420,
-	0x70ab, 0x0000, 0x70af, 0xffff, 0x7003, 0x0002, 0x00f6, 0x2079,
-	0x0100, 0x7827, 0x0003, 0x7828, 0x9085, 0x0003, 0x782a, 0x00fe,
-	0x2011, 0x0005, 0x080c, 0xa722, 0x080c, 0x9763, 0x080c, 0x743e,
-	0x0148, 0x00c6, 0x2061, 0x0100, 0x0016, 0x080c, 0x2994, 0x61e2,
-	0x001e, 0x00ce, 0x00fe, 0x012e, 0x0005, 0x00c6, 0x00b6, 0x080c,
-	0x743e, 0x1118, 0x20a9, 0x0800, 0x0010, 0x20a9, 0x0782, 0x080c,
-	0x743e, 0x1110, 0x900e, 0x0010, 0x2009, 0x007e, 0x86ff, 0x0138,
-	0x9180, 0x1000, 0x2004, 0x905d, 0x0110, 0xb800, 0xd0bc, 0x090c,
-	0x331a, 0x8108, 0x1f04, 0x0ace, 0x707f, 0x0000, 0x7080, 0x9084,
-	0x00ff, 0x7082, 0x70b3, 0x0000, 0x00be, 0x00ce, 0x0005, 0x00b6,
-	0x0126, 0x2091, 0x8000, 0x7000, 0x9086, 0x0002, 0x1904, 0x0bab,
-	0x70ac, 0x9086, 0xffff, 0x0130, 0x080c, 0x2ff5, 0x080c, 0x9763,
-	0x0804, 0x0bab, 0x70dc, 0xd0ac, 0x1110, 0xd09c, 0x0558, 0xd084,
-	0x0548, 0x0006, 0x2001, 0x0103, 0x2003, 0x002b, 0x000e, 0xd08c,
-	0x0508, 0x080c, 0x337d, 0x11d0, 0x70e0, 0x9086, 0xffff, 0x01b0,
-	0x080c, 0x318a, 0x080c, 0x9763, 0x70dc, 0xd094, 0x1904, 0x0bab,
-	0x2011, 0x0001, 0x080c, 0xd388, 0x0110, 0x2011, 0x0003, 0x901e,
-	0x080c, 0x31c4, 0x080c, 0x9763, 0x0804, 0x0bab, 0x70e4, 0x9005,
-	0x1904, 0x0bab, 0x70a8, 0x9005, 0x1904, 0x0bab, 0x70dc, 0xd0a4,
-	0x0118, 0xd0b4, 0x0904, 0x0bab, 0x080c, 0x69ca, 0x1904, 0x0bab,
-	0x080c, 0x6a1d, 0x1904, 0x0bab, 0x080c, 0x6a04, 0x01c0, 0x0156,
-	0x00c6, 0x20a9, 0x007f, 0x900e, 0x0016, 0x080c, 0x6699, 0x1118,
-	0xb800, 0xd0ec, 0x1138, 0x001e, 0x8108, 0x1f04, 0x0b44, 0x00ce,
-	0x015e, 0x0028, 0x001e, 0x00ce, 0x015e, 0x0804, 0x0bab, 0x0006,
-	0x2001, 0x0103, 0x2003, 0x002b, 0x000e, 0x2011, 0x19b2, 0x080c,
-	0x0f87, 0x2011, 0x19cc, 0x080c, 0x0f87, 0x7030, 0xc08c, 0x7032,
-	0x7003, 0x0003, 0x70af, 0xffff, 0x080c, 0x576c, 0x1130, 0x0026,
-	0x2011, 0x0040, 0x080c, 0x0edf, 0x002e, 0x9006, 0x080c, 0x2828,
-	0x080c, 0x337d, 0x0118, 0x080c, 0x4d1c, 0x0050, 0x0036, 0x0046,
-	0x2019, 0xffff, 0x2021, 0x0006, 0x080c, 0x4d36, 0x004e, 0x003e,
-	0x00f6, 0x2079, 0x0100, 0x080c, 0x7461, 0x0150, 0x080c, 0x743e,
-	0x7828, 0x0118, 0x9084, 0xe1ff, 0x0010, 0x9084, 0xffdf, 0x782a,
-	0x00fe, 0x2001, 0x19e7, 0x2004, 0x9086, 0x0005, 0x1120, 0x2011,
-	0x0000, 0x080c, 0xa722, 0x2011, 0x0000, 0x080c, 0xa72c, 0x080c,
-	0x9763, 0x080c, 0x9891, 0x012e, 0x00be, 0x0005, 0x0016, 0x0046,
-	0x00f6, 0x0126, 0x2091, 0x8000, 0x2079, 0x0100, 0x7904, 0x918c,
-	0xfffd, 0x7906, 0x2009, 0x00f7, 0x080c, 0x6029, 0x7940, 0x918c,
-	0x0010, 0x7942, 0x7924, 0xd1b4, 0x0110, 0x7827, 0x0040, 0xd19c,
-	0x0110, 0x7827, 0x0008, 0x0006, 0x0036, 0x0156, 0x7954, 0xd1ac,
-	0x1904, 0x0c3b, 0x2001, 0x19a6, 0x2004, 0x9005, 0x1518, 0x080c,
-	0x2c5e, 0x1148, 0x2001, 0x0001, 0x080c, 0x2bc6, 0x2001, 0x0001,
-	0x080c, 0x2ba9, 0x00b8, 0x080c, 0x2c66, 0x1138, 0x9006, 0x080c,
-	0x2bc6, 0x9006, 0x080c, 0x2ba9, 0x0068, 0x080c, 0x2c6e, 0x1d50,
-	0x2001, 0x1997, 0x2004, 0xd0fc, 0x0108, 0x0020, 0x080c, 0x29c0,
-	0x0804, 0x0d1a, 0x080c, 0x744f, 0x0148, 0x080c, 0x7461, 0x1118,
-	0x080c, 0x7733, 0x0050, 0x080c, 0x7446, 0x0dd0, 0x080c, 0x772e,
-	0x080c, 0x7724, 0x080c, 0x736a, 0x0058, 0x080c, 0x743e, 0x0140,
-	0x2009, 0x00f8, 0x080c, 0x6029, 0x7843, 0x0090, 0x7843, 0x0010,
-	0x20a9, 0x09c4, 0x7820, 0xd09c, 0x1138, 0x080c, 0x743e, 0x0138,
-	0x7824, 0xd0ac, 0x1904, 0x0d1f, 0x1f04, 0x0c1a, 0x0070, 0x7824,
-	0x080c, 0x7458, 0x0118, 0xd0ac, 0x1904, 0x0d1f, 0x9084, 0x1800,
-	0x0d98, 0x7003, 0x0001, 0x0804, 0x0d1f, 0x2001, 0x0001, 0x080c,
-	0x2828, 0x0804, 0x0d32, 0x2001, 0x19a6, 0x2004, 0x9005, 0x1518,
-	0x080c, 0x2c5e, 0x1148, 0x2001, 0x0001, 0x080c, 0x2bc6, 0x2001,
-	0x0001, 0x080c, 0x2ba9, 0x00b8, 0x080c, 0x2c66, 0x1138, 0x9006,
-	0x080c, 0x2bc6, 0x9006, 0x080c, 0x2ba9, 0x0068, 0x080c, 0x2c6e,
-	0x1d50, 0x2001, 0x1997, 0x2004, 0xd0fc, 0x0108, 0x0020, 0x080c,
-	0x29c0, 0x0804, 0x0d1a, 0x7850, 0x9085, 0x0040, 0x7852, 0x7938,
-	0x7850, 0x9084, 0xfbcf, 0x7852, 0x080c, 0x2c76, 0x9085, 0x2000,
-	0x7852, 0x793a, 0x20a9, 0x0046, 0x1d04, 0x0c74, 0x080c, 0x866a,
-	0x1f04, 0x0c74, 0x7850, 0x9085, 0x0400, 0x9084, 0xdfbf, 0x7852,
-	0x793a, 0x080c, 0x744f, 0x0148, 0x080c, 0x7461, 0x1118, 0x080c,
-	0x7733, 0x0050, 0x080c, 0x7446, 0x0dd0, 0x080c, 0x772e, 0x080c,
-	0x7724, 0x080c, 0x736a, 0x0020, 0x2009, 0x00f8, 0x080c, 0x6029,
-	0x20a9, 0x0028, 0xa001, 0x1f04, 0x0c9a, 0x7850, 0x9085, 0x1400,
-	0x7852, 0x080c, 0x743e, 0x0120, 0x7843, 0x0090, 0x7843, 0x0010,
-	0x2021, 0xe678, 0x2019, 0xea60, 0x0d0c, 0x866a, 0x7820, 0xd09c,
-	0x1580, 0x080c, 0x743e, 0x0904, 0x0cff, 0x7824, 0xd0ac, 0x1904,
-	0x0d1f, 0x080c, 0x7461, 0x1528, 0x0046, 0x2021, 0x0320, 0x8421,
-	0x1df0, 0x004e, 0x7827, 0x1800, 0x080c, 0x2c76, 0x7824, 0x9084,
-	0x1800, 0x1160, 0x9484, 0x0fff, 0x1138, 0x2001, 0x1810, 0x2004,
-	0xd0fc, 0x0110, 0x080c, 0x0d45, 0x8421, 0x1158, 0x1d04, 0x0cda,
-	0x080c, 0x866a, 0x080c, 0x772e, 0x080c, 0x7724, 0x7003, 0x0001,
-	0x04f0, 0x8319, 0x1948, 0x1d04, 0x0ce7, 0x080c, 0x866a, 0x2009,
-	0x199a, 0x2104, 0x9005, 0x0118, 0x8001, 0x200a, 0x1178, 0x200b,
-	0x000a, 0x7827, 0x0048, 0x20a9, 0x0002, 0x080c, 0x2c57, 0x7924,
-	0x080c, 0x2c76, 0xd19c, 0x0110, 0x080c, 0x2b97, 0x00d8, 0x080c,
-	0x744f, 0x1140, 0x94a2, 0x03e8, 0x1128, 0x080c, 0x7416, 0x7003,
-	0x0001, 0x00a8, 0x7827, 0x1800, 0x080c, 0x2c76, 0x7824, 0x080c,
-	0x7458, 0x0110, 0xd0ac, 0x1158, 0x9084, 0x1800, 0x0950, 0x7003,
-	0x0001, 0x0028, 0x2001, 0x0001, 0x080c, 0x2828, 0x0078, 0x2009,
-	0x180c, 0x210c, 0xd19c, 0x1120, 0x7904, 0x918d, 0x0002, 0x7906,
-	0x7827, 0x0048, 0x7828, 0x9085, 0x0028, 0x782a, 0x7850, 0x9085,
-	0x0400, 0x7852, 0x2001, 0x19a6, 0x2003, 0x0000, 0x9006, 0x78f2,
-	0x015e, 0x003e, 0x000e, 0x080c, 0x576c, 0x1110, 0x080c, 0x0e62,
-	0x012e, 0x00fe, 0x004e, 0x001e, 0x0005, 0x0006, 0x0016, 0x0036,
-	0x0046, 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x0156, 0x0069,
-	0x0d0c, 0x866a, 0x015e, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be,
-	0x004e, 0x003e, 0x001e, 0x000e, 0x0005, 0x00e6, 0x2071, 0x189e,
-	0x7004, 0x9086, 0x0001, 0x1110, 0x080c, 0x34ab, 0x00ee, 0x0005,
-	0x0005, 0x2a70, 0x2061, 0x19aa, 0x2063, 0x0003, 0x6007, 0x0003,
-	0x600b, 0x0008, 0x600f, 0x0137, 0x2001, 0x197b, 0x900e, 0x2102,
-	0x7196, 0x2001, 0x0100, 0x2004, 0x9082, 0x0002, 0x0218, 0x705f,
-	0xffff, 0x0008, 0x715e, 0x7067, 0xffff, 0x717e, 0x7182, 0x080c,
-	0xd0d9, 0x2061, 0x196b, 0x6003, 0x0909, 0x6106, 0x600b, 0x8800,
+	0x1178, 0x080c, 0x4ca8, 0x080c, 0x34d8, 0x080c, 0x78cd, 0x080c,
+	0x704e, 0x080c, 0x8a16, 0x080c, 0x863c, 0x080c, 0x2cff, 0x0c58,
+	0x000b, 0x0c78, 0x0944, 0x0945, 0x0ae0, 0x0942, 0x0ba0, 0x0d56,
+	0x0d56, 0x0d56, 0x080c, 0x0dc5, 0x0005, 0x0126, 0x00f6, 0x2091,
+	0x8000, 0x7000, 0x9086, 0x0001, 0x1904, 0x0ab3, 0x080c, 0x0e94,
+	0x080c, 0x7563, 0x0150, 0x080c, 0x7586, 0x15a0, 0x2079, 0x0100,
+	0x7828, 0x9085, 0x1800, 0x782a, 0x0468, 0x080c, 0x748f, 0x7000,
+	0x9086, 0x0001, 0x1904, 0x0ab3, 0x7098, 0x9086, 0x0029, 0x1904,
+	0x0ab3, 0x080c, 0x85f9, 0x080c, 0x85eb, 0x2001, 0x0161, 0x2003,
+	0x0001, 0x2079, 0x0100, 0x7827, 0xffff, 0x7a28, 0x9295, 0x5e2f,
+	0x7a2a, 0x2011, 0x73de, 0x080c, 0x8703, 0x2011, 0x73d1, 0x080c,
+	0x87dd, 0x2011, 0x5f8a, 0x080c, 0x8703, 0x2011, 0x8030, 0x901e,
+	0x7396, 0x04d0, 0x080c, 0x5837, 0x2079, 0x0100, 0x7844, 0x9005,
+	0x1904, 0x0ab3, 0x2011, 0x5f8a, 0x080c, 0x8703, 0x2011, 0x73de,
+	0x080c, 0x8703, 0x2011, 0x73d1, 0x080c, 0x87dd, 0x2001, 0x0265,
+	0x2001, 0x0205, 0x2003, 0x0000, 0x7840, 0x9084, 0xfffb, 0x7842,
+	0x2001, 0x19a7, 0x2004, 0x9005, 0x1140, 0x00c6, 0x2061, 0x0100,
+	0x080c, 0x60d7, 0x00ce, 0x0804, 0x0ab3, 0x780f, 0x006b, 0x7a28,
+	0x080c, 0x756b, 0x0118, 0x9295, 0x5e2f, 0x0010, 0x9295, 0x402f,
+	0x7a2a, 0x2011, 0x8010, 0x73d8, 0x2001, 0x19a8, 0x2003, 0x0001,
+	0x080c, 0x2ba4, 0x080c, 0x4be3, 0x7248, 0xc284, 0x724a, 0x2001,
+	0x180c, 0x200c, 0xc1ac, 0xc1cc, 0x2102, 0x080c, 0xa7c4, 0x2011,
+	0x0004, 0x080c, 0xce4f, 0x080c, 0x693a, 0x080c, 0x7563, 0x1120,
+	0x080c, 0x2be8, 0x02e0, 0x0400, 0x080c, 0x60de, 0x0140, 0x7097,
+	0x0001, 0x70d3, 0x0000, 0x080c, 0x5a04, 0x0804, 0x0ab3, 0x080c,
+	0x57cd, 0xd094, 0x0188, 0x2011, 0x180c, 0x2204, 0xc0cd, 0x2012,
+	0x080c, 0x57d1, 0xd0d4, 0x1118, 0x080c, 0x2be8, 0x1270, 0x2011,
+	0x180c, 0x2204, 0xc0bc, 0x00a8, 0x080c, 0x57d1, 0xd0d4, 0x1db8,
+	0x2011, 0x180c, 0x2204, 0xc0bd, 0x0060, 0x2011, 0x180c, 0x2204,
+	0xc0bd, 0x2012, 0x080c, 0x6a84, 0x1128, 0xd0a4, 0x0118, 0x2204,
+	0xc0fd, 0x2012, 0x080c, 0x6a4a, 0x0120, 0x7a0c, 0xc2b4, 0x7a0e,
+	0x00a8, 0x707f, 0x0000, 0x080c, 0x7563, 0x1130, 0x70b0, 0x9005,
+	0x1168, 0x080c, 0xd292, 0x0050, 0x080c, 0xd292, 0x70dc, 0xd09c,
+	0x1128, 0x70b0, 0x9005, 0x0110, 0x080c, 0x60b4, 0x70e7, 0x0000,
+	0x70e3, 0x0000, 0x70a7, 0x0000, 0x080c, 0x2bf0, 0x0228, 0x2011,
+	0x0101, 0x2204, 0xc0c4, 0x2012, 0x72dc, 0x080c, 0x7563, 0x1178,
+	0x9016, 0x0016, 0x080c, 0x29a1, 0x2019, 0x196e, 0x211a, 0x001e,
+	0x705f, 0xffff, 0x7063, 0x00ef, 0x7083, 0x0000, 0x0020, 0x2019,
+	0x196e, 0x201b, 0x0000, 0x2079, 0x1847, 0x7804, 0xd0ac, 0x0108,
+	0xc295, 0x72de, 0x080c, 0x7563, 0x0118, 0x9296, 0x0004, 0x0548,
+	0x2011, 0x0001, 0x080c, 0xce4f, 0x70ab, 0x0000, 0x70af, 0xffff,
+	0x7003, 0x0002, 0x2079, 0x0100, 0x7827, 0x0003, 0x7828, 0x9085,
+	0x0003, 0x782a, 0x00fe, 0x080c, 0x3022, 0x2011, 0x0005, 0x080c,
+	0xa8d3, 0x080c, 0x98e7, 0x080c, 0x7563, 0x0148, 0x00c6, 0x2061,
+	0x0100, 0x0016, 0x080c, 0x29a1, 0x61e2, 0x001e, 0x00ce, 0x012e,
+	0x0420, 0x70ab, 0x0000, 0x70af, 0xffff, 0x7003, 0x0002, 0x00f6,
+	0x2079, 0x0100, 0x7827, 0x0003, 0x7828, 0x9085, 0x0003, 0x782a,
+	0x00fe, 0x2011, 0x0005, 0x080c, 0xa8d3, 0x080c, 0x98e7, 0x080c,
+	0x7563, 0x0148, 0x00c6, 0x2061, 0x0100, 0x0016, 0x080c, 0x29a1,
+	0x61e2, 0x001e, 0x00ce, 0x00fe, 0x012e, 0x0005, 0x00c6, 0x00b6,
+	0x080c, 0x7563, 0x1118, 0x20a9, 0x0800, 0x0010, 0x20a9, 0x0782,
+	0x080c, 0x7563, 0x1110, 0x900e, 0x0010, 0x2009, 0x007e, 0x86ff,
+	0x0138, 0x9180, 0x1000, 0x2004, 0x905d, 0x0110, 0xb800, 0xd0bc,
+	0x090c, 0x3347, 0x8108, 0x1f04, 0x0ac7, 0x707f, 0x0000, 0x7080,
+	0x9084, 0x00ff, 0x7082, 0x70b3, 0x0000, 0x00be, 0x00ce, 0x0005,
+	0x00b6, 0x0126, 0x2091, 0x8000, 0x7000, 0x9086, 0x0002, 0x1904,
+	0x0b9d, 0x70ac, 0x9086, 0xffff, 0x0130, 0x080c, 0x3022, 0x080c,
+	0x98e7, 0x0804, 0x0b9d, 0x70dc, 0xd0ac, 0x1110, 0xd09c, 0x0558,
+	0xd084, 0x0548, 0x0006, 0x2001, 0x0103, 0x2003, 0x002b, 0x000e,
+	0xd08c, 0x0508, 0x080c, 0x33aa, 0x11d0, 0x70e0, 0x9086, 0xffff,
+	0x01b0, 0x080c, 0x31b7, 0x080c, 0x98e7, 0x70dc, 0xd094, 0x1904,
+	0x0b9d, 0x2011, 0x0001, 0x080c, 0xd548, 0x0110, 0x2011, 0x0003,
+	0x901e, 0x080c, 0x31f1, 0x080c, 0x98e7, 0x0804, 0x0b9d, 0x70e4,
+	0x9005, 0x1904, 0x0b9d, 0x70a8, 0x9005, 0x1904, 0x0b9d, 0x70dc,
+	0xd0a4, 0x0118, 0xd0b4, 0x0904, 0x0b9d, 0x080c, 0x6a4a, 0x1904,
+	0x0b9d, 0x080c, 0x6a9d, 0x1904, 0x0b9d, 0x080c, 0x6a84, 0x01c0,
+	0x0156, 0x00c6, 0x20a9, 0x007f, 0x900e, 0x0016, 0x080c, 0x6717,
+	0x1118, 0xb800, 0xd0ec, 0x1138, 0x001e, 0x8108, 0x1f04, 0x0b3d,
+	0x00ce, 0x015e, 0x0028, 0x001e, 0x00ce, 0x015e, 0x0804, 0x0b9d,
+	0x0006, 0x2001, 0x0103, 0x2003, 0x002b, 0x000e, 0x2011, 0x19b5,
+	0x080c, 0x0f96, 0x2011, 0x19cf, 0x080c, 0x0f96, 0x7030, 0xc08c,
+	0x7032, 0x7003, 0x0003, 0x70af, 0xffff, 0x080c, 0x0e76, 0x9006,
+	0x080c, 0x2832, 0x080c, 0x33aa, 0x0118, 0x080c, 0x4d80, 0x0050,
+	0x0036, 0x0046, 0x2019, 0xffff, 0x2021, 0x0006, 0x080c, 0x4d9a,
+	0x004e, 0x003e, 0x00f6, 0x2079, 0x0100, 0x080c, 0x7586, 0x0150,
+	0x080c, 0x7563, 0x7828, 0x0118, 0x9084, 0xe1ff, 0x0010, 0x9084,
+	0xffdf, 0x782a, 0x00fe, 0x2001, 0x19ea, 0x2004, 0x9086, 0x0005,
+	0x1120, 0x2011, 0x0000, 0x080c, 0xa8d3, 0x2011, 0x0000, 0x080c,
+	0xa8dd, 0x080c, 0x98e7, 0x080c, 0x9a09, 0x012e, 0x00be, 0x0005,
+	0x0016, 0x0046, 0x00f6, 0x0126, 0x2091, 0x8000, 0x2079, 0x0100,
+	0x7904, 0x918c, 0xfffd, 0x7906, 0x2009, 0x00f7, 0x080c, 0x609d,
+	0x7940, 0x918c, 0x0010, 0x7942, 0x7924, 0xd1b4, 0x0110, 0x7827,
+	0x0040, 0xd19c, 0x0110, 0x7827, 0x0008, 0x0006, 0x0036, 0x0156,
+	0x7954, 0xd1ac, 0x1904, 0x0c2d, 0x2001, 0x19a8, 0x2004, 0x9005,
+	0x1518, 0x080c, 0x2c6b, 0x1148, 0x2001, 0x0001, 0x080c, 0x2bd3,
+	0x2001, 0x0001, 0x080c, 0x2bb6, 0x00b8, 0x080c, 0x2c73, 0x1138,
+	0x9006, 0x080c, 0x2bd3, 0x9006, 0x080c, 0x2bb6, 0x0068, 0x080c,
+	0x2c7b, 0x1d50, 0x2001, 0x1999, 0x2004, 0xd0fc, 0x0108, 0x0020,
+	0x080c, 0x29cd, 0x0804, 0x0d0d, 0x080c, 0x7574, 0x0148, 0x080c,
+	0x7586, 0x1118, 0x080c, 0x7857, 0x0050, 0x080c, 0x756b, 0x0dd0,
+	0x080c, 0x7852, 0x080c, 0x7848, 0x080c, 0x748f, 0x0058, 0x080c,
+	0x7563, 0x0140, 0x2009, 0x00f8, 0x080c, 0x609d, 0x7843, 0x0090,
+	0x7843, 0x0010, 0x20a9, 0x09c4, 0x7820, 0xd09c, 0x1138, 0x080c,
+	0x7563, 0x0138, 0x7824, 0xd0ac, 0x1904, 0x0d12, 0x1f04, 0x0c0c,
+	0x0070, 0x7824, 0x080c, 0x757d, 0x0118, 0xd0ac, 0x1904, 0x0d12,
+	0x9084, 0x1800, 0x0d98, 0x7003, 0x0001, 0x0804, 0x0d12, 0x2001,
+	0x0001, 0x080c, 0x2832, 0x0804, 0x0d25, 0x2001, 0x19a8, 0x2004,
+	0x9005, 0x1518, 0x080c, 0x2c6b, 0x1148, 0x2001, 0x0001, 0x080c,
+	0x2bd3, 0x2001, 0x0001, 0x080c, 0x2bb6, 0x00b8, 0x080c, 0x2c73,
+	0x1138, 0x9006, 0x080c, 0x2bd3, 0x9006, 0x080c, 0x2bb6, 0x0068,
+	0x080c, 0x2c7b, 0x1d50, 0x2001, 0x1999, 0x2004, 0xd0fc, 0x0108,
+	0x0020, 0x080c, 0x29cd, 0x0804, 0x0d0d, 0x7850, 0x9085, 0x0040,
+	0x7852, 0x7938, 0x7850, 0x9084, 0xfbcf, 0x7852, 0x080c, 0x2c83,
+	0x9085, 0x2000, 0x7852, 0x793a, 0x20a9, 0x0046, 0x1d04, 0x0c66,
+	0x080c, 0x87bd, 0x1f04, 0x0c66, 0x7850, 0x9085, 0x0400, 0x9084,
+	0xdfbf, 0x7852, 0x793a, 0x080c, 0x7574, 0x0148, 0x080c, 0x7586,
+	0x1118, 0x080c, 0x7857, 0x0050, 0x080c, 0x756b, 0x0dd0, 0x080c,
+	0x7852, 0x080c, 0x7848, 0x080c, 0x748f, 0x0020, 0x2009, 0x00f8,
+	0x080c, 0x609d, 0x20a9, 0x0028, 0xa001, 0x1f04, 0x0c8c, 0x7850,
+	0x9085, 0x1400, 0x7852, 0x080c, 0x7563, 0x0120, 0x7843, 0x0090,
+	0x7843, 0x0010, 0x2021, 0xe678, 0x2019, 0xea60, 0x0d0c, 0x87bd,
+	0x7820, 0xd09c, 0x1588, 0x080c, 0x7563, 0x0904, 0x0cf2, 0x7824,
+	0xd0ac, 0x1904, 0x0d12, 0x080c, 0x7586, 0x1530, 0x0046, 0x2021,
+	0x0320, 0x8421, 0x1df0, 0x004e, 0x7827, 0x1800, 0x080c, 0x2c83,
+	0x7824, 0x9084, 0x1800, 0x1168, 0x9484, 0x0fff, 0x1140, 0x2001,
+	0x1810, 0x2004, 0x9084, 0x9000, 0x0110, 0x080c, 0x0d33, 0x8421,
+	0x1158, 0x1d04, 0x0ccd, 0x080c, 0x87bd, 0x080c, 0x7852, 0x080c,
+	0x7848, 0x7003, 0x0001, 0x04f0, 0x8319, 0x1940, 0x1d04, 0x0cda,
+	0x080c, 0x87bd, 0x2009, 0x199c, 0x2104, 0x9005, 0x0118, 0x8001,
+	0x200a, 0x1178, 0x200b, 0x000a, 0x7827, 0x0048, 0x20a9, 0x0002,
+	0x080c, 0x2c64, 0x7924, 0x080c, 0x2c83, 0xd19c, 0x0110, 0x080c,
+	0x2ba4, 0x00d8, 0x080c, 0x7574, 0x1140, 0x94a2, 0x03e8, 0x1128,
+	0x080c, 0x753b, 0x7003, 0x0001, 0x00a8, 0x7827, 0x1800, 0x080c,
+	0x2c83, 0x7824, 0x080c, 0x757d, 0x0110, 0xd0ac, 0x1158, 0x9084,
+	0x1800, 0x0950, 0x7003, 0x0001, 0x0028, 0x2001, 0x0001, 0x080c,
+	0x2832, 0x0078, 0x2009, 0x180c, 0x210c, 0xd19c, 0x1120, 0x7904,
+	0x918d, 0x0002, 0x7906, 0x7827, 0x0048, 0x7828, 0x9085, 0x0028,
+	0x782a, 0x7850, 0x9085, 0x0400, 0x7852, 0x2001, 0x19a8, 0x2003,
+	0x0000, 0x9006, 0x78f2, 0x015e, 0x003e, 0x000e, 0x012e, 0x00fe,
+	0x004e, 0x001e, 0x0005, 0x0006, 0x0016, 0x0036, 0x0046, 0x00b6,
+	0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x0156, 0x0069, 0x0d0c, 0x87bd,
+	0x015e, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x004e, 0x003e,
+	0x001e, 0x000e, 0x0005, 0x00e6, 0x2071, 0x189e, 0x7004, 0x9086,
+	0x0001, 0x1110, 0x080c, 0x34d8, 0x00ee, 0x0005, 0x0005, 0x2a70,
+	0x2061, 0x19ac, 0x2063, 0x0003, 0x6007, 0x0003, 0x600b, 0x000f,
+	0x600f, 0x0137, 0x2001, 0x197d, 0x900e, 0x2102, 0x7196, 0x2001,
+	0x0100, 0x2004, 0x9082, 0x0002, 0x0218, 0x705f, 0xffff, 0x0008,
+	0x715e, 0x7067, 0xffff, 0x717e, 0x7182, 0x080c, 0xd292, 0x70eb,
+	0x00c0, 0x2061, 0x196d, 0x6003, 0x0909, 0x6106, 0x600b, 0x8800,
 	0x600f, 0x0200, 0x6013, 0x00ff, 0x6017, 0x001f, 0x611a, 0x601f,
-	0x07d0, 0x2061, 0x1973, 0x6003, 0x8000, 0x6106, 0x610a, 0x600f,
+	0x07d0, 0x2061, 0x1975, 0x6003, 0x8000, 0x6106, 0x610a, 0x600f,
 	0x0200, 0x6013, 0x00ff, 0x6116, 0x601b, 0x0001, 0x611e, 0x2061,
-	0x1988, 0x6003, 0x514c, 0x6007, 0x4f47, 0x600b, 0x4943, 0x600f,
-	0x2020, 0x2001, 0x182c, 0x2102, 0x0005, 0x9016, 0x080c, 0x6699,
+	0x198a, 0x6003, 0x514c, 0x6007, 0x4f47, 0x600b, 0x4943, 0x600f,
+	0x2020, 0x2001, 0x182c, 0x2102, 0x0005, 0x9016, 0x080c, 0x6717,
 	0x1178, 0xb804, 0x90c4, 0x00ff, 0x98c6, 0x0006, 0x0128, 0x90c4,
 	0xff00, 0x98c6, 0x0600, 0x1120, 0x9186, 0x0080, 0x0108, 0x8210,
 	0x8108, 0x9186, 0x0800, 0x1d50, 0x2208, 0x0005, 0x2091, 0x8000,
 	0x2079, 0x0000, 0x000e, 0x00f6, 0x0010, 0x2091, 0x8000, 0x0e04,
-	0x0dd7, 0x0006, 0x0016, 0x2001, 0x8002, 0x0006, 0x2079, 0x0000,
+	0x0dc7, 0x0006, 0x0016, 0x2001, 0x8002, 0x0006, 0x2079, 0x0000,
 	0x000e, 0x7882, 0x7836, 0x001e, 0x798e, 0x000e, 0x788a, 0x000e,
-	0x7886, 0x3900, 0x789a, 0x7833, 0x0012, 0x2091, 0x5000, 0x0156,
-	0x00d6, 0x0036, 0x0026, 0x2079, 0x0300, 0x2069, 0x1aa4, 0x7a08,
-	0x226a, 0x2069, 0x1aa5, 0x7a18, 0x226a, 0x8d68, 0x7a1c, 0x226a,
-	0x782c, 0x2019, 0x1ab2, 0x201a, 0x2019, 0x1ab5, 0x9016, 0x7808,
-	0xd09c, 0x0168, 0x7820, 0x201a, 0x8210, 0x8318, 0x9386, 0x1aca,
-	0x0108, 0x0ca8, 0x7808, 0xd09c, 0x0110, 0x2011, 0xdead, 0x2019,
-	0x1ab3, 0x782c, 0x201a, 0x8318, 0x221a, 0x7803, 0x0000, 0x2069,
-	0x1a84, 0x901e, 0x20a9, 0x0020, 0x7b26, 0x7a28, 0x226a, 0x8d68,
-	0x8318, 0x1f04, 0x0e24, 0x002e, 0x003e, 0x00de, 0x015e, 0x2079,
-	0x1800, 0x7803, 0x0005, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004,
-	0xd084, 0x0180, 0x2001, 0x1a18, 0x2004, 0x9005, 0x0128, 0x2001,
-	0x008b, 0x2004, 0xd0fc, 0x0dd8, 0x2001, 0x008a, 0x2003, 0x0002,
-	0x2003, 0x1001, 0x080c, 0x576c, 0x1110, 0x080c, 0x0e99, 0x0cd0,
-	0x0005, 0x918c, 0x03ff, 0x2001, 0x0003, 0x2004, 0x9084, 0x0600,
-	0x1118, 0x918d, 0x2800, 0x0010, 0x918d, 0x2000, 0x2001, 0x017f,
-	0x2102, 0x0005, 0x00f6, 0x0006, 0x2079, 0x1827, 0x2f04, 0x8000,
-	0x207a, 0x080c, 0x2c6e, 0x1150, 0x0006, 0x2001, 0x1997, 0x2004,
-	0xd0fc, 0x000e, 0x1118, 0x9082, 0x7530, 0x0010, 0x9082, 0x000f,
-	0x0258, 0x9006, 0x207a, 0x2079, 0x182a, 0x2f04, 0x9084, 0x0001,
-	0x9086, 0x0001, 0x207a, 0x0090, 0x2079, 0x182a, 0x2f7c, 0x8fff,
-	0x1138, 0x0026, 0x2011, 0x0080, 0x080c, 0x0edf, 0x002e, 0x0030,
-	0x0026, 0x2011, 0x0000, 0x080c, 0x0edf, 0x002e, 0x000e, 0x00fe,
-	0x0005, 0x0026, 0x0126, 0x2011, 0x0080, 0x080c, 0x0edf, 0x20a9,
-	0x0fff, 0x080c, 0x0f00, 0x2011, 0x0040, 0x04c9, 0x20a9, 0x0fff,
-	0x080c, 0x0f00, 0x0c80, 0x7038, 0xd0b4, 0x1128, 0x0026, 0x2011,
-	0x0040, 0x0469, 0x002e, 0x0005, 0x7038, 0xd0b4, 0x1128, 0x0026,
-	0x2011, 0x0080, 0x0421, 0x002e, 0x0005, 0x0026, 0x70ef, 0x0000,
-	0x0459, 0x1148, 0x080c, 0x2c6e, 0x1118, 0x2011, 0x8484, 0x0058,
-	0x2011, 0x8282, 0x0040, 0x080c, 0x2c6e, 0x1118, 0x2011, 0xcdc5,
-	0x0010, 0x2011, 0xcac2, 0x00e9, 0x002e, 0x0005, 0xd0b4, 0x0130,
-	0x0006, 0x3b00, 0x9084, 0xff3f, 0x20d8, 0x000e, 0x0005, 0x0016,
-	0x3b08, 0x3a00, 0x9104, 0x918d, 0x00c0, 0x21d8, 0x9084, 0xff3f,
-	0x9205, 0x20d0, 0x001e, 0x0005, 0x2001, 0x183a, 0x2004, 0xd0dc,
-	0x0005, 0x9e86, 0x1800, 0x190c, 0x0dd5, 0x70e8, 0xd0e4, 0x0108,
-	0xc2e5, 0x72ea, 0xd0e4, 0x1118, 0x9294, 0x00c0, 0x0c01, 0x0005,
-	0x1d04, 0x0f00, 0x2091, 0x6000, 0x1f04, 0x0f00, 0x0005, 0x890e,
-	0x810e, 0x810f, 0x9194, 0x003f, 0x918c, 0xffc0, 0x0005, 0x0006,
-	0x2200, 0x914d, 0x894f, 0x894d, 0x894d, 0x000e, 0x0005, 0x01d6,
-	0x0146, 0x0036, 0x0096, 0x2061, 0x188d, 0x600b, 0x0000, 0x600f,
-	0x0000, 0x6003, 0x0000, 0x6007, 0x0000, 0x2009, 0xffc0, 0x2105,
-	0x0006, 0x2001, 0xaaaa, 0x200f, 0x2019, 0x5555, 0x9016, 0x2049,
-	0x0bff, 0xab02, 0xa001, 0xa001, 0xa800, 0x9306, 0x1138, 0x2105,
-	0x9306, 0x0120, 0x8210, 0x99c8, 0x0400, 0x0c98, 0x000e, 0x200f,
-	0x2001, 0x189d, 0x928a, 0x000e, 0x1638, 0x928a, 0x0006, 0x2011,
-	0x0006, 0x1210, 0x2011, 0x0000, 0x2202, 0x9006, 0x2008, 0x82ff,
-	0x01b0, 0x8200, 0x600a, 0x600f, 0xffff, 0x6003, 0x0002, 0x6007,
-	0x0000, 0x0026, 0x2019, 0x0010, 0x9280, 0x0001, 0x20e8, 0x21a0,
-	0x21a8, 0x4104, 0x8319, 0x1de0, 0x8211, 0x1da0, 0x002e, 0x009e,
-	0x003e, 0x014e, 0x01de, 0x0005, 0x2011, 0x000e, 0x08e8, 0x0016,
-	0x0026, 0x0096, 0x3348, 0x080c, 0x0f07, 0x2100, 0x9300, 0x2098,
-	0x22e0, 0x009e, 0x002e, 0x001e, 0x0036, 0x3518, 0x20a9, 0x0001,
-	0x4002, 0x8007, 0x4004, 0x8319, 0x1dd8, 0x003e, 0x0005, 0x20e9,
-	0x0001, 0x71b8, 0x81ff, 0x11c0, 0x9006, 0x2009, 0x0200, 0x20a9,
-	0x0002, 0x9298, 0x0018, 0x23a0, 0x4001, 0x2009, 0x0700, 0x20a9,
-	0x0002, 0x9298, 0x0008, 0x23a0, 0x4001, 0x707c, 0x8007, 0x7180,
-	0x810f, 0x20a9, 0x0002, 0x4001, 0x9298, 0x000c, 0x23a0, 0x900e,
-	0x080c, 0x0db5, 0x2001, 0x0000, 0x810f, 0x20a9, 0x0002, 0x4001,
-	0x0005, 0x89ff, 0x0140, 0xa804, 0xa807, 0x0000, 0x0006, 0x080c,
-	0x1031, 0x009e, 0x0cb0, 0x0005, 0x00e6, 0x2071, 0x1800, 0x080c,
-	0x10aa, 0x090c, 0x0dd5, 0x00ee, 0x0005, 0x0086, 0x00e6, 0x0006,
-	0x0026, 0x0036, 0x0126, 0x2091, 0x8000, 0x00c9, 0x2071, 0x1800,
-	0x73c0, 0x702c, 0x9016, 0x9045, 0x0158, 0x8210, 0x9906, 0x090c,
-	0x0dd5, 0x2300, 0x9202, 0x0120, 0x1a0c, 0x0dd5, 0xa000, 0x0c98,
-	0x012e, 0x003e, 0x002e, 0x000e, 0x00ee, 0x008e, 0x0005, 0x0086,
-	0x00e6, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x1910, 0x7010,
-	0x9005, 0x0140, 0x7018, 0x9045, 0x0128, 0x9906, 0x090c, 0x0dd5,
-	0xa000, 0x0cc8, 0x012e, 0x000e, 0x00ee, 0x008e, 0x0005, 0x00e6,
-	0x2071, 0x1800, 0x0126, 0x2091, 0x8000, 0x70c0, 0x8001, 0x0270,
-	0x70c2, 0x702c, 0x2048, 0x9085, 0x0001, 0xa800, 0x702e, 0xa803,
+	0x7886, 0x3900, 0x789a, 0x00d6, 0x2069, 0x0300, 0x6818, 0x78ae,
+	0x681c, 0x78b2, 0x2001, 0x1a0a, 0x2004, 0x78b6, 0x2001, 0x1a87,
+	0x2004, 0x78ba, 0x6808, 0x78be, 0x00de, 0x7833, 0x0012, 0x2091,
+	0x5000, 0x0156, 0x00d6, 0x0036, 0x0026, 0x2079, 0x0300, 0x2069,
+	0x1aaa, 0x7a08, 0x226a, 0x2069, 0x1aab, 0x7a18, 0x226a, 0x8d68,
+	0x7a1c, 0x226a, 0x782c, 0x2019, 0x1ab8, 0x201a, 0x2019, 0x1abb,
+	0x9016, 0x7808, 0xd09c, 0x0168, 0x7820, 0x201a, 0x8210, 0x8318,
+	0x9386, 0x1ad0, 0x0108, 0x0ca8, 0x7808, 0xd09c, 0x0110, 0x2011,
+	0xdead, 0x2019, 0x1ab9, 0x782c, 0x201a, 0x8318, 0x221a, 0x7803,
+	0x0000, 0x2069, 0x1a8a, 0x901e, 0x20a9, 0x0020, 0x7b26, 0x7a28,
+	0x226a, 0x8d68, 0x8318, 0x1f04, 0x0e26, 0x002e, 0x003e, 0x00de,
+	0x015e, 0x2079, 0x1800, 0x7803, 0x0005, 0x2091, 0x4080, 0x2001,
+	0x0089, 0x2004, 0xd084, 0x0180, 0x2001, 0x1a1d, 0x2004, 0x9005,
+	0x0128, 0x2001, 0x008b, 0x2004, 0xd0fc, 0x0dd8, 0x2001, 0x008a,
+	0x2003, 0x0002, 0x2003, 0x1001, 0x080c, 0x57dc, 0x1108, 0x0099,
+	0x0cd8, 0x0005, 0x918c, 0x03ff, 0x2001, 0x0003, 0x2004, 0x9084,
+	0x0600, 0x1118, 0x918d, 0x2800, 0x0010, 0x918d, 0x2000, 0x2001,
+	0x017f, 0x2102, 0x0005, 0x0026, 0x0126, 0x2011, 0x0080, 0x080c,
+	0x0eee, 0x20a9, 0x0900, 0x080c, 0x0f0f, 0x2011, 0x0040, 0x080c,
+	0x0eee, 0x20a9, 0x0900, 0x080c, 0x0f0f, 0x0c78, 0x0026, 0x080c,
+	0x0efb, 0x1118, 0x2011, 0x0040, 0x0098, 0x2011, 0x010e, 0x2214,
+	0x9294, 0x0007, 0x9296, 0x0007, 0x0118, 0x2011, 0xa880, 0x0010,
+	0x2011, 0x6840, 0xd0e4, 0x70ef, 0x0000, 0x1120, 0x70ef, 0x0fa0,
+	0x080c, 0x0f00, 0x002e, 0x0005, 0x0026, 0x080c, 0x0efb, 0x0128,
+	0xd0a4, 0x1138, 0x2011, 0xcdd5, 0x0010, 0x2011, 0x0080, 0x080c,
+	0x0f00, 0x002e, 0x0005, 0x0026, 0x70ef, 0x0000, 0x080c, 0x0efb,
+	0x1148, 0x080c, 0x2c7b, 0x1118, 0x2011, 0x8484, 0x0058, 0x2011,
+	0x8282, 0x0040, 0x080c, 0x2c7b, 0x1118, 0x2011, 0xcdc5, 0x0010,
+	0x2011, 0xcac2, 0x080c, 0x0f00, 0x002e, 0x0005, 0x00e6, 0x0006,
+	0x2071, 0x1800, 0xd0b4, 0x70e8, 0x1110, 0xc0e4, 0x0048, 0x0006,
+	0x3b00, 0x9084, 0xff3f, 0x20d8, 0x000e, 0x70ef, 0x0000, 0xc0e5,
+	0x0079, 0x000e, 0x00ee, 0x0005, 0x00e6, 0x2071, 0x1800, 0xd0e4,
+	0x70e8, 0x1110, 0xc0dc, 0x0008, 0xc0dd, 0x0011, 0x00ee, 0x0005,
+	0x70ea, 0x7000, 0x9084, 0x0007, 0x000b, 0x0005, 0x0ebd, 0x0e94,
+	0x0e94, 0x0e76, 0x0ea3, 0x0e94, 0x0e94, 0x0ea3, 0x0016, 0x3b08,
+	0x3a00, 0x9104, 0x918d, 0x00c0, 0x21d8, 0x9084, 0xff3f, 0x9205,
+	0x20d0, 0x001e, 0x0005, 0x2001, 0x183a, 0x2004, 0xd0dc, 0x0005,
+	0x9e86, 0x1800, 0x190c, 0x0dc5, 0x70e8, 0xd0e4, 0x0108, 0xc2e5,
+	0x72ea, 0xd0e4, 0x1118, 0x9294, 0x00c0, 0x0c01, 0x0005, 0x1d04,
+	0x0f0f, 0x2091, 0x6000, 0x1f04, 0x0f0f, 0x0005, 0x890e, 0x810e,
+	0x810f, 0x9194, 0x003f, 0x918c, 0xffc0, 0x0005, 0x0006, 0x2200,
+	0x914d, 0x894f, 0x894d, 0x894d, 0x000e, 0x0005, 0x01d6, 0x0146,
+	0x0036, 0x0096, 0x2061, 0x188d, 0x600b, 0x0000, 0x600f, 0x0000,
+	0x6003, 0x0000, 0x6007, 0x0000, 0x2009, 0xffc0, 0x2105, 0x0006,
+	0x2001, 0xaaaa, 0x200f, 0x2019, 0x5555, 0x9016, 0x2049, 0x0bff,
+	0xab02, 0xa001, 0xa001, 0xa800, 0x9306, 0x1138, 0x2105, 0x9306,
+	0x0120, 0x8210, 0x99c8, 0x0400, 0x0c98, 0x000e, 0x200f, 0x2001,
+	0x189d, 0x928a, 0x000e, 0x1638, 0x928a, 0x0006, 0x2011, 0x0006,
+	0x1210, 0x2011, 0x0000, 0x2202, 0x9006, 0x2008, 0x82ff, 0x01b0,
+	0x8200, 0x600a, 0x600f, 0xffff, 0x6003, 0x0002, 0x6007, 0x0000,
+	0x0026, 0x2019, 0x0010, 0x9280, 0x0001, 0x20e8, 0x21a0, 0x21a8,
+	0x4104, 0x8319, 0x1de0, 0x8211, 0x1da0, 0x002e, 0x009e, 0x003e,
+	0x014e, 0x01de, 0x0005, 0x2011, 0x000e, 0x08e8, 0x0016, 0x0026,
+	0x0096, 0x3348, 0x080c, 0x0f16, 0x2100, 0x9300, 0x2098, 0x22e0,
+	0x009e, 0x002e, 0x001e, 0x0036, 0x3518, 0x20a9, 0x0001, 0x4002,
+	0x8007, 0x4004, 0x8319, 0x1dd8, 0x003e, 0x0005, 0x20e9, 0x0001,
+	0x71b8, 0x81ff, 0x11c0, 0x9006, 0x2009, 0x0200, 0x20a9, 0x0002,
+	0x9298, 0x0018, 0x23a0, 0x4001, 0x2009, 0x0700, 0x20a9, 0x0002,
+	0x9298, 0x0008, 0x23a0, 0x4001, 0x707c, 0x8007, 0x7180, 0x810f,
+	0x20a9, 0x0002, 0x4001, 0x9298, 0x000c, 0x23a0, 0x900e, 0x080c,
+	0x0da5, 0x2001, 0x0000, 0x810f, 0x20a9, 0x0002, 0x4001, 0x0005,
+	0x89ff, 0x0140, 0xa804, 0xa807, 0x0000, 0x0006, 0x080c, 0x1040,
+	0x009e, 0x0cb0, 0x0005, 0x00e6, 0x2071, 0x1800, 0x080c, 0x10b9,
+	0x090c, 0x0dc5, 0x00ee, 0x0005, 0x0086, 0x00e6, 0x0006, 0x0026,
+	0x0036, 0x0126, 0x2091, 0x8000, 0x00c9, 0x2071, 0x1800, 0x73c0,
+	0x702c, 0x9016, 0x9045, 0x0158, 0x8210, 0x9906, 0x090c, 0x0dc5,
+	0x2300, 0x9202, 0x0120, 0x1a0c, 0x0dc5, 0xa000, 0x0c98, 0x012e,
+	0x003e, 0x002e, 0x000e, 0x00ee, 0x008e, 0x0005, 0x0086, 0x00e6,
+	0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x1910, 0x7010, 0x9005,
+	0x0140, 0x7018, 0x9045, 0x0128, 0x9906, 0x090c, 0x0dc5, 0xa000,
+	0x0cc8, 0x012e, 0x000e, 0x00ee, 0x008e, 0x0005, 0x00e6, 0x2071,
+	0x1800, 0x0126, 0x2091, 0x8000, 0x70c0, 0x8001, 0x0270, 0x70c2,
+	0x702c, 0x2048, 0x9085, 0x0001, 0xa800, 0x702e, 0xa803, 0x0000,
+	0xa807, 0x0000, 0x012e, 0x00ee, 0x0005, 0x904e, 0x0cd8, 0x00e6,
+	0x0126, 0x2091, 0x8000, 0x2071, 0x1800, 0x70c0, 0x90ca, 0x0020,
+	0x0268, 0x8001, 0x70c2, 0x702c, 0x2048, 0xa800, 0x702e, 0xa803,
 	0x0000, 0xa807, 0x0000, 0x012e, 0x00ee, 0x0005, 0x904e, 0x0cd8,
-	0x00e6, 0x0126, 0x2091, 0x8000, 0x2071, 0x1800, 0x70c0, 0x90ca,
-	0x0020, 0x0268, 0x8001, 0x70c2, 0x702c, 0x2048, 0xa800, 0x702e,
-	0xa803, 0x0000, 0xa807, 0x0000, 0x012e, 0x00ee, 0x0005, 0x904e,
-	0x0cd8, 0x00e6, 0x0126, 0x2091, 0x8000, 0x0016, 0x890e, 0x810e,
-	0x810f, 0x9184, 0x003f, 0xa862, 0x9184, 0xffc0, 0xa85e, 0x001e,
-	0x0020, 0x00e6, 0x0126, 0x2091, 0x8000, 0x2071, 0x1800, 0x702c,
-	0xa802, 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c, 0x84c2,
-	0x012e, 0x00ee, 0x0005, 0x2071, 0x1800, 0x9026, 0x2009, 0x0000,
-	0x2049, 0x0400, 0x2900, 0x702e, 0x8940, 0x2800, 0xa802, 0xa95e,
-	0xa863, 0x0001, 0x8420, 0x9886, 0x0440, 0x0120, 0x2848, 0x9188,
-	0x0040, 0x0c90, 0x2071, 0x188d, 0x7000, 0x9005, 0x11a0, 0x2001,
-	0x0534, 0xa802, 0x2048, 0x2009, 0x4d00, 0x8940, 0x2800, 0xa802,
-	0xa95e, 0xa863, 0x0001, 0x8420, 0x9886, 0x0800, 0x0120, 0x2848,
-	0x9188, 0x0040, 0x0c90, 0x2071, 0x188d, 0x7104, 0x7200, 0x82ff,
-	0x01d0, 0x7308, 0x8318, 0x831f, 0x831b, 0x831b, 0x7312, 0x8319,
-	0x2001, 0x0800, 0xa802, 0x2048, 0x8900, 0xa802, 0x2040, 0xa95e,
-	0xaa62, 0x8420, 0x2300, 0x9906, 0x0130, 0x2848, 0x9188, 0x0040,
-	0x9291, 0x0000, 0x0c88, 0xa803, 0x0000, 0x2071, 0x1800, 0x74be,
-	0x74c2, 0x0005, 0x00e6, 0x0016, 0x9984, 0xfc00, 0x01e8, 0x908c,
-	0xf800, 0x1168, 0x9982, 0x0400, 0x02b8, 0x9982, 0x0440, 0x0278,
-	0x9982, 0x0534, 0x0288, 0x9982, 0x0800, 0x1270, 0x0040, 0x9982,
-	0x0800, 0x0250, 0x2071, 0x188d, 0x7010, 0x9902, 0x1228, 0x9085,
-	0x0001, 0x001e, 0x00ee, 0x0005, 0x9006, 0x0cd8, 0x00e6, 0x2071,
-	0x1a17, 0x7007, 0x0000, 0x9006, 0x701e, 0x7022, 0x7002, 0x2071,
-	0x0000, 0x7010, 0x9085, 0x8044, 0x7012, 0x2071, 0x0080, 0x9006,
-	0x20a9, 0x0040, 0x7022, 0x1f04, 0x10e2, 0x702b, 0x0020, 0x00ee,
-	0x0005, 0x0126, 0x2091, 0x8000, 0x00e6, 0xa06f, 0x0000, 0x2071,
-	0x1a17, 0x701c, 0x9088, 0x1a21, 0x280a, 0x8000, 0x9084, 0x003f,
-	0x701e, 0x7120, 0x9106, 0x090c, 0x0dd5, 0x7004, 0x9005, 0x1128,
-	0x00f6, 0x2079, 0x0080, 0x00a9, 0x00fe, 0x00ee, 0x012e, 0x0005,
-	0x0126, 0x2091, 0x8000, 0x00e6, 0x2071, 0x1a17, 0x7004, 0x9005,
-	0x1128, 0x00f6, 0x2079, 0x0080, 0x0021, 0x00fe, 0x00ee, 0x012e,
-	0x0005, 0x7004, 0x9086, 0x0000, 0x1110, 0x7007, 0x0006, 0x7000,
-	0x0002, 0x112b, 0x12ae, 0x1129, 0x1129, 0x12a2, 0x12a2, 0x12a2,
-	0x12a2, 0x080c, 0x0dd5, 0x701c, 0x7120, 0x9106, 0x1148, 0x792c,
-	0x9184, 0x0001, 0x1120, 0xd1fc, 0x1110, 0x7007, 0x0000, 0x0005,
-	0x0096, 0x9180, 0x1a21, 0x2004, 0x700a, 0x2048, 0x8108, 0x918c,
-	0x003f, 0x7122, 0x782b, 0x0026, 0xa88c, 0x7802, 0xa890, 0x7806,
-	0xa894, 0x780a, 0xa898, 0x780e, 0xa878, 0x700e, 0xa870, 0x7016,
-	0xa874, 0x701a, 0xa868, 0x009e, 0xd084, 0x0120, 0x7007, 0x0001,
-	0x0029, 0x0005, 0x7007, 0x0002, 0x00b1, 0x0005, 0x0016, 0x0026,
-	0x710c, 0x2011, 0x0040, 0x9182, 0x0040, 0x1210, 0x2110, 0x9006,
-	0x700e, 0x7212, 0x8203, 0x7812, 0x782b, 0x0020, 0x782b, 0x0041,
-	0x002e, 0x001e, 0x0005, 0x0016, 0x0026, 0x0136, 0x0146, 0x0156,
-	0x7014, 0x20e0, 0x7018, 0x2098, 0x20e9, 0x0000, 0x20a1, 0x0088,
-	0x782b, 0x0026, 0x710c, 0x2011, 0x0040, 0x9182, 0x0040, 0x1210,
-	0x2110, 0x9006, 0x700e, 0x22a8, 0x4006, 0x8203, 0x7812, 0x782b,
-	0x0020, 0x3300, 0x701a, 0x782b, 0x0001, 0x015e, 0x014e, 0x013e,
-	0x002e, 0x001e, 0x0005, 0x2009, 0x1a17, 0x2104, 0xc095, 0x200a,
-	0x080c, 0x1108, 0x0005, 0x0016, 0x00e6, 0x2071, 0x1a17, 0x00f6,
-	0x2079, 0x0080, 0x792c, 0xd1bc, 0x190c, 0x0dce, 0x782b, 0x0002,
-	0xd1fc, 0x0120, 0x918c, 0x0700, 0x7004, 0x0023, 0x00fe, 0x00ee,
-	0x001e, 0x0005, 0x1119, 0x11c1, 0x11f5, 0x12cd, 0x0dd5, 0x12e8,
-	0x0dd5, 0x918c, 0x0700, 0x1550, 0x0136, 0x0146, 0x0156, 0x7014,
-	0x20e8, 0x7018, 0x20a0, 0x20e1, 0x0000, 0x2099, 0x0088, 0x782b,
-	0x0040, 0x7010, 0x20a8, 0x4005, 0x3400, 0x701a, 0x015e, 0x014e,
-	0x013e, 0x700c, 0x9005, 0x0578, 0x7800, 0x7802, 0x7804, 0x7806,
-	0x080c, 0x115e, 0x0005, 0x7008, 0x0096, 0x2048, 0xa86f, 0x0100,
-	0x009e, 0x7007, 0x0000, 0x080c, 0x1119, 0x0005, 0x7008, 0x0096,
-	0x2048, 0xa86f, 0x0200, 0x009e, 0x0ca0, 0x918c, 0x0700, 0x1150,
-	0x700c, 0x9005, 0x0180, 0x7800, 0x7802, 0x7804, 0x7806, 0x080c,
-	0x1173, 0x0005, 0x7008, 0x0096, 0x2048, 0xa86f, 0x0200, 0x009e,
-	0x7007, 0x0000, 0x0080, 0x0096, 0x7008, 0x2048, 0x7800, 0xa88e,
-	0x7804, 0xa892, 0x7808, 0xa896, 0x780c, 0xa89a, 0xa86f, 0x0100,
-	0x009e, 0x7007, 0x0000, 0x0096, 0x00d6, 0x7008, 0x2048, 0x2001,
-	0x18b9, 0x2004, 0x9906, 0x1128, 0xa89c, 0x080f, 0x00de, 0x009e,
-	0x00a0, 0x00de, 0x009e, 0x0096, 0x00d6, 0x7008, 0x2048, 0x0081,
-	0x0150, 0xa89c, 0x0086, 0x2940, 0x080f, 0x008e, 0x00de, 0x009e,
-	0x080c, 0x1108, 0x0005, 0x00de, 0x009e, 0x080c, 0x1108, 0x0005,
-	0xa8a8, 0xd08c, 0x0005, 0x0096, 0xa0a0, 0x904d, 0x090c, 0x0dd5,
-	0xa06c, 0x908e, 0x0100, 0x0130, 0xa87b, 0x0030, 0xa883, 0x0000,
-	0xa897, 0x4002, 0x080c, 0x6d0b, 0xa09f, 0x0000, 0xa0a3, 0x0000,
-	0x2848, 0x080c, 0x1031, 0x009e, 0x0005, 0x00a6, 0xa0a0, 0x904d,
-	0x090c, 0x0dd5, 0xa06c, 0x908e, 0x0100, 0x0128, 0xa87b, 0x0001,
-	0xa883, 0x0000, 0x00c0, 0xa80c, 0x2050, 0xb004, 0x9005, 0x0198,
-	0xa80e, 0x2050, 0x8006, 0x8006, 0x8007, 0x908c, 0x003f, 0x9084,
-	0xffc0, 0x9080, 0x0002, 0xa076, 0xa172, 0xb000, 0xa07a, 0x2810,
-	0x080c, 0x10e9, 0x00e8, 0xa97c, 0xa894, 0x0016, 0x0006, 0x080c,
-	0x6d0b, 0x000e, 0x001e, 0xd1fc, 0x1138, 0xd1f4, 0x0128, 0x00c6,
-	0x2060, 0x080c, 0xaf43, 0x00ce, 0x7008, 0x2048, 0xa89f, 0x0000,
-	0xa8a3, 0x0000, 0x080c, 0x1031, 0x7007, 0x0000, 0x080c, 0x1108,
-	0x00ae, 0x0005, 0x0126, 0x2091, 0x8000, 0x782b, 0x1001, 0x7007,
-	0x0005, 0x7000, 0xc094, 0x7002, 0x012e, 0x0005, 0x0096, 0x2001,
-	0x192e, 0x204c, 0xa87c, 0x7812, 0xa88c, 0x7802, 0xa890, 0x7806,
-	0xa894, 0x780a, 0xa898, 0x780e, 0x782b, 0x0020, 0x0126, 0x2091,
-	0x8000, 0x782b, 0x0041, 0x7007, 0x0003, 0x7000, 0xc084, 0x7002,
-	0x2900, 0x700a, 0x012e, 0x009e, 0x0005, 0x20e1, 0x0000, 0x2099,
-	0x0088, 0x782b, 0x0040, 0x0096, 0x2001, 0x192e, 0x204c, 0xaa7c,
-	0x009e, 0x080c, 0x8ad0, 0x2009, 0x188c, 0x2104, 0x9084, 0xfffc,
-	0x200a, 0x080c, 0x8939, 0x7007, 0x0000, 0x080c, 0x1119, 0x0005,
-	0x7007, 0x0000, 0x080c, 0x1119, 0x0005, 0x0126, 0x2091, 0x2200,
-	0x2079, 0x0300, 0x2071, 0x1a61, 0x7003, 0x0000, 0x78bf, 0x00f6,
-	0x781b, 0x4800, 0x00c1, 0x7803, 0x0003, 0x780f, 0x0000, 0x20a9,
-	0x03d0, 0x2061, 0xeba8, 0x2c0d, 0x7912, 0xe104, 0x9ce0, 0x0002,
-	0x7916, 0x1f04, 0x1303, 0x7807, 0x0007, 0x7803, 0x0000, 0x7803,
-	0x0001, 0x012e, 0x0005, 0x00c6, 0x7803, 0x0000, 0x7808, 0xd09c,
-	0x0120, 0x7820, 0x080c, 0x1362, 0x0cc8, 0x2001, 0x1a62, 0x2003,
-	0x0000, 0x78ab, 0x0004, 0x78ac, 0xd0ac, 0x1de8, 0x78ab, 0x0002,
-	0x7807, 0x0007, 0x7827, 0x0030, 0x782b, 0x0400, 0x7827, 0x0031,
-	0x782b, 0x1a84, 0x781f, 0xff00, 0x781b, 0xb700, 0x2001, 0x0200,
-	0x2004, 0xd0dc, 0x0110, 0x781f, 0x0303, 0x2061, 0x1a84, 0x602f,
-	0x1cd0, 0x2001, 0x181a, 0x2004, 0x9082, 0x1cd0, 0x6032, 0x603b,
-	0x20ce, 0x2001, 0x3384, 0xd0fc, 0x190c, 0x0dd5, 0x2001, 0x0003,
-	0x2004, 0xd0d4, 0x1118, 0x783f, 0x3384, 0x0020, 0x9084, 0xc000,
-	0x783f, 0xb384, 0x604f, 0x193c, 0x2001, 0x1927, 0x2004, 0x6042,
-	0x00ce, 0x0005, 0x9086, 0x000d, 0x11d0, 0x7808, 0xd09c, 0x01b8,
-	0x7820, 0x0026, 0x2010, 0x080c, 0xcc74, 0x0180, 0x2260, 0x6000,
-	0x9086, 0x0004, 0x1158, 0x0016, 0x6120, 0x9186, 0x0009, 0x0108,
-	0x0020, 0x2009, 0x004c, 0x080c, 0xafbe, 0x001e, 0x002e, 0x0005,
-	0x0126, 0x2091, 0x2200, 0x7908, 0x9184, 0x0070, 0x190c, 0x0dce,
-	0xd19c, 0x0158, 0x7820, 0x908c, 0xf000, 0x15e8, 0x908a, 0x0024,
-	0x1a0c, 0x0dd5, 0x0023, 0x012e, 0x0005, 0x012e, 0x0005, 0x13bb,
-	0x13bb, 0x13d2, 0x13d7, 0x13db, 0x13e0, 0x1408, 0x140c, 0x141a,
-	0x141e, 0x13bb, 0x14eb, 0x14ef, 0x1561, 0x1568, 0x13bb, 0x1569,
-	0x156a, 0x1575, 0x157c, 0x13bb, 0x13bb, 0x13bb, 0x13bb, 0x13bb,
-	0x13bb, 0x13bb, 0x13e2, 0x13bb, 0x13bb, 0x13bb, 0x13bb, 0x13bb,
-	0x13bb, 0x13bf, 0x13bd, 0x080c, 0x0dd5, 0x080c, 0x0dce, 0x080c,
-	0x1587, 0x2009, 0x1a7a, 0x2104, 0x8000, 0x200a, 0x080c, 0x7ed7,
-	0x080c, 0x1aec, 0x0005, 0x2009, 0x0048, 0x2060, 0x080c, 0xafbe,
-	0x012e, 0x0005, 0x7004, 0xc085, 0xc0b5, 0x7006, 0x0005, 0x7004,
-	0xc085, 0x7006, 0x0005, 0x080c, 0x1587, 0x080c, 0x16e7, 0x0005,
-	0x080c, 0x0dd5, 0x080c, 0x1587, 0x2060, 0x6014, 0x0096, 0x2048,
-	0xa83b, 0xffff, 0x009e, 0x2009, 0x0048, 0x080c, 0xafbe, 0x2001,
-	0x015d, 0x2003, 0x0000, 0x2009, 0x03e8, 0x8109, 0x0160, 0x2001,
-	0x0201, 0x2004, 0x9005, 0x0dc8, 0x2001, 0x0218, 0x2004, 0xd0ec,
-	0x1110, 0x080c, 0x158c, 0x2001, 0x0307, 0x2003, 0x8000, 0x0005,
-	0x7004, 0xc095, 0x7006, 0x0005, 0x080c, 0x1587, 0x2060, 0x6014,
-	0x0096, 0x2048, 0xa83b, 0xffff, 0x009e, 0x2009, 0x0048, 0x080c,
-	0xafbe, 0x0005, 0x080c, 0x1587, 0x080c, 0x0dd5, 0x080c, 0x1587,
-	0x080c, 0x14d6, 0x7827, 0x0018, 0x79ac, 0xd1dc, 0x0904, 0x1487,
-	0x7827, 0x0015, 0x7828, 0x782b, 0x0000, 0x9065, 0x0140, 0x2001,
-	0x020d, 0x2003, 0x0050, 0x2003, 0x0020, 0x0804, 0x148d, 0x7004,
-	0x9005, 0x01c8, 0x1188, 0x78ab, 0x0004, 0x7827, 0x0018, 0x782b,
-	0x0000, 0xd1bc, 0x090c, 0x0dd5, 0x2001, 0x020d, 0x2003, 0x0050,
-	0x2003, 0x0020, 0x0804, 0x14bb, 0x78ab, 0x0004, 0x7803, 0x0001,
-	0x080c, 0x14ef, 0x0005, 0x7827, 0x0018, 0xa001, 0x7828, 0x7827,
-	0x0011, 0xa001, 0x7928, 0x9106, 0x0110, 0x79ac, 0x08e0, 0x00e6,
-	0x2071, 0x0200, 0x702c, 0xd0c4, 0x0140, 0x00ee, 0x080c, 0x1aec,
-	0x080c, 0x1313, 0x7803, 0x0001, 0x0005, 0x7037, 0x0001, 0xa001,
-	0x7150, 0x00ee, 0x918c, 0xff00, 0x9186, 0x0500, 0x0110, 0x79ac,
-	0x0810, 0x7004, 0xc09d, 0x7006, 0x78ab, 0x0004, 0x7803, 0x0001,
-	0x080c, 0x14ef, 0x2001, 0x020d, 0x2003, 0x0020, 0x0005, 0x7828,
-	0x782b, 0x0000, 0x9065, 0x090c, 0x0dd5, 0x6014, 0x2048, 0x78ab,
-	0x0004, 0x918c, 0x0700, 0x01a8, 0x080c, 0x7ed7, 0x080c, 0x1aec,
-	0x080c, 0xcc86, 0x0158, 0xa9ac, 0xa936, 0xa9b0, 0xa93a, 0xa83f,
-	0xffff, 0xa843, 0xffff, 0xa880, 0xc0bd, 0xa882, 0x080c, 0xc8a5,
-	0x0005, 0x6020, 0x9086, 0x0009, 0x1128, 0x2009, 0x004c, 0x080c,
-	0xafbe, 0x0048, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc,
-	0x6024, 0x190c, 0xd072, 0x2029, 0x00c8, 0x8529, 0x0128, 0x2001,
-	0x0201, 0x2004, 0x9005, 0x0dc8, 0x7dbc, 0x080c, 0xeb51, 0xd5a4,
-	0x1118, 0x080c, 0x158c, 0x0005, 0x080c, 0x7ed7, 0x080c, 0x1aec,
-	0x0005, 0x781f, 0x0300, 0x7803, 0x0001, 0x0005, 0x0016, 0x0066,
-	0x0076, 0x00f6, 0x2079, 0x0300, 0x7908, 0x918c, 0x0007, 0x9186,
-	0x0003, 0x0120, 0x2001, 0x0016, 0x080c, 0x15fd, 0x00fe, 0x007e,
-	0x006e, 0x001e, 0x0005, 0x7004, 0xc09d, 0x7006, 0x0005, 0x7104,
-	0x9184, 0x0004, 0x190c, 0x0dd5, 0xd184, 0x11b1, 0xd19c, 0x0180,
-	0xc19c, 0x7106, 0x0016, 0x080c, 0x16ca, 0x001e, 0x0148, 0x2001,
-	0x020d, 0x2003, 0x0050, 0x2003, 0x0020, 0x080c, 0x158c, 0x0005,
-	0x81ff, 0x190c, 0x0dd5, 0x0005, 0x2100, 0xc184, 0xc1b4, 0x7106,
-	0xd0b4, 0x0016, 0x00e6, 0x1904, 0x1556, 0x2071, 0x0200, 0x080c,
-	0x16b7, 0x05e0, 0x080c, 0x16ca, 0x05b0, 0x6014, 0x9005, 0x05b0,
-	0x0096, 0x2048, 0xa864, 0x009e, 0x9084, 0x00ff, 0x908e, 0x0029,
-	0x0160, 0x908e, 0x0048, 0x1550, 0x601c, 0xd084, 0x11e0, 0x00f6,
-	0x2c78, 0x080c, 0x1754, 0x00fe, 0x00b0, 0x00f6, 0x2c78, 0x080c,
-	0x18dd, 0x00fe, 0x2009, 0x01f4, 0x8109, 0x0168, 0x2001, 0x0201,
-	0x2004, 0x9005, 0x0dc8, 0x2001, 0x0218, 0x2004, 0xd0ec, 0x1118,
-	0x080c, 0x158c, 0x0040, 0x2001, 0x020d, 0x2003, 0x0020, 0x080c,
-	0x1313, 0x7803, 0x0001, 0x00ee, 0x001e, 0x0005, 0x080c, 0x16ca,
-	0x0dd0, 0x2001, 0x020d, 0x2003, 0x0050, 0x2003, 0x0020, 0x0461,
-	0x0c90, 0x0429, 0x2060, 0x2009, 0x0053, 0x080c, 0xafbe, 0x0005,
-	0x0005, 0x0005, 0x00e1, 0x2008, 0x00d1, 0x0006, 0x7004, 0xc09d,
-	0x7006, 0x000e, 0x080c, 0x8e21, 0x0005, 0x0089, 0x9005, 0x0118,
-	0x080c, 0x8a28, 0x0cd0, 0x0005, 0x2001, 0x0036, 0x2009, 0x1820,
-	0x210c, 0x2011, 0x181f, 0x2214, 0x080c, 0x15fd, 0x0005, 0x7808,
-	0xd09c, 0x0de8, 0x7820, 0x0005, 0x080c, 0x14d6, 0x00d6, 0x2069,
-	0x0200, 0x2009, 0x01f4, 0x8109, 0x0510, 0x6804, 0x9005, 0x0dd8,
-	0x2001, 0x015d, 0x2003, 0x0000, 0x79bc, 0xd1a4, 0x1528, 0x79b8,
-	0x918c, 0x0fff, 0x0180, 0x9182, 0x0841, 0x1268, 0x9188, 0x0007,
-	0x918c, 0x0ff8, 0x810c, 0x810c, 0x810c, 0x080c, 0x15ef, 0x6827,
-	0x0001, 0x8109, 0x1dd0, 0x04d9, 0x6827, 0x0002, 0x04c1, 0x6804,
-	0x9005, 0x1130, 0x682c, 0xd0e4, 0x1500, 0x6804, 0x9005, 0x0de8,
-	0x79b8, 0xd1ec, 0x1130, 0x08c0, 0x080c, 0x7ed7, 0x080c, 0x1aec,
-	0x0090, 0x7827, 0x0015, 0x782b, 0x0000, 0x7827, 0x0018, 0x782b,
-	0x0000, 0x2001, 0x020d, 0x2003, 0x0020, 0x2001, 0x0307, 0x2003,
-	0x0300, 0x7803, 0x0001, 0x00de, 0x0005, 0x682c, 0x9084, 0x5400,
-	0x9086, 0x5400, 0x0d30, 0x7827, 0x0015, 0x782b, 0x0000, 0x7803,
-	0x0001, 0x6800, 0x9085, 0x1800, 0x6802, 0x00de, 0x0005, 0x6824,
-	0x9084, 0x0003, 0x1de0, 0x0005, 0x2001, 0x0030, 0x2c08, 0x621c,
-	0x0021, 0x7830, 0x9086, 0x0041, 0x0005, 0x00f6, 0x2079, 0x0300,
-	0x0006, 0x7808, 0xd09c, 0x0140, 0x0016, 0x0026, 0x00c6, 0x080c,
-	0x1380, 0x00ce, 0x002e, 0x001e, 0x000e, 0x0006, 0x7832, 0x7936,
-	0x7a3a, 0x781b, 0x8080, 0x0059, 0x1118, 0x000e, 0x00fe, 0x0005,
-	0x000e, 0x792c, 0x3900, 0x8000, 0x2004, 0x080c, 0x0dd5, 0x2009,
-	0x180c, 0x2104, 0xc0f4, 0x200a, 0x2009, 0xff00, 0x8109, 0x0904,
-	0x167b, 0x7a18, 0x9284, 0x0030, 0x0904, 0x1676, 0x9284, 0x0048,
-	0x9086, 0x0008, 0x1904, 0x1676, 0x2001, 0x0109, 0x2004, 0xd08c,
-	0x01f0, 0x0006, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x0126,
-	0x2091, 0x2800, 0x00f6, 0x0026, 0x0016, 0x2009, 0x1a7d, 0x2104,
-	0x8000, 0x0208, 0x200a, 0x080c, 0x9163, 0x001e, 0x002e, 0x00fe,
-	0x012e, 0x015e, 0x014e, 0x013e, 0x01de, 0x01ce, 0x000e, 0x2001,
-	0x009b, 0x2004, 0xd0fc, 0x01d0, 0x0006, 0x0126, 0x01c6, 0x01d6,
-	0x0136, 0x0146, 0x0156, 0x00f6, 0x0016, 0x2009, 0x1a7e, 0x2104,
-	0x8000, 0x0208, 0x200a, 0x080c, 0x1ef2, 0x001e, 0x00fe, 0x015e,
-	0x014e, 0x013e, 0x01de, 0x01ce, 0x012e, 0x000e, 0x7818, 0xd0bc,
-	0x1904, 0x1626, 0x0005, 0x2001, 0x180c, 0x2004, 0xd0f4, 0x1528,
-	0x7a18, 0x9284, 0x0030, 0x0508, 0x9284, 0x0048, 0x9086, 0x0008,
-	0x11e0, 0x2001, 0x19f5, 0x2004, 0x9005, 0x01b8, 0x2001, 0x1a65,
-	0x2004, 0x9086, 0x0000, 0x0188, 0x2009, 0x1a7c, 0x2104, 0x8000,
-	0x0208, 0x200a, 0x080c, 0xa3d4, 0x2009, 0x180c, 0x2104, 0xc0f5,
-	0x200a, 0x2009, 0xff00, 0x0804, 0x1626, 0x9085, 0x0001, 0x0005,
-	0x7832, 0x7936, 0x7a3a, 0x781b, 0x8080, 0x080c, 0x161f, 0x1108,
-	0x0005, 0x792c, 0x3900, 0x8000, 0x2004, 0x080c, 0x0dd5, 0x7037,
-	0x0001, 0x7150, 0x7037, 0x0002, 0x7050, 0x2060, 0xd1bc, 0x1110,
-	0x7054, 0x2060, 0x918c, 0xff00, 0x9186, 0x0500, 0x0110, 0x9085,
-	0x0001, 0x0005, 0x0006, 0x0046, 0x00e6, 0x2071, 0x0200, 0x7037,
-	0x0002, 0x7058, 0x9084, 0xff00, 0x8007, 0x9086, 0x00bc, 0x1158,
-	0x2021, 0x1a7b, 0x2404, 0x8000, 0x0208, 0x2022, 0x080c, 0x7ed7,
-	0x080c, 0x1aec, 0x9006, 0x00ee, 0x004e, 0x000e, 0x0005, 0x0c11,
-	0x1108, 0x0005, 0x00e6, 0x0016, 0x2071, 0x0200, 0x0841, 0x6124,
-	0xd1dc, 0x01f8, 0x701c, 0xd08c, 0x0904, 0x1749, 0x7017, 0x0000,
-	0x2001, 0x0264, 0x2004, 0xd0bc, 0x0904, 0x1749, 0x2001, 0x0268,
-	0x00c6, 0x2064, 0x6104, 0x6038, 0x00ce, 0x918e, 0x0039, 0x1904,
-	0x1749, 0x9c06, 0x15f0, 0x0126, 0x2091, 0x2600, 0x080c, 0x7e1e,
-	0x012e, 0x7358, 0x745c, 0x6014, 0x905d, 0x0598, 0x2b48, 0x6010,
-	0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x190c, 0xd04d, 0xab42,
-	0xac3e, 0x2001, 0x1869, 0x2004, 0xd0b4, 0x1170, 0x601c, 0xd0e4,
-	0x1158, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x1120,
-	0xa83b, 0x7fff, 0xa837, 0xffff, 0x080c, 0x20ee, 0x1190, 0x080c,
-	0x193a, 0x2a00, 0xa816, 0x0130, 0x2800, 0xa80e, 0x2c05, 0xa80a,
-	0x2c00, 0xa812, 0x7037, 0x0020, 0x781f, 0x0300, 0x001e, 0x00ee,
-	0x0005, 0x7037, 0x0050, 0x7037, 0x0020, 0x001e, 0x00ee, 0x080c,
-	0x158c, 0x0005, 0x080c, 0x0dd5, 0x2ff0, 0x0126, 0x2091, 0x2200,
-	0x0016, 0x00c6, 0x3e60, 0x6014, 0x2048, 0x2940, 0x903e, 0x2730,
-	0xa864, 0x2068, 0xa81a, 0x9d84, 0x000f, 0x9088, 0x20ce, 0x2165,
-	0x0002, 0x1780, 0x17ee, 0x1780, 0x1780, 0x1784, 0x17cf, 0x1780,
-	0x17a4, 0x1779, 0x17e5, 0x1780, 0x1780, 0x1789, 0x18db, 0x17b8,
-	0x17ae, 0xa964, 0x918c, 0x00ff, 0x918e, 0x0048, 0x0904, 0x17e5,
-	0x9085, 0x0001, 0x0804, 0x18d1, 0xa87c, 0xd0ac, 0x0dc8, 0x0804,
-	0x17f5, 0xa87c, 0xd0ac, 0x0da0, 0x0804, 0x1860, 0xa898, 0x901d,
-	0x1108, 0xab9c, 0x9016, 0xaab2, 0xaa3e, 0xaa42, 0x3e00, 0x9080,
-	0x0008, 0x2004, 0x9080, 0x8fef, 0x2005, 0x9005, 0x090c, 0x0dd5,
-	0x2004, 0xa8ae, 0x0804, 0x18b9, 0xa87c, 0xd0bc, 0x09c8, 0xa890,
-	0xa842, 0xa88c, 0xa83e, 0xa888, 0x0804, 0x17f5, 0xa87c, 0xd0bc,
-	0x0978, 0xa890, 0xa842, 0xa88c, 0xa83e, 0xa888, 0x0804, 0x1860,
-	0xa87c, 0xd0bc, 0x0928, 0xa890, 0xa842, 0xa88c, 0xa83e, 0xa804,
-	0x9045, 0x090c, 0x0dd5, 0xa164, 0xa91a, 0x91ec, 0x000f, 0x9d80,
-	0x20ce, 0x2065, 0xa888, 0xd19c, 0x1904, 0x1860, 0x0430, 0xa87c,
-	0xd0ac, 0x0904, 0x1780, 0xa804, 0x9045, 0x090c, 0x0dd5, 0xa164,
-	0xa91a, 0x91ec, 0x000f, 0x9d80, 0x20ce, 0x2065, 0x9006, 0xa842,
-	0xa83e, 0xd19c, 0x1904, 0x1860, 0x0080, 0xa87c, 0xd0ac, 0x0904,
-	0x1780, 0x9006, 0xa842, 0xa83e, 0x0804, 0x1860, 0xa87c, 0xd0ac,
-	0x0904, 0x1780, 0x9006, 0xa842, 0xa83e, 0x2c05, 0x908a, 0x0036,
-	0x1a0c, 0x0dd5, 0x9082, 0x001b, 0x0002, 0x1818, 0x1818, 0x181a,
-	0x1818, 0x1818, 0x1818, 0x1824, 0x1818, 0x1818, 0x1818, 0x182e,
-	0x1818, 0x1818, 0x1818, 0x1838, 0x1818, 0x1818, 0x1818, 0x1842,
-	0x1818, 0x1818, 0x1818, 0x184c, 0x1818, 0x1818, 0x1818, 0x1856,
-	0x080c, 0x0dd5, 0xa574, 0xa478, 0x9d86, 0x0024, 0x0904, 0x178e,
-	0xa37c, 0xa280, 0x0804, 0x18b9, 0xa584, 0xa488, 0x9d86, 0x0024,
-	0x0904, 0x178e, 0xa38c, 0xa290, 0x0804, 0x18b9, 0xa594, 0xa498,
-	0x9d86, 0x0024, 0x0904, 0x178e, 0xa39c, 0xa2a0, 0x0804, 0x18b9,
-	0xa5a4, 0xa4a8, 0x9d86, 0x0024, 0x0904, 0x178e, 0xa3ac, 0xa2b0,
-	0x0804, 0x18b9, 0xa5b4, 0xa4b8, 0x9d86, 0x0024, 0x0904, 0x178e,
-	0xa3bc, 0xa2c0, 0x0804, 0x18b9, 0xa5c4, 0xa4c8, 0x9d86, 0x0024,
-	0x0904, 0x178e, 0xa3cc, 0xa2d0, 0x0804, 0x18b9, 0xa5d4, 0xa4d8,
-	0x9d86, 0x0024, 0x0904, 0x178e, 0xa3dc, 0xa2e0, 0x0804, 0x18b9,
-	0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0dd5, 0x9082, 0x001b, 0x0002,
-	0x1883, 0x1881, 0x1881, 0x1881, 0x1881, 0x1881, 0x188e, 0x1881,
-	0x1881, 0x1881, 0x1881, 0x1881, 0x1899, 0x1881, 0x1881, 0x1881,
-	0x1881, 0x1881, 0x18a4, 0x1881, 0x1881, 0x1881, 0x1881, 0x1881,
-	0x18af, 0x080c, 0x0dd5, 0xa56c, 0xa470, 0xa774, 0xa678, 0x9d86,
-	0x002c, 0x0904, 0x178e, 0xa37c, 0xa280, 0x0458, 0xa584, 0xa488,
-	0xa78c, 0xa690, 0x9d86, 0x002c, 0x0904, 0x178e, 0xa394, 0xa298,
-	0x0400, 0xa59c, 0xa4a0, 0xa7a4, 0xa6a8, 0x9d86, 0x002c, 0x0904,
-	0x178e, 0xa3ac, 0xa2b0, 0x00a8, 0xa5b4, 0xa4b8, 0xa7bc, 0xa6c0,
-	0x9d86, 0x002c, 0x0904, 0x178e, 0xa3c4, 0xa2c8, 0x0050, 0xa5cc,
-	0xa4d0, 0xa7d4, 0xa6d8, 0x9d86, 0x002c, 0x0904, 0x178e, 0xa3dc,
-	0xa2e0, 0xab2e, 0xaa32, 0xad1e, 0xac22, 0xaf26, 0xae2a, 0xa988,
-	0x8c60, 0x2c1d, 0xa8ac, 0xaab0, 0xa836, 0xaa3a, 0x8109, 0xa916,
-	0x1160, 0x3e60, 0x601c, 0xc085, 0x601e, 0xa87c, 0xc0dd, 0xa87e,
-	0x9006, 0x00ce, 0x001e, 0x012e, 0x0005, 0x2800, 0xa80e, 0xab0a,
-	0x2c00, 0xa812, 0x0c70, 0x0804, 0x1780, 0x2ff0, 0x0126, 0x2091,
-	0x2200, 0x0016, 0x00c6, 0x3e60, 0x6014, 0x2048, 0x2940, 0xa80e,
-	0x2061, 0x20c9, 0xa813, 0x20c9, 0x2c05, 0xa80a, 0xa964, 0xa91a,
-	0xa87c, 0xd0ac, 0x090c, 0x0dd5, 0x9006, 0xa842, 0xa83e, 0x2c05,
-	0x908a, 0x0034, 0x1a0c, 0x0dd5, 0xadcc, 0xacd0, 0xafd4, 0xaed8,
-	0xabdc, 0xaae0, 0xab2e, 0xaa32, 0xad1e, 0xac22, 0xaf26, 0xae2a,
-	0xa8ac, 0xaab0, 0xa836, 0xaa3a, 0xa988, 0xa864, 0x9084, 0x00ff,
-	0x9086, 0x0008, 0x1120, 0x8109, 0xa916, 0x0128, 0x0080, 0x918a,
-	0x0002, 0xa916, 0x1160, 0x3e60, 0x601c, 0xc085, 0x601e, 0xa87c,
-	0xc0dd, 0xa87e, 0x9006, 0x00ce, 0x001e, 0x012e, 0x0005, 0xa804,
-	0x9045, 0x090c, 0x0dd5, 0xa80e, 0xa064, 0xa81a, 0x9084, 0x000f,
-	0x9080, 0x20ce, 0x2015, 0x82ff, 0x090c, 0x0dd5, 0xaa12, 0x2205,
-	0xa80a, 0x0c08, 0x903e, 0x2730, 0xa880, 0xd0fc, 0x1190, 0x2d00,
-	0x0002, 0x1a64, 0x1991, 0x1991, 0x1a64, 0x1991, 0x1a5e, 0x1a64,
-	0x1991, 0x1a01, 0x1a01, 0x1a01, 0x1a64, 0x1a01, 0x1a64, 0x1a5b,
-	0x1a01, 0xc0fc, 0xa882, 0xab2c, 0xaa30, 0xad1c, 0xac20, 0xdd9c,
-	0x0904, 0x1a66, 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0dd5, 0x9082,
-	0x001b, 0x0002, 0x197d, 0x197b, 0x197b, 0x197b, 0x197b, 0x197b,
-	0x1981, 0x197b, 0x197b, 0x197b, 0x197b, 0x197b, 0x1985, 0x197b,
-	0x197b, 0x197b, 0x197b, 0x197b, 0x1989, 0x197b, 0x197b, 0x197b,
-	0x197b, 0x197b, 0x198d, 0x080c, 0x0dd5, 0xa774, 0xa678, 0x0804,
-	0x1a66, 0xa78c, 0xa690, 0x0804, 0x1a66, 0xa7a4, 0xa6a8, 0x0804,
-	0x1a66, 0xa7bc, 0xa6c0, 0x0804, 0x1a66, 0xa7d4, 0xa6d8, 0x0804,
-	0x1a66, 0xa898, 0x901d, 0x1108, 0xab9c, 0x9016, 0x2c05, 0x908a,
-	0x0036, 0x1a0c, 0x0dd5, 0x9082, 0x001b, 0x0002, 0x19b9, 0x19b9,
-	0x19bb, 0x19b9, 0x19b9, 0x19b9, 0x19c5, 0x19b9, 0x19b9, 0x19b9,
-	0x19cf, 0x19b9, 0x19b9, 0x19b9, 0x19d9, 0x19b9, 0x19b9, 0x19b9,
-	0x19e3, 0x19b9, 0x19b9, 0x19b9, 0x19ed, 0x19b9, 0x19b9, 0x19b9,
-	0x19f7, 0x080c, 0x0dd5, 0xa574, 0xa478, 0x9d86, 0x0004, 0x0904,
-	0x1a66, 0xa37c, 0xa280, 0x0804, 0x1a66, 0xa584, 0xa488, 0x9d86,
-	0x0004, 0x0904, 0x1a66, 0xa38c, 0xa290, 0x0804, 0x1a66, 0xa594,
-	0xa498, 0x9d86, 0x0004, 0x0904, 0x1a66, 0xa39c, 0xa2a0, 0x0804,
-	0x1a66, 0xa5a4, 0xa4a8, 0x9d86, 0x0004, 0x0904, 0x1a66, 0xa3ac,
-	0xa2b0, 0x0804, 0x1a66, 0xa5b4, 0xa4b8, 0x9d86, 0x0004, 0x0904,
-	0x1a66, 0xa3bc, 0xa2c0, 0x0804, 0x1a66, 0xa5c4, 0xa4c8, 0x9d86,
-	0x0004, 0x0904, 0x1a66, 0xa3cc, 0xa2d0, 0x0804, 0x1a66, 0xa5d4,
-	0xa4d8, 0x9d86, 0x0004, 0x0904, 0x1a66, 0xa3dc, 0xa2e0, 0x0804,
-	0x1a66, 0xa898, 0x901d, 0x1108, 0xab9c, 0x9016, 0x2c05, 0x908a,
-	0x0034, 0x1a0c, 0x0dd5, 0x9082, 0x001b, 0x0002, 0x1a29, 0x1a27,
-	0x1a27, 0x1a27, 0x1a27, 0x1a27, 0x1a33, 0x1a27, 0x1a27, 0x1a27,
-	0x1a27, 0x1a27, 0x1a3d, 0x1a27, 0x1a27, 0x1a27, 0x1a27, 0x1a27,
-	0x1a47, 0x1a27, 0x1a27, 0x1a27, 0x1a27, 0x1a27, 0x1a51, 0x080c,
-	0x0dd5, 0xa56c, 0xa470, 0xa774, 0xa678, 0x9d86, 0x000c, 0x05b0,
-	0xa37c, 0xa280, 0x0498, 0xa584, 0xa488, 0xa78c, 0xa690, 0x9d86,
-	0x000c, 0x0560, 0xa394, 0xa298, 0x0448, 0xa59c, 0xa4a0, 0xa7a4,
-	0xa6a8, 0x9d86, 0x000c, 0x0510, 0xa3ac, 0xa2b0, 0x00f8, 0xa5b4,
-	0xa4b8, 0xa7bc, 0xa6c0, 0x9d86, 0x000c, 0x01c0, 0xa3c4, 0xa2c8,
-	0x00a8, 0xa5cc, 0xa4d0, 0xa7d4, 0xa6d8, 0x9d86, 0x000c, 0x0170,
-	0xa3dc, 0xa2e0, 0x0058, 0x9d86, 0x000e, 0x1130, 0x080c, 0x2086,
-	0x1904, 0x193a, 0x900e, 0x0050, 0x080c, 0x0dd5, 0xab2e, 0xaa32,
-	0xad1e, 0xac22, 0xaf26, 0xae2a, 0x080c, 0x2086, 0x0005, 0x6014,
-	0x2048, 0x6118, 0x810c, 0x810c, 0x810c, 0x81ff, 0x1118, 0xa887,
-	0x0001, 0x0008, 0xa986, 0x601b, 0x0002, 0xa874, 0x9084, 0x00ff,
-	0x9084, 0x0008, 0x0150, 0x00e9, 0x6000, 0x9086, 0x0004, 0x1120,
-	0x2009, 0x0048, 0x080c, 0xafbe, 0x0005, 0xa974, 0xd1dc, 0x1108,
-	0x0005, 0xa934, 0xa88c, 0x9106, 0x1158, 0xa938, 0xa890, 0x9106,
-	0x1138, 0x601c, 0xc084, 0x601e, 0x2009, 0x0048, 0x0804, 0xafbe,
-	0x0005, 0x0126, 0x00c6, 0x2091, 0x2200, 0x00ce, 0x7908, 0x918c,
-	0x0007, 0x9186, 0x0000, 0x05b0, 0x9186, 0x0003, 0x0598, 0x6020,
-	0x6023, 0x0000, 0x0006, 0x2031, 0x0008, 0x00c6, 0x781f, 0x0808,
-	0x7808, 0xd09c, 0x0120, 0x080c, 0x1380, 0x8631, 0x1db8, 0x00ce,
-	0x781f, 0x0800, 0x2031, 0x0168, 0x00c6, 0x7808, 0xd09c, 0x190c,
-	0x1380, 0x00ce, 0x2001, 0x0038, 0x080c, 0x1b74, 0x7930, 0x9186,
-	0x0040, 0x0160, 0x9186, 0x0042, 0x190c, 0x0dd5, 0x2001, 0x001e,
-	0x8001, 0x1df0, 0x8631, 0x1d40, 0x080c, 0x1b83, 0x000e, 0x6022,
-	0x012e, 0x0005, 0x080c, 0x1b70, 0x7827, 0x0015, 0x7828, 0x9c06,
-	0x1db8, 0x782b, 0x0000, 0x0ca0, 0x00f6, 0x2079, 0x0300, 0x7803,
-	0x0000, 0x78ab, 0x0004, 0x00fe, 0x080c, 0x743e, 0x1188, 0x2001,
-	0x0138, 0x2003, 0x0000, 0x2001, 0x0160, 0x2003, 0x0000, 0x2011,
-	0x012c, 0xa001, 0xa001, 0x8211, 0x1de0, 0x0059, 0x0804, 0x74ee,
-	0x0479, 0x0039, 0x2001, 0x0160, 0x2502, 0x2001, 0x0138, 0x2202,
-	0x0005, 0x00e6, 0x2071, 0x0200, 0x080c, 0x2c82, 0x2009, 0x003c,
-	0x080c, 0x2410, 0x2001, 0x015d, 0x2003, 0x0000, 0x7000, 0x9084,
-	0x003c, 0x1de0, 0x080c, 0x84c2, 0x70a0, 0x70a2, 0x7098, 0x709a,
-	0x709c, 0x709e, 0x2001, 0x020d, 0x2003, 0x0020, 0x00f6, 0x2079,
-	0x0300, 0x080c, 0x1313, 0x7803, 0x0001, 0x00fe, 0x00ee, 0x0005,
-	0x2001, 0x0138, 0x2014, 0x2003, 0x0000, 0x2001, 0x0160, 0x202c,
-	0x2003, 0x0000, 0x080c, 0x743e, 0x1108, 0x0005, 0x2021, 0x0260,
-	0x2001, 0x0141, 0x201c, 0xd3dc, 0x1168, 0x2001, 0x0109, 0x201c,
-	0x939c, 0x0048, 0x1160, 0x2001, 0x0111, 0x201c, 0x83ff, 0x1110,
-	0x8421, 0x1d70, 0x2001, 0x015d, 0x2003, 0x0000, 0x0005, 0x0046,
-	0x2021, 0x0019, 0x2003, 0x0048, 0xa001, 0xa001, 0x201c, 0x939c,
-	0x0048, 0x0120, 0x8421, 0x1db0, 0x004e, 0x0c60, 0x004e, 0x0c40,
-	0x601c, 0xc084, 0x601e, 0x0005, 0x2c08, 0x621c, 0x080c, 0x15fd,
-	0x7930, 0x0005, 0x2c08, 0x621c, 0x080c, 0x16a8, 0x7930, 0x0005,
-	0x8001, 0x1df0, 0x0005, 0x2031, 0x0064, 0x781c, 0x9084, 0x0007,
-	0x0170, 0x2001, 0x0038, 0x0c41, 0x9186, 0x0040, 0x0904, 0x1be1,
-	0x2001, 0x001e, 0x0c69, 0x8631, 0x1d80, 0x080c, 0x0dd5, 0x781f,
-	0x0202, 0x2001, 0x015d, 0x2003, 0x0000, 0x2001, 0x0dac, 0x0c01,
-	0x781c, 0xd084, 0x0110, 0x0861, 0x04e0, 0x2001, 0x0030, 0x0891,
-	0x9186, 0x0040, 0x0568, 0x781c, 0xd084, 0x1da8, 0x781f, 0x0101,
-	0x2001, 0x0014, 0x0869, 0x2001, 0x0037, 0x0821, 0x9186, 0x0040,
-	0x0140, 0x2001, 0x0030, 0x080c, 0x1b7a, 0x9186, 0x0040, 0x190c,
-	0x0dd5, 0x00d6, 0x2069, 0x0200, 0x692c, 0xd1f4, 0x1170, 0xd1c4,
-	0x0160, 0xd19c, 0x0130, 0x6800, 0x9085, 0x1800, 0x6802, 0x00de,
-	0x0080, 0x6908, 0x9184, 0x0007, 0x1db0, 0x00de, 0x781f, 0x0100,
-	0x791c, 0x9184, 0x0007, 0x090c, 0x0dd5, 0xa001, 0xa001, 0x781f,
-	0x0200, 0x0005, 0x0126, 0x2091, 0x2400, 0x2071, 0x1a65, 0x2079,
-	0x0090, 0x012e, 0x0005, 0x9280, 0x0005, 0x2004, 0x2048, 0xa97c,
-	0xd1dc, 0x1904, 0x1c83, 0xa964, 0x9184, 0x0007, 0x0002, 0x1bff,
-	0x1c6e, 0x1c16, 0x1c18, 0x1c16, 0x1c56, 0x1c36, 0x1c25, 0x918c,
-	0x00ff, 0x9186, 0x0008, 0x1170, 0xa87c, 0xd0b4, 0x0904, 0x1ead,
-	0x9006, 0xa842, 0xa83e, 0xa988, 0x2900, 0xa85a, 0xa813, 0x20c9,
-	0x0804, 0x1c7f, 0x9186, 0x0048, 0x0904, 0x1c6e, 0x080c, 0x0dd5,
-	0x9184, 0x00ff, 0x9086, 0x0013, 0x0904, 0x1c6e, 0x9184, 0x00ff,
-	0x9086, 0x001b, 0x0904, 0x1c6e, 0x0c88, 0xa87c, 0xd0b4, 0x0904,
-	0x1ead, 0xa890, 0xa842, 0xa83a, 0xa88c, 0xa83e, 0xa836, 0xa8ac,
-	0xa846, 0xa8b0, 0xa84a, 0xa988, 0x0804, 0x1c76, 0xa864, 0x9084,
-	0x00ff, 0x9086, 0x001e, 0x19d0, 0xa87c, 0xd0b4, 0x0904, 0x1ead,
-	0xa890, 0xa842, 0xa83a, 0xa88c, 0xa83e, 0xa836, 0xa8ac, 0xa846,
-	0xa8b0, 0xa84a, 0xa804, 0xa85a, 0x2040, 0xa064, 0x9084, 0x000f,
-	0x9080, 0x20ce, 0x2005, 0xa812, 0xa988, 0x0448, 0x918c, 0x00ff,
-	0x9186, 0x0015, 0x1540, 0xa87c, 0xd0b4, 0x0904, 0x1ead, 0xa804,
-	0xa85a, 0x2040, 0xa064, 0x9084, 0x000f, 0x9080, 0x20ce, 0x2005,
-	0xa812, 0xa988, 0x9006, 0xa842, 0xa83e, 0x0088, 0xa87c, 0xd0b4,
-	0x0904, 0x1ead, 0xa988, 0x9006, 0xa842, 0xa83e, 0x2900, 0xa85a,
-	0xa864, 0x9084, 0x000f, 0x9080, 0x20ce, 0x2005, 0xa812, 0xa916,
-	0xa87c, 0xc0dd, 0xa87e, 0x0005, 0x00f6, 0x2079, 0x0090, 0x782c,
-	0xd0fc, 0x190c, 0x1ef2, 0x00e6, 0x2071, 0x1a65, 0x7000, 0x9005,
-	0x1904, 0x1cec, 0x7206, 0x9280, 0x0005, 0x204c, 0x9280, 0x0004,
-	0x2004, 0x782b, 0x0004, 0x00f6, 0x2079, 0x0200, 0x7803, 0x0040,
-	0x00fe, 0x00b6, 0x2058, 0xb86c, 0x7836, 0xb890, 0x00be, 0x00f6,
-	0x2079, 0x0200, 0x7803, 0x0040, 0xa001, 0xa001, 0xa001, 0xa001,
-	0xa001, 0xa001, 0x781a, 0x2079, 0x0100, 0x8004, 0x78d6, 0x00fe,
-	0xa814, 0x2050, 0xa858, 0x2040, 0xa810, 0x2060, 0xa064, 0x90ec,
-	0x000f, 0xa944, 0x791a, 0x7116, 0xa848, 0x781e, 0x701a, 0x9006,
-	0x700e, 0x7012, 0x7004, 0xa940, 0xa838, 0x9106, 0x1500, 0xa93c,
-	0xa834, 0x9106, 0x11e0, 0x0006, 0x0016, 0xa938, 0xa834, 0x9105,
-	0x0118, 0x001e, 0x000e, 0x0098, 0x001e, 0x000e, 0x8aff, 0x01c8,
-	0x0126, 0x2091, 0x8000, 0x2009, 0x0306, 0x200b, 0x0808, 0x00d9,
-	0x0108, 0x00c9, 0x012e, 0x9006, 0x00ee, 0x00fe, 0x0005, 0x0036,
-	0x0046, 0xab38, 0xac34, 0x080c, 0x20ee, 0x004e, 0x003e, 0x0d30,
-	0x0c98, 0x9085, 0x0001, 0x0c80, 0x2009, 0x0306, 0x200b, 0x4800,
-	0x7027, 0x0000, 0x0005, 0x0076, 0x0066, 0x0056, 0x0046, 0x0036,
-	0x0026, 0x8aff, 0x0904, 0x1ea6, 0x700c, 0x7214, 0x923a, 0x7010,
-	0x7218, 0x9203, 0x0a04, 0x1ea5, 0x9705, 0x0904, 0x1ea5, 0x903e,
-	0x2730, 0xa880, 0xd0fc, 0x1190, 0x2d00, 0x0002, 0x1e2f, 0x1d6e,
-	0x1d6e, 0x1e2f, 0x1e2f, 0x1e0c, 0x1e2f, 0x1d6e, 0x1e13, 0x1dbd,
-	0x1dbd, 0x1e2f, 0x1e2f, 0x1e2f, 0x1e06, 0x1dbd, 0xc0fc, 0xa882,
-	0xab2c, 0xaa30, 0xad1c, 0xac20, 0xdd9c, 0x0904, 0x1e3c, 0x2c05,
-	0x908a, 0x0034, 0x1a0c, 0x0dd5, 0x9082, 0x001b, 0x0002, 0x1d5a,
-	0x1d58, 0x1d58, 0x1d58, 0x1d58, 0x1d58, 0x1d5e, 0x1d58, 0x1d58,
-	0x1d58, 0x1d58, 0x1d58, 0x1d62, 0x1d58, 0x1d58, 0x1d58, 0x1d58,
-	0x1d58, 0x1d66, 0x1d58, 0x1d58, 0x1d58, 0x1d58, 0x1d58, 0x1d6a,
-	0x080c, 0x0dd5, 0xa774, 0xa678, 0x0804, 0x1e3c, 0xa78c, 0xa690,
-	0x0804, 0x1e3c, 0xa7a4, 0xa6a8, 0x0804, 0x1e3c, 0xa7bc, 0xa6c0,
-	0x0804, 0x1e3c, 0xa7d4, 0xa6d8, 0x0804, 0x1e3c, 0x2c05, 0x908a,
-	0x0036, 0x1a0c, 0x0dd5, 0x9082, 0x001b, 0x0002, 0x1d91, 0x1d91,
-	0x1d93, 0x1d91, 0x1d91, 0x1d91, 0x1d99, 0x1d91, 0x1d91, 0x1d91,
-	0x1d9f, 0x1d91, 0x1d91, 0x1d91, 0x1da5, 0x1d91, 0x1d91, 0x1d91,
-	0x1dab, 0x1d91, 0x1d91, 0x1d91, 0x1db1, 0x1d91, 0x1d91, 0x1d91,
-	0x1db7, 0x080c, 0x0dd5, 0xa574, 0xa478, 0xa37c, 0xa280, 0x0804,
-	0x1e3c, 0xa584, 0xa488, 0xa38c, 0xa290, 0x0804, 0x1e3c, 0xa594,
-	0xa498, 0xa39c, 0xa2a0, 0x0804, 0x1e3c, 0xa5a4, 0xa4a8, 0xa3ac,
-	0xa2b0, 0x0804, 0x1e3c, 0xa5b4, 0xa4b8, 0xa3bc, 0xa2c0, 0x0804,
-	0x1e3c, 0xa5c4, 0xa4c8, 0xa3cc, 0xa2d0, 0x0804, 0x1e3c, 0xa5d4,
-	0xa4d8, 0xa3dc, 0xa2e0, 0x0804, 0x1e3c, 0x2c05, 0x908a, 0x0034,
-	0x1a0c, 0x0dd5, 0x9082, 0x001b, 0x0002, 0x1de0, 0x1dde, 0x1dde,
-	0x1dde, 0x1dde, 0x1dde, 0x1de8, 0x1dde, 0x1dde, 0x1dde, 0x1dde,
-	0x1dde, 0x1df0, 0x1dde, 0x1dde, 0x1dde, 0x1dde, 0x1dde, 0x1df8,
-	0x1dde, 0x1dde, 0x1dde, 0x1dde, 0x1dde, 0x1dff, 0x080c, 0x0dd5,
-	0xa56c, 0xa470, 0xa774, 0xa678, 0xa37c, 0xa280, 0x0804, 0x1e3c,
-	0xa584, 0xa488, 0xa78c, 0xa690, 0xa394, 0xa298, 0x0804, 0x1e3c,
-	0xa59c, 0xa4a0, 0xa7a4, 0xa6a8, 0xa3ac, 0xa2b0, 0x0804, 0x1e3c,
-	0xa5b4, 0xa4b8, 0xa7bc, 0xa6c0, 0xa3c4, 0xa2c8, 0x04e8, 0xa5cc,
-	0xa4d0, 0xa7d4, 0xa6d8, 0xa3dc, 0xa2e0, 0x04b0, 0xa864, 0x9084,
-	0x00ff, 0x9086, 0x001e, 0x1518, 0x080c, 0x2086, 0x1904, 0x1d09,
-	0x900e, 0x0804, 0x1ea6, 0xab64, 0x939c, 0x00ff, 0x9386, 0x0048,
-	0x1180, 0x00c6, 0x7004, 0x2060, 0x6004, 0x9086, 0x0043, 0x00ce,
-	0x0904, 0x1dbd, 0xab9c, 0x9016, 0xad8c, 0xac90, 0xaf94, 0xae98,
-	0x0098, 0x9386, 0x0008, 0x0904, 0x1dbd, 0x080c, 0x0dd5, 0xa964,
-	0x918c, 0x00ff, 0x9186, 0x0013, 0x0904, 0x1d6e, 0x9186, 0x001b,
-	0x0904, 0x1dbd, 0x080c, 0x0dd5, 0x2009, 0x030f, 0x2104, 0xd0fc,
-	0x0530, 0x0066, 0x2009, 0x0306, 0x2104, 0x9084, 0x0030, 0x15c8,
-	0x2031, 0x1000, 0x200b, 0x4000, 0x2600, 0x9302, 0x928b, 0x0000,
-	0xa82e, 0xa932, 0x0278, 0x9105, 0x0168, 0x2011, 0x0000, 0x2618,
-	0x2600, 0x9500, 0xa81e, 0x9481, 0x0000, 0xa822, 0xa880, 0xc0fd,
-	0xa882, 0x0020, 0xa82f, 0x0000, 0xa833, 0x0000, 0x006e, 0x7b12,
-	0x7a16, 0x7d02, 0x7c06, 0x7f0a, 0x7e0e, 0x782b, 0x0001, 0x7000,
-	0x8000, 0x7002, 0xa83c, 0x9300, 0xa83e, 0xa840, 0x9201, 0xa842,
-	0x700c, 0x9300, 0x700e, 0x7010, 0x9201, 0x7012, 0x080c, 0x2086,
-	0x0428, 0x2031, 0x0080, 0x9584, 0x007f, 0x0108, 0x9632, 0x7124,
-	0x7000, 0x9086, 0x0000, 0x1198, 0xc185, 0x7126, 0x2009, 0x0306,
-	0x2104, 0xd0b4, 0x1904, 0x1e4c, 0x200b, 0x4040, 0x2009, 0x1a7f,
-	0x2104, 0x8000, 0x0a04, 0x1e4c, 0x200a, 0x0804, 0x1e4c, 0xc18d,
-	0x7126, 0xd184, 0x1d58, 0x0804, 0x1e4c, 0x9006, 0x002e, 0x003e,
-	0x004e, 0x005e, 0x006e, 0x007e, 0x0005, 0x080c, 0x0dd5, 0x0026,
-	0x2001, 0x0105, 0x2003, 0x0010, 0x782b, 0x0004, 0x7003, 0x0000,
-	0x7004, 0x0016, 0x080c, 0x1cfc, 0x001e, 0x2060, 0x6014, 0x2048,
-	0x080c, 0xcc86, 0x0118, 0xa880, 0xc0bd, 0xa882, 0x6020, 0x9086,
-	0x0006, 0x1180, 0x2061, 0x0100, 0x62c8, 0x2001, 0x00fa, 0x8001,
-	0x1df0, 0x60c8, 0x9206, 0x1dc0, 0x60c4, 0xa89a, 0x60c8, 0xa896,
-	0x7004, 0x2060, 0x00c6, 0x080c, 0xc8a5, 0x00ce, 0x2001, 0x19f5,
-	0x2004, 0x9c06, 0x1160, 0x2009, 0x0040, 0x080c, 0x2410, 0x080c,
-	0xa89b, 0x2011, 0x0000, 0x080c, 0xa72c, 0x080c, 0x9891, 0x002e,
-	0x0804, 0x2036, 0x0126, 0x2091, 0x2400, 0xa858, 0x2040, 0x792c,
-	0x782b, 0x0002, 0x9184, 0x0700, 0x1904, 0x1eaf, 0x7000, 0x0002,
-	0x2036, 0x1f04, 0x1f84, 0x2034, 0x8001, 0x7002, 0x7027, 0x0000,
-	0xd19c, 0x1158, 0x8aff, 0x0904, 0x1f51, 0x080c, 0x1d03, 0x0904,
-	0x2036, 0x080c, 0x1d03, 0x0804, 0x2036, 0x782b, 0x0004, 0xd194,
-	0x0148, 0xa880, 0xc0fc, 0xa882, 0x8aff, 0x1518, 0xa87c, 0xc0f5,
-	0xa87e, 0x00f8, 0x0026, 0x0036, 0xab3c, 0xaa40, 0x0016, 0x7910,
-	0xa82c, 0x9100, 0xa82e, 0x7914, 0xa830, 0x9101, 0xa832, 0x001e,
-	0x7810, 0x931a, 0x7814, 0x9213, 0x7800, 0xa81e, 0x7804, 0xa822,
-	0xab3e, 0xaa42, 0x003e, 0x002e, 0x080c, 0x20a1, 0xa880, 0xc0fd,
-	0xa882, 0x2a00, 0xa816, 0x2800, 0xa85a, 0x2c00, 0xa812, 0x7003,
-	0x0000, 0x2009, 0x0306, 0x200b, 0x4800, 0x7027, 0x0000, 0x0804,
-	0x2036, 0x00f6, 0x0026, 0x781c, 0x0006, 0x7818, 0x0006, 0x2079,
-	0x0100, 0x7a14, 0x9284, 0x1984, 0x9085, 0x0012, 0x7816, 0x0036,
-	0x2019, 0x1000, 0x8319, 0x090c, 0x0dd5, 0x7820, 0xd0bc, 0x1dd0,
-	0x003e, 0x79c8, 0x000e, 0x9102, 0x001e, 0x0006, 0x0016, 0x79c4,
-	0x000e, 0x9103, 0x78c6, 0x000e, 0x78ca, 0x9284, 0x1984, 0x9085,
-	0x0012, 0x7816, 0x002e, 0x00fe, 0x782b, 0x0008, 0x7003, 0x0000,
-	0x080c, 0x1cfc, 0x0804, 0x2036, 0x8001, 0x7002, 0x7024, 0x8004,
-	0x7026, 0xd194, 0x0170, 0x782c, 0xd0fc, 0x1904, 0x1ef7, 0xd19c,
-	0x1904, 0x2032, 0x8aff, 0x0904, 0x2036, 0x080c, 0x1d03, 0x0804,
-	0x2036, 0x0026, 0x0036, 0xab3c, 0xaa40, 0x080c, 0x20a1, 0xdd9c,
-	0x1904, 0x1ff1, 0x2c05, 0x908a, 0x0036, 0x1a0c, 0x0dd5, 0x9082,
-	0x001b, 0x0002, 0x1fc5, 0x1fc5, 0x1fc7, 0x1fc5, 0x1fc5, 0x1fc5,
-	0x1fcd, 0x1fc5, 0x1fc5, 0x1fc5, 0x1fd3, 0x1fc5, 0x1fc5, 0x1fc5,
-	0x1fd9, 0x1fc5, 0x1fc5, 0x1fc5, 0x1fdf, 0x1fc5, 0x1fc5, 0x1fc5,
-	0x1fe5, 0x1fc5, 0x1fc5, 0x1fc5, 0x1feb, 0x080c, 0x0dd5, 0xa07c,
-	0x931a, 0xa080, 0x9213, 0x0804, 0x1f26, 0xa08c, 0x931a, 0xa090,
-	0x9213, 0x0804, 0x1f26, 0xa09c, 0x931a, 0xa0a0, 0x9213, 0x0804,
-	0x1f26, 0xa0ac, 0x931a, 0xa0b0, 0x9213, 0x0804, 0x1f26, 0xa0bc,
-	0x931a, 0xa0c0, 0x9213, 0x0804, 0x1f26, 0xa0cc, 0x931a, 0xa0d0,
-	0x9213, 0x0804, 0x1f26, 0xa0dc, 0x931a, 0xa0e0, 0x9213, 0x0804,
-	0x1f26, 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0dd5, 0x9082, 0x001b,
-	0x0002, 0x2014, 0x2012, 0x2012, 0x2012, 0x2012, 0x2012, 0x201a,
-	0x2012, 0x2012, 0x2012, 0x2012, 0x2012, 0x2020, 0x2012, 0x2012,
-	0x2012, 0x2012, 0x2012, 0x2026, 0x2012, 0x2012, 0x2012, 0x2012,
-	0x2012, 0x202c, 0x080c, 0x0dd5, 0xa07c, 0x931a, 0xa080, 0x9213,
-	0x0804, 0x1f26, 0xa094, 0x931a, 0xa098, 0x9213, 0x0804, 0x1f26,
-	0xa0ac, 0x931a, 0xa0b0, 0x9213, 0x0804, 0x1f26, 0xa0c4, 0x931a,
-	0xa0c8, 0x9213, 0x0804, 0x1f26, 0xa0dc, 0x931a, 0xa0e0, 0x9213,
-	0x0804, 0x1f26, 0x0804, 0x1f22, 0x080c, 0x0dd5, 0x012e, 0x0005,
-	0x00f6, 0x00e6, 0x2071, 0x1a65, 0x7000, 0x9086, 0x0000, 0x0904,
-	0x2081, 0x2079, 0x0090, 0x2009, 0x0207, 0x210c, 0xd194, 0x01b8,
-	0x2009, 0x020c, 0x210c, 0x9184, 0x0003, 0x0188, 0x080c, 0xeb9a,
-	0x2001, 0x0133, 0x2004, 0x9005, 0x090c, 0x0dd5, 0x0016, 0x2009,
-	0x0040, 0x080c, 0x2410, 0x001e, 0x2001, 0x020c, 0x2102, 0x2009,
-	0x0206, 0x2104, 0x2009, 0x0203, 0x210c, 0x9106, 0x1120, 0x2009,
-	0x0040, 0x080c, 0x2410, 0x782c, 0xd0fc, 0x09a8, 0x080c, 0x1ef2,
-	0x7000, 0x9086, 0x0000, 0x1978, 0x782b, 0x0004, 0x782c, 0xd0ac,
-	0x1de8, 0x2009, 0x0040, 0x080c, 0x2410, 0x782b, 0x0002, 0x7003,
-	0x0000, 0x080c, 0x1cfc, 0x00ee, 0x00fe, 0x0005, 0xa880, 0xd0fc,
-	0x11a8, 0x8c60, 0x2c05, 0x9005, 0x0110, 0x8a51, 0x0005, 0xa004,
-	0x9005, 0x0168, 0xa85a, 0x2040, 0xa064, 0x9084, 0x000f, 0x9080,
-	0x20ce, 0x2065, 0x8cff, 0x090c, 0x0dd5, 0x8a51, 0x0005, 0x2050,
-	0x0005, 0xa880, 0xd0fc, 0x11b8, 0x8a50, 0x8c61, 0x2c05, 0x9005,
-	0x1190, 0x2800, 0x9906, 0x0120, 0xa000, 0x9005, 0x1108, 0x2900,
-	0x2040, 0xa85a, 0xa064, 0x9084, 0x000f, 0x9080, 0x20de, 0x2065,
-	0x8cff, 0x090c, 0x0dd5, 0x0005, 0x0000, 0x001d, 0x0021, 0x0025,
-	0x0029, 0x002d, 0x0031, 0x0035, 0x0000, 0x001b, 0x0021, 0x0027,
-	0x002d, 0x0033, 0x0000, 0x0000, 0x0023, 0x0000, 0x0000, 0x20c1,
-	0x20bd, 0x20c1, 0x20c1, 0x20cb, 0x0000, 0x20c1, 0x20c8, 0x20c8,
-	0x20c5, 0x20c8, 0x20c8, 0x0000, 0x20cb, 0x20c8, 0x0000, 0x20c3,
-	0x20c3, 0x0000, 0x20c3, 0x20cb, 0x0000, 0x20c3, 0x20c9, 0x20c9,
-	0x20c9, 0x0000, 0x20c9, 0x0000, 0x20cb, 0x20c9, 0x00c6, 0x00d6,
-	0x0086, 0xab42, 0xac3e, 0xa888, 0x9055, 0x0904, 0x22cd, 0x2940,
-	0xa064, 0x90ec, 0x000f, 0x9084, 0x00ff, 0x9086, 0x0008, 0x1118,
-	0x2061, 0x20c9, 0x00d0, 0x9de0, 0x20ce, 0x9d86, 0x0007, 0x0130,
-	0x9d86, 0x000e, 0x0118, 0x9d86, 0x000f, 0x1120, 0xa08c, 0x9422,
-	0xa090, 0x931b, 0x2c05, 0x9065, 0x1140, 0x0310, 0x0804, 0x22cd,
-	0xa004, 0x9045, 0x0904, 0x22cd, 0x08d8, 0x2c05, 0x9005, 0x0904,
-	0x21b5, 0xdd9c, 0x1904, 0x2171, 0x908a, 0x0036, 0x1a0c, 0x0dd5,
-	0x9082, 0x001b, 0x0002, 0x2146, 0x2146, 0x2148, 0x2146, 0x2146,
-	0x2146, 0x214e, 0x2146, 0x2146, 0x2146, 0x2154, 0x2146, 0x2146,
-	0x2146, 0x215a, 0x2146, 0x2146, 0x2146, 0x2160, 0x2146, 0x2146,
-	0x2146, 0x2166, 0x2146, 0x2146, 0x2146, 0x216c, 0x080c, 0x0dd5,
-	0xa07c, 0x9422, 0xa080, 0x931b, 0x0804, 0x21ab, 0xa08c, 0x9422,
-	0xa090, 0x931b, 0x0804, 0x21ab, 0xa09c, 0x9422, 0xa0a0, 0x931b,
-	0x0804, 0x21ab, 0xa0ac, 0x9422, 0xa0b0, 0x931b, 0x0804, 0x21ab,
-	0xa0bc, 0x9422, 0xa0c0, 0x931b, 0x0804, 0x21ab, 0xa0cc, 0x9422,
-	0xa0d0, 0x931b, 0x0804, 0x21ab, 0xa0dc, 0x9422, 0xa0e0, 0x931b,
-	0x04d0, 0x908a, 0x0034, 0x1a0c, 0x0dd5, 0x9082, 0x001b, 0x0002,
-	0x2193, 0x2191, 0x2191, 0x2191, 0x2191, 0x2191, 0x2198, 0x2191,
-	0x2191, 0x2191, 0x2191, 0x2191, 0x219d, 0x2191, 0x2191, 0x2191,
-	0x2191, 0x2191, 0x21a2, 0x2191, 0x2191, 0x2191, 0x2191, 0x2191,
-	0x21a7, 0x080c, 0x0dd5, 0xa07c, 0x9422, 0xa080, 0x931b, 0x0098,
-	0xa094, 0x9422, 0xa098, 0x931b, 0x0070, 0xa0ac, 0x9422, 0xa0b0,
-	0x931b, 0x0048, 0xa0c4, 0x9422, 0xa0c8, 0x931b, 0x0020, 0xa0dc,
-	0x9422, 0xa0e0, 0x931b, 0x0630, 0x2300, 0x9405, 0x0160, 0x8a51,
-	0x0904, 0x22cd, 0x8c60, 0x0804, 0x211d, 0xa004, 0x9045, 0x0904,
-	0x22cd, 0x0804, 0x20f8, 0x8a51, 0x0904, 0x22cd, 0x8c60, 0x2c05,
-	0x9005, 0x1158, 0xa004, 0x9045, 0x0904, 0x22cd, 0xa064, 0x90ec,
-	0x000f, 0x9de0, 0x20ce, 0x2c05, 0x2060, 0xa880, 0xc0fc, 0xa882,
-	0x0804, 0x22c2, 0x2c05, 0x8422, 0x8420, 0x831a, 0x9399, 0x0000,
-	0xac2e, 0xab32, 0xdd9c, 0x1904, 0x225f, 0x9082, 0x001b, 0x0002,
-	0x21fb, 0x21fb, 0x21fd, 0x21fb, 0x21fb, 0x21fb, 0x220b, 0x21fb,
-	0x21fb, 0x21fb, 0x2219, 0x21fb, 0x21fb, 0x21fb, 0x2227, 0x21fb,
-	0x21fb, 0x21fb, 0x2235, 0x21fb, 0x21fb, 0x21fb, 0x2243, 0x21fb,
-	0x21fb, 0x21fb, 0x2251, 0x080c, 0x0dd5, 0xa17c, 0x2400, 0x9122,
-	0xa180, 0x2300, 0x911b, 0x0a0c, 0x0dd5, 0xa074, 0x9420, 0xa078,
-	0x9319, 0x0804, 0x22bd, 0xa18c, 0x2400, 0x9122, 0xa190, 0x2300,
-	0x911b, 0x0a0c, 0x0dd5, 0xa084, 0x9420, 0xa088, 0x9319, 0x0804,
-	0x22bd, 0xa19c, 0x2400, 0x9122, 0xa1a0, 0x2300, 0x911b, 0x0a0c,
-	0x0dd5, 0xa094, 0x9420, 0xa098, 0x9319, 0x0804, 0x22bd, 0xa1ac,
-	0x2400, 0x9122, 0xa1b0, 0x2300, 0x911b, 0x0a0c, 0x0dd5, 0xa0a4,
-	0x9420, 0xa0a8, 0x9319, 0x0804, 0x22bd, 0xa1bc, 0x2400, 0x9122,
-	0xa1c0, 0x2300, 0x911b, 0x0a0c, 0x0dd5, 0xa0b4, 0x9420, 0xa0b8,
-	0x9319, 0x0804, 0x22bd, 0xa1cc, 0x2400, 0x9122, 0xa1d0, 0x2300,
-	0x911b, 0x0a0c, 0x0dd5, 0xa0c4, 0x9420, 0xa0c8, 0x9319, 0x0804,
-	0x22bd, 0xa1dc, 0x2400, 0x9122, 0xa1e0, 0x2300, 0x911b, 0x0a0c,
-	0x0dd5, 0xa0d4, 0x9420, 0xa0d8, 0x9319, 0x0804, 0x22bd, 0x9082,
-	0x001b, 0x0002, 0x227d, 0x227b, 0x227b, 0x227b, 0x227b, 0x227b,
-	0x228a, 0x227b, 0x227b, 0x227b, 0x227b, 0x227b, 0x2297, 0x227b,
-	0x227b, 0x227b, 0x227b, 0x227b, 0x22a4, 0x227b, 0x227b, 0x227b,
-	0x227b, 0x227b, 0x22b1, 0x080c, 0x0dd5, 0xa17c, 0x2400, 0x9122,
-	0xa180, 0x2300, 0x911b, 0x0a0c, 0x0dd5, 0xa06c, 0x9420, 0xa070,
-	0x9319, 0x0498, 0xa194, 0x2400, 0x9122, 0xa198, 0x2300, 0x911b,
-	0x0a0c, 0x0dd5, 0xa084, 0x9420, 0xa088, 0x9319, 0x0430, 0xa1ac,
-	0x2400, 0x9122, 0xa1b0, 0x2300, 0x911b, 0x0a0c, 0x0dd5, 0xa09c,
-	0x9420, 0xa0a0, 0x9319, 0x00c8, 0xa1c4, 0x2400, 0x9122, 0xa1c8,
-	0x2300, 0x911b, 0x0a0c, 0x0dd5, 0xa0b4, 0x9420, 0xa0b8, 0x9319,
-	0x0060, 0xa1dc, 0x2400, 0x9122, 0xa1e0, 0x2300, 0x911b, 0x0a0c,
-	0x0dd5, 0xa0cc, 0x9420, 0xa0d0, 0x9319, 0xac1e, 0xab22, 0xa880,
-	0xc0fd, 0xa882, 0x2800, 0xa85a, 0x2c00, 0xa812, 0x2a00, 0xa816,
-	0x000e, 0x000e, 0x000e, 0x9006, 0x0028, 0x008e, 0x00de, 0x00ce,
-	0x9085, 0x0001, 0x0005, 0x2001, 0x0005, 0x2004, 0xd0bc, 0x190c,
-	0x0dce, 0x9084, 0x0007, 0x0002, 0x22ee, 0x1ef2, 0x22ee, 0x22e4,
-	0x22e7, 0x22ea, 0x22e7, 0x22ea, 0x080c, 0x1ef2, 0x0005, 0x080c,
-	0x11a3, 0x0005, 0x080c, 0x1ef2, 0x080c, 0x11a3, 0x0005, 0x0126,
-	0x2091, 0x2600, 0x2079, 0x0200, 0x2071, 0x0260, 0x2069, 0x1800,
-	0x7817, 0x0000, 0x789b, 0x0814, 0x78a3, 0x0406, 0x789f, 0x0410,
-	0x2009, 0x013b, 0x200b, 0x0400, 0x781b, 0x0002, 0x783b, 0x001f,
-	0x7837, 0x0020, 0x7803, 0x1600, 0x012e, 0x0005, 0x2091, 0x2600,
-	0x781c, 0xd0a4, 0x190c, 0x240d, 0x7900, 0xd1dc, 0x1118, 0x9084,
-	0x0006, 0x001a, 0x9084, 0x000e, 0x0002, 0x2335, 0x232d, 0x7e1e,
-	0x232d, 0x232f, 0x232f, 0x232f, 0x232f, 0x7e04, 0x232d, 0x2331,
-	0x232d, 0x232f, 0x232d, 0x232f, 0x232d, 0x080c, 0x0dd5, 0x0031,
-	0x0020, 0x080c, 0x7e04, 0x080c, 0x7e1e, 0x0005, 0x0006, 0x0016,
-	0x0026, 0x080c, 0xeb9a, 0x7930, 0x9184, 0x0003, 0x01c0, 0x2001,
-	0x19f5, 0x2004, 0x9005, 0x0170, 0x2001, 0x0133, 0x2004, 0x9005,
-	0x090c, 0x0dd5, 0x00c6, 0x2001, 0x19f5, 0x2064, 0x080c, 0xc8a5,
-	0x00ce, 0x00f8, 0x2009, 0x0040, 0x080c, 0x2410, 0x00d0, 0x9184,
-	0x0014, 0x01a0, 0x6a00, 0x9286, 0x0003, 0x0160, 0x080c, 0x743e,
-	0x1138, 0x080c, 0x7724, 0x080c, 0x60ad, 0x080c, 0x736a, 0x0010,
-	0x080c, 0x5f6c, 0x080c, 0x7ecd, 0x0041, 0x0018, 0x9184, 0x9540,
-	0x1dc8, 0x002e, 0x001e, 0x000e, 0x0005, 0x00e6, 0x0036, 0x0046,
-	0x0056, 0x2071, 0x1a61, 0x080c, 0x1aec, 0x005e, 0x004e, 0x003e,
-	0x00ee, 0x0005, 0x0126, 0x2091, 0x2e00, 0x2071, 0x1800, 0x7128,
-	0x2001, 0x196e, 0x2102, 0x2001, 0x1976, 0x2102, 0x2001, 0x013b,
-	0x2102, 0x2079, 0x0200, 0x2001, 0x0201, 0x789e, 0x78a3, 0x0200,
-	0x9198, 0x0007, 0x831c, 0x831c, 0x831c, 0x9398, 0x0005, 0x2320,
-	0x9182, 0x0204, 0x1230, 0x2011, 0x0008, 0x8423, 0x8423, 0x8423,
-	0x0488, 0x9182, 0x024c, 0x1240, 0x2011, 0x0007, 0x8403, 0x8003,
-	0x9400, 0x9400, 0x9420, 0x0430, 0x9182, 0x02bc, 0x1238, 0x2011,
-	0x0006, 0x8403, 0x8003, 0x9400, 0x9420, 0x00e0, 0x9182, 0x034c,
-	0x1230, 0x2011, 0x0005, 0x8403, 0x8003, 0x9420, 0x0098, 0x9182,
-	0x042c, 0x1228, 0x2011, 0x0004, 0x8423, 0x8423, 0x0058, 0x9182,
-	0x059c, 0x1228, 0x2011, 0x0003, 0x8403, 0x9420, 0x0018, 0x2011,
-	0x0002, 0x8423, 0x9482, 0x0228, 0x8002, 0x8020, 0x8301, 0x9402,
-	0x0110, 0x0208, 0x8321, 0x8217, 0x8203, 0x9405, 0x789a, 0x012e,
-	0x0005, 0x0006, 0x00d6, 0x2069, 0x0200, 0x6814, 0x9084, 0xffc0,
-	0x910d, 0x6916, 0x00de, 0x000e, 0x0005, 0x00d6, 0x2069, 0x0200,
-	0x9005, 0x6810, 0x0110, 0xc0a5, 0x0008, 0xc0a4, 0x6812, 0x00de,
-	0x0005, 0x0006, 0x00d6, 0x2069, 0x0200, 0x6810, 0x9084, 0xfff8,
-	0x910d, 0x6912, 0x00de, 0x000e, 0x0005, 0x7938, 0x080c, 0x0dce,
-	0x00f6, 0x2079, 0x0200, 0x7902, 0xa001, 0xa001, 0xa001, 0xa001,
-	0xa001, 0xa001, 0x7902, 0xa001, 0xa001, 0xa001, 0xa001, 0xa001,
-	0xa001, 0x00fe, 0x0005, 0x0126, 0x2091, 0x2800, 0x2061, 0x0100,
-	0x2071, 0x1800, 0x2009, 0x0000, 0x080c, 0x2c7c, 0x080c, 0x2b97,
-	0x6054, 0x8004, 0x8004, 0x8004, 0x8004, 0x9084, 0x000c, 0x6150,
-	0x918c, 0xfff3, 0x9105, 0x6052, 0x6050, 0x9084, 0xb17f, 0x9085,
-	0x2000, 0x6052, 0x2009, 0x199c, 0x2011, 0x199d, 0x6358, 0x939c,
-	0x38f0, 0x2320, 0x080c, 0x2bdb, 0x1238, 0x939d, 0x4003, 0x94a5,
-	0x8603, 0x230a, 0x2412, 0x0030, 0x939d, 0x0203, 0x94a5, 0x8603,
-	0x230a, 0x2412, 0x9006, 0x080c, 0x2bc6, 0x9006, 0x080c, 0x2ba9,
-	0x20a9, 0x0012, 0x1d04, 0x2462, 0x2091, 0x6000, 0x1f04, 0x2462,
-	0x602f, 0x0100, 0x602f, 0x0000, 0x6050, 0x9085, 0x0400, 0x9084,
-	0xdfff, 0x6052, 0x6024, 0x6026, 0x080c, 0x28b5, 0x2009, 0x00ef,
-	0x6132, 0x6136, 0x080c, 0x28c5, 0x60e7, 0x0000, 0x61ea, 0x60e3,
-	0x0008, 0x604b, 0xf7f7, 0x6043, 0x0000, 0x602f, 0x0080, 0x602f,
-	0x0000, 0x6007, 0x349f, 0x60bb, 0x0000, 0x20a9, 0x0018, 0x60bf,
-	0x0000, 0x1f04, 0x248f, 0x60bb, 0x0000, 0x60bf, 0x0108, 0x60bf,
-	0x0012, 0x60bf, 0x0405, 0x60bf, 0x0014, 0x60bf, 0x0320, 0x60bf,
-	0x0018, 0x601b, 0x00f0, 0x601f, 0x001e, 0x600f, 0x006b, 0x602b,
-	0x402f, 0x012e, 0x0005, 0x00f6, 0x2079, 0x0140, 0x78c3, 0x0080,
-	0x78c3, 0x0083, 0x78c3, 0x0000, 0x00fe, 0x0005, 0x2001, 0x1835,
-	0x2003, 0x0000, 0x2001, 0x1834, 0x2003, 0x0001, 0x0005, 0x0126,
-	0x2091, 0x2800, 0x0006, 0x0016, 0x0026, 0x6124, 0x0066, 0x2031,
-	0x1837, 0x2634, 0x96b4, 0x0028, 0x006e, 0x1138, 0x6020, 0xd1bc,
-	0x0120, 0xd0bc, 0x1168, 0xd0b4, 0x1198, 0x9184, 0x5e2c, 0x1118,
-	0x9184, 0x0007, 0x00aa, 0x9195, 0x0004, 0x9284, 0x0007, 0x0082,
-	0x0016, 0x2001, 0x188b, 0x200c, 0xd184, 0x001e, 0x0d70, 0x0c98,
-	0x0016, 0x2001, 0x188b, 0x200c, 0xd194, 0x001e, 0x0d30, 0x0c58,
-	0x2512, 0x24f8, 0x24fb, 0x24fe, 0x2503, 0x2505, 0x2509, 0x250d,
-	0x080c, 0x9094, 0x00b8, 0x080c, 0x9163, 0x00a0, 0x080c, 0x9163,
-	0x080c, 0x9094, 0x0078, 0x0099, 0x0068, 0x080c, 0x9094, 0x0079,
-	0x0048, 0x080c, 0x9163, 0x0059, 0x0028, 0x080c, 0x9163, 0x080c,
-	0x9094, 0x0029, 0x002e, 0x001e, 0x000e, 0x012e, 0x0005, 0x00a6,
-	0x6124, 0x6028, 0xd09c, 0x0118, 0xd19c, 0x1904, 0x277a, 0xd1f4,
-	0x190c, 0x0dce, 0x080c, 0x743e, 0x0904, 0x256d, 0x080c, 0xd388,
-	0x1120, 0x7000, 0x9086, 0x0003, 0x0570, 0x6024, 0x9084, 0x1800,
-	0x0550, 0x080c, 0x7461, 0x0118, 0x080c, 0x744f, 0x1520, 0x6027,
-	0x0020, 0x6043, 0x0000, 0x080c, 0xd388, 0x0168, 0x080c, 0x7461,
-	0x1150, 0x2001, 0x19a6, 0x2003, 0x0001, 0x6027, 0x1800, 0x080c,
-	0x72ce, 0x0804, 0x277d, 0x70a4, 0x9005, 0x1150, 0x70a7, 0x0001,
-	0x00d6, 0x2069, 0x0140, 0x080c, 0x7495, 0x00de, 0x1904, 0x277d,
-	0x080c, 0x772e, 0x0428, 0x080c, 0x7461, 0x1590, 0x6024, 0x9084,
-	0x1800, 0x1108, 0x0468, 0x080c, 0x772e, 0x080c, 0x7724, 0x080c,
-	0x60ad, 0x080c, 0x736a, 0x0804, 0x277a, 0xd1ac, 0x1508, 0x6024,
-	0xd0dc, 0x1170, 0xd0e4, 0x1178, 0xd0d4, 0x1190, 0xd0cc, 0x0130,
-	0x7098, 0x9086, 0x0028, 0x1110, 0x080c, 0x7611, 0x0804, 0x277a,
-	0x080c, 0x7729, 0x0048, 0x2001, 0x197c, 0x2003, 0x0002, 0x0020,
-	0x080c, 0x7576, 0x0804, 0x277a, 0x080c, 0x76ac, 0x0804, 0x277a,
-	0x6220, 0xd1bc, 0x0138, 0xd2bc, 0x1904, 0x27ed, 0xd2b4, 0x1904,
-	0x2800, 0x0000, 0xd1ac, 0x0904, 0x268f, 0x0036, 0x6328, 0xc3bc,
-	0x632a, 0x003e, 0x080c, 0x743e, 0x11c0, 0x6027, 0x0020, 0x0006,
-	0x0026, 0x0036, 0x080c, 0x7458, 0x1158, 0x080c, 0x7724, 0x080c,
-	0x60ad, 0x080c, 0x736a, 0x003e, 0x002e, 0x000e, 0x00ae, 0x0005,
-	0x003e, 0x002e, 0x000e, 0x080c, 0x7416, 0x0016, 0x0046, 0x00c6,
-	0x644c, 0x9486, 0xf0f0, 0x1138, 0x2061, 0x0100, 0x644a, 0x6043,
-	0x0090, 0x6043, 0x0010, 0x74da, 0x948c, 0xff00, 0x7038, 0xd084,
-	0x0178, 0x9186, 0xf800, 0x1160, 0x7048, 0xd084, 0x1148, 0xc085,
-	0x704a, 0x0036, 0x2418, 0x2011, 0x8016, 0x080c, 0x4b7f, 0x003e,
-	0x080c, 0xd381, 0x1904, 0x266c, 0x9196, 0xff00, 0x05a8, 0x7060,
-	0x9084, 0x00ff, 0x810f, 0x81ff, 0x0110, 0x9116, 0x0568, 0x7130,
-	0xd184, 0x1550, 0x080c, 0x3378, 0x0128, 0xc18d, 0x7132, 0x080c,
-	0x6a04, 0x1510, 0x6240, 0x9294, 0x0010, 0x0130, 0x6248, 0x9294,
-	0xff00, 0x9296, 0xff00, 0x01c0, 0x7030, 0xd08c, 0x0904, 0x266c,
-	0x7038, 0xd08c, 0x1140, 0x2001, 0x180c, 0x200c, 0xd1ac, 0x1904,
-	0x266c, 0xc1ad, 0x2102, 0x0036, 0x73d8, 0x2011, 0x8013, 0x080c,
-	0x4b7f, 0x003e, 0x0804, 0x266c, 0x7038, 0xd08c, 0x1140, 0x2001,
-	0x180c, 0x200c, 0xd1ac, 0x1904, 0x266c, 0xc1ad, 0x2102, 0x0036,
-	0x73d8, 0x2011, 0x8013, 0x080c, 0x4b7f, 0x003e, 0x7130, 0xc185,
-	0x7132, 0x2011, 0x1848, 0x220c, 0xd1a4, 0x01f0, 0x0016, 0x2009,
-	0x0001, 0x2011, 0x0100, 0x080c, 0x879a, 0x2019, 0x000e, 0x00c6,
-	0x2061, 0x0000, 0x080c, 0xe6ae, 0x00ce, 0x9484, 0x00ff, 0x9080,
-	0x3384, 0x200d, 0x918c, 0xff00, 0x810f, 0x2120, 0x9006, 0x2009,
-	0x000e, 0x080c, 0xe73a, 0x001e, 0x0016, 0x2009, 0x0002, 0x2019,
-	0x0004, 0x080c, 0x31e9, 0x001e, 0x0078, 0x0156, 0x00b6, 0x20a9,
-	0x007f, 0x900e, 0x080c, 0x6699, 0x1110, 0x080c, 0x60c7, 0x8108,
-	0x1f04, 0x2662, 0x00be, 0x015e, 0x00ce, 0x004e, 0x080c, 0xaeb4,
+	0x00e6, 0x0126, 0x2091, 0x8000, 0x0016, 0x890e, 0x810e, 0x810f,
+	0x9184, 0x003f, 0xa862, 0x9184, 0xffc0, 0xa85e, 0x001e, 0x0020,
+	0x00e6, 0x0126, 0x2091, 0x8000, 0x2071, 0x1800, 0x702c, 0xa802,
+	0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c, 0x85eb, 0x012e,
+	0x00ee, 0x0005, 0x2071, 0x1800, 0x9026, 0x2009, 0x0000, 0x2049,
+	0x0400, 0x2900, 0x702e, 0x8940, 0x2800, 0xa802, 0xa95e, 0xa863,
+	0x0001, 0x8420, 0x9886, 0x0440, 0x0120, 0x2848, 0x9188, 0x0040,
+	0x0c90, 0x2071, 0x188d, 0x7000, 0x9005, 0x11a0, 0x2001, 0x0534,
+	0xa802, 0x2048, 0x2009, 0x4d00, 0x8940, 0x2800, 0xa802, 0xa95e,
+	0xa863, 0x0001, 0x8420, 0x9886, 0x0800, 0x0120, 0x2848, 0x9188,
+	0x0040, 0x0c90, 0x2071, 0x188d, 0x7104, 0x7200, 0x82ff, 0x01d0,
+	0x7308, 0x8318, 0x831f, 0x831b, 0x831b, 0x7312, 0x8319, 0x2001,
+	0x0800, 0xa802, 0x2048, 0x8900, 0xa802, 0x2040, 0xa95e, 0xaa62,
+	0x8420, 0x2300, 0x9906, 0x0130, 0x2848, 0x9188, 0x0040, 0x9291,
+	0x0000, 0x0c88, 0xa803, 0x0000, 0x2071, 0x1800, 0x74be, 0x74c2,
+	0x0005, 0x00e6, 0x0016, 0x9984, 0xfc00, 0x01e8, 0x908c, 0xf800,
+	0x1168, 0x9982, 0x0400, 0x02b8, 0x9982, 0x0440, 0x0278, 0x9982,
+	0x0534, 0x0288, 0x9982, 0x0800, 0x1270, 0x0040, 0x9982, 0x0800,
+	0x0250, 0x2071, 0x188d, 0x7010, 0x9902, 0x1228, 0x9085, 0x0001,
+	0x001e, 0x00ee, 0x0005, 0x9006, 0x0cd8, 0x00e6, 0x2071, 0x1a1c,
+	0x7007, 0x0000, 0x9006, 0x701e, 0x7022, 0x7002, 0x2071, 0x0000,
+	0x7010, 0x9085, 0x8044, 0x7012, 0x2071, 0x0080, 0x9006, 0x20a9,
+	0x0040, 0x7022, 0x1f04, 0x10f1, 0x702b, 0x0020, 0x00ee, 0x0005,
+	0x0126, 0x2091, 0x8000, 0x00e6, 0xa06f, 0x0000, 0x2071, 0x1a1c,
+	0x701c, 0x9088, 0x1a26, 0x280a, 0x8000, 0x9084, 0x003f, 0x701e,
+	0x7120, 0x9106, 0x090c, 0x0dc5, 0x7004, 0x9005, 0x1128, 0x00f6,
+	0x2079, 0x0080, 0x00a9, 0x00fe, 0x00ee, 0x012e, 0x0005, 0x0126,
+	0x2091, 0x8000, 0x00e6, 0x2071, 0x1a1c, 0x7004, 0x9005, 0x1128,
+	0x00f6, 0x2079, 0x0080, 0x0021, 0x00fe, 0x00ee, 0x012e, 0x0005,
+	0x7004, 0x9086, 0x0000, 0x1110, 0x7007, 0x0006, 0x7000, 0x0002,
+	0x113a, 0x12bd, 0x1138, 0x1138, 0x12b1, 0x12b1, 0x12b1, 0x12b1,
+	0x080c, 0x0dc5, 0x701c, 0x7120, 0x9106, 0x1148, 0x792c, 0x9184,
+	0x0001, 0x1120, 0xd1fc, 0x1110, 0x7007, 0x0000, 0x0005, 0x0096,
+	0x9180, 0x1a26, 0x2004, 0x700a, 0x2048, 0x8108, 0x918c, 0x003f,
+	0x7122, 0x782b, 0x0026, 0xa88c, 0x7802, 0xa890, 0x7806, 0xa894,
+	0x780a, 0xa898, 0x780e, 0xa878, 0x700e, 0xa870, 0x7016, 0xa874,
+	0x701a, 0xa868, 0x009e, 0xd084, 0x0120, 0x7007, 0x0001, 0x0029,
+	0x0005, 0x7007, 0x0002, 0x00b1, 0x0005, 0x0016, 0x0026, 0x710c,
+	0x2011, 0x0040, 0x9182, 0x0040, 0x1210, 0x2110, 0x9006, 0x700e,
+	0x7212, 0x8203, 0x7812, 0x782b, 0x0020, 0x782b, 0x0041, 0x002e,
+	0x001e, 0x0005, 0x0016, 0x0026, 0x0136, 0x0146, 0x0156, 0x7014,
+	0x20e0, 0x7018, 0x2098, 0x20e9, 0x0000, 0x20a1, 0x0088, 0x782b,
+	0x0026, 0x710c, 0x2011, 0x0040, 0x9182, 0x0040, 0x1210, 0x2110,
+	0x9006, 0x700e, 0x22a8, 0x4006, 0x8203, 0x7812, 0x782b, 0x0020,
+	0x3300, 0x701a, 0x782b, 0x0001, 0x015e, 0x014e, 0x013e, 0x002e,
+	0x001e, 0x0005, 0x2009, 0x1a1c, 0x2104, 0xc095, 0x200a, 0x080c,
+	0x1117, 0x0005, 0x0016, 0x00e6, 0x2071, 0x1a1c, 0x00f6, 0x2079,
+	0x0080, 0x792c, 0xd1bc, 0x190c, 0x0dbe, 0x782b, 0x0002, 0xd1fc,
+	0x0120, 0x918c, 0x0700, 0x7004, 0x0023, 0x00fe, 0x00ee, 0x001e,
+	0x0005, 0x1128, 0x11d0, 0x1204, 0x12dc, 0x0dc5, 0x12f7, 0x0dc5,
+	0x918c, 0x0700, 0x1550, 0x0136, 0x0146, 0x0156, 0x7014, 0x20e8,
+	0x7018, 0x20a0, 0x20e1, 0x0000, 0x2099, 0x0088, 0x782b, 0x0040,
+	0x7010, 0x20a8, 0x4005, 0x3400, 0x701a, 0x015e, 0x014e, 0x013e,
+	0x700c, 0x9005, 0x0578, 0x7800, 0x7802, 0x7804, 0x7806, 0x080c,
+	0x116d, 0x0005, 0x7008, 0x0096, 0x2048, 0xa86f, 0x0100, 0x009e,
+	0x7007, 0x0000, 0x080c, 0x1128, 0x0005, 0x7008, 0x0096, 0x2048,
+	0xa86f, 0x0200, 0x009e, 0x0ca0, 0x918c, 0x0700, 0x1150, 0x700c,
+	0x9005, 0x0180, 0x7800, 0x7802, 0x7804, 0x7806, 0x080c, 0x1182,
+	0x0005, 0x7008, 0x0096, 0x2048, 0xa86f, 0x0200, 0x009e, 0x7007,
+	0x0000, 0x0080, 0x0096, 0x7008, 0x2048, 0x7800, 0xa88e, 0x7804,
+	0xa892, 0x7808, 0xa896, 0x780c, 0xa89a, 0xa86f, 0x0100, 0x009e,
+	0x7007, 0x0000, 0x0096, 0x00d6, 0x7008, 0x2048, 0x2001, 0x18b9,
+	0x2004, 0x9906, 0x1128, 0xa89c, 0x080f, 0x00de, 0x009e, 0x00a0,
+	0x00de, 0x009e, 0x0096, 0x00d6, 0x7008, 0x2048, 0x0081, 0x0150,
+	0xa89c, 0x0086, 0x2940, 0x080f, 0x008e, 0x00de, 0x009e, 0x080c,
+	0x1117, 0x0005, 0x00de, 0x009e, 0x080c, 0x1117, 0x0005, 0xa8a8,
+	0xd08c, 0x0005, 0x0096, 0xa0a0, 0x904d, 0x090c, 0x0dc5, 0xa06c,
+	0x908e, 0x0100, 0x0130, 0xa87b, 0x0030, 0xa883, 0x0000, 0xa897,
+	0x4002, 0x080c, 0x6dbe, 0xa09f, 0x0000, 0xa0a3, 0x0000, 0x2848,
+	0x080c, 0x1040, 0x009e, 0x0005, 0x00a6, 0xa0a0, 0x904d, 0x090c,
+	0x0dc5, 0xa06c, 0x908e, 0x0100, 0x0128, 0xa87b, 0x0001, 0xa883,
+	0x0000, 0x00c0, 0xa80c, 0x2050, 0xb004, 0x9005, 0x0198, 0xa80e,
+	0x2050, 0x8006, 0x8006, 0x8007, 0x908c, 0x003f, 0x9084, 0xffc0,
+	0x9080, 0x0002, 0xa076, 0xa172, 0xb000, 0xa07a, 0x2810, 0x080c,
+	0x10f8, 0x00e8, 0xa97c, 0xa894, 0x0016, 0x0006, 0x080c, 0x6dbe,
+	0x000e, 0x001e, 0xd1fc, 0x1138, 0xd1f4, 0x0128, 0x00c6, 0x2060,
+	0x080c, 0xb0e7, 0x00ce, 0x7008, 0x2048, 0xa89f, 0x0000, 0xa8a3,
+	0x0000, 0x080c, 0x1040, 0x7007, 0x0000, 0x080c, 0x1117, 0x00ae,
+	0x0005, 0x0126, 0x2091, 0x8000, 0x782b, 0x1001, 0x7007, 0x0005,
+	0x7000, 0xc094, 0x7002, 0x012e, 0x0005, 0x0096, 0x2001, 0x1930,
+	0x204c, 0xa87c, 0x7812, 0xa88c, 0x7802, 0xa890, 0x7806, 0xa894,
+	0x780a, 0xa898, 0x780e, 0x782b, 0x0020, 0x0126, 0x2091, 0x8000,
+	0x782b, 0x0041, 0x7007, 0x0003, 0x7000, 0xc084, 0x7002, 0x2900,
+	0x700a, 0x012e, 0x009e, 0x0005, 0x20e1, 0x0000, 0x2099, 0x0088,
+	0x782b, 0x0040, 0x0096, 0x2001, 0x1930, 0x204c, 0xaa7c, 0x009e,
+	0x080c, 0x8c54, 0x2009, 0x188c, 0x2104, 0x9084, 0xfffc, 0x200a,
+	0x080c, 0x8ab9, 0x7007, 0x0000, 0x080c, 0x1128, 0x0005, 0x7007,
+	0x0000, 0x080c, 0x1128, 0x0005, 0x0126, 0x2091, 0x2200, 0x2079,
+	0x0300, 0x2071, 0x1a66, 0x7003, 0x0000, 0x78bf, 0x00f6, 0x781b,
+	0x4800, 0x00c1, 0x7803, 0x0003, 0x780f, 0x0000, 0x20a9, 0x03e5,
+	0x2061, 0xedc4, 0x2c0d, 0x7912, 0xe104, 0x9ce0, 0x0002, 0x7916,
+	0x1f04, 0x1312, 0x7807, 0x0007, 0x7803, 0x0000, 0x7803, 0x0001,
+	0x012e, 0x0005, 0x00c6, 0x7803, 0x0000, 0x7808, 0xd09c, 0x0120,
+	0x7820, 0x080c, 0x1376, 0x0cc8, 0x2001, 0x1a67, 0x2003, 0x0000,
+	0x78ab, 0x0004, 0x78ac, 0xd0ac, 0x1de8, 0x78ab, 0x0002, 0x7807,
+	0x0007, 0x7827, 0x0030, 0x782b, 0x0400, 0x7827, 0x0031, 0x782b,
+	0x1a8a, 0x781f, 0xff00, 0x781b, 0xb700, 0x2001, 0x0200, 0x2004,
+	0xd0dc, 0x0110, 0x781f, 0x0303, 0x2061, 0x1a8a, 0x602f, 0x1cd0,
+	0x2001, 0x181a, 0x2004, 0x9082, 0x1cd0, 0x6032, 0x603b, 0x20e8,
+	0x2001, 0x33b1, 0xd0fc, 0x190c, 0x0dc5, 0x2001, 0x1810, 0x2004,
+	0xd0c4, 0x1128, 0x2001, 0x0003, 0x2004, 0xd0d4, 0x1118, 0x783f,
+	0x33b1, 0x0020, 0x9084, 0xc000, 0x783f, 0xb3b1, 0x604f, 0x193e,
+	0x2001, 0x1929, 0x2004, 0x6042, 0x00ce, 0x0005, 0x9086, 0x000d,
+	0x11d0, 0x7808, 0xd09c, 0x01b8, 0x7820, 0x0026, 0x2010, 0x080c,
+	0xce2d, 0x0180, 0x2260, 0x6000, 0x9086, 0x0004, 0x1158, 0x0016,
+	0x6120, 0x9186, 0x0009, 0x0108, 0x0020, 0x2009, 0x004c, 0x080c,
+	0xb166, 0x001e, 0x002e, 0x0005, 0x0126, 0x2091, 0x2200, 0x7908,
+	0x9184, 0x0070, 0x190c, 0x0dbe, 0xd19c, 0x0158, 0x7820, 0x908c,
+	0xf000, 0x15e8, 0x908a, 0x0024, 0x1a0c, 0x0dc5, 0x0023, 0x012e,
+	0x0005, 0x012e, 0x0005, 0x13cf, 0x13cf, 0x13e6, 0x13eb, 0x13ef,
+	0x13f4, 0x141c, 0x1420, 0x142e, 0x1432, 0x13cf, 0x14ff, 0x1503,
+	0x1575, 0x157c, 0x13cf, 0x157d, 0x157e, 0x1589, 0x1590, 0x13cf,
+	0x13cf, 0x13cf, 0x13cf, 0x13cf, 0x13cf, 0x13cf, 0x13f6, 0x13cf,
+	0x13cf, 0x13cf, 0x13cf, 0x13cf, 0x13cf, 0x13d3, 0x13d1, 0x080c,
+	0x0dc5, 0x080c, 0x0dbe, 0x080c, 0x159b, 0x2009, 0x1a7f, 0x2104,
+	0x8000, 0x200a, 0x080c, 0x8000, 0x080c, 0x1b02, 0x0005, 0x2009,
+	0x0048, 0x2060, 0x080c, 0xb166, 0x012e, 0x0005, 0x7004, 0xc085,
+	0xc0b5, 0x7006, 0x0005, 0x7004, 0xc085, 0x7006, 0x0005, 0x080c,
+	0x159b, 0x080c, 0x16fb, 0x0005, 0x080c, 0x0dc5, 0x080c, 0x159b,
+	0x2060, 0x6014, 0x0096, 0x2048, 0xa83b, 0xffff, 0x009e, 0x2009,
+	0x0048, 0x080c, 0xb166, 0x2001, 0x015d, 0x2003, 0x0000, 0x2009,
+	0x03e8, 0x8109, 0x0160, 0x2001, 0x0201, 0x2004, 0x9005, 0x0dc8,
+	0x2001, 0x0218, 0x2004, 0xd0ec, 0x1110, 0x080c, 0x15a0, 0x2001,
+	0x0307, 0x2003, 0x8000, 0x0005, 0x7004, 0xc095, 0x7006, 0x0005,
+	0x080c, 0x159b, 0x2060, 0x6014, 0x0096, 0x2048, 0xa83b, 0xffff,
+	0x009e, 0x2009, 0x0048, 0x080c, 0xb166, 0x0005, 0x080c, 0x159b,
+	0x080c, 0x0dc5, 0x080c, 0x159b, 0x080c, 0x14ea, 0x7827, 0x0018,
+	0x79ac, 0xd1dc, 0x0904, 0x149b, 0x7827, 0x0015, 0x7828, 0x782b,
+	0x0000, 0x9065, 0x0140, 0x2001, 0x020d, 0x2003, 0x0050, 0x2003,
+	0x0020, 0x0804, 0x14a1, 0x7004, 0x9005, 0x01c8, 0x1188, 0x78ab,
+	0x0004, 0x7827, 0x0018, 0x782b, 0x0000, 0xd1bc, 0x090c, 0x0dc5,
+	0x2001, 0x020d, 0x2003, 0x0050, 0x2003, 0x0020, 0x0804, 0x14cf,
+	0x78ab, 0x0004, 0x7803, 0x0001, 0x080c, 0x1503, 0x0005, 0x7827,
+	0x0018, 0xa001, 0x7828, 0x7827, 0x0011, 0xa001, 0x7928, 0x9106,
+	0x0110, 0x79ac, 0x08e0, 0x00e6, 0x2071, 0x0200, 0x702c, 0xd0c4,
+	0x0140, 0x00ee, 0x080c, 0x1b02, 0x080c, 0x1322, 0x7803, 0x0001,
+	0x0005, 0x7037, 0x0001, 0xa001, 0x7150, 0x00ee, 0x918c, 0xff00,
+	0x9186, 0x0500, 0x0110, 0x79ac, 0x0810, 0x7004, 0xc09d, 0x7006,
+	0x78ab, 0x0004, 0x7803, 0x0001, 0x080c, 0x1503, 0x2001, 0x020d,
+	0x2003, 0x0020, 0x0005, 0x7828, 0x782b, 0x0000, 0x9065, 0x090c,
+	0x0dc5, 0x6014, 0x2048, 0x78ab, 0x0004, 0x918c, 0x0700, 0x01a8,
+	0x080c, 0x8000, 0x080c, 0x1b02, 0x080c, 0xce3f, 0x0158, 0xa9ac,
+	0xa936, 0xa9b0, 0xa93a, 0xa83f, 0xffff, 0xa843, 0xffff, 0xa880,
+	0xc0bd, 0xa882, 0x080c, 0xca5e, 0x0005, 0x6020, 0x9086, 0x0009,
+	0x1128, 0x2009, 0x004c, 0x080c, 0xb166, 0x0048, 0x6010, 0x00b6,
+	0x2058, 0xb800, 0x00be, 0xd0bc, 0x6024, 0x190c, 0xd22b, 0x2029,
+	0x00c8, 0x8529, 0x0128, 0x2001, 0x0201, 0x2004, 0x9005, 0x0dc8,
+	0x7dbc, 0x080c, 0xed6d, 0xd5a4, 0x1118, 0x080c, 0x15a0, 0x0005,
+	0x080c, 0x8000, 0x080c, 0x1b02, 0x0005, 0x781f, 0x0300, 0x7803,
+	0x0001, 0x0005, 0x0016, 0x0066, 0x0076, 0x00f6, 0x2079, 0x0300,
+	0x7908, 0x918c, 0x0007, 0x9186, 0x0003, 0x0120, 0x2001, 0x0016,
+	0x080c, 0x1611, 0x00fe, 0x007e, 0x006e, 0x001e, 0x0005, 0x7004,
+	0xc09d, 0x7006, 0x0005, 0x7104, 0x9184, 0x0004, 0x190c, 0x0dc5,
+	0xd184, 0x11b1, 0xd19c, 0x0180, 0xc19c, 0x7106, 0x0016, 0x080c,
+	0x16de, 0x001e, 0x0148, 0x2001, 0x020d, 0x2003, 0x0050, 0x2003,
+	0x0020, 0x080c, 0x15a0, 0x0005, 0x81ff, 0x190c, 0x0dc5, 0x0005,
+	0x2100, 0xc184, 0xc1b4, 0x7106, 0xd0b4, 0x0016, 0x00e6, 0x1904,
+	0x156a, 0x2071, 0x0200, 0x080c, 0x16cb, 0x05e0, 0x080c, 0x16de,
+	0x05b0, 0x6014, 0x9005, 0x05b0, 0x0096, 0x2048, 0xa864, 0x009e,
+	0x9084, 0x00ff, 0x908e, 0x0029, 0x0160, 0x908e, 0x0048, 0x1550,
+	0x601c, 0xd084, 0x11e0, 0x00f6, 0x2c78, 0x080c, 0x1768, 0x00fe,
+	0x00b0, 0x00f6, 0x2c78, 0x080c, 0x18f1, 0x00fe, 0x2009, 0x01f4,
+	0x8109, 0x0168, 0x2001, 0x0201, 0x2004, 0x9005, 0x0dc8, 0x2001,
+	0x0218, 0x2004, 0xd0ec, 0x1118, 0x080c, 0x15a0, 0x0040, 0x2001,
+	0x020d, 0x2003, 0x0020, 0x080c, 0x1322, 0x7803, 0x0001, 0x00ee,
+	0x001e, 0x0005, 0x080c, 0x16de, 0x0dd0, 0x2001, 0x020d, 0x2003,
+	0x0050, 0x2003, 0x0020, 0x0461, 0x0c90, 0x0429, 0x2060, 0x2009,
+	0x0053, 0x080c, 0xb166, 0x0005, 0x0005, 0x0005, 0x00e1, 0x2008,
+	0x00d1, 0x0006, 0x7004, 0xc09d, 0x7006, 0x000e, 0x080c, 0x8fa5,
+	0x0005, 0x0089, 0x9005, 0x0118, 0x080c, 0x8ba8, 0x0cd0, 0x0005,
+	0x2001, 0x0036, 0x2009, 0x1820, 0x210c, 0x2011, 0x181f, 0x2214,
+	0x080c, 0x1611, 0x0005, 0x7808, 0xd09c, 0x0de8, 0x7820, 0x0005,
+	0x080c, 0x14ea, 0x00d6, 0x2069, 0x0200, 0x2009, 0x01f4, 0x8109,
+	0x0510, 0x6804, 0x9005, 0x0dd8, 0x2001, 0x015d, 0x2003, 0x0000,
+	0x79bc, 0xd1a4, 0x1528, 0x79b8, 0x918c, 0x0fff, 0x0180, 0x9182,
+	0x0841, 0x1268, 0x9188, 0x0007, 0x918c, 0x0ff8, 0x810c, 0x810c,
+	0x810c, 0x080c, 0x1603, 0x6827, 0x0001, 0x8109, 0x1dd0, 0x04d9,
+	0x6827, 0x0002, 0x04c1, 0x6804, 0x9005, 0x1130, 0x682c, 0xd0e4,
+	0x1500, 0x6804, 0x9005, 0x0de8, 0x79b8, 0xd1ec, 0x1130, 0x08c0,
+	0x080c, 0x8000, 0x080c, 0x1b02, 0x0090, 0x7827, 0x0015, 0x782b,
+	0x0000, 0x7827, 0x0018, 0x782b, 0x0000, 0x2001, 0x020d, 0x2003,
+	0x0020, 0x2001, 0x0307, 0x2003, 0x0300, 0x7803, 0x0001, 0x00de,
+	0x0005, 0x682c, 0x9084, 0x5400, 0x9086, 0x5400, 0x0d30, 0x7827,
+	0x0015, 0x782b, 0x0000, 0x7803, 0x0001, 0x6800, 0x9085, 0x1800,
+	0x6802, 0x00de, 0x0005, 0x6824, 0x9084, 0x0003, 0x1de0, 0x0005,
+	0x2001, 0x0030, 0x2c08, 0x621c, 0x0021, 0x7830, 0x9086, 0x0041,
+	0x0005, 0x00f6, 0x2079, 0x0300, 0x0006, 0x7808, 0xd09c, 0x0140,
+	0x0016, 0x0026, 0x00c6, 0x080c, 0x1394, 0x00ce, 0x002e, 0x001e,
+	0x000e, 0x0006, 0x7832, 0x7936, 0x7a3a, 0x781b, 0x8080, 0x0059,
+	0x1118, 0x000e, 0x00fe, 0x0005, 0x000e, 0x792c, 0x3900, 0x8000,
+	0x2004, 0x080c, 0x0dc5, 0x2009, 0x180c, 0x2104, 0xc0f4, 0x200a,
+	0x2009, 0xff00, 0x8109, 0x0904, 0x168f, 0x7a18, 0x9284, 0x0030,
+	0x0904, 0x168a, 0x9284, 0x0048, 0x9086, 0x0008, 0x1904, 0x168a,
+	0x2001, 0x0109, 0x2004, 0xd08c, 0x01f0, 0x0006, 0x01c6, 0x01d6,
+	0x0136, 0x0146, 0x0156, 0x0126, 0x2091, 0x2800, 0x00f6, 0x0026,
+	0x0016, 0x2009, 0x1a82, 0x2104, 0x8000, 0x0208, 0x200a, 0x080c,
+	0x92e7, 0x001e, 0x002e, 0x00fe, 0x012e, 0x015e, 0x014e, 0x013e,
+	0x01de, 0x01ce, 0x000e, 0x2001, 0x009b, 0x2004, 0xd0fc, 0x01d0,
+	0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x00f6,
+	0x0016, 0x2009, 0x1a83, 0x2104, 0x8000, 0x0208, 0x200a, 0x080c,
+	0x1f0c, 0x001e, 0x00fe, 0x015e, 0x014e, 0x013e, 0x01de, 0x01ce,
+	0x012e, 0x000e, 0x7818, 0xd0bc, 0x1904, 0x163a, 0x0005, 0x2001,
+	0x180c, 0x2004, 0xd0f4, 0x1528, 0x7a18, 0x9284, 0x0030, 0x0508,
+	0x9284, 0x0048, 0x9086, 0x0008, 0x11e0, 0x2001, 0x19f8, 0x2004,
+	0x9005, 0x01b8, 0x2001, 0x1a6a, 0x2004, 0x9086, 0x0000, 0x0188,
+	0x2009, 0x1a81, 0x2104, 0x8000, 0x0208, 0x200a, 0x080c, 0xa57b,
+	0x2009, 0x180c, 0x2104, 0xc0f5, 0x200a, 0x2009, 0xff00, 0x0804,
+	0x163a, 0x9085, 0x0001, 0x0005, 0x7832, 0x7936, 0x7a3a, 0x781b,
+	0x8080, 0x080c, 0x1633, 0x1108, 0x0005, 0x792c, 0x3900, 0x8000,
+	0x2004, 0x080c, 0x0dc5, 0x7037, 0x0001, 0x7150, 0x7037, 0x0002,
+	0x7050, 0x2060, 0xd1bc, 0x1110, 0x7054, 0x2060, 0x918c, 0xff00,
+	0x9186, 0x0500, 0x0110, 0x9085, 0x0001, 0x0005, 0x0006, 0x0046,
+	0x00e6, 0x2071, 0x0200, 0x7037, 0x0002, 0x7058, 0x9084, 0xff00,
+	0x8007, 0x9086, 0x00bc, 0x1158, 0x2021, 0x1a80, 0x2404, 0x8000,
+	0x0208, 0x2022, 0x080c, 0x8000, 0x080c, 0x1b02, 0x9006, 0x00ee,
+	0x004e, 0x000e, 0x0005, 0x0c11, 0x1108, 0x0005, 0x00e6, 0x0016,
+	0x2071, 0x0200, 0x0841, 0x6124, 0xd1dc, 0x01f8, 0x701c, 0xd08c,
+	0x0904, 0x175d, 0x7017, 0x0000, 0x2001, 0x0264, 0x2004, 0xd0bc,
+	0x0904, 0x175d, 0x2001, 0x0268, 0x00c6, 0x2064, 0x6104, 0x6038,
+	0x00ce, 0x918e, 0x0039, 0x1904, 0x175d, 0x9c06, 0x15f0, 0x0126,
+	0x2091, 0x2600, 0x080c, 0x7f47, 0x012e, 0x7358, 0x745c, 0x6014,
+	0x905d, 0x0598, 0x2b48, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be,
+	0xd0bc, 0x190c, 0xd206, 0xab42, 0xac3e, 0x2001, 0x1869, 0x2004,
+	0xd0b4, 0x1170, 0x601c, 0xd0e4, 0x1158, 0x6010, 0x00b6, 0x2058,
+	0xb800, 0x00be, 0xd0bc, 0x1120, 0xa83b, 0x7fff, 0xa837, 0xffff,
+	0x080c, 0x2108, 0x1190, 0x080c, 0x194e, 0x2a00, 0xa816, 0x0130,
+	0x2800, 0xa80e, 0x2c05, 0xa80a, 0x2c00, 0xa812, 0x7037, 0x0020,
+	0x781f, 0x0300, 0x001e, 0x00ee, 0x0005, 0x7037, 0x0050, 0x7037,
+	0x0020, 0x001e, 0x00ee, 0x080c, 0x15a0, 0x0005, 0x080c, 0x0dc5,
+	0x2ff0, 0x0126, 0x2091, 0x2200, 0x0016, 0x00c6, 0x3e60, 0x6014,
+	0x2048, 0x2940, 0x903e, 0x2730, 0xa864, 0x2068, 0xa81a, 0x9d84,
+	0x000f, 0x9088, 0x20e8, 0x2165, 0x0002, 0x1794, 0x1802, 0x1794,
+	0x1794, 0x1798, 0x17e3, 0x1794, 0x17b8, 0x178d, 0x17f9, 0x1794,
+	0x1794, 0x179d, 0x18ef, 0x17cc, 0x17c2, 0xa964, 0x918c, 0x00ff,
+	0x918e, 0x0048, 0x0904, 0x17f9, 0x9085, 0x0001, 0x0804, 0x18e5,
+	0xa87c, 0xd0ac, 0x0dc8, 0x0804, 0x1809, 0xa87c, 0xd0ac, 0x0da0,
+	0x0804, 0x1874, 0xa898, 0x901d, 0x1108, 0xab9c, 0x9016, 0xaab2,
+	0xaa3e, 0xaa42, 0x3e00, 0x9080, 0x0008, 0x2004, 0x9080, 0x9173,
+	0x2005, 0x9005, 0x090c, 0x0dc5, 0x2004, 0xa8ae, 0x0804, 0x18cd,
+	0xa87c, 0xd0bc, 0x09c8, 0xa890, 0xa842, 0xa88c, 0xa83e, 0xa888,
+	0x0804, 0x1809, 0xa87c, 0xd0bc, 0x0978, 0xa890, 0xa842, 0xa88c,
+	0xa83e, 0xa888, 0x0804, 0x1874, 0xa87c, 0xd0bc, 0x0928, 0xa890,
+	0xa842, 0xa88c, 0xa83e, 0xa804, 0x9045, 0x090c, 0x0dc5, 0xa164,
+	0xa91a, 0x91ec, 0x000f, 0x9d80, 0x20e8, 0x2065, 0xa888, 0xd19c,
+	0x1904, 0x1874, 0x0430, 0xa87c, 0xd0ac, 0x0904, 0x1794, 0xa804,
+	0x9045, 0x090c, 0x0dc5, 0xa164, 0xa91a, 0x91ec, 0x000f, 0x9d80,
+	0x20e8, 0x2065, 0x9006, 0xa842, 0xa83e, 0xd19c, 0x1904, 0x1874,
+	0x0080, 0xa87c, 0xd0ac, 0x0904, 0x1794, 0x9006, 0xa842, 0xa83e,
+	0x0804, 0x1874, 0xa87c, 0xd0ac, 0x0904, 0x1794, 0x9006, 0xa842,
+	0xa83e, 0x2c05, 0x908a, 0x0036, 0x1a0c, 0x0dc5, 0x9082, 0x001b,
+	0x0002, 0x182c, 0x182c, 0x182e, 0x182c, 0x182c, 0x182c, 0x1838,
+	0x182c, 0x182c, 0x182c, 0x1842, 0x182c, 0x182c, 0x182c, 0x184c,
+	0x182c, 0x182c, 0x182c, 0x1856, 0x182c, 0x182c, 0x182c, 0x1860,
+	0x182c, 0x182c, 0x182c, 0x186a, 0x080c, 0x0dc5, 0xa574, 0xa478,
+	0x9d86, 0x0024, 0x0904, 0x17a2, 0xa37c, 0xa280, 0x0804, 0x18cd,
+	0xa584, 0xa488, 0x9d86, 0x0024, 0x0904, 0x17a2, 0xa38c, 0xa290,
+	0x0804, 0x18cd, 0xa594, 0xa498, 0x9d86, 0x0024, 0x0904, 0x17a2,
+	0xa39c, 0xa2a0, 0x0804, 0x18cd, 0xa5a4, 0xa4a8, 0x9d86, 0x0024,
+	0x0904, 0x17a2, 0xa3ac, 0xa2b0, 0x0804, 0x18cd, 0xa5b4, 0xa4b8,
+	0x9d86, 0x0024, 0x0904, 0x17a2, 0xa3bc, 0xa2c0, 0x0804, 0x18cd,
+	0xa5c4, 0xa4c8, 0x9d86, 0x0024, 0x0904, 0x17a2, 0xa3cc, 0xa2d0,
+	0x0804, 0x18cd, 0xa5d4, 0xa4d8, 0x9d86, 0x0024, 0x0904, 0x17a2,
+	0xa3dc, 0xa2e0, 0x0804, 0x18cd, 0x2c05, 0x908a, 0x0034, 0x1a0c,
+	0x0dc5, 0x9082, 0x001b, 0x0002, 0x1897, 0x1895, 0x1895, 0x1895,
+	0x1895, 0x1895, 0x18a2, 0x1895, 0x1895, 0x1895, 0x1895, 0x1895,
+	0x18ad, 0x1895, 0x1895, 0x1895, 0x1895, 0x1895, 0x18b8, 0x1895,
+	0x1895, 0x1895, 0x1895, 0x1895, 0x18c3, 0x080c, 0x0dc5, 0xa56c,
+	0xa470, 0xa774, 0xa678, 0x9d86, 0x002c, 0x0904, 0x17a2, 0xa37c,
+	0xa280, 0x0458, 0xa584, 0xa488, 0xa78c, 0xa690, 0x9d86, 0x002c,
+	0x0904, 0x17a2, 0xa394, 0xa298, 0x0400, 0xa59c, 0xa4a0, 0xa7a4,
+	0xa6a8, 0x9d86, 0x002c, 0x0904, 0x17a2, 0xa3ac, 0xa2b0, 0x00a8,
+	0xa5b4, 0xa4b8, 0xa7bc, 0xa6c0, 0x9d86, 0x002c, 0x0904, 0x17a2,
+	0xa3c4, 0xa2c8, 0x0050, 0xa5cc, 0xa4d0, 0xa7d4, 0xa6d8, 0x9d86,
+	0x002c, 0x0904, 0x17a2, 0xa3dc, 0xa2e0, 0xab2e, 0xaa32, 0xad1e,
+	0xac22, 0xaf26, 0xae2a, 0xa988, 0x8c60, 0x2c1d, 0xa8ac, 0xaab0,
+	0xa836, 0xaa3a, 0x8109, 0xa916, 0x1160, 0x3e60, 0x601c, 0xc085,
+	0x601e, 0xa87c, 0xc0dd, 0xa87e, 0x9006, 0x00ce, 0x001e, 0x012e,
+	0x0005, 0x2800, 0xa80e, 0xab0a, 0x2c00, 0xa812, 0x0c70, 0x0804,
+	0x1794, 0x2ff0, 0x0126, 0x2091, 0x2200, 0x0016, 0x00c6, 0x3e60,
+	0x6014, 0x2048, 0x2940, 0xa80e, 0x2061, 0x20e3, 0xa813, 0x20e3,
+	0x2c05, 0xa80a, 0xa964, 0xa91a, 0xa87c, 0xd0ac, 0x090c, 0x0dc5,
+	0x9006, 0xa842, 0xa83e, 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0dc5,
+	0xadcc, 0xacd0, 0xafd4, 0xaed8, 0xabdc, 0xaae0, 0xab2e, 0xaa32,
+	0xad1e, 0xac22, 0xaf26, 0xae2a, 0xa8ac, 0xaab0, 0xa836, 0xaa3a,
+	0xa988, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0008, 0x1120, 0x8109,
+	0xa916, 0x0128, 0x0080, 0x918a, 0x0002, 0xa916, 0x1160, 0x3e60,
+	0x601c, 0xc085, 0x601e, 0xa87c, 0xc0dd, 0xa87e, 0x9006, 0x00ce,
+	0x001e, 0x012e, 0x0005, 0xa804, 0x9045, 0x090c, 0x0dc5, 0xa80e,
+	0xa064, 0xa81a, 0x9084, 0x000f, 0x9080, 0x20e8, 0x2015, 0x82ff,
+	0x090c, 0x0dc5, 0xaa12, 0x2205, 0xa80a, 0x0c08, 0x903e, 0x2730,
+	0xa880, 0xd0fc, 0x1190, 0x2d00, 0x0002, 0x1a78, 0x19a5, 0x19a5,
+	0x1a78, 0x19a5, 0x1a72, 0x1a78, 0x19a5, 0x1a15, 0x1a15, 0x1a15,
+	0x1a78, 0x1a15, 0x1a78, 0x1a6f, 0x1a15, 0xc0fc, 0xa882, 0xab2c,
+	0xaa30, 0xad1c, 0xac20, 0xdd9c, 0x0904, 0x1a7a, 0x2c05, 0x908a,
+	0x0034, 0x1a0c, 0x0dc5, 0x9082, 0x001b, 0x0002, 0x1991, 0x198f,
+	0x198f, 0x198f, 0x198f, 0x198f, 0x1995, 0x198f, 0x198f, 0x198f,
+	0x198f, 0x198f, 0x1999, 0x198f, 0x198f, 0x198f, 0x198f, 0x198f,
+	0x199d, 0x198f, 0x198f, 0x198f, 0x198f, 0x198f, 0x19a1, 0x080c,
+	0x0dc5, 0xa774, 0xa678, 0x0804, 0x1a7a, 0xa78c, 0xa690, 0x0804,
+	0x1a7a, 0xa7a4, 0xa6a8, 0x0804, 0x1a7a, 0xa7bc, 0xa6c0, 0x0804,
+	0x1a7a, 0xa7d4, 0xa6d8, 0x0804, 0x1a7a, 0xa898, 0x901d, 0x1108,
+	0xab9c, 0x9016, 0x2c05, 0x908a, 0x0036, 0x1a0c, 0x0dc5, 0x9082,
+	0x001b, 0x0002, 0x19cd, 0x19cd, 0x19cf, 0x19cd, 0x19cd, 0x19cd,
+	0x19d9, 0x19cd, 0x19cd, 0x19cd, 0x19e3, 0x19cd, 0x19cd, 0x19cd,
+	0x19ed, 0x19cd, 0x19cd, 0x19cd, 0x19f7, 0x19cd, 0x19cd, 0x19cd,
+	0x1a01, 0x19cd, 0x19cd, 0x19cd, 0x1a0b, 0x080c, 0x0dc5, 0xa574,
+	0xa478, 0x9d86, 0x0004, 0x0904, 0x1a7a, 0xa37c, 0xa280, 0x0804,
+	0x1a7a, 0xa584, 0xa488, 0x9d86, 0x0004, 0x0904, 0x1a7a, 0xa38c,
+	0xa290, 0x0804, 0x1a7a, 0xa594, 0xa498, 0x9d86, 0x0004, 0x0904,
+	0x1a7a, 0xa39c, 0xa2a0, 0x0804, 0x1a7a, 0xa5a4, 0xa4a8, 0x9d86,
+	0x0004, 0x0904, 0x1a7a, 0xa3ac, 0xa2b0, 0x0804, 0x1a7a, 0xa5b4,
+	0xa4b8, 0x9d86, 0x0004, 0x0904, 0x1a7a, 0xa3bc, 0xa2c0, 0x0804,
+	0x1a7a, 0xa5c4, 0xa4c8, 0x9d86, 0x0004, 0x0904, 0x1a7a, 0xa3cc,
+	0xa2d0, 0x0804, 0x1a7a, 0xa5d4, 0xa4d8, 0x9d86, 0x0004, 0x0904,
+	0x1a7a, 0xa3dc, 0xa2e0, 0x0804, 0x1a7a, 0xa898, 0x901d, 0x1108,
+	0xab9c, 0x9016, 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0dc5, 0x9082,
+	0x001b, 0x0002, 0x1a3d, 0x1a3b, 0x1a3b, 0x1a3b, 0x1a3b, 0x1a3b,
+	0x1a47, 0x1a3b, 0x1a3b, 0x1a3b, 0x1a3b, 0x1a3b, 0x1a51, 0x1a3b,
+	0x1a3b, 0x1a3b, 0x1a3b, 0x1a3b, 0x1a5b, 0x1a3b, 0x1a3b, 0x1a3b,
+	0x1a3b, 0x1a3b, 0x1a65, 0x080c, 0x0dc5, 0xa56c, 0xa470, 0xa774,
+	0xa678, 0x9d86, 0x000c, 0x05b0, 0xa37c, 0xa280, 0x0498, 0xa584,
+	0xa488, 0xa78c, 0xa690, 0x9d86, 0x000c, 0x0560, 0xa394, 0xa298,
+	0x0448, 0xa59c, 0xa4a0, 0xa7a4, 0xa6a8, 0x9d86, 0x000c, 0x0510,
+	0xa3ac, 0xa2b0, 0x00f8, 0xa5b4, 0xa4b8, 0xa7bc, 0xa6c0, 0x9d86,
+	0x000c, 0x01c0, 0xa3c4, 0xa2c8, 0x00a8, 0xa5cc, 0xa4d0, 0xa7d4,
+	0xa6d8, 0x9d86, 0x000c, 0x0170, 0xa3dc, 0xa2e0, 0x0058, 0x9d86,
+	0x000e, 0x1130, 0x080c, 0x20a0, 0x1904, 0x194e, 0x900e, 0x0050,
+	0x080c, 0x0dc5, 0xab2e, 0xaa32, 0xad1e, 0xac22, 0xaf26, 0xae2a,
+	0x080c, 0x20a0, 0x0005, 0x6014, 0x2048, 0x6118, 0x81ff, 0x0148,
+	0x810c, 0x810c, 0x810c, 0x81ff, 0x1118, 0xa887, 0x0001, 0x0008,
+	0xa986, 0x601b, 0x0002, 0xa874, 0x9084, 0x00ff, 0x9084, 0x0008,
+	0x0150, 0x00e9, 0x6000, 0x9086, 0x0004, 0x1120, 0x2009, 0x0048,
+	0x080c, 0xb166, 0x0005, 0xa974, 0xd1dc, 0x1108, 0x0005, 0xa934,
+	0xa88c, 0x9106, 0x1158, 0xa938, 0xa890, 0x9106, 0x1138, 0x601c,
+	0xc084, 0x601e, 0x2009, 0x0048, 0x0804, 0xb166, 0x0005, 0x0126,
+	0x00c6, 0x2091, 0x2200, 0x00ce, 0x7908, 0x918c, 0x0007, 0x9186,
+	0x0000, 0x05b0, 0x9186, 0x0003, 0x0598, 0x6020, 0x6023, 0x0000,
+	0x0006, 0x2031, 0x0008, 0x00c6, 0x781f, 0x0808, 0x7808, 0xd09c,
+	0x0120, 0x080c, 0x1394, 0x8631, 0x1db8, 0x00ce, 0x781f, 0x0800,
+	0x2031, 0x0168, 0x00c6, 0x7808, 0xd09c, 0x190c, 0x1394, 0x00ce,
+	0x2001, 0x0038, 0x080c, 0x1b8a, 0x7930, 0x9186, 0x0040, 0x0160,
+	0x9186, 0x0042, 0x190c, 0x0dc5, 0x2001, 0x001e, 0x8001, 0x1df0,
+	0x8631, 0x1d40, 0x080c, 0x1b99, 0x000e, 0x6022, 0x012e, 0x0005,
+	0x080c, 0x1b86, 0x7827, 0x0015, 0x7828, 0x9c06, 0x1db8, 0x782b,
+	0x0000, 0x0ca0, 0x00f6, 0x2079, 0x0300, 0x7803, 0x0000, 0x78ab,
+	0x0004, 0x00fe, 0x080c, 0x7563, 0x1188, 0x2001, 0x0138, 0x2003,
+	0x0000, 0x2001, 0x0160, 0x2003, 0x0000, 0x2011, 0x012c, 0xa001,
+	0xa001, 0x8211, 0x1de0, 0x0059, 0x0804, 0x7610, 0x0479, 0x0039,
+	0x2001, 0x0160, 0x2502, 0x2001, 0x0138, 0x2202, 0x0005, 0x00e6,
+	0x2071, 0x0200, 0x080c, 0x2c8f, 0x2009, 0x003c, 0x080c, 0x242a,
+	0x2001, 0x015d, 0x2003, 0x0000, 0x7000, 0x9084, 0x003c, 0x1de0,
+	0x080c, 0x85eb, 0x70a0, 0x70a2, 0x7098, 0x709a, 0x709c, 0x709e,
+	0x2001, 0x020d, 0x2003, 0x0020, 0x00f6, 0x2079, 0x0300, 0x080c,
+	0x1322, 0x7803, 0x0001, 0x00fe, 0x00ee, 0x0005, 0x2001, 0x0138,
+	0x2014, 0x2003, 0x0000, 0x2001, 0x0160, 0x202c, 0x2003, 0x0000,
+	0x080c, 0x7563, 0x1108, 0x0005, 0x2021, 0x0260, 0x2001, 0x0141,
+	0x201c, 0xd3dc, 0x1168, 0x2001, 0x0109, 0x201c, 0x939c, 0x0048,
+	0x1160, 0x2001, 0x0111, 0x201c, 0x83ff, 0x1110, 0x8421, 0x1d70,
+	0x2001, 0x015d, 0x2003, 0x0000, 0x0005, 0x0046, 0x2021, 0x0019,
+	0x2003, 0x0048, 0xa001, 0xa001, 0x201c, 0x939c, 0x0048, 0x0120,
+	0x8421, 0x1db0, 0x004e, 0x0c60, 0x004e, 0x0c40, 0x601c, 0xc084,
+	0x601e, 0x0005, 0x2c08, 0x621c, 0x080c, 0x1611, 0x7930, 0x0005,
+	0x2c08, 0x621c, 0x080c, 0x16bc, 0x7930, 0x0005, 0x8001, 0x1df0,
+	0x0005, 0x2031, 0x0064, 0x781c, 0x9084, 0x0007, 0x0170, 0x2001,
+	0x0038, 0x0c41, 0x9186, 0x0040, 0x0904, 0x1bf7, 0x2001, 0x001e,
+	0x0c69, 0x8631, 0x1d80, 0x080c, 0x0dc5, 0x781f, 0x0202, 0x2001,
+	0x015d, 0x2003, 0x0000, 0x2001, 0x0dac, 0x0c01, 0x781c, 0xd084,
+	0x0110, 0x0861, 0x04e0, 0x2001, 0x0030, 0x0891, 0x9186, 0x0040,
+	0x0568, 0x781c, 0xd084, 0x1da8, 0x781f, 0x0101, 0x2001, 0x0014,
+	0x0869, 0x2001, 0x0037, 0x0821, 0x9186, 0x0040, 0x0140, 0x2001,
+	0x0030, 0x080c, 0x1b90, 0x9186, 0x0040, 0x190c, 0x0dc5, 0x00d6,
+	0x2069, 0x0200, 0x692c, 0xd1f4, 0x1170, 0xd1c4, 0x0160, 0xd19c,
+	0x0130, 0x6800, 0x9085, 0x1800, 0x6802, 0x00de, 0x0080, 0x6908,
+	0x9184, 0x0007, 0x1db0, 0x00de, 0x781f, 0x0100, 0x791c, 0x9184,
+	0x0007, 0x090c, 0x0dc5, 0xa001, 0xa001, 0x781f, 0x0200, 0x0005,
+	0x0126, 0x2091, 0x2400, 0x2071, 0x1a6a, 0x2079, 0x0090, 0x012e,
+	0x0005, 0x9280, 0x0005, 0x2004, 0x2048, 0xa97c, 0xd1dc, 0x1904,
+	0x1c99, 0xa964, 0x9184, 0x0007, 0x0002, 0x1c15, 0x1c84, 0x1c2c,
+	0x1c2e, 0x1c2c, 0x1c6c, 0x1c4c, 0x1c3b, 0x918c, 0x00ff, 0x9186,
+	0x0008, 0x1170, 0xa87c, 0xd0b4, 0x0904, 0x1ec6, 0x9006, 0xa842,
+	0xa83e, 0xa988, 0x2900, 0xa85a, 0xa813, 0x20e3, 0x0804, 0x1c95,
+	0x9186, 0x0048, 0x0904, 0x1c84, 0x080c, 0x0dc5, 0x9184, 0x00ff,
+	0x9086, 0x0013, 0x0904, 0x1c84, 0x9184, 0x00ff, 0x9086, 0x001b,
+	0x0904, 0x1c84, 0x0c88, 0xa87c, 0xd0b4, 0x0904, 0x1ec6, 0xa890,
+	0xa842, 0xa83a, 0xa88c, 0xa83e, 0xa836, 0xa8ac, 0xa846, 0xa8b0,
+	0xa84a, 0xa988, 0x0804, 0x1c8c, 0xa864, 0x9084, 0x00ff, 0x9086,
+	0x001e, 0x19d0, 0xa87c, 0xd0b4, 0x0904, 0x1ec6, 0xa890, 0xa842,
+	0xa83a, 0xa88c, 0xa83e, 0xa836, 0xa8ac, 0xa846, 0xa8b0, 0xa84a,
+	0xa804, 0xa85a, 0x2040, 0xa064, 0x9084, 0x000f, 0x9080, 0x20e8,
+	0x2005, 0xa812, 0xa988, 0x0448, 0x918c, 0x00ff, 0x9186, 0x0015,
+	0x1540, 0xa87c, 0xd0b4, 0x0904, 0x1ec6, 0xa804, 0xa85a, 0x2040,
+	0xa064, 0x9084, 0x000f, 0x9080, 0x20e8, 0x2005, 0xa812, 0xa988,
+	0x9006, 0xa842, 0xa83e, 0x0088, 0xa87c, 0xd0b4, 0x0904, 0x1ec6,
+	0xa988, 0x9006, 0xa842, 0xa83e, 0x2900, 0xa85a, 0xa864, 0x9084,
+	0x000f, 0x9080, 0x20e8, 0x2005, 0xa812, 0xa916, 0xa87c, 0xc0dd,
+	0xa87e, 0x0005, 0x00f6, 0x2079, 0x0090, 0x782c, 0xd0fc, 0x190c,
+	0x1f0c, 0x00e6, 0x2071, 0x1a6a, 0x7000, 0x9005, 0x1904, 0x1d00,
+	0x7206, 0x9280, 0x0005, 0x204c, 0x9280, 0x0004, 0x2004, 0x782b,
+	0x0004, 0x00f6, 0x2079, 0x0200, 0x7803, 0x0040, 0x00fe, 0x00b6,
+	0x2058, 0xb86c, 0x7836, 0xb890, 0x00be, 0x00f6, 0x2079, 0x0200,
+	0x7803, 0x0040, 0xa001, 0xa001, 0xa001, 0xa001, 0xa001, 0xa001,
+	0x781a, 0x78d7, 0x0000, 0x00fe, 0xa814, 0x2050, 0xa858, 0x2040,
+	0xa810, 0x2060, 0xa064, 0x90ec, 0x000f, 0xa944, 0x791a, 0x7116,
+	0xa848, 0x781e, 0x701a, 0x9006, 0x700e, 0x7012, 0x7004, 0xa940,
+	0xa838, 0x9106, 0x1500, 0xa93c, 0xa834, 0x9106, 0x11e0, 0x0006,
+	0x0016, 0xa938, 0xa834, 0x9105, 0x0118, 0x001e, 0x000e, 0x0098,
+	0x001e, 0x000e, 0x8aff, 0x01c8, 0x0126, 0x2091, 0x8000, 0x2009,
+	0x0306, 0x200b, 0x0808, 0x00d9, 0x0108, 0x00c9, 0x012e, 0x9006,
+	0x00ee, 0x00fe, 0x0005, 0x0036, 0x0046, 0xab38, 0xac34, 0x080c,
+	0x2108, 0x004e, 0x003e, 0x0d30, 0x0c98, 0x9085, 0x0001, 0x0c80,
+	0x2009, 0x0306, 0x200b, 0x4800, 0x7027, 0x0000, 0x0005, 0x0076,
+	0x0066, 0x0056, 0x0046, 0x0036, 0x0026, 0x8aff, 0x0904, 0x1ebf,
+	0x700c, 0x7214, 0x923a, 0x7010, 0x7218, 0x9203, 0x0a04, 0x1ebe,
+	0x9705, 0x0904, 0x1ebe, 0x903e, 0x2730, 0xa880, 0xd0fc, 0x1190,
+	0x2d00, 0x0002, 0x1e43, 0x1d82, 0x1d82, 0x1e43, 0x1e43, 0x1e20,
+	0x1e43, 0x1d82, 0x1e27, 0x1dd1, 0x1dd1, 0x1e43, 0x1e43, 0x1e43,
+	0x1e1a, 0x1dd1, 0xc0fc, 0xa882, 0xab2c, 0xaa30, 0xad1c, 0xac20,
+	0xdd9c, 0x0904, 0x1e50, 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0dc5,
+	0x9082, 0x001b, 0x0002, 0x1d6e, 0x1d6c, 0x1d6c, 0x1d6c, 0x1d6c,
+	0x1d6c, 0x1d72, 0x1d6c, 0x1d6c, 0x1d6c, 0x1d6c, 0x1d6c, 0x1d76,
+	0x1d6c, 0x1d6c, 0x1d6c, 0x1d6c, 0x1d6c, 0x1d7a, 0x1d6c, 0x1d6c,
+	0x1d6c, 0x1d6c, 0x1d6c, 0x1d7e, 0x080c, 0x0dc5, 0xa774, 0xa678,
+	0x0804, 0x1e50, 0xa78c, 0xa690, 0x0804, 0x1e50, 0xa7a4, 0xa6a8,
+	0x0804, 0x1e50, 0xa7bc, 0xa6c0, 0x0804, 0x1e50, 0xa7d4, 0xa6d8,
+	0x0804, 0x1e50, 0x2c05, 0x908a, 0x0036, 0x1a0c, 0x0dc5, 0x9082,
+	0x001b, 0x0002, 0x1da5, 0x1da5, 0x1da7, 0x1da5, 0x1da5, 0x1da5,
+	0x1dad, 0x1da5, 0x1da5, 0x1da5, 0x1db3, 0x1da5, 0x1da5, 0x1da5,
+	0x1db9, 0x1da5, 0x1da5, 0x1da5, 0x1dbf, 0x1da5, 0x1da5, 0x1da5,
+	0x1dc5, 0x1da5, 0x1da5, 0x1da5, 0x1dcb, 0x080c, 0x0dc5, 0xa574,
+	0xa478, 0xa37c, 0xa280, 0x0804, 0x1e50, 0xa584, 0xa488, 0xa38c,
+	0xa290, 0x0804, 0x1e50, 0xa594, 0xa498, 0xa39c, 0xa2a0, 0x0804,
+	0x1e50, 0xa5a4, 0xa4a8, 0xa3ac, 0xa2b0, 0x0804, 0x1e50, 0xa5b4,
+	0xa4b8, 0xa3bc, 0xa2c0, 0x0804, 0x1e50, 0xa5c4, 0xa4c8, 0xa3cc,
+	0xa2d0, 0x0804, 0x1e50, 0xa5d4, 0xa4d8, 0xa3dc, 0xa2e0, 0x0804,
+	0x1e50, 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0dc5, 0x9082, 0x001b,
+	0x0002, 0x1df4, 0x1df2, 0x1df2, 0x1df2, 0x1df2, 0x1df2, 0x1dfc,
+	0x1df2, 0x1df2, 0x1df2, 0x1df2, 0x1df2, 0x1e04, 0x1df2, 0x1df2,
+	0x1df2, 0x1df2, 0x1df2, 0x1e0c, 0x1df2, 0x1df2, 0x1df2, 0x1df2,
+	0x1df2, 0x1e13, 0x080c, 0x0dc5, 0xa56c, 0xa470, 0xa774, 0xa678,
+	0xa37c, 0xa280, 0x0804, 0x1e50, 0xa584, 0xa488, 0xa78c, 0xa690,
+	0xa394, 0xa298, 0x0804, 0x1e50, 0xa59c, 0xa4a0, 0xa7a4, 0xa6a8,
+	0xa3ac, 0xa2b0, 0x0804, 0x1e50, 0xa5b4, 0xa4b8, 0xa7bc, 0xa6c0,
+	0xa3c4, 0xa2c8, 0x04e8, 0xa5cc, 0xa4d0, 0xa7d4, 0xa6d8, 0xa3dc,
+	0xa2e0, 0x04b0, 0xa864, 0x9084, 0x00ff, 0x9086, 0x001e, 0x1518,
+	0x080c, 0x20a0, 0x1904, 0x1d1d, 0x900e, 0x0804, 0x1ebf, 0xab64,
+	0x939c, 0x00ff, 0x9386, 0x0048, 0x1180, 0x00c6, 0x7004, 0x2060,
+	0x6004, 0x9086, 0x0043, 0x00ce, 0x0904, 0x1dd1, 0xab9c, 0x9016,
+	0xad8c, 0xac90, 0xaf94, 0xae98, 0x0098, 0x9386, 0x0008, 0x0904,
+	0x1dd1, 0x080c, 0x0dc5, 0xa964, 0x918c, 0x00ff, 0x9186, 0x0013,
+	0x0904, 0x1d82, 0x9186, 0x001b, 0x0904, 0x1dd1, 0x080c, 0x0dc5,
+	0x2009, 0x030f, 0x2104, 0xd0fc, 0x0538, 0x0066, 0x2009, 0x0306,
+	0x2134, 0x200b, 0x4000, 0x2104, 0x9084, 0x0030, 0x15b8, 0x2031,
+	0x1000, 0x2600, 0x9302, 0x928b, 0x0000, 0xa82e, 0xa932, 0x0278,
+	0x9105, 0x0168, 0x2011, 0x0000, 0x2618, 0x2600, 0x9500, 0xa81e,
+	0x9481, 0x0000, 0xa822, 0xa880, 0xc0fd, 0xa882, 0x0020, 0xa82f,
+	0x0000, 0xa833, 0x0000, 0x006e, 0x7b12, 0x7a16, 0x7d02, 0x7c06,
+	0x7f0a, 0x7e0e, 0x782b, 0x0001, 0x7000, 0x8000, 0x7002, 0xa83c,
+	0x9300, 0xa83e, 0xa840, 0x9201, 0xa842, 0x700c, 0x9300, 0x700e,
+	0x7010, 0x9201, 0x7012, 0x080c, 0x20a0, 0x0448, 0xd6b4, 0x0110,
+	0x200b, 0x4040, 0x2031, 0x0080, 0x9584, 0x007f, 0x0108, 0x9632,
+	0x7124, 0x7000, 0x9086, 0x0000, 0x1198, 0xc185, 0x7126, 0x2009,
+	0x0306, 0x2104, 0xd0b4, 0x1904, 0x1e61, 0x200b, 0x4040, 0x2009,
+	0x1a84, 0x2104, 0x8000, 0x0a04, 0x1e61, 0x200a, 0x0804, 0x1e61,
+	0xc18d, 0x7126, 0xd184, 0x1d58, 0x0804, 0x1e61, 0x9006, 0x002e,
+	0x003e, 0x004e, 0x005e, 0x006e, 0x007e, 0x0005, 0x080c, 0x0dc5,
+	0x0026, 0x2001, 0x0105, 0x2003, 0x0010, 0x782b, 0x0004, 0x7003,
+	0x0000, 0x7004, 0x2060, 0x6014, 0x2048, 0x080c, 0xce3f, 0x0118,
+	0xa880, 0xc0bd, 0xa882, 0x782c, 0xd0ac, 0x1de8, 0x080c, 0x1d10,
+	0x6020, 0x9086, 0x0006, 0x1180, 0x2061, 0x0100, 0x62c8, 0x2001,
+	0x00fa, 0x8001, 0x1df0, 0x60c8, 0x9206, 0x1dc0, 0x60c4, 0xa89a,
+	0x60c8, 0xa896, 0x7004, 0x2060, 0x00c6, 0x080c, 0xca5e, 0x00ce,
+	0x2001, 0x19f8, 0x2004, 0x9c06, 0x1160, 0x2009, 0x0040, 0x080c,
+	0x242a, 0x080c, 0xaa3f, 0x2011, 0x0000, 0x080c, 0xa8dd, 0x080c,
+	0x9a09, 0x002e, 0x0804, 0x2050, 0x0126, 0x2091, 0x2400, 0xa858,
+	0x2040, 0x792c, 0x782b, 0x0002, 0x9184, 0x0700, 0x1904, 0x1ec8,
+	0x7000, 0x0002, 0x2050, 0x1f1e, 0x1f9e, 0x204e, 0x8001, 0x7002,
+	0x7027, 0x0000, 0xd19c, 0x1158, 0x8aff, 0x0904, 0x1f6b, 0x080c,
+	0x1d17, 0x0904, 0x2050, 0x080c, 0x1d17, 0x0804, 0x2050, 0x782b,
+	0x0004, 0xd194, 0x0148, 0xa880, 0xc0fc, 0xa882, 0x8aff, 0x1518,
+	0xa87c, 0xc0f5, 0xa87e, 0x00f8, 0x0026, 0x0036, 0xab3c, 0xaa40,
+	0x0016, 0x7910, 0xa82c, 0x9100, 0xa82e, 0x7914, 0xa830, 0x9101,
+	0xa832, 0x001e, 0x7810, 0x931a, 0x7814, 0x9213, 0x7800, 0xa81e,
+	0x7804, 0xa822, 0xab3e, 0xaa42, 0x003e, 0x002e, 0x080c, 0x20bb,
+	0xa880, 0xc0fd, 0xa882, 0x2a00, 0xa816, 0x2800, 0xa85a, 0x2c00,
+	0xa812, 0x7003, 0x0000, 0x2009, 0x0306, 0x200b, 0x4800, 0x7027,
+	0x0000, 0x0804, 0x2050, 0x00f6, 0x0026, 0x781c, 0x0006, 0x7818,
+	0x0006, 0x2079, 0x0100, 0x7a14, 0x9284, 0x1984, 0x9085, 0x0012,
+	0x7816, 0x0036, 0x2019, 0x1000, 0x8319, 0x090c, 0x0dc5, 0x7820,
+	0xd0bc, 0x1dd0, 0x003e, 0x79c8, 0x000e, 0x9102, 0x001e, 0x0006,
+	0x0016, 0x79c4, 0x000e, 0x9103, 0x78c6, 0x000e, 0x78ca, 0x9284,
+	0x1984, 0x9085, 0x0012, 0x7816, 0x002e, 0x00fe, 0x782b, 0x0008,
+	0x7003, 0x0000, 0x080c, 0x1d10, 0x0804, 0x2050, 0x8001, 0x7002,
+	0x7024, 0x8004, 0x7026, 0xd194, 0x0170, 0x782c, 0xd0fc, 0x1904,
+	0x1f11, 0xd19c, 0x1904, 0x204c, 0x8aff, 0x0904, 0x2050, 0x080c,
+	0x1d17, 0x0804, 0x2050, 0x0026, 0x0036, 0xab3c, 0xaa40, 0x080c,
+	0x20bb, 0xdd9c, 0x1904, 0x200b, 0x2c05, 0x908a, 0x0036, 0x1a0c,
+	0x0dc5, 0x9082, 0x001b, 0x0002, 0x1fdf, 0x1fdf, 0x1fe1, 0x1fdf,
+	0x1fdf, 0x1fdf, 0x1fe7, 0x1fdf, 0x1fdf, 0x1fdf, 0x1fed, 0x1fdf,
+	0x1fdf, 0x1fdf, 0x1ff3, 0x1fdf, 0x1fdf, 0x1fdf, 0x1ff9, 0x1fdf,
+	0x1fdf, 0x1fdf, 0x1fff, 0x1fdf, 0x1fdf, 0x1fdf, 0x2005, 0x080c,
+	0x0dc5, 0xa07c, 0x931a, 0xa080, 0x9213, 0x0804, 0x1f40, 0xa08c,
+	0x931a, 0xa090, 0x9213, 0x0804, 0x1f40, 0xa09c, 0x931a, 0xa0a0,
+	0x9213, 0x0804, 0x1f40, 0xa0ac, 0x931a, 0xa0b0, 0x9213, 0x0804,
+	0x1f40, 0xa0bc, 0x931a, 0xa0c0, 0x9213, 0x0804, 0x1f40, 0xa0cc,
+	0x931a, 0xa0d0, 0x9213, 0x0804, 0x1f40, 0xa0dc, 0x931a, 0xa0e0,
+	0x9213, 0x0804, 0x1f40, 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0dc5,
+	0x9082, 0x001b, 0x0002, 0x202e, 0x202c, 0x202c, 0x202c, 0x202c,
+	0x202c, 0x2034, 0x202c, 0x202c, 0x202c, 0x202c, 0x202c, 0x203a,
+	0x202c, 0x202c, 0x202c, 0x202c, 0x202c, 0x2040, 0x202c, 0x202c,
+	0x202c, 0x202c, 0x202c, 0x2046, 0x080c, 0x0dc5, 0xa07c, 0x931a,
+	0xa080, 0x9213, 0x0804, 0x1f40, 0xa094, 0x931a, 0xa098, 0x9213,
+	0x0804, 0x1f40, 0xa0ac, 0x931a, 0xa0b0, 0x9213, 0x0804, 0x1f40,
+	0xa0c4, 0x931a, 0xa0c8, 0x9213, 0x0804, 0x1f40, 0xa0dc, 0x931a,
+	0xa0e0, 0x9213, 0x0804, 0x1f40, 0x0804, 0x1f3c, 0x080c, 0x0dc5,
+	0x012e, 0x0005, 0x00f6, 0x00e6, 0x2071, 0x1a6a, 0x7000, 0x9086,
+	0x0000, 0x0904, 0x209b, 0x2079, 0x0090, 0x2009, 0x0207, 0x210c,
+	0xd194, 0x01b8, 0x2009, 0x020c, 0x210c, 0x9184, 0x0003, 0x0188,
+	0x080c, 0xedb6, 0x2001, 0x0133, 0x2004, 0x9005, 0x090c, 0x0dc5,
+	0x0016, 0x2009, 0x0040, 0x080c, 0x242a, 0x001e, 0x2001, 0x020c,
+	0x2102, 0x2009, 0x0206, 0x2104, 0x2009, 0x0203, 0x210c, 0x9106,
+	0x1120, 0x2009, 0x0040, 0x080c, 0x242a, 0x782c, 0xd0fc, 0x09a8,
+	0x080c, 0x1f0c, 0x7000, 0x9086, 0x0000, 0x1978, 0x782b, 0x0004,
+	0x782c, 0xd0ac, 0x1de8, 0x2009, 0x0040, 0x080c, 0x242a, 0x782b,
+	0x0002, 0x7003, 0x0000, 0x080c, 0x1d10, 0x00ee, 0x00fe, 0x0005,
+	0xa880, 0xd0fc, 0x11a8, 0x8c60, 0x2c05, 0x9005, 0x0110, 0x8a51,
+	0x0005, 0xa004, 0x9005, 0x0168, 0xa85a, 0x2040, 0xa064, 0x9084,
+	0x000f, 0x9080, 0x20e8, 0x2065, 0x8cff, 0x090c, 0x0dc5, 0x8a51,
+	0x0005, 0x2050, 0x0005, 0xa880, 0xd0fc, 0x11b8, 0x8a50, 0x8c61,
+	0x2c05, 0x9005, 0x1190, 0x2800, 0x9906, 0x0120, 0xa000, 0x9005,
+	0x1108, 0x2900, 0x2040, 0xa85a, 0xa064, 0x9084, 0x000f, 0x9080,
+	0x20f8, 0x2065, 0x8cff, 0x090c, 0x0dc5, 0x0005, 0x0000, 0x001d,
+	0x0021, 0x0025, 0x0029, 0x002d, 0x0031, 0x0035, 0x0000, 0x001b,
+	0x0021, 0x0027, 0x002d, 0x0033, 0x0000, 0x0000, 0x0023, 0x0000,
+	0x0000, 0x20db, 0x20d7, 0x20db, 0x20db, 0x20e5, 0x0000, 0x20db,
+	0x20e2, 0x20e2, 0x20df, 0x20e2, 0x20e2, 0x0000, 0x20e5, 0x20e2,
+	0x0000, 0x20dd, 0x20dd, 0x0000, 0x20dd, 0x20e5, 0x0000, 0x20dd,
+	0x20e3, 0x20e3, 0x20e3, 0x0000, 0x20e3, 0x0000, 0x20e5, 0x20e3,
+	0x00c6, 0x00d6, 0x0086, 0xab42, 0xac3e, 0xa888, 0x9055, 0x0904,
+	0x22e7, 0x2940, 0xa064, 0x90ec, 0x000f, 0x9084, 0x00ff, 0x9086,
+	0x0008, 0x1118, 0x2061, 0x20e3, 0x00d0, 0x9de0, 0x20e8, 0x9d86,
+	0x0007, 0x0130, 0x9d86, 0x000e, 0x0118, 0x9d86, 0x000f, 0x1120,
+	0xa08c, 0x9422, 0xa090, 0x931b, 0x2c05, 0x9065, 0x1140, 0x0310,
+	0x0804, 0x22e7, 0xa004, 0x9045, 0x0904, 0x22e7, 0x08d8, 0x2c05,
+	0x9005, 0x0904, 0x21cf, 0xdd9c, 0x1904, 0x218b, 0x908a, 0x0036,
+	0x1a0c, 0x0dc5, 0x9082, 0x001b, 0x0002, 0x2160, 0x2160, 0x2162,
+	0x2160, 0x2160, 0x2160, 0x2168, 0x2160, 0x2160, 0x2160, 0x216e,
+	0x2160, 0x2160, 0x2160, 0x2174, 0x2160, 0x2160, 0x2160, 0x217a,
+	0x2160, 0x2160, 0x2160, 0x2180, 0x2160, 0x2160, 0x2160, 0x2186,
+	0x080c, 0x0dc5, 0xa07c, 0x9422, 0xa080, 0x931b, 0x0804, 0x21c5,
+	0xa08c, 0x9422, 0xa090, 0x931b, 0x0804, 0x21c5, 0xa09c, 0x9422,
+	0xa0a0, 0x931b, 0x0804, 0x21c5, 0xa0ac, 0x9422, 0xa0b0, 0x931b,
+	0x0804, 0x21c5, 0xa0bc, 0x9422, 0xa0c0, 0x931b, 0x0804, 0x21c5,
+	0xa0cc, 0x9422, 0xa0d0, 0x931b, 0x0804, 0x21c5, 0xa0dc, 0x9422,
+	0xa0e0, 0x931b, 0x04d0, 0x908a, 0x0034, 0x1a0c, 0x0dc5, 0x9082,
+	0x001b, 0x0002, 0x21ad, 0x21ab, 0x21ab, 0x21ab, 0x21ab, 0x21ab,
+	0x21b2, 0x21ab, 0x21ab, 0x21ab, 0x21ab, 0x21ab, 0x21b7, 0x21ab,
+	0x21ab, 0x21ab, 0x21ab, 0x21ab, 0x21bc, 0x21ab, 0x21ab, 0x21ab,
+	0x21ab, 0x21ab, 0x21c1, 0x080c, 0x0dc5, 0xa07c, 0x9422, 0xa080,
+	0x931b, 0x0098, 0xa094, 0x9422, 0xa098, 0x931b, 0x0070, 0xa0ac,
+	0x9422, 0xa0b0, 0x931b, 0x0048, 0xa0c4, 0x9422, 0xa0c8, 0x931b,
+	0x0020, 0xa0dc, 0x9422, 0xa0e0, 0x931b, 0x0630, 0x2300, 0x9405,
+	0x0160, 0x8a51, 0x0904, 0x22e7, 0x8c60, 0x0804, 0x2137, 0xa004,
+	0x9045, 0x0904, 0x22e7, 0x0804, 0x2112, 0x8a51, 0x0904, 0x22e7,
+	0x8c60, 0x2c05, 0x9005, 0x1158, 0xa004, 0x9045, 0x0904, 0x22e7,
+	0xa064, 0x90ec, 0x000f, 0x9de0, 0x20e8, 0x2c05, 0x2060, 0xa880,
+	0xc0fc, 0xa882, 0x0804, 0x22dc, 0x2c05, 0x8422, 0x8420, 0x831a,
+	0x9399, 0x0000, 0xac2e, 0xab32, 0xdd9c, 0x1904, 0x2279, 0x9082,
+	0x001b, 0x0002, 0x2215, 0x2215, 0x2217, 0x2215, 0x2215, 0x2215,
+	0x2225, 0x2215, 0x2215, 0x2215, 0x2233, 0x2215, 0x2215, 0x2215,
+	0x2241, 0x2215, 0x2215, 0x2215, 0x224f, 0x2215, 0x2215, 0x2215,
+	0x225d, 0x2215, 0x2215, 0x2215, 0x226b, 0x080c, 0x0dc5, 0xa17c,
+	0x2400, 0x9122, 0xa180, 0x2300, 0x911b, 0x0a0c, 0x0dc5, 0xa074,
+	0x9420, 0xa078, 0x9319, 0x0804, 0x22d7, 0xa18c, 0x2400, 0x9122,
+	0xa190, 0x2300, 0x911b, 0x0a0c, 0x0dc5, 0xa084, 0x9420, 0xa088,
+	0x9319, 0x0804, 0x22d7, 0xa19c, 0x2400, 0x9122, 0xa1a0, 0x2300,
+	0x911b, 0x0a0c, 0x0dc5, 0xa094, 0x9420, 0xa098, 0x9319, 0x0804,
+	0x22d7, 0xa1ac, 0x2400, 0x9122, 0xa1b0, 0x2300, 0x911b, 0x0a0c,
+	0x0dc5, 0xa0a4, 0x9420, 0xa0a8, 0x9319, 0x0804, 0x22d7, 0xa1bc,
+	0x2400, 0x9122, 0xa1c0, 0x2300, 0x911b, 0x0a0c, 0x0dc5, 0xa0b4,
+	0x9420, 0xa0b8, 0x9319, 0x0804, 0x22d7, 0xa1cc, 0x2400, 0x9122,
+	0xa1d0, 0x2300, 0x911b, 0x0a0c, 0x0dc5, 0xa0c4, 0x9420, 0xa0c8,
+	0x9319, 0x0804, 0x22d7, 0xa1dc, 0x2400, 0x9122, 0xa1e0, 0x2300,
+	0x911b, 0x0a0c, 0x0dc5, 0xa0d4, 0x9420, 0xa0d8, 0x9319, 0x0804,
+	0x22d7, 0x9082, 0x001b, 0x0002, 0x2297, 0x2295, 0x2295, 0x2295,
+	0x2295, 0x2295, 0x22a4, 0x2295, 0x2295, 0x2295, 0x2295, 0x2295,
+	0x22b1, 0x2295, 0x2295, 0x2295, 0x2295, 0x2295, 0x22be, 0x2295,
+	0x2295, 0x2295, 0x2295, 0x2295, 0x22cb, 0x080c, 0x0dc5, 0xa17c,
+	0x2400, 0x9122, 0xa180, 0x2300, 0x911b, 0x0a0c, 0x0dc5, 0xa06c,
+	0x9420, 0xa070, 0x9319, 0x0498, 0xa194, 0x2400, 0x9122, 0xa198,
+	0x2300, 0x911b, 0x0a0c, 0x0dc5, 0xa084, 0x9420, 0xa088, 0x9319,
+	0x0430, 0xa1ac, 0x2400, 0x9122, 0xa1b0, 0x2300, 0x911b, 0x0a0c,
+	0x0dc5, 0xa09c, 0x9420, 0xa0a0, 0x9319, 0x00c8, 0xa1c4, 0x2400,
+	0x9122, 0xa1c8, 0x2300, 0x911b, 0x0a0c, 0x0dc5, 0xa0b4, 0x9420,
+	0xa0b8, 0x9319, 0x0060, 0xa1dc, 0x2400, 0x9122, 0xa1e0, 0x2300,
+	0x911b, 0x0a0c, 0x0dc5, 0xa0cc, 0x9420, 0xa0d0, 0x9319, 0xac1e,
+	0xab22, 0xa880, 0xc0fd, 0xa882, 0x2800, 0xa85a, 0x2c00, 0xa812,
+	0x2a00, 0xa816, 0x000e, 0x000e, 0x000e, 0x9006, 0x0028, 0x008e,
+	0x00de, 0x00ce, 0x9085, 0x0001, 0x0005, 0x2001, 0x0005, 0x2004,
+	0xd0bc, 0x190c, 0x0dbe, 0x9084, 0x0007, 0x0002, 0x2308, 0x1f0c,
+	0x2308, 0x22fe, 0x2301, 0x2304, 0x2301, 0x2304, 0x080c, 0x1f0c,
+	0x0005, 0x080c, 0x11b2, 0x0005, 0x080c, 0x1f0c, 0x080c, 0x11b2,
+	0x0005, 0x0126, 0x2091, 0x2600, 0x2079, 0x0200, 0x2071, 0x0260,
+	0x2069, 0x1800, 0x7817, 0x0000, 0x789b, 0x0814, 0x78a3, 0x0406,
+	0x789f, 0x0410, 0x2009, 0x013b, 0x200b, 0x0400, 0x781b, 0x0002,
+	0x783b, 0x001f, 0x7837, 0x0020, 0x7803, 0x1600, 0x012e, 0x0005,
+	0x2091, 0x2600, 0x781c, 0xd0a4, 0x190c, 0x2427, 0x7900, 0xd1dc,
+	0x1118, 0x9084, 0x0006, 0x001a, 0x9084, 0x000e, 0x0002, 0x234f,
+	0x2347, 0x7f47, 0x2347, 0x2349, 0x2349, 0x2349, 0x2349, 0x7f2d,
+	0x2347, 0x234b, 0x2347, 0x2349, 0x2347, 0x2349, 0x2347, 0x080c,
+	0x0dc5, 0x0031, 0x0020, 0x080c, 0x7f2d, 0x080c, 0x7f47, 0x0005,
+	0x0006, 0x0016, 0x0026, 0x080c, 0xedb6, 0x7930, 0x9184, 0x0003,
+	0x01c0, 0x2001, 0x19f8, 0x2004, 0x9005, 0x0170, 0x2001, 0x0133,
+	0x2004, 0x9005, 0x090c, 0x0dc5, 0x00c6, 0x2001, 0x19f8, 0x2064,
+	0x080c, 0xca5e, 0x00ce, 0x00f8, 0x2009, 0x0040, 0x080c, 0x242a,
+	0x00d0, 0x9184, 0x0014, 0x01a0, 0x6a00, 0x9286, 0x0003, 0x0160,
+	0x080c, 0x7563, 0x1138, 0x080c, 0x7848, 0x080c, 0x6121, 0x080c,
+	0x748f, 0x0010, 0x080c, 0x5fe0, 0x080c, 0x7ff6, 0x0041, 0x0018,
+	0x9184, 0x9540, 0x1dc8, 0x002e, 0x001e, 0x000e, 0x0005, 0x00e6,
+	0x0036, 0x0046, 0x0056, 0x2071, 0x1a66, 0x080c, 0x1b02, 0x005e,
+	0x004e, 0x003e, 0x00ee, 0x0005, 0x0126, 0x2091, 0x2e00, 0x2071,
+	0x1800, 0x7128, 0x2001, 0x1970, 0x2102, 0x2001, 0x1978, 0x2102,
+	0x2001, 0x013b, 0x2102, 0x2079, 0x0200, 0x2001, 0x0201, 0x789e,
+	0x78a3, 0x0200, 0x9198, 0x0007, 0x831c, 0x831c, 0x831c, 0x9398,
+	0x0005, 0x2320, 0x9182, 0x0204, 0x1230, 0x2011, 0x0008, 0x8423,
+	0x8423, 0x8423, 0x0488, 0x9182, 0x024c, 0x1240, 0x2011, 0x0007,
+	0x8403, 0x8003, 0x9400, 0x9400, 0x9420, 0x0430, 0x9182, 0x02bc,
+	0x1238, 0x2011, 0x0006, 0x8403, 0x8003, 0x9400, 0x9420, 0x00e0,
+	0x9182, 0x034c, 0x1230, 0x2011, 0x0005, 0x8403, 0x8003, 0x9420,
+	0x0098, 0x9182, 0x042c, 0x1228, 0x2011, 0x0004, 0x8423, 0x8423,
+	0x0058, 0x9182, 0x059c, 0x1228, 0x2011, 0x0003, 0x8403, 0x9420,
+	0x0018, 0x2011, 0x0002, 0x8423, 0x9482, 0x0228, 0x8002, 0x8020,
+	0x8301, 0x9402, 0x0110, 0x0208, 0x8321, 0x8217, 0x8203, 0x9405,
+	0x789a, 0x012e, 0x0005, 0x0006, 0x00d6, 0x2069, 0x0200, 0x6814,
+	0x9084, 0xffc0, 0x910d, 0x6916, 0x00de, 0x000e, 0x0005, 0x00d6,
+	0x2069, 0x0200, 0x9005, 0x6810, 0x0110, 0xc0a5, 0x0008, 0xc0a4,
+	0x6812, 0x00de, 0x0005, 0x0006, 0x00d6, 0x2069, 0x0200, 0x6810,
+	0x9084, 0xfff8, 0x910d, 0x6912, 0x00de, 0x000e, 0x0005, 0x7938,
+	0x080c, 0x0dbe, 0x00f6, 0x2079, 0x0200, 0x7902, 0xa001, 0xa001,
+	0xa001, 0xa001, 0xa001, 0xa001, 0x7902, 0xa001, 0xa001, 0xa001,
+	0xa001, 0xa001, 0xa001, 0x00fe, 0x0005, 0x0126, 0x2091, 0x2800,
+	0x2061, 0x0100, 0x2071, 0x1800, 0x2009, 0x0000, 0x080c, 0x2c89,
+	0x080c, 0x2ba4, 0x6054, 0x8004, 0x8004, 0x8004, 0x8004, 0x9084,
+	0x000c, 0x6150, 0x918c, 0xfff3, 0x9105, 0x6052, 0x6050, 0x9084,
+	0xb17f, 0x9085, 0x2000, 0x6052, 0x2009, 0x199e, 0x2011, 0x199f,
+	0x6358, 0x939c, 0x38f0, 0x2320, 0x080c, 0x2be8, 0x1238, 0x939d,
+	0x4003, 0x94a5, 0x8603, 0x230a, 0x2412, 0x0030, 0x939d, 0x0203,
+	0x94a5, 0x8603, 0x230a, 0x2412, 0x9006, 0x080c, 0x2bd3, 0x9006,
+	0x080c, 0x2bb6, 0x20a9, 0x0012, 0x1d04, 0x247c, 0x2091, 0x6000,
+	0x1f04, 0x247c, 0x602f, 0x0100, 0x602f, 0x0000, 0x6050, 0x9085,
+	0x0400, 0x9084, 0xdfff, 0x6052, 0x6024, 0x6026, 0x080c, 0x28c2,
+	0x2009, 0x00ef, 0x6132, 0x6136, 0x080c, 0x28d2, 0x60e7, 0x0000,
+	0x61ea, 0x60e3, 0x0008, 0x604b, 0xf7f7, 0x6043, 0x0000, 0x602f,
+	0x0080, 0x602f, 0x0000, 0x6007, 0x349f, 0x60bb, 0x0000, 0x20a9,
+	0x0018, 0x60bf, 0x0000, 0x1f04, 0x24a9, 0x60bb, 0x0000, 0x60bf,
+	0x0108, 0x60bf, 0x0012, 0x60bf, 0x0405, 0x60bf, 0x0014, 0x60bf,
+	0x0320, 0x60bf, 0x0018, 0x601b, 0x00f0, 0x601f, 0x001e, 0x600f,
+	0x006b, 0x602b, 0x402f, 0x012e, 0x0005, 0x00f6, 0x2079, 0x0140,
+	0x78c3, 0x0080, 0x78c3, 0x0083, 0x78c3, 0x0000, 0x00fe, 0x0005,
+	0x2001, 0x1835, 0x2003, 0x0000, 0x2001, 0x1834, 0x2003, 0x0001,
+	0x0005, 0x0126, 0x2091, 0x2800, 0x0006, 0x0016, 0x0026, 0x6124,
+	0x0066, 0x2031, 0x1837, 0x2634, 0x96b4, 0x0028, 0x006e, 0x1138,
+	0x6020, 0xd1bc, 0x0120, 0xd0bc, 0x1168, 0xd0b4, 0x1198, 0x9184,
+	0x5e2c, 0x1118, 0x9184, 0x0007, 0x00aa, 0x9195, 0x0004, 0x9284,
+	0x0007, 0x0082, 0x0016, 0x2001, 0x188b, 0x200c, 0xd184, 0x001e,
+	0x0d70, 0x0c98, 0x0016, 0x2001, 0x188b, 0x200c, 0xd194, 0x001e,
+	0x0d30, 0x0c58, 0x252c, 0x2512, 0x2515, 0x2518, 0x251d, 0x251f,
+	0x2523, 0x2527, 0x080c, 0x9218, 0x00b8, 0x080c, 0x92e7, 0x00a0,
+	0x080c, 0x92e7, 0x080c, 0x9218, 0x0078, 0x0099, 0x0068, 0x080c,
+	0x9218, 0x0079, 0x0048, 0x080c, 0x92e7, 0x0059, 0x0028, 0x080c,
+	0x92e7, 0x080c, 0x9218, 0x0029, 0x002e, 0x001e, 0x000e, 0x012e,
+	0x0005, 0x00a6, 0x6124, 0x6028, 0xd09c, 0x0118, 0xd19c, 0x1904,
+	0x279a, 0xd1f4, 0x190c, 0x0dbe, 0x080c, 0x7563, 0x0904, 0x2587,
+	0x080c, 0xd548, 0x1120, 0x7000, 0x9086, 0x0003, 0x0570, 0x6024,
+	0x9084, 0x1800, 0x0550, 0x080c, 0x7586, 0x0118, 0x080c, 0x7574,
+	0x1520, 0x6027, 0x0020, 0x6043, 0x0000, 0x080c, 0xd548, 0x0168,
+	0x080c, 0x7586, 0x1150, 0x2001, 0x19a8, 0x2003, 0x0001, 0x6027,
+	0x1800, 0x080c, 0x73de, 0x0804, 0x279d, 0x70a4, 0x9005, 0x1150,
+	0x70a7, 0x0001, 0x00d6, 0x2069, 0x0140, 0x080c, 0x75b7, 0x00de,
+	0x1904, 0x279d, 0x080c, 0x7852, 0x0428, 0x080c, 0x7586, 0x1590,
+	0x6024, 0x9084, 0x1800, 0x1108, 0x0468, 0x080c, 0x7852, 0x080c,
+	0x7848, 0x080c, 0x6121, 0x080c, 0x748f, 0x0804, 0x279a, 0xd1ac,
+	0x1508, 0x6024, 0xd0dc, 0x1170, 0xd0e4, 0x1178, 0xd0d4, 0x1190,
+	0xd0cc, 0x0130, 0x7098, 0x9086, 0x0029, 0x1110, 0x080c, 0x7735,
+	0x0804, 0x279a, 0x080c, 0x784d, 0x0048, 0x2001, 0x197e, 0x2003,
+	0x0002, 0x0020, 0x080c, 0x7698, 0x0804, 0x279a, 0x080c, 0x77d0,
+	0x0804, 0x279a, 0x6220, 0xd1bc, 0x0138, 0xd2bc, 0x1904, 0x27f7,
+	0xd2b4, 0x1904, 0x280a, 0x0000, 0xd1ac, 0x0904, 0x26af, 0x0036,
+	0x6328, 0xc3bc, 0x632a, 0x003e, 0x080c, 0x7563, 0x11c0, 0x6027,
+	0x0020, 0x0006, 0x0026, 0x0036, 0x080c, 0x757d, 0x1158, 0x080c,
+	0x7848, 0x080c, 0x6121, 0x080c, 0x748f, 0x003e, 0x002e, 0x000e,
+	0x00ae, 0x0005, 0x003e, 0x002e, 0x000e, 0x080c, 0x753b, 0x0016,
+	0x0046, 0x00c6, 0x644c, 0x9486, 0xf0f0, 0x1138, 0x2061, 0x0100,
+	0x644a, 0x6043, 0x0090, 0x6043, 0x0010, 0x74da, 0x948c, 0xff00,
+	0x7038, 0xd084, 0x0178, 0x9186, 0xf800, 0x1160, 0x7048, 0xd084,
+	0x1148, 0xc085, 0x704a, 0x0036, 0x2418, 0x2011, 0x8016, 0x080c,
+	0x4be3, 0x003e, 0x080c, 0xd541, 0x1904, 0x268c, 0x9196, 0xff00,
+	0x05a8, 0x7060, 0x9084, 0x00ff, 0x810f, 0x81ff, 0x0110, 0x9116,
+	0x0568, 0x7130, 0xd184, 0x1550, 0x080c, 0x33a5, 0x0128, 0xc18d,
+	0x7132, 0x080c, 0x6a84, 0x1510, 0x6240, 0x9294, 0x0010, 0x0130,
+	0x6248, 0x9294, 0xff00, 0x9296, 0xff00, 0x01c0, 0x7030, 0xd08c,
+	0x0904, 0x268c, 0x7038, 0xd08c, 0x1140, 0x2001, 0x180c, 0x200c,
+	0xd1ac, 0x1904, 0x268c, 0xc1ad, 0x2102, 0x0036, 0x73d8, 0x2011,
+	0x8013, 0x080c, 0x4be3, 0x003e, 0x0804, 0x268c, 0x7038, 0xd08c,
+	0x1140, 0x2001, 0x180c, 0x200c, 0xd1ac, 0x1904, 0x268c, 0xc1ad,
+	0x2102, 0x0036, 0x73d8, 0x2011, 0x8013, 0x080c, 0x4be3, 0x003e,
+	0x7130, 0xc185, 0x7132, 0x2011, 0x1848, 0x220c, 0xd1a4, 0x01f0,
+	0x0016, 0x2009, 0x0001, 0x2011, 0x0100, 0x080c, 0x8916, 0x2019,
+	0x000e, 0x00c6, 0x2061, 0x0000, 0x080c, 0xe8b0, 0x00ce, 0x9484,
+	0x00ff, 0x9080, 0x33b1, 0x200d, 0x918c, 0xff00, 0x810f, 0x2120,
+	0x9006, 0x2009, 0x000e, 0x080c, 0xe940, 0x001e, 0x0016, 0x2009,
+	0x0002, 0x2019, 0x0004, 0x080c, 0x3216, 0x001e, 0x00a8, 0x0156,
+	0x00b6, 0x20a9, 0x007f, 0x900e, 0x080c, 0x6717, 0x1140, 0x7030,
+	0xd084, 0x1118, 0xb800, 0xd0bc, 0x1110, 0x080c, 0x613b, 0x8108,
+	0x1f04, 0x267c, 0x00be, 0x015e, 0x00ce, 0x004e, 0x080c, 0xb058,
 	0x60e3, 0x0000, 0x001e, 0x2001, 0x1800, 0x2014, 0x9296, 0x0004,
 	0x1170, 0xd19c, 0x11a0, 0x2011, 0x180c, 0x2214, 0xd29c, 0x1120,
 	0x6204, 0x9295, 0x0002, 0x6206, 0x6228, 0xc29d, 0x622a, 0x2003,
 	0x0001, 0x2001, 0x1826, 0x2003, 0x0000, 0x6027, 0x0020, 0xd194,
-	0x0904, 0x277a, 0x0016, 0x6220, 0xd2b4, 0x0904, 0x2717, 0x080c,
-	0x8636, 0x080c, 0xa356, 0x6027, 0x0004, 0x00f6, 0x2019, 0x19ef,
-	0x2304, 0x907d, 0x0904, 0x26e6, 0x7804, 0x9086, 0x0032, 0x15f0,
+	0x0904, 0x279a, 0x0016, 0x6220, 0xd2b4, 0x0904, 0x2737, 0x080c,
+	0x8789, 0x080c, 0xa4fd, 0x6027, 0x0004, 0x00f6, 0x2019, 0x19f2,
+	0x2304, 0x907d, 0x0904, 0x2706, 0x7804, 0x9086, 0x0032, 0x15f0,
 	0x00d6, 0x00c6, 0x00e6, 0x0096, 0x2069, 0x0140, 0x782c, 0x685e,
 	0x7808, 0x685a, 0x6043, 0x0002, 0x2001, 0x0003, 0x8001, 0x1df0,
-	0x6043, 0x0000, 0x2001, 0x003c, 0x8001, 0x1df0, 0x080c, 0x2d5e,
-	0x2001, 0x001e, 0x8001, 0x0240, 0x20a9, 0x0009, 0x080c, 0x2c57,
-	0x6904, 0xd1dc, 0x1140, 0x0cb0, 0x2001, 0x0100, 0x080c, 0x2d4e,
-	0x9006, 0x080c, 0x2d4e, 0x080c, 0x9657, 0x080c, 0x9763, 0x7814,
-	0x2048, 0xa867, 0x0103, 0x2f60, 0x080c, 0xaf43, 0x009e, 0x00ee,
+	0x6043, 0x0000, 0x2001, 0x003c, 0x8001, 0x1df0, 0x080c, 0x2d6b,
+	0x2001, 0x001e, 0x8001, 0x0240, 0x20a9, 0x0009, 0x080c, 0x2c64,
+	0x6904, 0xd1dc, 0x1140, 0x0cb0, 0x2001, 0x0100, 0x080c, 0x2d5b,
+	0x9006, 0x080c, 0x2d5b, 0x080c, 0x97db, 0x080c, 0x98e7, 0x7814,
+	0x2048, 0xa867, 0x0103, 0x2f60, 0x080c, 0xb0e7, 0x009e, 0x00ee,
 	0x00ce, 0x00de, 0x00fe, 0x001e, 0x00ae, 0x0005, 0x00fe, 0x00d6,
-	0x2069, 0x0140, 0x6804, 0x9084, 0x4000, 0x0110, 0x080c, 0x2d5e,
-	0x00de, 0x00c6, 0x2061, 0x19e6, 0x6028, 0x080c, 0xd388, 0x0120,
+	0x2069, 0x0140, 0x6804, 0x9084, 0x4000, 0x0110, 0x080c, 0x2d6b,
+	0x00de, 0x00c6, 0x2061, 0x19e9, 0x6028, 0x080c, 0xd548, 0x0120,
 	0x909a, 0x0003, 0x1258, 0x0018, 0x909a, 0x00c8, 0x1238, 0x8000,
-	0x602a, 0x00ce, 0x080c, 0xa332, 0x0804, 0x2779, 0x2061, 0x0100,
-	0x62c0, 0x080c, 0xad3a, 0x2019, 0x19ef, 0x2304, 0x9065, 0x0120,
-	0x2009, 0x0027, 0x080c, 0xafbe, 0x00ce, 0x0804, 0x2779, 0xd2bc,
-	0x0904, 0x2760, 0x080c, 0x8643, 0x6014, 0x9084, 0x1984, 0x9085,
+	0x602a, 0x00ce, 0x080c, 0xa4d9, 0x0804, 0x2799, 0x2061, 0x0100,
+	0x62c0, 0x080c, 0xaede, 0x2019, 0x19f2, 0x2304, 0x9065, 0x0120,
+	0x2009, 0x0027, 0x080c, 0xb166, 0x00ce, 0x0804, 0x2799, 0xd2bc,
+	0x0904, 0x2780, 0x080c, 0x8796, 0x6014, 0x9084, 0x1984, 0x9085,
 	0x0010, 0x6016, 0x6027, 0x0004, 0x00d6, 0x2069, 0x0140, 0x6804,
-	0x9084, 0x4000, 0x0110, 0x080c, 0x2d5e, 0x00de, 0x00c6, 0x2061,
-	0x19e6, 0x6044, 0x080c, 0xd388, 0x0120, 0x909a, 0x0003, 0x1658,
+	0x9084, 0x4000, 0x0110, 0x080c, 0x2d6b, 0x00de, 0x00c6, 0x2061,
+	0x19e9, 0x6044, 0x080c, 0xd548, 0x0120, 0x909a, 0x0003, 0x1658,
 	0x0018, 0x909a, 0x00c8, 0x1638, 0x8000, 0x6046, 0x603c, 0x00ce,
-	0x9005, 0x05b8, 0x2009, 0x07d0, 0x080c, 0x863b, 0x9080, 0x0008,
+	0x9005, 0x05b8, 0x2009, 0x07d0, 0x080c, 0x878e, 0x9080, 0x0008,
 	0x2004, 0x9086, 0x0006, 0x1138, 0x6114, 0x918c, 0x1984, 0x918d,
 	0x0012, 0x6116, 0x0430, 0x9080, 0x0008, 0x2004, 0x9086, 0x0009,
 	0x0d98, 0x6114, 0x918c, 0x1984, 0x918d, 0x0016, 0x6116, 0x00c8,
-	0x6027, 0x0004, 0x00b0, 0x0036, 0x2019, 0x0001, 0x080c, 0xa6ac,
-	0x003e, 0x2019, 0x19f5, 0x2304, 0x9065, 0x0150, 0x2009, 0x004f,
-	0x6020, 0x9086, 0x0009, 0x1110, 0x2009, 0x004f, 0x080c, 0xafbe,
-	0x00ce, 0x001e, 0xd19c, 0x0904, 0x27e8, 0x7038, 0xd0ac, 0x1904,
-	0x27c1, 0x0016, 0x0156, 0x6027, 0x0008, 0x6050, 0x9085, 0x0040,
-	0x6052, 0x6050, 0x9084, 0xfbcf, 0x6052, 0x080c, 0x2c76, 0x9085,
-	0x2000, 0x6052, 0x20a9, 0x0012, 0x1d04, 0x2794, 0x080c, 0x866a,
-	0x1f04, 0x2794, 0x6050, 0x9085, 0x0400, 0x9084, 0xdfbf, 0x6052,
-	0x20a9, 0x0028, 0xa001, 0x1f04, 0x27a2, 0x6150, 0x9185, 0x1400,
-	0x6052, 0x20a9, 0x0366, 0x1d04, 0x27ab, 0x080c, 0x866a, 0x6020,
-	0xd09c, 0x1130, 0x015e, 0x6152, 0x001e, 0x6027, 0x0008, 0x0480,
-	0x080c, 0x2c3e, 0x1f04, 0x27ab, 0x015e, 0x6152, 0x001e, 0x6027,
-	0x0008, 0x0016, 0x6028, 0xc09c, 0x602a, 0x080c, 0xaeb4, 0x60e3,
-	0x0000, 0x080c, 0xeb79, 0x080c, 0xeb94, 0x080c, 0x5761, 0xd0fc,
-	0x1138, 0x080c, 0xd381, 0x1120, 0x9085, 0x0001, 0x080c, 0x7485,
-	0x9006, 0x080c, 0x2d4e, 0x2009, 0x0002, 0x080c, 0x2c7c, 0x2001,
-	0x1800, 0x2003, 0x0004, 0x6027, 0x0008, 0x080c, 0x0bae, 0x001e,
-	0x918c, 0xffd0, 0x6126, 0x00ae, 0x0005, 0x0016, 0x2001, 0x188b,
-	0x200c, 0xd184, 0x001e, 0x0904, 0x259a, 0x0016, 0x2009, 0x27f9,
-	0x00d0, 0x2001, 0x188b, 0x200c, 0xc184, 0x2102, 0x001e, 0x0c40,
-	0x0016, 0x2001, 0x188b, 0x200c, 0xd194, 0x001e, 0x0904, 0x259a,
-	0x0016, 0x2009, 0x280c, 0x0038, 0x2001, 0x188b, 0x200c, 0xc194,
-	0x2102, 0x001e, 0x08a8, 0x6028, 0xc0bc, 0x602a, 0x2001, 0x0156,
-	0x2003, 0xbc91, 0x8000, 0x2003, 0xffff, 0x6043, 0x0001, 0x080c,
-	0x2c76, 0x6027, 0x0080, 0x6017, 0x0000, 0x6043, 0x0000, 0x0817,
-	0x0006, 0x0016, 0x0026, 0x0036, 0x00e6, 0x00f6, 0x0126, 0x2091,
-	0x8000, 0x2071, 0x1800, 0x71d0, 0x70d2, 0x9116, 0x05e8, 0x81ff,
-	0x01a0, 0x2009, 0x0000, 0x080c, 0x2c7c, 0x2011, 0x8011, 0x2019,
-	0x010e, 0x231c, 0x939e, 0x0007, 0x1118, 0x2019, 0x0001, 0x0010,
-	0x2019, 0x0000, 0x080c, 0x4b7f, 0x0438, 0x2001, 0x19a7, 0x200c,
-	0x81ff, 0x1140, 0x2001, 0x0109, 0x2004, 0xd0b4, 0x0118, 0x2019,
-	0x0003, 0x0008, 0x2118, 0x2011, 0x8012, 0x080c, 0x4b7f, 0x080c,
-	0x5761, 0xd0fc, 0x1188, 0x080c, 0xd381, 0x1170, 0x00c6, 0x080c,
-	0x2910, 0x080c, 0xa613, 0x2061, 0x0100, 0x2019, 0x0028, 0x2009,
-	0x0002, 0x080c, 0x31e9, 0x00ce, 0x012e, 0x00fe, 0x00ee, 0x003e,
-	0x002e, 0x001e, 0x000e, 0x0005, 0x2028, 0x918c, 0x00ff, 0x2130,
-	0x9094, 0xff00, 0x11f0, 0x2011, 0x1837, 0x2214, 0xd2ac, 0x11c8,
-	0x81ff, 0x01e8, 0x2011, 0x181f, 0x2204, 0x9106, 0x1190, 0x2011,
-	0x1820, 0x2214, 0x9294, 0xff00, 0x9584, 0xff00, 0x9206, 0x1148,
-	0x2011, 0x1820, 0x2214, 0x9294, 0x00ff, 0x9584, 0x00ff, 0x9206,
-	0x1120, 0x2500, 0x080c, 0x8142, 0x0048, 0x9584, 0x00ff, 0x9080,
-	0x3384, 0x200d, 0x918c, 0xff00, 0x810f, 0x9006, 0x0005, 0x9080,
-	0x3384, 0x200d, 0x918c, 0x00ff, 0x0005, 0x00d6, 0x2069, 0x0140,
-	0x2001, 0x1818, 0x2003, 0x00ef, 0x20a9, 0x0010, 0x9006, 0x6852,
-	0x6856, 0x1f04, 0x28c0, 0x00de, 0x0005, 0x0006, 0x00d6, 0x0026,
-	0x2069, 0x0140, 0x2001, 0x1818, 0x2102, 0x8114, 0x8214, 0x8214,
-	0x8214, 0x20a9, 0x0010, 0x6853, 0x0000, 0x9006, 0x82ff, 0x1128,
-	0x9184, 0x000f, 0x9080, 0xf346, 0x2005, 0x6856, 0x8211, 0x1f04,
-	0x28d5, 0x002e, 0x00de, 0x000e, 0x0005, 0x00c6, 0x2061, 0x1800,
-	0x6030, 0x0110, 0xc09d, 0x0008, 0xc09c, 0x6032, 0x00ce, 0x0005,
-	0x0156, 0x00d6, 0x0026, 0x0016, 0x0006, 0x2069, 0x0140, 0x6980,
-	0x9116, 0x0180, 0x9112, 0x1230, 0x8212, 0x8210, 0x22a8, 0x2001,
-	0x0402, 0x0018, 0x22a8, 0x2001, 0x0404, 0x680e, 0x1f04, 0x2905,
-	0x680f, 0x0000, 0x000e, 0x001e, 0x002e, 0x00de, 0x015e, 0x0005,
-	0x080c, 0x575d, 0xd0c4, 0x0150, 0xd0a4, 0x0140, 0x9006, 0x0046,
-	0x2020, 0x2009, 0x002e, 0x080c, 0xe73a, 0x004e, 0x0005, 0x00f6,
-	0x0016, 0x0026, 0x2079, 0x0140, 0x78c4, 0xd0dc, 0x0904, 0x297c,
-	0x080c, 0x2bdb, 0x0660, 0x9084, 0x0700, 0x908e, 0x0600, 0x1120,
-	0x2011, 0x4000, 0x900e, 0x0458, 0x908e, 0x0500, 0x1120, 0x2011,
-	0x8000, 0x900e, 0x0420, 0x908e, 0x0400, 0x1120, 0x9016, 0x2009,
-	0x0001, 0x00e8, 0x908e, 0x0300, 0x1120, 0x9016, 0x2009, 0x0002,
-	0x00b0, 0x908e, 0x0200, 0x1120, 0x9016, 0x2009, 0x0004, 0x0078,
-	0x908e, 0x0100, 0x1548, 0x9016, 0x2009, 0x0008, 0x0040, 0x9084,
-	0x0700, 0x908e, 0x0300, 0x1500, 0x2011, 0x0030, 0x0058, 0x2300,
-	0x9080, 0x0020, 0x2018, 0x080c, 0x9027, 0x928c, 0xff00, 0x0110,
-	0x2011, 0x00ff, 0x2200, 0x8007, 0x9085, 0x004c, 0x78c2, 0x2009,
-	0x0138, 0x220a, 0x080c, 0x743e, 0x1118, 0x2009, 0x196c, 0x220a,
-	0x002e, 0x001e, 0x00fe, 0x0005, 0x78c3, 0x0000, 0x0cc8, 0x0126,
-	0x2091, 0x2800, 0x0006, 0x0016, 0x0026, 0x2001, 0x0170, 0x200c,
-	0x8000, 0x2014, 0x9184, 0x0003, 0x0110, 0x080c, 0x0dce, 0x002e,
-	0x001e, 0x000e, 0x012e, 0x0005, 0x2001, 0x0171, 0x2004, 0xd0dc,
-	0x0168, 0x2001, 0x0170, 0x200c, 0x918c, 0x00ff, 0x918e, 0x004c,
-	0x1128, 0x200c, 0x918c, 0xff00, 0x810f, 0x0005, 0x900e, 0x2001,
-	0x0227, 0x2004, 0x8007, 0x9084, 0x00ff, 0x8004, 0x9108, 0x2001,
-	0x0226, 0x2004, 0x8007, 0x9084, 0x00ff, 0x8004, 0x9108, 0x0005,
-	0x0018, 0x000c, 0x0018, 0x0020, 0x1000, 0x0800, 0x1000, 0x1800,
-	0x0156, 0x0006, 0x0016, 0x0026, 0x00e6, 0x2001, 0x198f, 0x2004,
-	0x908a, 0x0007, 0x1a0c, 0x0dd5, 0x0033, 0x00ee, 0x002e, 0x001e,
-	0x000e, 0x015e, 0x0005, 0x29da, 0x29f8, 0x2a1c, 0x2a1e, 0x2a47,
-	0x2a49, 0x2a4b, 0x2001, 0x0001, 0x080c, 0x2828, 0x080c, 0x2c39,
-	0x2001, 0x1991, 0x2003, 0x0000, 0x7828, 0x9084, 0xe1d7, 0x782a,
-	0x9006, 0x20a9, 0x0009, 0x080c, 0x2bf7, 0x2001, 0x198f, 0x2003,
-	0x0006, 0x2009, 0x001e, 0x2011, 0x2a4c, 0x080c, 0x8648, 0x0005,
-	0x2009, 0x1994, 0x200b, 0x0000, 0x2001, 0x1999, 0x2003, 0x0036,
-	0x2001, 0x1998, 0x2003, 0x002a, 0x2001, 0x1991, 0x2003, 0x0001,
-	0x9006, 0x080c, 0x2ba9, 0x2001, 0xffff, 0x20a9, 0x0009, 0x080c,
-	0x2bf7, 0x2001, 0x198f, 0x2003, 0x0006, 0x2009, 0x001e, 0x2011,
-	0x2a4c, 0x080c, 0x8648, 0x0005, 0x080c, 0x0dd5, 0x2001, 0x1999,
-	0x2003, 0x0036, 0x2001, 0x1991, 0x2003, 0x0003, 0x7a38, 0x9294,
-	0x0005, 0x9296, 0x0004, 0x0110, 0x9006, 0x0010, 0x2001, 0x0001,
-	0x080c, 0x2ba9, 0x2001, 0x1995, 0x2003, 0x0000, 0x2001, 0xffff,
-	0x20a9, 0x0009, 0x080c, 0x2bf7, 0x2001, 0x198f, 0x2003, 0x0006,
-	0x2009, 0x001e, 0x2011, 0x2a4c, 0x080c, 0x8648, 0x0005, 0x080c,
-	0x0dd5, 0x080c, 0x0dd5, 0x0005, 0x0006, 0x0016, 0x0026, 0x00e6,
-	0x00f6, 0x0156, 0x0126, 0x2091, 0x8000, 0x2079, 0x0100, 0x2001,
-	0x1991, 0x2004, 0x908a, 0x0007, 0x1a0c, 0x0dd5, 0x0043, 0x012e,
-	0x015e, 0x00fe, 0x00ee, 0x002e, 0x001e, 0x000e, 0x0005, 0x2a6e,
-	0x2a8e, 0x2ace, 0x2afe, 0x2b22, 0x2b32, 0x2b34, 0x080c, 0x2beb,
-	0x11b0, 0x7850, 0x9084, 0xefff, 0x7852, 0x2009, 0x1997, 0x2104,
-	0x7a38, 0x9294, 0x0005, 0x9296, 0x0004, 0x0110, 0xc08d, 0x0008,
-	0xc085, 0x200a, 0x2001, 0x198f, 0x2003, 0x0001, 0x0030, 0x080c,
-	0x2b58, 0x2001, 0xffff, 0x080c, 0x29e9, 0x0005, 0x080c, 0x2b36,
-	0x05e0, 0x2009, 0x1998, 0x2104, 0x8001, 0x200a, 0x080c, 0x2beb,
-	0x1178, 0x7850, 0x9084, 0xefff, 0x7852, 0x7a38, 0x9294, 0x0005,
-	0x9296, 0x0005, 0x0518, 0x2009, 0x1997, 0x2104, 0xc085, 0x200a,
-	0x2009, 0x1994, 0x2104, 0x8000, 0x200a, 0x9086, 0x0005, 0x0118,
-	0x080c, 0x2b3e, 0x00c0, 0x200b, 0x0000, 0x7a38, 0x9294, 0x0006,
-	0x9296, 0x0004, 0x0110, 0x9006, 0x0010, 0x2001, 0x0001, 0x080c,
-	0x2bc6, 0x2001, 0x1991, 0x2003, 0x0002, 0x0028, 0x2001, 0x198f,
-	0x2003, 0x0003, 0x0010, 0x080c, 0x2a0b, 0x0005, 0x080c, 0x2b36,
-	0x0560, 0x2009, 0x1998, 0x2104, 0x8001, 0x200a, 0x080c, 0x2beb,
-	0x1168, 0x7850, 0x9084, 0xefff, 0x7852, 0x2001, 0x198f, 0x2003,
-	0x0003, 0x2001, 0x1990, 0x2003, 0x0000, 0x00b8, 0x2009, 0x1998,
-	0x2104, 0x9005, 0x1118, 0x080c, 0x2b7b, 0x0010, 0x080c, 0x2b4b,
-	0x080c, 0x2b3e, 0x2009, 0x1994, 0x200b, 0x0000, 0x2001, 0x1991,
-	0x2003, 0x0001, 0x080c, 0x2a0b, 0x0000, 0x0005, 0x04b9, 0x0508,
-	0x080c, 0x2beb, 0x11b8, 0x7850, 0x9084, 0xefff, 0x7852, 0x2009,
-	0x1995, 0x2104, 0x8000, 0x200a, 0x9086, 0x0007, 0x0108, 0x0078,
-	0x2001, 0x199a, 0x2003, 0x000a, 0x2009, 0x1997, 0x2104, 0xc0fd,
-	0x200a, 0x0038, 0x0419, 0x2001, 0x1991, 0x2003, 0x0004, 0x080c,
-	0x2a36, 0x0005, 0x0099, 0x0168, 0x080c, 0x2beb, 0x1138, 0x7850,
-	0x9084, 0xefff, 0x7852, 0x080c, 0x2a22, 0x0018, 0x0079, 0x080c,
-	0x2a36, 0x0005, 0x080c, 0x0dd5, 0x080c, 0x0dd5, 0x2009, 0x1999,
-	0x2104, 0x8001, 0x200a, 0x090c, 0x2b97, 0x0005, 0x7a38, 0x9294,
-	0x0005, 0x9296, 0x0005, 0x0110, 0x9006, 0x0010, 0x2001, 0x0001,
-	0x080c, 0x2bc6, 0x0005, 0x7a38, 0x9294, 0x0006, 0x9296, 0x0006,
-	0x0110, 0x9006, 0x0010, 0x2001, 0x0001, 0x080c, 0x2ba9, 0x0005,
-	0x2009, 0x1994, 0x2104, 0x8000, 0x200a, 0x9086, 0x0005, 0x0108,
-	0x0068, 0x200b, 0x0000, 0x7a38, 0x9294, 0x0006, 0x9296, 0x0006,
-	0x0110, 0x9006, 0x0010, 0x2001, 0x0001, 0x04d9, 0x7a38, 0x9294,
-	0x0005, 0x9296, 0x0005, 0x0110, 0x9006, 0x0010, 0x2001, 0x0001,
-	0x080c, 0x2bc6, 0x0005, 0x0086, 0x2001, 0x1997, 0x2004, 0x9084,
-	0x7fff, 0x090c, 0x0dd5, 0x2009, 0x1996, 0x2144, 0x8846, 0x280a,
-	0x9844, 0x0dd8, 0xd08c, 0x1120, 0xd084, 0x1120, 0x080c, 0x0dd5,
-	0x9006, 0x0010, 0x2001, 0x0001, 0x00a1, 0x008e, 0x0005, 0x0006,
-	0x0156, 0x2001, 0x198f, 0x20a9, 0x0009, 0x2003, 0x0000, 0x8000,
-	0x1f04, 0x2b9d, 0x2001, 0x1996, 0x2003, 0x8000, 0x015e, 0x000e,
-	0x0005, 0x00f6, 0x2079, 0x0100, 0x9085, 0x0000, 0x0158, 0x7838,
-	0x9084, 0xfff9, 0x9085, 0x0004, 0x783a, 0x2009, 0x199c, 0x210c,
-	0x795a, 0x0050, 0x7838, 0x9084, 0xfffb, 0x9085, 0x0006, 0x783a,
-	0x2009, 0x199d, 0x210c, 0x795a, 0x00fe, 0x0005, 0x00f6, 0x2079,
-	0x0100, 0x9085, 0x0000, 0x0138, 0x7838, 0x9084, 0xfffa, 0x9085,
-	0x0004, 0x783a, 0x0030, 0x7838, 0x9084, 0xfffb, 0x9085, 0x0005,
-	0x783a, 0x00fe, 0x0005, 0x0006, 0x2001, 0x0100, 0x2004, 0x9082,
-	0x0007, 0x000e, 0x0005, 0x0006, 0x2001, 0x0100, 0x2004, 0x9082,
-	0x0009, 0x000e, 0x0005, 0x0156, 0x20a9, 0x0064, 0x7820, 0x080c,
-	0x2c76, 0xd09c, 0x1110, 0x1f04, 0x2bee, 0x015e, 0x0005, 0x0126,
-	0x0016, 0x0006, 0x2091, 0x8000, 0x7850, 0x9085, 0x0040, 0x7852,
-	0x7850, 0x9084, 0xfbcf, 0x7852, 0x080c, 0x2c76, 0x9085, 0x2000,
-	0x7852, 0x000e, 0x2008, 0x9186, 0x0000, 0x1118, 0x783b, 0x0007,
-	0x0090, 0x9186, 0x0001, 0x1118, 0x783b, 0x0006, 0x0060, 0x9186,
-	0x0002, 0x1118, 0x783b, 0x0005, 0x0030, 0x9186, 0x0003, 0x1118,
-	0x783b, 0x0004, 0x0000, 0x0006, 0x1d04, 0x2c24, 0x080c, 0x866a,
-	0x1f04, 0x2c24, 0x7850, 0x9085, 0x0400, 0x9084, 0xdfbf, 0x7852,
-	0x080c, 0x2c76, 0x9085, 0x1000, 0x7852, 0x000e, 0x001e, 0x012e,
-	0x0005, 0x7850, 0x9084, 0xffcf, 0x7852, 0x0005, 0x0006, 0x0156,
-	0x00f6, 0x2079, 0x0100, 0x20a9, 0x000a, 0x7854, 0xd0ac, 0x1130,
-	0x7820, 0xd0e4, 0x1140, 0x1f04, 0x2c48, 0x0028, 0x7854, 0xd08c,
-	0x1110, 0x1f04, 0x2c4e, 0x00fe, 0x015e, 0x000e, 0x0005, 0x1d04,
-	0x2c57, 0x080c, 0x866a, 0x1f04, 0x2c57, 0x0005, 0x0006, 0x2001,
-	0x199b, 0x2004, 0x9086, 0x0000, 0x000e, 0x0005, 0x0006, 0x2001,
-	0x199b, 0x2004, 0x9086, 0x0001, 0x000e, 0x0005, 0x0006, 0x2001,
-	0x199b, 0x2004, 0x9086, 0x0002, 0x000e, 0x0005, 0xa001, 0xa001,
-	0xa001, 0xa001, 0xa001, 0x0005, 0x0006, 0x2001, 0x19a7, 0x2102,
-	0x000e, 0x0005, 0x2009, 0x0171, 0x2104, 0xd0dc, 0x0140, 0x2009,
-	0x0170, 0x2104, 0x200b, 0x0080, 0xa001, 0xa001, 0x200a, 0x0005,
-	0x0036, 0x0046, 0x2001, 0x0141, 0x200c, 0x918c, 0xff00, 0x9186,
-	0x2100, 0x0140, 0x9186, 0x2000, 0x0170, 0x9186, 0x0100, 0x1904,
-	0x2cef, 0x0048, 0x0016, 0x2009, 0x1a82, 0x2104, 0x8000, 0x0208,
-	0x200a, 0x001e, 0x04f0, 0x2009, 0x00a2, 0x080c, 0x0e51, 0x2019,
-	0x0160, 0x2324, 0x2011, 0x0003, 0x2009, 0x0169, 0x2104, 0x9084,
-	0x0007, 0x210c, 0x918c, 0x0007, 0x910e, 0x1db0, 0x9086, 0x0003,
-	0x1548, 0x2304, 0x0066, 0x0076, 0x2031, 0x0002, 0x233c, 0x973e,
-	0x0148, 0x8631, 0x1dd8, 0x2031, 0x1a83, 0x263c, 0x8738, 0x0208,
-	0x2732, 0x2304, 0x007e, 0x006e, 0x9402, 0x02a0, 0x19d0, 0x8211,
-	0x19d8, 0x84ff, 0x0170, 0x2001, 0x0141, 0x200c, 0x918c, 0xff00,
-	0x9186, 0x0100, 0x0130, 0x2009, 0x180c, 0x2104, 0xc0dd, 0x200a,
-	0x0008, 0x0421, 0x2001, 0x1980, 0x200c, 0x080c, 0x0e51, 0x004e,
-	0x003e, 0x0005, 0x2001, 0x180c, 0x2004, 0xd0dc, 0x01b0, 0x2001,
-	0x0160, 0x2004, 0x9005, 0x0140, 0x2001, 0x0141, 0x2004, 0x9084,
-	0xff00, 0x9086, 0x0100, 0x1148, 0x0126, 0x2091, 0x8000, 0x0016,
-	0x0026, 0x0021, 0x002e, 0x001e, 0x012e, 0x0005, 0x00c6, 0x2061,
-	0x0100, 0x6014, 0x0006, 0x2001, 0x0161, 0x2003, 0x0000, 0x6017,
-	0x0018, 0xa001, 0xa001, 0x602f, 0x0008, 0x6104, 0x918e, 0x0010,
-	0x6106, 0x918e, 0x0010, 0x6106, 0x6017, 0x0040, 0x04b9, 0x001e,
-	0x9184, 0x0003, 0x01e0, 0x0036, 0x0016, 0x2019, 0x0141, 0x6124,
-	0x918c, 0x0028, 0x1120, 0x2304, 0x9084, 0x2800, 0x0dc0, 0x001e,
-	0x919c, 0xffe4, 0x9184, 0x0001, 0x0118, 0x9385, 0x0009, 0x6016,
-	0x9184, 0x0002, 0x0118, 0x9385, 0x0012, 0x6016, 0x003e, 0x2001,
-	0x180c, 0x200c, 0xc1dc, 0x2102, 0x00ce, 0x0005, 0x0016, 0x0026,
-	0x080c, 0x7458, 0x0108, 0xc0bc, 0x2009, 0x0140, 0x2114, 0x9294,
-	0x0001, 0x9215, 0x220a, 0x002e, 0x001e, 0x0005, 0x0016, 0x0026,
-	0x2009, 0x0140, 0x2114, 0x9294, 0x0001, 0x9285, 0x1000, 0x200a,
-	0x220a, 0x002e, 0x001e, 0x0005, 0x0016, 0x0026, 0x2009, 0x0140,
-	0x2114, 0x9294, 0x0001, 0x9215, 0x220a, 0x002e, 0x001e, 0x0005,
-	0x0006, 0x0016, 0x2009, 0x0140, 0x2104, 0x1128, 0x080c, 0x7458,
-	0x0110, 0xc0bc, 0x0008, 0xc0bd, 0x200a, 0x001e, 0x000e, 0x0005,
-	0x2ff4, 0x2ff4, 0x2e18, 0x2e18, 0x2e24, 0x2e24, 0x2e30, 0x2e30,
-	0x2e3e, 0x2e3e, 0x2e4a, 0x2e4a, 0x2e58, 0x2e58, 0x2e66, 0x2e66,
-	0x2e78, 0x2e78, 0x2e84, 0x2e84, 0x2e92, 0x2e92, 0x2eb0, 0x2eb0,
-	0x2ed0, 0x2ed0, 0x2ea0, 0x2ea0, 0x2ec0, 0x2ec0, 0x2ede, 0x2ede,
-	0x2e76, 0x2e76, 0x2e76, 0x2e76, 0x2e76, 0x2e76, 0x2e76, 0x2e76,
-	0x2e76, 0x2e76, 0x2e76, 0x2e76, 0x2e76, 0x2e76, 0x2e76, 0x2e76,
-	0x2e76, 0x2e76, 0x2e76, 0x2e76, 0x2e76, 0x2e76, 0x2e76, 0x2e76,
-	0x2e76, 0x2e76, 0x2e76, 0x2e76, 0x2e76, 0x2e76, 0x2e76, 0x2e76,
-	0x2ef0, 0x2ef0, 0x2efc, 0x2efc, 0x2f0a, 0x2f0a, 0x2f18, 0x2f18,
-	0x2f28, 0x2f28, 0x2f36, 0x2f36, 0x2f46, 0x2f46, 0x2f56, 0x2f56,
-	0x2f68, 0x2f68, 0x2f76, 0x2f76, 0x2f86, 0x2f86, 0x2fa8, 0x2fa8,
-	0x2fca, 0x2fca, 0x2f96, 0x2f96, 0x2fb9, 0x2fb9, 0x2fd9, 0x2fd9,
-	0x2e76, 0x2e76, 0x2e76, 0x2e76, 0x2e76, 0x2e76, 0x2e76, 0x2e76,
-	0x2e76, 0x2e76, 0x2e76, 0x2e76, 0x2e76, 0x2e76, 0x2e76, 0x2e76,
-	0x2e76, 0x2e76, 0x2e76, 0x2e76, 0x2e76, 0x2e76, 0x2e76, 0x2e76,
-	0x2e76, 0x2e76, 0x2e76, 0x2e76, 0x2e76, 0x2e76, 0x2e76, 0x2e76,
-	0x2e76, 0x2e76, 0x2e76, 0x2e76, 0x2e76, 0x2e76, 0x2e76, 0x2e76,
-	0x2e76, 0x2e76, 0x2e76, 0x2e76, 0x2e76, 0x2e76, 0x2e76, 0x2e76,
-	0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156,
-	0x080c, 0x24bf, 0x0804, 0x2fec, 0x0106, 0x0006, 0x0126, 0x01c6,
-	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x22d3, 0x0804, 0x2fec,
-	0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156,
-	0x080c, 0x22d3, 0x080c, 0x24bf, 0x0804, 0x2fec, 0x0106, 0x0006,
-	0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x230e,
-	0x0804, 0x2fec, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
-	0x0146, 0x0156, 0x080c, 0x24bf, 0x080c, 0x230e, 0x0804, 0x2fec,
-	0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156,
-	0x080c, 0x22d3, 0x080c, 0x230e, 0x0804, 0x2fec, 0x0106, 0x0006,
-	0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x22d3,
-	0x080c, 0x24bf, 0x080c, 0x230e, 0x0804, 0x2fec, 0xa001, 0x0cf0,
-	0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156,
-	0x080c, 0x1380, 0x0804, 0x2fec, 0x0106, 0x0006, 0x0126, 0x01c6,
-	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x24bf, 0x080c, 0x1380,
-	0x0804, 0x2fec, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
-	0x0146, 0x0156, 0x080c, 0x22d3, 0x080c, 0x1380, 0x0804, 0x2fec,
-	0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156,
-	0x080c, 0x24bf, 0x080c, 0x1380, 0x080c, 0x230e, 0x0804, 0x2fec,
-	0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156,
-	0x080c, 0x22d3, 0x080c, 0x24bf, 0x080c, 0x1380, 0x0804, 0x2fec,
-	0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156,
-	0x080c, 0x22d3, 0x080c, 0x1380, 0x080c, 0x230e, 0x0804, 0x2fec,
-	0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156,
-	0x080c, 0x1380, 0x080c, 0x230e, 0x0804, 0x2fec, 0x0106, 0x0006,
-	0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x22d3,
-	0x080c, 0x24bf, 0x080c, 0x1380, 0x080c, 0x230e, 0x0804, 0x2fec,
-	0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156,
-	0x080c, 0x297f, 0x0804, 0x2fec, 0x0106, 0x0006, 0x0126, 0x01c6,
-	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x297f, 0x080c, 0x24bf,
-	0x0804, 0x2fec, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
-	0x0146, 0x0156, 0x080c, 0x297f, 0x080c, 0x22d3, 0x0804, 0x2fec,
-	0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156,
-	0x080c, 0x297f, 0x080c, 0x22d3, 0x080c, 0x24bf, 0x0804, 0x2fec,
-	0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156,
-	0x080c, 0x297f, 0x080c, 0x230e, 0x0804, 0x2fec, 0x0106, 0x0006,
-	0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x297f,
-	0x080c, 0x24bf, 0x080c, 0x230e, 0x0804, 0x2fec, 0x0106, 0x0006,
-	0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x297f,
-	0x080c, 0x22d3, 0x080c, 0x230e, 0x0804, 0x2fec, 0x0106, 0x0006,
-	0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x297f,
-	0x080c, 0x22d3, 0x080c, 0x24bf, 0x080c, 0x230e, 0x0804, 0x2fec,
-	0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156,
-	0x080c, 0x297f, 0x080c, 0x1380, 0x0804, 0x2fec, 0x0106, 0x0006,
-	0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x297f,
-	0x080c, 0x24bf, 0x080c, 0x1380, 0x0804, 0x2fec, 0x0106, 0x0006,
-	0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x297f,
-	0x080c, 0x22d3, 0x080c, 0x1380, 0x0804, 0x2fec, 0x0106, 0x0006,
-	0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x297f,
-	0x080c, 0x24bf, 0x080c, 0x1380, 0x080c, 0x230e, 0x0804, 0x2fec,
-	0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156,
-	0x080c, 0x297f, 0x080c, 0x22d3, 0x080c, 0x24bf, 0x080c, 0x1380,
-	0x0498, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146,
-	0x0156, 0x080c, 0x297f, 0x080c, 0x22d3, 0x080c, 0x1380, 0x080c,
-	0x230e, 0x0410, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
-	0x0146, 0x0156, 0x080c, 0x297f, 0x080c, 0x1380, 0x080c, 0x230e,
-	0x0098, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146,
-	0x0156, 0x080c, 0x297f, 0x080c, 0x22d3, 0x080c, 0x24bf, 0x080c,
-	0x1380, 0x080c, 0x230e, 0x0000, 0x015e, 0x014e, 0x013e, 0x01de,
-	0x01ce, 0x012e, 0x000e, 0x010e, 0x000d, 0x00b6, 0x00c6, 0x0026,
-	0x0046, 0x9026, 0x080c, 0x69ca, 0x1904, 0x3105, 0x72dc, 0x2001,
-	0x197b, 0x2004, 0x9005, 0x1110, 0xd29c, 0x0148, 0xd284, 0x1138,
-	0xd2bc, 0x1904, 0x3105, 0x080c, 0x310a, 0x0804, 0x3105, 0xd2cc,
-	0x1904, 0x3105, 0x080c, 0x743e, 0x1120, 0x70af, 0xffff, 0x0804,
-	0x3105, 0xd294, 0x0120, 0x70af, 0xffff, 0x0804, 0x3105, 0x080c,
-	0x3373, 0x0160, 0x080c, 0xd388, 0x0128, 0x2001, 0x1818, 0x203c,
-	0x0804, 0x3092, 0x70af, 0xffff, 0x0804, 0x3105, 0x2001, 0x1818,
-	0x203c, 0x7294, 0xd284, 0x0904, 0x3092, 0xd28c, 0x1904, 0x3092,
-	0x0036, 0x73ac, 0x938e, 0xffff, 0x1110, 0x2019, 0x0001, 0x8314,
-	0x92e0, 0x1c80, 0x2c04, 0x938c, 0x0001, 0x0120, 0x9084, 0xff00,
-	0x8007, 0x0010, 0x9084, 0x00ff, 0x970e, 0x05d0, 0x908e, 0x0000,
-	0x05b8, 0x908e, 0x00ff, 0x1150, 0x7230, 0xd284, 0x15b0, 0x7294,
-	0xc28d, 0x7296, 0x70af, 0xffff, 0x003e, 0x04a0, 0x900e, 0x080c,
-	0x287c, 0x080c, 0x6638, 0x1538, 0x9006, 0xb8bb, 0x0520, 0xb8ac,
-	0x9005, 0x0148, 0x00c6, 0x2060, 0x080c, 0x8a3d, 0x00ce, 0x090c,
-	0x8dda, 0xb8af, 0x0000, 0x080c, 0x6a0c, 0x1168, 0x7030, 0xd08c,
-	0x0130, 0xb800, 0xd0bc, 0x0138, 0x080c, 0x68b9, 0x0120, 0x080c,
-	0x3123, 0x0148, 0x0028, 0x080c, 0x3263, 0x080c, 0x314f, 0x0118,
-	0x8318, 0x0804, 0x303f, 0x73ae, 0x0010, 0x70af, 0xffff, 0x003e,
-	0x0804, 0x3105, 0x9780, 0x3384, 0x203d, 0x97bc, 0xff00, 0x873f,
-	0x2041, 0x007e, 0x70ac, 0x9096, 0xffff, 0x1118, 0x900e, 0x28a8,
-	0x0050, 0x9812, 0x0220, 0x2008, 0x9802, 0x20a8, 0x0020, 0x70af,
-	0xffff, 0x0804, 0x3105, 0x2700, 0x0156, 0x0016, 0x9106, 0x0904,
-	0x30fa, 0xc484, 0x080c, 0x6699, 0x0148, 0x080c, 0xd388, 0x1904,
-	0x30fa, 0x080c, 0x6638, 0x1904, 0x3102, 0x0008, 0xc485, 0xb8bb,
-	0x0520, 0xb8ac, 0x9005, 0x0148, 0x00c6, 0x2060, 0x080c, 0x8a3d,
-	0x00ce, 0x090c, 0x8dda, 0xb8af, 0x0000, 0x080c, 0x6a0c, 0x1130,
-	0x7030, 0xd08c, 0x01f8, 0xb800, 0xd0bc, 0x11e0, 0x7294, 0xd28c,
-	0x0180, 0x080c, 0x6a0c, 0x9082, 0x0006, 0x02e0, 0xd484, 0x1118,
-	0x080c, 0x665d, 0x0028, 0x080c, 0x32ef, 0x01a0, 0x080c, 0x331a,
-	0x0088, 0x080c, 0x3263, 0x080c, 0xd388, 0x1160, 0x080c, 0x314f,
-	0x0188, 0x0040, 0x080c, 0xd388, 0x1118, 0x080c, 0x32ef, 0x0110,
-	0x0451, 0x0140, 0x001e, 0x8108, 0x015e, 0x1f04, 0x30ab, 0x70af,
-	0xffff, 0x0018, 0x001e, 0x015e, 0x71ae, 0x004e, 0x002e, 0x00ce,
-	0x00be, 0x0005, 0x00c6, 0x0016, 0x70af, 0x0001, 0x2009, 0x007e,
-	0x080c, 0x6638, 0x1168, 0xb813, 0x00ff, 0xb817, 0xfffe, 0x080c,
-	0x3263, 0x04a9, 0x0128, 0x70dc, 0xc0bd, 0x70de, 0x080c, 0xd0d9,
-	0x001e, 0x00ce, 0x0005, 0x0016, 0x0076, 0x00d6, 0x00c6, 0x2001,
-	0x184c, 0x2004, 0x9084, 0x00ff, 0xb842, 0x080c, 0xaf91, 0x01d0,
-	0x2b00, 0x6012, 0x080c, 0xd102, 0x6023, 0x0001, 0x9006, 0x080c,
-	0x65d5, 0x2001, 0x0000, 0x080c, 0x65e9, 0x0126, 0x2091, 0x8000,
-	0x70a8, 0x8000, 0x70aa, 0x012e, 0x2009, 0x0004, 0x080c, 0xafbe,
-	0x9085, 0x0001, 0x00ce, 0x00de, 0x007e, 0x001e, 0x0005, 0x0016,
-	0x0076, 0x00d6, 0x00c6, 0x2001, 0x184c, 0x2004, 0x9084, 0x00ff,
-	0xb842, 0x080c, 0xaf91, 0x0548, 0x2b00, 0x6012, 0xb800, 0xc0c4,
-	0xb802, 0xb8a0, 0x9086, 0x007e, 0x0140, 0xb804, 0x9084, 0x00ff,
-	0x9086, 0x0006, 0x1110, 0x080c, 0x321e, 0x080c, 0xd102, 0x6023,
-	0x0001, 0x9006, 0x080c, 0x65d5, 0x2001, 0x0002, 0x080c, 0x65e9,
-	0x0126, 0x2091, 0x8000, 0x70a8, 0x8000, 0x70aa, 0x012e, 0x2009,
-	0x0002, 0x080c, 0xafbe, 0x9085, 0x0001, 0x00ce, 0x00de, 0x007e,
-	0x001e, 0x0005, 0x00b6, 0x00c6, 0x0026, 0x2009, 0x0080, 0x080c,
-	0x6638, 0x1140, 0xb813, 0x00ff, 0xb817, 0xfffc, 0x0039, 0x0110,
-	0x70e3, 0xffff, 0x002e, 0x00ce, 0x00be, 0x0005, 0x0016, 0x0076,
-	0x00d6, 0x00c6, 0x080c, 0xaeed, 0x01d0, 0x2b00, 0x6012, 0x080c,
-	0xd102, 0x6023, 0x0001, 0x9006, 0x080c, 0x65d5, 0x2001, 0x0002,
-	0x080c, 0x65e9, 0x0126, 0x2091, 0x8000, 0x70e4, 0x8000, 0x70e6,
-	0x012e, 0x2009, 0x0002, 0x080c, 0xafbe, 0x9085, 0x0001, 0x00ce,
-	0x00de, 0x007e, 0x001e, 0x0005, 0x00c6, 0x00d6, 0x0126, 0x2091,
-	0x8000, 0x2009, 0x007f, 0x080c, 0x6638, 0x11b8, 0xb813, 0x00ff,
-	0xb817, 0xfffd, 0xb8cf, 0x0004, 0x080c, 0xaeed, 0x0170, 0x2b00,
-	0x6012, 0x6316, 0x6023, 0x0001, 0x620a, 0x080c, 0xd102, 0x2009,
-	0x0022, 0x080c, 0xafbe, 0x9085, 0x0001, 0x012e, 0x00de, 0x00ce,
-	0x0005, 0x00e6, 0x00c6, 0x0066, 0x0036, 0x0026, 0x00b6, 0x21f0,
-	0x080c, 0x9361, 0x080c, 0x92e1, 0x080c, 0xad81, 0x080c, 0xbe6b,
-	0x3e08, 0x2130, 0x81ff, 0x0120, 0x20a9, 0x007e, 0x900e, 0x0018,
-	0x20a9, 0x007f, 0x900e, 0x0016, 0x080c, 0x6699, 0x1140, 0x9686,
-	0x0002, 0x1118, 0xb800, 0xd0bc, 0x1110, 0x080c, 0x60c7, 0x001e,
-	0x8108, 0x1f04, 0x3203, 0x9686, 0x0001, 0x190c, 0x3347, 0x00be,
-	0x002e, 0x003e, 0x006e, 0x00ce, 0x00ee, 0x0005, 0x00e6, 0x00c6,
-	0x0046, 0x0036, 0x0026, 0x0016, 0x00b6, 0x6210, 0x2258, 0xbaa0,
-	0x0026, 0x2019, 0x0029, 0x080c, 0x9356, 0x0076, 0x2039, 0x0000,
-	0x080c, 0x9229, 0x2c08, 0x080c, 0xe477, 0x007e, 0x001e, 0xba10,
-	0xbb14, 0xbcc0, 0x080c, 0x60c7, 0xba12, 0xbb16, 0xbcc2, 0x00be,
-	0x001e, 0x002e, 0x003e, 0x004e, 0x00ce, 0x00ee, 0x0005, 0x00e6,
-	0x0006, 0x00b6, 0x6010, 0x2058, 0xb8a0, 0x00be, 0x9086, 0x0080,
-	0x0150, 0x2071, 0x1800, 0x70a8, 0x9005, 0x0110, 0x8001, 0x70aa,
-	0x000e, 0x00ee, 0x0005, 0x2071, 0x1800, 0x70e4, 0x9005, 0x0dc0,
-	0x8001, 0x70e6, 0x0ca8, 0xb800, 0xc08c, 0xb802, 0x0005, 0x00f6,
-	0x00e6, 0x00c6, 0x00b6, 0x0046, 0x0036, 0x0026, 0x0016, 0x0156,
-	0x2178, 0x81ff, 0x1118, 0x20a9, 0x0001, 0x0078, 0x080c, 0x575d,
-	0xd0c4, 0x0140, 0xd0a4, 0x0130, 0x9006, 0x2020, 0x2009, 0x002d,
-	0x080c, 0xe73a, 0x20a9, 0x0800, 0x9016, 0x0026, 0x928e, 0x007e,
-	0x0904, 0x32ce, 0x928e, 0x007f, 0x0904, 0x32ce, 0x928e, 0x0080,
-	0x05e8, 0x9288, 0x1000, 0x210c, 0x81ff, 0x05c0, 0x8fff, 0x1148,
-	0x2001, 0x198d, 0x0006, 0x2003, 0x0001, 0x04f1, 0x000e, 0x2003,
-	0x0000, 0x00b6, 0x00c6, 0x2158, 0x2001, 0x0001, 0x080c, 0x69d6,
-	0x00ce, 0x00be, 0x2019, 0x0029, 0x080c, 0x9356, 0x0076, 0x2039,
-	0x0000, 0x080c, 0x9229, 0x00b6, 0x00c6, 0x0026, 0x2158, 0xba04,
-	0x9294, 0x00ff, 0x9286, 0x0006, 0x1118, 0xb807, 0x0404, 0x0028,
-	0x2001, 0x0004, 0x8007, 0x9215, 0xba06, 0x002e, 0x00ce, 0x00be,
-	0x0016, 0x2c08, 0x080c, 0xe477, 0x001e, 0x007e, 0x002e, 0x8210,
-	0x1f04, 0x3285, 0x015e, 0x001e, 0x002e, 0x003e, 0x004e, 0x00be,
-	0x00ce, 0x00ee, 0x00fe, 0x0005, 0x0046, 0x0026, 0x0016, 0x080c,
-	0x575d, 0xd0c4, 0x0140, 0xd0a4, 0x0130, 0x9006, 0x2220, 0x2009,
-	0x0029, 0x080c, 0xe73a, 0x001e, 0x002e, 0x004e, 0x0005, 0x0016,
-	0x0026, 0x0036, 0x00c6, 0x7294, 0x82ff, 0x01e8, 0x080c, 0x6a04,
-	0x11d0, 0x2100, 0x080c, 0x28af, 0x81ff, 0x01b8, 0x2019, 0x0001,
-	0x8314, 0x92e0, 0x1c80, 0x2c04, 0xd384, 0x0120, 0x9084, 0xff00,
-	0x8007, 0x0010, 0x9084, 0x00ff, 0x9116, 0x0138, 0x9096, 0x00ff,
-	0x0110, 0x8318, 0x0c68, 0x9085, 0x0001, 0x00ce, 0x003e, 0x002e,
-	0x001e, 0x0005, 0x0016, 0x00c6, 0x0126, 0x2091, 0x8000, 0x0036,
-	0x2019, 0x0029, 0x00a9, 0x003e, 0x9180, 0x1000, 0x2004, 0x9065,
-	0x0158, 0x0016, 0x00c6, 0x2061, 0x1ab2, 0x001e, 0x6112, 0x080c,
-	0x321e, 0x001e, 0x080c, 0x665d, 0x012e, 0x00ce, 0x001e, 0x0005,
-	0x0016, 0x0026, 0x2110, 0x080c, 0xa8dc, 0x080c, 0xeaa3, 0x002e,
-	0x001e, 0x0005, 0x2001, 0x1837, 0x2004, 0xd0cc, 0x0005, 0x00c6,
-	0x00b6, 0x080c, 0x743e, 0x1118, 0x20a9, 0x0800, 0x0010, 0x20a9,
-	0x0782, 0x080c, 0x743e, 0x1110, 0x900e, 0x0010, 0x2009, 0x007e,
-	0x9180, 0x1000, 0x2004, 0x905d, 0x0130, 0x86ff, 0x0110, 0xb800,
-	0xd0bc, 0x090c, 0x665d, 0x8108, 0x1f04, 0x3358, 0x2061, 0x1800,
-	0x607f, 0x0000, 0x6080, 0x9084, 0x00ff, 0x6082, 0x60b3, 0x0000,
-	0x00be, 0x00ce, 0x0005, 0x2001, 0x1869, 0x2004, 0xd0bc, 0x0005,
-	0x2011, 0x1848, 0x2214, 0xd2ec, 0x0005, 0x0026, 0x2011, 0x1867,
-	0x2214, 0xd2dc, 0x002e, 0x0005, 0x7eef, 0x7de8, 0x7ce4, 0x80e2,
-	0x7be1, 0x80e0, 0x80dc, 0x80da, 0x7ad9, 0x80d6, 0x80d5, 0x80d4,
-	0x80d3, 0x80d2, 0x80d1, 0x79ce, 0x78cd, 0x80cc, 0x80cb, 0x80ca,
-	0x80c9, 0x80c7, 0x80c6, 0x77c5, 0x76c3, 0x80bc, 0x80ba, 0x75b9,
-	0x80b6, 0x74b5, 0x73b4, 0x72b3, 0x80b2, 0x80b1, 0x80ae, 0x71ad,
-	0x80ac, 0x70ab, 0x6faa, 0x6ea9, 0x80a7, 0x6da6, 0x6ca5, 0x6ba3,
-	0x6a9f, 0x699e, 0x689d, 0x809b, 0x8098, 0x6797, 0x6690, 0x658f,
-	0x6488, 0x6384, 0x6282, 0x8081, 0x8080, 0x617c, 0x607a, 0x8079,
-	0x5f76, 0x8075, 0x8074, 0x8073, 0x8072, 0x8071, 0x806e, 0x5e6d,
-	0x806c, 0x5d6b, 0x5c6a, 0x5b69, 0x8067, 0x5a66, 0x5965, 0x5863,
-	0x575c, 0x565a, 0x5559, 0x8056, 0x8055, 0x5454, 0x5353, 0x5252,
-	0x5151, 0x504e, 0x4f4d, 0x804c, 0x804b, 0x4e4a, 0x4d49, 0x8047,
-	0x4c46, 0x8045, 0x8043, 0x803c, 0x803a, 0x8039, 0x8036, 0x4b35,
-	0x8034, 0x4a33, 0x4932, 0x4831, 0x802e, 0x472d, 0x462c, 0x452b,
-	0x442a, 0x4329, 0x4227, 0x8026, 0x8025, 0x4123, 0x401f, 0x3f1e,
-	0x3e1d, 0x3d1b, 0x3c18, 0x8017, 0x8010, 0x3b0f, 0x3a08, 0x8004,
-	0x3902, 0x8001, 0x8000, 0x8000, 0x3800, 0x3700, 0x3600, 0x8000,
-	0x3500, 0x8000, 0x8000, 0x8000, 0x3400, 0x8000, 0x8000, 0x8000,
-	0x8000, 0x8000, 0x8000, 0x3300, 0x3200, 0x8000, 0x8000, 0x8000,
-	0x8000, 0x8000, 0x8000, 0x3100, 0x3000, 0x8000, 0x8000, 0x2f00,
-	0x8000, 0x2e00, 0x2d00, 0x2c00, 0x8000, 0x8000, 0x8000, 0x2b00,
-	0x8000, 0x2a00, 0x2900, 0x2800, 0x8000, 0x2700, 0x2600, 0x2500,
-	0x2400, 0x2300, 0x2200, 0x8000, 0x8000, 0x2100, 0x2000, 0x1f00,
-	0x1e00, 0x1d00, 0x1c00, 0x8000, 0x8000, 0x1b00, 0x1a00, 0x8000,
-	0x1900, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x1800,
-	0x8000, 0x1700, 0x1600, 0x1500, 0x8000, 0x1400, 0x1300, 0x1200,
-	0x1100, 0x1000, 0x0f00, 0x8000, 0x8000, 0x0e00, 0x0d00, 0x0c00,
-	0x0b00, 0x0a00, 0x0900, 0x8000, 0x8000, 0x0800, 0x0700, 0x8000,
-	0x0600, 0x8000, 0x8000, 0x8000, 0x0500, 0x0400, 0x0300, 0x8000,
-	0x0200, 0x8000, 0x8000, 0x8000, 0x0100, 0x8000, 0x8000, 0x8000,
-	0x8000, 0x8000, 0x8000, 0x0000, 0x8000, 0x8000, 0x8000, 0x8000,
+	0x6027, 0x0004, 0x00b0, 0x0036, 0x2019, 0x0001, 0x080c, 0xa85d,
+	0x003e, 0x2019, 0x19f8, 0x2304, 0x9065, 0x0150, 0x2009, 0x004f,
+	0x6020, 0x9086, 0x0009, 0x1110, 0x2009, 0x004f, 0x080c, 0xb166,
+	0x00ce, 0x001e, 0xd19c, 0x0904, 0x27f2, 0x7038, 0xd0ac, 0x1538,
+	0x0016, 0x0156, 0x6027, 0x0008, 0x080c, 0x2d95, 0x20a9, 0x0028,
+	0xa001, 0x1f04, 0x27a8, 0x6150, 0x9185, 0x1400, 0x6052, 0x20a9,
+	0x0366, 0x1d04, 0x27b1, 0x080c, 0x87bd, 0x6020, 0xd09c, 0x1130,
+	0x015e, 0x6152, 0x001e, 0x6027, 0x0008, 0x04a0, 0x080c, 0x2c4b,
+	0x1f04, 0x27b1, 0x015e, 0x6152, 0x001e, 0x6027, 0x0008, 0x0016,
+	0x6028, 0xc09c, 0x602a, 0x080c, 0xb058, 0x60e3, 0x0000, 0x080c,
+	0xed95, 0x080c, 0xedb0, 0x080c, 0x57d1, 0xd0fc, 0x1138, 0x080c,
+	0xd541, 0x1120, 0x9085, 0x0001, 0x080c, 0x75a7, 0x9006, 0x080c,
+	0x2d5b, 0x2009, 0x0002, 0x080c, 0x2c89, 0x00e6, 0x2071, 0x1800,
+	0x7003, 0x0004, 0x080c, 0x0ea3, 0x00ee, 0x6027, 0x0008, 0x080c,
+	0x0ba0, 0x001e, 0x918c, 0xffd0, 0x6126, 0x00ae, 0x0005, 0x0016,
+	0x2001, 0x188b, 0x200c, 0xd184, 0x001e, 0x0904, 0x25b4, 0x0016,
+	0x2009, 0x2803, 0x00d0, 0x2001, 0x188b, 0x200c, 0xc184, 0x2102,
+	0x001e, 0x0c40, 0x0016, 0x2001, 0x188b, 0x200c, 0xd194, 0x001e,
+	0x0904, 0x25b4, 0x0016, 0x2009, 0x2816, 0x0038, 0x2001, 0x188b,
+	0x200c, 0xc194, 0x2102, 0x001e, 0x08a8, 0x6028, 0xc0bc, 0x602a,
+	0x2001, 0x0156, 0x2003, 0xbc91, 0x8000, 0x2003, 0xffff, 0x6043,
+	0x0001, 0x080c, 0x2c83, 0x6027, 0x0080, 0x6017, 0x0000, 0x6043,
+	0x0000, 0x0817, 0x0006, 0x0016, 0x0026, 0x0036, 0x00e6, 0x00f6,
+	0x0126, 0x2091, 0x8000, 0x2071, 0x1800, 0x71d0, 0x70d2, 0x9116,
+	0x0904, 0x2881, 0x81ff, 0x01a0, 0x2009, 0x0000, 0x080c, 0x2c89,
+	0x2011, 0x8011, 0x2019, 0x010e, 0x231c, 0x939e, 0x0007, 0x1118,
+	0x2019, 0x0001, 0x0010, 0x2019, 0x0000, 0x080c, 0x4be3, 0x0448,
+	0x2001, 0x19a9, 0x200c, 0x81ff, 0x1140, 0x2001, 0x0109, 0x2004,
+	0xd0b4, 0x0118, 0x2019, 0x0003, 0x0008, 0x2118, 0x2011, 0x8012,
+	0x080c, 0x4be3, 0x080c, 0x0ea3, 0x080c, 0x57d1, 0xd0fc, 0x1188,
+	0x080c, 0xd541, 0x1170, 0x00c6, 0x080c, 0x291d, 0x080c, 0xa7c4,
+	0x2061, 0x0100, 0x2019, 0x0028, 0x2009, 0x0002, 0x080c, 0x3216,
+	0x00ce, 0x012e, 0x00fe, 0x00ee, 0x003e, 0x002e, 0x001e, 0x000e,
+	0x0005, 0x2028, 0x918c, 0x00ff, 0x2130, 0x9094, 0xff00, 0x11f0,
+	0x2011, 0x1837, 0x2214, 0xd2ac, 0x11c8, 0x81ff, 0x01e8, 0x2011,
+	0x181f, 0x2204, 0x9106, 0x1190, 0x2011, 0x1820, 0x2214, 0x9294,
+	0xff00, 0x9584, 0xff00, 0x9206, 0x1148, 0x2011, 0x1820, 0x2214,
+	0x9294, 0x00ff, 0x9584, 0x00ff, 0x9206, 0x1120, 0x2500, 0x080c,
+	0x826b, 0x0048, 0x9584, 0x00ff, 0x9080, 0x33b1, 0x200d, 0x918c,
+	0xff00, 0x810f, 0x9006, 0x0005, 0x9080, 0x33b1, 0x200d, 0x918c,
+	0x00ff, 0x0005, 0x00d6, 0x2069, 0x0140, 0x2001, 0x1818, 0x2003,
+	0x00ef, 0x20a9, 0x0010, 0x9006, 0x6852, 0x6856, 0x1f04, 0x28cd,
+	0x00de, 0x0005, 0x0006, 0x00d6, 0x0026, 0x2069, 0x0140, 0x2001,
+	0x1818, 0x2102, 0x8114, 0x8214, 0x8214, 0x8214, 0x20a9, 0x0010,
+	0x6853, 0x0000, 0x9006, 0x82ff, 0x1128, 0x9184, 0x000f, 0x9080,
+	0xf58c, 0x2005, 0x6856, 0x8211, 0x1f04, 0x28e2, 0x002e, 0x00de,
+	0x000e, 0x0005, 0x00c6, 0x2061, 0x1800, 0x6030, 0x0110, 0xc09d,
+	0x0008, 0xc09c, 0x6032, 0x00ce, 0x0005, 0x0156, 0x00d6, 0x0026,
+	0x0016, 0x0006, 0x2069, 0x0140, 0x6980, 0x9116, 0x0180, 0x9112,
+	0x1230, 0x8212, 0x8210, 0x22a8, 0x2001, 0x0402, 0x0018, 0x22a8,
+	0x2001, 0x0404, 0x680e, 0x1f04, 0x2912, 0x680f, 0x0000, 0x000e,
+	0x001e, 0x002e, 0x00de, 0x015e, 0x0005, 0x080c, 0x57cd, 0xd0c4,
+	0x0150, 0xd0a4, 0x0140, 0x9006, 0x0046, 0x2020, 0x2009, 0x002e,
+	0x080c, 0xe940, 0x004e, 0x0005, 0x00f6, 0x0016, 0x0026, 0x2079,
+	0x0140, 0x78c4, 0xd0dc, 0x0904, 0x2989, 0x080c, 0x2be8, 0x0660,
+	0x9084, 0x0700, 0x908e, 0x0600, 0x1120, 0x2011, 0x4000, 0x900e,
+	0x0458, 0x908e, 0x0500, 0x1120, 0x2011, 0x8000, 0x900e, 0x0420,
+	0x908e, 0x0400, 0x1120, 0x9016, 0x2009, 0x0001, 0x00e8, 0x908e,
+	0x0300, 0x1120, 0x9016, 0x2009, 0x0002, 0x00b0, 0x908e, 0x0200,
+	0x1120, 0x9016, 0x2009, 0x0004, 0x0078, 0x908e, 0x0100, 0x1548,
+	0x9016, 0x2009, 0x0008, 0x0040, 0x9084, 0x0700, 0x908e, 0x0300,
+	0x1500, 0x2011, 0x0030, 0x0058, 0x2300, 0x9080, 0x0020, 0x2018,
+	0x080c, 0x91ab, 0x928c, 0xff00, 0x0110, 0x2011, 0x00ff, 0x2200,
+	0x8007, 0x9085, 0x004c, 0x78c2, 0x2009, 0x0138, 0x220a, 0x080c,
+	0x7563, 0x1118, 0x2009, 0x196e, 0x220a, 0x002e, 0x001e, 0x00fe,
+	0x0005, 0x78c3, 0x0000, 0x0cc8, 0x0126, 0x2091, 0x2800, 0x0006,
+	0x0016, 0x0026, 0x2001, 0x0170, 0x200c, 0x8000, 0x2014, 0x9184,
+	0x0003, 0x0110, 0x080c, 0x0dbe, 0x002e, 0x001e, 0x000e, 0x012e,
+	0x0005, 0x2001, 0x0171, 0x2004, 0xd0dc, 0x0168, 0x2001, 0x0170,
+	0x200c, 0x918c, 0x00ff, 0x918e, 0x004c, 0x1128, 0x200c, 0x918c,
+	0xff00, 0x810f, 0x0005, 0x900e, 0x2001, 0x0227, 0x2004, 0x8007,
+	0x9084, 0x00ff, 0x8004, 0x9108, 0x2001, 0x0226, 0x2004, 0x8007,
+	0x9084, 0x00ff, 0x8004, 0x9108, 0x0005, 0x0018, 0x000c, 0x0018,
+	0x0020, 0x1000, 0x0800, 0x1000, 0x1800, 0x0156, 0x0006, 0x0016,
+	0x0026, 0x00e6, 0x2001, 0x1991, 0x2004, 0x908a, 0x0007, 0x1a0c,
+	0x0dc5, 0x0033, 0x00ee, 0x002e, 0x001e, 0x000e, 0x015e, 0x0005,
+	0x29e7, 0x2a05, 0x2a29, 0x2a2b, 0x2a54, 0x2a56, 0x2a58, 0x2001,
+	0x0001, 0x080c, 0x2832, 0x080c, 0x2c46, 0x2001, 0x1993, 0x2003,
+	0x0000, 0x7828, 0x9084, 0xe1d7, 0x782a, 0x9006, 0x20a9, 0x0009,
+	0x080c, 0x2c04, 0x2001, 0x1991, 0x2003, 0x0006, 0x2009, 0x001e,
+	0x2011, 0x2a59, 0x080c, 0x879b, 0x0005, 0x2009, 0x1996, 0x200b,
+	0x0000, 0x2001, 0x199b, 0x2003, 0x0036, 0x2001, 0x199a, 0x2003,
+	0x002a, 0x2001, 0x1993, 0x2003, 0x0001, 0x9006, 0x080c, 0x2bb6,
+	0x2001, 0xffff, 0x20a9, 0x0009, 0x080c, 0x2c04, 0x2001, 0x1991,
+	0x2003, 0x0006, 0x2009, 0x001e, 0x2011, 0x2a59, 0x080c, 0x879b,
+	0x0005, 0x080c, 0x0dc5, 0x2001, 0x199b, 0x2003, 0x0036, 0x2001,
+	0x1993, 0x2003, 0x0003, 0x7a38, 0x9294, 0x0005, 0x9296, 0x0004,
+	0x0110, 0x9006, 0x0010, 0x2001, 0x0001, 0x080c, 0x2bb6, 0x2001,
+	0x1997, 0x2003, 0x0000, 0x2001, 0xffff, 0x20a9, 0x0009, 0x080c,
+	0x2c04, 0x2001, 0x1991, 0x2003, 0x0006, 0x2009, 0x001e, 0x2011,
+	0x2a59, 0x080c, 0x879b, 0x0005, 0x080c, 0x0dc5, 0x080c, 0x0dc5,
+	0x0005, 0x0006, 0x0016, 0x0026, 0x00e6, 0x00f6, 0x0156, 0x0126,
+	0x2091, 0x8000, 0x2079, 0x0100, 0x2001, 0x1993, 0x2004, 0x908a,
+	0x0007, 0x1a0c, 0x0dc5, 0x0043, 0x012e, 0x015e, 0x00fe, 0x00ee,
+	0x002e, 0x001e, 0x000e, 0x0005, 0x2a7b, 0x2a9b, 0x2adb, 0x2b0b,
+	0x2b2f, 0x2b3f, 0x2b41, 0x080c, 0x2bf8, 0x11b0, 0x7850, 0x9084,
+	0xefff, 0x7852, 0x2009, 0x1999, 0x2104, 0x7a38, 0x9294, 0x0005,
+	0x9296, 0x0004, 0x0110, 0xc08d, 0x0008, 0xc085, 0x200a, 0x2001,
+	0x1991, 0x2003, 0x0001, 0x0030, 0x080c, 0x2b65, 0x2001, 0xffff,
+	0x080c, 0x29f6, 0x0005, 0x080c, 0x2b43, 0x05e0, 0x2009, 0x199a,
+	0x2104, 0x8001, 0x200a, 0x080c, 0x2bf8, 0x1178, 0x7850, 0x9084,
+	0xefff, 0x7852, 0x7a38, 0x9294, 0x0005, 0x9296, 0x0005, 0x0518,
+	0x2009, 0x1999, 0x2104, 0xc085, 0x200a, 0x2009, 0x1996, 0x2104,
+	0x8000, 0x200a, 0x9086, 0x0005, 0x0118, 0x080c, 0x2b4b, 0x00c0,
+	0x200b, 0x0000, 0x7a38, 0x9294, 0x0006, 0x9296, 0x0004, 0x0110,
+	0x9006, 0x0010, 0x2001, 0x0001, 0x080c, 0x2bd3, 0x2001, 0x1993,
+	0x2003, 0x0002, 0x0028, 0x2001, 0x1991, 0x2003, 0x0003, 0x0010,
+	0x080c, 0x2a18, 0x0005, 0x080c, 0x2b43, 0x0560, 0x2009, 0x199a,
+	0x2104, 0x8001, 0x200a, 0x080c, 0x2bf8, 0x1168, 0x7850, 0x9084,
+	0xefff, 0x7852, 0x2001, 0x1991, 0x2003, 0x0003, 0x2001, 0x1992,
+	0x2003, 0x0000, 0x00b8, 0x2009, 0x199a, 0x2104, 0x9005, 0x1118,
+	0x080c, 0x2b88, 0x0010, 0x080c, 0x2b58, 0x080c, 0x2b4b, 0x2009,
+	0x1996, 0x200b, 0x0000, 0x2001, 0x1993, 0x2003, 0x0001, 0x080c,
+	0x2a18, 0x0000, 0x0005, 0x04b9, 0x0508, 0x080c, 0x2bf8, 0x11b8,
+	0x7850, 0x9084, 0xefff, 0x7852, 0x2009, 0x1997, 0x2104, 0x8000,
+	0x200a, 0x9086, 0x0007, 0x0108, 0x0078, 0x2001, 0x199c, 0x2003,
+	0x000a, 0x2009, 0x1999, 0x2104, 0xc0fd, 0x200a, 0x0038, 0x0419,
+	0x2001, 0x1993, 0x2003, 0x0004, 0x080c, 0x2a43, 0x0005, 0x0099,
+	0x0168, 0x080c, 0x2bf8, 0x1138, 0x7850, 0x9084, 0xefff, 0x7852,
+	0x080c, 0x2a2f, 0x0018, 0x0079, 0x080c, 0x2a43, 0x0005, 0x080c,
+	0x0dc5, 0x080c, 0x0dc5, 0x2009, 0x199b, 0x2104, 0x8001, 0x200a,
+	0x090c, 0x2ba4, 0x0005, 0x7a38, 0x9294, 0x0005, 0x9296, 0x0005,
+	0x0110, 0x9006, 0x0010, 0x2001, 0x0001, 0x080c, 0x2bd3, 0x0005,
+	0x7a38, 0x9294, 0x0006, 0x9296, 0x0006, 0x0110, 0x9006, 0x0010,
+	0x2001, 0x0001, 0x080c, 0x2bb6, 0x0005, 0x2009, 0x1996, 0x2104,
+	0x8000, 0x200a, 0x9086, 0x0005, 0x0108, 0x0068, 0x200b, 0x0000,
+	0x7a38, 0x9294, 0x0006, 0x9296, 0x0006, 0x0110, 0x9006, 0x0010,
+	0x2001, 0x0001, 0x04d9, 0x7a38, 0x9294, 0x0005, 0x9296, 0x0005,
+	0x0110, 0x9006, 0x0010, 0x2001, 0x0001, 0x080c, 0x2bd3, 0x0005,
+	0x0086, 0x2001, 0x1999, 0x2004, 0x9084, 0x7fff, 0x090c, 0x0dc5,
+	0x2009, 0x1998, 0x2144, 0x8846, 0x280a, 0x9844, 0x0dd8, 0xd08c,
+	0x1120, 0xd084, 0x1120, 0x080c, 0x0dc5, 0x9006, 0x0010, 0x2001,
+	0x0001, 0x00a1, 0x008e, 0x0005, 0x0006, 0x0156, 0x2001, 0x1991,
+	0x20a9, 0x0009, 0x2003, 0x0000, 0x8000, 0x1f04, 0x2baa, 0x2001,
+	0x1998, 0x2003, 0x8000, 0x015e, 0x000e, 0x0005, 0x00f6, 0x2079,
+	0x0100, 0x9085, 0x0000, 0x0158, 0x7838, 0x9084, 0xfff9, 0x9085,
+	0x0004, 0x783a, 0x2009, 0x199e, 0x210c, 0x795a, 0x0050, 0x7838,
+	0x9084, 0xfffb, 0x9085, 0x0006, 0x783a, 0x2009, 0x199f, 0x210c,
+	0x795a, 0x00fe, 0x0005, 0x00f6, 0x2079, 0x0100, 0x9085, 0x0000,
+	0x0138, 0x7838, 0x9084, 0xfffa, 0x9085, 0x0004, 0x783a, 0x0030,
+	0x7838, 0x9084, 0xfffb, 0x9085, 0x0005, 0x783a, 0x00fe, 0x0005,
+	0x0006, 0x2001, 0x0100, 0x2004, 0x9082, 0x0007, 0x000e, 0x0005,
+	0x0006, 0x2001, 0x0100, 0x2004, 0x9082, 0x0009, 0x000e, 0x0005,
+	0x0156, 0x20a9, 0x0064, 0x7820, 0x080c, 0x2c83, 0xd09c, 0x1110,
+	0x1f04, 0x2bfb, 0x015e, 0x0005, 0x0126, 0x0016, 0x0006, 0x2091,
+	0x8000, 0x7850, 0x9085, 0x0040, 0x7852, 0x7850, 0x9084, 0xfbcf,
+	0x7852, 0x080c, 0x2c83, 0x9085, 0x2000, 0x7852, 0x000e, 0x2008,
+	0x9186, 0x0000, 0x1118, 0x783b, 0x0007, 0x0090, 0x9186, 0x0001,
+	0x1118, 0x783b, 0x0006, 0x0060, 0x9186, 0x0002, 0x1118, 0x783b,
+	0x0005, 0x0030, 0x9186, 0x0003, 0x1118, 0x783b, 0x0004, 0x0000,
+	0x0006, 0x1d04, 0x2c31, 0x080c, 0x87bd, 0x1f04, 0x2c31, 0x7850,
+	0x9085, 0x0400, 0x9084, 0xdfbf, 0x7852, 0x080c, 0x2c83, 0x9085,
+	0x1000, 0x7852, 0x000e, 0x001e, 0x012e, 0x0005, 0x7850, 0x9084,
+	0xffcf, 0x7852, 0x0005, 0x0006, 0x0156, 0x00f6, 0x2079, 0x0100,
+	0x20a9, 0x000a, 0x7854, 0xd0ac, 0x1130, 0x7820, 0xd0e4, 0x1140,
+	0x1f04, 0x2c55, 0x0028, 0x7854, 0xd08c, 0x1110, 0x1f04, 0x2c5b,
+	0x00fe, 0x015e, 0x000e, 0x0005, 0x1d04, 0x2c64, 0x080c, 0x87bd,
+	0x1f04, 0x2c64, 0x0005, 0x0006, 0x2001, 0x199d, 0x2004, 0x9086,
+	0x0000, 0x000e, 0x0005, 0x0006, 0x2001, 0x199d, 0x2004, 0x9086,
+	0x0001, 0x000e, 0x0005, 0x0006, 0x2001, 0x199d, 0x2004, 0x9086,
+	0x0002, 0x000e, 0x0005, 0xa001, 0xa001, 0xa001, 0xa001, 0xa001,
+	0x0005, 0x0006, 0x2001, 0x19a9, 0x2102, 0x000e, 0x0005, 0x2009,
+	0x0171, 0x2104, 0xd0dc, 0x0140, 0x2009, 0x0170, 0x2104, 0x200b,
+	0x0080, 0xa001, 0xa001, 0x200a, 0x0005, 0x0036, 0x0046, 0x2001,
+	0x0141, 0x200c, 0x918c, 0xff00, 0x9186, 0x2100, 0x0140, 0x9186,
+	0x2000, 0x0170, 0x9186, 0x0100, 0x1904, 0x2cfc, 0x0048, 0x0016,
+	0x2009, 0x1a88, 0x2104, 0x8000, 0x0208, 0x200a, 0x001e, 0x04f0,
+	0x2009, 0x00a2, 0x080c, 0x0e52, 0x2019, 0x0160, 0x2324, 0x2011,
+	0x0003, 0x2009, 0x0169, 0x2104, 0x9084, 0x0007, 0x210c, 0x918c,
+	0x0007, 0x910e, 0x1db0, 0x9086, 0x0003, 0x1548, 0x2304, 0x0066,
+	0x0076, 0x2031, 0x0002, 0x233c, 0x973e, 0x0148, 0x8631, 0x1dd8,
+	0x2031, 0x1a89, 0x263c, 0x8738, 0x0208, 0x2732, 0x2304, 0x007e,
+	0x006e, 0x9402, 0x02a0, 0x19d0, 0x8211, 0x19d8, 0x84ff, 0x0170,
+	0x2001, 0x0141, 0x200c, 0x918c, 0xff00, 0x9186, 0x0100, 0x0130,
+	0x2009, 0x180c, 0x2104, 0xc0dd, 0x200a, 0x0008, 0x0421, 0x2001,
+	0x1982, 0x200c, 0x080c, 0x0e52, 0x004e, 0x003e, 0x0005, 0x2001,
+	0x180c, 0x2004, 0xd0dc, 0x01b0, 0x2001, 0x0160, 0x2004, 0x9005,
+	0x0140, 0x2001, 0x0141, 0x2004, 0x9084, 0xff00, 0x9086, 0x0100,
+	0x1148, 0x0126, 0x2091, 0x8000, 0x0016, 0x0026, 0x0021, 0x002e,
+	0x001e, 0x012e, 0x0005, 0x00c6, 0x2061, 0x0100, 0x6014, 0x0006,
+	0x2001, 0x0161, 0x2003, 0x0000, 0x6017, 0x0018, 0xa001, 0xa001,
+	0x602f, 0x0008, 0x6104, 0x918e, 0x0010, 0x6106, 0x918e, 0x0010,
+	0x6106, 0x6017, 0x0040, 0x04b9, 0x001e, 0x9184, 0x0003, 0x01e0,
+	0x0036, 0x0016, 0x2019, 0x0141, 0x6124, 0x918c, 0x0028, 0x1120,
+	0x2304, 0x9084, 0x2800, 0x0dc0, 0x001e, 0x919c, 0xffe4, 0x9184,
+	0x0001, 0x0118, 0x9385, 0x0009, 0x6016, 0x9184, 0x0002, 0x0118,
+	0x9385, 0x0012, 0x6016, 0x003e, 0x2001, 0x180c, 0x200c, 0xc1dc,
+	0x2102, 0x00ce, 0x0005, 0x0016, 0x0026, 0x080c, 0x757d, 0x0108,
+	0xc0bc, 0x2009, 0x0140, 0x2114, 0x9294, 0x0001, 0x9215, 0x220a,
+	0x002e, 0x001e, 0x0005, 0x0016, 0x0026, 0x2009, 0x0140, 0x2114,
+	0x9294, 0x0001, 0x9285, 0x1000, 0x200a, 0x220a, 0x002e, 0x001e,
+	0x0005, 0x0016, 0x0026, 0x2009, 0x0140, 0x2114, 0x9294, 0x0001,
+	0x9215, 0x220a, 0x002e, 0x001e, 0x0005, 0x0006, 0x0016, 0x2009,
+	0x0140, 0x2104, 0x1128, 0x080c, 0x757d, 0x0110, 0xc0bc, 0x0008,
+	0xc0bd, 0x200a, 0x001e, 0x000e, 0x0005, 0x0006, 0x0156, 0x6050,
+	0x9085, 0x0040, 0x6052, 0x6050, 0x9084, 0xfbcf, 0x6052, 0x080c,
+	0x2c83, 0x9085, 0x2000, 0x6052, 0x20a9, 0x0012, 0x1d04, 0x2da6,
+	0x080c, 0x87bd, 0x1f04, 0x2da6, 0x6050, 0x9085, 0x0400, 0x9084,
+	0xdfbf, 0x6052, 0x015e, 0x000e, 0x0005, 0x3021, 0x3021, 0x2e45,
+	0x2e45, 0x2e51, 0x2e51, 0x2e5d, 0x2e5d, 0x2e6b, 0x2e6b, 0x2e77,
+	0x2e77, 0x2e85, 0x2e85, 0x2e93, 0x2e93, 0x2ea5, 0x2ea5, 0x2eb1,
+	0x2eb1, 0x2ebf, 0x2ebf, 0x2edd, 0x2edd, 0x2efd, 0x2efd, 0x2ecd,
+	0x2ecd, 0x2eed, 0x2eed, 0x2f0b, 0x2f0b, 0x2ea3, 0x2ea3, 0x2ea3,
+	0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3,
+	0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3,
+	0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3,
+	0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2f1d, 0x2f1d, 0x2f29,
+	0x2f29, 0x2f37, 0x2f37, 0x2f45, 0x2f45, 0x2f55, 0x2f55, 0x2f63,
+	0x2f63, 0x2f73, 0x2f73, 0x2f83, 0x2f83, 0x2f95, 0x2f95, 0x2fa3,
+	0x2fa3, 0x2fb3, 0x2fb3, 0x2fd5, 0x2fd5, 0x2ff7, 0x2ff7, 0x2fc3,
+	0x2fc3, 0x2fe6, 0x2fe6, 0x3006, 0x3006, 0x2ea3, 0x2ea3, 0x2ea3,
+	0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3,
+	0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3,
+	0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3,
+	0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3,
+	0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3,
+	0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x2ea3, 0x0106, 0x0006, 0x0126,
+	0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x24d9, 0x0804,
+	0x3019, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146,
+	0x0156, 0x080c, 0x22ed, 0x0804, 0x3019, 0x0106, 0x0006, 0x0126,
+	0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x22ed, 0x080c,
+	0x24d9, 0x0804, 0x3019, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
+	0x0136, 0x0146, 0x0156, 0x080c, 0x2328, 0x0804, 0x3019, 0x0106,
+	0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c,
+	0x24d9, 0x080c, 0x2328, 0x0804, 0x3019, 0x0106, 0x0006, 0x0126,
+	0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x22ed, 0x080c,
+	0x2328, 0x0804, 0x3019, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
+	0x0136, 0x0146, 0x0156, 0x080c, 0x22ed, 0x080c, 0x24d9, 0x080c,
+	0x2328, 0x0804, 0x3019, 0xa001, 0x0cf0, 0x0106, 0x0006, 0x0126,
+	0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x1394, 0x0804,
+	0x3019, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146,
+	0x0156, 0x080c, 0x24d9, 0x080c, 0x1394, 0x0804, 0x3019, 0x0106,
+	0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c,
+	0x22ed, 0x080c, 0x1394, 0x0804, 0x3019, 0x0106, 0x0006, 0x0126,
+	0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x24d9, 0x080c,
+	0x1394, 0x080c, 0x2328, 0x0804, 0x3019, 0x0106, 0x0006, 0x0126,
+	0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x22ed, 0x080c,
+	0x24d9, 0x080c, 0x1394, 0x0804, 0x3019, 0x0106, 0x0006, 0x0126,
+	0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x22ed, 0x080c,
+	0x1394, 0x080c, 0x2328, 0x0804, 0x3019, 0x0106, 0x0006, 0x0126,
+	0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x1394, 0x080c,
+	0x2328, 0x0804, 0x3019, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
+	0x0136, 0x0146, 0x0156, 0x080c, 0x22ed, 0x080c, 0x24d9, 0x080c,
+	0x1394, 0x080c, 0x2328, 0x0804, 0x3019, 0x0106, 0x0006, 0x0126,
+	0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x298c, 0x0804,
+	0x3019, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146,
+	0x0156, 0x080c, 0x298c, 0x080c, 0x24d9, 0x0804, 0x3019, 0x0106,
+	0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c,
+	0x298c, 0x080c, 0x22ed, 0x0804, 0x3019, 0x0106, 0x0006, 0x0126,
+	0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x298c, 0x080c,
+	0x22ed, 0x080c, 0x24d9, 0x0804, 0x3019, 0x0106, 0x0006, 0x0126,
+	0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x298c, 0x080c,
+	0x2328, 0x0804, 0x3019, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
+	0x0136, 0x0146, 0x0156, 0x080c, 0x298c, 0x080c, 0x24d9, 0x080c,
+	0x2328, 0x0804, 0x3019, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
+	0x0136, 0x0146, 0x0156, 0x080c, 0x298c, 0x080c, 0x22ed, 0x080c,
+	0x2328, 0x0804, 0x3019, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
+	0x0136, 0x0146, 0x0156, 0x080c, 0x298c, 0x080c, 0x22ed, 0x080c,
+	0x24d9, 0x080c, 0x2328, 0x0804, 0x3019, 0x0106, 0x0006, 0x0126,
+	0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x298c, 0x080c,
+	0x1394, 0x0804, 0x3019, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
+	0x0136, 0x0146, 0x0156, 0x080c, 0x298c, 0x080c, 0x24d9, 0x080c,
+	0x1394, 0x0804, 0x3019, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
+	0x0136, 0x0146, 0x0156, 0x080c, 0x298c, 0x080c, 0x22ed, 0x080c,
+	0x1394, 0x0804, 0x3019, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
+	0x0136, 0x0146, 0x0156, 0x080c, 0x298c, 0x080c, 0x24d9, 0x080c,
+	0x1394, 0x080c, 0x2328, 0x0804, 0x3019, 0x0106, 0x0006, 0x0126,
+	0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x298c, 0x080c,
+	0x22ed, 0x080c, 0x24d9, 0x080c, 0x1394, 0x0498, 0x0106, 0x0006,
+	0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x298c,
+	0x080c, 0x22ed, 0x080c, 0x1394, 0x080c, 0x2328, 0x0410, 0x0106,
+	0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c,
+	0x298c, 0x080c, 0x1394, 0x080c, 0x2328, 0x0098, 0x0106, 0x0006,
+	0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x298c,
+	0x080c, 0x22ed, 0x080c, 0x24d9, 0x080c, 0x1394, 0x080c, 0x2328,
+	0x0000, 0x015e, 0x014e, 0x013e, 0x01de, 0x01ce, 0x012e, 0x000e,
+	0x010e, 0x000d, 0x00b6, 0x00c6, 0x0026, 0x0046, 0x9026, 0x080c,
+	0x6a4a, 0x1904, 0x3132, 0x72dc, 0x2001, 0x197d, 0x2004, 0x9005,
+	0x1110, 0xd29c, 0x0148, 0xd284, 0x1138, 0xd2bc, 0x1904, 0x3132,
+	0x080c, 0x3137, 0x0804, 0x3132, 0xd2cc, 0x1904, 0x3132, 0x080c,
+	0x7563, 0x1120, 0x70af, 0xffff, 0x0804, 0x3132, 0xd294, 0x0120,
+	0x70af, 0xffff, 0x0804, 0x3132, 0x080c, 0x33a0, 0x0160, 0x080c,
+	0xd548, 0x0128, 0x2001, 0x1818, 0x203c, 0x0804, 0x30bf, 0x70af,
+	0xffff, 0x0804, 0x3132, 0x2001, 0x1818, 0x203c, 0x7294, 0xd284,
+	0x0904, 0x30bf, 0xd28c, 0x1904, 0x30bf, 0x0036, 0x73ac, 0x938e,
+	0xffff, 0x1110, 0x2019, 0x0001, 0x8314, 0x92e0, 0x1c80, 0x2c04,
+	0x938c, 0x0001, 0x0120, 0x9084, 0xff00, 0x8007, 0x0010, 0x9084,
+	0x00ff, 0x970e, 0x05d0, 0x908e, 0x0000, 0x05b8, 0x908e, 0x00ff,
+	0x1150, 0x7230, 0xd284, 0x15b0, 0x7294, 0xc28d, 0x7296, 0x70af,
+	0xffff, 0x003e, 0x04a0, 0x900e, 0x080c, 0x2889, 0x080c, 0x66ac,
+	0x1538, 0x9006, 0xb8bb, 0x0520, 0xb8ac, 0x9005, 0x0148, 0x00c6,
+	0x2060, 0x080c, 0x8bbd, 0x00ce, 0x090c, 0x8f5e, 0xb8af, 0x0000,
+	0x080c, 0x6a8c, 0x1168, 0x7030, 0xd08c, 0x0130, 0xb800, 0xd0bc,
+	0x0138, 0x080c, 0x6937, 0x0120, 0x080c, 0x3150, 0x0148, 0x0028,
+	0x080c, 0x3290, 0x080c, 0x317c, 0x0118, 0x8318, 0x0804, 0x306c,
+	0x73ae, 0x0010, 0x70af, 0xffff, 0x003e, 0x0804, 0x3132, 0x9780,
+	0x33b1, 0x203d, 0x97bc, 0xff00, 0x873f, 0x2041, 0x007e, 0x70ac,
+	0x9096, 0xffff, 0x1118, 0x900e, 0x28a8, 0x0050, 0x9812, 0x0220,
+	0x2008, 0x9802, 0x20a8, 0x0020, 0x70af, 0xffff, 0x0804, 0x3132,
+	0x2700, 0x0156, 0x0016, 0x9106, 0x0904, 0x3127, 0xc484, 0x080c,
+	0x6717, 0x0148, 0x080c, 0xd548, 0x1904, 0x3127, 0x080c, 0x66ac,
+	0x1904, 0x312f, 0x0008, 0xc485, 0xb8bb, 0x0520, 0xb8ac, 0x9005,
+	0x0148, 0x00c6, 0x2060, 0x080c, 0x8bbd, 0x00ce, 0x090c, 0x8f5e,
+	0xb8af, 0x0000, 0x080c, 0x6a8c, 0x1130, 0x7030, 0xd08c, 0x01f8,
+	0xb800, 0xd0bc, 0x11e0, 0x7294, 0xd28c, 0x0180, 0x080c, 0x6a8c,
+	0x9082, 0x0006, 0x02e0, 0xd484, 0x1118, 0x080c, 0x66d1, 0x0028,
+	0x080c, 0x331c, 0x01a0, 0x080c, 0x3347, 0x0088, 0x080c, 0x3290,
+	0x080c, 0xd548, 0x1160, 0x080c, 0x317c, 0x0188, 0x0040, 0x080c,
+	0xd548, 0x1118, 0x080c, 0x331c, 0x0110, 0x0451, 0x0140, 0x001e,
+	0x8108, 0x015e, 0x1f04, 0x30d8, 0x70af, 0xffff, 0x0018, 0x001e,
+	0x015e, 0x71ae, 0x004e, 0x002e, 0x00ce, 0x00be, 0x0005, 0x00c6,
+	0x0016, 0x70af, 0x0001, 0x2009, 0x007e, 0x080c, 0x66ac, 0x1168,
+	0xb813, 0x00ff, 0xb817, 0xfffe, 0x080c, 0x3290, 0x04a9, 0x0128,
+	0x70dc, 0xc0bd, 0x70de, 0x080c, 0xd292, 0x001e, 0x00ce, 0x0005,
+	0x0016, 0x0076, 0x00d6, 0x00c6, 0x2001, 0x184c, 0x2004, 0x9084,
+	0x00ff, 0xb842, 0x080c, 0xb139, 0x01d0, 0x2b00, 0x6012, 0x080c,
+	0xd2bb, 0x6023, 0x0001, 0x9006, 0x080c, 0x6649, 0x2001, 0x0000,
+	0x080c, 0x665d, 0x0126, 0x2091, 0x8000, 0x70a8, 0x8000, 0x70aa,
+	0x012e, 0x2009, 0x0004, 0x080c, 0xb166, 0x9085, 0x0001, 0x00ce,
+	0x00de, 0x007e, 0x001e, 0x0005, 0x0016, 0x0076, 0x00d6, 0x00c6,
+	0x2001, 0x184c, 0x2004, 0x9084, 0x00ff, 0xb842, 0x080c, 0xb139,
+	0x0548, 0x2b00, 0x6012, 0xb800, 0xc0c4, 0xb802, 0xb8a0, 0x9086,
+	0x007e, 0x0140, 0xb804, 0x9084, 0x00ff, 0x9086, 0x0006, 0x1110,
+	0x080c, 0x324b, 0x080c, 0xd2bb, 0x6023, 0x0001, 0x9006, 0x080c,
+	0x6649, 0x2001, 0x0002, 0x080c, 0x665d, 0x0126, 0x2091, 0x8000,
+	0x70a8, 0x8000, 0x70aa, 0x012e, 0x2009, 0x0002, 0x080c, 0xb166,
+	0x9085, 0x0001, 0x00ce, 0x00de, 0x007e, 0x001e, 0x0005, 0x00b6,
+	0x00c6, 0x0026, 0x2009, 0x0080, 0x080c, 0x66ac, 0x1140, 0xb813,
+	0x00ff, 0xb817, 0xfffc, 0x0039, 0x0110, 0x70e3, 0xffff, 0x002e,
+	0x00ce, 0x00be, 0x0005, 0x0016, 0x0076, 0x00d6, 0x00c6, 0x080c,
+	0xb091, 0x01d0, 0x2b00, 0x6012, 0x080c, 0xd2bb, 0x6023, 0x0001,
+	0x9006, 0x080c, 0x6649, 0x2001, 0x0002, 0x080c, 0x665d, 0x0126,
+	0x2091, 0x8000, 0x70e4, 0x8000, 0x70e6, 0x012e, 0x2009, 0x0002,
+	0x080c, 0xb166, 0x9085, 0x0001, 0x00ce, 0x00de, 0x007e, 0x001e,
+	0x0005, 0x00c6, 0x00d6, 0x0126, 0x2091, 0x8000, 0x2009, 0x007f,
+	0x080c, 0x66ac, 0x11b8, 0xb813, 0x00ff, 0xb817, 0xfffd, 0xb8cf,
+	0x0004, 0x080c, 0xb091, 0x0170, 0x2b00, 0x6012, 0x6316, 0x6023,
+	0x0001, 0x620a, 0x080c, 0xd2bb, 0x2009, 0x0022, 0x080c, 0xb166,
+	0x9085, 0x0001, 0x012e, 0x00de, 0x00ce, 0x0005, 0x00e6, 0x00c6,
+	0x0066, 0x0036, 0x0026, 0x00b6, 0x21f0, 0x080c, 0x94e5, 0x080c,
+	0x9465, 0x080c, 0xaf25, 0x080c, 0xc041, 0x3e08, 0x2130, 0x81ff,
+	0x0120, 0x20a9, 0x007e, 0x900e, 0x0018, 0x20a9, 0x007f, 0x900e,
+	0x0016, 0x080c, 0x6717, 0x1140, 0x9686, 0x0002, 0x1118, 0xb800,
+	0xd0bc, 0x1110, 0x080c, 0x613b, 0x001e, 0x8108, 0x1f04, 0x3230,
+	0x9686, 0x0001, 0x190c, 0x3374, 0x00be, 0x002e, 0x003e, 0x006e,
+	0x00ce, 0x00ee, 0x0005, 0x00e6, 0x00c6, 0x0046, 0x0036, 0x0026,
+	0x0016, 0x00b6, 0x6210, 0x2258, 0xbaa0, 0x0026, 0x2019, 0x0029,
+	0x080c, 0x94da, 0x0076, 0x2039, 0x0000, 0x080c, 0x93ad, 0x2c08,
+	0x080c, 0xe671, 0x007e, 0x001e, 0xba10, 0xbb14, 0xbcc0, 0x080c,
+	0x613b, 0xba12, 0xbb16, 0xbcc2, 0x00be, 0x001e, 0x002e, 0x003e,
+	0x004e, 0x00ce, 0x00ee, 0x0005, 0x00e6, 0x0006, 0x00b6, 0x6010,
+	0x2058, 0xb8a0, 0x00be, 0x9086, 0x0080, 0x0150, 0x2071, 0x1800,
+	0x70a8, 0x9005, 0x0110, 0x8001, 0x70aa, 0x000e, 0x00ee, 0x0005,
+	0x2071, 0x1800, 0x70e4, 0x9005, 0x0dc0, 0x8001, 0x70e6, 0x0ca8,
+	0xb800, 0xc08c, 0xb802, 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x00b6,
+	0x0046, 0x0036, 0x0026, 0x0016, 0x0156, 0x2178, 0x81ff, 0x1118,
+	0x20a9, 0x0001, 0x0078, 0x080c, 0x57cd, 0xd0c4, 0x0140, 0xd0a4,
+	0x0130, 0x9006, 0x2020, 0x2009, 0x002d, 0x080c, 0xe940, 0x20a9,
+	0x0800, 0x9016, 0x0026, 0x928e, 0x007e, 0x0904, 0x32fb, 0x928e,
+	0x007f, 0x0904, 0x32fb, 0x928e, 0x0080, 0x05e8, 0x9288, 0x1000,
+	0x210c, 0x81ff, 0x05c0, 0x8fff, 0x1148, 0x2001, 0x198f, 0x0006,
+	0x2003, 0x0001, 0x04f1, 0x000e, 0x2003, 0x0000, 0x00b6, 0x00c6,
+	0x2158, 0x2001, 0x0001, 0x080c, 0x6a56, 0x00ce, 0x00be, 0x2019,
+	0x0029, 0x080c, 0x94da, 0x0076, 0x2039, 0x0000, 0x080c, 0x93ad,
+	0x00b6, 0x00c6, 0x0026, 0x2158, 0xba04, 0x9294, 0x00ff, 0x9286,
+	0x0006, 0x1118, 0xb807, 0x0404, 0x0028, 0x2001, 0x0004, 0x8007,
+	0x9215, 0xba06, 0x002e, 0x00ce, 0x00be, 0x0016, 0x2c08, 0x080c,
+	0xe671, 0x001e, 0x007e, 0x002e, 0x8210, 0x1f04, 0x32b2, 0x015e,
+	0x001e, 0x002e, 0x003e, 0x004e, 0x00be, 0x00ce, 0x00ee, 0x00fe,
+	0x0005, 0x0046, 0x0026, 0x0016, 0x080c, 0x57cd, 0xd0c4, 0x0140,
+	0xd0a4, 0x0130, 0x9006, 0x2220, 0x2009, 0x0029, 0x080c, 0xe940,
+	0x001e, 0x002e, 0x004e, 0x0005, 0x0016, 0x0026, 0x0036, 0x00c6,
+	0x7294, 0x82ff, 0x01e8, 0x080c, 0x6a84, 0x11d0, 0x2100, 0x080c,
+	0x28bc, 0x81ff, 0x01b8, 0x2019, 0x0001, 0x8314, 0x92e0, 0x1c80,
+	0x2c04, 0xd384, 0x0120, 0x9084, 0xff00, 0x8007, 0x0010, 0x9084,
+	0x00ff, 0x9116, 0x0138, 0x9096, 0x00ff, 0x0110, 0x8318, 0x0c68,
+	0x9085, 0x0001, 0x00ce, 0x003e, 0x002e, 0x001e, 0x0005, 0x0016,
+	0x00c6, 0x0126, 0x2091, 0x8000, 0x0036, 0x2019, 0x0029, 0x00a9,
+	0x003e, 0x9180, 0x1000, 0x2004, 0x9065, 0x0158, 0x0016, 0x00c6,
+	0x2061, 0x1ab8, 0x001e, 0x6112, 0x080c, 0x324b, 0x001e, 0x080c,
+	0x66d1, 0x012e, 0x00ce, 0x001e, 0x0005, 0x0016, 0x0026, 0x2110,
+	0x080c, 0xaa80, 0x080c, 0xecaa, 0x002e, 0x001e, 0x0005, 0x2001,
+	0x1837, 0x2004, 0xd0cc, 0x0005, 0x00c6, 0x00b6, 0x080c, 0x7563,
+	0x1118, 0x20a9, 0x0800, 0x0010, 0x20a9, 0x0782, 0x080c, 0x7563,
+	0x1110, 0x900e, 0x0010, 0x2009, 0x007e, 0x9180, 0x1000, 0x2004,
+	0x905d, 0x0130, 0x86ff, 0x0110, 0xb800, 0xd0bc, 0x090c, 0x66d1,
+	0x8108, 0x1f04, 0x3385, 0x2061, 0x1800, 0x607f, 0x0000, 0x6080,
+	0x9084, 0x00ff, 0x6082, 0x60b3, 0x0000, 0x00be, 0x00ce, 0x0005,
+	0x2001, 0x1869, 0x2004, 0xd0bc, 0x0005, 0x2011, 0x1848, 0x2214,
+	0xd2ec, 0x0005, 0x0026, 0x2011, 0x1867, 0x2214, 0xd2dc, 0x002e,
+	0x0005, 0x7eef, 0x7de8, 0x7ce4, 0x80e2, 0x7be1, 0x80e0, 0x80dc,
+	0x80da, 0x7ad9, 0x80d6, 0x80d5, 0x80d4, 0x80d3, 0x80d2, 0x80d1,
+	0x79ce, 0x78cd, 0x80cc, 0x80cb, 0x80ca, 0x80c9, 0x80c7, 0x80c6,
+	0x77c5, 0x76c3, 0x80bc, 0x80ba, 0x75b9, 0x80b6, 0x74b5, 0x73b4,
+	0x72b3, 0x80b2, 0x80b1, 0x80ae, 0x71ad, 0x80ac, 0x70ab, 0x6faa,
+	0x6ea9, 0x80a7, 0x6da6, 0x6ca5, 0x6ba3, 0x6a9f, 0x699e, 0x689d,
+	0x809b, 0x8098, 0x6797, 0x6690, 0x658f, 0x6488, 0x6384, 0x6282,
+	0x8081, 0x8080, 0x617c, 0x607a, 0x8079, 0x5f76, 0x8075, 0x8074,
+	0x8073, 0x8072, 0x8071, 0x806e, 0x5e6d, 0x806c, 0x5d6b, 0x5c6a,
+	0x5b69, 0x8067, 0x5a66, 0x5965, 0x5863, 0x575c, 0x565a, 0x5559,
+	0x8056, 0x8055, 0x5454, 0x5353, 0x5252, 0x5151, 0x504e, 0x4f4d,
+	0x804c, 0x804b, 0x4e4a, 0x4d49, 0x8047, 0x4c46, 0x8045, 0x8043,
+	0x803c, 0x803a, 0x8039, 0x8036, 0x4b35, 0x8034, 0x4a33, 0x4932,
+	0x4831, 0x802e, 0x472d, 0x462c, 0x452b, 0x442a, 0x4329, 0x4227,
+	0x8026, 0x8025, 0x4123, 0x401f, 0x3f1e, 0x3e1d, 0x3d1b, 0x3c18,
+	0x8017, 0x8010, 0x3b0f, 0x3a08, 0x8004, 0x3902, 0x8001, 0x8000,
+	0x8000, 0x3800, 0x3700, 0x3600, 0x8000, 0x3500, 0x8000, 0x8000,
+	0x8000, 0x3400, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
+	0x3300, 0x3200, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
+	0x3100, 0x3000, 0x8000, 0x8000, 0x2f00, 0x8000, 0x2e00, 0x2d00,
+	0x2c00, 0x8000, 0x8000, 0x8000, 0x2b00, 0x8000, 0x2a00, 0x2900,
+	0x2800, 0x8000, 0x2700, 0x2600, 0x2500, 0x2400, 0x2300, 0x2200,
+	0x8000, 0x8000, 0x2100, 0x2000, 0x1f00, 0x1e00, 0x1d00, 0x1c00,
+	0x8000, 0x8000, 0x1b00, 0x1a00, 0x8000, 0x1900, 0x8000, 0x8000,
+	0x8000, 0x8000, 0x8000, 0x8000, 0x1800, 0x8000, 0x1700, 0x1600,
+	0x1500, 0x8000, 0x1400, 0x1300, 0x1200, 0x1100, 0x1000, 0x0f00,
+	0x8000, 0x8000, 0x0e00, 0x0d00, 0x0c00, 0x0b00, 0x0a00, 0x0900,
+	0x8000, 0x8000, 0x0800, 0x0700, 0x8000, 0x0600, 0x8000, 0x8000,
+	0x8000, 0x0500, 0x0400, 0x0300, 0x8000, 0x0200, 0x8000, 0x8000,
+	0x8000, 0x0100, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
+	0x0000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
 	0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
-	0x8000, 0x8000, 0x8000, 0x8000, 0x2071, 0x189e, 0x7003, 0x0002,
-	0x9006, 0x7016, 0x701a, 0x704a, 0x704e, 0x700e, 0x7042, 0x7046,
-	0x703b, 0x18ba, 0x703f, 0x18ba, 0x7007, 0x0001, 0x080c, 0x1018,
-	0x090c, 0x0dd5, 0x2900, 0x706a, 0xa867, 0x0002, 0xa8ab, 0xdcb0,
-	0x080c, 0x1018, 0x090c, 0x0dd5, 0x2900, 0x706e, 0xa867, 0x0002,
-	0xa8ab, 0xdcb0, 0x0005, 0x2071, 0x189e, 0x7004, 0x0002, 0x34b3,
-	0x34b4, 0x34c7, 0x34db, 0x0005, 0x1004, 0x34c4, 0x0e04, 0x34c4,
-	0x2079, 0x0000, 0x0126, 0x2091, 0x8000, 0x700c, 0x9005, 0x1128,
-	0x700f, 0x0001, 0x012e, 0x0468, 0x0005, 0x012e, 0x0ce8, 0x2079,
-	0x0000, 0x2061, 0x18b8, 0x2c4c, 0xa86c, 0x908e, 0x0100, 0x0128,
-	0x9086, 0x0200, 0x0904, 0x35af, 0x0005, 0x7018, 0x2048, 0x2061,
-	0x1800, 0x701c, 0x0807, 0x7014, 0x2048, 0xa864, 0x9094, 0x00ff,
-	0x9296, 0x0029, 0x1120, 0xaa78, 0xd2fc, 0x0128, 0x0005, 0x9086,
-	0x0103, 0x0108, 0x0005, 0x2079, 0x0000, 0x2061, 0x1800, 0x701c,
-	0x0807, 0x2061, 0x1800, 0x7880, 0x908a, 0x0040, 0x1210, 0x61d0,
-	0x0042, 0x2100, 0x908a, 0x003f, 0x1a04, 0x35ac, 0x61d0, 0x0804,
-	0x3541, 0x3583, 0x35bb, 0x35ac, 0x35c5, 0x35cf, 0x35d5, 0x35d9,
-	0x35e9, 0x35ed, 0x3603, 0x3609, 0x360f, 0x361a, 0x3625, 0x3634,
-	0x3643, 0x3651, 0x3668, 0x3683, 0x35ac, 0x372c, 0x376a, 0x3810,
-	0x3821, 0x3844, 0x35ac, 0x35ac, 0x35ac, 0x387c, 0x3898, 0x38a1,
-	0x38d0, 0x38d6, 0x35ac, 0x391c, 0x35ac, 0x35ac, 0x35ac, 0x35ac,
-	0x35ac, 0x3927, 0x3930, 0x3938, 0x393a, 0x35ac, 0x35ac, 0x35ac,
-	0x35ac, 0x35ac, 0x35ac, 0x3966, 0x35ac, 0x35ac, 0x35ac, 0x35ac,
-	0x35ac, 0x3983, 0x39e4, 0x35ac, 0x35ac, 0x35ac, 0x35ac, 0x35ac,
-	0x35ac, 0x0002, 0x3a0e, 0x3a11, 0x3a70, 0x3a89, 0x3ab9, 0x3d57,
-	0x35ac, 0x5321, 0x35ac, 0x35ac, 0x35ac, 0x35ac, 0x35ac, 0x35ac,
-	0x35ac, 0x35ac, 0x3603, 0x3609, 0x4278, 0x5781, 0x4296, 0x53b0,
-	0x5401, 0x550c, 0x35ac, 0x556e, 0x55aa, 0x55db, 0x56e3, 0x5608,
-	0x5663, 0x35ac, 0x429a, 0x445b, 0x4471, 0x4496, 0x44fb, 0x456f,
-	0x458f, 0x4606, 0x4662, 0x46be, 0x46c1, 0x46e6, 0x4791, 0x47f7,
-	0x47ff, 0x4931, 0x4aa9, 0x4add, 0x4d41, 0x35ac, 0x4d5f, 0x4e05,
-	0x4ee7, 0x4f41, 0x35ac, 0x4ff8, 0x35ac, 0x5060, 0x507b, 0x47ff,
-	0x52c1, 0x714c, 0x0000, 0x2021, 0x4000, 0x080c, 0x4b5b, 0x0126,
-	0x2091, 0x8000, 0x0e04, 0x358d, 0x0010, 0x012e, 0x0cc0, 0x7c36,
-	0x9486, 0x4000, 0x0118, 0x7833, 0x0011, 0x0010, 0x7833, 0x0010,
-	0x7c82, 0x7986, 0x7a8a, 0x7b8e, 0x2091, 0x4080, 0x2001, 0x0089,
-	0x2004, 0xd084, 0x190c, 0x119b, 0x7007, 0x0001, 0x2091, 0x5000,
-	0x700f, 0x0000, 0x012e, 0x0005, 0x2021, 0x4001, 0x08b0, 0x2021,
-	0x4002, 0x0898, 0x2021, 0x4003, 0x0880, 0x2021, 0x4005, 0x0868,
-	0x2021, 0x4006, 0x0850, 0x2039, 0x0001, 0x902e, 0x2520, 0x7b88,
-	0x7a8c, 0x7884, 0x7990, 0x0804, 0x4b68, 0x2039, 0x0001, 0x902e,
-	0x2520, 0x7b88, 0x7a8c, 0x7884, 0x7990, 0x0804, 0x4b6b, 0x7984,
-	0x7888, 0x2114, 0x200a, 0x0804, 0x3583, 0x7984, 0x2114, 0x0804,
-	0x3583, 0x20e1, 0x0000, 0x2099, 0x0021, 0x20e9, 0x0000, 0x20a1,
-	0x0021, 0x20a9, 0x001f, 0x4003, 0x7984, 0x7a88, 0x7b8c, 0x0804,
-	0x3583, 0x7884, 0x2060, 0x0804, 0x3636, 0x2009, 0x0003, 0x2011,
-	0x0003, 0x2019, 0x0008, 0x789b, 0x0137, 0x7893, 0xffff, 0x2001,
-	0x188f, 0x2004, 0x9005, 0x0118, 0x7896, 0x0804, 0x3583, 0x7897,
-	0x0001, 0x0804, 0x3583, 0x2039, 0x0001, 0x7d98, 0x7c9c, 0x0804,
-	0x35bf, 0x2039, 0x0001, 0x7d98, 0x7c9c, 0x0804, 0x35c9, 0x79a0,
-	0x9182, 0x0040, 0x0210, 0x0804, 0x35b8, 0x2138, 0x7d98, 0x7c9c,
-	0x0804, 0x35bf, 0x79a0, 0x9182, 0x0040, 0x0210, 0x0804, 0x35b8,
-	0x2138, 0x7d98, 0x7c9c, 0x0804, 0x35c9, 0x79a0, 0x9182, 0x0040,
-	0x0210, 0x0804, 0x35b8, 0x21e8, 0x7984, 0x7888, 0x20a9, 0x0001,
-	0x21a0, 0x4004, 0x0804, 0x3583, 0x2061, 0x0800, 0xe10c, 0x9006,
-	0x2c15, 0x9200, 0x8c60, 0x8109, 0x1dd8, 0x2010, 0x9005, 0x0904,
-	0x3583, 0x0804, 0x35b2, 0x79a0, 0x9182, 0x0040, 0x0210, 0x0804,
-	0x35b8, 0x21e0, 0x20a9, 0x0001, 0x7984, 0x2198, 0x4012, 0x0804,
-	0x3583, 0x2069, 0x1847, 0x7884, 0x7990, 0x911a, 0x1a04, 0x35b8,
-	0x8019, 0x0904, 0x35b8, 0x684a, 0x6942, 0x788c, 0x6852, 0x7888,
-	0x6856, 0x9006, 0x685a, 0x685e, 0x080c, 0x7755, 0x0804, 0x3583,
-	0x2069, 0x1847, 0x7884, 0x7994, 0x911a, 0x1a04, 0x35b8, 0x8019,
-	0x0904, 0x35b8, 0x684e, 0x6946, 0x788c, 0x6862, 0x7888, 0x6866,
-	0x9006, 0x686a, 0x686e, 0x0126, 0x2091, 0x8000, 0x080c, 0x6a72,
-	0x012e, 0x0804, 0x3583, 0x902e, 0x2520, 0x81ff, 0x0120, 0x2009,
-	0x0001, 0x0804, 0x35b5, 0x7984, 0x7b88, 0x7a8c, 0x20a9, 0x0005,
-	0x20e9, 0x0001, 0x20a1, 0x18a6, 0x4101, 0x080c, 0x4b1f, 0x1120,
-	0x2009, 0x0002, 0x0804, 0x35b5, 0x2009, 0x0020, 0xa85c, 0x9080,
-	0x0019, 0xaf60, 0x080c, 0x4b68, 0x701f, 0x36a7, 0x0005, 0xa864,
-	0x2008, 0x9084, 0x00ff, 0x9096, 0x0011, 0x0168, 0x9096, 0x0019,
-	0x0150, 0x9096, 0x0015, 0x0138, 0x9096, 0x0048, 0x0120, 0x9096,
-	0x0029, 0x1904, 0x35b5, 0x810f, 0x918c, 0x00ff, 0x0904, 0x35b5,
-	0x7112, 0x7010, 0x8001, 0x0560, 0x7012, 0x080c, 0x4b1f, 0x1120,
-	0x2009, 0x0002, 0x0804, 0x35b5, 0x2009, 0x0020, 0x7068, 0x2040,
-	0xa28c, 0xa390, 0xa494, 0xa598, 0x9290, 0x0040, 0x9399, 0x0000,
-	0x94a1, 0x0000, 0x95a9, 0x0000, 0xa85c, 0x9080, 0x0019, 0xaf60,
-	0x080c, 0x4b68, 0x701f, 0x36e5, 0x0005, 0xa864, 0x9084, 0x00ff,
-	0x9096, 0x0002, 0x0120, 0x9096, 0x000a, 0x1904, 0x35b5, 0x0888,
-	0x7014, 0x2048, 0xa868, 0xc0fd, 0xa86a, 0xa864, 0x9084, 0x00ff,
-	0x9096, 0x0029, 0x1160, 0xc2fd, 0xaa7a, 0x080c, 0x621e, 0x0150,
-	0x0126, 0x2091, 0x8000, 0xa87a, 0xa982, 0x012e, 0x0050, 0x080c,
-	0x654e, 0x1128, 0x7007, 0x0003, 0x701f, 0x3711, 0x0005, 0x080c,
-	0x6f4a, 0x0126, 0x2091, 0x8000, 0x20a9, 0x0005, 0x20e1, 0x0001,
-	0x2099, 0x18a6, 0x400a, 0x2100, 0x9210, 0x9399, 0x0000, 0x94a1,
-	0x0000, 0x95a9, 0x0000, 0xa85c, 0x9080, 0x0019, 0x2009, 0x0020,
-	0x012e, 0xaf60, 0x0804, 0x4b6b, 0x2091, 0x8000, 0x7837, 0x4000,
-	0x7833, 0x0010, 0x7883, 0x4000, 0x7887, 0x4953, 0x788b, 0x5020,
-	0x788f, 0x2020, 0x2009, 0x017f, 0x2104, 0x7892, 0x3f00, 0x7896,
-	0x2061, 0x0100, 0x6200, 0x2061, 0x0200, 0x603c, 0x8007, 0x9205,
-	0x789a, 0x2009, 0x04fd, 0x2104, 0x789e, 0x2091, 0x5000, 0x2091,
-	0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x0180, 0x2001, 0x1a18,
-	0x2004, 0x9005, 0x0128, 0x2001, 0x008b, 0x2004, 0xd0fc, 0x0dd8,
-	0x2001, 0x008a, 0x2003, 0x0002, 0x2003, 0x1001, 0x2071, 0x0080,
-	0x0804, 0x0427, 0x81ff, 0x1904, 0x35b5, 0x7984, 0x080c, 0x6699,
-	0x1904, 0x35b8, 0x7e98, 0x9684, 0x3fff, 0x9082, 0x4000, 0x1a04,
-	0x35b8, 0x7c88, 0x7d8c, 0x080c, 0x67fc, 0x080c, 0x67cb, 0x0000,
-	0x1518, 0x2061, 0x1cd0, 0x0126, 0x2091, 0x8000, 0x6000, 0x9086,
-	0x0000, 0x0148, 0x6014, 0x904d, 0x0130, 0xa86c, 0x9406, 0x1118,
-	0xa870, 0x9506, 0x0150, 0x012e, 0x9ce0, 0x0018, 0x2001, 0x181a,
-	0x2004, 0x9c02, 0x1a04, 0x35b5, 0x0c30, 0x080c, 0xc8a5, 0x012e,
-	0x0904, 0x35b5, 0x0804, 0x3583, 0x900e, 0x2001, 0x0005, 0x080c,
-	0x6f4a, 0x0126, 0x2091, 0x8000, 0x080c, 0xcf82, 0x080c, 0x6d17,
-	0x012e, 0x0804, 0x3583, 0x00a6, 0x2950, 0xb198, 0x080c, 0x6699,
-	0x1904, 0x37fd, 0xb6a4, 0x9684, 0x3fff, 0x9082, 0x4000, 0x16e8,
-	0xb49c, 0xb5a0, 0x080c, 0x67fc, 0x080c, 0x67cb, 0x1520, 0x2061,
-	0x1cd0, 0x0126, 0x2091, 0x8000, 0x6000, 0x9086, 0x0000, 0x0148,
-	0x6014, 0x904d, 0x0130, 0xa86c, 0x9406, 0x1118, 0xa870, 0x9506,
-	0x0158, 0x012e, 0x9ce0, 0x0018, 0x2001, 0x181a, 0x2004, 0x9c02,
-	0x2009, 0x000d, 0x12b0, 0x0c28, 0x080c, 0xc8a5, 0x012e, 0x2009,
-	0x0003, 0x0178, 0x00e0, 0x900e, 0x2001, 0x0005, 0x080c, 0x6f4a,
-	0x0126, 0x2091, 0x8000, 0x080c, 0xcf82, 0x080c, 0x6d0b, 0x012e,
-	0x0070, 0xb097, 0x4005, 0xb19a, 0x0010, 0xb097, 0x4006, 0x900e,
-	0x9085, 0x0001, 0x2001, 0x0030, 0x2a48, 0x00ae, 0x0005, 0xb097,
-	0x4000, 0x9006, 0x918d, 0x0001, 0x2008, 0x2a48, 0x00ae, 0x0005,
-	0x81ff, 0x1904, 0x35b5, 0x080c, 0x4b36, 0x0904, 0x35b8, 0x080c,
-	0x6760, 0x0904, 0x35b5, 0x080c, 0x6802, 0x0904, 0x35b5, 0x0804,
-	0x4586, 0x81ff, 0x1904, 0x35b5, 0x080c, 0x4b52, 0x0904, 0x35b8,
-	0x080c, 0x6890, 0x0904, 0x35b5, 0x2019, 0x0005, 0x79a8, 0x080c,
-	0x681d, 0x0904, 0x35b5, 0x7888, 0x908a, 0x1000, 0x1a04, 0x35b8,
-	0x8003, 0x800b, 0x810b, 0x9108, 0x080c, 0x85be, 0x7984, 0xd184,
-	0x1904, 0x3583, 0x0804, 0x4586, 0x0126, 0x2091, 0x8000, 0x81ff,
-	0x0118, 0x2009, 0x0001, 0x0450, 0x2029, 0x07ff, 0x645c, 0x2400,
-	0x9506, 0x01f8, 0x2508, 0x080c, 0x6699, 0x11d8, 0x080c, 0x6890,
-	0x1128, 0x2009, 0x0002, 0x62c0, 0x2518, 0x00c0, 0x2019, 0x0004,
-	0x900e, 0x080c, 0x681d, 0x1118, 0x2009, 0x0006, 0x0078, 0x7884,
-	0x908a, 0x1000, 0x1270, 0x8003, 0x800b, 0x810b, 0x9108, 0x080c,
-	0x85be, 0x8529, 0x1ae0, 0x012e, 0x0804, 0x3583, 0x012e, 0x0804,
-	0x35b5, 0x012e, 0x0804, 0x35b8, 0x080c, 0x4b36, 0x0904, 0x35b8,
-	0x080c, 0x6760, 0x0904, 0x35b5, 0xbaa0, 0x2019, 0x0005, 0x00c6,
-	0x9066, 0x080c, 0x9356, 0x0076, 0x903e, 0x080c, 0x9229, 0x900e,
-	0x080c, 0xe477, 0x007e, 0x00ce, 0x080c, 0x67fc, 0x0804, 0x3583,
-	0x080c, 0x4b36, 0x0904, 0x35b8, 0x080c, 0x67fc, 0x2208, 0x0804,
-	0x3583, 0x0156, 0x00d6, 0x00e6, 0x2069, 0x1910, 0x6810, 0x6914,
-	0x910a, 0x1208, 0x900e, 0x6816, 0x9016, 0x901e, 0x20a9, 0x007e,
-	0x2069, 0x1000, 0x2d04, 0x905d, 0x0118, 0xb84c, 0x0059, 0x9210,
-	0x8d68, 0x1f04, 0x38b2, 0x2300, 0x9218, 0x00ee, 0x00de, 0x015e,
-	0x0804, 0x3583, 0x00f6, 0x0016, 0x907d, 0x0138, 0x9006, 0x8000,
-	0x2f0c, 0x81ff, 0x0110, 0x2178, 0x0cd0, 0x001e, 0x00fe, 0x0005,
-	0x2069, 0x1910, 0x6910, 0x62bc, 0x0804, 0x3583, 0x81ff, 0x0120,
-	0x2009, 0x0001, 0x0804, 0x35b5, 0x0126, 0x2091, 0x8000, 0x080c,
-	0x5771, 0x0128, 0x2009, 0x0007, 0x012e, 0x0804, 0x35b5, 0x012e,
-	0x615c, 0x9190, 0x3384, 0x2215, 0x9294, 0x00ff, 0x637c, 0x83ff,
-	0x0108, 0x6280, 0x67dc, 0x97c4, 0x000a, 0x98c6, 0x000a, 0x1118,
-	0x2031, 0x0001, 0x00e8, 0x97c4, 0x0022, 0x98c6, 0x0022, 0x1118,
-	0x2031, 0x0003, 0x00a8, 0x97c4, 0x0012, 0x98c6, 0x0012, 0x1118,
-	0x2031, 0x0002, 0x0068, 0x080c, 0x743e, 0x1118, 0x2031, 0x0004,
-	0x0038, 0xd79c, 0x0120, 0x2009, 0x0005, 0x0804, 0x35b5, 0x9036,
-	0x7e9a, 0x7f9e, 0x0804, 0x3583, 0x614c, 0x6250, 0x2019, 0x1985,
-	0x231c, 0x2001, 0x1986, 0x2004, 0x789a, 0x0804, 0x3583, 0x0126,
-	0x2091, 0x8000, 0x6138, 0x623c, 0x6340, 0x012e, 0x0804, 0x3583,
-	0x080c, 0x4b52, 0x0904, 0x35b8, 0xba44, 0xbb38, 0x0804, 0x3583,
-	0x080c, 0x0dd5, 0x080c, 0x4b52, 0x2110, 0x0904, 0x35b8, 0xb804,
-	0x908c, 0x00ff, 0x918e, 0x0006, 0x0140, 0x9084, 0xff00, 0x9086,
-	0x0600, 0x2009, 0x0009, 0x1904, 0x35b5, 0x0126, 0x2091, 0x8000,
-	0x2019, 0x0005, 0x00c6, 0x9066, 0x080c, 0xa8dc, 0x080c, 0x9356,
-	0x0076, 0x903e, 0x080c, 0x9229, 0x900e, 0x080c, 0xe477, 0x007e,
-	0x00ce, 0xb807, 0x0407, 0x012e, 0x0804, 0x3583, 0x614c, 0x6250,
-	0x7884, 0x604e, 0x7b88, 0x6352, 0x2069, 0x1847, 0x831f, 0x9305,
-	0x6816, 0x788c, 0x2069, 0x1985, 0x2d1c, 0x206a, 0x7e98, 0x9682,
-	0x0014, 0x1210, 0x2031, 0x07d0, 0x2069, 0x1986, 0x2d04, 0x266a,
-	0x789a, 0x0804, 0x3583, 0x0126, 0x2091, 0x8000, 0x7884, 0x603a,
-	0xd0c4, 0x01a8, 0x00d6, 0x78a8, 0x2009, 0x199c, 0x200a, 0x78ac,
-	0x2011, 0x199d, 0x2012, 0x2069, 0x0100, 0x6838, 0x9086, 0x0007,
-	0x1118, 0x2214, 0x6a5a, 0x0010, 0x210c, 0x695a, 0x00de, 0x7884,
-	0xd0b4, 0x0120, 0x3b00, 0x9084, 0xff3f, 0x20d8, 0x7888, 0x603e,
-	0x2011, 0x0114, 0x220c, 0x7888, 0xd08c, 0x0118, 0x918d, 0x0080,
-	0x0010, 0x918c, 0xff7f, 0x2112, 0x788c, 0x6042, 0x9084, 0x0020,
-	0x0130, 0x78b4, 0x6046, 0x9084, 0x0001, 0x090c, 0x4278, 0x6040,
-	0xd0cc, 0x0120, 0x78b0, 0x2011, 0x0114, 0x2012, 0x012e, 0x0804,
-	0x3583, 0x00f6, 0x2079, 0x1800, 0x7a38, 0xa898, 0x9084, 0xfebf,
-	0x9215, 0xa89c, 0x9084, 0xfebf, 0x8002, 0x9214, 0x7838, 0x9084,
-	0x0140, 0x9215, 0x7a3a, 0xa897, 0x4000, 0x900e, 0x9085, 0x0001,
-	0x2001, 0x0000, 0x00fe, 0x0005, 0x7898, 0x9005, 0x01a8, 0x7888,
-	0x9025, 0x0904, 0x35b8, 0x788c, 0x902d, 0x0904, 0x35b8, 0x900e,
-	0x080c, 0x6699, 0x1120, 0xba44, 0xbb38, 0xbc46, 0xbd3a, 0x9186,
-	0x07ff, 0x0190, 0x8108, 0x0ca0, 0x080c, 0x4b52, 0x0904, 0x35b8,
-	0x7888, 0x900d, 0x0904, 0x35b8, 0x788c, 0x9005, 0x0904, 0x35b8,
-	0xba44, 0xb946, 0xbb38, 0xb83a, 0x0804, 0x3583, 0x2011, 0xbc09,
-	0x0010, 0x2011, 0xbc05, 0x080c, 0x5771, 0x1904, 0x35b5, 0x00c6,
-	0x2061, 0x0100, 0x7984, 0x9186, 0x00ff, 0x1130, 0x2001, 0x1818,
-	0x2004, 0x9085, 0xff00, 0x0088, 0x9182, 0x007f, 0x16e0, 0x9188,
-	0x3384, 0x210d, 0x918c, 0x00ff, 0x2001, 0x1818, 0x2004, 0x0026,
-	0x9116, 0x002e, 0x0580, 0x810f, 0x9105, 0x0126, 0x2091, 0x8000,
-	0x0006, 0x080c, 0xaeed, 0x000e, 0x0510, 0x602e, 0x620a, 0x7984,
-	0x00b6, 0x080c, 0x663e, 0x2b08, 0x00be, 0x1500, 0x6112, 0x6023,
-	0x0001, 0x080c, 0x4b1f, 0x01d0, 0x9006, 0xa866, 0x7007, 0x0003,
-	0xa832, 0xa868, 0xc0fd, 0xa86a, 0x701f, 0x3a69, 0x2900, 0x6016,
-	0x2009, 0x0032, 0x080c, 0xafbe, 0x012e, 0x00ce, 0x0005, 0x012e,
-	0x00ce, 0x0804, 0x35b5, 0x00ce, 0x0804, 0x35b8, 0x080c, 0xaf43,
-	0x0cb0, 0xa830, 0x9086, 0x0100, 0x0904, 0x35b5, 0x0804, 0x3583,
-	0x2061, 0x1a70, 0x0126, 0x2091, 0x8000, 0x6000, 0xd084, 0x0170,
-	0x6104, 0x6208, 0x2061, 0x1800, 0x6354, 0x6074, 0x789a, 0x60c0,
-	0x789e, 0x60bc, 0x78aa, 0x012e, 0x0804, 0x3583, 0x900e, 0x2110,
-	0x0c88, 0x81ff, 0x1904, 0x35b5, 0x080c, 0x743e, 0x0904, 0x35b5,
-	0x0126, 0x2091, 0x8000, 0x6254, 0x6074, 0x9202, 0x0248, 0x9085,
-	0x0001, 0x080c, 0x28e5, 0x080c, 0x5990, 0x012e, 0x0804, 0x3583,
-	0x012e, 0x0804, 0x35b8, 0x0006, 0x0016, 0x00c6, 0x00e6, 0x2001,
-	0x19a8, 0x2070, 0x2061, 0x1847, 0x6008, 0x2072, 0x900e, 0x2011,
-	0x1400, 0x080c, 0x9027, 0x7206, 0x00ee, 0x00ce, 0x001e, 0x000e,
-	0x0005, 0x0126, 0x2091, 0x8000, 0x81ff, 0x0128, 0x012e, 0x2021,
-	0x400b, 0x0804, 0x3585, 0x7884, 0xd0fc, 0x0148, 0x2001, 0x002a,
-	0x2004, 0x9082, 0x00e1, 0x0288, 0x012e, 0x0804, 0x35b8, 0x2001,
-	0x002a, 0x2004, 0x2069, 0x1847, 0x6908, 0x9102, 0x1230, 0x012e,
-	0x0804, 0x35b8, 0x012e, 0x0804, 0x35b5, 0x080c, 0xaead, 0x0dd0,
-	0x7884, 0xd0fc, 0x0904, 0x3b34, 0x00c6, 0x080c, 0x4b1f, 0x00ce,
-	0x0d88, 0xa867, 0x0000, 0x7884, 0xa80a, 0x7898, 0xa80e, 0x789c,
-	0xa812, 0x2001, 0x002e, 0x2004, 0xa81a, 0x2001, 0x002f, 0x2004,
-	0xa81e, 0x2001, 0x0030, 0x2004, 0xa822, 0x2001, 0x0031, 0x2004,
-	0xa826, 0x2001, 0x0034, 0x2004, 0xa82a, 0x2001, 0x0035, 0x2004,
-	0xa82e, 0x2001, 0x002a, 0x2004, 0x9080, 0x0003, 0x9084, 0x00fc,
-	0x8004, 0xa816, 0x080c, 0x3cba, 0x0928, 0x7014, 0x2048, 0xad2c,
-	0xac28, 0xab1c, 0xaa18, 0xa930, 0xa808, 0xd0b4, 0x1120, 0x2029,
-	0x0000, 0x2021, 0x0000, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f,
-	0x9084, 0xffc0, 0x9080, 0x001b, 0x080c, 0x4b68, 0x701f, 0x3bf7,
-	0x7023, 0x0001, 0x012e, 0x0005, 0x0046, 0x0086, 0x0096, 0x00a6,
-	0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x080c, 0x3aa3, 0x2001,
-	0x199e, 0x2003, 0x0000, 0x2021, 0x000a, 0x2061, 0x0100, 0x6104,
-	0x0016, 0x60bb, 0x0000, 0x60bf, 0x32e1, 0x60bf, 0x0012, 0x080c,
-	0x3d29, 0x080c, 0x3ce8, 0x00f6, 0x00e6, 0x0086, 0x2940, 0x2071,
-	0x1a65, 0x2079, 0x0090, 0x00d6, 0x2069, 0x0000, 0x6884, 0xd0b4,
-	0x0140, 0x2001, 0x0035, 0x2004, 0x780e, 0x2001, 0x0034, 0x2004,
-	0x780a, 0x00de, 0x2011, 0x0001, 0x080c, 0x40bc, 0x008e, 0x00ee,
-	0x00fe, 0x080c, 0x3fe9, 0x080c, 0x3eee, 0x05b8, 0x2001, 0x020b,
-	0x2004, 0x9084, 0x0140, 0x1db8, 0x080c, 0x4130, 0x00f6, 0x2079,
-	0x0300, 0x78bc, 0x00fe, 0x908c, 0x0070, 0x1560, 0x2071, 0x0200,
-	0x7037, 0x0000, 0x7050, 0x9084, 0xff00, 0x9086, 0x3200, 0x1510,
-	0x7037, 0x0001, 0x7050, 0x9084, 0xff00, 0x9086, 0xe100, 0x11d0,
-	0x7037, 0x0000, 0x7054, 0x7037, 0x0000, 0x715c, 0x9106, 0x1190,
-	0x2001, 0x1820, 0x2004, 0x9106, 0x1168, 0x00c6, 0x2061, 0x0100,
-	0x6024, 0x9084, 0x1e00, 0x00ce, 0x0138, 0x080c, 0x3ef8, 0x080c,
-	0x3ce3, 0x0058, 0x080c, 0x3ce3, 0x080c, 0x4054, 0x080c, 0x3fdf,
-	0x2001, 0x020b, 0x2004, 0xd0e4, 0x0dd8, 0x2001, 0x032a, 0x2003,
-	0x0004, 0x2061, 0x0100, 0x6027, 0x0002, 0x001e, 0x6106, 0x2011,
-	0x020d, 0x2013, 0x0020, 0x60bb, 0x0000, 0x60bf, 0x0108, 0x60bf,
-	0x0012, 0x2001, 0x0004, 0x200c, 0x918c, 0xfffd, 0x2102, 0x080c,
-	0x12ed, 0x2009, 0x0028, 0x080c, 0x2410, 0x2001, 0x0227, 0x200c,
-	0x2102, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x00ae, 0x009e,
-	0x008e, 0x004e, 0x2001, 0x199e, 0x2004, 0x9005, 0x1118, 0x012e,
-	0x0804, 0x3583, 0x012e, 0x2021, 0x400c, 0x0804, 0x3585, 0x0016,
-	0x0026, 0x0036, 0x0046, 0x0056, 0x0076, 0x0086, 0x0096, 0x00d6,
-	0x0156, 0x7014, 0x2048, 0x7020, 0x20a8, 0x8000, 0x7022, 0xa804,
-	0x9005, 0x0904, 0x3c53, 0x2048, 0x1f04, 0x3c07, 0x7068, 0x2040,
-	0xa28c, 0xa390, 0xa494, 0xa598, 0xa930, 0xa808, 0xd0b4, 0x1120,
-	0x2029, 0x0000, 0x2021, 0x0000, 0x0096, 0x7014, 0x2048, 0xa864,
-	0x009e, 0x9086, 0x0103, 0x0170, 0x8906, 0x8006, 0x8007, 0x90bc,
-	0x003f, 0x9084, 0xffc0, 0x9080, 0x001b, 0x080c, 0x4b68, 0x701f,
-	0x3bf7, 0x00b0, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084,
-	0xffc0, 0x9080, 0x001b, 0x21a8, 0x27e0, 0x2098, 0x27e8, 0x20a0,
-	0x0006, 0x080c, 0x0f7c, 0x000e, 0x080c, 0x4b6b, 0x701f, 0x3bf7,
-	0x015e, 0x00de, 0x009e, 0x008e, 0x007e, 0x005e, 0x004e, 0x003e,
-	0x002e, 0x001e, 0x0005, 0x7014, 0x2048, 0xa864, 0x9086, 0x0103,
-	0x1118, 0x701f, 0x3cb8, 0x0450, 0x7014, 0x2048, 0xa868, 0xc0fd,
-	0xa86a, 0x2009, 0x007f, 0x080c, 0x6638, 0x0110, 0x9006, 0x0030,
-	0xb813, 0x00ff, 0xb817, 0xfffd, 0x080c, 0xd151, 0x015e, 0x00de,
-	0x009e, 0x008e, 0x007e, 0x005e, 0x004e, 0x003e, 0x002e, 0x001e,
-	0x0904, 0x35b5, 0x0016, 0x0026, 0x0036, 0x0046, 0x0056, 0x0076,
-	0x0086, 0x0096, 0x00d6, 0x0156, 0x701f, 0x3c8a, 0x7007, 0x0003,
-	0x0804, 0x3c48, 0xa830, 0x9086, 0x0100, 0x2021, 0x400c, 0x0904,
-	0x3585, 0x0076, 0xad10, 0xac0c, 0xab24, 0xaa20, 0xa930, 0xa808,
-	0xd0b4, 0x1120, 0x2029, 0x0000, 0x2021, 0x0000, 0x8906, 0x8006,
-	0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x001b, 0x21a8,
-	0x27e0, 0x2098, 0x27e8, 0x20a0, 0x0006, 0x080c, 0x0f7c, 0x000e,
-	0x080c, 0x4b6b, 0x007e, 0x701f, 0x3bf7, 0x7023, 0x0001, 0x0005,
-	0x0804, 0x3583, 0x0156, 0x00c6, 0xa814, 0x908a, 0x001e, 0x0218,
-	0xa833, 0x001e, 0x0010, 0xa832, 0x0078, 0x81ff, 0x0168, 0x0016,
-	0x080c, 0x4b1f, 0x001e, 0x0130, 0xa800, 0x2040, 0xa008, 0xa80a,
-	0x2100, 0x0c58, 0x9006, 0x0010, 0x9085, 0x0001, 0x00ce, 0x015e,
-	0x0005, 0x0006, 0x00f6, 0x2079, 0x0000, 0x7880, 0x9086, 0x0044,
-	0x00fe, 0x000e, 0x0005, 0x2001, 0x199e, 0x2003, 0x0001, 0x0005,
-	0x00f6, 0x00e6, 0x00c6, 0x2061, 0x0200, 0x2001, 0x19a9, 0x2004,
-	0x601a, 0x2061, 0x0100, 0x2001, 0x19a8, 0x2004, 0x60ce, 0x6104,
-	0xc1ac, 0x6106, 0x080c, 0x4b1f, 0xa813, 0x0019, 0xa817, 0x0001,
-	0x2900, 0xa85a, 0x2001, 0x002e, 0x2004, 0xa866, 0x2001, 0x002f,
-	0x2004, 0xa86a, 0x2061, 0x0090, 0x2079, 0x0100, 0x2001, 0x19a8,
-	0x2004, 0x6036, 0x2009, 0x0040, 0x080c, 0x2410, 0x2001, 0x002a,
-	0x2004, 0x9084, 0xfff8, 0xa86e, 0x601a, 0xa873, 0x0000, 0x601f,
-	0x0000, 0x78ca, 0x9006, 0x600a, 0x600e, 0x00ce, 0x00ee, 0x00fe,
-	0x0005, 0x00e6, 0x080c, 0x4b1f, 0x2940, 0xa013, 0x0019, 0xa017,
-	0x0001, 0x2800, 0xa05a, 0x2001, 0x0030, 0x2004, 0xa866, 0x2001,
-	0x0031, 0x2004, 0xa86a, 0x2001, 0x002a, 0x2004, 0x9084, 0xfff8,
-	0xa86e, 0xa873, 0x0000, 0x2001, 0x032a, 0x2003, 0x0004, 0x2001,
-	0x0300, 0x2003, 0x0000, 0x2001, 0x020d, 0x2003, 0x0000, 0x2001,
-	0x0004, 0x200c, 0x918d, 0x0002, 0x2102, 0x00ee, 0x0005, 0x0126,
-	0x2091, 0x8000, 0x81ff, 0x0148, 0x080c, 0x2c6e, 0x1130, 0x9006,
-	0x080c, 0x2bc6, 0x9006, 0x080c, 0x2ba9, 0x7884, 0x9084, 0x0007,
-	0x0002, 0x3d74, 0x3d7d, 0x3d86, 0x3d71, 0x3d71, 0x3d71, 0x3d71,
-	0x3d71, 0x012e, 0x0804, 0x35b8, 0x2009, 0x0114, 0x2104, 0x9085,
-	0x0800, 0x200a, 0x080c, 0x3f42, 0x00c0, 0x2009, 0x0114, 0x2104,
-	0x9085, 0x4000, 0x200a, 0x080c, 0x3f42, 0x0078, 0x080c, 0x743e,
-	0x1128, 0x012e, 0x2009, 0x0016, 0x0804, 0x35b5, 0x81ff, 0x0128,
-	0x012e, 0x2021, 0x400b, 0x0804, 0x3585, 0x0086, 0x0096, 0x00a6,
-	0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x080c, 0x3aa3, 0x2009,
+	0x8000, 0x2071, 0x189e, 0x7003, 0x0002, 0x9006, 0x7016, 0x701a,
+	0x704a, 0x704e, 0x700e, 0x7042, 0x7046, 0x703b, 0x18ba, 0x703f,
+	0x18ba, 0x7007, 0x0001, 0x080c, 0x1027, 0x090c, 0x0dc5, 0x2900,
+	0x706a, 0xa867, 0x0002, 0xa8ab, 0xdcb0, 0x080c, 0x1027, 0x090c,
+	0x0dc5, 0x2900, 0x706e, 0xa867, 0x0002, 0xa8ab, 0xdcb0, 0x0005,
+	0x2071, 0x189e, 0x7004, 0x0002, 0x34e0, 0x34e1, 0x34f4, 0x3508,
+	0x0005, 0x1004, 0x34f1, 0x0e04, 0x34f1, 0x2079, 0x0000, 0x0126,
+	0x2091, 0x8000, 0x700c, 0x9005, 0x1128, 0x700f, 0x0001, 0x012e,
+	0x0468, 0x0005, 0x012e, 0x0ce8, 0x2079, 0x0000, 0x2061, 0x18b8,
+	0x2c4c, 0xa86c, 0x908e, 0x0100, 0x0128, 0x9086, 0x0200, 0x0904,
+	0x35dc, 0x0005, 0x7018, 0x2048, 0x2061, 0x1800, 0x701c, 0x0807,
+	0x7014, 0x2048, 0xa864, 0x9094, 0x00ff, 0x9296, 0x0029, 0x1120,
+	0xaa78, 0xd2fc, 0x0128, 0x0005, 0x9086, 0x0103, 0x0108, 0x0005,
+	0x2079, 0x0000, 0x2061, 0x1800, 0x701c, 0x0807, 0x2061, 0x1800,
+	0x7880, 0x908a, 0x0040, 0x1210, 0x61d0, 0x0042, 0x2100, 0x908a,
+	0x003f, 0x1a04, 0x35d9, 0x61d0, 0x0804, 0x356e, 0x35b0, 0x35e8,
+	0x35d9, 0x35f4, 0x35fe, 0x3604, 0x3608, 0x3618, 0x361c, 0x3632,
+	0x3638, 0x363e, 0x3649, 0x3654, 0x3663, 0x3672, 0x3680, 0x3697,
+	0x36b2, 0x35d9, 0x375b, 0x3799, 0x383f, 0x3850, 0x3873, 0x35d9,
+	0x35d9, 0x35d9, 0x38ab, 0x38c7, 0x38d0, 0x38ff, 0x3905, 0x35d9,
+	0x394b, 0x35d9, 0x35d9, 0x35d9, 0x35d9, 0x35d9, 0x3956, 0x395f,
+	0x3967, 0x3969, 0x35d9, 0x35d9, 0x35d9, 0x35d9, 0x35d9, 0x35d9,
+	0x3995, 0x35d9, 0x35d9, 0x35d9, 0x35d9, 0x35d9, 0x39b2, 0x3a27,
+	0x35d9, 0x35d9, 0x35d9, 0x35d9, 0x35d9, 0x35d9, 0x0002, 0x3a51,
+	0x3a54, 0x3ab3, 0x3acc, 0x3afc, 0x3d9e, 0x35d9, 0x5390, 0x35d9,
+	0x35d9, 0x35d9, 0x35d9, 0x35d9, 0x35d9, 0x35d9, 0x35d9, 0x3632,
+	0x3638, 0x42c8, 0x57f1, 0x42e6, 0x541f, 0x5471, 0x557c, 0x35d9,
+	0x55de, 0x561a, 0x564b, 0x5753, 0x5678, 0x56d3, 0x35d9, 0x42ea,
+	0x44b0, 0x44c6, 0x44eb, 0x4550, 0x45c4, 0x45e4, 0x465b, 0x46b7,
+	0x4713, 0x4716, 0x473b, 0x47f2, 0x4858, 0x4860, 0x4995, 0x4b0d,
+	0x4b41, 0x4da5, 0x35d9, 0x4dc3, 0x4e69, 0x4f52, 0x4fac, 0x35d9,
+	0x5063, 0x35d9, 0x50cf, 0x50ea, 0x4860, 0x5330, 0x714c, 0x0000,
+	0x2021, 0x4000, 0x080c, 0x4bbf, 0x0126, 0x2091, 0x8000, 0x0e04,
+	0x35ba, 0x0010, 0x012e, 0x0cc0, 0x7c36, 0x9486, 0x4000, 0x0118,
+	0x7833, 0x0011, 0x0010, 0x7833, 0x0010, 0x7c82, 0x7986, 0x7a8a,
+	0x7b8e, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c,
+	0x11aa, 0x7007, 0x0001, 0x2091, 0x5000, 0x700f, 0x0000, 0x012e,
+	0x0005, 0x2021, 0x4001, 0x08b0, 0x2021, 0x4002, 0x0898, 0x2021,
+	0x4003, 0x0880, 0x2021, 0x4005, 0x0868, 0x2021, 0x4006, 0x0850,
+	0x2039, 0x0001, 0x902e, 0x2520, 0x7b88, 0x7a8c, 0x7884, 0x7990,
+	0x81ff, 0x0d98, 0x0804, 0x4bcc, 0x2039, 0x0001, 0x902e, 0x2520,
+	0x7b88, 0x7a8c, 0x7884, 0x7990, 0x0804, 0x4bcf, 0x7984, 0x7888,
+	0x2114, 0x200a, 0x0804, 0x35b0, 0x7984, 0x2114, 0x0804, 0x35b0,
+	0x20e1, 0x0000, 0x2099, 0x0021, 0x20e9, 0x0000, 0x20a1, 0x0021,
+	0x20a9, 0x001f, 0x4003, 0x7984, 0x7a88, 0x7b8c, 0x0804, 0x35b0,
+	0x7884, 0x2060, 0x0804, 0x3665, 0x2009, 0x0003, 0x2011, 0x0003,
+	0x2019, 0x000f, 0x789b, 0x0137, 0x7893, 0xffff, 0x2001, 0x188f,
+	0x2004, 0x9005, 0x0118, 0x7896, 0x0804, 0x35b0, 0x7897, 0x0001,
+	0x0804, 0x35b0, 0x2039, 0x0001, 0x7d98, 0x7c9c, 0x0804, 0x35ec,
+	0x2039, 0x0001, 0x7d98, 0x7c9c, 0x0804, 0x35f8, 0x79a0, 0x9182,
+	0x0040, 0x0210, 0x0804, 0x35e5, 0x2138, 0x7d98, 0x7c9c, 0x0804,
+	0x35ec, 0x79a0, 0x9182, 0x0040, 0x0210, 0x0804, 0x35e5, 0x2138,
+	0x7d98, 0x7c9c, 0x0804, 0x35f8, 0x79a0, 0x9182, 0x0040, 0x0210,
+	0x0804, 0x35e5, 0x21e8, 0x7984, 0x7888, 0x20a9, 0x0001, 0x21a0,
+	0x4004, 0x0804, 0x35b0, 0x2061, 0x0800, 0xe10c, 0x9006, 0x2c15,
+	0x9200, 0x8c60, 0x8109, 0x1dd8, 0x2010, 0x9005, 0x0904, 0x35b0,
+	0x0804, 0x35df, 0x79a0, 0x9182, 0x0040, 0x0210, 0x0804, 0x35e5,
+	0x21e0, 0x20a9, 0x0001, 0x7984, 0x2198, 0x4012, 0x0804, 0x35b0,
+	0x2069, 0x1847, 0x7884, 0x7990, 0x911a, 0x1a04, 0x35e5, 0x8019,
+	0x0904, 0x35e5, 0x684a, 0x6942, 0x788c, 0x6852, 0x7888, 0x6856,
+	0x9006, 0x685a, 0x685e, 0x080c, 0x7879, 0x0804, 0x35b0, 0x2069,
+	0x1847, 0x7884, 0x7994, 0x911a, 0x1a04, 0x35e5, 0x8019, 0x0904,
+	0x35e5, 0x684e, 0x6946, 0x788c, 0x6862, 0x7888, 0x6866, 0x9006,
+	0x686a, 0x686e, 0x0126, 0x2091, 0x8000, 0x080c, 0x6b24, 0x012e,
+	0x0804, 0x35b0, 0x902e, 0x2520, 0x81ff, 0x0120, 0x2009, 0x0001,
+	0x0804, 0x35e2, 0x7984, 0x7b88, 0x7a8c, 0x20a9, 0x0005, 0x20e9,
+	0x0001, 0x20a1, 0x18a6, 0x4101, 0x080c, 0x4b83, 0x1120, 0x2009,
+	0x0002, 0x0804, 0x35e2, 0x2009, 0x0020, 0xa85c, 0x9080, 0x0019,
+	0xaf60, 0x080c, 0x4bcc, 0x701f, 0x36d6, 0x0005, 0xa864, 0x2008,
+	0x9084, 0x00ff, 0x9096, 0x0011, 0x0168, 0x9096, 0x0019, 0x0150,
+	0x9096, 0x0015, 0x0138, 0x9096, 0x0048, 0x0120, 0x9096, 0x0029,
+	0x1904, 0x35e2, 0x810f, 0x918c, 0x00ff, 0x0904, 0x35e2, 0x7112,
+	0x7010, 0x8001, 0x0560, 0x7012, 0x080c, 0x4b83, 0x1120, 0x2009,
+	0x0002, 0x0804, 0x35e2, 0x2009, 0x0020, 0x7068, 0x2040, 0xa28c,
+	0xa390, 0xa494, 0xa598, 0x9290, 0x0040, 0x9399, 0x0000, 0x94a1,
+	0x0000, 0x95a9, 0x0000, 0xa85c, 0x9080, 0x0019, 0xaf60, 0x080c,
+	0x4bcc, 0x701f, 0x3714, 0x0005, 0xa864, 0x9084, 0x00ff, 0x9096,
+	0x0002, 0x0120, 0x9096, 0x000a, 0x1904, 0x35e2, 0x0888, 0x7014,
+	0x2048, 0xa868, 0xc0fd, 0xa86a, 0xa864, 0x9084, 0x00ff, 0x9096,
+	0x0029, 0x1160, 0xc2fd, 0xaa7a, 0x080c, 0x6292, 0x0150, 0x0126,
+	0x2091, 0x8000, 0xa87a, 0xa982, 0x012e, 0x0050, 0x080c, 0x65c2,
+	0x1128, 0x7007, 0x0003, 0x701f, 0x3740, 0x0005, 0x080c, 0x7037,
+	0x0126, 0x2091, 0x8000, 0x20a9, 0x0005, 0x20e1, 0x0001, 0x2099,
+	0x18a6, 0x400a, 0x2100, 0x9210, 0x9399, 0x0000, 0x94a1, 0x0000,
+	0x95a9, 0x0000, 0xa85c, 0x9080, 0x0019, 0x2009, 0x0020, 0x012e,
+	0xaf60, 0x0804, 0x4bcf, 0x2091, 0x8000, 0x7837, 0x4000, 0x7833,
+	0x0010, 0x7883, 0x4000, 0x7887, 0x4953, 0x788b, 0x5020, 0x788f,
+	0x2020, 0x2009, 0x017f, 0x2104, 0x7892, 0x3f00, 0x7896, 0x2061,
+	0x0100, 0x6200, 0x2061, 0x0200, 0x603c, 0x8007, 0x9205, 0x789a,
+	0x2009, 0x04fd, 0x2104, 0x789e, 0x2091, 0x5000, 0x2091, 0x4080,
+	0x2001, 0x0089, 0x2004, 0xd084, 0x0180, 0x2001, 0x1a1d, 0x2004,
+	0x9005, 0x0128, 0x2001, 0x008b, 0x2004, 0xd0fc, 0x0dd8, 0x2001,
+	0x008a, 0x2003, 0x0002, 0x2003, 0x1001, 0x2071, 0x0080, 0x0804,
+	0x0427, 0x81ff, 0x1904, 0x35e2, 0x7984, 0x080c, 0x6717, 0x1904,
+	0x35e5, 0x7e98, 0x9684, 0x3fff, 0x9082, 0x4000, 0x1a04, 0x35e5,
+	0x7c88, 0x7d8c, 0x080c, 0x687a, 0x080c, 0x6849, 0x0000, 0x1518,
+	0x2061, 0x1cd0, 0x0126, 0x2091, 0x8000, 0x6000, 0x9086, 0x0000,
+	0x0148, 0x6014, 0x904d, 0x0130, 0xa86c, 0x9406, 0x1118, 0xa870,
+	0x9506, 0x0150, 0x012e, 0x9ce0, 0x0018, 0x2001, 0x181a, 0x2004,
+	0x9c02, 0x1a04, 0x35e2, 0x0c30, 0x080c, 0xca5e, 0x012e, 0x0904,
+	0x35e2, 0x0804, 0x35b0, 0x900e, 0x2001, 0x0005, 0x080c, 0x7037,
+	0x0126, 0x2091, 0x8000, 0x080c, 0xd13b, 0x080c, 0x6dcb, 0x012e,
+	0x0804, 0x35b0, 0x00a6, 0x2950, 0xb198, 0x080c, 0x6717, 0x1904,
+	0x382c, 0xb6a4, 0x9684, 0x3fff, 0x9082, 0x4000, 0x16e8, 0xb49c,
+	0xb5a0, 0x080c, 0x687a, 0x080c, 0x6849, 0x1520, 0x2061, 0x1cd0,
+	0x0126, 0x2091, 0x8000, 0x6000, 0x9086, 0x0000, 0x0148, 0x6014,
+	0x904d, 0x0130, 0xa86c, 0x9406, 0x1118, 0xa870, 0x9506, 0x0158,
+	0x012e, 0x9ce0, 0x0018, 0x2001, 0x181a, 0x2004, 0x9c02, 0x2009,
+	0x000d, 0x12b0, 0x0c28, 0x080c, 0xca5e, 0x012e, 0x2009, 0x0003,
+	0x0178, 0x00e0, 0x900e, 0x2001, 0x0005, 0x080c, 0x7037, 0x0126,
+	0x2091, 0x8000, 0x080c, 0xd13b, 0x080c, 0x6dbe, 0x012e, 0x0070,
+	0xb097, 0x4005, 0xb19a, 0x0010, 0xb097, 0x4006, 0x900e, 0x9085,
+	0x0001, 0x2001, 0x0030, 0x2a48, 0x00ae, 0x0005, 0xb097, 0x4000,
+	0x9006, 0x918d, 0x0001, 0x2008, 0x2a48, 0x00ae, 0x0005, 0x81ff,
+	0x1904, 0x35e2, 0x080c, 0x4b9a, 0x0904, 0x35e5, 0x080c, 0x67de,
+	0x0904, 0x35e2, 0x080c, 0x6880, 0x0904, 0x35e2, 0x0804, 0x45db,
+	0x81ff, 0x1904, 0x35e2, 0x080c, 0x4bb6, 0x0904, 0x35e5, 0x080c,
+	0x690e, 0x0904, 0x35e2, 0x2019, 0x0005, 0x79a8, 0x080c, 0x689b,
+	0x0904, 0x35e2, 0x7888, 0x908a, 0x1000, 0x1a04, 0x35e5, 0x8003,
+	0x800b, 0x810b, 0x9108, 0x080c, 0x8711, 0x79a8, 0xd184, 0x1904,
+	0x35b0, 0x0804, 0x45db, 0x0126, 0x2091, 0x8000, 0x81ff, 0x0118,
+	0x2009, 0x0001, 0x0450, 0x2029, 0x07ff, 0x645c, 0x2400, 0x9506,
+	0x01f8, 0x2508, 0x080c, 0x6717, 0x11d8, 0x080c, 0x690e, 0x1128,
+	0x2009, 0x0002, 0x62c0, 0x2518, 0x00c0, 0x2019, 0x0004, 0x900e,
+	0x080c, 0x689b, 0x1118, 0x2009, 0x0006, 0x0078, 0x7884, 0x908a,
+	0x1000, 0x1270, 0x8003, 0x800b, 0x810b, 0x9108, 0x080c, 0x8711,
+	0x8529, 0x1ae0, 0x012e, 0x0804, 0x35b0, 0x012e, 0x0804, 0x35e2,
+	0x012e, 0x0804, 0x35e5, 0x080c, 0x4b9a, 0x0904, 0x35e5, 0x080c,
+	0x67de, 0x0904, 0x35e2, 0xbaa0, 0x2019, 0x0005, 0x00c6, 0x9066,
+	0x080c, 0x94da, 0x0076, 0x903e, 0x080c, 0x93ad, 0x900e, 0x080c,
+	0xe671, 0x007e, 0x00ce, 0x080c, 0x687a, 0x0804, 0x35b0, 0x080c,
+	0x4b9a, 0x0904, 0x35e5, 0x080c, 0x687a, 0x2208, 0x0804, 0x35b0,
+	0x0156, 0x00d6, 0x00e6, 0x2069, 0x1910, 0x6810, 0x6914, 0x910a,
+	0x1208, 0x900e, 0x6816, 0x9016, 0x901e, 0x20a9, 0x007e, 0x2069,
+	0x1000, 0x2d04, 0x905d, 0x0118, 0xb84c, 0x0059, 0x9210, 0x8d68,
+	0x1f04, 0x38e1, 0x2300, 0x9218, 0x00ee, 0x00de, 0x015e, 0x0804,
+	0x35b0, 0x00f6, 0x0016, 0x907d, 0x0138, 0x9006, 0x8000, 0x2f0c,
+	0x81ff, 0x0110, 0x2178, 0x0cd0, 0x001e, 0x00fe, 0x0005, 0x2069,
+	0x1910, 0x6910, 0x62bc, 0x0804, 0x35b0, 0x81ff, 0x0120, 0x2009,
+	0x0001, 0x0804, 0x35e2, 0x0126, 0x2091, 0x8000, 0x080c, 0x57e1,
+	0x0128, 0x2009, 0x0007, 0x012e, 0x0804, 0x35e2, 0x012e, 0x615c,
+	0x9190, 0x33b1, 0x2215, 0x9294, 0x00ff, 0x637c, 0x83ff, 0x0108,
+	0x6280, 0x67dc, 0x97c4, 0x000a, 0x98c6, 0x000a, 0x1118, 0x2031,
+	0x0001, 0x00e8, 0x97c4, 0x0022, 0x98c6, 0x0022, 0x1118, 0x2031,
+	0x0003, 0x00a8, 0x97c4, 0x0012, 0x98c6, 0x0012, 0x1118, 0x2031,
+	0x0002, 0x0068, 0x080c, 0x7563, 0x1118, 0x2031, 0x0004, 0x0038,
+	0xd79c, 0x0120, 0x2009, 0x0005, 0x0804, 0x35e2, 0x9036, 0x7e9a,
+	0x7f9e, 0x0804, 0x35b0, 0x614c, 0x6250, 0x2019, 0x1987, 0x231c,
+	0x2001, 0x1988, 0x2004, 0x789a, 0x0804, 0x35b0, 0x0126, 0x2091,
+	0x8000, 0x6138, 0x623c, 0x6340, 0x012e, 0x0804, 0x35b0, 0x080c,
+	0x4bb6, 0x0904, 0x35e5, 0xba44, 0xbb38, 0x0804, 0x35b0, 0x080c,
+	0x0dc5, 0x080c, 0x4bb6, 0x2110, 0x0904, 0x35e5, 0xb804, 0x908c,
+	0x00ff, 0x918e, 0x0006, 0x0140, 0x9084, 0xff00, 0x9086, 0x0600,
+	0x2009, 0x0009, 0x1904, 0x35e2, 0x0126, 0x2091, 0x8000, 0x2019,
+	0x0005, 0x00c6, 0x9066, 0x080c, 0xaa80, 0x080c, 0x94da, 0x0076,
+	0x903e, 0x080c, 0x93ad, 0x900e, 0x080c, 0xe671, 0x007e, 0x00ce,
+	0xb807, 0x0407, 0x012e, 0x0804, 0x35b0, 0x614c, 0x6250, 0x7884,
+	0x604e, 0x7b88, 0x6352, 0x2069, 0x1847, 0x831f, 0x9305, 0x6816,
+	0x788c, 0x2069, 0x1987, 0x2d1c, 0x206a, 0x7e98, 0x9682, 0x0014,
+	0x1210, 0x2031, 0x07d0, 0x2069, 0x1988, 0x2d04, 0x266a, 0x789a,
+	0x0804, 0x35b0, 0x0126, 0x2091, 0x8000, 0x6138, 0x7884, 0x603a,
+	0x910e, 0xd1b4, 0x190c, 0x0ebe, 0xd094, 0x0148, 0x00e6, 0x2071,
+	0x19fc, 0x79b4, 0x9192, 0x07d0, 0x1208, 0x713e, 0x00ee, 0xd0c4,
+	0x01a8, 0x00d6, 0x78a8, 0x2009, 0x199e, 0x200a, 0x78ac, 0x2011,
+	0x199f, 0x2012, 0x2069, 0x0100, 0x6838, 0x9086, 0x0007, 0x1118,
+	0x2214, 0x6a5a, 0x0010, 0x210c, 0x695a, 0x00de, 0x2011, 0x0114,
+	0x220c, 0x7888, 0xd08c, 0x0118, 0x918d, 0x0080, 0x0010, 0x918c,
+	0xff7f, 0x2112, 0x603c, 0x7988, 0x613e, 0x6140, 0x910d, 0x788c,
+	0x6042, 0x7a88, 0x9294, 0x1000, 0x9205, 0x910e, 0xd1e4, 0x190c,
+	0x0ed4, 0x9084, 0x0020, 0x0130, 0x78b4, 0x6046, 0x9084, 0x0001,
+	0x090c, 0x42c8, 0x6040, 0xd0cc, 0x0120, 0x78b0, 0x2011, 0x0114,
+	0x2012, 0x012e, 0x0804, 0x35b0, 0x00f6, 0x2079, 0x1800, 0x7a38,
+	0xa898, 0x9084, 0xfebf, 0x9215, 0xa89c, 0x9084, 0xfebf, 0x8002,
+	0x9214, 0x7838, 0x9084, 0x0140, 0x9215, 0x7a3a, 0xa897, 0x4000,
+	0x900e, 0x9085, 0x0001, 0x2001, 0x0000, 0x00fe, 0x0005, 0x7898,
+	0x9005, 0x01a8, 0x7888, 0x9025, 0x0904, 0x35e5, 0x788c, 0x902d,
+	0x0904, 0x35e5, 0x900e, 0x080c, 0x6717, 0x1120, 0xba44, 0xbb38,
+	0xbc46, 0xbd3a, 0x9186, 0x07ff, 0x0190, 0x8108, 0x0ca0, 0x080c,
+	0x4bb6, 0x0904, 0x35e5, 0x7888, 0x900d, 0x0904, 0x35e5, 0x788c,
+	0x9005, 0x0904, 0x35e5, 0xba44, 0xb946, 0xbb38, 0xb83a, 0x0804,
+	0x35b0, 0x2011, 0xbc09, 0x0010, 0x2011, 0xbc05, 0x080c, 0x57e1,
+	0x1904, 0x35e2, 0x00c6, 0x2061, 0x0100, 0x7984, 0x9186, 0x00ff,
+	0x1130, 0x2001, 0x1818, 0x2004, 0x9085, 0xff00, 0x0088, 0x9182,
+	0x007f, 0x16e0, 0x9188, 0x33b1, 0x210d, 0x918c, 0x00ff, 0x2001,
+	0x1818, 0x2004, 0x0026, 0x9116, 0x002e, 0x0580, 0x810f, 0x9105,
+	0x0126, 0x2091, 0x8000, 0x0006, 0x080c, 0xb091, 0x000e, 0x0510,
+	0x602e, 0x620a, 0x7984, 0x00b6, 0x080c, 0x66b2, 0x2b08, 0x00be,
+	0x1500, 0x6112, 0x6023, 0x0001, 0x080c, 0x4b83, 0x01d0, 0x9006,
+	0xa866, 0x7007, 0x0003, 0xa832, 0xa868, 0xc0fd, 0xa86a, 0x701f,
+	0x3aac, 0x2900, 0x6016, 0x2009, 0x0032, 0x080c, 0xb166, 0x012e,
+	0x00ce, 0x0005, 0x012e, 0x00ce, 0x0804, 0x35e2, 0x00ce, 0x0804,
+	0x35e5, 0x080c, 0xb0e7, 0x0cb0, 0xa830, 0x9086, 0x0100, 0x0904,
+	0x35e2, 0x0804, 0x35b0, 0x2061, 0x1a75, 0x0126, 0x2091, 0x8000,
+	0x6000, 0xd084, 0x0170, 0x6104, 0x6208, 0x2061, 0x1800, 0x6354,
+	0x6074, 0x789a, 0x60c0, 0x789e, 0x60bc, 0x78aa, 0x012e, 0x0804,
+	0x35b0, 0x900e, 0x2110, 0x0c88, 0x81ff, 0x1904, 0x35e2, 0x080c,
+	0x7563, 0x0904, 0x35e2, 0x0126, 0x2091, 0x8000, 0x6254, 0x6074,
+	0x9202, 0x0248, 0x9085, 0x0001, 0x080c, 0x28f2, 0x080c, 0x5a04,
+	0x012e, 0x0804, 0x35b0, 0x012e, 0x0804, 0x35e5, 0x0006, 0x0016,
+	0x00c6, 0x00e6, 0x2001, 0x19aa, 0x2070, 0x2061, 0x1847, 0x6008,
+	0x2072, 0x900e, 0x2011, 0x1400, 0x080c, 0x91ab, 0x7206, 0x00ee,
+	0x00ce, 0x001e, 0x000e, 0x0005, 0x0126, 0x2091, 0x8000, 0x81ff,
+	0x0128, 0x012e, 0x2021, 0x400b, 0x0804, 0x35b2, 0x7884, 0xd0fc,
+	0x0158, 0x2001, 0x002a, 0x2004, 0x9005, 0x0180, 0x9082, 0x00e1,
+	0x0298, 0x012e, 0x0804, 0x35e5, 0x2001, 0x002a, 0x2004, 0x9005,
+	0x0128, 0x2069, 0x1847, 0x6908, 0x9102, 0x1230, 0x012e, 0x0804,
+	0x35e5, 0x012e, 0x0804, 0x35e2, 0x080c, 0xb051, 0x0dd0, 0x7884,
+	0xd0fc, 0x0904, 0x3b7b, 0x00c6, 0x080c, 0x4b83, 0x00ce, 0x0d88,
+	0xa867, 0x0000, 0x7884, 0xa80a, 0x7898, 0xa80e, 0x789c, 0xa812,
+	0x2001, 0x002e, 0x2004, 0xa81a, 0x2001, 0x002f, 0x2004, 0xa81e,
+	0x2001, 0x0030, 0x2004, 0xa822, 0x2001, 0x0031, 0x2004, 0xa826,
+	0x2001, 0x0034, 0x2004, 0xa82a, 0x2001, 0x0035, 0x2004, 0xa82e,
+	0x2001, 0x002a, 0x2004, 0x9080, 0x0003, 0x9084, 0x00fc, 0x8004,
+	0xa816, 0x080c, 0x3d01, 0x0928, 0x7014, 0x2048, 0xad2c, 0xac28,
+	0xab1c, 0xaa18, 0xa930, 0xa808, 0xd0b4, 0x1120, 0x2029, 0x0000,
+	0x2021, 0x0000, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084,
+	0xffc0, 0x9080, 0x001b, 0x080c, 0x4bcc, 0x701f, 0x3c3e, 0x7023,
+	0x0001, 0x012e, 0x0005, 0x0046, 0x0086, 0x0096, 0x00a6, 0x00b6,
+	0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x080c, 0x3ae6, 0x2001, 0x19a0,
+	0x2003, 0x0000, 0x2021, 0x000a, 0x2061, 0x0100, 0x6104, 0x0016,
+	0x60bb, 0x0000, 0x60bf, 0x32e1, 0x60bf, 0x0012, 0x080c, 0x3d70,
+	0x080c, 0x3d2f, 0x00f6, 0x00e6, 0x0086, 0x2940, 0x2071, 0x1a6a,
+	0x2079, 0x0090, 0x00d6, 0x2069, 0x0000, 0x6884, 0xd0b4, 0x0140,
+	0x2001, 0x0035, 0x2004, 0x780e, 0x2001, 0x0034, 0x2004, 0x780a,
+	0x00de, 0x2011, 0x0001, 0x080c, 0x410c, 0x008e, 0x00ee, 0x00fe,
+	0x080c, 0x4039, 0x080c, 0x3f3e, 0x05b8, 0x2001, 0x020b, 0x2004,
+	0x9084, 0x0140, 0x1db8, 0x080c, 0x4180, 0x00f6, 0x2079, 0x0300,
+	0x78bc, 0x00fe, 0x908c, 0x0070, 0x1560, 0x2071, 0x0200, 0x7037,
+	0x0000, 0x7050, 0x9084, 0xff00, 0x9086, 0x3200, 0x1510, 0x7037,
+	0x0001, 0x7050, 0x9084, 0xff00, 0x9086, 0xe100, 0x11d0, 0x7037,
+	0x0000, 0x7054, 0x7037, 0x0000, 0x715c, 0x9106, 0x1190, 0x2001,
+	0x1820, 0x2004, 0x9106, 0x1168, 0x00c6, 0x2061, 0x0100, 0x6024,
+	0x9084, 0x1e00, 0x00ce, 0x0138, 0x080c, 0x3f48, 0x080c, 0x3d2a,
+	0x0058, 0x080c, 0x3d2a, 0x080c, 0x40a4, 0x080c, 0x402f, 0x2001,
+	0x020b, 0x2004, 0xd0e4, 0x0dd8, 0x2001, 0x032a, 0x2003, 0x0004,
+	0x2061, 0x0100, 0x6027, 0x0002, 0x001e, 0x6106, 0x2011, 0x020d,
+	0x2013, 0x0020, 0x60bb, 0x0000, 0x60bf, 0x0108, 0x60bf, 0x0012,
+	0x2001, 0x0004, 0x200c, 0x918c, 0xfffd, 0x2102, 0x080c, 0x12fc,
+	0x2009, 0x0028, 0x080c, 0x242a, 0x2001, 0x0227, 0x200c, 0x2102,
+	0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x00ae, 0x009e, 0x008e,
+	0x004e, 0x2001, 0x19a0, 0x2004, 0x9005, 0x1118, 0x012e, 0x0804,
+	0x35b0, 0x012e, 0x2021, 0x400c, 0x0804, 0x35b2, 0x0016, 0x0026,
+	0x0036, 0x0046, 0x0056, 0x0076, 0x0086, 0x0096, 0x00d6, 0x0156,
+	0x7014, 0x2048, 0x7020, 0x20a8, 0x8000, 0x7022, 0xa804, 0x9005,
+	0x0904, 0x3c9a, 0x2048, 0x1f04, 0x3c4e, 0x7068, 0x2040, 0xa28c,
+	0xa390, 0xa494, 0xa598, 0xa930, 0xa808, 0xd0b4, 0x1120, 0x2029,
+	0x0000, 0x2021, 0x0000, 0x0096, 0x7014, 0x2048, 0xa864, 0x009e,
+	0x9086, 0x0103, 0x0170, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f,
+	0x9084, 0xffc0, 0x9080, 0x001b, 0x080c, 0x4bcc, 0x701f, 0x3c3e,
+	0x00b0, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0,
+	0x9080, 0x001b, 0x21a8, 0x27e0, 0x2098, 0x27e8, 0x20a0, 0x0006,
+	0x080c, 0x0f8b, 0x000e, 0x080c, 0x4bcf, 0x701f, 0x3c3e, 0x015e,
+	0x00de, 0x009e, 0x008e, 0x007e, 0x005e, 0x004e, 0x003e, 0x002e,
+	0x001e, 0x0005, 0x7014, 0x2048, 0xa864, 0x9086, 0x0103, 0x1118,
+	0x701f, 0x3cff, 0x0450, 0x7014, 0x2048, 0xa868, 0xc0fd, 0xa86a,
+	0x2009, 0x007f, 0x080c, 0x66ac, 0x0110, 0x9006, 0x0030, 0xb813,
+	0x00ff, 0xb817, 0xfffd, 0x080c, 0xd30e, 0x015e, 0x00de, 0x009e,
+	0x008e, 0x007e, 0x005e, 0x004e, 0x003e, 0x002e, 0x001e, 0x0904,
+	0x35e2, 0x0016, 0x0026, 0x0036, 0x0046, 0x0056, 0x0076, 0x0086,
+	0x0096, 0x00d6, 0x0156, 0x701f, 0x3cd1, 0x7007, 0x0003, 0x0804,
+	0x3c8f, 0xa830, 0x9086, 0x0100, 0x2021, 0x400c, 0x0904, 0x35b2,
+	0x0076, 0xad10, 0xac0c, 0xab24, 0xaa20, 0xa930, 0xa808, 0xd0b4,
+	0x1120, 0x2029, 0x0000, 0x2021, 0x0000, 0x8906, 0x8006, 0x8007,
+	0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x001b, 0x21a8, 0x27e0,
+	0x2098, 0x27e8, 0x20a0, 0x0006, 0x080c, 0x0f8b, 0x000e, 0x080c,
+	0x4bcf, 0x007e, 0x701f, 0x3c3e, 0x7023, 0x0001, 0x0005, 0x0804,
+	0x35b0, 0x0156, 0x00c6, 0xa814, 0x908a, 0x001e, 0x0218, 0xa833,
+	0x001e, 0x0010, 0xa832, 0x0078, 0x81ff, 0x0168, 0x0016, 0x080c,
+	0x4b83, 0x001e, 0x0130, 0xa800, 0x2040, 0xa008, 0xa80a, 0x2100,
+	0x0c58, 0x9006, 0x0010, 0x9085, 0x0001, 0x00ce, 0x015e, 0x0005,
+	0x0006, 0x00f6, 0x2079, 0x0000, 0x7880, 0x9086, 0x0044, 0x00fe,
+	0x000e, 0x0005, 0x2001, 0x19a0, 0x2003, 0x0001, 0x0005, 0x00f6,
+	0x00e6, 0x00c6, 0x2061, 0x0200, 0x2001, 0x19ab, 0x2004, 0x601a,
+	0x2061, 0x0100, 0x2001, 0x19aa, 0x2004, 0x60ce, 0x6104, 0xc1ac,
+	0x6106, 0x080c, 0x4b83, 0xa813, 0x0019, 0xa817, 0x0001, 0x2900,
+	0xa85a, 0x2001, 0x002e, 0x2004, 0xa866, 0x2001, 0x002f, 0x2004,
+	0xa86a, 0x2061, 0x0090, 0x2079, 0x0100, 0x2001, 0x19aa, 0x2004,
+	0x6036, 0x2009, 0x0040, 0x080c, 0x242a, 0x2001, 0x002a, 0x2004,
+	0x9084, 0xfff8, 0xa86e, 0x601a, 0xa873, 0x0000, 0x601f, 0x0000,
+	0x78ca, 0x9006, 0x600a, 0x600e, 0x00ce, 0x00ee, 0x00fe, 0x0005,
+	0x00e6, 0x080c, 0x4b83, 0x2940, 0xa013, 0x0019, 0xa017, 0x0001,
+	0x2800, 0xa05a, 0x2001, 0x0030, 0x2004, 0xa866, 0x2001, 0x0031,
+	0x2004, 0xa86a, 0x2001, 0x002a, 0x2004, 0x9084, 0xfff8, 0xa86e,
+	0xa873, 0x0000, 0x2001, 0x032a, 0x2003, 0x0004, 0x2001, 0x0300,
+	0x2003, 0x0000, 0x2001, 0x020d, 0x2003, 0x0000, 0x2001, 0x0004,
+	0x200c, 0x918d, 0x0002, 0x2102, 0x00ee, 0x0005, 0x0126, 0x2091,
+	0x8000, 0x81ff, 0x0148, 0x080c, 0x2c7b, 0x1130, 0x9006, 0x080c,
+	0x2bd3, 0x9006, 0x080c, 0x2bb6, 0x7884, 0x9084, 0x0007, 0x0002,
+	0x3dbb, 0x3dc4, 0x3dcd, 0x3db8, 0x3db8, 0x3db8, 0x3db8, 0x3db8,
+	0x012e, 0x0804, 0x35e5, 0x2009, 0x0114, 0x2104, 0x9085, 0x0800,
+	0x200a, 0x080c, 0x3f92, 0x00c0, 0x2009, 0x0114, 0x2104, 0x9085,
+	0x4000, 0x200a, 0x080c, 0x3f92, 0x0078, 0x080c, 0x7563, 0x1128,
+	0x012e, 0x2009, 0x0016, 0x0804, 0x35e2, 0x81ff, 0x0128, 0x012e,
+	0x2021, 0x400b, 0x0804, 0x35b2, 0x6000, 0x9086, 0x0003, 0x1db8,
+	0x2001, 0x0141, 0x2004, 0xd0dc, 0x0d90, 0x0086, 0x0096, 0x00a6,
+	0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x080c, 0x3ae6, 0x2009,
 	0x0101, 0x210c, 0x0016, 0x7ec8, 0x7dcc, 0x9006, 0x2068, 0x2060,
-	0x2058, 0x080c, 0x420b, 0x080c, 0x415b, 0x903e, 0x2720, 0x00f6,
-	0x00e6, 0x0086, 0x2940, 0x2071, 0x1a65, 0x2079, 0x0090, 0x00d6,
+	0x2058, 0x080c, 0x425b, 0x080c, 0x41ab, 0x903e, 0x2720, 0x00f6,
+	0x00e6, 0x0086, 0x2940, 0x2071, 0x1a6a, 0x2079, 0x0090, 0x00d6,
 	0x2069, 0x0000, 0x6884, 0xd0b4, 0x0120, 0x68d4, 0x780e, 0x68d0,
-	0x780a, 0x00de, 0x2011, 0x0001, 0x080c, 0x40bc, 0x080c, 0x2c76,
-	0x080c, 0x2c76, 0x080c, 0x2c76, 0x080c, 0x2c76, 0x080c, 0x40bc,
-	0x008e, 0x00ee, 0x00fe, 0x080c, 0x3fe9, 0x2009, 0x9c40, 0x8109,
-	0x11b0, 0x080c, 0x3ef8, 0x2001, 0x0004, 0x200c, 0x918c, 0xfffd,
+	0x780a, 0x00de, 0x2011, 0x0001, 0x080c, 0x410c, 0x080c, 0x2c83,
+	0x080c, 0x2c83, 0x080c, 0x2c83, 0x080c, 0x2c83, 0x080c, 0x410c,
+	0x008e, 0x00ee, 0x00fe, 0x080c, 0x4039, 0x2009, 0x9c40, 0x8109,
+	0x11b0, 0x080c, 0x3f48, 0x2001, 0x0004, 0x200c, 0x918c, 0xfffd,
 	0x2102, 0x001e, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x00ae,
-	0x009e, 0x008e, 0x2009, 0x0017, 0x080c, 0x35b5, 0x0cf8, 0x2001,
+	0x009e, 0x008e, 0x2009, 0x0017, 0x080c, 0x35e2, 0x0cf8, 0x2001,
 	0x020b, 0x2004, 0x9084, 0x0140, 0x1d10, 0x00f6, 0x2079, 0x0000,
 	0x7884, 0x00fe, 0xd0bc, 0x0178, 0x2001, 0x0201, 0x200c, 0x81ff,
-	0x0150, 0x080c, 0x3fc7, 0x2d00, 0x9c05, 0x9b05, 0x0120, 0x080c,
-	0x3ef8, 0x0804, 0x3ea5, 0x080c, 0x4130, 0x080c, 0x4054, 0x080c,
-	0x3faa, 0x080c, 0x3fdf, 0x00f6, 0x2079, 0x0100, 0x7824, 0xd0ac,
-	0x0130, 0x8b58, 0x080c, 0x3ef8, 0x00fe, 0x0804, 0x3ea5, 0x00fe,
-	0x080c, 0x3eee, 0x1150, 0x8d68, 0x2001, 0x0032, 0x2602, 0x2001,
-	0x0033, 0x2502, 0x080c, 0x3ef8, 0x0080, 0x87ff, 0x0138, 0x2001,
-	0x0201, 0x2004, 0x9005, 0x1908, 0x8739, 0x0038, 0x2001, 0x1a61,
-	0x2004, 0x9086, 0x0000, 0x1904, 0x3df5, 0x2001, 0x032f, 0x2003,
-	0x00f6, 0x8631, 0x1208, 0x8529, 0x2500, 0x9605, 0x0904, 0x3ea5,
-	0x7884, 0xd0bc, 0x0128, 0x2d00, 0x9c05, 0x9b05, 0x1904, 0x3ea5,
+	0x0150, 0x080c, 0x4017, 0x2d00, 0x9c05, 0x9b05, 0x0120, 0x080c,
+	0x3f48, 0x0804, 0x3ef5, 0x080c, 0x4180, 0x080c, 0x40a4, 0x080c,
+	0x3ffa, 0x080c, 0x402f, 0x00f6, 0x2079, 0x0100, 0x7824, 0xd0ac,
+	0x0130, 0x8b58, 0x080c, 0x3f48, 0x00fe, 0x0804, 0x3ef5, 0x00fe,
+	0x080c, 0x3f3e, 0x1150, 0x8d68, 0x2001, 0x0032, 0x2602, 0x2001,
+	0x0033, 0x2502, 0x080c, 0x3f48, 0x0080, 0x87ff, 0x0138, 0x2001,
+	0x0201, 0x2004, 0x9005, 0x1908, 0x8739, 0x0038, 0x2001, 0x1a66,
+	0x2004, 0x9086, 0x0000, 0x1904, 0x3e45, 0x2001, 0x032f, 0x2003,
+	0x00f6, 0x8631, 0x1208, 0x8529, 0x2500, 0x9605, 0x0904, 0x3ef5,
+	0x7884, 0xd0bc, 0x0128, 0x2d00, 0x9c05, 0x9b05, 0x1904, 0x3ef5,
 	0xa013, 0x0019, 0x2001, 0x032a, 0x2003, 0x0004, 0x7884, 0xd0ac,
-	0x1148, 0x2001, 0x1a61, 0x2003, 0x0003, 0x2001, 0x032a, 0x2003,
+	0x1148, 0x2001, 0x1a66, 0x2003, 0x0003, 0x2001, 0x032a, 0x2003,
 	0x0009, 0x0030, 0xa017, 0x0001, 0x78b4, 0x9005, 0x0108, 0xa016,
-	0x2800, 0xa05a, 0x2009, 0x0040, 0x080c, 0x2410, 0x2900, 0xa85a,
+	0x2800, 0xa05a, 0x2009, 0x0040, 0x080c, 0x242a, 0x2900, 0xa85a,
 	0xa813, 0x0019, 0x7884, 0xd0a4, 0x1180, 0xa817, 0x0000, 0x00c6,
 	0x20a9, 0x0004, 0x2061, 0x0090, 0x602b, 0x0008, 0x2001, 0x0203,
-	0x2004, 0x1f04, 0x3e7c, 0x00ce, 0x0030, 0xa817, 0x0001, 0x78b0,
+	0x2004, 0x1f04, 0x3ecc, 0x00ce, 0x0030, 0xa817, 0x0001, 0x78b0,
 	0x9005, 0x0108, 0xa816, 0x00f6, 0x00c6, 0x2079, 0x0100, 0x2061,
 	0x0090, 0x7827, 0x0002, 0x2001, 0x002a, 0x2004, 0x9084, 0xfff8,
 	0x601a, 0x0006, 0x2001, 0x002b, 0x2004, 0x601e, 0x78c6, 0x000e,
-	0x78ca, 0x00ce, 0x00fe, 0x0804, 0x3daf, 0x001e, 0x00c6, 0x2001,
+	0x78ca, 0x00ce, 0x00fe, 0x0804, 0x3dff, 0x001e, 0x00c6, 0x2001,
 	0x032a, 0x2003, 0x0004, 0x2061, 0x0100, 0x6027, 0x0002, 0x6106,
 	0x2011, 0x020d, 0x2013, 0x0020, 0x2001, 0x0004, 0x200c, 0x918c,
-	0xfffd, 0x2102, 0x080c, 0x12ed, 0x7884, 0x9084, 0x0003, 0x9086,
-	0x0002, 0x01a0, 0x2009, 0x0028, 0x080c, 0x2410, 0x2001, 0x0227,
+	0xfffd, 0x2102, 0x080c, 0x12fc, 0x7884, 0x9084, 0x0003, 0x9086,
+	0x0002, 0x01a0, 0x2009, 0x0028, 0x080c, 0x242a, 0x2001, 0x0227,
 	0x200c, 0x2102, 0x6050, 0x9084, 0xb7ef, 0x6052, 0x602f, 0x0000,
 	0x604b, 0xf7f7, 0x6043, 0x0090, 0x6043, 0x0010, 0x00ce, 0x2d08,
 	0x2c10, 0x2b18, 0x2b00, 0x9c05, 0x9d05, 0x00fe, 0x00ee, 0x00de,
 	0x00ce, 0x00be, 0x00ae, 0x009e, 0x008e, 0x1118, 0x012e, 0x0804,
-	0x3583, 0x012e, 0x2021, 0x400c, 0x0804, 0x3585, 0x9085, 0x0001,
-	0x1d04, 0x3ef7, 0x2091, 0x6000, 0x8420, 0x9486, 0x0064, 0x0005,
+	0x35b0, 0x012e, 0x2021, 0x400c, 0x0804, 0x35b2, 0x9085, 0x0001,
+	0x1d04, 0x3f47, 0x2091, 0x6000, 0x8420, 0x9486, 0x0064, 0x0005,
 	0x2001, 0x0105, 0x2003, 0x0010, 0x2001, 0x032a, 0x2003, 0x0004,
-	0x2001, 0x1a61, 0x2003, 0x0000, 0x0071, 0x2009, 0x0048, 0x080c,
-	0x2410, 0x2001, 0x0227, 0x2024, 0x2402, 0x2001, 0x0109, 0x2003,
-	0x4000, 0x9026, 0x0005, 0x00f6, 0x00e6, 0x2071, 0x1a65, 0x7000,
+	0x2001, 0x1a66, 0x2003, 0x0000, 0x0071, 0x2009, 0x0048, 0x080c,
+	0x242a, 0x2001, 0x0227, 0x2024, 0x2402, 0x2001, 0x0109, 0x2003,
+	0x4000, 0x9026, 0x0005, 0x00f6, 0x00e6, 0x2071, 0x1a6a, 0x7000,
 	0x9086, 0x0000, 0x0520, 0x2079, 0x0090, 0x2009, 0x0206, 0x2104,
 	0x2009, 0x0203, 0x210c, 0x9106, 0x1120, 0x2009, 0x0040, 0x080c,
-	0x2410, 0x782c, 0xd0fc, 0x0d88, 0x080c, 0x4130, 0x7000, 0x9086,
+	0x242a, 0x782c, 0xd0fc, 0x0d88, 0x080c, 0x4180, 0x7000, 0x9086,
 	0x0000, 0x1d58, 0x782b, 0x0004, 0x782c, 0xd0ac, 0x1de8, 0x2009,
-	0x0040, 0x080c, 0x2410, 0x782b, 0x0002, 0x7003, 0x0000, 0x00ee,
+	0x0040, 0x080c, 0x242a, 0x782b, 0x0002, 0x7003, 0x0000, 0x00ee,
 	0x00fe, 0x0005, 0x00f6, 0x2079, 0x0100, 0x2001, 0x1818, 0x200c,
-	0x7932, 0x7936, 0x080c, 0x28c5, 0x7850, 0x9084, 0xfbff, 0x9085,
+	0x7932, 0x7936, 0x080c, 0x28d2, 0x7850, 0x9084, 0xfbff, 0x9085,
 	0x0030, 0x7852, 0x2019, 0x01f4, 0x8319, 0x1df0, 0x9084, 0xffcf,
-	0x9085, 0x2000, 0x7852, 0x20a9, 0x0046, 0x1d04, 0x3f5d, 0x2091,
-	0x6000, 0x1f04, 0x3f5d, 0x7850, 0x9085, 0x0400, 0x9084, 0xdfff,
+	0x9085, 0x2000, 0x7852, 0x20a9, 0x0046, 0x1d04, 0x3fad, 0x2091,
+	0x6000, 0x1f04, 0x3fad, 0x7850, 0x9085, 0x0400, 0x9084, 0xdfff,
 	0x7852, 0x2001, 0x0021, 0x2004, 0x9084, 0x0003, 0x9086, 0x0001,
 	0x1120, 0x7850, 0x9084, 0xdfff, 0x7852, 0x784b, 0xf7f7, 0x7843,
-	0x0090, 0x7843, 0x0010, 0x20a9, 0x0028, 0xa001, 0x1f04, 0x3f7d,
+	0x0090, 0x7843, 0x0010, 0x20a9, 0x0028, 0xa001, 0x1f04, 0x3fcd,
 	0x7850, 0x9085, 0x1400, 0x7852, 0x2019, 0x61a8, 0x7854, 0xa001,
 	0xa001, 0xd08c, 0x1110, 0x8319, 0x1dc8, 0x7827, 0x0048, 0x7850,
 	0x9085, 0x0400, 0x7852, 0x7843, 0x0040, 0x2019, 0x01f4, 0xa001,
-	0xa001, 0x8319, 0x1de0, 0x2001, 0x0100, 0x080c, 0x2d4e, 0x7827,
-	0x0020, 0x7843, 0x0000, 0x9006, 0x080c, 0x2d4e, 0x7827, 0x0048,
+	0xa001, 0x8319, 0x1de0, 0x2001, 0x0100, 0x080c, 0x2d5b, 0x7827,
+	0x0020, 0x7843, 0x0000, 0x9006, 0x080c, 0x2d5b, 0x7827, 0x0048,
 	0x00fe, 0x0005, 0x7884, 0xd0ac, 0x11c8, 0x00f6, 0x00e6, 0x2071,
-	0x1a61, 0x2079, 0x0320, 0x2001, 0x0201, 0x2004, 0x9005, 0x0160,
+	0x1a66, 0x2079, 0x0320, 0x2001, 0x0201, 0x2004, 0x9005, 0x0160,
 	0x7000, 0x9086, 0x0000, 0x1140, 0x0051, 0xd0bc, 0x0108, 0x8738,
 	0x7003, 0x0003, 0x782b, 0x0019, 0x00ee, 0x00fe, 0x0005, 0x00f6,
 	0x2079, 0x0300, 0x78bc, 0x00fe, 0x908c, 0x0070, 0x0178, 0x2009,
 	0x0032, 0x260a, 0x2009, 0x0033, 0x250a, 0xd0b4, 0x0108, 0x8c60,
 	0xd0ac, 0x0108, 0x8d68, 0xd0a4, 0x0108, 0x8b58, 0x0005, 0x00f6,
 	0x2079, 0x0200, 0x781c, 0xd084, 0x0110, 0x7837, 0x0050, 0x00fe,
-	0x0005, 0x00e6, 0x2071, 0x0100, 0x2001, 0x19a9, 0x2004, 0x70e2,
-	0x080c, 0x3cd9, 0x1188, 0x2001, 0x1820, 0x2004, 0x2009, 0x181f,
+	0x0005, 0x00e6, 0x2071, 0x0100, 0x2001, 0x19ab, 0x2004, 0x70e2,
+	0x080c, 0x3d20, 0x1188, 0x2001, 0x1820, 0x2004, 0x2009, 0x181f,
 	0x210c, 0x918c, 0x00ff, 0x706e, 0x716a, 0x7066, 0x918d, 0x3200,
 	0x7162, 0x7073, 0xe109, 0x0080, 0x702c, 0x9085, 0x0002, 0x702e,
 	0x2009, 0x1818, 0x210c, 0x716e, 0x7063, 0x0100, 0x7166, 0x719e,
 	0x706b, 0x0000, 0x7073, 0x0809, 0x7077, 0x0008, 0x7078, 0x9080,
 	0x0100, 0x707a, 0x7080, 0x8000, 0x7082, 0x7087, 0xaaaa, 0x9006,
 	0x708a, 0x708e, 0x707e, 0x70d6, 0x70ab, 0x0036, 0x70af, 0x95d5,
-	0x7014, 0x9084, 0x1984, 0x9085, 0x0092, 0x7016, 0x080c, 0x4130,
-	0x00f6, 0x2071, 0x1a61, 0x2079, 0x0320, 0x00d6, 0x2069, 0x0000,
+	0x7014, 0x9084, 0x1984, 0x9085, 0x0092, 0x7016, 0x080c, 0x4180,
+	0x00f6, 0x2071, 0x1a66, 0x2079, 0x0320, 0x00d6, 0x2069, 0x0000,
 	0x6884, 0xd0b4, 0x0120, 0x689c, 0x780e, 0x6898, 0x780a, 0x00de,
 	0x2009, 0x03e8, 0x8109, 0x1df0, 0x792c, 0xd1fc, 0x0110, 0x782b,
-	0x0004, 0x2011, 0x0011, 0x080c, 0x40bc, 0x2011, 0x0001, 0x080c,
-	0x40bc, 0x00fe, 0x00ee, 0x0005, 0x00f6, 0x00e6, 0x2071, 0x1a61,
-	0x2079, 0x0320, 0x792c, 0xd1fc, 0x0904, 0x40b9, 0x782b, 0x0002,
-	0x9026, 0xd19c, 0x1904, 0x40b5, 0x7000, 0x0002, 0x40b9, 0x406a,
-	0x409a, 0x40b5, 0xd1bc, 0x1170, 0xd1dc, 0x1190, 0x8001, 0x7002,
-	0x2011, 0x0001, 0x080c, 0x40bc, 0x0904, 0x40b9, 0x080c, 0x40bc,
-	0x0804, 0x40b9, 0x00f6, 0x2079, 0x0300, 0x78bf, 0x0000, 0x00fe,
+	0x0004, 0x2011, 0x0011, 0x080c, 0x410c, 0x2011, 0x0001, 0x080c,
+	0x410c, 0x00fe, 0x00ee, 0x0005, 0x00f6, 0x00e6, 0x2071, 0x1a66,
+	0x2079, 0x0320, 0x792c, 0xd1fc, 0x0904, 0x4109, 0x782b, 0x0002,
+	0x9026, 0xd19c, 0x1904, 0x4105, 0x7000, 0x0002, 0x4109, 0x40ba,
+	0x40ea, 0x4105, 0xd1bc, 0x1170, 0xd1dc, 0x1190, 0x8001, 0x7002,
+	0x2011, 0x0001, 0x080c, 0x410c, 0x0904, 0x4109, 0x080c, 0x410c,
+	0x0804, 0x4109, 0x00f6, 0x2079, 0x0300, 0x78bf, 0x0000, 0x00fe,
 	0x7810, 0x7914, 0x782b, 0x0004, 0x7812, 0x7916, 0x2001, 0x0201,
-	0x200c, 0x81ff, 0x0de8, 0x080c, 0x3fc7, 0x2009, 0x0001, 0x00f6,
+	0x200c, 0x81ff, 0x0de8, 0x080c, 0x4017, 0x2009, 0x0001, 0x00f6,
 	0x2079, 0x0300, 0x78b8, 0x00fe, 0xd0ec, 0x0110, 0x2009, 0x0011,
 	0x792a, 0x00f8, 0x8001, 0x7002, 0x9184, 0x0880, 0x1140, 0x782c,
-	0xd0fc, 0x1904, 0x405e, 0x2011, 0x0001, 0x00b1, 0x0090, 0xa010,
+	0xd0fc, 0x1904, 0x40ae, 0x2011, 0x0001, 0x00b1, 0x0090, 0xa010,
 	0x9092, 0x0004, 0x9086, 0x0015, 0x1120, 0xa000, 0xa05a, 0x2011,
 	0x0031, 0xa212, 0xd1dc, 0x1960, 0x0828, 0x782b, 0x0004, 0x7003,
 	0x0000, 0x00ee, 0x00fe, 0x0005, 0xa014, 0x9005, 0x0550, 0x8001,
 	0x0036, 0x0096, 0xa016, 0xa058, 0x2048, 0xa010, 0x2009, 0x0031,
-	0x911a, 0x831c, 0x831c, 0x938a, 0x0007, 0x1a0c, 0x0dd5, 0x9398,
-	0x40ea, 0x231d, 0x083f, 0x9080, 0x0004, 0x7a2a, 0x7100, 0x8108,
+	0x911a, 0x831c, 0x831c, 0x938a, 0x0007, 0x1a0c, 0x0dc5, 0x9398,
+	0x413a, 0x231d, 0x083f, 0x9080, 0x0004, 0x7a2a, 0x7100, 0x8108,
 	0x7102, 0x009e, 0x003e, 0x908a, 0x0035, 0x1140, 0x0096, 0xa058,
 	0x2048, 0xa804, 0xa05a, 0x2001, 0x0019, 0x009e, 0xa012, 0x9085,
-	0x0001, 0x0005, 0x4127, 0x411e, 0x4115, 0x410c, 0x4103, 0x40fa,
-	0x40f1, 0xa964, 0x7902, 0xa968, 0x7906, 0xa96c, 0x7912, 0xa970,
+	0x0001, 0x0005, 0x4177, 0x416e, 0x4165, 0x415c, 0x4153, 0x414a,
+	0x4141, 0xa964, 0x7902, 0xa968, 0x7906, 0xa96c, 0x7912, 0xa970,
 	0x7916, 0x0005, 0xa974, 0x7902, 0xa978, 0x7906, 0xa97c, 0x7912,
 	0xa980, 0x7916, 0x0005, 0xa984, 0x7902, 0xa988, 0x7906, 0xa98c,
 	0x7912, 0xa990, 0x7916, 0x0005, 0xa994, 0x7902, 0xa998, 0x7906,
@@ -1880,24 +1890,24 @@ unsigned short risc_code01[] = { 
 	0x7906, 0xa9ac, 0x7912, 0xa9b0, 0x7916, 0x0005, 0xa9b4, 0x7902,
 	0xa9b8, 0x7906, 0xa9bc, 0x7912, 0xa9c0, 0x7916, 0x0005, 0xa9c4,
 	0x7902, 0xa9c8, 0x7906, 0xa9cc, 0x7912, 0xa9d0, 0x7916, 0x0005,
-	0x00f6, 0x00e6, 0x0086, 0x2071, 0x1a65, 0x2079, 0x0090, 0x792c,
+	0x00f6, 0x00e6, 0x0086, 0x2071, 0x1a6a, 0x2079, 0x0090, 0x792c,
 	0xd1fc, 0x01e8, 0x782b, 0x0002, 0x2940, 0x9026, 0x7000, 0x0002,
-	0x4157, 0x4143, 0x414e, 0x8001, 0x7002, 0xd19c, 0x1180, 0x2011,
-	0x0001, 0x080c, 0x40bc, 0x190c, 0x40bc, 0x0048, 0x8001, 0x7002,
-	0x782c, 0xd0fc, 0x1d38, 0x2011, 0x0001, 0x080c, 0x40bc, 0x008e,
+	0x41a7, 0x4193, 0x419e, 0x8001, 0x7002, 0xd19c, 0x1180, 0x2011,
+	0x0001, 0x080c, 0x410c, 0x190c, 0x410c, 0x0048, 0x8001, 0x7002,
+	0x782c, 0xd0fc, 0x1d38, 0x2011, 0x0001, 0x080c, 0x410c, 0x008e,
 	0x00ee, 0x00fe, 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x0086, 0x2061,
-	0x0200, 0x2001, 0x19a9, 0x2004, 0x601a, 0x2061, 0x0100, 0x2001,
-	0x19a8, 0x2004, 0x60ce, 0x6104, 0xc1ac, 0x6106, 0x2001, 0x002c,
+	0x0200, 0x2001, 0x19ab, 0x2004, 0x601a, 0x2061, 0x0100, 0x2001,
+	0x19aa, 0x2004, 0x60ce, 0x6104, 0xc1ac, 0x6106, 0x2001, 0x002c,
 	0x2004, 0x9005, 0x0520, 0x2038, 0x2001, 0x002e, 0x2024, 0x2001,
-	0x002f, 0x201c, 0x080c, 0x4b1f, 0xa813, 0x0019, 0xaf16, 0x2900,
+	0x002f, 0x201c, 0x080c, 0x4b83, 0xa813, 0x0019, 0xaf16, 0x2900,
 	0xa85a, 0x978a, 0x0007, 0x0220, 0x2138, 0x2009, 0x0007, 0x0010,
 	0x2708, 0x903e, 0x0096, 0xa858, 0x2048, 0xa85c, 0x9080, 0x0019,
-	0x009e, 0x080c, 0x41d3, 0x1d68, 0x2900, 0xa85a, 0x00d0, 0x080c,
-	0x4b1f, 0xa813, 0x0019, 0xa817, 0x0001, 0x2900, 0xa85a, 0x2001,
+	0x009e, 0x080c, 0x4223, 0x1d68, 0x2900, 0xa85a, 0x00d0, 0x080c,
+	0x4b83, 0xa813, 0x0019, 0xa817, 0x0001, 0x2900, 0xa85a, 0x2001,
 	0x002e, 0x2004, 0xa866, 0x2001, 0x002f, 0x2004, 0xa86a, 0x2001,
 	0x002a, 0x2004, 0x9084, 0xfff8, 0xa86e, 0x2001, 0x002b, 0x2004,
-	0xa872, 0x2061, 0x0090, 0x2079, 0x0100, 0x2001, 0x19a8, 0x2004,
-	0x6036, 0x2009, 0x0040, 0x080c, 0x2410, 0x2001, 0x002a, 0x2004,
+	0xa872, 0x2061, 0x0090, 0x2079, 0x0100, 0x2001, 0x19aa, 0x2004,
+	0x6036, 0x2009, 0x0040, 0x080c, 0x242a, 0x2001, 0x002a, 0x2004,
 	0x9084, 0xfff8, 0x601a, 0x0006, 0x2001, 0x002b, 0x2004, 0x601e,
 	0x78c6, 0x000e, 0x78ca, 0x9006, 0x600a, 0x600e, 0x008e, 0x00ce,
 	0x00ee, 0x00fe, 0x0005, 0x00e6, 0x2071, 0x0080, 0xaa60, 0x22e8,
@@ -1905,1273 +1915,1279 @@ unsigned short risc_code01[] = { 
 	0x7306, 0x9006, 0x700a, 0x700e, 0x810b, 0x810b, 0x21a8, 0x810b,
 	0x7112, 0x702b, 0x0041, 0x702c, 0xd0fc, 0x0de8, 0x702b, 0x0002,
 	0x702b, 0x0040, 0x4005, 0x7400, 0x7304, 0x87ff, 0x0190, 0x0086,
-	0x0096, 0x2940, 0x0086, 0x080c, 0x4b1f, 0x008e, 0xa058, 0x00a6,
+	0x0096, 0x2940, 0x0086, 0x080c, 0x4b83, 0x008e, 0xa058, 0x00a6,
 	0x2050, 0x2900, 0xb006, 0xa05a, 0x00ae, 0x009e, 0x008e, 0x9085,
 	0x0001, 0x00ee, 0x0005, 0x00e6, 0x2001, 0x002d, 0x2004, 0x9005,
 	0x0528, 0x2038, 0x2001, 0x0030, 0x2024, 0x2001, 0x0031, 0x201c,
-	0x080c, 0x4b1f, 0x2940, 0xa813, 0x0019, 0xaf16, 0x2900, 0xa85a,
+	0x080c, 0x4b83, 0x2940, 0xa813, 0x0019, 0xaf16, 0x2900, 0xa85a,
 	0x978a, 0x0007, 0x0220, 0x2138, 0x2009, 0x0007, 0x0010, 0x2708,
 	0x903e, 0x0096, 0xa858, 0x2048, 0xa85c, 0x9080, 0x0019, 0x009e,
-	0x080c, 0x41d3, 0x1d68, 0x2900, 0xa85a, 0x00d8, 0x080c, 0x4b1f,
+	0x080c, 0x4223, 0x1d68, 0x2900, 0xa85a, 0x00d8, 0x080c, 0x4b83,
 	0x2940, 0xa013, 0x0019, 0xa017, 0x0001, 0x2800, 0xa05a, 0x2001,
 	0x0030, 0x2004, 0xa066, 0x2001, 0x0031, 0x2004, 0xa06a, 0x2001,
 	0x002a, 0x2004, 0x9084, 0xfff8, 0xa06e, 0x2001, 0x002b, 0x2004,
 	0xa072, 0x2001, 0x032a, 0x2003, 0x0004, 0x7884, 0xd0ac, 0x1180,
 	0x2001, 0x0101, 0x200c, 0x918d, 0x0200, 0x2102, 0xa017, 0x0000,
-	0x2001, 0x1a61, 0x2003, 0x0003, 0x2001, 0x032a, 0x2003, 0x0009,
+	0x2001, 0x1a66, 0x2003, 0x0003, 0x2001, 0x032a, 0x2003, 0x0009,
 	0x2001, 0x0300, 0x2003, 0x0000, 0x2001, 0x020d, 0x2003, 0x0000,
 	0x2001, 0x0004, 0x200c, 0x918d, 0x0002, 0x2102, 0x00ee, 0x0005,
 	0x0126, 0x2091, 0x8000, 0x20a9, 0x0007, 0x20a1, 0x1840, 0x20e9,
 	0x0001, 0x9006, 0x4004, 0x20a9, 0x0014, 0x20a1, 0xffec, 0x20e9,
 	0x0000, 0x9006, 0x4004, 0x2009, 0x013c, 0x200a, 0x012e, 0x7880,
-	0x9086, 0x0052, 0x0108, 0x0005, 0x0804, 0x3583, 0x7d98, 0x7c9c,
-	0x0804, 0x3685, 0x080c, 0x743e, 0x190c, 0x6072, 0x6040, 0x9084,
+	0x9086, 0x0052, 0x0108, 0x0005, 0x0804, 0x35b0, 0x7d98, 0x7c9c,
+	0x0804, 0x36b4, 0x080c, 0x7563, 0x190c, 0x60e6, 0x6040, 0x9084,
 	0x0020, 0x09b1, 0x2069, 0x1847, 0x2d00, 0x2009, 0x0030, 0x7a8c,
-	0x7b88, 0x7c9c, 0x7d98, 0x2039, 0x0001, 0x080c, 0x4b68, 0x701f,
-	0x42b2, 0x0005, 0x080c, 0x576c, 0x1130, 0x3b00, 0x3a08, 0xc194,
+	0x7b88, 0x7c9c, 0x7d98, 0x2039, 0x0001, 0x080c, 0x4bcc, 0x701f,
+	0x4302, 0x0005, 0x080c, 0x57dc, 0x1130, 0x3b00, 0x3a08, 0xc194,
 	0xc095, 0x20d8, 0x21d0, 0x2069, 0x1847, 0x6800, 0x9005, 0x0904,
-	0x35b8, 0x6804, 0xd0ac, 0x0118, 0xd0a4, 0x0904, 0x35b8, 0xd094,
+	0x35e5, 0x6804, 0xd0ac, 0x0118, 0xd0a4, 0x0904, 0x35e5, 0xd094,
 	0x00c6, 0x2061, 0x0100, 0x6104, 0x0138, 0x6200, 0x9292, 0x0005,
 	0x0218, 0x918c, 0xffdf, 0x0010, 0x918d, 0x0020, 0x6106, 0x00ce,
 	0xd08c, 0x00c6, 0x2061, 0x0100, 0x6104, 0x0118, 0x918d, 0x0010,
 	0x0010, 0x918c, 0xffef, 0x6106, 0x00ce, 0xd084, 0x0158, 0x6a28,
-	0x928a, 0x007f, 0x1a04, 0x35b8, 0x9288, 0x3384, 0x210d, 0x918c,
+	0x928a, 0x007f, 0x1a04, 0x35e5, 0x9288, 0x33b1, 0x210d, 0x918c,
 	0x00ff, 0x6166, 0xd0dc, 0x0130, 0x6828, 0x908a, 0x007f, 0x1a04,
-	0x35b8, 0x605e, 0x6888, 0x9084, 0x0030, 0x8004, 0x8004, 0x8004,
-	0x8004, 0x0006, 0x2009, 0x19b0, 0x9080, 0x29b8, 0x2005, 0x200a,
-	0x000e, 0x2009, 0x19b1, 0x9080, 0x29bc, 0x2005, 0x200a, 0x6808,
-	0x908a, 0x0100, 0x0a04, 0x35b8, 0x908a, 0x0841, 0x1a04, 0x35b8,
-	0x9084, 0x0007, 0x1904, 0x35b8, 0x680c, 0x9005, 0x0904, 0x35b8,
-	0x6810, 0x9005, 0x0904, 0x35b8, 0x6848, 0x6940, 0x910a, 0x1a04,
-	0x35b8, 0x8001, 0x0904, 0x35b8, 0x684c, 0x6944, 0x910a, 0x1a04,
-	0x35b8, 0x8001, 0x0904, 0x35b8, 0x2009, 0x1980, 0x200b, 0x0000,
-	0x2001, 0x1869, 0x2004, 0xd0c4, 0x0140, 0x7884, 0x200a, 0x2009,
-	0x017f, 0x200a, 0x3b00, 0xc085, 0x20d8, 0x6814, 0x908c, 0x00ff,
-	0x614e, 0x8007, 0x9084, 0x00ff, 0x6052, 0x080c, 0x7755, 0x080c,
-	0x6a3e, 0x080c, 0x6a72, 0x6808, 0x602a, 0x080c, 0x2382, 0x2009,
+	0x35e5, 0x605e, 0x6888, 0x9084, 0x0030, 0x8004, 0x8004, 0x8004,
+	0x8004, 0x0006, 0x2009, 0x19b3, 0x9080, 0x29c5, 0x2005, 0x200a,
+	0x000e, 0x2009, 0x19b4, 0x9080, 0x29c9, 0x2005, 0x200a, 0x6808,
+	0x908a, 0x0100, 0x0a04, 0x35e5, 0x908a, 0x0841, 0x1a04, 0x35e5,
+	0x9084, 0x0007, 0x1904, 0x35e5, 0x680c, 0x9005, 0x0904, 0x35e5,
+	0x6810, 0x9005, 0x0904, 0x35e5, 0x6848, 0x6940, 0x910a, 0x1a04,
+	0x35e5, 0x8001, 0x0904, 0x35e5, 0x684c, 0x6944, 0x910a, 0x1a04,
+	0x35e5, 0x8001, 0x0904, 0x35e5, 0x2009, 0x1982, 0x200b, 0x0000,
+	0x2001, 0x1869, 0x2004, 0xd0c4, 0x0140, 0x7884, 0x200a, 0x2008,
+	0x080c, 0x0e52, 0x3b00, 0xc085, 0x20d8, 0x6814, 0x908c, 0x00ff,
+	0x614e, 0x8007, 0x9084, 0x00ff, 0x6052, 0x080c, 0x7879, 0x080c,
+	0x6ac2, 0x080c, 0x6b24, 0x6808, 0x602a, 0x080c, 0x239c, 0x2009,
 	0x0170, 0x200b, 0x0080, 0xa001, 0xa001, 0x200b, 0x0000, 0x0036,
-	0x6b08, 0x080c, 0x291f, 0x003e, 0x6000, 0x9086, 0x0000, 0x1904,
-	0x4449, 0x6818, 0x691c, 0x6a20, 0x6b24, 0x8007, 0x810f, 0x8217,
+	0x6b08, 0x080c, 0x292c, 0x003e, 0x6000, 0x9086, 0x0000, 0x1904,
+	0x449e, 0x6818, 0x691c, 0x6a20, 0x6b24, 0x8007, 0x810f, 0x8217,
 	0x831f, 0x6016, 0x611a, 0x621e, 0x6322, 0x6c04, 0xd4f4, 0x0148,
 	0x6830, 0x6934, 0x6a38, 0x6b3c, 0x8007, 0x810f, 0x8217, 0x831f,
 	0x0010, 0x9084, 0xf0ff, 0x6006, 0x610a, 0x620e, 0x6312, 0x8007,
-	0x810f, 0x8217, 0x831f, 0x20a9, 0x0004, 0x20a1, 0x19b2, 0x20e9,
-	0x0001, 0x4001, 0x20a9, 0x0004, 0x20a1, 0x19cc, 0x20e9, 0x0001,
-	0x4001, 0x080c, 0x86ac, 0x00c6, 0x900e, 0x20a9, 0x0001, 0x6b70,
+	0x810f, 0x8217, 0x831f, 0x20a9, 0x0004, 0x20a1, 0x19b5, 0x20e9,
+	0x0001, 0x4001, 0x20a9, 0x0004, 0x20a1, 0x19cf, 0x20e9, 0x0001,
+	0x4001, 0x080c, 0x8828, 0x00c6, 0x900e, 0x20a9, 0x0001, 0x6b70,
 	0xd384, 0x0510, 0x0068, 0x2009, 0x0100, 0x210c, 0x918e, 0x0008,
 	0x1110, 0x839d, 0x0010, 0x83f5, 0x3e18, 0x12b0, 0x3508, 0x8109,
-	0x080c, 0x7d0c, 0x6878, 0x6016, 0x6874, 0x2008, 0x9084, 0xff00,
+	0x080c, 0x7e35, 0x6878, 0x6016, 0x6874, 0x2008, 0x9084, 0xff00,
 	0x8007, 0x600a, 0x9184, 0x00ff, 0x6006, 0x8108, 0x1118, 0x6003,
-	0x0003, 0x0010, 0x6003, 0x0001, 0x1f04, 0x43a3, 0x00ce, 0x00c6,
-	0x2061, 0x199b, 0x6a88, 0x9284, 0xc000, 0x2010, 0x9286, 0x0000,
-	0x1158, 0x2063, 0x0000, 0x2001, 0x0001, 0x080c, 0x2bc6, 0x2001,
-	0x0001, 0x080c, 0x2ba9, 0x0088, 0x9286, 0x4000, 0x1148, 0x2063,
-	0x0001, 0x9006, 0x080c, 0x2bc6, 0x9006, 0x080c, 0x2ba9, 0x0028,
-	0x9286, 0x8000, 0x1d30, 0x2063, 0x0002, 0x00ce, 0x6888, 0xd0ec,
-	0x0130, 0x2011, 0x0114, 0x2204, 0x9085, 0x0100, 0x2012, 0x6a80,
-	0x9284, 0x0030, 0x9086, 0x0030, 0x1128, 0x9294, 0xffcf, 0x9295,
-	0x0020, 0x6a82, 0x2001, 0x197b, 0x6a80, 0x9294, 0x0030, 0x928e,
-	0x0000, 0x0170, 0x928e, 0x0010, 0x0118, 0x928e, 0x0020, 0x0140,
-	0x2003, 0xaaaa, 0x080c, 0x2994, 0x2001, 0x196c, 0x2102, 0x0008,
-	0x2102, 0x00c6, 0x2061, 0x0100, 0x602f, 0x0040, 0x602f, 0x0000,
-	0x00ce, 0x080c, 0x743e, 0x0128, 0x080c, 0x5054, 0x0110, 0x080c,
-	0x28e5, 0x60d4, 0x9005, 0x01c0, 0x6003, 0x0001, 0x2009, 0x4431,
-	0x00e0, 0x080c, 0x743e, 0x1168, 0x2011, 0x72ce, 0x080c, 0x85b0,
-	0x2011, 0x72c1, 0x080c, 0x868a, 0x080c, 0x7729, 0x080c, 0x736a,
-	0x0040, 0x080c, 0x5f6c, 0x0028, 0x6003, 0x0004, 0x2009, 0x4449,
-	0x0020, 0x080c, 0x696e, 0x0804, 0x3583, 0x2001, 0x0170, 0x2004,
-	0x9084, 0x00ff, 0x9086, 0x004c, 0x1118, 0x2091, 0x30bd, 0x0817,
-	0x2091, 0x303d, 0x0817, 0x6000, 0x9086, 0x0000, 0x0904, 0x35b5,
-	0x2069, 0x1847, 0x7890, 0x6842, 0x7894, 0x6846, 0x2d00, 0x2009,
-	0x0030, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x2039, 0x0001, 0x0804,
-	0x4b6b, 0x9006, 0x080c, 0x28e5, 0x81ff, 0x1904, 0x35b5, 0x080c,
-	0x743e, 0x11b0, 0x080c, 0x7724, 0x080c, 0x60ad, 0x080c, 0x3378,
-	0x0118, 0x6130, 0xc18d, 0x6132, 0x080c, 0xd388, 0x0130, 0x080c,
-	0x7461, 0x1118, 0x080c, 0x7416, 0x0038, 0x080c, 0x736a, 0x0020,
-	0x080c, 0x6072, 0x080c, 0x5f6c, 0x0804, 0x3583, 0x81ff, 0x1904,
-	0x35b5, 0x080c, 0x743e, 0x1110, 0x0804, 0x35b5, 0x6194, 0x81ff,
-	0x01a8, 0x704f, 0x0000, 0x2001, 0x1c80, 0x2009, 0x0040, 0x7a8c,
-	0x7b88, 0x7c9c, 0x7d98, 0x0126, 0x2091, 0x8000, 0x2039, 0x0001,
-	0x080c, 0x4b6b, 0x701f, 0x3581, 0x012e, 0x0005, 0x704f, 0x0001,
-	0x00d6, 0x2069, 0x1c80, 0x20a9, 0x0040, 0x20e9, 0x0001, 0x20a1,
-	0x1c80, 0x2019, 0xffff, 0x4304, 0x655c, 0x9588, 0x3384, 0x210d,
-	0x918c, 0x00ff, 0x216a, 0x900e, 0x2011, 0x0002, 0x2100, 0x9506,
-	0x01a8, 0x080c, 0x6699, 0x1190, 0xb814, 0x821c, 0x0238, 0x9398,
-	0x1c80, 0x9085, 0xff00, 0x8007, 0x201a, 0x0038, 0x9398, 0x1c80,
-	0x2324, 0x94a4, 0xff00, 0x9405, 0x201a, 0x8210, 0x8108, 0x9182,
-	0x0080, 0x1208, 0x0c18, 0x8201, 0x8007, 0x2d0c, 0x9105, 0x206a,
-	0x00de, 0x20a9, 0x0040, 0x20a1, 0x1c80, 0x2099, 0x1c80, 0x080c,
-	0x5ffd, 0x0804, 0x44a3, 0x080c, 0x4b52, 0x0904, 0x35b8, 0x080c,
-	0x4b1f, 0x1120, 0x2009, 0x0002, 0x0804, 0x35b5, 0x080c, 0x575d,
-	0xd0b4, 0x0558, 0x7884, 0x908e, 0x007e, 0x0538, 0x908e, 0x007f,
-	0x0520, 0x908e, 0x0080, 0x0508, 0x080c, 0x3373, 0x1148, 0xb800,
-	0xd08c, 0x11d8, 0xb804, 0x9084, 0x00ff, 0x9086, 0x0006, 0x11a8,
-	0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x080c, 0xce51, 0x1120,
-	0x2009, 0x0003, 0x0804, 0x35b5, 0x7007, 0x0003, 0x701f, 0x4531,
-	0x0005, 0x080c, 0x4b52, 0x0904, 0x35b8, 0x20a9, 0x002b, 0xb8c4,
-	0x20e0, 0xb8c8, 0x2098, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0002,
-	0x20a0, 0x4003, 0x20a9, 0x0008, 0x9080, 0x0006, 0x20a0, 0xb8c4,
-	0x20e0, 0xb8c8, 0x9080, 0x0006, 0x2098, 0x080c, 0x0f7c, 0x0070,
-	0x20a9, 0x0004, 0xa85c, 0x9080, 0x000a, 0x20a0, 0xb8c4, 0x20e0,
-	0xb8c8, 0x9080, 0x000a, 0x2098, 0x080c, 0x0f7c, 0x8906, 0x8006,
-	0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x0002, 0x2009,
-	0x002b, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x0804, 0x4b6b, 0x81ff,
-	0x1904, 0x35b5, 0x080c, 0x4b36, 0x0904, 0x35b8, 0x080c, 0x680b,
-	0x0904, 0x35b5, 0x0058, 0xa878, 0x9005, 0x0120, 0x2009, 0x0004,
-	0x0804, 0x35b5, 0xa974, 0xaa94, 0x0804, 0x3583, 0x080c, 0x5765,
-	0x0904, 0x3583, 0x701f, 0x457b, 0x7007, 0x0003, 0x0005, 0x81ff,
-	0x1904, 0x35b5, 0x7888, 0x908a, 0x1000, 0x1a04, 0x35b8, 0x080c,
-	0x4b52, 0x0904, 0x35b8, 0x080c, 0x6a0c, 0x0120, 0x080c, 0x6a14,
-	0x1904, 0x35b8, 0x080c, 0x6890, 0x0904, 0x35b5, 0x2019, 0x0004,
-	0x900e, 0x080c, 0x681d, 0x0904, 0x35b5, 0x7984, 0x7a88, 0x04c9,
-	0x08a8, 0xa89c, 0x908a, 0x1000, 0x12f8, 0x080c, 0x4b50, 0x01e0,
-	0x080c, 0x6a0c, 0x0118, 0x080c, 0x6a14, 0x11b0, 0x080c, 0x6890,
-	0x2009, 0x0002, 0x0168, 0x2009, 0x0002, 0x2019, 0x0004, 0x080c,
-	0x681d, 0x2009, 0x0003, 0x0120, 0xa998, 0xaa9c, 0x00d1, 0x0060,
-	0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e, 0x9085,
-	0x0001, 0x2001, 0x0030, 0x0005, 0xa897, 0x4000, 0x080c, 0x5765,
-	0x0110, 0x9006, 0x0018, 0x900e, 0x9085, 0x0001, 0x2001, 0x0000,
-	0x0005, 0x9186, 0x00ff, 0x0110, 0x0071, 0x0060, 0x2029, 0x007e,
-	0x2061, 0x1800, 0x645c, 0x2400, 0x9506, 0x0110, 0x2508, 0x0019,
-	0x8529, 0x1ec8, 0x0005, 0x080c, 0x6699, 0x1138, 0x2200, 0x8003,
-	0x800b, 0x810b, 0x9108, 0x080c, 0x85be, 0x0005, 0x81ff, 0x1904,
-	0x35b5, 0x798c, 0x2001, 0x197f, 0x918c, 0x8000, 0x2102, 0x080c,
-	0x4b36, 0x0904, 0x35b8, 0x080c, 0x6a0c, 0x0120, 0x080c, 0x6a14,
-	0x1904, 0x35b8, 0x080c, 0x6760, 0x0904, 0x35b5, 0x080c, 0x6814,
-	0x0904, 0x35b5, 0x2001, 0x197f, 0x2004, 0xd0fc, 0x1904, 0x3583,
-	0x0804, 0x4586, 0xa9a0, 0x2001, 0x197f, 0x918c, 0x8000, 0xc18d,
-	0x2102, 0x080c, 0x4b43, 0x01a0, 0x080c, 0x6a0c, 0x0118, 0x080c,
-	0x6a14, 0x1170, 0x080c, 0x6760, 0x2009, 0x0002, 0x0128, 0x080c,
-	0x6814, 0x1170, 0x2009, 0x0003, 0xa897, 0x4005, 0xa99a, 0x0010,
+	0x0003, 0x0010, 0x6003, 0x0001, 0x1f04, 0x43f3, 0x00ce, 0x00c6,
+	0x2061, 0x199d, 0x6a88, 0x9284, 0xc000, 0x2010, 0x9286, 0x0000,
+	0x1158, 0x2063, 0x0000, 0x2001, 0x0001, 0x080c, 0x2bd3, 0x2001,
+	0x0001, 0x080c, 0x2bb6, 0x0088, 0x9286, 0x4000, 0x1148, 0x2063,
+	0x0001, 0x9006, 0x080c, 0x2bd3, 0x9006, 0x080c, 0x2bb6, 0x0028,
+	0x9286, 0x8000, 0x1d30, 0x2063, 0x0002, 0x00ce, 0x00e6, 0x2c70,
+	0x080c, 0x0ea3, 0x00ee, 0x6888, 0xd0ec, 0x0130, 0x2011, 0x0114,
+	0x2204, 0x9085, 0x0100, 0x2012, 0x6a80, 0x9284, 0x0030, 0x9086,
+	0x0030, 0x1128, 0x9294, 0xffcf, 0x9295, 0x0020, 0x6a82, 0x2001,
+	0x197d, 0x6a80, 0x9294, 0x0030, 0x928e, 0x0000, 0x0170, 0x928e,
+	0x0010, 0x0118, 0x928e, 0x0020, 0x0140, 0x2003, 0xaaaa, 0x080c,
+	0x29a1, 0x2001, 0x196e, 0x2102, 0x0008, 0x2102, 0x00c6, 0x2061,
+	0x0100, 0x602f, 0x0040, 0x602f, 0x0000, 0x00ce, 0x080c, 0x7563,
+	0x0128, 0x080c, 0x50c3, 0x0110, 0x080c, 0x28f2, 0x60d4, 0x9005,
+	0x01c0, 0x6003, 0x0001, 0x2009, 0x4486, 0x00e0, 0x080c, 0x7563,
+	0x1168, 0x2011, 0x73de, 0x080c, 0x8703, 0x2011, 0x73d1, 0x080c,
+	0x87dd, 0x080c, 0x784d, 0x080c, 0x748f, 0x0040, 0x080c, 0x5fe0,
+	0x0028, 0x6003, 0x0004, 0x2009, 0x449e, 0x0020, 0x080c, 0x69ee,
+	0x0804, 0x35b0, 0x2001, 0x0170, 0x2004, 0x9084, 0x00ff, 0x9086,
+	0x004c, 0x1118, 0x2091, 0x30bd, 0x0817, 0x2091, 0x303d, 0x0817,
+	0x6000, 0x9086, 0x0000, 0x0904, 0x35e2, 0x2069, 0x1847, 0x7890,
+	0x6842, 0x7894, 0x6846, 0x2d00, 0x2009, 0x0030, 0x7a8c, 0x7b88,
+	0x7c9c, 0x7d98, 0x2039, 0x0001, 0x0804, 0x4bcf, 0x9006, 0x080c,
+	0x28f2, 0x81ff, 0x1904, 0x35e2, 0x080c, 0x7563, 0x11b0, 0x080c,
+	0x7848, 0x080c, 0x6121, 0x080c, 0x33a5, 0x0118, 0x6130, 0xc18d,
+	0x6132, 0x080c, 0xd548, 0x0130, 0x080c, 0x7586, 0x1118, 0x080c,
+	0x753b, 0x0038, 0x080c, 0x748f, 0x0020, 0x080c, 0x60e6, 0x080c,
+	0x5fe0, 0x0804, 0x35b0, 0x81ff, 0x1904, 0x35e2, 0x080c, 0x7563,
+	0x1110, 0x0804, 0x35e2, 0x0126, 0x2091, 0x8000, 0x6194, 0x81ff,
+	0x0190, 0x704f, 0x0000, 0x2001, 0x1c80, 0x2009, 0x0040, 0x7a8c,
+	0x7b88, 0x7c9c, 0x7d98, 0x2039, 0x0001, 0x080c, 0x4bcf, 0x701f,
+	0x35ae, 0x012e, 0x0005, 0x704f, 0x0001, 0x00d6, 0x2069, 0x1c80,
+	0x20a9, 0x0040, 0x20e9, 0x0001, 0x20a1, 0x1c80, 0x2019, 0xffff,
+	0x4304, 0x655c, 0x9588, 0x33b1, 0x210d, 0x918c, 0x00ff, 0x216a,
+	0x900e, 0x2011, 0x0002, 0x2100, 0x9506, 0x01a8, 0x080c, 0x6717,
+	0x1190, 0xb814, 0x821c, 0x0238, 0x9398, 0x1c80, 0x9085, 0xff00,
+	0x8007, 0x201a, 0x0038, 0x9398, 0x1c80, 0x2324, 0x94a4, 0xff00,
+	0x9405, 0x201a, 0x8210, 0x8108, 0x9182, 0x0080, 0x1208, 0x0c18,
+	0x8201, 0x8007, 0x2d0c, 0x9105, 0x206a, 0x00de, 0x20a9, 0x0040,
+	0x20a1, 0x1c80, 0x2099, 0x1c80, 0x080c, 0x6071, 0x0804, 0x44fb,
+	0x080c, 0x4bb6, 0x0904, 0x35e5, 0x080c, 0x4b83, 0x1120, 0x2009,
+	0x0002, 0x0804, 0x35e2, 0x080c, 0x57cd, 0xd0b4, 0x0558, 0x7884,
+	0x908e, 0x007e, 0x0538, 0x908e, 0x007f, 0x0520, 0x908e, 0x0080,
+	0x0508, 0x080c, 0x33a0, 0x1148, 0xb800, 0xd08c, 0x11d8, 0xb804,
+	0x9084, 0x00ff, 0x9086, 0x0006, 0x11a8, 0xa867, 0x0000, 0xa868,
+	0xc0fd, 0xa86a, 0x080c, 0xd00a, 0x1120, 0x2009, 0x0003, 0x0804,
+	0x35e2, 0x7007, 0x0003, 0x701f, 0x4586, 0x0005, 0x080c, 0x4bb6,
+	0x0904, 0x35e5, 0x20a9, 0x002b, 0xb8c4, 0x20e0, 0xb8c8, 0x2098,
+	0xa860, 0x20e8, 0xa85c, 0x9080, 0x0002, 0x20a0, 0x4003, 0x20a9,
+	0x0008, 0x9080, 0x0006, 0x20a0, 0xb8c4, 0x20e0, 0xb8c8, 0x9080,
+	0x0006, 0x2098, 0x080c, 0x0f8b, 0x0070, 0x20a9, 0x0004, 0xa85c,
+	0x9080, 0x000a, 0x20a0, 0xb8c4, 0x20e0, 0xb8c8, 0x9080, 0x000a,
+	0x2098, 0x080c, 0x0f8b, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f,
+	0x9084, 0xffc0, 0x9080, 0x0002, 0x2009, 0x002b, 0x7a8c, 0x7b88,
+	0x7c9c, 0x7d98, 0x0804, 0x4bcf, 0x81ff, 0x1904, 0x35e2, 0x080c,
+	0x4b9a, 0x0904, 0x35e5, 0x080c, 0x6889, 0x0904, 0x35e2, 0x0058,
+	0xa878, 0x9005, 0x0120, 0x2009, 0x0004, 0x0804, 0x35e2, 0xa974,
+	0xaa94, 0x0804, 0x35b0, 0x080c, 0x57d5, 0x0904, 0x35b0, 0x701f,
+	0x45d0, 0x7007, 0x0003, 0x0005, 0x81ff, 0x1904, 0x35e2, 0x7888,
+	0x908a, 0x1000, 0x1a04, 0x35e5, 0x080c, 0x4bb6, 0x0904, 0x35e5,
+	0x080c, 0x6a8c, 0x0120, 0x080c, 0x6a94, 0x1904, 0x35e5, 0x080c,
+	0x690e, 0x0904, 0x35e2, 0x2019, 0x0004, 0x900e, 0x080c, 0x689b,
+	0x0904, 0x35e2, 0x7984, 0x7a88, 0x04c9, 0x08a8, 0xa89c, 0x908a,
+	0x1000, 0x12f8, 0x080c, 0x4bb4, 0x01e0, 0x080c, 0x6a8c, 0x0118,
+	0x080c, 0x6a94, 0x11b0, 0x080c, 0x690e, 0x2009, 0x0002, 0x0168,
+	0x2009, 0x0002, 0x2019, 0x0004, 0x080c, 0x689b, 0x2009, 0x0003,
+	0x0120, 0xa998, 0xaa9c, 0x00d1, 0x0060, 0xa897, 0x4005, 0xa99a,
+	0x0010, 0xa897, 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030,
+	0x0005, 0xa897, 0x4000, 0x080c, 0x57d5, 0x0110, 0x9006, 0x0018,
+	0x900e, 0x9085, 0x0001, 0x2001, 0x0000, 0x0005, 0x9186, 0x00ff,
+	0x0110, 0x0071, 0x0060, 0x2029, 0x007e, 0x2061, 0x1800, 0x645c,
+	0x2400, 0x9506, 0x0110, 0x2508, 0x0019, 0x8529, 0x1ec8, 0x0005,
+	0x080c, 0x6717, 0x1138, 0x2200, 0x8003, 0x800b, 0x810b, 0x9108,
+	0x080c, 0x8711, 0x0005, 0x81ff, 0x1904, 0x35e2, 0x798c, 0x2001,
+	0x1981, 0x918c, 0x8000, 0x2102, 0x080c, 0x4b9a, 0x0904, 0x35e5,
+	0x080c, 0x6a8c, 0x0120, 0x080c, 0x6a94, 0x1904, 0x35e5, 0x080c,
+	0x67de, 0x0904, 0x35e2, 0x080c, 0x6892, 0x0904, 0x35e2, 0x2001,
+	0x1981, 0x2004, 0xd0fc, 0x1904, 0x35b0, 0x0804, 0x45db, 0xa9a0,
+	0x2001, 0x1981, 0x918c, 0x8000, 0xc18d, 0x2102, 0x080c, 0x4ba7,
+	0x01a0, 0x080c, 0x6a8c, 0x0118, 0x080c, 0x6a94, 0x1170, 0x080c,
+	0x67de, 0x2009, 0x0002, 0x0128, 0x080c, 0x6892, 0x1170, 0x2009,
+	0x0003, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e,
+	0x9085, 0x0001, 0x2001, 0x0030, 0x0005, 0xa897, 0x4000, 0x2001,
+	0x1981, 0x2004, 0xd0fc, 0x1128, 0x080c, 0x57d5, 0x0110, 0x9006,
+	0x0018, 0x900e, 0x9085, 0x0001, 0x2001, 0x0000, 0x0005, 0x81ff,
+	0x1904, 0x35e2, 0x798c, 0x2001, 0x1980, 0x918c, 0x8000, 0x2102,
+	0x080c, 0x4b9a, 0x0904, 0x35e5, 0x080c, 0x6a8c, 0x0120, 0x080c,
+	0x6a94, 0x1904, 0x35e5, 0x080c, 0x67de, 0x0904, 0x35e2, 0x080c,
+	0x6880, 0x0904, 0x35e2, 0x2001, 0x1980, 0x2004, 0xd0fc, 0x1904,
+	0x35b0, 0x0804, 0x45db, 0xa9a0, 0x2001, 0x1980, 0x918c, 0x8000,
+	0xc18d, 0x2102, 0x080c, 0x4ba7, 0x01a0, 0x080c, 0x6a8c, 0x0118,
+	0x080c, 0x6a94, 0x1170, 0x080c, 0x67de, 0x2009, 0x0002, 0x0128,
+	0x080c, 0x6880, 0x1170, 0x2009, 0x0003, 0xa897, 0x4005, 0xa99a,
+	0x0010, 0xa897, 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030,
+	0x0005, 0xa897, 0x4000, 0x2001, 0x1980, 0x2004, 0xd0fc, 0x1128,
+	0x080c, 0x57d5, 0x0110, 0x9006, 0x0018, 0x900e, 0x9085, 0x0001,
+	0x2001, 0x0000, 0x0005, 0x6100, 0x0804, 0x35b0, 0x080c, 0x4bb6,
+	0x0904, 0x35e5, 0x080c, 0x57e1, 0x1904, 0x35e2, 0x79a8, 0xd184,
+	0x1158, 0xb834, 0x8007, 0x789e, 0xb830, 0x8007, 0x789a, 0xbb2c,
+	0x831f, 0xba28, 0x8217, 0x0050, 0xb824, 0x8007, 0x789e, 0xb820,
+	0x8007, 0x789a, 0xbb1c, 0x831f, 0xba18, 0x8217, 0xb900, 0x918c,
+	0x0202, 0x0804, 0x35b0, 0x78a8, 0x909c, 0x0003, 0xd0ac, 0x1158,
+	0xd0b4, 0x1148, 0x939a, 0x0003, 0x1a04, 0x35e2, 0x625c, 0x7884,
+	0x9206, 0x1904, 0x4796, 0x080c, 0x8812, 0x2001, 0xffec, 0x2009,
+	0x000c, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x2039, 0x0000, 0x0006,
+	0x78a8, 0x9084, 0x0080, 0x1528, 0x0006, 0x0036, 0x2001, 0x1a84,
+	0x201c, 0x7b9a, 0x2003, 0x0000, 0x2001, 0x1a85, 0x201c, 0x7b9e,
+	0x2003, 0x0000, 0x2001, 0x1a86, 0x201c, 0x7bae, 0x2003, 0x0000,
+	0x2001, 0x1a80, 0x201c, 0x7baa, 0x2003, 0x0000, 0x2001, 0x1a87,
+	0x201c, 0x7bb2, 0x2003, 0x0000, 0x003e, 0x000e, 0x000e, 0x0804,
+	0x4bcf, 0x000e, 0x2031, 0x0000, 0x2061, 0x18b8, 0x2c44, 0xa66a,
+	0xa17a, 0xa772, 0xa076, 0xa28e, 0xa392, 0xa496, 0xa59a, 0x080c,
+	0x10f8, 0x7007, 0x0002, 0x701f, 0x47b6, 0x0005, 0x81ff, 0x1904,
+	0x35e2, 0x080c, 0x4bb6, 0x0904, 0x35e5, 0x080c, 0x6a8c, 0x1904,
+	0x35e2, 0x00c6, 0x080c, 0x4b83, 0x00ce, 0x0904, 0x35e2, 0xa867,
+	0x0000, 0xa868, 0xc0fd, 0xa86a, 0x7ea8, 0x080c, 0xcfb0, 0x0904,
+	0x35e2, 0x7007, 0x0003, 0x701f, 0x47dc, 0x0005, 0x080c, 0x42c8,
+	0x0006, 0x0036, 0x2001, 0x1a84, 0x201c, 0x7b9a, 0x2003, 0x0000,
+	0x2001, 0x1a85, 0x201c, 0x7b9e, 0x2003, 0x0000, 0x2001, 0x1a86,
+	0x201c, 0x7bae, 0x2003, 0x0000, 0x2001, 0x1a80, 0x201c, 0x7baa,
+	0x2003, 0x0000, 0x2001, 0x1a87, 0x201c, 0x7bb2, 0x2003, 0x0000,
+	0x003e, 0x000e, 0x0804, 0x35b0, 0xa830, 0x9086, 0x0100, 0x0904,
+	0x35e2, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0,
+	0x9080, 0x001b, 0x2009, 0x000c, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98,
+	0x0804, 0x4bcf, 0x9006, 0x080c, 0x28f2, 0x78a8, 0x9084, 0x00ff,
+	0x9086, 0x00ff, 0x0118, 0x81ff, 0x1904, 0x35e2, 0x080c, 0x7563,
+	0x0110, 0x080c, 0x60e6, 0x7888, 0x908a, 0x1000, 0x1a04, 0x35e5,
+	0x7984, 0x9186, 0x00ff, 0x0138, 0x9182, 0x007f, 0x1a04, 0x35e5,
+	0x2100, 0x080c, 0x28bc, 0x0026, 0x00c6, 0x0126, 0x2091, 0x8000,
+	0x2061, 0x19fc, 0x601b, 0x0000, 0x601f, 0x0000, 0x607b, 0x0000,
+	0x607f, 0x0000, 0x080c, 0x7563, 0x1158, 0x080c, 0x7848, 0x080c,
+	0x6121, 0x9085, 0x0001, 0x080c, 0x75a7, 0x080c, 0x748f, 0x00d0,
+	0x080c, 0xb058, 0x2061, 0x0100, 0x2001, 0x1818, 0x2004, 0x9084,
+	0x00ff, 0x810f, 0x9105, 0x604a, 0x6043, 0x0090, 0x6043, 0x0010,
+	0x2009, 0x199a, 0x200b, 0x0000, 0x2009, 0x002d, 0x2011, 0x600c,
+	0x080c, 0x879b, 0x7984, 0x080c, 0x7563, 0x1110, 0x2009, 0x00ff,
+	0x7a88, 0x080c, 0x463e, 0x012e, 0x00ce, 0x002e, 0x0804, 0x35b0,
+	0x7984, 0x080c, 0x66ac, 0x2b08, 0x1904, 0x35e5, 0x0804, 0x35b0,
+	0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x35e2, 0x60dc, 0xd0ac,
+	0x1130, 0xd09c, 0x1120, 0x2009, 0x0005, 0x0804, 0x35e2, 0x080c,
+	0x4b83, 0x1120, 0x2009, 0x0002, 0x0804, 0x35e2, 0x7984, 0x81ff,
+	0x0904, 0x35e5, 0x9192, 0x0021, 0x1a04, 0x35e5, 0x7a8c, 0x7b88,
+	0x7c9c, 0x7d98, 0xa85c, 0x9080, 0x0019, 0x702a, 0xaf60, 0x7736,
+	0x080c, 0x4bcc, 0x701f, 0x4893, 0x7880, 0x9086, 0x006e, 0x0110,
+	0x701f, 0x5275, 0x0005, 0x2009, 0x0080, 0x080c, 0x6717, 0x1118,
+	0x080c, 0x6a8c, 0x0120, 0x2021, 0x400a, 0x0804, 0x35b2, 0x00d6,
+	0x0096, 0xa964, 0xaa6c, 0xab70, 0xac74, 0xad78, 0xae7c, 0xa884,
+	0x90be, 0x0100, 0x0904, 0x492c, 0x90be, 0x0112, 0x0904, 0x492c,
+	0x90be, 0x0113, 0x0904, 0x492c, 0x90be, 0x0114, 0x0904, 0x492c,
+	0x90be, 0x0117, 0x0904, 0x492c, 0x90be, 0x011a, 0x0904, 0x492c,
+	0x90be, 0x011c, 0x0904, 0x492c, 0x90be, 0x0121, 0x0904, 0x4913,
+	0x90be, 0x0131, 0x0904, 0x4913, 0x90be, 0x0171, 0x0904, 0x492c,
+	0x90be, 0x0173, 0x0904, 0x492c, 0x90be, 0x01a1, 0x1128, 0xa894,
+	0x8007, 0xa896, 0x0804, 0x4937, 0x90be, 0x0212, 0x0904, 0x4920,
+	0x90be, 0x0213, 0x05e8, 0x90be, 0x0214, 0x0500, 0x90be, 0x0217,
+	0x0188, 0x90be, 0x021a, 0x1120, 0xa89c, 0x8007, 0xa89e, 0x04e0,
+	0x90be, 0x021f, 0x05c8, 0x90be, 0x0300, 0x05b0, 0x009e, 0x00de,
+	0x0804, 0x35e5, 0x7028, 0x9080, 0x0010, 0x2098, 0x20a0, 0x7034,
+	0x20e0, 0x20e8, 0x20a9, 0x0007, 0x080c, 0x4975, 0x7028, 0x9080,
+	0x000e, 0x2098, 0x20a0, 0x7034, 0x20e0, 0x20e8, 0x20a9, 0x0001,
+	0x080c, 0x4975, 0x00c8, 0x7028, 0x9080, 0x000c, 0x2098, 0x20a0,
+	0x7034, 0x20e0, 0x20e8, 0x20a9, 0x0001, 0x080c, 0x4982, 0x00b8,
+	0x7028, 0x9080, 0x000e, 0x2098, 0x20a0, 0x7034, 0x20e0, 0x20e8,
+	0x20a9, 0x0001, 0x080c, 0x4982, 0x7028, 0x9080, 0x000c, 0x2098,
+	0x20a0, 0x7034, 0x20e0, 0x20e8, 0x20a9, 0x0001, 0x04f1, 0x00c6,
+	0x080c, 0x4b83, 0x0550, 0xa868, 0xc0fd, 0xa86a, 0xa867, 0x0119,
+	0x9006, 0xa882, 0xa87f, 0x0020, 0xa88b, 0x0001, 0x810b, 0xa9ae,
+	0xa8b2, 0xaab6, 0xabba, 0xacbe, 0xadc2, 0xa9c6, 0xa8ca, 0x00ce,
+	0x009e, 0x00de, 0xa866, 0xa822, 0xa868, 0xc0fd, 0xa86a, 0xa804,
+	0x2048, 0x080c, 0xcfcb, 0x1120, 0x2009, 0x0003, 0x0804, 0x35e2,
+	0x7007, 0x0003, 0x701f, 0x496c, 0x0005, 0x00ce, 0x009e, 0x00de,
+	0x2009, 0x0002, 0x0804, 0x35e2, 0xa820, 0x9086, 0x8001, 0x1904,
+	0x35b0, 0x2009, 0x0004, 0x0804, 0x35e2, 0x0016, 0x0026, 0x3510,
+	0x20a9, 0x0002, 0x4002, 0x4104, 0x4004, 0x8211, 0x1dc8, 0x002e,
+	0x001e, 0x0005, 0x0016, 0x0026, 0x0036, 0x0046, 0x3520, 0x20a9,
+	0x0004, 0x4002, 0x4304, 0x4204, 0x4104, 0x4004, 0x8421, 0x1db8,
+	0x004e, 0x003e, 0x002e, 0x001e, 0x0005, 0x81ff, 0x0120, 0x2009,
+	0x0001, 0x0804, 0x35e2, 0x60dc, 0xd0ac, 0x1130, 0xd09c, 0x1120,
+	0x2009, 0x0005, 0x0804, 0x35e2, 0x7984, 0x78a8, 0x2040, 0x080c,
+	0xb051, 0x1120, 0x9182, 0x007f, 0x0a04, 0x35e5, 0x9186, 0x00ff,
+	0x0904, 0x35e5, 0x9182, 0x0800, 0x1a04, 0x35e5, 0x7a8c, 0x7b88,
+	0x607c, 0x9306, 0x1158, 0x6080, 0x924e, 0x0904, 0x35e5, 0x080c,
+	0xb051, 0x1120, 0x99cc, 0xff00, 0x0904, 0x35e5, 0x0126, 0x2091,
+	0x8000, 0x080c, 0x4a96, 0x0904, 0x4a16, 0x0086, 0x90c6, 0x4000,
+	0x008e, 0x1538, 0x00c6, 0x0006, 0x0036, 0xb818, 0xbb1c, 0x9305,
+	0xbb20, 0x9305, 0xbb24, 0x9305, 0xbb28, 0x9305, 0xbb2c, 0x9305,
+	0xbb30, 0x9305, 0xbb34, 0x9305, 0x003e, 0x0570, 0xd88c, 0x1128,
+	0x080c, 0x6a8c, 0x0110, 0xc89d, 0x0438, 0x900e, 0x080c, 0x6937,
+	0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x000e, 0x00ce,
+	0x00b8, 0x90c6, 0x4007, 0x1110, 0x2408, 0x0090, 0x90c6, 0x4008,
+	0x1118, 0x2708, 0x2610, 0x0060, 0x90c6, 0x4009, 0x1108, 0x0040,
+	0x90c6, 0x4006, 0x1108, 0x0020, 0x2001, 0x4005, 0x2009, 0x000a,
+	0x2020, 0x012e, 0x0804, 0x35b2, 0x000e, 0x00ce, 0x2b00, 0x7026,
+	0x0016, 0x00b6, 0x00c6, 0x00e6, 0x2c70, 0x080c, 0xb139, 0x0904,
+	0x4a6b, 0x2b00, 0x6012, 0x080c, 0xd2bb, 0x2e58, 0x00ee, 0x00e6,
+	0x00c6, 0x080c, 0x4b83, 0x00ce, 0x2b70, 0x1158, 0x080c, 0xb0e7,
+	0x00ee, 0x00ce, 0x00be, 0x001e, 0x012e, 0x2009, 0x0002, 0x0804,
+	0x35e2, 0x900e, 0xa966, 0xa96a, 0x2900, 0x6016, 0xa932, 0xa868,
+	0xc0fd, 0xd88c, 0x0108, 0xc0f5, 0xa86a, 0xd89c, 0x1110, 0x080c,
+	0x324b, 0x6023, 0x0001, 0x9006, 0x080c, 0x6649, 0xd89c, 0x0138,
+	0x2001, 0x0004, 0x080c, 0x665d, 0x2009, 0x0003, 0x0030, 0x2001,
+	0x0002, 0x080c, 0x665d, 0x2009, 0x0002, 0x080c, 0xb166, 0x78a8,
+	0xd094, 0x0138, 0x00ee, 0x7024, 0x00e6, 0x2058, 0xb8cc, 0xc08d,
+	0xb8ce, 0x9085, 0x0001, 0x00ee, 0x00ce, 0x00be, 0x001e, 0x012e,
+	0x1120, 0x2009, 0x0003, 0x0804, 0x35e2, 0x7007, 0x0003, 0x701f,
+	0x4a7a, 0x0005, 0xa830, 0x9086, 0x0100, 0x7024, 0x2058, 0x1138,
+	0x2009, 0x0004, 0xba04, 0x9294, 0x00ff, 0x0804, 0x5721, 0x900e,
+	0xa868, 0xd0f4, 0x1904, 0x35b0, 0x080c, 0x6937, 0x1108, 0xc185,
+	0xb800, 0xd0bc, 0x0108, 0xc18d, 0x0804, 0x35b0, 0x00e6, 0x00d6,
+	0x0096, 0x83ff, 0x0904, 0x4ae5, 0x902e, 0x080c, 0xb051, 0x0130,
+	0x9026, 0x20a9, 0x0800, 0x2071, 0x1000, 0x0030, 0x2021, 0x007f,
+	0x20a9, 0x0781, 0x2071, 0x107f, 0x2e04, 0x9005, 0x11b8, 0x2100,
+	0x9406, 0x1904, 0x4af6, 0x2428, 0x94ce, 0x007f, 0x1120, 0x92ce,
+	0xfffd, 0x1558, 0x0030, 0x94ce, 0x0080, 0x1130, 0x92ce, 0xfffc,
+	0x1520, 0x93ce, 0x00ff, 0x1508, 0xc5fd, 0x0480, 0x2058, 0xbf10,
+	0x2700, 0x9306, 0x11e8, 0xbe14, 0x2600, 0x9206, 0x11c8, 0x2400,
+	0x9106, 0x1180, 0xd884, 0x0598, 0xd894, 0x1588, 0x080c, 0x6a2c,
+	0x1570, 0x2001, 0x4000, 0x0460, 0x080c, 0x6a8c, 0x1540, 0x2001,
+	0x4000, 0x0430, 0x2001, 0x4007, 0x0418, 0x2001, 0x4006, 0x0400,
+	0x2400, 0x9106, 0x1158, 0xbe14, 0x87ff, 0x1128, 0x86ff, 0x0918,
+	0x080c, 0xb051, 0x1900, 0x2001, 0x4008, 0x0090, 0x8420, 0x8e70,
+	0x1f04, 0x4aac, 0x85ff, 0x1130, 0x2001, 0x4009, 0x0048, 0x2001,
+	0x0001, 0x0030, 0x080c, 0x66ac, 0x1dd0, 0xbb12, 0xba16, 0x9006,
+	0x9005, 0x009e, 0x00de, 0x00ee, 0x0005, 0x81ff, 0x0120, 0x2009,
+	0x0001, 0x0804, 0x35e2, 0x080c, 0x4b83, 0x1120, 0x2009, 0x0002,
+	0x0804, 0x35e2, 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x7884,
+	0x9005, 0x0904, 0x35e5, 0x9096, 0x00ff, 0x0120, 0x9092, 0x0004,
+	0x1a04, 0x35e5, 0x2010, 0x2918, 0x080c, 0x31f1, 0x1120, 0x2009,
+	0x0003, 0x0804, 0x35e2, 0x7007, 0x0003, 0x701f, 0x4b38, 0x0005,
+	0xa830, 0x9086, 0x0100, 0x1904, 0x35b0, 0x2009, 0x0004, 0x0804,
+	0x35e2, 0x7984, 0x080c, 0xb051, 0x1120, 0x9182, 0x007f, 0x0a04,
+	0x35e5, 0x9186, 0x00ff, 0x0904, 0x35e5, 0x9182, 0x0800, 0x1a04,
+	0x35e5, 0x2001, 0x9400, 0x080c, 0x577c, 0x1904, 0x35e2, 0x0804,
+	0x35b0, 0xa998, 0x080c, 0xb051, 0x1118, 0x9182, 0x007f, 0x0280,
+	0x9186, 0x00ff, 0x0168, 0x9182, 0x0800, 0x1250, 0x2001, 0x9400,
+	0x080c, 0x577c, 0x11a8, 0x0060, 0xa897, 0x4005, 0xa99a, 0x0010,
 	0xa897, 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x0005,
-	0xa897, 0x4000, 0x2001, 0x197f, 0x2004, 0xd0fc, 0x1128, 0x080c,
-	0x5765, 0x0110, 0x9006, 0x0018, 0x900e, 0x9085, 0x0001, 0x2001,
-	0x0000, 0x0005, 0x81ff, 0x1904, 0x35b5, 0x798c, 0x2001, 0x197e,
-	0x918c, 0x8000, 0x2102, 0x080c, 0x4b36, 0x0904, 0x35b8, 0x080c,
-	0x6a0c, 0x0120, 0x080c, 0x6a14, 0x1904, 0x35b8, 0x080c, 0x6760,
-	0x0904, 0x35b5, 0x080c, 0x6802, 0x0904, 0x35b5, 0x2001, 0x197e,
-	0x2004, 0xd0fc, 0x1904, 0x3583, 0x0804, 0x4586, 0xa9a0, 0x2001,
-	0x197e, 0x918c, 0x8000, 0xc18d, 0x2102, 0x080c, 0x4b43, 0x01a0,
-	0x080c, 0x6a0c, 0x0118, 0x080c, 0x6a14, 0x1170, 0x080c, 0x6760,
-	0x2009, 0x0002, 0x0128, 0x080c, 0x6802, 0x1170, 0x2009, 0x0003,
-	0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e, 0x9085,
-	0x0001, 0x2001, 0x0030, 0x0005, 0xa897, 0x4000, 0x2001, 0x197e,
-	0x2004, 0xd0fc, 0x1128, 0x080c, 0x5765, 0x0110, 0x9006, 0x0018,
-	0x900e, 0x9085, 0x0001, 0x2001, 0x0000, 0x0005, 0x6100, 0x0804,
-	0x3583, 0x080c, 0x4b52, 0x0904, 0x35b8, 0x080c, 0x5771, 0x1904,
-	0x35b5, 0x79a8, 0xd184, 0x1158, 0xb834, 0x8007, 0x789e, 0xb830,
-	0x8007, 0x789a, 0xbb2c, 0x831f, 0xba28, 0x8217, 0x0050, 0xb824,
-	0x8007, 0x789e, 0xb820, 0x8007, 0x789a, 0xbb1c, 0x831f, 0xba18,
-	0x8217, 0xb900, 0x918c, 0x0202, 0x0804, 0x3583, 0x78a8, 0x909c,
-	0x0003, 0xd0ac, 0x1158, 0xd0b4, 0x1148, 0x939a, 0x0003, 0x1a04,
-	0x35b5, 0x625c, 0x7884, 0x9206, 0x1904, 0x473b, 0x080c, 0x8696,
-	0x2001, 0xffec, 0x2009, 0x000c, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98,
-	0x2039, 0x0000, 0x0006, 0x78a8, 0x9084, 0x0080, 0x11f8, 0x0006,
-	0x0036, 0x2001, 0x1a7f, 0x201c, 0x7b9a, 0x2003, 0x0000, 0x2001,
-	0x1a80, 0x201c, 0x7b9e, 0x2003, 0x0000, 0x2001, 0x1a81, 0x201c,
-	0x7ba2, 0x2003, 0x0000, 0x2001, 0x1a7b, 0x201c, 0x7baa, 0x2003,
-	0x0000, 0x003e, 0x000e, 0x000e, 0x0804, 0x4b6b, 0x000e, 0x2031,
+	0xa897, 0x4000, 0x900e, 0x9085, 0x0001, 0x2001, 0x0000, 0x0005,
+	0x2009, 0x000a, 0x0c48, 0x080c, 0x100e, 0x0198, 0x9006, 0xa802,
+	0x7014, 0x9005, 0x1120, 0x2900, 0x7016, 0x701a, 0x0040, 0x7018,
+	0xa802, 0x0086, 0x2040, 0x2900, 0xa006, 0x701a, 0x008e, 0x9085,
+	0x0001, 0x0005, 0x7984, 0x080c, 0x6717, 0x1130, 0x7e88, 0x9684,
+	0x3fff, 0x9082, 0x4000, 0x0208, 0x905e, 0x8bff, 0x0005, 0xa998,
+	0x080c, 0x6717, 0x1130, 0xae9c, 0x9684, 0x3fff, 0x9082, 0x4000,
+	0x0208, 0x905e, 0x8bff, 0x0005, 0xae98, 0x0008, 0x7e84, 0x2608,
+	0x080c, 0x6717, 0x1108, 0x0008, 0x905e, 0x8bff, 0x0005, 0x0016,
+	0x7114, 0x81ff, 0x0128, 0x2148, 0xa904, 0x080c, 0x1040, 0x0cc8,
+	0x7116, 0x711a, 0x001e, 0x0005, 0x2031, 0x0001, 0x0010, 0x2031,
 	0x0000, 0x2061, 0x18b8, 0x2c44, 0xa66a, 0xa17a, 0xa772, 0xa076,
-	0xa28e, 0xa392, 0xa496, 0xa59a, 0x080c, 0x10e9, 0x7007, 0x0002,
-	0x701f, 0x475b, 0x0005, 0x81ff, 0x1904, 0x35b5, 0x080c, 0x4b52,
-	0x0904, 0x35b8, 0x080c, 0x6a0c, 0x1904, 0x35b5, 0x00c6, 0x080c,
-	0x4b1f, 0x00ce, 0x0904, 0x35b5, 0xa867, 0x0000, 0xa868, 0xc0fd,
-	0xa86a, 0x7ea8, 0x080c, 0xcdf7, 0x0904, 0x35b5, 0x7007, 0x0003,
-	0x701f, 0x477b, 0x0005, 0x080c, 0x4278, 0x0006, 0x0036, 0x2001,
-	0x1a7f, 0x201c, 0x7b9a, 0x2003, 0x0000, 0x2001, 0x1a80, 0x201c,
-	0x7b9e, 0x2003, 0x0000, 0x2001, 0x1a81, 0x201c, 0x7ba2, 0x2003,
-	0x0000, 0x2001, 0x1a7b, 0x201c, 0x7baa, 0x2003, 0x0000, 0x003e,
-	0x000e, 0x0804, 0x3583, 0xa830, 0x9086, 0x0100, 0x0904, 0x35b5,
-	0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080,
-	0x001b, 0x2009, 0x000c, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x0804,
-	0x4b6b, 0x9006, 0x080c, 0x28e5, 0x78a8, 0x9084, 0x00ff, 0x9086,
-	0x00ff, 0x0118, 0x81ff, 0x1904, 0x35b5, 0x080c, 0x743e, 0x0110,
-	0x080c, 0x6072, 0x7888, 0x908a, 0x1000, 0x1a04, 0x35b8, 0x7984,
-	0x9186, 0x00ff, 0x0138, 0x9182, 0x007f, 0x1a04, 0x35b8, 0x2100,
-	0x080c, 0x28af, 0x0026, 0x00c6, 0x0126, 0x2091, 0x8000, 0x2061,
-	0x19f9, 0x601b, 0x0000, 0x601f, 0x0000, 0x6073, 0x0000, 0x6077,
-	0x0000, 0x080c, 0x743e, 0x1158, 0x080c, 0x7724, 0x080c, 0x60ad,
-	0x9085, 0x0001, 0x080c, 0x7485, 0x080c, 0x736a, 0x00d0, 0x080c,
-	0xaeb4, 0x2061, 0x0100, 0x2001, 0x1818, 0x2004, 0x9084, 0x00ff,
-	0x810f, 0x9105, 0x604a, 0x6043, 0x0090, 0x6043, 0x0010, 0x2009,
-	0x1998, 0x200b, 0x0000, 0x2009, 0x002d, 0x2011, 0x5f98, 0x080c,
-	0x8648, 0x7984, 0x080c, 0x743e, 0x1110, 0x2009, 0x00ff, 0x7a88,
-	0x080c, 0x45e9, 0x012e, 0x00ce, 0x002e, 0x0804, 0x3583, 0x7984,
-	0x080c, 0x6638, 0x2b08, 0x1904, 0x35b8, 0x0804, 0x3583, 0x81ff,
-	0x0120, 0x2009, 0x0001, 0x0804, 0x35b5, 0x60dc, 0xd0ac, 0x1130,
-	0xd09c, 0x1120, 0x2009, 0x0005, 0x0804, 0x35b5, 0x080c, 0x4b1f,
-	0x1120, 0x2009, 0x0002, 0x0804, 0x35b5, 0x7984, 0x9192, 0x0021,
-	0x1a04, 0x35b8, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0xa85c, 0x9080,
-	0x0019, 0x702a, 0xaf60, 0x7736, 0x080c, 0x4b68, 0x701f, 0x482f,
-	0x7880, 0x9086, 0x006e, 0x0110, 0x701f, 0x5206, 0x0005, 0x2009,
-	0x0080, 0x080c, 0x6699, 0x1118, 0x080c, 0x6a0c, 0x0120, 0x2021,
-	0x400a, 0x0804, 0x3585, 0x00d6, 0x0096, 0xa964, 0xaa6c, 0xab70,
-	0xac74, 0xad78, 0xae7c, 0xa884, 0x90be, 0x0100, 0x0904, 0x48c8,
-	0x90be, 0x0112, 0x0904, 0x48c8, 0x90be, 0x0113, 0x0904, 0x48c8,
-	0x90be, 0x0114, 0x0904, 0x48c8, 0x90be, 0x0117, 0x0904, 0x48c8,
-	0x90be, 0x011a, 0x0904, 0x48c8, 0x90be, 0x011c, 0x0904, 0x48c8,
-	0x90be, 0x0121, 0x0904, 0x48af, 0x90be, 0x0131, 0x0904, 0x48af,
-	0x90be, 0x0171, 0x0904, 0x48c8, 0x90be, 0x0173, 0x0904, 0x48c8,
-	0x90be, 0x01a1, 0x1128, 0xa894, 0x8007, 0xa896, 0x0804, 0x48d3,
-	0x90be, 0x0212, 0x0904, 0x48bc, 0x90be, 0x0213, 0x05e8, 0x90be,
-	0x0214, 0x0500, 0x90be, 0x0217, 0x0188, 0x90be, 0x021a, 0x1120,
-	0xa89c, 0x8007, 0xa89e, 0x04e0, 0x90be, 0x021f, 0x05c8, 0x90be,
-	0x0300, 0x05b0, 0x009e, 0x00de, 0x0804, 0x35b8, 0x7028, 0x9080,
-	0x0010, 0x2098, 0x20a0, 0x7034, 0x20e0, 0x20e8, 0x20a9, 0x0007,
-	0x080c, 0x4911, 0x7028, 0x9080, 0x000e, 0x2098, 0x20a0, 0x7034,
-	0x20e0, 0x20e8, 0x20a9, 0x0001, 0x080c, 0x4911, 0x00c8, 0x7028,
-	0x9080, 0x000c, 0x2098, 0x20a0, 0x7034, 0x20e0, 0x20e8, 0x20a9,
-	0x0001, 0x080c, 0x491e, 0x00b8, 0x7028, 0x9080, 0x000e, 0x2098,
-	0x20a0, 0x7034, 0x20e0, 0x20e8, 0x20a9, 0x0001, 0x080c, 0x491e,
-	0x7028, 0x9080, 0x000c, 0x2098, 0x20a0, 0x7034, 0x20e0, 0x20e8,
-	0x20a9, 0x0001, 0x04f1, 0x00c6, 0x080c, 0x4b1f, 0x0550, 0xa868,
-	0xc0fd, 0xa86a, 0xa867, 0x0119, 0x9006, 0xa882, 0xa87f, 0x0020,
-	0xa88b, 0x0001, 0x810b, 0xa9ae, 0xa8b2, 0xaab6, 0xabba, 0xacbe,
-	0xadc2, 0xa9c6, 0xa8ca, 0x00ce, 0x009e, 0x00de, 0xa866, 0xa822,
-	0xa868, 0xc0fd, 0xa86a, 0xa804, 0x2048, 0x080c, 0xce12, 0x1120,
-	0x2009, 0x0003, 0x0804, 0x35b5, 0x7007, 0x0003, 0x701f, 0x4908,
-	0x0005, 0x00ce, 0x009e, 0x00de, 0x2009, 0x0002, 0x0804, 0x35b5,
-	0xa820, 0x9086, 0x8001, 0x1904, 0x3583, 0x2009, 0x0004, 0x0804,
-	0x35b5, 0x0016, 0x0026, 0x3510, 0x20a9, 0x0002, 0x4002, 0x4104,
-	0x4004, 0x8211, 0x1dc8, 0x002e, 0x001e, 0x0005, 0x0016, 0x0026,
-	0x0036, 0x0046, 0x3520, 0x20a9, 0x0004, 0x4002, 0x4304, 0x4204,
-	0x4104, 0x4004, 0x8421, 0x1db8, 0x004e, 0x003e, 0x002e, 0x001e,
-	0x0005, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x35b5, 0x60dc,
-	0xd0ac, 0x1130, 0xd09c, 0x1120, 0x2009, 0x0005, 0x0804, 0x35b5,
-	0x7984, 0x78a8, 0x2040, 0x080c, 0xaead, 0x1120, 0x9182, 0x007f,
-	0x0a04, 0x35b8, 0x9186, 0x00ff, 0x0904, 0x35b8, 0x9182, 0x0800,
-	0x1a04, 0x35b8, 0x7a8c, 0x7b88, 0x607c, 0x9306, 0x1158, 0x6080,
-	0x924e, 0x0904, 0x35b8, 0x080c, 0xaead, 0x1120, 0x99cc, 0xff00,
-	0x0904, 0x35b8, 0x0126, 0x2091, 0x8000, 0x080c, 0x4a32, 0x0904,
-	0x49b2, 0x0086, 0x90c6, 0x4000, 0x008e, 0x1538, 0x00c6, 0x0006,
-	0x0036, 0xb818, 0xbb1c, 0x9305, 0xbb20, 0x9305, 0xbb24, 0x9305,
-	0xbb28, 0x9305, 0xbb2c, 0x9305, 0xbb30, 0x9305, 0xbb34, 0x9305,
-	0x003e, 0x0570, 0xd88c, 0x1128, 0x080c, 0x6a0c, 0x0110, 0xc89d,
-	0x0438, 0x900e, 0x080c, 0x68b9, 0x1108, 0xc185, 0xb800, 0xd0bc,
-	0x0108, 0xc18d, 0x000e, 0x00ce, 0x00b8, 0x90c6, 0x4007, 0x1110,
-	0x2408, 0x0090, 0x90c6, 0x4008, 0x1118, 0x2708, 0x2610, 0x0060,
-	0x90c6, 0x4009, 0x1108, 0x0040, 0x90c6, 0x4006, 0x1108, 0x0020,
-	0x2001, 0x4005, 0x2009, 0x000a, 0x2020, 0x012e, 0x0804, 0x3585,
-	0x000e, 0x00ce, 0x2b00, 0x7026, 0x0016, 0x00b6, 0x00c6, 0x00e6,
-	0x2c70, 0x080c, 0xaf91, 0x0904, 0x4a07, 0x2b00, 0x6012, 0x080c,
-	0xd102, 0x2e58, 0x00ee, 0x00e6, 0x00c6, 0x080c, 0x4b1f, 0x00ce,
-	0x2b70, 0x1158, 0x080c, 0xaf43, 0x00ee, 0x00ce, 0x00be, 0x001e,
-	0x012e, 0x2009, 0x0002, 0x0804, 0x35b5, 0x900e, 0xa966, 0xa96a,
-	0x2900, 0x6016, 0xa932, 0xa868, 0xc0fd, 0xd88c, 0x0108, 0xc0f5,
-	0xa86a, 0xd89c, 0x1110, 0x080c, 0x321e, 0x6023, 0x0001, 0x9006,
-	0x080c, 0x65d5, 0xd89c, 0x0138, 0x2001, 0x0004, 0x080c, 0x65e9,
-	0x2009, 0x0003, 0x0030, 0x2001, 0x0002, 0x080c, 0x65e9, 0x2009,
-	0x0002, 0x080c, 0xafbe, 0x78a8, 0xd094, 0x0138, 0x00ee, 0x7024,
-	0x00e6, 0x2058, 0xb8cc, 0xc08d, 0xb8ce, 0x9085, 0x0001, 0x00ee,
-	0x00ce, 0x00be, 0x001e, 0x012e, 0x1120, 0x2009, 0x0003, 0x0804,
-	0x35b5, 0x7007, 0x0003, 0x701f, 0x4a16, 0x0005, 0xa830, 0x9086,
-	0x0100, 0x7024, 0x2058, 0x1138, 0x2009, 0x0004, 0xba04, 0x9294,
-	0x00ff, 0x0804, 0x56b1, 0x900e, 0xa868, 0xd0f4, 0x1904, 0x3583,
-	0x080c, 0x68b9, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d,
-	0x0804, 0x3583, 0x00e6, 0x00d6, 0x0096, 0x83ff, 0x0904, 0x4a81,
-	0x902e, 0x080c, 0xaead, 0x0130, 0x9026, 0x20a9, 0x0800, 0x2071,
-	0x1000, 0x0030, 0x2021, 0x007f, 0x20a9, 0x0781, 0x2071, 0x107f,
-	0x2e04, 0x9005, 0x11b8, 0x2100, 0x9406, 0x1904, 0x4a92, 0x2428,
-	0x94ce, 0x007f, 0x1120, 0x92ce, 0xfffd, 0x1558, 0x0030, 0x94ce,
-	0x0080, 0x1130, 0x92ce, 0xfffc, 0x1520, 0x93ce, 0x00ff, 0x1508,
-	0xc5fd, 0x0480, 0x2058, 0xbf10, 0x2700, 0x9306, 0x11e8, 0xbe14,
-	0x2600, 0x9206, 0x11c8, 0x2400, 0x9106, 0x1180, 0xd884, 0x0598,
-	0xd894, 0x1588, 0x080c, 0x69ac, 0x1570, 0x2001, 0x4000, 0x0460,
-	0x080c, 0x6a0c, 0x1540, 0x2001, 0x4000, 0x0430, 0x2001, 0x4007,
-	0x0418, 0x2001, 0x4006, 0x0400, 0x2400, 0x9106, 0x1158, 0xbe14,
-	0x87ff, 0x1128, 0x86ff, 0x0918, 0x080c, 0xaead, 0x1900, 0x2001,
-	0x4008, 0x0090, 0x8420, 0x8e70, 0x1f04, 0x4a48, 0x85ff, 0x1130,
-	0x2001, 0x4009, 0x0048, 0x2001, 0x0001, 0x0030, 0x080c, 0x6638,
-	0x1dd0, 0xbb12, 0xba16, 0x9006, 0x9005, 0x009e, 0x00de, 0x00ee,
-	0x0005, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x35b5, 0x080c,
-	0x4b1f, 0x1120, 0x2009, 0x0002, 0x0804, 0x35b5, 0xa867, 0x0000,
-	0xa868, 0xc0fd, 0xa86a, 0x7884, 0x9005, 0x0904, 0x35b8, 0x9096,
-	0x00ff, 0x0120, 0x9092, 0x0004, 0x1a04, 0x35b8, 0x2010, 0x2918,
-	0x080c, 0x31c4, 0x1120, 0x2009, 0x0003, 0x0804, 0x35b5, 0x7007,
-	0x0003, 0x701f, 0x4ad4, 0x0005, 0xa830, 0x9086, 0x0100, 0x1904,
-	0x3583, 0x2009, 0x0004, 0x0804, 0x35b5, 0x7984, 0x080c, 0xaead,
-	0x1120, 0x9182, 0x007f, 0x0a04, 0x35b8, 0x9186, 0x00ff, 0x0904,
-	0x35b8, 0x9182, 0x0800, 0x1a04, 0x35b8, 0x2001, 0x9400, 0x080c,
-	0x570c, 0x1904, 0x35b5, 0x0804, 0x3583, 0xa998, 0x080c, 0xaead,
-	0x1118, 0x9182, 0x007f, 0x0280, 0x9186, 0x00ff, 0x0168, 0x9182,
-	0x0800, 0x1250, 0x2001, 0x9400, 0x080c, 0x570c, 0x11a8, 0x0060,
+	0xa28e, 0xa392, 0xa496, 0xa59a, 0x080c, 0x10f8, 0x7007, 0x0002,
+	0x701f, 0x35b0, 0x0005, 0x00f6, 0x0126, 0x2091, 0x8000, 0x2079,
+	0x0000, 0x2001, 0x18b0, 0x2004, 0x9005, 0x1190, 0x0e04, 0x4c00,
+	0x7a36, 0x7833, 0x0012, 0x7a82, 0x7b86, 0x7c8a, 0x2091, 0x4080,
+	0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11aa, 0x0804, 0x4c66,
+	0x0016, 0x0086, 0x0096, 0x00c6, 0x00e6, 0x2071, 0x189e, 0x7044,
+	0x9005, 0x1540, 0x7148, 0x9182, 0x0010, 0x0288, 0x7038, 0x2060,
+	0x080c, 0x100e, 0x0904, 0x4c5e, 0xa84b, 0x0000, 0x2900, 0x7046,
+	0x2001, 0x0002, 0x9080, 0x20e8, 0x2005, 0xa846, 0x0098, 0x7038,
+	0x90e0, 0x0004, 0x2001, 0x18ba, 0x9c82, 0x18fa, 0x0210, 0x2061,
+	0x18ba, 0x2c00, 0x703a, 0x7148, 0x81ff, 0x1108, 0x703e, 0x8108,
+	0x714a, 0x0460, 0x7148, 0x8108, 0x714a, 0x7044, 0x2040, 0xa144,
+	0x2105, 0x0016, 0x908a, 0x0036, 0x1a0c, 0x0dc5, 0x2060, 0x001e,
+	0x8108, 0x2105, 0x9005, 0xa146, 0x1520, 0x080c, 0x100e, 0x1130,
+	0x8109, 0xa946, 0x7148, 0x8109, 0x714a, 0x00d8, 0x9006, 0xa806,
+	0xa84a, 0xa046, 0x2800, 0xa802, 0x2900, 0xa006, 0x7046, 0x2001,
+	0x0002, 0x9080, 0x20e8, 0x2005, 0xa846, 0x0058, 0x2262, 0x6306,
+	0x640a, 0x00ee, 0x00ce, 0x009e, 0x008e, 0x001e, 0x012e, 0x00fe,
+	0x0005, 0x2c00, 0x9082, 0x001b, 0x0002, 0x4c88, 0x4c88, 0x4c8a,
+	0x4c88, 0x4c88, 0x4c88, 0x4c8e, 0x4c88, 0x4c88, 0x4c88, 0x4c92,
+	0x4c88, 0x4c88, 0x4c88, 0x4c96, 0x4c88, 0x4c88, 0x4c88, 0x4c9a,
+	0x4c88, 0x4c88, 0x4c88, 0x4c9e, 0x4c88, 0x4c88, 0x4c88, 0x4ca3,
+	0x080c, 0x0dc5, 0xa276, 0xa37a, 0xa47e, 0x0898, 0xa286, 0xa38a,
+	0xa48e, 0x0878, 0xa296, 0xa39a, 0xa49e, 0x0858, 0xa2a6, 0xa3aa,
+	0xa4ae, 0x0838, 0xa2b6, 0xa3ba, 0xa4be, 0x0818, 0xa2c6, 0xa3ca,
+	0xa4ce, 0x0804, 0x4c61, 0xa2d6, 0xa3da, 0xa4de, 0x0804, 0x4c61,
+	0x00e6, 0x2071, 0x189e, 0x7048, 0x9005, 0x0904, 0x4d3a, 0x0126,
+	0x2091, 0x8000, 0x0e04, 0x4d39, 0x00f6, 0x2079, 0x0000, 0x00c6,
+	0x0096, 0x0086, 0x0076, 0x9006, 0x2038, 0x7040, 0x2048, 0x9005,
+	0x0500, 0xa948, 0x2105, 0x0016, 0x908a, 0x0036, 0x1a0c, 0x0dc5,
+	0x2060, 0x001e, 0x8108, 0x2105, 0x9005, 0xa94a, 0x1904, 0x4d3c,
+	0xa804, 0x9005, 0x090c, 0x0dc5, 0x7042, 0x2938, 0x2040, 0xa003,
+	0x0000, 0x2001, 0x0002, 0x9080, 0x20e8, 0x2005, 0xa04a, 0x0804,
+	0x4d3c, 0x703c, 0x2060, 0x2c14, 0x6304, 0x6408, 0x650c, 0x2200,
+	0x7836, 0x7833, 0x0012, 0x7882, 0x2300, 0x7886, 0x2400, 0x788a,
+	0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11aa,
+	0x87ff, 0x0118, 0x2748, 0x080c, 0x1040, 0x7048, 0x8001, 0x704a,
+	0x9005, 0x1170, 0x7040, 0x2048, 0x9005, 0x0128, 0x080c, 0x1040,
+	0x9006, 0x7042, 0x7046, 0x703b, 0x18ba, 0x703f, 0x18ba, 0x0420,
+	0x7040, 0x9005, 0x1508, 0x7238, 0x2c00, 0x9206, 0x0148, 0x9c80,
+	0x0004, 0x90fa, 0x18fa, 0x0210, 0x2001, 0x18ba, 0x703e, 0x00a0,
+	0x9006, 0x703e, 0x703a, 0x7044, 0x9005, 0x090c, 0x0dc5, 0x2048,
+	0xa800, 0x9005, 0x1de0, 0x2900, 0x7042, 0x2001, 0x0002, 0x9080,
+	0x20e8, 0x2005, 0xa84a, 0x0000, 0x007e, 0x008e, 0x009e, 0x00ce,
+	0x00fe, 0x012e, 0x00ee, 0x0005, 0x2c00, 0x9082, 0x001b, 0x0002,
+	0x4d5b, 0x4d5b, 0x4d5d, 0x4d5b, 0x4d5b, 0x4d5b, 0x4d62, 0x4d5b,
+	0x4d5b, 0x4d5b, 0x4d67, 0x4d5b, 0x4d5b, 0x4d5b, 0x4d6c, 0x4d5b,
+	0x4d5b, 0x4d5b, 0x4d71, 0x4d5b, 0x4d5b, 0x4d5b, 0x4d76, 0x4d5b,
+	0x4d5b, 0x4d5b, 0x4d7b, 0x080c, 0x0dc5, 0xaa74, 0xab78, 0xac7c,
+	0x0804, 0x4ce7, 0xaa84, 0xab88, 0xac8c, 0x0804, 0x4ce7, 0xaa94,
+	0xab98, 0xac9c, 0x0804, 0x4ce7, 0xaaa4, 0xaba8, 0xacac, 0x0804,
+	0x4ce7, 0xaab4, 0xabb8, 0xacbc, 0x0804, 0x4ce7, 0xaac4, 0xabc8,
+	0xaccc, 0x0804, 0x4ce7, 0xaad4, 0xabd8, 0xacdc, 0x0804, 0x4ce7,
+	0x0016, 0x0026, 0x0036, 0x00b6, 0x00c6, 0x2009, 0x007e, 0x080c,
+	0x6717, 0x2019, 0x0001, 0xb85c, 0xd0ac, 0x0110, 0x2019, 0x0000,
+	0x2011, 0x801b, 0x080c, 0x4be3, 0x00ce, 0x00be, 0x003e, 0x002e,
+	0x001e, 0x0005, 0x0026, 0x080c, 0x57cd, 0xd0c4, 0x0120, 0x2011,
+	0x8014, 0x080c, 0x4be3, 0x002e, 0x0005, 0x81ff, 0x1904, 0x35e2,
+	0x0126, 0x2091, 0x8000, 0x6030, 0xc08d, 0xc085, 0xc0ac, 0x6032,
+	0x080c, 0x7563, 0x1158, 0x080c, 0x7848, 0x080c, 0x6121, 0x9085,
+	0x0001, 0x080c, 0x75a7, 0x080c, 0x748f, 0x0010, 0x080c, 0x5fe0,
+	0x012e, 0x0804, 0x35b0, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804,
+	0x35e2, 0x080c, 0x57e1, 0x0120, 0x2009, 0x0007, 0x0804, 0x35e2,
+	0x080c, 0x6a84, 0x0120, 0x2009, 0x0008, 0x0804, 0x35e2, 0x7984,
+	0x080c, 0x66ac, 0x1904, 0x35e5, 0x080c, 0x4bb6, 0x0904, 0x35e5,
+	0x2b00, 0x7026, 0x080c, 0x6a8c, 0x7888, 0x1170, 0x9084, 0x0005,
+	0x1158, 0x900e, 0x080c, 0x6937, 0x1108, 0xc185, 0xb800, 0xd0bc,
+	0x0108, 0xc18d, 0x0804, 0x35b0, 0x080c, 0x4b83, 0x0904, 0x35e2,
+	0x9006, 0xa866, 0xa832, 0xa868, 0xc0fd, 0xa86a, 0x080c, 0xd069,
+	0x0904, 0x35e2, 0x7888, 0xd094, 0x0118, 0xb8cc, 0xc08d, 0xb8ce,
+	0x7007, 0x0003, 0x701f, 0x4e56, 0x0005, 0x2061, 0x1800, 0x080c,
+	0x57e1, 0x2009, 0x0007, 0x1560, 0x080c, 0x6a84, 0x0118, 0x2009,
+	0x0008, 0x0430, 0xa998, 0x080c, 0x66ac, 0x1530, 0x080c, 0x4bb4,
+	0x0518, 0x080c, 0x6a8c, 0xa89c, 0x1168, 0x9084, 0x0005, 0x1150,
+	0x900e, 0x080c, 0x6937, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108,
+	0xc18d, 0x00d0, 0xa868, 0xc0fc, 0xa86a, 0x080c, 0xd069, 0x11e0,
+	0xa89c, 0xd094, 0x0118, 0xb8cc, 0xc08d, 0xb8ce, 0x2009, 0x0003,
 	0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e, 0x9085,
-	0x0001, 0x2001, 0x0030, 0x0005, 0xa897, 0x4000, 0x900e, 0x9085,
-	0x0001, 0x2001, 0x0000, 0x0005, 0x2009, 0x000a, 0x0c48, 0x080c,
-	0x0fff, 0x0198, 0x9006, 0xa802, 0x7014, 0x9005, 0x1120, 0x2900,
-	0x7016, 0x701a, 0x0040, 0x7018, 0xa802, 0x0086, 0x2040, 0x2900,
-	0xa006, 0x701a, 0x008e, 0x9085, 0x0001, 0x0005, 0x7984, 0x080c,
-	0x6699, 0x1130, 0x7e88, 0x9684, 0x3fff, 0x9082, 0x4000, 0x0208,
-	0x905e, 0x8bff, 0x0005, 0xa998, 0x080c, 0x6699, 0x1130, 0xae9c,
-	0x9684, 0x3fff, 0x9082, 0x4000, 0x0208, 0x905e, 0x8bff, 0x0005,
-	0xae98, 0x0008, 0x7e84, 0x2608, 0x080c, 0x6699, 0x1108, 0x0008,
-	0x905e, 0x8bff, 0x0005, 0x0016, 0x7114, 0x81ff, 0x0128, 0x2148,
-	0xa904, 0x080c, 0x1031, 0x0cc8, 0x7116, 0x711a, 0x001e, 0x0005,
-	0x2031, 0x0001, 0x0010, 0x2031, 0x0000, 0x2061, 0x18b8, 0x2c44,
-	0xa66a, 0xa17a, 0xa772, 0xa076, 0xa28e, 0xa392, 0xa496, 0xa59a,
-	0x080c, 0x10e9, 0x7007, 0x0002, 0x701f, 0x3583, 0x0005, 0x00f6,
-	0x0126, 0x2091, 0x8000, 0x2079, 0x0000, 0x2001, 0x18b0, 0x2004,
-	0x9005, 0x1190, 0x0e04, 0x4b9c, 0x7a36, 0x7833, 0x0012, 0x7a82,
-	0x7b86, 0x7c8a, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084,
-	0x190c, 0x119b, 0x0804, 0x4c02, 0x0016, 0x0086, 0x0096, 0x00c6,
-	0x00e6, 0x2071, 0x189e, 0x7044, 0x9005, 0x1540, 0x7148, 0x9182,
-	0x0010, 0x0288, 0x7038, 0x2060, 0x080c, 0x0fff, 0x0904, 0x4bfa,
-	0xa84b, 0x0000, 0x2900, 0x7046, 0x2001, 0x0002, 0x9080, 0x20ce,
-	0x2005, 0xa846, 0x0098, 0x7038, 0x90e0, 0x0004, 0x2001, 0x18ba,
-	0x9c82, 0x18fa, 0x0210, 0x2061, 0x18ba, 0x2c00, 0x703a, 0x7148,
-	0x81ff, 0x1108, 0x703e, 0x8108, 0x714a, 0x0460, 0x7148, 0x8108,
-	0x714a, 0x7044, 0x2040, 0xa144, 0x2105, 0x0016, 0x908a, 0x0036,
-	0x1a0c, 0x0dd5, 0x2060, 0x001e, 0x8108, 0x2105, 0x9005, 0xa146,
-	0x1520, 0x080c, 0x0fff, 0x1130, 0x8109, 0xa946, 0x7148, 0x8109,
-	0x714a, 0x00d8, 0x9006, 0xa806, 0xa84a, 0xa046, 0x2800, 0xa802,
-	0x2900, 0xa006, 0x7046, 0x2001, 0x0002, 0x9080, 0x20ce, 0x2005,
-	0xa846, 0x0058, 0x2262, 0x6306, 0x640a, 0x00ee, 0x00ce, 0x009e,
-	0x008e, 0x001e, 0x012e, 0x00fe, 0x0005, 0x2c00, 0x9082, 0x001b,
-	0x0002, 0x4c24, 0x4c24, 0x4c26, 0x4c24, 0x4c24, 0x4c24, 0x4c2a,
-	0x4c24, 0x4c24, 0x4c24, 0x4c2e, 0x4c24, 0x4c24, 0x4c24, 0x4c32,
-	0x4c24, 0x4c24, 0x4c24, 0x4c36, 0x4c24, 0x4c24, 0x4c24, 0x4c3a,
-	0x4c24, 0x4c24, 0x4c24, 0x4c3f, 0x080c, 0x0dd5, 0xa276, 0xa37a,
-	0xa47e, 0x0898, 0xa286, 0xa38a, 0xa48e, 0x0878, 0xa296, 0xa39a,
-	0xa49e, 0x0858, 0xa2a6, 0xa3aa, 0xa4ae, 0x0838, 0xa2b6, 0xa3ba,
-	0xa4be, 0x0818, 0xa2c6, 0xa3ca, 0xa4ce, 0x0804, 0x4bfd, 0xa2d6,
-	0xa3da, 0xa4de, 0x0804, 0x4bfd, 0x00e6, 0x2071, 0x189e, 0x7048,
-	0x9005, 0x0904, 0x4cd6, 0x0126, 0x2091, 0x8000, 0x0e04, 0x4cd5,
-	0x00f6, 0x2079, 0x0000, 0x00c6, 0x0096, 0x0086, 0x0076, 0x9006,
-	0x2038, 0x7040, 0x2048, 0x9005, 0x0500, 0xa948, 0x2105, 0x0016,
-	0x908a, 0x0036, 0x1a0c, 0x0dd5, 0x2060, 0x001e, 0x8108, 0x2105,
-	0x9005, 0xa94a, 0x1904, 0x4cd8, 0xa804, 0x9005, 0x090c, 0x0dd5,
-	0x7042, 0x2938, 0x2040, 0xa003, 0x0000, 0x2001, 0x0002, 0x9080,
-	0x20ce, 0x2005, 0xa04a, 0x0804, 0x4cd8, 0x703c, 0x2060, 0x2c14,
-	0x6304, 0x6408, 0x650c, 0x2200, 0x7836, 0x7833, 0x0012, 0x7882,
-	0x2300, 0x7886, 0x2400, 0x788a, 0x2091, 0x4080, 0x2001, 0x0089,
-	0x2004, 0xd084, 0x190c, 0x119b, 0x87ff, 0x0118, 0x2748, 0x080c,
-	0x1031, 0x7048, 0x8001, 0x704a, 0x9005, 0x1170, 0x7040, 0x2048,
-	0x9005, 0x0128, 0x080c, 0x1031, 0x9006, 0x7042, 0x7046, 0x703b,
-	0x18ba, 0x703f, 0x18ba, 0x0420, 0x7040, 0x9005, 0x1508, 0x7238,
-	0x2c00, 0x9206, 0x0148, 0x9c80, 0x0004, 0x90fa, 0x18fa, 0x0210,
-	0x2001, 0x18ba, 0x703e, 0x00a0, 0x9006, 0x703e, 0x703a, 0x7044,
-	0x9005, 0x090c, 0x0dd5, 0x2048, 0xa800, 0x9005, 0x1de0, 0x2900,
-	0x7042, 0x2001, 0x0002, 0x9080, 0x20ce, 0x2005, 0xa84a, 0x0000,
-	0x007e, 0x008e, 0x009e, 0x00ce, 0x00fe, 0x012e, 0x00ee, 0x0005,
-	0x2c00, 0x9082, 0x001b, 0x0002, 0x4cf7, 0x4cf7, 0x4cf9, 0x4cf7,
-	0x4cf7, 0x4cf7, 0x4cfe, 0x4cf7, 0x4cf7, 0x4cf7, 0x4d03, 0x4cf7,
-	0x4cf7, 0x4cf7, 0x4d08, 0x4cf7, 0x4cf7, 0x4cf7, 0x4d0d, 0x4cf7,
-	0x4cf7, 0x4cf7, 0x4d12, 0x4cf7, 0x4cf7, 0x4cf7, 0x4d17, 0x080c,
-	0x0dd5, 0xaa74, 0xab78, 0xac7c, 0x0804, 0x4c83, 0xaa84, 0xab88,
-	0xac8c, 0x0804, 0x4c83, 0xaa94, 0xab98, 0xac9c, 0x0804, 0x4c83,
-	0xaaa4, 0xaba8, 0xacac, 0x0804, 0x4c83, 0xaab4, 0xabb8, 0xacbc,
-	0x0804, 0x4c83, 0xaac4, 0xabc8, 0xaccc, 0x0804, 0x4c83, 0xaad4,
-	0xabd8, 0xacdc, 0x0804, 0x4c83, 0x0016, 0x0026, 0x0036, 0x00b6,
-	0x00c6, 0x2009, 0x007e, 0x080c, 0x6699, 0x2019, 0x0001, 0xb85c,
-	0xd0ac, 0x0110, 0x2019, 0x0000, 0x2011, 0x801b, 0x080c, 0x4b7f,
-	0x00ce, 0x00be, 0x003e, 0x002e, 0x001e, 0x0005, 0x0026, 0x080c,
-	0x575d, 0xd0c4, 0x0120, 0x2011, 0x8014, 0x080c, 0x4b7f, 0x002e,
-	0x0005, 0x81ff, 0x1904, 0x35b5, 0x0126, 0x2091, 0x8000, 0x6030,
-	0xc08d, 0xc085, 0xc0ac, 0x6032, 0x080c, 0x743e, 0x1158, 0x080c,
-	0x7724, 0x080c, 0x60ad, 0x9085, 0x0001, 0x080c, 0x7485, 0x080c,
-	0x736a, 0x0010, 0x080c, 0x5f6c, 0x012e, 0x0804, 0x3583, 0x81ff,
-	0x0120, 0x2009, 0x0001, 0x0804, 0x35b5, 0x080c, 0x5771, 0x0120,
-	0x2009, 0x0007, 0x0804, 0x35b5, 0x080c, 0x6a04, 0x0120, 0x2009,
-	0x0008, 0x0804, 0x35b5, 0x7984, 0x080c, 0x6638, 0x1904, 0x35b8,
-	0x080c, 0x4b52, 0x0904, 0x35b8, 0x2b00, 0x7026, 0x080c, 0x6a0c,
-	0x7888, 0x1170, 0x9084, 0x0005, 0x1158, 0x900e, 0x080c, 0x68b9,
-	0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x0804, 0x3583,
-	0x080c, 0x4b1f, 0x0904, 0x35b5, 0x9006, 0xa866, 0xa832, 0xa868,
-	0xc0fd, 0xa86a, 0x080c, 0xceb0, 0x0904, 0x35b5, 0x7888, 0xd094,
-	0x0118, 0xb8cc, 0xc08d, 0xb8ce, 0x7007, 0x0003, 0x701f, 0x4df2,
-	0x0005, 0x2061, 0x1800, 0x080c, 0x5771, 0x2009, 0x0007, 0x1560,
-	0x080c, 0x6a04, 0x0118, 0x2009, 0x0008, 0x0430, 0xa998, 0x080c,
-	0x6638, 0x1530, 0x080c, 0x4b50, 0x0518, 0x080c, 0x6a0c, 0xa89c,
-	0x1168, 0x9084, 0x0005, 0x1150, 0x900e, 0x080c, 0x68b9, 0x1108,
-	0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x00d0, 0xa868, 0xc0fc,
-	0xa86a, 0x080c, 0xceb0, 0x11e0, 0xa89c, 0xd094, 0x0118, 0xb8cc,
-	0xc08d, 0xb8ce, 0x2009, 0x0003, 0xa897, 0x4005, 0xa99a, 0x0010,
-	0xa897, 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x0005,
-	0xa897, 0x4000, 0xa99a, 0x9006, 0x918d, 0x0001, 0x2008, 0x0005,
-	0x9006, 0x0005, 0xa830, 0x9086, 0x0100, 0x7024, 0x2058, 0x1110,
-	0x0804, 0x56b1, 0x900e, 0x080c, 0x68b9, 0x1108, 0xc185, 0xb800,
-	0xd0bc, 0x0108, 0xc18d, 0x0804, 0x3583, 0x080c, 0x5771, 0x0120,
-	0x2009, 0x0007, 0x0804, 0x35b5, 0x7f84, 0x7a8c, 0x7b88, 0x7c9c,
-	0x7d98, 0x080c, 0x4b1f, 0x1120, 0x2009, 0x0002, 0x0804, 0x35b5,
-	0x900e, 0x2130, 0x7126, 0x7132, 0xa860, 0x20e8, 0x7036, 0xa85c,
-	0x9080, 0x0005, 0x702a, 0x20a0, 0x080c, 0x6699, 0x1904, 0x4e94,
-	0x080c, 0x6a0c, 0x0138, 0x080c, 0x6a14, 0x0120, 0x080c, 0x69ac,
-	0x1904, 0x4e94, 0xd794, 0x1110, 0xd784, 0x01a8, 0xb8c4, 0x20e0,
-	0xb8c8, 0x9080, 0x0006, 0x2098, 0x3400, 0xd794, 0x0160, 0x20a9,
-	0x0008, 0x4003, 0x2098, 0x20a0, 0x3d00, 0x20e0, 0x20a9, 0x0002,
-	0x080c, 0x491e, 0x0048, 0x20a9, 0x0004, 0x4003, 0x2098, 0x20a0,
-	0x3d00, 0x20e0, 0x080c, 0x491e, 0x9186, 0x007e, 0x0170, 0x9186,
-	0x0080, 0x0158, 0x080c, 0x6a0c, 0x90c2, 0x0006, 0x1210, 0xc1fd,
-	0x0020, 0x080c, 0x68b9, 0x1108, 0xc1fd, 0x4104, 0xc1fc, 0xd794,
-	0x0528, 0xb8c4, 0x20e0, 0xb8c8, 0x2060, 0x9c80, 0x0000, 0x2098,
-	0x20a9, 0x0002, 0x4003, 0x9c80, 0x0003, 0x2098, 0x20a9, 0x0001,
-	0x4005, 0x9c80, 0x0004, 0x2098, 0x3400, 0x20a9, 0x0002, 0x4003,
-	0x2098, 0x20a0, 0x3d00, 0x20e0, 0x080c, 0x4911, 0x9c80, 0x0026,
-	0x2098, 0xb8c4, 0x20e0, 0x20a9, 0x0002, 0x4003, 0xd794, 0x0110,
-	0x96b0, 0x000b, 0x96b0, 0x0005, 0x8108, 0x080c, 0xaead, 0x0118,
-	0x9186, 0x0800, 0x0040, 0xd78c, 0x0120, 0x9186, 0x0800, 0x0170,
-	0x0018, 0x9186, 0x007e, 0x0150, 0xd794, 0x0118, 0x9686, 0x0020,
-	0x0010, 0x9686, 0x0028, 0x0150, 0x0804, 0x4e24, 0x86ff, 0x1120,
-	0x7124, 0x810b, 0x0804, 0x3583, 0x7033, 0x0001, 0x7122, 0x7024,
-	0x9600, 0x7026, 0x772e, 0x2061, 0x18b8, 0x2c44, 0xa06b, 0x0000,
-	0xa67a, 0x7034, 0xa072, 0x7028, 0xa076, 0xa28e, 0xa392, 0xa496,
-	0xa59a, 0x080c, 0x10e9, 0x7007, 0x0002, 0x701f, 0x4ed0, 0x0005,
-	0x7030, 0x9005, 0x1180, 0x7120, 0x7028, 0x20a0, 0x772c, 0x9036,
-	0x7034, 0x20e8, 0x2061, 0x18b8, 0x2c44, 0xa28c, 0xa390, 0xa494,
-	0xa598, 0x0804, 0x4e24, 0x7124, 0x810b, 0x0804, 0x3583, 0x2029,
-	0x007e, 0x7984, 0x7a88, 0x7b8c, 0x7c98, 0x9184, 0xff00, 0x8007,
-	0x90e2, 0x0020, 0x0a04, 0x35b8, 0x9502, 0x0a04, 0x35b8, 0x9184,
-	0x00ff, 0x90e2, 0x0020, 0x0a04, 0x35b8, 0x9502, 0x0a04, 0x35b8,
-	0x9284, 0xff00, 0x8007, 0x90e2, 0x0020, 0x0a04, 0x35b8, 0x9502,
-	0x0a04, 0x35b8, 0x9284, 0x00ff, 0x90e2, 0x0020, 0x0a04, 0x35b8,
-	0x9502, 0x0a04, 0x35b8, 0x9384, 0xff00, 0x8007, 0x90e2, 0x0020,
-	0x0a04, 0x35b8, 0x9502, 0x0a04, 0x35b8, 0x9384, 0x00ff, 0x90e2,
-	0x0020, 0x0a04, 0x35b8, 0x9502, 0x0a04, 0x35b8, 0x9484, 0xff00,
-	0x8007, 0x90e2, 0x0020, 0x0a04, 0x35b8, 0x9502, 0x0a04, 0x35b8,
-	0x9484, 0x00ff, 0x90e2, 0x0020, 0x0a04, 0x35b8, 0x9502, 0x0a04,
-	0x35b8, 0x2061, 0x1988, 0x6102, 0x6206, 0x630a, 0x640e, 0x0804,
-	0x3583, 0x080c, 0x4b1f, 0x0904, 0x35b5, 0x2009, 0x0016, 0x7a8c,
-	0x7b88, 0x7c9c, 0x7d98, 0xa85c, 0x9080, 0x0019, 0xaf60, 0x080c,
-	0x4b68, 0x701f, 0x4f54, 0x0005, 0x2001, 0x0138, 0x2003, 0x0000,
-	0x00e6, 0x2071, 0x0300, 0x701c, 0xd0a4, 0x1de8, 0x00ee, 0x20a9,
-	0x0016, 0x896e, 0x8d6e, 0x8d6f, 0x9d84, 0xffc0, 0x9080, 0x0019,
-	0x2098, 0x9d84, 0x003f, 0x20e0, 0x2069, 0x1877, 0x20e9, 0x0001,
-	0x2da0, 0x4003, 0x6800, 0x9005, 0x0904, 0x4fd5, 0x6804, 0x2008,
-	0x918c, 0xfff8, 0x1904, 0x4fd5, 0x680c, 0x9005, 0x0904, 0x4fd5,
-	0x9082, 0xff01, 0x1a04, 0x4fd5, 0x6810, 0x9082, 0x005c, 0x0a04,
-	0x4fd5, 0x6824, 0x2008, 0x9082, 0x0008, 0x0a04, 0x4fd5, 0x9182,
-	0x0400, 0x1a04, 0x4fd5, 0x0056, 0x2029, 0x0000, 0x080c, 0x8bbf,
-	0x005e, 0x6944, 0x6820, 0x9102, 0x06c0, 0x6820, 0x9082, 0x0019,
-	0x16a0, 0x6828, 0x6944, 0x810c, 0x9102, 0x0678, 0x6840, 0x9082,
-	0x000f, 0x1658, 0x080c, 0x1018, 0x2900, 0x0904, 0x4ff1, 0x684e,
-	0x00e6, 0x2071, 0x1930, 0x00b6, 0x2059, 0x0000, 0x080c, 0x8a7b,
-	0x00be, 0x00ee, 0x0568, 0x080c, 0x87ce, 0x080c, 0x8819, 0x11e0,
-	0x6857, 0x0000, 0x00c6, 0x2061, 0x0100, 0x6104, 0x918d, 0x2000,
-	0x6106, 0x6b10, 0x2061, 0x1a61, 0x630a, 0x00ce, 0x080c, 0x2994,
-	0x2001, 0x0138, 0x2102, 0x0804, 0x3583, 0x080c, 0x2994, 0x2001,
-	0x0138, 0x2102, 0x0804, 0x35b8, 0x080c, 0x8812, 0x00e6, 0x2071,
-	0x1930, 0x080c, 0x8c3f, 0x080c, 0x8c4e, 0x080c, 0x8a62, 0x00ee,
-	0x2001, 0x188a, 0x204c, 0x080c, 0x1031, 0x2001, 0x188a, 0x2003,
-	0x0000, 0x080c, 0x2994, 0x2001, 0x0138, 0x2102, 0x0804, 0x35b5,
-	0x2001, 0x1924, 0x200c, 0x918e, 0x0000, 0x0904, 0x5052, 0x080c,
-	0x8a5d, 0x0904, 0x5052, 0x2001, 0x0101, 0x200c, 0x918c, 0xdfff,
-	0x2102, 0x2001, 0x0138, 0x2003, 0x0000, 0x00e6, 0x2071, 0x0300,
-	0x701c, 0xd0a4, 0x1de8, 0x00ee, 0x080c, 0x8a62, 0x2001, 0x0035,
-	0x080c, 0x15fd, 0x00c6, 0x2061, 0x193c, 0x6004, 0x6100, 0x9106,
-	0x1de0, 0x00ce, 0x080c, 0x2994, 0x2001, 0x0138, 0x2102, 0x00e6,
-	0x00f6, 0x2071, 0x1923, 0x080c, 0x899c, 0x0120, 0x2f00, 0x080c,
-	0x8a28, 0x0cc8, 0x00fe, 0x00ee, 0x0126, 0x2091, 0x8000, 0x2001,
-	0x188a, 0x200c, 0x81ff, 0x0138, 0x2148, 0x080c, 0x1031, 0x2001,
-	0x188a, 0x2003, 0x0000, 0x2001, 0x183c, 0x2003, 0x0020, 0x080c,
-	0x8812, 0x00e6, 0x2071, 0x1930, 0x080c, 0x8c3f, 0x080c, 0x8c4e,
-	0x00ee, 0x012e, 0x0804, 0x3583, 0x0006, 0x080c, 0x575d, 0xd0cc,
-	0x000e, 0x0005, 0x0006, 0x080c, 0x5761, 0xd0bc, 0x000e, 0x0005,
-	0x6174, 0x7a84, 0x6300, 0x82ff, 0x1118, 0x7986, 0x0804, 0x3583,
-	0x83ff, 0x1904, 0x35b8, 0x2001, 0xfff0, 0x9200, 0x1a04, 0x35b8,
-	0x2019, 0xffff, 0x6078, 0x9302, 0x9200, 0x0a04, 0x35b8, 0x7986,
-	0x6276, 0x0804, 0x3583, 0x080c, 0x5771, 0x1904, 0x35b5, 0x7c88,
-	0x7d84, 0x7e98, 0x7f8c, 0x080c, 0x4b1f, 0x0904, 0x35b5, 0x900e,
-	0x901e, 0x7326, 0x7332, 0xa860, 0x20e8, 0x7036, 0xa85c, 0x9080,
-	0x0003, 0x702a, 0x20a0, 0x91d8, 0x1000, 0x2b5c, 0x8bff, 0x0178,
-	0x080c, 0x6a0c, 0x0118, 0x080c, 0x6a14, 0x1148, 0x20a9, 0x0001,
-	0xb814, 0x4004, 0xb810, 0x4004, 0x4104, 0x9398, 0x0003, 0x8108,
-	0x9182, 0x0800, 0x0120, 0x9386, 0x003c, 0x0170, 0x0c20, 0x83ff,
-	0x1148, 0x7224, 0x900e, 0x2001, 0x0003, 0x080c, 0x9027, 0x2208,
-	0x0804, 0x3583, 0x7033, 0x0001, 0x7122, 0x7024, 0x9300, 0x7026,
-	0x2061, 0x18b8, 0x2c44, 0xa06b, 0x0000, 0xa37a, 0x7028, 0xa076,
-	0x7034, 0xa072, 0xa48e, 0xa592, 0xa696, 0xa79a, 0x080c, 0x10e9,
-	0x7007, 0x0002, 0x701f, 0x50d5, 0x0005, 0x7030, 0x9005, 0x1178,
-	0x7120, 0x7028, 0x20a0, 0x901e, 0x7034, 0x20e8, 0x2061, 0x18b8,
-	0x2c44, 0xa48c, 0xa590, 0xa694, 0xa798, 0x0804, 0x5093, 0x7224,
-	0x900e, 0x2001, 0x0003, 0x080c, 0x9027, 0x2208, 0x0804, 0x3583,
-	0x00f6, 0x00e6, 0x080c, 0x5771, 0x2009, 0x0007, 0x1904, 0x5168,
-	0x2071, 0x189e, 0x745c, 0x84ff, 0x2009, 0x000e, 0x1904, 0x5168,
-	0xac9c, 0xad98, 0xaea4, 0xafa0, 0x0096, 0x080c, 0x1018, 0x2009,
-	0x0002, 0x0904, 0x5168, 0x2900, 0x705e, 0x900e, 0x901e, 0x7356,
-	0x7362, 0xa860, 0x7066, 0xa85c, 0x9080, 0x0003, 0x705a, 0x20a0,
-	0x91d8, 0x1000, 0x2b5c, 0x8bff, 0x0178, 0x080c, 0x6a0c, 0x0118,
-	0x080c, 0x6a14, 0x1148, 0xb814, 0x20a9, 0x0001, 0x4004, 0xb810,
-	0x4004, 0x4104, 0x9398, 0x0003, 0x8108, 0x9182, 0x0800, 0x0120,
-	0x9386, 0x003c, 0x01e8, 0x0c20, 0x83ff, 0x11c0, 0x7254, 0x900e,
-	0x2001, 0x0003, 0x080c, 0x9027, 0x2208, 0x009e, 0xa897, 0x4000,
-	0xa99a, 0x715c, 0x81ff, 0x090c, 0x0dd5, 0x2148, 0x080c, 0x1031,
-	0x9006, 0x705e, 0x918d, 0x0001, 0x2008, 0x0418, 0x7063, 0x0001,
-	0x7152, 0x7054, 0x9300, 0x7056, 0x2061, 0x18b9, 0x2c44, 0xa37a,
-	0x7058, 0xa076, 0x7064, 0xa072, 0xa48e, 0xa592, 0xa696, 0xa79a,
-	0xa09f, 0x5174, 0x000e, 0xa0a2, 0x080c, 0x10e9, 0x9006, 0x0048,
-	0x009e, 0xa897, 0x4005, 0xa99a, 0x900e, 0x9085, 0x0001, 0x2001,
-	0x0030, 0x00ee, 0x00fe, 0x0005, 0x00f6, 0xa0a0, 0x904d, 0x090c,
-	0x0dd5, 0x00e6, 0x2071, 0x189e, 0xa06c, 0x908e, 0x0100, 0x0138,
-	0xa87b, 0x0030, 0xa883, 0x0000, 0xa897, 0x4002, 0x00d8, 0x7060,
-	0x9005, 0x1158, 0x7150, 0x7058, 0x20a0, 0x901e, 0x7064, 0x20e8,
-	0xa48c, 0xa590, 0xa694, 0xa798, 0x0428, 0xa87b, 0x0000, 0xa883,
-	0x0000, 0xa897, 0x4000, 0x7254, 0x900e, 0x2001, 0x0003, 0x080c,
-	0x9027, 0xaa9a, 0x715c, 0x81ff, 0x090c, 0x0dd5, 0x2148, 0x080c,
-	0x1031, 0x705f, 0x0000, 0xa0a0, 0x2048, 0x0126, 0x2091, 0x8000,
-	0x080c, 0x6d17, 0x012e, 0xa09f, 0x0000, 0xa0a3, 0x0000, 0x00ee,
-	0x00fe, 0x0005, 0x91d8, 0x1000, 0x2b5c, 0x8bff, 0x0178, 0x080c,
-	0x6a0c, 0x0118, 0x080c, 0x6a14, 0x1148, 0xb814, 0x20a9, 0x0001,
+	0x0001, 0x2001, 0x0030, 0x0005, 0xa897, 0x4000, 0xa99a, 0x9006,
+	0x918d, 0x0001, 0x2008, 0x0005, 0x9006, 0x0005, 0xa830, 0x9086,
+	0x0100, 0x7024, 0x2058, 0x1110, 0x0804, 0x5721, 0x900e, 0x080c,
+	0x6937, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x0804,
+	0x35b0, 0x080c, 0x57e1, 0x0120, 0x2009, 0x0007, 0x0804, 0x35e2,
+	0x7f84, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x080c, 0x4b83, 0x1120,
+	0x2009, 0x0002, 0x0804, 0x35e2, 0x900e, 0x2130, 0x7126, 0x7132,
+	0xa860, 0x20e8, 0x7036, 0xa85c, 0x9080, 0x0005, 0x702a, 0x20a0,
+	0x080c, 0x6717, 0x1904, 0x4eff, 0x080c, 0x6a8c, 0x0138, 0x080c,
+	0x6a94, 0x0120, 0x080c, 0x6a2c, 0x1904, 0x4eff, 0xd794, 0x1110,
+	0xd784, 0x01a8, 0xb8c4, 0x20e0, 0xb8c8, 0x9080, 0x0006, 0x2098,
+	0x3400, 0xd794, 0x0198, 0x20a9, 0x0008, 0x4003, 0x2098, 0x20a0,
+	0x3d00, 0x20e0, 0x20a9, 0x0002, 0x080c, 0x4982, 0x0080, 0xb8c4,
+	0x20e0, 0xb8c8, 0x9080, 0x000a, 0x2098, 0x3400, 0x20a9, 0x0004,
+	0x4003, 0x2098, 0x20a0, 0x3d00, 0x20e0, 0x080c, 0x4982, 0x9186,
+	0x007e, 0x0170, 0x9186, 0x0080, 0x0158, 0x080c, 0x6a8c, 0x90c2,
+	0x0006, 0x1210, 0xc1fd, 0x0020, 0x080c, 0x6937, 0x1108, 0xc1fd,
+	0x4104, 0xc1fc, 0xd794, 0x0528, 0xb8c4, 0x20e0, 0xb8c8, 0x2060,
+	0x9c80, 0x0000, 0x2098, 0x20a9, 0x0002, 0x4003, 0x9c80, 0x0003,
+	0x2098, 0x20a9, 0x0001, 0x4005, 0x9c80, 0x0004, 0x2098, 0x3400,
+	0x20a9, 0x0002, 0x4003, 0x2098, 0x20a0, 0x3d00, 0x20e0, 0x080c,
+	0x4975, 0x9c80, 0x0026, 0x2098, 0xb8c4, 0x20e0, 0x20a9, 0x0002,
+	0x4003, 0xd794, 0x0110, 0x96b0, 0x000b, 0x96b0, 0x0005, 0x8108,
+	0x080c, 0xb051, 0x0118, 0x9186, 0x0800, 0x0040, 0xd78c, 0x0120,
+	0x9186, 0x0800, 0x0170, 0x0018, 0x9186, 0x007e, 0x0150, 0xd794,
+	0x0118, 0x9686, 0x0020, 0x0010, 0x9686, 0x0028, 0x0150, 0x0804,
+	0x4e88, 0x86ff, 0x1120, 0x7124, 0x810b, 0x0804, 0x35b0, 0x7033,
+	0x0001, 0x7122, 0x7024, 0x9600, 0x7026, 0x772e, 0x2061, 0x18b8,
+	0x2c44, 0xa06b, 0x0000, 0xa67a, 0x7034, 0xa072, 0x7028, 0xa076,
+	0xa28e, 0xa392, 0xa496, 0xa59a, 0x080c, 0x10f8, 0x7007, 0x0002,
+	0x701f, 0x4f3b, 0x0005, 0x7030, 0x9005, 0x1180, 0x7120, 0x7028,
+	0x20a0, 0x772c, 0x9036, 0x7034, 0x20e8, 0x2061, 0x18b8, 0x2c44,
+	0xa28c, 0xa390, 0xa494, 0xa598, 0x0804, 0x4e88, 0x7124, 0x810b,
+	0x0804, 0x35b0, 0x2029, 0x007e, 0x7984, 0x7a88, 0x7b8c, 0x7c98,
+	0x9184, 0xff00, 0x8007, 0x90e2, 0x0020, 0x0a04, 0x35e5, 0x9502,
+	0x0a04, 0x35e5, 0x9184, 0x00ff, 0x90e2, 0x0020, 0x0a04, 0x35e5,
+	0x9502, 0x0a04, 0x35e5, 0x9284, 0xff00, 0x8007, 0x90e2, 0x0020,
+	0x0a04, 0x35e5, 0x9502, 0x0a04, 0x35e5, 0x9284, 0x00ff, 0x90e2,
+	0x0020, 0x0a04, 0x35e5, 0x9502, 0x0a04, 0x35e5, 0x9384, 0xff00,
+	0x8007, 0x90e2, 0x0020, 0x0a04, 0x35e5, 0x9502, 0x0a04, 0x35e5,
+	0x9384, 0x00ff, 0x90e2, 0x0020, 0x0a04, 0x35e5, 0x9502, 0x0a04,
+	0x35e5, 0x9484, 0xff00, 0x8007, 0x90e2, 0x0020, 0x0a04, 0x35e5,
+	0x9502, 0x0a04, 0x35e5, 0x9484, 0x00ff, 0x90e2, 0x0020, 0x0a04,
+	0x35e5, 0x9502, 0x0a04, 0x35e5, 0x2061, 0x198a, 0x6102, 0x6206,
+	0x630a, 0x640e, 0x0804, 0x35b0, 0x080c, 0x4b83, 0x0904, 0x35e2,
+	0x2009, 0x0016, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0xa85c, 0x9080,
+	0x0019, 0xaf60, 0x080c, 0x4bcc, 0x701f, 0x4fbf, 0x0005, 0x2001,
+	0x0138, 0x2003, 0x0000, 0x00e6, 0x2071, 0x0300, 0x701c, 0xd0a4,
+	0x1de8, 0x00ee, 0x20a9, 0x0016, 0x896e, 0x8d6e, 0x8d6f, 0x9d84,
+	0xffc0, 0x9080, 0x0019, 0x2098, 0x9d84, 0x003f, 0x20e0, 0x2069,
+	0x1877, 0x20e9, 0x0001, 0x2da0, 0x4003, 0x6800, 0x9005, 0x0904,
+	0x5040, 0x6804, 0x2008, 0x918c, 0xfff8, 0x1904, 0x5040, 0x680c,
+	0x9005, 0x0904, 0x5040, 0x9082, 0xff01, 0x1a04, 0x5040, 0x6810,
+	0x9082, 0x005c, 0x0a04, 0x5040, 0x6824, 0x2008, 0x9082, 0x0008,
+	0x0a04, 0x5040, 0x9182, 0x0400, 0x1a04, 0x5040, 0x0056, 0x2029,
+	0x0000, 0x080c, 0x8d43, 0x005e, 0x6944, 0x6820, 0x9102, 0x06c0,
+	0x6820, 0x9082, 0x0019, 0x16a0, 0x6828, 0x6944, 0x810c, 0x9102,
+	0x0678, 0x6840, 0x9082, 0x000f, 0x1658, 0x080c, 0x1027, 0x2900,
+	0x0904, 0x505c, 0x684e, 0x00e6, 0x2071, 0x1932, 0x00b6, 0x2059,
+	0x0000, 0x080c, 0x8bff, 0x00be, 0x00ee, 0x0568, 0x080c, 0x894a,
+	0x080c, 0x8999, 0x11e0, 0x6857, 0x0000, 0x00c6, 0x2061, 0x0100,
+	0x6104, 0x918d, 0x2000, 0x6106, 0x6b10, 0x2061, 0x1a66, 0x630a,
+	0x00ce, 0x080c, 0x29a1, 0x2001, 0x0138, 0x2102, 0x0804, 0x35b0,
+	0x080c, 0x29a1, 0x2001, 0x0138, 0x2102, 0x0804, 0x35e5, 0x080c,
+	0x8992, 0x00e6, 0x2071, 0x1932, 0x080c, 0x8dc3, 0x080c, 0x8dd2,
+	0x080c, 0x8be2, 0x00ee, 0x2001, 0x188a, 0x204c, 0x080c, 0x1040,
+	0x2001, 0x188a, 0x2003, 0x0000, 0x080c, 0x29a1, 0x2001, 0x0138,
+	0x2102, 0x0804, 0x35e2, 0x2001, 0x1926, 0x200c, 0x918e, 0x0000,
+	0x0904, 0x50c1, 0x080c, 0x8bdd, 0x0904, 0x50c1, 0x2001, 0x0101,
+	0x200c, 0x918c, 0xdfff, 0x2102, 0x2001, 0x0138, 0x2003, 0x0000,
+	0x00e6, 0x2071, 0x0300, 0x701c, 0xd0a4, 0x1de8, 0x00ee, 0x080c,
+	0x8be2, 0x0126, 0x2091, 0x8000, 0x2001, 0x0035, 0x080c, 0x1611,
+	0x012e, 0x00c6, 0x2061, 0x193e, 0x6004, 0x6100, 0x9106, 0x1de0,
+	0x00ce, 0x080c, 0x29a1, 0x2001, 0x0138, 0x2102, 0x00e6, 0x00f6,
+	0x2071, 0x1925, 0x080c, 0x8b1c, 0x0120, 0x2f00, 0x080c, 0x8ba8,
+	0x0cc8, 0x00fe, 0x00ee, 0x0126, 0x2091, 0x8000, 0x2001, 0x188a,
+	0x200c, 0x81ff, 0x0138, 0x2148, 0x080c, 0x1040, 0x2001, 0x188a,
+	0x2003, 0x0000, 0x2001, 0x183d, 0x2003, 0x0020, 0x080c, 0x8992,
+	0x00e6, 0x2071, 0x1932, 0x080c, 0x8dc3, 0x080c, 0x8dd2, 0x00ee,
+	0x012e, 0x0804, 0x35b0, 0x0006, 0x080c, 0x57cd, 0xd0cc, 0x000e,
+	0x0005, 0x0006, 0x080c, 0x57d1, 0xd0bc, 0x000e, 0x0005, 0x6174,
+	0x7a84, 0x6300, 0x82ff, 0x1118, 0x7986, 0x0804, 0x35b0, 0x83ff,
+	0x1904, 0x35e5, 0x2001, 0xfff0, 0x9200, 0x1a04, 0x35e5, 0x2019,
+	0xffff, 0x6078, 0x9302, 0x9200, 0x0a04, 0x35e5, 0x7986, 0x6276,
+	0x0804, 0x35b0, 0x080c, 0x57e1, 0x1904, 0x35e2, 0x7c88, 0x7d84,
+	0x7e98, 0x7f8c, 0x080c, 0x4b83, 0x0904, 0x35e2, 0x900e, 0x901e,
+	0x7326, 0x7332, 0xa860, 0x20e8, 0x7036, 0xa85c, 0x9080, 0x0003,
+	0x702a, 0x20a0, 0x91d8, 0x1000, 0x2b5c, 0x8bff, 0x0178, 0x080c,
+	0x6a8c, 0x0118, 0x080c, 0x6a94, 0x1148, 0x20a9, 0x0001, 0xb814,
 	0x4004, 0xb810, 0x4004, 0x4104, 0x9398, 0x0003, 0x8108, 0x9182,
-	0x0800, 0x0120, 0x9386, 0x003c, 0x0518, 0x0c20, 0x83ff, 0x11f0,
-	0x7154, 0x810c, 0xa99a, 0xa897, 0x4000, 0x715c, 0x81ff, 0x090c,
-	0x0dd5, 0x2148, 0x080c, 0x1031, 0x9006, 0x705e, 0x918d, 0x0001,
-	0x2008, 0xa0a0, 0x2048, 0x0126, 0x2091, 0x8000, 0x080c, 0x6d17,
-	0x012e, 0xa09f, 0x0000, 0xa0a3, 0x0000, 0x0070, 0x7063, 0x0001,
-	0x7152, 0x7054, 0x9300, 0x7056, 0xa37a, 0xa48e, 0xa592, 0xa696,
-	0xa79a, 0x080c, 0x10e9, 0x9006, 0x00ee, 0x0005, 0x0096, 0xa88c,
-	0x90be, 0x7000, 0x0148, 0x90be, 0x7100, 0x0130, 0x90be, 0x7200,
-	0x0118, 0x009e, 0x0804, 0x35b8, 0xa884, 0xa988, 0x080c, 0x287c,
-	0x1518, 0x080c, 0x6638, 0x1500, 0x7126, 0xbe12, 0xbd16, 0xae7c,
-	0x080c, 0x4b1f, 0x01c8, 0x080c, 0x4b1f, 0x01b0, 0x009e, 0xa867,
-	0x0000, 0xa868, 0xc0fd, 0xa86a, 0xa823, 0x0000, 0xa804, 0x2048,
-	0x080c, 0xce32, 0x1120, 0x2009, 0x0003, 0x0804, 0x35b5, 0x7007,
-	0x0003, 0x701f, 0x5241, 0x0005, 0x009e, 0x2009, 0x0002, 0x0804,
-	0x35b5, 0x7124, 0x080c, 0x331a, 0xa820, 0x9086, 0x8001, 0x1120,
-	0x2009, 0x0004, 0x0804, 0x35b5, 0x2900, 0x7022, 0xa804, 0x0096,
-	0x2048, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0,
-	0x009e, 0x9080, 0x0002, 0x0076, 0x0006, 0x2098, 0x20a0, 0x27e0,
-	0x27e8, 0x20a9, 0x002a, 0x080c, 0x0f7c, 0xaa6c, 0xab70, 0xac74,
-	0xad78, 0x2061, 0x18b8, 0x2c44, 0xa06b, 0x0000, 0xae64, 0xaf8c,
-	0x97c6, 0x7000, 0x0118, 0x97c6, 0x7100, 0x1148, 0x96c2, 0x0004,
-	0x0600, 0x2009, 0x0004, 0x000e, 0x007e, 0x0804, 0x4b6b, 0x97c6,
-	0x7200, 0x11b8, 0x96c2, 0x0054, 0x02a0, 0x000e, 0x007e, 0x2061,
-	0x18b8, 0x2c44, 0xa076, 0xa772, 0xa07b, 0x002a, 0xa28e, 0xa392,
-	0xa496, 0xa59a, 0x080c, 0x10e9, 0x7007, 0x0002, 0x701f, 0x529d,
-	0x0005, 0x000e, 0x007e, 0x0804, 0x35b8, 0x7020, 0x2048, 0xa804,
-	0x2048, 0xa804, 0x2048, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f,
-	0x9084, 0xffc0, 0x9080, 0x0002, 0x2098, 0x20a0, 0x27e0, 0x27e8,
-	0x20a9, 0x002a, 0x080c, 0x0f7c, 0x2100, 0x2238, 0x2061, 0x18b8,
-	0x2c44, 0xa28c, 0xa390, 0xa494, 0xa598, 0x2009, 0x002a, 0x0804,
-	0x4b6b, 0x81ff, 0x1904, 0x35b5, 0x798c, 0x2001, 0x197d, 0x918c,
-	0x8000, 0x2102, 0x080c, 0x4b36, 0x0904, 0x35b8, 0x080c, 0x6a0c,
-	0x0120, 0x080c, 0x6a14, 0x1904, 0x35b8, 0x080c, 0x6760, 0x0904,
-	0x35b5, 0x0126, 0x2091, 0x8000, 0x080c, 0x6826, 0x012e, 0x0904,
-	0x35b5, 0x2001, 0x197d, 0x2004, 0xd0fc, 0x1904, 0x3583, 0x0804,
-	0x4586, 0xa9a0, 0x2001, 0x197d, 0x918c, 0x8000, 0xc18d, 0x2102,
-	0x080c, 0x4b43, 0x01a0, 0x080c, 0x6a0c, 0x0118, 0x080c, 0x6a14,
-	0x1170, 0x080c, 0x6760, 0x2009, 0x0002, 0x0128, 0x080c, 0x6826,
-	0x1170, 0x2009, 0x0003, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897,
-	0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x0005, 0xa897,
-	0x4000, 0x2001, 0x197d, 0x2004, 0xd0fc, 0x1128, 0x080c, 0x5765,
-	0x0110, 0x9006, 0x0018, 0x900e, 0x9085, 0x0001, 0x2001, 0x0000,
-	0x0005, 0x78a8, 0xd08c, 0x1118, 0xd084, 0x0904, 0x44fb, 0x080c,
-	0x4b52, 0x0904, 0x35b8, 0x080c, 0x4b1f, 0x1120, 0x2009, 0x0002,
-	0x0804, 0x35b5, 0x080c, 0x6a0c, 0x0130, 0x908e, 0x0004, 0x0118,
-	0x908e, 0x0005, 0x15a0, 0x78a8, 0xd08c, 0x0120, 0xb800, 0xc08c,
-	0xb802, 0x0028, 0x080c, 0x575d, 0xd0b4, 0x0904, 0x4535, 0x7884,
-	0x908e, 0x007e, 0x0904, 0x4535, 0x908e, 0x007f, 0x0904, 0x4535,
-	0x908e, 0x0080, 0x0904, 0x4535, 0xb800, 0xd08c, 0x1904, 0x4535,
-	0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x080c, 0xce51, 0x1120,
-	0x2009, 0x0003, 0x0804, 0x35b5, 0x7007, 0x0003, 0x701f, 0x5369,
-	0x0005, 0x080c, 0x4b52, 0x0904, 0x35b8, 0x0804, 0x4535, 0x080c,
-	0x3373, 0x0108, 0x0005, 0x2009, 0x1834, 0x210c, 0x81ff, 0x0120,
-	0x2009, 0x0001, 0x0804, 0x35b5, 0x080c, 0x5771, 0x0120, 0x2009,
-	0x0007, 0x0804, 0x35b5, 0x080c, 0x6a04, 0x0120, 0x2009, 0x0008,
-	0x0804, 0x35b5, 0xb89c, 0xd0a4, 0x1118, 0xd0ac, 0x1904, 0x4535,
-	0x9006, 0xa866, 0xa832, 0xa868, 0xc0fd, 0xa86a, 0x080c, 0xceb0,
-	0x1120, 0x2009, 0x0003, 0x0804, 0x35b5, 0x7007, 0x0003, 0x701f,
-	0x53a2, 0x0005, 0xa830, 0x9086, 0x0100, 0x1120, 0x2009, 0x0004,
-	0x0804, 0x56b1, 0x080c, 0x4b52, 0x0904, 0x35b8, 0x0804, 0x533b,
-	0x81ff, 0x2009, 0x0001, 0x1904, 0x35b5, 0x080c, 0x5771, 0x2009,
-	0x0007, 0x1904, 0x35b5, 0x080c, 0x6a04, 0x0120, 0x2009, 0x0008,
-	0x0804, 0x35b5, 0x080c, 0x4b52, 0x0904, 0x35b8, 0x080c, 0x6a0c,
-	0x2009, 0x0009, 0x1904, 0x35b5, 0x080c, 0x4b1f, 0x2009, 0x0002,
-	0x0904, 0x35b5, 0x9006, 0xa866, 0xa832, 0xa868, 0xc0fd, 0xa86a,
-	0x7988, 0x9194, 0xff00, 0x918c, 0x00ff, 0x9006, 0x82ff, 0x1128,
+	0x0800, 0x0120, 0x9386, 0x003c, 0x0170, 0x0c20, 0x83ff, 0x1148,
+	0x7224, 0x900e, 0x2001, 0x0003, 0x080c, 0x91ab, 0x2208, 0x0804,
+	0x35b0, 0x7033, 0x0001, 0x7122, 0x7024, 0x9300, 0x7026, 0x2061,
+	0x18b8, 0x2c44, 0xa06b, 0x0000, 0xa37a, 0x7028, 0xa076, 0x7034,
+	0xa072, 0xa48e, 0xa592, 0xa696, 0xa79a, 0x080c, 0x10f8, 0x7007,
+	0x0002, 0x701f, 0x5144, 0x0005, 0x7030, 0x9005, 0x1178, 0x7120,
+	0x7028, 0x20a0, 0x901e, 0x7034, 0x20e8, 0x2061, 0x18b8, 0x2c44,
+	0xa48c, 0xa590, 0xa694, 0xa798, 0x0804, 0x5102, 0x7224, 0x900e,
+	0x2001, 0x0003, 0x080c, 0x91ab, 0x2208, 0x0804, 0x35b0, 0x00f6,
+	0x00e6, 0x080c, 0x57e1, 0x2009, 0x0007, 0x1904, 0x51d7, 0x2071,
+	0x189e, 0x745c, 0x84ff, 0x2009, 0x000e, 0x1904, 0x51d7, 0xac9c,
+	0xad98, 0xaea4, 0xafa0, 0x0096, 0x080c, 0x1027, 0x2009, 0x0002,
+	0x0904, 0x51d7, 0x2900, 0x705e, 0x900e, 0x901e, 0x7356, 0x7362,
+	0xa860, 0x7066, 0xa85c, 0x9080, 0x0003, 0x705a, 0x20a0, 0x91d8,
+	0x1000, 0x2b5c, 0x8bff, 0x0178, 0x080c, 0x6a8c, 0x0118, 0x080c,
+	0x6a94, 0x1148, 0xb814, 0x20a9, 0x0001, 0x4004, 0xb810, 0x4004,
+	0x4104, 0x9398, 0x0003, 0x8108, 0x9182, 0x0800, 0x0120, 0x9386,
+	0x003c, 0x01e8, 0x0c20, 0x83ff, 0x11c0, 0x7254, 0x900e, 0x2001,
+	0x0003, 0x080c, 0x91ab, 0x2208, 0x009e, 0xa897, 0x4000, 0xa99a,
+	0x715c, 0x81ff, 0x090c, 0x0dc5, 0x2148, 0x080c, 0x1040, 0x9006,
+	0x705e, 0x918d, 0x0001, 0x2008, 0x0418, 0x7063, 0x0001, 0x7152,
+	0x7054, 0x9300, 0x7056, 0x2061, 0x18b9, 0x2c44, 0xa37a, 0x7058,
+	0xa076, 0x7064, 0xa072, 0xa48e, 0xa592, 0xa696, 0xa79a, 0xa09f,
+	0x51e3, 0x000e, 0xa0a2, 0x080c, 0x10f8, 0x9006, 0x0048, 0x009e,
+	0xa897, 0x4005, 0xa99a, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030,
+	0x00ee, 0x00fe, 0x0005, 0x00f6, 0xa0a0, 0x904d, 0x090c, 0x0dc5,
+	0x00e6, 0x2071, 0x189e, 0xa06c, 0x908e, 0x0100, 0x0138, 0xa87b,
+	0x0030, 0xa883, 0x0000, 0xa897, 0x4002, 0x00d8, 0x7060, 0x9005,
+	0x1158, 0x7150, 0x7058, 0x20a0, 0x901e, 0x7064, 0x20e8, 0xa48c,
+	0xa590, 0xa694, 0xa798, 0x0428, 0xa87b, 0x0000, 0xa883, 0x0000,
+	0xa897, 0x4000, 0x7254, 0x900e, 0x2001, 0x0003, 0x080c, 0x91ab,
+	0xaa9a, 0x715c, 0x81ff, 0x090c, 0x0dc5, 0x2148, 0x080c, 0x1040,
+	0x705f, 0x0000, 0xa0a0, 0x2048, 0x0126, 0x2091, 0x8000, 0x080c,
+	0x6dcb, 0x012e, 0xa09f, 0x0000, 0xa0a3, 0x0000, 0x00ee, 0x00fe,
+	0x0005, 0x91d8, 0x1000, 0x2b5c, 0x8bff, 0x0178, 0x080c, 0x6a8c,
+	0x0118, 0x080c, 0x6a94, 0x1148, 0xb814, 0x20a9, 0x0001, 0x4004,
+	0xb810, 0x4004, 0x4104, 0x9398, 0x0003, 0x8108, 0x9182, 0x0800,
+	0x0120, 0x9386, 0x003c, 0x0518, 0x0c20, 0x83ff, 0x11f0, 0x7154,
+	0x810c, 0xa99a, 0xa897, 0x4000, 0x715c, 0x81ff, 0x090c, 0x0dc5,
+	0x2148, 0x080c, 0x1040, 0x9006, 0x705e, 0x918d, 0x0001, 0x2008,
+	0xa0a0, 0x2048, 0x0126, 0x2091, 0x8000, 0x080c, 0x6dcb, 0x012e,
+	0xa09f, 0x0000, 0xa0a3, 0x0000, 0x0070, 0x7063, 0x0001, 0x7152,
+	0x7054, 0x9300, 0x7056, 0xa37a, 0xa48e, 0xa592, 0xa696, 0xa79a,
+	0x080c, 0x10f8, 0x9006, 0x00ee, 0x0005, 0x0096, 0xa88c, 0x90be,
+	0x7000, 0x0148, 0x90be, 0x7100, 0x0130, 0x90be, 0x7200, 0x0118,
+	0x009e, 0x0804, 0x35e5, 0xa884, 0xa988, 0x080c, 0x2889, 0x1518,
+	0x080c, 0x66ac, 0x1500, 0x7126, 0xbe12, 0xbd16, 0xae7c, 0x080c,
+	0x4b83, 0x01c8, 0x080c, 0x4b83, 0x01b0, 0x009e, 0xa867, 0x0000,
+	0xa868, 0xc0fd, 0xa86a, 0xa823, 0x0000, 0xa804, 0x2048, 0x080c,
+	0xcfeb, 0x1120, 0x2009, 0x0003, 0x0804, 0x35e2, 0x7007, 0x0003,
+	0x701f, 0x52b0, 0x0005, 0x009e, 0x2009, 0x0002, 0x0804, 0x35e2,
+	0x7124, 0x080c, 0x3347, 0xa820, 0x9086, 0x8001, 0x1120, 0x2009,
+	0x0004, 0x0804, 0x35e2, 0x2900, 0x7022, 0xa804, 0x0096, 0x2048,
+	0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x009e,
+	0x9080, 0x0002, 0x0076, 0x0006, 0x2098, 0x20a0, 0x27e0, 0x27e8,
+	0x20a9, 0x002a, 0x080c, 0x0f8b, 0xaa6c, 0xab70, 0xac74, 0xad78,
+	0x2061, 0x18b8, 0x2c44, 0xa06b, 0x0000, 0xae64, 0xaf8c, 0x97c6,
+	0x7000, 0x0118, 0x97c6, 0x7100, 0x1148, 0x96c2, 0x0004, 0x0600,
+	0x2009, 0x0004, 0x000e, 0x007e, 0x0804, 0x4bcf, 0x97c6, 0x7200,
+	0x11b8, 0x96c2, 0x0054, 0x02a0, 0x000e, 0x007e, 0x2061, 0x18b8,
+	0x2c44, 0xa076, 0xa772, 0xa07b, 0x002a, 0xa28e, 0xa392, 0xa496,
+	0xa59a, 0x080c, 0x10f8, 0x7007, 0x0002, 0x701f, 0x530c, 0x0005,
+	0x000e, 0x007e, 0x0804, 0x35e5, 0x7020, 0x2048, 0xa804, 0x2048,
+	0xa804, 0x2048, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084,
+	0xffc0, 0x9080, 0x0002, 0x2098, 0x20a0, 0x27e0, 0x27e8, 0x20a9,
+	0x002a, 0x080c, 0x0f8b, 0x2100, 0x2238, 0x2061, 0x18b8, 0x2c44,
+	0xa28c, 0xa390, 0xa494, 0xa598, 0x2009, 0x002a, 0x0804, 0x4bcf,
+	0x81ff, 0x1904, 0x35e2, 0x798c, 0x2001, 0x197f, 0x918c, 0x8000,
+	0x2102, 0x080c, 0x4b9a, 0x0904, 0x35e5, 0x080c, 0x6a8c, 0x0120,
+	0x080c, 0x6a94, 0x1904, 0x35e5, 0x080c, 0x67de, 0x0904, 0x35e2,
+	0x0126, 0x2091, 0x8000, 0x080c, 0x68a4, 0x012e, 0x0904, 0x35e2,
+	0x2001, 0x197f, 0x2004, 0xd0fc, 0x1904, 0x35b0, 0x0804, 0x45db,
+	0xa9a0, 0x2001, 0x197f, 0x918c, 0x8000, 0xc18d, 0x2102, 0x080c,
+	0x4ba7, 0x01a0, 0x080c, 0x6a8c, 0x0118, 0x080c, 0x6a94, 0x1170,
+	0x080c, 0x67de, 0x2009, 0x0002, 0x0128, 0x080c, 0x68a4, 0x1170,
+	0x2009, 0x0003, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006,
+	0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x0005, 0xa897, 0x4000,
+	0x2001, 0x197f, 0x2004, 0xd0fc, 0x1128, 0x080c, 0x57d5, 0x0110,
+	0x9006, 0x0018, 0x900e, 0x9085, 0x0001, 0x2001, 0x0000, 0x0005,
+	0x78a8, 0xd08c, 0x1118, 0xd084, 0x0904, 0x4550, 0x080c, 0x4bb6,
+	0x0904, 0x35e5, 0x080c, 0x4b83, 0x1120, 0x2009, 0x0002, 0x0804,
+	0x35e2, 0x080c, 0x6a8c, 0x0130, 0x908e, 0x0004, 0x0118, 0x908e,
+	0x0005, 0x15a0, 0x78a8, 0xd08c, 0x0120, 0xb800, 0xc08c, 0xb802,
+	0x0028, 0x080c, 0x57cd, 0xd0b4, 0x0904, 0x458a, 0x7884, 0x908e,
+	0x007e, 0x0904, 0x458a, 0x908e, 0x007f, 0x0904, 0x458a, 0x908e,
+	0x0080, 0x0904, 0x458a, 0xb800, 0xd08c, 0x1904, 0x458a, 0xa867,
+	0x0000, 0xa868, 0xc0fd, 0xa86a, 0x080c, 0xd00a, 0x1120, 0x2009,
+	0x0003, 0x0804, 0x35e2, 0x7007, 0x0003, 0x701f, 0x53d8, 0x0005,
+	0x080c, 0x4bb6, 0x0904, 0x35e5, 0x0804, 0x458a, 0x080c, 0x33a0,
+	0x0108, 0x0005, 0x2009, 0x1834, 0x210c, 0x81ff, 0x0120, 0x2009,
+	0x0001, 0x0804, 0x35e2, 0x080c, 0x57e1, 0x0120, 0x2009, 0x0007,
+	0x0804, 0x35e2, 0x080c, 0x6a84, 0x0120, 0x2009, 0x0008, 0x0804,
+	0x35e2, 0xb89c, 0xd0a4, 0x1118, 0xd0ac, 0x1904, 0x458a, 0x9006,
+	0xa866, 0xa832, 0xa868, 0xc0fd, 0xa86a, 0x080c, 0xd069, 0x1120,
+	0x2009, 0x0003, 0x0804, 0x35e2, 0x7007, 0x0003, 0x701f, 0x5411,
+	0x0005, 0xa830, 0x9086, 0x0100, 0x1120, 0x2009, 0x0004, 0x0804,
+	0x5721, 0x080c, 0x4bb6, 0x0904, 0x35e5, 0x0804, 0x53aa, 0x81ff,
+	0x2009, 0x0001, 0x1904, 0x35e2, 0x080c, 0x57e1, 0x2009, 0x0007,
+	0x1904, 0x35e2, 0x080c, 0x6a84, 0x0120, 0x2009, 0x0008, 0x0804,
+	0x35e2, 0x080c, 0x4bb6, 0x0904, 0x35e5, 0x080c, 0x6a8c, 0x2009,
+	0x0009, 0x1904, 0x35e2, 0x080c, 0x4b83, 0x2009, 0x0002, 0x0904,
+	0x35e2, 0x9006, 0xa866, 0xa832, 0xa868, 0xc0fd, 0xa86a, 0x7988,
+	0xa95a, 0x9194, 0xfd00, 0x918c, 0x00ff, 0x9006, 0x82ff, 0x1128,
 	0xc0ed, 0xa952, 0x798c, 0xa956, 0x0038, 0x928e, 0x0100, 0x1904,
-	0x35b8, 0xc0e5, 0xa952, 0xa956, 0xa83e, 0x080c, 0xd103, 0x2009,
-	0x0003, 0x0904, 0x35b5, 0x7007, 0x0003, 0x701f, 0x53f8, 0x0005,
-	0xa830, 0x9086, 0x0100, 0x2009, 0x0004, 0x0904, 0x35b5, 0x0804,
-	0x3583, 0x7aa8, 0x9284, 0xc000, 0x0148, 0xd2ec, 0x01a0, 0x080c,
-	0x5771, 0x1188, 0x2009, 0x0014, 0x0804, 0x35b5, 0xd2dc, 0x1578,
-	0x81ff, 0x2009, 0x0001, 0x1904, 0x35b5, 0x080c, 0x5771, 0x2009,
-	0x0007, 0x1904, 0x35b5, 0xd2f4, 0x0138, 0x9284, 0x5000, 0xc0d5,
-	0x080c, 0x5737, 0x0804, 0x3583, 0xd2fc, 0x0160, 0x080c, 0x4b52,
-	0x0904, 0x35b8, 0x7984, 0x9284, 0x9000, 0xc0d5, 0x080c, 0x570c,
-	0x0804, 0x3583, 0x080c, 0x4b52, 0x0904, 0x35b8, 0xb804, 0x9084,
-	0x00ff, 0x9086, 0x0006, 0x2009, 0x0009, 0x1904, 0x54e7, 0x080c,
-	0x4b1f, 0x2009, 0x0002, 0x0904, 0x54e7, 0xa85c, 0x9080, 0x001b,
+	0x35e5, 0xc0e5, 0xa952, 0xa956, 0xa83e, 0x080c, 0xd2bc, 0x2009,
+	0x0003, 0x0904, 0x35e2, 0x7007, 0x0003, 0x701f, 0x5468, 0x0005,
+	0xa830, 0x9086, 0x0100, 0x2009, 0x0004, 0x0904, 0x35e2, 0x0804,
+	0x35b0, 0x7aa8, 0x9284, 0xc000, 0x0148, 0xd2ec, 0x01a0, 0x080c,
+	0x57e1, 0x1188, 0x2009, 0x0014, 0x0804, 0x35e2, 0xd2dc, 0x1578,
+	0x81ff, 0x2009, 0x0001, 0x1904, 0x35e2, 0x080c, 0x57e1, 0x2009,
+	0x0007, 0x1904, 0x35e2, 0xd2f4, 0x0138, 0x9284, 0x5000, 0xc0d5,
+	0x080c, 0x57a7, 0x0804, 0x35b0, 0xd2fc, 0x0160, 0x080c, 0x4bb6,
+	0x0904, 0x35e5, 0x7984, 0x9284, 0x9000, 0xc0d5, 0x080c, 0x577c,
+	0x0804, 0x35b0, 0x080c, 0x4bb6, 0x0904, 0x35e5, 0xb804, 0x9084,
+	0x00ff, 0x9086, 0x0006, 0x2009, 0x0009, 0x1904, 0x5557, 0x080c,
+	0x4b83, 0x2009, 0x0002, 0x0904, 0x5557, 0xa85c, 0x9080, 0x001b,
 	0xaf60, 0x2009, 0x0008, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x080c,
-	0x4b68, 0x701f, 0x5454, 0x0005, 0xa86c, 0x9086, 0x0500, 0x1138,
+	0x4bcc, 0x701f, 0x54c4, 0x0005, 0xa86c, 0x9086, 0x0500, 0x1138,
 	0xa870, 0x9005, 0x1120, 0xa874, 0x9084, 0xff00, 0x0110, 0x1904,
-	0x35b8, 0xa866, 0xa832, 0xa868, 0xc0fd, 0xa86a, 0x080c, 0x4b52,
-	0x1110, 0x0804, 0x35b8, 0x2009, 0x0043, 0x080c, 0xd16b, 0x2009,
-	0x0003, 0x0904, 0x54e7, 0x7007, 0x0003, 0x701f, 0x5478, 0x0005,
-	0xa830, 0x9086, 0x0100, 0x2009, 0x0004, 0x0904, 0x54e7, 0x7984,
-	0x7aa8, 0x9284, 0x1000, 0xe085, 0x080c, 0x570c, 0x0804, 0x3583,
+	0x35e5, 0xa866, 0xa832, 0xa868, 0xc0fd, 0xa86a, 0x080c, 0x4bb6,
+	0x1110, 0x0804, 0x35e5, 0x2009, 0x0043, 0x080c, 0xd328, 0x2009,
+	0x0003, 0x0904, 0x5557, 0x7007, 0x0003, 0x701f, 0x54e8, 0x0005,
+	0xa830, 0x9086, 0x0100, 0x2009, 0x0004, 0x0904, 0x5557, 0x7984,
+	0x7aa8, 0x9284, 0x1000, 0xc0d5, 0x080c, 0x577c, 0x0804, 0x35b0,
 	0x00c6, 0xaab0, 0x9284, 0xc000, 0x0148, 0xd2ec, 0x0170, 0x080c,
-	0x5771, 0x1158, 0x2009, 0x0014, 0x0804, 0x54d6, 0x2061, 0x1800,
-	0x080c, 0x5771, 0x2009, 0x0007, 0x15c8, 0xd2f4, 0x0130, 0x9284,
-	0x5000, 0xc0d5, 0x080c, 0x5737, 0x0058, 0xd2fc, 0x0180, 0x080c,
-	0x4b50, 0x0590, 0xa998, 0x9284, 0x9000, 0xc0d5, 0x080c, 0x570c,
+	0x57e1, 0x1158, 0x2009, 0x0014, 0x0804, 0x5546, 0x2061, 0x1800,
+	0x080c, 0x57e1, 0x2009, 0x0007, 0x15c8, 0xd2f4, 0x0130, 0x9284,
+	0x5000, 0xc0d5, 0x080c, 0x57a7, 0x0058, 0xd2fc, 0x0180, 0x080c,
+	0x4bb4, 0x0590, 0xa998, 0x9284, 0x9000, 0xc0d5, 0x080c, 0x577c,
 	0xa87b, 0x0000, 0xa883, 0x0000, 0xa897, 0x4000, 0x0438, 0x080c,
-	0x4b50, 0x0510, 0x080c, 0x6a0c, 0x2009, 0x0009, 0x11b8, 0xa8c4,
+	0x4bb4, 0x0510, 0x080c, 0x6a8c, 0x2009, 0x0009, 0x11b8, 0xa8c4,
 	0x9086, 0x0500, 0x11c8, 0xa8c8, 0x9005, 0x11b0, 0xa8cc, 0x9084,
-	0xff00, 0x1190, 0x080c, 0x4b50, 0x1108, 0x0070, 0x2009, 0x004b,
-	0x080c, 0xd16b, 0x2009, 0x0003, 0x0108, 0x0078, 0x0431, 0x19c0,
+	0xff00, 0x1190, 0x080c, 0x4bb4, 0x1108, 0x0070, 0x2009, 0x004b,
+	0x080c, 0xd328, 0x2009, 0x0003, 0x0108, 0x0078, 0x0431, 0x19c0,
 	0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e, 0x9085,
 	0x0001, 0x2001, 0x0030, 0x00ce, 0x0005, 0x9006, 0x0ce0, 0x7aa8,
-	0xd2dc, 0x0904, 0x35b5, 0x0016, 0x7984, 0x9284, 0x1000, 0xc0fd,
-	0x080c, 0x570c, 0x001e, 0x1904, 0x35b5, 0x0804, 0x3583, 0x00f6,
+	0xd2dc, 0x0904, 0x35e2, 0x0016, 0x7984, 0x9284, 0x1000, 0xc0fd,
+	0x080c, 0x577c, 0x001e, 0x1904, 0x35e2, 0x0804, 0x35b0, 0x00f6,
 	0x2d78, 0xaab0, 0x0021, 0x00fe, 0x0005, 0xaab0, 0xc2d5, 0xd2dc,
-	0x0150, 0x0016, 0xa998, 0x9284, 0x1400, 0xc0fd, 0x080c, 0x570c,
+	0x0150, 0x0016, 0xa998, 0x9284, 0x1400, 0xc0fd, 0x080c, 0x577c,
 	0x001e, 0x9085, 0x0001, 0x0005, 0x81ff, 0x0120, 0x2009, 0x0001,
-	0x0804, 0x35b5, 0x080c, 0x5771, 0x0120, 0x2009, 0x0007, 0x0804,
-	0x35b5, 0x7984, 0x7ea8, 0x96b4, 0x00ff, 0x080c, 0x6699, 0x1904,
-	0x35b8, 0x9186, 0x007f, 0x0138, 0x080c, 0x6a0c, 0x0120, 0x2009,
-	0x0009, 0x0804, 0x35b5, 0x080c, 0x4b1f, 0x1120, 0x2009, 0x0002,
-	0x0804, 0x35b5, 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x2001,
-	0x0100, 0x8007, 0xa80a, 0x080c, 0xce6b, 0x1120, 0x2009, 0x0003,
-	0x0804, 0x35b5, 0x7007, 0x0003, 0x701f, 0x5547, 0x0005, 0xa808,
-	0x8007, 0x9086, 0x0100, 0x1120, 0x2009, 0x0004, 0x0804, 0x35b5,
+	0x0804, 0x35e2, 0x080c, 0x57e1, 0x0120, 0x2009, 0x0007, 0x0804,
+	0x35e2, 0x7984, 0x7ea8, 0x96b4, 0x00ff, 0x080c, 0x6717, 0x1904,
+	0x35e5, 0x9186, 0x007f, 0x0138, 0x080c, 0x6a8c, 0x0120, 0x2009,
+	0x0009, 0x0804, 0x35e2, 0x080c, 0x4b83, 0x1120, 0x2009, 0x0002,
+	0x0804, 0x35e2, 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x2001,
+	0x0100, 0x8007, 0xa80a, 0x080c, 0xd024, 0x1120, 0x2009, 0x0003,
+	0x0804, 0x35e2, 0x7007, 0x0003, 0x701f, 0x55b7, 0x0005, 0xa808,
+	0x8007, 0x9086, 0x0100, 0x1120, 0x2009, 0x0004, 0x0804, 0x35e2,
 	0xa8e0, 0xa866, 0xa810, 0x8007, 0x9084, 0x00ff, 0x800c, 0xa814,
 	0x8007, 0x9084, 0x00ff, 0x8004, 0x9080, 0x0002, 0x9108, 0x8906,
 	0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x0004,
-	0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x0804, 0x4b6b, 0x080c, 0x4b1f,
-	0x1120, 0x2009, 0x0002, 0x0804, 0x35b5, 0x7984, 0x9194, 0xff00,
-	0x918c, 0x00ff, 0x8217, 0x82ff, 0x1118, 0x7023, 0x19b2, 0x0040,
-	0x92c6, 0x0001, 0x1118, 0x7023, 0x19cc, 0x0010, 0x0804, 0x35b8,
+	0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x0804, 0x4bcf, 0x080c, 0x4b83,
+	0x1120, 0x2009, 0x0002, 0x0804, 0x35e2, 0x7984, 0x9194, 0xff00,
+	0x918c, 0x00ff, 0x8217, 0x82ff, 0x1118, 0x7023, 0x19b5, 0x0040,
+	0x92c6, 0x0001, 0x1118, 0x7023, 0x19cf, 0x0010, 0x0804, 0x35e5,
 	0x2009, 0x001a, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0xa85c, 0x9080,
-	0x0019, 0xaf60, 0x080c, 0x4b68, 0x701f, 0x5597, 0x0005, 0x2001,
+	0x0019, 0xaf60, 0x080c, 0x4bcc, 0x701f, 0x5607, 0x0005, 0x2001,
 	0x182e, 0x2003, 0x0001, 0xa85c, 0x9080, 0x0019, 0x2098, 0xa860,
 	0x20e0, 0x20a9, 0x001a, 0x7020, 0x20a0, 0x20e9, 0x0001, 0x4003,
-	0x0804, 0x3583, 0x080c, 0x4b1f, 0x1120, 0x2009, 0x0002, 0x0804,
-	0x35b5, 0x7984, 0x9194, 0xff00, 0x918c, 0x00ff, 0x8217, 0x82ff,
-	0x1118, 0x2099, 0x19b2, 0x0040, 0x92c6, 0x0001, 0x1118, 0x2099,
-	0x19cc, 0x0010, 0x0804, 0x35b8, 0xa85c, 0x9080, 0x0019, 0x20a0,
+	0x0804, 0x35b0, 0x080c, 0x4b83, 0x1120, 0x2009, 0x0002, 0x0804,
+	0x35e2, 0x7984, 0x9194, 0xff00, 0x918c, 0x00ff, 0x8217, 0x82ff,
+	0x1118, 0x2099, 0x19b5, 0x0040, 0x92c6, 0x0001, 0x1118, 0x2099,
+	0x19cf, 0x0010, 0x0804, 0x35e5, 0xa85c, 0x9080, 0x0019, 0x20a0,
 	0xa860, 0x20e8, 0x20a9, 0x001a, 0x20e1, 0x0001, 0x4003, 0x2009,
 	0x001a, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0xa85c, 0x9080, 0x0019,
-	0xaf60, 0x0804, 0x4b6b, 0x7884, 0x908a, 0x1000, 0x1a04, 0x35b8,
+	0xaf60, 0x0804, 0x4bcf, 0x7884, 0x908a, 0x1000, 0x1a04, 0x35e5,
 	0x0126, 0x2091, 0x8000, 0x8003, 0x800b, 0x810b, 0x9108, 0x00c6,
-	0x2061, 0x19f9, 0x6142, 0x00ce, 0x012e, 0x0804, 0x3583, 0x00c6,
-	0x080c, 0x743e, 0x1160, 0x080c, 0x7724, 0x080c, 0x60ad, 0x9085,
-	0x0001, 0x080c, 0x7485, 0x080c, 0x736a, 0x080c, 0x0dd5, 0x2061,
-	0x1800, 0x6030, 0xc09d, 0x6032, 0x080c, 0x5f6c, 0x00ce, 0x0005,
-	0x00c6, 0x2001, 0x1800, 0x2004, 0x908e, 0x0000, 0x0904, 0x35b5,
-	0x7884, 0x9005, 0x0188, 0x7888, 0x2061, 0x199b, 0x2c0c, 0x2062,
-	0x080c, 0x2c5e, 0x01a0, 0x080c, 0x2c66, 0x0188, 0x080c, 0x2c6e,
-	0x0170, 0x2162, 0x0804, 0x35b8, 0x2061, 0x0100, 0x6038, 0x9086,
+	0x2061, 0x19fc, 0x614a, 0x00ce, 0x012e, 0x0804, 0x35b0, 0x00c6,
+	0x080c, 0x7563, 0x1160, 0x080c, 0x7848, 0x080c, 0x6121, 0x9085,
+	0x0001, 0x080c, 0x75a7, 0x080c, 0x748f, 0x080c, 0x0dc5, 0x2061,
+	0x1800, 0x6030, 0xc09d, 0x6032, 0x080c, 0x5fe0, 0x00ce, 0x0005,
+	0x00c6, 0x2001, 0x1800, 0x2004, 0x908e, 0x0000, 0x0904, 0x35e2,
+	0x7884, 0x9005, 0x0188, 0x7888, 0x2061, 0x199d, 0x2c0c, 0x2062,
+	0x080c, 0x2c6b, 0x01a0, 0x080c, 0x2c73, 0x0188, 0x080c, 0x2c7b,
+	0x0170, 0x2162, 0x0804, 0x35e5, 0x2061, 0x0100, 0x6038, 0x9086,
 	0x0007, 0x1118, 0x2009, 0x0001, 0x0010, 0x2009, 0x0000, 0x7884,
 	0x9086, 0x0002, 0x1568, 0x2061, 0x0100, 0x6028, 0xc09c, 0x602a,
-	0x0026, 0x2011, 0x0003, 0x080c, 0xa722, 0x2011, 0x0002, 0x080c,
-	0xa72c, 0x002e, 0x080c, 0xa636, 0x0036, 0x901e, 0x080c, 0xa6ac,
-	0x003e, 0x60e3, 0x0000, 0x080c, 0xeb79, 0x080c, 0xeb94, 0x9085,
-	0x0001, 0x080c, 0x7485, 0x9006, 0x080c, 0x2d4e, 0x2001, 0x1800,
-	0x2003, 0x0004, 0x2001, 0x19a6, 0x2003, 0x0000, 0x6027, 0x0008,
-	0x00ce, 0x0804, 0x3583, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804,
-	0x35b5, 0x080c, 0x5771, 0x0120, 0x2009, 0x0007, 0x0804, 0x35b5,
-	0x7984, 0x7ea8, 0x96b4, 0x00ff, 0x080c, 0x6699, 0x1904, 0x35b8,
-	0x9186, 0x007f, 0x0138, 0x080c, 0x6a0c, 0x0120, 0x2009, 0x0009,
-	0x0804, 0x35b5, 0x080c, 0x4b1f, 0x1120, 0x2009, 0x0002, 0x0804,
-	0x35b5, 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x080c, 0xce6e,
-	0x1120, 0x2009, 0x0003, 0x0804, 0x35b5, 0x7007, 0x0003, 0x701f,
-	0x569a, 0x0005, 0xa830, 0x9086, 0x0100, 0x1120, 0x2009, 0x0004,
-	0x0804, 0x35b5, 0xa8e0, 0xa866, 0xa834, 0x8007, 0x800c, 0xa85c,
+	0x0026, 0x2011, 0x0003, 0x080c, 0xa8d3, 0x2011, 0x0002, 0x080c,
+	0xa8dd, 0x002e, 0x080c, 0xa7e7, 0x0036, 0x901e, 0x080c, 0xa85d,
+	0x003e, 0x60e3, 0x0000, 0x080c, 0xed95, 0x080c, 0xedb0, 0x9085,
+	0x0001, 0x080c, 0x75a7, 0x9006, 0x080c, 0x2d5b, 0x2001, 0x1800,
+	0x2003, 0x0004, 0x2001, 0x19a8, 0x2003, 0x0000, 0x6027, 0x0008,
+	0x00ce, 0x0804, 0x35b0, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804,
+	0x35e2, 0x080c, 0x57e1, 0x0120, 0x2009, 0x0007, 0x0804, 0x35e2,
+	0x7984, 0x7ea8, 0x96b4, 0x00ff, 0x080c, 0x6717, 0x1904, 0x35e5,
+	0x9186, 0x007f, 0x0138, 0x080c, 0x6a8c, 0x0120, 0x2009, 0x0009,
+	0x0804, 0x35e2, 0x080c, 0x4b83, 0x1120, 0x2009, 0x0002, 0x0804,
+	0x35e2, 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x080c, 0xd027,
+	0x1120, 0x2009, 0x0003, 0x0804, 0x35e2, 0x7007, 0x0003, 0x701f,
+	0x570a, 0x0005, 0xa830, 0x9086, 0x0100, 0x1120, 0x2009, 0x0004,
+	0x0804, 0x35e2, 0xa8e0, 0xa866, 0xa834, 0x8007, 0x800c, 0xa85c,
 	0x9080, 0x000c, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0xaf60, 0x0804,
-	0x4b6b, 0xa898, 0x9086, 0x000d, 0x1904, 0x35b5, 0x2021, 0x4005,
-	0x0126, 0x2091, 0x8000, 0x0e04, 0x56be, 0x0010, 0x012e, 0x0cc0,
+	0x4bcf, 0xa898, 0x9086, 0x000d, 0x1904, 0x35e2, 0x2021, 0x4005,
+	0x0126, 0x2091, 0x8000, 0x0e04, 0x572e, 0x0010, 0x012e, 0x0cc0,
 	0x7c36, 0x9486, 0x4000, 0x0118, 0x7833, 0x0011, 0x0010, 0x7833,
 	0x0010, 0x7883, 0x4005, 0xa998, 0x7986, 0xa9a4, 0x799a, 0xa9a8,
-	0x799e, 0x080c, 0x4b5b, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004,
-	0xd084, 0x190c, 0x119b, 0x7007, 0x0001, 0x2091, 0x5000, 0x700f,
+	0x799e, 0x080c, 0x4bbf, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004,
+	0xd084, 0x190c, 0x11aa, 0x7007, 0x0001, 0x2091, 0x5000, 0x700f,
 	0x0000, 0x012e, 0x0005, 0x0126, 0x2091, 0x8000, 0x00c6, 0x2061,
-	0x19f9, 0x7984, 0x6152, 0x614e, 0x6057, 0x0000, 0x604b, 0x0009,
-	0x7898, 0x606a, 0x789c, 0x6066, 0x7888, 0x6062, 0x788c, 0x605e,
-	0x2001, 0x1a07, 0x2044, 0x2001, 0x1a0e, 0xa076, 0xa060, 0xa072,
+	0x19fc, 0x7984, 0x615a, 0x6156, 0x605f, 0x0000, 0x6053, 0x0009,
+	0x7898, 0x6072, 0x789c, 0x606e, 0x7888, 0x606a, 0x788c, 0x6066,
+	0x2001, 0x1a0c, 0x2044, 0x2001, 0x1a13, 0xa076, 0xa060, 0xa072,
 	0xa07b, 0x0001, 0xa07f, 0x0002, 0xa06b, 0x0000, 0xa09f, 0x0000,
-	0x00ce, 0x012e, 0x0804, 0x3583, 0x0126, 0x2091, 0x8000, 0x00b6,
+	0x00ce, 0x012e, 0x0804, 0x35b0, 0x0126, 0x2091, 0x8000, 0x00b6,
 	0x00c6, 0x90e4, 0xc000, 0x0168, 0x0006, 0xd0d4, 0x0130, 0x0036,
-	0x2019, 0x0029, 0x080c, 0x3338, 0x003e, 0x080c, 0xccd3, 0x000e,
+	0x2019, 0x0029, 0x080c, 0x3365, 0x003e, 0x080c, 0xce8c, 0x000e,
 	0x1198, 0xd0e4, 0x0160, 0x9180, 0x1000, 0x2004, 0x905d, 0x0160,
-	0x080c, 0x60c7, 0x080c, 0xaead, 0x0110, 0xb817, 0x0000, 0x9006,
+	0x080c, 0x613b, 0x080c, 0xb051, 0x0110, 0xb817, 0x0000, 0x9006,
 	0x00ce, 0x00be, 0x012e, 0x0005, 0x9085, 0x0001, 0x0cc8, 0x0126,
 	0x2091, 0x8000, 0x0156, 0x2010, 0x900e, 0x20a9, 0x0800, 0x0016,
 	0x9180, 0x1000, 0x2004, 0x9005, 0x0188, 0x9186, 0x007e, 0x0170,
 	0x9186, 0x007f, 0x0158, 0x9186, 0x0080, 0x0140, 0x9186, 0x00ff,
-	0x0128, 0x0026, 0x2200, 0x080c, 0x570c, 0x002e, 0x001e, 0x8108,
-	0x1f04, 0x573f, 0x015e, 0x012e, 0x0005, 0x2001, 0x1848, 0x2004,
+	0x0128, 0x0026, 0x2200, 0x080c, 0x577c, 0x002e, 0x001e, 0x8108,
+	0x1f04, 0x57af, 0x015e, 0x012e, 0x0005, 0x2001, 0x1848, 0x2004,
 	0x0005, 0x2001, 0x1867, 0x2004, 0x0005, 0x0006, 0x2001, 0x1810,
 	0x2004, 0xd0d4, 0x000e, 0x0005, 0x2001, 0x180e, 0x2004, 0xd0b4,
 	0x0005, 0x2001, 0x1800, 0x2004, 0x9086, 0x0003, 0x0005, 0x0016,
 	0x00e6, 0x2071, 0x189e, 0x7108, 0x910d, 0x710a, 0x00ee, 0x001e,
-	0x0005, 0x79a4, 0x9182, 0x0081, 0x1a04, 0x35b8, 0x810c, 0x0016,
-	0x080c, 0x4b1f, 0x0170, 0x080c, 0x0f07, 0x2100, 0x2238, 0x7d84,
-	0x7c88, 0x7b8c, 0x7a90, 0x001e, 0x080c, 0x4b68, 0x701f, 0x579d,
-	0x0005, 0x2009, 0x0002, 0x0804, 0x35b5, 0x2079, 0x0000, 0x7d94,
-	0x7c98, 0x7ba8, 0x7aac, 0x79a4, 0x810c, 0x2061, 0x18b8, 0x2c44,
-	0xa770, 0xa074, 0x2071, 0x189e, 0x080c, 0x4b6b, 0x701f, 0x57b1,
-	0x0005, 0x2061, 0x18b8, 0x2c44, 0x0016, 0x0026, 0xa270, 0xa174,
-	0x080c, 0x0f0f, 0x002e, 0x001e, 0x080c, 0x0fbc, 0x9006, 0xa802,
-	0xa806, 0x0804, 0x3583, 0x0126, 0x0156, 0x0136, 0x0146, 0x01c6,
-	0x01d6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2061, 0x0100, 0x2069,
-	0x0200, 0x2071, 0x1800, 0x6044, 0xd0a4, 0x11e8, 0xd084, 0x0118,
-	0x080c, 0x596c, 0x0068, 0xd08c, 0x0118, 0x080c, 0x5875, 0x0040,
-	0xd094, 0x0118, 0x080c, 0x5845, 0x0018, 0xd09c, 0x0108, 0x0099,
-	0x00fe, 0x00ee, 0x00de, 0x00ce, 0x01de, 0x01ce, 0x014e, 0x013e,
-	0x015e, 0x012e, 0x0005, 0x0016, 0x6128, 0xd19c, 0x1110, 0xc19d,
-	0x612a, 0x001e, 0x0c68, 0x0006, 0x7098, 0x9005, 0x000e, 0x0120,
-	0x709b, 0x0000, 0x7093, 0x0000, 0x624c, 0x9286, 0xf0f0, 0x1150,
-	0x6048, 0x9086, 0xf0f0, 0x0130, 0x624a, 0x6043, 0x0090, 0x6043,
-	0x0010, 0x0490, 0x9294, 0xff00, 0x9296, 0xf700, 0x0178, 0x7138,
-	0xd1a4, 0x1160, 0x6240, 0x9295, 0x0100, 0x6242, 0x9294, 0x0010,
-	0x0128, 0x2009, 0x00f7, 0x080c, 0x6029, 0x00f0, 0x6040, 0x9084,
-	0x0010, 0x9085, 0x0140, 0x6042, 0x6043, 0x0000, 0x7087, 0x0000,
-	0x70a3, 0x0001, 0x70c7, 0x0000, 0x70df, 0x0000, 0x2009, 0x1c80,
-	0x200b, 0x0000, 0x7097, 0x0000, 0x708b, 0x000f, 0x2009, 0x000f,
-	0x2011, 0x5f0f, 0x080c, 0x8648, 0x0005, 0x2001, 0x1869, 0x2004,
-	0xd08c, 0x0110, 0x705f, 0xffff, 0x7088, 0x9005, 0x1528, 0x2011,
-	0x5f0f, 0x080c, 0x85b0, 0x6040, 0x9094, 0x0010, 0x9285, 0x0020,
-	0x6042, 0x20a9, 0x00c8, 0x6044, 0xd08c, 0x1168, 0x1f04, 0x585b,
-	0x6242, 0x709b, 0x0000, 0x6040, 0x9094, 0x0010, 0x9285, 0x0080,
-	0x6042, 0x6242, 0x0048, 0x6242, 0x709b, 0x0000, 0x708f, 0x0000,
-	0x9006, 0x080c, 0x60b2, 0x0000, 0x0005, 0x708c, 0x908a, 0x0003,
-	0x1a0c, 0x0dd5, 0x000b, 0x0005, 0x587f, 0x58d0, 0x596b, 0x00f6,
-	0x0016, 0x6900, 0x918c, 0x0800, 0x708f, 0x0001, 0x2001, 0x015d,
-	0x2003, 0x0000, 0x6803, 0x00fc, 0x20a9, 0x0004, 0x6800, 0x9084,
-	0x00fc, 0x0120, 0x1f04, 0x588e, 0x080c, 0x0dd5, 0x68a0, 0x68a2,
-	0x689c, 0x689e, 0x6898, 0x689a, 0xa001, 0x918d, 0x1600, 0x6902,
-	0x001e, 0x6837, 0x0020, 0x080c, 0x608e, 0x2079, 0x1c00, 0x7833,
-	0x1101, 0x7837, 0x0000, 0x20e1, 0x0001, 0x2099, 0x1805, 0x20e9,
-	0x0001, 0x20a1, 0x1c0e, 0x20a9, 0x0004, 0x4003, 0x080c, 0xabfe,
-	0x20e1, 0x0001, 0x2099, 0x1c00, 0x20e9, 0x0000, 0x20a1, 0x0240,
-	0x20a9, 0x0014, 0x4003, 0x60c3, 0x000c, 0x600f, 0x0000, 0x080c,
-	0x5f40, 0x00fe, 0x9006, 0x7092, 0x6043, 0x0008, 0x6042, 0x0005,
-	0x00f6, 0x7090, 0x7093, 0x0000, 0x9025, 0x0904, 0x5948, 0x6020,
-	0xd0b4, 0x1904, 0x5946, 0x71a0, 0x81ff, 0x0904, 0x5934, 0x9486,
-	0x000c, 0x1904, 0x5941, 0x9480, 0x0018, 0x8004, 0x20a8, 0x080c,
-	0x6087, 0x2011, 0x0260, 0x2019, 0x1c00, 0x220c, 0x2304, 0x9106,
-	0x11e8, 0x8210, 0x8318, 0x1f04, 0x58ed, 0x6043, 0x0004, 0x2061,
-	0x0140, 0x605b, 0xbc94, 0x605f, 0xf0f0, 0x2061, 0x0100, 0x6043,
-	0x0006, 0x708f, 0x0002, 0x709b, 0x0002, 0x2009, 0x07d0, 0x2011,
-	0x5f16, 0x080c, 0x8648, 0x080c, 0x608e, 0x04c0, 0x080c, 0x6087,
-	0x2079, 0x0260, 0x7930, 0x918e, 0x1101, 0x1558, 0x7834, 0x9005,
-	0x1540, 0x7900, 0x918c, 0x00ff, 0x1118, 0x7804, 0x9005, 0x0190,
-	0x080c, 0x6087, 0x2011, 0x026e, 0x2019, 0x1805, 0x20a9, 0x0004,
-	0x220c, 0x2304, 0x9102, 0x0230, 0x11a0, 0x8210, 0x8318, 0x1f04,
-	0x5928, 0x0078, 0x70a3, 0x0000, 0x080c, 0x6087, 0x20e1, 0x0000,
-	0x2099, 0x0260, 0x20e9, 0x0001, 0x20a1, 0x1c00, 0x20a9, 0x0014,
-	0x4003, 0x6043, 0x0008, 0x6043, 0x0000, 0x0010, 0x00fe, 0x0005,
-	0x6040, 0x9085, 0x0100, 0x6042, 0x6020, 0xd0b4, 0x1db8, 0x080c,
-	0xabfe, 0x20e1, 0x0001, 0x2099, 0x1c00, 0x20e9, 0x0000, 0x20a1,
-	0x0240, 0x20a9, 0x0014, 0x4003, 0x60c3, 0x000c, 0x2011, 0x19f0,
-	0x2013, 0x0000, 0x7093, 0x0000, 0x60a3, 0x0056, 0x60a7, 0x9575,
-	0x080c, 0xa34d, 0x08d8, 0x0005, 0x7098, 0x908a, 0x001d, 0x1a0c,
-	0x0dd5, 0x000b, 0x0005, 0x599d, 0x59b0, 0x59d9, 0x59f9, 0x5a1f,
-	0x5a4e, 0x5a74, 0x5aac, 0x5ad2, 0x5b00, 0x5b3b, 0x5b73, 0x5b91,
-	0x5bbc, 0x5bde, 0x5bf9, 0x5c03, 0x5c37, 0x5c5d, 0x5c8c, 0x5cb2,
-	0x5cea, 0x5d2e, 0x5d6b, 0x5d8c, 0x5de5, 0x5e07, 0x5e35, 0x5e35,
-	0x00c6, 0x2061, 0x1800, 0x6003, 0x0007, 0x2061, 0x0100, 0x6004,
-	0x9084, 0xfff9, 0x6006, 0x00ce, 0x0005, 0x2061, 0x0140, 0x605b,
-	0xbc94, 0x605f, 0xf0f0, 0x2061, 0x0100, 0x6043, 0x0002, 0x709b,
-	0x0001, 0x2009, 0x07d0, 0x2011, 0x5f16, 0x080c, 0x8648, 0x0005,
-	0x00f6, 0x7090, 0x9086, 0x0014, 0x1510, 0x6042, 0x6020, 0xd0b4,
-	0x11f0, 0x080c, 0x6087, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1102,
-	0x11a0, 0x7834, 0x9005, 0x1188, 0x7a38, 0xd2fc, 0x0128, 0x70c4,
-	0x9005, 0x1110, 0x70c7, 0x0001, 0x2011, 0x5f16, 0x080c, 0x85b0,
-	0x709b, 0x0010, 0x080c, 0x5c03, 0x0010, 0x7093, 0x0000, 0x00fe,
-	0x0005, 0x00f6, 0x709b, 0x0003, 0x6043, 0x0004, 0x2011, 0x5f16,
-	0x080c, 0x85b0, 0x080c, 0x600b, 0x2079, 0x0240, 0x7833, 0x1102,
-	0x7837, 0x0000, 0x20a9, 0x0008, 0x9f88, 0x000e, 0x200b, 0x0000,
-	0x8108, 0x1f04, 0x59ee, 0x60c3, 0x0014, 0x080c, 0x5f40, 0x00fe,
-	0x0005, 0x00f6, 0x7090, 0x9005, 0x0500, 0x2011, 0x5f16, 0x080c,
-	0x85b0, 0x9086, 0x0014, 0x11b8, 0x080c, 0x6087, 0x2079, 0x0260,
-	0x7a30, 0x9296, 0x1102, 0x1178, 0x7834, 0x9005, 0x1160, 0x7a38,
-	0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, 0x709b,
-	0x0004, 0x0029, 0x0010, 0x080c, 0x6063, 0x00fe, 0x0005, 0x00f6,
-	0x709b, 0x0005, 0x080c, 0x600b, 0x2079, 0x0240, 0x7833, 0x1103,
-	0x7837, 0x0000, 0x080c, 0x6087, 0x080c, 0x606a, 0x1170, 0x7084,
-	0x9005, 0x1158, 0x715c, 0x9186, 0xffff, 0x0138, 0x2011, 0x0008,
-	0x080c, 0x5ec3, 0x0168, 0x080c, 0x6040, 0x20a9, 0x0008, 0x20e1,
+	0x0005, 0x79a4, 0x81ff, 0x0904, 0x35e5, 0x9182, 0x0081, 0x1a04,
+	0x35e5, 0x810c, 0x0016, 0x080c, 0x4b83, 0x0170, 0x080c, 0x0f16,
+	0x2100, 0x2238, 0x7d84, 0x7c88, 0x7b8c, 0x7a90, 0x001e, 0x080c,
+	0x4bcc, 0x701f, 0x5811, 0x0005, 0x001e, 0x2009, 0x0002, 0x0804,
+	0x35e2, 0x2079, 0x0000, 0x7d94, 0x7c98, 0x7ba8, 0x7aac, 0x79a4,
+	0x810c, 0x2061, 0x18b8, 0x2c44, 0xa770, 0xa074, 0x2071, 0x189e,
+	0x080c, 0x4bcf, 0x701f, 0x5825, 0x0005, 0x2061, 0x18b8, 0x2c44,
+	0x0016, 0x0026, 0xa270, 0xa174, 0x080c, 0x0f1e, 0x002e, 0x001e,
+	0x080c, 0x0fcb, 0x9006, 0xa802, 0xa806, 0x0804, 0x35b0, 0x0126,
+	0x0156, 0x0136, 0x0146, 0x01c6, 0x01d6, 0x00c6, 0x00d6, 0x00e6,
+	0x00f6, 0x2061, 0x0100, 0x2069, 0x0200, 0x2071, 0x1800, 0x6044,
+	0xd0a4, 0x11e8, 0xd084, 0x0118, 0x080c, 0x59e0, 0x0068, 0xd08c,
+	0x0118, 0x080c, 0x58e9, 0x0040, 0xd094, 0x0118, 0x080c, 0x58b9,
+	0x0018, 0xd09c, 0x0108, 0x0099, 0x00fe, 0x00ee, 0x00de, 0x00ce,
+	0x01de, 0x01ce, 0x014e, 0x013e, 0x015e, 0x012e, 0x0005, 0x0016,
+	0x6128, 0xd19c, 0x1110, 0xc19d, 0x612a, 0x001e, 0x0c68, 0x0006,
+	0x7098, 0x9005, 0x000e, 0x0120, 0x709b, 0x0000, 0x7093, 0x0000,
+	0x624c, 0x9286, 0xf0f0, 0x1150, 0x6048, 0x9086, 0xf0f0, 0x0130,
+	0x624a, 0x6043, 0x0090, 0x6043, 0x0010, 0x0490, 0x9294, 0xff00,
+	0x9296, 0xf700, 0x0178, 0x7138, 0xd1a4, 0x1160, 0x6240, 0x9295,
+	0x0100, 0x6242, 0x9294, 0x0010, 0x0128, 0x2009, 0x00f7, 0x080c,
+	0x609d, 0x00f0, 0x6040, 0x9084, 0x0010, 0x9085, 0x0140, 0x6042,
+	0x6043, 0x0000, 0x7087, 0x0000, 0x70a3, 0x0001, 0x70c7, 0x0000,
+	0x70df, 0x0000, 0x2009, 0x1c80, 0x200b, 0x0000, 0x7097, 0x0000,
+	0x708b, 0x000f, 0x2009, 0x000f, 0x2011, 0x5f83, 0x080c, 0x879b,
+	0x0005, 0x2001, 0x1869, 0x2004, 0xd08c, 0x0110, 0x705f, 0xffff,
+	0x7088, 0x9005, 0x1528, 0x2011, 0x5f83, 0x080c, 0x8703, 0x6040,
+	0x9094, 0x0010, 0x9285, 0x0020, 0x6042, 0x20a9, 0x00c8, 0x6044,
+	0xd08c, 0x1168, 0x1f04, 0x58cf, 0x6242, 0x709b, 0x0000, 0x6040,
+	0x9094, 0x0010, 0x9285, 0x0080, 0x6042, 0x6242, 0x0048, 0x6242,
+	0x709b, 0x0000, 0x708f, 0x0000, 0x9006, 0x080c, 0x6126, 0x0000,
+	0x0005, 0x708c, 0x908a, 0x0003, 0x1a0c, 0x0dc5, 0x000b, 0x0005,
+	0x58f3, 0x5944, 0x59df, 0x00f6, 0x0016, 0x6900, 0x918c, 0x0800,
+	0x708f, 0x0001, 0x2001, 0x015d, 0x2003, 0x0000, 0x6803, 0x00fc,
+	0x20a9, 0x0004, 0x6800, 0x9084, 0x00fc, 0x0120, 0x1f04, 0x5902,
+	0x080c, 0x0dc5, 0x68a0, 0x68a2, 0x689c, 0x689e, 0x6898, 0x689a,
+	0xa001, 0x918d, 0x1600, 0x6902, 0x001e, 0x6837, 0x0020, 0x080c,
+	0x6102, 0x2079, 0x1c00, 0x7833, 0x1101, 0x7837, 0x0000, 0x20e1,
+	0x0001, 0x2099, 0x1805, 0x20e9, 0x0001, 0x20a1, 0x1c0e, 0x20a9,
+	0x0004, 0x4003, 0x080c, 0xada2, 0x20e1, 0x0001, 0x2099, 0x1c00,
+	0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, 0x0014, 0x4003, 0x60c3,
+	0x000c, 0x600f, 0x0000, 0x080c, 0x5fb4, 0x00fe, 0x9006, 0x7092,
+	0x6043, 0x0008, 0x6042, 0x0005, 0x00f6, 0x7090, 0x7093, 0x0000,
+	0x9025, 0x0904, 0x59bc, 0x6020, 0xd0b4, 0x1904, 0x59ba, 0x71a0,
+	0x81ff, 0x0904, 0x59a8, 0x9486, 0x000c, 0x1904, 0x59b5, 0x9480,
+	0x0018, 0x8004, 0x20a8, 0x080c, 0x60fb, 0x2011, 0x0260, 0x2019,
+	0x1c00, 0x220c, 0x2304, 0x9106, 0x11e8, 0x8210, 0x8318, 0x1f04,
+	0x5961, 0x6043, 0x0004, 0x2061, 0x0140, 0x605b, 0xbc94, 0x605f,
+	0xf0f0, 0x2061, 0x0100, 0x6043, 0x0006, 0x708f, 0x0002, 0x709b,
+	0x0002, 0x2009, 0x07d0, 0x2011, 0x5f8a, 0x080c, 0x879b, 0x080c,
+	0x6102, 0x04c0, 0x080c, 0x60fb, 0x2079, 0x0260, 0x7930, 0x918e,
+	0x1101, 0x1558, 0x7834, 0x9005, 0x1540, 0x7900, 0x918c, 0x00ff,
+	0x1118, 0x7804, 0x9005, 0x0190, 0x080c, 0x60fb, 0x2011, 0x026e,
+	0x2019, 0x1805, 0x20a9, 0x0004, 0x220c, 0x2304, 0x9102, 0x0230,
+	0x11a0, 0x8210, 0x8318, 0x1f04, 0x599c, 0x0078, 0x70a3, 0x0000,
+	0x080c, 0x60fb, 0x20e1, 0x0000, 0x2099, 0x0260, 0x20e9, 0x0001,
+	0x20a1, 0x1c00, 0x20a9, 0x0014, 0x4003, 0x6043, 0x0008, 0x6043,
+	0x0000, 0x0010, 0x00fe, 0x0005, 0x6040, 0x9085, 0x0100, 0x6042,
+	0x6020, 0xd0b4, 0x1db8, 0x080c, 0xada2, 0x20e1, 0x0001, 0x2099,
+	0x1c00, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, 0x0014, 0x4003,
+	0x60c3, 0x000c, 0x2011, 0x19f3, 0x2013, 0x0000, 0x7093, 0x0000,
+	0x60a3, 0x0056, 0x60a7, 0x9575, 0x080c, 0xa4f4, 0x08d8, 0x0005,
+	0x7098, 0x908a, 0x001d, 0x1a0c, 0x0dc5, 0x000b, 0x0005, 0x5a11,
+	0x5a24, 0x5a4d, 0x5a6d, 0x5a93, 0x5ac2, 0x5ae8, 0x5b20, 0x5b46,
+	0x5b74, 0x5baf, 0x5be7, 0x5c05, 0x5c30, 0x5c52, 0x5c6d, 0x5c77,
+	0x5cab, 0x5cd1, 0x5d00, 0x5d26, 0x5d5e, 0x5da2, 0x5ddf, 0x5e00,
+	0x5e59, 0x5e7b, 0x5ea9, 0x5ea9, 0x00c6, 0x2061, 0x1800, 0x6003,
+	0x0007, 0x2061, 0x0100, 0x6004, 0x9084, 0xfff9, 0x6006, 0x00ce,
+	0x0005, 0x2061, 0x0140, 0x605b, 0xbc94, 0x605f, 0xf0f0, 0x2061,
+	0x0100, 0x6043, 0x0002, 0x709b, 0x0001, 0x2009, 0x07d0, 0x2011,
+	0x5f8a, 0x080c, 0x879b, 0x0005, 0x00f6, 0x7090, 0x9086, 0x0014,
+	0x1510, 0x6042, 0x6020, 0xd0b4, 0x11f0, 0x080c, 0x60fb, 0x2079,
+	0x0260, 0x7a30, 0x9296, 0x1102, 0x11a0, 0x7834, 0x9005, 0x1188,
+	0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001,
+	0x2011, 0x5f8a, 0x080c, 0x8703, 0x709b, 0x0010, 0x080c, 0x5c77,
+	0x0010, 0x7093, 0x0000, 0x00fe, 0x0005, 0x00f6, 0x709b, 0x0003,
+	0x6043, 0x0004, 0x2011, 0x5f8a, 0x080c, 0x8703, 0x080c, 0x607f,
+	0x2079, 0x0240, 0x7833, 0x1102, 0x7837, 0x0000, 0x20a9, 0x0008,
+	0x9f88, 0x000e, 0x200b, 0x0000, 0x8108, 0x1f04, 0x5a62, 0x60c3,
+	0x0014, 0x080c, 0x5fb4, 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005,
+	0x0500, 0x2011, 0x5f8a, 0x080c, 0x8703, 0x9086, 0x0014, 0x11b8,
+	0x080c, 0x60fb, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1102, 0x1178,
+	0x7834, 0x9005, 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005,
+	0x1110, 0x70c7, 0x0001, 0x709b, 0x0004, 0x0029, 0x0010, 0x080c,
+	0x60d7, 0x00fe, 0x0005, 0x00f6, 0x709b, 0x0005, 0x080c, 0x607f,
+	0x2079, 0x0240, 0x7833, 0x1103, 0x7837, 0x0000, 0x080c, 0x60fb,
+	0x080c, 0x60de, 0x1170, 0x7084, 0x9005, 0x1158, 0x715c, 0x9186,
+	0xffff, 0x0138, 0x2011, 0x0008, 0x080c, 0x5f37, 0x0168, 0x080c,
+	0x60b4, 0x20a9, 0x0008, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9,
+	0x0000, 0x20a1, 0x024e, 0x4003, 0x60c3, 0x0014, 0x080c, 0x5fb4,
+	0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005, 0x0500, 0x2011, 0x5f8a,
+	0x080c, 0x8703, 0x9086, 0x0014, 0x11b8, 0x080c, 0x60fb, 0x2079,
+	0x0260, 0x7a30, 0x9296, 0x1103, 0x1178, 0x7834, 0x9005, 0x1160,
+	0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001,
+	0x709b, 0x0006, 0x0029, 0x0010, 0x080c, 0x60d7, 0x00fe, 0x0005,
+	0x00f6, 0x709b, 0x0007, 0x080c, 0x607f, 0x2079, 0x0240, 0x7833,
+	0x1104, 0x7837, 0x0000, 0x080c, 0x60fb, 0x080c, 0x60de, 0x11b8,
+	0x7084, 0x9005, 0x11a0, 0x7164, 0x9186, 0xffff, 0x0180, 0x9180,
+	0x33b1, 0x200d, 0x918c, 0xff00, 0x810f, 0x2011, 0x0008, 0x080c,
+	0x5f37, 0x0180, 0x080c, 0x50c9, 0x0110, 0x080c, 0x28f2, 0x20a9,
+	0x0008, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1,
+	0x024e, 0x4003, 0x60c3, 0x0014, 0x080c, 0x5fb4, 0x00fe, 0x0005,
+	0x00f6, 0x7090, 0x9005, 0x0500, 0x2011, 0x5f8a, 0x080c, 0x8703,
+	0x9086, 0x0014, 0x11b8, 0x080c, 0x60fb, 0x2079, 0x0260, 0x7a30,
+	0x9296, 0x1104, 0x1178, 0x7834, 0x9005, 0x1160, 0x7a38, 0xd2fc,
+	0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, 0x709b, 0x0008,
+	0x0029, 0x0010, 0x080c, 0x60d7, 0x00fe, 0x0005, 0x00f6, 0x709b,
+	0x0009, 0x080c, 0x607f, 0x2079, 0x0240, 0x7833, 0x1105, 0x7837,
+	0x0100, 0x080c, 0x60de, 0x1150, 0x7084, 0x9005, 0x1138, 0x080c,
+	0x5eaa, 0x1188, 0x9085, 0x0001, 0x080c, 0x28f2, 0x20a9, 0x0008,
+	0x080c, 0x60fb, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000,
+	0x20a1, 0x024e, 0x4003, 0x60c3, 0x0014, 0x080c, 0x5fb4, 0x0010,
+	0x080c, 0x5a04, 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005, 0x05a8,
+	0x2011, 0x5f8a, 0x080c, 0x8703, 0x9086, 0x0014, 0x1560, 0x080c,
+	0x60fb, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1105, 0x1520, 0x7834,
+	0x9084, 0x0100, 0x2011, 0x0100, 0x921e, 0x1160, 0x7a38, 0xd2fc,
+	0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, 0x709b, 0x000a,
+	0x00b1, 0x0098, 0x9005, 0x1178, 0x7a38, 0xd2fc, 0x0128, 0x70c4,
+	0x9005, 0x1110, 0x70c7, 0x0001, 0x7097, 0x0000, 0x709b, 0x000e,
+	0x080c, 0x5c52, 0x0010, 0x080c, 0x60d7, 0x00fe, 0x0005, 0x00f6,
+	0x709b, 0x000b, 0x2011, 0x1c0e, 0x20e9, 0x0001, 0x22a0, 0x20a9,
+	0x0040, 0x2019, 0xffff, 0x4304, 0x080c, 0x607f, 0x2079, 0x0240,
+	0x7833, 0x1106, 0x7837, 0x0000, 0x080c, 0x60de, 0x0118, 0x2013,
+	0x0000, 0x0020, 0x7060, 0x9085, 0x0100, 0x2012, 0x20a9, 0x0040,
+	0x2009, 0x024e, 0x2011, 0x1c0e, 0x220e, 0x8210, 0x8108, 0x9186,
+	0x0260, 0x1128, 0x6810, 0x8000, 0x6812, 0x2009, 0x0240, 0x1f04,
+	0x5bd4, 0x60c3, 0x0084, 0x080c, 0x5fb4, 0x00fe, 0x0005, 0x00f6,
+	0x7090, 0x9005, 0x01c0, 0x2011, 0x5f8a, 0x080c, 0x8703, 0x9086,
+	0x0084, 0x1178, 0x080c, 0x60fb, 0x2079, 0x0260, 0x7a30, 0x9296,
+	0x1106, 0x1138, 0x7834, 0x9005, 0x1120, 0x709b, 0x000c, 0x0029,
+	0x0010, 0x080c, 0x60d7, 0x00fe, 0x0005, 0x00f6, 0x709b, 0x000d,
+	0x080c, 0x607f, 0x2079, 0x0240, 0x7833, 0x1107, 0x7837, 0x0000,
+	0x080c, 0x60fb, 0x20a9, 0x0040, 0x2011, 0x026e, 0x2009, 0x024e,
+	0x220e, 0x8210, 0x8108, 0x9186, 0x0260, 0x1150, 0x6810, 0x8000,
+	0x6812, 0x2009, 0x0240, 0x6814, 0x8000, 0x6816, 0x2011, 0x0260,
+	0x1f04, 0x5c18, 0x60c3, 0x0084, 0x080c, 0x5fb4, 0x00fe, 0x0005,
+	0x00f6, 0x7090, 0x9005, 0x01e0, 0x2011, 0x5f8a, 0x080c, 0x8703,
+	0x9086, 0x0084, 0x1198, 0x080c, 0x60fb, 0x2079, 0x0260, 0x7a30,
+	0x9296, 0x1107, 0x1158, 0x7834, 0x9005, 0x1140, 0x7097, 0x0001,
+	0x080c, 0x6051, 0x709b, 0x000e, 0x0029, 0x0010, 0x080c, 0x60d7,
+	0x00fe, 0x0005, 0x918d, 0x0001, 0x080c, 0x6126, 0x709b, 0x000f,
+	0x7093, 0x0000, 0x2061, 0x0140, 0x605b, 0xbc85, 0x605f, 0xb5b5,
+	0x2061, 0x0100, 0x6043, 0x0005, 0x6043, 0x0004, 0x2009, 0x07d0,
+	0x2011, 0x5f8a, 0x080c, 0x86f7, 0x0005, 0x7090, 0x9005, 0x0130,
+	0x2011, 0x5f8a, 0x080c, 0x8703, 0x709b, 0x0000, 0x0005, 0x709b,
+	0x0011, 0x080c, 0xada2, 0x080c, 0x60fb, 0x20e1, 0x0000, 0x2099,
+	0x0260, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x7490, 0x9480, 0x0018,
+	0x9080, 0x0007, 0x9084, 0x03f8, 0x8004, 0x20a8, 0x4003, 0x080c,
+	0x60de, 0x11a0, 0x717c, 0x81ff, 0x0188, 0x900e, 0x7080, 0x9084,
+	0x00ff, 0x0160, 0x080c, 0x2889, 0x9186, 0x007e, 0x0138, 0x9186,
+	0x0080, 0x0120, 0x2011, 0x0008, 0x080c, 0x5f37, 0x60c3, 0x0014,
+	0x080c, 0x5fb4, 0x0005, 0x00f6, 0x7090, 0x9005, 0x0500, 0x2011,
+	0x5f8a, 0x080c, 0x8703, 0x9086, 0x0014, 0x11b8, 0x080c, 0x60fb,
+	0x2079, 0x0260, 0x7a30, 0x9296, 0x1103, 0x1178, 0x7834, 0x9005,
+	0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7,
+	0x0001, 0x709b, 0x0012, 0x0029, 0x0010, 0x7093, 0x0000, 0x00fe,
+	0x0005, 0x00f6, 0x709b, 0x0013, 0x080c, 0x608d, 0x2079, 0x0240,
+	0x7833, 0x1103, 0x7837, 0x0000, 0x080c, 0x60fb, 0x080c, 0x60de,
+	0x1170, 0x7084, 0x9005, 0x1158, 0x715c, 0x9186, 0xffff, 0x0138,
+	0x2011, 0x0008, 0x080c, 0x5f37, 0x0168, 0x080c, 0x60b4, 0x20a9,
+	0x0008, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1,
+	0x024e, 0x4003, 0x60c3, 0x0014, 0x080c, 0x5fb4, 0x00fe, 0x0005,
+	0x00f6, 0x7090, 0x9005, 0x0500, 0x2011, 0x5f8a, 0x080c, 0x8703,
+	0x9086, 0x0014, 0x11b8, 0x080c, 0x60fb, 0x2079, 0x0260, 0x7a30,
+	0x9296, 0x1104, 0x1178, 0x7834, 0x9005, 0x1160, 0x7a38, 0xd2fc,
+	0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, 0x709b, 0x0014,
+	0x0029, 0x0010, 0x7093, 0x0000, 0x00fe, 0x0005, 0x00f6, 0x709b,
+	0x0015, 0x080c, 0x608d, 0x2079, 0x0240, 0x7833, 0x1104, 0x7837,
+	0x0000, 0x080c, 0x60fb, 0x080c, 0x60de, 0x11b8, 0x7084, 0x9005,
+	0x11a0, 0x7164, 0x9186, 0xffff, 0x0180, 0x9180, 0x33b1, 0x200d,
+	0x918c, 0xff00, 0x810f, 0x2011, 0x0008, 0x080c, 0x5f37, 0x0180,
+	0x080c, 0x50c9, 0x0110, 0x080c, 0x28f2, 0x20a9, 0x0008, 0x20e1,
 	0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003,
-	0x60c3, 0x0014, 0x080c, 0x5f40, 0x00fe, 0x0005, 0x00f6, 0x7090,
-	0x9005, 0x0500, 0x2011, 0x5f16, 0x080c, 0x85b0, 0x9086, 0x0014,
-	0x11b8, 0x080c, 0x6087, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1103,
-	0x1178, 0x7834, 0x9005, 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c4,
-	0x9005, 0x1110, 0x70c7, 0x0001, 0x709b, 0x0006, 0x0029, 0x0010,
-	0x080c, 0x6063, 0x00fe, 0x0005, 0x00f6, 0x709b, 0x0007, 0x080c,
-	0x600b, 0x2079, 0x0240, 0x7833, 0x1104, 0x7837, 0x0000, 0x080c,
-	0x6087, 0x080c, 0x606a, 0x11b8, 0x7084, 0x9005, 0x11a0, 0x7164,
-	0x9186, 0xffff, 0x0180, 0x9180, 0x3384, 0x200d, 0x918c, 0xff00,
-	0x810f, 0x2011, 0x0008, 0x080c, 0x5ec3, 0x0180, 0x080c, 0x505a,
-	0x0110, 0x080c, 0x28e5, 0x20a9, 0x0008, 0x20e1, 0x0000, 0x2099,
-	0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003, 0x60c3, 0x0014,
-	0x080c, 0x5f40, 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005, 0x0500,
-	0x2011, 0x5f16, 0x080c, 0x85b0, 0x9086, 0x0014, 0x11b8, 0x080c,
-	0x6087, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1104, 0x1178, 0x7834,
-	0x9005, 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110,
-	0x70c7, 0x0001, 0x709b, 0x0008, 0x0029, 0x0010, 0x080c, 0x6063,
-	0x00fe, 0x0005, 0x00f6, 0x709b, 0x0009, 0x080c, 0x600b, 0x2079,
-	0x0240, 0x7833, 0x1105, 0x7837, 0x0100, 0x080c, 0x606a, 0x1150,
-	0x7084, 0x9005, 0x1138, 0x080c, 0x5e36, 0x1188, 0x9085, 0x0001,
-	0x080c, 0x28e5, 0x20a9, 0x0008, 0x080c, 0x6087, 0x20e1, 0x0000,
+	0x60c3, 0x0014, 0x080c, 0x5fb4, 0x00fe, 0x0005, 0x00f6, 0x7090,
+	0x9005, 0x05f0, 0x2011, 0x5f8a, 0x080c, 0x8703, 0x9086, 0x0014,
+	0x15a8, 0x080c, 0x60fb, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1105,
+	0x1568, 0x7834, 0x9084, 0x0100, 0x2011, 0x0100, 0x921e, 0x1168,
+	0x9085, 0x0001, 0x080c, 0x6126, 0x7a38, 0xd2fc, 0x0128, 0x70c4,
+	0x9005, 0x1110, 0x70c7, 0x0001, 0x0080, 0x9005, 0x11b8, 0x7a38,
+	0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, 0x9085,
+	0x0001, 0x080c, 0x6126, 0x7097, 0x0000, 0x7a38, 0xd2f4, 0x0110,
+	0x70df, 0x0008, 0x709b, 0x0016, 0x0029, 0x0010, 0x7093, 0x0000,
+	0x00fe, 0x0005, 0x080c, 0xada2, 0x080c, 0x60fb, 0x20e1, 0x0000,
+	0x2099, 0x0260, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, 0x000e,
+	0x4003, 0x2011, 0x026d, 0x2204, 0x9084, 0x0100, 0x2011, 0x024d,
+	0x2012, 0x2011, 0x026e, 0x709b, 0x0017, 0x080c, 0x60de, 0x1150,
+	0x7084, 0x9005, 0x1138, 0x080c, 0x5eaa, 0x1188, 0x9085, 0x0001,
+	0x080c, 0x28f2, 0x20a9, 0x0008, 0x080c, 0x60fb, 0x20e1, 0x0000,
 	0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003, 0x60c3,
-	0x0014, 0x080c, 0x5f40, 0x0010, 0x080c, 0x5990, 0x00fe, 0x0005,
-	0x00f6, 0x7090, 0x9005, 0x05a8, 0x2011, 0x5f16, 0x080c, 0x85b0,
-	0x9086, 0x0014, 0x1560, 0x080c, 0x6087, 0x2079, 0x0260, 0x7a30,
-	0x9296, 0x1105, 0x1520, 0x7834, 0x9084, 0x0100, 0x2011, 0x0100,
-	0x921e, 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110,
-	0x70c7, 0x0001, 0x709b, 0x000a, 0x00b1, 0x0098, 0x9005, 0x1178,
-	0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001,
-	0x7097, 0x0000, 0x709b, 0x000e, 0x080c, 0x5bde, 0x0010, 0x080c,
-	0x6063, 0x00fe, 0x0005, 0x00f6, 0x709b, 0x000b, 0x2011, 0x1c0e,
-	0x20e9, 0x0001, 0x22a0, 0x20a9, 0x0040, 0x2019, 0xffff, 0x4304,
-	0x080c, 0x600b, 0x2079, 0x0240, 0x7833, 0x1106, 0x7837, 0x0000,
-	0x080c, 0x606a, 0x0118, 0x2013, 0x0000, 0x0020, 0x7060, 0x9085,
-	0x0100, 0x2012, 0x20a9, 0x0040, 0x2009, 0x024e, 0x2011, 0x1c0e,
-	0x220e, 0x8210, 0x8108, 0x9186, 0x0260, 0x1128, 0x6810, 0x8000,
-	0x6812, 0x2009, 0x0240, 0x1f04, 0x5b60, 0x60c3, 0x0084, 0x080c,
-	0x5f40, 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005, 0x01c0, 0x2011,
-	0x5f16, 0x080c, 0x85b0, 0x9086, 0x0084, 0x1178, 0x080c, 0x6087,
-	0x2079, 0x0260, 0x7a30, 0x9296, 0x1106, 0x1138, 0x7834, 0x9005,
-	0x1120, 0x709b, 0x000c, 0x0029, 0x0010, 0x080c, 0x6063, 0x00fe,
-	0x0005, 0x00f6, 0x709b, 0x000d, 0x080c, 0x600b, 0x2079, 0x0240,
-	0x7833, 0x1107, 0x7837, 0x0000, 0x080c, 0x6087, 0x20a9, 0x0040,
-	0x2011, 0x026e, 0x2009, 0x024e, 0x220e, 0x8210, 0x8108, 0x9186,
-	0x0260, 0x1150, 0x6810, 0x8000, 0x6812, 0x2009, 0x0240, 0x6814,
-	0x8000, 0x6816, 0x2011, 0x0260, 0x1f04, 0x5ba4, 0x60c3, 0x0084,
-	0x080c, 0x5f40, 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005, 0x01e0,
-	0x2011, 0x5f16, 0x080c, 0x85b0, 0x9086, 0x0084, 0x1198, 0x080c,
-	0x6087, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1107, 0x1158, 0x7834,
-	0x9005, 0x1140, 0x7097, 0x0001, 0x080c, 0x5fdd, 0x709b, 0x000e,
-	0x0029, 0x0010, 0x080c, 0x6063, 0x00fe, 0x0005, 0x918d, 0x0001,
-	0x080c, 0x60b2, 0x709b, 0x000f, 0x7093, 0x0000, 0x2061, 0x0140,
-	0x605b, 0xbc85, 0x605f, 0xb5b5, 0x2061, 0x0100, 0x6043, 0x0005,
-	0x6043, 0x0004, 0x2009, 0x07d0, 0x2011, 0x5f16, 0x080c, 0x85a4,
-	0x0005, 0x7090, 0x9005, 0x0130, 0x2011, 0x5f16, 0x080c, 0x85b0,
-	0x709b, 0x0000, 0x0005, 0x709b, 0x0011, 0x080c, 0xabfe, 0x080c,
-	0x6087, 0x20e1, 0x0000, 0x2099, 0x0260, 0x20e9, 0x0000, 0x20a1,
+	0x0014, 0x080c, 0x5fb4, 0x0010, 0x080c, 0x5a04, 0x0005, 0x00f6,
+	0x7090, 0x9005, 0x01d8, 0x2011, 0x5f8a, 0x080c, 0x8703, 0x9086,
+	0x0084, 0x1190, 0x080c, 0x60fb, 0x2079, 0x0260, 0x7a30, 0x9296,
+	0x1106, 0x1150, 0x7834, 0x9005, 0x1138, 0x9006, 0x080c, 0x6126,
+	0x709b, 0x0018, 0x0029, 0x0010, 0x7093, 0x0000, 0x00fe, 0x0005,
+	0x00f6, 0x709b, 0x0019, 0x080c, 0x608d, 0x2079, 0x0240, 0x7833,
+	0x1106, 0x7837, 0x0000, 0x080c, 0x60fb, 0x2009, 0x026e, 0x2039,
+	0x1c0e, 0x20a9, 0x0040, 0x213e, 0x8738, 0x8108, 0x9186, 0x0280,
+	0x1128, 0x6814, 0x8000, 0x6816, 0x2009, 0x0260, 0x1f04, 0x5e13,
+	0x2039, 0x1c0e, 0x080c, 0x60de, 0x11e8, 0x2728, 0x2514, 0x8207,
+	0x9084, 0x00ff, 0x8000, 0x2018, 0x9294, 0x00ff, 0x8007, 0x9205,
+	0x202a, 0x7060, 0x2310, 0x8214, 0x92a0, 0x1c0e, 0x2414, 0x938c,
+	0x0001, 0x0118, 0x9294, 0xff00, 0x0018, 0x9294, 0x00ff, 0x8007,
+	0x9215, 0x2222, 0x20a9, 0x0040, 0x2009, 0x024e, 0x270e, 0x8738,
+	0x8108, 0x9186, 0x0260, 0x1128, 0x6810, 0x8000, 0x6812, 0x2009,
+	0x0240, 0x1f04, 0x5e46, 0x60c3, 0x0084, 0x080c, 0x5fb4, 0x00fe,
+	0x0005, 0x00f6, 0x7090, 0x9005, 0x01e0, 0x2011, 0x5f8a, 0x080c,
+	0x8703, 0x9086, 0x0084, 0x1198, 0x080c, 0x60fb, 0x2079, 0x0260,
+	0x7a30, 0x9296, 0x1107, 0x1158, 0x7834, 0x9005, 0x1140, 0x7097,
+	0x0001, 0x080c, 0x6051, 0x709b, 0x001a, 0x0029, 0x0010, 0x7093,
+	0x0000, 0x00fe, 0x0005, 0x9085, 0x0001, 0x080c, 0x6126, 0x709b,
+	0x001b, 0x080c, 0xada2, 0x080c, 0x60fb, 0x2011, 0x0260, 0x2009,
 	0x0240, 0x7490, 0x9480, 0x0018, 0x9080, 0x0007, 0x9084, 0x03f8,
-	0x8004, 0x20a8, 0x4003, 0x080c, 0x606a, 0x11a0, 0x717c, 0x81ff,
-	0x0188, 0x900e, 0x7080, 0x9084, 0x00ff, 0x0160, 0x080c, 0x287c,
-	0x9186, 0x007e, 0x0138, 0x9186, 0x0080, 0x0120, 0x2011, 0x0008,
-	0x080c, 0x5ec3, 0x60c3, 0x0014, 0x080c, 0x5f40, 0x0005, 0x00f6,
-	0x7090, 0x9005, 0x0500, 0x2011, 0x5f16, 0x080c, 0x85b0, 0x9086,
-	0x0014, 0x11b8, 0x080c, 0x6087, 0x2079, 0x0260, 0x7a30, 0x9296,
-	0x1103, 0x1178, 0x7834, 0x9005, 0x1160, 0x7a38, 0xd2fc, 0x0128,
-	0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, 0x709b, 0x0012, 0x0029,
-	0x0010, 0x7093, 0x0000, 0x00fe, 0x0005, 0x00f6, 0x709b, 0x0013,
-	0x080c, 0x6019, 0x2079, 0x0240, 0x7833, 0x1103, 0x7837, 0x0000,
-	0x080c, 0x6087, 0x080c, 0x606a, 0x1170, 0x7084, 0x9005, 0x1158,
-	0x715c, 0x9186, 0xffff, 0x0138, 0x2011, 0x0008, 0x080c, 0x5ec3,
-	0x0168, 0x080c, 0x6040, 0x20a9, 0x0008, 0x20e1, 0x0000, 0x2099,
-	0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003, 0x60c3, 0x0014,
-	0x080c, 0x5f40, 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005, 0x0500,
-	0x2011, 0x5f16, 0x080c, 0x85b0, 0x9086, 0x0014, 0x11b8, 0x080c,
-	0x6087, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1104, 0x1178, 0x7834,
-	0x9005, 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110,
-	0x70c7, 0x0001, 0x709b, 0x0014, 0x0029, 0x0010, 0x7093, 0x0000,
-	0x00fe, 0x0005, 0x00f6, 0x709b, 0x0015, 0x080c, 0x6019, 0x2079,
-	0x0240, 0x7833, 0x1104, 0x7837, 0x0000, 0x080c, 0x6087, 0x080c,
-	0x606a, 0x11b8, 0x7084, 0x9005, 0x11a0, 0x7164, 0x9186, 0xffff,
-	0x0180, 0x9180, 0x3384, 0x200d, 0x918c, 0xff00, 0x810f, 0x2011,
-	0x0008, 0x080c, 0x5ec3, 0x0180, 0x080c, 0x505a, 0x0110, 0x080c,
-	0x28e5, 0x20a9, 0x0008, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9,
-	0x0000, 0x20a1, 0x024e, 0x4003, 0x60c3, 0x0014, 0x080c, 0x5f40,
-	0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005, 0x05f0, 0x2011, 0x5f16,
-	0x080c, 0x85b0, 0x9086, 0x0014, 0x15a8, 0x080c, 0x6087, 0x2079,
-	0x0260, 0x7a30, 0x9296, 0x1105, 0x1568, 0x7834, 0x9084, 0x0100,
-	0x2011, 0x0100, 0x921e, 0x1168, 0x9085, 0x0001, 0x080c, 0x60b2,
-	0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001,
-	0x0080, 0x9005, 0x11b8, 0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005,
-	0x1110, 0x70c7, 0x0001, 0x9085, 0x0001, 0x080c, 0x60b2, 0x7097,
-	0x0000, 0x7a38, 0xd2f4, 0x0110, 0x70df, 0x0008, 0x709b, 0x0016,
-	0x0029, 0x0010, 0x7093, 0x0000, 0x00fe, 0x0005, 0x080c, 0xabfe,
-	0x080c, 0x6087, 0x20e1, 0x0000, 0x2099, 0x0260, 0x20e9, 0x0000,
-	0x20a1, 0x0240, 0x20a9, 0x000e, 0x4003, 0x2011, 0x026d, 0x2204,
-	0x9084, 0x0100, 0x2011, 0x024d, 0x2012, 0x2011, 0x026e, 0x709b,
-	0x0017, 0x080c, 0x606a, 0x1150, 0x7084, 0x9005, 0x1138, 0x080c,
-	0x5e36, 0x1188, 0x9085, 0x0001, 0x080c, 0x28e5, 0x20a9, 0x0008,
-	0x080c, 0x6087, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000,
-	0x20a1, 0x024e, 0x4003, 0x60c3, 0x0014, 0x080c, 0x5f40, 0x0010,
-	0x080c, 0x5990, 0x0005, 0x00f6, 0x7090, 0x9005, 0x01d8, 0x2011,
-	0x5f16, 0x080c, 0x85b0, 0x9086, 0x0084, 0x1190, 0x080c, 0x6087,
-	0x2079, 0x0260, 0x7a30, 0x9296, 0x1106, 0x1150, 0x7834, 0x9005,
-	0x1138, 0x9006, 0x080c, 0x60b2, 0x709b, 0x0018, 0x0029, 0x0010,
-	0x7093, 0x0000, 0x00fe, 0x0005, 0x00f6, 0x709b, 0x0019, 0x080c,
-	0x6019, 0x2079, 0x0240, 0x7833, 0x1106, 0x7837, 0x0000, 0x080c,
-	0x6087, 0x2009, 0x026e, 0x2039, 0x1c0e, 0x20a9, 0x0040, 0x213e,
-	0x8738, 0x8108, 0x9186, 0x0280, 0x1128, 0x6814, 0x8000, 0x6816,
-	0x2009, 0x0260, 0x1f04, 0x5d9f, 0x2039, 0x1c0e, 0x080c, 0x606a,
-	0x11e8, 0x2728, 0x2514, 0x8207, 0x9084, 0x00ff, 0x8000, 0x2018,
-	0x9294, 0x00ff, 0x8007, 0x9205, 0x202a, 0x7060, 0x2310, 0x8214,
-	0x92a0, 0x1c0e, 0x2414, 0x938c, 0x0001, 0x0118, 0x9294, 0xff00,
-	0x0018, 0x9294, 0x00ff, 0x8007, 0x9215, 0x2222, 0x20a9, 0x0040,
-	0x2009, 0x024e, 0x270e, 0x8738, 0x8108, 0x9186, 0x0260, 0x1128,
-	0x6810, 0x8000, 0x6812, 0x2009, 0x0240, 0x1f04, 0x5dd2, 0x60c3,
-	0x0084, 0x080c, 0x5f40, 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005,
-	0x01e0, 0x2011, 0x5f16, 0x080c, 0x85b0, 0x9086, 0x0084, 0x1198,
-	0x080c, 0x6087, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1107, 0x1158,
-	0x7834, 0x9005, 0x1140, 0x7097, 0x0001, 0x080c, 0x5fdd, 0x709b,
-	0x001a, 0x0029, 0x0010, 0x7093, 0x0000, 0x00fe, 0x0005, 0x9085,
-	0x0001, 0x080c, 0x60b2, 0x709b, 0x001b, 0x080c, 0xabfe, 0x080c,
-	0x6087, 0x2011, 0x0260, 0x2009, 0x0240, 0x7490, 0x9480, 0x0018,
-	0x9080, 0x0007, 0x9084, 0x03f8, 0x8004, 0x20a8, 0x220e, 0x8210,
-	0x8108, 0x9186, 0x0260, 0x1150, 0x6810, 0x8000, 0x6812, 0x2009,
-	0x0240, 0x6814, 0x8000, 0x6816, 0x2011, 0x0260, 0x1f04, 0x5e1e,
-	0x60c3, 0x0084, 0x080c, 0x5f40, 0x0005, 0x0005, 0x0086, 0x0096,
-	0x2029, 0x1848, 0x252c, 0x20a9, 0x0008, 0x2041, 0x1c0e, 0x20e9,
-	0x0001, 0x28a0, 0x080c, 0x6087, 0x20e1, 0x0000, 0x2099, 0x026e,
-	0x4003, 0x20a9, 0x0008, 0x2011, 0x0007, 0xd5d4, 0x0108, 0x9016,
-	0x2800, 0x9200, 0x200c, 0x91a6, 0xffff, 0x1148, 0xd5d4, 0x0110,
-	0x8210, 0x0008, 0x8211, 0x1f04, 0x5e50, 0x0804, 0x5ebf, 0x82ff,
-	0x1160, 0xd5d4, 0x0120, 0x91a6, 0x3fff, 0x0d90, 0x0020, 0x91a6,
-	0x3fff, 0x0904, 0x5ebf, 0x918d, 0xc000, 0x20a9, 0x0010, 0x2019,
-	0x0001, 0xd5d4, 0x0110, 0x2019, 0x0010, 0x2120, 0xd5d4, 0x0110,
-	0x8423, 0x0008, 0x8424, 0x1240, 0xd5d4, 0x0110, 0x8319, 0x0008,
-	0x8318, 0x1f04, 0x5e76, 0x04d8, 0x23a8, 0x2021, 0x0001, 0x8426,
-	0x8425, 0x1f04, 0x5e88, 0x2328, 0x8529, 0x92be, 0x0007, 0x0158,
-	0x0006, 0x2039, 0x0007, 0x2200, 0x973a, 0x000e, 0x27a8, 0x95a8,
-	0x0010, 0x1f04, 0x5e97, 0x755e, 0x95c8, 0x3384, 0x292d, 0x95ac,
-	0x00ff, 0x7582, 0x6532, 0x6536, 0x0016, 0x2508, 0x080c, 0x28c5,
-	0x001e, 0x60e7, 0x0000, 0x65ea, 0x2018, 0x2304, 0x9405, 0x201a,
-	0x7087, 0x0001, 0x20e9, 0x0000, 0x20a1, 0x024e, 0x20e1, 0x0001,
-	0x2898, 0x20a9, 0x0008, 0x4003, 0x9085, 0x0001, 0x0008, 0x9006,
-	0x009e, 0x008e, 0x0005, 0x0156, 0x01c6, 0x01d6, 0x0136, 0x0146,
-	0x22a8, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, 0x2011,
-	0x024e, 0x22a0, 0x4003, 0x014e, 0x013e, 0x01de, 0x01ce, 0x015e,
-	0x2118, 0x9026, 0x2001, 0x0007, 0x939a, 0x0010, 0x0218, 0x8420,
-	0x8001, 0x0cd0, 0x2118, 0x84ff, 0x0120, 0x939a, 0x0010, 0x8421,
-	0x1de0, 0x2021, 0x0001, 0x83ff, 0x0118, 0x8423, 0x8319, 0x1de8,
-	0x9238, 0x2029, 0x026e, 0x9528, 0x2504, 0x942c, 0x11b8, 0x9405,
-	0x203a, 0x715e, 0x91a0, 0x3384, 0x242d, 0x95ac, 0x00ff, 0x7582,
-	0x6532, 0x6536, 0x0016, 0x2508, 0x080c, 0x28c5, 0x001e, 0x60e7,
-	0x0000, 0x65ea, 0x7087, 0x0001, 0x9084, 0x0000, 0x0005, 0x00e6,
-	0x2071, 0x1800, 0x708b, 0x0000, 0x00ee, 0x0005, 0x00e6, 0x00f6,
-	0x2079, 0x0100, 0x2071, 0x0140, 0x080c, 0x5fcc, 0x080c, 0xa356,
-	0x7004, 0x9084, 0x4000, 0x0110, 0x080c, 0x2d5e, 0x0126, 0x2091,
-	0x8000, 0x2071, 0x1826, 0x2073, 0x0000, 0x7840, 0x0026, 0x0016,
-	0x2009, 0x00f7, 0x080c, 0x6029, 0x001e, 0x9094, 0x0010, 0x9285,
-	0x0080, 0x7842, 0x7a42, 0x002e, 0x012e, 0x00fe, 0x00ee, 0x0005,
-	0x0126, 0x2091, 0x8000, 0x080c, 0x2be3, 0x0228, 0x2011, 0x0101,
-	0x2204, 0xc0c5, 0x2012, 0x2011, 0x19f0, 0x2013, 0x0000, 0x7093,
-	0x0000, 0x012e, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x080c, 0xa34d,
-	0x6144, 0xd184, 0x0120, 0x7198, 0x918d, 0x2000, 0x0018, 0x718c,
-	0x918d, 0x1000, 0x2011, 0x1998, 0x2112, 0x2009, 0x07d0, 0x2011,
-	0x5f16, 0x080c, 0x8648, 0x0005, 0x0016, 0x0026, 0x00c6, 0x0126,
-	0x2091, 0x8000, 0x080c, 0xaeb4, 0x2009, 0x00f7, 0x080c, 0x6029,
-	0x2061, 0x19f9, 0x900e, 0x611a, 0x611e, 0x6172, 0x6176, 0x2061,
-	0x1800, 0x6003, 0x0001, 0x2061, 0x0100, 0x6043, 0x0090, 0x6043,
-	0x0010, 0x2009, 0x1998, 0x200b, 0x0000, 0x2009, 0x002d, 0x2011,
-	0x5f98, 0x080c, 0x85a4, 0x012e, 0x00ce, 0x002e, 0x001e, 0x0005,
-	0x00e6, 0x0006, 0x0126, 0x2091, 0x8000, 0x0471, 0x2071, 0x0100,
-	0x080c, 0xa356, 0x2071, 0x0140, 0x7004, 0x9084, 0x4000, 0x0110,
-	0x080c, 0x2d5e, 0x080c, 0x7446, 0x0188, 0x080c, 0x7461, 0x1170,
-	0x080c, 0x772e, 0x0016, 0x080c, 0x2994, 0x2001, 0x196c, 0x2102,
-	0x001e, 0x080c, 0x7729, 0x080c, 0x736a, 0x0050, 0x2009, 0x0001,
-	0x080c, 0x2c7c, 0x2001, 0x0001, 0x080c, 0x2828, 0x080c, 0x5f6c,
-	0x012e, 0x000e, 0x00ee, 0x0005, 0x2001, 0x180e, 0x2004, 0xd0bc,
-	0x0158, 0x0026, 0x0036, 0x2011, 0x8017, 0x2001, 0x1998, 0x201c,
-	0x080c, 0x4b7f, 0x003e, 0x002e, 0x0005, 0x20a9, 0x0012, 0x20e9,
-	0x0001, 0x20a1, 0x1c80, 0x080c, 0x6087, 0x20e9, 0x0000, 0x2099,
-	0x026e, 0x0099, 0x20a9, 0x0020, 0x080c, 0x6081, 0x2099, 0x0260,
-	0x20a1, 0x1c92, 0x0051, 0x20a9, 0x000e, 0x080c, 0x6084, 0x2099,
-	0x0260, 0x20a1, 0x1cb2, 0x0009, 0x0005, 0x0016, 0x0026, 0x3410,
-	0x3308, 0x2104, 0x8007, 0x2012, 0x8108, 0x8210, 0x1f04, 0x6001,
-	0x002e, 0x001e, 0x0005, 0x080c, 0xabfe, 0x20e1, 0x0001, 0x2099,
-	0x1c00, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, 0x000c, 0x4003,
-	0x0005, 0x080c, 0xabfe, 0x080c, 0x6087, 0x20e1, 0x0000, 0x2099,
-	0x0260, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, 0x000c, 0x4003,
-	0x0005, 0x00c6, 0x0006, 0x2061, 0x0100, 0x810f, 0x2001, 0x1834,
-	0x2004, 0x9005, 0x1138, 0x2001, 0x1818, 0x2004, 0x9084, 0x00ff,
-	0x9105, 0x0010, 0x9185, 0x00f7, 0x604a, 0x000e, 0x00ce, 0x0005,
-	0x0016, 0x0046, 0x080c, 0x6a08, 0x0158, 0x9006, 0x2020, 0x2009,
-	0x002a, 0x080c, 0xe73a, 0x2001, 0x180c, 0x200c, 0xc195, 0x2102,
-	0x2019, 0x002a, 0x900e, 0x080c, 0x31e9, 0x080c, 0xd388, 0x0140,
-	0x0036, 0x2019, 0xffff, 0x2021, 0x0007, 0x080c, 0x4d36, 0x003e,
-	0x004e, 0x001e, 0x0005, 0x080c, 0x5f6c, 0x709b, 0x0000, 0x7093,
-	0x0000, 0x0005, 0x0006, 0x2001, 0x180c, 0x2004, 0xd09c, 0x0100,
-	0x000e, 0x0005, 0x0006, 0x0016, 0x0126, 0x2091, 0x8000, 0x2001,
-	0x0101, 0x200c, 0x918d, 0x0006, 0x2102, 0x012e, 0x001e, 0x000e,
-	0x0005, 0x2009, 0x0001, 0x0020, 0x2009, 0x0002, 0x0008, 0x900e,
-	0x6814, 0x9084, 0xffc0, 0x910d, 0x6916, 0x0005, 0x00f6, 0x0156,
-	0x0146, 0x01d6, 0x9006, 0x20a9, 0x0080, 0x20e9, 0x0001, 0x20a1,
-	0x1c00, 0x4004, 0x2079, 0x1c00, 0x7803, 0x2200, 0x7807, 0x00ef,
-	0x780f, 0x00ef, 0x7813, 0x0138, 0x7823, 0xffff, 0x7827, 0xffff,
-	0x01de, 0x014e, 0x015e, 0x00fe, 0x0005, 0x2001, 0x1800, 0x2003,
-	0x0001, 0x0005, 0x2001, 0x19a5, 0x0118, 0x2003, 0x0001, 0x0010,
-	0x2003, 0x0000, 0x0005, 0x0156, 0x20a9, 0x0800, 0x2009, 0x1000,
-	0x9006, 0x200a, 0x8108, 0x1f04, 0x60c1, 0x015e, 0x0005, 0x00d6,
-	0x0036, 0x0156, 0x0136, 0x0146, 0x2069, 0x1847, 0x9006, 0xb802,
-	0xb8ce, 0xb807, 0x0707, 0xb80a, 0xb80e, 0xb812, 0x9198, 0x3384,
-	0x231d, 0x939c, 0x00ff, 0xbb16, 0x0016, 0x0026, 0xb8c2, 0x080c,
-	0xaead, 0x1120, 0x9192, 0x007e, 0x1208, 0xbbc2, 0x20a9, 0x0004,
-	0xb8c4, 0x20e8, 0xb9c8, 0x9198, 0x0006, 0x9006, 0x23a0, 0x4004,
-	0x20a9, 0x0004, 0x9198, 0x000a, 0x23a0, 0x4004, 0x002e, 0x001e,
-	0xb83e, 0xb842, 0xb84e, 0xb852, 0xb856, 0xb85a, 0xb85e, 0xb862,
-	0xb866, 0xb86a, 0xb86f, 0x0100, 0xb872, 0xb876, 0xb87a, 0xb88a,
-	0xb88e, 0xb893, 0x0008, 0xb896, 0xb89a, 0xb89e, 0xb8be, 0xb9a2,
-	0x0096, 0xb8a4, 0x904d, 0x0110, 0x080c, 0x1031, 0xb8a7, 0x0000,
-	0x009e, 0x9006, 0xb84a, 0x6810, 0xb83a, 0x680c, 0xb846, 0xb8bb,
-	0x0520, 0xb8ac, 0x9005, 0x0198, 0x00c6, 0x2060, 0x9c82, 0x1cd0,
-	0x0a0c, 0x0dd5, 0x2001, 0x181a, 0x2004, 0x9c02, 0x1a0c, 0x0dd5,
-	0x080c, 0x8a3d, 0x00ce, 0x090c, 0x8dda, 0xb8af, 0x0000, 0x6814,
-	0x9084, 0x00ff, 0xb842, 0x014e, 0x013e, 0x015e, 0x003e, 0x00de,
-	0x0005, 0x0126, 0x2091, 0x8000, 0xa974, 0xae78, 0x9684, 0x3fff,
-	0x9082, 0x4000, 0x1a04, 0x61af, 0x9182, 0x0800, 0x1a04, 0x61b3,
-	0x2001, 0x180c, 0x2004, 0x9084, 0x0003, 0x1904, 0x61b9, 0x9188,
-	0x1000, 0x2104, 0x905d, 0x0518, 0xb804, 0x9084, 0x00ff, 0x908e,
-	0x0006, 0x1508, 0xb8a4, 0x900d, 0x1904, 0x61cb, 0xb850, 0x900d,
-	0x1148, 0xa802, 0x2900, 0xb852, 0xb84e, 0x080c, 0x91ce, 0x9006,
-	0x012e, 0x0005, 0x00a6, 0x2150, 0x2900, 0xb002, 0xa803, 0x0000,
-	0x00ae, 0xb852, 0x0c90, 0x2001, 0x0005, 0x900e, 0x04b8, 0x2001,
-	0x0028, 0x900e, 0x0498, 0x9082, 0x0006, 0x1290, 0x080c, 0xaead,
-	0x1160, 0xb8a0, 0x9084, 0xff80, 0x1140, 0xb900, 0xd1fc, 0x0990,
-	0x2001, 0x0029, 0x2009, 0x1000, 0x0408, 0x2001, 0x0028, 0x00a8,
-	0x2009, 0x180c, 0x210c, 0xd18c, 0x0118, 0x2001, 0x0004, 0x0068,
-	0xd184, 0x0118, 0x2001, 0x0004, 0x0040, 0x2001, 0x0029, 0xb900,
-	0xd1fc, 0x0118, 0x2009, 0x1000, 0x0048, 0x900e, 0x0038, 0x2001,
-	0x0029, 0x900e, 0x0018, 0x2001, 0x0029, 0x900e, 0x9005, 0x012e,
-	0x0005, 0x2001, 0x180c, 0x2004, 0xd084, 0x19d0, 0x9188, 0x1000,
-	0x2104, 0x905d, 0x09a8, 0x080c, 0x6a0c, 0x1990, 0xb800, 0xd0bc,
-	0x0978, 0x0804, 0x6162, 0x080c, 0x6835, 0x0904, 0x617b, 0x0804,
-	0x6166, 0x00b6, 0x00e6, 0x0126, 0x2091, 0x8000, 0xa874, 0x908e,
-	0x00ff, 0x1120, 0x2001, 0x196a, 0x205c, 0x0060, 0xa974, 0x9182,
-	0x0800, 0x1690, 0x9188, 0x1000, 0x2104, 0x905d, 0x01d0, 0x080c,
-	0x69ac, 0x11d0, 0x080c, 0xaeed, 0x0570, 0x2b00, 0x6012, 0x2900,
-	0x6016, 0x6023, 0x0009, 0x600b, 0x0000, 0xa874, 0x908e, 0x00ff,
-	0x1110, 0x600b, 0x8000, 0x2009, 0x0043, 0x080c, 0xafbe, 0x9006,
-	0x00b0, 0x2001, 0x0028, 0x0090, 0x2009, 0x180c, 0x210c, 0xd18c,
-	0x0118, 0x2001, 0x0004, 0x0038, 0xd184, 0x0118, 0x2001, 0x0004,
-	0x0010, 0x2001, 0x0029, 0x0010, 0x2001, 0x0029, 0x9005, 0x012e,
-	0x00ee, 0x00be, 0x0005, 0x2001, 0x002c, 0x0cc0, 0x00b6, 0x00e6,
-	0x0126, 0x2091, 0x8000, 0xa974, 0x9182, 0x0800, 0x1a04, 0x629c,
-	0x9188, 0x1000, 0x2104, 0x905d, 0x0904, 0x6274, 0xb8a0, 0x9086,
-	0x007f, 0x0190, 0xa87c, 0xd0fc, 0x1178, 0x080c, 0x6a14, 0x0160,
-	0xa994, 0x81ff, 0x0130, 0x908e, 0x0004, 0x0130, 0x908e, 0x0005,
-	0x0118, 0x080c, 0x6a0c, 0x1598, 0xa87c, 0xd0fc, 0x01e0, 0xa894,
-	0x9005, 0x01c8, 0x2060, 0x0026, 0x2010, 0x080c, 0xcc74, 0x002e,
-	0x1120, 0x2001, 0x0008, 0x0804, 0x629e, 0x6020, 0x9086, 0x000a,
-	0x0120, 0x2001, 0x0008, 0x0804, 0x629e, 0x601a, 0x6003, 0x0008,
-	0x2900, 0x6016, 0x0058, 0x080c, 0xaeed, 0x05e8, 0x2b00, 0x6012,
-	0x2900, 0x6016, 0x600b, 0xffff, 0x6023, 0x000a, 0x2009, 0x0003,
-	0x080c, 0xafbe, 0x9006, 0x0458, 0x2001, 0x0028, 0x0438, 0x9082,
-	0x0006, 0x1290, 0x080c, 0xaead, 0x1160, 0xb8a0, 0x9084, 0xff80,
-	0x1140, 0xb900, 0xd1fc, 0x0900, 0x2001, 0x0029, 0x2009, 0x1000,
-	0x00a8, 0x2001, 0x0028, 0x0090, 0x2009, 0x180c, 0x210c, 0xd18c,
-	0x0118, 0x2001, 0x0004, 0x0050, 0xd184, 0x0118, 0x2001, 0x0004,
-	0x0028, 0x2001, 0x0029, 0x0010, 0x2001, 0x0029, 0x9005, 0x012e,
-	0x00ee, 0x00be, 0x0005, 0x2001, 0x002c, 0x0cc0, 0x00f6, 0x00b6,
-	0x0126, 0x2091, 0x8000, 0xa8e0, 0x9005, 0x1550, 0xa8dc, 0x9082,
-	0x0101, 0x1630, 0xa8c8, 0x9005, 0x1518, 0xa8c4, 0x9082, 0x0101,
-	0x12f8, 0xa974, 0x2079, 0x1800, 0x9182, 0x0800, 0x12e8, 0x7830,
-	0x9084, 0x0003, 0x1130, 0xaa98, 0xab94, 0xa878, 0x9084, 0x0007,
-	0x00ea, 0x7930, 0xd18c, 0x0118, 0x2001, 0x0004, 0x0038, 0xd184,
-	0x0118, 0x2001, 0x0004, 0x0010, 0x2001, 0x0029, 0x900e, 0x0038,
-	0x2001, 0x002c, 0x900e, 0x0018, 0x2001, 0x0029, 0x900e, 0x9006,
-	0x0008, 0x9005, 0x012e, 0x00be, 0x00fe, 0x0005, 0x6333, 0x62ee,
-	0x6305, 0x6333, 0x6333, 0x6333, 0x6333, 0x6333, 0x2100, 0x9082,
-	0x007e, 0x1278, 0x080c, 0x6638, 0x0148, 0x9046, 0xb810, 0x9306,
-	0x1904, 0x633b, 0xb814, 0x9206, 0x15f0, 0x0028, 0xbb12, 0xba16,
-	0x0010, 0x080c, 0x4a32, 0x0150, 0x04b0, 0x080c, 0x6699, 0x1598,
-	0xb810, 0x9306, 0x1580, 0xb814, 0x9206, 0x1568, 0x080c, 0xaeed,
-	0x0530, 0x2b00, 0x6012, 0x080c, 0xd102, 0x2900, 0x6016, 0x600b,
-	0xffff, 0x6023, 0x000a, 0xa878, 0x9086, 0x0001, 0x1170, 0x080c,
-	0x321e, 0x9006, 0x080c, 0x65d5, 0x2001, 0x0002, 0x080c, 0x65e9,
-	0x2001, 0x0200, 0xb86e, 0xb893, 0x0002, 0x2009, 0x0003, 0x080c,
-	0xafbe, 0x9006, 0x0068, 0x2001, 0x0001, 0x900e, 0x0038, 0x2001,
-	0x002c, 0x900e, 0x0018, 0x2001, 0x0028, 0x900e, 0x9005, 0x0000,
-	0x012e, 0x00be, 0x00fe, 0x0005, 0x00b6, 0x00f6, 0x00e6, 0x0126,
-	0x2091, 0x8000, 0xa894, 0x90c6, 0x0015, 0x0904, 0x6526, 0x90c6,
-	0x0056, 0x0904, 0x652a, 0x90c6, 0x0066, 0x0904, 0x652e, 0x90c6,
-	0x0067, 0x0904, 0x6532, 0x90c6, 0x0068, 0x0904, 0x6536, 0x90c6,
-	0x0071, 0x0904, 0x653a, 0x90c6, 0x0074, 0x0904, 0x653e, 0x90c6,
-	0x007c, 0x0904, 0x6542, 0x90c6, 0x007e, 0x0904, 0x6546, 0x90c6,
-	0x0037, 0x0904, 0x654a, 0x9016, 0x2079, 0x1800, 0xa974, 0x9186,
-	0x00ff, 0x0904, 0x6521, 0x9182, 0x0800, 0x1a04, 0x6521, 0x080c,
-	0x6699, 0x1198, 0xb804, 0x9084, 0x00ff, 0x9082, 0x0006, 0x1268,
-	0xa894, 0x90c6, 0x006f, 0x0148, 0x080c, 0xaead, 0x1904, 0x650a,
-	0xb8a0, 0x9084, 0xff80, 0x1904, 0x650a, 0xa894, 0x90c6, 0x006f,
-	0x0158, 0x90c6, 0x005e, 0x0904, 0x646a, 0x90c6, 0x0064, 0x0904,
-	0x6493, 0x2008, 0x0804, 0x642c, 0xa998, 0xa8b0, 0x2040, 0x080c,
-	0xaead, 0x1120, 0x9182, 0x007f, 0x0a04, 0x642c, 0x9186, 0x00ff,
-	0x0904, 0x642c, 0x9182, 0x0800, 0x1a04, 0x642c, 0xaaa0, 0xab9c,
-	0x787c, 0x9306, 0x11a8, 0x7880, 0x0096, 0x924e, 0x1128, 0x2208,
-	0x2310, 0x009e, 0x0804, 0x642c, 0x080c, 0xaead, 0x1140, 0x99cc,
-	0xff00, 0x009e, 0x1128, 0x2208, 0x2310, 0x0804, 0x642c, 0x009e,
-	0x080c, 0x4a32, 0x0904, 0x6436, 0x900e, 0x9016, 0x90c6, 0x4000,
-	0x15e0, 0x0006, 0x080c, 0x68b9, 0x1108, 0xc185, 0xb800, 0xd0bc,
-	0x0108, 0xc18d, 0x20a9, 0x0004, 0xa860, 0x20e8, 0xa85c, 0x9080,
-	0x0031, 0x20a0, 0xb8c4, 0x20e0, 0xb8c8, 0x9080, 0x0006, 0x2098,
-	0x080c, 0x0f7c, 0x20a9, 0x0004, 0xa860, 0x20e8, 0xa85c, 0x9080,
-	0x0035, 0x20a0, 0xb8c4, 0x20e0, 0xb8c8, 0x9080, 0x000a, 0x2098,
-	0x080c, 0x0f7c, 0xa8c4, 0xabc8, 0x9305, 0xabcc, 0x9305, 0xabd0,
-	0x9305, 0xabd4, 0x9305, 0xabd8, 0x9305, 0xabdc, 0x9305, 0xabe0,
-	0x9305, 0x9005, 0x0510, 0x000e, 0x00c8, 0x90c6, 0x4007, 0x1110,
-	0x2408, 0x00a0, 0x90c6, 0x4008, 0x1118, 0x2708, 0x2610, 0x0070,
-	0x90c6, 0x4009, 0x1108, 0x0050, 0x90c6, 0x4006, 0x0138, 0x2001,
-	0x4005, 0x2009, 0x000a, 0x0010, 0x2001, 0x4006, 0xa896, 0xa99a,
-	0xaa9e, 0x2001, 0x0030, 0x900e, 0x0478, 0x000e, 0x080c, 0xaeed,
-	0x1130, 0x2001, 0x4005, 0x2009, 0x0003, 0x9016, 0x0c78, 0x2b00,
-	0x6012, 0x080c, 0xd102, 0x2900, 0x6016, 0x6023, 0x0001, 0xa868,
-	0xd88c, 0x0108, 0xc0f5, 0xa86a, 0x0126, 0x2091, 0x8000, 0x080c,
-	0x321e, 0x012e, 0x9006, 0x080c, 0x65d5, 0x2001, 0x0002, 0x080c,
-	0x65e9, 0x2009, 0x0002, 0x080c, 0xafbe, 0xa8b0, 0xd094, 0x0118,
-	0xb8cc, 0xc08d, 0xb8ce, 0x9006, 0x9005, 0x012e, 0x00ee, 0x00fe,
-	0x00be, 0x0005, 0x080c, 0x5771, 0x0118, 0x2009, 0x0007, 0x00f8,
-	0xa998, 0xaeb0, 0x080c, 0x6699, 0x1904, 0x6427, 0x9186, 0x007f,
-	0x0130, 0x080c, 0x6a0c, 0x0118, 0x2009, 0x0009, 0x0080, 0x0096,
-	0x080c, 0x0fff, 0x1120, 0x009e, 0x2009, 0x0002, 0x0040, 0x2900,
-	0x009e, 0xa806, 0x080c, 0xce6e, 0x19b0, 0x2009, 0x0003, 0x2001,
-	0x4005, 0x0804, 0x642e, 0xa998, 0xaeb0, 0x080c, 0x6699, 0x1904,
-	0x6427, 0x0096, 0x080c, 0x0fff, 0x1128, 0x009e, 0x2009, 0x0002,
-	0x0804, 0x64e7, 0x2900, 0x009e, 0xa806, 0x0096, 0x2048, 0x20a9,
-	0x002b, 0xb8c4, 0x20e0, 0xb8c8, 0x2098, 0xa860, 0x20e8, 0xa85c,
-	0x9080, 0x0002, 0x20a0, 0x4003, 0x20a9, 0x0008, 0x9080, 0x0006,
-	0x20a0, 0xbbc8, 0x9398, 0x0006, 0x2398, 0x080c, 0x0f7c, 0x009e,
-	0xa87b, 0x0000, 0xa883, 0x0000, 0xa897, 0x4000, 0xd684, 0x1168,
-	0x080c, 0x575d, 0xd0b4, 0x1118, 0xa89b, 0x000b, 0x00e0, 0xb800,
-	0xd08c, 0x0118, 0xa89b, 0x000c, 0x00b0, 0x080c, 0x6a0c, 0x0118,
-	0xa89b, 0x0009, 0x0080, 0x080c, 0x5771, 0x0118, 0xa89b, 0x0007,
-	0x0050, 0x080c, 0xce51, 0x1904, 0x6463, 0x2009, 0x0003, 0x2001,
-	0x4005, 0x0804, 0x642e, 0xa87b, 0x0030, 0xa897, 0x4005, 0xa804,
-	0x8006, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080,
-	0x0002, 0x2009, 0x002b, 0xaaa0, 0xab9c, 0xaca8, 0xada4, 0x2031,
-	0x0000, 0x2041, 0x1243, 0x080c, 0xb45d, 0x1904, 0x6463, 0x2009,
-	0x0002, 0x08e8, 0x2001, 0x0028, 0x900e, 0x0804, 0x6464, 0x2009,
-	0x180c, 0x210c, 0xd18c, 0x0118, 0x2001, 0x0004, 0x0038, 0xd184,
-	0x0118, 0x2001, 0x0004, 0x0010, 0x2001, 0x0029, 0x900e, 0x0804,
-	0x6464, 0x2001, 0x0029, 0x900e, 0x0804, 0x6464, 0x080c, 0x37b3,
-	0x0804, 0x6465, 0x080c, 0x5488, 0x0804, 0x6465, 0x080c, 0x45b1,
-	0x0804, 0x6465, 0x080c, 0x462a, 0x0804, 0x6465, 0x080c, 0x4686,
-	0x0804, 0x6465, 0x080c, 0x4af5, 0x0804, 0x6465, 0x080c, 0x4da9,
-	0x0804, 0x6465, 0x080c, 0x50f0, 0x0804, 0x6465, 0x080c, 0x52e9,
-	0x0804, 0x6465, 0x080c, 0x39c9, 0x0804, 0x6465, 0x00b6, 0xa974,
-	0xae78, 0x9684, 0x3fff, 0x9082, 0x4000, 0x1618, 0x9182, 0x0800,
-	0x1268, 0x9188, 0x1000, 0x2104, 0x905d, 0x0140, 0x080c, 0x6a0c,
-	0x1148, 0x00e9, 0x080c, 0x67c4, 0x9006, 0x00b0, 0x2001, 0x0028,
-	0x900e, 0x0090, 0x9082, 0x0006, 0x1240, 0xb900, 0xd1fc, 0x0d88,
-	0x2001, 0x0029, 0x2009, 0x1000, 0x0038, 0x2001, 0x0029, 0x900e,
-	0x0018, 0x2001, 0x0029, 0x900e, 0x9005, 0x00be, 0x0005, 0x0126,
-	0x2091, 0x8000, 0xb850, 0x900d, 0x0150, 0x2900, 0x0096, 0x2148,
-	0xa802, 0x009e, 0xa803, 0x0000, 0xb852, 0x012e, 0x0005, 0x2900,
-	0xb852, 0xb84e, 0xa803, 0x0000, 0x0cc0, 0x0126, 0x2091, 0x8000,
-	0xb84c, 0x9005, 0x0170, 0x00e6, 0x2071, 0x19e6, 0x7004, 0x9086,
-	0x0002, 0x0168, 0x00ee, 0xb84c, 0xa802, 0x2900, 0xb84e, 0x012e,
-	0x0005, 0x2900, 0xb852, 0xb84e, 0xa803, 0x0000, 0x0cc0, 0x701c,
-	0x9b06, 0x1d80, 0xb84c, 0x00a6, 0x2050, 0xb000, 0xa802, 0x2900,
-	0xb002, 0x00ae, 0x00ee, 0x012e, 0x0005, 0x0126, 0x2091, 0x8000,
-	0xb84c, 0x904d, 0x0130, 0xa800, 0x9005, 0x1108, 0xb852, 0xb84e,
-	0x9905, 0x012e, 0x0005, 0xb84c, 0x904d, 0x0130, 0xa800, 0x9005,
-	0x1108, 0xb852, 0xb84e, 0x9905, 0x0005, 0x00b6, 0x0126, 0x00c6,
-	0x0026, 0x2091, 0x8000, 0x6210, 0x2258, 0xba00, 0x9005, 0x0110,
-	0xc285, 0x0008, 0xc284, 0xba02, 0x002e, 0x00ce, 0x012e, 0x00be,
-	0x0005, 0x00b6, 0x0126, 0x00c6, 0x2091, 0x8000, 0x6210, 0x2258,
-	0xba04, 0x0006, 0x9086, 0x0006, 0x1170, 0xb89c, 0xd0ac, 0x0158,
-	0x080c, 0x6a08, 0x0140, 0x9284, 0xff00, 0x8007, 0x9086, 0x0007,
-	0x1110, 0x2011, 0x0600, 0x000e, 0x9294, 0xff00, 0x9215, 0xba06,
-	0x0006, 0x9086, 0x0006, 0x1120, 0xba90, 0x82ff, 0x090c, 0x0dd5,
-	0x000e, 0x00ce, 0x012e, 0x00be, 0x0005, 0x00b6, 0x0126, 0x00c6,
+	0x8004, 0x20a8, 0x220e, 0x8210, 0x8108, 0x9186, 0x0260, 0x1150,
+	0x6810, 0x8000, 0x6812, 0x2009, 0x0240, 0x6814, 0x8000, 0x6816,
+	0x2011, 0x0260, 0x1f04, 0x5e92, 0x60c3, 0x0084, 0x080c, 0x5fb4,
+	0x0005, 0x0005, 0x0086, 0x0096, 0x2029, 0x1848, 0x252c, 0x20a9,
+	0x0008, 0x2041, 0x1c0e, 0x20e9, 0x0001, 0x28a0, 0x080c, 0x60fb,
+	0x20e1, 0x0000, 0x2099, 0x026e, 0x4003, 0x20a9, 0x0008, 0x2011,
+	0x0007, 0xd5d4, 0x0108, 0x9016, 0x2800, 0x9200, 0x200c, 0x91a6,
+	0xffff, 0x1148, 0xd5d4, 0x0110, 0x8210, 0x0008, 0x8211, 0x1f04,
+	0x5ec4, 0x0804, 0x5f33, 0x82ff, 0x1160, 0xd5d4, 0x0120, 0x91a6,
+	0x3fff, 0x0d90, 0x0020, 0x91a6, 0x3fff, 0x0904, 0x5f33, 0x918d,
+	0xc000, 0x20a9, 0x0010, 0x2019, 0x0001, 0xd5d4, 0x0110, 0x2019,
+	0x0010, 0x2120, 0xd5d4, 0x0110, 0x8423, 0x0008, 0x8424, 0x1240,
+	0xd5d4, 0x0110, 0x8319, 0x0008, 0x8318, 0x1f04, 0x5eea, 0x04d8,
+	0x23a8, 0x2021, 0x0001, 0x8426, 0x8425, 0x1f04, 0x5efc, 0x2328,
+	0x8529, 0x92be, 0x0007, 0x0158, 0x0006, 0x2039, 0x0007, 0x2200,
+	0x973a, 0x000e, 0x27a8, 0x95a8, 0x0010, 0x1f04, 0x5f0b, 0x755e,
+	0x95c8, 0x33b1, 0x292d, 0x95ac, 0x00ff, 0x7582, 0x6532, 0x6536,
+	0x0016, 0x2508, 0x080c, 0x28d2, 0x001e, 0x60e7, 0x0000, 0x65ea,
+	0x2018, 0x2304, 0x9405, 0x201a, 0x7087, 0x0001, 0x20e9, 0x0000,
+	0x20a1, 0x024e, 0x20e1, 0x0001, 0x2898, 0x20a9, 0x0008, 0x4003,
+	0x9085, 0x0001, 0x0008, 0x9006, 0x009e, 0x008e, 0x0005, 0x0156,
+	0x01c6, 0x01d6, 0x0136, 0x0146, 0x22a8, 0x20e1, 0x0000, 0x2099,
+	0x026e, 0x20e9, 0x0000, 0x2011, 0x024e, 0x22a0, 0x4003, 0x014e,
+	0x013e, 0x01de, 0x01ce, 0x015e, 0x2118, 0x9026, 0x2001, 0x0007,
+	0x939a, 0x0010, 0x0218, 0x8420, 0x8001, 0x0cd0, 0x2118, 0x84ff,
+	0x0120, 0x939a, 0x0010, 0x8421, 0x1de0, 0x2021, 0x0001, 0x83ff,
+	0x0118, 0x8423, 0x8319, 0x1de8, 0x9238, 0x2029, 0x026e, 0x9528,
+	0x2504, 0x942c, 0x11b8, 0x9405, 0x203a, 0x715e, 0x91a0, 0x33b1,
+	0x242d, 0x95ac, 0x00ff, 0x7582, 0x6532, 0x6536, 0x0016, 0x2508,
+	0x080c, 0x28d2, 0x001e, 0x60e7, 0x0000, 0x65ea, 0x7087, 0x0001,
+	0x9084, 0x0000, 0x0005, 0x00e6, 0x2071, 0x1800, 0x708b, 0x0000,
+	0x00ee, 0x0005, 0x00e6, 0x00f6, 0x2079, 0x0100, 0x2071, 0x0140,
+	0x080c, 0x6040, 0x080c, 0xa4fd, 0x7004, 0x9084, 0x4000, 0x0110,
+	0x080c, 0x2d6b, 0x0126, 0x2091, 0x8000, 0x2071, 0x1826, 0x2073,
+	0x0000, 0x7840, 0x0026, 0x0016, 0x2009, 0x00f7, 0x080c, 0x609d,
+	0x001e, 0x9094, 0x0010, 0x9285, 0x0080, 0x7842, 0x7a42, 0x002e,
+	0x012e, 0x00fe, 0x00ee, 0x0005, 0x0126, 0x2091, 0x8000, 0x080c,
+	0x2bf0, 0x0228, 0x2011, 0x0101, 0x2204, 0xc0c5, 0x2012, 0x2011,
+	0x19f3, 0x2013, 0x0000, 0x7093, 0x0000, 0x012e, 0x60a3, 0x0056,
+	0x60a7, 0x9575, 0x080c, 0xa4f4, 0x6144, 0xd184, 0x0120, 0x7198,
+	0x918d, 0x2000, 0x0018, 0x718c, 0x918d, 0x1000, 0x2011, 0x199a,
+	0x2112, 0x2009, 0x07d0, 0x2011, 0x5f8a, 0x080c, 0x879b, 0x0005,
+	0x0016, 0x0026, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xb058,
+	0x2009, 0x00f7, 0x080c, 0x609d, 0x2061, 0x19fc, 0x900e, 0x611a,
+	0x611e, 0x617a, 0x617e, 0x2061, 0x1800, 0x6003, 0x0001, 0x2061,
+	0x0100, 0x6043, 0x0090, 0x6043, 0x0010, 0x2009, 0x199a, 0x200b,
+	0x0000, 0x2009, 0x002d, 0x2011, 0x600c, 0x080c, 0x86f7, 0x012e,
+	0x00ce, 0x002e, 0x001e, 0x0005, 0x00e6, 0x0006, 0x0126, 0x2091,
+	0x8000, 0x0471, 0x2071, 0x0100, 0x080c, 0xa4fd, 0x2071, 0x0140,
+	0x7004, 0x9084, 0x4000, 0x0110, 0x080c, 0x2d6b, 0x080c, 0x756b,
+	0x0188, 0x080c, 0x7586, 0x1170, 0x080c, 0x7852, 0x0016, 0x080c,
+	0x29a1, 0x2001, 0x196e, 0x2102, 0x001e, 0x080c, 0x784d, 0x080c,
+	0x748f, 0x0050, 0x2009, 0x0001, 0x080c, 0x2c89, 0x2001, 0x0001,
+	0x080c, 0x2832, 0x080c, 0x5fe0, 0x012e, 0x000e, 0x00ee, 0x0005,
+	0x2001, 0x180e, 0x2004, 0xd0bc, 0x0158, 0x0026, 0x0036, 0x2011,
+	0x8017, 0x2001, 0x199a, 0x201c, 0x080c, 0x4be3, 0x003e, 0x002e,
+	0x0005, 0x20a9, 0x0012, 0x20e9, 0x0001, 0x20a1, 0x1c80, 0x080c,
+	0x60fb, 0x20e9, 0x0000, 0x2099, 0x026e, 0x0099, 0x20a9, 0x0020,
+	0x080c, 0x60f5, 0x2099, 0x0260, 0x20a1, 0x1c92, 0x0051, 0x20a9,
+	0x000e, 0x080c, 0x60f8, 0x2099, 0x0260, 0x20a1, 0x1cb2, 0x0009,
+	0x0005, 0x0016, 0x0026, 0x3410, 0x3308, 0x2104, 0x8007, 0x2012,
+	0x8108, 0x8210, 0x1f04, 0x6075, 0x002e, 0x001e, 0x0005, 0x080c,
+	0xada2, 0x20e1, 0x0001, 0x2099, 0x1c00, 0x20e9, 0x0000, 0x20a1,
+	0x0240, 0x20a9, 0x000c, 0x4003, 0x0005, 0x080c, 0xada2, 0x080c,
+	0x60fb, 0x20e1, 0x0000, 0x2099, 0x0260, 0x20e9, 0x0000, 0x20a1,
+	0x0240, 0x20a9, 0x000c, 0x4003, 0x0005, 0x00c6, 0x0006, 0x2061,
+	0x0100, 0x810f, 0x2001, 0x1834, 0x2004, 0x9005, 0x1138, 0x2001,
+	0x1818, 0x2004, 0x9084, 0x00ff, 0x9105, 0x0010, 0x9185, 0x00f7,
+	0x604a, 0x000e, 0x00ce, 0x0005, 0x0016, 0x0046, 0x080c, 0x6a88,
+	0x0158, 0x9006, 0x2020, 0x2009, 0x002a, 0x080c, 0xe940, 0x2001,
+	0x180c, 0x200c, 0xc195, 0x2102, 0x2019, 0x002a, 0x900e, 0x080c,
+	0x3216, 0x080c, 0xd548, 0x0140, 0x0036, 0x2019, 0xffff, 0x2021,
+	0x0007, 0x080c, 0x4d9a, 0x003e, 0x004e, 0x001e, 0x0005, 0x080c,
+	0x5fe0, 0x709b, 0x0000, 0x7093, 0x0000, 0x0005, 0x0006, 0x2001,
+	0x180c, 0x2004, 0xd09c, 0x0100, 0x000e, 0x0005, 0x0006, 0x0016,
+	0x0126, 0x2091, 0x8000, 0x2001, 0x0101, 0x200c, 0x918d, 0x0006,
+	0x2102, 0x012e, 0x001e, 0x000e, 0x0005, 0x2009, 0x0001, 0x0020,
+	0x2009, 0x0002, 0x0008, 0x900e, 0x6814, 0x9084, 0xffc0, 0x910d,
+	0x6916, 0x0005, 0x00f6, 0x0156, 0x0146, 0x01d6, 0x9006, 0x20a9,
+	0x0080, 0x20e9, 0x0001, 0x20a1, 0x1c00, 0x4004, 0x2079, 0x1c00,
+	0x7803, 0x2200, 0x7807, 0x00ef, 0x780f, 0x00ef, 0x7813, 0x0138,
+	0x7823, 0xffff, 0x7827, 0xffff, 0x01de, 0x014e, 0x015e, 0x00fe,
+	0x0005, 0x2001, 0x1800, 0x2003, 0x0001, 0x0005, 0x2001, 0x19a7,
+	0x0118, 0x2003, 0x0001, 0x0010, 0x2003, 0x0000, 0x0005, 0x0156,
+	0x20a9, 0x0800, 0x2009, 0x1000, 0x9006, 0x200a, 0x8108, 0x1f04,
+	0x6135, 0x015e, 0x0005, 0x00d6, 0x0036, 0x0156, 0x0136, 0x0146,
+	0x2069, 0x1847, 0x9006, 0xb802, 0xb8ce, 0xb807, 0x0707, 0xb80a,
+	0xb80e, 0xb812, 0x9198, 0x33b1, 0x231d, 0x939c, 0x00ff, 0xbb16,
+	0x0016, 0x0026, 0xb8c2, 0x080c, 0xb051, 0x1120, 0x9192, 0x007e,
+	0x1208, 0xbbc2, 0x20a9, 0x0004, 0xb8c4, 0x20e8, 0xb9c8, 0x9198,
+	0x0006, 0x9006, 0x23a0, 0x4004, 0x20a9, 0x0004, 0x9198, 0x000a,
+	0x23a0, 0x4004, 0x002e, 0x001e, 0xb83e, 0xb842, 0xb84e, 0xb852,
+	0xb856, 0xb85a, 0xb85e, 0xb862, 0xb866, 0xb86a, 0xb86f, 0x0100,
+	0xb872, 0xb876, 0xb87a, 0xb88a, 0xb88e, 0xb893, 0x0008, 0xb896,
+	0xb89a, 0xb89e, 0xb8be, 0xb9a2, 0x0096, 0xb8a4, 0x904d, 0x0110,
+	0x080c, 0x1040, 0xb8a7, 0x0000, 0x009e, 0x9006, 0xb84a, 0x6810,
+	0xb83a, 0x680c, 0xb846, 0xb8bb, 0x0520, 0xb8ac, 0x9005, 0x0198,
+	0x00c6, 0x2060, 0x9c82, 0x1cd0, 0x0a0c, 0x0dc5, 0x2001, 0x181a,
+	0x2004, 0x9c02, 0x1a0c, 0x0dc5, 0x080c, 0x8bbd, 0x00ce, 0x090c,
+	0x8f5e, 0xb8af, 0x0000, 0x6814, 0x9084, 0x00ff, 0xb842, 0x014e,
+	0x013e, 0x015e, 0x003e, 0x00de, 0x0005, 0x0126, 0x2091, 0x8000,
+	0xa974, 0xae78, 0x9684, 0x3fff, 0x9082, 0x4000, 0x1a04, 0x6223,
+	0x9182, 0x0800, 0x1a04, 0x6227, 0x2001, 0x180c, 0x2004, 0x9084,
+	0x0003, 0x1904, 0x622d, 0x9188, 0x1000, 0x2104, 0x905d, 0x0518,
+	0xb804, 0x9084, 0x00ff, 0x908e, 0x0006, 0x1508, 0xb8a4, 0x900d,
+	0x1904, 0x623f, 0xb850, 0x900d, 0x1148, 0xa802, 0x2900, 0xb852,
+	0xb84e, 0x080c, 0x9352, 0x9006, 0x012e, 0x0005, 0x00a6, 0x2150,
+	0x2900, 0xb002, 0xa803, 0x0000, 0x00ae, 0xb852, 0x0c90, 0x2001,
+	0x0005, 0x900e, 0x04b8, 0x2001, 0x0028, 0x900e, 0x0498, 0x9082,
+	0x0006, 0x1290, 0x080c, 0xb051, 0x1160, 0xb8a0, 0x9084, 0xff80,
+	0x1140, 0xb900, 0xd1fc, 0x0990, 0x2001, 0x0029, 0x2009, 0x1000,
+	0x0408, 0x2001, 0x0028, 0x00a8, 0x2009, 0x180c, 0x210c, 0xd18c,
+	0x0118, 0x2001, 0x0004, 0x0068, 0xd184, 0x0118, 0x2001, 0x0004,
+	0x0040, 0x2001, 0x0029, 0xb900, 0xd1fc, 0x0118, 0x2009, 0x1000,
+	0x0048, 0x900e, 0x0038, 0x2001, 0x0029, 0x900e, 0x0018, 0x2001,
+	0x0029, 0x900e, 0x9005, 0x012e, 0x0005, 0x2001, 0x180c, 0x2004,
+	0xd084, 0x19d0, 0x9188, 0x1000, 0x2104, 0x905d, 0x09a8, 0x080c,
+	0x6a8c, 0x1990, 0xb800, 0xd0bc, 0x0978, 0x0804, 0x61d6, 0x080c,
+	0x68b3, 0x0904, 0x61ef, 0x0804, 0x61da, 0x00b6, 0x00e6, 0x0126,
+	0x2091, 0x8000, 0xa874, 0x908e, 0x00ff, 0x1120, 0x2001, 0x196c,
+	0x205c, 0x0060, 0xa974, 0x9182, 0x0800, 0x1690, 0x9188, 0x1000,
+	0x2104, 0x905d, 0x01d0, 0x080c, 0x6a2c, 0x11d0, 0x080c, 0xb091,
+	0x0570, 0x2b00, 0x6012, 0x2900, 0x6016, 0x6023, 0x0009, 0x600b,
+	0x0000, 0xa874, 0x908e, 0x00ff, 0x1110, 0x600b, 0x8000, 0x2009,
+	0x0043, 0x080c, 0xb166, 0x9006, 0x00b0, 0x2001, 0x0028, 0x0090,
+	0x2009, 0x180c, 0x210c, 0xd18c, 0x0118, 0x2001, 0x0004, 0x0038,
+	0xd184, 0x0118, 0x2001, 0x0004, 0x0010, 0x2001, 0x0029, 0x0010,
+	0x2001, 0x0029, 0x9005, 0x012e, 0x00ee, 0x00be, 0x0005, 0x2001,
+	0x002c, 0x0cc0, 0x00b6, 0x00e6, 0x0126, 0x2091, 0x8000, 0xa974,
+	0x9182, 0x0800, 0x1a04, 0x6310, 0x9188, 0x1000, 0x2104, 0x905d,
+	0x0904, 0x62e8, 0xb8a0, 0x9086, 0x007f, 0x0190, 0xa87c, 0xd0fc,
+	0x1178, 0x080c, 0x6a94, 0x0160, 0xa994, 0x81ff, 0x0130, 0x908e,
+	0x0004, 0x0130, 0x908e, 0x0005, 0x0118, 0x080c, 0x6a8c, 0x1598,
+	0xa87c, 0xd0fc, 0x01e0, 0xa894, 0x9005, 0x01c8, 0x2060, 0x0026,
+	0x2010, 0x080c, 0xce2d, 0x002e, 0x1120, 0x2001, 0x0008, 0x0804,
+	0x6312, 0x6020, 0x9086, 0x000a, 0x0120, 0x2001, 0x0008, 0x0804,
+	0x6312, 0x601a, 0x6003, 0x0008, 0x2900, 0x6016, 0x0058, 0x080c,
+	0xb091, 0x05e8, 0x2b00, 0x6012, 0x2900, 0x6016, 0x600b, 0xffff,
+	0x6023, 0x000a, 0x2009, 0x0003, 0x080c, 0xb166, 0x9006, 0x0458,
+	0x2001, 0x0028, 0x0438, 0x9082, 0x0006, 0x1290, 0x080c, 0xb051,
+	0x1160, 0xb8a0, 0x9084, 0xff80, 0x1140, 0xb900, 0xd1fc, 0x0900,
+	0x2001, 0x0029, 0x2009, 0x1000, 0x00a8, 0x2001, 0x0028, 0x0090,
+	0x2009, 0x180c, 0x210c, 0xd18c, 0x0118, 0x2001, 0x0004, 0x0050,
+	0xd184, 0x0118, 0x2001, 0x0004, 0x0028, 0x2001, 0x0029, 0x0010,
+	0x2001, 0x0029, 0x9005, 0x012e, 0x00ee, 0x00be, 0x0005, 0x2001,
+	0x002c, 0x0cc0, 0x00f6, 0x00b6, 0x0126, 0x2091, 0x8000, 0xa8e0,
+	0x9005, 0x1550, 0xa8dc, 0x9082, 0x0101, 0x1630, 0xa8c8, 0x9005,
+	0x1518, 0xa8c4, 0x9082, 0x0101, 0x12f8, 0xa974, 0x2079, 0x1800,
+	0x9182, 0x0800, 0x12e8, 0x7830, 0x9084, 0x0003, 0x1130, 0xaa98,
+	0xab94, 0xa878, 0x9084, 0x0007, 0x00ea, 0x7930, 0xd18c, 0x0118,
+	0x2001, 0x0004, 0x0038, 0xd184, 0x0118, 0x2001, 0x0004, 0x0010,
+	0x2001, 0x0029, 0x900e, 0x0038, 0x2001, 0x002c, 0x900e, 0x0018,
+	0x2001, 0x0029, 0x900e, 0x9006, 0x0008, 0x9005, 0x012e, 0x00be,
+	0x00fe, 0x0005, 0x63a7, 0x6362, 0x6379, 0x63a7, 0x63a7, 0x63a7,
+	0x63a7, 0x63a7, 0x2100, 0x9082, 0x007e, 0x1278, 0x080c, 0x66ac,
+	0x0148, 0x9046, 0xb810, 0x9306, 0x1904, 0x63af, 0xb814, 0x9206,
+	0x15f0, 0x0028, 0xbb12, 0xba16, 0x0010, 0x080c, 0x4a96, 0x0150,
+	0x04b0, 0x080c, 0x6717, 0x1598, 0xb810, 0x9306, 0x1580, 0xb814,
+	0x9206, 0x1568, 0x080c, 0xb091, 0x0530, 0x2b00, 0x6012, 0x080c,
+	0xd2bb, 0x2900, 0x6016, 0x600b, 0xffff, 0x6023, 0x000a, 0xa878,
+	0x9086, 0x0001, 0x1170, 0x080c, 0x324b, 0x9006, 0x080c, 0x6649,
+	0x2001, 0x0002, 0x080c, 0x665d, 0x2001, 0x0200, 0xb86e, 0xb893,
+	0x0002, 0x2009, 0x0003, 0x080c, 0xb166, 0x9006, 0x0068, 0x2001,
+	0x0001, 0x900e, 0x0038, 0x2001, 0x002c, 0x900e, 0x0018, 0x2001,
+	0x0028, 0x900e, 0x9005, 0x0000, 0x012e, 0x00be, 0x00fe, 0x0005,
+	0x00b6, 0x00f6, 0x00e6, 0x0126, 0x2091, 0x8000, 0xa894, 0x90c6,
+	0x0015, 0x0904, 0x659a, 0x90c6, 0x0056, 0x0904, 0x659e, 0x90c6,
+	0x0066, 0x0904, 0x65a2, 0x90c6, 0x0067, 0x0904, 0x65a6, 0x90c6,
+	0x0068, 0x0904, 0x65aa, 0x90c6, 0x0071, 0x0904, 0x65ae, 0x90c6,
+	0x0074, 0x0904, 0x65b2, 0x90c6, 0x007c, 0x0904, 0x65b6, 0x90c6,
+	0x007e, 0x0904, 0x65ba, 0x90c6, 0x0037, 0x0904, 0x65be, 0x9016,
+	0x2079, 0x1800, 0xa974, 0x9186, 0x00ff, 0x0904, 0x6595, 0x9182,
+	0x0800, 0x1a04, 0x6595, 0x080c, 0x6717, 0x1198, 0xb804, 0x9084,
+	0x00ff, 0x9082, 0x0006, 0x1268, 0xa894, 0x90c6, 0x006f, 0x0148,
+	0x080c, 0xb051, 0x1904, 0x657e, 0xb8a0, 0x9084, 0xff80, 0x1904,
+	0x657e, 0xa894, 0x90c6, 0x006f, 0x0158, 0x90c6, 0x005e, 0x0904,
+	0x64de, 0x90c6, 0x0064, 0x0904, 0x6507, 0x2008, 0x0804, 0x64a0,
+	0xa998, 0xa8b0, 0x2040, 0x080c, 0xb051, 0x1120, 0x9182, 0x007f,
+	0x0a04, 0x64a0, 0x9186, 0x00ff, 0x0904, 0x64a0, 0x9182, 0x0800,
+	0x1a04, 0x64a0, 0xaaa0, 0xab9c, 0x787c, 0x9306, 0x11a8, 0x7880,
+	0x0096, 0x924e, 0x1128, 0x2208, 0x2310, 0x009e, 0x0804, 0x64a0,
+	0x080c, 0xb051, 0x1140, 0x99cc, 0xff00, 0x009e, 0x1128, 0x2208,
+	0x2310, 0x0804, 0x64a0, 0x009e, 0x080c, 0x4a96, 0x0904, 0x64aa,
+	0x900e, 0x9016, 0x90c6, 0x4000, 0x15e0, 0x0006, 0x080c, 0x6937,
+	0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x20a9, 0x0004,
+	0xa860, 0x20e8, 0xa85c, 0x9080, 0x0031, 0x20a0, 0xb8c4, 0x20e0,
+	0xb8c8, 0x9080, 0x0006, 0x2098, 0x080c, 0x0f8b, 0x20a9, 0x0004,
+	0xa860, 0x20e8, 0xa85c, 0x9080, 0x0035, 0x20a0, 0xb8c4, 0x20e0,
+	0xb8c8, 0x9080, 0x000a, 0x2098, 0x080c, 0x0f8b, 0xa8c4, 0xabc8,
+	0x9305, 0xabcc, 0x9305, 0xabd0, 0x9305, 0xabd4, 0x9305, 0xabd8,
+	0x9305, 0xabdc, 0x9305, 0xabe0, 0x9305, 0x9005, 0x0510, 0x000e,
+	0x00c8, 0x90c6, 0x4007, 0x1110, 0x2408, 0x00a0, 0x90c6, 0x4008,
+	0x1118, 0x2708, 0x2610, 0x0070, 0x90c6, 0x4009, 0x1108, 0x0050,
+	0x90c6, 0x4006, 0x0138, 0x2001, 0x4005, 0x2009, 0x000a, 0x0010,
+	0x2001, 0x4006, 0xa896, 0xa99a, 0xaa9e, 0x2001, 0x0030, 0x900e,
+	0x0478, 0x000e, 0x080c, 0xb091, 0x1130, 0x2001, 0x4005, 0x2009,
+	0x0003, 0x9016, 0x0c78, 0x2b00, 0x6012, 0x080c, 0xd2bb, 0x2900,
+	0x6016, 0x6023, 0x0001, 0xa868, 0xd88c, 0x0108, 0xc0f5, 0xa86a,
+	0x0126, 0x2091, 0x8000, 0x080c, 0x324b, 0x012e, 0x9006, 0x080c,
+	0x6649, 0x2001, 0x0002, 0x080c, 0x665d, 0x2009, 0x0002, 0x080c,
+	0xb166, 0xa8b0, 0xd094, 0x0118, 0xb8cc, 0xc08d, 0xb8ce, 0x9006,
+	0x9005, 0x012e, 0x00ee, 0x00fe, 0x00be, 0x0005, 0x080c, 0x57e1,
+	0x0118, 0x2009, 0x0007, 0x00f8, 0xa998, 0xaeb0, 0x080c, 0x6717,
+	0x1904, 0x649b, 0x9186, 0x007f, 0x0130, 0x080c, 0x6a8c, 0x0118,
+	0x2009, 0x0009, 0x0080, 0x0096, 0x080c, 0x100e, 0x1120, 0x009e,
+	0x2009, 0x0002, 0x0040, 0x2900, 0x009e, 0xa806, 0x080c, 0xd027,
+	0x19b0, 0x2009, 0x0003, 0x2001, 0x4005, 0x0804, 0x64a2, 0xa998,
+	0xaeb0, 0x080c, 0x6717, 0x1904, 0x649b, 0x0096, 0x080c, 0x100e,
+	0x1128, 0x009e, 0x2009, 0x0002, 0x0804, 0x655b, 0x2900, 0x009e,
+	0xa806, 0x0096, 0x2048, 0x20a9, 0x002b, 0xb8c4, 0x20e0, 0xb8c8,
+	0x2098, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0002, 0x20a0, 0x4003,
+	0x20a9, 0x0008, 0x9080, 0x0006, 0x20a0, 0xbbc8, 0x9398, 0x0006,
+	0x2398, 0x080c, 0x0f8b, 0x009e, 0xa87b, 0x0000, 0xa883, 0x0000,
+	0xa897, 0x4000, 0xd684, 0x1168, 0x080c, 0x57cd, 0xd0b4, 0x1118,
+	0xa89b, 0x000b, 0x00e0, 0xb800, 0xd08c, 0x0118, 0xa89b, 0x000c,
+	0x00b0, 0x080c, 0x6a8c, 0x0118, 0xa89b, 0x0009, 0x0080, 0x080c,
+	0x57e1, 0x0118, 0xa89b, 0x0007, 0x0050, 0x080c, 0xd00a, 0x1904,
+	0x64d7, 0x2009, 0x0003, 0x2001, 0x4005, 0x0804, 0x64a2, 0xa87b,
+	0x0030, 0xa897, 0x4005, 0xa804, 0x8006, 0x8006, 0x8007, 0x90bc,
+	0x003f, 0x9084, 0xffc0, 0x9080, 0x0002, 0x2009, 0x002b, 0xaaa0,
+	0xab9c, 0xaca8, 0xada4, 0x2031, 0x0000, 0x2041, 0x1252, 0x080c,
+	0xb608, 0x1904, 0x64d7, 0x2009, 0x0002, 0x08e8, 0x2001, 0x0028,
+	0x900e, 0x0804, 0x64d8, 0x2009, 0x180c, 0x210c, 0xd18c, 0x0118,
+	0x2001, 0x0004, 0x0038, 0xd184, 0x0118, 0x2001, 0x0004, 0x0010,
+	0x2001, 0x0029, 0x900e, 0x0804, 0x64d8, 0x2001, 0x0029, 0x900e,
+	0x0804, 0x64d8, 0x080c, 0x37e2, 0x0804, 0x64d9, 0x080c, 0x54f8,
+	0x0804, 0x64d9, 0x080c, 0x4606, 0x0804, 0x64d9, 0x080c, 0x467f,
+	0x0804, 0x64d9, 0x080c, 0x46db, 0x0804, 0x64d9, 0x080c, 0x4b59,
+	0x0804, 0x64d9, 0x080c, 0x4e0d, 0x0804, 0x64d9, 0x080c, 0x515f,
+	0x0804, 0x64d9, 0x080c, 0x5358, 0x0804, 0x64d9, 0x080c, 0x3a0c,
+	0x0804, 0x64d9, 0x00b6, 0xa974, 0xae78, 0x9684, 0x3fff, 0x9082,
+	0x4000, 0x1618, 0x9182, 0x0800, 0x1268, 0x9188, 0x1000, 0x2104,
+	0x905d, 0x0140, 0x080c, 0x6a8c, 0x1148, 0x00e9, 0x080c, 0x6842,
+	0x9006, 0x00b0, 0x2001, 0x0028, 0x900e, 0x0090, 0x9082, 0x0006,
+	0x1240, 0xb900, 0xd1fc, 0x0d88, 0x2001, 0x0029, 0x2009, 0x1000,
+	0x0038, 0x2001, 0x0029, 0x900e, 0x0018, 0x2001, 0x0029, 0x900e,
+	0x9005, 0x00be, 0x0005, 0x0126, 0x2091, 0x8000, 0xb850, 0x900d,
+	0x0150, 0x2900, 0x0096, 0x2148, 0xa802, 0x009e, 0xa803, 0x0000,
+	0xb852, 0x012e, 0x0005, 0x2900, 0xb852, 0xb84e, 0xa803, 0x0000,
+	0x0cc0, 0x0126, 0x2091, 0x8000, 0xb84c, 0x9005, 0x0170, 0x00e6,
+	0x2071, 0x19e9, 0x7004, 0x9086, 0x0002, 0x0168, 0x00ee, 0xb84c,
+	0xa802, 0x2900, 0xb84e, 0x012e, 0x0005, 0x2900, 0xb852, 0xb84e,
+	0xa803, 0x0000, 0x0cc0, 0x701c, 0x9b06, 0x1d80, 0xb84c, 0x00a6,
+	0x2050, 0xb000, 0xa802, 0x2900, 0xb002, 0x00ae, 0x00ee, 0x012e,
+	0x0005, 0x0126, 0x2091, 0x8000, 0xb84c, 0x904d, 0x0130, 0xa800,
+	0x9005, 0x1108, 0xb852, 0xb84e, 0x9905, 0x012e, 0x0005, 0xb84c,
+	0x904d, 0x0130, 0xa800, 0x9005, 0x1108, 0xb852, 0xb84e, 0x9905,
+	0x0005, 0x00b6, 0x0126, 0x00c6, 0x0026, 0x2091, 0x8000, 0x6210,
+	0x2258, 0xba00, 0x9005, 0x0110, 0xc285, 0x0008, 0xc284, 0xba02,
+	0x002e, 0x00ce, 0x012e, 0x00be, 0x0005, 0x00b6, 0x0126, 0x00c6,
 	0x2091, 0x8000, 0x6210, 0x2258, 0xba04, 0x0006, 0x9086, 0x0006,
-	0x1168, 0xb89c, 0xd0a4, 0x0150, 0x080c, 0x6a04, 0x1138, 0x9284,
-	0x00ff, 0x9086, 0x0007, 0x1110, 0x2011, 0x0006, 0x000e, 0x9294,
-	0x00ff, 0x8007, 0x9215, 0xba06, 0x00ce, 0x012e, 0x00be, 0x0005,
-	0x9182, 0x0800, 0x0218, 0x9085, 0x0001, 0x0005, 0x00d6, 0x0026,
-	0x9190, 0x1000, 0x2204, 0x905d, 0x1188, 0x0096, 0x080c, 0x0fff,
-	0x2958, 0x009e, 0x0168, 0x2b00, 0x2012, 0xb85c, 0xb8ca, 0xb860,
-	0xb8c6, 0x9006, 0xb8a6, 0xb8ae, 0x080c, 0x60c7, 0x9006, 0x0010,
-	0x9085, 0x0001, 0x002e, 0x00de, 0x0005, 0x00b6, 0x0096, 0x0126,
-	0x2091, 0x8000, 0x0026, 0x9182, 0x0800, 0x0218, 0x9085, 0x0001,
-	0x0458, 0x00d6, 0x9190, 0x1000, 0x2204, 0x905d, 0x0518, 0x2013,
-	0x0000, 0xb8a4, 0x904d, 0x0110, 0x080c, 0x1031, 0x00d6, 0x00c6,
-	0xb8bc, 0x2060, 0x8cff, 0x0168, 0x600c, 0x0006, 0x6014, 0x2048,
-	0x080c, 0xcc86, 0x0110, 0x080c, 0x0fb1, 0x080c, 0xaf43, 0x00ce,
-	0x0c88, 0x00ce, 0x00de, 0x2b48, 0xb8c8, 0xb85e, 0xb8c4, 0xb862,
-	0x080c, 0x1041, 0x00de, 0x9006, 0x002e, 0x012e, 0x009e, 0x00be,
-	0x0005, 0x0016, 0x9182, 0x0800, 0x0218, 0x9085, 0x0001, 0x0030,
-	0x9188, 0x1000, 0x2104, 0x905d, 0x0dc0, 0x9006, 0x001e, 0x0005,
-	0x00d6, 0x0156, 0x0136, 0x0146, 0x9006, 0xb80a, 0xb80e, 0xb800,
-	0xc08c, 0xb802, 0x080c, 0x743e, 0x1510, 0xb8a0, 0x9086, 0x007e,
-	0x0120, 0x080c, 0xaead, 0x11d8, 0x0078, 0x7040, 0xd0e4, 0x01b8,
-	0x00c6, 0x2061, 0x1981, 0x7048, 0x2062, 0x704c, 0x6006, 0x7050,
-	0x600a, 0x7054, 0x600e, 0x00ce, 0x703c, 0x2069, 0x0140, 0x9005,
-	0x1110, 0x2001, 0x0001, 0x6886, 0x2069, 0x1800, 0x68b6, 0x7040,
-	0xb85e, 0x7048, 0xb862, 0x704c, 0xb866, 0x20e1, 0x0000, 0x2099,
-	0x0276, 0xb8c4, 0x20e8, 0xb8c8, 0x9088, 0x000a, 0x21a0, 0x20a9,
-	0x0004, 0x4003, 0x2099, 0x027a, 0x9088, 0x0006, 0x21a0, 0x20a9,
-	0x0004, 0x4003, 0x2069, 0x0200, 0x6817, 0x0001, 0x7040, 0xb86a,
-	0x7144, 0xb96e, 0x7048, 0xb872, 0x7050, 0xb876, 0x2069, 0x0200,
-	0x6817, 0x0000, 0xb8a0, 0x9086, 0x007e, 0x1110, 0x7144, 0xb96e,
-	0x9182, 0x0211, 0x1218, 0x2009, 0x0008, 0x0400, 0x9182, 0x0259,
-	0x1218, 0x2009, 0x0007, 0x00d0, 0x9182, 0x02c1, 0x1218, 0x2009,
-	0x0006, 0x00a0, 0x9182, 0x0349, 0x1218, 0x2009, 0x0005, 0x0070,
-	0x9182, 0x0421, 0x1218, 0x2009, 0x0004, 0x0040, 0x9182, 0x0581,
-	0x1218, 0x2009, 0x0003, 0x0010, 0x2009, 0x0002, 0xb992, 0x014e,
-	0x013e, 0x015e, 0x00de, 0x0005, 0x0016, 0x0026, 0x00e6, 0x2071,
-	0x0260, 0x7034, 0xb896, 0x703c, 0xb89a, 0x7054, 0xb89e, 0x0036,
-	0xbbcc, 0xc384, 0xba00, 0x2009, 0x1867, 0x210c, 0xd0bc, 0x0120,
-	0xd1ec, 0x0110, 0xc2ad, 0x0008, 0xc2ac, 0xd0c4, 0x0148, 0xd1e4,
-	0x0138, 0xc2bd, 0xd0cc, 0x0128, 0xd38c, 0x1108, 0xc385, 0x0008,
-	0xc2bc, 0xba02, 0xbbce, 0x003e, 0x00ee, 0x002e, 0x001e, 0x0005,
-	0x0096, 0x0126, 0x2091, 0x8000, 0xb8a4, 0x904d, 0x0578, 0xa900,
-	0x81ff, 0x15c0, 0xaa04, 0x9282, 0x0010, 0x16c8, 0x0136, 0x0146,
-	0x01c6, 0x01d6, 0x8906, 0x8006, 0x8007, 0x908c, 0x003f, 0x21e0,
-	0x9084, 0xffc0, 0x9080, 0x0004, 0x2098, 0x2009, 0x0010, 0x20a9,
-	0x0001, 0x4002, 0x9086, 0xffff, 0x0120, 0x8109, 0x1dd0, 0x080c,
-	0x0dd5, 0x3c00, 0x20e8, 0x3300, 0x8001, 0x20a0, 0x4604, 0x8210,
-	0xaa06, 0x01de, 0x01ce, 0x014e, 0x013e, 0x0060, 0x080c, 0x0fff,
-	0x0170, 0x2900, 0xb8a6, 0xa803, 0x0000, 0x080c, 0x6855, 0xa807,
-	0x0001, 0xae12, 0x9085, 0x0001, 0x012e, 0x009e, 0x0005, 0x9006,
-	0x0cd8, 0x0126, 0x2091, 0x8000, 0x0096, 0xb8a4, 0x904d, 0x0188,
-	0xa800, 0x9005, 0x1150, 0x080c, 0x6864, 0x1158, 0xa804, 0x908a,
-	0x0002, 0x0218, 0x8001, 0xa806, 0x0020, 0x080c, 0x1031, 0xb8a7,
-	0x0000, 0x009e, 0x012e, 0x0005, 0x0126, 0x2091, 0x8000, 0x080c,
-	0x91ce, 0x012e, 0x0005, 0x901e, 0x0010, 0x2019, 0x0001, 0x900e,
-	0x0126, 0x2091, 0x8000, 0xb84c, 0x2048, 0xb800, 0xd0dc, 0x1170,
-	0x89ff, 0x0500, 0x83ff, 0x0120, 0xa878, 0x9606, 0x0158, 0x0030,
-	0xa86c, 0x9406, 0x1118, 0xa870, 0x9506, 0x0120, 0x2908, 0xa800,
-	0x2048, 0x0c70, 0x080c, 0xa761, 0xaa00, 0xb84c, 0x9906, 0x1110,
-	0xba4e, 0x0020, 0x00a6, 0x2150, 0xb202, 0x00ae, 0x82ff, 0x1110,
-	0xb952, 0x89ff, 0x012e, 0x0005, 0x9016, 0x0489, 0x1110, 0x2011,
-	0x0001, 0x0005, 0x080c, 0x68b9, 0x0128, 0x080c, 0xcd43, 0x0010,
-	0x9085, 0x0001, 0x0005, 0x080c, 0x68b9, 0x0128, 0x080c, 0xcce8,
-	0x0010, 0x9085, 0x0001, 0x0005, 0x080c, 0x68b9, 0x0128, 0x080c,
-	0xcd40, 0x0010, 0x9085, 0x0001, 0x0005, 0x080c, 0x68b9, 0x0128,
-	0x080c, 0xcd07, 0x0010, 0x9085, 0x0001, 0x0005, 0x080c, 0x68b9,
-	0x0128, 0x080c, 0xcd86, 0x0010, 0x9085, 0x0001, 0x0005, 0xb8a4,
-	0x900d, 0x1118, 0x9085, 0x0001, 0x0005, 0x0136, 0x01c6, 0xa800,
-	0x9005, 0x11b8, 0x890e, 0x810e, 0x810f, 0x9184, 0x003f, 0x20e0,
-	0x9184, 0xffc0, 0x9080, 0x0004, 0x2098, 0x20a9, 0x0001, 0x2009,
-	0x0010, 0x4002, 0x9606, 0x0128, 0x8109, 0x1dd8, 0x9085, 0x0001,
-	0x0008, 0x9006, 0x01ce, 0x013e, 0x0005, 0x0146, 0x01d6, 0xa860,
-	0x20e8, 0xa85c, 0x9080, 0x0004, 0x20a0, 0x20a9, 0x0010, 0x2009,
-	0xffff, 0x4104, 0x01de, 0x014e, 0x0136, 0x01c6, 0xa800, 0x9005,
-	0x11b8, 0x890e, 0x810e, 0x810f, 0x9184, 0x003f, 0x20e0, 0x9184,
-	0xffc0, 0x9080, 0x0004, 0x2098, 0x20a9, 0x0001, 0x2009, 0x0010,
-	0x4002, 0x9606, 0x0128, 0x8109, 0x1dd8, 0x9085, 0x0001, 0x0068,
-	0x0146, 0x01d6, 0x3300, 0x8001, 0x20a0, 0x3c00, 0x20e8, 0x2001,
-	0xffff, 0x4004, 0x01de, 0x014e, 0x9006, 0x01ce, 0x013e, 0x0005,
-	0x0096, 0x0126, 0x2091, 0x8000, 0xb8a4, 0x904d, 0x1128, 0x080c,
-	0x0fff, 0x0168, 0x2900, 0xb8a6, 0x080c, 0x6855, 0xa803, 0x0001,
-	0xa807, 0x0000, 0x9085, 0x0001, 0x012e, 0x009e, 0x0005, 0x9006,
-	0x0cd8, 0x0096, 0x0126, 0x2091, 0x8000, 0xb8a4, 0x904d, 0x0130,
-	0xb8a7, 0x0000, 0x080c, 0x1031, 0x9085, 0x0001, 0x012e, 0x009e,
-	0x0005, 0xb89c, 0xd0a4, 0x0005, 0x00b6, 0x00f6, 0x080c, 0x743e,
-	0x01b0, 0x71c4, 0x81ff, 0x1198, 0x71dc, 0xd19c, 0x0180, 0x2001,
-	0x007e, 0x9080, 0x1000, 0x2004, 0x905d, 0x0148, 0xb804, 0x9084,
-	0x00ff, 0x9086, 0x0006, 0x1118, 0xb800, 0xc0ed, 0xb802, 0x2079,
-	0x1847, 0x7804, 0xd0a4, 0x01d0, 0x0156, 0x20a9, 0x007f, 0x900e,
-	0x0016, 0x080c, 0x6699, 0x1168, 0xb804, 0x9084, 0xff00, 0x8007,
-	0x9096, 0x0004, 0x0118, 0x9086, 0x0006, 0x1118, 0xb800, 0xc0ed,
-	0xb802, 0x001e, 0x8108, 0x1f04, 0x68e0, 0x015e, 0x080c, 0x69ca,
-	0x0120, 0x2001, 0x1984, 0x200c, 0x0038, 0x2079, 0x1847, 0x7804,
-	0xd0a4, 0x0130, 0x2009, 0x07d0, 0x2011, 0x690b, 0x080c, 0x8648,
-	0x00fe, 0x00be, 0x0005, 0x00b6, 0x2011, 0x690b, 0x080c, 0x85b0,
-	0x080c, 0x69ca, 0x01d8, 0x2001, 0x107e, 0x2004, 0x2058, 0xb900,
-	0xc1ec, 0xb902, 0x080c, 0x6a08, 0x0130, 0x2009, 0x07d0, 0x2011,
-	0x690b, 0x080c, 0x8648, 0x00e6, 0x2071, 0x1800, 0x9006, 0x707e,
-	0x7060, 0x7082, 0x080c, 0x2ff5, 0x00ee, 0x04b0, 0x0156, 0x00c6,
-	0x20a9, 0x007f, 0x900e, 0x0016, 0x080c, 0x6699, 0x1538, 0xb800,
-	0xd0ec, 0x0520, 0x0046, 0xbaa0, 0x2220, 0x9006, 0x2009, 0x0029,
-	0x080c, 0xe73a, 0xb800, 0xc0e5, 0xc0ec, 0xb802, 0x080c, 0x6a04,
+	0x1170, 0xb89c, 0xd0ac, 0x0158, 0x080c, 0x6a88, 0x0140, 0x9284,
+	0xff00, 0x8007, 0x9086, 0x0007, 0x1110, 0x2011, 0x0600, 0x000e,
+	0x9294, 0xff00, 0x9215, 0xba06, 0x0006, 0x9086, 0x0006, 0x1120,
+	0xba90, 0x82ff, 0x090c, 0x0dc5, 0x000e, 0x00ce, 0x012e, 0x00be,
+	0x0005, 0x00b6, 0x0126, 0x00c6, 0x2091, 0x8000, 0x6210, 0x2258,
+	0xba04, 0x0006, 0x9086, 0x0006, 0x1168, 0xb89c, 0xd0a4, 0x0150,
+	0x080c, 0x6a84, 0x1138, 0x9284, 0x00ff, 0x9086, 0x0007, 0x1110,
+	0x2011, 0x0006, 0x000e, 0x9294, 0x00ff, 0x8007, 0x9215, 0xba06,
+	0x00ce, 0x012e, 0x00be, 0x0005, 0x9182, 0x0800, 0x0218, 0x9085,
+	0x0001, 0x0005, 0x00d6, 0x0026, 0x9190, 0x1000, 0x2204, 0x905d,
+	0x1188, 0x0096, 0x080c, 0x100e, 0x2958, 0x009e, 0x0168, 0x2b00,
+	0x2012, 0xb85c, 0xb8ca, 0xb860, 0xb8c6, 0x9006, 0xb8a6, 0xb8ae,
+	0x080c, 0x613b, 0x9006, 0x0010, 0x9085, 0x0001, 0x002e, 0x00de,
+	0x0005, 0x00b6, 0x0096, 0x0126, 0x2091, 0x8000, 0x0026, 0x9182,
+	0x0800, 0x0218, 0x9085, 0x0001, 0x04a8, 0x00d6, 0x9190, 0x1000,
+	0x2204, 0x905d, 0x0568, 0x2013, 0x0000, 0xb8a4, 0x904d, 0x0110,
+	0x080c, 0x1040, 0x00d6, 0x00c6, 0xb8bc, 0x2060, 0x8cff, 0x0168,
+	0x600c, 0x0006, 0x6014, 0x2048, 0x080c, 0xce3f, 0x0110, 0x080c,
+	0x0fc0, 0x080c, 0xb0e7, 0x00ce, 0x0c88, 0x00ce, 0x00de, 0x00c6,
+	0xb8ac, 0x9065, 0x0128, 0x621c, 0xd2c4, 0x0110, 0x080c, 0x8f5e,
+	0x00ce, 0x2b48, 0xb8c8, 0xb85e, 0xb8c4, 0xb862, 0x080c, 0x1050,
+	0x00de, 0x9006, 0x002e, 0x012e, 0x009e, 0x00be, 0x0005, 0x0016,
+	0x9182, 0x0800, 0x0218, 0x9085, 0x0001, 0x0030, 0x9188, 0x1000,
+	0x2104, 0x905d, 0x0dc0, 0x9006, 0x001e, 0x0005, 0x00d6, 0x0156,
+	0x0136, 0x0146, 0x9006, 0xb80a, 0xb80e, 0xb800, 0xc08c, 0xb802,
+	0x080c, 0x7563, 0x1510, 0xb8a0, 0x9086, 0x007e, 0x0120, 0x080c,
+	0xb051, 0x11d8, 0x0078, 0x7040, 0xd0e4, 0x01b8, 0x00c6, 0x2061,
+	0x1983, 0x7048, 0x2062, 0x704c, 0x6006, 0x7050, 0x600a, 0x7054,
+	0x600e, 0x00ce, 0x703c, 0x2069, 0x0140, 0x9005, 0x1110, 0x2001,
+	0x0001, 0x6886, 0x2069, 0x1800, 0x68b6, 0x7040, 0xb85e, 0x7048,
+	0xb862, 0x704c, 0xb866, 0x20e1, 0x0000, 0x2099, 0x0276, 0xb8c4,
+	0x20e8, 0xb8c8, 0x9088, 0x000a, 0x21a0, 0x20a9, 0x0004, 0x4003,
+	0x2099, 0x027a, 0x9088, 0x0006, 0x21a0, 0x20a9, 0x0004, 0x4003,
+	0x2069, 0x0200, 0x6817, 0x0001, 0x7040, 0xb86a, 0x7144, 0xb96e,
+	0x7048, 0xb872, 0x7050, 0xb876, 0x2069, 0x0200, 0x6817, 0x0000,
+	0xb8a0, 0x9086, 0x007e, 0x1110, 0x7144, 0xb96e, 0x9182, 0x0211,
+	0x1218, 0x2009, 0x0008, 0x0400, 0x9182, 0x0259, 0x1218, 0x2009,
+	0x0007, 0x00d0, 0x9182, 0x02c1, 0x1218, 0x2009, 0x0006, 0x00a0,
+	0x9182, 0x0349, 0x1218, 0x2009, 0x0005, 0x0070, 0x9182, 0x0421,
+	0x1218, 0x2009, 0x0004, 0x0040, 0x9182, 0x0581, 0x1218, 0x2009,
+	0x0003, 0x0010, 0x2009, 0x0002, 0xb992, 0x014e, 0x013e, 0x015e,
+	0x00de, 0x0005, 0x0016, 0x0026, 0x00e6, 0x2071, 0x0260, 0x7034,
+	0xb896, 0x703c, 0xb89a, 0x7054, 0xb89e, 0x0036, 0xbbcc, 0xc384,
+	0xba00, 0x2009, 0x1867, 0x210c, 0xd0bc, 0x0120, 0xd1ec, 0x0110,
+	0xc2ad, 0x0008, 0xc2ac, 0xd0c4, 0x0148, 0xd1e4, 0x0138, 0xc2bd,
+	0xd0cc, 0x0128, 0xd38c, 0x1108, 0xc385, 0x0008, 0xc2bc, 0xba02,
+	0xbbce, 0x003e, 0x00ee, 0x002e, 0x001e, 0x0005, 0x0096, 0x0126,
+	0x2091, 0x8000, 0xb8a4, 0x904d, 0x0578, 0xa900, 0x81ff, 0x15c0,
+	0xaa04, 0x9282, 0x0010, 0x16c8, 0x0136, 0x0146, 0x01c6, 0x01d6,
+	0x8906, 0x8006, 0x8007, 0x908c, 0x003f, 0x21e0, 0x9084, 0xffc0,
+	0x9080, 0x0004, 0x2098, 0x2009, 0x0010, 0x20a9, 0x0001, 0x4002,
+	0x9086, 0xffff, 0x0120, 0x8109, 0x1dd0, 0x080c, 0x0dc5, 0x3c00,
+	0x20e8, 0x3300, 0x8001, 0x20a0, 0x4604, 0x8210, 0xaa06, 0x01de,
+	0x01ce, 0x014e, 0x013e, 0x0060, 0x080c, 0x100e, 0x0170, 0x2900,
+	0xb8a6, 0xa803, 0x0000, 0x080c, 0x68d3, 0xa807, 0x0001, 0xae12,
+	0x9085, 0x0001, 0x012e, 0x009e, 0x0005, 0x9006, 0x0cd8, 0x0126,
+	0x2091, 0x8000, 0x0096, 0xb8a4, 0x904d, 0x0188, 0xa800, 0x9005,
+	0x1150, 0x080c, 0x68e2, 0x1158, 0xa804, 0x908a, 0x0002, 0x0218,
+	0x8001, 0xa806, 0x0020, 0x080c, 0x1040, 0xb8a7, 0x0000, 0x009e,
+	0x012e, 0x0005, 0x0126, 0x2091, 0x8000, 0x080c, 0x9352, 0x012e,
+	0x0005, 0x901e, 0x0010, 0x2019, 0x0001, 0x900e, 0x0126, 0x2091,
+	0x8000, 0xb84c, 0x2048, 0xb800, 0xd0dc, 0x1170, 0x89ff, 0x0500,
+	0x83ff, 0x0120, 0xa878, 0x9606, 0x0158, 0x0030, 0xa86c, 0x9406,
+	0x1118, 0xa870, 0x9506, 0x0120, 0x2908, 0xa800, 0x2048, 0x0c70,
+	0x080c, 0xa905, 0xaa00, 0xb84c, 0x9906, 0x1110, 0xba4e, 0x0020,
+	0x00a6, 0x2150, 0xb202, 0x00ae, 0x82ff, 0x1110, 0xb952, 0x89ff,
+	0x012e, 0x0005, 0x9016, 0x0489, 0x1110, 0x2011, 0x0001, 0x0005,
+	0x080c, 0x6937, 0x0128, 0x080c, 0xcefc, 0x0010, 0x9085, 0x0001,
+	0x0005, 0x080c, 0x6937, 0x0128, 0x080c, 0xcea1, 0x0010, 0x9085,
+	0x0001, 0x0005, 0x080c, 0x6937, 0x0128, 0x080c, 0xcef9, 0x0010,
+	0x9085, 0x0001, 0x0005, 0x080c, 0x6937, 0x0128, 0x080c, 0xcec0,
+	0x0010, 0x9085, 0x0001, 0x0005, 0x080c, 0x6937, 0x0128, 0x080c,
+	0xcf3f, 0x0010, 0x9085, 0x0001, 0x0005, 0xb8a4, 0x900d, 0x1118,
+	0x9085, 0x0001, 0x0005, 0x0136, 0x01c6, 0xa800, 0x9005, 0x11b8,
+	0x890e, 0x810e, 0x810f, 0x9184, 0x003f, 0x20e0, 0x9184, 0xffc0,
+	0x9080, 0x0004, 0x2098, 0x20a9, 0x0001, 0x2009, 0x0010, 0x4002,
+	0x9606, 0x0128, 0x8109, 0x1dd8, 0x9085, 0x0001, 0x0008, 0x9006,
+	0x01ce, 0x013e, 0x0005, 0x0146, 0x01d6, 0xa860, 0x20e8, 0xa85c,
+	0x9080, 0x0004, 0x20a0, 0x20a9, 0x0010, 0x2009, 0xffff, 0x4104,
+	0x01de, 0x014e, 0x0136, 0x01c6, 0xa800, 0x9005, 0x11b8, 0x890e,
+	0x810e, 0x810f, 0x9184, 0x003f, 0x20e0, 0x9184, 0xffc0, 0x9080,
+	0x0004, 0x2098, 0x20a9, 0x0001, 0x2009, 0x0010, 0x4002, 0x9606,
+	0x0128, 0x8109, 0x1dd8, 0x9085, 0x0001, 0x0068, 0x0146, 0x01d6,
+	0x3300, 0x8001, 0x20a0, 0x3c00, 0x20e8, 0x2001, 0xffff, 0x4004,
+	0x01de, 0x014e, 0x9006, 0x01ce, 0x013e, 0x0005, 0x0096, 0x0126,
+	0x2091, 0x8000, 0xb8a4, 0x904d, 0x1128, 0x080c, 0x100e, 0x0168,
+	0x2900, 0xb8a6, 0x080c, 0x68d3, 0xa803, 0x0001, 0xa807, 0x0000,
+	0x9085, 0x0001, 0x012e, 0x009e, 0x0005, 0x9006, 0x0cd8, 0x0096,
+	0x0126, 0x2091, 0x8000, 0xb8a4, 0x904d, 0x0130, 0xb8a7, 0x0000,
+	0x080c, 0x1040, 0x9085, 0x0001, 0x012e, 0x009e, 0x0005, 0xb89c,
+	0xd0a4, 0x0005, 0x00b6, 0x00f6, 0x080c, 0x7563, 0x01b0, 0x71c4,
+	0x81ff, 0x1198, 0x71dc, 0xd19c, 0x0180, 0x2001, 0x007e, 0x9080,
+	0x1000, 0x2004, 0x905d, 0x0148, 0xb804, 0x9084, 0x00ff, 0x9086,
+	0x0006, 0x1118, 0xb800, 0xc0ed, 0xb802, 0x2079, 0x1847, 0x7804,
+	0xd0a4, 0x01d0, 0x0156, 0x20a9, 0x007f, 0x900e, 0x0016, 0x080c,
+	0x6717, 0x1168, 0xb804, 0x9084, 0xff00, 0x8007, 0x9096, 0x0004,
+	0x0118, 0x9086, 0x0006, 0x1118, 0xb800, 0xc0ed, 0xb802, 0x001e,
+	0x8108, 0x1f04, 0x695e, 0x015e, 0x080c, 0x6a4a, 0x0120, 0x2001,
+	0x1986, 0x200c, 0x0038, 0x2079, 0x1847, 0x7804, 0xd0a4, 0x0130,
+	0x2009, 0x07d0, 0x2011, 0x6989, 0x080c, 0x879b, 0x00fe, 0x00be,
+	0x0005, 0x00b6, 0x2011, 0x6989, 0x080c, 0x8703, 0x080c, 0x6a4a,
+	0x01d8, 0x2001, 0x107e, 0x2004, 0x2058, 0xb900, 0xc1ec, 0xb902,
+	0x080c, 0x6a88, 0x0130, 0x2009, 0x07d0, 0x2011, 0x6989, 0x080c,
+	0x879b, 0x00e6, 0x2071, 0x1800, 0x9006, 0x707e, 0x7060, 0x7082,
+	0x080c, 0x3022, 0x00ee, 0x04c0, 0x0156, 0x00c6, 0x20a9, 0x007f,
+	0x900e, 0x0016, 0x080c, 0x6717, 0x1548, 0xb800, 0xd0ec, 0x0530,
+	0xd0bc, 0x1520, 0x0046, 0xbaa0, 0x2220, 0x9006, 0x2009, 0x0029,
+	0x080c, 0xe940, 0xb800, 0xc0e5, 0xc0ec, 0xb802, 0x080c, 0x6a84,
 	0x2001, 0x0707, 0x1128, 0xb804, 0x9084, 0x00ff, 0x9085, 0x0700,
-	0xb806, 0x2019, 0x0029, 0x080c, 0x9356, 0x0076, 0x903e, 0x080c,
-	0x9229, 0x900e, 0x080c, 0xe477, 0x007e, 0x004e, 0x001e, 0x8108,
-	0x1f04, 0x6933, 0x00ce, 0x015e, 0x00be, 0x0005, 0x00b6, 0x6010,
+	0xb806, 0x2019, 0x0029, 0x080c, 0x94da, 0x0076, 0x903e, 0x080c,
+	0x93ad, 0x900e, 0x080c, 0xe671, 0x007e, 0x004e, 0x001e, 0x8108,
+	0x1f04, 0x69b1, 0x00ce, 0x015e, 0x00be, 0x0005, 0x00b6, 0x6010,
 	0x2058, 0xb800, 0xc0ec, 0xb802, 0x00be, 0x0005, 0x00b6, 0x00c6,
-	0x0096, 0x080c, 0x1018, 0x090c, 0x0dd5, 0x2958, 0x009e, 0x2001,
-	0x196a, 0x2b02, 0x8b07, 0x8006, 0x8006, 0x908c, 0x003f, 0xb9c6,
+	0x0096, 0x080c, 0x1027, 0x090c, 0x0dc5, 0x2958, 0x009e, 0x2001,
+	0x196c, 0x2b02, 0x8b07, 0x8006, 0x8006, 0x908c, 0x003f, 0xb9c6,
 	0x908c, 0xffc0, 0xb9ca, 0xb8af, 0x0000, 0x2009, 0x00ff, 0x080c,
-	0x60c7, 0xb807, 0x0006, 0xb813, 0x00ff, 0xb817, 0xffff, 0xb86f,
+	0x613b, 0xb807, 0x0006, 0xb813, 0x00ff, 0xb817, 0xffff, 0xb86f,
 	0x0200, 0xb86c, 0xb893, 0x0002, 0xb8bb, 0x0520, 0xb8a3, 0x00ff,
 	0xb8af, 0x0000, 0x00ce, 0x00be, 0x0005, 0x7810, 0x00b6, 0x2058,
 	0xb800, 0x00be, 0xd0ac, 0x0005, 0x6010, 0x00b6, 0x905d, 0x0108,
@@ -3182,2267 +3198,2304 @@ unsigned short risc_code01[] = { 
 	0x000e, 0x0005, 0x00b6, 0x00f6, 0x2001, 0x107e, 0x2004, 0x905d,
 	0x0110, 0xb800, 0xd0ec, 0x00fe, 0x00be, 0x0005, 0x0126, 0x0026,
 	0x2091, 0x8000, 0x0006, 0xbaa0, 0x9290, 0x1000, 0x2204, 0x9b06,
-	0x190c, 0x0dd5, 0x000e, 0xba00, 0x9005, 0x0110, 0xc2fd, 0x0008,
+	0x190c, 0x0dc5, 0x000e, 0xba00, 0x9005, 0x0110, 0xc2fd, 0x0008,
 	0xc2fc, 0xba02, 0x002e, 0x012e, 0x0005, 0x2011, 0x1837, 0x2204,
-	0xd0cc, 0x0138, 0x2001, 0x1982, 0x200c, 0x2011, 0x69fa, 0x080c,
-	0x8648, 0x0005, 0x2011, 0x69fa, 0x080c, 0x85b0, 0x2011, 0x1837,
-	0x2204, 0xc0cc, 0x2012, 0x0005, 0x080c, 0x575d, 0xd0ac, 0x0005,
-	0x080c, 0x575d, 0xd0a4, 0x0005, 0x0016, 0xb904, 0x9184, 0x00ff,
+	0xd0cc, 0x0138, 0x2001, 0x1984, 0x200c, 0x2011, 0x6a7a, 0x080c,
+	0x879b, 0x0005, 0x2011, 0x6a7a, 0x080c, 0x8703, 0x2011, 0x1837,
+	0x2204, 0xc0cc, 0x2012, 0x0005, 0x080c, 0x57cd, 0xd0ac, 0x0005,
+	0x080c, 0x57cd, 0xd0a4, 0x0005, 0x0016, 0xb904, 0x9184, 0x00ff,
 	0x908e, 0x0006, 0x001e, 0x0005, 0x0016, 0xb904, 0x9184, 0xff00,
 	0x8007, 0x908e, 0x0006, 0x001e, 0x0005, 0x00b6, 0x00f6, 0x080c,
-	0xd388, 0x0158, 0x70dc, 0x9084, 0x0028, 0x0138, 0x2001, 0x107f,
+	0xd548, 0x0158, 0x70dc, 0x9084, 0x0028, 0x0138, 0x2001, 0x107f,
 	0x2004, 0x905d, 0x0110, 0xb8cc, 0xd094, 0x00fe, 0x00be, 0x0005,
 	0x2071, 0x1910, 0x7003, 0x0001, 0x7007, 0x0000, 0x9006, 0x7012,
-	0x7016, 0x701a, 0x701e, 0x700a, 0x7046, 0x0005, 0x0016, 0x00e6,
-	0x2071, 0x1947, 0x900e, 0x710a, 0x080c, 0x575d, 0xd0fc, 0x1140,
-	0x080c, 0x575d, 0x900e, 0xd09c, 0x0108, 0x8108, 0x7102, 0x00f8,
-	0x2001, 0x1867, 0x200c, 0x9184, 0x0007, 0x0002, 0x6a48, 0x6a48,
-	0x6a48, 0x6a48, 0x6a48, 0x6a5e, 0x6a6c, 0x6a48, 0x7003, 0x0003,
-	0x2009, 0x1868, 0x210c, 0x9184, 0xff00, 0x8007, 0x9005, 0x1110,
-	0x2001, 0x0002, 0x7006, 0x0018, 0x7003, 0x0005, 0x0c88, 0x00ee,
-	0x001e, 0x0005, 0x00e6, 0x2071, 0x0050, 0x684c, 0x9005, 0x1150,
-	0x00e6, 0x2071, 0x1910, 0x7028, 0xc085, 0x702a, 0x00ee, 0x9085,
-	0x0001, 0x0488, 0x6844, 0x9005, 0x0158, 0x080c, 0x7796, 0x6a60,
-	0x9200, 0x7002, 0x6864, 0x9101, 0x7006, 0x9006, 0x7012, 0x7016,
-	0x6860, 0x7002, 0x6864, 0x7006, 0x6868, 0x700a, 0x686c, 0x700e,
-	0x6844, 0x9005, 0x1110, 0x7012, 0x7016, 0x684c, 0x701a, 0x701c,
-	0x9085, 0x0040, 0x701e, 0x7037, 0x0019, 0x702b, 0x0001, 0x00e6,
-	0x2071, 0x1910, 0x7028, 0xc084, 0x702a, 0x7007, 0x0001, 0x700b,
-	0x0000, 0x00ee, 0x9006, 0x00ee, 0x0005, 0x00e6, 0x0026, 0x2071,
-	0x1947, 0x7000, 0x9015, 0x0904, 0x6d1c, 0x9286, 0x0003, 0x0904,
-	0x6bb2, 0x9286, 0x0005, 0x0904, 0x6bb2, 0x2071, 0x1877, 0xa87c,
-	0x9005, 0x0904, 0x6b13, 0x7140, 0xa868, 0x9102, 0x0a04, 0x6d1c,
-	0xa878, 0xd084, 0x15d8, 0xa853, 0x0019, 0x2001, 0x8023, 0xa84e,
-	0x2071, 0x1910, 0x701c, 0x9005, 0x1904, 0x6eb2, 0x0e04, 0x6f20,
-	0x2071, 0x0000, 0xa850, 0x7032, 0xa84c, 0x7082, 0xa870, 0x7086,
-	0xa86c, 0x708a, 0xa880, 0x708e, 0x7036, 0x0146, 0x01d6, 0x0136,
-	0x01c6, 0x0156, 0x20e9, 0x0000, 0x20a1, 0x002a, 0xa868, 0x20a8,
-	0xa860, 0x20e0, 0xa85c, 0x9080, 0x0021, 0x2098, 0x4003, 0x015e,
-	0x01ce, 0x013e, 0x01de, 0x014e, 0x2091, 0x4080, 0x2001, 0x0089,
-	0x2004, 0xd084, 0x190c, 0x119b, 0x0804, 0x6b95, 0xa853, 0x001b,
-	0x2001, 0x8027, 0x0820, 0x7004, 0xd08c, 0x1904, 0x6d1c, 0xa853,
-	0x001a, 0x2001, 0x8024, 0x0804, 0x6ad7, 0x00e6, 0x0026, 0x2071,
-	0x1947, 0x7000, 0x9015, 0x0904, 0x6d1c, 0x9286, 0x0003, 0x0904,
-	0x6bb2, 0x9286, 0x0005, 0x0904, 0x6bb2, 0xa84f, 0x8022, 0xa853,
-	0x0018, 0x0804, 0x6b7a, 0xa868, 0xd0fc, 0x11d8, 0x00e6, 0x0026,
-	0x2001, 0x1947, 0x2004, 0x9005, 0x0904, 0x6d1c, 0xa87c, 0xd0bc,
-	0x1904, 0x6d1c, 0xa978, 0xa874, 0x9105, 0x1904, 0x6d1c, 0x2001,
-	0x1947, 0x2004, 0x0002, 0x6d1c, 0x6b76, 0x6bb2, 0x6bb2, 0x6d1c,
-	0x6bb2, 0x0005, 0xa868, 0xd0fc, 0x1500, 0x00e6, 0x0026, 0x2009,
-	0x1947, 0x210c, 0x81ff, 0x0904, 0x6d1c, 0xa87c, 0xd0cc, 0x0904,
-	0x6d1c, 0xa880, 0x9084, 0x00ff, 0x9086, 0x0001, 0x1904, 0x6d1c,
-	0x9186, 0x0003, 0x0904, 0x6bb2, 0x9186, 0x0005, 0x0904, 0x6bb2,
+	0x7016, 0x701a, 0x701e, 0x700a, 0x7046, 0x2001, 0x1922, 0x2003,
+	0x0000, 0x0005, 0x0016, 0x00e6, 0x2071, 0x1949, 0x900e, 0x710a,
+	0x080c, 0x57cd, 0xd0fc, 0x1140, 0x080c, 0x57cd, 0x900e, 0xd09c,
+	0x0108, 0x8108, 0x7102, 0x0430, 0x2001, 0x1867, 0x200c, 0x9184,
+	0x0007, 0x0002, 0x6acc, 0x6acc, 0x6acc, 0x6acc, 0x6acc, 0x6ae2,
+	0x6af7, 0x6b05, 0x7003, 0x0003, 0x2009, 0x1868, 0x210c, 0x9184,
+	0xff00, 0x908e, 0xff00, 0x0140, 0x8007, 0x9005, 0x1110, 0x2001,
+	0x0002, 0x8003, 0x7006, 0x0030, 0x7007, 0x0001, 0x0018, 0x7003,
+	0x0005, 0x0c50, 0x2071, 0x1910, 0x704f, 0x0000, 0x2071, 0x1800,
+	0x70f3, 0x0001, 0x00ee, 0x001e, 0x0005, 0x7003, 0x0000, 0x2071,
+	0x1910, 0x2009, 0x1868, 0x210c, 0x9184, 0x7f00, 0x8007, 0x908c,
+	0x000f, 0x0160, 0x714e, 0x8004, 0x8004, 0x8004, 0x8004, 0x2071,
+	0x1800, 0x908c, 0x0007, 0x0128, 0x70f2, 0x0c20, 0x704f, 0x000f,
+	0x0c90, 0x70f3, 0x0005, 0x08f0, 0x00e6, 0x2071, 0x0050, 0x684c,
+	0x9005, 0x1150, 0x00e6, 0x2071, 0x1910, 0x7028, 0xc085, 0x702a,
+	0x00ee, 0x9085, 0x0001, 0x0488, 0x6844, 0x9005, 0x0158, 0x080c,
+	0x78ba, 0x6a60, 0x9200, 0x7002, 0x6864, 0x9101, 0x7006, 0x9006,
+	0x7012, 0x7016, 0x6860, 0x7002, 0x6864, 0x7006, 0x6868, 0x700a,
+	0x686c, 0x700e, 0x6844, 0x9005, 0x1110, 0x7012, 0x7016, 0x684c,
+	0x701a, 0x701c, 0x9085, 0x0040, 0x701e, 0x7037, 0x0019, 0x702b,
+	0x0001, 0x00e6, 0x2071, 0x1910, 0x7028, 0xc084, 0x702a, 0x7007,
+	0x0001, 0x700b, 0x0000, 0x00ee, 0x9006, 0x00ee, 0x0005, 0x00e6,
+	0x0026, 0x2071, 0x1949, 0x7000, 0x9015, 0x0904, 0x6dd1, 0x9286,
+	0x0003, 0x0904, 0x6c6a, 0x9286, 0x0005, 0x0904, 0x6c6a, 0x2071,
+	0x1877, 0xa87c, 0x9005, 0x0904, 0x6bc5, 0x7140, 0xa868, 0x9102,
+	0x0a04, 0x6dd1, 0xa878, 0xd084, 0x15d8, 0xa853, 0x0019, 0x2001,
+	0x8023, 0xa84e, 0x2071, 0x1910, 0x701c, 0x9005, 0x1904, 0x6f9f,
+	0x0e04, 0x700d, 0x2071, 0x0000, 0xa850, 0x7032, 0xa84c, 0x7082,
+	0xa870, 0x7086, 0xa86c, 0x708a, 0xa880, 0x708e, 0x7036, 0x0146,
+	0x01d6, 0x0136, 0x01c6, 0x0156, 0x20e9, 0x0000, 0x20a1, 0x002a,
+	0xa868, 0x20a8, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0021, 0x2098,
+	0x4003, 0x015e, 0x01ce, 0x013e, 0x01de, 0x014e, 0x2091, 0x4080,
+	0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11aa, 0x0804, 0x6c4d,
+	0xa853, 0x001b, 0x2001, 0x8027, 0x0820, 0x7004, 0xd08c, 0x1904,
+	0x6dd1, 0xa853, 0x001a, 0x2001, 0x8024, 0x0804, 0x6b89, 0x00e6,
+	0x0026, 0x2071, 0x1949, 0x7000, 0x9015, 0x0904, 0x6dd1, 0x9286,
+	0x0003, 0x0904, 0x6c6a, 0x9286, 0x0005, 0x0904, 0x6c6a, 0xa84f,
+	0x8022, 0xa853, 0x0018, 0x0804, 0x6c32, 0xa868, 0xd0fc, 0x1508,
+	0x00e6, 0x0026, 0x2001, 0x1949, 0x2004, 0x9015, 0x0904, 0x6dd1,
+	0xa978, 0xa874, 0x9105, 0x1904, 0x6dd1, 0x9286, 0x0003, 0x0904,
+	0x6c6a, 0x9286, 0x0005, 0x0904, 0x6c6a, 0xa87c, 0xd0bc, 0x1904,
+	0x6dd1, 0x2200, 0x0002, 0x6dd1, 0x6c2e, 0x6c6a, 0x6c6a, 0x6dd1,
+	0x6c6a, 0x0005, 0xa868, 0xd0fc, 0x1500, 0x00e6, 0x0026, 0x2009,
+	0x1949, 0x210c, 0x81ff, 0x0904, 0x6dd1, 0xa880, 0x9084, 0x00ff,
+	0x9086, 0x0001, 0x1904, 0x6dd1, 0x9186, 0x0003, 0x0904, 0x6c6a,
+	0x9186, 0x0005, 0x0904, 0x6c6a, 0xa87c, 0xd0cc, 0x0904, 0x6dd1,
 	0xa84f, 0x8021, 0xa853, 0x0017, 0x0028, 0x0005, 0xa84f, 0x8020,
-	0xa853, 0x0016, 0x2071, 0x1910, 0x701c, 0x9005, 0x1904, 0x6eb2,
-	0x0e04, 0x6f20, 0x2071, 0x0000, 0xa84c, 0x7082, 0xa850, 0x7032,
+	0xa853, 0x0016, 0x2071, 0x1910, 0x701c, 0x9005, 0x1904, 0x6f9f,
+	0x0e04, 0x700d, 0x2071, 0x0000, 0xa84c, 0x7082, 0xa850, 0x7032,
 	0xa86c, 0x7086, 0x7036, 0xa870, 0x708a, 0x2091, 0x4080, 0x2001,
-	0x0089, 0x2004, 0xd084, 0x190c, 0x119b, 0x2071, 0x1800, 0x2011,
+	0x0089, 0x2004, 0xd084, 0x190c, 0x11aa, 0x2071, 0x1800, 0x2011,
 	0x0001, 0xa804, 0x900d, 0x702c, 0x1158, 0xa802, 0x2900, 0x702e,
-	0x70c0, 0x9200, 0x70c2, 0x080c, 0x84c2, 0x002e, 0x00ee, 0x0005,
+	0x70c0, 0x9200, 0x70c2, 0x080c, 0x85eb, 0x002e, 0x00ee, 0x0005,
 	0x0096, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8,
 	0x009e, 0x0c58, 0xa84f, 0x0000, 0x00f6, 0x2079, 0x0050, 0x2071,
-	0x1910, 0xa803, 0x0000, 0x7010, 0x9005, 0x1904, 0x6ca1, 0x782c,
-	0x908c, 0x0780, 0x190c, 0x706e, 0x8004, 0x8004, 0x8004, 0x9084,
-	0x0003, 0x0002, 0x6bd0, 0x6ca1, 0x6bf5, 0x6c3c, 0x080c, 0x0dd5,
-	0x2071, 0x1800, 0x2900, 0x7822, 0xa804, 0x900d, 0x1170, 0x2071,
-	0x19f9, 0x703c, 0x9005, 0x1328, 0x2001, 0x1948, 0x2004, 0x8005,
-	0x703e, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x9016, 0x702c, 0x2148,
-	0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70c0,
-	0x9200, 0x70c2, 0x080c, 0x84c2, 0x0c10, 0x2071, 0x1800, 0x2900,
-	0x7822, 0xa804, 0x900d, 0x1580, 0x7824, 0x00e6, 0x2071, 0x0040,
-	0x712c, 0xd19c, 0x1148, 0x2009, 0x1830, 0x210c, 0x918a, 0x0020,
-	0x0218, 0x7022, 0x00ee, 0x0058, 0x00ee, 0x2048, 0x702c, 0xa802,
-	0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c, 0x84c2, 0x782c,
-	0x9094, 0x0780, 0x190c, 0x706e, 0xd0a4, 0x19f0, 0x2071, 0x19f9,
-	0x703c, 0x9005, 0x1328, 0x2001, 0x1948, 0x2004, 0x8005, 0x703e,
+	0x1910, 0xa803, 0x0000, 0x7010, 0x9005, 0x1904, 0x6d55, 0x782c,
+	0x908c, 0x0780, 0x190c, 0x715b, 0x8004, 0x8004, 0x8004, 0x9084,
+	0x0003, 0x0002, 0x6c88, 0x6d55, 0x6cac, 0x6cf2, 0x080c, 0x0dc5,
+	0x2071, 0x1800, 0x2900, 0x7822, 0xa804, 0x900d, 0x1168, 0x2071,
+	0x19fc, 0x7044, 0x9005, 0x1320, 0x2001, 0x194a, 0x2004, 0x7046,
 	0x00fe, 0x002e, 0x00ee, 0x0005, 0x9016, 0x702c, 0x2148, 0xa904,
 	0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200,
-	0x70c2, 0x080c, 0x84c2, 0x0800, 0x0096, 0x00e6, 0x7824, 0x2048,
-	0x2071, 0x1800, 0x702c, 0xa802, 0x2900, 0x702e, 0x70c0, 0x8000,
-	0x70c2, 0x080c, 0x84c2, 0x782c, 0x9094, 0x0780, 0x190c, 0x706e,
-	0xd0a4, 0x1d60, 0x00ee, 0x782c, 0x9094, 0x0780, 0x190c, 0x706e,
-	0xd09c, 0x11a0, 0x009e, 0x2900, 0x7822, 0xa804, 0x900d, 0x1560,
-	0x2071, 0x19f9, 0x703c, 0x9005, 0x1328, 0x2001, 0x1948, 0x2004,
-	0x8005, 0x703e, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x009e, 0x2908,
-	0x7010, 0x8000, 0x7012, 0x7018, 0x904d, 0x711a, 0x0110, 0xa902,
-	0x0008, 0x711e, 0x2148, 0xa804, 0x900d, 0x1170, 0x2071, 0x19f9,
-	0x703c, 0x9005, 0x1328, 0x2001, 0x1948, 0x2004, 0x8005, 0x703e,
-	0x00fe, 0x002e, 0x00ee, 0x0005, 0x2071, 0x1800, 0x9016, 0x702c,
-	0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e,
-	0x70c0, 0x9200, 0x70c2, 0x080c, 0x84c2, 0x00fe, 0x002e, 0x00ee,
-	0x0005, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018, 0x904d, 0x711a,
-	0x0110, 0xa902, 0x0008, 0x711e, 0x2148, 0xa804, 0x900d, 0x1904,
-	0x6cf6, 0x782c, 0x9094, 0x0780, 0x190c, 0x706e, 0xd09c, 0x1198,
-	0x701c, 0x904d, 0x0180, 0x7010, 0x8001, 0x7012, 0x1108, 0x701a,
-	0xa800, 0x701e, 0x2900, 0x7822, 0x782c, 0x9094, 0x0780, 0x190c,
-	0x706e, 0xd09c, 0x0d68, 0x782c, 0x9094, 0x0780, 0x190c, 0x706e,
-	0xd0a4, 0x01b0, 0x00e6, 0x7824, 0x2048, 0x2071, 0x1800, 0x702c,
-	0xa802, 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c, 0x84c2,
-	0x782c, 0x9094, 0x0780, 0x190c, 0x706e, 0xd0a4, 0x1d60, 0x00ee,
-	0x2071, 0x19f9, 0x703c, 0x9005, 0x1328, 0x2001, 0x1948, 0x2004,
-	0x8005, 0x703e, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x00e6, 0x2071,
-	0x1800, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900,
-	0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x84c2,
-	0x00ee, 0x0804, 0x6cb1, 0xa868, 0xd0fc, 0x1560, 0x0096, 0xa804,
-	0xa807, 0x0000, 0x904d, 0x190c, 0x0fb1, 0x009e, 0x0018, 0xa868,
-	0xd0fc, 0x1500, 0x00e6, 0x0026, 0xa84f, 0x0000, 0x00f6, 0x2079,
-	0x0050, 0x2071, 0x1910, 0xa803, 0x0000, 0x7010, 0x9005, 0x1904,
-	0x6e30, 0x782c, 0x908c, 0x0780, 0x190c, 0x706e, 0x8004, 0x8004,
-	0x8004, 0x9084, 0x0003, 0x0002, 0x6d3b, 0x6e30, 0x6d56, 0x6dc3,
-	0x080c, 0x0dd5, 0x0005, 0x2071, 0x1800, 0x2900, 0x7822, 0xa804,
-	0x900d, 0x1120, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x9016, 0x702c,
-	0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e,
-	0x70c0, 0x9200, 0x70c2, 0x080c, 0x84c2, 0x0c60, 0x2071, 0x1800,
-	0x2900, 0x7822, 0xa804, 0x900d, 0x1904, 0x6db2, 0x7830, 0x8007,
-	0x9084, 0x001f, 0x9082, 0x0001, 0x1220, 0x00fe, 0x002e, 0x00ee,
-	0x0005, 0x7824, 0x00e6, 0x2071, 0x0040, 0x712c, 0xd19c, 0x1148,
-	0x2009, 0x1830, 0x210c, 0x918a, 0x0020, 0x0218, 0x7022, 0x00ee,
-	0x0058, 0x00ee, 0x2048, 0x702c, 0xa802, 0x2900, 0x702e, 0x70c0,
-	0x8000, 0x70c2, 0x080c, 0x84c2, 0x782c, 0x9094, 0x0780, 0x190c,
-	0x706e, 0xd0a4, 0x19f0, 0x0e04, 0x6da9, 0x7838, 0x7938, 0x910e,
-	0x1de0, 0x00d6, 0x2069, 0x0000, 0x6836, 0x6833, 0x0013, 0x00de,
-	0x2001, 0x1921, 0x200c, 0xc184, 0x2102, 0x2091, 0x4080, 0x2001,
-	0x0089, 0x2004, 0xd084, 0x190c, 0x119b, 0x00fe, 0x002e, 0x00ee,
-	0x0005, 0x2001, 0x1921, 0x200c, 0xc185, 0x2102, 0x00fe, 0x002e,
+	0x70c2, 0x080c, 0x85eb, 0x0c18, 0x2071, 0x1800, 0x2900, 0x7822,
+	0xa804, 0x900d, 0x1578, 0x7824, 0x00e6, 0x2071, 0x0040, 0x712c,
+	0xd19c, 0x1148, 0x2009, 0x1830, 0x210c, 0x918a, 0x0020, 0x0218,
+	0x7022, 0x00ee, 0x0058, 0x00ee, 0x2048, 0x702c, 0xa802, 0x2900,
+	0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c, 0x85eb, 0x782c, 0x9094,
+	0x0780, 0x190c, 0x715b, 0xd0a4, 0x19f0, 0x2071, 0x19fc, 0x7044,
+	0x9005, 0x1320, 0x2001, 0x194a, 0x2004, 0x7046, 0x00fe, 0x002e,
 	0x00ee, 0x0005, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210,
 	0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c,
-	0x84c2, 0x0804, 0x6d69, 0x0096, 0x00e6, 0x7824, 0x2048, 0x2071,
-	0x1800, 0x702c, 0xa802, 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2,
-	0x080c, 0x84c2, 0x782c, 0x9094, 0x0780, 0x190c, 0x706e, 0xd0a4,
-	0x1d60, 0x00ee, 0x0e04, 0x6e03, 0x7838, 0x7938, 0x910e, 0x1de0,
-	0x00d6, 0x2069, 0x0000, 0x6836, 0x6833, 0x0013, 0x00de, 0x7044,
-	0xc084, 0x7046, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084,
-	0x190c, 0x119b, 0x782c, 0x9094, 0x0780, 0x190c, 0x706e, 0xd09c,
-	0x1170, 0x009e, 0x2900, 0x7822, 0xa804, 0x900d, 0x11e0, 0x00fe,
-	0x002e, 0x00ee, 0x0005, 0x7044, 0xc085, 0x7046, 0x0c58, 0x009e,
-	0x2908, 0x7010, 0x8000, 0x7012, 0x7018, 0x904d, 0x711a, 0x0110,
-	0xa902, 0x0008, 0x711e, 0x2148, 0xa804, 0x900d, 0x1120, 0x00fe,
+	0x85eb, 0x0808, 0x0096, 0x00e6, 0x7824, 0x2048, 0x2071, 0x1800,
+	0x702c, 0xa802, 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c,
+	0x85eb, 0x782c, 0x9094, 0x0780, 0x190c, 0x715b, 0xd0a4, 0x1d60,
+	0x00ee, 0x782c, 0x9094, 0x0780, 0x190c, 0x715b, 0xd09c, 0x1198,
+	0x009e, 0x2900, 0x7822, 0xa804, 0x900d, 0x1550, 0x2071, 0x19fc,
+	0x7044, 0x9005, 0x1320, 0x2001, 0x194a, 0x2004, 0x7046, 0x00fe,
+	0x002e, 0x00ee, 0x0005, 0x009e, 0x2908, 0x7010, 0x8000, 0x7012,
+	0x7018, 0x904d, 0x711a, 0x0110, 0xa902, 0x0008, 0x711e, 0x2148,
+	0xa804, 0x900d, 0x1168, 0x2071, 0x19fc, 0x7044, 0x9005, 0x1320,
+	0x2001, 0x194a, 0x2004, 0x7046, 0x00fe, 0x002e, 0x00ee, 0x0005,
+	0x2071, 0x1800, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210,
+	0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c,
+	0x85eb, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x2908, 0x7010, 0x8000,
+	0x7012, 0x7018, 0x904d, 0x711a, 0x0110, 0xa902, 0x0008, 0x711e,
+	0x2148, 0xa804, 0x900d, 0x1904, 0x6da9, 0x782c, 0x9094, 0x0780,
+	0x190c, 0x715b, 0xd09c, 0x1198, 0x701c, 0x904d, 0x0180, 0x7010,
+	0x8001, 0x7012, 0x1108, 0x701a, 0xa800, 0x701e, 0x2900, 0x7822,
+	0x782c, 0x9094, 0x0780, 0x190c, 0x715b, 0xd09c, 0x0d68, 0x782c,
+	0x9094, 0x0780, 0x190c, 0x715b, 0xd0a4, 0x01b0, 0x00e6, 0x7824,
+	0x2048, 0x2071, 0x1800, 0x702c, 0xa802, 0x2900, 0x702e, 0x70c0,
+	0x8000, 0x70c2, 0x080c, 0x85eb, 0x782c, 0x9094, 0x0780, 0x190c,
+	0x715b, 0xd0a4, 0x1d60, 0x00ee, 0x2071, 0x19fc, 0x7044, 0x9005,
+	0x1320, 0x2001, 0x194a, 0x2004, 0x7046, 0x00fe, 0x002e, 0x00ee,
+	0x0005, 0x00e6, 0x2071, 0x1800, 0x9016, 0x702c, 0x2148, 0xa904,
+	0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200,
+	0x70c2, 0x080c, 0x85eb, 0x00ee, 0x0804, 0x6d65, 0xa868, 0xd0fc,
+	0x1904, 0x6e1f, 0x0096, 0xa804, 0xa807, 0x0000, 0x904d, 0x190c,
+	0x0fc0, 0x009e, 0x0020, 0xa868, 0xd0fc, 0x1904, 0x6e1f, 0x00e6,
+	0x0026, 0xa84f, 0x0000, 0x00f6, 0x2079, 0x0050, 0x2071, 0x1800,
+	0x70ec, 0x8001, 0x0558, 0x1a04, 0x6e1c, 0x2071, 0x1910, 0xa803,
+	0x0000, 0xa864, 0x9084, 0x00ff, 0x908e, 0x0016, 0x01a8, 0x7010,
+	0x9005, 0x1904, 0x6f1b, 0x782c, 0x908c, 0x0780, 0x190c, 0x715b,
+	0x8004, 0x8004, 0x8004, 0x9084, 0x0003, 0x0002, 0x6e20, 0x6f1b,
+	0x6e3b, 0x6eac, 0x080c, 0x0dc5, 0x2009, 0x1949, 0x2104, 0x0002,
+	0x6de7, 0x6de7, 0x6de7, 0x6c73, 0x6de7, 0x6c73, 0x70ef, 0x0fa0,
+	0x71e8, 0x8107, 0x9106, 0x9094, 0x00c0, 0x9184, 0xff3f, 0x9205,
+	0x70ea, 0x3b08, 0x3a00, 0x9104, 0x918d, 0x00c0, 0x21d8, 0x9084,
+	0xff3f, 0x9205, 0x20d0, 0x0808, 0x70ee, 0x0804, 0x6ddd, 0x0005,
+	0x2071, 0x1800, 0x2900, 0x7822, 0xa804, 0x900d, 0x1120, 0x00fe,
+	0x002e, 0x00ee, 0x0005, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802,
+	0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2,
+	0x080c, 0x85eb, 0x0c60, 0x2071, 0x1800, 0x2900, 0x7822, 0xa804,
+	0x900d, 0x1904, 0x6e9b, 0x7830, 0x8007, 0x908c, 0x001f, 0x70f0,
+	0x9102, 0x1220, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x7824, 0x00e6,
+	0x2071, 0x0040, 0x712c, 0xd19c, 0x1148, 0x2009, 0x1830, 0x210c,
+	0x918a, 0x0020, 0x0218, 0x7022, 0x00ee, 0x0058, 0x00ee, 0x2048,
+	0x702c, 0xa802, 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c,
+	0x85eb, 0x782c, 0x9094, 0x0780, 0x190c, 0x715b, 0xd0a4, 0x19f0,
+	0x0e04, 0x6e92, 0x7838, 0x7938, 0x910e, 0x1de0, 0x00d6, 0x2069,
+	0x0000, 0x6836, 0x6833, 0x0013, 0x00de, 0x2001, 0x1921, 0x200c,
+	0xc184, 0x2102, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084,
+	0x190c, 0x11aa, 0x2001, 0x1922, 0x2003, 0x0000, 0x00fe, 0x002e,
+	0x00ee, 0x0005, 0x2001, 0x1921, 0x200c, 0xc185, 0x2102, 0x00fe,
+	0x002e, 0x00ee, 0x0005, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802,
+	0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2,
+	0x080c, 0x85eb, 0x0804, 0x6e4e, 0x0096, 0x00e6, 0x7824, 0x2048,
+	0x2071, 0x1800, 0x702c, 0xa802, 0x2900, 0x702e, 0x70c0, 0x8000,
+	0x70c2, 0x080c, 0x85eb, 0x782c, 0x9094, 0x0780, 0x190c, 0x715b,
+	0xd0a4, 0x1d60, 0x00ee, 0x0e04, 0x6eee, 0x7838, 0x7938, 0x910e,
+	0x1de0, 0x00d6, 0x2069, 0x0000, 0x6836, 0x6833, 0x0013, 0x00de,
+	0x7044, 0xc084, 0x7046, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004,
+	0xd084, 0x190c, 0x11aa, 0x704b, 0x0000, 0x782c, 0x9094, 0x0780,
+	0x190c, 0x715b, 0xd09c, 0x1170, 0x009e, 0x2900, 0x7822, 0xa804,
+	0x900d, 0x11e0, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x7044, 0xc085,
+	0x7046, 0x0c58, 0x009e, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018,
+	0x904d, 0x711a, 0x0110, 0xa902, 0x0008, 0x711e, 0x2148, 0xa804,
+	0x900d, 0x1120, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x2071, 0x1800,
+	0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff,
+	0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x85eb, 0x00fe,
+	0x002e, 0x00ee, 0x0005, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018,
+	0x904d, 0x711a, 0x0110, 0xa902, 0x0008, 0x711e, 0x2148, 0xa804,
+	0x900d, 0x1904, 0x6f8a, 0x782c, 0x9094, 0x0780, 0x190c, 0x715b,
+	0xd09c, 0x11b0, 0x701c, 0x904d, 0x0198, 0xa84c, 0x9005, 0x1180,
+	0x7010, 0x8001, 0x7012, 0x1108, 0x701a, 0xa800, 0x701e, 0x2900,
+	0x7822, 0x782c, 0x9094, 0x0780, 0x190c, 0x715b, 0xd09c, 0x0d50,
+	0x782c, 0x9094, 0x0780, 0x190c, 0x715b, 0xd0a4, 0x05b8, 0x00e6,
+	0x7824, 0x2048, 0x2071, 0x1800, 0x702c, 0xa802, 0x2900, 0x702e,
+	0x70c0, 0x8000, 0x70c2, 0x080c, 0x85eb, 0x782c, 0x9094, 0x0780,
+	0x190c, 0x715b, 0xd0a4, 0x1d60, 0x00ee, 0x0e04, 0x6f83, 0x7838,
+	0x7938, 0x910e, 0x1de0, 0x00d6, 0x2069, 0x0000, 0x6836, 0x6833,
+	0x0013, 0x00de, 0x7044, 0xc084, 0x7046, 0x2091, 0x4080, 0x2001,
+	0x0089, 0x2004, 0xd084, 0x190c, 0x11aa, 0x704b, 0x0000, 0x00fe,
+	0x002e, 0x00ee, 0x0005, 0x7044, 0xc085, 0x7046, 0x00fe, 0x002e,
+	0x00ee, 0x0005, 0x00e6, 0x2071, 0x1800, 0x9016, 0x702c, 0x2148,
+	0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70c0,
+	0x9200, 0x70c2, 0x080c, 0x85eb, 0x00ee, 0x0804, 0x6f2b, 0x2071,
+	0x1910, 0xa803, 0x0000, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018,
+	0x904d, 0x711a, 0x0110, 0xa902, 0x0008, 0x711e, 0x2148, 0xa804,
+	0x900d, 0x1128, 0x1e04, 0x6fca, 0x002e, 0x00ee, 0x0005, 0x2071,
+	0x1800, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900,
+	0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x85eb,
+	0x0e04, 0x6fb4, 0x2071, 0x1910, 0x701c, 0x2048, 0xa84c, 0x900d,
+	0x0d18, 0x2071, 0x0000, 0x7182, 0xa850, 0x7032, 0xa86c, 0x7086,
+	0x7036, 0xa870, 0x708a, 0xa850, 0x9082, 0x0019, 0x1278, 0x2091,
+	0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11aa, 0x2071,
+	0x1910, 0x080c, 0x7147, 0x002e, 0x00ee, 0x0005, 0xa850, 0x9082,
+	0x001c, 0x1e68, 0xa880, 0x708e, 0x7036, 0x0146, 0x01d6, 0x0136,
+	0x01c6, 0x0156, 0x20e9, 0x0000, 0x20a1, 0x002a, 0xa868, 0x20a8,
+	0xa860, 0x20e0, 0xa85c, 0x9080, 0x0021, 0x2098, 0x4003, 0x015e,
+	0x01ce, 0x013e, 0x01de, 0x014e, 0x0890, 0x2071, 0x1910, 0xa803,
+	0x0000, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018, 0x904d, 0x711a,
+	0x0110, 0xa902, 0x0008, 0x711e, 0x2148, 0xa804, 0x900d, 0x1118,
 	0x002e, 0x00ee, 0x0005, 0x2071, 0x1800, 0x9016, 0x702c, 0x2148,
 	0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70c0,
-	0x9200, 0x70c2, 0x080c, 0x84c2, 0x00fe, 0x002e, 0x00ee, 0x0005,
-	0x2908, 0x7010, 0x8000, 0x7012, 0x7018, 0x904d, 0x711a, 0x0110,
-	0xa902, 0x0008, 0x711e, 0x2148, 0xa804, 0x900d, 0x1904, 0x6e9d,
-	0x782c, 0x9094, 0x0780, 0x190c, 0x706e, 0xd09c, 0x11b0, 0x701c,
-	0x904d, 0x0198, 0xa84c, 0x9005, 0x1180, 0x7010, 0x8001, 0x7012,
-	0x1108, 0x701a, 0xa800, 0x701e, 0x2900, 0x7822, 0x782c, 0x9094,
-	0x0780, 0x190c, 0x706e, 0xd09c, 0x0d50, 0x782c, 0x9094, 0x0780,
-	0x190c, 0x706e, 0xd0a4, 0x05a8, 0x00e6, 0x7824, 0x2048, 0x2071,
-	0x1800, 0x702c, 0xa802, 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2,
-	0x080c, 0x84c2, 0x782c, 0x9094, 0x0780, 0x190c, 0x706e, 0xd0a4,
-	0x1d60, 0x00ee, 0x0e04, 0x6e96, 0x7838, 0x7938, 0x910e, 0x1de0,
-	0x00d6, 0x2069, 0x0000, 0x6836, 0x6833, 0x0013, 0x00de, 0x7044,
-	0xc084, 0x7046, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084,
-	0x190c, 0x119b, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x7044, 0xc085,
-	0x7046, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x00e6, 0x2071, 0x1800,
-	0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff,
-	0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x84c2, 0x00ee,
-	0x0804, 0x6e40, 0x2071, 0x1910, 0xa803, 0x0000, 0x2908, 0x7010,
-	0x8000, 0x7012, 0x7018, 0x904d, 0x711a, 0x0110, 0xa902, 0x0008,
-	0x711e, 0x2148, 0xa804, 0x900d, 0x1128, 0x1e04, 0x6edd, 0x002e,
-	0x00ee, 0x0005, 0x2071, 0x1800, 0x9016, 0x702c, 0x2148, 0xa904,
-	0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200,
-	0x70c2, 0x080c, 0x84c2, 0x0e04, 0x6ec7, 0x2071, 0x1910, 0x701c,
-	0x2048, 0xa84c, 0x900d, 0x0d18, 0x2071, 0x0000, 0x7182, 0xa850,
+	0x9200, 0x70c2, 0x080c, 0x85eb, 0x002e, 0x00ee, 0x0005, 0x0006,
+	0xa87c, 0x0006, 0xa867, 0x0103, 0x20a9, 0x001c, 0xa860, 0x20e8,
+	0xa85c, 0x9080, 0x001d, 0x20a0, 0x9006, 0x4004, 0x000e, 0x9084,
+	0x00ff, 0xa87e, 0x000e, 0xa87a, 0xa982, 0x0005, 0x2071, 0x1910,
+	0x7004, 0x0002, 0x705a, 0x705b, 0x7146, 0x705b, 0x7058, 0x7146,
+	0x080c, 0x0dc5, 0x0005, 0x2001, 0x1949, 0x2004, 0x0002, 0x7065,
+	0x7065, 0x70df, 0x70e0, 0x7065, 0x70e0, 0x0126, 0x2091, 0x8000,
+	0x1e0c, 0x7166, 0x701c, 0x904d, 0x0508, 0xa84c, 0x9005, 0x0904,
+	0x70b0, 0x0e04, 0x708e, 0xa94c, 0x2071, 0x0000, 0x7182, 0xa850,
 	0x7032, 0xa86c, 0x7086, 0x7036, 0xa870, 0x708a, 0xa850, 0x9082,
 	0x0019, 0x1278, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084,
-	0x190c, 0x119b, 0x2071, 0x1910, 0x080c, 0x705a, 0x002e, 0x00ee,
-	0x0005, 0xa850, 0x9082, 0x001c, 0x1e68, 0xa880, 0x708e, 0x7036,
+	0x190c, 0x11aa, 0x2071, 0x1910, 0x080c, 0x7147, 0x012e, 0x0804,
+	0x70de, 0xa850, 0x9082, 0x001c, 0x1e68, 0xa880, 0x708e, 0x7036,
 	0x0146, 0x01d6, 0x0136, 0x01c6, 0x0156, 0x20e9, 0x0000, 0x20a1,
 	0x002a, 0xa868, 0x20a8, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0021,
 	0x2098, 0x4003, 0x015e, 0x01ce, 0x013e, 0x01de, 0x014e, 0x0890,
-	0x2071, 0x1910, 0xa803, 0x0000, 0x2908, 0x7010, 0x8000, 0x7012,
-	0x7018, 0x904d, 0x711a, 0x0110, 0xa902, 0x0008, 0x711e, 0x2148,
-	0xa804, 0x900d, 0x1118, 0x002e, 0x00ee, 0x0005, 0x2071, 0x1800,
-	0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff,
-	0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x84c2, 0x002e,
-	0x00ee, 0x0005, 0x0006, 0xa87c, 0x0006, 0xa867, 0x0103, 0x20a9,
-	0x001c, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x001d, 0x20a0, 0x9006,
-	0x4004, 0x000e, 0x9084, 0x00ff, 0xa87e, 0x000e, 0xa87a, 0xa982,
-	0x0005, 0x2071, 0x1910, 0x7004, 0x0002, 0x6f6d, 0x6f6e, 0x7059,
-	0x6f6e, 0x6f6b, 0x7059, 0x080c, 0x0dd5, 0x0005, 0x2001, 0x1947,
-	0x2004, 0x0002, 0x6f78, 0x6f78, 0x6ff2, 0x6ff3, 0x6f78, 0x6ff3,
-	0x0126, 0x2091, 0x8000, 0x1e0c, 0x7079, 0x701c, 0x904d, 0x0508,
-	0xa84c, 0x9005, 0x0904, 0x6fc3, 0x0e04, 0x6fa1, 0xa94c, 0x2071,
-	0x0000, 0x7182, 0xa850, 0x7032, 0xa86c, 0x7086, 0x7036, 0xa870,
-	0x708a, 0xa850, 0x9082, 0x0019, 0x1278, 0x2091, 0x4080, 0x2001,
-	0x0089, 0x2004, 0xd084, 0x190c, 0x119b, 0x2071, 0x1910, 0x080c,
-	0x705a, 0x012e, 0x0804, 0x6ff1, 0xa850, 0x9082, 0x001c, 0x1e68,
-	0xa880, 0x708e, 0x7036, 0x0146, 0x01d6, 0x0136, 0x01c6, 0x0156,
-	0x20e9, 0x0000, 0x20a1, 0x002a, 0xa868, 0x20a8, 0xa860, 0x20e0,
-	0xa85c, 0x9080, 0x0021, 0x2098, 0x4003, 0x015e, 0x01ce, 0x013e,
-	0x01de, 0x014e, 0x0890, 0x2001, 0x005b, 0x2004, 0x9094, 0x0780,
-	0x190c, 0x706e, 0xd09c, 0x2071, 0x1910, 0x1510, 0x2071, 0x1910,
-	0x700f, 0x0001, 0xa964, 0x9184, 0x00ff, 0x9086, 0x0003, 0x1130,
-	0x810f, 0x918c, 0x00ff, 0x8101, 0x0108, 0x710e, 0x2900, 0x00d6,
-	0x2069, 0x0050, 0x6822, 0x00de, 0x2071, 0x1910, 0x701c, 0x2048,
-	0x7010, 0x8001, 0x7012, 0xa800, 0x701e, 0x9005, 0x1108, 0x701a,
-	0x012e, 0x0005, 0x0005, 0x00d6, 0x2008, 0x2069, 0x19f9, 0x683c,
-	0x9005, 0x0760, 0x0158, 0x9186, 0x0003, 0x0540, 0x2001, 0x1815,
-	0x2004, 0x2009, 0x1aca, 0x210c, 0x9102, 0x1500, 0x0126, 0x2091,
-	0x8000, 0x2069, 0x0050, 0x693c, 0x6838, 0x9106, 0x0190, 0x0e04,
-	0x7025, 0x2069, 0x0000, 0x6837, 0x8040, 0x6833, 0x0012, 0x6883,
-	0x8040, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c,
-	0x119b, 0x2069, 0x19f9, 0x683f, 0xffff, 0x012e, 0x00de, 0x0126,
-	0x2091, 0x8000, 0x1e0c, 0x70da, 0x701c, 0x904d, 0x0540, 0x2001,
-	0x005b, 0x2004, 0x9094, 0x0780, 0x15c9, 0xd09c, 0x1500, 0x2071,
-	0x1910, 0x700f, 0x0001, 0xa964, 0x9184, 0x00ff, 0x9086, 0x0003,
-	0x1130, 0x810f, 0x918c, 0x00ff, 0x8101, 0x0108, 0x710e, 0x2900,
-	0x00d6, 0x2069, 0x0050, 0x6822, 0x00de, 0x701c, 0x2048, 0x7010,
-	0x8001, 0x7012, 0xa800, 0x701e, 0x9005, 0x1108, 0x701a, 0x012e,
-	0x0005, 0x0005, 0x0126, 0x2091, 0x8000, 0x701c, 0x904d, 0x0160,
-	0x7010, 0x8001, 0x7012, 0xa800, 0x701e, 0x9005, 0x1108, 0x701a,
-	0x012e, 0x080c, 0x1031, 0x0005, 0x012e, 0x0005, 0x2091, 0x8000,
-	0x0e04, 0x7070, 0x0006, 0x0016, 0x2001, 0x8004, 0x0006, 0x0804,
-	0x0dde, 0x0096, 0x00f6, 0x2079, 0x0050, 0x7044, 0xd084, 0x01c0,
-	0xc084, 0x7046, 0x7838, 0x7938, 0x910e, 0x1de0, 0x00d6, 0x2069,
-	0x0000, 0x6836, 0x6833, 0x0013, 0x00de, 0x2091, 0x4080, 0x2001,
-	0x0089, 0x2004, 0xd084, 0x190c, 0x119b, 0x00fe, 0x009e, 0x0005,
-	0x782c, 0x9094, 0x0780, 0x1991, 0xd0a4, 0x0db8, 0x00e6, 0x2071,
-	0x1800, 0x7824, 0x00e6, 0x2071, 0x0040, 0x712c, 0xd19c, 0x1148,
-	0x2009, 0x1830, 0x210c, 0x918a, 0x0020, 0x0218, 0x7022, 0x00ee,
-	0x0058, 0x00ee, 0x2048, 0x702c, 0xa802, 0x2900, 0x702e, 0x70c0,
-	0x8000, 0x70c2, 0x080c, 0x84c2, 0x782c, 0x9094, 0x0780, 0x190c,
-	0x706e, 0xd0a4, 0x19f0, 0x7838, 0x7938, 0x910e, 0x1de0, 0x00d6,
-	0x2069, 0x0000, 0x6836, 0x6833, 0x0013, 0x00de, 0x2091, 0x4080,
-	0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x119b, 0x00ee, 0x00fe,
-	0x009e, 0x0005, 0x00f6, 0x2079, 0x0050, 0x7044, 0xd084, 0x01b8,
-	0xc084, 0x7046, 0x7838, 0x7938, 0x910e, 0x1de0, 0x00d6, 0x2069,
-	0x0000, 0x6836, 0x6833, 0x0013, 0x00de, 0x2091, 0x4080, 0x2001,
-	0x0089, 0x2004, 0xd084, 0x190c, 0x119b, 0x00fe, 0x0005, 0x782c,
-	0x9094, 0x0780, 0x190c, 0x706e, 0xd0a4, 0x0db8, 0x00e6, 0x2071,
-	0x1800, 0x7824, 0x2048, 0x702c, 0xa802, 0x2900, 0x702e, 0x70c0,
-	0x8000, 0x70c2, 0x080c, 0x84c2, 0x782c, 0x9094, 0x0780, 0x190c,
-	0x706e, 0xd0a4, 0x1d70, 0x00d6, 0x2069, 0x0050, 0x693c, 0x2069,
-	0x1947, 0x6808, 0x690a, 0x2069, 0x19f9, 0x9102, 0x1118, 0x683c,
-	0x9005, 0x1328, 0x2001, 0x1948, 0x200c, 0x810d, 0x693e, 0x00de,
-	0x00ee, 0x00fe, 0x0005, 0x7098, 0x908a, 0x0029, 0x1a0c, 0x0dd5,
-	0x9082, 0x001d, 0x001b, 0x6027, 0x1e00, 0x0005, 0x7202, 0x7188,
-	0x71a4, 0x71ce, 0x71f1, 0x7231, 0x7243, 0x71a4, 0x7219, 0x7143,
-	0x7171, 0x7142, 0x0005, 0x00d6, 0x2069, 0x0200, 0x6804, 0x9005,
-	0x1180, 0x6808, 0x9005, 0x1518, 0x709b, 0x0028, 0x2069, 0x198e,
-	0x2d04, 0x7002, 0x080c, 0x7576, 0x6028, 0x9085, 0x0600, 0x602a,
-	0x00b0, 0x709b, 0x0028, 0x2069, 0x198e, 0x2d04, 0x7002, 0x6028,
-	0x9085, 0x0600, 0x602a, 0x00e6, 0x0036, 0x0046, 0x0056, 0x2071,
-	0x1a61, 0x080c, 0x1aec, 0x005e, 0x004e, 0x003e, 0x00ee, 0x00de,
-	0x0005, 0x00d6, 0x2069, 0x0200, 0x6804, 0x9005, 0x1178, 0x6808,
-	0x9005, 0x1160, 0x709b, 0x0028, 0x2069, 0x198e, 0x2d04, 0x7002,
-	0x080c, 0x7611, 0x6028, 0x9085, 0x0600, 0x602a, 0x00de, 0x0005,
-	0x0006, 0x2001, 0x0090, 0x080c, 0x2d4e, 0x000e, 0x6124, 0xd1e4,
-	0x1190, 0x080c, 0x72b0, 0xd1d4, 0x1160, 0xd1dc, 0x1138, 0xd1cc,
-	0x0150, 0x709b, 0x0020, 0x080c, 0x72b0, 0x0028, 0x709b, 0x001d,
-	0x0010, 0x709b, 0x001f, 0x0005, 0x2001, 0x0088, 0x080c, 0x2d4e,
-	0x6124, 0xd1cc, 0x11e8, 0xd1dc, 0x11c0, 0xd1e4, 0x1198, 0x9184,
-	0x1e00, 0x11d8, 0x080c, 0x1b11, 0x60e3, 0x0001, 0x600c, 0xc0b4,
-	0x600e, 0x080c, 0x746a, 0x2001, 0x0080, 0x080c, 0x2d4e, 0x709b,
-	0x0028, 0x0058, 0x709b, 0x001e, 0x0040, 0x709b, 0x001d, 0x0028,
-	0x709b, 0x0020, 0x0010, 0x709b, 0x001f, 0x0005, 0x080c, 0x1b11,
-	0x60e3, 0x0001, 0x600c, 0xc0b4, 0x600e, 0x080c, 0x746a, 0x2001,
-	0x0080, 0x080c, 0x2d4e, 0x6124, 0xd1d4, 0x1180, 0xd1dc, 0x1158,
-	0xd1e4, 0x1130, 0x9184, 0x1e00, 0x1158, 0x709b, 0x0028, 0x0040,
+	0x2001, 0x005b, 0x2004, 0x9094, 0x0780, 0x190c, 0x715b, 0xd09c,
+	0x2071, 0x1910, 0x1510, 0x2071, 0x1910, 0x700f, 0x0001, 0xa964,
+	0x9184, 0x00ff, 0x9086, 0x0003, 0x1130, 0x810f, 0x918c, 0x00ff,
+	0x8101, 0x0108, 0x710e, 0x2900, 0x00d6, 0x2069, 0x0050, 0x6822,
+	0x00de, 0x2071, 0x1910, 0x701c, 0x2048, 0x7010, 0x8001, 0x7012,
+	0xa800, 0x701e, 0x9005, 0x1108, 0x701a, 0x012e, 0x0005, 0x0005,
+	0x00d6, 0x2008, 0x2069, 0x19fc, 0x6844, 0x9005, 0x0760, 0x0158,
+	0x9186, 0x0003, 0x0540, 0x2001, 0x1815, 0x2004, 0x2009, 0x1ad2,
+	0x210c, 0x9102, 0x1500, 0x0126, 0x2091, 0x8000, 0x2069, 0x0050,
+	0x693c, 0x6838, 0x9106, 0x0190, 0x0e04, 0x7112, 0x2069, 0x0000,
+	0x6837, 0x8040, 0x6833, 0x0012, 0x6883, 0x8040, 0x2091, 0x4080,
+	0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11aa, 0x2069, 0x19fc,
+	0x6847, 0xffff, 0x012e, 0x00de, 0x0126, 0x2091, 0x8000, 0x1e0c,
+	0x71d1, 0x701c, 0x904d, 0x0540, 0x2001, 0x005b, 0x2004, 0x9094,
+	0x0780, 0x15c9, 0xd09c, 0x1500, 0x2071, 0x1910, 0x700f, 0x0001,
+	0xa964, 0x9184, 0x00ff, 0x9086, 0x0003, 0x1130, 0x810f, 0x918c,
+	0x00ff, 0x8101, 0x0108, 0x710e, 0x2900, 0x00d6, 0x2069, 0x0050,
+	0x6822, 0x00de, 0x701c, 0x2048, 0x7010, 0x8001, 0x7012, 0xa800,
+	0x701e, 0x9005, 0x1108, 0x701a, 0x012e, 0x0005, 0x0005, 0x0126,
+	0x2091, 0x8000, 0x701c, 0x904d, 0x0160, 0x7010, 0x8001, 0x7012,
+	0xa800, 0x701e, 0x9005, 0x1108, 0x701a, 0x012e, 0x080c, 0x1040,
+	0x0005, 0x012e, 0x0005, 0x2091, 0x8000, 0x0e04, 0x715d, 0x0006,
+	0x0016, 0x2001, 0x8004, 0x0006, 0x0804, 0x0dce, 0x0096, 0x00f6,
+	0x2079, 0x0050, 0x7044, 0xd084, 0x01d0, 0xc084, 0x7046, 0x7838,
+	0x7938, 0x910e, 0x1de0, 0x00d6, 0x2069, 0x0000, 0x6836, 0x6833,
+	0x0013, 0x00de, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084,
+	0x190c, 0x11aa, 0x704b, 0x0000, 0x00fe, 0x009e, 0x0005, 0x782c,
+	0x9094, 0x0780, 0x1981, 0xd0a4, 0x0db8, 0x7148, 0x704c, 0x8108,
+	0x714a, 0x9102, 0x0e88, 0x00e6, 0x2071, 0x1800, 0x7824, 0x00e6,
+	0x2071, 0x0040, 0x712c, 0xd19c, 0x1148, 0x2009, 0x1830, 0x210c,
+	0x918a, 0x0020, 0x0218, 0x7022, 0x00ee, 0x0058, 0x00ee, 0x2048,
+	0x702c, 0xa802, 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c,
+	0x85eb, 0x782c, 0x9094, 0x0780, 0x190c, 0x715b, 0xd0a4, 0x19f0,
+	0x7838, 0x7938, 0x910e, 0x1de0, 0x00d6, 0x2069, 0x0000, 0x6836,
+	0x6833, 0x0013, 0x00de, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004,
+	0xd084, 0x190c, 0x11aa, 0x00ee, 0x704b, 0x0000, 0x00fe, 0x009e,
+	0x0005, 0x00f6, 0x2079, 0x0050, 0x7044, 0xd084, 0x01b8, 0xc084,
+	0x7046, 0x7838, 0x7938, 0x910e, 0x1de0, 0x00d6, 0x2069, 0x0000,
+	0x6836, 0x6833, 0x0013, 0x00de, 0x2091, 0x4080, 0x2001, 0x0089,
+	0x2004, 0xd084, 0x190c, 0x11aa, 0x00fe, 0x0005, 0x782c, 0x9094,
+	0x0780, 0x190c, 0x715b, 0xd0a4, 0x0db8, 0x00e6, 0x2071, 0x1800,
+	0x7824, 0x2048, 0x702c, 0xa802, 0x2900, 0x702e, 0x70c0, 0x8000,
+	0x70c2, 0x080c, 0x85eb, 0x782c, 0x9094, 0x0780, 0x190c, 0x715b,
+	0xd0a4, 0x1d70, 0x00d6, 0x2069, 0x0050, 0x693c, 0x2069, 0x1949,
+	0x6808, 0x690a, 0x2069, 0x19fc, 0x9102, 0x1118, 0x6844, 0x9005,
+	0x1320, 0x2001, 0x194a, 0x200c, 0x6946, 0x00de, 0x00ee, 0x00fe,
+	0x0005, 0x7098, 0x908a, 0x002a, 0x1a0c, 0x0dc5, 0x9082, 0x001d,
+	0x001b, 0x6027, 0x1e00, 0x0005, 0x7312, 0x727f, 0x729b, 0x72c5,
+	0x7301, 0x7341, 0x7353, 0x729b, 0x7329, 0x723a, 0x7268, 0x72eb,
+	0x7239, 0x0005, 0x00d6, 0x2069, 0x0200, 0x6804, 0x9005, 0x1180,
+	0x6808, 0x9005, 0x1518, 0x709b, 0x0029, 0x2069, 0x1990, 0x2d04,
+	0x7002, 0x080c, 0x7698, 0x6028, 0x9085, 0x0600, 0x602a, 0x00b0,
+	0x709b, 0x0029, 0x2069, 0x1990, 0x2d04, 0x7002, 0x6028, 0x9085,
+	0x0600, 0x602a, 0x00e6, 0x0036, 0x0046, 0x0056, 0x2071, 0x1a66,
+	0x080c, 0x1b02, 0x005e, 0x004e, 0x003e, 0x00ee, 0x00de, 0x0005,
+	0x00d6, 0x2069, 0x0200, 0x6804, 0x9005, 0x1178, 0x6808, 0x9005,
+	0x1160, 0x709b, 0x0029, 0x2069, 0x1990, 0x2d04, 0x7002, 0x080c,
+	0x7735, 0x6028, 0x9085, 0x0600, 0x602a, 0x00de, 0x0005, 0x0006,
+	0x2001, 0x0090, 0x080c, 0x2d5b, 0x000e, 0x6124, 0xd1e4, 0x1190,
+	0x080c, 0x73c0, 0xd1d4, 0x1160, 0xd1dc, 0x1138, 0xd1cc, 0x0150,
+	0x709b, 0x0020, 0x080c, 0x73c0, 0x0028, 0x709b, 0x001d, 0x0010,
+	0x709b, 0x001f, 0x0005, 0x2001, 0x0088, 0x080c, 0x2d5b, 0x6124,
+	0xd1cc, 0x11e8, 0xd1dc, 0x11c0, 0xd1e4, 0x1198, 0x9184, 0x1e00,
+	0x11d8, 0x080c, 0x1b27, 0x60e3, 0x0001, 0x600c, 0xc0b4, 0x600e,
+	0x080c, 0x758f, 0x2001, 0x0080, 0x080c, 0x2d5b, 0x709b, 0x0029,
+	0x0058, 0x709b, 0x001e, 0x0040, 0x709b, 0x001d, 0x0028, 0x709b,
+	0x0020, 0x0010, 0x709b, 0x001f, 0x0005, 0x080c, 0x1b27, 0x60e3,
+	0x0001, 0x600c, 0xc0b4, 0x600e, 0x080c, 0x758f, 0x2001, 0x0080,
+	0x080c, 0x2d5b, 0x6124, 0xd1d4, 0x1198, 0xd1dc, 0x1170, 0xd1e4,
+	0x1148, 0x9184, 0x1e00, 0x1118, 0x709b, 0x0029, 0x0058, 0x709b,
+	0x0028, 0x0040, 0x709b, 0x001e, 0x0028, 0x709b, 0x001d, 0x0010,
+	0x709b, 0x001f, 0x0005, 0x6124, 0xd1d4, 0x1180, 0xd1dc, 0x1158,
+	0xd1e4, 0x1130, 0x9184, 0x1e00, 0x1158, 0x709b, 0x0029, 0x0040,
 	0x709b, 0x001e, 0x0028, 0x709b, 0x001d, 0x0010, 0x709b, 0x001f,
-	0x0005, 0x2001, 0x00a0, 0x080c, 0x2d4e, 0x6124, 0xd1dc, 0x1138,
-	0xd1e4, 0x0138, 0x080c, 0x1b11, 0x709b, 0x001e, 0x0010, 0x709b,
-	0x001d, 0x0005, 0x080c, 0x7333, 0x6124, 0xd1dc, 0x1188, 0x080c,
-	0x72b0, 0x0016, 0x080c, 0x1b11, 0x001e, 0xd1d4, 0x1128, 0xd1e4,
-	0x0138, 0x709b, 0x001e, 0x0020, 0x709b, 0x001f, 0x080c, 0x72b0,
-	0x0005, 0x0006, 0x2001, 0x00a0, 0x080c, 0x2d4e, 0x000e, 0x6124,
+	0x0005, 0x2001, 0x00a0, 0x080c, 0x2d5b, 0x6124, 0xd1dc, 0x1138,
+	0xd1e4, 0x0138, 0x080c, 0x1b27, 0x709b, 0x001e, 0x0010, 0x709b,
+	0x001d, 0x0005, 0x080c, 0x7443, 0x6124, 0xd1dc, 0x1188, 0x080c,
+	0x73c0, 0x0016, 0x080c, 0x1b27, 0x001e, 0xd1d4, 0x1128, 0xd1e4,
+	0x0138, 0x709b, 0x001e, 0x0020, 0x709b, 0x001f, 0x080c, 0x73c0,
+	0x0005, 0x0006, 0x2001, 0x00a0, 0x080c, 0x2d5b, 0x000e, 0x6124,
 	0xd1d4, 0x1160, 0xd1cc, 0x1150, 0xd1dc, 0x1128, 0xd1e4, 0x0140,
 	0x709b, 0x001e, 0x0028, 0x709b, 0x001d, 0x0010, 0x709b, 0x0021,
-	0x0005, 0x080c, 0x7333, 0x6124, 0xd1d4, 0x1150, 0xd1dc, 0x1128,
+	0x0005, 0x080c, 0x7443, 0x6124, 0xd1d4, 0x1150, 0xd1dc, 0x1128,
 	0xd1e4, 0x0140, 0x709b, 0x001e, 0x0028, 0x709b, 0x001d, 0x0010,
-	0x709b, 0x001f, 0x0005, 0x0006, 0x2001, 0x0090, 0x080c, 0x2d4e,
+	0x709b, 0x001f, 0x0005, 0x0006, 0x2001, 0x0090, 0x080c, 0x2d5b,
 	0x000e, 0x6124, 0xd1d4, 0x1178, 0xd1cc, 0x1150, 0xd1dc, 0x1128,
 	0xd1e4, 0x0158, 0x709b, 0x001e, 0x0040, 0x709b, 0x001d, 0x0028,
 	0x709b, 0x0020, 0x0010, 0x709b, 0x001f, 0x0005, 0x0016, 0x00c6,
 	0x00d6, 0x00e6, 0x0126, 0x2061, 0x0100, 0x2069, 0x0140, 0x2071,
-	0x1800, 0x2091, 0x8000, 0x080c, 0x743e, 0x11d8, 0x2001, 0x180c,
+	0x1800, 0x2091, 0x8000, 0x080c, 0x7563, 0x11d8, 0x2001, 0x180c,
 	0x200c, 0xd1b4, 0x01b0, 0xc1b4, 0x2102, 0x6027, 0x0200, 0x080c,
-	0x2c76, 0x6024, 0xd0cc, 0x0148, 0x2001, 0x00a0, 0x080c, 0x2d4e,
-	0x080c, 0x7724, 0x080c, 0x60ad, 0x0428, 0x6028, 0xc0cd, 0x602a,
-	0x0408, 0x080c, 0x7458, 0x0150, 0x080c, 0x744f, 0x1138, 0x2001,
-	0x0001, 0x080c, 0x2828, 0x080c, 0x7416, 0x00a0, 0x080c, 0x7330,
-	0x0178, 0x2001, 0x0001, 0x080c, 0x2828, 0x7098, 0x9086, 0x001e,
+	0x2c83, 0x6024, 0xd0cc, 0x0148, 0x2001, 0x00a0, 0x080c, 0x2d5b,
+	0x080c, 0x7848, 0x080c, 0x6121, 0x0428, 0x6028, 0xc0cd, 0x602a,
+	0x0408, 0x080c, 0x757d, 0x0150, 0x080c, 0x7574, 0x1138, 0x2001,
+	0x0001, 0x080c, 0x2832, 0x080c, 0x753b, 0x00a0, 0x080c, 0x7440,
+	0x0178, 0x2001, 0x0001, 0x080c, 0x2832, 0x7098, 0x9086, 0x001e,
 	0x0120, 0x7098, 0x9086, 0x0022, 0x1118, 0x709b, 0x0025, 0x0010,
 	0x709b, 0x0021, 0x012e, 0x00ee, 0x00de, 0x00ce, 0x001e, 0x0005,
-	0x0026, 0x2011, 0x72c1, 0x080c, 0x868a, 0x002e, 0x0016, 0x0026,
-	0x2009, 0x0064, 0x2011, 0x72c1, 0x080c, 0x8681, 0x002e, 0x001e,
-	0x0005, 0x00e6, 0x00f6, 0x0016, 0x080c, 0xa356, 0x2071, 0x1800,
-	0x080c, 0x725e, 0x001e, 0x00fe, 0x00ee, 0x0005, 0x0016, 0x0026,
-	0x0036, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x0126, 0x080c, 0xa356,
-	0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0x1800, 0x2091, 0x8000,
-	0x6028, 0xc09c, 0x602a, 0x2011, 0x0003, 0x080c, 0xa722, 0x2011,
-	0x0002, 0x080c, 0xa72c, 0x080c, 0xa636, 0x080c, 0x8636, 0x0036,
-	0x901e, 0x080c, 0xa6ac, 0x003e, 0x60e3, 0x0000, 0x080c, 0xeb79,
-	0x080c, 0xeb94, 0x2009, 0x0004, 0x080c, 0x2c7c, 0x080c, 0x2b97,
-	0x2001, 0x1800, 0x2003, 0x0004, 0x6027, 0x0008, 0x2011, 0x72c1,
-	0x080c, 0x868a, 0x080c, 0x7458, 0x0118, 0x9006, 0x080c, 0x2d4e,
-	0x080c, 0x0bae, 0x2001, 0x0001, 0x080c, 0x2828, 0x012e, 0x00fe,
+	0x0026, 0x2011, 0x73d1, 0x080c, 0x87dd, 0x002e, 0x0016, 0x0026,
+	0x2009, 0x0064, 0x2011, 0x73d1, 0x080c, 0x87d4, 0x002e, 0x001e,
+	0x0005, 0x00e6, 0x00f6, 0x0016, 0x080c, 0xa4fd, 0x2071, 0x1800,
+	0x080c, 0x736e, 0x001e, 0x00fe, 0x00ee, 0x0005, 0x0016, 0x0026,
+	0x0036, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x0126, 0x2071, 0x1800,
+	0x080c, 0xa4fd, 0x2061, 0x0100, 0x2069, 0x0140, 0x2091, 0x8000,
+	0x6028, 0xc09c, 0x602a, 0x2011, 0x0003, 0x080c, 0xa8d3, 0x2011,
+	0x0002, 0x080c, 0xa8dd, 0x080c, 0xa7e7, 0x080c, 0x8789, 0x0036,
+	0x901e, 0x080c, 0xa85d, 0x003e, 0x60e3, 0x0000, 0x080c, 0xed95,
+	0x080c, 0xedb0, 0x2009, 0x0004, 0x080c, 0x2c89, 0x080c, 0x2ba4,
+	0x2001, 0x1800, 0x2003, 0x0004, 0x6027, 0x0008, 0x2011, 0x73d1,
+	0x080c, 0x87dd, 0x080c, 0x757d, 0x0118, 0x9006, 0x080c, 0x2d5b,
+	0x080c, 0x0ba0, 0x2001, 0x0001, 0x080c, 0x2832, 0x012e, 0x00fe,
 	0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e, 0x001e, 0x0005, 0x0026,
-	0x00e6, 0x2011, 0x72ce, 0x2071, 0x19f9, 0x701c, 0x9206, 0x1118,
+	0x00e6, 0x2011, 0x73de, 0x2071, 0x19fc, 0x701c, 0x9206, 0x1118,
 	0x7018, 0x9005, 0x0110, 0x9085, 0x0001, 0x00ee, 0x002e, 0x0005,
 	0x6020, 0xd09c, 0x0005, 0x6800, 0x9084, 0xfffe, 0x9086, 0x00c0,
-	0x0170, 0x2001, 0x00c0, 0x080c, 0x2d4e, 0x0156, 0x20a9, 0x002d,
-	0x1d04, 0x7340, 0x2091, 0x6000, 0x1f04, 0x7340, 0x015e, 0x0005,
-	0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2069, 0x0140, 0x2071,
-	0x1800, 0x080c, 0x7733, 0x2001, 0x196c, 0x2003, 0x0000, 0x9006,
-	0x709a, 0x60e2, 0x6886, 0x080c, 0x28f0, 0x9006, 0x080c, 0x2d4e,
-	0x080c, 0x5f6c, 0x6027, 0xffff, 0x602b, 0x182f, 0x00ee, 0x00de,
-	0x00ce, 0x0005, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2069,
-	0x0140, 0x2071, 0x1800, 0x2001, 0x197c, 0x200c, 0x9186, 0x0000,
-	0x0158, 0x9186, 0x0001, 0x0158, 0x9186, 0x0002, 0x0158, 0x9186,
-	0x0003, 0x0158, 0x0804, 0x7406, 0x709b, 0x0022, 0x0040, 0x709b,
-	0x0021, 0x0028, 0x709b, 0x0023, 0x0010, 0x709b, 0x0024, 0x60e3,
-	0x0000, 0x6887, 0x0001, 0x2001, 0x0001, 0x080c, 0x28f0, 0x0026,
-	0x080c, 0xaeb4, 0x002e, 0x7000, 0x908e, 0x0004, 0x0118, 0x602b,
-	0x0028, 0x0010, 0x602b, 0x0020, 0x0156, 0x0126, 0x2091, 0x8000,
-	0x20a9, 0x0005, 0x6024, 0xd0ac, 0x0150, 0x012e, 0x015e, 0x080c,
-	0xd388, 0x0118, 0x9006, 0x080c, 0x2d78, 0x0804, 0x7412, 0x6800,
-	0x9084, 0x00a1, 0xc0bd, 0x6802, 0x080c, 0x2c76, 0x6904, 0xd1d4,
-	0x1140, 0x2001, 0x0100, 0x080c, 0x2d4e, 0x1f04, 0x73aa, 0x080c,
-	0x7495, 0x012e, 0x015e, 0x080c, 0x744f, 0x01d8, 0x6044, 0x9005,
-	0x0198, 0x2011, 0x0114, 0x2204, 0x9085, 0x0100, 0x2012, 0x6050,
-	0x0006, 0x9085, 0x0020, 0x6052, 0x080c, 0x7495, 0x9006, 0x8001,
-	0x1df0, 0x000e, 0x6052, 0x0028, 0x6804, 0xd0d4, 0x1110, 0x080c,
-	0x7495, 0x080c, 0xd388, 0x0118, 0x9006, 0x080c, 0x2d78, 0x0016,
-	0x0026, 0x7000, 0x908e, 0x0004, 0x0130, 0x2009, 0x00c8, 0x2011,
-	0x72ce, 0x080c, 0x8648, 0x002e, 0x001e, 0x080c, 0x84b9, 0x7034,
-	0xc085, 0x7036, 0x2001, 0x197c, 0x2003, 0x0004, 0x080c, 0x712b,
-	0x080c, 0x744f, 0x0138, 0x6804, 0xd0d4, 0x1120, 0xd0dc, 0x1100,
-	0x080c, 0x7729, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x00c6, 0x00d6,
-	0x00e6, 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0x1800, 0x080c,
-	0x84d0, 0x080c, 0x84c2, 0x080c, 0x7733, 0x2001, 0x196c, 0x2003,
-	0x0000, 0x9006, 0x709a, 0x60e2, 0x6886, 0x080c, 0x28f0, 0x9006,
-	0x080c, 0x2d4e, 0x6043, 0x0090, 0x6043, 0x0010, 0x6027, 0xffff,
-	0x602b, 0x182f, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x0006, 0x2001,
-	0x197b, 0x2004, 0x9086, 0xaaaa, 0x000e, 0x0005, 0x0006, 0x080c,
-	0x5761, 0x9084, 0x0030, 0x9086, 0x0000, 0x000e, 0x0005, 0x0006,
-	0x080c, 0x5761, 0x9084, 0x0030, 0x9086, 0x0030, 0x000e, 0x0005,
-	0x0006, 0x080c, 0x5761, 0x9084, 0x0030, 0x9086, 0x0010, 0x000e,
-	0x0005, 0x0006, 0x080c, 0x5761, 0x9084, 0x0030, 0x9086, 0x0020,
-	0x000e, 0x0005, 0x0036, 0x0016, 0x2001, 0x180c, 0x2004, 0x908c,
-	0x0013, 0x0180, 0x0020, 0x080c, 0x2910, 0x900e, 0x0028, 0x080c,
-	0x6a04, 0x1dc8, 0x2009, 0x0002, 0x2019, 0x0028, 0x080c, 0x31e9,
-	0x9006, 0x0019, 0x001e, 0x003e, 0x0005, 0x00e6, 0x2071, 0x180c,
-	0x2e04, 0x0130, 0x080c, 0xd381, 0x1128, 0x9085, 0x0010, 0x0010,
-	0x9084, 0xffef, 0x2072, 0x00ee, 0x0005, 0x6050, 0x0006, 0x60ec,
-	0x0006, 0x600c, 0x0006, 0x6004, 0x0006, 0x6028, 0x0006, 0x0016,
-	0x6138, 0x6050, 0x9084, 0xfbff, 0x9085, 0x2000, 0x6052, 0x613a,
-	0x20a9, 0x0012, 0x1d04, 0x74aa, 0x2091, 0x6000, 0x1f04, 0x74aa,
-	0x602f, 0x0100, 0x602f, 0x0000, 0x6050, 0x9085, 0x0400, 0x9084,
-	0xdfff, 0x6052, 0x613a, 0x001e, 0x602f, 0x0040, 0x602f, 0x0000,
-	0x000e, 0x602a, 0x000e, 0x6006, 0x000e, 0x600e, 0x000e, 0x60ee,
-	0x60e3, 0x0000, 0x6887, 0x0001, 0x2001, 0x0001, 0x080c, 0x28f0,
-	0x2001, 0x00a0, 0x0006, 0x080c, 0xd388, 0x000e, 0x0130, 0x080c,
-	0x2d6c, 0x9006, 0x080c, 0x2d78, 0x0010, 0x080c, 0x2d4e, 0x000e,
-	0x6052, 0x6050, 0x0006, 0xc0e5, 0x6052, 0x00f6, 0x2079, 0x0100,
-	0x080c, 0x2beb, 0x00fe, 0x000e, 0x6052, 0x0005, 0x0156, 0x0016,
-	0x0026, 0x0036, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2069,
-	0x0140, 0x2071, 0x1800, 0x6020, 0x9084, 0x0080, 0x0138, 0x2001,
-	0x180c, 0x200c, 0xc1c5, 0x2102, 0x0804, 0x7568, 0x2001, 0x180c,
-	0x200c, 0xc1c4, 0x2102, 0x6028, 0x9084, 0xe1ff, 0x602a, 0x6027,
-	0x0200, 0x2001, 0x0090, 0x080c, 0x2d4e, 0x20a9, 0x0366, 0x6024,
-	0xd0cc, 0x1518, 0x1d04, 0x7517, 0x2091, 0x6000, 0x1f04, 0x7517,
-	0x2011, 0x0003, 0x080c, 0xa722, 0x2011, 0x0002, 0x080c, 0xa72c,
-	0x080c, 0xa636, 0x901e, 0x080c, 0xa6ac, 0x2001, 0x00a0, 0x080c,
-	0x2d4e, 0x080c, 0x7724, 0x080c, 0x60ad, 0x080c, 0xd388, 0x0110,
-	0x080c, 0x0d45, 0x9085, 0x0001, 0x0488, 0x080c, 0x1b11, 0x60e3,
-	0x0000, 0x2001, 0x196c, 0x2004, 0x080c, 0x28f0, 0x60e2, 0x2001,
-	0x0080, 0x080c, 0x2d4e, 0x20a9, 0x0366, 0x6027, 0x1e00, 0x2009,
-	0x1e00, 0x080c, 0x2c76, 0x6024, 0x910c, 0x0138, 0x1d04, 0x754d,
-	0x2091, 0x6000, 0x1f04, 0x754d, 0x0818, 0x6028, 0x9085, 0x1e00,
-	0x602a, 0x70b4, 0x9005, 0x1118, 0x6887, 0x0001, 0x0008, 0x6886,
-	0x080c, 0xd388, 0x0110, 0x080c, 0x0d45, 0x9006, 0x00ee, 0x00de,
-	0x00ce, 0x003e, 0x002e, 0x001e, 0x015e, 0x0005, 0x0156, 0x0016,
-	0x0026, 0x0036, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2071,
-	0x1800, 0x7000, 0x9086, 0x0003, 0x1168, 0x2001, 0x020b, 0x2004,
-	0x9084, 0x5540, 0x9086, 0x5540, 0x1128, 0x2069, 0x1a78, 0x2d04,
-	0x8000, 0x206a, 0x2069, 0x0140, 0x6020, 0x9084, 0x00c0, 0x0120,
-	0x6884, 0x9005, 0x1904, 0x75db, 0x2001, 0x0088, 0x080c, 0x2d4e,
-	0x9006, 0x60e2, 0x6886, 0x080c, 0x28f0, 0x2069, 0x0200, 0x6804,
-	0x9005, 0x1118, 0x6808, 0x9005, 0x01c0, 0x6028, 0x9084, 0xfbff,
-	0x602a, 0x6027, 0x0400, 0x2069, 0x198e, 0x7000, 0x206a, 0x709b,
-	0x0026, 0x7003, 0x0001, 0x20a9, 0x0002, 0x1d04, 0x75bd, 0x2091,
-	0x6000, 0x1f04, 0x75bd, 0x0804, 0x7609, 0x2069, 0x0140, 0x20a9,
-	0x0384, 0x6027, 0x1e00, 0x2009, 0x1e00, 0x080c, 0x2c76, 0x6024,
-	0x910c, 0x0508, 0x9084, 0x1a00, 0x11f0, 0x1d04, 0x75c9, 0x2091,
-	0x6000, 0x1f04, 0x75c9, 0x2011, 0x0003, 0x080c, 0xa722, 0x2011,
-	0x0002, 0x080c, 0xa72c, 0x080c, 0xa636, 0x901e, 0x080c, 0xa6ac,
-	0x2001, 0x00a0, 0x080c, 0x2d4e, 0x080c, 0x7724, 0x080c, 0x60ad,
-	0x9085, 0x0001, 0x00b0, 0x2001, 0x0080, 0x080c, 0x2d4e, 0x2069,
-	0x0140, 0x60e3, 0x0000, 0x70b4, 0x9005, 0x1118, 0x6887, 0x0001,
-	0x0008, 0x6886, 0x2001, 0x196c, 0x2004, 0x080c, 0x28f0, 0x60e2,
-	0x9006, 0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e, 0x001e, 0x015e,
-	0x0005, 0x0156, 0x0016, 0x0026, 0x0036, 0x00c6, 0x00d6, 0x00e6,
-	0x2061, 0x0100, 0x2071, 0x1800, 0x6020, 0x9084, 0x00c0, 0x01c8,
-	0x2011, 0x0003, 0x080c, 0xa722, 0x2011, 0x0002, 0x080c, 0xa72c,
-	0x080c, 0xa636, 0x901e, 0x080c, 0xa6ac, 0x2069, 0x0140, 0x2001,
-	0x00a0, 0x080c, 0x2d4e, 0x080c, 0x7724, 0x080c, 0x60ad, 0x0804,
-	0x76a4, 0x2001, 0x180c, 0x200c, 0xd1b4, 0x1160, 0xc1b5, 0x2102,
-	0x080c, 0x72b6, 0x2069, 0x0140, 0x2001, 0x0080, 0x080c, 0x2d4e,
-	0x60e3, 0x0000, 0x2069, 0x0200, 0x6804, 0x9005, 0x1118, 0x6808,
-	0x9005, 0x0180, 0x6028, 0x9084, 0xfdff, 0x602a, 0x6027, 0x0200,
-	0x2069, 0x198e, 0x7000, 0x206a, 0x709b, 0x0027, 0x7003, 0x0001,
-	0x0804, 0x76a4, 0x6027, 0x1e00, 0x2009, 0x1e00, 0x080c, 0x2c76,
-	0x6024, 0x910c, 0x01c8, 0x9084, 0x1c00, 0x11b0, 0x1d04, 0x7662,
-	0x0006, 0x0016, 0x00c6, 0x00d6, 0x00e6, 0x080c, 0x8510, 0x00ee,
-	0x00de, 0x00ce, 0x001e, 0x000e, 0x00e6, 0x2071, 0x19f9, 0x7070,
-	0x00ee, 0x9005, 0x19f8, 0x0400, 0x0026, 0x2011, 0x72ce, 0x080c,
-	0x85b0, 0x2011, 0x72c1, 0x080c, 0x868a, 0x002e, 0x2069, 0x0140,
-	0x60e3, 0x0000, 0x70b4, 0x9005, 0x1118, 0x6887, 0x0001, 0x0008,
-	0x6886, 0x2001, 0x196c, 0x2004, 0x080c, 0x28f0, 0x60e2, 0x2001,
-	0x180c, 0x200c, 0xc1b4, 0x2102, 0x00ee, 0x00de, 0x00ce, 0x003e,
-	0x002e, 0x001e, 0x015e, 0x0005, 0x0156, 0x0016, 0x0026, 0x0036,
-	0x0046, 0x00c6, 0x00e6, 0x2061, 0x0100, 0x2071, 0x1800, 0x080c,
-	0xd381, 0x1904, 0x7712, 0x7130, 0xd184, 0x1170, 0x080c, 0x3378,
-	0x0138, 0xc18d, 0x7132, 0x2011, 0x1848, 0x2214, 0xd2ac, 0x1120,
-	0x7030, 0xd08c, 0x0904, 0x7712, 0x2011, 0x1848, 0x220c, 0xd1a4,
-	0x0538, 0x0016, 0x2019, 0x000e, 0x080c, 0xe6ae, 0x0156, 0x00b6,
-	0x20a9, 0x007f, 0x900e, 0x9186, 0x007e, 0x01a0, 0x9186, 0x0080,
-	0x0188, 0x080c, 0x6699, 0x1170, 0x2120, 0x9006, 0x0016, 0x2009,
-	0x000e, 0x080c, 0xe73a, 0x2009, 0x0001, 0x2011, 0x0100, 0x080c,
-	0x879a, 0x001e, 0x8108, 0x1f04, 0x76db, 0x00be, 0x015e, 0x001e,
-	0xd1ac, 0x1148, 0x0016, 0x2009, 0x0002, 0x2019, 0x0004, 0x080c,
-	0x31e9, 0x001e, 0x0078, 0x0156, 0x00b6, 0x20a9, 0x007f, 0x900e,
-	0x080c, 0x6699, 0x1110, 0x080c, 0x60c7, 0x8108, 0x1f04, 0x7708,
-	0x00be, 0x015e, 0x080c, 0x1b11, 0x080c, 0xaeb4, 0x60e3, 0x0000,
-	0x080c, 0x60ad, 0x080c, 0x736a, 0x00ee, 0x00ce, 0x004e, 0x003e,
-	0x002e, 0x001e, 0x015e, 0x0005, 0x2001, 0x197c, 0x2003, 0x0001,
-	0x0005, 0x2001, 0x197c, 0x2003, 0x0000, 0x0005, 0x2001, 0x197b,
-	0x2003, 0xaaaa, 0x0005, 0x2001, 0x197b, 0x2003, 0x0000, 0x0005,
-	0x2071, 0x18fa, 0x7003, 0x0000, 0x7007, 0x0000, 0x080c, 0x1018,
-	0x090c, 0x0dd5, 0xa8ab, 0xdcb0, 0x2900, 0x704e, 0x080c, 0x1018,
-	0x090c, 0x0dd5, 0xa8ab, 0xdcb0, 0x2900, 0x7052, 0xa867, 0x0000,
-	0xa86b, 0x0001, 0xa89f, 0x0000, 0x0005, 0x00e6, 0x2071, 0x0040,
-	0x6848, 0x9005, 0x1118, 0x9085, 0x0001, 0x04b0, 0x6840, 0x9005,
-	0x0150, 0x04a1, 0x6a50, 0x9200, 0x7002, 0x6854, 0x9101, 0x7006,
-	0x9006, 0x7012, 0x7016, 0x6850, 0x7002, 0x6854, 0x7006, 0x6858,
-	0x700a, 0x685c, 0x700e, 0x6840, 0x9005, 0x1110, 0x7012, 0x7016,
-	0x6848, 0x701a, 0x701c, 0x9085, 0x0040, 0x701e, 0x2001, 0x0019,
-	0x7036, 0x702b, 0x0001, 0x2001, 0x0004, 0x200c, 0x918c, 0xfff7,
-	0x918d, 0x8000, 0x2102, 0x00d6, 0x2069, 0x18fa, 0x6807, 0x0001,
-	0x00de, 0x080c, 0x7d11, 0x9006, 0x00ee, 0x0005, 0x900e, 0x0156,
-	0x20a9, 0x0006, 0x8003, 0x2011, 0x0100, 0x2214, 0x9296, 0x0008,
-	0x1110, 0x818d, 0x0010, 0x81f5, 0x3e08, 0x1f04, 0x779a, 0x015e,
-	0x0005, 0x2079, 0x0040, 0x2071, 0x18fa, 0x7004, 0x0002, 0x77b9,
-	0x77ba, 0x77f2, 0x784d, 0x795d, 0x77b7, 0x77b7, 0x7987, 0x080c,
-	0x0dd5, 0x0005, 0x2079, 0x0040, 0x782c, 0x908c, 0x0780, 0x190c,
-	0x7df3, 0xd0a4, 0x01f8, 0x7824, 0x2048, 0x9006, 0xa802, 0xa806,
-	0xa864, 0x9084, 0x00ff, 0x908a, 0x0040, 0x0610, 0x00c0, 0x2001,
-	0x1800, 0x200c, 0x9186, 0x0003, 0x1168, 0x7004, 0x0002, 0x77e2,
-	0x77bc, 0x77e2, 0x77e0, 0x77e2, 0x77e2, 0x77e2, 0x77e2, 0x77e2,
-	0x080c, 0x784d, 0x782c, 0xd09c, 0x090c, 0x7d11, 0x0005, 0x9082,
-	0x005a, 0x1218, 0x2100, 0x003b, 0x0c10, 0x080c, 0x7883, 0x0c90,
-	0x00e3, 0x08e8, 0x0005, 0x7883, 0x7883, 0x7883, 0x7883, 0x7883,
-	0x7883, 0x7883, 0x7883, 0x78a5, 0x7883, 0x7883, 0x7883, 0x7883,
-	0x7883, 0x7883, 0x7883, 0x7883, 0x7883, 0x7883, 0x7883, 0x7883,
-	0x7883, 0x7883, 0x7883, 0x7883, 0x7883, 0x7883, 0x7883, 0x788f,
-	0x7883, 0x7a78, 0x7883, 0x7883, 0x7883, 0x78a5, 0x7883, 0x788f,
-	0x7ab9, 0x7afa, 0x7b41, 0x7b55, 0x7883, 0x7883, 0x78a5, 0x788f,
-	0x78b9, 0x7883, 0x7931, 0x7c00, 0x7c1b, 0x7883, 0x78a5, 0x7883,
-	0x78b9, 0x7883, 0x7883, 0x7927, 0x7c1b, 0x7883, 0x7883, 0x7883,
-	0x7883, 0x7883, 0x7883, 0x7883, 0x7883, 0x7883, 0x78cd, 0x7883,
-	0x7883, 0x7883, 0x7883, 0x7883, 0x7883, 0x7883, 0x7883, 0x7883,
-	0x7d97, 0x7883, 0x7d41, 0x7883, 0x7d41, 0x7883, 0x78e2, 0x7883,
-	0x7883, 0x7883, 0x7883, 0x7883, 0x7883, 0x2079, 0x0040, 0x7004,
-	0x9086, 0x0003, 0x1198, 0x782c, 0x080c, 0x7d3a, 0xd0a4, 0x0170,
-	0x7824, 0x2048, 0x9006, 0xa802, 0xa806, 0xa864, 0x9084, 0x00ff,
-	0x908a, 0x001a, 0x1210, 0x002b, 0x0c50, 0x00e9, 0x080c, 0x7d11,
-	0x0005, 0x7883, 0x788f, 0x7a64, 0x7883, 0x788f, 0x7883, 0x788f,
-	0x788f, 0x7883, 0x788f, 0x7a64, 0x788f, 0x788f, 0x788f, 0x788f,
-	0x788f, 0x7883, 0x788f, 0x7a64, 0x7883, 0x7883, 0x788f, 0x7883,
-	0x7883, 0x7883, 0x788f, 0x00e6, 0x2071, 0x18fa, 0x2009, 0x0400,
-	0x0071, 0x00ee, 0x0005, 0x2009, 0x1000, 0x0049, 0x0005, 0x2009,
-	0x2000, 0x0029, 0x0005, 0x2009, 0x0800, 0x0009, 0x0005, 0x7007,
-	0x0001, 0xa868, 0x9084, 0x00ff, 0x9105, 0xa86a, 0x0126, 0x2091,
-	0x8000, 0x080c, 0x6d17, 0x012e, 0x0005, 0xa864, 0x8007, 0x9084,
-	0x00ff, 0x0d08, 0x8001, 0x1120, 0x7007, 0x0001, 0x0804, 0x7a06,
-	0x7007, 0x0003, 0x7012, 0x2900, 0x7016, 0x701a, 0x704b, 0x7a06,
-	0x0005, 0xa864, 0x8007, 0x9084, 0x00ff, 0x0968, 0x8001, 0x1120,
-	0x7007, 0x0001, 0x0804, 0x7a21, 0x7007, 0x0003, 0x7012, 0x2900,
-	0x7016, 0x701a, 0x704b, 0x7a21, 0x0005, 0xa864, 0x8007, 0x9084,
-	0x00ff, 0x0904, 0x788b, 0x8001, 0x1120, 0x7007, 0x0001, 0x0804,
-	0x7a3d, 0x7007, 0x0003, 0x7012, 0x2900, 0x7016, 0x701a, 0x704b,
-	0x7a3d, 0x0005, 0xa864, 0x8007, 0x9084, 0x00ff, 0x9086, 0x0001,
-	0x1904, 0x788b, 0x7007, 0x0001, 0x2009, 0x1834, 0x210c, 0x81ff,
-	0x11a8, 0xa868, 0x9084, 0x00ff, 0xa86a, 0xa883, 0x0000, 0x080c,
-	0x6344, 0x1108, 0x0005, 0x0126, 0x2091, 0x8000, 0xa867, 0x0139,
-	0xa87a, 0xa982, 0x080c, 0x6d17, 0x012e, 0x0ca0, 0xa994, 0x9186,
-	0x0071, 0x0d38, 0x9186, 0x0064, 0x0d20, 0x9186, 0x007c, 0x0d08,
-	0x9186, 0x0028, 0x09f0, 0x9186, 0x0038, 0x09d8, 0x9186, 0x0078,
-	0x09c0, 0x9186, 0x005f, 0x09a8, 0x9186, 0x0056, 0x0990, 0xa897,
-	0x4005, 0xa89b, 0x0001, 0x2001, 0x0030, 0x900e, 0x08a0, 0xa87c,
-	0x9084, 0x00c0, 0x9086, 0x00c0, 0x1120, 0x7007, 0x0001, 0x0804,
-	0x7c32, 0x2900, 0x7016, 0x701a, 0x20a9, 0x0004, 0xa860, 0x20e0,
-	0xa85c, 0x9080, 0x0030, 0x2098, 0x7050, 0x2040, 0xa060, 0x20e8,
-	0xa05c, 0x9080, 0x0023, 0x20a0, 0x4003, 0xa888, 0x7012, 0x9082,
-	0x0401, 0x1a04, 0x7893, 0xaab4, 0x928a, 0x0002, 0x1a04, 0x7893,
-	0x82ff, 0x1138, 0xa8b8, 0xa9bc, 0x9105, 0x0118, 0x2001, 0x79c4,
-	0x0018, 0x9280, 0x79ba, 0x2005, 0x7056, 0x7010, 0x9015, 0x0904,
-	0x79a5, 0x080c, 0x1018, 0x1118, 0x7007, 0x0004, 0x0005, 0x2900,
-	0x7022, 0x7054, 0x2060, 0xe000, 0xa866, 0x7050, 0x2040, 0xa95c,
-	0xe004, 0x9100, 0xa076, 0xa860, 0xa072, 0xe008, 0x920a, 0x1210,
-	0x900e, 0x2200, 0x7112, 0xe20c, 0x8003, 0x800b, 0x9296, 0x0004,
-	0x0108, 0x9108, 0xa17a, 0x810b, 0xa17e, 0x080c, 0x10e9, 0xa06c,
-	0x908e, 0x0100, 0x0170, 0x9086, 0x0200, 0x0118, 0x7007, 0x0007,
-	0x0005, 0x7020, 0x2048, 0x080c, 0x1031, 0x7014, 0x2048, 0x0804,
-	0x7893, 0x7020, 0x2048, 0x7018, 0xa802, 0xa807, 0x0000, 0x2908,
-	0x2048, 0xa906, 0x711a, 0x0804, 0x795d, 0x7014, 0x2048, 0x7007,
-	0x0001, 0xa8b4, 0x9005, 0x1128, 0xa8b8, 0xa9bc, 0x9105, 0x0108,
-	0x00b9, 0xa864, 0x9084, 0x00ff, 0x9086, 0x001e, 0x0904, 0x7c32,
-	0x0804, 0x7a06, 0x79bc, 0x79c0, 0x0002, 0x001d, 0x0007, 0x0004,
-	0x000a, 0x001b, 0x0005, 0x0006, 0x000a, 0x001d, 0x0005, 0x0004,
-	0x0076, 0x0066, 0xafb8, 0xaebc, 0xa804, 0x2050, 0xb0c0, 0xb0e2,
-	0xb0bc, 0xb0de, 0xb0b8, 0xb0d2, 0xb0b4, 0xb0ce, 0xb6da, 0xb7d6,
-	0xb0b0, 0xb0ca, 0xb0ac, 0xb0c6, 0xb0a8, 0xb0ba, 0xb0a4, 0xb0b6,
-	0xb6c2, 0xb7be, 0xb0a0, 0xb0b2, 0xb09c, 0xb0ae, 0xb098, 0xb0a2,
-	0xb094, 0xb09e, 0xb6aa, 0xb7a6, 0xb090, 0xb09a, 0xb08c, 0xb096,
-	0xb088, 0xb08a, 0xb084, 0xb086, 0xb692, 0xb78e, 0xb080, 0xb082,
-	0xb07c, 0xb07e, 0xb078, 0xb072, 0xb074, 0xb06e, 0xb67a, 0xb776,
-	0xb004, 0x9055, 0x1958, 0x006e, 0x007e, 0x0005, 0x2009, 0x1834,
-	0x210c, 0x81ff, 0x1178, 0x080c, 0x6141, 0x1108, 0x0005, 0x080c,
-	0x6f4a, 0x0126, 0x2091, 0x8000, 0x080c, 0xcf7c, 0x080c, 0x6d17,
-	0x012e, 0x0ca0, 0x080c, 0xd381, 0x1d70, 0x2001, 0x0028, 0x900e,
-	0x0c70, 0x2009, 0x1834, 0x210c, 0x81ff, 0x1188, 0xa888, 0x9005,
-	0x0188, 0xa883, 0x0000, 0x080c, 0x61d1, 0x1108, 0x0005, 0xa87a,
-	0x0126, 0x2091, 0x8000, 0x080c, 0x6d17, 0x012e, 0x0cb8, 0x2001,
-	0x0028, 0x0ca8, 0x2001, 0x0000, 0x0c90, 0x2009, 0x1834, 0x210c,
-	0x81ff, 0x11d8, 0xa888, 0x9005, 0x01e0, 0xa883, 0x0000, 0xa87c,
-	0xd0f4, 0x0120, 0x080c, 0x62a6, 0x1138, 0x0005, 0x9006, 0xa87a,
-	0x080c, 0x621e, 0x1108, 0x0005, 0x0126, 0x2091, 0x8000, 0xa87a,
-	0xa982, 0x080c, 0x6d17, 0x012e, 0x0cb0, 0x2001, 0x0028, 0x900e,
-	0x0c98, 0x2001, 0x0000, 0x0c80, 0x7018, 0xa802, 0x2908, 0x2048,
-	0xa906, 0x711a, 0x7010, 0x8001, 0x7012, 0x0118, 0x7007, 0x0003,
-	0x0030, 0x7014, 0x2048, 0x7007, 0x0001, 0x7048, 0x080f, 0x0005,
-	0x00b6, 0x7007, 0x0001, 0xa974, 0xa878, 0x9084, 0x00ff, 0x9096,
-	0x0004, 0x0540, 0x20a9, 0x0001, 0x9096, 0x0001, 0x0190, 0x900e,
-	0x20a9, 0x0800, 0x9096, 0x0002, 0x0160, 0x9005, 0x11d8, 0xa974,
-	0x080c, 0x6699, 0x11b8, 0x0066, 0xae80, 0x080c, 0x67a9, 0x006e,
-	0x0088, 0x0046, 0x2011, 0x180c, 0x2224, 0xc484, 0x2412, 0x004e,
-	0x00c6, 0x080c, 0x6699, 0x1110, 0x080c, 0x68a9, 0x8108, 0x1f04,
-	0x7aa1, 0x00ce, 0xa87c, 0xd084, 0x1120, 0x080c, 0x1031, 0x00be,
-	0x0005, 0x0126, 0x2091, 0x8000, 0x080c, 0x6d17, 0x012e, 0x00be,
-	0x0005, 0x0126, 0x2091, 0x8000, 0x7007, 0x0001, 0x080c, 0x6a08,
-	0x0580, 0x2061, 0x1a70, 0x6100, 0xd184, 0x0178, 0xa888, 0x9084,
-	0x00ff, 0x1550, 0x6000, 0xd084, 0x0520, 0x6004, 0x9005, 0x1538,
-	0x6003, 0x0000, 0x600b, 0x0000, 0x00c8, 0x2011, 0x0001, 0xa890,
-	0x9005, 0x1110, 0x2001, 0x001e, 0x8000, 0x6016, 0xa888, 0x9084,
-	0x00ff, 0x0178, 0x6006, 0xa888, 0x8007, 0x9084, 0x00ff, 0x0148,
-	0x600a, 0xa888, 0x8000, 0x1108, 0xc28d, 0x6202, 0x012e, 0x0804,
-	0x7cfb, 0x012e, 0x0804, 0x7cf5, 0x012e, 0x0804, 0x7cef, 0x012e,
-	0x0804, 0x7cf2, 0x0126, 0x2091, 0x8000, 0x7007, 0x0001, 0x080c,
-	0x6a08, 0x05e0, 0x2061, 0x1a70, 0x6000, 0xd084, 0x05b8, 0x6204,
-	0x6308, 0xd08c, 0x1530, 0xac78, 0x9484, 0x0003, 0x0170, 0xa988,
-	0x918c, 0x00ff, 0x8001, 0x1120, 0x2100, 0x9210, 0x0620, 0x0028,
-	0x8001, 0x1508, 0x2100, 0x9212, 0x02f0, 0x9484, 0x000c, 0x0188,
-	0xa988, 0x810f, 0x918c, 0x00ff, 0x9082, 0x0004, 0x1120, 0x2100,
-	0x9318, 0x0288, 0x0030, 0x9082, 0x0004, 0x1168, 0x2100, 0x931a,
-	0x0250, 0xa890, 0x9005, 0x0110, 0x8000, 0x6016, 0x6206, 0x630a,
-	0x012e, 0x0804, 0x7cfb, 0x012e, 0x0804, 0x7cf8, 0x012e, 0x0804,
-	0x7cf5, 0x0126, 0x2091, 0x8000, 0x7007, 0x0001, 0x2061, 0x1a70,
-	0x6300, 0xd38c, 0x1120, 0x6308, 0x8318, 0x0220, 0x630a, 0x012e,
-	0x0804, 0x7d09, 0x012e, 0x0804, 0x7cf8, 0x00b6, 0x0126, 0x00c6,
-	0x2091, 0x8000, 0x7007, 0x0001, 0xa87c, 0xd0ac, 0x0148, 0x00c6,
-	0x2061, 0x1a70, 0x6000, 0x9084, 0xfcff, 0x6002, 0x00ce, 0x0440,
-	0xa888, 0x9005, 0x05d8, 0xa88c, 0x9065, 0x0598, 0x2001, 0x1834,
-	0x2004, 0x9005, 0x0118, 0x080c, 0xaf74, 0x0068, 0x6017, 0xf400,
-	0x605b, 0x0000, 0xa97c, 0xd1a4, 0x0110, 0xa980, 0x615a, 0x2009,
-	0x0041, 0x080c, 0xafbe, 0xa988, 0x918c, 0xff00, 0x9186, 0x2000,
-	0x1138, 0x0026, 0x900e, 0x2011, 0xfdff, 0x080c, 0x879a, 0x002e,
-	0xa87c, 0xd0c4, 0x0148, 0x2061, 0x1a70, 0x6000, 0xd08c, 0x1120,
-	0x6008, 0x8000, 0x0208, 0x600a, 0x00ce, 0x012e, 0x00be, 0x0804,
-	0x7cfb, 0x00ce, 0x012e, 0x00be, 0x0804, 0x7cf5, 0xa984, 0x9186,
-	0x002e, 0x0d30, 0x9186, 0x002d, 0x0d18, 0x9186, 0x0045, 0x0510,
-	0x9186, 0x002a, 0x1130, 0x2001, 0x180c, 0x200c, 0xc194, 0x2102,
-	0x08b8, 0x9186, 0x0020, 0x0158, 0x9186, 0x0029, 0x1d10, 0xa974,
-	0x080c, 0x6699, 0x1968, 0xb800, 0xc0e4, 0xb802, 0x0848, 0xa88c,
-	0x9065, 0x09b8, 0x6007, 0x0024, 0x2001, 0x1985, 0x2004, 0x601a,
-	0x0804, 0x7b90, 0xa88c, 0x9065, 0x0960, 0x00e6, 0xa890, 0x9075,
-	0x2001, 0x1834, 0x2004, 0x9005, 0x0150, 0x080c, 0xaf74, 0x8eff,
-	0x0118, 0x2e60, 0x080c, 0xaf74, 0x00ee, 0x0804, 0x7b90, 0x6024,
-	0xc0dc, 0xc0d5, 0x6026, 0x2e60, 0x6007, 0x003a, 0xa8a0, 0x9005,
-	0x0130, 0x6007, 0x003b, 0xa8a4, 0x602e, 0xa8a8, 0x6016, 0x6003,
-	0x0001, 0x080c, 0x91b1, 0x080c, 0x9763, 0x00ee, 0x0804, 0x7b90,
-	0x2061, 0x1a70, 0x6000, 0xd084, 0x0190, 0xd08c, 0x1904, 0x7d09,
-	0x0126, 0x2091, 0x8000, 0x6204, 0x8210, 0x0220, 0x6206, 0x012e,
-	0x0804, 0x7d09, 0x012e, 0xa883, 0x0016, 0x0804, 0x7d02, 0xa883,
-	0x0007, 0x0804, 0x7d02, 0xa864, 0x8007, 0x9084, 0x00ff, 0x0130,
-	0x8001, 0x1138, 0x7007, 0x0001, 0x0069, 0x0005, 0x080c, 0x788b,
-	0x0040, 0x7007, 0x0003, 0x7012, 0x2900, 0x7016, 0x701a, 0x704b,
-	0x7c32, 0x0005, 0x00b6, 0x00e6, 0x0126, 0x2091, 0x8000, 0x903e,
-	0x2061, 0x1800, 0x61d0, 0x81ff, 0x1904, 0x7cb4, 0x6130, 0xd194,
-	0x1904, 0x7cde, 0xa878, 0x2070, 0x9e82, 0x1cd0, 0x0a04, 0x7ca8,
-	0x6068, 0x9e02, 0x1a04, 0x7ca8, 0x7120, 0x9186, 0x0006, 0x1904,
-	0x7c9a, 0x7010, 0x905d, 0x0904, 0x7cb4, 0xb800, 0xd0e4, 0x1904,
-	0x7cd8, 0x2061, 0x1a70, 0x6100, 0x9184, 0x0301, 0x9086, 0x0001,
-	0x15a0, 0x7024, 0xd0dc, 0x1904, 0x7ce1, 0xa883, 0x0000, 0xa803,
-	0x0000, 0x2908, 0x7014, 0x9005, 0x1198, 0x7116, 0xa87c, 0xd0f4,
-	0x1904, 0x7ce4, 0x080c, 0x575d, 0xd09c, 0x1118, 0xa87c, 0xc0cc,
-	0xa87e, 0x2e60, 0x080c, 0x86ba, 0x012e, 0x00ee, 0x00be, 0x0005,
-	0x2048, 0xa800, 0x9005, 0x1de0, 0xa902, 0x2148, 0xa87c, 0xd0f4,
-	0x1904, 0x7ce4, 0x012e, 0x00ee, 0x00be, 0x0005, 0x012e, 0x00ee,
-	0xa883, 0x0006, 0x00be, 0x0804, 0x7d02, 0xd184, 0x0db8, 0xd1c4,
-	0x1190, 0x00a0, 0xa974, 0x080c, 0x6699, 0x15d0, 0xb800, 0xd0e4,
-	0x15b8, 0x7120, 0x9186, 0x0007, 0x1118, 0xa883, 0x0002, 0x0490,
-	0xa883, 0x0008, 0x0478, 0xa883, 0x000e, 0x0460, 0xa883, 0x0017,
-	0x0448, 0xa883, 0x0035, 0x0430, 0x080c, 0x5761, 0xd0fc, 0x01e8,
-	0xa878, 0x2070, 0x9e82, 0x1cd0, 0x02c0, 0x6068, 0x9e02, 0x12a8,
-	0x7120, 0x9186, 0x0006, 0x1188, 0x7010, 0x905d, 0x0170, 0xb800,
-	0xd0bc, 0x0158, 0x2039, 0x0001, 0x7000, 0x9086, 0x0007, 0x1904,
-	0x7c3e, 0x7003, 0x0002, 0x0804, 0x7c3e, 0xa883, 0x0028, 0x0010,
-	0xa883, 0x0029, 0x012e, 0x00ee, 0x00be, 0x0420, 0xa883, 0x002a,
-	0x0cc8, 0xa883, 0x0045, 0x0cb0, 0x2e60, 0x2019, 0x0002, 0x601b,
-	0x0014, 0x080c, 0xe2c0, 0x012e, 0x00ee, 0x00be, 0x0005, 0x2009,
-	0x003e, 0x0058, 0x2009, 0x0004, 0x0040, 0x2009, 0x0006, 0x0028,
-	0x2009, 0x0016, 0x0010, 0x2009, 0x0001, 0xa884, 0x9084, 0xff00,
-	0x9105, 0xa886, 0x0126, 0x2091, 0x8000, 0x080c, 0x6d17, 0x012e,
-	0x0005, 0x080c, 0x1031, 0x0005, 0x00d6, 0x080c, 0x86b1, 0x00de,
-	0x0005, 0x00d6, 0x00e6, 0x0126, 0x2091, 0x8000, 0x2071, 0x0040,
-	0x702c, 0xd084, 0x01d8, 0x908c, 0x0780, 0x190c, 0x7df3, 0xd09c,
-	0x11a8, 0x2071, 0x1800, 0x70c0, 0x90ea, 0x0020, 0x0278, 0x8001,
-	0x70c2, 0x702c, 0x2048, 0xa800, 0x702e, 0x9006, 0xa802, 0xa806,
-	0x2071, 0x0040, 0x2900, 0x7022, 0x702c, 0x0c28, 0x012e, 0x00ee,
-	0x00de, 0x0005, 0x0006, 0x9084, 0x0780, 0x190c, 0x7df3, 0x000e,
-	0x0005, 0xa898, 0x9084, 0x0003, 0x05a8, 0x080c, 0xaeed, 0x05d8,
-	0x2900, 0x6016, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0035, 0x1138,
-	0x6008, 0xc0fd, 0x600a, 0x2001, 0x196a, 0x2004, 0x0098, 0xa8a0,
-	0x9084, 0x00ff, 0xa99c, 0x918c, 0xff00, 0x9105, 0xa99c, 0x918c,
-	0x00ff, 0x080c, 0x287c, 0x1540, 0x00b6, 0x080c, 0x6699, 0x2b00,
-	0x00be, 0x1510, 0x6012, 0x6023, 0x0001, 0x2009, 0x0040, 0xa864,
-	0x9084, 0x00ff, 0x9086, 0x0035, 0x0110, 0x2009, 0x0041, 0x080c,
-	0xafbe, 0x0005, 0xa87b, 0x0101, 0x0126, 0x2091, 0x8000, 0x080c,
-	0x6d17, 0x012e, 0x0005, 0xa87b, 0x002c, 0x0126, 0x2091, 0x8000,
-	0x080c, 0x6d17, 0x012e, 0x0005, 0xa87b, 0x0028, 0x0126, 0x2091,
-	0x8000, 0x080c, 0x6d17, 0x012e, 0x080c, 0xaf43, 0x0005, 0x00d6,
-	0x00c6, 0x0036, 0x0026, 0x0016, 0x00b6, 0x7007, 0x0001, 0xaa74,
-	0x9282, 0x0004, 0x1a04, 0x7de4, 0xa97c, 0x9188, 0x1000, 0x2104,
-	0x905d, 0xb804, 0xd284, 0x0140, 0x05e8, 0x8007, 0x9084, 0x00ff,
-	0x9084, 0x0006, 0x1108, 0x04b0, 0x2b10, 0x080c, 0xaeed, 0x1118,
-	0x080c, 0xaf91, 0x05a8, 0x6212, 0xa874, 0x0002, 0x7dc2, 0x7dc7,
-	0x7dca, 0x7dd0, 0x2019, 0x0002, 0x080c, 0xe6ae, 0x0060, 0x080c,
-	0xe64a, 0x0048, 0x2019, 0x0002, 0xa980, 0x080c, 0xe665, 0x0018,
-	0xa980, 0x080c, 0xe64a, 0x080c, 0xaf43, 0xa887, 0x0000, 0x0126,
-	0x2091, 0x8000, 0x080c, 0x6d17, 0x012e, 0x00be, 0x001e, 0x002e,
-	0x003e, 0x00ce, 0x00de, 0x0005, 0xa887, 0x0006, 0x0c80, 0xa887,
-	0x0002, 0x0c68, 0xa887, 0x0005, 0x0c50, 0xa887, 0x0004, 0x0c38,
-	0xa887, 0x0007, 0x0c20, 0x2091, 0x8000, 0x0e04, 0x7df5, 0x0006,
-	0x0016, 0x2001, 0x8003, 0x0006, 0x0804, 0x0dde, 0x2001, 0x1834,
-	0x2004, 0x9005, 0x0005, 0x0005, 0x00f6, 0x2079, 0x0300, 0x2001,
-	0x0200, 0x200c, 0xc1e5, 0xc1dc, 0x2102, 0x2009, 0x0218, 0x210c,
-	0xd1ec, 0x1120, 0x080c, 0x158c, 0x00fe, 0x0005, 0x2001, 0x020d,
-	0x2003, 0x0020, 0x781f, 0x0300, 0x00fe, 0x0005, 0x781c, 0xd08c,
-	0x0904, 0x7e75, 0x68c0, 0x90aa, 0x0005, 0x0a04, 0x84b9, 0x7d44,
-	0x7c40, 0x9584, 0x00f6, 0x1510, 0x9484, 0x7000, 0x0140, 0x908a,
-	0x2000, 0x1260, 0x9584, 0x0700, 0x8007, 0x0804, 0x7e7c, 0x7000,
-	0x9084, 0xff00, 0x9086, 0x8100, 0x0da8, 0x00b0, 0x9484, 0x0fff,
-	0x1130, 0x7000, 0x9084, 0xff00, 0x9086, 0x8100, 0x11c0, 0x080c,
-	0xeb51, 0x080c, 0x839e, 0x7817, 0x0140, 0x00a8, 0x9584, 0x0076,
-	0x1118, 0x080c, 0x83fc, 0x19c0, 0xd5a4, 0x0148, 0x0046, 0x0056,
-	0x080c, 0x7ed7, 0x080c, 0x2375, 0x005e, 0x004e, 0x0020, 0x080c,
-	0xeb51, 0x7817, 0x0140, 0x080c, 0x743e, 0x0168, 0x2001, 0x0111,
-	0x2004, 0xd08c, 0x0140, 0x6893, 0x0000, 0x2001, 0x0110, 0x2003,
-	0x0008, 0x2003, 0x0000, 0x080c, 0x7eb8, 0x2001, 0x19ef, 0x2004,
-	0x9005, 0x090c, 0x9763, 0x0005, 0x0002, 0x7e8e, 0x81a6, 0x7e85,
-	0x7e85, 0x7e85, 0x7e85, 0x7e85, 0x7e85, 0x7817, 0x0140, 0x2001,
-	0x19ef, 0x2004, 0x9005, 0x090c, 0x9763, 0x0005, 0x7000, 0x908c,
-	0xff00, 0x9194, 0xf000, 0x810f, 0x9484, 0x0fff, 0x6892, 0x9286,
-	0x2000, 0x1150, 0x6800, 0x9086, 0x0001, 0x1118, 0x080c, 0x57c3,
-	0x0070, 0x080c, 0x7ef7, 0x0058, 0x9286, 0x3000, 0x1118, 0x080c,
-	0x80de, 0x0028, 0x9286, 0x8000, 0x1110, 0x080c, 0x82c5, 0x7817,
-	0x0140, 0x2001, 0x19ef, 0x2004, 0x9005, 0x090c, 0x9763, 0x0005,
-	0x2001, 0x1810, 0x2004, 0xd08c, 0x0178, 0x2001, 0x1800, 0x2004,
-	0x9086, 0x0003, 0x1148, 0x0026, 0x0036, 0x2011, 0x8048, 0x2518,
-	0x080c, 0x4b7f, 0x003e, 0x002e, 0x0005, 0x0036, 0x0046, 0x0056,
-	0x00f6, 0x2079, 0x0200, 0x2019, 0xfffe, 0x7c30, 0x0050, 0x0036,
-	0x0046, 0x0056, 0x00f6, 0x2079, 0x0200, 0x7d44, 0x7c40, 0x2019,
-	0xffff, 0x2001, 0x1810, 0x2004, 0xd08c, 0x0160, 0x2001, 0x1800,
-	0x2004, 0x9086, 0x0003, 0x1130, 0x0026, 0x2011, 0x8048, 0x080c,
-	0x4b7f, 0x002e, 0x00fe, 0x005e, 0x004e, 0x003e, 0x0005, 0x00b6,
-	0x00c6, 0x7010, 0x9084, 0xff00, 0x8007, 0x9096, 0x0001, 0x0120,
-	0x9096, 0x0023, 0x1904, 0x80af, 0x9186, 0x0023, 0x15c0, 0x080c,
-	0x8363, 0x0904, 0x80af, 0x6120, 0x9186, 0x0001, 0x0150, 0x9186,
-	0x0004, 0x0138, 0x9186, 0x0008, 0x0120, 0x9186, 0x000a, 0x1904,
-	0x80af, 0x7124, 0x610a, 0x7030, 0x908e, 0x0200, 0x1130, 0x2009,
-	0x0015, 0x080c, 0xafbe, 0x0804, 0x80af, 0x908e, 0x0214, 0x0118,
-	0x908e, 0x0210, 0x1130, 0x2009, 0x0015, 0x080c, 0xafbe, 0x0804,
-	0x80af, 0x908e, 0x0100, 0x1904, 0x80af, 0x7034, 0x9005, 0x1904,
-	0x80af, 0x2009, 0x0016, 0x080c, 0xafbe, 0x0804, 0x80af, 0x9186,
-	0x0022, 0x1904, 0x80af, 0x7030, 0x908e, 0x0300, 0x1580, 0x68dc,
-	0xd0a4, 0x0528, 0xc0b5, 0x68de, 0x7100, 0x918c, 0x00ff, 0x697e,
-	0x7004, 0x6882, 0x00f6, 0x2079, 0x0100, 0x79e6, 0x78ea, 0x0006,
-	0x9084, 0x00ff, 0x0016, 0x2008, 0x080c, 0x28c5, 0x7932, 0x7936,
-	0x001e, 0x000e, 0x00fe, 0x080c, 0x287c, 0x695e, 0x703c, 0x00e6,
-	0x2071, 0x0140, 0x7086, 0x2071, 0x1800, 0x70b6, 0x00ee, 0x7034,
-	0x9005, 0x1904, 0x80af, 0x2009, 0x0017, 0x0804, 0x805f, 0x908e,
-	0x0400, 0x1190, 0x7034, 0x9005, 0x1904, 0x80af, 0x080c, 0x743e,
-	0x0120, 0x2009, 0x001d, 0x0804, 0x805f, 0x68dc, 0xc0a5, 0x68de,
-	0x2009, 0x0030, 0x0804, 0x805f, 0x908e, 0x0500, 0x1140, 0x7034,
-	0x9005, 0x1904, 0x80af, 0x2009, 0x0018, 0x0804, 0x805f, 0x908e,
-	0x2010, 0x1120, 0x2009, 0x0019, 0x0804, 0x805f, 0x908e, 0x2110,
-	0x1120, 0x2009, 0x001a, 0x0804, 0x805f, 0x908e, 0x5200, 0x1140,
-	0x7034, 0x9005, 0x1904, 0x80af, 0x2009, 0x001b, 0x0804, 0x805f,
-	0x908e, 0x5000, 0x1140, 0x7034, 0x9005, 0x1904, 0x80af, 0x2009,
-	0x001c, 0x0804, 0x805f, 0x908e, 0x1300, 0x1120, 0x2009, 0x0034,
-	0x0804, 0x805f, 0x908e, 0x1200, 0x1140, 0x7034, 0x9005, 0x1904,
-	0x80af, 0x2009, 0x0024, 0x0804, 0x805f, 0x908c, 0xff00, 0x918e,
-	0x2400, 0x1170, 0x2009, 0x002d, 0x2001, 0x1810, 0x2004, 0xd09c,
-	0x0904, 0x805f, 0x080c, 0xda85, 0x1904, 0x80af, 0x0804, 0x805d,
-	0x908c, 0xff00, 0x918e, 0x5300, 0x1120, 0x2009, 0x002a, 0x0804,
-	0x805f, 0x908e, 0x0f00, 0x1120, 0x2009, 0x0020, 0x0804, 0x805f,
-	0x908e, 0x6104, 0x1530, 0x2029, 0x0205, 0x2011, 0x026d, 0x8208,
-	0x2204, 0x9082, 0x0004, 0x8004, 0x8004, 0x20a8, 0x2011, 0x8015,
-	0x211c, 0x8108, 0x0046, 0x2124, 0x080c, 0x4b7f, 0x004e, 0x8108,
-	0x0f04, 0x8013, 0x9186, 0x0280, 0x1d88, 0x2504, 0x8000, 0x202a,
-	0x2009, 0x0260, 0x0c58, 0x202b, 0x0000, 0x2009, 0x0023, 0x0804,
-	0x805f, 0x908e, 0x6000, 0x1120, 0x2009, 0x003f, 0x0804, 0x805f,
-	0x908e, 0x5400, 0x1138, 0x080c, 0x8469, 0x1904, 0x80af, 0x2009,
-	0x0046, 0x04a8, 0x908e, 0x5500, 0x1148, 0x080c, 0x8491, 0x1118,
-	0x2009, 0x0041, 0x0460, 0x2009, 0x0042, 0x0448, 0x908e, 0x7800,
-	0x1118, 0x2009, 0x0045, 0x0418, 0x908e, 0x1000, 0x1118, 0x2009,
-	0x004e, 0x00e8, 0x908e, 0x6300, 0x1118, 0x2009, 0x004a, 0x00b8,
-	0x908c, 0xff00, 0x918e, 0x5600, 0x1118, 0x2009, 0x004f, 0x0078,
-	0x908c, 0xff00, 0x918e, 0x5700, 0x1118, 0x2009, 0x0050, 0x0038,
-	0x2009, 0x001d, 0x6838, 0xd0d4, 0x0110, 0x2009, 0x004c, 0x0016,
-	0x2011, 0x0263, 0x2204, 0x8211, 0x220c, 0x080c, 0x287c, 0x1904,
-	0x80b2, 0x080c, 0x6638, 0x1904, 0x80b2, 0xbe12, 0xbd16, 0x001e,
-	0x0016, 0x080c, 0x743e, 0x01c0, 0x68dc, 0xd08c, 0x1148, 0x7000,
-	0x9084, 0x00ff, 0x1188, 0x7004, 0x9084, 0xff00, 0x1168, 0x0040,
-	0x687c, 0x9606, 0x1148, 0x6880, 0x9506, 0x9084, 0xff00, 0x1120,
-	0x9584, 0x00ff, 0xb8c2, 0x0080, 0xb8c0, 0x9005, 0x1168, 0x9186,
-	0x0046, 0x1150, 0x687c, 0x9606, 0x1138, 0x6880, 0x9506, 0x9084,
-	0xff00, 0x1110, 0x001e, 0x0098, 0x080c, 0xaeed, 0x01a8, 0x2b08,
-	0x6112, 0x6023, 0x0004, 0x7120, 0x610a, 0x001e, 0x9186, 0x004c,
-	0x1110, 0x6023, 0x000a, 0x0016, 0x001e, 0x080c, 0xafbe, 0x00ce,
-	0x00be, 0x0005, 0x001e, 0x0cd8, 0x2001, 0x180e, 0x2004, 0xd0ec,
-	0x0120, 0x2011, 0x8049, 0x080c, 0x4b7f, 0x080c, 0xaf91, 0x0d90,
-	0x2b08, 0x6112, 0x6023, 0x0004, 0x7120, 0x610a, 0x001e, 0x0016,
-	0x9186, 0x0017, 0x0118, 0x9186, 0x0030, 0x1128, 0x6007, 0x0009,
-	0x6017, 0x2900, 0x0020, 0x6007, 0x0051, 0x6017, 0x0000, 0x602f,
-	0x0009, 0x6003, 0x0001, 0x080c, 0x91f9, 0x08a0, 0x080c, 0x84d8,
-	0x1158, 0x080c, 0x3342, 0x1140, 0x7010, 0x9084, 0xff00, 0x8007,
-	0x908e, 0x0008, 0x1108, 0x0009, 0x0005, 0x00b6, 0x00c6, 0x0046,
-	0x7000, 0x908c, 0xff00, 0x810f, 0x9186, 0x0033, 0x11e8, 0x080c,
-	0x8363, 0x0904, 0x813e, 0x7124, 0x610a, 0x7030, 0x908e, 0x0200,
-	0x1140, 0x7034, 0x9005, 0x15d0, 0x2009, 0x0015, 0x080c, 0xafbe,
-	0x04a8, 0x908e, 0x0100, 0x1590, 0x7034, 0x9005, 0x1578, 0x2009,
-	0x0016, 0x080c, 0xafbe, 0x0450, 0x9186, 0x0032, 0x1538, 0x7030,
-	0x908e, 0x1400, 0x1518, 0x2009, 0x0038, 0x0016, 0x2011, 0x0263,
-	0x2204, 0x8211, 0x220c, 0x080c, 0x287c, 0x11b8, 0x080c, 0x6638,
-	0x11a0, 0xbe12, 0xbd16, 0x080c, 0xaeed, 0x0178, 0x2b08, 0x6112,
-	0x080c, 0xd102, 0x6023, 0x0004, 0x7120, 0x610a, 0x001e, 0x080c,
-	0xafbe, 0x080c, 0x9763, 0x0010, 0x00ce, 0x001e, 0x004e, 0x00ce,
-	0x00be, 0x0005, 0x00b6, 0x0046, 0x00e6, 0x00d6, 0x2028, 0x2130,
-	0x9696, 0x00ff, 0x11b8, 0x9592, 0xfffc, 0x02a0, 0x9596, 0xfffd,
-	0x1120, 0x2009, 0x007f, 0x0804, 0x81a0, 0x9596, 0xfffe, 0x1120,
-	0x2009, 0x007e, 0x0804, 0x81a0, 0x9596, 0xfffc, 0x1118, 0x2009,
-	0x0080, 0x04f0, 0x2011, 0x0000, 0x2019, 0x1837, 0x231c, 0xd3ac,
-	0x0130, 0x9026, 0x20a9, 0x0800, 0x2071, 0x1000, 0x0030, 0x2021,
-	0x0081, 0x20a9, 0x077f, 0x2071, 0x1081, 0x2e1c, 0x93dd, 0x0000,
-	0x1140, 0x82ff, 0x11d0, 0x9496, 0x00ff, 0x01b8, 0x2410, 0xc2fd,
-	0x00a0, 0xbf10, 0x2600, 0x9706, 0xb814, 0x1120, 0x9546, 0x1110,
-	0x2408, 0x00b0, 0x9745, 0x1148, 0x94c6, 0x007e, 0x0130, 0x94c6,
-	0x007f, 0x0118, 0x94c6, 0x0080, 0x1d20, 0x8420, 0x8e70, 0x1f04,
-	0x8175, 0x82ff, 0x1118, 0x9085, 0x0001, 0x0018, 0xc2fc, 0x2208,
-	0x9006, 0x00de, 0x00ee, 0x004e, 0x00be, 0x0005, 0x2001, 0x1837,
-	0x200c, 0x9184, 0x0080, 0x0110, 0xd18c, 0x0138, 0x7000, 0x908c,
-	0xff00, 0x810f, 0x9184, 0x000f, 0x004a, 0x7817, 0x0140, 0x2001,
-	0x19ef, 0x2004, 0x9005, 0x090c, 0x9763, 0x0005, 0x81ce, 0x81ce,
-	0x81ce, 0x8375, 0x81ce, 0x81d7, 0x8202, 0x8290, 0x81ce, 0x81ce,
-	0x81ce, 0x81ce, 0x81ce, 0x81ce, 0x81ce, 0x81ce, 0x7817, 0x0140,
-	0x2001, 0x19ef, 0x2004, 0x9005, 0x090c, 0x9763, 0x0005, 0x00b6,
-	0x7110, 0xd1bc, 0x01e8, 0x7120, 0x2160, 0x9c8c, 0x0007, 0x11c0,
-	0x9c8a, 0x1cd0, 0x02a8, 0x6868, 0x9c02, 0x1290, 0x7008, 0x9084,
-	0x00ff, 0x6110, 0x2158, 0xb910, 0x9106, 0x1150, 0x700c, 0xb914,
-	0x9106, 0x1130, 0x7124, 0x610a, 0x2009, 0x0046, 0x080c, 0xafbe,
-	0x7817, 0x0140, 0x2001, 0x19ef, 0x2004, 0x9005, 0x090c, 0x9763,
-	0x00be, 0x0005, 0x00b6, 0x00c6, 0x9484, 0x0fff, 0x0904, 0x8266,
-	0x7110, 0xd1bc, 0x1904, 0x8266, 0x7108, 0x700c, 0x2028, 0x918c,
-	0x00ff, 0x2130, 0x9094, 0xff00, 0x15b0, 0x81ff, 0x15a0, 0x9080,
-	0x3384, 0x200d, 0x918c, 0xff00, 0x810f, 0x2001, 0x0080, 0x9106,
-	0x0904, 0x8266, 0x080c, 0x6638, 0x1904, 0x8266, 0xbe12, 0xbd16,
-	0xb800, 0xd0ec, 0x15d8, 0xba04, 0x9294, 0xff00, 0x9286, 0x0600,
-	0x11a0, 0x080c, 0xaeed, 0x05e8, 0x2b08, 0x7028, 0x6046, 0x702c,
-	0x604a, 0x6112, 0x6023, 0x0006, 0x7120, 0x610a, 0x7130, 0x6156,
-	0x2009, 0x0044, 0x080c, 0xdce5, 0x0408, 0x080c, 0x6a0c, 0x1138,
-	0xb807, 0x0606, 0x0c30, 0x190c, 0x8142, 0x11c0, 0x0898, 0x080c,
-	0xaeed, 0x2b08, 0x0198, 0x6112, 0x6023, 0x0004, 0x7120, 0x610a,
-	0x9286, 0x0400, 0x1118, 0x6007, 0x0005, 0x0010, 0x6007, 0x0001,
-	0x6003, 0x0001, 0x080c, 0x91f9, 0x080c, 0x9763, 0x7817, 0x0140,
-	0x2001, 0x19ef, 0x2004, 0x9005, 0x090c, 0x9763, 0x00ce, 0x00be,
-	0x0005, 0x2001, 0x180e, 0x2004, 0xd0ec, 0x0120, 0x2011, 0x8049,
-	0x080c, 0x4b7f, 0x080c, 0xaf91, 0x0d48, 0x2b08, 0x6112, 0x6023,
-	0x0006, 0x7120, 0x610a, 0x7130, 0x6156, 0x6017, 0xf300, 0x6003,
-	0x0001, 0x6007, 0x0041, 0x080c, 0x91b1, 0x080c, 0x9763, 0x08b0,
-	0x00b6, 0x7110, 0xd1bc, 0x01e8, 0x7020, 0x2060, 0x9c84, 0x0007,
-	0x11c0, 0x9c82, 0x1cd0, 0x02a8, 0x6868, 0x9c02, 0x1290, 0x7008,
+	0x01b8, 0x2001, 0x00c0, 0x080c, 0x2d5b, 0x0156, 0x20a9, 0x002d,
+	0x1d04, 0x7450, 0x2091, 0x6000, 0x1f04, 0x7450, 0x015e, 0x00d6,
+	0x2069, 0x1800, 0x689c, 0x8001, 0x0220, 0x0118, 0x689e, 0x00de,
+	0x0005, 0x689f, 0x0014, 0x68e8, 0xd0dc, 0x0dc8, 0x6800, 0x9086,
+	0x0001, 0x1da8, 0x080c, 0x87e9, 0x0c90, 0x00c6, 0x00d6, 0x00e6,
+	0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0x1800, 0x080c, 0x7857,
+	0x2001, 0x196e, 0x2003, 0x0000, 0x9006, 0x709a, 0x60e2, 0x6886,
+	0x080c, 0x28fd, 0x9006, 0x080c, 0x2d5b, 0x080c, 0x5fe0, 0x6027,
+	0xffff, 0x602b, 0x182f, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x00c6,
+	0x00d6, 0x00e6, 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0x1800,
+	0x2001, 0x197e, 0x200c, 0x9186, 0x0000, 0x0158, 0x9186, 0x0001,
+	0x0158, 0x9186, 0x0002, 0x0158, 0x9186, 0x0003, 0x0158, 0x0804,
+	0x752b, 0x709b, 0x0022, 0x0040, 0x709b, 0x0021, 0x0028, 0x709b,
+	0x0023, 0x0010, 0x709b, 0x0024, 0x60e3, 0x0000, 0x6887, 0x0001,
+	0x2001, 0x0001, 0x080c, 0x28fd, 0x0026, 0x080c, 0xb058, 0x002e,
+	0x7000, 0x908e, 0x0004, 0x0118, 0x602b, 0x0028, 0x0010, 0x602b,
+	0x0020, 0x0156, 0x0126, 0x2091, 0x8000, 0x20a9, 0x0005, 0x6024,
+	0xd0ac, 0x0150, 0x012e, 0x015e, 0x080c, 0xd548, 0x0118, 0x9006,
+	0x080c, 0x2d85, 0x0804, 0x7537, 0x6800, 0x9084, 0x00a1, 0xc0bd,
+	0x6802, 0x080c, 0x2c83, 0x6904, 0xd1d4, 0x1140, 0x2001, 0x0100,
+	0x080c, 0x2d5b, 0x1f04, 0x74cf, 0x080c, 0x75b7, 0x012e, 0x015e,
+	0x080c, 0x7574, 0x01d8, 0x6044, 0x9005, 0x0198, 0x2011, 0x0114,
+	0x2204, 0x9085, 0x0100, 0x2012, 0x6050, 0x0006, 0x9085, 0x0020,
+	0x6052, 0x080c, 0x75b7, 0x9006, 0x8001, 0x1df0, 0x000e, 0x6052,
+	0x0028, 0x6804, 0xd0d4, 0x1110, 0x080c, 0x75b7, 0x080c, 0xd548,
+	0x0118, 0x9006, 0x080c, 0x2d85, 0x0016, 0x0026, 0x7000, 0x908e,
+	0x0004, 0x0130, 0x2009, 0x00c8, 0x2011, 0x73de, 0x080c, 0x879b,
+	0x002e, 0x001e, 0x080c, 0x85e2, 0x7034, 0xc085, 0x7036, 0x2001,
+	0x197e, 0x2003, 0x0004, 0x080c, 0x7221, 0x080c, 0x7574, 0x0138,
+	0x6804, 0xd0d4, 0x1120, 0xd0dc, 0x1100, 0x080c, 0x784d, 0x00ee,
+	0x00de, 0x00ce, 0x0005, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100,
+	0x2069, 0x0140, 0x2071, 0x1800, 0x080c, 0x85f9, 0x080c, 0x85eb,
+	0x080c, 0x7857, 0x2001, 0x196e, 0x2003, 0x0000, 0x9006, 0x709a,
+	0x60e2, 0x6886, 0x080c, 0x28fd, 0x9006, 0x080c, 0x2d5b, 0x6043,
+	0x0090, 0x6043, 0x0010, 0x6027, 0xffff, 0x602b, 0x182f, 0x00ee,
+	0x00de, 0x00ce, 0x0005, 0x0006, 0x2001, 0x197d, 0x2004, 0x9086,
+	0xaaaa, 0x000e, 0x0005, 0x0006, 0x080c, 0x57d1, 0x9084, 0x0030,
+	0x9086, 0x0000, 0x000e, 0x0005, 0x0006, 0x080c, 0x57d1, 0x9084,
+	0x0030, 0x9086, 0x0030, 0x000e, 0x0005, 0x0006, 0x080c, 0x57d1,
+	0x9084, 0x0030, 0x9086, 0x0010, 0x000e, 0x0005, 0x0006, 0x080c,
+	0x57d1, 0x9084, 0x0030, 0x9086, 0x0020, 0x000e, 0x0005, 0x0036,
+	0x0016, 0x2001, 0x180c, 0x2004, 0x908c, 0x0013, 0x0168, 0x0020,
+	0x080c, 0x291d, 0x900e, 0x0010, 0x2009, 0x0002, 0x2019, 0x0028,
+	0x080c, 0x3216, 0x9006, 0x0019, 0x001e, 0x003e, 0x0005, 0x00e6,
+	0x2071, 0x180c, 0x2e04, 0x0130, 0x080c, 0xd541, 0x1128, 0x9085,
+	0x0010, 0x0010, 0x9084, 0xffef, 0x2072, 0x00ee, 0x0005, 0x6050,
+	0x0006, 0x60ec, 0x0006, 0x600c, 0x0006, 0x6004, 0x0006, 0x6028,
+	0x0006, 0x0016, 0x6138, 0x6050, 0x9084, 0xfbff, 0x9085, 0x2000,
+	0x6052, 0x613a, 0x20a9, 0x0012, 0x1d04, 0x75cc, 0x2091, 0x6000,
+	0x1f04, 0x75cc, 0x602f, 0x0100, 0x602f, 0x0000, 0x6050, 0x9085,
+	0x0400, 0x9084, 0xdfff, 0x6052, 0x613a, 0x001e, 0x602f, 0x0040,
+	0x602f, 0x0000, 0x000e, 0x602a, 0x000e, 0x6006, 0x000e, 0x600e,
+	0x000e, 0x60ee, 0x60e3, 0x0000, 0x6887, 0x0001, 0x2001, 0x0001,
+	0x080c, 0x28fd, 0x2001, 0x00a0, 0x0006, 0x080c, 0xd548, 0x000e,
+	0x0130, 0x080c, 0x2d79, 0x9006, 0x080c, 0x2d85, 0x0010, 0x080c,
+	0x2d5b, 0x000e, 0x6052, 0x6050, 0x0006, 0xc0e5, 0x6052, 0x00f6,
+	0x2079, 0x0100, 0x080c, 0x2bf8, 0x00fe, 0x000e, 0x6052, 0x0005,
+	0x0156, 0x0016, 0x0026, 0x0036, 0x00c6, 0x00d6, 0x00e6, 0x2061,
+	0x0100, 0x2069, 0x0140, 0x2071, 0x1800, 0x6020, 0x9084, 0x0080,
+	0x0138, 0x2001, 0x180c, 0x200c, 0xc1c5, 0x2102, 0x0804, 0x768a,
+	0x2001, 0x180c, 0x200c, 0xc1c4, 0x2102, 0x6028, 0x9084, 0xe1ff,
+	0x602a, 0x6027, 0x0200, 0x2001, 0x0090, 0x080c, 0x2d5b, 0x20a9,
+	0x0366, 0x6024, 0xd0cc, 0x1518, 0x1d04, 0x7639, 0x2091, 0x6000,
+	0x1f04, 0x7639, 0x2011, 0x0003, 0x080c, 0xa8d3, 0x2011, 0x0002,
+	0x080c, 0xa8dd, 0x080c, 0xa7e7, 0x901e, 0x080c, 0xa85d, 0x2001,
+	0x00a0, 0x080c, 0x2d5b, 0x080c, 0x7848, 0x080c, 0x6121, 0x080c,
+	0xd548, 0x0110, 0x080c, 0x0d33, 0x9085, 0x0001, 0x0488, 0x080c,
+	0x1b27, 0x60e3, 0x0000, 0x2001, 0x196e, 0x2004, 0x080c, 0x28fd,
+	0x60e2, 0x2001, 0x0080, 0x080c, 0x2d5b, 0x20a9, 0x0366, 0x6027,
+	0x1e00, 0x2009, 0x1e00, 0x080c, 0x2c83, 0x6024, 0x910c, 0x0138,
+	0x1d04, 0x766f, 0x2091, 0x6000, 0x1f04, 0x766f, 0x0818, 0x6028,
+	0x9085, 0x1e00, 0x602a, 0x70b4, 0x9005, 0x1118, 0x6887, 0x0001,
+	0x0008, 0x6886, 0x080c, 0xd548, 0x0110, 0x080c, 0x0d33, 0x9006,
+	0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e, 0x001e, 0x015e, 0x0005,
+	0x0156, 0x0016, 0x0026, 0x0036, 0x00c6, 0x00d6, 0x00e6, 0x2061,
+	0x0100, 0x2071, 0x1800, 0x7000, 0x9086, 0x0003, 0x1168, 0x2001,
+	0x020b, 0x2004, 0x9084, 0x5540, 0x9086, 0x5540, 0x1128, 0x2069,
+	0x1a7d, 0x2d04, 0x8000, 0x206a, 0x2069, 0x0140, 0x6020, 0x9084,
+	0x00c0, 0x0120, 0x6884, 0x9005, 0x1904, 0x76fd, 0x2001, 0x0088,
+	0x080c, 0x2d5b, 0x9006, 0x60e2, 0x6886, 0x080c, 0x28fd, 0x2069,
+	0x0200, 0x6804, 0x9005, 0x1118, 0x6808, 0x9005, 0x01c0, 0x6028,
+	0x9084, 0xfbff, 0x602a, 0x6027, 0x0400, 0x2069, 0x1990, 0x7000,
+	0x206a, 0x709b, 0x0026, 0x7003, 0x0001, 0x20a9, 0x0002, 0x1d04,
+	0x76df, 0x2091, 0x6000, 0x1f04, 0x76df, 0x0804, 0x772d, 0x2069,
+	0x0140, 0x20a9, 0x0384, 0x6027, 0x1e00, 0x2009, 0x1e00, 0x080c,
+	0x2c83, 0x6024, 0x910c, 0x0508, 0x9084, 0x1a00, 0x11f0, 0x1d04,
+	0x76eb, 0x2091, 0x6000, 0x1f04, 0x76eb, 0x2011, 0x0003, 0x080c,
+	0xa8d3, 0x2011, 0x0002, 0x080c, 0xa8dd, 0x080c, 0xa7e7, 0x901e,
+	0x080c, 0xa85d, 0x2001, 0x00a0, 0x080c, 0x2d5b, 0x080c, 0x7848,
+	0x080c, 0x6121, 0x9085, 0x0001, 0x00c0, 0x080c, 0x1b27, 0x2001,
+	0x0080, 0x080c, 0x2d5b, 0x2069, 0x0140, 0x60e3, 0x0000, 0x70b4,
+	0x9005, 0x1118, 0x6887, 0x0001, 0x0008, 0x6886, 0x2001, 0x196e,
+	0x2004, 0x080c, 0x28fd, 0x60e2, 0x9006, 0x00ee, 0x00de, 0x00ce,
+	0x003e, 0x002e, 0x001e, 0x015e, 0x0005, 0x0156, 0x0016, 0x0026,
+	0x0036, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2071, 0x1800,
+	0x6020, 0x9084, 0x00c0, 0x01c8, 0x2011, 0x0003, 0x080c, 0xa8d3,
+	0x2011, 0x0002, 0x080c, 0xa8dd, 0x080c, 0xa7e7, 0x901e, 0x080c,
+	0xa85d, 0x2069, 0x0140, 0x2001, 0x00a0, 0x080c, 0x2d5b, 0x080c,
+	0x7848, 0x080c, 0x6121, 0x0804, 0x77c8, 0x2001, 0x180c, 0x200c,
+	0xd1b4, 0x1160, 0xc1b5, 0x2102, 0x080c, 0x73c6, 0x2069, 0x0140,
+	0x2001, 0x0080, 0x080c, 0x2d5b, 0x60e3, 0x0000, 0x2069, 0x0200,
+	0x6804, 0x9005, 0x1118, 0x6808, 0x9005, 0x0180, 0x6028, 0x9084,
+	0xfdff, 0x602a, 0x6027, 0x0200, 0x2069, 0x1990, 0x7000, 0x206a,
+	0x709b, 0x0027, 0x7003, 0x0001, 0x0804, 0x77c8, 0x6027, 0x1e00,
+	0x2009, 0x1e00, 0x080c, 0x2c83, 0x6024, 0x910c, 0x01c8, 0x9084,
+	0x1c00, 0x11b0, 0x1d04, 0x7786, 0x0006, 0x0016, 0x00c6, 0x00d6,
+	0x00e6, 0x080c, 0x863c, 0x00ee, 0x00de, 0x00ce, 0x001e, 0x000e,
+	0x00e6, 0x2071, 0x19fc, 0x7078, 0x00ee, 0x9005, 0x19f8, 0x0400,
+	0x0026, 0x2011, 0x73de, 0x080c, 0x8703, 0x2011, 0x73d1, 0x080c,
+	0x87dd, 0x002e, 0x2069, 0x0140, 0x60e3, 0x0000, 0x70b4, 0x9005,
+	0x1118, 0x6887, 0x0001, 0x0008, 0x6886, 0x2001, 0x196e, 0x2004,
+	0x080c, 0x28fd, 0x60e2, 0x2001, 0x180c, 0x200c, 0xc1b4, 0x2102,
+	0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e, 0x001e, 0x015e, 0x0005,
+	0x0156, 0x0016, 0x0026, 0x0036, 0x0046, 0x00c6, 0x00e6, 0x2061,
+	0x0100, 0x2071, 0x1800, 0x080c, 0xd541, 0x1904, 0x7836, 0x7130,
+	0xd184, 0x1170, 0x080c, 0x33a5, 0x0138, 0xc18d, 0x7132, 0x2011,
+	0x1848, 0x2214, 0xd2ac, 0x1120, 0x7030, 0xd08c, 0x0904, 0x7836,
+	0x2011, 0x1848, 0x220c, 0xd1a4, 0x0538, 0x0016, 0x2019, 0x000e,
+	0x080c, 0xe8b0, 0x0156, 0x00b6, 0x20a9, 0x007f, 0x900e, 0x9186,
+	0x007e, 0x01a0, 0x9186, 0x0080, 0x0188, 0x080c, 0x6717, 0x1170,
+	0x2120, 0x9006, 0x0016, 0x2009, 0x000e, 0x080c, 0xe940, 0x2009,
+	0x0001, 0x2011, 0x0100, 0x080c, 0x8916, 0x001e, 0x8108, 0x1f04,
+	0x77ff, 0x00be, 0x015e, 0x001e, 0xd1ac, 0x1148, 0x0016, 0x2009,
+	0x0002, 0x2019, 0x0004, 0x080c, 0x3216, 0x001e, 0x0078, 0x0156,
+	0x00b6, 0x20a9, 0x007f, 0x900e, 0x080c, 0x6717, 0x1110, 0x080c,
+	0x613b, 0x8108, 0x1f04, 0x782c, 0x00be, 0x015e, 0x080c, 0x1b27,
+	0x080c, 0xb058, 0x60e3, 0x0000, 0x080c, 0x6121, 0x080c, 0x748f,
+	0x00ee, 0x00ce, 0x004e, 0x003e, 0x002e, 0x001e, 0x015e, 0x0005,
+	0x2001, 0x197e, 0x2003, 0x0001, 0x0005, 0x2001, 0x197e, 0x2003,
+	0x0000, 0x0005, 0x2001, 0x197d, 0x2003, 0xaaaa, 0x0005, 0x2001,
+	0x197d, 0x2003, 0x0000, 0x0005, 0x2071, 0x18fa, 0x7003, 0x0000,
+	0x7007, 0x0000, 0x080c, 0x1027, 0x090c, 0x0dc5, 0xa8ab, 0xdcb0,
+	0x2900, 0x704e, 0x080c, 0x1027, 0x090c, 0x0dc5, 0xa8ab, 0xdcb0,
+	0x2900, 0x7052, 0xa867, 0x0000, 0xa86b, 0x0001, 0xa89f, 0x0000,
+	0x0005, 0x00e6, 0x2071, 0x0040, 0x6848, 0x9005, 0x1118, 0x9085,
+	0x0001, 0x04b0, 0x6840, 0x9005, 0x0150, 0x04a1, 0x6a50, 0x9200,
+	0x7002, 0x6854, 0x9101, 0x7006, 0x9006, 0x7012, 0x7016, 0x6850,
+	0x7002, 0x6854, 0x7006, 0x6858, 0x700a, 0x685c, 0x700e, 0x6840,
+	0x9005, 0x1110, 0x7012, 0x7016, 0x6848, 0x701a, 0x701c, 0x9085,
+	0x0040, 0x701e, 0x2001, 0x0019, 0x7036, 0x702b, 0x0001, 0x2001,
+	0x0004, 0x200c, 0x918c, 0xfff7, 0x918d, 0x8000, 0x2102, 0x00d6,
+	0x2069, 0x18fa, 0x6807, 0x0001, 0x00de, 0x080c, 0x7e3a, 0x9006,
+	0x00ee, 0x0005, 0x900e, 0x0156, 0x20a9, 0x0006, 0x8003, 0x2011,
+	0x0100, 0x2214, 0x9296, 0x0008, 0x1110, 0x818d, 0x0010, 0x81f5,
+	0x3e08, 0x1f04, 0x78be, 0x015e, 0x0005, 0x2079, 0x0040, 0x2071,
+	0x18fa, 0x7004, 0x0002, 0x78dd, 0x78de, 0x7916, 0x7971, 0x7a81,
+	0x78db, 0x78db, 0x7aab, 0x080c, 0x0dc5, 0x0005, 0x2079, 0x0040,
+	0x782c, 0x908c, 0x0780, 0x190c, 0x7f1c, 0xd0a4, 0x01f8, 0x7824,
+	0x2048, 0x9006, 0xa802, 0xa806, 0xa864, 0x9084, 0x00ff, 0x908a,
+	0x0040, 0x0610, 0x00c0, 0x2001, 0x1800, 0x200c, 0x9186, 0x0003,
+	0x1168, 0x7004, 0x0002, 0x7906, 0x78e0, 0x7906, 0x7904, 0x7906,
+	0x7906, 0x7906, 0x7906, 0x7906, 0x080c, 0x7971, 0x782c, 0xd09c,
+	0x090c, 0x7e3a, 0x0005, 0x9082, 0x005a, 0x1218, 0x2100, 0x003b,
+	0x0c10, 0x080c, 0x79a7, 0x0c90, 0x00e3, 0x08e8, 0x0005, 0x79a7,
+	0x79a7, 0x79a7, 0x79a7, 0x79a7, 0x79a7, 0x79a7, 0x79a7, 0x79c9,
+	0x79a7, 0x79a7, 0x79a7, 0x79a7, 0x79a7, 0x79a7, 0x79a7, 0x79a7,
+	0x79a7, 0x79a7, 0x79a7, 0x79a7, 0x79a7, 0x79a7, 0x79a7, 0x79a7,
+	0x79a7, 0x79a7, 0x79a7, 0x79b3, 0x79a7, 0x7ba1, 0x79a7, 0x79a7,
+	0x79a7, 0x79c9, 0x79a7, 0x79b3, 0x7be2, 0x7c23, 0x7c6a, 0x7c7e,
+	0x79a7, 0x79a7, 0x79c9, 0x79b3, 0x79dd, 0x79a7, 0x7a55, 0x7d29,
+	0x7d44, 0x79a7, 0x79c9, 0x79a7, 0x79dd, 0x79a7, 0x79a7, 0x7a4b,
+	0x7d44, 0x79a7, 0x79a7, 0x79a7, 0x79a7, 0x79a7, 0x79a7, 0x79a7,
+	0x79a7, 0x79a7, 0x79f1, 0x79a7, 0x79a7, 0x79a7, 0x79a7, 0x79a7,
+	0x79a7, 0x79a7, 0x79a7, 0x79a7, 0x7ec0, 0x79a7, 0x7e6a, 0x79a7,
+	0x7e6a, 0x79a7, 0x7a06, 0x79a7, 0x79a7, 0x79a7, 0x79a7, 0x79a7,
+	0x79a7, 0x2079, 0x0040, 0x7004, 0x9086, 0x0003, 0x1198, 0x782c,
+	0x080c, 0x7e63, 0xd0a4, 0x0170, 0x7824, 0x2048, 0x9006, 0xa802,
+	0xa806, 0xa864, 0x9084, 0x00ff, 0x908a, 0x001a, 0x1210, 0x002b,
+	0x0c50, 0x00e9, 0x080c, 0x7e3a, 0x0005, 0x79a7, 0x79b3, 0x7b8d,
+	0x79a7, 0x79b3, 0x79a7, 0x79b3, 0x79b3, 0x79a7, 0x79b3, 0x7b8d,
+	0x79b3, 0x79b3, 0x79b3, 0x79b3, 0x79b3, 0x79a7, 0x79b3, 0x7b8d,
+	0x79a7, 0x79a7, 0x79b3, 0x79a7, 0x79a7, 0x79a7, 0x79b3, 0x00e6,
+	0x2071, 0x18fa, 0x2009, 0x0400, 0x0071, 0x00ee, 0x0005, 0x2009,
+	0x1000, 0x0049, 0x0005, 0x2009, 0x2000, 0x0029, 0x0005, 0x2009,
+	0x0800, 0x0009, 0x0005, 0x7007, 0x0001, 0xa868, 0x9084, 0x00ff,
+	0x9105, 0xa86a, 0x0126, 0x2091, 0x8000, 0x080c, 0x6dcb, 0x012e,
+	0x0005, 0xa864, 0x8007, 0x9084, 0x00ff, 0x0d08, 0x8001, 0x1120,
+	0x7007, 0x0001, 0x0804, 0x7b2a, 0x7007, 0x0003, 0x7012, 0x2900,
+	0x7016, 0x701a, 0x704b, 0x7b2a, 0x0005, 0xa864, 0x8007, 0x9084,
+	0x00ff, 0x0968, 0x8001, 0x1120, 0x7007, 0x0001, 0x0804, 0x7b45,
+	0x7007, 0x0003, 0x7012, 0x2900, 0x7016, 0x701a, 0x704b, 0x7b45,
+	0x0005, 0xa864, 0x8007, 0x9084, 0x00ff, 0x0904, 0x79af, 0x8001,
+	0x1120, 0x7007, 0x0001, 0x0804, 0x7b61, 0x7007, 0x0003, 0x7012,
+	0x2900, 0x7016, 0x701a, 0x704b, 0x7b61, 0x0005, 0xa864, 0x8007,
+	0x9084, 0x00ff, 0x9086, 0x0001, 0x1904, 0x79af, 0x7007, 0x0001,
+	0x2009, 0x1834, 0x210c, 0x81ff, 0x11a8, 0xa868, 0x9084, 0x00ff,
+	0xa86a, 0xa883, 0x0000, 0x080c, 0x63b8, 0x1108, 0x0005, 0x0126,
+	0x2091, 0x8000, 0xa867, 0x0139, 0xa87a, 0xa982, 0x080c, 0x6dcb,
+	0x012e, 0x0ca0, 0xa994, 0x9186, 0x0071, 0x0d38, 0x9186, 0x0064,
+	0x0d20, 0x9186, 0x007c, 0x0d08, 0x9186, 0x0028, 0x09f0, 0x9186,
+	0x0038, 0x09d8, 0x9186, 0x0078, 0x09c0, 0x9186, 0x005f, 0x09a8,
+	0x9186, 0x0056, 0x0990, 0xa897, 0x4005, 0xa89b, 0x0001, 0x2001,
+	0x0030, 0x900e, 0x08a0, 0xa87c, 0x9084, 0x00c0, 0x9086, 0x00c0,
+	0x1120, 0x7007, 0x0001, 0x0804, 0x7d5b, 0x2900, 0x7016, 0x701a,
+	0x20a9, 0x0004, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0030, 0x2098,
+	0x7050, 0x2040, 0xa060, 0x20e8, 0xa05c, 0x9080, 0x0023, 0x20a0,
+	0x4003, 0xa888, 0x7012, 0x9082, 0x0401, 0x1a04, 0x79b7, 0xaab4,
+	0x928a, 0x0002, 0x1a04, 0x79b7, 0x82ff, 0x1138, 0xa8b8, 0xa9bc,
+	0x9105, 0x0118, 0x2001, 0x7ae8, 0x0018, 0x9280, 0x7ade, 0x2005,
+	0x7056, 0x7010, 0x9015, 0x0904, 0x7ac9, 0x080c, 0x1027, 0x1118,
+	0x7007, 0x0004, 0x0005, 0x2900, 0x7022, 0x7054, 0x2060, 0xe000,
+	0xa866, 0x7050, 0x2040, 0xa95c, 0xe004, 0x9100, 0xa076, 0xa860,
+	0xa072, 0xe008, 0x920a, 0x1210, 0x900e, 0x2200, 0x7112, 0xe20c,
+	0x8003, 0x800b, 0x9296, 0x0004, 0x0108, 0x9108, 0xa17a, 0x810b,
+	0xa17e, 0x080c, 0x10f8, 0xa06c, 0x908e, 0x0100, 0x0170, 0x9086,
+	0x0200, 0x0118, 0x7007, 0x0007, 0x0005, 0x7020, 0x2048, 0x080c,
+	0x1040, 0x7014, 0x2048, 0x0804, 0x79b7, 0x7020, 0x2048, 0x7018,
+	0xa802, 0xa807, 0x0000, 0x2908, 0x2048, 0xa906, 0x711a, 0x0804,
+	0x7a81, 0x7014, 0x2048, 0x7007, 0x0001, 0xa8b4, 0x9005, 0x1128,
+	0xa8b8, 0xa9bc, 0x9105, 0x0108, 0x00b9, 0xa864, 0x9084, 0x00ff,
+	0x9086, 0x001e, 0x0904, 0x7d5b, 0x0804, 0x7b2a, 0x7ae0, 0x7ae4,
+	0x0002, 0x001d, 0x0007, 0x0004, 0x000a, 0x001b, 0x0005, 0x0006,
+	0x000a, 0x001d, 0x0005, 0x0004, 0x0076, 0x0066, 0xafb8, 0xaebc,
+	0xa804, 0x2050, 0xb0c0, 0xb0e2, 0xb0bc, 0xb0de, 0xb0b8, 0xb0d2,
+	0xb0b4, 0xb0ce, 0xb6da, 0xb7d6, 0xb0b0, 0xb0ca, 0xb0ac, 0xb0c6,
+	0xb0a8, 0xb0ba, 0xb0a4, 0xb0b6, 0xb6c2, 0xb7be, 0xb0a0, 0xb0b2,
+	0xb09c, 0xb0ae, 0xb098, 0xb0a2, 0xb094, 0xb09e, 0xb6aa, 0xb7a6,
+	0xb090, 0xb09a, 0xb08c, 0xb096, 0xb088, 0xb08a, 0xb084, 0xb086,
+	0xb692, 0xb78e, 0xb080, 0xb082, 0xb07c, 0xb07e, 0xb078, 0xb072,
+	0xb074, 0xb06e, 0xb67a, 0xb776, 0xb004, 0x9055, 0x1958, 0x006e,
+	0x007e, 0x0005, 0x2009, 0x1834, 0x210c, 0x81ff, 0x1178, 0x080c,
+	0x61b5, 0x1108, 0x0005, 0x080c, 0x7037, 0x0126, 0x2091, 0x8000,
+	0x080c, 0xd135, 0x080c, 0x6dcb, 0x012e, 0x0ca0, 0x080c, 0xd541,
+	0x1d70, 0x2001, 0x0028, 0x900e, 0x0c70, 0x2009, 0x1834, 0x210c,
+	0x81ff, 0x1188, 0xa888, 0x9005, 0x0188, 0xa883, 0x0000, 0x080c,
+	0x6245, 0x1108, 0x0005, 0xa87a, 0x0126, 0x2091, 0x8000, 0x080c,
+	0x6dcb, 0x012e, 0x0cb8, 0x2001, 0x0028, 0x0ca8, 0x2001, 0x0000,
+	0x0c90, 0x0419, 0x11d8, 0xa888, 0x9005, 0x01e0, 0xa883, 0x0000,
+	0xa87c, 0xd0f4, 0x0120, 0x080c, 0x631a, 0x1138, 0x0005, 0x9006,
+	0xa87a, 0x080c, 0x6292, 0x1108, 0x0005, 0x0126, 0x2091, 0x8000,
+	0xa87a, 0xa982, 0x080c, 0x6dcb, 0x012e, 0x0cb0, 0x2001, 0x0028,
+	0x900e, 0x0c98, 0x2001, 0x0000, 0x0c80, 0x00c6, 0x2061, 0x1800,
+	0x60d0, 0x9005, 0x0100, 0x00ce, 0x0005, 0x7018, 0xa802, 0x2908,
+	0x2048, 0xa906, 0x711a, 0x7010, 0x8001, 0x7012, 0x0118, 0x7007,
+	0x0003, 0x0030, 0x7014, 0x2048, 0x7007, 0x0001, 0x7048, 0x080f,
+	0x0005, 0x00b6, 0x7007, 0x0001, 0xa974, 0xa878, 0x9084, 0x00ff,
+	0x9096, 0x0004, 0x0540, 0x20a9, 0x0001, 0x9096, 0x0001, 0x0190,
+	0x900e, 0x20a9, 0x0800, 0x9096, 0x0002, 0x0160, 0x9005, 0x11d8,
+	0xa974, 0x080c, 0x6717, 0x11b8, 0x0066, 0xae80, 0x080c, 0x6827,
+	0x006e, 0x0088, 0x0046, 0x2011, 0x180c, 0x2224, 0xc484, 0x2412,
+	0x004e, 0x00c6, 0x080c, 0x6717, 0x1110, 0x080c, 0x6927, 0x8108,
+	0x1f04, 0x7bca, 0x00ce, 0xa87c, 0xd084, 0x1120, 0x080c, 0x1040,
+	0x00be, 0x0005, 0x0126, 0x2091, 0x8000, 0x080c, 0x6dcb, 0x012e,
+	0x00be, 0x0005, 0x0126, 0x2091, 0x8000, 0x7007, 0x0001, 0x080c,
+	0x6a88, 0x0580, 0x2061, 0x1a75, 0x6100, 0xd184, 0x0178, 0xa888,
+	0x9084, 0x00ff, 0x1550, 0x6000, 0xd084, 0x0520, 0x6004, 0x9005,
+	0x1538, 0x6003, 0x0000, 0x600b, 0x0000, 0x00c8, 0x2011, 0x0001,
+	0xa890, 0x9005, 0x1110, 0x2001, 0x001e, 0x8000, 0x6016, 0xa888,
+	0x9084, 0x00ff, 0x0178, 0x6006, 0xa888, 0x8007, 0x9084, 0x00ff,
+	0x0148, 0x600a, 0xa888, 0x8000, 0x1108, 0xc28d, 0x6202, 0x012e,
+	0x0804, 0x7e24, 0x012e, 0x0804, 0x7e1e, 0x012e, 0x0804, 0x7e18,
+	0x012e, 0x0804, 0x7e1b, 0x0126, 0x2091, 0x8000, 0x7007, 0x0001,
+	0x080c, 0x6a88, 0x05e0, 0x2061, 0x1a75, 0x6000, 0xd084, 0x05b8,
+	0x6204, 0x6308, 0xd08c, 0x1530, 0xac78, 0x9484, 0x0003, 0x0170,
+	0xa988, 0x918c, 0x00ff, 0x8001, 0x1120, 0x2100, 0x9210, 0x0620,
+	0x0028, 0x8001, 0x1508, 0x2100, 0x9212, 0x02f0, 0x9484, 0x000c,
+	0x0188, 0xa988, 0x810f, 0x918c, 0x00ff, 0x9082, 0x0004, 0x1120,
+	0x2100, 0x9318, 0x0288, 0x0030, 0x9082, 0x0004, 0x1168, 0x2100,
+	0x931a, 0x0250, 0xa890, 0x9005, 0x0110, 0x8000, 0x6016, 0x6206,
+	0x630a, 0x012e, 0x0804, 0x7e24, 0x012e, 0x0804, 0x7e21, 0x012e,
+	0x0804, 0x7e1e, 0x0126, 0x2091, 0x8000, 0x7007, 0x0001, 0x2061,
+	0x1a75, 0x6300, 0xd38c, 0x1120, 0x6308, 0x8318, 0x0220, 0x630a,
+	0x012e, 0x0804, 0x7e32, 0x012e, 0x0804, 0x7e21, 0x00b6, 0x0126,
+	0x00c6, 0x2091, 0x8000, 0x7007, 0x0001, 0xa87c, 0xd0ac, 0x0148,
+	0x00c6, 0x2061, 0x1a75, 0x6000, 0x9084, 0xfcff, 0x6002, 0x00ce,
+	0x0440, 0xa888, 0x9005, 0x05d8, 0xa88c, 0x9065, 0x0598, 0x2001,
+	0x1834, 0x2004, 0x9005, 0x0118, 0x080c, 0xb11a, 0x0068, 0x6017,
+	0xf400, 0x605b, 0x0000, 0xa97c, 0xd1a4, 0x0110, 0xa980, 0x615a,
+	0x2009, 0x0041, 0x080c, 0xb166, 0xa988, 0x918c, 0xff00, 0x9186,
+	0x2000, 0x1138, 0x0026, 0x900e, 0x2011, 0xfdff, 0x080c, 0x8916,
+	0x002e, 0xa87c, 0xd0c4, 0x0148, 0x2061, 0x1a75, 0x6000, 0xd08c,
+	0x1120, 0x6008, 0x8000, 0x0208, 0x600a, 0x00ce, 0x012e, 0x00be,
+	0x0804, 0x7e24, 0x00ce, 0x012e, 0x00be, 0x0804, 0x7e1e, 0xa984,
+	0x9186, 0x002e, 0x0d30, 0x9186, 0x002d, 0x0d18, 0x9186, 0x0045,
+	0x0510, 0x9186, 0x002a, 0x1130, 0x2001, 0x180c, 0x200c, 0xc194,
+	0x2102, 0x08b8, 0x9186, 0x0020, 0x0158, 0x9186, 0x0029, 0x1d10,
+	0xa974, 0x080c, 0x6717, 0x1968, 0xb800, 0xc0e4, 0xb802, 0x0848,
+	0xa88c, 0x9065, 0x09b8, 0x6007, 0x0024, 0x2001, 0x1987, 0x2004,
+	0x601a, 0x0804, 0x7cb9, 0xa88c, 0x9065, 0x0960, 0x00e6, 0xa890,
+	0x9075, 0x2001, 0x1834, 0x2004, 0x9005, 0x0150, 0x080c, 0xb11a,
+	0x8eff, 0x0118, 0x2e60, 0x080c, 0xb11a, 0x00ee, 0x0804, 0x7cb9,
+	0x6024, 0xc0dc, 0xc0d5, 0x6026, 0x2e60, 0x6007, 0x003a, 0xa8a0,
+	0x9005, 0x0130, 0x6007, 0x003b, 0xa8a4, 0x602e, 0xa8a8, 0x6016,
+	0x6003, 0x0001, 0x080c, 0x9335, 0x080c, 0x98e7, 0x00ee, 0x0804,
+	0x7cb9, 0x2061, 0x1a75, 0x6000, 0xd084, 0x0190, 0xd08c, 0x1904,
+	0x7e32, 0x0126, 0x2091, 0x8000, 0x6204, 0x8210, 0x0220, 0x6206,
+	0x012e, 0x0804, 0x7e32, 0x012e, 0xa883, 0x0016, 0x0804, 0x7e2b,
+	0xa883, 0x0007, 0x0804, 0x7e2b, 0xa864, 0x8007, 0x9084, 0x00ff,
+	0x0130, 0x8001, 0x1138, 0x7007, 0x0001, 0x0069, 0x0005, 0x080c,
+	0x79af, 0x0040, 0x7007, 0x0003, 0x7012, 0x2900, 0x7016, 0x701a,
+	0x704b, 0x7d5b, 0x0005, 0x00b6, 0x00e6, 0x0126, 0x2091, 0x8000,
+	0x903e, 0x2061, 0x1800, 0x61d0, 0x81ff, 0x1904, 0x7ddd, 0x6130,
+	0xd194, 0x1904, 0x7e07, 0xa878, 0x2070, 0x9e82, 0x1cd0, 0x0a04,
+	0x7dd1, 0x6068, 0x9e02, 0x1a04, 0x7dd1, 0x7120, 0x9186, 0x0006,
+	0x1904, 0x7dc3, 0x7010, 0x905d, 0x0904, 0x7ddd, 0xb800, 0xd0e4,
+	0x1904, 0x7e01, 0x2061, 0x1a75, 0x6100, 0x9184, 0x0301, 0x9086,
+	0x0001, 0x15a0, 0x7024, 0xd0dc, 0x1904, 0x7e0a, 0xa883, 0x0000,
+	0xa803, 0x0000, 0x2908, 0x7014, 0x9005, 0x1198, 0x7116, 0xa87c,
+	0xd0f4, 0x1904, 0x7e0d, 0x080c, 0x57cd, 0xd09c, 0x1118, 0xa87c,
+	0xc0cc, 0xa87e, 0x2e60, 0x080c, 0x8836, 0x012e, 0x00ee, 0x00be,
+	0x0005, 0x2048, 0xa800, 0x9005, 0x1de0, 0xa902, 0x2148, 0xa87c,
+	0xd0f4, 0x1904, 0x7e0d, 0x012e, 0x00ee, 0x00be, 0x0005, 0x012e,
+	0x00ee, 0xa883, 0x0006, 0x00be, 0x0804, 0x7e2b, 0xd184, 0x0db8,
+	0xd1c4, 0x1190, 0x00a0, 0xa974, 0x080c, 0x6717, 0x15d0, 0xb800,
+	0xd0e4, 0x15b8, 0x7120, 0x9186, 0x0007, 0x1118, 0xa883, 0x0002,
+	0x0490, 0xa883, 0x0008, 0x0478, 0xa883, 0x000e, 0x0460, 0xa883,
+	0x0017, 0x0448, 0xa883, 0x0035, 0x0430, 0x080c, 0x57d1, 0xd0fc,
+	0x01e8, 0xa878, 0x2070, 0x9e82, 0x1cd0, 0x02c0, 0x6068, 0x9e02,
+	0x12a8, 0x7120, 0x9186, 0x0006, 0x1188, 0x7010, 0x905d, 0x0170,
+	0xb800, 0xd0bc, 0x0158, 0x2039, 0x0001, 0x7000, 0x9086, 0x0007,
+	0x1904, 0x7d67, 0x7003, 0x0002, 0x0804, 0x7d67, 0xa883, 0x0028,
+	0x0010, 0xa883, 0x0029, 0x012e, 0x00ee, 0x00be, 0x0420, 0xa883,
+	0x002a, 0x0cc8, 0xa883, 0x0045, 0x0cb0, 0x2e60, 0x2019, 0x0002,
+	0x601b, 0x0014, 0x080c, 0xe4ba, 0x012e, 0x00ee, 0x00be, 0x0005,
+	0x2009, 0x003e, 0x0058, 0x2009, 0x0004, 0x0040, 0x2009, 0x0006,
+	0x0028, 0x2009, 0x0016, 0x0010, 0x2009, 0x0001, 0xa884, 0x9084,
+	0xff00, 0x9105, 0xa886, 0x0126, 0x2091, 0x8000, 0x080c, 0x6dcb,
+	0x012e, 0x0005, 0x080c, 0x1040, 0x0005, 0x00d6, 0x080c, 0x882d,
+	0x00de, 0x0005, 0x00d6, 0x00e6, 0x0126, 0x2091, 0x8000, 0x2071,
+	0x0040, 0x702c, 0xd084, 0x01d8, 0x908c, 0x0780, 0x190c, 0x7f1c,
+	0xd09c, 0x11a8, 0x2071, 0x1800, 0x70c0, 0x90ea, 0x0020, 0x0278,
+	0x8001, 0x70c2, 0x702c, 0x2048, 0xa800, 0x702e, 0x9006, 0xa802,
+	0xa806, 0x2071, 0x0040, 0x2900, 0x7022, 0x702c, 0x0c28, 0x012e,
+	0x00ee, 0x00de, 0x0005, 0x0006, 0x9084, 0x0780, 0x190c, 0x7f1c,
+	0x000e, 0x0005, 0xa898, 0x9084, 0x0003, 0x05a8, 0x080c, 0xb091,
+	0x05d8, 0x2900, 0x6016, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0035,
+	0x1138, 0x6008, 0xc0fd, 0x600a, 0x2001, 0x196c, 0x2004, 0x0098,
+	0xa8a0, 0x9084, 0x00ff, 0xa99c, 0x918c, 0xff00, 0x9105, 0xa99c,
+	0x918c, 0x00ff, 0x080c, 0x2889, 0x1540, 0x00b6, 0x080c, 0x6717,
+	0x2b00, 0x00be, 0x1510, 0x6012, 0x6023, 0x0001, 0x2009, 0x0040,
+	0xa864, 0x9084, 0x00ff, 0x9086, 0x0035, 0x0110, 0x2009, 0x0041,
+	0x080c, 0xb166, 0x0005, 0xa87b, 0x0101, 0x0126, 0x2091, 0x8000,
+	0x080c, 0x6dcb, 0x012e, 0x0005, 0xa87b, 0x002c, 0x0126, 0x2091,
+	0x8000, 0x080c, 0x6dcb, 0x012e, 0x0005, 0xa87b, 0x0028, 0x0126,
+	0x2091, 0x8000, 0x080c, 0x6dcb, 0x012e, 0x080c, 0xb0e7, 0x0005,
+	0x00d6, 0x00c6, 0x0036, 0x0026, 0x0016, 0x00b6, 0x7007, 0x0001,
+	0xaa74, 0x9282, 0x0004, 0x1a04, 0x7f0d, 0xa97c, 0x9188, 0x1000,
+	0x2104, 0x905d, 0xb804, 0xd284, 0x0140, 0x05e8, 0x8007, 0x9084,
+	0x00ff, 0x9084, 0x0006, 0x1108, 0x04b0, 0x2b10, 0x080c, 0xb091,
+	0x1118, 0x080c, 0xb139, 0x05a8, 0x6212, 0xa874, 0x0002, 0x7eeb,
+	0x7ef0, 0x7ef3, 0x7ef9, 0x2019, 0x0002, 0x080c, 0xe8b0, 0x0060,
+	0x080c, 0xe847, 0x0048, 0x2019, 0x0002, 0xa980, 0x080c, 0xe862,
+	0x0018, 0xa980, 0x080c, 0xe847, 0x080c, 0xb0e7, 0xa887, 0x0000,
+	0x0126, 0x2091, 0x8000, 0x080c, 0x6dcb, 0x012e, 0x00be, 0x001e,
+	0x002e, 0x003e, 0x00ce, 0x00de, 0x0005, 0xa887, 0x0006, 0x0c80,
+	0xa887, 0x0002, 0x0c68, 0xa887, 0x0005, 0x0c50, 0xa887, 0x0004,
+	0x0c38, 0xa887, 0x0007, 0x0c20, 0x2091, 0x8000, 0x0e04, 0x7f1e,
+	0x0006, 0x0016, 0x2001, 0x8003, 0x0006, 0x0804, 0x0dce, 0x2001,
+	0x1834, 0x2004, 0x9005, 0x0005, 0x0005, 0x00f6, 0x2079, 0x0300,
+	0x2001, 0x0200, 0x200c, 0xc1e5, 0xc1dc, 0x2102, 0x2009, 0x0218,
+	0x210c, 0xd1ec, 0x1120, 0x080c, 0x15a0, 0x00fe, 0x0005, 0x2001,
+	0x020d, 0x2003, 0x0020, 0x781f, 0x0300, 0x00fe, 0x0005, 0x781c,
+	0xd08c, 0x0904, 0x7f9e, 0x68c0, 0x90aa, 0x0005, 0x0a04, 0x85e2,
+	0x7d44, 0x7c40, 0x9584, 0x00f6, 0x1510, 0x9484, 0x7000, 0x0140,
+	0x908a, 0x2000, 0x1260, 0x9584, 0x0700, 0x8007, 0x0804, 0x7fa5,
+	0x7000, 0x9084, 0xff00, 0x9086, 0x8100, 0x0da8, 0x00b0, 0x9484,
+	0x0fff, 0x1130, 0x7000, 0x9084, 0xff00, 0x9086, 0x8100, 0x11c0,
+	0x080c, 0xed6d, 0x080c, 0x84c7, 0x7817, 0x0140, 0x00a8, 0x9584,
+	0x0076, 0x1118, 0x080c, 0x8525, 0x19c0, 0xd5a4, 0x0148, 0x0046,
+	0x0056, 0x080c, 0x8000, 0x080c, 0x238f, 0x005e, 0x004e, 0x0020,
+	0x080c, 0xed6d, 0x7817, 0x0140, 0x080c, 0x7563, 0x0168, 0x2001,
+	0x0111, 0x2004, 0xd08c, 0x0140, 0x6893, 0x0000, 0x2001, 0x0110,
+	0x2003, 0x0008, 0x2003, 0x0000, 0x080c, 0x7fe1, 0x2001, 0x19f2,
+	0x2004, 0x9005, 0x090c, 0x98e7, 0x0005, 0x0002, 0x7fb7, 0x82cf,
+	0x7fae, 0x7fae, 0x7fae, 0x7fae, 0x7fae, 0x7fae, 0x7817, 0x0140,
+	0x2001, 0x19f2, 0x2004, 0x9005, 0x090c, 0x98e7, 0x0005, 0x7000,
+	0x908c, 0xff00, 0x9194, 0xf000, 0x810f, 0x9484, 0x0fff, 0x6892,
+	0x9286, 0x2000, 0x1150, 0x6800, 0x9086, 0x0001, 0x1118, 0x080c,
+	0x5837, 0x0070, 0x080c, 0x8020, 0x0058, 0x9286, 0x3000, 0x1118,
+	0x080c, 0x8207, 0x0028, 0x9286, 0x8000, 0x1110, 0x080c, 0x83ee,
+	0x7817, 0x0140, 0x2001, 0x19f2, 0x2004, 0x9005, 0x090c, 0x98e7,
+	0x0005, 0x2001, 0x1810, 0x2004, 0xd08c, 0x0178, 0x2001, 0x1800,
+	0x2004, 0x9086, 0x0003, 0x1148, 0x0026, 0x0036, 0x2011, 0x8048,
+	0x2518, 0x080c, 0x4be3, 0x003e, 0x002e, 0x0005, 0x0036, 0x0046,
+	0x0056, 0x00f6, 0x2079, 0x0200, 0x2019, 0xfffe, 0x7c30, 0x0050,
+	0x0036, 0x0046, 0x0056, 0x00f6, 0x2079, 0x0200, 0x7d44, 0x7c40,
+	0x2019, 0xffff, 0x2001, 0x1810, 0x2004, 0xd08c, 0x0160, 0x2001,
+	0x1800, 0x2004, 0x9086, 0x0003, 0x1130, 0x0026, 0x2011, 0x8048,
+	0x080c, 0x4be3, 0x002e, 0x00fe, 0x005e, 0x004e, 0x003e, 0x0005,
+	0x00b6, 0x00c6, 0x7010, 0x9084, 0xff00, 0x8007, 0x9096, 0x0001,
+	0x0120, 0x9096, 0x0023, 0x1904, 0x81d8, 0x9186, 0x0023, 0x15c0,
+	0x080c, 0x848c, 0x0904, 0x81d8, 0x6120, 0x9186, 0x0001, 0x0150,
+	0x9186, 0x0004, 0x0138, 0x9186, 0x0008, 0x0120, 0x9186, 0x000a,
+	0x1904, 0x81d8, 0x7124, 0x610a, 0x7030, 0x908e, 0x0200, 0x1130,
+	0x2009, 0x0015, 0x080c, 0xb166, 0x0804, 0x81d8, 0x908e, 0x0214,
+	0x0118, 0x908e, 0x0210, 0x1130, 0x2009, 0x0015, 0x080c, 0xb166,
+	0x0804, 0x81d8, 0x908e, 0x0100, 0x1904, 0x81d8, 0x7034, 0x9005,
+	0x1904, 0x81d8, 0x2009, 0x0016, 0x080c, 0xb166, 0x0804, 0x81d8,
+	0x9186, 0x0022, 0x1904, 0x81d8, 0x7030, 0x908e, 0x0300, 0x1580,
+	0x68dc, 0xd0a4, 0x0528, 0xc0b5, 0x68de, 0x7100, 0x918c, 0x00ff,
+	0x697e, 0x7004, 0x6882, 0x00f6, 0x2079, 0x0100, 0x79e6, 0x78ea,
+	0x0006, 0x9084, 0x00ff, 0x0016, 0x2008, 0x080c, 0x28d2, 0x7932,
+	0x7936, 0x001e, 0x000e, 0x00fe, 0x080c, 0x2889, 0x695e, 0x703c,
+	0x00e6, 0x2071, 0x0140, 0x7086, 0x2071, 0x1800, 0x70b6, 0x00ee,
+	0x7034, 0x9005, 0x1904, 0x81d8, 0x2009, 0x0017, 0x0804, 0x8188,
+	0x908e, 0x0400, 0x1190, 0x7034, 0x9005, 0x1904, 0x81d8, 0x080c,
+	0x7563, 0x0120, 0x2009, 0x001d, 0x0804, 0x8188, 0x68dc, 0xc0a5,
+	0x68de, 0x2009, 0x0030, 0x0804, 0x8188, 0x908e, 0x0500, 0x1140,
+	0x7034, 0x9005, 0x1904, 0x81d8, 0x2009, 0x0018, 0x0804, 0x8188,
+	0x908e, 0x2010, 0x1120, 0x2009, 0x0019, 0x0804, 0x8188, 0x908e,
+	0x2110, 0x1120, 0x2009, 0x001a, 0x0804, 0x8188, 0x908e, 0x5200,
+	0x1140, 0x7034, 0x9005, 0x1904, 0x81d8, 0x2009, 0x001b, 0x0804,
+	0x8188, 0x908e, 0x5000, 0x1140, 0x7034, 0x9005, 0x1904, 0x81d8,
+	0x2009, 0x001c, 0x0804, 0x8188, 0x908e, 0x1300, 0x1120, 0x2009,
+	0x0034, 0x0804, 0x8188, 0x908e, 0x1200, 0x1140, 0x7034, 0x9005,
+	0x1904, 0x81d8, 0x2009, 0x0024, 0x0804, 0x8188, 0x908c, 0xff00,
+	0x918e, 0x2400, 0x1170, 0x2009, 0x002d, 0x2001, 0x1810, 0x2004,
+	0xd09c, 0x0904, 0x8188, 0x080c, 0xdc7f, 0x1904, 0x81d8, 0x0804,
+	0x8186, 0x908c, 0xff00, 0x918e, 0x5300, 0x1120, 0x2009, 0x002a,
+	0x0804, 0x8188, 0x908e, 0x0f00, 0x1120, 0x2009, 0x0020, 0x0804,
+	0x8188, 0x908e, 0x6104, 0x1530, 0x2029, 0x0205, 0x2011, 0x026d,
+	0x8208, 0x2204, 0x9082, 0x0004, 0x8004, 0x8004, 0x20a8, 0x2011,
+	0x8015, 0x211c, 0x8108, 0x0046, 0x2124, 0x080c, 0x4be3, 0x004e,
+	0x8108, 0x0f04, 0x813c, 0x9186, 0x0280, 0x1d88, 0x2504, 0x8000,
+	0x202a, 0x2009, 0x0260, 0x0c58, 0x202b, 0x0000, 0x2009, 0x0023,
+	0x0804, 0x8188, 0x908e, 0x6000, 0x1120, 0x2009, 0x003f, 0x0804,
+	0x8188, 0x908e, 0x5400, 0x1138, 0x080c, 0x8592, 0x1904, 0x81d8,
+	0x2009, 0x0046, 0x04a8, 0x908e, 0x5500, 0x1148, 0x080c, 0x85ba,
+	0x1118, 0x2009, 0x0041, 0x0460, 0x2009, 0x0042, 0x0448, 0x908e,
+	0x7800, 0x1118, 0x2009, 0x0045, 0x0418, 0x908e, 0x1000, 0x1118,
+	0x2009, 0x004e, 0x00e8, 0x908e, 0x6300, 0x1118, 0x2009, 0x004a,
+	0x00b8, 0x908c, 0xff00, 0x918e, 0x5600, 0x1118, 0x2009, 0x004f,
+	0x0078, 0x908c, 0xff00, 0x918e, 0x5700, 0x1118, 0x2009, 0x0050,
+	0x0038, 0x2009, 0x001d, 0x6838, 0xd0d4, 0x0110, 0x2009, 0x004c,
+	0x0016, 0x2011, 0x0263, 0x2204, 0x8211, 0x220c, 0x080c, 0x2889,
+	0x1904, 0x81db, 0x080c, 0x66ac, 0x1904, 0x81db, 0xbe12, 0xbd16,
+	0x001e, 0x0016, 0x080c, 0x7563, 0x01c0, 0x68dc, 0xd08c, 0x1148,
+	0x7000, 0x9084, 0x00ff, 0x1188, 0x7004, 0x9084, 0xff00, 0x1168,
+	0x0040, 0x687c, 0x9606, 0x1148, 0x6880, 0x9506, 0x9084, 0xff00,
+	0x1120, 0x9584, 0x00ff, 0xb8c2, 0x0080, 0xb8c0, 0x9005, 0x1168,
+	0x9186, 0x0046, 0x1150, 0x687c, 0x9606, 0x1138, 0x6880, 0x9506,
+	0x9084, 0xff00, 0x1110, 0x001e, 0x0098, 0x080c, 0xb091, 0x01a8,
+	0x2b08, 0x6112, 0x6023, 0x0004, 0x7120, 0x610a, 0x001e, 0x9186,
+	0x004c, 0x1110, 0x6023, 0x000a, 0x0016, 0x001e, 0x080c, 0xb166,
+	0x00ce, 0x00be, 0x0005, 0x001e, 0x0cd8, 0x2001, 0x180e, 0x2004,
+	0xd0ec, 0x0120, 0x2011, 0x8049, 0x080c, 0x4be3, 0x080c, 0xb139,
+	0x0d90, 0x2b08, 0x6112, 0x6023, 0x0004, 0x7120, 0x610a, 0x001e,
+	0x0016, 0x9186, 0x0017, 0x0118, 0x9186, 0x0030, 0x1128, 0x6007,
+	0x0009, 0x6017, 0x2900, 0x0020, 0x6007, 0x0051, 0x6017, 0x0000,
+	0x602f, 0x0009, 0x6003, 0x0001, 0x080c, 0x937d, 0x08a0, 0x080c,
+	0x8601, 0x1158, 0x080c, 0x336f, 0x1140, 0x7010, 0x9084, 0xff00,
+	0x8007, 0x908e, 0x0008, 0x1108, 0x0009, 0x0005, 0x00b6, 0x00c6,
+	0x0046, 0x7000, 0x908c, 0xff00, 0x810f, 0x9186, 0x0033, 0x11e8,
+	0x080c, 0x848c, 0x0904, 0x8267, 0x7124, 0x610a, 0x7030, 0x908e,
+	0x0200, 0x1140, 0x7034, 0x9005, 0x15d0, 0x2009, 0x0015, 0x080c,
+	0xb166, 0x04a8, 0x908e, 0x0100, 0x1590, 0x7034, 0x9005, 0x1578,
+	0x2009, 0x0016, 0x080c, 0xb166, 0x0450, 0x9186, 0x0032, 0x1538,
+	0x7030, 0x908e, 0x1400, 0x1518, 0x2009, 0x0038, 0x0016, 0x2011,
+	0x0263, 0x2204, 0x8211, 0x220c, 0x080c, 0x2889, 0x11b8, 0x080c,
+	0x66ac, 0x11a0, 0xbe12, 0xbd16, 0x080c, 0xb091, 0x0178, 0x2b08,
+	0x6112, 0x080c, 0xd2bb, 0x6023, 0x0004, 0x7120, 0x610a, 0x001e,
+	0x080c, 0xb166, 0x080c, 0x98e7, 0x0010, 0x00ce, 0x001e, 0x004e,
+	0x00ce, 0x00be, 0x0005, 0x00b6, 0x0046, 0x00e6, 0x00d6, 0x2028,
+	0x2130, 0x9696, 0x00ff, 0x11b8, 0x9592, 0xfffc, 0x02a0, 0x9596,
+	0xfffd, 0x1120, 0x2009, 0x007f, 0x0804, 0x82c9, 0x9596, 0xfffe,
+	0x1120, 0x2009, 0x007e, 0x0804, 0x82c9, 0x9596, 0xfffc, 0x1118,
+	0x2009, 0x0080, 0x04f0, 0x2011, 0x0000, 0x2019, 0x1837, 0x231c,
+	0xd3ac, 0x0130, 0x9026, 0x20a9, 0x0800, 0x2071, 0x1000, 0x0030,
+	0x2021, 0x0081, 0x20a9, 0x077f, 0x2071, 0x1081, 0x2e1c, 0x93dd,
+	0x0000, 0x1140, 0x82ff, 0x11d0, 0x9496, 0x00ff, 0x01b8, 0x2410,
+	0xc2fd, 0x00a0, 0xbf10, 0x2600, 0x9706, 0xb814, 0x1120, 0x9546,
+	0x1110, 0x2408, 0x00b0, 0x9745, 0x1148, 0x94c6, 0x007e, 0x0130,
+	0x94c6, 0x007f, 0x0118, 0x94c6, 0x0080, 0x1d20, 0x8420, 0x8e70,
+	0x1f04, 0x829e, 0x82ff, 0x1118, 0x9085, 0x0001, 0x0018, 0xc2fc,
+	0x2208, 0x9006, 0x00de, 0x00ee, 0x004e, 0x00be, 0x0005, 0x2001,
+	0x1837, 0x200c, 0x9184, 0x0080, 0x0110, 0xd18c, 0x0138, 0x7000,
+	0x908c, 0xff00, 0x810f, 0x9184, 0x000f, 0x004a, 0x7817, 0x0140,
+	0x2001, 0x19f2, 0x2004, 0x9005, 0x090c, 0x98e7, 0x0005, 0x82f7,
+	0x82f7, 0x82f7, 0x849e, 0x82f7, 0x8300, 0x832b, 0x83b9, 0x82f7,
+	0x82f7, 0x82f7, 0x82f7, 0x82f7, 0x82f7, 0x82f7, 0x82f7, 0x7817,
+	0x0140, 0x2001, 0x19f2, 0x2004, 0x9005, 0x090c, 0x98e7, 0x0005,
+	0x00b6, 0x7110, 0xd1bc, 0x01e8, 0x7120, 0x2160, 0x9c8c, 0x0007,
+	0x11c0, 0x9c8a, 0x1cd0, 0x02a8, 0x6868, 0x9c02, 0x1290, 0x7008,
 	0x9084, 0x00ff, 0x6110, 0x2158, 0xb910, 0x9106, 0x1150, 0x700c,
-	0xb914, 0x9106, 0x1130, 0x7124, 0x610a, 0x2009, 0x0045, 0x080c,
-	0xafbe, 0x7817, 0x0140, 0x2001, 0x19ef, 0x2004, 0x9005, 0x090c,
-	0x9763, 0x00be, 0x0005, 0x6120, 0x9186, 0x0002, 0x0128, 0x9186,
-	0x0005, 0x0110, 0x9085, 0x0001, 0x0005, 0x080c, 0x84d8, 0x1180,
-	0x080c, 0x3342, 0x1168, 0x7010, 0x9084, 0xff00, 0x8007, 0x9086,
-	0x0000, 0x1130, 0x9184, 0x000f, 0x908a, 0x0006, 0x1208, 0x000b,
-	0x0005, 0x82df, 0x82e0, 0x82df, 0x82df, 0x8345, 0x8354, 0x0005,
-	0x00b6, 0x700c, 0x7108, 0x080c, 0x287c, 0x1904, 0x8343, 0x080c,
-	0x6638, 0x1904, 0x8343, 0xbe12, 0xbd16, 0x7110, 0xd1bc, 0x0540,
-	0x702c, 0xd084, 0x1120, 0xb800, 0xd0bc, 0x1904, 0x8343, 0x080c,
-	0x6a0c, 0x0148, 0x9086, 0x0004, 0x0130, 0x080c, 0x6a14, 0x0118,
-	0x9086, 0x0004, 0x1588, 0x00c6, 0x080c, 0x8363, 0x00ce, 0x05d8,
-	0x080c, 0xaeed, 0x2b08, 0x05b8, 0x6112, 0x080c, 0xd102, 0x6023,
-	0x0002, 0x7120, 0x610a, 0x2009, 0x0088, 0x080c, 0xafbe, 0x0458,
-	0x080c, 0x6a0c, 0x0148, 0x9086, 0x0004, 0x0130, 0x080c, 0x6a14,
-	0x0118, 0x9086, 0x0004, 0x1180, 0x080c, 0xaeed, 0x2b08, 0x01d8,
-	0x6112, 0x080c, 0xd102, 0x6023, 0x0005, 0x7120, 0x610a, 0x2009,
-	0x0088, 0x080c, 0xafbe, 0x0078, 0x080c, 0xaeed, 0x2b08, 0x0158,
-	0x6112, 0x080c, 0xd102, 0x6023, 0x0004, 0x7120, 0x610a, 0x2009,
-	0x0001, 0x080c, 0xafbe, 0x00be, 0x0005, 0x7110, 0xd1bc, 0x0158,
-	0x00d1, 0x0148, 0x080c, 0x82bb, 0x1130, 0x7124, 0x610a, 0x2009,
-	0x0089, 0x080c, 0xafbe, 0x0005, 0x7110, 0xd1bc, 0x0158, 0x0059,
-	0x0148, 0x080c, 0x82bb, 0x1130, 0x7124, 0x610a, 0x2009, 0x008a,
-	0x080c, 0xafbe, 0x0005, 0x7020, 0x2060, 0x9c84, 0x0007, 0x1158,
-	0x9c82, 0x1cd0, 0x0240, 0x2001, 0x181a, 0x2004, 0x9c02, 0x1218,
-	0x9085, 0x0001, 0x0005, 0x9006, 0x0ce8, 0x00b6, 0x7110, 0xd1bc,
-	0x11d8, 0x7024, 0x2060, 0x9c84, 0x0007, 0x11b0, 0x9c82, 0x1cd0,
-	0x0298, 0x6868, 0x9c02, 0x1280, 0x7008, 0x9084, 0x00ff, 0x6110,
-	0x2158, 0xb910, 0x9106, 0x1140, 0x700c, 0xb914, 0x9106, 0x1120,
-	0x2009, 0x0051, 0x080c, 0xafbe, 0x7817, 0x0140, 0x2001, 0x19ef,
-	0x2004, 0x9005, 0x090c, 0x9763, 0x00be, 0x0005, 0x2031, 0x0105,
-	0x0069, 0x0005, 0x2031, 0x0206, 0x0049, 0x0005, 0x2031, 0x0207,
-	0x0029, 0x0005, 0x2031, 0x0213, 0x0009, 0x0005, 0x00c6, 0x0096,
-	0x00f6, 0x7000, 0x9084, 0xf000, 0x9086, 0xc000, 0x05d0, 0x080c,
-	0xaeed, 0x05b8, 0x0066, 0x00c6, 0x0046, 0x2011, 0x0263, 0x2204,
-	0x8211, 0x220c, 0x080c, 0x287c, 0x15a0, 0x080c, 0x6638, 0x1588,
-	0xbe12, 0xbd16, 0x2b00, 0x004e, 0x00ce, 0x6012, 0x080c, 0xd102,
-	0x080c, 0x0fff, 0x0510, 0x2900, 0x605a, 0x9006, 0xa802, 0xa866,
-	0xac6a, 0xa85c, 0x90f8, 0x001b, 0x20a9, 0x000e, 0xa860, 0x20e8,
-	0x20e1, 0x0000, 0x2fa0, 0x2e98, 0x4003, 0x006e, 0x6616, 0x6007,
-	0x003e, 0x6023, 0x0001, 0x6003, 0x0001, 0x080c, 0x91f9, 0x080c,
-	0x9763, 0x00fe, 0x009e, 0x00ce, 0x0005, 0x080c, 0xaf43, 0x006e,
-	0x0cc0, 0x004e, 0x00ce, 0x0cc8, 0x00c6, 0x7000, 0x908c, 0xff00,
-	0x9184, 0xf000, 0x810f, 0x9086, 0x2000, 0x1904, 0x8453, 0x9186,
-	0x0022, 0x15f0, 0x2001, 0x0111, 0x2004, 0x9005, 0x1904, 0x8455,
-	0x7030, 0x908e, 0x0400, 0x0904, 0x8455, 0x908e, 0x6000, 0x05e8,
-	0x908e, 0x5400, 0x05d0, 0x908e, 0x0300, 0x11d8, 0x2009, 0x1837,
-	0x210c, 0xd18c, 0x1590, 0xd1a4, 0x1580, 0x080c, 0x69ca, 0x0588,
-	0x68b0, 0x9084, 0x00ff, 0x7100, 0x918c, 0x00ff, 0x9106, 0x1518,
-	0x6880, 0x69b0, 0x918c, 0xff00, 0x9105, 0x7104, 0x9106, 0x11d8,
-	0x00e0, 0x2009, 0x0103, 0x210c, 0xd1b4, 0x11a8, 0x908e, 0x5200,
-	0x09e8, 0x908e, 0x0500, 0x09d0, 0x908e, 0x5000, 0x09b8, 0x0058,
-	0x9186, 0x0023, 0x1140, 0x080c, 0x8363, 0x0128, 0x6004, 0x9086,
-	0x0002, 0x0118, 0x0000, 0x9006, 0x0010, 0x9085, 0x0001, 0x00ce,
-	0x0005, 0x7030, 0x908e, 0x0300, 0x0118, 0x908e, 0x5200, 0x1d98,
-	0x2001, 0x1837, 0x2004, 0x9084, 0x0009, 0x9086, 0x0008, 0x0d68,
-	0x0c50, 0x0156, 0x0046, 0x0016, 0x0036, 0x7038, 0x2020, 0x8427,
-	0x94a4, 0x0007, 0xd484, 0x0148, 0x20a9, 0x0004, 0x2019, 0x1805,
-	0x2011, 0x027a, 0x080c, 0xbefd, 0x1178, 0xd48c, 0x0148, 0x20a9,
-	0x0004, 0x2019, 0x1801, 0x2011, 0x027e, 0x080c, 0xbefd, 0x1120,
-	0xd494, 0x0110, 0x9085, 0x0001, 0x003e, 0x001e, 0x004e, 0x015e,
-	0x0005, 0x0156, 0x0046, 0x0016, 0x0036, 0x7038, 0x2020, 0x8427,
-	0x94a4, 0x0007, 0xd484, 0x0148, 0x20a9, 0x0004, 0x2019, 0x1805,
-	0x2011, 0x0272, 0x080c, 0xbefd, 0x1178, 0xd48c, 0x0148, 0x20a9,
-	0x0004, 0x2019, 0x1801, 0x2011, 0x0276, 0x080c, 0xbefd, 0x1120,
-	0xd494, 0x0110, 0x9085, 0x0001, 0x003e, 0x001e, 0x004e, 0x015e,
-	0x0005, 0x00f6, 0x2079, 0x0200, 0x7800, 0xc0e5, 0xc0cc, 0x7802,
-	0x00fe, 0x0005, 0x00f6, 0x2079, 0x1800, 0x7834, 0xd084, 0x1130,
-	0x2079, 0x0200, 0x7800, 0x9085, 0x1200, 0x7802, 0x00fe, 0x0005,
-	0x00e6, 0x2071, 0x1800, 0x7034, 0xc084, 0x7036, 0x00ee, 0x0005,
-	0x0016, 0x2001, 0x1837, 0x200c, 0x9184, 0x0080, 0x0118, 0xd18c,
-	0x0118, 0x9006, 0x001e, 0x0005, 0x9085, 0x0001, 0x0cd8, 0x2071,
-	0x19f9, 0x7003, 0x0003, 0x700f, 0x0361, 0x9006, 0x701a, 0x7072,
-	0x7012, 0x7017, 0x1cd0, 0x7007, 0x0000, 0x7026, 0x702b, 0xa36c,
-	0x7032, 0x7037, 0xa3d4, 0x703f, 0xffff, 0x7042, 0x7047, 0x55ef,
-	0x704a, 0x705b, 0x8651, 0x080c, 0x1018, 0x090c, 0x0dd5, 0x2900,
-	0x703a, 0xa867, 0x0003, 0xa86f, 0x0100, 0xa8ab, 0xdcb0, 0x0005,
-	0x2071, 0x19f9, 0x1d04, 0x859f, 0x2091, 0x6000, 0x700c, 0x8001,
-	0x700e, 0x1530, 0x2001, 0x013c, 0x2004, 0x9005, 0x190c, 0x8696,
-	0x2001, 0x1869, 0x2004, 0xd0c4, 0x0158, 0x3a00, 0xd08c, 0x1140,
-	0x20d1, 0x0000, 0x20d1, 0x0001, 0x20d1, 0x0000, 0x080c, 0x0dd5,
-	0x700f, 0x0361, 0x7007, 0x0001, 0x0126, 0x2091, 0x8000, 0x7040,
-	0x900d, 0x0148, 0x8109, 0x7142, 0x1130, 0x7044, 0x080f, 0x0018,
-	0x0126, 0x2091, 0x8000, 0x7024, 0x900d, 0x0188, 0x7020, 0x8001,
-	0x7022, 0x1168, 0x7023, 0x0009, 0x8109, 0x7126, 0x9186, 0x03e8,
-	0x1110, 0x7028, 0x080f, 0x81ff, 0x1110, 0x7028, 0x080f, 0x7030,
-	0x900d, 0x0180, 0x702c, 0x8001, 0x702e, 0x1160, 0x702f, 0x0009,
-	0x8109, 0x7132, 0x0128, 0x9184, 0x007f, 0x090c, 0xa50e, 0x0010,
-	0x7034, 0x080f, 0x703c, 0x9005, 0x0118, 0x0310, 0x8001, 0x703e,
-	0x704c, 0x900d, 0x0168, 0x7048, 0x8001, 0x704a, 0x1148, 0x704b,
-	0x0009, 0x8109, 0x714e, 0x1120, 0x7150, 0x714e, 0x7058, 0x080f,
-	0x7018, 0x900d, 0x01d8, 0x0016, 0x7070, 0x900d, 0x0158, 0x706c,
-	0x8001, 0x706e, 0x1138, 0x706f, 0x0009, 0x8109, 0x7172, 0x1110,
-	0x7074, 0x080f, 0x001e, 0x7008, 0x8001, 0x700a, 0x1138, 0x700b,
-	0x0009, 0x8109, 0x711a, 0x1110, 0x701c, 0x080f, 0x012e, 0x7004,
-	0x0002, 0x85c7, 0x85c8, 0x85e4, 0x00e6, 0x2071, 0x19f9, 0x7018,
-	0x9005, 0x1120, 0x711a, 0x721e, 0x700b, 0x0009, 0x00ee, 0x0005,
-	0x00e6, 0x0006, 0x2071, 0x19f9, 0x701c, 0x9206, 0x1120, 0x701a,
-	0x701e, 0x7072, 0x7076, 0x000e, 0x00ee, 0x0005, 0x00e6, 0x2071,
-	0x19f9, 0xb888, 0x9102, 0x0208, 0xb98a, 0x00ee, 0x0005, 0x0005,
-	0x00b6, 0x7110, 0x080c, 0x6699, 0x1168, 0xb888, 0x8001, 0x0250,
-	0xb88a, 0x1140, 0x0126, 0x2091, 0x8000, 0x0016, 0x080c, 0x9763,
-	0x001e, 0x012e, 0x8108, 0x9182, 0x0800, 0x0218, 0x900e, 0x7007,
-	0x0002, 0x7112, 0x00be, 0x0005, 0x7014, 0x2060, 0x0126, 0x2091,
-	0x8000, 0x6040, 0x9005, 0x0128, 0x8001, 0x6042, 0x1110, 0x080c,
-	0xcf93, 0x6018, 0x9005, 0x0558, 0x8001, 0x601a, 0x1540, 0x6120,
-	0x9186, 0x0003, 0x0148, 0x9186, 0x0006, 0x0130, 0x9186, 0x0009,
-	0x11e0, 0x611c, 0xd1c4, 0x1100, 0x080c, 0xcc86, 0x01b0, 0x6014,
-	0x2048, 0xa884, 0x908a, 0x199a, 0x0280, 0x9082, 0x1999, 0xa886,
-	0x908a, 0x199a, 0x0210, 0x2001, 0x1999, 0x8003, 0x800b, 0x810b,
-	0x9108, 0x611a, 0xa87c, 0xd0e4, 0x0110, 0x080c, 0xc972, 0x012e,
-	0x9c88, 0x0018, 0x7116, 0x2001, 0x181a, 0x2004, 0x9102, 0x0220,
-	0x7017, 0x1cd0, 0x7007, 0x0000, 0x0005, 0x00e6, 0x2071, 0x19f9,
-	0x7027, 0x07d0, 0x7023, 0x0009, 0x00ee, 0x0005, 0x2001, 0x1a02,
-	0x2003, 0x0000, 0x0005, 0x00e6, 0x2071, 0x19f9, 0x7132, 0x702f,
-	0x0009, 0x00ee, 0x0005, 0x2011, 0x1a05, 0x2013, 0x0000, 0x0005,
-	0x00e6, 0x2071, 0x19f9, 0x711a, 0x721e, 0x700b, 0x0009, 0x00ee,
-	0x0005, 0x0086, 0x0026, 0x7054, 0x8000, 0x7056, 0x2001, 0x1a07,
-	0x2044, 0xa06c, 0x9086, 0x0000, 0x0150, 0x7068, 0xa09a, 0x7064,
-	0xa096, 0x7060, 0xa092, 0x705c, 0xa08e, 0x080c, 0x10e9, 0x002e,
-	0x008e, 0x0005, 0x0006, 0x0016, 0x0096, 0x00a6, 0x00b6, 0x00c6,
-	0x00d6, 0x00e6, 0x00f6, 0x0156, 0x080c, 0x8510, 0x015e, 0x00fe,
-	0x00ee, 0x00de, 0x00ce, 0x00be, 0x00ae, 0x009e, 0x001e, 0x000e,
-	0x0005, 0x00e6, 0x2071, 0x19f9, 0x7172, 0x7276, 0x706f, 0x0009,
-	0x00ee, 0x0005, 0x00e6, 0x0006, 0x2071, 0x19f9, 0x7074, 0x9206,
-	0x1110, 0x7072, 0x7076, 0x000e, 0x00ee, 0x0005, 0x0016, 0x00c6,
-	0x2009, 0xfff4, 0x210d, 0x2061, 0x0100, 0x60f0, 0x9100, 0x60f3,
-	0x0000, 0x2009, 0xfff4, 0x200f, 0x1220, 0x8108, 0x2105, 0x8000,
-	0x200f, 0x00ce, 0x001e, 0x0005, 0x00c6, 0x2061, 0x1a70, 0x00ce,
-	0x0005, 0x9184, 0x000f, 0x8003, 0x8003, 0x8003, 0x9080, 0x1a70,
-	0x2060, 0x0005, 0xa884, 0x908a, 0x199a, 0x1638, 0x9005, 0x1150,
-	0x00c6, 0x2061, 0x1a70, 0x6014, 0x00ce, 0x9005, 0x1130, 0x2001,
-	0x001e, 0x0018, 0x908e, 0xffff, 0x01b0, 0x8003, 0x800b, 0x810b,
-	0x9108, 0x611a, 0xa87c, 0x908c, 0x00c0, 0x918e, 0x00c0, 0x0904,
-	0x8744, 0xd0b4, 0x1168, 0xd0bc, 0x1904, 0x871d, 0x2009, 0x0006,
-	0x080c, 0x8771, 0x0005, 0x900e, 0x0c60, 0x2001, 0x1999, 0x08b0,
-	0xd0fc, 0x0160, 0x908c, 0x0003, 0x0120, 0x918e, 0x0003, 0x1904,
-	0x876b, 0x908c, 0x2020, 0x918e, 0x2020, 0x01a8, 0x6024, 0xd0d4,
-	0x11e8, 0x2009, 0x1869, 0x2104, 0xd084, 0x1138, 0x87ff, 0x1120,
-	0x2009, 0x0043, 0x0804, 0xafbe, 0x0005, 0x87ff, 0x1de8, 0x2009,
-	0x0042, 0x0804, 0xafbe, 0x6110, 0x00b6, 0x2158, 0xb900, 0x00be,
-	0xd1ac, 0x0d20, 0x6024, 0xc0cd, 0x6026, 0x0c00, 0xc0d4, 0x6026,
-	0xa890, 0x602e, 0xa88c, 0x6032, 0x08e0, 0xd0fc, 0x0160, 0x908c,
-	0x0003, 0x0120, 0x918e, 0x0003, 0x1904, 0x876b, 0x908c, 0x2020,
-	0x918e, 0x2020, 0x0170, 0x0076, 0x00f6, 0x2c78, 0x080c, 0x1754,
-	0x00fe, 0x007e, 0x87ff, 0x1120, 0x2009, 0x0042, 0x080c, 0xafbe,
-	0x0005, 0x6110, 0x00b6, 0x2158, 0xb900, 0x00be, 0xd1ac, 0x0d58,
-	0x6124, 0xc1cd, 0x6126, 0x0c38, 0xd0fc, 0x0188, 0x908c, 0x2020,
-	0x918e, 0x2020, 0x01a8, 0x9084, 0x0003, 0x908e, 0x0002, 0x0148,
-	0x87ff, 0x1120, 0x2009, 0x0041, 0x080c, 0xafbe, 0x0005, 0x00b9,
-	0x0ce8, 0x87ff, 0x1dd8, 0x2009, 0x0043, 0x080c, 0xafbe, 0x0cb0,
-	0x6110, 0x00b6, 0x2158, 0xb900, 0x00be, 0xd1ac, 0x0d20, 0x6124,
-	0xc1cd, 0x6126, 0x0c00, 0x2009, 0x0004, 0x0019, 0x0005, 0x2009,
-	0x0001, 0x0096, 0x080c, 0xcc86, 0x0518, 0x6014, 0x2048, 0xa982,
-	0xa800, 0x6016, 0x9186, 0x0001, 0x1188, 0xa97c, 0x918c, 0x8100,
-	0x918e, 0x8100, 0x1158, 0x00c6, 0x2061, 0x1a70, 0x6200, 0xd28c,
-	0x1120, 0x6204, 0x8210, 0x0208, 0x6206, 0x00ce, 0x080c, 0x6b52,
-	0x6014, 0x904d, 0x0076, 0x2039, 0x0000, 0x190c, 0x86ba, 0x007e,
-	0x009e, 0x0005, 0x0156, 0x00c6, 0x2061, 0x1a70, 0x6000, 0x81ff,
-	0x0110, 0x9205, 0x0008, 0x9204, 0x6002, 0x00ce, 0x015e, 0x0005,
-	0x6800, 0xd08c, 0x1138, 0x6808, 0x9005, 0x0120, 0x8001, 0x680a,
-	0x9085, 0x0001, 0x0005, 0x2071, 0x1923, 0x7003, 0x0006, 0x7007,
-	0x0000, 0x700f, 0x0000, 0x7013, 0x0001, 0x080c, 0x1018, 0x090c,
-	0x0dd5, 0xa867, 0x0006, 0xa86b, 0x0001, 0xa8ab, 0xdcb0, 0xa89f,
-	0x0000, 0x2900, 0x702e, 0x7033, 0x0000, 0x0005, 0x0096, 0x00e6,
-	0x2071, 0x1923, 0x702c, 0x2048, 0x6a2c, 0x721e, 0x6b30, 0x7322,
-	0x6834, 0x7026, 0xa896, 0x6838, 0x702a, 0xa89a, 0x6824, 0x7016,
-	0x683c, 0x701a, 0x2009, 0x0028, 0x200a, 0x9005, 0x0148, 0x900e,
-	0x9188, 0x000c, 0x8001, 0x1de0, 0x2100, 0x9210, 0x1208, 0x8318,
-	0xaa8e, 0xab92, 0x7010, 0xd084, 0x0168, 0xc084, 0x7007, 0x0001,
-	0x700f, 0x0000, 0x0006, 0x2009, 0x1aca, 0x2104, 0x9082, 0x0007,
-	0x200a, 0x000e, 0xc095, 0x7012, 0x2008, 0x2001, 0x003b, 0x080c,
-	0x15fd, 0x9006, 0x2071, 0x193c, 0x7002, 0x7006, 0x702a, 0x00ee,
-	0x009e, 0x0005, 0x2009, 0x1aca, 0x2104, 0x9080, 0x0007, 0x200a,
+	0xb914, 0x9106, 0x1130, 0x7124, 0x610a, 0x2009, 0x0046, 0x080c,
+	0xb166, 0x7817, 0x0140, 0x2001, 0x19f2, 0x2004, 0x9005, 0x090c,
+	0x98e7, 0x00be, 0x0005, 0x00b6, 0x00c6, 0x9484, 0x0fff, 0x0904,
+	0x838f, 0x7110, 0xd1bc, 0x1904, 0x838f, 0x7108, 0x700c, 0x2028,
+	0x918c, 0x00ff, 0x2130, 0x9094, 0xff00, 0x15b0, 0x81ff, 0x15a0,
+	0x9080, 0x33b1, 0x200d, 0x918c, 0xff00, 0x810f, 0x2001, 0x0080,
+	0x9106, 0x0904, 0x838f, 0x080c, 0x66ac, 0x1904, 0x838f, 0xbe12,
+	0xbd16, 0xb800, 0xd0ec, 0x15d8, 0xba04, 0x9294, 0xff00, 0x9286,
+	0x0600, 0x11a0, 0x080c, 0xb091, 0x05e8, 0x2b08, 0x7028, 0x6046,
+	0x702c, 0x604a, 0x6112, 0x6023, 0x0006, 0x7120, 0x610a, 0x7130,
+	0x6156, 0x2009, 0x0044, 0x080c, 0xdf02, 0x0408, 0x080c, 0x6a8c,
+	0x1138, 0xb807, 0x0606, 0x0c30, 0x190c, 0x826b, 0x11c0, 0x0898,
+	0x080c, 0xb091, 0x2b08, 0x0198, 0x6112, 0x6023, 0x0004, 0x7120,
+	0x610a, 0x9286, 0x0400, 0x1118, 0x6007, 0x0005, 0x0010, 0x6007,
+	0x0001, 0x6003, 0x0001, 0x080c, 0x937d, 0x080c, 0x98e7, 0x7817,
+	0x0140, 0x2001, 0x19f2, 0x2004, 0x9005, 0x090c, 0x98e7, 0x00ce,
+	0x00be, 0x0005, 0x2001, 0x180e, 0x2004, 0xd0ec, 0x0120, 0x2011,
+	0x8049, 0x080c, 0x4be3, 0x080c, 0xb139, 0x0d48, 0x2b08, 0x6112,
+	0x6023, 0x0006, 0x7120, 0x610a, 0x7130, 0x6156, 0x6017, 0xf300,
+	0x6003, 0x0001, 0x6007, 0x0041, 0x080c, 0x9335, 0x080c, 0x98e7,
+	0x08b0, 0x00b6, 0x7110, 0xd1bc, 0x01e8, 0x7020, 0x2060, 0x9c84,
+	0x0007, 0x11c0, 0x9c82, 0x1cd0, 0x02a8, 0x6868, 0x9c02, 0x1290,
+	0x7008, 0x9084, 0x00ff, 0x6110, 0x2158, 0xb910, 0x9106, 0x1150,
+	0x700c, 0xb914, 0x9106, 0x1130, 0x7124, 0x610a, 0x2009, 0x0045,
+	0x080c, 0xb166, 0x7817, 0x0140, 0x2001, 0x19f2, 0x2004, 0x9005,
+	0x090c, 0x98e7, 0x00be, 0x0005, 0x6120, 0x9186, 0x0002, 0x0128,
+	0x9186, 0x0005, 0x0110, 0x9085, 0x0001, 0x0005, 0x080c, 0x8601,
+	0x1180, 0x080c, 0x336f, 0x1168, 0x7010, 0x9084, 0xff00, 0x8007,
+	0x9086, 0x0000, 0x1130, 0x9184, 0x000f, 0x908a, 0x0006, 0x1208,
+	0x000b, 0x0005, 0x8408, 0x8409, 0x8408, 0x8408, 0x846e, 0x847d,
+	0x0005, 0x00b6, 0x700c, 0x7108, 0x080c, 0x2889, 0x1904, 0x846c,
+	0x080c, 0x66ac, 0x1904, 0x846c, 0xbe12, 0xbd16, 0x7110, 0xd1bc,
+	0x0540, 0x702c, 0xd084, 0x1120, 0xb800, 0xd0bc, 0x1904, 0x846c,
+	0x080c, 0x6a8c, 0x0148, 0x9086, 0x0004, 0x0130, 0x080c, 0x6a94,
+	0x0118, 0x9086, 0x0004, 0x1588, 0x00c6, 0x080c, 0x848c, 0x00ce,
+	0x05d8, 0x080c, 0xb091, 0x2b08, 0x05b8, 0x6112, 0x080c, 0xd2bb,
+	0x6023, 0x0002, 0x7120, 0x610a, 0x2009, 0x0088, 0x080c, 0xb166,
+	0x0458, 0x080c, 0x6a8c, 0x0148, 0x9086, 0x0004, 0x0130, 0x080c,
+	0x6a94, 0x0118, 0x9086, 0x0004, 0x1180, 0x080c, 0xb091, 0x2b08,
+	0x01d8, 0x6112, 0x080c, 0xd2bb, 0x6023, 0x0005, 0x7120, 0x610a,
+	0x2009, 0x0088, 0x080c, 0xb166, 0x0078, 0x080c, 0xb091, 0x2b08,
+	0x0158, 0x6112, 0x080c, 0xd2bb, 0x6023, 0x0004, 0x7120, 0x610a,
+	0x2009, 0x0001, 0x080c, 0xb166, 0x00be, 0x0005, 0x7110, 0xd1bc,
+	0x0158, 0x00d1, 0x0148, 0x080c, 0x83e4, 0x1130, 0x7124, 0x610a,
+	0x2009, 0x0089, 0x080c, 0xb166, 0x0005, 0x7110, 0xd1bc, 0x0158,
+	0x0059, 0x0148, 0x080c, 0x83e4, 0x1130, 0x7124, 0x610a, 0x2009,
+	0x008a, 0x080c, 0xb166, 0x0005, 0x7020, 0x2060, 0x9c84, 0x0007,
+	0x1158, 0x9c82, 0x1cd0, 0x0240, 0x2001, 0x181a, 0x2004, 0x9c02,
+	0x1218, 0x9085, 0x0001, 0x0005, 0x9006, 0x0ce8, 0x00b6, 0x7110,
+	0xd1bc, 0x11d8, 0x7024, 0x2060, 0x9c84, 0x0007, 0x11b0, 0x9c82,
+	0x1cd0, 0x0298, 0x6868, 0x9c02, 0x1280, 0x7008, 0x9084, 0x00ff,
+	0x6110, 0x2158, 0xb910, 0x9106, 0x1140, 0x700c, 0xb914, 0x9106,
+	0x1120, 0x2009, 0x0051, 0x080c, 0xb166, 0x7817, 0x0140, 0x2001,
+	0x19f2, 0x2004, 0x9005, 0x090c, 0x98e7, 0x00be, 0x0005, 0x2031,
+	0x0105, 0x0069, 0x0005, 0x2031, 0x0206, 0x0049, 0x0005, 0x2031,
+	0x0207, 0x0029, 0x0005, 0x2031, 0x0213, 0x0009, 0x0005, 0x00c6,
+	0x0096, 0x00f6, 0x7000, 0x9084, 0xf000, 0x9086, 0xc000, 0x05d0,
+	0x080c, 0xb091, 0x05b8, 0x0066, 0x00c6, 0x0046, 0x2011, 0x0263,
+	0x2204, 0x8211, 0x220c, 0x080c, 0x2889, 0x15a0, 0x080c, 0x66ac,
+	0x1588, 0xbe12, 0xbd16, 0x2b00, 0x004e, 0x00ce, 0x6012, 0x080c,
+	0xd2bb, 0x080c, 0x100e, 0x0510, 0x2900, 0x605a, 0x9006, 0xa802,
+	0xa866, 0xac6a, 0xa85c, 0x90f8, 0x001b, 0x20a9, 0x000e, 0xa860,
+	0x20e8, 0x20e1, 0x0000, 0x2fa0, 0x2e98, 0x4003, 0x006e, 0x6616,
+	0x6007, 0x003e, 0x6023, 0x0001, 0x6003, 0x0001, 0x080c, 0x937d,
+	0x080c, 0x98e7, 0x00fe, 0x009e, 0x00ce, 0x0005, 0x080c, 0xb0e7,
+	0x006e, 0x0cc0, 0x004e, 0x00ce, 0x0cc8, 0x00c6, 0x7000, 0x908c,
+	0xff00, 0x9184, 0xf000, 0x810f, 0x9086, 0x2000, 0x1904, 0x857c,
+	0x9186, 0x0022, 0x15f0, 0x2001, 0x0111, 0x2004, 0x9005, 0x1904,
+	0x857e, 0x7030, 0x908e, 0x0400, 0x0904, 0x857e, 0x908e, 0x6000,
+	0x05e8, 0x908e, 0x5400, 0x05d0, 0x908e, 0x0300, 0x11d8, 0x2009,
+	0x1837, 0x210c, 0xd18c, 0x1590, 0xd1a4, 0x1580, 0x080c, 0x6a4a,
+	0x0588, 0x68b0, 0x9084, 0x00ff, 0x7100, 0x918c, 0x00ff, 0x9106,
+	0x1518, 0x6880, 0x69b0, 0x918c, 0xff00, 0x9105, 0x7104, 0x9106,
+	0x11d8, 0x00e0, 0x2009, 0x0103, 0x210c, 0xd1b4, 0x11a8, 0x908e,
+	0x5200, 0x09e8, 0x908e, 0x0500, 0x09d0, 0x908e, 0x5000, 0x09b8,
+	0x0058, 0x9186, 0x0023, 0x1140, 0x080c, 0x848c, 0x0128, 0x6004,
+	0x9086, 0x0002, 0x0118, 0x0000, 0x9006, 0x0010, 0x9085, 0x0001,
+	0x00ce, 0x0005, 0x7030, 0x908e, 0x0300, 0x0118, 0x908e, 0x5200,
+	0x1d98, 0x2001, 0x1837, 0x2004, 0x9084, 0x0009, 0x9086, 0x0008,
+	0x0d68, 0x0c50, 0x0156, 0x0046, 0x0016, 0x0036, 0x7038, 0x2020,
+	0x8427, 0x94a4, 0x0007, 0xd484, 0x0148, 0x20a9, 0x0004, 0x2019,
+	0x1805, 0x2011, 0x027a, 0x080c, 0xc0d3, 0x1178, 0xd48c, 0x0148,
+	0x20a9, 0x0004, 0x2019, 0x1801, 0x2011, 0x027e, 0x080c, 0xc0d3,
+	0x1120, 0xd494, 0x0110, 0x9085, 0x0001, 0x003e, 0x001e, 0x004e,
+	0x015e, 0x0005, 0x0156, 0x0046, 0x0016, 0x0036, 0x7038, 0x2020,
+	0x8427, 0x94a4, 0x0007, 0xd484, 0x0148, 0x20a9, 0x0004, 0x2019,
+	0x1805, 0x2011, 0x0272, 0x080c, 0xc0d3, 0x1178, 0xd48c, 0x0148,
+	0x20a9, 0x0004, 0x2019, 0x1801, 0x2011, 0x0276, 0x080c, 0xc0d3,
+	0x1120, 0xd494, 0x0110, 0x9085, 0x0001, 0x003e, 0x001e, 0x004e,
+	0x015e, 0x0005, 0x00f6, 0x2079, 0x0200, 0x7800, 0xc0e5, 0xc0cc,
+	0x7802, 0x00fe, 0x0005, 0x00f6, 0x2079, 0x1800, 0x7834, 0xd084,
+	0x1130, 0x2079, 0x0200, 0x7800, 0x9085, 0x1200, 0x7802, 0x00fe,
+	0x0005, 0x00e6, 0x2071, 0x1800, 0x7034, 0xc084, 0x7036, 0x00ee,
+	0x0005, 0x0016, 0x2001, 0x1837, 0x200c, 0x9184, 0x0080, 0x0118,
+	0xd18c, 0x0118, 0x9006, 0x001e, 0x0005, 0x9085, 0x0001, 0x0cd8,
+	0x2071, 0x19fc, 0x7003, 0x0003, 0x700f, 0x0361, 0x9006, 0x701a,
+	0x707a, 0x7012, 0x7017, 0x1cd0, 0x7007, 0x0000, 0x7026, 0x702b,
+	0xa513, 0x7032, 0x703a, 0x703f, 0x0064, 0x7037, 0xa57b, 0x7047,
+	0xffff, 0x704a, 0x704f, 0x565f, 0x7052, 0x7063, 0x87a4, 0x080c,
+	0x1027, 0x090c, 0x0dc5, 0x2900, 0x7042, 0xa867, 0x0003, 0xa86f,
+	0x0100, 0xa8ab, 0xdcb0, 0x0005, 0x2071, 0x19fc, 0x1d04, 0x86f2,
+	0x2091, 0x6000, 0x700c, 0x8001, 0x700e, 0x1540, 0x2001, 0x013c,
+	0x2004, 0x9005, 0x190c, 0x8812, 0x2001, 0x1869, 0x2004, 0xd0c4,
+	0x0158, 0x3a00, 0xd08c, 0x1140, 0x20d1, 0x0000, 0x20d1, 0x0001,
+	0x20d1, 0x0000, 0x080c, 0x0dc5, 0x700f, 0x0361, 0x7007, 0x0001,
+	0x0126, 0x2091, 0x8000, 0x080c, 0x87e9, 0x7048, 0x900d, 0x0148,
+	0x8109, 0x714a, 0x1130, 0x704c, 0x080f, 0x0018, 0x0126, 0x2091,
+	0x8000, 0x7024, 0x900d, 0x0188, 0x7020, 0x8001, 0x7022, 0x1168,
+	0x7023, 0x0009, 0x8109, 0x7126, 0x9186, 0x03e8, 0x1110, 0x7028,
+	0x080f, 0x81ff, 0x1110, 0x7028, 0x080f, 0x7030, 0x900d, 0x05a8,
+	0x702c, 0x8001, 0x702e, 0x1588, 0x0016, 0x2009, 0x0306, 0x210c,
+	0x9184, 0x0030, 0x01e8, 0x9184, 0x0048, 0x9086, 0x0008, 0x11c0,
+	0x7038, 0x9005, 0x01a8, 0x8001, 0x703a, 0x1190, 0x080c, 0x7563,
+	0x0178, 0x00e6, 0x2071, 0x19e9, 0x080c, 0xa609, 0x00ee, 0x1140,
+	0x2009, 0x1a87, 0x2104, 0x8000, 0x0208, 0x200a, 0x001e, 0x0068,
+	0x001e, 0x702f, 0x0009, 0x8109, 0x7132, 0x0128, 0x9184, 0x007f,
+	0x090c, 0xa6bf, 0x0010, 0x7034, 0x080f, 0x7044, 0x9005, 0x0118,
+	0x0310, 0x8001, 0x7046, 0x7054, 0x900d, 0x0168, 0x7050, 0x8001,
+	0x7052, 0x1148, 0x7053, 0x0009, 0x8109, 0x7156, 0x1120, 0x7158,
+	0x7156, 0x7060, 0x080f, 0x7018, 0x900d, 0x01d8, 0x0016, 0x7078,
+	0x900d, 0x0158, 0x7074, 0x8001, 0x7076, 0x1138, 0x7077, 0x0009,
+	0x8109, 0x717a, 0x1110, 0x707c, 0x080f, 0x001e, 0x7008, 0x8001,
+	0x700a, 0x1138, 0x700b, 0x0009, 0x8109, 0x711a, 0x1110, 0x701c,
+	0x080f, 0x012e, 0x7004, 0x0002, 0x871a, 0x871b, 0x8737, 0x00e6,
+	0x2071, 0x19fc, 0x7018, 0x9005, 0x1120, 0x711a, 0x721e, 0x700b,
+	0x0009, 0x00ee, 0x0005, 0x00e6, 0x0006, 0x2071, 0x19fc, 0x701c,
+	0x9206, 0x1120, 0x701a, 0x701e, 0x707a, 0x707e, 0x000e, 0x00ee,
+	0x0005, 0x00e6, 0x2071, 0x19fc, 0xb888, 0x9102, 0x0208, 0xb98a,
+	0x00ee, 0x0005, 0x0005, 0x00b6, 0x7110, 0x080c, 0x6717, 0x1168,
+	0xb888, 0x8001, 0x0250, 0xb88a, 0x1140, 0x0126, 0x2091, 0x8000,
+	0x0016, 0x080c, 0x98e7, 0x001e, 0x012e, 0x8108, 0x9182, 0x0800,
+	0x0218, 0x900e, 0x7007, 0x0002, 0x7112, 0x00be, 0x0005, 0x7014,
+	0x2060, 0x0126, 0x2091, 0x8000, 0x6040, 0x9005, 0x0128, 0x8001,
+	0x6042, 0x1110, 0x080c, 0xd14c, 0x6018, 0x9005, 0x0558, 0x8001,
+	0x601a, 0x1540, 0x6120, 0x9186, 0x0003, 0x0148, 0x9186, 0x0006,
+	0x0130, 0x9186, 0x0009, 0x11e0, 0x611c, 0xd1c4, 0x1100, 0x080c,
+	0xce3f, 0x01b0, 0x6014, 0x2048, 0xa884, 0x908a, 0x199a, 0x0280,
+	0x9082, 0x1999, 0xa886, 0x908a, 0x199a, 0x0210, 0x2001, 0x1999,
+	0x8003, 0x800b, 0x810b, 0x9108, 0x611a, 0xa87c, 0xd0e4, 0x0110,
+	0x080c, 0xcb2b, 0x012e, 0x9c88, 0x0018, 0x7116, 0x2001, 0x181a,
+	0x2004, 0x9102, 0x0220, 0x7017, 0x1cd0, 0x7007, 0x0000, 0x0005,
+	0x00e6, 0x2071, 0x19fc, 0x7027, 0x07d0, 0x7023, 0x0009, 0x00ee,
+	0x0005, 0x2001, 0x1a05, 0x2003, 0x0000, 0x0005, 0x00e6, 0x2071,
+	0x19fc, 0x7132, 0x702f, 0x0009, 0x00ee, 0x0005, 0x2011, 0x1a08,
+	0x2013, 0x0000, 0x0005, 0x00e6, 0x2071, 0x19fc, 0x711a, 0x721e,
+	0x700b, 0x0009, 0x00ee, 0x0005, 0x0086, 0x0026, 0x705c, 0x8000,
+	0x705e, 0x2001, 0x1a0c, 0x2044, 0xa06c, 0x9086, 0x0000, 0x0150,
+	0x7070, 0xa09a, 0x706c, 0xa096, 0x7068, 0xa092, 0x7064, 0xa08e,
+	0x080c, 0x10f8, 0x002e, 0x008e, 0x0005, 0x0006, 0x0016, 0x0096,
+	0x00a6, 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x0156, 0x080c,
+	0x863c, 0x015e, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x00ae,
+	0x009e, 0x001e, 0x000e, 0x0005, 0x00e6, 0x2071, 0x19fc, 0x717a,
+	0x727e, 0x7077, 0x0009, 0x00ee, 0x0005, 0x00e6, 0x0006, 0x2071,
+	0x19fc, 0x707c, 0x9206, 0x1110, 0x707a, 0x707e, 0x000e, 0x00ee,
+	0x0005, 0x2069, 0x1800, 0x69e8, 0xd1e4, 0x1518, 0x0026, 0xd1ec,
+	0x0140, 0x6a54, 0x6874, 0x9202, 0x0288, 0x8117, 0x9294, 0x00c0,
+	0x0088, 0x9184, 0x0007, 0x01a0, 0x8109, 0x9184, 0x0007, 0x0110,
+	0x69ea, 0x0070, 0x8107, 0x9084, 0x0007, 0x910d, 0x8107, 0x9106,
+	0x9094, 0x00c0, 0x9184, 0xff3f, 0x9205, 0x68ea, 0x080c, 0x0eee,
+	0x002e, 0x0005, 0x0016, 0x00c6, 0x2009, 0xfff4, 0x210d, 0x2061,
+	0x0100, 0x60f0, 0x9100, 0x60f3, 0x0000, 0x2009, 0xfff4, 0x200f,
+	0x1220, 0x8108, 0x2105, 0x8000, 0x200f, 0x00ce, 0x001e, 0x0005,
+	0x00c6, 0x2061, 0x1a75, 0x00ce, 0x0005, 0x9184, 0x000f, 0x8003,
+	0x8003, 0x8003, 0x9080, 0x1a75, 0x2060, 0x0005, 0xa884, 0x908a,
+	0x199a, 0x1638, 0x9005, 0x1150, 0x00c6, 0x2061, 0x1a75, 0x6014,
+	0x00ce, 0x9005, 0x1130, 0x2001, 0x001e, 0x0018, 0x908e, 0xffff,
+	0x01b0, 0x8003, 0x800b, 0x810b, 0x9108, 0x611a, 0xa87c, 0x908c,
+	0x00c0, 0x918e, 0x00c0, 0x0904, 0x88c0, 0xd0b4, 0x1168, 0xd0bc,
+	0x1904, 0x8899, 0x2009, 0x0006, 0x080c, 0x88ed, 0x0005, 0x900e,
+	0x0c60, 0x2001, 0x1999, 0x08b0, 0xd0fc, 0x0160, 0x908c, 0x0003,
+	0x0120, 0x918e, 0x0003, 0x1904, 0x88e7, 0x908c, 0x2020, 0x918e,
+	0x2020, 0x01a8, 0x6024, 0xd0d4, 0x11e8, 0x2009, 0x1869, 0x2104,
+	0xd084, 0x1138, 0x87ff, 0x1120, 0x2009, 0x0043, 0x0804, 0xb166,
+	0x0005, 0x87ff, 0x1de8, 0x2009, 0x0042, 0x0804, 0xb166, 0x6110,
+	0x00b6, 0x2158, 0xb900, 0x00be, 0xd1ac, 0x0d20, 0x6024, 0xc0cd,
+	0x6026, 0x0c00, 0xc0d4, 0x6026, 0xa890, 0x602e, 0xa88c, 0x6032,
+	0x08e0, 0xd0fc, 0x0160, 0x908c, 0x0003, 0x0120, 0x918e, 0x0003,
+	0x1904, 0x88e7, 0x908c, 0x2020, 0x918e, 0x2020, 0x0170, 0x0076,
+	0x00f6, 0x2c78, 0x080c, 0x1768, 0x00fe, 0x007e, 0x87ff, 0x1120,
+	0x2009, 0x0042, 0x080c, 0xb166, 0x0005, 0x6110, 0x00b6, 0x2158,
+	0xb900, 0x00be, 0xd1ac, 0x0d58, 0x6124, 0xc1cd, 0x6126, 0x0c38,
+	0xd0fc, 0x0188, 0x908c, 0x2020, 0x918e, 0x2020, 0x01a8, 0x9084,
+	0x0003, 0x908e, 0x0002, 0x0148, 0x87ff, 0x1120, 0x2009, 0x0041,
+	0x080c, 0xb166, 0x0005, 0x00b9, 0x0ce8, 0x87ff, 0x1dd8, 0x2009,
+	0x0043, 0x080c, 0xb166, 0x0cb0, 0x6110, 0x00b6, 0x2158, 0xb900,
+	0x00be, 0xd1ac, 0x0d20, 0x6124, 0xc1cd, 0x6126, 0x0c00, 0x2009,
+	0x0004, 0x0019, 0x0005, 0x2009, 0x0001, 0x0096, 0x080c, 0xce3f,
+	0x0518, 0x6014, 0x2048, 0xa982, 0xa800, 0x6016, 0x9186, 0x0001,
+	0x1188, 0xa97c, 0x918c, 0x8100, 0x918e, 0x8100, 0x1158, 0x00c6,
+	0x2061, 0x1a75, 0x6200, 0xd28c, 0x1120, 0x6204, 0x8210, 0x0208,
+	0x6206, 0x00ce, 0x080c, 0x6c0a, 0x6014, 0x904d, 0x0076, 0x2039,
+	0x0000, 0x190c, 0x8836, 0x007e, 0x009e, 0x0005, 0x0156, 0x00c6,
+	0x2061, 0x1a75, 0x6000, 0x81ff, 0x0110, 0x9205, 0x0008, 0x9204,
+	0x6002, 0x00ce, 0x015e, 0x0005, 0x6800, 0xd08c, 0x1138, 0x6808,
+	0x9005, 0x0120, 0x8001, 0x680a, 0x9085, 0x0001, 0x0005, 0x2071,
+	0x1925, 0x7003, 0x0006, 0x7007, 0x0000, 0x700f, 0x0000, 0x7013,
+	0x0001, 0x080c, 0x1027, 0x090c, 0x0dc5, 0xa867, 0x0006, 0xa86b,
+	0x0001, 0xa8ab, 0xdcb0, 0xa89f, 0x0000, 0x2900, 0x702e, 0x7033,
+	0x0000, 0x0005, 0x0126, 0x2091, 0x8000, 0x0096, 0x00e6, 0x2071,
+	0x1925, 0x702c, 0x2048, 0x6a2c, 0x721e, 0x6b30, 0x7322, 0x6834,
+	0x7026, 0xa896, 0x6838, 0x702a, 0xa89a, 0x6824, 0x7016, 0x683c,
+	0x701a, 0x2009, 0x0028, 0x200a, 0x9005, 0x0148, 0x900e, 0x9188,
+	0x000c, 0x8001, 0x1de0, 0x2100, 0x9210, 0x1208, 0x8318, 0xaa8e,
+	0xab92, 0x7010, 0xd084, 0x0168, 0xc084, 0x7007, 0x0001, 0x700f,
+	0x0000, 0x0006, 0x2009, 0x1ad2, 0x2104, 0x9082, 0x0007, 0x200a,
+	0x000e, 0xc095, 0x7012, 0x2008, 0x2001, 0x003b, 0x080c, 0x1611,
+	0x9006, 0x2071, 0x193e, 0x7002, 0x7006, 0x702a, 0x00ee, 0x009e,
+	0x012e, 0x0005, 0x2009, 0x1ad2, 0x2104, 0x9080, 0x0007, 0x200a,
 	0x0005, 0x00e6, 0x0126, 0x0156, 0x2091, 0x8000, 0x2071, 0x1800,
 	0x7154, 0x2001, 0x0008, 0x910a, 0x0638, 0x2001, 0x187d, 0x20ac,
-	0x9006, 0x9080, 0x0008, 0x1f04, 0x8829, 0x71c0, 0x9102, 0x02e0,
-	0x2071, 0x1877, 0x20a9, 0x0007, 0x00c6, 0x080c, 0xaeed, 0x6023,
+	0x9006, 0x9080, 0x0008, 0x1f04, 0x89a9, 0x71c0, 0x9102, 0x02e0,
+	0x2071, 0x1877, 0x20a9, 0x0007, 0x00c6, 0x080c, 0xb091, 0x6023,
 	0x0009, 0x6003, 0x0004, 0x601f, 0x0101, 0x0089, 0x0126, 0x2091,
-	0x8000, 0x080c, 0x89a7, 0x012e, 0x1f04, 0x8835, 0x9006, 0x00ce,
+	0x8000, 0x080c, 0x8b27, 0x012e, 0x1f04, 0x89b5, 0x9006, 0x00ce,
 	0x015e, 0x012e, 0x00ee, 0x0005, 0x9085, 0x0001, 0x0cc8, 0x00e6,
 	0x00b6, 0x0096, 0x0086, 0x0056, 0x0046, 0x0026, 0x7118, 0x720c,
 	0x7620, 0x7004, 0xd084, 0x1128, 0x2021, 0x0024, 0x2029, 0x0002,
-	0x0020, 0x2021, 0x002c, 0x2029, 0x000a, 0x080c, 0x0fff, 0x090c,
-	0x0dd5, 0x2900, 0x6016, 0x2058, 0xac66, 0x9006, 0xa802, 0xa806,
+	0x0020, 0x2021, 0x002c, 0x2029, 0x000a, 0x080c, 0x100e, 0x090c,
+	0x0dc5, 0x2900, 0x6016, 0x2058, 0xac66, 0x9006, 0xa802, 0xa806,
 	0xa86a, 0xa87a, 0xa8aa, 0xa887, 0x0005, 0xa87f, 0x0020, 0x7008,
 	0xa89a, 0x7010, 0xa89e, 0xae8a, 0xa8af, 0xffff, 0xa8b3, 0x0000,
-	0x8109, 0x0160, 0x080c, 0x0fff, 0x090c, 0x0dd5, 0xad66, 0x2b00,
+	0x8109, 0x0160, 0x080c, 0x100e, 0x090c, 0x0dc5, 0xad66, 0x2b00,
 	0xa802, 0x2900, 0xb806, 0x2058, 0x8109, 0x1da0, 0x002e, 0x004e,
 	0x005e, 0x008e, 0x009e, 0x00be, 0x00ee, 0x0005, 0x2079, 0x0000,
-	0x2071, 0x1923, 0x7004, 0x004b, 0x700c, 0x0002, 0x88a1, 0x889a,
-	0x889a, 0x0005, 0x88ab, 0x8901, 0x8901, 0x8901, 0x8902, 0x8913,
-	0x8913, 0x700c, 0x0cba, 0x0126, 0x2091, 0x8000, 0x78a0, 0x79a0,
-	0x9106, 0x1904, 0x88f3, 0x7814, 0xd0bc, 0x1904, 0x88fc, 0x012e,
-	0x7018, 0x910a, 0x1128, 0x7030, 0x9005, 0x1904, 0x8945, 0x0005,
+	0x2071, 0x1925, 0x7004, 0x004b, 0x700c, 0x0002, 0x8a21, 0x8a1a,
+	0x8a1a, 0x0005, 0x8a2b, 0x8a81, 0x8a81, 0x8a81, 0x8a82, 0x8a93,
+	0x8a93, 0x700c, 0x0cba, 0x0126, 0x2091, 0x8000, 0x78a0, 0x79a0,
+	0x9106, 0x1904, 0x8a73, 0x7814, 0xd0bc, 0x1904, 0x8a7c, 0x012e,
+	0x7018, 0x910a, 0x1128, 0x7030, 0x9005, 0x1904, 0x8ac5, 0x0005,
 	0x1210, 0x7114, 0x910a, 0x9192, 0x000a, 0x0210, 0x2009, 0x000a,
-	0x2001, 0x1888, 0x2014, 0x2001, 0x1935, 0x2004, 0x9100, 0x9202,
-	0x0e50, 0x080c, 0x8a9b, 0x2200, 0x9102, 0x0208, 0x2208, 0x0096,
-	0x702c, 0x2048, 0xa873, 0x0001, 0xa976, 0x080c, 0x8ba4, 0x2100,
+	0x2001, 0x1888, 0x2014, 0x2001, 0x1937, 0x2004, 0x9100, 0x9202,
+	0x0e50, 0x080c, 0x8c1f, 0x2200, 0x9102, 0x0208, 0x2208, 0x0096,
+	0x702c, 0x2048, 0xa873, 0x0001, 0xa976, 0x080c, 0x8d28, 0x2100,
 	0xa87e, 0xa86f, 0x0000, 0x009e, 0x0126, 0x2091, 0x8000, 0x2009,
-	0x1a17, 0x2104, 0xc085, 0x200a, 0x700f, 0x0002, 0x012e, 0x080c,
-	0x1108, 0x1de8, 0x0005, 0x78a0, 0x79a0, 0x9106, 0x0904, 0x88b3,
-	0x080c, 0x8a73, 0x012e, 0x0005, 0x7810, 0xc0c5, 0x7812, 0x0804,
-	0x88b3, 0x0005, 0x700c, 0x0002, 0x8907, 0x890a, 0x8909, 0x080c,
-	0x88a9, 0x0005, 0x8001, 0x700e, 0x0096, 0x702c, 0x2048, 0xa974,
+	0x1a1c, 0x2104, 0xc085, 0x200a, 0x700f, 0x0002, 0x012e, 0x080c,
+	0x1117, 0x1de8, 0x0005, 0x78a0, 0x79a0, 0x9106, 0x0904, 0x8a33,
+	0x080c, 0x8bf7, 0x012e, 0x0005, 0x7810, 0xc0c5, 0x7812, 0x0804,
+	0x8a33, 0x0005, 0x700c, 0x0002, 0x8a87, 0x8a8a, 0x8a89, 0x080c,
+	0x8a29, 0x0005, 0x8001, 0x700e, 0x0096, 0x702c, 0x2048, 0xa974,
 	0x009e, 0x0011, 0x0ca0, 0x0005, 0x0096, 0x702c, 0x2048, 0x7018,
 	0x9100, 0x7214, 0x921a, 0x1130, 0x701c, 0xa88e, 0x7020, 0xa892,
-	0x9006, 0x0068, 0x0006, 0x080c, 0x8ba4, 0x2100, 0xaa8c, 0x9210,
+	0x9006, 0x0068, 0x0006, 0x080c, 0x8d28, 0x2100, 0xaa8c, 0x9210,
 	0xaa8e, 0x1220, 0xa890, 0x9081, 0x0000, 0xa892, 0x000e, 0x009e,
-	0x0126, 0x2091, 0x8000, 0x78a2, 0x701a, 0x080c, 0x8a73, 0x012e,
-	0x0005, 0x00e6, 0x2071, 0x1923, 0x700c, 0x0002, 0x8943, 0x8943,
-	0x8941, 0x700f, 0x0001, 0x00ee, 0x0005, 0x0126, 0x2091, 0x8000,
+	0x0126, 0x2091, 0x8000, 0x78a2, 0x701a, 0x080c, 0x8bf7, 0x012e,
+	0x0005, 0x00e6, 0x2071, 0x1925, 0x700c, 0x0002, 0x8ac3, 0x8ac3,
+	0x8ac1, 0x700f, 0x0001, 0x00ee, 0x0005, 0x0126, 0x2091, 0x8000,
 	0x7030, 0x9005, 0x0508, 0x2078, 0x7814, 0x2048, 0xae88, 0x00b6,
-	0x2059, 0x0000, 0x080c, 0x89b0, 0x00be, 0x01b0, 0x00e6, 0x2071,
-	0x193c, 0x080c, 0x89f7, 0x00ee, 0x0178, 0x0096, 0x080c, 0x1018,
-	0x2900, 0x009e, 0x0148, 0xa8aa, 0x04b9, 0x0041, 0x2001, 0x1946,
+	0x2059, 0x0000, 0x080c, 0x8b30, 0x00be, 0x01b0, 0x00e6, 0x2071,
+	0x193e, 0x080c, 0x8b77, 0x00ee, 0x0178, 0x0096, 0x080c, 0x1027,
+	0x2900, 0x009e, 0x0148, 0xa8aa, 0x04b9, 0x0041, 0x2001, 0x1948,
 	0x2003, 0x0000, 0x012e, 0x08c8, 0x012e, 0x0005, 0x00d6, 0x00c6,
 	0x0086, 0x00a6, 0x2940, 0x2650, 0x2600, 0x9005, 0x0180, 0xa864,
-	0x9084, 0x000f, 0x2068, 0x9d88, 0x20ce, 0x2165, 0x0056, 0x2029,
-	0x0000, 0x080c, 0x8b29, 0x080c, 0x2086, 0x1dd8, 0x005e, 0x00ae,
-	0x2001, 0x187f, 0x2004, 0xa88a, 0x080c, 0x1754, 0x781f, 0x0101,
-	0x7813, 0x0000, 0x0126, 0x2091, 0x8000, 0x080c, 0x8a06, 0x012e,
+	0x9084, 0x000f, 0x2068, 0x9d88, 0x20e8, 0x2165, 0x0056, 0x2029,
+	0x0000, 0x080c, 0x8cad, 0x080c, 0x20a0, 0x1dd8, 0x005e, 0x00ae,
+	0x2001, 0x187f, 0x2004, 0xa88a, 0x080c, 0x1768, 0x781f, 0x0101,
+	0x7813, 0x0000, 0x0126, 0x2091, 0x8000, 0x080c, 0x8b86, 0x012e,
 	0x008e, 0x00ce, 0x00de, 0x0005, 0x7030, 0x9005, 0x0138, 0x2078,
-	0x780c, 0x7032, 0x2001, 0x1946, 0x2003, 0x0001, 0x0005, 0x00e6,
-	0x2071, 0x1923, 0x7030, 0x600e, 0x2c00, 0x7032, 0x00ee, 0x0005,
-	0x00d6, 0x00c6, 0x0026, 0x9b80, 0x8c72, 0x2005, 0x906d, 0x090c,
-	0x0dd5, 0x9b80, 0x8c6a, 0x2005, 0x9065, 0x090c, 0x0dd5, 0x6114,
+	0x780c, 0x7032, 0x2001, 0x1948, 0x2003, 0x0001, 0x0005, 0x00e6,
+	0x2071, 0x1925, 0x7030, 0x600e, 0x2c00, 0x7032, 0x00ee, 0x0005,
+	0x00d6, 0x00c6, 0x0026, 0x9b80, 0x8df6, 0x2005, 0x906d, 0x090c,
+	0x0dc5, 0x9b80, 0x8dee, 0x2005, 0x9065, 0x090c, 0x0dc5, 0x6114,
 	0x2600, 0x9102, 0x0248, 0x6828, 0x9102, 0x02f0, 0x9085, 0x0001,
 	0x002e, 0x00ce, 0x00de, 0x0005, 0x6804, 0xd094, 0x0148, 0x6854,
-	0xd084, 0x1178, 0xc085, 0x6856, 0x2011, 0x8026, 0x080c, 0x4b7f,
-	0x684c, 0x0096, 0x904d, 0x090c, 0x0dd5, 0xa804, 0x8000, 0xa806,
+	0xd084, 0x1178, 0xc085, 0x6856, 0x2011, 0x8026, 0x080c, 0x4be3,
+	0x684c, 0x0096, 0x904d, 0x090c, 0x0dc5, 0xa804, 0x8000, 0xa806,
 	0x009e, 0x9006, 0x2030, 0x0c20, 0x6854, 0xd08c, 0x1d08, 0xc08d,
-	0x6856, 0x2011, 0x8025, 0x080c, 0x4b7f, 0x684c, 0x0096, 0x904d,
-	0x090c, 0x0dd5, 0xa800, 0x8000, 0xa802, 0x009e, 0x0888, 0x7000,
+	0x6856, 0x2011, 0x8025, 0x080c, 0x4be3, 0x684c, 0x0096, 0x904d,
+	0x090c, 0x0dc5, 0xa800, 0x8000, 0xa802, 0x009e, 0x0888, 0x7000,
 	0x2019, 0x0008, 0x8319, 0x7104, 0x9102, 0x1118, 0x2300, 0x9005,
 	0x0020, 0x0210, 0x9302, 0x0008, 0x8002, 0x0005, 0x00d6, 0x7814,
-	0x9005, 0x090c, 0x0dd5, 0x781c, 0x9084, 0x0101, 0x9086, 0x0101,
-	0x190c, 0x0dd5, 0x7827, 0x0000, 0x2069, 0x193c, 0x6804, 0x9080,
-	0x193e, 0x2f08, 0x2102, 0x6904, 0x8108, 0x9182, 0x0008, 0x0208,
-	0x900e, 0x6906, 0x9180, 0x193e, 0x2003, 0x0000, 0x00de, 0x0005,
+	0x9005, 0x090c, 0x0dc5, 0x781c, 0x9084, 0x0101, 0x9086, 0x0101,
+	0x190c, 0x0dc5, 0x7827, 0x0000, 0x2069, 0x193e, 0x6804, 0x9080,
+	0x1940, 0x2f08, 0x2102, 0x6904, 0x8108, 0x9182, 0x0008, 0x0208,
+	0x900e, 0x6906, 0x9180, 0x1940, 0x2003, 0x0000, 0x00de, 0x0005,
 	0x0096, 0x00c6, 0x2060, 0x6014, 0x2048, 0xa8a8, 0x0096, 0x2048,
-	0x9005, 0x190c, 0x1031, 0x009e, 0xa8ab, 0x0000, 0x080c, 0x0fb1,
-	0x080c, 0xaf43, 0x00ce, 0x009e, 0x0005, 0x6020, 0x9086, 0x0009,
+	0x9005, 0x190c, 0x1040, 0x009e, 0xa8ab, 0x0000, 0x080c, 0x0fc0,
+	0x080c, 0xb0e7, 0x00ce, 0x009e, 0x0005, 0x6020, 0x9086, 0x0009,
 	0x1128, 0x601c, 0xd0c4, 0x0110, 0x9006, 0x0005, 0x9085, 0x0001,
 	0x0005, 0x6000, 0x9086, 0x0000, 0x0178, 0x6010, 0x9005, 0x0150,
-	0x00b6, 0x2058, 0x080c, 0x8da7, 0x00be, 0x6013, 0x0000, 0x601b,
-	0x0000, 0x0010, 0x2c00, 0x0861, 0x0005, 0x2009, 0x1927, 0x210c,
-	0xd194, 0x0005, 0x00e6, 0x2071, 0x1923, 0x7110, 0xc194, 0xd19c,
-	0x1118, 0xc185, 0x7007, 0x0000, 0x7112, 0x2001, 0x003b, 0x080c,
-	0x15fd, 0x00ee, 0x0005, 0x7814, 0xd0bc, 0x1108, 0x0005, 0x7810,
-	0xc0c5, 0x7812, 0x0cc0, 0x0096, 0x00d6, 0x9006, 0x7006, 0x700e,
-	0x701a, 0x701e, 0x7022, 0x7016, 0x702a, 0x7026, 0x702f, 0x0000,
-	0x080c, 0x8bf2, 0x0170, 0x080c, 0x8c27, 0x0158, 0x2900, 0x7002,
-	0x700a, 0x701a, 0x7013, 0x0001, 0x701f, 0x000a, 0x00de, 0x009e,
-	0x0005, 0x900e, 0x0cd8, 0x00e6, 0x0096, 0x0086, 0x00d6, 0x00c6,
-	0x2071, 0x1930, 0x721c, 0x2100, 0x9202, 0x1618, 0x080c, 0x8c27,
-	0x090c, 0x0dd5, 0x7018, 0x9005, 0x1160, 0x2900, 0x7002, 0x700a,
-	0x701a, 0x9006, 0x7006, 0x700e, 0xa806, 0xa802, 0x7012, 0x701e,
-	0x0038, 0x2040, 0xa806, 0x2900, 0xa002, 0x701a, 0xa803, 0x0000,
-	0x7010, 0x8000, 0x7012, 0x701c, 0x9080, 0x000a, 0x701e, 0x721c,
-	0x08d0, 0x721c, 0x00ce, 0x00de, 0x008e, 0x009e, 0x00ee, 0x0005,
-	0x0096, 0x0156, 0x0136, 0x0146, 0x00e6, 0x0126, 0x2091, 0x8000,
-	0x2071, 0x1930, 0x7300, 0x831f, 0x831e, 0x831e, 0x9384, 0x003f,
-	0x20e8, 0x939c, 0xffc0, 0x9398, 0x0003, 0x7104, 0x080c, 0x8ba4,
-	0x810c, 0x2100, 0x9318, 0x8003, 0x2228, 0x2021, 0x0078, 0x9402,
-	0x9532, 0x0208, 0x2028, 0x2500, 0x8004, 0x20a8, 0x23a0, 0xa001,
-	0xa001, 0x4005, 0x2508, 0x080c, 0x8bad, 0x2130, 0x7014, 0x9600,
-	0x7016, 0x2600, 0x711c, 0x9102, 0x701e, 0x7004, 0x9600, 0x2008,
-	0x9082, 0x000a, 0x1190, 0x7000, 0x2048, 0xa800, 0x9005, 0x1148,
-	0x2009, 0x0001, 0x0026, 0x080c, 0x8a9b, 0x002e, 0x7000, 0x2048,
-	0xa800, 0x7002, 0x7007, 0x0000, 0x0008, 0x7106, 0x2500, 0x9212,
-	0x1904, 0x8ada, 0x012e, 0x00ee, 0x014e, 0x013e, 0x015e, 0x009e,
-	0x0005, 0x0016, 0x0026, 0x00e6, 0x0126, 0x2091, 0x8000, 0x9580,
-	0x8c6a, 0x2005, 0x9075, 0x090c, 0x0dd5, 0x080c, 0x8b7f, 0x012e,
-	0x9580, 0x8c66, 0x2005, 0x9075, 0x090c, 0x0dd5, 0x0156, 0x0136,
-	0x01c6, 0x0146, 0x01d6, 0x831f, 0x831e, 0x831e, 0x9384, 0x003f,
-	0x20e0, 0x9384, 0xffc0, 0x9100, 0x2098, 0xa860, 0x20e8, 0xa95c,
-	0x2c05, 0x9100, 0x20a0, 0x20a9, 0x0002, 0x4003, 0x2e0c, 0x2d00,
-	0x0002, 0x8b69, 0x8b69, 0x8b6b, 0x8b69, 0x8b6b, 0x8b69, 0x8b69,
-	0x8b69, 0x8b69, 0x8b69, 0x8b71, 0x8b69, 0x8b71, 0x8b69, 0x8b69,
-	0x8b69, 0x080c, 0x0dd5, 0x4104, 0x20a9, 0x0002, 0x4002, 0x4003,
-	0x0028, 0x20a9, 0x0002, 0x4003, 0x4104, 0x4003, 0x01de, 0x014e,
-	0x01ce, 0x013e, 0x015e, 0x00ee, 0x002e, 0x001e, 0x0005, 0x0096,
-	0x7014, 0x8001, 0x7016, 0x710c, 0x2110, 0x00f1, 0x810c, 0x9188,
-	0x0003, 0x7308, 0x8210, 0x9282, 0x000a, 0x1198, 0x7008, 0x2048,
-	0xa800, 0x9005, 0x0158, 0x0006, 0x080c, 0x8c36, 0x009e, 0xa807,
-	0x0000, 0x2900, 0x700a, 0x7010, 0x8001, 0x7012, 0x700f, 0x0000,
-	0x0008, 0x720e, 0x009e, 0x0005, 0x0006, 0x810b, 0x810b, 0x2100,
-	0x810b, 0x9100, 0x2008, 0x000e, 0x0005, 0x0006, 0x0026, 0x2100,
-	0x9005, 0x0158, 0x9092, 0x000c, 0x0240, 0x900e, 0x8108, 0x9082,
-	0x000c, 0x1de0, 0x002e, 0x000e, 0x0005, 0x900e, 0x0cd8, 0x2d00,
-	0x90b8, 0x0008, 0x2031, 0x8bf0, 0x901e, 0x6808, 0x9005, 0x0108,
-	0x8318, 0x690c, 0x910a, 0x0248, 0x0140, 0x8318, 0x6810, 0x9112,
-	0x0220, 0x0118, 0x8318, 0x2208, 0x0cd0, 0x233a, 0x6804, 0xd084,
-	0x2300, 0x2021, 0x0001, 0x1150, 0x9082, 0x0003, 0x0967, 0x0a67,
-	0x8420, 0x9082, 0x0007, 0x0967, 0x0a67, 0x0cd0, 0x9082, 0x0002,
-	0x0967, 0x0a67, 0x8420, 0x9082, 0x0005, 0x0967, 0x0a67, 0x0cd0,
-	0x6c1a, 0x0005, 0x0096, 0x0046, 0x0126, 0x2091, 0x8000, 0x2b00,
-	0x9080, 0x8c6e, 0x2005, 0x9005, 0x090c, 0x0dd5, 0x2004, 0x90a0,
-	0x000a, 0x080c, 0x1018, 0x01d0, 0x2900, 0x7026, 0xa803, 0x0000,
-	0xa807, 0x0000, 0x080c, 0x1018, 0x0188, 0x7024, 0xa802, 0xa807,
-	0x0000, 0x2900, 0x7026, 0x94a2, 0x000a, 0x0110, 0x0208, 0x0c90,
-	0x9085, 0x0001, 0x012e, 0x004e, 0x009e, 0x0005, 0x7024, 0x9005,
-	0x0dc8, 0x2048, 0xac00, 0x080c, 0x1031, 0x2400, 0x0cc0, 0x0126,
-	0x2091, 0x8000, 0x7024, 0x2048, 0x9005, 0x0130, 0xa800, 0x7026,
-	0xa803, 0x0000, 0xa807, 0x0000, 0x012e, 0x0005, 0x0126, 0x2091,
-	0x8000, 0x7024, 0xa802, 0x2900, 0x7026, 0x012e, 0x0005, 0x0096,
-	0x9e80, 0x0009, 0x2004, 0x9005, 0x0138, 0x2048, 0xa800, 0x0006,
-	0x080c, 0x1031, 0x000e, 0x0cb8, 0x009e, 0x0005, 0x0096, 0x7008,
-	0x9005, 0x0138, 0x2048, 0xa800, 0x0006, 0x080c, 0x1031, 0x000e,
-	0x0cb8, 0x9006, 0x7002, 0x700a, 0x7006, 0x700e, 0x701a, 0x701e,
-	0x7022, 0x702a, 0x7026, 0x702e, 0x009e, 0x0005, 0x1a63, 0x0000,
-	0x0000, 0x0000, 0x1930, 0x0000, 0x0000, 0x0000, 0x1888, 0x0000,
-	0x0000, 0x0000, 0x1877, 0x0000, 0x0000, 0x0000, 0x00e6, 0x00c6,
-	0x00b6, 0x00a6, 0xa8a8, 0x2040, 0x2071, 0x1877, 0x080c, 0x8d92,
-	0xa067, 0x0023, 0x6010, 0x905d, 0x0904, 0x8d67, 0xb814, 0xa06e,
-	0xb910, 0xa172, 0xb9a0, 0xa176, 0x2001, 0x0003, 0xa07e, 0xa834,
-	0xa082, 0xa07b, 0x0000, 0xa898, 0x9005, 0x0118, 0xa078, 0xc085,
-	0xa07a, 0x2858, 0x2031, 0x0018, 0xa068, 0x908a, 0x0019, 0x1a0c,
-	0x0dd5, 0x2020, 0x2050, 0x2940, 0xa864, 0x90bc, 0x00ff, 0x908c,
-	0x000f, 0x91e0, 0x20ce, 0x2c65, 0x9786, 0x0024, 0x2c05, 0x1590,
-	0x908a, 0x0036, 0x1a0c, 0x0dd5, 0x9082, 0x001b, 0x0002, 0x8cd2,
-	0x8cd2, 0x8cd4, 0x8cd2, 0x8cd2, 0x8cd2, 0x8cd6, 0x8cd2, 0x8cd2,
-	0x8cd2, 0x8cd8, 0x8cd2, 0x8cd2, 0x8cd2, 0x8cda, 0x8cd2, 0x8cd2,
-	0x8cd2, 0x8cdc, 0x8cd2, 0x8cd2, 0x8cd2, 0x8cde, 0x8cd2, 0x8cd2,
-	0x8cd2, 0x8ce0, 0x080c, 0x0dd5, 0xa180, 0x04b8, 0xa190, 0x04a8,
-	0xa1a0, 0x0498, 0xa1b0, 0x0488, 0xa1c0, 0x0478, 0xa1d0, 0x0468,
-	0xa1e0, 0x0458, 0x908a, 0x0034, 0x1a0c, 0x0dd5, 0x9082, 0x001b,
-	0x0002, 0x8d04, 0x8d02, 0x8d02, 0x8d02, 0x8d02, 0x8d02, 0x8d06,
-	0x8d02, 0x8d02, 0x8d02, 0x8d02, 0x8d02, 0x8d08, 0x8d02, 0x8d02,
-	0x8d02, 0x8d02, 0x8d02, 0x8d0a, 0x8d02, 0x8d02, 0x8d02, 0x8d02,
-	0x8d02, 0x8d0c, 0x080c, 0x0dd5, 0xa180, 0x0038, 0xa198, 0x0028,
-	0xa1b0, 0x0018, 0xa1c8, 0x0008, 0xa1e0, 0x2600, 0x0002, 0x8d28,
-	0x8d2a, 0x8d2c, 0x8d2e, 0x8d30, 0x8d32, 0x8d34, 0x8d36, 0x8d38,
-	0x8d3a, 0x8d3c, 0x8d3e, 0x8d40, 0x8d42, 0x8d44, 0x8d46, 0x8d48,
-	0x8d4a, 0x8d4c, 0x8d4e, 0x8d50, 0x8d52, 0x8d54, 0x8d56, 0x8d58,
-	0x080c, 0x0dd5, 0xb9e2, 0x0468, 0xb9de, 0x0458, 0xb9da, 0x0448,
-	0xb9d6, 0x0438, 0xb9d2, 0x0428, 0xb9ce, 0x0418, 0xb9ca, 0x0408,
-	0xb9c6, 0x00f8, 0xb9c2, 0x00e8, 0xb9be, 0x00d8, 0xb9ba, 0x00c8,
-	0xb9b6, 0x00b8, 0xb9b2, 0x00a8, 0xb9ae, 0x0098, 0xb9aa, 0x0088,
-	0xb9a6, 0x0078, 0xb9a2, 0x0068, 0xb99e, 0x0058, 0xb99a, 0x0048,
-	0xb996, 0x0038, 0xb992, 0x0028, 0xb98e, 0x0018, 0xb98a, 0x0008,
-	0xb986, 0x8631, 0x8421, 0x0130, 0x080c, 0x2086, 0x090c, 0x0dd5,
-	0x0804, 0x8cac, 0x00ae, 0x00be, 0x00ce, 0x00ee, 0x0005, 0xa86c,
-	0xa06e, 0xa870, 0xa072, 0xa077, 0x00ff, 0x9006, 0x0804, 0x8c8e,
-	0x0006, 0x0016, 0x00b6, 0x6010, 0x2058, 0xb810, 0x9005, 0x01b0,
-	0x2001, 0x1924, 0x2004, 0x9005, 0x0188, 0x2001, 0x1800, 0x2004,
-	0x9086, 0x0003, 0x1158, 0x0036, 0x0046, 0xbba0, 0x2021, 0x0004,
-	0x2011, 0x8014, 0x080c, 0x4b7f, 0x004e, 0x003e, 0x00be, 0x001e,
-	0x000e, 0x0005, 0x9016, 0x710c, 0xa834, 0x910a, 0xa936, 0x7008,
-	0x9005, 0x0120, 0x8210, 0x910a, 0x0238, 0x0130, 0x7010, 0x8210,
-	0x910a, 0x0210, 0x0108, 0x0cd8, 0xaa8a, 0xa26a, 0x0005, 0x00f6,
-	0x00d6, 0x0036, 0x2079, 0x0300, 0x781b, 0x0200, 0x7818, 0xd094,
-	0x1dd8, 0x781b, 0x0202, 0xa001, 0xa001, 0x7818, 0xd094, 0x1da0,
-	0xb8ac, 0x9005, 0x01b8, 0x2068, 0x2079, 0x0000, 0x2c08, 0x911e,
-	0x1118, 0x680c, 0xb8ae, 0x0060, 0x9106, 0x0140, 0x2d00, 0x2078,
-	0x680c, 0x9005, 0x090c, 0x0dd5, 0x2068, 0x0cb0, 0x6b0c, 0x7b0e,
-	0x600f, 0x0000, 0x2079, 0x0300, 0x781b, 0x0200, 0x003e, 0x00de,
-	0x00fe, 0x0005, 0x00e6, 0x00d6, 0x0096, 0x00c6, 0x0036, 0x0126,
-	0x2091, 0x8000, 0x0156, 0x20a9, 0x01ff, 0x2071, 0x0300, 0x701b,
-	0x0200, 0x7018, 0xd094, 0x0110, 0x1f04, 0x8de7, 0x701b, 0x0202,
-	0xa001, 0xa001, 0x7018, 0xd094, 0x1d90, 0xb8ac, 0x9005, 0x01e8,
-	0x2060, 0x600c, 0xb8ae, 0x6024, 0xc08d, 0x6026, 0x6003, 0x0004,
-	0x601b, 0x0000, 0x6013, 0x0000, 0x601f, 0x0101, 0x6014, 0x2048,
-	0xa88b, 0x0000, 0xa8a8, 0xa8ab, 0x0000, 0x904d, 0x090c, 0x0dd5,
-	0x080c, 0x1031, 0x080c, 0x89a7, 0x0c00, 0x2071, 0x0300, 0x701b,
-	0x0200, 0x015e, 0x012e, 0x003e, 0x00ce, 0x009e, 0x00de, 0x00ee,
-	0x0005, 0x00c6, 0x00b6, 0x0016, 0x0006, 0x0156, 0x080c, 0x287c,
-	0x015e, 0x11b0, 0x080c, 0x6638, 0x190c, 0x0dd5, 0x000e, 0x001e,
-	0xb912, 0xb816, 0x080c, 0xaeed, 0x0140, 0x2b00, 0x6012, 0x6023,
-	0x0001, 0x2009, 0x0001, 0x080c, 0xafbe, 0x00be, 0x00ce, 0x0005,
-	0x000e, 0x001e, 0x0cd0, 0x0066, 0x6000, 0x90b2, 0x0016, 0x1a0c,
-	0x0dd5, 0x0013, 0x006e, 0x0005, 0x8e5c, 0x8e5c, 0x8e5c, 0x8e5e,
-	0x8eaf, 0x8e5c, 0x8e5c, 0x8e5c, 0x8f16, 0x8e5c, 0x8f53, 0x8e5c,
-	0x8e5c, 0x8e5c, 0x8e5c, 0x8e5c, 0x080c, 0x0dd5, 0x9182, 0x0040,
-	0x0002, 0x8e71, 0x8e71, 0x8e71, 0x8e71, 0x8e71, 0x8e71, 0x8e71,
-	0x8e71, 0x8e71, 0x8e73, 0x8e88, 0x8e71, 0x8e71, 0x8e71, 0x8e71,
-	0x8e9b, 0x080c, 0x0dd5, 0x0096, 0x080c, 0x9713, 0x080c, 0x9891,
-	0x6114, 0x2148, 0xa87b, 0x0000, 0x6010, 0x00b6, 0x2058, 0xb8bb,
-	0x0500, 0x00be, 0x080c, 0x6b1d, 0x080c, 0xaf43, 0x009e, 0x0005,
-	0x080c, 0x9713, 0x00d6, 0x6114, 0x080c, 0xcc86, 0x0130, 0x0096,
-	0x6114, 0x2148, 0x080c, 0x6d17, 0x009e, 0x00de, 0x080c, 0xaf43,
-	0x080c, 0x9891, 0x0005, 0x080c, 0x9713, 0x080c, 0x321e, 0x6114,
-	0x0096, 0x2148, 0x080c, 0xcc86, 0x0120, 0xa87b, 0x0029, 0x080c,
-	0x6d17, 0x009e, 0x080c, 0xaf43, 0x080c, 0x9891, 0x0005, 0x601b,
-	0x0000, 0x9182, 0x0040, 0x0096, 0x0002, 0x8eca, 0x8eca, 0x8eca,
-	0x8eca, 0x8eca, 0x8eca, 0x8eca, 0x8eca, 0x8ecc, 0x8eca, 0x8eca,
-	0x8eca, 0x8f12, 0x8eca, 0x8eca, 0x8eca, 0x8eca, 0x8eca, 0x8eca,
-	0x8ed3, 0x8eca, 0x080c, 0x0dd5, 0x6114, 0x2148, 0xa938, 0x918e,
-	0xffff, 0x0904, 0x8f12, 0x6024, 0xd08c, 0x15c0, 0x00e6, 0x6114,
-	0x2148, 0x080c, 0x8c76, 0x0096, 0xa8a8, 0x2048, 0x080c, 0x6ab5,
-	0x009e, 0xa8ab, 0x0000, 0x6010, 0x9005, 0x0128, 0x00b6, 0x2058,
-	0x080c, 0x8da7, 0x00be, 0xae88, 0x00b6, 0x2059, 0x0000, 0x080c,
-	0x89b0, 0x00be, 0x01e0, 0x2071, 0x193c, 0x080c, 0x89f7, 0x01b8,
-	0x9086, 0x0001, 0x1128, 0x2001, 0x1946, 0x2004, 0x9005, 0x1178,
-	0x0096, 0x080c, 0x0fff, 0x2900, 0x009e, 0x0148, 0xa8aa, 0x00f6,
-	0x2c78, 0x080c, 0x896e, 0x00fe, 0x00ee, 0x009e, 0x0005, 0x080c,
-	0x89a7, 0x0cd0, 0x080c, 0x8fc0, 0x009e, 0x0005, 0x9182, 0x0040,
-	0x0096, 0x0002, 0x8f2a, 0x8f2a, 0x8f2a, 0x8f2c, 0x8f2a, 0x8f2a,
-	0x8f2a, 0x8f51, 0x8f2a, 0x8f2a, 0x8f2a, 0x8f2a, 0x8f2a, 0x8f2a,
-	0x8f2a, 0x8f2a, 0x080c, 0x0dd5, 0x6003, 0x0003, 0x6106, 0x6014,
-	0x2048, 0xa8ac, 0xa846, 0xa8b0, 0xa84a, 0xa837, 0x0000, 0xa83b,
-	0x0000, 0xa884, 0x9092, 0x199a, 0x0210, 0x2001, 0x1999, 0x8003,
-	0x8013, 0x8213, 0x9210, 0x621a, 0x2c10, 0x080c, 0x1beb, 0x080c,
-	0x9216, 0x0126, 0x2091, 0x8000, 0x080c, 0x9891, 0x012e, 0x009e,
-	0x0005, 0x080c, 0x0dd5, 0x080c, 0x9713, 0x080c, 0x9891, 0x6114,
-	0x2148, 0xa87b, 0x0000, 0x6010, 0x00b6, 0x2058, 0xb8bb, 0x0500,
-	0x00be, 0x080c, 0x6d17, 0x080c, 0xaf43, 0x009e, 0x0005, 0x6000,
-	0x908a, 0x0016, 0x1a0c, 0x0dd5, 0x0096, 0x0013, 0x009e, 0x0005,
-	0x8f80, 0x8f80, 0x8f80, 0x8f82, 0x8f93, 0x8f80, 0x8f80, 0x8f80,
-	0x8f80, 0x8f80, 0x8f80, 0x8f80, 0x8f80, 0x8f80, 0x8f80, 0x8f80,
-	0x080c, 0x0dd5, 0x080c, 0xa89b, 0x6114, 0x2148, 0xa87b, 0x0006,
-	0x6010, 0x00b6, 0x2058, 0xb8bb, 0x0500, 0x00be, 0x080c, 0x6d17,
-	0x080c, 0xaf43, 0x0005, 0x0461, 0x0005, 0x6000, 0x908a, 0x0016,
-	0x1a0c, 0x0dd5, 0x0096, 0x0013, 0x009e, 0x0005, 0x8fae, 0x8fae,
-	0x8fae, 0x8fb0, 0x8fc0, 0x8fae, 0x8fae, 0x8fae, 0x8fae, 0x8fae,
-	0x8fae, 0x8fae, 0x8fae, 0x8fae, 0x8fae, 0x8fae, 0x080c, 0x0dd5,
-	0x0036, 0x00e6, 0x2071, 0x19e6, 0x703c, 0x9c06, 0x1120, 0x2019,
-	0x0000, 0x080c, 0xa6ac, 0x080c, 0xa89b, 0x00ee, 0x003e, 0x0005,
-	0x6024, 0xd08c, 0x11f0, 0x00f6, 0x00e6, 0x601b, 0x0000, 0x6014,
-	0x2048, 0x6010, 0x9005, 0x0128, 0x00b6, 0x2058, 0x080c, 0x8da7,
-	0x00be, 0x2071, 0x193c, 0x080c, 0x89f7, 0x0160, 0x2001, 0x187f,
-	0x2004, 0xa88a, 0x2031, 0x0000, 0x2c78, 0x080c, 0x896e, 0x00ee,
-	0x00fe, 0x0005, 0x0096, 0xa88b, 0x0000, 0xa8a8, 0x2048, 0x080c,
-	0x1031, 0x009e, 0xa8ab, 0x0000, 0x080c, 0x89a7, 0x0c80, 0x0000,
-	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
-	0x187a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0126,
-	0x2091, 0x8000, 0x0036, 0x0046, 0x20a9, 0x0010, 0x9006, 0x8004,
-	0x2019, 0x0100, 0x231c, 0x93a6, 0x0008, 0x1118, 0x8086, 0x818e,
-	0x0020, 0x80f6, 0x3e00, 0x81f6, 0x3e08, 0x1208, 0x9200, 0x1f04,
-	0x9008, 0x93a6, 0x0008, 0x1118, 0x8086, 0x818e, 0x0020, 0x80f6,
-	0x3e00, 0x81f6, 0x3e08, 0x004e, 0x003e, 0x012e, 0x0005, 0x0126,
-	0x2091, 0x8000, 0x0076, 0x0156, 0x20a9, 0x0010, 0x9005, 0x0510,
-	0x911a, 0x1600, 0x8213, 0x2039, 0x0100, 0x273c, 0x97be, 0x0008,
-	0x1110, 0x818d, 0x0010, 0x81f5, 0x3e08, 0x0228, 0x911a, 0x1220,
-	0x1f04, 0x9032, 0x0028, 0x911a, 0x2308, 0x8210, 0x1f04, 0x9032,
-	0x0006, 0x3200, 0x9084, 0xefff, 0x2080, 0x000e, 0x015e, 0x007e,
-	0x012e, 0x0005, 0x0006, 0x3200, 0x9085, 0x1000, 0x0ca8, 0x0126,
-	0x2091, 0x2800, 0x2079, 0x19e6, 0x012e, 0x00d6, 0x2069, 0x19e6,
-	0x6803, 0x0005, 0x0156, 0x0146, 0x01d6, 0x20e9, 0x0000, 0x2069,
-	0x0200, 0x080c, 0xabfe, 0x0401, 0x080c, 0xabe9, 0x00e9, 0x080c,
-	0xabec, 0x00d1, 0x080c, 0xabef, 0x00b9, 0x080c, 0xabf2, 0x00a1,
-	0x080c, 0xabf5, 0x0089, 0x080c, 0xabf8, 0x0071, 0x080c, 0xabfb,
-	0x0059, 0x01de, 0x014e, 0x015e, 0x2069, 0x0004, 0x2d04, 0x9085,
-	0x8001, 0x206a, 0x00de, 0x0005, 0x20a9, 0x0020, 0x20a1, 0x0240,
-	0x2001, 0x0000, 0x4004, 0x0005, 0x00c6, 0x6027, 0x0001, 0x7804,
-	0x9084, 0x0007, 0x0002, 0x90a5, 0x90c9, 0x910a, 0x90ab, 0x90c9,
-	0x90a5, 0x90a3, 0x90a3, 0x080c, 0x0dd5, 0x080c, 0x8636, 0x080c,
-	0x9763, 0x00ce, 0x0005, 0x62c0, 0x82ff, 0x1110, 0x00ce, 0x0005,
-	0x2011, 0x5f16, 0x080c, 0x85b0, 0x7828, 0x9092, 0x00c8, 0x1228,
-	0x8000, 0x782a, 0x080c, 0x5f56, 0x0c88, 0x62c0, 0x080c, 0xad3a,
-	0x080c, 0x5f16, 0x7807, 0x0003, 0x7827, 0x0000, 0x782b, 0x0000,
-	0x0c28, 0x080c, 0x8636, 0x6220, 0xd2a4, 0x0170, 0xd2cc, 0x0160,
-	0x782b, 0x0000, 0x7824, 0x9065, 0x090c, 0x0dd5, 0x2009, 0x0013,
-	0x080c, 0xafbe, 0x00ce, 0x0005, 0x00c6, 0x7824, 0x9065, 0x090c,
-	0x0dd5, 0x7828, 0x9092, 0xc350, 0x12c0, 0x8000, 0x782a, 0x00ce,
-	0x080c, 0x2be3, 0x0278, 0x00c6, 0x7924, 0x2160, 0x6010, 0x906d,
-	0x090c, 0x0dd5, 0x7807, 0x0000, 0x7827, 0x0000, 0x00ce, 0x080c,
-	0x9763, 0x0c00, 0x080c, 0xa332, 0x08e8, 0x2011, 0x0130, 0x2214,
-	0x080c, 0xad3a, 0x080c, 0xeb8e, 0x2009, 0x0014, 0x080c, 0xafbe,
-	0x00ce, 0x0880, 0x2001, 0x1a02, 0x2003, 0x0000, 0x62c0, 0x82ff,
-	0x1160, 0x782b, 0x0000, 0x7824, 0x9065, 0x090c, 0x0dd5, 0x2009,
-	0x0013, 0x080c, 0xb010, 0x00ce, 0x0005, 0x00b6, 0x00c6, 0x00d6,
-	0x7824, 0x9005, 0x090c, 0x0dd5, 0x7828, 0x9092, 0xc350, 0x1648,
-	0x8000, 0x782a, 0x00de, 0x00ce, 0x00be, 0x080c, 0x2be3, 0x02f0,
-	0x00b6, 0x00c6, 0x00d6, 0x781c, 0x905d, 0x090c, 0x0dd5, 0xb800,
-	0xc0dc, 0xb802, 0x7924, 0x2160, 0x080c, 0xaf43, 0xb93c, 0x81ff,
-	0x090c, 0x0dd5, 0x8109, 0xb93e, 0x7807, 0x0000, 0x7827, 0x0000,
-	0x00de, 0x00ce, 0x00be, 0x080c, 0x9763, 0x0868, 0x080c, 0xa332,
-	0x0850, 0x2011, 0x0130, 0x2214, 0x080c, 0xad3a, 0x080c, 0xeb8e,
-	0x7824, 0x9065, 0x2009, 0x0014, 0x080c, 0xafbe, 0x00de, 0x00ce,
-	0x00be, 0x0804, 0x911b, 0x00c6, 0x2001, 0x009b, 0x2004, 0xd0fc,
-	0x190c, 0x1ef2, 0x6024, 0x6027, 0x0002, 0xd0f4, 0x15b8, 0x62c8,
-	0x60c4, 0x9205, 0x1170, 0x783c, 0x9065, 0x0130, 0x2009, 0x0049,
-	0x080c, 0xafbe, 0x00ce, 0x0005, 0x2011, 0x1a05, 0x2013, 0x0000,
-	0x0cc8, 0x793c, 0x81ff, 0x0dc0, 0x7944, 0x9192, 0x7530, 0x1628,
-	0x8108, 0x7946, 0x793c, 0x9188, 0x0008, 0x210c, 0x918e, 0x0006,
-	0x1138, 0x6014, 0x9084, 0x1984, 0x9085, 0x0012, 0x6016, 0x0c10,
-	0x793c, 0x9188, 0x0008, 0x210c, 0x918e, 0x0009, 0x0d90, 0x6014,
-	0x9084, 0x1984, 0x9085, 0x0016, 0x6016, 0x08a0, 0x793c, 0x2160,
-	0x2009, 0x004a, 0x080c, 0xafbe, 0x0868, 0x7848, 0xc085, 0x784a,
-	0x0848, 0x0006, 0x0016, 0x00c6, 0x0126, 0x2091, 0x8000, 0x600f,
-	0x0000, 0x2c08, 0x2061, 0x19e6, 0x6020, 0x8000, 0x6022, 0x6010,
-	0x9005, 0x0148, 0x9080, 0x0003, 0x2102, 0x6112, 0x012e, 0x00ce,
-	0x001e, 0x000e, 0x0005, 0x6116, 0x6112, 0x0cc0, 0x00d6, 0x2069,
-	0x19e6, 0xb800, 0xd0d4, 0x0168, 0x6820, 0x8000, 0x6822, 0x9086,
-	0x0001, 0x1110, 0x2b00, 0x681e, 0x00de, 0x0804, 0x9763, 0x00de,
-	0x0005, 0xc0d5, 0xb802, 0x6818, 0x9005, 0x0168, 0xb856, 0xb85b,
-	0x0000, 0x0086, 0x0006, 0x2b00, 0x681a, 0x008e, 0xa05a, 0x008e,
-	0x2069, 0x19e6, 0x0c08, 0xb856, 0xb85a, 0x2b00, 0x681a, 0x681e,
-	0x08d8, 0x0006, 0x0016, 0x00c6, 0x0126, 0x2091, 0x8000, 0x600f,
-	0x0000, 0x2c08, 0x2061, 0x19e6, 0x6020, 0x8000, 0x6022, 0x6008,
-	0x9005, 0x0148, 0x9080, 0x0003, 0x2102, 0x610a, 0x012e, 0x00ce,
-	0x001e, 0x000e, 0x0005, 0x610e, 0x610a, 0x0cc0, 0x00c6, 0x600f,
-	0x0000, 0x2c08, 0x2061, 0x19e6, 0x6034, 0x9005, 0x0130, 0x9080,
-	0x0003, 0x2102, 0x6136, 0x00ce, 0x0005, 0x613a, 0x6136, 0x00ce,
-	0x0005, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x00b6, 0x0096, 0x0076,
-	0x0066, 0x0056, 0x0036, 0x0026, 0x0016, 0x0006, 0x0126, 0x902e,
-	0x2071, 0x19e6, 0x7638, 0x2660, 0x2678, 0x2091, 0x8000, 0x8cff,
-	0x0904, 0x92a5, 0x6010, 0x2058, 0xb8a0, 0x9206, 0x1904, 0x92a0,
-	0x87ff, 0x0120, 0x6054, 0x9106, 0x1904, 0x92a0, 0x703c, 0x9c06,
-	0x1178, 0x0036, 0x2019, 0x0001, 0x080c, 0xa6ac, 0x7033, 0x0000,
-	0x9006, 0x703e, 0x7042, 0x7046, 0x704a, 0x003e, 0x2029, 0x0001,
-	0x7038, 0x9c36, 0x1110, 0x660c, 0x763a, 0x7034, 0x9c36, 0x1140,
-	0x2c00, 0x9f36, 0x0118, 0x2f00, 0x7036, 0x0010, 0x7037, 0x0000,
-	0x660c, 0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678,
-	0x600f, 0x0000, 0x080c, 0xcc86, 0x01f0, 0x6014, 0x2048, 0x6020,
-	0x9086, 0x0003, 0x15b8, 0x6004, 0x9086, 0x0040, 0x090c, 0xa88b,
-	0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x0016, 0x0036, 0x0076,
-	0x080c, 0xcf7c, 0x080c, 0xea94, 0x080c, 0x6d17, 0x007e, 0x003e,
-	0x001e, 0x080c, 0xce71, 0x080c, 0xaf74, 0x00ce, 0x0804, 0x923f,
-	0x2c78, 0x600c, 0x2060, 0x0804, 0x923f, 0x85ff, 0x0120, 0x0036,
-	0x080c, 0x9891, 0x003e, 0x012e, 0x000e, 0x001e, 0x002e, 0x003e,
-	0x005e, 0x006e, 0x007e, 0x009e, 0x00be, 0x00ce, 0x00de, 0x00ee,
-	0x00fe, 0x0005, 0x6020, 0x9086, 0x0006, 0x1158, 0x0016, 0x0036,
-	0x0076, 0x080c, 0xea94, 0x080c, 0xe6dd, 0x007e, 0x003e, 0x001e,
-	0x0890, 0x6020, 0x9086, 0x0009, 0x1168, 0xa87b, 0x0006, 0x0016,
-	0x0036, 0x0076, 0x080c, 0x6d17, 0x080c, 0xaf43, 0x007e, 0x003e,
-	0x001e, 0x0818, 0x6020, 0x9086, 0x000a, 0x0904, 0x928a, 0x0804,
-	0x9283, 0x0006, 0x0066, 0x0096, 0x00c6, 0x00d6, 0x00f6, 0x9036,
-	0x0126, 0x2091, 0x8000, 0x2079, 0x19e6, 0x7838, 0x9065, 0x0904,
-	0x9336, 0x600c, 0x0006, 0x600f, 0x0000, 0x783c, 0x9c06, 0x1168,
-	0x0036, 0x2019, 0x0001, 0x080c, 0xa6ac, 0x7833, 0x0000, 0x901e,
-	0x7b3e, 0x7b42, 0x7b46, 0x7b4a, 0x003e, 0x080c, 0xcc86, 0x0548,
-	0x6014, 0x2048, 0x6020, 0x9086, 0x0003, 0x1590, 0x3e08, 0x918e,
-	0x0002, 0x1188, 0x6010, 0x9005, 0x0170, 0x00b6, 0x2058, 0xb800,
-	0x00be, 0xd0bc, 0x0140, 0x6040, 0x9005, 0x11a8, 0x2001, 0x1987,
-	0x2004, 0x6042, 0x0080, 0x6004, 0x9086, 0x0040, 0x090c, 0xa88b,
-	0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0x6d0b, 0x080c,
-	0xce71, 0x080c, 0xaf74, 0x000e, 0x0804, 0x92ee, 0x7e3a, 0x7e36,
-	0x012e, 0x00fe, 0x00de, 0x00ce, 0x009e, 0x006e, 0x000e, 0x0005,
-	0x6020, 0x9086, 0x0006, 0x1118, 0x080c, 0xe6dd, 0x0c50, 0x6020,
-	0x9086, 0x0009, 0x1130, 0xab7a, 0x080c, 0x6d17, 0x080c, 0xaf43,
-	0x0c10, 0x6020, 0x9086, 0x000a, 0x09a8, 0x0868, 0x0016, 0x0026,
-	0x0086, 0x9046, 0x0099, 0x080c, 0x9441, 0x008e, 0x002e, 0x001e,
-	0x0005, 0x00f6, 0x0126, 0x2079, 0x19e6, 0x2091, 0x8000, 0x080c,
-	0x94d8, 0x080c, 0x9568, 0x012e, 0x00fe, 0x0005, 0x00b6, 0x0096,
-	0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0016, 0x0006, 0x0126,
-	0x2091, 0x8000, 0x2071, 0x19e6, 0x7614, 0x2660, 0x2678, 0x8cff,
-	0x0904, 0x9406, 0x6010, 0x2058, 0xb8a0, 0x9206, 0x1904, 0x9401,
-	0x88ff, 0x0120, 0x6054, 0x9106, 0x1904, 0x9401, 0x7024, 0x9c06,
-	0x1568, 0x2069, 0x0100, 0x6820, 0xd0a4, 0x0110, 0xd0cc, 0x1508,
-	0x080c, 0x8636, 0x080c, 0xa356, 0x68c3, 0x0000, 0x080c, 0xa88b,
-	0x7027, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0x9384, 0x1000,
-	0x0138, 0x2001, 0x0100, 0x080c, 0x2d4e, 0x9006, 0x080c, 0x2d4e,
-	0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x003e,
-	0x0028, 0x6003, 0x0009, 0x630a, 0x0804, 0x9401, 0x7014, 0x9c36,
-	0x1110, 0x660c, 0x7616, 0x7010, 0x9c36, 0x1140, 0x2c00, 0x9f36,
-	0x0118, 0x2f00, 0x7012, 0x0010, 0x7013, 0x0000, 0x660c, 0x0066,
-	0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000,
-	0x6014, 0x2048, 0x080c, 0xcc86, 0x01e8, 0x6020, 0x9086, 0x0003,
-	0x1580, 0x080c, 0xce8e, 0x1118, 0x080c, 0xb905, 0x0098, 0xa867,
-	0x0103, 0xab7a, 0xa877, 0x0000, 0x0016, 0x0036, 0x0086, 0x080c,
-	0xcf7c, 0x080c, 0xea94, 0x080c, 0x6d17, 0x008e, 0x003e, 0x001e,
-	0x080c, 0xce71, 0x080c, 0xaf74, 0x080c, 0xa761, 0x00ce, 0x0804,
-	0x937f, 0x2c78, 0x600c, 0x2060, 0x0804, 0x937f, 0x012e, 0x000e,
-	0x001e, 0x006e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x009e, 0x00be,
-	0x0005, 0x6020, 0x9086, 0x0006, 0x1158, 0x0016, 0x0036, 0x0086,
-	0x080c, 0xea94, 0x080c, 0xe6dd, 0x008e, 0x003e, 0x001e, 0x08d0,
-	0x080c, 0xb905, 0x6020, 0x9086, 0x0002, 0x1160, 0x6004, 0x0006,
-	0x9086, 0x0085, 0x000e, 0x0904, 0x93e7, 0x9086, 0x008b, 0x0904,
-	0x93e7, 0x0840, 0x6020, 0x9086, 0x0005, 0x1920, 0x6004, 0x0006,
-	0x9086, 0x0085, 0x000e, 0x09c8, 0x9086, 0x008b, 0x09b0, 0x0804,
-	0x93fa, 0x00b6, 0x00a6, 0x0096, 0x00c6, 0x0006, 0x0126, 0x2091,
-	0x8000, 0x9280, 0x1000, 0x2004, 0x905d, 0x0904, 0x94d1, 0x00f6,
-	0x00e6, 0x00d6, 0x0066, 0x2071, 0x19e6, 0xbe54, 0x7018, 0x9b06,
-	0x1108, 0x761a, 0x701c, 0x9b06, 0x1130, 0x86ff, 0x1118, 0x7018,
-	0x701e, 0x0008, 0x761e, 0xb858, 0x904d, 0x0108, 0xae56, 0x96d5,
-	0x0000, 0x0110, 0x2900, 0xb05a, 0xb857, 0x0000, 0xb85b, 0x0000,
-	0xb800, 0xc0d4, 0xc0dc, 0xb802, 0x080c, 0x65cb, 0x0904, 0x94cd,
-	0x7624, 0x86ff, 0x0904, 0x94bc, 0x9680, 0x0005, 0x2004, 0x9906,
-	0x15d8, 0x00d6, 0x2069, 0x0100, 0x68c0, 0x9005, 0x0560, 0x080c,
-	0x8636, 0x080c, 0xa356, 0x68c3, 0x0000, 0x080c, 0xa88b, 0x7027,
-	0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138,
-	0x2001, 0x0100, 0x080c, 0x2d4e, 0x9006, 0x080c, 0x2d4e, 0x2069,
-	0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x00de,
-	0x00c6, 0xb83c, 0x9005, 0x0110, 0x8001, 0xb83e, 0x2660, 0x080c,
-	0xaf74, 0x00ce, 0x0048, 0x00de, 0x00c6, 0x2660, 0x6003, 0x0009,
-	0x630a, 0x00ce, 0x0804, 0x9474, 0x89ff, 0x0158, 0xa867, 0x0103,
-	0xab7a, 0xa877, 0x0000, 0x080c, 0xcf7c, 0x080c, 0xea94, 0x080c,
-	0x6d17, 0x080c, 0xa761, 0x0804, 0x9474, 0x006e, 0x00de, 0x00ee,
-	0x00fe, 0x012e, 0x000e, 0x00ce, 0x009e, 0x00ae, 0x00be, 0x0005,
-	0x0096, 0x0006, 0x0066, 0x00c6, 0x00d6, 0x9036, 0x7814, 0x9065,
-	0x0904, 0x953b, 0x600c, 0x0006, 0x600f, 0x0000, 0x7824, 0x9c06,
-	0x1580, 0x2069, 0x0100, 0x6820, 0xd0a4, 0x0110, 0xd0cc, 0x1508,
-	0x080c, 0x8636, 0x080c, 0xa356, 0x68c3, 0x0000, 0x080c, 0xa88b,
-	0x7827, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0x9384, 0x1000,
-	0x0138, 0x2001, 0x0100, 0x080c, 0x2d4e, 0x9006, 0x080c, 0x2d4e,
-	0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x003e,
-	0x0040, 0x080c, 0x69a4, 0x1520, 0x6003, 0x0009, 0x630a, 0x2c30,
-	0x00f8, 0x6014, 0x2048, 0x080c, 0xcc84, 0x01b0, 0x6020, 0x9086,
-	0x0003, 0x1508, 0x080c, 0xce8e, 0x1118, 0x080c, 0xb905, 0x0060,
-	0x080c, 0x69a4, 0x1168, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000,
-	0x080c, 0x6d17, 0x080c, 0xce71, 0x080c, 0xaf74, 0x080c, 0xa761,
-	0x000e, 0x0804, 0x94df, 0x7e16, 0x7e12, 0x00de, 0x00ce, 0x006e,
-	0x000e, 0x009e, 0x0005, 0x6020, 0x9086, 0x0006, 0x1118, 0x080c,
-	0xe6dd, 0x0c50, 0x080c, 0xb905, 0x6020, 0x9086, 0x0002, 0x1150,
-	0x6004, 0x0006, 0x9086, 0x0085, 0x000e, 0x0990, 0x9086, 0x008b,
-	0x0978, 0x08d0, 0x6020, 0x9086, 0x0005, 0x19b0, 0x6004, 0x0006,
-	0x9086, 0x0085, 0x000e, 0x0d18, 0x9086, 0x008b, 0x0d00, 0x0860,
-	0x0006, 0x0066, 0x0096, 0x00b6, 0x00c6, 0x00d6, 0x7818, 0x905d,
-	0x0904, 0x95e8, 0xb854, 0x0006, 0x9006, 0xb856, 0xb85a, 0xb800,
-	0xc0d4, 0xc0dc, 0xb802, 0x080c, 0x65cb, 0x0904, 0x95e5, 0x7e24,
-	0x86ff, 0x0904, 0x95d8, 0x9680, 0x0005, 0x2004, 0x9906, 0x1904,
-	0x95d8, 0x00d6, 0x2069, 0x0100, 0x68c0, 0x9005, 0x0904, 0x95cf,
-	0x080c, 0x8636, 0x080c, 0xa356, 0x68c3, 0x0000, 0x080c, 0xa88b,
-	0x7827, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0x9384, 0x1000,
-	0x0138, 0x2001, 0x0100, 0x080c, 0x2d4e, 0x9006, 0x080c, 0x2d4e,
-	0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x003e,
-	0x00de, 0x00c6, 0x3e08, 0x918e, 0x0002, 0x1168, 0xb800, 0xd0bc,
-	0x0150, 0x9680, 0x0010, 0x200c, 0x81ff, 0x1518, 0x2009, 0x1987,
-	0x210c, 0x2102, 0x00f0, 0xb83c, 0x9005, 0x0110, 0x8001, 0xb83e,
-	0x2660, 0x600f, 0x0000, 0x080c, 0xaf74, 0x00ce, 0x0048, 0x00de,
-	0x00c6, 0x2660, 0x6003, 0x0009, 0x630a, 0x00ce, 0x0804, 0x957b,
-	0x89ff, 0x0138, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c,
-	0x6d17, 0x080c, 0xa761, 0x0804, 0x957b, 0x000e, 0x0804, 0x956f,
-	0x781e, 0x781a, 0x00de, 0x00ce, 0x00be, 0x009e, 0x006e, 0x000e,
-	0x0005, 0x00e6, 0x00d6, 0x0096, 0x0066, 0xb800, 0xd0dc, 0x01a0,
-	0xb84c, 0x904d, 0x0188, 0xa878, 0x9606, 0x1170, 0x2071, 0x19e6,
-	0x7024, 0x9035, 0x0148, 0x9080, 0x0005, 0x2004, 0x9906, 0x1120,
-	0xb800, 0xc0dc, 0xb802, 0x0029, 0x006e, 0x009e, 0x00de, 0x00ee,
-	0x0005, 0x00f6, 0x2079, 0x0100, 0x78c0, 0x9005, 0x1138, 0x00c6,
-	0x2660, 0x6003, 0x0009, 0x630a, 0x00ce, 0x04b8, 0x080c, 0xa356,
-	0x78c3, 0x0000, 0x080c, 0xa88b, 0x7027, 0x0000, 0x0036, 0x2079,
-	0x0140, 0x7b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c,
-	0x2d4e, 0x9006, 0x080c, 0x2d4e, 0x2079, 0x0100, 0x7824, 0xd084,
-	0x0110, 0x7827, 0x0001, 0x080c, 0xa88b, 0x003e, 0x080c, 0x65cb,
-	0x00c6, 0xb83c, 0x9005, 0x0110, 0x8001, 0xb83e, 0x2660, 0x080c,
-	0xaf43, 0x00ce, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c,
-	0xcf7c, 0x080c, 0x6d17, 0x080c, 0xa761, 0x00fe, 0x0005, 0x00b6,
-	0x00e6, 0x00c6, 0x2011, 0x0101, 0x2204, 0xc0c4, 0x2012, 0x2001,
-	0x180c, 0x2014, 0xc2e4, 0x2202, 0x2071, 0x19e6, 0x7004, 0x9084,
-	0x0007, 0x0002, 0x9674, 0x9678, 0x9696, 0x96bf, 0x96fd, 0x9674,
-	0x968f, 0x9672, 0x080c, 0x0dd5, 0x00ce, 0x00ee, 0x00be, 0x0005,
-	0x7024, 0x9065, 0x0148, 0x7020, 0x8001, 0x7022, 0x600c, 0x9015,
-	0x0158, 0x7216, 0x600f, 0x0000, 0x7007, 0x0000, 0x7027, 0x0000,
-	0x00ce, 0x00ee, 0x00be, 0x0005, 0x7216, 0x7212, 0x0ca8, 0x7007,
-	0x0000, 0x7027, 0x0000, 0x7020, 0x9005, 0x0070, 0x6010, 0x2058,
-	0x080c, 0x65cb, 0xb800, 0xc0dc, 0xb802, 0x7007, 0x0000, 0x7027,
-	0x0000, 0x7020, 0x8001, 0x7022, 0x1148, 0x2001, 0x180c, 0x2014,
-	0xd2ec, 0x1180, 0x00ce, 0x00ee, 0x00be, 0x0005, 0xb854, 0x9015,
-	0x0120, 0x721e, 0x080c, 0x9763, 0x0ca8, 0x7218, 0x721e, 0x080c,
-	0x9763, 0x0c80, 0xc2ec, 0x2202, 0x080c, 0x9891, 0x0c58, 0x7024,
-	0x9065, 0x05b8, 0x700c, 0x9c06, 0x1160, 0x080c, 0xa761, 0x600c,
-	0x9015, 0x0120, 0x720e, 0x600f, 0x0000, 0x0448, 0x720e, 0x720a,
-	0x0430, 0x7014, 0x9c06, 0x1160, 0x080c, 0xa761, 0x600c, 0x9015,
-	0x0120, 0x7216, 0x600f, 0x0000, 0x00d0, 0x7216, 0x7212, 0x00b8,
-	0x6020, 0x9086, 0x0003, 0x1198, 0x6010, 0x2058, 0x080c, 0x65cb,
-	0xb800, 0xc0dc, 0xb802, 0x080c, 0xa761, 0x701c, 0x9065, 0x0138,
-	0xb854, 0x9015, 0x0110, 0x721e, 0x0010, 0x7218, 0x721e, 0x7027,
-	0x0000, 0x00ce, 0x00ee, 0x00be, 0x0005, 0x7024, 0x9065, 0x0140,
-	0x080c, 0xa761, 0x600c, 0x9015, 0x0158, 0x720e, 0x600f, 0x0000,
-	0x080c, 0xa88b, 0x7027, 0x0000, 0x00ce, 0x00ee, 0x00be, 0x0005,
-	0x720e, 0x720a, 0x0ca8, 0x00d6, 0x2069, 0x19e6, 0x6830, 0x9084,
-	0x0003, 0x0002, 0x9720, 0x9722, 0x9746, 0x971e, 0x080c, 0x0dd5,
-	0x00de, 0x0005, 0x00c6, 0x6840, 0x9086, 0x0001, 0x01b8, 0x683c,
-	0x9065, 0x0130, 0x600c, 0x9015, 0x0170, 0x6a3a, 0x600f, 0x0000,
-	0x6833, 0x0000, 0x683f, 0x0000, 0x2011, 0x1a05, 0x2013, 0x0000,
-	0x00ce, 0x00de, 0x0005, 0x683a, 0x6836, 0x0c90, 0x6843, 0x0000,
-	0x6838, 0x9065, 0x0d68, 0x6003, 0x0003, 0x0c50, 0x00c6, 0x9006,
-	0x6842, 0x6846, 0x684a, 0x683c, 0x9065, 0x0160, 0x600c, 0x9015,
-	0x0130, 0x6a3a, 0x600f, 0x0000, 0x683f, 0x0000, 0x0018, 0x683e,
-	0x683a, 0x6836, 0x00ce, 0x00de, 0x0005, 0x2001, 0x180c, 0x200c,
-	0xc1e5, 0x2102, 0x0005, 0x2001, 0x180c, 0x200c, 0xd1ec, 0x0120,
-	0xc1ec, 0x2102, 0x080c, 0x9891, 0x2001, 0x19f2, 0x2004, 0x9086,
-	0x0001, 0x0d58, 0x00d6, 0x2069, 0x19e6, 0x6804, 0x9084, 0x0007,
-	0x0006, 0x9005, 0x11c8, 0x2001, 0x1837, 0x2004, 0x9084, 0x0028,
-	0x1198, 0x2001, 0x197b, 0x2004, 0x9086, 0xaaaa, 0x0168, 0x2001,
-	0x188b, 0x2004, 0xd08c, 0x1118, 0xd084, 0x1118, 0x0028, 0x080c,
-	0x9891, 0x000e, 0x00de, 0x0005, 0x000e, 0x0002, 0x97a0, 0x985f,
-	0x985f, 0x985f, 0x985f, 0x9861, 0x985f, 0x979e, 0x080c, 0x0dd5,
-	0x6820, 0x9005, 0x1110, 0x00de, 0x0005, 0x00c6, 0x680c, 0x9065,
-	0x0520, 0x6114, 0x0096, 0x2148, 0xa964, 0x009e, 0x918c, 0x00ff,
-	0x918e, 0x0035, 0x1180, 0x2009, 0x1837, 0x210c, 0x918c, 0x0028,
-	0x1150, 0x080c, 0x743e, 0x0138, 0x0006, 0x2009, 0x188b, 0x2104,
-	0xc095, 0x200a, 0x000e, 0x6807, 0x0004, 0x6826, 0x682b, 0x0000,
-	0x080c, 0x993a, 0x00ce, 0x00de, 0x0005, 0x6814, 0x9065, 0x0150,
-	0x6807, 0x0001, 0x6826, 0x682b, 0x0000, 0x080c, 0x993a, 0x00ce,
-	0x00de, 0x0005, 0x00b6, 0x00e6, 0x6a1c, 0x92dd, 0x0000, 0x0904,
-	0x9849, 0xb84c, 0x900d, 0x0118, 0xb888, 0x9005, 0x01a0, 0xb854,
-	0x905d, 0x0120, 0x920e, 0x0904, 0x9849, 0x0028, 0x6818, 0x920e,
-	0x0904, 0x9849, 0x2058, 0xb84c, 0x900d, 0x0d88, 0xb888, 0x9005,
-	0x1d70, 0x2b00, 0x681e, 0xbb3c, 0xb838, 0x9302, 0x1e40, 0x080c,
-	0xaf1a, 0x0904, 0x9849, 0x8318, 0xbb3e, 0x6116, 0x2b10, 0x6212,
-	0x0096, 0x2148, 0xa880, 0x9084, 0x00ff, 0x605e, 0xa883, 0x0000,
-	0xa884, 0x009e, 0x908a, 0x199a, 0x0210, 0x2001, 0x1999, 0x8003,
-	0x801b, 0x831b, 0x9318, 0x631a, 0x6114, 0x0096, 0x2148, 0xa964,
-	0x009e, 0x918c, 0x00ff, 0x918e, 0x0048, 0x0538, 0x00f6, 0x2c78,
-	0x2061, 0x0100, 0xbac0, 0x629a, 0x2069, 0x0200, 0x2071, 0x0240,
-	0x080c, 0x9e91, 0x2069, 0x19e6, 0xbb00, 0xc3dd, 0xbb02, 0x6807,
-	0x0002, 0x2f18, 0x6b26, 0x682b, 0x0000, 0x7823, 0x0003, 0x7803,
-	0x0001, 0x7807, 0x0040, 0x00fe, 0x00ee, 0x00be, 0x00ce, 0x00de,
-	0x0005, 0x00ee, 0x00be, 0x00ce, 0x0cd0, 0x6807, 0x0006, 0x2c18,
-	0x6b26, 0x6820, 0x8001, 0x6822, 0x682b, 0x0000, 0x080c, 0x65cb,
-	0x080c, 0xad5a, 0x00ee, 0x00be, 0x00ce, 0x00de, 0x0005, 0x00de,
-	0x0005, 0x00c6, 0x680c, 0x9065, 0x0508, 0x6114, 0x0096, 0x2148,
-	0xa964, 0x009e, 0x918c, 0x00ff, 0x918e, 0x0035, 0x1180, 0x2009,
-	0x1837, 0x210c, 0x918c, 0x0028, 0x1150, 0x080c, 0x743e, 0x0138,
+	0x00b6, 0x2058, 0x080c, 0x8f2b, 0x00be, 0x6013, 0x0000, 0x601b,
+	0x0000, 0x0010, 0x2c00, 0x0861, 0x0005, 0x2009, 0x1929, 0x210c,
+	0xd194, 0x0005, 0x0126, 0x2091, 0x8000, 0x00e6, 0x2071, 0x1925,
+	0x7110, 0xc194, 0xd19c, 0x1118, 0xc185, 0x7007, 0x0000, 0x7112,
+	0x2001, 0x003b, 0x080c, 0x1611, 0x00ee, 0x012e, 0x0005, 0x7814,
+	0xd0bc, 0x1108, 0x0005, 0x7810, 0xc0c5, 0x7812, 0x0cc0, 0x0096,
+	0x00d6, 0x9006, 0x7006, 0x700e, 0x701a, 0x701e, 0x7022, 0x7016,
+	0x702a, 0x7026, 0x702f, 0x0000, 0x080c, 0x8d76, 0x0170, 0x080c,
+	0x8dab, 0x0158, 0x2900, 0x7002, 0x700a, 0x701a, 0x7013, 0x0001,
+	0x701f, 0x000a, 0x00de, 0x009e, 0x0005, 0x900e, 0x0cd8, 0x00e6,
+	0x0096, 0x0086, 0x00d6, 0x00c6, 0x2071, 0x1932, 0x721c, 0x2100,
+	0x9202, 0x1618, 0x080c, 0x8dab, 0x090c, 0x0dc5, 0x7018, 0x9005,
+	0x1160, 0x2900, 0x7002, 0x700a, 0x701a, 0x9006, 0x7006, 0x700e,
+	0xa806, 0xa802, 0x7012, 0x701e, 0x0038, 0x2040, 0xa806, 0x2900,
+	0xa002, 0x701a, 0xa803, 0x0000, 0x7010, 0x8000, 0x7012, 0x701c,
+	0x9080, 0x000a, 0x701e, 0x721c, 0x08d0, 0x721c, 0x00ce, 0x00de,
+	0x008e, 0x009e, 0x00ee, 0x0005, 0x0096, 0x0156, 0x0136, 0x0146,
+	0x00e6, 0x0126, 0x2091, 0x8000, 0x2071, 0x1932, 0x7300, 0x831f,
+	0x831e, 0x831e, 0x9384, 0x003f, 0x20e8, 0x939c, 0xffc0, 0x9398,
+	0x0003, 0x7104, 0x080c, 0x8d28, 0x810c, 0x2100, 0x9318, 0x8003,
+	0x2228, 0x2021, 0x0078, 0x9402, 0x9532, 0x0208, 0x2028, 0x2500,
+	0x8004, 0x20a8, 0x23a0, 0xa001, 0xa001, 0x4005, 0x2508, 0x080c,
+	0x8d31, 0x2130, 0x7014, 0x9600, 0x7016, 0x2600, 0x711c, 0x9102,
+	0x701e, 0x7004, 0x9600, 0x2008, 0x9082, 0x000a, 0x1190, 0x7000,
+	0x2048, 0xa800, 0x9005, 0x1148, 0x2009, 0x0001, 0x0026, 0x080c,
+	0x8c1f, 0x002e, 0x7000, 0x2048, 0xa800, 0x7002, 0x7007, 0x0000,
+	0x0008, 0x7106, 0x2500, 0x9212, 0x1904, 0x8c5e, 0x012e, 0x00ee,
+	0x014e, 0x013e, 0x015e, 0x009e, 0x0005, 0x0016, 0x0026, 0x00e6,
+	0x0126, 0x2091, 0x8000, 0x9580, 0x8dee, 0x2005, 0x9075, 0x090c,
+	0x0dc5, 0x080c, 0x8d03, 0x012e, 0x9580, 0x8dea, 0x2005, 0x9075,
+	0x090c, 0x0dc5, 0x0156, 0x0136, 0x01c6, 0x0146, 0x01d6, 0x831f,
+	0x831e, 0x831e, 0x9384, 0x003f, 0x20e0, 0x9384, 0xffc0, 0x9100,
+	0x2098, 0xa860, 0x20e8, 0xa95c, 0x2c05, 0x9100, 0x20a0, 0x20a9,
+	0x0002, 0x4003, 0x2e0c, 0x2d00, 0x0002, 0x8ced, 0x8ced, 0x8cef,
+	0x8ced, 0x8cef, 0x8ced, 0x8ced, 0x8ced, 0x8ced, 0x8ced, 0x8cf5,
+	0x8ced, 0x8cf5, 0x8ced, 0x8ced, 0x8ced, 0x080c, 0x0dc5, 0x4104,
+	0x20a9, 0x0002, 0x4002, 0x4003, 0x0028, 0x20a9, 0x0002, 0x4003,
+	0x4104, 0x4003, 0x01de, 0x014e, 0x01ce, 0x013e, 0x015e, 0x00ee,
+	0x002e, 0x001e, 0x0005, 0x0096, 0x7014, 0x8001, 0x7016, 0x710c,
+	0x2110, 0x00f1, 0x810c, 0x9188, 0x0003, 0x7308, 0x8210, 0x9282,
+	0x000a, 0x1198, 0x7008, 0x2048, 0xa800, 0x9005, 0x0158, 0x0006,
+	0x080c, 0x8dba, 0x009e, 0xa807, 0x0000, 0x2900, 0x700a, 0x7010,
+	0x8001, 0x7012, 0x700f, 0x0000, 0x0008, 0x720e, 0x009e, 0x0005,
+	0x0006, 0x810b, 0x810b, 0x2100, 0x810b, 0x9100, 0x2008, 0x000e,
+	0x0005, 0x0006, 0x0026, 0x2100, 0x9005, 0x0158, 0x9092, 0x000c,
+	0x0240, 0x900e, 0x8108, 0x9082, 0x000c, 0x1de0, 0x002e, 0x000e,
+	0x0005, 0x900e, 0x0cd8, 0x2d00, 0x90b8, 0x0008, 0x2031, 0x8d74,
+	0x901e, 0x6808, 0x9005, 0x0108, 0x8318, 0x690c, 0x910a, 0x0248,
+	0x0140, 0x8318, 0x6810, 0x9112, 0x0220, 0x0118, 0x8318, 0x2208,
+	0x0cd0, 0x233a, 0x6804, 0xd084, 0x2300, 0x2021, 0x0001, 0x1150,
+	0x9082, 0x0003, 0x0967, 0x0a67, 0x8420, 0x9082, 0x0007, 0x0967,
+	0x0a67, 0x0cd0, 0x9082, 0x0002, 0x0967, 0x0a67, 0x8420, 0x9082,
+	0x0005, 0x0967, 0x0a67, 0x0cd0, 0x6c1a, 0x0005, 0x0096, 0x0046,
+	0x0126, 0x2091, 0x8000, 0x2b00, 0x9080, 0x8df2, 0x2005, 0x9005,
+	0x090c, 0x0dc5, 0x2004, 0x90a0, 0x000a, 0x080c, 0x1027, 0x01d0,
+	0x2900, 0x7026, 0xa803, 0x0000, 0xa807, 0x0000, 0x080c, 0x1027,
+	0x0188, 0x7024, 0xa802, 0xa807, 0x0000, 0x2900, 0x7026, 0x94a2,
+	0x000a, 0x0110, 0x0208, 0x0c90, 0x9085, 0x0001, 0x012e, 0x004e,
+	0x009e, 0x0005, 0x7024, 0x9005, 0x0dc8, 0x2048, 0xac00, 0x080c,
+	0x1040, 0x2400, 0x0cc0, 0x0126, 0x2091, 0x8000, 0x7024, 0x2048,
+	0x9005, 0x0130, 0xa800, 0x7026, 0xa803, 0x0000, 0xa807, 0x0000,
+	0x012e, 0x0005, 0x0126, 0x2091, 0x8000, 0x7024, 0xa802, 0x2900,
+	0x7026, 0x012e, 0x0005, 0x0096, 0x9e80, 0x0009, 0x2004, 0x9005,
+	0x0138, 0x2048, 0xa800, 0x0006, 0x080c, 0x1040, 0x000e, 0x0cb8,
+	0x009e, 0x0005, 0x0096, 0x7008, 0x9005, 0x0138, 0x2048, 0xa800,
+	0x0006, 0x080c, 0x1040, 0x000e, 0x0cb8, 0x9006, 0x7002, 0x700a,
+	0x7006, 0x700e, 0x701a, 0x701e, 0x7022, 0x702a, 0x7026, 0x702e,
+	0x009e, 0x0005, 0x1a68, 0x0000, 0x0000, 0x0000, 0x1932, 0x0000,
+	0x0000, 0x0000, 0x1888, 0x0000, 0x0000, 0x0000, 0x1877, 0x0000,
+	0x0000, 0x0000, 0x00e6, 0x00c6, 0x00b6, 0x00a6, 0xa8a8, 0x2040,
+	0x2071, 0x1877, 0x080c, 0x8f16, 0xa067, 0x0023, 0x6010, 0x905d,
+	0x0904, 0x8eeb, 0xb814, 0xa06e, 0xb910, 0xa172, 0xb9a0, 0xa176,
+	0x2001, 0x0003, 0xa07e, 0xa834, 0xa082, 0xa07b, 0x0000, 0xa898,
+	0x9005, 0x0118, 0xa078, 0xc085, 0xa07a, 0x2858, 0x2031, 0x0018,
+	0xa068, 0x908a, 0x0019, 0x1a0c, 0x0dc5, 0x2020, 0x2050, 0x2940,
+	0xa864, 0x90bc, 0x00ff, 0x908c, 0x000f, 0x91e0, 0x20e8, 0x2c65,
+	0x9786, 0x0024, 0x2c05, 0x1590, 0x908a, 0x0036, 0x1a0c, 0x0dc5,
+	0x9082, 0x001b, 0x0002, 0x8e56, 0x8e56, 0x8e58, 0x8e56, 0x8e56,
+	0x8e56, 0x8e5a, 0x8e56, 0x8e56, 0x8e56, 0x8e5c, 0x8e56, 0x8e56,
+	0x8e56, 0x8e5e, 0x8e56, 0x8e56, 0x8e56, 0x8e60, 0x8e56, 0x8e56,
+	0x8e56, 0x8e62, 0x8e56, 0x8e56, 0x8e56, 0x8e64, 0x080c, 0x0dc5,
+	0xa180, 0x04b8, 0xa190, 0x04a8, 0xa1a0, 0x0498, 0xa1b0, 0x0488,
+	0xa1c0, 0x0478, 0xa1d0, 0x0468, 0xa1e0, 0x0458, 0x908a, 0x0034,
+	0x1a0c, 0x0dc5, 0x9082, 0x001b, 0x0002, 0x8e88, 0x8e86, 0x8e86,
+	0x8e86, 0x8e86, 0x8e86, 0x8e8a, 0x8e86, 0x8e86, 0x8e86, 0x8e86,
+	0x8e86, 0x8e8c, 0x8e86, 0x8e86, 0x8e86, 0x8e86, 0x8e86, 0x8e8e,
+	0x8e86, 0x8e86, 0x8e86, 0x8e86, 0x8e86, 0x8e90, 0x080c, 0x0dc5,
+	0xa180, 0x0038, 0xa198, 0x0028, 0xa1b0, 0x0018, 0xa1c8, 0x0008,
+	0xa1e0, 0x2600, 0x0002, 0x8eac, 0x8eae, 0x8eb0, 0x8eb2, 0x8eb4,
+	0x8eb6, 0x8eb8, 0x8eba, 0x8ebc, 0x8ebe, 0x8ec0, 0x8ec2, 0x8ec4,
+	0x8ec6, 0x8ec8, 0x8eca, 0x8ecc, 0x8ece, 0x8ed0, 0x8ed2, 0x8ed4,
+	0x8ed6, 0x8ed8, 0x8eda, 0x8edc, 0x080c, 0x0dc5, 0xb9e2, 0x0468,
+	0xb9de, 0x0458, 0xb9da, 0x0448, 0xb9d6, 0x0438, 0xb9d2, 0x0428,
+	0xb9ce, 0x0418, 0xb9ca, 0x0408, 0xb9c6, 0x00f8, 0xb9c2, 0x00e8,
+	0xb9be, 0x00d8, 0xb9ba, 0x00c8, 0xb9b6, 0x00b8, 0xb9b2, 0x00a8,
+	0xb9ae, 0x0098, 0xb9aa, 0x0088, 0xb9a6, 0x0078, 0xb9a2, 0x0068,
+	0xb99e, 0x0058, 0xb99a, 0x0048, 0xb996, 0x0038, 0xb992, 0x0028,
+	0xb98e, 0x0018, 0xb98a, 0x0008, 0xb986, 0x8631, 0x8421, 0x0130,
+	0x080c, 0x20a0, 0x090c, 0x0dc5, 0x0804, 0x8e30, 0x00ae, 0x00be,
+	0x00ce, 0x00ee, 0x0005, 0xa86c, 0xa06e, 0xa870, 0xa072, 0xa077,
+	0x00ff, 0x9006, 0x0804, 0x8e12, 0x0006, 0x0016, 0x00b6, 0x6010,
+	0x2058, 0xb810, 0x9005, 0x01b0, 0x2001, 0x1926, 0x2004, 0x9005,
+	0x0188, 0x2001, 0x1800, 0x2004, 0x9086, 0x0003, 0x1158, 0x0036,
+	0x0046, 0xbba0, 0x2021, 0x0004, 0x2011, 0x8014, 0x080c, 0x4be3,
+	0x004e, 0x003e, 0x00be, 0x001e, 0x000e, 0x0005, 0x9016, 0x710c,
+	0xa834, 0x910a, 0xa936, 0x7008, 0x9005, 0x0120, 0x8210, 0x910a,
+	0x0238, 0x0130, 0x7010, 0x8210, 0x910a, 0x0210, 0x0108, 0x0cd8,
+	0xaa8a, 0xa26a, 0x0005, 0x00f6, 0x00d6, 0x0036, 0x2079, 0x0300,
+	0x781b, 0x0200, 0x7818, 0xd094, 0x1dd8, 0x781b, 0x0202, 0xa001,
+	0xa001, 0x7818, 0xd094, 0x1da0, 0xb8ac, 0x9005, 0x01b8, 0x2068,
+	0x2079, 0x0000, 0x2c08, 0x911e, 0x1118, 0x680c, 0xb8ae, 0x0060,
+	0x9106, 0x0140, 0x2d00, 0x2078, 0x680c, 0x9005, 0x090c, 0x0dc5,
+	0x2068, 0x0cb0, 0x6b0c, 0x7b0e, 0x600f, 0x0000, 0x2079, 0x0300,
+	0x781b, 0x0200, 0x003e, 0x00de, 0x00fe, 0x0005, 0x00e6, 0x00d6,
+	0x0096, 0x00c6, 0x0036, 0x0126, 0x2091, 0x8000, 0x0156, 0x20a9,
+	0x01ff, 0x2071, 0x0300, 0x701b, 0x0200, 0x7018, 0xd094, 0x0110,
+	0x1f04, 0x8f6b, 0x701b, 0x0202, 0xa001, 0xa001, 0x7018, 0xd094,
+	0x1d90, 0xb8ac, 0x9005, 0x01e8, 0x2060, 0x600c, 0xb8ae, 0x6024,
+	0xc08d, 0x6026, 0x6003, 0x0004, 0x601b, 0x0000, 0x6013, 0x0000,
+	0x601f, 0x0101, 0x6014, 0x2048, 0xa88b, 0x0000, 0xa8a8, 0xa8ab,
+	0x0000, 0x904d, 0x090c, 0x0dc5, 0x080c, 0x1040, 0x080c, 0x8b27,
+	0x0c00, 0x2071, 0x0300, 0x701b, 0x0200, 0x015e, 0x012e, 0x003e,
+	0x00ce, 0x009e, 0x00de, 0x00ee, 0x0005, 0x00c6, 0x00b6, 0x0016,
+	0x0006, 0x0156, 0x080c, 0x2889, 0x015e, 0x11b0, 0x080c, 0x66ac,
+	0x190c, 0x0dc5, 0x000e, 0x001e, 0xb912, 0xb816, 0x080c, 0xb091,
+	0x0140, 0x2b00, 0x6012, 0x6023, 0x0001, 0x2009, 0x0001, 0x080c,
+	0xb166, 0x00be, 0x00ce, 0x0005, 0x000e, 0x001e, 0x0cd0, 0x0066,
+	0x6000, 0x90b2, 0x0016, 0x1a0c, 0x0dc5, 0x0013, 0x006e, 0x0005,
+	0x8fe0, 0x8fe0, 0x8fe0, 0x8fe2, 0x9033, 0x8fe0, 0x8fe0, 0x8fe0,
+	0x909a, 0x8fe0, 0x90d7, 0x8fe0, 0x8fe0, 0x8fe0, 0x8fe0, 0x8fe0,
+	0x080c, 0x0dc5, 0x9182, 0x0040, 0x0002, 0x8ff5, 0x8ff5, 0x8ff5,
+	0x8ff5, 0x8ff5, 0x8ff5, 0x8ff5, 0x8ff5, 0x8ff5, 0x8ff7, 0x900c,
+	0x8ff5, 0x8ff5, 0x8ff5, 0x8ff5, 0x901f, 0x080c, 0x0dc5, 0x0096,
+	0x080c, 0x9897, 0x080c, 0x9a09, 0x6114, 0x2148, 0xa87b, 0x0000,
+	0x6010, 0x00b6, 0x2058, 0xb8bb, 0x0500, 0x00be, 0x080c, 0x6bcf,
+	0x080c, 0xb0e7, 0x009e, 0x0005, 0x080c, 0x9897, 0x00d6, 0x6114,
+	0x080c, 0xce3f, 0x0130, 0x0096, 0x6114, 0x2148, 0x080c, 0x6dcb,
+	0x009e, 0x00de, 0x080c, 0xb0e7, 0x080c, 0x9a09, 0x0005, 0x080c,
+	0x9897, 0x080c, 0x324b, 0x6114, 0x0096, 0x2148, 0x080c, 0xce3f,
+	0x0120, 0xa87b, 0x0029, 0x080c, 0x6dcb, 0x009e, 0x080c, 0xb0e7,
+	0x080c, 0x9a09, 0x0005, 0x601b, 0x0000, 0x9182, 0x0040, 0x0096,
+	0x0002, 0x904e, 0x904e, 0x904e, 0x904e, 0x904e, 0x904e, 0x904e,
+	0x904e, 0x9050, 0x904e, 0x904e, 0x904e, 0x9096, 0x904e, 0x904e,
+	0x904e, 0x904e, 0x904e, 0x904e, 0x9057, 0x904e, 0x080c, 0x0dc5,
+	0x6114, 0x2148, 0xa938, 0x918e, 0xffff, 0x0904, 0x9096, 0x6024,
+	0xd08c, 0x15c0, 0x00e6, 0x6114, 0x2148, 0x080c, 0x8dfa, 0x0096,
+	0xa8a8, 0x2048, 0x080c, 0x6b67, 0x009e, 0xa8ab, 0x0000, 0x6010,
+	0x9005, 0x0128, 0x00b6, 0x2058, 0x080c, 0x8f2b, 0x00be, 0xae88,
+	0x00b6, 0x2059, 0x0000, 0x080c, 0x8b30, 0x00be, 0x01e0, 0x2071,
+	0x193e, 0x080c, 0x8b77, 0x01b8, 0x9086, 0x0001, 0x1128, 0x2001,
+	0x1948, 0x2004, 0x9005, 0x1178, 0x0096, 0x080c, 0x100e, 0x2900,
+	0x009e, 0x0148, 0xa8aa, 0x00f6, 0x2c78, 0x080c, 0x8aee, 0x00fe,
+	0x00ee, 0x009e, 0x0005, 0x080c, 0x8b27, 0x0cd0, 0x080c, 0x9144,
+	0x009e, 0x0005, 0x9182, 0x0040, 0x0096, 0x0002, 0x90ae, 0x90ae,
+	0x90ae, 0x90b0, 0x90ae, 0x90ae, 0x90ae, 0x90d5, 0x90ae, 0x90ae,
+	0x90ae, 0x90ae, 0x90ae, 0x90ae, 0x90ae, 0x90ae, 0x080c, 0x0dc5,
+	0x6003, 0x0003, 0x6106, 0x6014, 0x2048, 0xa8ac, 0xa846, 0xa8b0,
+	0xa84a, 0xa837, 0x0000, 0xa83b, 0x0000, 0xa884, 0x9092, 0x199a,
+	0x0210, 0x2001, 0x1999, 0x8003, 0x8013, 0x8213, 0x9210, 0x621a,
+	0x2c10, 0x080c, 0x1c01, 0x080c, 0x939a, 0x0126, 0x2091, 0x8000,
+	0x080c, 0x9a09, 0x012e, 0x009e, 0x0005, 0x080c, 0x0dc5, 0x080c,
+	0x9897, 0x080c, 0x9a09, 0x6114, 0x2148, 0xa87b, 0x0000, 0x6010,
+	0x00b6, 0x2058, 0xb8bb, 0x0500, 0x00be, 0x080c, 0x6dcb, 0x080c,
+	0xb0e7, 0x009e, 0x0005, 0x6000, 0x908a, 0x0016, 0x1a0c, 0x0dc5,
+	0x0096, 0x0013, 0x009e, 0x0005, 0x9104, 0x9104, 0x9104, 0x9106,
+	0x9117, 0x9104, 0x9104, 0x9104, 0x9104, 0x9104, 0x9104, 0x9104,
+	0x9104, 0x9104, 0x9104, 0x9104, 0x080c, 0x0dc5, 0x080c, 0xaa3f,
+	0x6114, 0x2148, 0xa87b, 0x0006, 0x6010, 0x00b6, 0x2058, 0xb8bb,
+	0x0500, 0x00be, 0x080c, 0x6dcb, 0x080c, 0xb0e7, 0x0005, 0x0461,
+	0x0005, 0x6000, 0x908a, 0x0016, 0x1a0c, 0x0dc5, 0x0096, 0x0013,
+	0x009e, 0x0005, 0x9132, 0x9132, 0x9132, 0x9134, 0x9144, 0x9132,
+	0x9132, 0x9132, 0x9132, 0x9132, 0x9132, 0x9132, 0x9132, 0x9132,
+	0x9132, 0x9132, 0x080c, 0x0dc5, 0x0036, 0x00e6, 0x2071, 0x19e9,
+	0x703c, 0x9c06, 0x1120, 0x2019, 0x0000, 0x080c, 0xa85d, 0x080c,
+	0xaa3f, 0x00ee, 0x003e, 0x0005, 0x6024, 0xd08c, 0x11f0, 0x00f6,
+	0x00e6, 0x601b, 0x0000, 0x6014, 0x2048, 0x6010, 0x9005, 0x0128,
+	0x00b6, 0x2058, 0x080c, 0x8f2b, 0x00be, 0x2071, 0x193e, 0x080c,
+	0x8b77, 0x0160, 0x2001, 0x187f, 0x2004, 0xa88a, 0x2031, 0x0000,
+	0x2c78, 0x080c, 0x8aee, 0x00ee, 0x00fe, 0x0005, 0x0096, 0xa88b,
+	0x0000, 0xa8a8, 0x2048, 0x080c, 0x1040, 0x009e, 0xa8ab, 0x0000,
+	0x080c, 0x8b27, 0x0c80, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x187a, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0126, 0x2091, 0x8000, 0x0036, 0x0046,
+	0x20a9, 0x0010, 0x9006, 0x8004, 0x2019, 0x0100, 0x231c, 0x93a6,
+	0x0008, 0x1118, 0x8086, 0x818e, 0x0020, 0x80f6, 0x3e00, 0x81f6,
+	0x3e08, 0x1208, 0x9200, 0x1f04, 0x918c, 0x93a6, 0x0008, 0x1118,
+	0x8086, 0x818e, 0x0020, 0x80f6, 0x3e00, 0x81f6, 0x3e08, 0x004e,
+	0x003e, 0x012e, 0x0005, 0x0126, 0x2091, 0x8000, 0x0076, 0x0156,
+	0x20a9, 0x0010, 0x9005, 0x0510, 0x911a, 0x1600, 0x8213, 0x2039,
+	0x0100, 0x273c, 0x97be, 0x0008, 0x1110, 0x818d, 0x0010, 0x81f5,
+	0x3e08, 0x0228, 0x911a, 0x1220, 0x1f04, 0x91b6, 0x0028, 0x911a,
+	0x2308, 0x8210, 0x1f04, 0x91b6, 0x0006, 0x3200, 0x9084, 0xefff,
+	0x2080, 0x000e, 0x015e, 0x007e, 0x012e, 0x0005, 0x0006, 0x3200,
+	0x9085, 0x1000, 0x0ca8, 0x0126, 0x2091, 0x2800, 0x2079, 0x19e9,
+	0x012e, 0x00d6, 0x2069, 0x19e9, 0x6803, 0x0005, 0x0156, 0x0146,
+	0x01d6, 0x20e9, 0x0000, 0x2069, 0x0200, 0x080c, 0xada2, 0x0401,
+	0x080c, 0xad8d, 0x00e9, 0x080c, 0xad90, 0x00d1, 0x080c, 0xad93,
+	0x00b9, 0x080c, 0xad96, 0x00a1, 0x080c, 0xad99, 0x0089, 0x080c,
+	0xad9c, 0x0071, 0x080c, 0xad9f, 0x0059, 0x01de, 0x014e, 0x015e,
+	0x2069, 0x0004, 0x2d04, 0x9085, 0x8001, 0x206a, 0x00de, 0x0005,
+	0x20a9, 0x0020, 0x20a1, 0x0240, 0x2001, 0x0000, 0x4004, 0x0005,
+	0x00c6, 0x6027, 0x0001, 0x7804, 0x9084, 0x0007, 0x0002, 0x9229,
+	0x924d, 0x928e, 0x922f, 0x924d, 0x9229, 0x9227, 0x9227, 0x080c,
+	0x0dc5, 0x080c, 0x8789, 0x080c, 0x98e7, 0x00ce, 0x0005, 0x62c0,
+	0x82ff, 0x1110, 0x00ce, 0x0005, 0x2011, 0x5f8a, 0x080c, 0x8703,
+	0x7828, 0x9092, 0x00c8, 0x1228, 0x8000, 0x782a, 0x080c, 0x5fca,
+	0x0c88, 0x62c0, 0x080c, 0xaede, 0x080c, 0x5f8a, 0x7807, 0x0003,
+	0x7827, 0x0000, 0x782b, 0x0000, 0x0c28, 0x080c, 0x8789, 0x6220,
+	0xd2a4, 0x0170, 0xd2cc, 0x0160, 0x782b, 0x0000, 0x7824, 0x9065,
+	0x090c, 0x0dc5, 0x2009, 0x0013, 0x080c, 0xb166, 0x00ce, 0x0005,
+	0x00c6, 0x7824, 0x9065, 0x090c, 0x0dc5, 0x7828, 0x9092, 0xc350,
+	0x12c0, 0x8000, 0x782a, 0x00ce, 0x080c, 0x2bf0, 0x0278, 0x00c6,
+	0x7924, 0x2160, 0x6010, 0x906d, 0x090c, 0x0dc5, 0x7807, 0x0000,
+	0x7827, 0x0000, 0x00ce, 0x080c, 0x98e7, 0x0c00, 0x080c, 0xa4d9,
+	0x08e8, 0x2011, 0x0130, 0x2214, 0x080c, 0xaede, 0x080c, 0xedaa,
+	0x2009, 0x0014, 0x080c, 0xb166, 0x00ce, 0x0880, 0x2001, 0x1a05,
+	0x2003, 0x0000, 0x62c0, 0x82ff, 0x1160, 0x782b, 0x0000, 0x7824,
+	0x9065, 0x090c, 0x0dc5, 0x2009, 0x0013, 0x080c, 0xb1b8, 0x00ce,
+	0x0005, 0x00b6, 0x00c6, 0x00d6, 0x7824, 0x9005, 0x090c, 0x0dc5,
+	0x7828, 0x9092, 0xc350, 0x1648, 0x8000, 0x782a, 0x00de, 0x00ce,
+	0x00be, 0x080c, 0x2bf0, 0x02f0, 0x00b6, 0x00c6, 0x00d6, 0x781c,
+	0x905d, 0x090c, 0x0dc5, 0xb800, 0xc0dc, 0xb802, 0x7924, 0x2160,
+	0x080c, 0xb0e7, 0xb93c, 0x81ff, 0x090c, 0x0dc5, 0x8109, 0xb93e,
+	0x7807, 0x0000, 0x7827, 0x0000, 0x00de, 0x00ce, 0x00be, 0x080c,
+	0x98e7, 0x0868, 0x080c, 0xa4d9, 0x0850, 0x2011, 0x0130, 0x2214,
+	0x080c, 0xaede, 0x080c, 0xedaa, 0x7824, 0x9065, 0x2009, 0x0014,
+	0x080c, 0xb166, 0x00de, 0x00ce, 0x00be, 0x0804, 0x929f, 0x00c6,
+	0x2001, 0x009b, 0x2004, 0xd0fc, 0x190c, 0x1f0c, 0x6024, 0x6027,
+	0x0002, 0xd0f4, 0x15b8, 0x62c8, 0x60c4, 0x9205, 0x1170, 0x783c,
+	0x9065, 0x0130, 0x2009, 0x0049, 0x080c, 0xb166, 0x00ce, 0x0005,
+	0x2011, 0x1a08, 0x2013, 0x0000, 0x0cc8, 0x793c, 0x81ff, 0x0dc0,
+	0x7944, 0x9192, 0x7530, 0x1628, 0x8108, 0x7946, 0x793c, 0x9188,
+	0x0008, 0x210c, 0x918e, 0x0006, 0x1138, 0x6014, 0x9084, 0x1984,
+	0x9085, 0x0012, 0x6016, 0x0c10, 0x793c, 0x9188, 0x0008, 0x210c,
+	0x918e, 0x0009, 0x0d90, 0x6014, 0x9084, 0x1984, 0x9085, 0x0016,
+	0x6016, 0x08a0, 0x793c, 0x2160, 0x2009, 0x004a, 0x080c, 0xb166,
+	0x0868, 0x7848, 0xc085, 0x784a, 0x0848, 0x0006, 0x0016, 0x00c6,
+	0x0126, 0x2091, 0x8000, 0x600f, 0x0000, 0x2c08, 0x2061, 0x19e9,
+	0x6020, 0x8000, 0x6022, 0x6010, 0x9005, 0x0148, 0x9080, 0x0003,
+	0x2102, 0x6112, 0x012e, 0x00ce, 0x001e, 0x000e, 0x0005, 0x6116,
+	0x6112, 0x0cc0, 0x00d6, 0x2069, 0x19e9, 0xb800, 0xd0d4, 0x0168,
+	0x6820, 0x8000, 0x6822, 0x9086, 0x0001, 0x1110, 0x2b00, 0x681e,
+	0x00de, 0x0804, 0x98e7, 0x00de, 0x0005, 0xc0d5, 0xb802, 0x6818,
+	0x9005, 0x0168, 0xb856, 0xb85b, 0x0000, 0x0086, 0x0006, 0x2b00,
+	0x681a, 0x008e, 0xa05a, 0x008e, 0x2069, 0x19e9, 0x0c08, 0xb856,
+	0xb85a, 0x2b00, 0x681a, 0x681e, 0x08d8, 0x0006, 0x0016, 0x00c6,
+	0x0126, 0x2091, 0x8000, 0x600f, 0x0000, 0x2c08, 0x2061, 0x19e9,
+	0x6020, 0x8000, 0x6022, 0x6008, 0x9005, 0x0148, 0x9080, 0x0003,
+	0x2102, 0x610a, 0x012e, 0x00ce, 0x001e, 0x000e, 0x0005, 0x610e,
+	0x610a, 0x0cc0, 0x00c6, 0x600f, 0x0000, 0x2c08, 0x2061, 0x19e9,
+	0x6034, 0x9005, 0x0130, 0x9080, 0x0003, 0x2102, 0x6136, 0x00ce,
+	0x0005, 0x613a, 0x6136, 0x00ce, 0x0005, 0x00f6, 0x00e6, 0x00d6,
+	0x00c6, 0x00b6, 0x0096, 0x0076, 0x0066, 0x0056, 0x0036, 0x0026,
+	0x0016, 0x0006, 0x0126, 0x902e, 0x2071, 0x19e9, 0x7638, 0x2660,
+	0x2678, 0x2091, 0x8000, 0x8cff, 0x0904, 0x9429, 0x6010, 0x2058,
+	0xb8a0, 0x9206, 0x1904, 0x9424, 0x87ff, 0x0120, 0x6054, 0x9106,
+	0x1904, 0x9424, 0x703c, 0x9c06, 0x1178, 0x0036, 0x2019, 0x0001,
+	0x080c, 0xa85d, 0x7033, 0x0000, 0x9006, 0x703e, 0x7042, 0x7046,
+	0x704a, 0x003e, 0x2029, 0x0001, 0x7038, 0x9c36, 0x1110, 0x660c,
+	0x763a, 0x7034, 0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00,
+	0x7036, 0x0010, 0x7037, 0x0000, 0x660c, 0x0066, 0x2c00, 0x9f06,
+	0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0x080c, 0xce3f,
+	0x01f0, 0x6014, 0x2048, 0x6020, 0x9086, 0x0003, 0x15b8, 0x6004,
+	0x9086, 0x0040, 0x090c, 0xaa2f, 0xa867, 0x0103, 0xab7a, 0xa877,
+	0x0000, 0x0016, 0x0036, 0x0076, 0x080c, 0xd135, 0x080c, 0xec9b,
+	0x080c, 0x6dcb, 0x007e, 0x003e, 0x001e, 0x080c, 0xd02a, 0x080c,
+	0xb11a, 0x00ce, 0x0804, 0x93c3, 0x2c78, 0x600c, 0x2060, 0x0804,
+	0x93c3, 0x85ff, 0x0120, 0x0036, 0x080c, 0x9a09, 0x003e, 0x012e,
+	0x000e, 0x001e, 0x002e, 0x003e, 0x005e, 0x006e, 0x007e, 0x009e,
+	0x00be, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x6020, 0x9086,
+	0x0006, 0x1158, 0x0016, 0x0036, 0x0076, 0x080c, 0xec9b, 0x080c,
+	0xe8e3, 0x007e, 0x003e, 0x001e, 0x0890, 0x6020, 0x9086, 0x0009,
+	0x1168, 0xa87b, 0x0006, 0x0016, 0x0036, 0x0076, 0x080c, 0x6dcb,
+	0x080c, 0xb0e7, 0x007e, 0x003e, 0x001e, 0x0818, 0x6020, 0x9086,
+	0x000a, 0x0904, 0x940e, 0x0804, 0x9407, 0x0006, 0x0066, 0x0096,
+	0x00c6, 0x00d6, 0x00f6, 0x9036, 0x0126, 0x2091, 0x8000, 0x2079,
+	0x19e9, 0x7838, 0x9065, 0x0904, 0x94ba, 0x600c, 0x0006, 0x600f,
+	0x0000, 0x783c, 0x9c06, 0x1168, 0x0036, 0x2019, 0x0001, 0x080c,
+	0xa85d, 0x7833, 0x0000, 0x901e, 0x7b3e, 0x7b42, 0x7b46, 0x7b4a,
+	0x003e, 0x080c, 0xce3f, 0x0548, 0x6014, 0x2048, 0x6020, 0x9086,
+	0x0003, 0x1590, 0x3e08, 0x918e, 0x0002, 0x1188, 0x6010, 0x9005,
+	0x0170, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x0140, 0x6040,
+	0x9005, 0x11a8, 0x2001, 0x1989, 0x2004, 0x6042, 0x0080, 0x6004,
+	0x9086, 0x0040, 0x090c, 0xaa2f, 0xa867, 0x0103, 0xab7a, 0xa877,
+	0x0000, 0x080c, 0x6dbe, 0x080c, 0xd02a, 0x080c, 0xb11a, 0x000e,
+	0x0804, 0x9472, 0x7e3a, 0x7e36, 0x012e, 0x00fe, 0x00de, 0x00ce,
+	0x009e, 0x006e, 0x000e, 0x0005, 0x6020, 0x9086, 0x0006, 0x1118,
+	0x080c, 0xe8e3, 0x0c50, 0x6020, 0x9086, 0x0009, 0x1130, 0xab7a,
+	0x080c, 0x6dcb, 0x080c, 0xb0e7, 0x0c10, 0x6020, 0x9086, 0x000a,
+	0x09a8, 0x0868, 0x0016, 0x0026, 0x0086, 0x9046, 0x0099, 0x080c,
+	0x95c5, 0x008e, 0x002e, 0x001e, 0x0005, 0x00f6, 0x0126, 0x2079,
+	0x19e9, 0x2091, 0x8000, 0x080c, 0x965c, 0x080c, 0x96ec, 0x012e,
+	0x00fe, 0x0005, 0x00b6, 0x0096, 0x00f6, 0x00e6, 0x00d6, 0x00c6,
+	0x0066, 0x0016, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x19e9,
+	0x7614, 0x2660, 0x2678, 0x8cff, 0x0904, 0x958a, 0x6010, 0x2058,
+	0xb8a0, 0x9206, 0x1904, 0x9585, 0x88ff, 0x0120, 0x6054, 0x9106,
+	0x1904, 0x9585, 0x7024, 0x9c06, 0x1568, 0x2069, 0x0100, 0x6820,
+	0xd0a4, 0x0110, 0xd0cc, 0x1508, 0x080c, 0x8789, 0x080c, 0xa4fd,
+	0x68c3, 0x0000, 0x080c, 0xaa2f, 0x7027, 0x0000, 0x0036, 0x2069,
+	0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c,
+	0x2d5b, 0x9006, 0x080c, 0x2d5b, 0x2069, 0x0100, 0x6824, 0xd084,
+	0x0110, 0x6827, 0x0001, 0x003e, 0x0028, 0x6003, 0x0009, 0x630a,
+	0x0804, 0x9585, 0x7014, 0x9c36, 0x1110, 0x660c, 0x7616, 0x7010,
+	0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x7012, 0x0010,
+	0x7013, 0x0000, 0x660c, 0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e,
+	0x0008, 0x2678, 0x600f, 0x0000, 0x6014, 0x2048, 0x080c, 0xce3f,
+	0x01e8, 0x6020, 0x9086, 0x0003, 0x1580, 0x080c, 0xd047, 0x1118,
+	0x080c, 0xbacb, 0x0098, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000,
+	0x0016, 0x0036, 0x0086, 0x080c, 0xd135, 0x080c, 0xec9b, 0x080c,
+	0x6dcb, 0x008e, 0x003e, 0x001e, 0x080c, 0xd02a, 0x080c, 0xb11a,
+	0x080c, 0xa905, 0x00ce, 0x0804, 0x9503, 0x2c78, 0x600c, 0x2060,
+	0x0804, 0x9503, 0x012e, 0x000e, 0x001e, 0x006e, 0x00ce, 0x00de,
+	0x00ee, 0x00fe, 0x009e, 0x00be, 0x0005, 0x6020, 0x9086, 0x0006,
+	0x1158, 0x0016, 0x0036, 0x0086, 0x080c, 0xec9b, 0x080c, 0xe8e3,
+	0x008e, 0x003e, 0x001e, 0x08d0, 0x080c, 0xbacb, 0x6020, 0x9086,
+	0x0002, 0x1160, 0x6004, 0x0006, 0x9086, 0x0085, 0x000e, 0x0904,
+	0x956b, 0x9086, 0x008b, 0x0904, 0x956b, 0x0840, 0x6020, 0x9086,
+	0x0005, 0x1920, 0x6004, 0x0006, 0x9086, 0x0085, 0x000e, 0x09c8,
+	0x9086, 0x008b, 0x09b0, 0x0804, 0x957e, 0x00b6, 0x00a6, 0x0096,
+	0x00c6, 0x0006, 0x0126, 0x2091, 0x8000, 0x9280, 0x1000, 0x2004,
+	0x905d, 0x0904, 0x9655, 0x00f6, 0x00e6, 0x00d6, 0x0066, 0x2071,
+	0x19e9, 0xbe54, 0x7018, 0x9b06, 0x1108, 0x761a, 0x701c, 0x9b06,
+	0x1130, 0x86ff, 0x1118, 0x7018, 0x701e, 0x0008, 0x761e, 0xb858,
+	0x904d, 0x0108, 0xae56, 0x96d5, 0x0000, 0x0110, 0x2900, 0xb05a,
+	0xb857, 0x0000, 0xb85b, 0x0000, 0xb800, 0xc0d4, 0xc0dc, 0xb802,
+	0x080c, 0x663f, 0x0904, 0x9651, 0x7624, 0x86ff, 0x0904, 0x9640,
+	0x9680, 0x0005, 0x2004, 0x9906, 0x15d8, 0x00d6, 0x2069, 0x0100,
+	0x68c0, 0x9005, 0x0560, 0x080c, 0x8789, 0x080c, 0xa4fd, 0x68c3,
+	0x0000, 0x080c, 0xaa2f, 0x7027, 0x0000, 0x0036, 0x2069, 0x0140,
+	0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2d5b,
+	0x9006, 0x080c, 0x2d5b, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110,
+	0x6827, 0x0001, 0x003e, 0x00de, 0x00c6, 0xb83c, 0x9005, 0x0110,
+	0x8001, 0xb83e, 0x2660, 0x080c, 0xb11a, 0x00ce, 0x0048, 0x00de,
+	0x00c6, 0x2660, 0x6003, 0x0009, 0x630a, 0x00ce, 0x0804, 0x95f8,
+	0x89ff, 0x0158, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c,
+	0xd135, 0x080c, 0xec9b, 0x080c, 0x6dcb, 0x080c, 0xa905, 0x0804,
+	0x95f8, 0x006e, 0x00de, 0x00ee, 0x00fe, 0x012e, 0x000e, 0x00ce,
+	0x009e, 0x00ae, 0x00be, 0x0005, 0x0096, 0x0006, 0x0066, 0x00c6,
+	0x00d6, 0x9036, 0x7814, 0x9065, 0x0904, 0x96bf, 0x600c, 0x0006,
+	0x600f, 0x0000, 0x7824, 0x9c06, 0x1580, 0x2069, 0x0100, 0x6820,
+	0xd0a4, 0x0110, 0xd0cc, 0x1508, 0x080c, 0x8789, 0x080c, 0xa4fd,
+	0x68c3, 0x0000, 0x080c, 0xaa2f, 0x7827, 0x0000, 0x0036, 0x2069,
+	0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c,
+	0x2d5b, 0x9006, 0x080c, 0x2d5b, 0x2069, 0x0100, 0x6824, 0xd084,
+	0x0110, 0x6827, 0x0001, 0x003e, 0x0040, 0x080c, 0x6a24, 0x1520,
+	0x6003, 0x0009, 0x630a, 0x2c30, 0x00f8, 0x6014, 0x2048, 0x080c,
+	0xce3d, 0x01b0, 0x6020, 0x9086, 0x0003, 0x1508, 0x080c, 0xd047,
+	0x1118, 0x080c, 0xbacb, 0x0060, 0x080c, 0x6a24, 0x1168, 0xa867,
+	0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0x6dcb, 0x080c, 0xd02a,
+	0x080c, 0xb11a, 0x080c, 0xa905, 0x000e, 0x0804, 0x9663, 0x7e16,
+	0x7e12, 0x00de, 0x00ce, 0x006e, 0x000e, 0x009e, 0x0005, 0x6020,
+	0x9086, 0x0006, 0x1118, 0x080c, 0xe8e3, 0x0c50, 0x080c, 0xbacb,
+	0x6020, 0x9086, 0x0002, 0x1150, 0x6004, 0x0006, 0x9086, 0x0085,
+	0x000e, 0x0990, 0x9086, 0x008b, 0x0978, 0x08d0, 0x6020, 0x9086,
+	0x0005, 0x19b0, 0x6004, 0x0006, 0x9086, 0x0085, 0x000e, 0x0d18,
+	0x9086, 0x008b, 0x0d00, 0x0860, 0x0006, 0x0066, 0x0096, 0x00b6,
+	0x00c6, 0x00d6, 0x7818, 0x905d, 0x0904, 0x976c, 0xb854, 0x0006,
+	0x9006, 0xb856, 0xb85a, 0xb800, 0xc0d4, 0xc0dc, 0xb802, 0x080c,
+	0x663f, 0x0904, 0x9769, 0x7e24, 0x86ff, 0x0904, 0x975c, 0x9680,
+	0x0005, 0x2004, 0x9906, 0x1904, 0x975c, 0x00d6, 0x2069, 0x0100,
+	0x68c0, 0x9005, 0x0904, 0x9753, 0x080c, 0x8789, 0x080c, 0xa4fd,
+	0x68c3, 0x0000, 0x080c, 0xaa2f, 0x7827, 0x0000, 0x0036, 0x2069,
+	0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c,
+	0x2d5b, 0x9006, 0x080c, 0x2d5b, 0x2069, 0x0100, 0x6824, 0xd084,
+	0x0110, 0x6827, 0x0001, 0x003e, 0x00de, 0x00c6, 0x3e08, 0x918e,
+	0x0002, 0x1168, 0xb800, 0xd0bc, 0x0150, 0x9680, 0x0010, 0x200c,
+	0x81ff, 0x1518, 0x2009, 0x1989, 0x210c, 0x2102, 0x00f0, 0xb83c,
+	0x9005, 0x0110, 0x8001, 0xb83e, 0x2660, 0x600f, 0x0000, 0x080c,
+	0xb11a, 0x00ce, 0x0048, 0x00de, 0x00c6, 0x2660, 0x6003, 0x0009,
+	0x630a, 0x00ce, 0x0804, 0x96ff, 0x89ff, 0x0138, 0xa867, 0x0103,
+	0xab7a, 0xa877, 0x0000, 0x080c, 0x6dcb, 0x080c, 0xa905, 0x0804,
+	0x96ff, 0x000e, 0x0804, 0x96f3, 0x781e, 0x781a, 0x00de, 0x00ce,
+	0x00be, 0x009e, 0x006e, 0x000e, 0x0005, 0x00e6, 0x00d6, 0x0096,
+	0x0066, 0xb800, 0xd0dc, 0x01a0, 0xb84c, 0x904d, 0x0188, 0xa878,
+	0x9606, 0x1170, 0x2071, 0x19e9, 0x7024, 0x9035, 0x0148, 0x9080,
+	0x0005, 0x2004, 0x9906, 0x1120, 0xb800, 0xc0dc, 0xb802, 0x0029,
+	0x006e, 0x009e, 0x00de, 0x00ee, 0x0005, 0x00f6, 0x2079, 0x0100,
+	0x78c0, 0x9005, 0x1138, 0x00c6, 0x2660, 0x6003, 0x0009, 0x630a,
+	0x00ce, 0x04b8, 0x080c, 0xa4fd, 0x78c3, 0x0000, 0x080c, 0xaa2f,
+	0x7027, 0x0000, 0x0036, 0x2079, 0x0140, 0x7b04, 0x9384, 0x1000,
+	0x0138, 0x2001, 0x0100, 0x080c, 0x2d5b, 0x9006, 0x080c, 0x2d5b,
+	0x2079, 0x0100, 0x7824, 0xd084, 0x0110, 0x7827, 0x0001, 0x080c,
+	0xaa2f, 0x003e, 0x080c, 0x663f, 0x00c6, 0xb83c, 0x9005, 0x0110,
+	0x8001, 0xb83e, 0x2660, 0x080c, 0xb0e7, 0x00ce, 0xa867, 0x0103,
+	0xab7a, 0xa877, 0x0000, 0x080c, 0xd135, 0x080c, 0x6dcb, 0x080c,
+	0xa905, 0x00fe, 0x0005, 0x00b6, 0x00e6, 0x00c6, 0x2011, 0x0101,
+	0x2204, 0xc0c4, 0x2012, 0x2001, 0x180c, 0x2014, 0xc2e4, 0x2202,
+	0x2071, 0x19e9, 0x7004, 0x9084, 0x0007, 0x0002, 0x97f8, 0x97fc,
+	0x981a, 0x9843, 0x9881, 0x97f8, 0x9813, 0x97f6, 0x080c, 0x0dc5,
+	0x00ce, 0x00ee, 0x00be, 0x0005, 0x7024, 0x9065, 0x0148, 0x7020,
+	0x8001, 0x7022, 0x600c, 0x9015, 0x0158, 0x7216, 0x600f, 0x0000,
+	0x7007, 0x0000, 0x7027, 0x0000, 0x00ce, 0x00ee, 0x00be, 0x0005,
+	0x7216, 0x7212, 0x0ca8, 0x7007, 0x0000, 0x7027, 0x0000, 0x7020,
+	0x9005, 0x0070, 0x6010, 0x2058, 0x080c, 0x663f, 0xb800, 0xc0dc,
+	0xb802, 0x7007, 0x0000, 0x7027, 0x0000, 0x7020, 0x8001, 0x7022,
+	0x1148, 0x2001, 0x180c, 0x2014, 0xd2ec, 0x1180, 0x00ce, 0x00ee,
+	0x00be, 0x0005, 0xb854, 0x9015, 0x0120, 0x721e, 0x080c, 0x98e7,
+	0x0ca8, 0x7218, 0x721e, 0x080c, 0x98e7, 0x0c80, 0xc2ec, 0x2202,
+	0x080c, 0x9a09, 0x0c58, 0x7024, 0x9065, 0x05b8, 0x700c, 0x9c06,
+	0x1160, 0x080c, 0xa905, 0x600c, 0x9015, 0x0120, 0x720e, 0x600f,
+	0x0000, 0x0448, 0x720e, 0x720a, 0x0430, 0x7014, 0x9c06, 0x1160,
+	0x080c, 0xa905, 0x600c, 0x9015, 0x0120, 0x7216, 0x600f, 0x0000,
+	0x00d0, 0x7216, 0x7212, 0x00b8, 0x6020, 0x9086, 0x0003, 0x1198,
+	0x6010, 0x2058, 0x080c, 0x663f, 0xb800, 0xc0dc, 0xb802, 0x080c,
+	0xa905, 0x701c, 0x9065, 0x0138, 0xb854, 0x9015, 0x0110, 0x721e,
+	0x0010, 0x7218, 0x721e, 0x7027, 0x0000, 0x00ce, 0x00ee, 0x00be,
+	0x0005, 0x7024, 0x9065, 0x0140, 0x080c, 0xa905, 0x600c, 0x9015,
+	0x0158, 0x720e, 0x600f, 0x0000, 0x080c, 0xaa2f, 0x7027, 0x0000,
+	0x00ce, 0x00ee, 0x00be, 0x0005, 0x720e, 0x720a, 0x0ca8, 0x00d6,
+	0x2069, 0x19e9, 0x6830, 0x9084, 0x0003, 0x0002, 0x98a4, 0x98a6,
+	0x98ca, 0x98a2, 0x080c, 0x0dc5, 0x00de, 0x0005, 0x00c6, 0x6840,
+	0x9086, 0x0001, 0x01b8, 0x683c, 0x9065, 0x0130, 0x600c, 0x9015,
+	0x0170, 0x6a3a, 0x600f, 0x0000, 0x6833, 0x0000, 0x683f, 0x0000,
+	0x2011, 0x1a08, 0x2013, 0x0000, 0x00ce, 0x00de, 0x0005, 0x683a,
+	0x6836, 0x0c90, 0x6843, 0x0000, 0x6838, 0x9065, 0x0d68, 0x6003,
+	0x0003, 0x0c50, 0x00c6, 0x9006, 0x6842, 0x6846, 0x684a, 0x683c,
+	0x9065, 0x0160, 0x600c, 0x9015, 0x0130, 0x6a3a, 0x600f, 0x0000,
+	0x683f, 0x0000, 0x0018, 0x683e, 0x683a, 0x6836, 0x00ce, 0x00de,
+	0x0005, 0x2001, 0x180c, 0x200c, 0xc1e5, 0x2102, 0x0005, 0x2001,
+	0x180c, 0x200c, 0xd1ec, 0x0120, 0xc1ec, 0x2102, 0x080c, 0x9a09,
+	0x2001, 0x19f5, 0x2004, 0x9086, 0x0001, 0x0d58, 0x00d6, 0x2069,
+	0x19e9, 0x6804, 0x9084, 0x0007, 0x0006, 0x9005, 0x11c8, 0x2001,
+	0x1837, 0x2004, 0x9084, 0x0028, 0x1198, 0x2001, 0x197d, 0x2004,
+	0x9086, 0xaaaa, 0x0168, 0x2001, 0x188b, 0x2004, 0xd08c, 0x1118,
+	0xd084, 0x1118, 0x0028, 0x080c, 0x9a09, 0x000e, 0x00de, 0x0005,
+	0x000e, 0x0002, 0x9924, 0x99dd, 0x99dd, 0x99dd, 0x99dd, 0x99df,
+	0x99dd, 0x9922, 0x080c, 0x0dc5, 0x6820, 0x9005, 0x1110, 0x00de,
+	0x0005, 0x00c6, 0x680c, 0x9065, 0x01f0, 0x6104, 0x918e, 0x0040,
+	0x1180, 0x2009, 0x1837, 0x210c, 0x918c, 0x0028, 0x1150, 0x080c,
+	0x7563, 0x0138, 0x0006, 0x2009, 0x188b, 0x2104, 0xc095, 0x200a,
+	0x000e, 0x6807, 0x0004, 0x6826, 0x682b, 0x0000, 0x080c, 0x9ab2,
+	0x00ce, 0x00de, 0x0005, 0x6814, 0x9065, 0x0150, 0x6807, 0x0001,
+	0x6826, 0x682b, 0x0000, 0x080c, 0x9ab2, 0x00ce, 0x00de, 0x0005,
+	0x00b6, 0x00e6, 0x6a1c, 0x92dd, 0x0000, 0x0904, 0x99c7, 0xb84c,
+	0x900d, 0x0118, 0xb888, 0x9005, 0x01a0, 0xb854, 0x905d, 0x0120,
+	0x920e, 0x0904, 0x99c7, 0x0028, 0x6818, 0x920e, 0x0904, 0x99c7,
+	0x2058, 0xb84c, 0x900d, 0x0d88, 0xb888, 0x9005, 0x1d70, 0x2b00,
+	0x681e, 0xbb3c, 0xb838, 0x9302, 0x1e40, 0x080c, 0xb0be, 0x0904,
+	0x99c7, 0x8318, 0xbb3e, 0x6116, 0x2b10, 0x6212, 0x0096, 0x2148,
+	0xa880, 0x9084, 0x00ff, 0x605e, 0xa883, 0x0000, 0xa884, 0x009e,
+	0x908a, 0x199a, 0x0210, 0x2001, 0x1999, 0x8003, 0x801b, 0x831b,
+	0x9318, 0x631a, 0x6114, 0x0096, 0x2148, 0xa964, 0x009e, 0x918c,
+	0x00ff, 0x918e, 0x0048, 0x0538, 0x00f6, 0x2c78, 0x2061, 0x0100,
+	0xbac0, 0x629a, 0x2069, 0x0200, 0x2071, 0x0240, 0x080c, 0xa02d,
+	0x2069, 0x19e9, 0xbb00, 0xc3dd, 0xbb02, 0x6807, 0x0002, 0x2f18,
+	0x6b26, 0x682b, 0x0000, 0x7823, 0x0003, 0x7803, 0x0001, 0x7807,
+	0x0040, 0x00fe, 0x00ee, 0x00be, 0x00ce, 0x00de, 0x0005, 0x00ee,
+	0x00be, 0x00ce, 0x0cd0, 0x6807, 0x0006, 0x2c18, 0x6b26, 0x6820,
+	0x8001, 0x6822, 0x682b, 0x0000, 0x080c, 0x663f, 0x080c, 0xaefe,
+	0x00ee, 0x00be, 0x00ce, 0x00de, 0x0005, 0x00de, 0x0005, 0x00c6,
+	0x680c, 0x9065, 0x01d8, 0x6104, 0x918e, 0x0040, 0x1180, 0x2009,
+	0x1837, 0x210c, 0x918c, 0x0028, 0x1150, 0x080c, 0x7563, 0x0138,
 	0x0006, 0x2009, 0x188b, 0x2104, 0xc095, 0x200a, 0x000e, 0x6807,
-	0x0004, 0x6826, 0x682b, 0x0000, 0x080c, 0x993a, 0x00ce, 0x00de,
+	0x0004, 0x6826, 0x682b, 0x0000, 0x080c, 0x9ab2, 0x00ce, 0x00de,
 	0x0005, 0x2001, 0x180c, 0x2014, 0xc2ed, 0x2202, 0x00de, 0x00fe,
-	0x0005, 0x00f6, 0x00d6, 0x2069, 0x19e6, 0x6830, 0x9086, 0x0000,
+	0x0005, 0x00f6, 0x00d6, 0x2069, 0x19e9, 0x6830, 0x9086, 0x0000,
 	0x1570, 0x2001, 0x180c, 0x2014, 0xd2e4, 0x0130, 0xc2e4, 0x2202,
-	0x080c, 0x9772, 0x2069, 0x19e6, 0x2001, 0x180c, 0x200c, 0xd1c4,
+	0x080c, 0x98f6, 0x2069, 0x19e9, 0x2001, 0x180c, 0x200c, 0xd1c4,
 	0x1508, 0x6838, 0x907d, 0x01d8, 0x6a04, 0x9296, 0x0000, 0x1904,
-	0x992e, 0x7920, 0x918e, 0x0009, 0x0568, 0x6833, 0x0001, 0x683e,
+	0x9aa6, 0x7920, 0x918e, 0x0009, 0x0568, 0x6833, 0x0001, 0x683e,
 	0x6847, 0x0000, 0x684b, 0x0000, 0x0126, 0x00f6, 0x2091, 0x2400,
-	0x002e, 0x080c, 0x1c84, 0x1158, 0x012e, 0x080c, 0xa1b3, 0x00de,
-	0x00fe, 0x0005, 0xc1c4, 0x2102, 0x080c, 0x74ee, 0x08d0, 0x012e,
+	0x002e, 0x080c, 0x1c9a, 0x1158, 0x012e, 0x080c, 0xa35a, 0x00de,
+	0x00fe, 0x0005, 0xc1c4, 0x2102, 0x080c, 0x7610, 0x08d0, 0x012e,
 	0x6843, 0x0000, 0x7803, 0x0002, 0x780c, 0x9015, 0x0140, 0x6a3a,
 	0x780f, 0x0000, 0x6833, 0x0000, 0x683f, 0x0000, 0x0c40, 0x683a,
 	0x6836, 0x0cc0, 0x7908, 0xd1fc, 0x1198, 0x6833, 0x0001, 0x683e,
 	0x6847, 0x0000, 0x684b, 0x0000, 0x0126, 0x00f6, 0x2091, 0x2400,
-	0x002e, 0x080c, 0x1c84, 0x19d8, 0x012e, 0x080c, 0xa134, 0x0878,
-	0x2001, 0x1837, 0x2004, 0x9084, 0x0028, 0x1188, 0x2001, 0x197b,
-	0x2004, 0x9086, 0xaaaa, 0x0158, 0x2001, 0x19e7, 0x2004, 0x9005,
+	0x002e, 0x080c, 0x1c9a, 0x19d8, 0x012e, 0x080c, 0xa2db, 0x0878,
+	0x2001, 0x1837, 0x2004, 0x9084, 0x0028, 0x1188, 0x2001, 0x197d,
+	0x2004, 0x9086, 0xaaaa, 0x0158, 0x2001, 0x19ea, 0x2004, 0x9005,
 	0x11f0, 0x2001, 0x188b, 0x200c, 0xc185, 0xc18c, 0x2102, 0x2f00,
 	0x6833, 0x0001, 0x683e, 0x6847, 0x0000, 0x684b, 0x0000, 0x0126,
-	0x00f6, 0x2091, 0x2400, 0x002e, 0x080c, 0x1c84, 0x1904, 0x98cf,
-	0x012e, 0x6a3c, 0x2278, 0x080c, 0xa0be, 0x0804, 0x98c7, 0x2011,
-	0x188b, 0x2204, 0xc08d, 0x2012, 0x0804, 0x98c7, 0x6a04, 0x9296,
-	0x0006, 0x1904, 0x9889, 0x6a30, 0x9296, 0x0000, 0x0904, 0x98b1,
-	0x0804, 0x9889, 0x6020, 0x9084, 0x000f, 0x000b, 0x0005, 0x994e,
-	0x9953, 0x9dc1, 0x9e5a, 0x9953, 0x9dc1, 0x9e5a, 0x994e, 0x9953,
-	0x994e, 0x994e, 0x994e, 0x994e, 0x994e, 0x994e, 0x080c, 0x9657,
-	0x080c, 0x9763, 0x0005, 0x00b6, 0x0156, 0x0136, 0x0146, 0x01c6,
+	0x00f6, 0x2091, 0x2400, 0x002e, 0x080c, 0x1c9a, 0x1904, 0x9a47,
+	0x012e, 0x6a3c, 0x2278, 0x080c, 0xa265, 0x0804, 0x9a3f, 0x2011,
+	0x188b, 0x2204, 0xc08d, 0x2012, 0x0804, 0x9a3f, 0x6a04, 0x9296,
+	0x0006, 0x1904, 0x9a01, 0x6a30, 0x9296, 0x0000, 0x0904, 0x9a29,
+	0x0804, 0x9a01, 0x6020, 0x9084, 0x000f, 0x000b, 0x0005, 0x9ac6,
+	0x9acb, 0x9f5d, 0x9ff6, 0x9acb, 0x9f5d, 0x9ff6, 0x9ac6, 0x9acb,
+	0x9ac6, 0x9ac6, 0x9ac6, 0x9ac6, 0x9ac6, 0x9ac6, 0x080c, 0x97db,
+	0x080c, 0x98e7, 0x0005, 0x00b6, 0x0156, 0x0136, 0x0146, 0x01c6,
 	0x01d6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2069, 0x0200, 0x2071,
-	0x0240, 0x6004, 0x908a, 0x0053, 0x1a0c, 0x0dd5, 0x6110, 0x2158,
+	0x0240, 0x6004, 0x908a, 0x0053, 0x1a0c, 0x0dc5, 0x6110, 0x2158,
 	0xb9c0, 0x2c78, 0x2061, 0x0100, 0x619a, 0x908a, 0x0040, 0x1a04,
-	0x99bf, 0x005b, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x01de, 0x01ce,
-	0x014e, 0x013e, 0x015e, 0x00be, 0x0005, 0x9b44, 0x9b7f, 0x9ba8,
-	0x9c50, 0x9c72, 0x9c78, 0x9c85, 0x9c8d, 0x9c99, 0x9c9f, 0x9cb0,
-	0x9c9f, 0x9d08, 0x9c8d, 0x9d14, 0x9d1a, 0x9c99, 0x9d1a, 0x9d26,
-	0x99bd, 0x99bd, 0x99bd, 0x99bd, 0x99bd, 0x99bd, 0x99bd, 0x99bd,
-	0x99bd, 0x99bd, 0x99bd, 0xa563, 0xa586, 0xa597, 0xa5b7, 0xa5e9,
-	0x9c85, 0x99bd, 0x9c85, 0x9c9f, 0x99bd, 0x9ba8, 0x9c50, 0x99bd,
-	0xa982, 0x9c9f, 0x99bd, 0xa99e, 0x9c9f, 0x99bd, 0x9c99, 0x9b3e,
-	0x99e0, 0x99bd, 0xa9ba, 0xaa27, 0xab02, 0x99bd, 0xab0f, 0x9c82,
-	0xab3a, 0x99bd, 0xa5f3, 0xab67, 0x99bd, 0x080c, 0x0dd5, 0x2100,
+	0x9b37, 0x005b, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x01de, 0x01ce,
+	0x014e, 0x013e, 0x015e, 0x00be, 0x0005, 0x9ce0, 0x9d1b, 0x9d44,
+	0x9dec, 0x9e0e, 0x9e14, 0x9e21, 0x9e29, 0x9e35, 0x9e3b, 0x9e4c,
+	0x9e3b, 0x9ea4, 0x9e29, 0x9eb0, 0x9eb6, 0x9e35, 0x9eb6, 0x9ec2,
+	0x9b35, 0x9b35, 0x9b35, 0x9b35, 0x9b35, 0x9b35, 0x9b35, 0x9b35,
+	0x9b35, 0x9b35, 0x9b35, 0xa714, 0xa737, 0xa748, 0xa768, 0xa79a,
+	0x9e21, 0x9b35, 0x9e21, 0x9e3b, 0x9b35, 0x9d44, 0x9dec, 0x9b35,
+	0xab26, 0x9e3b, 0x9b35, 0xab42, 0x9e3b, 0x9b35, 0x9e35, 0x9cda,
+	0x9b58, 0x9b35, 0xab5e, 0xabcb, 0xaca6, 0x9b35, 0xacb3, 0x9e1e,
+	0xacde, 0x9b35, 0xa7a4, 0xad0b, 0x9b35, 0x080c, 0x0dc5, 0x2100,
 	0x005b, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x01de, 0x01ce, 0x014e,
-	0x013e, 0x015e, 0x00be, 0x0005, 0xac02, 0xacb4, 0x99de, 0x9a07,
-	0x9ab3, 0x9abe, 0x99de, 0x9c85, 0x99de, 0x9b05, 0x9b11, 0x9a22,
-	0x99de, 0x9a3d, 0x9a71, 0xae21, 0xae66, 0x9c9f, 0x080c, 0x0dd5,
-	0x00d6, 0x0096, 0x080c, 0x9d39, 0x7003, 0x2414, 0x7007, 0x0018,
-	0x700b, 0x0800, 0x7814, 0x2048, 0xa83c, 0x700e, 0xa850, 0x7022,
-	0xa854, 0x7026, 0x60c3, 0x0018, 0x080c, 0xa32a, 0x009e, 0x00de,
-	0x0005, 0x7810, 0x00b6, 0x2058, 0xb8a0, 0x00be, 0x080c, 0xaead,
-	0x1118, 0x9084, 0xff80, 0x0110, 0x9085, 0x0001, 0x0005, 0x00d6,
-	0x0096, 0x080c, 0x9d39, 0x7003, 0x0500, 0x7814, 0x2048, 0xa874,
-	0x700a, 0xa878, 0x700e, 0xa87c, 0x7012, 0xa880, 0x7016, 0xa884,
-	0x701a, 0xa888, 0x701e, 0x60c3, 0x0010, 0x080c, 0xa32a, 0x009e,
-	0x00de, 0x0005, 0x00d6, 0x0096, 0x080c, 0x9d39, 0x7003, 0x0500,
-	0x7814, 0x2048, 0xa8cc, 0x700a, 0xa8d0, 0x700e, 0xa8d4, 0x7012,
-	0xa8d8, 0x7016, 0xa8dc, 0x701a, 0xa8e0, 0x701e, 0x60c3, 0x0010,
-	0x080c, 0xa32a, 0x009e, 0x00de, 0x0005, 0x00d6, 0x0096, 0x0126,
-	0x2091, 0x8000, 0x080c, 0x9d39, 0x20e9, 0x0000, 0x2001, 0x19a2,
-	0x2003, 0x0000, 0x7814, 0x2048, 0xa814, 0x8003, 0x60c2, 0xa830,
-	0x20a8, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x001b, 0x2098, 0x2001,
-	0x19a2, 0x0016, 0x200c, 0x2001, 0x0001, 0x080c, 0x23f5, 0x080c,
-	0xd9e7, 0x9006, 0x080c, 0x23f5, 0x001e, 0xa804, 0x9005, 0x0110,
-	0x2048, 0x0c28, 0x04d9, 0x080c, 0xa32a, 0x012e, 0x009e, 0x00de,
-	0x0005, 0x00d6, 0x0096, 0x0126, 0x2091, 0x8000, 0x080c, 0x9d84,
-	0x20e9, 0x0000, 0x2001, 0x19a2, 0x2003, 0x0000, 0x7814, 0x2048,
-	0xa86f, 0x0200, 0xa873, 0x0000, 0xa814, 0x8003, 0x60c2, 0xa830,
-	0x20a8, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x001b, 0x2098, 0x2001,
-	0x19a2, 0x0016, 0x200c, 0x080c, 0xd9e7, 0x001e, 0xa804, 0x9005,
-	0x0110, 0x2048, 0x0c60, 0x0051, 0x7814, 0x2048, 0x080c, 0x0fb1,
-	0x080c, 0xa32a, 0x012e, 0x009e, 0x00de, 0x0005, 0x60c0, 0x8004,
-	0x9084, 0x0003, 0x9005, 0x0130, 0x9082, 0x0004, 0x20a3, 0x0000,
-	0x8000, 0x1de0, 0x0005, 0x080c, 0x9d39, 0x7003, 0x7800, 0x7808,
-	0x8007, 0x700a, 0x60c3, 0x0008, 0x0804, 0xa32a, 0x00d6, 0x00e6,
-	0x080c, 0x9d84, 0x7814, 0x9084, 0xff00, 0x2073, 0x0200, 0x8e70,
-	0x8e70, 0x9095, 0x0010, 0x2272, 0x8e70, 0x2073, 0x0034, 0x8e70,
-	0x2069, 0x1805, 0x20a9, 0x0004, 0x2d76, 0x8d68, 0x8e70, 0x1f04,
-	0x9ad4, 0x2069, 0x1801, 0x20a9, 0x0004, 0x2d76, 0x8d68, 0x8e70,
-	0x1f04, 0x9add, 0x2069, 0x19b2, 0x9086, 0xdf00, 0x0110, 0x2069,
-	0x19cc, 0x20a9, 0x001a, 0x9e86, 0x0260, 0x1148, 0x00c6, 0x2061,
-	0x0200, 0x6010, 0x8000, 0x6012, 0x00ce, 0x2071, 0x0240, 0x2d04,
-	0x8007, 0x2072, 0x8d68, 0x8e70, 0x1f04, 0x9aeb, 0x60c3, 0x004c,
-	0x080c, 0xa32a, 0x00ee, 0x00de, 0x0005, 0x080c, 0x9d39, 0x7003,
-	0x6300, 0x7007, 0x0028, 0x7808, 0x700e, 0x60c3, 0x0008, 0x0804,
-	0xa32a, 0x00d6, 0x0026, 0x0016, 0x080c, 0x9d84, 0x7003, 0x0200,
-	0x7814, 0x700e, 0x00e6, 0x9ef0, 0x0004, 0x2009, 0x0001, 0x2011,
-	0x000c, 0x2069, 0x1923, 0x6810, 0xd084, 0x1148, 0x2073, 0x0500,
-	0x8e70, 0x2073, 0x0000, 0x8e70, 0x8108, 0x9290, 0x0004, 0x2073,
-	0x0800, 0x8e70, 0x2073, 0x0000, 0x00ee, 0x7206, 0x710a, 0x62c2,
-	0x080c, 0xa32a, 0x001e, 0x002e, 0x00de, 0x0005, 0x2001, 0x1818,
-	0x2004, 0x609a, 0x0804, 0xa32a, 0x080c, 0x9d39, 0x7003, 0x5200,
-	0x2069, 0x1847, 0x6804, 0xd084, 0x0130, 0x6828, 0x0016, 0x080c,
-	0x28af, 0x710e, 0x001e, 0x20a9, 0x0004, 0x20e1, 0x0001, 0x2099,
-	0x1805, 0x20e9, 0x0000, 0x20a1, 0x0250, 0x4003, 0x20a9, 0x0004,
-	0x2099, 0x1801, 0x20a1, 0x0254, 0x4003, 0x080c, 0xaead, 0x1120,
-	0xb8a0, 0x9082, 0x007f, 0x0248, 0x2001, 0x181f, 0x2004, 0x7032,
-	0x2001, 0x1820, 0x2004, 0x7036, 0x0030, 0x2001, 0x1818, 0x2004,
-	0x9084, 0x00ff, 0x7036, 0x60c3, 0x001c, 0x0804, 0xa32a, 0x080c,
-	0x9d39, 0x7003, 0x0500, 0x080c, 0xaead, 0x1120, 0xb8a0, 0x9082,
-	0x007f, 0x0248, 0x2001, 0x181f, 0x2004, 0x700a, 0x2001, 0x1820,
-	0x2004, 0x700e, 0x0030, 0x2001, 0x1818, 0x2004, 0x9084, 0x00ff,
-	0x700e, 0x20a9, 0x0004, 0x20e1, 0x0001, 0x2099, 0x1805, 0x20e9,
-	0x0000, 0x20a1, 0x0250, 0x4003, 0x60c3, 0x0010, 0x0804, 0xa32a,
-	0x080c, 0x9d39, 0x9006, 0x080c, 0x69d6, 0xb8a0, 0x9086, 0x007e,
-	0x1130, 0x7003, 0x0400, 0x620c, 0xc2b4, 0x620e, 0x0058, 0x7814,
-	0x0096, 0x904d, 0x0120, 0x9006, 0xa89a, 0xa8a6, 0xa8aa, 0x009e,
-	0x7003, 0x0300, 0xb8a0, 0x9086, 0x007e, 0x1904, 0x9c17, 0x00d6,
-	0x2069, 0x196b, 0x2001, 0x1837, 0x2004, 0xd0a4, 0x0188, 0x6800,
-	0x700a, 0x6808, 0x9084, 0x2000, 0x7012, 0x080c, 0xaec4, 0x680c,
-	0x7016, 0x701f, 0x2710, 0x6818, 0x7022, 0x681c, 0x7026, 0x0090,
-	0x6800, 0x700a, 0x6804, 0x700e, 0x6808, 0x080c, 0x743e, 0x1118,
-	0x9084, 0x37ff, 0x0010, 0x9084, 0x3fff, 0x7012, 0x080c, 0xaec4,
-	0x680c, 0x7016, 0x00de, 0x20a9, 0x0004, 0x20e1, 0x0001, 0x2099,
-	0x1805, 0x20e9, 0x0000, 0x20a1, 0x0256, 0x4003, 0x20a9, 0x0004,
-	0x2099, 0x1801, 0x20a1, 0x025a, 0x4003, 0x00d6, 0x080c, 0xabe9,
-	0x2069, 0x1973, 0x2071, 0x024e, 0x6800, 0xc0dd, 0x7002, 0x080c,
-	0x5761, 0xd0e4, 0x0110, 0x680c, 0x700e, 0x00de, 0x04a8, 0x2001,
-	0x1837, 0x2004, 0xd0a4, 0x0170, 0x0016, 0x2001, 0x196c, 0x200c,
-	0x60e0, 0x9106, 0x0130, 0x2100, 0x60e3, 0x0000, 0x080c, 0x28f0,
-	0x61e2, 0x001e, 0x20e1, 0x0001, 0x2099, 0x196b, 0x20e9, 0x0000,
-	0x20a1, 0x024e, 0x20a9, 0x0008, 0x4003, 0x20a9, 0x0004, 0x2099,
-	0x1805, 0x20a1, 0x0256, 0x4003, 0x20a9, 0x0004, 0x2099, 0x1801,
-	0x20a1, 0x025a, 0x4003, 0x080c, 0xabe9, 0x20a1, 0x024e, 0x20a9,
-	0x0008, 0x2099, 0x1973, 0x4003, 0x60c3, 0x0074, 0x0804, 0xa32a,
-	0x080c, 0x9d39, 0x7003, 0x2010, 0x7007, 0x0014, 0x700b, 0x0800,
-	0x700f, 0x2000, 0x9006, 0x00f6, 0x2079, 0x1847, 0x7904, 0x00fe,
-	0xd1ac, 0x1110, 0x9085, 0x0020, 0xd1a4, 0x0110, 0x9085, 0x0010,
-	0x9085, 0x0002, 0x00d6, 0x0804, 0x9ce9, 0x7026, 0x60c3, 0x0014,
-	0x0804, 0xa32a, 0x080c, 0x9d39, 0x7003, 0x5000, 0x0804, 0x9bc2,
-	0x080c, 0x9d39, 0x7003, 0x2110, 0x7007, 0x0014, 0x60c3, 0x0014,
-	0x0804, 0xa32a, 0x080c, 0x9d7b, 0x0010, 0x080c, 0x9d84, 0x7003,
-	0x0200, 0x60c3, 0x0004, 0x0804, 0xa32a, 0x080c, 0x9d84, 0x7003,
-	0x0100, 0x700b, 0x0003, 0x700f, 0x2a00, 0x60c3, 0x0008, 0x0804,
-	0xa32a, 0x080c, 0x9d84, 0x7003, 0x0200, 0x0804, 0x9bc2, 0x080c,
-	0x9d84, 0x7003, 0x0100, 0x782c, 0x9005, 0x0110, 0x700a, 0x0010,
-	0x700b, 0x0003, 0x7814, 0x700e, 0x60c3, 0x0008, 0x0804, 0xa32a,
-	0x00d6, 0x080c, 0x9d84, 0x7003, 0x0210, 0x7007, 0x0014, 0x700b,
-	0x0800, 0xb894, 0x9086, 0x0014, 0x1198, 0xb99c, 0x9184, 0x0030,
-	0x0190, 0xb998, 0x9184, 0xc000, 0x1140, 0xd1ec, 0x0118, 0x700f,
-	0x2100, 0x0058, 0x700f, 0x0100, 0x0040, 0x700f, 0x0400, 0x0028,
-	0x700f, 0x0700, 0x0010, 0x700f, 0x0800, 0x00f6, 0x2079, 0x1847,
-	0x7904, 0x00fe, 0xd1ac, 0x1110, 0x9085, 0x0020, 0xd1a4, 0x0110,
-	0x9085, 0x0010, 0x2009, 0x1869, 0x210c, 0xd184, 0x1110, 0x9085,
-	0x0002, 0x0026, 0x2009, 0x1867, 0x210c, 0xd1e4, 0x0150, 0xc0c5,
-	0xbacc, 0xd28c, 0x1108, 0xc0cd, 0x9094, 0x0030, 0x9296, 0x0010,
-	0x0140, 0xd1ec, 0x0130, 0x9094, 0x0030, 0x9296, 0x0010, 0x0108,
-	0xc0bd, 0x002e, 0x7026, 0x60c3, 0x0014, 0x00de, 0x0804, 0xa32a,
-	0x080c, 0x9d84, 0x7003, 0x0210, 0x7007, 0x0014, 0x700f, 0x0100,
-	0x60c3, 0x0014, 0x0804, 0xa32a, 0x080c, 0x9d84, 0x7003, 0x0200,
-	0x0804, 0x9b48, 0x080c, 0x9d84, 0x7003, 0x0100, 0x700b, 0x0003,
-	0x700f, 0x2a00, 0x60c3, 0x0008, 0x0804, 0xa32a, 0x080c, 0x9d84,
-	0x7003, 0x0100, 0x700b, 0x000b, 0x60c3, 0x0008, 0x0804, 0xa32a,
-	0x0026, 0x00d6, 0x0036, 0x0046, 0x2019, 0x3200, 0x2021, 0x0800,
-	0x0040, 0x0026, 0x00d6, 0x0036, 0x0046, 0x2019, 0x2200, 0x2021,
-	0x0100, 0x080c, 0xabfe, 0xb810, 0x9305, 0x7002, 0xb814, 0x7006,
-	0x2069, 0x1800, 0x687c, 0x700a, 0x6880, 0x700e, 0x9485, 0x0029,
-	0x7012, 0x004e, 0x003e, 0x00de, 0x080c, 0xa318, 0x721a, 0x9f95,
-	0x0000, 0x7222, 0x7027, 0xffff, 0x2071, 0x024c, 0x002e, 0x0005,
-	0x0026, 0x080c, 0xabfe, 0x7003, 0x02ff, 0x7007, 0xfffc, 0x00d6,
-	0x2069, 0x1800, 0x687c, 0x700a, 0x6880, 0x700e, 0x00de, 0x7013,
-	0x2029, 0x0c10, 0x7003, 0x0100, 0x7007, 0x0000, 0x700b, 0xfc02,
-	0x700f, 0x0000, 0x0005, 0x0026, 0x00d6, 0x0036, 0x0046, 0x2019,
-	0x3300, 0x2021, 0x0800, 0x0040, 0x0026, 0x00d6, 0x0036, 0x0046,
-	0x2019, 0x2300, 0x2021, 0x0100, 0x080c, 0xabfe, 0xb810, 0x9305,
-	0x7002, 0xb814, 0x7006, 0x2069, 0x1800, 0xb810, 0x9005, 0x1140,
-	0xb814, 0x9005, 0x1128, 0x700b, 0x00ff, 0x700f, 0xfffe, 0x0020,
-	0x687c, 0x700a, 0x6880, 0x700e, 0x0000, 0x9485, 0x0098, 0x7012,
-	0x004e, 0x003e, 0x00de, 0x080c, 0xa318, 0x721a, 0x7a08, 0x7222,
-	0x2f10, 0x7226, 0x2071, 0x024c, 0x002e, 0x0005, 0x080c, 0xa318,
-	0x721a, 0x7a08, 0x7222, 0x7814, 0x7026, 0x2071, 0x024c, 0x002e,
-	0x0005, 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2069, 0x0200,
-	0x2071, 0x0240, 0x6004, 0x908a, 0x0085, 0x0a0c, 0x0dd5, 0x908a,
-	0x0092, 0x1a0c, 0x0dd5, 0x6110, 0x2158, 0xb9c0, 0x2c78, 0x2061,
-	0x0100, 0x619a, 0x9082, 0x0085, 0x0033, 0x00fe, 0x00ee, 0x00de,
-	0x00ce, 0x00be, 0x0005, 0x9df2, 0x9e01, 0x9e0c, 0x9df0, 0x9df0,
-	0x9df0, 0x9df2, 0x9df0, 0x9df0, 0x9df0, 0x9df0, 0x9df0, 0x9df0,
-	0x080c, 0x0dd5, 0x0411, 0x60c3, 0x0000, 0x0026, 0x080c, 0x2be3,
-	0x0228, 0x2011, 0x0101, 0x2204, 0xc0c5, 0x2012, 0x002e, 0x0804,
-	0xa32a, 0x0431, 0x7808, 0x700a, 0x7814, 0x700e, 0x7017, 0xffff,
-	0x60c3, 0x000c, 0x0804, 0xa32a, 0x04a1, 0x7003, 0x0003, 0x7007,
-	0x0300, 0x60c3, 0x0004, 0x0804, 0xa32a, 0x0026, 0x080c, 0xabfe,
-	0xb810, 0x9085, 0x8100, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800,
-	0x687c, 0x700a, 0x6880, 0x700e, 0x7013, 0x0009, 0x0804, 0x9d54,
-	0x0026, 0x080c, 0xabfe, 0xb810, 0x9085, 0x8400, 0x7002, 0xb814,
-	0x7006, 0x2069, 0x1800, 0x687c, 0x700a, 0x6880, 0x700e, 0x2001,
-	0x0099, 0x7a20, 0x9296, 0x0005, 0x0108, 0xc0bc, 0x7012, 0x0804,
-	0x9db6, 0x0026, 0x080c, 0xabfe, 0xb810, 0x9085, 0x8500, 0x7002,
+	0x013e, 0x015e, 0x00be, 0x0005, 0xada6, 0xae58, 0x9b56, 0x9b90,
+	0x9c3c, 0x9c47, 0x9b56, 0x9e21, 0x9b56, 0x9ca1, 0x9cad, 0x9bab,
+	0x9b56, 0x9bc6, 0x9bfa, 0xafc5, 0xb00a, 0x9e3b, 0x080c, 0x0dc5,
+	0x00d6, 0x0096, 0x080c, 0x9ed5, 0x0026, 0x0036, 0x7814, 0x2048,
+	0xa958, 0xd1cc, 0x1138, 0x2009, 0x2414, 0x2011, 0x0018, 0x2019,
+	0x0018, 0x0030, 0x2009, 0x2410, 0x2011, 0x0014, 0x2019, 0x0014,
+	0x7102, 0x7206, 0x700b, 0x0800, 0xa83c, 0x700e, 0xa850, 0x7022,
+	0xa854, 0x7026, 0x63c2, 0x080c, 0xa4d1, 0x003e, 0x002e, 0x009e,
+	0x00de, 0x0005, 0x7810, 0x00b6, 0x2058, 0xb8a0, 0x00be, 0x080c,
+	0xb051, 0x1118, 0x9084, 0xff80, 0x0110, 0x9085, 0x0001, 0x0005,
+	0x00d6, 0x0096, 0x080c, 0x9ed5, 0x7003, 0x0500, 0x7814, 0x2048,
+	0xa874, 0x700a, 0xa878, 0x700e, 0xa87c, 0x7012, 0xa880, 0x7016,
+	0xa884, 0x701a, 0xa888, 0x701e, 0x60c3, 0x0010, 0x080c, 0xa4d1,
+	0x009e, 0x00de, 0x0005, 0x00d6, 0x0096, 0x080c, 0x9ed5, 0x7003,
+	0x0500, 0x7814, 0x2048, 0xa8cc, 0x700a, 0xa8d0, 0x700e, 0xa8d4,
+	0x7012, 0xa8d8, 0x7016, 0xa8dc, 0x701a, 0xa8e0, 0x701e, 0x60c3,
+	0x0010, 0x080c, 0xa4d1, 0x009e, 0x00de, 0x0005, 0x00d6, 0x0096,
+	0x0126, 0x2091, 0x8000, 0x080c, 0x9ed5, 0x20e9, 0x0000, 0x2001,
+	0x19a4, 0x2003, 0x0000, 0x7814, 0x2048, 0xa814, 0x8003, 0x60c2,
+	0xa830, 0x20a8, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x001b, 0x2098,
+	0x2001, 0x19a4, 0x0016, 0x200c, 0x2001, 0x0001, 0x080c, 0x240f,
+	0x080c, 0xdbe1, 0x9006, 0x080c, 0x240f, 0x001e, 0xa804, 0x9005,
+	0x0110, 0x2048, 0x0c28, 0x04d9, 0x080c, 0xa4d1, 0x012e, 0x009e,
+	0x00de, 0x0005, 0x00d6, 0x0096, 0x0126, 0x2091, 0x8000, 0x080c,
+	0x9f20, 0x20e9, 0x0000, 0x2001, 0x19a4, 0x2003, 0x0000, 0x7814,
+	0x2048, 0xa86f, 0x0200, 0xa873, 0x0000, 0xa814, 0x8003, 0x60c2,
+	0xa830, 0x20a8, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x001b, 0x2098,
+	0x2001, 0x19a4, 0x0016, 0x200c, 0x080c, 0xdbe1, 0x001e, 0xa804,
+	0x9005, 0x0110, 0x2048, 0x0c60, 0x0051, 0x7814, 0x2048, 0x080c,
+	0x0fc0, 0x080c, 0xa4d1, 0x012e, 0x009e, 0x00de, 0x0005, 0x60c0,
+	0x8004, 0x9084, 0x0003, 0x9005, 0x0130, 0x9082, 0x0004, 0x20a3,
+	0x0000, 0x8000, 0x1de0, 0x0005, 0x080c, 0x9ed5, 0x7003, 0x7800,
+	0x7808, 0x8007, 0x700a, 0x60c3, 0x0008, 0x0804, 0xa4d1, 0x00d6,
+	0x00e6, 0x080c, 0x9f20, 0x7814, 0x9084, 0xff00, 0x2073, 0x0200,
+	0x8e70, 0x8e70, 0x9096, 0xdf00, 0x0138, 0x9096, 0xe000, 0x0120,
+	0x2073, 0x0010, 0x8e70, 0x0030, 0x9095, 0x0010, 0x2272, 0x8e70,
+	0x2073, 0x0034, 0x8e70, 0x2069, 0x1805, 0x20a9, 0x0004, 0x2d76,
+	0x8d68, 0x8e70, 0x1f04, 0x9c67, 0x2069, 0x1801, 0x20a9, 0x0004,
+	0x2d76, 0x8d68, 0x8e70, 0x1f04, 0x9c70, 0x9096, 0xdf00, 0x0130,
+	0x9096, 0xe000, 0x0118, 0x60c3, 0x0018, 0x00f0, 0x2069, 0x19b5,
+	0x9086, 0xdf00, 0x0110, 0x2069, 0x19cf, 0x20a9, 0x001a, 0x9e86,
+	0x0260, 0x1148, 0x00c6, 0x2061, 0x0200, 0x6010, 0x8000, 0x6012,
+	0x00ce, 0x2071, 0x0240, 0x2d04, 0x8007, 0x2072, 0x8d68, 0x8e70,
+	0x1f04, 0x9c87, 0x60c3, 0x004c, 0x080c, 0xa4d1, 0x00ee, 0x00de,
+	0x0005, 0x080c, 0x9ed5, 0x7003, 0x6300, 0x7007, 0x0028, 0x7808,
+	0x700e, 0x60c3, 0x0008, 0x0804, 0xa4d1, 0x00d6, 0x0026, 0x0016,
+	0x080c, 0x9f20, 0x7003, 0x0200, 0x7814, 0x700e, 0x00e6, 0x9ef0,
+	0x0004, 0x2009, 0x0001, 0x2011, 0x000c, 0x2069, 0x1925, 0x6810,
+	0xd084, 0x1148, 0x2073, 0x0500, 0x8e70, 0x2073, 0x0000, 0x8e70,
+	0x8108, 0x9290, 0x0004, 0x2073, 0x0800, 0x8e70, 0x2073, 0x0000,
+	0x00ee, 0x7206, 0x710a, 0x62c2, 0x080c, 0xa4d1, 0x001e, 0x002e,
+	0x00de, 0x0005, 0x2001, 0x1818, 0x2004, 0x609a, 0x0804, 0xa4d1,
+	0x080c, 0x9ed5, 0x7003, 0x5200, 0x2069, 0x1847, 0x6804, 0xd084,
+	0x0130, 0x6828, 0x0016, 0x080c, 0x28bc, 0x710e, 0x001e, 0x20a9,
+	0x0004, 0x20e1, 0x0001, 0x2099, 0x1805, 0x20e9, 0x0000, 0x20a1,
+	0x0250, 0x4003, 0x20a9, 0x0004, 0x2099, 0x1801, 0x20a1, 0x0254,
+	0x4003, 0x080c, 0xb051, 0x1120, 0xb8a0, 0x9082, 0x007f, 0x0248,
+	0x2001, 0x181f, 0x2004, 0x7032, 0x2001, 0x1820, 0x2004, 0x7036,
+	0x0030, 0x2001, 0x1818, 0x2004, 0x9084, 0x00ff, 0x7036, 0x60c3,
+	0x001c, 0x0804, 0xa4d1, 0x080c, 0x9ed5, 0x7003, 0x0500, 0x080c,
+	0xb051, 0x1120, 0xb8a0, 0x9082, 0x007f, 0x0248, 0x2001, 0x181f,
+	0x2004, 0x700a, 0x2001, 0x1820, 0x2004, 0x700e, 0x0030, 0x2001,
+	0x1818, 0x2004, 0x9084, 0x00ff, 0x700e, 0x20a9, 0x0004, 0x20e1,
+	0x0001, 0x2099, 0x1805, 0x20e9, 0x0000, 0x20a1, 0x0250, 0x4003,
+	0x60c3, 0x0010, 0x0804, 0xa4d1, 0x080c, 0x9ed5, 0x9006, 0x080c,
+	0x6a56, 0xb8a0, 0x9086, 0x007e, 0x1130, 0x7003, 0x0400, 0x620c,
+	0xc2b4, 0x620e, 0x0058, 0x7814, 0x0096, 0x904d, 0x0120, 0x9006,
+	0xa89a, 0xa8a6, 0xa8aa, 0x009e, 0x7003, 0x0300, 0xb8a0, 0x9086,
+	0x007e, 0x1904, 0x9db3, 0x00d6, 0x2069, 0x196d, 0x2001, 0x1837,
+	0x2004, 0xd0a4, 0x0188, 0x6800, 0x700a, 0x6808, 0x9084, 0x2000,
+	0x7012, 0x080c, 0xb068, 0x680c, 0x7016, 0x701f, 0x2710, 0x6818,
+	0x7022, 0x681c, 0x7026, 0x0090, 0x6800, 0x700a, 0x6804, 0x700e,
+	0x6808, 0x080c, 0x7563, 0x1118, 0x9084, 0x37ff, 0x0010, 0x9084,
+	0x3fff, 0x7012, 0x080c, 0xb068, 0x680c, 0x7016, 0x00de, 0x20a9,
+	0x0004, 0x20e1, 0x0001, 0x2099, 0x1805, 0x20e9, 0x0000, 0x20a1,
+	0x0256, 0x4003, 0x20a9, 0x0004, 0x2099, 0x1801, 0x20a1, 0x025a,
+	0x4003, 0x00d6, 0x080c, 0xad8d, 0x2069, 0x1975, 0x2071, 0x024e,
+	0x6800, 0xc0dd, 0x7002, 0x080c, 0x57d1, 0xd0e4, 0x0110, 0x680c,
+	0x700e, 0x00de, 0x04a8, 0x2001, 0x1837, 0x2004, 0xd0a4, 0x0170,
+	0x0016, 0x2001, 0x196e, 0x200c, 0x60e0, 0x9106, 0x0130, 0x2100,
+	0x60e3, 0x0000, 0x080c, 0x28fd, 0x61e2, 0x001e, 0x20e1, 0x0001,
+	0x2099, 0x196d, 0x20e9, 0x0000, 0x20a1, 0x024e, 0x20a9, 0x0008,
+	0x4003, 0x20a9, 0x0004, 0x2099, 0x1805, 0x20a1, 0x0256, 0x4003,
+	0x20a9, 0x0004, 0x2099, 0x1801, 0x20a1, 0x025a, 0x4003, 0x080c,
+	0xad8d, 0x20a1, 0x024e, 0x20a9, 0x0008, 0x2099, 0x1975, 0x4003,
+	0x60c3, 0x0074, 0x0804, 0xa4d1, 0x080c, 0x9ed5, 0x7003, 0x2010,
+	0x7007, 0x0014, 0x700b, 0x0800, 0x700f, 0x2000, 0x9006, 0x00f6,
+	0x2079, 0x1847, 0x7904, 0x00fe, 0xd1ac, 0x1110, 0x9085, 0x0020,
+	0xd1a4, 0x0110, 0x9085, 0x0010, 0x9085, 0x0002, 0x00d6, 0x0804,
+	0x9e85, 0x7026, 0x60c3, 0x0014, 0x0804, 0xa4d1, 0x080c, 0x9ed5,
+	0x7003, 0x5000, 0x0804, 0x9d5e, 0x080c, 0x9ed5, 0x7003, 0x2110,
+	0x7007, 0x0014, 0x60c3, 0x0014, 0x0804, 0xa4d1, 0x080c, 0x9f17,
+	0x0010, 0x080c, 0x9f20, 0x7003, 0x0200, 0x60c3, 0x0004, 0x0804,
+	0xa4d1, 0x080c, 0x9f20, 0x7003, 0x0100, 0x700b, 0x0003, 0x700f,
+	0x2a00, 0x60c3, 0x0008, 0x0804, 0xa4d1, 0x080c, 0x9f20, 0x7003,
+	0x0200, 0x0804, 0x9d5e, 0x080c, 0x9f20, 0x7003, 0x0100, 0x782c,
+	0x9005, 0x0110, 0x700a, 0x0010, 0x700b, 0x0003, 0x7814, 0x700e,
+	0x60c3, 0x0008, 0x0804, 0xa4d1, 0x00d6, 0x080c, 0x9f20, 0x7003,
+	0x0210, 0x7007, 0x0014, 0x700b, 0x0800, 0xb894, 0x9086, 0x0014,
+	0x1198, 0xb99c, 0x9184, 0x0030, 0x0190, 0xb998, 0x9184, 0xc000,
+	0x1140, 0xd1ec, 0x0118, 0x700f, 0x2100, 0x0058, 0x700f, 0x0100,
+	0x0040, 0x700f, 0x0400, 0x0028, 0x700f, 0x0700, 0x0010, 0x700f,
+	0x0800, 0x00f6, 0x2079, 0x1847, 0x7904, 0x00fe, 0xd1ac, 0x1110,
+	0x9085, 0x0020, 0xd1a4, 0x0110, 0x9085, 0x0010, 0x2009, 0x1869,
+	0x210c, 0xd184, 0x1110, 0x9085, 0x0002, 0x0026, 0x2009, 0x1867,
+	0x210c, 0xd1e4, 0x0150, 0xc0c5, 0xbacc, 0xd28c, 0x1108, 0xc0cd,
+	0x9094, 0x0030, 0x9296, 0x0010, 0x0140, 0xd1ec, 0x0130, 0x9094,
+	0x0030, 0x9296, 0x0010, 0x0108, 0xc0bd, 0x002e, 0x7026, 0x60c3,
+	0x0014, 0x00de, 0x0804, 0xa4d1, 0x080c, 0x9f20, 0x7003, 0x0210,
+	0x7007, 0x0014, 0x700f, 0x0100, 0x60c3, 0x0014, 0x0804, 0xa4d1,
+	0x080c, 0x9f20, 0x7003, 0x0200, 0x0804, 0x9ce4, 0x080c, 0x9f20,
+	0x7003, 0x0100, 0x700b, 0x0003, 0x700f, 0x2a00, 0x60c3, 0x0008,
+	0x0804, 0xa4d1, 0x080c, 0x9f20, 0x7003, 0x0100, 0x700b, 0x000b,
+	0x60c3, 0x0008, 0x0804, 0xa4d1, 0x0026, 0x00d6, 0x0036, 0x0046,
+	0x2019, 0x3200, 0x2021, 0x0800, 0x0040, 0x0026, 0x00d6, 0x0036,
+	0x0046, 0x2019, 0x2200, 0x2021, 0x0100, 0x080c, 0xada2, 0xb810,
+	0x9305, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, 0x687c, 0x700a,
+	0x6880, 0x700e, 0x9485, 0x0029, 0x7012, 0x004e, 0x003e, 0x00de,
+	0x080c, 0xa4bf, 0x721a, 0x9f95, 0x0000, 0x7222, 0x7027, 0xffff,
+	0x2071, 0x024c, 0x002e, 0x0005, 0x0026, 0x080c, 0xada2, 0x7003,
+	0x02ff, 0x7007, 0xfffc, 0x00d6, 0x2069, 0x1800, 0x687c, 0x700a,
+	0x6880, 0x700e, 0x00de, 0x7013, 0x2029, 0x0c10, 0x7003, 0x0100,
+	0x7007, 0x0000, 0x700b, 0xfc02, 0x700f, 0x0000, 0x0005, 0x0026,
+	0x00d6, 0x0036, 0x0046, 0x2019, 0x3300, 0x2021, 0x0800, 0x0040,
+	0x0026, 0x00d6, 0x0036, 0x0046, 0x2019, 0x2300, 0x2021, 0x0100,
+	0x080c, 0xada2, 0xb810, 0x9305, 0x7002, 0xb814, 0x7006, 0x2069,
+	0x1800, 0xb810, 0x9005, 0x1140, 0xb814, 0x9005, 0x1128, 0x700b,
+	0x00ff, 0x700f, 0xfffe, 0x0020, 0x687c, 0x700a, 0x6880, 0x700e,
+	0x0000, 0x9485, 0x0098, 0x7012, 0x004e, 0x003e, 0x00de, 0x080c,
+	0xa4bf, 0x721a, 0x7a08, 0x7222, 0x2f10, 0x7226, 0x2071, 0x024c,
+	0x002e, 0x0005, 0x080c, 0xa4bf, 0x721a, 0x7a08, 0x7222, 0x7814,
+	0x7026, 0x2071, 0x024c, 0x002e, 0x0005, 0x00b6, 0x00c6, 0x00d6,
+	0x00e6, 0x00f6, 0x2069, 0x0200, 0x2071, 0x0240, 0x6004, 0x908a,
+	0x0085, 0x0a0c, 0x0dc5, 0x908a, 0x0092, 0x1a0c, 0x0dc5, 0x6110,
+	0x2158, 0xb9c0, 0x2c78, 0x2061, 0x0100, 0x619a, 0x9082, 0x0085,
+	0x0033, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x0005, 0x9f8e,
+	0x9f9d, 0x9fa8, 0x9f8c, 0x9f8c, 0x9f8c, 0x9f8e, 0x9f8c, 0x9f8c,
+	0x9f8c, 0x9f8c, 0x9f8c, 0x9f8c, 0x080c, 0x0dc5, 0x0411, 0x60c3,
+	0x0000, 0x0026, 0x080c, 0x2bf0, 0x0228, 0x2011, 0x0101, 0x2204,
+	0xc0c5, 0x2012, 0x002e, 0x0804, 0xa4d1, 0x0431, 0x7808, 0x700a,
+	0x7814, 0x700e, 0x7017, 0xffff, 0x60c3, 0x000c, 0x0804, 0xa4d1,
+	0x04a1, 0x7003, 0x0003, 0x7007, 0x0300, 0x60c3, 0x0004, 0x0804,
+	0xa4d1, 0x0026, 0x080c, 0xada2, 0xb810, 0x9085, 0x8100, 0x7002,
 	0xb814, 0x7006, 0x2069, 0x1800, 0x687c, 0x700a, 0x6880, 0x700e,
-	0x2001, 0x0099, 0x7a20, 0x9296, 0x0005, 0x0108, 0xc0bc, 0x7012,
-	0x0804, 0x9db6, 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2c78,
-	0x2069, 0x0200, 0x2071, 0x0240, 0x7804, 0x908a, 0x0040, 0x0a0c,
-	0x0dd5, 0x908a, 0x0054, 0x1a0c, 0x0dd5, 0x7910, 0x2158, 0xb9c0,
-	0x2061, 0x0100, 0x619a, 0x9082, 0x0040, 0x0033, 0x00fe, 0x00ee,
-	0x00de, 0x00ce, 0x00be, 0x0005, 0x9e91, 0x9f4d, 0x9f20, 0xa06f,
-	0x9e8f, 0x9e8f, 0x9e8f, 0x9e8f, 0x9e8f, 0x9e8f, 0x9e8f, 0xa73e,
-	0xa746, 0xa74e, 0xa756, 0x9e8f, 0xab46, 0x9e8f, 0xa736, 0x080c,
-	0x0dd5, 0x0096, 0x780b, 0xffff, 0x080c, 0x9efc, 0x7914, 0x2148,
-	0xa978, 0x7956, 0xae64, 0x96b4, 0x00ff, 0x9686, 0x0008, 0x1148,
-	0xa8b4, 0x7032, 0xa8b8, 0x7036, 0xa8bc, 0x703a, 0xa8c0, 0x703e,
-	0x0008, 0x7132, 0xa97c, 0x9184, 0x000f, 0x1118, 0x2001, 0x0005,
-	0x0040, 0xd184, 0x0118, 0x2001, 0x0004, 0x0018, 0x9084, 0x0006,
-	0x8004, 0x2010, 0x785c, 0x9084, 0x00ff, 0x8007, 0x9205, 0x7042,
-	0xd1ac, 0x0158, 0x7047, 0x0002, 0x9686, 0x0008, 0x1118, 0x080c,
-	0x18dd, 0x0010, 0x080c, 0x1754, 0x0050, 0xd1b4, 0x0118, 0x7047,
-	0x0001, 0x0028, 0x7047, 0x0000, 0x9016, 0x2230, 0x0010, 0xaab0,
-	0xaeac, 0x726a, 0x766e, 0x20a9, 0x0008, 0x20e9, 0x0000, 0xa860,
-	0x20e0, 0xa85c, 0x9080, 0x0023, 0x2098, 0x20a1, 0x0252, 0x2069,
-	0x0200, 0x6813, 0x0018, 0x4003, 0x6813, 0x0008, 0x60c3, 0x0020,
-	0x6017, 0x0009, 0x2001, 0x1a02, 0x2003, 0x07d0, 0x2001, 0x1a01,
-	0x2003, 0x0009, 0x009e, 0x0005, 0x6813, 0x0008, 0xba8c, 0x8210,
-	0xb8cc, 0xd084, 0x0128, 0x7a4a, 0x7b14, 0x7b46, 0x722e, 0x732a,
-	0x9294, 0x00ff, 0xba8e, 0x8217, 0x721a, 0xba10, 0x9295, 0x0600,
-	0x7202, 0xba14, 0x7206, 0x2069, 0x1800, 0x6a7c, 0x720a, 0x6a80,
-	0x720e, 0x7013, 0x0829, 0x2f10, 0x7222, 0x7027, 0xffff, 0x0005,
-	0x00d6, 0x0096, 0x0081, 0x7814, 0x2048, 0xa890, 0x7002, 0xa88c,
-	0x7006, 0xa8b0, 0x700a, 0xa8ac, 0x700e, 0x60c3, 0x000c, 0x009e,
-	0x00de, 0x0804, 0xa32a, 0x6813, 0x0008, 0xb810, 0x9085, 0x0500,
-	0x7002, 0xb814, 0x7006, 0x2069, 0x1800, 0x687c, 0x700a, 0x6880,
-	0x700e, 0x7013, 0x0889, 0x080c, 0xa318, 0x721a, 0x7a08, 0x7222,
-	0x2f10, 0x7226, 0x2071, 0x024c, 0x0005, 0x00d6, 0x0096, 0x080c,
-	0xa04d, 0x7814, 0x2048, 0x080c, 0xcc84, 0x1130, 0x7814, 0x9084,
-	0x0700, 0x8007, 0x0033, 0x0010, 0x9006, 0x001b, 0x009e, 0x00de,
-	0x0005, 0x9f6b, 0x9fd4, 0x9fe4, 0xa00a, 0xa016, 0xa027, 0xa02f,
-	0x9f69, 0x080c, 0x0dd5, 0x0016, 0x0036, 0xa97c, 0x918c, 0x0003,
-	0x0118, 0x9186, 0x0003, 0x1198, 0xaba8, 0x7824, 0xd0cc, 0x1168,
-	0x7316, 0xa898, 0x701a, 0xa894, 0x701e, 0x003e, 0x001e, 0x2001,
-	0x19b0, 0x2004, 0x60c2, 0x0804, 0xa32a, 0xc3e5, 0x0c88, 0x9186,
-	0x0001, 0x190c, 0x0dd5, 0xaba8, 0x7824, 0xd0cc, 0x1904, 0x9fd1,
-	0x7316, 0xa898, 0x701a, 0xa894, 0x701e, 0xa8a4, 0x7026, 0xa8ac,
-	0x702e, 0x2009, 0x0018, 0x9384, 0x0300, 0x0570, 0xd3c4, 0x0110,
-	0xa8ac, 0x9108, 0xd3cc, 0x0110, 0xa8a4, 0x9108, 0x6810, 0x9085,
-	0x0010, 0x6812, 0x2011, 0x0258, 0x20e9, 0x0000, 0x22a0, 0x0156,
-	0x20a9, 0x0008, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x002c, 0x2098,
-	0x4003, 0x6810, 0x8000, 0x6812, 0x2011, 0x0240, 0x22a0, 0x20a9,
-	0x0005, 0x4003, 0x6810, 0xc084, 0x6812, 0x015e, 0x9184, 0x0003,
-	0x0118, 0x2019, 0x0245, 0x201a, 0x61c2, 0x003e, 0x001e, 0x0804,
-	0xa32a, 0xc3e5, 0x0804, 0x9f90, 0x2011, 0x0008, 0x2001, 0x180f,
-	0x2004, 0xd0a4, 0x0110, 0x2011, 0x0028, 0x7824, 0xd0cc, 0x1110,
-	0x7216, 0x0470, 0x0ce8, 0xc2e5, 0x2011, 0x0302, 0x0016, 0x782c,
-	0x701a, 0x7930, 0x711e, 0x9105, 0x0108, 0xc2dd, 0x001e, 0x7824,
-	0xd0cc, 0x0108, 0xc2e5, 0x7216, 0x7027, 0x0012, 0x702f, 0x0008,
-	0x7043, 0x7000, 0x7047, 0x0500, 0x704f, 0x000a, 0x2069, 0x0200,
-	0x6813, 0x0009, 0x2071, 0x0240, 0x700b, 0x2500, 0x60c3, 0x0032,
-	0x0804, 0xa32a, 0x2011, 0x0028, 0x7824, 0xd0cc, 0x1128, 0x7216,
-	0x60c3, 0x0018, 0x0804, 0xa32a, 0x0cd0, 0xc2e5, 0x2011, 0x0100,
-	0x7824, 0xd0cc, 0x0108, 0xc2e5, 0x7216, 0x702f, 0x0008, 0x7858,
-	0x9084, 0x00ff, 0x7036, 0x60c3, 0x0020, 0x0804, 0xa32a, 0x2011,
-	0x0008, 0x7824, 0xd0cc, 0x0108, 0xc2e5, 0x7216, 0x0c08, 0x0036,
-	0x7b14, 0x9384, 0xff00, 0x7816, 0x9384, 0x00ff, 0x8001, 0x1138,
-	0x7824, 0xd0cc, 0x0108, 0xc2e5, 0x7216, 0x003e, 0x0888, 0x0046,
-	0x2021, 0x0800, 0x0006, 0x7824, 0xd0cc, 0x000e, 0x0108, 0xc4e5,
-	0x7416, 0x004e, 0x701e, 0x003e, 0x0818, 0x00d6, 0x6813, 0x0008,
-	0xb810, 0x9085, 0x0700, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800,
-	0x687c, 0x700a, 0x6880, 0x700e, 0x7824, 0xd0cc, 0x1168, 0x7013,
-	0x0898, 0x080c, 0xa318, 0x721a, 0x7a08, 0x7222, 0x2f10, 0x7226,
-	0x2071, 0x024c, 0x00de, 0x0005, 0x7013, 0x0889, 0x0c90, 0x0016,
-	0x7814, 0x9084, 0x0700, 0x8007, 0x0013, 0x001e, 0x0005, 0xa07f,
-	0xa07f, 0xa081, 0xa07f, 0xa07f, 0xa07f, 0xa09b, 0xa07f, 0x080c,
-	0x0dd5, 0x7914, 0x918c, 0x08ff, 0x918d, 0xf600, 0x7916, 0x2009,
-	0x0003, 0x00b9, 0x2069, 0x1847, 0x6804, 0xd0bc, 0x0130, 0x682c,
-	0x9084, 0x00ff, 0x8007, 0x7032, 0x0010, 0x7033, 0x3f00, 0x60c3,
-	0x0001, 0x0804, 0xa32a, 0x2009, 0x0003, 0x0019, 0x7033, 0x7f00,
-	0x0cb0, 0x0016, 0x080c, 0xabfe, 0x001e, 0xb810, 0x9085, 0x0100,
-	0x7002, 0xb814, 0x7006, 0x2069, 0x1800, 0x6a7c, 0x720a, 0x6a80,
-	0x720e, 0x7013, 0x0888, 0x918d, 0x0008, 0x7116, 0x080c, 0xa318,
-	0x721a, 0x7a08, 0x7222, 0x2f10, 0x7226, 0x0005, 0x00b6, 0x00e6,
-	0x00d6, 0x00c6, 0x0066, 0x0056, 0x0046, 0x0036, 0x2061, 0x0100,
-	0x2071, 0x1800, 0x7160, 0x7810, 0x2058, 0x76dc, 0x96b4, 0x0028,
-	0x0110, 0x737c, 0x7480, 0x2500, 0x76dc, 0x96b4, 0x0028, 0x0140,
-	0x2001, 0x04ff, 0x6062, 0x6067, 0xffff, 0x636a, 0x646e, 0x0050,
-	0x2001, 0x00ff, 0x9085, 0x0400, 0x6062, 0x6067, 0xffff, 0x606b,
-	0x0000, 0x616e, 0xb8b8, 0x6073, 0x0530, 0x6077, 0x0008, 0xb88c,
+	0x7013, 0x0009, 0x0804, 0x9ef0, 0x0026, 0x080c, 0xada2, 0xb810,
+	0x9085, 0x8400, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, 0x687c,
+	0x700a, 0x6880, 0x700e, 0x2001, 0x0099, 0x7a20, 0x9296, 0x0005,
+	0x0108, 0xc0bc, 0x7012, 0x0804, 0x9f52, 0x0026, 0x080c, 0xada2,
+	0xb810, 0x9085, 0x8500, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800,
+	0x687c, 0x700a, 0x6880, 0x700e, 0x2001, 0x0099, 0x7a20, 0x9296,
+	0x0005, 0x0108, 0xc0bc, 0x7012, 0x0804, 0x9f52, 0x00b6, 0x00c6,
+	0x00d6, 0x00e6, 0x00f6, 0x2c78, 0x2069, 0x0200, 0x2071, 0x0240,
+	0x7804, 0x908a, 0x0040, 0x0a0c, 0x0dc5, 0x908a, 0x0054, 0x1a0c,
+	0x0dc5, 0x7910, 0x2158, 0xb9c0, 0x2061, 0x0100, 0x619a, 0x9082,
+	0x0040, 0x0033, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x0005,
+	0xa02d, 0xa0f4, 0xa0c7, 0xa216, 0xa02b, 0xa02b, 0xa02b, 0xa02b,
+	0xa02b, 0xa02b, 0xa02b, 0xa8ec, 0xa8f1, 0xa8f6, 0xa8fb, 0xa02b,
+	0xacea, 0xa02b, 0xa8e7, 0x080c, 0x0dc5, 0x0096, 0x780b, 0xffff,
+	0x080c, 0xa098, 0x7914, 0x2148, 0xa978, 0x7956, 0xae64, 0x96b4,
+	0x00ff, 0x9686, 0x0008, 0x1148, 0xa8b4, 0x7032, 0xa8b8, 0x7036,
+	0xa8bc, 0x703a, 0xa8c0, 0x703e, 0x0008, 0x7132, 0xa97c, 0x9184,
+	0x000f, 0x1118, 0x2001, 0x0005, 0x0040, 0xd184, 0x0118, 0x2001,
+	0x0004, 0x0018, 0x9084, 0x0006, 0x8004, 0x2010, 0x785c, 0x9084,
+	0x00ff, 0x8007, 0x9205, 0x7042, 0xd1ac, 0x0158, 0x7047, 0x0002,
+	0x9686, 0x0008, 0x1118, 0x080c, 0x18f1, 0x0010, 0x080c, 0x1768,
+	0x0050, 0xd1b4, 0x0118, 0x7047, 0x0001, 0x0028, 0x7047, 0x0000,
+	0x9016, 0x2230, 0x0010, 0xaab0, 0xaeac, 0x726a, 0x766e, 0x20a9,
+	0x0008, 0x20e9, 0x0000, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0023,
+	0x2098, 0x20a1, 0x0252, 0x2069, 0x0200, 0x6813, 0x0018, 0x4003,
+	0x6813, 0x0008, 0x60c3, 0x0020, 0x6017, 0x0009, 0x2001, 0x1a05,
+	0x2003, 0x07d0, 0x2001, 0x1a04, 0x2003, 0x0009, 0x009e, 0x0005,
+	0x6813, 0x0008, 0xba8c, 0x8210, 0xb8cc, 0xd084, 0x0180, 0x2001,
+	0x1ad1, 0x200c, 0x8108, 0x2102, 0x2001, 0x1ad0, 0x201c, 0x1218,
+	0x8318, 0x2302, 0x0ea0, 0x794a, 0x712e, 0x7b46, 0x732a, 0x9294,
+	0x00ff, 0xba8e, 0x8217, 0x721a, 0xba10, 0x9295, 0x0600, 0x7202,
+	0xba14, 0x7206, 0x2069, 0x1800, 0x6a7c, 0x720a, 0x6a80, 0x720e,
+	0x7013, 0x0829, 0x2f10, 0x7222, 0x7027, 0xffff, 0x0005, 0x00d6,
+	0x0096, 0x0081, 0x7814, 0x2048, 0xa890, 0x7002, 0xa88c, 0x7006,
+	0xa8b0, 0x700a, 0xa8ac, 0x700e, 0x60c3, 0x000c, 0x009e, 0x00de,
+	0x0804, 0xa4d1, 0x6813, 0x0008, 0xb810, 0x9085, 0x0500, 0x7002,
+	0xb814, 0x7006, 0x2069, 0x1800, 0x687c, 0x700a, 0x6880, 0x700e,
+	0x7013, 0x0889, 0x080c, 0xa4bf, 0x721a, 0x7a08, 0x7222, 0x2f10,
+	0x7226, 0x2071, 0x024c, 0x0005, 0x00d6, 0x0096, 0x080c, 0xa1f4,
+	0x7814, 0x2048, 0x080c, 0xce3d, 0x1130, 0x7814, 0x9084, 0x0700,
+	0x8007, 0x0033, 0x0010, 0x9006, 0x001b, 0x009e, 0x00de, 0x0005,
+	0xa112, 0xa17b, 0xa18b, 0xa1b1, 0xa1bd, 0xa1ce, 0xa1d6, 0xa110,
+	0x080c, 0x0dc5, 0x0016, 0x0036, 0xa97c, 0x918c, 0x0003, 0x0118,
+	0x9186, 0x0003, 0x1198, 0xaba8, 0x7824, 0xd0cc, 0x1168, 0x7316,
+	0xa898, 0x701a, 0xa894, 0x701e, 0x003e, 0x001e, 0x2001, 0x19b3,
+	0x2004, 0x60c2, 0x0804, 0xa4d1, 0xc3e5, 0x0c88, 0x9186, 0x0001,
+	0x190c, 0x0dc5, 0xaba8, 0x7824, 0xd0cc, 0x1904, 0xa178, 0x7316,
+	0xa898, 0x701a, 0xa894, 0x701e, 0xa8a4, 0x7026, 0xa8ac, 0x702e,
+	0x2009, 0x0018, 0x9384, 0x0300, 0x0570, 0xd3c4, 0x0110, 0xa8ac,
+	0x9108, 0xd3cc, 0x0110, 0xa8a4, 0x9108, 0x6810, 0x9085, 0x0010,
+	0x6812, 0x2011, 0x0258, 0x20e9, 0x0000, 0x22a0, 0x0156, 0x20a9,
+	0x0008, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x002c, 0x2098, 0x4003,
+	0x6810, 0x8000, 0x6812, 0x2011, 0x0240, 0x22a0, 0x20a9, 0x0005,
+	0x4003, 0x6810, 0xc0a4, 0x6812, 0x015e, 0x9184, 0x0003, 0x0118,
+	0x2019, 0x0245, 0x201a, 0x61c2, 0x003e, 0x001e, 0x0804, 0xa4d1,
+	0xc3e5, 0x0804, 0xa137, 0x2011, 0x0008, 0x2001, 0x180f, 0x2004,
+	0xd0a4, 0x0110, 0x2011, 0x0028, 0x7824, 0xd0cc, 0x1110, 0x7216,
+	0x0470, 0x0ce8, 0xc2e5, 0x2011, 0x0302, 0x0016, 0x782c, 0x701a,
+	0x7930, 0x711e, 0x9105, 0x0108, 0xc2dd, 0x001e, 0x7824, 0xd0cc,
+	0x0108, 0xc2e5, 0x7216, 0x7027, 0x0012, 0x702f, 0x0008, 0x7043,
+	0x7000, 0x7047, 0x0500, 0x704f, 0x000a, 0x2069, 0x0200, 0x6813,
+	0x0009, 0x2071, 0x0240, 0x700b, 0x2500, 0x60c3, 0x0032, 0x0804,
+	0xa4d1, 0x2011, 0x0028, 0x7824, 0xd0cc, 0x1128, 0x7216, 0x60c3,
+	0x0018, 0x0804, 0xa4d1, 0x0cd0, 0xc2e5, 0x2011, 0x0100, 0x7824,
+	0xd0cc, 0x0108, 0xc2e5, 0x7216, 0x702f, 0x0008, 0x7858, 0x9084,
+	0x00ff, 0x7036, 0x60c3, 0x0020, 0x0804, 0xa4d1, 0x2011, 0x0008,
+	0x7824, 0xd0cc, 0x0108, 0xc2e5, 0x7216, 0x0c08, 0x0036, 0x7b14,
+	0x9384, 0xff00, 0x7816, 0x9384, 0x00ff, 0x8001, 0x1138, 0x7824,
+	0xd0cc, 0x0108, 0xc2e5, 0x7216, 0x003e, 0x0888, 0x0046, 0x2021,
+	0x0800, 0x0006, 0x7824, 0xd0cc, 0x000e, 0x0108, 0xc4e5, 0x7416,
+	0x004e, 0x701e, 0x003e, 0x0818, 0x00d6, 0x6813, 0x0008, 0xb810,
+	0x9085, 0x0700, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, 0x687c,
+	0x700a, 0x6880, 0x700e, 0x7824, 0xd0cc, 0x1168, 0x7013, 0x0898,
+	0x080c, 0xa4bf, 0x721a, 0x7a08, 0x7222, 0x2f10, 0x7226, 0x2071,
+	0x024c, 0x00de, 0x0005, 0x7013, 0x0889, 0x0c90, 0x0016, 0x7814,
+	0x9084, 0x0700, 0x8007, 0x0013, 0x001e, 0x0005, 0xa226, 0xa226,
+	0xa228, 0xa226, 0xa226, 0xa226, 0xa242, 0xa226, 0x080c, 0x0dc5,
+	0x7914, 0x918c, 0x08ff, 0x918d, 0xf600, 0x7916, 0x2009, 0x0003,
+	0x00b9, 0x2069, 0x1847, 0x6804, 0xd0bc, 0x0130, 0x682c, 0x9084,
+	0x00ff, 0x8007, 0x7032, 0x0010, 0x7033, 0x3f00, 0x60c3, 0x0001,
+	0x0804, 0xa4d1, 0x2009, 0x0003, 0x0019, 0x7033, 0x7f00, 0x0cb0,
+	0x0016, 0x080c, 0xada2, 0x001e, 0xb810, 0x9085, 0x0100, 0x7002,
+	0xb814, 0x7006, 0x2069, 0x1800, 0x6a7c, 0x720a, 0x6a80, 0x720e,
+	0x7013, 0x0888, 0x918d, 0x0008, 0x7116, 0x080c, 0xa4bf, 0x721a,
+	0x7a08, 0x7222, 0x2f10, 0x7226, 0x0005, 0x00b6, 0x00e6, 0x00d6,
+	0x00c6, 0x0066, 0x0056, 0x0046, 0x0036, 0x2061, 0x0100, 0x2071,
+	0x1800, 0x7160, 0x7810, 0x2058, 0x76dc, 0x96b4, 0x0028, 0x0110,
+	0x737c, 0x7480, 0x2500, 0x76dc, 0x96b4, 0x0028, 0x0140, 0x2001,
+	0x04ff, 0x6062, 0x6067, 0xffff, 0x636a, 0x646e, 0x0050, 0x2001,
+	0x00ff, 0x9085, 0x0400, 0x6062, 0x6067, 0xffff, 0x606b, 0x0000,
+	0x616e, 0xb8b8, 0x6073, 0x0530, 0x6077, 0x0008, 0xb88c, 0x8000,
+	0x9084, 0x00ff, 0xb88e, 0x8007, 0x9085, 0x0020, 0x607a, 0x607f,
+	0x0000, 0x2b00, 0x6082, 0x6087, 0xffff, 0x7814, 0x0096, 0x2048,
+	0xa838, 0x608a, 0xa834, 0x608e, 0xa848, 0x60c6, 0xa844, 0x60ca,
+	0x009e, 0xb86c, 0x60ce, 0x60ab, 0x0036, 0x60af, 0x95d5, 0x60d7,
+	0x0000, 0x2001, 0x1837, 0x2004, 0x9084, 0x0028, 0x0128, 0x609f,
+	0x0000, 0x2001, 0x0092, 0x0048, 0x6028, 0xc0bd, 0x602a, 0x609f,
+	0x00ff, 0x6027, 0xffff, 0x2001, 0x00b2, 0x6016, 0x2009, 0x07d0,
+	0x080c, 0x878e, 0x003e, 0x004e, 0x005e, 0x006e, 0x00ce, 0x00de,
+	0x00ee, 0x00be, 0x0005, 0x00b6, 0x00e6, 0x00d6, 0x00c6, 0x0066,
+	0x0056, 0x0046, 0x0036, 0x2061, 0x0100, 0x2071, 0x1800, 0x7160,
+	0x7810, 0x2058, 0xb8a0, 0x2028, 0x76dc, 0xd6ac, 0x1168, 0x9582,
+	0x007e, 0x1250, 0x2500, 0x9094, 0xff80, 0x1130, 0x9080, 0x33b1,
+	0x2015, 0x9294, 0x00ff, 0x0020, 0xb910, 0xba14, 0x737c, 0x7480,
+	0x70dc, 0xd0ac, 0x1130, 0x9582, 0x007e, 0x1218, 0x9584, 0xff80,
+	0x0138, 0x9185, 0x0400, 0x6062, 0x6266, 0x636a, 0x646e, 0x0030,
+	0x6063, 0x0400, 0x6266, 0x606b, 0x0000, 0x616e, 0xb8b8, 0x6072,
+	0x6077, 0x0000, 0xb864, 0xd0a4, 0x0110, 0x6077, 0x0008, 0xb88c,
 	0x8000, 0x9084, 0x00ff, 0xb88e, 0x8007, 0x9085, 0x0020, 0x607a,
 	0x607f, 0x0000, 0x2b00, 0x6082, 0x6087, 0xffff, 0x7814, 0x0096,
 	0x2048, 0xa838, 0x608a, 0xa834, 0x608e, 0xa848, 0x60c6, 0xa844,
 	0x60ca, 0x009e, 0xb86c, 0x60ce, 0x60ab, 0x0036, 0x60af, 0x95d5,
-	0x60d7, 0x0000, 0x2001, 0x1837, 0x2004, 0x9084, 0x0028, 0x0128,
-	0x609f, 0x0000, 0x2001, 0x0092, 0x0048, 0x6028, 0xc0bd, 0x602a,
-	0x609f, 0x00ff, 0x6027, 0xffff, 0x2001, 0x00b2, 0x6016, 0x2009,
-	0x07d0, 0x080c, 0x863b, 0x003e, 0x004e, 0x005e, 0x006e, 0x00ce,
-	0x00de, 0x00ee, 0x00be, 0x0005, 0x00b6, 0x00e6, 0x00d6, 0x00c6,
-	0x0066, 0x0056, 0x0046, 0x0036, 0x2061, 0x0100, 0x2071, 0x1800,
-	0x7160, 0x7810, 0x2058, 0xb8a0, 0x2028, 0x76dc, 0xd6ac, 0x1168,
-	0x9582, 0x007e, 0x1250, 0x2500, 0x9094, 0xff80, 0x1130, 0x9080,
-	0x3384, 0x2015, 0x9294, 0x00ff, 0x0020, 0xb910, 0xba14, 0x737c,
-	0x7480, 0x70dc, 0xd0ac, 0x1130, 0x9582, 0x007e, 0x1218, 0x9584,
-	0xff80, 0x0138, 0x9185, 0x0400, 0x6062, 0x6266, 0x636a, 0x646e,
-	0x0030, 0x6063, 0x0400, 0x6266, 0x606b, 0x0000, 0x616e, 0xb8b8,
-	0x6072, 0x6077, 0x0000, 0xb864, 0xd0a4, 0x0110, 0x6077, 0x0008,
-	0xb88c, 0x8000, 0x9084, 0x00ff, 0xb88e, 0x8007, 0x9085, 0x0020,
-	0x607a, 0x607f, 0x0000, 0x2b00, 0x6082, 0x6087, 0xffff, 0x7814,
-	0x0096, 0x2048, 0xa838, 0x608a, 0xa834, 0x608e, 0xa848, 0x60c6,
-	0xa844, 0x60ca, 0x009e, 0xb86c, 0x60ce, 0x60ab, 0x0036, 0x60af,
-	0x95d5, 0x60d7, 0x0000, 0xbac0, 0x629e, 0x00f6, 0x2079, 0x0140,
-	0x7803, 0x0000, 0x00fe, 0x2009, 0x0092, 0x6116, 0x2009, 0x07d0,
-	0x080c, 0x863b, 0x003e, 0x004e, 0x005e, 0x006e, 0x00ce, 0x00de,
-	0x00ee, 0x00be, 0x0005, 0x00b6, 0x0096, 0x00e6, 0x00d6, 0x00c6,
-	0x0056, 0x0046, 0x0036, 0x2061, 0x0100, 0x2071, 0x1800, 0x7810,
-	0x2058, 0xb8a0, 0x2028, 0xb910, 0xba14, 0x737c, 0x7480, 0x7820,
-	0x90be, 0x0006, 0x0904, 0xa287, 0x90be, 0x000a, 0x1904, 0xa243,
-	0xb8c0, 0x609e, 0x7814, 0x2048, 0xa87c, 0xd0fc, 0x0558, 0xaf90,
-	0x9784, 0xff00, 0x9105, 0x6062, 0x873f, 0x9784, 0xff00, 0x0006,
-	0x7814, 0x2048, 0xa878, 0xc0fc, 0x9005, 0x000e, 0x1160, 0xaf94,
-	0x87ff, 0x0198, 0x2039, 0x0098, 0x9705, 0x6072, 0x7808, 0x6082,
-	0x2f00, 0x6086, 0x0038, 0x9185, 0x2200, 0x6062, 0x6073, 0x0129,
-	0x6077, 0x0000, 0xb8c0, 0x609e, 0x0050, 0x2039, 0x0029, 0x9705,
-	0x6072, 0x0cc0, 0x9185, 0x0200, 0x6062, 0x6073, 0x2029, 0xa87c,
-	0xd0fc, 0x0118, 0xaf94, 0x87ff, 0x1120, 0x2f00, 0x6082, 0x7808,
-	0x6086, 0x6266, 0x636a, 0x646e, 0x6077, 0x0000, 0xb88c, 0x8000,
-	0x9084, 0x00ff, 0xb88e, 0x8007, 0x607a, 0x607f, 0x0000, 0xa838,
-	0x608a, 0xa834, 0x608e, 0xa848, 0x60c6, 0xa844, 0x60ca, 0xb86c,
-	0x60ce, 0x60af, 0x95d5, 0x60d7, 0x0000, 0x080c, 0xabe3, 0x2009,
-	0x07d0, 0x60c4, 0x9084, 0xfff0, 0x9005, 0x0110, 0x2009, 0x1b58,
-	0x080c, 0x863b, 0x003e, 0x004e, 0x005e, 0x00ce, 0x00de, 0x00ee,
-	0x009e, 0x00be, 0x0005, 0x7804, 0x9086, 0x0040, 0x0904, 0xa2c3,
-	0x9185, 0x0100, 0x6062, 0x6266, 0x636a, 0x646e, 0x6073, 0x0809,
-	0x6077, 0x0008, 0x60af, 0x95d5, 0x60d7, 0x0000, 0xb88c, 0x8000,
-	0x9084, 0x00ff, 0xb88e, 0x8007, 0x607a, 0x607f, 0x0000, 0x2f00,
-	0x6082, 0x7808, 0x6086, 0x7814, 0x2048, 0xa838, 0x608a, 0xa834,
-	0x608e, 0xa848, 0x60c6, 0xa844, 0x60ca, 0xb86c, 0x60ce, 0xbac0,
-	0x629e, 0x080c, 0xabe3, 0x2009, 0x07d0, 0x60c4, 0x9084, 0xfff0,
-	0x9005, 0x0110, 0x2009, 0x1b58, 0x080c, 0x863b, 0x003e, 0x004e,
-	0x005e, 0x00ce, 0x00de, 0x00ee, 0x009e, 0x00be, 0x0005, 0x7814,
-	0x2048, 0xa87c, 0x9084, 0x0003, 0x9086, 0x0002, 0x0904, 0xa2df,
-	0x9185, 0x0100, 0x6062, 0x6266, 0x636a, 0x646e, 0x6073, 0x0880,
-	0x6077, 0x0008, 0xb88c, 0x8000, 0x9084, 0x00ff, 0xb88e, 0x8007,
-	0x607a, 0x7838, 0x607e, 0x2f00, 0x6086, 0x7808, 0x6082, 0xa890,
-	0x608a, 0xa88c, 0x608e, 0xa8b0, 0x60c6, 0xa8ac, 0x60ca, 0xa8ac,
-	0x7930, 0x9108, 0x7932, 0xa8b0, 0x792c, 0x9109, 0x792e, 0xb86c,
-	0x60ce, 0x60af, 0x95d5, 0x60d7, 0x0000, 0xbac0, 0x629e, 0x080c,
-	0xabc0, 0x0804, 0xa273, 0xb8cc, 0xd084, 0x0148, 0xb88c, 0x7814,
-	0x2048, 0xb88c, 0x784a, 0xa836, 0x2900, 0xa83a, 0xb046, 0x9185,
-	0x0600, 0x6062, 0x6266, 0x636a, 0x646e, 0x6073, 0x0829, 0x6077,
-	0x0000, 0x60af, 0x9575, 0x60d7, 0x0000, 0x0804, 0xa256, 0x9185,
-	0x0700, 0x6062, 0x6266, 0x636a, 0x646e, 0x7824, 0xd0cc, 0x7826,
-	0x0118, 0x6073, 0x0889, 0x0010, 0x6073, 0x0898, 0x6077, 0x0000,
-	0xb88c, 0x8000, 0x9084, 0x00ff, 0xb88e, 0x8007, 0x607a, 0x607f,
-	0x0000, 0x2f00, 0x6086, 0x7808, 0x6082, 0xa838, 0x608a, 0xa834,
-	0x608e, 0xa848, 0x60c6, 0xa844, 0x60ca, 0xb86c, 0x60ce, 0x60af,
-	0x95d5, 0x60d7, 0x0000, 0xbac0, 0x629e, 0x7824, 0xd0cc, 0x0120,
-	0x080c, 0xabe3, 0x0804, 0xa273, 0x080c, 0xabc0, 0x0804, 0xa273,
-	0x7a10, 0x00b6, 0x2258, 0xba8c, 0x8210, 0x9294, 0x00ff, 0xba8e,
-	0x00be, 0x8217, 0x0005, 0x00d6, 0x2069, 0x19e6, 0x6843, 0x0001,
-	0x00de, 0x0005, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x00f1, 0x080c,
-	0x862d, 0x0005, 0x0016, 0x2001, 0x180c, 0x200c, 0x9184, 0x0600,
-	0x9086, 0x0600, 0x0128, 0x0089, 0x080c, 0x862d, 0x001e, 0x0005,
-	0xc1e5, 0x2001, 0x180c, 0x2102, 0x2001, 0x19e7, 0x2003, 0x0000,
-	0x2001, 0x19ef, 0x2003, 0x0000, 0x0c88, 0x0006, 0x6014, 0x9084,
-	0x1804, 0x9085, 0x0009, 0x6016, 0x000e, 0x0005, 0x0016, 0x00c6,
-	0x0006, 0x2061, 0x0100, 0x61a4, 0x60a7, 0x95f5, 0x6014, 0x9084,
-	0x1804, 0x9085, 0x0008, 0x6016, 0x000e, 0xa001, 0xa001, 0xa001,
-	0x61a6, 0x00ce, 0x001e, 0x0005, 0x00c6, 0x00d6, 0x0016, 0x0026,
-	0x2061, 0x0100, 0x2069, 0x0140, 0x080c, 0x743e, 0x11c0, 0x2001,
-	0x1a02, 0x2004, 0x9005, 0x15d0, 0x080c, 0x74ee, 0x1160, 0x2061,
-	0x0100, 0x6020, 0xd0b4, 0x1120, 0x6024, 0xd084, 0x090c, 0x0dd5,
-	0x080c, 0x862d, 0x0458, 0x00c6, 0x2061, 0x19e6, 0x00c8, 0x6904,
-	0x9194, 0x4000, 0x0540, 0x0811, 0x080c, 0x2d5e, 0x00c6, 0x2061,
-	0x19e6, 0x6128, 0x9192, 0x0008, 0x1258, 0x8108, 0x612a, 0x6124,
-	0x00ce, 0x81ff, 0x0198, 0x080c, 0x862d, 0x080c, 0xa34d, 0x0070,
-	0x6124, 0x91e5, 0x0000, 0x0140, 0x080c, 0xeb8e, 0x080c, 0x8636,
-	0x2009, 0x0014, 0x080c, 0xafbe, 0x00ce, 0x0000, 0x002e, 0x001e,
-	0x00de, 0x00ce, 0x0005, 0x2001, 0x1a02, 0x2004, 0x9005, 0x1db0,
-	0x00c6, 0x2061, 0x19e6, 0x6128, 0x9192, 0x0003, 0x1e08, 0x8108,
-	0x612a, 0x00ce, 0x080c, 0x862d, 0x080c, 0x5f6c, 0x2009, 0x1846,
-	0x2114, 0x8210, 0x220a, 0x0c10, 0x0096, 0x00c6, 0x00d6, 0x00e6,
-	0x0016, 0x0026, 0x080c, 0x8643, 0x2071, 0x19e6, 0x713c, 0x81ff,
-	0x0904, 0xa456, 0x2061, 0x0100, 0x2069, 0x0140, 0x080c, 0x743e,
-	0x11e0, 0x0036, 0x2019, 0x0002, 0x080c, 0xa6ac, 0x003e, 0x713c,
-	0x2160, 0x080c, 0xeb8e, 0x2009, 0x004a, 0x6220, 0x9296, 0x0009,
-	0x1130, 0x6114, 0x2148, 0xa87b, 0x0006, 0x2009, 0x004a, 0x080c,
-	0xafbe, 0x080c, 0x74ee, 0x0804, 0xa456, 0x080c, 0xa462, 0x0904,
-	0xa456, 0x6904, 0xd1f4, 0x0904, 0xa45d, 0x080c, 0x2d5e, 0x00c6,
-	0x703c, 0x9065, 0x090c, 0x0dd5, 0x6020, 0x00ce, 0x9086, 0x0006,
-	0x1528, 0x61c8, 0x60c4, 0x9105, 0x1508, 0x2009, 0x180c, 0x2104,
-	0xd0d4, 0x01e0, 0x6214, 0x9294, 0x1800, 0x1128, 0x6224, 0x9294,
-	0x0002, 0x1560, 0x0030, 0xc0d4, 0x200a, 0xd0cc, 0x0110, 0x080c,
-	0x2c90, 0x6014, 0x9084, 0xe7fd, 0x9085, 0x0010, 0x6016, 0x703c,
-	0x2060, 0x2009, 0x0049, 0x080c, 0xafbe, 0x00c0, 0x0036, 0x2019,
-	0x0001, 0x080c, 0xa6ac, 0x003e, 0x713c, 0x2160, 0x080c, 0xeb8e,
-	0x2009, 0x004a, 0x6220, 0x9296, 0x0009, 0x1130, 0x6114, 0x2148,
-	0xa87b, 0x0006, 0x2009, 0x004a, 0x080c, 0xafbe, 0x002e, 0x001e,
-	0x00ee, 0x00de, 0x00ce, 0x009e, 0x0005, 0xd1ec, 0x1904, 0xa40d,
-	0x0804, 0xa40f, 0x00d6, 0x00c6, 0x0096, 0x703c, 0x9065, 0x090c,
-	0x0dd5, 0x2001, 0x0306, 0x200c, 0x9184, 0x0030, 0x0904, 0xa50b,
-	0x9184, 0x0048, 0x9086, 0x0008, 0x1904, 0xa50b, 0x2009, 0x0206,
-	0x2104, 0x2009, 0x0203, 0x210c, 0x9106, 0x1904, 0xa50b, 0x2009,
-	0x022a, 0x2104, 0x2009, 0x022f, 0x210c, 0x9116, 0x9084, 0x03ff,
-	0x918c, 0x03ff, 0x9294, 0x0400, 0x0110, 0x9102, 0x0030, 0x2010,
-	0x2100, 0x9202, 0x2009, 0x0228, 0x9102, 0x9082, 0x0005, 0x0250,
-	0x2008, 0x2001, 0x013b, 0x2004, 0x8004, 0x8004, 0x8004, 0x9102,
-	0x1a04, 0xa50b, 0x2009, 0x1a80, 0x2104, 0x8000, 0x0208, 0x200a,
-	0x2069, 0x0100, 0x6914, 0x918c, 0x0184, 0x918d, 0x0010, 0x6916,
-	0x69c8, 0x2011, 0x0020, 0x68c8, 0x9106, 0x1570, 0x8211, 0x1dd8,
-	0x2001, 0x0306, 0x2003, 0x4800, 0x2001, 0x009a, 0x2003, 0x0004,
-	0x2001, 0x1a65, 0x2003, 0x0000, 0x2001, 0x1a6e, 0x2003, 0x0000,
-	0x6a88, 0x698c, 0x2200, 0x9105, 0x1120, 0x2c10, 0x080c, 0x1beb,
-	0x0040, 0x6014, 0x2048, 0xaa3a, 0xa936, 0x6ac4, 0x69c8, 0xa946,
-	0xaa4a, 0x0126, 0x00c6, 0x2091, 0x2400, 0x002e, 0x080c, 0x1c84,
-	0x190c, 0x0dd5, 0x012e, 0x0090, 0x2009, 0x1a81, 0x2104, 0x8000,
-	0x0208, 0x200a, 0x69c8, 0x2011, 0x0020, 0x8211, 0x1df0, 0x68c8,
-	0x9106, 0x1dc0, 0x69c4, 0x68c8, 0x9105, 0x0160, 0x6824, 0xd08c,
-	0x0110, 0x6827, 0x0002, 0x7048, 0xc085, 0x704a, 0x0079, 0x7048,
-	0xc084, 0x704a, 0x2009, 0x07d0, 0x080c, 0x863b, 0x9006, 0x009e,
-	0x00ce, 0x00de, 0x0005, 0x9085, 0x0001, 0x0cc8, 0x0026, 0x00e6,
-	0x2071, 0x19e6, 0x7048, 0xd084, 0x01d8, 0x713c, 0x81ff, 0x01c0,
-	0x2071, 0x0100, 0x9188, 0x0008, 0x2114, 0x928e, 0x0006, 0x1138,
-	0x7014, 0x9084, 0x1984, 0x9085, 0x0012, 0x7016, 0x0048, 0x928e,
-	0x0009, 0x0db0, 0x7014, 0x9084, 0x1984, 0x9085, 0x0016, 0x7016,
-	0x00ee, 0x002e, 0x0005, 0x00b6, 0x00e6, 0x00d6, 0x00c6, 0x0066,
-	0x0056, 0x0046, 0x0006, 0x0126, 0x2091, 0x8000, 0x6010, 0x2058,
-	0xbca0, 0x2071, 0x19e6, 0x7018, 0x2058, 0x8bff, 0x0190, 0xb8a0,
-	0x9406, 0x0118, 0xb854, 0x2058, 0x0cc0, 0x6014, 0x0096, 0x2048,
-	0xac6c, 0xad70, 0xae78, 0x009e, 0x080c, 0x67cb, 0x0110, 0x9085,
-	0x0001, 0x012e, 0x000e, 0x004e, 0x005e, 0x006e, 0x00ce, 0x00de,
-	0x00ee, 0x00be, 0x0005, 0x080c, 0x9d39, 0x7003, 0x1200, 0x7838,
-	0x7012, 0x783c, 0x7016, 0x00c6, 0x7820, 0x9086, 0x0004, 0x1148,
-	0x7810, 0x9005, 0x0130, 0x00b6, 0x2058, 0xb810, 0xb914, 0x00be,
-	0x0020, 0x2061, 0x1800, 0x607c, 0x6180, 0x9084, 0x00ff, 0x700a,
-	0x710e, 0x00ce, 0x60c3, 0x002c, 0x0804, 0xa32a, 0x080c, 0x9d39,
-	0x7003, 0x0f00, 0x7808, 0xd09c, 0x0128, 0xb810, 0x9084, 0x00ff,
-	0x700a, 0xb814, 0x700e, 0x60c3, 0x0008, 0x0804, 0xa32a, 0x0156,
-	0x080c, 0x9d84, 0x7003, 0x0200, 0x080c, 0x8696, 0x20a9, 0x0006,
-	0x2011, 0xffec, 0x2019, 0xffed, 0x9ef0, 0x0002, 0x2305, 0x2072,
-	0x8e70, 0x2205, 0x2072, 0x8e70, 0x9398, 0x0002, 0x9290, 0x0002,
-	0x1f04, 0xa5a6, 0x60c3, 0x001c, 0x015e, 0x0804, 0xa32a, 0x0016,
-	0x0026, 0x080c, 0x9d60, 0x080c, 0x9d72, 0x9e80, 0x0004, 0x20e9,
-	0x0000, 0x20a0, 0x7814, 0x0096, 0x2048, 0xa800, 0x2048, 0xa860,
-	0x20e0, 0xa85c, 0x9080, 0x0021, 0x2098, 0x009e, 0x7808, 0x9088,
-	0x0002, 0x21a8, 0x9192, 0x0010, 0x1250, 0x4003, 0x9080, 0x0004,
-	0x8003, 0x60c2, 0x080c, 0xa32a, 0x002e, 0x001e, 0x0005, 0x20a9,
-	0x0010, 0x4003, 0x080c, 0xabe9, 0x20a1, 0x0240, 0x22a8, 0x4003,
-	0x0c68, 0x080c, 0x9d39, 0x7003, 0x6200, 0x7808, 0x700e, 0x60c3,
-	0x0008, 0x0804, 0xa32a, 0x0016, 0x0026, 0x080c, 0x9d39, 0x20e9,
-	0x0000, 0x20a1, 0x024c, 0x7814, 0x0096, 0x2048, 0xa800, 0x2048,
-	0xa860, 0x20e0, 0xa85c, 0x9080, 0x0023, 0x2098, 0x009e, 0x7808,
-	0x9088, 0x0002, 0x21a8, 0x4003, 0x8003, 0x60c2, 0x080c, 0xa32a,
-	0x002e, 0x001e, 0x0005, 0x00e6, 0x00c6, 0x0006, 0x0126, 0x2091,
-	0x8000, 0x2071, 0x19e6, 0x700c, 0x2060, 0x8cff, 0x0178, 0x080c,
-	0xce8e, 0x1110, 0x080c, 0xb905, 0x600c, 0x0006, 0x080c, 0xd0fa,
-	0x080c, 0xaf43, 0x080c, 0xa761, 0x00ce, 0x0c78, 0x2c00, 0x700e,
-	0x700a, 0x012e, 0x000e, 0x00ce, 0x00ee, 0x0005, 0x0126, 0x0156,
-	0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0026, 0x0016, 0x0006,
-	0x2091, 0x8000, 0x2001, 0x180c, 0x200c, 0x918c, 0xe7ff, 0x2102,
-	0x2069, 0x0100, 0x2079, 0x0140, 0x2071, 0x19e6, 0x7024, 0x2060,
-	0x8cff, 0x01f8, 0x080c, 0xa356, 0x6ac0, 0x68c3, 0x0000, 0x080c,
-	0x8636, 0x00c6, 0x2061, 0x0100, 0x080c, 0xad3a, 0x00ce, 0x20a9,
-	0x01f4, 0x0461, 0x2009, 0x0013, 0x080c, 0xafbe, 0x000e, 0x001e,
-	0x002e, 0x006e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x015e, 0x012e,
-	0x0005, 0x2001, 0x1800, 0x2004, 0x9096, 0x0001, 0x0d78, 0x9096,
-	0x0004, 0x0d60, 0x080c, 0x8636, 0x6814, 0x9084, 0x0001, 0x0110,
-	0x68a7, 0x95f5, 0x6817, 0x0008, 0x68c3, 0x0000, 0x2011, 0x5f16,
-	0x080c, 0x85b0, 0x20a9, 0x01f4, 0x0009, 0x08c0, 0x6824, 0xd094,
-	0x0140, 0x6827, 0x0004, 0x7804, 0x9084, 0x4000, 0x190c, 0x2d5e,
-	0x0090, 0xd084, 0x0118, 0x6827, 0x0001, 0x0010, 0x1f04, 0xa68e,
-	0x7804, 0x9084, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2d4e,
-	0x9006, 0x080c, 0x2d4e, 0x0005, 0x0126, 0x0156, 0x00f6, 0x00e6,
-	0x00d6, 0x00c6, 0x0066, 0x0026, 0x0016, 0x0006, 0x2091, 0x8000,
-	0x2001, 0x180c, 0x200c, 0x918c, 0xdbff, 0x2102, 0x2069, 0x0100,
-	0x2079, 0x0140, 0x2071, 0x19e6, 0x703c, 0x2060, 0x8cff, 0x0904,
-	0xa717, 0x9386, 0x0002, 0x1128, 0x6814, 0x9084, 0x0002, 0x0904,
-	0xa717, 0x68af, 0x95f5, 0x6817, 0x0010, 0x2009, 0x00fa, 0x8109,
-	0x1df0, 0x69c6, 0x68cb, 0x0008, 0x080c, 0x8643, 0x080c, 0x2038,
-	0x2001, 0x0032, 0x6920, 0xd1bc, 0x0130, 0x8001, 0x1dd8, 0x692c,
-	0x918d, 0x0008, 0x692e, 0x20a9, 0x03e8, 0x6824, 0xd094, 0x0140,
-	0x6827, 0x0004, 0x7804, 0x9084, 0x4000, 0x190c, 0x2d5e, 0x0090,
-	0xd08c, 0x0118, 0x6827, 0x0002, 0x0010, 0x1f04, 0xa6ed, 0x7804,
-	0x9084, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2d4e, 0x9006,
-	0x080c, 0x2d4e, 0x6827, 0x4000, 0x6824, 0x83ff, 0x1140, 0x2009,
-	0x0049, 0x6020, 0x9086, 0x0009, 0x0110, 0x080c, 0xafbe, 0x000e,
+	0x60d7, 0x0000, 0xbac0, 0x629e, 0x00f6, 0x2079, 0x0140, 0x7803,
+	0x0000, 0x00fe, 0x2009, 0x0092, 0x6116, 0x2009, 0x07d0, 0x080c,
+	0x878e, 0x003e, 0x004e, 0x005e, 0x006e, 0x00ce, 0x00de, 0x00ee,
+	0x00be, 0x0005, 0x00b6, 0x0096, 0x00e6, 0x00d6, 0x00c6, 0x0056,
+	0x0046, 0x0036, 0x2061, 0x0100, 0x2071, 0x1800, 0x7810, 0x2058,
+	0xb8a0, 0x2028, 0xb910, 0xba14, 0x737c, 0x7480, 0x7820, 0x90be,
+	0x0006, 0x0904, 0xa42e, 0x90be, 0x000a, 0x1904, 0xa3ea, 0xb8c0,
+	0x609e, 0x7814, 0x2048, 0xa87c, 0xd0fc, 0x0558, 0xaf90, 0x9784,
+	0xff00, 0x9105, 0x6062, 0x873f, 0x9784, 0xff00, 0x0006, 0x7814,
+	0x2048, 0xa878, 0xc0fc, 0x9005, 0x000e, 0x1160, 0xaf94, 0x87ff,
+	0x0198, 0x2039, 0x0098, 0x9705, 0x6072, 0x7808, 0x6082, 0x2f00,
+	0x6086, 0x0038, 0x9185, 0x2200, 0x6062, 0x6073, 0x0129, 0x6077,
+	0x0000, 0xb8c0, 0x609e, 0x0050, 0x2039, 0x0029, 0x9705, 0x6072,
+	0x0cc0, 0x9185, 0x0200, 0x6062, 0x6073, 0x2029, 0xa87c, 0xd0fc,
+	0x0118, 0xaf94, 0x87ff, 0x1120, 0x2f00, 0x6082, 0x7808, 0x6086,
+	0x6266, 0x636a, 0x646e, 0x6077, 0x0000, 0xb88c, 0x8000, 0x9084,
+	0x00ff, 0xb88e, 0x8007, 0x607a, 0x607f, 0x0000, 0xa838, 0x608a,
+	0xa834, 0x608e, 0xa848, 0x60c6, 0xa844, 0x60ca, 0xb86c, 0x60ce,
+	0x60af, 0x95d5, 0x60d7, 0x0000, 0x080c, 0xad87, 0x2009, 0x07d0,
+	0x60c4, 0x9084, 0xfff0, 0x9005, 0x0110, 0x2009, 0x1b58, 0x080c,
+	0x878e, 0x003e, 0x004e, 0x005e, 0x00ce, 0x00de, 0x00ee, 0x009e,
+	0x00be, 0x0005, 0x7804, 0x9086, 0x0040, 0x0904, 0xa46a, 0x9185,
+	0x0100, 0x6062, 0x6266, 0x636a, 0x646e, 0x6073, 0x0809, 0x6077,
+	0x0008, 0x60af, 0x95d5, 0x60d7, 0x0000, 0xb88c, 0x8000, 0x9084,
+	0x00ff, 0xb88e, 0x8007, 0x607a, 0x607f, 0x0000, 0x2f00, 0x6082,
+	0x7808, 0x6086, 0x7814, 0x2048, 0xa838, 0x608a, 0xa834, 0x608e,
+	0xa848, 0x60c6, 0xa844, 0x60ca, 0xb86c, 0x60ce, 0xbac0, 0x629e,
+	0x080c, 0xad87, 0x2009, 0x07d0, 0x60c4, 0x9084, 0xfff0, 0x9005,
+	0x0110, 0x2009, 0x1b58, 0x080c, 0x878e, 0x003e, 0x004e, 0x005e,
+	0x00ce, 0x00de, 0x00ee, 0x009e, 0x00be, 0x0005, 0x7814, 0x2048,
+	0xa87c, 0x9084, 0x0003, 0x9086, 0x0002, 0x0904, 0xa486, 0x9185,
+	0x0100, 0x6062, 0x6266, 0x636a, 0x646e, 0x6073, 0x0880, 0x6077,
+	0x0008, 0xb88c, 0x8000, 0x9084, 0x00ff, 0xb88e, 0x8007, 0x607a,
+	0x7838, 0x607e, 0x2f00, 0x6086, 0x7808, 0x6082, 0xa890, 0x608a,
+	0xa88c, 0x608e, 0xa8b0, 0x60c6, 0xa8ac, 0x60ca, 0xa8ac, 0x7930,
+	0x9108, 0x7932, 0xa8b0, 0x792c, 0x9109, 0x792e, 0xb86c, 0x60ce,
+	0x60af, 0x95d5, 0x60d7, 0x0000, 0xbac0, 0x629e, 0x080c, 0xad64,
+	0x0804, 0xa41a, 0xb8cc, 0xd084, 0x0148, 0xb88c, 0x7814, 0x2048,
+	0xb88c, 0x784a, 0xa836, 0x2900, 0xa83a, 0xb046, 0x9185, 0x0600,
+	0x6062, 0x6266, 0x636a, 0x646e, 0x6073, 0x0829, 0x6077, 0x0000,
+	0x60af, 0x9575, 0x60d7, 0x0000, 0x0804, 0xa3fd, 0x9185, 0x0700,
+	0x6062, 0x6266, 0x636a, 0x646e, 0x7824, 0xd0cc, 0x7826, 0x0118,
+	0x6073, 0x0889, 0x0010, 0x6073, 0x0898, 0x6077, 0x0000, 0xb88c,
+	0x8000, 0x9084, 0x00ff, 0xb88e, 0x8007, 0x607a, 0x607f, 0x0000,
+	0x2f00, 0x6086, 0x7808, 0x6082, 0xa838, 0x608a, 0xa834, 0x608e,
+	0xa848, 0x60c6, 0xa844, 0x60ca, 0xb86c, 0x60ce, 0x60af, 0x95d5,
+	0x60d7, 0x0000, 0xbac0, 0x629e, 0x7824, 0xd0cc, 0x0120, 0x080c,
+	0xad87, 0x0804, 0xa41a, 0x080c, 0xad64, 0x0804, 0xa41a, 0x7a10,
+	0x00b6, 0x2258, 0xba8c, 0x8210, 0x9294, 0x00ff, 0xba8e, 0x00be,
+	0x8217, 0x0005, 0x00d6, 0x2069, 0x19e9, 0x6843, 0x0001, 0x00de,
+	0x0005, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x00f1, 0x080c, 0x8780,
+	0x0005, 0x0016, 0x2001, 0x180c, 0x200c, 0x9184, 0x0600, 0x9086,
+	0x0600, 0x0128, 0x0089, 0x080c, 0x8780, 0x001e, 0x0005, 0xc1e5,
+	0x2001, 0x180c, 0x2102, 0x2001, 0x19ea, 0x2003, 0x0000, 0x2001,
+	0x19f2, 0x2003, 0x0000, 0x0c88, 0x0006, 0x6014, 0x9084, 0x1804,
+	0x9085, 0x0009, 0x6016, 0x000e, 0x0005, 0x0016, 0x00c6, 0x0006,
+	0x2061, 0x0100, 0x61a4, 0x60a7, 0x95f5, 0x6014, 0x9084, 0x1804,
+	0x9085, 0x0008, 0x6016, 0x000e, 0xa001, 0xa001, 0xa001, 0x61a6,
+	0x00ce, 0x001e, 0x0005, 0x00c6, 0x00d6, 0x0016, 0x0026, 0x2061,
+	0x0100, 0x2069, 0x0140, 0x080c, 0x7563, 0x11c0, 0x2001, 0x1a05,
+	0x2004, 0x9005, 0x15d0, 0x080c, 0x7610, 0x1160, 0x2061, 0x0100,
+	0x6020, 0xd0b4, 0x1120, 0x6024, 0xd084, 0x090c, 0x0dc5, 0x080c,
+	0x8780, 0x0458, 0x00c6, 0x2061, 0x19e9, 0x00c8, 0x6904, 0x9194,
+	0x4000, 0x0540, 0x0811, 0x080c, 0x2d6b, 0x00c6, 0x2061, 0x19e9,
+	0x6128, 0x9192, 0x0008, 0x1258, 0x8108, 0x612a, 0x6124, 0x00ce,
+	0x81ff, 0x0198, 0x080c, 0x8780, 0x080c, 0xa4f4, 0x0070, 0x6124,
+	0x91e5, 0x0000, 0x0140, 0x080c, 0xedaa, 0x080c, 0x8789, 0x2009,
+	0x0014, 0x080c, 0xb166, 0x00ce, 0x0000, 0x002e, 0x001e, 0x00de,
+	0x00ce, 0x0005, 0x2001, 0x1a05, 0x2004, 0x9005, 0x1db0, 0x00c6,
+	0x2061, 0x19e9, 0x6128, 0x9192, 0x0003, 0x1e08, 0x8108, 0x612a,
+	0x00ce, 0x080c, 0x8780, 0x080c, 0x5fe0, 0x2009, 0x1846, 0x2114,
+	0x8210, 0x220a, 0x0c10, 0x0096, 0x00c6, 0x00d6, 0x00e6, 0x0016,
+	0x0026, 0x080c, 0x8796, 0x2071, 0x19e9, 0x713c, 0x81ff, 0x0904,
+	0xa5fd, 0x2061, 0x0100, 0x2069, 0x0140, 0x080c, 0x7563, 0x11e0,
+	0x0036, 0x2019, 0x0002, 0x080c, 0xa85d, 0x003e, 0x713c, 0x2160,
+	0x080c, 0xedaa, 0x2009, 0x004a, 0x6220, 0x9296, 0x0009, 0x1130,
+	0x6114, 0x2148, 0xa87b, 0x0006, 0x2009, 0x004a, 0x080c, 0xb166,
+	0x080c, 0x7610, 0x0804, 0xa5fd, 0x080c, 0xa609, 0x0904, 0xa5fd,
+	0x6904, 0xd1f4, 0x0904, 0xa604, 0x080c, 0x2d6b, 0x00c6, 0x703c,
+	0x9065, 0x090c, 0x0dc5, 0x6020, 0x00ce, 0x9086, 0x0006, 0x1528,
+	0x61c8, 0x60c4, 0x9105, 0x1508, 0x2009, 0x180c, 0x2104, 0xd0d4,
+	0x01e0, 0x6214, 0x9294, 0x1800, 0x1128, 0x6224, 0x9294, 0x0002,
+	0x1560, 0x0030, 0xc0d4, 0x200a, 0xd0cc, 0x0110, 0x080c, 0x2c9d,
+	0x6014, 0x9084, 0xe7fd, 0x9085, 0x0010, 0x6016, 0x703c, 0x2060,
+	0x2009, 0x0049, 0x080c, 0xb166, 0x00c0, 0x0036, 0x2019, 0x0001,
+	0x080c, 0xa85d, 0x003e, 0x713c, 0x2160, 0x080c, 0xedaa, 0x2009,
+	0x004a, 0x6220, 0x9296, 0x0009, 0x1130, 0x6114, 0x2148, 0xa87b,
+	0x0006, 0x2009, 0x004a, 0x080c, 0xb166, 0x002e, 0x001e, 0x00ee,
+	0x00de, 0x00ce, 0x009e, 0x0005, 0xd1ec, 0x1904, 0xa5b4, 0x0804,
+	0xa5b6, 0x00d6, 0x00c6, 0x0096, 0x703c, 0x9065, 0x090c, 0x0dc5,
+	0x2001, 0x0306, 0x200c, 0x9184, 0x0030, 0x0904, 0xa6bc, 0x9184,
+	0x0048, 0x9086, 0x0008, 0x1904, 0xa6bc, 0x2009, 0x0206, 0x2104,
+	0x2009, 0x0203, 0x210c, 0x9106, 0x1904, 0xa6bc, 0x2009, 0x022a,
+	0x2104, 0x2009, 0x022f, 0x210c, 0x9116, 0x9084, 0x03ff, 0x918c,
+	0x03ff, 0x9294, 0x0400, 0x0110, 0x9102, 0x0030, 0x2010, 0x2100,
+	0x9202, 0x2009, 0x0228, 0x9102, 0x9082, 0x0005, 0x0250, 0x2008,
+	0x2001, 0x013b, 0x2004, 0x8004, 0x8004, 0x8004, 0x9102, 0x1a04,
+	0xa6bc, 0x2009, 0x1a85, 0x2104, 0x8000, 0x0208, 0x200a, 0x2069,
+	0x0100, 0x6914, 0x918c, 0x1984, 0x918d, 0x0010, 0x6916, 0x69c8,
+	0x2011, 0x0020, 0x68c8, 0x9106, 0x15c0, 0x8211, 0x1dd8, 0x2001,
+	0x0306, 0x2003, 0x4800, 0x2001, 0x009a, 0x2003, 0x0004, 0x2001,
+	0x1a6a, 0x2003, 0x0000, 0x2001, 0x1a73, 0x2003, 0x0000, 0x6a88,
+	0x698c, 0x2200, 0x9105, 0x1170, 0x0096, 0x6014, 0x2048, 0xa87c,
+	0xc0dc, 0xa87e, 0xa880, 0xc0fc, 0xa882, 0x009e, 0x2c10, 0x080c,
+	0x1c01, 0x0040, 0x6014, 0x2048, 0xaa3a, 0xa936, 0x6ac4, 0x69c8,
+	0xa946, 0xaa4a, 0x0126, 0x00c6, 0x2091, 0x2400, 0x002e, 0x080c,
+	0x1c9a, 0x190c, 0x0dc5, 0x012e, 0x0090, 0x2009, 0x1a86, 0x2104,
+	0x8000, 0x0208, 0x200a, 0x69c8, 0x2011, 0x0020, 0x8211, 0x1df0,
+	0x68c8, 0x9106, 0x1dc0, 0x69c4, 0x68c8, 0x9105, 0x0160, 0x6824,
+	0xd08c, 0x0110, 0x6827, 0x0002, 0x7048, 0xc085, 0x704a, 0x0079,
+	0x7048, 0xc084, 0x704a, 0x2009, 0x07d0, 0x080c, 0x878e, 0x9006,
+	0x009e, 0x00ce, 0x00de, 0x0005, 0x9085, 0x0001, 0x0cc8, 0x0026,
+	0x00e6, 0x2071, 0x19e9, 0x7048, 0xd084, 0x01d8, 0x713c, 0x81ff,
+	0x01c0, 0x2071, 0x0100, 0x9188, 0x0008, 0x2114, 0x928e, 0x0006,
+	0x1138, 0x7014, 0x9084, 0x1984, 0x9085, 0x0012, 0x7016, 0x0048,
+	0x928e, 0x0009, 0x0db0, 0x7014, 0x9084, 0x1984, 0x9085, 0x0016,
+	0x7016, 0x00ee, 0x002e, 0x0005, 0x00b6, 0x00e6, 0x00d6, 0x00c6,
+	0x0066, 0x0056, 0x0046, 0x0006, 0x0126, 0x2091, 0x8000, 0x6010,
+	0x2058, 0xbca0, 0x2071, 0x19e9, 0x7018, 0x2058, 0x8bff, 0x0190,
+	0xb8a0, 0x9406, 0x0118, 0xb854, 0x2058, 0x0cc0, 0x6014, 0x0096,
+	0x2048, 0xac6c, 0xad70, 0xae78, 0x009e, 0x080c, 0x6849, 0x0110,
+	0x9085, 0x0001, 0x012e, 0x000e, 0x004e, 0x005e, 0x006e, 0x00ce,
+	0x00de, 0x00ee, 0x00be, 0x0005, 0x080c, 0x9ed5, 0x7003, 0x1200,
+	0x7838, 0x7012, 0x783c, 0x7016, 0x00c6, 0x7820, 0x9086, 0x0004,
+	0x1148, 0x7810, 0x9005, 0x0130, 0x00b6, 0x2058, 0xb810, 0xb914,
+	0x00be, 0x0020, 0x2061, 0x1800, 0x607c, 0x6180, 0x9084, 0x00ff,
+	0x700a, 0x710e, 0x00ce, 0x60c3, 0x002c, 0x0804, 0xa4d1, 0x080c,
+	0x9ed5, 0x7003, 0x0f00, 0x7808, 0xd09c, 0x0128, 0xb810, 0x9084,
+	0x00ff, 0x700a, 0xb814, 0x700e, 0x60c3, 0x0008, 0x0804, 0xa4d1,
+	0x0156, 0x080c, 0x9f20, 0x7003, 0x0200, 0x080c, 0x8812, 0x20a9,
+	0x0006, 0x2011, 0xffec, 0x2019, 0xffed, 0x9ef0, 0x0002, 0x2305,
+	0x2072, 0x8e70, 0x2205, 0x2072, 0x8e70, 0x9398, 0x0002, 0x9290,
+	0x0002, 0x1f04, 0xa757, 0x60c3, 0x001c, 0x015e, 0x0804, 0xa4d1,
+	0x0016, 0x0026, 0x080c, 0x9efc, 0x080c, 0x9f0e, 0x9e80, 0x0004,
+	0x20e9, 0x0000, 0x20a0, 0x7814, 0x0096, 0x2048, 0xa800, 0x2048,
+	0xa860, 0x20e0, 0xa85c, 0x9080, 0x0021, 0x2098, 0x009e, 0x7808,
+	0x9088, 0x0002, 0x21a8, 0x9192, 0x0010, 0x1250, 0x4003, 0x9080,
+	0x0004, 0x8003, 0x60c2, 0x080c, 0xa4d1, 0x002e, 0x001e, 0x0005,
+	0x20a9, 0x0010, 0x4003, 0x080c, 0xad8d, 0x20a1, 0x0240, 0x22a8,
+	0x4003, 0x0c68, 0x080c, 0x9ed5, 0x7003, 0x6200, 0x7808, 0x700e,
+	0x60c3, 0x0008, 0x0804, 0xa4d1, 0x0016, 0x0026, 0x080c, 0x9ed5,
+	0x20e9, 0x0000, 0x20a1, 0x024c, 0x7814, 0x0096, 0x2048, 0xa800,
+	0x2048, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0023, 0x2098, 0x009e,
+	0x7808, 0x9088, 0x0002, 0x21a8, 0x4003, 0x8003, 0x60c2, 0x080c,
+	0xa4d1, 0x002e, 0x001e, 0x0005, 0x00e6, 0x00c6, 0x0006, 0x0126,
+	0x2091, 0x8000, 0x2071, 0x19e9, 0x700c, 0x2060, 0x8cff, 0x0178,
+	0x080c, 0xd047, 0x1110, 0x080c, 0xbacb, 0x600c, 0x0006, 0x080c,
+	0xd2b3, 0x080c, 0xb0e7, 0x080c, 0xa905, 0x00ce, 0x0c78, 0x2c00,
+	0x700e, 0x700a, 0x012e, 0x000e, 0x00ce, 0x00ee, 0x0005, 0x0126,
+	0x0156, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0026, 0x0016,
+	0x0006, 0x2091, 0x8000, 0x2001, 0x180c, 0x200c, 0x918c, 0xe7ff,
+	0x2102, 0x2069, 0x0100, 0x2079, 0x0140, 0x2071, 0x19e9, 0x7024,
+	0x2060, 0x8cff, 0x01f8, 0x080c, 0xa4fd, 0x6ac0, 0x68c3, 0x0000,
+	0x080c, 0x8789, 0x00c6, 0x2061, 0x0100, 0x080c, 0xaede, 0x00ce,
+	0x20a9, 0x01f4, 0x0461, 0x2009, 0x0013, 0x080c, 0xb166, 0x000e,
 	0x001e, 0x002e, 0x006e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x015e,
-	0x012e, 0x0005, 0x00d6, 0x0126, 0x2091, 0x8000, 0x2069, 0x19e6,
-	0x6a06, 0x012e, 0x00de, 0x0005, 0x00d6, 0x0126, 0x2091, 0x8000,
-	0x2069, 0x19e6, 0x6a32, 0x012e, 0x00de, 0x0005, 0x080c, 0x9efc,
-	0x7854, 0x7032, 0x7042, 0x7047, 0x1000, 0x00f8, 0x080c, 0x9efc,
-	0x7854, 0x7032, 0x7042, 0x7047, 0x4000, 0x00b8, 0x080c, 0x9efc,
-	0x7854, 0x7032, 0x7042, 0x7047, 0x2000, 0x0078, 0x080c, 0x9efc,
-	0x7854, 0x7032, 0x7042, 0x7047, 0x0400, 0x0038, 0x080c, 0x9efc,
-	0x7854, 0x7032, 0x7042, 0x7047, 0x0200, 0x60c3, 0x0020, 0x0804,
-	0xa32a, 0x00e6, 0x2071, 0x19e6, 0x7020, 0x9005, 0x0110, 0x8001,
-	0x7022, 0x00ee, 0x0005, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0076,
-	0x0066, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x19e6, 0x7614,
-	0x2660, 0x2678, 0x2039, 0x0001, 0x87ff, 0x0904, 0xa806, 0x8cff,
-	0x0904, 0xa806, 0x6020, 0x9086, 0x0006, 0x1904, 0xa801, 0x88ff,
-	0x0138, 0x2800, 0x9c06, 0x1904, 0xa801, 0x2039, 0x0000, 0x0050,
-	0x6010, 0x9b06, 0x1904, 0xa801, 0x85ff, 0x0120, 0x6054, 0x9106,
-	0x1904, 0xa801, 0x7024, 0x9c06, 0x15b0, 0x2069, 0x0100, 0x68c0,
-	0x9005, 0x1160, 0x6824, 0xd084, 0x0148, 0x6827, 0x0001, 0x080c,
-	0x8636, 0x080c, 0xa88b, 0x7027, 0x0000, 0x0428, 0x080c, 0x8636,
-	0x6820, 0xd0b4, 0x0110, 0x68a7, 0x95f5, 0x6817, 0x0008, 0x68c3,
-	0x0000, 0x080c, 0xa88b, 0x7027, 0x0000, 0x0036, 0x2069, 0x0140,
-	0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2d4e,
-	0x9006, 0x080c, 0x2d4e, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110,
-	0x6827, 0x0001, 0x003e, 0x7014, 0x9c36, 0x1110, 0x660c, 0x7616,
-	0x7010, 0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x7012,
-	0x0010, 0x7013, 0x0000, 0x660c, 0x0066, 0x2c00, 0x9f06, 0x0110,
-	0x7e0e, 0x0008, 0x2678, 0x89ff, 0x1168, 0x600f, 0x0000, 0x6014,
-	0x0096, 0x2048, 0x080c, 0xcc84, 0x0110, 0x080c, 0xe6dd, 0x009e,
-	0x080c, 0xaf74, 0x080c, 0xa761, 0x88ff, 0x1190, 0x00ce, 0x0804,
-	0xa77c, 0x2c78, 0x600c, 0x2060, 0x0804, 0xa77c, 0x9006, 0x012e,
-	0x000e, 0x006e, 0x007e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x0005,
-	0x601b, 0x0000, 0x00ce, 0x98c5, 0x0001, 0x0c88, 0x00f6, 0x00e6,
-	0x00d6, 0x0096, 0x00c6, 0x0066, 0x0026, 0x0006, 0x0126, 0x2091,
-	0x8000, 0x2071, 0x19e6, 0x7638, 0x2660, 0x2678, 0x8cff, 0x0904,
-	0xa87a, 0x6020, 0x9086, 0x0006, 0x1904, 0xa875, 0x87ff, 0x0128,
-	0x2700, 0x9c06, 0x1904, 0xa875, 0x0040, 0x6010, 0x9b06, 0x15e8,
-	0x85ff, 0x0118, 0x6054, 0x9106, 0x15c0, 0x703c, 0x9c06, 0x1168,
-	0x0036, 0x2019, 0x0001, 0x080c, 0xa6ac, 0x7033, 0x0000, 0x9006,
-	0x703e, 0x7042, 0x7046, 0x704a, 0x003e, 0x7038, 0x9c36, 0x1110,
-	0x660c, 0x763a, 0x7034, 0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118,
-	0x2f00, 0x7036, 0x0010, 0x7037, 0x0000, 0x660c, 0x0066, 0x2c00,
-	0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0x6014,
-	0x2048, 0x080c, 0xcc84, 0x0110, 0x080c, 0xe6dd, 0x080c, 0xaf74,
-	0x87ff, 0x1198, 0x00ce, 0x0804, 0xa826, 0x2c78, 0x600c, 0x2060,
-	0x0804, 0xa826, 0x9006, 0x012e, 0x000e, 0x002e, 0x006e, 0x00ce,
-	0x009e, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x601b, 0x0000, 0x00ce,
-	0x97bd, 0x0001, 0x0c80, 0x00e6, 0x2071, 0x19e6, 0x2001, 0x1800,
-	0x2004, 0x9086, 0x0002, 0x1118, 0x7007, 0x0005, 0x0010, 0x7007,
-	0x0000, 0x00ee, 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x0066, 0x0026,
-	0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x19e6, 0x2c10, 0x7638,
-	0x2660, 0x2678, 0x8cff, 0x0540, 0x2200, 0x9c06, 0x1508, 0x7038,
-	0x9c36, 0x1110, 0x660c, 0x763a, 0x7034, 0x9c36, 0x1140, 0x2c00,
-	0x9f36, 0x0118, 0x2f00, 0x7036, 0x0010, 0x7037, 0x0000, 0x660c,
-	0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000,
-	0x6004, 0x9086, 0x0040, 0x090c, 0x9657, 0x9085, 0x0001, 0x0020,
-	0x2c78, 0x600c, 0x2060, 0x08b0, 0x012e, 0x000e, 0x002e, 0x006e,
-	0x00ce, 0x00ee, 0x00fe, 0x0005, 0x0096, 0x00f6, 0x00e6, 0x00d6,
-	0x00c6, 0x0066, 0x0026, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071,
-	0x19e6, 0x760c, 0x2660, 0x2678, 0x8cff, 0x0904, 0xa971, 0x6010,
-	0x00b6, 0x2058, 0xb8a0, 0x00be, 0x9206, 0x1904, 0xa96c, 0x7024,
-	0x9c06, 0x1520, 0x2069, 0x0100, 0x68c0, 0x9005, 0x0904, 0xa943,
-	0x080c, 0xa356, 0x68c3, 0x0000, 0x080c, 0xa88b, 0x7027, 0x0000,
+	0x012e, 0x0005, 0x2001, 0x1800, 0x2004, 0x9096, 0x0001, 0x0d78,
+	0x9096, 0x0004, 0x0d60, 0x080c, 0x8789, 0x6814, 0x9084, 0x0001,
+	0x0110, 0x68a7, 0x95f5, 0x6817, 0x0008, 0x68c3, 0x0000, 0x2011,
+	0x5f8a, 0x080c, 0x8703, 0x20a9, 0x01f4, 0x0009, 0x08c0, 0x6824,
+	0xd094, 0x0140, 0x6827, 0x0004, 0x7804, 0x9084, 0x4000, 0x190c,
+	0x2d6b, 0x0090, 0xd084, 0x0118, 0x6827, 0x0001, 0x0010, 0x1f04,
+	0xa83f, 0x7804, 0x9084, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c,
+	0x2d5b, 0x9006, 0x080c, 0x2d5b, 0x0005, 0x0126, 0x0156, 0x00f6,
+	0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0026, 0x0016, 0x0006, 0x2091,
+	0x8000, 0x2001, 0x180c, 0x200c, 0x918c, 0xdbff, 0x2102, 0x2069,
+	0x0100, 0x2079, 0x0140, 0x2071, 0x19e9, 0x703c, 0x2060, 0x8cff,
+	0x0904, 0xa8c8, 0x9386, 0x0002, 0x1128, 0x6814, 0x9084, 0x0002,
+	0x0904, 0xa8c8, 0x68af, 0x95f5, 0x6817, 0x0010, 0x2009, 0x00fa,
+	0x8109, 0x1df0, 0x69c6, 0x68cb, 0x0008, 0x080c, 0x8796, 0x080c,
+	0x2052, 0x2001, 0x0032, 0x6920, 0xd1bc, 0x0130, 0x8001, 0x1dd8,
+	0x692c, 0x918d, 0x0008, 0x692e, 0x20a9, 0x03e8, 0x6824, 0xd094,
+	0x0140, 0x6827, 0x0004, 0x7804, 0x9084, 0x4000, 0x190c, 0x2d6b,
+	0x0090, 0xd08c, 0x0118, 0x6827, 0x0002, 0x0010, 0x1f04, 0xa89e,
+	0x7804, 0x9084, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2d5b,
+	0x9006, 0x080c, 0x2d5b, 0x6827, 0x4000, 0x6824, 0x83ff, 0x1140,
+	0x2009, 0x0049, 0x6020, 0x9086, 0x0009, 0x0110, 0x080c, 0xb166,
+	0x000e, 0x001e, 0x002e, 0x006e, 0x00ce, 0x00de, 0x00ee, 0x00fe,
+	0x015e, 0x012e, 0x0005, 0x00d6, 0x0126, 0x2091, 0x8000, 0x2069,
+	0x19e9, 0x6a06, 0x012e, 0x00de, 0x0005, 0x00d6, 0x0126, 0x2091,
+	0x8000, 0x2069, 0x19e9, 0x6a32, 0x012e, 0x00de, 0x0005, 0x080c,
+	0xa098, 0x7047, 0x1000, 0x0098, 0x080c, 0xa098, 0x7047, 0x4000,
+	0x0070, 0x080c, 0xa098, 0x7047, 0x2000, 0x0048, 0x080c, 0xa098,
+	0x7047, 0x0400, 0x0020, 0x080c, 0xa098, 0x7047, 0x0200, 0x7854,
+	0x7032, 0x60c3, 0x0020, 0x0804, 0xa4d1, 0x00e6, 0x2071, 0x19e9,
+	0x7020, 0x9005, 0x0110, 0x8001, 0x7022, 0x00ee, 0x0005, 0x00f6,
+	0x00e6, 0x00d6, 0x00c6, 0x0076, 0x0066, 0x0006, 0x0126, 0x2091,
+	0x8000, 0x2071, 0x19e9, 0x7614, 0x2660, 0x2678, 0x2039, 0x0001,
+	0x87ff, 0x0904, 0xa9aa, 0x8cff, 0x0904, 0xa9aa, 0x6020, 0x9086,
+	0x0006, 0x1904, 0xa9a5, 0x88ff, 0x0138, 0x2800, 0x9c06, 0x1904,
+	0xa9a5, 0x2039, 0x0000, 0x0050, 0x6010, 0x9b06, 0x1904, 0xa9a5,
+	0x85ff, 0x0120, 0x6054, 0x9106, 0x1904, 0xa9a5, 0x7024, 0x9c06,
+	0x15b0, 0x2069, 0x0100, 0x68c0, 0x9005, 0x1160, 0x6824, 0xd084,
+	0x0148, 0x6827, 0x0001, 0x080c, 0x8789, 0x080c, 0xaa2f, 0x7027,
+	0x0000, 0x0428, 0x080c, 0x8789, 0x6820, 0xd0b4, 0x0110, 0x68a7,
+	0x95f5, 0x6817, 0x0008, 0x68c3, 0x0000, 0x080c, 0xaa2f, 0x7027,
+	0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138,
+	0x2001, 0x0100, 0x080c, 0x2d5b, 0x9006, 0x080c, 0x2d5b, 0x2069,
+	0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x7014,
+	0x9c36, 0x1110, 0x660c, 0x7616, 0x7010, 0x9c36, 0x1140, 0x2c00,
+	0x9f36, 0x0118, 0x2f00, 0x7012, 0x0010, 0x7013, 0x0000, 0x660c,
+	0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x89ff,
+	0x1168, 0x600f, 0x0000, 0x6014, 0x0096, 0x2048, 0x080c, 0xce3d,
+	0x0110, 0x080c, 0xe8e3, 0x009e, 0x080c, 0xb11a, 0x080c, 0xa905,
+	0x88ff, 0x1190, 0x00ce, 0x0804, 0xa920, 0x2c78, 0x600c, 0x2060,
+	0x0804, 0xa920, 0x9006, 0x012e, 0x000e, 0x006e, 0x007e, 0x00ce,
+	0x00de, 0x00ee, 0x00fe, 0x0005, 0x601b, 0x0000, 0x00ce, 0x98c5,
+	0x0001, 0x0c88, 0x00f6, 0x00e6, 0x00d6, 0x0096, 0x00c6, 0x0066,
+	0x0026, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x19e9, 0x7638,
+	0x2660, 0x2678, 0x8cff, 0x0904, 0xaa1e, 0x6020, 0x9086, 0x0006,
+	0x1904, 0xaa19, 0x87ff, 0x0128, 0x2700, 0x9c06, 0x1904, 0xaa19,
+	0x0040, 0x6010, 0x9b06, 0x15e8, 0x85ff, 0x0118, 0x6054, 0x9106,
+	0x15c0, 0x703c, 0x9c06, 0x1168, 0x0036, 0x2019, 0x0001, 0x080c,
+	0xa85d, 0x7033, 0x0000, 0x9006, 0x703e, 0x7042, 0x7046, 0x704a,
+	0x003e, 0x7038, 0x9c36, 0x1110, 0x660c, 0x763a, 0x7034, 0x9c36,
+	0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x7036, 0x0010, 0x7037,
+	0x0000, 0x660c, 0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008,
+	0x2678, 0x600f, 0x0000, 0x6014, 0x2048, 0x080c, 0xce3d, 0x0110,
+	0x080c, 0xe8e3, 0x080c, 0xb11a, 0x87ff, 0x1198, 0x00ce, 0x0804,
+	0xa9ca, 0x2c78, 0x600c, 0x2060, 0x0804, 0xa9ca, 0x9006, 0x012e,
+	0x000e, 0x002e, 0x006e, 0x00ce, 0x009e, 0x00de, 0x00ee, 0x00fe,
+	0x0005, 0x601b, 0x0000, 0x00ce, 0x97bd, 0x0001, 0x0c80, 0x00e6,
+	0x2071, 0x19e9, 0x2001, 0x1800, 0x2004, 0x9086, 0x0002, 0x1118,
+	0x7007, 0x0005, 0x0010, 0x7007, 0x0000, 0x00ee, 0x0005, 0x00f6,
+	0x00e6, 0x00c6, 0x0066, 0x0026, 0x0006, 0x0126, 0x2091, 0x8000,
+	0x2071, 0x19e9, 0x2c10, 0x7638, 0x2660, 0x2678, 0x8cff, 0x0540,
+	0x2200, 0x9c06, 0x1508, 0x7038, 0x9c36, 0x1110, 0x660c, 0x763a,
+	0x7034, 0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x7036,
+	0x0010, 0x7037, 0x0000, 0x660c, 0x2c00, 0x9f06, 0x0110, 0x7e0e,
+	0x0008, 0x2678, 0x600f, 0x0000, 0x6004, 0x9086, 0x0040, 0x090c,
+	0x97db, 0x9085, 0x0001, 0x0020, 0x2c78, 0x600c, 0x2060, 0x08b0,
+	0x012e, 0x000e, 0x002e, 0x006e, 0x00ce, 0x00ee, 0x00fe, 0x0005,
+	0x0096, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0026, 0x0006,
+	0x0126, 0x2091, 0x8000, 0x2071, 0x19e9, 0x760c, 0x2660, 0x2678,
+	0x8cff, 0x0904, 0xab15, 0x6010, 0x00b6, 0x2058, 0xb8a0, 0x00be,
+	0x9206, 0x1904, 0xab10, 0x7024, 0x9c06, 0x1520, 0x2069, 0x0100,
+	0x68c0, 0x9005, 0x0904, 0xaae7, 0x080c, 0xa4fd, 0x68c3, 0x0000,
+	0x080c, 0xaa2f, 0x7027, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04,
+	0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2d5b, 0x9006,
+	0x080c, 0x2d5b, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827,
+	0x0001, 0x003e, 0x700c, 0x9c36, 0x1110, 0x660c, 0x760e, 0x7008,
+	0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x700a, 0x0010,
+	0x700b, 0x0000, 0x660c, 0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e,
+	0x0008, 0x2678, 0x600f, 0x0000, 0x080c, 0xd036, 0x1180, 0x080c,
+	0x3274, 0x080c, 0xd047, 0x1518, 0x080c, 0xbacb, 0x0400, 0x080c,
+	0xaa2f, 0x6824, 0xd084, 0x09b0, 0x6827, 0x0001, 0x0898, 0x080c,
+	0xd047, 0x1118, 0x080c, 0xbacb, 0x0090, 0x6014, 0x2048, 0x080c,
+	0xce3d, 0x0168, 0x6020, 0x9086, 0x0003, 0x1508, 0xa867, 0x0103,
+	0xab7a, 0xa877, 0x0000, 0x080c, 0x6dbe, 0x080c, 0xd02a, 0x080c,
+	0xd2b3, 0x080c, 0xb11a, 0x080c, 0xa905, 0x00ce, 0x0804, 0xaa90,
+	0x2c78, 0x600c, 0x2060, 0x0804, 0xaa90, 0x012e, 0x000e, 0x002e,
+	0x006e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x009e, 0x0005, 0x6020,
+	0x9086, 0x0006, 0x1d20, 0x080c, 0xe8e3, 0x0c08, 0x00d6, 0x080c,
+	0x9f20, 0x7003, 0x0200, 0x7007, 0x0014, 0x60c3, 0x0014, 0x20e1,
+	0x0001, 0x2099, 0x198a, 0x20e9, 0x0000, 0x20a1, 0x0250, 0x20a9,
+	0x0004, 0x4003, 0x7023, 0x0004, 0x7027, 0x7878, 0x080c, 0xa4d1,
+	0x00de, 0x0005, 0x080c, 0x9f20, 0x700b, 0x0800, 0x7814, 0x9084,
+	0xff00, 0x700e, 0x7814, 0x9084, 0x00ff, 0x7022, 0x782c, 0x7026,
+	0x7858, 0x9084, 0x00ff, 0x9085, 0x0200, 0x7002, 0x7858, 0x9084,
+	0xff00, 0x8007, 0x7006, 0x60c2, 0x0804, 0xa4d1, 0x00b6, 0x00d6,
+	0x0016, 0x00d6, 0x2f68, 0x2009, 0x0035, 0x080c, 0xd4c0, 0x00de,
+	0x1904, 0xabc3, 0x080c, 0x9ed5, 0x7003, 0x1300, 0x782c, 0x080c,
+	0xacc9, 0x2068, 0x6820, 0x9086, 0x0003, 0x0560, 0x7810, 0x2058,
+	0xbaa0, 0x080c, 0xb051, 0x11d8, 0x9286, 0x007e, 0x1128, 0x700b,
+	0x00ff, 0x700f, 0xfffe, 0x0498, 0x9286, 0x007f, 0x1128, 0x700b,
+	0x00ff, 0x700f, 0xfffd, 0x0458, 0x9284, 0xff80, 0x0180, 0x9286,
+	0x0080, 0x1128, 0x700b, 0x00ff, 0x700f, 0xfffc, 0x0400, 0x92d8,
+	0x1000, 0x2b5c, 0xb810, 0x700a, 0xb814, 0x700e, 0x00c0, 0x6098,
+	0x700e, 0x00a8, 0x080c, 0xb051, 0x1130, 0x7810, 0x2058, 0xb8a0,
+	0x9082, 0x007e, 0x0250, 0x00d6, 0x2069, 0x181f, 0x2d04, 0x700a,
+	0x8d68, 0x2d04, 0x700e, 0x00de, 0x0010, 0x6034, 0x700e, 0x7838,
+	0x7012, 0x783c, 0x7016, 0x60c3, 0x000c, 0x001e, 0x00de, 0x080c,
+	0xa4d1, 0x00be, 0x0005, 0x781b, 0x0001, 0x7803, 0x0006, 0x001e,
+	0x00de, 0x00be, 0x0005, 0x792c, 0x9180, 0x0008, 0x200c, 0x9186,
+	0x0006, 0x01c0, 0x9186, 0x0003, 0x0904, 0xac3e, 0x9186, 0x0005,
+	0x0904, 0xac26, 0x9186, 0x0004, 0x05d8, 0x9186, 0x0008, 0x0904,
+	0xac2f, 0x7807, 0x0037, 0x782f, 0x0003, 0x7817, 0x1700, 0x080c,
+	0xaca6, 0x0005, 0x080c, 0xac67, 0x00d6, 0x0026, 0x792c, 0x2168,
+	0x2009, 0x4000, 0x6800, 0x0002, 0xac07, 0xac12, 0xac09, 0xac12,
+	0xac0e, 0xac07, 0xac07, 0xac12, 0xac12, 0xac12, 0xac12, 0xac07,
+	0xac07, 0xac07, 0xac07, 0xac07, 0xac12, 0xac07, 0xac12, 0x080c,
+	0x0dc5, 0x6824, 0xd0e4, 0x0110, 0xd0cc, 0x0110, 0x900e, 0x0010,
+	0x2009, 0x2000, 0x682c, 0x7022, 0x6830, 0x7026, 0x0804, 0xac60,
+	0x080c, 0xac67, 0x00d6, 0x0026, 0x792c, 0x2168, 0x2009, 0x4000,
+	0x6a00, 0x9286, 0x0002, 0x1108, 0x900e, 0x04d0, 0x080c, 0xac67,
+	0x00d6, 0x0026, 0x792c, 0x2168, 0x2009, 0x4000, 0x0488, 0x04b9,
+	0x00d6, 0x0026, 0x792c, 0x2168, 0x2009, 0x4000, 0x9286, 0x0005,
+	0x0118, 0x9286, 0x0002, 0x1108, 0x900e, 0x0410, 0x0441, 0x00d6,
+	0x0026, 0x792c, 0x2168, 0x6814, 0x6924, 0xc185, 0x6926, 0x0096,
+	0x2048, 0xa9ac, 0xa834, 0x9112, 0xa9b0, 0xa838, 0x009e, 0x9103,
+	0x7022, 0x7226, 0x792c, 0x9180, 0x0000, 0x2004, 0x908e, 0x0002,
+	0x0130, 0x908e, 0x0004, 0x0118, 0x2009, 0x4000, 0x0008, 0x900e,
+	0x712a, 0x60c3, 0x0018, 0x002e, 0x00de, 0x0804, 0xa4d1, 0x00b6,
+	0x0036, 0x0046, 0x0056, 0x0066, 0x080c, 0x9f20, 0x9006, 0x7003,
+	0x0200, 0x7938, 0x710a, 0x793c, 0x710e, 0x7810, 0x2058, 0xb8a0,
+	0x080c, 0xb051, 0x1118, 0x9092, 0x007e, 0x0268, 0x00d6, 0x2069,
+	0x181f, 0x2d2c, 0x8d68, 0x2d34, 0x90d8, 0x1000, 0x2b5c, 0xbb10,
+	0xbc14, 0x00de, 0x0028, 0x901e, 0x6498, 0x2029, 0x0000, 0x6634,
+	0x782c, 0x9080, 0x0008, 0x2004, 0x9086, 0x0003, 0x1128, 0x7512,
+	0x7616, 0x731a, 0x741e, 0x0020, 0x7312, 0x7416, 0x751a, 0x761e,
+	0x006e, 0x005e, 0x004e, 0x003e, 0x00be, 0x0005, 0x080c, 0x9f20,
+	0x7003, 0x0100, 0x782c, 0x700a, 0x7814, 0x700e, 0x700e, 0x60c3,
+	0x0008, 0x0804, 0xa4d1, 0x080c, 0x9ecc, 0x7003, 0x1400, 0x7838,
+	0x700a, 0x0079, 0x783c, 0x700e, 0x782c, 0x7012, 0x7830, 0x7016,
+	0x7834, 0x9084, 0x00ff, 0x8007, 0x701a, 0x60c3, 0x0010, 0x0804,
+	0xa4d1, 0x00e6, 0x2071, 0x0240, 0x0006, 0x00f6, 0x2078, 0x7810,
+	0x00b6, 0x2058, 0xb8cc, 0xd084, 0x0120, 0x7844, 0x702a, 0x7848,
+	0x702e, 0x00be, 0x00fe, 0x000e, 0x00ee, 0x0005, 0x080c, 0x9f17,
+	0x7003, 0x0100, 0x782c, 0x700a, 0x7814, 0x700e, 0x60c3, 0x0008,
+	0x0804, 0xa4d1, 0x0021, 0x60c3, 0x0000, 0x0804, 0xa4d1, 0x00d6,
+	0x080c, 0xada2, 0xb810, 0x9085, 0x0300, 0x7002, 0xb814, 0x7006,
+	0x2069, 0x1800, 0x687c, 0x700a, 0x6880, 0x700e, 0x7013, 0x0819,
+	0x080c, 0xa4bf, 0x721a, 0x2f10, 0x7222, 0x7a08, 0x7226, 0x2071,
+	0x024c, 0x00de, 0x0005, 0x00a9, 0x7914, 0x712a, 0x60c3, 0x0000,
+	0x60a7, 0x9575, 0x0026, 0x080c, 0x2bf0, 0x0228, 0x2011, 0x0101,
+	0x2204, 0xc0c5, 0x2012, 0x002e, 0x080c, 0xa4f4, 0x080c, 0x8780,
+	0x0005, 0x0036, 0x0096, 0x00d6, 0x00e6, 0x7858, 0x2048, 0xaa7c,
+	0x9296, 0x00c0, 0x9294, 0x00fd, 0xaa7e, 0xaa80, 0x9294, 0x0300,
+	0xaa82, 0xa96c, 0x9194, 0x00ff, 0xab74, 0x9384, 0x00ff, 0x908d,
+	0xc200, 0xa96e, 0x9384, 0xff00, 0x9215, 0xaa76, 0xa870, 0xaa78,
+	0xa87a, 0xaa72, 0x00d6, 0x2069, 0x0200, 0x080c, 0xada2, 0x00de,
+	0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, 0x000a, 0xa860, 0x20e0,
+	0xa85c, 0x9080, 0x001b, 0x2098, 0x4003, 0x60a3, 0x0035, 0xaa68,
+	0x9294, 0x7000, 0x9286, 0x3000, 0x0110, 0x60a3, 0x0037, 0x00ee,
+	0x00de, 0x009e, 0x003e, 0x0005, 0x900e, 0x7814, 0x0096, 0x2048,
+	0xa87c, 0xd0fc, 0x01c0, 0x9084, 0x0003, 0x11a8, 0x2001, 0x180c,
+	0x2004, 0xd0bc, 0x0180, 0x7824, 0xd0cc, 0x1168, 0xd0c4, 0x1158,
+	0xa8a8, 0x9005, 0x1140, 0x2001, 0x180c, 0x200c, 0xc1d5, 0x2102,
+	0x2009, 0x19b4, 0x210c, 0x009e, 0x918d, 0x0092, 0x0010, 0x2009,
+	0x0096, 0x60ab, 0x0036, 0x6116, 0x0005, 0x2009, 0x0009, 0x00a0,
+	0x2009, 0x000a, 0x0088, 0x2009, 0x000b, 0x0070, 0x2009, 0x000c,
+	0x0058, 0x2009, 0x000d, 0x0040, 0x2009, 0x000e, 0x0028, 0x2009,
+	0x000f, 0x0010, 0x2009, 0x0008, 0x6912, 0x0005, 0x080c, 0x9ed5,
+	0x0016, 0x0026, 0x0096, 0x00d6, 0x7814, 0x2048, 0x7013, 0x0138,
+	0x2001, 0x1837, 0x2004, 0x9084, 0x0028, 0x1138, 0x2001, 0x197d,
+	0x2004, 0x9086, 0xaaaa, 0x1904, 0xae47, 0x7003, 0x5400, 0x00c6,
+	0x2061, 0x1800, 0x607c, 0x9084, 0x00ff, 0xa998, 0x810f, 0x918c,
+	0xff00, 0x9105, 0x700a, 0x6080, 0x700e, 0xa998, 0x918c, 0xff00,
+	0x7112, 0x20a9, 0x0004, 0x2009, 0x1805, 0x2e10, 0x9290, 0x0006,
+	0x2104, 0x2012, 0x8108, 0x8210, 0x1f04, 0xadd8, 0x20a9, 0x0004,
+	0x2009, 0x1801, 0x2104, 0x2012, 0x8108, 0x8210, 0x1f04, 0xade2,
+	0xa860, 0x20e0, 0xa85c, 0x9080, 0x0029, 0x2098, 0x2009, 0x0006,
+	0x20a9, 0x0001, 0x4002, 0x8007, 0x2012, 0x8210, 0x8109, 0x1dc0,
+	0x00d6, 0x2069, 0x0200, 0x080c, 0xad8d, 0x00de, 0x2071, 0x0240,
+	0x2011, 0x0240, 0x2009, 0x0002, 0x20a9, 0x0001, 0x4002, 0x8007,
+	0x2012, 0x8210, 0x8109, 0x1dc0, 0x2009, 0x0008, 0x20a9, 0x0001,
+	0x4002, 0x8007, 0x2012, 0x8210, 0x8109, 0x1dc0, 0xa85c, 0x9080,
+	0x0031, 0x2098, 0x2009, 0x0008, 0x20a9, 0x0001, 0x4002, 0x8007,
+	0x2012, 0x8210, 0x8109, 0x1dc0, 0x00ce, 0x60c3, 0x004c, 0x60a3,
+	0x0056, 0x60a7, 0x9575, 0x2001, 0x1837, 0x2004, 0x9084, 0x0028,
+	0x1168, 0x080c, 0x7563, 0x0150, 0x6028, 0xc0bd, 0x602a, 0x6014,
+	0x9084, 0x1804, 0x9085, 0x0029, 0x6016, 0x0010, 0x080c, 0xa4d1,
+	0x080c, 0x8780, 0x00de, 0x009e, 0x002e, 0x001e, 0x0005, 0x00e6,
+	0x2071, 0x0240, 0x2001, 0x2200, 0x9085, 0x00ff, 0x7002, 0x7007,
+	0xffff, 0x2071, 0x0100, 0x709b, 0x00ff, 0x00ee, 0x0804, 0xadbd,
+	0x080c, 0x9ed5, 0x0016, 0x0026, 0x0096, 0x00d6, 0x7814, 0x2048,
+	0x7013, 0x0138, 0x7003, 0x5500, 0x00c6, 0xa89c, 0x9084, 0x00ff,
+	0xa998, 0x810f, 0x918c, 0xff00, 0x9105, 0x700a, 0xa99c, 0x918c,
+	0xff00, 0xa8a0, 0x9084, 0x00ff, 0x9105, 0x700e, 0xa998, 0x918c,
+	0xff00, 0x2061, 0x1800, 0x607c, 0x9084, 0x00ff, 0x910d, 0x7112,
+	0x6180, 0x7116, 0x2009, 0x0008, 0xa860, 0x20e0, 0xa85c, 0x9080,
+	0x0029, 0x2098, 0x2e10, 0x9290, 0x0006, 0x20a9, 0x0001, 0x4002,
+	0x8007, 0x2012, 0x8210, 0x8109, 0x1dc0, 0x20a9, 0x0004, 0x2009,
+	0x1805, 0x2104, 0x2012, 0x8108, 0x8210, 0x1f04, 0xae99, 0x20a9,
+	0x0002, 0x2009, 0x1801, 0x2104, 0x2012, 0x8108, 0x8210, 0x1f04,
+	0xaea3, 0x00d6, 0x0016, 0x2069, 0x0200, 0x080c, 0xad8d, 0x001e,
+	0x00de, 0x2071, 0x0240, 0x20a9, 0x0002, 0x2009, 0x1803, 0x2011,
+	0x0240, 0x2104, 0x2012, 0x8108, 0x8210, 0x1f04, 0xaeb9, 0x2009,
+	0x0008, 0x4002, 0x8007, 0x2012, 0x8210, 0x8109, 0x1dd0, 0x9006,
+	0x20a9, 0x0008, 0x2012, 0x8210, 0x1f04, 0xaeca, 0x00ce, 0x60c3,
+	0x004c, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x080c, 0xa4d1, 0x080c,
+	0x8780, 0x00de, 0x009e, 0x002e, 0x001e, 0x0005, 0x00d6, 0x9290,
+	0x0018, 0x8214, 0x20e9, 0x0000, 0x2069, 0x0200, 0x6813, 0x0000,
+	0x22a8, 0x9284, 0x00e0, 0x0128, 0x20a9, 0x0020, 0x9292, 0x0020,
+	0x0008, 0x9016, 0x20a1, 0x0240, 0x9006, 0x4004, 0x82ff, 0x0120,
+	0x6810, 0x8000, 0x6812, 0x0c60, 0x00de, 0x0005, 0x00d6, 0x0096,
+	0x6014, 0x2048, 0xa878, 0x6056, 0x9006, 0xa836, 0xa83a, 0xa99c,
+	0xa946, 0xa84a, 0x6023, 0x0003, 0x6007, 0x0040, 0x6003, 0x0003,
+	0x600b, 0xffff, 0xa817, 0x0001, 0xa842, 0xa83e, 0x2900, 0xa85a,
+	0xa813, 0x20e6, 0x080c, 0x939a, 0x0126, 0x2091, 0x8000, 0x080c,
+	0x9a09, 0x012e, 0x009e, 0x00de, 0x0005, 0x00f6, 0x00e6, 0x00d6,
+	0x00c6, 0x00a6, 0x0096, 0x0066, 0x0126, 0x2091, 0x8000, 0x2071,
+	0x19e9, 0x760c, 0x2660, 0x2678, 0x8cff, 0x0904, 0xafb1, 0x7024,
+	0x9c06, 0x1520, 0x2069, 0x0100, 0x68c0, 0x9005, 0x0904, 0xaf83,
+	0x080c, 0xa4fd, 0x68c3, 0x0000, 0x080c, 0xaa2f, 0x7027, 0x0000,
 	0x0036, 0x2069, 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001,
-	0x0100, 0x080c, 0x2d4e, 0x9006, 0x080c, 0x2d4e, 0x2069, 0x0100,
+	0x0100, 0x080c, 0x2d5b, 0x9006, 0x080c, 0x2d5b, 0x2069, 0x0100,
 	0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x700c, 0x9c36,
 	0x1110, 0x660c, 0x760e, 0x7008, 0x9c36, 0x1140, 0x2c00, 0x9f36,
 	0x0118, 0x2f00, 0x700a, 0x0010, 0x700b, 0x0000, 0x660c, 0x0066,
 	0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000,
-	0x080c, 0xce7d, 0x1180, 0x080c, 0x3247, 0x080c, 0xce8e, 0x1518,
-	0x080c, 0xb905, 0x0400, 0x080c, 0xa88b, 0x6824, 0xd084, 0x09b0,
-	0x6827, 0x0001, 0x0898, 0x080c, 0xce8e, 0x1118, 0x080c, 0xb905,
-	0x0090, 0x6014, 0x2048, 0x080c, 0xcc84, 0x0168, 0x6020, 0x9086,
-	0x0003, 0x1508, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c,
-	0x6d0b, 0x080c, 0xce71, 0x080c, 0xd0fa, 0x080c, 0xaf74, 0x080c,
-	0xa761, 0x00ce, 0x0804, 0xa8ec, 0x2c78, 0x600c, 0x2060, 0x0804,
-	0xa8ec, 0x012e, 0x000e, 0x002e, 0x006e, 0x00ce, 0x00de, 0x00ee,
-	0x00fe, 0x009e, 0x0005, 0x6020, 0x9086, 0x0006, 0x1d20, 0x080c,
-	0xe6dd, 0x0c08, 0x00d6, 0x080c, 0x9d84, 0x7003, 0x0200, 0x7007,
-	0x0014, 0x60c3, 0x0014, 0x20e1, 0x0001, 0x2099, 0x1988, 0x20e9,
-	0x0000, 0x20a1, 0x0250, 0x20a9, 0x0004, 0x4003, 0x7023, 0x0004,
-	0x7027, 0x7878, 0x080c, 0xa32a, 0x00de, 0x0005, 0x080c, 0x9d84,
-	0x700b, 0x0800, 0x7814, 0x9084, 0xff00, 0x700e, 0x7814, 0x9084,
-	0x00ff, 0x7022, 0x782c, 0x7026, 0x7858, 0x9084, 0x00ff, 0x9085,
-	0x0200, 0x7002, 0x7858, 0x9084, 0xff00, 0x8007, 0x7006, 0x60c2,
-	0x0804, 0xa32a, 0x00b6, 0x00d6, 0x0016, 0x00d6, 0x2f68, 0x2009,
-	0x0035, 0x080c, 0xd300, 0x00de, 0x1904, 0xaa1f, 0x080c, 0x9d39,
-	0x7003, 0x1300, 0x782c, 0x080c, 0xab25, 0x2068, 0x6820, 0x9086,
-	0x0003, 0x0560, 0x7810, 0x2058, 0xbaa0, 0x080c, 0xaead, 0x11d8,
-	0x9286, 0x007e, 0x1128, 0x700b, 0x00ff, 0x700f, 0xfffe, 0x0498,
-	0x9286, 0x007f, 0x1128, 0x700b, 0x00ff, 0x700f, 0xfffd, 0x0458,
-	0x9284, 0xff80, 0x0180, 0x9286, 0x0080, 0x1128, 0x700b, 0x00ff,
-	0x700f, 0xfffc, 0x0400, 0x92d8, 0x1000, 0x2b5c, 0xb810, 0x700a,
-	0xb814, 0x700e, 0x00c0, 0x6098, 0x700e, 0x00a8, 0x080c, 0xaead,
-	0x1130, 0x7810, 0x2058, 0xb8a0, 0x9082, 0x007e, 0x0250, 0x00d6,
-	0x2069, 0x181f, 0x2d04, 0x700a, 0x8d68, 0x2d04, 0x700e, 0x00de,
-	0x0010, 0x6034, 0x700e, 0x7838, 0x7012, 0x783c, 0x7016, 0x60c3,
-	0x000c, 0x001e, 0x00de, 0x080c, 0xa32a, 0x00be, 0x0005, 0x781b,
-	0x0001, 0x7803, 0x0006, 0x001e, 0x00de, 0x00be, 0x0005, 0x792c,
-	0x9180, 0x0008, 0x200c, 0x9186, 0x0006, 0x01c0, 0x9186, 0x0003,
-	0x0904, 0xaa9a, 0x9186, 0x0005, 0x0904, 0xaa82, 0x9186, 0x0004,
-	0x05d8, 0x9186, 0x0008, 0x0904, 0xaa8b, 0x7807, 0x0037, 0x782f,
-	0x0003, 0x7817, 0x1700, 0x080c, 0xab02, 0x0005, 0x080c, 0xaac3,
-	0x00d6, 0x0026, 0x792c, 0x2168, 0x2009, 0x4000, 0x6800, 0x0002,
-	0xaa63, 0xaa6e, 0xaa65, 0xaa6e, 0xaa6a, 0xaa63, 0xaa63, 0xaa6e,
-	0xaa6e, 0xaa6e, 0xaa6e, 0xaa63, 0xaa63, 0xaa63, 0xaa63, 0xaa63,
-	0xaa6e, 0xaa63, 0xaa6e, 0x080c, 0x0dd5, 0x6824, 0xd0e4, 0x0110,
-	0xd0cc, 0x0110, 0x900e, 0x0010, 0x2009, 0x2000, 0x682c, 0x7022,
-	0x6830, 0x7026, 0x0804, 0xaabc, 0x080c, 0xaac3, 0x00d6, 0x0026,
-	0x792c, 0x2168, 0x2009, 0x4000, 0x6a00, 0x9286, 0x0002, 0x1108,
-	0x900e, 0x04d0, 0x080c, 0xaac3, 0x00d6, 0x0026, 0x792c, 0x2168,
-	0x2009, 0x4000, 0x0488, 0x04b9, 0x00d6, 0x0026, 0x792c, 0x2168,
-	0x2009, 0x4000, 0x9286, 0x0005, 0x0118, 0x9286, 0x0002, 0x1108,
-	0x900e, 0x0410, 0x0441, 0x00d6, 0x0026, 0x792c, 0x2168, 0x6814,
-	0x6924, 0xc185, 0x6926, 0x0096, 0x2048, 0xa9ac, 0xa834, 0x9112,
-	0xa9b0, 0xa838, 0x009e, 0x9103, 0x7022, 0x7226, 0x792c, 0x9180,
-	0x0000, 0x2004, 0x908e, 0x0002, 0x0130, 0x908e, 0x0004, 0x0118,
-	0x2009, 0x4000, 0x0008, 0x900e, 0x712a, 0x60c3, 0x0018, 0x002e,
-	0x00de, 0x0804, 0xa32a, 0x00b6, 0x0036, 0x0046, 0x0056, 0x0066,
-	0x080c, 0x9d84, 0x9006, 0x7003, 0x0200, 0x7938, 0x710a, 0x793c,
-	0x710e, 0x7810, 0x2058, 0xb8a0, 0x080c, 0xaead, 0x1118, 0x9092,
-	0x007e, 0x0268, 0x00d6, 0x2069, 0x181f, 0x2d2c, 0x8d68, 0x2d34,
-	0x90d8, 0x1000, 0x2b5c, 0xbb10, 0xbc14, 0x00de, 0x0028, 0x901e,
-	0x6498, 0x2029, 0x0000, 0x6634, 0x782c, 0x9080, 0x0008, 0x2004,
-	0x9086, 0x0003, 0x1128, 0x7512, 0x7616, 0x731a, 0x741e, 0x0020,
-	0x7312, 0x7416, 0x751a, 0x761e, 0x006e, 0x005e, 0x004e, 0x003e,
-	0x00be, 0x0005, 0x080c, 0x9d84, 0x7003, 0x0100, 0x782c, 0x700a,
-	0x7814, 0x700e, 0x700e, 0x60c3, 0x0008, 0x0804, 0xa32a, 0x080c,
-	0x9d30, 0x7003, 0x1400, 0x7838, 0x700a, 0x0079, 0x783c, 0x700e,
-	0x782c, 0x7012, 0x7830, 0x7016, 0x7834, 0x9084, 0x00ff, 0x8007,
-	0x701a, 0x60c3, 0x0010, 0x0804, 0xa32a, 0x00e6, 0x2071, 0x0240,
-	0x0006, 0x00f6, 0x2078, 0x7810, 0x00b6, 0x2058, 0xb8cc, 0xd084,
-	0x0120, 0x7844, 0x702a, 0x7848, 0x702e, 0x00be, 0x00fe, 0x000e,
-	0x00ee, 0x0005, 0x080c, 0x9d7b, 0x7003, 0x0100, 0x782c, 0x700a,
-	0x7814, 0x700e, 0x60c3, 0x0008, 0x0804, 0xa32a, 0x0021, 0x60c3,
-	0x0000, 0x0804, 0xa32a, 0x00d6, 0x080c, 0xabfe, 0xb810, 0x9085,
-	0x0300, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, 0x687c, 0x700a,
-	0x6880, 0x700e, 0x7013, 0x0819, 0x080c, 0xa318, 0x721a, 0x2f10,
-	0x7222, 0x7a08, 0x7226, 0x2071, 0x024c, 0x00de, 0x0005, 0x00a9,
-	0x7914, 0x712a, 0x60c3, 0x0000, 0x60a7, 0x9575, 0x0026, 0x080c,
-	0x2be3, 0x0228, 0x2011, 0x0101, 0x2204, 0xc0c5, 0x2012, 0x002e,
-	0x080c, 0xa34d, 0x080c, 0x862d, 0x0005, 0x0036, 0x0096, 0x00d6,
-	0x00e6, 0x7858, 0x2048, 0xaa7c, 0x9296, 0x00c0, 0x9294, 0xfffd,
-	0xaa7e, 0xaa80, 0x9294, 0x0300, 0xaa82, 0xa96c, 0x9194, 0x00ff,
-	0xab74, 0x9384, 0x00ff, 0x908d, 0xc200, 0xa96e, 0x9384, 0xff00,
-	0x9215, 0xaa76, 0xa870, 0xaa78, 0xa87a, 0xaa72, 0x00d6, 0x2069,
-	0x0200, 0x080c, 0xabfe, 0x00de, 0x20e9, 0x0000, 0x20a1, 0x0240,
-	0x20a9, 0x000a, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x001b, 0x2098,
-	0x4003, 0x60a3, 0x0035, 0xaa68, 0x9294, 0x7000, 0x9286, 0x3000,
-	0x0110, 0x60a3, 0x0037, 0x00ee, 0x00de, 0x009e, 0x003e, 0x0005,
-	0x900e, 0x7814, 0x0096, 0x2048, 0xa87c, 0xd0fc, 0x01c0, 0x9084,
-	0x0003, 0x11a8, 0x2001, 0x180c, 0x2004, 0xd0bc, 0x0180, 0x7824,
-	0xd0cc, 0x1168, 0xd0c4, 0x1158, 0xa8a8, 0x9005, 0x1140, 0x2001,
-	0x180c, 0x200c, 0xc1d5, 0x2102, 0x2009, 0x19b1, 0x210c, 0x009e,
-	0x918d, 0x0092, 0x0010, 0x2009, 0x0096, 0x60ab, 0x0036, 0x6116,
-	0x0005, 0x2009, 0x0009, 0x00a0, 0x2009, 0x000a, 0x0088, 0x2009,
-	0x000b, 0x0070, 0x2009, 0x000c, 0x0058, 0x2009, 0x000d, 0x0040,
-	0x2009, 0x000e, 0x0028, 0x2009, 0x000f, 0x0010, 0x2009, 0x0008,
-	0x6912, 0x0005, 0x080c, 0x9d39, 0x0016, 0x0026, 0x0096, 0x00d6,
-	0x7814, 0x2048, 0x7013, 0x0138, 0x2001, 0x1837, 0x2004, 0x9084,
-	0x0028, 0x1138, 0x2001, 0x197b, 0x2004, 0x9086, 0xaaaa, 0x1904,
-	0xaca3, 0x7003, 0x5400, 0x00c6, 0x2061, 0x1800, 0x607c, 0x9084,
-	0x00ff, 0xa998, 0x810f, 0x918c, 0xff00, 0x9105, 0x700a, 0x6080,
-	0x700e, 0xa998, 0x918c, 0xff00, 0x7112, 0x20a9, 0x0004, 0x2009,
-	0x1805, 0x2e10, 0x9290, 0x0006, 0x2104, 0x2012, 0x8108, 0x8210,
-	0x1f04, 0xac34, 0x20a9, 0x0004, 0x2009, 0x1801, 0x2104, 0x2012,
-	0x8108, 0x8210, 0x1f04, 0xac3e, 0xa860, 0x20e0, 0xa85c, 0x9080,
-	0x0029, 0x2098, 0x2009, 0x0006, 0x20a9, 0x0001, 0x4002, 0x8007,
-	0x2012, 0x8210, 0x8109, 0x1dc0, 0x00d6, 0x2069, 0x0200, 0x080c,
-	0xabe9, 0x00de, 0x2071, 0x0240, 0x2011, 0x0240, 0x2009, 0x0002,
-	0x20a9, 0x0001, 0x4002, 0x8007, 0x2012, 0x8210, 0x8109, 0x1dc0,
-	0x2009, 0x0008, 0x20a9, 0x0001, 0x4002, 0x8007, 0x2012, 0x8210,
-	0x8109, 0x1dc0, 0xa85c, 0x9080, 0x0031, 0x2098, 0x2009, 0x0008,
-	0x20a9, 0x0001, 0x4002, 0x8007, 0x2012, 0x8210, 0x8109, 0x1dc0,
-	0x00ce, 0x60c3, 0x004c, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x2001,
-	0x1837, 0x2004, 0x9084, 0x0028, 0x1168, 0x080c, 0x743e, 0x0150,
-	0x6028, 0xc0bd, 0x602a, 0x6014, 0x9084, 0x1804, 0x9085, 0x0029,
-	0x6016, 0x0010, 0x080c, 0xa32a, 0x080c, 0x862d, 0x00de, 0x009e,
-	0x002e, 0x001e, 0x0005, 0x00e6, 0x2071, 0x0240, 0x2001, 0x2200,
-	0x9085, 0x00ff, 0x7002, 0x7007, 0xffff, 0x2071, 0x0100, 0x709b,
-	0x00ff, 0x00ee, 0x0804, 0xac19, 0x080c, 0x9d39, 0x0016, 0x0026,
-	0x0096, 0x00d6, 0x7814, 0x2048, 0x7013, 0x0138, 0x7003, 0x5500,
-	0x00c6, 0xa89c, 0x9084, 0x00ff, 0xa998, 0x810f, 0x918c, 0xff00,
-	0x9105, 0x700a, 0xa99c, 0x918c, 0xff00, 0xa8a0, 0x9084, 0x00ff,
-	0x9105, 0x700e, 0xa998, 0x918c, 0xff00, 0x2061, 0x1800, 0x607c,
-	0x9084, 0x00ff, 0x910d, 0x7112, 0x6180, 0x7116, 0x2009, 0x0008,
-	0xa860, 0x20e0, 0xa85c, 0x9080, 0x0029, 0x2098, 0x2e10, 0x9290,
-	0x0006, 0x20a9, 0x0001, 0x4002, 0x8007, 0x2012, 0x8210, 0x8109,
-	0x1dc0, 0x20a9, 0x0004, 0x2009, 0x1805, 0x2104, 0x2012, 0x8108,
-	0x8210, 0x1f04, 0xacf5, 0x20a9, 0x0002, 0x2009, 0x1801, 0x2104,
-	0x2012, 0x8108, 0x8210, 0x1f04, 0xacff, 0x00d6, 0x0016, 0x2069,
-	0x0200, 0x080c, 0xabe9, 0x001e, 0x00de, 0x2071, 0x0240, 0x20a9,
-	0x0002, 0x2009, 0x1803, 0x2011, 0x0240, 0x2104, 0x2012, 0x8108,
-	0x8210, 0x1f04, 0xad15, 0x2009, 0x0008, 0x4002, 0x8007, 0x2012,
-	0x8210, 0x8109, 0x1dd0, 0x9006, 0x20a9, 0x0008, 0x2012, 0x8210,
-	0x1f04, 0xad26, 0x00ce, 0x60c3, 0x004c, 0x60a3, 0x0056, 0x60a7,
-	0x9575, 0x080c, 0xa32a, 0x080c, 0x862d, 0x00de, 0x009e, 0x002e,
-	0x001e, 0x0005, 0x00d6, 0x9290, 0x0018, 0x8214, 0x20e9, 0x0000,
-	0x2069, 0x0200, 0x6813, 0x0000, 0x22a8, 0x9284, 0x00e0, 0x0128,
-	0x20a9, 0x0020, 0x9292, 0x0020, 0x0008, 0x9016, 0x20a1, 0x0240,
-	0x9006, 0x4004, 0x82ff, 0x0120, 0x6810, 0x8000, 0x6812, 0x0c60,
-	0x00de, 0x0005, 0x00d6, 0x0096, 0x6014, 0x2048, 0xa878, 0x6056,
-	0x9006, 0xa836, 0xa83a, 0xa99c, 0xa946, 0xa84a, 0x6023, 0x0003,
-	0x6007, 0x0040, 0x6003, 0x0003, 0x600b, 0xffff, 0xa817, 0x0001,
-	0xa842, 0xa83e, 0x2900, 0xa85a, 0xa813, 0x20cc, 0x080c, 0x9216,
-	0x0126, 0x2091, 0x8000, 0x080c, 0x9891, 0x012e, 0x009e, 0x00de,
-	0x0005, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x00a6, 0x0096, 0x0066,
-	0x0126, 0x2091, 0x8000, 0x2071, 0x19e6, 0x760c, 0x2660, 0x2678,
-	0x8cff, 0x0904, 0xae0d, 0x7024, 0x9c06, 0x1520, 0x2069, 0x0100,
-	0x68c0, 0x9005, 0x0904, 0xaddf, 0x080c, 0xa356, 0x68c3, 0x0000,
-	0x080c, 0xa88b, 0x7027, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04,
-	0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2d4e, 0x9006,
-	0x080c, 0x2d4e, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827,
-	0x0001, 0x003e, 0x700c, 0x9c36, 0x1110, 0x660c, 0x760e, 0x7008,
-	0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x700a, 0x0010,
-	0x700b, 0x0000, 0x660c, 0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e,
-	0x0008, 0x2678, 0x600f, 0x0000, 0x080c, 0xce7d, 0x1180, 0x080c,
-	0x3247, 0x080c, 0xce8e, 0x1518, 0x080c, 0xb905, 0x0400, 0x080c,
-	0xa88b, 0x6824, 0xd084, 0x09b0, 0x6827, 0x0001, 0x0898, 0x080c,
-	0xce8e, 0x1118, 0x080c, 0xb905, 0x0090, 0x6014, 0x2048, 0x080c,
-	0xcc84, 0x0168, 0x6020, 0x9086, 0x0003, 0x1520, 0xa867, 0x0103,
-	0xab7a, 0xa877, 0x0000, 0x080c, 0x6d17, 0x080c, 0xce71, 0x080c,
-	0xd0fa, 0x080c, 0xaf74, 0x080c, 0xa761, 0x00ce, 0x0804, 0xad90,
-	0x2c78, 0x600c, 0x2060, 0x0804, 0xad90, 0x700f, 0x0000, 0x700b,
-	0x0000, 0x012e, 0x006e, 0x009e, 0x00ae, 0x00ce, 0x00de, 0x00ee,
-	0x00fe, 0x0005, 0x6020, 0x9086, 0x0006, 0x1d08, 0x080c, 0xe6dd,
-	0x08f0, 0x00d6, 0x0156, 0x080c, 0x9d84, 0x7a14, 0x82ff, 0x0138,
-	0x7003, 0x0100, 0x700b, 0x0003, 0x60c3, 0x0008, 0x0490, 0x7003,
-	0x0200, 0x7007, 0x0000, 0x2069, 0x1800, 0x901e, 0x6800, 0x9086,
-	0x0004, 0x1110, 0xc38d, 0x0060, 0x080c, 0x743e, 0x1110, 0xc3ad,
-	0x0008, 0xc3a5, 0x6adc, 0xd29c, 0x1110, 0xd2ac, 0x0108, 0xc39d,
-	0x730e, 0x080c, 0x8696, 0x20a9, 0x0006, 0x2011, 0xffec, 0x2019,
-	0xffed, 0x2071, 0x0250, 0x2305, 0x2072, 0x8e70, 0x2205, 0x2072,
-	0x8e70, 0x9398, 0x0002, 0x9290, 0x0002, 0x1f04, 0xae53, 0x60c3,
-	0x0020, 0x080c, 0xa32a, 0x015e, 0x00de, 0x0005, 0x0156, 0x080c,
-	0x9d84, 0x7a14, 0x82ff, 0x0168, 0x9286, 0xffff, 0x0118, 0x9282,
-	0x000e, 0x1238, 0x7003, 0x0100, 0x700b, 0x0003, 0x60c3, 0x0008,
-	0x0488, 0x7003, 0x0200, 0x7007, 0x001c, 0x700f, 0x0001, 0x2011,
-	0x19bc, 0x2204, 0x8007, 0x701a, 0x8210, 0x2204, 0x8007, 0x701e,
-	0x0421, 0x1120, 0xb8a0, 0x9082, 0x007f, 0x0248, 0x2001, 0x181f,
-	0x2004, 0x7022, 0x2001, 0x1820, 0x2004, 0x7026, 0x0030, 0x2001,
-	0x1818, 0x2004, 0x9084, 0x00ff, 0x7026, 0x20a9, 0x0004, 0x20e1,
-	0x0001, 0x2099, 0x1805, 0x20e9, 0x0000, 0x20a1, 0x0256, 0x4003,
-	0x60c3, 0x001c, 0x015e, 0x0804, 0xa32a, 0x0006, 0x2001, 0x1837,
-	0x2004, 0xd0ac, 0x000e, 0x0005, 0x2011, 0x0003, 0x080c, 0xa722,
-	0x2011, 0x0002, 0x080c, 0xa72c, 0x080c, 0xa636, 0x0036, 0x901e,
-	0x080c, 0xa6ac, 0x003e, 0x0005, 0x080c, 0x337d, 0x0188, 0x0016,
-	0x00b6, 0x00c6, 0x7010, 0x9085, 0x0020, 0x7012, 0x2009, 0x007e,
-	0x080c, 0x6699, 0xb85c, 0xc0ac, 0xb85e, 0x00ce, 0x00be, 0x001e,
-	0x0005, 0x2071, 0x188d, 0x7000, 0x9005, 0x0140, 0x2001, 0x0976,
-	0x2071, 0x1800, 0x7076, 0x707a, 0x706b, 0xffe0, 0x2071, 0x1800,
-	0x7074, 0x7056, 0x705b, 0x1cd0, 0x0005, 0x00e6, 0x0126, 0x2071,
-	0x1800, 0x2091, 0x8000, 0x7554, 0x9582, 0x0010, 0x0608, 0x7058,
-	0x2060, 0x6000, 0x9086, 0x0000, 0x0148, 0x9ce0, 0x0018, 0x7068,
-	0x9c02, 0x1208, 0x0cb0, 0x2061, 0x1cd0, 0x0c98, 0x6003, 0x0008,
-	0x8529, 0x7556, 0x9ca8, 0x0018, 0x7068, 0x9502, 0x1230, 0x755a,
-	0x9085, 0x0001, 0x012e, 0x00ee, 0x0005, 0x705b, 0x1cd0, 0x0cc0,
-	0x9006, 0x0cc0, 0x00e6, 0x2071, 0x1800, 0x7554, 0x9582, 0x0010,
-	0x0600, 0x7058, 0x2060, 0x6000, 0x9086, 0x0000, 0x0148, 0x9ce0,
-	0x0018, 0x7068, 0x9c02, 0x1208, 0x0cb0, 0x2061, 0x1cd0, 0x0c98,
-	0x6003, 0x0008, 0x8529, 0x7556, 0x9ca8, 0x0018, 0x7068, 0x9502,
-	0x1228, 0x755a, 0x9085, 0x0001, 0x00ee, 0x0005, 0x705b, 0x1cd0,
-	0x0cc8, 0x9006, 0x0cc8, 0x9c82, 0x1cd0, 0x0a0c, 0x0dd5, 0x2001,
-	0x181a, 0x2004, 0x9c02, 0x1a0c, 0x0dd5, 0x9006, 0x6006, 0x600a,
-	0x600e, 0x6016, 0x601a, 0x6012, 0x6023, 0x0000, 0x6003, 0x0000,
-	0x601e, 0x6056, 0x605a, 0x6026, 0x602a, 0x602e, 0x6032, 0x6036,
-	0x603a, 0x603e, 0x6042, 0x602a, 0x2061, 0x1800, 0x6054, 0x8000,
-	0x6056, 0x9086, 0x0001, 0x0108, 0x0005, 0x0126, 0x2091, 0x8000,
-	0x080c, 0x9763, 0x012e, 0x0cc0, 0x0006, 0x6000, 0x9086, 0x0000,
-	0x01b0, 0x601c, 0xd084, 0x190c, 0x1aa1, 0x6017, 0x0000, 0x6023,
-	0x0007, 0x2001, 0x1985, 0x2004, 0x0006, 0x9082, 0x0051, 0x000e,
-	0x0208, 0x8004, 0x601a, 0x080c, 0xe997, 0x6043, 0x0000, 0x000e,
+	0x080c, 0xd036, 0x1180, 0x080c, 0x3274, 0x080c, 0xd047, 0x1518,
+	0x080c, 0xbacb, 0x0400, 0x080c, 0xaa2f, 0x6824, 0xd084, 0x09b0,
+	0x6827, 0x0001, 0x0898, 0x080c, 0xd047, 0x1118, 0x080c, 0xbacb,
+	0x0090, 0x6014, 0x2048, 0x080c, 0xce3d, 0x0168, 0x6020, 0x9086,
+	0x0003, 0x1520, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c,
+	0x6dcb, 0x080c, 0xd02a, 0x080c, 0xd2b3, 0x080c, 0xb11a, 0x080c,
+	0xa905, 0x00ce, 0x0804, 0xaf34, 0x2c78, 0x600c, 0x2060, 0x0804,
+	0xaf34, 0x700f, 0x0000, 0x700b, 0x0000, 0x012e, 0x006e, 0x009e,
+	0x00ae, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x6020, 0x9086,
+	0x0006, 0x1d08, 0x080c, 0xe8e3, 0x08f0, 0x00d6, 0x0156, 0x080c,
+	0x9f20, 0x7a14, 0x82ff, 0x0138, 0x7003, 0x0100, 0x700b, 0x0003,
+	0x60c3, 0x0008, 0x0490, 0x7003, 0x0200, 0x7007, 0x0000, 0x2069,
+	0x1800, 0x901e, 0x6800, 0x9086, 0x0004, 0x1110, 0xc38d, 0x0060,
+	0x080c, 0x7563, 0x1110, 0xc3ad, 0x0008, 0xc3a5, 0x6adc, 0xd29c,
+	0x1110, 0xd2ac, 0x0108, 0xc39d, 0x730e, 0x080c, 0x8812, 0x20a9,
+	0x0006, 0x2011, 0xffec, 0x2019, 0xffed, 0x2071, 0x0250, 0x2305,
+	0x2072, 0x8e70, 0x2205, 0x2072, 0x8e70, 0x9398, 0x0002, 0x9290,
+	0x0002, 0x1f04, 0xaff7, 0x60c3, 0x0020, 0x080c, 0xa4d1, 0x015e,
+	0x00de, 0x0005, 0x0156, 0x080c, 0x9f20, 0x7a14, 0x82ff, 0x0168,
+	0x9286, 0xffff, 0x0118, 0x9282, 0x000e, 0x1238, 0x7003, 0x0100,
+	0x700b, 0x0003, 0x60c3, 0x0008, 0x0488, 0x7003, 0x0200, 0x7007,
+	0x001c, 0x700f, 0x0001, 0x2011, 0x19bf, 0x2204, 0x8007, 0x701a,
+	0x8210, 0x2204, 0x8007, 0x701e, 0x0421, 0x1120, 0xb8a0, 0x9082,
+	0x007f, 0x0248, 0x2001, 0x181f, 0x2004, 0x7022, 0x2001, 0x1820,
+	0x2004, 0x7026, 0x0030, 0x2001, 0x1818, 0x2004, 0x9084, 0x00ff,
+	0x7026, 0x20a9, 0x0004, 0x20e1, 0x0001, 0x2099, 0x1805, 0x20e9,
+	0x0000, 0x20a1, 0x0256, 0x4003, 0x60c3, 0x001c, 0x015e, 0x0804,
+	0xa4d1, 0x0006, 0x2001, 0x1837, 0x2004, 0xd0ac, 0x000e, 0x0005,
+	0x2011, 0x0003, 0x080c, 0xa8d3, 0x2011, 0x0002, 0x080c, 0xa8dd,
+	0x080c, 0xa7e7, 0x0036, 0x901e, 0x080c, 0xa85d, 0x003e, 0x0005,
+	0x080c, 0x33aa, 0x0188, 0x0016, 0x00b6, 0x00c6, 0x7010, 0x9085,
+	0x0020, 0x7012, 0x2009, 0x007e, 0x080c, 0x6717, 0xb85c, 0xc0ac,
+	0xb85e, 0x00ce, 0x00be, 0x001e, 0x0005, 0x2071, 0x188d, 0x7000,
+	0x9005, 0x0140, 0x2001, 0x0976, 0x2071, 0x1800, 0x7076, 0x707a,
+	0x706b, 0xffe0, 0x2071, 0x1800, 0x7074, 0x7056, 0x705b, 0x1cd0,
+	0x0005, 0x00e6, 0x0126, 0x2071, 0x1800, 0x2091, 0x8000, 0x7554,
+	0x9582, 0x0010, 0x0608, 0x7058, 0x2060, 0x6000, 0x9086, 0x0000,
+	0x0148, 0x9ce0, 0x0018, 0x7068, 0x9c02, 0x1208, 0x0cb0, 0x2061,
+	0x1cd0, 0x0c98, 0x6003, 0x0008, 0x8529, 0x7556, 0x9ca8, 0x0018,
+	0x7068, 0x9502, 0x1230, 0x755a, 0x9085, 0x0001, 0x012e, 0x00ee,
+	0x0005, 0x705b, 0x1cd0, 0x0cc0, 0x9006, 0x0cc0, 0x00e6, 0x2071,
+	0x1800, 0x7554, 0x9582, 0x0010, 0x0600, 0x7058, 0x2060, 0x6000,
+	0x9086, 0x0000, 0x0148, 0x9ce0, 0x0018, 0x7068, 0x9c02, 0x1208,
+	0x0cb0, 0x2061, 0x1cd0, 0x0c98, 0x6003, 0x0008, 0x8529, 0x7556,
+	0x9ca8, 0x0018, 0x7068, 0x9502, 0x1228, 0x755a, 0x9085, 0x0001,
+	0x00ee, 0x0005, 0x705b, 0x1cd0, 0x0cc8, 0x9006, 0x0cc8, 0x9c82,
+	0x1cd0, 0x0a0c, 0x0dc5, 0x2001, 0x181a, 0x2004, 0x9c02, 0x1a0c,
+	0x0dc5, 0x9006, 0x6006, 0x600a, 0x600e, 0x6016, 0x601a, 0x6012,
+	0x6023, 0x0000, 0x6003, 0x0000, 0x601e, 0x6056, 0x605a, 0x6026,
+	0x602a, 0x602e, 0x6032, 0x6036, 0x603a, 0x603e, 0x6042, 0x602a,
+	0x2061, 0x1800, 0x6054, 0x8000, 0x6056, 0x9086, 0x0001, 0x0108,
+	0x0005, 0x0126, 0x2091, 0x8000, 0x0016, 0x080c, 0x98e7, 0x001e,
+	0x012e, 0x0cb0, 0x0006, 0x6000, 0x9086, 0x0000, 0x01c0, 0x601c,
+	0xd084, 0x190c, 0x1ab7, 0x6017, 0x0000, 0x6023, 0x0007, 0x2001,
+	0x1987, 0x2004, 0x0006, 0x9082, 0x0051, 0x000e, 0x0208, 0x8004,
+	0x601a, 0x080c, 0xeb9d, 0x6043, 0x0000, 0x6013, 0x0000, 0x000e,
 	0x0005, 0x00e6, 0x0126, 0x2071, 0x1800, 0x2091, 0x8000, 0x7554,
 	0x9582, 0x0001, 0x0608, 0x7058, 0x2060, 0x6000, 0x9086, 0x0000,
 	0x0148, 0x9ce0, 0x0018, 0x7068, 0x9c02, 0x1208, 0x0cb0, 0x2061,
 	0x1cd0, 0x0c98, 0x6003, 0x0008, 0x8529, 0x7556, 0x9ca8, 0x0018,
 	0x7068, 0x9502, 0x1230, 0x755a, 0x9085, 0x0001, 0x012e, 0x00ee,
 	0x0005, 0x705b, 0x1cd0, 0x0cc0, 0x9006, 0x0cc0, 0x6020, 0x9084,
-	0x000f, 0x0002, 0xafd1, 0xafda, 0xaff5, 0xb010, 0xd3ae, 0xd3cb,
-	0xd3e6, 0xafd1, 0xafda, 0x8e43, 0xb02c, 0xafd1, 0xafd1, 0xafd1,
-	0xafd1, 0x9186, 0x0013, 0x1128, 0x080c, 0x9657, 0x080c, 0x9763,
-	0x0005, 0x0005, 0x0066, 0x6000, 0x90b2, 0x0016, 0x1a0c, 0x0dd5,
-	0x0013, 0x006e, 0x0005, 0xaff3, 0xb76f, 0xb94c, 0xaff3, 0xb9e2,
-	0xb30f, 0xaff3, 0xaff3, 0xb6f1, 0xbf49, 0xaff3, 0xaff3, 0xaff3,
-	0xaff3, 0xaff3, 0xaff3, 0x080c, 0x0dd5, 0x0066, 0x6000, 0x90b2,
-	0x0016, 0x1a0c, 0x0dd5, 0x0013, 0x006e, 0x0005, 0xb00e, 0xc630,
-	0xb00e, 0xb00e, 0xb00e, 0xb00e, 0xb00e, 0xb00e, 0xc5c7, 0xc7b2,
-	0xb00e, 0xc671, 0xc6f0, 0xc671, 0xc6f0, 0xb00e, 0x080c, 0x0dd5,
-	0x6000, 0x9082, 0x0016, 0x1a0c, 0x0dd5, 0x6000, 0x0002, 0xb02a,
-	0xbf90, 0xc075, 0xc1a5, 0xc354, 0xb02a, 0xb02a, 0xb02a, 0xbf64,
-	0xc553, 0xc556, 0xb02a, 0xb02a, 0xb02a, 0xb02a, 0xc585, 0xb02a,
-	0xb02a, 0xb02a, 0x080c, 0x0dd5, 0x0066, 0x6000, 0x90b2, 0x0016,
-	0x1a0c, 0x0dd5, 0x0013, 0x006e, 0x0005, 0xb045, 0xb045, 0xb088,
-	0xb127, 0xb1bc, 0xb045, 0xb045, 0xb045, 0xb047, 0xb045, 0xb045,
-	0xb045, 0xb045, 0xb045, 0xb045, 0xb045, 0x080c, 0x0dd5, 0x9186,
-	0x004c, 0x0588, 0x9186, 0x0003, 0x190c, 0x0dd5, 0x0096, 0x601c,
+	0x000f, 0x0002, 0xb179, 0xb182, 0xb19d, 0xb1b8, 0xd590, 0xd5ad,
+	0xd5c8, 0xb179, 0xb182, 0x8fc7, 0xb1d4, 0xb179, 0xb179, 0xb179,
+	0xb179, 0x9186, 0x0013, 0x1128, 0x080c, 0x97db, 0x080c, 0x98e7,
+	0x0005, 0x0005, 0x0066, 0x6000, 0x90b2, 0x0016, 0x1a0c, 0x0dc5,
+	0x0013, 0x006e, 0x0005, 0xb19b, 0xb91a, 0xbb12, 0xb19b, 0xbba8,
+	0xb4b7, 0xb19b, 0xb19b, 0xb89c, 0xc11f, 0xb19b, 0xb19b, 0xb19b,
+	0xb19b, 0xb19b, 0xb19b, 0x080c, 0x0dc5, 0x0066, 0x6000, 0x90b2,
+	0x0016, 0x1a0c, 0x0dc5, 0x0013, 0x006e, 0x0005, 0xb1b6, 0xc7e9,
+	0xb1b6, 0xb1b6, 0xb1b6, 0xb1b6, 0xb1b6, 0xb1b6, 0xc780, 0xc96b,
+	0xb1b6, 0xc82a, 0xc8a9, 0xc82a, 0xc8a9, 0xb1b6, 0x080c, 0x0dc5,
+	0x6000, 0x9082, 0x0016, 0x1a0c, 0x0dc5, 0x6000, 0x0002, 0xb1d2,
+	0xc166, 0xc22e, 0xc35e, 0xc50d, 0xb1d2, 0xb1d2, 0xb1d2, 0xc13a,
+	0xc70c, 0xc70f, 0xb1d2, 0xb1d2, 0xb1d2, 0xb1d2, 0xc73e, 0xb1d2,
+	0xb1d2, 0xb1d2, 0x080c, 0x0dc5, 0x0066, 0x6000, 0x90b2, 0x0016,
+	0x1a0c, 0x0dc5, 0x0013, 0x006e, 0x0005, 0xb1ed, 0xb1ed, 0xb230,
+	0xb2cf, 0xb364, 0xb1ed, 0xb1ed, 0xb1ed, 0xb1ef, 0xb1ed, 0xb1ed,
+	0xb1ed, 0xb1ed, 0xb1ed, 0xb1ed, 0xb1ed, 0x080c, 0x0dc5, 0x9186,
+	0x004c, 0x0588, 0x9186, 0x0003, 0x190c, 0x0dc5, 0x0096, 0x601c,
 	0xc0ed, 0x601e, 0x6003, 0x0003, 0x6106, 0x6014, 0x2048, 0xa87c,
 	0x9084, 0xa000, 0xc0b5, 0xa87e, 0xa8ac, 0xa846, 0xa8b0, 0xa84a,
 	0x9006, 0xa836, 0xa83a, 0xa884, 0x9092, 0x199a, 0x0210, 0x2001,
 	0x1999, 0x8003, 0x8013, 0x8213, 0x9210, 0x621a, 0x009e, 0x2c10,
-	0x080c, 0x1beb, 0x080c, 0x9216, 0x0126, 0x2091, 0x8000, 0x080c,
-	0x9891, 0x012e, 0x0005, 0x6010, 0x00b6, 0x2058, 0xbca0, 0x00be,
-	0x2c00, 0x080c, 0xb1de, 0x080c, 0xd3a0, 0x6003, 0x0007, 0x0005,
+	0x080c, 0x1c01, 0x080c, 0x939a, 0x0126, 0x2091, 0x8000, 0x080c,
+	0x9a09, 0x012e, 0x0005, 0x6010, 0x00b6, 0x2058, 0xbca0, 0x00be,
+	0x2c00, 0x080c, 0xb386, 0x080c, 0xd560, 0x6003, 0x0007, 0x0005,
 	0x00d6, 0x0096, 0x00f6, 0x2079, 0x1800, 0x7a90, 0x6014, 0x2048,
 	0xa87c, 0xd0ec, 0x1110, 0x9290, 0x0018, 0xac78, 0xc4fc, 0x0046,
 	0xa8e0, 0x9005, 0x1140, 0xa8dc, 0x921a, 0x0140, 0x0220, 0xa87b,
@@ -5451,2140 +5504,2160 @@ unsigned short risc_code01[] = { 
 	0x00d6, 0x00e6, 0x00f6, 0x2400, 0x9005, 0x1108, 0x009a, 0x2100,
 	0x9086, 0x0015, 0x1118, 0x2001, 0x0001, 0x0038, 0x2100, 0x9086,
 	0x0016, 0x0118, 0x2001, 0x0001, 0x002a, 0x94a4, 0x0007, 0x8423,
-	0x9405, 0x0002, 0xb0ef, 0xb0ef, 0xb0ea, 0xb0ed, 0xb0ef, 0xb0e7,
-	0xb0da, 0xb0da, 0xb0da, 0xb0da, 0xb0da, 0xb0da, 0xb0da, 0xb0da,
-	0xb0da, 0xb0da, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x002e, 0x001e,
-	0x000e, 0x004e, 0x00fe, 0x009e, 0x00de, 0x080c, 0x0dd5, 0x080c,
-	0xbba1, 0x0028, 0x080c, 0xbc86, 0x0010, 0x080c, 0xbd7c, 0x00fe,
+	0x9405, 0x0002, 0xb297, 0xb297, 0xb292, 0xb295, 0xb297, 0xb28f,
+	0xb282, 0xb282, 0xb282, 0xb282, 0xb282, 0xb282, 0xb282, 0xb282,
+	0xb282, 0xb282, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x002e, 0x001e,
+	0x000e, 0x004e, 0x00fe, 0x009e, 0x00de, 0x080c, 0x0dc5, 0x080c,
+	0xbd75, 0x0028, 0x080c, 0xbe5c, 0x0010, 0x080c, 0xbf52, 0x00fe,
 	0x00ee, 0x00de, 0x00ce, 0x002e, 0x001e, 0x2c00, 0xa896, 0x000e,
-	0x080c, 0xb29c, 0x0530, 0xa804, 0xa80e, 0x00a6, 0x2050, 0xb100,
+	0x080c, 0xb444, 0x0530, 0xa804, 0xa80e, 0x00a6, 0x2050, 0xb100,
 	0x00ae, 0x8006, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0,
 	0x9080, 0x0002, 0xaacc, 0xabd0, 0xacd4, 0xadd8, 0x2031, 0x0000,
-	0x2041, 0x125d, 0x080c, 0xb45d, 0x0160, 0x000e, 0x9005, 0x0120,
+	0x2041, 0x126c, 0x080c, 0xb608, 0x0160, 0x000e, 0x9005, 0x0120,
 	0x00fe, 0x009e, 0x00de, 0x0005, 0x00fe, 0x009e, 0x00de, 0x0804,
-	0xaf43, 0x2001, 0x002c, 0x900e, 0x080c, 0xb302, 0x0c70, 0x91b6,
+	0xb0e7, 0x2001, 0x002c, 0x900e, 0x080c, 0xb4aa, 0x0c70, 0x91b6,
 	0x0015, 0x0170, 0x91b6, 0x0016, 0x0158, 0x91b2, 0x0047, 0x0a0c,
-	0x0dd5, 0x91b2, 0x0050, 0x1a0c, 0x0dd5, 0x9182, 0x0047, 0x00ca,
+	0x0dc5, 0x91b2, 0x0050, 0x1a0c, 0x0dc5, 0x9182, 0x0047, 0x00ca,
 	0x2001, 0x0109, 0x2004, 0xd08c, 0x0198, 0x0126, 0x2091, 0x2800,
-	0x0006, 0x0016, 0x0026, 0x080c, 0x9163, 0x002e, 0x001e, 0x000e,
-	0x012e, 0xa001, 0x6000, 0x9086, 0x0002, 0x1110, 0x0804, 0xb088,
-	0x0005, 0xb15a, 0xb15a, 0xb15c, 0xb192, 0xb15a, 0xb15a, 0xb15a,
-	0xb15a, 0xb1a5, 0x080c, 0x0dd5, 0x00d6, 0x0016, 0x0096, 0x080c,
-	0x9713, 0x080c, 0x9891, 0x6003, 0x0004, 0x6114, 0x2148, 0xa87c,
+	0x0006, 0x0016, 0x0026, 0x080c, 0x92e7, 0x002e, 0x001e, 0x000e,
+	0x012e, 0xa001, 0x6000, 0x9086, 0x0002, 0x1110, 0x0804, 0xb230,
+	0x0005, 0xb302, 0xb302, 0xb304, 0xb33a, 0xb302, 0xb302, 0xb302,
+	0xb302, 0xb34d, 0x080c, 0x0dc5, 0x00d6, 0x0016, 0x0096, 0x080c,
+	0x9897, 0x080c, 0x9a09, 0x6003, 0x0004, 0x6114, 0x2148, 0xa87c,
 	0xd0fc, 0x01c0, 0xa878, 0xc0fc, 0x9005, 0x1158, 0xa894, 0x9005,
-	0x0140, 0x2001, 0x0000, 0x900e, 0x080c, 0xb302, 0x080c, 0xaf43,
+	0x0140, 0x2001, 0x0000, 0x900e, 0x080c, 0xb4aa, 0x080c, 0xb0e7,
 	0x00a8, 0x6003, 0x0002, 0xa8a4, 0xa9a8, 0x9105, 0x1178, 0xa8ae,
 	0xa8b2, 0x0c78, 0xa87f, 0x0020, 0xa88c, 0xa88a, 0xa8a4, 0xa8ae,
 	0xa8a8, 0xa8b2, 0xa8c7, 0x0000, 0xa8cb, 0x0000, 0x009e, 0x001e,
-	0x00de, 0x0005, 0x080c, 0x9713, 0x00d6, 0x0096, 0x6114, 0x2148,
-	0x080c, 0xcc86, 0x0120, 0xa87b, 0x0006, 0x080c, 0x6d17, 0x009e,
-	0x00de, 0x080c, 0xaf43, 0x0804, 0x9891, 0x080c, 0x9713, 0x080c,
-	0x321e, 0x080c, 0xd39d, 0x00d6, 0x0096, 0x6114, 0x2148, 0x080c,
-	0xcc86, 0x0120, 0xa87b, 0x0029, 0x080c, 0x6d17, 0x009e, 0x00de,
-	0x080c, 0xaf43, 0x0804, 0x9891, 0x9182, 0x0047, 0x0002, 0xb1cc,
-	0xb1ce, 0xb1cc, 0xb1cc, 0xb1cc, 0xb1cc, 0xb1cc, 0xb1cc, 0xb1cc,
-	0xb1cc, 0xb1cc, 0xb1cc, 0xb1ce, 0x080c, 0x0dd5, 0x00d6, 0x0096,
+	0x00de, 0x0005, 0x080c, 0x9897, 0x00d6, 0x0096, 0x6114, 0x2148,
+	0x080c, 0xce3f, 0x0120, 0xa87b, 0x0006, 0x080c, 0x6dcb, 0x009e,
+	0x00de, 0x080c, 0xb0e7, 0x0804, 0x9a09, 0x080c, 0x9897, 0x080c,
+	0x324b, 0x080c, 0xd55d, 0x00d6, 0x0096, 0x6114, 0x2148, 0x080c,
+	0xce3f, 0x0120, 0xa87b, 0x0029, 0x080c, 0x6dcb, 0x009e, 0x00de,
+	0x080c, 0xb0e7, 0x0804, 0x9a09, 0x9182, 0x0047, 0x0002, 0xb374,
+	0xb376, 0xb374, 0xb374, 0xb374, 0xb374, 0xb374, 0xb374, 0xb374,
+	0xb374, 0xb374, 0xb374, 0xb376, 0x080c, 0x0dc5, 0x00d6, 0x0096,
 	0x601f, 0x0000, 0x6114, 0x2148, 0xa87b, 0x0000, 0xa883, 0x0000,
-	0x080c, 0x6d17, 0x009e, 0x00de, 0x0804, 0xaf43, 0x0026, 0x0036,
-	0x0056, 0x0066, 0x0096, 0x00a6, 0x00f6, 0x0006, 0x080c, 0x0fff,
-	0x000e, 0x090c, 0x0dd5, 0xa960, 0x21e8, 0xa95c, 0x9188, 0x0019,
+	0x080c, 0x6dcb, 0x009e, 0x00de, 0x0804, 0xb0e7, 0x0026, 0x0036,
+	0x0056, 0x0066, 0x0096, 0x00a6, 0x00f6, 0x0006, 0x080c, 0x100e,
+	0x000e, 0x090c, 0x0dc5, 0xa960, 0x21e8, 0xa95c, 0x9188, 0x0019,
 	0x21a0, 0x900e, 0x20a9, 0x0020, 0x4104, 0xa87a, 0x2079, 0x1800,
 	0x7990, 0x9188, 0x0018, 0x918c, 0x0fff, 0xa972, 0xac76, 0x2950,
 	0x00a6, 0x2001, 0x0205, 0x2003, 0x0000, 0x901e, 0x2029, 0x0001,
-	0x9182, 0x0034, 0x1228, 0x2011, 0x001f, 0x080c, 0xc837, 0x04c0,
-	0x2130, 0x2009, 0x0034, 0x2011, 0x001f, 0x080c, 0xc837, 0x96b2,
-	0x0034, 0xb004, 0x904d, 0x0110, 0x080c, 0x0fb1, 0x080c, 0x0fff,
+	0x9182, 0x0034, 0x1228, 0x2011, 0x001f, 0x080c, 0xc9f0, 0x04c0,
+	0x2130, 0x2009, 0x0034, 0x2011, 0x001f, 0x080c, 0xc9f0, 0x96b2,
+	0x0034, 0xb004, 0x904d, 0x0110, 0x080c, 0x0fc0, 0x080c, 0x100e,
 	0x01d0, 0x8528, 0xa867, 0x0110, 0xa86b, 0x0000, 0x2920, 0xb406,
-	0x968a, 0x003d, 0x1230, 0x2608, 0x2011, 0x001b, 0x080c, 0xc837,
+	0x968a, 0x003d, 0x1230, 0x2608, 0x2011, 0x001b, 0x080c, 0xc9f0,
 	0x00b8, 0x96b2, 0x003c, 0x2009, 0x003c, 0x2950, 0x2011, 0x001b,
-	0x080c, 0xc837, 0x0c18, 0x2001, 0x0205, 0x2003, 0x0000, 0x00ae,
+	0x080c, 0xc9f0, 0x0c18, 0x2001, 0x0205, 0x2003, 0x0000, 0x00ae,
 	0x852f, 0x95ad, 0x0050, 0xb566, 0xb070, 0xc0fd, 0xb072, 0x0048,
 	0x2001, 0x0205, 0x2003, 0x0000, 0x00ae, 0x852f, 0x95ad, 0x0050,
-	0xb566, 0x2a48, 0xa804, 0xa807, 0x0000, 0x0006, 0x080c, 0x6d17,
+	0xb566, 0x2a48, 0xa804, 0xa807, 0x0000, 0x0006, 0x080c, 0x6dcb,
 	0x000e, 0x2048, 0x9005, 0x1db0, 0x00fe, 0x00ae, 0x009e, 0x006e,
 	0x005e, 0x003e, 0x002e, 0x0005, 0x00d6, 0x00f6, 0x0096, 0x0006,
-	0x080c, 0x0fff, 0x000e, 0x090c, 0x0dd5, 0xa960, 0x21e8, 0xa95c,
+	0x080c, 0x100e, 0x000e, 0x090c, 0x0dc5, 0xa960, 0x21e8, 0xa95c,
 	0x9188, 0x0019, 0x21a0, 0x900e, 0x20a9, 0x0020, 0x4104, 0xaa66,
 	0xa87a, 0x2079, 0x1800, 0x7990, 0x810c, 0x9188, 0x000c, 0x9182,
 	0x001a, 0x0210, 0x2009, 0x001a, 0x21a8, 0x810b, 0xa972, 0xac76,
 	0x2e98, 0xa85c, 0x9080, 0x001f, 0x20a0, 0x2001, 0x0205, 0x200c,
-	0x918d, 0x0080, 0x2102, 0x4003, 0x2003, 0x0000, 0x080c, 0x6d17,
+	0x918d, 0x0080, 0x2102, 0x4003, 0x2003, 0x0000, 0x080c, 0x6dcb,
 	0x009e, 0x00fe, 0x00de, 0x0005, 0x0016, 0x00d6, 0x00f6, 0x0096,
 	0x0016, 0x2001, 0x0205, 0x200c, 0x918d, 0x0080, 0x2102, 0x001e,
 	0x2079, 0x0200, 0x2e98, 0xa87c, 0xd0ec, 0x0118, 0x9e80, 0x000c,
 	0x2098, 0x2021, 0x003e, 0x901e, 0x9282, 0x0020, 0x0218, 0x2011,
-	0x0020, 0x2018, 0x9486, 0x003e, 0x1170, 0x0096, 0x080c, 0x0fff,
+	0x0020, 0x2018, 0x9486, 0x003e, 0x1170, 0x0096, 0x080c, 0x100e,
 	0x2900, 0x009e, 0x05c0, 0xa806, 0x2048, 0xa860, 0x20e8, 0xa85c,
 	0x9080, 0x0002, 0x20a0, 0x3300, 0x908e, 0x0260, 0x0140, 0x2009,
 	0x0280, 0x9102, 0x920a, 0x0218, 0x2010, 0x2100, 0x9318, 0x2200,
 	0x9402, 0x1228, 0x2400, 0x9202, 0x2410, 0x9318, 0x9006, 0x2020,
 	0x22a8, 0xa800, 0x9200, 0xa802, 0x20e1, 0x0000, 0x4003, 0x83ff,
 	0x0180, 0x3300, 0x9086, 0x0280, 0x1130, 0x7814, 0x8000, 0x9085,
-	0x0080, 0x7816, 0x2e98, 0x2310, 0x84ff, 0x0904, 0xb2b1, 0x0804,
-	0xb2b3, 0x9085, 0x0001, 0x7817, 0x0000, 0x009e, 0x00fe, 0x00de,
+	0x0080, 0x7816, 0x2e98, 0x2310, 0x84ff, 0x0904, 0xb459, 0x0804,
+	0xb45b, 0x9085, 0x0001, 0x7817, 0x0000, 0x009e, 0x00fe, 0x00de,
 	0x001e, 0x0005, 0x00d6, 0x0036, 0x0096, 0x6314, 0x2348, 0xa87a,
-	0xa982, 0x080c, 0x6d0b, 0x009e, 0x003e, 0x00de, 0x0005, 0x91b6,
-	0x0015, 0x1118, 0x080c, 0xaf43, 0x0030, 0x91b6, 0x0016, 0x190c,
-	0x0dd5, 0x080c, 0xaf43, 0x0005, 0x20a9, 0x000e, 0x20e1, 0x0000,
+	0xa982, 0x080c, 0x6dbe, 0x009e, 0x003e, 0x00de, 0x0005, 0x91b6,
+	0x0015, 0x1118, 0x080c, 0xb0e7, 0x0030, 0x91b6, 0x0016, 0x190c,
+	0x0dc5, 0x080c, 0xb0e7, 0x0005, 0x20a9, 0x000e, 0x20e1, 0x0000,
 	0x2e98, 0x6014, 0x0096, 0x2048, 0xa860, 0x20e8, 0xa85c, 0x20a0,
-	0x009e, 0x4003, 0x0136, 0x9080, 0x001b, 0x20a0, 0x2011, 0x0006,
-	0x20a9, 0x0001, 0x3418, 0x8318, 0x23a0, 0x4003, 0x3318, 0x8318,
-	0x2398, 0x8211, 0x1db8, 0x2011, 0x0006, 0x013e, 0x20a0, 0x3318,
-	0x8318, 0x2398, 0x4003, 0x3418, 0x8318, 0x23a0, 0x8211, 0x1db8,
-	0x0096, 0x080c, 0xcc86, 0x0130, 0x6014, 0x2048, 0xa807, 0x0000,
-	0xa867, 0x0103, 0x009e, 0x0804, 0xaf43, 0x0096, 0x00d6, 0x0036,
-	0x7330, 0x9386, 0x0200, 0x11a8, 0x6010, 0x00b6, 0x2058, 0xb8cf,
-	0x0000, 0x00be, 0x6014, 0x9005, 0x0130, 0x2048, 0xa807, 0x0000,
-	0xa867, 0x0103, 0xab32, 0x080c, 0xaf43, 0x003e, 0x00de, 0x009e,
-	0x0005, 0x0011, 0x1d48, 0x0cc8, 0x0006, 0x0016, 0x080c, 0xd388,
-	0x0188, 0x6014, 0x9005, 0x1170, 0x600b, 0x0003, 0x601b, 0x0000,
-	0x6043, 0x0000, 0x2009, 0x0022, 0x080c, 0xb747, 0x9006, 0x001e,
-	0x000e, 0x0005, 0x9085, 0x0001, 0x0cd0, 0x0096, 0x0016, 0x20a9,
-	0x0014, 0x9e80, 0x000c, 0x20e1, 0x0000, 0x2098, 0x6014, 0x2048,
-	0xa860, 0x20e8, 0xa85c, 0x9080, 0x0002, 0x20a0, 0x4003, 0x2001,
-	0x0205, 0x2003, 0x0001, 0x2099, 0x0260, 0x20a9, 0x0016, 0x4003,
-	0x20a9, 0x000a, 0xa804, 0x2048, 0xa860, 0x20e8, 0xa85c, 0x9080,
-	0x0002, 0x20a0, 0x4003, 0x2001, 0x0205, 0x2003, 0x0002, 0x2099,
-	0x0260, 0x20a9, 0x0020, 0x4003, 0x2003, 0x0000, 0x6014, 0x2048,
-	0xa800, 0x2048, 0xa867, 0x0103, 0x080c, 0xaf43, 0x001e, 0x009e,
-	0x0005, 0x0096, 0x0016, 0x900e, 0x7030, 0x9086, 0x0100, 0x0140,
-	0x7038, 0x9084, 0x00ff, 0x800c, 0x703c, 0x9084, 0x00ff, 0x8004,
-	0x9080, 0x0004, 0x9108, 0x810b, 0x2011, 0x0002, 0x2019, 0x000c,
-	0x6014, 0x2048, 0x080c, 0xc837, 0x080c, 0xcc86, 0x0140, 0x6014,
-	0x2048, 0xa807, 0x0000, 0xa864, 0xa8e2, 0xa867, 0x0103, 0x080c,
-	0xaf43, 0x001e, 0x009e, 0x0005, 0x0016, 0x2009, 0x0000, 0x7030,
-	0x9086, 0x0200, 0x0110, 0x2009, 0x0001, 0x0096, 0x6014, 0x904d,
-	0x090c, 0x0dd5, 0xa97a, 0x080c, 0x6d17, 0x009e, 0x080c, 0xaf43,
-	0x001e, 0x0005, 0x0016, 0x0096, 0x7030, 0x9086, 0x0100, 0x1118,
-	0x2009, 0x0004, 0x0010, 0x7034, 0x800c, 0x810b, 0x2011, 0x000c,
-	0x2019, 0x000c, 0x6014, 0x2048, 0xa804, 0x0096, 0x9005, 0x0108,
-	0x2048, 0x080c, 0xc837, 0x009e, 0x080c, 0xcc86, 0x0148, 0xa804,
-	0x9005, 0x1158, 0xa807, 0x0000, 0xa864, 0xa8e2, 0xa867, 0x0103,
-	0x080c, 0xaf43, 0x009e, 0x001e, 0x0005, 0x0086, 0x2040, 0xa030,
-	0x8007, 0x9086, 0x0100, 0x1118, 0x080c, 0xb905, 0x00e0, 0xa034,
-	0x8007, 0x800c, 0x8806, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084,
-	0xffc0, 0x9080, 0x000c, 0xa87b, 0x0000, 0xa883, 0x0000, 0xa897,
-	0x4000, 0xaaa0, 0xab9c, 0xaca8, 0xada4, 0x2031, 0x0000, 0x2041,
-	0x1243, 0x0019, 0x0d08, 0x008e, 0x0898, 0x0096, 0x0006, 0x080c,
-	0x0fff, 0x000e, 0x01b0, 0xa8ab, 0x0dcb, 0xa876, 0x000e, 0xa8a2,
-	0x0006, 0xae6a, 0x2800, 0xa89e, 0xa97a, 0xaf72, 0xaa8e, 0xab92,
-	0xac96, 0xad9a, 0x0086, 0x2940, 0x080c, 0x10e9, 0x008e, 0x9085,
-	0x0001, 0x009e, 0x0005, 0x00e6, 0x00d6, 0x0026, 0x7008, 0x9084,
-	0x00ff, 0x6210, 0x00b6, 0x2258, 0xba10, 0x00be, 0x9206, 0x1520,
-	0x700c, 0x6210, 0x00b6, 0x2258, 0xba14, 0x00be, 0x9206, 0x11e0,
-	0x6043, 0x0000, 0x2c68, 0x0016, 0x2009, 0x0035, 0x080c, 0xd300,
-	0x001e, 0x1158, 0x622c, 0x2268, 0x2071, 0x026c, 0x6b20, 0x9386,
-	0x0003, 0x0130, 0x9386, 0x0006, 0x0128, 0x080c, 0xaf43, 0x0020,
-	0x0039, 0x0010, 0x080c, 0xb57c, 0x002e, 0x00de, 0x00ee, 0x0005,
-	0x0096, 0x6814, 0x2048, 0x9186, 0x0015, 0x0904, 0xb564, 0x918e,
-	0x0016, 0x1904, 0xb57a, 0x700c, 0x908c, 0xff00, 0x9186, 0x1700,
-	0x0120, 0x9186, 0x0300, 0x1904, 0xb53e, 0x89ff, 0x1138, 0x6800,
-	0x9086, 0x000f, 0x0904, 0xb521, 0x0804, 0xb578, 0x6808, 0x9086,
-	0xffff, 0x1904, 0xb566, 0xa87c, 0x9084, 0x0060, 0x9086, 0x0020,
-	0x1128, 0xa83c, 0xa940, 0x9105, 0x1904, 0xb566, 0x6824, 0xd084,
-	0x1904, 0xb566, 0xd0b4, 0x0158, 0x0016, 0x2001, 0x1985, 0x200c,
-	0x6018, 0x9102, 0x9082, 0x0005, 0x001e, 0x1a04, 0xb566, 0x080c,
-	0xce71, 0x685c, 0xa882, 0xa87c, 0xc0dc, 0xc0f4, 0xc0d4, 0xa87e,
-	0x0026, 0x900e, 0x6a18, 0x2001, 0x000a, 0x080c, 0x9027, 0xa884,
-	0x920a, 0x0208, 0x8011, 0xaa86, 0x82ff, 0x002e, 0x1138, 0x00c6,
-	0x2d60, 0x080c, 0xc999, 0x00ce, 0x0804, 0xb578, 0x00c6, 0xa868,
-	0xd0fc, 0x1118, 0x080c, 0x6141, 0x0010, 0x080c, 0x654e, 0x00ce,
-	0x1904, 0xb566, 0x00c6, 0x2d60, 0x080c, 0xaf43, 0x00ce, 0x0804,
-	0xb578, 0x00c6, 0x080c, 0xaf91, 0x0198, 0x6017, 0x0000, 0x6810,
-	0x6012, 0x080c, 0xd102, 0x6023, 0x0003, 0x6904, 0x00c6, 0x2d60,
-	0x080c, 0xaf43, 0x00ce, 0x080c, 0xafbe, 0x00ce, 0x0804, 0xb578,
-	0x2001, 0x1987, 0x2004, 0x6842, 0x00ce, 0x04d0, 0x7008, 0x9086,
-	0x000b, 0x11c8, 0x6010, 0x00b6, 0x2058, 0xb900, 0xc1bc, 0xb902,
-	0x00be, 0x00c6, 0x2d60, 0xa87b, 0x0003, 0x080c, 0xd342, 0x6007,
-	0x0085, 0x6003, 0x000b, 0x6023, 0x0002, 0x080c, 0x91b1, 0x080c,
-	0x9763, 0x00ce, 0x00e8, 0x700c, 0x9086, 0x2a00, 0x1138, 0x2001,
-	0x1987, 0x2004, 0x6842, 0x00a0, 0x0479, 0x00a0, 0x89ff, 0x090c,
-	0x0dd5, 0x00c6, 0x00d6, 0x2d60, 0xa867, 0x0103, 0xa87b, 0x0003,
-	0x080c, 0x6b33, 0x080c, 0xce71, 0x080c, 0xaf74, 0x00de, 0x00ce,
-	0x080c, 0xaf43, 0x009e, 0x0005, 0x9186, 0x0015, 0x1128, 0x2001,
-	0x1987, 0x2004, 0x6842, 0x0068, 0x918e, 0x0016, 0x1160, 0x00c6,
-	0x2d00, 0x2060, 0x080c, 0xe997, 0x080c, 0x876f, 0x080c, 0xaf43,
-	0x00ce, 0x080c, 0xaf43, 0x0005, 0x0026, 0x0036, 0x0046, 0x7228,
-	0xacb0, 0xabac, 0xd2f4, 0x0130, 0x2001, 0x1987, 0x2004, 0x6842,
-	0x0804, 0xb5f6, 0x00c6, 0x2d60, 0x080c, 0xc898, 0x00ce, 0x6804,
-	0x9086, 0x0050, 0x1168, 0x00c6, 0x2d00, 0x2060, 0x6003, 0x0001,
-	0x6007, 0x0050, 0x080c, 0x91b1, 0x080c, 0x9763, 0x00ce, 0x04f0,
-	0x6800, 0x9086, 0x000f, 0x01a8, 0x89ff, 0x090c, 0x0dd5, 0x6800,
-	0x9086, 0x0004, 0x1190, 0xa87c, 0xd0ac, 0x0178, 0xa843, 0x0fff,
-	0xa83f, 0x0fff, 0xa880, 0xc0fc, 0xa882, 0x2001, 0x0001, 0x6832,
-	0x0400, 0x2001, 0x0007, 0x6832, 0x00e0, 0xa87c, 0xd0b4, 0x1150,
-	0xd0ac, 0x0db8, 0x6824, 0xd0f4, 0x1d48, 0xa838, 0xa934, 0x9105,
-	0x0d80, 0x0c20, 0xd2ec, 0x1d68, 0x7024, 0x9306, 0x1118, 0x7020,
-	0x9406, 0x0d38, 0x7020, 0x683e, 0x7024, 0x683a, 0x2001, 0x0005,
-	0x6832, 0x080c, 0xcff9, 0x080c, 0x9763, 0x0010, 0x080c, 0xaf43,
-	0x004e, 0x003e, 0x002e, 0x0005, 0x00e6, 0x00d6, 0x0026, 0x7008,
-	0x9084, 0x00ff, 0x6210, 0x00b6, 0x2258, 0xba10, 0x00be, 0x9206,
-	0x1904, 0xb661, 0x700c, 0x6210, 0x00b6, 0x2258, 0xba14, 0x00be,
-	0x9206, 0x1904, 0xb661, 0x6038, 0x2068, 0x6824, 0xc0dc, 0x6826,
-	0x6a20, 0x9286, 0x0007, 0x0904, 0xb661, 0x9286, 0x0002, 0x0904,
-	0xb661, 0x9286, 0x0000, 0x05e8, 0x6808, 0x633c, 0x9306, 0x15c8,
-	0x2071, 0x026c, 0x9186, 0x0015, 0x0570, 0x918e, 0x0016, 0x1100,
-	0x00c6, 0x6038, 0x2060, 0x6104, 0x9186, 0x004b, 0x01c0, 0x9186,
-	0x004c, 0x01a8, 0x9186, 0x004d, 0x0190, 0x9186, 0x004e, 0x0178,
-	0x9186, 0x0052, 0x0160, 0x6014, 0x0096, 0x2048, 0x080c, 0xcc86,
-	0x090c, 0x0dd5, 0xa87b, 0x0003, 0x009e, 0x080c, 0xd342, 0x6007,
-	0x0085, 0x6003, 0x000b, 0x6023, 0x0002, 0x080c, 0x91b1, 0x080c,
-	0x9763, 0x00ce, 0x0030, 0x6038, 0x2070, 0x2001, 0x1987, 0x2004,
-	0x7042, 0x080c, 0xaf43, 0x002e, 0x00de, 0x00ee, 0x0005, 0x00b6,
-	0x0096, 0x00f6, 0x6014, 0x2048, 0x6010, 0x2058, 0x91b6, 0x0015,
-	0x0130, 0xba08, 0xbb0c, 0xbc00, 0xc48c, 0xbc02, 0x0460, 0x0096,
-	0x0156, 0x0036, 0x0026, 0x2b48, 0x9e90, 0x0010, 0x2019, 0x000a,
-	0x20a9, 0x0004, 0x080c, 0xbf11, 0x002e, 0x003e, 0x015e, 0x009e,
-	0x1904, 0xb6d0, 0x0096, 0x0156, 0x0036, 0x0026, 0x2b48, 0x9e90,
-	0x0014, 0x2019, 0x0006, 0x20a9, 0x0004, 0x080c, 0xbf11, 0x002e,
-	0x003e, 0x015e, 0x009e, 0x15a0, 0x7238, 0xba0a, 0x733c, 0xbb0e,
-	0xbc00, 0xc48d, 0xbc02, 0xa804, 0x9005, 0x1128, 0x00fe, 0x009e,
-	0x00be, 0x0804, 0xb348, 0x0096, 0x2048, 0xaa12, 0xab16, 0xac0a,
-	0x009e, 0x8006, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0,
-	0x9080, 0x0002, 0x2009, 0x002b, 0xaaa0, 0xab9c, 0xaca8, 0xada4,
-	0x2031, 0x0000, 0x2041, 0x1243, 0x080c, 0xb45d, 0x0130, 0x00fe,
-	0x009e, 0x080c, 0xaf43, 0x00be, 0x0005, 0x080c, 0xb905, 0x0cb8,
-	0x2b78, 0x00f6, 0x080c, 0x321e, 0x080c, 0xd39d, 0x00fe, 0x00c6,
-	0x080c, 0xaeed, 0x2f00, 0x6012, 0x6017, 0x0000, 0x6023, 0x0001,
-	0x6007, 0x0001, 0x6003, 0x0001, 0x2001, 0x0007, 0x080c, 0x65e9,
-	0x080c, 0x6615, 0x080c, 0x91f9, 0x080c, 0x9763, 0x00ce, 0x0804,
-	0xb6a3, 0x2100, 0x91b2, 0x0053, 0x1a0c, 0x0dd5, 0x91b2, 0x0040,
-	0x1a04, 0xb759, 0x0002, 0xb747, 0xb747, 0xb73d, 0xb747, 0xb747,
-	0xb747, 0xb73b, 0xb73b, 0xb73b, 0xb73b, 0xb73b, 0xb73b, 0xb73b,
-	0xb73b, 0xb73b, 0xb73b, 0xb73b, 0xb73b, 0xb73b, 0xb73b, 0xb73b,
-	0xb73b, 0xb73b, 0xb73b, 0xb73b, 0xb73b, 0xb73b, 0xb73b, 0xb73b,
-	0xb73b, 0xb73b, 0xb747, 0xb73b, 0xb747, 0xb747, 0xb73b, 0xb73b,
-	0xb73b, 0xb73b, 0xb73b, 0xb73d, 0xb73b, 0xb73b, 0xb73b, 0xb73b,
-	0xb73b, 0xb73b, 0xb73b, 0xb73b, 0xb73b, 0xb747, 0xb747, 0xb73b,
-	0xb73b, 0xb73b, 0xb73b, 0xb73b, 0xb73b, 0xb73b, 0xb73b, 0xb73b,
-	0xb747, 0xb73b, 0xb73b, 0x080c, 0x0dd5, 0x0066, 0x00b6, 0x6610,
-	0x2658, 0xb8cc, 0xc08c, 0xb8ce, 0x00be, 0x006e, 0x0000, 0x6003,
-	0x0001, 0x6106, 0x9186, 0x0032, 0x0118, 0x080c, 0x91f9, 0x0010,
-	0x080c, 0x91b1, 0x0126, 0x2091, 0x8000, 0x080c, 0x9763, 0x012e,
-	0x0005, 0x2600, 0x0002, 0xb747, 0xb747, 0xb76d, 0xb747, 0xb747,
-	0xb76d, 0xb76d, 0xb76d, 0xb76d, 0xb747, 0xb76d, 0xb747, 0xb76d,
-	0xb747, 0xb76d, 0xb76d, 0xb76d, 0xb76d, 0x080c, 0x0dd5, 0x6004,
-	0x90b2, 0x0053, 0x1a0c, 0x0dd5, 0x91b6, 0x0013, 0x0904, 0xb831,
-	0x91b6, 0x0027, 0x1904, 0xb7ec, 0x080c, 0x9657, 0x6004, 0x080c,
-	0xce7d, 0x01b0, 0x080c, 0xce8e, 0x01a8, 0x908e, 0x0021, 0x0904,
-	0xb7e9, 0x908e, 0x0022, 0x1130, 0x080c, 0xb374, 0x0904, 0xb7e5,
-	0x0804, 0xb7e6, 0x908e, 0x003d, 0x0904, 0xb7e9, 0x0804, 0xb7df,
-	0x080c, 0x3247, 0x2001, 0x0007, 0x080c, 0x65e9, 0x6010, 0x00b6,
-	0x2058, 0xb9a0, 0x00be, 0x080c, 0xb905, 0x9186, 0x007e, 0x1148,
-	0x2001, 0x1837, 0x2014, 0xc285, 0x080c, 0x743e, 0x1108, 0xc2ad,
-	0x2202, 0x0036, 0x0026, 0x2019, 0x0028, 0x2110, 0x080c, 0xeaa3,
-	0x002e, 0x003e, 0x0016, 0x0026, 0x0036, 0x2110, 0x2019, 0x0028,
-	0x080c, 0x9356, 0x0076, 0x903e, 0x080c, 0x9229, 0x6010, 0x00b6,
-	0x905d, 0x0100, 0x00be, 0x2c08, 0x080c, 0xe477, 0x007e, 0x003e,
-	0x002e, 0x001e, 0x080c, 0xd39d, 0x0016, 0x080c, 0xd0fa, 0x080c,
-	0xaf43, 0x001e, 0x080c, 0x331a, 0x080c, 0x9763, 0x0030, 0x080c,
-	0xd0fa, 0x080c, 0xaf43, 0x080c, 0x9763, 0x0005, 0x080c, 0xb905,
-	0x0cb0, 0x080c, 0xb941, 0x0c98, 0x9186, 0x0014, 0x1db0, 0x080c,
-	0x9657, 0x6004, 0x908e, 0x0022, 0x1118, 0x080c, 0xb374, 0x0d68,
-	0x080c, 0x321e, 0x080c, 0xd39d, 0x080c, 0xce7d, 0x1190, 0x080c,
-	0x3247, 0x6010, 0x00b6, 0x2058, 0xb9a0, 0x00be, 0x080c, 0xb905,
-	0x9186, 0x007e, 0x1128, 0x2001, 0x1837, 0x200c, 0xc185, 0x2102,
-	0x0870, 0x080c, 0xce8e, 0x1118, 0x080c, 0xb905, 0x0840, 0x6004,
-	0x908e, 0x0032, 0x1160, 0x00e6, 0x00f6, 0x2071, 0x189e, 0x2079,
-	0x0000, 0x080c, 0x35b5, 0x00fe, 0x00ee, 0x0804, 0xb7df, 0x6004,
-	0x908e, 0x0021, 0x0d48, 0x908e, 0x0022, 0x090c, 0xb905, 0x0804,
-	0xb7df, 0x90b2, 0x0040, 0x1a04, 0xb8e1, 0x2008, 0x0002, 0xb879,
-	0xb87a, 0xb87d, 0xb880, 0xb883, 0xb886, 0xb877, 0xb877, 0xb877,
-	0xb877, 0xb877, 0xb877, 0xb877, 0xb877, 0xb877, 0xb877, 0xb877,
-	0xb877, 0xb877, 0xb877, 0xb877, 0xb877, 0xb877, 0xb877, 0xb877,
-	0xb877, 0xb877, 0xb877, 0xb877, 0xb877, 0xb889, 0xb896, 0xb877,
-	0xb898, 0xb896, 0xb877, 0xb877, 0xb877, 0xb877, 0xb877, 0xb896,
-	0xb896, 0xb877, 0xb877, 0xb877, 0xb877, 0xb877, 0xb877, 0xb877,
-	0xb877, 0xb8c8, 0xb896, 0xb877, 0xb892, 0xb877, 0xb877, 0xb877,
-	0xb893, 0xb877, 0xb877, 0xb877, 0xb896, 0xb8bf, 0xb877, 0x080c,
-	0x0dd5, 0x00e0, 0x2001, 0x000b, 0x0420, 0x2001, 0x0003, 0x0408,
-	0x2001, 0x0005, 0x00f0, 0x2001, 0x0001, 0x00d8, 0x2001, 0x0009,
-	0x00c0, 0x080c, 0x9657, 0x6003, 0x0005, 0x080c, 0xd3a0, 0x080c,
-	0x9763, 0x0070, 0x0018, 0x0010, 0x080c, 0x65e9, 0x0804, 0xb8d9,
-	0x080c, 0x9657, 0x080c, 0xd3a0, 0x6003, 0x0004, 0x080c, 0x9763,
-	0x0005, 0x080c, 0x65e9, 0x080c, 0x9657, 0x6003, 0x0002, 0x0036,
-	0x2019, 0x1852, 0x2304, 0x9084, 0xff00, 0x1120, 0x2001, 0x1985,
-	0x201c, 0x0040, 0x8007, 0x909a, 0x0004, 0x0ec0, 0x8003, 0x801b,
-	0x831b, 0x9318, 0x631a, 0x003e, 0x080c, 0x9763, 0x0c08, 0x080c,
-	0x9657, 0x080c, 0xd0fa, 0x080c, 0xaf43, 0x080c, 0x9763, 0x08c0,
-	0x00e6, 0x00f6, 0x2071, 0x189e, 0x2079, 0x0000, 0x080c, 0x35b5,
-	0x00fe, 0x00ee, 0x080c, 0x9657, 0x080c, 0xaf43, 0x080c, 0x9763,
-	0x0838, 0x080c, 0x9657, 0x6003, 0x0002, 0x080c, 0xd3a0, 0x0804,
-	0x9763, 0x2600, 0x2008, 0x0002, 0xb8f8, 0xb8d9, 0xb8f6, 0xb8d9,
-	0xb8d9, 0xb8f6, 0xb8f6, 0xb8f6, 0xb8f6, 0xb8d9, 0xb8f6, 0xb8d9,
-	0xb8f6, 0xb8d9, 0xb8f6, 0xb8f6, 0xb8f6, 0xb8f6, 0x080c, 0x0dd5,
-	0x080c, 0x9657, 0x0096, 0x6014, 0x2048, 0x080c, 0x6d17, 0x009e,
-	0x080c, 0xaf43, 0x080c, 0x9763, 0x0005, 0x00e6, 0x0096, 0x0026,
-	0x0016, 0x080c, 0xcc86, 0x0568, 0x6014, 0x2048, 0xa864, 0x9086,
-	0x0139, 0x11a8, 0xa894, 0x9086, 0x0056, 0x1148, 0x080c, 0x54f7,
-	0x0130, 0x2001, 0x0000, 0x900e, 0x2011, 0x4000, 0x0028, 0x2001,
-	0x0030, 0x900e, 0x2011, 0x4005, 0x080c, 0xd267, 0x0090, 0xa868,
-	0xd0fc, 0x0178, 0xa807, 0x0000, 0x0016, 0x6004, 0x908e, 0x0021,
-	0x0168, 0x908e, 0x003d, 0x0150, 0x001e, 0xa867, 0x0103, 0xa833,
-	0x0100, 0x001e, 0x002e, 0x009e, 0x00ee, 0x0005, 0x001e, 0x0009,
-	0x0cc0, 0x0096, 0x6014, 0x2048, 0xa800, 0x2048, 0xa867, 0x0103,
-	0xa823, 0x8001, 0x009e, 0x0005, 0x00b6, 0x6610, 0x2658, 0xb804,
-	0x9084, 0x00ff, 0x90b2, 0x000c, 0x1a0c, 0x0dd5, 0x6604, 0x96b6,
-	0x004d, 0x1120, 0x080c, 0xd186, 0x0804, 0xb9d1, 0x6604, 0x96b6,
-	0x0043, 0x1120, 0x080c, 0xd1cf, 0x0804, 0xb9d1, 0x6604, 0x96b6,
-	0x004b, 0x1120, 0x080c, 0xd1fb, 0x0804, 0xb9d1, 0x6604, 0x96b6,
-	0x0033, 0x1120, 0x080c, 0xd11c, 0x0804, 0xb9d1, 0x6604, 0x96b6,
-	0x0028, 0x1120, 0x080c, 0xcecc, 0x0804, 0xb9d1, 0x6604, 0x96b6,
-	0x0029, 0x1120, 0x080c, 0xcf0d, 0x0804, 0xb9d1, 0x6604, 0x96b6,
-	0x001f, 0x1120, 0x080c, 0xb31c, 0x0804, 0xb9d1, 0x6604, 0x96b6,
-	0x0000, 0x1118, 0x080c, 0xb667, 0x04e0, 0x6604, 0x96b6, 0x0022,
-	0x1118, 0x080c, 0xb355, 0x04a8, 0x6604, 0x96b6, 0x0035, 0x1118,
-	0x080c, 0xb47b, 0x0470, 0x6604, 0x96b6, 0x0039, 0x1118, 0x080c,
-	0xb5fc, 0x0438, 0x6604, 0x96b6, 0x003d, 0x1118, 0x080c, 0xb38d,
-	0x0400, 0x6604, 0x96b6, 0x0044, 0x1118, 0x080c, 0xb3c9, 0x00c8,
-	0x6604, 0x96b6, 0x0049, 0x1118, 0x080c, 0xb40a, 0x0090, 0x6604,
-	0x96b6, 0x0041, 0x1118, 0x080c, 0xb3f4, 0x0058, 0x91b6, 0x0015,
-	0x1110, 0x0063, 0x0030, 0x91b6, 0x0016, 0x1128, 0x00be, 0x0804,
-	0xbc2d, 0x00be, 0x0005, 0x080c, 0xafd9, 0x0cd8, 0xb9ee, 0xb9f1,
-	0xb9ee, 0xba38, 0xb9ee, 0xbba1, 0xbc3a, 0xb9ee, 0xb9ee, 0xbc03,
-	0xb9ee, 0xbc19, 0x0096, 0x601f, 0x0000, 0x6014, 0x2048, 0xa800,
-	0x2048, 0xa867, 0x0103, 0x009e, 0x0804, 0xaf43, 0xa001, 0xa001,
-	0x0005, 0x00e6, 0x2071, 0x1800, 0x7090, 0x9086, 0x0074, 0x1540,
-	0x080c, 0xe448, 0x11b0, 0x6010, 0x00b6, 0x2058, 0x7030, 0xd08c,
-	0x0128, 0xb800, 0xd0bc, 0x0110, 0xc0c5, 0xb802, 0x00f9, 0x00be,
-	0x2001, 0x0006, 0x080c, 0x65e9, 0x080c, 0x3247, 0x080c, 0xaf43,
-	0x0098, 0x2001, 0x000a, 0x080c, 0x65e9, 0x080c, 0x3247, 0x6003,
-	0x0001, 0x6007, 0x0001, 0x080c, 0x91f9, 0x080c, 0x9763, 0x0020,
-	0x2001, 0x0001, 0x080c, 0xbb71, 0x00ee, 0x0005, 0x00d6, 0xb800,
-	0xd084, 0x0160, 0x9006, 0x080c, 0x65d5, 0x2069, 0x1847, 0x6804,
-	0xd0a4, 0x0120, 0x2001, 0x0006, 0x080c, 0x6615, 0x00de, 0x0005,
-	0x00b6, 0x0096, 0x00d6, 0x2011, 0x1824, 0x2204, 0x9086, 0x0074,
-	0x1904, 0xbb46, 0x6010, 0x2058, 0xbaa0, 0x9286, 0x007e, 0x1120,
-	0x080c, 0xbd87, 0x0804, 0xbaaa, 0x080c, 0xbd7c, 0x6010, 0x2058,
-	0xbaa0, 0x9286, 0x0080, 0x1510, 0x6014, 0x9005, 0x01a8, 0x2048,
-	0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, 0x1140, 0x2001, 0x0000,
-	0x900e, 0x2011, 0x4000, 0x080c, 0xd267, 0x0030, 0xa807, 0x0000,
-	0xa867, 0x0103, 0xa833, 0x0200, 0x2001, 0x0006, 0x080c, 0x65e9,
-	0x080c, 0x3247, 0x080c, 0xaf43, 0x0804, 0xbb4b, 0x080c, 0xbb59,
-	0x6014, 0x9005, 0x0190, 0x2048, 0xa868, 0xd0f4, 0x01e8, 0xa864,
-	0x9084, 0x00ff, 0x9086, 0x0039, 0x1d08, 0x2001, 0x0000, 0x900e,
-	0x2011, 0x4000, 0x080c, 0xd267, 0x08f8, 0x080c, 0xbb4f, 0x0160,
-	0x9006, 0x080c, 0x65d5, 0x2001, 0x0004, 0x080c, 0x6615, 0x2001,
-	0x0007, 0x080c, 0x65e9, 0x08a0, 0x2001, 0x0004, 0x080c, 0x65e9,
-	0x6003, 0x0001, 0x6007, 0x0003, 0x080c, 0x91f9, 0x080c, 0x9763,
-	0x0804, 0xbb4b, 0xb85c, 0xd0e4, 0x01d8, 0x080c, 0xd09c, 0x080c,
-	0x743e, 0x0118, 0xd0dc, 0x1904, 0xba6c, 0x2011, 0x1837, 0x2204,
-	0xc0ad, 0x2012, 0x2001, 0x196c, 0x2004, 0x00f6, 0x2079, 0x0100,
-	0x78e3, 0x0000, 0x080c, 0x28f0, 0x78e2, 0x00fe, 0x0804, 0xba6c,
-	0x080c, 0xd0d9, 0x2011, 0x1837, 0x2204, 0xc0a5, 0x2012, 0x0006,
-	0x080c, 0xe5cd, 0x000e, 0x1904, 0xba6c, 0xc0b5, 0x2012, 0x2001,
-	0x0006, 0x080c, 0x65e9, 0x9006, 0x080c, 0x65d5, 0x00c6, 0x2001,
-	0x180f, 0x2004, 0xd09c, 0x0520, 0x00f6, 0x2079, 0x0100, 0x00e6,
-	0x2071, 0x1800, 0x700c, 0x9084, 0x00ff, 0x78e6, 0x707e, 0x7010,
-	0x78ea, 0x7082, 0x908c, 0x00ff, 0x00ee, 0x780c, 0xc0b5, 0x780e,
-	0x00fe, 0x080c, 0x28c5, 0x00f6, 0x2100, 0x900e, 0x080c, 0x287c,
-	0x795e, 0x00fe, 0x9186, 0x0081, 0x01d8, 0x2009, 0x0081, 0x00c8,
-	0x2009, 0x00ef, 0x00f6, 0x2079, 0x0100, 0x79ea, 0x7932, 0x7936,
-	0x780c, 0xc0b5, 0x780e, 0x00fe, 0x080c, 0x28c5, 0x00f6, 0x2079,
-	0x1800, 0x7982, 0x2100, 0x900e, 0x080c, 0x287c, 0x795e, 0x00fe,
-	0x8108, 0x080c, 0x6638, 0x2b00, 0x00ce, 0x1904, 0xba6c, 0x6012,
-	0x2009, 0x180f, 0x210c, 0xd19c, 0x0150, 0x2009, 0x027c, 0x210c,
-	0x918c, 0x00ff, 0xb912, 0x2009, 0x027d, 0x210c, 0xb916, 0x2001,
-	0x0002, 0x080c, 0x65e9, 0x6023, 0x0001, 0x6003, 0x0001, 0x6007,
-	0x0002, 0x080c, 0x91f9, 0x080c, 0x9763, 0x0028, 0x080c, 0xb905,
-	0x2001, 0x0001, 0x0431, 0x00de, 0x009e, 0x00be, 0x0005, 0x2001,
-	0x1810, 0x2004, 0xd0a4, 0x0120, 0x2001, 0x1848, 0x2004, 0xd0ac,
-	0x0005, 0x00e6, 0x080c, 0xeafc, 0x0190, 0x2071, 0x0260, 0x7108,
-	0x720c, 0x918c, 0x00ff, 0x1118, 0x9284, 0xff00, 0x0140, 0x6010,
-	0x2058, 0xb8a0, 0x9084, 0xff80, 0x1110, 0xb912, 0xba16, 0x00ee,
-	0x0005, 0x2030, 0x9005, 0x0158, 0x2001, 0x0007, 0x080c, 0x65e9,
-	0x080c, 0x5771, 0x1120, 0x2001, 0x0007, 0x080c, 0x6615, 0x2600,
-	0x9005, 0x11b0, 0x6014, 0x0096, 0x2048, 0xa868, 0x009e, 0xd0fc,
-	0x1178, 0x0036, 0x0046, 0x6010, 0x00b6, 0x2058, 0xbba0, 0x00be,
-	0x2021, 0x0004, 0x2011, 0x8014, 0x080c, 0x4b7f, 0x004e, 0x003e,
-	0x080c, 0x3247, 0x6020, 0x9086, 0x000a, 0x1108, 0x0005, 0x0804,
-	0xaf43, 0x00b6, 0x00e6, 0x0026, 0x0016, 0x2071, 0x1800, 0x7090,
-	0x9086, 0x0014, 0x1904, 0xbbf9, 0x080c, 0x5771, 0x1170, 0x6014,
-	0x9005, 0x1158, 0x0036, 0x0046, 0x6010, 0x2058, 0xbba0, 0x2021,
-	0x0006, 0x080c, 0x4d36, 0x004e, 0x003e, 0x00d6, 0x6010, 0x2058,
-	0x080c, 0x6734, 0x080c, 0xba26, 0x00de, 0x080c, 0xbe4d, 0x1588,
-	0x6010, 0x2058, 0xb890, 0x9005, 0x0560, 0x2001, 0x0006, 0x080c,
-	0x65e9, 0x0096, 0x6014, 0x904d, 0x01d0, 0xa864, 0x9084, 0x00ff,
-	0x9086, 0x0039, 0x1140, 0x2001, 0x0000, 0x900e, 0x2011, 0x4000,
-	0x080c, 0xd267, 0x0060, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0029,
-	0x0130, 0xa807, 0x0000, 0xa867, 0x0103, 0xa833, 0x0200, 0x009e,
-	0x080c, 0x3247, 0x6020, 0x9086, 0x000a, 0x0140, 0x080c, 0xaf43,
-	0x0028, 0x080c, 0xb905, 0x9006, 0x080c, 0xbb71, 0x001e, 0x002e,
-	0x00ee, 0x00be, 0x0005, 0x2011, 0x1824, 0x2204, 0x9086, 0x0014,
-	0x1160, 0x2001, 0x0002, 0x080c, 0x65e9, 0x6003, 0x0001, 0x6007,
-	0x0001, 0x080c, 0x91f9, 0x0804, 0x9763, 0x2001, 0x0001, 0x0804,
-	0xbb71, 0x2030, 0x2011, 0x1824, 0x2204, 0x9086, 0x0004, 0x1148,
-	0x96b6, 0x000b, 0x1120, 0x2001, 0x0007, 0x080c, 0x65e9, 0x0804,
-	0xaf43, 0x2001, 0x0001, 0x0804, 0xbb71, 0x0002, 0xb9ee, 0xbc45,
-	0xb9ee, 0xbc86, 0xb9ee, 0xbd33, 0xbc3a, 0xb9ee, 0xb9ee, 0xbd47,
-	0xb9ee, 0xbd59, 0x6604, 0x9686, 0x0003, 0x0904, 0xbba1, 0x96b6,
-	0x001e, 0x1110, 0x080c, 0xaf43, 0x0005, 0x00b6, 0x00d6, 0x00c6,
-	0x080c, 0xbd6b, 0x11a0, 0x9006, 0x080c, 0x65d5, 0x080c, 0x321e,
-	0x080c, 0xd39d, 0x2001, 0x0002, 0x080c, 0x65e9, 0x6003, 0x0001,
-	0x6007, 0x0002, 0x080c, 0x91f9, 0x080c, 0x9763, 0x0418, 0x2009,
-	0x026e, 0x2104, 0x9086, 0x0009, 0x1160, 0x6010, 0x2058, 0xb840,
-	0x9084, 0x00ff, 0x9005, 0x0170, 0x8001, 0xb842, 0x601b, 0x000a,
-	0x0088, 0x2009, 0x026f, 0x2104, 0x9084, 0xff00, 0x9086, 0x1900,
-	0x1108, 0x08a0, 0x080c, 0x321e, 0x080c, 0xd39d, 0x2001, 0x0001,
-	0x080c, 0xbb71, 0x00ce, 0x00de, 0x00be, 0x0005, 0x0096, 0x00b6,
-	0x0026, 0x9016, 0x080c, 0xbd79, 0x00d6, 0x2069, 0x197b, 0x2d04,
-	0x9005, 0x0168, 0x6010, 0x2058, 0xb8a0, 0x9086, 0x007e, 0x1138,
-	0x2069, 0x1820, 0x2d04, 0x8000, 0x206a, 0x00de, 0x0010, 0x00de,
-	0x0088, 0x9006, 0x080c, 0x65d5, 0x2001, 0x0002, 0x080c, 0x65e9,
-	0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x91f9, 0x080c, 0x9763,
-	0x0804, 0xbd03, 0x080c, 0xcc86, 0x01b0, 0x6014, 0x2048, 0xa864,
-	0x2010, 0x9086, 0x0139, 0x1138, 0x6007, 0x0016, 0x2001, 0x0002,
-	0x080c, 0xd2c1, 0x00b0, 0x6014, 0x2048, 0xa864, 0xd0fc, 0x0118,
-	0x2001, 0x0001, 0x0ca8, 0x2001, 0x180e, 0x2004, 0xd0dc, 0x0148,
-	0x6010, 0x2058, 0xb840, 0x9084, 0x00ff, 0x9005, 0x1110, 0x9006,
-	0x0c38, 0x080c, 0xb905, 0x2009, 0x026e, 0x2134, 0x96b4, 0x00ff,
-	0x9686, 0x0005, 0x0520, 0x9686, 0x000b, 0x01c8, 0x2009, 0x026f,
-	0x2104, 0x9084, 0xff00, 0x1118, 0x9686, 0x0009, 0x01c0, 0x9086,
-	0x1900, 0x1168, 0x9686, 0x0009, 0x0190, 0x2001, 0x0004, 0x080c,
-	0x65e9, 0x2001, 0x0028, 0x601a, 0x6007, 0x0052, 0x0020, 0x2001,
-	0x0001, 0x080c, 0xbb71, 0x002e, 0x00be, 0x009e, 0x0005, 0x9286,
-	0x0139, 0x0160, 0x6014, 0x2048, 0x080c, 0xcc86, 0x0140, 0xa864,
-	0x9086, 0x0139, 0x0118, 0xa868, 0xd0fc, 0x0108, 0x0c40, 0x6010,
-	0x2058, 0xb840, 0x9084, 0x00ff, 0x9005, 0x0138, 0x8001, 0xb842,
-	0x601b, 0x000a, 0x6007, 0x0016, 0x08f0, 0xb8a0, 0x9086, 0x007e,
-	0x1138, 0x00e6, 0x2071, 0x1800, 0x080c, 0x6040, 0x00ee, 0x0010,
-	0x080c, 0x321e, 0x0860, 0x080c, 0xbd79, 0x1160, 0x2001, 0x0004,
-	0x080c, 0x65e9, 0x6003, 0x0001, 0x6007, 0x0003, 0x080c, 0x91f9,
-	0x0804, 0x9763, 0x080c, 0xb905, 0x9006, 0x0804, 0xbb71, 0x0489,
-	0x1160, 0x2001, 0x0008, 0x080c, 0x65e9, 0x6003, 0x0001, 0x6007,
-	0x0005, 0x080c, 0x91f9, 0x0804, 0x9763, 0x2001, 0x0001, 0x0804,
-	0xbb71, 0x00f9, 0x1160, 0x2001, 0x000a, 0x080c, 0x65e9, 0x6003,
-	0x0001, 0x6007, 0x0001, 0x080c, 0x91f9, 0x0804, 0x9763, 0x2001,
-	0x0001, 0x0804, 0xbb71, 0x2009, 0x026e, 0x2104, 0x9086, 0x0003,
-	0x1138, 0x2009, 0x026f, 0x2104, 0x9084, 0xff00, 0x9086, 0x2a00,
-	0x0005, 0x9085, 0x0001, 0x0005, 0x00b6, 0x00c6, 0x0016, 0x6110,
-	0x2158, 0x080c, 0x66a8, 0x001e, 0x00ce, 0x00be, 0x0005, 0x00b6,
-	0x00f6, 0x00e6, 0x00d6, 0x0036, 0x0016, 0x6010, 0x2058, 0x2009,
-	0x1837, 0x2104, 0x9085, 0x0003, 0x200a, 0x080c, 0xbe1f, 0x0560,
-	0x2009, 0x1837, 0x2104, 0xc0cd, 0x200a, 0x080c, 0x6a08, 0x0158,
-	0x9006, 0x2020, 0x2009, 0x002a, 0x080c, 0xe73a, 0x2001, 0x180c,
-	0x200c, 0xc195, 0x2102, 0x2019, 0x002a, 0x2009, 0x0001, 0x080c,
-	0x31e9, 0x00e6, 0x2071, 0x1800, 0x080c, 0x2ff5, 0x00ee, 0x00c6,
-	0x0156, 0x20a9, 0x0781, 0x2009, 0x007f, 0x080c, 0x331a, 0x8108,
-	0x1f04, 0xbdbd, 0x015e, 0x00ce, 0x080c, 0xbd7c, 0x2071, 0x0260,
-	0x2079, 0x0200, 0x7817, 0x0001, 0x2001, 0x1837, 0x200c, 0xc1c5,
-	0x7018, 0xd0fc, 0x0110, 0xd0dc, 0x0118, 0x7038, 0xd0dc, 0x1108,
-	0xc1c4, 0x7817, 0x0000, 0x2001, 0x1837, 0x2102, 0x2079, 0x0100,
-	0x2e04, 0x9084, 0x00ff, 0x2069, 0x181f, 0x206a, 0x78e6, 0x0006,
-	0x8e70, 0x2e04, 0x2069, 0x1820, 0x206a, 0x78ea, 0x7832, 0x7836,
-	0x2010, 0x9084, 0xff00, 0x001e, 0x9105, 0x2009, 0x182c, 0x200a,
-	0x2200, 0x9084, 0x00ff, 0x2008, 0x080c, 0x28c5, 0x080c, 0x743e,
-	0x0170, 0x2071, 0x0260, 0x2069, 0x1981, 0x7048, 0x206a, 0x704c,
-	0x6806, 0x7050, 0x680a, 0x7054, 0x680e, 0x080c, 0xd09c, 0x0040,
-	0x2001, 0x0006, 0x080c, 0x65e9, 0x080c, 0x3247, 0x080c, 0xaf43,
-	0x001e, 0x003e, 0x00de, 0x00ee, 0x00fe, 0x00be, 0x0005, 0x0096,
-	0x0026, 0x0036, 0x00e6, 0x0156, 0x2019, 0x182c, 0x231c, 0x83ff,
-	0x01f0, 0x2071, 0x0260, 0x7200, 0x9294, 0x00ff, 0x7004, 0x9084,
-	0xff00, 0x9205, 0x9306, 0x1198, 0x2011, 0x0276, 0x20a9, 0x0004,
-	0x2b48, 0x2019, 0x000a, 0x080c, 0xbf11, 0x1148, 0x2011, 0x027a,
-	0x20a9, 0x0004, 0x2019, 0x0006, 0x080c, 0xbf11, 0x1100, 0x015e,
-	0x00ee, 0x003e, 0x002e, 0x009e, 0x0005, 0x00e6, 0x2071, 0x0260,
-	0x7034, 0x9086, 0x0014, 0x11a8, 0x7038, 0x9086, 0x0800, 0x1188,
-	0x703c, 0xd0ec, 0x0160, 0x9084, 0x0f00, 0x9086, 0x0100, 0x1138,
-	0x7054, 0xd0a4, 0x1110, 0xd0ac, 0x0110, 0x9006, 0x0010, 0x9085,
-	0x0001, 0x00ee, 0x0005, 0x00e6, 0x0096, 0x00c6, 0x0076, 0x0056,
-	0x0046, 0x0026, 0x0006, 0x0126, 0x2091, 0x8000, 0x2029, 0x19ef,
-	0x252c, 0x2021, 0x19f5, 0x2424, 0x2061, 0x1cd0, 0x2071, 0x1800,
-	0x7254, 0x7074, 0x9202, 0x1a04, 0xbedd, 0x080c, 0x8a3d, 0x0904,
-	0xbed6, 0x080c, 0xe76b, 0x0904, 0xbed6, 0x6720, 0x9786, 0x0007,
-	0x0904, 0xbed6, 0x2500, 0x9c06, 0x0904, 0xbed6, 0x2400, 0x9c06,
-	0x05e8, 0x3e08, 0x9186, 0x0002, 0x1148, 0x6010, 0x9005, 0x0130,
-	0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x1580, 0x00c6, 0x6000,
-	0x9086, 0x0004, 0x1110, 0x080c, 0x1aa1, 0x9786, 0x000a, 0x0148,
-	0x080c, 0xce8e, 0x1130, 0x00ce, 0x080c, 0xb905, 0x080c, 0xaf74,
-	0x00e8, 0x6014, 0x2048, 0x080c, 0xcc86, 0x01a8, 0x9786, 0x0003,
-	0x1530, 0xa867, 0x0103, 0xa87c, 0xd0cc, 0x0130, 0x0096, 0xa878,
-	0x2048, 0x080c, 0x0fb1, 0x009e, 0xab7a, 0xa877, 0x0000, 0x080c,
-	0x6d0b, 0x080c, 0xce71, 0x080c, 0xaf74, 0x00ce, 0x9ce0, 0x0018,
-	0x7068, 0x9c02, 0x1210, 0x0804, 0xbe80, 0x012e, 0x000e, 0x002e,
-	0x004e, 0x005e, 0x007e, 0x00ce, 0x009e, 0x00ee, 0x0005, 0x9786,
-	0x0006, 0x1118, 0x080c, 0xe6dd, 0x0c30, 0x9786, 0x0009, 0x1148,
-	0x6000, 0x9086, 0x0004, 0x0d08, 0x2009, 0x004c, 0x080c, 0xafbe,
-	0x08e0, 0x9786, 0x000a, 0x0980, 0x0820, 0x220c, 0x2304, 0x9106,
-	0x1130, 0x8210, 0x8318, 0x1f04, 0xbefd, 0x9006, 0x0005, 0x2304,
-	0x9102, 0x0218, 0x2001, 0x0001, 0x0008, 0x9006, 0x918d, 0x0001,
-	0x0005, 0x0136, 0x01c6, 0x0016, 0x8906, 0x8006, 0x8007, 0x908c,
-	0x003f, 0x21e0, 0x9084, 0xffc0, 0x9300, 0x2098, 0x3518, 0x20a9,
-	0x0001, 0x220c, 0x4002, 0x910e, 0x1140, 0x8210, 0x8319, 0x1dc8,
-	0x9006, 0x001e, 0x01ce, 0x013e, 0x0005, 0x220c, 0x9102, 0x0218,
-	0x2001, 0x0001, 0x0010, 0x2001, 0x0000, 0x918d, 0x0001, 0x001e,
-	0x01ce, 0x013e, 0x0005, 0x220c, 0x810f, 0x2304, 0x9106, 0x1130,
-	0x8210, 0x8318, 0x1f04, 0xbf3b, 0x9006, 0x0005, 0x918d, 0x0001,
-	0x0005, 0x6004, 0x908a, 0x0053, 0x1a0c, 0x0dd5, 0x080c, 0xce7d,
-	0x0120, 0x080c, 0xce8e, 0x0168, 0x0028, 0x080c, 0x3247, 0x080c,
-	0xce8e, 0x0138, 0x080c, 0x9657, 0x080c, 0xaf43, 0x080c, 0x9763,
-	0x0005, 0x080c, 0xb905, 0x0cb0, 0x9182, 0x0054, 0x1220, 0x9182,
-	0x0040, 0x0208, 0x000a, 0x0005, 0xbf80, 0xbf80, 0xbf80, 0xbf80,
-	0xbf80, 0xbf80, 0xbf80, 0xbf80, 0xbf80, 0xbf80, 0xbf80, 0xbf82,
-	0xbf82, 0xbf82, 0xbf82, 0xbf80, 0xbf80, 0xbf80, 0xbf82, 0xbf80,
-	0x080c, 0x0dd5, 0x600b, 0xffff, 0x6003, 0x0001, 0x6106, 0x080c,
-	0x91b1, 0x0126, 0x2091, 0x8000, 0x080c, 0x9763, 0x012e, 0x0005,
-	0x9186, 0x0013, 0x1128, 0x6004, 0x9082, 0x0040, 0x0804, 0xc037,
-	0x9186, 0x0027, 0x1520, 0x080c, 0x9657, 0x080c, 0x321e, 0x080c,
-	0xd39d, 0x0096, 0x6114, 0x2148, 0x080c, 0xcc86, 0x0198, 0x080c,
-	0xce8e, 0x1118, 0x080c, 0xb905, 0x0068, 0xa867, 0x0103, 0xa87b,
-	0x0029, 0xa877, 0x0000, 0xa97c, 0xc1c5, 0xa97e, 0x080c, 0x6d17,
-	0x080c, 0xce71, 0x009e, 0x080c, 0xaf43, 0x0804, 0x9763, 0x9186,
-	0x0014, 0x1120, 0x6004, 0x9082, 0x0040, 0x04a0, 0x9186, 0x0046,
-	0x0150, 0x9186, 0x0045, 0x0138, 0x9186, 0x0053, 0x0120, 0x9186,
-	0x0048, 0x190c, 0x0dd5, 0x2001, 0x0109, 0x2004, 0xd084, 0x0508,
-	0x0126, 0x2091, 0x2800, 0x0006, 0x0016, 0x0026, 0x0036, 0x00f6,
-	0x00e6, 0x00c6, 0x2079, 0x19e6, 0x2071, 0x1800, 0x2061, 0x0100,
-	0x080c, 0x9094, 0x00ce, 0x00ee, 0x00fe, 0x003e, 0x002e, 0x001e,
-	0x000e, 0x012e, 0xa001, 0x6000, 0x9086, 0x0002, 0x1110, 0x0804,
-	0xc075, 0x0005, 0x0002, 0xc011, 0xc00f, 0xc00f, 0xc00f, 0xc00f,
-	0xc00f, 0xc00f, 0xc00f, 0xc00f, 0xc00f, 0xc00f, 0xc02c, 0xc02c,
-	0xc02c, 0xc02c, 0xc00f, 0xc02c, 0xc00f, 0xc02c, 0xc00f, 0x080c,
-	0x0dd5, 0x080c, 0x9657, 0x0096, 0x6114, 0x2148, 0x080c, 0xcc86,
-	0x0168, 0xa867, 0x0103, 0xa87b, 0x0006, 0xa877, 0x0000, 0xa880,
-	0xc0ec, 0xa882, 0x080c, 0x6d17, 0x080c, 0xce71, 0x009e, 0x080c,
-	0xaf43, 0x080c, 0x9763, 0x0005, 0x080c, 0x9657, 0x080c, 0xce8e,
-	0x090c, 0xb905, 0x080c, 0xaf43, 0x080c, 0x9763, 0x0005, 0x0002,
-	0xc04e, 0xc04c, 0xc04c, 0xc04c, 0xc04c, 0xc04c, 0xc04c, 0xc04c,
-	0xc04c, 0xc04c, 0xc04c, 0xc065, 0xc065, 0xc065, 0xc065, 0xc04c,
-	0xc06f, 0xc04c, 0xc065, 0xc04c, 0x080c, 0x0dd5, 0x0096, 0x080c,
-	0x9657, 0x6014, 0x2048, 0x2001, 0x1987, 0x2004, 0x6042, 0xa97c,
-	0xd1ac, 0x0140, 0x6003, 0x0004, 0xa87c, 0x9085, 0x0400, 0xa87e,
-	0x009e, 0x0005, 0x6003, 0x0002, 0x0cb8, 0x080c, 0x9657, 0x080c,
-	0xd3a0, 0x080c, 0xd3a5, 0x6003, 0x000f, 0x0804, 0x9763, 0x080c,
-	0x9657, 0x080c, 0xaf43, 0x0804, 0x9763, 0x9182, 0x0054, 0x1220,
-	0x9182, 0x0040, 0x0208, 0x000a, 0x0005, 0xc091, 0xc091, 0xc091,
-	0xc091, 0xc091, 0xc093, 0xc170, 0xc091, 0xc1a4, 0xc091, 0xc091,
-	0xc091, 0xc091, 0xc091, 0xc091, 0xc091, 0xc091, 0xc091, 0xc091,
-	0xc1a4, 0x080c, 0x0dd5, 0x00b6, 0x0096, 0x6114, 0x2148, 0x7644,
-	0x96b4, 0x0fff, 0x86ff, 0x1528, 0x6010, 0x2058, 0xb800, 0xd0bc,
-	0x1904, 0xc15f, 0xa87b, 0x0000, 0xa867, 0x0103, 0xae76, 0xa87c,
-	0xd0ac, 0x0128, 0xa834, 0xa938, 0x9115, 0x190c, 0xc33d, 0x080c,
-	0x6b33, 0x6210, 0x2258, 0xba3c, 0x82ff, 0x0110, 0x8211, 0xba3e,
-	0x7044, 0xd0e4, 0x1904, 0xc143, 0x080c, 0xaf43, 0x009e, 0x00be,
-	0x0005, 0x968c, 0x0c00, 0x0150, 0x6010, 0x2058, 0xb800, 0xd0bc,
-	0x1904, 0xc147, 0x7348, 0xab92, 0x734c, 0xab8e, 0x968c, 0x00ff,
-	0x9186, 0x0002, 0x0508, 0x9186, 0x0028, 0x1118, 0xa87b, 0x001c,
-	0x00e8, 0xd6dc, 0x01a0, 0xa87b, 0x0015, 0xa87c, 0xd0ac, 0x0170,
-	0xa938, 0xaa34, 0x2100, 0x9205, 0x0148, 0x7048, 0x9106, 0x1118,
-	0x704c, 0x9206, 0x0118, 0xa992, 0xaa8e, 0xc6dc, 0x0038, 0xd6d4,
-	0x0118, 0xa87b, 0x0007, 0x0010, 0xa87b, 0x0000, 0xa867, 0x0103,
-	0xae76, 0x901e, 0xd6c4, 0x01d8, 0x9686, 0x0100, 0x1130, 0x7064,
-	0x9005, 0x1118, 0xc6c4, 0x0804, 0xc09a, 0x735c, 0xab86, 0x83ff,
-	0x0170, 0x938a, 0x0009, 0x0210, 0x2019, 0x0008, 0x0036, 0x2308,
-	0x2019, 0x0018, 0x2011, 0x0025, 0x080c, 0xc837, 0x003e, 0xd6cc,
-	0x0904, 0xc0af, 0x7154, 0xa98a, 0x81ff, 0x0904, 0xc0af, 0x9192,
-	0x0021, 0x1278, 0x8304, 0x9098, 0x0018, 0x2011, 0x0029, 0x080c,
-	0xc837, 0x2011, 0x0205, 0x2013, 0x0000, 0x080c, 0xd32d, 0x0804,
-	0xc0af, 0xa868, 0xd0fc, 0x0120, 0x2009, 0x0020, 0xa98a, 0x0c50,
-	0x00a6, 0x2950, 0x080c, 0xc7d6, 0x00ae, 0x080c, 0xd32d, 0x080c,
-	0xc827, 0x0804, 0xc0b1, 0x080c, 0xcf86, 0x0804, 0xc0be, 0xa87c,
-	0xd0ac, 0x0904, 0xc0ca, 0xa880, 0xd0bc, 0x1904, 0xc0ca, 0x7348,
-	0xa838, 0x9306, 0x11c8, 0x734c, 0xa834, 0x931e, 0x0904, 0xc0ca,
-	0xd6d4, 0x0190, 0xab38, 0x9305, 0x0904, 0xc0ca, 0x0068, 0xa87c,
-	0xd0ac, 0x0904, 0xc0a2, 0xa838, 0xa934, 0x9105, 0x0904, 0xc0a2,
-	0xa880, 0xd0bc, 0x1904, 0xc0a2, 0x080c, 0xcfc0, 0x0804, 0xc0be,
-	0x0096, 0x00f6, 0x6003, 0x0003, 0x6007, 0x0043, 0x2079, 0x026c,
-	0x7c04, 0x7b00, 0x7e0c, 0x7d08, 0x6014, 0x2048, 0xa87c, 0xd0ac,
-	0x0140, 0x6003, 0x0002, 0x00fe, 0x009e, 0x0005, 0x2130, 0x2228,
-	0x0058, 0x2400, 0xa9ac, 0x910a, 0x2300, 0xaab0, 0x9213, 0x2600,
-	0x9102, 0x2500, 0x9203, 0x0e90, 0xac36, 0xab3a, 0xae46, 0xad4a,
-	0x00fe, 0x6043, 0x0000, 0x2c10, 0x080c, 0x1beb, 0x080c, 0x9216,
-	0x080c, 0x9891, 0x009e, 0x0005, 0x0005, 0x9182, 0x0054, 0x1220,
-	0x9182, 0x0040, 0x0208, 0x000a, 0x0005, 0xc1c1, 0xc1c1, 0xc1c1,
-	0xc1c1, 0xc1c1, 0xc1c3, 0xc259, 0xc1c1, 0xc1c1, 0xc270, 0xc300,
-	0xc1c1, 0xc1c1, 0xc1c1, 0xc1c1, 0xc315, 0xc1c1, 0xc1c1, 0xc1c1,
-	0xc1c1, 0x080c, 0x0dd5, 0x0076, 0x00a6, 0x00e6, 0x0096, 0x2071,
+	0x009e, 0x4003, 0x9196, 0x0016, 0x01f0, 0x0136, 0x9080, 0x001b,
+	0x20a0, 0x2011, 0x0006, 0x20a9, 0x0001, 0x3418, 0x8318, 0x23a0,
+	0x4003, 0x3318, 0x8318, 0x2398, 0x8211, 0x1db8, 0x2011, 0x0006,
+	0x013e, 0x20a0, 0x3318, 0x8318, 0x2398, 0x4003, 0x3418, 0x8318,
+	0x23a0, 0x8211, 0x1db8, 0x0096, 0x080c, 0xce3f, 0x0130, 0x6014,
+	0x2048, 0xa807, 0x0000, 0xa867, 0x0103, 0x009e, 0x0804, 0xb0e7,
+	0x0096, 0x00d6, 0x0036, 0x7330, 0x9386, 0x0200, 0x11a8, 0x6010,
+	0x00b6, 0x2058, 0xb8cf, 0x0000, 0x00be, 0x6014, 0x9005, 0x0130,
+	0x2048, 0xa807, 0x0000, 0xa867, 0x0103, 0xab32, 0x080c, 0xb0e7,
+	0x003e, 0x00de, 0x009e, 0x0005, 0x0011, 0x1d48, 0x0cc8, 0x0006,
+	0x0016, 0x080c, 0xd548, 0x0188, 0x6014, 0x9005, 0x1170, 0x600b,
+	0x0003, 0x601b, 0x0000, 0x6043, 0x0000, 0x2009, 0x0022, 0x080c,
+	0xb8f2, 0x9006, 0x001e, 0x000e, 0x0005, 0x9085, 0x0001, 0x0cd0,
+	0x0096, 0x0016, 0x20a9, 0x0014, 0x9e80, 0x000c, 0x20e1, 0x0000,
+	0x2098, 0x6014, 0x2048, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0002,
+	0x20a0, 0x4003, 0x2001, 0x0205, 0x2003, 0x0001, 0x2099, 0x0260,
+	0x20a9, 0x0016, 0x4003, 0x20a9, 0x000a, 0xa804, 0x2048, 0xa860,
+	0x20e8, 0xa85c, 0x9080, 0x0002, 0x20a0, 0x4003, 0x2001, 0x0205,
+	0x2003, 0x0002, 0x2099, 0x0260, 0x20a9, 0x0020, 0x4003, 0x2003,
+	0x0000, 0x6014, 0x2048, 0xa800, 0x2048, 0xa867, 0x0103, 0x080c,
+	0xb0e7, 0x001e, 0x009e, 0x0005, 0x0096, 0x0016, 0x900e, 0x7030,
+	0x9086, 0x0100, 0x0140, 0x7038, 0x9084, 0x00ff, 0x800c, 0x703c,
+	0x9084, 0x00ff, 0x8004, 0x9080, 0x0004, 0x9108, 0x810b, 0x2011,
+	0x0002, 0x2019, 0x000c, 0x6014, 0x2048, 0x080c, 0xc9f0, 0x080c,
+	0xce3f, 0x0140, 0x6014, 0x2048, 0xa807, 0x0000, 0xa864, 0xa8e2,
+	0xa867, 0x0103, 0x080c, 0xb0e7, 0x001e, 0x009e, 0x0005, 0x0016,
+	0x2009, 0x0000, 0x7030, 0x9086, 0x0200, 0x0110, 0x2009, 0x0001,
+	0x0096, 0x6014, 0x904d, 0x090c, 0x0dc5, 0xa97a, 0x080c, 0x6dcb,
+	0x009e, 0x080c, 0xb0e7, 0x001e, 0x0005, 0x0016, 0x0096, 0x7030,
+	0x9086, 0x0100, 0x1118, 0x2009, 0x0004, 0x0010, 0x7034, 0x800c,
+	0x810b, 0x2011, 0x000c, 0x2019, 0x000c, 0x6014, 0x2048, 0xa804,
+	0x0096, 0x9005, 0x0108, 0x2048, 0x080c, 0xc9f0, 0x009e, 0x080c,
+	0xce3f, 0x0148, 0xa804, 0x9005, 0x1158, 0xa807, 0x0000, 0xa864,
+	0xa8e2, 0xa867, 0x0103, 0x080c, 0xb0e7, 0x009e, 0x001e, 0x0005,
+	0x0086, 0x2040, 0xa030, 0x8007, 0x9086, 0x0100, 0x1118, 0x080c,
+	0xbacb, 0x00e0, 0xa034, 0x8007, 0x800c, 0x8806, 0x8006, 0x8007,
+	0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x000c, 0xa87b, 0x0000,
+	0xa883, 0x0000, 0xa897, 0x4000, 0xaaa0, 0xab9c, 0xaca8, 0xada4,
+	0x2031, 0x0000, 0x2041, 0x1252, 0x0019, 0x0d08, 0x008e, 0x0898,
+	0x0096, 0x0006, 0x080c, 0x100e, 0x000e, 0x01b0, 0xa8ab, 0x0dcb,
+	0xa876, 0x000e, 0xa8a2, 0x0006, 0xae6a, 0x2800, 0xa89e, 0xa97a,
+	0xaf72, 0xaa8e, 0xab92, 0xac96, 0xad9a, 0x0086, 0x2940, 0x080c,
+	0x10f8, 0x008e, 0x9085, 0x0001, 0x009e, 0x0005, 0x00e6, 0x00d6,
+	0x0026, 0x7008, 0x9084, 0x00ff, 0x6210, 0x00b6, 0x2258, 0xba10,
+	0x00be, 0x9206, 0x1520, 0x700c, 0x6210, 0x00b6, 0x2258, 0xba14,
+	0x00be, 0x9206, 0x11e0, 0x6043, 0x0000, 0x2c68, 0x0016, 0x2009,
+	0x0035, 0x080c, 0xd4c0, 0x001e, 0x1158, 0x622c, 0x2268, 0x2071,
+	0x026c, 0x6b20, 0x9386, 0x0003, 0x0130, 0x9386, 0x0006, 0x0128,
+	0x080c, 0xb0e7, 0x0020, 0x0039, 0x0010, 0x080c, 0xb727, 0x002e,
+	0x00de, 0x00ee, 0x0005, 0x0096, 0x6814, 0x2048, 0x9186, 0x0015,
+	0x0904, 0xb70f, 0x918e, 0x0016, 0x1904, 0xb725, 0x700c, 0x908c,
+	0xff00, 0x9186, 0x1700, 0x0120, 0x9186, 0x0300, 0x1904, 0xb6e9,
+	0x89ff, 0x1138, 0x6800, 0x9086, 0x000f, 0x0904, 0xb6cc, 0x0804,
+	0xb723, 0x6808, 0x9086, 0xffff, 0x1904, 0xb711, 0xa87c, 0x9084,
+	0x0060, 0x9086, 0x0020, 0x1128, 0xa83c, 0xa940, 0x9105, 0x1904,
+	0xb711, 0x6824, 0xd084, 0x1904, 0xb711, 0xd0b4, 0x0158, 0x0016,
+	0x2001, 0x1987, 0x200c, 0x6018, 0x9102, 0x9082, 0x0005, 0x001e,
+	0x1a04, 0xb711, 0x080c, 0xd02a, 0x685c, 0xa882, 0xa87c, 0xc0dc,
+	0xc0f4, 0xc0d4, 0xa87e, 0x0026, 0x900e, 0x6a18, 0x2001, 0x000a,
+	0x080c, 0x91ab, 0xa884, 0x920a, 0x0208, 0x8011, 0xaa86, 0x82ff,
+	0x002e, 0x1138, 0x00c6, 0x2d60, 0x080c, 0xcb52, 0x00ce, 0x0804,
+	0xb723, 0x00c6, 0xa868, 0xd0fc, 0x1118, 0x080c, 0x61b5, 0x0010,
+	0x080c, 0x65c2, 0x00ce, 0x1904, 0xb711, 0x00c6, 0x2d60, 0x080c,
+	0xb0e7, 0x00ce, 0x0804, 0xb723, 0x00c6, 0x080c, 0xb139, 0x0198,
+	0x6017, 0x0000, 0x6810, 0x6012, 0x080c, 0xd2bb, 0x6023, 0x0003,
+	0x6904, 0x00c6, 0x2d60, 0x080c, 0xb0e7, 0x00ce, 0x080c, 0xb166,
+	0x00ce, 0x0804, 0xb723, 0x2001, 0x1989, 0x2004, 0x6842, 0x00ce,
+	0x04d0, 0x7008, 0x9086, 0x000b, 0x11c8, 0x6010, 0x00b6, 0x2058,
+	0xb900, 0xc1bc, 0xb902, 0x00be, 0x00c6, 0x2d60, 0xa87b, 0x0003,
+	0x080c, 0xd502, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002,
+	0x080c, 0x9335, 0x080c, 0x98e7, 0x00ce, 0x00e8, 0x700c, 0x9086,
+	0x2a00, 0x1138, 0x2001, 0x1989, 0x2004, 0x6842, 0x00a0, 0x0479,
+	0x00a0, 0x89ff, 0x090c, 0x0dc5, 0x00c6, 0x00d6, 0x2d60, 0xa867,
+	0x0103, 0xa87b, 0x0003, 0x080c, 0x6be5, 0x080c, 0xd02a, 0x080c,
+	0xb11a, 0x00de, 0x00ce, 0x080c, 0xb0e7, 0x009e, 0x0005, 0x9186,
+	0x0015, 0x1128, 0x2001, 0x1989, 0x2004, 0x6842, 0x0068, 0x918e,
+	0x0016, 0x1160, 0x00c6, 0x2d00, 0x2060, 0x080c, 0xeb9d, 0x080c,
+	0x88eb, 0x080c, 0xb0e7, 0x00ce, 0x080c, 0xb0e7, 0x0005, 0x0026,
+	0x0036, 0x0046, 0x7228, 0xacb0, 0xabac, 0xd2f4, 0x0130, 0x2001,
+	0x1989, 0x2004, 0x6842, 0x0804, 0xb7a1, 0x00c6, 0x2d60, 0x080c,
+	0xca51, 0x00ce, 0x6804, 0x9086, 0x0050, 0x1168, 0x00c6, 0x2d00,
+	0x2060, 0x6003, 0x0001, 0x6007, 0x0050, 0x080c, 0x9335, 0x080c,
+	0x98e7, 0x00ce, 0x04f0, 0x6800, 0x9086, 0x000f, 0x01a8, 0x89ff,
+	0x090c, 0x0dc5, 0x6800, 0x9086, 0x0004, 0x1190, 0xa87c, 0xd0ac,
+	0x0178, 0xa843, 0x0fff, 0xa83f, 0x0fff, 0xa880, 0xc0fc, 0xa882,
+	0x2001, 0x0001, 0x6832, 0x0400, 0x2001, 0x0007, 0x6832, 0x00e0,
+	0xa87c, 0xd0b4, 0x1150, 0xd0ac, 0x0db8, 0x6824, 0xd0f4, 0x1d48,
+	0xa838, 0xa934, 0x9105, 0x0d80, 0x0c20, 0xd2ec, 0x1d68, 0x7024,
+	0x9306, 0x1118, 0x7020, 0x9406, 0x0d38, 0x7020, 0x683e, 0x7024,
+	0x683a, 0x2001, 0x0005, 0x6832, 0x080c, 0xd1b2, 0x080c, 0x98e7,
+	0x0010, 0x080c, 0xb0e7, 0x004e, 0x003e, 0x002e, 0x0005, 0x00e6,
+	0x00d6, 0x0026, 0x7008, 0x9084, 0x00ff, 0x6210, 0x00b6, 0x2258,
+	0xba10, 0x00be, 0x9206, 0x1904, 0xb80c, 0x700c, 0x6210, 0x00b6,
+	0x2258, 0xba14, 0x00be, 0x9206, 0x1904, 0xb80c, 0x6038, 0x2068,
+	0x6824, 0xc0dc, 0x6826, 0x6a20, 0x9286, 0x0007, 0x0904, 0xb80c,
+	0x9286, 0x0002, 0x0904, 0xb80c, 0x9286, 0x0000, 0x05e8, 0x6808,
+	0x633c, 0x9306, 0x15c8, 0x2071, 0x026c, 0x9186, 0x0015, 0x0570,
+	0x918e, 0x0016, 0x1100, 0x00c6, 0x6038, 0x2060, 0x6104, 0x9186,
+	0x004b, 0x01c0, 0x9186, 0x004c, 0x01a8, 0x9186, 0x004d, 0x0190,
+	0x9186, 0x004e, 0x0178, 0x9186, 0x0052, 0x0160, 0x6014, 0x0096,
+	0x2048, 0x080c, 0xce3f, 0x090c, 0x0dc5, 0xa87b, 0x0003, 0x009e,
+	0x080c, 0xd502, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002,
+	0x080c, 0x9335, 0x080c, 0x98e7, 0x00ce, 0x0030, 0x6038, 0x2070,
+	0x2001, 0x1989, 0x2004, 0x7042, 0x080c, 0xb0e7, 0x002e, 0x00de,
+	0x00ee, 0x0005, 0x00b6, 0x0096, 0x00f6, 0x6014, 0x2048, 0x6010,
+	0x2058, 0x91b6, 0x0015, 0x0130, 0xba08, 0xbb0c, 0xbc00, 0xc48c,
+	0xbc02, 0x0460, 0x0096, 0x0156, 0x0036, 0x0026, 0x2b48, 0x9e90,
+	0x0010, 0x2019, 0x000a, 0x20a9, 0x0004, 0x080c, 0xc0e7, 0x002e,
+	0x003e, 0x015e, 0x009e, 0x1904, 0xb87b, 0x0096, 0x0156, 0x0036,
+	0x0026, 0x2b48, 0x9e90, 0x0014, 0x2019, 0x0006, 0x20a9, 0x0004,
+	0x080c, 0xc0e7, 0x002e, 0x003e, 0x015e, 0x009e, 0x15a0, 0x7238,
+	0xba0a, 0x733c, 0xbb0e, 0xbc00, 0xc48d, 0xbc02, 0xa804, 0x9005,
+	0x1128, 0x00fe, 0x009e, 0x00be, 0x0804, 0xb4f3, 0x0096, 0x2048,
+	0xaa12, 0xab16, 0xac0a, 0x009e, 0x8006, 0x8006, 0x8007, 0x90bc,
+	0x003f, 0x9084, 0xffc0, 0x9080, 0x0002, 0x2009, 0x002b, 0xaaa0,
+	0xab9c, 0xaca8, 0xada4, 0x2031, 0x0000, 0x2041, 0x1252, 0x080c,
+	0xb608, 0x0130, 0x00fe, 0x009e, 0x080c, 0xb0e7, 0x00be, 0x0005,
+	0x080c, 0xbacb, 0x0cb8, 0x2b78, 0x00f6, 0x080c, 0x324b, 0x080c,
+	0xd55d, 0x00fe, 0x00c6, 0x080c, 0xb091, 0x2f00, 0x6012, 0x6017,
+	0x0000, 0x6023, 0x0001, 0x6007, 0x0001, 0x6003, 0x0001, 0x2001,
+	0x0007, 0x080c, 0x665d, 0x080c, 0x6689, 0x080c, 0x937d, 0x080c,
+	0x98e7, 0x00ce, 0x0804, 0xb84e, 0x2100, 0x91b2, 0x0053, 0x1a0c,
+	0x0dc5, 0x91b2, 0x0040, 0x1a04, 0xb904, 0x0002, 0xb8f2, 0xb8f2,
+	0xb8e8, 0xb8f2, 0xb8f2, 0xb8f2, 0xb8e6, 0xb8e6, 0xb8e6, 0xb8e6,
+	0xb8e6, 0xb8e6, 0xb8e6, 0xb8e6, 0xb8e6, 0xb8e6, 0xb8e6, 0xb8e6,
+	0xb8e6, 0xb8e6, 0xb8e6, 0xb8e6, 0xb8e6, 0xb8e6, 0xb8e6, 0xb8e6,
+	0xb8e6, 0xb8e6, 0xb8e6, 0xb8e6, 0xb8e6, 0xb8f2, 0xb8e6, 0xb8f2,
+	0xb8f2, 0xb8e6, 0xb8e6, 0xb8e6, 0xb8e6, 0xb8e6, 0xb8e8, 0xb8e6,
+	0xb8e6, 0xb8e6, 0xb8e6, 0xb8e6, 0xb8e6, 0xb8e6, 0xb8e6, 0xb8e6,
+	0xb8f2, 0xb8f2, 0xb8e6, 0xb8e6, 0xb8e6, 0xb8e6, 0xb8e6, 0xb8e6,
+	0xb8e6, 0xb8e6, 0xb8e6, 0xb8f2, 0xb8e6, 0xb8e6, 0x080c, 0x0dc5,
+	0x0066, 0x00b6, 0x6610, 0x2658, 0xb8cc, 0xc08c, 0xb8ce, 0x00be,
+	0x006e, 0x0000, 0x6003, 0x0001, 0x6106, 0x9186, 0x0032, 0x0118,
+	0x080c, 0x937d, 0x0010, 0x080c, 0x9335, 0x0126, 0x2091, 0x8000,
+	0x080c, 0x98e7, 0x012e, 0x0005, 0x2600, 0x0002, 0xb8f2, 0xb8f2,
+	0xb918, 0xb8f2, 0xb8f2, 0xb918, 0xb918, 0xb918, 0xb918, 0xb8f2,
+	0xb918, 0xb8f2, 0xb918, 0xb8f2, 0xb918, 0xb918, 0xb918, 0xb918,
+	0x080c, 0x0dc5, 0x6004, 0x90b2, 0x0053, 0x1a0c, 0x0dc5, 0x91b6,
+	0x0013, 0x0904, 0xb9ed, 0x91b6, 0x0027, 0x1904, 0xb997, 0x080c,
+	0x97db, 0x6004, 0x080c, 0xd036, 0x01b0, 0x080c, 0xd047, 0x01a8,
+	0x908e, 0x0021, 0x0904, 0xb994, 0x908e, 0x0022, 0x1130, 0x080c,
+	0xb51f, 0x0904, 0xb990, 0x0804, 0xb991, 0x908e, 0x003d, 0x0904,
+	0xb994, 0x0804, 0xb98a, 0x080c, 0x3274, 0x2001, 0x0007, 0x080c,
+	0x665d, 0x6010, 0x00b6, 0x2058, 0xb9a0, 0x00be, 0x080c, 0xbacb,
+	0x9186, 0x007e, 0x1148, 0x2001, 0x1837, 0x2014, 0xc285, 0x080c,
+	0x7563, 0x1108, 0xc2ad, 0x2202, 0x0036, 0x0026, 0x2019, 0x0028,
+	0x2110, 0x080c, 0xecaa, 0x002e, 0x003e, 0x0016, 0x0026, 0x0036,
+	0x2110, 0x2019, 0x0028, 0x080c, 0x94da, 0x0076, 0x903e, 0x080c,
+	0x93ad, 0x6010, 0x00b6, 0x905d, 0x0100, 0x00be, 0x2c08, 0x080c,
+	0xe671, 0x007e, 0x003e, 0x002e, 0x001e, 0x080c, 0xd55d, 0x0016,
+	0x080c, 0xd2b3, 0x080c, 0xb0e7, 0x001e, 0x080c, 0x3347, 0x080c,
+	0x98e7, 0x0030, 0x080c, 0xd2b3, 0x080c, 0xb0e7, 0x080c, 0x98e7,
+	0x0005, 0x080c, 0xbacb, 0x0cb0, 0x080c, 0xbb07, 0x0c98, 0x9186,
+	0x0015, 0x0118, 0x9186, 0x0016, 0x1148, 0x080c, 0xd56e, 0x0d80,
+	0x6000, 0x9086, 0x0002, 0x0904, 0xbb12, 0x0c50, 0x9186, 0x0014,
+	0x1d38, 0x080c, 0x97db, 0x6004, 0x908e, 0x0022, 0x1118, 0x080c,
+	0xb51f, 0x09f0, 0x080c, 0x324b, 0x080c, 0xd55d, 0x080c, 0xd036,
+	0x1198, 0x080c, 0x3274, 0x6010, 0x00b6, 0x2058, 0xb9a0, 0x00be,
+	0x080c, 0xbacb, 0x9186, 0x007e, 0x1128, 0x2001, 0x1837, 0x200c,
+	0xc185, 0x2102, 0x0804, 0xb98a, 0x080c, 0xd047, 0x1120, 0x080c,
+	0xbacb, 0x0804, 0xb98a, 0x6004, 0x908e, 0x0032, 0x1160, 0x00e6,
+	0x00f6, 0x2071, 0x189e, 0x2079, 0x0000, 0x080c, 0x35e2, 0x00fe,
+	0x00ee, 0x0804, 0xb98a, 0x6004, 0x908e, 0x0021, 0x0d40, 0x908e,
+	0x0022, 0x090c, 0xbacb, 0x0804, 0xb98a, 0x90b2, 0x0040, 0x1a04,
+	0xbaa7, 0x2008, 0x0002, 0xba35, 0xba36, 0xba39, 0xba3c, 0xba3f,
+	0xba4c, 0xba33, 0xba33, 0xba33, 0xba33, 0xba33, 0xba33, 0xba33,
+	0xba33, 0xba33, 0xba33, 0xba33, 0xba33, 0xba33, 0xba33, 0xba33,
+	0xba33, 0xba33, 0xba33, 0xba33, 0xba33, 0xba33, 0xba33, 0xba33,
+	0xba33, 0xba4f, 0xba5c, 0xba33, 0xba5e, 0xba5c, 0xba33, 0xba33,
+	0xba33, 0xba33, 0xba33, 0xba5c, 0xba5c, 0xba33, 0xba33, 0xba33,
+	0xba33, 0xba33, 0xba33, 0xba33, 0xba33, 0xba8e, 0xba5c, 0xba33,
+	0xba58, 0xba33, 0xba33, 0xba33, 0xba59, 0xba33, 0xba33, 0xba33,
+	0xba5c, 0xba85, 0xba33, 0x080c, 0x0dc5, 0x0430, 0x2001, 0x000b,
+	0x0470, 0x2001, 0x0003, 0x0458, 0x2001, 0x0005, 0x0440, 0x6010,
+	0x00b6, 0x2058, 0xb804, 0x00be, 0x9084, 0x00ff, 0x9086, 0x0000,
+	0x1500, 0x2001, 0x0001, 0x00d8, 0x2001, 0x0009, 0x00c0, 0x080c,
+	0x97db, 0x6003, 0x0005, 0x080c, 0xd560, 0x080c, 0x98e7, 0x0070,
+	0x0018, 0x0010, 0x080c, 0x665d, 0x0804, 0xba9f, 0x080c, 0x97db,
+	0x080c, 0xd560, 0x6003, 0x0004, 0x080c, 0x98e7, 0x0005, 0x080c,
+	0x665d, 0x080c, 0x97db, 0x6003, 0x0002, 0x0036, 0x2019, 0x1852,
+	0x2304, 0x9084, 0xff00, 0x1120, 0x2001, 0x1987, 0x201c, 0x0040,
+	0x8007, 0x909a, 0x0004, 0x0ec0, 0x8003, 0x801b, 0x831b, 0x9318,
+	0x631a, 0x003e, 0x080c, 0x98e7, 0x0c08, 0x080c, 0x97db, 0x080c,
+	0xd2b3, 0x080c, 0xb0e7, 0x080c, 0x98e7, 0x08c0, 0x00e6, 0x00f6,
+	0x2071, 0x189e, 0x2079, 0x0000, 0x080c, 0x35e2, 0x00fe, 0x00ee,
+	0x080c, 0x97db, 0x080c, 0xb0e7, 0x080c, 0x98e7, 0x0838, 0x080c,
+	0x97db, 0x6003, 0x0002, 0x080c, 0xd560, 0x0804, 0x98e7, 0x2600,
+	0x2008, 0x0002, 0xbabe, 0xba9f, 0xbabc, 0xba9f, 0xba9f, 0xbabc,
+	0xbabc, 0xbabc, 0xbabc, 0xba9f, 0xbabc, 0xba9f, 0xbabc, 0xba9f,
+	0xbabc, 0xbabc, 0xbabc, 0xbabc, 0x080c, 0x0dc5, 0x080c, 0x97db,
+	0x0096, 0x6014, 0x2048, 0x080c, 0x6dcb, 0x009e, 0x080c, 0xb0e7,
+	0x080c, 0x98e7, 0x0005, 0x00e6, 0x0096, 0x0026, 0x0016, 0x080c,
+	0xce3f, 0x0568, 0x6014, 0x2048, 0xa864, 0x9086, 0x0139, 0x11a8,
+	0xa894, 0x9086, 0x0056, 0x1148, 0x080c, 0x5567, 0x0130, 0x2001,
+	0x0000, 0x900e, 0x2011, 0x4000, 0x0028, 0x2001, 0x0030, 0x900e,
+	0x2011, 0x4005, 0x080c, 0xd424, 0x0090, 0xa868, 0xd0fc, 0x0178,
+	0xa807, 0x0000, 0x0016, 0x6004, 0x908e, 0x0021, 0x0168, 0x908e,
+	0x003d, 0x0150, 0x001e, 0xa867, 0x0103, 0xa833, 0x0100, 0x001e,
+	0x002e, 0x009e, 0x00ee, 0x0005, 0x001e, 0x0009, 0x0cc0, 0x0096,
+	0x6014, 0x2048, 0xa800, 0x2048, 0xa867, 0x0103, 0xa823, 0x8001,
+	0x009e, 0x0005, 0x00b6, 0x6610, 0x2658, 0xb804, 0x9084, 0x00ff,
+	0x90b2, 0x000c, 0x1a0c, 0x0dc5, 0x6604, 0x96b6, 0x004d, 0x1120,
+	0x080c, 0xd343, 0x0804, 0xbb97, 0x6604, 0x96b6, 0x0043, 0x1120,
+	0x080c, 0xd38c, 0x0804, 0xbb97, 0x6604, 0x96b6, 0x004b, 0x1120,
+	0x080c, 0xd3b8, 0x0804, 0xbb97, 0x6604, 0x96b6, 0x0033, 0x1120,
+	0x080c, 0xd2d5, 0x0804, 0xbb97, 0x6604, 0x96b6, 0x0028, 0x1120,
+	0x080c, 0xd085, 0x0804, 0xbb97, 0x6604, 0x96b6, 0x0029, 0x1120,
+	0x080c, 0xd0c6, 0x0804, 0xbb97, 0x6604, 0x96b6, 0x001f, 0x1120,
+	0x080c, 0xb4c4, 0x0804, 0xbb97, 0x6604, 0x96b6, 0x0000, 0x1118,
+	0x080c, 0xb812, 0x04e0, 0x6604, 0x96b6, 0x0022, 0x1118, 0x080c,
+	0xb500, 0x04a8, 0x6604, 0x96b6, 0x0035, 0x1118, 0x080c, 0xb626,
+	0x0470, 0x6604, 0x96b6, 0x0039, 0x1118, 0x080c, 0xb7a7, 0x0438,
+	0x6604, 0x96b6, 0x003d, 0x1118, 0x080c, 0xb538, 0x0400, 0x6604,
+	0x96b6, 0x0044, 0x1118, 0x080c, 0xb574, 0x00c8, 0x6604, 0x96b6,
+	0x0049, 0x1118, 0x080c, 0xb5b5, 0x0090, 0x6604, 0x96b6, 0x0041,
+	0x1118, 0x080c, 0xb59f, 0x0058, 0x91b6, 0x0015, 0x1110, 0x0063,
+	0x0030, 0x91b6, 0x0016, 0x1128, 0x00be, 0x0804, 0xbe01, 0x00be,
+	0x0005, 0x080c, 0xb181, 0x0cd8, 0xbbb4, 0xbbc2, 0xbbb4, 0xbc09,
+	0xbbb4, 0xbd75, 0xbe0e, 0xbbb4, 0xbbb4, 0xbdd7, 0xbbb4, 0xbded,
+	0x0096, 0x601f, 0x0000, 0x6014, 0x2048, 0xa800, 0x2048, 0xa867,
+	0x0103, 0x009e, 0x0804, 0xb0e7, 0xa001, 0xa001, 0x0005, 0x6604,
+	0x96b6, 0x0004, 0x1130, 0x2001, 0x0001, 0x080c, 0x6649, 0x0804,
+	0xb0e7, 0x0005, 0x00e6, 0x2071, 0x1800, 0x7090, 0x9086, 0x0074,
+	0x1540, 0x080c, 0xe642, 0x11b0, 0x6010, 0x00b6, 0x2058, 0x7030,
+	0xd08c, 0x0128, 0xb800, 0xd0bc, 0x0110, 0xc0c5, 0xb802, 0x00f9,
+	0x00be, 0x2001, 0x0006, 0x080c, 0x665d, 0x080c, 0x3274, 0x080c,
+	0xb0e7, 0x0098, 0x2001, 0x000a, 0x080c, 0x665d, 0x080c, 0x3274,
+	0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x937d, 0x080c, 0x98e7,
+	0x0020, 0x2001, 0x0001, 0x080c, 0xbd45, 0x00ee, 0x0005, 0x00d6,
+	0xb800, 0xd084, 0x0160, 0x9006, 0x080c, 0x6649, 0x2069, 0x1847,
+	0x6804, 0xd0a4, 0x0120, 0x2001, 0x0006, 0x080c, 0x6689, 0x00de,
+	0x0005, 0x00b6, 0x0096, 0x00d6, 0x2011, 0x1824, 0x2204, 0x9086,
+	0x0074, 0x1904, 0xbd1a, 0x6010, 0x2058, 0xbaa0, 0x9286, 0x007e,
+	0x1120, 0x080c, 0xbf5d, 0x0804, 0xbc7b, 0x080c, 0xbf52, 0x6010,
+	0x2058, 0xbaa0, 0x9286, 0x0080, 0x1510, 0x6014, 0x9005, 0x01a8,
+	0x2048, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, 0x1140, 0x2001,
+	0x0000, 0x900e, 0x2011, 0x4000, 0x080c, 0xd424, 0x0030, 0xa807,
+	0x0000, 0xa867, 0x0103, 0xa833, 0x0200, 0x2001, 0x0006, 0x080c,
+	0x665d, 0x080c, 0x3274, 0x080c, 0xb0e7, 0x0804, 0xbd1f, 0x080c,
+	0xbd2d, 0x6014, 0x9005, 0x0190, 0x2048, 0xa868, 0xd0f4, 0x01e8,
+	0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, 0x1d08, 0x2001, 0x0000,
+	0x900e, 0x2011, 0x4000, 0x080c, 0xd424, 0x08f8, 0x080c, 0xbd23,
+	0x0160, 0x9006, 0x080c, 0x6649, 0x2001, 0x0004, 0x080c, 0x6689,
+	0x2001, 0x0007, 0x080c, 0x665d, 0x08a0, 0x2001, 0x0004, 0x080c,
+	0x665d, 0x6003, 0x0001, 0x6007, 0x0003, 0x080c, 0x937d, 0x080c,
+	0x98e7, 0x0804, 0xbd1f, 0xb85c, 0xd0e4, 0x01d8, 0x080c, 0xd255,
+	0x080c, 0x7563, 0x0118, 0xd0dc, 0x1904, 0xbc3d, 0x2011, 0x1837,
+	0x2204, 0xc0ad, 0x2012, 0x2001, 0x196e, 0x2004, 0x00f6, 0x2079,
+	0x0100, 0x78e3, 0x0000, 0x080c, 0x28fd, 0x78e2, 0x00fe, 0x0804,
+	0xbc3d, 0x080c, 0xd292, 0x2011, 0x1837, 0x2204, 0xc0a5, 0x2012,
+	0x0006, 0x080c, 0xe7c8, 0x000e, 0x1904, 0xbc3d, 0xc0b5, 0x2012,
+	0x2001, 0x0006, 0x080c, 0x665d, 0x9006, 0x080c, 0x6649, 0x00c6,
+	0x2001, 0x180f, 0x2004, 0xd09c, 0x0520, 0x00f6, 0x2079, 0x0100,
+	0x00e6, 0x2071, 0x1800, 0x700c, 0x9084, 0x00ff, 0x78e6, 0x707e,
+	0x7010, 0x78ea, 0x7082, 0x908c, 0x00ff, 0x00ee, 0x780c, 0xc0b5,
+	0x780e, 0x00fe, 0x080c, 0x28d2, 0x00f6, 0x2100, 0x900e, 0x080c,
+	0x2889, 0x795e, 0x00fe, 0x9186, 0x0081, 0x01f0, 0x2009, 0x0081,
+	0x00e0, 0x2009, 0x00ef, 0x00f6, 0x2079, 0x0100, 0x79ea, 0x78e7,
+	0x0000, 0x7932, 0x7936, 0x780c, 0xc0b5, 0x780e, 0x00fe, 0x080c,
+	0x28d2, 0x00f6, 0x2079, 0x1800, 0x7982, 0x2100, 0x900e, 0x797e,
+	0x080c, 0x2889, 0x795e, 0x00fe, 0x8108, 0x080c, 0x66ac, 0x2b00,
+	0x00ce, 0x1904, 0xbc3d, 0x6012, 0x2009, 0x180f, 0x210c, 0xd19c,
+	0x0150, 0x2009, 0x027c, 0x210c, 0x918c, 0x00ff, 0xb912, 0x2009,
+	0x027d, 0x210c, 0xb916, 0x2001, 0x0002, 0x080c, 0x665d, 0x6023,
+	0x0001, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x937d, 0x080c,
+	0x98e7, 0x0028, 0x080c, 0xbacb, 0x2001, 0x0001, 0x0431, 0x00de,
+	0x009e, 0x00be, 0x0005, 0x2001, 0x1810, 0x2004, 0xd0a4, 0x0120,
+	0x2001, 0x1848, 0x2004, 0xd0ac, 0x0005, 0x00e6, 0x080c, 0xed03,
+	0x0190, 0x2071, 0x0260, 0x7108, 0x720c, 0x918c, 0x00ff, 0x1118,
+	0x9284, 0xff00, 0x0140, 0x6010, 0x2058, 0xb8a0, 0x9084, 0xff80,
+	0x1110, 0xb912, 0xba16, 0x00ee, 0x0005, 0x2030, 0x9005, 0x0158,
+	0x2001, 0x0007, 0x080c, 0x665d, 0x080c, 0x57e1, 0x1120, 0x2001,
+	0x0007, 0x080c, 0x6689, 0x2600, 0x9005, 0x11b0, 0x6014, 0x0096,
+	0x2048, 0xa868, 0x009e, 0xd0fc, 0x1178, 0x0036, 0x0046, 0x6010,
+	0x00b6, 0x2058, 0xbba0, 0x00be, 0x2021, 0x0004, 0x2011, 0x8014,
+	0x080c, 0x4be3, 0x004e, 0x003e, 0x080c, 0x3274, 0x6020, 0x9086,
+	0x000a, 0x1108, 0x0005, 0x0804, 0xb0e7, 0x00b6, 0x00e6, 0x0026,
+	0x0016, 0x2071, 0x1800, 0x7090, 0x9086, 0x0014, 0x1904, 0xbdcd,
+	0x080c, 0x57e1, 0x1170, 0x6014, 0x9005, 0x1158, 0x0036, 0x0046,
+	0x6010, 0x2058, 0xbba0, 0x2021, 0x0006, 0x080c, 0x4d9a, 0x004e,
+	0x003e, 0x00d6, 0x6010, 0x2058, 0x080c, 0x67b2, 0x080c, 0xbbf7,
+	0x00de, 0x080c, 0xc023, 0x1588, 0x6010, 0x2058, 0xb890, 0x9005,
+	0x0560, 0x2001, 0x0006, 0x080c, 0x665d, 0x0096, 0x6014, 0x904d,
+	0x01d0, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, 0x1140, 0x2001,
+	0x0000, 0x900e, 0x2011, 0x4000, 0x080c, 0xd424, 0x0060, 0xa864,
+	0x9084, 0x00ff, 0x9086, 0x0029, 0x0130, 0xa807, 0x0000, 0xa867,
+	0x0103, 0xa833, 0x0200, 0x009e, 0x080c, 0x3274, 0x6020, 0x9086,
+	0x000a, 0x0140, 0x080c, 0xb0e7, 0x0028, 0x080c, 0xbacb, 0x9006,
+	0x080c, 0xbd45, 0x001e, 0x002e, 0x00ee, 0x00be, 0x0005, 0x2011,
+	0x1824, 0x2204, 0x9086, 0x0014, 0x1160, 0x2001, 0x0002, 0x080c,
+	0x665d, 0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x937d, 0x0804,
+	0x98e7, 0x2001, 0x0001, 0x0804, 0xbd45, 0x2030, 0x2011, 0x1824,
+	0x2204, 0x9086, 0x0004, 0x1148, 0x96b6, 0x000b, 0x1120, 0x2001,
+	0x0007, 0x080c, 0x665d, 0x0804, 0xb0e7, 0x2001, 0x0001, 0x0804,
+	0xbd45, 0x0002, 0xbbb4, 0xbe19, 0xbbb4, 0xbe5c, 0xbbb4, 0xbf09,
+	0xbe0e, 0xbbb7, 0xbbb4, 0xbf1d, 0xbbb4, 0xbf2f, 0x6604, 0x9686,
+	0x0003, 0x0904, 0xbd75, 0x96b6, 0x001e, 0x1110, 0x080c, 0xb0e7,
+	0x0005, 0x00b6, 0x00d6, 0x00c6, 0x080c, 0xbf41, 0x11a0, 0x9006,
+	0x080c, 0x6649, 0x080c, 0x324b, 0x080c, 0xd55d, 0x2001, 0x0002,
+	0x080c, 0x665d, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x937d,
+	0x080c, 0x98e7, 0x0428, 0x2009, 0x026e, 0x2104, 0x9086, 0x0009,
+	0x1160, 0x6010, 0x2058, 0xb840, 0x9084, 0x00ff, 0x9005, 0x0180,
+	0x8001, 0xb842, 0x601b, 0x000a, 0x0098, 0x2009, 0x026f, 0x2104,
+	0x9084, 0xff00, 0x908e, 0x1900, 0x0158, 0x908e, 0x1e00, 0x0990,
+	0x080c, 0x324b, 0x080c, 0xd55d, 0x2001, 0x0001, 0x080c, 0xbd45,
+	0x00ce, 0x00de, 0x00be, 0x0005, 0x0096, 0x00b6, 0x0026, 0x9016,
+	0x080c, 0xbf4f, 0x00d6, 0x2069, 0x197d, 0x2d04, 0x9005, 0x0168,
+	0x6010, 0x2058, 0xb8a0, 0x9086, 0x007e, 0x1138, 0x2069, 0x1820,
+	0x2d04, 0x8000, 0x206a, 0x00de, 0x0010, 0x00de, 0x0088, 0x9006,
+	0x080c, 0x6649, 0x2001, 0x0002, 0x080c, 0x665d, 0x6003, 0x0001,
+	0x6007, 0x0002, 0x080c, 0x937d, 0x080c, 0x98e7, 0x0804, 0xbed9,
+	0x080c, 0xce3f, 0x01b0, 0x6014, 0x2048, 0xa864, 0x2010, 0x9086,
+	0x0139, 0x1138, 0x6007, 0x0016, 0x2001, 0x0002, 0x080c, 0xd481,
+	0x00b0, 0x6014, 0x2048, 0xa864, 0xd0fc, 0x0118, 0x2001, 0x0001,
+	0x0ca8, 0x2001, 0x180e, 0x2004, 0xd0dc, 0x0148, 0x6010, 0x2058,
+	0xb840, 0x9084, 0x00ff, 0x9005, 0x1110, 0x9006, 0x0c38, 0x080c,
+	0xbacb, 0x2009, 0x026e, 0x2134, 0x96b4, 0x00ff, 0x9686, 0x0005,
+	0x0520, 0x9686, 0x000b, 0x01c8, 0x2009, 0x026f, 0x2104, 0x9084,
+	0xff00, 0x1118, 0x9686, 0x0009, 0x01c0, 0x9086, 0x1900, 0x1168,
+	0x9686, 0x0009, 0x0190, 0x2001, 0x0004, 0x080c, 0x665d, 0x2001,
+	0x0028, 0x601a, 0x6007, 0x0052, 0x0020, 0x2001, 0x0001, 0x080c,
+	0xbd45, 0x002e, 0x00be, 0x009e, 0x0005, 0x9286, 0x0139, 0x0160,
+	0x6014, 0x2048, 0x080c, 0xce3f, 0x0140, 0xa864, 0x9086, 0x0139,
+	0x0118, 0xa868, 0xd0fc, 0x0108, 0x0c40, 0x6010, 0x2058, 0xb840,
+	0x9084, 0x00ff, 0x9005, 0x0138, 0x8001, 0xb842, 0x601b, 0x000a,
+	0x6007, 0x0016, 0x08f0, 0xb8a0, 0x9086, 0x007e, 0x1138, 0x00e6,
+	0x2071, 0x1800, 0x080c, 0x60b4, 0x00ee, 0x0010, 0x080c, 0x324b,
+	0x0860, 0x2001, 0x0004, 0x080c, 0x665d, 0x080c, 0xbf4f, 0x1140,
+	0x6003, 0x0001, 0x6007, 0x0003, 0x080c, 0x937d, 0x0804, 0x98e7,
+	0x080c, 0xbacb, 0x9006, 0x0804, 0xbd45, 0x0489, 0x1160, 0x2001,
+	0x0008, 0x080c, 0x665d, 0x6003, 0x0001, 0x6007, 0x0005, 0x080c,
+	0x937d, 0x0804, 0x98e7, 0x2001, 0x0001, 0x0804, 0xbd45, 0x00f9,
+	0x1160, 0x2001, 0x000a, 0x080c, 0x665d, 0x6003, 0x0001, 0x6007,
+	0x0001, 0x080c, 0x937d, 0x0804, 0x98e7, 0x2001, 0x0001, 0x0804,
+	0xbd45, 0x2009, 0x026e, 0x2104, 0x9086, 0x0003, 0x1138, 0x2009,
+	0x026f, 0x2104, 0x9084, 0xff00, 0x9086, 0x2a00, 0x0005, 0x9085,
+	0x0001, 0x0005, 0x00b6, 0x00c6, 0x0016, 0x6110, 0x2158, 0x080c,
+	0x6726, 0x001e, 0x00ce, 0x00be, 0x0005, 0x00b6, 0x00f6, 0x00e6,
+	0x00d6, 0x0036, 0x0016, 0x6010, 0x2058, 0x2009, 0x1837, 0x2104,
+	0x9085, 0x0003, 0x200a, 0x080c, 0xbff5, 0x0560, 0x2009, 0x1837,
+	0x2104, 0xc0cd, 0x200a, 0x080c, 0x6a88, 0x0158, 0x9006, 0x2020,
+	0x2009, 0x002a, 0x080c, 0xe940, 0x2001, 0x180c, 0x200c, 0xc195,
+	0x2102, 0x2019, 0x002a, 0x2009, 0x0001, 0x080c, 0x3216, 0x00e6,
+	0x2071, 0x1800, 0x080c, 0x3022, 0x00ee, 0x00c6, 0x0156, 0x20a9,
+	0x0781, 0x2009, 0x007f, 0x080c, 0x3347, 0x8108, 0x1f04, 0xbf93,
+	0x015e, 0x00ce, 0x080c, 0xbf52, 0x2071, 0x0260, 0x2079, 0x0200,
+	0x7817, 0x0001, 0x2001, 0x1837, 0x200c, 0xc1c5, 0x7018, 0xd0fc,
+	0x0110, 0xd0dc, 0x0118, 0x7038, 0xd0dc, 0x1108, 0xc1c4, 0x7817,
+	0x0000, 0x2001, 0x1837, 0x2102, 0x2079, 0x0100, 0x2e04, 0x9084,
+	0x00ff, 0x2069, 0x181f, 0x206a, 0x78e6, 0x0006, 0x8e70, 0x2e04,
+	0x2069, 0x1820, 0x206a, 0x78ea, 0x7832, 0x7836, 0x2010, 0x9084,
+	0xff00, 0x001e, 0x9105, 0x2009, 0x182c, 0x200a, 0x2200, 0x9084,
+	0x00ff, 0x2008, 0x080c, 0x28d2, 0x080c, 0x7563, 0x0170, 0x2071,
+	0x0260, 0x2069, 0x1983, 0x7048, 0x206a, 0x704c, 0x6806, 0x7050,
+	0x680a, 0x7054, 0x680e, 0x080c, 0xd255, 0x0040, 0x2001, 0x0006,
+	0x080c, 0x665d, 0x080c, 0x3274, 0x080c, 0xb0e7, 0x001e, 0x003e,
+	0x00de, 0x00ee, 0x00fe, 0x00be, 0x0005, 0x0096, 0x0026, 0x0036,
+	0x00e6, 0x0156, 0x2019, 0x182c, 0x231c, 0x83ff, 0x01f0, 0x2071,
+	0x0260, 0x7200, 0x9294, 0x00ff, 0x7004, 0x9084, 0xff00, 0x9205,
+	0x9306, 0x1198, 0x2011, 0x0276, 0x20a9, 0x0004, 0x2b48, 0x2019,
+	0x000a, 0x080c, 0xc0e7, 0x1148, 0x2011, 0x027a, 0x20a9, 0x0004,
+	0x2019, 0x0006, 0x080c, 0xc0e7, 0x1100, 0x015e, 0x00ee, 0x003e,
+	0x002e, 0x009e, 0x0005, 0x00e6, 0x2071, 0x0260, 0x7034, 0x9086,
+	0x0014, 0x11a8, 0x7038, 0x9086, 0x0800, 0x1188, 0x703c, 0xd0ec,
+	0x0160, 0x9084, 0x0f00, 0x9086, 0x0100, 0x1138, 0x7054, 0xd0a4,
+	0x1110, 0xd0ac, 0x0110, 0x9006, 0x0010, 0x9085, 0x0001, 0x00ee,
+	0x0005, 0x00e6, 0x0096, 0x00c6, 0x0076, 0x0056, 0x0046, 0x0026,
+	0x0006, 0x0126, 0x2091, 0x8000, 0x2029, 0x19f2, 0x252c, 0x2021,
+	0x19f8, 0x2424, 0x2061, 0x1cd0, 0x2071, 0x1800, 0x7254, 0x7074,
+	0x9202, 0x1a04, 0xc0b3, 0x080c, 0x8bbd, 0x0904, 0xc0ac, 0x080c,
+	0xe971, 0x0904, 0xc0ac, 0x6720, 0x9786, 0x0007, 0x0904, 0xc0ac,
+	0x2500, 0x9c06, 0x0904, 0xc0ac, 0x2400, 0x9c06, 0x05e8, 0x3e08,
+	0x9186, 0x0002, 0x1148, 0x6010, 0x9005, 0x0130, 0x00b6, 0x2058,
+	0xb800, 0x00be, 0xd0bc, 0x1580, 0x00c6, 0x6000, 0x9086, 0x0004,
+	0x1110, 0x080c, 0x1ab7, 0x9786, 0x000a, 0x0148, 0x080c, 0xd047,
+	0x1130, 0x00ce, 0x080c, 0xbacb, 0x080c, 0xb11a, 0x00e8, 0x6014,
+	0x2048, 0x080c, 0xce3f, 0x01a8, 0x9786, 0x0003, 0x1530, 0xa867,
+	0x0103, 0xa87c, 0xd0cc, 0x0130, 0x0096, 0xa878, 0x2048, 0x080c,
+	0x0fc0, 0x009e, 0xab7a, 0xa877, 0x0000, 0x080c, 0x6dbe, 0x080c,
+	0xd02a, 0x080c, 0xb11a, 0x00ce, 0x9ce0, 0x0018, 0x7068, 0x9c02,
+	0x1210, 0x0804, 0xc056, 0x012e, 0x000e, 0x002e, 0x004e, 0x005e,
+	0x007e, 0x00ce, 0x009e, 0x00ee, 0x0005, 0x9786, 0x0006, 0x1118,
+	0x080c, 0xe8e3, 0x0c30, 0x9786, 0x0009, 0x1148, 0x6000, 0x9086,
+	0x0004, 0x0d08, 0x2009, 0x004c, 0x080c, 0xb166, 0x08e0, 0x9786,
+	0x000a, 0x0980, 0x0820, 0x220c, 0x2304, 0x9106, 0x1130, 0x8210,
+	0x8318, 0x1f04, 0xc0d3, 0x9006, 0x0005, 0x2304, 0x9102, 0x0218,
+	0x2001, 0x0001, 0x0008, 0x9006, 0x918d, 0x0001, 0x0005, 0x0136,
+	0x01c6, 0x0016, 0x8906, 0x8006, 0x8007, 0x908c, 0x003f, 0x21e0,
+	0x9084, 0xffc0, 0x9300, 0x2098, 0x3518, 0x20a9, 0x0001, 0x220c,
+	0x4002, 0x910e, 0x1140, 0x8210, 0x8319, 0x1dc8, 0x9006, 0x001e,
+	0x01ce, 0x013e, 0x0005, 0x220c, 0x9102, 0x0218, 0x2001, 0x0001,
+	0x0010, 0x2001, 0x0000, 0x918d, 0x0001, 0x001e, 0x01ce, 0x013e,
+	0x0005, 0x220c, 0x810f, 0x2304, 0x9106, 0x1130, 0x8210, 0x8318,
+	0x1f04, 0xc111, 0x9006, 0x0005, 0x918d, 0x0001, 0x0005, 0x6004,
+	0x908a, 0x0053, 0x1a0c, 0x0dc5, 0x080c, 0xd036, 0x0120, 0x080c,
+	0xd047, 0x0168, 0x0028, 0x080c, 0x3274, 0x080c, 0xd047, 0x0138,
+	0x080c, 0x97db, 0x080c, 0xb0e7, 0x080c, 0x98e7, 0x0005, 0x080c,
+	0xbacb, 0x0cb0, 0x9182, 0x0054, 0x1220, 0x9182, 0x0040, 0x0208,
+	0x000a, 0x0005, 0xc156, 0xc156, 0xc156, 0xc156, 0xc156, 0xc156,
+	0xc156, 0xc156, 0xc156, 0xc156, 0xc156, 0xc158, 0xc158, 0xc158,
+	0xc158, 0xc156, 0xc156, 0xc156, 0xc158, 0xc156, 0x080c, 0x0dc5,
+	0x600b, 0xffff, 0x6003, 0x0001, 0x6106, 0x080c, 0x9335, 0x0126,
+	0x2091, 0x8000, 0x080c, 0x98e7, 0x012e, 0x0005, 0x9186, 0x0013,
+	0x1128, 0x6004, 0x9082, 0x0040, 0x0804, 0xc1f0, 0x9186, 0x0027,
+	0x1520, 0x080c, 0x97db, 0x080c, 0x324b, 0x080c, 0xd55d, 0x0096,
+	0x6114, 0x2148, 0x080c, 0xce3f, 0x0198, 0x080c, 0xd047, 0x1118,
+	0x080c, 0xbacb, 0x0068, 0xa867, 0x0103, 0xa87b, 0x0029, 0xa877,
+	0x0000, 0xa97c, 0xc1c5, 0xa97e, 0x080c, 0x6dcb, 0x080c, 0xd02a,
+	0x009e, 0x080c, 0xb0e7, 0x0804, 0x98e7, 0x9186, 0x0014, 0x1120,
+	0x6004, 0x9082, 0x0040, 0x00b8, 0x9186, 0x0046, 0x0150, 0x9186,
+	0x0045, 0x0138, 0x9186, 0x0053, 0x0120, 0x9186, 0x0048, 0x190c,
+	0x0dc5, 0x080c, 0xd56e, 0x0130, 0x6000, 0x9086, 0x0002, 0x1110,
+	0x0804, 0xc22e, 0x0005, 0x0002, 0xc1ca, 0xc1c8, 0xc1c8, 0xc1c8,
+	0xc1c8, 0xc1c8, 0xc1c8, 0xc1c8, 0xc1c8, 0xc1c8, 0xc1c8, 0xc1e5,
+	0xc1e5, 0xc1e5, 0xc1e5, 0xc1c8, 0xc1e5, 0xc1c8, 0xc1e5, 0xc1c8,
+	0x080c, 0x0dc5, 0x080c, 0x97db, 0x0096, 0x6114, 0x2148, 0x080c,
+	0xce3f, 0x0168, 0xa867, 0x0103, 0xa87b, 0x0006, 0xa877, 0x0000,
+	0xa880, 0xc0ec, 0xa882, 0x080c, 0x6dcb, 0x080c, 0xd02a, 0x009e,
+	0x080c, 0xb0e7, 0x080c, 0x98e7, 0x0005, 0x080c, 0x97db, 0x080c,
+	0xd047, 0x090c, 0xbacb, 0x080c, 0xb0e7, 0x080c, 0x98e7, 0x0005,
+	0x0002, 0xc207, 0xc205, 0xc205, 0xc205, 0xc205, 0xc205, 0xc205,
+	0xc205, 0xc205, 0xc205, 0xc205, 0xc21e, 0xc21e, 0xc21e, 0xc21e,
+	0xc205, 0xc228, 0xc205, 0xc21e, 0xc205, 0x080c, 0x0dc5, 0x0096,
+	0x080c, 0x97db, 0x6014, 0x2048, 0x2001, 0x1989, 0x2004, 0x6042,
+	0xa97c, 0xd1ac, 0x0140, 0x6003, 0x0004, 0xa87c, 0x9085, 0x0400,
+	0xa87e, 0x009e, 0x0005, 0x6003, 0x0002, 0x0cb8, 0x080c, 0x97db,
+	0x080c, 0xd560, 0x080c, 0xd565, 0x6003, 0x000f, 0x0804, 0x98e7,
+	0x080c, 0x97db, 0x080c, 0xb0e7, 0x0804, 0x98e7, 0x9182, 0x0054,
+	0x1220, 0x9182, 0x0040, 0x0208, 0x000a, 0x0005, 0xc24a, 0xc24a,
+	0xc24a, 0xc24a, 0xc24a, 0xc24c, 0xc329, 0xc24a, 0xc35d, 0xc24a,
+	0xc24a, 0xc24a, 0xc24a, 0xc24a, 0xc24a, 0xc24a, 0xc24a, 0xc24a,
+	0xc24a, 0xc35d, 0x080c, 0x0dc5, 0x00b6, 0x0096, 0x6114, 0x2148,
+	0x7644, 0x96b4, 0x0fff, 0x86ff, 0x1528, 0x6010, 0x2058, 0xb800,
+	0xd0bc, 0x1904, 0xc318, 0xa87b, 0x0000, 0xa867, 0x0103, 0xae76,
+	0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938, 0x9115, 0x190c, 0xc4f6,
+	0x080c, 0x6be5, 0x6210, 0x2258, 0xba3c, 0x82ff, 0x0110, 0x8211,
+	0xba3e, 0x7044, 0xd0e4, 0x1904, 0xc2fc, 0x080c, 0xb0e7, 0x009e,
+	0x00be, 0x0005, 0x968c, 0x0c00, 0x0150, 0x6010, 0x2058, 0xb800,
+	0xd0bc, 0x1904, 0xc300, 0x7348, 0xab92, 0x734c, 0xab8e, 0x968c,
+	0x00ff, 0x9186, 0x0002, 0x0508, 0x9186, 0x0028, 0x1118, 0xa87b,
+	0x001c, 0x00e8, 0xd6dc, 0x01a0, 0xa87b, 0x0015, 0xa87c, 0xd0ac,
+	0x0170, 0xa938, 0xaa34, 0x2100, 0x9205, 0x0148, 0x7048, 0x9106,
+	0x1118, 0x704c, 0x9206, 0x0118, 0xa992, 0xaa8e, 0xc6dc, 0x0038,
+	0xd6d4, 0x0118, 0xa87b, 0x0007, 0x0010, 0xa87b, 0x0000, 0xa867,
+	0x0103, 0xae76, 0x901e, 0xd6c4, 0x01d8, 0x9686, 0x0100, 0x1130,
+	0x7064, 0x9005, 0x1118, 0xc6c4, 0x0804, 0xc253, 0x735c, 0xab86,
+	0x83ff, 0x0170, 0x938a, 0x0009, 0x0210, 0x2019, 0x0008, 0x0036,
+	0x2308, 0x2019, 0x0018, 0x2011, 0x0025, 0x080c, 0xc9f0, 0x003e,
+	0xd6cc, 0x0904, 0xc268, 0x7154, 0xa98a, 0x81ff, 0x0904, 0xc268,
+	0x9192, 0x0021, 0x1278, 0x8304, 0x9098, 0x0018, 0x2011, 0x0029,
+	0x080c, 0xc9f0, 0x2011, 0x0205, 0x2013, 0x0000, 0x080c, 0xd4ed,
+	0x0804, 0xc268, 0xa868, 0xd0fc, 0x0120, 0x2009, 0x0020, 0xa98a,
+	0x0c50, 0x00a6, 0x2950, 0x080c, 0xc98f, 0x00ae, 0x080c, 0xd4ed,
+	0x080c, 0xc9e0, 0x0804, 0xc26a, 0x080c, 0xd13f, 0x0804, 0xc277,
+	0xa87c, 0xd0ac, 0x0904, 0xc283, 0xa880, 0xd0bc, 0x1904, 0xc283,
+	0x7348, 0xa838, 0x9306, 0x11c8, 0x734c, 0xa834, 0x931e, 0x0904,
+	0xc283, 0xd6d4, 0x0190, 0xab38, 0x9305, 0x0904, 0xc283, 0x0068,
+	0xa87c, 0xd0ac, 0x0904, 0xc25b, 0xa838, 0xa934, 0x9105, 0x0904,
+	0xc25b, 0xa880, 0xd0bc, 0x1904, 0xc25b, 0x080c, 0xd179, 0x0804,
+	0xc277, 0x0096, 0x00f6, 0x6003, 0x0003, 0x6007, 0x0043, 0x2079,
+	0x026c, 0x7c04, 0x7b00, 0x7e0c, 0x7d08, 0x6014, 0x2048, 0xa87c,
+	0xd0ac, 0x0140, 0x6003, 0x0002, 0x00fe, 0x009e, 0x0005, 0x2130,
+	0x2228, 0x0058, 0x2400, 0xa9ac, 0x910a, 0x2300, 0xaab0, 0x9213,
+	0x2600, 0x9102, 0x2500, 0x9203, 0x0e90, 0xac36, 0xab3a, 0xae46,
+	0xad4a, 0x00fe, 0x6043, 0x0000, 0x2c10, 0x080c, 0x1c01, 0x080c,
+	0x939a, 0x080c, 0x9a09, 0x009e, 0x0005, 0x0005, 0x9182, 0x0054,
+	0x1220, 0x9182, 0x0040, 0x0208, 0x000a, 0x0005, 0xc37a, 0xc37a,
+	0xc37a, 0xc37a, 0xc37a, 0xc37c, 0xc412, 0xc37a, 0xc37a, 0xc429,
+	0xc4b9, 0xc37a, 0xc37a, 0xc37a, 0xc37a, 0xc4ce, 0xc37a, 0xc37a,
+	0xc37a, 0xc37a, 0x080c, 0x0dc5, 0x0076, 0x00a6, 0x00e6, 0x0096,
+	0x2071, 0x0260, 0x6114, 0x2150, 0x7644, 0xb676, 0x96b4, 0x0fff,
+	0xb77c, 0xc7e5, 0xb77e, 0x6210, 0x00b6, 0x2258, 0xba3c, 0x82ff,
+	0x0110, 0x8211, 0xba3e, 0x00be, 0x86ff, 0x0904, 0xc40d, 0x9694,
+	0xff00, 0x9284, 0x0c00, 0x0120, 0x7048, 0xb092, 0x704c, 0xb08e,
+	0x9284, 0x0300, 0x0904, 0xc40d, 0x080c, 0x100e, 0x090c, 0x0dc5,
+	0x2900, 0xb07a, 0xb77c, 0xc7cd, 0xb77e, 0xa867, 0x0103, 0xb068,
+	0xa86a, 0xb06c, 0xa86e, 0xb070, 0xa872, 0xae76, 0x968c, 0x0c00,
+	0x0120, 0x7348, 0xab92, 0x734c, 0xab8e, 0x968c, 0x00ff, 0x9186,
+	0x0002, 0x0180, 0x9186, 0x0028, 0x1118, 0xa87b, 0x001c, 0x0060,
+	0xd6dc, 0x0118, 0xa87b, 0x0015, 0x0038, 0xd6d4, 0x0118, 0xa87b,
+	0x0007, 0x0010, 0xa87b, 0x0000, 0xaf7e, 0xb080, 0xa882, 0xb084,
+	0xa886, 0x901e, 0xd6c4, 0x0190, 0x735c, 0xab86, 0x83ff, 0x0170,
+	0x938a, 0x0009, 0x0210, 0x2019, 0x0008, 0x0036, 0x2308, 0x2019,
+	0x0018, 0x2011, 0x0025, 0x080c, 0xc9f0, 0x003e, 0xd6cc, 0x01e8,
+	0x7154, 0xa98a, 0x81ff, 0x01c8, 0x9192, 0x0021, 0x1260, 0x8304,
+	0x9098, 0x0018, 0x2011, 0x0029, 0x080c, 0xc9f0, 0x2011, 0x0205,
+	0x2013, 0x0000, 0x0050, 0xb068, 0xd0fc, 0x0120, 0x2009, 0x0020,
+	0xa98a, 0x0c68, 0x2950, 0x080c, 0xc98f, 0x009e, 0x00ee, 0x00ae,
+	0x007e, 0x0005, 0x00f6, 0x00a6, 0x6003, 0x0003, 0x2079, 0x026c,
+	0x7c04, 0x7b00, 0x7e0c, 0x7d08, 0x6014, 0x2050, 0xb436, 0xb33a,
+	0xb646, 0xb54a, 0x00ae, 0x00fe, 0x2c10, 0x080c, 0x1c01, 0x0804,
+	0xa4ca, 0x6003, 0x0002, 0x6004, 0x9086, 0x0040, 0x11c8, 0x0096,
+	0x6014, 0x2048, 0xa87c, 0xd0ac, 0x0160, 0x601c, 0xd084, 0x1130,
+	0x00f6, 0x2c00, 0x2078, 0x080c, 0x1768, 0x00fe, 0x6003, 0x0004,
+	0x0010, 0x6003, 0x0002, 0x009e, 0x080c, 0x97db, 0x080c, 0x98e7,
+	0x0096, 0x2001, 0x1989, 0x2004, 0x6042, 0x080c, 0x9897, 0x080c,
+	0x9a09, 0x6114, 0x2148, 0xa97c, 0xd1e4, 0x0904, 0xc4b4, 0xd1cc,
+	0x05c8, 0xa978, 0xa868, 0xd0fc, 0x0540, 0x0016, 0xa87c, 0x0006,
+	0xa880, 0x0006, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0019, 0x20a0,
+	0x810e, 0x810e, 0x810f, 0x9184, 0x003f, 0x20e0, 0x9184, 0xffc0,
+	0x9080, 0x0019, 0x2098, 0x0156, 0x20a9, 0x0020, 0x4003, 0x015e,
+	0x000e, 0xa882, 0x000e, 0xc0cc, 0xa87e, 0x001e, 0xa874, 0x0006,
+	0x2148, 0x080c, 0x0fc0, 0x001e, 0x0458, 0x0016, 0x080c, 0x0fc0,
+	0x009e, 0xa87c, 0xc0cc, 0xa87e, 0xa974, 0x0016, 0x080c, 0xc9e0,
+	0x001e, 0x00f0, 0xa867, 0x0103, 0xa974, 0x9184, 0x00ff, 0x90b6,
+	0x0002, 0x0180, 0x9086, 0x0028, 0x1118, 0xa87b, 0x001c, 0x0060,
+	0xd1dc, 0x0118, 0xa87b, 0x0015, 0x0038, 0xd1d4, 0x0118, 0xa87b,
+	0x0007, 0x0010, 0xa87b, 0x0000, 0x0016, 0x080c, 0x6be5, 0x001e,
+	0xd1e4, 0x1120, 0x080c, 0xb0e7, 0x009e, 0x0005, 0x080c, 0xd13f,
+	0x0cd8, 0x6004, 0x9086, 0x0040, 0x1120, 0x080c, 0x97db, 0x080c,
+	0x98e7, 0x2019, 0x0001, 0x080c, 0xa85d, 0x6003, 0x0002, 0x080c,
+	0xd565, 0x080c, 0x9897, 0x080c, 0x9a09, 0x0005, 0x6004, 0x9086,
+	0x0040, 0x1120, 0x080c, 0x97db, 0x080c, 0x98e7, 0x2019, 0x0001,
+	0x080c, 0xa85d, 0x080c, 0x9897, 0x080c, 0x324b, 0x080c, 0xd55d,
+	0x0096, 0x6114, 0x2148, 0x080c, 0xce3f, 0x0150, 0xa867, 0x0103,
+	0xa87b, 0x0029, 0xa877, 0x0000, 0x080c, 0x6dcb, 0x080c, 0xd02a,
+	0x009e, 0x080c, 0xb0e7, 0x080c, 0x9a09, 0x0005, 0xa87b, 0x0015,
+	0xd1fc, 0x0180, 0xa87b, 0x0007, 0x8002, 0x8000, 0x810a, 0x9189,
+	0x0000, 0x0006, 0x0016, 0x2009, 0x1a7e, 0x2104, 0x8000, 0x200a,
+	0x001e, 0x000e, 0xa992, 0xa88e, 0x0005, 0x9182, 0x0054, 0x1220,
+	0x9182, 0x0040, 0x0208, 0x000a, 0x0005, 0xc529, 0xc529, 0xc529,
+	0xc529, 0xc529, 0xc52b, 0xc529, 0xc529, 0xc5d1, 0xc529, 0xc529,
+	0xc529, 0xc529, 0xc529, 0xc529, 0xc529, 0xc529, 0xc529, 0xc529,
+	0xc703, 0x080c, 0x0dc5, 0x0076, 0x00a6, 0x00e6, 0x0096, 0x2071,
 	0x0260, 0x6114, 0x2150, 0x7644, 0xb676, 0x96b4, 0x0fff, 0xb77c,
 	0xc7e5, 0xb77e, 0x6210, 0x00b6, 0x2258, 0xba3c, 0x82ff, 0x0110,
-	0x8211, 0xba3e, 0x00be, 0x86ff, 0x0904, 0xc254, 0x9694, 0xff00,
+	0x8211, 0xba3e, 0x00be, 0x86ff, 0x0904, 0xc5ca, 0x9694, 0xff00,
 	0x9284, 0x0c00, 0x0120, 0x7048, 0xb092, 0x704c, 0xb08e, 0x9284,
-	0x0300, 0x0904, 0xc254, 0x080c, 0x0fff, 0x090c, 0x0dd5, 0x2900,
-	0xb07a, 0xb77c, 0xc7cd, 0xb77e, 0xa867, 0x0103, 0xb068, 0xa86a,
-	0xb06c, 0xa86e, 0xb070, 0xa872, 0xae76, 0x968c, 0x0c00, 0x0120,
-	0x7348, 0xab92, 0x734c, 0xab8e, 0x968c, 0x00ff, 0x9186, 0x0002,
-	0x0180, 0x9186, 0x0028, 0x1118, 0xa87b, 0x001c, 0x0060, 0xd6dc,
-	0x0118, 0xa87b, 0x0015, 0x0038, 0xd6d4, 0x0118, 0xa87b, 0x0007,
-	0x0010, 0xa87b, 0x0000, 0xaf7e, 0xb080, 0xa882, 0xb084, 0xa886,
-	0x901e, 0xd6c4, 0x0190, 0x735c, 0xab86, 0x83ff, 0x0170, 0x938a,
-	0x0009, 0x0210, 0x2019, 0x0008, 0x0036, 0x2308, 0x2019, 0x0018,
-	0x2011, 0x0025, 0x080c, 0xc837, 0x003e, 0xd6cc, 0x01e8, 0x7154,
-	0xa98a, 0x81ff, 0x01c8, 0x9192, 0x0021, 0x1260, 0x8304, 0x9098,
-	0x0018, 0x2011, 0x0029, 0x080c, 0xc837, 0x2011, 0x0205, 0x2013,
-	0x0000, 0x0050, 0xb068, 0xd0fc, 0x0120, 0x2009, 0x0020, 0xa98a,
-	0x0c68, 0x2950, 0x080c, 0xc7d6, 0x009e, 0x00ee, 0x00ae, 0x007e,
-	0x0005, 0x00f6, 0x00a6, 0x6003, 0x0003, 0x2079, 0x026c, 0x7c04,
-	0x7b00, 0x7e0c, 0x7d08, 0x6014, 0x2050, 0xb436, 0xb33a, 0xb646,
-	0xb54a, 0x00ae, 0x00fe, 0x2c10, 0x080c, 0x1beb, 0x0804, 0xa323,
-	0x6003, 0x0002, 0x6004, 0x9086, 0x0040, 0x11c8, 0x0096, 0x6014,
-	0x2048, 0xa87c, 0xd0ac, 0x0160, 0x601c, 0xd084, 0x1130, 0x00f6,
-	0x2c00, 0x2078, 0x080c, 0x1754, 0x00fe, 0x6003, 0x0004, 0x0010,
-	0x6003, 0x0002, 0x009e, 0x080c, 0x9657, 0x080c, 0x9763, 0x0096,
-	0x2001, 0x1987, 0x2004, 0x6042, 0x080c, 0x9713, 0x080c, 0x9891,
-	0x6114, 0x2148, 0xa97c, 0xd1e4, 0x0904, 0xc2fb, 0xd1cc, 0x05c8,
-	0xa978, 0xa868, 0xd0fc, 0x0540, 0x0016, 0xa87c, 0x0006, 0xa880,
-	0x0006, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0019, 0x20a0, 0x810e,
-	0x810e, 0x810f, 0x9184, 0x003f, 0x20e0, 0x9184, 0xffc0, 0x9080,
-	0x0019, 0x2098, 0x0156, 0x20a9, 0x0020, 0x4003, 0x015e, 0x000e,
-	0xa882, 0x000e, 0xc0cc, 0xa87e, 0x001e, 0xa874, 0x0006, 0x2148,
-	0x080c, 0x0fb1, 0x001e, 0x0458, 0x0016, 0x080c, 0x0fb1, 0x009e,
-	0xa87c, 0xc0cc, 0xa87e, 0xa974, 0x0016, 0x080c, 0xc827, 0x001e,
-	0x00f0, 0xa867, 0x0103, 0xa974, 0x9184, 0x00ff, 0x90b6, 0x0002,
-	0x0180, 0x9086, 0x0028, 0x1118, 0xa87b, 0x001c, 0x0060, 0xd1dc,
-	0x0118, 0xa87b, 0x0015, 0x0038, 0xd1d4, 0x0118, 0xa87b, 0x0007,
-	0x0010, 0xa87b, 0x0000, 0x0016, 0x080c, 0x6b33, 0x001e, 0xd1e4,
-	0x1120, 0x080c, 0xaf43, 0x009e, 0x0005, 0x080c, 0xcf86, 0x0cd8,
-	0x6004, 0x9086, 0x0040, 0x1120, 0x080c, 0x9657, 0x080c, 0x9763,
-	0x2019, 0x0001, 0x080c, 0xa6ac, 0x6003, 0x0002, 0x080c, 0xd3a5,
-	0x080c, 0x9713, 0x080c, 0x9891, 0x0005, 0x6004, 0x9086, 0x0040,
-	0x1120, 0x080c, 0x9657, 0x080c, 0x9763, 0x2019, 0x0001, 0x080c,
-	0xa6ac, 0x080c, 0x9713, 0x080c, 0x321e, 0x080c, 0xd39d, 0x0096,
-	0x6114, 0x2148, 0x080c, 0xcc86, 0x0150, 0xa867, 0x0103, 0xa87b,
-	0x0029, 0xa877, 0x0000, 0x080c, 0x6d17, 0x080c, 0xce71, 0x009e,
-	0x080c, 0xaf43, 0x080c, 0x9891, 0x0005, 0xa87b, 0x0015, 0xd1fc,
-	0x0180, 0xa87b, 0x0007, 0x8002, 0x8000, 0x810a, 0x9189, 0x0000,
-	0x0006, 0x0016, 0x2009, 0x1a79, 0x2104, 0x8000, 0x200a, 0x001e,
-	0x000e, 0xa992, 0xa88e, 0x0005, 0x9182, 0x0054, 0x1220, 0x9182,
-	0x0040, 0x0208, 0x000a, 0x0005, 0xc370, 0xc370, 0xc370, 0xc370,
-	0xc370, 0xc372, 0xc370, 0xc370, 0xc418, 0xc370, 0xc370, 0xc370,
-	0xc370, 0xc370, 0xc370, 0xc370, 0xc370, 0xc370, 0xc370, 0xc54a,
-	0x080c, 0x0dd5, 0x0076, 0x00a6, 0x00e6, 0x0096, 0x2071, 0x0260,
-	0x6114, 0x2150, 0x7644, 0xb676, 0x96b4, 0x0fff, 0xb77c, 0xc7e5,
-	0xb77e, 0x6210, 0x00b6, 0x2258, 0xba3c, 0x82ff, 0x0110, 0x8211,
-	0xba3e, 0x00be, 0x86ff, 0x0904, 0xc411, 0x9694, 0xff00, 0x9284,
-	0x0c00, 0x0120, 0x7048, 0xb092, 0x704c, 0xb08e, 0x9284, 0x0300,
-	0x0904, 0xc411, 0x9686, 0x0100, 0x1130, 0x7064, 0x9005, 0x1118,
-	0xc6c4, 0xb676, 0x0c38, 0x080c, 0x0fff, 0x090c, 0x0dd5, 0x2900,
-	0xb07a, 0xb77c, 0x97bd, 0x0200, 0xb77e, 0xa867, 0x0103, 0xb068,
-	0xa86a, 0xb06c, 0xa86e, 0xb070, 0xa872, 0x7044, 0x9084, 0xf000,
-	0x9635, 0xae76, 0x968c, 0x0c00, 0x0120, 0x7348, 0xab92, 0x734c,
-	0xab8e, 0x968c, 0x00ff, 0x9186, 0x0002, 0x0180, 0x9186, 0x0028,
-	0x1118, 0xa87b, 0x001c, 0x0060, 0xd6dc, 0x0118, 0xa87b, 0x0015,
-	0x0038, 0xd6d4, 0x0118, 0xa87b, 0x0007, 0x0010, 0xa87b, 0x0000,
-	0xaf7e, 0xb080, 0xa882, 0xb084, 0xa886, 0x901e, 0xd6c4, 0x0190,
-	0x735c, 0xab86, 0x83ff, 0x0170, 0x938a, 0x0009, 0x0210, 0x2019,
-	0x0008, 0x0036, 0x2308, 0x2019, 0x0018, 0x2011, 0x0025, 0x080c,
-	0xc837, 0x003e, 0xd6cc, 0x01e8, 0x7154, 0xa98a, 0x81ff, 0x01c8,
-	0x9192, 0x0021, 0x1260, 0x8304, 0x9098, 0x0018, 0x2011, 0x0029,
-	0x080c, 0xc837, 0x2011, 0x0205, 0x2013, 0x0000, 0x0050, 0xb068,
-	0xd0fc, 0x0120, 0x2009, 0x0020, 0xa98a, 0x0c68, 0x2950, 0x080c,
-	0xc7d6, 0x080c, 0x1a6f, 0x009e, 0x00ee, 0x00ae, 0x007e, 0x0005,
-	0x2001, 0x1987, 0x2004, 0x6042, 0x0096, 0x6114, 0x2148, 0xa83c,
-	0xa940, 0x9105, 0x1118, 0xa87c, 0xc0dc, 0xa87e, 0x6003, 0x0002,
-	0xa97c, 0xd1e4, 0x0904, 0xc545, 0x6043, 0x0000, 0x6010, 0x00b6,
-	0x2058, 0xb800, 0x00be, 0xd0bc, 0x1500, 0xd1cc, 0x0904, 0xc514,
-	0xa978, 0xa868, 0xd0fc, 0x0904, 0xc4d5, 0x0016, 0xa87c, 0x0006,
-	0xa880, 0x0006, 0x00a6, 0x2150, 0xb174, 0x9184, 0x00ff, 0x90b6,
-	0x0002, 0x0904, 0xc4a2, 0x9086, 0x0028, 0x1904, 0xc48e, 0xa87b,
-	0x001c, 0xb07b, 0x001c, 0x0804, 0xc4aa, 0x6024, 0xd0f4, 0x11d0,
-	0xa838, 0xaa34, 0x9205, 0x09c8, 0xa838, 0xaa90, 0x9206, 0x1120,
-	0xa88c, 0xaa34, 0x9206, 0x0988, 0x6024, 0xd0d4, 0x1148, 0xa9ac,
-	0xa834, 0x9102, 0x603a, 0xa9b0, 0xa838, 0x9103, 0x603e, 0x6024,
-	0xc0f5, 0x6026, 0x6010, 0x00b6, 0x2058, 0xb83c, 0x8000, 0xb83e,
-	0x00be, 0x9006, 0xa876, 0xa892, 0xa88e, 0xa87c, 0xc0e4, 0xa87e,
-	0xd0cc, 0x0140, 0xc0cc, 0xa87e, 0x0096, 0xa878, 0x2048, 0x080c,
-	0x0fb1, 0x009e, 0x080c, 0xcfc0, 0x0804, 0xc545, 0xd1dc, 0x0158,
-	0xa87b, 0x0015, 0xb07b, 0x0015, 0x080c, 0xd250, 0x0118, 0xb174,
-	0xc1dc, 0xb176, 0x0078, 0xd1d4, 0x0128, 0xa87b, 0x0007, 0xb07b,
-	0x0007, 0x0040, 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938, 0x9115,
-	0x190c, 0xc33d, 0xa87c, 0xb07e, 0xa890, 0xb092, 0xa88c, 0xb08e,
-	0xa860, 0x20e8, 0xa85c, 0x9080, 0x0019, 0x20a0, 0x20a9, 0x0020,
-	0x8a06, 0x8006, 0x8007, 0x9094, 0x003f, 0x22e0, 0x9084, 0xffc0,
-	0x9080, 0x0019, 0x2098, 0x4003, 0x00ae, 0x000e, 0xa882, 0x000e,
-	0xc0cc, 0xa87e, 0x080c, 0xd32d, 0x001e, 0xa874, 0x0006, 0x2148,
-	0x080c, 0x0fb1, 0x001e, 0x0804, 0xc541, 0x0016, 0x00a6, 0x2150,
-	0xb174, 0x9184, 0x00ff, 0x90b6, 0x0002, 0x01e0, 0x9086, 0x0028,
-	0x1128, 0xa87b, 0x001c, 0xb07b, 0x001c, 0x00e0, 0xd1dc, 0x0158,
-	0xa87b, 0x0015, 0xb07b, 0x0015, 0x080c, 0xd250, 0x0118, 0xb174,
-	0xc1dc, 0xb176, 0x0078, 0xd1d4, 0x0128, 0xa87b, 0x0007, 0xb07b,
-	0x0007, 0x0040, 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938, 0x9115,
-	0x190c, 0xc33d, 0xa890, 0xb092, 0xa88c, 0xb08e, 0xa87c, 0xb07e,
-	0x00ae, 0x080c, 0x0fb1, 0x009e, 0x080c, 0xd32d, 0xa974, 0x0016,
-	0x080c, 0xc827, 0x001e, 0x0468, 0xa867, 0x0103, 0xa974, 0x9184,
-	0x00ff, 0x90b6, 0x0002, 0x01b0, 0x9086, 0x0028, 0x1118, 0xa87b,
-	0x001c, 0x00d0, 0xd1dc, 0x0148, 0xa87b, 0x0015, 0x080c, 0xd250,
-	0x0118, 0xa974, 0xc1dc, 0xa976, 0x0078, 0xd1d4, 0x0118, 0xa87b,
-	0x0007, 0x0050, 0xa87b, 0x0000, 0xa87c, 0xd0ac, 0x0128, 0xa834,
-	0xa938, 0x9115, 0x190c, 0xc33d, 0xa974, 0x0016, 0x080c, 0x6b33,
-	0x001e, 0xd1e4, 0x1120, 0x080c, 0xaf43, 0x009e, 0x0005, 0x080c,
-	0xcf86, 0x0cd8, 0x6114, 0x0096, 0x2148, 0xa97c, 0xd1e4, 0x190c,
-	0x1a8d, 0x009e, 0x0005, 0x080c, 0x9657, 0x0010, 0x080c, 0x9713,
-	0x080c, 0xcc86, 0x01f0, 0x0096, 0x6114, 0x2148, 0x080c, 0xce8e,
-	0x1118, 0x080c, 0xb905, 0x00a0, 0xa867, 0x0103, 0x2009, 0x180c,
-	0x210c, 0xd18c, 0x11b8, 0xd184, 0x1190, 0x6108, 0xa97a, 0x918e,
-	0x0029, 0x1110, 0x080c, 0xea94, 0xa877, 0x0000, 0x080c, 0x6d17,
-	0x009e, 0x080c, 0xaf43, 0x080c, 0x9763, 0x0804, 0x9891, 0xa87b,
-	0x0004, 0x0c90, 0xa87b, 0x0004, 0x0c78, 0x9182, 0x0054, 0x1220,
-	0x9182, 0x0040, 0x0208, 0x000a, 0x0005, 0xc5a1, 0xc5a1, 0xc5a1,
-	0xc5a1, 0xc5a1, 0xc5a3, 0xc5a1, 0xc5a1, 0xc5a1, 0xc5a1, 0xc5a1,
-	0xc5a1, 0xc5a1, 0xc5a1, 0xc5a1, 0xc5a1, 0xc5a1, 0xc5a1, 0xc5a1,
-	0xc5a1, 0x080c, 0x0dd5, 0x080c, 0x5765, 0x01f8, 0x6014, 0x7144,
-	0x918c, 0x0fff, 0x9016, 0xd1c4, 0x0118, 0x7264, 0x9294, 0x00ff,
-	0x0096, 0x904d, 0x0188, 0xa87b, 0x0000, 0xa864, 0x9086, 0x0139,
-	0x0128, 0xa867, 0x0103, 0xa976, 0xaa96, 0x0030, 0xa897, 0x4000,
-	0xa99a, 0xaa9e, 0x080c, 0x6d17, 0x009e, 0x0804, 0xaf43, 0x9182,
-	0x0085, 0x0002, 0xc5d9, 0xc5d7, 0xc5d7, 0xc5e5, 0xc5d7, 0xc5d7,
-	0xc5d7, 0xc5d7, 0xc5d7, 0xc5d7, 0xc5d7, 0xc5d7, 0xc5d7, 0x080c,
-	0x0dd5, 0x6003, 0x0001, 0x6106, 0x080c, 0x91b1, 0x0126, 0x2091,
-	0x8000, 0x080c, 0x9763, 0x012e, 0x0005, 0x0026, 0x0056, 0x00d6,
-	0x00e6, 0x2071, 0x0260, 0x7224, 0x6216, 0x7220, 0x080c, 0xcc74,
-	0x01f8, 0x2268, 0x6800, 0x9086, 0x0000, 0x01d0, 0x6010, 0x6d10,
-	0x952e, 0x11b0, 0x00c6, 0x2d60, 0x00d6, 0x080c, 0xc898, 0x00de,
-	0x00ce, 0x0158, 0x702c, 0xd084, 0x1118, 0x080c, 0xc862, 0x0010,
-	0x6803, 0x0002, 0x6007, 0x0086, 0x0028, 0x080c, 0xc884, 0x0d90,
-	0x6007, 0x0087, 0x6003, 0x0001, 0x080c, 0x91b1, 0x080c, 0x9763,
-	0x7220, 0x080c, 0xcc74, 0x0178, 0x6810, 0x00b6, 0x2058, 0xb800,
-	0x00be, 0xd0bc, 0x0140, 0x6824, 0xd0ec, 0x0128, 0x00c6, 0x2d60,
-	0x080c, 0xcfc0, 0x00ce, 0x00ee, 0x00de, 0x005e, 0x002e, 0x0005,
-	0x9186, 0x0013, 0x1160, 0x6004, 0x908a, 0x0085, 0x0a0c, 0x0dd5,
-	0x908a, 0x0092, 0x1a0c, 0x0dd5, 0x9082, 0x0085, 0x00e2, 0x9186,
-	0x0027, 0x0120, 0x9186, 0x0014, 0x190c, 0x0dd5, 0x080c, 0x9657,
-	0x0096, 0x6014, 0x2048, 0x080c, 0xcc86, 0x0140, 0xa867, 0x0103,
-	0xa877, 0x0000, 0xa87b, 0x0029, 0x080c, 0x6d17, 0x009e, 0x080c,
-	0xaf74, 0x0804, 0x9763, 0xc668, 0xc66a, 0xc66a, 0xc668, 0xc668,
-	0xc668, 0xc668, 0xc668, 0xc668, 0xc668, 0xc668, 0xc668, 0xc668,
-	0x080c, 0x0dd5, 0x080c, 0x9657, 0x080c, 0xaf74, 0x080c, 0x9763,
-	0x0005, 0x9186, 0x0013, 0x1128, 0x6004, 0x9082, 0x0085, 0x2008,
-	0x04b8, 0x9186, 0x0027, 0x11f8, 0x080c, 0x9657, 0x080c, 0x321e,
-	0x080c, 0xd39d, 0x0096, 0x6014, 0x2048, 0x080c, 0xcc86, 0x0150,
-	0xa867, 0x0103, 0xa877, 0x0000, 0xa87b, 0x0029, 0x080c, 0x6d17,
-	0x080c, 0xce71, 0x009e, 0x080c, 0xaf43, 0x080c, 0x9763, 0x0005,
-	0x080c, 0xafd9, 0x0ce0, 0x9186, 0x0014, 0x1dd0, 0x080c, 0x9657,
-	0x0096, 0x6014, 0x2048, 0x080c, 0xcc86, 0x0d60, 0xa867, 0x0103,
-	0xa877, 0x0000, 0xa87b, 0x0006, 0xa880, 0xc0ec, 0xa882, 0x08f0,
-	0x0002, 0xc6c0, 0xc6be, 0xc6be, 0xc6be, 0xc6be, 0xc6be, 0xc6d8,
-	0xc6be, 0xc6be, 0xc6be, 0xc6be, 0xc6be, 0xc6be, 0x080c, 0x0dd5,
-	0x080c, 0x9657, 0x6034, 0x908c, 0xff00, 0x810f, 0x9186, 0x0039,
-	0x0118, 0x9186, 0x0035, 0x1118, 0x2001, 0x1985, 0x0010, 0x2001,
-	0x1986, 0x2004, 0x601a, 0x6003, 0x000c, 0x080c, 0x9763, 0x0005,
-	0x080c, 0x9657, 0x6034, 0x908c, 0xff00, 0x810f, 0x9186, 0x0039,
-	0x0118, 0x9186, 0x0035, 0x1118, 0x2001, 0x1985, 0x0010, 0x2001,
-	0x1986, 0x2004, 0x601a, 0x6003, 0x000e, 0x080c, 0x9763, 0x0005,
-	0x9182, 0x0092, 0x1220, 0x9182, 0x0085, 0x0208, 0x0012, 0x0804,
-	0xafd9, 0xc706, 0xc706, 0xc706, 0xc706, 0xc708, 0xc755, 0xc706,
-	0xc706, 0xc706, 0xc706, 0xc706, 0xc706, 0xc706, 0x080c, 0x0dd5,
-	0x0096, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x0168,
-	0x6034, 0x908c, 0xff00, 0x810f, 0x9186, 0x0039, 0x0118, 0x9186,
-	0x0035, 0x1118, 0x009e, 0x0804, 0xc769, 0x080c, 0xcc86, 0x1118,
-	0x080c, 0xce71, 0x0068, 0x6014, 0x2048, 0xa87c, 0xd0e4, 0x1110,
-	0x080c, 0xce71, 0xa867, 0x0103, 0x080c, 0xd368, 0x080c, 0x6d17,
-	0x00d6, 0x2c68, 0x080c, 0xaeed, 0x01d0, 0x6003, 0x0001, 0x6007,
-	0x001e, 0x600b, 0xffff, 0x2009, 0x026e, 0x210c, 0x613a, 0x2009,
-	0x026f, 0x210c, 0x613e, 0x6910, 0x6112, 0x080c, 0xd102, 0x6954,
-	0x6156, 0x6023, 0x0001, 0x080c, 0x91b1, 0x080c, 0x9763, 0x2d60,
-	0x00de, 0x080c, 0xaf43, 0x009e, 0x0005, 0x6010, 0x00b6, 0x2058,
-	0xb800, 0x00be, 0xd0bc, 0x05a0, 0x6034, 0x908c, 0xff00, 0x810f,
-	0x9186, 0x0035, 0x0130, 0x9186, 0x001e, 0x0118, 0x9186, 0x0039,
-	0x1538, 0x00d6, 0x2c68, 0x080c, 0xd300, 0x11f0, 0x080c, 0xaeed,
-	0x01d8, 0x6106, 0x6003, 0x0001, 0x6023, 0x0001, 0x6910, 0x6112,
-	0x692c, 0x612e, 0x6930, 0x6132, 0x6934, 0x918c, 0x00ff, 0x6136,
-	0x6938, 0x613a, 0x693c, 0x613e, 0x6954, 0x6156, 0x080c, 0xd102,
-	0x080c, 0x91b1, 0x080c, 0x9763, 0x2d60, 0x00de, 0x0804, 0xaf43,
-	0x0096, 0x6014, 0x2048, 0x080c, 0xcc86, 0x01c8, 0xa867, 0x0103,
-	0xa880, 0xd0b4, 0x0128, 0xc0ec, 0xa882, 0xa87b, 0x0006, 0x0048,
-	0xd0bc, 0x0118, 0xa87b, 0x0002, 0x0020, 0xa87b, 0x0005, 0x080c,
-	0xcf82, 0xa877, 0x0000, 0x080c, 0x6d17, 0x080c, 0xce71, 0x009e,
-	0x0804, 0xaf43, 0x0016, 0x0096, 0x6014, 0x2048, 0x080c, 0xcc86,
-	0x0140, 0xa867, 0x0103, 0xa87b, 0x0028, 0xa877, 0x0000, 0x080c,
-	0x6d17, 0x009e, 0x001e, 0x9186, 0x0013, 0x0148, 0x9186, 0x0014,
-	0x0130, 0x9186, 0x0027, 0x0118, 0x080c, 0xafd9, 0x0030, 0x080c,
-	0x9657, 0x080c, 0xaf74, 0x080c, 0x9763, 0x0005, 0x0056, 0x0066,
-	0x0096, 0x00a6, 0x2029, 0x0001, 0x9182, 0x0101, 0x1208, 0x0010,
-	0x2009, 0x0100, 0x2130, 0x8304, 0x9098, 0x0018, 0x2009, 0x0020,
-	0x2011, 0x0029, 0x080c, 0xc837, 0x96b2, 0x0020, 0xb004, 0x904d,
-	0x0110, 0x080c, 0x0fb1, 0x080c, 0x0fff, 0x0520, 0x8528, 0xa867,
-	0x0110, 0xa86b, 0x0000, 0x2920, 0xb406, 0x968a, 0x003d, 0x1228,
-	0x2608, 0x2011, 0x001b, 0x0499, 0x00a8, 0x96b2, 0x003c, 0x2009,
-	0x003c, 0x2950, 0x2011, 0x001b, 0x0451, 0x0c28, 0x2001, 0x0205,
-	0x2003, 0x0000, 0x00ae, 0x852f, 0x95ad, 0x0003, 0xb566, 0x95ac,
-	0x0000, 0x0048, 0x2001, 0x0205, 0x2003, 0x0000, 0x00ae, 0x852f,
-	0x95ad, 0x0003, 0xb566, 0x009e, 0x006e, 0x005e, 0x0005, 0x00a6,
-	0x89ff, 0x0158, 0xa804, 0x9055, 0x0130, 0xa807, 0x0000, 0x080c,
-	0x6d17, 0x2a48, 0x0cb8, 0x080c, 0x6d17, 0x00ae, 0x0005, 0x00f6,
-	0x2079, 0x0200, 0x7814, 0x9085, 0x0080, 0x7816, 0xd184, 0x0108,
-	0x8108, 0x810c, 0x20a9, 0x0001, 0xa860, 0x20e8, 0xa85c, 0x9200,
-	0x20a0, 0x20e1, 0x0000, 0x2300, 0x9e00, 0x2098, 0x4003, 0x8318,
-	0x9386, 0x0020, 0x1148, 0x2018, 0x2300, 0x9e00, 0x2098, 0x7814,
-	0x8000, 0x9085, 0x0080, 0x7816, 0x8109, 0x1d80, 0x7817, 0x0000,
-	0x00fe, 0x0005, 0x6920, 0x9186, 0x0003, 0x0118, 0x9186, 0x0002,
-	0x11d0, 0x00c6, 0x00d6, 0x00e6, 0x2d60, 0x0096, 0x6014, 0x2048,
-	0x080c, 0xcc86, 0x0150, 0x2001, 0x0006, 0xa980, 0xc1d5, 0x080c,
-	0x6f4a, 0x080c, 0x6d0b, 0x080c, 0xce71, 0x009e, 0x080c, 0xaf74,
-	0x00ee, 0x00de, 0x00ce, 0x0005, 0x00c6, 0x702c, 0xd084, 0x1170,
-	0x6008, 0x2060, 0x6020, 0x9086, 0x0002, 0x1140, 0x6104, 0x9186,
-	0x0085, 0x0118, 0x9186, 0x008b, 0x1108, 0x9006, 0x00ce, 0x0005,
-	0x0066, 0x0126, 0x2091, 0x8000, 0x2031, 0x0001, 0x6020, 0x9084,
-	0x000f, 0x0083, 0x012e, 0x006e, 0x0005, 0x0126, 0x2091, 0x8000,
-	0x0066, 0x2031, 0x0000, 0x6020, 0x9084, 0x000f, 0x001b, 0x006e,
-	0x012e, 0x0005, 0xc8d3, 0xc8d3, 0xc8ce, 0xc8f5, 0xc8c1, 0xc8ce,
-	0xc8f5, 0xc8ce, 0xc8c1, 0x8f95, 0xc8ce, 0xc8ce, 0xc8ce, 0xc8c1,
-	0xc8c1, 0x080c, 0x0dd5, 0x0036, 0x2019, 0x0010, 0x080c, 0xe2c0,
-	0x6023, 0x0006, 0x6003, 0x0007, 0x003e, 0x0005, 0x9006, 0x0005,
-	0x9085, 0x0001, 0x0005, 0x0096, 0x86ff, 0x11d8, 0x6014, 0x2048,
-	0x080c, 0xcc86, 0x01c0, 0xa864, 0x9086, 0x0139, 0x1128, 0xa87b,
-	0x0005, 0xa883, 0x0000, 0x0028, 0x900e, 0x2001, 0x0005, 0x080c,
-	0x6f4a, 0x080c, 0xcf82, 0x080c, 0x6d0b, 0x080c, 0xaf74, 0x9085,
-	0x0001, 0x009e, 0x0005, 0x9006, 0x0ce0, 0x6000, 0x908a, 0x0016,
-	0x1a0c, 0x0dd5, 0x0002, 0xc90b, 0xc93b, 0xc90d, 0xc95c, 0xc936,
-	0xc90b, 0xc8ce, 0xc8d3, 0xc8d3, 0xc8ce, 0xc8ce, 0xc8ce, 0xc8ce,
-	0xc8ce, 0xc8ce, 0xc8ce, 0x080c, 0x0dd5, 0x86ff, 0x1520, 0x6020,
-	0x9086, 0x0006, 0x0500, 0x0096, 0x6014, 0x2048, 0x080c, 0xcc86,
-	0x0168, 0xa87c, 0xd0cc, 0x0140, 0x0096, 0xc0cc, 0xa87e, 0xa878,
-	0x2048, 0x080c, 0x0fb1, 0x009e, 0x080c, 0xcf82, 0x009e, 0x080c,
-	0xd342, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002, 0x080c,
-	0x91b1, 0x080c, 0x9763, 0x9085, 0x0001, 0x0005, 0x0066, 0x080c,
-	0x1aa1, 0x006e, 0x0890, 0x00e6, 0x2071, 0x19e6, 0x7024, 0x9c06,
-	0x1120, 0x080c, 0xa636, 0x00ee, 0x0840, 0x6020, 0x9084, 0x000f,
-	0x9086, 0x0006, 0x1150, 0x0086, 0x0096, 0x2049, 0x0001, 0x2c40,
-	0x080c, 0xa76b, 0x009e, 0x008e, 0x0010, 0x080c, 0xa533, 0x00ee,
-	0x1904, 0xc90d, 0x0804, 0xc8ce, 0x0036, 0x00e6, 0x2071, 0x19e6,
-	0x703c, 0x9c06, 0x1138, 0x901e, 0x080c, 0xa6ac, 0x00ee, 0x003e,
-	0x0804, 0xc90d, 0x080c, 0xa89b, 0x00ee, 0x003e, 0x1904, 0xc90d,
-	0x0804, 0xc8ce, 0x00c6, 0x6020, 0x9084, 0x000f, 0x0013, 0x00ce,
-	0x0005, 0xc98f, 0xca5a, 0xcbc4, 0xc999, 0xaf74, 0xc98f, 0xe2b2,
-	0xd3aa, 0xca5a, 0x8f67, 0xcc50, 0xc988, 0xc988, 0xc988, 0xc988,
-	0x080c, 0x0dd5, 0x080c, 0xce8e, 0x1110, 0x080c, 0xb905, 0x0005,
-	0x080c, 0x9657, 0x080c, 0x9763, 0x0804, 0xaf43, 0x601b, 0x0001,
-	0x0005, 0x080c, 0xcc86, 0x0130, 0x6014, 0x0096, 0x2048, 0x2c00,
-	0xa896, 0x009e, 0x6000, 0x908a, 0x0016, 0x1a0c, 0x0dd5, 0x0002,
-	0xc9b8, 0xc9ba, 0xc9de, 0xc9f2, 0xca18, 0xc9b8, 0xc98f, 0xc98f,
-	0xc98f, 0xc9f2, 0xc9f2, 0xc9b8, 0xc9b8, 0xc9b8, 0xc9b8, 0xc9fc,
-	0x080c, 0x0dd5, 0x00e6, 0x6014, 0x0096, 0x2048, 0xa880, 0xc0b5,
-	0xa882, 0x009e, 0x2071, 0x19e6, 0x7024, 0x9c06, 0x01a0, 0x080c,
-	0xa533, 0x080c, 0xd342, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023,
-	0x0002, 0x2001, 0x1986, 0x2004, 0x601a, 0x080c, 0x91b1, 0x080c,
-	0x9763, 0x00ee, 0x0005, 0x601b, 0x0001, 0x0cd8, 0x0096, 0x6014,
-	0x2048, 0xa880, 0xc0b5, 0xa882, 0x009e, 0x080c, 0xd342, 0x6007,
-	0x0085, 0x6003, 0x000b, 0x6023, 0x0002, 0x080c, 0x91b1, 0x080c,
-	0x9763, 0x0005, 0x0096, 0x601b, 0x0001, 0x6014, 0x2048, 0xa880,
-	0xc0b5, 0xa882, 0x009e, 0x0005, 0x080c, 0x5765, 0x01b8, 0x6014,
-	0x0096, 0x904d, 0x0190, 0xa864, 0xa867, 0x0103, 0xa87b, 0x0006,
-	0x9086, 0x0139, 0x1150, 0xa867, 0x0139, 0xa87b, 0x0030, 0xa897,
-	0x4005, 0xa89b, 0x0004, 0x080c, 0x6d17, 0x009e, 0x0804, 0xaf43,
-	0x6014, 0x0096, 0x904d, 0x05c8, 0xa97c, 0xd1e4, 0x05b0, 0x2001,
-	0x180f, 0x2004, 0xd0c4, 0x0110, 0x009e, 0x0005, 0xa884, 0x009e,
-	0x8003, 0x800b, 0x810b, 0x9108, 0x611a, 0x2001, 0x0030, 0x2c08,
-	0x080c, 0x15fd, 0x2001, 0x030c, 0x2004, 0x9086, 0x0041, 0x11a0,
-	0x6014, 0x0096, 0x904d, 0x090c, 0x0dd5, 0xa880, 0xd0f4, 0x1130,
-	0xc0f5, 0xa882, 0x009e, 0x601b, 0x0002, 0x0070, 0x009e, 0x2001,
-	0x0037, 0x2c08, 0x080c, 0x15fd, 0x6000, 0x9086, 0x0004, 0x1120,
-	0x2009, 0x0048, 0x080c, 0xafbe, 0x0005, 0x009e, 0x080c, 0x1aa1,
-	0x0804, 0xc9de, 0x6000, 0x908a, 0x0016, 0x1a0c, 0x0dd5, 0x000b,
-	0x0005, 0xca71, 0xc996, 0xca73, 0xca71, 0xca73, 0xca73, 0xc990,
-	0xca71, 0xc98a, 0xc98a, 0xca71, 0xca71, 0xca71, 0xca71, 0xca71,
-	0xca71, 0x080c, 0x0dd5, 0x6010, 0x00b6, 0x2058, 0xb804, 0x9084,
-	0x00ff, 0x00be, 0x908a, 0x000c, 0x1a0c, 0x0dd5, 0x00b6, 0x0013,
-	0x00be, 0x0005, 0xca8e, 0xcb5b, 0xca90, 0xcad0, 0xca90, 0xcad0,
-	0xca90, 0xca9e, 0xca8e, 0xcad0, 0xca8e, 0xcabf, 0x080c, 0x0dd5,
-	0x6004, 0x908e, 0x0016, 0x05c0, 0x908e, 0x0004, 0x05a8, 0x908e,
-	0x0002, 0x0590, 0x908e, 0x0052, 0x0904, 0xcb57, 0x6004, 0x080c,
-	0xce8e, 0x0904, 0xcb74, 0x908e, 0x0004, 0x1110, 0x080c, 0x3247,
-	0x908e, 0x0021, 0x0904, 0xcb78, 0x908e, 0x0022, 0x0904, 0xcbbf,
-	0x908e, 0x003d, 0x0904, 0xcb78, 0x908e, 0x0039, 0x0904, 0xcb7c,
-	0x908e, 0x0035, 0x0904, 0xcb7c, 0x908e, 0x001e, 0x0178, 0x908e,
-	0x0001, 0x1140, 0x6010, 0x2058, 0xb804, 0x9084, 0x00ff, 0x9086,
-	0x0006, 0x0110, 0x080c, 0x321e, 0x080c, 0xb905, 0x0804, 0xaf74,
-	0x00c6, 0x00d6, 0x6104, 0x9186, 0x0016, 0x0904, 0xcb48, 0x9186,
-	0x0002, 0x1904, 0xcb1d, 0x2001, 0x1837, 0x2004, 0xd08c, 0x11c8,
-	0x080c, 0x743e, 0x11b0, 0x080c, 0xd388, 0x0138, 0x080c, 0x7461,
-	0x1120, 0x080c, 0x7348, 0x0804, 0xcba8, 0x2001, 0x197c, 0x2003,
-	0x0001, 0x2001, 0x1800, 0x2003, 0x0001, 0x080c, 0x736a, 0x0804,
-	0xcba8, 0x6010, 0x2058, 0x2001, 0x1837, 0x2004, 0xd0ac, 0x1904,
-	0xcba8, 0xb8a0, 0x9084, 0xff80, 0x1904, 0xcba8, 0xb840, 0x9084,
-	0x00ff, 0x9005, 0x0190, 0x8001, 0xb842, 0x6017, 0x0000, 0x6023,
-	0x0007, 0x601b, 0x0398, 0x6043, 0x0000, 0x080c, 0xaeed, 0x0128,
-	0x2b00, 0x6012, 0x6023, 0x0001, 0x0458, 0x00de, 0x00ce, 0x6004,
-	0x908e, 0x0002, 0x11a0, 0x6010, 0x2058, 0xb8a0, 0x9086, 0x007e,
-	0x1170, 0x2009, 0x1837, 0x2104, 0xc085, 0x200a, 0x00e6, 0x2071,
-	0x1800, 0x080c, 0x6040, 0x00ee, 0x080c, 0xb905, 0x0030, 0x080c,
-	0xb905, 0x080c, 0x321e, 0x080c, 0xd39d, 0x00e6, 0x0126, 0x2091,
-	0x8000, 0x080c, 0x3247, 0x012e, 0x00ee, 0x080c, 0xaf74, 0x0005,
-	0x2001, 0x0002, 0x080c, 0x65e9, 0x6003, 0x0001, 0x6007, 0x0002,
-	0x080c, 0x91f9, 0x080c, 0x9763, 0x00de, 0x00ce, 0x0c80, 0x080c,
-	0x3247, 0x0804, 0xcacc, 0x00c6, 0x00d6, 0x6104, 0x9186, 0x0016,
-	0x0d38, 0x6010, 0x2058, 0xb840, 0x9084, 0x00ff, 0x9005, 0x0904,
-	0xcb1d, 0x8001, 0xb842, 0x6003, 0x0001, 0x080c, 0x91f9, 0x080c,
-	0x9763, 0x00de, 0x00ce, 0x0898, 0x080c, 0xb905, 0x0804, 0xcace,
-	0x080c, 0xb941, 0x0804, 0xcace, 0x00d6, 0x2c68, 0x6104, 0x080c,
-	0xd300, 0x00de, 0x0118, 0x080c, 0xaf43, 0x0408, 0x6004, 0x8007,
-	0x6134, 0x918c, 0x00ff, 0x9105, 0x6036, 0x6007, 0x0085, 0x6003,
-	0x000b, 0x6023, 0x0002, 0x603c, 0x600a, 0x2001, 0x1986, 0x2004,
-	0x601a, 0x602c, 0x2c08, 0x2060, 0x6024, 0xd0b4, 0x0108, 0xc085,
-	0xc0b5, 0x6026, 0x2160, 0x080c, 0x91b1, 0x080c, 0x9763, 0x0005,
-	0x00de, 0x00ce, 0x080c, 0xb905, 0x080c, 0x321e, 0x00e6, 0x0126,
-	0x2091, 0x8000, 0x080c, 0x3247, 0x6017, 0x0000, 0x6023, 0x0007,
-	0x601b, 0x0398, 0x6043, 0x0000, 0x012e, 0x00ee, 0x0005, 0x080c,
-	0xb374, 0x1904, 0xcb74, 0x0005, 0x6000, 0x908a, 0x0016, 0x1a0c,
-	0x0dd5, 0x0096, 0x00d6, 0x001b, 0x00de, 0x009e, 0x0005, 0xcbdf,
-	0xcbdf, 0xcbdf, 0xcbdf, 0xcbdf, 0xcbdf, 0xcbdf, 0xcbdf, 0xcbdf,
-	0xc98f, 0xcbdf, 0xc996, 0xcbe1, 0xc996, 0xcbfb, 0xcbdf, 0x080c,
-	0x0dd5, 0x6004, 0x9086, 0x008b, 0x01b0, 0x6034, 0x908c, 0xff00,
-	0x810f, 0x9186, 0x0035, 0x1130, 0x602c, 0x9080, 0x0009, 0x200c,
-	0xc185, 0x2102, 0x6007, 0x008b, 0x6003, 0x000d, 0x080c, 0x91b1,
-	0x080c, 0x9763, 0x0005, 0x080c, 0xd37c, 0x0118, 0x080c, 0xd38f,
-	0x0010, 0x080c, 0xd39d, 0x080c, 0xce71, 0x080c, 0xcc86, 0x0570,
-	0x080c, 0x321e, 0x080c, 0xcc86, 0x0168, 0x6014, 0x2048, 0xa867,
-	0x0103, 0xa87b, 0x0006, 0xa877, 0x0000, 0xa880, 0xc0ed, 0xa882,
-	0x080c, 0x6d17, 0x2c68, 0x080c, 0xaeed, 0x0150, 0x6810, 0x6012,
-	0x080c, 0xd102, 0x00c6, 0x2d60, 0x080c, 0xaf74, 0x00ce, 0x0008,
-	0x2d60, 0x6017, 0x0000, 0x6023, 0x0001, 0x6007, 0x0001, 0x6003,
-	0x0001, 0x080c, 0x91f9, 0x080c, 0x9763, 0x00c8, 0x080c, 0xd37c,
-	0x0138, 0x6034, 0x9086, 0x4000, 0x1118, 0x080c, 0x321e, 0x08d0,
-	0x6034, 0x908c, 0xff00, 0x810f, 0x9186, 0x0039, 0x0118, 0x9186,
-	0x0035, 0x1118, 0x080c, 0x321e, 0x0868, 0x080c, 0xaf74, 0x0005,
-	0x6000, 0x908a, 0x0016, 0x1a0c, 0x0dd5, 0x0002, 0xcc66, 0xcc66,
-	0xcc68, 0xcc68, 0xcc68, 0xcc66, 0xcc66, 0xaf74, 0xcc66, 0xcc66,
-	0xcc66, 0xcc66, 0xcc66, 0xcc66, 0xcc66, 0xcc66, 0x080c, 0x0dd5,
-	0x080c, 0xa89b, 0x6114, 0x0096, 0x2148, 0xa87b, 0x0006, 0x080c,
-	0x6d17, 0x009e, 0x0804, 0xaf43, 0x9284, 0x0007, 0x1158, 0x9282,
-	0x1cd0, 0x0240, 0x2001, 0x181a, 0x2004, 0x9202, 0x1218, 0x9085,
-	0x0001, 0x0005, 0x9006, 0x0ce8, 0x0096, 0x0028, 0x0096, 0x0006,
-	0x6014, 0x2048, 0x000e, 0x0006, 0x9984, 0xf000, 0x9086, 0xf000,
-	0x0110, 0x080c, 0x10aa, 0x000e, 0x009e, 0x0005, 0x00e6, 0x00c6,
-	0x0036, 0x0006, 0x0126, 0x2091, 0x8000, 0x2061, 0x1cd0, 0x2071,
-	0x1800, 0x7354, 0x7074, 0x9302, 0x1640, 0x6020, 0x9206, 0x11f8,
-	0x080c, 0xd388, 0x0180, 0x9286, 0x0001, 0x1168, 0x6004, 0x9086,
-	0x0004, 0x1148, 0x080c, 0x321e, 0x080c, 0xd39d, 0x00c6, 0x080c,
-	0xaf74, 0x00ce, 0x0060, 0x080c, 0xd07c, 0x0148, 0x080c, 0xce8e,
-	0x1110, 0x080c, 0xb905, 0x00c6, 0x080c, 0xaf43, 0x00ce, 0x9ce0,
-	0x0018, 0x7068, 0x9c02, 0x1208, 0x08a0, 0x012e, 0x000e, 0x003e,
-	0x00ce, 0x00ee, 0x0005, 0x00e6, 0x00c6, 0x0016, 0x9188, 0x1000,
-	0x210c, 0x81ff, 0x0128, 0x2061, 0x1ab2, 0x6112, 0x080c, 0x321e,
-	0x9006, 0x0010, 0x9085, 0x0001, 0x001e, 0x00ce, 0x00ee, 0x0005,
-	0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xaeed, 0x01b0, 0x6656,
-	0x2b00, 0x6012, 0x080c, 0x5765, 0x0118, 0x080c, 0xcdb5, 0x0168,
-	0x080c, 0xd102, 0x6023, 0x0003, 0x2009, 0x004b, 0x080c, 0xafbe,
-	0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x00c6,
-	0x0126, 0x2091, 0x8000, 0xbaa0, 0x080c, 0xaf91, 0x0560, 0x6057,
-	0x0000, 0x2b00, 0x6012, 0x080c, 0xd102, 0x6023, 0x0003, 0x0016,
-	0x080c, 0x9356, 0x0076, 0x903e, 0x080c, 0x9229, 0x2c08, 0x080c,
-	0xe477, 0x007e, 0x001e, 0xd184, 0x0128, 0x080c, 0xaf43, 0x9085,
-	0x0001, 0x0070, 0x080c, 0x5765, 0x0128, 0xd18c, 0x1170, 0x080c,
-	0xcdb5, 0x0148, 0x2009, 0x004c, 0x080c, 0xafbe, 0x9085, 0x0001,
-	0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x2900, 0x6016, 0x0c90,
-	0x2009, 0x004d, 0x0010, 0x2009, 0x004e, 0x00f6, 0x00c6, 0x0046,
-	0x0016, 0x080c, 0xaeed, 0x2c78, 0x05a0, 0x7e56, 0x2b00, 0x7812,
-	0x7823, 0x0003, 0x0016, 0x2021, 0x0005, 0x080c, 0xcdc7, 0x001e,
-	0x9186, 0x004d, 0x0118, 0x9186, 0x004e, 0x0148, 0x2001, 0x197f,
-	0x200c, 0xd1fc, 0x0168, 0x2f60, 0x080c, 0xaf43, 0x00d0, 0x2001,
-	0x197e, 0x200c, 0xd1fc, 0x0120, 0x2f60, 0x080c, 0xaf43, 0x0088,
-	0x2f60, 0x080c, 0x5765, 0x0138, 0xd18c, 0x1118, 0x04f1, 0x0148,
-	0x0010, 0x2900, 0x7816, 0x001e, 0x0016, 0x080c, 0xafbe, 0x9085,
-	0x0001, 0x001e, 0x004e, 0x00ce, 0x00fe, 0x0005, 0x00f6, 0x00c6,
-	0x0046, 0x080c, 0xaeed, 0x2c78, 0x0508, 0x7e56, 0x2b00, 0x7812,
-	0x7823, 0x0003, 0x0096, 0x2021, 0x0004, 0x0489, 0x009e, 0x2001,
-	0x197d, 0x200c, 0xd1fc, 0x0120, 0x2f60, 0x080c, 0xaf43, 0x0060,
-	0x2f60, 0x080c, 0x5765, 0x0120, 0xd18c, 0x1160, 0x0071, 0x0130,
-	0x2009, 0x0052, 0x080c, 0xafbe, 0x9085, 0x0001, 0x004e, 0x00ce,
-	0x00fe, 0x0005, 0x2900, 0x7816, 0x0c98, 0x00c6, 0x080c, 0x4b1f,
-	0x00ce, 0x1120, 0x080c, 0xaf43, 0x9006, 0x0005, 0xa867, 0x0000,
-	0xa86b, 0x8000, 0x2900, 0x6016, 0x9085, 0x0001, 0x0005, 0x0096,
-	0x0076, 0x0126, 0x2091, 0x8000, 0x080c, 0x67cd, 0x0158, 0x2001,
-	0xcdcc, 0x0006, 0x900e, 0x2400, 0x080c, 0x6f4a, 0x080c, 0x6d17,
-	0x000e, 0x0807, 0x2418, 0x080c, 0x95f1, 0xbaa0, 0x0086, 0x2041,
-	0x0001, 0x2039, 0x0001, 0x2608, 0x080c, 0x936e, 0x008e, 0x080c,
-	0x9229, 0x2f08, 0x2648, 0x080c, 0xe477, 0xb93c, 0x81ff, 0x090c,
-	0x9441, 0x080c, 0x9763, 0x012e, 0x007e, 0x009e, 0x0005, 0x00c6,
-	0x0126, 0x2091, 0x8000, 0x080c, 0xaeed, 0x0190, 0x660a, 0x2b08,
-	0x6112, 0x080c, 0xd102, 0x6023, 0x0001, 0x2900, 0x6016, 0x2009,
-	0x001f, 0x080c, 0xafbe, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005,
-	0x9006, 0x0cd8, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xaf91,
-	0x01b8, 0x660a, 0x2b08, 0x6112, 0x080c, 0xd102, 0x6023, 0x0008,
-	0x2900, 0x6016, 0x00f6, 0x2c78, 0x080c, 0x1754, 0x00fe, 0x2009,
-	0x0021, 0x080c, 0xafbe, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005,
-	0x9006, 0x0cd8, 0x2009, 0x003d, 0x00c6, 0x0126, 0x0016, 0x2091,
-	0x8000, 0x080c, 0xaeed, 0x0198, 0x660a, 0x2b08, 0x6112, 0x080c,
-	0xd102, 0x6023, 0x0001, 0x2900, 0x6016, 0x001e, 0x0016, 0x080c,
-	0xafbe, 0x9085, 0x0001, 0x001e, 0x012e, 0x00ce, 0x0005, 0x9006,
-	0x0cd0, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xaf91, 0x0188,
-	0x2b08, 0x6112, 0x080c, 0xd102, 0x6023, 0x0001, 0x2900, 0x6016,
-	0x2009, 0x0000, 0x080c, 0xafbe, 0x9085, 0x0001, 0x012e, 0x00ce,
-	0x0005, 0x9006, 0x0cd8, 0x2009, 0x0044, 0x0830, 0x2009, 0x0049,
-	0x0818, 0x0026, 0x00b6, 0x6210, 0x2258, 0xba3c, 0x82ff, 0x0110,
-	0x8211, 0xba3e, 0x00be, 0x002e, 0x0005, 0x0006, 0x0016, 0x6004,
-	0x908e, 0x0002, 0x0140, 0x908e, 0x0003, 0x0128, 0x908e, 0x0004,
-	0x0110, 0x9085, 0x0001, 0x001e, 0x000e, 0x0005, 0x0006, 0x0086,
-	0x0096, 0x6020, 0x9086, 0x0004, 0x01a8, 0x6014, 0x904d, 0x080c,
-	0xcc86, 0x0180, 0xa864, 0x9086, 0x0139, 0x0170, 0x6020, 0x90c6,
-	0x0003, 0x0140, 0x90c6, 0x0002, 0x0128, 0xa868, 0xd0fc, 0x0110,
-	0x9006, 0x0010, 0x9085, 0x0001, 0x009e, 0x008e, 0x000e, 0x0005,
-	0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xaf91, 0x0198, 0x2b08,
-	0x6112, 0x080c, 0xd102, 0x6023, 0x0001, 0x2900, 0x6016, 0x080c,
-	0x321e, 0x2009, 0x0028, 0x080c, 0xafbe, 0x9085, 0x0001, 0x012e,
-	0x00ce, 0x0005, 0x9006, 0x0cd8, 0x9186, 0x0015, 0x11a8, 0x2011,
-	0x1824, 0x2204, 0x9086, 0x0074, 0x1178, 0x00b6, 0x080c, 0xbb59,
-	0x00be, 0x080c, 0xbd7c, 0x6003, 0x0001, 0x6007, 0x0029, 0x080c,
-	0x91f9, 0x080c, 0x9763, 0x0078, 0x6014, 0x0096, 0x2048, 0xa868,
-	0x009e, 0xd0fc, 0x0148, 0x2001, 0x0001, 0x080c, 0xd2c1, 0x080c,
-	0xb905, 0x080c, 0xaf43, 0x0005, 0x0096, 0x6014, 0x904d, 0x090c,
-	0x0dd5, 0xa87b, 0x0030, 0xa883, 0x0000, 0xa897, 0x4005, 0xa89b,
-	0x0004, 0xa867, 0x0139, 0x0126, 0x2091, 0x8000, 0x080c, 0x6d17,
-	0x012e, 0x009e, 0x080c, 0xaf43, 0x0c30, 0x0096, 0x9186, 0x0016,
-	0x1128, 0x2001, 0x0004, 0x080c, 0x65e9, 0x00e8, 0x9186, 0x0015,
-	0x1510, 0x2011, 0x1824, 0x2204, 0x9086, 0x0014, 0x11e0, 0x6010,
-	0x00b6, 0x2058, 0x080c, 0x6734, 0x00be, 0x080c, 0xbe4d, 0x1198,
-	0x6010, 0x00b6, 0x2058, 0xb890, 0x00be, 0x9005, 0x0160, 0x2001,
-	0x0006, 0x080c, 0x65e9, 0x6014, 0x2048, 0xa868, 0xd0fc, 0x0170,
-	0x080c, 0xb348, 0x0048, 0x6014, 0x2048, 0xa868, 0xd0fc, 0x0528,
-	0x080c, 0xb905, 0x080c, 0xaf43, 0x009e, 0x0005, 0x6014, 0x6310,
-	0x2358, 0x904d, 0x090c, 0x0dd5, 0xa87b, 0x0000, 0xa883, 0x0000,
-	0xa897, 0x4000, 0x900e, 0x080c, 0x68b9, 0x1108, 0xc185, 0xb800,
-	0xd0bc, 0x0108, 0xc18d, 0xa99a, 0x0126, 0x2091, 0x8000, 0x080c,
-	0x6d17, 0x012e, 0x080c, 0xaf43, 0x08f8, 0x6014, 0x904d, 0x090c,
-	0x0dd5, 0xa87b, 0x0030, 0xa883, 0x0000, 0xa897, 0x4005, 0xa89b,
-	0x0004, 0xa867, 0x0139, 0x0126, 0x2091, 0x8000, 0x080c, 0x6d17,
-	0x012e, 0x080c, 0xaf43, 0x0840, 0xa878, 0x9086, 0x0005, 0x1108,
-	0x0009, 0x0005, 0xa880, 0xc0ad, 0xa882, 0x0005, 0x6043, 0x0000,
-	0x6017, 0x0000, 0x6003, 0x0001, 0x6007, 0x0050, 0x080c, 0x91b1,
-	0x080c, 0x9763, 0x0005, 0x00c6, 0x6010, 0x00b6, 0x2058, 0xb800,
-	0x00be, 0xd0bc, 0x0120, 0x6020, 0x9084, 0x000f, 0x0013, 0x00ce,
-	0x0005, 0xc98f, 0xcfb2, 0xcfb2, 0xcfb5, 0xe789, 0xe7a4, 0xe7a7,
-	0xc98f, 0xc98f, 0xc98f, 0xc98f, 0xc98f, 0xc98f, 0xc98f, 0xc98f,
-	0x080c, 0x0dd5, 0xa001, 0xa001, 0x0005, 0x0096, 0x6014, 0x904d,
-	0x0118, 0xa87c, 0xd0e4, 0x1110, 0x009e, 0x0010, 0x009e, 0x0005,
-	0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x0550, 0x2001,
-	0x1834, 0x2004, 0x9005, 0x1540, 0x00f6, 0x2c78, 0x080c, 0xaeed,
-	0x0508, 0x7810, 0x6012, 0x080c, 0xd102, 0x7820, 0x9086, 0x0003,
-	0x0128, 0x7808, 0x603a, 0x2f00, 0x603e, 0x0020, 0x7808, 0x603e,
-	0x2f00, 0x603a, 0x602e, 0x6023, 0x0001, 0x6007, 0x0035, 0x6003,
-	0x0001, 0x7954, 0x6156, 0x080c, 0x91b1, 0x080c, 0x9763, 0x2f60,
-	0x00fe, 0x0005, 0x2f60, 0x00fe, 0x2001, 0x1987, 0x2004, 0x6042,
-	0x0005, 0x0016, 0x0096, 0x6814, 0x2048, 0xa87c, 0xd0e4, 0x0180,
-	0xc0e4, 0xa87e, 0xa877, 0x0000, 0xa893, 0x0000, 0xa88f, 0x0000,
-	0xd0cc, 0x0130, 0xc0cc, 0xa87e, 0xa878, 0x2048, 0x080c, 0x0fb1,
-	0x6830, 0x6036, 0x908e, 0x0001, 0x0148, 0x6803, 0x0002, 0x9086,
-	0x0005, 0x0170, 0x9006, 0x602e, 0x6032, 0x00d0, 0x681c, 0xc085,
-	0x681e, 0x6803, 0x0004, 0x6824, 0xc0f4, 0x9085, 0x0c00, 0x6826,
-	0x6814, 0x2048, 0xa8ac, 0x6938, 0x9102, 0xa8b0, 0x693c, 0x9103,
-	0x1e48, 0x683c, 0x602e, 0x6838, 0x9084, 0xfffc, 0x683a, 0x6032,
-	0x2d00, 0x603a, 0x6808, 0x603e, 0x6910, 0x6112, 0x6954, 0x6156,
-	0x6023, 0x0001, 0x6007, 0x0039, 0x6003, 0x0001, 0x080c, 0x91b1,
-	0x080c, 0x9763, 0x009e, 0x001e, 0x0005, 0x6024, 0xd0d4, 0x0510,
-	0xd0f4, 0x11f8, 0x6038, 0x940a, 0x603c, 0x9303, 0x0230, 0x9105,
-	0x0120, 0x6024, 0xc0d4, 0xc0f5, 0x0098, 0x643a, 0x633e, 0xac3e,
-	0xab42, 0x0046, 0x0036, 0x2400, 0xacac, 0x9402, 0xa836, 0x2300,
-	0xabb0, 0x9303, 0xa83a, 0x003e, 0x004e, 0x6024, 0xc0d4, 0x0000,
-	0x6026, 0x0005, 0xd0f4, 0x1138, 0xa83c, 0x603a, 0xa840, 0x603e,
-	0x6024, 0xc0f5, 0x6026, 0x0005, 0x0006, 0x0016, 0x6004, 0x908e,
-	0x0034, 0x01b8, 0x908e, 0x0035, 0x01a0, 0x908e, 0x0036, 0x0188,
-	0x908e, 0x0037, 0x0170, 0x908e, 0x0038, 0x0158, 0x908e, 0x0039,
-	0x0140, 0x908e, 0x003a, 0x0128, 0x908e, 0x003b, 0x0110, 0x9085,
-	0x0001, 0x001e, 0x000e, 0x0005, 0x0006, 0x0016, 0x0026, 0x0036,
-	0x00e6, 0x2001, 0x1981, 0x200c, 0x8000, 0x2014, 0x2001, 0x0032,
-	0x080c, 0x9027, 0x2001, 0x1985, 0x82ff, 0x1110, 0x2011, 0x0014,
-	0x2202, 0x2001, 0x1983, 0x200c, 0x8000, 0x2014, 0x2071, 0x196b,
-	0x711a, 0x721e, 0x2001, 0x0064, 0x080c, 0x9027, 0x2001, 0x1986,
-	0x82ff, 0x1110, 0x2011, 0x0014, 0x2202, 0x2001, 0x1987, 0x9288,
-	0x000a, 0x2102, 0x2001, 0x1a93, 0x2102, 0x2001, 0x0032, 0x080c,
-	0x15fd, 0x080c, 0x69ed, 0x00ee, 0x003e, 0x002e, 0x001e, 0x000e,
-	0x0005, 0x0006, 0x0016, 0x00e6, 0x2001, 0x1985, 0x2003, 0x0028,
-	0x2001, 0x1986, 0x2003, 0x0014, 0x2071, 0x196b, 0x701b, 0x0000,
-	0x701f, 0x07d0, 0x2001, 0x1987, 0x2009, 0x001e, 0x2102, 0x2001,
-	0x1a93, 0x2102, 0x2001, 0x0032, 0x080c, 0x15fd, 0x00ee, 0x001e,
-	0x000e, 0x0005, 0x0096, 0x6058, 0x904d, 0x0110, 0x080c, 0x1031,
-	0x009e, 0x0005, 0x0005, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c,
-	0xaeed, 0x0180, 0x2b08, 0x6112, 0x0ca9, 0x6023, 0x0001, 0x2900,
-	0x6016, 0x2009, 0x0033, 0x080c, 0xafbe, 0x9085, 0x0001, 0x012e,
-	0x00ce, 0x0005, 0x9006, 0x0cd8, 0x0096, 0x00e6, 0x00f6, 0x2071,
-	0x1800, 0x9186, 0x0015, 0x1500, 0x7090, 0x9086, 0x0018, 0x11e0,
-	0x6014, 0x2048, 0xaa3c, 0xd2e4, 0x1160, 0x2c78, 0x080c, 0x99f9,
-	0x01d8, 0x707c, 0xaa50, 0x9206, 0x1160, 0x7080, 0xaa54, 0x9206,
-	0x1140, 0x6210, 0x00b6, 0x2258, 0xbaa0, 0x00be, 0x900e, 0x080c,
-	0x3267, 0x080c, 0xb348, 0x0020, 0x080c, 0xb905, 0x080c, 0xaf43,
-	0x00fe, 0x00ee, 0x009e, 0x0005, 0x7060, 0xaa54, 0x9206, 0x0d48,
-	0x0c80, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xaeed, 0x0188,
-	0x2b08, 0x6112, 0x080c, 0xd102, 0x6023, 0x0001, 0x2900, 0x6016,
-	0x2009, 0x004d, 0x080c, 0xafbe, 0x9085, 0x0001, 0x012e, 0x00ce,
-	0x0005, 0x9006, 0x0cd8, 0x00c6, 0x0126, 0x2091, 0x8000, 0x0016,
-	0x080c, 0xaeed, 0x0180, 0x2b08, 0x6112, 0x080c, 0xd102, 0x6023,
-	0x0001, 0x2900, 0x6016, 0x001e, 0x080c, 0xafbe, 0x9085, 0x0001,
-	0x012e, 0x00ce, 0x0005, 0x001e, 0x9006, 0x0cd0, 0x0016, 0x0026,
-	0x0036, 0x0046, 0x0056, 0x0066, 0x0096, 0x00e6, 0x00f6, 0x2071,
-	0x1800, 0x9186, 0x0015, 0x1568, 0x7190, 0x6014, 0x2048, 0xa814,
-	0x8003, 0x9106, 0x1530, 0x20e1, 0x0000, 0x2001, 0x199f, 0x2003,
-	0x0000, 0x6014, 0x2048, 0xa830, 0x20a8, 0x8906, 0x8006, 0x8007,
-	0x9094, 0x003f, 0x22e8, 0x9084, 0xffc0, 0x9080, 0x001b, 0x20a0,
-	0x2001, 0x199f, 0x0016, 0x200c, 0x080c, 0xd99b, 0x001e, 0xa804,
-	0x9005, 0x0110, 0x2048, 0x0c38, 0x6014, 0x2048, 0xa867, 0x0103,
-	0x0010, 0x080c, 0xb905, 0x080c, 0xaf43, 0x00fe, 0x00ee, 0x009e,
-	0x006e, 0x005e, 0x004e, 0x003e, 0x002e, 0x001e, 0x0005, 0x0096,
-	0x00e6, 0x00f6, 0x2071, 0x1800, 0x9186, 0x0015, 0x11b8, 0x7090,
-	0x9086, 0x0004, 0x1198, 0x6014, 0x2048, 0x2c78, 0x080c, 0x99f9,
-	0x01a8, 0x707c, 0xaa74, 0x9206, 0x1130, 0x7080, 0xaa78, 0x9206,
-	0x1110, 0x080c, 0x321e, 0x080c, 0xb348, 0x0020, 0x080c, 0xb905,
-	0x080c, 0xaf43, 0x00fe, 0x00ee, 0x009e, 0x0005, 0x7060, 0xaa78,
-	0x9206, 0x0d78, 0x0c80, 0x0096, 0x00e6, 0x00f6, 0x2071, 0x1800,
-	0x9186, 0x0015, 0x1550, 0x7090, 0x9086, 0x0004, 0x1530, 0x6014,
-	0x2048, 0x2c78, 0x080c, 0x99f9, 0x05f0, 0x707c, 0xaacc, 0x9206,
-	0x1180, 0x7080, 0xaad0, 0x9206, 0x1160, 0x080c, 0x321e, 0x0016,
-	0xa998, 0xaab0, 0x9284, 0x1000, 0xc0fd, 0x080c, 0x570c, 0x001e,
-	0x0010, 0x080c, 0x54f7, 0x080c, 0xcc86, 0x0508, 0xa87b, 0x0000,
-	0xa883, 0x0000, 0xa897, 0x4000, 0x0080, 0x080c, 0xcc86, 0x01b8,
-	0x6014, 0x2048, 0x080c, 0x54f7, 0x1d70, 0xa87b, 0x0030, 0xa883,
-	0x0000, 0xa897, 0x4005, 0xa89b, 0x0004, 0x0126, 0x2091, 0x8000,
-	0xa867, 0x0139, 0x080c, 0x6d17, 0x012e, 0x080c, 0xaf43, 0x00fe,
-	0x00ee, 0x009e, 0x0005, 0x7060, 0xaad0, 0x9206, 0x0930, 0x0888,
-	0x0016, 0x0026, 0xa87c, 0xd0ac, 0x0178, 0xa938, 0xaa34, 0x2100,
-	0x9205, 0x0150, 0xa890, 0x9106, 0x1118, 0xa88c, 0x9206, 0x0120,
-	0xa992, 0xaa8e, 0x9085, 0x0001, 0x002e, 0x001e, 0x0005, 0x00b6,
-	0x00d6, 0x0036, 0x080c, 0xcc86, 0x0904, 0xd2bd, 0x0096, 0x6314,
-	0x2348, 0xa87a, 0xa982, 0x929e, 0x4000, 0x1580, 0x6310, 0x00c6,
-	0x2358, 0x2009, 0x0000, 0xa868, 0xd0f4, 0x1140, 0x080c, 0x68b9,
-	0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0xaa96, 0xa99a,
-	0x20a9, 0x0004, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0031, 0x20a0,
-	0xb8c4, 0x20e0, 0xb8c8, 0x9080, 0x0006, 0x2098, 0x080c, 0x0f7c,
-	0x20a9, 0x0004, 0xa85c, 0x9080, 0x0035, 0x20a0, 0xb8c8, 0x9080,
-	0x000a, 0x2098, 0x080c, 0x0f7c, 0x00ce, 0x0090, 0xaa96, 0x3918,
-	0x9398, 0x0007, 0x231c, 0x6004, 0x9086, 0x0016, 0x0110, 0xa89b,
-	0x0004, 0xaba2, 0x6310, 0x2358, 0xb804, 0x9084, 0x00ff, 0xa89e,
-	0x080c, 0x6d0b, 0x6017, 0x0000, 0x009e, 0x003e, 0x00de, 0x00be,
+	0x0300, 0x0904, 0xc5ca, 0x9686, 0x0100, 0x1130, 0x7064, 0x9005,
+	0x1118, 0xc6c4, 0xb676, 0x0c38, 0x080c, 0x100e, 0x090c, 0x0dc5,
+	0x2900, 0xb07a, 0xb77c, 0x97bd, 0x0200, 0xb77e, 0xa867, 0x0103,
+	0xb068, 0xa86a, 0xb06c, 0xa86e, 0xb070, 0xa872, 0x7044, 0x9084,
+	0xf000, 0x9635, 0xae76, 0x968c, 0x0c00, 0x0120, 0x7348, 0xab92,
+	0x734c, 0xab8e, 0x968c, 0x00ff, 0x9186, 0x0002, 0x0180, 0x9186,
+	0x0028, 0x1118, 0xa87b, 0x001c, 0x0060, 0xd6dc, 0x0118, 0xa87b,
+	0x0015, 0x0038, 0xd6d4, 0x0118, 0xa87b, 0x0007, 0x0010, 0xa87b,
+	0x0000, 0xaf7e, 0xb080, 0xa882, 0xb084, 0xa886, 0x901e, 0xd6c4,
+	0x0190, 0x735c, 0xab86, 0x83ff, 0x0170, 0x938a, 0x0009, 0x0210,
+	0x2019, 0x0008, 0x0036, 0x2308, 0x2019, 0x0018, 0x2011, 0x0025,
+	0x080c, 0xc9f0, 0x003e, 0xd6cc, 0x01e8, 0x7154, 0xa98a, 0x81ff,
+	0x01c8, 0x9192, 0x0021, 0x1260, 0x8304, 0x9098, 0x0018, 0x2011,
+	0x0029, 0x080c, 0xc9f0, 0x2011, 0x0205, 0x2013, 0x0000, 0x0050,
+	0xb068, 0xd0fc, 0x0120, 0x2009, 0x0020, 0xa98a, 0x0c68, 0x2950,
+	0x080c, 0xc98f, 0x080c, 0x1a83, 0x009e, 0x00ee, 0x00ae, 0x007e,
+	0x0005, 0x2001, 0x1989, 0x2004, 0x6042, 0x0096, 0x6114, 0x2148,
+	0xa83c, 0xa940, 0x9105, 0x1118, 0xa87c, 0xc0dc, 0xa87e, 0x6003,
+	0x0002, 0xa97c, 0xd1e4, 0x0904, 0xc6fe, 0x6043, 0x0000, 0x6010,
+	0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x1500, 0xd1cc, 0x0904,
+	0xc6cd, 0xa978, 0xa868, 0xd0fc, 0x0904, 0xc68e, 0x0016, 0xa87c,
+	0x0006, 0xa880, 0x0006, 0x00a6, 0x2150, 0xb174, 0x9184, 0x00ff,
+	0x90b6, 0x0002, 0x0904, 0xc65b, 0x9086, 0x0028, 0x1904, 0xc647,
+	0xa87b, 0x001c, 0xb07b, 0x001c, 0x0804, 0xc663, 0x6024, 0xd0f4,
+	0x11d0, 0xa838, 0xaa34, 0x9205, 0x09c8, 0xa838, 0xaa90, 0x9206,
+	0x1120, 0xa88c, 0xaa34, 0x9206, 0x0988, 0x6024, 0xd0d4, 0x1148,
+	0xa9ac, 0xa834, 0x9102, 0x603a, 0xa9b0, 0xa838, 0x9103, 0x603e,
+	0x6024, 0xc0f5, 0x6026, 0x6010, 0x00b6, 0x2058, 0xb83c, 0x8000,
+	0xb83e, 0x00be, 0x9006, 0xa876, 0xa892, 0xa88e, 0xa87c, 0xc0e4,
+	0xa87e, 0xd0cc, 0x0140, 0xc0cc, 0xa87e, 0x0096, 0xa878, 0x2048,
+	0x080c, 0x0fc0, 0x009e, 0x080c, 0xd179, 0x0804, 0xc6fe, 0xd1dc,
+	0x0158, 0xa87b, 0x0015, 0xb07b, 0x0015, 0x080c, 0xd40d, 0x0118,
+	0xb174, 0xc1dc, 0xb176, 0x0078, 0xd1d4, 0x0128, 0xa87b, 0x0007,
+	0xb07b, 0x0007, 0x0040, 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938,
+	0x9115, 0x190c, 0xc4f6, 0xa87c, 0xb07e, 0xa890, 0xb092, 0xa88c,
+	0xb08e, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0019, 0x20a0, 0x20a9,
+	0x0020, 0x8a06, 0x8006, 0x8007, 0x9094, 0x003f, 0x22e0, 0x9084,
+	0xffc0, 0x9080, 0x0019, 0x2098, 0x4003, 0x00ae, 0x000e, 0xa882,
+	0x000e, 0xc0cc, 0xa87e, 0x080c, 0xd4ed, 0x001e, 0xa874, 0x0006,
+	0x2148, 0x080c, 0x0fc0, 0x001e, 0x0804, 0xc6fa, 0x0016, 0x00a6,
+	0x2150, 0xb174, 0x9184, 0x00ff, 0x90b6, 0x0002, 0x01e0, 0x9086,
+	0x0028, 0x1128, 0xa87b, 0x001c, 0xb07b, 0x001c, 0x00e0, 0xd1dc,
+	0x0158, 0xa87b, 0x0015, 0xb07b, 0x0015, 0x080c, 0xd40d, 0x0118,
+	0xb174, 0xc1dc, 0xb176, 0x0078, 0xd1d4, 0x0128, 0xa87b, 0x0007,
+	0xb07b, 0x0007, 0x0040, 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938,
+	0x9115, 0x190c, 0xc4f6, 0xa890, 0xb092, 0xa88c, 0xb08e, 0xa87c,
+	0xb07e, 0x00ae, 0x080c, 0x0fc0, 0x009e, 0x080c, 0xd4ed, 0xa974,
+	0x0016, 0x080c, 0xc9e0, 0x001e, 0x0468, 0xa867, 0x0103, 0xa974,
+	0x9184, 0x00ff, 0x90b6, 0x0002, 0x01b0, 0x9086, 0x0028, 0x1118,
+	0xa87b, 0x001c, 0x00d0, 0xd1dc, 0x0148, 0xa87b, 0x0015, 0x080c,
+	0xd40d, 0x0118, 0xa974, 0xc1dc, 0xa976, 0x0078, 0xd1d4, 0x0118,
+	0xa87b, 0x0007, 0x0050, 0xa87b, 0x0000, 0xa87c, 0xd0ac, 0x0128,
+	0xa834, 0xa938, 0x9115, 0x190c, 0xc4f6, 0xa974, 0x0016, 0x080c,
+	0x6be5, 0x001e, 0xd1e4, 0x1120, 0x080c, 0xb0e7, 0x009e, 0x0005,
+	0x080c, 0xd13f, 0x0cd8, 0x6114, 0x0096, 0x2148, 0xa97c, 0xd1e4,
+	0x190c, 0x1aa3, 0x009e, 0x0005, 0x080c, 0x97db, 0x0010, 0x080c,
+	0x9897, 0x080c, 0xce3f, 0x01f0, 0x0096, 0x6114, 0x2148, 0x080c,
+	0xd047, 0x1118, 0x080c, 0xbacb, 0x00a0, 0xa867, 0x0103, 0x2009,
+	0x180c, 0x210c, 0xd18c, 0x11b8, 0xd184, 0x1190, 0x6108, 0xa97a,
+	0x918e, 0x0029, 0x1110, 0x080c, 0xec9b, 0xa877, 0x0000, 0x080c,
+	0x6dcb, 0x009e, 0x080c, 0xb0e7, 0x080c, 0x98e7, 0x0804, 0x9a09,
+	0xa87b, 0x0004, 0x0c90, 0xa87b, 0x0004, 0x0c78, 0x9182, 0x0054,
+	0x1220, 0x9182, 0x0040, 0x0208, 0x000a, 0x0005, 0xc75a, 0xc75a,
+	0xc75a, 0xc75a, 0xc75a, 0xc75c, 0xc75a, 0xc75a, 0xc75a, 0xc75a,
+	0xc75a, 0xc75a, 0xc75a, 0xc75a, 0xc75a, 0xc75a, 0xc75a, 0xc75a,
+	0xc75a, 0xc75a, 0x080c, 0x0dc5, 0x080c, 0x57d5, 0x01f8, 0x6014,
+	0x7144, 0x918c, 0x0fff, 0x9016, 0xd1c4, 0x0118, 0x7264, 0x9294,
+	0x00ff, 0x0096, 0x904d, 0x0188, 0xa87b, 0x0000, 0xa864, 0x9086,
+	0x0139, 0x0128, 0xa867, 0x0103, 0xa976, 0xaa96, 0x0030, 0xa897,
+	0x4000, 0xa99a, 0xaa9e, 0x080c, 0x6dcb, 0x009e, 0x0804, 0xb0e7,
+	0x9182, 0x0085, 0x0002, 0xc792, 0xc790, 0xc790, 0xc79e, 0xc790,
+	0xc790, 0xc790, 0xc790, 0xc790, 0xc790, 0xc790, 0xc790, 0xc790,
+	0x080c, 0x0dc5, 0x6003, 0x0001, 0x6106, 0x080c, 0x9335, 0x0126,
+	0x2091, 0x8000, 0x080c, 0x98e7, 0x012e, 0x0005, 0x0026, 0x0056,
+	0x00d6, 0x00e6, 0x2071, 0x0260, 0x7224, 0x6216, 0x7220, 0x080c,
+	0xce2d, 0x01f8, 0x2268, 0x6800, 0x9086, 0x0000, 0x01d0, 0x6010,
+	0x6d10, 0x952e, 0x11b0, 0x00c6, 0x2d60, 0x00d6, 0x080c, 0xca51,
+	0x00de, 0x00ce, 0x0158, 0x702c, 0xd084, 0x1118, 0x080c, 0xca1b,
+	0x0010, 0x6803, 0x0002, 0x6007, 0x0086, 0x0028, 0x080c, 0xca3d,
+	0x0d90, 0x6007, 0x0087, 0x6003, 0x0001, 0x080c, 0x9335, 0x080c,
+	0x98e7, 0x7220, 0x080c, 0xce2d, 0x0178, 0x6810, 0x00b6, 0x2058,
+	0xb800, 0x00be, 0xd0bc, 0x0140, 0x6824, 0xd0ec, 0x0128, 0x00c6,
+	0x2d60, 0x080c, 0xd179, 0x00ce, 0x00ee, 0x00de, 0x005e, 0x002e,
+	0x0005, 0x9186, 0x0013, 0x1160, 0x6004, 0x908a, 0x0085, 0x0a0c,
+	0x0dc5, 0x908a, 0x0092, 0x1a0c, 0x0dc5, 0x9082, 0x0085, 0x00e2,
+	0x9186, 0x0027, 0x0120, 0x9186, 0x0014, 0x190c, 0x0dc5, 0x080c,
+	0x97db, 0x0096, 0x6014, 0x2048, 0x080c, 0xce3f, 0x0140, 0xa867,
+	0x0103, 0xa877, 0x0000, 0xa87b, 0x0029, 0x080c, 0x6dcb, 0x009e,
+	0x080c, 0xb11a, 0x0804, 0x98e7, 0xc821, 0xc823, 0xc823, 0xc821,
+	0xc821, 0xc821, 0xc821, 0xc821, 0xc821, 0xc821, 0xc821, 0xc821,
+	0xc821, 0x080c, 0x0dc5, 0x080c, 0x97db, 0x080c, 0xb11a, 0x080c,
+	0x98e7, 0x0005, 0x9186, 0x0013, 0x1128, 0x6004, 0x9082, 0x0085,
+	0x2008, 0x04b8, 0x9186, 0x0027, 0x11f8, 0x080c, 0x97db, 0x080c,
+	0x324b, 0x080c, 0xd55d, 0x0096, 0x6014, 0x2048, 0x080c, 0xce3f,
+	0x0150, 0xa867, 0x0103, 0xa877, 0x0000, 0xa87b, 0x0029, 0x080c,
+	0x6dcb, 0x080c, 0xd02a, 0x009e, 0x080c, 0xb0e7, 0x080c, 0x98e7,
+	0x0005, 0x080c, 0xb181, 0x0ce0, 0x9186, 0x0014, 0x1dd0, 0x080c,
+	0x97db, 0x0096, 0x6014, 0x2048, 0x080c, 0xce3f, 0x0d60, 0xa867,
+	0x0103, 0xa877, 0x0000, 0xa87b, 0x0006, 0xa880, 0xc0ec, 0xa882,
+	0x08f0, 0x0002, 0xc879, 0xc877, 0xc877, 0xc877, 0xc877, 0xc877,
+	0xc891, 0xc877, 0xc877, 0xc877, 0xc877, 0xc877, 0xc877, 0x080c,
+	0x0dc5, 0x080c, 0x97db, 0x6034, 0x908c, 0xff00, 0x810f, 0x9186,
+	0x0039, 0x0118, 0x9186, 0x0035, 0x1118, 0x2001, 0x1987, 0x0010,
+	0x2001, 0x1988, 0x2004, 0x601a, 0x6003, 0x000c, 0x080c, 0x98e7,
+	0x0005, 0x080c, 0x97db, 0x6034, 0x908c, 0xff00, 0x810f, 0x9186,
+	0x0039, 0x0118, 0x9186, 0x0035, 0x1118, 0x2001, 0x1987, 0x0010,
+	0x2001, 0x1988, 0x2004, 0x601a, 0x6003, 0x000e, 0x080c, 0x98e7,
+	0x0005, 0x9182, 0x0092, 0x1220, 0x9182, 0x0085, 0x0208, 0x0012,
+	0x0804, 0xb181, 0xc8bf, 0xc8bf, 0xc8bf, 0xc8bf, 0xc8c1, 0xc90e,
+	0xc8bf, 0xc8bf, 0xc8bf, 0xc8bf, 0xc8bf, 0xc8bf, 0xc8bf, 0x080c,
+	0x0dc5, 0x0096, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc,
+	0x0168, 0x6034, 0x908c, 0xff00, 0x810f, 0x9186, 0x0039, 0x0118,
+	0x9186, 0x0035, 0x1118, 0x009e, 0x0804, 0xc922, 0x080c, 0xce3f,
+	0x1118, 0x080c, 0xd02a, 0x0068, 0x6014, 0x2048, 0xa87c, 0xd0e4,
+	0x1110, 0x080c, 0xd02a, 0xa867, 0x0103, 0x080c, 0xd528, 0x080c,
+	0x6dcb, 0x00d6, 0x2c68, 0x080c, 0xb091, 0x01d0, 0x6003, 0x0001,
+	0x6007, 0x001e, 0x600b, 0xffff, 0x2009, 0x026e, 0x210c, 0x613a,
+	0x2009, 0x026f, 0x210c, 0x613e, 0x6910, 0x6112, 0x080c, 0xd2bb,
+	0x6954, 0x6156, 0x6023, 0x0001, 0x080c, 0x9335, 0x080c, 0x98e7,
+	0x2d60, 0x00de, 0x080c, 0xb0e7, 0x009e, 0x0005, 0x6010, 0x00b6,
+	0x2058, 0xb800, 0x00be, 0xd0bc, 0x05a0, 0x6034, 0x908c, 0xff00,
+	0x810f, 0x9186, 0x0035, 0x0130, 0x9186, 0x001e, 0x0118, 0x9186,
+	0x0039, 0x1538, 0x00d6, 0x2c68, 0x080c, 0xd4c0, 0x11f0, 0x080c,
+	0xb091, 0x01d8, 0x6106, 0x6003, 0x0001, 0x6023, 0x0001, 0x6910,
+	0x6112, 0x692c, 0x612e, 0x6930, 0x6132, 0x6934, 0x918c, 0x00ff,
+	0x6136, 0x6938, 0x613a, 0x693c, 0x613e, 0x6954, 0x6156, 0x080c,
+	0xd2bb, 0x080c, 0x9335, 0x080c, 0x98e7, 0x2d60, 0x00de, 0x0804,
+	0xb0e7, 0x0096, 0x6014, 0x2048, 0x080c, 0xce3f, 0x01c8, 0xa867,
+	0x0103, 0xa880, 0xd0b4, 0x0128, 0xc0ec, 0xa882, 0xa87b, 0x0006,
+	0x0048, 0xd0bc, 0x0118, 0xa87b, 0x0002, 0x0020, 0xa87b, 0x0005,
+	0x080c, 0xd13b, 0xa877, 0x0000, 0x080c, 0x6dcb, 0x080c, 0xd02a,
+	0x009e, 0x0804, 0xb0e7, 0x0016, 0x0096, 0x6014, 0x2048, 0x080c,
+	0xce3f, 0x0140, 0xa867, 0x0103, 0xa87b, 0x0028, 0xa877, 0x0000,
+	0x080c, 0x6dcb, 0x009e, 0x001e, 0x9186, 0x0013, 0x0148, 0x9186,
+	0x0014, 0x0130, 0x9186, 0x0027, 0x0118, 0x080c, 0xb181, 0x0030,
+	0x080c, 0x97db, 0x080c, 0xb11a, 0x080c, 0x98e7, 0x0005, 0x0056,
+	0x0066, 0x0096, 0x00a6, 0x2029, 0x0001, 0x9182, 0x0101, 0x1208,
+	0x0010, 0x2009, 0x0100, 0x2130, 0x8304, 0x9098, 0x0018, 0x2009,
+	0x0020, 0x2011, 0x0029, 0x080c, 0xc9f0, 0x96b2, 0x0020, 0xb004,
+	0x904d, 0x0110, 0x080c, 0x0fc0, 0x080c, 0x100e, 0x0520, 0x8528,
+	0xa867, 0x0110, 0xa86b, 0x0000, 0x2920, 0xb406, 0x968a, 0x003d,
+	0x1228, 0x2608, 0x2011, 0x001b, 0x0499, 0x00a8, 0x96b2, 0x003c,
+	0x2009, 0x003c, 0x2950, 0x2011, 0x001b, 0x0451, 0x0c28, 0x2001,
+	0x0205, 0x2003, 0x0000, 0x00ae, 0x852f, 0x95ad, 0x0003, 0xb566,
+	0x95ac, 0x0000, 0x0048, 0x2001, 0x0205, 0x2003, 0x0000, 0x00ae,
+	0x852f, 0x95ad, 0x0003, 0xb566, 0x009e, 0x006e, 0x005e, 0x0005,
+	0x00a6, 0x89ff, 0x0158, 0xa804, 0x9055, 0x0130, 0xa807, 0x0000,
+	0x080c, 0x6dcb, 0x2a48, 0x0cb8, 0x080c, 0x6dcb, 0x00ae, 0x0005,
+	0x00f6, 0x2079, 0x0200, 0x7814, 0x9085, 0x0080, 0x7816, 0xd184,
+	0x0108, 0x8108, 0x810c, 0x20a9, 0x0001, 0xa860, 0x20e8, 0xa85c,
+	0x9200, 0x20a0, 0x20e1, 0x0000, 0x2300, 0x9e00, 0x2098, 0x4003,
+	0x8318, 0x9386, 0x0020, 0x1148, 0x2018, 0x2300, 0x9e00, 0x2098,
+	0x7814, 0x8000, 0x9085, 0x0080, 0x7816, 0x8109, 0x1d80, 0x7817,
+	0x0000, 0x00fe, 0x0005, 0x6920, 0x9186, 0x0003, 0x0118, 0x9186,
+	0x0002, 0x11d0, 0x00c6, 0x00d6, 0x00e6, 0x2d60, 0x0096, 0x6014,
+	0x2048, 0x080c, 0xce3f, 0x0150, 0x2001, 0x0006, 0xa980, 0xc1d5,
+	0x080c, 0x7037, 0x080c, 0x6dbe, 0x080c, 0xd02a, 0x009e, 0x080c,
+	0xb11a, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x00c6, 0x702c, 0xd084,
+	0x1170, 0x6008, 0x2060, 0x6020, 0x9086, 0x0002, 0x1140, 0x6104,
+	0x9186, 0x0085, 0x0118, 0x9186, 0x008b, 0x1108, 0x9006, 0x00ce,
+	0x0005, 0x0066, 0x0126, 0x2091, 0x8000, 0x2031, 0x0001, 0x6020,
+	0x9084, 0x000f, 0x0083, 0x012e, 0x006e, 0x0005, 0x0126, 0x2091,
+	0x8000, 0x0066, 0x2031, 0x0000, 0x6020, 0x9084, 0x000f, 0x001b,
+	0x006e, 0x012e, 0x0005, 0xca8c, 0xca8c, 0xca87, 0xcaae, 0xca7a,
+	0xca87, 0xcaae, 0xca87, 0xca7a, 0x9119, 0xca87, 0xca87, 0xca87,
+	0xca7a, 0xca7a, 0x080c, 0x0dc5, 0x0036, 0x2019, 0x0010, 0x080c,
+	0xe4ba, 0x6023, 0x0006, 0x6003, 0x0007, 0x003e, 0x0005, 0x9006,
+	0x0005, 0x9085, 0x0001, 0x0005, 0x0096, 0x86ff, 0x11d8, 0x6014,
+	0x2048, 0x080c, 0xce3f, 0x01c0, 0xa864, 0x9086, 0x0139, 0x1128,
+	0xa87b, 0x0005, 0xa883, 0x0000, 0x0028, 0x900e, 0x2001, 0x0005,
+	0x080c, 0x7037, 0x080c, 0xd13b, 0x080c, 0x6dbe, 0x080c, 0xb11a,
+	0x9085, 0x0001, 0x009e, 0x0005, 0x9006, 0x0ce0, 0x6000, 0x908a,
+	0x0016, 0x1a0c, 0x0dc5, 0x0002, 0xcac4, 0xcaf4, 0xcac6, 0xcb15,
+	0xcaef, 0xcac4, 0xca87, 0xca8c, 0xca8c, 0xca87, 0xca87, 0xca87,
+	0xca87, 0xca87, 0xca87, 0xca87, 0x080c, 0x0dc5, 0x86ff, 0x1520,
+	0x6020, 0x9086, 0x0006, 0x0500, 0x0096, 0x6014, 0x2048, 0x080c,
+	0xce3f, 0x0168, 0xa87c, 0xd0cc, 0x0140, 0x0096, 0xc0cc, 0xa87e,
+	0xa878, 0x2048, 0x080c, 0x0fc0, 0x009e, 0x080c, 0xd13b, 0x009e,
+	0x080c, 0xd502, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002,
+	0x080c, 0x9335, 0x080c, 0x98e7, 0x9085, 0x0001, 0x0005, 0x0066,
+	0x080c, 0x1ab7, 0x006e, 0x0890, 0x00e6, 0x2071, 0x19e9, 0x7024,
+	0x9c06, 0x1120, 0x080c, 0xa7e7, 0x00ee, 0x0840, 0x6020, 0x9084,
+	0x000f, 0x9086, 0x0006, 0x1150, 0x0086, 0x0096, 0x2049, 0x0001,
+	0x2c40, 0x080c, 0xa90f, 0x009e, 0x008e, 0x0010, 0x080c, 0xa6e4,
+	0x00ee, 0x1904, 0xcac6, 0x0804, 0xca87, 0x0036, 0x00e6, 0x2071,
+	0x19e9, 0x703c, 0x9c06, 0x1138, 0x901e, 0x080c, 0xa85d, 0x00ee,
+	0x003e, 0x0804, 0xcac6, 0x080c, 0xaa3f, 0x00ee, 0x003e, 0x1904,
+	0xcac6, 0x0804, 0xca87, 0x00c6, 0x6020, 0x9084, 0x000f, 0x0013,
+	0x00ce, 0x0005, 0xcb48, 0xcc13, 0xcd7d, 0xcb52, 0xb11a, 0xcb48,
+	0xe4ac, 0xd56a, 0xcc13, 0x90eb, 0xce09, 0xcb41, 0xcb41, 0xcb41,
+	0xcb41, 0x080c, 0x0dc5, 0x080c, 0xd047, 0x1110, 0x080c, 0xbacb,
+	0x0005, 0x080c, 0x97db, 0x080c, 0x98e7, 0x0804, 0xb0e7, 0x601b,
+	0x0001, 0x0005, 0x080c, 0xce3f, 0x0130, 0x6014, 0x0096, 0x2048,
+	0x2c00, 0xa896, 0x009e, 0x6000, 0x908a, 0x0016, 0x1a0c, 0x0dc5,
+	0x0002, 0xcb71, 0xcb73, 0xcb97, 0xcbab, 0xcbd1, 0xcb71, 0xcb48,
+	0xcb48, 0xcb48, 0xcbab, 0xcbab, 0xcb71, 0xcb71, 0xcb71, 0xcb71,
+	0xcbb5, 0x080c, 0x0dc5, 0x00e6, 0x6014, 0x0096, 0x2048, 0xa880,
+	0xc0b5, 0xa882, 0x009e, 0x2071, 0x19e9, 0x7024, 0x9c06, 0x01a0,
+	0x080c, 0xa6e4, 0x080c, 0xd502, 0x6007, 0x0085, 0x6003, 0x000b,
+	0x6023, 0x0002, 0x2001, 0x1988, 0x2004, 0x601a, 0x080c, 0x9335,
+	0x080c, 0x98e7, 0x00ee, 0x0005, 0x601b, 0x0001, 0x0cd8, 0x0096,
+	0x6014, 0x2048, 0xa880, 0xc0b5, 0xa882, 0x009e, 0x080c, 0xd502,
+	0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002, 0x080c, 0x9335,
+	0x080c, 0x98e7, 0x0005, 0x0096, 0x601b, 0x0001, 0x6014, 0x2048,
+	0xa880, 0xc0b5, 0xa882, 0x009e, 0x0005, 0x080c, 0x57d5, 0x01b8,
+	0x6014, 0x0096, 0x904d, 0x0190, 0xa864, 0xa867, 0x0103, 0xa87b,
+	0x0006, 0x9086, 0x0139, 0x1150, 0xa867, 0x0139, 0xa87b, 0x0030,
+	0xa897, 0x4005, 0xa89b, 0x0004, 0x080c, 0x6dcb, 0x009e, 0x0804,
+	0xb0e7, 0x6014, 0x0096, 0x904d, 0x05c8, 0xa97c, 0xd1e4, 0x05b0,
+	0x2001, 0x180f, 0x2004, 0xd0c4, 0x0110, 0x009e, 0x0005, 0xa884,
+	0x009e, 0x8003, 0x800b, 0x810b, 0x9108, 0x611a, 0x2001, 0x0030,
+	0x2c08, 0x080c, 0x1611, 0x2001, 0x030c, 0x2004, 0x9086, 0x0041,
+	0x11a0, 0x6014, 0x0096, 0x904d, 0x090c, 0x0dc5, 0xa880, 0xd0f4,
+	0x1130, 0xc0f5, 0xa882, 0x009e, 0x601b, 0x0002, 0x0070, 0x009e,
+	0x2001, 0x0037, 0x2c08, 0x080c, 0x1611, 0x6000, 0x9086, 0x0004,
+	0x1120, 0x2009, 0x0048, 0x080c, 0xb166, 0x0005, 0x009e, 0x080c,
+	0x1ab7, 0x0804, 0xcb97, 0x6000, 0x908a, 0x0016, 0x1a0c, 0x0dc5,
+	0x000b, 0x0005, 0xcc2a, 0xcb4f, 0xcc2c, 0xcc2a, 0xcc2c, 0xcc2c,
+	0xcb49, 0xcc2a, 0xcb43, 0xcb43, 0xcc2a, 0xcc2a, 0xcc2a, 0xcc2a,
+	0xcc2a, 0xcc2a, 0x080c, 0x0dc5, 0x6010, 0x00b6, 0x2058, 0xb804,
+	0x9084, 0x00ff, 0x00be, 0x908a, 0x000c, 0x1a0c, 0x0dc5, 0x00b6,
+	0x0013, 0x00be, 0x0005, 0xcc47, 0xcd14, 0xcc49, 0xcc89, 0xcc49,
+	0xcc89, 0xcc49, 0xcc57, 0xcc47, 0xcc89, 0xcc47, 0xcc78, 0x080c,
+	0x0dc5, 0x6004, 0x908e, 0x0016, 0x05c0, 0x908e, 0x0004, 0x05a8,
+	0x908e, 0x0002, 0x0590, 0x908e, 0x0052, 0x0904, 0xcd10, 0x6004,
+	0x080c, 0xd047, 0x0904, 0xcd2d, 0x908e, 0x0004, 0x1110, 0x080c,
+	0x3274, 0x908e, 0x0021, 0x0904, 0xcd31, 0x908e, 0x0022, 0x0904,
+	0xcd78, 0x908e, 0x003d, 0x0904, 0xcd31, 0x908e, 0x0039, 0x0904,
+	0xcd35, 0x908e, 0x0035, 0x0904, 0xcd35, 0x908e, 0x001e, 0x0178,
+	0x908e, 0x0001, 0x1140, 0x6010, 0x2058, 0xb804, 0x9084, 0x00ff,
+	0x9086, 0x0006, 0x0110, 0x080c, 0x324b, 0x080c, 0xbacb, 0x0804,
+	0xb11a, 0x00c6, 0x00d6, 0x6104, 0x9186, 0x0016, 0x0904, 0xcd01,
+	0x9186, 0x0002, 0x1904, 0xccd6, 0x2001, 0x1837, 0x2004, 0xd08c,
+	0x11c8, 0x080c, 0x7563, 0x11b0, 0x080c, 0xd548, 0x0138, 0x080c,
+	0x7586, 0x1120, 0x080c, 0x746d, 0x0804, 0xcd61, 0x2001, 0x197e,
+	0x2003, 0x0001, 0x2001, 0x1800, 0x2003, 0x0001, 0x080c, 0x748f,
+	0x0804, 0xcd61, 0x6010, 0x2058, 0x2001, 0x1837, 0x2004, 0xd0ac,
+	0x1904, 0xcd61, 0xb8a0, 0x9084, 0xff80, 0x1904, 0xcd61, 0xb840,
+	0x9084, 0x00ff, 0x9005, 0x0190, 0x8001, 0xb842, 0x6017, 0x0000,
+	0x6023, 0x0007, 0x601b, 0x0398, 0x6043, 0x0000, 0x080c, 0xb091,
+	0x0128, 0x2b00, 0x6012, 0x6023, 0x0001, 0x0458, 0x00de, 0x00ce,
+	0x6004, 0x908e, 0x0002, 0x11a0, 0x6010, 0x2058, 0xb8a0, 0x9086,
+	0x007e, 0x1170, 0x2009, 0x1837, 0x2104, 0xc085, 0x200a, 0x00e6,
+	0x2071, 0x1800, 0x080c, 0x60b4, 0x00ee, 0x080c, 0xbacb, 0x0030,
+	0x080c, 0xbacb, 0x080c, 0x324b, 0x080c, 0xd55d, 0x00e6, 0x0126,
+	0x2091, 0x8000, 0x080c, 0x3274, 0x012e, 0x00ee, 0x080c, 0xb11a,
+	0x0005, 0x2001, 0x0002, 0x080c, 0x665d, 0x6003, 0x0001, 0x6007,
+	0x0002, 0x080c, 0x937d, 0x080c, 0x98e7, 0x00de, 0x00ce, 0x0c80,
+	0x080c, 0x3274, 0x0804, 0xcc85, 0x00c6, 0x00d6, 0x6104, 0x9186,
+	0x0016, 0x0d38, 0x6010, 0x2058, 0xb840, 0x9084, 0x00ff, 0x9005,
+	0x0904, 0xccd6, 0x8001, 0xb842, 0x6003, 0x0001, 0x080c, 0x937d,
+	0x080c, 0x98e7, 0x00de, 0x00ce, 0x0898, 0x080c, 0xbacb, 0x0804,
+	0xcc87, 0x080c, 0xbb07, 0x0804, 0xcc87, 0x00d6, 0x2c68, 0x6104,
+	0x080c, 0xd4c0, 0x00de, 0x0118, 0x080c, 0xb0e7, 0x0408, 0x6004,
+	0x8007, 0x6134, 0x918c, 0x00ff, 0x9105, 0x6036, 0x6007, 0x0085,
+	0x6003, 0x000b, 0x6023, 0x0002, 0x603c, 0x600a, 0x2001, 0x1988,
+	0x2004, 0x601a, 0x602c, 0x2c08, 0x2060, 0x6024, 0xd0b4, 0x0108,
+	0xc085, 0xc0b5, 0x6026, 0x2160, 0x080c, 0x9335, 0x080c, 0x98e7,
+	0x0005, 0x00de, 0x00ce, 0x080c, 0xbacb, 0x080c, 0x324b, 0x00e6,
+	0x0126, 0x2091, 0x8000, 0x080c, 0x3274, 0x6017, 0x0000, 0x6023,
+	0x0007, 0x601b, 0x0398, 0x6043, 0x0000, 0x012e, 0x00ee, 0x0005,
+	0x080c, 0xb51f, 0x1904, 0xcd2d, 0x0005, 0x6000, 0x908a, 0x0016,
+	0x1a0c, 0x0dc5, 0x0096, 0x00d6, 0x001b, 0x00de, 0x009e, 0x0005,
+	0xcd98, 0xcd98, 0xcd98, 0xcd98, 0xcd98, 0xcd98, 0xcd98, 0xcd98,
+	0xcd98, 0xcb48, 0xcd98, 0xcb4f, 0xcd9a, 0xcb4f, 0xcdb4, 0xcd98,
+	0x080c, 0x0dc5, 0x6004, 0x9086, 0x008b, 0x01b0, 0x6034, 0x908c,
+	0xff00, 0x810f, 0x9186, 0x0035, 0x1130, 0x602c, 0x9080, 0x0009,
+	0x200c, 0xc185, 0x2102, 0x6007, 0x008b, 0x6003, 0x000d, 0x080c,
+	0x9335, 0x080c, 0x98e7, 0x0005, 0x080c, 0xd53c, 0x0118, 0x080c,
+	0xd54f, 0x0010, 0x080c, 0xd55d, 0x080c, 0xd02a, 0x080c, 0xce3f,
+	0x0570, 0x080c, 0x324b, 0x080c, 0xce3f, 0x0168, 0x6014, 0x2048,
+	0xa867, 0x0103, 0xa87b, 0x0006, 0xa877, 0x0000, 0xa880, 0xc0ed,
+	0xa882, 0x080c, 0x6dcb, 0x2c68, 0x080c, 0xb091, 0x0150, 0x6810,
+	0x6012, 0x080c, 0xd2bb, 0x00c6, 0x2d60, 0x080c, 0xb11a, 0x00ce,
+	0x0008, 0x2d60, 0x6017, 0x0000, 0x6023, 0x0001, 0x6007, 0x0001,
+	0x6003, 0x0001, 0x080c, 0x937d, 0x080c, 0x98e7, 0x00c8, 0x080c,
+	0xd53c, 0x0138, 0x6034, 0x9086, 0x4000, 0x1118, 0x080c, 0x324b,
+	0x08d0, 0x6034, 0x908c, 0xff00, 0x810f, 0x9186, 0x0039, 0x0118,
+	0x9186, 0x0035, 0x1118, 0x080c, 0x324b, 0x0868, 0x080c, 0xb11a,
+	0x0005, 0x6000, 0x908a, 0x0016, 0x1a0c, 0x0dc5, 0x0002, 0xce1f,
+	0xce1f, 0xce21, 0xce21, 0xce21, 0xce1f, 0xce1f, 0xb11a, 0xce1f,
+	0xce1f, 0xce1f, 0xce1f, 0xce1f, 0xce1f, 0xce1f, 0xce1f, 0x080c,
+	0x0dc5, 0x080c, 0xaa3f, 0x6114, 0x0096, 0x2148, 0xa87b, 0x0006,
+	0x080c, 0x6dcb, 0x009e, 0x0804, 0xb0e7, 0x9284, 0x0007, 0x1158,
+	0x9282, 0x1cd0, 0x0240, 0x2001, 0x181a, 0x2004, 0x9202, 0x1218,
+	0x9085, 0x0001, 0x0005, 0x9006, 0x0ce8, 0x0096, 0x0028, 0x0096,
+	0x0006, 0x6014, 0x2048, 0x000e, 0x0006, 0x9984, 0xf000, 0x9086,
+	0xf000, 0x0110, 0x080c, 0x10b9, 0x000e, 0x009e, 0x0005, 0x00e6,
+	0x00c6, 0x0036, 0x0006, 0x0126, 0x2091, 0x8000, 0x2061, 0x1cd0,
+	0x2071, 0x1800, 0x7354, 0x7074, 0x9302, 0x1640, 0x6020, 0x9206,
+	0x11f8, 0x080c, 0xd548, 0x0180, 0x9286, 0x0001, 0x1168, 0x6004,
+	0x9086, 0x0004, 0x1148, 0x080c, 0x324b, 0x080c, 0xd55d, 0x00c6,
+	0x080c, 0xb11a, 0x00ce, 0x0060, 0x080c, 0xd235, 0x0148, 0x080c,
+	0xd047, 0x1110, 0x080c, 0xbacb, 0x00c6, 0x080c, 0xb0e7, 0x00ce,
+	0x9ce0, 0x0018, 0x7068, 0x9c02, 0x1208, 0x08a0, 0x012e, 0x000e,
+	0x003e, 0x00ce, 0x00ee, 0x0005, 0x00e6, 0x00c6, 0x0016, 0x9188,
+	0x1000, 0x210c, 0x81ff, 0x0128, 0x2061, 0x1ab8, 0x6112, 0x080c,
+	0x324b, 0x9006, 0x0010, 0x9085, 0x0001, 0x001e, 0x00ce, 0x00ee,
+	0x0005, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xb091, 0x01b0,
+	0x6656, 0x2b00, 0x6012, 0x080c, 0x57d5, 0x0118, 0x080c, 0xcf6e,
+	0x0168, 0x080c, 0xd2bb, 0x6023, 0x0003, 0x2009, 0x004b, 0x080c,
+	0xb166, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8,
+	0x00c6, 0x0126, 0x2091, 0x8000, 0xbaa0, 0x080c, 0xb139, 0x0560,
+	0x6057, 0x0000, 0x2b00, 0x6012, 0x080c, 0xd2bb, 0x6023, 0x0003,
+	0x0016, 0x080c, 0x94da, 0x0076, 0x903e, 0x080c, 0x93ad, 0x2c08,
+	0x080c, 0xe671, 0x007e, 0x001e, 0xd184, 0x0128, 0x080c, 0xb0e7,
+	0x9085, 0x0001, 0x0070, 0x080c, 0x57d5, 0x0128, 0xd18c, 0x1170,
+	0x080c, 0xcf6e, 0x0148, 0x2009, 0x004c, 0x080c, 0xb166, 0x9085,
+	0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x2900, 0x6016,
+	0x0c90, 0x2009, 0x004d, 0x0010, 0x2009, 0x004e, 0x00f6, 0x00c6,
+	0x0046, 0x0016, 0x080c, 0xb091, 0x2c78, 0x05a0, 0x7e56, 0x2b00,
+	0x7812, 0x7823, 0x0003, 0x0016, 0x2021, 0x0005, 0x080c, 0xcf80,
+	0x001e, 0x9186, 0x004d, 0x0118, 0x9186, 0x004e, 0x0148, 0x2001,
+	0x1981, 0x200c, 0xd1fc, 0x0168, 0x2f60, 0x080c, 0xb0e7, 0x00d0,
+	0x2001, 0x1980, 0x200c, 0xd1fc, 0x0120, 0x2f60, 0x080c, 0xb0e7,
+	0x0088, 0x2f60, 0x080c, 0x57d5, 0x0138, 0xd18c, 0x1118, 0x04f1,
+	0x0148, 0x0010, 0x2900, 0x7816, 0x001e, 0x0016, 0x080c, 0xb166,
+	0x9085, 0x0001, 0x001e, 0x004e, 0x00ce, 0x00fe, 0x0005, 0x00f6,
+	0x00c6, 0x0046, 0x080c, 0xb091, 0x2c78, 0x0508, 0x7e56, 0x2b00,
+	0x7812, 0x7823, 0x0003, 0x0096, 0x2021, 0x0004, 0x0489, 0x009e,
+	0x2001, 0x197f, 0x200c, 0xd1fc, 0x0120, 0x2f60, 0x080c, 0xb0e7,
+	0x0060, 0x2f60, 0x080c, 0x57d5, 0x0120, 0xd18c, 0x1160, 0x0071,
+	0x0130, 0x2009, 0x0052, 0x080c, 0xb166, 0x9085, 0x0001, 0x004e,
+	0x00ce, 0x00fe, 0x0005, 0x2900, 0x7816, 0x0c98, 0x00c6, 0x080c,
+	0x4b83, 0x00ce, 0x1120, 0x080c, 0xb0e7, 0x9006, 0x0005, 0xa867,
+	0x0000, 0xa86b, 0x8000, 0x2900, 0x6016, 0x9085, 0x0001, 0x0005,
+	0x0096, 0x0076, 0x0126, 0x2091, 0x8000, 0x080c, 0x684b, 0x0158,
+	0x2001, 0xcf85, 0x0006, 0x900e, 0x2400, 0x080c, 0x7037, 0x080c,
+	0x6dcb, 0x000e, 0x0807, 0x2418, 0x080c, 0x9775, 0xbaa0, 0x0086,
+	0x2041, 0x0001, 0x2039, 0x0001, 0x2608, 0x080c, 0x94f2, 0x008e,
+	0x080c, 0x93ad, 0x2f08, 0x2648, 0x080c, 0xe671, 0xb93c, 0x81ff,
+	0x090c, 0x95c5, 0x080c, 0x98e7, 0x012e, 0x007e, 0x009e, 0x0005,
+	0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xb091, 0x0190, 0x660a,
+	0x2b08, 0x6112, 0x080c, 0xd2bb, 0x6023, 0x0001, 0x2900, 0x6016,
+	0x2009, 0x001f, 0x080c, 0xb166, 0x9085, 0x0001, 0x012e, 0x00ce,
+	0x0005, 0x9006, 0x0cd8, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c,
+	0xb139, 0x01b8, 0x660a, 0x2b08, 0x6112, 0x080c, 0xd2bb, 0x6023,
+	0x0008, 0x2900, 0x6016, 0x00f6, 0x2c78, 0x080c, 0x1768, 0x00fe,
+	0x2009, 0x0021, 0x080c, 0xb166, 0x9085, 0x0001, 0x012e, 0x00ce,
+	0x0005, 0x9006, 0x0cd8, 0x2009, 0x003d, 0x00c6, 0x0126, 0x0016,
+	0x2091, 0x8000, 0x080c, 0xb091, 0x0198, 0x660a, 0x2b08, 0x6112,
+	0x080c, 0xd2bb, 0x6023, 0x0001, 0x2900, 0x6016, 0x001e, 0x0016,
+	0x080c, 0xb166, 0x9085, 0x0001, 0x001e, 0x012e, 0x00ce, 0x0005,
+	0x9006, 0x0cd0, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xb139,
+	0x0188, 0x2b08, 0x6112, 0x080c, 0xd2bb, 0x6023, 0x0001, 0x2900,
+	0x6016, 0x2009, 0x0000, 0x080c, 0xb166, 0x9085, 0x0001, 0x012e,
+	0x00ce, 0x0005, 0x9006, 0x0cd8, 0x2009, 0x0044, 0x0830, 0x2009,
+	0x0049, 0x0818, 0x0026, 0x00b6, 0x6210, 0x2258, 0xba3c, 0x82ff,
+	0x0110, 0x8211, 0xba3e, 0x00be, 0x002e, 0x0005, 0x0006, 0x0016,
+	0x6004, 0x908e, 0x0002, 0x0140, 0x908e, 0x0003, 0x0128, 0x908e,
+	0x0004, 0x0110, 0x9085, 0x0001, 0x001e, 0x000e, 0x0005, 0x0006,
+	0x0086, 0x0096, 0x6020, 0x9086, 0x0004, 0x01a8, 0x6014, 0x904d,
+	0x080c, 0xce3f, 0x0180, 0xa864, 0x9086, 0x0139, 0x0170, 0x6020,
+	0x90c6, 0x0003, 0x0140, 0x90c6, 0x0002, 0x0128, 0xa868, 0xd0fc,
+	0x0110, 0x9006, 0x0010, 0x9085, 0x0001, 0x009e, 0x008e, 0x000e,
+	0x0005, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xb139, 0x0198,
+	0x2b08, 0x6112, 0x080c, 0xd2bb, 0x6023, 0x0001, 0x2900, 0x6016,
+	0x080c, 0x324b, 0x2009, 0x0028, 0x080c, 0xb166, 0x9085, 0x0001,
+	0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x9186, 0x0015, 0x11a8,
+	0x2011, 0x1824, 0x2204, 0x9086, 0x0074, 0x1178, 0x00b6, 0x080c,
+	0xbd2d, 0x00be, 0x080c, 0xbf52, 0x6003, 0x0001, 0x6007, 0x0029,
+	0x080c, 0x937d, 0x080c, 0x98e7, 0x0078, 0x6014, 0x0096, 0x2048,
+	0xa868, 0x009e, 0xd0fc, 0x0148, 0x2001, 0x0001, 0x080c, 0xd481,
+	0x080c, 0xbacb, 0x080c, 0xb0e7, 0x0005, 0x0096, 0x6014, 0x904d,
+	0x090c, 0x0dc5, 0xa87b, 0x0030, 0xa883, 0x0000, 0xa897, 0x4005,
+	0xa89b, 0x0004, 0xa867, 0x0139, 0x0126, 0x2091, 0x8000, 0x080c,
+	0x6dcb, 0x012e, 0x009e, 0x080c, 0xb0e7, 0x0c30, 0x0096, 0x9186,
+	0x0016, 0x1128, 0x2001, 0x0004, 0x080c, 0x665d, 0x00e8, 0x9186,
+	0x0015, 0x1510, 0x2011, 0x1824, 0x2204, 0x9086, 0x0014, 0x11e0,
+	0x6010, 0x00b6, 0x2058, 0x080c, 0x67b2, 0x00be, 0x080c, 0xc023,
+	0x1198, 0x6010, 0x00b6, 0x2058, 0xb890, 0x00be, 0x9005, 0x0160,
+	0x2001, 0x0006, 0x080c, 0x665d, 0x6014, 0x2048, 0xa868, 0xd0fc,
+	0x0170, 0x080c, 0xb4f3, 0x0048, 0x6014, 0x2048, 0xa868, 0xd0fc,
+	0x0528, 0x080c, 0xbacb, 0x080c, 0xb0e7, 0x009e, 0x0005, 0x6014,
+	0x6310, 0x2358, 0x904d, 0x090c, 0x0dc5, 0xa87b, 0x0000, 0xa883,
+	0x0000, 0xa897, 0x4000, 0x900e, 0x080c, 0x6937, 0x1108, 0xc185,
+	0xb800, 0xd0bc, 0x0108, 0xc18d, 0xa99a, 0x0126, 0x2091, 0x8000,
+	0x080c, 0x6dcb, 0x012e, 0x080c, 0xb0e7, 0x08f8, 0x6014, 0x904d,
+	0x090c, 0x0dc5, 0xa87b, 0x0030, 0xa883, 0x0000, 0xa897, 0x4005,
+	0xa89b, 0x0004, 0xa867, 0x0139, 0x0126, 0x2091, 0x8000, 0x080c,
+	0x6dcb, 0x012e, 0x080c, 0xb0e7, 0x0840, 0xa878, 0x9086, 0x0005,
+	0x1108, 0x0009, 0x0005, 0xa880, 0xc0ad, 0xa882, 0x0005, 0x6043,
+	0x0000, 0x6017, 0x0000, 0x6003, 0x0001, 0x6007, 0x0050, 0x080c,
+	0x9335, 0x080c, 0x98e7, 0x0005, 0x00c6, 0x6010, 0x00b6, 0x2058,
+	0xb800, 0x00be, 0xd0bc, 0x0120, 0x6020, 0x9084, 0x000f, 0x0013,
+	0x00ce, 0x0005, 0xcb48, 0xd16b, 0xd16b, 0xd16e, 0xe98f, 0xe9aa,
+	0xe9ad, 0xcb48, 0xcb48, 0xcb48, 0xcb48, 0xcb48, 0xcb48, 0xcb48,
+	0xcb48, 0x080c, 0x0dc5, 0xa001, 0xa001, 0x0005, 0x0096, 0x6014,
+	0x904d, 0x0118, 0xa87c, 0xd0e4, 0x1110, 0x009e, 0x0010, 0x009e,
+	0x0005, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x0550,
+	0x2001, 0x1834, 0x2004, 0x9005, 0x1540, 0x00f6, 0x2c78, 0x080c,
+	0xb091, 0x0508, 0x7810, 0x6012, 0x080c, 0xd2bb, 0x7820, 0x9086,
+	0x0003, 0x0128, 0x7808, 0x603a, 0x2f00, 0x603e, 0x0020, 0x7808,
+	0x603e, 0x2f00, 0x603a, 0x602e, 0x6023, 0x0001, 0x6007, 0x0035,
+	0x6003, 0x0001, 0x7954, 0x6156, 0x080c, 0x9335, 0x080c, 0x98e7,
+	0x2f60, 0x00fe, 0x0005, 0x2f60, 0x00fe, 0x2001, 0x1989, 0x2004,
+	0x6042, 0x0005, 0x0016, 0x0096, 0x6814, 0x2048, 0xa87c, 0xd0e4,
+	0x0180, 0xc0e4, 0xa87e, 0xa877, 0x0000, 0xa893, 0x0000, 0xa88f,
+	0x0000, 0xd0cc, 0x0130, 0xc0cc, 0xa87e, 0xa878, 0x2048, 0x080c,
+	0x0fc0, 0x6830, 0x6036, 0x908e, 0x0001, 0x0148, 0x6803, 0x0002,
+	0x9086, 0x0005, 0x0170, 0x9006, 0x602e, 0x6032, 0x00d0, 0x681c,
+	0xc085, 0x681e, 0x6803, 0x0004, 0x6824, 0xc0f4, 0x9085, 0x0c00,
+	0x6826, 0x6814, 0x2048, 0xa8ac, 0x6938, 0x9102, 0xa8b0, 0x693c,
+	0x9103, 0x1e48, 0x683c, 0x602e, 0x6838, 0x9084, 0xfffc, 0x683a,
+	0x6032, 0x2d00, 0x603a, 0x6808, 0x603e, 0x6910, 0x6112, 0x6954,
+	0x6156, 0x6023, 0x0001, 0x6007, 0x0039, 0x6003, 0x0001, 0x080c,
+	0x9335, 0x080c, 0x98e7, 0x009e, 0x001e, 0x0005, 0x6024, 0xd0d4,
+	0x0510, 0xd0f4, 0x11f8, 0x6038, 0x940a, 0x603c, 0x9303, 0x0230,
+	0x9105, 0x0120, 0x6024, 0xc0d4, 0xc0f5, 0x0098, 0x643a, 0x633e,
+	0xac3e, 0xab42, 0x0046, 0x0036, 0x2400, 0xacac, 0x9402, 0xa836,
+	0x2300, 0xabb0, 0x9303, 0xa83a, 0x003e, 0x004e, 0x6024, 0xc0d4,
+	0x0000, 0x6026, 0x0005, 0xd0f4, 0x1138, 0xa83c, 0x603a, 0xa840,
+	0x603e, 0x6024, 0xc0f5, 0x6026, 0x0005, 0x0006, 0x0016, 0x6004,
+	0x908e, 0x0034, 0x01b8, 0x908e, 0x0035, 0x01a0, 0x908e, 0x0036,
+	0x0188, 0x908e, 0x0037, 0x0170, 0x908e, 0x0038, 0x0158, 0x908e,
+	0x0039, 0x0140, 0x908e, 0x003a, 0x0128, 0x908e, 0x003b, 0x0110,
+	0x9085, 0x0001, 0x001e, 0x000e, 0x0005, 0x0006, 0x0016, 0x0026,
+	0x0036, 0x00e6, 0x2001, 0x1983, 0x200c, 0x8000, 0x2014, 0x2001,
+	0x0032, 0x080c, 0x91ab, 0x2001, 0x1987, 0x82ff, 0x1110, 0x2011,
+	0x0014, 0x2202, 0x2001, 0x1985, 0x200c, 0x8000, 0x2014, 0x2071,
+	0x196d, 0x711a, 0x721e, 0x2001, 0x0064, 0x080c, 0x91ab, 0x2001,
+	0x1988, 0x82ff, 0x1110, 0x2011, 0x0014, 0x2202, 0x2001, 0x1989,
+	0x9288, 0x000a, 0x2102, 0x2001, 0x1a99, 0x2102, 0x2001, 0x0032,
+	0x080c, 0x1611, 0x080c, 0x6a6d, 0x00ee, 0x003e, 0x002e, 0x001e,
+	0x000e, 0x0005, 0x0006, 0x0016, 0x00e6, 0x2001, 0x1987, 0x2003,
+	0x0028, 0x2001, 0x1988, 0x2003, 0x0014, 0x2071, 0x196d, 0x701b,
+	0x0000, 0x701f, 0x07d0, 0x2001, 0x1989, 0x2009, 0x001e, 0x2102,
+	0x2001, 0x1a99, 0x2102, 0x2001, 0x0032, 0x080c, 0x1611, 0x00ee,
+	0x001e, 0x000e, 0x0005, 0x0096, 0x6058, 0x904d, 0x0110, 0x080c,
+	0x1040, 0x009e, 0x0005, 0x0005, 0x00c6, 0x0126, 0x2091, 0x8000,
+	0x080c, 0xb091, 0x0180, 0x2b08, 0x6112, 0x0ca9, 0x6023, 0x0001,
+	0x2900, 0x6016, 0x2009, 0x0033, 0x080c, 0xb166, 0x9085, 0x0001,
+	0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x0096, 0x00e6, 0x00f6,
+	0x2071, 0x1800, 0x9186, 0x0015, 0x1520, 0x7090, 0x9086, 0x0018,
+	0x0120, 0x7090, 0x9086, 0x0014, 0x11e0, 0x6014, 0x2048, 0xaa3c,
+	0xd2e4, 0x1160, 0x2c78, 0x080c, 0x9b82, 0x01d8, 0x707c, 0xaa50,
+	0x9206, 0x1160, 0x7080, 0xaa54, 0x9206, 0x1140, 0x6210, 0x00b6,
+	0x2258, 0xbaa0, 0x00be, 0x900e, 0x080c, 0x3294, 0x080c, 0xb4f3,
+	0x0020, 0x080c, 0xbacb, 0x080c, 0xb0e7, 0x00fe, 0x00ee, 0x009e,
+	0x0005, 0x7060, 0xaa54, 0x9206, 0x0d48, 0x0c80, 0x00c6, 0x0126,
+	0x2091, 0x8000, 0x080c, 0xb091, 0x0188, 0x2b08, 0x6112, 0x080c,
+	0xd2bb, 0x6023, 0x0001, 0x2900, 0x6016, 0x2009, 0x004d, 0x080c,
+	0xb166, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8,
+	0x00c6, 0x0126, 0x2091, 0x8000, 0x0016, 0x080c, 0xb091, 0x0180,
+	0x2b08, 0x6112, 0x080c, 0xd2bb, 0x6023, 0x0001, 0x2900, 0x6016,
+	0x001e, 0x080c, 0xb166, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005,
+	0x001e, 0x9006, 0x0cd0, 0x0016, 0x0026, 0x0036, 0x0046, 0x0056,
+	0x0066, 0x0096, 0x00e6, 0x00f6, 0x2071, 0x1800, 0x9186, 0x0015,
+	0x1568, 0x7190, 0x6014, 0x2048, 0xa814, 0x8003, 0x9106, 0x1530,
+	0x20e1, 0x0000, 0x2001, 0x19a1, 0x2003, 0x0000, 0x6014, 0x2048,
+	0xa830, 0x20a8, 0x8906, 0x8006, 0x8007, 0x9094, 0x003f, 0x22e8,
+	0x9084, 0xffc0, 0x9080, 0x001b, 0x20a0, 0x2001, 0x19a1, 0x0016,
+	0x200c, 0x080c, 0xdb93, 0x001e, 0xa804, 0x9005, 0x0110, 0x2048,
+	0x0c38, 0x6014, 0x2048, 0xa867, 0x0103, 0x0010, 0x080c, 0xbacb,
+	0x080c, 0xb0e7, 0x00fe, 0x00ee, 0x009e, 0x006e, 0x005e, 0x004e,
+	0x003e, 0x002e, 0x001e, 0x0005, 0x0096, 0x00e6, 0x00f6, 0x2071,
+	0x1800, 0x9186, 0x0015, 0x11b8, 0x7090, 0x9086, 0x0004, 0x1198,
+	0x6014, 0x2048, 0x2c78, 0x080c, 0x9b82, 0x01a8, 0x707c, 0xaa74,
+	0x9206, 0x1130, 0x7080, 0xaa78, 0x9206, 0x1110, 0x080c, 0x324b,
+	0x080c, 0xb4f3, 0x0020, 0x080c, 0xbacb, 0x080c, 0xb0e7, 0x00fe,
+	0x00ee, 0x009e, 0x0005, 0x7060, 0xaa78, 0x9206, 0x0d78, 0x0c80,
+	0x0096, 0x00e6, 0x00f6, 0x2071, 0x1800, 0x9186, 0x0015, 0x1550,
+	0x7090, 0x9086, 0x0004, 0x1530, 0x6014, 0x2048, 0x2c78, 0x080c,
+	0x9b82, 0x05f0, 0x707c, 0xaacc, 0x9206, 0x1180, 0x7080, 0xaad0,
+	0x9206, 0x1160, 0x080c, 0x324b, 0x0016, 0xa998, 0xaab0, 0x9284,
+	0x1000, 0xc0fd, 0x080c, 0x577c, 0x001e, 0x0010, 0x080c, 0x5567,
+	0x080c, 0xce3f, 0x0508, 0xa87b, 0x0000, 0xa883, 0x0000, 0xa897,
+	0x4000, 0x0080, 0x080c, 0xce3f, 0x01b8, 0x6014, 0x2048, 0x080c,
+	0x5567, 0x1d70, 0xa87b, 0x0030, 0xa883, 0x0000, 0xa897, 0x4005,
+	0xa89b, 0x0004, 0x0126, 0x2091, 0x8000, 0xa867, 0x0139, 0x080c,
+	0x6dcb, 0x012e, 0x080c, 0xb0e7, 0x00fe, 0x00ee, 0x009e, 0x0005,
+	0x7060, 0xaad0, 0x9206, 0x0930, 0x0888, 0x0016, 0x0026, 0xa87c,
+	0xd0ac, 0x0178, 0xa938, 0xaa34, 0x2100, 0x9205, 0x0150, 0xa890,
+	0x9106, 0x1118, 0xa88c, 0x9206, 0x0120, 0xa992, 0xaa8e, 0x9085,
+	0x0001, 0x002e, 0x001e, 0x0005, 0x00b6, 0x00d6, 0x0036, 0x080c,
+	0xce3f, 0x0904, 0xd47d, 0x0096, 0x6314, 0x2348, 0xa87a, 0xa982,
+	0x929e, 0x4000, 0x1580, 0x6310, 0x00c6, 0x2358, 0x2009, 0x0000,
+	0xa868, 0xd0f4, 0x1140, 0x080c, 0x6937, 0x1108, 0xc185, 0xb800,
+	0xd0bc, 0x0108, 0xc18d, 0xaa96, 0xa99a, 0x20a9, 0x0004, 0xa860,
+	0x20e8, 0xa85c, 0x9080, 0x0031, 0x20a0, 0xb8c4, 0x20e0, 0xb8c8,
+	0x9080, 0x0006, 0x2098, 0x080c, 0x0f8b, 0x20a9, 0x0004, 0xa85c,
+	0x9080, 0x0035, 0x20a0, 0xb8c8, 0x9080, 0x000a, 0x2098, 0x080c,
+	0x0f8b, 0x00ce, 0x0090, 0xaa96, 0x3918, 0x9398, 0x0007, 0x231c,
+	0x6004, 0x9086, 0x0016, 0x0110, 0xa89b, 0x0004, 0xaba2, 0x6310,
+	0x2358, 0xb804, 0x9084, 0x00ff, 0xa89e, 0xa868, 0xc0f4, 0xa86a,
+	0x080c, 0x6dbe, 0x6017, 0x0000, 0x009e, 0x003e, 0x00de, 0x00be,
 	0x0005, 0x0026, 0x0036, 0x0046, 0x00b6, 0x0096, 0x00f6, 0x6214,
 	0x2248, 0x6210, 0x2258, 0x2079, 0x0260, 0x9096, 0x0000, 0x11a0,
-	0xb814, 0x9084, 0x00ff, 0x900e, 0x080c, 0x287c, 0x2118, 0x831f,
+	0xb814, 0x9084, 0x00ff, 0x900e, 0x080c, 0x2889, 0x2118, 0x831f,
 	0x939c, 0xff00, 0x7838, 0x9084, 0x00ff, 0x931d, 0x7c3c, 0x2011,
-	0x8018, 0x080c, 0x4b7f, 0x00a8, 0x9096, 0x0001, 0x1148, 0x89ff,
+	0x8018, 0x080c, 0x4be3, 0x00a8, 0x9096, 0x0001, 0x1148, 0x89ff,
 	0x0180, 0xa89b, 0x000d, 0x7838, 0xa8a6, 0x783c, 0xa8aa, 0x0048,
 	0x9096, 0x0002, 0x1130, 0xa89b, 0x000d, 0x7838, 0xa8a6, 0x783c,
 	0xa8aa, 0x00fe, 0x009e, 0x00be, 0x004e, 0x003e, 0x002e, 0x0005,
 	0x00c6, 0x0026, 0x0016, 0x9186, 0x0035, 0x0110, 0x6a38, 0x0008,
-	0x6a2c, 0x080c, 0xcc74, 0x01f0, 0x2260, 0x6120, 0x9186, 0x0003,
+	0x6a2c, 0x080c, 0xce2d, 0x01f0, 0x2260, 0x6120, 0x9186, 0x0003,
 	0x0118, 0x9186, 0x0006, 0x1190, 0x6838, 0x9206, 0x0140, 0x683c,
 	0x9206, 0x1160, 0x6108, 0x6838, 0x9106, 0x1140, 0x0020, 0x6008,
 	0x693c, 0x9106, 0x1118, 0x6010, 0x6910, 0x9106, 0x001e, 0x002e,
 	0x00ce, 0x0005, 0x9085, 0x0001, 0x0cc8, 0xa974, 0xd1cc, 0x0188,
 	0x918c, 0x00ff, 0x918e, 0x0002, 0x1160, 0xa9a8, 0x918c, 0x0f00,
 	0x810f, 0x918e, 0x0001, 0x1128, 0xa834, 0xa938, 0x9115, 0x190c,
-	0xc33d, 0x0005, 0x0036, 0x2019, 0x0001, 0x0010, 0x0036, 0x901e,
-	0x0499, 0x01e0, 0x080c, 0xcc86, 0x01c8, 0x080c, 0xce71, 0x6037,
+	0xc4f6, 0x0005, 0x0036, 0x2019, 0x0001, 0x0010, 0x0036, 0x901e,
+	0x0499, 0x01e0, 0x080c, 0xce3f, 0x01c8, 0x080c, 0xd02a, 0x6037,
 	0x4000, 0x6014, 0x6017, 0x0000, 0x0096, 0x2048, 0xa87c, 0x080c,
-	0xce8e, 0x1118, 0x080c, 0xb905, 0x0040, 0xa867, 0x0103, 0xa877,
-	0x0000, 0x83ff, 0x1129, 0x080c, 0x6d17, 0x009e, 0x003e, 0x0005,
+	0xd047, 0x1118, 0x080c, 0xbacb, 0x0040, 0xa867, 0x0103, 0xa877,
+	0x0000, 0x83ff, 0x1129, 0x080c, 0x6dcb, 0x009e, 0x003e, 0x0005,
 	0xa880, 0xd0b4, 0x0128, 0xa87b, 0x0006, 0xc0ec, 0xa882, 0x0048,
 	0xd0bc, 0x0118, 0xa87b, 0x0002, 0x0020, 0xa87b, 0x0005, 0x080c,
-	0xcf82, 0xa877, 0x0000, 0x0005, 0x2001, 0x1810, 0x2004, 0xd0ec,
+	0xd13b, 0xa877, 0x0000, 0x0005, 0x2001, 0x1810, 0x2004, 0xd0ec,
 	0x0005, 0x0006, 0x2001, 0x1810, 0x2004, 0xd0f4, 0x000e, 0x0005,
 	0x0006, 0x2001, 0x1810, 0x2004, 0xd0e4, 0x000e, 0x0005, 0x0036,
 	0x0046, 0x6010, 0x00b6, 0x2058, 0xbba0, 0x00be, 0x2021, 0x0007,
-	0x080c, 0x4d36, 0x004e, 0x003e, 0x0005, 0x0c51, 0x1d81, 0x0005,
-	0x2001, 0x1985, 0x2004, 0x601a, 0x0005, 0x2001, 0x1987, 0x2004,
-	0x6042, 0x0005, 0x080c, 0xaf43, 0x0804, 0x9763, 0x00b6, 0x0066,
-	0x6000, 0x90b2, 0x0016, 0x1a0c, 0x0dd5, 0x001b, 0x006e, 0x00be,
-	0x0005, 0xd3c9, 0xdaf8, 0xdc55, 0xd3c9, 0xd3c9, 0xd3c9, 0xd3c9,
-	0xd3c9, 0xd400, 0xdcd9, 0xd3c9, 0xd3c9, 0xd3c9, 0xd3c9, 0xd3c9,
-	0xd3c9, 0x080c, 0x0dd5, 0x0066, 0x6000, 0x90b2, 0x0016, 0x1a0c,
-	0x0dd5, 0x0013, 0x006e, 0x0005, 0xd3e4, 0xe24b, 0xd3e4, 0xd3e4,
-	0xd3e4, 0xd3e4, 0xd3e4, 0xd3e4, 0xe1f8, 0xe29f, 0xd3e4, 0xe8c4,
-	0xe8fa, 0xe8c4, 0xe8fa, 0xd3e4, 0x080c, 0x0dd5, 0x6000, 0x9082,
-	0x0016, 0x1a0c, 0x0dd5, 0x6000, 0x000a, 0x0005, 0xd3fe, 0xdeb7,
-	0xdfa9, 0xdfcc, 0xe08c, 0xd3fe, 0xe16b, 0xe114, 0xdce5, 0xe1ce,
-	0xe1e3, 0xd3fe, 0xd3fe, 0xd3fe, 0xd3fe, 0xd3fe, 0x080c, 0x0dd5,
-	0x91b2, 0x0053, 0x1a0c, 0x0dd5, 0x2100, 0x91b2, 0x0040, 0x1a04,
-	0xd86c, 0x0002, 0xd44a, 0xd63a, 0xd44a, 0xd44a, 0xd44a, 0xd643,
-	0xd44a, 0xd44a, 0xd44a, 0xd44a, 0xd44a, 0xd44a, 0xd44a, 0xd44a,
-	0xd44a, 0xd44a, 0xd44a, 0xd44a, 0xd44a, 0xd44a, 0xd44a, 0xd44a,
-	0xd44a, 0xd44c, 0xd4af, 0xd4be, 0xd522, 0xd54d, 0xd5c6, 0xd625,
-	0xd44a, 0xd44a, 0xd646, 0xd44a, 0xd44a, 0xd65b, 0xd668, 0xd44a,
-	0xd44a, 0xd44a, 0xd44a, 0xd44a, 0xd70e, 0xd44a, 0xd44a, 0xd722,
-	0xd44a, 0xd44a, 0xd6dd, 0xd44a, 0xd44a, 0xd44a, 0xd73a, 0xd44a,
-	0xd44a, 0xd44a, 0xd7b7, 0xd44a, 0xd44a, 0xd44a, 0xd44a, 0xd44a,
-	0xd44a, 0xd834, 0x080c, 0x0dd5, 0x080c, 0x69ca, 0x1150, 0x2001,
-	0x1837, 0x2004, 0xd0cc, 0x1128, 0x9084, 0x0009, 0x9086, 0x0008,
-	0x1140, 0x6007, 0x0009, 0x602f, 0x0009, 0x6017, 0x0000, 0x0804,
-	0xd633, 0x080c, 0x6966, 0x00e6, 0x00c6, 0x0036, 0x0026, 0x0016,
-	0x6210, 0x2258, 0xbaa0, 0x0026, 0x2019, 0x0029, 0x080c, 0x9356,
-	0x0076, 0x903e, 0x080c, 0x9229, 0x2c08, 0x080c, 0xe477, 0x007e,
-	0x001e, 0x001e, 0x002e, 0x003e, 0x00ce, 0x00ee, 0x6610, 0x2658,
-	0x080c, 0x66a8, 0xbe04, 0x9684, 0x00ff, 0x9082, 0x0006, 0x1268,
-	0x0016, 0x0026, 0x6210, 0x00b6, 0x2258, 0xbaa0, 0x00be, 0x2c08,
-	0x080c, 0xeb23, 0x002e, 0x001e, 0x1178, 0x080c, 0xe3a9, 0x1904,
-	0xd51a, 0x080c, 0xe345, 0x1120, 0x6007, 0x0008, 0x0804, 0xd633,
-	0x6007, 0x0009, 0x0804, 0xd633, 0x080c, 0xe5cd, 0x0128, 0x080c,
-	0xe3a9, 0x0d78, 0x0804, 0xd51a, 0x6017, 0x1900, 0x0c88, 0x080c,
-	0x3342, 0x1904, 0xd869, 0x6106, 0x080c, 0xe2fa, 0x6007, 0x0006,
-	0x0804, 0xd633, 0x6007, 0x0007, 0x0804, 0xd633, 0x080c, 0xe936,
-	0x1904, 0xd869, 0x080c, 0x3342, 0x1904, 0xd869, 0x00d6, 0x6610,
-	0x2658, 0xbe04, 0x9684, 0x00ff, 0x9082, 0x0006, 0x1220, 0x2001,
-	0x0001, 0x080c, 0x65d5, 0x96b4, 0xff00, 0x8637, 0x9686, 0x0006,
-	0x0188, 0x9686, 0x0004, 0x0170, 0xbe04, 0x96b4, 0x00ff, 0x9686,
-	0x0006, 0x0140, 0x9686, 0x0004, 0x0128, 0x9686, 0x0005, 0x0110,
-	0x00de, 0x0480, 0x00e6, 0x2071, 0x0260, 0x7034, 0x9084, 0x0003,
-	0x1140, 0x7034, 0x9082, 0x0014, 0x0220, 0x7030, 0x9084, 0x0003,
-	0x0130, 0x00ee, 0x6017, 0x0000, 0x602f, 0x0007, 0x00b0, 0x00ee,
-	0x080c, 0xe40d, 0x1190, 0x9686, 0x0006, 0x1140, 0x0026, 0x6210,
-	0x2258, 0xbaa0, 0x900e, 0x080c, 0x3267, 0x002e, 0x080c, 0x6734,
-	0x6007, 0x000a, 0x00de, 0x0804, 0xd633, 0x6007, 0x000b, 0x00de,
-	0x0804, 0xd633, 0x080c, 0x321e, 0x080c, 0xd39d, 0x6007, 0x0001,
-	0x0804, 0xd633, 0x080c, 0xe936, 0x1904, 0xd869, 0x080c, 0x3342,
-	0x1904, 0xd869, 0x2071, 0x0260, 0x7034, 0x90b4, 0x0003, 0x1948,
-	0x90b2, 0x0014, 0x0a30, 0x7030, 0x9084, 0x0003, 0x1910, 0x6610,
-	0x2658, 0xbe04, 0x9686, 0x0707, 0x09e8, 0x0026, 0x6210, 0x2258,
-	0xbaa0, 0x900e, 0x080c, 0x3267, 0x002e, 0x6007, 0x000c, 0x2001,
-	0x0001, 0x080c, 0xeb03, 0x0804, 0xd633, 0x080c, 0x69ca, 0x1140,
-	0x2001, 0x1837, 0x2004, 0x9084, 0x0009, 0x9086, 0x0008, 0x1110,
-	0x0804, 0xd459, 0x080c, 0x6966, 0x6610, 0x2658, 0xbe04, 0x9684,
-	0x00ff, 0x9082, 0x0006, 0x06c8, 0x1138, 0x0026, 0x2001, 0x0006,
-	0x080c, 0x6615, 0x002e, 0x0050, 0x96b4, 0xff00, 0x8637, 0x9686,
-	0x0004, 0x0120, 0x9686, 0x0006, 0x1904, 0xd51a, 0x080c, 0xe41a,
-	0x1120, 0x6007, 0x000e, 0x0804, 0xd633, 0x0046, 0x6410, 0x2458,
-	0xbca0, 0x0046, 0x080c, 0x321e, 0x080c, 0xd39d, 0x004e, 0x0016,
-	0x9006, 0x2009, 0x1848, 0x210c, 0xd1a4, 0x0148, 0x2009, 0x0029,
-	0x080c, 0xe73a, 0x6010, 0x2058, 0xb800, 0xc0e5, 0xb802, 0x001e,
-	0x004e, 0x6007, 0x0001, 0x0804, 0xd633, 0x2001, 0x0001, 0x080c,
-	0x65d5, 0x0156, 0x0016, 0x0026, 0x0036, 0x20a9, 0x0004, 0x2019,
-	0x1805, 0x2011, 0x0270, 0x080c, 0xbefd, 0x003e, 0x002e, 0x001e,
-	0x015e, 0x9005, 0x0168, 0x96b4, 0xff00, 0x8637, 0x9682, 0x0004,
-	0x0a04, 0xd51a, 0x9682, 0x0007, 0x0a04, 0xd576, 0x0804, 0xd51a,
-	0x6017, 0x1900, 0x6007, 0x0009, 0x0804, 0xd633, 0x080c, 0x69ca,
-	0x1140, 0x2001, 0x1837, 0x2004, 0x9084, 0x0009, 0x9086, 0x0008,
-	0x1110, 0x0804, 0xd459, 0x080c, 0x6966, 0x6610, 0x2658, 0xbe04,
-	0x9684, 0x00ff, 0x0006, 0x9086, 0x0001, 0x000e, 0x0170, 0x9082,
-	0x0006, 0x0698, 0x0150, 0x96b4, 0xff00, 0x8637, 0x9686, 0x0004,
-	0x0120, 0x9686, 0x0006, 0x1904, 0xd51a, 0x080c, 0xe448, 0x1130,
-	0x080c, 0xe345, 0x1118, 0x6007, 0x0010, 0x04e8, 0x0046, 0x6410,
-	0x2458, 0xbca0, 0x0046, 0x080c, 0x321e, 0x080c, 0xd39d, 0x004e,
-	0x0016, 0x9006, 0x2009, 0x1848, 0x210c, 0xd1a4, 0x0148, 0x2009,
-	0x0029, 0x080c, 0xe73a, 0x6010, 0x2058, 0xb800, 0xc0e5, 0xb802,
-	0x001e, 0x004e, 0x6007, 0x0001, 0x00f0, 0x080c, 0xe5cd, 0x0140,
-	0x96b4, 0xff00, 0x8637, 0x9686, 0x0006, 0x0978, 0x0804, 0xd51a,
-	0x6017, 0x1900, 0x6007, 0x0009, 0x0070, 0x080c, 0x3342, 0x1904,
-	0xd869, 0x080c, 0xe936, 0x1904, 0xd869, 0x080c, 0xda36, 0x1904,
-	0xd51a, 0x6007, 0x0012, 0x6003, 0x0001, 0x080c, 0x91f9, 0x080c,
-	0x9763, 0x0005, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c, 0x91f9,
-	0x080c, 0x9763, 0x0cb0, 0x6007, 0x0005, 0x0c68, 0x080c, 0xe936,
-	0x1904, 0xd869, 0x080c, 0x3342, 0x1904, 0xd869, 0x080c, 0xda36,
-	0x1904, 0xd51a, 0x6007, 0x0020, 0x6003, 0x0001, 0x080c, 0x91f9,
-	0x080c, 0x9763, 0x0005, 0x080c, 0x3342, 0x1904, 0xd869, 0x6007,
-	0x0023, 0x6003, 0x0001, 0x080c, 0x91f9, 0x080c, 0x9763, 0x0005,
-	0x080c, 0xe936, 0x1904, 0xd869, 0x080c, 0x3342, 0x1904, 0xd869,
-	0x080c, 0xda36, 0x1904, 0xd51a, 0x0016, 0x0026, 0x00e6, 0x2071,
-	0x0260, 0x2c08, 0x2011, 0x1820, 0x2214, 0x703c, 0x9206, 0x11e0,
-	0x2011, 0x181f, 0x2214, 0x7038, 0x9084, 0x00ff, 0x9206, 0x11a0,
-	0x7240, 0x080c, 0xcc74, 0x0570, 0x2260, 0x6008, 0x9086, 0xffff,
-	0x0120, 0x7244, 0x6008, 0x9206, 0x1528, 0x6020, 0x9086, 0x0007,
-	0x1508, 0x080c, 0xaf43, 0x04a0, 0x7244, 0x9286, 0xffff, 0x0180,
-	0x2c08, 0x080c, 0xcc74, 0x01b0, 0x2260, 0x7240, 0x6008, 0x9206,
-	0x1188, 0x6010, 0x9190, 0x0004, 0x2214, 0x9206, 0x01b8, 0x0050,
-	0x7240, 0x2c08, 0x9006, 0x080c, 0xe704, 0x1180, 0x7244, 0x9286,
-	0xffff, 0x01b0, 0x2160, 0x6007, 0x0026, 0x6017, 0x1700, 0x7214,
-	0x9296, 0xffff, 0x1180, 0x6007, 0x0025, 0x0068, 0x6020, 0x9086,
-	0x0007, 0x1d80, 0x6004, 0x9086, 0x0024, 0x1110, 0x080c, 0xaf43,
-	0x2160, 0x6007, 0x0025, 0x6003, 0x0001, 0x080c, 0x91f9, 0x080c,
-	0x9763, 0x00ee, 0x002e, 0x001e, 0x0005, 0x2001, 0x0001, 0x080c,
-	0x65d5, 0x0156, 0x0016, 0x0026, 0x0036, 0x20a9, 0x0004, 0x2019,
-	0x1805, 0x2011, 0x0276, 0x080c, 0xbefd, 0x003e, 0x002e, 0x001e,
-	0x015e, 0x0120, 0x6007, 0x0031, 0x0804, 0xd633, 0x080c, 0xbb71,
-	0x080c, 0x743e, 0x1190, 0x0006, 0x0026, 0x0036, 0x080c, 0x7458,
-	0x1138, 0x080c, 0x7724, 0x080c, 0x60ad, 0x080c, 0x736a, 0x0010,
-	0x080c, 0x7416, 0x003e, 0x002e, 0x000e, 0x0005, 0x080c, 0x3342,
-	0x1904, 0xd869, 0x080c, 0xda36, 0x1904, 0xd51a, 0x6106, 0x080c,
-	0xda52, 0x1120, 0x6007, 0x002b, 0x0804, 0xd633, 0x6007, 0x002c,
-	0x0804, 0xd633, 0x080c, 0xe936, 0x1904, 0xd869, 0x080c, 0x3342,
-	0x1904, 0xd869, 0x080c, 0xda36, 0x1904, 0xd51a, 0x6106, 0x080c,
-	0xda57, 0x1120, 0x6007, 0x002e, 0x0804, 0xd633, 0x6007, 0x002f,
-	0x0804, 0xd633, 0x080c, 0x3342, 0x1904, 0xd869, 0x00e6, 0x00d6,
-	0x00c6, 0x6010, 0x2058, 0xb904, 0x9184, 0x00ff, 0x9086, 0x0006,
-	0x0158, 0x9184, 0xff00, 0x8007, 0x9086, 0x0006, 0x0128, 0x00ce,
-	0x00de, 0x00ee, 0x0804, 0xd63a, 0x080c, 0x5761, 0xd0e4, 0x0904,
-	0xd7b4, 0x2071, 0x026c, 0x7010, 0x603a, 0x7014, 0x603e, 0x7108,
-	0x720c, 0x080c, 0x6a08, 0x0140, 0x6010, 0x2058, 0xb810, 0x9106,
-	0x1118, 0xb814, 0x9206, 0x0510, 0x080c, 0x6a04, 0x15b8, 0x2069,
-	0x1800, 0x6880, 0x9206, 0x1590, 0x687c, 0x9106, 0x1578, 0x7210,
-	0x080c, 0xcc74, 0x0590, 0x080c, 0xd921, 0x0578, 0x080c, 0xe7b6,
-	0x0560, 0x622e, 0x6007, 0x0036, 0x6003, 0x0001, 0x080c, 0x91b1,
-	0x080c, 0x9763, 0x00ce, 0x00de, 0x00ee, 0x0005, 0x7214, 0x9286,
-	0xffff, 0x0150, 0x080c, 0xcc74, 0x01c0, 0x9280, 0x0002, 0x2004,
-	0x7110, 0x9106, 0x1190, 0x08e0, 0x7210, 0x2c08, 0x9085, 0x0001,
-	0x080c, 0xe704, 0x2c10, 0x2160, 0x0140, 0x0890, 0x6007, 0x0037,
-	0x602f, 0x0009, 0x6017, 0x1500, 0x08b8, 0x6007, 0x0037, 0x602f,
-	0x0003, 0x6017, 0x1700, 0x0880, 0x6007, 0x0012, 0x0868, 0x080c,
-	0x3342, 0x1904, 0xd869, 0x6010, 0x2058, 0xb804, 0x9084, 0xff00,
-	0x8007, 0x9086, 0x0006, 0x1904, 0xd63a, 0x00e6, 0x00d6, 0x00c6,
-	0x080c, 0x5761, 0xd0e4, 0x0904, 0xd82c, 0x2069, 0x1800, 0x2071,
-	0x026c, 0x7008, 0x603a, 0x720c, 0x623e, 0x9286, 0xffff, 0x1150,
-	0x7208, 0x00c6, 0x2c08, 0x9085, 0x0001, 0x080c, 0xe704, 0x2c10,
-	0x00ce, 0x05e8, 0x080c, 0xcc74, 0x05d0, 0x7108, 0x9280, 0x0002,
-	0x2004, 0x9106, 0x15a0, 0x00c6, 0x0026, 0x2260, 0x080c, 0xc898,
-	0x002e, 0x00ce, 0x7118, 0x918c, 0xff00, 0x810f, 0x9186, 0x0001,
-	0x0178, 0x9186, 0x0005, 0x0118, 0x9186, 0x0007, 0x1198, 0x9280,
-	0x0005, 0x2004, 0x9005, 0x0170, 0x080c, 0xd921, 0x0904, 0xd7ad,
-	0x0056, 0x7510, 0x7614, 0x080c, 0xe7cf, 0x005e, 0x00ce, 0x00de,
-	0x00ee, 0x0005, 0x6007, 0x003b, 0x602f, 0x0009, 0x6017, 0x2a00,
-	0x6003, 0x0001, 0x080c, 0x91b1, 0x080c, 0x9763, 0x0c78, 0x6007,
-	0x003b, 0x602f, 0x0003, 0x6017, 0x0300, 0x6003, 0x0001, 0x080c,
-	0x91b1, 0x080c, 0x9763, 0x0c10, 0x6007, 0x003b, 0x602f, 0x000b,
-	0x6017, 0x0000, 0x0804, 0xd784, 0x00e6, 0x0026, 0x080c, 0x69ca,
-	0x0550, 0x080c, 0x6966, 0x080c, 0xe9a8, 0x1518, 0x2071, 0x1800,
-	0x70dc, 0x9085, 0x0003, 0x70de, 0x00f6, 0x2079, 0x0100, 0x72b0,
-	0x9284, 0x00ff, 0x707e, 0x78e6, 0x9284, 0xff00, 0x7280, 0x9205,
-	0x7082, 0x78ea, 0x00fe, 0x70e7, 0x0000, 0x080c, 0x6a08, 0x0120,
-	0x2011, 0x19ff, 0x2013, 0x07d0, 0xd0ac, 0x1128, 0x080c, 0x2ff5,
-	0x0010, 0x080c, 0xe9da, 0x002e, 0x00ee, 0x080c, 0xaf43, 0x0804,
-	0xd639, 0x080c, 0xaf43, 0x0005, 0x2600, 0x0002, 0xd880, 0xd8b1,
-	0xd8c2, 0xd880, 0xd880, 0xd882, 0xd8d3, 0xd880, 0xd880, 0xd880,
-	0xd89f, 0xd880, 0xd880, 0xd880, 0xd8de, 0xd8eb, 0xd91c, 0xd880,
-	0x080c, 0x0dd5, 0x080c, 0xe936, 0x1d20, 0x080c, 0x3342, 0x1d08,
-	0x080c, 0xda36, 0x1148, 0x7038, 0x6016, 0x6007, 0x0045, 0x6003,
-	0x0001, 0x080c, 0x91f9, 0x0005, 0x080c, 0x321e, 0x080c, 0xd39d,
-	0x6007, 0x0001, 0x6003, 0x0001, 0x080c, 0x91f9, 0x0005, 0x080c,
-	0xe936, 0x1938, 0x080c, 0x3342, 0x1920, 0x080c, 0xda36, 0x1d60,
-	0x703c, 0x6016, 0x6007, 0x004a, 0x6003, 0x0001, 0x080c, 0x91f9,
-	0x0005, 0x080c, 0x3342, 0x1904, 0xd869, 0x2009, 0x0041, 0x080c,
-	0xe9e3, 0x6007, 0x0047, 0x6003, 0x0001, 0x080c, 0x91f9, 0x080c,
-	0x9763, 0x0005, 0x080c, 0x3342, 0x1904, 0xd869, 0x2009, 0x0042,
-	0x080c, 0xe9e3, 0x6007, 0x0047, 0x6003, 0x0001, 0x080c, 0x91f9,
-	0x080c, 0x9763, 0x0005, 0x080c, 0x3342, 0x1904, 0xd869, 0x2009,
-	0x0046, 0x080c, 0xe9e3, 0x080c, 0xaf43, 0x0005, 0x080c, 0xd93e,
-	0x0904, 0xd869, 0x6007, 0x004e, 0x6003, 0x0001, 0x080c, 0x91f9,
-	0x080c, 0x9763, 0x0005, 0x6007, 0x004f, 0x6017, 0x0000, 0x7134,
-	0x918c, 0x00ff, 0x81ff, 0x0508, 0x9186, 0x0001, 0x1160, 0x7140,
-	0x2001, 0x19bc, 0x2004, 0x9106, 0x11b0, 0x7144, 0x2001, 0x19bd,
-	0x2004, 0x9106, 0x0190, 0x9186, 0x0002, 0x1168, 0x2011, 0x0276,
-	0x20a9, 0x0004, 0x6010, 0x0096, 0x2048, 0x2019, 0x000a, 0x080c,
-	0xbf11, 0x009e, 0x0110, 0x6017, 0x0001, 0x6003, 0x0001, 0x080c,
-	0x91f9, 0x080c, 0x9763, 0x0005, 0x6007, 0x0050, 0x703c, 0x6016,
-	0x0ca0, 0x0016, 0x00e6, 0x2071, 0x0260, 0x00b6, 0x00c6, 0x2260,
-	0x6010, 0x2058, 0xb8cc, 0xd084, 0x0150, 0x7128, 0x6044, 0x9106,
-	0x1120, 0x712c, 0x6048, 0x9106, 0x0110, 0x9006, 0x0010, 0x9085,
-	0x0001, 0x00ce, 0x00be, 0x00ee, 0x001e, 0x0005, 0x0016, 0x0096,
-	0x0086, 0x00e6, 0x01c6, 0x01d6, 0x0126, 0x2091, 0x8000, 0x2071,
-	0x1800, 0x7090, 0x908a, 0x00f9, 0x16e8, 0x20e1, 0x0000, 0x2001,
-	0x199f, 0x2003, 0x0000, 0x080c, 0x1018, 0x05a0, 0x2900, 0x6016,
+	0x080c, 0x4d9a, 0x004e, 0x003e, 0x0005, 0x0c51, 0x1d81, 0x0005,
+	0x2001, 0x1987, 0x2004, 0x601a, 0x0005, 0x2001, 0x1989, 0x2004,
+	0x6042, 0x0005, 0x080c, 0xb0e7, 0x0804, 0x98e7, 0x2001, 0x0109,
+	0x2004, 0xd084, 0x01e0, 0x0126, 0x2091, 0x2800, 0x0006, 0x0016,
+	0x0026, 0x0036, 0x00f6, 0x00e6, 0x00c6, 0x2079, 0x19e9, 0x2071,
+	0x1800, 0x2061, 0x0100, 0x080c, 0x9218, 0x00ce, 0x00ee, 0x00fe,
+	0x003e, 0x002e, 0x001e, 0x000e, 0x012e, 0x9085, 0x0001, 0x0005,
+	0x00b6, 0x0066, 0x6000, 0x90b2, 0x0016, 0x1a0c, 0x0dc5, 0x001b,
+	0x006e, 0x00be, 0x0005, 0xd5ab, 0xdcf2, 0xde72, 0xd5ab, 0xd5ab,
+	0xd5ab, 0xd5ab, 0xd5ab, 0xd5e2, 0xdef6, 0xd5ab, 0xd5ab, 0xd5ab,
+	0xd5ab, 0xd5ab, 0xd5ab, 0x080c, 0x0dc5, 0x0066, 0x6000, 0x90b2,
+	0x0016, 0x1a0c, 0x0dc5, 0x0013, 0x006e, 0x0005, 0xd5c6, 0xe445,
+	0xd5c6, 0xd5c6, 0xd5c6, 0xd5c6, 0xd5c6, 0xd5c6, 0xe3f2, 0xe499,
+	0xd5c6, 0xeaca, 0xeb00, 0xeaca, 0xeb00, 0xd5c6, 0x080c, 0x0dc5,
+	0x6000, 0x9082, 0x0016, 0x1a0c, 0x0dc5, 0x6000, 0x000a, 0x0005,
+	0xd5e0, 0xe0d4, 0xe1a3, 0xe1c6, 0xe286, 0xd5e0, 0xe365, 0xe30e,
+	0xdf02, 0xe3c8, 0xe3dd, 0xd5e0, 0xd5e0, 0xd5e0, 0xd5e0, 0xd5e0,
+	0x080c, 0x0dc5, 0x91b2, 0x0053, 0x1a0c, 0x0dc5, 0x2100, 0x91b2,
+	0x0040, 0x1a04, 0xda62, 0x0002, 0xd62c, 0xd830, 0xd62c, 0xd62c,
+	0xd62c, 0xd839, 0xd62c, 0xd62c, 0xd62c, 0xd62c, 0xd62c, 0xd62c,
+	0xd62c, 0xd62c, 0xd62c, 0xd62c, 0xd62c, 0xd62c, 0xd62c, 0xd62c,
+	0xd62c, 0xd62c, 0xd62c, 0xd62e, 0xd691, 0xd6a0, 0xd704, 0xd72f,
+	0xd7a8, 0xd81b, 0xd62c, 0xd62c, 0xd83c, 0xd62c, 0xd62c, 0xd851,
+	0xd85e, 0xd62c, 0xd62c, 0xd62c, 0xd62c, 0xd62c, 0xd904, 0xd62c,
+	0xd62c, 0xd918, 0xd62c, 0xd62c, 0xd8d3, 0xd62c, 0xd62c, 0xd62c,
+	0xd930, 0xd62c, 0xd62c, 0xd62c, 0xd9ad, 0xd62c, 0xd62c, 0xd62c,
+	0xd62c, 0xd62c, 0xd62c, 0xda2a, 0x080c, 0x0dc5, 0x080c, 0x6a4a,
+	0x1150, 0x2001, 0x1837, 0x2004, 0xd0cc, 0x1128, 0x9084, 0x0009,
+	0x9086, 0x0008, 0x1140, 0x6007, 0x0009, 0x602f, 0x0009, 0x6017,
+	0x0000, 0x0804, 0xd829, 0x080c, 0x69e6, 0x00e6, 0x00c6, 0x0036,
+	0x0026, 0x0016, 0x6210, 0x2258, 0xbaa0, 0x0026, 0x2019, 0x0029,
+	0x080c, 0x94da, 0x0076, 0x903e, 0x080c, 0x93ad, 0x2c08, 0x080c,
+	0xe671, 0x007e, 0x001e, 0x001e, 0x002e, 0x003e, 0x00ce, 0x00ee,
+	0x6610, 0x2658, 0x080c, 0x6726, 0xbe04, 0x9684, 0x00ff, 0x9082,
+	0x0006, 0x1268, 0x0016, 0x0026, 0x6210, 0x00b6, 0x2258, 0xbaa0,
+	0x00be, 0x2c08, 0x080c, 0xed2b, 0x002e, 0x001e, 0x1178, 0x080c,
+	0xe5a3, 0x1904, 0xd6fc, 0x080c, 0xe53f, 0x1120, 0x6007, 0x0008,
+	0x0804, 0xd829, 0x6007, 0x0009, 0x0804, 0xd829, 0x080c, 0xe7c8,
+	0x0128, 0x080c, 0xe5a3, 0x0d78, 0x0804, 0xd6fc, 0x6017, 0x1900,
+	0x0c88, 0x080c, 0x336f, 0x1904, 0xda5f, 0x6106, 0x080c, 0xe4f4,
+	0x6007, 0x0006, 0x0804, 0xd829, 0x6007, 0x0007, 0x0804, 0xd829,
+	0x080c, 0xeb3c, 0x1904, 0xda5f, 0x080c, 0x336f, 0x1904, 0xda5f,
+	0x00d6, 0x6610, 0x2658, 0xbe04, 0x9684, 0x00ff, 0x9082, 0x0006,
+	0x1220, 0x2001, 0x0001, 0x080c, 0x6649, 0x96b4, 0xff00, 0x8637,
+	0x9686, 0x0006, 0x0188, 0x9686, 0x0004, 0x0170, 0xbe04, 0x96b4,
+	0x00ff, 0x9686, 0x0006, 0x0140, 0x9686, 0x0004, 0x0128, 0x9686,
+	0x0005, 0x0110, 0x00de, 0x0480, 0x00e6, 0x2071, 0x0260, 0x7034,
+	0x9084, 0x0003, 0x1140, 0x7034, 0x9082, 0x0014, 0x0220, 0x7030,
+	0x9084, 0x0003, 0x0130, 0x00ee, 0x6017, 0x0000, 0x602f, 0x0007,
+	0x00b0, 0x00ee, 0x080c, 0xe607, 0x1190, 0x9686, 0x0006, 0x1140,
+	0x0026, 0x6210, 0x2258, 0xbaa0, 0x900e, 0x080c, 0x3294, 0x002e,
+	0x080c, 0x67b2, 0x6007, 0x000a, 0x00de, 0x0804, 0xd829, 0x6007,
+	0x000b, 0x00de, 0x0804, 0xd829, 0x080c, 0x324b, 0x080c, 0xd55d,
+	0x6007, 0x0001, 0x0804, 0xd829, 0x080c, 0xeb3c, 0x1904, 0xda5f,
+	0x080c, 0x336f, 0x1904, 0xda5f, 0x2071, 0x0260, 0x7034, 0x90b4,
+	0x0003, 0x1948, 0x90b2, 0x0014, 0x0a30, 0x7030, 0x9084, 0x0003,
+	0x1910, 0x6610, 0x2658, 0xbe04, 0x9686, 0x0707, 0x09e8, 0x0026,
+	0x6210, 0x2258, 0xbaa0, 0x900e, 0x080c, 0x3294, 0x002e, 0x6007,
+	0x000c, 0x2001, 0x0001, 0x080c, 0xed0a, 0x0804, 0xd829, 0x080c,
+	0x6a4a, 0x1140, 0x2001, 0x1837, 0x2004, 0x9084, 0x0009, 0x9086,
+	0x0008, 0x1110, 0x0804, 0xd63b, 0x080c, 0x69e6, 0x6610, 0x2658,
+	0xbe04, 0x9684, 0x00ff, 0x9082, 0x0006, 0x06c8, 0x1138, 0x0026,
+	0x2001, 0x0006, 0x080c, 0x6689, 0x002e, 0x0050, 0x96b4, 0xff00,
+	0x8637, 0x9686, 0x0004, 0x0120, 0x9686, 0x0006, 0x1904, 0xd6fc,
+	0x080c, 0xe614, 0x1120, 0x6007, 0x000e, 0x0804, 0xd829, 0x0046,
+	0x6410, 0x2458, 0xbca0, 0x0046, 0x080c, 0x324b, 0x080c, 0xd55d,
+	0x004e, 0x0016, 0x9006, 0x2009, 0x1848, 0x210c, 0xd1a4, 0x0148,
+	0x2009, 0x0029, 0x080c, 0xe940, 0x6010, 0x2058, 0xb800, 0xc0e5,
+	0xb802, 0x001e, 0x004e, 0x6007, 0x0001, 0x0804, 0xd829, 0x2001,
+	0x0001, 0x080c, 0x6649, 0x0156, 0x0016, 0x0026, 0x0036, 0x20a9,
+	0x0004, 0x2019, 0x1805, 0x2011, 0x0270, 0x080c, 0xc0d3, 0x003e,
+	0x002e, 0x001e, 0x015e, 0x9005, 0x0168, 0x96b4, 0xff00, 0x8637,
+	0x9682, 0x0004, 0x0a04, 0xd6fc, 0x9682, 0x0007, 0x0a04, 0xd758,
+	0x0804, 0xd6fc, 0x6017, 0x1900, 0x6007, 0x0009, 0x0804, 0xd829,
+	0x080c, 0x6a4a, 0x1140, 0x2001, 0x1837, 0x2004, 0x9084, 0x0009,
+	0x9086, 0x0008, 0x1110, 0x0804, 0xd63b, 0x080c, 0x69e6, 0x6610,
+	0x2658, 0xbe04, 0x9684, 0x00ff, 0x0006, 0x0016, 0x908e, 0x0001,
+	0x0118, 0x908e, 0x0000, 0x1118, 0x001e, 0x000e, 0x0080, 0x001e,
+	0x000e, 0x9082, 0x0006, 0x06a0, 0x0150, 0x96b4, 0xff00, 0x8637,
+	0x9686, 0x0004, 0x0120, 0x9686, 0x0006, 0x1904, 0xd6fc, 0x080c,
+	0xe642, 0x1138, 0x080c, 0xe53f, 0x1120, 0x6007, 0x0010, 0x0804,
+	0xd829, 0x0046, 0x6410, 0x2458, 0xbca0, 0x0046, 0x080c, 0x324b,
+	0x080c, 0xd55d, 0x004e, 0x0016, 0x9006, 0x2009, 0x1848, 0x210c,
+	0xd1a4, 0x0148, 0x2009, 0x0029, 0x080c, 0xe940, 0x6010, 0x2058,
+	0xb800, 0xc0e5, 0xb802, 0x001e, 0x004e, 0x6007, 0x0001, 0x0448,
+	0x080c, 0xe7c8, 0x0198, 0x0016, 0x968c, 0x00ff, 0x9186, 0x0002,
+	0x0160, 0x9186, 0x0003, 0x0148, 0x001e, 0x96b4, 0xff00, 0x8637,
+	0x9686, 0x0006, 0x0920, 0x0804, 0xd6fc, 0x001e, 0x6017, 0x1900,
+	0x6007, 0x0009, 0x0070, 0x080c, 0x336f, 0x1904, 0xda5f, 0x080c,
+	0xeb3c, 0x1904, 0xda5f, 0x080c, 0xdc30, 0x1904, 0xd6fc, 0x6007,
+	0x0012, 0x6003, 0x0001, 0x080c, 0x937d, 0x080c, 0x98e7, 0x0005,
+	0x6007, 0x0001, 0x6003, 0x0001, 0x080c, 0x937d, 0x080c, 0x98e7,
+	0x0cb0, 0x6007, 0x0005, 0x0c68, 0x080c, 0xeb3c, 0x1904, 0xda5f,
+	0x080c, 0x336f, 0x1904, 0xda5f, 0x080c, 0xdc30, 0x1904, 0xd6fc,
+	0x6007, 0x0020, 0x6003, 0x0001, 0x080c, 0x937d, 0x080c, 0x98e7,
+	0x0005, 0x080c, 0x336f, 0x1904, 0xda5f, 0x6007, 0x0023, 0x6003,
+	0x0001, 0x080c, 0x937d, 0x080c, 0x98e7, 0x0005, 0x080c, 0xeb3c,
+	0x1904, 0xda5f, 0x080c, 0x336f, 0x1904, 0xda5f, 0x080c, 0xdc30,
+	0x1904, 0xd6fc, 0x0016, 0x0026, 0x00e6, 0x2071, 0x0260, 0x2c08,
+	0x2011, 0x1820, 0x2214, 0x703c, 0x9206, 0x11e0, 0x2011, 0x181f,
+	0x2214, 0x7038, 0x9084, 0x00ff, 0x9206, 0x11a0, 0x7240, 0x080c,
+	0xce2d, 0x0570, 0x2260, 0x6008, 0x9086, 0xffff, 0x0120, 0x7244,
+	0x6008, 0x9206, 0x1528, 0x6020, 0x9086, 0x0007, 0x1508, 0x080c,
+	0xb0e7, 0x04a0, 0x7244, 0x9286, 0xffff, 0x0180, 0x2c08, 0x080c,
+	0xce2d, 0x01b0, 0x2260, 0x7240, 0x6008, 0x9206, 0x1188, 0x6010,
+	0x9190, 0x0004, 0x2214, 0x9206, 0x01b8, 0x0050, 0x7240, 0x2c08,
+	0x9006, 0x080c, 0xe90a, 0x1180, 0x7244, 0x9286, 0xffff, 0x01b0,
+	0x2160, 0x6007, 0x0026, 0x6017, 0x1700, 0x7214, 0x9296, 0xffff,
+	0x1180, 0x6007, 0x0025, 0x0068, 0x6020, 0x9086, 0x0007, 0x1d80,
+	0x6004, 0x9086, 0x0024, 0x1110, 0x080c, 0xb0e7, 0x2160, 0x6007,
+	0x0025, 0x6003, 0x0001, 0x080c, 0x937d, 0x080c, 0x98e7, 0x00ee,
+	0x002e, 0x001e, 0x0005, 0x2001, 0x0001, 0x080c, 0x6649, 0x0156,
+	0x0016, 0x0026, 0x0036, 0x20a9, 0x0004, 0x2019, 0x1805, 0x2011,
+	0x0276, 0x080c, 0xc0d3, 0x003e, 0x002e, 0x001e, 0x015e, 0x0120,
+	0x6007, 0x0031, 0x0804, 0xd829, 0x080c, 0xbd45, 0x080c, 0x7563,
+	0x1190, 0x0006, 0x0026, 0x0036, 0x080c, 0x757d, 0x1138, 0x080c,
+	0x7848, 0x080c, 0x6121, 0x080c, 0x748f, 0x0010, 0x080c, 0x753b,
+	0x003e, 0x002e, 0x000e, 0x0005, 0x080c, 0x336f, 0x1904, 0xda5f,
+	0x080c, 0xdc30, 0x1904, 0xd6fc, 0x6106, 0x080c, 0xdc4c, 0x1120,
+	0x6007, 0x002b, 0x0804, 0xd829, 0x6007, 0x002c, 0x0804, 0xd829,
+	0x080c, 0xeb3c, 0x1904, 0xda5f, 0x080c, 0x336f, 0x1904, 0xda5f,
+	0x080c, 0xdc30, 0x1904, 0xd6fc, 0x6106, 0x080c, 0xdc51, 0x1120,
+	0x6007, 0x002e, 0x0804, 0xd829, 0x6007, 0x002f, 0x0804, 0xd829,
+	0x080c, 0x336f, 0x1904, 0xda5f, 0x00e6, 0x00d6, 0x00c6, 0x6010,
+	0x2058, 0xb904, 0x9184, 0x00ff, 0x9086, 0x0006, 0x0158, 0x9184,
+	0xff00, 0x8007, 0x9086, 0x0006, 0x0128, 0x00ce, 0x00de, 0x00ee,
+	0x0804, 0xd830, 0x080c, 0x57d1, 0xd0e4, 0x0904, 0xd9aa, 0x2071,
+	0x026c, 0x7010, 0x603a, 0x7014, 0x603e, 0x7108, 0x720c, 0x080c,
+	0x6a88, 0x0140, 0x6010, 0x2058, 0xb810, 0x9106, 0x1118, 0xb814,
+	0x9206, 0x0510, 0x080c, 0x6a84, 0x15b8, 0x2069, 0x1800, 0x6880,
+	0x9206, 0x1590, 0x687c, 0x9106, 0x1578, 0x7210, 0x080c, 0xce2d,
+	0x0590, 0x080c, 0xdb1d, 0x0578, 0x080c, 0xe9bc, 0x0560, 0x622e,
+	0x6007, 0x0036, 0x6003, 0x0001, 0x080c, 0x9335, 0x080c, 0x98e7,
+	0x00ce, 0x00de, 0x00ee, 0x0005, 0x7214, 0x9286, 0xffff, 0x0150,
+	0x080c, 0xce2d, 0x01c0, 0x9280, 0x0002, 0x2004, 0x7110, 0x9106,
+	0x1190, 0x08e0, 0x7210, 0x2c08, 0x9085, 0x0001, 0x080c, 0xe90a,
+	0x2c10, 0x2160, 0x0140, 0x0890, 0x6007, 0x0037, 0x602f, 0x0009,
+	0x6017, 0x1500, 0x08b8, 0x6007, 0x0037, 0x602f, 0x0003, 0x6017,
+	0x1700, 0x0880, 0x6007, 0x0012, 0x0868, 0x080c, 0x336f, 0x1904,
+	0xda5f, 0x6010, 0x2058, 0xb804, 0x9084, 0xff00, 0x8007, 0x9086,
+	0x0006, 0x1904, 0xd830, 0x00e6, 0x00d6, 0x00c6, 0x080c, 0x57d1,
+	0xd0e4, 0x0904, 0xda22, 0x2069, 0x1800, 0x2071, 0x026c, 0x7008,
+	0x603a, 0x720c, 0x623e, 0x9286, 0xffff, 0x1150, 0x7208, 0x00c6,
+	0x2c08, 0x9085, 0x0001, 0x080c, 0xe90a, 0x2c10, 0x00ce, 0x05e8,
+	0x080c, 0xce2d, 0x05d0, 0x7108, 0x9280, 0x0002, 0x2004, 0x9106,
+	0x15a0, 0x00c6, 0x0026, 0x2260, 0x080c, 0xca51, 0x002e, 0x00ce,
+	0x7118, 0x918c, 0xff00, 0x810f, 0x9186, 0x0001, 0x0178, 0x9186,
+	0x0005, 0x0118, 0x9186, 0x0007, 0x1198, 0x9280, 0x0005, 0x2004,
+	0x9005, 0x0170, 0x080c, 0xdb1d, 0x0904, 0xd9a3, 0x0056, 0x7510,
+	0x7614, 0x080c, 0xe9d5, 0x005e, 0x00ce, 0x00de, 0x00ee, 0x0005,
+	0x6007, 0x003b, 0x602f, 0x0009, 0x6017, 0x2a00, 0x6003, 0x0001,
+	0x080c, 0x9335, 0x080c, 0x98e7, 0x0c78, 0x6007, 0x003b, 0x602f,
+	0x0003, 0x6017, 0x0300, 0x6003, 0x0001, 0x080c, 0x9335, 0x080c,
+	0x98e7, 0x0c10, 0x6007, 0x003b, 0x602f, 0x000b, 0x6017, 0x0000,
+	0x0804, 0xd97a, 0x00e6, 0x0026, 0x080c, 0x6a4a, 0x0550, 0x080c,
+	0x69e6, 0x080c, 0xebad, 0x1518, 0x2071, 0x1800, 0x70dc, 0x9085,
+	0x0003, 0x70de, 0x00f6, 0x2079, 0x0100, 0x72b0, 0x9284, 0x00ff,
+	0x707e, 0x78e6, 0x9284, 0xff00, 0x7280, 0x9205, 0x7082, 0x78ea,
+	0x00fe, 0x70e7, 0x0000, 0x080c, 0x6a88, 0x0120, 0x2011, 0x1a02,
+	0x2013, 0x07d0, 0xd0ac, 0x1128, 0x080c, 0x3022, 0x0010, 0x080c,
+	0xebe1, 0x002e, 0x00ee, 0x080c, 0xb0e7, 0x0804, 0xd82f, 0x080c,
+	0xb0e7, 0x0005, 0x2600, 0x0002, 0xda76, 0xdaa4, 0xdab5, 0xda76,
+	0xda76, 0xda78, 0xdac6, 0xda76, 0xda76, 0xda76, 0xda92, 0xda76,
+	0xda76, 0xda76, 0xdad1, 0xdae7, 0xdb18, 0xda76, 0x080c, 0x0dc5,
+	0x080c, 0xeb3c, 0x1d20, 0x080c, 0x336f, 0x1d08, 0x7038, 0x6016,
+	0x6007, 0x0045, 0x6003, 0x0001, 0x080c, 0x937d, 0x0005, 0x080c,
+	0x324b, 0x080c, 0xd55d, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c,
+	0x937d, 0x0005, 0x080c, 0xeb3c, 0x1950, 0x080c, 0x336f, 0x1938,
+	0x080c, 0xdc30, 0x1d60, 0x703c, 0x6016, 0x6007, 0x004a, 0x6003,
+	0x0001, 0x080c, 0x937d, 0x0005, 0x080c, 0x336f, 0x1904, 0xda5f,
+	0x2009, 0x0041, 0x080c, 0xebea, 0x6007, 0x0047, 0x6003, 0x0001,
+	0x080c, 0x937d, 0x080c, 0x98e7, 0x0005, 0x080c, 0x336f, 0x1904,
+	0xda5f, 0x2009, 0x0042, 0x080c, 0xebea, 0x6007, 0x0047, 0x6003,
+	0x0001, 0x080c, 0x937d, 0x080c, 0x98e7, 0x0005, 0x080c, 0x336f,
+	0x1904, 0xda5f, 0x2009, 0x0046, 0x080c, 0xebea, 0x080c, 0xb0e7,
+	0x0005, 0x2001, 0x1824, 0x2004, 0x9082, 0x00e1, 0x1268, 0x080c,
+	0xdb3a, 0x0904, 0xda5f, 0x6007, 0x004e, 0x6003, 0x0001, 0x080c,
+	0x937d, 0x080c, 0x98e7, 0x0005, 0x6007, 0x0012, 0x0cb0, 0x6007,
+	0x004f, 0x6017, 0x0000, 0x7134, 0x918c, 0x00ff, 0x81ff, 0x0508,
+	0x9186, 0x0001, 0x1160, 0x7140, 0x2001, 0x19bf, 0x2004, 0x9106,
+	0x11b0, 0x7144, 0x2001, 0x19c0, 0x2004, 0x9106, 0x0190, 0x9186,
+	0x0002, 0x1168, 0x2011, 0x0276, 0x20a9, 0x0004, 0x6010, 0x0096,
+	0x2048, 0x2019, 0x000a, 0x080c, 0xc0e7, 0x009e, 0x0110, 0x6017,
+	0x0001, 0x6003, 0x0001, 0x080c, 0x937d, 0x080c, 0x98e7, 0x0005,
+	0x6007, 0x0050, 0x703c, 0x6016, 0x0ca0, 0x0016, 0x00e6, 0x2071,
+	0x0260, 0x00b6, 0x00c6, 0x2260, 0x6010, 0x2058, 0xb8cc, 0xd084,
+	0x0150, 0x7128, 0x6044, 0x9106, 0x1120, 0x712c, 0x6048, 0x9106,
+	0x0110, 0x9006, 0x0010, 0x9085, 0x0001, 0x00ce, 0x00be, 0x00ee,
+	0x001e, 0x0005, 0x0016, 0x0096, 0x0086, 0x00e6, 0x01c6, 0x01d6,
+	0x0126, 0x2091, 0x8000, 0x2071, 0x1800, 0x20e1, 0x0000, 0x2001,
+	0x19a1, 0x2003, 0x0000, 0x080c, 0x1027, 0x05a0, 0x2900, 0x6016,
 	0x7090, 0x8004, 0xa816, 0x908a, 0x001e, 0x02d0, 0xa833, 0x001e,
 	0x20a9, 0x001e, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x001b, 0x20a0,
-	0x2001, 0x199f, 0x0016, 0x200c, 0x0471, 0x001e, 0x2940, 0x080c,
-	0x1018, 0x01c0, 0x2900, 0xa006, 0x2100, 0x81ff, 0x0180, 0x0c18,
+	0x2001, 0x19a1, 0x0016, 0x200c, 0x0471, 0x001e, 0x81ff, 0x01b8,
+	0x2940, 0x080c, 0x1027, 0x01b0, 0x2900, 0xa006, 0x2100, 0x0c18,
 	0xa832, 0x20a8, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x001b, 0x20a0,
-	0x2001, 0x199f, 0x0016, 0x200c, 0x00b1, 0x001e, 0x0000, 0x9085,
+	0x2001, 0x19a1, 0x0016, 0x200c, 0x00b1, 0x001e, 0x0000, 0x9085,
 	0x0001, 0x0048, 0x2071, 0x1800, 0x7093, 0x0000, 0x6014, 0x2048,
-	0x080c, 0x0fb1, 0x9006, 0x012e, 0x01de, 0x01ce, 0x00ee, 0x008e,
+	0x080c, 0x0fc0, 0x9006, 0x012e, 0x01de, 0x01ce, 0x00ee, 0x008e,
 	0x009e, 0x001e, 0x0005, 0x0006, 0x0016, 0x0026, 0x0036, 0x00c6,
-	0x918c, 0xffff, 0x11a8, 0x080c, 0x23e9, 0x2099, 0x026c, 0x2001,
-	0x0014, 0x3518, 0x9312, 0x1218, 0x23a8, 0x4003, 0x00f8, 0x20a8,
-	0x4003, 0x22a8, 0x8108, 0x080c, 0x23e9, 0x2099, 0x0260, 0x0ca8,
-	0x080c, 0x23e9, 0x2061, 0x199f, 0x6004, 0x2098, 0x6008, 0x3518,
-	0x9312, 0x1218, 0x23a8, 0x4003, 0x0048, 0x20a8, 0x4003, 0x22a8,
-	0x8108, 0x080c, 0x23e9, 0x2099, 0x0260, 0x0ca8, 0x2061, 0x199f,
-	0x2019, 0x0280, 0x3300, 0x931e, 0x0110, 0x6006, 0x0020, 0x2001,
-	0x0260, 0x6006, 0x8108, 0x2162, 0x9292, 0x0021, 0x9296, 0xffff,
-	0x620a, 0x00ce, 0x003e, 0x002e, 0x001e, 0x000e, 0x0005, 0x0006,
-	0x0016, 0x0026, 0x0036, 0x00c6, 0x81ff, 0x11b8, 0x080c, 0x2401,
-	0x20a1, 0x024c, 0x2001, 0x0014, 0x3518, 0x9312, 0x1218, 0x23a8,
-	0x4003, 0x0418, 0x20a8, 0x4003, 0x82ff, 0x01f8, 0x22a8, 0x8108,
-	0x080c, 0x2401, 0x20a1, 0x0240, 0x0c98, 0x080c, 0x2401, 0x2061,
-	0x19a2, 0x6004, 0x20a0, 0x6008, 0x3518, 0x9312, 0x1218, 0x23a8,
-	0x4003, 0x0058, 0x20a8, 0x4003, 0x82ff, 0x0138, 0x22a8, 0x8108,
-	0x080c, 0x2401, 0x20a1, 0x0240, 0x0c98, 0x2061, 0x19a2, 0x2019,
-	0x0260, 0x3400, 0x931e, 0x0110, 0x6006, 0x0020, 0x2001, 0x0240,
-	0x6006, 0x8108, 0x2162, 0x9292, 0x0021, 0x9296, 0xffff, 0x620a,
-	0x00ce, 0x003e, 0x002e, 0x001e, 0x000e, 0x0005, 0x00b6, 0x0066,
-	0x6610, 0x2658, 0xbe04, 0x96b4, 0xff00, 0x8637, 0x9686, 0x0006,
-	0x0170, 0x9686, 0x0004, 0x0158, 0xbe04, 0x96b4, 0x00ff, 0x9686,
-	0x0006, 0x0128, 0x9686, 0x0004, 0x0110, 0x9085, 0x0001, 0x006e,
-	0x00be, 0x0005, 0x00d6, 0x080c, 0xdace, 0x00de, 0x0005, 0x00d6,
-	0x080c, 0xdadb, 0x1520, 0x680c, 0x908c, 0xff00, 0x6820, 0x9084,
-	0x00ff, 0x9115, 0x6216, 0x6824, 0x602e, 0xd1e4, 0x0130, 0x9006,
-	0x080c, 0xeb03, 0x2009, 0x0001, 0x0078, 0xd1ec, 0x0180, 0x6920,
-	0x918c, 0x00ff, 0x6824, 0x080c, 0x287c, 0x1148, 0x2001, 0x0001,
-	0x080c, 0xeb03, 0x2110, 0x900e, 0x080c, 0x3267, 0x0018, 0x9085,
-	0x0001, 0x0008, 0x9006, 0x00de, 0x0005, 0x00b6, 0x00c6, 0x080c,
-	0xaf91, 0x05a8, 0x0016, 0x0026, 0x00c6, 0x2011, 0x0263, 0x2204,
-	0x8211, 0x220c, 0x080c, 0x287c, 0x1578, 0x080c, 0x6638, 0x1560,
-	0xbe12, 0xbd16, 0x00ce, 0x002e, 0x001e, 0x2b00, 0x6012, 0x080c,
-	0xe936, 0x11d8, 0x080c, 0x3342, 0x11c0, 0x080c, 0xda36, 0x0510,
-	0x2001, 0x0007, 0x080c, 0x65e9, 0x2001, 0x0007, 0x080c, 0x6615,
-	0x6017, 0x0000, 0x6023, 0x0001, 0x6007, 0x0001, 0x6003, 0x0001,
-	0x080c, 0x91f9, 0x080c, 0x9763, 0x0010, 0x080c, 0xaf43, 0x9085,
-	0x0001, 0x00ce, 0x00be, 0x0005, 0x080c, 0xaf43, 0x00ce, 0x002e,
-	0x001e, 0x0ca8, 0x080c, 0xaf43, 0x9006, 0x0c98, 0x2069, 0x026d,
-	0x6800, 0x9082, 0x0010, 0x1228, 0x6017, 0x0000, 0x9085, 0x0001,
-	0x0008, 0x9006, 0x0005, 0x6017, 0x0000, 0x2069, 0x026c, 0x6808,
-	0x9084, 0xff00, 0x9086, 0x0800, 0x1190, 0x6904, 0x9186, 0x0018,
-	0x0118, 0x9186, 0x0014, 0x1158, 0x810f, 0x6800, 0x9084, 0x00ff,
-	0x910d, 0x615a, 0x908e, 0x0014, 0x0110, 0x908e, 0x0010, 0x0005,
-	0x6004, 0x90b2, 0x0053, 0x1a0c, 0x0dd5, 0x91b6, 0x0013, 0x1130,
-	0x2008, 0x91b2, 0x0040, 0x1a04, 0xdc25, 0x0092, 0x91b6, 0x0027,
-	0x0120, 0x91b6, 0x0014, 0x190c, 0x0dd5, 0x2001, 0x0007, 0x080c,
-	0x6615, 0x080c, 0x9657, 0x080c, 0xaf74, 0x080c, 0x9763, 0x0005,
-	0xdb58, 0xdb5a, 0xdb58, 0xdb58, 0xdb58, 0xdb5a, 0xdb69, 0xdc1e,
-	0xdbbb, 0xdc1e, 0xdbcf, 0xdc1e, 0xdb69, 0xdc1e, 0xdc16, 0xdc1e,
-	0xdc16, 0xdc1e, 0xdc1e, 0xdb58, 0xdb58, 0xdb58, 0xdb58, 0xdb58,
-	0xdb58, 0xdb58, 0xdb58, 0xdb58, 0xdb58, 0xdb58, 0xdb5a, 0xdb58,
-	0xdc1e, 0xdb58, 0xdb58, 0xdc1e, 0xdb58, 0xdc1b, 0xdc1e, 0xdb58,
-	0xdb58, 0xdb58, 0xdb58, 0xdc1e, 0xdc1e, 0xdb58, 0xdc1e, 0xdc1e,
-	0xdb58, 0xdb64, 0xdb58, 0xdb58, 0xdb58, 0xdb58, 0xdc1a, 0xdc1e,
-	0xdb58, 0xdb58, 0xdc1e, 0xdc1e, 0xdb58, 0xdb58, 0xdb58, 0xdb58,
-	0x080c, 0x0dd5, 0x080c, 0x9657, 0x080c, 0xd3a0, 0x6003, 0x0002,
-	0x080c, 0x9763, 0x0804, 0xdc24, 0x9006, 0x080c, 0x65d5, 0x0804,
-	0xdc1e, 0x080c, 0x6a04, 0x1904, 0xdc1e, 0x9006, 0x080c, 0x65d5,
-	0x6010, 0x2058, 0xb810, 0x9086, 0x00ff, 0x1140, 0x00f6, 0x2079,
-	0x1800, 0x78a8, 0x8000, 0x78aa, 0x00fe, 0x0428, 0x6010, 0x2058,
-	0xb8c0, 0x9005, 0x1178, 0x080c, 0xd388, 0x1904, 0xdc1e, 0x0036,
-	0x0046, 0xbba0, 0x2021, 0x0007, 0x080c, 0x4d36, 0x004e, 0x003e,
-	0x0804, 0xdc1e, 0x080c, 0x3373, 0x1904, 0xdc1e, 0x2001, 0x1800,
-	0x2004, 0x9086, 0x0002, 0x1138, 0x00f6, 0x2079, 0x1800, 0x78a8,
-	0x8000, 0x78aa, 0x00fe, 0x2001, 0x0002, 0x080c, 0x65e9, 0x080c,
-	0x9657, 0x6023, 0x0001, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c,
-	0x91f9, 0x080c, 0x9763, 0x6110, 0x2158, 0x2009, 0x0001, 0x080c,
-	0x85be, 0x0804, 0xdc24, 0x6610, 0x2658, 0xbe04, 0x96b4, 0xff00,
-	0x8637, 0x9686, 0x0006, 0x0904, 0xdc1e, 0x9686, 0x0004, 0x0904,
-	0xdc1e, 0x080c, 0x8d70, 0x2001, 0x0004, 0x0804, 0xdc1c, 0x2001,
-	0x1800, 0x2004, 0x9086, 0x0003, 0x1158, 0x0036, 0x0046, 0x6010,
-	0x2058, 0xbba0, 0x2021, 0x0006, 0x080c, 0x4d36, 0x004e, 0x003e,
-	0x2001, 0x0006, 0x080c, 0xdc42, 0x6610, 0x2658, 0xbe04, 0x0066,
-	0x96b4, 0xff00, 0x8637, 0x9686, 0x0006, 0x006e, 0x0168, 0x2001,
-	0x0006, 0x080c, 0x6615, 0x9284, 0x00ff, 0x908e, 0x0007, 0x1120,
-	0x2001, 0x0006, 0x080c, 0x65e9, 0x080c, 0x6a04, 0x11f8, 0x2001,
-	0x1837, 0x2004, 0xd0a4, 0x01d0, 0xbe04, 0x96b4, 0x00ff, 0x9686,
-	0x0006, 0x01a0, 0x00f6, 0x2079, 0x1800, 0x78a8, 0x8000, 0x78aa,
-	0x00fe, 0x0804, 0xdba3, 0x2001, 0x0004, 0x0030, 0x2001, 0x0006,
-	0x0449, 0x0020, 0x0018, 0x0010, 0x080c, 0x6615, 0x080c, 0x9657,
-	0x080c, 0xaf43, 0x080c, 0x9763, 0x0005, 0x2600, 0x0002, 0xdc39,
-	0xdc39, 0xdc39, 0xdc39, 0xdc39, 0xdc3b, 0xdc39, 0xdc3b, 0xdc39,
-	0xdc39, 0xdc3b, 0xdc39, 0xdc39, 0xdc39, 0xdc3b, 0xdc3b, 0xdc3b,
-	0xdc3b, 0x080c, 0x0dd5, 0x080c, 0x9657, 0x080c, 0xaf43, 0x080c,
-	0x9763, 0x0005, 0x0016, 0x00b6, 0x00d6, 0x6110, 0x2158, 0xb900,
-	0xd184, 0x0138, 0x080c, 0x65e9, 0x9006, 0x080c, 0x65d5, 0x080c,
-	0x3247, 0x00de, 0x00be, 0x001e, 0x0005, 0x6610, 0x2658, 0xb804,
-	0x9084, 0xff00, 0x8007, 0x90b2, 0x000c, 0x1a0c, 0x0dd5, 0x91b6,
-	0x0015, 0x1110, 0x003b, 0x0028, 0x91b6, 0x0016, 0x190c, 0x0dd5,
-	0x006b, 0x0005, 0xb9ee, 0xb9ee, 0xb9ee, 0xb9ee, 0xdcd7, 0xb9ee,
-	0xdcc1, 0xdc82, 0xb9ee, 0xb9ee, 0xb9ee, 0xb9ee, 0xb9ee, 0xb9ee,
-	0xb9ee, 0xb9ee, 0xdcd7, 0xb9ee, 0xdcc1, 0xdcc8, 0xb9ee, 0xb9ee,
-	0xb9ee, 0xb9ee, 0x00f6, 0x080c, 0x6a04, 0x11d8, 0x080c, 0xd388,
-	0x11c0, 0x6010, 0x905d, 0x01a8, 0xb8c0, 0x9005, 0x0190, 0x9006,
-	0x080c, 0x65d5, 0x2001, 0x0002, 0x080c, 0x65e9, 0x6023, 0x0001,
-	0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x91f9, 0x080c, 0x9763,
-	0x00f0, 0x2011, 0x0263, 0x2204, 0x8211, 0x220c, 0x080c, 0x287c,
-	0x11b0, 0x080c, 0x6699, 0x0118, 0x080c, 0xaf43, 0x0080, 0xb810,
-	0x0006, 0xb814, 0x0006, 0xb8c0, 0x0006, 0x080c, 0x60c7, 0x000e,
-	0xb8c2, 0x000e, 0xb816, 0x000e, 0xb812, 0x080c, 0xaf43, 0x00fe,
-	0x0005, 0x6604, 0x96b6, 0x001e, 0x1110, 0x080c, 0xaf43, 0x0005,
-	0x080c, 0xbd79, 0x1148, 0x6003, 0x0001, 0x6007, 0x0001, 0x080c,
-	0x91f9, 0x080c, 0x9763, 0x0010, 0x080c, 0xaf43, 0x0005, 0x0804,
-	0xaf43, 0x6004, 0x908a, 0x0053, 0x1a0c, 0x0dd5, 0x080c, 0x9657,
-	0x080c, 0xaf74, 0x080c, 0x9763, 0x0005, 0x9182, 0x0040, 0x0002,
-	0xdcfc, 0xdcfc, 0xdcfc, 0xdcfc, 0xdcfe, 0xdcfc, 0xdcfc, 0xdcfc,
-	0xdcfc, 0xdcfc, 0xdcfc, 0xdcfc, 0xdcfc, 0xdcfc, 0xdcfc, 0xdcfc,
-	0xdcfc, 0xdcfc, 0xdcfc, 0xdcfc, 0x080c, 0x0dd5, 0x0096, 0x00b6,
-	0x00d6, 0x00e6, 0x00f6, 0x0046, 0x0026, 0x6210, 0x2258, 0xb8bc,
-	0x9005, 0x11a8, 0x6106, 0x2071, 0x0260, 0x7444, 0x94a4, 0xff00,
-	0x0904, 0xdd64, 0x080c, 0xeaf7, 0x1170, 0x9486, 0x2000, 0x1158,
-	0x2009, 0x0001, 0x2011, 0x0200, 0x080c, 0x879a, 0x0020, 0x9026,
-	0x080c, 0xe97b, 0x0c38, 0x080c, 0x0fff, 0x090c, 0x0dd5, 0x6003,
-	0x0007, 0xa867, 0x010d, 0x9006, 0xa802, 0xa86a, 0xac8a, 0x2c00,
-	0xa88e, 0x6008, 0xa8e2, 0x6010, 0x2058, 0xb8a0, 0x7130, 0xa97a,
-	0x0016, 0xa876, 0xa87f, 0x0000, 0xa883, 0x0000, 0xa887, 0x0036,
-	0x080c, 0x6d17, 0x001e, 0x080c, 0xeaf7, 0x1904, 0xddc4, 0x9486,
-	0x2000, 0x1130, 0x2019, 0x0017, 0x080c, 0xe6ae, 0x0804, 0xddc4,
-	0x9486, 0x0200, 0x1120, 0x080c, 0xe64a, 0x0804, 0xddc4, 0x9486,
-	0x0400, 0x0120, 0x9486, 0x1000, 0x1904, 0xddc4, 0x2019, 0x0002,
-	0x080c, 0xe665, 0x0804, 0xddc4, 0x2069, 0x1a70, 0x6a00, 0xd284,
-	0x0904, 0xde2e, 0x9284, 0x0300, 0x1904, 0xde27, 0x6804, 0x9005,
-	0x0904, 0xde0f, 0x2d78, 0x6003, 0x0007, 0x080c, 0x1018, 0x0904,
-	0xddd0, 0x7800, 0xd08c, 0x1118, 0x7804, 0x8001, 0x7806, 0x6017,
-	0x0000, 0x2001, 0x180f, 0x2004, 0xd084, 0x1904, 0xde32, 0x9006,
-	0xa802, 0xa867, 0x0116, 0xa86a, 0x6008, 0xa8e2, 0x2c00, 0xa87a,
-	0x6010, 0x2058, 0xb8a0, 0x7130, 0xa9b6, 0xa876, 0xb928, 0xa9ba,
-	0xb92c, 0xa9be, 0xb930, 0xa9c2, 0xb934, 0xa9c6, 0xa883, 0x003d,
-	0x7044, 0x9084, 0x0003, 0x9080, 0xddcc, 0x2005, 0xa87e, 0x20a9,
-	0x000a, 0x2001, 0x0270, 0xaa5c, 0x9290, 0x0021, 0x2009, 0x0205,
-	0x200b, 0x0080, 0x20e1, 0x0000, 0xab60, 0x23e8, 0x2098, 0x22a0,
-	0x4003, 0x200b, 0x0000, 0x2001, 0x027a, 0x200c, 0xa9b2, 0x8000,
-	0x200c, 0xa9ae, 0x080c, 0x6d17, 0x002e, 0x004e, 0x00fe, 0x00ee,
-	0x00de, 0x00be, 0x009e, 0x0005, 0x0000, 0x0080, 0x0040, 0x0000,
-	0x2001, 0x1810, 0x2004, 0xd084, 0x0120, 0x080c, 0x0fff, 0x1904,
-	0xdd79, 0x6017, 0xf100, 0x6003, 0x0001, 0x6007, 0x0041, 0x080c,
-	0x91b1, 0x080c, 0x9763, 0x0c00, 0x2069, 0x0260, 0x6848, 0x9084,
-	0xff00, 0x9086, 0x1200, 0x1198, 0x686c, 0x9084, 0x00ff, 0x0016,
-	0x6114, 0x918c, 0xf700, 0x910d, 0x6116, 0x001e, 0x6003, 0x0001,
-	0x6007, 0x0043, 0x080c, 0x91b1, 0x080c, 0x9763, 0x0828, 0x6868,
-	0x602e, 0x686c, 0x6032, 0x6017, 0xf200, 0x6003, 0x0001, 0x6007,
-	0x0041, 0x080c, 0x91b1, 0x080c, 0x9763, 0x0804, 0xddc4, 0x2001,
-	0x180e, 0x2004, 0xd0ec, 0x0120, 0x2011, 0x8049, 0x080c, 0x4b7f,
-	0x6017, 0xf300, 0x0010, 0x6017, 0xf100, 0x6003, 0x0001, 0x6007,
-	0x0041, 0x080c, 0x91b1, 0x080c, 0x9763, 0x0804, 0xddc4, 0x6017,
-	0xf500, 0x0c98, 0x6017, 0xf600, 0x0804, 0xdde4, 0x6017, 0xf200,
-	0x0804, 0xdde4, 0xa867, 0x0146, 0xa86b, 0x0000, 0x6008, 0xa886,
-	0x2c00, 0xa87a, 0x7044, 0x9084, 0x0003, 0x9080, 0xddcc, 0x2005,
-	0xa87e, 0x2928, 0x6010, 0x2058, 0xb8a0, 0xa876, 0xb828, 0xa88a,
-	0xb82c, 0xa88e, 0xb830, 0xa892, 0xb834, 0xa896, 0xa883, 0x003d,
-	0x2009, 0x0205, 0x2104, 0x9085, 0x0080, 0x200a, 0x20e1, 0x0000,
-	0x2011, 0x0210, 0x2214, 0x9294, 0x0fff, 0xaaa2, 0x9282, 0x0111,
-	0x1a0c, 0x0dd5, 0x8210, 0x821c, 0x2001, 0x026c, 0x2098, 0xa860,
-	0x20e8, 0xa85c, 0x9080, 0x0029, 0x20a0, 0x2011, 0xdeae, 0x2041,
-	0x0001, 0x223d, 0x9784, 0x00ff, 0x9322, 0x1208, 0x2300, 0x20a8,
-	0x4003, 0x931a, 0x0530, 0x8210, 0xd7fc, 0x1130, 0x8d68, 0x2d0a,
-	0x2001, 0x0260, 0x2098, 0x0c68, 0x2950, 0x080c, 0x1018, 0x0170,
-	0x2900, 0xb002, 0xa867, 0x0147, 0xa86b, 0x0000, 0xa860, 0x20e8,
-	0xa85c, 0x9080, 0x001b, 0x20a0, 0x8840, 0x08d8, 0x2548, 0xa800,
-	0x902d, 0x0118, 0x080c, 0x1031, 0x0cc8, 0x080c, 0x1031, 0x0804,
-	0xddd0, 0x2548, 0x8847, 0x9885, 0x0046, 0xa866, 0x2009, 0x0205,
-	0x200b, 0x0000, 0x080c, 0xe6dd, 0x0804, 0xddc4, 0x8010, 0x0004,
-	0x801a, 0x0006, 0x8018, 0x0008, 0x8016, 0x000a, 0x8014, 0x9186,
-	0x0013, 0x1160, 0x6004, 0x908a, 0x0054, 0x1a0c, 0x0dd5, 0x9082,
-	0x0040, 0x0a0c, 0x0dd5, 0x2008, 0x0804, 0xdf60, 0x9186, 0x0051,
-	0x0108, 0x00c0, 0x2001, 0x0109, 0x2004, 0xd084, 0x0904, 0xdf10,
-	0x0126, 0x2091, 0x2800, 0x0006, 0x0016, 0x0026, 0x080c, 0x9094,
-	0x002e, 0x001e, 0x000e, 0x012e, 0x6000, 0x9086, 0x0002, 0x1580,
-	0x0804, 0xdfa9, 0x9186, 0x0027, 0x0530, 0x9186, 0x0048, 0x0128,
-	0x9186, 0x0014, 0x0500, 0x190c, 0x0dd5, 0x2001, 0x0109, 0x2004,
-	0xd084, 0x01f0, 0x00c6, 0x0126, 0x2091, 0x2800, 0x00c6, 0x2061,
-	0x0100, 0x0006, 0x0016, 0x0026, 0x080c, 0x9094, 0x002e, 0x001e,
-	0x000e, 0x00ce, 0x012e, 0x00ce, 0x6000, 0x9086, 0x0004, 0x190c,
-	0x0dd5, 0x0804, 0xe08c, 0x6004, 0x9082, 0x0040, 0x2008, 0x001a,
-	0x080c, 0xafd9, 0x0005, 0xdf27, 0xdf29, 0xdf29, 0xdf50, 0xdf27,
-	0xdf27, 0xdf27, 0xdf27, 0xdf27, 0xdf27, 0xdf27, 0xdf27, 0xdf27,
-	0xdf27, 0xdf27, 0xdf27, 0xdf27, 0xdf27, 0xdf27, 0xdf27, 0x080c,
-	0x0dd5, 0x080c, 0x9657, 0x080c, 0x9763, 0x0036, 0x0096, 0x6014,
-	0x904d, 0x01d8, 0x080c, 0xcc86, 0x01c0, 0x6003, 0x0002, 0x6010,
-	0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x1178, 0x2019, 0x0004,
-	0x080c, 0xe6dd, 0x6017, 0x0000, 0x6018, 0x9005, 0x1120, 0x2001,
-	0x1986, 0x2004, 0x601a, 0x6003, 0x0007, 0x009e, 0x003e, 0x0005,
-	0x0096, 0x080c, 0x9657, 0x080c, 0x9763, 0x080c, 0xcc86, 0x0120,
-	0x6014, 0x2048, 0x080c, 0x1031, 0x080c, 0xaf74, 0x009e, 0x0005,
-	0x0002, 0xdf75, 0xdf8c, 0xdf77, 0xdfa3, 0xdf75, 0xdf75, 0xdf75,
-	0xdf75, 0xdf75, 0xdf75, 0xdf75, 0xdf75, 0xdf75, 0xdf75, 0xdf75,
-	0xdf75, 0xdf75, 0xdf75, 0xdf75, 0xdf75, 0x080c, 0x0dd5, 0x0096,
-	0x080c, 0x9657, 0x6014, 0x2048, 0xa87c, 0xd0b4, 0x0138, 0x6003,
-	0x0007, 0x2009, 0x0043, 0x080c, 0xafbe, 0x0010, 0x6003, 0x0004,
-	0x080c, 0x9763, 0x009e, 0x0005, 0x080c, 0x9657, 0x080c, 0xcc86,
-	0x0138, 0x6114, 0x0096, 0x2148, 0xa97c, 0x009e, 0xd1ec, 0x1138,
-	0x080c, 0x876f, 0x080c, 0xaf43, 0x080c, 0x9763, 0x0005, 0x080c,
-	0xe93f, 0x0db0, 0x0cc8, 0x080c, 0x9657, 0x2009, 0x0041, 0x0804,
-	0xe114, 0x9182, 0x0040, 0x0002, 0xdfc0, 0xdfc2, 0xdfc0, 0xdfc0,
-	0xdfc0, 0xdfc0, 0xdfc0, 0xdfc0, 0xdfc0, 0xdfc0, 0xdfc0, 0xdfc0,
-	0xdfc0, 0xdfc0, 0xdfc0, 0xdfc0, 0xdfc0, 0xdfc3, 0xdfc0, 0xdfc0,
-	0x080c, 0x0dd5, 0x0005, 0x00d6, 0x080c, 0x876f, 0x00de, 0x080c,
-	0xe997, 0x080c, 0xaf43, 0x0005, 0x9182, 0x0040, 0x0002, 0xdfe3,
-	0xdfe3, 0xdfe3, 0xdfe3, 0xdfe3, 0xdfe3, 0xdfe3, 0xdfe3, 0xdfe3,
-	0xdfe5, 0xe054, 0xdfe3, 0xdfe3, 0xdfe3, 0xdfe3, 0xe054, 0xdfe3,
-	0xdfe3, 0xdfe3, 0xdfe3, 0x080c, 0x0dd5, 0x2001, 0x0105, 0x2004,
-	0x9084, 0x1800, 0x01c8, 0x2001, 0x0132, 0x200c, 0x2001, 0x0131,
-	0x2004, 0x9105, 0x1904, 0xe054, 0x2009, 0x180c, 0x2104, 0xd0d4,
-	0x0904, 0xe054, 0xc0d4, 0x200a, 0x2009, 0x0105, 0x2104, 0x9084,
-	0xe7fd, 0x9085, 0x0010, 0x200a, 0x2001, 0x1867, 0x2004, 0xd0e4,
-	0x1528, 0x603b, 0x0000, 0x080c, 0x9713, 0x6014, 0x0096, 0x2048,
-	0xa87c, 0xd0fc, 0x0188, 0x908c, 0x0003, 0x918e, 0x0002, 0x0508,
-	0x2001, 0x180c, 0x2004, 0xd0d4, 0x11e0, 0x080c, 0x9891, 0x2009,
-	0x0041, 0x009e, 0x0804, 0xe114, 0x080c, 0x9891, 0x6003, 0x0007,
-	0x601b, 0x0000, 0x080c, 0x876f, 0x009e, 0x0005, 0x2001, 0x0100,
-	0x2004, 0x9082, 0x0005, 0x0aa8, 0x2001, 0x011f, 0x2004, 0x603a,
-	0x0890, 0x2001, 0x180c, 0x200c, 0xc1d4, 0x2102, 0xd1cc, 0x0110,
-	0x080c, 0x2c90, 0x080c, 0x9891, 0x6014, 0x2048, 0xa97c, 0xd1ec,
-	0x1130, 0x080c, 0x876f, 0x080c, 0xaf43, 0x009e, 0x0005, 0x080c,
-	0xe93f, 0x0db8, 0x009e, 0x0005, 0x2001, 0x180c, 0x200c, 0xc1d4,
-	0x2102, 0x0036, 0x080c, 0x9713, 0x080c, 0x9891, 0x6014, 0x0096,
-	0x2048, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x0188,
-	0xa87c, 0x9084, 0x0003, 0x9086, 0x0002, 0x0140, 0xa8ac, 0x6330,
-	0x931a, 0x6332, 0xa8b0, 0x632c, 0x931b, 0x632e, 0x6003, 0x0002,
-	0x0080, 0x2019, 0x0004, 0x080c, 0xe6dd, 0x6018, 0x9005, 0x1128,
-	0x2001, 0x1986, 0x2004, 0x8003, 0x601a, 0x6017, 0x0000, 0x6003,
-	0x0007, 0x009e, 0x003e, 0x0005, 0x9182, 0x0040, 0x0002, 0xe0a3,
-	0xe0a3, 0xe0a3, 0xe0a3, 0xe0a3, 0xe0a3, 0xe0a3, 0xe0a3, 0xe0a5,
-	0xe0a3, 0xe0a3, 0xe0a3, 0xe0a3, 0xe0a3, 0xe0a3, 0xe0a3, 0xe0a3,
-	0xe0a3, 0xe0a3, 0xe0f0, 0x080c, 0x0dd5, 0x6014, 0x0096, 0x2048,
-	0xa834, 0xaa38, 0x6110, 0x00b6, 0x2158, 0xb900, 0x00be, 0xd1bc,
-	0x1190, 0x920d, 0x1518, 0xa87c, 0xd0fc, 0x0128, 0x2009, 0x0041,
-	0x009e, 0x0804, 0xe114, 0x6003, 0x0007, 0x601b, 0x0000, 0x080c,
-	0x876f, 0x009e, 0x0005, 0x6124, 0xd1f4, 0x1d58, 0x0006, 0x0046,
-	0xacac, 0x9422, 0xa9b0, 0x2200, 0x910b, 0x6030, 0x9420, 0x6432,
-	0x602c, 0x9109, 0x612e, 0x004e, 0x000e, 0x08d8, 0x6110, 0x00b6,
-	0x2158, 0xb900, 0x00be, 0xd1bc, 0x1178, 0x2009, 0x180e, 0x210c,
-	0xd19c, 0x0118, 0x6003, 0x0007, 0x0010, 0x6003, 0x0006, 0x00e9,
-	0x080c, 0x8771, 0x009e, 0x0005, 0x6003, 0x0002, 0x009e, 0x0005,
-	0x6024, 0xd0f4, 0x0128, 0x080c, 0x15f4, 0x1904, 0xe0a5, 0x0005,
-	0x6014, 0x0096, 0x2048, 0xa834, 0xa938, 0x009e, 0x9105, 0x1120,
-	0x080c, 0x15f4, 0x1904, 0xe0a5, 0x0005, 0xd2fc, 0x0140, 0x8002,
-	0x8000, 0x8212, 0x9291, 0x0000, 0x2009, 0x0009, 0x0010, 0x2009,
-	0x0015, 0xaa9a, 0xa896, 0x0005, 0x9182, 0x0040, 0x0208, 0x0062,
-	0x9186, 0x0013, 0x0120, 0x9186, 0x0014, 0x190c, 0x0dd5, 0x6024,
-	0xd0dc, 0x090c, 0x0dd5, 0x0005, 0xe138, 0xe144, 0xe150, 0xe15c,
-	0xe138, 0xe138, 0xe138, 0xe138, 0xe13f, 0xe13a, 0xe13a, 0xe138,
-	0xe138, 0xe138, 0xe138, 0xe13a, 0xe138, 0xe13a, 0xe138, 0xe13f,
-	0x080c, 0x0dd5, 0x6024, 0xd0dc, 0x090c, 0x0dd5, 0x0005, 0x6014,
-	0x9005, 0x190c, 0x0dd5, 0x0005, 0x6003, 0x0001, 0x6106, 0x080c,
-	0x91b1, 0x0126, 0x2091, 0x8000, 0x080c, 0x9763, 0x012e, 0x0005,
-	0x6003, 0x0001, 0x6106, 0x080c, 0x91b1, 0x0126, 0x2091, 0x8000,
-	0x080c, 0x9763, 0x012e, 0x0005, 0x6003, 0x0003, 0x6106, 0x2c10,
-	0x080c, 0x1beb, 0x0126, 0x2091, 0x8000, 0x080c, 0x9216, 0x080c,
-	0x9891, 0x012e, 0x0005, 0x0126, 0x2091, 0x8000, 0x0036, 0x0096,
-	0x9182, 0x0040, 0x0023, 0x009e, 0x003e, 0x012e, 0x0005, 0xe18b,
-	0xe18d, 0xe19f, 0xe1b9, 0xe18b, 0xe18b, 0xe18b, 0xe18b, 0xe18b,
-	0xe18b, 0xe18b, 0xe18b, 0xe18b, 0xe18b, 0xe18b, 0xe18b, 0xe18b,
-	0xe18b, 0xe18b, 0xe18b, 0x080c, 0x0dd5, 0x6014, 0x2048, 0xa87c,
-	0xd0fc, 0x01f8, 0x909c, 0x0003, 0x939e, 0x0003, 0x01d0, 0x6003,
-	0x0001, 0x6106, 0x080c, 0x91b1, 0x080c, 0x9763, 0x0470, 0x6014,
-	0x2048, 0xa87c, 0xd0fc, 0x0168, 0x909c, 0x0003, 0x939e, 0x0003,
-	0x0140, 0x6003, 0x0001, 0x6106, 0x080c, 0x91b1, 0x080c, 0x9763,
-	0x00e0, 0x901e, 0x6316, 0x631a, 0x2019, 0x0004, 0x080c, 0xe6dd,
-	0x00a0, 0x6014, 0x2048, 0xa87c, 0xd0fc, 0x0d98, 0x909c, 0x0003,
-	0x939e, 0x0003, 0x0d70, 0x6003, 0x0003, 0x6106, 0x2c10, 0x080c,
-	0x1beb, 0x080c, 0x9216, 0x080c, 0x9891, 0x0005, 0x080c, 0x9657,
-	0x6114, 0x81ff, 0x0158, 0x0096, 0x2148, 0x080c, 0xea94, 0x0036,
-	0x2019, 0x0029, 0x080c, 0xe6dd, 0x003e, 0x009e, 0x080c, 0xaf74,
-	0x080c, 0x9763, 0x0005, 0x080c, 0x9713, 0x6114, 0x81ff, 0x0158,
-	0x0096, 0x2148, 0x080c, 0xea94, 0x0036, 0x2019, 0x0029, 0x080c,
-	0xe6dd, 0x003e, 0x009e, 0x080c, 0xaf74, 0x080c, 0x9891, 0x0005,
-	0x9182, 0x0085, 0x0002, 0xe20a, 0xe208, 0xe208, 0xe216, 0xe208,
-	0xe208, 0xe208, 0xe208, 0xe208, 0xe208, 0xe208, 0xe208, 0xe208,
-	0x080c, 0x0dd5, 0x6003, 0x000b, 0x6106, 0x080c, 0x91b1, 0x0126,
-	0x2091, 0x8000, 0x080c, 0x9763, 0x012e, 0x0005, 0x0026, 0x00e6,
-	0x080c, 0xe936, 0x0118, 0x080c, 0xaf43, 0x0450, 0x2071, 0x0260,
-	0x7224, 0x6216, 0x2001, 0x180e, 0x2004, 0xd0e4, 0x0150, 0x6010,
-	0x00b6, 0x2058, 0xbca0, 0x00be, 0x2c00, 0x2011, 0x014e, 0x080c,
-	0xb264, 0x7220, 0x080c, 0xe583, 0x0118, 0x6007, 0x0086, 0x0040,
-	0x6007, 0x0087, 0x7224, 0x9296, 0xffff, 0x1110, 0x6007, 0x0086,
-	0x6003, 0x0001, 0x080c, 0x91b1, 0x080c, 0x9763, 0x080c, 0x9891,
-	0x00ee, 0x002e, 0x0005, 0x9186, 0x0013, 0x1160, 0x6004, 0x908a,
-	0x0085, 0x0a0c, 0x0dd5, 0x908a, 0x0092, 0x1a0c, 0x0dd5, 0x9082,
-	0x0085, 0x00a2, 0x9186, 0x0027, 0x0130, 0x9186, 0x0014, 0x0118,
-	0x080c, 0xafd9, 0x0050, 0x2001, 0x0007, 0x080c, 0x6615, 0x080c,
-	0x9657, 0x080c, 0xaf74, 0x080c, 0x9763, 0x0005, 0xe27b, 0xe27d,
-	0xe27d, 0xe27b, 0xe27b, 0xe27b, 0xe27b, 0xe27b, 0xe27b, 0xe27b,
-	0xe27b, 0xe27b, 0xe27b, 0x080c, 0x0dd5, 0x080c, 0x9657, 0x080c,
-	0xaf74, 0x080c, 0x9763, 0x0005, 0x9182, 0x0085, 0x0a0c, 0x0dd5,
-	0x9182, 0x0092, 0x1a0c, 0x0dd5, 0x9182, 0x0085, 0x0002, 0xe29c,
-	0xe29c, 0xe29c, 0xe29e, 0xe29c, 0xe29c, 0xe29c, 0xe29c, 0xe29c,
-	0xe29c, 0xe29c, 0xe29c, 0xe29c, 0x080c, 0x0dd5, 0x0005, 0x9186,
-	0x0013, 0x0148, 0x9186, 0x0014, 0x0130, 0x9186, 0x0027, 0x0118,
-	0x080c, 0xafd9, 0x0030, 0x080c, 0x9657, 0x080c, 0xaf74, 0x080c,
-	0x9763, 0x0005, 0x0036, 0x080c, 0xe997, 0x6043, 0x0000, 0x2019,
-	0x000b, 0x0031, 0x6023, 0x0006, 0x6003, 0x0007, 0x003e, 0x0005,
-	0x0126, 0x0036, 0x2091, 0x8000, 0x0086, 0x2c40, 0x0096, 0x904e,
-	0x080c, 0xa76b, 0x009e, 0x008e, 0x1550, 0x0076, 0x2c38, 0x080c,
-	0xa816, 0x007e, 0x1520, 0x6000, 0x9086, 0x0000, 0x0500, 0x6020,
-	0x9086, 0x0007, 0x01e0, 0x0096, 0x601c, 0xd084, 0x0140, 0x080c,
-	0xe997, 0x080c, 0xd3a0, 0x080c, 0x1aa1, 0x6023, 0x0007, 0x6014,
-	0x2048, 0x080c, 0xcc86, 0x0110, 0x080c, 0xe6dd, 0x009e, 0x6017,
-	0x0000, 0x080c, 0xe997, 0x6023, 0x0007, 0x080c, 0xd3a0, 0x003e,
-	0x012e, 0x0005, 0x00f6, 0x00c6, 0x00b6, 0x0036, 0x0156, 0x2079,
-	0x0260, 0x7938, 0x783c, 0x080c, 0x287c, 0x15c8, 0x0016, 0x00c6,
-	0x080c, 0x6699, 0x1590, 0x001e, 0x00c6, 0x2160, 0x080c, 0xd39d,
-	0x00ce, 0x002e, 0x0026, 0x0016, 0x2019, 0x0029, 0x080c, 0xa8dc,
-	0x080c, 0x9356, 0x0076, 0x903e, 0x080c, 0x9229, 0x007e, 0x001e,
-	0x0076, 0x903e, 0x080c, 0xe477, 0x007e, 0x0026, 0xba04, 0x9294,
-	0xff00, 0x8217, 0x9286, 0x0006, 0x0118, 0x9286, 0x0004, 0x1118,
-	0xbaa0, 0x080c, 0x32dc, 0x002e, 0xbcc0, 0x001e, 0x080c, 0x60c7,
-	0xbe12, 0xbd16, 0xbcc2, 0x9006, 0x0010, 0x00ce, 0x001e, 0x015e,
-	0x003e, 0x00be, 0x00ce, 0x00fe, 0x0005, 0x00c6, 0x00d6, 0x00b6,
-	0x0016, 0x2009, 0x1824, 0x2104, 0x9086, 0x0074, 0x1904, 0xe39e,
-	0x2069, 0x0260, 0x6944, 0x9182, 0x0100, 0x06e0, 0x6940, 0x9184,
-	0x8000, 0x0904, 0xe39b, 0x2001, 0x197b, 0x2004, 0x9005, 0x1140,
-	0x6010, 0x2058, 0xb8c0, 0x9005, 0x0118, 0x9184, 0x0800, 0x0598,
-	0x6948, 0x918a, 0x0001, 0x0648, 0x080c, 0xeafc, 0x0118, 0x6978,
-	0xd1fc, 0x11b8, 0x2009, 0x0205, 0x200b, 0x0001, 0x693c, 0x81ff,
-	0x1198, 0x6944, 0x9182, 0x0100, 0x02a8, 0x6940, 0x81ff, 0x1178,
-	0x6948, 0x918a, 0x0001, 0x0288, 0x6950, 0x918a, 0x0001, 0x0298,
-	0x00d0, 0x6017, 0x0100, 0x00a0, 0x6017, 0x0300, 0x0088, 0x6017,
-	0x0500, 0x0070, 0x6017, 0x0700, 0x0058, 0x6017, 0x0900, 0x0040,
-	0x6017, 0x0b00, 0x0028, 0x6017, 0x0f00, 0x0010, 0x6017, 0x2d00,
-	0x9085, 0x0001, 0x0008, 0x9006, 0x001e, 0x00be, 0x00de, 0x00ce,
-	0x0005, 0x00c6, 0x00b6, 0x0026, 0x0036, 0x0156, 0x6210, 0x2258,
-	0xbb04, 0x9394, 0x00ff, 0x9286, 0x0006, 0x0180, 0x9286, 0x0004,
-	0x0168, 0x9394, 0xff00, 0x8217, 0x9286, 0x0006, 0x0138, 0x9286,
-	0x0004, 0x0120, 0x080c, 0x66a8, 0x0804, 0xe406, 0x2011, 0x0276,
-	0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019, 0x000a, 0x080c, 0xbf11,
-	0x009e, 0x15a8, 0x2011, 0x027a, 0x20a9, 0x0004, 0x0096, 0x2b48,
-	0x2019, 0x0006, 0x080c, 0xbf11, 0x009e, 0x1548, 0x0046, 0x0016,
-	0xbaa0, 0x2220, 0x9006, 0x2009, 0x1848, 0x210c, 0xd1a4, 0x0138,
-	0x2009, 0x0029, 0x080c, 0xe73a, 0xb800, 0xc0e5, 0xb802, 0x2019,
-	0x0029, 0x080c, 0x9356, 0x0076, 0x2039, 0x0000, 0x080c, 0x9229,
-	0x2c08, 0x080c, 0xe477, 0x007e, 0x2001, 0x0007, 0x080c, 0x6615,
-	0x2001, 0x0007, 0x080c, 0x65e9, 0x001e, 0x004e, 0x9006, 0x015e,
-	0x003e, 0x002e, 0x00be, 0x00ce, 0x0005, 0x00d6, 0x2069, 0x026e,
-	0x6800, 0x9086, 0x0800, 0x0118, 0x6017, 0x0000, 0x0008, 0x9006,
-	0x00de, 0x0005, 0x00b6, 0x00f6, 0x0016, 0x0026, 0x0036, 0x0156,
-	0x2079, 0x026c, 0x7930, 0x7834, 0x080c, 0x287c, 0x11d0, 0x080c,
-	0x6699, 0x11b8, 0x2011, 0x0270, 0x20a9, 0x0004, 0x0096, 0x2b48,
-	0x2019, 0x000a, 0x080c, 0xbf11, 0x009e, 0x1158, 0x2011, 0x0274,
-	0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019, 0x0006, 0x080c, 0xbf11,
-	0x009e, 0x015e, 0x003e, 0x002e, 0x001e, 0x00fe, 0x00be, 0x0005,
-	0x00b6, 0x0006, 0x0016, 0x0026, 0x0036, 0x0156, 0x2011, 0x0263,
-	0x2204, 0x8211, 0x220c, 0x080c, 0x287c, 0x11d0, 0x080c, 0x6699,
-	0x11b8, 0x2011, 0x0276, 0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019,
-	0x000a, 0x080c, 0xbf11, 0x009e, 0x1158, 0x2011, 0x027a, 0x20a9,
-	0x0004, 0x0096, 0x2b48, 0x2019, 0x0006, 0x080c, 0xbf11, 0x009e,
-	0x015e, 0x003e, 0x002e, 0x001e, 0x000e, 0x00be, 0x0005, 0x00e6,
-	0x00c6, 0x0086, 0x0076, 0x0066, 0x0056, 0x0046, 0x0026, 0x0126,
-	0x2091, 0x8000, 0x2740, 0x2029, 0x19ef, 0x252c, 0x2021, 0x19f5,
-	0x2424, 0x2061, 0x1cd0, 0x2071, 0x1800, 0x7654, 0x7074, 0x81ff,
-	0x0150, 0x0006, 0x9186, 0x1ab2, 0x000e, 0x0128, 0x8001, 0x9602,
-	0x1a04, 0xe514, 0x0018, 0x9606, 0x0904, 0xe514, 0x080c, 0x8a3d,
-	0x0904, 0xe50b, 0x2100, 0x9c06, 0x0904, 0xe50b, 0x080c, 0xe77b,
-	0x1904, 0xe50b, 0x080c, 0xeb19, 0x0904, 0xe50b, 0x080c, 0xe76b,
-	0x0904, 0xe50b, 0x6720, 0x9786, 0x0001, 0x1148, 0x080c, 0x3373,
-	0x0904, 0xe553, 0x6004, 0x9086, 0x0000, 0x1904, 0xe553, 0x9786,
-	0x0004, 0x0904, 0xe553, 0x9786, 0x0007, 0x0904, 0xe50b, 0x2500,
-	0x9c06, 0x0904, 0xe50b, 0x2400, 0x9c06, 0x05e8, 0x88ff, 0x0118,
-	0x6054, 0x9906, 0x15c0, 0x0096, 0x6000, 0x9086, 0x0004, 0x1120,
-	0x0016, 0x080c, 0x1aa1, 0x001e, 0x9786, 0x000a, 0x0148, 0x080c,
-	0xce8e, 0x1130, 0x080c, 0xb905, 0x009e, 0x080c, 0xaf74, 0x0418,
-	0x6014, 0x2048, 0x080c, 0xcc86, 0x01d8, 0x9786, 0x0003, 0x1570,
-	0xa867, 0x0103, 0xa87c, 0xd0cc, 0x0130, 0x0096, 0xa878, 0x2048,
-	0x080c, 0x0fb1, 0x009e, 0xab7a, 0xa877, 0x0000, 0x080c, 0xea94,
-	0x0016, 0x080c, 0xcf7c, 0x080c, 0x6d0b, 0x001e, 0x080c, 0xce71,
-	0x009e, 0x080c, 0xaf74, 0x9ce0, 0x0018, 0x2001, 0x181a, 0x2004,
-	0x9c02, 0x1210, 0x0804, 0xe48b, 0x012e, 0x002e, 0x004e, 0x005e,
-	0x006e, 0x007e, 0x008e, 0x00ce, 0x00ee, 0x0005, 0x9786, 0x0006,
-	0x1150, 0x9386, 0x0005, 0x0128, 0x080c, 0xea94, 0x080c, 0xe6dd,
-	0x08f8, 0x009e, 0x0c00, 0x9786, 0x0009, 0x11f8, 0x6000, 0x9086,
-	0x0004, 0x01c0, 0x6000, 0x9086, 0x0003, 0x11a0, 0x080c, 0x9713,
-	0x0096, 0x6114, 0x2148, 0x080c, 0xcc86, 0x0118, 0x6010, 0x080c,
-	0x6d17, 0x009e, 0x00c6, 0x080c, 0xaf43, 0x00ce, 0x0036, 0x080c,
-	0x9891, 0x003e, 0x009e, 0x0804, 0xe50b, 0x9786, 0x000a, 0x0904,
-	0xe4fb, 0x0804, 0xe4f0, 0x81ff, 0x0904, 0xe50b, 0x9180, 0x0001,
-	0x2004, 0x9086, 0x0018, 0x0138, 0x9180, 0x0001, 0x2004, 0x9086,
-	0x002d, 0x1904, 0xe50b, 0x6000, 0x9086, 0x0002, 0x1904, 0xe50b,
-	0x080c, 0xce7d, 0x0138, 0x080c, 0xce8e, 0x1904, 0xe50b, 0x080c,
-	0xb905, 0x0038, 0x080c, 0x3247, 0x080c, 0xce8e, 0x1110, 0x080c,
-	0xb905, 0x080c, 0xaf74, 0x0804, 0xe50b, 0xa864, 0x9084, 0x00ff,
-	0x9086, 0x0039, 0x0005, 0x00c6, 0x00e6, 0x0016, 0x2c08, 0x2170,
-	0x9006, 0x080c, 0xe704, 0x001e, 0x0120, 0x6020, 0x9084, 0x000f,
-	0x001b, 0x00ee, 0x00ce, 0x0005, 0xe5a2, 0xe5a2, 0xe5a2, 0xe5a2,
-	0xe5a2, 0xe5a2, 0xe5a4, 0xe5a2, 0xe5a2, 0xe5a2, 0xe5a2, 0xaf74,
-	0xaf74, 0xe5a2, 0x9006, 0x0005, 0x0036, 0x0046, 0x0016, 0x7010,
-	0x00b6, 0x2058, 0xbca0, 0x00be, 0x2c00, 0x2009, 0x0020, 0x080c,
-	0xe73a, 0x001e, 0x004e, 0x2019, 0x0002, 0x080c, 0xe2c0, 0x003e,
-	0x9085, 0x0001, 0x0005, 0x0096, 0x080c, 0xcc86, 0x0140, 0x6014,
-	0x904d, 0x080c, 0xc8a5, 0x687b, 0x0005, 0x080c, 0x6d17, 0x009e,
-	0x080c, 0xaf74, 0x9085, 0x0001, 0x0005, 0x2001, 0x0001, 0x080c,
-	0x65d5, 0x0156, 0x0016, 0x0026, 0x0036, 0x20a9, 0x0004, 0x2019,
-	0x1805, 0x2011, 0x0276, 0x080c, 0xbefd, 0x003e, 0x002e, 0x001e,
-	0x015e, 0x9005, 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x0086, 0x0076,
-	0x0066, 0x00b6, 0x0126, 0x2091, 0x8000, 0x2740, 0x2061, 0x1cd0,
-	0x2079, 0x0001, 0x8fff, 0x0904, 0xe63d, 0x2071, 0x1800, 0x7654,
-	0x7074, 0x8001, 0x9602, 0x1a04, 0xe63d, 0x88ff, 0x0120, 0x2800,
-	0x9c06, 0x1590, 0x2078, 0x080c, 0xe76b, 0x0570, 0x2400, 0x9c06,
-	0x0558, 0x6720, 0x9786, 0x0006, 0x1538, 0x9786, 0x0007, 0x0520,
-	0x88ff, 0x1140, 0x6010, 0x9b06, 0x11f8, 0x85ff, 0x0118, 0x6054,
-	0x9106, 0x11d0, 0x0096, 0x601c, 0xd084, 0x0140, 0x080c, 0xe997,
-	0x080c, 0xd3a0, 0x080c, 0x1aa1, 0x6023, 0x0007, 0x6014, 0x2048,
-	0x080c, 0xcc86, 0x0120, 0x0046, 0x080c, 0xe6dd, 0x004e, 0x009e,
-	0x080c, 0xaf74, 0x88ff, 0x1198, 0x9ce0, 0x0018, 0x2001, 0x181a,
-	0x2004, 0x9c02, 0x1210, 0x0804, 0xe5f2, 0x9006, 0x012e, 0x00be,
-	0x006e, 0x007e, 0x008e, 0x00ce, 0x00ee, 0x00fe, 0x0005, 0x98c5,
-	0x0001, 0x0ca0, 0x00b6, 0x0076, 0x0056, 0x0086, 0x9046, 0x2029,
-	0x0001, 0x2c20, 0x2019, 0x0002, 0x6210, 0x2258, 0x0096, 0x904e,
-	0x080c, 0xa76b, 0x009e, 0x008e, 0x903e, 0x080c, 0xa816, 0x080c,
-	0xe5e3, 0x005e, 0x007e, 0x00be, 0x0005, 0x00b6, 0x0046, 0x0056,
-	0x0076, 0x00c6, 0x0156, 0x2c20, 0x2128, 0x20a9, 0x007f, 0x900e,
-	0x0016, 0x0036, 0x080c, 0x6699, 0x1190, 0x0056, 0x0086, 0x9046,
-	0x2508, 0x2029, 0x0001, 0x0096, 0x904e, 0x080c, 0xa76b, 0x009e,
-	0x008e, 0x903e, 0x080c, 0xa816, 0x080c, 0xe5e3, 0x005e, 0x003e,
-	0x001e, 0x8108, 0x1f04, 0xe670, 0x015e, 0x00ce, 0x007e, 0x005e,
-	0x004e, 0x00be, 0x0005, 0x00b6, 0x0076, 0x0056, 0x6210, 0x2258,
-	0x0086, 0x9046, 0x2029, 0x0001, 0x2019, 0x0048, 0x0096, 0x904e,
-	0x080c, 0xa76b, 0x009e, 0x008e, 0x903e, 0x080c, 0xa816, 0x2c20,
-	0x080c, 0xe5e3, 0x005e, 0x007e, 0x00be, 0x0005, 0x00b6, 0x0046,
-	0x0056, 0x0076, 0x00c6, 0x0156, 0x2c20, 0x20a9, 0x0800, 0x900e,
-	0x0016, 0x0036, 0x080c, 0x6699, 0x11a0, 0x0086, 0x9046, 0x2828,
-	0x0046, 0x2021, 0x0001, 0x080c, 0xe97b, 0x004e, 0x0096, 0x904e,
-	0x080c, 0xa76b, 0x009e, 0x008e, 0x903e, 0x080c, 0xa816, 0x080c,
-	0xe5e3, 0x003e, 0x001e, 0x8108, 0x1f04, 0xe6b8, 0x015e, 0x00ce,
-	0x007e, 0x005e, 0x004e, 0x00be, 0x0005, 0x0016, 0x00f6, 0x080c,
-	0xcc84, 0x0198, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0046, 0x0180,
-	0xa800, 0x907d, 0x0138, 0xa803, 0x0000, 0xab82, 0x080c, 0x6d17,
-	0x2f48, 0x0cb0, 0xab82, 0x080c, 0x6d17, 0x00fe, 0x001e, 0x0005,
-	0xa800, 0x907d, 0x0130, 0xa803, 0x0000, 0x080c, 0x6d17, 0x2f48,
-	0x0cb8, 0x080c, 0x6d17, 0x0c88, 0x00e6, 0x0046, 0x0036, 0x2061,
-	0x1cd0, 0x9005, 0x1138, 0x2071, 0x1800, 0x7454, 0x7074, 0x8001,
-	0x9402, 0x12f8, 0x2100, 0x9c06, 0x0188, 0x6000, 0x9086, 0x0000,
-	0x0168, 0x6008, 0x9206, 0x1150, 0x6320, 0x9386, 0x0009, 0x01b0,
-	0x6010, 0x91a0, 0x0004, 0x2424, 0x9406, 0x0140, 0x9ce0, 0x0018,
-	0x2001, 0x181a, 0x2004, 0x9c02, 0x1220, 0x0c20, 0x9085, 0x0001,
-	0x0008, 0x9006, 0x003e, 0x004e, 0x00ee, 0x0005, 0x631c, 0xd3c4,
-	0x1d68, 0x0c30, 0x0096, 0x0006, 0x080c, 0x0fff, 0x000e, 0x090c,
-	0x0dd5, 0xaae2, 0xa867, 0x010d, 0xa88e, 0x0026, 0x2010, 0x080c,
-	0xcc74, 0x2001, 0x0000, 0x0120, 0x2200, 0x9080, 0x0015, 0x2004,
-	0x002e, 0xa87a, 0x9186, 0x0020, 0x0110, 0xa8e3, 0xffff, 0xa986,
-	0xac76, 0xa87f, 0x0000, 0x2001, 0x198d, 0x2004, 0xa882, 0x9006,
-	0xa802, 0xa86a, 0xa88a, 0x0126, 0x2091, 0x8000, 0x080c, 0x6d17,
-	0x012e, 0x009e, 0x0005, 0x6700, 0x9786, 0x0000, 0x0158, 0x9786,
-	0x0001, 0x0140, 0x9786, 0x000a, 0x0128, 0x9786, 0x0009, 0x0110,
-	0x9085, 0x0001, 0x0005, 0x00e6, 0x6010, 0x9075, 0x0138, 0x00b6,
-	0x2058, 0xb8a0, 0x00be, 0x9206, 0x00ee, 0x0005, 0x9085, 0x0001,
-	0x0cd8, 0x0016, 0x6004, 0x908e, 0x001e, 0x11a0, 0x8007, 0x6134,
-	0x918c, 0x00ff, 0x9105, 0x6036, 0x6007, 0x0085, 0x6003, 0x000b,
-	0x6023, 0x0005, 0x2001, 0x1986, 0x2004, 0x601a, 0x080c, 0x91b1,
-	0x080c, 0x9763, 0x001e, 0x0005, 0xa001, 0xa001, 0x0005, 0x6024,
-	0xd0e4, 0x0158, 0xd0cc, 0x0118, 0x080c, 0xcfc0, 0x0030, 0x080c,
-	0xe997, 0x080c, 0x876f, 0x080c, 0xaf43, 0x0005, 0x9280, 0x0008,
-	0x2004, 0x9084, 0x000f, 0x0002, 0xe7ca, 0xe7ca, 0xe7ca, 0xe7cc,
-	0xe7ca, 0xe7cc, 0xe7cc, 0xe7ca, 0xe7cc, 0xe7ca, 0xe7ca, 0xe7ca,
-	0xe7ca, 0xe7ca, 0x9006, 0x0005, 0x9085, 0x0001, 0x0005, 0x9280,
-	0x0008, 0x2004, 0x9084, 0x000f, 0x0002, 0xe7e3, 0xe7e3, 0xe7e3,
-	0xe7e3, 0xe7e3, 0xe7e3, 0xe7f0, 0xe7e3, 0xe7e3, 0xe7e3, 0xe7e3,
-	0xe7e3, 0xe7e3, 0xe7e3, 0x6007, 0x003b, 0x602f, 0x0009, 0x6017,
-	0x2a00, 0x6003, 0x0001, 0x080c, 0x91b1, 0x080c, 0x9763, 0x0005,
-	0x0096, 0x00c6, 0x2260, 0x080c, 0xe997, 0x6043, 0x0000, 0x6024,
-	0xc0f4, 0xc0e4, 0x6026, 0x603b, 0x0000, 0x00ce, 0x00d6, 0x2268,
-	0x9186, 0x0007, 0x1904, 0xe849, 0x6814, 0x9005, 0x0138, 0x2048,
-	0xa87c, 0xd0fc, 0x1118, 0x00de, 0x009e, 0x08a8, 0x6007, 0x003a,
-	0x6003, 0x0001, 0x080c, 0x91b1, 0x080c, 0x9763, 0x00c6, 0x2d60,
-	0x6100, 0x9186, 0x0002, 0x1904, 0xe8c0, 0x6014, 0x9005, 0x1138,
-	0x6000, 0x9086, 0x0007, 0x190c, 0x0dd5, 0x0804, 0xe8c0, 0x2048,
-	0x080c, 0xcc86, 0x1130, 0x0028, 0x2048, 0xa800, 0x9005, 0x1de0,
-	0x2900, 0x2048, 0xa87c, 0x9084, 0x0003, 0x9086, 0x0002, 0x1168,
-	0xa87c, 0xc0dc, 0xc0f4, 0xa87e, 0xa880, 0xc0fc, 0xa882, 0x2009,
-	0x0043, 0x080c, 0xe114, 0x0804, 0xe8c0, 0x2009, 0x0041, 0x0804,
-	0xe8ba, 0x9186, 0x0005, 0x15a0, 0x6814, 0x2048, 0xa87c, 0xd0bc,
-	0x1120, 0x00de, 0x009e, 0x0804, 0xe7e3, 0xd0b4, 0x0128, 0xd0fc,
-	0x090c, 0x0dd5, 0x0804, 0xe804, 0x6007, 0x003a, 0x6003, 0x0001,
-	0x080c, 0x91b1, 0x080c, 0x9763, 0x00c6, 0x2d60, 0x6100, 0x9186,
-	0x0002, 0x0120, 0x9186, 0x0004, 0x1904, 0xe8c0, 0x6814, 0x2048,
-	0xa97c, 0xc1f4, 0xc1dc, 0xa97e, 0xa980, 0xc1fc, 0xc1bc, 0xa982,
-	0x00f6, 0x2c78, 0x080c, 0x1754, 0x00fe, 0x2009, 0x0042, 0x04d0,
-	0x0036, 0x080c, 0x0fff, 0x090c, 0x0dd5, 0xa867, 0x010d, 0x9006,
-	0xa802, 0xa86a, 0xa88a, 0x2d18, 0xab8e, 0xa887, 0x0045, 0x2c00,
-	0xa892, 0x6038, 0xa8a2, 0x2360, 0x6024, 0xc0dd, 0x6026, 0x6010,
-	0x00b6, 0x2058, 0xb8a0, 0x00be, 0x2004, 0x6354, 0xab7a, 0xa876,
-	0x9006, 0xa87e, 0xa882, 0xad9a, 0xae96, 0xa89f, 0x0001, 0x080c,
-	0x6d17, 0x2019, 0x0045, 0x6008, 0x2068, 0x080c, 0xe2c0, 0x2d00,
-	0x600a, 0x6023, 0x0006, 0x6003, 0x0007, 0x901e, 0x631a, 0x6342,
-	0x003e, 0x0038, 0x6043, 0x0000, 0x6003, 0x0007, 0x080c, 0xe114,
-	0x00ce, 0x00de, 0x009e, 0x0005, 0x9186, 0x0013, 0x1128, 0x6004,
-	0x9082, 0x0085, 0x2008, 0x00c2, 0x9186, 0x0027, 0x1178, 0x080c,
-	0x9657, 0x0036, 0x0096, 0x6014, 0x2048, 0x2019, 0x0004, 0x080c,
-	0xe6dd, 0x009e, 0x003e, 0x080c, 0x9763, 0x0005, 0x9186, 0x0014,
-	0x0d70, 0x080c, 0xafd9, 0x0005, 0xe8f3, 0xe8f1, 0xe8f1, 0xe8f1,
-	0xe8f1, 0xe8f1, 0xe8f3, 0xe8f1, 0xe8f1, 0xe8f1, 0xe8f1, 0xe8f1,
-	0xe8f1, 0x080c, 0x0dd5, 0x080c, 0x9657, 0x6003, 0x000c, 0x080c,
-	0x9763, 0x0005, 0x9182, 0x0092, 0x1220, 0x9182, 0x0085, 0x0208,
-	0x001a, 0x080c, 0xafd9, 0x0005, 0xe911, 0xe911, 0xe911, 0xe911,
-	0xe913, 0xe933, 0xe911, 0xe911, 0xe911, 0xe911, 0xe911, 0xe911,
-	0xe911, 0x080c, 0x0dd5, 0x00d6, 0x2c68, 0x080c, 0xaeed, 0x01b0,
-	0x6003, 0x0001, 0x6007, 0x001e, 0x2009, 0x026e, 0x210c, 0x613a,
-	0x2009, 0x026f, 0x210c, 0x613e, 0x600b, 0xffff, 0x6910, 0x6112,
-	0x6023, 0x0004, 0x080c, 0x91b1, 0x080c, 0x9763, 0x2d60, 0x080c,
-	0xaf43, 0x00de, 0x0005, 0x080c, 0xaf43, 0x0005, 0x00e6, 0x6010,
-	0x00b6, 0x2058, 0xb800, 0x00be, 0xd0ec, 0x00ee, 0x0005, 0x2009,
-	0x1867, 0x210c, 0xd1ec, 0x05b0, 0x6003, 0x0002, 0x6024, 0xc0e5,
-	0x6026, 0xd0cc, 0x0150, 0x2001, 0x1987, 0x2004, 0x6042, 0x2009,
-	0x1867, 0x210c, 0xd1f4, 0x1520, 0x00a0, 0x2009, 0x1867, 0x210c,
-	0xd1f4, 0x0128, 0x6024, 0xc0e4, 0x6026, 0x9006, 0x00d8, 0x2001,
-	0x1987, 0x200c, 0x2001, 0x1985, 0x2004, 0x9100, 0x9080, 0x000a,
-	0x6042, 0x6010, 0x00b6, 0x2058, 0xb8bc, 0x00be, 0x0008, 0x2104,
-	0x9005, 0x0118, 0x9088, 0x0003, 0x0cd0, 0x2c0a, 0x600f, 0x0000,
-	0x9085, 0x0001, 0x0005, 0x0016, 0x00c6, 0x00e6, 0x6154, 0xb8bc,
-	0x2060, 0x8cff, 0x0180, 0x84ff, 0x1118, 0x6054, 0x9106, 0x1138,
-	0x600c, 0x2072, 0x080c, 0x876f, 0x080c, 0xaf43, 0x0010, 0x9cf0,
-	0x0003, 0x2e64, 0x0c70, 0x00ee, 0x00ce, 0x001e, 0x0005, 0x00d6,
-	0x00b6, 0x6010, 0x2058, 0xb8bc, 0x2068, 0x9005, 0x0130, 0x9c06,
-	0x0110, 0x680c, 0x0cd0, 0x600c, 0x680e, 0x00be, 0x00de, 0x0005,
-	0x0026, 0x0036, 0x0156, 0x2011, 0x182c, 0x2204, 0x9084, 0x00ff,
-	0x2019, 0x026e, 0x2334, 0x9636, 0x1508, 0x8318, 0x2334, 0x2204,
-	0x9084, 0xff00, 0x9636, 0x11d0, 0x2011, 0x0270, 0x20a9, 0x0004,
-	0x6010, 0x0096, 0x2048, 0x2019, 0x000a, 0x080c, 0xbf11, 0x009e,
-	0x1168, 0x2011, 0x0274, 0x20a9, 0x0004, 0x6010, 0x0096, 0x2048,
-	0x2019, 0x0006, 0x080c, 0xbf11, 0x009e, 0x1100, 0x015e, 0x003e,
-	0x002e, 0x0005, 0x00e6, 0x2071, 0x1800, 0x080c, 0x6040, 0x080c,
-	0x2ff5, 0x00ee, 0x0005, 0x0096, 0x0026, 0x080c, 0x0fff, 0x090c,
-	0x0dd5, 0xa85c, 0x9080, 0x001a, 0x20a0, 0x20a9, 0x000c, 0xa860,
-	0x20e8, 0x9006, 0x4004, 0x9186, 0x0046, 0x1118, 0xa867, 0x0136,
-	0x0038, 0xa867, 0x0138, 0x9186, 0x0041, 0x0110, 0xa87b, 0x0001,
-	0x7038, 0x9084, 0xff00, 0x7240, 0x9294, 0xff00, 0x8007, 0x9215,
-	0xaa9a, 0x9186, 0x0046, 0x1168, 0x7038, 0x9084, 0x00ff, 0x723c,
-	0x9294, 0xff00, 0x9215, 0xaa9e, 0x723c, 0x9294, 0x00ff, 0xaaa2,
-	0x0060, 0x7040, 0x9084, 0x00ff, 0x7244, 0x9294, 0xff00, 0x9215,
-	0xaa9e, 0x7244, 0x9294, 0x00ff, 0xaaa2, 0x9186, 0x0046, 0x1118,
-	0x9e90, 0x0012, 0x0010, 0x9e90, 0x001a, 0x2204, 0x8007, 0xa8a6,
-	0x8210, 0x2204, 0x8007, 0xa8aa, 0x8210, 0x2204, 0x8007, 0xa8ae,
-	0x8210, 0x2204, 0x8007, 0xa8b2, 0x8210, 0x9186, 0x0046, 0x11b8,
-	0x9e90, 0x0016, 0x2204, 0x8007, 0xa8b6, 0x8210, 0x2204, 0x8007,
-	0xa8ba, 0x8210, 0x2204, 0x8007, 0xa8be, 0x8210, 0x2204, 0x8007,
-	0xa8c2, 0x8210, 0x2011, 0x0205, 0x2013, 0x0001, 0x00b0, 0x9e90,
-	0x001e, 0x2204, 0x8007, 0xa8b6, 0x8210, 0x2204, 0x8007, 0xa8ba,
-	0x2011, 0x0205, 0x2013, 0x0001, 0x2011, 0x0260, 0x2204, 0x8007,
-	0xa8be, 0x8210, 0x2204, 0x8007, 0xa8c2, 0x9186, 0x0046, 0x1118,
-	0x2011, 0x0262, 0x0010, 0x2011, 0x026a, 0x0146, 0x01d6, 0x0036,
-	0x20a9, 0x0001, 0x2019, 0x0008, 0xa860, 0x20e8, 0xa85c, 0x9080,
-	0x0031, 0x20a0, 0x2204, 0x8007, 0x4004, 0x8210, 0x8319, 0x1dd0,
-	0x003e, 0x01ce, 0x013e, 0x2011, 0x0205, 0x2013, 0x0000, 0x002e,
-	0x080c, 0x6d17, 0x009e, 0x0005, 0x00e6, 0x6010, 0x00b6, 0x2058,
-	0xb800, 0x00be, 0xd0fc, 0x0108, 0x0011, 0x00ee, 0x0005, 0xa880,
-	0xc0e5, 0xa882, 0x0005, 0x00e6, 0x00d6, 0x00c6, 0x0076, 0x0066,
-	0x0056, 0x0046, 0x0026, 0x0016, 0x0126, 0x2091, 0x8000, 0x2029,
-	0x19ef, 0x252c, 0x2021, 0x19f5, 0x2424, 0x2061, 0x1cd0, 0x2071,
-	0x1800, 0x7654, 0x7074, 0x9606, 0x0578, 0x6720, 0x9786, 0x0001,
-	0x0118, 0x9786, 0x0008, 0x1500, 0x2500, 0x9c06, 0x01e8, 0x2400,
-	0x9c06, 0x01d0, 0x080c, 0xe76b, 0x01b8, 0x080c, 0xe77b, 0x11a0,
-	0x6000, 0x9086, 0x0004, 0x1120, 0x0016, 0x080c, 0x1aa1, 0x001e,
-	0x080c, 0xce7d, 0x1110, 0x080c, 0x3247, 0x080c, 0xce8e, 0x1110,
-	0x080c, 0xb905, 0x080c, 0xaf74, 0x9ce0, 0x0018, 0x2001, 0x181a,
-	0x2004, 0x9c02, 0x1208, 0x0858, 0x012e, 0x001e, 0x002e, 0x004e,
-	0x005e, 0x006e, 0x007e, 0x00ce, 0x00de, 0x00ee, 0x0005, 0x2001,
-	0x1810, 0x2004, 0xd0dc, 0x0005, 0x0006, 0x2001, 0x1837, 0x2004,
-	0xd09c, 0x000e, 0x0005, 0x0006, 0x0036, 0x0046, 0x080c, 0xd388,
-	0x0168, 0x2019, 0xffff, 0x9005, 0x0128, 0x6010, 0x00b6, 0x2058,
-	0xbba0, 0x00be, 0x2021, 0x0004, 0x080c, 0x4d36, 0x004e, 0x003e,
-	0x000e, 0x6004, 0x9086, 0x0001, 0x1128, 0x080c, 0xa8dc, 0x080c,
-	0xaf74, 0x9006, 0x0005, 0x00e6, 0x00c6, 0x00b6, 0x0046, 0x2061,
+	0x918c, 0xffff, 0x11b0, 0x080c, 0x2403, 0x2099, 0x026c, 0x2001,
+	0x0014, 0x3518, 0x9312, 0x0108, 0x1218, 0x23a8, 0x4003, 0x0400,
+	0x20a8, 0x4003, 0x22a8, 0x8108, 0x080c, 0x2403, 0x2099, 0x0260,
+	0x0ca8, 0x080c, 0x2403, 0x2061, 0x19a1, 0x6004, 0x2098, 0x6008,
+	0x3518, 0x9312, 0x0108, 0x1218, 0x23a8, 0x4003, 0x0048, 0x20a8,
+	0x4003, 0x22a8, 0x8108, 0x080c, 0x2403, 0x2099, 0x0260, 0x0ca8,
+	0x2061, 0x19a1, 0x2019, 0x0280, 0x3300, 0x931e, 0x0110, 0x6006,
+	0x0020, 0x2001, 0x0260, 0x6006, 0x8108, 0x2162, 0x9292, 0x0021,
+	0x9296, 0xffff, 0x620a, 0x00ce, 0x003e, 0x002e, 0x001e, 0x000e,
+	0x0005, 0x0006, 0x0016, 0x0026, 0x0036, 0x00c6, 0x81ff, 0x11b8,
+	0x080c, 0x241b, 0x20a1, 0x024c, 0x2001, 0x0014, 0x3518, 0x9312,
+	0x1218, 0x23a8, 0x4003, 0x0418, 0x20a8, 0x4003, 0x82ff, 0x01f8,
+	0x22a8, 0x8108, 0x080c, 0x241b, 0x20a1, 0x0240, 0x0c98, 0x080c,
+	0x241b, 0x2061, 0x19a4, 0x6004, 0x20a0, 0x6008, 0x3518, 0x9312,
+	0x1218, 0x23a8, 0x4003, 0x0058, 0x20a8, 0x4003, 0x82ff, 0x0138,
+	0x22a8, 0x8108, 0x080c, 0x241b, 0x20a1, 0x0240, 0x0c98, 0x2061,
+	0x19a4, 0x2019, 0x0260, 0x3400, 0x931e, 0x0110, 0x6006, 0x0020,
+	0x2001, 0x0240, 0x6006, 0x8108, 0x2162, 0x9292, 0x0021, 0x9296,
+	0xffff, 0x620a, 0x00ce, 0x003e, 0x002e, 0x001e, 0x000e, 0x0005,
+	0x00b6, 0x0066, 0x6610, 0x2658, 0xbe04, 0x96b4, 0xff00, 0x8637,
+	0x9686, 0x0006, 0x0170, 0x9686, 0x0004, 0x0158, 0xbe04, 0x96b4,
+	0x00ff, 0x9686, 0x0006, 0x0128, 0x9686, 0x0004, 0x0110, 0x9085,
+	0x0001, 0x006e, 0x00be, 0x0005, 0x00d6, 0x080c, 0xdcc8, 0x00de,
+	0x0005, 0x00d6, 0x080c, 0xdcd5, 0x1520, 0x680c, 0x908c, 0xff00,
+	0x6820, 0x9084, 0x00ff, 0x9115, 0x6216, 0x6824, 0x602e, 0xd1e4,
+	0x0130, 0x9006, 0x080c, 0xed0a, 0x2009, 0x0001, 0x0078, 0xd1ec,
+	0x0180, 0x6920, 0x918c, 0x00ff, 0x6824, 0x080c, 0x2889, 0x1148,
+	0x2001, 0x0001, 0x080c, 0xed0a, 0x2110, 0x900e, 0x080c, 0x3294,
+	0x0018, 0x9085, 0x0001, 0x0008, 0x9006, 0x00de, 0x0005, 0x00b6,
+	0x00c6, 0x080c, 0xb139, 0x05a8, 0x0016, 0x0026, 0x00c6, 0x2011,
+	0x0263, 0x2204, 0x8211, 0x220c, 0x080c, 0x2889, 0x1578, 0x080c,
+	0x66ac, 0x1560, 0xbe12, 0xbd16, 0x00ce, 0x002e, 0x001e, 0x2b00,
+	0x6012, 0x080c, 0xeb3c, 0x11d8, 0x080c, 0x336f, 0x11c0, 0x080c,
+	0xdc30, 0x0510, 0x2001, 0x0007, 0x080c, 0x665d, 0x2001, 0x0007,
+	0x080c, 0x6689, 0x6017, 0x0000, 0x6023, 0x0001, 0x6007, 0x0001,
+	0x6003, 0x0001, 0x080c, 0x937d, 0x080c, 0x98e7, 0x0010, 0x080c,
+	0xb0e7, 0x9085, 0x0001, 0x00ce, 0x00be, 0x0005, 0x080c, 0xb0e7,
+	0x00ce, 0x002e, 0x001e, 0x0ca8, 0x080c, 0xb0e7, 0x9006, 0x0c98,
+	0x2069, 0x026d, 0x6800, 0x9082, 0x0010, 0x1228, 0x6017, 0x0000,
+	0x9085, 0x0001, 0x0008, 0x9006, 0x0005, 0x6017, 0x0000, 0x2069,
+	0x026c, 0x6808, 0x9084, 0xff00, 0x9086, 0x0800, 0x1190, 0x6904,
+	0x9186, 0x0018, 0x0118, 0x9186, 0x0014, 0x1158, 0x810f, 0x6800,
+	0x9084, 0x00ff, 0x910d, 0x615a, 0x908e, 0x0014, 0x0110, 0x908e,
+	0x0010, 0x0005, 0x6004, 0x90b2, 0x0053, 0x1a0c, 0x0dc5, 0x91b6,
+	0x0013, 0x1130, 0x2008, 0x91b2, 0x0040, 0x1a04, 0xde42, 0x040a,
+	0x91b6, 0x0027, 0x0198, 0x9186, 0x0015, 0x0118, 0x9186, 0x0016,
+	0x1148, 0x080c, 0xd56e, 0x0128, 0x6000, 0x9086, 0x0002, 0x0904,
+	0xbb12, 0x0005, 0x91b6, 0x0014, 0x190c, 0x0dc5, 0x2001, 0x0007,
+	0x080c, 0x6689, 0x080c, 0x97db, 0x080c, 0xb11a, 0x080c, 0x98e7,
+	0x0005, 0xdd61, 0xdd63, 0xdd61, 0xdd61, 0xdd61, 0xdd63, 0xdd72,
+	0xde3b, 0xddc4, 0xde3b, 0xddec, 0xde3b, 0xdd72, 0xde3b, 0xde33,
+	0xde3b, 0xde33, 0xde3b, 0xde3b, 0xdd61, 0xdd61, 0xdd61, 0xdd61,
+	0xdd61, 0xdd61, 0xdd61, 0xdd61, 0xdd61, 0xdd61, 0xdd61, 0xdd63,
+	0xdd61, 0xde3b, 0xdd61, 0xdd61, 0xde3b, 0xdd61, 0xde38, 0xde3b,
+	0xdd61, 0xdd61, 0xdd61, 0xdd61, 0xde3b, 0xde3b, 0xdd61, 0xde3b,
+	0xde3b, 0xdd61, 0xdd6d, 0xdd61, 0xdd61, 0xdd61, 0xdd61, 0xde37,
+	0xde3b, 0xdd61, 0xdd61, 0xde3b, 0xde3b, 0xdd61, 0xdd61, 0xdd61,
+	0xdd61, 0x080c, 0x0dc5, 0x080c, 0x97db, 0x080c, 0xd560, 0x6003,
+	0x0002, 0x080c, 0x98e7, 0x0804, 0xde41, 0x9006, 0x080c, 0x6649,
+	0x0804, 0xde3b, 0x080c, 0x6a84, 0x1904, 0xde3b, 0x9006, 0x080c,
+	0x6649, 0x6010, 0x2058, 0xb810, 0x9086, 0x00ff, 0x1140, 0x00f6,
+	0x2079, 0x1800, 0x78a8, 0x8000, 0x78aa, 0x00fe, 0x0428, 0x6010,
+	0x2058, 0xb8c0, 0x9005, 0x1178, 0x080c, 0xd548, 0x1904, 0xde3b,
+	0x0036, 0x0046, 0xbba0, 0x2021, 0x0007, 0x080c, 0x4d9a, 0x004e,
+	0x003e, 0x0804, 0xde3b, 0x080c, 0x33a0, 0x1904, 0xde3b, 0x2001,
+	0x1800, 0x2004, 0x9086, 0x0002, 0x1138, 0x00f6, 0x2079, 0x1800,
+	0x78a8, 0x8000, 0x78aa, 0x00fe, 0x2001, 0x0002, 0x080c, 0x665d,
+	0x080c, 0x97db, 0x6023, 0x0001, 0x6003, 0x0001, 0x6007, 0x0002,
+	0x080c, 0x937d, 0x080c, 0x98e7, 0x6110, 0x2158, 0x2009, 0x0001,
+	0x080c, 0x8711, 0x0804, 0xde41, 0x6610, 0x2658, 0xbe04, 0x96b4,
+	0xff00, 0x8637, 0x9686, 0x0006, 0x0148, 0x9686, 0x0004, 0x0130,
+	0x080c, 0x8ef4, 0x2001, 0x0004, 0x080c, 0x6689, 0x080c, 0xed59,
+	0x0904, 0xde3b, 0x080c, 0x97db, 0x2001, 0x0004, 0x080c, 0x665d,
+	0x6023, 0x0001, 0x6003, 0x0001, 0x6007, 0x0003, 0x080c, 0x937d,
+	0x080c, 0x98e7, 0x0804, 0xde41, 0x2001, 0x1800, 0x2004, 0x9086,
+	0x0003, 0x1158, 0x0036, 0x0046, 0x6010, 0x2058, 0xbba0, 0x2021,
+	0x0006, 0x080c, 0x4d9a, 0x004e, 0x003e, 0x2001, 0x0006, 0x080c,
+	0xde5f, 0x6610, 0x2658, 0xbe04, 0x0066, 0x96b4, 0xff00, 0x8637,
+	0x9686, 0x0006, 0x006e, 0x0168, 0x2001, 0x0006, 0x080c, 0x6689,
+	0x9284, 0x00ff, 0x908e, 0x0007, 0x1120, 0x2001, 0x0006, 0x080c,
+	0x665d, 0x080c, 0x6a84, 0x11f8, 0x2001, 0x1837, 0x2004, 0xd0a4,
+	0x01d0, 0xbe04, 0x96b4, 0x00ff, 0x9686, 0x0006, 0x01a0, 0x00f6,
+	0x2079, 0x1800, 0x78a8, 0x8000, 0x78aa, 0x00fe, 0x0804, 0xddac,
+	0x2001, 0x0004, 0x0030, 0x2001, 0x0006, 0x0449, 0x0020, 0x0018,
+	0x0010, 0x080c, 0x6689, 0x080c, 0x97db, 0x080c, 0xb0e7, 0x080c,
+	0x98e7, 0x0005, 0x2600, 0x0002, 0xde56, 0xde56, 0xde56, 0xde56,
+	0xde56, 0xde58, 0xde56, 0xde58, 0xde56, 0xde56, 0xde58, 0xde56,
+	0xde56, 0xde56, 0xde58, 0xde58, 0xde58, 0xde58, 0x080c, 0x0dc5,
+	0x080c, 0x97db, 0x080c, 0xb0e7, 0x080c, 0x98e7, 0x0005, 0x0016,
+	0x00b6, 0x00d6, 0x6110, 0x2158, 0xb900, 0xd184, 0x0138, 0x080c,
+	0x665d, 0x9006, 0x080c, 0x6649, 0x080c, 0x3274, 0x00de, 0x00be,
+	0x001e, 0x0005, 0x6610, 0x2658, 0xb804, 0x9084, 0xff00, 0x8007,
+	0x90b2, 0x000c, 0x1a0c, 0x0dc5, 0x91b6, 0x0015, 0x1110, 0x003b,
+	0x0028, 0x91b6, 0x0016, 0x190c, 0x0dc5, 0x006b, 0x0005, 0xbbb4,
+	0xbbb4, 0xbbb4, 0xbbb4, 0xdef4, 0xbbb4, 0xdede, 0xde9f, 0xbbb4,
+	0xbbb4, 0xbbb4, 0xbbb4, 0xbbb4, 0xbbb4, 0xbbb4, 0xbbb4, 0xdef4,
+	0xbbb4, 0xdede, 0xdee5, 0xbbb4, 0xbbb4, 0xbbb4, 0xbbb4, 0x00f6,
+	0x080c, 0x6a84, 0x11d8, 0x080c, 0xd548, 0x11c0, 0x6010, 0x905d,
+	0x01a8, 0xb8c0, 0x9005, 0x0190, 0x9006, 0x080c, 0x6649, 0x2001,
+	0x0002, 0x080c, 0x665d, 0x6023, 0x0001, 0x6003, 0x0001, 0x6007,
+	0x0002, 0x080c, 0x937d, 0x080c, 0x98e7, 0x00f0, 0x2011, 0x0263,
+	0x2204, 0x8211, 0x220c, 0x080c, 0x2889, 0x11b0, 0x080c, 0x6717,
+	0x0118, 0x080c, 0xb0e7, 0x0080, 0xb810, 0x0006, 0xb814, 0x0006,
+	0xb8c0, 0x0006, 0x080c, 0x613b, 0x000e, 0xb8c2, 0x000e, 0xb816,
+	0x000e, 0xb812, 0x080c, 0xb0e7, 0x00fe, 0x0005, 0x6604, 0x96b6,
+	0x001e, 0x1110, 0x080c, 0xb0e7, 0x0005, 0x080c, 0xbf4f, 0x1148,
+	0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x937d, 0x080c, 0x98e7,
+	0x0010, 0x080c, 0xb0e7, 0x0005, 0x0804, 0xb0e7, 0x6004, 0x908a,
+	0x0053, 0x1a0c, 0x0dc5, 0x080c, 0x97db, 0x080c, 0xb11a, 0x080c,
+	0x98e7, 0x0005, 0x9182, 0x0040, 0x0002, 0xdf19, 0xdf19, 0xdf19,
+	0xdf19, 0xdf1b, 0xdf19, 0xdf19, 0xdf19, 0xdf19, 0xdf19, 0xdf19,
+	0xdf19, 0xdf19, 0xdf19, 0xdf19, 0xdf19, 0xdf19, 0xdf19, 0xdf19,
+	0xdf19, 0x080c, 0x0dc5, 0x0096, 0x00b6, 0x00d6, 0x00e6, 0x00f6,
+	0x0046, 0x0026, 0x6210, 0x2258, 0xb8bc, 0x9005, 0x11a8, 0x6106,
+	0x2071, 0x0260, 0x7444, 0x94a4, 0xff00, 0x0904, 0xdf81, 0x080c,
+	0xecfe, 0x1170, 0x9486, 0x2000, 0x1158, 0x2009, 0x0001, 0x2011,
+	0x0200, 0x080c, 0x8916, 0x0020, 0x9026, 0x080c, 0xeb81, 0x0c38,
+	0x080c, 0x100e, 0x090c, 0x0dc5, 0x6003, 0x0007, 0xa867, 0x010d,
+	0x9006, 0xa802, 0xa86a, 0xac8a, 0x2c00, 0xa88e, 0x6008, 0xa8e2,
+	0x6010, 0x2058, 0xb8a0, 0x7130, 0xa97a, 0x0016, 0xa876, 0xa87f,
+	0x0000, 0xa883, 0x0000, 0xa887, 0x0036, 0x080c, 0x6dcb, 0x001e,
+	0x080c, 0xecfe, 0x1904, 0xdfe1, 0x9486, 0x2000, 0x1130, 0x2019,
+	0x0017, 0x080c, 0xe8b0, 0x0804, 0xdfe1, 0x9486, 0x0200, 0x1120,
+	0x080c, 0xe847, 0x0804, 0xdfe1, 0x9486, 0x0400, 0x0120, 0x9486,
+	0x1000, 0x1904, 0xdfe1, 0x2019, 0x0002, 0x080c, 0xe862, 0x0804,
+	0xdfe1, 0x2069, 0x1a75, 0x6a00, 0xd284, 0x0904, 0xe04b, 0x9284,
+	0x0300, 0x1904, 0xe044, 0x6804, 0x9005, 0x0904, 0xe02c, 0x2d78,
+	0x6003, 0x0007, 0x080c, 0x1027, 0x0904, 0xdfed, 0x7800, 0xd08c,
+	0x1118, 0x7804, 0x8001, 0x7806, 0x6017, 0x0000, 0x2001, 0x180f,
+	0x2004, 0xd084, 0x1904, 0xe04f, 0x9006, 0xa802, 0xa867, 0x0116,
+	0xa86a, 0x6008, 0xa8e2, 0x2c00, 0xa87a, 0x6010, 0x2058, 0xb8a0,
+	0x7130, 0xa9b6, 0xa876, 0xb928, 0xa9ba, 0xb92c, 0xa9be, 0xb930,
+	0xa9c2, 0xb934, 0xa9c6, 0xa883, 0x003d, 0x7044, 0x9084, 0x0003,
+	0x9080, 0xdfe9, 0x2005, 0xa87e, 0x20a9, 0x000a, 0x2001, 0x0270,
+	0xaa5c, 0x9290, 0x0021, 0x2009, 0x0205, 0x200b, 0x0080, 0x20e1,
+	0x0000, 0xab60, 0x23e8, 0x2098, 0x22a0, 0x4003, 0x200b, 0x0000,
+	0x2001, 0x027a, 0x200c, 0xa9b2, 0x8000, 0x200c, 0xa9ae, 0x080c,
+	0x6dcb, 0x002e, 0x004e, 0x00fe, 0x00ee, 0x00de, 0x00be, 0x009e,
+	0x0005, 0x0000, 0x0080, 0x0040, 0x0000, 0x2001, 0x1810, 0x2004,
+	0xd084, 0x0120, 0x080c, 0x100e, 0x1904, 0xdf96, 0x6017, 0xf100,
+	0x6003, 0x0001, 0x6007, 0x0041, 0x080c, 0x9335, 0x080c, 0x98e7,
+	0x0c00, 0x2069, 0x0260, 0x6848, 0x9084, 0xff00, 0x9086, 0x1200,
+	0x1198, 0x686c, 0x9084, 0x00ff, 0x0016, 0x6114, 0x918c, 0xf700,
+	0x910d, 0x6116, 0x001e, 0x6003, 0x0001, 0x6007, 0x0043, 0x080c,
+	0x9335, 0x080c, 0x98e7, 0x0828, 0x6868, 0x602e, 0x686c, 0x6032,
+	0x6017, 0xf200, 0x6003, 0x0001, 0x6007, 0x0041, 0x080c, 0x9335,
+	0x080c, 0x98e7, 0x0804, 0xdfe1, 0x2001, 0x180e, 0x2004, 0xd0ec,
+	0x0120, 0x2011, 0x8049, 0x080c, 0x4be3, 0x6017, 0xf300, 0x0010,
+	0x6017, 0xf100, 0x6003, 0x0001, 0x6007, 0x0041, 0x080c, 0x9335,
+	0x080c, 0x98e7, 0x0804, 0xdfe1, 0x6017, 0xf500, 0x0c98, 0x6017,
+	0xf600, 0x0804, 0xe001, 0x6017, 0xf200, 0x0804, 0xe001, 0xa867,
+	0x0146, 0xa86b, 0x0000, 0x6008, 0xa886, 0x2c00, 0xa87a, 0x7044,
+	0x9084, 0x0003, 0x9080, 0xdfe9, 0x2005, 0xa87e, 0x2928, 0x6010,
+	0x2058, 0xb8a0, 0xa876, 0xb828, 0xa88a, 0xb82c, 0xa88e, 0xb830,
+	0xa892, 0xb834, 0xa896, 0xa883, 0x003d, 0x2009, 0x0205, 0x2104,
+	0x9085, 0x0080, 0x200a, 0x20e1, 0x0000, 0x2011, 0x0210, 0x2214,
+	0x9294, 0x0fff, 0xaaa2, 0x9282, 0x0111, 0x1a0c, 0x0dc5, 0x8210,
+	0x821c, 0x2001, 0x026c, 0x2098, 0xa860, 0x20e8, 0xa85c, 0x9080,
+	0x0029, 0x20a0, 0x2011, 0xe0cb, 0x2041, 0x0001, 0x223d, 0x9784,
+	0x00ff, 0x9322, 0x1208, 0x2300, 0x20a8, 0x4003, 0x931a, 0x0530,
+	0x8210, 0xd7fc, 0x1130, 0x8d68, 0x2d0a, 0x2001, 0x0260, 0x2098,
+	0x0c68, 0x2950, 0x080c, 0x1027, 0x0170, 0x2900, 0xb002, 0xa867,
+	0x0147, 0xa86b, 0x0000, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x001b,
+	0x20a0, 0x8840, 0x08d8, 0x2548, 0xa800, 0x902d, 0x0118, 0x080c,
+	0x1040, 0x0cc8, 0x080c, 0x1040, 0x0804, 0xdfed, 0x2548, 0x8847,
+	0x9885, 0x0046, 0xa866, 0x2009, 0x0205, 0x200b, 0x0000, 0x080c,
+	0xe8e3, 0x0804, 0xdfe1, 0x8010, 0x0004, 0x801a, 0x0006, 0x8018,
+	0x0008, 0x8016, 0x000a, 0x8014, 0x9186, 0x0013, 0x1160, 0x6004,
+	0x908a, 0x0054, 0x1a0c, 0x0dc5, 0x9082, 0x0040, 0x0a0c, 0x0dc5,
+	0x2008, 0x0804, 0xe15a, 0x9186, 0x0051, 0x0108, 0x0048, 0x080c,
+	0xd56e, 0x0500, 0x6000, 0x9086, 0x0002, 0x11e0, 0x0804, 0xe1a3,
+	0x9186, 0x0027, 0x0190, 0x9186, 0x0048, 0x0128, 0x9186, 0x0014,
+	0x0160, 0x190c, 0x0dc5, 0x080c, 0xd56e, 0x0160, 0x6000, 0x9086,
+	0x0004, 0x190c, 0x0dc5, 0x0804, 0xe286, 0x6004, 0x9082, 0x0040,
+	0x2008, 0x001a, 0x080c, 0xb181, 0x0005, 0xe121, 0xe123, 0xe123,
+	0xe14a, 0xe121, 0xe121, 0xe121, 0xe121, 0xe121, 0xe121, 0xe121,
+	0xe121, 0xe121, 0xe121, 0xe121, 0xe121, 0xe121, 0xe121, 0xe121,
+	0xe121, 0x080c, 0x0dc5, 0x080c, 0x97db, 0x080c, 0x98e7, 0x0036,
+	0x0096, 0x6014, 0x904d, 0x01d8, 0x080c, 0xce3f, 0x01c0, 0x6003,
+	0x0002, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x1178,
+	0x2019, 0x0004, 0x080c, 0xe8e3, 0x6017, 0x0000, 0x6018, 0x9005,
+	0x1120, 0x2001, 0x1988, 0x2004, 0x601a, 0x6003, 0x0007, 0x009e,
+	0x003e, 0x0005, 0x0096, 0x080c, 0x97db, 0x080c, 0x98e7, 0x080c,
+	0xce3f, 0x0120, 0x6014, 0x2048, 0x080c, 0x1040, 0x080c, 0xb11a,
+	0x009e, 0x0005, 0x0002, 0xe16f, 0xe186, 0xe171, 0xe19d, 0xe16f,
+	0xe16f, 0xe16f, 0xe16f, 0xe16f, 0xe16f, 0xe16f, 0xe16f, 0xe16f,
+	0xe16f, 0xe16f, 0xe16f, 0xe16f, 0xe16f, 0xe16f, 0xe16f, 0x080c,
+	0x0dc5, 0x0096, 0x080c, 0x97db, 0x6014, 0x2048, 0xa87c, 0xd0b4,
+	0x0138, 0x6003, 0x0007, 0x2009, 0x0043, 0x080c, 0xb166, 0x0010,
+	0x6003, 0x0004, 0x080c, 0x98e7, 0x009e, 0x0005, 0x080c, 0x97db,
+	0x080c, 0xce3f, 0x0138, 0x6114, 0x0096, 0x2148, 0xa97c, 0x009e,
+	0xd1ec, 0x1138, 0x080c, 0x88eb, 0x080c, 0xb0e7, 0x080c, 0x98e7,
+	0x0005, 0x080c, 0xeb45, 0x0db0, 0x0cc8, 0x080c, 0x97db, 0x2009,
+	0x0041, 0x0804, 0xe30e, 0x9182, 0x0040, 0x0002, 0xe1ba, 0xe1bc,
+	0xe1ba, 0xe1ba, 0xe1ba, 0xe1ba, 0xe1ba, 0xe1ba, 0xe1ba, 0xe1ba,
+	0xe1ba, 0xe1ba, 0xe1ba, 0xe1ba, 0xe1ba, 0xe1ba, 0xe1ba, 0xe1bd,
+	0xe1ba, 0xe1ba, 0x080c, 0x0dc5, 0x0005, 0x00d6, 0x080c, 0x88eb,
+	0x00de, 0x080c, 0xeb9d, 0x080c, 0xb0e7, 0x0005, 0x9182, 0x0040,
+	0x0002, 0xe1dd, 0xe1dd, 0xe1dd, 0xe1dd, 0xe1dd, 0xe1dd, 0xe1dd,
+	0xe1dd, 0xe1dd, 0xe1df, 0xe24e, 0xe1dd, 0xe1dd, 0xe1dd, 0xe1dd,
+	0xe24e, 0xe1dd, 0xe1dd, 0xe1dd, 0xe1dd, 0x080c, 0x0dc5, 0x2001,
+	0x0105, 0x2004, 0x9084, 0x1800, 0x01c8, 0x2001, 0x0132, 0x200c,
+	0x2001, 0x0131, 0x2004, 0x9105, 0x1904, 0xe24e, 0x2009, 0x180c,
+	0x2104, 0xd0d4, 0x0904, 0xe24e, 0xc0d4, 0x200a, 0x2009, 0x0105,
+	0x2104, 0x9084, 0xe7fd, 0x9085, 0x0010, 0x200a, 0x2001, 0x1867,
+	0x2004, 0xd0e4, 0x1528, 0x603b, 0x0000, 0x080c, 0x9897, 0x6014,
+	0x0096, 0x2048, 0xa87c, 0xd0fc, 0x0188, 0x908c, 0x0003, 0x918e,
+	0x0002, 0x0508, 0x2001, 0x180c, 0x2004, 0xd0d4, 0x11e0, 0x080c,
+	0x9a09, 0x2009, 0x0041, 0x009e, 0x0804, 0xe30e, 0x080c, 0x9a09,
+	0x6003, 0x0007, 0x601b, 0x0000, 0x080c, 0x88eb, 0x009e, 0x0005,
+	0x2001, 0x0100, 0x2004, 0x9082, 0x0005, 0x0aa8, 0x2001, 0x011f,
+	0x2004, 0x603a, 0x0890, 0x2001, 0x180c, 0x200c, 0xc1d4, 0x2102,
+	0xd1cc, 0x0110, 0x080c, 0x2c9d, 0x080c, 0x9a09, 0x6014, 0x2048,
+	0xa97c, 0xd1ec, 0x1130, 0x080c, 0x88eb, 0x080c, 0xb0e7, 0x009e,
+	0x0005, 0x080c, 0xeb45, 0x0db8, 0x009e, 0x0005, 0x2001, 0x180c,
+	0x200c, 0xc1d4, 0x2102, 0x0036, 0x080c, 0x9897, 0x080c, 0x9a09,
+	0x6014, 0x0096, 0x2048, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be,
+	0xd0bc, 0x0188, 0xa87c, 0x9084, 0x0003, 0x9086, 0x0002, 0x0140,
+	0xa8ac, 0x6330, 0x931a, 0x6332, 0xa8b0, 0x632c, 0x931b, 0x632e,
+	0x6003, 0x0002, 0x0080, 0x2019, 0x0004, 0x080c, 0xe8e3, 0x6018,
+	0x9005, 0x1128, 0x2001, 0x1988, 0x2004, 0x8003, 0x601a, 0x6017,
+	0x0000, 0x6003, 0x0007, 0x009e, 0x003e, 0x0005, 0x9182, 0x0040,
+	0x0002, 0xe29d, 0xe29d, 0xe29d, 0xe29d, 0xe29d, 0xe29d, 0xe29d,
+	0xe29d, 0xe29f, 0xe29d, 0xe29d, 0xe29d, 0xe29d, 0xe29d, 0xe29d,
+	0xe29d, 0xe29d, 0xe29d, 0xe29d, 0xe2ea, 0x080c, 0x0dc5, 0x6014,
+	0x0096, 0x2048, 0xa834, 0xaa38, 0x6110, 0x00b6, 0x2158, 0xb900,
+	0x00be, 0xd1bc, 0x1190, 0x920d, 0x1518, 0xa87c, 0xd0fc, 0x0128,
+	0x2009, 0x0041, 0x009e, 0x0804, 0xe30e, 0x6003, 0x0007, 0x601b,
+	0x0000, 0x080c, 0x88eb, 0x009e, 0x0005, 0x6124, 0xd1f4, 0x1d58,
+	0x0006, 0x0046, 0xacac, 0x9422, 0xa9b0, 0x2200, 0x910b, 0x6030,
+	0x9420, 0x6432, 0x602c, 0x9109, 0x612e, 0x004e, 0x000e, 0x08d8,
+	0x6110, 0x00b6, 0x2158, 0xb900, 0x00be, 0xd1bc, 0x1178, 0x2009,
+	0x180e, 0x210c, 0xd19c, 0x0118, 0x6003, 0x0007, 0x0010, 0x6003,
+	0x0006, 0x00e9, 0x080c, 0x88ed, 0x009e, 0x0005, 0x6003, 0x0002,
+	0x009e, 0x0005, 0x6024, 0xd0f4, 0x0128, 0x080c, 0x1608, 0x1904,
+	0xe29f, 0x0005, 0x6014, 0x0096, 0x2048, 0xa834, 0xa938, 0x009e,
+	0x9105, 0x1120, 0x080c, 0x1608, 0x1904, 0xe29f, 0x0005, 0xd2fc,
+	0x0140, 0x8002, 0x8000, 0x8212, 0x9291, 0x0000, 0x2009, 0x0009,
+	0x0010, 0x2009, 0x0015, 0xaa9a, 0xa896, 0x0005, 0x9182, 0x0040,
+	0x0208, 0x0062, 0x9186, 0x0013, 0x0120, 0x9186, 0x0014, 0x190c,
+	0x0dc5, 0x6024, 0xd0dc, 0x090c, 0x0dc5, 0x0005, 0xe332, 0xe33e,
+	0xe34a, 0xe356, 0xe332, 0xe332, 0xe332, 0xe332, 0xe339, 0xe334,
+	0xe334, 0xe332, 0xe332, 0xe332, 0xe332, 0xe334, 0xe332, 0xe334,
+	0xe332, 0xe339, 0x080c, 0x0dc5, 0x6024, 0xd0dc, 0x090c, 0x0dc5,
+	0x0005, 0x6014, 0x9005, 0x190c, 0x0dc5, 0x0005, 0x6003, 0x0001,
+	0x6106, 0x080c, 0x9335, 0x0126, 0x2091, 0x8000, 0x080c, 0x98e7,
+	0x012e, 0x0005, 0x6003, 0x0001, 0x6106, 0x080c, 0x9335, 0x0126,
+	0x2091, 0x8000, 0x080c, 0x98e7, 0x012e, 0x0005, 0x6003, 0x0003,
+	0x6106, 0x2c10, 0x080c, 0x1c01, 0x0126, 0x2091, 0x8000, 0x080c,
+	0x939a, 0x080c, 0x9a09, 0x012e, 0x0005, 0x0126, 0x2091, 0x8000,
+	0x0036, 0x0096, 0x9182, 0x0040, 0x0023, 0x009e, 0x003e, 0x012e,
+	0x0005, 0xe385, 0xe387, 0xe399, 0xe3b3, 0xe385, 0xe385, 0xe385,
+	0xe385, 0xe385, 0xe385, 0xe385, 0xe385, 0xe385, 0xe385, 0xe385,
+	0xe385, 0xe385, 0xe385, 0xe385, 0xe385, 0x080c, 0x0dc5, 0x6014,
+	0x2048, 0xa87c, 0xd0fc, 0x01f8, 0x909c, 0x0003, 0x939e, 0x0003,
+	0x01d0, 0x6003, 0x0001, 0x6106, 0x080c, 0x9335, 0x080c, 0x98e7,
+	0x0470, 0x6014, 0x2048, 0xa87c, 0xd0fc, 0x0168, 0x909c, 0x0003,
+	0x939e, 0x0003, 0x0140, 0x6003, 0x0001, 0x6106, 0x080c, 0x9335,
+	0x080c, 0x98e7, 0x00e0, 0x901e, 0x6316, 0x631a, 0x2019, 0x0004,
+	0x080c, 0xe8e3, 0x00a0, 0x6014, 0x2048, 0xa87c, 0xd0fc, 0x0d98,
+	0x909c, 0x0003, 0x939e, 0x0003, 0x0d70, 0x6003, 0x0003, 0x6106,
+	0x2c10, 0x080c, 0x1c01, 0x080c, 0x939a, 0x080c, 0x9a09, 0x0005,
+	0x080c, 0x97db, 0x6114, 0x81ff, 0x0158, 0x0096, 0x2148, 0x080c,
+	0xec9b, 0x0036, 0x2019, 0x0029, 0x080c, 0xe8e3, 0x003e, 0x009e,
+	0x080c, 0xb11a, 0x080c, 0x98e7, 0x0005, 0x080c, 0x9897, 0x6114,
+	0x81ff, 0x0158, 0x0096, 0x2148, 0x080c, 0xec9b, 0x0036, 0x2019,
+	0x0029, 0x080c, 0xe8e3, 0x003e, 0x009e, 0x080c, 0xb11a, 0x080c,
+	0x9a09, 0x0005, 0x9182, 0x0085, 0x0002, 0xe404, 0xe402, 0xe402,
+	0xe410, 0xe402, 0xe402, 0xe402, 0xe402, 0xe402, 0xe402, 0xe402,
+	0xe402, 0xe402, 0x080c, 0x0dc5, 0x6003, 0x000b, 0x6106, 0x080c,
+	0x9335, 0x0126, 0x2091, 0x8000, 0x080c, 0x98e7, 0x012e, 0x0005,
+	0x0026, 0x00e6, 0x080c, 0xeb3c, 0x0118, 0x080c, 0xb0e7, 0x0450,
+	0x2071, 0x0260, 0x7224, 0x6216, 0x2001, 0x180e, 0x2004, 0xd0e4,
+	0x0150, 0x6010, 0x00b6, 0x2058, 0xbca0, 0x00be, 0x2c00, 0x2011,
+	0x014e, 0x080c, 0xb40c, 0x7220, 0x080c, 0xe77e, 0x0118, 0x6007,
+	0x0086, 0x0040, 0x6007, 0x0087, 0x7224, 0x9296, 0xffff, 0x1110,
+	0x6007, 0x0086, 0x6003, 0x0001, 0x080c, 0x9335, 0x080c, 0x98e7,
+	0x080c, 0x9a09, 0x00ee, 0x002e, 0x0005, 0x9186, 0x0013, 0x1160,
+	0x6004, 0x908a, 0x0085, 0x0a0c, 0x0dc5, 0x908a, 0x0092, 0x1a0c,
+	0x0dc5, 0x9082, 0x0085, 0x00a2, 0x9186, 0x0027, 0x0130, 0x9186,
+	0x0014, 0x0118, 0x080c, 0xb181, 0x0050, 0x2001, 0x0007, 0x080c,
+	0x6689, 0x080c, 0x97db, 0x080c, 0xb11a, 0x080c, 0x98e7, 0x0005,
+	0xe475, 0xe477, 0xe477, 0xe475, 0xe475, 0xe475, 0xe475, 0xe475,
+	0xe475, 0xe475, 0xe475, 0xe475, 0xe475, 0x080c, 0x0dc5, 0x080c,
+	0x97db, 0x080c, 0xb11a, 0x080c, 0x98e7, 0x0005, 0x9182, 0x0085,
+	0x0a0c, 0x0dc5, 0x9182, 0x0092, 0x1a0c, 0x0dc5, 0x9182, 0x0085,
+	0x0002, 0xe496, 0xe496, 0xe496, 0xe498, 0xe496, 0xe496, 0xe496,
+	0xe496, 0xe496, 0xe496, 0xe496, 0xe496, 0xe496, 0x080c, 0x0dc5,
+	0x0005, 0x9186, 0x0013, 0x0148, 0x9186, 0x0014, 0x0130, 0x9186,
+	0x0027, 0x0118, 0x080c, 0xb181, 0x0030, 0x080c, 0x97db, 0x080c,
+	0xb11a, 0x080c, 0x98e7, 0x0005, 0x0036, 0x080c, 0xeb9d, 0x6043,
+	0x0000, 0x2019, 0x000b, 0x0031, 0x6023, 0x0006, 0x6003, 0x0007,
+	0x003e, 0x0005, 0x0126, 0x0036, 0x2091, 0x8000, 0x0086, 0x2c40,
+	0x0096, 0x904e, 0x080c, 0xa90f, 0x009e, 0x008e, 0x1550, 0x0076,
+	0x2c38, 0x080c, 0xa9ba, 0x007e, 0x1520, 0x6000, 0x9086, 0x0000,
+	0x0500, 0x6020, 0x9086, 0x0007, 0x01e0, 0x0096, 0x601c, 0xd084,
+	0x0140, 0x080c, 0xeb9d, 0x080c, 0xd560, 0x080c, 0x1ab7, 0x6023,
+	0x0007, 0x6014, 0x2048, 0x080c, 0xce3f, 0x0110, 0x080c, 0xe8e3,
+	0x009e, 0x6017, 0x0000, 0x080c, 0xeb9d, 0x6023, 0x0007, 0x080c,
+	0xd560, 0x003e, 0x012e, 0x0005, 0x00f6, 0x00c6, 0x00b6, 0x0036,
+	0x0156, 0x2079, 0x0260, 0x7938, 0x783c, 0x080c, 0x2889, 0x15c8,
+	0x0016, 0x00c6, 0x080c, 0x6717, 0x1590, 0x001e, 0x00c6, 0x2160,
+	0x080c, 0xd55d, 0x00ce, 0x002e, 0x0026, 0x0016, 0x2019, 0x0029,
+	0x080c, 0xaa80, 0x080c, 0x94da, 0x0076, 0x903e, 0x080c, 0x93ad,
+	0x007e, 0x001e, 0x0076, 0x903e, 0x080c, 0xe671, 0x007e, 0x0026,
+	0xba04, 0x9294, 0xff00, 0x8217, 0x9286, 0x0006, 0x0118, 0x9286,
+	0x0004, 0x1118, 0xbaa0, 0x080c, 0x3309, 0x002e, 0xbcc0, 0x001e,
+	0x080c, 0x613b, 0xbe12, 0xbd16, 0xbcc2, 0x9006, 0x0010, 0x00ce,
+	0x001e, 0x015e, 0x003e, 0x00be, 0x00ce, 0x00fe, 0x0005, 0x00c6,
+	0x00d6, 0x00b6, 0x0016, 0x2009, 0x1824, 0x2104, 0x9086, 0x0074,
+	0x1904, 0xe598, 0x2069, 0x0260, 0x6944, 0x9182, 0x0100, 0x06e0,
+	0x6940, 0x9184, 0x8000, 0x0904, 0xe595, 0x2001, 0x197d, 0x2004,
+	0x9005, 0x1140, 0x6010, 0x2058, 0xb8c0, 0x9005, 0x0118, 0x9184,
+	0x0800, 0x0598, 0x6948, 0x918a, 0x0001, 0x0648, 0x080c, 0xed03,
+	0x0118, 0x6978, 0xd1fc, 0x11b8, 0x2009, 0x0205, 0x200b, 0x0001,
+	0x693c, 0x81ff, 0x1198, 0x6944, 0x9182, 0x0100, 0x02a8, 0x6940,
+	0x81ff, 0x1178, 0x6948, 0x918a, 0x0001, 0x0288, 0x6950, 0x918a,
+	0x0001, 0x0298, 0x00d0, 0x6017, 0x0100, 0x00a0, 0x6017, 0x0300,
+	0x0088, 0x6017, 0x0500, 0x0070, 0x6017, 0x0700, 0x0058, 0x6017,
+	0x0900, 0x0040, 0x6017, 0x0b00, 0x0028, 0x6017, 0x0f00, 0x0010,
+	0x6017, 0x2d00, 0x9085, 0x0001, 0x0008, 0x9006, 0x001e, 0x00be,
+	0x00de, 0x00ce, 0x0005, 0x00c6, 0x00b6, 0x0026, 0x0036, 0x0156,
+	0x6210, 0x2258, 0xbb04, 0x9394, 0x00ff, 0x9286, 0x0006, 0x0180,
+	0x9286, 0x0004, 0x0168, 0x9394, 0xff00, 0x8217, 0x9286, 0x0006,
+	0x0138, 0x9286, 0x0004, 0x0120, 0x080c, 0x6726, 0x0804, 0xe600,
+	0x2011, 0x0276, 0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019, 0x000a,
+	0x080c, 0xc0e7, 0x009e, 0x15a8, 0x2011, 0x027a, 0x20a9, 0x0004,
+	0x0096, 0x2b48, 0x2019, 0x0006, 0x080c, 0xc0e7, 0x009e, 0x1548,
+	0x0046, 0x0016, 0xbaa0, 0x2220, 0x9006, 0x2009, 0x1848, 0x210c,
+	0xd1a4, 0x0138, 0x2009, 0x0029, 0x080c, 0xe940, 0xb800, 0xc0e5,
+	0xb802, 0x2019, 0x0029, 0x080c, 0x94da, 0x0076, 0x2039, 0x0000,
+	0x080c, 0x93ad, 0x2c08, 0x080c, 0xe671, 0x007e, 0x2001, 0x0007,
+	0x080c, 0x6689, 0x2001, 0x0007, 0x080c, 0x665d, 0x001e, 0x004e,
+	0x9006, 0x015e, 0x003e, 0x002e, 0x00be, 0x00ce, 0x0005, 0x00d6,
+	0x2069, 0x026e, 0x6800, 0x9086, 0x0800, 0x0118, 0x6017, 0x0000,
+	0x0008, 0x9006, 0x00de, 0x0005, 0x00b6, 0x00f6, 0x0016, 0x0026,
+	0x0036, 0x0156, 0x2079, 0x026c, 0x7930, 0x7834, 0x080c, 0x2889,
+	0x11d0, 0x080c, 0x6717, 0x11b8, 0x2011, 0x0270, 0x20a9, 0x0004,
+	0x0096, 0x2b48, 0x2019, 0x000a, 0x080c, 0xc0e7, 0x009e, 0x1158,
+	0x2011, 0x0274, 0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019, 0x0006,
+	0x080c, 0xc0e7, 0x009e, 0x015e, 0x003e, 0x002e, 0x001e, 0x00fe,
+	0x00be, 0x0005, 0x00b6, 0x0006, 0x0016, 0x0026, 0x0036, 0x0156,
+	0x2011, 0x0263, 0x2204, 0x8211, 0x220c, 0x080c, 0x2889, 0x11d0,
+	0x080c, 0x6717, 0x11b8, 0x2011, 0x0276, 0x20a9, 0x0004, 0x0096,
+	0x2b48, 0x2019, 0x000a, 0x080c, 0xc0e7, 0x009e, 0x1158, 0x2011,
+	0x027a, 0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019, 0x0006, 0x080c,
+	0xc0e7, 0x009e, 0x015e, 0x003e, 0x002e, 0x001e, 0x000e, 0x00be,
+	0x0005, 0x00e6, 0x00c6, 0x0086, 0x0076, 0x0066, 0x0056, 0x0046,
+	0x0026, 0x0126, 0x2091, 0x8000, 0x2740, 0x2029, 0x19f2, 0x252c,
+	0x2021, 0x19f8, 0x2424, 0x2061, 0x1cd0, 0x2071, 0x1800, 0x7654,
+	0x7074, 0x81ff, 0x0150, 0x0006, 0x9186, 0x1ab8, 0x000e, 0x0128,
+	0x8001, 0x9602, 0x1a04, 0xe70f, 0x0018, 0x9606, 0x0904, 0xe70f,
+	0x080c, 0x8bbd, 0x0904, 0xe706, 0x2100, 0x9c06, 0x0904, 0xe706,
+	0x6720, 0x9786, 0x0007, 0x0904, 0xe706, 0x080c, 0xe981, 0x1904,
+	0xe706, 0x080c, 0xed21, 0x0904, 0xe706, 0x080c, 0xe971, 0x0904,
+	0xe706, 0x6720, 0x9786, 0x0001, 0x1148, 0x080c, 0x33a0, 0x0904,
+	0xe74e, 0x6004, 0x9086, 0x0000, 0x1904, 0xe74e, 0x9786, 0x0004,
+	0x0904, 0xe74e, 0x2500, 0x9c06, 0x0904, 0xe706, 0x2400, 0x9c06,
+	0x05e8, 0x88ff, 0x0118, 0x6054, 0x9906, 0x15c0, 0x0096, 0x6000,
+	0x9086, 0x0004, 0x1120, 0x0016, 0x080c, 0x1ab7, 0x001e, 0x9786,
+	0x000a, 0x0148, 0x080c, 0xd047, 0x1130, 0x080c, 0xbacb, 0x009e,
+	0x080c, 0xb11a, 0x0418, 0x6014, 0x2048, 0x080c, 0xce3f, 0x01d8,
+	0x9786, 0x0003, 0x1570, 0xa867, 0x0103, 0xa87c, 0xd0cc, 0x0130,
+	0x0096, 0xa878, 0x2048, 0x080c, 0x0fc0, 0x009e, 0xab7a, 0xa877,
+	0x0000, 0x080c, 0xec9b, 0x0016, 0x080c, 0xd135, 0x080c, 0x6dbe,
+	0x001e, 0x080c, 0xd02a, 0x009e, 0x080c, 0xb11a, 0x9ce0, 0x0018,
+	0x2001, 0x181a, 0x2004, 0x9c02, 0x1210, 0x0804, 0xe685, 0x012e,
+	0x002e, 0x004e, 0x005e, 0x006e, 0x007e, 0x008e, 0x00ce, 0x00ee,
+	0x0005, 0x9786, 0x0006, 0x1150, 0x9386, 0x0005, 0x0128, 0x080c,
+	0xec9b, 0x080c, 0xe8e3, 0x08f8, 0x009e, 0x0c00, 0x9786, 0x0009,
+	0x11f8, 0x6000, 0x9086, 0x0004, 0x01c0, 0x6000, 0x9086, 0x0003,
+	0x11a0, 0x080c, 0x9897, 0x0096, 0x6114, 0x2148, 0x080c, 0xce3f,
+	0x0118, 0x6010, 0x080c, 0x6dcb, 0x009e, 0x00c6, 0x080c, 0xb0e7,
+	0x00ce, 0x0036, 0x080c, 0x9a09, 0x003e, 0x009e, 0x0804, 0xe706,
+	0x9786, 0x000a, 0x0904, 0xe6f6, 0x0804, 0xe6eb, 0x81ff, 0x0904,
+	0xe706, 0x9180, 0x0001, 0x2004, 0x9086, 0x0018, 0x0138, 0x9180,
+	0x0001, 0x2004, 0x9086, 0x002d, 0x1904, 0xe706, 0x6000, 0x9086,
+	0x0002, 0x1904, 0xe706, 0x080c, 0xd036, 0x0138, 0x080c, 0xd047,
+	0x1904, 0xe706, 0x080c, 0xbacb, 0x0038, 0x080c, 0x3274, 0x080c,
+	0xd047, 0x1110, 0x080c, 0xbacb, 0x080c, 0xb11a, 0x0804, 0xe706,
+	0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, 0x0005, 0x00c6, 0x00e6,
+	0x0016, 0x2c08, 0x2170, 0x9006, 0x080c, 0xe90a, 0x001e, 0x0120,
+	0x6020, 0x9084, 0x000f, 0x001b, 0x00ee, 0x00ce, 0x0005, 0xe79d,
+	0xe79d, 0xe79d, 0xe79d, 0xe79d, 0xe79d, 0xe79f, 0xe79d, 0xe79d,
+	0xe79d, 0xe79d, 0xb11a, 0xb11a, 0xe79d, 0x9006, 0x0005, 0x0036,
+	0x0046, 0x0016, 0x7010, 0x00b6, 0x2058, 0xbca0, 0x00be, 0x2c00,
+	0x2009, 0x0020, 0x080c, 0xe940, 0x001e, 0x004e, 0x2019, 0x0002,
+	0x080c, 0xe4ba, 0x003e, 0x9085, 0x0001, 0x0005, 0x0096, 0x080c,
+	0xce3f, 0x0140, 0x6014, 0x904d, 0x080c, 0xca5e, 0x687b, 0x0005,
+	0x080c, 0x6dcb, 0x009e, 0x080c, 0xb11a, 0x9085, 0x0001, 0x0005,
+	0x2001, 0x0001, 0x080c, 0x6649, 0x0156, 0x0016, 0x0026, 0x0036,
+	0x20a9, 0x0004, 0x2019, 0x1805, 0x2011, 0x0276, 0x080c, 0xc0d3,
+	0x003e, 0x002e, 0x001e, 0x015e, 0x9005, 0x0005, 0x00f6, 0x00e6,
+	0x00c6, 0x0086, 0x0076, 0x0066, 0x00b6, 0x0126, 0x2091, 0x8000,
+	0x2740, 0x2061, 0x1cd0, 0x2079, 0x0001, 0x8fff, 0x0904, 0xe83a,
+	0x2071, 0x1800, 0x7654, 0x7074, 0x8001, 0x9602, 0x1a04, 0xe83a,
+	0x88ff, 0x0120, 0x2800, 0x9c06, 0x15a0, 0x2078, 0x080c, 0xe971,
+	0x0580, 0x2400, 0x9c06, 0x0568, 0x6720, 0x9786, 0x0006, 0x1548,
+	0x9786, 0x0007, 0x0530, 0x88ff, 0x1150, 0xd58c, 0x1118, 0x6010,
+	0x9b06, 0x11f8, 0xd584, 0x0118, 0x6054, 0x9106, 0x11d0, 0x0096,
+	0x601c, 0xd084, 0x0140, 0x080c, 0xeb9d, 0x080c, 0xd560, 0x080c,
+	0x1ab7, 0x6023, 0x0007, 0x6014, 0x2048, 0x080c, 0xce3f, 0x0120,
+	0x0046, 0x080c, 0xe8e3, 0x004e, 0x009e, 0x080c, 0xb11a, 0x88ff,
+	0x1198, 0x9ce0, 0x0018, 0x2001, 0x181a, 0x2004, 0x9c02, 0x1210,
+	0x0804, 0xe7ed, 0x9006, 0x012e, 0x00be, 0x006e, 0x007e, 0x008e,
+	0x00ce, 0x00ee, 0x00fe, 0x0005, 0x98c5, 0x0001, 0x0ca0, 0x00b6,
+	0x0076, 0x0056, 0x0086, 0x9046, 0x2029, 0x0001, 0x2c20, 0x2019,
+	0x0002, 0x6210, 0x2258, 0x0096, 0x904e, 0x080c, 0xa90f, 0x009e,
+	0x008e, 0x903e, 0x080c, 0xa9ba, 0x080c, 0xe7de, 0x005e, 0x007e,
+	0x00be, 0x0005, 0x00b6, 0x0046, 0x0056, 0x0076, 0x00c6, 0x0156,
+	0x2c20, 0x2128, 0x20a9, 0x007f, 0x900e, 0x0016, 0x0036, 0x080c,
+	0x6717, 0x1180, 0x0056, 0x0086, 0x9046, 0x2508, 0x2029, 0x0001,
+	0x0096, 0x904e, 0x080c, 0xa90f, 0x009e, 0x008e, 0x903e, 0x080c,
+	0xa9ba, 0x005e, 0x003e, 0x001e, 0x8108, 0x1f04, 0xe86d, 0x0036,
+	0x2508, 0x2029, 0x0003, 0x080c, 0xe7de, 0x003e, 0x015e, 0x00ce,
+	0x007e, 0x005e, 0x004e, 0x00be, 0x0005, 0x00b6, 0x0076, 0x0056,
+	0x6210, 0x2258, 0x0086, 0x9046, 0x2029, 0x0001, 0x2019, 0x0048,
+	0x0096, 0x904e, 0x080c, 0xa90f, 0x009e, 0x008e, 0x903e, 0x080c,
+	0xa9ba, 0x2c20, 0x080c, 0xe7de, 0x005e, 0x007e, 0x00be, 0x0005,
+	0x00b6, 0x0046, 0x0056, 0x0076, 0x00c6, 0x0156, 0x2c20, 0x20a9,
+	0x0800, 0x900e, 0x0016, 0x0036, 0x080c, 0x6717, 0x1190, 0x0086,
+	0x9046, 0x2828, 0x0046, 0x2021, 0x0001, 0x080c, 0xeb81, 0x004e,
+	0x0096, 0x904e, 0x080c, 0xa90f, 0x009e, 0x008e, 0x903e, 0x080c,
+	0xa9ba, 0x003e, 0x001e, 0x8108, 0x1f04, 0xe8ba, 0x0036, 0x2029,
+	0x0002, 0x080c, 0xe7de, 0x003e, 0x015e, 0x00ce, 0x007e, 0x005e,
+	0x004e, 0x00be, 0x0005, 0x0016, 0x00f6, 0x080c, 0xce3d, 0x0198,
+	0xa864, 0x9084, 0x00ff, 0x9086, 0x0046, 0x0180, 0xa800, 0x907d,
+	0x0138, 0xa803, 0x0000, 0xab82, 0x080c, 0x6dcb, 0x2f48, 0x0cb0,
+	0xab82, 0x080c, 0x6dcb, 0x00fe, 0x001e, 0x0005, 0xa800, 0x907d,
+	0x0130, 0xa803, 0x0000, 0x080c, 0x6dcb, 0x2f48, 0x0cb8, 0x080c,
+	0x6dcb, 0x0c88, 0x00e6, 0x0046, 0x0036, 0x2061, 0x1cd0, 0x9005,
+	0x1138, 0x2071, 0x1800, 0x7454, 0x7074, 0x8001, 0x9402, 0x12f8,
+	0x2100, 0x9c06, 0x0188, 0x6000, 0x9086, 0x0000, 0x0168, 0x6008,
+	0x9206, 0x1150, 0x6320, 0x9386, 0x0009, 0x01b0, 0x6010, 0x91a0,
+	0x0004, 0x2424, 0x9406, 0x0140, 0x9ce0, 0x0018, 0x2001, 0x181a,
+	0x2004, 0x9c02, 0x1220, 0x0c20, 0x9085, 0x0001, 0x0008, 0x9006,
+	0x003e, 0x004e, 0x00ee, 0x0005, 0x631c, 0xd3c4, 0x1d68, 0x0c30,
+	0x0096, 0x0006, 0x080c, 0x100e, 0x000e, 0x090c, 0x0dc5, 0xaae2,
+	0xa867, 0x010d, 0xa88e, 0x0026, 0x2010, 0x080c, 0xce2d, 0x2001,
+	0x0000, 0x0120, 0x2200, 0x9080, 0x0015, 0x2004, 0x002e, 0xa87a,
+	0x9186, 0x0020, 0x0110, 0xa8e3, 0xffff, 0xa986, 0xac76, 0xa87f,
+	0x0000, 0x2001, 0x198f, 0x2004, 0xa882, 0x9006, 0xa802, 0xa86a,
+	0xa88a, 0x0126, 0x2091, 0x8000, 0x080c, 0x6dcb, 0x012e, 0x009e,
+	0x0005, 0x6700, 0x9786, 0x0000, 0x0158, 0x9786, 0x0001, 0x0140,
+	0x9786, 0x000a, 0x0128, 0x9786, 0x0009, 0x0110, 0x9085, 0x0001,
+	0x0005, 0x00e6, 0x6010, 0x9075, 0x0138, 0x00b6, 0x2058, 0xb8a0,
+	0x00be, 0x9206, 0x00ee, 0x0005, 0x9085, 0x0001, 0x0cd8, 0x0016,
+	0x6004, 0x908e, 0x001e, 0x11a0, 0x8007, 0x6134, 0x918c, 0x00ff,
+	0x9105, 0x6036, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0005,
+	0x2001, 0x1988, 0x2004, 0x601a, 0x080c, 0x9335, 0x080c, 0x98e7,
+	0x001e, 0x0005, 0xa001, 0xa001, 0x0005, 0x6024, 0xd0e4, 0x0158,
+	0xd0cc, 0x0118, 0x080c, 0xd179, 0x0030, 0x080c, 0xeb9d, 0x080c,
+	0x88eb, 0x080c, 0xb0e7, 0x0005, 0x9280, 0x0008, 0x2004, 0x9084,
+	0x000f, 0x0002, 0xe9d0, 0xe9d0, 0xe9d0, 0xe9d2, 0xe9d0, 0xe9d2,
+	0xe9d2, 0xe9d0, 0xe9d2, 0xe9d0, 0xe9d0, 0xe9d0, 0xe9d0, 0xe9d0,
+	0x9006, 0x0005, 0x9085, 0x0001, 0x0005, 0x9280, 0x0008, 0x2004,
+	0x9084, 0x000f, 0x0002, 0xe9e9, 0xe9e9, 0xe9e9, 0xe9e9, 0xe9e9,
+	0xe9e9, 0xe9f6, 0xe9e9, 0xe9e9, 0xe9e9, 0xe9e9, 0xe9e9, 0xe9e9,
+	0xe9e9, 0x6007, 0x003b, 0x602f, 0x0009, 0x6017, 0x2a00, 0x6003,
+	0x0001, 0x080c, 0x9335, 0x080c, 0x98e7, 0x0005, 0x0096, 0x00c6,
+	0x2260, 0x080c, 0xeb9d, 0x6043, 0x0000, 0x6024, 0xc0f4, 0xc0e4,
+	0x6026, 0x603b, 0x0000, 0x00ce, 0x00d6, 0x2268, 0x9186, 0x0007,
+	0x1904, 0xea4f, 0x6814, 0x9005, 0x0138, 0x2048, 0xa87c, 0xd0fc,
+	0x1118, 0x00de, 0x009e, 0x08a8, 0x6007, 0x003a, 0x6003, 0x0001,
+	0x080c, 0x9335, 0x080c, 0x98e7, 0x00c6, 0x2d60, 0x6100, 0x9186,
+	0x0002, 0x1904, 0xeac6, 0x6014, 0x9005, 0x1138, 0x6000, 0x9086,
+	0x0007, 0x190c, 0x0dc5, 0x0804, 0xeac6, 0x2048, 0x080c, 0xce3f,
+	0x1130, 0x0028, 0x2048, 0xa800, 0x9005, 0x1de0, 0x2900, 0x2048,
+	0xa87c, 0x9084, 0x0003, 0x9086, 0x0002, 0x1168, 0xa87c, 0xc0dc,
+	0xc0f4, 0xa87e, 0xa880, 0xc0fc, 0xa882, 0x2009, 0x0043, 0x080c,
+	0xe30e, 0x0804, 0xeac6, 0x2009, 0x0041, 0x0804, 0xeac0, 0x9186,
+	0x0005, 0x15a0, 0x6814, 0x2048, 0xa87c, 0xd0bc, 0x1120, 0x00de,
+	0x009e, 0x0804, 0xe9e9, 0xd0b4, 0x0128, 0xd0fc, 0x090c, 0x0dc5,
+	0x0804, 0xea0a, 0x6007, 0x003a, 0x6003, 0x0001, 0x080c, 0x9335,
+	0x080c, 0x98e7, 0x00c6, 0x2d60, 0x6100, 0x9186, 0x0002, 0x0120,
+	0x9186, 0x0004, 0x1904, 0xeac6, 0x6814, 0x2048, 0xa97c, 0xc1f4,
+	0xc1dc, 0xa97e, 0xa980, 0xc1fc, 0xc1bc, 0xa982, 0x00f6, 0x2c78,
+	0x080c, 0x1768, 0x00fe, 0x2009, 0x0042, 0x04d0, 0x0036, 0x080c,
+	0x100e, 0x090c, 0x0dc5, 0xa867, 0x010d, 0x9006, 0xa802, 0xa86a,
+	0xa88a, 0x2d18, 0xab8e, 0xa887, 0x0045, 0x2c00, 0xa892, 0x6038,
+	0xa8a2, 0x2360, 0x6024, 0xc0dd, 0x6026, 0x6010, 0x00b6, 0x2058,
+	0xb8a0, 0x00be, 0x2004, 0x6354, 0xab7a, 0xa876, 0x9006, 0xa87e,
+	0xa882, 0xad9a, 0xae96, 0xa89f, 0x0001, 0x080c, 0x6dcb, 0x2019,
+	0x0045, 0x6008, 0x2068, 0x080c, 0xe4ba, 0x2d00, 0x600a, 0x6023,
+	0x0006, 0x6003, 0x0007, 0x901e, 0x631a, 0x6342, 0x003e, 0x0038,
+	0x6043, 0x0000, 0x6003, 0x0007, 0x080c, 0xe30e, 0x00ce, 0x00de,
+	0x009e, 0x0005, 0x9186, 0x0013, 0x1128, 0x6004, 0x9082, 0x0085,
+	0x2008, 0x00c2, 0x9186, 0x0027, 0x1178, 0x080c, 0x97db, 0x0036,
+	0x0096, 0x6014, 0x2048, 0x2019, 0x0004, 0x080c, 0xe8e3, 0x009e,
+	0x003e, 0x080c, 0x98e7, 0x0005, 0x9186, 0x0014, 0x0d70, 0x080c,
+	0xb181, 0x0005, 0xeaf9, 0xeaf7, 0xeaf7, 0xeaf7, 0xeaf7, 0xeaf7,
+	0xeaf9, 0xeaf7, 0xeaf7, 0xeaf7, 0xeaf7, 0xeaf7, 0xeaf7, 0x080c,
+	0x0dc5, 0x080c, 0x97db, 0x6003, 0x000c, 0x080c, 0x98e7, 0x0005,
+	0x9182, 0x0092, 0x1220, 0x9182, 0x0085, 0x0208, 0x001a, 0x080c,
+	0xb181, 0x0005, 0xeb17, 0xeb17, 0xeb17, 0xeb17, 0xeb19, 0xeb39,
+	0xeb17, 0xeb17, 0xeb17, 0xeb17, 0xeb17, 0xeb17, 0xeb17, 0x080c,
+	0x0dc5, 0x00d6, 0x2c68, 0x080c, 0xb091, 0x01b0, 0x6003, 0x0001,
+	0x6007, 0x001e, 0x2009, 0x026e, 0x210c, 0x613a, 0x2009, 0x026f,
+	0x210c, 0x613e, 0x600b, 0xffff, 0x6910, 0x6112, 0x6023, 0x0004,
+	0x080c, 0x9335, 0x080c, 0x98e7, 0x2d60, 0x080c, 0xb0e7, 0x00de,
+	0x0005, 0x080c, 0xb0e7, 0x0005, 0x00e6, 0x6010, 0x00b6, 0x2058,
+	0xb800, 0x00be, 0xd0ec, 0x00ee, 0x0005, 0x2009, 0x1867, 0x210c,
+	0xd1ec, 0x05b0, 0x6003, 0x0002, 0x6024, 0xc0e5, 0x6026, 0xd0cc,
+	0x0150, 0x2001, 0x1989, 0x2004, 0x6042, 0x2009, 0x1867, 0x210c,
+	0xd1f4, 0x1520, 0x00a0, 0x2009, 0x1867, 0x210c, 0xd1f4, 0x0128,
+	0x6024, 0xc0e4, 0x6026, 0x9006, 0x00d8, 0x2001, 0x1989, 0x200c,
+	0x2001, 0x1987, 0x2004, 0x9100, 0x9080, 0x000a, 0x6042, 0x6010,
+	0x00b6, 0x2058, 0xb8bc, 0x00be, 0x0008, 0x2104, 0x9005, 0x0118,
+	0x9088, 0x0003, 0x0cd0, 0x2c0a, 0x600f, 0x0000, 0x9085, 0x0001,
+	0x0005, 0x0016, 0x00c6, 0x00e6, 0x6154, 0xb8bc, 0x2060, 0x8cff,
+	0x0180, 0x84ff, 0x1118, 0x6054, 0x9106, 0x1138, 0x600c, 0x2072,
+	0x080c, 0x88eb, 0x080c, 0xb0e7, 0x0010, 0x9cf0, 0x0003, 0x2e64,
+	0x0c70, 0x00ee, 0x00ce, 0x001e, 0x0005, 0x00d6, 0x00b6, 0x6010,
+	0x2058, 0xb8bc, 0x906d, 0x0130, 0x9c06, 0x0110, 0x680c, 0x0cd0,
+	0x600c, 0x680e, 0x00be, 0x00de, 0x0005, 0x0026, 0x0036, 0x0156,
+	0x2011, 0x182c, 0x2204, 0x9084, 0x00ff, 0x2019, 0x026e, 0x2334,
+	0x96b4, 0x00ff, 0x9636, 0x1508, 0x8318, 0x2334, 0x2204, 0x9084,
+	0xff00, 0x9636, 0x11d0, 0x2011, 0x0270, 0x20a9, 0x0004, 0x6010,
+	0x0096, 0x2048, 0x2019, 0x000a, 0x080c, 0xc0e7, 0x009e, 0x1168,
+	0x2011, 0x0274, 0x20a9, 0x0004, 0x6010, 0x0096, 0x2048, 0x2019,
+	0x0006, 0x080c, 0xc0e7, 0x009e, 0x1100, 0x015e, 0x003e, 0x002e,
+	0x0005, 0x00e6, 0x2071, 0x1800, 0x080c, 0x60b4, 0x080c, 0x3022,
+	0x00ee, 0x0005, 0x0096, 0x0026, 0x080c, 0x100e, 0x090c, 0x0dc5,
+	0xa85c, 0x9080, 0x001a, 0x20a0, 0x20a9, 0x000c, 0xa860, 0x20e8,
+	0x9006, 0x4004, 0x9186, 0x0046, 0x1118, 0xa867, 0x0136, 0x0038,
+	0xa867, 0x0138, 0x9186, 0x0041, 0x0110, 0xa87b, 0x0001, 0x7038,
+	0x9084, 0xff00, 0x7240, 0x9294, 0xff00, 0x8007, 0x9215, 0xaa9a,
+	0x9186, 0x0046, 0x1168, 0x7038, 0x9084, 0x00ff, 0x723c, 0x9294,
+	0xff00, 0x9215, 0xaa9e, 0x723c, 0x9294, 0x00ff, 0xaaa2, 0x0060,
+	0x7040, 0x9084, 0x00ff, 0x7244, 0x9294, 0xff00, 0x9215, 0xaa9e,
+	0x7244, 0x9294, 0x00ff, 0xaaa2, 0x9186, 0x0046, 0x1118, 0x9e90,
+	0x0012, 0x0010, 0x9e90, 0x001a, 0x2204, 0x8007, 0xa8a6, 0x8210,
+	0x2204, 0x8007, 0xa8aa, 0x8210, 0x2204, 0x8007, 0xa8ae, 0x8210,
+	0x2204, 0x8007, 0xa8b2, 0x8210, 0x9186, 0x0046, 0x11b8, 0x9e90,
+	0x0016, 0x2204, 0x8007, 0xa8b6, 0x8210, 0x2204, 0x8007, 0xa8ba,
+	0x8210, 0x2204, 0x8007, 0xa8be, 0x8210, 0x2204, 0x8007, 0xa8c2,
+	0x8210, 0x2011, 0x0205, 0x2013, 0x0001, 0x00b0, 0x9e90, 0x001e,
+	0x2204, 0x8007, 0xa8b6, 0x8210, 0x2204, 0x8007, 0xa8ba, 0x2011,
+	0x0205, 0x2013, 0x0001, 0x2011, 0x0260, 0x2204, 0x8007, 0xa8be,
+	0x8210, 0x2204, 0x8007, 0xa8c2, 0x9186, 0x0046, 0x1118, 0x2011,
+	0x0262, 0x0010, 0x2011, 0x026a, 0x0146, 0x01d6, 0x0036, 0x20a9,
+	0x0001, 0x2019, 0x0008, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0031,
+	0x20a0, 0x2204, 0x8007, 0x4004, 0x8210, 0x8319, 0x1dd0, 0x003e,
+	0x01ce, 0x013e, 0x2011, 0x0205, 0x2013, 0x0000, 0x002e, 0x080c,
+	0x6dcb, 0x009e, 0x0005, 0x00e6, 0x6010, 0x00b6, 0x2058, 0xb800,
+	0x00be, 0xd0fc, 0x0108, 0x0011, 0x00ee, 0x0005, 0xa880, 0xc0e5,
+	0xa882, 0x0005, 0x00e6, 0x00d6, 0x00c6, 0x0076, 0x0066, 0x0056,
+	0x0046, 0x0026, 0x0016, 0x0126, 0x2091, 0x8000, 0x2029, 0x19f2,
+	0x252c, 0x2021, 0x19f8, 0x2424, 0x2061, 0x1cd0, 0x2071, 0x1800,
+	0x7654, 0x7074, 0x9606, 0x0578, 0x6720, 0x9786, 0x0001, 0x0118,
+	0x9786, 0x0008, 0x1500, 0x2500, 0x9c06, 0x01e8, 0x2400, 0x9c06,
+	0x01d0, 0x080c, 0xe971, 0x01b8, 0x080c, 0xe981, 0x11a0, 0x6000,
+	0x9086, 0x0004, 0x1120, 0x0016, 0x080c, 0x1ab7, 0x001e, 0x080c,
+	0xd036, 0x1110, 0x080c, 0x3274, 0x080c, 0xd047, 0x1110, 0x080c,
+	0xbacb, 0x080c, 0xb11a, 0x9ce0, 0x0018, 0x2001, 0x181a, 0x2004,
+	0x9c02, 0x1208, 0x0858, 0x012e, 0x001e, 0x002e, 0x004e, 0x005e,
+	0x006e, 0x007e, 0x00ce, 0x00de, 0x00ee, 0x0005, 0x2001, 0x1810,
+	0x2004, 0xd0dc, 0x0005, 0x0006, 0x2001, 0x1837, 0x2004, 0xd09c,
+	0x000e, 0x0005, 0x0006, 0x0036, 0x0046, 0x080c, 0xd548, 0x0168,
+	0x2019, 0xffff, 0x9005, 0x0128, 0x6010, 0x00b6, 0x2058, 0xbba0,
+	0x00be, 0x2021, 0x0004, 0x080c, 0x4d9a, 0x004e, 0x003e, 0x000e,
+	0x0005, 0x6004, 0x9086, 0x0001, 0x1128, 0x080c, 0xaa80, 0x080c,
+	0xb11a, 0x9006, 0x0005, 0x00e6, 0x00c6, 0x00b6, 0x0046, 0x2061,
 	0x1cd0, 0x2071, 0x1800, 0x7454, 0x7074, 0x8001, 0x9402, 0x12d8,
 	0x2100, 0x9c06, 0x0168, 0x6000, 0x9086, 0x0000, 0x0148, 0x6010,
 	0x2058, 0xb8a0, 0x9206, 0x1120, 0x6004, 0x9086, 0x0002, 0x0140,
 	0x9ce0, 0x0018, 0x2001, 0x181a, 0x2004, 0x9c02, 0x1220, 0x0c40,
 	0x9085, 0x0001, 0x0008, 0x9006, 0x004e, 0x00be, 0x00ce, 0x00ee,
-	0x0005, 0x0126, 0x0006, 0x00e6, 0x0016, 0x2091, 0x8000, 0x2071,
-	0x1840, 0xd5a4, 0x0118, 0x7004, 0x8000, 0x7006, 0xd5b4, 0x0118,
-	0x7000, 0x8000, 0x7002, 0xd5ac, 0x0178, 0x2500, 0x9084, 0x0007,
-	0x908e, 0x0003, 0x0148, 0x908e, 0x0004, 0x0130, 0x908e, 0x0005,
-	0x0118, 0x2071, 0xfff6, 0x0089, 0x001e, 0x00ee, 0x000e, 0x012e,
-	0x0005, 0x0126, 0x0006, 0x00e6, 0x2091, 0x8000, 0x2071, 0xffee,
-	0x0021, 0x00ee, 0x000e, 0x012e, 0x0005, 0x2e05, 0x8000, 0x2077,
-	0x1220, 0x8e70, 0x2e05, 0x8000, 0x2077, 0x0005, 0x00e6, 0x2071,
-	0xffec, 0x0c99, 0x00ee, 0x0005, 0x00e6, 0x2071, 0xfff0, 0x0c69,
-	0x00ee, 0x0005, 0x0126, 0x0006, 0x00e6, 0x2091, 0x8000, 0x2071,
-	0x1840, 0x7014, 0x8000, 0x7016, 0x00ee, 0x000e, 0x012e, 0x0005,
-	0x0003, 0x000b, 0x079e, 0x0000, 0xc000, 0x0001, 0x8064, 0x0008,
-	0x0010, 0x0000, 0x8066, 0x0000, 0x0101, 0x0008, 0x4407, 0x0003,
-	0x8060, 0x0000, 0x0400, 0x0000, 0x580d, 0x000b, 0x79a8, 0x000b,
-	0x50ee, 0x000b, 0x4c0a, 0x0003, 0xbac0, 0x0009, 0x008a, 0x0000,
-	0x0c0a, 0x000b, 0x15fe, 0x0008, 0x340a, 0x0003, 0xc4c0, 0x0009,
-	0x7000, 0x0000, 0xffa0, 0x0001, 0x2000, 0x0000, 0x1668, 0x000b,
-	0x808c, 0x0008, 0x0001, 0x0000, 0x0000, 0x0007, 0x4028, 0x0000,
-	0x4047, 0x000a, 0x808c, 0x0008, 0x0002, 0x0000, 0x0822, 0x0003,
-	0x4022, 0x0000, 0x0028, 0x000b, 0x4122, 0x0008, 0x94c0, 0x0009,
-	0xff00, 0x0008, 0xffe0, 0x0009, 0x0500, 0x0008, 0x0a93, 0x000b,
-	0x4447, 0x0002, 0x0e90, 0x0003, 0x0bfe, 0x0008, 0x11a0, 0x0001,
-	0x126e, 0x0003, 0x0ca0, 0x0001, 0x126e, 0x0003, 0x9180, 0x0001,
-	0x0004, 0x0000, 0x8060, 0x0000, 0x0400, 0x0000, 0x7f62, 0x0008,
-	0x8066, 0x0000, 0x0009, 0x0008, 0x4436, 0x000b, 0x808c, 0x0008,
-	0x0000, 0x0008, 0x0060, 0x0008, 0x8062, 0x0008, 0x0004, 0x0000,
-	0x8066, 0x0000, 0x0411, 0x0000, 0x443e, 0x0003, 0x03fe, 0x0000,
-	0x43e0, 0x0001, 0x0e6b, 0x000b, 0xc2c0, 0x0009, 0x00ff, 0x0008,
-	0x02e0, 0x0001, 0x0e6b, 0x000b, 0x9180, 0x0001, 0x0005, 0x0008,
-	0x8060, 0x0000, 0x0400, 0x0000, 0x7f62, 0x0008, 0x8066, 0x0000,
-	0x0019, 0x0000, 0x444d, 0x000b, 0x0240, 0x0002, 0x0a68, 0x0003,
-	0x00fe, 0x0000, 0x326b, 0x000b, 0x0248, 0x000a, 0x085c, 0x0003,
-	0x9180, 0x0001, 0x0006, 0x0008, 0x7f62, 0x0008, 0x8002, 0x0008,
-	0x0003, 0x0008, 0x8066, 0x0000, 0x020a, 0x0000, 0x445b, 0x0003,
-	0x112a, 0x0000, 0x002e, 0x0008, 0x022c, 0x0008, 0x3a44, 0x0002,
-	0x0c0a, 0x000b, 0x808c, 0x0008, 0x0002, 0x0000, 0x1760, 0x0008,
-	0x8062, 0x0008, 0x000f, 0x0008, 0x8066, 0x0000, 0x0011, 0x0008,
-	0x4468, 0x0003, 0x01fe, 0x0008, 0x42e0, 0x0009, 0x0e5c, 0x0003,
-	0x00fe, 0x0000, 0x43e0, 0x0001, 0x0e5c, 0x0003, 0x1734, 0x0000,
-	0x1530, 0x0000, 0x1632, 0x0008, 0x0d2a, 0x0008, 0x9880, 0x0001,
-	0x0010, 0x0000, 0x8060, 0x0000, 0x0400, 0x0000, 0x7f62, 0x0008,
-	0x8066, 0x0000, 0x1e0a, 0x0008, 0x447a, 0x0003, 0x808a, 0x0008,
-	0x0003, 0x0008, 0x1a60, 0x0000, 0x8062, 0x0008, 0x0002, 0x0000,
-	0x5880, 0x000b, 0x8066, 0x0000, 0x3679, 0x0000, 0x4483, 0x0003,
-	0x5884, 0x0003, 0x3efe, 0x0008, 0x7f4f, 0x0002, 0x088a, 0x000b,
-	0x0d00, 0x0000, 0x0092, 0x000c, 0x8054, 0x0008, 0x0011, 0x0008,
-	0x8074, 0x0000, 0x1010, 0x0008, 0x1efe, 0x0000, 0x300a, 0x000b,
-	0x00c8, 0x000c, 0x000a, 0x000b, 0x00fe, 0x0000, 0x349a, 0x0003,
-	0x1a60, 0x0000, 0x8062, 0x0008, 0x0007, 0x0000, 0x8066, 0x0000,
-	0x0231, 0x0008, 0x4499, 0x000b, 0x03fe, 0x0000, 0x04d0, 0x0001,
-	0x0cc0, 0x000b, 0x82c0, 0x0001, 0x1f00, 0x0000, 0xffa0, 0x0001,
-	0x0400, 0x0000, 0x08af, 0x0003, 0x14c0, 0x000b, 0x01fe, 0x0008,
-	0x0580, 0x0009, 0x7f06, 0x0000, 0x02fe, 0x0008, 0xffc0, 0x0001,
-	0x00ff, 0x0008, 0x0690, 0x0001, 0x10af, 0x0003, 0x7f08, 0x0008,
-	0x84c0, 0x0001, 0xff00, 0x0008, 0x08c0, 0x0003, 0x00fe, 0x0000,
-	0x34b6, 0x000b, 0x8072, 0x0000, 0x1010, 0x0008, 0x3944, 0x0002,
-	0x08b1, 0x0003, 0x00ba, 0x0003, 0x8072, 0x0000, 0x2020, 0x0008,
-	0x3945, 0x000a, 0x08b6, 0x000b, 0x3946, 0x000a, 0x0cc7, 0x0003,
-	0x0000, 0x0007, 0x3943, 0x000a, 0x08c7, 0x000b, 0x00ba, 0x0003,
-	0x00fe, 0x0000, 0x34c5, 0x0003, 0x8072, 0x0000, 0x1000, 0x0000,
-	0x00c7, 0x0003, 0x8072, 0x0000, 0x2000, 0x0000, 0x4000, 0x000f,
-	0x1c60, 0x0000, 0x1b62, 0x0000, 0x8066, 0x0000, 0x0231, 0x0008,
-	0x44cc, 0x000b, 0x58cd, 0x000b, 0x0140, 0x0008, 0x0242, 0x0000,
-	0x1f43, 0x0002, 0x0cdb, 0x000b, 0x0d44, 0x0000, 0x0d46, 0x0008,
-	0x0348, 0x0008, 0x044a, 0x0008, 0x030a, 0x0008, 0x040c, 0x0000,
-	0x0d06, 0x0000, 0x0d08, 0x0008, 0x00df, 0x0003, 0x0344, 0x0008,
-	0x0446, 0x0008, 0x0548, 0x0008, 0x064a, 0x0000, 0x1948, 0x000a,
-	0x08e2, 0x0003, 0x0d4a, 0x0008, 0x58e2, 0x0003, 0x3efe, 0x0008,
-	0x7f4f, 0x0002, 0x08e9, 0x000b, 0x8000, 0x0000, 0x0001, 0x0000,
-	0x0092, 0x000c, 0x8054, 0x0008, 0x0001, 0x0000, 0x8074, 0x0000,
-	0x2020, 0x0008, 0x4000, 0x000f, 0x3a40, 0x000a, 0x0c0d, 0x0003,
-	0x2b24, 0x0008, 0x2b24, 0x0008, 0x58f2, 0x000b, 0x8054, 0x0008,
-	0x0002, 0x0000, 0x1242, 0x0002, 0x0940, 0x0003, 0x3a45, 0x000a,
-	0x092f, 0x0003, 0x8072, 0x0000, 0x1000, 0x0000, 0x3945, 0x000a,
-	0x08ff, 0x0003, 0x8072, 0x0000, 0x3010, 0x0000, 0x1e10, 0x000a,
-	0x7f3c, 0x0000, 0x092a, 0x0003, 0x1d00, 0x0002, 0x7f3a, 0x0000,
-	0x0d60, 0x0000, 0x7f62, 0x0008, 0x8066, 0x0000, 0x0009, 0x0008,
-	0x4508, 0x000b, 0x00fe, 0x0000, 0x3527, 0x000b, 0x1c60, 0x0000,
-	0x8062, 0x0008, 0x0001, 0x0000, 0x8066, 0x0000, 0x0009, 0x0008,
-	0x4510, 0x000b, 0x00fe, 0x0000, 0x3243, 0x000b, 0x0038, 0x0000,
-	0x0060, 0x0008, 0x8062, 0x0008, 0x0019, 0x0000, 0x8066, 0x0000,
-	0x0009, 0x0008, 0x4519, 0x000b, 0x80c0, 0x0009, 0x00ff, 0x0008,
-	0x7f3e, 0x0008, 0x0d60, 0x0000, 0x0efe, 0x0008, 0x1f80, 0x0001,
-	0x7f62, 0x0008, 0x8066, 0x0000, 0x0009, 0x0008, 0x4523, 0x000b,
-	0x003a, 0x0008, 0x1dfe, 0x0000, 0x0104, 0x000b, 0x0036, 0x0008,
-	0x00c8, 0x000c, 0x0140, 0x000b, 0x8074, 0x0000, 0x2000, 0x0000,
-	0x8072, 0x0000, 0x2000, 0x0000, 0x0140, 0x000b, 0x3a44, 0x0002,
-	0x0a71, 0x000b, 0x8074, 0x0000, 0x1000, 0x0000, 0x8072, 0x0000,
-	0x1000, 0x0000, 0x2d0e, 0x0000, 0x2d0e, 0x0000, 0x3640, 0x0003,
-	0x26fe, 0x0008, 0x26fe, 0x0008, 0x2700, 0x0008, 0x2700, 0x0008,
-	0x00d0, 0x0009, 0x0d52, 0x000b, 0x8074, 0x0000, 0x4040, 0x0008,
-	0x5940, 0x0003, 0x50ee, 0x000b, 0x3a46, 0x000a, 0x0d52, 0x000b,
-	0x3a47, 0x0002, 0x094d, 0x000b, 0x8054, 0x0008, 0x0004, 0x0000,
-	0x8074, 0x0000, 0x8000, 0x0000, 0x8072, 0x0000, 0x3000, 0x0008,
-	0x019c, 0x0003, 0x92c0, 0x0009, 0x0fc8, 0x0000, 0x080a, 0x0003,
-	0x1246, 0x000a, 0x0e3a, 0x0003, 0x1a60, 0x0000, 0x8062, 0x0008,
-	0x0002, 0x0000, 0x8066, 0x0000, 0x362a, 0x0000, 0x4557, 0x000b,
-	0x2000, 0x0000, 0x2000, 0x0000, 0x2102, 0x0000, 0x2102, 0x0000,
-	0x2204, 0x0000, 0x2204, 0x0000, 0x2306, 0x0000, 0x2306, 0x0000,
-	0x2408, 0x0000, 0x2408, 0x0000, 0x250a, 0x0000, 0x250a, 0x0000,
-	0x260c, 0x0000, 0x260c, 0x0000, 0x270e, 0x0000, 0x270e, 0x0000,
-	0x2810, 0x0000, 0x2810, 0x0000, 0x2912, 0x0000, 0x2912, 0x0000,
-	0x1a60, 0x0000, 0x8062, 0x0008, 0x0007, 0x0000, 0x8066, 0x0000,
-	0x0052, 0x0000, 0x4571, 0x0003, 0x92c0, 0x0009, 0x0780, 0x0008,
-	0x0e56, 0x0003, 0x124b, 0x0002, 0x097a, 0x0003, 0x2e4d, 0x0002,
-	0x2e4d, 0x0002, 0x0a40, 0x0003, 0x3a46, 0x000a, 0x0d8a, 0x000b,
-	0x597c, 0x0003, 0x8054, 0x0008, 0x0004, 0x0000, 0x1243, 0x000a,
-	0x0998, 0x0003, 0x8010, 0x0008, 0x000d, 0x0000, 0x021b, 0x000c,
-	0x1948, 0x000a, 0x0987, 0x000b, 0x0210, 0x0004, 0x1810, 0x0000,
-	0x021b, 0x000c, 0x0198, 0x000b, 0x1948, 0x000a, 0x098e, 0x000b,
-	0x1243, 0x000a, 0x0a43, 0x0003, 0x194d, 0x000a, 0x0992, 0x0003,
-	0x1243, 0x000a, 0x0a4a, 0x0003, 0x5992, 0x0003, 0x8054, 0x0008,
-	0x0004, 0x0000, 0x0210, 0x0004, 0x1810, 0x0000, 0x021b, 0x000c,
-	0x8074, 0x0000, 0xf000, 0x0008, 0x8072, 0x0000, 0x3000, 0x0008,
-	0x0d30, 0x0000, 0x3a42, 0x0002, 0x0da2, 0x000b, 0x15fe, 0x0008,
-	0x3461, 0x000b, 0x000a, 0x000b, 0x8074, 0x0000, 0x0501, 0x0000,
-	0x8010, 0x0008, 0x000c, 0x0008, 0x021b, 0x000c, 0x000a, 0x000b,
-	0xbbe0, 0x0009, 0x0030, 0x0008, 0x0db8, 0x0003, 0x18fe, 0x0000,
-	0x3ce0, 0x0009, 0x09b5, 0x0003, 0x15fe, 0x0008, 0x3ce0, 0x0009,
-	0x09b5, 0x0003, 0x020b, 0x0004, 0x8076, 0x0008, 0x0040, 0x0000,
-	0x0208, 0x000b, 0x8076, 0x0008, 0x0041, 0x0008, 0x0208, 0x000b,
-	0xbbe0, 0x0009, 0x0032, 0x0000, 0x0dbd, 0x0003, 0x3c1e, 0x0008,
-	0x0208, 0x000b, 0xbbe0, 0x0009, 0x003b, 0x0000, 0x0dc2, 0x000b,
-	0x3c20, 0x0000, 0x0208, 0x000b, 0xbbe0, 0x0009, 0x0035, 0x0008,
-	0x0dc8, 0x000b, 0x8072, 0x0000, 0x8000, 0x0000, 0x0384, 0x000b,
-	0xbbe0, 0x0009, 0x0036, 0x0008, 0x0aa5, 0x000b, 0xbbe0, 0x0009,
-	0x0037, 0x0000, 0x0de9, 0x000b, 0x18fe, 0x0000, 0x3ce0, 0x0009,
-	0x0db5, 0x000b, 0x8076, 0x0008, 0x0040, 0x0000, 0x1a60, 0x0000,
-	0x8062, 0x0008, 0x000d, 0x0000, 0x2604, 0x0008, 0x2604, 0x0008,
-	0x2706, 0x0008, 0x2706, 0x0008, 0x2808, 0x0000, 0x2808, 0x0000,
-	0x290a, 0x0000, 0x290a, 0x0000, 0x8066, 0x0000, 0x0422, 0x0000,
-	0x45e0, 0x000b, 0x0210, 0x0004, 0x8054, 0x0008, 0x0004, 0x0000,
-	0x8074, 0x0000, 0xf000, 0x0008, 0x8072, 0x0000, 0xb000, 0x0000,
-	0x019c, 0x0003, 0xbbe0, 0x0009, 0x0038, 0x0000, 0x0dfb, 0x000b,
-	0x18fe, 0x0000, 0x3ce0, 0x0009, 0x09f8, 0x0003, 0x15fe, 0x0008,
-	0x3ce0, 0x0009, 0x0db1, 0x0003, 0x020b, 0x0004, 0x8076, 0x0008,
-	0x0040, 0x0000, 0x8072, 0x0000, 0x8000, 0x0000, 0x0268, 0x000b,
-	0x8076, 0x0008, 0x0042, 0x0008, 0x0208, 0x000b, 0xbbe0, 0x0009,
-	0x0016, 0x0000, 0x0e08, 0x000b, 0x8074, 0x0000, 0x0808, 0x0008,
-	0x3a44, 0x0002, 0x0c0c, 0x000b, 0x8074, 0x0000, 0x0800, 0x0000,
-	0x8072, 0x0000, 0x8000, 0x0000, 0x8000, 0x000f, 0x000a, 0x000b,
-	0x8072, 0x0000, 0x8000, 0x0000, 0x000a, 0x000b, 0x3d30, 0x000a,
-	0x7f00, 0x0000, 0xbc80, 0x0001, 0x0007, 0x0000, 0x0214, 0x0003,
-	0x1930, 0x000a, 0x7f00, 0x0000, 0x9880, 0x0001, 0x0007, 0x0000,
-	0x8060, 0x0000, 0x0400, 0x0000, 0x7f62, 0x0008, 0x8066, 0x0000,
-	0x000a, 0x0008, 0x4619, 0x000b, 0x4000, 0x000f, 0x221e, 0x000b,
-	0x0870, 0x0008, 0x4000, 0x000f, 0x7e1b, 0x000b, 0xbbe0, 0x0009,
-	0x0030, 0x0008, 0x0e1b, 0x0003, 0x18fe, 0x0000, 0x3ce0, 0x0009,
-	0x0a2c, 0x0003, 0x15fe, 0x0008, 0x3ce0, 0x0009, 0x0a2c, 0x0003,
-	0x020b, 0x0004, 0x8076, 0x0008, 0x0040, 0x0000, 0x022e, 0x0003,
-	0x8076, 0x0008, 0x0041, 0x0008, 0x8072, 0x0000, 0x8000, 0x0000,
-	0x021b, 0x0003, 0xbac0, 0x0009, 0x0090, 0x0008, 0x0a37, 0x0003,
-	0x8074, 0x0000, 0x0706, 0x0000, 0x0239, 0x0003, 0x8074, 0x0000,
-	0x0703, 0x0000, 0x4000, 0x000f, 0x8010, 0x0008, 0x0023, 0x0000,
-	0x0276, 0x000b, 0x8010, 0x0008, 0x0008, 0x0000, 0x0276, 0x000b,
-	0x8010, 0x0008, 0x0022, 0x0008, 0x0276, 0x000b, 0x0210, 0x0004,
-	0x8010, 0x0008, 0x0007, 0x0000, 0x021b, 0x000c, 0x1810, 0x0000,
-	0x021b, 0x000c, 0x0282, 0x0003, 0x0210, 0x0004, 0x8010, 0x0008,
-	0x001b, 0x0008, 0x021b, 0x000c, 0x1810, 0x0000, 0x021b, 0x000c,
-	0x8074, 0x0000, 0xf080, 0x0000, 0x8072, 0x0000, 0x3000, 0x0008,
-	0x0d30, 0x0000, 0x000a, 0x000b, 0x8010, 0x0008, 0x0009, 0x0008,
-	0x0276, 0x000b, 0x8010, 0x0008, 0x0005, 0x0008, 0x0276, 0x000b,
-	0x1648, 0x000a, 0x0c6f, 0x000b, 0x808c, 0x0008, 0x0001, 0x0000,
-	0x8010, 0x0008, 0x0004, 0x0000, 0x4143, 0x000a, 0x086f, 0x0003,
-	0x3a44, 0x0002, 0x0c0a, 0x000b, 0x0d2a, 0x0008, 0x0276, 0x000b,
-	0x8010, 0x0008, 0x0003, 0x0008, 0x027a, 0x000b, 0x8010, 0x0008,
-	0x000b, 0x0000, 0x027a, 0x000b, 0x8010, 0x0008, 0x0002, 0x0000,
-	0x027a, 0x000b, 0x3a47, 0x0002, 0x0d40, 0x000b, 0x8010, 0x0008,
-	0x0006, 0x0008, 0x027a, 0x000b, 0x8074, 0x0000, 0xf000, 0x0008,
-	0x8072, 0x0000, 0x3000, 0x0008, 0x021b, 0x000c, 0x0231, 0x0004,
-	0x3a40, 0x000a, 0x080a, 0x0003, 0x8010, 0x0008, 0x000c, 0x0008,
-	0x021b, 0x000c, 0x000a, 0x000b, 0x8074, 0x0000, 0xf080, 0x0000,
-	0x8072, 0x0000, 0x3000, 0x0008, 0x0d30, 0x0000, 0x2e4d, 0x0002,
-	0x2e4d, 0x0002, 0x0a8d, 0x000b, 0x8054, 0x0008, 0x0019, 0x0000,
-	0x000a, 0x000b, 0x8054, 0x0008, 0x0009, 0x0008, 0x000a, 0x000b,
-	0x3a44, 0x0002, 0x0c0a, 0x000b, 0x026b, 0x000b, 0x808c, 0x0008,
-	0x0000, 0x0008, 0x4447, 0x0002, 0x0ab9, 0x0003, 0xc0c0, 0x0001,
-	0x00ff, 0x0008, 0xffe0, 0x0009, 0x00ff, 0x0008, 0x0e90, 0x0003,
-	0xc1e0, 0x0001, 0xffff, 0x0008, 0x0e90, 0x0003, 0x8010, 0x0008,
-	0x0013, 0x0000, 0x021b, 0x000c, 0x8074, 0x0000, 0x0202, 0x0008,
-	0x000a, 0x000b, 0x3a40, 0x000a, 0x0eb6, 0x000b, 0x8074, 0x0000,
-	0x0200, 0x0000, 0x3d00, 0x0000, 0x3cfe, 0x0000, 0x8072, 0x0000,
-	0x8000, 0x0000, 0x43e0, 0x0001, 0x0eb4, 0x0003, 0x42fe, 0x0000,
-	0xffc0, 0x0001, 0x00ff, 0x0008, 0x00e0, 0x0009, 0x0a90, 0x000b,
-	0x0d08, 0x0008, 0x0309, 0x000b, 0x8072, 0x0000, 0x8000, 0x0000,
-	0x000a, 0x000b, 0x038d, 0x0004, 0x808c, 0x0008, 0x0001, 0x0000,
-	0x04fe, 0x0008, 0x3370, 0x0003, 0x0460, 0x0000, 0x8062, 0x0008,
-	0x0001, 0x0000, 0x8066, 0x0000, 0x0009, 0x0008, 0x46c3, 0x0003,
-	0x0004, 0x0000, 0x80c0, 0x0009, 0x00ff, 0x0008, 0x7f00, 0x0000,
-	0x80e0, 0x0001, 0x0004, 0x0000, 0x0add, 0x000b, 0x80e0, 0x0001,
-	0x0005, 0x0008, 0x0add, 0x000b, 0x80e0, 0x0001, 0x0006, 0x0008,
-	0x0add, 0x000b, 0x82c0, 0x0001, 0xff00, 0x0008, 0x7f04, 0x0008,
-	0x82e0, 0x0009, 0x0600, 0x0008, 0x0add, 0x000b, 0x82e0, 0x0009,
-	0x0500, 0x0008, 0x0add, 0x000b, 0x82e0, 0x0009, 0x0400, 0x0000,
-	0x0f70, 0x0003, 0xc4c0, 0x0009, 0x7000, 0x0000, 0xffe0, 0x0009,
-	0x1000, 0x0000, 0x0b09, 0x0003, 0x037e, 0x0004, 0x3941, 0x0002,
-	0x0ae8, 0x000b, 0x8072, 0x0000, 0x0400, 0x0000, 0x000a, 0x000b,
-	0x0460, 0x0000, 0x80fe, 0x0008, 0x002b, 0x0008, 0x7f62, 0x0008,
-	0x8066, 0x0000, 0x2209, 0x0008, 0x46ee, 0x0003, 0x11fe, 0x0000,
-	0x3304, 0x0003, 0x9180, 0x0001, 0x0002, 0x0000, 0x8060, 0x0000,
-	0x0400, 0x0000, 0x7f62, 0x0008, 0x8066, 0x0000, 0x0609, 0x0008,
-	0x46f8, 0x000b, 0x42fe, 0x0000, 0xffc0, 0x0001, 0xff00, 0x0008,
-	0x03e0, 0x0009, 0x0f01, 0x0003, 0x8072, 0x0000, 0x0400, 0x0000,
-	0x0046, 0x0003, 0x9180, 0x0001, 0x0003, 0x0008, 0x02eb, 0x0003,
-	0x8072, 0x0000, 0x0400, 0x0000, 0x8010, 0x0008, 0x0010, 0x0000,
-	0x0361, 0x0003, 0x037e, 0x0004, 0x3941, 0x0002, 0x0b0f, 0x0003,
-	0x8072, 0x0000, 0x0400, 0x0000, 0x000a, 0x000b, 0x0346, 0x000c,
-	0x11fe, 0x0000, 0x3717, 0x0003, 0x8072, 0x0000, 0x0400, 0x0000,
-	0x8010, 0x0008, 0x000e, 0x0000, 0x0361, 0x0003, 0x8060, 0x0000,
-	0x0400, 0x0000, 0x04fe, 0x0008, 0x372c, 0x000b, 0x808c, 0x0008,
-	0x0000, 0x0008, 0x9180, 0x0001, 0x0005, 0x0008, 0x7f62, 0x0008,
-	0x8066, 0x0000, 0x0009, 0x0008, 0x4722, 0x000b, 0x0060, 0x0008,
-	0x8062, 0x0008, 0x001b, 0x0008, 0x4304, 0x0008, 0x4206, 0x0008,
-	0x8066, 0x0000, 0x0412, 0x0000, 0x472a, 0x0003, 0x0343, 0x0003,
-	0x808c, 0x0008, 0x0001, 0x0000, 0x0460, 0x0000, 0x8062, 0x0008,
-	0x002b, 0x0008, 0x8066, 0x0000, 0x0609, 0x0008, 0x4733, 0x000b,
-	0x8066, 0x0000, 0x220a, 0x0008, 0x4736, 0x000b, 0x42fe, 0x0000,
-	0xffc0, 0x0001, 0xff00, 0x0008, 0x7f04, 0x0008, 0x8060, 0x0000,
-	0x0400, 0x0000, 0x9180, 0x0001, 0x0002, 0x0000, 0x7f62, 0x0008,
-	0x8066, 0x0000, 0x041a, 0x0008, 0x4742, 0x000b, 0x8072, 0x0000,
-	0x0400, 0x0000, 0x0046, 0x0003, 0x8060, 0x0000, 0x0400, 0x0000,
-	0x1362, 0x0008, 0x8066, 0x0000, 0x0411, 0x0000, 0x474b, 0x000b,
-	0x02fe, 0x0008, 0x03e0, 0x0009, 0x0f51, 0x0003, 0x0d22, 0x0000,
-	0x4000, 0x000f, 0x8280, 0x0009, 0x0002, 0x0000, 0x1380, 0x0001,
-	0x7f62, 0x0008, 0x8066, 0x0000, 0x2209, 0x0008, 0x4757, 0x0003,
-	0x0200, 0x000a, 0xffc0, 0x0001, 0x0007, 0x0000, 0x7f06, 0x0000,
-	0x1362, 0x0008, 0x8066, 0x0000, 0x060a, 0x0008, 0x475f, 0x000b,
-	0x4000, 0x000f, 0x3a44, 0x0002, 0x0c0a, 0x000b, 0x2f44, 0x000a,
-	0x2f44, 0x000a, 0x0e6b, 0x000b, 0x808a, 0x0008, 0x0003, 0x0008,
-	0x8074, 0x0000, 0xf080, 0x0000, 0x8072, 0x0000, 0x3000, 0x0008,
-	0x5b6c, 0x0003, 0x8054, 0x0008, 0x0019, 0x0000, 0x000a, 0x000b,
-	0x3a44, 0x0002, 0x0c0a, 0x000b, 0x808c, 0x0008, 0x0000, 0x0008,
-	0x8010, 0x0008, 0x0011, 0x0008, 0x021b, 0x000c, 0x42fe, 0x0000,
-	0xffc0, 0x0001, 0x00ff, 0x0008, 0x7f10, 0x0008, 0x021b, 0x000c,
-	0x4310, 0x0008, 0x027a, 0x000b, 0x3941, 0x0002, 0x0b81, 0x0003,
-	0x4000, 0x000f, 0x8072, 0x0000, 0x0404, 0x0008, 0x4000, 0x000f,
-	0x8010, 0x0008, 0x0012, 0x0008, 0x021b, 0x000c, 0x0346, 0x000c,
-	0x1110, 0x0000, 0x021b, 0x000c, 0x11fe, 0x0000, 0x3787, 0x0003,
-	0x000a, 0x000b, 0xc2c0, 0x0009, 0x00ff, 0x0008, 0x7f00, 0x0000,
-	0xc3c0, 0x0001, 0xff00, 0x0008, 0x00d0, 0x0009, 0x0bb2, 0x0003,
-	0x0d0a, 0x0000, 0x8580, 0x0001, 0x1000, 0x0000, 0x7f62, 0x0008,
-	0x8060, 0x0000, 0x0400, 0x0000, 0x8066, 0x0000, 0x0809, 0x0000,
-	0x479c, 0x000b, 0x04fe, 0x0008, 0x33ab, 0x0003, 0x0460, 0x0000,
-	0x8062, 0x0008, 0x0004, 0x0000, 0x8066, 0x0000, 0x0211, 0x0000,
-	0x47a4, 0x0003, 0x01fe, 0x0008, 0x00e0, 0x0009, 0x0fab, 0x0003,
-	0x02fe, 0x0008, 0x43e0, 0x0001, 0x0bb1, 0x0003, 0x0500, 0x0002,
-	0x7f0a, 0x0000, 0xffe0, 0x0009, 0x0800, 0x0000, 0x0f95, 0x000b,
-	0x0d08, 0x0008, 0x4000, 0x000f, 0x43fe, 0x0008, 0x3e80, 0x0001,
-	0xffc0, 0x0001, 0x7fff, 0x0000, 0x0d60, 0x0000, 0x7f62, 0x0008,
-	0x8066, 0x0000, 0x0809, 0x0000, 0x47ba, 0x0003, 0x8060, 0x0000,
-	0x0400, 0x0000, 0x84c0, 0x0001, 0xff00, 0x0008, 0x7f60, 0x000a,
+	0x0005, 0x2001, 0x1810, 0x2004, 0xd0a4, 0x0160, 0x2001, 0x1837,
+	0x2004, 0xd0a4, 0x0138, 0x2001, 0x1848, 0x2004, 0xd0a4, 0x1118,
+	0x9085, 0x0001, 0x0005, 0x9006, 0x0ce8, 0x0126, 0x0006, 0x00e6,
+	0x0016, 0x2091, 0x8000, 0x2071, 0x1840, 0xd5a4, 0x0118, 0x7004,
+	0x8000, 0x7006, 0xd5b4, 0x0118, 0x7000, 0x8000, 0x7002, 0xd5ac,
+	0x0178, 0x2500, 0x9084, 0x0007, 0x908e, 0x0003, 0x0148, 0x908e,
+	0x0004, 0x0130, 0x908e, 0x0005, 0x0118, 0x2071, 0xfff6, 0x0089,
+	0x001e, 0x00ee, 0x000e, 0x012e, 0x0005, 0x0126, 0x0006, 0x00e6,
+	0x2091, 0x8000, 0x2071, 0xffee, 0x0021, 0x00ee, 0x000e, 0x012e,
+	0x0005, 0x2e05, 0x8000, 0x2077, 0x1220, 0x8e70, 0x2e05, 0x8000,
+	0x2077, 0x0005, 0x00e6, 0x2071, 0xffec, 0x0c99, 0x00ee, 0x0005,
+	0x00e6, 0x2071, 0xfff0, 0x0c69, 0x00ee, 0x0005, 0x0126, 0x0006,
+	0x00e6, 0x2091, 0x8000, 0x2071, 0x1840, 0x7014, 0x8000, 0x7016,
+	0x00ee, 0x000e, 0x012e, 0x0005, 0x0003, 0x000b, 0x07c8, 0x0000,
+	0xc000, 0x0001, 0x8064, 0x0008, 0x0010, 0x0000, 0x8066, 0x0000,
+	0x0101, 0x0008, 0x4407, 0x0003, 0x8060, 0x0000, 0x0400, 0x0000,
+	0x580d, 0x000b, 0x79bd, 0x0003, 0x5103, 0x0003, 0x4c0a, 0x0003,
+	0xbac0, 0x0009, 0x008a, 0x0000, 0x0c0a, 0x000b, 0x15fe, 0x0008,
+	0x340a, 0x0003, 0xc4c0, 0x0009, 0x7000, 0x0000, 0xffa0, 0x0001,
+	0x2000, 0x0000, 0x167d, 0x0003, 0x808c, 0x0008, 0x0001, 0x0000,
+	0x0000, 0x0007, 0x4028, 0x0000, 0x4047, 0x000a, 0x808c, 0x0008,
+	0x0002, 0x0000, 0x0822, 0x0003, 0x4022, 0x0000, 0x0028, 0x000b,
+	0x4122, 0x0008, 0x94c0, 0x0009, 0xff00, 0x0008, 0xffe0, 0x0009,
+	0x0500, 0x0008, 0x0aa8, 0x0003, 0x4447, 0x0002, 0x0ea5, 0x0003,
+	0x0bfe, 0x0008, 0x11a0, 0x0001, 0x1283, 0x0003, 0x0ca0, 0x0001,
+	0x1283, 0x0003, 0x9180, 0x0001, 0x0004, 0x0000, 0x8060, 0x0000,
+	0x0400, 0x0000, 0x7f62, 0x0008, 0x8066, 0x0000, 0x0009, 0x0008,
+	0x4436, 0x000b, 0x808c, 0x0008, 0x0000, 0x0008, 0x0060, 0x0008,
+	0x8062, 0x0008, 0x0004, 0x0000, 0x8066, 0x0000, 0x0411, 0x0000,
+	0x443e, 0x0003, 0x03fe, 0x0000, 0x43e0, 0x0001, 0x0e80, 0x000b,
+	0xc2c0, 0x0009, 0x00ff, 0x0008, 0x02e0, 0x0001, 0x0e80, 0x000b,
+	0x9180, 0x0001, 0x0005, 0x0008, 0x8060, 0x0000, 0x0400, 0x0000,
+	0x7f62, 0x0008, 0x8066, 0x0000, 0x0019, 0x0000, 0x444d, 0x000b,
+	0x0240, 0x0002, 0x0a7d, 0x000b, 0x00fe, 0x0000, 0x3280, 0x000b,
+	0x0248, 0x000a, 0x085c, 0x0003, 0x9180, 0x0001, 0x0006, 0x0008,
+	0x7f62, 0x0008, 0x8002, 0x0008, 0x0003, 0x0008, 0x8066, 0x0000,
+	0x020a, 0x0000, 0x445b, 0x0003, 0x112a, 0x0000, 0x002e, 0x0008,
+	0x022c, 0x0008, 0x3a44, 0x0002, 0x0c0a, 0x000b, 0x808c, 0x0008,
+	0x0002, 0x0000, 0x1760, 0x0008, 0x8062, 0x0008, 0x000f, 0x0008,
+	0x8066, 0x0000, 0x0011, 0x0008, 0x4468, 0x0003, 0x01fe, 0x0008,
+	0x42e0, 0x0009, 0x0e71, 0x0003, 0x00fe, 0x0000, 0x43e0, 0x0001,
+	0x0e71, 0x0003, 0x1734, 0x0000, 0x1530, 0x0000, 0x1632, 0x0008,
+	0x0d2a, 0x0008, 0x9880, 0x0001, 0x0010, 0x0000, 0x8060, 0x0000,
+	0x0400, 0x0000, 0x7f62, 0x0008, 0x8066, 0x0000, 0x1e0a, 0x0008,
+	0x447a, 0x0003, 0x808a, 0x0008, 0x0003, 0x0008, 0x1a60, 0x0000,
+	0x8062, 0x0008, 0x0002, 0x0000, 0x5880, 0x000b, 0x8066, 0x0000,
+	0x3679, 0x0000, 0x4483, 0x0003, 0x5884, 0x0003, 0x3efe, 0x0008,
+	0x7f4f, 0x0002, 0x088a, 0x000b, 0x0d00, 0x0000, 0x0092, 0x000c,
+	0x8054, 0x0008, 0x0011, 0x0008, 0x8074, 0x0000, 0x1010, 0x0008,
+	0x1efe, 0x0000, 0x300a, 0x000b, 0x00dd, 0x0004, 0x000a, 0x000b,
+	0x00fe, 0x0000, 0x349a, 0x0003, 0x1a60, 0x0000, 0x8062, 0x0008,
+	0x0007, 0x0000, 0x8066, 0x0000, 0x0231, 0x0008, 0x4499, 0x000b,
+	0x03fe, 0x0000, 0x04d0, 0x0001, 0x0cd1, 0x000b, 0x82c0, 0x0001,
+	0x1f00, 0x0000, 0xffa0, 0x0001, 0x0400, 0x0000, 0x08af, 0x0003,
+	0x14d9, 0x0003, 0x01fe, 0x0008, 0x0580, 0x0009, 0x7f06, 0x0000,
+	0x02fe, 0x0008, 0xffc0, 0x0001, 0x00ff, 0x0008, 0x0690, 0x0001,
+	0x10af, 0x0003, 0x7f08, 0x0008, 0x84c0, 0x0001, 0xff00, 0x0008,
+	0x08d1, 0x0003, 0xb9c0, 0x0009, 0x0030, 0x0008, 0x0cc0, 0x000b,
+	0x8060, 0x0000, 0x0400, 0x0000, 0x80fe, 0x0008, 0x1a0b, 0x0001,
+	0x7f62, 0x0008, 0x8066, 0x0000, 0x0409, 0x0000, 0x44b9, 0x0003,
+	0x80fe, 0x0008, 0x1a0a, 0x0009, 0x7f62, 0x0008, 0x8066, 0x0000,
+	0x040a, 0x0000, 0x44bf, 0x0003, 0x00fe, 0x0000, 0x34c7, 0x000b,
+	0x8072, 0x0000, 0x1010, 0x0008, 0x3944, 0x0002, 0x08c2, 0x000b,
+	0x00cb, 0x0003, 0x8072, 0x0000, 0x2020, 0x0008, 0x3945, 0x000a,
+	0x08c7, 0x000b, 0x3946, 0x000a, 0x0cd8, 0x000b, 0x0000, 0x0007,
+	0x3943, 0x000a, 0x08d8, 0x0003, 0x00cb, 0x0003, 0x00fe, 0x0000,
+	0x34d6, 0x000b, 0x8072, 0x0000, 0x1000, 0x0000, 0x00d8, 0x000b,
+	0x8072, 0x0000, 0x2000, 0x0000, 0x4000, 0x000f, 0x86c0, 0x0009,
+	0xfc00, 0x0008, 0x08d1, 0x0003, 0x00af, 0x000b, 0x1c60, 0x0000,
+	0x1b62, 0x0000, 0x8066, 0x0000, 0x0231, 0x0008, 0x44e1, 0x000b,
+	0x58e2, 0x0003, 0x0140, 0x0008, 0x0242, 0x0000, 0x1f43, 0x0002,
+	0x0cf0, 0x000b, 0x0d44, 0x0000, 0x0d46, 0x0008, 0x0348, 0x0008,
+	0x044a, 0x0008, 0x030a, 0x0008, 0x040c, 0x0000, 0x0d06, 0x0000,
+	0x0d08, 0x0008, 0x00f4, 0x0003, 0x0344, 0x0008, 0x0446, 0x0008,
+	0x0548, 0x0008, 0x064a, 0x0000, 0x1948, 0x000a, 0x08f7, 0x000b,
+	0x0d4a, 0x0008, 0x58f7, 0x000b, 0x3efe, 0x0008, 0x7f4f, 0x0002,
+	0x08fe, 0x000b, 0x8000, 0x0000, 0x0001, 0x0000, 0x0092, 0x000c,
+	0x8054, 0x0008, 0x0001, 0x0000, 0x8074, 0x0000, 0x2020, 0x0008,
+	0x4000, 0x000f, 0x3a40, 0x000a, 0x0c0d, 0x0003, 0x2b24, 0x0008,
+	0x2b24, 0x0008, 0x5907, 0x0003, 0x8054, 0x0008, 0x0002, 0x0000,
+	0x1242, 0x0002, 0x0955, 0x000b, 0x3a45, 0x000a, 0x0944, 0x000b,
+	0x8072, 0x0000, 0x1000, 0x0000, 0x3945, 0x000a, 0x0914, 0x000b,
+	0x8072, 0x0000, 0x3010, 0x0000, 0x1e10, 0x000a, 0x7f3c, 0x0000,
+	0x093f, 0x000b, 0x1d00, 0x0002, 0x7f3a, 0x0000, 0x0d60, 0x0000,
+	0x7f62, 0x0008, 0x8066, 0x0000, 0x0009, 0x0008, 0x451d, 0x0003,
+	0x00fe, 0x0000, 0x353c, 0x000b, 0x1c60, 0x0000, 0x8062, 0x0008,
+	0x0001, 0x0000, 0x8066, 0x0000, 0x0009, 0x0008, 0x4525, 0x000b,
+	0x00fe, 0x0000, 0x3258, 0x000b, 0x0038, 0x0000, 0x0060, 0x0008,
+	0x8062, 0x0008, 0x0019, 0x0000, 0x8066, 0x0000, 0x0009, 0x0008,
+	0x452e, 0x0003, 0x80c0, 0x0009, 0x00ff, 0x0008, 0x7f3e, 0x0008,
+	0x0d60, 0x0000, 0x0efe, 0x0008, 0x1f80, 0x0001, 0x7f62, 0x0008,
+	0x8066, 0x0000, 0x0009, 0x0008, 0x4538, 0x000b, 0x003a, 0x0008,
+	0x1dfe, 0x0000, 0x0119, 0x000b, 0x0036, 0x0008, 0x00dd, 0x0004,
+	0x0155, 0x0003, 0x8074, 0x0000, 0x2000, 0x0000, 0x8072, 0x0000,
+	0x2000, 0x0000, 0x0155, 0x0003, 0x3a44, 0x0002, 0x0a86, 0x0003,
+	0x8074, 0x0000, 0x1000, 0x0000, 0x8072, 0x0000, 0x1000, 0x0000,
+	0x2d0e, 0x0000, 0x2d0e, 0x0000, 0x3655, 0x000b, 0x26fe, 0x0008,
+	0x26fe, 0x0008, 0x2700, 0x0008, 0x2700, 0x0008, 0x00d0, 0x0009,
+	0x0d67, 0x000b, 0x8074, 0x0000, 0x4040, 0x0008, 0x5955, 0x000b,
+	0x5103, 0x0003, 0x3a46, 0x000a, 0x0d67, 0x000b, 0x3a47, 0x0002,
+	0x0962, 0x0003, 0x8054, 0x0008, 0x0004, 0x0000, 0x8074, 0x0000,
+	0x8000, 0x0000, 0x8072, 0x0000, 0x3000, 0x0008, 0x01b1, 0x0003,
+	0x92c0, 0x0009, 0x0fc8, 0x0000, 0x080a, 0x0003, 0x1246, 0x000a,
+	0x0e4f, 0x000b, 0x1a60, 0x0000, 0x8062, 0x0008, 0x0002, 0x0000,
+	0x8066, 0x0000, 0x362a, 0x0000, 0x456c, 0x0003, 0x2000, 0x0000,
+	0x2000, 0x0000, 0x2102, 0x0000, 0x2102, 0x0000, 0x2204, 0x0000,
+	0x2204, 0x0000, 0x2306, 0x0000, 0x2306, 0x0000, 0x2408, 0x0000,
+	0x2408, 0x0000, 0x250a, 0x0000, 0x250a, 0x0000, 0x260c, 0x0000,
+	0x260c, 0x0000, 0x270e, 0x0000, 0x270e, 0x0000, 0x2810, 0x0000,
+	0x2810, 0x0000, 0x2912, 0x0000, 0x2912, 0x0000, 0x1a60, 0x0000,
+	0x8062, 0x0008, 0x0007, 0x0000, 0x8066, 0x0000, 0x0052, 0x0000,
+	0x4586, 0x000b, 0x92c0, 0x0009, 0x0780, 0x0008, 0x0e6b, 0x000b,
+	0x124b, 0x0002, 0x098f, 0x0003, 0x2e4d, 0x0002, 0x2e4d, 0x0002,
+	0x0a55, 0x000b, 0x3a46, 0x000a, 0x0d9f, 0x0003, 0x5991, 0x0003,
+	0x8054, 0x0008, 0x0004, 0x0000, 0x1243, 0x000a, 0x09ad, 0x0003,
+	0x8010, 0x0008, 0x000d, 0x0000, 0x0230, 0x000c, 0x1948, 0x000a,
+	0x099c, 0x000b, 0x0225, 0x0004, 0x1810, 0x0000, 0x0230, 0x000c,
+	0x01ad, 0x000b, 0x1948, 0x000a, 0x09a3, 0x000b, 0x1243, 0x000a,
+	0x0a58, 0x0003, 0x194d, 0x000a, 0x09a7, 0x0003, 0x1243, 0x000a,
+	0x0a5f, 0x000b, 0x59a7, 0x0003, 0x8054, 0x0008, 0x0004, 0x0000,
+	0x0225, 0x0004, 0x1810, 0x0000, 0x0230, 0x000c, 0x8074, 0x0000,
+	0xf000, 0x0008, 0x8072, 0x0000, 0x3000, 0x0008, 0x0d30, 0x0000,
+	0x3a42, 0x0002, 0x0db7, 0x0003, 0x15fe, 0x0008, 0x3461, 0x000b,
+	0x000a, 0x000b, 0x8074, 0x0000, 0x0501, 0x0000, 0x8010, 0x0008,
+	0x000c, 0x0008, 0x0230, 0x000c, 0x000a, 0x000b, 0xbbe0, 0x0009,
+	0x0030, 0x0008, 0x0dcd, 0x000b, 0x18fe, 0x0000, 0x3ce0, 0x0009,
+	0x09ca, 0x000b, 0x15fe, 0x0008, 0x3ce0, 0x0009, 0x09ca, 0x000b,
+	0x0220, 0x0004, 0x8076, 0x0008, 0x0040, 0x0000, 0x021d, 0x0003,
+	0x8076, 0x0008, 0x0041, 0x0008, 0x021d, 0x0003, 0xbbe0, 0x0009,
+	0x0032, 0x0000, 0x0dd2, 0x0003, 0x3c1e, 0x0008, 0x021d, 0x0003,
+	0xbbe0, 0x0009, 0x003b, 0x0000, 0x0dd7, 0x0003, 0x3c20, 0x0000,
+	0x021d, 0x0003, 0xbbe0, 0x0009, 0x0035, 0x0008, 0x0ddd, 0x0003,
+	0x8072, 0x0000, 0x8000, 0x0000, 0x0399, 0x000b, 0xbbe0, 0x0009,
+	0x0036, 0x0008, 0x0aba, 0x0003, 0xbbe0, 0x0009, 0x0037, 0x0000,
+	0x0dfe, 0x000b, 0x18fe, 0x0000, 0x3ce0, 0x0009, 0x0dca, 0x0003,
+	0x8076, 0x0008, 0x0040, 0x0000, 0x1a60, 0x0000, 0x8062, 0x0008,
+	0x000d, 0x0000, 0x2604, 0x0008, 0x2604, 0x0008, 0x2706, 0x0008,
+	0x2706, 0x0008, 0x2808, 0x0000, 0x2808, 0x0000, 0x290a, 0x0000,
+	0x290a, 0x0000, 0x8066, 0x0000, 0x0422, 0x0000, 0x45f5, 0x0003,
+	0x0225, 0x0004, 0x8054, 0x0008, 0x0004, 0x0000, 0x8074, 0x0000,
+	0xf000, 0x0008, 0x8072, 0x0000, 0xb000, 0x0000, 0x01b1, 0x0003,
+	0xbbe0, 0x0009, 0x0038, 0x0000, 0x0e10, 0x000b, 0x18fe, 0x0000,
+	0x3ce0, 0x0009, 0x0a0d, 0x0003, 0x15fe, 0x0008, 0x3ce0, 0x0009,
+	0x0dc6, 0x0003, 0x0220, 0x0004, 0x8076, 0x0008, 0x0040, 0x0000,
+	0x8072, 0x0000, 0x8000, 0x0000, 0x027d, 0x0003, 0x8076, 0x0008,
+	0x0042, 0x0008, 0x021d, 0x0003, 0xbbe0, 0x0009, 0x0016, 0x0000,
+	0x0e1d, 0x0003, 0x8074, 0x0000, 0x0808, 0x0008, 0x3a44, 0x0002,
+	0x0c0c, 0x000b, 0x8074, 0x0000, 0x0800, 0x0000, 0x8072, 0x0000,
+	0x8000, 0x0000, 0x8000, 0x000f, 0x000a, 0x000b, 0x8072, 0x0000,
+	0x8000, 0x0000, 0x000a, 0x000b, 0x3d30, 0x000a, 0x7f00, 0x0000,
+	0xbc80, 0x0001, 0x0007, 0x0000, 0x0229, 0x000b, 0x1930, 0x000a,
+	0x7f00, 0x0000, 0x9880, 0x0001, 0x0007, 0x0000, 0x8060, 0x0000,
+	0x0400, 0x0000, 0x7f62, 0x0008, 0x8066, 0x0000, 0x000a, 0x0008,
+	0x462e, 0x0003, 0x4000, 0x000f, 0x2233, 0x000b, 0x0870, 0x0008,
+	0x4000, 0x000f, 0x7e30, 0x000b, 0xbbe0, 0x0009, 0x0030, 0x0008,
+	0x0e30, 0x0003, 0x18fe, 0x0000, 0x3ce0, 0x0009, 0x0a41, 0x000b,
+	0x15fe, 0x0008, 0x3ce0, 0x0009, 0x0a41, 0x000b, 0x0220, 0x0004,
+	0x8076, 0x0008, 0x0040, 0x0000, 0x0243, 0x000b, 0x8076, 0x0008,
+	0x0041, 0x0008, 0x8072, 0x0000, 0x8000, 0x0000, 0x0230, 0x0003,
+	0xbac0, 0x0009, 0x0090, 0x0008, 0x0a4c, 0x0003, 0x8074, 0x0000,
+	0x0706, 0x0000, 0x024e, 0x0003, 0x8074, 0x0000, 0x0703, 0x0000,
+	0x4000, 0x000f, 0x8010, 0x0008, 0x0023, 0x0000, 0x028b, 0x0003,
+	0x8010, 0x0008, 0x0008, 0x0000, 0x028b, 0x0003, 0x8010, 0x0008,
+	0x0022, 0x0008, 0x028b, 0x0003, 0x0225, 0x0004, 0x8010, 0x0008,
+	0x0007, 0x0000, 0x0230, 0x000c, 0x1810, 0x0000, 0x0230, 0x000c,
+	0x0297, 0x000b, 0x0225, 0x0004, 0x8010, 0x0008, 0x001b, 0x0008,
+	0x0230, 0x000c, 0x1810, 0x0000, 0x0230, 0x000c, 0x8074, 0x0000,
+	0xf080, 0x0000, 0x8072, 0x0000, 0x3000, 0x0008, 0x0d30, 0x0000,
+	0x000a, 0x000b, 0x8010, 0x0008, 0x0009, 0x0008, 0x028b, 0x0003,
+	0x8010, 0x0008, 0x0005, 0x0008, 0x028b, 0x0003, 0x1648, 0x000a,
+	0x0c6f, 0x000b, 0x808c, 0x0008, 0x0001, 0x0000, 0x8010, 0x0008,
+	0x0004, 0x0000, 0x4143, 0x000a, 0x086f, 0x0003, 0x3a44, 0x0002,
+	0x0c0a, 0x000b, 0x0d2a, 0x0008, 0x028b, 0x0003, 0x8010, 0x0008,
+	0x0003, 0x0008, 0x028f, 0x000b, 0x8010, 0x0008, 0x000b, 0x0000,
+	0x028f, 0x000b, 0x8010, 0x0008, 0x0002, 0x0000, 0x028f, 0x000b,
+	0x3a47, 0x0002, 0x0d55, 0x0003, 0x8010, 0x0008, 0x0006, 0x0008,
+	0x028f, 0x000b, 0x8074, 0x0000, 0xf000, 0x0008, 0x8072, 0x0000,
+	0x3000, 0x0008, 0x0230, 0x000c, 0x0246, 0x0004, 0x3a40, 0x000a,
+	0x080a, 0x0003, 0x8010, 0x0008, 0x000c, 0x0008, 0x0230, 0x000c,
+	0x000a, 0x000b, 0x8074, 0x0000, 0xf080, 0x0000, 0x8072, 0x0000,
+	0x3000, 0x0008, 0x0d30, 0x0000, 0x2e4d, 0x0002, 0x2e4d, 0x0002,
+	0x0aa2, 0x0003, 0x8054, 0x0008, 0x0019, 0x0000, 0x000a, 0x000b,
+	0x8054, 0x0008, 0x0009, 0x0008, 0x000a, 0x000b, 0x3a44, 0x0002,
+	0x0c0a, 0x000b, 0x0280, 0x000b, 0x808c, 0x0008, 0x0000, 0x0008,
+	0x4447, 0x0002, 0x0ace, 0x0003, 0xc0c0, 0x0001, 0x00ff, 0x0008,
+	0xffe0, 0x0009, 0x00ff, 0x0008, 0x0ea5, 0x0003, 0xc1e0, 0x0001,
+	0xffff, 0x0008, 0x0ea5, 0x0003, 0x8010, 0x0008, 0x0013, 0x0000,
+	0x0230, 0x000c, 0x8074, 0x0000, 0x0202, 0x0008, 0x000a, 0x000b,
+	0x3a40, 0x000a, 0x0ecb, 0x000b, 0x8074, 0x0000, 0x0200, 0x0000,
+	0x3d00, 0x0000, 0x3cfe, 0x0000, 0x8072, 0x0000, 0x8000, 0x0000,
+	0x43e0, 0x0001, 0x0ec9, 0x0003, 0x42fe, 0x0000, 0xffc0, 0x0001,
+	0x00ff, 0x0008, 0x00e0, 0x0009, 0x0aa5, 0x000b, 0x0d08, 0x0008,
+	0x031e, 0x000b, 0x8072, 0x0000, 0x8000, 0x0000, 0x000a, 0x000b,
+	0x03a2, 0x000c, 0x808c, 0x0008, 0x0001, 0x0000, 0x04fe, 0x0008,
+	0x3385, 0x0003, 0x0460, 0x0000, 0x8062, 0x0008, 0x0001, 0x0000,
+	0x8066, 0x0000, 0x0009, 0x0008, 0x46d8, 0x0003, 0x0004, 0x0000,
+	0x80c0, 0x0009, 0x00ff, 0x0008, 0x7f00, 0x0000, 0x80e0, 0x0001,
+	0x0004, 0x0000, 0x0af2, 0x0003, 0x80e0, 0x0001, 0x0005, 0x0008,
+	0x0af2, 0x0003, 0x80e0, 0x0001, 0x0006, 0x0008, 0x0af2, 0x0003,
+	0x82c0, 0x0001, 0xff00, 0x0008, 0x7f04, 0x0008, 0x82e0, 0x0009,
+	0x0600, 0x0008, 0x0af2, 0x0003, 0x82e0, 0x0009, 0x0500, 0x0008,
+	0x0af2, 0x0003, 0x82e0, 0x0009, 0x0400, 0x0000, 0x0f85, 0x0003,
+	0xc4c0, 0x0009, 0x7000, 0x0000, 0xffe0, 0x0009, 0x1000, 0x0000,
+	0x0b1e, 0x0003, 0x0393, 0x0004, 0x3941, 0x0002, 0x0afd, 0x0003,
+	0x8072, 0x0000, 0x0400, 0x0000, 0x000a, 0x000b, 0x0460, 0x0000,
+	0x80fe, 0x0008, 0x002b, 0x0008, 0x7f62, 0x0008, 0x8066, 0x0000,
+	0x2209, 0x0008, 0x4703, 0x000b, 0x11fe, 0x0000, 0x3319, 0x0003,
+	0x9180, 0x0001, 0x0002, 0x0000, 0x8060, 0x0000, 0x0400, 0x0000,
+	0x7f62, 0x0008, 0x8066, 0x0000, 0x0609, 0x0008, 0x470d, 0x0003,
+	0x42fe, 0x0000, 0xffc0, 0x0001, 0xff00, 0x0008, 0x03e0, 0x0009,
+	0x0f16, 0x0003, 0x8072, 0x0000, 0x0400, 0x0000, 0x0046, 0x0003,
+	0x9180, 0x0001, 0x0003, 0x0008, 0x0300, 0x000b, 0x8072, 0x0000,
+	0x0400, 0x0000, 0x8010, 0x0008, 0x0010, 0x0000, 0x0376, 0x0003,
+	0x0393, 0x0004, 0x3941, 0x0002, 0x0b24, 0x0003, 0x8072, 0x0000,
+	0x0400, 0x0000, 0x000a, 0x000b, 0x035b, 0x000c, 0x11fe, 0x0000,
+	0x372c, 0x000b, 0x8072, 0x0000, 0x0400, 0x0000, 0x8010, 0x0008,
+	0x000e, 0x0000, 0x0376, 0x0003, 0x8060, 0x0000, 0x0400, 0x0000,
+	0x04fe, 0x0008, 0x3741, 0x0003, 0x808c, 0x0008, 0x0000, 0x0008,
+	0x9180, 0x0001, 0x0005, 0x0008, 0x7f62, 0x0008, 0x8066, 0x0000,
+	0x0009, 0x0008, 0x4737, 0x0003, 0x0060, 0x0008, 0x8062, 0x0008,
+	0x001b, 0x0008, 0x4304, 0x0008, 0x4206, 0x0008, 0x8066, 0x0000,
+	0x0412, 0x0000, 0x473f, 0x000b, 0x0358, 0x0003, 0x808c, 0x0008,
+	0x0001, 0x0000, 0x0460, 0x0000, 0x8062, 0x0008, 0x002b, 0x0008,
+	0x8066, 0x0000, 0x0609, 0x0008, 0x4748, 0x000b, 0x8066, 0x0000,
+	0x220a, 0x0008, 0x474b, 0x000b, 0x42fe, 0x0000, 0xffc0, 0x0001,
+	0xff00, 0x0008, 0x7f04, 0x0008, 0x8060, 0x0000, 0x0400, 0x0000,
+	0x9180, 0x0001, 0x0002, 0x0000, 0x7f62, 0x0008, 0x8066, 0x0000,
+	0x041a, 0x0008, 0x4757, 0x0003, 0x8072, 0x0000, 0x0400, 0x0000,
+	0x0046, 0x0003, 0x8060, 0x0000, 0x0400, 0x0000, 0x1362, 0x0008,
+	0x8066, 0x0000, 0x0411, 0x0000, 0x4760, 0x000b, 0x02fe, 0x0008,
+	0x03e0, 0x0009, 0x0f66, 0x000b, 0x0d22, 0x0000, 0x4000, 0x000f,
+	0x8280, 0x0009, 0x0002, 0x0000, 0x1380, 0x0001, 0x7f62, 0x0008,
+	0x8066, 0x0000, 0x2209, 0x0008, 0x476c, 0x000b, 0x0200, 0x000a,
+	0xffc0, 0x0001, 0x0007, 0x0000, 0x7f06, 0x0000, 0x1362, 0x0008,
+	0x8066, 0x0000, 0x060a, 0x0008, 0x4774, 0x000b, 0x4000, 0x000f,
+	0x3a44, 0x0002, 0x0c0a, 0x000b, 0x2f44, 0x000a, 0x2f44, 0x000a,
+	0x0e80, 0x000b, 0x808a, 0x0008, 0x0003, 0x0008, 0x8074, 0x0000,
+	0xf080, 0x0000, 0x8072, 0x0000, 0x3000, 0x0008, 0x5b81, 0x0003,
+	0x8054, 0x0008, 0x0019, 0x0000, 0x000a, 0x000b, 0x3a44, 0x0002,
+	0x0c0a, 0x000b, 0x808c, 0x0008, 0x0000, 0x0008, 0x8010, 0x0008,
+	0x0011, 0x0008, 0x0230, 0x000c, 0x42fe, 0x0000, 0xffc0, 0x0001,
+	0x00ff, 0x0008, 0x7f10, 0x0008, 0x0230, 0x000c, 0x4310, 0x0008,
+	0x028f, 0x000b, 0x3941, 0x0002, 0x0b96, 0x0003, 0x4000, 0x000f,
+	0x8072, 0x0000, 0x0404, 0x0008, 0x4000, 0x000f, 0x8010, 0x0008,
+	0x0012, 0x0008, 0x0230, 0x000c, 0x035b, 0x000c, 0x1110, 0x0000,
+	0x0230, 0x000c, 0x11fe, 0x0000, 0x379c, 0x0003, 0x000a, 0x000b,
+	0xc2c0, 0x0009, 0x00ff, 0x0008, 0x7f00, 0x0000, 0xc3c0, 0x0001,
+	0xff00, 0x0008, 0x00d0, 0x0009, 0x0bc7, 0x000b, 0x0d0a, 0x0000,
+	0x8580, 0x0001, 0x1000, 0x0000, 0x7f62, 0x0008, 0x8060, 0x0000,
+	0x0400, 0x0000, 0x8066, 0x0000, 0x0809, 0x0000, 0x47b1, 0x000b,
+	0x04fe, 0x0008, 0x33c0, 0x000b, 0x0460, 0x0000, 0x8062, 0x0008,
+	0x0004, 0x0000, 0x8066, 0x0000, 0x0211, 0x0000, 0x47b9, 0x0003,
+	0x01fe, 0x0008, 0x00e0, 0x0009, 0x0fc0, 0x000b, 0x02fe, 0x0008,
+	0x43e0, 0x0001, 0x0bc6, 0x0003, 0x0500, 0x0002, 0x7f0a, 0x0000,
+	0xffe0, 0x0009, 0x0800, 0x0000, 0x0faa, 0x000b, 0x0d08, 0x0008,
+	0x4000, 0x000f, 0x43fe, 0x0008, 0x3e80, 0x0001, 0xffc0, 0x0001,
+	0x7fff, 0x0000, 0x0d60, 0x0000, 0x7f62, 0x0008, 0x8066, 0x0000,
+	0x0809, 0x0000, 0x47cf, 0x000b, 0x8060, 0x0000, 0x0400, 0x0000,
+	0x84c0, 0x0001, 0xff00, 0x0008, 0x7f60, 0x000a, 0x7f60, 0x000a,
 	0x7f60, 0x000a, 0x7f60, 0x000a, 0x7f60, 0x000a, 0x7f60, 0x000a,
-	0x7f60, 0x000a, 0x7f60, 0x000a, 0x7f60, 0x000a, 0xff80, 0x0009,
-	0x1000, 0x0000, 0x7f62, 0x0008, 0x8066, 0x0000, 0x0809, 0x0000,
-	0x47cc, 0x000b, 0x4000, 0x000f, 0x5ff4, 0xebed, 0x0001, 0x0002,
-	0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100, 0x0200,
-	0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000, 0xa258
+	0x7f60, 0x000a, 0x7f60, 0x000a, 0xff80, 0x0009, 0x1000, 0x0000,
+	0x7f62, 0x0008, 0x8066, 0x0000, 0x0809, 0x0000, 0x47e1, 0x000b,
+	0x4000, 0x000f, 0xb10e, 0xebeb, 0x0001, 0x0002, 0x0004, 0x0008,
+	0x0010, 0x0020, 0x0040, 0x0080, 0x0100, 0x0200, 0x0400, 0x0800,
+	0x1000, 0x2000, 0x4000, 0x8000, 0x393e
 };
 #ifdef UNIQUE_FW_NAME
-unsigned short fw2300ipx_length01 = 0xeb57;
+unsigned short fw2300ipx_length01 = 0xed9d;
 #else
-unsigned short risc_code_length01 = 0xeb57;
+unsigned short risc_code_length01 = 0xed9d;
 #endif
 
diff --git a/drivers/scsi/qla2xxx/ql2322.c b/drivers/scsi/qla2xxx/ql2322.c
--- a/drivers/scsi/qla2xxx/ql2322.c
+++ b/drivers/scsi/qla2xxx/ql2322.c
@@ -1,6 +1,6 @@
 /*
  * QLogic ISP2322 device driver for Linux 2.6.x
- * Copyright (C) 2003-2004 QLogic Corporation (www.qlogic.com)
+ * Copyright (C) 2003-2005 QLogic Corporation (www.qlogic.com)
  *
  * Released under GPL v2.
  */
diff --git a/drivers/scsi/qla2xxx/ql2322_fw.c b/drivers/scsi/qla2xxx/ql2322_fw.c
--- a/drivers/scsi/qla2xxx/ql2322_fw.c
+++ b/drivers/scsi/qla2xxx/ql2322_fw.c
@@ -2,7 +2,7 @@
  *                  QLOGIC LINUX SOFTWARE
  *
  * QLogic ISP2x00 device driver for Linux 2.6.x
- * Copyright (C) 2003 QLogic Corporation
+ * Copyright (C) 2005 QLogic Corporation
  * (www.qlogic.com)
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -18,7 +18,7 @@
  ******************************************************************************/
 
 /*
- *	Firmware Version 3.03.08 (10:03 Nov 12, 2004)
+ *	Firmware Version 3.03.15 (10:09 May 26, 2005)
  */
 
 #ifdef UNIQUE_FW_NAME
@@ -28,15 +28,15 @@ unsigned short risc_code_version = 3*102
 #endif
 
 #ifdef UNIQUE_FW_NAME
-unsigned char fw2322ipx_version_str[] = {3, 3, 8};
+unsigned char fw2322ipx_version_str[] = {3, 3,15};
 #else
-unsigned char firmware_version[] = {3, 3, 8};
+unsigned char firmware_version[] = {3, 3,15};
 #endif
 
 #ifdef UNIQUE_FW_NAME
-#define fw2322ipx_VERSION_STRING "3.03.08"
+#define fw2322ipx_VERSION_STRING "3.03.15"
 #else
-#define FW_VERSION_STRING "3.03.08"
+#define FW_VERSION_STRING "3.03.15"
 #endif
 
 #ifdef UNIQUE_FW_NAME
@@ -50,12 +50,12 @@ unsigned short fw2322ipx_code01[] = { 
 #else
 unsigned short risc_code01[] = { 
 #endif
-	0x0470, 0x0000, 0x0000, 0xe0c2, 0x0000, 0x0003, 0x0003, 0x0008,
+	0x0470, 0x0000, 0x0000, 0xe3bd, 0x0000, 0x0003, 0x0003, 0x000f,
 	0x0137, 0x2043, 0x4f50, 0x5952, 0x4947, 0x4854, 0x2032, 0x3030,
 	0x3120, 0x514c, 0x4f47, 0x4943, 0x2043, 0x4f52, 0x504f, 0x5241,
 	0x5449, 0x4f4e, 0x2049, 0x5350, 0x3233, 0x3030, 0x2046, 0x6972,
 	0x6d77, 0x6172, 0x6520, 0x2056, 0x6572, 0x7369, 0x6f6e, 0x2030,
-	0x332e, 0x3033, 0x2e30, 0x3820, 0x2020, 0x2020, 0x2400, 0x20a9,
+	0x332e, 0x3033, 0x2e31, 0x3520, 0x2020, 0x2020, 0x2400, 0x20a9,
 	0x000f, 0x2001, 0x0000, 0x400f, 0x2091, 0x2200, 0x20a9, 0x000f,
 	0x2001, 0x0000, 0x400f, 0x2091, 0x2400, 0x20a9, 0x000f, 0x2001,
 	0x0000, 0x400f, 0x2091, 0x2600, 0x20a9, 0x000f, 0x2001, 0x0000,
@@ -64,1388 +64,1414 @@ unsigned short risc_code01[] = { 
 	0x2c00, 0x20a9, 0x000f, 0x2001, 0x0000, 0x400f, 0x2091, 0x2e00,
 	0x20a9, 0x000f, 0x2001, 0x0000, 0x400f, 0x2091, 0x2000, 0x2001,
 	0x0000, 0x20c1, 0x0004, 0x20c9, 0x1cff, 0x2059, 0x0000, 0x2b78,
-	0x7883, 0x0004, 0x2089, 0x2b14, 0x2051, 0x1800, 0x2a70, 0x20e1,
-	0x0001, 0x20e9, 0x0001, 0x2009, 0x0000, 0x080c, 0x0e62, 0x00f6,
-	0x7888, 0x9005, 0x11f8, 0x2061, 0xc000, 0x080c, 0x20b0, 0x1170,
-	0x2079, 0x0300, 0x080c, 0x20c6, 0x2061, 0xe000, 0x080c, 0x20b0,
-	0x1128, 0x2079, 0x0380, 0x080c, 0x20c6, 0x0060, 0x00fe, 0x7883,
-	0x4010, 0x7837, 0x4010, 0x7833, 0x0010, 0x2091, 0x5000, 0x2091,
+	0x7883, 0x0004, 0x2089, 0x2be4, 0x2051, 0x1800, 0x2a70, 0x20e1,
+	0x0001, 0x20e9, 0x0001, 0x2009, 0x0000, 0x080c, 0x0e74, 0x00f6,
+	0x7888, 0x9005, 0x11f8, 0x2061, 0xc000, 0x080c, 0x20e7, 0x1170,
+	0x2079, 0x0300, 0x080c, 0x20fd, 0x2061, 0xe000, 0x080c, 0x20e7,
+	0x1128, 0x2079, 0x0380, 0x080c, 0x20fd, 0x0060, 0x00fe, 0x7883,
+	0x4010, 0x7837, 0x4010, 0x7833, 0x0011, 0x2091, 0x5000, 0x2091,
 	0x4080, 0x0cf8, 0x00fe, 0x2029, 0x5600, 0x2031, 0xffff, 0x2039,
 	0x55dc, 0x2021, 0x0200, 0x20e9, 0x0001, 0x20a1, 0x0000, 0x20a9,
 	0x0800, 0x900e, 0x4104, 0x20e9, 0x0001, 0x20a1, 0x1000, 0x900e,
 	0x2001, 0x0dc1, 0x9084, 0x0fff, 0x20a8, 0x4104, 0x2001, 0x0000,
 	0x9086, 0x0000, 0x0120, 0x21a8, 0x4104, 0x8001, 0x1de0, 0x756e,
-	0x7672, 0x776a, 0x7476, 0x747a, 0x00e6, 0x2071, 0x1b50, 0x2472,
+	0x7672, 0x776a, 0x7476, 0x747a, 0x00e6, 0x2071, 0x1b74, 0x2472,
 	0x00ee, 0x20a1, 0x1ddc, 0x7170, 0x810d, 0x810d, 0x810d, 0x810d,
 	0x918c, 0x000f, 0x2001, 0x0001, 0x9112, 0x900e, 0x21a8, 0x4104,
 	0x8211, 0x1de0, 0x7170, 0x3400, 0x8001, 0x9102, 0x0120, 0x0218,
 	0x20a8, 0x900e, 0x4104, 0x2009, 0x1800, 0x810d, 0x810d, 0x810d,
 	0x810d, 0x810d, 0x918c, 0x001f, 0x2001, 0x0001, 0x9112, 0x20e9,
 	0x0001, 0x20a1, 0x0800, 0x900e, 0x20a9, 0x0800, 0x4104, 0x8211,
-	0x1dd8, 0x080c, 0x0f5f, 0x080c, 0x60a0, 0x080c, 0xac46, 0x080c,
-	0x1116, 0x080c, 0x1340, 0x080c, 0x1c06, 0x080c, 0x921f, 0x080c,
-	0x0d0f, 0x080c, 0x109b, 0x080c, 0x34b9, 0x080c, 0x7854, 0x080c,
-	0x6b01, 0x080c, 0x8992, 0x080c, 0x85f3, 0x080c, 0x22a1, 0x080c,
-	0x7f2a, 0x080c, 0x20df, 0x080c, 0x221d, 0x080c, 0x2296, 0x2091,
+	0x1dd8, 0x080c, 0x0f71, 0x080c, 0x618c, 0x080c, 0xaec4, 0x080c,
+	0x1128, 0x080c, 0x1352, 0x080c, 0x1c3d, 0x080c, 0x9393, 0x080c,
+	0x0d17, 0x080c, 0x10ad, 0x080c, 0x3589, 0x080c, 0x79bb, 0x080c,
+	0x6bf9, 0x080c, 0x8afe, 0x080c, 0x875f, 0x080c, 0x22d8, 0x080c,
+	0x8096, 0x080c, 0x2116, 0x080c, 0x2254, 0x080c, 0x22cd, 0x2091,
 	0x3009, 0x7883, 0x0000, 0x1004, 0x0943, 0x7880, 0x9086, 0x0002,
 	0x1190, 0x7883, 0x4000, 0x7837, 0x4000, 0x7833, 0x0010, 0x0e04,
 	0x0937, 0x2091, 0x5000, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004,
-	0xd084, 0x190c, 0x11ee, 0x2071, 0x1800, 0x7003, 0x0000, 0x780c,
-	0x9084, 0x0030, 0x9086, 0x0000, 0x190c, 0x0d7d, 0x2071, 0x1800,
-	0x7000, 0x908e, 0x0003, 0x1168, 0x080c, 0x4c17, 0x080c, 0x34e0,
-	0x080c, 0x78bc, 0x080c, 0x7039, 0x080c, 0x8a75, 0x080c, 0x861c,
+	0xd084, 0x190c, 0x1200, 0x2071, 0x1800, 0x7003, 0x0000, 0x780c,
+	0x9084, 0x0030, 0x9086, 0x0000, 0x190c, 0x0d85, 0x2071, 0x1800,
+	0x7000, 0x908e, 0x0003, 0x1168, 0x080c, 0x4cf3, 0x080c, 0x35b0,
+	0x080c, 0x7a23, 0x080c, 0x717c, 0x080c, 0x8be5, 0x080c, 0x8788,
 	0x0c68, 0x000b, 0x0c88, 0x096d, 0x096e, 0x0b09, 0x096b, 0x0bc3,
-	0x0d0e, 0x0d0e, 0x0d0e, 0x080c, 0x0d7d, 0x0005, 0x0126, 0x00f6,
+	0x0d16, 0x0d16, 0x0d16, 0x080c, 0x0d85, 0x0005, 0x0126, 0x00f6,
 	0x2091, 0x8000, 0x7000, 0x9086, 0x0001, 0x1904, 0x0adc, 0x080c,
-	0x0eb2, 0x080c, 0x753d, 0x0150, 0x080c, 0x7560, 0x15b0, 0x2079,
-	0x0100, 0x7828, 0x9085, 0x1800, 0x782a, 0x0478, 0x080c, 0x746e,
-	0x7000, 0x9086, 0x0001, 0x1904, 0x0adc, 0x7098, 0x9086, 0x0028,
-	0x1904, 0x0adc, 0x080c, 0x85dc, 0x080c, 0x85ce, 0x2001, 0x0161,
-	0x2003, 0x0001, 0x2079, 0x0100, 0x2011, 0xffff, 0x080c, 0x2ab4,
-	0x7a28, 0x9295, 0x5e2c, 0x7a2a, 0x2011, 0x73b3, 0x080c, 0x86c8,
-	0x2011, 0x73a6, 0x080c, 0x87d4, 0x2011, 0x5ef7, 0x080c, 0x86c8,
-	0x2011, 0x8030, 0x901e, 0x7396, 0x04d0, 0x080c, 0x57a4, 0x2079,
-	0x0100, 0x7844, 0x9005, 0x1904, 0x0adc, 0x2011, 0x5ef7, 0x080c,
-	0x86c8, 0x2011, 0x73b3, 0x080c, 0x86c8, 0x2011, 0x73a6, 0x080c,
-	0x87d4, 0x2001, 0x0265, 0x2001, 0x0205, 0x2003, 0x0000, 0x7840,
-	0x9084, 0xfffb, 0x7842, 0x2001, 0x19a5, 0x2004, 0x9005, 0x1140,
-	0x00c6, 0x2061, 0x0100, 0x080c, 0x6048, 0x00ce, 0x0804, 0x0adc,
-	0x780f, 0x006b, 0x7a28, 0x080c, 0x7545, 0x0118, 0x9295, 0x5e2c,
+	0x0ec4, 0x080c, 0x76a5, 0x0150, 0x080c, 0x76c8, 0x15b0, 0x2079,
+	0x0100, 0x7828, 0x9085, 0x1800, 0x782a, 0x0478, 0x080c, 0x75d4,
+	0x7000, 0x9086, 0x0001, 0x1904, 0x0adc, 0x7098, 0x9086, 0x0029,
+	0x1904, 0x0adc, 0x080c, 0x8748, 0x080c, 0x873a, 0x2001, 0x0161,
+	0x2003, 0x0001, 0x2079, 0x0100, 0x2011, 0xffff, 0x080c, 0x2af5,
+	0x7a28, 0x9295, 0x5e2c, 0x7a2a, 0x2011, 0x7519, 0x080c, 0x8834,
+	0x2011, 0x750c, 0x080c, 0x8940, 0x2011, 0x5fe3, 0x080c, 0x8834,
+	0x2011, 0x8030, 0x901e, 0x7396, 0x04d0, 0x080c, 0x5890, 0x2079,
+	0x0100, 0x7844, 0x9005, 0x1904, 0x0adc, 0x2011, 0x5fe3, 0x080c,
+	0x8834, 0x2011, 0x7519, 0x080c, 0x8834, 0x2011, 0x750c, 0x080c,
+	0x8940, 0x2001, 0x0265, 0x2001, 0x0205, 0x2003, 0x0000, 0x7840,
+	0x9084, 0xfffb, 0x7842, 0x2001, 0x19a7, 0x2004, 0x9005, 0x1140,
+	0x00c6, 0x2061, 0x0100, 0x080c, 0x6134, 0x00ce, 0x0804, 0x0adc,
+	0x780f, 0x006b, 0x7a28, 0x080c, 0x76ad, 0x0118, 0x9295, 0x5e2c,
 	0x0010, 0x9295, 0x402c, 0x7a2a, 0x2011, 0x8010, 0x73d8, 0x2001,
-	0x19a6, 0x2003, 0x0001, 0x080c, 0x297c, 0x080c, 0x4b52, 0x7248,
+	0x19a8, 0x2003, 0x0001, 0x080c, 0x29bd, 0x080c, 0x4c2e, 0x7248,
 	0xc284, 0x724a, 0x2001, 0x180c, 0x200c, 0xc1ac, 0xc1cc, 0x2102,
-	0x2001, 0x0390, 0x2003, 0x0400, 0x080c, 0xa91e, 0x080c, 0xa113,
-	0x2011, 0x0004, 0x080c, 0xc98a, 0x080c, 0xa93a, 0x080c, 0x6989,
-	0x080c, 0x753d, 0x1120, 0x080c, 0x29dd, 0x0600, 0x0420, 0x080c,
-	0x604f, 0x0140, 0x7097, 0x0001, 0x70d3, 0x0000, 0x080c, 0x5971,
-	0x0804, 0x0adc, 0x080c, 0x573e, 0xd094, 0x01a8, 0x2001, 0x0390,
-	0x2003, 0x0404, 0x2011, 0x180c, 0x2204, 0xc0cd, 0x2012, 0x080c,
-	0x5742, 0xd0d4, 0x1118, 0x080c, 0x29dd, 0x1270, 0x2011, 0x180c,
-	0x2204, 0xc0bc, 0x00a8, 0x080c, 0x5742, 0xd0d4, 0x1db8, 0x2011,
+	0x2001, 0x0390, 0x2003, 0x0400, 0x080c, 0xaae0, 0x080c, 0xa2db,
+	0x2011, 0x0004, 0x080c, 0xcc26, 0x080c, 0xaafc, 0x080c, 0x6a7f,
+	0x080c, 0x76a5, 0x1120, 0x080c, 0x2a1e, 0x0600, 0x0420, 0x080c,
+	0x613b, 0x0140, 0x7097, 0x0001, 0x70d3, 0x0000, 0x080c, 0x5a5d,
+	0x0804, 0x0adc, 0x2001, 0x0390, 0x2003, 0x0404, 0x080c, 0x5826,
+	0xd094, 0x0188, 0x2011, 0x180c, 0x2204, 0xc0cd, 0x2012, 0x080c,
+	0x582a, 0xd0d4, 0x1118, 0x080c, 0x2a1e, 0x1270, 0x2011, 0x180c,
+	0x2204, 0xc0bc, 0x00a8, 0x080c, 0x582a, 0xd0d4, 0x1db8, 0x2011,
 	0x180c, 0x2204, 0xc0bd, 0x0060, 0x2011, 0x180c, 0x2204, 0xc0bd,
-	0x2012, 0x080c, 0x6ad5, 0x1128, 0xd0a4, 0x0118, 0x2204, 0xc0fd,
-	0x2012, 0x080c, 0x6a9b, 0x0120, 0x7a0c, 0xc2b4, 0x7a0e, 0x00a8,
-	0x707f, 0x0000, 0x080c, 0x753d, 0x1130, 0x70b0, 0x9005, 0x1168,
-	0x080c, 0xcde8, 0x0050, 0x080c, 0xcde8, 0x70dc, 0xd09c, 0x1128,
-	0x70b0, 0x9005, 0x0110, 0x080c, 0x6025, 0x70e7, 0x0000, 0x70e3,
-	0x0000, 0x70a7, 0x0000, 0x080c, 0x29e5, 0x0228, 0x2011, 0x0101,
-	0x2204, 0xc0c4, 0x2012, 0x72dc, 0x080c, 0x753d, 0x1178, 0x9016,
-	0x0016, 0x080c, 0x2779, 0x2019, 0x196c, 0x211a, 0x001e, 0x705f,
-	0xffff, 0x7063, 0x00ef, 0x7083, 0x0000, 0x0020, 0x2019, 0x196c,
+	0x2012, 0x080c, 0x6bcd, 0x1128, 0xd0a4, 0x0118, 0x2204, 0xc0fd,
+	0x2012, 0x080c, 0x6b93, 0x0120, 0x7a0c, 0xc2b4, 0x7a0e, 0x00a8,
+	0x707f, 0x0000, 0x080c, 0x76a5, 0x1130, 0x70b0, 0x9005, 0x1168,
+	0x080c, 0xd084, 0x0050, 0x080c, 0xd084, 0x70dc, 0xd09c, 0x1128,
+	0x70b0, 0x9005, 0x0110, 0x080c, 0x6111, 0x70e7, 0x0000, 0x70e3,
+	0x0000, 0x70a7, 0x0000, 0x080c, 0x2a26, 0x0228, 0x2011, 0x0101,
+	0x2204, 0xc0c4, 0x2012, 0x72dc, 0x080c, 0x76a5, 0x1178, 0x9016,
+	0x0016, 0x080c, 0x27ba, 0x2019, 0x196e, 0x211a, 0x001e, 0x705f,
+	0xffff, 0x7063, 0x00ef, 0x7083, 0x0000, 0x0020, 0x2019, 0x196e,
 	0x201b, 0x0000, 0x2079, 0x1847, 0x7804, 0xd0ac, 0x0108, 0xc295,
-	0x72de, 0x080c, 0x753d, 0x0118, 0x9296, 0x0004, 0x0518, 0x2011,
-	0x0001, 0x080c, 0xc98a, 0x70ab, 0x0000, 0x70af, 0xffff, 0x7003,
-	0x0002, 0x00fe, 0x080c, 0x3011, 0x080c, 0xa91e, 0x2011, 0x0005,
-	0x080c, 0xa243, 0x080c, 0xa93a, 0x080c, 0x753d, 0x0148, 0x00c6,
-	0x2061, 0x0100, 0x0016, 0x080c, 0x2779, 0x61e2, 0x001e, 0x00ce,
+	0x72de, 0x080c, 0x76a5, 0x0118, 0x9296, 0x0004, 0x0518, 0x2011,
+	0x0001, 0x080c, 0xcc26, 0x70ab, 0x0000, 0x70af, 0xffff, 0x7003,
+	0x0002, 0x00fe, 0x080c, 0x30e1, 0x080c, 0xaae0, 0x2011, 0x0005,
+	0x080c, 0xa40f, 0x080c, 0xaafc, 0x080c, 0x76a5, 0x0148, 0x00c6,
+	0x2061, 0x0100, 0x0016, 0x080c, 0x27ba, 0x61e2, 0x001e, 0x00ce,
 	0x012e, 0x00e0, 0x70ab, 0x0000, 0x70af, 0xffff, 0x7003, 0x0002,
-	0x080c, 0xa91e, 0x2011, 0x0005, 0x080c, 0xa243, 0x080c, 0xa93a,
-	0x080c, 0x753d, 0x0148, 0x00c6, 0x2061, 0x0100, 0x0016, 0x080c,
-	0x2779, 0x61e2, 0x001e, 0x00ce, 0x00fe, 0x012e, 0x0005, 0x00c6,
-	0x00b6, 0x080c, 0x753d, 0x1118, 0x20a9, 0x0800, 0x0010, 0x20a9,
-	0x0782, 0x080c, 0x753d, 0x1110, 0x900e, 0x0010, 0x2009, 0x007e,
+	0x080c, 0xaae0, 0x2011, 0x0005, 0x080c, 0xa40f, 0x080c, 0xaafc,
+	0x080c, 0x76a5, 0x0148, 0x00c6, 0x2061, 0x0100, 0x0016, 0x080c,
+	0x27ba, 0x61e2, 0x001e, 0x00ce, 0x00fe, 0x012e, 0x0005, 0x00c6,
+	0x00b6, 0x080c, 0x76a5, 0x1118, 0x20a9, 0x0800, 0x0010, 0x20a9,
+	0x0782, 0x080c, 0x76a5, 0x1110, 0x900e, 0x0010, 0x2009, 0x007e,
 	0x86ff, 0x0138, 0x9180, 0x1000, 0x2004, 0x905d, 0x0110, 0xb800,
-	0xd0bc, 0x090c, 0x3349, 0x8108, 0x1f04, 0x0af0, 0x707f, 0x0000,
+	0xd0bc, 0x090c, 0x3419, 0x8108, 0x1f04, 0x0af0, 0x707f, 0x0000,
 	0x7080, 0x9084, 0x00ff, 0x7082, 0x70b3, 0x0000, 0x00be, 0x00ce,
 	0x0005, 0x00b6, 0x0126, 0x2091, 0x8000, 0x7000, 0x9086, 0x0002,
-	0x1904, 0x0bc0, 0x70ac, 0x9086, 0xffff, 0x0120, 0x080c, 0x3011,
+	0x1904, 0x0bc0, 0x70ac, 0x9086, 0xffff, 0x0120, 0x080c, 0x30e1,
 	0x0804, 0x0bc0, 0x70dc, 0xd0ac, 0x1110, 0xd09c, 0x0538, 0xd084,
 	0x0528, 0x0006, 0x2001, 0x0103, 0x2003, 0x002b, 0x000e, 0xd08c,
-	0x01e8, 0x080c, 0x33b2, 0x11b0, 0x70e0, 0x9086, 0xffff, 0x0190,
-	0x080c, 0x31a6, 0x70dc, 0xd094, 0x1904, 0x0bc0, 0x2011, 0x0001,
-	0x080c, 0xd09b, 0x0110, 0x2011, 0x0003, 0x901e, 0x080c, 0x31e0,
+	0x01e8, 0x080c, 0x3482, 0x11b0, 0x70e0, 0x9086, 0xffff, 0x0190,
+	0x080c, 0x3276, 0x70dc, 0xd094, 0x1904, 0x0bc0, 0x2011, 0x0001,
+	0x080c, 0xd33e, 0x0110, 0x2011, 0x0003, 0x901e, 0x080c, 0x32b0,
 	0x0804, 0x0bc0, 0x70e4, 0x9005, 0x1904, 0x0bc0, 0x70a8, 0x9005,
 	0x1904, 0x0bc0, 0x70dc, 0xd0a4, 0x0118, 0xd0b4, 0x0904, 0x0bc0,
-	0x080c, 0x6a9b, 0x1904, 0x0bc0, 0x080c, 0x6aee, 0x1904, 0x0bc0,
-	0x080c, 0x6ad5, 0x01c0, 0x0156, 0x00c6, 0x20a9, 0x007f, 0x900e,
-	0x0016, 0x080c, 0x6693, 0x1118, 0xb800, 0xd0ec, 0x1138, 0x001e,
+	0x080c, 0x6b93, 0x1904, 0x0bc0, 0x080c, 0x6be6, 0x1904, 0x0bc0,
+	0x080c, 0x6bcd, 0x01c0, 0x0156, 0x00c6, 0x20a9, 0x007f, 0x900e,
+	0x0016, 0x080c, 0x6789, 0x1118, 0xb800, 0xd0ec, 0x1138, 0x001e,
 	0x8108, 0x1f04, 0x0b60, 0x00ce, 0x015e, 0x0028, 0x001e, 0x00ce,
 	0x015e, 0x0804, 0x0bc0, 0x0006, 0x2001, 0x0103, 0x2003, 0x002b,
-	0x000e, 0x2011, 0x19b2, 0x080c, 0x0fcf, 0x2011, 0x19cc, 0x080c,
-	0x0fcf, 0x7030, 0xc08c, 0x7032, 0x7003, 0x0003, 0x70af, 0xffff,
-	0x080c, 0x0e86, 0x9006, 0x080c, 0x2606, 0x080c, 0x33b2, 0x0118,
-	0x080c, 0x4cef, 0x0050, 0x0036, 0x0046, 0x2019, 0xffff, 0x2021,
-	0x0006, 0x080c, 0x4d09, 0x004e, 0x003e, 0x00f6, 0x2079, 0x0100,
-	0x080c, 0x7560, 0x0150, 0x080c, 0x753d, 0x7828, 0x0118, 0x9084,
-	0xe1ff, 0x0010, 0x9084, 0xffdf, 0x782a, 0x00fe, 0x080c, 0xa91e,
-	0x2001, 0x19e7, 0x2004, 0x9086, 0x0005, 0x1120, 0x2011, 0x0000,
-	0x080c, 0xa243, 0x2011, 0x0000, 0x080c, 0xa24d, 0x080c, 0xa93a,
+	0x000e, 0x2011, 0x19b5, 0x080c, 0x0fe1, 0x2011, 0x19cf, 0x080c,
+	0x0fe1, 0x7030, 0xc08c, 0x7032, 0x7003, 0x0003, 0x70af, 0xffff,
+	0x080c, 0x0e98, 0x9006, 0x080c, 0x2647, 0x080c, 0x3482, 0x0118,
+	0x080c, 0x4dcb, 0x0050, 0x0036, 0x0046, 0x2019, 0xffff, 0x2021,
+	0x0006, 0x080c, 0x4de5, 0x004e, 0x003e, 0x00f6, 0x2079, 0x0100,
+	0x080c, 0x76c8, 0x0150, 0x080c, 0x76a5, 0x7828, 0x0118, 0x9084,
+	0xe1ff, 0x0010, 0x9084, 0xffdf, 0x782a, 0x00fe, 0x080c, 0xaae0,
+	0x2001, 0x19ea, 0x2004, 0x9086, 0x0005, 0x1120, 0x2011, 0x0000,
+	0x080c, 0xa40f, 0x2011, 0x0000, 0x080c, 0xa419, 0x080c, 0xaafc,
 	0x012e, 0x00be, 0x0005, 0x0016, 0x0026, 0x0046, 0x00f6, 0x0126,
 	0x2091, 0x8000, 0x2079, 0x0100, 0x7904, 0x918c, 0xfffd, 0x7906,
-	0x2009, 0x00f7, 0x080c, 0x600e, 0x7940, 0x918c, 0x0010, 0x7942,
-	0x7924, 0xd1b4, 0x0120, 0x2011, 0x0040, 0x080c, 0x2ab4, 0xd19c,
-	0x0120, 0x2011, 0x0008, 0x080c, 0x2ab4, 0x0006, 0x0036, 0x0156,
-	0x0000, 0x2001, 0x19a6, 0x2004, 0x9005, 0x1518, 0x080c, 0x2a48,
-	0x1148, 0x2001, 0x0001, 0x080c, 0x29ab, 0x2001, 0x0001, 0x080c,
-	0x298e, 0x00b8, 0x080c, 0x2a50, 0x1138, 0x9006, 0x080c, 0x29ab,
-	0x9006, 0x080c, 0x298e, 0x0068, 0x080c, 0x2a58, 0x1d50, 0x2001,
-	0x1997, 0x2004, 0xd0fc, 0x0108, 0x0020, 0x080c, 0x27a5, 0x0804,
-	0x0cc1, 0x080c, 0x2ad7, 0x080c, 0x2b0a, 0x20a9, 0x003a, 0x1d04,
-	0x0c17, 0x080c, 0x87b4, 0x1f04, 0x0c17, 0x080c, 0x754e, 0x0148,
-	0x080c, 0x7560, 0x1118, 0x080c, 0x784f, 0x0050, 0x080c, 0x7545,
-	0x0dd0, 0x080c, 0x784a, 0x080c, 0x7840, 0x080c, 0x746e, 0x0020,
-	0x2009, 0x00f8, 0x080c, 0x600e, 0x7850, 0xc0e5, 0x7852, 0x080c,
-	0x753d, 0x0120, 0x7843, 0x0090, 0x7843, 0x0010, 0x2021, 0xe678,
-	0x2019, 0xea60, 0x0d0c, 0x87b4, 0x7820, 0xd09c, 0x15a0, 0x080c,
-	0x753d, 0x0904, 0x0ca3, 0x7824, 0xd0ac, 0x1904, 0x0cc6, 0x080c,
-	0x7560, 0x1548, 0x0046, 0x2021, 0x0320, 0x8421, 0x1df0, 0x004e,
-	0x2011, 0x1800, 0x080c, 0x2ab4, 0x080c, 0x2a60, 0x7824, 0x9084,
+	0x2009, 0x00f7, 0x080c, 0x60fa, 0x7940, 0x918c, 0x0010, 0x7942,
+	0x7924, 0xd1b4, 0x0120, 0x2011, 0x0040, 0x080c, 0x2af5, 0xd19c,
+	0x0120, 0x2011, 0x0008, 0x080c, 0x2af5, 0x0006, 0x0036, 0x0156,
+	0x0000, 0x2001, 0x19a8, 0x2004, 0x9005, 0x1518, 0x080c, 0x2a89,
+	0x1148, 0x2001, 0x0001, 0x080c, 0x29ec, 0x2001, 0x0001, 0x080c,
+	0x29cf, 0x00b8, 0x080c, 0x2a91, 0x1138, 0x9006, 0x080c, 0x29ec,
+	0x9006, 0x080c, 0x29cf, 0x0068, 0x080c, 0x2a99, 0x1d50, 0x2001,
+	0x1999, 0x2004, 0xd0fc, 0x0108, 0x0020, 0x080c, 0x27e6, 0x0804,
+	0x0cc9, 0x2009, 0x19b1, 0x2104, 0x8000, 0x200a, 0x9084, 0x0001,
+	0x0120, 0x080c, 0x2b18, 0x080c, 0x2b4b, 0x20a9, 0x003a, 0x1d04,
+	0x0c1f, 0x080c, 0x8920, 0x1f04, 0x0c1f, 0x080c, 0x76b6, 0x0148,
+	0x080c, 0x76c8, 0x1118, 0x080c, 0x79b6, 0x0050, 0x080c, 0x76ad,
+	0x0dd0, 0x080c, 0x79b1, 0x080c, 0x79a7, 0x080c, 0x75d4, 0x0020,
+	0x2009, 0x00f8, 0x080c, 0x60fa, 0x7850, 0xc0e5, 0x7852, 0x080c,
+	0x76a5, 0x0120, 0x7843, 0x0090, 0x7843, 0x0010, 0x2021, 0xe678,
+	0x2019, 0xea60, 0x0d0c, 0x8920, 0x7820, 0xd09c, 0x15a0, 0x080c,
+	0x76a5, 0x0904, 0x0cab, 0x7824, 0xd0ac, 0x1904, 0x0cce, 0x080c,
+	0x76c8, 0x1548, 0x0046, 0x2021, 0x0320, 0x8421, 0x1df0, 0x004e,
+	0x2011, 0x1800, 0x080c, 0x2af5, 0x080c, 0x2aa1, 0x7824, 0x9084,
 	0x1800, 0x1168, 0x9484, 0x0fff, 0x1140, 0x2001, 0x1810, 0x2004,
-	0x9084, 0x9000, 0x0110, 0x080c, 0x0ce9, 0x8421, 0x1160, 0x1d04,
-	0x0c73, 0x080c, 0x87b4, 0x080c, 0x784a, 0x080c, 0x7840, 0x7003,
-	0x0001, 0x0804, 0x0cc6, 0x8319, 0x1928, 0x2001, 0x1810, 0x2004,
-	0x9084, 0x9000, 0x0110, 0x080c, 0x0ce9, 0x1d04, 0x0c89, 0x080c,
-	0x87b4, 0x2009, 0x199a, 0x2104, 0x9005, 0x0118, 0x8001, 0x200a,
-	0x1188, 0x200b, 0x000a, 0x2011, 0x0048, 0x080c, 0x2ab4, 0x20a9,
-	0x0002, 0x080c, 0x2a41, 0x7924, 0x080c, 0x2a60, 0xd19c, 0x0110,
-	0x080c, 0x297c, 0x00f0, 0x080c, 0x754e, 0x1140, 0x94a2, 0x03e8,
-	0x1128, 0x080c, 0x7511, 0x7003, 0x0001, 0x00c0, 0x2011, 0x1800,
-	0x080c, 0x2ab4, 0x080c, 0x2a60, 0x7824, 0x080c, 0x7557, 0x0110,
-	0xd0ac, 0x1160, 0x9084, 0x1800, 0x0904, 0x0c7b, 0x7003, 0x0001,
-	0x0028, 0x2001, 0x0001, 0x080c, 0x2606, 0x00a0, 0x7850, 0xc0e4,
+	0x9084, 0x9000, 0x0110, 0x080c, 0x0cf1, 0x8421, 0x1160, 0x1d04,
+	0x0c7b, 0x080c, 0x8920, 0x080c, 0x79b1, 0x080c, 0x79a7, 0x7003,
+	0x0001, 0x0804, 0x0cce, 0x8319, 0x1928, 0x2001, 0x1810, 0x2004,
+	0x9084, 0x9000, 0x0110, 0x080c, 0x0cf1, 0x1d04, 0x0c91, 0x080c,
+	0x8920, 0x2009, 0x199c, 0x2104, 0x9005, 0x0118, 0x8001, 0x200a,
+	0x1188, 0x200b, 0x000a, 0x2011, 0x0048, 0x080c, 0x2af5, 0x20a9,
+	0x0002, 0x080c, 0x2a82, 0x7924, 0x080c, 0x2aa1, 0xd19c, 0x0110,
+	0x080c, 0x29bd, 0x00f0, 0x080c, 0x76b6, 0x1140, 0x94a2, 0x03e8,
+	0x1128, 0x080c, 0x7679, 0x7003, 0x0001, 0x00c0, 0x2011, 0x1800,
+	0x080c, 0x2af5, 0x080c, 0x2aa1, 0x7824, 0x080c, 0x76bf, 0x0110,
+	0xd0ac, 0x1160, 0x9084, 0x1800, 0x0904, 0x0c83, 0x7003, 0x0001,
+	0x0028, 0x2001, 0x0001, 0x080c, 0x2647, 0x00a0, 0x7850, 0xc0e4,
 	0x7852, 0x2009, 0x180c, 0x210c, 0xd19c, 0x1120, 0x7904, 0x918d,
-	0x0002, 0x7906, 0x2011, 0x0048, 0x080c, 0x2ab4, 0x7828, 0x9085,
-	0x0028, 0x782a, 0x2001, 0x19a6, 0x2003, 0x0000, 0x9006, 0x78f2,
+	0x0002, 0x7906, 0x2011, 0x0048, 0x080c, 0x2af5, 0x7828, 0x9085,
+	0x0028, 0x782a, 0x2001, 0x19a8, 0x2003, 0x0000, 0x9006, 0x78f2,
 	0x015e, 0x003e, 0x000e, 0x012e, 0x00fe, 0x004e, 0x002e, 0x001e,
 	0x0005, 0x0006, 0x0016, 0x0026, 0x0036, 0x0046, 0x00b6, 0x00c6,
-	0x00d6, 0x00e6, 0x00f6, 0x0156, 0x0071, 0x0d0c, 0x87b4, 0x015e,
+	0x00d6, 0x00e6, 0x00f6, 0x0156, 0x0071, 0x0d0c, 0x8920, 0x015e,
 	0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x004e, 0x003e, 0x002e,
 	0x001e, 0x000e, 0x0005, 0x00e6, 0x2071, 0x189e, 0x7004, 0x9086,
-	0x0001, 0x1110, 0x080c, 0x34e0, 0x00ee, 0x0005, 0x0005, 0x2a70,
-	0x2061, 0x19aa, 0x2063, 0x0003, 0x6007, 0x0003, 0x600b, 0x0008,
-	0x600f, 0x0137, 0x2001, 0x197b, 0x900e, 0x2102, 0x7196, 0x2001,
+	0x0001, 0x1110, 0x080c, 0x35b0, 0x00ee, 0x0005, 0x0005, 0x2a70,
+	0x2061, 0x19ac, 0x2063, 0x0003, 0x6007, 0x0003, 0x600b, 0x000f,
+	0x600f, 0x0137, 0x2001, 0x197d, 0x900e, 0x2102, 0x7196, 0x2001,
 	0x0100, 0x2004, 0x9082, 0x0002, 0x0218, 0x705f, 0xffff, 0x0008,
-	0x715e, 0x7067, 0xffff, 0x717e, 0x7182, 0x080c, 0xcde8, 0x70ef,
-	0x00c0, 0x2061, 0x196b, 0x6003, 0x0909, 0x6106, 0x600b, 0x8800,
+	0x715e, 0x7067, 0xffff, 0x717e, 0x7182, 0x080c, 0xd084, 0x70ef,
+	0x00c0, 0x2061, 0x196d, 0x6003, 0x0909, 0x6106, 0x600b, 0x8800,
 	0x600f, 0x0200, 0x6013, 0x00ff, 0x6017, 0x001f, 0x611a, 0x601f,
-	0x07d0, 0x2061, 0x1973, 0x6003, 0x8000, 0x6106, 0x610a, 0x600f,
+	0x07d0, 0x2061, 0x1975, 0x6003, 0x8000, 0x6106, 0x610a, 0x600f,
 	0x0200, 0x6013, 0x00ff, 0x6116, 0x601b, 0x0001, 0x611e, 0x2061,
-	0x1988, 0x6003, 0x514c, 0x6007, 0x4f47, 0x600b, 0x4943, 0x600f,
-	0x2020, 0x2001, 0x182c, 0x2102, 0x0005, 0x9016, 0x080c, 0x6693,
+	0x198a, 0x6003, 0x514c, 0x6007, 0x4f47, 0x600b, 0x4943, 0x600f,
+	0x2020, 0x2001, 0x182c, 0x2102, 0x0005, 0x9016, 0x080c, 0x6789,
 	0x1178, 0xb804, 0x90c4, 0x00ff, 0x98c6, 0x0006, 0x0128, 0x90c4,
 	0xff00, 0x98c6, 0x0600, 0x1120, 0x9186, 0x0080, 0x0108, 0x8210,
 	0x8108, 0x9186, 0x0800, 0x1d50, 0x2208, 0x0005, 0x2091, 0x8000,
 	0x2079, 0x0000, 0x000e, 0x00f6, 0x0010, 0x2091, 0x8000, 0x0e04,
-	0x0d7f, 0x0006, 0x0016, 0x2001, 0x8002, 0x0006, 0x2079, 0x0000,
+	0x0d87, 0x0006, 0x0016, 0x2001, 0x8002, 0x0006, 0x2079, 0x0000,
 	0x000e, 0x7882, 0x7836, 0x001e, 0x798e, 0x000e, 0x788a, 0x000e,
-	0x7886, 0x3900, 0x789a, 0x7833, 0x0012, 0x2091, 0x5000, 0x0156,
-	0x00d6, 0x0036, 0x0026, 0x2079, 0x0300, 0x2069, 0x1b26, 0x7a08,
-	0x226a, 0x2069, 0x1b27, 0x7a18, 0x226a, 0x8d68, 0x7a1c, 0x226a,
-	0x782c, 0x2019, 0x1b34, 0x201a, 0x2019, 0x1b37, 0x9016, 0x7808,
-	0xd09c, 0x0168, 0x7820, 0x201a, 0x8210, 0x8318, 0x9386, 0x1b50,
-	0x0108, 0x0ca8, 0x7808, 0xd09c, 0x0110, 0x2011, 0xdead, 0x2019,
-	0x1b35, 0x782c, 0x201a, 0x8318, 0x221a, 0x7803, 0x0000, 0x2069,
-	0x1a7c, 0x901e, 0x20a9, 0x0020, 0x7b26, 0x7a28, 0x226a, 0x8d68,
-	0x8318, 0x1f04, 0x0dcc, 0x2069, 0x1a9c, 0x2019, 0x0050, 0x20a9,
-	0x0020, 0x7b26, 0x7a28, 0x226a, 0x8d68, 0x8318, 0x1f04, 0x0dd9,
-	0x0491, 0x002e, 0x003e, 0x00de, 0x015e, 0x2079, 0x1800, 0x7803,
-	0x0005, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x0180,
-	0x2001, 0x1a21, 0x2004, 0x9005, 0x0128, 0x2001, 0x008b, 0x2004,
-	0xd0fc, 0x0dd8, 0x2001, 0x008a, 0x2003, 0x0002, 0x2003, 0x1001,
-	0x080c, 0x574d, 0x1170, 0x080c, 0x0f20, 0x0110, 0x080c, 0x0e73,
-	0x080c, 0x574d, 0x1130, 0x2071, 0x1800, 0x2011, 0x8000, 0x080c,
-	0x0f34, 0x0c70, 0x0005, 0x2001, 0x0382, 0x2004, 0x9084, 0x0007,
-	0x9086, 0x0001, 0x1120, 0x2001, 0x0015, 0x080c, 0xa90f, 0x2079,
-	0x0380, 0x2069, 0x1b06, 0x7818, 0x6802, 0x781c, 0x6806, 0x7840,
-	0x680a, 0x7844, 0x680e, 0x782c, 0x6812, 0x2019, 0x1b11, 0x9016,
-	0x7808, 0xd09c, 0x0150, 0x7820, 0x201a, 0x8210, 0x8318, 0x8210,
-	0x9282, 0x0011, 0x0ea8, 0x2011, 0xdead, 0x6a2a, 0x7830, 0x681a,
-	0x7834, 0x681e, 0x7838, 0x6822, 0x783c, 0x6826, 0x7803, 0x0000,
-	0x2069, 0x1ac6, 0x901e, 0x20a9, 0x0020, 0x7b26, 0x7828, 0x206a,
-	0x8d68, 0x8318, 0x1f04, 0x0e4d, 0x2069, 0x1ae6, 0x2019, 0x00b0,
-	0x20a9, 0x0020, 0x7b26, 0x7828, 0x206a, 0x8d68, 0x8318, 0x1f04,
-	0x0e5a, 0x0005, 0x918c, 0x03ff, 0x2001, 0x0003, 0x2004, 0x9084,
-	0x0600, 0x1118, 0x918d, 0x6c00, 0x0010, 0x918d, 0x6400, 0x2001,
-	0x017f, 0x2102, 0x0005, 0x0026, 0x0126, 0x2011, 0x0080, 0x080c,
-	0x0f12, 0x20a9, 0x0900, 0x080c, 0x0f48, 0x2011, 0x0040, 0x080c,
-	0x0f12, 0x20a9, 0x0900, 0x080c, 0x0f48, 0x0c78, 0x0026, 0x080c,
-	0x0f20, 0x1188, 0x2011, 0x010e, 0x2214, 0x9294, 0x0007, 0x9296,
-	0x0007, 0x0118, 0x2011, 0x0947, 0x0010, 0x2011, 0x1b47, 0x080c,
-	0x0f34, 0x002e, 0x0005, 0x2011, 0x010e, 0x2214, 0x9294, 0x0007,
-	0x9296, 0x0007, 0x0118, 0x2011, 0xa880, 0x0010, 0x2011, 0x6840,
-	0xd0e4, 0x70f3, 0x0000, 0x1120, 0x70f3, 0x0fa0, 0x080c, 0x0f25,
-	0x002e, 0x0005, 0x0026, 0x080c, 0x0f20, 0x0148, 0xd0a4, 0x1138,
-	0x2011, 0xcdd5, 0x0010, 0x2011, 0x0080, 0x080c, 0x0f25, 0x002e,
-	0x0005, 0x0026, 0x70f3, 0x0000, 0x080c, 0x0f20, 0x1130, 0x2011,
-	0x8040, 0x080c, 0x0f34, 0x002e, 0x0005, 0x080c, 0x2a58, 0x1118,
-	0x2011, 0xcdc5, 0x0010, 0x2011, 0xcac2, 0x080c, 0x0f25, 0x002e,
-	0x0005, 0x00e6, 0x0016, 0x0006, 0x2071, 0x1800, 0xd0b4, 0x70ec,
-	0x71e8, 0x1118, 0xc0e4, 0xc1f4, 0x0050, 0x0006, 0x3b00, 0x9084,
-	0xff3e, 0x20d8, 0x000e, 0x70f3, 0x0000, 0xc0e5, 0xc1f5, 0x0099,
-	0x000e, 0x001e, 0x00ee, 0x0005, 0x00e6, 0x2071, 0x1800, 0xd0e4,
-	0x70ec, 0x1110, 0xc0dc, 0x0008, 0xc0dd, 0x0016, 0x71e8, 0x0019,
-	0x001e, 0x00ee, 0x0005, 0x70ee, 0x71ea, 0x7000, 0x9084, 0x0007,
-	0x000b, 0x0005, 0x0ed8, 0x0eb2, 0x0eb2, 0x0e86, 0x0ec1, 0x0eb2,
-	0x0eb2, 0x0ec1, 0xc284, 0x0016, 0x3b08, 0x3a00, 0x9104, 0x918d,
-	0x00c1, 0x21d8, 0x9084, 0xff3e, 0x9205, 0x20d0, 0x001e, 0x0005,
-	0x2001, 0x183b, 0x2004, 0xd0dc, 0x0005, 0x9e86, 0x1800, 0x190c,
-	0x0d7d, 0x70ec, 0xd0e4, 0x0108, 0xc2e5, 0x72ee, 0xd0e4, 0x1118,
-	0x9294, 0x00c1, 0x08f9, 0x0005, 0x9e86, 0x1800, 0x190c, 0x0d7d,
-	0x70e8, 0xd0f4, 0x0108, 0xc2f5, 0x72ea, 0xd0f4, 0x1140, 0x9284,
-	0x8000, 0x8005, 0xc284, 0x9215, 0x9294, 0x00c1, 0x0861, 0x0005,
-	0x1d04, 0x0f48, 0x2091, 0x6000, 0x1f04, 0x0f48, 0x0005, 0x890e,
-	0x810e, 0x810f, 0x9194, 0x003f, 0x918c, 0xffc0, 0x0005, 0x0006,
-	0x2200, 0x914d, 0x894f, 0x894d, 0x894d, 0x000e, 0x0005, 0x01d6,
-	0x0146, 0x0036, 0x0096, 0x2061, 0x188d, 0x600b, 0x0000, 0x600f,
-	0x0000, 0x6003, 0x0000, 0x6007, 0x0000, 0x2009, 0xffc0, 0x2105,
-	0x0006, 0x2001, 0xaaaa, 0x200f, 0x2019, 0x5555, 0x9016, 0x2049,
-	0x0bff, 0xab02, 0xa001, 0xa001, 0xa800, 0x9306, 0x1138, 0x2105,
-	0x9306, 0x0120, 0x8210, 0x99c8, 0x0400, 0x0c98, 0x000e, 0x200f,
-	0x2001, 0x189d, 0x928a, 0x000e, 0x1638, 0x928a, 0x0006, 0x2011,
-	0x0006, 0x1210, 0x2011, 0x0000, 0x2202, 0x9006, 0x2008, 0x82ff,
-	0x01b0, 0x8200, 0x600a, 0x600f, 0xffff, 0x6003, 0x0002, 0x6007,
-	0x0000, 0x0026, 0x2019, 0x0010, 0x9280, 0x0001, 0x20e8, 0x21a0,
-	0x21a8, 0x4104, 0x8319, 0x1de0, 0x8211, 0x1da0, 0x002e, 0x009e,
-	0x003e, 0x014e, 0x01de, 0x0005, 0x2011, 0x000e, 0x08e8, 0x0016,
-	0x0026, 0x0096, 0x3348, 0x080c, 0x0f4f, 0x2100, 0x9300, 0x2098,
-	0x22e0, 0x009e, 0x002e, 0x001e, 0x0036, 0x3518, 0x20a9, 0x0001,
-	0x4002, 0x8007, 0x4004, 0x8319, 0x1dd8, 0x003e, 0x0005, 0x20e9,
-	0x0001, 0x71b8, 0x81ff, 0x11c0, 0x9006, 0x2009, 0x0200, 0x20a9,
-	0x0002, 0x9298, 0x0018, 0x23a0, 0x4001, 0x2009, 0x0700, 0x20a9,
-	0x0002, 0x9298, 0x0008, 0x23a0, 0x4001, 0x707c, 0x8007, 0x7180,
-	0x810f, 0x20a9, 0x0002, 0x4001, 0x9298, 0x000c, 0x23a0, 0x900e,
-	0x080c, 0x0d5d, 0x2001, 0x0000, 0x810f, 0x20a9, 0x0002, 0x4001,
-	0x0005, 0x89ff, 0x0140, 0xa804, 0xa807, 0x0000, 0x0006, 0x080c,
-	0x1079, 0x009e, 0x0cb0, 0x0005, 0x00e6, 0x2071, 0x1800, 0x080c,
-	0x10f2, 0x090c, 0x0d7d, 0x00ee, 0x0005, 0x0086, 0x00e6, 0x0006,
-	0x0026, 0x0036, 0x0126, 0x2091, 0x8000, 0x00c9, 0x2071, 0x1800,
-	0x73c0, 0x702c, 0x9016, 0x9045, 0x0158, 0x8210, 0x9906, 0x090c,
-	0x0d7d, 0x2300, 0x9202, 0x0120, 0x1a0c, 0x0d7d, 0xa000, 0x0c98,
-	0x012e, 0x003e, 0x002e, 0x000e, 0x00ee, 0x008e, 0x0005, 0x0086,
-	0x00e6, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x1910, 0x7010,
-	0x9005, 0x0140, 0x7018, 0x9045, 0x0128, 0x9906, 0x090c, 0x0d7d,
-	0xa000, 0x0cc8, 0x012e, 0x000e, 0x00ee, 0x008e, 0x0005, 0x00e6,
-	0x2071, 0x1800, 0x0126, 0x2091, 0x8000, 0x70c0, 0x8001, 0x0270,
-	0x70c2, 0x702c, 0x2048, 0x9085, 0x0001, 0xa800, 0x702e, 0xa803,
-	0x0000, 0xa807, 0x0000, 0x012e, 0x00ee, 0x0005, 0x904e, 0x0cd8,
-	0x00e6, 0x0126, 0x2091, 0x8000, 0x2071, 0x1800, 0x70c0, 0x90ca,
-	0x0020, 0x0268, 0x8001, 0x70c2, 0x702c, 0x2048, 0xa800, 0x702e,
-	0xa803, 0x0000, 0xa807, 0x0000, 0x012e, 0x00ee, 0x0005, 0x904e,
-	0x0cd8, 0x00e6, 0x0126, 0x2091, 0x8000, 0x0016, 0x890e, 0x810e,
-	0x810f, 0x9184, 0x003f, 0xa862, 0x9184, 0xffc0, 0xa85e, 0x001e,
-	0x0020, 0x00e6, 0x0126, 0x2091, 0x8000, 0x2071, 0x1800, 0x702c,
-	0xa802, 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c, 0x85ce,
-	0x012e, 0x00ee, 0x0005, 0x2071, 0x1800, 0x9026, 0x2009, 0x0000,
-	0x2049, 0x0400, 0x2900, 0x702e, 0x8940, 0x2800, 0xa802, 0xa95e,
-	0xa863, 0x0001, 0x8420, 0x9886, 0x0440, 0x0120, 0x2848, 0x9188,
-	0x0040, 0x0c90, 0x2071, 0x188d, 0x7000, 0x9005, 0x11a0, 0x2001,
-	0x0558, 0xa802, 0x2048, 0x2009, 0x5600, 0x8940, 0x2800, 0xa802,
-	0xa95e, 0xa863, 0x0001, 0x8420, 0x9886, 0x0800, 0x0120, 0x2848,
-	0x9188, 0x0040, 0x0c90, 0x2071, 0x188d, 0x7104, 0x7200, 0x82ff,
-	0x01d0, 0x7308, 0x8318, 0x831f, 0x831b, 0x831b, 0x7312, 0x8319,
-	0x2001, 0x0800, 0xa802, 0x2048, 0x8900, 0xa802, 0x2040, 0xa95e,
-	0xaa62, 0x8420, 0x2300, 0x9906, 0x0130, 0x2848, 0x9188, 0x0040,
-	0x9291, 0x0000, 0x0c88, 0xa803, 0x0000, 0x2071, 0x1800, 0x74be,
-	0x74c2, 0x0005, 0x00e6, 0x0016, 0x9984, 0xfc00, 0x01e8, 0x908c,
-	0xf800, 0x1168, 0x9982, 0x0400, 0x02b8, 0x9982, 0x0440, 0x0278,
-	0x9982, 0x0558, 0x0288, 0x9982, 0x0800, 0x1270, 0x0040, 0x9982,
-	0x0800, 0x0250, 0x2071, 0x188d, 0x7010, 0x9902, 0x1228, 0x9085,
-	0x0001, 0x001e, 0x00ee, 0x0005, 0x9006, 0x0cd8, 0x00e6, 0x2071,
-	0x1a20, 0x7007, 0x0000, 0x9006, 0x701e, 0x7022, 0x7002, 0x2071,
-	0x0000, 0x7010, 0x9085, 0x8044, 0x7012, 0x2071, 0x0080, 0x9006,
-	0x702b, 0x0060, 0x20a9, 0x0040, 0x7022, 0x1f04, 0x112c, 0x702b,
-	0x0060, 0x702b, 0x0020, 0x20a9, 0x0040, 0x7022, 0x1f04, 0x1135,
-	0x702b, 0x0020, 0x00ee, 0x0005, 0x0126, 0x2091, 0x8000, 0x00e6,
-	0xa06f, 0x0000, 0x2071, 0x1a20, 0x701c, 0x9088, 0x1a2a, 0x280a,
-	0x8000, 0x9084, 0x003f, 0x701e, 0x7120, 0x9106, 0x090c, 0x0d7d,
-	0x7004, 0x9005, 0x1128, 0x00f6, 0x2079, 0x0080, 0x00a9, 0x00fe,
-	0x00ee, 0x012e, 0x0005, 0x0126, 0x2091, 0x8000, 0x00e6, 0x2071,
-	0x1a20, 0x7004, 0x9005, 0x1128, 0x00f6, 0x2079, 0x0080, 0x0021,
-	0x00fe, 0x00ee, 0x012e, 0x0005, 0x7004, 0x9086, 0x0000, 0x1110,
-	0x7007, 0x0006, 0x7000, 0x0002, 0x117e, 0x1301, 0x117c, 0x117c,
-	0x12f5, 0x12f5, 0x12f5, 0x12f5, 0x080c, 0x0d7d, 0x701c, 0x7120,
-	0x9106, 0x1148, 0x792c, 0x9184, 0x0001, 0x1120, 0xd1fc, 0x1110,
-	0x7007, 0x0000, 0x0005, 0x0096, 0x9180, 0x1a2a, 0x2004, 0x700a,
-	0x2048, 0x8108, 0x918c, 0x003f, 0x7122, 0x782b, 0x0026, 0xa88c,
-	0x7802, 0xa890, 0x7806, 0xa894, 0x780a, 0xa898, 0x780e, 0xa878,
-	0x700e, 0xa870, 0x7016, 0xa874, 0x701a, 0xa868, 0x009e, 0xd084,
-	0x0120, 0x7007, 0x0001, 0x0029, 0x0005, 0x7007, 0x0002, 0x00b1,
-	0x0005, 0x0016, 0x0026, 0x710c, 0x2011, 0x0040, 0x9182, 0x0040,
-	0x1210, 0x2110, 0x9006, 0x700e, 0x7212, 0x8203, 0x7812, 0x782b,
-	0x0020, 0x782b, 0x0041, 0x002e, 0x001e, 0x0005, 0x0016, 0x0026,
-	0x0136, 0x0146, 0x0156, 0x7014, 0x20e0, 0x7018, 0x2098, 0x20e9,
-	0x0000, 0x20a1, 0x0088, 0x782b, 0x0026, 0x710c, 0x2011, 0x0040,
-	0x9182, 0x0040, 0x1210, 0x2110, 0x9006, 0x700e, 0x22a8, 0x4006,
-	0x8203, 0x7812, 0x782b, 0x0020, 0x3300, 0x701a, 0x782b, 0x0001,
-	0x015e, 0x014e, 0x013e, 0x002e, 0x001e, 0x0005, 0x2009, 0x1a20,
-	0x2104, 0xc095, 0x200a, 0x080c, 0x115b, 0x0005, 0x0016, 0x00e6,
-	0x2071, 0x1a20, 0x00f6, 0x2079, 0x0080, 0x792c, 0xd1bc, 0x190c,
-	0x0d76, 0x782b, 0x0002, 0xd1fc, 0x0120, 0x918c, 0x0700, 0x7004,
-	0x0023, 0x00fe, 0x00ee, 0x001e, 0x0005, 0x116c, 0x1214, 0x1248,
-	0x1320, 0x0d7d, 0x133b, 0x0d7d, 0x918c, 0x0700, 0x1550, 0x0136,
-	0x0146, 0x0156, 0x7014, 0x20e8, 0x7018, 0x20a0, 0x20e1, 0x0000,
-	0x2099, 0x0088, 0x782b, 0x0040, 0x7010, 0x20a8, 0x4005, 0x3400,
-	0x701a, 0x015e, 0x014e, 0x013e, 0x700c, 0x9005, 0x0578, 0x7800,
-	0x7802, 0x7804, 0x7806, 0x080c, 0x11b1, 0x0005, 0x7008, 0x0096,
-	0x2048, 0xa86f, 0x0100, 0x009e, 0x7007, 0x0000, 0x080c, 0x116c,
-	0x0005, 0x7008, 0x0096, 0x2048, 0xa86f, 0x0200, 0x009e, 0x0ca0,
-	0x918c, 0x0700, 0x1150, 0x700c, 0x9005, 0x0180, 0x7800, 0x7802,
-	0x7804, 0x7806, 0x080c, 0x11c6, 0x0005, 0x7008, 0x0096, 0x2048,
-	0xa86f, 0x0200, 0x009e, 0x7007, 0x0000, 0x0080, 0x0096, 0x7008,
-	0x2048, 0x7800, 0xa88e, 0x7804, 0xa892, 0x7808, 0xa896, 0x780c,
-	0xa89a, 0xa86f, 0x0100, 0x009e, 0x7007, 0x0000, 0x0096, 0x00d6,
-	0x7008, 0x2048, 0x2001, 0x18b9, 0x2004, 0x9906, 0x1128, 0xa89c,
-	0x080f, 0x00de, 0x009e, 0x00a0, 0x00de, 0x009e, 0x0096, 0x00d6,
-	0x7008, 0x2048, 0x0081, 0x0150, 0xa89c, 0x0086, 0x2940, 0x080f,
-	0x008e, 0x00de, 0x009e, 0x080c, 0x115b, 0x0005, 0x00de, 0x009e,
-	0x080c, 0x115b, 0x0005, 0xa8a8, 0xd08c, 0x0005, 0x0096, 0xa0a0,
-	0x904d, 0x090c, 0x0d7d, 0xa06c, 0x908e, 0x0100, 0x0130, 0xa87b,
-	0x0030, 0xa883, 0x0000, 0xa897, 0x4002, 0x080c, 0x6de2, 0xa09f,
-	0x0000, 0xa0a3, 0x0000, 0x2848, 0x080c, 0x1079, 0x009e, 0x0005,
-	0x00a6, 0xa0a0, 0x904d, 0x090c, 0x0d7d, 0xa06c, 0x908e, 0x0100,
-	0x0128, 0xa87b, 0x0001, 0xa883, 0x0000, 0x00c0, 0xa80c, 0x2050,
-	0xb004, 0x9005, 0x0198, 0xa80e, 0x2050, 0x8006, 0x8006, 0x8007,
-	0x908c, 0x003f, 0x9084, 0xffc0, 0x9080, 0x0002, 0xa076, 0xa172,
-	0xb000, 0xa07a, 0x2810, 0x080c, 0x113c, 0x00e8, 0xa97c, 0xa894,
-	0x0016, 0x0006, 0x080c, 0x6de2, 0x000e, 0x001e, 0xd1fc, 0x1138,
-	0xd1f4, 0x0128, 0x00c6, 0x2060, 0x080c, 0xacb0, 0x00ce, 0x7008,
-	0x2048, 0xa89f, 0x0000, 0xa8a3, 0x0000, 0x080c, 0x1079, 0x7007,
-	0x0000, 0x080c, 0x115b, 0x00ae, 0x0005, 0x0126, 0x2091, 0x8000,
-	0x782b, 0x1001, 0x7007, 0x0005, 0x7000, 0xc094, 0x7002, 0x012e,
-	0x0005, 0x0096, 0x2001, 0x192e, 0x204c, 0xa87c, 0x7812, 0xa88c,
-	0x7802, 0xa890, 0x7806, 0xa894, 0x780a, 0xa898, 0x780e, 0x782b,
-	0x0020, 0x0126, 0x2091, 0x8000, 0x782b, 0x0041, 0x7007, 0x0003,
-	0x7000, 0xc084, 0x7002, 0x2900, 0x700a, 0x012e, 0x009e, 0x0005,
-	0x20e1, 0x0000, 0x2099, 0x0088, 0x782b, 0x0040, 0x0096, 0x2001,
-	0x192e, 0x204c, 0xaa7c, 0x009e, 0x080c, 0x8cb2, 0x2009, 0x188c,
-	0x2104, 0x9084, 0xfffc, 0x200a, 0x080c, 0x8b18, 0x7007, 0x0000,
-	0x080c, 0x116c, 0x0005, 0x7007, 0x0000, 0x080c, 0x116c, 0x0005,
-	0x0126, 0x2091, 0x2200, 0x2079, 0x0300, 0x2071, 0x1a6a, 0x7003,
-	0x0000, 0x78bf, 0x00f6, 0x0041, 0x7807, 0x0007, 0x7803, 0x0000,
-	0x7803, 0x0001, 0x012e, 0x0005, 0x00c6, 0x7803, 0x0000, 0x2001,
-	0x0165, 0x2003, 0x4198, 0x7808, 0xd09c, 0x0118, 0x7820, 0x04e9,
-	0x0cd0, 0x2001, 0x1a6b, 0x2003, 0x0000, 0x78ab, 0x0004, 0x78ac,
-	0xd0ac, 0x1de8, 0x78ab, 0x0002, 0x7807, 0x0007, 0x7827, 0x0030,
-	0x782b, 0x0400, 0x7827, 0x0031, 0x782b, 0x1a7c, 0x781f, 0xff00,
-	0x781b, 0xff00, 0x2001, 0x0200, 0x2004, 0xd0dc, 0x0110, 0x781f,
-	0x0303, 0x2061, 0x1a7c, 0x602f, 0x1ddc, 0x2001, 0x181a, 0x2004,
-	0x9082, 0x1ddc, 0x6032, 0x603b, 0x1eab, 0x602b, 0x1abc, 0x6007,
-	0x1a9c, 0x2061, 0x1a9c, 0x606f, 0x193c, 0x2001, 0x1927, 0x2004,
-	0x607a, 0x783f, 0x33b9, 0x00ce, 0x0005, 0x9086, 0x000d, 0x11d0,
-	0x7808, 0xd09c, 0x01b8, 0x7820, 0x0026, 0x2010, 0x080c, 0xc968,
-	0x0180, 0x2260, 0x6000, 0x9086, 0x0004, 0x1158, 0x0016, 0x6120,
-	0x9186, 0x0009, 0x0108, 0x0020, 0x2009, 0x004c, 0x080c, 0xad4d,
-	0x001e, 0x002e, 0x0005, 0x0126, 0x2091, 0x2200, 0x7908, 0x9184,
-	0x0070, 0x190c, 0x0d76, 0xd19c, 0x05a0, 0x7820, 0x908c, 0xf000,
-	0x0540, 0x2060, 0x6020, 0x9086, 0x0003, 0x1550, 0x6000, 0x9086,
-	0x0004, 0x1530, 0x6114, 0x2148, 0xa876, 0xa87a, 0xa867, 0x0103,
-	0x080c, 0x6c04, 0x00b6, 0x6010, 0x2058, 0xba3c, 0x8211, 0x0208,
-	0xba3e, 0xb8d0, 0x9005, 0x190c, 0x67be, 0x00be, 0x6044, 0xd0fc,
-	0x190c, 0xa947, 0x080c, 0xacd9, 0x7808, 0xd09c, 0x19b0, 0x012e,
-	0x0005, 0x908a, 0x0024, 0x1a0c, 0x0d7d, 0x002b, 0x012e, 0x0005,
-	0x04b0, 0x012e, 0x0005, 0x141f, 0x1445, 0x1475, 0x147a, 0x147e,
-	0x1483, 0x14ab, 0x14af, 0x14bd, 0x14c1, 0x141f, 0x158e, 0x1592,
-	0x1604, 0x160b, 0x141f, 0x160c, 0x160d, 0x1618, 0x161f, 0x141f,
-	0x141f, 0x141f, 0x141f, 0x141f, 0x141f, 0x141f, 0x1485, 0x141f,
-	0x144d, 0x1472, 0x1439, 0x141f, 0x1459, 0x1423, 0x1421, 0x080c,
-	0x0d7d, 0x080c, 0x0d76, 0x080c, 0x162a, 0x2009, 0x1a78, 0x2104,
-	0x8000, 0x200a, 0x080c, 0x7fed, 0x080c, 0x1b10, 0x0005, 0x6044,
-	0xd0fc, 0x190c, 0xa947, 0x2009, 0x0055, 0x080c, 0xad4d, 0x012e,
-	0x0005, 0x080c, 0x162a, 0x2060, 0x6044, 0xd0fc, 0x190c, 0xa947,
-	0x2009, 0x0055, 0x080c, 0xad4d, 0x0005, 0x2009, 0x0048, 0x080c,
-	0x162a, 0x2060, 0x080c, 0xad4d, 0x0005, 0x2009, 0x0054, 0x080c,
-	0x162a, 0x2060, 0x6044, 0xd0fc, 0x190c, 0xa947, 0x080c, 0xad4d,
-	0x0005, 0x080c, 0x162a, 0x2060, 0x0056, 0x0066, 0x080c, 0x162a,
-	0x2028, 0x080c, 0x162a, 0x2030, 0x0036, 0x0046, 0x2021, 0x0000,
-	0x2418, 0x2009, 0x0056, 0x080c, 0xad4d, 0x004e, 0x003e, 0x006e,
-	0x005e, 0x0005, 0x080c, 0x162a, 0x0005, 0x7004, 0xc085, 0xc0b5,
-	0x7006, 0x0005, 0x7004, 0xc085, 0x7006, 0x0005, 0x080c, 0x162a,
-	0x080c, 0x170b, 0x0005, 0x080c, 0x0d7d, 0x080c, 0x162a, 0x2060,
-	0x6014, 0x0096, 0x2048, 0xa83b, 0xffff, 0x009e, 0x2009, 0x0048,
-	0x080c, 0xad4d, 0x2001, 0x015d, 0x2003, 0x0000, 0x2009, 0x03e8,
-	0x8109, 0x0160, 0x2001, 0x0201, 0x2004, 0x9005, 0x0dc8, 0x2001,
-	0x0218, 0x2004, 0xd0ec, 0x1110, 0x080c, 0x162f, 0x2001, 0x0307,
-	0x2003, 0x8000, 0x0005, 0x7004, 0xc095, 0x7006, 0x0005, 0x080c,
-	0x162a, 0x2060, 0x6014, 0x0096, 0x2048, 0xa83b, 0xffff, 0x009e,
-	0x2009, 0x0048, 0x080c, 0xad4d, 0x0005, 0x080c, 0x162a, 0x080c,
-	0x0d7d, 0x080c, 0x162a, 0x080c, 0x1579, 0x7827, 0x0018, 0x79ac,
-	0xd1dc, 0x0904, 0x152a, 0x7827, 0x0015, 0x7828, 0x782b, 0x0000,
-	0x9065, 0x0140, 0x2001, 0x020d, 0x2003, 0x0050, 0x2003, 0x0020,
-	0x0804, 0x1530, 0x7004, 0x9005, 0x01c8, 0x1188, 0x78ab, 0x0004,
-	0x7827, 0x0018, 0x782b, 0x0000, 0xd1bc, 0x090c, 0x0d7d, 0x2001,
-	0x020d, 0x2003, 0x0050, 0x2003, 0x0020, 0x0804, 0x155e, 0x78ab,
-	0x0004, 0x7803, 0x0001, 0x080c, 0x1592, 0x0005, 0x7827, 0x0018,
-	0xa001, 0x7828, 0x7827, 0x0011, 0xa001, 0x7928, 0x9106, 0x0110,
-	0x79ac, 0x08e0, 0x00e6, 0x2071, 0x0200, 0x702c, 0xd0c4, 0x0140,
-	0x00ee, 0x080c, 0x1b10, 0x080c, 0x1354, 0x7803, 0x0001, 0x0005,
-	0x7037, 0x0001, 0xa001, 0x7150, 0x00ee, 0x918c, 0xff00, 0x9186,
-	0x0500, 0x0110, 0x79ac, 0x0810, 0x7004, 0xc09d, 0x7006, 0x78ab,
-	0x0004, 0x7803, 0x0001, 0x080c, 0x1592, 0x2001, 0x020d, 0x2003,
-	0x0020, 0x0005, 0x7828, 0x782b, 0x0000, 0x9065, 0x090c, 0x0d7d,
-	0x6014, 0x2048, 0x78ab, 0x0004, 0x918c, 0x0700, 0x01a8, 0x080c,
-	0x7fed, 0x080c, 0x1b10, 0x080c, 0xc97a, 0x0158, 0xa9ac, 0xa936,
-	0xa9b0, 0xa93a, 0xa83f, 0xffff, 0xa843, 0xffff, 0xa880, 0xc0bd,
-	0xa882, 0x080c, 0xc566, 0x0005, 0x6020, 0x9086, 0x0009, 0x1128,
-	0x2009, 0x004c, 0x080c, 0xad4d, 0x0048, 0x6010, 0x00b6, 0x2058,
-	0xb800, 0x00be, 0xd0bc, 0x6024, 0x190c, 0xcd7d, 0x2029, 0x00c8,
-	0x8529, 0x0128, 0x2001, 0x0201, 0x2004, 0x9005, 0x0dc8, 0x7dbc,
-	0x080c, 0xe85a, 0xd5a4, 0x1118, 0x080c, 0x162f, 0x0005, 0x080c,
-	0x7fed, 0x080c, 0x1b10, 0x0005, 0x781f, 0x0300, 0x7803, 0x0001,
-	0x0005, 0x0016, 0x0066, 0x0076, 0x00f6, 0x2079, 0x0300, 0x7908,
-	0x918c, 0x0007, 0x9186, 0x0003, 0x0120, 0x2001, 0x0016, 0x080c,
-	0x16a0, 0x00fe, 0x007e, 0x006e, 0x001e, 0x0005, 0x7004, 0xc09d,
-	0x7006, 0x0005, 0x7104, 0x9184, 0x0004, 0x190c, 0x0d7d, 0xd184,
-	0x11b1, 0xd19c, 0x0180, 0xc19c, 0x7106, 0x0016, 0x080c, 0x16ee,
-	0x001e, 0x0148, 0x2001, 0x020d, 0x2003, 0x0050, 0x2003, 0x0020,
-	0x080c, 0x162f, 0x0005, 0x81ff, 0x190c, 0x0d7d, 0x0005, 0x2100,
-	0xc184, 0xc1b4, 0x7106, 0xd0b4, 0x0016, 0x00e6, 0x1904, 0x15f9,
-	0x2071, 0x0200, 0x080c, 0x16db, 0x05e0, 0x080c, 0x16ee, 0x05b0,
-	0x6014, 0x9005, 0x05b0, 0x0096, 0x2048, 0xa864, 0x009e, 0x9084,
-	0x00ff, 0x908e, 0x0029, 0x0160, 0x908e, 0x0048, 0x1550, 0x601c,
-	0xd084, 0x11e0, 0x00f6, 0x2c78, 0x080c, 0x1778, 0x00fe, 0x00b0,
-	0x00f6, 0x2c78, 0x080c, 0x1901, 0x00fe, 0x2009, 0x01f4, 0x8109,
-	0x0168, 0x2001, 0x0201, 0x2004, 0x9005, 0x0dc8, 0x2001, 0x0218,
-	0x2004, 0xd0ec, 0x1118, 0x080c, 0x162f, 0x0040, 0x2001, 0x020d,
-	0x2003, 0x0020, 0x080c, 0x1354, 0x7803, 0x0001, 0x00ee, 0x001e,
-	0x0005, 0x080c, 0x16ee, 0x0dd0, 0x2001, 0x020d, 0x2003, 0x0050,
-	0x2003, 0x0020, 0x0461, 0x0c90, 0x0429, 0x2060, 0x2009, 0x0053,
-	0x080c, 0xad4d, 0x0005, 0x0005, 0x0005, 0x00e1, 0x2008, 0x00d1,
-	0x0006, 0x7004, 0xc09d, 0x7006, 0x000e, 0x080c, 0x9003, 0x0005,
-	0x0089, 0x9005, 0x0118, 0x080c, 0x8c0a, 0x0cd0, 0x0005, 0x2001,
-	0x0036, 0x2009, 0x1820, 0x210c, 0x2011, 0x181f, 0x2214, 0x080c,
-	0x16a0, 0x0005, 0x7808, 0xd09c, 0x0de8, 0x7820, 0x0005, 0x080c,
-	0x1579, 0x00d6, 0x2069, 0x0200, 0x2009, 0x01f4, 0x8109, 0x0510,
-	0x6804, 0x9005, 0x0dd8, 0x2001, 0x015d, 0x2003, 0x0000, 0x79bc,
-	0xd1a4, 0x1528, 0x79b8, 0x918c, 0x0fff, 0x0180, 0x9182, 0x0841,
-	0x1268, 0x9188, 0x0007, 0x918c, 0x0ff8, 0x810c, 0x810c, 0x810c,
-	0x080c, 0x1692, 0x6827, 0x0001, 0x8109, 0x1dd0, 0x04d9, 0x6827,
-	0x0002, 0x04c1, 0x6804, 0x9005, 0x1130, 0x682c, 0xd0e4, 0x1500,
-	0x6804, 0x9005, 0x0de8, 0x79b8, 0xd1ec, 0x1130, 0x08c0, 0x080c,
-	0x7fed, 0x080c, 0x1b10, 0x0090, 0x7827, 0x0015, 0x782b, 0x0000,
-	0x7827, 0x0018, 0x782b, 0x0000, 0x2001, 0x020d, 0x2003, 0x0020,
-	0x2001, 0x0307, 0x2003, 0x0300, 0x7803, 0x0001, 0x00de, 0x0005,
-	0x682c, 0x9084, 0x5400, 0x9086, 0x5400, 0x0d30, 0x7827, 0x0015,
-	0x782b, 0x0000, 0x7803, 0x0001, 0x6800, 0x9085, 0x1800, 0x6802,
-	0x00de, 0x0005, 0x6824, 0x9084, 0x0003, 0x1de0, 0x0005, 0x2001,
-	0x0030, 0x2c08, 0x621c, 0x0021, 0x7830, 0x9086, 0x0041, 0x0005,
-	0x00f6, 0x2079, 0x0300, 0x0006, 0x7808, 0xd09c, 0x0140, 0x0016,
-	0x0026, 0x00c6, 0x080c, 0x13bb, 0x00ce, 0x002e, 0x001e, 0x000e,
-	0x0006, 0x7832, 0x7936, 0x7a3a, 0x781b, 0x8080, 0x0059, 0x1118,
-	0x000e, 0x00fe, 0x0005, 0x000e, 0x792c, 0x3900, 0x8000, 0x2004,
-	0x080c, 0x0d7d, 0x2009, 0xff00, 0x8109, 0x0120, 0x7818, 0xd0bc,
-	0x1dd8, 0x0005, 0x9085, 0x0001, 0x0005, 0x7832, 0x7936, 0x7a3a,
-	0x781b, 0x8080, 0x0c79, 0x1108, 0x0005, 0x792c, 0x3900, 0x8000,
-	0x2004, 0x080c, 0x0d7d, 0x7037, 0x0001, 0x7150, 0x7037, 0x0002,
-	0x7050, 0x2060, 0xd1bc, 0x1110, 0x7054, 0x2060, 0x918c, 0xff00,
-	0x9186, 0x0500, 0x0110, 0x9085, 0x0001, 0x0005, 0x0006, 0x0046,
-	0x00e6, 0x2071, 0x0200, 0x7037, 0x0002, 0x7058, 0x9084, 0xff00,
-	0x8007, 0x9086, 0x00bc, 0x1158, 0x2021, 0x1a79, 0x2404, 0x8000,
-	0x0208, 0x2022, 0x080c, 0x7fed, 0x080c, 0x1b10, 0x9006, 0x00ee,
-	0x004e, 0x000e, 0x0005, 0x0c11, 0x1108, 0x0005, 0x00e6, 0x0016,
-	0x2071, 0x0200, 0x0841, 0x6124, 0xd1dc, 0x01f8, 0x701c, 0xd08c,
-	0x0904, 0x176d, 0x7017, 0x0000, 0x2001, 0x0264, 0x2004, 0xd0bc,
-	0x0904, 0x176d, 0x2001, 0x0268, 0x00c6, 0x2064, 0x6104, 0x6038,
-	0x00ce, 0x918e, 0x0039, 0x1904, 0x176d, 0x9c06, 0x15f0, 0x0126,
-	0x2091, 0x2600, 0x080c, 0x7f45, 0x012e, 0x7358, 0x745c, 0x6014,
-	0x905d, 0x0598, 0x2b48, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be,
-	0xd0bc, 0x190c, 0xcd58, 0xab42, 0xac3e, 0x2001, 0x1869, 0x2004,
-	0xd0b4, 0x1170, 0x601c, 0xd0e4, 0x1158, 0x6010, 0x00b6, 0x2058,
-	0xb800, 0x00be, 0xd0bc, 0x1120, 0xa83b, 0x7fff, 0xa837, 0xffff,
-	0x080c, 0x1ecb, 0x1190, 0x080c, 0x195e, 0x2a00, 0xa816, 0x0130,
-	0x2800, 0xa80e, 0x2c05, 0xa80a, 0x2c00, 0xa812, 0x7037, 0x0020,
-	0x781f, 0x0300, 0x001e, 0x00ee, 0x0005, 0x7037, 0x0050, 0x7037,
-	0x0020, 0x001e, 0x00ee, 0x080c, 0x162f, 0x0005, 0x080c, 0x0d7d,
-	0x2cf0, 0x0126, 0x2091, 0x2200, 0x0016, 0x00c6, 0x3e60, 0x6014,
-	0x2048, 0x2940, 0x903e, 0x2730, 0xa864, 0x2068, 0xa81a, 0x9d84,
-	0x000f, 0x9088, 0x1eab, 0x2165, 0x0002, 0x17a4, 0x1812, 0x17a4,
-	0x17a4, 0x17a8, 0x17f3, 0x17a4, 0x17c8, 0x179d, 0x1809, 0x17a4,
-	0x17a4, 0x17ad, 0x18ff, 0x17dc, 0x17d2, 0xa964, 0x918c, 0x00ff,
-	0x918e, 0x0048, 0x0904, 0x1809, 0x9085, 0x0001, 0x0804, 0x18f5,
-	0xa87c, 0xd0ac, 0x0dc8, 0x0804, 0x1819, 0xa87c, 0xd0ac, 0x0da0,
-	0x0804, 0x1884, 0xa898, 0x901d, 0x1108, 0xab9c, 0x9016, 0xaab2,
-	0xaa3e, 0xaa42, 0x3e00, 0x9080, 0x0008, 0x2004, 0x9080, 0x91d3,
-	0x2005, 0x9005, 0x090c, 0x0d7d, 0x2004, 0xa8ae, 0x0804, 0x18dd,
-	0xa87c, 0xd0bc, 0x09c8, 0xa890, 0xa842, 0xa88c, 0xa83e, 0xa888,
-	0x0804, 0x1819, 0xa87c, 0xd0bc, 0x0978, 0xa890, 0xa842, 0xa88c,
-	0xa83e, 0xa888, 0x0804, 0x1884, 0xa87c, 0xd0bc, 0x0928, 0xa890,
-	0xa842, 0xa88c, 0xa83e, 0xa804, 0x9045, 0x090c, 0x0d7d, 0xa164,
-	0xa91a, 0x91ec, 0x000f, 0x9d80, 0x1eab, 0x2065, 0xa888, 0xd19c,
-	0x1904, 0x1884, 0x0430, 0xa87c, 0xd0ac, 0x0904, 0x17a4, 0xa804,
-	0x9045, 0x090c, 0x0d7d, 0xa164, 0xa91a, 0x91ec, 0x000f, 0x9d80,
-	0x1eab, 0x2065, 0x9006, 0xa842, 0xa83e, 0xd19c, 0x1904, 0x1884,
-	0x0080, 0xa87c, 0xd0ac, 0x0904, 0x17a4, 0x9006, 0xa842, 0xa83e,
-	0x0804, 0x1884, 0xa87c, 0xd0ac, 0x0904, 0x17a4, 0x9006, 0xa842,
-	0xa83e, 0x2c05, 0x908a, 0x0036, 0x1a0c, 0x0d7d, 0x9082, 0x001b,
-	0x0002, 0x183c, 0x183c, 0x183e, 0x183c, 0x183c, 0x183c, 0x1848,
-	0x183c, 0x183c, 0x183c, 0x1852, 0x183c, 0x183c, 0x183c, 0x185c,
-	0x183c, 0x183c, 0x183c, 0x1866, 0x183c, 0x183c, 0x183c, 0x1870,
-	0x183c, 0x183c, 0x183c, 0x187a, 0x080c, 0x0d7d, 0xa574, 0xa478,
-	0x9d86, 0x0024, 0x0904, 0x17b2, 0xa37c, 0xa280, 0x0804, 0x18dd,
-	0xa584, 0xa488, 0x9d86, 0x0024, 0x0904, 0x17b2, 0xa38c, 0xa290,
-	0x0804, 0x18dd, 0xa594, 0xa498, 0x9d86, 0x0024, 0x0904, 0x17b2,
-	0xa39c, 0xa2a0, 0x0804, 0x18dd, 0xa5a4, 0xa4a8, 0x9d86, 0x0024,
-	0x0904, 0x17b2, 0xa3ac, 0xa2b0, 0x0804, 0x18dd, 0xa5b4, 0xa4b8,
-	0x9d86, 0x0024, 0x0904, 0x17b2, 0xa3bc, 0xa2c0, 0x0804, 0x18dd,
-	0xa5c4, 0xa4c8, 0x9d86, 0x0024, 0x0904, 0x17b2, 0xa3cc, 0xa2d0,
-	0x0804, 0x18dd, 0xa5d4, 0xa4d8, 0x9d86, 0x0024, 0x0904, 0x17b2,
-	0xa3dc, 0xa2e0, 0x0804, 0x18dd, 0x2c05, 0x908a, 0x0034, 0x1a0c,
-	0x0d7d, 0x9082, 0x001b, 0x0002, 0x18a7, 0x18a5, 0x18a5, 0x18a5,
-	0x18a5, 0x18a5, 0x18b2, 0x18a5, 0x18a5, 0x18a5, 0x18a5, 0x18a5,
-	0x18bd, 0x18a5, 0x18a5, 0x18a5, 0x18a5, 0x18a5, 0x18c8, 0x18a5,
-	0x18a5, 0x18a5, 0x18a5, 0x18a5, 0x18d3, 0x080c, 0x0d7d, 0xa56c,
-	0xa470, 0xa774, 0xa678, 0x9d86, 0x002c, 0x0904, 0x17b2, 0xa37c,
-	0xa280, 0x0458, 0xa584, 0xa488, 0xa78c, 0xa690, 0x9d86, 0x002c,
-	0x0904, 0x17b2, 0xa394, 0xa298, 0x0400, 0xa59c, 0xa4a0, 0xa7a4,
-	0xa6a8, 0x9d86, 0x002c, 0x0904, 0x17b2, 0xa3ac, 0xa2b0, 0x00a8,
-	0xa5b4, 0xa4b8, 0xa7bc, 0xa6c0, 0x9d86, 0x002c, 0x0904, 0x17b2,
-	0xa3c4, 0xa2c8, 0x0050, 0xa5cc, 0xa4d0, 0xa7d4, 0xa6d8, 0x9d86,
-	0x002c, 0x0904, 0x17b2, 0xa3dc, 0xa2e0, 0xab2e, 0xaa32, 0xad1e,
-	0xac22, 0xaf26, 0xae2a, 0xa988, 0x8c60, 0x2c1d, 0xa8ac, 0xaab0,
-	0xa836, 0xaa3a, 0x8109, 0xa916, 0x1160, 0x3e60, 0x601c, 0xc085,
-	0x601e, 0xa87c, 0xc0dd, 0xa87e, 0x9006, 0x00ce, 0x001e, 0x012e,
-	0x0005, 0x2800, 0xa80e, 0xab0a, 0x2c00, 0xa812, 0x0c70, 0x0804,
-	0x17a4, 0x2ff0, 0x0126, 0x2091, 0x2200, 0x0016, 0x00c6, 0x3e60,
-	0x6014, 0x2048, 0x2940, 0xa80e, 0x2061, 0x1ea6, 0xa813, 0x1ea6,
-	0x2c05, 0xa80a, 0xa964, 0xa91a, 0xa87c, 0xd0ac, 0x090c, 0x0d7d,
-	0x9006, 0xa842, 0xa83e, 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0d7d,
-	0xadcc, 0xacd0, 0xafd4, 0xaed8, 0xabdc, 0xaae0, 0xab2e, 0xaa32,
-	0xad1e, 0xac22, 0xaf26, 0xae2a, 0xa8ac, 0xaab0, 0xa836, 0xaa3a,
-	0xa988, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0008, 0x1120, 0x8109,
-	0xa916, 0x0128, 0x0080, 0x918a, 0x0002, 0xa916, 0x1160, 0x3e60,
-	0x601c, 0xc085, 0x601e, 0xa87c, 0xc0dd, 0xa87e, 0x9006, 0x00ce,
-	0x001e, 0x012e, 0x0005, 0xa804, 0x9045, 0x090c, 0x0d7d, 0xa80e,
-	0xa064, 0xa81a, 0x9084, 0x000f, 0x9080, 0x1eab, 0x2015, 0x82ff,
-	0x090c, 0x0d7d, 0xaa12, 0x2205, 0xa80a, 0x0c08, 0x903e, 0x2730,
-	0xa880, 0xd0fc, 0x1190, 0x2d00, 0x0002, 0x1a88, 0x19b5, 0x19b5,
-	0x1a88, 0x19b5, 0x1a82, 0x1a88, 0x19b5, 0x1a25, 0x1a25, 0x1a25,
-	0x1a88, 0x1a25, 0x1a88, 0x1a7f, 0x1a25, 0xc0fc, 0xa882, 0xab2c,
-	0xaa30, 0xad1c, 0xac20, 0xdd9c, 0x0904, 0x1a8a, 0x2c05, 0x908a,
-	0x0034, 0x1a0c, 0x0d7d, 0x9082, 0x001b, 0x0002, 0x19a1, 0x199f,
-	0x199f, 0x199f, 0x199f, 0x199f, 0x19a5, 0x199f, 0x199f, 0x199f,
-	0x199f, 0x199f, 0x19a9, 0x199f, 0x199f, 0x199f, 0x199f, 0x199f,
-	0x19ad, 0x199f, 0x199f, 0x199f, 0x199f, 0x199f, 0x19b1, 0x080c,
-	0x0d7d, 0xa774, 0xa678, 0x0804, 0x1a8a, 0xa78c, 0xa690, 0x0804,
-	0x1a8a, 0xa7a4, 0xa6a8, 0x0804, 0x1a8a, 0xa7bc, 0xa6c0, 0x0804,
-	0x1a8a, 0xa7d4, 0xa6d8, 0x0804, 0x1a8a, 0xa898, 0x901d, 0x1108,
-	0xab9c, 0x9016, 0x2c05, 0x908a, 0x0036, 0x1a0c, 0x0d7d, 0x9082,
-	0x001b, 0x0002, 0x19dd, 0x19dd, 0x19df, 0x19dd, 0x19dd, 0x19dd,
-	0x19e9, 0x19dd, 0x19dd, 0x19dd, 0x19f3, 0x19dd, 0x19dd, 0x19dd,
-	0x19fd, 0x19dd, 0x19dd, 0x19dd, 0x1a07, 0x19dd, 0x19dd, 0x19dd,
-	0x1a11, 0x19dd, 0x19dd, 0x19dd, 0x1a1b, 0x080c, 0x0d7d, 0xa574,
-	0xa478, 0x9d86, 0x0004, 0x0904, 0x1a8a, 0xa37c, 0xa280, 0x0804,
-	0x1a8a, 0xa584, 0xa488, 0x9d86, 0x0004, 0x0904, 0x1a8a, 0xa38c,
-	0xa290, 0x0804, 0x1a8a, 0xa594, 0xa498, 0x9d86, 0x0004, 0x0904,
-	0x1a8a, 0xa39c, 0xa2a0, 0x0804, 0x1a8a, 0xa5a4, 0xa4a8, 0x9d86,
-	0x0004, 0x0904, 0x1a8a, 0xa3ac, 0xa2b0, 0x0804, 0x1a8a, 0xa5b4,
-	0xa4b8, 0x9d86, 0x0004, 0x0904, 0x1a8a, 0xa3bc, 0xa2c0, 0x0804,
-	0x1a8a, 0xa5c4, 0xa4c8, 0x9d86, 0x0004, 0x0904, 0x1a8a, 0xa3cc,
-	0xa2d0, 0x0804, 0x1a8a, 0xa5d4, 0xa4d8, 0x9d86, 0x0004, 0x0904,
-	0x1a8a, 0xa3dc, 0xa2e0, 0x0804, 0x1a8a, 0xa898, 0x901d, 0x1108,
-	0xab9c, 0x9016, 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0d7d, 0x9082,
-	0x001b, 0x0002, 0x1a4d, 0x1a4b, 0x1a4b, 0x1a4b, 0x1a4b, 0x1a4b,
-	0x1a57, 0x1a4b, 0x1a4b, 0x1a4b, 0x1a4b, 0x1a4b, 0x1a61, 0x1a4b,
-	0x1a4b, 0x1a4b, 0x1a4b, 0x1a4b, 0x1a6b, 0x1a4b, 0x1a4b, 0x1a4b,
-	0x1a4b, 0x1a4b, 0x1a75, 0x080c, 0x0d7d, 0xa56c, 0xa470, 0xa774,
-	0xa678, 0x9d86, 0x000c, 0x05b0, 0xa37c, 0xa280, 0x0498, 0xa584,
-	0xa488, 0xa78c, 0xa690, 0x9d86, 0x000c, 0x0560, 0xa394, 0xa298,
-	0x0448, 0xa59c, 0xa4a0, 0xa7a4, 0xa6a8, 0x9d86, 0x000c, 0x0510,
-	0xa3ac, 0xa2b0, 0x00f8, 0xa5b4, 0xa4b8, 0xa7bc, 0xa6c0, 0x9d86,
-	0x000c, 0x01c0, 0xa3c4, 0xa2c8, 0x00a8, 0xa5cc, 0xa4d0, 0xa7d4,
-	0xa6d8, 0x9d86, 0x000c, 0x0170, 0xa3dc, 0xa2e0, 0x0058, 0x9d86,
-	0x000e, 0x1130, 0x080c, 0x1e81, 0x1904, 0x195e, 0x900e, 0x0050,
-	0x080c, 0x0d7d, 0xab2e, 0xaa32, 0xad1e, 0xac22, 0xaf26, 0xae2a,
-	0x080c, 0x1e81, 0x0005, 0x6014, 0x2048, 0x6118, 0x810c, 0x810c,
-	0x810c, 0x81ff, 0x1118, 0xa887, 0x0001, 0x0008, 0xa986, 0x601b,
-	0x0002, 0xa874, 0x9084, 0x00ff, 0x9084, 0x0008, 0x0150, 0x00e9,
-	0x6000, 0x9086, 0x0004, 0x1120, 0x2009, 0x0048, 0x080c, 0xad4d,
-	0x0005, 0xa974, 0xd1dc, 0x1108, 0x0005, 0xa934, 0xa88c, 0x9106,
-	0x1158, 0xa938, 0xa890, 0x9106, 0x1138, 0x601c, 0xc084, 0x601e,
-	0x2009, 0x0048, 0x0804, 0xad4d, 0x0005, 0x0126, 0x00c6, 0x2091,
-	0x2200, 0x00ce, 0x7908, 0x918c, 0x0007, 0x9186, 0x0000, 0x05b0,
-	0x9186, 0x0003, 0x0598, 0x6020, 0x6023, 0x0000, 0x0006, 0x2031,
-	0x0008, 0x00c6, 0x781f, 0x0808, 0x7808, 0xd09c, 0x0120, 0x080c,
-	0x13bb, 0x8631, 0x1db8, 0x00ce, 0x781f, 0x0800, 0x2031, 0x0168,
-	0x00c6, 0x7808, 0xd09c, 0x190c, 0x13bb, 0x00ce, 0x2001, 0x0038,
-	0x080c, 0x1b98, 0x7930, 0x9186, 0x0040, 0x0160, 0x9186, 0x0042,
-	0x190c, 0x0d7d, 0x2001, 0x001e, 0x8001, 0x1df0, 0x8631, 0x1d40,
-	0x080c, 0x1ba7, 0x000e, 0x6022, 0x012e, 0x0005, 0x080c, 0x1b94,
-	0x7827, 0x0015, 0x7828, 0x9c06, 0x1db8, 0x782b, 0x0000, 0x0ca0,
-	0x00f6, 0x2079, 0x0300, 0x7803, 0x0000, 0x78ab, 0x0004, 0x00fe,
-	0x080c, 0x753d, 0x1188, 0x2001, 0x0138, 0x2003, 0x0000, 0x2001,
-	0x0160, 0x2003, 0x0000, 0x2011, 0x012c, 0xa001, 0xa001, 0x8211,
-	0x1de0, 0x0059, 0x0804, 0x75e2, 0x0479, 0x0039, 0x2001, 0x0160,
-	0x2502, 0x2001, 0x0138, 0x2202, 0x0005, 0x00e6, 0x2071, 0x0200,
-	0x080c, 0x2a6c, 0x2009, 0x003c, 0x080c, 0x220a, 0x2001, 0x015d,
-	0x2003, 0x0000, 0x7000, 0x9084, 0x003c, 0x1de0, 0x080c, 0x85ce,
-	0x70a0, 0x70a2, 0x7098, 0x709a, 0x709c, 0x709e, 0x2001, 0x020d,
-	0x2003, 0x0020, 0x00f6, 0x2079, 0x0300, 0x080c, 0x1354, 0x7803,
-	0x0001, 0x00fe, 0x00ee, 0x0005, 0x2001, 0x0138, 0x2014, 0x2003,
-	0x0000, 0x2001, 0x0160, 0x202c, 0x2003, 0x0000, 0x080c, 0x753d,
-	0x1108, 0x0005, 0x2021, 0x0260, 0x2001, 0x0141, 0x201c, 0xd3dc,
-	0x1168, 0x2001, 0x0109, 0x201c, 0x939c, 0x0048, 0x1160, 0x2001,
-	0x0111, 0x201c, 0x83ff, 0x1110, 0x8421, 0x1d70, 0x2001, 0x015d,
-	0x2003, 0x0000, 0x0005, 0x0046, 0x2021, 0x0019, 0x2003, 0x0048,
-	0xa001, 0xa001, 0x201c, 0x939c, 0x0048, 0x0120, 0x8421, 0x1db0,
-	0x004e, 0x0c60, 0x004e, 0x0c40, 0x601c, 0xc084, 0x601e, 0x0005,
-	0x2c08, 0x621c, 0x080c, 0x16a0, 0x7930, 0x0005, 0x2c08, 0x621c,
-	0x080c, 0x16cd, 0x7930, 0x0005, 0x8001, 0x1df0, 0x0005, 0x2031,
-	0x0064, 0x781c, 0x9084, 0x0007, 0x0170, 0x2001, 0x0038, 0x0c41,
-	0x9186, 0x0040, 0x0904, 0x1c05, 0x2001, 0x001e, 0x0c69, 0x8631,
-	0x1d80, 0x080c, 0x0d7d, 0x781f, 0x0202, 0x2001, 0x015d, 0x2003,
-	0x0000, 0x2001, 0x0dac, 0x0c01, 0x781c, 0xd084, 0x0110, 0x0861,
-	0x04e0, 0x2001, 0x0030, 0x0891, 0x9186, 0x0040, 0x0568, 0x781c,
-	0xd084, 0x1da8, 0x781f, 0x0101, 0x2001, 0x0014, 0x0869, 0x2001,
-	0x0037, 0x0821, 0x9186, 0x0040, 0x0140, 0x2001, 0x0030, 0x080c,
-	0x1b9e, 0x9186, 0x0040, 0x190c, 0x0d7d, 0x00d6, 0x2069, 0x0200,
-	0x692c, 0xd1f4, 0x1170, 0xd1c4, 0x0160, 0xd19c, 0x0130, 0x6800,
-	0x9085, 0x1800, 0x6802, 0x00de, 0x0080, 0x6908, 0x9184, 0x0007,
-	0x1db0, 0x00de, 0x781f, 0x0100, 0x791c, 0x9184, 0x0007, 0x090c,
-	0x0d7d, 0xa001, 0xa001, 0x781f, 0x0200, 0x0005, 0x0126, 0x2091,
-	0x2400, 0x2079, 0x0380, 0x2001, 0x19e6, 0x2070, 0x012e, 0x0005,
-	0x2cf0, 0x0126, 0x2091, 0x2400, 0x3e60, 0x6014, 0x2048, 0xa964,
-	0xa91a, 0x918c, 0x00ff, 0x9184, 0x000f, 0x0002, 0x1c3a, 0x1c3a,
-	0x1c3a, 0x1c3c, 0x1c3a, 0x1c3a, 0x1c3a, 0x1c3a, 0x1c2e, 0x1c44,
-	0x1c3a, 0x1c40, 0x1c3a, 0x1c3a, 0x1c3a, 0x1c3a, 0x9086, 0x0008,
-	0x1148, 0xa87c, 0xd0b4, 0x0904, 0x1db4, 0x2011, 0x1ea6, 0x2205,
-	0xab88, 0x00a8, 0x080c, 0x0d7d, 0x9186, 0x0013, 0x0128, 0x0cd0,
-	0x9186, 0x001b, 0x0108, 0x0cb0, 0xa87c, 0xd0b4, 0x0904, 0x1db4,
-	0x9184, 0x000f, 0x9080, 0x1eab, 0x2015, 0x2205, 0xab88, 0x2908,
-	0xa80a, 0xa90e, 0xaa12, 0xab16, 0x9006, 0xa842, 0xa83e, 0x012e,
-	0x0005, 0x2cf0, 0x0126, 0x2091, 0x2400, 0x3e60, 0x6014, 0x2048,
-	0xa88c, 0xa990, 0xaaac, 0xabb0, 0xaa36, 0xab3a, 0xa83e, 0xa942,
-	0xa846, 0xa94a, 0xa964, 0x918c, 0x00ff, 0x9186, 0x001e, 0x0198,
-	0x2940, 0xa064, 0xa81a, 0x90ec, 0x000f, 0x9d80, 0x1eab, 0x2065,
-	0x2c05, 0x2808, 0x2c10, 0xab88, 0xa80a, 0xa90e, 0xaa12, 0xab16,
-	0x012e, 0x3e60, 0x0005, 0xa804, 0x2040, 0x0c58, 0x2cf0, 0x0126,
-	0x2091, 0x2400, 0x3e60, 0x6014, 0x2048, 0xa97c, 0x2950, 0xd1dc,
-	0x1904, 0x1d7e, 0xc1dd, 0xa97e, 0x9006, 0xa842, 0xa83e, 0xa988,
-	0x8109, 0xa916, 0xa964, 0xa91a, 0x9184, 0x000f, 0x9088, 0x1eab,
-	0x2145, 0x0002, 0x1cb2, 0x1cc0, 0x1cb2, 0x1cb2, 0x1cb2, 0x1cb4,
-	0x1cb2, 0x1cb2, 0x1d15, 0x1d15, 0x1cb2, 0x1cb2, 0x1cb2, 0x1d13,
-	0x1cb2, 0x1cb2, 0x080c, 0x0d7d, 0xa804, 0x2050, 0xb164, 0xa91a,
-	0x9184, 0x000f, 0x9080, 0x1eab, 0x2045, 0xd19c, 0x1904, 0x1d15,
-	0x9036, 0x2638, 0x2805, 0x908a, 0x0036, 0x1a0c, 0x0d7d, 0x9082,
-	0x001b, 0x0002, 0x1ce5, 0x1ce5, 0x1ce7, 0x1ce5, 0x1ce5, 0x1ce5,
-	0x1ced, 0x1ce5, 0x1ce5, 0x1ce5, 0x1cf3, 0x1ce5, 0x1ce5, 0x1ce5,
-	0x1cf9, 0x1ce5, 0x1ce5, 0x1ce5, 0x1cff, 0x1ce5, 0x1ce5, 0x1ce5,
-	0x1d05, 0x1ce5, 0x1ce5, 0x1ce5, 0x1d0b, 0x080c, 0x0d7d, 0xb574,
-	0xb478, 0xb37c, 0xb280, 0x0804, 0x1d5a, 0xb584, 0xb488, 0xb38c,
-	0xb290, 0x0804, 0x1d5a, 0xb594, 0xb498, 0xb39c, 0xb2a0, 0x0804,
-	0x1d5a, 0xb5a4, 0xb4a8, 0xb3ac, 0xb2b0, 0x0804, 0x1d5a, 0xb5b4,
-	0xb4b8, 0xb3bc, 0xb2c0, 0x0804, 0x1d5a, 0xb5c4, 0xb4c8, 0xb3cc,
-	0xb2d0, 0x0804, 0x1d5a, 0xb5d4, 0xb4d8, 0xb3dc, 0xb2e0, 0x0804,
-	0x1d5a, 0x0804, 0x1d5a, 0x080c, 0x0d7d, 0x2805, 0x908a, 0x0034,
-	0x1a0c, 0x0d7d, 0x9082, 0x001b, 0x0002, 0x1d38, 0x1d36, 0x1d36,
-	0x1d36, 0x1d36, 0x1d36, 0x1d3f, 0x1d36, 0x1d36, 0x1d36, 0x1d36,
-	0x1d36, 0x1d46, 0x1d36, 0x1d36, 0x1d36, 0x1d36, 0x1d36, 0x1d4d,
-	0x1d36, 0x1d36, 0x1d36, 0x1d36, 0x1d36, 0x1d54, 0x080c, 0x0d7d,
-	0xb56c, 0xb470, 0xb774, 0xb678, 0xb37c, 0xb280, 0x00d8, 0xb584,
-	0xb488, 0xb78c, 0xb690, 0xb394, 0xb298, 0x00a0, 0xb59c, 0xb4a0,
-	0xb7a4, 0xb6a8, 0xb3ac, 0xb2b0, 0x0068, 0xb5b4, 0xb4b8, 0xb7bc,
-	0xb6c0, 0xb3c4, 0xb2c8, 0x0030, 0xb5cc, 0xb4d0, 0xb7d4, 0xb6d8,
-	0xb3dc, 0xb2e0, 0xab2e, 0xaa32, 0xad1e, 0xac22, 0xaf26, 0xae2a,
-	0xa988, 0x8109, 0xa916, 0x1118, 0x9006, 0x012e, 0x0005, 0x8840,
-	0x2805, 0x9005, 0x1168, 0xb004, 0x9005, 0x090c, 0x0d7d, 0x2050,
-	0xb164, 0xa91a, 0x9184, 0x000f, 0x9080, 0x1eab, 0x2045, 0x2805,
-	0x2810, 0x2a08, 0xa80a, 0xa90e, 0xaa12, 0x0c30, 0x3e60, 0x6344,
-	0xd3fc, 0x190c, 0x0d7d, 0xa93c, 0xaa40, 0xa844, 0x9106, 0x1118,
-	0xa848, 0x9206, 0x0508, 0x2958, 0xab48, 0xac44, 0x2940, 0x080c,
-	0x1ecb, 0x1998, 0x2850, 0x2c40, 0xab14, 0xa880, 0xd0fc, 0x1140,
-	0xa810, 0x2005, 0xa80a, 0x2a00, 0xa80e, 0x2009, 0x8015, 0x0070,
-	0x00c6, 0x3e60, 0x6044, 0xc0a4, 0x9085, 0x8005, 0x6046, 0x00ce,
-	0x8319, 0xab16, 0x1904, 0x1d67, 0x2009, 0x8005, 0x3e60, 0x6044,
-	0x9105, 0x6046, 0x0804, 0x1d64, 0x080c, 0x0d7d, 0x00f6, 0x00e6,
-	0x0096, 0x00c6, 0x0026, 0x704c, 0x9c06, 0x190c, 0x0d7d, 0x2079,
-	0x0090, 0x2001, 0x0105, 0x2003, 0x0010, 0x782b, 0x0004, 0x7057,
-	0x0000, 0x6014, 0x2048, 0x080c, 0xc97a, 0x0118, 0xa880, 0xc0bd,
-	0xa882, 0x6020, 0x9086, 0x0006, 0x1170, 0x2061, 0x0100, 0x62c8,
-	0x2001, 0x00fa, 0x8001, 0x1df0, 0x60c8, 0x9206, 0x1dc0, 0x60c4,
-	0xa89a, 0x60c8, 0xa896, 0x704c, 0x2060, 0x00c6, 0x080c, 0xc566,
-	0x080c, 0xa91e, 0x00ce, 0x704c, 0x9c06, 0x1150, 0x2009, 0x0040,
-	0x080c, 0x220a, 0x080c, 0xa3c3, 0x2011, 0x0000, 0x080c, 0xa24d,
-	0x002e, 0x00ce, 0x009e, 0x00ee, 0x00fe, 0x0005, 0x00f6, 0x2079,
-	0x0090, 0x781c, 0x0006, 0x7818, 0x0006, 0x2079, 0x0100, 0x7a14,
-	0x9284, 0x1984, 0x9085, 0x0012, 0x7816, 0x2019, 0x1000, 0x8319,
-	0x090c, 0x0d7d, 0x7820, 0xd0bc, 0x1dd0, 0x79c8, 0x000e, 0x9102,
-	0x001e, 0x0006, 0x0016, 0x79c4, 0x000e, 0x9103, 0x78c6, 0x000e,
-	0x78ca, 0x9284, 0x1984, 0x9085, 0x0012, 0x7816, 0x2079, 0x0090,
-	0x782b, 0x0008, 0x7057, 0x0000, 0x00fe, 0x0005, 0x00f6, 0x00e6,
-	0x2071, 0x19e6, 0x7054, 0x9086, 0x0000, 0x0904, 0x1e7c, 0x2079,
-	0x0090, 0x2009, 0x0207, 0x210c, 0xd194, 0x01b8, 0x2009, 0x020c,
-	0x210c, 0x9184, 0x0003, 0x0188, 0x080c, 0xe8a3, 0x2001, 0x0133,
-	0x2004, 0x9005, 0x090c, 0x0d7d, 0x0016, 0x2009, 0x0040, 0x080c,
-	0x220a, 0x001e, 0x2001, 0x020c, 0x2102, 0x2009, 0x0206, 0x2104,
-	0x2009, 0x0203, 0x210c, 0x9106, 0x1120, 0x2009, 0x0040, 0x080c,
-	0x220a, 0x782c, 0xd0fc, 0x09a8, 0x080c, 0xa93a, 0x782c, 0xd0fc,
-	0x1de8, 0x080c, 0xa91e, 0x7054, 0x9086, 0x0000, 0x1950, 0x782b,
-	0x0004, 0x782c, 0xd0ac, 0x1de8, 0x2009, 0x0040, 0x080c, 0x220a,
-	0x782b, 0x0002, 0x7057, 0x0000, 0x00ee, 0x00fe, 0x0005, 0x080c,
-	0x0d7d, 0x8c60, 0x2c05, 0x9005, 0x0110, 0x8a51, 0x0005, 0xa004,
-	0x9005, 0x0168, 0xa85a, 0x2040, 0xa064, 0x9084, 0x000f, 0x9080,
-	0x1eab, 0x2065, 0x8cff, 0x090c, 0x0d7d, 0x8a51, 0x0005, 0x2050,
-	0x0005, 0x0000, 0x001d, 0x0021, 0x0025, 0x0029, 0x002d, 0x0031,
-	0x0035, 0x0000, 0x001b, 0x0021, 0x0027, 0x002d, 0x0033, 0x0000,
-	0x0000, 0x0023, 0x0000, 0x0000, 0x1e9e, 0x1e9a, 0x1e9e, 0x1e9e,
-	0x1ea8, 0x0000, 0x1e9e, 0x1ea5, 0x1ea5, 0x1ea2, 0x1ea5, 0x1ea5,
-	0x0000, 0x1ea8, 0x1ea5, 0x0000, 0x1ea0, 0x1ea0, 0x0000, 0x1ea0,
-	0x1ea8, 0x0000, 0x1ea0, 0x1ea6, 0x1ea6, 0x1ea6, 0x0000, 0x1ea6,
-	0x0000, 0x1ea8, 0x1ea6, 0x00c6, 0x00d6, 0x0086, 0xab42, 0xac3e,
-	0xa888, 0x9055, 0x0904, 0x20aa, 0x2940, 0xa064, 0x90ec, 0x000f,
-	0x9084, 0x00ff, 0x9086, 0x0008, 0x1118, 0x2061, 0x1ea6, 0x00d0,
-	0x9de0, 0x1eab, 0x9d86, 0x0007, 0x0130, 0x9d86, 0x000e, 0x0118,
-	0x9d86, 0x000f, 0x1120, 0xa08c, 0x9422, 0xa090, 0x931b, 0x2c05,
-	0x9065, 0x1140, 0x0310, 0x0804, 0x20aa, 0xa004, 0x9045, 0x0904,
-	0x20aa, 0x08d8, 0x2c05, 0x9005, 0x0904, 0x1f92, 0xdd9c, 0x1904,
-	0x1f4e, 0x908a, 0x0036, 0x1a0c, 0x0d7d, 0x9082, 0x001b, 0x0002,
-	0x1f23, 0x1f23, 0x1f25, 0x1f23, 0x1f23, 0x1f23, 0x1f2b, 0x1f23,
-	0x1f23, 0x1f23, 0x1f31, 0x1f23, 0x1f23, 0x1f23, 0x1f37, 0x1f23,
-	0x1f23, 0x1f23, 0x1f3d, 0x1f23, 0x1f23, 0x1f23, 0x1f43, 0x1f23,
-	0x1f23, 0x1f23, 0x1f49, 0x080c, 0x0d7d, 0xa07c, 0x9422, 0xa080,
-	0x931b, 0x0804, 0x1f88, 0xa08c, 0x9422, 0xa090, 0x931b, 0x0804,
-	0x1f88, 0xa09c, 0x9422, 0xa0a0, 0x931b, 0x0804, 0x1f88, 0xa0ac,
-	0x9422, 0xa0b0, 0x931b, 0x0804, 0x1f88, 0xa0bc, 0x9422, 0xa0c0,
-	0x931b, 0x0804, 0x1f88, 0xa0cc, 0x9422, 0xa0d0, 0x931b, 0x0804,
-	0x1f88, 0xa0dc, 0x9422, 0xa0e0, 0x931b, 0x04d0, 0x908a, 0x0034,
-	0x1a0c, 0x0d7d, 0x9082, 0x001b, 0x0002, 0x1f70, 0x1f6e, 0x1f6e,
-	0x1f6e, 0x1f6e, 0x1f6e, 0x1f75, 0x1f6e, 0x1f6e, 0x1f6e, 0x1f6e,
-	0x1f6e, 0x1f7a, 0x1f6e, 0x1f6e, 0x1f6e, 0x1f6e, 0x1f6e, 0x1f7f,
-	0x1f6e, 0x1f6e, 0x1f6e, 0x1f6e, 0x1f6e, 0x1f84, 0x080c, 0x0d7d,
-	0xa07c, 0x9422, 0xa080, 0x931b, 0x0098, 0xa094, 0x9422, 0xa098,
-	0x931b, 0x0070, 0xa0ac, 0x9422, 0xa0b0, 0x931b, 0x0048, 0xa0c4,
-	0x9422, 0xa0c8, 0x931b, 0x0020, 0xa0dc, 0x9422, 0xa0e0, 0x931b,
-	0x0630, 0x2300, 0x9405, 0x0160, 0x8a51, 0x0904, 0x20aa, 0x8c60,
-	0x0804, 0x1efa, 0xa004, 0x9045, 0x0904, 0x20aa, 0x0804, 0x1ed5,
-	0x8a51, 0x0904, 0x20aa, 0x8c60, 0x2c05, 0x9005, 0x1158, 0xa004,
-	0x9045, 0x0904, 0x20aa, 0xa064, 0x90ec, 0x000f, 0x9de0, 0x1eab,
-	0x2c05, 0x2060, 0xa880, 0xc0fc, 0xa882, 0x0804, 0x209f, 0x2c05,
-	0x8422, 0x8420, 0x831a, 0x9399, 0x0000, 0xac2e, 0xab32, 0xdd9c,
-	0x1904, 0x203c, 0x9082, 0x001b, 0x0002, 0x1fd8, 0x1fd8, 0x1fda,
-	0x1fd8, 0x1fd8, 0x1fd8, 0x1fe8, 0x1fd8, 0x1fd8, 0x1fd8, 0x1ff6,
-	0x1fd8, 0x1fd8, 0x1fd8, 0x2004, 0x1fd8, 0x1fd8, 0x1fd8, 0x2012,
-	0x1fd8, 0x1fd8, 0x1fd8, 0x2020, 0x1fd8, 0x1fd8, 0x1fd8, 0x202e,
-	0x080c, 0x0d7d, 0xa17c, 0x2400, 0x9122, 0xa180, 0x2300, 0x911b,
-	0x0a0c, 0x0d7d, 0xa074, 0x9420, 0xa078, 0x9319, 0x0804, 0x209a,
-	0xa18c, 0x2400, 0x9122, 0xa190, 0x2300, 0x911b, 0x0a0c, 0x0d7d,
-	0xa084, 0x9420, 0xa088, 0x9319, 0x0804, 0x209a, 0xa19c, 0x2400,
-	0x9122, 0xa1a0, 0x2300, 0x911b, 0x0a0c, 0x0d7d, 0xa094, 0x9420,
-	0xa098, 0x9319, 0x0804, 0x209a, 0xa1ac, 0x2400, 0x9122, 0xa1b0,
-	0x2300, 0x911b, 0x0a0c, 0x0d7d, 0xa0a4, 0x9420, 0xa0a8, 0x9319,
-	0x0804, 0x209a, 0xa1bc, 0x2400, 0x9122, 0xa1c0, 0x2300, 0x911b,
-	0x0a0c, 0x0d7d, 0xa0b4, 0x9420, 0xa0b8, 0x9319, 0x0804, 0x209a,
-	0xa1cc, 0x2400, 0x9122, 0xa1d0, 0x2300, 0x911b, 0x0a0c, 0x0d7d,
-	0xa0c4, 0x9420, 0xa0c8, 0x9319, 0x0804, 0x209a, 0xa1dc, 0x2400,
-	0x9122, 0xa1e0, 0x2300, 0x911b, 0x0a0c, 0x0d7d, 0xa0d4, 0x9420,
-	0xa0d8, 0x9319, 0x0804, 0x209a, 0x9082, 0x001b, 0x0002, 0x205a,
-	0x2058, 0x2058, 0x2058, 0x2058, 0x2058, 0x2067, 0x2058, 0x2058,
-	0x2058, 0x2058, 0x2058, 0x2074, 0x2058, 0x2058, 0x2058, 0x2058,
-	0x2058, 0x2081, 0x2058, 0x2058, 0x2058, 0x2058, 0x2058, 0x208e,
-	0x080c, 0x0d7d, 0xa17c, 0x2400, 0x9122, 0xa180, 0x2300, 0x911b,
-	0x0a0c, 0x0d7d, 0xa06c, 0x9420, 0xa070, 0x9319, 0x0498, 0xa194,
-	0x2400, 0x9122, 0xa198, 0x2300, 0x911b, 0x0a0c, 0x0d7d, 0xa084,
-	0x9420, 0xa088, 0x9319, 0x0430, 0xa1ac, 0x2400, 0x9122, 0xa1b0,
-	0x2300, 0x911b, 0x0a0c, 0x0d7d, 0xa09c, 0x9420, 0xa0a0, 0x9319,
-	0x00c8, 0xa1c4, 0x2400, 0x9122, 0xa1c8, 0x2300, 0x911b, 0x0a0c,
-	0x0d7d, 0xa0b4, 0x9420, 0xa0b8, 0x9319, 0x0060, 0xa1dc, 0x2400,
-	0x9122, 0xa1e0, 0x2300, 0x911b, 0x0a0c, 0x0d7d, 0xa0cc, 0x9420,
-	0xa0d0, 0x9319, 0xac1e, 0xab22, 0xa880, 0xc0fd, 0xa882, 0x2800,
-	0xa85a, 0x2c00, 0xa812, 0x2a00, 0xa816, 0x000e, 0x000e, 0x000e,
-	0x9006, 0x0028, 0x008e, 0x00de, 0x00ce, 0x9085, 0x0001, 0x0005,
-	0x00c6, 0x610c, 0x0016, 0x9026, 0x2410, 0x6004, 0x9420, 0x9291,
-	0x0000, 0x2c04, 0x9210, 0x9ce0, 0x0002, 0x918a, 0x0002, 0x1da8,
-	0x9284, 0x000f, 0x9405, 0x001e, 0x00ce, 0x0005, 0x7803, 0x0003,
-	0x780f, 0x0000, 0x6004, 0x7812, 0x2c04, 0x7816, 0x9ce0, 0x0002,
-	0x918a, 0x0002, 0x1db8, 0x0005, 0x2001, 0x0005, 0x2004, 0xd0bc,
-	0x190c, 0x0d76, 0xd094, 0x0110, 0x080c, 0x11f6, 0x0005, 0x0126,
-	0x2091, 0x2600, 0x2079, 0x0200, 0x2071, 0x0260, 0x2069, 0x1800,
-	0x7817, 0x0000, 0x789b, 0x0814, 0x78a3, 0x0406, 0x789f, 0x0410,
-	0x2009, 0x013b, 0x200b, 0x0400, 0x781b, 0x0002, 0x783b, 0x001f,
-	0x7837, 0x0020, 0x7803, 0x1600, 0x012e, 0x0005, 0x2091, 0x2600,
-	0x781c, 0xd0a4, 0x190c, 0x2207, 0x7900, 0xd1dc, 0x1118, 0x9084,
-	0x0006, 0x001a, 0x9084, 0x000e, 0x0002, 0x2125, 0x211d, 0x7f45,
-	0x211d, 0x211f, 0x211f, 0x211f, 0x211f, 0x7f2b, 0x211d, 0x2121,
-	0x211d, 0x211f, 0x211d, 0x211f, 0x211d, 0x080c, 0x0d7d, 0x0031,
-	0x0020, 0x080c, 0x7f2b, 0x080c, 0x7f45, 0x0005, 0x0006, 0x0016,
-	0x0026, 0x080c, 0xe8a3, 0x7930, 0x9184, 0x0003, 0x0510, 0x080c,
-	0xa91e, 0x2001, 0x19f9, 0x2004, 0x9005, 0x01a0, 0x2001, 0x0133,
-	0x2004, 0x9005, 0x090c, 0x0d7d, 0x00c6, 0x2001, 0x19f9, 0x2064,
-	0x080c, 0xa93a, 0x080c, 0xc566, 0x2009, 0x0040, 0x080c, 0x220a,
-	0x00ce, 0x0408, 0x2009, 0x0040, 0x080c, 0x220a, 0x080c, 0xa93a,
-	0x00d0, 0x9184, 0x0014, 0x01a0, 0x6a00, 0x9286, 0x0003, 0x0160,
-	0x080c, 0x753d, 0x1138, 0x080c, 0x7840, 0x080c, 0x6092, 0x080c,
-	0x746e, 0x0010, 0x080c, 0x5f4d, 0x080c, 0x7fe3, 0x0041, 0x0018,
-	0x9184, 0x9540, 0x1dc8, 0x002e, 0x001e, 0x000e, 0x0005, 0x00e6,
-	0x0036, 0x0046, 0x0056, 0x2071, 0x1a6a, 0x080c, 0x1b10, 0x005e,
-	0x004e, 0x003e, 0x00ee, 0x0005, 0x0126, 0x2091, 0x2e00, 0x2071,
-	0x1800, 0x7128, 0x2001, 0x196e, 0x2102, 0x2001, 0x1976, 0x2102,
-	0x2001, 0x013b, 0x2102, 0x2079, 0x0200, 0x2001, 0x0201, 0x789e,
-	0x78a3, 0x0200, 0x9198, 0x0007, 0x831c, 0x831c, 0x831c, 0x9398,
-	0x0005, 0x2320, 0x9182, 0x0204, 0x1230, 0x2011, 0x0008, 0x8423,
-	0x8423, 0x8423, 0x0488, 0x9182, 0x024c, 0x1240, 0x2011, 0x0007,
-	0x8403, 0x8003, 0x9400, 0x9400, 0x9420, 0x0430, 0x9182, 0x02bc,
-	0x1238, 0x2011, 0x0006, 0x8403, 0x8003, 0x9400, 0x9420, 0x00e0,
-	0x9182, 0x034c, 0x1230, 0x2011, 0x0005, 0x8403, 0x8003, 0x9420,
-	0x0098, 0x9182, 0x042c, 0x1228, 0x2011, 0x0004, 0x8423, 0x8423,
-	0x0058, 0x9182, 0x059c, 0x1228, 0x2011, 0x0003, 0x8403, 0x9420,
-	0x0018, 0x2011, 0x0002, 0x8423, 0x9482, 0x0228, 0x8002, 0x8020,
-	0x8301, 0x9402, 0x0110, 0x0208, 0x8321, 0x8217, 0x8203, 0x9405,
-	0x789a, 0x012e, 0x0005, 0x0006, 0x00d6, 0x2069, 0x0200, 0x6814,
-	0x9084, 0xffc0, 0x910d, 0x6916, 0x00de, 0x000e, 0x0005, 0x00d6,
-	0x2069, 0x0200, 0x9005, 0x6810, 0x0110, 0xc0a5, 0x0008, 0xc0a4,
-	0x6812, 0x00de, 0x0005, 0x0006, 0x00d6, 0x2069, 0x0200, 0x6810,
-	0x9084, 0xfff8, 0x910d, 0x6912, 0x00de, 0x000e, 0x0005, 0x7938,
-	0x080c, 0x0d76, 0x00f6, 0x2079, 0x0200, 0x7902, 0xa001, 0xa001,
-	0xa001, 0xa001, 0xa001, 0xa001, 0x7902, 0xa001, 0xa001, 0xa001,
-	0xa001, 0xa001, 0xa001, 0x00fe, 0x0005, 0x0126, 0x2091, 0x2800,
-	0x2061, 0x0100, 0x2071, 0x1800, 0x2009, 0x0000, 0x080c, 0x2a66,
-	0x080c, 0x297c, 0x2001, 0x199c, 0x2003, 0x0700, 0x2001, 0x199d,
-	0x2003, 0x0700, 0x080c, 0x2ad7, 0x9006, 0x080c, 0x29ab, 0x9006,
-	0x080c, 0x298e, 0x20a9, 0x0012, 0x1d04, 0x223c, 0x2091, 0x6000,
-	0x1f04, 0x223c, 0x602f, 0x0100, 0x602f, 0x0000, 0x6050, 0x9085,
-	0x0400, 0x9084, 0xdfff, 0x6052, 0x6224, 0x080c, 0x2ab4, 0x080c,
-	0x269a, 0x2009, 0x00ef, 0x6132, 0x6136, 0x080c, 0x26aa, 0x60e7,
-	0x0000, 0x61ea, 0x60e3, 0x0008, 0x604b, 0xf7f7, 0x6043, 0x0000,
-	0x602f, 0x0080, 0x602f, 0x0000, 0x6007, 0x349f, 0x00c6, 0x2061,
-	0x0140, 0x608b, 0x000b, 0x608f, 0x10b8, 0x6093, 0x0000, 0x6097,
-	0x0198, 0x00ce, 0x6004, 0x9085, 0x8000, 0x6006, 0x60bb, 0x0000,
-	0x20a9, 0x0018, 0x60bf, 0x0000, 0x1f04, 0x227a, 0x60bb, 0x0000,
-	0x60bf, 0x0108, 0x60bf, 0x0012, 0x60bf, 0x0405, 0x60bf, 0x0014,
-	0x60bf, 0x0320, 0x60bf, 0x0018, 0x601b, 0x00f0, 0x601f, 0x001e,
-	0x600f, 0x006b, 0x602b, 0x402c, 0x012e, 0x0005, 0x00f6, 0x2079,
-	0x0140, 0x78c3, 0x0080, 0x78c3, 0x0083, 0x78c3, 0x0000, 0x00fe,
-	0x0005, 0x2001, 0x1835, 0x2003, 0x0000, 0x2001, 0x1834, 0x2003,
-	0x0001, 0x0005, 0x0126, 0x2091, 0x2800, 0x0006, 0x0016, 0x0026,
-	0x6124, 0x6028, 0x910c, 0x0066, 0x2031, 0x1837, 0x2634, 0x96b4,
-	0x0028, 0x006e, 0x1138, 0x6020, 0xd1bc, 0x0120, 0xd0bc, 0x1168,
-	0xd0b4, 0x1198, 0x9184, 0x5e2c, 0x1118, 0x9184, 0x0007, 0x00aa,
-	0x9195, 0x0004, 0x9284, 0x0007, 0x0082, 0x0016, 0x2001, 0x0387,
-	0x200c, 0xd1a4, 0x001e, 0x0d70, 0x0c98, 0x0016, 0x2001, 0x0387,
-	0x200c, 0xd1b4, 0x001e, 0x0d30, 0x0c58, 0x22e8, 0x22e5, 0x22e5,
-	0x22e5, 0x22e7, 0x22e5, 0x22e5, 0x22e5, 0x080c, 0x0d7d, 0x0029,
-	0x002e, 0x001e, 0x000e, 0x012e, 0x0005, 0x00a6, 0x6124, 0x6028,
-	0xd09c, 0x0118, 0xd19c, 0x1904, 0x2562, 0xd1f4, 0x190c, 0x0d76,
-	0x080c, 0x753d, 0x0904, 0x2345, 0x080c, 0xd09b, 0x1120, 0x7000,
-	0x9086, 0x0003, 0x0580, 0x6024, 0x9084, 0x1800, 0x0560, 0x080c,
-	0x7560, 0x0118, 0x080c, 0x754e, 0x1530, 0x2011, 0x0020, 0x080c,
-	0x2ab4, 0x6043, 0x0000, 0x080c, 0xd09b, 0x0168, 0x080c, 0x7560,
-	0x1150, 0x2001, 0x19a6, 0x2003, 0x0001, 0x6027, 0x1800, 0x080c,
-	0x73b3, 0x0804, 0x2565, 0x70a4, 0x9005, 0x1150, 0x70a7, 0x0001,
-	0x00d6, 0x2069, 0x0140, 0x080c, 0x7594, 0x00de, 0x1904, 0x2565,
-	0x080c, 0x784a, 0x0428, 0x080c, 0x7560, 0x1590, 0x6024, 0x9084,
-	0x1800, 0x1108, 0x0468, 0x080c, 0x784a, 0x080c, 0x7840, 0x080c,
-	0x6092, 0x080c, 0x746e, 0x0804, 0x2562, 0xd1ac, 0x1508, 0x6024,
-	0xd0dc, 0x1170, 0xd0e4, 0x1178, 0xd0d4, 0x1190, 0xd0cc, 0x0130,
-	0x7098, 0x9086, 0x0028, 0x1110, 0x080c, 0x7721, 0x0804, 0x2562,
-	0x080c, 0x7845, 0x0048, 0x2001, 0x197c, 0x2003, 0x0002, 0x0020,
-	0x080c, 0x767e, 0x0804, 0x2562, 0x080c, 0x77c4, 0x0804, 0x2562,
-	0x6220, 0xd1bc, 0x0138, 0xd2bc, 0x1904, 0x25cb, 0xd2b4, 0x1904,
-	0x25dd, 0x0000, 0xd1ac, 0x0904, 0x246f, 0x0036, 0x6328, 0xc3bc,
-	0x632a, 0x003e, 0x080c, 0x753d, 0x11d0, 0x2011, 0x0020, 0x080c,
-	0x2ab4, 0x0006, 0x0026, 0x0036, 0x080c, 0x7557, 0x1158, 0x080c,
-	0x7840, 0x080c, 0x6092, 0x080c, 0x746e, 0x003e, 0x002e, 0x000e,
-	0x00ae, 0x0005, 0x003e, 0x002e, 0x000e, 0x080c, 0x7511, 0x0016,
-	0x0046, 0x00c6, 0x644c, 0x9486, 0xf0f0, 0x1138, 0x2061, 0x0100,
-	0x644a, 0x6043, 0x0090, 0x6043, 0x0010, 0x74da, 0x948c, 0xff00,
-	0x7038, 0xd084, 0x0178, 0x9186, 0xf800, 0x1160, 0x7048, 0xd084,
-	0x1148, 0xc085, 0x704a, 0x0036, 0x2418, 0x2011, 0x8016, 0x080c,
-	0x4b52, 0x003e, 0x080c, 0xd094, 0x1904, 0x2446, 0x9196, 0xff00,
-	0x05a8, 0x7060, 0x9084, 0x00ff, 0x810f, 0x81ff, 0x0110, 0x9116,
-	0x0568, 0x7130, 0xd184, 0x1550, 0x080c, 0x33ad, 0x0128, 0xc18d,
-	0x7132, 0x080c, 0x6ad5, 0x1510, 0x6240, 0x9294, 0x0010, 0x0130,
-	0x6248, 0x9294, 0xff00, 0x9296, 0xff00, 0x01c0, 0x7030, 0xd08c,
-	0x0904, 0x2446, 0x7038, 0xd08c, 0x1140, 0x2001, 0x180c, 0x200c,
-	0xd1ac, 0x1904, 0x2446, 0xc1ad, 0x2102, 0x0036, 0x73d8, 0x2011,
-	0x8013, 0x080c, 0x4b52, 0x003e, 0x0804, 0x2446, 0x7038, 0xd08c,
-	0x1140, 0x2001, 0x180c, 0x200c, 0xd1ac, 0x1904, 0x2446, 0xc1ad,
-	0x2102, 0x0036, 0x73d8, 0x2011, 0x8013, 0x080c, 0x4b52, 0x003e,
-	0x7130, 0xc185, 0x7132, 0x2011, 0x1848, 0x220c, 0xd1a4, 0x01f0,
-	0x0016, 0x2009, 0x0001, 0x2011, 0x0100, 0x080c, 0x8979, 0x2019,
-	0x000e, 0x00c6, 0x2061, 0x0000, 0x080c, 0xe3b5, 0x00ce, 0x9484,
-	0x00ff, 0x9080, 0x33b9, 0x200d, 0x918c, 0xff00, 0x810f, 0x2120,
-	0x9006, 0x2009, 0x000e, 0x080c, 0xe445, 0x001e, 0x0016, 0x2009,
-	0x0002, 0x2019, 0x0004, 0x080c, 0x3205, 0x001e, 0x0078, 0x0156,
-	0x00b6, 0x20a9, 0x007f, 0x900e, 0x080c, 0x6693, 0x1110, 0x080c,
-	0x60ac, 0x8108, 0x1f04, 0x243c, 0x00be, 0x015e, 0x00ce, 0x004e,
-	0x080c, 0xa91e, 0x080c, 0xabe9, 0x080c, 0xa93a, 0x60e3, 0x0000,
-	0x001e, 0x2001, 0x1800, 0x2014, 0x9296, 0x0004, 0x1170, 0xd19c,
-	0x11b0, 0x2011, 0x180c, 0x2214, 0xd29c, 0x1120, 0x6204, 0x9295,
-	0x0002, 0x6206, 0x6228, 0xc29d, 0x622a, 0x2003, 0x0001, 0x2001,
-	0x1826, 0x2003, 0x0000, 0x2011, 0x0020, 0x080c, 0x2ab4, 0xd194,
-	0x0904, 0x2562, 0x0016, 0x080c, 0xa91e, 0x6220, 0xd2b4, 0x0904,
-	0x24fd, 0x080c, 0x8780, 0x080c, 0x9ed4, 0x2011, 0x0004, 0x080c,
-	0x2ab4, 0x00f6, 0x2019, 0x19f2, 0x2304, 0x907d, 0x0904, 0x24ca,
-	0x7804, 0x9086, 0x0032, 0x15f0, 0x00d6, 0x00c6, 0x00e6, 0x0096,
-	0x2069, 0x0140, 0x782c, 0x685e, 0x7808, 0x685a, 0x6043, 0x0002,
-	0x2001, 0x0003, 0x8001, 0x1df0, 0x6043, 0x0000, 0x2001, 0x003c,
-	0x8001, 0x1df0, 0x080c, 0x2a8a, 0x2001, 0x001e, 0x8001, 0x0240,
-	0x20a9, 0x0009, 0x080c, 0x2a41, 0x6904, 0xd1dc, 0x1140, 0x0cb0,
-	0x2001, 0x0100, 0x080c, 0x2a7a, 0x9006, 0x080c, 0x2a7a, 0x080c,
-	0x967a, 0x080c, 0xa93a, 0x7814, 0x2048, 0xa867, 0x0103, 0x2f60,
-	0x080c, 0xacb0, 0x009e, 0x00ee, 0x00ce, 0x00de, 0x00fe, 0x001e,
-	0x00ae, 0x0005, 0x00fe, 0x00d6, 0x2069, 0x0140, 0x6804, 0x9084,
-	0x4000, 0x0110, 0x080c, 0x2a8a, 0x00de, 0x00c6, 0x2061, 0x19e6,
-	0x6034, 0x080c, 0xd09b, 0x0120, 0x909a, 0x0003, 0x1258, 0x0018,
-	0x909a, 0x00c8, 0x1238, 0x8000, 0x6036, 0x00ce, 0x080c, 0x9eac,
-	0x0804, 0x255f, 0x2061, 0x0100, 0x62c0, 0x080c, 0xa84f, 0x2019,
-	0x19f2, 0x2304, 0x9065, 0x0130, 0x6003, 0x0001, 0x2009, 0x0027,
-	0x080c, 0xad4d, 0x00ce, 0x0804, 0x255f, 0xd2bc, 0x0904, 0x2542,
-	0x080c, 0x878d, 0x2011, 0x0004, 0x080c, 0x2ab4, 0x00d6, 0x2069,
-	0x0140, 0x6804, 0x9084, 0x4000, 0x0110, 0x080c, 0x2a8a, 0x00de,
-	0x00c6, 0x2061, 0x19e6, 0x6050, 0x080c, 0xd09b, 0x0120, 0x909a,
-	0x0003, 0x1668, 0x0018, 0x909a, 0x00c8, 0x1648, 0x8000, 0x6052,
-	0x604c, 0x00ce, 0x9005, 0x05d8, 0x2009, 0x07d0, 0x080c, 0x8785,
-	0x9080, 0x0008, 0x2004, 0x9086, 0x0006, 0x1138, 0x2009, 0x1984,
-	0x2011, 0x0012, 0x080c, 0x2ac3, 0x0450, 0x9080, 0x0008, 0x2004,
-	0x9086, 0x0009, 0x0d98, 0x2009, 0x1984, 0x2011, 0x0016, 0x080c,
-	0x2ac3, 0x00e8, 0x2011, 0x0004, 0x080c, 0x2ab4, 0x00c0, 0x0036,
-	0x2019, 0x0001, 0x080c, 0xa1b8, 0x003e, 0x2019, 0x19f9, 0x2304,
-	0x9065, 0x0160, 0x2009, 0x004f, 0x6020, 0x9086, 0x0009, 0x1110,
-	0x2009, 0x004f, 0x6003, 0x0003, 0x080c, 0xad4d, 0x00ce, 0x080c,
-	0xa93a, 0x001e, 0xd19c, 0x0904, 0x25c4, 0x7038, 0xd0ac, 0x1558,
-	0x0016, 0x0156, 0x2011, 0x0008, 0x080c, 0x2ab4, 0x080c, 0x2ad7,
-	0x080c, 0x2b0a, 0x6050, 0xc0e5, 0x6052, 0x20a9, 0x0367, 0x1f04,
-	0x2591, 0x1d04, 0x2579, 0x080c, 0x87b4, 0x6020, 0xd09c, 0x1db8,
-	0x00f6, 0x2079, 0x0100, 0x080c, 0x29ed, 0x00fe, 0x1d80, 0x6050,
-	0xc0e4, 0x6052, 0x2011, 0x0008, 0x080c, 0x2ab4, 0x015e, 0x001e,
-	0x0498, 0x015e, 0x001e, 0x0016, 0x6028, 0xc09c, 0x602a, 0x080c,
-	0xa91e, 0x080c, 0xabe9, 0x080c, 0xa93a, 0x60e3, 0x0000, 0x080c,
-	0xe882, 0x080c, 0xe89d, 0x080c, 0x5742, 0xd0fc, 0x1138, 0x080c,
-	0xd094, 0x1120, 0x9085, 0x0001, 0x080c, 0x7584, 0x9006, 0x080c,
-	0x2a7a, 0x2009, 0x0002, 0x080c, 0x2a66, 0x00e6, 0x2071, 0x1800,
-	0x7003, 0x0004, 0x080c, 0x0ec1, 0x00ee, 0x2011, 0x0008, 0x080c,
-	0x2ab4, 0x080c, 0x0bc3, 0x001e, 0x918c, 0xffd0, 0x2110, 0x080c,
-	0x2ab4, 0x00ae, 0x0005, 0x0016, 0x2001, 0x0387, 0x200c, 0xd1a4,
-	0x001e, 0x0904, 0x2372, 0x0016, 0x2009, 0x25d7, 0x00c0, 0x2001,
-	0x0387, 0x2003, 0x1000, 0x001e, 0x0c38, 0x0016, 0x2001, 0x0387,
-	0x200c, 0xd1b4, 0x001e, 0x0904, 0x2372, 0x0016, 0x2009, 0x25e9,
-	0x0030, 0x2001, 0x0387, 0x2003, 0x4000, 0x001e, 0x08a8, 0x6028,
-	0xc0bc, 0x602a, 0x2001, 0x0156, 0x2003, 0xbc91, 0x8000, 0x2003,
-	0xffff, 0x6043, 0x0001, 0x080c, 0x2a60, 0x2011, 0x0080, 0x080c,
-	0x2ab4, 0x6017, 0x0000, 0x6043, 0x0000, 0x0817, 0x0006, 0x0016,
-	0x0026, 0x0036, 0x00e6, 0x00f6, 0x0126, 0x2091, 0x8000, 0x2071,
-	0x1800, 0x71d0, 0x70d2, 0x9116, 0x0904, 0x2659, 0x81ff, 0x01a0,
-	0x2009, 0x0000, 0x080c, 0x2a66, 0x2011, 0x8011, 0x2019, 0x010e,
-	0x231c, 0x939e, 0x0007, 0x1118, 0x2019, 0x0001, 0x0010, 0x2019,
-	0x0000, 0x080c, 0x4b52, 0x0468, 0x2001, 0x19a7, 0x200c, 0x81ff,
-	0x1140, 0x2001, 0x0109, 0x2004, 0xd0b4, 0x0118, 0x2019, 0x0003,
-	0x0008, 0x2118, 0x2011, 0x8012, 0x080c, 0x4b52, 0x080c, 0x0ec1,
-	0x080c, 0x5742, 0xd0fc, 0x11a8, 0x080c, 0xd094, 0x1190, 0x00c6,
-	0x080c, 0x26f5, 0x080c, 0xa91e, 0x080c, 0xa113, 0x080c, 0xa93a,
-	0x2061, 0x0100, 0x2019, 0x0028, 0x2009, 0x0002, 0x080c, 0x3205,
-	0x00ce, 0x012e, 0x00fe, 0x00ee, 0x003e, 0x002e, 0x001e, 0x000e,
-	0x0005, 0x2028, 0x918c, 0x00ff, 0x2130, 0x9094, 0xff00, 0x11f0,
-	0x2011, 0x1837, 0x2214, 0xd2ac, 0x11c8, 0x81ff, 0x01e8, 0x2011,
-	0x181f, 0x2204, 0x9106, 0x1190, 0x2011, 0x1820, 0x2214, 0x9294,
-	0xff00, 0x9584, 0xff00, 0x9206, 0x1148, 0x2011, 0x1820, 0x2214,
-	0x9294, 0x00ff, 0x9584, 0x00ff, 0x9206, 0x1120, 0x2500, 0x080c,
-	0x8256, 0x0048, 0x9584, 0x00ff, 0x9080, 0x33b9, 0x200d, 0x918c,
-	0xff00, 0x810f, 0x9006, 0x0005, 0x9080, 0x33b9, 0x200d, 0x918c,
-	0x00ff, 0x0005, 0x00d6, 0x2069, 0x0140, 0x2001, 0x1818, 0x2003,
-	0x00ef, 0x20a9, 0x0010, 0x9006, 0x6852, 0x6856, 0x1f04, 0x26a5,
-	0x00de, 0x0005, 0x0006, 0x00d6, 0x0026, 0x2069, 0x0140, 0x2001,
-	0x1818, 0x2102, 0x8114, 0x8214, 0x8214, 0x8214, 0x20a9, 0x0010,
-	0x6853, 0x0000, 0x9006, 0x82ff, 0x1128, 0x9184, 0x000f, 0x9080,
-	0xe8b1, 0x2005, 0x6856, 0x8211, 0x1f04, 0x26ba, 0x002e, 0x00de,
-	0x000e, 0x0005, 0x00c6, 0x2061, 0x1800, 0x6030, 0x0110, 0xc09d,
-	0x0008, 0xc09c, 0x6032, 0x00ce, 0x0005, 0x0156, 0x00d6, 0x0026,
-	0x0016, 0x0006, 0x2069, 0x0140, 0x6980, 0x9116, 0x0180, 0x9112,
-	0x1230, 0x8212, 0x8210, 0x22a8, 0x2001, 0x0402, 0x0018, 0x22a8,
-	0x2001, 0x0404, 0x680e, 0x1f04, 0x26ea, 0x680f, 0x0000, 0x000e,
-	0x001e, 0x002e, 0x00de, 0x015e, 0x0005, 0x080c, 0x573e, 0xd0c4,
-	0x0150, 0xd0a4, 0x0140, 0x9006, 0x0046, 0x2020, 0x2009, 0x002e,
-	0x080c, 0xe445, 0x004e, 0x0005, 0x00f6, 0x0016, 0x0026, 0x2079,
-	0x0140, 0x78c4, 0xd0dc, 0x0904, 0x2761, 0x080c, 0x29dd, 0x0660,
-	0x9084, 0x0700, 0x908e, 0x0600, 0x1120, 0x2011, 0x4000, 0x900e,
-	0x0458, 0x908e, 0x0500, 0x1120, 0x2011, 0x8000, 0x900e, 0x0420,
-	0x908e, 0x0400, 0x1120, 0x9016, 0x2009, 0x0001, 0x00e8, 0x908e,
-	0x0300, 0x1120, 0x9016, 0x2009, 0x0002, 0x00b0, 0x908e, 0x0200,
-	0x1120, 0x9016, 0x2009, 0x0004, 0x0078, 0x908e, 0x0100, 0x1548,
-	0x9016, 0x2009, 0x0008, 0x0040, 0x9084, 0x0700, 0x908e, 0x0300,
-	0x1500, 0x2011, 0x0030, 0x0058, 0x2300, 0x9080, 0x0020, 0x2018,
-	0x080c, 0x91f8, 0x928c, 0xff00, 0x0110, 0x2011, 0x00ff, 0x2200,
-	0x8007, 0x9085, 0x004c, 0x78c2, 0x2009, 0x0138, 0x220a, 0x080c,
-	0x753d, 0x1118, 0x2009, 0x196c, 0x220a, 0x002e, 0x001e, 0x00fe,
-	0x0005, 0x78c3, 0x0000, 0x0cc8, 0x0126, 0x2091, 0x2800, 0x0006,
-	0x0016, 0x0026, 0x2001, 0x0170, 0x200c, 0x8000, 0x2014, 0x9184,
-	0x0003, 0x0110, 0x080c, 0x0d76, 0x002e, 0x001e, 0x000e, 0x012e,
-	0x0005, 0x2001, 0x0171, 0x2004, 0xd0dc, 0x0168, 0x2001, 0x0170,
-	0x200c, 0x918c, 0x00ff, 0x918e, 0x004c, 0x1128, 0x200c, 0x918c,
-	0xff00, 0x810f, 0x0005, 0x900e, 0x2001, 0x0227, 0x2004, 0x8007,
-	0x9084, 0x00ff, 0x8004, 0x9108, 0x2001, 0x0226, 0x2004, 0x8007,
-	0x9084, 0x00ff, 0x8004, 0x9108, 0x0005, 0x0018, 0x000c, 0x0018,
-	0x0020, 0x1000, 0x0800, 0x1000, 0x1800, 0x0156, 0x0006, 0x0016,
-	0x0026, 0x00e6, 0x2001, 0x198f, 0x2004, 0x908a, 0x0007, 0x1a0c,
-	0x0d7d, 0x0033, 0x00ee, 0x002e, 0x001e, 0x000e, 0x015e, 0x0005,
-	0x27bf, 0x27dd, 0x2801, 0x2803, 0x282c, 0x282e, 0x2830, 0x2001,
-	0x0001, 0x080c, 0x2606, 0x080c, 0x2a2b, 0x2001, 0x1991, 0x2003,
-	0x0000, 0x7828, 0x9084, 0xe1d7, 0x782a, 0x9006, 0x20a9, 0x0009,
-	0x080c, 0x29f9, 0x2001, 0x198f, 0x2003, 0x0006, 0x2009, 0x001e,
-	0x2011, 0x2831, 0x080c, 0x8792, 0x0005, 0x2009, 0x1994, 0x200b,
-	0x0000, 0x2001, 0x1999, 0x2003, 0x0036, 0x2001, 0x1998, 0x2003,
-	0x002a, 0x2001, 0x1991, 0x2003, 0x0001, 0x9006, 0x080c, 0x298e,
-	0x2001, 0xffff, 0x20a9, 0x0009, 0x080c, 0x29f9, 0x2001, 0x198f,
-	0x2003, 0x0006, 0x2009, 0x001e, 0x2011, 0x2831, 0x080c, 0x8792,
-	0x0005, 0x080c, 0x0d7d, 0x2001, 0x1999, 0x2003, 0x0036, 0x2001,
-	0x1991, 0x2003, 0x0003, 0x7a38, 0x9294, 0x0005, 0x9296, 0x0004,
-	0x0110, 0x9006, 0x0010, 0x2001, 0x0001, 0x080c, 0x298e, 0x2001,
-	0x1995, 0x2003, 0x0000, 0x2001, 0xffff, 0x20a9, 0x0009, 0x080c,
-	0x29f9, 0x2001, 0x198f, 0x2003, 0x0006, 0x2009, 0x001e, 0x2011,
-	0x2831, 0x080c, 0x8792, 0x0005, 0x080c, 0x0d7d, 0x080c, 0x0d7d,
-	0x0005, 0x0006, 0x0016, 0x0026, 0x00e6, 0x00f6, 0x0156, 0x0126,
-	0x2091, 0x8000, 0x2079, 0x0100, 0x2001, 0x1991, 0x2004, 0x908a,
-	0x0007, 0x1a0c, 0x0d7d, 0x0043, 0x012e, 0x015e, 0x00fe, 0x00ee,
-	0x002e, 0x001e, 0x000e, 0x0005, 0x2853, 0x2873, 0x28b3, 0x28e3,
-	0x2907, 0x2917, 0x2919, 0x080c, 0x29ed, 0x11b0, 0x7850, 0x9084,
-	0xefff, 0x7852, 0x2009, 0x1997, 0x2104, 0x7a38, 0x9294, 0x0005,
-	0x9296, 0x0004, 0x0110, 0xc08d, 0x0008, 0xc085, 0x200a, 0x2001,
-	0x198f, 0x2003, 0x0001, 0x0030, 0x080c, 0x293d, 0x2001, 0xffff,
-	0x080c, 0x27ce, 0x0005, 0x080c, 0x291b, 0x05e0, 0x2009, 0x1998,
-	0x2104, 0x8001, 0x200a, 0x080c, 0x29ed, 0x1178, 0x7850, 0x9084,
-	0xefff, 0x7852, 0x7a38, 0x9294, 0x0005, 0x9296, 0x0005, 0x0518,
-	0x2009, 0x1997, 0x2104, 0xc085, 0x200a, 0x2009, 0x1994, 0x2104,
-	0x8000, 0x200a, 0x9086, 0x0005, 0x0118, 0x080c, 0x2923, 0x00c0,
-	0x200b, 0x0000, 0x7a38, 0x9294, 0x0006, 0x9296, 0x0004, 0x0110,
-	0x9006, 0x0010, 0x2001, 0x0001, 0x080c, 0x29ab, 0x2001, 0x1991,
-	0x2003, 0x0002, 0x0028, 0x2001, 0x198f, 0x2003, 0x0003, 0x0010,
-	0x080c, 0x27f0, 0x0005, 0x080c, 0x291b, 0x0560, 0x2009, 0x1998,
-	0x2104, 0x8001, 0x200a, 0x080c, 0x29ed, 0x1168, 0x7850, 0x9084,
-	0xefff, 0x7852, 0x2001, 0x198f, 0x2003, 0x0003, 0x2001, 0x1990,
-	0x2003, 0x0000, 0x00b8, 0x2009, 0x1998, 0x2104, 0x9005, 0x1118,
-	0x080c, 0x2960, 0x0010, 0x080c, 0x2930, 0x080c, 0x2923, 0x2009,
-	0x1994, 0x200b, 0x0000, 0x2001, 0x1991, 0x2003, 0x0001, 0x080c,
-	0x27f0, 0x0000, 0x0005, 0x04b9, 0x0508, 0x080c, 0x29ed, 0x11b8,
-	0x7850, 0x9084, 0xefff, 0x7852, 0x2009, 0x1995, 0x2104, 0x8000,
-	0x200a, 0x9086, 0x0007, 0x0108, 0x0078, 0x2001, 0x199a, 0x2003,
-	0x000a, 0x2009, 0x1997, 0x2104, 0xc0fd, 0x200a, 0x0038, 0x0419,
-	0x2001, 0x1991, 0x2003, 0x0004, 0x080c, 0x281b, 0x0005, 0x0099,
-	0x0168, 0x080c, 0x29ed, 0x1138, 0x7850, 0x9084, 0xefff, 0x7852,
-	0x080c, 0x2807, 0x0018, 0x0079, 0x080c, 0x281b, 0x0005, 0x080c,
-	0x0d7d, 0x080c, 0x0d7d, 0x2009, 0x1999, 0x2104, 0x8001, 0x200a,
-	0x090c, 0x297c, 0x0005, 0x7a38, 0x9294, 0x0005, 0x9296, 0x0005,
-	0x0110, 0x9006, 0x0010, 0x2001, 0x0001, 0x080c, 0x29ab, 0x0005,
-	0x7a38, 0x9294, 0x0006, 0x9296, 0x0006, 0x0110, 0x9006, 0x0010,
-	0x2001, 0x0001, 0x080c, 0x298e, 0x0005, 0x2009, 0x1994, 0x2104,
-	0x8000, 0x200a, 0x9086, 0x0005, 0x0108, 0x0068, 0x200b, 0x0000,
-	0x7a38, 0x9294, 0x0006, 0x9296, 0x0006, 0x0110, 0x9006, 0x0010,
-	0x2001, 0x0001, 0x04d9, 0x7a38, 0x9294, 0x0005, 0x9296, 0x0005,
-	0x0110, 0x9006, 0x0010, 0x2001, 0x0001, 0x080c, 0x29ab, 0x0005,
-	0x0086, 0x2001, 0x1997, 0x2004, 0x9084, 0x7fff, 0x090c, 0x0d7d,
-	0x2009, 0x1996, 0x2144, 0x8846, 0x280a, 0x9844, 0x0dd8, 0xd08c,
-	0x1120, 0xd084, 0x1120, 0x080c, 0x0d7d, 0x9006, 0x0010, 0x2001,
-	0x0001, 0x00a1, 0x008e, 0x0005, 0x0006, 0x0156, 0x2001, 0x198f,
-	0x20a9, 0x0009, 0x2003, 0x0000, 0x8000, 0x1f04, 0x2982, 0x2001,
-	0x1996, 0x2003, 0x8000, 0x015e, 0x000e, 0x0005, 0x00f6, 0x2079,
-	0x0100, 0x9085, 0x0000, 0x0158, 0x7838, 0x9084, 0xfff9, 0x9085,
-	0x0004, 0x783a, 0x2009, 0x199c, 0x210c, 0x795a, 0x0050, 0x7838,
-	0x9084, 0xfffb, 0x9085, 0x0006, 0x783a, 0x2009, 0x199d, 0x210c,
-	0x795a, 0x00fe, 0x0005, 0x00f6, 0x2079, 0x0100, 0x9085, 0x0000,
-	0x0158, 0x7838, 0x9084, 0xfffa, 0x9085, 0x0004, 0x783a, 0x7850,
-	0x9084, 0xfff0, 0x7852, 0x00f8, 0x7838, 0x9084, 0xfffb, 0x9085,
-	0x0005, 0x783a, 0x7850, 0x9084, 0xfff0, 0x0016, 0x2009, 0x017f,
-	0x210c, 0x918e, 0x0005, 0x0140, 0x2009, 0x0003, 0x210c, 0x918c,
-	0x0600, 0x918e, 0x0400, 0x0118, 0x9085, 0x000a, 0x0010, 0x9085,
-	0x0000, 0x001e, 0x7852, 0x00fe, 0x0005, 0x0006, 0x2001, 0x0100,
-	0x2004, 0x9082, 0x0007, 0x000e, 0x0005, 0x0006, 0x2001, 0x0100,
-	0x2004, 0x9082, 0x0009, 0x000e, 0x0005, 0x0156, 0x20a9, 0x0064,
-	0x7820, 0x080c, 0x2a60, 0xd09c, 0x1110, 0x1f04, 0x29f0, 0x015e,
-	0x0005, 0x0126, 0x0016, 0x0006, 0x2091, 0x8000, 0x080c, 0x2ad7,
-	0x080c, 0x2b0a, 0x000e, 0x2008, 0x9186, 0x0000, 0x1118, 0x783b,
-	0x0007, 0x0090, 0x9186, 0x0001, 0x1118, 0x783b, 0x0006, 0x0060,
-	0x9186, 0x0002, 0x1118, 0x783b, 0x0005, 0x0030, 0x9186, 0x0003,
-	0x1118, 0x783b, 0x0004, 0x0000, 0x0006, 0x1d04, 0x2a1d, 0x080c,
-	0x87b4, 0x1f04, 0x2a1d, 0x7850, 0x9085, 0x1000, 0x7852, 0x000e,
-	0x001e, 0x012e, 0x0005, 0x080c, 0x2b0a, 0x0005, 0x0006, 0x0156,
-	0x00f6, 0x2079, 0x0100, 0x20a9, 0x000a, 0x7854, 0xd0ac, 0x1100,
-	0x7854, 0xd08c, 0x1110, 0x1f04, 0x2a38, 0x00fe, 0x015e, 0x000e,
-	0x0005, 0x1d04, 0x2a41, 0x080c, 0x87b4, 0x1f04, 0x2a41, 0x0005,
-	0x0006, 0x2001, 0x199b, 0x2004, 0x9086, 0x0000, 0x000e, 0x0005,
-	0x0006, 0x2001, 0x199b, 0x2004, 0x9086, 0x0001, 0x000e, 0x0005,
-	0x0006, 0x2001, 0x199b, 0x2004, 0x9086, 0x0002, 0x000e, 0x0005,
-	0xa001, 0xa001, 0xa001, 0xa001, 0xa001, 0x0005, 0x0006, 0x2001,
-	0x19a7, 0x2102, 0x000e, 0x0005, 0x2009, 0x0171, 0x2104, 0xd0dc,
-	0x0140, 0x2009, 0x0170, 0x2104, 0x200b, 0x0080, 0xa001, 0xa001,
-	0x200a, 0x0005, 0x0016, 0x0026, 0x080c, 0x7557, 0x0108, 0xc0bc,
-	0x2009, 0x0140, 0x2114, 0x9294, 0x0001, 0x9215, 0x220a, 0x002e,
-	0x001e, 0x0005, 0x0016, 0x0026, 0x2009, 0x0140, 0x2114, 0x9294,
-	0x0001, 0x9285, 0x1000, 0x200a, 0x220a, 0x002e, 0x001e, 0x0005,
-	0x0016, 0x0026, 0x2009, 0x0140, 0x2114, 0x9294, 0x0001, 0x9215,
-	0x220a, 0x002e, 0x001e, 0x0005, 0x0006, 0x0016, 0x2009, 0x0140,
-	0x2104, 0x1128, 0x080c, 0x7557, 0x0110, 0xc0bc, 0x0008, 0xc0bd,
-	0x200a, 0x001e, 0x000e, 0x0005, 0x00f6, 0x2079, 0x0380, 0x7843,
-	0x0101, 0x7844, 0xd084, 0x1de8, 0x2001, 0x0109, 0x2202, 0x7843,
-	0x0100, 0x00fe, 0x0005, 0x00f6, 0x2079, 0x0380, 0x7843, 0x0202,
-	0x7844, 0xd08c, 0x1de8, 0x2079, 0x0100, 0x7814, 0x9104, 0x9205,
-	0x7a16, 0x2079, 0x0380, 0x7843, 0x0200, 0x00fe, 0x0005, 0x0016,
-	0x0026, 0x0036, 0x00c6, 0x2061, 0x0100, 0x6050, 0x9084, 0xfbff,
-	0x9085, 0x0040, 0x6052, 0x20a9, 0x0002, 0x080c, 0x2a41, 0x6050,
-	0x9085, 0x0400, 0x9084, 0xff9f, 0x6052, 0x20a9, 0x0005, 0x080c,
-	0x2a41, 0x6054, 0xd0bc, 0x090c, 0x0d7d, 0x20a9, 0x0005, 0x080c,
-	0x2a41, 0x6054, 0xd0ac, 0x090c, 0x0d7d, 0x2009, 0x19ae, 0x9084,
-	0x7e00, 0x8007, 0x8004, 0x8004, 0x200a, 0x00ce, 0x003e, 0x002e,
-	0x001e, 0x0005, 0x0006, 0x00c6, 0x2061, 0x0100, 0x6050, 0xc0cd,
-	0x6052, 0x00ce, 0x000e, 0x0005, 0x3010, 0x3010, 0x2c14, 0x2c14,
-	0x2c20, 0x2c20, 0x2c2c, 0x2c2c, 0x2c3a, 0x2c3a, 0x2c46, 0x2c46,
-	0x2c54, 0x2c54, 0x2c62, 0x2c62, 0x2c74, 0x2c74, 0x2c80, 0x2c80,
-	0x2c8e, 0x2c8e, 0x2cac, 0x2cac, 0x2ccc, 0x2ccc, 0x2c9c, 0x2c9c,
-	0x2cbc, 0x2cbc, 0x2cda, 0x2cda, 0x2c72, 0x2c72, 0x2c72, 0x2c72,
-	0x2c72, 0x2c72, 0x2c72, 0x2c72, 0x2c72, 0x2c72, 0x2c72, 0x2c72,
-	0x2c72, 0x2c72, 0x2c72, 0x2c72, 0x2c72, 0x2c72, 0x2c72, 0x2c72,
-	0x2c72, 0x2c72, 0x2c72, 0x2c72, 0x2c72, 0x2c72, 0x2c72, 0x2c72,
-	0x2c72, 0x2c72, 0x2c72, 0x2c72, 0x2cec, 0x2cec, 0x2cf8, 0x2cf8,
-	0x2d06, 0x2d06, 0x2d14, 0x2d14, 0x2d24, 0x2d24, 0x2d32, 0x2d32,
-	0x2d42, 0x2d42, 0x2d52, 0x2d52, 0x2d64, 0x2d64, 0x2d72, 0x2d72,
-	0x2d82, 0x2d82, 0x2da4, 0x2da4, 0x2dc8, 0x2dc8, 0x2d92, 0x2d92,
-	0x2db6, 0x2db6, 0x2dd8, 0x2dd8, 0x2c72, 0x2c72, 0x2c72, 0x2c72,
-	0x2c72, 0x2c72, 0x2c72, 0x2c72, 0x2c72, 0x2c72, 0x2c72, 0x2c72,
-	0x2c72, 0x2c72, 0x2c72, 0x2c72, 0x2c72, 0x2c72, 0x2c72, 0x2c72,
-	0x2c72, 0x2c72, 0x2c72, 0x2c72, 0x2c72, 0x2c72, 0x2c72, 0x2c72,
-	0x2c72, 0x2c72, 0x2c72, 0x2c72, 0x2dec, 0x2dec, 0x2df8, 0x2df8,
-	0x2e06, 0x2e06, 0x2e14, 0x2e14, 0x2e24, 0x2e24, 0x2e32, 0x2e32,
-	0x2e42, 0x2e42, 0x2e52, 0x2e52, 0x2e64, 0x2e64, 0x2e72, 0x2e72,
-	0x2e82, 0x2e82, 0x2e92, 0x2e92, 0x2ea4, 0x2ea4, 0x2eb4, 0x2eb4,
-	0x2ec6, 0x2ec6, 0x2ed8, 0x2ed8, 0x2c72, 0x2c72, 0x2c72, 0x2c72,
-	0x2c72, 0x2c72, 0x2c72, 0x2c72, 0x2c72, 0x2c72, 0x2c72, 0x2c72,
-	0x2c72, 0x2c72, 0x2c72, 0x2c72, 0x2c72, 0x2c72, 0x2c72, 0x2c72,
-	0x2c72, 0x2c72, 0x2c72, 0x2c72, 0x2c72, 0x2c72, 0x2c72, 0x2c72,
-	0x2c72, 0x2c72, 0x2c72, 0x2c72, 0x2eec, 0x2eec, 0x2efa, 0x2efa,
-	0x2f0a, 0x2f0a, 0x2f1a, 0x2f1a, 0x2f2c, 0x2f2c, 0x2f3c, 0x2f3c,
-	0x2f4e, 0x2f4e, 0x2f60, 0x2f60, 0x2f74, 0x2f74, 0x2f84, 0x2f84,
-	0x2f96, 0x2f96, 0x2fa8, 0x2fa8, 0x2fbc, 0x2fbc, 0x2fcd, 0x2fcd,
-	0x2fe0, 0x2fe0, 0x2ff3, 0x2ff3, 0x2c72, 0x2c72, 0x2c72, 0x2c72,
-	0x2c72, 0x2c72, 0x2c72, 0x2c72, 0x2c72, 0x2c72, 0x2c72, 0x2c72,
-	0x2c72, 0x2c72, 0x2c72, 0x2c72, 0x2c72, 0x2c72, 0x2c72, 0x2c72,
-	0x2c72, 0x2c72, 0x2c72, 0x2c72, 0x2c72, 0x2c72, 0x2c72, 0x2c72,
-	0x2c72, 0x2c72, 0x2c72, 0x2c72, 0x0106, 0x0006, 0x0126, 0x01c6,
-	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x22aa, 0x0804, 0x3008,
+	0x7886, 0x3900, 0x789a, 0x00d6, 0x2069, 0x0300, 0x6818, 0x78ae,
+	0x681c, 0x78b2, 0x6808, 0x78be, 0x00de, 0x7833, 0x0012, 0x2091,
+	0x5000, 0x0156, 0x00d6, 0x0036, 0x0026, 0x2079, 0x0300, 0x2069,
+	0x1b2c, 0x7a08, 0x226a, 0x2069, 0x1b2d, 0x7a18, 0x226a, 0x8d68,
+	0x7a1c, 0x226a, 0x782c, 0x2019, 0x1b3a, 0x201a, 0x2019, 0x1b3d,
+	0x9016, 0x7808, 0xd09c, 0x0168, 0x7820, 0x201a, 0x8210, 0x8318,
+	0x9386, 0x1b56, 0x0108, 0x0ca8, 0x7808, 0xd09c, 0x0110, 0x2011,
+	0xdead, 0x2019, 0x1b3b, 0x782c, 0x201a, 0x8318, 0x221a, 0x7803,
+	0x0000, 0x2069, 0x1a82, 0x901e, 0x20a9, 0x0020, 0x7b26, 0x7a28,
+	0x226a, 0x8d68, 0x8318, 0x1f04, 0x0dde, 0x2069, 0x1aa2, 0x2019,
+	0x0050, 0x20a9, 0x0020, 0x7b26, 0x7a28, 0x226a, 0x8d68, 0x8318,
+	0x1f04, 0x0deb, 0x0491, 0x002e, 0x003e, 0x00de, 0x015e, 0x2079,
+	0x1800, 0x7803, 0x0005, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004,
+	0xd084, 0x0180, 0x2001, 0x1a26, 0x2004, 0x9005, 0x0128, 0x2001,
+	0x008b, 0x2004, 0xd0fc, 0x0dd8, 0x2001, 0x008a, 0x2003, 0x0002,
+	0x2003, 0x1001, 0x080c, 0x5835, 0x1170, 0x080c, 0x0f32, 0x0110,
+	0x080c, 0x0e85, 0x080c, 0x5835, 0x1130, 0x2071, 0x1800, 0x2011,
+	0x8000, 0x080c, 0x0f46, 0x0c70, 0x0005, 0x2001, 0x0382, 0x2004,
+	0x9084, 0x0007, 0x9086, 0x0001, 0x1120, 0x2001, 0x0015, 0x080c,
+	0xaad1, 0x2079, 0x0380, 0x2069, 0x1b0c, 0x7818, 0x6802, 0x781c,
+	0x6806, 0x7840, 0x680a, 0x7844, 0x680e, 0x782c, 0x6812, 0x2019,
+	0x1b17, 0x9016, 0x7808, 0xd09c, 0x0150, 0x7820, 0x201a, 0x8210,
+	0x8318, 0x8210, 0x9282, 0x0011, 0x0ea8, 0x2011, 0xdead, 0x6a2a,
+	0x7830, 0x681a, 0x7834, 0x681e, 0x7838, 0x6822, 0x783c, 0x6826,
+	0x7803, 0x0000, 0x2069, 0x1acc, 0x901e, 0x20a9, 0x0020, 0x7b26,
+	0x7828, 0x206a, 0x8d68, 0x8318, 0x1f04, 0x0e5f, 0x2069, 0x1aec,
+	0x2019, 0x00b0, 0x20a9, 0x0020, 0x7b26, 0x7828, 0x206a, 0x8d68,
+	0x8318, 0x1f04, 0x0e6c, 0x0005, 0x918c, 0x03ff, 0x2001, 0x0003,
+	0x2004, 0x9084, 0x0600, 0x1118, 0x918d, 0x6c00, 0x0010, 0x918d,
+	0x6400, 0x2001, 0x017f, 0x2102, 0x0005, 0x0026, 0x0126, 0x2011,
+	0x0080, 0x080c, 0x0f24, 0x20a9, 0x0900, 0x080c, 0x0f5a, 0x2011,
+	0x0040, 0x080c, 0x0f24, 0x20a9, 0x0900, 0x080c, 0x0f5a, 0x0c78,
+	0x0026, 0x080c, 0x0f32, 0x1188, 0x2011, 0x010e, 0x2214, 0x9294,
+	0x0007, 0x9296, 0x0007, 0x0118, 0x2011, 0x0947, 0x0010, 0x2011,
+	0x1b47, 0x080c, 0x0f46, 0x002e, 0x0005, 0x2011, 0x010e, 0x2214,
+	0x9294, 0x0007, 0x9296, 0x0007, 0x0118, 0x2011, 0xa880, 0x0010,
+	0x2011, 0x6840, 0xd0e4, 0x70f3, 0x0000, 0x1120, 0x70f3, 0x0fa0,
+	0x080c, 0x0f37, 0x002e, 0x0005, 0x0026, 0x080c, 0x0f32, 0x0148,
+	0xd0a4, 0x1138, 0x2011, 0xcdd5, 0x0010, 0x2011, 0x0080, 0x080c,
+	0x0f37, 0x002e, 0x0005, 0x0026, 0x70f3, 0x0000, 0x080c, 0x0f32,
+	0x1130, 0x2011, 0x8040, 0x080c, 0x0f46, 0x002e, 0x0005, 0x080c,
+	0x2a99, 0x1118, 0x2011, 0xcdc5, 0x0010, 0x2011, 0xcac2, 0x080c,
+	0x0f37, 0x002e, 0x0005, 0x00e6, 0x0016, 0x0006, 0x2071, 0x1800,
+	0xd0b4, 0x70ec, 0x71e8, 0x1118, 0xc0e4, 0xc1f4, 0x0050, 0x0006,
+	0x3b00, 0x9084, 0xff3e, 0x20d8, 0x000e, 0x70f3, 0x0000, 0xc0e5,
+	0xc1f5, 0x0099, 0x000e, 0x001e, 0x00ee, 0x0005, 0x00e6, 0x2071,
+	0x1800, 0xd0e4, 0x70ec, 0x1110, 0xc0dc, 0x0008, 0xc0dd, 0x0016,
+	0x71e8, 0x0019, 0x001e, 0x00ee, 0x0005, 0x70ee, 0x71ea, 0x7000,
+	0x9084, 0x0007, 0x000b, 0x0005, 0x0eea, 0x0ec4, 0x0ec4, 0x0e98,
+	0x0ed3, 0x0ec4, 0x0ec4, 0x0ed3, 0xc284, 0x0016, 0x3b08, 0x3a00,
+	0x9104, 0x918d, 0x00c1, 0x21d8, 0x9084, 0xff3e, 0x9205, 0x20d0,
+	0x001e, 0x0005, 0x2001, 0x183b, 0x2004, 0xd0dc, 0x0005, 0x9e86,
+	0x1800, 0x190c, 0x0d85, 0x70ec, 0xd0e4, 0x0108, 0xc2e5, 0x72ee,
+	0xd0e4, 0x1118, 0x9294, 0x00c1, 0x08f9, 0x0005, 0x9e86, 0x1800,
+	0x190c, 0x0d85, 0x70e8, 0xd0f4, 0x0108, 0xc2f5, 0x72ea, 0xd0f4,
+	0x1140, 0x9284, 0x8000, 0x8005, 0xc284, 0x9215, 0x9294, 0x00c1,
+	0x0861, 0x0005, 0x1d04, 0x0f5a, 0x2091, 0x6000, 0x1f04, 0x0f5a,
+	0x0005, 0x890e, 0x810e, 0x810f, 0x9194, 0x003f, 0x918c, 0xffc0,
+	0x0005, 0x0006, 0x2200, 0x914d, 0x894f, 0x894d, 0x894d, 0x000e,
+	0x0005, 0x01d6, 0x0146, 0x0036, 0x0096, 0x2061, 0x188d, 0x600b,
+	0x0000, 0x600f, 0x0000, 0x6003, 0x0000, 0x6007, 0x0000, 0x2009,
+	0xffc0, 0x2105, 0x0006, 0x2001, 0xaaaa, 0x200f, 0x2019, 0x5555,
+	0x9016, 0x2049, 0x0bff, 0xab02, 0xa001, 0xa001, 0xa800, 0x9306,
+	0x1138, 0x2105, 0x9306, 0x0120, 0x8210, 0x99c8, 0x0400, 0x0c98,
+	0x000e, 0x200f, 0x2001, 0x189d, 0x928a, 0x000e, 0x1638, 0x928a,
+	0x0006, 0x2011, 0x0006, 0x1210, 0x2011, 0x0000, 0x2202, 0x9006,
+	0x2008, 0x82ff, 0x01b0, 0x8200, 0x600a, 0x600f, 0xffff, 0x6003,
+	0x0002, 0x6007, 0x0000, 0x0026, 0x2019, 0x0010, 0x9280, 0x0001,
+	0x20e8, 0x21a0, 0x21a8, 0x4104, 0x8319, 0x1de0, 0x8211, 0x1da0,
+	0x002e, 0x009e, 0x003e, 0x014e, 0x01de, 0x0005, 0x2011, 0x000e,
+	0x08e8, 0x0016, 0x0026, 0x0096, 0x3348, 0x080c, 0x0f61, 0x2100,
+	0x9300, 0x2098, 0x22e0, 0x009e, 0x002e, 0x001e, 0x0036, 0x3518,
+	0x20a9, 0x0001, 0x4002, 0x8007, 0x4004, 0x8319, 0x1dd8, 0x003e,
+	0x0005, 0x20e9, 0x0001, 0x71b8, 0x81ff, 0x11c0, 0x9006, 0x2009,
+	0x0200, 0x20a9, 0x0002, 0x9298, 0x0018, 0x23a0, 0x4001, 0x2009,
+	0x0700, 0x20a9, 0x0002, 0x9298, 0x0008, 0x23a0, 0x4001, 0x707c,
+	0x8007, 0x7180, 0x810f, 0x20a9, 0x0002, 0x4001, 0x9298, 0x000c,
+	0x23a0, 0x900e, 0x080c, 0x0d65, 0x2001, 0x0000, 0x810f, 0x20a9,
+	0x0002, 0x4001, 0x0005, 0x89ff, 0x0140, 0xa804, 0xa807, 0x0000,
+	0x0006, 0x080c, 0x108b, 0x009e, 0x0cb0, 0x0005, 0x00e6, 0x2071,
+	0x1800, 0x080c, 0x1104, 0x090c, 0x0d85, 0x00ee, 0x0005, 0x0086,
+	0x00e6, 0x0006, 0x0026, 0x0036, 0x0126, 0x2091, 0x8000, 0x00c9,
+	0x2071, 0x1800, 0x73c0, 0x702c, 0x9016, 0x9045, 0x0158, 0x8210,
+	0x9906, 0x090c, 0x0d85, 0x2300, 0x9202, 0x0120, 0x1a0c, 0x0d85,
+	0xa000, 0x0c98, 0x012e, 0x003e, 0x002e, 0x000e, 0x00ee, 0x008e,
+	0x0005, 0x0086, 0x00e6, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071,
+	0x1910, 0x7010, 0x9005, 0x0140, 0x7018, 0x9045, 0x0128, 0x9906,
+	0x090c, 0x0d85, 0xa000, 0x0cc8, 0x012e, 0x000e, 0x00ee, 0x008e,
+	0x0005, 0x00e6, 0x2071, 0x1800, 0x0126, 0x2091, 0x8000, 0x70c0,
+	0x8001, 0x0270, 0x70c2, 0x702c, 0x2048, 0x9085, 0x0001, 0xa800,
+	0x702e, 0xa803, 0x0000, 0xa807, 0x0000, 0x012e, 0x00ee, 0x0005,
+	0x904e, 0x0cd8, 0x00e6, 0x0126, 0x2091, 0x8000, 0x2071, 0x1800,
+	0x70c0, 0x90ca, 0x0020, 0x0268, 0x8001, 0x70c2, 0x702c, 0x2048,
+	0xa800, 0x702e, 0xa803, 0x0000, 0xa807, 0x0000, 0x012e, 0x00ee,
+	0x0005, 0x904e, 0x0cd8, 0x00e6, 0x0126, 0x2091, 0x8000, 0x0016,
+	0x890e, 0x810e, 0x810f, 0x9184, 0x003f, 0xa862, 0x9184, 0xffc0,
+	0xa85e, 0x001e, 0x0020, 0x00e6, 0x0126, 0x2091, 0x8000, 0x2071,
+	0x1800, 0x702c, 0xa802, 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2,
+	0x080c, 0x873a, 0x012e, 0x00ee, 0x0005, 0x2071, 0x1800, 0x9026,
+	0x2009, 0x0000, 0x2049, 0x0400, 0x2900, 0x702e, 0x8940, 0x2800,
+	0xa802, 0xa95e, 0xa863, 0x0001, 0x8420, 0x9886, 0x0440, 0x0120,
+	0x2848, 0x9188, 0x0040, 0x0c90, 0x2071, 0x188d, 0x7000, 0x9005,
+	0x11a0, 0x2001, 0x0558, 0xa802, 0x2048, 0x2009, 0x5600, 0x8940,
+	0x2800, 0xa802, 0xa95e, 0xa863, 0x0001, 0x8420, 0x9886, 0x0800,
+	0x0120, 0x2848, 0x9188, 0x0040, 0x0c90, 0x2071, 0x188d, 0x7104,
+	0x7200, 0x82ff, 0x01d0, 0x7308, 0x8318, 0x831f, 0x831b, 0x831b,
+	0x7312, 0x8319, 0x2001, 0x0800, 0xa802, 0x2048, 0x8900, 0xa802,
+	0x2040, 0xa95e, 0xaa62, 0x8420, 0x2300, 0x9906, 0x0130, 0x2848,
+	0x9188, 0x0040, 0x9291, 0x0000, 0x0c88, 0xa803, 0x0000, 0x2071,
+	0x1800, 0x74be, 0x74c2, 0x0005, 0x00e6, 0x0016, 0x9984, 0xfc00,
+	0x01e8, 0x908c, 0xf800, 0x1168, 0x9982, 0x0400, 0x02b8, 0x9982,
+	0x0440, 0x0278, 0x9982, 0x0558, 0x0288, 0x9982, 0x0800, 0x1270,
+	0x0040, 0x9982, 0x0800, 0x0250, 0x2071, 0x188d, 0x7010, 0x9902,
+	0x1228, 0x9085, 0x0001, 0x001e, 0x00ee, 0x0005, 0x9006, 0x0cd8,
+	0x00e6, 0x2071, 0x1a25, 0x7007, 0x0000, 0x9006, 0x701e, 0x7022,
+	0x7002, 0x2071, 0x0000, 0x7010, 0x9085, 0x8044, 0x7012, 0x2071,
+	0x0080, 0x9006, 0x702b, 0x0060, 0x20a9, 0x0040, 0x7022, 0x1f04,
+	0x113e, 0x702b, 0x0060, 0x702b, 0x0020, 0x20a9, 0x0040, 0x7022,
+	0x1f04, 0x1147, 0x702b, 0x0020, 0x00ee, 0x0005, 0x0126, 0x2091,
+	0x8000, 0x00e6, 0xa06f, 0x0000, 0x2071, 0x1a25, 0x701c, 0x9088,
+	0x1a2f, 0x280a, 0x8000, 0x9084, 0x003f, 0x701e, 0x7120, 0x9106,
+	0x090c, 0x0d85, 0x7004, 0x9005, 0x1128, 0x00f6, 0x2079, 0x0080,
+	0x00a9, 0x00fe, 0x00ee, 0x012e, 0x0005, 0x0126, 0x2091, 0x8000,
+	0x00e6, 0x2071, 0x1a25, 0x7004, 0x9005, 0x1128, 0x00f6, 0x2079,
+	0x0080, 0x0021, 0x00fe, 0x00ee, 0x012e, 0x0005, 0x7004, 0x9086,
+	0x0000, 0x1110, 0x7007, 0x0006, 0x7000, 0x0002, 0x1190, 0x1313,
+	0x118e, 0x118e, 0x1307, 0x1307, 0x1307, 0x1307, 0x080c, 0x0d85,
+	0x701c, 0x7120, 0x9106, 0x1148, 0x792c, 0x9184, 0x0001, 0x1120,
+	0xd1fc, 0x1110, 0x7007, 0x0000, 0x0005, 0x0096, 0x9180, 0x1a2f,
+	0x2004, 0x700a, 0x2048, 0x8108, 0x918c, 0x003f, 0x7122, 0x782b,
+	0x0026, 0xa88c, 0x7802, 0xa890, 0x7806, 0xa894, 0x780a, 0xa898,
+	0x780e, 0xa878, 0x700e, 0xa870, 0x7016, 0xa874, 0x701a, 0xa868,
+	0x009e, 0xd084, 0x0120, 0x7007, 0x0001, 0x0029, 0x0005, 0x7007,
+	0x0002, 0x00b1, 0x0005, 0x0016, 0x0026, 0x710c, 0x2011, 0x0040,
+	0x9182, 0x0040, 0x1210, 0x2110, 0x9006, 0x700e, 0x7212, 0x8203,
+	0x7812, 0x782b, 0x0020, 0x782b, 0x0041, 0x002e, 0x001e, 0x0005,
+	0x0016, 0x0026, 0x0136, 0x0146, 0x0156, 0x7014, 0x20e0, 0x7018,
+	0x2098, 0x20e9, 0x0000, 0x20a1, 0x0088, 0x782b, 0x0026, 0x710c,
+	0x2011, 0x0040, 0x9182, 0x0040, 0x1210, 0x2110, 0x9006, 0x700e,
+	0x22a8, 0x4006, 0x8203, 0x7812, 0x782b, 0x0020, 0x3300, 0x701a,
+	0x782b, 0x0001, 0x015e, 0x014e, 0x013e, 0x002e, 0x001e, 0x0005,
+	0x2009, 0x1a25, 0x2104, 0xc095, 0x200a, 0x080c, 0x116d, 0x0005,
+	0x0016, 0x00e6, 0x2071, 0x1a25, 0x00f6, 0x2079, 0x0080, 0x792c,
+	0xd1bc, 0x190c, 0x0d7e, 0x782b, 0x0002, 0xd1fc, 0x0120, 0x918c,
+	0x0700, 0x7004, 0x0023, 0x00fe, 0x00ee, 0x001e, 0x0005, 0x117e,
+	0x1226, 0x125a, 0x1332, 0x0d85, 0x134d, 0x0d85, 0x918c, 0x0700,
+	0x1550, 0x0136, 0x0146, 0x0156, 0x7014, 0x20e8, 0x7018, 0x20a0,
+	0x20e1, 0x0000, 0x2099, 0x0088, 0x782b, 0x0040, 0x7010, 0x20a8,
+	0x4005, 0x3400, 0x701a, 0x015e, 0x014e, 0x013e, 0x700c, 0x9005,
+	0x0578, 0x7800, 0x7802, 0x7804, 0x7806, 0x080c, 0x11c3, 0x0005,
+	0x7008, 0x0096, 0x2048, 0xa86f, 0x0100, 0x009e, 0x7007, 0x0000,
+	0x080c, 0x117e, 0x0005, 0x7008, 0x0096, 0x2048, 0xa86f, 0x0200,
+	0x009e, 0x0ca0, 0x918c, 0x0700, 0x1150, 0x700c, 0x9005, 0x0180,
+	0x7800, 0x7802, 0x7804, 0x7806, 0x080c, 0x11d8, 0x0005, 0x7008,
+	0x0096, 0x2048, 0xa86f, 0x0200, 0x009e, 0x7007, 0x0000, 0x0080,
+	0x0096, 0x7008, 0x2048, 0x7800, 0xa88e, 0x7804, 0xa892, 0x7808,
+	0xa896, 0x780c, 0xa89a, 0xa86f, 0x0100, 0x009e, 0x7007, 0x0000,
+	0x0096, 0x00d6, 0x7008, 0x2048, 0x2001, 0x18b9, 0x2004, 0x9906,
+	0x1128, 0xa89c, 0x080f, 0x00de, 0x009e, 0x00a0, 0x00de, 0x009e,
+	0x0096, 0x00d6, 0x7008, 0x2048, 0x0081, 0x0150, 0xa89c, 0x0086,
+	0x2940, 0x080f, 0x008e, 0x00de, 0x009e, 0x080c, 0x116d, 0x0005,
+	0x00de, 0x009e, 0x080c, 0x116d, 0x0005, 0xa8a8, 0xd08c, 0x0005,
+	0x0096, 0xa0a0, 0x904d, 0x090c, 0x0d85, 0xa06c, 0x908e, 0x0100,
+	0x0130, 0xa87b, 0x0030, 0xa883, 0x0000, 0xa897, 0x4002, 0x080c,
+	0x6f0d, 0xa09f, 0x0000, 0xa0a3, 0x0000, 0x2848, 0x080c, 0x108b,
+	0x009e, 0x0005, 0x00a6, 0xa0a0, 0x904d, 0x090c, 0x0d85, 0xa06c,
+	0x908e, 0x0100, 0x0128, 0xa87b, 0x0001, 0xa883, 0x0000, 0x00c0,
+	0xa80c, 0x2050, 0xb004, 0x9005, 0x0198, 0xa80e, 0x2050, 0x8006,
+	0x8006, 0x8007, 0x908c, 0x003f, 0x9084, 0xffc0, 0x9080, 0x0002,
+	0xa076, 0xa172, 0xb000, 0xa07a, 0x2810, 0x080c, 0x114e, 0x00e8,
+	0xa97c, 0xa894, 0x0016, 0x0006, 0x080c, 0x6f0d, 0x000e, 0x001e,
+	0xd1fc, 0x1138, 0xd1f4, 0x0128, 0x00c6, 0x2060, 0x080c, 0xaf2e,
+	0x00ce, 0x7008, 0x2048, 0xa89f, 0x0000, 0xa8a3, 0x0000, 0x080c,
+	0x108b, 0x7007, 0x0000, 0x080c, 0x116d, 0x00ae, 0x0005, 0x0126,
+	0x2091, 0x8000, 0x782b, 0x1001, 0x7007, 0x0005, 0x7000, 0xc094,
+	0x7002, 0x012e, 0x0005, 0x0096, 0x2001, 0x1930, 0x204c, 0xa87c,
+	0x7812, 0xa88c, 0x7802, 0xa890, 0x7806, 0xa894, 0x780a, 0xa898,
+	0x780e, 0x782b, 0x0020, 0x0126, 0x2091, 0x8000, 0x782b, 0x0041,
+	0x7007, 0x0003, 0x7000, 0xc084, 0x7002, 0x2900, 0x700a, 0x012e,
+	0x009e, 0x0005, 0x20e1, 0x0000, 0x2099, 0x0088, 0x782b, 0x0040,
+	0x0096, 0x2001, 0x1930, 0x204c, 0xaa7c, 0x009e, 0x080c, 0x8e26,
+	0x2009, 0x188c, 0x2104, 0x9084, 0xfffc, 0x200a, 0x080c, 0x8c88,
+	0x7007, 0x0000, 0x080c, 0x117e, 0x0005, 0x7007, 0x0000, 0x080c,
+	0x117e, 0x0005, 0x0126, 0x2091, 0x2200, 0x2079, 0x0300, 0x2071,
+	0x1a6f, 0x7003, 0x0000, 0x78bf, 0x00f6, 0x0041, 0x7807, 0x0007,
+	0x7803, 0x0000, 0x7803, 0x0001, 0x012e, 0x0005, 0x00c6, 0x7803,
+	0x0000, 0x2001, 0x0165, 0x2003, 0x4198, 0x7808, 0xd09c, 0x0120,
+	0x7820, 0x080c, 0x13b6, 0x0cc8, 0x2001, 0x1a70, 0x2003, 0x0000,
+	0x78ab, 0x0004, 0x78ac, 0xd0ac, 0x1de8, 0x78ab, 0x0002, 0x7807,
+	0x0007, 0x7827, 0x0030, 0x782b, 0x0400, 0x7827, 0x0031, 0x782b,
+	0x1a82, 0x78e3, 0xff00, 0x781f, 0xff00, 0x781b, 0xff00, 0x2001,
+	0x1a71, 0x2003, 0x0000, 0x2001, 0x0200, 0x2004, 0xd0dc, 0x0110,
+	0x781f, 0x0303, 0x2061, 0x1a82, 0x602f, 0x1ddc, 0x2001, 0x181a,
+	0x2004, 0x9082, 0x1ddc, 0x6032, 0x603b, 0x1ee2, 0x602b, 0x1ac2,
+	0x6007, 0x1aa2, 0x2061, 0x1aa2, 0x606f, 0x193e, 0x2001, 0x1929,
+	0x2004, 0x607a, 0x783f, 0x3489, 0x00ce, 0x0005, 0x9086, 0x000d,
+	0x11d0, 0x7808, 0xd09c, 0x01b8, 0x7820, 0x0026, 0x2010, 0x080c,
+	0xcc04, 0x0180, 0x2260, 0x6000, 0x9086, 0x0004, 0x1158, 0x0016,
+	0x6120, 0x9186, 0x0009, 0x0108, 0x0020, 0x2009, 0x004c, 0x080c,
+	0xafcc, 0x001e, 0x002e, 0x0005, 0x0126, 0x2091, 0x2200, 0x7908,
+	0x9184, 0x0070, 0x190c, 0x0d7e, 0xd19c, 0x05a0, 0x7820, 0x908c,
+	0xf000, 0x0540, 0x2060, 0x6020, 0x9086, 0x0003, 0x1550, 0x6000,
+	0x9086, 0x0004, 0x1530, 0x6114, 0x2148, 0xa876, 0xa87a, 0xa867,
+	0x0103, 0x080c, 0x6d2e, 0x00b6, 0x6010, 0x2058, 0xba3c, 0x8211,
+	0x0208, 0xba3e, 0xb8d0, 0x9005, 0x190c, 0x68b4, 0x00be, 0x6044,
+	0xd0fc, 0x190c, 0xab09, 0x080c, 0xaf57, 0x7808, 0xd09c, 0x19b0,
+	0x012e, 0x0005, 0x908a, 0x0024, 0x1a0c, 0x0d85, 0x002b, 0x012e,
+	0x0005, 0x04b0, 0x012e, 0x0005, 0x1438, 0x145e, 0x148e, 0x1493,
+	0x1497, 0x149c, 0x14c4, 0x14c8, 0x14d6, 0x14da, 0x1438, 0x15a7,
+	0x15ab, 0x161d, 0x1624, 0x1438, 0x1625, 0x1626, 0x1631, 0x1638,
+	0x1438, 0x1438, 0x1438, 0x1438, 0x1438, 0x1438, 0x1438, 0x149e,
+	0x1438, 0x1466, 0x148b, 0x1452, 0x1438, 0x1472, 0x143c, 0x143a,
+	0x080c, 0x0d85, 0x080c, 0x0d7e, 0x080c, 0x1643, 0x2009, 0x1a7e,
+	0x2104, 0x8000, 0x200a, 0x080c, 0x8159, 0x080c, 0x1b47, 0x0005,
+	0x6044, 0xd0fc, 0x190c, 0xab09, 0x2009, 0x0055, 0x080c, 0xafcc,
+	0x012e, 0x0005, 0x080c, 0x1643, 0x2060, 0x6044, 0xd0fc, 0x190c,
+	0xab09, 0x2009, 0x0055, 0x080c, 0xafcc, 0x0005, 0x2009, 0x0048,
+	0x080c, 0x1643, 0x2060, 0x080c, 0xafcc, 0x0005, 0x2009, 0x0054,
+	0x080c, 0x1643, 0x2060, 0x6044, 0xd0fc, 0x190c, 0xab09, 0x080c,
+	0xafcc, 0x0005, 0x080c, 0x1643, 0x2060, 0x0056, 0x0066, 0x080c,
+	0x1643, 0x2028, 0x080c, 0x1643, 0x2030, 0x0036, 0x0046, 0x2021,
+	0x0000, 0x2418, 0x2009, 0x0056, 0x080c, 0xafcc, 0x004e, 0x003e,
+	0x006e, 0x005e, 0x0005, 0x080c, 0x1643, 0x0005, 0x7004, 0xc085,
+	0xc0b5, 0x7006, 0x0005, 0x7004, 0xc085, 0x7006, 0x0005, 0x080c,
+	0x1643, 0x080c, 0x1740, 0x0005, 0x080c, 0x0d85, 0x080c, 0x1643,
+	0x2060, 0x6014, 0x0096, 0x2048, 0xa83b, 0xffff, 0x009e, 0x2009,
+	0x0048, 0x080c, 0xafcc, 0x2001, 0x015d, 0x2003, 0x0000, 0x2009,
+	0x03e8, 0x8109, 0x0160, 0x2001, 0x0201, 0x2004, 0x9005, 0x0dc8,
+	0x2001, 0x0218, 0x2004, 0xd0ec, 0x1110, 0x080c, 0x1648, 0x2001,
+	0x0307, 0x2003, 0x8000, 0x0005, 0x7004, 0xc095, 0x7006, 0x0005,
+	0x080c, 0x1643, 0x2060, 0x6014, 0x0096, 0x2048, 0xa83b, 0xffff,
+	0x009e, 0x2009, 0x0048, 0x080c, 0xafcc, 0x0005, 0x080c, 0x1643,
+	0x080c, 0x0d85, 0x080c, 0x1643, 0x080c, 0x1592, 0x7827, 0x0018,
+	0x79ac, 0xd1dc, 0x0904, 0x1543, 0x7827, 0x0015, 0x7828, 0x782b,
+	0x0000, 0x9065, 0x0140, 0x2001, 0x020d, 0x2003, 0x0050, 0x2003,
+	0x0020, 0x0804, 0x1549, 0x7004, 0x9005, 0x01c8, 0x1188, 0x78ab,
+	0x0004, 0x7827, 0x0018, 0x782b, 0x0000, 0xd1bc, 0x090c, 0x0d85,
+	0x2001, 0x020d, 0x2003, 0x0050, 0x2003, 0x0020, 0x0804, 0x1577,
+	0x78ab, 0x0004, 0x7803, 0x0001, 0x080c, 0x15ab, 0x0005, 0x7827,
+	0x0018, 0xa001, 0x7828, 0x7827, 0x0011, 0xa001, 0x7928, 0x9106,
+	0x0110, 0x79ac, 0x08e0, 0x00e6, 0x2071, 0x0200, 0x702c, 0xd0c4,
+	0x0140, 0x00ee, 0x080c, 0x1b47, 0x080c, 0x1366, 0x7803, 0x0001,
+	0x0005, 0x7037, 0x0001, 0xa001, 0x7150, 0x00ee, 0x918c, 0xff00,
+	0x9186, 0x0500, 0x0110, 0x79ac, 0x0810, 0x7004, 0xc09d, 0x7006,
+	0x78ab, 0x0004, 0x7803, 0x0001, 0x080c, 0x15ab, 0x2001, 0x020d,
+	0x2003, 0x0020, 0x0005, 0x7828, 0x782b, 0x0000, 0x9065, 0x090c,
+	0x0d85, 0x6014, 0x2048, 0x78ab, 0x0004, 0x918c, 0x0700, 0x01a8,
+	0x080c, 0x8159, 0x080c, 0x1b47, 0x080c, 0xcc16, 0x0158, 0xa9ac,
+	0xa936, 0xa9b0, 0xa93a, 0xa83f, 0xffff, 0xa843, 0xffff, 0xa880,
+	0xc0bd, 0xa882, 0x080c, 0xc802, 0x0005, 0x6020, 0x9086, 0x0009,
+	0x1128, 0x2009, 0x004c, 0x080c, 0xafcc, 0x0048, 0x6010, 0x00b6,
+	0x2058, 0xb800, 0x00be, 0xd0bc, 0x6024, 0x190c, 0xd019, 0x2029,
+	0x00c8, 0x8529, 0x0128, 0x2001, 0x0201, 0x2004, 0x9005, 0x0dc8,
+	0x7dbc, 0x080c, 0xeb55, 0xd5a4, 0x1118, 0x080c, 0x1648, 0x0005,
+	0x080c, 0x8159, 0x080c, 0x1b47, 0x0005, 0x781f, 0x0300, 0x7803,
+	0x0001, 0x0005, 0x0016, 0x0066, 0x0076, 0x00f6, 0x2079, 0x0300,
+	0x7908, 0x918c, 0x0007, 0x9186, 0x0003, 0x0120, 0x2001, 0x0016,
+	0x080c, 0x16b9, 0x00fe, 0x007e, 0x006e, 0x001e, 0x0005, 0x7004,
+	0xc09d, 0x7006, 0x0005, 0x7104, 0x9184, 0x0004, 0x190c, 0x0d85,
+	0xd184, 0x11b1, 0xd19c, 0x0180, 0xc19c, 0x7106, 0x0016, 0x080c,
+	0x1723, 0x001e, 0x0148, 0x2001, 0x020d, 0x2003, 0x0050, 0x2003,
+	0x0020, 0x080c, 0x1648, 0x0005, 0x81ff, 0x190c, 0x0d85, 0x0005,
+	0x2100, 0xc184, 0xc1b4, 0x7106, 0xd0b4, 0x0016, 0x00e6, 0x1904,
+	0x1612, 0x2071, 0x0200, 0x080c, 0x1710, 0x05e0, 0x080c, 0x1723,
+	0x05b0, 0x6014, 0x9005, 0x05b0, 0x0096, 0x2048, 0xa864, 0x009e,
+	0x9084, 0x00ff, 0x908e, 0x0029, 0x0160, 0x908e, 0x0048, 0x1550,
+	0x601c, 0xd084, 0x11e0, 0x00f6, 0x2c78, 0x080c, 0x17ad, 0x00fe,
+	0x00b0, 0x00f6, 0x2c78, 0x080c, 0x1936, 0x00fe, 0x2009, 0x01f4,
+	0x8109, 0x0168, 0x2001, 0x0201, 0x2004, 0x9005, 0x0dc8, 0x2001,
+	0x0218, 0x2004, 0xd0ec, 0x1118, 0x080c, 0x1648, 0x0040, 0x2001,
+	0x020d, 0x2003, 0x0020, 0x080c, 0x1366, 0x7803, 0x0001, 0x00ee,
+	0x001e, 0x0005, 0x080c, 0x1723, 0x0dd0, 0x2001, 0x020d, 0x2003,
+	0x0050, 0x2003, 0x0020, 0x0461, 0x0c90, 0x0429, 0x2060, 0x2009,
+	0x0053, 0x080c, 0xafcc, 0x0005, 0x0005, 0x0005, 0x00e1, 0x2008,
+	0x00d1, 0x0006, 0x7004, 0xc09d, 0x7006, 0x000e, 0x080c, 0x9177,
+	0x0005, 0x0089, 0x9005, 0x0118, 0x080c, 0x8d7a, 0x0cd0, 0x0005,
+	0x2001, 0x0036, 0x2009, 0x1820, 0x210c, 0x2011, 0x181f, 0x2214,
+	0x080c, 0x16b9, 0x0005, 0x7808, 0xd09c, 0x0de8, 0x7820, 0x0005,
+	0x080c, 0x1592, 0x00d6, 0x2069, 0x0200, 0x2009, 0x01f4, 0x8109,
+	0x0510, 0x6804, 0x9005, 0x0dd8, 0x2001, 0x015d, 0x2003, 0x0000,
+	0x79bc, 0xd1a4, 0x1528, 0x79b8, 0x918c, 0x0fff, 0x0180, 0x9182,
+	0x0841, 0x1268, 0x9188, 0x0007, 0x918c, 0x0ff8, 0x810c, 0x810c,
+	0x810c, 0x080c, 0x16ab, 0x6827, 0x0001, 0x8109, 0x1dd0, 0x04d9,
+	0x6827, 0x0002, 0x04c1, 0x6804, 0x9005, 0x1130, 0x682c, 0xd0e4,
+	0x1500, 0x6804, 0x9005, 0x0de8, 0x79b8, 0xd1ec, 0x1130, 0x08c0,
+	0x080c, 0x8159, 0x080c, 0x1b47, 0x0090, 0x7827, 0x0015, 0x782b,
+	0x0000, 0x7827, 0x0018, 0x782b, 0x0000, 0x2001, 0x020d, 0x2003,
+	0x0020, 0x2001, 0x0307, 0x2003, 0x0300, 0x7803, 0x0001, 0x00de,
+	0x0005, 0x682c, 0x9084, 0x5400, 0x9086, 0x5400, 0x0d30, 0x7827,
+	0x0015, 0x782b, 0x0000, 0x7803, 0x0001, 0x6800, 0x9085, 0x1800,
+	0x6802, 0x00de, 0x0005, 0x6824, 0x9084, 0x0003, 0x1de0, 0x0005,
+	0x2001, 0x0030, 0x2c08, 0x621c, 0x0021, 0x7830, 0x9086, 0x0041,
+	0x0005, 0x00f6, 0x00e6, 0x2079, 0x0300, 0x0006, 0x2071, 0x1a6f,
+	0x7008, 0x9005, 0x1110, 0x78e3, 0x0c0c, 0x8000, 0x700a, 0x0026,
+	0x2011, 0x0006, 0x7808, 0xd09c, 0x0150, 0x0016, 0x0026, 0x00c6,
+	0x080c, 0x13d4, 0x00ce, 0x002e, 0x001e, 0x8211, 0x1d98, 0x002e,
+	0x000e, 0x0006, 0x7832, 0x7936, 0x7a3a, 0x781b, 0x8080, 0x00b9,
+	0x1178, 0x2071, 0x1a6f, 0x7008, 0x9005, 0x0130, 0x8001, 0x0a0c,
+	0x0d85, 0x700a, 0x78e3, 0x0c00, 0x000e, 0x00ee, 0x00fe, 0x0005,
+	0x000e, 0x792c, 0x3900, 0x8000, 0x2004, 0x080c, 0x0d85, 0x2009,
+	0xff00, 0x8109, 0x0120, 0x7818, 0xd0bc, 0x1dd8, 0x0005, 0x9085,
+	0x0001, 0x0005, 0x7832, 0x7936, 0x7a3a, 0x781b, 0x8080, 0x0c79,
+	0x1108, 0x0005, 0x792c, 0x3900, 0x8000, 0x2004, 0x080c, 0x0d85,
+	0x7037, 0x0001, 0x7150, 0x7037, 0x0002, 0x7050, 0x2060, 0xd1bc,
+	0x1110, 0x7054, 0x2060, 0x918c, 0xff00, 0x9186, 0x0500, 0x0110,
+	0x9085, 0x0001, 0x0005, 0x0006, 0x0046, 0x00e6, 0x2071, 0x0200,
+	0x7037, 0x0002, 0x7058, 0x9084, 0xff00, 0x8007, 0x9086, 0x00bc,
+	0x1158, 0x2021, 0x1a7f, 0x2404, 0x8000, 0x0208, 0x2022, 0x080c,
+	0x8159, 0x080c, 0x1b47, 0x9006, 0x00ee, 0x004e, 0x000e, 0x0005,
+	0x0c11, 0x1108, 0x0005, 0x00e6, 0x0016, 0x2071, 0x0200, 0x0841,
+	0x6124, 0xd1dc, 0x01f8, 0x701c, 0xd08c, 0x0904, 0x17a2, 0x7017,
+	0x0000, 0x2001, 0x0264, 0x2004, 0xd0bc, 0x0904, 0x17a2, 0x2001,
+	0x0268, 0x00c6, 0x2064, 0x6104, 0x6038, 0x00ce, 0x918e, 0x0039,
+	0x1904, 0x17a2, 0x9c06, 0x15f0, 0x0126, 0x2091, 0x2600, 0x080c,
+	0x80b1, 0x012e, 0x7358, 0x745c, 0x6014, 0x905d, 0x0598, 0x2b48,
+	0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x190c, 0xcff4,
+	0xab42, 0xac3e, 0x2001, 0x1869, 0x2004, 0xd0b4, 0x1170, 0x601c,
+	0xd0e4, 0x1158, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc,
+	0x1120, 0xa83b, 0x7fff, 0xa837, 0xffff, 0x080c, 0x1f02, 0x1190,
+	0x080c, 0x1993, 0x2a00, 0xa816, 0x0130, 0x2800, 0xa80e, 0x2c05,
+	0xa80a, 0x2c00, 0xa812, 0x7037, 0x0020, 0x781f, 0x0300, 0x001e,
+	0x00ee, 0x0005, 0x7037, 0x0050, 0x7037, 0x0020, 0x001e, 0x00ee,
+	0x080c, 0x1648, 0x0005, 0x080c, 0x0d85, 0x2cf0, 0x0126, 0x2091,
+	0x2200, 0x0016, 0x00c6, 0x3e60, 0x6014, 0x2048, 0x2940, 0x903e,
+	0x2730, 0xa864, 0x2068, 0xa81a, 0x9d84, 0x000f, 0x9088, 0x1ee2,
+	0x2165, 0x0002, 0x17d9, 0x1847, 0x17d9, 0x17d9, 0x17dd, 0x1828,
+	0x17d9, 0x17fd, 0x17d2, 0x183e, 0x17d9, 0x17d9, 0x17e2, 0x1934,
+	0x1811, 0x1807, 0xa964, 0x918c, 0x00ff, 0x918e, 0x0048, 0x0904,
+	0x183e, 0x9085, 0x0001, 0x0804, 0x192a, 0xa87c, 0xd0ac, 0x0dc8,
+	0x0804, 0x184e, 0xa87c, 0xd0ac, 0x0da0, 0x0804, 0x18b9, 0xa898,
+	0x901d, 0x1108, 0xab9c, 0x9016, 0xaab2, 0xaa3e, 0xaa42, 0x3e00,
+	0x9080, 0x0008, 0x2004, 0x9080, 0x9347, 0x2005, 0x9005, 0x090c,
+	0x0d85, 0x2004, 0xa8ae, 0x0804, 0x1912, 0xa87c, 0xd0bc, 0x09c8,
+	0xa890, 0xa842, 0xa88c, 0xa83e, 0xa888, 0x0804, 0x184e, 0xa87c,
+	0xd0bc, 0x0978, 0xa890, 0xa842, 0xa88c, 0xa83e, 0xa888, 0x0804,
+	0x18b9, 0xa87c, 0xd0bc, 0x0928, 0xa890, 0xa842, 0xa88c, 0xa83e,
+	0xa804, 0x9045, 0x090c, 0x0d85, 0xa164, 0xa91a, 0x91ec, 0x000f,
+	0x9d80, 0x1ee2, 0x2065, 0xa888, 0xd19c, 0x1904, 0x18b9, 0x0430,
+	0xa87c, 0xd0ac, 0x0904, 0x17d9, 0xa804, 0x9045, 0x090c, 0x0d85,
+	0xa164, 0xa91a, 0x91ec, 0x000f, 0x9d80, 0x1ee2, 0x2065, 0x9006,
+	0xa842, 0xa83e, 0xd19c, 0x1904, 0x18b9, 0x0080, 0xa87c, 0xd0ac,
+	0x0904, 0x17d9, 0x9006, 0xa842, 0xa83e, 0x0804, 0x18b9, 0xa87c,
+	0xd0ac, 0x0904, 0x17d9, 0x9006, 0xa842, 0xa83e, 0x2c05, 0x908a,
+	0x0036, 0x1a0c, 0x0d85, 0x9082, 0x001b, 0x0002, 0x1871, 0x1871,
+	0x1873, 0x1871, 0x1871, 0x1871, 0x187d, 0x1871, 0x1871, 0x1871,
+	0x1887, 0x1871, 0x1871, 0x1871, 0x1891, 0x1871, 0x1871, 0x1871,
+	0x189b, 0x1871, 0x1871, 0x1871, 0x18a5, 0x1871, 0x1871, 0x1871,
+	0x18af, 0x080c, 0x0d85, 0xa574, 0xa478, 0x9d86, 0x0024, 0x0904,
+	0x17e7, 0xa37c, 0xa280, 0x0804, 0x1912, 0xa584, 0xa488, 0x9d86,
+	0x0024, 0x0904, 0x17e7, 0xa38c, 0xa290, 0x0804, 0x1912, 0xa594,
+	0xa498, 0x9d86, 0x0024, 0x0904, 0x17e7, 0xa39c, 0xa2a0, 0x0804,
+	0x1912, 0xa5a4, 0xa4a8, 0x9d86, 0x0024, 0x0904, 0x17e7, 0xa3ac,
+	0xa2b0, 0x0804, 0x1912, 0xa5b4, 0xa4b8, 0x9d86, 0x0024, 0x0904,
+	0x17e7, 0xa3bc, 0xa2c0, 0x0804, 0x1912, 0xa5c4, 0xa4c8, 0x9d86,
+	0x0024, 0x0904, 0x17e7, 0xa3cc, 0xa2d0, 0x0804, 0x1912, 0xa5d4,
+	0xa4d8, 0x9d86, 0x0024, 0x0904, 0x17e7, 0xa3dc, 0xa2e0, 0x0804,
+	0x1912, 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0d85, 0x9082, 0x001b,
+	0x0002, 0x18dc, 0x18da, 0x18da, 0x18da, 0x18da, 0x18da, 0x18e7,
+	0x18da, 0x18da, 0x18da, 0x18da, 0x18da, 0x18f2, 0x18da, 0x18da,
+	0x18da, 0x18da, 0x18da, 0x18fd, 0x18da, 0x18da, 0x18da, 0x18da,
+	0x18da, 0x1908, 0x080c, 0x0d85, 0xa56c, 0xa470, 0xa774, 0xa678,
+	0x9d86, 0x002c, 0x0904, 0x17e7, 0xa37c, 0xa280, 0x0458, 0xa584,
+	0xa488, 0xa78c, 0xa690, 0x9d86, 0x002c, 0x0904, 0x17e7, 0xa394,
+	0xa298, 0x0400, 0xa59c, 0xa4a0, 0xa7a4, 0xa6a8, 0x9d86, 0x002c,
+	0x0904, 0x17e7, 0xa3ac, 0xa2b0, 0x00a8, 0xa5b4, 0xa4b8, 0xa7bc,
+	0xa6c0, 0x9d86, 0x002c, 0x0904, 0x17e7, 0xa3c4, 0xa2c8, 0x0050,
+	0xa5cc, 0xa4d0, 0xa7d4, 0xa6d8, 0x9d86, 0x002c, 0x0904, 0x17e7,
+	0xa3dc, 0xa2e0, 0xab2e, 0xaa32, 0xad1e, 0xac22, 0xaf26, 0xae2a,
+	0xa988, 0x8c60, 0x2c1d, 0xa8ac, 0xaab0, 0xa836, 0xaa3a, 0x8109,
+	0xa916, 0x1160, 0x3e60, 0x601c, 0xc085, 0x601e, 0xa87c, 0xc0dd,
+	0xa87e, 0x9006, 0x00ce, 0x001e, 0x012e, 0x0005, 0x2800, 0xa80e,
+	0xab0a, 0x2c00, 0xa812, 0x0c70, 0x0804, 0x17d9, 0x2ff0, 0x0126,
+	0x2091, 0x2200, 0x0016, 0x00c6, 0x3e60, 0x6014, 0x2048, 0x2940,
+	0xa80e, 0x2061, 0x1edd, 0xa813, 0x1edd, 0x2c05, 0xa80a, 0xa964,
+	0xa91a, 0xa87c, 0xd0ac, 0x090c, 0x0d85, 0x9006, 0xa842, 0xa83e,
+	0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0d85, 0xadcc, 0xacd0, 0xafd4,
+	0xaed8, 0xabdc, 0xaae0, 0xab2e, 0xaa32, 0xad1e, 0xac22, 0xaf26,
+	0xae2a, 0xa8ac, 0xaab0, 0xa836, 0xaa3a, 0xa988, 0xa864, 0x9084,
+	0x00ff, 0x9086, 0x0008, 0x1120, 0x8109, 0xa916, 0x0128, 0x0080,
+	0x918a, 0x0002, 0xa916, 0x1160, 0x3e60, 0x601c, 0xc085, 0x601e,
+	0xa87c, 0xc0dd, 0xa87e, 0x9006, 0x00ce, 0x001e, 0x012e, 0x0005,
+	0xa804, 0x9045, 0x090c, 0x0d85, 0xa80e, 0xa064, 0xa81a, 0x9084,
+	0x000f, 0x9080, 0x1ee2, 0x2015, 0x82ff, 0x090c, 0x0d85, 0xaa12,
+	0x2205, 0xa80a, 0x0c08, 0x903e, 0x2730, 0xa880, 0xd0fc, 0x1190,
+	0x2d00, 0x0002, 0x1abd, 0x19ea, 0x19ea, 0x1abd, 0x19ea, 0x1ab7,
+	0x1abd, 0x19ea, 0x1a5a, 0x1a5a, 0x1a5a, 0x1abd, 0x1a5a, 0x1abd,
+	0x1ab4, 0x1a5a, 0xc0fc, 0xa882, 0xab2c, 0xaa30, 0xad1c, 0xac20,
+	0xdd9c, 0x0904, 0x1abf, 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0d85,
+	0x9082, 0x001b, 0x0002, 0x19d6, 0x19d4, 0x19d4, 0x19d4, 0x19d4,
+	0x19d4, 0x19da, 0x19d4, 0x19d4, 0x19d4, 0x19d4, 0x19d4, 0x19de,
+	0x19d4, 0x19d4, 0x19d4, 0x19d4, 0x19d4, 0x19e2, 0x19d4, 0x19d4,
+	0x19d4, 0x19d4, 0x19d4, 0x19e6, 0x080c, 0x0d85, 0xa774, 0xa678,
+	0x0804, 0x1abf, 0xa78c, 0xa690, 0x0804, 0x1abf, 0xa7a4, 0xa6a8,
+	0x0804, 0x1abf, 0xa7bc, 0xa6c0, 0x0804, 0x1abf, 0xa7d4, 0xa6d8,
+	0x0804, 0x1abf, 0xa898, 0x901d, 0x1108, 0xab9c, 0x9016, 0x2c05,
+	0x908a, 0x0036, 0x1a0c, 0x0d85, 0x9082, 0x001b, 0x0002, 0x1a12,
+	0x1a12, 0x1a14, 0x1a12, 0x1a12, 0x1a12, 0x1a1e, 0x1a12, 0x1a12,
+	0x1a12, 0x1a28, 0x1a12, 0x1a12, 0x1a12, 0x1a32, 0x1a12, 0x1a12,
+	0x1a12, 0x1a3c, 0x1a12, 0x1a12, 0x1a12, 0x1a46, 0x1a12, 0x1a12,
+	0x1a12, 0x1a50, 0x080c, 0x0d85, 0xa574, 0xa478, 0x9d86, 0x0004,
+	0x0904, 0x1abf, 0xa37c, 0xa280, 0x0804, 0x1abf, 0xa584, 0xa488,
+	0x9d86, 0x0004, 0x0904, 0x1abf, 0xa38c, 0xa290, 0x0804, 0x1abf,
+	0xa594, 0xa498, 0x9d86, 0x0004, 0x0904, 0x1abf, 0xa39c, 0xa2a0,
+	0x0804, 0x1abf, 0xa5a4, 0xa4a8, 0x9d86, 0x0004, 0x0904, 0x1abf,
+	0xa3ac, 0xa2b0, 0x0804, 0x1abf, 0xa5b4, 0xa4b8, 0x9d86, 0x0004,
+	0x0904, 0x1abf, 0xa3bc, 0xa2c0, 0x0804, 0x1abf, 0xa5c4, 0xa4c8,
+	0x9d86, 0x0004, 0x0904, 0x1abf, 0xa3cc, 0xa2d0, 0x0804, 0x1abf,
+	0xa5d4, 0xa4d8, 0x9d86, 0x0004, 0x0904, 0x1abf, 0xa3dc, 0xa2e0,
+	0x0804, 0x1abf, 0xa898, 0x901d, 0x1108, 0xab9c, 0x9016, 0x2c05,
+	0x908a, 0x0034, 0x1a0c, 0x0d85, 0x9082, 0x001b, 0x0002, 0x1a82,
+	0x1a80, 0x1a80, 0x1a80, 0x1a80, 0x1a80, 0x1a8c, 0x1a80, 0x1a80,
+	0x1a80, 0x1a80, 0x1a80, 0x1a96, 0x1a80, 0x1a80, 0x1a80, 0x1a80,
+	0x1a80, 0x1aa0, 0x1a80, 0x1a80, 0x1a80, 0x1a80, 0x1a80, 0x1aaa,
+	0x080c, 0x0d85, 0xa56c, 0xa470, 0xa774, 0xa678, 0x9d86, 0x000c,
+	0x05b0, 0xa37c, 0xa280, 0x0498, 0xa584, 0xa488, 0xa78c, 0xa690,
+	0x9d86, 0x000c, 0x0560, 0xa394, 0xa298, 0x0448, 0xa59c, 0xa4a0,
+	0xa7a4, 0xa6a8, 0x9d86, 0x000c, 0x0510, 0xa3ac, 0xa2b0, 0x00f8,
+	0xa5b4, 0xa4b8, 0xa7bc, 0xa6c0, 0x9d86, 0x000c, 0x01c0, 0xa3c4,
+	0xa2c8, 0x00a8, 0xa5cc, 0xa4d0, 0xa7d4, 0xa6d8, 0x9d86, 0x000c,
+	0x0170, 0xa3dc, 0xa2e0, 0x0058, 0x9d86, 0x000e, 0x1130, 0x080c,
+	0x1eb8, 0x1904, 0x1993, 0x900e, 0x0050, 0x080c, 0x0d85, 0xab2e,
+	0xaa32, 0xad1e, 0xac22, 0xaf26, 0xae2a, 0x080c, 0x1eb8, 0x0005,
+	0x6014, 0x2048, 0x6118, 0x81ff, 0x0148, 0x810c, 0x810c, 0x810c,
+	0x81ff, 0x1118, 0xa887, 0x0001, 0x0008, 0xa986, 0x601b, 0x0002,
+	0xa874, 0x9084, 0x00ff, 0x9084, 0x0008, 0x0150, 0x00e9, 0x6000,
+	0x9086, 0x0004, 0x1120, 0x2009, 0x0048, 0x080c, 0xafcc, 0x0005,
+	0xa974, 0xd1dc, 0x1108, 0x0005, 0xa934, 0xa88c, 0x9106, 0x1158,
+	0xa938, 0xa890, 0x9106, 0x1138, 0x601c, 0xc084, 0x601e, 0x2009,
+	0x0048, 0x0804, 0xafcc, 0x0005, 0x0126, 0x00c6, 0x2091, 0x2200,
+	0x00ce, 0x7908, 0x918c, 0x0007, 0x9186, 0x0000, 0x05b0, 0x9186,
+	0x0003, 0x0598, 0x6020, 0x6023, 0x0000, 0x0006, 0x2031, 0x0008,
+	0x00c6, 0x781f, 0x0808, 0x7808, 0xd09c, 0x0120, 0x080c, 0x13d4,
+	0x8631, 0x1db8, 0x00ce, 0x781f, 0x0800, 0x2031, 0x0168, 0x00c6,
+	0x7808, 0xd09c, 0x190c, 0x13d4, 0x00ce, 0x2001, 0x0038, 0x080c,
+	0x1bcf, 0x7930, 0x9186, 0x0040, 0x0160, 0x9186, 0x0042, 0x190c,
+	0x0d85, 0x2001, 0x001e, 0x8001, 0x1df0, 0x8631, 0x1d40, 0x080c,
+	0x1bde, 0x000e, 0x6022, 0x012e, 0x0005, 0x080c, 0x1bcb, 0x7827,
+	0x0015, 0x7828, 0x9c06, 0x1db8, 0x782b, 0x0000, 0x0ca0, 0x00f6,
+	0x2079, 0x0300, 0x7803, 0x0000, 0x78ab, 0x0004, 0x00fe, 0x080c,
+	0x76a5, 0x1188, 0x2001, 0x0138, 0x2003, 0x0000, 0x2001, 0x0160,
+	0x2003, 0x0000, 0x2011, 0x012c, 0xa001, 0xa001, 0x8211, 0x1de0,
+	0x0059, 0x0804, 0x7747, 0x0479, 0x0039, 0x2001, 0x0160, 0x2502,
+	0x2001, 0x0138, 0x2202, 0x0005, 0x00e6, 0x2071, 0x0200, 0x080c,
+	0x2aad, 0x2009, 0x003c, 0x080c, 0x2241, 0x2001, 0x015d, 0x2003,
+	0x0000, 0x7000, 0x9084, 0x003c, 0x1de0, 0x080c, 0x873a, 0x70a0,
+	0x70a2, 0x7098, 0x709a, 0x709c, 0x709e, 0x2001, 0x020d, 0x2003,
+	0x0020, 0x00f6, 0x2079, 0x0300, 0x080c, 0x1366, 0x7803, 0x0001,
+	0x00fe, 0x00ee, 0x0005, 0x2001, 0x0138, 0x2014, 0x2003, 0x0000,
+	0x2001, 0x0160, 0x202c, 0x2003, 0x0000, 0x080c, 0x76a5, 0x1108,
+	0x0005, 0x2021, 0x0260, 0x2001, 0x0141, 0x201c, 0xd3dc, 0x1168,
+	0x2001, 0x0109, 0x201c, 0x939c, 0x0048, 0x1160, 0x2001, 0x0111,
+	0x201c, 0x83ff, 0x1110, 0x8421, 0x1d70, 0x2001, 0x015d, 0x2003,
+	0x0000, 0x0005, 0x0046, 0x2021, 0x0019, 0x2003, 0x0048, 0xa001,
+	0xa001, 0x201c, 0x939c, 0x0048, 0x0120, 0x8421, 0x1db0, 0x004e,
+	0x0c60, 0x004e, 0x0c40, 0x601c, 0xc084, 0x601e, 0x0005, 0x2c08,
+	0x621c, 0x080c, 0x16b9, 0x7930, 0x0005, 0x2c08, 0x621c, 0x080c,
+	0x1702, 0x7930, 0x0005, 0x8001, 0x1df0, 0x0005, 0x2031, 0x0064,
+	0x781c, 0x9084, 0x0007, 0x0170, 0x2001, 0x0038, 0x0c41, 0x9186,
+	0x0040, 0x0904, 0x1c3c, 0x2001, 0x001e, 0x0c69, 0x8631, 0x1d80,
+	0x080c, 0x0d85, 0x781f, 0x0202, 0x2001, 0x015d, 0x2003, 0x0000,
+	0x2001, 0x0dac, 0x0c01, 0x781c, 0xd084, 0x0110, 0x0861, 0x04e0,
+	0x2001, 0x0030, 0x0891, 0x9186, 0x0040, 0x0568, 0x781c, 0xd084,
+	0x1da8, 0x781f, 0x0101, 0x2001, 0x0014, 0x0869, 0x2001, 0x0037,
+	0x0821, 0x9186, 0x0040, 0x0140, 0x2001, 0x0030, 0x080c, 0x1bd5,
+	0x9186, 0x0040, 0x190c, 0x0d85, 0x00d6, 0x2069, 0x0200, 0x692c,
+	0xd1f4, 0x1170, 0xd1c4, 0x0160, 0xd19c, 0x0130, 0x6800, 0x9085,
+	0x1800, 0x6802, 0x00de, 0x0080, 0x6908, 0x9184, 0x0007, 0x1db0,
+	0x00de, 0x781f, 0x0100, 0x791c, 0x9184, 0x0007, 0x090c, 0x0d85,
+	0xa001, 0xa001, 0x781f, 0x0200, 0x0005, 0x0126, 0x2091, 0x2400,
+	0x2079, 0x0380, 0x2001, 0x19e9, 0x2070, 0x012e, 0x0005, 0x2cf0,
+	0x0126, 0x2091, 0x2400, 0x3e60, 0x6014, 0x2048, 0xa964, 0xa91a,
+	0x918c, 0x00ff, 0x9184, 0x000f, 0x0002, 0x1c71, 0x1c71, 0x1c71,
+	0x1c73, 0x1c71, 0x1c71, 0x1c71, 0x1c71, 0x1c65, 0x1c7b, 0x1c71,
+	0x1c77, 0x1c71, 0x1c71, 0x1c71, 0x1c71, 0x9086, 0x0008, 0x1148,
+	0xa87c, 0xd0b4, 0x0904, 0x1deb, 0x2011, 0x1edd, 0x2205, 0xab88,
+	0x00a8, 0x080c, 0x0d85, 0x9186, 0x0013, 0x0128, 0x0cd0, 0x9186,
+	0x001b, 0x0108, 0x0cb0, 0xa87c, 0xd0b4, 0x0904, 0x1deb, 0x9184,
+	0x000f, 0x9080, 0x1ee2, 0x2015, 0x2205, 0xab88, 0x2908, 0xa80a,
+	0xa90e, 0xaa12, 0xab16, 0x9006, 0xa842, 0xa83e, 0x012e, 0x0005,
+	0x2cf0, 0x0126, 0x2091, 0x2400, 0x3e60, 0x6014, 0x2048, 0xa88c,
+	0xa990, 0xaaac, 0xabb0, 0xaa36, 0xab3a, 0xa83e, 0xa942, 0xa846,
+	0xa94a, 0xa964, 0x918c, 0x00ff, 0x9186, 0x001e, 0x0198, 0x2940,
+	0xa064, 0xa81a, 0x90ec, 0x000f, 0x9d80, 0x1ee2, 0x2065, 0x2c05,
+	0x2808, 0x2c10, 0xab88, 0xa80a, 0xa90e, 0xaa12, 0xab16, 0x012e,
+	0x3e60, 0x0005, 0xa804, 0x2040, 0x0c58, 0x2cf0, 0x0126, 0x2091,
+	0x2400, 0x3e60, 0x6014, 0x2048, 0xa97c, 0x2950, 0xd1dc, 0x1904,
+	0x1db5, 0xc1dd, 0xa97e, 0x9006, 0xa842, 0xa83e, 0xa988, 0x8109,
+	0xa916, 0xa964, 0xa91a, 0x9184, 0x000f, 0x9088, 0x1ee2, 0x2145,
+	0x0002, 0x1ce9, 0x1cf7, 0x1ce9, 0x1ce9, 0x1ce9, 0x1ceb, 0x1ce9,
+	0x1ce9, 0x1d4c, 0x1d4c, 0x1ce9, 0x1ce9, 0x1ce9, 0x1d4a, 0x1ce9,
+	0x1ce9, 0x080c, 0x0d85, 0xa804, 0x2050, 0xb164, 0xa91a, 0x9184,
+	0x000f, 0x9080, 0x1ee2, 0x2045, 0xd19c, 0x1904, 0x1d4c, 0x9036,
+	0x2638, 0x2805, 0x908a, 0x0036, 0x1a0c, 0x0d85, 0x9082, 0x001b,
+	0x0002, 0x1d1c, 0x1d1c, 0x1d1e, 0x1d1c, 0x1d1c, 0x1d1c, 0x1d24,
+	0x1d1c, 0x1d1c, 0x1d1c, 0x1d2a, 0x1d1c, 0x1d1c, 0x1d1c, 0x1d30,
+	0x1d1c, 0x1d1c, 0x1d1c, 0x1d36, 0x1d1c, 0x1d1c, 0x1d1c, 0x1d3c,
+	0x1d1c, 0x1d1c, 0x1d1c, 0x1d42, 0x080c, 0x0d85, 0xb574, 0xb478,
+	0xb37c, 0xb280, 0x0804, 0x1d91, 0xb584, 0xb488, 0xb38c, 0xb290,
+	0x0804, 0x1d91, 0xb594, 0xb498, 0xb39c, 0xb2a0, 0x0804, 0x1d91,
+	0xb5a4, 0xb4a8, 0xb3ac, 0xb2b0, 0x0804, 0x1d91, 0xb5b4, 0xb4b8,
+	0xb3bc, 0xb2c0, 0x0804, 0x1d91, 0xb5c4, 0xb4c8, 0xb3cc, 0xb2d0,
+	0x0804, 0x1d91, 0xb5d4, 0xb4d8, 0xb3dc, 0xb2e0, 0x0804, 0x1d91,
+	0x0804, 0x1d91, 0x080c, 0x0d85, 0x2805, 0x908a, 0x0034, 0x1a0c,
+	0x0d85, 0x9082, 0x001b, 0x0002, 0x1d6f, 0x1d6d, 0x1d6d, 0x1d6d,
+	0x1d6d, 0x1d6d, 0x1d76, 0x1d6d, 0x1d6d, 0x1d6d, 0x1d6d, 0x1d6d,
+	0x1d7d, 0x1d6d, 0x1d6d, 0x1d6d, 0x1d6d, 0x1d6d, 0x1d84, 0x1d6d,
+	0x1d6d, 0x1d6d, 0x1d6d, 0x1d6d, 0x1d8b, 0x080c, 0x0d85, 0xb56c,
+	0xb470, 0xb774, 0xb678, 0xb37c, 0xb280, 0x00d8, 0xb584, 0xb488,
+	0xb78c, 0xb690, 0xb394, 0xb298, 0x00a0, 0xb59c, 0xb4a0, 0xb7a4,
+	0xb6a8, 0xb3ac, 0xb2b0, 0x0068, 0xb5b4, 0xb4b8, 0xb7bc, 0xb6c0,
+	0xb3c4, 0xb2c8, 0x0030, 0xb5cc, 0xb4d0, 0xb7d4, 0xb6d8, 0xb3dc,
+	0xb2e0, 0xab2e, 0xaa32, 0xad1e, 0xac22, 0xaf26, 0xae2a, 0xa988,
+	0x8109, 0xa916, 0x1118, 0x9006, 0x012e, 0x0005, 0x8840, 0x2805,
+	0x9005, 0x1168, 0xb004, 0x9005, 0x090c, 0x0d85, 0x2050, 0xb164,
+	0xa91a, 0x9184, 0x000f, 0x9080, 0x1ee2, 0x2045, 0x2805, 0x2810,
+	0x2a08, 0xa80a, 0xa90e, 0xaa12, 0x0c30, 0x3e60, 0x6344, 0xd3fc,
+	0x190c, 0x0d85, 0xa93c, 0xaa40, 0xa844, 0x9106, 0x1118, 0xa848,
+	0x9206, 0x0508, 0x2958, 0xab48, 0xac44, 0x2940, 0x080c, 0x1f02,
+	0x1998, 0x2850, 0x2c40, 0xab14, 0xa880, 0xd0fc, 0x1140, 0xa810,
+	0x2005, 0xa80a, 0x2a00, 0xa80e, 0x2009, 0x8015, 0x0070, 0x00c6,
+	0x3e60, 0x6044, 0xc0a4, 0x9085, 0x8005, 0x6046, 0x00ce, 0x8319,
+	0xab16, 0x1904, 0x1d9e, 0x2009, 0x8005, 0x3e60, 0x6044, 0x9105,
+	0x6046, 0x0804, 0x1d9b, 0x080c, 0x0d85, 0x00f6, 0x00e6, 0x0096,
+	0x00c6, 0x0026, 0x704c, 0x9c06, 0x190c, 0x0d85, 0x2079, 0x0090,
+	0x2001, 0x0105, 0x2003, 0x0010, 0x782b, 0x0004, 0x7057, 0x0000,
+	0x6014, 0x2048, 0x080c, 0xcc16, 0x0118, 0xa880, 0xc0bd, 0xa882,
+	0x6020, 0x9086, 0x0006, 0x1170, 0x2061, 0x0100, 0x62c8, 0x2001,
+	0x00fa, 0x8001, 0x1df0, 0x60c8, 0x9206, 0x1dc0, 0x60c4, 0xa89a,
+	0x60c8, 0xa896, 0x704c, 0x2060, 0x00c6, 0x080c, 0xc802, 0x080c,
+	0xaae0, 0x00ce, 0x704c, 0x9c06, 0x1150, 0x2009, 0x0040, 0x080c,
+	0x2241, 0x080c, 0xa585, 0x2011, 0x0000, 0x080c, 0xa419, 0x002e,
+	0x00ce, 0x009e, 0x00ee, 0x00fe, 0x0005, 0x00f6, 0x2079, 0x0090,
+	0x781c, 0x0006, 0x7818, 0x0006, 0x2079, 0x0100, 0x7a14, 0x9284,
+	0x1984, 0x9085, 0x0012, 0x7816, 0x2019, 0x1000, 0x8319, 0x090c,
+	0x0d85, 0x7820, 0xd0bc, 0x1dd0, 0x79c8, 0x000e, 0x9102, 0x001e,
+	0x0006, 0x0016, 0x79c4, 0x000e, 0x9103, 0x78c6, 0x000e, 0x78ca,
+	0x9284, 0x1984, 0x9085, 0x0012, 0x7816, 0x2079, 0x0090, 0x782b,
+	0x0008, 0x7057, 0x0000, 0x00fe, 0x0005, 0x00f6, 0x00e6, 0x2071,
+	0x19e9, 0x7054, 0x9086, 0x0000, 0x0904, 0x1eb3, 0x2079, 0x0090,
+	0x2009, 0x0207, 0x210c, 0xd194, 0x01b8, 0x2009, 0x020c, 0x210c,
+	0x9184, 0x0003, 0x0188, 0x080c, 0xeb9e, 0x2001, 0x0133, 0x2004,
+	0x9005, 0x090c, 0x0d85, 0x0016, 0x2009, 0x0040, 0x080c, 0x2241,
+	0x001e, 0x2001, 0x020c, 0x2102, 0x2009, 0x0206, 0x2104, 0x2009,
+	0x0203, 0x210c, 0x9106, 0x1120, 0x2009, 0x0040, 0x080c, 0x2241,
+	0x782c, 0xd0fc, 0x09a8, 0x080c, 0xaafc, 0x782c, 0xd0fc, 0x1de8,
+	0x080c, 0xaae0, 0x7054, 0x9086, 0x0000, 0x1950, 0x782b, 0x0004,
+	0x782c, 0xd0ac, 0x1de8, 0x2009, 0x0040, 0x080c, 0x2241, 0x782b,
+	0x0002, 0x7057, 0x0000, 0x00ee, 0x00fe, 0x0005, 0x080c, 0x0d85,
+	0x8c60, 0x2c05, 0x9005, 0x0110, 0x8a51, 0x0005, 0xa004, 0x9005,
+	0x0168, 0xa85a, 0x2040, 0xa064, 0x9084, 0x000f, 0x9080, 0x1ee2,
+	0x2065, 0x8cff, 0x090c, 0x0d85, 0x8a51, 0x0005, 0x2050, 0x0005,
+	0x0000, 0x001d, 0x0021, 0x0025, 0x0029, 0x002d, 0x0031, 0x0035,
+	0x0000, 0x001b, 0x0021, 0x0027, 0x002d, 0x0033, 0x0000, 0x0000,
+	0x0023, 0x0000, 0x0000, 0x1ed5, 0x1ed1, 0x1ed5, 0x1ed5, 0x1edf,
+	0x0000, 0x1ed5, 0x1edc, 0x1edc, 0x1ed9, 0x1edc, 0x1edc, 0x0000,
+	0x1edf, 0x1edc, 0x0000, 0x1ed7, 0x1ed7, 0x0000, 0x1ed7, 0x1edf,
+	0x0000, 0x1ed7, 0x1edd, 0x1edd, 0x1edd, 0x0000, 0x1edd, 0x0000,
+	0x1edf, 0x1edd, 0x00c6, 0x00d6, 0x0086, 0xab42, 0xac3e, 0xa888,
+	0x9055, 0x0904, 0x20e1, 0x2940, 0xa064, 0x90ec, 0x000f, 0x9084,
+	0x00ff, 0x9086, 0x0008, 0x1118, 0x2061, 0x1edd, 0x00d0, 0x9de0,
+	0x1ee2, 0x9d86, 0x0007, 0x0130, 0x9d86, 0x000e, 0x0118, 0x9d86,
+	0x000f, 0x1120, 0xa08c, 0x9422, 0xa090, 0x931b, 0x2c05, 0x9065,
+	0x1140, 0x0310, 0x0804, 0x20e1, 0xa004, 0x9045, 0x0904, 0x20e1,
+	0x08d8, 0x2c05, 0x9005, 0x0904, 0x1fc9, 0xdd9c, 0x1904, 0x1f85,
+	0x908a, 0x0036, 0x1a0c, 0x0d85, 0x9082, 0x001b, 0x0002, 0x1f5a,
+	0x1f5a, 0x1f5c, 0x1f5a, 0x1f5a, 0x1f5a, 0x1f62, 0x1f5a, 0x1f5a,
+	0x1f5a, 0x1f68, 0x1f5a, 0x1f5a, 0x1f5a, 0x1f6e, 0x1f5a, 0x1f5a,
+	0x1f5a, 0x1f74, 0x1f5a, 0x1f5a, 0x1f5a, 0x1f7a, 0x1f5a, 0x1f5a,
+	0x1f5a, 0x1f80, 0x080c, 0x0d85, 0xa07c, 0x9422, 0xa080, 0x931b,
+	0x0804, 0x1fbf, 0xa08c, 0x9422, 0xa090, 0x931b, 0x0804, 0x1fbf,
+	0xa09c, 0x9422, 0xa0a0, 0x931b, 0x0804, 0x1fbf, 0xa0ac, 0x9422,
+	0xa0b0, 0x931b, 0x0804, 0x1fbf, 0xa0bc, 0x9422, 0xa0c0, 0x931b,
+	0x0804, 0x1fbf, 0xa0cc, 0x9422, 0xa0d0, 0x931b, 0x0804, 0x1fbf,
+	0xa0dc, 0x9422, 0xa0e0, 0x931b, 0x04d0, 0x908a, 0x0034, 0x1a0c,
+	0x0d85, 0x9082, 0x001b, 0x0002, 0x1fa7, 0x1fa5, 0x1fa5, 0x1fa5,
+	0x1fa5, 0x1fa5, 0x1fac, 0x1fa5, 0x1fa5, 0x1fa5, 0x1fa5, 0x1fa5,
+	0x1fb1, 0x1fa5, 0x1fa5, 0x1fa5, 0x1fa5, 0x1fa5, 0x1fb6, 0x1fa5,
+	0x1fa5, 0x1fa5, 0x1fa5, 0x1fa5, 0x1fbb, 0x080c, 0x0d85, 0xa07c,
+	0x9422, 0xa080, 0x931b, 0x0098, 0xa094, 0x9422, 0xa098, 0x931b,
+	0x0070, 0xa0ac, 0x9422, 0xa0b0, 0x931b, 0x0048, 0xa0c4, 0x9422,
+	0xa0c8, 0x931b, 0x0020, 0xa0dc, 0x9422, 0xa0e0, 0x931b, 0x0630,
+	0x2300, 0x9405, 0x0160, 0x8a51, 0x0904, 0x20e1, 0x8c60, 0x0804,
+	0x1f31, 0xa004, 0x9045, 0x0904, 0x20e1, 0x0804, 0x1f0c, 0x8a51,
+	0x0904, 0x20e1, 0x8c60, 0x2c05, 0x9005, 0x1158, 0xa004, 0x9045,
+	0x0904, 0x20e1, 0xa064, 0x90ec, 0x000f, 0x9de0, 0x1ee2, 0x2c05,
+	0x2060, 0xa880, 0xc0fc, 0xa882, 0x0804, 0x20d6, 0x2c05, 0x8422,
+	0x8420, 0x831a, 0x9399, 0x0000, 0xac2e, 0xab32, 0xdd9c, 0x1904,
+	0x2073, 0x9082, 0x001b, 0x0002, 0x200f, 0x200f, 0x2011, 0x200f,
+	0x200f, 0x200f, 0x201f, 0x200f, 0x200f, 0x200f, 0x202d, 0x200f,
+	0x200f, 0x200f, 0x203b, 0x200f, 0x200f, 0x200f, 0x2049, 0x200f,
+	0x200f, 0x200f, 0x2057, 0x200f, 0x200f, 0x200f, 0x2065, 0x080c,
+	0x0d85, 0xa17c, 0x2400, 0x9122, 0xa180, 0x2300, 0x911b, 0x0a0c,
+	0x0d85, 0xa074, 0x9420, 0xa078, 0x9319, 0x0804, 0x20d1, 0xa18c,
+	0x2400, 0x9122, 0xa190, 0x2300, 0x911b, 0x0a0c, 0x0d85, 0xa084,
+	0x9420, 0xa088, 0x9319, 0x0804, 0x20d1, 0xa19c, 0x2400, 0x9122,
+	0xa1a0, 0x2300, 0x911b, 0x0a0c, 0x0d85, 0xa094, 0x9420, 0xa098,
+	0x9319, 0x0804, 0x20d1, 0xa1ac, 0x2400, 0x9122, 0xa1b0, 0x2300,
+	0x911b, 0x0a0c, 0x0d85, 0xa0a4, 0x9420, 0xa0a8, 0x9319, 0x0804,
+	0x20d1, 0xa1bc, 0x2400, 0x9122, 0xa1c0, 0x2300, 0x911b, 0x0a0c,
+	0x0d85, 0xa0b4, 0x9420, 0xa0b8, 0x9319, 0x0804, 0x20d1, 0xa1cc,
+	0x2400, 0x9122, 0xa1d0, 0x2300, 0x911b, 0x0a0c, 0x0d85, 0xa0c4,
+	0x9420, 0xa0c8, 0x9319, 0x0804, 0x20d1, 0xa1dc, 0x2400, 0x9122,
+	0xa1e0, 0x2300, 0x911b, 0x0a0c, 0x0d85, 0xa0d4, 0x9420, 0xa0d8,
+	0x9319, 0x0804, 0x20d1, 0x9082, 0x001b, 0x0002, 0x2091, 0x208f,
+	0x208f, 0x208f, 0x208f, 0x208f, 0x209e, 0x208f, 0x208f, 0x208f,
+	0x208f, 0x208f, 0x20ab, 0x208f, 0x208f, 0x208f, 0x208f, 0x208f,
+	0x20b8, 0x208f, 0x208f, 0x208f, 0x208f, 0x208f, 0x20c5, 0x080c,
+	0x0d85, 0xa17c, 0x2400, 0x9122, 0xa180, 0x2300, 0x911b, 0x0a0c,
+	0x0d85, 0xa06c, 0x9420, 0xa070, 0x9319, 0x0498, 0xa194, 0x2400,
+	0x9122, 0xa198, 0x2300, 0x911b, 0x0a0c, 0x0d85, 0xa084, 0x9420,
+	0xa088, 0x9319, 0x0430, 0xa1ac, 0x2400, 0x9122, 0xa1b0, 0x2300,
+	0x911b, 0x0a0c, 0x0d85, 0xa09c, 0x9420, 0xa0a0, 0x9319, 0x00c8,
+	0xa1c4, 0x2400, 0x9122, 0xa1c8, 0x2300, 0x911b, 0x0a0c, 0x0d85,
+	0xa0b4, 0x9420, 0xa0b8, 0x9319, 0x0060, 0xa1dc, 0x2400, 0x9122,
+	0xa1e0, 0x2300, 0x911b, 0x0a0c, 0x0d85, 0xa0cc, 0x9420, 0xa0d0,
+	0x9319, 0xac1e, 0xab22, 0xa880, 0xc0fd, 0xa882, 0x2800, 0xa85a,
+	0x2c00, 0xa812, 0x2a00, 0xa816, 0x000e, 0x000e, 0x000e, 0x9006,
+	0x0028, 0x008e, 0x00de, 0x00ce, 0x9085, 0x0001, 0x0005, 0x00c6,
+	0x610c, 0x0016, 0x9026, 0x2410, 0x6004, 0x9420, 0x9291, 0x0000,
+	0x2c04, 0x9210, 0x9ce0, 0x0002, 0x918a, 0x0002, 0x1da8, 0x9284,
+	0x000f, 0x9405, 0x001e, 0x00ce, 0x0005, 0x7803, 0x0003, 0x780f,
+	0x0000, 0x6004, 0x7812, 0x2c04, 0x7816, 0x9ce0, 0x0002, 0x918a,
+	0x0002, 0x1db8, 0x0005, 0x2001, 0x0005, 0x2004, 0xd0bc, 0x190c,
+	0x0d7e, 0xd094, 0x0110, 0x080c, 0x1208, 0x0005, 0x0126, 0x2091,
+	0x2600, 0x2079, 0x0200, 0x2071, 0x0260, 0x2069, 0x1800, 0x7817,
+	0x0000, 0x789b, 0x0814, 0x78a3, 0x0406, 0x789f, 0x0410, 0x2009,
+	0x013b, 0x200b, 0x0400, 0x781b, 0x0002, 0x783b, 0x001f, 0x7837,
+	0x0020, 0x7803, 0x1600, 0x012e, 0x0005, 0x2091, 0x2600, 0x781c,
+	0xd0a4, 0x190c, 0x223e, 0x7900, 0xd1dc, 0x1118, 0x9084, 0x0006,
+	0x001a, 0x9084, 0x000e, 0x0002, 0x215c, 0x2154, 0x80b1, 0x2154,
+	0x2156, 0x2156, 0x2156, 0x2156, 0x8097, 0x2154, 0x2158, 0x2154,
+	0x2156, 0x2154, 0x2156, 0x2154, 0x080c, 0x0d85, 0x0031, 0x0020,
+	0x080c, 0x8097, 0x080c, 0x80b1, 0x0005, 0x0006, 0x0016, 0x0026,
+	0x080c, 0xeb9e, 0x7930, 0x9184, 0x0003, 0x0510, 0x080c, 0xaae0,
+	0x2001, 0x19fc, 0x2004, 0x9005, 0x01a0, 0x2001, 0x0133, 0x2004,
+	0x9005, 0x090c, 0x0d85, 0x00c6, 0x2001, 0x19fc, 0x2064, 0x080c,
+	0xaafc, 0x080c, 0xc802, 0x2009, 0x0040, 0x080c, 0x2241, 0x00ce,
+	0x0408, 0x2009, 0x0040, 0x080c, 0x2241, 0x080c, 0xaafc, 0x00d0,
+	0x9184, 0x0014, 0x01a0, 0x6a00, 0x9286, 0x0003, 0x0160, 0x080c,
+	0x76a5, 0x1138, 0x080c, 0x79a7, 0x080c, 0x617e, 0x080c, 0x75d4,
+	0x0010, 0x080c, 0x6039, 0x080c, 0x814f, 0x0041, 0x0018, 0x9184,
+	0x9540, 0x1dc8, 0x002e, 0x001e, 0x000e, 0x0005, 0x00e6, 0x0036,
+	0x0046, 0x0056, 0x2071, 0x1a6f, 0x080c, 0x1b47, 0x005e, 0x004e,
+	0x003e, 0x00ee, 0x0005, 0x0126, 0x2091, 0x2e00, 0x2071, 0x1800,
+	0x7128, 0x2001, 0x1970, 0x2102, 0x2001, 0x1978, 0x2102, 0x2001,
+	0x013b, 0x2102, 0x2079, 0x0200, 0x2001, 0x0201, 0x789e, 0x78a3,
+	0x0200, 0x9198, 0x0007, 0x831c, 0x831c, 0x831c, 0x9398, 0x0005,
+	0x2320, 0x9182, 0x0204, 0x1230, 0x2011, 0x0008, 0x8423, 0x8423,
+	0x8423, 0x0488, 0x9182, 0x024c, 0x1240, 0x2011, 0x0007, 0x8403,
+	0x8003, 0x9400, 0x9400, 0x9420, 0x0430, 0x9182, 0x02bc, 0x1238,
+	0x2011, 0x0006, 0x8403, 0x8003, 0x9400, 0x9420, 0x00e0, 0x9182,
+	0x034c, 0x1230, 0x2011, 0x0005, 0x8403, 0x8003, 0x9420, 0x0098,
+	0x9182, 0x042c, 0x1228, 0x2011, 0x0004, 0x8423, 0x8423, 0x0058,
+	0x9182, 0x059c, 0x1228, 0x2011, 0x0003, 0x8403, 0x9420, 0x0018,
+	0x2011, 0x0002, 0x8423, 0x9482, 0x0228, 0x8002, 0x8020, 0x8301,
+	0x9402, 0x0110, 0x0208, 0x8321, 0x8217, 0x8203, 0x9405, 0x789a,
+	0x012e, 0x0005, 0x0006, 0x00d6, 0x2069, 0x0200, 0x6814, 0x9084,
+	0xffc0, 0x910d, 0x6916, 0x00de, 0x000e, 0x0005, 0x00d6, 0x2069,
+	0x0200, 0x9005, 0x6810, 0x0110, 0xc0a5, 0x0008, 0xc0a4, 0x6812,
+	0x00de, 0x0005, 0x0006, 0x00d6, 0x2069, 0x0200, 0x6810, 0x9084,
+	0xfff8, 0x910d, 0x6912, 0x00de, 0x000e, 0x0005, 0x7938, 0x080c,
+	0x0d7e, 0x00f6, 0x2079, 0x0200, 0x7902, 0xa001, 0xa001, 0xa001,
+	0xa001, 0xa001, 0xa001, 0x7902, 0xa001, 0xa001, 0xa001, 0xa001,
+	0xa001, 0xa001, 0x00fe, 0x0005, 0x0126, 0x2091, 0x2800, 0x2061,
+	0x0100, 0x2071, 0x1800, 0x2009, 0x0000, 0x080c, 0x2aa7, 0x080c,
+	0x29bd, 0x2001, 0x199e, 0x2003, 0x0700, 0x2001, 0x199f, 0x2003,
+	0x0700, 0x080c, 0x2b18, 0x9006, 0x080c, 0x29ec, 0x9006, 0x080c,
+	0x29cf, 0x20a9, 0x0012, 0x1d04, 0x2273, 0x2091, 0x6000, 0x1f04,
+	0x2273, 0x602f, 0x0100, 0x602f, 0x0000, 0x6050, 0x9085, 0x0400,
+	0x9084, 0xdfff, 0x6052, 0x6224, 0x080c, 0x2af5, 0x080c, 0x26db,
+	0x2009, 0x00ef, 0x6132, 0x6136, 0x080c, 0x26eb, 0x60e7, 0x0000,
+	0x61ea, 0x60e3, 0x0008, 0x604b, 0xf7f7, 0x6043, 0x0000, 0x602f,
+	0x0080, 0x602f, 0x0000, 0x6007, 0x349f, 0x00c6, 0x2061, 0x0140,
+	0x608b, 0x000b, 0x608f, 0x10b8, 0x6093, 0x0000, 0x6097, 0x0198,
+	0x00ce, 0x6004, 0x9085, 0x8000, 0x6006, 0x60bb, 0x0000, 0x20a9,
+	0x0018, 0x60bf, 0x0000, 0x1f04, 0x22b1, 0x60bb, 0x0000, 0x60bf,
+	0x0108, 0x60bf, 0x0012, 0x60bf, 0x0405, 0x60bf, 0x0014, 0x60bf,
+	0x0320, 0x60bf, 0x0018, 0x601b, 0x00f0, 0x601f, 0x001e, 0x600f,
+	0x006b, 0x602b, 0x402c, 0x012e, 0x0005, 0x00f6, 0x2079, 0x0140,
+	0x78c3, 0x0080, 0x78c3, 0x0083, 0x78c3, 0x0000, 0x00fe, 0x0005,
+	0x2001, 0x1835, 0x2003, 0x0000, 0x2001, 0x1834, 0x2003, 0x0001,
+	0x0005, 0x0126, 0x2091, 0x2800, 0x0006, 0x0016, 0x0026, 0x6124,
+	0x6028, 0x910c, 0x0066, 0x2031, 0x1837, 0x2634, 0x96b4, 0x0028,
+	0x006e, 0x1138, 0x6020, 0xd1bc, 0x0120, 0xd0bc, 0x1168, 0xd0b4,
+	0x1198, 0x9184, 0x5e2c, 0x1118, 0x9184, 0x0007, 0x00aa, 0x9195,
+	0x0004, 0x9284, 0x0007, 0x0082, 0x0016, 0x2001, 0x0387, 0x200c,
+	0xd1a4, 0x001e, 0x0d70, 0x0c98, 0x0016, 0x2001, 0x0387, 0x200c,
+	0xd1b4, 0x001e, 0x0d30, 0x0c58, 0x231f, 0x231c, 0x231c, 0x231c,
+	0x231e, 0x231c, 0x231c, 0x231c, 0x080c, 0x0d85, 0x0029, 0x002e,
+	0x001e, 0x000e, 0x012e, 0x0005, 0x00a6, 0x6124, 0x6028, 0xd09c,
+	0x0118, 0xd19c, 0x1904, 0x25a1, 0xd1f4, 0x190c, 0x0d7e, 0x080c,
+	0x76a5, 0x0904, 0x237c, 0x080c, 0xd33e, 0x1120, 0x7000, 0x9086,
+	0x0003, 0x0580, 0x6024, 0x9084, 0x1800, 0x0560, 0x080c, 0x76c8,
+	0x0118, 0x080c, 0x76b6, 0x1530, 0x2011, 0x0020, 0x080c, 0x2af5,
+	0x6043, 0x0000, 0x080c, 0xd33e, 0x0168, 0x080c, 0x76c8, 0x1150,
+	0x2001, 0x19a8, 0x2003, 0x0001, 0x6027, 0x1800, 0x080c, 0x7519,
+	0x0804, 0x25a4, 0x70a4, 0x9005, 0x1150, 0x70a7, 0x0001, 0x00d6,
+	0x2069, 0x0140, 0x080c, 0x76f9, 0x00de, 0x1904, 0x25a4, 0x080c,
+	0x79b1, 0x0428, 0x080c, 0x76c8, 0x1590, 0x6024, 0x9084, 0x1800,
+	0x1108, 0x0468, 0x080c, 0x79b1, 0x080c, 0x79a7, 0x080c, 0x617e,
+	0x080c, 0x75d4, 0x0804, 0x25a1, 0xd1ac, 0x1508, 0x6024, 0xd0dc,
+	0x1170, 0xd0e4, 0x1178, 0xd0d4, 0x1190, 0xd0cc, 0x0130, 0x7098,
+	0x9086, 0x0029, 0x1110, 0x080c, 0x7888, 0x0804, 0x25a1, 0x080c,
+	0x79ac, 0x0048, 0x2001, 0x197e, 0x2003, 0x0002, 0x0020, 0x080c,
+	0x77e3, 0x0804, 0x25a1, 0x080c, 0x792b, 0x0804, 0x25a1, 0x6220,
+	0xd1bc, 0x0138, 0xd2bc, 0x1904, 0x260c, 0xd2b4, 0x1904, 0x261e,
+	0x0000, 0xd1ac, 0x0904, 0x24ae, 0x0036, 0x6328, 0xc3bc, 0x632a,
+	0x003e, 0x080c, 0x76a5, 0x11d0, 0x2011, 0x0020, 0x080c, 0x2af5,
+	0x0006, 0x0026, 0x0036, 0x080c, 0x76bf, 0x1158, 0x080c, 0x79a7,
+	0x080c, 0x617e, 0x080c, 0x75d4, 0x003e, 0x002e, 0x000e, 0x00ae,
+	0x0005, 0x003e, 0x002e, 0x000e, 0x080c, 0x7679, 0x0016, 0x0046,
+	0x00c6, 0x644c, 0x9486, 0xf0f0, 0x1138, 0x2061, 0x0100, 0x644a,
+	0x6043, 0x0090, 0x6043, 0x0010, 0x74da, 0x948c, 0xff00, 0x7038,
+	0xd084, 0x0178, 0x9186, 0xf800, 0x1160, 0x7048, 0xd084, 0x1148,
+	0xc085, 0x704a, 0x0036, 0x2418, 0x2011, 0x8016, 0x080c, 0x4c2e,
+	0x003e, 0x080c, 0xd337, 0x1904, 0x2483, 0x9196, 0xff00, 0x05a8,
+	0x7060, 0x9084, 0x00ff, 0x810f, 0x81ff, 0x0110, 0x9116, 0x0568,
+	0x7130, 0xd184, 0x1550, 0x080c, 0x347d, 0x0128, 0xc18d, 0x7132,
+	0x080c, 0x6bcd, 0x1510, 0x6240, 0x9294, 0x0010, 0x0130, 0x6248,
+	0x9294, 0xff00, 0x9296, 0xff00, 0x01c0, 0x7030, 0xd08c, 0x0904,
+	0x2483, 0x7038, 0xd08c, 0x1140, 0x2001, 0x180c, 0x200c, 0xd1ac,
+	0x1904, 0x2483, 0xc1ad, 0x2102, 0x0036, 0x73d8, 0x2011, 0x8013,
+	0x080c, 0x4c2e, 0x003e, 0x0804, 0x2483, 0x7038, 0xd08c, 0x1140,
+	0x2001, 0x180c, 0x200c, 0xd1ac, 0x1904, 0x2483, 0xc1ad, 0x2102,
+	0x0036, 0x73d8, 0x2011, 0x8013, 0x080c, 0x4c2e, 0x003e, 0x7130,
+	0xc185, 0x7132, 0x2011, 0x1848, 0x220c, 0xd1a4, 0x01f0, 0x0016,
+	0x2009, 0x0001, 0x2011, 0x0100, 0x080c, 0x8ae5, 0x2019, 0x000e,
+	0x00c6, 0x2061, 0x0000, 0x080c, 0xe696, 0x00ce, 0x9484, 0x00ff,
+	0x9080, 0x3489, 0x200d, 0x918c, 0xff00, 0x810f, 0x2120, 0x9006,
+	0x2009, 0x000e, 0x080c, 0xe72a, 0x001e, 0x0016, 0x2009, 0x0002,
+	0x2019, 0x0004, 0x080c, 0x32d5, 0x001e, 0x00a8, 0x0156, 0x00b6,
+	0x20a9, 0x007f, 0x900e, 0x080c, 0x6789, 0x1140, 0x7030, 0xd084,
+	0x1118, 0xb800, 0xd0bc, 0x1110, 0x080c, 0x6198, 0x8108, 0x1f04,
+	0x2473, 0x00be, 0x015e, 0x00ce, 0x004e, 0x080c, 0xaae0, 0x080c,
+	0xad9e, 0x080c, 0xae67, 0x080c, 0xaafc, 0x60e3, 0x0000, 0x001e,
+	0x2001, 0x1800, 0x2014, 0x9296, 0x0004, 0x1170, 0xd19c, 0x11b0,
+	0x2011, 0x180c, 0x2214, 0xd29c, 0x1120, 0x6204, 0x9295, 0x0002,
+	0x6206, 0x6228, 0xc29d, 0x622a, 0x2003, 0x0001, 0x2001, 0x1826,
+	0x2003, 0x0000, 0x2011, 0x0020, 0x080c, 0x2af5, 0xd194, 0x0904,
+	0x25a1, 0x0016, 0x080c, 0xaae0, 0x6220, 0xd2b4, 0x0904, 0x253c,
+	0x080c, 0x88ec, 0x080c, 0xa08a, 0x2011, 0x0004, 0x080c, 0x2af5,
+	0x00f6, 0x2019, 0x19f5, 0x2304, 0x907d, 0x0904, 0x2509, 0x7804,
+	0x9086, 0x0032, 0x15f0, 0x00d6, 0x00c6, 0x00e6, 0x0096, 0x2069,
+	0x0140, 0x782c, 0x685e, 0x7808, 0x685a, 0x6043, 0x0002, 0x2001,
+	0x0003, 0x8001, 0x1df0, 0x6043, 0x0000, 0x2001, 0x003c, 0x8001,
+	0x1df0, 0x080c, 0x2acb, 0x2001, 0x001e, 0x8001, 0x0240, 0x20a9,
+	0x0009, 0x080c, 0x2a82, 0x6904, 0xd1dc, 0x1140, 0x0cb0, 0x2001,
+	0x0100, 0x080c, 0x2abb, 0x9006, 0x080c, 0x2abb, 0x080c, 0x97fe,
+	0x080c, 0xaafc, 0x7814, 0x2048, 0xa867, 0x0103, 0x2f60, 0x080c,
+	0xaf2e, 0x009e, 0x00ee, 0x00ce, 0x00de, 0x00fe, 0x001e, 0x00ae,
+	0x0005, 0x00fe, 0x00d6, 0x2069, 0x0140, 0x6804, 0x9084, 0x4000,
+	0x0110, 0x080c, 0x2acb, 0x00de, 0x00c6, 0x2061, 0x19e9, 0x6034,
+	0x080c, 0xd33e, 0x0120, 0x909a, 0x0003, 0x1258, 0x0018, 0x909a,
+	0x00c8, 0x1238, 0x8000, 0x6036, 0x00ce, 0x080c, 0xa062, 0x0804,
+	0x259e, 0x2061, 0x0100, 0x62c0, 0x080c, 0xaa11, 0x2019, 0x19f5,
+	0x2304, 0x9065, 0x0130, 0x6003, 0x0001, 0x2009, 0x0027, 0x080c,
+	0xafcc, 0x00ce, 0x0804, 0x259e, 0xd2bc, 0x0904, 0x2581, 0x080c,
+	0x88f9, 0x2011, 0x0004, 0x080c, 0x2af5, 0x00d6, 0x2069, 0x0140,
+	0x6804, 0x9084, 0x4000, 0x0110, 0x080c, 0x2acb, 0x00de, 0x00c6,
+	0x2061, 0x19e9, 0x6050, 0x080c, 0xd33e, 0x0120, 0x909a, 0x0003,
+	0x1668, 0x0018, 0x909a, 0x00c8, 0x1648, 0x8000, 0x6052, 0x604c,
+	0x00ce, 0x9005, 0x05d8, 0x2009, 0x07d0, 0x080c, 0x88f1, 0x9080,
+	0x0008, 0x2004, 0x9086, 0x0006, 0x1138, 0x2009, 0x1984, 0x2011,
+	0x0012, 0x080c, 0x2b04, 0x0450, 0x9080, 0x0008, 0x2004, 0x9086,
+	0x0009, 0x0d98, 0x2009, 0x1984, 0x2011, 0x0016, 0x080c, 0x2b04,
+	0x00e8, 0x2011, 0x0004, 0x080c, 0x2af5, 0x00c0, 0x0036, 0x2019,
+	0x0001, 0x080c, 0xa380, 0x003e, 0x2019, 0x19fc, 0x2304, 0x9065,
+	0x0160, 0x2009, 0x004f, 0x6020, 0x9086, 0x0009, 0x1110, 0x2009,
+	0x004f, 0x6003, 0x0003, 0x080c, 0xafcc, 0x00ce, 0x080c, 0xaafc,
+	0x001e, 0xd19c, 0x0904, 0x2605, 0x7038, 0xd0ac, 0x1558, 0x0016,
+	0x0156, 0x2011, 0x0008, 0x080c, 0x2af5, 0x080c, 0x2b18, 0x080c,
+	0x2b4b, 0x6050, 0xc0e5, 0x6052, 0x20a9, 0x0367, 0x1f04, 0x25d0,
+	0x1d04, 0x25b8, 0x080c, 0x8920, 0x6020, 0xd09c, 0x1db8, 0x00f6,
+	0x2079, 0x0100, 0x080c, 0x2a2e, 0x00fe, 0x1d80, 0x6050, 0xc0e4,
+	0x6052, 0x2011, 0x0008, 0x080c, 0x2af5, 0x015e, 0x001e, 0x04a8,
+	0x015e, 0x001e, 0x0016, 0x6028, 0xc09c, 0x602a, 0x080c, 0xaae0,
+	0x080c, 0xad9e, 0x080c, 0xae67, 0x080c, 0xaafc, 0x60e3, 0x0000,
+	0x080c, 0xeb7d, 0x080c, 0xeb98, 0x080c, 0x582a, 0xd0fc, 0x1138,
+	0x080c, 0xd337, 0x1120, 0x9085, 0x0001, 0x080c, 0x76e9, 0x9006,
+	0x080c, 0x2abb, 0x2009, 0x0002, 0x080c, 0x2aa7, 0x00e6, 0x2071,
+	0x1800, 0x7003, 0x0004, 0x080c, 0x0ed3, 0x00ee, 0x2011, 0x0008,
+	0x080c, 0x2af5, 0x080c, 0x0bc3, 0x001e, 0x918c, 0xffd0, 0x2110,
+	0x080c, 0x2af5, 0x00ae, 0x0005, 0x0016, 0x2001, 0x0387, 0x200c,
+	0xd1a4, 0x001e, 0x0904, 0x23a9, 0x0016, 0x2009, 0x2618, 0x00c0,
+	0x2001, 0x0387, 0x2003, 0x1000, 0x001e, 0x0c38, 0x0016, 0x2001,
+	0x0387, 0x200c, 0xd1b4, 0x001e, 0x0904, 0x23a9, 0x0016, 0x2009,
+	0x262a, 0x0030, 0x2001, 0x0387, 0x2003, 0x4000, 0x001e, 0x08a8,
+	0x6028, 0xc0bc, 0x602a, 0x2001, 0x0156, 0x2003, 0xbc91, 0x8000,
+	0x2003, 0xffff, 0x6043, 0x0001, 0x080c, 0x2aa1, 0x2011, 0x0080,
+	0x080c, 0x2af5, 0x6017, 0x0000, 0x6043, 0x0000, 0x0817, 0x0006,
+	0x0016, 0x0026, 0x0036, 0x00e6, 0x00f6, 0x0126, 0x2091, 0x8000,
+	0x2071, 0x1800, 0x71d0, 0x70d2, 0x9116, 0x0904, 0x269a, 0x81ff,
+	0x01a0, 0x2009, 0x0000, 0x080c, 0x2aa7, 0x2011, 0x8011, 0x2019,
+	0x010e, 0x231c, 0x939e, 0x0007, 0x1118, 0x2019, 0x0001, 0x0010,
+	0x2019, 0x0000, 0x080c, 0x4c2e, 0x0468, 0x2001, 0x19a9, 0x200c,
+	0x81ff, 0x1140, 0x2001, 0x0109, 0x2004, 0xd0b4, 0x0118, 0x2019,
+	0x0003, 0x0008, 0x2118, 0x2011, 0x8012, 0x080c, 0x4c2e, 0x080c,
+	0x0ed3, 0x080c, 0x582a, 0xd0fc, 0x11a8, 0x080c, 0xd337, 0x1190,
+	0x00c6, 0x080c, 0x2736, 0x080c, 0xaae0, 0x080c, 0xa2db, 0x080c,
+	0xaafc, 0x2061, 0x0100, 0x2019, 0x0028, 0x2009, 0x0002, 0x080c,
+	0x32d5, 0x00ce, 0x012e, 0x00fe, 0x00ee, 0x003e, 0x002e, 0x001e,
+	0x000e, 0x0005, 0x2028, 0x918c, 0x00ff, 0x2130, 0x9094, 0xff00,
+	0x11f0, 0x2011, 0x1837, 0x2214, 0xd2ac, 0x11c8, 0x81ff, 0x01e8,
+	0x2011, 0x181f, 0x2204, 0x9106, 0x1190, 0x2011, 0x1820, 0x2214,
+	0x9294, 0xff00, 0x9584, 0xff00, 0x9206, 0x1148, 0x2011, 0x1820,
+	0x2214, 0x9294, 0x00ff, 0x9584, 0x00ff, 0x9206, 0x1120, 0x2500,
+	0x080c, 0x83c2, 0x0048, 0x9584, 0x00ff, 0x9080, 0x3489, 0x200d,
+	0x918c, 0xff00, 0x810f, 0x9006, 0x0005, 0x9080, 0x3489, 0x200d,
+	0x918c, 0x00ff, 0x0005, 0x00d6, 0x2069, 0x0140, 0x2001, 0x1818,
+	0x2003, 0x00ef, 0x20a9, 0x0010, 0x9006, 0x6852, 0x6856, 0x1f04,
+	0x26e6, 0x00de, 0x0005, 0x0006, 0x00d6, 0x0026, 0x2069, 0x0140,
+	0x2001, 0x1818, 0x2102, 0x8114, 0x8214, 0x8214, 0x8214, 0x20a9,
+	0x0010, 0x6853, 0x0000, 0x9006, 0x82ff, 0x1128, 0x9184, 0x000f,
+	0x9080, 0xebac, 0x2005, 0x6856, 0x8211, 0x1f04, 0x26fb, 0x002e,
+	0x00de, 0x000e, 0x0005, 0x00c6, 0x2061, 0x1800, 0x6030, 0x0110,
+	0xc09d, 0x0008, 0xc09c, 0x6032, 0x00ce, 0x0005, 0x0156, 0x00d6,
+	0x0026, 0x0016, 0x0006, 0x2069, 0x0140, 0x6980, 0x9116, 0x0180,
+	0x9112, 0x1230, 0x8212, 0x8210, 0x22a8, 0x2001, 0x0402, 0x0018,
+	0x22a8, 0x2001, 0x0404, 0x680e, 0x1f04, 0x272b, 0x680f, 0x0000,
+	0x000e, 0x001e, 0x002e, 0x00de, 0x015e, 0x0005, 0x080c, 0x5826,
+	0xd0c4, 0x0150, 0xd0a4, 0x0140, 0x9006, 0x0046, 0x2020, 0x2009,
+	0x002e, 0x080c, 0xe72a, 0x004e, 0x0005, 0x00f6, 0x0016, 0x0026,
+	0x2079, 0x0140, 0x78c4, 0xd0dc, 0x0904, 0x27a2, 0x080c, 0x2a1e,
+	0x0660, 0x9084, 0x0700, 0x908e, 0x0600, 0x1120, 0x2011, 0x4000,
+	0x900e, 0x0458, 0x908e, 0x0500, 0x1120, 0x2011, 0x8000, 0x900e,
+	0x0420, 0x908e, 0x0400, 0x1120, 0x9016, 0x2009, 0x0001, 0x00e8,
+	0x908e, 0x0300, 0x1120, 0x9016, 0x2009, 0x0002, 0x00b0, 0x908e,
+	0x0200, 0x1120, 0x9016, 0x2009, 0x0004, 0x0078, 0x908e, 0x0100,
+	0x1548, 0x9016, 0x2009, 0x0008, 0x0040, 0x9084, 0x0700, 0x908e,
+	0x0300, 0x1500, 0x2011, 0x0030, 0x0058, 0x2300, 0x9080, 0x0020,
+	0x2018, 0x080c, 0x936c, 0x928c, 0xff00, 0x0110, 0x2011, 0x00ff,
+	0x2200, 0x8007, 0x9085, 0x004c, 0x78c2, 0x2009, 0x0138, 0x220a,
+	0x080c, 0x76a5, 0x1118, 0x2009, 0x196e, 0x220a, 0x002e, 0x001e,
+	0x00fe, 0x0005, 0x78c3, 0x0000, 0x0cc8, 0x0126, 0x2091, 0x2800,
+	0x0006, 0x0016, 0x0026, 0x2001, 0x0170, 0x200c, 0x8000, 0x2014,
+	0x9184, 0x0003, 0x0110, 0x080c, 0x0d7e, 0x002e, 0x001e, 0x000e,
+	0x012e, 0x0005, 0x2001, 0x0171, 0x2004, 0xd0dc, 0x0168, 0x2001,
+	0x0170, 0x200c, 0x918c, 0x00ff, 0x918e, 0x004c, 0x1128, 0x200c,
+	0x918c, 0xff00, 0x810f, 0x0005, 0x900e, 0x2001, 0x0227, 0x2004,
+	0x8007, 0x9084, 0x00ff, 0x8004, 0x9108, 0x2001, 0x0226, 0x2004,
+	0x8007, 0x9084, 0x00ff, 0x8004, 0x9108, 0x0005, 0x0018, 0x000c,
+	0x0018, 0x0020, 0x1000, 0x0800, 0x1000, 0x1800, 0x0156, 0x0006,
+	0x0016, 0x0026, 0x00e6, 0x2001, 0x1991, 0x2004, 0x908a, 0x0007,
+	0x1a0c, 0x0d85, 0x0033, 0x00ee, 0x002e, 0x001e, 0x000e, 0x015e,
+	0x0005, 0x2800, 0x281e, 0x2842, 0x2844, 0x286d, 0x286f, 0x2871,
+	0x2001, 0x0001, 0x080c, 0x2647, 0x080c, 0x2a6c, 0x2001, 0x1993,
+	0x2003, 0x0000, 0x7828, 0x9084, 0xe1d7, 0x782a, 0x9006, 0x20a9,
+	0x0009, 0x080c, 0x2a3a, 0x2001, 0x1991, 0x2003, 0x0006, 0x2009,
+	0x001e, 0x2011, 0x2872, 0x080c, 0x88fe, 0x0005, 0x2009, 0x1996,
+	0x200b, 0x0000, 0x2001, 0x199b, 0x2003, 0x0036, 0x2001, 0x199a,
+	0x2003, 0x002a, 0x2001, 0x1993, 0x2003, 0x0001, 0x9006, 0x080c,
+	0x29cf, 0x2001, 0xffff, 0x20a9, 0x0009, 0x080c, 0x2a3a, 0x2001,
+	0x1991, 0x2003, 0x0006, 0x2009, 0x001e, 0x2011, 0x2872, 0x080c,
+	0x88fe, 0x0005, 0x080c, 0x0d85, 0x2001, 0x199b, 0x2003, 0x0036,
+	0x2001, 0x1993, 0x2003, 0x0003, 0x7a38, 0x9294, 0x0005, 0x9296,
+	0x0004, 0x0110, 0x9006, 0x0010, 0x2001, 0x0001, 0x080c, 0x29cf,
+	0x2001, 0x1997, 0x2003, 0x0000, 0x2001, 0xffff, 0x20a9, 0x0009,
+	0x080c, 0x2a3a, 0x2001, 0x1991, 0x2003, 0x0006, 0x2009, 0x001e,
+	0x2011, 0x2872, 0x080c, 0x88fe, 0x0005, 0x080c, 0x0d85, 0x080c,
+	0x0d85, 0x0005, 0x0006, 0x0016, 0x0026, 0x00e6, 0x00f6, 0x0156,
+	0x0126, 0x2091, 0x8000, 0x2079, 0x0100, 0x2001, 0x1993, 0x2004,
+	0x908a, 0x0007, 0x1a0c, 0x0d85, 0x0043, 0x012e, 0x015e, 0x00fe,
+	0x00ee, 0x002e, 0x001e, 0x000e, 0x0005, 0x2894, 0x28b4, 0x28f4,
+	0x2924, 0x2948, 0x2958, 0x295a, 0x080c, 0x2a2e, 0x11b0, 0x7850,
+	0x9084, 0xefff, 0x7852, 0x2009, 0x1999, 0x2104, 0x7a38, 0x9294,
+	0x0005, 0x9296, 0x0004, 0x0110, 0xc08d, 0x0008, 0xc085, 0x200a,
+	0x2001, 0x1991, 0x2003, 0x0001, 0x0030, 0x080c, 0x297e, 0x2001,
+	0xffff, 0x080c, 0x280f, 0x0005, 0x080c, 0x295c, 0x05e0, 0x2009,
+	0x199a, 0x2104, 0x8001, 0x200a, 0x080c, 0x2a2e, 0x1178, 0x7850,
+	0x9084, 0xefff, 0x7852, 0x7a38, 0x9294, 0x0005, 0x9296, 0x0005,
+	0x0518, 0x2009, 0x1999, 0x2104, 0xc085, 0x200a, 0x2009, 0x1996,
+	0x2104, 0x8000, 0x200a, 0x9086, 0x0005, 0x0118, 0x080c, 0x2964,
+	0x00c0, 0x200b, 0x0000, 0x7a38, 0x9294, 0x0006, 0x9296, 0x0004,
+	0x0110, 0x9006, 0x0010, 0x2001, 0x0001, 0x080c, 0x29ec, 0x2001,
+	0x1993, 0x2003, 0x0002, 0x0028, 0x2001, 0x1991, 0x2003, 0x0003,
+	0x0010, 0x080c, 0x2831, 0x0005, 0x080c, 0x295c, 0x0560, 0x2009,
+	0x199a, 0x2104, 0x8001, 0x200a, 0x080c, 0x2a2e, 0x1168, 0x7850,
+	0x9084, 0xefff, 0x7852, 0x2001, 0x1991, 0x2003, 0x0003, 0x2001,
+	0x1992, 0x2003, 0x0000, 0x00b8, 0x2009, 0x199a, 0x2104, 0x9005,
+	0x1118, 0x080c, 0x29a1, 0x0010, 0x080c, 0x2971, 0x080c, 0x2964,
+	0x2009, 0x1996, 0x200b, 0x0000, 0x2001, 0x1993, 0x2003, 0x0001,
+	0x080c, 0x2831, 0x0000, 0x0005, 0x04b9, 0x0508, 0x080c, 0x2a2e,
+	0x11b8, 0x7850, 0x9084, 0xefff, 0x7852, 0x2009, 0x1997, 0x2104,
+	0x8000, 0x200a, 0x9086, 0x0007, 0x0108, 0x0078, 0x2001, 0x199c,
+	0x2003, 0x000a, 0x2009, 0x1999, 0x2104, 0xc0fd, 0x200a, 0x0038,
+	0x0419, 0x2001, 0x1993, 0x2003, 0x0004, 0x080c, 0x285c, 0x0005,
+	0x0099, 0x0168, 0x080c, 0x2a2e, 0x1138, 0x7850, 0x9084, 0xefff,
+	0x7852, 0x080c, 0x2848, 0x0018, 0x0079, 0x080c, 0x285c, 0x0005,
+	0x080c, 0x0d85, 0x080c, 0x0d85, 0x2009, 0x199b, 0x2104, 0x8001,
+	0x200a, 0x090c, 0x29bd, 0x0005, 0x7a38, 0x9294, 0x0005, 0x9296,
+	0x0005, 0x0110, 0x9006, 0x0010, 0x2001, 0x0001, 0x080c, 0x29ec,
+	0x0005, 0x7a38, 0x9294, 0x0006, 0x9296, 0x0006, 0x0110, 0x9006,
+	0x0010, 0x2001, 0x0001, 0x080c, 0x29cf, 0x0005, 0x2009, 0x1996,
+	0x2104, 0x8000, 0x200a, 0x9086, 0x0005, 0x0108, 0x0068, 0x200b,
+	0x0000, 0x7a38, 0x9294, 0x0006, 0x9296, 0x0006, 0x0110, 0x9006,
+	0x0010, 0x2001, 0x0001, 0x04d9, 0x7a38, 0x9294, 0x0005, 0x9296,
+	0x0005, 0x0110, 0x9006, 0x0010, 0x2001, 0x0001, 0x080c, 0x29ec,
+	0x0005, 0x0086, 0x2001, 0x1999, 0x2004, 0x9084, 0x7fff, 0x090c,
+	0x0d85, 0x2009, 0x1998, 0x2144, 0x8846, 0x280a, 0x9844, 0x0dd8,
+	0xd08c, 0x1120, 0xd084, 0x1120, 0x080c, 0x0d85, 0x9006, 0x0010,
+	0x2001, 0x0001, 0x00a1, 0x008e, 0x0005, 0x0006, 0x0156, 0x2001,
+	0x1991, 0x20a9, 0x0009, 0x2003, 0x0000, 0x8000, 0x1f04, 0x29c3,
+	0x2001, 0x1998, 0x2003, 0x8000, 0x015e, 0x000e, 0x0005, 0x00f6,
+	0x2079, 0x0100, 0x9085, 0x0000, 0x0158, 0x7838, 0x9084, 0xfff9,
+	0x9085, 0x0004, 0x783a, 0x2009, 0x199e, 0x210c, 0x795a, 0x0050,
+	0x7838, 0x9084, 0xfffb, 0x9085, 0x0006, 0x783a, 0x2009, 0x199f,
+	0x210c, 0x795a, 0x00fe, 0x0005, 0x00f6, 0x2079, 0x0100, 0x9085,
+	0x0000, 0x0158, 0x7838, 0x9084, 0xfffa, 0x9085, 0x0004, 0x783a,
+	0x7850, 0x9084, 0xfff0, 0x7852, 0x00f8, 0x7838, 0x9084, 0xfffb,
+	0x9085, 0x0005, 0x783a, 0x7850, 0x9084, 0xfff0, 0x0016, 0x2009,
+	0x017f, 0x210c, 0x918e, 0x0005, 0x0140, 0x2009, 0x0003, 0x210c,
+	0x918c, 0x0600, 0x918e, 0x0400, 0x0118, 0x9085, 0x000a, 0x0010,
+	0x9085, 0x0000, 0x001e, 0x7852, 0x00fe, 0x0005, 0x0006, 0x2001,
+	0x0100, 0x2004, 0x9082, 0x0007, 0x000e, 0x0005, 0x0006, 0x2001,
+	0x0100, 0x2004, 0x9082, 0x0009, 0x000e, 0x0005, 0x0156, 0x20a9,
+	0x0064, 0x7820, 0x080c, 0x2aa1, 0xd09c, 0x1110, 0x1f04, 0x2a31,
+	0x015e, 0x0005, 0x0126, 0x0016, 0x0006, 0x2091, 0x8000, 0x080c,
+	0x2b18, 0x080c, 0x2b4b, 0x000e, 0x2008, 0x9186, 0x0000, 0x1118,
+	0x783b, 0x0007, 0x0090, 0x9186, 0x0001, 0x1118, 0x783b, 0x0006,
+	0x0060, 0x9186, 0x0002, 0x1118, 0x783b, 0x0005, 0x0030, 0x9186,
+	0x0003, 0x1118, 0x783b, 0x0004, 0x0000, 0x0006, 0x1d04, 0x2a5e,
+	0x080c, 0x8920, 0x1f04, 0x2a5e, 0x7850, 0x9085, 0x1000, 0x7852,
+	0x000e, 0x001e, 0x012e, 0x0005, 0x080c, 0x2b4b, 0x0005, 0x0006,
+	0x0156, 0x00f6, 0x2079, 0x0100, 0x20a9, 0x000a, 0x7854, 0xd0ac,
+	0x1100, 0x7854, 0xd08c, 0x1110, 0x1f04, 0x2a79, 0x00fe, 0x015e,
+	0x000e, 0x0005, 0x1d04, 0x2a82, 0x080c, 0x8920, 0x1f04, 0x2a82,
+	0x0005, 0x0006, 0x2001, 0x199d, 0x2004, 0x9086, 0x0000, 0x000e,
+	0x0005, 0x0006, 0x2001, 0x199d, 0x2004, 0x9086, 0x0001, 0x000e,
+	0x0005, 0x0006, 0x2001, 0x199d, 0x2004, 0x9086, 0x0002, 0x000e,
+	0x0005, 0xa001, 0xa001, 0xa001, 0xa001, 0xa001, 0x0005, 0x0006,
+	0x2001, 0x19a9, 0x2102, 0x000e, 0x0005, 0x2009, 0x0171, 0x2104,
+	0xd0dc, 0x0140, 0x2009, 0x0170, 0x2104, 0x200b, 0x0080, 0xa001,
+	0xa001, 0x200a, 0x0005, 0x0016, 0x0026, 0x080c, 0x76bf, 0x0108,
+	0xc0bc, 0x2009, 0x0140, 0x2114, 0x9294, 0x0001, 0x9215, 0x220a,
+	0x002e, 0x001e, 0x0005, 0x0016, 0x0026, 0x2009, 0x0140, 0x2114,
+	0x9294, 0x0001, 0x9285, 0x1000, 0x200a, 0x220a, 0x002e, 0x001e,
+	0x0005, 0x0016, 0x0026, 0x2009, 0x0140, 0x2114, 0x9294, 0x0001,
+	0x9215, 0x220a, 0x002e, 0x001e, 0x0005, 0x0006, 0x0016, 0x2009,
+	0x0140, 0x2104, 0x1128, 0x080c, 0x76bf, 0x0110, 0xc0bc, 0x0008,
+	0xc0bd, 0x200a, 0x001e, 0x000e, 0x0005, 0x00f6, 0x2079, 0x0380,
+	0x7843, 0x0101, 0x7844, 0xd084, 0x1de8, 0x2001, 0x0109, 0x2202,
+	0x7843, 0x0100, 0x00fe, 0x0005, 0x00f6, 0x2079, 0x0380, 0x7843,
+	0x0202, 0x7844, 0xd08c, 0x1de8, 0x2079, 0x0100, 0x7814, 0x9104,
+	0x9205, 0x7a16, 0x2079, 0x0380, 0x7843, 0x0200, 0x00fe, 0x0005,
+	0x0016, 0x0026, 0x0036, 0x00c6, 0x2061, 0x0100, 0x6050, 0x9084,
+	0xfbff, 0x9085, 0x0040, 0x6052, 0x20a9, 0x0002, 0x080c, 0x2a82,
+	0x6050, 0x9085, 0x0400, 0x9084, 0xff9f, 0x6052, 0x20a9, 0x0005,
+	0x080c, 0x2a82, 0x6054, 0xd0bc, 0x090c, 0x0d85, 0x20a9, 0x0005,
+	0x080c, 0x2a82, 0x6054, 0xd0ac, 0x090c, 0x0d85, 0x2009, 0x19b0,
+	0x9084, 0x7e00, 0x8007, 0x8004, 0x8004, 0x200a, 0x00ce, 0x003e,
+	0x002e, 0x001e, 0x0005, 0x0006, 0x00c6, 0x2061, 0x0100, 0x6050,
+	0xc0cd, 0x6052, 0x00ce, 0x000e, 0x0005, 0x0016, 0x00c6, 0x00d6,
+	0x0006, 0x2061, 0x0100, 0x2069, 0x0140, 0x6030, 0x0006, 0x6048,
+	0x0006, 0x60e4, 0x0006, 0x60e8, 0x0006, 0x6050, 0x0006, 0x60ec,
+	0x0006, 0x600c, 0x0006, 0x6004, 0x0006, 0xc0fc, 0x6006, 0x2009,
+	0x0800, 0x2001, 0x0338, 0x2003, 0x0301, 0x8109, 0x090c, 0x0d85,
+	0x2001, 0x0338, 0x2004, 0xd084, 0x1dc0, 0x6028, 0x0006, 0x60e0,
+	0x0006, 0x6888, 0x0006, 0x688c, 0x0006, 0x6890, 0x0006, 0x080c,
+	0x76a5, 0x1110, 0x6884, 0x0006, 0x602f, 0x0100, 0x602f, 0x0000,
+	0xa001, 0xa001, 0xa001, 0xa001, 0x602f, 0x0040, 0x602f, 0x0000,
+	0x080c, 0x76a5, 0x1120, 0x6803, 0x0080, 0x000e, 0x6886, 0x6897,
+	0x4198, 0x000e, 0x6892, 0x000e, 0x688e, 0x000e, 0x688a, 0x000e,
+	0x60e2, 0x000e, 0x602a, 0x000e, 0x6006, 0x000e, 0x600e, 0x000e,
+	0x60ee, 0x000e, 0x6052, 0x000e, 0x60ea, 0x000e, 0x60e6, 0x000e,
+	0x604a, 0x000e, 0x6032, 0x6036, 0x2008, 0x080c, 0x26eb, 0x000e,
+	0x00de, 0x00ce, 0x001e, 0x0005, 0x0006, 0x0156, 0x6050, 0x9085,
+	0x0040, 0x6052, 0x6050, 0x9084, 0xfbcf, 0x6052, 0x080c, 0x2aa1,
+	0x9085, 0x2000, 0x6052, 0x20a9, 0x0012, 0x1d04, 0x2bd5, 0x080c,
+	0x8920, 0x1f04, 0x2bd5, 0x6050, 0x9085, 0x0400, 0x9084, 0xdfbf,
+	0x6052, 0x015e, 0x000e, 0x0005, 0x30e0, 0x30e0, 0x2ce4, 0x2ce4,
+	0x2cf0, 0x2cf0, 0x2cfc, 0x2cfc, 0x2d0a, 0x2d0a, 0x2d16, 0x2d16,
+	0x2d24, 0x2d24, 0x2d32, 0x2d32, 0x2d44, 0x2d44, 0x2d50, 0x2d50,
+	0x2d5e, 0x2d5e, 0x2d7c, 0x2d7c, 0x2d9c, 0x2d9c, 0x2d6c, 0x2d6c,
+	0x2d8c, 0x2d8c, 0x2daa, 0x2daa, 0x2d42, 0x2d42, 0x2d42, 0x2d42,
+	0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42,
+	0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42,
+	0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42,
+	0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2dbc, 0x2dbc, 0x2dc8, 0x2dc8,
+	0x2dd6, 0x2dd6, 0x2de4, 0x2de4, 0x2df4, 0x2df4, 0x2e02, 0x2e02,
+	0x2e12, 0x2e12, 0x2e22, 0x2e22, 0x2e34, 0x2e34, 0x2e42, 0x2e42,
+	0x2e52, 0x2e52, 0x2e74, 0x2e74, 0x2e98, 0x2e98, 0x2e62, 0x2e62,
+	0x2e86, 0x2e86, 0x2ea8, 0x2ea8, 0x2d42, 0x2d42, 0x2d42, 0x2d42,
+	0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42,
+	0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42,
+	0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42,
+	0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2ebc, 0x2ebc, 0x2ec8, 0x2ec8,
+	0x2ed6, 0x2ed6, 0x2ee4, 0x2ee4, 0x2ef4, 0x2ef4, 0x2f02, 0x2f02,
+	0x2f12, 0x2f12, 0x2f22, 0x2f22, 0x2f34, 0x2f34, 0x2f42, 0x2f42,
+	0x2f52, 0x2f52, 0x2f62, 0x2f62, 0x2f74, 0x2f74, 0x2f84, 0x2f84,
+	0x2f96, 0x2f96, 0x2fa8, 0x2fa8, 0x2d42, 0x2d42, 0x2d42, 0x2d42,
+	0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42,
+	0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42,
+	0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42,
+	0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2fbc, 0x2fbc, 0x2fca, 0x2fca,
+	0x2fda, 0x2fda, 0x2fea, 0x2fea, 0x2ffc, 0x2ffc, 0x300c, 0x300c,
+	0x301e, 0x301e, 0x3030, 0x3030, 0x3044, 0x3044, 0x3054, 0x3054,
+	0x3066, 0x3066, 0x3078, 0x3078, 0x308c, 0x308c, 0x309d, 0x309d,
+	0x30b0, 0x30b0, 0x30c3, 0x30c3, 0x2d42, 0x2d42, 0x2d42, 0x2d42,
+	0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42,
+	0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42,
+	0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x2d42,
+	0x2d42, 0x2d42, 0x2d42, 0x2d42, 0x0106, 0x0006, 0x0126, 0x01c6,
+	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x22e1, 0x0804, 0x30d8,
 	0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156,
-	0x080c, 0x20d4, 0x0804, 0x3008, 0x0106, 0x0006, 0x0126, 0x01c6,
-	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x20d4, 0x080c, 0x22aa,
-	0x0804, 0x3008, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
-	0x0146, 0x0156, 0x080c, 0x20fe, 0x0804, 0x3008, 0x0106, 0x0006,
-	0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x22aa,
-	0x080c, 0x20fe, 0x0804, 0x3008, 0x0106, 0x0006, 0x0126, 0x01c6,
-	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x20d4, 0x080c, 0x20fe,
-	0x0804, 0x3008, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
-	0x0146, 0x0156, 0x080c, 0x20d4, 0x080c, 0x22aa, 0x080c, 0x20fe,
-	0x0804, 0x3008, 0xa001, 0x0cf0, 0x0106, 0x0006, 0x0126, 0x01c6,
-	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x13bb, 0x0804, 0x3008,
+	0x080c, 0x210b, 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6,
+	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x210b, 0x080c, 0x22e1,
+	0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
+	0x0146, 0x0156, 0x080c, 0x2135, 0x0804, 0x30d8, 0x0106, 0x0006,
+	0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x22e1,
+	0x080c, 0x2135, 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6,
+	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x210b, 0x080c, 0x2135,
+	0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
+	0x0146, 0x0156, 0x080c, 0x210b, 0x080c, 0x22e1, 0x080c, 0x2135,
+	0x0804, 0x30d8, 0xa001, 0x0cf0, 0x0106, 0x0006, 0x0126, 0x01c6,
+	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x13d4, 0x0804, 0x30d8,
 	0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156,
-	0x080c, 0x22aa, 0x080c, 0x13bb, 0x0804, 0x3008, 0x0106, 0x0006,
-	0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x20d4,
-	0x080c, 0x13bb, 0x0804, 0x3008, 0x0106, 0x0006, 0x0126, 0x01c6,
-	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x22aa, 0x080c, 0x13bb,
-	0x080c, 0x20fe, 0x0804, 0x3008, 0x0106, 0x0006, 0x0126, 0x01c6,
-	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x20d4, 0x080c, 0x22aa,
-	0x080c, 0x13bb, 0x0804, 0x3008, 0x0106, 0x0006, 0x0126, 0x01c6,
-	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x20d4, 0x080c, 0x13bb,
-	0x080c, 0x20fe, 0x0804, 0x3008, 0x0106, 0x0006, 0x0126, 0x01c6,
-	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x13bb, 0x080c, 0x20fe,
-	0x0804, 0x3008, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
-	0x0146, 0x0156, 0x080c, 0x20d4, 0x080c, 0x22aa, 0x080c, 0x13bb,
-	0x080c, 0x20fe, 0x0804, 0x3008, 0x0106, 0x0006, 0x0126, 0x01c6,
-	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2764, 0x0804, 0x3008,
+	0x080c, 0x22e1, 0x080c, 0x13d4, 0x0804, 0x30d8, 0x0106, 0x0006,
+	0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x210b,
+	0x080c, 0x13d4, 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6,
+	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x22e1, 0x080c, 0x13d4,
+	0x080c, 0x2135, 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6,
+	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x210b, 0x080c, 0x22e1,
+	0x080c, 0x13d4, 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6,
+	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x210b, 0x080c, 0x13d4,
+	0x080c, 0x2135, 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6,
+	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x13d4, 0x080c, 0x2135,
+	0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
+	0x0146, 0x0156, 0x080c, 0x210b, 0x080c, 0x22e1, 0x080c, 0x13d4,
+	0x080c, 0x2135, 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6,
+	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x27a5, 0x0804, 0x30d8,
 	0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156,
-	0x080c, 0x2764, 0x080c, 0x22aa, 0x0804, 0x3008, 0x0106, 0x0006,
-	0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2764,
-	0x080c, 0x20d4, 0x0804, 0x3008, 0x0106, 0x0006, 0x0126, 0x01c6,
-	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2764, 0x080c, 0x20d4,
-	0x080c, 0x22aa, 0x0804, 0x3008, 0x0106, 0x0006, 0x0126, 0x01c6,
-	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2764, 0x080c, 0x20fe,
-	0x0804, 0x3008, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
-	0x0146, 0x0156, 0x080c, 0x2764, 0x080c, 0x22aa, 0x080c, 0x20fe,
-	0x0804, 0x3008, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
-	0x0146, 0x0156, 0x080c, 0x2764, 0x080c, 0x20d4, 0x080c, 0x20fe,
-	0x0804, 0x3008, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
-	0x0146, 0x0156, 0x080c, 0x2764, 0x080c, 0x20d4, 0x080c, 0x22aa,
-	0x080c, 0x20fe, 0x0804, 0x3008, 0x0106, 0x0006, 0x0126, 0x01c6,
-	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2764, 0x080c, 0x13bb,
-	0x0804, 0x3008, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
-	0x0146, 0x0156, 0x080c, 0x2764, 0x080c, 0x22aa, 0x080c, 0x13bb,
-	0x0804, 0x3008, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
-	0x0146, 0x0156, 0x080c, 0x2764, 0x080c, 0x20d4, 0x080c, 0x13bb,
-	0x0804, 0x3008, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
-	0x0146, 0x0156, 0x080c, 0x2764, 0x080c, 0x22aa, 0x080c, 0x13bb,
-	0x080c, 0x20fe, 0x0804, 0x3008, 0x0106, 0x0006, 0x0126, 0x01c6,
-	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2764, 0x080c, 0x20d4,
-	0x080c, 0x22aa, 0x080c, 0x13bb, 0x0804, 0x3008, 0x0106, 0x0006,
-	0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2764,
-	0x080c, 0x20d4, 0x080c, 0x13bb, 0x080c, 0x20fe, 0x0804, 0x3008,
+	0x080c, 0x27a5, 0x080c, 0x22e1, 0x0804, 0x30d8, 0x0106, 0x0006,
+	0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x27a5,
+	0x080c, 0x210b, 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6,
+	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x27a5, 0x080c, 0x210b,
+	0x080c, 0x22e1, 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6,
+	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x27a5, 0x080c, 0x2135,
+	0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
+	0x0146, 0x0156, 0x080c, 0x27a5, 0x080c, 0x22e1, 0x080c, 0x2135,
+	0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
+	0x0146, 0x0156, 0x080c, 0x27a5, 0x080c, 0x210b, 0x080c, 0x2135,
+	0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
+	0x0146, 0x0156, 0x080c, 0x27a5, 0x080c, 0x210b, 0x080c, 0x22e1,
+	0x080c, 0x2135, 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6,
+	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x27a5, 0x080c, 0x13d4,
+	0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
+	0x0146, 0x0156, 0x080c, 0x27a5, 0x080c, 0x22e1, 0x080c, 0x13d4,
+	0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
+	0x0146, 0x0156, 0x080c, 0x27a5, 0x080c, 0x210b, 0x080c, 0x13d4,
+	0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
+	0x0146, 0x0156, 0x080c, 0x27a5, 0x080c, 0x22e1, 0x080c, 0x13d4,
+	0x080c, 0x2135, 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6,
+	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x27a5, 0x080c, 0x210b,
+	0x080c, 0x22e1, 0x080c, 0x13d4, 0x0804, 0x30d8, 0x0106, 0x0006,
+	0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x27a5,
+	0x080c, 0x210b, 0x080c, 0x13d4, 0x080c, 0x2135, 0x0804, 0x30d8,
 	0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156,
-	0x080c, 0x2764, 0x080c, 0x13bb, 0x080c, 0x20fe, 0x0804, 0x3008,
+	0x080c, 0x27a5, 0x080c, 0x13d4, 0x080c, 0x2135, 0x0804, 0x30d8,
 	0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156,
-	0x080c, 0x2764, 0x080c, 0x20d4, 0x080c, 0x22aa, 0x080c, 0x13bb,
-	0x080c, 0x20fe, 0x0804, 0x3008, 0x0106, 0x0006, 0x0126, 0x01c6,
-	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0xa984, 0x0804, 0x3008,
+	0x080c, 0x27a5, 0x080c, 0x210b, 0x080c, 0x22e1, 0x080c, 0x13d4,
+	0x080c, 0x2135, 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6,
+	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0xab46, 0x0804, 0x30d8,
 	0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156,
-	0x080c, 0xa984, 0x080c, 0x22aa, 0x0804, 0x3008, 0x0106, 0x0006,
-	0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x20d4,
-	0x080c, 0xa984, 0x0804, 0x3008, 0x0106, 0x0006, 0x0126, 0x01c6,
-	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x20d4, 0x080c, 0xa984,
-	0x080c, 0x22aa, 0x0804, 0x3008, 0x0106, 0x0006, 0x0126, 0x01c6,
-	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0xa984, 0x080c, 0x20fe,
-	0x0804, 0x3008, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
-	0x0146, 0x0156, 0x080c, 0xa984, 0x080c, 0x22aa, 0x080c, 0x20fe,
-	0x0804, 0x3008, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
-	0x0146, 0x0156, 0x080c, 0x20d4, 0x080c, 0xa984, 0x080c, 0x20fe,
-	0x0804, 0x3008, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
-	0x0146, 0x0156, 0x080c, 0x20d4, 0x080c, 0xa984, 0x080c, 0x22aa,
-	0x080c, 0x20fe, 0x0804, 0x3008, 0x0106, 0x0006, 0x0126, 0x01c6,
-	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0xa984, 0x080c, 0x13bb,
-	0x0804, 0x3008, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
-	0x0146, 0x0156, 0x080c, 0xa984, 0x080c, 0x22aa, 0x080c, 0x13bb,
-	0x0804, 0x3008, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
-	0x0146, 0x0156, 0x080c, 0x20d4, 0x080c, 0xa984, 0x080c, 0x13bb,
-	0x0804, 0x3008, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
-	0x0146, 0x0156, 0x080c, 0x20d4, 0x080c, 0xa984, 0x080c, 0x22aa,
-	0x080c, 0x13bb, 0x0804, 0x3008, 0x0106, 0x0006, 0x0126, 0x01c6,
-	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0xa984, 0x080c, 0x13bb,
-	0x080c, 0x20fe, 0x0804, 0x3008, 0x0106, 0x0006, 0x0126, 0x01c6,
-	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0xa984, 0x080c, 0x22aa,
-	0x080c, 0x13bb, 0x080c, 0x20fe, 0x0804, 0x3008, 0x0106, 0x0006,
-	0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x20d4,
-	0x080c, 0xa984, 0x080c, 0x13bb, 0x080c, 0x20fe, 0x0804, 0x3008,
+	0x080c, 0xab46, 0x080c, 0x22e1, 0x0804, 0x30d8, 0x0106, 0x0006,
+	0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x210b,
+	0x080c, 0xab46, 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6,
+	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x210b, 0x080c, 0xab46,
+	0x080c, 0x22e1, 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6,
+	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0xab46, 0x080c, 0x2135,
+	0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
+	0x0146, 0x0156, 0x080c, 0xab46, 0x080c, 0x22e1, 0x080c, 0x2135,
+	0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
+	0x0146, 0x0156, 0x080c, 0x210b, 0x080c, 0xab46, 0x080c, 0x2135,
+	0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
+	0x0146, 0x0156, 0x080c, 0x210b, 0x080c, 0xab46, 0x080c, 0x22e1,
+	0x080c, 0x2135, 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6,
+	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0xab46, 0x080c, 0x13d4,
+	0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
+	0x0146, 0x0156, 0x080c, 0xab46, 0x080c, 0x22e1, 0x080c, 0x13d4,
+	0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
+	0x0146, 0x0156, 0x080c, 0x210b, 0x080c, 0xab46, 0x080c, 0x13d4,
+	0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
+	0x0146, 0x0156, 0x080c, 0x210b, 0x080c, 0xab46, 0x080c, 0x22e1,
+	0x080c, 0x13d4, 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6,
+	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0xab46, 0x080c, 0x13d4,
+	0x080c, 0x2135, 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6,
+	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0xab46, 0x080c, 0x22e1,
+	0x080c, 0x13d4, 0x080c, 0x2135, 0x0804, 0x30d8, 0x0106, 0x0006,
+	0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x210b,
+	0x080c, 0xab46, 0x080c, 0x13d4, 0x080c, 0x2135, 0x0804, 0x30d8,
 	0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156,
-	0x080c, 0x20d4, 0x080c, 0xa984, 0x080c, 0x22aa, 0x080c, 0x13bb,
-	0x080c, 0x20fe, 0x0804, 0x3008, 0x0106, 0x0006, 0x0126, 0x01c6,
-	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2764, 0x080c, 0xa984,
-	0x0804, 0x3008, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
-	0x0146, 0x0156, 0x080c, 0x2764, 0x080c, 0xa984, 0x080c, 0x22aa,
-	0x0804, 0x3008, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
-	0x0146, 0x0156, 0x080c, 0x2764, 0x080c, 0x20d4, 0x080c, 0xa984,
-	0x0804, 0x3008, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
-	0x0146, 0x0156, 0x080c, 0x2764, 0x080c, 0x20d4, 0x080c, 0xa984,
-	0x080c, 0x22aa, 0x0804, 0x3008, 0x0106, 0x0006, 0x0126, 0x01c6,
-	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2764, 0x080c, 0xa984,
-	0x080c, 0x20fe, 0x0804, 0x3008, 0x0106, 0x0006, 0x0126, 0x01c6,
-	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2764, 0x080c, 0xa984,
-	0x080c, 0x22aa, 0x080c, 0x20fe, 0x0804, 0x3008, 0x0106, 0x0006,
-	0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2764,
-	0x080c, 0x20d4, 0x080c, 0xa984, 0x080c, 0x20fe, 0x0804, 0x3008,
+	0x080c, 0x210b, 0x080c, 0xab46, 0x080c, 0x22e1, 0x080c, 0x13d4,
+	0x080c, 0x2135, 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6,
+	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x27a5, 0x080c, 0xab46,
+	0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
+	0x0146, 0x0156, 0x080c, 0x27a5, 0x080c, 0xab46, 0x080c, 0x22e1,
+	0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
+	0x0146, 0x0156, 0x080c, 0x27a5, 0x080c, 0x210b, 0x080c, 0xab46,
+	0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136,
+	0x0146, 0x0156, 0x080c, 0x27a5, 0x080c, 0x210b, 0x080c, 0xab46,
+	0x080c, 0x22e1, 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6,
+	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x27a5, 0x080c, 0xab46,
+	0x080c, 0x2135, 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6,
+	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x27a5, 0x080c, 0xab46,
+	0x080c, 0x22e1, 0x080c, 0x2135, 0x0804, 0x30d8, 0x0106, 0x0006,
+	0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x27a5,
+	0x080c, 0x210b, 0x080c, 0xab46, 0x080c, 0x2135, 0x0804, 0x30d8,
 	0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156,
-	0x080c, 0x2764, 0x080c, 0x20d4, 0x080c, 0xa984, 0x080c, 0x22aa,
-	0x080c, 0x20fe, 0x0804, 0x3008, 0x0106, 0x0006, 0x0126, 0x01c6,
-	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2764, 0x080c, 0xa984,
-	0x080c, 0x13bb, 0x0804, 0x3008, 0x0106, 0x0006, 0x0126, 0x01c6,
-	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2764, 0x080c, 0xa984,
-	0x080c, 0x22aa, 0x080c, 0x13bb, 0x0804, 0x3008, 0x0106, 0x0006,
-	0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2764,
-	0x080c, 0x20d4, 0x080c, 0xa984, 0x080c, 0x13bb, 0x0804, 0x3008,
+	0x080c, 0x27a5, 0x080c, 0x210b, 0x080c, 0xab46, 0x080c, 0x22e1,
+	0x080c, 0x2135, 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6,
+	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x27a5, 0x080c, 0xab46,
+	0x080c, 0x13d4, 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6,
+	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x27a5, 0x080c, 0xab46,
+	0x080c, 0x22e1, 0x080c, 0x13d4, 0x0804, 0x30d8, 0x0106, 0x0006,
+	0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x27a5,
+	0x080c, 0x210b, 0x080c, 0xab46, 0x080c, 0x13d4, 0x0804, 0x30d8,
 	0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156,
-	0x080c, 0x2764, 0x080c, 0x20d4, 0x080c, 0xa984, 0x080c, 0x22aa,
-	0x080c, 0x13bb, 0x0804, 0x3008, 0x0106, 0x0006, 0x0126, 0x01c6,
-	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2764, 0x080c, 0xa984,
-	0x080c, 0x13bb, 0x080c, 0x20fe, 0x04d8, 0x0106, 0x0006, 0x0126,
-	0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2764, 0x080c,
-	0xa984, 0x080c, 0x22aa, 0x080c, 0x13bb, 0x080c, 0x20fe, 0x0440,
+	0x080c, 0x27a5, 0x080c, 0x210b, 0x080c, 0xab46, 0x080c, 0x22e1,
+	0x080c, 0x13d4, 0x0804, 0x30d8, 0x0106, 0x0006, 0x0126, 0x01c6,
+	0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x27a5, 0x080c, 0xab46,
+	0x080c, 0x13d4, 0x080c, 0x2135, 0x04d8, 0x0106, 0x0006, 0x0126,
+	0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x27a5, 0x080c,
+	0xab46, 0x080c, 0x22e1, 0x080c, 0x13d4, 0x080c, 0x2135, 0x0440,
 	0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156,
-	0x080c, 0x2764, 0x080c, 0x20d4, 0x080c, 0x13bb, 0x080c, 0xa984,
-	0x080c, 0x20fe, 0x00a8, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
-	0x0136, 0x0146, 0x0156, 0x080c, 0x2764, 0x080c, 0x20d4, 0x080c,
-	0xa984, 0x080c, 0x22aa, 0x080c, 0x13bb, 0x080c, 0x20fe, 0x0000,
+	0x080c, 0x27a5, 0x080c, 0x210b, 0x080c, 0x13d4, 0x080c, 0xab46,
+	0x080c, 0x2135, 0x00a8, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
+	0x0136, 0x0146, 0x0156, 0x080c, 0x27a5, 0x080c, 0x210b, 0x080c,
+	0xab46, 0x080c, 0x22e1, 0x080c, 0x13d4, 0x080c, 0x2135, 0x0000,
 	0x015e, 0x014e, 0x013e, 0x01de, 0x01ce, 0x012e, 0x000e, 0x010e,
-	0x000d, 0x00b6, 0x00c6, 0x0026, 0x0046, 0x9026, 0x080c, 0x6a9b,
-	0x1904, 0x3121, 0x72dc, 0x2001, 0x197b, 0x2004, 0x9005, 0x1110,
-	0xd29c, 0x0148, 0xd284, 0x1138, 0xd2bc, 0x1904, 0x3121, 0x080c,
-	0x3126, 0x0804, 0x3121, 0xd2cc, 0x1904, 0x3121, 0x080c, 0x753d,
-	0x1120, 0x70af, 0xffff, 0x0804, 0x3121, 0xd294, 0x0120, 0x70af,
-	0xffff, 0x0804, 0x3121, 0x080c, 0x33a8, 0x0160, 0x080c, 0xd09b,
-	0x0128, 0x2001, 0x1818, 0x203c, 0x0804, 0x30ae, 0x70af, 0xffff,
-	0x0804, 0x3121, 0x2001, 0x1818, 0x203c, 0x7294, 0xd284, 0x0904,
-	0x30ae, 0xd28c, 0x1904, 0x30ae, 0x0036, 0x73ac, 0x938e, 0xffff,
+	0x000d, 0x00b6, 0x00c6, 0x0026, 0x0046, 0x9026, 0x080c, 0x6b93,
+	0x1904, 0x31f1, 0x72dc, 0x2001, 0x197d, 0x2004, 0x9005, 0x1110,
+	0xd29c, 0x0148, 0xd284, 0x1138, 0xd2bc, 0x1904, 0x31f1, 0x080c,
+	0x31f6, 0x0804, 0x31f1, 0xd2cc, 0x1904, 0x31f1, 0x080c, 0x76a5,
+	0x1120, 0x70af, 0xffff, 0x0804, 0x31f1, 0xd294, 0x0120, 0x70af,
+	0xffff, 0x0804, 0x31f1, 0x080c, 0x3478, 0x0160, 0x080c, 0xd33e,
+	0x0128, 0x2001, 0x1818, 0x203c, 0x0804, 0x317e, 0x70af, 0xffff,
+	0x0804, 0x31f1, 0x2001, 0x1818, 0x203c, 0x7294, 0xd284, 0x0904,
+	0x317e, 0xd28c, 0x1904, 0x317e, 0x0036, 0x73ac, 0x938e, 0xffff,
 	0x1110, 0x2019, 0x0001, 0x8314, 0x92e0, 0x1d80, 0x2c04, 0x938c,
 	0x0001, 0x0120, 0x9084, 0xff00, 0x8007, 0x0010, 0x9084, 0x00ff,
 	0x970e, 0x05d0, 0x908e, 0x0000, 0x05b8, 0x908e, 0x00ff, 0x1150,
 	0x7230, 0xd284, 0x15b0, 0x7294, 0xc28d, 0x7296, 0x70af, 0xffff,
-	0x003e, 0x04a0, 0x900e, 0x080c, 0x2661, 0x080c, 0x6632, 0x1538,
+	0x003e, 0x04a0, 0x900e, 0x080c, 0x26a2, 0x080c, 0x671e, 0x1538,
 	0x9006, 0xb8bb, 0x0520, 0xb8ac, 0x9005, 0x0148, 0x00c6, 0x2060,
-	0x080c, 0x8c1f, 0x00ce, 0x090c, 0x8fbc, 0xb8af, 0x0000, 0x080c,
-	0x6add, 0x1168, 0x7030, 0xd08c, 0x0130, 0xb800, 0xd0bc, 0x0138,
-	0x080c, 0x6986, 0x0120, 0x080c, 0x313f, 0x0148, 0x0028, 0x080c,
-	0x328b, 0x080c, 0x316b, 0x0118, 0x8318, 0x0804, 0x305b, 0x73ae,
-	0x0010, 0x70af, 0xffff, 0x003e, 0x0804, 0x3121, 0x9780, 0x33b9,
+	0x080c, 0x8d8f, 0x00ce, 0x090c, 0x9130, 0xb8af, 0x0000, 0x080c,
+	0x6bd5, 0x1168, 0x7030, 0xd08c, 0x0130, 0xb800, 0xd0bc, 0x0138,
+	0x080c, 0x6a7c, 0x0120, 0x080c, 0x320f, 0x0148, 0x0028, 0x080c,
+	0x335b, 0x080c, 0x323b, 0x0118, 0x8318, 0x0804, 0x312b, 0x73ae,
+	0x0010, 0x70af, 0xffff, 0x003e, 0x0804, 0x31f1, 0x9780, 0x3489,
 	0x203d, 0x97bc, 0xff00, 0x873f, 0x2041, 0x007e, 0x70ac, 0x9096,
 	0xffff, 0x1118, 0x900e, 0x28a8, 0x0050, 0x9812, 0x0220, 0x2008,
-	0x9802, 0x20a8, 0x0020, 0x70af, 0xffff, 0x0804, 0x3121, 0x2700,
-	0x0156, 0x0016, 0x9106, 0x0904, 0x3116, 0xc484, 0x080c, 0x6693,
-	0x0148, 0x080c, 0xd09b, 0x1904, 0x3116, 0x080c, 0x6632, 0x1904,
-	0x311e, 0x0008, 0xc485, 0xb8bb, 0x0520, 0xb8ac, 0x9005, 0x0148,
-	0x00c6, 0x2060, 0x080c, 0x8c1f, 0x00ce, 0x090c, 0x8fbc, 0xb8af,
-	0x0000, 0x080c, 0x6add, 0x1130, 0x7030, 0xd08c, 0x01f8, 0xb800,
-	0xd0bc, 0x11e0, 0x7294, 0xd28c, 0x0180, 0x080c, 0x6add, 0x9082,
-	0x0006, 0x02e0, 0xd484, 0x1118, 0x080c, 0x6657, 0x0028, 0x080c,
-	0x331e, 0x01a0, 0x080c, 0x3349, 0x0088, 0x080c, 0x328b, 0x080c,
-	0xd09b, 0x1160, 0x080c, 0x316b, 0x0188, 0x0040, 0x080c, 0xd09b,
-	0x1118, 0x080c, 0x331e, 0x0110, 0x0451, 0x0140, 0x001e, 0x8108,
-	0x015e, 0x1f04, 0x30c7, 0x70af, 0xffff, 0x0018, 0x001e, 0x015e,
+	0x9802, 0x20a8, 0x0020, 0x70af, 0xffff, 0x0804, 0x31f1, 0x2700,
+	0x0156, 0x0016, 0x9106, 0x0904, 0x31e6, 0xc484, 0x080c, 0x6789,
+	0x0148, 0x080c, 0xd33e, 0x1904, 0x31e6, 0x080c, 0x671e, 0x1904,
+	0x31ee, 0x0008, 0xc485, 0xb8bb, 0x0520, 0xb8ac, 0x9005, 0x0148,
+	0x00c6, 0x2060, 0x080c, 0x8d8f, 0x00ce, 0x090c, 0x9130, 0xb8af,
+	0x0000, 0x080c, 0x6bd5, 0x1130, 0x7030, 0xd08c, 0x01f8, 0xb800,
+	0xd0bc, 0x11e0, 0x7294, 0xd28c, 0x0180, 0x080c, 0x6bd5, 0x9082,
+	0x0006, 0x02e0, 0xd484, 0x1118, 0x080c, 0x6743, 0x0028, 0x080c,
+	0x33ee, 0x01a0, 0x080c, 0x3419, 0x0088, 0x080c, 0x335b, 0x080c,
+	0xd33e, 0x1160, 0x080c, 0x323b, 0x0188, 0x0040, 0x080c, 0xd33e,
+	0x1118, 0x080c, 0x33ee, 0x0110, 0x0451, 0x0140, 0x001e, 0x8108,
+	0x015e, 0x1f04, 0x3197, 0x70af, 0xffff, 0x0018, 0x001e, 0x015e,
 	0x71ae, 0x004e, 0x002e, 0x00ce, 0x00be, 0x0005, 0x00c6, 0x0016,
-	0x70af, 0x0001, 0x2009, 0x007e, 0x080c, 0x6632, 0x1168, 0xb813,
-	0x00ff, 0xb817, 0xfffe, 0x080c, 0x328b, 0x04a9, 0x0128, 0x70dc,
-	0xc0bd, 0x70de, 0x080c, 0xcde8, 0x001e, 0x00ce, 0x0005, 0x0016,
+	0x70af, 0x0001, 0x2009, 0x007e, 0x080c, 0x671e, 0x1168, 0xb813,
+	0x00ff, 0xb817, 0xfffe, 0x080c, 0x335b, 0x04a9, 0x0128, 0x70dc,
+	0xc0bd, 0x70de, 0x080c, 0xd084, 0x001e, 0x00ce, 0x0005, 0x0016,
 	0x0076, 0x00d6, 0x00c6, 0x2001, 0x184c, 0x2004, 0x9084, 0x00ff,
-	0xb842, 0x080c, 0xad20, 0x01d0, 0x2b00, 0x6012, 0x080c, 0xce15,
-	0x6023, 0x0001, 0x9006, 0x080c, 0x65cf, 0x2001, 0x0000, 0x080c,
-	0x65e3, 0x0126, 0x2091, 0x8000, 0x70a8, 0x8000, 0x70aa, 0x012e,
-	0x2009, 0x0004, 0x080c, 0xad4d, 0x9085, 0x0001, 0x00ce, 0x00de,
+	0xb842, 0x080c, 0xaf9f, 0x01d0, 0x2b00, 0x6012, 0x080c, 0xd0b1,
+	0x6023, 0x0001, 0x9006, 0x080c, 0x66bb, 0x2001, 0x0000, 0x080c,
+	0x66cf, 0x0126, 0x2091, 0x8000, 0x70a8, 0x8000, 0x70aa, 0x012e,
+	0x2009, 0x0004, 0x080c, 0xafcc, 0x9085, 0x0001, 0x00ce, 0x00de,
 	0x007e, 0x001e, 0x0005, 0x0016, 0x0076, 0x00d6, 0x00c6, 0x2001,
-	0x184c, 0x2004, 0x9084, 0x00ff, 0xb842, 0x080c, 0xad20, 0x0548,
+	0x184c, 0x2004, 0x9084, 0x00ff, 0xb842, 0x080c, 0xaf9f, 0x0548,
 	0x2b00, 0x6012, 0xb800, 0xc0c4, 0xb802, 0xb8a0, 0x9086, 0x007e,
 	0x0140, 0xb804, 0x9084, 0x00ff, 0x9086, 0x0006, 0x1110, 0x080c,
-	0x3240, 0x080c, 0xce15, 0x6023, 0x0001, 0x9006, 0x080c, 0x65cf,
-	0x2001, 0x0002, 0x080c, 0x65e3, 0x0126, 0x2091, 0x8000, 0x70a8,
-	0x8000, 0x70aa, 0x012e, 0x2009, 0x0002, 0x080c, 0xad4d, 0x9085,
+	0x3310, 0x080c, 0xd0b1, 0x6023, 0x0001, 0x9006, 0x080c, 0x66bb,
+	0x2001, 0x0002, 0x080c, 0x66cf, 0x0126, 0x2091, 0x8000, 0x70a8,
+	0x8000, 0x70aa, 0x012e, 0x2009, 0x0002, 0x080c, 0xafcc, 0x9085,
 	0x0001, 0x00ce, 0x00de, 0x007e, 0x001e, 0x0005, 0x00b6, 0x00c6,
-	0x0026, 0x2009, 0x0080, 0x080c, 0x6632, 0x1140, 0xb813, 0x00ff,
+	0x0026, 0x2009, 0x0080, 0x080c, 0x671e, 0x1140, 0xb813, 0x00ff,
 	0xb817, 0xfffc, 0x0039, 0x0110, 0x70e3, 0xffff, 0x002e, 0x00ce,
-	0x00be, 0x0005, 0x0016, 0x0076, 0x00d6, 0x00c6, 0x080c, 0xac5a,
-	0x01d0, 0x2b00, 0x6012, 0x080c, 0xce15, 0x6023, 0x0001, 0x9006,
-	0x080c, 0x65cf, 0x2001, 0x0002, 0x080c, 0x65e3, 0x0126, 0x2091,
+	0x00be, 0x0005, 0x0016, 0x0076, 0x00d6, 0x00c6, 0x080c, 0xaed8,
+	0x01d0, 0x2b00, 0x6012, 0x080c, 0xd0b1, 0x6023, 0x0001, 0x9006,
+	0x080c, 0x66bb, 0x2001, 0x0002, 0x080c, 0x66cf, 0x0126, 0x2091,
 	0x8000, 0x70e4, 0x8000, 0x70e6, 0x012e, 0x2009, 0x0002, 0x080c,
-	0xad4d, 0x9085, 0x0001, 0x00ce, 0x00de, 0x007e, 0x001e, 0x0005,
+	0xafcc, 0x9085, 0x0001, 0x00ce, 0x00de, 0x007e, 0x001e, 0x0005,
 	0x00c6, 0x00d6, 0x0126, 0x2091, 0x8000, 0x2009, 0x007f, 0x080c,
-	0x6632, 0x11b8, 0xb813, 0x00ff, 0xb817, 0xfffd, 0xb8d7, 0x0004,
-	0x080c, 0xac5a, 0x0170, 0x2b00, 0x6012, 0x6316, 0x6023, 0x0001,
-	0x620a, 0x080c, 0xce15, 0x2009, 0x0022, 0x080c, 0xad4d, 0x9085,
+	0x671e, 0x11b8, 0xb813, 0x00ff, 0xb817, 0xfffd, 0xb8d7, 0x0004,
+	0x080c, 0xaed8, 0x0170, 0x2b00, 0x6012, 0x6316, 0x6023, 0x0001,
+	0x620a, 0x080c, 0xd0b1, 0x2009, 0x0022, 0x080c, 0xafcc, 0x9085,
 	0x0001, 0x012e, 0x00de, 0x00ce, 0x0005, 0x00e6, 0x00c6, 0x0066,
-	0x0036, 0x0026, 0x00b6, 0x21f0, 0x080c, 0xa91e, 0x0106, 0x080c,
-	0x9448, 0x080c, 0x93b9, 0x080c, 0xa86f, 0x080c, 0xbbf9, 0x010e,
-	0x090c, 0xa93a, 0x3e08, 0x2130, 0x81ff, 0x0120, 0x20a9, 0x007e,
-	0x900e, 0x0018, 0x20a9, 0x007f, 0x900e, 0x0016, 0x080c, 0x6693,
+	0x0036, 0x0026, 0x00b6, 0x21f0, 0x080c, 0xaae0, 0x0106, 0x080c,
+	0x95cc, 0x080c, 0x9538, 0x080c, 0xaa31, 0x080c, 0xbe95, 0x010e,
+	0x090c, 0xaafc, 0x3e08, 0x2130, 0x81ff, 0x0120, 0x20a9, 0x007e,
+	0x900e, 0x0018, 0x20a9, 0x007f, 0x900e, 0x0016, 0x080c, 0x6789,
 	0x1140, 0x9686, 0x0002, 0x1118, 0xb800, 0xd0bc, 0x1110, 0x080c,
-	0x60ac, 0x001e, 0x8108, 0x1f04, 0x3225, 0x9686, 0x0001, 0x190c,
-	0x337c, 0x00be, 0x002e, 0x003e, 0x006e, 0x00ce, 0x00ee, 0x0005,
+	0x6198, 0x001e, 0x8108, 0x1f04, 0x32f5, 0x9686, 0x0001, 0x190c,
+	0x344c, 0x00be, 0x002e, 0x003e, 0x006e, 0x00ce, 0x00ee, 0x0005,
 	0x00e6, 0x00c6, 0x0046, 0x0036, 0x0026, 0x0016, 0x00b6, 0x080c,
-	0xa91e, 0x0106, 0x6210, 0x2258, 0xbaa0, 0x0026, 0x2019, 0x0029,
-	0x080c, 0x943d, 0x0076, 0x2039, 0x0000, 0x080c, 0x9306, 0x2c08,
-	0x080c, 0xe167, 0x007e, 0x001e, 0x010e, 0x090c, 0xa93a, 0xba10,
-	0xbb14, 0xbc84, 0x080c, 0x60ac, 0xba12, 0xbb16, 0xbc86, 0x00be,
+	0xaae0, 0x0106, 0x6210, 0x2258, 0xbaa0, 0x0026, 0x2019, 0x0029,
+	0x080c, 0x95c1, 0x0076, 0x2039, 0x0000, 0x080c, 0x947e, 0x2c08,
+	0x080c, 0xe440, 0x007e, 0x001e, 0x010e, 0x090c, 0xaafc, 0xba10,
+	0xbb14, 0xbc84, 0x080c, 0x6198, 0xba12, 0xbb16, 0xbc86, 0x00be,
 	0x001e, 0x002e, 0x003e, 0x004e, 0x00ce, 0x00ee, 0x0005, 0x00e6,
 	0x0006, 0x00b6, 0x6010, 0x2058, 0xb8a0, 0x00be, 0x9086, 0x0080,
 	0x0150, 0x2071, 0x1800, 0x70a8, 0x9005, 0x0110, 0x8001, 0x70aa,
 	0x000e, 0x00ee, 0x0005, 0x2071, 0x1800, 0x70e4, 0x9005, 0x0dc0,
 	0x8001, 0x70e6, 0x0ca8, 0xb800, 0xc08c, 0xb802, 0x0005, 0x00f6,
 	0x00e6, 0x00c6, 0x00b6, 0x0046, 0x0036, 0x0026, 0x0016, 0x0156,
-	0x2178, 0x080c, 0xa91e, 0x0106, 0x81ff, 0x1118, 0x20a9, 0x0001,
-	0x0078, 0x080c, 0x573e, 0xd0c4, 0x0140, 0xd0a4, 0x0130, 0x9006,
-	0x2020, 0x2009, 0x002d, 0x080c, 0xe445, 0x20a9, 0x0800, 0x9016,
-	0x0026, 0x928e, 0x007e, 0x0904, 0x32fa, 0x928e, 0x007f, 0x0904,
-	0x32fa, 0x928e, 0x0080, 0x05f0, 0x9288, 0x1000, 0x210c, 0x81ff,
-	0x05c8, 0x8fff, 0x1150, 0x2001, 0x198d, 0x0006, 0x2003, 0x0001,
-	0x080c, 0x330b, 0x000e, 0x2003, 0x0000, 0x00b6, 0x00c6, 0x2158,
-	0x2001, 0x0001, 0x080c, 0x6aa7, 0x00ce, 0x00be, 0x2019, 0x0029,
-	0x080c, 0x943d, 0x0076, 0x2039, 0x0000, 0x080c, 0x9306, 0x00b6,
+	0x2178, 0x080c, 0xaae0, 0x0106, 0x81ff, 0x1118, 0x20a9, 0x0001,
+	0x0078, 0x080c, 0x5826, 0xd0c4, 0x0140, 0xd0a4, 0x0130, 0x9006,
+	0x2020, 0x2009, 0x002d, 0x080c, 0xe72a, 0x20a9, 0x0800, 0x9016,
+	0x0026, 0x928e, 0x007e, 0x0904, 0x33ca, 0x928e, 0x007f, 0x0904,
+	0x33ca, 0x928e, 0x0080, 0x05f0, 0x9288, 0x1000, 0x210c, 0x81ff,
+	0x05c8, 0x8fff, 0x1150, 0x2001, 0x198f, 0x0006, 0x2003, 0x0001,
+	0x080c, 0x33db, 0x000e, 0x2003, 0x0000, 0x00b6, 0x00c6, 0x2158,
+	0x2001, 0x0001, 0x080c, 0x6b9f, 0x00ce, 0x00be, 0x2019, 0x0029,
+	0x080c, 0x95c1, 0x0076, 0x2039, 0x0000, 0x080c, 0x947e, 0x00b6,
 	0x00c6, 0x0026, 0x2158, 0xba04, 0x9294, 0x00ff, 0x9286, 0x0006,
 	0x1118, 0xb807, 0x0404, 0x0028, 0x2001, 0x0004, 0x8007, 0x9215,
-	0xba06, 0x002e, 0x00ce, 0x00be, 0x0016, 0x2c08, 0x080c, 0xe167,
-	0x001e, 0x007e, 0x002e, 0x8210, 0x1f04, 0x32b0, 0x010e, 0x090c,
-	0xa93a, 0x015e, 0x001e, 0x002e, 0x003e, 0x004e, 0x00be, 0x00ce,
-	0x00ee, 0x00fe, 0x0005, 0x0046, 0x0026, 0x0016, 0x080c, 0x573e,
+	0xba06, 0x002e, 0x00ce, 0x00be, 0x0016, 0x2c08, 0x080c, 0xe440,
+	0x001e, 0x007e, 0x002e, 0x8210, 0x1f04, 0x3380, 0x010e, 0x090c,
+	0xaafc, 0x015e, 0x001e, 0x002e, 0x003e, 0x004e, 0x00be, 0x00ce,
+	0x00ee, 0x00fe, 0x0005, 0x0046, 0x0026, 0x0016, 0x080c, 0x5826,
 	0xd0c4, 0x0140, 0xd0a4, 0x0130, 0x9006, 0x2220, 0x2009, 0x0029,
-	0x080c, 0xe445, 0x001e, 0x002e, 0x004e, 0x0005, 0x0016, 0x0026,
-	0x0036, 0x00c6, 0x7294, 0x82ff, 0x01e8, 0x080c, 0x6ad5, 0x11d0,
-	0x2100, 0x080c, 0x2694, 0x81ff, 0x01b8, 0x2019, 0x0001, 0x8314,
+	0x080c, 0xe72a, 0x001e, 0x002e, 0x004e, 0x0005, 0x0016, 0x0026,
+	0x0036, 0x00c6, 0x7294, 0x82ff, 0x01e8, 0x080c, 0x6bcd, 0x11d0,
+	0x2100, 0x080c, 0x26d5, 0x81ff, 0x01b8, 0x2019, 0x0001, 0x8314,
 	0x92e0, 0x1d80, 0x2c04, 0xd384, 0x0120, 0x9084, 0xff00, 0x8007,
 	0x0010, 0x9084, 0x00ff, 0x9116, 0x0138, 0x9096, 0x00ff, 0x0110,
 	0x8318, 0x0c68, 0x9085, 0x0001, 0x00ce, 0x003e, 0x002e, 0x001e,
-	0x0005, 0x0016, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xa91e,
+	0x0005, 0x0016, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xaae0,
 	0x0106, 0x0036, 0x2019, 0x0029, 0x00c1, 0x003e, 0x010e, 0x090c,
-	0xa93a, 0x9180, 0x1000, 0x2004, 0x9065, 0x0158, 0x0016, 0x00c6,
-	0x2061, 0x1b34, 0x001e, 0x6112, 0x080c, 0x3240, 0x001e, 0x080c,
-	0x6657, 0x012e, 0x00ce, 0x001e, 0x0005, 0x0016, 0x0026, 0x2110,
-	0x080c, 0xa404, 0x080c, 0xe7ac, 0x002e, 0x001e, 0x0005, 0x2001,
-	0x1837, 0x2004, 0xd0cc, 0x0005, 0x00c6, 0x00b6, 0x080c, 0x753d,
-	0x1118, 0x20a9, 0x0800, 0x0010, 0x20a9, 0x0782, 0x080c, 0x753d,
+	0xaafc, 0x9180, 0x1000, 0x2004, 0x9065, 0x0158, 0x0016, 0x00c6,
+	0x2061, 0x1b3a, 0x001e, 0x6112, 0x080c, 0x3310, 0x001e, 0x080c,
+	0x6743, 0x012e, 0x00ce, 0x001e, 0x0005, 0x0016, 0x0026, 0x2110,
+	0x080c, 0xa5c6, 0x080c, 0xea92, 0x002e, 0x001e, 0x0005, 0x2001,
+	0x1837, 0x2004, 0xd0cc, 0x0005, 0x00c6, 0x00b6, 0x080c, 0x76a5,
+	0x1118, 0x20a9, 0x0800, 0x0010, 0x20a9, 0x0782, 0x080c, 0x76a5,
 	0x1110, 0x900e, 0x0010, 0x2009, 0x007e, 0x9180, 0x1000, 0x2004,
-	0x905d, 0x0130, 0x86ff, 0x0110, 0xb800, 0xd0bc, 0x090c, 0x6657,
-	0x8108, 0x1f04, 0x338d, 0x2061, 0x1800, 0x607f, 0x0000, 0x6080,
+	0x905d, 0x0130, 0x86ff, 0x0110, 0xb800, 0xd0bc, 0x090c, 0x6743,
+	0x8108, 0x1f04, 0x345d, 0x2061, 0x1800, 0x607f, 0x0000, 0x6080,
 	0x9084, 0x00ff, 0x6082, 0x60b3, 0x0000, 0x00be, 0x00ce, 0x0005,
 	0x2001, 0x1869, 0x2004, 0xd0bc, 0x0005, 0x2011, 0x1848, 0x2214,
 	0xd2ec, 0x0005, 0x0026, 0x2011, 0x1867, 0x2214, 0xd2dc, 0x002e,
@@ -1483,1721 +1509,1726 @@ unsigned short risc_code01[] = { 
 	0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
 	0x8000, 0x2071, 0x189e, 0x7003, 0x0002, 0x9006, 0x7016, 0x701a,
 	0x704a, 0x704e, 0x700e, 0x7042, 0x7046, 0x703b, 0x18ba, 0x703f,
-	0x18ba, 0x7007, 0x0001, 0x080c, 0x1060, 0x090c, 0x0d7d, 0x2900,
-	0x706a, 0xa867, 0x0002, 0xa8ab, 0xdcb0, 0x080c, 0x1060, 0x090c,
-	0x0d7d, 0x2900, 0x706e, 0xa867, 0x0002, 0xa8ab, 0xdcb0, 0x0005,
-	0x2071, 0x189e, 0x7004, 0x0002, 0x34e8, 0x34e9, 0x34fc, 0x3510,
-	0x0005, 0x1004, 0x34f9, 0x0e04, 0x34f9, 0x2079, 0x0000, 0x0126,
+	0x18ba, 0x7007, 0x0001, 0x080c, 0x1072, 0x090c, 0x0d85, 0x2900,
+	0x706a, 0xa867, 0x0002, 0xa8ab, 0xdcb0, 0x080c, 0x1072, 0x090c,
+	0x0d85, 0x2900, 0x706e, 0xa867, 0x0002, 0xa8ab, 0xdcb0, 0x0005,
+	0x2071, 0x189e, 0x7004, 0x0002, 0x35b8, 0x35b9, 0x35cc, 0x35e0,
+	0x0005, 0x1004, 0x35c9, 0x0e04, 0x35c9, 0x2079, 0x0000, 0x0126,
 	0x2091, 0x8000, 0x700c, 0x9005, 0x1128, 0x700f, 0x0001, 0x012e,
 	0x0468, 0x0005, 0x012e, 0x0ce8, 0x2079, 0x0000, 0x2061, 0x18b8,
 	0x2c4c, 0xa86c, 0x908e, 0x0100, 0x0128, 0x9086, 0x0200, 0x0904,
-	0x35e4, 0x0005, 0x7018, 0x2048, 0x2061, 0x1800, 0x701c, 0x0807,
+	0x36b4, 0x0005, 0x7018, 0x2048, 0x2061, 0x1800, 0x701c, 0x0807,
 	0x7014, 0x2048, 0xa864, 0x9094, 0x00ff, 0x9296, 0x0029, 0x1120,
 	0xaa78, 0xd2fc, 0x0128, 0x0005, 0x9086, 0x0103, 0x0108, 0x0005,
 	0x2079, 0x0000, 0x2061, 0x1800, 0x701c, 0x0807, 0x2061, 0x1800,
 	0x7880, 0x908a, 0x0040, 0x1210, 0x61d0, 0x0042, 0x2100, 0x908a,
-	0x003f, 0x1a04, 0x35e1, 0x61d0, 0x0804, 0x3576, 0x35b8, 0x35f0,
-	0x35e1, 0x35fa, 0x3604, 0x360a, 0x360e, 0x361e, 0x3622, 0x3638,
-	0x363e, 0x3644, 0x364f, 0x365a, 0x3669, 0x3678, 0x3686, 0x369d,
-	0x36b8, 0x35e1, 0x3761, 0x379f, 0x3844, 0x3855, 0x3878, 0x35e1,
-	0x35e1, 0x35e1, 0x38b0, 0x38d0, 0x38d9, 0x3905, 0x390b, 0x35e1,
-	0x3951, 0x35e1, 0x35e1, 0x35e1, 0x35e1, 0x35e1, 0x395c, 0x3965,
-	0x396d, 0x396f, 0x35e1, 0x35e1, 0x35e1, 0x35e1, 0x35e1, 0x35e1,
-	0x399f, 0x35e1, 0x35e1, 0x35e1, 0x35e1, 0x35e1, 0x39bc, 0x3a26,
-	0x35e1, 0x35e1, 0x35e1, 0x35e1, 0x35e1, 0x35e1, 0x0002, 0x3a50,
-	0x3a53, 0x3ab2, 0x3acb, 0x3afb, 0x3d9d, 0x35e1, 0x52f4, 0x35e1,
-	0x35e1, 0x35e1, 0x35e1, 0x35e1, 0x35e1, 0x35e1, 0x35e1, 0x3638,
-	0x363e, 0x428c, 0x5762, 0x42aa, 0x5383, 0x53d4, 0x54df, 0x35e1,
-	0x5541, 0x557d, 0x55ae, 0x56be, 0x55db, 0x563e, 0x35e1, 0x42ae,
-	0x4463, 0x4479, 0x449e, 0x4503, 0x4577, 0x4597, 0x460e, 0x466a,
-	0x46c6, 0x46c9, 0x46ee, 0x4760, 0x47ca, 0x47d2, 0x4904, 0x4a7c,
-	0x4ab0, 0x4d14, 0x35e1, 0x4d32, 0x4dd8, 0x4eba, 0x4f14, 0x35e1,
-	0x4fcb, 0x35e1, 0x5033, 0x504e, 0x47d2, 0x5294, 0x714c, 0x0000,
-	0x2021, 0x4000, 0x080c, 0x4b2e, 0x0126, 0x2091, 0x8000, 0x0e04,
-	0x35c2, 0x0010, 0x012e, 0x0cc0, 0x7c36, 0x9486, 0x4000, 0x0118,
+	0x003f, 0x1a04, 0x36b1, 0x61d0, 0x0804, 0x3646, 0x3688, 0x36c0,
+	0x36b1, 0x36cc, 0x36d6, 0x36dc, 0x36e0, 0x36f0, 0x36f4, 0x370a,
+	0x3710, 0x3716, 0x3721, 0x372c, 0x373b, 0x374a, 0x3758, 0x376f,
+	0x378a, 0x36b1, 0x3833, 0x3871, 0x3916, 0x3927, 0x394a, 0x36b1,
+	0x36b1, 0x36b1, 0x3982, 0x39a2, 0x39ab, 0x39d7, 0x39dd, 0x36b1,
+	0x3a23, 0x36b1, 0x36b1, 0x36b1, 0x36b1, 0x36b1, 0x3a2e, 0x3a37,
+	0x3a3f, 0x3a41, 0x36b1, 0x36b1, 0x36b1, 0x36b1, 0x36b1, 0x36b1,
+	0x3a71, 0x36b1, 0x36b1, 0x36b1, 0x36b1, 0x36b1, 0x3a8e, 0x3af2,
+	0x36b1, 0x36b1, 0x36b1, 0x36b1, 0x36b1, 0x36b1, 0x0002, 0x3b1c,
+	0x3b1f, 0x3b7e, 0x3b97, 0x3bc7, 0x3e6d, 0x36b1, 0x53db, 0x36b1,
+	0x36b1, 0x36b1, 0x36b1, 0x36b1, 0x36b1, 0x36b1, 0x36b1, 0x370a,
+	0x3710, 0x4365, 0x584a, 0x4383, 0x546a, 0x54bc, 0x55c7, 0x36b1,
+	0x5629, 0x5665, 0x5696, 0x57a6, 0x56c3, 0x5726, 0x36b1, 0x4387,
+	0x453c, 0x4552, 0x4577, 0x45dc, 0x4650, 0x4670, 0x46e7, 0x4743,
+	0x479f, 0x47a2, 0x47c7, 0x4839, 0x48a3, 0x48ab, 0x49e0, 0x4b58,
+	0x4b8c, 0x4df0, 0x36b1, 0x4e0e, 0x4eb4, 0x4f9d, 0x4ff7, 0x36b1,
+	0x50ae, 0x36b1, 0x511a, 0x5135, 0x48ab, 0x537b, 0x714c, 0x0000,
+	0x2021, 0x4000, 0x080c, 0x4c0a, 0x0126, 0x2091, 0x8000, 0x0e04,
+	0x3692, 0x0010, 0x012e, 0x0cc0, 0x7c36, 0x9486, 0x4000, 0x0118,
 	0x7833, 0x0011, 0x0010, 0x7833, 0x0010, 0x7c82, 0x7986, 0x7a8a,
 	0x7b8e, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c,
-	0x11ee, 0x7007, 0x0001, 0x2091, 0x5000, 0x700f, 0x0000, 0x012e,
+	0x1200, 0x7007, 0x0001, 0x2091, 0x5000, 0x700f, 0x0000, 0x012e,
 	0x0005, 0x2021, 0x4001, 0x08b0, 0x2021, 0x4002, 0x0898, 0x2021,
 	0x4003, 0x0880, 0x2021, 0x4005, 0x0868, 0x2021, 0x4006, 0x0850,
 	0x2039, 0x0001, 0x902e, 0x2520, 0x7b88, 0x7a8c, 0x7884, 0x7990,
-	0x0804, 0x4b3b, 0x2039, 0x0001, 0x902e, 0x2520, 0x7b88, 0x7a8c,
-	0x7884, 0x7990, 0x0804, 0x4b3e, 0x7984, 0x7888, 0x2114, 0x200a,
-	0x0804, 0x35b8, 0x7984, 0x2114, 0x0804, 0x35b8, 0x20e1, 0x0000,
-	0x2099, 0x0021, 0x20e9, 0x0000, 0x20a1, 0x0021, 0x20a9, 0x001f,
-	0x4003, 0x7984, 0x7a88, 0x7b8c, 0x0804, 0x35b8, 0x7884, 0x2060,
-	0x0804, 0x366b, 0x2009, 0x0003, 0x2011, 0x0003, 0x2019, 0x0008,
-	0x789b, 0x0137, 0x7893, 0xffff, 0x2001, 0x188f, 0x2004, 0x9005,
-	0x0118, 0x7896, 0x0804, 0x35b8, 0x7897, 0x0001, 0x0804, 0x35b8,
-	0x2039, 0x0001, 0x7d98, 0x7c9c, 0x0804, 0x35f4, 0x2039, 0x0001,
-	0x7d98, 0x7c9c, 0x0804, 0x35fe, 0x79a0, 0x9182, 0x0040, 0x0210,
-	0x0804, 0x35ed, 0x2138, 0x7d98, 0x7c9c, 0x0804, 0x35f4, 0x79a0,
-	0x9182, 0x0040, 0x0210, 0x0804, 0x35ed, 0x2138, 0x7d98, 0x7c9c,
-	0x0804, 0x35fe, 0x79a0, 0x9182, 0x0040, 0x0210, 0x0804, 0x35ed,
-	0x21e8, 0x7984, 0x7888, 0x20a9, 0x0001, 0x21a0, 0x4004, 0x0804,
-	0x35b8, 0x2061, 0x0800, 0xe10c, 0x9006, 0x2c15, 0x9200, 0x8c60,
-	0x8109, 0x1dd8, 0x2010, 0x9005, 0x0904, 0x35b8, 0x0804, 0x35e7,
-	0x79a0, 0x9182, 0x0040, 0x0210, 0x0804, 0x35ed, 0x21e0, 0x20a9,
-	0x0001, 0x7984, 0x2198, 0x4012, 0x0804, 0x35b8, 0x2069, 0x1847,
-	0x7884, 0x7990, 0x911a, 0x1a04, 0x35ed, 0x8019, 0x0904, 0x35ed,
-	0x684a, 0x6942, 0x788c, 0x6852, 0x7888, 0x6856, 0x9006, 0x685a,
-	0x685e, 0x080c, 0x7871, 0x0804, 0x35b8, 0x2069, 0x1847, 0x7884,
-	0x7994, 0x911a, 0x1a04, 0x35ed, 0x8019, 0x0904, 0x35ed, 0x684e,
-	0x6946, 0x788c, 0x6862, 0x7888, 0x6866, 0x9006, 0x686a, 0x686e,
-	0x0126, 0x2091, 0x8000, 0x080c, 0x6b43, 0x012e, 0x0804, 0x35b8,
-	0x902e, 0x2520, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x35ea,
-	0x7984, 0x7b88, 0x7a8c, 0x20a9, 0x0005, 0x20e9, 0x0001, 0x20a1,
-	0x18a6, 0x4101, 0x080c, 0x4af2, 0x1120, 0x2009, 0x0002, 0x0804,
-	0x35ea, 0x2009, 0x0020, 0xa85c, 0x9080, 0x0019, 0xaf60, 0x080c,
-	0x4b3b, 0x701f, 0x36dc, 0x0005, 0xa864, 0x2008, 0x9084, 0x00ff,
-	0x9096, 0x0011, 0x0168, 0x9096, 0x0019, 0x0150, 0x9096, 0x0015,
-	0x0138, 0x9096, 0x0048, 0x0120, 0x9096, 0x0029, 0x1904, 0x35ea,
-	0x810f, 0x918c, 0x00ff, 0x0904, 0x35ea, 0x7112, 0x7010, 0x8001,
-	0x0560, 0x7012, 0x080c, 0x4af2, 0x1120, 0x2009, 0x0002, 0x0804,
-	0x35ea, 0x2009, 0x0020, 0x7068, 0x2040, 0xa28c, 0xa390, 0xa494,
-	0xa598, 0x9290, 0x0040, 0x9399, 0x0000, 0x94a1, 0x0000, 0x95a9,
-	0x0000, 0xa85c, 0x9080, 0x0019, 0xaf60, 0x080c, 0x4b3b, 0x701f,
-	0x371a, 0x0005, 0xa864, 0x9084, 0x00ff, 0x9096, 0x0002, 0x0120,
-	0x9096, 0x000a, 0x1904, 0x35ea, 0x0888, 0x7014, 0x2048, 0xa868,
-	0xc0fd, 0xa86a, 0xa864, 0x9084, 0x00ff, 0x9096, 0x0029, 0x1160,
-	0xc2fd, 0xaa7a, 0x080c, 0x61ff, 0x0150, 0x0126, 0x2091, 0x8000,
-	0xa87a, 0xa982, 0x012e, 0x0050, 0x080c, 0x652f, 0x1128, 0x7007,
-	0x0003, 0x701f, 0x3746, 0x0005, 0x080c, 0x7022, 0x0126, 0x2091,
-	0x8000, 0x20a9, 0x0005, 0x20e1, 0x0001, 0x2099, 0x18a6, 0x400a,
-	0x2100, 0x9210, 0x9399, 0x0000, 0x94a1, 0x0000, 0x95a9, 0x0000,
-	0xa85c, 0x9080, 0x0019, 0x2009, 0x0020, 0x012e, 0xaf60, 0x0804,
-	0x4b3e, 0x2091, 0x8000, 0x7837, 0x4000, 0x7833, 0x0010, 0x7883,
-	0x4000, 0x7887, 0x4953, 0x788b, 0x5020, 0x788f, 0x2020, 0x2009,
-	0x017f, 0x2104, 0x7892, 0x3f00, 0x7896, 0x2061, 0x0100, 0x6200,
-	0x2061, 0x0200, 0x603c, 0x8007, 0x9205, 0x789a, 0x2009, 0x04fd,
-	0x2104, 0x789e, 0x2091, 0x5000, 0x2091, 0x4080, 0x2001, 0x0089,
-	0x2004, 0xd084, 0x0180, 0x2001, 0x1a21, 0x2004, 0x9005, 0x0128,
-	0x2001, 0x008b, 0x2004, 0xd0fc, 0x0dd8, 0x2001, 0x008a, 0x2003,
-	0x0002, 0x2003, 0x1001, 0x2071, 0x0080, 0x0804, 0x0427, 0x81ff,
-	0x1904, 0x35ea, 0x7984, 0x080c, 0x6693, 0x1904, 0x35ed, 0x7e98,
-	0x9684, 0x3fff, 0x9082, 0x4000, 0x1a04, 0x35ed, 0x7c88, 0x7d8c,
-	0x080c, 0x68c9, 0x080c, 0x6856, 0x1518, 0x2061, 0x1ddc, 0x0126,
+	0x81ff, 0x0d98, 0x0804, 0x4c17, 0x2039, 0x0001, 0x902e, 0x2520,
+	0x7b88, 0x7a8c, 0x7884, 0x7990, 0x0804, 0x4c1a, 0x7984, 0x7888,
+	0x2114, 0x200a, 0x0804, 0x3688, 0x7984, 0x2114, 0x0804, 0x3688,
+	0x20e1, 0x0000, 0x2099, 0x0021, 0x20e9, 0x0000, 0x20a1, 0x0021,
+	0x20a9, 0x001f, 0x4003, 0x7984, 0x7a88, 0x7b8c, 0x0804, 0x3688,
+	0x7884, 0x2060, 0x0804, 0x373d, 0x2009, 0x0003, 0x2011, 0x0003,
+	0x2019, 0x000f, 0x789b, 0x0137, 0x7893, 0xffff, 0x2001, 0x188f,
+	0x2004, 0x9005, 0x0118, 0x7896, 0x0804, 0x3688, 0x7897, 0x0001,
+	0x0804, 0x3688, 0x2039, 0x0001, 0x7d98, 0x7c9c, 0x0804, 0x36c4,
+	0x2039, 0x0001, 0x7d98, 0x7c9c, 0x0804, 0x36d0, 0x79a0, 0x9182,
+	0x0040, 0x0210, 0x0804, 0x36bd, 0x2138, 0x7d98, 0x7c9c, 0x0804,
+	0x36c4, 0x79a0, 0x9182, 0x0040, 0x0210, 0x0804, 0x36bd, 0x2138,
+	0x7d98, 0x7c9c, 0x0804, 0x36d0, 0x79a0, 0x9182, 0x0040, 0x0210,
+	0x0804, 0x36bd, 0x21e8, 0x7984, 0x7888, 0x20a9, 0x0001, 0x21a0,
+	0x4004, 0x0804, 0x3688, 0x2061, 0x0800, 0xe10c, 0x9006, 0x2c15,
+	0x9200, 0x8c60, 0x8109, 0x1dd8, 0x2010, 0x9005, 0x0904, 0x3688,
+	0x0804, 0x36b7, 0x79a0, 0x9182, 0x0040, 0x0210, 0x0804, 0x36bd,
+	0x21e0, 0x20a9, 0x0001, 0x7984, 0x2198, 0x4012, 0x0804, 0x3688,
+	0x2069, 0x1847, 0x7884, 0x7990, 0x911a, 0x1a04, 0x36bd, 0x8019,
+	0x0904, 0x36bd, 0x684a, 0x6942, 0x788c, 0x6852, 0x7888, 0x6856,
+	0x9006, 0x685a, 0x685e, 0x080c, 0x79d8, 0x0804, 0x3688, 0x2069,
+	0x1847, 0x7884, 0x7994, 0x911a, 0x1a04, 0x36bd, 0x8019, 0x0904,
+	0x36bd, 0x684e, 0x6946, 0x788c, 0x6862, 0x7888, 0x6866, 0x9006,
+	0x686a, 0x686e, 0x0126, 0x2091, 0x8000, 0x080c, 0x6c6d, 0x012e,
+	0x0804, 0x3688, 0x902e, 0x2520, 0x81ff, 0x0120, 0x2009, 0x0001,
+	0x0804, 0x36ba, 0x7984, 0x7b88, 0x7a8c, 0x20a9, 0x0005, 0x20e9,
+	0x0001, 0x20a1, 0x18a6, 0x4101, 0x080c, 0x4bce, 0x1120, 0x2009,
+	0x0002, 0x0804, 0x36ba, 0x2009, 0x0020, 0xa85c, 0x9080, 0x0019,
+	0xaf60, 0x080c, 0x4c17, 0x701f, 0x37ae, 0x0005, 0xa864, 0x2008,
+	0x9084, 0x00ff, 0x9096, 0x0011, 0x0168, 0x9096, 0x0019, 0x0150,
+	0x9096, 0x0015, 0x0138, 0x9096, 0x0048, 0x0120, 0x9096, 0x0029,
+	0x1904, 0x36ba, 0x810f, 0x918c, 0x00ff, 0x0904, 0x36ba, 0x7112,
+	0x7010, 0x8001, 0x0560, 0x7012, 0x080c, 0x4bce, 0x1120, 0x2009,
+	0x0002, 0x0804, 0x36ba, 0x2009, 0x0020, 0x7068, 0x2040, 0xa28c,
+	0xa390, 0xa494, 0xa598, 0x9290, 0x0040, 0x9399, 0x0000, 0x94a1,
+	0x0000, 0x95a9, 0x0000, 0xa85c, 0x9080, 0x0019, 0xaf60, 0x080c,
+	0x4c17, 0x701f, 0x37ec, 0x0005, 0xa864, 0x9084, 0x00ff, 0x9096,
+	0x0002, 0x0120, 0x9096, 0x000a, 0x1904, 0x36ba, 0x0888, 0x7014,
+	0x2048, 0xa868, 0xc0fd, 0xa86a, 0xa864, 0x9084, 0x00ff, 0x9096,
+	0x0029, 0x1160, 0xc2fd, 0xaa7a, 0x080c, 0x62eb, 0x0150, 0x0126,
+	0x2091, 0x8000, 0xa87a, 0xa982, 0x012e, 0x0050, 0x080c, 0x661b,
+	0x1128, 0x7007, 0x0003, 0x701f, 0x3818, 0x0005, 0x080c, 0x7165,
+	0x0126, 0x2091, 0x8000, 0x20a9, 0x0005, 0x20e1, 0x0001, 0x2099,
+	0x18a6, 0x400a, 0x2100, 0x9210, 0x9399, 0x0000, 0x94a1, 0x0000,
+	0x95a9, 0x0000, 0xa85c, 0x9080, 0x0019, 0x2009, 0x0020, 0x012e,
+	0xaf60, 0x0804, 0x4c1a, 0x2091, 0x8000, 0x7837, 0x4000, 0x7833,
+	0x0010, 0x7883, 0x4000, 0x7887, 0x4953, 0x788b, 0x5020, 0x788f,
+	0x2020, 0x2009, 0x017f, 0x2104, 0x7892, 0x3f00, 0x7896, 0x2061,
+	0x0100, 0x6200, 0x2061, 0x0200, 0x603c, 0x8007, 0x9205, 0x789a,
+	0x2009, 0x04fd, 0x2104, 0x789e, 0x2091, 0x5000, 0x2091, 0x4080,
+	0x2001, 0x0089, 0x2004, 0xd084, 0x0180, 0x2001, 0x1a26, 0x2004,
+	0x9005, 0x0128, 0x2001, 0x008b, 0x2004, 0xd0fc, 0x0dd8, 0x2001,
+	0x008a, 0x2003, 0x0002, 0x2003, 0x1001, 0x2071, 0x0080, 0x0804,
+	0x0427, 0x81ff, 0x1904, 0x36ba, 0x7984, 0x080c, 0x6789, 0x1904,
+	0x36bd, 0x7e98, 0x9684, 0x3fff, 0x9082, 0x4000, 0x1a04, 0x36bd,
+	0x7c88, 0x7d8c, 0x080c, 0x69bf, 0x080c, 0x694c, 0x1518, 0x2061,
+	0x1ddc, 0x0126, 0x2091, 0x8000, 0x6000, 0x9086, 0x0000, 0x0148,
+	0x6014, 0x904d, 0x0130, 0xa86c, 0x9406, 0x1118, 0xa870, 0x9506,
+	0x0150, 0x012e, 0x9ce0, 0x001c, 0x2001, 0x181a, 0x2004, 0x9c02,
+	0x1a04, 0x36ba, 0x0c30, 0x080c, 0xc802, 0x012e, 0x0904, 0x36ba,
+	0x0804, 0x3688, 0x900e, 0x2001, 0x0005, 0x080c, 0x7165, 0x0126,
+	0x2091, 0x8000, 0x080c, 0xcf21, 0x080c, 0x6f19, 0x012e, 0x0804,
+	0x3688, 0x00a6, 0x2950, 0xb198, 0x080c, 0x6789, 0x1904, 0x3903,
+	0xb6a4, 0x9684, 0x3fff, 0x9082, 0x4000, 0x16e8, 0xb49c, 0xb5a0,
+	0x080c, 0x69bf, 0x080c, 0x694c, 0x1520, 0x2061, 0x1ddc, 0x0126,
 	0x2091, 0x8000, 0x6000, 0x9086, 0x0000, 0x0148, 0x6014, 0x904d,
-	0x0130, 0xa86c, 0x9406, 0x1118, 0xa870, 0x9506, 0x0150, 0x012e,
-	0x9ce0, 0x001c, 0x2001, 0x181a, 0x2004, 0x9c02, 0x1a04, 0x35ea,
-	0x0c30, 0x080c, 0xc566, 0x012e, 0x0904, 0x35ea, 0x0804, 0x35b8,
-	0x900e, 0x2001, 0x0005, 0x080c, 0x7022, 0x0126, 0x2091, 0x8000,
-	0x080c, 0xcc85, 0x080c, 0x6dee, 0x012e, 0x0804, 0x35b8, 0x00a6,
-	0x2950, 0xb198, 0x080c, 0x6693, 0x1904, 0x3831, 0xb6a4, 0x9684,
-	0x3fff, 0x9082, 0x4000, 0x16e8, 0xb49c, 0xb5a0, 0x080c, 0x68c9,
-	0x080c, 0x6873, 0x1520, 0x2061, 0x1ddc, 0x0126, 0x2091, 0x8000,
-	0x6000, 0x9086, 0x0000, 0x0148, 0x6014, 0x904d, 0x0130, 0xa86c,
-	0x9406, 0x1118, 0xa870, 0x9506, 0x0158, 0x012e, 0x9ce0, 0x001c,
-	0x2001, 0x181a, 0x2004, 0x9c02, 0x2009, 0x000d, 0x12b0, 0x0c28,
-	0x080c, 0xc566, 0x012e, 0x2009, 0x0003, 0x0178, 0x00e0, 0x900e,
-	0x2001, 0x0005, 0x080c, 0x7022, 0x0126, 0x2091, 0x8000, 0x080c,
-	0xcc85, 0x080c, 0x6de2, 0x012e, 0x0070, 0xb097, 0x4005, 0xb19a,
-	0x0010, 0xb097, 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030,
-	0x2a48, 0x00ae, 0x0005, 0xb097, 0x4000, 0x9006, 0x918d, 0x0001,
-	0x2008, 0x2a48, 0x00ae, 0x0005, 0x81ff, 0x1904, 0x35ea, 0x080c,
-	0x4b09, 0x0904, 0x35ed, 0x080c, 0x675a, 0x0904, 0x35ea, 0x080c,
-	0x68cf, 0x0904, 0x35ea, 0x0804, 0x458e, 0x81ff, 0x1904, 0x35ea,
-	0x080c, 0x4b25, 0x0904, 0x35ed, 0x080c, 0x695d, 0x0904, 0x35ea,
-	0x2019, 0x0005, 0x79a8, 0x080c, 0x68ea, 0x0904, 0x35ea, 0x7888,
-	0x908a, 0x1000, 0x1a04, 0x35ed, 0x8003, 0x800b, 0x810b, 0x9108,
-	0x080c, 0x86d6, 0x7984, 0xd184, 0x1904, 0x35b8, 0x0804, 0x458e,
-	0x0126, 0x2091, 0x8000, 0x81ff, 0x0118, 0x2009, 0x0001, 0x0450,
-	0x2029, 0x07ff, 0x645c, 0x2400, 0x9506, 0x01f8, 0x2508, 0x080c,
-	0x6693, 0x11d8, 0x080c, 0x695d, 0x1128, 0x2009, 0x0002, 0x62c0,
-	0x2518, 0x00c0, 0x2019, 0x0004, 0x900e, 0x080c, 0x68ea, 0x1118,
-	0x2009, 0x0006, 0x0078, 0x7884, 0x908a, 0x1000, 0x1270, 0x8003,
-	0x800b, 0x810b, 0x9108, 0x080c, 0x86d6, 0x8529, 0x1ae0, 0x012e,
-	0x0804, 0x35b8, 0x012e, 0x0804, 0x35ea, 0x012e, 0x0804, 0x35ed,
-	0x080c, 0x4b09, 0x0904, 0x35ed, 0x080c, 0x675a, 0x0904, 0x35ea,
-	0x080c, 0xa91e, 0xbaa0, 0x2019, 0x0005, 0x00c6, 0x9066, 0x080c,
-	0x943d, 0x0076, 0x903e, 0x080c, 0x9306, 0x900e, 0x080c, 0xe167,
-	0x007e, 0x00ce, 0x080c, 0xa93a, 0x080c, 0x68c9, 0x0804, 0x35b8,
-	0x080c, 0x4b09, 0x0904, 0x35ed, 0x080c, 0x68c9, 0x2208, 0x0804,
-	0x35b8, 0x0156, 0x00d6, 0x00e6, 0x00c6, 0x2069, 0x1910, 0x6810,
-	0x6914, 0x910a, 0x1208, 0x900e, 0x6816, 0x9016, 0x901e, 0x2071,
-	0x19e6, 0x7028, 0x9065, 0x0118, 0x8210, 0x600c, 0x0cd8, 0x2300,
-	0x9218, 0x00ce, 0x00ee, 0x00de, 0x015e, 0x0804, 0x35b8, 0x00f6,
-	0x0016, 0x907d, 0x0138, 0x9006, 0x8000, 0x2f0c, 0x81ff, 0x0110,
-	0x2178, 0x0cd0, 0x001e, 0x00fe, 0x0005, 0x2069, 0x1910, 0x6910,
-	0x62bc, 0x0804, 0x35b8, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804,
-	0x35ea, 0x0126, 0x2091, 0x8000, 0x080c, 0x5752, 0x0128, 0x2009,
-	0x0007, 0x012e, 0x0804, 0x35ea, 0x012e, 0x615c, 0x9190, 0x33b9,
-	0x2215, 0x9294, 0x00ff, 0x637c, 0x83ff, 0x0108, 0x6280, 0x67dc,
-	0x97c4, 0x000a, 0x98c6, 0x000a, 0x1118, 0x2031, 0x0001, 0x00e8,
-	0x97c4, 0x0022, 0x98c6, 0x0022, 0x1118, 0x2031, 0x0003, 0x00a8,
-	0x97c4, 0x0012, 0x98c6, 0x0012, 0x1118, 0x2031, 0x0002, 0x0068,
-	0x080c, 0x753d, 0x1118, 0x2031, 0x0004, 0x0038, 0xd79c, 0x0120,
-	0x2009, 0x0005, 0x0804, 0x35ea, 0x9036, 0x7e9a, 0x7f9e, 0x0804,
-	0x35b8, 0x614c, 0x6250, 0x2019, 0x1985, 0x231c, 0x2001, 0x1986,
-	0x2004, 0x789a, 0x0804, 0x35b8, 0x0126, 0x2091, 0x8000, 0x6138,
-	0x623c, 0x6340, 0x012e, 0x0804, 0x35b8, 0x080c, 0x4b25, 0x0904,
-	0x35ed, 0xba44, 0xbb38, 0x0804, 0x35b8, 0x080c, 0x0d7d, 0x080c,
-	0x4b25, 0x2110, 0x0904, 0x35ed, 0xb804, 0x908c, 0x00ff, 0x918e,
-	0x0006, 0x0140, 0x9084, 0xff00, 0x9086, 0x0600, 0x2009, 0x0009,
-	0x1904, 0x35ea, 0x0126, 0x2091, 0x8000, 0x2019, 0x0005, 0x00c6,
-	0x9066, 0x080c, 0xa91e, 0x080c, 0xa404, 0x080c, 0x943d, 0x0076,
-	0x903e, 0x080c, 0x9306, 0x900e, 0x080c, 0xe167, 0x007e, 0x00ce,
-	0x080c, 0xa93a, 0xb807, 0x0407, 0x012e, 0x0804, 0x35b8, 0x614c,
-	0x6250, 0x7884, 0x604e, 0x7b88, 0x6352, 0x2069, 0x1847, 0x831f,
-	0x9305, 0x6816, 0x788c, 0x2069, 0x1985, 0x2d1c, 0x206a, 0x7e98,
-	0x9682, 0x0014, 0x1210, 0x2031, 0x07d0, 0x2069, 0x1986, 0x2d04,
-	0x266a, 0x789a, 0x0804, 0x35b8, 0x0126, 0x2091, 0x8000, 0x6138,
-	0x7884, 0x603a, 0x910e, 0xd1b4, 0x190c, 0x0ed9, 0xd0c4, 0x01a8,
-	0x00d6, 0x78a8, 0x2009, 0x199c, 0x200a, 0x78ac, 0x2011, 0x199d,
-	0x2012, 0x2069, 0x0100, 0x6838, 0x9086, 0x0007, 0x1118, 0x2214,
-	0x6a5a, 0x0010, 0x210c, 0x695a, 0x00de, 0x2011, 0x0116, 0x220c,
-	0x7888, 0xd08c, 0x0118, 0x918d, 0x0040, 0x0010, 0x918c, 0xff7f,
-	0x2112, 0x603c, 0x7988, 0x613e, 0x6140, 0x910d, 0x788c, 0x6042,
-	0x7a88, 0x9294, 0x1000, 0x9205, 0x910e, 0xd1e4, 0x190c, 0x0ef4,
-	0x9084, 0x0020, 0x0130, 0x78b4, 0x6046, 0x9084, 0x0001, 0x090c,
-	0x428c, 0x6040, 0xd0cc, 0x0120, 0x78b0, 0x2011, 0x0114, 0x2012,
-	0x012e, 0x0804, 0x35b8, 0x00f6, 0x2079, 0x1800, 0x7a38, 0xa898,
-	0x9084, 0xfebf, 0x9215, 0xa89c, 0x9084, 0xfebf, 0x8002, 0x9214,
-	0x7838, 0x9084, 0x0140, 0x9215, 0x7a3a, 0xa897, 0x4000, 0x900e,
-	0x9085, 0x0001, 0x2001, 0x0000, 0x00fe, 0x0005, 0x7898, 0x9005,
-	0x01a8, 0x7888, 0x9025, 0x0904, 0x35ed, 0x788c, 0x902d, 0x0904,
-	0x35ed, 0x900e, 0x080c, 0x6693, 0x1120, 0xba44, 0xbb38, 0xbc46,
-	0xbd3a, 0x9186, 0x07ff, 0x0190, 0x8108, 0x0ca0, 0x080c, 0x4b25,
-	0x0904, 0x35ed, 0x7888, 0x900d, 0x0904, 0x35ed, 0x788c, 0x9005,
-	0x0904, 0x35ed, 0xba44, 0xb946, 0xbb38, 0xb83a, 0x0804, 0x35b8,
-	0x2011, 0xbc09, 0x0010, 0x2011, 0xbc05, 0x080c, 0x5752, 0x1904,
-	0x35ea, 0x00c6, 0x2061, 0x0100, 0x7984, 0x9186, 0x00ff, 0x1130,
-	0x2001, 0x1818, 0x2004, 0x9085, 0xff00, 0x0088, 0x9182, 0x007f,
-	0x16e0, 0x9188, 0x33b9, 0x210d, 0x918c, 0x00ff, 0x2001, 0x1818,
-	0x2004, 0x0026, 0x9116, 0x002e, 0x0580, 0x810f, 0x9105, 0x0126,
-	0x2091, 0x8000, 0x0006, 0x080c, 0xac5a, 0x000e, 0x0510, 0x602e,
-	0x620a, 0x7984, 0x00b6, 0x080c, 0x6638, 0x2b08, 0x00be, 0x1500,
-	0x6112, 0x6023, 0x0001, 0x080c, 0x4af2, 0x01d0, 0x9006, 0xa866,
-	0x7007, 0x0003, 0xa832, 0xa868, 0xc0fd, 0xa86a, 0x701f, 0x3aab,
-	0x2900, 0x6016, 0x2009, 0x0032, 0x080c, 0xad4d, 0x012e, 0x00ce,
-	0x0005, 0x012e, 0x00ce, 0x0804, 0x35ea, 0x00ce, 0x0804, 0x35ed,
-	0x080c, 0xacb0, 0x0cb0, 0xa830, 0x9086, 0x0100, 0x0904, 0x35ea,
-	0x0804, 0x35b8, 0x2061, 0x1a6e, 0x0126, 0x2091, 0x8000, 0x6000,
-	0xd084, 0x0170, 0x6104, 0x6208, 0x2061, 0x1800, 0x6354, 0x6074,
-	0x789a, 0x60c0, 0x789e, 0x60bc, 0x78aa, 0x012e, 0x0804, 0x35b8,
-	0x900e, 0x2110, 0x0c88, 0x81ff, 0x1904, 0x35ea, 0x080c, 0x753d,
-	0x0904, 0x35ea, 0x0126, 0x2091, 0x8000, 0x6254, 0x6074, 0x9202,
-	0x0248, 0x9085, 0x0001, 0x080c, 0x26ca, 0x080c, 0x5971, 0x012e,
-	0x0804, 0x35b8, 0x012e, 0x0804, 0x35ed, 0x0006, 0x0016, 0x00c6,
-	0x00e6, 0x2001, 0x19a8, 0x2070, 0x2061, 0x1847, 0x6008, 0x2072,
-	0x900e, 0x2011, 0x1400, 0x080c, 0x91f8, 0x7206, 0x00ee, 0x00ce,
-	0x001e, 0x000e, 0x0005, 0x0126, 0x2091, 0x8000, 0x81ff, 0x0128,
-	0x012e, 0x2021, 0x400b, 0x0804, 0x35ba, 0x7884, 0xd0fc, 0x0148,
-	0x2001, 0x002a, 0x2004, 0x9082, 0x00e1, 0x0288, 0x012e, 0x0804,
-	0x35ed, 0x2001, 0x002a, 0x2004, 0x2069, 0x1847, 0x6908, 0x9102,
-	0x1230, 0x012e, 0x0804, 0x35ed, 0x012e, 0x0804, 0x35ea, 0x080c,
-	0xabe2, 0x0dd0, 0x7884, 0xd0fc, 0x0904, 0x3b76, 0x00c6, 0x080c,
-	0x4af2, 0x00ce, 0x0d88, 0xa867, 0x0000, 0x7884, 0xa80a, 0x7898,
+	0x0130, 0xa86c, 0x9406, 0x1118, 0xa870, 0x9506, 0x0158, 0x012e,
+	0x9ce0, 0x001c, 0x2001, 0x181a, 0x2004, 0x9c02, 0x2009, 0x000d,
+	0x12b0, 0x0c28, 0x080c, 0xc802, 0x012e, 0x2009, 0x0003, 0x0178,
+	0x00e0, 0x900e, 0x2001, 0x0005, 0x080c, 0x7165, 0x0126, 0x2091,
+	0x8000, 0x080c, 0xcf21, 0x080c, 0x6f0d, 0x012e, 0x0070, 0xb097,
+	0x4005, 0xb19a, 0x0010, 0xb097, 0x4006, 0x900e, 0x9085, 0x0001,
+	0x2001, 0x0030, 0x2a48, 0x00ae, 0x0005, 0xb097, 0x4000, 0x9006,
+	0x918d, 0x0001, 0x2008, 0x2a48, 0x00ae, 0x0005, 0x81ff, 0x1904,
+	0x36ba, 0x080c, 0x4be5, 0x0904, 0x36bd, 0x080c, 0x6850, 0x0904,
+	0x36ba, 0x080c, 0x69c5, 0x0904, 0x36ba, 0x0804, 0x4667, 0x81ff,
+	0x1904, 0x36ba, 0x080c, 0x4c01, 0x0904, 0x36bd, 0x080c, 0x6a53,
+	0x0904, 0x36ba, 0x2019, 0x0005, 0x79a8, 0x080c, 0x69e0, 0x0904,
+	0x36ba, 0x7888, 0x908a, 0x1000, 0x1a04, 0x36bd, 0x8003, 0x800b,
+	0x810b, 0x9108, 0x080c, 0x8842, 0x79a8, 0xd184, 0x1904, 0x3688,
+	0x0804, 0x4667, 0x0126, 0x2091, 0x8000, 0x81ff, 0x0118, 0x2009,
+	0x0001, 0x0450, 0x2029, 0x07ff, 0x645c, 0x2400, 0x9506, 0x01f8,
+	0x2508, 0x080c, 0x6789, 0x11d8, 0x080c, 0x6a53, 0x1128, 0x2009,
+	0x0002, 0x62c0, 0x2518, 0x00c0, 0x2019, 0x0004, 0x900e, 0x080c,
+	0x69e0, 0x1118, 0x2009, 0x0006, 0x0078, 0x7884, 0x908a, 0x1000,
+	0x1270, 0x8003, 0x800b, 0x810b, 0x9108, 0x080c, 0x8842, 0x8529,
+	0x1ae0, 0x012e, 0x0804, 0x3688, 0x012e, 0x0804, 0x36ba, 0x012e,
+	0x0804, 0x36bd, 0x080c, 0x4be5, 0x0904, 0x36bd, 0x080c, 0x6850,
+	0x0904, 0x36ba, 0x080c, 0xaae0, 0xbaa0, 0x2019, 0x0005, 0x00c6,
+	0x9066, 0x080c, 0x95c1, 0x0076, 0x903e, 0x080c, 0x947e, 0x900e,
+	0x080c, 0xe440, 0x007e, 0x00ce, 0x080c, 0xaafc, 0x080c, 0x69bf,
+	0x0804, 0x3688, 0x080c, 0x4be5, 0x0904, 0x36bd, 0x080c, 0x69bf,
+	0x2208, 0x0804, 0x3688, 0x0156, 0x00d6, 0x00e6, 0x00c6, 0x2069,
+	0x1910, 0x6810, 0x6914, 0x910a, 0x1208, 0x900e, 0x6816, 0x9016,
+	0x901e, 0x2071, 0x19e9, 0x7028, 0x9065, 0x0118, 0x8210, 0x600c,
+	0x0cd8, 0x2300, 0x9218, 0x00ce, 0x00ee, 0x00de, 0x015e, 0x0804,
+	0x3688, 0x00f6, 0x0016, 0x907d, 0x0138, 0x9006, 0x8000, 0x2f0c,
+	0x81ff, 0x0110, 0x2178, 0x0cd0, 0x001e, 0x00fe, 0x0005, 0x2069,
+	0x1910, 0x6910, 0x62bc, 0x0804, 0x3688, 0x81ff, 0x0120, 0x2009,
+	0x0001, 0x0804, 0x36ba, 0x0126, 0x2091, 0x8000, 0x080c, 0x583a,
+	0x0128, 0x2009, 0x0007, 0x012e, 0x0804, 0x36ba, 0x012e, 0x615c,
+	0x9190, 0x3489, 0x2215, 0x9294, 0x00ff, 0x637c, 0x83ff, 0x0108,
+	0x6280, 0x67dc, 0x97c4, 0x000a, 0x98c6, 0x000a, 0x1118, 0x2031,
+	0x0001, 0x00e8, 0x97c4, 0x0022, 0x98c6, 0x0022, 0x1118, 0x2031,
+	0x0003, 0x00a8, 0x97c4, 0x0012, 0x98c6, 0x0012, 0x1118, 0x2031,
+	0x0002, 0x0068, 0x080c, 0x76a5, 0x1118, 0x2031, 0x0004, 0x0038,
+	0xd79c, 0x0120, 0x2009, 0x0005, 0x0804, 0x36ba, 0x9036, 0x7e9a,
+	0x7f9e, 0x0804, 0x3688, 0x614c, 0x6250, 0x2019, 0x1987, 0x231c,
+	0x2001, 0x1988, 0x2004, 0x789a, 0x0804, 0x3688, 0x0126, 0x2091,
+	0x8000, 0x6138, 0x623c, 0x6340, 0x012e, 0x0804, 0x3688, 0x080c,
+	0x4c01, 0x0904, 0x36bd, 0xba44, 0xbb38, 0x0804, 0x3688, 0x080c,
+	0x0d85, 0x080c, 0x4c01, 0x2110, 0x0904, 0x36bd, 0xb804, 0x908c,
+	0x00ff, 0x918e, 0x0006, 0x0140, 0x9084, 0xff00, 0x9086, 0x0600,
+	0x2009, 0x0009, 0x1904, 0x36ba, 0x0126, 0x2091, 0x8000, 0x2019,
+	0x0005, 0x00c6, 0x9066, 0x080c, 0xaae0, 0x080c, 0xa5c6, 0x080c,
+	0x95c1, 0x0076, 0x903e, 0x080c, 0x947e, 0x900e, 0x080c, 0xe440,
+	0x007e, 0x00ce, 0x080c, 0xaafc, 0xb807, 0x0407, 0x012e, 0x0804,
+	0x3688, 0x614c, 0x6250, 0x7884, 0x604e, 0x7b88, 0x6352, 0x2069,
+	0x1847, 0x831f, 0x9305, 0x6816, 0x788c, 0x2069, 0x1987, 0x2d1c,
+	0x206a, 0x7e98, 0x9682, 0x0014, 0x1210, 0x2031, 0x07d0, 0x2069,
+	0x1988, 0x2d04, 0x266a, 0x789a, 0x0804, 0x3688, 0x0126, 0x2091,
+	0x8000, 0x6138, 0x7884, 0x603a, 0x910e, 0xd1b4, 0x190c, 0x0eeb,
+	0xd0c4, 0x01a8, 0x00d6, 0x78a8, 0x2009, 0x199e, 0x200a, 0x78ac,
+	0x2011, 0x199f, 0x2012, 0x2069, 0x0100, 0x6838, 0x9086, 0x0007,
+	0x1118, 0x2214, 0x6a5a, 0x0010, 0x210c, 0x695a, 0x00de, 0x2011,
+	0x0116, 0x220c, 0x7888, 0xd08c, 0x0118, 0x918d, 0x0040, 0x0010,
+	0x918c, 0xff7f, 0x2112, 0x7988, 0x613e, 0x6140, 0x788c, 0x6042,
+	0x910e, 0xd1e4, 0x190c, 0x0f06, 0x9084, 0x0020, 0x0130, 0x78b4,
+	0x6046, 0x9084, 0x0001, 0x090c, 0x4365, 0x6040, 0xd0cc, 0x0120,
+	0x78b0, 0x2011, 0x0114, 0x2012, 0x012e, 0x0804, 0x3688, 0x00f6,
+	0x2079, 0x1800, 0x7a38, 0xa898, 0x9084, 0xfebf, 0x9215, 0xa89c,
+	0x9084, 0xfebf, 0x8002, 0x9214, 0x7838, 0x9084, 0x0140, 0x9215,
+	0x7a3a, 0xa897, 0x4000, 0x900e, 0x9085, 0x0001, 0x2001, 0x0000,
+	0x00fe, 0x0005, 0x7898, 0x9005, 0x01a8, 0x7888, 0x9025, 0x0904,
+	0x36bd, 0x788c, 0x902d, 0x0904, 0x36bd, 0x900e, 0x080c, 0x6789,
+	0x1120, 0xba44, 0xbb38, 0xbc46, 0xbd3a, 0x9186, 0x07ff, 0x0190,
+	0x8108, 0x0ca0, 0x080c, 0x4c01, 0x0904, 0x36bd, 0x7888, 0x900d,
+	0x0904, 0x36bd, 0x788c, 0x9005, 0x0904, 0x36bd, 0xba44, 0xb946,
+	0xbb38, 0xb83a, 0x0804, 0x3688, 0x2011, 0xbc09, 0x0010, 0x2011,
+	0xbc05, 0x080c, 0x583a, 0x1904, 0x36ba, 0x00c6, 0x2061, 0x0100,
+	0x7984, 0x9186, 0x00ff, 0x1130, 0x2001, 0x1818, 0x2004, 0x9085,
+	0xff00, 0x0088, 0x9182, 0x007f, 0x16e0, 0x9188, 0x3489, 0x210d,
+	0x918c, 0x00ff, 0x2001, 0x1818, 0x2004, 0x0026, 0x9116, 0x002e,
+	0x0580, 0x810f, 0x9105, 0x0126, 0x2091, 0x8000, 0x0006, 0x080c,
+	0xaed8, 0x000e, 0x0510, 0x602e, 0x620a, 0x7984, 0x00b6, 0x080c,
+	0x6724, 0x2b08, 0x00be, 0x1500, 0x6112, 0x6023, 0x0001, 0x080c,
+	0x4bce, 0x01d0, 0x9006, 0xa866, 0x7007, 0x0003, 0xa832, 0xa868,
+	0xc0fd, 0xa86a, 0x701f, 0x3b77, 0x2900, 0x6016, 0x2009, 0x0032,
+	0x080c, 0xafcc, 0x012e, 0x00ce, 0x0005, 0x012e, 0x00ce, 0x0804,
+	0x36ba, 0x00ce, 0x0804, 0x36bd, 0x080c, 0xaf2e, 0x0cb0, 0xa830,
+	0x9086, 0x0100, 0x0904, 0x36ba, 0x0804, 0x3688, 0x2061, 0x1a74,
+	0x0126, 0x2091, 0x8000, 0x6000, 0xd084, 0x0170, 0x6104, 0x6208,
+	0x2061, 0x1800, 0x6354, 0x6074, 0x789a, 0x60c0, 0x789e, 0x60bc,
+	0x78aa, 0x012e, 0x0804, 0x3688, 0x900e, 0x2110, 0x0c88, 0x81ff,
+	0x1904, 0x36ba, 0x080c, 0x76a5, 0x0904, 0x36ba, 0x0126, 0x2091,
+	0x8000, 0x6254, 0x6074, 0x9202, 0x0248, 0x9085, 0x0001, 0x080c,
+	0x270b, 0x080c, 0x5a5d, 0x012e, 0x0804, 0x3688, 0x012e, 0x0804,
+	0x36bd, 0x0006, 0x0016, 0x00c6, 0x00e6, 0x2001, 0x19aa, 0x2070,
+	0x2061, 0x1847, 0x6008, 0x2072, 0x900e, 0x2011, 0x1400, 0x080c,
+	0x936c, 0x7206, 0x00ee, 0x00ce, 0x001e, 0x000e, 0x0005, 0x0126,
+	0x2091, 0x8000, 0x81ff, 0x0128, 0x012e, 0x2021, 0x400b, 0x0804,
+	0x368a, 0x7884, 0xd0fc, 0x0158, 0x2001, 0x002a, 0x2004, 0x9005,
+	0x0180, 0x9082, 0x00e1, 0x0298, 0x012e, 0x0804, 0x36bd, 0x2001,
+	0x002a, 0x2004, 0x9005, 0x0128, 0x2069, 0x1847, 0x6908, 0x9102,
+	0x1230, 0x012e, 0x0804, 0x36bd, 0x012e, 0x0804, 0x36ba, 0x080c,
+	0xae60, 0x0dd0, 0x7884, 0xd0fc, 0x0904, 0x3c46, 0x00c6, 0x080c,
+	0x4bce, 0x00ce, 0x0d88, 0xa867, 0x0000, 0x7884, 0xa80a, 0x7898,
 	0xa80e, 0x789c, 0xa812, 0x2001, 0x002e, 0x2004, 0xa81a, 0x2001,
 	0x002f, 0x2004, 0xa81e, 0x2001, 0x0030, 0x2004, 0xa822, 0x2001,
 	0x0031, 0x2004, 0xa826, 0x2001, 0x0034, 0x2004, 0xa82a, 0x2001,
 	0x0035, 0x2004, 0xa82e, 0x2001, 0x002a, 0x2004, 0x9080, 0x0003,
-	0x9084, 0x00fc, 0x8004, 0xa816, 0x080c, 0x3d00, 0x0928, 0x7014,
+	0x9084, 0x00fc, 0x8004, 0xa816, 0x080c, 0x3dd0, 0x0928, 0x7014,
 	0x2048, 0xad2c, 0xac28, 0xab1c, 0xaa18, 0xa930, 0xa808, 0xd0b4,
 	0x1120, 0x2029, 0x0000, 0x2021, 0x0000, 0x8906, 0x8006, 0x8007,
-	0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x001b, 0x080c, 0x4b3b,
-	0x701f, 0x3c3d, 0x7023, 0x0001, 0x012e, 0x0005, 0x080c, 0xa91e,
+	0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x001b, 0x080c, 0x4c17,
+	0x701f, 0x3d0d, 0x7023, 0x0001, 0x012e, 0x0005, 0x080c, 0xaae0,
 	0x0046, 0x0086, 0x0096, 0x00a6, 0x00b6, 0x00c6, 0x00d6, 0x00e6,
-	0x00f6, 0x080c, 0x3ae5, 0x2001, 0x199e, 0x2003, 0x0000, 0x2021,
+	0x00f6, 0x080c, 0x3bb1, 0x2001, 0x19a0, 0x2003, 0x0000, 0x2021,
 	0x000a, 0x2061, 0x0100, 0x6104, 0x0016, 0x60bb, 0x0000, 0x60bf,
-	0x32e1, 0x60bf, 0x0012, 0x080c, 0x3d6f, 0x080c, 0x3d2e, 0x00f6,
-	0x00e6, 0x0086, 0x2940, 0x2071, 0x19e6, 0x2079, 0x0090, 0x00d6,
+	0x32e1, 0x60bf, 0x0012, 0x080c, 0x3e3f, 0x080c, 0x3dfe, 0x00f6,
+	0x00e6, 0x0086, 0x2940, 0x2071, 0x19e9, 0x2079, 0x0090, 0x00d6,
 	0x2069, 0x0000, 0x6884, 0xd0b4, 0x0140, 0x2001, 0x0035, 0x2004,
 	0x780e, 0x2001, 0x0034, 0x2004, 0x780a, 0x00de, 0x2011, 0x0001,
-	0x080c, 0x40d0, 0x008e, 0x00ee, 0x00fe, 0x080c, 0x3ffd, 0x080c,
-	0x3f2a, 0x05b8, 0x2001, 0x020b, 0x2004, 0x9084, 0x0140, 0x1db8,
-	0x080c, 0x4144, 0x00f6, 0x2079, 0x0300, 0x78bc, 0x00fe, 0x908c,
+	0x080c, 0x41a9, 0x008e, 0x00ee, 0x00fe, 0x080c, 0x40d6, 0x080c,
+	0x4003, 0x05b8, 0x2001, 0x020b, 0x2004, 0x9084, 0x0140, 0x1db8,
+	0x080c, 0x421d, 0x00f6, 0x2079, 0x0300, 0x78bc, 0x00fe, 0x908c,
 	0x0070, 0x1560, 0x2071, 0x0200, 0x7037, 0x0000, 0x7050, 0x9084,
 	0xff00, 0x9086, 0x3200, 0x1510, 0x7037, 0x0001, 0x7050, 0x9084,
 	0xff00, 0x9086, 0xe100, 0x11d0, 0x7037, 0x0000, 0x7054, 0x7037,
 	0x0000, 0x715c, 0x9106, 0x1190, 0x2001, 0x1820, 0x2004, 0x9106,
 	0x1168, 0x00c6, 0x2061, 0x0100, 0x6024, 0x9084, 0x1e00, 0x00ce,
-	0x0138, 0x080c, 0x3f34, 0x080c, 0x3d29, 0x0058, 0x080c, 0x3d29,
-	0x080c, 0x4068, 0x080c, 0x3ff3, 0x2001, 0x020b, 0x2004, 0xd0e4,
+	0x0138, 0x080c, 0x400d, 0x080c, 0x3df9, 0x0058, 0x080c, 0x3df9,
+	0x080c, 0x4141, 0x080c, 0x40cc, 0x2001, 0x020b, 0x2004, 0xd0e4,
 	0x0dd8, 0x2001, 0x032a, 0x2003, 0x0004, 0x2061, 0x0100, 0x6027,
 	0x0002, 0x001e, 0x6106, 0x2011, 0x020d, 0x2013, 0x0020, 0x60bb,
 	0x0000, 0x60bf, 0x0108, 0x60bf, 0x0012, 0x2001, 0x0004, 0x200c,
-	0x918c, 0xfffd, 0x2102, 0x080c, 0x1340, 0x2009, 0x0028, 0x080c,
-	0x220a, 0x2001, 0x0227, 0x200c, 0x2102, 0x080c, 0xa93a, 0x00fe,
+	0x918c, 0xfffd, 0x2102, 0x080c, 0x1352, 0x2009, 0x0028, 0x080c,
+	0x2241, 0x2001, 0x0227, 0x200c, 0x2102, 0x080c, 0xaafc, 0x00fe,
 	0x00ee, 0x00de, 0x00ce, 0x00be, 0x00ae, 0x009e, 0x008e, 0x004e,
-	0x2001, 0x199e, 0x2004, 0x9005, 0x1118, 0x012e, 0x0804, 0x35b8,
-	0x012e, 0x2021, 0x400c, 0x0804, 0x35ba, 0x0016, 0x0026, 0x0036,
+	0x2001, 0x19a0, 0x2004, 0x9005, 0x1118, 0x012e, 0x0804, 0x3688,
+	0x012e, 0x2021, 0x400c, 0x0804, 0x368a, 0x0016, 0x0026, 0x0036,
 	0x0046, 0x0056, 0x0076, 0x0086, 0x0096, 0x00d6, 0x0156, 0x7014,
 	0x2048, 0x7020, 0x20a8, 0x8000, 0x7022, 0xa804, 0x9005, 0x0904,
-	0x3c99, 0x2048, 0x1f04, 0x3c4d, 0x7068, 0x2040, 0xa28c, 0xa390,
+	0x3d69, 0x2048, 0x1f04, 0x3d1d, 0x7068, 0x2040, 0xa28c, 0xa390,
 	0xa494, 0xa598, 0xa930, 0xa808, 0xd0b4, 0x1120, 0x2029, 0x0000,
 	0x2021, 0x0000, 0x0096, 0x7014, 0x2048, 0xa864, 0x009e, 0x9086,
 	0x0103, 0x0170, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084,
-	0xffc0, 0x9080, 0x001b, 0x080c, 0x4b3b, 0x701f, 0x3c3d, 0x00b0,
+	0xffc0, 0x9080, 0x001b, 0x080c, 0x4c17, 0x701f, 0x3d0d, 0x00b0,
 	0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080,
 	0x001b, 0x21a8, 0x27e0, 0x2098, 0x27e8, 0x20a0, 0x0006, 0x080c,
-	0x0fc4, 0x000e, 0x080c, 0x4b3e, 0x701f, 0x3c3d, 0x015e, 0x00de,
+	0x0fd6, 0x000e, 0x080c, 0x4c1a, 0x701f, 0x3d0d, 0x015e, 0x00de,
 	0x009e, 0x008e, 0x007e, 0x005e, 0x004e, 0x003e, 0x002e, 0x001e,
 	0x0005, 0x7014, 0x2048, 0xa864, 0x9086, 0x0103, 0x1118, 0x701f,
-	0x3cfe, 0x0450, 0x7014, 0x2048, 0xa868, 0xc0fd, 0xa86a, 0x2009,
-	0x007f, 0x080c, 0x6632, 0x0110, 0x9006, 0x0030, 0xb813, 0x00ff,
-	0xb817, 0xfffd, 0x080c, 0xce64, 0x015e, 0x00de, 0x009e, 0x008e,
-	0x007e, 0x005e, 0x004e, 0x003e, 0x002e, 0x001e, 0x0904, 0x35ea,
+	0x3dce, 0x0450, 0x7014, 0x2048, 0xa868, 0xc0fd, 0xa86a, 0x2009,
+	0x007f, 0x080c, 0x671e, 0x0110, 0x9006, 0x0030, 0xb813, 0x00ff,
+	0xb817, 0xfffd, 0x080c, 0xd104, 0x015e, 0x00de, 0x009e, 0x008e,
+	0x007e, 0x005e, 0x004e, 0x003e, 0x002e, 0x001e, 0x0904, 0x36ba,
 	0x0016, 0x0026, 0x0036, 0x0046, 0x0056, 0x0076, 0x0086, 0x0096,
-	0x00d6, 0x0156, 0x701f, 0x3cd0, 0x7007, 0x0003, 0x0804, 0x3c8e,
-	0xa830, 0x9086, 0x0100, 0x2021, 0x400c, 0x0904, 0x35ba, 0x0076,
+	0x00d6, 0x0156, 0x701f, 0x3da0, 0x7007, 0x0003, 0x0804, 0x3d5e,
+	0xa830, 0x9086, 0x0100, 0x2021, 0x400c, 0x0904, 0x368a, 0x0076,
 	0xad10, 0xac0c, 0xab24, 0xaa20, 0xa930, 0xa808, 0xd0b4, 0x1120,
 	0x2029, 0x0000, 0x2021, 0x0000, 0x8906, 0x8006, 0x8007, 0x90bc,
 	0x003f, 0x9084, 0xffc0, 0x9080, 0x001b, 0x21a8, 0x27e0, 0x2098,
-	0x27e8, 0x20a0, 0x0006, 0x080c, 0x0fc4, 0x000e, 0x080c, 0x4b3e,
-	0x007e, 0x701f, 0x3c3d, 0x7023, 0x0001, 0x0005, 0x0804, 0x35b8,
+	0x27e8, 0x20a0, 0x0006, 0x080c, 0x0fd6, 0x000e, 0x080c, 0x4c1a,
+	0x007e, 0x701f, 0x3d0d, 0x7023, 0x0001, 0x0005, 0x0804, 0x3688,
 	0x0156, 0x00c6, 0xa814, 0x908a, 0x001e, 0x0218, 0xa833, 0x001e,
-	0x0010, 0xa832, 0x0078, 0x81ff, 0x0168, 0x0016, 0x080c, 0x4af2,
+	0x0010, 0xa832, 0x0078, 0x81ff, 0x0168, 0x0016, 0x080c, 0x4bce,
 	0x001e, 0x0130, 0xa800, 0x2040, 0xa008, 0xa80a, 0x2100, 0x0c58,
 	0x9006, 0x0010, 0x9085, 0x0001, 0x00ce, 0x015e, 0x0005, 0x0006,
 	0x00f6, 0x2079, 0x0000, 0x7880, 0x9086, 0x0044, 0x00fe, 0x000e,
-	0x0005, 0x2001, 0x199e, 0x2003, 0x0001, 0x0005, 0x00f6, 0x00e6,
-	0x00c6, 0x2061, 0x0200, 0x2001, 0x19a9, 0x2004, 0x601a, 0x2061,
-	0x0100, 0x2001, 0x19a8, 0x2004, 0x60ce, 0x6104, 0xc1ac, 0x6106,
-	0x080c, 0x4af2, 0xa813, 0x0019, 0xa817, 0x0001, 0x2900, 0xa85a,
+	0x0005, 0x2001, 0x19a0, 0x2003, 0x0001, 0x0005, 0x00f6, 0x00e6,
+	0x00c6, 0x2061, 0x0200, 0x2001, 0x19ab, 0x2004, 0x601a, 0x2061,
+	0x0100, 0x2001, 0x19aa, 0x2004, 0x60ce, 0x6104, 0xc1ac, 0x6106,
+	0x080c, 0x4bce, 0xa813, 0x0019, 0xa817, 0x0001, 0x2900, 0xa85a,
 	0x2001, 0x002e, 0x2004, 0xa866, 0x2001, 0x002f, 0x2004, 0xa86a,
-	0x2061, 0x0090, 0x2079, 0x0100, 0x2001, 0x19a8, 0x2004, 0x6036,
-	0x2009, 0x0040, 0x080c, 0x220a, 0x2001, 0x002a, 0x2004, 0x9084,
+	0x2061, 0x0090, 0x2079, 0x0100, 0x2001, 0x19aa, 0x2004, 0x6036,
+	0x2009, 0x0040, 0x080c, 0x2241, 0x2001, 0x002a, 0x2004, 0x9084,
 	0xfff8, 0xa86e, 0x601a, 0xa873, 0x0000, 0x601f, 0x0000, 0x78ca,
 	0x9006, 0x600a, 0x600e, 0x00ce, 0x00ee, 0x00fe, 0x0005, 0x00e6,
-	0x080c, 0x4af2, 0x2940, 0xa013, 0x0019, 0xa017, 0x0001, 0x2800,
+	0x080c, 0x4bce, 0x2940, 0xa013, 0x0019, 0xa017, 0x0001, 0x2800,
 	0xa05a, 0x2001, 0x0030, 0x2004, 0xa866, 0x2001, 0x0031, 0x2004,
 	0xa86a, 0x2001, 0x002a, 0x2004, 0x9084, 0xfff8, 0xa86e, 0xa873,
 	0x0000, 0x2001, 0x032a, 0x2003, 0x0004, 0x2001, 0x0300, 0x2003,
 	0x0000, 0x2001, 0x020d, 0x2003, 0x0000, 0x2001, 0x0004, 0x200c,
 	0x918d, 0x0002, 0x2102, 0x00ee, 0x0005, 0x0126, 0x2091, 0x8000,
-	0x81ff, 0x0148, 0x080c, 0x2a58, 0x1130, 0x9006, 0x080c, 0x29ab,
-	0x9006, 0x080c, 0x298e, 0x7884, 0x9084, 0x0007, 0x0002, 0x3dba,
-	0x3dbb, 0x3dbc, 0x3db7, 0x3db7, 0x3db7, 0x3db7, 0x3db7, 0x012e,
-	0x0804, 0x35ed, 0x0ce0, 0x0cd8, 0x080c, 0x753d, 0x1128, 0x012e,
-	0x2009, 0x0016, 0x0804, 0x35ea, 0x81ff, 0x0128, 0x012e, 0x2021,
-	0x400b, 0x0804, 0x35ba, 0x080c, 0xa91e, 0x0086, 0x0096, 0x00a6,
-	0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x080c, 0x3ae5, 0x2009,
-	0x0101, 0x210c, 0x0016, 0x7ec8, 0x7dcc, 0x9006, 0x2068, 0x2060,
-	0x2058, 0x080c, 0x421f, 0x080c, 0x416f, 0x903e, 0x2720, 0x00f6,
-	0x00e6, 0x0086, 0x2940, 0x2071, 0x19e6, 0x2079, 0x0090, 0x00d6,
-	0x2069, 0x0000, 0x6884, 0xd0b4, 0x0120, 0x68d4, 0x780e, 0x68d0,
-	0x780a, 0x00de, 0x2011, 0x0001, 0x080c, 0x40d0, 0x080c, 0x2a60,
-	0x080c, 0x2a60, 0x080c, 0x2a60, 0x080c, 0x2a60, 0x080c, 0x40d0,
-	0x008e, 0x00ee, 0x00fe, 0x080c, 0x3ffd, 0x2009, 0x9c40, 0x8109,
-	0x11b0, 0x080c, 0x3f34, 0x2001, 0x0004, 0x200c, 0x918c, 0xfffd,
-	0x2102, 0x001e, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x00ae,
-	0x009e, 0x008e, 0x2009, 0x0017, 0x080c, 0x35ea, 0x0cf8, 0x2001,
-	0x020b, 0x2004, 0x9084, 0x0140, 0x1d10, 0x00f6, 0x2079, 0x0000,
-	0x7884, 0x00fe, 0xd0bc, 0x0178, 0x2001, 0x0201, 0x200c, 0x81ff,
-	0x0150, 0x080c, 0x3fdb, 0x2d00, 0x9c05, 0x9b05, 0x0120, 0x080c,
-	0x3f34, 0x0804, 0x3edd, 0x080c, 0x4144, 0x080c, 0x4068, 0x080c,
-	0x3fbe, 0x080c, 0x3ff3, 0x00f6, 0x2079, 0x0100, 0x7824, 0xd0ac,
-	0x0130, 0x8b58, 0x080c, 0x3f34, 0x00fe, 0x0804, 0x3edd, 0x00fe,
-	0x080c, 0x3f2a, 0x1150, 0x8d68, 0x2001, 0x0032, 0x2602, 0x2001,
-	0x0033, 0x2502, 0x080c, 0x3f34, 0x0080, 0x87ff, 0x0138, 0x2001,
-	0x0201, 0x2004, 0x9005, 0x1908, 0x8739, 0x0038, 0x2001, 0x1a6a,
-	0x2004, 0x9086, 0x0000, 0x1904, 0x3e2d, 0x2001, 0x032f, 0x2003,
-	0x00f6, 0x8631, 0x1208, 0x8529, 0x2500, 0x9605, 0x0904, 0x3edd,
-	0x7884, 0xd0bc, 0x0128, 0x2d00, 0x9c05, 0x9b05, 0x1904, 0x3edd,
-	0xa013, 0x0019, 0x2001, 0x032a, 0x2003, 0x0004, 0x7884, 0xd0ac,
-	0x1148, 0x2001, 0x1a6a, 0x2003, 0x0003, 0x2001, 0x032a, 0x2003,
-	0x0009, 0x0030, 0xa017, 0x0001, 0x78b4, 0x9005, 0x0108, 0xa016,
-	0x2800, 0xa05a, 0x2009, 0x0040, 0x080c, 0x220a, 0x2900, 0xa85a,
-	0xa813, 0x0019, 0x7884, 0xd0a4, 0x1180, 0xa817, 0x0000, 0x00c6,
-	0x20a9, 0x0004, 0x2061, 0x0090, 0x602b, 0x0008, 0x2001, 0x0203,
-	0x2004, 0x1f04, 0x3eb4, 0x00ce, 0x0030, 0xa817, 0x0001, 0x78b0,
-	0x9005, 0x0108, 0xa816, 0x00f6, 0x00c6, 0x2079, 0x0100, 0x2061,
-	0x0090, 0x7827, 0x0002, 0x2001, 0x002a, 0x2004, 0x9084, 0xfff8,
-	0x601a, 0x0006, 0x2001, 0x002b, 0x2004, 0x601e, 0x78c6, 0x000e,
-	0x78ca, 0x00ce, 0x00fe, 0x0804, 0x3de7, 0x001e, 0x00c6, 0x2001,
-	0x032a, 0x2003, 0x0004, 0x2061, 0x0100, 0x6027, 0x0002, 0x6106,
-	0x2011, 0x020d, 0x2013, 0x0020, 0x2001, 0x0004, 0x200c, 0x918c,
-	0xfffd, 0x2102, 0x080c, 0x1340, 0x7884, 0x9084, 0x0003, 0x9086,
-	0x0002, 0x01b0, 0x2009, 0x0028, 0x080c, 0x220a, 0x2001, 0x0227,
-	0x200c, 0x2102, 0x6050, 0x9084, 0xb7ff, 0x080c, 0x2b0a, 0x6052,
-	0x602f, 0x0000, 0x604b, 0xf7f7, 0x6043, 0x0090, 0x6043, 0x0010,
-	0x080c, 0xa93a, 0x00ce, 0x2d08, 0x2c10, 0x2b18, 0x2b00, 0x9c05,
-	0x9d05, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x00ae, 0x009e,
-	0x008e, 0x1118, 0x012e, 0x0804, 0x35b8, 0x012e, 0x2021, 0x400c,
-	0x0804, 0x35ba, 0x9085, 0x0001, 0x1d04, 0x3f33, 0x2091, 0x6000,
-	0x8420, 0x9486, 0x0064, 0x0005, 0x2001, 0x0105, 0x2003, 0x0010,
-	0x2001, 0x032a, 0x2003, 0x0004, 0x2001, 0x1a6a, 0x2003, 0x0000,
-	0x0071, 0x2009, 0x0048, 0x080c, 0x220a, 0x2001, 0x0227, 0x2024,
-	0x2402, 0x2001, 0x0109, 0x2003, 0x4000, 0x9026, 0x0005, 0x00f6,
-	0x00e6, 0x2071, 0x19e6, 0x7054, 0x9086, 0x0000, 0x0520, 0x2079,
-	0x0090, 0x2009, 0x0206, 0x2104, 0x2009, 0x0203, 0x210c, 0x9106,
-	0x1120, 0x2009, 0x0040, 0x080c, 0x220a, 0x782c, 0xd0fc, 0x0d88,
-	0x080c, 0x4144, 0x7054, 0x9086, 0x0000, 0x1d58, 0x782b, 0x0004,
-	0x782c, 0xd0ac, 0x1de8, 0x2009, 0x0040, 0x080c, 0x220a, 0x782b,
-	0x0002, 0x7057, 0x0000, 0x00ee, 0x00fe, 0x0005, 0x00f6, 0x2079,
-	0x0100, 0x2001, 0x1818, 0x200c, 0x7932, 0x7936, 0x080c, 0x26aa,
-	0x080c, 0x2ad7, 0x080c, 0x2b0a, 0x784b, 0xf7f7, 0x7843, 0x0090,
-	0x7843, 0x0010, 0x7850, 0xc0e5, 0x7852, 0x2019, 0x61a8, 0x7820,
-	0xd09c, 0x0110, 0x8319, 0x1dd8, 0x7850, 0xc0e4, 0x7852, 0x2011,
-	0x0048, 0x080c, 0x2ab4, 0x7843, 0x0040, 0x2019, 0x01f4, 0xa001,
-	0xa001, 0x8319, 0x1de0, 0x2001, 0x0100, 0x080c, 0x2a7a, 0x2011,
-	0x0020, 0x080c, 0x2ab4, 0x7843, 0x0000, 0x9006, 0x080c, 0x2a7a,
-	0x2011, 0x0048, 0x080c, 0x2ab4, 0x00fe, 0x0005, 0x7884, 0xd0ac,
-	0x11c8, 0x00f6, 0x00e6, 0x2071, 0x1a6a, 0x2079, 0x0320, 0x2001,
-	0x0201, 0x2004, 0x9005, 0x0160, 0x7000, 0x9086, 0x0000, 0x1140,
-	0x0051, 0xd0bc, 0x0108, 0x8738, 0x7003, 0x0003, 0x782b, 0x0019,
-	0x00ee, 0x00fe, 0x0005, 0x00f6, 0x2079, 0x0300, 0x78bc, 0x00fe,
-	0x908c, 0x0070, 0x0178, 0x2009, 0x0032, 0x260a, 0x2009, 0x0033,
-	0x250a, 0xd0b4, 0x0108, 0x8c60, 0xd0ac, 0x0108, 0x8d68, 0xd0a4,
-	0x0108, 0x8b58, 0x0005, 0x00f6, 0x2079, 0x0200, 0x781c, 0xd084,
-	0x0110, 0x7837, 0x0050, 0x00fe, 0x0005, 0x00e6, 0x2071, 0x0100,
-	0x2001, 0x19a9, 0x2004, 0x70e2, 0x080c, 0x3d1f, 0x1188, 0x2001,
-	0x1820, 0x2004, 0x2009, 0x181f, 0x210c, 0x918c, 0x00ff, 0x706e,
-	0x716a, 0x7066, 0x918d, 0x3200, 0x7162, 0x7073, 0xe109, 0x0080,
-	0x702c, 0x9085, 0x0002, 0x702e, 0x2009, 0x1818, 0x210c, 0x716e,
-	0x7063, 0x0100, 0x7166, 0x719e, 0x706b, 0x0000, 0x7073, 0x0809,
-	0x7077, 0x0008, 0x7078, 0x9080, 0x0100, 0x707a, 0x7080, 0x8000,
-	0x7082, 0x7087, 0xaaaa, 0x9006, 0x708a, 0x708e, 0x707e, 0x70d6,
-	0x70ab, 0x0036, 0x70af, 0x95d5, 0x7014, 0x9084, 0x1984, 0x9085,
-	0x0092, 0x7016, 0x080c, 0x4144, 0x00f6, 0x2071, 0x1a6a, 0x2079,
-	0x0320, 0x00d6, 0x2069, 0x0000, 0x6884, 0xd0b4, 0x0120, 0x689c,
-	0x780e, 0x6898, 0x780a, 0x00de, 0x2009, 0x03e8, 0x8109, 0x1df0,
-	0x792c, 0xd1fc, 0x0110, 0x782b, 0x0004, 0x2011, 0x0011, 0x080c,
-	0x40d0, 0x2011, 0x0001, 0x080c, 0x40d0, 0x00fe, 0x00ee, 0x0005,
-	0x00f6, 0x00e6, 0x2071, 0x1a6a, 0x2079, 0x0320, 0x792c, 0xd1fc,
-	0x0904, 0x40cd, 0x782b, 0x0002, 0x9026, 0xd19c, 0x1904, 0x40c9,
-	0x7000, 0x0002, 0x40cd, 0x407e, 0x40ae, 0x40c9, 0xd1bc, 0x1170,
-	0xd1dc, 0x1190, 0x8001, 0x7002, 0x2011, 0x0001, 0x080c, 0x40d0,
-	0x0904, 0x40cd, 0x080c, 0x40d0, 0x0804, 0x40cd, 0x00f6, 0x2079,
-	0x0300, 0x78bf, 0x0000, 0x00fe, 0x7810, 0x7914, 0x782b, 0x0004,
-	0x7812, 0x7916, 0x2001, 0x0201, 0x200c, 0x81ff, 0x0de8, 0x080c,
-	0x3fdb, 0x2009, 0x0001, 0x00f6, 0x2079, 0x0300, 0x78b8, 0x00fe,
-	0xd0ec, 0x0110, 0x2009, 0x0011, 0x792a, 0x00f8, 0x8001, 0x7002,
-	0x9184, 0x0880, 0x1140, 0x782c, 0xd0fc, 0x1904, 0x4072, 0x2011,
-	0x0001, 0x00b1, 0x0090, 0xa010, 0x9092, 0x0004, 0x9086, 0x0015,
-	0x1120, 0xa000, 0xa05a, 0x2011, 0x0031, 0xa212, 0xd1dc, 0x1960,
-	0x0828, 0x782b, 0x0004, 0x7003, 0x0000, 0x00ee, 0x00fe, 0x0005,
-	0xa014, 0x9005, 0x0550, 0x8001, 0x0036, 0x0096, 0xa016, 0xa058,
-	0x2048, 0xa010, 0x2009, 0x0031, 0x911a, 0x831c, 0x831c, 0x938a,
-	0x0007, 0x1a0c, 0x0d7d, 0x9398, 0x40fe, 0x231d, 0x083f, 0x9080,
-	0x0004, 0x7a2a, 0x7100, 0x8108, 0x7102, 0x009e, 0x003e, 0x908a,
-	0x0035, 0x1140, 0x0096, 0xa058, 0x2048, 0xa804, 0xa05a, 0x2001,
-	0x0019, 0x009e, 0xa012, 0x9085, 0x0001, 0x0005, 0x413b, 0x4132,
-	0x4129, 0x4120, 0x4117, 0x410e, 0x4105, 0xa964, 0x7902, 0xa968,
-	0x7906, 0xa96c, 0x7912, 0xa970, 0x7916, 0x0005, 0xa974, 0x7902,
-	0xa978, 0x7906, 0xa97c, 0x7912, 0xa980, 0x7916, 0x0005, 0xa984,
-	0x7902, 0xa988, 0x7906, 0xa98c, 0x7912, 0xa990, 0x7916, 0x0005,
-	0xa994, 0x7902, 0xa998, 0x7906, 0xa99c, 0x7912, 0xa9a0, 0x7916,
-	0x0005, 0xa9a4, 0x7902, 0xa9a8, 0x7906, 0xa9ac, 0x7912, 0xa9b0,
-	0x7916, 0x0005, 0xa9b4, 0x7902, 0xa9b8, 0x7906, 0xa9bc, 0x7912,
-	0xa9c0, 0x7916, 0x0005, 0xa9c4, 0x7902, 0xa9c8, 0x7906, 0xa9cc,
-	0x7912, 0xa9d0, 0x7916, 0x0005, 0x00f6, 0x00e6, 0x0086, 0x2071,
-	0x19e6, 0x2079, 0x0090, 0x792c, 0xd1fc, 0x01e8, 0x782b, 0x0002,
-	0x2940, 0x9026, 0x7054, 0x0002, 0x416b, 0x4157, 0x4162, 0x8001,
-	0x7056, 0xd19c, 0x1180, 0x2011, 0x0001, 0x080c, 0x40d0, 0x190c,
-	0x40d0, 0x0048, 0x8001, 0x7056, 0x782c, 0xd0fc, 0x1d38, 0x2011,
-	0x0001, 0x080c, 0x40d0, 0x008e, 0x00ee, 0x00fe, 0x0005, 0x00f6,
-	0x00e6, 0x00c6, 0x0086, 0x2061, 0x0200, 0x2001, 0x19a9, 0x2004,
-	0x601a, 0x2061, 0x0100, 0x2001, 0x19a8, 0x2004, 0x60ce, 0x6104,
-	0xc1ac, 0x6106, 0x2001, 0x002c, 0x2004, 0x9005, 0x0520, 0x2038,
-	0x2001, 0x002e, 0x2024, 0x2001, 0x002f, 0x201c, 0x080c, 0x4af2,
+	0x81ff, 0x0148, 0x080c, 0x2a99, 0x1130, 0x9006, 0x080c, 0x29ec,
+	0x9006, 0x080c, 0x29cf, 0x7884, 0x9084, 0x0007, 0x0002, 0x3e8a,
+	0x3e8b, 0x3e8c, 0x3e87, 0x3e87, 0x3e87, 0x3e87, 0x3e87, 0x012e,
+	0x0804, 0x36bd, 0x0ce0, 0x0cd8, 0x080c, 0x76a5, 0x1128, 0x012e,
+	0x2009, 0x0016, 0x0804, 0x36ba, 0x81ff, 0x0128, 0x012e, 0x2021,
+	0x400b, 0x0804, 0x368a, 0x6000, 0x9086, 0x0003, 0x1db8, 0x2001,
+	0x0141, 0x2004, 0xd0dc, 0x0d90, 0x080c, 0xaae0, 0x0086, 0x0096,
+	0x00a6, 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x080c, 0x3bb1,
+	0x2009, 0x0101, 0x210c, 0x0016, 0x7ec8, 0x7dcc, 0x9006, 0x2068,
+	0x2060, 0x2058, 0x080c, 0x42f8, 0x080c, 0x4248, 0x903e, 0x2720,
+	0x00f6, 0x00e6, 0x0086, 0x2940, 0x2071, 0x19e9, 0x2079, 0x0090,
+	0x00d6, 0x2069, 0x0000, 0x6884, 0xd0b4, 0x0120, 0x68d4, 0x780e,
+	0x68d0, 0x780a, 0x00de, 0x2011, 0x0001, 0x080c, 0x41a9, 0x080c,
+	0x2aa1, 0x080c, 0x2aa1, 0x080c, 0x2aa1, 0x080c, 0x2aa1, 0x080c,
+	0x41a9, 0x008e, 0x00ee, 0x00fe, 0x080c, 0x40d6, 0x2009, 0x9c40,
+	0x8109, 0x11b0, 0x080c, 0x400d, 0x2001, 0x0004, 0x200c, 0x918c,
+	0xfffd, 0x2102, 0x001e, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be,
+	0x00ae, 0x009e, 0x008e, 0x2009, 0x0017, 0x080c, 0x36ba, 0x0cf8,
+	0x2001, 0x020b, 0x2004, 0x9084, 0x0140, 0x1d10, 0x00f6, 0x2079,
+	0x0000, 0x7884, 0x00fe, 0xd0bc, 0x0178, 0x2001, 0x0201, 0x200c,
+	0x81ff, 0x0150, 0x080c, 0x40b4, 0x2d00, 0x9c05, 0x9b05, 0x0120,
+	0x080c, 0x400d, 0x0804, 0x3fb6, 0x080c, 0x421d, 0x080c, 0x4141,
+	0x080c, 0x4097, 0x080c, 0x40cc, 0x00f6, 0x2079, 0x0100, 0x7824,
+	0xd0ac, 0x0130, 0x8b58, 0x080c, 0x400d, 0x00fe, 0x0804, 0x3fb6,
+	0x00fe, 0x080c, 0x4003, 0x1150, 0x8d68, 0x2001, 0x0032, 0x2602,
+	0x2001, 0x0033, 0x2502, 0x080c, 0x400d, 0x0080, 0x87ff, 0x0138,
+	0x2001, 0x0201, 0x2004, 0x9005, 0x1908, 0x8739, 0x0038, 0x2001,
+	0x1a6f, 0x2004, 0x9086, 0x0000, 0x1904, 0x3f06, 0x2001, 0x032f,
+	0x2003, 0x00f6, 0x8631, 0x1208, 0x8529, 0x2500, 0x9605, 0x0904,
+	0x3fb6, 0x7884, 0xd0bc, 0x0128, 0x2d00, 0x9c05, 0x9b05, 0x1904,
+	0x3fb6, 0xa013, 0x0019, 0x2001, 0x032a, 0x2003, 0x0004, 0x7884,
+	0xd0ac, 0x1148, 0x2001, 0x1a6f, 0x2003, 0x0003, 0x2001, 0x032a,
+	0x2003, 0x0009, 0x0030, 0xa017, 0x0001, 0x78b4, 0x9005, 0x0108,
+	0xa016, 0x2800, 0xa05a, 0x2009, 0x0040, 0x080c, 0x2241, 0x2900,
+	0xa85a, 0xa813, 0x0019, 0x7884, 0xd0a4, 0x1180, 0xa817, 0x0000,
+	0x00c6, 0x20a9, 0x0004, 0x2061, 0x0090, 0x602b, 0x0008, 0x2001,
+	0x0203, 0x2004, 0x1f04, 0x3f8d, 0x00ce, 0x0030, 0xa817, 0x0001,
+	0x78b0, 0x9005, 0x0108, 0xa816, 0x00f6, 0x00c6, 0x2079, 0x0100,
+	0x2061, 0x0090, 0x7827, 0x0002, 0x2001, 0x002a, 0x2004, 0x9084,
+	0xfff8, 0x601a, 0x0006, 0x2001, 0x002b, 0x2004, 0x601e, 0x78c6,
+	0x000e, 0x78ca, 0x00ce, 0x00fe, 0x0804, 0x3ec0, 0x001e, 0x00c6,
+	0x2001, 0x032a, 0x2003, 0x0004, 0x2061, 0x0100, 0x6027, 0x0002,
+	0x6106, 0x2011, 0x020d, 0x2013, 0x0020, 0x2001, 0x0004, 0x200c,
+	0x918c, 0xfffd, 0x2102, 0x080c, 0x1352, 0x7884, 0x9084, 0x0003,
+	0x9086, 0x0002, 0x01b0, 0x2009, 0x0028, 0x080c, 0x2241, 0x2001,
+	0x0227, 0x200c, 0x2102, 0x6050, 0x9084, 0xb7ff, 0x080c, 0x2b4b,
+	0x6052, 0x602f, 0x0000, 0x604b, 0xf7f7, 0x6043, 0x0090, 0x6043,
+	0x0010, 0x080c, 0xaafc, 0x00ce, 0x2d08, 0x2c10, 0x2b18, 0x2b00,
+	0x9c05, 0x9d05, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x00ae,
+	0x009e, 0x008e, 0x1118, 0x012e, 0x0804, 0x3688, 0x012e, 0x2021,
+	0x400c, 0x0804, 0x368a, 0x9085, 0x0001, 0x1d04, 0x400c, 0x2091,
+	0x6000, 0x8420, 0x9486, 0x0064, 0x0005, 0x2001, 0x0105, 0x2003,
+	0x0010, 0x2001, 0x032a, 0x2003, 0x0004, 0x2001, 0x1a6f, 0x2003,
+	0x0000, 0x0071, 0x2009, 0x0048, 0x080c, 0x2241, 0x2001, 0x0227,
+	0x2024, 0x2402, 0x2001, 0x0109, 0x2003, 0x4000, 0x9026, 0x0005,
+	0x00f6, 0x00e6, 0x2071, 0x19e9, 0x7054, 0x9086, 0x0000, 0x0520,
+	0x2079, 0x0090, 0x2009, 0x0206, 0x2104, 0x2009, 0x0203, 0x210c,
+	0x9106, 0x1120, 0x2009, 0x0040, 0x080c, 0x2241, 0x782c, 0xd0fc,
+	0x0d88, 0x080c, 0x421d, 0x7054, 0x9086, 0x0000, 0x1d58, 0x782b,
+	0x0004, 0x782c, 0xd0ac, 0x1de8, 0x2009, 0x0040, 0x080c, 0x2241,
+	0x782b, 0x0002, 0x7057, 0x0000, 0x00ee, 0x00fe, 0x0005, 0x00f6,
+	0x2079, 0x0100, 0x2001, 0x1818, 0x200c, 0x7932, 0x7936, 0x080c,
+	0x26eb, 0x080c, 0x2b18, 0x080c, 0x2b4b, 0x784b, 0xf7f7, 0x7843,
+	0x0090, 0x7843, 0x0010, 0x7850, 0xc0e5, 0x7852, 0x2019, 0x61a8,
+	0x7820, 0xd09c, 0x0110, 0x8319, 0x1dd8, 0x7850, 0xc0e4, 0x7852,
+	0x2011, 0x0048, 0x080c, 0x2af5, 0x7843, 0x0040, 0x2019, 0x01f4,
+	0xa001, 0xa001, 0x8319, 0x1de0, 0x2001, 0x0100, 0x080c, 0x2abb,
+	0x2011, 0x0020, 0x080c, 0x2af5, 0x7843, 0x0000, 0x9006, 0x080c,
+	0x2abb, 0x2011, 0x0048, 0x080c, 0x2af5, 0x00fe, 0x0005, 0x7884,
+	0xd0ac, 0x11c8, 0x00f6, 0x00e6, 0x2071, 0x1a6f, 0x2079, 0x0320,
+	0x2001, 0x0201, 0x2004, 0x9005, 0x0160, 0x7000, 0x9086, 0x0000,
+	0x1140, 0x0051, 0xd0bc, 0x0108, 0x8738, 0x7003, 0x0003, 0x782b,
+	0x0019, 0x00ee, 0x00fe, 0x0005, 0x00f6, 0x2079, 0x0300, 0x78bc,
+	0x00fe, 0x908c, 0x0070, 0x0178, 0x2009, 0x0032, 0x260a, 0x2009,
+	0x0033, 0x250a, 0xd0b4, 0x0108, 0x8c60, 0xd0ac, 0x0108, 0x8d68,
+	0xd0a4, 0x0108, 0x8b58, 0x0005, 0x00f6, 0x2079, 0x0200, 0x781c,
+	0xd084, 0x0110, 0x7837, 0x0050, 0x00fe, 0x0005, 0x00e6, 0x2071,
+	0x0100, 0x2001, 0x19ab, 0x2004, 0x70e2, 0x080c, 0x3def, 0x1188,
+	0x2001, 0x1820, 0x2004, 0x2009, 0x181f, 0x210c, 0x918c, 0x00ff,
+	0x706e, 0x716a, 0x7066, 0x918d, 0x3200, 0x7162, 0x7073, 0xe109,
+	0x0080, 0x702c, 0x9085, 0x0002, 0x702e, 0x2009, 0x1818, 0x210c,
+	0x716e, 0x7063, 0x0100, 0x7166, 0x719e, 0x706b, 0x0000, 0x7073,
+	0x0809, 0x7077, 0x0008, 0x7078, 0x9080, 0x0100, 0x707a, 0x7080,
+	0x8000, 0x7082, 0x7087, 0xaaaa, 0x9006, 0x708a, 0x708e, 0x707e,
+	0x70d6, 0x70ab, 0x0036, 0x70af, 0x95d5, 0x7014, 0x9084, 0x1984,
+	0x9085, 0x0092, 0x7016, 0x080c, 0x421d, 0x00f6, 0x2071, 0x1a6f,
+	0x2079, 0x0320, 0x00d6, 0x2069, 0x0000, 0x6884, 0xd0b4, 0x0120,
+	0x689c, 0x780e, 0x6898, 0x780a, 0x00de, 0x2009, 0x03e8, 0x8109,
+	0x1df0, 0x792c, 0xd1fc, 0x0110, 0x782b, 0x0004, 0x2011, 0x0011,
+	0x080c, 0x41a9, 0x2011, 0x0001, 0x080c, 0x41a9, 0x00fe, 0x00ee,
+	0x0005, 0x00f6, 0x00e6, 0x2071, 0x1a6f, 0x2079, 0x0320, 0x792c,
+	0xd1fc, 0x0904, 0x41a6, 0x782b, 0x0002, 0x9026, 0xd19c, 0x1904,
+	0x41a2, 0x7000, 0x0002, 0x41a6, 0x4157, 0x4187, 0x41a2, 0xd1bc,
+	0x1170, 0xd1dc, 0x1190, 0x8001, 0x7002, 0x2011, 0x0001, 0x080c,
+	0x41a9, 0x0904, 0x41a6, 0x080c, 0x41a9, 0x0804, 0x41a6, 0x00f6,
+	0x2079, 0x0300, 0x78bf, 0x0000, 0x00fe, 0x7810, 0x7914, 0x782b,
+	0x0004, 0x7812, 0x7916, 0x2001, 0x0201, 0x200c, 0x81ff, 0x0de8,
+	0x080c, 0x40b4, 0x2009, 0x0001, 0x00f6, 0x2079, 0x0300, 0x78b8,
+	0x00fe, 0xd0ec, 0x0110, 0x2009, 0x0011, 0x792a, 0x00f8, 0x8001,
+	0x7002, 0x9184, 0x0880, 0x1140, 0x782c, 0xd0fc, 0x1904, 0x414b,
+	0x2011, 0x0001, 0x00b1, 0x0090, 0xa010, 0x9092, 0x0004, 0x9086,
+	0x0015, 0x1120, 0xa000, 0xa05a, 0x2011, 0x0031, 0xa212, 0xd1dc,
+	0x1960, 0x0828, 0x782b, 0x0004, 0x7003, 0x0000, 0x00ee, 0x00fe,
+	0x0005, 0xa014, 0x9005, 0x0550, 0x8001, 0x0036, 0x0096, 0xa016,
+	0xa058, 0x2048, 0xa010, 0x2009, 0x0031, 0x911a, 0x831c, 0x831c,
+	0x938a, 0x0007, 0x1a0c, 0x0d85, 0x9398, 0x41d7, 0x231d, 0x083f,
+	0x9080, 0x0004, 0x7a2a, 0x7100, 0x8108, 0x7102, 0x009e, 0x003e,
+	0x908a, 0x0035, 0x1140, 0x0096, 0xa058, 0x2048, 0xa804, 0xa05a,
+	0x2001, 0x0019, 0x009e, 0xa012, 0x9085, 0x0001, 0x0005, 0x4214,
+	0x420b, 0x4202, 0x41f9, 0x41f0, 0x41e7, 0x41de, 0xa964, 0x7902,
+	0xa968, 0x7906, 0xa96c, 0x7912, 0xa970, 0x7916, 0x0005, 0xa974,
+	0x7902, 0xa978, 0x7906, 0xa97c, 0x7912, 0xa980, 0x7916, 0x0005,
+	0xa984, 0x7902, 0xa988, 0x7906, 0xa98c, 0x7912, 0xa990, 0x7916,
+	0x0005, 0xa994, 0x7902, 0xa998, 0x7906, 0xa99c, 0x7912, 0xa9a0,
+	0x7916, 0x0005, 0xa9a4, 0x7902, 0xa9a8, 0x7906, 0xa9ac, 0x7912,
+	0xa9b0, 0x7916, 0x0005, 0xa9b4, 0x7902, 0xa9b8, 0x7906, 0xa9bc,
+	0x7912, 0xa9c0, 0x7916, 0x0005, 0xa9c4, 0x7902, 0xa9c8, 0x7906,
+	0xa9cc, 0x7912, 0xa9d0, 0x7916, 0x0005, 0x00f6, 0x00e6, 0x0086,
+	0x2071, 0x19e9, 0x2079, 0x0090, 0x792c, 0xd1fc, 0x01e8, 0x782b,
+	0x0002, 0x2940, 0x9026, 0x7054, 0x0002, 0x4244, 0x4230, 0x423b,
+	0x8001, 0x7056, 0xd19c, 0x1180, 0x2011, 0x0001, 0x080c, 0x41a9,
+	0x190c, 0x41a9, 0x0048, 0x8001, 0x7056, 0x782c, 0xd0fc, 0x1d38,
+	0x2011, 0x0001, 0x080c, 0x41a9, 0x008e, 0x00ee, 0x00fe, 0x0005,
+	0x00f6, 0x00e6, 0x00c6, 0x0086, 0x2061, 0x0200, 0x2001, 0x19ab,
+	0x2004, 0x601a, 0x2061, 0x0100, 0x2001, 0x19aa, 0x2004, 0x60ce,
+	0x6104, 0xc1ac, 0x6106, 0x2001, 0x002c, 0x2004, 0x9005, 0x0520,
+	0x2038, 0x2001, 0x002e, 0x2024, 0x2001, 0x002f, 0x201c, 0x080c,
+	0x4bce, 0xa813, 0x0019, 0xaf16, 0x2900, 0xa85a, 0x978a, 0x0007,
+	0x0220, 0x2138, 0x2009, 0x0007, 0x0010, 0x2708, 0x903e, 0x0096,
+	0xa858, 0x2048, 0xa85c, 0x9080, 0x0019, 0x009e, 0x080c, 0x42c0,
+	0x1d68, 0x2900, 0xa85a, 0x00d0, 0x080c, 0x4bce, 0xa813, 0x0019,
+	0xa817, 0x0001, 0x2900, 0xa85a, 0x2001, 0x002e, 0x2004, 0xa866,
+	0x2001, 0x002f, 0x2004, 0xa86a, 0x2001, 0x002a, 0x2004, 0x9084,
+	0xfff8, 0xa86e, 0x2001, 0x002b, 0x2004, 0xa872, 0x2061, 0x0090,
+	0x2079, 0x0100, 0x2001, 0x19aa, 0x2004, 0x6036, 0x2009, 0x0040,
+	0x080c, 0x2241, 0x2001, 0x002a, 0x2004, 0x9084, 0xfff8, 0x601a,
+	0x0006, 0x2001, 0x002b, 0x2004, 0x601e, 0x78c6, 0x000e, 0x78ca,
+	0x9006, 0x600a, 0x600e, 0x008e, 0x00ce, 0x00ee, 0x00fe, 0x0005,
+	0x00e6, 0x2071, 0x0080, 0xaa60, 0x22e8, 0x20a0, 0x20e1, 0x0000,
+	0x2099, 0x0088, 0x702b, 0x0026, 0x7402, 0x7306, 0x9006, 0x700a,
+	0x700e, 0x810b, 0x810b, 0x21a8, 0x810b, 0x7112, 0x702b, 0x0041,
+	0x702c, 0xd0fc, 0x0de8, 0x702b, 0x0002, 0x702b, 0x0040, 0x4005,
+	0x7400, 0x7304, 0x87ff, 0x0190, 0x0086, 0x0096, 0x2940, 0x0086,
+	0x080c, 0x4bce, 0x008e, 0xa058, 0x00a6, 0x2050, 0x2900, 0xb006,
+	0xa05a, 0x00ae, 0x009e, 0x008e, 0x9085, 0x0001, 0x00ee, 0x0005,
+	0x00e6, 0x2001, 0x002d, 0x2004, 0x9005, 0x0528, 0x2038, 0x2001,
+	0x0030, 0x2024, 0x2001, 0x0031, 0x201c, 0x080c, 0x4bce, 0x2940,
 	0xa813, 0x0019, 0xaf16, 0x2900, 0xa85a, 0x978a, 0x0007, 0x0220,
 	0x2138, 0x2009, 0x0007, 0x0010, 0x2708, 0x903e, 0x0096, 0xa858,
-	0x2048, 0xa85c, 0x9080, 0x0019, 0x009e, 0x080c, 0x41e7, 0x1d68,
-	0x2900, 0xa85a, 0x00d0, 0x080c, 0x4af2, 0xa813, 0x0019, 0xa817,
-	0x0001, 0x2900, 0xa85a, 0x2001, 0x002e, 0x2004, 0xa866, 0x2001,
-	0x002f, 0x2004, 0xa86a, 0x2001, 0x002a, 0x2004, 0x9084, 0xfff8,
-	0xa86e, 0x2001, 0x002b, 0x2004, 0xa872, 0x2061, 0x0090, 0x2079,
-	0x0100, 0x2001, 0x19a8, 0x2004, 0x6036, 0x2009, 0x0040, 0x080c,
-	0x220a, 0x2001, 0x002a, 0x2004, 0x9084, 0xfff8, 0x601a, 0x0006,
-	0x2001, 0x002b, 0x2004, 0x601e, 0x78c6, 0x000e, 0x78ca, 0x9006,
-	0x600a, 0x600e, 0x008e, 0x00ce, 0x00ee, 0x00fe, 0x0005, 0x00e6,
-	0x2071, 0x0080, 0xaa60, 0x22e8, 0x20a0, 0x20e1, 0x0000, 0x2099,
-	0x0088, 0x702b, 0x0026, 0x7402, 0x7306, 0x9006, 0x700a, 0x700e,
-	0x810b, 0x810b, 0x21a8, 0x810b, 0x7112, 0x702b, 0x0041, 0x702c,
-	0xd0fc, 0x0de8, 0x702b, 0x0002, 0x702b, 0x0040, 0x4005, 0x7400,
-	0x7304, 0x87ff, 0x0190, 0x0086, 0x0096, 0x2940, 0x0086, 0x080c,
-	0x4af2, 0x008e, 0xa058, 0x00a6, 0x2050, 0x2900, 0xb006, 0xa05a,
-	0x00ae, 0x009e, 0x008e, 0x9085, 0x0001, 0x00ee, 0x0005, 0x00e6,
-	0x2001, 0x002d, 0x2004, 0x9005, 0x0528, 0x2038, 0x2001, 0x0030,
-	0x2024, 0x2001, 0x0031, 0x201c, 0x080c, 0x4af2, 0x2940, 0xa813,
-	0x0019, 0xaf16, 0x2900, 0xa85a, 0x978a, 0x0007, 0x0220, 0x2138,
-	0x2009, 0x0007, 0x0010, 0x2708, 0x903e, 0x0096, 0xa858, 0x2048,
-	0xa85c, 0x9080, 0x0019, 0x009e, 0x080c, 0x41e7, 0x1d68, 0x2900,
-	0xa85a, 0x00d8, 0x080c, 0x4af2, 0x2940, 0xa013, 0x0019, 0xa017,
-	0x0001, 0x2800, 0xa05a, 0x2001, 0x0030, 0x2004, 0xa066, 0x2001,
-	0x0031, 0x2004, 0xa06a, 0x2001, 0x002a, 0x2004, 0x9084, 0xfff8,
-	0xa06e, 0x2001, 0x002b, 0x2004, 0xa072, 0x2001, 0x032a, 0x2003,
-	0x0004, 0x7884, 0xd0ac, 0x1180, 0x2001, 0x0101, 0x200c, 0x918d,
-	0x0200, 0x2102, 0xa017, 0x0000, 0x2001, 0x1a6a, 0x2003, 0x0003,
-	0x2001, 0x032a, 0x2003, 0x0009, 0x2001, 0x0300, 0x2003, 0x0000,
-	0x2001, 0x020d, 0x2003, 0x0000, 0x2001, 0x0004, 0x200c, 0x918d,
-	0x0002, 0x2102, 0x00ee, 0x0005, 0x0126, 0x2091, 0x8000, 0x20a9,
-	0x0007, 0x20a1, 0x1840, 0x20e9, 0x0001, 0x9006, 0x4004, 0x20a9,
-	0x0014, 0x20a1, 0xffec, 0x20e9, 0x0000, 0x9006, 0x4004, 0x2009,
-	0x013c, 0x200a, 0x012e, 0x7880, 0x9086, 0x0052, 0x0108, 0x0005,
-	0x0804, 0x35b8, 0x7d98, 0x7c9c, 0x0804, 0x36ba, 0x080c, 0x753d,
-	0x190c, 0x6057, 0x6040, 0x9084, 0x0020, 0x09b1, 0x2069, 0x1847,
-	0x2d00, 0x2009, 0x0030, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x2039,
-	0x0001, 0x080c, 0x4b3b, 0x701f, 0x42c6, 0x0005, 0x080c, 0x574d,
-	0x1130, 0x3b00, 0x3a08, 0xc194, 0xc095, 0x20d8, 0x21d0, 0x2069,
-	0x1847, 0x6800, 0x9005, 0x0904, 0x35ed, 0x6804, 0xd0ac, 0x0118,
-	0xd0a4, 0x0904, 0x35ed, 0xd094, 0x00c6, 0x2061, 0x0100, 0x6104,
-	0x0138, 0x6200, 0x9292, 0x0005, 0x0218, 0x918c, 0xffdf, 0x0010,
-	0x918d, 0x0020, 0x6106, 0x00ce, 0xd08c, 0x00c6, 0x2061, 0x0100,
-	0x6104, 0x0118, 0x918d, 0x0010, 0x0010, 0x918c, 0xffef, 0x6106,
-	0x00ce, 0xd084, 0x0158, 0x6a28, 0x928a, 0x007f, 0x1a04, 0x35ed,
-	0x9288, 0x33b9, 0x210d, 0x918c, 0x00ff, 0x6166, 0xd0dc, 0x0130,
-	0x6828, 0x908a, 0x007f, 0x1a04, 0x35ed, 0x605e, 0x6888, 0x9084,
-	0x0030, 0x8004, 0x8004, 0x8004, 0x8004, 0x0006, 0x2009, 0x19b0,
-	0x9080, 0x279d, 0x2005, 0x200a, 0x2008, 0x2001, 0x0018, 0x080c,
-	0xa90f, 0x2009, 0x0390, 0x200b, 0x0400, 0x000e, 0x2009, 0x19b1,
-	0x9080, 0x27a1, 0x2005, 0x200a, 0x6808, 0x908a, 0x0100, 0x0a04,
-	0x35ed, 0x908a, 0x0841, 0x1a04, 0x35ed, 0x9084, 0x0007, 0x1904,
-	0x35ed, 0x680c, 0x9005, 0x0904, 0x35ed, 0x6810, 0x9005, 0x0904,
-	0x35ed, 0x6848, 0x6940, 0x910a, 0x1a04, 0x35ed, 0x8001, 0x0904,
-	0x35ed, 0x684c, 0x6944, 0x910a, 0x1a04, 0x35ed, 0x8001, 0x0904,
-	0x35ed, 0x6814, 0x908c, 0x00ff, 0x614e, 0x8007, 0x9084, 0x00ff,
-	0x6052, 0x080c, 0x7871, 0x080c, 0x6b0f, 0x080c, 0x6b43, 0x6808,
-	0x602a, 0x080c, 0x217c, 0x2009, 0x0170, 0x200b, 0x0080, 0xa001,
-	0xa001, 0x200b, 0x0000, 0x0036, 0x6b08, 0x080c, 0x2704, 0x003e,
-	0x6000, 0x9086, 0x0000, 0x1904, 0x4451, 0x6818, 0x691c, 0x6a20,
-	0x6b24, 0x8007, 0x810f, 0x8217, 0x831f, 0x6016, 0x611a, 0x621e,
-	0x6322, 0x6c04, 0xd4f4, 0x0148, 0x6830, 0x6934, 0x6a38, 0x6b3c,
-	0x8007, 0x810f, 0x8217, 0x831f, 0x0010, 0x9084, 0xf0ff, 0x6006,
-	0x610a, 0x620e, 0x6312, 0x8007, 0x810f, 0x8217, 0x831f, 0x20a9,
-	0x0004, 0x20a1, 0x19b2, 0x20e9, 0x0001, 0x4001, 0x20a9, 0x0004,
-	0x20a1, 0x19cc, 0x20e9, 0x0001, 0x4001, 0x080c, 0x885b, 0x00c6,
-	0x900e, 0x20a9, 0x0001, 0x6b70, 0xd384, 0x01c8, 0x0020, 0x839d,
-	0x12b0, 0x3508, 0x8109, 0x080c, 0x7e33, 0x6878, 0x6016, 0x6874,
-	0x2008, 0x9084, 0xff00, 0x8007, 0x600a, 0x9184, 0x00ff, 0x6006,
-	0x8108, 0x1118, 0x6003, 0x0003, 0x0010, 0x6003, 0x0001, 0x1f04,
-	0x43af, 0x00ce, 0x00c6, 0x2061, 0x199b, 0x6a88, 0x9284, 0xc000,
-	0x2010, 0x9286, 0x0000, 0x1158, 0x2063, 0x0000, 0x2001, 0x0001,
-	0x080c, 0x29ab, 0x2001, 0x0001, 0x080c, 0x298e, 0x0088, 0x9286,
-	0x4000, 0x1148, 0x2063, 0x0001, 0x9006, 0x080c, 0x29ab, 0x9006,
-	0x080c, 0x298e, 0x0028, 0x9286, 0x8000, 0x1d30, 0x2063, 0x0002,
-	0x00ce, 0x00e6, 0x2c70, 0x080c, 0x0ec1, 0x00ee, 0x6888, 0xd0ec,
-	0x0130, 0x2011, 0x0114, 0x2204, 0x9085, 0x0180, 0x2012, 0x6a80,
-	0x9284, 0x0030, 0x9086, 0x0030, 0x1128, 0x9294, 0xffcf, 0x9295,
-	0x0020, 0x6a82, 0x2001, 0x197b, 0x6a80, 0x9294, 0x0030, 0x928e,
-	0x0000, 0x0170, 0x928e, 0x0010, 0x0118, 0x928e, 0x0020, 0x0140,
-	0x2003, 0xaaaa, 0x080c, 0x2779, 0x2001, 0x196c, 0x2102, 0x0008,
-	0x2102, 0x00c6, 0x2061, 0x0100, 0x602f, 0x0040, 0x602f, 0x0000,
-	0x00ce, 0x080c, 0x753d, 0x0128, 0x080c, 0x5027, 0x0110, 0x080c,
-	0x26ca, 0x60d4, 0x9005, 0x01c0, 0x6003, 0x0001, 0x2009, 0x4439,
-	0x00e0, 0x080c, 0x753d, 0x1168, 0x2011, 0x73b3, 0x080c, 0x86c8,
-	0x2011, 0x73a6, 0x080c, 0x87d4, 0x080c, 0x7845, 0x080c, 0x746e,
-	0x0040, 0x080c, 0x5f4d, 0x0028, 0x6003, 0x0004, 0x2009, 0x4451,
-	0x0020, 0x080c, 0x6a3f, 0x0804, 0x35b8, 0x2001, 0x0170, 0x2004,
-	0x9084, 0x00ff, 0x9086, 0x004c, 0x1118, 0x2091, 0x31bd, 0x0817,
-	0x2091, 0x313d, 0x0817, 0x6000, 0x9086, 0x0000, 0x0904, 0x35ea,
-	0x2069, 0x1847, 0x7890, 0x6842, 0x7894, 0x6846, 0x2d00, 0x2009,
-	0x0030, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x2039, 0x0001, 0x0804,
-	0x4b3e, 0x9006, 0x080c, 0x26ca, 0x81ff, 0x1904, 0x35ea, 0x080c,
-	0x753d, 0x11b0, 0x080c, 0x7840, 0x080c, 0x6092, 0x080c, 0x33ad,
-	0x0118, 0x6130, 0xc18d, 0x6132, 0x080c, 0xd09b, 0x0130, 0x080c,
-	0x7560, 0x1118, 0x080c, 0x7511, 0x0038, 0x080c, 0x746e, 0x0020,
-	0x080c, 0x6057, 0x080c, 0x5f4d, 0x0804, 0x35b8, 0x81ff, 0x1904,
-	0x35ea, 0x080c, 0x753d, 0x1110, 0x0804, 0x35ea, 0x6194, 0x81ff,
-	0x01a8, 0x704f, 0x0000, 0x2001, 0x1d80, 0x2009, 0x0040, 0x7a8c,
-	0x7b88, 0x7c9c, 0x7d98, 0x0126, 0x2091, 0x8000, 0x2039, 0x0001,
-	0x080c, 0x4b3e, 0x701f, 0x35b6, 0x012e, 0x0005, 0x704f, 0x0001,
-	0x00d6, 0x2069, 0x1d80, 0x20a9, 0x0040, 0x20e9, 0x0001, 0x20a1,
-	0x1d80, 0x2019, 0xffff, 0x4304, 0x655c, 0x9588, 0x33b9, 0x210d,
-	0x918c, 0x00ff, 0x216a, 0x900e, 0x2011, 0x0002, 0x2100, 0x9506,
-	0x01a8, 0x080c, 0x6693, 0x1190, 0xb814, 0x821c, 0x0238, 0x9398,
-	0x1d80, 0x9085, 0xff00, 0x8007, 0x201a, 0x0038, 0x9398, 0x1d80,
-	0x2324, 0x94a4, 0xff00, 0x9405, 0x201a, 0x8210, 0x8108, 0x9182,
-	0x0080, 0x1208, 0x0c18, 0x8201, 0x8007, 0x2d0c, 0x9105, 0x206a,
-	0x00de, 0x20a9, 0x0040, 0x20a1, 0x1d80, 0x2099, 0x1d80, 0x080c,
-	0x5fe2, 0x0804, 0x44ab, 0x080c, 0x4b25, 0x0904, 0x35ed, 0x080c,
-	0x4af2, 0x1120, 0x2009, 0x0002, 0x0804, 0x35ea, 0x080c, 0x573e,
-	0xd0b4, 0x0558, 0x7884, 0x908e, 0x007e, 0x0538, 0x908e, 0x007f,
-	0x0520, 0x908e, 0x0080, 0x0508, 0x080c, 0x33a8, 0x1148, 0xb800,
-	0xd08c, 0x11d8, 0xb804, 0x9084, 0x00ff, 0x9086, 0x0006, 0x11a8,
-	0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x080c, 0xcb4b, 0x1120,
-	0x2009, 0x0003, 0x0804, 0x35ea, 0x7007, 0x0003, 0x701f, 0x4539,
-	0x0005, 0x080c, 0x4b25, 0x0904, 0x35ed, 0x20a9, 0x002b, 0xb8c4,
-	0x20e0, 0xb8c8, 0x2098, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0002,
-	0x20a0, 0x4003, 0x20a9, 0x0008, 0x9080, 0x0006, 0x20a0, 0xb8c4,
-	0x20e0, 0xb8c8, 0x9080, 0x0006, 0x2098, 0x080c, 0x0fc4, 0x0070,
-	0x20a9, 0x0004, 0xa85c, 0x9080, 0x000a, 0x20a0, 0xb8c4, 0x20e0,
-	0xb8c8, 0x9080, 0x000a, 0x2098, 0x080c, 0x0fc4, 0x8906, 0x8006,
-	0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x0002, 0x2009,
-	0x002b, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x0804, 0x4b3e, 0x81ff,
-	0x1904, 0x35ea, 0x080c, 0x4b09, 0x0904, 0x35ed, 0x080c, 0x68d8,
-	0x0904, 0x35ea, 0x0058, 0xa878, 0x9005, 0x0120, 0x2009, 0x0004,
-	0x0804, 0x35ea, 0xa974, 0xaa94, 0x0804, 0x35b8, 0x080c, 0x5746,
-	0x0904, 0x35b8, 0x701f, 0x4583, 0x7007, 0x0003, 0x0005, 0x81ff,
-	0x1904, 0x35ea, 0x7888, 0x908a, 0x1000, 0x1a04, 0x35ed, 0x080c,
-	0x4b25, 0x0904, 0x35ed, 0x080c, 0x6add, 0x0120, 0x080c, 0x6ae5,
-	0x1904, 0x35ed, 0x080c, 0x695d, 0x0904, 0x35ea, 0x2019, 0x0004,
-	0x900e, 0x080c, 0x68ea, 0x0904, 0x35ea, 0x7984, 0x7a88, 0x04c9,
-	0x08a8, 0xa89c, 0x908a, 0x1000, 0x12f8, 0x080c, 0x4b23, 0x01e0,
-	0x080c, 0x6add, 0x0118, 0x080c, 0x6ae5, 0x11b0, 0x080c, 0x695d,
-	0x2009, 0x0002, 0x0168, 0x2009, 0x0002, 0x2019, 0x0004, 0x080c,
-	0x68ea, 0x2009, 0x0003, 0x0120, 0xa998, 0xaa9c, 0x00d1, 0x0060,
-	0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e, 0x9085,
-	0x0001, 0x2001, 0x0030, 0x0005, 0xa897, 0x4000, 0x080c, 0x5746,
-	0x0110, 0x9006, 0x0018, 0x900e, 0x9085, 0x0001, 0x2001, 0x0000,
-	0x0005, 0x9186, 0x00ff, 0x0110, 0x0071, 0x0060, 0x2029, 0x007e,
-	0x2061, 0x1800, 0x645c, 0x2400, 0x9506, 0x0110, 0x2508, 0x0019,
-	0x8529, 0x1ec8, 0x0005, 0x080c, 0x6693, 0x1138, 0x2200, 0x8003,
-	0x800b, 0x810b, 0x9108, 0x080c, 0x86d6, 0x0005, 0x81ff, 0x1904,
-	0x35ea, 0x798c, 0x2001, 0x197f, 0x918c, 0x8000, 0x2102, 0x080c,
-	0x4b09, 0x0904, 0x35ed, 0x080c, 0x6add, 0x0120, 0x080c, 0x6ae5,
-	0x1904, 0x35ed, 0x080c, 0x675a, 0x0904, 0x35ea, 0x080c, 0x68e1,
-	0x0904, 0x35ea, 0x2001, 0x197f, 0x2004, 0xd0fc, 0x1904, 0x35b8,
-	0x0804, 0x458e, 0xa9a0, 0x2001, 0x197f, 0x918c, 0x8000, 0xc18d,
-	0x2102, 0x080c, 0x4b16, 0x01a0, 0x080c, 0x6add, 0x0118, 0x080c,
-	0x6ae5, 0x1170, 0x080c, 0x675a, 0x2009, 0x0002, 0x0128, 0x080c,
-	0x68e1, 0x1170, 0x2009, 0x0003, 0xa897, 0x4005, 0xa99a, 0x0010,
-	0xa897, 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x0005,
-	0xa897, 0x4000, 0x2001, 0x197f, 0x2004, 0xd0fc, 0x1128, 0x080c,
-	0x5746, 0x0110, 0x9006, 0x0018, 0x900e, 0x9085, 0x0001, 0x2001,
-	0x0000, 0x0005, 0x81ff, 0x1904, 0x35ea, 0x798c, 0x2001, 0x197e,
-	0x918c, 0x8000, 0x2102, 0x080c, 0x4b09, 0x0904, 0x35ed, 0x080c,
-	0x6add, 0x0120, 0x080c, 0x6ae5, 0x1904, 0x35ed, 0x080c, 0x675a,
-	0x0904, 0x35ea, 0x080c, 0x68cf, 0x0904, 0x35ea, 0x2001, 0x197e,
-	0x2004, 0xd0fc, 0x1904, 0x35b8, 0x0804, 0x458e, 0xa9a0, 0x2001,
-	0x197e, 0x918c, 0x8000, 0xc18d, 0x2102, 0x080c, 0x4b16, 0x01a0,
-	0x080c, 0x6add, 0x0118, 0x080c, 0x6ae5, 0x1170, 0x080c, 0x675a,
-	0x2009, 0x0002, 0x0128, 0x080c, 0x68cf, 0x1170, 0x2009, 0x0003,
-	0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e, 0x9085,
-	0x0001, 0x2001, 0x0030, 0x0005, 0xa897, 0x4000, 0x2001, 0x197e,
-	0x2004, 0xd0fc, 0x1128, 0x080c, 0x5746, 0x0110, 0x9006, 0x0018,
-	0x900e, 0x9085, 0x0001, 0x2001, 0x0000, 0x0005, 0x6100, 0x0804,
-	0x35b8, 0x080c, 0x4b25, 0x0904, 0x35ed, 0x080c, 0x5752, 0x1904,
-	0x35ea, 0x79a8, 0xd184, 0x1158, 0xb834, 0x8007, 0x789e, 0xb830,
-	0x8007, 0x789a, 0xbb2c, 0x831f, 0xba28, 0x8217, 0x0050, 0xb824,
-	0x8007, 0x789e, 0xb820, 0x8007, 0x789a, 0xbb1c, 0x831f, 0xba18,
-	0x8217, 0xb900, 0x918c, 0x0202, 0x0804, 0x35b8, 0x78a8, 0x909c,
-	0x0003, 0xd0ac, 0x1150, 0xd0b4, 0x1140, 0x939a, 0x0003, 0x1a04,
-	0x35ea, 0x625c, 0x7884, 0x9206, 0x1548, 0x080c, 0x8845, 0x2001,
-	0xffec, 0x2009, 0x000c, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x2039,
-	0x0000, 0x0006, 0x78a8, 0x9084, 0x0080, 0x1118, 0x000e, 0x0804,
-	0x4b3e, 0x000e, 0x2031, 0x0000, 0x2061, 0x18b8, 0x2c44, 0xa66a,
+	0x2048, 0xa85c, 0x9080, 0x0019, 0x009e, 0x080c, 0x42c0, 0x1d68,
+	0x2900, 0xa85a, 0x00d8, 0x080c, 0x4bce, 0x2940, 0xa013, 0x0019,
+	0xa017, 0x0001, 0x2800, 0xa05a, 0x2001, 0x0030, 0x2004, 0xa066,
+	0x2001, 0x0031, 0x2004, 0xa06a, 0x2001, 0x002a, 0x2004, 0x9084,
+	0xfff8, 0xa06e, 0x2001, 0x002b, 0x2004, 0xa072, 0x2001, 0x032a,
+	0x2003, 0x0004, 0x7884, 0xd0ac, 0x1180, 0x2001, 0x0101, 0x200c,
+	0x918d, 0x0200, 0x2102, 0xa017, 0x0000, 0x2001, 0x1a6f, 0x2003,
+	0x0003, 0x2001, 0x032a, 0x2003, 0x0009, 0x2001, 0x0300, 0x2003,
+	0x0000, 0x2001, 0x020d, 0x2003, 0x0000, 0x2001, 0x0004, 0x200c,
+	0x918d, 0x0002, 0x2102, 0x00ee, 0x0005, 0x0126, 0x2091, 0x8000,
+	0x20a9, 0x0007, 0x20a1, 0x1840, 0x20e9, 0x0001, 0x9006, 0x4004,
+	0x20a9, 0x0014, 0x20a1, 0xffec, 0x20e9, 0x0000, 0x9006, 0x4004,
+	0x2009, 0x013c, 0x200a, 0x012e, 0x7880, 0x9086, 0x0052, 0x0108,
+	0x0005, 0x0804, 0x3688, 0x7d98, 0x7c9c, 0x0804, 0x378c, 0x080c,
+	0x76a5, 0x190c, 0x6143, 0x6040, 0x9084, 0x0020, 0x09b1, 0x2069,
+	0x1847, 0x2d00, 0x2009, 0x0030, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98,
+	0x2039, 0x0001, 0x080c, 0x4c17, 0x701f, 0x439f, 0x0005, 0x080c,
+	0x5835, 0x1130, 0x3b00, 0x3a08, 0xc194, 0xc095, 0x20d8, 0x21d0,
+	0x2069, 0x1847, 0x6800, 0x9005, 0x0904, 0x36bd, 0x6804, 0xd0ac,
+	0x0118, 0xd0a4, 0x0904, 0x36bd, 0xd094, 0x00c6, 0x2061, 0x0100,
+	0x6104, 0x0138, 0x6200, 0x9292, 0x0005, 0x0218, 0x918c, 0xffdf,
+	0x0010, 0x918d, 0x0020, 0x6106, 0x00ce, 0xd08c, 0x00c6, 0x2061,
+	0x0100, 0x6104, 0x0118, 0x918d, 0x0010, 0x0010, 0x918c, 0xffef,
+	0x6106, 0x00ce, 0xd084, 0x0158, 0x6a28, 0x928a, 0x007f, 0x1a04,
+	0x36bd, 0x9288, 0x3489, 0x210d, 0x918c, 0x00ff, 0x6166, 0xd0dc,
+	0x0130, 0x6828, 0x908a, 0x007f, 0x1a04, 0x36bd, 0x605e, 0x6888,
+	0x9084, 0x0030, 0x8004, 0x8004, 0x8004, 0x8004, 0x0006, 0x2009,
+	0x19b3, 0x9080, 0x27de, 0x2005, 0x200a, 0x2008, 0x2001, 0x0018,
+	0x080c, 0xaad1, 0x2009, 0x0390, 0x200b, 0x0400, 0x000e, 0x2009,
+	0x19b4, 0x9080, 0x27e2, 0x2005, 0x200a, 0x6808, 0x908a, 0x0100,
+	0x0a04, 0x36bd, 0x908a, 0x0841, 0x1a04, 0x36bd, 0x9084, 0x0007,
+	0x1904, 0x36bd, 0x680c, 0x9005, 0x0904, 0x36bd, 0x6810, 0x9005,
+	0x0904, 0x36bd, 0x6848, 0x6940, 0x910a, 0x1a04, 0x36bd, 0x8001,
+	0x0904, 0x36bd, 0x684c, 0x6944, 0x910a, 0x1a04, 0x36bd, 0x8001,
+	0x0904, 0x36bd, 0x6814, 0x908c, 0x00ff, 0x614e, 0x8007, 0x9084,
+	0x00ff, 0x6052, 0x080c, 0x79d8, 0x080c, 0x6c0b, 0x080c, 0x6c6d,
+	0x6808, 0x602a, 0x080c, 0x21b3, 0x2009, 0x0170, 0x200b, 0x0080,
+	0xa001, 0xa001, 0x200b, 0x0000, 0x0036, 0x6b08, 0x080c, 0x2745,
+	0x003e, 0x6000, 0x9086, 0x0000, 0x1904, 0x452a, 0x6818, 0x691c,
+	0x6a20, 0x6b24, 0x8007, 0x810f, 0x8217, 0x831f, 0x6016, 0x611a,
+	0x621e, 0x6322, 0x6c04, 0xd4f4, 0x0148, 0x6830, 0x6934, 0x6a38,
+	0x6b3c, 0x8007, 0x810f, 0x8217, 0x831f, 0x0010, 0x9084, 0xf0ff,
+	0x6006, 0x610a, 0x620e, 0x6312, 0x8007, 0x810f, 0x8217, 0x831f,
+	0x20a9, 0x0004, 0x20a1, 0x19b5, 0x20e9, 0x0001, 0x4001, 0x20a9,
+	0x0004, 0x20a1, 0x19cf, 0x20e9, 0x0001, 0x4001, 0x080c, 0x89c7,
+	0x00c6, 0x900e, 0x20a9, 0x0001, 0x6b70, 0xd384, 0x01c8, 0x0020,
+	0x839d, 0x12b0, 0x3508, 0x8109, 0x080c, 0x7f9f, 0x6878, 0x6016,
+	0x6874, 0x2008, 0x9084, 0xff00, 0x8007, 0x600a, 0x9184, 0x00ff,
+	0x6006, 0x8108, 0x1118, 0x6003, 0x0003, 0x0010, 0x6003, 0x0001,
+	0x1f04, 0x4488, 0x00ce, 0x00c6, 0x2061, 0x199d, 0x6a88, 0x9284,
+	0xc000, 0x2010, 0x9286, 0x0000, 0x1158, 0x2063, 0x0000, 0x2001,
+	0x0001, 0x080c, 0x29ec, 0x2001, 0x0001, 0x080c, 0x29cf, 0x0088,
+	0x9286, 0x4000, 0x1148, 0x2063, 0x0001, 0x9006, 0x080c, 0x29ec,
+	0x9006, 0x080c, 0x29cf, 0x0028, 0x9286, 0x8000, 0x1d30, 0x2063,
+	0x0002, 0x00ce, 0x00e6, 0x2c70, 0x080c, 0x0ed3, 0x00ee, 0x6888,
+	0xd0ec, 0x0130, 0x2011, 0x0114, 0x2204, 0x9085, 0x0180, 0x2012,
+	0x6a80, 0x9284, 0x0030, 0x9086, 0x0030, 0x1128, 0x9294, 0xffcf,
+	0x9295, 0x0020, 0x6a82, 0x2001, 0x197d, 0x6a80, 0x9294, 0x0030,
+	0x928e, 0x0000, 0x0170, 0x928e, 0x0010, 0x0118, 0x928e, 0x0020,
+	0x0140, 0x2003, 0xaaaa, 0x080c, 0x27ba, 0x2001, 0x196e, 0x2102,
+	0x0008, 0x2102, 0x00c6, 0x2061, 0x0100, 0x602f, 0x0040, 0x602f,
+	0x0000, 0x00ce, 0x080c, 0x76a5, 0x0128, 0x080c, 0x510e, 0x0110,
+	0x080c, 0x270b, 0x60d4, 0x9005, 0x01c0, 0x6003, 0x0001, 0x2009,
+	0x4512, 0x00e0, 0x080c, 0x76a5, 0x1168, 0x2011, 0x7519, 0x080c,
+	0x8834, 0x2011, 0x750c, 0x080c, 0x8940, 0x080c, 0x79ac, 0x080c,
+	0x75d4, 0x0040, 0x080c, 0x6039, 0x0028, 0x6003, 0x0004, 0x2009,
+	0x452a, 0x0020, 0x080c, 0x6b37, 0x0804, 0x3688, 0x2001, 0x0170,
+	0x2004, 0x9084, 0x00ff, 0x9086, 0x004c, 0x1118, 0x2091, 0x31bd,
+	0x0817, 0x2091, 0x313d, 0x0817, 0x6000, 0x9086, 0x0000, 0x0904,
+	0x36ba, 0x2069, 0x1847, 0x7890, 0x6842, 0x7894, 0x6846, 0x2d00,
+	0x2009, 0x0030, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x2039, 0x0001,
+	0x0804, 0x4c1a, 0x9006, 0x080c, 0x270b, 0x81ff, 0x1904, 0x36ba,
+	0x080c, 0x76a5, 0x11b0, 0x080c, 0x79a7, 0x080c, 0x617e, 0x080c,
+	0x347d, 0x0118, 0x6130, 0xc18d, 0x6132, 0x080c, 0xd33e, 0x0130,
+	0x080c, 0x76c8, 0x1118, 0x080c, 0x7679, 0x0038, 0x080c, 0x75d4,
+	0x0020, 0x080c, 0x6143, 0x080c, 0x6039, 0x0804, 0x3688, 0x81ff,
+	0x1904, 0x36ba, 0x080c, 0x76a5, 0x1110, 0x0804, 0x36ba, 0x0126,
+	0x2091, 0x8000, 0x6194, 0x81ff, 0x0190, 0x704f, 0x0000, 0x2001,
+	0x1d80, 0x2009, 0x0040, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x2039,
+	0x0001, 0x080c, 0x4c1a, 0x701f, 0x3686, 0x012e, 0x0005, 0x704f,
+	0x0001, 0x00d6, 0x2069, 0x1d80, 0x20a9, 0x0040, 0x20e9, 0x0001,
+	0x20a1, 0x1d80, 0x2019, 0xffff, 0x4304, 0x655c, 0x9588, 0x3489,
+	0x210d, 0x918c, 0x00ff, 0x216a, 0x900e, 0x2011, 0x0002, 0x2100,
+	0x9506, 0x01a8, 0x080c, 0x6789, 0x1190, 0xb814, 0x821c, 0x0238,
+	0x9398, 0x1d80, 0x9085, 0xff00, 0x8007, 0x201a, 0x0038, 0x9398,
+	0x1d80, 0x2324, 0x94a4, 0xff00, 0x9405, 0x201a, 0x8210, 0x8108,
+	0x9182, 0x0080, 0x1208, 0x0c18, 0x8201, 0x8007, 0x2d0c, 0x9105,
+	0x206a, 0x00de, 0x20a9, 0x0040, 0x20a1, 0x1d80, 0x2099, 0x1d80,
+	0x080c, 0x60ce, 0x0804, 0x4587, 0x080c, 0x4c01, 0x0904, 0x36bd,
+	0x080c, 0x4bce, 0x1120, 0x2009, 0x0002, 0x0804, 0x36ba, 0x080c,
+	0x5826, 0xd0b4, 0x0558, 0x7884, 0x908e, 0x007e, 0x0538, 0x908e,
+	0x007f, 0x0520, 0x908e, 0x0080, 0x0508, 0x080c, 0x3478, 0x1148,
+	0xb800, 0xd08c, 0x11d8, 0xb804, 0x9084, 0x00ff, 0x9086, 0x0006,
+	0x11a8, 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x080c, 0xcde7,
+	0x1120, 0x2009, 0x0003, 0x0804, 0x36ba, 0x7007, 0x0003, 0x701f,
+	0x4612, 0x0005, 0x080c, 0x4c01, 0x0904, 0x36bd, 0x20a9, 0x002b,
+	0xb8c4, 0x20e0, 0xb8c8, 0x2098, 0xa860, 0x20e8, 0xa85c, 0x9080,
+	0x0002, 0x20a0, 0x4003, 0x20a9, 0x0008, 0x9080, 0x0006, 0x20a0,
+	0xb8c4, 0x20e0, 0xb8c8, 0x9080, 0x0006, 0x2098, 0x080c, 0x0fd6,
+	0x0070, 0x20a9, 0x0004, 0xa85c, 0x9080, 0x000a, 0x20a0, 0xb8c4,
+	0x20e0, 0xb8c8, 0x9080, 0x000a, 0x2098, 0x080c, 0x0fd6, 0x8906,
+	0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x0002,
+	0x2009, 0x002b, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x0804, 0x4c1a,
+	0x81ff, 0x1904, 0x36ba, 0x080c, 0x4be5, 0x0904, 0x36bd, 0x080c,
+	0x69ce, 0x0904, 0x36ba, 0x0058, 0xa878, 0x9005, 0x0120, 0x2009,
+	0x0004, 0x0804, 0x36ba, 0xa974, 0xaa94, 0x0804, 0x3688, 0x080c,
+	0x582e, 0x0904, 0x3688, 0x701f, 0x465c, 0x7007, 0x0003, 0x0005,
+	0x81ff, 0x1904, 0x36ba, 0x7888, 0x908a, 0x1000, 0x1a04, 0x36bd,
+	0x080c, 0x4c01, 0x0904, 0x36bd, 0x080c, 0x6bd5, 0x0120, 0x080c,
+	0x6bdd, 0x1904, 0x36bd, 0x080c, 0x6a53, 0x0904, 0x36ba, 0x2019,
+	0x0004, 0x900e, 0x080c, 0x69e0, 0x0904, 0x36ba, 0x7984, 0x7a88,
+	0x04c9, 0x08a8, 0xa89c, 0x908a, 0x1000, 0x12f8, 0x080c, 0x4bff,
+	0x01e0, 0x080c, 0x6bd5, 0x0118, 0x080c, 0x6bdd, 0x11b0, 0x080c,
+	0x6a53, 0x2009, 0x0002, 0x0168, 0x2009, 0x0002, 0x2019, 0x0004,
+	0x080c, 0x69e0, 0x2009, 0x0003, 0x0120, 0xa998, 0xaa9c, 0x00d1,
+	0x0060, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e,
+	0x9085, 0x0001, 0x2001, 0x0030, 0x0005, 0xa897, 0x4000, 0x080c,
+	0x582e, 0x0110, 0x9006, 0x0018, 0x900e, 0x9085, 0x0001, 0x2001,
+	0x0000, 0x0005, 0x9186, 0x00ff, 0x0110, 0x0071, 0x0060, 0x2029,
+	0x007e, 0x2061, 0x1800, 0x645c, 0x2400, 0x9506, 0x0110, 0x2508,
+	0x0019, 0x8529, 0x1ec8, 0x0005, 0x080c, 0x6789, 0x1138, 0x2200,
+	0x8003, 0x800b, 0x810b, 0x9108, 0x080c, 0x8842, 0x0005, 0x81ff,
+	0x1904, 0x36ba, 0x798c, 0x2001, 0x1981, 0x918c, 0x8000, 0x2102,
+	0x080c, 0x4be5, 0x0904, 0x36bd, 0x080c, 0x6bd5, 0x0120, 0x080c,
+	0x6bdd, 0x1904, 0x36bd, 0x080c, 0x6850, 0x0904, 0x36ba, 0x080c,
+	0x69d7, 0x0904, 0x36ba, 0x2001, 0x1981, 0x2004, 0xd0fc, 0x1904,
+	0x3688, 0x0804, 0x4667, 0xa9a0, 0x2001, 0x1981, 0x918c, 0x8000,
+	0xc18d, 0x2102, 0x080c, 0x4bf2, 0x01a0, 0x080c, 0x6bd5, 0x0118,
+	0x080c, 0x6bdd, 0x1170, 0x080c, 0x6850, 0x2009, 0x0002, 0x0128,
+	0x080c, 0x69d7, 0x1170, 0x2009, 0x0003, 0xa897, 0x4005, 0xa99a,
+	0x0010, 0xa897, 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030,
+	0x0005, 0xa897, 0x4000, 0x2001, 0x1981, 0x2004, 0xd0fc, 0x1128,
+	0x080c, 0x582e, 0x0110, 0x9006, 0x0018, 0x900e, 0x9085, 0x0001,
+	0x2001, 0x0000, 0x0005, 0x81ff, 0x1904, 0x36ba, 0x798c, 0x2001,
+	0x1980, 0x918c, 0x8000, 0x2102, 0x080c, 0x4be5, 0x0904, 0x36bd,
+	0x080c, 0x6bd5, 0x0120, 0x080c, 0x6bdd, 0x1904, 0x36bd, 0x080c,
+	0x6850, 0x0904, 0x36ba, 0x080c, 0x69c5, 0x0904, 0x36ba, 0x2001,
+	0x1980, 0x2004, 0xd0fc, 0x1904, 0x3688, 0x0804, 0x4667, 0xa9a0,
+	0x2001, 0x1980, 0x918c, 0x8000, 0xc18d, 0x2102, 0x080c, 0x4bf2,
+	0x01a0, 0x080c, 0x6bd5, 0x0118, 0x080c, 0x6bdd, 0x1170, 0x080c,
+	0x6850, 0x2009, 0x0002, 0x0128, 0x080c, 0x69c5, 0x1170, 0x2009,
+	0x0003, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e,
+	0x9085, 0x0001, 0x2001, 0x0030, 0x0005, 0xa897, 0x4000, 0x2001,
+	0x1980, 0x2004, 0xd0fc, 0x1128, 0x080c, 0x582e, 0x0110, 0x9006,
+	0x0018, 0x900e, 0x9085, 0x0001, 0x2001, 0x0000, 0x0005, 0x6100,
+	0x0804, 0x3688, 0x080c, 0x4c01, 0x0904, 0x36bd, 0x080c, 0x583a,
+	0x1904, 0x36ba, 0x79a8, 0xd184, 0x1158, 0xb834, 0x8007, 0x789e,
+	0xb830, 0x8007, 0x789a, 0xbb2c, 0x831f, 0xba28, 0x8217, 0x0050,
+	0xb824, 0x8007, 0x789e, 0xb820, 0x8007, 0x789a, 0xbb1c, 0x831f,
+	0xba18, 0x8217, 0xb900, 0x918c, 0x0202, 0x0804, 0x3688, 0x78a8,
+	0x909c, 0x0003, 0xd0ac, 0x1150, 0xd0b4, 0x1140, 0x939a, 0x0003,
+	0x1a04, 0x36ba, 0x625c, 0x7884, 0x9206, 0x1548, 0x080c, 0x89b1,
+	0x2001, 0xffec, 0x2009, 0x000c, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98,
+	0x2039, 0x0000, 0x0006, 0x78a8, 0x9084, 0x0080, 0x1118, 0x000e,
+	0x0804, 0x4c1a, 0x000e, 0x2031, 0x0000, 0x2061, 0x18b8, 0x2c44,
+	0xa66a, 0xa17a, 0xa772, 0xa076, 0xa28e, 0xa392, 0xa496, 0xa59a,
+	0x080c, 0x114e, 0x7007, 0x0002, 0x701f, 0x481f, 0x0005, 0x81ff,
+	0x1904, 0x36ba, 0x080c, 0x4c01, 0x0904, 0x36bd, 0x080c, 0x6bd5,
+	0x1904, 0x36ba, 0x00c6, 0x080c, 0x4bce, 0x00ce, 0x0904, 0x36ba,
+	0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x7ea8, 0x080c, 0xcd8d,
+	0x0904, 0x36ba, 0x7007, 0x0003, 0x701f, 0x4823, 0x0005, 0x080c,
+	0x4365, 0x0804, 0x3688, 0xa830, 0x9086, 0x0100, 0x0904, 0x36ba,
+	0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080,
+	0x001b, 0x2009, 0x000c, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x0804,
+	0x4c1a, 0x9006, 0x080c, 0x270b, 0x78a8, 0x9084, 0x00ff, 0x9086,
+	0x00ff, 0x0118, 0x81ff, 0x1904, 0x36ba, 0x080c, 0x76a5, 0x0110,
+	0x080c, 0x6143, 0x7888, 0x908a, 0x1000, 0x1a04, 0x36bd, 0x7984,
+	0x9186, 0x00ff, 0x0138, 0x9182, 0x007f, 0x1a04, 0x36bd, 0x2100,
+	0x080c, 0x26d5, 0x0026, 0x00c6, 0x0126, 0x2091, 0x8000, 0x2061,
+	0x1a05, 0x601b, 0x0000, 0x601f, 0x0000, 0x607b, 0x0000, 0x607f,
+	0x0000, 0x080c, 0x76a5, 0x1158, 0x080c, 0x79a7, 0x080c, 0x617e,
+	0x9085, 0x0001, 0x080c, 0x76e9, 0x080c, 0x75d4, 0x00f0, 0x080c,
+	0xaae0, 0x080c, 0xae67, 0x080c, 0xaafc, 0x2061, 0x0100, 0x2001,
+	0x1818, 0x2004, 0x9084, 0x00ff, 0x810f, 0x9105, 0x604a, 0x6043,
+	0x0090, 0x6043, 0x0010, 0x2009, 0x199a, 0x200b, 0x0000, 0x2009,
+	0x002d, 0x2011, 0x6069, 0x080c, 0x88fe, 0x7984, 0x080c, 0x76a5,
+	0x1110, 0x2009, 0x00ff, 0x7a88, 0x080c, 0x46ca, 0x012e, 0x00ce,
+	0x002e, 0x0804, 0x3688, 0x7984, 0x080c, 0x671e, 0x2b08, 0x1904,
+	0x36bd, 0x0804, 0x3688, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804,
+	0x36ba, 0x60dc, 0xd0ac, 0x1130, 0xd09c, 0x1120, 0x2009, 0x0005,
+	0x0804, 0x36ba, 0x080c, 0x4bce, 0x1120, 0x2009, 0x0002, 0x0804,
+	0x36ba, 0x7984, 0x81ff, 0x0904, 0x36bd, 0x9192, 0x0021, 0x1a04,
+	0x36bd, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0xa85c, 0x9080, 0x0019,
+	0x702a, 0xaf60, 0x7736, 0x080c, 0x4c17, 0x701f, 0x48de, 0x7880,
+	0x9086, 0x006e, 0x0110, 0x701f, 0x52c0, 0x0005, 0x2009, 0x0080,
+	0x080c, 0x6789, 0x1118, 0x080c, 0x6bd5, 0x0120, 0x2021, 0x400a,
+	0x0804, 0x368a, 0x00d6, 0x0096, 0xa964, 0xaa6c, 0xab70, 0xac74,
+	0xad78, 0xae7c, 0xa884, 0x90be, 0x0100, 0x0904, 0x4977, 0x90be,
+	0x0112, 0x0904, 0x4977, 0x90be, 0x0113, 0x0904, 0x4977, 0x90be,
+	0x0114, 0x0904, 0x4977, 0x90be, 0x0117, 0x0904, 0x4977, 0x90be,
+	0x011a, 0x0904, 0x4977, 0x90be, 0x011c, 0x0904, 0x4977, 0x90be,
+	0x0121, 0x0904, 0x495e, 0x90be, 0x0131, 0x0904, 0x495e, 0x90be,
+	0x0171, 0x0904, 0x4977, 0x90be, 0x0173, 0x0904, 0x4977, 0x90be,
+	0x01a1, 0x1128, 0xa894, 0x8007, 0xa896, 0x0804, 0x4982, 0x90be,
+	0x0212, 0x0904, 0x496b, 0x90be, 0x0213, 0x05e8, 0x90be, 0x0214,
+	0x0500, 0x90be, 0x0217, 0x0188, 0x90be, 0x021a, 0x1120, 0xa89c,
+	0x8007, 0xa89e, 0x04e0, 0x90be, 0x021f, 0x05c8, 0x90be, 0x0300,
+	0x05b0, 0x009e, 0x00de, 0x0804, 0x36bd, 0x7028, 0x9080, 0x0010,
+	0x2098, 0x20a0, 0x7034, 0x20e0, 0x20e8, 0x20a9, 0x0007, 0x080c,
+	0x49c0, 0x7028, 0x9080, 0x000e, 0x2098, 0x20a0, 0x7034, 0x20e0,
+	0x20e8, 0x20a9, 0x0001, 0x080c, 0x49c0, 0x00c8, 0x7028, 0x9080,
+	0x000c, 0x2098, 0x20a0, 0x7034, 0x20e0, 0x20e8, 0x20a9, 0x0001,
+	0x080c, 0x49cd, 0x00b8, 0x7028, 0x9080, 0x000e, 0x2098, 0x20a0,
+	0x7034, 0x20e0, 0x20e8, 0x20a9, 0x0001, 0x080c, 0x49cd, 0x7028,
+	0x9080, 0x000c, 0x2098, 0x20a0, 0x7034, 0x20e0, 0x20e8, 0x20a9,
+	0x0001, 0x04f1, 0x00c6, 0x080c, 0x4bce, 0x0550, 0xa868, 0xc0fd,
+	0xa86a, 0xa867, 0x0119, 0x9006, 0xa882, 0xa87f, 0x0020, 0xa88b,
+	0x0001, 0x810b, 0xa9ae, 0xa8b2, 0xaab6, 0xabba, 0xacbe, 0xadc2,
+	0xa9c6, 0xa8ca, 0x00ce, 0x009e, 0x00de, 0xa866, 0xa822, 0xa868,
+	0xc0fd, 0xa86a, 0xa804, 0x2048, 0x080c, 0xcda8, 0x1120, 0x2009,
+	0x0003, 0x0804, 0x36ba, 0x7007, 0x0003, 0x701f, 0x49b7, 0x0005,
+	0x00ce, 0x009e, 0x00de, 0x2009, 0x0002, 0x0804, 0x36ba, 0xa820,
+	0x9086, 0x8001, 0x1904, 0x3688, 0x2009, 0x0004, 0x0804, 0x36ba,
+	0x0016, 0x0026, 0x3510, 0x20a9, 0x0002, 0x4002, 0x4104, 0x4004,
+	0x8211, 0x1dc8, 0x002e, 0x001e, 0x0005, 0x0016, 0x0026, 0x0036,
+	0x0046, 0x3520, 0x20a9, 0x0004, 0x4002, 0x4304, 0x4204, 0x4104,
+	0x4004, 0x8421, 0x1db8, 0x004e, 0x003e, 0x002e, 0x001e, 0x0005,
+	0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x36ba, 0x60dc, 0xd0ac,
+	0x1130, 0xd09c, 0x1120, 0x2009, 0x0005, 0x0804, 0x36ba, 0x7984,
+	0x78a8, 0x2040, 0x080c, 0xae60, 0x1120, 0x9182, 0x007f, 0x0a04,
+	0x36bd, 0x9186, 0x00ff, 0x0904, 0x36bd, 0x9182, 0x0800, 0x1a04,
+	0x36bd, 0x7a8c, 0x7b88, 0x607c, 0x9306, 0x1158, 0x6080, 0x924e,
+	0x0904, 0x36bd, 0x080c, 0xae60, 0x1120, 0x99cc, 0xff00, 0x0904,
+	0x36bd, 0x0126, 0x2091, 0x8000, 0x080c, 0x4ae1, 0x0904, 0x4a61,
+	0x0086, 0x90c6, 0x4000, 0x008e, 0x1538, 0x00c6, 0x0006, 0x0036,
+	0xb818, 0xbb1c, 0x9305, 0xbb20, 0x9305, 0xbb24, 0x9305, 0xbb28,
+	0x9305, 0xbb2c, 0x9305, 0xbb30, 0x9305, 0xbb34, 0x9305, 0x003e,
+	0x0570, 0xd88c, 0x1128, 0x080c, 0x6bd5, 0x0110, 0xc89d, 0x0438,
+	0x900e, 0x080c, 0x6a7c, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108,
+	0xc18d, 0x000e, 0x00ce, 0x00b8, 0x90c6, 0x4007, 0x1110, 0x2408,
+	0x0090, 0x90c6, 0x4008, 0x1118, 0x2708, 0x2610, 0x0060, 0x90c6,
+	0x4009, 0x1108, 0x0040, 0x90c6, 0x4006, 0x1108, 0x0020, 0x2001,
+	0x4005, 0x2009, 0x000a, 0x2020, 0x012e, 0x0804, 0x368a, 0x000e,
+	0x00ce, 0x2b00, 0x7026, 0x0016, 0x00b6, 0x00c6, 0x00e6, 0x2c70,
+	0x080c, 0xaf9f, 0x0904, 0x4ab6, 0x2b00, 0x6012, 0x080c, 0xd0b1,
+	0x2e58, 0x00ee, 0x00e6, 0x00c6, 0x080c, 0x4bce, 0x00ce, 0x2b70,
+	0x1158, 0x080c, 0xaf2e, 0x00ee, 0x00ce, 0x00be, 0x001e, 0x012e,
+	0x2009, 0x0002, 0x0804, 0x36ba, 0x900e, 0xa966, 0xa96a, 0x2900,
+	0x6016, 0xa932, 0xa868, 0xc0fd, 0xd88c, 0x0108, 0xc0f5, 0xa86a,
+	0xd89c, 0x1110, 0x080c, 0x3310, 0x6023, 0x0001, 0x9006, 0x080c,
+	0x66bb, 0xd89c, 0x0138, 0x2001, 0x0004, 0x080c, 0x66cf, 0x2009,
+	0x0003, 0x0030, 0x2001, 0x0002, 0x080c, 0x66cf, 0x2009, 0x0002,
+	0x080c, 0xafcc, 0x78a8, 0xd094, 0x0138, 0x00ee, 0x7024, 0x00e6,
+	0x2058, 0xb8d4, 0xc08d, 0xb8d6, 0x9085, 0x0001, 0x00ee, 0x00ce,
+	0x00be, 0x001e, 0x012e, 0x1120, 0x2009, 0x0003, 0x0804, 0x36ba,
+	0x7007, 0x0003, 0x701f, 0x4ac5, 0x0005, 0xa830, 0x9086, 0x0100,
+	0x7024, 0x2058, 0x1138, 0x2009, 0x0004, 0xba04, 0x9294, 0x00ff,
+	0x0804, 0x5774, 0x900e, 0xa868, 0xd0f4, 0x1904, 0x3688, 0x080c,
+	0x6a7c, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x0804,
+	0x3688, 0x00e6, 0x00d6, 0x0096, 0x83ff, 0x0904, 0x4b30, 0x902e,
+	0x080c, 0xae60, 0x0130, 0x9026, 0x20a9, 0x0800, 0x2071, 0x1000,
+	0x0030, 0x2021, 0x007f, 0x20a9, 0x0781, 0x2071, 0x107f, 0x2e04,
+	0x9005, 0x11b8, 0x2100, 0x9406, 0x1904, 0x4b41, 0x2428, 0x94ce,
+	0x007f, 0x1120, 0x92ce, 0xfffd, 0x1558, 0x0030, 0x94ce, 0x0080,
+	0x1130, 0x92ce, 0xfffc, 0x1520, 0x93ce, 0x00ff, 0x1508, 0xc5fd,
+	0x0480, 0x2058, 0xbf10, 0x2700, 0x9306, 0x11e8, 0xbe14, 0x2600,
+	0x9206, 0x11c8, 0x2400, 0x9106, 0x1180, 0xd884, 0x0598, 0xd894,
+	0x1588, 0x080c, 0x6b75, 0x1570, 0x2001, 0x4000, 0x0460, 0x080c,
+	0x6bd5, 0x1540, 0x2001, 0x4000, 0x0430, 0x2001, 0x4007, 0x0418,
+	0x2001, 0x4006, 0x0400, 0x2400, 0x9106, 0x1158, 0xbe14, 0x87ff,
+	0x1128, 0x86ff, 0x0918, 0x080c, 0xae60, 0x1900, 0x2001, 0x4008,
+	0x0090, 0x8420, 0x8e70, 0x1f04, 0x4af7, 0x85ff, 0x1130, 0x2001,
+	0x4009, 0x0048, 0x2001, 0x0001, 0x0030, 0x080c, 0x671e, 0x1dd0,
+	0xbb12, 0xba16, 0x9006, 0x9005, 0x009e, 0x00de, 0x00ee, 0x0005,
+	0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x36ba, 0x080c, 0x4bce,
+	0x1120, 0x2009, 0x0002, 0x0804, 0x36ba, 0xa867, 0x0000, 0xa868,
+	0xc0fd, 0xa86a, 0x7884, 0x9005, 0x0904, 0x36bd, 0x9096, 0x00ff,
+	0x0120, 0x9092, 0x0004, 0x1a04, 0x36bd, 0x2010, 0x2918, 0x080c,
+	0x32b0, 0x1120, 0x2009, 0x0003, 0x0804, 0x36ba, 0x7007, 0x0003,
+	0x701f, 0x4b83, 0x0005, 0xa830, 0x9086, 0x0100, 0x1904, 0x3688,
+	0x2009, 0x0004, 0x0804, 0x36ba, 0x7984, 0x080c, 0xae60, 0x1120,
+	0x9182, 0x007f, 0x0a04, 0x36bd, 0x9186, 0x00ff, 0x0904, 0x36bd,
+	0x9182, 0x0800, 0x1a04, 0x36bd, 0x2001, 0x9400, 0x080c, 0x57cf,
+	0x1904, 0x36ba, 0x0804, 0x3688, 0xa998, 0x080c, 0xae60, 0x1118,
+	0x9182, 0x007f, 0x0280, 0x9186, 0x00ff, 0x0168, 0x9182, 0x0800,
+	0x1250, 0x2001, 0x9400, 0x080c, 0x57cf, 0x11a8, 0x0060, 0xa897,
+	0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e, 0x9085, 0x0001,
+	0x2001, 0x0030, 0x0005, 0xa897, 0x4000, 0x900e, 0x9085, 0x0001,
+	0x2001, 0x0000, 0x0005, 0x2009, 0x000a, 0x0c48, 0x080c, 0x1059,
+	0x0198, 0x9006, 0xa802, 0x7014, 0x9005, 0x1120, 0x2900, 0x7016,
+	0x701a, 0x0040, 0x7018, 0xa802, 0x0086, 0x2040, 0x2900, 0xa006,
+	0x701a, 0x008e, 0x9085, 0x0001, 0x0005, 0x7984, 0x080c, 0x6789,
+	0x1130, 0x7e88, 0x9684, 0x3fff, 0x9082, 0x4000, 0x0208, 0x905e,
+	0x8bff, 0x0005, 0xa998, 0x080c, 0x6789, 0x1130, 0xae9c, 0x9684,
+	0x3fff, 0x9082, 0x4000, 0x0208, 0x905e, 0x8bff, 0x0005, 0xae98,
+	0x0008, 0x7e84, 0x2608, 0x080c, 0x6789, 0x1108, 0x0008, 0x905e,
+	0x8bff, 0x0005, 0x0016, 0x7114, 0x81ff, 0x0128, 0x2148, 0xa904,
+	0x080c, 0x108b, 0x0cc8, 0x7116, 0x711a, 0x001e, 0x0005, 0x2031,
+	0x0001, 0x0010, 0x2031, 0x0000, 0x2061, 0x18b8, 0x2c44, 0xa66a,
 	0xa17a, 0xa772, 0xa076, 0xa28e, 0xa392, 0xa496, 0xa59a, 0x080c,
-	0x113c, 0x7007, 0x0002, 0x701f, 0x4746, 0x0005, 0x81ff, 0x1904,
-	0x35ea, 0x080c, 0x4b25, 0x0904, 0x35ed, 0x080c, 0x6add, 0x1904,
-	0x35ea, 0x00c6, 0x080c, 0x4af2, 0x00ce, 0x0904, 0x35ea, 0xa867,
-	0x0000, 0xa868, 0xc0fd, 0xa86a, 0x7ea8, 0x080c, 0xcaf1, 0x0904,
-	0x35ea, 0x7007, 0x0003, 0x701f, 0x474a, 0x0005, 0x080c, 0x428c,
-	0x0804, 0x35b8, 0xa830, 0x9086, 0x0100, 0x0904, 0x35ea, 0x8906,
-	0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x001b,
-	0x2009, 0x000c, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x0804, 0x4b3e,
-	0x9006, 0x080c, 0x26ca, 0x78a8, 0x9084, 0x00ff, 0x9086, 0x00ff,
-	0x0118, 0x81ff, 0x1904, 0x35ea, 0x080c, 0x753d, 0x0110, 0x080c,
-	0x6057, 0x7888, 0x908a, 0x1000, 0x1a04, 0x35ed, 0x7984, 0x9186,
-	0x00ff, 0x0138, 0x9182, 0x007f, 0x1a04, 0x35ed, 0x2100, 0x080c,
-	0x2694, 0x0026, 0x00c6, 0x0126, 0x2091, 0x8000, 0x2061, 0x1a02,
-	0x601b, 0x0000, 0x601f, 0x0000, 0x6073, 0x0000, 0x6077, 0x0000,
-	0x080c, 0x753d, 0x1158, 0x080c, 0x7840, 0x080c, 0x6092, 0x9085,
-	0x0001, 0x080c, 0x7584, 0x080c, 0x746e, 0x00f0, 0x080c, 0xa91e,
-	0x080c, 0xabe9, 0x080c, 0xa93a, 0x2061, 0x0100, 0x2001, 0x1818,
-	0x2004, 0x9084, 0x00ff, 0x810f, 0x9105, 0x604a, 0x6043, 0x0090,
-	0x6043, 0x0010, 0x2009, 0x1998, 0x200b, 0x0000, 0x2009, 0x002d,
-	0x2011, 0x5f7d, 0x080c, 0x8792, 0x7984, 0x080c, 0x753d, 0x1110,
-	0x2009, 0x00ff, 0x7a88, 0x080c, 0x45f1, 0x012e, 0x00ce, 0x002e,
-	0x0804, 0x35b8, 0x7984, 0x080c, 0x6632, 0x2b08, 0x1904, 0x35ed,
-	0x0804, 0x35b8, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x35ea,
-	0x60dc, 0xd0ac, 0x1130, 0xd09c, 0x1120, 0x2009, 0x0005, 0x0804,
-	0x35ea, 0x080c, 0x4af2, 0x1120, 0x2009, 0x0002, 0x0804, 0x35ea,
-	0x7984, 0x9192, 0x0021, 0x1a04, 0x35ed, 0x7a8c, 0x7b88, 0x7c9c,
-	0x7d98, 0xa85c, 0x9080, 0x0019, 0x702a, 0xaf60, 0x7736, 0x080c,
-	0x4b3b, 0x701f, 0x4802, 0x7880, 0x9086, 0x006e, 0x0110, 0x701f,
-	0x51d9, 0x0005, 0x2009, 0x0080, 0x080c, 0x6693, 0x1118, 0x080c,
-	0x6add, 0x0120, 0x2021, 0x400a, 0x0804, 0x35ba, 0x00d6, 0x0096,
-	0xa964, 0xaa6c, 0xab70, 0xac74, 0xad78, 0xae7c, 0xa884, 0x90be,
-	0x0100, 0x0904, 0x489b, 0x90be, 0x0112, 0x0904, 0x489b, 0x90be,
-	0x0113, 0x0904, 0x489b, 0x90be, 0x0114, 0x0904, 0x489b, 0x90be,
-	0x0117, 0x0904, 0x489b, 0x90be, 0x011a, 0x0904, 0x489b, 0x90be,
-	0x011c, 0x0904, 0x489b, 0x90be, 0x0121, 0x0904, 0x4882, 0x90be,
-	0x0131, 0x0904, 0x4882, 0x90be, 0x0171, 0x0904, 0x489b, 0x90be,
-	0x0173, 0x0904, 0x489b, 0x90be, 0x01a1, 0x1128, 0xa894, 0x8007,
-	0xa896, 0x0804, 0x48a6, 0x90be, 0x0212, 0x0904, 0x488f, 0x90be,
-	0x0213, 0x05e8, 0x90be, 0x0214, 0x0500, 0x90be, 0x0217, 0x0188,
-	0x90be, 0x021a, 0x1120, 0xa89c, 0x8007, 0xa89e, 0x04e0, 0x90be,
-	0x021f, 0x05c8, 0x90be, 0x0300, 0x05b0, 0x009e, 0x00de, 0x0804,
-	0x35ed, 0x7028, 0x9080, 0x0010, 0x2098, 0x20a0, 0x7034, 0x20e0,
-	0x20e8, 0x20a9, 0x0007, 0x080c, 0x48e4, 0x7028, 0x9080, 0x000e,
-	0x2098, 0x20a0, 0x7034, 0x20e0, 0x20e8, 0x20a9, 0x0001, 0x080c,
-	0x48e4, 0x00c8, 0x7028, 0x9080, 0x000c, 0x2098, 0x20a0, 0x7034,
-	0x20e0, 0x20e8, 0x20a9, 0x0001, 0x080c, 0x48f1, 0x00b8, 0x7028,
-	0x9080, 0x000e, 0x2098, 0x20a0, 0x7034, 0x20e0, 0x20e8, 0x20a9,
-	0x0001, 0x080c, 0x48f1, 0x7028, 0x9080, 0x000c, 0x2098, 0x20a0,
-	0x7034, 0x20e0, 0x20e8, 0x20a9, 0x0001, 0x04f1, 0x00c6, 0x080c,
-	0x4af2, 0x0550, 0xa868, 0xc0fd, 0xa86a, 0xa867, 0x0119, 0x9006,
-	0xa882, 0xa87f, 0x0020, 0xa88b, 0x0001, 0x810b, 0xa9ae, 0xa8b2,
-	0xaab6, 0xabba, 0xacbe, 0xadc2, 0xa9c6, 0xa8ca, 0x00ce, 0x009e,
-	0x00de, 0xa866, 0xa822, 0xa868, 0xc0fd, 0xa86a, 0xa804, 0x2048,
-	0x080c, 0xcb0c, 0x1120, 0x2009, 0x0003, 0x0804, 0x35ea, 0x7007,
-	0x0003, 0x701f, 0x48db, 0x0005, 0x00ce, 0x009e, 0x00de, 0x2009,
-	0x0002, 0x0804, 0x35ea, 0xa820, 0x9086, 0x8001, 0x1904, 0x35b8,
-	0x2009, 0x0004, 0x0804, 0x35ea, 0x0016, 0x0026, 0x3510, 0x20a9,
-	0x0002, 0x4002, 0x4104, 0x4004, 0x8211, 0x1dc8, 0x002e, 0x001e,
-	0x0005, 0x0016, 0x0026, 0x0036, 0x0046, 0x3520, 0x20a9, 0x0004,
-	0x4002, 0x4304, 0x4204, 0x4104, 0x4004, 0x8421, 0x1db8, 0x004e,
-	0x003e, 0x002e, 0x001e, 0x0005, 0x81ff, 0x0120, 0x2009, 0x0001,
-	0x0804, 0x35ea, 0x60dc, 0xd0ac, 0x1130, 0xd09c, 0x1120, 0x2009,
-	0x0005, 0x0804, 0x35ea, 0x7984, 0x78a8, 0x2040, 0x080c, 0xabe2,
-	0x1120, 0x9182, 0x007f, 0x0a04, 0x35ed, 0x9186, 0x00ff, 0x0904,
-	0x35ed, 0x9182, 0x0800, 0x1a04, 0x35ed, 0x7a8c, 0x7b88, 0x607c,
-	0x9306, 0x1158, 0x6080, 0x924e, 0x0904, 0x35ed, 0x080c, 0xabe2,
-	0x1120, 0x99cc, 0xff00, 0x0904, 0x35ed, 0x0126, 0x2091, 0x8000,
-	0x080c, 0x4a05, 0x0904, 0x4985, 0x0086, 0x90c6, 0x4000, 0x008e,
-	0x1538, 0x00c6, 0x0006, 0x0036, 0xb818, 0xbb1c, 0x9305, 0xbb20,
-	0x9305, 0xbb24, 0x9305, 0xbb28, 0x9305, 0xbb2c, 0x9305, 0xbb30,
-	0x9305, 0xbb34, 0x9305, 0x003e, 0x0570, 0xd88c, 0x1128, 0x080c,
-	0x6add, 0x0110, 0xc89d, 0x0438, 0x900e, 0x080c, 0x6986, 0x1108,
-	0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x000e, 0x00ce, 0x00b8,
-	0x90c6, 0x4007, 0x1110, 0x2408, 0x0090, 0x90c6, 0x4008, 0x1118,
-	0x2708, 0x2610, 0x0060, 0x90c6, 0x4009, 0x1108, 0x0040, 0x90c6,
-	0x4006, 0x1108, 0x0020, 0x2001, 0x4005, 0x2009, 0x000a, 0x2020,
-	0x012e, 0x0804, 0x35ba, 0x000e, 0x00ce, 0x2b00, 0x7026, 0x0016,
-	0x00b6, 0x00c6, 0x00e6, 0x2c70, 0x080c, 0xad20, 0x0904, 0x49da,
-	0x2b00, 0x6012, 0x080c, 0xce15, 0x2e58, 0x00ee, 0x00e6, 0x00c6,
-	0x080c, 0x4af2, 0x00ce, 0x2b70, 0x1158, 0x080c, 0xacb0, 0x00ee,
-	0x00ce, 0x00be, 0x001e, 0x012e, 0x2009, 0x0002, 0x0804, 0x35ea,
-	0x900e, 0xa966, 0xa96a, 0x2900, 0x6016, 0xa932, 0xa868, 0xc0fd,
-	0xd88c, 0x0108, 0xc0f5, 0xa86a, 0xd89c, 0x1110, 0x080c, 0x3240,
-	0x6023, 0x0001, 0x9006, 0x080c, 0x65cf, 0xd89c, 0x0138, 0x2001,
-	0x0004, 0x080c, 0x65e3, 0x2009, 0x0003, 0x0030, 0x2001, 0x0002,
-	0x080c, 0x65e3, 0x2009, 0x0002, 0x080c, 0xad4d, 0x78a8, 0xd094,
-	0x0138, 0x00ee, 0x7024, 0x00e6, 0x2058, 0xb8d4, 0xc08d, 0xb8d6,
-	0x9085, 0x0001, 0x00ee, 0x00ce, 0x00be, 0x001e, 0x012e, 0x1120,
-	0x2009, 0x0003, 0x0804, 0x35ea, 0x7007, 0x0003, 0x701f, 0x49e9,
-	0x0005, 0xa830, 0x9086, 0x0100, 0x7024, 0x2058, 0x1138, 0x2009,
-	0x0004, 0xba04, 0x9294, 0x00ff, 0x0804, 0x568c, 0x900e, 0xa868,
-	0xd0f4, 0x1904, 0x35b8, 0x080c, 0x6986, 0x1108, 0xc185, 0xb800,
-	0xd0bc, 0x0108, 0xc18d, 0x0804, 0x35b8, 0x00e6, 0x00d6, 0x0096,
-	0x83ff, 0x0904, 0x4a54, 0x902e, 0x080c, 0xabe2, 0x0130, 0x9026,
-	0x20a9, 0x0800, 0x2071, 0x1000, 0x0030, 0x2021, 0x007f, 0x20a9,
-	0x0781, 0x2071, 0x107f, 0x2e04, 0x9005, 0x11b8, 0x2100, 0x9406,
-	0x1904, 0x4a65, 0x2428, 0x94ce, 0x007f, 0x1120, 0x92ce, 0xfffd,
-	0x1558, 0x0030, 0x94ce, 0x0080, 0x1130, 0x92ce, 0xfffc, 0x1520,
-	0x93ce, 0x00ff, 0x1508, 0xc5fd, 0x0480, 0x2058, 0xbf10, 0x2700,
-	0x9306, 0x11e8, 0xbe14, 0x2600, 0x9206, 0x11c8, 0x2400, 0x9106,
-	0x1180, 0xd884, 0x0598, 0xd894, 0x1588, 0x080c, 0x6a7d, 0x1570,
-	0x2001, 0x4000, 0x0460, 0x080c, 0x6add, 0x1540, 0x2001, 0x4000,
-	0x0430, 0x2001, 0x4007, 0x0418, 0x2001, 0x4006, 0x0400, 0x2400,
-	0x9106, 0x1158, 0xbe14, 0x87ff, 0x1128, 0x86ff, 0x0918, 0x080c,
-	0xabe2, 0x1900, 0x2001, 0x4008, 0x0090, 0x8420, 0x8e70, 0x1f04,
-	0x4a1b, 0x85ff, 0x1130, 0x2001, 0x4009, 0x0048, 0x2001, 0x0001,
-	0x0030, 0x080c, 0x6632, 0x1dd0, 0xbb12, 0xba16, 0x9006, 0x9005,
-	0x009e, 0x00de, 0x00ee, 0x0005, 0x81ff, 0x0120, 0x2009, 0x0001,
-	0x0804, 0x35ea, 0x080c, 0x4af2, 0x1120, 0x2009, 0x0002, 0x0804,
-	0x35ea, 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x7884, 0x9005,
-	0x0904, 0x35ed, 0x9096, 0x00ff, 0x0120, 0x9092, 0x0004, 0x1a04,
-	0x35ed, 0x2010, 0x2918, 0x080c, 0x31e0, 0x1120, 0x2009, 0x0003,
-	0x0804, 0x35ea, 0x7007, 0x0003, 0x701f, 0x4aa7, 0x0005, 0xa830,
-	0x9086, 0x0100, 0x1904, 0x35b8, 0x2009, 0x0004, 0x0804, 0x35ea,
-	0x7984, 0x080c, 0xabe2, 0x1120, 0x9182, 0x007f, 0x0a04, 0x35ed,
-	0x9186, 0x00ff, 0x0904, 0x35ed, 0x9182, 0x0800, 0x1a04, 0x35ed,
-	0x2001, 0x9400, 0x080c, 0x56e7, 0x1904, 0x35ea, 0x0804, 0x35b8,
-	0xa998, 0x080c, 0xabe2, 0x1118, 0x9182, 0x007f, 0x0280, 0x9186,
-	0x00ff, 0x0168, 0x9182, 0x0800, 0x1250, 0x2001, 0x9400, 0x080c,
-	0x56e7, 0x11a8, 0x0060, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897,
+	0x114e, 0x7007, 0x0002, 0x701f, 0x3688, 0x0005, 0x00f6, 0x0126,
+	0x2091, 0x8000, 0x2079, 0x0000, 0x2001, 0x18b0, 0x2004, 0x9005,
+	0x1190, 0x0e04, 0x4c4b, 0x7a36, 0x7833, 0x0012, 0x7a82, 0x7b86,
+	0x7c8a, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c,
+	0x1200, 0x0804, 0x4cb1, 0x0016, 0x0086, 0x0096, 0x00c6, 0x00e6,
+	0x2071, 0x189e, 0x7044, 0x9005, 0x1540, 0x7148, 0x9182, 0x0010,
+	0x0288, 0x7038, 0x2060, 0x080c, 0x1059, 0x0904, 0x4ca9, 0xa84b,
+	0x0000, 0x2900, 0x7046, 0x2001, 0x0002, 0x9080, 0x1ee2, 0x2005,
+	0xa846, 0x0098, 0x7038, 0x90e0, 0x0004, 0x2001, 0x18ba, 0x9c82,
+	0x18fa, 0x0210, 0x2061, 0x18ba, 0x2c00, 0x703a, 0x7148, 0x81ff,
+	0x1108, 0x703e, 0x8108, 0x714a, 0x0460, 0x7148, 0x8108, 0x714a,
+	0x7044, 0x2040, 0xa144, 0x2105, 0x0016, 0x908a, 0x0036, 0x1a0c,
+	0x0d85, 0x2060, 0x001e, 0x8108, 0x2105, 0x9005, 0xa146, 0x1520,
+	0x080c, 0x1059, 0x1130, 0x8109, 0xa946, 0x7148, 0x8109, 0x714a,
+	0x00d8, 0x9006, 0xa806, 0xa84a, 0xa046, 0x2800, 0xa802, 0x2900,
+	0xa006, 0x7046, 0x2001, 0x0002, 0x9080, 0x1ee2, 0x2005, 0xa846,
+	0x0058, 0x2262, 0x6306, 0x640a, 0x00ee, 0x00ce, 0x009e, 0x008e,
+	0x001e, 0x012e, 0x00fe, 0x0005, 0x2c00, 0x9082, 0x001b, 0x0002,
+	0x4cd3, 0x4cd3, 0x4cd5, 0x4cd3, 0x4cd3, 0x4cd3, 0x4cd9, 0x4cd3,
+	0x4cd3, 0x4cd3, 0x4cdd, 0x4cd3, 0x4cd3, 0x4cd3, 0x4ce1, 0x4cd3,
+	0x4cd3, 0x4cd3, 0x4ce5, 0x4cd3, 0x4cd3, 0x4cd3, 0x4ce9, 0x4cd3,
+	0x4cd3, 0x4cd3, 0x4cee, 0x080c, 0x0d85, 0xa276, 0xa37a, 0xa47e,
+	0x0898, 0xa286, 0xa38a, 0xa48e, 0x0878, 0xa296, 0xa39a, 0xa49e,
+	0x0858, 0xa2a6, 0xa3aa, 0xa4ae, 0x0838, 0xa2b6, 0xa3ba, 0xa4be,
+	0x0818, 0xa2c6, 0xa3ca, 0xa4ce, 0x0804, 0x4cac, 0xa2d6, 0xa3da,
+	0xa4de, 0x0804, 0x4cac, 0x00e6, 0x2071, 0x189e, 0x7048, 0x9005,
+	0x0904, 0x4d85, 0x0126, 0x2091, 0x8000, 0x0e04, 0x4d84, 0x00f6,
+	0x2079, 0x0000, 0x00c6, 0x0096, 0x0086, 0x0076, 0x9006, 0x2038,
+	0x7040, 0x2048, 0x9005, 0x0500, 0xa948, 0x2105, 0x0016, 0x908a,
+	0x0036, 0x1a0c, 0x0d85, 0x2060, 0x001e, 0x8108, 0x2105, 0x9005,
+	0xa94a, 0x1904, 0x4d87, 0xa804, 0x9005, 0x090c, 0x0d85, 0x7042,
+	0x2938, 0x2040, 0xa003, 0x0000, 0x2001, 0x0002, 0x9080, 0x1ee2,
+	0x2005, 0xa04a, 0x0804, 0x4d87, 0x703c, 0x2060, 0x2c14, 0x6304,
+	0x6408, 0x650c, 0x2200, 0x7836, 0x7833, 0x0012, 0x7882, 0x2300,
+	0x7886, 0x2400, 0x788a, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004,
+	0xd084, 0x190c, 0x1200, 0x87ff, 0x0118, 0x2748, 0x080c, 0x108b,
+	0x7048, 0x8001, 0x704a, 0x9005, 0x1170, 0x7040, 0x2048, 0x9005,
+	0x0128, 0x080c, 0x108b, 0x9006, 0x7042, 0x7046, 0x703b, 0x18ba,
+	0x703f, 0x18ba, 0x0420, 0x7040, 0x9005, 0x1508, 0x7238, 0x2c00,
+	0x9206, 0x0148, 0x9c80, 0x0004, 0x90fa, 0x18fa, 0x0210, 0x2001,
+	0x18ba, 0x703e, 0x00a0, 0x9006, 0x703e, 0x703a, 0x7044, 0x9005,
+	0x090c, 0x0d85, 0x2048, 0xa800, 0x9005, 0x1de0, 0x2900, 0x7042,
+	0x2001, 0x0002, 0x9080, 0x1ee2, 0x2005, 0xa84a, 0x0000, 0x007e,
+	0x008e, 0x009e, 0x00ce, 0x00fe, 0x012e, 0x00ee, 0x0005, 0x2c00,
+	0x9082, 0x001b, 0x0002, 0x4da6, 0x4da6, 0x4da8, 0x4da6, 0x4da6,
+	0x4da6, 0x4dad, 0x4da6, 0x4da6, 0x4da6, 0x4db2, 0x4da6, 0x4da6,
+	0x4da6, 0x4db7, 0x4da6, 0x4da6, 0x4da6, 0x4dbc, 0x4da6, 0x4da6,
+	0x4da6, 0x4dc1, 0x4da6, 0x4da6, 0x4da6, 0x4dc6, 0x080c, 0x0d85,
+	0xaa74, 0xab78, 0xac7c, 0x0804, 0x4d32, 0xaa84, 0xab88, 0xac8c,
+	0x0804, 0x4d32, 0xaa94, 0xab98, 0xac9c, 0x0804, 0x4d32, 0xaaa4,
+	0xaba8, 0xacac, 0x0804, 0x4d32, 0xaab4, 0xabb8, 0xacbc, 0x0804,
+	0x4d32, 0xaac4, 0xabc8, 0xaccc, 0x0804, 0x4d32, 0xaad4, 0xabd8,
+	0xacdc, 0x0804, 0x4d32, 0x0016, 0x0026, 0x0036, 0x00b6, 0x00c6,
+	0x2009, 0x007e, 0x080c, 0x6789, 0x2019, 0x0001, 0xb85c, 0xd0ac,
+	0x0110, 0x2019, 0x0000, 0x2011, 0x801b, 0x080c, 0x4c2e, 0x00ce,
+	0x00be, 0x003e, 0x002e, 0x001e, 0x0005, 0x0026, 0x080c, 0x5826,
+	0xd0c4, 0x0120, 0x2011, 0x8014, 0x080c, 0x4c2e, 0x002e, 0x0005,
+	0x81ff, 0x1904, 0x36ba, 0x0126, 0x2091, 0x8000, 0x6030, 0xc08d,
+	0xc085, 0xc0ac, 0x6032, 0x080c, 0x76a5, 0x1158, 0x080c, 0x79a7,
+	0x080c, 0x617e, 0x9085, 0x0001, 0x080c, 0x76e9, 0x080c, 0x75d4,
+	0x0010, 0x080c, 0x6039, 0x012e, 0x0804, 0x3688, 0x81ff, 0x0120,
+	0x2009, 0x0001, 0x0804, 0x36ba, 0x080c, 0x583a, 0x0120, 0x2009,
+	0x0007, 0x0804, 0x36ba, 0x080c, 0x6bcd, 0x0120, 0x2009, 0x0008,
+	0x0804, 0x36ba, 0x7984, 0x080c, 0x671e, 0x1904, 0x36bd, 0x080c,
+	0x4c01, 0x0904, 0x36bd, 0x2b00, 0x7026, 0x080c, 0x6bd5, 0x7888,
+	0x1170, 0x9084, 0x0005, 0x1158, 0x900e, 0x080c, 0x6a7c, 0x1108,
+	0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x0804, 0x3688, 0x080c,
+	0x4bce, 0x0904, 0x36ba, 0x9006, 0xa866, 0xa832, 0xa868, 0xc0fd,
+	0xa86a, 0x080c, 0xce4f, 0x0904, 0x36ba, 0x7888, 0xd094, 0x0118,
+	0xb8d4, 0xc08d, 0xb8d6, 0x7007, 0x0003, 0x701f, 0x4ea1, 0x0005,
+	0x2061, 0x1800, 0x080c, 0x583a, 0x2009, 0x0007, 0x1560, 0x080c,
+	0x6bcd, 0x0118, 0x2009, 0x0008, 0x0430, 0xa998, 0x080c, 0x671e,
+	0x1530, 0x080c, 0x4bff, 0x0518, 0x080c, 0x6bd5, 0xa89c, 0x1168,
+	0x9084, 0x0005, 0x1150, 0x900e, 0x080c, 0x6a7c, 0x1108, 0xc185,
+	0xb800, 0xd0bc, 0x0108, 0xc18d, 0x00d0, 0xa868, 0xc0fc, 0xa86a,
+	0x080c, 0xce4f, 0x11e0, 0xa89c, 0xd094, 0x0118, 0xb8d4, 0xc08d,
+	0xb8d6, 0x2009, 0x0003, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897,
 	0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x0005, 0xa897,
-	0x4000, 0x900e, 0x9085, 0x0001, 0x2001, 0x0000, 0x0005, 0x2009,
-	0x000a, 0x0c48, 0x080c, 0x1047, 0x0198, 0x9006, 0xa802, 0x7014,
-	0x9005, 0x1120, 0x2900, 0x7016, 0x701a, 0x0040, 0x7018, 0xa802,
-	0x0086, 0x2040, 0x2900, 0xa006, 0x701a, 0x008e, 0x9085, 0x0001,
-	0x0005, 0x7984, 0x080c, 0x6693, 0x1130, 0x7e88, 0x9684, 0x3fff,
-	0x9082, 0x4000, 0x0208, 0x905e, 0x8bff, 0x0005, 0xa998, 0x080c,
-	0x6693, 0x1130, 0xae9c, 0x9684, 0x3fff, 0x9082, 0x4000, 0x0208,
-	0x905e, 0x8bff, 0x0005, 0xae98, 0x0008, 0x7e84, 0x2608, 0x080c,
-	0x6693, 0x1108, 0x0008, 0x905e, 0x8bff, 0x0005, 0x0016, 0x7114,
-	0x81ff, 0x0128, 0x2148, 0xa904, 0x080c, 0x1079, 0x0cc8, 0x7116,
-	0x711a, 0x001e, 0x0005, 0x2031, 0x0001, 0x0010, 0x2031, 0x0000,
-	0x2061, 0x18b8, 0x2c44, 0xa66a, 0xa17a, 0xa772, 0xa076, 0xa28e,
-	0xa392, 0xa496, 0xa59a, 0x080c, 0x113c, 0x7007, 0x0002, 0x701f,
-	0x35b8, 0x0005, 0x00f6, 0x0126, 0x2091, 0x8000, 0x2079, 0x0000,
-	0x2001, 0x18b0, 0x2004, 0x9005, 0x1190, 0x0e04, 0x4b6f, 0x7a36,
-	0x7833, 0x0012, 0x7a82, 0x7b86, 0x7c8a, 0x2091, 0x4080, 0x2001,
-	0x0089, 0x2004, 0xd084, 0x190c, 0x11ee, 0x0804, 0x4bd5, 0x0016,
-	0x0086, 0x0096, 0x00c6, 0x00e6, 0x2071, 0x189e, 0x7044, 0x9005,
-	0x1540, 0x7148, 0x9182, 0x0010, 0x0288, 0x7038, 0x2060, 0x080c,
-	0x1047, 0x0904, 0x4bcd, 0xa84b, 0x0000, 0x2900, 0x7046, 0x2001,
-	0x0002, 0x9080, 0x1eab, 0x2005, 0xa846, 0x0098, 0x7038, 0x90e0,
-	0x0004, 0x2001, 0x18ba, 0x9c82, 0x18fa, 0x0210, 0x2061, 0x18ba,
-	0x2c00, 0x703a, 0x7148, 0x81ff, 0x1108, 0x703e, 0x8108, 0x714a,
-	0x0460, 0x7148, 0x8108, 0x714a, 0x7044, 0x2040, 0xa144, 0x2105,
-	0x0016, 0x908a, 0x0036, 0x1a0c, 0x0d7d, 0x2060, 0x001e, 0x8108,
-	0x2105, 0x9005, 0xa146, 0x1520, 0x080c, 0x1047, 0x1130, 0x8109,
-	0xa946, 0x7148, 0x8109, 0x714a, 0x00d8, 0x9006, 0xa806, 0xa84a,
-	0xa046, 0x2800, 0xa802, 0x2900, 0xa006, 0x7046, 0x2001, 0x0002,
-	0x9080, 0x1eab, 0x2005, 0xa846, 0x0058, 0x2262, 0x6306, 0x640a,
-	0x00ee, 0x00ce, 0x009e, 0x008e, 0x001e, 0x012e, 0x00fe, 0x0005,
-	0x2c00, 0x9082, 0x001b, 0x0002, 0x4bf7, 0x4bf7, 0x4bf9, 0x4bf7,
-	0x4bf7, 0x4bf7, 0x4bfd, 0x4bf7, 0x4bf7, 0x4bf7, 0x4c01, 0x4bf7,
-	0x4bf7, 0x4bf7, 0x4c05, 0x4bf7, 0x4bf7, 0x4bf7, 0x4c09, 0x4bf7,
-	0x4bf7, 0x4bf7, 0x4c0d, 0x4bf7, 0x4bf7, 0x4bf7, 0x4c12, 0x080c,
-	0x0d7d, 0xa276, 0xa37a, 0xa47e, 0x0898, 0xa286, 0xa38a, 0xa48e,
-	0x0878, 0xa296, 0xa39a, 0xa49e, 0x0858, 0xa2a6, 0xa3aa, 0xa4ae,
-	0x0838, 0xa2b6, 0xa3ba, 0xa4be, 0x0818, 0xa2c6, 0xa3ca, 0xa4ce,
-	0x0804, 0x4bd0, 0xa2d6, 0xa3da, 0xa4de, 0x0804, 0x4bd0, 0x00e6,
-	0x2071, 0x189e, 0x7048, 0x9005, 0x0904, 0x4ca9, 0x0126, 0x2091,
-	0x8000, 0x0e04, 0x4ca8, 0x00f6, 0x2079, 0x0000, 0x00c6, 0x0096,
-	0x0086, 0x0076, 0x9006, 0x2038, 0x7040, 0x2048, 0x9005, 0x0500,
-	0xa948, 0x2105, 0x0016, 0x908a, 0x0036, 0x1a0c, 0x0d7d, 0x2060,
-	0x001e, 0x8108, 0x2105, 0x9005, 0xa94a, 0x1904, 0x4cab, 0xa804,
-	0x9005, 0x090c, 0x0d7d, 0x7042, 0x2938, 0x2040, 0xa003, 0x0000,
-	0x2001, 0x0002, 0x9080, 0x1eab, 0x2005, 0xa04a, 0x0804, 0x4cab,
-	0x703c, 0x2060, 0x2c14, 0x6304, 0x6408, 0x650c, 0x2200, 0x7836,
-	0x7833, 0x0012, 0x7882, 0x2300, 0x7886, 0x2400, 0x788a, 0x2091,
-	0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11ee, 0x87ff,
-	0x0118, 0x2748, 0x080c, 0x1079, 0x7048, 0x8001, 0x704a, 0x9005,
-	0x1170, 0x7040, 0x2048, 0x9005, 0x0128, 0x080c, 0x1079, 0x9006,
-	0x7042, 0x7046, 0x703b, 0x18ba, 0x703f, 0x18ba, 0x0420, 0x7040,
-	0x9005, 0x1508, 0x7238, 0x2c00, 0x9206, 0x0148, 0x9c80, 0x0004,
-	0x90fa, 0x18fa, 0x0210, 0x2001, 0x18ba, 0x703e, 0x00a0, 0x9006,
-	0x703e, 0x703a, 0x7044, 0x9005, 0x090c, 0x0d7d, 0x2048, 0xa800,
-	0x9005, 0x1de0, 0x2900, 0x7042, 0x2001, 0x0002, 0x9080, 0x1eab,
-	0x2005, 0xa84a, 0x0000, 0x007e, 0x008e, 0x009e, 0x00ce, 0x00fe,
-	0x012e, 0x00ee, 0x0005, 0x2c00, 0x9082, 0x001b, 0x0002, 0x4cca,
-	0x4cca, 0x4ccc, 0x4cca, 0x4cca, 0x4cca, 0x4cd1, 0x4cca, 0x4cca,
-	0x4cca, 0x4cd6, 0x4cca, 0x4cca, 0x4cca, 0x4cdb, 0x4cca, 0x4cca,
-	0x4cca, 0x4ce0, 0x4cca, 0x4cca, 0x4cca, 0x4ce5, 0x4cca, 0x4cca,
-	0x4cca, 0x4cea, 0x080c, 0x0d7d, 0xaa74, 0xab78, 0xac7c, 0x0804,
-	0x4c56, 0xaa84, 0xab88, 0xac8c, 0x0804, 0x4c56, 0xaa94, 0xab98,
-	0xac9c, 0x0804, 0x4c56, 0xaaa4, 0xaba8, 0xacac, 0x0804, 0x4c56,
-	0xaab4, 0xabb8, 0xacbc, 0x0804, 0x4c56, 0xaac4, 0xabc8, 0xaccc,
-	0x0804, 0x4c56, 0xaad4, 0xabd8, 0xacdc, 0x0804, 0x4c56, 0x0016,
-	0x0026, 0x0036, 0x00b6, 0x00c6, 0x2009, 0x007e, 0x080c, 0x6693,
-	0x2019, 0x0001, 0xb85c, 0xd0ac, 0x0110, 0x2019, 0x0000, 0x2011,
-	0x801b, 0x080c, 0x4b52, 0x00ce, 0x00be, 0x003e, 0x002e, 0x001e,
-	0x0005, 0x0026, 0x080c, 0x573e, 0xd0c4, 0x0120, 0x2011, 0x8014,
-	0x080c, 0x4b52, 0x002e, 0x0005, 0x81ff, 0x1904, 0x35ea, 0x0126,
-	0x2091, 0x8000, 0x6030, 0xc08d, 0xc085, 0xc0ac, 0x6032, 0x080c,
-	0x753d, 0x1158, 0x080c, 0x7840, 0x080c, 0x6092, 0x9085, 0x0001,
-	0x080c, 0x7584, 0x080c, 0x746e, 0x0010, 0x080c, 0x5f4d, 0x012e,
-	0x0804, 0x35b8, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x35ea,
-	0x080c, 0x5752, 0x0120, 0x2009, 0x0007, 0x0804, 0x35ea, 0x080c,
-	0x6ad5, 0x0120, 0x2009, 0x0008, 0x0804, 0x35ea, 0x7984, 0x080c,
-	0x6632, 0x1904, 0x35ed, 0x080c, 0x4b25, 0x0904, 0x35ed, 0x2b00,
-	0x7026, 0x080c, 0x6add, 0x7888, 0x1170, 0x9084, 0x0005, 0x1158,
-	0x900e, 0x080c, 0x6986, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108,
-	0xc18d, 0x0804, 0x35b8, 0x080c, 0x4af2, 0x0904, 0x35ea, 0x9006,
-	0xa866, 0xa832, 0xa868, 0xc0fd, 0xa86a, 0x080c, 0xcbb3, 0x0904,
-	0x35ea, 0x7888, 0xd094, 0x0118, 0xb8d4, 0xc08d, 0xb8d6, 0x7007,
-	0x0003, 0x701f, 0x4dc5, 0x0005, 0x2061, 0x1800, 0x080c, 0x5752,
-	0x2009, 0x0007, 0x1560, 0x080c, 0x6ad5, 0x0118, 0x2009, 0x0008,
-	0x0430, 0xa998, 0x080c, 0x6632, 0x1530, 0x080c, 0x4b23, 0x0518,
-	0x080c, 0x6add, 0xa89c, 0x1168, 0x9084, 0x0005, 0x1150, 0x900e,
-	0x080c, 0x6986, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d,
-	0x00d0, 0xa868, 0xc0fc, 0xa86a, 0x080c, 0xcbb3, 0x11e0, 0xa89c,
-	0xd094, 0x0118, 0xb8d4, 0xc08d, 0xb8d6, 0x2009, 0x0003, 0xa897,
-	0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e, 0x9085, 0x0001,
-	0x2001, 0x0030, 0x0005, 0xa897, 0x4000, 0xa99a, 0x9006, 0x918d,
-	0x0001, 0x2008, 0x0005, 0x9006, 0x0005, 0xa830, 0x9086, 0x0100,
-	0x7024, 0x2058, 0x1110, 0x0804, 0x568c, 0x900e, 0x080c, 0x6986,
-	0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x0804, 0x35b8,
-	0x080c, 0x5752, 0x0120, 0x2009, 0x0007, 0x0804, 0x35ea, 0x7f84,
-	0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x080c, 0x4af2, 0x1120, 0x2009,
-	0x0002, 0x0804, 0x35ea, 0x900e, 0x2130, 0x7126, 0x7132, 0xa860,
-	0x20e8, 0x7036, 0xa85c, 0x9080, 0x0005, 0x702a, 0x20a0, 0x080c,
-	0x6693, 0x1904, 0x4e67, 0x080c, 0x6add, 0x0138, 0x080c, 0x6ae5,
-	0x0120, 0x080c, 0x6a7d, 0x1904, 0x4e67, 0xd794, 0x1110, 0xd784,
-	0x01a8, 0xb8c4, 0x20e0, 0xb8c8, 0x9080, 0x0006, 0x2098, 0x3400,
-	0xd794, 0x0160, 0x20a9, 0x0008, 0x4003, 0x2098, 0x20a0, 0x3d00,
-	0x20e0, 0x20a9, 0x0002, 0x080c, 0x48f1, 0x0048, 0x20a9, 0x0004,
-	0x4003, 0x2098, 0x20a0, 0x3d00, 0x20e0, 0x080c, 0x48f1, 0x9186,
-	0x007e, 0x0170, 0x9186, 0x0080, 0x0158, 0x080c, 0x6add, 0x90c2,
-	0x0006, 0x1210, 0xc1fd, 0x0020, 0x080c, 0x6986, 0x1108, 0xc1fd,
-	0x4104, 0xc1fc, 0xd794, 0x0528, 0xb8c4, 0x20e0, 0xb8c8, 0x2060,
-	0x9c80, 0x0000, 0x2098, 0x20a9, 0x0002, 0x4003, 0x9c80, 0x0003,
-	0x2098, 0x20a9, 0x0001, 0x4005, 0x9c80, 0x0004, 0x2098, 0x3400,
-	0x20a9, 0x0002, 0x4003, 0x2098, 0x20a0, 0x3d00, 0x20e0, 0x080c,
-	0x48e4, 0x9c80, 0x0026, 0x2098, 0xb8c4, 0x20e0, 0x20a9, 0x0002,
-	0x4003, 0xd794, 0x0110, 0x96b0, 0x000b, 0x96b0, 0x0005, 0x8108,
-	0x080c, 0xabe2, 0x0118, 0x9186, 0x0800, 0x0040, 0xd78c, 0x0120,
-	0x9186, 0x0800, 0x0170, 0x0018, 0x9186, 0x007e, 0x0150, 0xd794,
-	0x0118, 0x9686, 0x0020, 0x0010, 0x9686, 0x0028, 0x0150, 0x0804,
-	0x4df7, 0x86ff, 0x1120, 0x7124, 0x810b, 0x0804, 0x35b8, 0x7033,
-	0x0001, 0x7122, 0x7024, 0x9600, 0x7026, 0x772e, 0x2061, 0x18b8,
-	0x2c44, 0xa06b, 0x0000, 0xa67a, 0x7034, 0xa072, 0x7028, 0xa076,
-	0xa28e, 0xa392, 0xa496, 0xa59a, 0x080c, 0x113c, 0x7007, 0x0002,
-	0x701f, 0x4ea3, 0x0005, 0x7030, 0x9005, 0x1180, 0x7120, 0x7028,
-	0x20a0, 0x772c, 0x9036, 0x7034, 0x20e8, 0x2061, 0x18b8, 0x2c44,
-	0xa28c, 0xa390, 0xa494, 0xa598, 0x0804, 0x4df7, 0x7124, 0x810b,
-	0x0804, 0x35b8, 0x2029, 0x007e, 0x7984, 0x7a88, 0x7b8c, 0x7c98,
-	0x9184, 0xff00, 0x8007, 0x90e2, 0x0020, 0x0a04, 0x35ed, 0x9502,
-	0x0a04, 0x35ed, 0x9184, 0x00ff, 0x90e2, 0x0020, 0x0a04, 0x35ed,
-	0x9502, 0x0a04, 0x35ed, 0x9284, 0xff00, 0x8007, 0x90e2, 0x0020,
-	0x0a04, 0x35ed, 0x9502, 0x0a04, 0x35ed, 0x9284, 0x00ff, 0x90e2,
-	0x0020, 0x0a04, 0x35ed, 0x9502, 0x0a04, 0x35ed, 0x9384, 0xff00,
-	0x8007, 0x90e2, 0x0020, 0x0a04, 0x35ed, 0x9502, 0x0a04, 0x35ed,
-	0x9384, 0x00ff, 0x90e2, 0x0020, 0x0a04, 0x35ed, 0x9502, 0x0a04,
-	0x35ed, 0x9484, 0xff00, 0x8007, 0x90e2, 0x0020, 0x0a04, 0x35ed,
-	0x9502, 0x0a04, 0x35ed, 0x9484, 0x00ff, 0x90e2, 0x0020, 0x0a04,
-	0x35ed, 0x9502, 0x0a04, 0x35ed, 0x2061, 0x1988, 0x6102, 0x6206,
-	0x630a, 0x640e, 0x0804, 0x35b8, 0x080c, 0x4af2, 0x0904, 0x35ea,
-	0x2009, 0x0016, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0xa85c, 0x9080,
-	0x0019, 0xaf60, 0x080c, 0x4b3b, 0x701f, 0x4f27, 0x0005, 0x2001,
+	0x4000, 0xa99a, 0x9006, 0x918d, 0x0001, 0x2008, 0x0005, 0x9006,
+	0x0005, 0xa830, 0x9086, 0x0100, 0x7024, 0x2058, 0x1110, 0x0804,
+	0x5774, 0x900e, 0x080c, 0x6a7c, 0x1108, 0xc185, 0xb800, 0xd0bc,
+	0x0108, 0xc18d, 0x0804, 0x3688, 0x080c, 0x583a, 0x0120, 0x2009,
+	0x0007, 0x0804, 0x36ba, 0x7f84, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98,
+	0x080c, 0x4bce, 0x1120, 0x2009, 0x0002, 0x0804, 0x36ba, 0x900e,
+	0x2130, 0x7126, 0x7132, 0xa860, 0x20e8, 0x7036, 0xa85c, 0x9080,
+	0x0005, 0x702a, 0x20a0, 0x080c, 0x6789, 0x1904, 0x4f4a, 0x080c,
+	0x6bd5, 0x0138, 0x080c, 0x6bdd, 0x0120, 0x080c, 0x6b75, 0x1904,
+	0x4f4a, 0xd794, 0x1110, 0xd784, 0x01a8, 0xb8c4, 0x20e0, 0xb8c8,
+	0x9080, 0x0006, 0x2098, 0x3400, 0xd794, 0x0198, 0x20a9, 0x0008,
+	0x4003, 0x2098, 0x20a0, 0x3d00, 0x20e0, 0x20a9, 0x0002, 0x080c,
+	0x49cd, 0x0080, 0xb8c4, 0x20e0, 0xb8c8, 0x9080, 0x000a, 0x2098,
+	0x3400, 0x20a9, 0x0004, 0x4003, 0x2098, 0x20a0, 0x3d00, 0x20e0,
+	0x080c, 0x49cd, 0x9186, 0x007e, 0x0170, 0x9186, 0x0080, 0x0158,
+	0x080c, 0x6bd5, 0x90c2, 0x0006, 0x1210, 0xc1fd, 0x0020, 0x080c,
+	0x6a7c, 0x1108, 0xc1fd, 0x4104, 0xc1fc, 0xd794, 0x0528, 0xb8c4,
+	0x20e0, 0xb8c8, 0x2060, 0x9c80, 0x0000, 0x2098, 0x20a9, 0x0002,
+	0x4003, 0x9c80, 0x0003, 0x2098, 0x20a9, 0x0001, 0x4005, 0x9c80,
+	0x0004, 0x2098, 0x3400, 0x20a9, 0x0002, 0x4003, 0x2098, 0x20a0,
+	0x3d00, 0x20e0, 0x080c, 0x49c0, 0x9c80, 0x0026, 0x2098, 0xb8c4,
+	0x20e0, 0x20a9, 0x0002, 0x4003, 0xd794, 0x0110, 0x96b0, 0x000b,
+	0x96b0, 0x0005, 0x8108, 0x080c, 0xae60, 0x0118, 0x9186, 0x0800,
+	0x0040, 0xd78c, 0x0120, 0x9186, 0x0800, 0x0170, 0x0018, 0x9186,
+	0x007e, 0x0150, 0xd794, 0x0118, 0x9686, 0x0020, 0x0010, 0x9686,
+	0x0028, 0x0150, 0x0804, 0x4ed3, 0x86ff, 0x1120, 0x7124, 0x810b,
+	0x0804, 0x3688, 0x7033, 0x0001, 0x7122, 0x7024, 0x9600, 0x7026,
+	0x772e, 0x2061, 0x18b8, 0x2c44, 0xa06b, 0x0000, 0xa67a, 0x7034,
+	0xa072, 0x7028, 0xa076, 0xa28e, 0xa392, 0xa496, 0xa59a, 0x080c,
+	0x114e, 0x7007, 0x0002, 0x701f, 0x4f86, 0x0005, 0x7030, 0x9005,
+	0x1180, 0x7120, 0x7028, 0x20a0, 0x772c, 0x9036, 0x7034, 0x20e8,
+	0x2061, 0x18b8, 0x2c44, 0xa28c, 0xa390, 0xa494, 0xa598, 0x0804,
+	0x4ed3, 0x7124, 0x810b, 0x0804, 0x3688, 0x2029, 0x007e, 0x7984,
+	0x7a88, 0x7b8c, 0x7c98, 0x9184, 0xff00, 0x8007, 0x90e2, 0x0020,
+	0x0a04, 0x36bd, 0x9502, 0x0a04, 0x36bd, 0x9184, 0x00ff, 0x90e2,
+	0x0020, 0x0a04, 0x36bd, 0x9502, 0x0a04, 0x36bd, 0x9284, 0xff00,
+	0x8007, 0x90e2, 0x0020, 0x0a04, 0x36bd, 0x9502, 0x0a04, 0x36bd,
+	0x9284, 0x00ff, 0x90e2, 0x0020, 0x0a04, 0x36bd, 0x9502, 0x0a04,
+	0x36bd, 0x9384, 0xff00, 0x8007, 0x90e2, 0x0020, 0x0a04, 0x36bd,
+	0x9502, 0x0a04, 0x36bd, 0x9384, 0x00ff, 0x90e2, 0x0020, 0x0a04,
+	0x36bd, 0x9502, 0x0a04, 0x36bd, 0x9484, 0xff00, 0x8007, 0x90e2,
+	0x0020, 0x0a04, 0x36bd, 0x9502, 0x0a04, 0x36bd, 0x9484, 0x00ff,
+	0x90e2, 0x0020, 0x0a04, 0x36bd, 0x9502, 0x0a04, 0x36bd, 0x2061,
+	0x198a, 0x6102, 0x6206, 0x630a, 0x640e, 0x0804, 0x3688, 0x080c,
+	0x4bce, 0x0904, 0x36ba, 0x2009, 0x0016, 0x7a8c, 0x7b88, 0x7c9c,
+	0x7d98, 0xa85c, 0x9080, 0x0019, 0xaf60, 0x080c, 0x4c17, 0x701f,
+	0x500a, 0x0005, 0x2001, 0x0138, 0x2003, 0x0000, 0x00e6, 0x2071,
+	0x0300, 0x701c, 0xd0a4, 0x1de8, 0x00ee, 0x20a9, 0x0016, 0x896e,
+	0x8d6e, 0x8d6f, 0x9d84, 0xffc0, 0x9080, 0x0019, 0x2098, 0x9d84,
+	0x003f, 0x20e0, 0x2069, 0x1877, 0x20e9, 0x0001, 0x2da0, 0x4003,
+	0x6800, 0x9005, 0x0904, 0x508b, 0x6804, 0x2008, 0x918c, 0xfff8,
+	0x1904, 0x508b, 0x680c, 0x9005, 0x0904, 0x508b, 0x9082, 0xff01,
+	0x1a04, 0x508b, 0x6810, 0x9082, 0x005c, 0x0a04, 0x508b, 0x6824,
+	0x2008, 0x9082, 0x0008, 0x0a04, 0x508b, 0x9182, 0x0400, 0x1a04,
+	0x508b, 0x0056, 0x2029, 0x0000, 0x080c, 0x8f15, 0x005e, 0x6944,
+	0x6820, 0x9102, 0x06c0, 0x6820, 0x9082, 0x0019, 0x16a0, 0x6828,
+	0x6944, 0x810c, 0x9102, 0x0678, 0x6840, 0x9082, 0x000f, 0x1658,
+	0x080c, 0x1072, 0x2900, 0x0904, 0x50a7, 0x684e, 0x00e6, 0x2071,
+	0x1932, 0x00b6, 0x2059, 0x0000, 0x080c, 0x8dd1, 0x00be, 0x00ee,
+	0x0568, 0x080c, 0x8b19, 0x080c, 0x8b68, 0x11e0, 0x6857, 0x0000,
+	0x00c6, 0x2061, 0x0100, 0x6104, 0x918d, 0x2000, 0x6106, 0x6b10,
+	0x2061, 0x1a6f, 0x630e, 0x00ce, 0x080c, 0x27ba, 0x2001, 0x0138,
+	0x2102, 0x0804, 0x3688, 0x080c, 0x27ba, 0x2001, 0x0138, 0x2102,
+	0x0804, 0x36bd, 0x080c, 0x8b61, 0x00e6, 0x2071, 0x1932, 0x080c,
+	0x8f95, 0x080c, 0x8fa4, 0x080c, 0x8db4, 0x00ee, 0x2001, 0x188a,
+	0x204c, 0x080c, 0x108b, 0x2001, 0x188a, 0x2003, 0x0000, 0x080c,
+	0x27ba, 0x2001, 0x0138, 0x2102, 0x0804, 0x36ba, 0x2001, 0x1926,
+	0x200c, 0x918e, 0x0000, 0x0904, 0x510c, 0x080c, 0x8daf, 0x0904,
+	0x510c, 0x2001, 0x0101, 0x200c, 0x918c, 0xdfff, 0x2102, 0x2001,
 	0x0138, 0x2003, 0x0000, 0x00e6, 0x2071, 0x0300, 0x701c, 0xd0a4,
-	0x1de8, 0x00ee, 0x20a9, 0x0016, 0x896e, 0x8d6e, 0x8d6f, 0x9d84,
-	0xffc0, 0x9080, 0x0019, 0x2098, 0x9d84, 0x003f, 0x20e0, 0x2069,
-	0x1877, 0x20e9, 0x0001, 0x2da0, 0x4003, 0x6800, 0x9005, 0x0904,
-	0x4fa8, 0x6804, 0x2008, 0x918c, 0xfff8, 0x1904, 0x4fa8, 0x680c,
-	0x9005, 0x0904, 0x4fa8, 0x9082, 0xff01, 0x1a04, 0x4fa8, 0x6810,
-	0x9082, 0x005c, 0x0a04, 0x4fa8, 0x6824, 0x2008, 0x9082, 0x0008,
-	0x0a04, 0x4fa8, 0x9182, 0x0400, 0x1a04, 0x4fa8, 0x0056, 0x2029,
-	0x0000, 0x080c, 0x8da1, 0x005e, 0x6944, 0x6820, 0x9102, 0x06c0,
-	0x6820, 0x9082, 0x0019, 0x16a0, 0x6828, 0x6944, 0x810c, 0x9102,
-	0x0678, 0x6840, 0x9082, 0x000f, 0x1658, 0x080c, 0x1060, 0x2900,
-	0x0904, 0x4fc4, 0x684e, 0x00e6, 0x2071, 0x1930, 0x00b6, 0x2059,
-	0x0000, 0x080c, 0x8c5d, 0x00be, 0x00ee, 0x0568, 0x080c, 0x89ad,
-	0x080c, 0x89f8, 0x11e0, 0x6857, 0x0000, 0x00c6, 0x2061, 0x0100,
-	0x6104, 0x918d, 0x2000, 0x6106, 0x6b10, 0x2061, 0x1a6a, 0x630a,
-	0x00ce, 0x080c, 0x2779, 0x2001, 0x0138, 0x2102, 0x0804, 0x35b8,
-	0x080c, 0x2779, 0x2001, 0x0138, 0x2102, 0x0804, 0x35ed, 0x080c,
-	0x89f1, 0x00e6, 0x2071, 0x1930, 0x080c, 0x8e21, 0x080c, 0x8e30,
-	0x080c, 0x8c44, 0x00ee, 0x2001, 0x188a, 0x204c, 0x080c, 0x1079,
-	0x2001, 0x188a, 0x2003, 0x0000, 0x080c, 0x2779, 0x2001, 0x0138,
-	0x2102, 0x0804, 0x35ea, 0x2001, 0x1924, 0x200c, 0x918e, 0x0000,
-	0x0904, 0x5025, 0x080c, 0x8c3f, 0x0904, 0x5025, 0x2001, 0x0101,
-	0x200c, 0x918c, 0xdfff, 0x2102, 0x2001, 0x0138, 0x2003, 0x0000,
-	0x00e6, 0x2071, 0x0300, 0x701c, 0xd0a4, 0x1de8, 0x00ee, 0x080c,
-	0x8c44, 0x2001, 0x0035, 0x080c, 0x16a0, 0x00c6, 0x2061, 0x193c,
-	0x6004, 0x6100, 0x9106, 0x1de0, 0x00ce, 0x080c, 0x2779, 0x2001,
-	0x0138, 0x2102, 0x00e6, 0x00f6, 0x2071, 0x1923, 0x080c, 0x8b7e,
-	0x0120, 0x2f00, 0x080c, 0x8c0a, 0x0cc8, 0x00fe, 0x00ee, 0x0126,
-	0x2091, 0x8000, 0x2001, 0x188a, 0x200c, 0x81ff, 0x0138, 0x2148,
-	0x080c, 0x1079, 0x2001, 0x188a, 0x2003, 0x0000, 0x2001, 0x183d,
-	0x2003, 0x0020, 0x080c, 0x89f1, 0x00e6, 0x2071, 0x1930, 0x080c,
-	0x8e21, 0x080c, 0x8e30, 0x00ee, 0x012e, 0x0804, 0x35b8, 0x0006,
-	0x080c, 0x573e, 0xd0cc, 0x000e, 0x0005, 0x0006, 0x080c, 0x5742,
-	0xd0bc, 0x000e, 0x0005, 0x6174, 0x7a84, 0x6300, 0x82ff, 0x1118,
-	0x7986, 0x0804, 0x35b8, 0x83ff, 0x1904, 0x35ed, 0x2001, 0xfff0,
-	0x9200, 0x1a04, 0x35ed, 0x2019, 0xffff, 0x6078, 0x9302, 0x9200,
-	0x0a04, 0x35ed, 0x7986, 0x6276, 0x0804, 0x35b8, 0x080c, 0x5752,
-	0x1904, 0x35ea, 0x7c88, 0x7d84, 0x7e98, 0x7f8c, 0x080c, 0x4af2,
-	0x0904, 0x35ea, 0x900e, 0x901e, 0x7326, 0x7332, 0xa860, 0x20e8,
-	0x7036, 0xa85c, 0x9080, 0x0003, 0x702a, 0x20a0, 0x91d8, 0x1000,
-	0x2b5c, 0x8bff, 0x0178, 0x080c, 0x6add, 0x0118, 0x080c, 0x6ae5,
-	0x1148, 0x20a9, 0x0001, 0xb814, 0x4004, 0xb810, 0x4004, 0x4104,
-	0x9398, 0x0003, 0x8108, 0x9182, 0x0800, 0x0120, 0x9386, 0x003c,
-	0x0170, 0x0c20, 0x83ff, 0x1148, 0x7224, 0x900e, 0x2001, 0x0003,
-	0x080c, 0x91f8, 0x2208, 0x0804, 0x35b8, 0x7033, 0x0001, 0x7122,
-	0x7024, 0x9300, 0x7026, 0x2061, 0x18b8, 0x2c44, 0xa06b, 0x0000,
-	0xa37a, 0x7028, 0xa076, 0x7034, 0xa072, 0xa48e, 0xa592, 0xa696,
-	0xa79a, 0x080c, 0x113c, 0x7007, 0x0002, 0x701f, 0x50a8, 0x0005,
-	0x7030, 0x9005, 0x1178, 0x7120, 0x7028, 0x20a0, 0x901e, 0x7034,
-	0x20e8, 0x2061, 0x18b8, 0x2c44, 0xa48c, 0xa590, 0xa694, 0xa798,
-	0x0804, 0x5066, 0x7224, 0x900e, 0x2001, 0x0003, 0x080c, 0x91f8,
-	0x2208, 0x0804, 0x35b8, 0x00f6, 0x00e6, 0x080c, 0x5752, 0x2009,
-	0x0007, 0x1904, 0x513b, 0x2071, 0x189e, 0x745c, 0x84ff, 0x2009,
-	0x000e, 0x1904, 0x513b, 0xac9c, 0xad98, 0xaea4, 0xafa0, 0x0096,
-	0x080c, 0x1060, 0x2009, 0x0002, 0x0904, 0x513b, 0x2900, 0x705e,
-	0x900e, 0x901e, 0x7356, 0x7362, 0xa860, 0x7066, 0xa85c, 0x9080,
-	0x0003, 0x705a, 0x20a0, 0x91d8, 0x1000, 0x2b5c, 0x8bff, 0x0178,
-	0x080c, 0x6add, 0x0118, 0x080c, 0x6ae5, 0x1148, 0xb814, 0x20a9,
-	0x0001, 0x4004, 0xb810, 0x4004, 0x4104, 0x9398, 0x0003, 0x8108,
-	0x9182, 0x0800, 0x0120, 0x9386, 0x003c, 0x01e8, 0x0c20, 0x83ff,
-	0x11c0, 0x7254, 0x900e, 0x2001, 0x0003, 0x080c, 0x91f8, 0x2208,
-	0x009e, 0xa897, 0x4000, 0xa99a, 0x715c, 0x81ff, 0x090c, 0x0d7d,
-	0x2148, 0x080c, 0x1079, 0x9006, 0x705e, 0x918d, 0x0001, 0x2008,
-	0x0418, 0x7063, 0x0001, 0x7152, 0x7054, 0x9300, 0x7056, 0x2061,
-	0x18b9, 0x2c44, 0xa37a, 0x7058, 0xa076, 0x7064, 0xa072, 0xa48e,
-	0xa592, 0xa696, 0xa79a, 0xa09f, 0x5147, 0x000e, 0xa0a2, 0x080c,
-	0x113c, 0x9006, 0x0048, 0x009e, 0xa897, 0x4005, 0xa99a, 0x900e,
-	0x9085, 0x0001, 0x2001, 0x0030, 0x00ee, 0x00fe, 0x0005, 0x00f6,
-	0xa0a0, 0x904d, 0x090c, 0x0d7d, 0x00e6, 0x2071, 0x189e, 0xa06c,
-	0x908e, 0x0100, 0x0138, 0xa87b, 0x0030, 0xa883, 0x0000, 0xa897,
-	0x4002, 0x00d8, 0x7060, 0x9005, 0x1158, 0x7150, 0x7058, 0x20a0,
-	0x901e, 0x7064, 0x20e8, 0xa48c, 0xa590, 0xa694, 0xa798, 0x0428,
-	0xa87b, 0x0000, 0xa883, 0x0000, 0xa897, 0x4000, 0x7254, 0x900e,
-	0x2001, 0x0003, 0x080c, 0x91f8, 0xaa9a, 0x715c, 0x81ff, 0x090c,
-	0x0d7d, 0x2148, 0x080c, 0x1079, 0x705f, 0x0000, 0xa0a0, 0x2048,
-	0x0126, 0x2091, 0x8000, 0x080c, 0x6dee, 0x012e, 0xa09f, 0x0000,
-	0xa0a3, 0x0000, 0x00ee, 0x00fe, 0x0005, 0x91d8, 0x1000, 0x2b5c,
-	0x8bff, 0x0178, 0x080c, 0x6add, 0x0118, 0x080c, 0x6ae5, 0x1148,
-	0xb814, 0x20a9, 0x0001, 0x4004, 0xb810, 0x4004, 0x4104, 0x9398,
-	0x0003, 0x8108, 0x9182, 0x0800, 0x0120, 0x9386, 0x003c, 0x0518,
-	0x0c20, 0x83ff, 0x11f0, 0x7154, 0x810c, 0xa99a, 0xa897, 0x4000,
-	0x715c, 0x81ff, 0x090c, 0x0d7d, 0x2148, 0x080c, 0x1079, 0x9006,
-	0x705e, 0x918d, 0x0001, 0x2008, 0xa0a0, 0x2048, 0x0126, 0x2091,
-	0x8000, 0x080c, 0x6dee, 0x012e, 0xa09f, 0x0000, 0xa0a3, 0x0000,
-	0x0070, 0x7063, 0x0001, 0x7152, 0x7054, 0x9300, 0x7056, 0xa37a,
-	0xa48e, 0xa592, 0xa696, 0xa79a, 0x080c, 0x113c, 0x9006, 0x00ee,
-	0x0005, 0x0096, 0xa88c, 0x90be, 0x7000, 0x0148, 0x90be, 0x7100,
-	0x0130, 0x90be, 0x7200, 0x0118, 0x009e, 0x0804, 0x35ed, 0xa884,
-	0xa988, 0x080c, 0x2661, 0x1518, 0x080c, 0x6632, 0x1500, 0x7126,
-	0xbe12, 0xbd16, 0xae7c, 0x080c, 0x4af2, 0x01c8, 0x080c, 0x4af2,
-	0x01b0, 0x009e, 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, 0xa823,
-	0x0000, 0xa804, 0x2048, 0x080c, 0xcb2c, 0x1120, 0x2009, 0x0003,
-	0x0804, 0x35ea, 0x7007, 0x0003, 0x701f, 0x5214, 0x0005, 0x009e,
-	0x2009, 0x0002, 0x0804, 0x35ea, 0x7124, 0x080c, 0x3349, 0xa820,
-	0x9086, 0x8001, 0x1120, 0x2009, 0x0004, 0x0804, 0x35ea, 0x2900,
-	0x7022, 0xa804, 0x0096, 0x2048, 0x8906, 0x8006, 0x8007, 0x90bc,
-	0x003f, 0x9084, 0xffc0, 0x009e, 0x9080, 0x0002, 0x0076, 0x0006,
-	0x2098, 0x20a0, 0x27e0, 0x27e8, 0x20a9, 0x002a, 0x080c, 0x0fc4,
-	0xaa6c, 0xab70, 0xac74, 0xad78, 0x2061, 0x18b8, 0x2c44, 0xa06b,
-	0x0000, 0xae64, 0xaf8c, 0x97c6, 0x7000, 0x0118, 0x97c6, 0x7100,
-	0x1148, 0x96c2, 0x0004, 0x0600, 0x2009, 0x0004, 0x000e, 0x007e,
-	0x0804, 0x4b3e, 0x97c6, 0x7200, 0x11b8, 0x96c2, 0x0054, 0x02a0,
-	0x000e, 0x007e, 0x2061, 0x18b8, 0x2c44, 0xa076, 0xa772, 0xa07b,
-	0x002a, 0xa28e, 0xa392, 0xa496, 0xa59a, 0x080c, 0x113c, 0x7007,
-	0x0002, 0x701f, 0x5270, 0x0005, 0x000e, 0x007e, 0x0804, 0x35ed,
-	0x7020, 0x2048, 0xa804, 0x2048, 0xa804, 0x2048, 0x8906, 0x8006,
-	0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x0002, 0x2098,
-	0x20a0, 0x27e0, 0x27e8, 0x20a9, 0x002a, 0x080c, 0x0fc4, 0x2100,
-	0x2238, 0x2061, 0x18b8, 0x2c44, 0xa28c, 0xa390, 0xa494, 0xa598,
-	0x2009, 0x002a, 0x0804, 0x4b3e, 0x81ff, 0x1904, 0x35ea, 0x798c,
-	0x2001, 0x197d, 0x918c, 0x8000, 0x2102, 0x080c, 0x4b09, 0x0904,
-	0x35ed, 0x080c, 0x6add, 0x0120, 0x080c, 0x6ae5, 0x1904, 0x35ed,
-	0x080c, 0x675a, 0x0904, 0x35ea, 0x0126, 0x2091, 0x8000, 0x080c,
-	0x68f3, 0x012e, 0x0904, 0x35ea, 0x2001, 0x197d, 0x2004, 0xd0fc,
-	0x1904, 0x35b8, 0x0804, 0x458e, 0xa9a0, 0x2001, 0x197d, 0x918c,
-	0x8000, 0xc18d, 0x2102, 0x080c, 0x4b16, 0x01a0, 0x080c, 0x6add,
-	0x0118, 0x080c, 0x6ae5, 0x1170, 0x080c, 0x675a, 0x2009, 0x0002,
-	0x0128, 0x080c, 0x68f3, 0x1170, 0x2009, 0x0003, 0xa897, 0x4005,
-	0xa99a, 0x0010, 0xa897, 0x4006, 0x900e, 0x9085, 0x0001, 0x2001,
-	0x0030, 0x0005, 0xa897, 0x4000, 0x2001, 0x197d, 0x2004, 0xd0fc,
-	0x1128, 0x080c, 0x5746, 0x0110, 0x9006, 0x0018, 0x900e, 0x9085,
-	0x0001, 0x2001, 0x0000, 0x0005, 0x78a8, 0xd08c, 0x1118, 0xd084,
-	0x0904, 0x4503, 0x080c, 0x4b25, 0x0904, 0x35ed, 0x080c, 0x4af2,
-	0x1120, 0x2009, 0x0002, 0x0804, 0x35ea, 0x080c, 0x6add, 0x0130,
-	0x908e, 0x0004, 0x0118, 0x908e, 0x0005, 0x15a0, 0x78a8, 0xd08c,
-	0x0120, 0xb800, 0xc08c, 0xb802, 0x0028, 0x080c, 0x573e, 0xd0b4,
-	0x0904, 0x453d, 0x7884, 0x908e, 0x007e, 0x0904, 0x453d, 0x908e,
-	0x007f, 0x0904, 0x453d, 0x908e, 0x0080, 0x0904, 0x453d, 0xb800,
-	0xd08c, 0x1904, 0x453d, 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a,
-	0x080c, 0xcb4b, 0x1120, 0x2009, 0x0003, 0x0804, 0x35ea, 0x7007,
-	0x0003, 0x701f, 0x533c, 0x0005, 0x080c, 0x4b25, 0x0904, 0x35ed,
-	0x0804, 0x453d, 0x080c, 0x33a8, 0x0108, 0x0005, 0x2009, 0x1834,
-	0x210c, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x35ea, 0x080c,
-	0x5752, 0x0120, 0x2009, 0x0007, 0x0804, 0x35ea, 0x080c, 0x6ad5,
-	0x0120, 0x2009, 0x0008, 0x0804, 0x35ea, 0xb89c, 0xd0a4, 0x1118,
-	0xd0ac, 0x1904, 0x453d, 0x9006, 0xa866, 0xa832, 0xa868, 0xc0fd,
-	0xa86a, 0x080c, 0xcbb3, 0x1120, 0x2009, 0x0003, 0x0804, 0x35ea,
-	0x7007, 0x0003, 0x701f, 0x5375, 0x0005, 0xa830, 0x9086, 0x0100,
-	0x1120, 0x2009, 0x0004, 0x0804, 0x568c, 0x080c, 0x4b25, 0x0904,
-	0x35ed, 0x0804, 0x530e, 0x81ff, 0x2009, 0x0001, 0x1904, 0x35ea,
-	0x080c, 0x5752, 0x2009, 0x0007, 0x1904, 0x35ea, 0x080c, 0x6ad5,
-	0x0120, 0x2009, 0x0008, 0x0804, 0x35ea, 0x080c, 0x4b25, 0x0904,
-	0x35ed, 0x080c, 0x6add, 0x2009, 0x0009, 0x1904, 0x35ea, 0x080c,
-	0x4af2, 0x2009, 0x0002, 0x0904, 0x35ea, 0x9006, 0xa866, 0xa832,
-	0xa868, 0xc0fd, 0xa86a, 0x7988, 0x9194, 0xff00, 0x918c, 0x00ff,
+	0x1de8, 0x00ee, 0x080c, 0x8db4, 0x0126, 0x2091, 0x8000, 0x2001,
+	0x0035, 0x080c, 0x16b9, 0x012e, 0x00c6, 0x2061, 0x193e, 0x6004,
+	0x6100, 0x9106, 0x1de0, 0x00ce, 0x080c, 0x27ba, 0x2001, 0x0138,
+	0x2102, 0x00e6, 0x00f6, 0x2071, 0x1925, 0x080c, 0x8cee, 0x0120,
+	0x2f00, 0x080c, 0x8d7a, 0x0cc8, 0x00fe, 0x00ee, 0x0126, 0x2091,
+	0x8000, 0x2001, 0x188a, 0x200c, 0x81ff, 0x0138, 0x2148, 0x080c,
+	0x108b, 0x2001, 0x188a, 0x2003, 0x0000, 0x2001, 0x183e, 0x2003,
+	0x0020, 0x080c, 0x8b61, 0x00e6, 0x2071, 0x1932, 0x080c, 0x8f95,
+	0x080c, 0x8fa4, 0x00ee, 0x012e, 0x0804, 0x3688, 0x0006, 0x080c,
+	0x5826, 0xd0cc, 0x000e, 0x0005, 0x0006, 0x080c, 0x582a, 0xd0bc,
+	0x000e, 0x0005, 0x6174, 0x7a84, 0x6300, 0x82ff, 0x1118, 0x7986,
+	0x0804, 0x3688, 0x83ff, 0x1904, 0x36bd, 0x2001, 0xfff0, 0x9200,
+	0x1a04, 0x36bd, 0x2019, 0xffff, 0x6078, 0x9302, 0x9200, 0x0a04,
+	0x36bd, 0x7986, 0x6276, 0x0804, 0x3688, 0x080c, 0x583a, 0x1904,
+	0x36ba, 0x7c88, 0x7d84, 0x7e98, 0x7f8c, 0x080c, 0x4bce, 0x0904,
+	0x36ba, 0x900e, 0x901e, 0x7326, 0x7332, 0xa860, 0x20e8, 0x7036,
+	0xa85c, 0x9080, 0x0003, 0x702a, 0x20a0, 0x91d8, 0x1000, 0x2b5c,
+	0x8bff, 0x0178, 0x080c, 0x6bd5, 0x0118, 0x080c, 0x6bdd, 0x1148,
+	0x20a9, 0x0001, 0xb814, 0x4004, 0xb810, 0x4004, 0x4104, 0x9398,
+	0x0003, 0x8108, 0x9182, 0x0800, 0x0120, 0x9386, 0x003c, 0x0170,
+	0x0c20, 0x83ff, 0x1148, 0x7224, 0x900e, 0x2001, 0x0003, 0x080c,
+	0x936c, 0x2208, 0x0804, 0x3688, 0x7033, 0x0001, 0x7122, 0x7024,
+	0x9300, 0x7026, 0x2061, 0x18b8, 0x2c44, 0xa06b, 0x0000, 0xa37a,
+	0x7028, 0xa076, 0x7034, 0xa072, 0xa48e, 0xa592, 0xa696, 0xa79a,
+	0x080c, 0x114e, 0x7007, 0x0002, 0x701f, 0x518f, 0x0005, 0x7030,
+	0x9005, 0x1178, 0x7120, 0x7028, 0x20a0, 0x901e, 0x7034, 0x20e8,
+	0x2061, 0x18b8, 0x2c44, 0xa48c, 0xa590, 0xa694, 0xa798, 0x0804,
+	0x514d, 0x7224, 0x900e, 0x2001, 0x0003, 0x080c, 0x936c, 0x2208,
+	0x0804, 0x3688, 0x00f6, 0x00e6, 0x080c, 0x583a, 0x2009, 0x0007,
+	0x1904, 0x5222, 0x2071, 0x189e, 0x745c, 0x84ff, 0x2009, 0x000e,
+	0x1904, 0x5222, 0xac9c, 0xad98, 0xaea4, 0xafa0, 0x0096, 0x080c,
+	0x1072, 0x2009, 0x0002, 0x0904, 0x5222, 0x2900, 0x705e, 0x900e,
+	0x901e, 0x7356, 0x7362, 0xa860, 0x7066, 0xa85c, 0x9080, 0x0003,
+	0x705a, 0x20a0, 0x91d8, 0x1000, 0x2b5c, 0x8bff, 0x0178, 0x080c,
+	0x6bd5, 0x0118, 0x080c, 0x6bdd, 0x1148, 0xb814, 0x20a9, 0x0001,
+	0x4004, 0xb810, 0x4004, 0x4104, 0x9398, 0x0003, 0x8108, 0x9182,
+	0x0800, 0x0120, 0x9386, 0x003c, 0x01e8, 0x0c20, 0x83ff, 0x11c0,
+	0x7254, 0x900e, 0x2001, 0x0003, 0x080c, 0x936c, 0x2208, 0x009e,
+	0xa897, 0x4000, 0xa99a, 0x715c, 0x81ff, 0x090c, 0x0d85, 0x2148,
+	0x080c, 0x108b, 0x9006, 0x705e, 0x918d, 0x0001, 0x2008, 0x0418,
+	0x7063, 0x0001, 0x7152, 0x7054, 0x9300, 0x7056, 0x2061, 0x18b9,
+	0x2c44, 0xa37a, 0x7058, 0xa076, 0x7064, 0xa072, 0xa48e, 0xa592,
+	0xa696, 0xa79a, 0xa09f, 0x522e, 0x000e, 0xa0a2, 0x080c, 0x114e,
+	0x9006, 0x0048, 0x009e, 0xa897, 0x4005, 0xa99a, 0x900e, 0x9085,
+	0x0001, 0x2001, 0x0030, 0x00ee, 0x00fe, 0x0005, 0x00f6, 0xa0a0,
+	0x904d, 0x090c, 0x0d85, 0x00e6, 0x2071, 0x189e, 0xa06c, 0x908e,
+	0x0100, 0x0138, 0xa87b, 0x0030, 0xa883, 0x0000, 0xa897, 0x4002,
+	0x00d8, 0x7060, 0x9005, 0x1158, 0x7150, 0x7058, 0x20a0, 0x901e,
+	0x7064, 0x20e8, 0xa48c, 0xa590, 0xa694, 0xa798, 0x0428, 0xa87b,
+	0x0000, 0xa883, 0x0000, 0xa897, 0x4000, 0x7254, 0x900e, 0x2001,
+	0x0003, 0x080c, 0x936c, 0xaa9a, 0x715c, 0x81ff, 0x090c, 0x0d85,
+	0x2148, 0x080c, 0x108b, 0x705f, 0x0000, 0xa0a0, 0x2048, 0x0126,
+	0x2091, 0x8000, 0x080c, 0x6f19, 0x012e, 0xa09f, 0x0000, 0xa0a3,
+	0x0000, 0x00ee, 0x00fe, 0x0005, 0x91d8, 0x1000, 0x2b5c, 0x8bff,
+	0x0178, 0x080c, 0x6bd5, 0x0118, 0x080c, 0x6bdd, 0x1148, 0xb814,
+	0x20a9, 0x0001, 0x4004, 0xb810, 0x4004, 0x4104, 0x9398, 0x0003,
+	0x8108, 0x9182, 0x0800, 0x0120, 0x9386, 0x003c, 0x0518, 0x0c20,
+	0x83ff, 0x11f0, 0x7154, 0x810c, 0xa99a, 0xa897, 0x4000, 0x715c,
+	0x81ff, 0x090c, 0x0d85, 0x2148, 0x080c, 0x108b, 0x9006, 0x705e,
+	0x918d, 0x0001, 0x2008, 0xa0a0, 0x2048, 0x0126, 0x2091, 0x8000,
+	0x080c, 0x6f19, 0x012e, 0xa09f, 0x0000, 0xa0a3, 0x0000, 0x0070,
+	0x7063, 0x0001, 0x7152, 0x7054, 0x9300, 0x7056, 0xa37a, 0xa48e,
+	0xa592, 0xa696, 0xa79a, 0x080c, 0x114e, 0x9006, 0x00ee, 0x0005,
+	0x0096, 0xa88c, 0x90be, 0x7000, 0x0148, 0x90be, 0x7100, 0x0130,
+	0x90be, 0x7200, 0x0118, 0x009e, 0x0804, 0x36bd, 0xa884, 0xa988,
+	0x080c, 0x26a2, 0x1518, 0x080c, 0x671e, 0x1500, 0x7126, 0xbe12,
+	0xbd16, 0xae7c, 0x080c, 0x4bce, 0x01c8, 0x080c, 0x4bce, 0x01b0,
+	0x009e, 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, 0xa823, 0x0000,
+	0xa804, 0x2048, 0x080c, 0xcdc8, 0x1120, 0x2009, 0x0003, 0x0804,
+	0x36ba, 0x7007, 0x0003, 0x701f, 0x52fb, 0x0005, 0x009e, 0x2009,
+	0x0002, 0x0804, 0x36ba, 0x7124, 0x080c, 0x3419, 0xa820, 0x9086,
+	0x8001, 0x1120, 0x2009, 0x0004, 0x0804, 0x36ba, 0x2900, 0x7022,
+	0xa804, 0x0096, 0x2048, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f,
+	0x9084, 0xffc0, 0x009e, 0x9080, 0x0002, 0x0076, 0x0006, 0x2098,
+	0x20a0, 0x27e0, 0x27e8, 0x20a9, 0x002a, 0x080c, 0x0fd6, 0xaa6c,
+	0xab70, 0xac74, 0xad78, 0x2061, 0x18b8, 0x2c44, 0xa06b, 0x0000,
+	0xae64, 0xaf8c, 0x97c6, 0x7000, 0x0118, 0x97c6, 0x7100, 0x1148,
+	0x96c2, 0x0004, 0x0600, 0x2009, 0x0004, 0x000e, 0x007e, 0x0804,
+	0x4c1a, 0x97c6, 0x7200, 0x11b8, 0x96c2, 0x0054, 0x02a0, 0x000e,
+	0x007e, 0x2061, 0x18b8, 0x2c44, 0xa076, 0xa772, 0xa07b, 0x002a,
+	0xa28e, 0xa392, 0xa496, 0xa59a, 0x080c, 0x114e, 0x7007, 0x0002,
+	0x701f, 0x5357, 0x0005, 0x000e, 0x007e, 0x0804, 0x36bd, 0x7020,
+	0x2048, 0xa804, 0x2048, 0xa804, 0x2048, 0x8906, 0x8006, 0x8007,
+	0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x0002, 0x2098, 0x20a0,
+	0x27e0, 0x27e8, 0x20a9, 0x002a, 0x080c, 0x0fd6, 0x2100, 0x2238,
+	0x2061, 0x18b8, 0x2c44, 0xa28c, 0xa390, 0xa494, 0xa598, 0x2009,
+	0x002a, 0x0804, 0x4c1a, 0x81ff, 0x1904, 0x36ba, 0x798c, 0x2001,
+	0x197f, 0x918c, 0x8000, 0x2102, 0x080c, 0x4be5, 0x0904, 0x36bd,
+	0x080c, 0x6bd5, 0x0120, 0x080c, 0x6bdd, 0x1904, 0x36bd, 0x080c,
+	0x6850, 0x0904, 0x36ba, 0x0126, 0x2091, 0x8000, 0x080c, 0x69e9,
+	0x012e, 0x0904, 0x36ba, 0x2001, 0x197f, 0x2004, 0xd0fc, 0x1904,
+	0x3688, 0x0804, 0x4667, 0xa9a0, 0x2001, 0x197f, 0x918c, 0x8000,
+	0xc18d, 0x2102, 0x080c, 0x4bf2, 0x01a0, 0x080c, 0x6bd5, 0x0118,
+	0x080c, 0x6bdd, 0x1170, 0x080c, 0x6850, 0x2009, 0x0002, 0x0128,
+	0x080c, 0x69e9, 0x1170, 0x2009, 0x0003, 0xa897, 0x4005, 0xa99a,
+	0x0010, 0xa897, 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030,
+	0x0005, 0xa897, 0x4000, 0x2001, 0x197f, 0x2004, 0xd0fc, 0x1128,
+	0x080c, 0x582e, 0x0110, 0x9006, 0x0018, 0x900e, 0x9085, 0x0001,
+	0x2001, 0x0000, 0x0005, 0x78a8, 0xd08c, 0x1118, 0xd084, 0x0904,
+	0x45dc, 0x080c, 0x4c01, 0x0904, 0x36bd, 0x080c, 0x4bce, 0x1120,
+	0x2009, 0x0002, 0x0804, 0x36ba, 0x080c, 0x6bd5, 0x0130, 0x908e,
+	0x0004, 0x0118, 0x908e, 0x0005, 0x15a0, 0x78a8, 0xd08c, 0x0120,
+	0xb800, 0xc08c, 0xb802, 0x0028, 0x080c, 0x5826, 0xd0b4, 0x0904,
+	0x4616, 0x7884, 0x908e, 0x007e, 0x0904, 0x4616, 0x908e, 0x007f,
+	0x0904, 0x4616, 0x908e, 0x0080, 0x0904, 0x4616, 0xb800, 0xd08c,
+	0x1904, 0x4616, 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x080c,
+	0xcde7, 0x1120, 0x2009, 0x0003, 0x0804, 0x36ba, 0x7007, 0x0003,
+	0x701f, 0x5423, 0x0005, 0x080c, 0x4c01, 0x0904, 0x36bd, 0x0804,
+	0x4616, 0x080c, 0x3478, 0x0108, 0x0005, 0x2009, 0x1834, 0x210c,
+	0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x36ba, 0x080c, 0x583a,
+	0x0120, 0x2009, 0x0007, 0x0804, 0x36ba, 0x080c, 0x6bcd, 0x0120,
+	0x2009, 0x0008, 0x0804, 0x36ba, 0xb89c, 0xd0a4, 0x1118, 0xd0ac,
+	0x1904, 0x4616, 0x9006, 0xa866, 0xa832, 0xa868, 0xc0fd, 0xa86a,
+	0x080c, 0xce4f, 0x1120, 0x2009, 0x0003, 0x0804, 0x36ba, 0x7007,
+	0x0003, 0x701f, 0x545c, 0x0005, 0xa830, 0x9086, 0x0100, 0x1120,
+	0x2009, 0x0004, 0x0804, 0x5774, 0x080c, 0x4c01, 0x0904, 0x36bd,
+	0x0804, 0x53f5, 0x81ff, 0x2009, 0x0001, 0x1904, 0x36ba, 0x080c,
+	0x583a, 0x2009, 0x0007, 0x1904, 0x36ba, 0x080c, 0x6bcd, 0x0120,
+	0x2009, 0x0008, 0x0804, 0x36ba, 0x080c, 0x4c01, 0x0904, 0x36bd,
+	0x080c, 0x6bd5, 0x2009, 0x0009, 0x1904, 0x36ba, 0x080c, 0x4bce,
+	0x2009, 0x0002, 0x0904, 0x36ba, 0x9006, 0xa866, 0xa832, 0xa868,
+	0xc0fd, 0xa86a, 0x7988, 0xa95a, 0x9194, 0xfd00, 0x918c, 0x00ff,
 	0x9006, 0x82ff, 0x1128, 0xc0ed, 0xa952, 0x798c, 0xa956, 0x0038,
-	0x928e, 0x0100, 0x1904, 0x35ed, 0xc0e5, 0xa952, 0xa956, 0xa83e,
-	0x080c, 0xce16, 0x2009, 0x0003, 0x0904, 0x35ea, 0x7007, 0x0003,
-	0x701f, 0x53cb, 0x0005, 0xa830, 0x9086, 0x0100, 0x2009, 0x0004,
-	0x0904, 0x35ea, 0x0804, 0x35b8, 0x7aa8, 0x9284, 0xc000, 0x0148,
-	0xd2ec, 0x01a0, 0x080c, 0x5752, 0x1188, 0x2009, 0x0014, 0x0804,
-	0x35ea, 0xd2dc, 0x1578, 0x81ff, 0x2009, 0x0001, 0x1904, 0x35ea,
-	0x080c, 0x5752, 0x2009, 0x0007, 0x1904, 0x35ea, 0xd2f4, 0x0138,
-	0x9284, 0x5000, 0xc0d5, 0x080c, 0x5718, 0x0804, 0x35b8, 0xd2fc,
-	0x0160, 0x080c, 0x4b25, 0x0904, 0x35ed, 0x7984, 0x9284, 0x9000,
-	0xc0d5, 0x080c, 0x56e7, 0x0804, 0x35b8, 0x080c, 0x4b25, 0x0904,
-	0x35ed, 0xb804, 0x9084, 0x00ff, 0x9086, 0x0006, 0x2009, 0x0009,
-	0x1904, 0x54ba, 0x080c, 0x4af2, 0x2009, 0x0002, 0x0904, 0x54ba,
+	0x928e, 0x0100, 0x1904, 0x36bd, 0xc0e5, 0xa952, 0xa956, 0xa83e,
+	0x080c, 0xd0b2, 0x2009, 0x0003, 0x0904, 0x36ba, 0x7007, 0x0003,
+	0x701f, 0x54b3, 0x0005, 0xa830, 0x9086, 0x0100, 0x2009, 0x0004,
+	0x0904, 0x36ba, 0x0804, 0x3688, 0x7aa8, 0x9284, 0xc000, 0x0148,
+	0xd2ec, 0x01a0, 0x080c, 0x583a, 0x1188, 0x2009, 0x0014, 0x0804,
+	0x36ba, 0xd2dc, 0x1578, 0x81ff, 0x2009, 0x0001, 0x1904, 0x36ba,
+	0x080c, 0x583a, 0x2009, 0x0007, 0x1904, 0x36ba, 0xd2f4, 0x0138,
+	0x9284, 0x5000, 0xc0d5, 0x080c, 0x5800, 0x0804, 0x3688, 0xd2fc,
+	0x0160, 0x080c, 0x4c01, 0x0904, 0x36bd, 0x7984, 0x9284, 0x9000,
+	0xc0d5, 0x080c, 0x57cf, 0x0804, 0x3688, 0x080c, 0x4c01, 0x0904,
+	0x36bd, 0xb804, 0x9084, 0x00ff, 0x9086, 0x0006, 0x2009, 0x0009,
+	0x1904, 0x55a2, 0x080c, 0x4bce, 0x2009, 0x0002, 0x0904, 0x55a2,
 	0xa85c, 0x9080, 0x001b, 0xaf60, 0x2009, 0x0008, 0x7a8c, 0x7b88,
-	0x7c9c, 0x7d98, 0x080c, 0x4b3b, 0x701f, 0x5427, 0x0005, 0xa86c,
+	0x7c9c, 0x7d98, 0x080c, 0x4c17, 0x701f, 0x550f, 0x0005, 0xa86c,
 	0x9086, 0x0500, 0x1138, 0xa870, 0x9005, 0x1120, 0xa874, 0x9084,
-	0xff00, 0x0110, 0x1904, 0x35ed, 0xa866, 0xa832, 0xa868, 0xc0fd,
-	0xa86a, 0x080c, 0x4b25, 0x1110, 0x0804, 0x35ed, 0x2009, 0x0043,
-	0x080c, 0xce7e, 0x2009, 0x0003, 0x0904, 0x54ba, 0x7007, 0x0003,
-	0x701f, 0x544b, 0x0005, 0xa830, 0x9086, 0x0100, 0x2009, 0x0004,
-	0x0904, 0x54ba, 0x7984, 0x7aa8, 0x9284, 0x1000, 0xe085, 0x080c,
-	0x56e7, 0x0804, 0x35b8, 0x00c6, 0xaab0, 0x9284, 0xc000, 0x0148,
-	0xd2ec, 0x0170, 0x080c, 0x5752, 0x1158, 0x2009, 0x0014, 0x0804,
-	0x54a9, 0x2061, 0x1800, 0x080c, 0x5752, 0x2009, 0x0007, 0x15c8,
-	0xd2f4, 0x0130, 0x9284, 0x5000, 0xc0d5, 0x080c, 0x5718, 0x0058,
-	0xd2fc, 0x0180, 0x080c, 0x4b23, 0x0590, 0xa998, 0x9284, 0x9000,
-	0xc0d5, 0x080c, 0x56e7, 0xa87b, 0x0000, 0xa883, 0x0000, 0xa897,
-	0x4000, 0x0438, 0x080c, 0x4b23, 0x0510, 0x080c, 0x6add, 0x2009,
+	0xff00, 0x0110, 0x1904, 0x36bd, 0xa866, 0xa832, 0xa868, 0xc0fd,
+	0xa86a, 0x080c, 0x4c01, 0x1110, 0x0804, 0x36bd, 0x2009, 0x0043,
+	0x080c, 0xd11e, 0x2009, 0x0003, 0x0904, 0x55a2, 0x7007, 0x0003,
+	0x701f, 0x5533, 0x0005, 0xa830, 0x9086, 0x0100, 0x2009, 0x0004,
+	0x0904, 0x55a2, 0x7984, 0x7aa8, 0x9284, 0x1000, 0xc0d5, 0x080c,
+	0x57cf, 0x0804, 0x3688, 0x00c6, 0xaab0, 0x9284, 0xc000, 0x0148,
+	0xd2ec, 0x0170, 0x080c, 0x583a, 0x1158, 0x2009, 0x0014, 0x0804,
+	0x5591, 0x2061, 0x1800, 0x080c, 0x583a, 0x2009, 0x0007, 0x15c8,
+	0xd2f4, 0x0130, 0x9284, 0x5000, 0xc0d5, 0x080c, 0x5800, 0x0058,
+	0xd2fc, 0x0180, 0x080c, 0x4bff, 0x0590, 0xa998, 0x9284, 0x9000,
+	0xc0d5, 0x080c, 0x57cf, 0xa87b, 0x0000, 0xa883, 0x0000, 0xa897,
+	0x4000, 0x0438, 0x080c, 0x4bff, 0x0510, 0x080c, 0x6bd5, 0x2009,
 	0x0009, 0x11b8, 0xa8c4, 0x9086, 0x0500, 0x11c8, 0xa8c8, 0x9005,
-	0x11b0, 0xa8cc, 0x9084, 0xff00, 0x1190, 0x080c, 0x4b23, 0x1108,
-	0x0070, 0x2009, 0x004b, 0x080c, 0xce7e, 0x2009, 0x0003, 0x0108,
+	0x11b0, 0xa8cc, 0x9084, 0xff00, 0x1190, 0x080c, 0x4bff, 0x1108,
+	0x0070, 0x2009, 0x004b, 0x080c, 0xd11e, 0x2009, 0x0003, 0x0108,
 	0x0078, 0x0431, 0x19c0, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897,
 	0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x00ce, 0x0005,
-	0x9006, 0x0ce0, 0x7aa8, 0xd2dc, 0x0904, 0x35ea, 0x0016, 0x7984,
-	0x9284, 0x1000, 0xc0fd, 0x080c, 0x56e7, 0x001e, 0x1904, 0x35ea,
-	0x0804, 0x35b8, 0x00f6, 0x2d78, 0xaab0, 0x0021, 0x00fe, 0x0005,
+	0x9006, 0x0ce0, 0x7aa8, 0xd2dc, 0x0904, 0x36ba, 0x0016, 0x7984,
+	0x9284, 0x1000, 0xc0fd, 0x080c, 0x57cf, 0x001e, 0x1904, 0x36ba,
+	0x0804, 0x3688, 0x00f6, 0x2d78, 0xaab0, 0x0021, 0x00fe, 0x0005,
 	0xaab0, 0xc2d5, 0xd2dc, 0x0150, 0x0016, 0xa998, 0x9284, 0x1400,
-	0xc0fd, 0x080c, 0x56e7, 0x001e, 0x9085, 0x0001, 0x0005, 0x81ff,
-	0x0120, 0x2009, 0x0001, 0x0804, 0x35ea, 0x080c, 0x5752, 0x0120,
-	0x2009, 0x0007, 0x0804, 0x35ea, 0x7984, 0x7ea8, 0x96b4, 0x00ff,
-	0x080c, 0x6693, 0x1904, 0x35ed, 0x9186, 0x007f, 0x0138, 0x080c,
-	0x6add, 0x0120, 0x2009, 0x0009, 0x0804, 0x35ea, 0x080c, 0x4af2,
-	0x1120, 0x2009, 0x0002, 0x0804, 0x35ea, 0xa867, 0x0000, 0xa868,
-	0xc0fd, 0xa86a, 0x2001, 0x0100, 0x8007, 0xa80a, 0x080c, 0xcb65,
-	0x1120, 0x2009, 0x0003, 0x0804, 0x35ea, 0x7007, 0x0003, 0x701f,
-	0x551a, 0x0005, 0xa808, 0x8007, 0x9086, 0x0100, 0x1120, 0x2009,
-	0x0004, 0x0804, 0x35ea, 0xa8e0, 0xa866, 0xa810, 0x8007, 0x9084,
+	0xc0fd, 0x080c, 0x57cf, 0x001e, 0x9085, 0x0001, 0x0005, 0x81ff,
+	0x0120, 0x2009, 0x0001, 0x0804, 0x36ba, 0x080c, 0x583a, 0x0120,
+	0x2009, 0x0007, 0x0804, 0x36ba, 0x7984, 0x7ea8, 0x96b4, 0x00ff,
+	0x080c, 0x6789, 0x1904, 0x36bd, 0x9186, 0x007f, 0x0138, 0x080c,
+	0x6bd5, 0x0120, 0x2009, 0x0009, 0x0804, 0x36ba, 0x080c, 0x4bce,
+	0x1120, 0x2009, 0x0002, 0x0804, 0x36ba, 0xa867, 0x0000, 0xa868,
+	0xc0fd, 0xa86a, 0x2001, 0x0100, 0x8007, 0xa80a, 0x080c, 0xce01,
+	0x1120, 0x2009, 0x0003, 0x0804, 0x36ba, 0x7007, 0x0003, 0x701f,
+	0x5602, 0x0005, 0xa808, 0x8007, 0x9086, 0x0100, 0x1120, 0x2009,
+	0x0004, 0x0804, 0x36ba, 0xa8e0, 0xa866, 0xa810, 0x8007, 0x9084,
 	0x00ff, 0x800c, 0xa814, 0x8007, 0x9084, 0x00ff, 0x8004, 0x9080,
 	0x0002, 0x9108, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084,
 	0xffc0, 0x9080, 0x0004, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x0804,
-	0x4b3e, 0x080c, 0x4af2, 0x1120, 0x2009, 0x0002, 0x0804, 0x35ea,
+	0x4c1a, 0x080c, 0x4bce, 0x1120, 0x2009, 0x0002, 0x0804, 0x36ba,
 	0x7984, 0x9194, 0xff00, 0x918c, 0x00ff, 0x8217, 0x82ff, 0x1118,
-	0x7023, 0x19b2, 0x0040, 0x92c6, 0x0001, 0x1118, 0x7023, 0x19cc,
-	0x0010, 0x0804, 0x35ed, 0x2009, 0x001a, 0x7a8c, 0x7b88, 0x7c9c,
-	0x7d98, 0xa85c, 0x9080, 0x0019, 0xaf60, 0x080c, 0x4b3b, 0x701f,
-	0x556a, 0x0005, 0x2001, 0x182e, 0x2003, 0x0001, 0xa85c, 0x9080,
+	0x7023, 0x19b5, 0x0040, 0x92c6, 0x0001, 0x1118, 0x7023, 0x19cf,
+	0x0010, 0x0804, 0x36bd, 0x2009, 0x001a, 0x7a8c, 0x7b88, 0x7c9c,
+	0x7d98, 0xa85c, 0x9080, 0x0019, 0xaf60, 0x080c, 0x4c17, 0x701f,
+	0x5652, 0x0005, 0x2001, 0x182e, 0x2003, 0x0001, 0xa85c, 0x9080,
 	0x0019, 0x2098, 0xa860, 0x20e0, 0x20a9, 0x001a, 0x7020, 0x20a0,
-	0x20e9, 0x0001, 0x4003, 0x0804, 0x35b8, 0x080c, 0x4af2, 0x1120,
-	0x2009, 0x0002, 0x0804, 0x35ea, 0x7984, 0x9194, 0xff00, 0x918c,
-	0x00ff, 0x8217, 0x82ff, 0x1118, 0x2099, 0x19b2, 0x0040, 0x92c6,
-	0x0001, 0x1118, 0x2099, 0x19cc, 0x0010, 0x0804, 0x35ed, 0xa85c,
+	0x20e9, 0x0001, 0x4003, 0x0804, 0x3688, 0x080c, 0x4bce, 0x1120,
+	0x2009, 0x0002, 0x0804, 0x36ba, 0x7984, 0x9194, 0xff00, 0x918c,
+	0x00ff, 0x8217, 0x82ff, 0x1118, 0x2099, 0x19b5, 0x0040, 0x92c6,
+	0x0001, 0x1118, 0x2099, 0x19cf, 0x0010, 0x0804, 0x36bd, 0xa85c,
 	0x9080, 0x0019, 0x20a0, 0xa860, 0x20e8, 0x20a9, 0x001a, 0x20e1,
 	0x0001, 0x4003, 0x2009, 0x001a, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98,
-	0xa85c, 0x9080, 0x0019, 0xaf60, 0x0804, 0x4b3e, 0x7884, 0x908a,
-	0x1000, 0x1a04, 0x35ed, 0x0126, 0x2091, 0x8000, 0x8003, 0x800b,
-	0x810b, 0x9108, 0x00c6, 0x2061, 0x1a02, 0x6142, 0x00ce, 0x012e,
-	0x0804, 0x35b8, 0x00c6, 0x080c, 0x753d, 0x1160, 0x080c, 0x7840,
-	0x080c, 0x6092, 0x9085, 0x0001, 0x080c, 0x7584, 0x080c, 0x746e,
-	0x080c, 0x0d7d, 0x2061, 0x1800, 0x6030, 0xc09d, 0x6032, 0x080c,
-	0x5f4d, 0x00ce, 0x0005, 0x00c6, 0x2001, 0x1800, 0x2004, 0x908e,
-	0x0000, 0x0904, 0x35ea, 0x7884, 0x9005, 0x0188, 0x7888, 0x2061,
-	0x199b, 0x2c0c, 0x2062, 0x080c, 0x2a48, 0x01a0, 0x080c, 0x2a50,
-	0x0188, 0x080c, 0x2a58, 0x0170, 0x2162, 0x0804, 0x35ed, 0x2061,
+	0xa85c, 0x9080, 0x0019, 0xaf60, 0x0804, 0x4c1a, 0x7884, 0x908a,
+	0x1000, 0x1a04, 0x36bd, 0x0126, 0x2091, 0x8000, 0x8003, 0x800b,
+	0x810b, 0x9108, 0x00c6, 0x2061, 0x1a05, 0x614a, 0x00ce, 0x012e,
+	0x0804, 0x3688, 0x00c6, 0x080c, 0x76a5, 0x1160, 0x080c, 0x79a7,
+	0x080c, 0x617e, 0x9085, 0x0001, 0x080c, 0x76e9, 0x080c, 0x75d4,
+	0x080c, 0x0d85, 0x2061, 0x1800, 0x6030, 0xc09d, 0x6032, 0x080c,
+	0x6039, 0x00ce, 0x0005, 0x00c6, 0x2001, 0x1800, 0x2004, 0x908e,
+	0x0000, 0x0904, 0x36ba, 0x7884, 0x9005, 0x0188, 0x7888, 0x2061,
+	0x199d, 0x2c0c, 0x2062, 0x080c, 0x2a89, 0x01a0, 0x080c, 0x2a91,
+	0x0188, 0x080c, 0x2a99, 0x0170, 0x2162, 0x0804, 0x36bd, 0x2061,
 	0x0100, 0x6038, 0x9086, 0x0007, 0x1118, 0x2009, 0x0001, 0x0010,
 	0x2009, 0x0000, 0x7884, 0x9086, 0x0002, 0x15a8, 0x2061, 0x0100,
-	0x6028, 0xc09c, 0x602a, 0x080c, 0xa91e, 0x0026, 0x2011, 0x0003,
-	0x080c, 0xa243, 0x2011, 0x0002, 0x080c, 0xa24d, 0x002e, 0x080c,
-	0xa138, 0x0036, 0x901e, 0x080c, 0xa1b8, 0x003e, 0x080c, 0xa93a,
-	0x60e3, 0x0000, 0x080c, 0xe882, 0x080c, 0xe89d, 0x9085, 0x0001,
-	0x080c, 0x7584, 0x9006, 0x080c, 0x2a7a, 0x2001, 0x1800, 0x2003,
-	0x0004, 0x2001, 0x19a6, 0x2003, 0x0000, 0x0026, 0x2011, 0x0008,
-	0x080c, 0x2ab4, 0x002e, 0x00ce, 0x0804, 0x35b8, 0x81ff, 0x0120,
-	0x2009, 0x0001, 0x0804, 0x35ea, 0x080c, 0x5752, 0x0120, 0x2009,
-	0x0007, 0x0804, 0x35ea, 0x7984, 0x7ea8, 0x96b4, 0x00ff, 0x080c,
-	0x6693, 0x1904, 0x35ed, 0x9186, 0x007f, 0x0138, 0x080c, 0x6add,
-	0x0120, 0x2009, 0x0009, 0x0804, 0x35ea, 0x080c, 0x4af2, 0x1120,
-	0x2009, 0x0002, 0x0804, 0x35ea, 0xa867, 0x0000, 0xa868, 0xc0fd,
-	0xa86a, 0x080c, 0xcb68, 0x1120, 0x2009, 0x0003, 0x0804, 0x35ea,
-	0x7007, 0x0003, 0x701f, 0x5675, 0x0005, 0xa830, 0x9086, 0x0100,
-	0x1120, 0x2009, 0x0004, 0x0804, 0x35ea, 0xa8e0, 0xa866, 0xa834,
+	0x6028, 0xc09c, 0x602a, 0x080c, 0xaae0, 0x0026, 0x2011, 0x0003,
+	0x080c, 0xa40f, 0x2011, 0x0002, 0x080c, 0xa419, 0x002e, 0x080c,
+	0xa300, 0x0036, 0x901e, 0x080c, 0xa380, 0x003e, 0x080c, 0xaafc,
+	0x60e3, 0x0000, 0x080c, 0xeb7d, 0x080c, 0xeb98, 0x9085, 0x0001,
+	0x080c, 0x76e9, 0x9006, 0x080c, 0x2abb, 0x2001, 0x1800, 0x2003,
+	0x0004, 0x2001, 0x19a8, 0x2003, 0x0000, 0x0026, 0x2011, 0x0008,
+	0x080c, 0x2af5, 0x002e, 0x00ce, 0x0804, 0x3688, 0x81ff, 0x0120,
+	0x2009, 0x0001, 0x0804, 0x36ba, 0x080c, 0x583a, 0x0120, 0x2009,
+	0x0007, 0x0804, 0x36ba, 0x7984, 0x7ea8, 0x96b4, 0x00ff, 0x080c,
+	0x6789, 0x1904, 0x36bd, 0x9186, 0x007f, 0x0138, 0x080c, 0x6bd5,
+	0x0120, 0x2009, 0x0009, 0x0804, 0x36ba, 0x080c, 0x4bce, 0x1120,
+	0x2009, 0x0002, 0x0804, 0x36ba, 0xa867, 0x0000, 0xa868, 0xc0fd,
+	0xa86a, 0x080c, 0xce04, 0x1120, 0x2009, 0x0003, 0x0804, 0x36ba,
+	0x7007, 0x0003, 0x701f, 0x575d, 0x0005, 0xa830, 0x9086, 0x0100,
+	0x1120, 0x2009, 0x0004, 0x0804, 0x36ba, 0xa8e0, 0xa866, 0xa834,
 	0x8007, 0x800c, 0xa85c, 0x9080, 0x000c, 0x7a8c, 0x7b88, 0x7c9c,
-	0x7d98, 0xaf60, 0x0804, 0x4b3e, 0xa898, 0x9086, 0x000d, 0x1904,
-	0x35ea, 0x2021, 0x4005, 0x0126, 0x2091, 0x8000, 0x0e04, 0x5699,
+	0x7d98, 0xaf60, 0x0804, 0x4c1a, 0xa898, 0x9086, 0x000d, 0x1904,
+	0x36ba, 0x2021, 0x4005, 0x0126, 0x2091, 0x8000, 0x0e04, 0x5781,
 	0x0010, 0x012e, 0x0cc0, 0x7c36, 0x9486, 0x4000, 0x0118, 0x7833,
 	0x0011, 0x0010, 0x7833, 0x0010, 0x7883, 0x4005, 0xa998, 0x7986,
-	0xa9a4, 0x799a, 0xa9a8, 0x799e, 0x080c, 0x4b2e, 0x2091, 0x4080,
-	0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11ee, 0x7007, 0x0001,
+	0xa9a4, 0x799a, 0xa9a8, 0x799e, 0x080c, 0x4c0a, 0x2091, 0x4080,
+	0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x1200, 0x7007, 0x0001,
 	0x2091, 0x5000, 0x700f, 0x0000, 0x012e, 0x0005, 0x0126, 0x2091,
-	0x8000, 0x00c6, 0x2061, 0x1a02, 0x7984, 0x6152, 0x614e, 0x6057,
-	0x0000, 0x604b, 0x0009, 0x7898, 0x606a, 0x789c, 0x6066, 0x7888,
-	0x6062, 0x788c, 0x605e, 0x2001, 0x1a10, 0x2044, 0x2001, 0x1a17,
+	0x8000, 0x00c6, 0x2061, 0x1a05, 0x7984, 0x615a, 0x6156, 0x605f,
+	0x0000, 0x6053, 0x0009, 0x7898, 0x6072, 0x789c, 0x606e, 0x7888,
+	0x606a, 0x788c, 0x6066, 0x2001, 0x1a15, 0x2044, 0x2001, 0x1a1c,
 	0xa076, 0xa060, 0xa072, 0xa07b, 0x0001, 0xa07f, 0x0002, 0xa06b,
-	0x0000, 0xa09f, 0x0000, 0x00ce, 0x012e, 0x0804, 0x35b8, 0x0126,
+	0x0000, 0xa09f, 0x0000, 0x00ce, 0x012e, 0x0804, 0x3688, 0x0126,
 	0x2091, 0x8000, 0x00b6, 0x00c6, 0x90e4, 0xc000, 0x0198, 0x0006,
-	0xd0d4, 0x0160, 0x0036, 0x2019, 0x0029, 0x080c, 0xa91e, 0x0106,
-	0x080c, 0x336d, 0x010e, 0x090c, 0xa93a, 0x003e, 0x080c, 0xc9c7,
+	0xd0d4, 0x0160, 0x0036, 0x2019, 0x0029, 0x080c, 0xaae0, 0x0106,
+	0x080c, 0x343d, 0x010e, 0x090c, 0xaafc, 0x003e, 0x080c, 0xcc63,
 	0x000e, 0x1198, 0xd0e4, 0x0160, 0x9180, 0x1000, 0x2004, 0x905d,
-	0x0160, 0x080c, 0x60ac, 0x080c, 0xabe2, 0x0110, 0xb817, 0x0000,
+	0x0160, 0x080c, 0x6198, 0x080c, 0xae60, 0x0110, 0xb817, 0x0000,
 	0x9006, 0x00ce, 0x00be, 0x012e, 0x0005, 0x9085, 0x0001, 0x0cc8,
 	0x0126, 0x2091, 0x8000, 0x0156, 0x2010, 0x900e, 0x20a9, 0x0800,
 	0x0016, 0x9180, 0x1000, 0x2004, 0x9005, 0x0188, 0x9186, 0x007e,
 	0x0170, 0x9186, 0x007f, 0x0158, 0x9186, 0x0080, 0x0140, 0x9186,
-	0x00ff, 0x0128, 0x0026, 0x2200, 0x080c, 0x56e7, 0x002e, 0x001e,
-	0x8108, 0x1f04, 0x5720, 0x015e, 0x012e, 0x0005, 0x2001, 0x1848,
+	0x00ff, 0x0128, 0x0026, 0x2200, 0x080c, 0x57cf, 0x002e, 0x001e,
+	0x8108, 0x1f04, 0x5808, 0x015e, 0x012e, 0x0005, 0x2001, 0x1848,
 	0x2004, 0x0005, 0x2001, 0x1867, 0x2004, 0x0005, 0x0006, 0x2001,
 	0x1810, 0x2004, 0xd0d4, 0x000e, 0x0005, 0x2001, 0x180e, 0x2004,
 	0xd0b4, 0x0005, 0x2001, 0x1800, 0x2004, 0x9086, 0x0003, 0x0005,
 	0x0016, 0x00e6, 0x2071, 0x189e, 0x7108, 0x910d, 0x710a, 0x00ee,
-	0x001e, 0x0005, 0x79a4, 0x9182, 0x0081, 0x1a04, 0x35ed, 0x810c,
-	0x0016, 0x080c, 0x4af2, 0x0170, 0x080c, 0x0f4f, 0x2100, 0x2238,
-	0x7d84, 0x7c88, 0x7b8c, 0x7a90, 0x001e, 0x080c, 0x4b3b, 0x701f,
-	0x577e, 0x0005, 0x2009, 0x0002, 0x0804, 0x35ea, 0x2079, 0x0000,
-	0x7d94, 0x7c98, 0x7ba8, 0x7aac, 0x79a4, 0x810c, 0x2061, 0x18b8,
-	0x2c44, 0xa770, 0xa074, 0x2071, 0x189e, 0x080c, 0x4b3e, 0x701f,
-	0x5792, 0x0005, 0x2061, 0x18b8, 0x2c44, 0x0016, 0x0026, 0xa270,
-	0xa174, 0x080c, 0x0f57, 0x002e, 0x001e, 0x080c, 0x1004, 0x9006,
-	0xa802, 0xa806, 0x0804, 0x35b8, 0x0126, 0x0156, 0x0136, 0x0146,
-	0x01c6, 0x01d6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2061, 0x0100,
-	0x2069, 0x0200, 0x2071, 0x1800, 0x6044, 0xd0a4, 0x11e8, 0xd084,
-	0x0118, 0x080c, 0x594d, 0x0068, 0xd08c, 0x0118, 0x080c, 0x5856,
-	0x0040, 0xd094, 0x0118, 0x080c, 0x5826, 0x0018, 0xd09c, 0x0108,
-	0x0099, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x01de, 0x01ce, 0x014e,
-	0x013e, 0x015e, 0x012e, 0x0005, 0x0016, 0x6128, 0xd19c, 0x1110,
-	0xc19d, 0x612a, 0x001e, 0x0c68, 0x0006, 0x7098, 0x9005, 0x000e,
-	0x0120, 0x709b, 0x0000, 0x7093, 0x0000, 0x624c, 0x9286, 0xf0f0,
-	0x1150, 0x6048, 0x9086, 0xf0f0, 0x0130, 0x624a, 0x6043, 0x0090,
-	0x6043, 0x0010, 0x0490, 0x9294, 0xff00, 0x9296, 0xf700, 0x0178,
-	0x7138, 0xd1a4, 0x1160, 0x6240, 0x9295, 0x0100, 0x6242, 0x9294,
-	0x0010, 0x0128, 0x2009, 0x00f7, 0x080c, 0x600e, 0x00f0, 0x6040,
-	0x9084, 0x0010, 0x9085, 0x0140, 0x6042, 0x6043, 0x0000, 0x7087,
-	0x0000, 0x70a3, 0x0001, 0x70c7, 0x0000, 0x70df, 0x0000, 0x2009,
-	0x1d80, 0x200b, 0x0000, 0x7097, 0x0000, 0x708b, 0x000f, 0x2009,
-	0x000f, 0x2011, 0x5ef0, 0x080c, 0x8792, 0x0005, 0x2001, 0x1869,
-	0x2004, 0xd08c, 0x0110, 0x705f, 0xffff, 0x7088, 0x9005, 0x1528,
-	0x2011, 0x5ef0, 0x080c, 0x86c8, 0x6040, 0x9094, 0x0010, 0x9285,
-	0x0020, 0x6042, 0x20a9, 0x00c8, 0x6044, 0xd08c, 0x1168, 0x1f04,
-	0x583c, 0x6242, 0x709b, 0x0000, 0x6040, 0x9094, 0x0010, 0x9285,
-	0x0080, 0x6042, 0x6242, 0x0048, 0x6242, 0x709b, 0x0000, 0x708f,
-	0x0000, 0x9006, 0x080c, 0x6097, 0x0000, 0x0005, 0x708c, 0x908a,
-	0x0003, 0x1a0c, 0x0d7d, 0x000b, 0x0005, 0x5860, 0x58b1, 0x594c,
-	0x00f6, 0x0016, 0x6900, 0x918c, 0x0800, 0x708f, 0x0001, 0x2001,
-	0x015d, 0x2003, 0x0000, 0x6803, 0x00fc, 0x20a9, 0x0004, 0x6800,
-	0x9084, 0x00fc, 0x0120, 0x1f04, 0x586f, 0x080c, 0x0d7d, 0x68a0,
-	0x68a2, 0x689c, 0x689e, 0x6898, 0x689a, 0xa001, 0x918d, 0x1600,
-	0x6902, 0x001e, 0x6837, 0x0020, 0x080c, 0x6073, 0x2079, 0x1d00,
-	0x7833, 0x1101, 0x7837, 0x0000, 0x20e1, 0x0001, 0x2099, 0x1805,
-	0x20e9, 0x0001, 0x20a1, 0x1d0e, 0x20a9, 0x0004, 0x4003, 0x080c,
-	0xa713, 0x20e1, 0x0001, 0x2099, 0x1d00, 0x20e9, 0x0000, 0x20a1,
-	0x0240, 0x20a9, 0x0014, 0x4003, 0x60c3, 0x000c, 0x600f, 0x0000,
-	0x080c, 0x5f21, 0x00fe, 0x9006, 0x7092, 0x6043, 0x0008, 0x6042,
-	0x0005, 0x00f6, 0x7090, 0x7093, 0x0000, 0x9025, 0x0904, 0x5929,
-	0x6020, 0xd0b4, 0x1904, 0x5927, 0x71a0, 0x81ff, 0x0904, 0x5915,
-	0x9486, 0x000c, 0x1904, 0x5922, 0x9480, 0x0018, 0x8004, 0x20a8,
-	0x080c, 0x606c, 0x2011, 0x0260, 0x2019, 0x1d00, 0x220c, 0x2304,
-	0x9106, 0x11e8, 0x8210, 0x8318, 0x1f04, 0x58ce, 0x6043, 0x0004,
-	0x2061, 0x0140, 0x605b, 0xbc94, 0x605f, 0xf0f0, 0x2061, 0x0100,
-	0x6043, 0x0006, 0x708f, 0x0002, 0x709b, 0x0002, 0x2009, 0x07d0,
-	0x2011, 0x5ef7, 0x080c, 0x8792, 0x080c, 0x6073, 0x04c0, 0x080c,
-	0x606c, 0x2079, 0x0260, 0x7930, 0x918e, 0x1101, 0x1558, 0x7834,
-	0x9005, 0x1540, 0x7900, 0x918c, 0x00ff, 0x1118, 0x7804, 0x9005,
-	0x0190, 0x080c, 0x606c, 0x2011, 0x026e, 0x2019, 0x1805, 0x20a9,
-	0x0004, 0x220c, 0x2304, 0x9102, 0x0230, 0x11a0, 0x8210, 0x8318,
-	0x1f04, 0x5909, 0x0078, 0x70a3, 0x0000, 0x080c, 0x606c, 0x20e1,
-	0x0000, 0x2099, 0x0260, 0x20e9, 0x0001, 0x20a1, 0x1d00, 0x20a9,
-	0x0014, 0x4003, 0x6043, 0x0008, 0x6043, 0x0000, 0x0010, 0x00fe,
-	0x0005, 0x6040, 0x9085, 0x0100, 0x6042, 0x6020, 0xd0b4, 0x1db8,
-	0x080c, 0xa713, 0x20e1, 0x0001, 0x2099, 0x1d00, 0x20e9, 0x0000,
-	0x20a1, 0x0240, 0x20a9, 0x0014, 0x4003, 0x60c3, 0x000c, 0x2011,
-	0x19f3, 0x2013, 0x0000, 0x7093, 0x0000, 0x60a3, 0x0056, 0x60a7,
-	0x9575, 0x080c, 0x9ec7, 0x08d8, 0x0005, 0x7098, 0x908a, 0x001d,
-	0x1a0c, 0x0d7d, 0x000b, 0x0005, 0x597e, 0x5991, 0x59ba, 0x59da,
-	0x5a00, 0x5a2f, 0x5a55, 0x5a8d, 0x5ab3, 0x5ae1, 0x5b1c, 0x5b54,
-	0x5b72, 0x5b9d, 0x5bbf, 0x5bda, 0x5be4, 0x5c18, 0x5c3e, 0x5c6d,
-	0x5c93, 0x5ccb, 0x5d0f, 0x5d4c, 0x5d6d, 0x5dc6, 0x5de8, 0x5e16,
-	0x5e16, 0x00c6, 0x2061, 0x1800, 0x6003, 0x0007, 0x2061, 0x0100,
-	0x6004, 0x9084, 0xfff9, 0x6006, 0x00ce, 0x0005, 0x2061, 0x0140,
-	0x605b, 0xbc94, 0x605f, 0xf0f0, 0x2061, 0x0100, 0x6043, 0x0002,
-	0x709b, 0x0001, 0x2009, 0x07d0, 0x2011, 0x5ef7, 0x080c, 0x8792,
-	0x0005, 0x00f6, 0x7090, 0x9086, 0x0014, 0x1510, 0x6042, 0x6020,
-	0xd0b4, 0x11f0, 0x080c, 0x606c, 0x2079, 0x0260, 0x7a30, 0x9296,
-	0x1102, 0x11a0, 0x7834, 0x9005, 0x1188, 0x7a38, 0xd2fc, 0x0128,
-	0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, 0x2011, 0x5ef7, 0x080c,
-	0x86c8, 0x709b, 0x0010, 0x080c, 0x5be4, 0x0010, 0x7093, 0x0000,
-	0x00fe, 0x0005, 0x00f6, 0x709b, 0x0003, 0x6043, 0x0004, 0x2011,
-	0x5ef7, 0x080c, 0x86c8, 0x080c, 0x5ff0, 0x2079, 0x0240, 0x7833,
-	0x1102, 0x7837, 0x0000, 0x20a9, 0x0008, 0x9f88, 0x000e, 0x200b,
-	0x0000, 0x8108, 0x1f04, 0x59cf, 0x60c3, 0x0014, 0x080c, 0x5f21,
-	0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005, 0x0500, 0x2011, 0x5ef7,
-	0x080c, 0x86c8, 0x9086, 0x0014, 0x11b8, 0x080c, 0x606c, 0x2079,
-	0x0260, 0x7a30, 0x9296, 0x1102, 0x1178, 0x7834, 0x9005, 0x1160,
-	0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001,
-	0x709b, 0x0004, 0x0029, 0x0010, 0x080c, 0x6048, 0x00fe, 0x0005,
-	0x00f6, 0x709b, 0x0005, 0x080c, 0x5ff0, 0x2079, 0x0240, 0x7833,
-	0x1103, 0x7837, 0x0000, 0x080c, 0x606c, 0x080c, 0x604f, 0x1170,
-	0x7084, 0x9005, 0x1158, 0x715c, 0x9186, 0xffff, 0x0138, 0x2011,
-	0x0008, 0x080c, 0x5ea4, 0x0168, 0x080c, 0x6025, 0x20a9, 0x0008,
+	0x001e, 0x0005, 0x79a4, 0x81ff, 0x0904, 0x36bd, 0x9182, 0x0081,
+	0x1a04, 0x36bd, 0x810c, 0x0016, 0x080c, 0x4bce, 0x0170, 0x080c,
+	0x0f61, 0x2100, 0x2238, 0x7d84, 0x7c88, 0x7b8c, 0x7a90, 0x001e,
+	0x080c, 0x4c17, 0x701f, 0x586a, 0x0005, 0x001e, 0x2009, 0x0002,
+	0x0804, 0x36ba, 0x2079, 0x0000, 0x7d94, 0x7c98, 0x7ba8, 0x7aac,
+	0x79a4, 0x810c, 0x2061, 0x18b8, 0x2c44, 0xa770, 0xa074, 0x2071,
+	0x189e, 0x080c, 0x4c1a, 0x701f, 0x587e, 0x0005, 0x2061, 0x18b8,
+	0x2c44, 0x0016, 0x0026, 0xa270, 0xa174, 0x080c, 0x0f69, 0x002e,
+	0x001e, 0x080c, 0x1016, 0x9006, 0xa802, 0xa806, 0x0804, 0x3688,
+	0x0126, 0x0156, 0x0136, 0x0146, 0x01c6, 0x01d6, 0x00c6, 0x00d6,
+	0x00e6, 0x00f6, 0x2061, 0x0100, 0x2069, 0x0200, 0x2071, 0x1800,
+	0x6044, 0xd0a4, 0x11e8, 0xd084, 0x0118, 0x080c, 0x5a39, 0x0068,
+	0xd08c, 0x0118, 0x080c, 0x5942, 0x0040, 0xd094, 0x0118, 0x080c,
+	0x5912, 0x0018, 0xd09c, 0x0108, 0x0099, 0x00fe, 0x00ee, 0x00de,
+	0x00ce, 0x01de, 0x01ce, 0x014e, 0x013e, 0x015e, 0x012e, 0x0005,
+	0x0016, 0x6128, 0xd19c, 0x1110, 0xc19d, 0x612a, 0x001e, 0x0c68,
+	0x0006, 0x7098, 0x9005, 0x000e, 0x0120, 0x709b, 0x0000, 0x7093,
+	0x0000, 0x624c, 0x9286, 0xf0f0, 0x1150, 0x6048, 0x9086, 0xf0f0,
+	0x0130, 0x624a, 0x6043, 0x0090, 0x6043, 0x0010, 0x0490, 0x9294,
+	0xff00, 0x9296, 0xf700, 0x0178, 0x7138, 0xd1a4, 0x1160, 0x6240,
+	0x9295, 0x0100, 0x6242, 0x9294, 0x0010, 0x0128, 0x2009, 0x00f7,
+	0x080c, 0x60fa, 0x00f0, 0x6040, 0x9084, 0x0010, 0x9085, 0x0140,
+	0x6042, 0x6043, 0x0000, 0x7087, 0x0000, 0x70a3, 0x0001, 0x70c7,
+	0x0000, 0x70df, 0x0000, 0x2009, 0x1d80, 0x200b, 0x0000, 0x7097,
+	0x0000, 0x708b, 0x000f, 0x2009, 0x000f, 0x2011, 0x5fdc, 0x080c,
+	0x88fe, 0x0005, 0x2001, 0x1869, 0x2004, 0xd08c, 0x0110, 0x705f,
+	0xffff, 0x7088, 0x9005, 0x1528, 0x2011, 0x5fdc, 0x080c, 0x8834,
+	0x6040, 0x9094, 0x0010, 0x9285, 0x0020, 0x6042, 0x20a9, 0x00c8,
+	0x6044, 0xd08c, 0x1168, 0x1f04, 0x5928, 0x6242, 0x709b, 0x0000,
+	0x6040, 0x9094, 0x0010, 0x9285, 0x0080, 0x6042, 0x6242, 0x0048,
+	0x6242, 0x709b, 0x0000, 0x708f, 0x0000, 0x9006, 0x080c, 0x6183,
+	0x0000, 0x0005, 0x708c, 0x908a, 0x0003, 0x1a0c, 0x0d85, 0x000b,
+	0x0005, 0x594c, 0x599d, 0x5a38, 0x00f6, 0x0016, 0x6900, 0x918c,
+	0x0800, 0x708f, 0x0001, 0x2001, 0x015d, 0x2003, 0x0000, 0x6803,
+	0x00fc, 0x20a9, 0x0004, 0x6800, 0x9084, 0x00fc, 0x0120, 0x1f04,
+	0x595b, 0x080c, 0x0d85, 0x68a0, 0x68a2, 0x689c, 0x689e, 0x6898,
+	0x689a, 0xa001, 0x918d, 0x1600, 0x6902, 0x001e, 0x6837, 0x0020,
+	0x080c, 0x615f, 0x2079, 0x1d00, 0x7833, 0x1101, 0x7837, 0x0000,
+	0x20e1, 0x0001, 0x2099, 0x1805, 0x20e9, 0x0001, 0x20a1, 0x1d0e,
+	0x20a9, 0x0004, 0x4003, 0x080c, 0xa8d5, 0x20e1, 0x0001, 0x2099,
+	0x1d00, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, 0x0014, 0x4003,
+	0x60c3, 0x000c, 0x600f, 0x0000, 0x080c, 0x600d, 0x00fe, 0x9006,
+	0x7092, 0x6043, 0x0008, 0x6042, 0x0005, 0x00f6, 0x7090, 0x7093,
+	0x0000, 0x9025, 0x0904, 0x5a15, 0x6020, 0xd0b4, 0x1904, 0x5a13,
+	0x71a0, 0x81ff, 0x0904, 0x5a01, 0x9486, 0x000c, 0x1904, 0x5a0e,
+	0x9480, 0x0018, 0x8004, 0x20a8, 0x080c, 0x6158, 0x2011, 0x0260,
+	0x2019, 0x1d00, 0x220c, 0x2304, 0x9106, 0x11e8, 0x8210, 0x8318,
+	0x1f04, 0x59ba, 0x6043, 0x0004, 0x2061, 0x0140, 0x605b, 0xbc94,
+	0x605f, 0xf0f0, 0x2061, 0x0100, 0x6043, 0x0006, 0x708f, 0x0002,
+	0x709b, 0x0002, 0x2009, 0x07d0, 0x2011, 0x5fe3, 0x080c, 0x88fe,
+	0x080c, 0x615f, 0x04c0, 0x080c, 0x6158, 0x2079, 0x0260, 0x7930,
+	0x918e, 0x1101, 0x1558, 0x7834, 0x9005, 0x1540, 0x7900, 0x918c,
+	0x00ff, 0x1118, 0x7804, 0x9005, 0x0190, 0x080c, 0x6158, 0x2011,
+	0x026e, 0x2019, 0x1805, 0x20a9, 0x0004, 0x220c, 0x2304, 0x9102,
+	0x0230, 0x11a0, 0x8210, 0x8318, 0x1f04, 0x59f5, 0x0078, 0x70a3,
+	0x0000, 0x080c, 0x6158, 0x20e1, 0x0000, 0x2099, 0x0260, 0x20e9,
+	0x0001, 0x20a1, 0x1d00, 0x20a9, 0x0014, 0x4003, 0x6043, 0x0008,
+	0x6043, 0x0000, 0x0010, 0x00fe, 0x0005, 0x6040, 0x9085, 0x0100,
+	0x6042, 0x6020, 0xd0b4, 0x1db8, 0x080c, 0xa8d5, 0x20e1, 0x0001,
+	0x2099, 0x1d00, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, 0x0014,
+	0x4003, 0x60c3, 0x000c, 0x2011, 0x19f6, 0x2013, 0x0000, 0x7093,
+	0x0000, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x080c, 0xa07d, 0x08d8,
+	0x0005, 0x7098, 0x908a, 0x001d, 0x1a0c, 0x0d85, 0x000b, 0x0005,
+	0x5a6a, 0x5a7d, 0x5aa6, 0x5ac6, 0x5aec, 0x5b1b, 0x5b41, 0x5b79,
+	0x5b9f, 0x5bcd, 0x5c08, 0x5c40, 0x5c5e, 0x5c89, 0x5cab, 0x5cc6,
+	0x5cd0, 0x5d04, 0x5d2a, 0x5d59, 0x5d7f, 0x5db7, 0x5dfb, 0x5e38,
+	0x5e59, 0x5eb2, 0x5ed4, 0x5f02, 0x5f02, 0x00c6, 0x2061, 0x1800,
+	0x6003, 0x0007, 0x2061, 0x0100, 0x6004, 0x9084, 0xfff9, 0x6006,
+	0x00ce, 0x0005, 0x2061, 0x0140, 0x605b, 0xbc94, 0x605f, 0xf0f0,
+	0x2061, 0x0100, 0x6043, 0x0002, 0x709b, 0x0001, 0x2009, 0x07d0,
+	0x2011, 0x5fe3, 0x080c, 0x88fe, 0x0005, 0x00f6, 0x7090, 0x9086,
+	0x0014, 0x1510, 0x6042, 0x6020, 0xd0b4, 0x11f0, 0x080c, 0x6158,
+	0x2079, 0x0260, 0x7a30, 0x9296, 0x1102, 0x11a0, 0x7834, 0x9005,
+	0x1188, 0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7,
+	0x0001, 0x2011, 0x5fe3, 0x080c, 0x8834, 0x709b, 0x0010, 0x080c,
+	0x5cd0, 0x0010, 0x7093, 0x0000, 0x00fe, 0x0005, 0x00f6, 0x709b,
+	0x0003, 0x6043, 0x0004, 0x2011, 0x5fe3, 0x080c, 0x8834, 0x080c,
+	0x60dc, 0x2079, 0x0240, 0x7833, 0x1102, 0x7837, 0x0000, 0x20a9,
+	0x0008, 0x9f88, 0x000e, 0x200b, 0x0000, 0x8108, 0x1f04, 0x5abb,
+	0x60c3, 0x0014, 0x080c, 0x600d, 0x00fe, 0x0005, 0x00f6, 0x7090,
+	0x9005, 0x0500, 0x2011, 0x5fe3, 0x080c, 0x8834, 0x9086, 0x0014,
+	0x11b8, 0x080c, 0x6158, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1102,
+	0x1178, 0x7834, 0x9005, 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c4,
+	0x9005, 0x1110, 0x70c7, 0x0001, 0x709b, 0x0004, 0x0029, 0x0010,
+	0x080c, 0x6134, 0x00fe, 0x0005, 0x00f6, 0x709b, 0x0005, 0x080c,
+	0x60dc, 0x2079, 0x0240, 0x7833, 0x1103, 0x7837, 0x0000, 0x080c,
+	0x6158, 0x080c, 0x613b, 0x1170, 0x7084, 0x9005, 0x1158, 0x715c,
+	0x9186, 0xffff, 0x0138, 0x2011, 0x0008, 0x080c, 0x5f90, 0x0168,
+	0x080c, 0x6111, 0x20a9, 0x0008, 0x20e1, 0x0000, 0x2099, 0x026e,
+	0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003, 0x60c3, 0x0014, 0x080c,
+	0x600d, 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005, 0x0500, 0x2011,
+	0x5fe3, 0x080c, 0x8834, 0x9086, 0x0014, 0x11b8, 0x080c, 0x6158,
+	0x2079, 0x0260, 0x7a30, 0x9296, 0x1103, 0x1178, 0x7834, 0x9005,
+	0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7,
+	0x0001, 0x709b, 0x0006, 0x0029, 0x0010, 0x080c, 0x6134, 0x00fe,
+	0x0005, 0x00f6, 0x709b, 0x0007, 0x080c, 0x60dc, 0x2079, 0x0240,
+	0x7833, 0x1104, 0x7837, 0x0000, 0x080c, 0x6158, 0x080c, 0x613b,
+	0x11b8, 0x7084, 0x9005, 0x11a0, 0x7164, 0x9186, 0xffff, 0x0180,
+	0x9180, 0x3489, 0x200d, 0x918c, 0xff00, 0x810f, 0x2011, 0x0008,
+	0x080c, 0x5f90, 0x0180, 0x080c, 0x5114, 0x0110, 0x080c, 0x270b,
+	0x20a9, 0x0008, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000,
+	0x20a1, 0x024e, 0x4003, 0x60c3, 0x0014, 0x080c, 0x600d, 0x00fe,
+	0x0005, 0x00f6, 0x7090, 0x9005, 0x0500, 0x2011, 0x5fe3, 0x080c,
+	0x8834, 0x9086, 0x0014, 0x11b8, 0x080c, 0x6158, 0x2079, 0x0260,
+	0x7a30, 0x9296, 0x1104, 0x1178, 0x7834, 0x9005, 0x1160, 0x7a38,
+	0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, 0x709b,
+	0x0008, 0x0029, 0x0010, 0x080c, 0x6134, 0x00fe, 0x0005, 0x00f6,
+	0x709b, 0x0009, 0x080c, 0x60dc, 0x2079, 0x0240, 0x7833, 0x1105,
+	0x7837, 0x0100, 0x080c, 0x613b, 0x1150, 0x7084, 0x9005, 0x1138,
+	0x080c, 0x5f03, 0x1188, 0x9085, 0x0001, 0x080c, 0x270b, 0x20a9,
+	0x0008, 0x080c, 0x6158, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9,
+	0x0000, 0x20a1, 0x024e, 0x4003, 0x60c3, 0x0014, 0x080c, 0x600d,
+	0x0010, 0x080c, 0x5a5d, 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005,
+	0x05a8, 0x2011, 0x5fe3, 0x080c, 0x8834, 0x9086, 0x0014, 0x1560,
+	0x080c, 0x6158, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1105, 0x1520,
+	0x7834, 0x9084, 0x0100, 0x2011, 0x0100, 0x921e, 0x1160, 0x7a38,
+	0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, 0x709b,
+	0x000a, 0x00b1, 0x0098, 0x9005, 0x1178, 0x7a38, 0xd2fc, 0x0128,
+	0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, 0x7097, 0x0000, 0x709b,
+	0x000e, 0x080c, 0x5cab, 0x0010, 0x080c, 0x6134, 0x00fe, 0x0005,
+	0x00f6, 0x709b, 0x000b, 0x2011, 0x1d0e, 0x20e9, 0x0001, 0x22a0,
+	0x20a9, 0x0040, 0x2019, 0xffff, 0x4304, 0x080c, 0x60dc, 0x2079,
+	0x0240, 0x7833, 0x1106, 0x7837, 0x0000, 0x080c, 0x613b, 0x0118,
+	0x2013, 0x0000, 0x0020, 0x7060, 0x9085, 0x0100, 0x2012, 0x20a9,
+	0x0040, 0x2009, 0x024e, 0x2011, 0x1d0e, 0x220e, 0x8210, 0x8108,
+	0x9186, 0x0260, 0x1128, 0x6810, 0x8000, 0x6812, 0x2009, 0x0240,
+	0x1f04, 0x5c2d, 0x60c3, 0x0084, 0x080c, 0x600d, 0x00fe, 0x0005,
+	0x00f6, 0x7090, 0x9005, 0x01c0, 0x2011, 0x5fe3, 0x080c, 0x8834,
+	0x9086, 0x0084, 0x1178, 0x080c, 0x6158, 0x2079, 0x0260, 0x7a30,
+	0x9296, 0x1106, 0x1138, 0x7834, 0x9005, 0x1120, 0x709b, 0x000c,
+	0x0029, 0x0010, 0x080c, 0x6134, 0x00fe, 0x0005, 0x00f6, 0x709b,
+	0x000d, 0x080c, 0x60dc, 0x2079, 0x0240, 0x7833, 0x1107, 0x7837,
+	0x0000, 0x080c, 0x6158, 0x20a9, 0x0040, 0x2011, 0x026e, 0x2009,
+	0x024e, 0x220e, 0x8210, 0x8108, 0x9186, 0x0260, 0x1150, 0x6810,
+	0x8000, 0x6812, 0x2009, 0x0240, 0x6814, 0x8000, 0x6816, 0x2011,
+	0x0260, 0x1f04, 0x5c71, 0x60c3, 0x0084, 0x080c, 0x600d, 0x00fe,
+	0x0005, 0x00f6, 0x7090, 0x9005, 0x01e0, 0x2011, 0x5fe3, 0x080c,
+	0x8834, 0x9086, 0x0084, 0x1198, 0x080c, 0x6158, 0x2079, 0x0260,
+	0x7a30, 0x9296, 0x1107, 0x1158, 0x7834, 0x9005, 0x1140, 0x7097,
+	0x0001, 0x080c, 0x60ae, 0x709b, 0x000e, 0x0029, 0x0010, 0x080c,
+	0x6134, 0x00fe, 0x0005, 0x918d, 0x0001, 0x080c, 0x6183, 0x709b,
+	0x000f, 0x7093, 0x0000, 0x2061, 0x0140, 0x605b, 0xbc85, 0x605f,
+	0xb5b5, 0x2061, 0x0100, 0x6043, 0x0005, 0x6043, 0x0004, 0x2009,
+	0x07d0, 0x2011, 0x5fe3, 0x080c, 0x8828, 0x0005, 0x7090, 0x9005,
+	0x0130, 0x2011, 0x5fe3, 0x080c, 0x8834, 0x709b, 0x0000, 0x0005,
+	0x709b, 0x0011, 0x080c, 0xa8d5, 0x080c, 0x6158, 0x20e1, 0x0000,
+	0x2099, 0x0260, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x7490, 0x9480,
+	0x0018, 0x9080, 0x0007, 0x9084, 0x03f8, 0x8004, 0x20a8, 0x4003,
+	0x080c, 0x613b, 0x11a0, 0x717c, 0x81ff, 0x0188, 0x900e, 0x7080,
+	0x9084, 0x00ff, 0x0160, 0x080c, 0x26a2, 0x9186, 0x007e, 0x0138,
+	0x9186, 0x0080, 0x0120, 0x2011, 0x0008, 0x080c, 0x5f90, 0x60c3,
+	0x0014, 0x080c, 0x600d, 0x0005, 0x00f6, 0x7090, 0x9005, 0x0500,
+	0x2011, 0x5fe3, 0x080c, 0x8834, 0x9086, 0x0014, 0x11b8, 0x080c,
+	0x6158, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1103, 0x1178, 0x7834,
+	0x9005, 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110,
+	0x70c7, 0x0001, 0x709b, 0x0012, 0x0029, 0x0010, 0x7093, 0x0000,
+	0x00fe, 0x0005, 0x00f6, 0x709b, 0x0013, 0x080c, 0x60ea, 0x2079,
+	0x0240, 0x7833, 0x1103, 0x7837, 0x0000, 0x080c, 0x6158, 0x080c,
+	0x613b, 0x1170, 0x7084, 0x9005, 0x1158, 0x715c, 0x9186, 0xffff,
+	0x0138, 0x2011, 0x0008, 0x080c, 0x5f90, 0x0168, 0x080c, 0x6111,
+	0x20a9, 0x0008, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000,
+	0x20a1, 0x024e, 0x4003, 0x60c3, 0x0014, 0x080c, 0x600d, 0x00fe,
+	0x0005, 0x00f6, 0x7090, 0x9005, 0x0500, 0x2011, 0x5fe3, 0x080c,
+	0x8834, 0x9086, 0x0014, 0x11b8, 0x080c, 0x6158, 0x2079, 0x0260,
+	0x7a30, 0x9296, 0x1104, 0x1178, 0x7834, 0x9005, 0x1160, 0x7a38,
+	0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, 0x709b,
+	0x0014, 0x0029, 0x0010, 0x7093, 0x0000, 0x00fe, 0x0005, 0x00f6,
+	0x709b, 0x0015, 0x080c, 0x60ea, 0x2079, 0x0240, 0x7833, 0x1104,
+	0x7837, 0x0000, 0x080c, 0x6158, 0x080c, 0x613b, 0x11b8, 0x7084,
+	0x9005, 0x11a0, 0x7164, 0x9186, 0xffff, 0x0180, 0x9180, 0x3489,
+	0x200d, 0x918c, 0xff00, 0x810f, 0x2011, 0x0008, 0x080c, 0x5f90,
+	0x0180, 0x080c, 0x5114, 0x0110, 0x080c, 0x270b, 0x20a9, 0x0008,
 	0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e,
-	0x4003, 0x60c3, 0x0014, 0x080c, 0x5f21, 0x00fe, 0x0005, 0x00f6,
-	0x7090, 0x9005, 0x0500, 0x2011, 0x5ef7, 0x080c, 0x86c8, 0x9086,
-	0x0014, 0x11b8, 0x080c, 0x606c, 0x2079, 0x0260, 0x7a30, 0x9296,
-	0x1103, 0x1178, 0x7834, 0x9005, 0x1160, 0x7a38, 0xd2fc, 0x0128,
-	0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, 0x709b, 0x0006, 0x0029,
-	0x0010, 0x080c, 0x6048, 0x00fe, 0x0005, 0x00f6, 0x709b, 0x0007,
-	0x080c, 0x5ff0, 0x2079, 0x0240, 0x7833, 0x1104, 0x7837, 0x0000,
-	0x080c, 0x606c, 0x080c, 0x604f, 0x11b8, 0x7084, 0x9005, 0x11a0,
-	0x7164, 0x9186, 0xffff, 0x0180, 0x9180, 0x33b9, 0x200d, 0x918c,
-	0xff00, 0x810f, 0x2011, 0x0008, 0x080c, 0x5ea4, 0x0180, 0x080c,
-	0x502d, 0x0110, 0x080c, 0x26ca, 0x20a9, 0x0008, 0x20e1, 0x0000,
-	0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003, 0x60c3,
-	0x0014, 0x080c, 0x5f21, 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005,
-	0x0500, 0x2011, 0x5ef7, 0x080c, 0x86c8, 0x9086, 0x0014, 0x11b8,
-	0x080c, 0x606c, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1104, 0x1178,
-	0x7834, 0x9005, 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005,
-	0x1110, 0x70c7, 0x0001, 0x709b, 0x0008, 0x0029, 0x0010, 0x080c,
-	0x6048, 0x00fe, 0x0005, 0x00f6, 0x709b, 0x0009, 0x080c, 0x5ff0,
-	0x2079, 0x0240, 0x7833, 0x1105, 0x7837, 0x0100, 0x080c, 0x604f,
-	0x1150, 0x7084, 0x9005, 0x1138, 0x080c, 0x5e17, 0x1188, 0x9085,
-	0x0001, 0x080c, 0x26ca, 0x20a9, 0x0008, 0x080c, 0x606c, 0x20e1,
+	0x4003, 0x60c3, 0x0014, 0x080c, 0x600d, 0x00fe, 0x0005, 0x00f6,
+	0x7090, 0x9005, 0x05f0, 0x2011, 0x5fe3, 0x080c, 0x8834, 0x9086,
+	0x0014, 0x15a8, 0x080c, 0x6158, 0x2079, 0x0260, 0x7a30, 0x9296,
+	0x1105, 0x1568, 0x7834, 0x9084, 0x0100, 0x2011, 0x0100, 0x921e,
+	0x1168, 0x9085, 0x0001, 0x080c, 0x6183, 0x7a38, 0xd2fc, 0x0128,
+	0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, 0x0080, 0x9005, 0x11b8,
+	0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001,
+	0x9085, 0x0001, 0x080c, 0x6183, 0x7097, 0x0000, 0x7a38, 0xd2f4,
+	0x0110, 0x70df, 0x0008, 0x709b, 0x0016, 0x0029, 0x0010, 0x7093,
+	0x0000, 0x00fe, 0x0005, 0x080c, 0xa8d5, 0x080c, 0x6158, 0x20e1,
+	0x0000, 0x2099, 0x0260, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9,
+	0x000e, 0x4003, 0x2011, 0x026d, 0x2204, 0x9084, 0x0100, 0x2011,
+	0x024d, 0x2012, 0x2011, 0x026e, 0x709b, 0x0017, 0x080c, 0x613b,
+	0x1150, 0x7084, 0x9005, 0x1138, 0x080c, 0x5f03, 0x1188, 0x9085,
+	0x0001, 0x080c, 0x270b, 0x20a9, 0x0008, 0x080c, 0x6158, 0x20e1,
 	0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003,
-	0x60c3, 0x0014, 0x080c, 0x5f21, 0x0010, 0x080c, 0x5971, 0x00fe,
-	0x0005, 0x00f6, 0x7090, 0x9005, 0x05a8, 0x2011, 0x5ef7, 0x080c,
-	0x86c8, 0x9086, 0x0014, 0x1560, 0x080c, 0x606c, 0x2079, 0x0260,
-	0x7a30, 0x9296, 0x1105, 0x1520, 0x7834, 0x9084, 0x0100, 0x2011,
-	0x0100, 0x921e, 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005,
-	0x1110, 0x70c7, 0x0001, 0x709b, 0x000a, 0x00b1, 0x0098, 0x9005,
-	0x1178, 0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7,
-	0x0001, 0x7097, 0x0000, 0x709b, 0x000e, 0x080c, 0x5bbf, 0x0010,
-	0x080c, 0x6048, 0x00fe, 0x0005, 0x00f6, 0x709b, 0x000b, 0x2011,
-	0x1d0e, 0x20e9, 0x0001, 0x22a0, 0x20a9, 0x0040, 0x2019, 0xffff,
-	0x4304, 0x080c, 0x5ff0, 0x2079, 0x0240, 0x7833, 0x1106, 0x7837,
-	0x0000, 0x080c, 0x604f, 0x0118, 0x2013, 0x0000, 0x0020, 0x7060,
-	0x9085, 0x0100, 0x2012, 0x20a9, 0x0040, 0x2009, 0x024e, 0x2011,
-	0x1d0e, 0x220e, 0x8210, 0x8108, 0x9186, 0x0260, 0x1128, 0x6810,
-	0x8000, 0x6812, 0x2009, 0x0240, 0x1f04, 0x5b41, 0x60c3, 0x0084,
-	0x080c, 0x5f21, 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005, 0x01c0,
-	0x2011, 0x5ef7, 0x080c, 0x86c8, 0x9086, 0x0084, 0x1178, 0x080c,
-	0x606c, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1106, 0x1138, 0x7834,
-	0x9005, 0x1120, 0x709b, 0x000c, 0x0029, 0x0010, 0x080c, 0x6048,
-	0x00fe, 0x0005, 0x00f6, 0x709b, 0x000d, 0x080c, 0x5ff0, 0x2079,
-	0x0240, 0x7833, 0x1107, 0x7837, 0x0000, 0x080c, 0x606c, 0x20a9,
-	0x0040, 0x2011, 0x026e, 0x2009, 0x024e, 0x220e, 0x8210, 0x8108,
-	0x9186, 0x0260, 0x1150, 0x6810, 0x8000, 0x6812, 0x2009, 0x0240,
-	0x6814, 0x8000, 0x6816, 0x2011, 0x0260, 0x1f04, 0x5b85, 0x60c3,
-	0x0084, 0x080c, 0x5f21, 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005,
-	0x01e0, 0x2011, 0x5ef7, 0x080c, 0x86c8, 0x9086, 0x0084, 0x1198,
-	0x080c, 0x606c, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1107, 0x1158,
-	0x7834, 0x9005, 0x1140, 0x7097, 0x0001, 0x080c, 0x5fc2, 0x709b,
-	0x000e, 0x0029, 0x0010, 0x080c, 0x6048, 0x00fe, 0x0005, 0x918d,
-	0x0001, 0x080c, 0x6097, 0x709b, 0x000f, 0x7093, 0x0000, 0x2061,
-	0x0140, 0x605b, 0xbc85, 0x605f, 0xb5b5, 0x2061, 0x0100, 0x6043,
-	0x0005, 0x6043, 0x0004, 0x2009, 0x07d0, 0x2011, 0x5ef7, 0x080c,
-	0x86bc, 0x0005, 0x7090, 0x9005, 0x0130, 0x2011, 0x5ef7, 0x080c,
-	0x86c8, 0x709b, 0x0000, 0x0005, 0x709b, 0x0011, 0x080c, 0xa713,
-	0x080c, 0x606c, 0x20e1, 0x0000, 0x2099, 0x0260, 0x20e9, 0x0000,
-	0x20a1, 0x0240, 0x7490, 0x9480, 0x0018, 0x9080, 0x0007, 0x9084,
-	0x03f8, 0x8004, 0x20a8, 0x4003, 0x080c, 0x604f, 0x11a0, 0x717c,
-	0x81ff, 0x0188, 0x900e, 0x7080, 0x9084, 0x00ff, 0x0160, 0x080c,
-	0x2661, 0x9186, 0x007e, 0x0138, 0x9186, 0x0080, 0x0120, 0x2011,
-	0x0008, 0x080c, 0x5ea4, 0x60c3, 0x0014, 0x080c, 0x5f21, 0x0005,
-	0x00f6, 0x7090, 0x9005, 0x0500, 0x2011, 0x5ef7, 0x080c, 0x86c8,
-	0x9086, 0x0014, 0x11b8, 0x080c, 0x606c, 0x2079, 0x0260, 0x7a30,
-	0x9296, 0x1103, 0x1178, 0x7834, 0x9005, 0x1160, 0x7a38, 0xd2fc,
-	0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7, 0x0001, 0x709b, 0x0012,
-	0x0029, 0x0010, 0x7093, 0x0000, 0x00fe, 0x0005, 0x00f6, 0x709b,
-	0x0013, 0x080c, 0x5ffe, 0x2079, 0x0240, 0x7833, 0x1103, 0x7837,
-	0x0000, 0x080c, 0x606c, 0x080c, 0x604f, 0x1170, 0x7084, 0x9005,
-	0x1158, 0x715c, 0x9186, 0xffff, 0x0138, 0x2011, 0x0008, 0x080c,
-	0x5ea4, 0x0168, 0x080c, 0x6025, 0x20a9, 0x0008, 0x20e1, 0x0000,
-	0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003, 0x60c3,
-	0x0014, 0x080c, 0x5f21, 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005,
-	0x0500, 0x2011, 0x5ef7, 0x080c, 0x86c8, 0x9086, 0x0014, 0x11b8,
-	0x080c, 0x606c, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1104, 0x1178,
-	0x7834, 0x9005, 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005,
-	0x1110, 0x70c7, 0x0001, 0x709b, 0x0014, 0x0029, 0x0010, 0x7093,
-	0x0000, 0x00fe, 0x0005, 0x00f6, 0x709b, 0x0015, 0x080c, 0x5ffe,
-	0x2079, 0x0240, 0x7833, 0x1104, 0x7837, 0x0000, 0x080c, 0x606c,
-	0x080c, 0x604f, 0x11b8, 0x7084, 0x9005, 0x11a0, 0x7164, 0x9186,
-	0xffff, 0x0180, 0x9180, 0x33b9, 0x200d, 0x918c, 0xff00, 0x810f,
-	0x2011, 0x0008, 0x080c, 0x5ea4, 0x0180, 0x080c, 0x502d, 0x0110,
-	0x080c, 0x26ca, 0x20a9, 0x0008, 0x20e1, 0x0000, 0x2099, 0x026e,
-	0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003, 0x60c3, 0x0014, 0x080c,
-	0x5f21, 0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005, 0x05f0, 0x2011,
-	0x5ef7, 0x080c, 0x86c8, 0x9086, 0x0014, 0x15a8, 0x080c, 0x606c,
-	0x2079, 0x0260, 0x7a30, 0x9296, 0x1105, 0x1568, 0x7834, 0x9084,
-	0x0100, 0x2011, 0x0100, 0x921e, 0x1168, 0x9085, 0x0001, 0x080c,
-	0x6097, 0x7a38, 0xd2fc, 0x0128, 0x70c4, 0x9005, 0x1110, 0x70c7,
-	0x0001, 0x0080, 0x9005, 0x11b8, 0x7a38, 0xd2fc, 0x0128, 0x70c4,
-	0x9005, 0x1110, 0x70c7, 0x0001, 0x9085, 0x0001, 0x080c, 0x6097,
-	0x7097, 0x0000, 0x7a38, 0xd2f4, 0x0110, 0x70df, 0x0008, 0x709b,
-	0x0016, 0x0029, 0x0010, 0x7093, 0x0000, 0x00fe, 0x0005, 0x080c,
-	0xa713, 0x080c, 0x606c, 0x20e1, 0x0000, 0x2099, 0x0260, 0x20e9,
-	0x0000, 0x20a1, 0x0240, 0x20a9, 0x000e, 0x4003, 0x2011, 0x026d,
-	0x2204, 0x9084, 0x0100, 0x2011, 0x024d, 0x2012, 0x2011, 0x026e,
-	0x709b, 0x0017, 0x080c, 0x604f, 0x1150, 0x7084, 0x9005, 0x1138,
-	0x080c, 0x5e17, 0x1188, 0x9085, 0x0001, 0x080c, 0x26ca, 0x20a9,
-	0x0008, 0x080c, 0x606c, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9,
-	0x0000, 0x20a1, 0x024e, 0x4003, 0x60c3, 0x0014, 0x080c, 0x5f21,
-	0x0010, 0x080c, 0x5971, 0x0005, 0x00f6, 0x7090, 0x9005, 0x01d8,
-	0x2011, 0x5ef7, 0x080c, 0x86c8, 0x9086, 0x0084, 0x1190, 0x080c,
-	0x606c, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1106, 0x1150, 0x7834,
-	0x9005, 0x1138, 0x9006, 0x080c, 0x6097, 0x709b, 0x0018, 0x0029,
-	0x0010, 0x7093, 0x0000, 0x00fe, 0x0005, 0x00f6, 0x709b, 0x0019,
-	0x080c, 0x5ffe, 0x2079, 0x0240, 0x7833, 0x1106, 0x7837, 0x0000,
-	0x080c, 0x606c, 0x2009, 0x026e, 0x2039, 0x1d0e, 0x20a9, 0x0040,
-	0x213e, 0x8738, 0x8108, 0x9186, 0x0280, 0x1128, 0x6814, 0x8000,
-	0x6816, 0x2009, 0x0260, 0x1f04, 0x5d80, 0x2039, 0x1d0e, 0x080c,
-	0x604f, 0x11e8, 0x2728, 0x2514, 0x8207, 0x9084, 0x00ff, 0x8000,
-	0x2018, 0x9294, 0x00ff, 0x8007, 0x9205, 0x202a, 0x7060, 0x2310,
-	0x8214, 0x92a0, 0x1d0e, 0x2414, 0x938c, 0x0001, 0x0118, 0x9294,
-	0xff00, 0x0018, 0x9294, 0x00ff, 0x8007, 0x9215, 0x2222, 0x20a9,
-	0x0040, 0x2009, 0x024e, 0x270e, 0x8738, 0x8108, 0x9186, 0x0260,
-	0x1128, 0x6810, 0x8000, 0x6812, 0x2009, 0x0240, 0x1f04, 0x5db3,
-	0x60c3, 0x0084, 0x080c, 0x5f21, 0x00fe, 0x0005, 0x00f6, 0x7090,
-	0x9005, 0x01e0, 0x2011, 0x5ef7, 0x080c, 0x86c8, 0x9086, 0x0084,
-	0x1198, 0x080c, 0x606c, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1107,
-	0x1158, 0x7834, 0x9005, 0x1140, 0x7097, 0x0001, 0x080c, 0x5fc2,
-	0x709b, 0x001a, 0x0029, 0x0010, 0x7093, 0x0000, 0x00fe, 0x0005,
-	0x9085, 0x0001, 0x080c, 0x6097, 0x709b, 0x001b, 0x080c, 0xa713,
-	0x080c, 0x606c, 0x2011, 0x0260, 0x2009, 0x0240, 0x7490, 0x9480,
-	0x0018, 0x9080, 0x0007, 0x9084, 0x03f8, 0x8004, 0x20a8, 0x220e,
-	0x8210, 0x8108, 0x9186, 0x0260, 0x1150, 0x6810, 0x8000, 0x6812,
-	0x2009, 0x0240, 0x6814, 0x8000, 0x6816, 0x2011, 0x0260, 0x1f04,
-	0x5dff, 0x60c3, 0x0084, 0x080c, 0x5f21, 0x0005, 0x0005, 0x0086,
-	0x0096, 0x2029, 0x1848, 0x252c, 0x20a9, 0x0008, 0x2041, 0x1d0e,
-	0x20e9, 0x0001, 0x28a0, 0x080c, 0x606c, 0x20e1, 0x0000, 0x2099,
-	0x026e, 0x4003, 0x20a9, 0x0008, 0x2011, 0x0007, 0xd5d4, 0x0108,
-	0x9016, 0x2800, 0x9200, 0x200c, 0x91a6, 0xffff, 0x1148, 0xd5d4,
-	0x0110, 0x8210, 0x0008, 0x8211, 0x1f04, 0x5e31, 0x0804, 0x5ea0,
-	0x82ff, 0x1160, 0xd5d4, 0x0120, 0x91a6, 0x3fff, 0x0d90, 0x0020,
-	0x91a6, 0x3fff, 0x0904, 0x5ea0, 0x918d, 0xc000, 0x20a9, 0x0010,
-	0x2019, 0x0001, 0xd5d4, 0x0110, 0x2019, 0x0010, 0x2120, 0xd5d4,
-	0x0110, 0x8423, 0x0008, 0x8424, 0x1240, 0xd5d4, 0x0110, 0x8319,
-	0x0008, 0x8318, 0x1f04, 0x5e57, 0x04d8, 0x23a8, 0x2021, 0x0001,
-	0x8426, 0x8425, 0x1f04, 0x5e69, 0x2328, 0x8529, 0x92be, 0x0007,
-	0x0158, 0x0006, 0x2039, 0x0007, 0x2200, 0x973a, 0x000e, 0x27a8,
-	0x95a8, 0x0010, 0x1f04, 0x5e78, 0x755e, 0x95c8, 0x33b9, 0x292d,
-	0x95ac, 0x00ff, 0x7582, 0x6532, 0x6536, 0x0016, 0x2508, 0x080c,
-	0x26aa, 0x001e, 0x60e7, 0x0000, 0x65ea, 0x2018, 0x2304, 0x9405,
-	0x201a, 0x7087, 0x0001, 0x20e9, 0x0000, 0x20a1, 0x024e, 0x20e1,
-	0x0001, 0x2898, 0x20a9, 0x0008, 0x4003, 0x9085, 0x0001, 0x0008,
-	0x9006, 0x009e, 0x008e, 0x0005, 0x0156, 0x01c6, 0x01d6, 0x0136,
-	0x0146, 0x22a8, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000,
-	0x2011, 0x024e, 0x22a0, 0x4003, 0x014e, 0x013e, 0x01de, 0x01ce,
-	0x015e, 0x2118, 0x9026, 0x2001, 0x0007, 0x939a, 0x0010, 0x0218,
-	0x8420, 0x8001, 0x0cd0, 0x2118, 0x84ff, 0x0120, 0x939a, 0x0010,
-	0x8421, 0x1de0, 0x2021, 0x0001, 0x83ff, 0x0118, 0x8423, 0x8319,
-	0x1de8, 0x9238, 0x2029, 0x026e, 0x9528, 0x2504, 0x942c, 0x11b8,
-	0x9405, 0x203a, 0x715e, 0x91a0, 0x33b9, 0x242d, 0x95ac, 0x00ff,
-	0x7582, 0x6532, 0x6536, 0x0016, 0x2508, 0x080c, 0x26aa, 0x001e,
-	0x60e7, 0x0000, 0x65ea, 0x7087, 0x0001, 0x9084, 0x0000, 0x0005,
-	0x00e6, 0x2071, 0x1800, 0x708b, 0x0000, 0x00ee, 0x0005, 0x00e6,
-	0x00f6, 0x2079, 0x0100, 0x2071, 0x0140, 0x080c, 0x5fb1, 0x080c,
-	0x9ed4, 0x7004, 0x9084, 0x4000, 0x0110, 0x080c, 0x2a8a, 0x0126,
-	0x2091, 0x8000, 0x2071, 0x1826, 0x2073, 0x0000, 0x7840, 0x0026,
-	0x0016, 0x2009, 0x00f7, 0x080c, 0x600e, 0x001e, 0x9094, 0x0010,
-	0x9285, 0x0080, 0x7842, 0x7a42, 0x002e, 0x012e, 0x00fe, 0x00ee,
-	0x0005, 0x0126, 0x2091, 0x8000, 0x080c, 0x29e5, 0x0228, 0x2011,
-	0x0101, 0x2204, 0xc0c5, 0x2012, 0x2011, 0x19f3, 0x2013, 0x0000,
-	0x7093, 0x0000, 0x012e, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x080c,
-	0x9ec7, 0x6144, 0xd184, 0x0120, 0x7198, 0x918d, 0x2000, 0x0018,
-	0x718c, 0x918d, 0x1000, 0x2011, 0x1998, 0x2112, 0x2009, 0x07d0,
-	0x2011, 0x5ef7, 0x080c, 0x8792, 0x0005, 0x0016, 0x0026, 0x00c6,
-	0x0126, 0x2091, 0x8000, 0x080c, 0xa91e, 0x080c, 0xabe9, 0x080c,
-	0xa93a, 0x2009, 0x00f7, 0x080c, 0x600e, 0x2061, 0x1a02, 0x900e,
-	0x611a, 0x611e, 0x6172, 0x6176, 0x2061, 0x1800, 0x6003, 0x0001,
-	0x2061, 0x0100, 0x6043, 0x0090, 0x6043, 0x0010, 0x2009, 0x1998,
-	0x200b, 0x0000, 0x2009, 0x002d, 0x2011, 0x5f7d, 0x080c, 0x86bc,
-	0x012e, 0x00ce, 0x002e, 0x001e, 0x0005, 0x00e6, 0x0006, 0x0126,
-	0x2091, 0x8000, 0x0471, 0x2071, 0x0100, 0x080c, 0x9ed4, 0x2071,
-	0x0140, 0x7004, 0x9084, 0x4000, 0x0110, 0x080c, 0x2a8a, 0x080c,
-	0x7545, 0x0188, 0x080c, 0x7560, 0x1170, 0x080c, 0x784a, 0x0016,
-	0x080c, 0x2779, 0x2001, 0x196c, 0x2102, 0x001e, 0x080c, 0x7845,
-	0x080c, 0x746e, 0x0050, 0x2009, 0x0001, 0x080c, 0x2a66, 0x2001,
-	0x0001, 0x080c, 0x2606, 0x080c, 0x5f4d, 0x012e, 0x000e, 0x00ee,
-	0x0005, 0x2001, 0x180e, 0x2004, 0xd0bc, 0x0158, 0x0026, 0x0036,
-	0x2011, 0x8017, 0x2001, 0x1998, 0x201c, 0x080c, 0x4b52, 0x003e,
-	0x002e, 0x0005, 0x20a9, 0x0012, 0x20e9, 0x0001, 0x20a1, 0x1d80,
-	0x080c, 0x606c, 0x20e9, 0x0000, 0x2099, 0x026e, 0x0099, 0x20a9,
-	0x0020, 0x080c, 0x6066, 0x2099, 0x0260, 0x20a1, 0x1d92, 0x0051,
-	0x20a9, 0x000e, 0x080c, 0x6069, 0x2099, 0x0260, 0x20a1, 0x1db2,
-	0x0009, 0x0005, 0x0016, 0x0026, 0x3410, 0x3308, 0x2104, 0x8007,
-	0x2012, 0x8108, 0x8210, 0x1f04, 0x5fe6, 0x002e, 0x001e, 0x0005,
-	0x080c, 0xa713, 0x20e1, 0x0001, 0x2099, 0x1d00, 0x20e9, 0x0000,
-	0x20a1, 0x0240, 0x20a9, 0x000c, 0x4003, 0x0005, 0x080c, 0xa713,
-	0x080c, 0x606c, 0x20e1, 0x0000, 0x2099, 0x0260, 0x20e9, 0x0000,
-	0x20a1, 0x0240, 0x20a9, 0x000c, 0x4003, 0x0005, 0x00c6, 0x0006,
-	0x2061, 0x0100, 0x810f, 0x2001, 0x1834, 0x2004, 0x9005, 0x1138,
-	0x2001, 0x1818, 0x2004, 0x9084, 0x00ff, 0x9105, 0x0010, 0x9185,
-	0x00f7, 0x604a, 0x000e, 0x00ce, 0x0005, 0x0016, 0x0046, 0x080c,
-	0x6ad9, 0x0158, 0x9006, 0x2020, 0x2009, 0x002a, 0x080c, 0xe445,
-	0x2001, 0x180c, 0x200c, 0xc195, 0x2102, 0x2019, 0x002a, 0x900e,
-	0x080c, 0x3205, 0x080c, 0xd09b, 0x0140, 0x0036, 0x2019, 0xffff,
-	0x2021, 0x0007, 0x080c, 0x4d09, 0x003e, 0x004e, 0x001e, 0x0005,
-	0x080c, 0x5f4d, 0x709b, 0x0000, 0x7093, 0x0000, 0x0005, 0x0006,
-	0x2001, 0x180c, 0x2004, 0xd09c, 0x0100, 0x000e, 0x0005, 0x0006,
-	0x0016, 0x0126, 0x2091, 0x8000, 0x2001, 0x0101, 0x200c, 0x918d,
-	0x0006, 0x2102, 0x012e, 0x001e, 0x000e, 0x0005, 0x2009, 0x0001,
-	0x0020, 0x2009, 0x0002, 0x0008, 0x900e, 0x6814, 0x9084, 0xffc0,
-	0x910d, 0x6916, 0x0005, 0x00f6, 0x0156, 0x0146, 0x01d6, 0x9006,
-	0x20a9, 0x0080, 0x20e9, 0x0001, 0x20a1, 0x1d00, 0x4004, 0x2079,
-	0x1d00, 0x7803, 0x2200, 0x7807, 0x00ef, 0x780f, 0x00ef, 0x7813,
-	0x0138, 0x7823, 0xffff, 0x7827, 0xffff, 0x01de, 0x014e, 0x015e,
-	0x00fe, 0x0005, 0x2001, 0x1800, 0x2003, 0x0001, 0x0005, 0x2001,
-	0x19a5, 0x0118, 0x2003, 0x0001, 0x0010, 0x2003, 0x0000, 0x0005,
-	0x0156, 0x20a9, 0x0800, 0x2009, 0x1000, 0x9006, 0x200a, 0x8108,
-	0x1f04, 0x60a6, 0x015e, 0x0005, 0x00d6, 0x0036, 0x0156, 0x0136,
-	0x0146, 0x2069, 0x1847, 0x9006, 0xb802, 0xb8d6, 0xb807, 0x0707,
-	0xb80a, 0xb80e, 0xb812, 0x9198, 0x33b9, 0x231d, 0x939c, 0x00ff,
-	0xbb16, 0x0016, 0x0026, 0xb886, 0x080c, 0xabe2, 0x1120, 0x9192,
-	0x007e, 0x1208, 0xbb86, 0x20a9, 0x0004, 0xb8c4, 0x20e8, 0xb9c8,
-	0x9198, 0x0006, 0x9006, 0x23a0, 0x4004, 0x20a9, 0x0004, 0x9198,
-	0x000a, 0x23a0, 0x4004, 0x002e, 0x001e, 0xb83e, 0xb842, 0xb8ce,
-	0xb8d2, 0xb85e, 0xb862, 0xb866, 0xb86a, 0xb86f, 0x0100, 0xb872,
-	0xb876, 0xb87a, 0xb88a, 0xb88e, 0xb893, 0x0008, 0xb896, 0xb89a,
-	0xb89e, 0xb8be, 0xb9a2, 0x0096, 0xb8a4, 0x904d, 0x0110, 0x080c,
-	0x1079, 0xb8a7, 0x0000, 0x009e, 0x9006, 0xb84a, 0x6810, 0xb83a,
-	0x680c, 0xb846, 0xb8bb, 0x0520, 0xb8ac, 0x9005, 0x0198, 0x00c6,
-	0x2060, 0x9c82, 0x1ddc, 0x0a0c, 0x0d7d, 0x2001, 0x181a, 0x2004,
-	0x9c02, 0x1a0c, 0x0d7d, 0x080c, 0x8c1f, 0x00ce, 0x090c, 0x8fbc,
-	0xb8af, 0x0000, 0x6814, 0x9084, 0x00ff, 0xb842, 0x014e, 0x013e,
-	0x015e, 0x003e, 0x00de, 0x0005, 0x0126, 0x2091, 0x8000, 0xa974,
-	0xae78, 0x9684, 0x3fff, 0x9082, 0x4000, 0x1a04, 0x6182, 0x9182,
-	0x0800, 0x1a04, 0x6186, 0x2001, 0x180c, 0x2004, 0x9084, 0x0003,
-	0x1904, 0x618c, 0x9188, 0x1000, 0x2104, 0x905d, 0x0198, 0xb804,
-	0x9084, 0x00ff, 0x908e, 0x0006, 0x1188, 0xb8a4, 0x900d, 0x1904,
-	0x619e, 0x080c, 0x655e, 0x9006, 0x012e, 0x0005, 0x2001, 0x0005,
-	0x900e, 0x04b8, 0x2001, 0x0028, 0x900e, 0x0498, 0x9082, 0x0006,
-	0x1290, 0x080c, 0xabe2, 0x1160, 0xb8a0, 0x9084, 0xff80, 0x1140,
-	0xb900, 0xd1fc, 0x0d10, 0x2001, 0x0029, 0x2009, 0x1000, 0x0408,
-	0x2001, 0x0028, 0x00a8, 0x2009, 0x180c, 0x210c, 0xd18c, 0x0118,
-	0x2001, 0x0004, 0x0068, 0xd184, 0x0118, 0x2001, 0x0004, 0x0040,
-	0x2001, 0x0029, 0xb900, 0xd1fc, 0x0118, 0x2009, 0x1000, 0x0048,
-	0x900e, 0x0038, 0x2001, 0x0029, 0x900e, 0x0018, 0x2001, 0x0029,
-	0x900e, 0x9005, 0x012e, 0x0005, 0x2001, 0x180c, 0x2004, 0xd084,
-	0x19d0, 0x9188, 0x1000, 0x2104, 0x9065, 0x09a8, 0x080c, 0x6add,
-	0x1990, 0xb800, 0xd0bc, 0x0978, 0x0804, 0x6145, 0x080c, 0x6902,
-	0x0904, 0x614e, 0x0804, 0x6149, 0x00e6, 0x2071, 0x19e6, 0x7004,
-	0x9086, 0x0002, 0x1128, 0x7030, 0x9080, 0x0004, 0x2004, 0x9b06,
-	0x00ee, 0x0005, 0x00b6, 0x00e6, 0x0126, 0x2091, 0x8000, 0xa874,
-	0x908e, 0x00ff, 0x1120, 0x2001, 0x196a, 0x205c, 0x0060, 0xa974,
-	0x9182, 0x0800, 0x1690, 0x9188, 0x1000, 0x2104, 0x905d, 0x01d0,
-	0x080c, 0x6a7d, 0x11d0, 0x080c, 0xac5a, 0x0570, 0x2b00, 0x6012,
-	0x2900, 0x6016, 0x6023, 0x0009, 0x602b, 0x0000, 0xa874, 0x908e,
-	0x00ff, 0x1110, 0x602b, 0x8000, 0x2009, 0x0043, 0x080c, 0xad4d,
-	0x9006, 0x00b0, 0x2001, 0x0028, 0x0090, 0x2009, 0x180c, 0x210c,
-	0xd18c, 0x0118, 0x2001, 0x0004, 0x0038, 0xd184, 0x0118, 0x2001,
-	0x0004, 0x0010, 0x2001, 0x0029, 0x0010, 0x2001, 0x0029, 0x9005,
-	0x012e, 0x00ee, 0x00be, 0x0005, 0x2001, 0x002c, 0x0cc0, 0x00b6,
-	0x00e6, 0x0126, 0x2091, 0x8000, 0xa974, 0x9182, 0x0800, 0x1a04,
-	0x627d, 0x9188, 0x1000, 0x2104, 0x905d, 0x0904, 0x6255, 0xb8a0,
-	0x9086, 0x007f, 0x0190, 0xa87c, 0xd0fc, 0x1178, 0x080c, 0x6ae5,
-	0x0160, 0xa994, 0x81ff, 0x0130, 0x908e, 0x0004, 0x0130, 0x908e,
-	0x0005, 0x0118, 0x080c, 0x6add, 0x1598, 0xa87c, 0xd0fc, 0x01e0,
-	0xa894, 0x9005, 0x01c8, 0x2060, 0x0026, 0x2010, 0x080c, 0xc968,
-	0x002e, 0x1120, 0x2001, 0x0008, 0x0804, 0x627f, 0x6020, 0x9086,
-	0x000a, 0x0120, 0x2001, 0x0008, 0x0804, 0x627f, 0x601a, 0x6003,
-	0x0008, 0x2900, 0x6016, 0x0058, 0x080c, 0xac5a, 0x05e8, 0x2b00,
-	0x6012, 0x2900, 0x6016, 0x600b, 0xffff, 0x6023, 0x000a, 0x2009,
-	0x0003, 0x080c, 0xad4d, 0x9006, 0x0458, 0x2001, 0x0028, 0x0438,
-	0x9082, 0x0006, 0x1290, 0x080c, 0xabe2, 0x1160, 0xb8a0, 0x9084,
-	0xff80, 0x1140, 0xb900, 0xd1fc, 0x0900, 0x2001, 0x0029, 0x2009,
-	0x1000, 0x00a8, 0x2001, 0x0028, 0x0090, 0x2009, 0x180c, 0x210c,
-	0xd18c, 0x0118, 0x2001, 0x0004, 0x0050, 0xd184, 0x0118, 0x2001,
-	0x0004, 0x0028, 0x2001, 0x0029, 0x0010, 0x2001, 0x0029, 0x9005,
-	0x012e, 0x00ee, 0x00be, 0x0005, 0x2001, 0x002c, 0x0cc0, 0x00f6,
-	0x00b6, 0x0126, 0x2091, 0x8000, 0xa8e0, 0x9005, 0x1550, 0xa8dc,
-	0x9082, 0x0101, 0x1630, 0xa8c8, 0x9005, 0x1518, 0xa8c4, 0x9082,
-	0x0101, 0x12f8, 0xa974, 0x2079, 0x1800, 0x9182, 0x0800, 0x12e8,
-	0x7830, 0x9084, 0x0003, 0x1130, 0xaa98, 0xab94, 0xa878, 0x9084,
-	0x0007, 0x00ea, 0x7930, 0xd18c, 0x0118, 0x2001, 0x0004, 0x0038,
-	0xd184, 0x0118, 0x2001, 0x0004, 0x0010, 0x2001, 0x0029, 0x900e,
-	0x0038, 0x2001, 0x002c, 0x900e, 0x0018, 0x2001, 0x0029, 0x900e,
-	0x9006, 0x0008, 0x9005, 0x012e, 0x00be, 0x00fe, 0x0005, 0x6314,
-	0x62cf, 0x62e6, 0x6314, 0x6314, 0x6314, 0x6314, 0x6314, 0x2100,
-	0x9082, 0x007e, 0x1278, 0x080c, 0x6632, 0x0148, 0x9046, 0xb810,
-	0x9306, 0x1904, 0x631c, 0xb814, 0x9206, 0x15f0, 0x0028, 0xbb12,
-	0xba16, 0x0010, 0x080c, 0x4a05, 0x0150, 0x04b0, 0x080c, 0x6693,
-	0x1598, 0xb810, 0x9306, 0x1580, 0xb814, 0x9206, 0x1568, 0x080c,
-	0xac5a, 0x0530, 0x2b00, 0x6012, 0x080c, 0xce15, 0x2900, 0x6016,
-	0x600b, 0xffff, 0x6023, 0x000a, 0xa878, 0x9086, 0x0001, 0x1170,
-	0x080c, 0x3240, 0x9006, 0x080c, 0x65cf, 0x2001, 0x0002, 0x080c,
-	0x65e3, 0x2001, 0x0200, 0xb86e, 0xb893, 0x0002, 0x2009, 0x0003,
-	0x080c, 0xad4d, 0x9006, 0x0068, 0x2001, 0x0001, 0x900e, 0x0038,
-	0x2001, 0x002c, 0x900e, 0x0018, 0x2001, 0x0028, 0x900e, 0x9005,
-	0x0000, 0x012e, 0x00be, 0x00fe, 0x0005, 0x00b6, 0x00f6, 0x00e6,
-	0x0126, 0x2091, 0x8000, 0xa894, 0x90c6, 0x0015, 0x0904, 0x6507,
-	0x90c6, 0x0056, 0x0904, 0x650b, 0x90c6, 0x0066, 0x0904, 0x650f,
-	0x90c6, 0x0067, 0x0904, 0x6513, 0x90c6, 0x0068, 0x0904, 0x6517,
-	0x90c6, 0x0071, 0x0904, 0x651b, 0x90c6, 0x0074, 0x0904, 0x651f,
-	0x90c6, 0x007c, 0x0904, 0x6523, 0x90c6, 0x007e, 0x0904, 0x6527,
-	0x90c6, 0x0037, 0x0904, 0x652b, 0x9016, 0x2079, 0x1800, 0xa974,
-	0x9186, 0x00ff, 0x0904, 0x6502, 0x9182, 0x0800, 0x1a04, 0x6502,
-	0x080c, 0x6693, 0x1198, 0xb804, 0x9084, 0x00ff, 0x9082, 0x0006,
-	0x1268, 0xa894, 0x90c6, 0x006f, 0x0148, 0x080c, 0xabe2, 0x1904,
-	0x64eb, 0xb8a0, 0x9084, 0xff80, 0x1904, 0x64eb, 0xa894, 0x90c6,
-	0x006f, 0x0158, 0x90c6, 0x005e, 0x0904, 0x644b, 0x90c6, 0x0064,
-	0x0904, 0x6474, 0x2008, 0x0804, 0x640d, 0xa998, 0xa8b0, 0x2040,
-	0x080c, 0xabe2, 0x1120, 0x9182, 0x007f, 0x0a04, 0x640d, 0x9186,
-	0x00ff, 0x0904, 0x640d, 0x9182, 0x0800, 0x1a04, 0x640d, 0xaaa0,
-	0xab9c, 0x787c, 0x9306, 0x11a8, 0x7880, 0x0096, 0x924e, 0x1128,
-	0x2208, 0x2310, 0x009e, 0x0804, 0x640d, 0x080c, 0xabe2, 0x1140,
-	0x99cc, 0xff00, 0x009e, 0x1128, 0x2208, 0x2310, 0x0804, 0x640d,
-	0x009e, 0x080c, 0x4a05, 0x0904, 0x6417, 0x900e, 0x9016, 0x90c6,
-	0x4000, 0x15e0, 0x0006, 0x080c, 0x6986, 0x1108, 0xc185, 0xb800,
-	0xd0bc, 0x0108, 0xc18d, 0x20a9, 0x0004, 0xa860, 0x20e8, 0xa85c,
-	0x9080, 0x0031, 0x20a0, 0xb8c4, 0x20e0, 0xb8c8, 0x9080, 0x0006,
-	0x2098, 0x080c, 0x0fc4, 0x20a9, 0x0004, 0xa860, 0x20e8, 0xa85c,
-	0x9080, 0x0035, 0x20a0, 0xb8c4, 0x20e0, 0xb8c8, 0x9080, 0x000a,
-	0x2098, 0x080c, 0x0fc4, 0xa8c4, 0xabc8, 0x9305, 0xabcc, 0x9305,
-	0xabd0, 0x9305, 0xabd4, 0x9305, 0xabd8, 0x9305, 0xabdc, 0x9305,
-	0xabe0, 0x9305, 0x9005, 0x0510, 0x000e, 0x00c8, 0x90c6, 0x4007,
-	0x1110, 0x2408, 0x00a0, 0x90c6, 0x4008, 0x1118, 0x2708, 0x2610,
-	0x0070, 0x90c6, 0x4009, 0x1108, 0x0050, 0x90c6, 0x4006, 0x0138,
-	0x2001, 0x4005, 0x2009, 0x000a, 0x0010, 0x2001, 0x4006, 0xa896,
-	0xa99a, 0xaa9e, 0x2001, 0x0030, 0x900e, 0x0478, 0x000e, 0x080c,
-	0xac5a, 0x1130, 0x2001, 0x4005, 0x2009, 0x0003, 0x9016, 0x0c78,
-	0x2b00, 0x6012, 0x080c, 0xce15, 0x2900, 0x6016, 0x6023, 0x0001,
-	0xa868, 0xd88c, 0x0108, 0xc0f5, 0xa86a, 0x0126, 0x2091, 0x8000,
-	0x080c, 0x3240, 0x012e, 0x9006, 0x080c, 0x65cf, 0x2001, 0x0002,
-	0x080c, 0x65e3, 0x2009, 0x0002, 0x080c, 0xad4d, 0xa8b0, 0xd094,
-	0x0118, 0xb8d4, 0xc08d, 0xb8d6, 0x9006, 0x9005, 0x012e, 0x00ee,
-	0x00fe, 0x00be, 0x0005, 0x080c, 0x5752, 0x0118, 0x2009, 0x0007,
-	0x00f8, 0xa998, 0xaeb0, 0x080c, 0x6693, 0x1904, 0x6408, 0x9186,
-	0x007f, 0x0130, 0x080c, 0x6add, 0x0118, 0x2009, 0x0009, 0x0080,
-	0x0096, 0x080c, 0x1047, 0x1120, 0x009e, 0x2009, 0x0002, 0x0040,
-	0x2900, 0x009e, 0xa806, 0x080c, 0xcb68, 0x19b0, 0x2009, 0x0003,
-	0x2001, 0x4005, 0x0804, 0x640f, 0xa998, 0xaeb0, 0x080c, 0x6693,
-	0x1904, 0x6408, 0x0096, 0x080c, 0x1047, 0x1128, 0x009e, 0x2009,
-	0x0002, 0x0804, 0x64c8, 0x2900, 0x009e, 0xa806, 0x0096, 0x2048,
-	0x20a9, 0x002b, 0xb8c4, 0x20e0, 0xb8c8, 0x2098, 0xa860, 0x20e8,
-	0xa85c, 0x9080, 0x0002, 0x20a0, 0x4003, 0x20a9, 0x0008, 0x9080,
-	0x0006, 0x20a0, 0xbbc8, 0x9398, 0x0006, 0x2398, 0x080c, 0x0fc4,
-	0x009e, 0xa87b, 0x0000, 0xa883, 0x0000, 0xa897, 0x4000, 0xd684,
-	0x1168, 0x080c, 0x573e, 0xd0b4, 0x1118, 0xa89b, 0x000b, 0x00e0,
-	0xb800, 0xd08c, 0x0118, 0xa89b, 0x000c, 0x00b0, 0x080c, 0x6add,
-	0x0118, 0xa89b, 0x0009, 0x0080, 0x080c, 0x5752, 0x0118, 0xa89b,
-	0x0007, 0x0050, 0x080c, 0xcb4b, 0x1904, 0x6444, 0x2009, 0x0003,
-	0x2001, 0x4005, 0x0804, 0x640f, 0xa87b, 0x0030, 0xa897, 0x4005,
-	0xa804, 0x8006, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0,
-	0x9080, 0x0002, 0x2009, 0x002b, 0xaaa0, 0xab9c, 0xaca8, 0xada4,
-	0x2031, 0x0000, 0x2041, 0x1296, 0x080c, 0xb1d4, 0x1904, 0x6444,
-	0x2009, 0x0002, 0x08e8, 0x2001, 0x0028, 0x900e, 0x0804, 0x6445,
-	0x2009, 0x180c, 0x210c, 0xd18c, 0x0118, 0x2001, 0x0004, 0x0038,
-	0xd184, 0x0118, 0x2001, 0x0004, 0x0010, 0x2001, 0x0029, 0x900e,
-	0x0804, 0x6445, 0x2001, 0x0029, 0x900e, 0x0804, 0x6445, 0x080c,
-	0x37e7, 0x0804, 0x6446, 0x080c, 0x545b, 0x0804, 0x6446, 0x080c,
-	0x45b9, 0x0804, 0x6446, 0x080c, 0x4632, 0x0804, 0x6446, 0x080c,
-	0x468e, 0x0804, 0x6446, 0x080c, 0x4ac8, 0x0804, 0x6446, 0x080c,
-	0x4d7c, 0x0804, 0x6446, 0x080c, 0x50c3, 0x0804, 0x6446, 0x080c,
-	0x52bc, 0x0804, 0x6446, 0x080c, 0x3a0b, 0x0804, 0x6446, 0x00b6,
-	0xa974, 0xae78, 0x9684, 0x3fff, 0x9082, 0x4000, 0x1608, 0x9182,
-	0x0800, 0x1258, 0x9188, 0x1000, 0x2104, 0x905d, 0x0130, 0x080c,
-	0x6add, 0x1138, 0x00d9, 0x9006, 0x00b0, 0x2001, 0x0028, 0x900e,
-	0x0090, 0x9082, 0x0006, 0x1240, 0xb900, 0xd1fc, 0x0d98, 0x2001,
-	0x0029, 0x2009, 0x1000, 0x0038, 0x2001, 0x0029, 0x900e, 0x0018,
-	0x2001, 0x0029, 0x900e, 0x9005, 0x00be, 0x0005, 0xa877, 0x0000,
-	0xb8d0, 0x9005, 0x1904, 0x65c3, 0xb888, 0x9005, 0x1904, 0x65c3,
-	0xb838, 0xb93c, 0x9102, 0x1a04, 0x65c3, 0x2b10, 0x080c, 0xac87,
-	0x0904, 0x65bf, 0x8108, 0xb93e, 0x6212, 0x2900, 0x6016, 0x6023,
-	0x0003, 0x600b, 0xffff, 0x6007, 0x0040, 0xa878, 0x605e, 0xa880,
-	0x6066, 0xa883, 0x0000, 0xa87c, 0xd0ac, 0x0588, 0xc0dd, 0xa87e,
-	0xa888, 0x8001, 0x1530, 0xa816, 0xa864, 0x9094, 0x00f7, 0x9296,
-	0x0011, 0x11f8, 0x9084, 0x00ff, 0xc0bd, 0x601e, 0xa8ac, 0xaab0,
-	0xa836, 0xaa3a, 0x2001, 0x000f, 0x8001, 0x1df0, 0x2001, 0x8004,
-	0x6003, 0x0004, 0x6046, 0x00f6, 0x2079, 0x0380, 0x7818, 0xd0bc,
-	0x1de8, 0x7833, 0x0010, 0x2c00, 0x7836, 0x781b, 0x8080, 0x00fe,
-	0x0005, 0x080c, 0x1778, 0x601c, 0xc0bd, 0x601e, 0x0c38, 0xd0b4,
-	0x190c, 0x1c86, 0x2001, 0x8004, 0x6003, 0x0002, 0x0c18, 0x81ff,
-	0x1110, 0xb88b, 0x0001, 0x2908, 0xb8cc, 0xb9ce, 0x9005, 0x1110,
-	0xb9d2, 0x0020, 0x0096, 0x2048, 0xa902, 0x009e, 0x0005, 0x00b6,
-	0x0126, 0x00c6, 0x0026, 0x2091, 0x8000, 0x6210, 0x2258, 0xba00,
-	0x9005, 0x0110, 0xc285, 0x0008, 0xc284, 0xba02, 0x002e, 0x00ce,
-	0x012e, 0x00be, 0x0005, 0x00b6, 0x0126, 0x00c6, 0x2091, 0x8000,
-	0x6210, 0x2258, 0xba04, 0x0006, 0x9086, 0x0006, 0x1170, 0xb89c,
-	0xd0ac, 0x0158, 0x080c, 0x6ad9, 0x0140, 0x9284, 0xff00, 0x8007,
-	0x9086, 0x0007, 0x1110, 0x2011, 0x0600, 0x000e, 0x9294, 0xff00,
-	0x9215, 0xba06, 0x0006, 0x9086, 0x0006, 0x1120, 0xba90, 0x82ff,
-	0x090c, 0x0d7d, 0x000e, 0x00ce, 0x012e, 0x00be, 0x0005, 0x00b6,
+	0x60c3, 0x0014, 0x080c, 0x600d, 0x0010, 0x080c, 0x5a5d, 0x0005,
+	0x00f6, 0x7090, 0x9005, 0x01d8, 0x2011, 0x5fe3, 0x080c, 0x8834,
+	0x9086, 0x0084, 0x1190, 0x080c, 0x6158, 0x2079, 0x0260, 0x7a30,
+	0x9296, 0x1106, 0x1150, 0x7834, 0x9005, 0x1138, 0x9006, 0x080c,
+	0x6183, 0x709b, 0x0018, 0x0029, 0x0010, 0x7093, 0x0000, 0x00fe,
+	0x0005, 0x00f6, 0x709b, 0x0019, 0x080c, 0x60ea, 0x2079, 0x0240,
+	0x7833, 0x1106, 0x7837, 0x0000, 0x080c, 0x6158, 0x2009, 0x026e,
+	0x2039, 0x1d0e, 0x20a9, 0x0040, 0x213e, 0x8738, 0x8108, 0x9186,
+	0x0280, 0x1128, 0x6814, 0x8000, 0x6816, 0x2009, 0x0260, 0x1f04,
+	0x5e6c, 0x2039, 0x1d0e, 0x080c, 0x613b, 0x11e8, 0x2728, 0x2514,
+	0x8207, 0x9084, 0x00ff, 0x8000, 0x2018, 0x9294, 0x00ff, 0x8007,
+	0x9205, 0x202a, 0x7060, 0x2310, 0x8214, 0x92a0, 0x1d0e, 0x2414,
+	0x938c, 0x0001, 0x0118, 0x9294, 0xff00, 0x0018, 0x9294, 0x00ff,
+	0x8007, 0x9215, 0x2222, 0x20a9, 0x0040, 0x2009, 0x024e, 0x270e,
+	0x8738, 0x8108, 0x9186, 0x0260, 0x1128, 0x6810, 0x8000, 0x6812,
+	0x2009, 0x0240, 0x1f04, 0x5e9f, 0x60c3, 0x0084, 0x080c, 0x600d,
+	0x00fe, 0x0005, 0x00f6, 0x7090, 0x9005, 0x01e0, 0x2011, 0x5fe3,
+	0x080c, 0x8834, 0x9086, 0x0084, 0x1198, 0x080c, 0x6158, 0x2079,
+	0x0260, 0x7a30, 0x9296, 0x1107, 0x1158, 0x7834, 0x9005, 0x1140,
+	0x7097, 0x0001, 0x080c, 0x60ae, 0x709b, 0x001a, 0x0029, 0x0010,
+	0x7093, 0x0000, 0x00fe, 0x0005, 0x9085, 0x0001, 0x080c, 0x6183,
+	0x709b, 0x001b, 0x080c, 0xa8d5, 0x080c, 0x6158, 0x2011, 0x0260,
+	0x2009, 0x0240, 0x7490, 0x9480, 0x0018, 0x9080, 0x0007, 0x9084,
+	0x03f8, 0x8004, 0x20a8, 0x220e, 0x8210, 0x8108, 0x9186, 0x0260,
+	0x1150, 0x6810, 0x8000, 0x6812, 0x2009, 0x0240, 0x6814, 0x8000,
+	0x6816, 0x2011, 0x0260, 0x1f04, 0x5eeb, 0x60c3, 0x0084, 0x080c,
+	0x600d, 0x0005, 0x0005, 0x0086, 0x0096, 0x2029, 0x1848, 0x252c,
+	0x20a9, 0x0008, 0x2041, 0x1d0e, 0x20e9, 0x0001, 0x28a0, 0x080c,
+	0x6158, 0x20e1, 0x0000, 0x2099, 0x026e, 0x4003, 0x20a9, 0x0008,
+	0x2011, 0x0007, 0xd5d4, 0x0108, 0x9016, 0x2800, 0x9200, 0x200c,
+	0x91a6, 0xffff, 0x1148, 0xd5d4, 0x0110, 0x8210, 0x0008, 0x8211,
+	0x1f04, 0x5f1d, 0x0804, 0x5f8c, 0x82ff, 0x1160, 0xd5d4, 0x0120,
+	0x91a6, 0x3fff, 0x0d90, 0x0020, 0x91a6, 0x3fff, 0x0904, 0x5f8c,
+	0x918d, 0xc000, 0x20a9, 0x0010, 0x2019, 0x0001, 0xd5d4, 0x0110,
+	0x2019, 0x0010, 0x2120, 0xd5d4, 0x0110, 0x8423, 0x0008, 0x8424,
+	0x1240, 0xd5d4, 0x0110, 0x8319, 0x0008, 0x8318, 0x1f04, 0x5f43,
+	0x04d8, 0x23a8, 0x2021, 0x0001, 0x8426, 0x8425, 0x1f04, 0x5f55,
+	0x2328, 0x8529, 0x92be, 0x0007, 0x0158, 0x0006, 0x2039, 0x0007,
+	0x2200, 0x973a, 0x000e, 0x27a8, 0x95a8, 0x0010, 0x1f04, 0x5f64,
+	0x755e, 0x95c8, 0x3489, 0x292d, 0x95ac, 0x00ff, 0x7582, 0x6532,
+	0x6536, 0x0016, 0x2508, 0x080c, 0x26eb, 0x001e, 0x60e7, 0x0000,
+	0x65ea, 0x2018, 0x2304, 0x9405, 0x201a, 0x7087, 0x0001, 0x20e9,
+	0x0000, 0x20a1, 0x024e, 0x20e1, 0x0001, 0x2898, 0x20a9, 0x0008,
+	0x4003, 0x9085, 0x0001, 0x0008, 0x9006, 0x009e, 0x008e, 0x0005,
+	0x0156, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x22a8, 0x20e1, 0x0000,
+	0x2099, 0x026e, 0x20e9, 0x0000, 0x2011, 0x024e, 0x22a0, 0x4003,
+	0x014e, 0x013e, 0x01de, 0x01ce, 0x015e, 0x2118, 0x9026, 0x2001,
+	0x0007, 0x939a, 0x0010, 0x0218, 0x8420, 0x8001, 0x0cd0, 0x2118,
+	0x84ff, 0x0120, 0x939a, 0x0010, 0x8421, 0x1de0, 0x2021, 0x0001,
+	0x83ff, 0x0118, 0x8423, 0x8319, 0x1de8, 0x9238, 0x2029, 0x026e,
+	0x9528, 0x2504, 0x942c, 0x11b8, 0x9405, 0x203a, 0x715e, 0x91a0,
+	0x3489, 0x242d, 0x95ac, 0x00ff, 0x7582, 0x6532, 0x6536, 0x0016,
+	0x2508, 0x080c, 0x26eb, 0x001e, 0x60e7, 0x0000, 0x65ea, 0x7087,
+	0x0001, 0x9084, 0x0000, 0x0005, 0x00e6, 0x2071, 0x1800, 0x708b,
+	0x0000, 0x00ee, 0x0005, 0x00e6, 0x00f6, 0x2079, 0x0100, 0x2071,
+	0x0140, 0x080c, 0x609d, 0x080c, 0xa08a, 0x7004, 0x9084, 0x4000,
+	0x0110, 0x080c, 0x2acb, 0x0126, 0x2091, 0x8000, 0x2071, 0x1826,
+	0x2073, 0x0000, 0x7840, 0x0026, 0x0016, 0x2009, 0x00f7, 0x080c,
+	0x60fa, 0x001e, 0x9094, 0x0010, 0x9285, 0x0080, 0x7842, 0x7a42,
+	0x002e, 0x012e, 0x00fe, 0x00ee, 0x0005, 0x0126, 0x2091, 0x8000,
+	0x080c, 0x2a26, 0x0228, 0x2011, 0x0101, 0x2204, 0xc0c5, 0x2012,
+	0x2011, 0x19f6, 0x2013, 0x0000, 0x7093, 0x0000, 0x012e, 0x60a3,
+	0x0056, 0x60a7, 0x9575, 0x080c, 0xa07d, 0x6144, 0xd184, 0x0120,
+	0x7198, 0x918d, 0x2000, 0x0018, 0x718c, 0x918d, 0x1000, 0x2011,
+	0x199a, 0x2112, 0x2009, 0x07d0, 0x2011, 0x5fe3, 0x080c, 0x88fe,
+	0x0005, 0x0016, 0x0026, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c,
+	0xaae0, 0x080c, 0xae67, 0x080c, 0xaafc, 0x2009, 0x00f7, 0x080c,
+	0x60fa, 0x2061, 0x1a05, 0x900e, 0x611a, 0x611e, 0x617a, 0x617e,
+	0x2061, 0x1800, 0x6003, 0x0001, 0x2061, 0x0100, 0x6043, 0x0090,
+	0x6043, 0x0010, 0x2009, 0x199a, 0x200b, 0x0000, 0x2009, 0x002d,
+	0x2011, 0x6069, 0x080c, 0x8828, 0x012e, 0x00ce, 0x002e, 0x001e,
+	0x0005, 0x00e6, 0x0006, 0x0126, 0x2091, 0x8000, 0x0471, 0x2071,
+	0x0100, 0x080c, 0xa08a, 0x2071, 0x0140, 0x7004, 0x9084, 0x4000,
+	0x0110, 0x080c, 0x2acb, 0x080c, 0x76ad, 0x0188, 0x080c, 0x76c8,
+	0x1170, 0x080c, 0x79b1, 0x0016, 0x080c, 0x27ba, 0x2001, 0x196e,
+	0x2102, 0x001e, 0x080c, 0x79ac, 0x080c, 0x75d4, 0x0050, 0x2009,
+	0x0001, 0x080c, 0x2aa7, 0x2001, 0x0001, 0x080c, 0x2647, 0x080c,
+	0x6039, 0x012e, 0x000e, 0x00ee, 0x0005, 0x2001, 0x180e, 0x2004,
+	0xd0bc, 0x0158, 0x0026, 0x0036, 0x2011, 0x8017, 0x2001, 0x199a,
+	0x201c, 0x080c, 0x4c2e, 0x003e, 0x002e, 0x0005, 0x20a9, 0x0012,
+	0x20e9, 0x0001, 0x20a1, 0x1d80, 0x080c, 0x6158, 0x20e9, 0x0000,
+	0x2099, 0x026e, 0x0099, 0x20a9, 0x0020, 0x080c, 0x6152, 0x2099,
+	0x0260, 0x20a1, 0x1d92, 0x0051, 0x20a9, 0x000e, 0x080c, 0x6155,
+	0x2099, 0x0260, 0x20a1, 0x1db2, 0x0009, 0x0005, 0x0016, 0x0026,
+	0x3410, 0x3308, 0x2104, 0x8007, 0x2012, 0x8108, 0x8210, 0x1f04,
+	0x60d2, 0x002e, 0x001e, 0x0005, 0x080c, 0xa8d5, 0x20e1, 0x0001,
+	0x2099, 0x1d00, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, 0x000c,
+	0x4003, 0x0005, 0x080c, 0xa8d5, 0x080c, 0x6158, 0x20e1, 0x0000,
+	0x2099, 0x0260, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, 0x000c,
+	0x4003, 0x0005, 0x00c6, 0x0006, 0x2061, 0x0100, 0x810f, 0x2001,
+	0x1834, 0x2004, 0x9005, 0x1138, 0x2001, 0x1818, 0x2004, 0x9084,
+	0x00ff, 0x9105, 0x0010, 0x9185, 0x00f7, 0x604a, 0x000e, 0x00ce,
+	0x0005, 0x0016, 0x0046, 0x080c, 0x6bd1, 0x0158, 0x9006, 0x2020,
+	0x2009, 0x002a, 0x080c, 0xe72a, 0x2001, 0x180c, 0x200c, 0xc195,
+	0x2102, 0x2019, 0x002a, 0x900e, 0x080c, 0x32d5, 0x080c, 0xd33e,
+	0x0140, 0x0036, 0x2019, 0xffff, 0x2021, 0x0007, 0x080c, 0x4de5,
+	0x003e, 0x004e, 0x001e, 0x0005, 0x080c, 0x6039, 0x709b, 0x0000,
+	0x7093, 0x0000, 0x0005, 0x0006, 0x2001, 0x180c, 0x2004, 0xd09c,
+	0x0100, 0x000e, 0x0005, 0x0006, 0x0016, 0x0126, 0x2091, 0x8000,
+	0x2001, 0x0101, 0x200c, 0x918d, 0x0006, 0x2102, 0x012e, 0x001e,
+	0x000e, 0x0005, 0x2009, 0x0001, 0x0020, 0x2009, 0x0002, 0x0008,
+	0x900e, 0x6814, 0x9084, 0xffc0, 0x910d, 0x6916, 0x0005, 0x00f6,
+	0x0156, 0x0146, 0x01d6, 0x9006, 0x20a9, 0x0080, 0x20e9, 0x0001,
+	0x20a1, 0x1d00, 0x4004, 0x2079, 0x1d00, 0x7803, 0x2200, 0x7807,
+	0x00ef, 0x780f, 0x00ef, 0x7813, 0x0138, 0x7823, 0xffff, 0x7827,
+	0xffff, 0x01de, 0x014e, 0x015e, 0x00fe, 0x0005, 0x2001, 0x1800,
+	0x2003, 0x0001, 0x0005, 0x2001, 0x19a7, 0x0118, 0x2003, 0x0001,
+	0x0010, 0x2003, 0x0000, 0x0005, 0x0156, 0x20a9, 0x0800, 0x2009,
+	0x1000, 0x9006, 0x200a, 0x8108, 0x1f04, 0x6192, 0x015e, 0x0005,
+	0x00d6, 0x0036, 0x0156, 0x0136, 0x0146, 0x2069, 0x1847, 0x9006,
+	0xb802, 0xb8d6, 0xb807, 0x0707, 0xb80a, 0xb80e, 0xb812, 0x9198,
+	0x3489, 0x231d, 0x939c, 0x00ff, 0xbb16, 0x0016, 0x0026, 0xb886,
+	0x080c, 0xae60, 0x1120, 0x9192, 0x007e, 0x1208, 0xbb86, 0x20a9,
+	0x0004, 0xb8c4, 0x20e8, 0xb9c8, 0x9198, 0x0006, 0x9006, 0x23a0,
+	0x4004, 0x20a9, 0x0004, 0x9198, 0x000a, 0x23a0, 0x4004, 0x002e,
+	0x001e, 0xb83e, 0xb842, 0xb8ce, 0xb8d2, 0xb85e, 0xb862, 0xb866,
+	0xb86a, 0xb86f, 0x0100, 0xb872, 0xb876, 0xb87a, 0xb88a, 0xb88e,
+	0xb893, 0x0008, 0xb896, 0xb89a, 0xb89e, 0xb8be, 0xb9a2, 0x0096,
+	0xb8a4, 0x904d, 0x0110, 0x080c, 0x108b, 0xb8a7, 0x0000, 0x009e,
+	0x9006, 0xb84a, 0x6810, 0xb83a, 0x680c, 0xb846, 0xb8bb, 0x0520,
+	0xb8ac, 0x9005, 0x0198, 0x00c6, 0x2060, 0x9c82, 0x1ddc, 0x0a0c,
+	0x0d85, 0x2001, 0x181a, 0x2004, 0x9c02, 0x1a0c, 0x0d85, 0x080c,
+	0x8d8f, 0x00ce, 0x090c, 0x9130, 0xb8af, 0x0000, 0x6814, 0x9084,
+	0x00ff, 0xb842, 0x014e, 0x013e, 0x015e, 0x003e, 0x00de, 0x0005,
+	0x0126, 0x2091, 0x8000, 0xa974, 0xae78, 0x9684, 0x3fff, 0x9082,
+	0x4000, 0x1a04, 0x626e, 0x9182, 0x0800, 0x1a04, 0x6272, 0x2001,
+	0x180c, 0x2004, 0x9084, 0x0003, 0x1904, 0x6278, 0x9188, 0x1000,
+	0x2104, 0x905d, 0x0198, 0xb804, 0x9084, 0x00ff, 0x908e, 0x0006,
+	0x1188, 0xb8a4, 0x900d, 0x1904, 0x628a, 0x080c, 0x664a, 0x9006,
+	0x012e, 0x0005, 0x2001, 0x0005, 0x900e, 0x04b8, 0x2001, 0x0028,
+	0x900e, 0x0498, 0x9082, 0x0006, 0x1290, 0x080c, 0xae60, 0x1160,
+	0xb8a0, 0x9084, 0xff80, 0x1140, 0xb900, 0xd1fc, 0x0d10, 0x2001,
+	0x0029, 0x2009, 0x1000, 0x0408, 0x2001, 0x0028, 0x00a8, 0x2009,
+	0x180c, 0x210c, 0xd18c, 0x0118, 0x2001, 0x0004, 0x0068, 0xd184,
+	0x0118, 0x2001, 0x0004, 0x0040, 0x2001, 0x0029, 0xb900, 0xd1fc,
+	0x0118, 0x2009, 0x1000, 0x0048, 0x900e, 0x0038, 0x2001, 0x0029,
+	0x900e, 0x0018, 0x2001, 0x0029, 0x900e, 0x9005, 0x012e, 0x0005,
+	0x2001, 0x180c, 0x2004, 0xd084, 0x19d0, 0x9188, 0x1000, 0x2104,
+	0x9065, 0x09a8, 0x080c, 0x6bd5, 0x1990, 0xb800, 0xd0bc, 0x0978,
+	0x0804, 0x6231, 0x080c, 0x69f8, 0x0904, 0x623a, 0x0804, 0x6235,
+	0x00e6, 0x2071, 0x19e9, 0x7004, 0x9086, 0x0002, 0x1128, 0x7030,
+	0x9080, 0x0004, 0x2004, 0x9b06, 0x00ee, 0x0005, 0x00b6, 0x00e6,
+	0x0126, 0x2091, 0x8000, 0xa874, 0x908e, 0x00ff, 0x1120, 0x2001,
+	0x196c, 0x205c, 0x0060, 0xa974, 0x9182, 0x0800, 0x1690, 0x9188,
+	0x1000, 0x2104, 0x905d, 0x01d0, 0x080c, 0x6b75, 0x11d0, 0x080c,
+	0xaed8, 0x0570, 0x2b00, 0x6012, 0x2900, 0x6016, 0x6023, 0x0009,
+	0x602b, 0x0000, 0xa874, 0x908e, 0x00ff, 0x1110, 0x602b, 0x8000,
+	0x2009, 0x0043, 0x080c, 0xafcc, 0x9006, 0x00b0, 0x2001, 0x0028,
+	0x0090, 0x2009, 0x180c, 0x210c, 0xd18c, 0x0118, 0x2001, 0x0004,
+	0x0038, 0xd184, 0x0118, 0x2001, 0x0004, 0x0010, 0x2001, 0x0029,
+	0x0010, 0x2001, 0x0029, 0x9005, 0x012e, 0x00ee, 0x00be, 0x0005,
+	0x2001, 0x002c, 0x0cc0, 0x00b6, 0x00e6, 0x0126, 0x2091, 0x8000,
+	0xa974, 0x9182, 0x0800, 0x1a04, 0x6369, 0x9188, 0x1000, 0x2104,
+	0x905d, 0x0904, 0x6341, 0xb8a0, 0x9086, 0x007f, 0x0190, 0xa87c,
+	0xd0fc, 0x1178, 0x080c, 0x6bdd, 0x0160, 0xa994, 0x81ff, 0x0130,
+	0x908e, 0x0004, 0x0130, 0x908e, 0x0005, 0x0118, 0x080c, 0x6bd5,
+	0x1598, 0xa87c, 0xd0fc, 0x01e0, 0xa894, 0x9005, 0x01c8, 0x2060,
+	0x0026, 0x2010, 0x080c, 0xcc04, 0x002e, 0x1120, 0x2001, 0x0008,
+	0x0804, 0x636b, 0x6020, 0x9086, 0x000a, 0x0120, 0x2001, 0x0008,
+	0x0804, 0x636b, 0x601a, 0x6003, 0x0008, 0x2900, 0x6016, 0x0058,
+	0x080c, 0xaed8, 0x05e8, 0x2b00, 0x6012, 0x2900, 0x6016, 0x600b,
+	0xffff, 0x6023, 0x000a, 0x2009, 0x0003, 0x080c, 0xafcc, 0x9006,
+	0x0458, 0x2001, 0x0028, 0x0438, 0x9082, 0x0006, 0x1290, 0x080c,
+	0xae60, 0x1160, 0xb8a0, 0x9084, 0xff80, 0x1140, 0xb900, 0xd1fc,
+	0x0900, 0x2001, 0x0029, 0x2009, 0x1000, 0x00a8, 0x2001, 0x0028,
+	0x0090, 0x2009, 0x180c, 0x210c, 0xd18c, 0x0118, 0x2001, 0x0004,
+	0x0050, 0xd184, 0x0118, 0x2001, 0x0004, 0x0028, 0x2001, 0x0029,
+	0x0010, 0x2001, 0x0029, 0x9005, 0x012e, 0x00ee, 0x00be, 0x0005,
+	0x2001, 0x002c, 0x0cc0, 0x00f6, 0x00b6, 0x0126, 0x2091, 0x8000,
+	0xa8e0, 0x9005, 0x1550, 0xa8dc, 0x9082, 0x0101, 0x1630, 0xa8c8,
+	0x9005, 0x1518, 0xa8c4, 0x9082, 0x0101, 0x12f8, 0xa974, 0x2079,
+	0x1800, 0x9182, 0x0800, 0x12e8, 0x7830, 0x9084, 0x0003, 0x1130,
+	0xaa98, 0xab94, 0xa878, 0x9084, 0x0007, 0x00ea, 0x7930, 0xd18c,
+	0x0118, 0x2001, 0x0004, 0x0038, 0xd184, 0x0118, 0x2001, 0x0004,
+	0x0010, 0x2001, 0x0029, 0x900e, 0x0038, 0x2001, 0x002c, 0x900e,
+	0x0018, 0x2001, 0x0029, 0x900e, 0x9006, 0x0008, 0x9005, 0x012e,
+	0x00be, 0x00fe, 0x0005, 0x6400, 0x63bb, 0x63d2, 0x6400, 0x6400,
+	0x6400, 0x6400, 0x6400, 0x2100, 0x9082, 0x007e, 0x1278, 0x080c,
+	0x671e, 0x0148, 0x9046, 0xb810, 0x9306, 0x1904, 0x6408, 0xb814,
+	0x9206, 0x15f0, 0x0028, 0xbb12, 0xba16, 0x0010, 0x080c, 0x4ae1,
+	0x0150, 0x04b0, 0x080c, 0x6789, 0x1598, 0xb810, 0x9306, 0x1580,
+	0xb814, 0x9206, 0x1568, 0x080c, 0xaed8, 0x0530, 0x2b00, 0x6012,
+	0x080c, 0xd0b1, 0x2900, 0x6016, 0x600b, 0xffff, 0x6023, 0x000a,
+	0xa878, 0x9086, 0x0001, 0x1170, 0x080c, 0x3310, 0x9006, 0x080c,
+	0x66bb, 0x2001, 0x0002, 0x080c, 0x66cf, 0x2001, 0x0200, 0xb86e,
+	0xb893, 0x0002, 0x2009, 0x0003, 0x080c, 0xafcc, 0x9006, 0x0068,
+	0x2001, 0x0001, 0x900e, 0x0038, 0x2001, 0x002c, 0x900e, 0x0018,
+	0x2001, 0x0028, 0x900e, 0x9005, 0x0000, 0x012e, 0x00be, 0x00fe,
+	0x0005, 0x00b6, 0x00f6, 0x00e6, 0x0126, 0x2091, 0x8000, 0xa894,
+	0x90c6, 0x0015, 0x0904, 0x65f3, 0x90c6, 0x0056, 0x0904, 0x65f7,
+	0x90c6, 0x0066, 0x0904, 0x65fb, 0x90c6, 0x0067, 0x0904, 0x65ff,
+	0x90c6, 0x0068, 0x0904, 0x6603, 0x90c6, 0x0071, 0x0904, 0x6607,
+	0x90c6, 0x0074, 0x0904, 0x660b, 0x90c6, 0x007c, 0x0904, 0x660f,
+	0x90c6, 0x007e, 0x0904, 0x6613, 0x90c6, 0x0037, 0x0904, 0x6617,
+	0x9016, 0x2079, 0x1800, 0xa974, 0x9186, 0x00ff, 0x0904, 0x65ee,
+	0x9182, 0x0800, 0x1a04, 0x65ee, 0x080c, 0x6789, 0x1198, 0xb804,
+	0x9084, 0x00ff, 0x9082, 0x0006, 0x1268, 0xa894, 0x90c6, 0x006f,
+	0x0148, 0x080c, 0xae60, 0x1904, 0x65d7, 0xb8a0, 0x9084, 0xff80,
+	0x1904, 0x65d7, 0xa894, 0x90c6, 0x006f, 0x0158, 0x90c6, 0x005e,
+	0x0904, 0x6537, 0x90c6, 0x0064, 0x0904, 0x6560, 0x2008, 0x0804,
+	0x64f9, 0xa998, 0xa8b0, 0x2040, 0x080c, 0xae60, 0x1120, 0x9182,
+	0x007f, 0x0a04, 0x64f9, 0x9186, 0x00ff, 0x0904, 0x64f9, 0x9182,
+	0x0800, 0x1a04, 0x64f9, 0xaaa0, 0xab9c, 0x787c, 0x9306, 0x11a8,
+	0x7880, 0x0096, 0x924e, 0x1128, 0x2208, 0x2310, 0x009e, 0x0804,
+	0x64f9, 0x080c, 0xae60, 0x1140, 0x99cc, 0xff00, 0x009e, 0x1128,
+	0x2208, 0x2310, 0x0804, 0x64f9, 0x009e, 0x080c, 0x4ae1, 0x0904,
+	0x6503, 0x900e, 0x9016, 0x90c6, 0x4000, 0x15e0, 0x0006, 0x080c,
+	0x6a7c, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x20a9,
+	0x0004, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0031, 0x20a0, 0xb8c4,
+	0x20e0, 0xb8c8, 0x9080, 0x0006, 0x2098, 0x080c, 0x0fd6, 0x20a9,
+	0x0004, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0035, 0x20a0, 0xb8c4,
+	0x20e0, 0xb8c8, 0x9080, 0x000a, 0x2098, 0x080c, 0x0fd6, 0xa8c4,
+	0xabc8, 0x9305, 0xabcc, 0x9305, 0xabd0, 0x9305, 0xabd4, 0x9305,
+	0xabd8, 0x9305, 0xabdc, 0x9305, 0xabe0, 0x9305, 0x9005, 0x0510,
+	0x000e, 0x00c8, 0x90c6, 0x4007, 0x1110, 0x2408, 0x00a0, 0x90c6,
+	0x4008, 0x1118, 0x2708, 0x2610, 0x0070, 0x90c6, 0x4009, 0x1108,
+	0x0050, 0x90c6, 0x4006, 0x0138, 0x2001, 0x4005, 0x2009, 0x000a,
+	0x0010, 0x2001, 0x4006, 0xa896, 0xa99a, 0xaa9e, 0x2001, 0x0030,
+	0x900e, 0x0478, 0x000e, 0x080c, 0xaed8, 0x1130, 0x2001, 0x4005,
+	0x2009, 0x0003, 0x9016, 0x0c78, 0x2b00, 0x6012, 0x080c, 0xd0b1,
+	0x2900, 0x6016, 0x6023, 0x0001, 0xa868, 0xd88c, 0x0108, 0xc0f5,
+	0xa86a, 0x0126, 0x2091, 0x8000, 0x080c, 0x3310, 0x012e, 0x9006,
+	0x080c, 0x66bb, 0x2001, 0x0002, 0x080c, 0x66cf, 0x2009, 0x0002,
+	0x080c, 0xafcc, 0xa8b0, 0xd094, 0x0118, 0xb8d4, 0xc08d, 0xb8d6,
+	0x9006, 0x9005, 0x012e, 0x00ee, 0x00fe, 0x00be, 0x0005, 0x080c,
+	0x583a, 0x0118, 0x2009, 0x0007, 0x00f8, 0xa998, 0xaeb0, 0x080c,
+	0x6789, 0x1904, 0x64f4, 0x9186, 0x007f, 0x0130, 0x080c, 0x6bd5,
+	0x0118, 0x2009, 0x0009, 0x0080, 0x0096, 0x080c, 0x1059, 0x1120,
+	0x009e, 0x2009, 0x0002, 0x0040, 0x2900, 0x009e, 0xa806, 0x080c,
+	0xce04, 0x19b0, 0x2009, 0x0003, 0x2001, 0x4005, 0x0804, 0x64fb,
+	0xa998, 0xaeb0, 0x080c, 0x6789, 0x1904, 0x64f4, 0x0096, 0x080c,
+	0x1059, 0x1128, 0x009e, 0x2009, 0x0002, 0x0804, 0x65b4, 0x2900,
+	0x009e, 0xa806, 0x0096, 0x2048, 0x20a9, 0x002b, 0xb8c4, 0x20e0,
+	0xb8c8, 0x2098, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0002, 0x20a0,
+	0x4003, 0x20a9, 0x0008, 0x9080, 0x0006, 0x20a0, 0xbbc8, 0x9398,
+	0x0006, 0x2398, 0x080c, 0x0fd6, 0x009e, 0xa87b, 0x0000, 0xa883,
+	0x0000, 0xa897, 0x4000, 0xd684, 0x1168, 0x080c, 0x5826, 0xd0b4,
+	0x1118, 0xa89b, 0x000b, 0x00e0, 0xb800, 0xd08c, 0x0118, 0xa89b,
+	0x000c, 0x00b0, 0x080c, 0x6bd5, 0x0118, 0xa89b, 0x0009, 0x0080,
+	0x080c, 0x583a, 0x0118, 0xa89b, 0x0007, 0x0050, 0x080c, 0xcde7,
+	0x1904, 0x6530, 0x2009, 0x0003, 0x2001, 0x4005, 0x0804, 0x64fb,
+	0xa87b, 0x0030, 0xa897, 0x4005, 0xa804, 0x8006, 0x8006, 0x8007,
+	0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x0002, 0x2009, 0x002b,
+	0xaaa0, 0xab9c, 0xaca8, 0xada4, 0x2031, 0x0000, 0x2041, 0x12a8,
+	0x080c, 0xb456, 0x1904, 0x6530, 0x2009, 0x0002, 0x08e8, 0x2001,
+	0x0028, 0x900e, 0x0804, 0x6531, 0x2009, 0x180c, 0x210c, 0xd18c,
+	0x0118, 0x2001, 0x0004, 0x0038, 0xd184, 0x0118, 0x2001, 0x0004,
+	0x0010, 0x2001, 0x0029, 0x900e, 0x0804, 0x6531, 0x2001, 0x0029,
+	0x900e, 0x0804, 0x6531, 0x080c, 0x38b9, 0x0804, 0x6532, 0x080c,
+	0x5543, 0x0804, 0x6532, 0x080c, 0x4692, 0x0804, 0x6532, 0x080c,
+	0x470b, 0x0804, 0x6532, 0x080c, 0x4767, 0x0804, 0x6532, 0x080c,
+	0x4ba4, 0x0804, 0x6532, 0x080c, 0x4e58, 0x0804, 0x6532, 0x080c,
+	0x51aa, 0x0804, 0x6532, 0x080c, 0x53a3, 0x0804, 0x6532, 0x080c,
+	0x3ad7, 0x0804, 0x6532, 0x00b6, 0xa974, 0xae78, 0x9684, 0x3fff,
+	0x9082, 0x4000, 0x1608, 0x9182, 0x0800, 0x1258, 0x9188, 0x1000,
+	0x2104, 0x905d, 0x0130, 0x080c, 0x6bd5, 0x1138, 0x00d9, 0x9006,
+	0x00b0, 0x2001, 0x0028, 0x900e, 0x0090, 0x9082, 0x0006, 0x1240,
+	0xb900, 0xd1fc, 0x0d98, 0x2001, 0x0029, 0x2009, 0x1000, 0x0038,
+	0x2001, 0x0029, 0x900e, 0x0018, 0x2001, 0x0029, 0x900e, 0x9005,
+	0x00be, 0x0005, 0xa877, 0x0000, 0xb8d0, 0x9005, 0x1904, 0x66af,
+	0xb888, 0x9005, 0x1904, 0x66af, 0xb838, 0xb93c, 0x9102, 0x1a04,
+	0x66af, 0x2b10, 0x080c, 0xaf05, 0x0904, 0x66ab, 0x8108, 0xb93e,
+	0x6212, 0x2900, 0x6016, 0x6023, 0x0003, 0x600b, 0xffff, 0x6007,
+	0x0040, 0xa878, 0x605e, 0xa880, 0x6066, 0xa883, 0x0000, 0xa87c,
+	0xd0ac, 0x0588, 0xc0dd, 0xa87e, 0xa888, 0x8001, 0x1530, 0xa816,
+	0xa864, 0x9094, 0x00f7, 0x9296, 0x0011, 0x11f8, 0x9084, 0x00ff,
+	0xc0bd, 0x601e, 0xa8ac, 0xaab0, 0xa836, 0xaa3a, 0x2001, 0x000f,
+	0x8001, 0x1df0, 0x2001, 0x8004, 0x6003, 0x0004, 0x6046, 0x00f6,
+	0x2079, 0x0380, 0x7818, 0xd0bc, 0x1de8, 0x7833, 0x0010, 0x2c00,
+	0x7836, 0x781b, 0x8080, 0x00fe, 0x0005, 0x080c, 0x17ad, 0x601c,
+	0xc0bd, 0x601e, 0x0c38, 0xd0b4, 0x190c, 0x1cbd, 0x2001, 0x8004,
+	0x6003, 0x0002, 0x0c18, 0x81ff, 0x1110, 0xb88b, 0x0001, 0x2908,
+	0xb8cc, 0xb9ce, 0x9005, 0x1110, 0xb9d2, 0x0020, 0x0096, 0x2048,
+	0xa902, 0x009e, 0x0005, 0x00b6, 0x0126, 0x00c6, 0x0026, 0x2091,
+	0x8000, 0x6210, 0x2258, 0xba00, 0x9005, 0x0110, 0xc285, 0x0008,
+	0xc284, 0xba02, 0x002e, 0x00ce, 0x012e, 0x00be, 0x0005, 0x00b6,
 	0x0126, 0x00c6, 0x2091, 0x8000, 0x6210, 0x2258, 0xba04, 0x0006,
-	0x9086, 0x0006, 0x1168, 0xb89c, 0xd0a4, 0x0150, 0x080c, 0x6ad5,
-	0x1138, 0x9284, 0x00ff, 0x9086, 0x0007, 0x1110, 0x2011, 0x0006,
-	0x000e, 0x9294, 0x00ff, 0x8007, 0x9215, 0xba06, 0x00ce, 0x012e,
-	0x00be, 0x0005, 0x9182, 0x0800, 0x0218, 0x9085, 0x0001, 0x0005,
-	0x00d6, 0x0026, 0x9190, 0x1000, 0x2204, 0x905d, 0x1188, 0x0096,
-	0x080c, 0x1047, 0x2958, 0x009e, 0x0168, 0x2b00, 0x2012, 0xb85c,
-	0xb8ca, 0xb860, 0xb8c6, 0x9006, 0xb8a6, 0xb8ae, 0x080c, 0x60ac,
-	0x9006, 0x0010, 0x9085, 0x0001, 0x002e, 0x00de, 0x0005, 0x00b6,
-	0x0096, 0x0126, 0x2091, 0x8000, 0x0026, 0x9182, 0x0800, 0x0218,
-	0x9085, 0x0001, 0x0458, 0x00d6, 0x9190, 0x1000, 0x2204, 0x905d,
-	0x0518, 0x2013, 0x0000, 0xb8a4, 0x904d, 0x0110, 0x080c, 0x1079,
-	0x00d6, 0x00c6, 0xb8bc, 0x2060, 0x8cff, 0x0168, 0x600c, 0x0006,
-	0x6014, 0x2048, 0x080c, 0xc97a, 0x0110, 0x080c, 0x0ff9, 0x080c,
-	0xacb0, 0x00ce, 0x0c88, 0x00ce, 0x00de, 0x2b48, 0xb8c8, 0xb85e,
-	0xb8c4, 0xb862, 0x080c, 0x1089, 0x00de, 0x9006, 0x002e, 0x012e,
-	0x009e, 0x00be, 0x0005, 0x0016, 0x9182, 0x0800, 0x0218, 0x9085,
-	0x0001, 0x0030, 0x9188, 0x1000, 0x2104, 0x905d, 0x0dc0, 0x9006,
-	0x001e, 0x0005, 0x00d6, 0x0156, 0x0136, 0x0146, 0x9006, 0xb80a,
-	0xb80e, 0xb800, 0xc08c, 0xb802, 0x080c, 0x753d, 0x1510, 0xb8a0,
-	0x9086, 0x007e, 0x0120, 0x080c, 0xabe2, 0x11d8, 0x0078, 0x7040,
-	0xd0e4, 0x01b8, 0x00c6, 0x2061, 0x1981, 0x7048, 0x2062, 0x704c,
-	0x6006, 0x7050, 0x600a, 0x7054, 0x600e, 0x00ce, 0x703c, 0x2069,
-	0x0140, 0x9005, 0x1110, 0x2001, 0x0001, 0x6886, 0x2069, 0x1800,
-	0x68b6, 0x7040, 0xb85e, 0x7048, 0xb862, 0x704c, 0xb866, 0x20e1,
-	0x0000, 0x2099, 0x0276, 0xb8c4, 0x20e8, 0xb8c8, 0x9088, 0x000a,
-	0x21a0, 0x20a9, 0x0004, 0x4003, 0x2099, 0x027a, 0x9088, 0x0006,
-	0x21a0, 0x20a9, 0x0004, 0x4003, 0x2069, 0x0200, 0x6817, 0x0001,
-	0x7040, 0xb86a, 0x7144, 0xb96e, 0x7048, 0xb872, 0x7050, 0xb876,
-	0x2069, 0x0200, 0x6817, 0x0000, 0xb8a0, 0x9086, 0x007e, 0x1110,
-	0x7144, 0xb96e, 0x9182, 0x0211, 0x1218, 0x2009, 0x0008, 0x0400,
-	0x9182, 0x0259, 0x1218, 0x2009, 0x0007, 0x00d0, 0x9182, 0x02c1,
-	0x1218, 0x2009, 0x0006, 0x00a0, 0x9182, 0x0349, 0x1218, 0x2009,
-	0x0005, 0x0070, 0x9182, 0x0421, 0x1218, 0x2009, 0x0004, 0x0040,
-	0x9182, 0x0581, 0x1218, 0x2009, 0x0003, 0x0010, 0x2009, 0x0002,
-	0xb992, 0x014e, 0x013e, 0x015e, 0x00de, 0x0005, 0x0016, 0x0026,
-	0x00e6, 0x2071, 0x0260, 0x7034, 0xb896, 0x703c, 0xb89a, 0x7054,
-	0xb89e, 0x0036, 0xbbd4, 0xc384, 0xba00, 0x2009, 0x1867, 0x210c,
-	0xd0bc, 0x0120, 0xd1ec, 0x0110, 0xc2ad, 0x0008, 0xc2ac, 0xd0c4,
-	0x0148, 0xd1e4, 0x0138, 0xc2bd, 0xd0cc, 0x0128, 0xd38c, 0x1108,
-	0xc385, 0x0008, 0xc2bc, 0xba02, 0xbbd6, 0x003e, 0x00ee, 0x002e,
-	0x001e, 0x0005, 0x0096, 0x0126, 0x2091, 0x8000, 0xb8a4, 0x904d,
-	0x0578, 0xa900, 0x81ff, 0x15c0, 0xaa04, 0x9282, 0x0010, 0x16c8,
-	0x0136, 0x0146, 0x01c6, 0x01d6, 0x8906, 0x8006, 0x8007, 0x908c,
-	0x003f, 0x21e0, 0x9084, 0xffc0, 0x9080, 0x0004, 0x2098, 0x2009,
-	0x0010, 0x20a9, 0x0001, 0x4002, 0x9086, 0xffff, 0x0120, 0x8109,
-	0x1dd0, 0x080c, 0x0d7d, 0x3c00, 0x20e8, 0x3300, 0x8001, 0x20a0,
-	0x4604, 0x8210, 0xaa06, 0x01de, 0x01ce, 0x014e, 0x013e, 0x0060,
-	0x080c, 0x1047, 0x0170, 0x2900, 0xb8a6, 0xa803, 0x0000, 0x080c,
-	0x6922, 0xa807, 0x0001, 0xae12, 0x9085, 0x0001, 0x012e, 0x009e,
-	0x0005, 0x9006, 0x0cd8, 0x0126, 0x2091, 0x8000, 0x0096, 0xb8a4,
-	0x904d, 0x0188, 0xa800, 0x9005, 0x1150, 0x080c, 0x6931, 0x1158,
-	0xa804, 0x908a, 0x0002, 0x0218, 0x8001, 0xa806, 0x0020, 0x080c,
-	0x1079, 0xb8a7, 0x0000, 0x009e, 0x012e, 0x0005, 0x0096, 0x00c6,
-	0xb888, 0x9005, 0x1904, 0x6817, 0xb8d0, 0x904d, 0x0904, 0x6817,
-	0x080c, 0xac87, 0x0904, 0x6813, 0x8210, 0xba3e, 0xa800, 0xb8d2,
-	0x9005, 0x1108, 0xb8ce, 0x2b00, 0x6012, 0x2900, 0x6016, 0x6023,
-	0x0003, 0x600b, 0xffff, 0x6007, 0x0040, 0xa878, 0x605e, 0xa880,
-	0x9084, 0x00ff, 0x6066, 0xa883, 0x0000, 0xa87c, 0xd0ac, 0x01c8,
-	0xc0dd, 0xa87e, 0xa888, 0x8001, 0x1568, 0xa816, 0xa864, 0x9094,
-	0x00f7, 0x9296, 0x0011, 0x1530, 0x9084, 0x00ff, 0xc0bd, 0x601e,
-	0xa8ac, 0xaab0, 0xa836, 0xaa3a, 0x2001, 0x8004, 0x6003, 0x0004,
-	0x0030, 0x080c, 0x1c86, 0x2001, 0x8004, 0x6003, 0x0002, 0x6046,
-	0x2001, 0x0010, 0x2c08, 0x080c, 0xa90f, 0xb838, 0xba3c, 0x9202,
-	0x0a04, 0x67c4, 0x0020, 0x82ff, 0x1110, 0xb88b, 0x0001, 0x00ce,
-	0x009e, 0x0005, 0x080c, 0x1778, 0x601c, 0xc0bd, 0x601e, 0x08e0,
-	0x00b6, 0x0096, 0x0016, 0x20a9, 0x0800, 0x900e, 0x0016, 0x080c,
-	0x6693, 0x1158, 0xb8d0, 0x904d, 0x0140, 0x3e00, 0x9086, 0x0002,
-	0x1118, 0xb800, 0xd0bc, 0x1108, 0x0041, 0x001e, 0x8108, 0x1f04,
-	0x6826, 0x001e, 0x00be, 0x009e, 0x0005, 0x0096, 0x0016, 0xb8d0,
-	0x904d, 0x0188, 0xa800, 0xb8d2, 0x9005, 0x1108, 0xb8ce, 0x9006,
-	0xa802, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0xcc7f,
-	0x080c, 0x6dee, 0x0c60, 0x001e, 0x009e, 0x0005, 0x0086, 0x9046,
-	0xb8d0, 0x904d, 0x01b0, 0xa86c, 0x9406, 0x1118, 0xa870, 0x9506,
-	0x0128, 0x2940, 0xa800, 0x904d, 0x0160, 0x0ca8, 0xa800, 0x88ff,
-	0x1128, 0xb8d2, 0x9005, 0x1118, 0xb8ce, 0x0008, 0xa002, 0xa803,
-	0x0000, 0x008e, 0x0005, 0x901e, 0x0010, 0x2019, 0x0001, 0x0126,
-	0x2091, 0x8000, 0x00e6, 0x0096, 0x00c6, 0x0086, 0x0026, 0x2071,
-	0x19e6, 0x9046, 0x7028, 0x9065, 0x01e8, 0x6014, 0x2068, 0x83ff,
-	0x0120, 0x605c, 0x9606, 0x0158, 0x0030, 0xa86c, 0x9406, 0x1118,
-	0xa870, 0x9506, 0x0120, 0x2c40, 0x600c, 0x2060, 0x0c60, 0x600c,
-	0x0006, 0x0066, 0x2830, 0x080c, 0xa042, 0x006e, 0x000e, 0x83ff,
-	0x0508, 0x0c08, 0x9046, 0xb8d0, 0x904d, 0x01e0, 0x83ff, 0x0120,
-	0xa878, 0x9606, 0x0158, 0x0030, 0xa86c, 0x9406, 0x1118, 0xa870,
-	0x9506, 0x0120, 0x2940, 0xa800, 0x2048, 0x0c70, 0xb8d0, 0xaa00,
-	0x0026, 0x9906, 0x1110, 0xbad2, 0x0008, 0xa202, 0x000e, 0x83ff,
-	0x0108, 0x0c10, 0x002e, 0x008e, 0x00ce, 0x009e, 0x00ee, 0x012e,
-	0x0005, 0x9016, 0x0489, 0x1110, 0x2011, 0x0001, 0x0005, 0x080c,
-	0x6986, 0x0128, 0x080c, 0xca3b, 0x0010, 0x9085, 0x0001, 0x0005,
-	0x080c, 0x6986, 0x0128, 0x080c, 0xc9dc, 0x0010, 0x9085, 0x0001,
-	0x0005, 0x080c, 0x6986, 0x0128, 0x080c, 0xca38, 0x0010, 0x9085,
-	0x0001, 0x0005, 0x080c, 0x6986, 0x0128, 0x080c, 0xc9fb, 0x0010,
-	0x9085, 0x0001, 0x0005, 0x080c, 0x6986, 0x0128, 0x080c, 0xca7e,
-	0x0010, 0x9085, 0x0001, 0x0005, 0xb8a4, 0x900d, 0x1118, 0x9085,
-	0x0001, 0x0005, 0x0136, 0x01c6, 0xa800, 0x9005, 0x11b8, 0x890e,
-	0x810e, 0x810f, 0x9184, 0x003f, 0x20e0, 0x9184, 0xffc0, 0x9080,
-	0x0004, 0x2098, 0x20a9, 0x0001, 0x2009, 0x0010, 0x4002, 0x9606,
-	0x0128, 0x8109, 0x1dd8, 0x9085, 0x0001, 0x0008, 0x9006, 0x01ce,
-	0x013e, 0x0005, 0x0146, 0x01d6, 0xa860, 0x20e8, 0xa85c, 0x9080,
-	0x0004, 0x20a0, 0x20a9, 0x0010, 0x2009, 0xffff, 0x4104, 0x01de,
-	0x014e, 0x0136, 0x01c6, 0xa800, 0x9005, 0x11b8, 0x890e, 0x810e,
-	0x810f, 0x9184, 0x003f, 0x20e0, 0x9184, 0xffc0, 0x9080, 0x0004,
-	0x2098, 0x20a9, 0x0001, 0x2009, 0x0010, 0x4002, 0x9606, 0x0128,
-	0x8109, 0x1dd8, 0x9085, 0x0001, 0x0068, 0x0146, 0x01d6, 0x3300,
-	0x8001, 0x20a0, 0x3c00, 0x20e8, 0x2001, 0xffff, 0x4004, 0x01de,
-	0x014e, 0x9006, 0x01ce, 0x013e, 0x0005, 0x0096, 0x0126, 0x2091,
-	0x8000, 0xb8a4, 0x904d, 0x1128, 0x080c, 0x1047, 0x0168, 0x2900,
-	0xb8a6, 0x080c, 0x6922, 0xa803, 0x0001, 0xa807, 0x0000, 0x9085,
-	0x0001, 0x012e, 0x009e, 0x0005, 0x9006, 0x0cd8, 0x0096, 0x0126,
-	0x2091, 0x8000, 0xb8a4, 0x904d, 0x0130, 0xb8a7, 0x0000, 0x080c,
-	0x1079, 0x9085, 0x0001, 0x012e, 0x009e, 0x0005, 0xb89c, 0xd0a4,
-	0x0005, 0x00b6, 0x00f6, 0x080c, 0x753d, 0x01b0, 0x71c4, 0x81ff,
-	0x1198, 0x71dc, 0xd19c, 0x0180, 0x2001, 0x007e, 0x9080, 0x1000,
-	0x2004, 0x905d, 0x0148, 0xb804, 0x9084, 0x00ff, 0x9086, 0x0006,
-	0x1118, 0xb800, 0xc0ed, 0xb802, 0x2079, 0x1847, 0x7804, 0xd0a4,
-	0x01d0, 0x0156, 0x20a9, 0x007f, 0x900e, 0x0016, 0x080c, 0x6693,
-	0x1168, 0xb804, 0x9084, 0xff00, 0x8007, 0x9096, 0x0004, 0x0118,
-	0x9086, 0x0006, 0x1118, 0xb800, 0xc0ed, 0xb802, 0x001e, 0x8108,
-	0x1f04, 0x69ad, 0x015e, 0x080c, 0x6a9b, 0x0120, 0x2001, 0x1984,
-	0x200c, 0x0038, 0x2079, 0x1847, 0x7804, 0xd0a4, 0x0130, 0x2009,
-	0x07d0, 0x2011, 0x69d8, 0x080c, 0x8792, 0x00fe, 0x00be, 0x0005,
-	0x00b6, 0x2011, 0x69d8, 0x080c, 0x86c8, 0x080c, 0x6a9b, 0x01d8,
-	0x2001, 0x107e, 0x2004, 0x2058, 0xb900, 0xc1ec, 0xb902, 0x080c,
-	0x6ad9, 0x0130, 0x2009, 0x07d0, 0x2011, 0x69d8, 0x080c, 0x8792,
-	0x00e6, 0x2071, 0x1800, 0x9006, 0x707e, 0x7060, 0x7082, 0x080c,
-	0x3011, 0x00ee, 0x04d0, 0x0156, 0x00c6, 0x20a9, 0x007f, 0x900e,
-	0x0016, 0x080c, 0x6693, 0x1558, 0xb800, 0xd0ec, 0x0540, 0x0046,
-	0xbaa0, 0x2220, 0x9006, 0x2009, 0x0029, 0x080c, 0xe445, 0xb800,
-	0xc0e5, 0xc0ec, 0xb802, 0x080c, 0x6ad5, 0x2001, 0x0707, 0x1128,
-	0xb804, 0x9084, 0x00ff, 0x9085, 0x0700, 0xb806, 0x080c, 0xa91e,
-	0x2019, 0x0029, 0x080c, 0x943d, 0x0076, 0x903e, 0x080c, 0x9306,
-	0x900e, 0x080c, 0xe167, 0x007e, 0x004e, 0x080c, 0xa93a, 0x001e,
-	0x8108, 0x1f04, 0x6a00, 0x00ce, 0x015e, 0x00be, 0x0005, 0x00b6,
+	0x9086, 0x0006, 0x1170, 0xb89c, 0xd0ac, 0x0158, 0x080c, 0x6bd1,
+	0x0140, 0x9284, 0xff00, 0x8007, 0x9086, 0x0007, 0x1110, 0x2011,
+	0x0600, 0x000e, 0x9294, 0xff00, 0x9215, 0xba06, 0x0006, 0x9086,
+	0x0006, 0x1120, 0xba90, 0x82ff, 0x090c, 0x0d85, 0x000e, 0x00ce,
+	0x012e, 0x00be, 0x0005, 0x00b6, 0x0126, 0x00c6, 0x2091, 0x8000,
+	0x6210, 0x2258, 0xba04, 0x0006, 0x9086, 0x0006, 0x1168, 0xb89c,
+	0xd0a4, 0x0150, 0x080c, 0x6bcd, 0x1138, 0x9284, 0x00ff, 0x9086,
+	0x0007, 0x1110, 0x2011, 0x0006, 0x000e, 0x9294, 0x00ff, 0x8007,
+	0x9215, 0xba06, 0x00ce, 0x012e, 0x00be, 0x0005, 0x9182, 0x0800,
+	0x0218, 0x9085, 0x0001, 0x0005, 0x00d6, 0x0026, 0x9190, 0x1000,
+	0x2204, 0x905d, 0x1188, 0x0096, 0x080c, 0x1059, 0x2958, 0x009e,
+	0x0168, 0x2b00, 0x2012, 0xb85c, 0xb8ca, 0xb860, 0xb8c6, 0x9006,
+	0xb8a6, 0xb8ae, 0x080c, 0x6198, 0x9006, 0x0010, 0x9085, 0x0001,
+	0x002e, 0x00de, 0x0005, 0x00b6, 0x0096, 0x0126, 0x2091, 0x8000,
+	0x0026, 0x9182, 0x0800, 0x0218, 0x9085, 0x0001, 0x04a8, 0x00d6,
+	0x9190, 0x1000, 0x2204, 0x905d, 0x0568, 0x2013, 0x0000, 0xb8a4,
+	0x904d, 0x0110, 0x080c, 0x108b, 0x00d6, 0x00c6, 0xb8bc, 0x2060,
+	0x8cff, 0x0168, 0x600c, 0x0006, 0x6014, 0x2048, 0x080c, 0xcc16,
+	0x0110, 0x080c, 0x100b, 0x080c, 0xaf2e, 0x00ce, 0x0c88, 0x00ce,
+	0x00de, 0x00c6, 0xb8ac, 0x9065, 0x0128, 0x621c, 0xd2c4, 0x0110,
+	0x080c, 0x9130, 0x00ce, 0x2b48, 0xb8c8, 0xb85e, 0xb8c4, 0xb862,
+	0x080c, 0x109b, 0x00de, 0x9006, 0x002e, 0x012e, 0x009e, 0x00be,
+	0x0005, 0x0016, 0x9182, 0x0800, 0x0218, 0x9085, 0x0001, 0x0030,
+	0x9188, 0x1000, 0x2104, 0x905d, 0x0dc0, 0x9006, 0x001e, 0x0005,
+	0x00d6, 0x0156, 0x0136, 0x0146, 0x9006, 0xb80a, 0xb80e, 0xb800,
+	0xc08c, 0xb802, 0x080c, 0x76a5, 0x1510, 0xb8a0, 0x9086, 0x007e,
+	0x0120, 0x080c, 0xae60, 0x11d8, 0x0078, 0x7040, 0xd0e4, 0x01b8,
+	0x00c6, 0x2061, 0x1983, 0x7048, 0x2062, 0x704c, 0x6006, 0x7050,
+	0x600a, 0x7054, 0x600e, 0x00ce, 0x703c, 0x2069, 0x0140, 0x9005,
+	0x1110, 0x2001, 0x0001, 0x6886, 0x2069, 0x1800, 0x68b6, 0x7040,
+	0xb85e, 0x7048, 0xb862, 0x704c, 0xb866, 0x20e1, 0x0000, 0x2099,
+	0x0276, 0xb8c4, 0x20e8, 0xb8c8, 0x9088, 0x000a, 0x21a0, 0x20a9,
+	0x0004, 0x4003, 0x2099, 0x027a, 0x9088, 0x0006, 0x21a0, 0x20a9,
+	0x0004, 0x4003, 0x2069, 0x0200, 0x6817, 0x0001, 0x7040, 0xb86a,
+	0x7144, 0xb96e, 0x7048, 0xb872, 0x7050, 0xb876, 0x2069, 0x0200,
+	0x6817, 0x0000, 0xb8a0, 0x9086, 0x007e, 0x1110, 0x7144, 0xb96e,
+	0x9182, 0x0211, 0x1218, 0x2009, 0x0008, 0x0400, 0x9182, 0x0259,
+	0x1218, 0x2009, 0x0007, 0x00d0, 0x9182, 0x02c1, 0x1218, 0x2009,
+	0x0006, 0x00a0, 0x9182, 0x0349, 0x1218, 0x2009, 0x0005, 0x0070,
+	0x9182, 0x0421, 0x1218, 0x2009, 0x0004, 0x0040, 0x9182, 0x0581,
+	0x1218, 0x2009, 0x0003, 0x0010, 0x2009, 0x0002, 0xb992, 0x014e,
+	0x013e, 0x015e, 0x00de, 0x0005, 0x0016, 0x0026, 0x00e6, 0x2071,
+	0x0260, 0x7034, 0xb896, 0x703c, 0xb89a, 0x7054, 0xb89e, 0x0036,
+	0xbbd4, 0xc384, 0xba00, 0x2009, 0x1867, 0x210c, 0xd0bc, 0x0120,
+	0xd1ec, 0x0110, 0xc2ad, 0x0008, 0xc2ac, 0xd0c4, 0x0148, 0xd1e4,
+	0x0138, 0xc2bd, 0xd0cc, 0x0128, 0xd38c, 0x1108, 0xc385, 0x0008,
+	0xc2bc, 0xba02, 0xbbd6, 0x003e, 0x00ee, 0x002e, 0x001e, 0x0005,
+	0x0096, 0x0126, 0x2091, 0x8000, 0xb8a4, 0x904d, 0x0578, 0xa900,
+	0x81ff, 0x15c0, 0xaa04, 0x9282, 0x0010, 0x16c8, 0x0136, 0x0146,
+	0x01c6, 0x01d6, 0x8906, 0x8006, 0x8007, 0x908c, 0x003f, 0x21e0,
+	0x9084, 0xffc0, 0x9080, 0x0004, 0x2098, 0x2009, 0x0010, 0x20a9,
+	0x0001, 0x4002, 0x9086, 0xffff, 0x0120, 0x8109, 0x1dd0, 0x080c,
+	0x0d85, 0x3c00, 0x20e8, 0x3300, 0x8001, 0x20a0, 0x4604, 0x8210,
+	0xaa06, 0x01de, 0x01ce, 0x014e, 0x013e, 0x0060, 0x080c, 0x1059,
+	0x0170, 0x2900, 0xb8a6, 0xa803, 0x0000, 0x080c, 0x6a18, 0xa807,
+	0x0001, 0xae12, 0x9085, 0x0001, 0x012e, 0x009e, 0x0005, 0x9006,
+	0x0cd8, 0x0126, 0x2091, 0x8000, 0x0096, 0xb8a4, 0x904d, 0x0188,
+	0xa800, 0x9005, 0x1150, 0x080c, 0x6a27, 0x1158, 0xa804, 0x908a,
+	0x0002, 0x0218, 0x8001, 0xa806, 0x0020, 0x080c, 0x108b, 0xb8a7,
+	0x0000, 0x009e, 0x012e, 0x0005, 0x0096, 0x00c6, 0xb888, 0x9005,
+	0x1904, 0x690d, 0xb8d0, 0x904d, 0x0904, 0x690d, 0x080c, 0xaf05,
+	0x0904, 0x6909, 0x8210, 0xba3e, 0xa800, 0xb8d2, 0x9005, 0x1108,
+	0xb8ce, 0x2b00, 0x6012, 0x2900, 0x6016, 0x6023, 0x0003, 0x600b,
+	0xffff, 0x6007, 0x0040, 0xa878, 0x605e, 0xa880, 0x9084, 0x00ff,
+	0x6066, 0xa883, 0x0000, 0xa87c, 0xd0ac, 0x01c8, 0xc0dd, 0xa87e,
+	0xa888, 0x8001, 0x1568, 0xa816, 0xa864, 0x9094, 0x00f7, 0x9296,
+	0x0011, 0x1530, 0x9084, 0x00ff, 0xc0bd, 0x601e, 0xa8ac, 0xaab0,
+	0xa836, 0xaa3a, 0x2001, 0x8004, 0x6003, 0x0004, 0x0030, 0x080c,
+	0x1cbd, 0x2001, 0x8004, 0x6003, 0x0002, 0x6046, 0x2001, 0x0010,
+	0x2c08, 0x080c, 0xaad1, 0xb838, 0xba3c, 0x9202, 0x0a04, 0x68ba,
+	0x0020, 0x82ff, 0x1110, 0xb88b, 0x0001, 0x00ce, 0x009e, 0x0005,
+	0x080c, 0x17ad, 0x601c, 0xc0bd, 0x601e, 0x08e0, 0x00b6, 0x0096,
+	0x0016, 0x20a9, 0x0800, 0x900e, 0x0016, 0x080c, 0x6789, 0x1158,
+	0xb8d0, 0x904d, 0x0140, 0x3e00, 0x9086, 0x0002, 0x1118, 0xb800,
+	0xd0bc, 0x1108, 0x0041, 0x001e, 0x8108, 0x1f04, 0x691c, 0x001e,
+	0x00be, 0x009e, 0x0005, 0x0096, 0x0016, 0xb8d0, 0x904d, 0x0188,
+	0xa800, 0xb8d2, 0x9005, 0x1108, 0xb8ce, 0x9006, 0xa802, 0xa867,
+	0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0xcf1b, 0x080c, 0x6f19,
+	0x0c60, 0x001e, 0x009e, 0x0005, 0x0086, 0x9046, 0xb8d0, 0x904d,
+	0x01b0, 0xa86c, 0x9406, 0x1118, 0xa870, 0x9506, 0x0128, 0x2940,
+	0xa800, 0x904d, 0x0160, 0x0ca8, 0xa800, 0x88ff, 0x1128, 0xb8d2,
+	0x9005, 0x1118, 0xb8ce, 0x0008, 0xa002, 0xa803, 0x0000, 0x008e,
+	0x0005, 0x901e, 0x0010, 0x2019, 0x0001, 0x0126, 0x2091, 0x8000,
+	0x00e6, 0x0096, 0x00c6, 0x0086, 0x0026, 0x2071, 0x19e9, 0x9046,
+	0x7028, 0x9065, 0x01e8, 0x6014, 0x2068, 0x83ff, 0x0120, 0x605c,
+	0x9606, 0x0158, 0x0030, 0xa86c, 0x9406, 0x1118, 0xa870, 0x9506,
+	0x0120, 0x2c40, 0x600c, 0x2060, 0x0c60, 0x600c, 0x0006, 0x0066,
+	0x2830, 0x080c, 0xa20a, 0x006e, 0x000e, 0x83ff, 0x0508, 0x0c08,
+	0x9046, 0xb8d0, 0x904d, 0x01e0, 0x83ff, 0x0120, 0xa878, 0x9606,
+	0x0158, 0x0030, 0xa86c, 0x9406, 0x1118, 0xa870, 0x9506, 0x0120,
+	0x2940, 0xa800, 0x2048, 0x0c70, 0xb8d0, 0xaa00, 0x0026, 0x9906,
+	0x1110, 0xbad2, 0x0008, 0xa202, 0x000e, 0x83ff, 0x0108, 0x0c10,
+	0x002e, 0x008e, 0x00ce, 0x009e, 0x00ee, 0x012e, 0x0005, 0x9016,
+	0x0489, 0x1110, 0x2011, 0x0001, 0x0005, 0x080c, 0x6a7c, 0x0128,
+	0x080c, 0xccd7, 0x0010, 0x9085, 0x0001, 0x0005, 0x080c, 0x6a7c,
+	0x0128, 0x080c, 0xcc78, 0x0010, 0x9085, 0x0001, 0x0005, 0x080c,
+	0x6a7c, 0x0128, 0x080c, 0xccd4, 0x0010, 0x9085, 0x0001, 0x0005,
+	0x080c, 0x6a7c, 0x0128, 0x080c, 0xcc97, 0x0010, 0x9085, 0x0001,
+	0x0005, 0x080c, 0x6a7c, 0x0128, 0x080c, 0xcd1a, 0x0010, 0x9085,
+	0x0001, 0x0005, 0xb8a4, 0x900d, 0x1118, 0x9085, 0x0001, 0x0005,
+	0x0136, 0x01c6, 0xa800, 0x9005, 0x11b8, 0x890e, 0x810e, 0x810f,
+	0x9184, 0x003f, 0x20e0, 0x9184, 0xffc0, 0x9080, 0x0004, 0x2098,
+	0x20a9, 0x0001, 0x2009, 0x0010, 0x4002, 0x9606, 0x0128, 0x8109,
+	0x1dd8, 0x9085, 0x0001, 0x0008, 0x9006, 0x01ce, 0x013e, 0x0005,
+	0x0146, 0x01d6, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0004, 0x20a0,
+	0x20a9, 0x0010, 0x2009, 0xffff, 0x4104, 0x01de, 0x014e, 0x0136,
+	0x01c6, 0xa800, 0x9005, 0x11b8, 0x890e, 0x810e, 0x810f, 0x9184,
+	0x003f, 0x20e0, 0x9184, 0xffc0, 0x9080, 0x0004, 0x2098, 0x20a9,
+	0x0001, 0x2009, 0x0010, 0x4002, 0x9606, 0x0128, 0x8109, 0x1dd8,
+	0x9085, 0x0001, 0x0068, 0x0146, 0x01d6, 0x3300, 0x8001, 0x20a0,
+	0x3c00, 0x20e8, 0x2001, 0xffff, 0x4004, 0x01de, 0x014e, 0x9006,
+	0x01ce, 0x013e, 0x0005, 0x0096, 0x0126, 0x2091, 0x8000, 0xb8a4,
+	0x904d, 0x1128, 0x080c, 0x1059, 0x0168, 0x2900, 0xb8a6, 0x080c,
+	0x6a18, 0xa803, 0x0001, 0xa807, 0x0000, 0x9085, 0x0001, 0x012e,
+	0x009e, 0x0005, 0x9006, 0x0cd8, 0x0096, 0x0126, 0x2091, 0x8000,
+	0xb8a4, 0x904d, 0x0130, 0xb8a7, 0x0000, 0x080c, 0x108b, 0x9085,
+	0x0001, 0x012e, 0x009e, 0x0005, 0xb89c, 0xd0a4, 0x0005, 0x00b6,
+	0x00f6, 0x080c, 0x76a5, 0x01b0, 0x71c4, 0x81ff, 0x1198, 0x71dc,
+	0xd19c, 0x0180, 0x2001, 0x007e, 0x9080, 0x1000, 0x2004, 0x905d,
+	0x0148, 0xb804, 0x9084, 0x00ff, 0x9086, 0x0006, 0x1118, 0xb800,
+	0xc0ed, 0xb802, 0x2079, 0x1847, 0x7804, 0xd0a4, 0x01d0, 0x0156,
+	0x20a9, 0x007f, 0x900e, 0x0016, 0x080c, 0x6789, 0x1168, 0xb804,
+	0x9084, 0xff00, 0x8007, 0x9096, 0x0004, 0x0118, 0x9086, 0x0006,
+	0x1118, 0xb800, 0xc0ed, 0xb802, 0x001e, 0x8108, 0x1f04, 0x6aa3,
+	0x015e, 0x080c, 0x6b93, 0x0120, 0x2001, 0x1986, 0x200c, 0x0038,
+	0x2079, 0x1847, 0x7804, 0xd0a4, 0x0130, 0x2009, 0x07d0, 0x2011,
+	0x6ace, 0x080c, 0x88fe, 0x00fe, 0x00be, 0x0005, 0x00b6, 0x2011,
+	0x6ace, 0x080c, 0x8834, 0x080c, 0x6b93, 0x01d8, 0x2001, 0x107e,
+	0x2004, 0x2058, 0xb900, 0xc1ec, 0xb902, 0x080c, 0x6bd1, 0x0130,
+	0x2009, 0x07d0, 0x2011, 0x6ace, 0x080c, 0x88fe, 0x00e6, 0x2071,
+	0x1800, 0x9006, 0x707e, 0x7060, 0x7082, 0x080c, 0x30e1, 0x00ee,
+	0x04e0, 0x0156, 0x00c6, 0x20a9, 0x007f, 0x900e, 0x0016, 0x080c,
+	0x6789, 0x1568, 0xb800, 0xd0ec, 0x0550, 0xd0bc, 0x1540, 0x0046,
+	0xbaa0, 0x2220, 0x9006, 0x2009, 0x0029, 0x080c, 0xe72a, 0xb800,
+	0xc0e5, 0xc0ec, 0xb802, 0x080c, 0x6bcd, 0x2001, 0x0707, 0x1128,
+	0xb804, 0x9084, 0x00ff, 0x9085, 0x0700, 0xb806, 0x080c, 0xaae0,
+	0x2019, 0x0029, 0x080c, 0x95c1, 0x0076, 0x903e, 0x080c, 0x947e,
+	0x900e, 0x080c, 0xe440, 0x007e, 0x004e, 0x080c, 0xaafc, 0x001e,
+	0x8108, 0x1f04, 0x6af6, 0x00ce, 0x015e, 0x00be, 0x0005, 0x00b6,
 	0x6010, 0x2058, 0xb800, 0xc0ec, 0xb802, 0x00be, 0x0005, 0x00b6,
-	0x00c6, 0x0096, 0x080c, 0x1060, 0x090c, 0x0d7d, 0x2958, 0x009e,
-	0x2001, 0x196a, 0x2b02, 0x8b07, 0x8006, 0x8006, 0x908c, 0x003f,
+	0x00c6, 0x0096, 0x080c, 0x1072, 0x090c, 0x0d85, 0x2958, 0x009e,
+	0x2001, 0x196c, 0x2b02, 0x8b07, 0x8006, 0x8006, 0x908c, 0x003f,
 	0xb9c6, 0x908c, 0xffc0, 0xb9ca, 0xb8af, 0x0000, 0x2009, 0x00ff,
-	0x080c, 0x60ac, 0xb807, 0x0006, 0xb813, 0x00ff, 0xb817, 0xffff,
+	0x080c, 0x6198, 0xb807, 0x0006, 0xb813, 0x00ff, 0xb817, 0xffff,
 	0xb86f, 0x0200, 0xb86c, 0xb893, 0x0002, 0xb8bb, 0x0520, 0xb8a3,
 	0x00ff, 0xb8af, 0x0000, 0x00ce, 0x00be, 0x0005, 0x7810, 0x00b6,
 	0x2058, 0xb800, 0x00be, 0xd0ac, 0x0005, 0x6010, 0x00b6, 0x905d,
@@ -3208,4046 +3239,4110 @@ unsigned short risc_code01[] = { 
 	0x001e, 0x000e, 0x0005, 0x00b6, 0x00f6, 0x2001, 0x107e, 0x2004,
 	0x905d, 0x0110, 0xb800, 0xd0ec, 0x00fe, 0x00be, 0x0005, 0x0126,
 	0x0026, 0x2091, 0x8000, 0x0006, 0xbaa0, 0x9290, 0x1000, 0x2204,
-	0x9b06, 0x190c, 0x0d7d, 0x000e, 0xba00, 0x9005, 0x0110, 0xc2fd,
+	0x9b06, 0x190c, 0x0d85, 0x000e, 0xba00, 0x9005, 0x0110, 0xc2fd,
 	0x0008, 0xc2fc, 0xba02, 0x002e, 0x012e, 0x0005, 0x2011, 0x1837,
-	0x2204, 0xd0cc, 0x0138, 0x2001, 0x1982, 0x200c, 0x2011, 0x6acb,
-	0x080c, 0x8792, 0x0005, 0x2011, 0x6acb, 0x080c, 0x86c8, 0x2011,
-	0x1837, 0x2204, 0xc0cc, 0x2012, 0x0005, 0x080c, 0x573e, 0xd0ac,
-	0x0005, 0x080c, 0x573e, 0xd0a4, 0x0005, 0x0016, 0xb904, 0x9184,
+	0x2204, 0xd0cc, 0x0138, 0x2001, 0x1984, 0x200c, 0x2011, 0x6bc3,
+	0x080c, 0x88fe, 0x0005, 0x2011, 0x6bc3, 0x080c, 0x8834, 0x2011,
+	0x1837, 0x2204, 0xc0cc, 0x2012, 0x0005, 0x080c, 0x5826, 0xd0ac,
+	0x0005, 0x080c, 0x5826, 0xd0a4, 0x0005, 0x0016, 0xb904, 0x9184,
 	0x00ff, 0x908e, 0x0006, 0x001e, 0x0005, 0x0016, 0xb904, 0x9184,
 	0xff00, 0x8007, 0x908e, 0x0006, 0x001e, 0x0005, 0x00b6, 0x00f6,
-	0x080c, 0xd09b, 0x0158, 0x70dc, 0x9084, 0x0028, 0x0138, 0x2001,
+	0x080c, 0xd33e, 0x0158, 0x70dc, 0x9084, 0x0028, 0x0138, 0x2001,
 	0x107f, 0x2004, 0x905d, 0x0110, 0xb8d4, 0xd094, 0x00fe, 0x00be,
 	0x0005, 0x2071, 0x1910, 0x7003, 0x0001, 0x7007, 0x0000, 0x9006,
-	0x7012, 0x7016, 0x701a, 0x701e, 0x700a, 0x7046, 0x0005, 0x0016,
-	0x00e6, 0x2071, 0x1947, 0x900e, 0x710a, 0x080c, 0x573e, 0xd0fc,
-	0x1140, 0x080c, 0x573e, 0x900e, 0xd09c, 0x0108, 0x8108, 0x7102,
-	0x00f8, 0x2001, 0x1867, 0x200c, 0x9184, 0x0007, 0x0002, 0x6b19,
-	0x6b19, 0x6b19, 0x6b19, 0x6b19, 0x6b2f, 0x6b3d, 0x6b19, 0x7003,
-	0x0003, 0x2009, 0x1868, 0x210c, 0x9184, 0xff00, 0x8007, 0x9005,
-	0x1110, 0x2001, 0x0002, 0x7006, 0x0018, 0x7003, 0x0005, 0x0c88,
-	0x00ee, 0x001e, 0x0005, 0x00e6, 0x2071, 0x0050, 0x684c, 0x9005,
-	0x1150, 0x00e6, 0x2071, 0x1910, 0x7028, 0xc085, 0x702a, 0x00ee,
-	0x9085, 0x0001, 0x0488, 0x6844, 0x9005, 0x0158, 0x080c, 0x78b2,
-	0x6a60, 0x9200, 0x7002, 0x6864, 0x9101, 0x7006, 0x9006, 0x7012,
-	0x7016, 0x6860, 0x7002, 0x6864, 0x7006, 0x6868, 0x700a, 0x686c,
-	0x700e, 0x6844, 0x9005, 0x1110, 0x7012, 0x7016, 0x684c, 0x701a,
-	0x701c, 0x9085, 0x0040, 0x701e, 0x7037, 0x0019, 0x702b, 0x0001,
-	0x00e6, 0x2071, 0x1910, 0x7028, 0xc084, 0x702a, 0x7007, 0x0001,
-	0x700b, 0x0000, 0x00ee, 0x9006, 0x00ee, 0x0005, 0x00e6, 0x0026,
-	0x2071, 0x1947, 0x7000, 0x9015, 0x0904, 0x6df3, 0x9286, 0x0003,
-	0x0904, 0x6c83, 0x9286, 0x0005, 0x0904, 0x6c83, 0x2071, 0x1877,
-	0xa87c, 0x9005, 0x0904, 0x6be4, 0x7140, 0xa868, 0x9102, 0x0a04,
-	0x6df3, 0xa878, 0xd084, 0x15d8, 0xa853, 0x0019, 0x2001, 0x8023,
-	0xa84e, 0x2071, 0x1910, 0x701c, 0x9005, 0x1904, 0x6f8a, 0x0e04,
-	0x6ff8, 0x2071, 0x0000, 0xa850, 0x7032, 0xa84c, 0x7082, 0xa870,
-	0x7086, 0xa86c, 0x708a, 0xa880, 0x708e, 0x7036, 0x0146, 0x01d6,
-	0x0136, 0x01c6, 0x0156, 0x20e9, 0x0000, 0x20a1, 0x002a, 0xa868,
-	0x20a8, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0021, 0x2098, 0x4003,
-	0x015e, 0x01ce, 0x013e, 0x01de, 0x014e, 0x2091, 0x4080, 0x2001,
-	0x0089, 0x2004, 0xd084, 0x190c, 0x11ee, 0x0804, 0x6c66, 0xa853,
-	0x001b, 0x2001, 0x8027, 0x0820, 0x7004, 0xd08c, 0x1904, 0x6df3,
-	0xa853, 0x001a, 0x2001, 0x8024, 0x0804, 0x6ba8, 0x00e6, 0x0026,
-	0x2071, 0x1947, 0x7000, 0x9015, 0x0904, 0x6df3, 0x9286, 0x0003,
-	0x0904, 0x6c83, 0x9286, 0x0005, 0x0904, 0x6c83, 0xa84f, 0x8022,
-	0xa853, 0x0018, 0x0804, 0x6c4b, 0xa868, 0xd0fc, 0x11d8, 0x00e6,
-	0x0026, 0x2001, 0x1947, 0x2004, 0x9005, 0x0904, 0x6df3, 0xa87c,
-	0xd0bc, 0x1904, 0x6df3, 0xa978, 0xa874, 0x9105, 0x1904, 0x6df3,
-	0x2001, 0x1947, 0x2004, 0x0002, 0x6df3, 0x6c47, 0x6c83, 0x6c83,
-	0x6df3, 0x6c83, 0x0005, 0xa868, 0xd0fc, 0x1500, 0x00e6, 0x0026,
-	0x2009, 0x1947, 0x210c, 0x81ff, 0x0904, 0x6df3, 0xa87c, 0xd0cc,
-	0x0904, 0x6df3, 0xa880, 0x9084, 0x00ff, 0x9086, 0x0001, 0x1904,
-	0x6df3, 0x9186, 0x0003, 0x0904, 0x6c83, 0x9186, 0x0005, 0x0904,
-	0x6c83, 0xa84f, 0x8021, 0xa853, 0x0017, 0x0028, 0x0005, 0xa84f,
+	0x7012, 0x7016, 0x701a, 0x701e, 0x700a, 0x7046, 0x2001, 0x1922,
+	0x2003, 0x0000, 0x0005, 0x0016, 0x00e6, 0x2071, 0x1949, 0x900e,
+	0x710a, 0x080c, 0x5826, 0xd0fc, 0x1140, 0x080c, 0x5826, 0x900e,
+	0xd09c, 0x0108, 0x8108, 0x7102, 0x0430, 0x2001, 0x1867, 0x200c,
+	0x9184, 0x0007, 0x0002, 0x6c15, 0x6c15, 0x6c15, 0x6c15, 0x6c15,
+	0x6c2b, 0x6c40, 0x6c4e, 0x7003, 0x0003, 0x2009, 0x1868, 0x210c,
+	0x9184, 0xff00, 0x908e, 0xff00, 0x0140, 0x8007, 0x9005, 0x1110,
+	0x2001, 0x0002, 0x8003, 0x7006, 0x0030, 0x7007, 0x0001, 0x0018,
+	0x7003, 0x0005, 0x0c50, 0x2071, 0x1910, 0x704f, 0x0000, 0x2071,
+	0x1800, 0x70f7, 0x0001, 0x00ee, 0x001e, 0x0005, 0x7003, 0x0000,
+	0x2071, 0x1910, 0x2009, 0x1868, 0x210c, 0x9184, 0x7f00, 0x8007,
+	0x908c, 0x000f, 0x0160, 0x714e, 0x8004, 0x8004, 0x8004, 0x8004,
+	0x2071, 0x1800, 0x908c, 0x0007, 0x0128, 0x70f6, 0x0c20, 0x704f,
+	0x000f, 0x0c90, 0x70f7, 0x0005, 0x08f0, 0x00e6, 0x2071, 0x0050,
+	0x684c, 0x9005, 0x1150, 0x00e6, 0x2071, 0x1910, 0x7028, 0xc085,
+	0x702a, 0x00ee, 0x9085, 0x0001, 0x0488, 0x6844, 0x9005, 0x0158,
+	0x080c, 0x7a19, 0x6a60, 0x9200, 0x7002, 0x6864, 0x9101, 0x7006,
+	0x9006, 0x7012, 0x7016, 0x6860, 0x7002, 0x6864, 0x7006, 0x6868,
+	0x700a, 0x686c, 0x700e, 0x6844, 0x9005, 0x1110, 0x7012, 0x7016,
+	0x684c, 0x701a, 0x701c, 0x9085, 0x0040, 0x701e, 0x7037, 0x0019,
+	0x702b, 0x0001, 0x00e6, 0x2071, 0x1910, 0x7028, 0xc084, 0x702a,
+	0x7007, 0x0001, 0x700b, 0x0000, 0x00ee, 0x9006, 0x00ee, 0x0005,
+	0x00e6, 0x0026, 0x2071, 0x1949, 0x7000, 0x9015, 0x0904, 0x6f1e,
+	0x9286, 0x0003, 0x0904, 0x6db3, 0x9286, 0x0005, 0x0904, 0x6db3,
+	0x2071, 0x1877, 0xa87c, 0x9005, 0x0904, 0x6d0e, 0x7140, 0xa868,
+	0x9102, 0x0a04, 0x6f1e, 0xa878, 0xd084, 0x15d8, 0xa853, 0x0019,
+	0x2001, 0x8023, 0xa84e, 0x2071, 0x1910, 0x701c, 0x9005, 0x1904,
+	0x70cd, 0x0e04, 0x713b, 0x2071, 0x0000, 0xa850, 0x7032, 0xa84c,
+	0x7082, 0xa870, 0x7086, 0xa86c, 0x708a, 0xa880, 0x708e, 0x7036,
+	0x0146, 0x01d6, 0x0136, 0x01c6, 0x0156, 0x20e9, 0x0000, 0x20a1,
+	0x002a, 0xa868, 0x20a8, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0021,
+	0x2098, 0x4003, 0x015e, 0x01ce, 0x013e, 0x01de, 0x014e, 0x2091,
+	0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x1200, 0x0804,
+	0x6d96, 0xa853, 0x001b, 0x2001, 0x8027, 0x0820, 0x7004, 0xd08c,
+	0x1904, 0x6f1e, 0xa853, 0x001a, 0x2001, 0x8024, 0x0804, 0x6cd2,
+	0x00e6, 0x0026, 0x2071, 0x1949, 0x7000, 0x9015, 0x0904, 0x6f1e,
+	0x9286, 0x0003, 0x0904, 0x6db3, 0x9286, 0x0005, 0x0904, 0x6db3,
+	0xa84f, 0x8022, 0xa853, 0x0018, 0x0804, 0x6d7b, 0xa868, 0xd0fc,
+	0x1508, 0x00e6, 0x0026, 0x2001, 0x1949, 0x2004, 0x9015, 0x0904,
+	0x6f1e, 0xa978, 0xa874, 0x9105, 0x1904, 0x6f1e, 0x9286, 0x0003,
+	0x0904, 0x6db3, 0x9286, 0x0005, 0x0904, 0x6db3, 0xa87c, 0xd0bc,
+	0x1904, 0x6f1e, 0x2200, 0x0002, 0x6f1e, 0x6d77, 0x6db3, 0x6db3,
+	0x6f1e, 0x6db3, 0x0005, 0xa868, 0xd0fc, 0x1500, 0x00e6, 0x0026,
+	0x2009, 0x1949, 0x210c, 0x81ff, 0x0904, 0x6f1e, 0xa880, 0x9084,
+	0x00ff, 0x9086, 0x0001, 0x1904, 0x6f1e, 0x9186, 0x0003, 0x0904,
+	0x6db3, 0x9186, 0x0005, 0x0904, 0x6db3, 0xa87c, 0xd0cc, 0x0904,
+	0x6f1e, 0xa84f, 0x8021, 0xa853, 0x0017, 0x0028, 0x0005, 0xa84f,
 	0x8020, 0xa853, 0x0016, 0x2071, 0x1910, 0x701c, 0x9005, 0x1904,
-	0x6f8a, 0x0e04, 0x6ff8, 0x2071, 0x0000, 0xa84c, 0x7082, 0xa850,
+	0x70cd, 0x0e04, 0x713b, 0x2071, 0x0000, 0xa84c, 0x7082, 0xa850,
 	0x7032, 0xa86c, 0x7086, 0x7036, 0xa870, 0x708a, 0x2091, 0x4080,
-	0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11ee, 0x2071, 0x1800,
+	0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x1200, 0x2071, 0x1800,
 	0x2011, 0x0001, 0xa804, 0x900d, 0x702c, 0x1158, 0xa802, 0x2900,
-	0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x85ce, 0x002e, 0x00ee,
+	0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x873a, 0x002e, 0x00ee,
 	0x0005, 0x0096, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff,
 	0x1dc8, 0x009e, 0x0c58, 0xa84f, 0x0000, 0x00f6, 0x2079, 0x0050,
-	0x2071, 0x1910, 0xa803, 0x0000, 0x7010, 0x9005, 0x1904, 0x6d78,
-	0x782c, 0x908c, 0x0780, 0x190c, 0x7146, 0x8004, 0x8004, 0x8004,
-	0x9084, 0x0003, 0x0002, 0x6ca1, 0x6d78, 0x6cc6, 0x6d13, 0x080c,
-	0x0d7d, 0x2071, 0x1800, 0x2900, 0x7822, 0xa804, 0x900d, 0x1170,
-	0x2071, 0x1a02, 0x703c, 0x9005, 0x1328, 0x2001, 0x1948, 0x2004,
-	0x8005, 0x703e, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x9016, 0x702c,
-	0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e,
-	0x70c0, 0x9200, 0x70c2, 0x080c, 0x85ce, 0x0c10, 0x2071, 0x1800,
-	0x2900, 0x7822, 0xa804, 0x900d, 0x15a8, 0x7824, 0x00e6, 0x2071,
-	0x0040, 0x712c, 0xd19c, 0x1170, 0x2009, 0x1830, 0x210c, 0x918a,
-	0x0020, 0x0240, 0x7022, 0x2001, 0x1dc0, 0x200c, 0x8108, 0x2102,
-	0x00ee, 0x0058, 0x00ee, 0x2048, 0x702c, 0xa802, 0x2900, 0x702e,
-	0x70c0, 0x8000, 0x70c2, 0x080c, 0x85ce, 0x782c, 0x9094, 0x0780,
-	0x190c, 0x7146, 0xd0a4, 0x19c8, 0x2071, 0x1a02, 0x703c, 0x9005,
-	0x1328, 0x2001, 0x1948, 0x2004, 0x8005, 0x703e, 0x00fe, 0x002e,
-	0x00ee, 0x0005, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210,
-	0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c,
-	0x85ce, 0x0804, 0x6ccd, 0x0096, 0x00e6, 0x7824, 0x2048, 0x2071,
-	0x1800, 0x702c, 0xa802, 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2,
-	0x080c, 0x85ce, 0x782c, 0x9094, 0x0780, 0x190c, 0x7146, 0xd0a4,
-	0x1d60, 0x00ee, 0x782c, 0x9094, 0x0780, 0x190c, 0x7146, 0xd09c,
-	0x11a0, 0x009e, 0x2900, 0x7822, 0xa804, 0x900d, 0x1560, 0x2071,
-	0x1a02, 0x703c, 0x9005, 0x1328, 0x2001, 0x1948, 0x2004, 0x8005,
-	0x703e, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x009e, 0x2908, 0x7010,
-	0x8000, 0x7012, 0x7018, 0x904d, 0x711a, 0x0110, 0xa902, 0x0008,
-	0x711e, 0x2148, 0xa804, 0x900d, 0x1170, 0x2071, 0x1a02, 0x703c,
-	0x9005, 0x1328, 0x2001, 0x1948, 0x2004, 0x8005, 0x703e, 0x00fe,
-	0x002e, 0x00ee, 0x0005, 0x2071, 0x1800, 0x9016, 0x702c, 0x2148,
-	0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70c0,
-	0x9200, 0x70c2, 0x080c, 0x85ce, 0x00fe, 0x002e, 0x00ee, 0x0005,
-	0x2908, 0x7010, 0x8000, 0x7012, 0x7018, 0x904d, 0x711a, 0x0110,
-	0xa902, 0x0008, 0x711e, 0x2148, 0xa804, 0x900d, 0x1904, 0x6dcd,
-	0x782c, 0x9094, 0x0780, 0x190c, 0x7146, 0xd09c, 0x1198, 0x701c,
-	0x904d, 0x0180, 0x7010, 0x8001, 0x7012, 0x1108, 0x701a, 0xa800,
-	0x701e, 0x2900, 0x7822, 0x782c, 0x9094, 0x0780, 0x190c, 0x7146,
-	0xd09c, 0x0d68, 0x782c, 0x9094, 0x0780, 0x190c, 0x7146, 0xd0a4,
-	0x01b0, 0x00e6, 0x7824, 0x2048, 0x2071, 0x1800, 0x702c, 0xa802,
-	0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c, 0x85ce, 0x782c,
-	0x9094, 0x0780, 0x190c, 0x7146, 0xd0a4, 0x1d60, 0x00ee, 0x2071,
-	0x1a02, 0x703c, 0x9005, 0x1328, 0x2001, 0x1948, 0x2004, 0x8005,
-	0x703e, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x00e6, 0x2071, 0x1800,
-	0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff,
-	0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x85ce, 0x00ee,
-	0x0804, 0x6d88, 0xa868, 0xd0fc, 0x1560, 0x0096, 0xa804, 0xa807,
-	0x0000, 0x904d, 0x190c, 0x0ff9, 0x009e, 0x0018, 0xa868, 0xd0fc,
-	0x1500, 0x00e6, 0x0026, 0xa84f, 0x0000, 0x00f6, 0x2079, 0x0050,
-	0x2071, 0x1910, 0xa803, 0x0000, 0x7010, 0x9005, 0x1904, 0x6f08,
-	0x782c, 0x908c, 0x0780, 0x190c, 0x7146, 0x8004, 0x8004, 0x8004,
-	0x9084, 0x0003, 0x0002, 0x6e12, 0x6f08, 0x6e2d, 0x6e9b, 0x080c,
-	0x0d7d, 0x0005, 0x2071, 0x1800, 0x2900, 0x7822, 0xa804, 0x900d,
-	0x1120, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x9016, 0x702c, 0x2148,
+	0x2071, 0x1910, 0xa803, 0x0000, 0x7010, 0x9005, 0x1904, 0x6ea4,
+	0x782c, 0x908c, 0x0780, 0x190c, 0x7289, 0x8004, 0x8004, 0x8004,
+	0x9084, 0x0003, 0x0002, 0x6dd1, 0x6ea4, 0x6df5, 0x6e41, 0x080c,
+	0x0d85, 0x2071, 0x1800, 0x2900, 0x7822, 0xa804, 0x900d, 0x1168,
+	0x2071, 0x1a05, 0x7044, 0x9005, 0x1320, 0x2001, 0x194a, 0x2004,
+	0x7046, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x9016, 0x702c, 0x2148,
 	0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70c0,
-	0x9200, 0x70c2, 0x080c, 0x85ce, 0x0c60, 0x2071, 0x1800, 0x2900,
-	0x7822, 0xa804, 0x900d, 0x1904, 0x6e8a, 0x7830, 0xd0dc, 0x1120,
-	0x00fe, 0x002e, 0x00ee, 0x0005, 0x7824, 0x00e6, 0x2071, 0x0040,
+	0x9200, 0x70c2, 0x080c, 0x873a, 0x0c18, 0x2071, 0x1800, 0x2900,
+	0x7822, 0xa804, 0x900d, 0x15a0, 0x7824, 0x00e6, 0x2071, 0x0040,
 	0x712c, 0xd19c, 0x1170, 0x2009, 0x1830, 0x210c, 0x918a, 0x0020,
 	0x0240, 0x7022, 0x2001, 0x1dc0, 0x200c, 0x8108, 0x2102, 0x00ee,
 	0x0058, 0x00ee, 0x2048, 0x702c, 0xa802, 0x2900, 0x702e, 0x70c0,
-	0x8000, 0x70c2, 0x080c, 0x85ce, 0x782c, 0x9094, 0x0780, 0x190c,
-	0x7146, 0xd0a4, 0x19c8, 0x0e04, 0x6e81, 0x7838, 0x7938, 0x910e,
-	0x1de0, 0x00d6, 0x2069, 0x0000, 0x6836, 0x6833, 0x0013, 0x00de,
-	0x2001, 0x1921, 0x200c, 0xc184, 0x2102, 0x2091, 0x4080, 0x2001,
-	0x0089, 0x2004, 0xd084, 0x190c, 0x11ee, 0x00fe, 0x002e, 0x00ee,
-	0x0005, 0x2001, 0x1921, 0x200c, 0xc185, 0x2102, 0x00fe, 0x002e,
-	0x00ee, 0x0005, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210,
-	0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c,
-	0x85ce, 0x0804, 0x6e3c, 0x0096, 0x00e6, 0x7824, 0x2048, 0x2071,
-	0x1800, 0x702c, 0xa802, 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2,
-	0x080c, 0x85ce, 0x782c, 0x9094, 0x0780, 0x190c, 0x7146, 0xd0a4,
-	0x1d60, 0x00ee, 0x0e04, 0x6edb, 0x7838, 0x7938, 0x910e, 0x1de0,
-	0x00d6, 0x2069, 0x0000, 0x6836, 0x6833, 0x0013, 0x00de, 0x7044,
-	0xc084, 0x7046, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084,
-	0x190c, 0x11ee, 0x782c, 0x9094, 0x0780, 0x190c, 0x7146, 0xd09c,
-	0x1170, 0x009e, 0x2900, 0x7822, 0xa804, 0x900d, 0x11e0, 0x00fe,
-	0x002e, 0x00ee, 0x0005, 0x7044, 0xc085, 0x7046, 0x0c58, 0x009e,
-	0x2908, 0x7010, 0x8000, 0x7012, 0x7018, 0x904d, 0x711a, 0x0110,
-	0xa902, 0x0008, 0x711e, 0x2148, 0xa804, 0x900d, 0x1120, 0x00fe,
-	0x002e, 0x00ee, 0x0005, 0x2071, 0x1800, 0x9016, 0x702c, 0x2148,
-	0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70c0,
-	0x9200, 0x70c2, 0x080c, 0x85ce, 0x00fe, 0x002e, 0x00ee, 0x0005,
-	0x2908, 0x7010, 0x8000, 0x7012, 0x7018, 0x904d, 0x711a, 0x0110,
-	0xa902, 0x0008, 0x711e, 0x2148, 0xa804, 0x900d, 0x1904, 0x6f75,
-	0x782c, 0x9094, 0x0780, 0x190c, 0x7146, 0xd09c, 0x11b0, 0x701c,
-	0x904d, 0x0198, 0xa84c, 0x9005, 0x1180, 0x7010, 0x8001, 0x7012,
-	0x1108, 0x701a, 0xa800, 0x701e, 0x2900, 0x7822, 0x782c, 0x9094,
-	0x0780, 0x190c, 0x7146, 0xd09c, 0x0d50, 0x782c, 0x9094, 0x0780,
-	0x190c, 0x7146, 0xd0a4, 0x05a8, 0x00e6, 0x7824, 0x2048, 0x2071,
-	0x1800, 0x702c, 0xa802, 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2,
-	0x080c, 0x85ce, 0x782c, 0x9094, 0x0780, 0x190c, 0x7146, 0xd0a4,
-	0x1d60, 0x00ee, 0x0e04, 0x6f6e, 0x7838, 0x7938, 0x910e, 0x1de0,
-	0x00d6, 0x2069, 0x0000, 0x6836, 0x6833, 0x0013, 0x00de, 0x7044,
-	0xc084, 0x7046, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084,
-	0x190c, 0x11ee, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x7044, 0xc085,
-	0x7046, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x00e6, 0x2071, 0x1800,
+	0x8000, 0x70c2, 0x080c, 0x873a, 0x782c, 0x9094, 0x0780, 0x190c,
+	0x7289, 0xd0a4, 0x19c8, 0x2071, 0x1a05, 0x7044, 0x9005, 0x1320,
+	0x2001, 0x194a, 0x2004, 0x7046, 0x00fe, 0x002e, 0x00ee, 0x0005,
 	0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff,
-	0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x85ce, 0x00ee,
-	0x0804, 0x6f18, 0x2071, 0x1910, 0xa803, 0x0000, 0x2908, 0x7010,
-	0x8000, 0x7012, 0x7018, 0x904d, 0x711a, 0x0110, 0xa902, 0x0008,
-	0x711e, 0x2148, 0xa804, 0x900d, 0x1128, 0x1e04, 0x6fb5, 0x002e,
-	0x00ee, 0x0005, 0x2071, 0x1800, 0x9016, 0x702c, 0x2148, 0xa904,
-	0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200,
-	0x70c2, 0x080c, 0x85ce, 0x0e04, 0x6f9f, 0x2071, 0x1910, 0x701c,
-	0x2048, 0xa84c, 0x900d, 0x0d18, 0x2071, 0x0000, 0x7182, 0xa850,
-	0x7032, 0xa86c, 0x7086, 0x7036, 0xa870, 0x708a, 0xa850, 0x9082,
-	0x0019, 0x1278, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084,
-	0x190c, 0x11ee, 0x2071, 0x1910, 0x080c, 0x7132, 0x002e, 0x00ee,
-	0x0005, 0xa850, 0x9082, 0x001c, 0x1e68, 0xa880, 0x708e, 0x7036,
-	0x0146, 0x01d6, 0x0136, 0x01c6, 0x0156, 0x20e9, 0x0000, 0x20a1,
-	0x002a, 0xa868, 0x20a8, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0021,
-	0x2098, 0x4003, 0x015e, 0x01ce, 0x013e, 0x01de, 0x014e, 0x0890,
-	0x2071, 0x1910, 0xa803, 0x0000, 0x2908, 0x7010, 0x8000, 0x7012,
+	0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x873a, 0x0804,
+	0x6dfc, 0x0096, 0x00e6, 0x7824, 0x2048, 0x2071, 0x1800, 0x702c,
+	0xa802, 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c, 0x873a,
+	0x782c, 0x9094, 0x0780, 0x190c, 0x7289, 0xd0a4, 0x1d60, 0x00ee,
+	0x782c, 0x9094, 0x0780, 0x190c, 0x7289, 0xd09c, 0x1198, 0x009e,
+	0x2900, 0x7822, 0xa804, 0x900d, 0x1550, 0x2071, 0x1a05, 0x7044,
+	0x9005, 0x1320, 0x2001, 0x194a, 0x2004, 0x7046, 0x00fe, 0x002e,
+	0x00ee, 0x0005, 0x009e, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018,
+	0x904d, 0x711a, 0x0110, 0xa902, 0x0008, 0x711e, 0x2148, 0xa804,
+	0x900d, 0x1168, 0x2071, 0x1a05, 0x7044, 0x9005, 0x1320, 0x2001,
+	0x194a, 0x2004, 0x7046, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x2071,
+	0x1800, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900,
+	0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x873a,
+	0x00fe, 0x002e, 0x00ee, 0x0005, 0x2908, 0x7010, 0x8000, 0x7012,
 	0x7018, 0x904d, 0x711a, 0x0110, 0xa902, 0x0008, 0x711e, 0x2148,
-	0xa804, 0x900d, 0x1118, 0x002e, 0x00ee, 0x0005, 0x2071, 0x1800,
+	0xa804, 0x900d, 0x1904, 0x6ef8, 0x782c, 0x9094, 0x0780, 0x190c,
+	0x7289, 0xd09c, 0x1198, 0x701c, 0x904d, 0x0180, 0x7010, 0x8001,
+	0x7012, 0x1108, 0x701a, 0xa800, 0x701e, 0x2900, 0x7822, 0x782c,
+	0x9094, 0x0780, 0x190c, 0x7289, 0xd09c, 0x0d68, 0x782c, 0x9094,
+	0x0780, 0x190c, 0x7289, 0xd0a4, 0x01b0, 0x00e6, 0x7824, 0x2048,
+	0x2071, 0x1800, 0x702c, 0xa802, 0x2900, 0x702e, 0x70c0, 0x8000,
+	0x70c2, 0x080c, 0x873a, 0x782c, 0x9094, 0x0780, 0x190c, 0x7289,
+	0xd0a4, 0x1d60, 0x00ee, 0x2071, 0x1a05, 0x7044, 0x9005, 0x1320,
+	0x2001, 0x194a, 0x2004, 0x7046, 0x00fe, 0x002e, 0x00ee, 0x0005,
+	0x00e6, 0x2071, 0x1800, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802,
+	0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2,
+	0x080c, 0x873a, 0x00ee, 0x0804, 0x6eb4, 0xa868, 0xd0fc, 0x15e0,
+	0x0096, 0xa804, 0xa807, 0x0000, 0x904d, 0x190c, 0x100b, 0x009e,
+	0x0018, 0xa868, 0xd0fc, 0x1580, 0x00e6, 0x0026, 0xa84f, 0x0000,
+	0x00f6, 0x2079, 0x0050, 0x2071, 0x1910, 0xa803, 0x0000, 0xa864,
+	0x9084, 0x00ff, 0x908e, 0x0016, 0x01a8, 0x7010, 0x9005, 0x1904,
+	0x7049, 0x782c, 0x908c, 0x0780, 0x190c, 0x7289, 0x8004, 0x8004,
+	0x8004, 0x9084, 0x0003, 0x0002, 0x6f4d, 0x7049, 0x6f68, 0x6fda,
+	0x080c, 0x0d85, 0x2009, 0x1949, 0x2104, 0x0002, 0x6f2d, 0x6f2d,
+	0x6f2d, 0x6dbc, 0x6f2d, 0x6dbc, 0x0005, 0x2071, 0x1800, 0x2900,
+	0x7822, 0xa804, 0x900d, 0x1120, 0x00fe, 0x002e, 0x00ee, 0x0005,
 	0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff,
-	0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x85ce, 0x002e,
-	0x00ee, 0x0005, 0x0006, 0xa87c, 0x0006, 0xa867, 0x0103, 0x20a9,
-	0x001c, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x001d, 0x20a0, 0x9006,
-	0x4004, 0x000e, 0x9084, 0x00ff, 0xa87e, 0x000e, 0xa87a, 0xa982,
-	0x0005, 0x2071, 0x1910, 0x7004, 0x0002, 0x7045, 0x7046, 0x7131,
-	0x7046, 0x7043, 0x7131, 0x080c, 0x0d7d, 0x0005, 0x2001, 0x1947,
-	0x2004, 0x0002, 0x7050, 0x7050, 0x70ca, 0x70cb, 0x7050, 0x70cb,
-	0x0126, 0x2091, 0x8000, 0x1e0c, 0x7151, 0x701c, 0x904d, 0x0508,
-	0xa84c, 0x9005, 0x0904, 0x709b, 0x0e04, 0x7079, 0xa94c, 0x2071,
+	0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x873a, 0x0c60,
+	0x2071, 0x1800, 0x2900, 0x7822, 0xa804, 0x900d, 0x1904, 0x6fc9,
+	0x7830, 0xd0dc, 0x1120, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x7824,
+	0x00e6, 0x2071, 0x0040, 0x712c, 0xd19c, 0x1170, 0x2009, 0x1830,
+	0x210c, 0x918a, 0x0020, 0x0240, 0x7022, 0x2001, 0x1dc0, 0x200c,
+	0x8108, 0x2102, 0x00ee, 0x0058, 0x00ee, 0x2048, 0x702c, 0xa802,
+	0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c, 0x873a, 0x782c,
+	0x9094, 0x0780, 0x190c, 0x7289, 0xd0a4, 0x19c8, 0x0e04, 0x6fc0,
+	0x7838, 0x7938, 0x910e, 0x1de0, 0x00d6, 0x2069, 0x0000, 0x6836,
+	0x6833, 0x0013, 0x00de, 0x2001, 0x1921, 0x200c, 0xc184, 0x2102,
+	0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x1200,
+	0x2001, 0x1922, 0x2003, 0x0000, 0x00fe, 0x002e, 0x00ee, 0x0005,
+	0x2001, 0x1921, 0x200c, 0xc185, 0x2102, 0x00fe, 0x002e, 0x00ee,
+	0x0005, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900,
+	0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x873a,
+	0x0804, 0x6f77, 0x0096, 0x00e6, 0x7824, 0x2048, 0x2071, 0x1800,
+	0x702c, 0xa802, 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c,
+	0x873a, 0x782c, 0x9094, 0x0780, 0x190c, 0x7289, 0xd0a4, 0x1d60,
+	0x00ee, 0x0e04, 0x701c, 0x7838, 0x7938, 0x910e, 0x1de0, 0x00d6,
+	0x2069, 0x0000, 0x6836, 0x6833, 0x0013, 0x00de, 0x7044, 0xc084,
+	0x7046, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c,
+	0x1200, 0x704b, 0x0000, 0x782c, 0x9094, 0x0780, 0x190c, 0x7289,
+	0xd09c, 0x1170, 0x009e, 0x2900, 0x7822, 0xa804, 0x900d, 0x11e0,
+	0x00fe, 0x002e, 0x00ee, 0x0005, 0x7044, 0xc085, 0x7046, 0x0c58,
+	0x009e, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018, 0x904d, 0x711a,
+	0x0110, 0xa902, 0x0008, 0x711e, 0x2148, 0xa804, 0x900d, 0x1120,
+	0x00fe, 0x002e, 0x00ee, 0x0005, 0x2071, 0x1800, 0x9016, 0x702c,
+	0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e,
+	0x70c0, 0x9200, 0x70c2, 0x080c, 0x873a, 0x00fe, 0x002e, 0x00ee,
+	0x0005, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018, 0x904d, 0x711a,
+	0x0110, 0xa902, 0x0008, 0x711e, 0x2148, 0xa804, 0x900d, 0x1904,
+	0x70b8, 0x782c, 0x9094, 0x0780, 0x190c, 0x7289, 0xd09c, 0x11b0,
+	0x701c, 0x904d, 0x0198, 0xa84c, 0x9005, 0x1180, 0x7010, 0x8001,
+	0x7012, 0x1108, 0x701a, 0xa800, 0x701e, 0x2900, 0x7822, 0x782c,
+	0x9094, 0x0780, 0x190c, 0x7289, 0xd09c, 0x0d50, 0x782c, 0x9094,
+	0x0780, 0x190c, 0x7289, 0xd0a4, 0x05b8, 0x00e6, 0x7824, 0x2048,
+	0x2071, 0x1800, 0x702c, 0xa802, 0x2900, 0x702e, 0x70c0, 0x8000,
+	0x70c2, 0x080c, 0x873a, 0x782c, 0x9094, 0x0780, 0x190c, 0x7289,
+	0xd0a4, 0x1d60, 0x00ee, 0x0e04, 0x70b1, 0x7838, 0x7938, 0x910e,
+	0x1de0, 0x00d6, 0x2069, 0x0000, 0x6836, 0x6833, 0x0013, 0x00de,
+	0x7044, 0xc084, 0x7046, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004,
+	0xd084, 0x190c, 0x1200, 0x704b, 0x0000, 0x00fe, 0x002e, 0x00ee,
+	0x0005, 0x7044, 0xc085, 0x7046, 0x00fe, 0x002e, 0x00ee, 0x0005,
+	0x00e6, 0x2071, 0x1800, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802,
+	0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2,
+	0x080c, 0x873a, 0x00ee, 0x0804, 0x7059, 0x2071, 0x1910, 0xa803,
+	0x0000, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018, 0x904d, 0x711a,
+	0x0110, 0xa902, 0x0008, 0x711e, 0x2148, 0xa804, 0x900d, 0x1128,
+	0x1e04, 0x70f8, 0x002e, 0x00ee, 0x0005, 0x2071, 0x1800, 0x9016,
+	0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8,
+	0x702e, 0x70c0, 0x9200, 0x70c2, 0x080c, 0x873a, 0x0e04, 0x70e2,
+	0x2071, 0x1910, 0x701c, 0x2048, 0xa84c, 0x900d, 0x0d18, 0x2071,
 	0x0000, 0x7182, 0xa850, 0x7032, 0xa86c, 0x7086, 0x7036, 0xa870,
 	0x708a, 0xa850, 0x9082, 0x0019, 0x1278, 0x2091, 0x4080, 0x2001,
-	0x0089, 0x2004, 0xd084, 0x190c, 0x11ee, 0x2071, 0x1910, 0x080c,
-	0x7132, 0x012e, 0x0804, 0x70c9, 0xa850, 0x9082, 0x001c, 0x1e68,
+	0x0089, 0x2004, 0xd084, 0x190c, 0x1200, 0x2071, 0x1910, 0x080c,
+	0x7275, 0x002e, 0x00ee, 0x0005, 0xa850, 0x9082, 0x001c, 0x1e68,
 	0xa880, 0x708e, 0x7036, 0x0146, 0x01d6, 0x0136, 0x01c6, 0x0156,
 	0x20e9, 0x0000, 0x20a1, 0x002a, 0xa868, 0x20a8, 0xa860, 0x20e0,
 	0xa85c, 0x9080, 0x0021, 0x2098, 0x4003, 0x015e, 0x01ce, 0x013e,
-	0x01de, 0x014e, 0x0890, 0x2001, 0x005b, 0x2004, 0x9094, 0x0780,
-	0x190c, 0x7146, 0xd09c, 0x2071, 0x1910, 0x1510, 0x2071, 0x1910,
-	0x700f, 0x0001, 0xa964, 0x9184, 0x00ff, 0x9086, 0x0003, 0x1130,
-	0x810f, 0x918c, 0x00ff, 0x8101, 0x0108, 0x710e, 0x2900, 0x00d6,
-	0x2069, 0x0050, 0x6822, 0x00de, 0x2071, 0x1910, 0x701c, 0x2048,
-	0x7010, 0x8001, 0x7012, 0xa800, 0x701e, 0x9005, 0x1108, 0x701a,
-	0x012e, 0x0005, 0x0005, 0x00d6, 0x2008, 0x2069, 0x1a02, 0x683c,
-	0x9005, 0x0760, 0x0158, 0x9186, 0x0003, 0x0540, 0x2001, 0x1815,
-	0x2004, 0x2009, 0x1b50, 0x210c, 0x9102, 0x1500, 0x0126, 0x2091,
-	0x8000, 0x2069, 0x0050, 0x693c, 0x6838, 0x9106, 0x0190, 0x0e04,
-	0x70fd, 0x2069, 0x0000, 0x6837, 0x8040, 0x6833, 0x0012, 0x6883,
-	0x8040, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c,
-	0x11ee, 0x2069, 0x1a02, 0x683f, 0xffff, 0x012e, 0x00de, 0x0126,
-	0x2091, 0x8000, 0x1e0c, 0x71b7, 0x701c, 0x904d, 0x0540, 0x2001,
-	0x005b, 0x2004, 0x9094, 0x0780, 0x15c9, 0xd09c, 0x1500, 0x2071,
-	0x1910, 0x700f, 0x0001, 0xa964, 0x9184, 0x00ff, 0x9086, 0x0003,
-	0x1130, 0x810f, 0x918c, 0x00ff, 0x8101, 0x0108, 0x710e, 0x2900,
-	0x00d6, 0x2069, 0x0050, 0x6822, 0x00de, 0x701c, 0x2048, 0x7010,
-	0x8001, 0x7012, 0xa800, 0x701e, 0x9005, 0x1108, 0x701a, 0x012e,
-	0x0005, 0x0005, 0x0126, 0x2091, 0x8000, 0x701c, 0x904d, 0x0160,
-	0x7010, 0x8001, 0x7012, 0xa800, 0x701e, 0x9005, 0x1108, 0x701a,
-	0x012e, 0x080c, 0x1079, 0x0005, 0x012e, 0x0005, 0x2091, 0x8000,
-	0x0e04, 0x7148, 0x0006, 0x0016, 0x2001, 0x8004, 0x0006, 0x0804,
-	0x0d86, 0x0096, 0x00f6, 0x2079, 0x0050, 0x7044, 0xd084, 0x01c0,
-	0xc084, 0x7046, 0x7838, 0x7938, 0x910e, 0x1de0, 0x00d6, 0x2069,
-	0x0000, 0x6836, 0x6833, 0x0013, 0x00de, 0x2091, 0x4080, 0x2001,
-	0x0089, 0x2004, 0xd084, 0x190c, 0x11ee, 0x00fe, 0x009e, 0x0005,
-	0x782c, 0x9094, 0x0780, 0x1991, 0xd0a4, 0x0db8, 0x00e6, 0x2071,
-	0x1800, 0x7824, 0x00e6, 0x2071, 0x0040, 0x712c, 0xd19c, 0x1170,
-	0x2009, 0x1830, 0x210c, 0x918a, 0x0020, 0x0240, 0x7022, 0x2001,
-	0x1dc0, 0x200c, 0x8108, 0x2102, 0x00ee, 0x0058, 0x00ee, 0x2048,
-	0x702c, 0xa802, 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c,
-	0x85ce, 0x782c, 0x9094, 0x0780, 0x190c, 0x7146, 0xd0a4, 0x19c8,
-	0x7838, 0x7938, 0x910e, 0x1de0, 0x00d6, 0x2069, 0x0000, 0x6836,
-	0x6833, 0x0013, 0x00de, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004,
-	0xd084, 0x190c, 0x11ee, 0x00ee, 0x00fe, 0x009e, 0x0005, 0x00f6,
-	0x2079, 0x0050, 0x7044, 0xd084, 0x01b8, 0xc084, 0x7046, 0x7838,
-	0x7938, 0x910e, 0x1de0, 0x00d6, 0x2069, 0x0000, 0x6836, 0x6833,
-	0x0013, 0x00de, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084,
-	0x190c, 0x11ee, 0x00fe, 0x0005, 0x782c, 0x9094, 0x0780, 0x190c,
-	0x7146, 0xd0a4, 0x0db8, 0x00e6, 0x2071, 0x1800, 0x7824, 0x2048,
-	0x702c, 0xa802, 0x2900, 0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c,
-	0x85ce, 0x782c, 0x9094, 0x0780, 0x190c, 0x7146, 0xd0a4, 0x1d70,
-	0x00d6, 0x2069, 0x0050, 0x693c, 0x2069, 0x1947, 0x6808, 0x690a,
-	0x2069, 0x1a02, 0x9102, 0x1118, 0x683c, 0x9005, 0x1328, 0x2001,
-	0x1948, 0x200c, 0x810d, 0x693e, 0x00de, 0x00ee, 0x00fe, 0x0005,
-	0x7098, 0x908a, 0x0029, 0x1a0c, 0x0d7d, 0x9082, 0x001d, 0x003b,
-	0x0026, 0x2011, 0x1e00, 0x080c, 0x2ab4, 0x002e, 0x0005, 0x72e3,
-	0x7269, 0x7285, 0x72af, 0x72d2, 0x7312, 0x7324, 0x7285, 0x72fa,
-	0x7224, 0x7252, 0x7223, 0x0005, 0x00d6, 0x2069, 0x0200, 0x6804,
-	0x9005, 0x1180, 0x6808, 0x9005, 0x1518, 0x709b, 0x0028, 0x2069,
-	0x198e, 0x2d04, 0x7002, 0x080c, 0x767e, 0x6028, 0x9085, 0x0600,
-	0x602a, 0x00b0, 0x709b, 0x0028, 0x2069, 0x198e, 0x2d04, 0x7002,
-	0x6028, 0x9085, 0x0600, 0x602a, 0x00e6, 0x0036, 0x0046, 0x0056,
-	0x2071, 0x1a6a, 0x080c, 0x1b10, 0x005e, 0x004e, 0x003e, 0x00ee,
-	0x00de, 0x0005, 0x00d6, 0x2069, 0x0200, 0x6804, 0x9005, 0x1178,
-	0x6808, 0x9005, 0x1160, 0x709b, 0x0028, 0x2069, 0x198e, 0x2d04,
-	0x7002, 0x080c, 0x7721, 0x6028, 0x9085, 0x0600, 0x602a, 0x00de,
-	0x0005, 0x0006, 0x2001, 0x0090, 0x080c, 0x2a7a, 0x000e, 0x6124,
-	0xd1e4, 0x1190, 0x080c, 0x7395, 0xd1d4, 0x1160, 0xd1dc, 0x1138,
-	0xd1cc, 0x0150, 0x709b, 0x0020, 0x080c, 0x7395, 0x0028, 0x709b,
-	0x001d, 0x0010, 0x709b, 0x001f, 0x0005, 0x2001, 0x0088, 0x080c,
-	0x2a7a, 0x6124, 0xd1cc, 0x11e8, 0xd1dc, 0x11c0, 0xd1e4, 0x1198,
-	0x9184, 0x1e00, 0x11d8, 0x080c, 0x1b35, 0x60e3, 0x0001, 0x600c,
-	0xc0b4, 0x600e, 0x080c, 0x7569, 0x2001, 0x0080, 0x080c, 0x2a7a,
-	0x709b, 0x0028, 0x0058, 0x709b, 0x001e, 0x0040, 0x709b, 0x001d,
-	0x0028, 0x709b, 0x0020, 0x0010, 0x709b, 0x001f, 0x0005, 0x080c,
-	0x1b35, 0x60e3, 0x0001, 0x600c, 0xc0b4, 0x600e, 0x080c, 0x7569,
-	0x2001, 0x0080, 0x080c, 0x2a7a, 0x6124, 0xd1d4, 0x1180, 0xd1dc,
-	0x1158, 0xd1e4, 0x1130, 0x9184, 0x1e00, 0x1158, 0x709b, 0x0028,
+	0x01de, 0x014e, 0x0890, 0x2071, 0x1910, 0xa803, 0x0000, 0x2908,
+	0x7010, 0x8000, 0x7012, 0x7018, 0x904d, 0x711a, 0x0110, 0xa902,
+	0x0008, 0x711e, 0x2148, 0xa804, 0x900d, 0x1118, 0x002e, 0x00ee,
+	0x0005, 0x2071, 0x1800, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802,
+	0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70c0, 0x9200, 0x70c2,
+	0x080c, 0x873a, 0x002e, 0x00ee, 0x0005, 0x0006, 0xa87c, 0x0006,
+	0xa867, 0x0103, 0x20a9, 0x001c, 0xa860, 0x20e8, 0xa85c, 0x9080,
+	0x001d, 0x20a0, 0x9006, 0x4004, 0x000e, 0x9084, 0x00ff, 0xa87e,
+	0x000e, 0xa87a, 0xa982, 0x0005, 0x2071, 0x1910, 0x7004, 0x0002,
+	0x7188, 0x7189, 0x7274, 0x7189, 0x7186, 0x7274, 0x080c, 0x0d85,
+	0x0005, 0x2001, 0x1949, 0x2004, 0x0002, 0x7193, 0x7193, 0x720d,
+	0x720e, 0x7193, 0x720e, 0x0126, 0x2091, 0x8000, 0x1e0c, 0x7294,
+	0x701c, 0x904d, 0x0508, 0xa84c, 0x9005, 0x0904, 0x71de, 0x0e04,
+	0x71bc, 0xa94c, 0x2071, 0x0000, 0x7182, 0xa850, 0x7032, 0xa86c,
+	0x7086, 0x7036, 0xa870, 0x708a, 0xa850, 0x9082, 0x0019, 0x1278,
+	0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x1200,
+	0x2071, 0x1910, 0x080c, 0x7275, 0x012e, 0x0804, 0x720c, 0xa850,
+	0x9082, 0x001c, 0x1e68, 0xa880, 0x708e, 0x7036, 0x0146, 0x01d6,
+	0x0136, 0x01c6, 0x0156, 0x20e9, 0x0000, 0x20a1, 0x002a, 0xa868,
+	0x20a8, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0021, 0x2098, 0x4003,
+	0x015e, 0x01ce, 0x013e, 0x01de, 0x014e, 0x0890, 0x2001, 0x005b,
+	0x2004, 0x9094, 0x0780, 0x190c, 0x7289, 0xd09c, 0x2071, 0x1910,
+	0x1510, 0x2071, 0x1910, 0x700f, 0x0001, 0xa964, 0x9184, 0x00ff,
+	0x9086, 0x0003, 0x1130, 0x810f, 0x918c, 0x00ff, 0x8101, 0x0108,
+	0x710e, 0x2900, 0x00d6, 0x2069, 0x0050, 0x6822, 0x00de, 0x2071,
+	0x1910, 0x701c, 0x2048, 0x7010, 0x8001, 0x7012, 0xa800, 0x701e,
+	0x9005, 0x1108, 0x701a, 0x012e, 0x0005, 0x0005, 0x00d6, 0x2008,
+	0x2069, 0x1a05, 0x6844, 0x9005, 0x0760, 0x0158, 0x9186, 0x0003,
+	0x0540, 0x2001, 0x1815, 0x2004, 0x2009, 0x1b74, 0x210c, 0x9102,
+	0x1500, 0x0126, 0x2091, 0x8000, 0x2069, 0x0050, 0x693c, 0x6838,
+	0x9106, 0x0190, 0x0e04, 0x7240, 0x2069, 0x0000, 0x6837, 0x8040,
+	0x6833, 0x0012, 0x6883, 0x8040, 0x2091, 0x4080, 0x2001, 0x0089,
+	0x2004, 0xd084, 0x190c, 0x1200, 0x2069, 0x1a05, 0x6847, 0xffff,
+	0x012e, 0x00de, 0x0126, 0x2091, 0x8000, 0x1e0c, 0x7304, 0x701c,
+	0x904d, 0x0540, 0x2001, 0x005b, 0x2004, 0x9094, 0x0780, 0x15c9,
+	0xd09c, 0x1500, 0x2071, 0x1910, 0x700f, 0x0001, 0xa964, 0x9184,
+	0x00ff, 0x9086, 0x0003, 0x1130, 0x810f, 0x918c, 0x00ff, 0x8101,
+	0x0108, 0x710e, 0x2900, 0x00d6, 0x2069, 0x0050, 0x6822, 0x00de,
+	0x701c, 0x2048, 0x7010, 0x8001, 0x7012, 0xa800, 0x701e, 0x9005,
+	0x1108, 0x701a, 0x012e, 0x0005, 0x0005, 0x0126, 0x2091, 0x8000,
+	0x701c, 0x904d, 0x0160, 0x7010, 0x8001, 0x7012, 0xa800, 0x701e,
+	0x9005, 0x1108, 0x701a, 0x012e, 0x080c, 0x108b, 0x0005, 0x012e,
+	0x0005, 0x2091, 0x8000, 0x0e04, 0x728b, 0x0006, 0x0016, 0x2001,
+	0x8004, 0x0006, 0x0804, 0x0d8e, 0x0096, 0x00f6, 0x2079, 0x0050,
+	0x7044, 0xd084, 0x01d0, 0xc084, 0x7046, 0x7838, 0x7938, 0x910e,
+	0x1de0, 0x00d6, 0x2069, 0x0000, 0x6836, 0x6833, 0x0013, 0x00de,
+	0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x1200,
+	0x704b, 0x0000, 0x00fe, 0x009e, 0x0005, 0x782c, 0x9094, 0x0780,
+	0x1981, 0xd0a4, 0x0db8, 0x7148, 0x704c, 0x8108, 0x714a, 0x9102,
+	0x0e88, 0x00e6, 0x2071, 0x1800, 0x7824, 0x00e6, 0x2071, 0x0040,
+	0x712c, 0xd19c, 0x1170, 0x2009, 0x1830, 0x210c, 0x918a, 0x0020,
+	0x0240, 0x7022, 0x2001, 0x1dc0, 0x200c, 0x8108, 0x2102, 0x00ee,
+	0x0058, 0x00ee, 0x2048, 0x702c, 0xa802, 0x2900, 0x702e, 0x70c0,
+	0x8000, 0x70c2, 0x080c, 0x873a, 0x782c, 0x9094, 0x0780, 0x190c,
+	0x7289, 0xd0a4, 0x19c8, 0x7838, 0x7938, 0x910e, 0x1de0, 0x00d6,
+	0x2069, 0x0000, 0x6836, 0x6833, 0x0013, 0x00de, 0x2091, 0x4080,
+	0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x1200, 0x00ee, 0x704b,
+	0x0000, 0x00fe, 0x009e, 0x0005, 0x00f6, 0x2079, 0x0050, 0x7044,
+	0xd084, 0x01b8, 0xc084, 0x7046, 0x7838, 0x7938, 0x910e, 0x1de0,
+	0x00d6, 0x2069, 0x0000, 0x6836, 0x6833, 0x0013, 0x00de, 0x2091,
+	0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x1200, 0x00fe,
+	0x0005, 0x782c, 0x9094, 0x0780, 0x190c, 0x7289, 0xd0a4, 0x0db8,
+	0x00e6, 0x2071, 0x1800, 0x7824, 0x2048, 0x702c, 0xa802, 0x2900,
+	0x702e, 0x70c0, 0x8000, 0x70c2, 0x080c, 0x873a, 0x782c, 0x9094,
+	0x0780, 0x190c, 0x7289, 0xd0a4, 0x1d70, 0x00d6, 0x2069, 0x0050,
+	0x693c, 0x2069, 0x1949, 0x6808, 0x690a, 0x2069, 0x1a05, 0x9102,
+	0x1118, 0x6844, 0x9005, 0x1320, 0x2001, 0x194a, 0x200c, 0x6946,
+	0x00de, 0x00ee, 0x00fe, 0x0005, 0x7098, 0x908a, 0x002a, 0x1a0c,
+	0x0d85, 0x9082, 0x001d, 0x003b, 0x0026, 0x2011, 0x1e00, 0x080c,
+	0x2af5, 0x002e, 0x0005, 0x7449, 0x73b6, 0x73d2, 0x73fc, 0x7438,
+	0x7478, 0x748a, 0x73d2, 0x7460, 0x7371, 0x739f, 0x7422, 0x7370,
+	0x0005, 0x00d6, 0x2069, 0x0200, 0x6804, 0x9005, 0x1180, 0x6808,
+	0x9005, 0x1518, 0x709b, 0x0029, 0x2069, 0x1990, 0x2d04, 0x7002,
+	0x080c, 0x77e3, 0x6028, 0x9085, 0x0600, 0x602a, 0x00b0, 0x709b,
+	0x0029, 0x2069, 0x1990, 0x2d04, 0x7002, 0x6028, 0x9085, 0x0600,
+	0x602a, 0x00e6, 0x0036, 0x0046, 0x0056, 0x2071, 0x1a6f, 0x080c,
+	0x1b47, 0x005e, 0x004e, 0x003e, 0x00ee, 0x00de, 0x0005, 0x00d6,
+	0x2069, 0x0200, 0x6804, 0x9005, 0x1178, 0x6808, 0x9005, 0x1160,
+	0x709b, 0x0029, 0x2069, 0x1990, 0x2d04, 0x7002, 0x080c, 0x7888,
+	0x6028, 0x9085, 0x0600, 0x602a, 0x00de, 0x0005, 0x0006, 0x2001,
+	0x0090, 0x080c, 0x2abb, 0x000e, 0x6124, 0xd1e4, 0x1190, 0x080c,
+	0x74fb, 0xd1d4, 0x1160, 0xd1dc, 0x1138, 0xd1cc, 0x0150, 0x709b,
+	0x0020, 0x080c, 0x74fb, 0x0028, 0x709b, 0x001d, 0x0010, 0x709b,
+	0x001f, 0x0005, 0x2001, 0x0088, 0x080c, 0x2abb, 0x6124, 0xd1cc,
+	0x11e8, 0xd1dc, 0x11c0, 0xd1e4, 0x1198, 0x9184, 0x1e00, 0x11d8,
+	0x080c, 0x1b6c, 0x60e3, 0x0001, 0x600c, 0xc0b4, 0x600e, 0x080c,
+	0x76d1, 0x2001, 0x0080, 0x080c, 0x2abb, 0x709b, 0x0029, 0x0058,
+	0x709b, 0x001e, 0x0040, 0x709b, 0x001d, 0x0028, 0x709b, 0x0020,
+	0x0010, 0x709b, 0x001f, 0x0005, 0x080c, 0x1b6c, 0x60e3, 0x0001,
+	0x600c, 0xc0b4, 0x600e, 0x080c, 0x76d1, 0x2001, 0x0080, 0x080c,
+	0x2abb, 0x6124, 0xd1d4, 0x1198, 0xd1dc, 0x1170, 0xd1e4, 0x1148,
+	0x9184, 0x1e00, 0x1118, 0x709b, 0x0029, 0x0058, 0x709b, 0x0028,
 	0x0040, 0x709b, 0x001e, 0x0028, 0x709b, 0x001d, 0x0010, 0x709b,
-	0x001f, 0x0005, 0x2001, 0x00a0, 0x080c, 0x2a7a, 0x6124, 0xd1dc,
-	0x1138, 0xd1e4, 0x0138, 0x080c, 0x1b35, 0x709b, 0x001e, 0x0010,
-	0x709b, 0x001d, 0x0005, 0x080c, 0x741e, 0x6124, 0xd1dc, 0x1188,
-	0x080c, 0x7395, 0x0016, 0x080c, 0x1b35, 0x001e, 0xd1d4, 0x1128,
-	0xd1e4, 0x0138, 0x709b, 0x001e, 0x0020, 0x709b, 0x001f, 0x080c,
-	0x7395, 0x0005, 0x0006, 0x2001, 0x00a0, 0x080c, 0x2a7a, 0x000e,
-	0x6124, 0xd1d4, 0x1160, 0xd1cc, 0x1150, 0xd1dc, 0x1128, 0xd1e4,
+	0x001f, 0x0005, 0x6124, 0xd1d4, 0x1180, 0xd1dc, 0x1158, 0xd1e4,
+	0x1130, 0x9184, 0x1e00, 0x1158, 0x709b, 0x0029, 0x0040, 0x709b,
+	0x001e, 0x0028, 0x709b, 0x001d, 0x0010, 0x709b, 0x001f, 0x0005,
+	0x2001, 0x00a0, 0x080c, 0x2abb, 0x6124, 0xd1dc, 0x1138, 0xd1e4,
+	0x0138, 0x080c, 0x1b6c, 0x709b, 0x001e, 0x0010, 0x709b, 0x001d,
+	0x0005, 0x080c, 0x7584, 0x6124, 0xd1dc, 0x1188, 0x080c, 0x74fb,
+	0x0016, 0x080c, 0x1b6c, 0x001e, 0xd1d4, 0x1128, 0xd1e4, 0x0138,
+	0x709b, 0x001e, 0x0020, 0x709b, 0x001f, 0x080c, 0x74fb, 0x0005,
+	0x0006, 0x2001, 0x00a0, 0x080c, 0x2abb, 0x000e, 0x6124, 0xd1d4,
+	0x1160, 0xd1cc, 0x1150, 0xd1dc, 0x1128, 0xd1e4, 0x0140, 0x709b,
+	0x001e, 0x0028, 0x709b, 0x001d, 0x0010, 0x709b, 0x0021, 0x0005,
+	0x080c, 0x7584, 0x6124, 0xd1d4, 0x1150, 0xd1dc, 0x1128, 0xd1e4,
 	0x0140, 0x709b, 0x001e, 0x0028, 0x709b, 0x001d, 0x0010, 0x709b,
-	0x0021, 0x0005, 0x080c, 0x741e, 0x6124, 0xd1d4, 0x1150, 0xd1dc,
-	0x1128, 0xd1e4, 0x0140, 0x709b, 0x001e, 0x0028, 0x709b, 0x001d,
-	0x0010, 0x709b, 0x001f, 0x0005, 0x0006, 0x2001, 0x0090, 0x080c,
-	0x2a7a, 0x000e, 0x6124, 0xd1d4, 0x1178, 0xd1cc, 0x1150, 0xd1dc,
-	0x1128, 0xd1e4, 0x0158, 0x709b, 0x001e, 0x0040, 0x709b, 0x001d,
-	0x0028, 0x709b, 0x0020, 0x0010, 0x709b, 0x001f, 0x0005, 0x0016,
-	0x00c6, 0x00d6, 0x00e6, 0x0126, 0x2061, 0x0100, 0x2069, 0x0140,
-	0x2071, 0x1800, 0x2091, 0x8000, 0x080c, 0x753d, 0x11f8, 0x2001,
-	0x180c, 0x200c, 0xd1b4, 0x01d0, 0xc1b4, 0x2102, 0x0026, 0x2011,
-	0x0200, 0x080c, 0x2ab4, 0x002e, 0x080c, 0x2a60, 0x6024, 0xd0cc,
-	0x0148, 0x2001, 0x00a0, 0x080c, 0x2a7a, 0x080c, 0x7840, 0x080c,
-	0x6092, 0x0428, 0x6028, 0xc0cd, 0x602a, 0x0408, 0x080c, 0x7557,
-	0x0150, 0x080c, 0x754e, 0x1138, 0x2001, 0x0001, 0x080c, 0x2606,
-	0x080c, 0x7511, 0x00a0, 0x080c, 0x741b, 0x0178, 0x2001, 0x0001,
-	0x080c, 0x2606, 0x7098, 0x9086, 0x001e, 0x0120, 0x7098, 0x9086,
-	0x0022, 0x1118, 0x709b, 0x0025, 0x0010, 0x709b, 0x0021, 0x012e,
-	0x00ee, 0x00de, 0x00ce, 0x001e, 0x0005, 0x0026, 0x2011, 0x73a6,
-	0x080c, 0x87d4, 0x002e, 0x0016, 0x0026, 0x2009, 0x0064, 0x2011,
-	0x73a6, 0x080c, 0x87cb, 0x002e, 0x001e, 0x0005, 0x00e6, 0x00f6,
-	0x0016, 0x080c, 0x9ed4, 0x2071, 0x1800, 0x080c, 0x733f, 0x001e,
-	0x00fe, 0x00ee, 0x0005, 0x0016, 0x0026, 0x0036, 0x00c6, 0x00d6,
-	0x00e6, 0x00f6, 0x0126, 0x080c, 0x9ed4, 0x2061, 0x0100, 0x2069,
-	0x0140, 0x2071, 0x1800, 0x2091, 0x8000, 0x6028, 0xc09c, 0x602a,
-	0x080c, 0xa91e, 0x2011, 0x0003, 0x080c, 0xa243, 0x2011, 0x0002,
-	0x080c, 0xa24d, 0x080c, 0xa138, 0x080c, 0x8780, 0x0036, 0x901e,
-	0x080c, 0xa1b8, 0x003e, 0x080c, 0xa93a, 0x60e3, 0x0000, 0x080c,
-	0xe882, 0x080c, 0xe89d, 0x2009, 0x0004, 0x080c, 0x2a66, 0x080c,
-	0x297c, 0x2001, 0x1800, 0x2003, 0x0004, 0x2011, 0x0008, 0x080c,
-	0x2ab4, 0x2011, 0x73a6, 0x080c, 0x87d4, 0x080c, 0x7557, 0x0118,
-	0x9006, 0x080c, 0x2a7a, 0x080c, 0x0bc3, 0x2001, 0x0001, 0x080c,
-	0x2606, 0x012e, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e,
-	0x001e, 0x0005, 0x0026, 0x00e6, 0x2011, 0x73b3, 0x2071, 0x1a02,
-	0x701c, 0x9206, 0x1118, 0x7018, 0x9005, 0x0110, 0x9085, 0x0001,
-	0x00ee, 0x002e, 0x0005, 0x6020, 0xd09c, 0x0005, 0x6800, 0x9084,
-	0xfffe, 0x9086, 0x00c0, 0x01b8, 0x2001, 0x00c0, 0x080c, 0x2a7a,
-	0x0156, 0x20a9, 0x002d, 0x1d04, 0x742b, 0x2091, 0x6000, 0x1f04,
-	0x742b, 0x015e, 0x00d6, 0x2069, 0x1800, 0x689c, 0x8001, 0x0220,
-	0x0118, 0x689e, 0x00de, 0x0005, 0x689f, 0x0014, 0x68ec, 0xd0dc,
-	0x0dc8, 0x6800, 0x9086, 0x0001, 0x1da8, 0x080c, 0x87e0, 0x0c90,
-	0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2069, 0x0140, 0x2071,
-	0x1800, 0x080c, 0x784f, 0x2001, 0x196c, 0x2003, 0x0000, 0x9006,
-	0x709a, 0x60e2, 0x6886, 0x080c, 0x26d5, 0x9006, 0x080c, 0x2a7a,
-	0x080c, 0x5f4d, 0x0026, 0x2011, 0xffff, 0x080c, 0x2ab4, 0x002e,
-	0x602b, 0x182c, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x00c6, 0x00d6,
-	0x00e6, 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0x1800, 0x2001,
-	0x197c, 0x200c, 0x9186, 0x0000, 0x0158, 0x9186, 0x0001, 0x0158,
-	0x9186, 0x0002, 0x0158, 0x9186, 0x0003, 0x0158, 0x0804, 0x7501,
-	0x709b, 0x0022, 0x0040, 0x709b, 0x0021, 0x0028, 0x709b, 0x0023,
-	0x0010, 0x709b, 0x0024, 0x60e3, 0x0000, 0x6887, 0x0001, 0x2001,
-	0x0001, 0x080c, 0x26d5, 0x080c, 0xa91e, 0x0026, 0x080c, 0xabe9,
-	0x002e, 0x080c, 0xa93a, 0x7000, 0x908e, 0x0004, 0x0118, 0x602b,
+	0x001f, 0x0005, 0x0006, 0x2001, 0x0090, 0x080c, 0x2abb, 0x000e,
+	0x6124, 0xd1d4, 0x1178, 0xd1cc, 0x1150, 0xd1dc, 0x1128, 0xd1e4,
+	0x0158, 0x709b, 0x001e, 0x0040, 0x709b, 0x001d, 0x0028, 0x709b,
+	0x0020, 0x0010, 0x709b, 0x001f, 0x0005, 0x0016, 0x00c6, 0x00d6,
+	0x00e6, 0x0126, 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0x1800,
+	0x2091, 0x8000, 0x080c, 0x76a5, 0x11f8, 0x2001, 0x180c, 0x200c,
+	0xd1b4, 0x01d0, 0xc1b4, 0x2102, 0x0026, 0x2011, 0x0200, 0x080c,
+	0x2af5, 0x002e, 0x080c, 0x2aa1, 0x6024, 0xd0cc, 0x0148, 0x2001,
+	0x00a0, 0x080c, 0x2abb, 0x080c, 0x79a7, 0x080c, 0x617e, 0x0428,
+	0x6028, 0xc0cd, 0x602a, 0x0408, 0x080c, 0x76bf, 0x0150, 0x080c,
+	0x76b6, 0x1138, 0x2001, 0x0001, 0x080c, 0x2647, 0x080c, 0x7679,
+	0x00a0, 0x080c, 0x7581, 0x0178, 0x2001, 0x0001, 0x080c, 0x2647,
+	0x7098, 0x9086, 0x001e, 0x0120, 0x7098, 0x9086, 0x0022, 0x1118,
+	0x709b, 0x0025, 0x0010, 0x709b, 0x0021, 0x012e, 0x00ee, 0x00de,
+	0x00ce, 0x001e, 0x0005, 0x0026, 0x2011, 0x750c, 0x080c, 0x8940,
+	0x002e, 0x0016, 0x0026, 0x2009, 0x0064, 0x2011, 0x750c, 0x080c,
+	0x8937, 0x002e, 0x001e, 0x0005, 0x00e6, 0x00f6, 0x0016, 0x080c,
+	0xa08a, 0x2071, 0x1800, 0x080c, 0x74a5, 0x001e, 0x00fe, 0x00ee,
+	0x0005, 0x0016, 0x0026, 0x0036, 0x00c6, 0x00d6, 0x00e6, 0x00f6,
+	0x0126, 0x2071, 0x1800, 0x080c, 0xa08a, 0x2061, 0x0100, 0x2069,
+	0x0140, 0x2091, 0x8000, 0x6028, 0xc09c, 0x602a, 0x080c, 0xaae0,
+	0x2011, 0x0003, 0x080c, 0xa40f, 0x2011, 0x0002, 0x080c, 0xa419,
+	0x080c, 0xa300, 0x080c, 0x88ec, 0x0036, 0x901e, 0x080c, 0xa380,
+	0x003e, 0x080c, 0xaafc, 0x60e3, 0x0000, 0x080c, 0xeb7d, 0x080c,
+	0xeb98, 0x2009, 0x0004, 0x080c, 0x2aa7, 0x080c, 0x29bd, 0x2001,
+	0x1800, 0x2003, 0x0004, 0x2011, 0x0008, 0x080c, 0x2af5, 0x2011,
+	0x750c, 0x080c, 0x8940, 0x080c, 0x76bf, 0x0118, 0x9006, 0x080c,
+	0x2abb, 0x080c, 0x0bc3, 0x2001, 0x0001, 0x080c, 0x2647, 0x012e,
+	0x00fe, 0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e, 0x001e, 0x0005,
+	0x0026, 0x00e6, 0x2011, 0x7519, 0x2071, 0x1a05, 0x701c, 0x9206,
+	0x1118, 0x7018, 0x9005, 0x0110, 0x9085, 0x0001, 0x00ee, 0x002e,
+	0x0005, 0x6020, 0xd09c, 0x0005, 0x6800, 0x9084, 0xfffe, 0x9086,
+	0x00c0, 0x01b8, 0x2001, 0x00c0, 0x080c, 0x2abb, 0x0156, 0x20a9,
+	0x002d, 0x1d04, 0x7591, 0x2091, 0x6000, 0x1f04, 0x7591, 0x015e,
+	0x00d6, 0x2069, 0x1800, 0x689c, 0x8001, 0x0220, 0x0118, 0x689e,
+	0x00de, 0x0005, 0x689f, 0x0014, 0x68ec, 0xd0dc, 0x0dc8, 0x6800,
+	0x9086, 0x0001, 0x1da8, 0x080c, 0x894c, 0x0c90, 0x00c6, 0x00d6,
+	0x00e6, 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0x1800, 0x080c,
+	0x79b6, 0x2001, 0x196e, 0x2003, 0x0000, 0x9006, 0x709a, 0x60e2,
+	0x6886, 0x080c, 0x2716, 0x9006, 0x080c, 0x2abb, 0x080c, 0x6039,
+	0x0026, 0x2011, 0xffff, 0x080c, 0x2af5, 0x002e, 0x602b, 0x182c,
+	0x00ee, 0x00de, 0x00ce, 0x0005, 0x00c6, 0x00d6, 0x00e6, 0x2061,
+	0x0100, 0x2069, 0x0140, 0x2071, 0x1800, 0x2001, 0x197e, 0x200c,
+	0x9186, 0x0000, 0x0158, 0x9186, 0x0001, 0x0158, 0x9186, 0x0002,
+	0x0158, 0x9186, 0x0003, 0x0158, 0x0804, 0x7669, 0x709b, 0x0022,
+	0x0040, 0x709b, 0x0021, 0x0028, 0x709b, 0x0023, 0x0010, 0x709b,
+	0x0024, 0x60e3, 0x0000, 0x6887, 0x0001, 0x2001, 0x0001, 0x080c,
+	0x2716, 0x080c, 0xaae0, 0x0026, 0x080c, 0xad9e, 0x080c, 0xae67,
+	0x002e, 0x080c, 0xaafc, 0x7000, 0x908e, 0x0004, 0x0118, 0x602b,
 	0x0028, 0x0010, 0x602b, 0x0020, 0x0156, 0x0126, 0x2091, 0x8000,
 	0x20a9, 0x0005, 0x6024, 0xd0ac, 0x0150, 0x012e, 0x015e, 0x080c,
-	0xd09b, 0x0118, 0x9006, 0x080c, 0x2aa4, 0x0804, 0x750d, 0x6800,
-	0x9084, 0x00a1, 0xc0bd, 0x6802, 0x080c, 0x2a60, 0x6904, 0xd1d4,
-	0x1140, 0x2001, 0x0100, 0x080c, 0x2a7a, 0x1f04, 0x74b2, 0x080c,
-	0x7594, 0x012e, 0x015e, 0x080c, 0x754e, 0x0170, 0x6044, 0x9005,
-	0x0130, 0x080c, 0x7594, 0x9006, 0x8001, 0x1df0, 0x0028, 0x6804,
-	0xd0d4, 0x1110, 0x080c, 0x7594, 0x080c, 0xd09b, 0x0118, 0x9006,
-	0x080c, 0x2aa4, 0x0016, 0x0026, 0x7000, 0x908e, 0x0004, 0x0130,
-	0x2009, 0x00c8, 0x2011, 0x73b3, 0x080c, 0x8792, 0x002e, 0x001e,
-	0x080c, 0x85c5, 0x7034, 0xc085, 0x7036, 0x2001, 0x197c, 0x2003,
-	0x0004, 0x080c, 0x7208, 0x080c, 0x754e, 0x0138, 0x6804, 0xd0d4,
-	0x1120, 0xd0dc, 0x1100, 0x080c, 0x7845, 0x00ee, 0x00de, 0x00ce,
+	0xd33e, 0x0118, 0x9006, 0x080c, 0x2ae5, 0x0804, 0x7675, 0x6800,
+	0x9084, 0x00a1, 0xc0bd, 0x6802, 0x080c, 0x2aa1, 0x6904, 0xd1d4,
+	0x1140, 0x2001, 0x0100, 0x080c, 0x2abb, 0x1f04, 0x761a, 0x080c,
+	0x76f9, 0x012e, 0x015e, 0x080c, 0x76b6, 0x0170, 0x6044, 0x9005,
+	0x0130, 0x080c, 0x76f9, 0x9006, 0x8001, 0x1df0, 0x0028, 0x6804,
+	0xd0d4, 0x1110, 0x080c, 0x76f9, 0x080c, 0xd33e, 0x0118, 0x9006,
+	0x080c, 0x2ae5, 0x0016, 0x0026, 0x7000, 0x908e, 0x0004, 0x0130,
+	0x2009, 0x00c8, 0x2011, 0x7519, 0x080c, 0x88fe, 0x002e, 0x001e,
+	0x080c, 0x8731, 0x7034, 0xc085, 0x7036, 0x2001, 0x197e, 0x2003,
+	0x0004, 0x080c, 0x7354, 0x080c, 0x76b6, 0x0138, 0x6804, 0xd0d4,
+	0x1120, 0xd0dc, 0x1100, 0x080c, 0x79ac, 0x00ee, 0x00de, 0x00ce,
 	0x0005, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2069, 0x0140,
-	0x2071, 0x1800, 0x080c, 0x85dc, 0x080c, 0x85ce, 0x080c, 0x784f,
-	0x2001, 0x196c, 0x2003, 0x0000, 0x9006, 0x709a, 0x60e2, 0x6886,
-	0x080c, 0x26d5, 0x9006, 0x080c, 0x2a7a, 0x6043, 0x0090, 0x6043,
-	0x0010, 0x0026, 0x2011, 0xffff, 0x080c, 0x2ab4, 0x002e, 0x602b,
-	0x182c, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x0006, 0x2001, 0x197b,
-	0x2004, 0x9086, 0xaaaa, 0x000e, 0x0005, 0x0006, 0x080c, 0x5742,
+	0x2071, 0x1800, 0x080c, 0x8748, 0x080c, 0x873a, 0x080c, 0x79b6,
+	0x2001, 0x196e, 0x2003, 0x0000, 0x9006, 0x709a, 0x60e2, 0x6886,
+	0x080c, 0x2716, 0x9006, 0x080c, 0x2abb, 0x6043, 0x0090, 0x6043,
+	0x0010, 0x0026, 0x2011, 0xffff, 0x080c, 0x2af5, 0x002e, 0x602b,
+	0x182c, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x0006, 0x2001, 0x197d,
+	0x2004, 0x9086, 0xaaaa, 0x000e, 0x0005, 0x0006, 0x080c, 0x582a,
 	0x9084, 0x0030, 0x9086, 0x0000, 0x000e, 0x0005, 0x0006, 0x080c,
-	0x5742, 0x9084, 0x0030, 0x9086, 0x0030, 0x000e, 0x0005, 0x0006,
-	0x080c, 0x5742, 0x9084, 0x0030, 0x9086, 0x0010, 0x000e, 0x0005,
-	0x0006, 0x080c, 0x5742, 0x9084, 0x0030, 0x9086, 0x0020, 0x000e,
+	0x582a, 0x9084, 0x0030, 0x9086, 0x0030, 0x000e, 0x0005, 0x0006,
+	0x080c, 0x582a, 0x9084, 0x0030, 0x9086, 0x0010, 0x000e, 0x0005,
+	0x0006, 0x080c, 0x582a, 0x9084, 0x0030, 0x9086, 0x0020, 0x000e,
 	0x0005, 0x0036, 0x0016, 0x2001, 0x180c, 0x2004, 0x908c, 0x0013,
-	0x0180, 0x0020, 0x080c, 0x26f5, 0x900e, 0x0028, 0x080c, 0x6ad5,
-	0x1dc8, 0x2009, 0x0002, 0x2019, 0x0028, 0x080c, 0x3205, 0x9006,
-	0x0019, 0x001e, 0x003e, 0x0005, 0x00e6, 0x2071, 0x180c, 0x2e04,
-	0x0130, 0x080c, 0xd094, 0x1128, 0x9085, 0x0010, 0x0010, 0x9084,
-	0xffef, 0x2072, 0x00ee, 0x0005, 0x6050, 0x0006, 0x60ec, 0x0006,
-	0x600c, 0x0006, 0x6004, 0x0006, 0x6028, 0x0006, 0x080c, 0x2ad7,
-	0x080c, 0x2b0a, 0x602f, 0x0100, 0x602f, 0x0000, 0x602f, 0x0040,
-	0x602f, 0x0000, 0x20a9, 0x0002, 0x080c, 0x2a41, 0x0026, 0x2011,
-	0x0040, 0x080c, 0x2ab4, 0x002e, 0x000e, 0x602a, 0x000e, 0x6006,
-	0x000e, 0x600e, 0x000e, 0x60ee, 0x60e3, 0x0000, 0x6887, 0x0001,
-	0x2001, 0x0001, 0x080c, 0x26d5, 0x2001, 0x00a0, 0x0006, 0x080c,
-	0xd09b, 0x000e, 0x0130, 0x080c, 0x2a98, 0x9006, 0x080c, 0x2aa4,
-	0x0010, 0x080c, 0x2a7a, 0x000e, 0x6052, 0x6050, 0x0006, 0xc0e5,
-	0x6052, 0x00f6, 0x2079, 0x0100, 0x080c, 0x29ed, 0x00fe, 0x000e,
-	0x6052, 0x0005, 0x0156, 0x0016, 0x0026, 0x0036, 0x00c6, 0x00d6,
-	0x00e6, 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0x1800, 0x080c,
-	0xa97c, 0x0158, 0x2001, 0x0386, 0x2004, 0xd0b4, 0x1130, 0x2001,
-	0x0016, 0x080c, 0xa90f, 0x0804, 0x7670, 0x2001, 0x180c, 0x200c,
-	0xc1c4, 0x2102, 0x6028, 0x9084, 0xe1ff, 0x602a, 0x2011, 0x0200,
-	0x080c, 0x2ab4, 0x2001, 0x0090, 0x080c, 0x2a7a, 0x20a9, 0x0366,
-	0x6024, 0xd0cc, 0x1558, 0x1d04, 0x7610, 0x2091, 0x6000, 0x1f04,
-	0x7610, 0x080c, 0xa91e, 0x2011, 0x0003, 0x080c, 0xa243, 0x2011,
-	0x0002, 0x080c, 0xa24d, 0x080c, 0xa138, 0x901e, 0x080c, 0xa1b8,
-	0x2001, 0x0386, 0x2003, 0x7000, 0x080c, 0xa93a, 0x2001, 0x00a0,
-	0x080c, 0x2a7a, 0x080c, 0x7840, 0x080c, 0x6092, 0x080c, 0xd09b,
-	0x0110, 0x080c, 0x0ce9, 0x9085, 0x0001, 0x04c0, 0x080c, 0x1b35,
-	0x60e3, 0x0000, 0x2001, 0x196c, 0x2004, 0x080c, 0x26d5, 0x60e2,
-	0x2001, 0x0080, 0x080c, 0x2a7a, 0x20a9, 0x0366, 0x2011, 0x1e00,
-	0x080c, 0x2ab4, 0x2009, 0x1e00, 0x080c, 0x2a60, 0x6024, 0x910c,
-	0x0140, 0x1d04, 0x764e, 0x2091, 0x6000, 0x1f04, 0x764e, 0x0804,
-	0x7619, 0x2001, 0x0386, 0x2003, 0x7000, 0x6028, 0x9085, 0x1e00,
-	0x602a, 0x70b4, 0x9005, 0x1118, 0x6887, 0x0001, 0x0008, 0x6886,
-	0x080c, 0xd09b, 0x0110, 0x080c, 0x0ce9, 0x9006, 0x00ee, 0x00de,
-	0x00ce, 0x003e, 0x002e, 0x001e, 0x015e, 0x0005, 0x0156, 0x0016,
-	0x0026, 0x0036, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2071,
-	0x1800, 0x7000, 0x9086, 0x0003, 0x1168, 0x2001, 0x020b, 0x2004,
-	0x9084, 0x5540, 0x9086, 0x5540, 0x1128, 0x2069, 0x1a76, 0x2d04,
-	0x8000, 0x206a, 0x2069, 0x0140, 0x6020, 0x9084, 0x00c0, 0x0120,
-	0x6884, 0x9005, 0x1904, 0x76e7, 0x2001, 0x0088, 0x080c, 0x2a7a,
-	0x9006, 0x60e2, 0x6886, 0x080c, 0x26d5, 0x2069, 0x0200, 0x6804,
-	0x9005, 0x1118, 0x6808, 0x9005, 0x01d0, 0x6028, 0x9084, 0xfbff,
-	0x602a, 0x2011, 0x0400, 0x080c, 0x2ab4, 0x2069, 0x198e, 0x7000,
-	0x206a, 0x709b, 0x0026, 0x7003, 0x0001, 0x20a9, 0x0002, 0x1d04,
-	0x76c7, 0x2091, 0x6000, 0x1f04, 0x76c7, 0x0804, 0x7719, 0x2069,
-	0x0140, 0x20a9, 0x0384, 0x2011, 0x1e00, 0x080c, 0x2ab4, 0x2009,
-	0x1e00, 0x080c, 0x2a60, 0x6024, 0x910c, 0x0528, 0x9084, 0x1a00,
-	0x1510, 0x1d04, 0x76d3, 0x2091, 0x6000, 0x1f04, 0x76d3, 0x080c,
-	0xa91e, 0x2011, 0x0003, 0x080c, 0xa243, 0x2011, 0x0002, 0x080c,
-	0xa24d, 0x080c, 0xa138, 0x901e, 0x080c, 0xa1b8, 0x080c, 0xa93a,
-	0x2001, 0x00a0, 0x080c, 0x2a7a, 0x080c, 0x7840, 0x080c, 0x6092,
-	0x9085, 0x0001, 0x00b0, 0x2001, 0x0080, 0x080c, 0x2a7a, 0x2069,
-	0x0140, 0x60e3, 0x0000, 0x70b4, 0x9005, 0x1118, 0x6887, 0x0001,
-	0x0008, 0x6886, 0x2001, 0x196c, 0x2004, 0x080c, 0x26d5, 0x60e2,
-	0x9006, 0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e, 0x001e, 0x015e,
-	0x0005, 0x0156, 0x0016, 0x0026, 0x0036, 0x00c6, 0x00d6, 0x00e6,
-	0x2061, 0x0100, 0x2071, 0x1800, 0x6020, 0x9084, 0x00c0, 0x01e8,
-	0x080c, 0xa91e, 0x2011, 0x0003, 0x080c, 0xa243, 0x2011, 0x0002,
-	0x080c, 0xa24d, 0x080c, 0xa138, 0x901e, 0x080c, 0xa1b8, 0x080c,
-	0xa93a, 0x2069, 0x0140, 0x2001, 0x00a0, 0x080c, 0x2a7a, 0x080c,
-	0x7840, 0x080c, 0x6092, 0x0804, 0x77bc, 0x2001, 0x180c, 0x200c,
-	0xd1b4, 0x1160, 0xc1b5, 0x2102, 0x080c, 0x739b, 0x2069, 0x0140,
-	0x2001, 0x0080, 0x080c, 0x2a7a, 0x60e3, 0x0000, 0x2069, 0x0200,
-	0x6804, 0x9005, 0x1118, 0x6808, 0x9005, 0x0190, 0x6028, 0x9084,
-	0xfdff, 0x602a, 0x2011, 0x0200, 0x080c, 0x2ab4, 0x2069, 0x198e,
-	0x7000, 0x206a, 0x709b, 0x0027, 0x7003, 0x0001, 0x0804, 0x77bc,
-	0x2011, 0x1e00, 0x080c, 0x2ab4, 0x2009, 0x1e00, 0x080c, 0x2a60,
-	0x6024, 0x910c, 0x01c8, 0x9084, 0x1c00, 0x11b0, 0x1d04, 0x7778,
-	0x0006, 0x0016, 0x00c6, 0x00d6, 0x00e6, 0x080c, 0x861c, 0x00ee,
-	0x00de, 0x00ce, 0x001e, 0x000e, 0x00e6, 0x2071, 0x1a02, 0x7070,
-	0x00ee, 0x9005, 0x19e8, 0x0400, 0x0026, 0x2011, 0x73b3, 0x080c,
-	0x86c8, 0x2011, 0x73a6, 0x080c, 0x87d4, 0x002e, 0x2069, 0x0140,
+	0x0168, 0x0020, 0x080c, 0x2736, 0x900e, 0x0010, 0x2009, 0x0002,
+	0x2019, 0x0028, 0x080c, 0x32d5, 0x9006, 0x0019, 0x001e, 0x003e,
+	0x0005, 0x00e6, 0x2071, 0x180c, 0x2e04, 0x0130, 0x080c, 0xd337,
+	0x1128, 0x9085, 0x0010, 0x0010, 0x9084, 0xffef, 0x2072, 0x00ee,
+	0x0005, 0x6050, 0x0006, 0x60ec, 0x0006, 0x600c, 0x0006, 0x6004,
+	0x0006, 0x6028, 0x0006, 0x080c, 0x2b18, 0x080c, 0x2b4b, 0x602f,
+	0x0100, 0x602f, 0x0000, 0x602f, 0x0040, 0x602f, 0x0000, 0x20a9,
+	0x0002, 0x080c, 0x2a82, 0x0026, 0x2011, 0x0040, 0x080c, 0x2af5,
+	0x002e, 0x000e, 0x602a, 0x000e, 0x6006, 0x000e, 0x600e, 0x000e,
+	0x60ee, 0x60e3, 0x0000, 0x6887, 0x0001, 0x2001, 0x0001, 0x080c,
+	0x2716, 0x2001, 0x00a0, 0x0006, 0x080c, 0xd33e, 0x000e, 0x0130,
+	0x080c, 0x2ad9, 0x9006, 0x080c, 0x2ae5, 0x0010, 0x080c, 0x2abb,
+	0x000e, 0x6052, 0x6050, 0x0006, 0xc0e5, 0x6052, 0x00f6, 0x2079,
+	0x0100, 0x080c, 0x2a2e, 0x00fe, 0x000e, 0x6052, 0x0005, 0x0156,
+	0x0016, 0x0026, 0x0036, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100,
+	0x2069, 0x0140, 0x2071, 0x1800, 0x080c, 0xab3e, 0x0158, 0x2001,
+	0x0386, 0x2004, 0xd0b4, 0x1130, 0x2001, 0x0016, 0x080c, 0xaad1,
+	0x0804, 0x77d5, 0x2001, 0x180c, 0x200c, 0xc1c4, 0x2102, 0x6028,
+	0x9084, 0xe1ff, 0x602a, 0x2011, 0x0200, 0x080c, 0x2af5, 0x2001,
+	0x0090, 0x080c, 0x2abb, 0x20a9, 0x0366, 0x6024, 0xd0cc, 0x1558,
+	0x1d04, 0x7775, 0x2091, 0x6000, 0x1f04, 0x7775, 0x080c, 0xaae0,
+	0x2011, 0x0003, 0x080c, 0xa40f, 0x2011, 0x0002, 0x080c, 0xa419,
+	0x080c, 0xa300, 0x901e, 0x080c, 0xa380, 0x2001, 0x0386, 0x2003,
+	0x7000, 0x080c, 0xaafc, 0x2001, 0x00a0, 0x080c, 0x2abb, 0x080c,
+	0x79a7, 0x080c, 0x617e, 0x080c, 0xd33e, 0x0110, 0x080c, 0x0cf1,
+	0x9085, 0x0001, 0x04c0, 0x080c, 0x1b6c, 0x60e3, 0x0000, 0x2001,
+	0x196e, 0x2004, 0x080c, 0x2716, 0x60e2, 0x2001, 0x0080, 0x080c,
+	0x2abb, 0x20a9, 0x0366, 0x2011, 0x1e00, 0x080c, 0x2af5, 0x2009,
+	0x1e00, 0x080c, 0x2aa1, 0x6024, 0x910c, 0x0140, 0x1d04, 0x77b3,
+	0x2091, 0x6000, 0x1f04, 0x77b3, 0x0804, 0x777e, 0x2001, 0x0386,
+	0x2003, 0x7000, 0x6028, 0x9085, 0x1e00, 0x602a, 0x70b4, 0x9005,
+	0x1118, 0x6887, 0x0001, 0x0008, 0x6886, 0x080c, 0xd33e, 0x0110,
+	0x080c, 0x0cf1, 0x9006, 0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e,
+	0x001e, 0x015e, 0x0005, 0x0156, 0x0016, 0x0026, 0x0036, 0x00c6,
+	0x00d6, 0x00e6, 0x2061, 0x0100, 0x2071, 0x1800, 0x7000, 0x9086,
+	0x0003, 0x1168, 0x2001, 0x020b, 0x2004, 0x9084, 0x5540, 0x9086,
+	0x5540, 0x1128, 0x2069, 0x1a7c, 0x2d04, 0x8000, 0x206a, 0x2069,
+	0x0140, 0x6020, 0x9084, 0x00c0, 0x0120, 0x6884, 0x9005, 0x1904,
+	0x784c, 0x2001, 0x0088, 0x080c, 0x2abb, 0x9006, 0x60e2, 0x6886,
+	0x080c, 0x2716, 0x2069, 0x0200, 0x6804, 0x9005, 0x1118, 0x6808,
+	0x9005, 0x01d0, 0x6028, 0x9084, 0xfbff, 0x602a, 0x2011, 0x0400,
+	0x080c, 0x2af5, 0x2069, 0x1990, 0x7000, 0x206a, 0x709b, 0x0026,
+	0x7003, 0x0001, 0x20a9, 0x0002, 0x1d04, 0x782c, 0x2091, 0x6000,
+	0x1f04, 0x782c, 0x0804, 0x7880, 0x2069, 0x0140, 0x20a9, 0x0384,
+	0x2011, 0x1e00, 0x080c, 0x2af5, 0x2009, 0x1e00, 0x080c, 0x2aa1,
+	0x6024, 0x910c, 0x0528, 0x9084, 0x1a00, 0x1510, 0x1d04, 0x7838,
+	0x2091, 0x6000, 0x1f04, 0x7838, 0x080c, 0xaae0, 0x2011, 0x0003,
+	0x080c, 0xa40f, 0x2011, 0x0002, 0x080c, 0xa419, 0x080c, 0xa300,
+	0x901e, 0x080c, 0xa380, 0x080c, 0xaafc, 0x2001, 0x00a0, 0x080c,
+	0x2abb, 0x080c, 0x79a7, 0x080c, 0x617e, 0x9085, 0x0001, 0x00c0,
+	0x080c, 0x1b6c, 0x2001, 0x0080, 0x080c, 0x2abb, 0x2069, 0x0140,
 	0x60e3, 0x0000, 0x70b4, 0x9005, 0x1118, 0x6887, 0x0001, 0x0008,
-	0x6886, 0x2001, 0x196c, 0x2004, 0x080c, 0x26d5, 0x60e2, 0x2001,
-	0x180c, 0x200c, 0xc1b4, 0x2102, 0x00ee, 0x00de, 0x00ce, 0x003e,
-	0x002e, 0x001e, 0x015e, 0x0005, 0x0156, 0x0016, 0x0026, 0x0036,
-	0x0046, 0x00c6, 0x00e6, 0x2061, 0x0100, 0x2071, 0x1800, 0x080c,
-	0xd094, 0x1904, 0x782a, 0x7130, 0xd184, 0x1170, 0x080c, 0x33ad,
-	0x0138, 0xc18d, 0x7132, 0x2011, 0x1848, 0x2214, 0xd2ac, 0x1120,
-	0x7030, 0xd08c, 0x0904, 0x782a, 0x2011, 0x1848, 0x220c, 0xd1a4,
-	0x0538, 0x0016, 0x2019, 0x000e, 0x080c, 0xe3b5, 0x0156, 0x00b6,
-	0x20a9, 0x007f, 0x900e, 0x9186, 0x007e, 0x01a0, 0x9186, 0x0080,
-	0x0188, 0x080c, 0x6693, 0x1170, 0x2120, 0x9006, 0x0016, 0x2009,
-	0x000e, 0x080c, 0xe445, 0x2009, 0x0001, 0x2011, 0x0100, 0x080c,
-	0x8979, 0x001e, 0x8108, 0x1f04, 0x77f3, 0x00be, 0x015e, 0x001e,
-	0xd1ac, 0x1148, 0x0016, 0x2009, 0x0002, 0x2019, 0x0004, 0x080c,
-	0x3205, 0x001e, 0x0078, 0x0156, 0x00b6, 0x20a9, 0x007f, 0x900e,
-	0x080c, 0x6693, 0x1110, 0x080c, 0x60ac, 0x8108, 0x1f04, 0x7820,
-	0x00be, 0x015e, 0x080c, 0x1b35, 0x080c, 0xa91e, 0x080c, 0xabe9,
-	0x080c, 0xa93a, 0x60e3, 0x0000, 0x080c, 0x6092, 0x080c, 0x746e,
-	0x00ee, 0x00ce, 0x004e, 0x003e, 0x002e, 0x001e, 0x015e, 0x0005,
-	0x2001, 0x197c, 0x2003, 0x0001, 0x0005, 0x2001, 0x197c, 0x2003,
-	0x0000, 0x0005, 0x2001, 0x197b, 0x2003, 0xaaaa, 0x0005, 0x2001,
-	0x197b, 0x2003, 0x0000, 0x0005, 0x2071, 0x18fa, 0x7003, 0x0000,
-	0x7007, 0x0000, 0x080c, 0x1060, 0x090c, 0x0d7d, 0xa8ab, 0xdcb0,
-	0x2900, 0x704e, 0x080c, 0x1060, 0x090c, 0x0d7d, 0xa8ab, 0xdcb0,
-	0x2900, 0x7052, 0xa867, 0x0000, 0xa86b, 0x0001, 0xa89f, 0x0000,
-	0x0005, 0x00e6, 0x2071, 0x0040, 0x6848, 0x9005, 0x1118, 0x9085,
-	0x0001, 0x04b0, 0x6840, 0x9005, 0x0150, 0x04a1, 0x6a50, 0x9200,
-	0x7002, 0x6854, 0x9101, 0x7006, 0x9006, 0x7012, 0x7016, 0x6850,
-	0x7002, 0x6854, 0x7006, 0x6858, 0x700a, 0x685c, 0x700e, 0x6840,
-	0x9005, 0x1110, 0x7012, 0x7016, 0x6848, 0x701a, 0x701c, 0x9085,
-	0x0040, 0x701e, 0x2001, 0x0019, 0x7036, 0x702b, 0x0001, 0x2001,
-	0x0004, 0x200c, 0x918c, 0xfff7, 0x918d, 0x8000, 0x2102, 0x00d6,
-	0x2069, 0x18fa, 0x6807, 0x0001, 0x00de, 0x080c, 0x7e38, 0x9006,
-	0x00ee, 0x0005, 0x900e, 0x0156, 0x20a9, 0x0006, 0x8003, 0x818d,
-	0x1f04, 0x78b6, 0x015e, 0x0005, 0x2079, 0x0040, 0x2071, 0x18fa,
-	0x7004, 0x0002, 0x78cc, 0x78cd, 0x7919, 0x7974, 0x7a84, 0x78ca,
-	0x78ca, 0x7aae, 0x080c, 0x0d7d, 0x0005, 0x2079, 0x0040, 0x2001,
-	0x1dc0, 0x2003, 0x0000, 0x782c, 0x908c, 0x0780, 0x190c, 0x7f1a,
-	0xd0a4, 0x0578, 0x2001, 0x1dc0, 0x2004, 0x9082, 0x0080, 0x1648,
-	0x1d04, 0x78ea, 0x2001, 0x1a05, 0x200c, 0x8109, 0x0510, 0x2091,
-	0x6000, 0x2102, 0x7824, 0x2048, 0x9006, 0xa802, 0xa806, 0xa864,
-	0x9084, 0x00ff, 0x908a, 0x0040, 0x0610, 0x00c0, 0x2001, 0x1800,
-	0x200c, 0x9186, 0x0003, 0x1168, 0x7004, 0x0002, 0x7909, 0x78d3,
-	0x7909, 0x7907, 0x7909, 0x7909, 0x7909, 0x7909, 0x7909, 0x080c,
-	0x7974, 0x782c, 0xd09c, 0x090c, 0x7e38, 0x0005, 0x9082, 0x005a,
-	0x1218, 0x2100, 0x003b, 0x0c10, 0x080c, 0x79aa, 0x0c90, 0x00e3,
-	0x08e8, 0x0005, 0x79aa, 0x79aa, 0x79aa, 0x79aa, 0x79aa, 0x79aa,
-	0x79aa, 0x79aa, 0x79cc, 0x79aa, 0x79aa, 0x79aa, 0x79aa, 0x79aa,
-	0x79aa, 0x79aa, 0x79aa, 0x79aa, 0x79aa, 0x79aa, 0x79aa, 0x79aa,
-	0x79aa, 0x79aa, 0x79aa, 0x79aa, 0x79aa, 0x79aa, 0x79b6, 0x79aa,
-	0x7b9f, 0x79aa, 0x79aa, 0x79aa, 0x79cc, 0x79aa, 0x79b6, 0x7be0,
-	0x7c21, 0x7c68, 0x7c7c, 0x79aa, 0x79aa, 0x79cc, 0x79b6, 0x79e0,
-	0x79aa, 0x7a58, 0x7d27, 0x7d42, 0x79aa, 0x79cc, 0x79aa, 0x79e0,
-	0x79aa, 0x79aa, 0x7a4e, 0x7d42, 0x79aa, 0x79aa, 0x79aa, 0x79aa,
-	0x79aa, 0x79aa, 0x79aa, 0x79aa, 0x79aa, 0x79f4, 0x79aa, 0x79aa,
-	0x79aa, 0x79aa, 0x79aa, 0x79aa, 0x79aa, 0x79aa, 0x79aa, 0x7ebe,
-	0x79aa, 0x7e68, 0x79aa, 0x7e68, 0x79aa, 0x7a09, 0x79aa, 0x79aa,
-	0x79aa, 0x79aa, 0x79aa, 0x79aa, 0x2079, 0x0040, 0x7004, 0x9086,
-	0x0003, 0x1198, 0x782c, 0x080c, 0x7e61, 0xd0a4, 0x0170, 0x7824,
-	0x2048, 0x9006, 0xa802, 0xa806, 0xa864, 0x9084, 0x00ff, 0x908a,
-	0x001a, 0x1210, 0x002b, 0x0c50, 0x00e9, 0x080c, 0x7e38, 0x0005,
-	0x79aa, 0x79b6, 0x7b8b, 0x79aa, 0x79b6, 0x79aa, 0x79b6, 0x79b6,
-	0x79aa, 0x79b6, 0x7b8b, 0x79b6, 0x79b6, 0x79b6, 0x79b6, 0x79b6,
-	0x79aa, 0x79b6, 0x7b8b, 0x79aa, 0x79aa, 0x79b6, 0x79aa, 0x79aa,
-	0x79aa, 0x79b6, 0x00e6, 0x2071, 0x18fa, 0x2009, 0x0400, 0x0071,
-	0x00ee, 0x0005, 0x2009, 0x1000, 0x0049, 0x0005, 0x2009, 0x2000,
-	0x0029, 0x0005, 0x2009, 0x0800, 0x0009, 0x0005, 0x7007, 0x0001,
-	0xa868, 0x9084, 0x00ff, 0x9105, 0xa86a, 0x0126, 0x2091, 0x8000,
-	0x080c, 0x6dee, 0x012e, 0x0005, 0xa864, 0x8007, 0x9084, 0x00ff,
-	0x0d08, 0x8001, 0x1120, 0x7007, 0x0001, 0x0804, 0x7b2d, 0x7007,
-	0x0003, 0x7012, 0x2900, 0x7016, 0x701a, 0x704b, 0x7b2d, 0x0005,
-	0xa864, 0x8007, 0x9084, 0x00ff, 0x0968, 0x8001, 0x1120, 0x7007,
-	0x0001, 0x0804, 0x7b48, 0x7007, 0x0003, 0x7012, 0x2900, 0x7016,
-	0x701a, 0x704b, 0x7b48, 0x0005, 0xa864, 0x8007, 0x9084, 0x00ff,
-	0x0904, 0x79b2, 0x8001, 0x1120, 0x7007, 0x0001, 0x0804, 0x7b64,
-	0x7007, 0x0003, 0x7012, 0x2900, 0x7016, 0x701a, 0x704b, 0x7b64,
-	0x0005, 0xa864, 0x8007, 0x9084, 0x00ff, 0x9086, 0x0001, 0x1904,
-	0x79b2, 0x7007, 0x0001, 0x2009, 0x1834, 0x210c, 0x81ff, 0x11a8,
-	0xa868, 0x9084, 0x00ff, 0xa86a, 0xa883, 0x0000, 0x080c, 0x6325,
-	0x1108, 0x0005, 0x0126, 0x2091, 0x8000, 0xa867, 0x0139, 0xa87a,
-	0xa982, 0x080c, 0x6dee, 0x012e, 0x0ca0, 0xa994, 0x9186, 0x0071,
-	0x0d38, 0x9186, 0x0064, 0x0d20, 0x9186, 0x007c, 0x0d08, 0x9186,
-	0x0028, 0x09f0, 0x9186, 0x0038, 0x09d8, 0x9186, 0x0078, 0x09c0,
-	0x9186, 0x005f, 0x09a8, 0x9186, 0x0056, 0x0990, 0xa897, 0x4005,
-	0xa89b, 0x0001, 0x2001, 0x0030, 0x900e, 0x08a0, 0xa87c, 0x9084,
-	0x00c0, 0x9086, 0x00c0, 0x1120, 0x7007, 0x0001, 0x0804, 0x7d59,
-	0x2900, 0x7016, 0x701a, 0x20a9, 0x0004, 0xa860, 0x20e0, 0xa85c,
-	0x9080, 0x0030, 0x2098, 0x7050, 0x2040, 0xa060, 0x20e8, 0xa05c,
-	0x9080, 0x0023, 0x20a0, 0x4003, 0xa888, 0x7012, 0x9082, 0x0401,
-	0x1a04, 0x79ba, 0xaab4, 0x928a, 0x0002, 0x1a04, 0x79ba, 0x82ff,
-	0x1138, 0xa8b8, 0xa9bc, 0x9105, 0x0118, 0x2001, 0x7aeb, 0x0018,
-	0x9280, 0x7ae1, 0x2005, 0x7056, 0x7010, 0x9015, 0x0904, 0x7acc,
-	0x080c, 0x1060, 0x1118, 0x7007, 0x0004, 0x0005, 0x2900, 0x7022,
-	0x7054, 0x2060, 0xe000, 0xa866, 0x7050, 0x2040, 0xa95c, 0xe004,
-	0x9100, 0xa076, 0xa860, 0xa072, 0xe008, 0x920a, 0x1210, 0x900e,
-	0x2200, 0x7112, 0xe20c, 0x8003, 0x800b, 0x9296, 0x0004, 0x0108,
-	0x9108, 0xa17a, 0x810b, 0xa17e, 0x080c, 0x113c, 0xa06c, 0x908e,
-	0x0100, 0x0170, 0x9086, 0x0200, 0x0118, 0x7007, 0x0007, 0x0005,
-	0x7020, 0x2048, 0x080c, 0x1079, 0x7014, 0x2048, 0x0804, 0x79ba,
-	0x7020, 0x2048, 0x7018, 0xa802, 0xa807, 0x0000, 0x2908, 0x2048,
-	0xa906, 0x711a, 0x0804, 0x7a84, 0x7014, 0x2048, 0x7007, 0x0001,
-	0xa8b4, 0x9005, 0x1128, 0xa8b8, 0xa9bc, 0x9105, 0x0108, 0x00b9,
-	0xa864, 0x9084, 0x00ff, 0x9086, 0x001e, 0x0904, 0x7d59, 0x0804,
-	0x7b2d, 0x7ae3, 0x7ae7, 0x0002, 0x001d, 0x0007, 0x0004, 0x000a,
-	0x001b, 0x0005, 0x0006, 0x000a, 0x001d, 0x0005, 0x0004, 0x0076,
-	0x0066, 0xafb8, 0xaebc, 0xa804, 0x2050, 0xb0c0, 0xb0e2, 0xb0bc,
-	0xb0de, 0xb0b8, 0xb0d2, 0xb0b4, 0xb0ce, 0xb6da, 0xb7d6, 0xb0b0,
-	0xb0ca, 0xb0ac, 0xb0c6, 0xb0a8, 0xb0ba, 0xb0a4, 0xb0b6, 0xb6c2,
-	0xb7be, 0xb0a0, 0xb0b2, 0xb09c, 0xb0ae, 0xb098, 0xb0a2, 0xb094,
-	0xb09e, 0xb6aa, 0xb7a6, 0xb090, 0xb09a, 0xb08c, 0xb096, 0xb088,
-	0xb08a, 0xb084, 0xb086, 0xb692, 0xb78e, 0xb080, 0xb082, 0xb07c,
-	0xb07e, 0xb078, 0xb072, 0xb074, 0xb06e, 0xb67a, 0xb776, 0xb004,
-	0x9055, 0x1958, 0x006e, 0x007e, 0x0005, 0x2009, 0x1834, 0x210c,
-	0x81ff, 0x1178, 0x080c, 0x6124, 0x1108, 0x0005, 0x080c, 0x7022,
-	0x0126, 0x2091, 0x8000, 0x080c, 0xcc7f, 0x080c, 0x6dee, 0x012e,
-	0x0ca0, 0x080c, 0xd094, 0x1d70, 0x2001, 0x0028, 0x900e, 0x0c70,
-	0x2009, 0x1834, 0x210c, 0x81ff, 0x1188, 0xa888, 0x9005, 0x0188,
-	0xa883, 0x0000, 0x080c, 0x61b2, 0x1108, 0x0005, 0xa87a, 0x0126,
-	0x2091, 0x8000, 0x080c, 0x6dee, 0x012e, 0x0cb8, 0x2001, 0x0028,
-	0x0ca8, 0x2001, 0x0000, 0x0c90, 0x2009, 0x1834, 0x210c, 0x81ff,
-	0x11d8, 0xa888, 0x9005, 0x01e0, 0xa883, 0x0000, 0xa87c, 0xd0f4,
-	0x0120, 0x080c, 0x6287, 0x1138, 0x0005, 0x9006, 0xa87a, 0x080c,
-	0x61ff, 0x1108, 0x0005, 0x0126, 0x2091, 0x8000, 0xa87a, 0xa982,
-	0x080c, 0x6dee, 0x012e, 0x0cb0, 0x2001, 0x0028, 0x900e, 0x0c98,
-	0x2001, 0x0000, 0x0c80, 0x7018, 0xa802, 0x2908, 0x2048, 0xa906,
-	0x711a, 0x7010, 0x8001, 0x7012, 0x0118, 0x7007, 0x0003, 0x0030,
-	0x7014, 0x2048, 0x7007, 0x0001, 0x7048, 0x080f, 0x0005, 0x00b6,
-	0x7007, 0x0001, 0xa974, 0xa878, 0x9084, 0x00ff, 0x9096, 0x0004,
-	0x0540, 0x20a9, 0x0001, 0x9096, 0x0001, 0x0190, 0x900e, 0x20a9,
-	0x0800, 0x9096, 0x0002, 0x0160, 0x9005, 0x11d8, 0xa974, 0x080c,
-	0x6693, 0x11b8, 0x0066, 0xae80, 0x080c, 0x67a3, 0x006e, 0x0088,
-	0x0046, 0x2011, 0x180c, 0x2224, 0xc484, 0x2412, 0x004e, 0x00c6,
-	0x080c, 0x6693, 0x1110, 0x080c, 0x6976, 0x8108, 0x1f04, 0x7bc8,
-	0x00ce, 0xa87c, 0xd084, 0x1120, 0x080c, 0x1079, 0x00be, 0x0005,
-	0x0126, 0x2091, 0x8000, 0x080c, 0x6dee, 0x012e, 0x00be, 0x0005,
-	0x0126, 0x2091, 0x8000, 0x7007, 0x0001, 0x080c, 0x6ad9, 0x0580,
-	0x2061, 0x1a6e, 0x6100, 0xd184, 0x0178, 0xa888, 0x9084, 0x00ff,
-	0x1550, 0x6000, 0xd084, 0x0520, 0x6004, 0x9005, 0x1538, 0x6003,
-	0x0000, 0x600b, 0x0000, 0x00c8, 0x2011, 0x0001, 0xa890, 0x9005,
-	0x1110, 0x2001, 0x001e, 0x8000, 0x6016, 0xa888, 0x9084, 0x00ff,
-	0x0178, 0x6006, 0xa888, 0x8007, 0x9084, 0x00ff, 0x0148, 0x600a,
-	0xa888, 0x8000, 0x1108, 0xc28d, 0x6202, 0x012e, 0x0804, 0x7e22,
-	0x012e, 0x0804, 0x7e1c, 0x012e, 0x0804, 0x7e16, 0x012e, 0x0804,
-	0x7e19, 0x0126, 0x2091, 0x8000, 0x7007, 0x0001, 0x080c, 0x6ad9,
-	0x05e0, 0x2061, 0x1a6e, 0x6000, 0xd084, 0x05b8, 0x6204, 0x6308,
-	0xd08c, 0x1530, 0xac78, 0x9484, 0x0003, 0x0170, 0xa988, 0x918c,
-	0x00ff, 0x8001, 0x1120, 0x2100, 0x9210, 0x0620, 0x0028, 0x8001,
-	0x1508, 0x2100, 0x9212, 0x02f0, 0x9484, 0x000c, 0x0188, 0xa988,
-	0x810f, 0x918c, 0x00ff, 0x9082, 0x0004, 0x1120, 0x2100, 0x9318,
-	0x0288, 0x0030, 0x9082, 0x0004, 0x1168, 0x2100, 0x931a, 0x0250,
-	0xa890, 0x9005, 0x0110, 0x8000, 0x6016, 0x6206, 0x630a, 0x012e,
-	0x0804, 0x7e22, 0x012e, 0x0804, 0x7e1f, 0x012e, 0x0804, 0x7e1c,
-	0x0126, 0x2091, 0x8000, 0x7007, 0x0001, 0x2061, 0x1a6e, 0x6300,
-	0xd38c, 0x1120, 0x6308, 0x8318, 0x0220, 0x630a, 0x012e, 0x0804,
-	0x7e30, 0x012e, 0x0804, 0x7e1f, 0x00b6, 0x0126, 0x00c6, 0x2091,
-	0x8000, 0x7007, 0x0001, 0xa87c, 0xd0ac, 0x0148, 0x00c6, 0x2061,
-	0x1a6e, 0x6000, 0x9084, 0xfcff, 0x6002, 0x00ce, 0x0440, 0xa888,
-	0x9005, 0x05d8, 0xa88c, 0x9065, 0x0598, 0x2001, 0x1834, 0x2004,
-	0x9005, 0x0118, 0x080c, 0xaceb, 0x0068, 0x6017, 0xf400, 0x6063,
-	0x0000, 0xa97c, 0xd1a4, 0x0110, 0xa980, 0x6162, 0x2009, 0x0041,
-	0x080c, 0xad4d, 0xa988, 0x918c, 0xff00, 0x9186, 0x2000, 0x1138,
-	0x0026, 0x900e, 0x2011, 0xfdff, 0x080c, 0x8979, 0x002e, 0xa87c,
-	0xd0c4, 0x0148, 0x2061, 0x1a6e, 0x6000, 0xd08c, 0x1120, 0x6008,
-	0x8000, 0x0208, 0x600a, 0x00ce, 0x012e, 0x00be, 0x0804, 0x7e22,
-	0x00ce, 0x012e, 0x00be, 0x0804, 0x7e1c, 0xa984, 0x9186, 0x002e,
-	0x0d30, 0x9186, 0x002d, 0x0d18, 0x9186, 0x0045, 0x0510, 0x9186,
-	0x002a, 0x1130, 0x2001, 0x180c, 0x200c, 0xc194, 0x2102, 0x08b8,
-	0x9186, 0x0020, 0x0158, 0x9186, 0x0029, 0x1d10, 0xa974, 0x080c,
-	0x6693, 0x1968, 0xb800, 0xc0e4, 0xb802, 0x0848, 0xa88c, 0x9065,
-	0x09b8, 0x6007, 0x0024, 0x2001, 0x1985, 0x2004, 0x601a, 0x0804,
-	0x7cb7, 0xa88c, 0x9065, 0x0960, 0x00e6, 0xa890, 0x9075, 0x2001,
-	0x1834, 0x2004, 0x9005, 0x0150, 0x080c, 0xaceb, 0x8eff, 0x0118,
-	0x2e60, 0x080c, 0xaceb, 0x00ee, 0x0804, 0x7cb7, 0x6024, 0xc0dc,
-	0xc0d5, 0x6026, 0x2e60, 0x6007, 0x003a, 0xa8a0, 0x9005, 0x0130,
-	0x6007, 0x003b, 0xa8a4, 0x602e, 0xa8a8, 0x6016, 0x6003, 0x0001,
-	0x2009, 0x8020, 0x080c, 0x92b0, 0x00ee, 0x0804, 0x7cb7, 0x2061,
-	0x1a6e, 0x6000, 0xd084, 0x0190, 0xd08c, 0x1904, 0x7e30, 0x0126,
-	0x2091, 0x8000, 0x6204, 0x8210, 0x0220, 0x6206, 0x012e, 0x0804,
-	0x7e30, 0x012e, 0xa883, 0x0016, 0x0804, 0x7e29, 0xa883, 0x0007,
-	0x0804, 0x7e29, 0xa864, 0x8007, 0x9084, 0x00ff, 0x0130, 0x8001,
-	0x1138, 0x7007, 0x0001, 0x0069, 0x0005, 0x080c, 0x79b2, 0x0040,
-	0x7007, 0x0003, 0x7012, 0x2900, 0x7016, 0x701a, 0x704b, 0x7d59,
-	0x0005, 0x00b6, 0x00e6, 0x0126, 0x2091, 0x8000, 0x903e, 0x2061,
-	0x1800, 0x61d0, 0x81ff, 0x1904, 0x7ddb, 0x6130, 0xd194, 0x1904,
-	0x7e05, 0xa878, 0x2070, 0x9e82, 0x1ddc, 0x0a04, 0x7dcf, 0x6068,
-	0x9e02, 0x1a04, 0x7dcf, 0x7120, 0x9186, 0x0006, 0x1904, 0x7dc1,
-	0x7010, 0x905d, 0x0904, 0x7ddb, 0xb800, 0xd0e4, 0x1904, 0x7dff,
-	0x2061, 0x1a6e, 0x6100, 0x9184, 0x0301, 0x9086, 0x0001, 0x15a0,
-	0x7024, 0xd0dc, 0x1904, 0x7e08, 0xa883, 0x0000, 0xa803, 0x0000,
-	0x2908, 0x7014, 0x9005, 0x1198, 0x7116, 0xa87c, 0xd0f4, 0x1904,
-	0x7e0b, 0x080c, 0x573e, 0xd09c, 0x1118, 0xa87c, 0xc0cc, 0xa87e,
-	0x2e60, 0x080c, 0x8869, 0x012e, 0x00ee, 0x00be, 0x0005, 0x2048,
-	0xa800, 0x9005, 0x1de0, 0xa902, 0x2148, 0xa87c, 0xd0f4, 0x1904,
-	0x7e0b, 0x012e, 0x00ee, 0x00be, 0x0005, 0x012e, 0x00ee, 0xa883,
-	0x0006, 0x00be, 0x0804, 0x7e29, 0xd184, 0x0db8, 0xd1c4, 0x1190,
-	0x00a0, 0xa974, 0x080c, 0x6693, 0x15d0, 0xb800, 0xd0e4, 0x15b8,
-	0x7120, 0x9186, 0x0007, 0x1118, 0xa883, 0x0002, 0x0490, 0xa883,
-	0x0008, 0x0478, 0xa883, 0x000e, 0x0460, 0xa883, 0x0017, 0x0448,
-	0xa883, 0x0035, 0x0430, 0x080c, 0x5742, 0xd0fc, 0x01e8, 0xa878,
-	0x2070, 0x9e82, 0x1ddc, 0x02c0, 0x6068, 0x9e02, 0x12a8, 0x7120,
-	0x9186, 0x0006, 0x1188, 0x7010, 0x905d, 0x0170, 0xb800, 0xd0bc,
-	0x0158, 0x2039, 0x0001, 0x7000, 0x9086, 0x0007, 0x1904, 0x7d65,
-	0x7003, 0x0002, 0x0804, 0x7d65, 0xa883, 0x0028, 0x0010, 0xa883,
-	0x0029, 0x012e, 0x00ee, 0x00be, 0x0420, 0xa883, 0x002a, 0x0cc8,
-	0xa883, 0x0045, 0x0cb0, 0x2e60, 0x2019, 0x0002, 0x601b, 0x0014,
-	0x080c, 0xdfa1, 0x012e, 0x00ee, 0x00be, 0x0005, 0x2009, 0x003e,
-	0x0058, 0x2009, 0x0004, 0x0040, 0x2009, 0x0006, 0x0028, 0x2009,
-	0x0016, 0x0010, 0x2009, 0x0001, 0xa884, 0x9084, 0xff00, 0x9105,
-	0xa886, 0x0126, 0x2091, 0x8000, 0x080c, 0x6dee, 0x012e, 0x0005,
-	0x080c, 0x1079, 0x0005, 0x00d6, 0x080c, 0x8860, 0x00de, 0x0005,
-	0x00d6, 0x00e6, 0x0126, 0x2091, 0x8000, 0x2071, 0x0040, 0x702c,
-	0xd084, 0x01d8, 0x908c, 0x0780, 0x190c, 0x7f1a, 0xd09c, 0x11a8,
-	0x2071, 0x1800, 0x70c0, 0x90ea, 0x0020, 0x0278, 0x8001, 0x70c2,
-	0x702c, 0x2048, 0xa800, 0x702e, 0x9006, 0xa802, 0xa806, 0x2071,
-	0x0040, 0x2900, 0x7022, 0x702c, 0x0c28, 0x012e, 0x00ee, 0x00de,
-	0x0005, 0x0006, 0x9084, 0x0780, 0x190c, 0x7f1a, 0x000e, 0x0005,
-	0xa898, 0x9084, 0x0003, 0x05a8, 0x080c, 0xac5a, 0x05d8, 0x2900,
-	0x6016, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0035, 0x1138, 0x6028,
-	0xc0fd, 0x602a, 0x2001, 0x196a, 0x2004, 0x0098, 0xa8a0, 0x9084,
-	0x00ff, 0xa99c, 0x918c, 0xff00, 0x9105, 0xa99c, 0x918c, 0x00ff,
-	0x080c, 0x2661, 0x1540, 0x00b6, 0x080c, 0x6693, 0x2b00, 0x00be,
-	0x1510, 0x6012, 0x6023, 0x0001, 0x2009, 0x0040, 0xa864, 0x9084,
-	0x00ff, 0x9086, 0x0035, 0x0110, 0x2009, 0x0041, 0x080c, 0xad4d,
-	0x0005, 0xa87b, 0x0101, 0x0126, 0x2091, 0x8000, 0x080c, 0x6dee,
-	0x012e, 0x0005, 0xa87b, 0x002c, 0x0126, 0x2091, 0x8000, 0x080c,
-	0x6dee, 0x012e, 0x0005, 0xa87b, 0x0028, 0x0126, 0x2091, 0x8000,
-	0x080c, 0x6dee, 0x012e, 0x080c, 0xacb0, 0x0005, 0x00d6, 0x00c6,
-	0x0036, 0x0026, 0x0016, 0x00b6, 0x7007, 0x0001, 0xaa74, 0x9282,
-	0x0004, 0x1a04, 0x7f0b, 0xa97c, 0x9188, 0x1000, 0x2104, 0x905d,
-	0xb804, 0xd284, 0x0140, 0x05e8, 0x8007, 0x9084, 0x00ff, 0x9084,
-	0x0006, 0x1108, 0x04b0, 0x2b10, 0x080c, 0xac5a, 0x1118, 0x080c,
-	0xad20, 0x05a8, 0x6212, 0xa874, 0x0002, 0x7ee9, 0x7eee, 0x7ef1,
-	0x7ef7, 0x2019, 0x0002, 0x080c, 0xe3b5, 0x0060, 0x080c, 0xe345,
-	0x0048, 0x2019, 0x0002, 0xa980, 0x080c, 0xe364, 0x0018, 0xa980,
-	0x080c, 0xe345, 0x080c, 0xacb0, 0xa887, 0x0000, 0x0126, 0x2091,
-	0x8000, 0x080c, 0x6dee, 0x012e, 0x00be, 0x001e, 0x002e, 0x003e,
-	0x00ce, 0x00de, 0x0005, 0xa887, 0x0006, 0x0c80, 0xa887, 0x0002,
-	0x0c68, 0xa887, 0x0005, 0x0c50, 0xa887, 0x0004, 0x0c38, 0xa887,
-	0x0007, 0x0c20, 0x2091, 0x8000, 0x0e04, 0x7f1c, 0x0006, 0x0016,
-	0x2001, 0x8003, 0x0006, 0x0804, 0x0d86, 0x2001, 0x1834, 0x2004,
-	0x9005, 0x0005, 0x0005, 0x00f6, 0x2079, 0x0300, 0x2001, 0x0200,
-	0x200c, 0xc1e5, 0xc1dc, 0x2102, 0x2009, 0x0218, 0x210c, 0xd1ec,
-	0x1120, 0x080c, 0x162f, 0x00fe, 0x0005, 0x2001, 0x020d, 0x2003,
-	0x0020, 0x781f, 0x0300, 0x00fe, 0x0005, 0x781c, 0xd08c, 0x0904,
-	0x7f9d, 0x68c0, 0x90aa, 0x0005, 0x0a04, 0x85c5, 0x7d44, 0x7c40,
-	0xd59c, 0x190c, 0x0d7d, 0x9584, 0x00f6, 0x1508, 0x9484, 0x7000,
-	0x0138, 0x908a, 0x2000, 0x1258, 0x9584, 0x0700, 0x8007, 0x04f0,
-	0x7000, 0x9084, 0xff00, 0x9086, 0x8100, 0x0db0, 0x00b0, 0x9484,
-	0x0fff, 0x1130, 0x7000, 0x9084, 0xff00, 0x9086, 0x8100, 0x11c0,
-	0x080c, 0xe85a, 0x080c, 0x84ac, 0x7817, 0x0140, 0x00a8, 0x9584,
-	0x0076, 0x1118, 0x080c, 0x8508, 0x19c8, 0xd5a4, 0x0148, 0x0046,
-	0x0056, 0x080c, 0x7fed, 0x080c, 0x216f, 0x005e, 0x004e, 0x0020,
-	0x080c, 0xe85a, 0x7817, 0x0140, 0x080c, 0x753d, 0x0168, 0x2001,
-	0x0111, 0x2004, 0xd08c, 0x0140, 0x6893, 0x0000, 0x2001, 0x0110,
-	0x2003, 0x0008, 0x2003, 0x0000, 0x0489, 0x0005, 0x0002, 0x7faa,
-	0x82ba, 0x7fa7, 0x7fa7, 0x7fa7, 0x7fa7, 0x7fa7, 0x7fa7, 0x7817,
-	0x0140, 0x0005, 0x7000, 0x908c, 0xff00, 0x9194, 0xf000, 0x810f,
-	0x9484, 0x0fff, 0x6892, 0x9286, 0x2000, 0x1150, 0x6800, 0x9086,
-	0x0001, 0x1118, 0x080c, 0x57a4, 0x0070, 0x080c, 0x800d, 0x0058,
-	0x9286, 0x3000, 0x1118, 0x080c, 0x81f4, 0x0028, 0x9286, 0x8000,
-	0x1110, 0x080c, 0x83d9, 0x7817, 0x0140, 0x0005, 0x2001, 0x1810,
-	0x2004, 0xd08c, 0x0178, 0x2001, 0x1800, 0x2004, 0x9086, 0x0003,
-	0x1148, 0x0026, 0x0036, 0x2011, 0x8048, 0x2518, 0x080c, 0x4b52,
-	0x003e, 0x002e, 0x0005, 0x0036, 0x0046, 0x0056, 0x00f6, 0x2079,
-	0x0200, 0x2019, 0xfffe, 0x7c30, 0x0050, 0x0036, 0x0046, 0x0056,
-	0x00f6, 0x2079, 0x0200, 0x7d44, 0x7c40, 0x2019, 0xffff, 0x2001,
-	0x1810, 0x2004, 0xd08c, 0x0160, 0x2001, 0x1800, 0x2004, 0x9086,
-	0x0003, 0x1130, 0x0026, 0x2011, 0x8048, 0x080c, 0x4b52, 0x002e,
-	0x00fe, 0x005e, 0x004e, 0x003e, 0x0005, 0x00b6, 0x00c6, 0x7010,
-	0x9084, 0xff00, 0x8007, 0x9096, 0x0001, 0x0120, 0x9096, 0x0023,
-	0x1904, 0x81c5, 0x9186, 0x0023, 0x15c0, 0x080c, 0x8477, 0x0904,
-	0x81c5, 0x6120, 0x9186, 0x0001, 0x0150, 0x9186, 0x0004, 0x0138,
-	0x9186, 0x0008, 0x0120, 0x9186, 0x000a, 0x1904, 0x81c5, 0x7124,
-	0x610a, 0x7030, 0x908e, 0x0200, 0x1130, 0x2009, 0x0015, 0x080c,
-	0xad4d, 0x0804, 0x81c5, 0x908e, 0x0214, 0x0118, 0x908e, 0x0210,
-	0x1130, 0x2009, 0x0015, 0x080c, 0xad4d, 0x0804, 0x81c5, 0x908e,
-	0x0100, 0x1904, 0x81c5, 0x7034, 0x9005, 0x1904, 0x81c5, 0x2009,
-	0x0016, 0x080c, 0xad4d, 0x0804, 0x81c5, 0x9186, 0x0022, 0x1904,
-	0x81c5, 0x7030, 0x908e, 0x0300, 0x1580, 0x68dc, 0xd0a4, 0x0528,
-	0xc0b5, 0x68de, 0x7100, 0x918c, 0x00ff, 0x697e, 0x7004, 0x6882,
-	0x00f6, 0x2079, 0x0100, 0x79e6, 0x78ea, 0x0006, 0x9084, 0x00ff,
-	0x0016, 0x2008, 0x080c, 0x26aa, 0x7932, 0x7936, 0x001e, 0x000e,
-	0x00fe, 0x080c, 0x2661, 0x695e, 0x703c, 0x00e6, 0x2071, 0x0140,
-	0x7086, 0x2071, 0x1800, 0x70b6, 0x00ee, 0x7034, 0x9005, 0x1904,
-	0x81c5, 0x2009, 0x0017, 0x0804, 0x8175, 0x908e, 0x0400, 0x1190,
-	0x7034, 0x9005, 0x1904, 0x81c5, 0x080c, 0x753d, 0x0120, 0x2009,
-	0x001d, 0x0804, 0x8175, 0x68dc, 0xc0a5, 0x68de, 0x2009, 0x0030,
-	0x0804, 0x8175, 0x908e, 0x0500, 0x1140, 0x7034, 0x9005, 0x1904,
-	0x81c5, 0x2009, 0x0018, 0x0804, 0x8175, 0x908e, 0x2010, 0x1120,
-	0x2009, 0x0019, 0x0804, 0x8175, 0x908e, 0x2110, 0x1120, 0x2009,
-	0x001a, 0x0804, 0x8175, 0x908e, 0x5200, 0x1140, 0x7034, 0x9005,
-	0x1904, 0x81c5, 0x2009, 0x001b, 0x0804, 0x8175, 0x908e, 0x5000,
-	0x1140, 0x7034, 0x9005, 0x1904, 0x81c5, 0x2009, 0x001c, 0x0804,
-	0x8175, 0x908e, 0x1300, 0x1120, 0x2009, 0x0034, 0x0804, 0x8175,
-	0x908e, 0x1200, 0x1140, 0x7034, 0x9005, 0x1904, 0x81c5, 0x2009,
-	0x0024, 0x0804, 0x8175, 0x908c, 0xff00, 0x918e, 0x2400, 0x1170,
-	0x2009, 0x002d, 0x2001, 0x1810, 0x2004, 0xd09c, 0x0904, 0x8175,
-	0x080c, 0xd7c9, 0x1904, 0x81c5, 0x0804, 0x8173, 0x908c, 0xff00,
-	0x918e, 0x5300, 0x1120, 0x2009, 0x002a, 0x0804, 0x8175, 0x908e,
-	0x0f00, 0x1120, 0x2009, 0x0020, 0x0804, 0x8175, 0x908e, 0x6104,
-	0x1530, 0x2029, 0x0205, 0x2011, 0x026d, 0x8208, 0x2204, 0x9082,
-	0x0004, 0x8004, 0x8004, 0x20a8, 0x2011, 0x8015, 0x211c, 0x8108,
-	0x0046, 0x2124, 0x080c, 0x4b52, 0x004e, 0x8108, 0x0f04, 0x8129,
-	0x9186, 0x0280, 0x1d88, 0x2504, 0x8000, 0x202a, 0x2009, 0x0260,
-	0x0c58, 0x202b, 0x0000, 0x2009, 0x0023, 0x0804, 0x8175, 0x908e,
-	0x6000, 0x1120, 0x2009, 0x003f, 0x0804, 0x8175, 0x908e, 0x5400,
-	0x1138, 0x080c, 0x8575, 0x1904, 0x81c5, 0x2009, 0x0046, 0x04a8,
-	0x908e, 0x5500, 0x1148, 0x080c, 0x859d, 0x1118, 0x2009, 0x0041,
-	0x0460, 0x2009, 0x0042, 0x0448, 0x908e, 0x7800, 0x1118, 0x2009,
-	0x0045, 0x0418, 0x908e, 0x1000, 0x1118, 0x2009, 0x004e, 0x00e8,
-	0x908e, 0x6300, 0x1118, 0x2009, 0x004a, 0x00b8, 0x908c, 0xff00,
-	0x918e, 0x5600, 0x1118, 0x2009, 0x004f, 0x0078, 0x908c, 0xff00,
-	0x918e, 0x5700, 0x1118, 0x2009, 0x0050, 0x0038, 0x2009, 0x001d,
-	0x6838, 0xd0d4, 0x0110, 0x2009, 0x004c, 0x0016, 0x2011, 0x0263,
-	0x2204, 0x8211, 0x220c, 0x080c, 0x2661, 0x1904, 0x81c8, 0x080c,
-	0x6632, 0x1904, 0x81c8, 0xbe12, 0xbd16, 0x001e, 0x0016, 0x080c,
-	0x753d, 0x01c0, 0x68dc, 0xd08c, 0x1148, 0x7000, 0x9084, 0x00ff,
-	0x1188, 0x7004, 0x9084, 0xff00, 0x1168, 0x0040, 0x687c, 0x9606,
-	0x1148, 0x6880, 0x9506, 0x9084, 0xff00, 0x1120, 0x9584, 0x00ff,
-	0xb886, 0x0080, 0xb884, 0x9005, 0x1168, 0x9186, 0x0046, 0x1150,
-	0x687c, 0x9606, 0x1138, 0x6880, 0x9506, 0x9084, 0xff00, 0x1110,
-	0x001e, 0x0098, 0x080c, 0xac5a, 0x01a8, 0x2b08, 0x6112, 0x6023,
-	0x0004, 0x7120, 0x610a, 0x001e, 0x9186, 0x004c, 0x1110, 0x6023,
-	0x000a, 0x0016, 0x001e, 0x080c, 0xad4d, 0x00ce, 0x00be, 0x0005,
-	0x001e, 0x0cd8, 0x2001, 0x180e, 0x2004, 0xd0ec, 0x0120, 0x2011,
-	0x8049, 0x080c, 0x4b52, 0x080c, 0xad20, 0x0d90, 0x2b08, 0x6112,
-	0x6023, 0x0004, 0x7120, 0x610a, 0x001e, 0x0016, 0x9186, 0x0017,
-	0x0118, 0x9186, 0x0030, 0x1128, 0x6007, 0x0009, 0x6017, 0x2900,
-	0x0020, 0x6007, 0x0051, 0x6017, 0x0000, 0x602f, 0x0009, 0x6003,
-	0x0001, 0x080c, 0x92b7, 0x08a0, 0x080c, 0x85e4, 0x1158, 0x080c,
-	0x3377, 0x1140, 0x7010, 0x9084, 0xff00, 0x8007, 0x908e, 0x0008,
-	0x1108, 0x0009, 0x0005, 0x00b6, 0x00c6, 0x0046, 0x7000, 0x908c,
-	0xff00, 0x810f, 0x9186, 0x0033, 0x11e8, 0x080c, 0x8477, 0x0904,
-	0x8252, 0x7124, 0x610a, 0x7030, 0x908e, 0x0200, 0x1140, 0x7034,
-	0x9005, 0x15c0, 0x2009, 0x0015, 0x080c, 0xad4d, 0x0498, 0x908e,
-	0x0100, 0x1580, 0x7034, 0x9005, 0x1568, 0x2009, 0x0016, 0x080c,
-	0xad4d, 0x0440, 0x9186, 0x0032, 0x1528, 0x7030, 0x908e, 0x1400,
-	0x1508, 0x2009, 0x0038, 0x0016, 0x2011, 0x0263, 0x2204, 0x8211,
-	0x220c, 0x080c, 0x2661, 0x11a8, 0x080c, 0x6632, 0x1190, 0xbe12,
-	0xbd16, 0x080c, 0xac5a, 0x0168, 0x2b08, 0x6112, 0x080c, 0xce15,
-	0x6023, 0x0004, 0x7120, 0x610a, 0x001e, 0x080c, 0xad4d, 0x0010,
-	0x00ce, 0x001e, 0x004e, 0x00ce, 0x00be, 0x0005, 0x00b6, 0x0046,
-	0x00e6, 0x00d6, 0x2028, 0x2130, 0x9696, 0x00ff, 0x11b8, 0x9592,
-	0xfffc, 0x02a0, 0x9596, 0xfffd, 0x1120, 0x2009, 0x007f, 0x0804,
-	0x82b4, 0x9596, 0xfffe, 0x1120, 0x2009, 0x007e, 0x0804, 0x82b4,
-	0x9596, 0xfffc, 0x1118, 0x2009, 0x0080, 0x04f0, 0x2011, 0x0000,
-	0x2019, 0x1837, 0x231c, 0xd3ac, 0x0130, 0x9026, 0x20a9, 0x0800,
-	0x2071, 0x1000, 0x0030, 0x2021, 0x0081, 0x20a9, 0x077f, 0x2071,
-	0x1081, 0x2e1c, 0x93dd, 0x0000, 0x1140, 0x82ff, 0x11d0, 0x9496,
-	0x00ff, 0x01b8, 0x2410, 0xc2fd, 0x00a0, 0xbf10, 0x2600, 0x9706,
-	0xb814, 0x1120, 0x9546, 0x1110, 0x2408, 0x00b0, 0x9745, 0x1148,
-	0x94c6, 0x007e, 0x0130, 0x94c6, 0x007f, 0x0118, 0x94c6, 0x0080,
-	0x1d20, 0x8420, 0x8e70, 0x1f04, 0x8289, 0x82ff, 0x1118, 0x9085,
-	0x0001, 0x0018, 0xc2fc, 0x2208, 0x9006, 0x00de, 0x00ee, 0x004e,
-	0x00be, 0x0005, 0x2001, 0x1837, 0x200c, 0x9184, 0x0080, 0x0110,
-	0xd18c, 0x0138, 0x7000, 0x908c, 0xff00, 0x810f, 0x9184, 0x000f,
-	0x001a, 0x7817, 0x0140, 0x0005, 0x82dc, 0x82dc, 0x82dc, 0x8489,
-	0x82dc, 0x82df, 0x8304, 0x838d, 0x82dc, 0x82dc, 0x82dc, 0x82dc,
-	0x82dc, 0x82dc, 0x82dc, 0x82dc, 0x7817, 0x0140, 0x0005, 0x00b6,
-	0x7110, 0xd1bc, 0x01e8, 0x7120, 0x2160, 0x9c8c, 0x0003, 0x11c0,
-	0x9c8a, 0x1ddc, 0x02a8, 0x6868, 0x9c02, 0x1290, 0x7008, 0x9084,
-	0x00ff, 0x6110, 0x2158, 0xb910, 0x9106, 0x1150, 0x700c, 0xb914,
-	0x9106, 0x1130, 0x7124, 0x610a, 0x2009, 0x0046, 0x080c, 0xad4d,
-	0x7817, 0x0140, 0x00be, 0x0005, 0x00b6, 0x00c6, 0x9484, 0x0fff,
-	0x0904, 0x8369, 0x7110, 0xd1bc, 0x1904, 0x8369, 0x7108, 0x700c,
-	0x2028, 0x918c, 0x00ff, 0x2130, 0x9094, 0xff00, 0x15c8, 0x81ff,
-	0x15b8, 0x9080, 0x33b9, 0x200d, 0x918c, 0xff00, 0x810f, 0x2001,
-	0x0080, 0x9106, 0x0904, 0x8369, 0x9182, 0x0801, 0x1a04, 0x8369,
-	0x9190, 0x1000, 0x2204, 0x905d, 0x05e0, 0xbe12, 0xbd16, 0xb800,
-	0xd0ec, 0x15b8, 0xba04, 0x9294, 0xff00, 0x9286, 0x0600, 0x1190,
-	0x080c, 0xac5a, 0x0598, 0x2b08, 0x7028, 0x604e, 0x702c, 0x6052,
-	0x6112, 0x6023, 0x0006, 0x7120, 0x610a, 0x7130, 0x615e, 0x080c,
-	0xda32, 0x00f8, 0x080c, 0x6add, 0x1138, 0xb807, 0x0606, 0x0c40,
-	0x190c, 0x8256, 0x11b0, 0x0880, 0x080c, 0xac5a, 0x2b08, 0x0188,
-	0x6112, 0x6023, 0x0004, 0x7120, 0x610a, 0x9286, 0x0400, 0x1118,
-	0x6007, 0x0005, 0x0010, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c,
-	0x92b7, 0x7817, 0x0140, 0x00ce, 0x00be, 0x0005, 0x2001, 0x180e,
-	0x2004, 0xd0ec, 0x0120, 0x2011, 0x8049, 0x080c, 0x4b52, 0x080c,
-	0xad20, 0x0d78, 0x2b08, 0x6112, 0x6023, 0x0006, 0x7120, 0x610a,
-	0x7130, 0x615e, 0x6017, 0xf300, 0x6003, 0x0001, 0x6007, 0x0041,
-	0x2009, 0xa022, 0x080c, 0x92b0, 0x08e0, 0x00b6, 0x7110, 0xd1bc,
-	0x05d0, 0x7020, 0x2060, 0x9c84, 0x0003, 0x15a8, 0x9c82, 0x1ddc,
-	0x0690, 0x6868, 0x9c02, 0x1678, 0x9484, 0x0fff, 0x9082, 0x000c,
-	0x0650, 0x7008, 0x9084, 0x00ff, 0x6110, 0x2158, 0xb910, 0x9106,
-	0x1510, 0x700c, 0xb914, 0x9106, 0x11f0, 0x7124, 0x610a, 0x601c,
-	0xd0fc, 0x11c8, 0x2001, 0x0271, 0x2004, 0x9005, 0x1180, 0x9484,
-	0x0fff, 0x9082, 0x000c, 0x0158, 0x0066, 0x2031, 0x0100, 0xa001,
-	0xa001, 0x8631, 0x1de0, 0x006e, 0x601c, 0xd0fc, 0x1120, 0x2009,
-	0x0045, 0x080c, 0xad4d, 0x7817, 0x0140, 0x00be, 0x0005, 0x6120,
-	0x9186, 0x0002, 0x0128, 0x9186, 0x0005, 0x0110, 0x9085, 0x0001,
-	0x0005, 0x080c, 0x85e4, 0x1180, 0x080c, 0x3377, 0x1168, 0x7010,
-	0x9084, 0xff00, 0x8007, 0x9086, 0x0000, 0x1130, 0x9184, 0x000f,
-	0x908a, 0x0006, 0x1208, 0x000b, 0x0005, 0x83f3, 0x83f4, 0x83f3,
-	0x83f3, 0x8459, 0x8468, 0x0005, 0x00b6, 0x700c, 0x7108, 0x080c,
-	0x2661, 0x1904, 0x8457, 0x080c, 0x6632, 0x1904, 0x8457, 0xbe12,
-	0xbd16, 0x7110, 0xd1bc, 0x0540, 0x702c, 0xd084, 0x1120, 0xb800,
-	0xd0bc, 0x1904, 0x8457, 0x080c, 0x6add, 0x0148, 0x9086, 0x0004,
-	0x0130, 0x080c, 0x6ae5, 0x0118, 0x9086, 0x0004, 0x1588, 0x00c6,
-	0x080c, 0x8477, 0x00ce, 0x05d8, 0x080c, 0xac5a, 0x2b08, 0x05b8,
-	0x6112, 0x080c, 0xce15, 0x6023, 0x0002, 0x7120, 0x610a, 0x2009,
-	0x0088, 0x080c, 0xad4d, 0x0458, 0x080c, 0x6add, 0x0148, 0x9086,
-	0x0004, 0x0130, 0x080c, 0x6ae5, 0x0118, 0x9086, 0x0004, 0x1180,
-	0x080c, 0xac5a, 0x2b08, 0x01d8, 0x6112, 0x080c, 0xce15, 0x6023,
-	0x0005, 0x7120, 0x610a, 0x2009, 0x0088, 0x080c, 0xad4d, 0x0078,
-	0x080c, 0xac5a, 0x2b08, 0x0158, 0x6112, 0x080c, 0xce15, 0x6023,
-	0x0004, 0x7120, 0x610a, 0x2009, 0x0001, 0x080c, 0xad4d, 0x00be,
-	0x0005, 0x7110, 0xd1bc, 0x0158, 0x00d1, 0x0148, 0x080c, 0x83cf,
-	0x1130, 0x7124, 0x610a, 0x2009, 0x0089, 0x080c, 0xad4d, 0x0005,
-	0x7110, 0xd1bc, 0x0158, 0x0059, 0x0148, 0x080c, 0x83cf, 0x1130,
-	0x7124, 0x610a, 0x2009, 0x008a, 0x080c, 0xad4d, 0x0005, 0x7020,
-	0x2060, 0x9c84, 0x0003, 0x1158, 0x9c82, 0x1ddc, 0x0240, 0x2001,
-	0x181a, 0x2004, 0x9c02, 0x1218, 0x9085, 0x0001, 0x0005, 0x9006,
-	0x0ce8, 0x00b6, 0x7110, 0xd1bc, 0x11d8, 0x7024, 0x2060, 0x9c84,
-	0x0003, 0x11b0, 0x9c82, 0x1ddc, 0x0298, 0x6868, 0x9c02, 0x1280,
-	0x7008, 0x9084, 0x00ff, 0x6110, 0x2158, 0xb910, 0x9106, 0x1140,
-	0x700c, 0xb914, 0x9106, 0x1120, 0x2009, 0x0051, 0x080c, 0xad4d,
-	0x7817, 0x0140, 0x00be, 0x0005, 0x2031, 0x0105, 0x0069, 0x0005,
-	0x2031, 0x0206, 0x0049, 0x0005, 0x2031, 0x0207, 0x0029, 0x0005,
-	0x2031, 0x0213, 0x0009, 0x0005, 0x00c6, 0x0096, 0x00f6, 0x7000,
-	0x9084, 0xf000, 0x9086, 0xc000, 0x05c0, 0x080c, 0xac5a, 0x05a8,
-	0x0066, 0x00c6, 0x0046, 0x2011, 0x0263, 0x2204, 0x8211, 0x220c,
-	0x080c, 0x2661, 0x1590, 0x080c, 0x6632, 0x1578, 0xbe12, 0xbd16,
-	0x2b00, 0x004e, 0x00ce, 0x6012, 0x080c, 0xce15, 0x080c, 0x1047,
-	0x0500, 0x2900, 0x6062, 0x9006, 0xa802, 0xa866, 0xac6a, 0xa85c,
-	0x90f8, 0x001b, 0x20a9, 0x000e, 0xa860, 0x20e8, 0x20e1, 0x0000,
-	0x2fa0, 0x2e98, 0x4003, 0x006e, 0x6616, 0x6007, 0x003e, 0x6023,
-	0x0001, 0x6003, 0x0001, 0x080c, 0x92b7, 0x00fe, 0x009e, 0x00ce,
-	0x0005, 0x080c, 0xacb0, 0x006e, 0x0cc0, 0x004e, 0x00ce, 0x0cc8,
-	0x00c6, 0x7000, 0x908c, 0xff00, 0x9184, 0xf000, 0x810f, 0x9086,
-	0x2000, 0x1904, 0x855f, 0x9186, 0x0022, 0x15f0, 0x2001, 0x0111,
-	0x2004, 0x9005, 0x1904, 0x8561, 0x7030, 0x908e, 0x0400, 0x0904,
-	0x8561, 0x908e, 0x6000, 0x05e8, 0x908e, 0x5400, 0x05d0, 0x908e,
-	0x0300, 0x11d8, 0x2009, 0x1837, 0x210c, 0xd18c, 0x1590, 0xd1a4,
-	0x1580, 0x080c, 0x6a9b, 0x0588, 0x68b0, 0x9084, 0x00ff, 0x7100,
-	0x918c, 0x00ff, 0x9106, 0x1518, 0x6880, 0x69b0, 0x918c, 0xff00,
-	0x9105, 0x7104, 0x9106, 0x11d8, 0x00e0, 0x2009, 0x0103, 0x210c,
-	0xd1b4, 0x11a8, 0x908e, 0x5200, 0x09e8, 0x908e, 0x0500, 0x09d0,
-	0x908e, 0x5000, 0x09b8, 0x0058, 0x9186, 0x0023, 0x1140, 0x080c,
-	0x8477, 0x0128, 0x6004, 0x9086, 0x0002, 0x0118, 0x0000, 0x9006,
-	0x0010, 0x9085, 0x0001, 0x00ce, 0x0005, 0x7030, 0x908e, 0x0300,
-	0x0118, 0x908e, 0x5200, 0x1d98, 0x2001, 0x1837, 0x2004, 0x9084,
-	0x0009, 0x9086, 0x0008, 0x0d68, 0x0c50, 0x0156, 0x0046, 0x0016,
-	0x0036, 0x7038, 0x2020, 0x8427, 0x94a4, 0x0007, 0xd484, 0x0148,
-	0x20a9, 0x0004, 0x2019, 0x1805, 0x2011, 0x027a, 0x080c, 0xbc8e,
-	0x1178, 0xd48c, 0x0148, 0x20a9, 0x0004, 0x2019, 0x1801, 0x2011,
-	0x027e, 0x080c, 0xbc8e, 0x1120, 0xd494, 0x0110, 0x9085, 0x0001,
-	0x003e, 0x001e, 0x004e, 0x015e, 0x0005, 0x0156, 0x0046, 0x0016,
-	0x0036, 0x7038, 0x2020, 0x8427, 0x94a4, 0x0007, 0xd484, 0x0148,
-	0x20a9, 0x0004, 0x2019, 0x1805, 0x2011, 0x0272, 0x080c, 0xbc8e,
-	0x1178, 0xd48c, 0x0148, 0x20a9, 0x0004, 0x2019, 0x1801, 0x2011,
-	0x0276, 0x080c, 0xbc8e, 0x1120, 0xd494, 0x0110, 0x9085, 0x0001,
-	0x003e, 0x001e, 0x004e, 0x015e, 0x0005, 0x00f6, 0x2079, 0x0200,
-	0x7800, 0xc0e5, 0xc0cc, 0x7802, 0x00fe, 0x0005, 0x00f6, 0x2079,
-	0x1800, 0x7834, 0xd084, 0x1130, 0x2079, 0x0200, 0x7800, 0x9085,
-	0x1200, 0x7802, 0x00fe, 0x0005, 0x00e6, 0x2071, 0x1800, 0x7034,
-	0xc084, 0x7036, 0x00ee, 0x0005, 0x0016, 0x2001, 0x1837, 0x200c,
-	0x9184, 0x0080, 0x0118, 0xd18c, 0x0118, 0x9006, 0x001e, 0x0005,
-	0x9085, 0x0001, 0x0cd8, 0x2071, 0x1a02, 0x7003, 0x0003, 0x700f,
-	0x0361, 0x9006, 0x701a, 0x7072, 0x7012, 0x7017, 0x1ddc, 0x7007,
-	0x0000, 0x7026, 0x702b, 0x9ef4, 0x7032, 0x7037, 0x9f71, 0x703f,
-	0xffff, 0x7042, 0x7047, 0x55c2, 0x704a, 0x705b, 0x879b, 0x080c,
-	0x1060, 0x090c, 0x0d7d, 0x2900, 0x703a, 0xa867, 0x0003, 0xa86f,
-	0x0100, 0xa8ab, 0xdcb0, 0x0005, 0x2071, 0x1a02, 0x1d04, 0x86b7,
-	0x2091, 0x6000, 0x700c, 0x8001, 0x700e, 0x1590, 0x2001, 0x013c,
-	0x2004, 0x9005, 0x190c, 0x8845, 0x2001, 0x1869, 0x2004, 0xd0c4,
-	0x0158, 0x3a00, 0xd08c, 0x1140, 0x20d1, 0x0000, 0x20d1, 0x0001,
-	0x20d1, 0x0000, 0x080c, 0x0d7d, 0x700f, 0x0361, 0x7007, 0x0001,
-	0x0126, 0x2091, 0x8000, 0x2069, 0x1800, 0x69ec, 0xd1e4, 0x1138,
-	0xd1dc, 0x1118, 0x080c, 0x8809, 0x0010, 0x080c, 0x87e0, 0x7040,
-	0x900d, 0x0148, 0x8109, 0x7142, 0x1130, 0x7044, 0x080f, 0x0018,
-	0x0126, 0x2091, 0x8000, 0x7024, 0x900d, 0x0188, 0x7020, 0x8001,
-	0x7022, 0x1168, 0x7023, 0x0009, 0x8109, 0x7126, 0x9186, 0x03e8,
-	0x1110, 0x7028, 0x080f, 0x81ff, 0x1110, 0x7028, 0x080f, 0x7030,
-	0x900d, 0x0180, 0x702c, 0x8001, 0x702e, 0x1160, 0x702f, 0x0009,
-	0x8109, 0x7132, 0x0128, 0x9184, 0x007f, 0x090c, 0xa00d, 0x0010,
-	0x7034, 0x080f, 0x703c, 0x9005, 0x0118, 0x0310, 0x8001, 0x703e,
-	0x704c, 0x900d, 0x0168, 0x7048, 0x8001, 0x704a, 0x1148, 0x704b,
-	0x0009, 0x8109, 0x714e, 0x1120, 0x7150, 0x714e, 0x7058, 0x080f,
-	0x7018, 0x900d, 0x01d8, 0x0016, 0x7070, 0x900d, 0x0158, 0x706c,
-	0x8001, 0x706e, 0x1138, 0x706f, 0x0009, 0x8109, 0x7172, 0x1110,
-	0x7074, 0x080f, 0x001e, 0x7008, 0x8001, 0x700a, 0x1138, 0x700b,
-	0x0009, 0x8109, 0x711a, 0x1110, 0x701c, 0x080f, 0x012e, 0x7004,
-	0x0002, 0x86df, 0x86e0, 0x870a, 0x00e6, 0x2071, 0x1a02, 0x7018,
-	0x9005, 0x1120, 0x711a, 0x721e, 0x700b, 0x0009, 0x00ee, 0x0005,
-	0x00e6, 0x0006, 0x2071, 0x1a02, 0x701c, 0x9206, 0x1120, 0x701a,
-	0x701e, 0x7072, 0x7076, 0x000e, 0x00ee, 0x0005, 0x00e6, 0x2071,
-	0x1a02, 0xb888, 0x9102, 0x0208, 0xb98a, 0x00ee, 0x0005, 0x0005,
-	0x00b6, 0x2031, 0x0010, 0x7110, 0x080c, 0x6693, 0x11a8, 0xb888,
-	0x8001, 0x0290, 0xb88a, 0x1180, 0x0126, 0x2091, 0x8000, 0x0066,
-	0xb8d0, 0x9005, 0x0138, 0x0026, 0xba3c, 0x0016, 0x080c, 0x67be,
-	0x001e, 0x002e, 0x006e, 0x012e, 0x8108, 0x9182, 0x0800, 0x1220,
-	0x8631, 0x0128, 0x7112, 0x0c00, 0x900e, 0x7007, 0x0002, 0x7112,
-	0x00be, 0x0005, 0x2031, 0x0010, 0x7014, 0x2060, 0x0126, 0x2091,
-	0x8000, 0x6048, 0x9005, 0x0128, 0x8001, 0x604a, 0x1110, 0x080c,
-	0xcc96, 0x6018, 0x9005, 0x0904, 0x8762, 0x00f6, 0x2079, 0x0300,
-	0x7918, 0xd1b4, 0x1904, 0x8775, 0x781b, 0x2020, 0xa001, 0x7918,
-	0xd1b4, 0x0120, 0x781b, 0x2000, 0x0804, 0x8775, 0x8001, 0x601a,
-	0x0106, 0x781b, 0x2000, 0xa001, 0x7918, 0xd1ac, 0x1dd0, 0x010e,
-	0x00fe, 0x1540, 0x6120, 0x9186, 0x0003, 0x0148, 0x9186, 0x0006,
-	0x0130, 0x9186, 0x0009, 0x11e0, 0x611c, 0xd1c4, 0x1100, 0x080c,
-	0xc97a, 0x01b0, 0x6014, 0x2048, 0xa884, 0x908a, 0x199a, 0x0280,
-	0x9082, 0x1999, 0xa886, 0x908a, 0x199a, 0x0210, 0x2001, 0x1999,
-	0x8003, 0x800b, 0x810b, 0x9108, 0x611a, 0x080c, 0xd0c7, 0x0110,
-	0x080c, 0xc65b, 0x012e, 0x9c88, 0x001c, 0x7116, 0x2001, 0x181a,
-	0x2004, 0x9102, 0x1228, 0x8631, 0x0138, 0x2160, 0x0804, 0x870e,
-	0x7017, 0x1ddc, 0x7007, 0x0000, 0x0005, 0x00fe, 0x0c58, 0x00e6,
-	0x2071, 0x1a02, 0x7027, 0x07d0, 0x7023, 0x0009, 0x00ee, 0x0005,
-	0x2001, 0x1a0b, 0x2003, 0x0000, 0x0005, 0x00e6, 0x2071, 0x1a02,
-	0x7132, 0x702f, 0x0009, 0x00ee, 0x0005, 0x2011, 0x1a0e, 0x2013,
-	0x0000, 0x0005, 0x00e6, 0x2071, 0x1a02, 0x711a, 0x721e, 0x700b,
-	0x0009, 0x00ee, 0x0005, 0x0086, 0x0026, 0x7054, 0x8000, 0x7056,
-	0x2001, 0x1a10, 0x2044, 0xa06c, 0x9086, 0x0000, 0x0150, 0x7068,
-	0xa09a, 0x7064, 0xa096, 0x7060, 0xa092, 0x705c, 0xa08e, 0x080c,
-	0x113c, 0x002e, 0x008e, 0x0005, 0x0006, 0x0016, 0x0096, 0x00a6,
-	0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x0156, 0x080c, 0x861c,
-	0x015e, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x00ae, 0x009e,
-	0x001e, 0x000e, 0x0005, 0x00e6, 0x2071, 0x1a02, 0x7172, 0x7276,
-	0x706f, 0x0009, 0x00ee, 0x0005, 0x00e6, 0x0006, 0x2071, 0x1a02,
-	0x7074, 0x9206, 0x1110, 0x7072, 0x7076, 0x000e, 0x00ee, 0x0005,
-	0x2069, 0x1800, 0x69ec, 0xd1e4, 0x1518, 0x0026, 0xd1ec, 0x0140,
-	0x6a54, 0x6874, 0x9202, 0x0288, 0x8117, 0x9294, 0x00c1, 0x0088,
-	0x9184, 0x0007, 0x01a0, 0x8109, 0x9184, 0x0007, 0x0110, 0x69ee,
-	0x0070, 0x8107, 0x9084, 0x0007, 0x910d, 0x8107, 0x9106, 0x9094,
-	0x00c1, 0x9184, 0xff3e, 0x9205, 0x68ee, 0x080c, 0x0f12, 0x002e,
-	0x0005, 0x69e8, 0x9184, 0x003f, 0x05b8, 0x8109, 0x9184, 0x003f,
-	0x01a8, 0x6a54, 0x6874, 0x9202, 0x0220, 0xd1bc, 0x0168, 0xc1bc,
-	0x0018, 0xd1bc, 0x1148, 0xc1bd, 0x2110, 0x00e6, 0x2071, 0x1800,
-	0x080c, 0x0f34, 0x00ee, 0x0400, 0x69ea, 0x00f0, 0x0026, 0x8107,
-	0x9094, 0x0007, 0x0128, 0x8001, 0x8007, 0x9085, 0x0007, 0x0050,
-	0x2010, 0x8004, 0x8004, 0x8004, 0x9084, 0x0007, 0x9205, 0x8007,
-	0x9085, 0x0028, 0x9086, 0x0040, 0x2010, 0x00e6, 0x2071, 0x1800,
-	0x080c, 0x0f34, 0x00ee, 0x002e, 0x0005, 0x0016, 0x00c6, 0x2009,
-	0xfff4, 0x210d, 0x2061, 0x0100, 0x60f0, 0x9100, 0x60f3, 0x0000,
-	0x2009, 0xfff4, 0x200f, 0x1220, 0x8108, 0x2105, 0x8000, 0x200f,
-	0x00ce, 0x001e, 0x0005, 0x00c6, 0x2061, 0x1a6e, 0x00ce, 0x0005,
-	0x9184, 0x000f, 0x8003, 0x8003, 0x8003, 0x9080, 0x1a6e, 0x2060,
-	0x0005, 0xa884, 0x908a, 0x199a, 0x1638, 0x9005, 0x1150, 0x00c6,
-	0x2061, 0x1a6e, 0x6014, 0x00ce, 0x9005, 0x1130, 0x2001, 0x001e,
-	0x0018, 0x908e, 0xffff, 0x01b0, 0x8003, 0x800b, 0x810b, 0x9108,
-	0x611a, 0xa87c, 0x908c, 0x00c0, 0x918e, 0x00c0, 0x0904, 0x8923,
-	0xd0b4, 0x1168, 0xd0bc, 0x1904, 0x88fc, 0x2009, 0x0006, 0x080c,
-	0x8950, 0x0005, 0x900e, 0x0c60, 0x2001, 0x1999, 0x08b0, 0xd0fc,
-	0x05e0, 0x908c, 0x2023, 0x1568, 0x87ff, 0x1558, 0xa9a8, 0x81ff,
-	0x1540, 0x6124, 0x918c, 0x0500, 0x1520, 0x6100, 0x918e, 0x0007,
-	0x1500, 0x2009, 0x1869, 0x210c, 0xd184, 0x11d8, 0x6003, 0x0003,
-	0x6007, 0x0043, 0x6047, 0xb035, 0x080c, 0x1c59, 0xa87c, 0xc0dd,
-	0xa87e, 0x600f, 0x0000, 0x00f6, 0x2079, 0x0380, 0x7818, 0xd0bc,
-	0x1de8, 0x7833, 0x0013, 0x2c00, 0x7836, 0x781b, 0x8080, 0x00fe,
-	0x0005, 0x908c, 0x0003, 0x0120, 0x918e, 0x0003, 0x1904, 0x894a,
-	0x908c, 0x2020, 0x918e, 0x2020, 0x01a8, 0x6024, 0xd0d4, 0x11e8,
-	0x2009, 0x1869, 0x2104, 0xd084, 0x1138, 0x87ff, 0x1120, 0x2009,
-	0x0043, 0x0804, 0xad4d, 0x0005, 0x87ff, 0x1de8, 0x2009, 0x0042,
-	0x0804, 0xad4d, 0x6110, 0x00b6, 0x2158, 0xb900, 0x00be, 0xd1ac,
-	0x0d20, 0x6024, 0xc0cd, 0x6026, 0x0c00, 0xc0d4, 0x6026, 0xa890,
-	0x602e, 0xa88c, 0x6032, 0x08e0, 0xd0fc, 0x0160, 0x908c, 0x0003,
-	0x0120, 0x918e, 0x0003, 0x1904, 0x894a, 0x908c, 0x2020, 0x918e,
-	0x2020, 0x0170, 0x0076, 0x00f6, 0x2c78, 0x080c, 0x1778, 0x00fe,
-	0x007e, 0x87ff, 0x1120, 0x2009, 0x0042, 0x080c, 0xad4d, 0x0005,
-	0x6110, 0x00b6, 0x2158, 0xb900, 0x00be, 0xd1ac, 0x0d58, 0x6124,
-	0xc1cd, 0x6126, 0x0c38, 0xd0fc, 0x0188, 0x908c, 0x2020, 0x918e,
-	0x2020, 0x01a8, 0x9084, 0x0003, 0x908e, 0x0002, 0x0148, 0x87ff,
-	0x1120, 0x2009, 0x0041, 0x080c, 0xad4d, 0x0005, 0x00b9, 0x0ce8,
-	0x87ff, 0x1dd8, 0x2009, 0x0043, 0x080c, 0xad4d, 0x0cb0, 0x6110,
-	0x00b6, 0x2158, 0xb900, 0x00be, 0xd1ac, 0x0d20, 0x6124, 0xc1cd,
-	0x6126, 0x0c00, 0x2009, 0x0004, 0x0019, 0x0005, 0x2009, 0x0001,
-	0x0096, 0x080c, 0xc97a, 0x0518, 0x6014, 0x2048, 0xa982, 0xa800,
-	0x6016, 0x9186, 0x0001, 0x1188, 0xa97c, 0x918c, 0x8100, 0x918e,
-	0x8100, 0x1158, 0x00c6, 0x2061, 0x1a6e, 0x6200, 0xd28c, 0x1120,
-	0x6204, 0x8210, 0x0208, 0x6206, 0x00ce, 0x080c, 0x6c23, 0x6014,
-	0x904d, 0x0076, 0x2039, 0x0000, 0x190c, 0x8869, 0x007e, 0x009e,
-	0x0005, 0x0156, 0x00c6, 0x2061, 0x1a6e, 0x6000, 0x81ff, 0x0110,
-	0x9205, 0x0008, 0x9204, 0x6002, 0x00ce, 0x015e, 0x0005, 0x6800,
-	0xd08c, 0x1138, 0x6808, 0x9005, 0x0120, 0x8001, 0x680a, 0x9085,
-	0x0001, 0x0005, 0x2071, 0x1923, 0x7003, 0x0006, 0x7007, 0x0000,
-	0x700f, 0x0000, 0x7013, 0x0001, 0x080c, 0x1060, 0x090c, 0x0d7d,
-	0xa867, 0x0006, 0xa86b, 0x0001, 0xa8ab, 0xdcb0, 0xa89f, 0x0000,
-	0x2900, 0x702e, 0x7033, 0x0000, 0x0005, 0x0096, 0x00e6, 0x2071,
-	0x1923, 0x702c, 0x2048, 0x6a2c, 0x721e, 0x6b30, 0x7322, 0x6834,
-	0x7026, 0xa896, 0x6838, 0x702a, 0xa89a, 0x6824, 0x7016, 0x683c,
-	0x701a, 0x2009, 0x0028, 0x200a, 0x9005, 0x0148, 0x900e, 0x9188,
-	0x000c, 0x8001, 0x1de0, 0x2100, 0x9210, 0x1208, 0x8318, 0xaa8e,
-	0xab92, 0x7010, 0xd084, 0x0168, 0xc084, 0x7007, 0x0001, 0x700f,
-	0x0000, 0x0006, 0x2009, 0x1b50, 0x2104, 0x9082, 0x0007, 0x200a,
-	0x000e, 0xc095, 0x7012, 0x2008, 0x2001, 0x003b, 0x080c, 0x16a0,
-	0x9006, 0x2071, 0x193c, 0x7002, 0x7006, 0x702a, 0x00ee, 0x009e,
-	0x0005, 0x2009, 0x1b50, 0x2104, 0x9080, 0x0007, 0x200a, 0x0005,
+	0x6886, 0x2001, 0x196e, 0x2004, 0x080c, 0x2716, 0x60e2, 0x9006,
+	0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e, 0x001e, 0x015e, 0x0005,
+	0x0156, 0x0016, 0x0026, 0x0036, 0x00c6, 0x00d6, 0x00e6, 0x2061,
+	0x0100, 0x2071, 0x1800, 0x6020, 0x9084, 0x00c0, 0x01e8, 0x080c,
+	0xaae0, 0x2011, 0x0003, 0x080c, 0xa40f, 0x2011, 0x0002, 0x080c,
+	0xa419, 0x080c, 0xa300, 0x901e, 0x080c, 0xa380, 0x080c, 0xaafc,
+	0x2069, 0x0140, 0x2001, 0x00a0, 0x080c, 0x2abb, 0x080c, 0x79a7,
+	0x080c, 0x617e, 0x0804, 0x7923, 0x2001, 0x180c, 0x200c, 0xd1b4,
+	0x1160, 0xc1b5, 0x2102, 0x080c, 0x7501, 0x2069, 0x0140, 0x2001,
+	0x0080, 0x080c, 0x2abb, 0x60e3, 0x0000, 0x2069, 0x0200, 0x6804,
+	0x9005, 0x1118, 0x6808, 0x9005, 0x0190, 0x6028, 0x9084, 0xfdff,
+	0x602a, 0x2011, 0x0200, 0x080c, 0x2af5, 0x2069, 0x1990, 0x7000,
+	0x206a, 0x709b, 0x0027, 0x7003, 0x0001, 0x0804, 0x7923, 0x2011,
+	0x1e00, 0x080c, 0x2af5, 0x2009, 0x1e00, 0x080c, 0x2aa1, 0x6024,
+	0x910c, 0x01c8, 0x9084, 0x1c00, 0x11b0, 0x1d04, 0x78df, 0x0006,
+	0x0016, 0x00c6, 0x00d6, 0x00e6, 0x080c, 0x8788, 0x00ee, 0x00de,
+	0x00ce, 0x001e, 0x000e, 0x00e6, 0x2071, 0x1a05, 0x7078, 0x00ee,
+	0x9005, 0x19e8, 0x0400, 0x0026, 0x2011, 0x7519, 0x080c, 0x8834,
+	0x2011, 0x750c, 0x080c, 0x8940, 0x002e, 0x2069, 0x0140, 0x60e3,
+	0x0000, 0x70b4, 0x9005, 0x1118, 0x6887, 0x0001, 0x0008, 0x6886,
+	0x2001, 0x196e, 0x2004, 0x080c, 0x2716, 0x60e2, 0x2001, 0x180c,
+	0x200c, 0xc1b4, 0x2102, 0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e,
+	0x001e, 0x015e, 0x0005, 0x0156, 0x0016, 0x0026, 0x0036, 0x0046,
+	0x00c6, 0x00e6, 0x2061, 0x0100, 0x2071, 0x1800, 0x080c, 0xd337,
+	0x1904, 0x7991, 0x7130, 0xd184, 0x1170, 0x080c, 0x347d, 0x0138,
+	0xc18d, 0x7132, 0x2011, 0x1848, 0x2214, 0xd2ac, 0x1120, 0x7030,
+	0xd08c, 0x0904, 0x7991, 0x2011, 0x1848, 0x220c, 0xd1a4, 0x0538,
+	0x0016, 0x2019, 0x000e, 0x080c, 0xe696, 0x0156, 0x00b6, 0x20a9,
+	0x007f, 0x900e, 0x9186, 0x007e, 0x01a0, 0x9186, 0x0080, 0x0188,
+	0x080c, 0x6789, 0x1170, 0x2120, 0x9006, 0x0016, 0x2009, 0x000e,
+	0x080c, 0xe72a, 0x2009, 0x0001, 0x2011, 0x0100, 0x080c, 0x8ae5,
+	0x001e, 0x8108, 0x1f04, 0x795a, 0x00be, 0x015e, 0x001e, 0xd1ac,
+	0x1148, 0x0016, 0x2009, 0x0002, 0x2019, 0x0004, 0x080c, 0x32d5,
+	0x001e, 0x0078, 0x0156, 0x00b6, 0x20a9, 0x007f, 0x900e, 0x080c,
+	0x6789, 0x1110, 0x080c, 0x6198, 0x8108, 0x1f04, 0x7987, 0x00be,
+	0x015e, 0x080c, 0x1b6c, 0x080c, 0xaae0, 0x080c, 0xae67, 0x080c,
+	0xaafc, 0x60e3, 0x0000, 0x080c, 0x617e, 0x080c, 0x75d4, 0x00ee,
+	0x00ce, 0x004e, 0x003e, 0x002e, 0x001e, 0x015e, 0x0005, 0x2001,
+	0x197e, 0x2003, 0x0001, 0x0005, 0x2001, 0x197e, 0x2003, 0x0000,
+	0x0005, 0x2001, 0x197d, 0x2003, 0xaaaa, 0x0005, 0x2001, 0x197d,
+	0x2003, 0x0000, 0x0005, 0x2071, 0x18fa, 0x7003, 0x0000, 0x7007,
+	0x0000, 0x080c, 0x1072, 0x090c, 0x0d85, 0xa8ab, 0xdcb0, 0x2900,
+	0x704e, 0x080c, 0x1072, 0x090c, 0x0d85, 0xa8ab, 0xdcb0, 0x2900,
+	0x7052, 0xa867, 0x0000, 0xa86b, 0x0001, 0xa89f, 0x0000, 0x0005,
+	0x00e6, 0x2071, 0x0040, 0x6848, 0x9005, 0x1118, 0x9085, 0x0001,
+	0x04b0, 0x6840, 0x9005, 0x0150, 0x04a1, 0x6a50, 0x9200, 0x7002,
+	0x6854, 0x9101, 0x7006, 0x9006, 0x7012, 0x7016, 0x6850, 0x7002,
+	0x6854, 0x7006, 0x6858, 0x700a, 0x685c, 0x700e, 0x6840, 0x9005,
+	0x1110, 0x7012, 0x7016, 0x6848, 0x701a, 0x701c, 0x9085, 0x0040,
+	0x701e, 0x2001, 0x0019, 0x7036, 0x702b, 0x0001, 0x2001, 0x0004,
+	0x200c, 0x918c, 0xfff7, 0x918d, 0x8000, 0x2102, 0x00d6, 0x2069,
+	0x18fa, 0x6807, 0x0001, 0x00de, 0x080c, 0x7fa4, 0x9006, 0x00ee,
+	0x0005, 0x900e, 0x0156, 0x20a9, 0x0006, 0x8003, 0x818d, 0x1f04,
+	0x7a1d, 0x015e, 0x0005, 0x2079, 0x0040, 0x2071, 0x18fa, 0x7004,
+	0x0002, 0x7a33, 0x7a34, 0x7a80, 0x7adb, 0x7beb, 0x7a31, 0x7a31,
+	0x7c15, 0x080c, 0x0d85, 0x0005, 0x2079, 0x0040, 0x2001, 0x1dc0,
+	0x2003, 0x0000, 0x782c, 0x908c, 0x0780, 0x190c, 0x8086, 0xd0a4,
+	0x0578, 0x2001, 0x1dc0, 0x2004, 0x9082, 0x0080, 0x1648, 0x1d04,
+	0x7a51, 0x2001, 0x1a08, 0x200c, 0x8109, 0x0510, 0x2091, 0x6000,
+	0x2102, 0x7824, 0x2048, 0x9006, 0xa802, 0xa806, 0xa864, 0x9084,
+	0x00ff, 0x908a, 0x0040, 0x0610, 0x00c0, 0x2001, 0x1800, 0x200c,
+	0x9186, 0x0003, 0x1168, 0x7004, 0x0002, 0x7a70, 0x7a3a, 0x7a70,
+	0x7a6e, 0x7a70, 0x7a70, 0x7a70, 0x7a70, 0x7a70, 0x080c, 0x7adb,
+	0x782c, 0xd09c, 0x090c, 0x7fa4, 0x0005, 0x9082, 0x005a, 0x1218,
+	0x2100, 0x003b, 0x0c10, 0x080c, 0x7b11, 0x0c90, 0x00e3, 0x08e8,
+	0x0005, 0x7b11, 0x7b11, 0x7b11, 0x7b11, 0x7b11, 0x7b11, 0x7b11,
+	0x7b11, 0x7b33, 0x7b11, 0x7b11, 0x7b11, 0x7b11, 0x7b11, 0x7b11,
+	0x7b11, 0x7b11, 0x7b11, 0x7b11, 0x7b11, 0x7b11, 0x7b11, 0x7b11,
+	0x7b11, 0x7b11, 0x7b11, 0x7b11, 0x7b11, 0x7b1d, 0x7b11, 0x7d0b,
+	0x7b11, 0x7b11, 0x7b11, 0x7b33, 0x7b11, 0x7b1d, 0x7d4c, 0x7d8d,
+	0x7dd4, 0x7de8, 0x7b11, 0x7b11, 0x7b33, 0x7b1d, 0x7b47, 0x7b11,
+	0x7bbf, 0x7e93, 0x7eae, 0x7b11, 0x7b33, 0x7b11, 0x7b47, 0x7b11,
+	0x7b11, 0x7bb5, 0x7eae, 0x7b11, 0x7b11, 0x7b11, 0x7b11, 0x7b11,
+	0x7b11, 0x7b11, 0x7b11, 0x7b11, 0x7b5b, 0x7b11, 0x7b11, 0x7b11,
+	0x7b11, 0x7b11, 0x7b11, 0x7b11, 0x7b11, 0x7b11, 0x802a, 0x7b11,
+	0x7fd4, 0x7b11, 0x7fd4, 0x7b11, 0x7b70, 0x7b11, 0x7b11, 0x7b11,
+	0x7b11, 0x7b11, 0x7b11, 0x2079, 0x0040, 0x7004, 0x9086, 0x0003,
+	0x1198, 0x782c, 0x080c, 0x7fcd, 0xd0a4, 0x0170, 0x7824, 0x2048,
+	0x9006, 0xa802, 0xa806, 0xa864, 0x9084, 0x00ff, 0x908a, 0x001a,
+	0x1210, 0x002b, 0x0c50, 0x00e9, 0x080c, 0x7fa4, 0x0005, 0x7b11,
+	0x7b1d, 0x7cf7, 0x7b11, 0x7b1d, 0x7b11, 0x7b1d, 0x7b1d, 0x7b11,
+	0x7b1d, 0x7cf7, 0x7b1d, 0x7b1d, 0x7b1d, 0x7b1d, 0x7b1d, 0x7b11,
+	0x7b1d, 0x7cf7, 0x7b11, 0x7b11, 0x7b1d, 0x7b11, 0x7b11, 0x7b11,
+	0x7b1d, 0x00e6, 0x2071, 0x18fa, 0x2009, 0x0400, 0x0071, 0x00ee,
+	0x0005, 0x2009, 0x1000, 0x0049, 0x0005, 0x2009, 0x2000, 0x0029,
+	0x0005, 0x2009, 0x0800, 0x0009, 0x0005, 0x7007, 0x0001, 0xa868,
+	0x9084, 0x00ff, 0x9105, 0xa86a, 0x0126, 0x2091, 0x8000, 0x080c,
+	0x6f19, 0x012e, 0x0005, 0xa864, 0x8007, 0x9084, 0x00ff, 0x0d08,
+	0x8001, 0x1120, 0x7007, 0x0001, 0x0804, 0x7c94, 0x7007, 0x0003,
+	0x7012, 0x2900, 0x7016, 0x701a, 0x704b, 0x7c94, 0x0005, 0xa864,
+	0x8007, 0x9084, 0x00ff, 0x0968, 0x8001, 0x1120, 0x7007, 0x0001,
+	0x0804, 0x7caf, 0x7007, 0x0003, 0x7012, 0x2900, 0x7016, 0x701a,
+	0x704b, 0x7caf, 0x0005, 0xa864, 0x8007, 0x9084, 0x00ff, 0x0904,
+	0x7b19, 0x8001, 0x1120, 0x7007, 0x0001, 0x0804, 0x7ccb, 0x7007,
+	0x0003, 0x7012, 0x2900, 0x7016, 0x701a, 0x704b, 0x7ccb, 0x0005,
+	0xa864, 0x8007, 0x9084, 0x00ff, 0x9086, 0x0001, 0x1904, 0x7b19,
+	0x7007, 0x0001, 0x2009, 0x1834, 0x210c, 0x81ff, 0x11a8, 0xa868,
+	0x9084, 0x00ff, 0xa86a, 0xa883, 0x0000, 0x080c, 0x6411, 0x1108,
+	0x0005, 0x0126, 0x2091, 0x8000, 0xa867, 0x0139, 0xa87a, 0xa982,
+	0x080c, 0x6f19, 0x012e, 0x0ca0, 0xa994, 0x9186, 0x0071, 0x0d38,
+	0x9186, 0x0064, 0x0d20, 0x9186, 0x007c, 0x0d08, 0x9186, 0x0028,
+	0x09f0, 0x9186, 0x0038, 0x09d8, 0x9186, 0x0078, 0x09c0, 0x9186,
+	0x005f, 0x09a8, 0x9186, 0x0056, 0x0990, 0xa897, 0x4005, 0xa89b,
+	0x0001, 0x2001, 0x0030, 0x900e, 0x08a0, 0xa87c, 0x9084, 0x00c0,
+	0x9086, 0x00c0, 0x1120, 0x7007, 0x0001, 0x0804, 0x7ec5, 0x2900,
+	0x7016, 0x701a, 0x20a9, 0x0004, 0xa860, 0x20e0, 0xa85c, 0x9080,
+	0x0030, 0x2098, 0x7050, 0x2040, 0xa060, 0x20e8, 0xa05c, 0x9080,
+	0x0023, 0x20a0, 0x4003, 0xa888, 0x7012, 0x9082, 0x0401, 0x1a04,
+	0x7b21, 0xaab4, 0x928a, 0x0002, 0x1a04, 0x7b21, 0x82ff, 0x1138,
+	0xa8b8, 0xa9bc, 0x9105, 0x0118, 0x2001, 0x7c52, 0x0018, 0x9280,
+	0x7c48, 0x2005, 0x7056, 0x7010, 0x9015, 0x0904, 0x7c33, 0x080c,
+	0x1072, 0x1118, 0x7007, 0x0004, 0x0005, 0x2900, 0x7022, 0x7054,
+	0x2060, 0xe000, 0xa866, 0x7050, 0x2040, 0xa95c, 0xe004, 0x9100,
+	0xa076, 0xa860, 0xa072, 0xe008, 0x920a, 0x1210, 0x900e, 0x2200,
+	0x7112, 0xe20c, 0x8003, 0x800b, 0x9296, 0x0004, 0x0108, 0x9108,
+	0xa17a, 0x810b, 0xa17e, 0x080c, 0x114e, 0xa06c, 0x908e, 0x0100,
+	0x0170, 0x9086, 0x0200, 0x0118, 0x7007, 0x0007, 0x0005, 0x7020,
+	0x2048, 0x080c, 0x108b, 0x7014, 0x2048, 0x0804, 0x7b21, 0x7020,
+	0x2048, 0x7018, 0xa802, 0xa807, 0x0000, 0x2908, 0x2048, 0xa906,
+	0x711a, 0x0804, 0x7beb, 0x7014, 0x2048, 0x7007, 0x0001, 0xa8b4,
+	0x9005, 0x1128, 0xa8b8, 0xa9bc, 0x9105, 0x0108, 0x00b9, 0xa864,
+	0x9084, 0x00ff, 0x9086, 0x001e, 0x0904, 0x7ec5, 0x0804, 0x7c94,
+	0x7c4a, 0x7c4e, 0x0002, 0x001d, 0x0007, 0x0004, 0x000a, 0x001b,
+	0x0005, 0x0006, 0x000a, 0x001d, 0x0005, 0x0004, 0x0076, 0x0066,
+	0xafb8, 0xaebc, 0xa804, 0x2050, 0xb0c0, 0xb0e2, 0xb0bc, 0xb0de,
+	0xb0b8, 0xb0d2, 0xb0b4, 0xb0ce, 0xb6da, 0xb7d6, 0xb0b0, 0xb0ca,
+	0xb0ac, 0xb0c6, 0xb0a8, 0xb0ba, 0xb0a4, 0xb0b6, 0xb6c2, 0xb7be,
+	0xb0a0, 0xb0b2, 0xb09c, 0xb0ae, 0xb098, 0xb0a2, 0xb094, 0xb09e,
+	0xb6aa, 0xb7a6, 0xb090, 0xb09a, 0xb08c, 0xb096, 0xb088, 0xb08a,
+	0xb084, 0xb086, 0xb692, 0xb78e, 0xb080, 0xb082, 0xb07c, 0xb07e,
+	0xb078, 0xb072, 0xb074, 0xb06e, 0xb67a, 0xb776, 0xb004, 0x9055,
+	0x1958, 0x006e, 0x007e, 0x0005, 0x2009, 0x1834, 0x210c, 0x81ff,
+	0x1178, 0x080c, 0x6210, 0x1108, 0x0005, 0x080c, 0x7165, 0x0126,
+	0x2091, 0x8000, 0x080c, 0xcf1b, 0x080c, 0x6f19, 0x012e, 0x0ca0,
+	0x080c, 0xd337, 0x1d70, 0x2001, 0x0028, 0x900e, 0x0c70, 0x2009,
+	0x1834, 0x210c, 0x81ff, 0x1188, 0xa888, 0x9005, 0x0188, 0xa883,
+	0x0000, 0x080c, 0x629e, 0x1108, 0x0005, 0xa87a, 0x0126, 0x2091,
+	0x8000, 0x080c, 0x6f19, 0x012e, 0x0cb8, 0x2001, 0x0028, 0x0ca8,
+	0x2001, 0x0000, 0x0c90, 0x0419, 0x11d8, 0xa888, 0x9005, 0x01e0,
+	0xa883, 0x0000, 0xa87c, 0xd0f4, 0x0120, 0x080c, 0x6373, 0x1138,
+	0x0005, 0x9006, 0xa87a, 0x080c, 0x62eb, 0x1108, 0x0005, 0x0126,
+	0x2091, 0x8000, 0xa87a, 0xa982, 0x080c, 0x6f19, 0x012e, 0x0cb0,
+	0x2001, 0x0028, 0x900e, 0x0c98, 0x2001, 0x0000, 0x0c80, 0x00c6,
+	0x2061, 0x1800, 0x60d0, 0x9005, 0x0100, 0x00ce, 0x0005, 0x7018,
+	0xa802, 0x2908, 0x2048, 0xa906, 0x711a, 0x7010, 0x8001, 0x7012,
+	0x0118, 0x7007, 0x0003, 0x0030, 0x7014, 0x2048, 0x7007, 0x0001,
+	0x7048, 0x080f, 0x0005, 0x00b6, 0x7007, 0x0001, 0xa974, 0xa878,
+	0x9084, 0x00ff, 0x9096, 0x0004, 0x0540, 0x20a9, 0x0001, 0x9096,
+	0x0001, 0x0190, 0x900e, 0x20a9, 0x0800, 0x9096, 0x0002, 0x0160,
+	0x9005, 0x11d8, 0xa974, 0x080c, 0x6789, 0x11b8, 0x0066, 0xae80,
+	0x080c, 0x6899, 0x006e, 0x0088, 0x0046, 0x2011, 0x180c, 0x2224,
+	0xc484, 0x2412, 0x004e, 0x00c6, 0x080c, 0x6789, 0x1110, 0x080c,
+	0x6a6c, 0x8108, 0x1f04, 0x7d34, 0x00ce, 0xa87c, 0xd084, 0x1120,
+	0x080c, 0x108b, 0x00be, 0x0005, 0x0126, 0x2091, 0x8000, 0x080c,
+	0x6f19, 0x012e, 0x00be, 0x0005, 0x0126, 0x2091, 0x8000, 0x7007,
+	0x0001, 0x080c, 0x6bd1, 0x0580, 0x2061, 0x1a74, 0x6100, 0xd184,
+	0x0178, 0xa888, 0x9084, 0x00ff, 0x1550, 0x6000, 0xd084, 0x0520,
+	0x6004, 0x9005, 0x1538, 0x6003, 0x0000, 0x600b, 0x0000, 0x00c8,
+	0x2011, 0x0001, 0xa890, 0x9005, 0x1110, 0x2001, 0x001e, 0x8000,
+	0x6016, 0xa888, 0x9084, 0x00ff, 0x0178, 0x6006, 0xa888, 0x8007,
+	0x9084, 0x00ff, 0x0148, 0x600a, 0xa888, 0x8000, 0x1108, 0xc28d,
+	0x6202, 0x012e, 0x0804, 0x7f8e, 0x012e, 0x0804, 0x7f88, 0x012e,
+	0x0804, 0x7f82, 0x012e, 0x0804, 0x7f85, 0x0126, 0x2091, 0x8000,
+	0x7007, 0x0001, 0x080c, 0x6bd1, 0x05e0, 0x2061, 0x1a74, 0x6000,
+	0xd084, 0x05b8, 0x6204, 0x6308, 0xd08c, 0x1530, 0xac78, 0x9484,
+	0x0003, 0x0170, 0xa988, 0x918c, 0x00ff, 0x8001, 0x1120, 0x2100,
+	0x9210, 0x0620, 0x0028, 0x8001, 0x1508, 0x2100, 0x9212, 0x02f0,
+	0x9484, 0x000c, 0x0188, 0xa988, 0x810f, 0x918c, 0x00ff, 0x9082,
+	0x0004, 0x1120, 0x2100, 0x9318, 0x0288, 0x0030, 0x9082, 0x0004,
+	0x1168, 0x2100, 0x931a, 0x0250, 0xa890, 0x9005, 0x0110, 0x8000,
+	0x6016, 0x6206, 0x630a, 0x012e, 0x0804, 0x7f8e, 0x012e, 0x0804,
+	0x7f8b, 0x012e, 0x0804, 0x7f88, 0x0126, 0x2091, 0x8000, 0x7007,
+	0x0001, 0x2061, 0x1a74, 0x6300, 0xd38c, 0x1120, 0x6308, 0x8318,
+	0x0220, 0x630a, 0x012e, 0x0804, 0x7f9c, 0x012e, 0x0804, 0x7f8b,
+	0x00b6, 0x0126, 0x00c6, 0x2091, 0x8000, 0x7007, 0x0001, 0xa87c,
+	0xd0ac, 0x0148, 0x00c6, 0x2061, 0x1a74, 0x6000, 0x9084, 0xfcff,
+	0x6002, 0x00ce, 0x0440, 0xa888, 0x9005, 0x05d8, 0xa88c, 0x9065,
+	0x0598, 0x2001, 0x1834, 0x2004, 0x9005, 0x0118, 0x080c, 0xaf69,
+	0x0068, 0x6017, 0xf400, 0x6063, 0x0000, 0xa97c, 0xd1a4, 0x0110,
+	0xa980, 0x6162, 0x2009, 0x0041, 0x080c, 0xafcc, 0xa988, 0x918c,
+	0xff00, 0x9186, 0x2000, 0x1138, 0x0026, 0x900e, 0x2011, 0xfdff,
+	0x080c, 0x8ae5, 0x002e, 0xa87c, 0xd0c4, 0x0148, 0x2061, 0x1a74,
+	0x6000, 0xd08c, 0x1120, 0x6008, 0x8000, 0x0208, 0x600a, 0x00ce,
+	0x012e, 0x00be, 0x0804, 0x7f8e, 0x00ce, 0x012e, 0x00be, 0x0804,
+	0x7f88, 0xa984, 0x9186, 0x002e, 0x0d30, 0x9186, 0x002d, 0x0d18,
+	0x9186, 0x0045, 0x0510, 0x9186, 0x002a, 0x1130, 0x2001, 0x180c,
+	0x200c, 0xc194, 0x2102, 0x08b8, 0x9186, 0x0020, 0x0158, 0x9186,
+	0x0029, 0x1d10, 0xa974, 0x080c, 0x6789, 0x1968, 0xb800, 0xc0e4,
+	0xb802, 0x0848, 0xa88c, 0x9065, 0x09b8, 0x6007, 0x0024, 0x2001,
+	0x1987, 0x2004, 0x601a, 0x0804, 0x7e23, 0xa88c, 0x9065, 0x0960,
+	0x00e6, 0xa890, 0x9075, 0x2001, 0x1834, 0x2004, 0x9005, 0x0150,
+	0x080c, 0xaf69, 0x8eff, 0x0118, 0x2e60, 0x080c, 0xaf69, 0x00ee,
+	0x0804, 0x7e23, 0x6024, 0xc0dc, 0xc0d5, 0x6026, 0x2e60, 0x6007,
+	0x003a, 0xa8a0, 0x9005, 0x0130, 0x6007, 0x003b, 0xa8a4, 0x602e,
+	0xa8a8, 0x6016, 0x6003, 0x0001, 0x2009, 0x8020, 0x080c, 0x9428,
+	0x00ee, 0x0804, 0x7e23, 0x2061, 0x1a74, 0x6000, 0xd084, 0x0190,
+	0xd08c, 0x1904, 0x7f9c, 0x0126, 0x2091, 0x8000, 0x6204, 0x8210,
+	0x0220, 0x6206, 0x012e, 0x0804, 0x7f9c, 0x012e, 0xa883, 0x0016,
+	0x0804, 0x7f95, 0xa883, 0x0007, 0x0804, 0x7f95, 0xa864, 0x8007,
+	0x9084, 0x00ff, 0x0130, 0x8001, 0x1138, 0x7007, 0x0001, 0x0069,
+	0x0005, 0x080c, 0x7b19, 0x0040, 0x7007, 0x0003, 0x7012, 0x2900,
+	0x7016, 0x701a, 0x704b, 0x7ec5, 0x0005, 0x00b6, 0x00e6, 0x0126,
+	0x2091, 0x8000, 0x903e, 0x2061, 0x1800, 0x61d0, 0x81ff, 0x1904,
+	0x7f47, 0x6130, 0xd194, 0x1904, 0x7f71, 0xa878, 0x2070, 0x9e82,
+	0x1ddc, 0x0a04, 0x7f3b, 0x6068, 0x9e02, 0x1a04, 0x7f3b, 0x7120,
+	0x9186, 0x0006, 0x1904, 0x7f2d, 0x7010, 0x905d, 0x0904, 0x7f47,
+	0xb800, 0xd0e4, 0x1904, 0x7f6b, 0x2061, 0x1a74, 0x6100, 0x9184,
+	0x0301, 0x9086, 0x0001, 0x15a0, 0x7024, 0xd0dc, 0x1904, 0x7f74,
+	0xa883, 0x0000, 0xa803, 0x0000, 0x2908, 0x7014, 0x9005, 0x1198,
+	0x7116, 0xa87c, 0xd0f4, 0x1904, 0x7f77, 0x080c, 0x5826, 0xd09c,
+	0x1118, 0xa87c, 0xc0cc, 0xa87e, 0x2e60, 0x080c, 0x89d5, 0x012e,
+	0x00ee, 0x00be, 0x0005, 0x2048, 0xa800, 0x9005, 0x1de0, 0xa902,
+	0x2148, 0xa87c, 0xd0f4, 0x1904, 0x7f77, 0x012e, 0x00ee, 0x00be,
+	0x0005, 0x012e, 0x00ee, 0xa883, 0x0006, 0x00be, 0x0804, 0x7f95,
+	0xd184, 0x0db8, 0xd1c4, 0x1190, 0x00a0, 0xa974, 0x080c, 0x6789,
+	0x15d0, 0xb800, 0xd0e4, 0x15b8, 0x7120, 0x9186, 0x0007, 0x1118,
+	0xa883, 0x0002, 0x0490, 0xa883, 0x0008, 0x0478, 0xa883, 0x000e,
+	0x0460, 0xa883, 0x0017, 0x0448, 0xa883, 0x0035, 0x0430, 0x080c,
+	0x582a, 0xd0fc, 0x01e8, 0xa878, 0x2070, 0x9e82, 0x1ddc, 0x02c0,
+	0x6068, 0x9e02, 0x12a8, 0x7120, 0x9186, 0x0006, 0x1188, 0x7010,
+	0x905d, 0x0170, 0xb800, 0xd0bc, 0x0158, 0x2039, 0x0001, 0x7000,
+	0x9086, 0x0007, 0x1904, 0x7ed1, 0x7003, 0x0002, 0x0804, 0x7ed1,
+	0xa883, 0x0028, 0x0010, 0xa883, 0x0029, 0x012e, 0x00ee, 0x00be,
+	0x0420, 0xa883, 0x002a, 0x0cc8, 0xa883, 0x0045, 0x0cb0, 0x2e60,
+	0x2019, 0x0002, 0x601b, 0x0014, 0x080c, 0xe27a, 0x012e, 0x00ee,
+	0x00be, 0x0005, 0x2009, 0x003e, 0x0058, 0x2009, 0x0004, 0x0040,
+	0x2009, 0x0006, 0x0028, 0x2009, 0x0016, 0x0010, 0x2009, 0x0001,
+	0xa884, 0x9084, 0xff00, 0x9105, 0xa886, 0x0126, 0x2091, 0x8000,
+	0x080c, 0x6f19, 0x012e, 0x0005, 0x080c, 0x108b, 0x0005, 0x00d6,
+	0x080c, 0x89cc, 0x00de, 0x0005, 0x00d6, 0x00e6, 0x0126, 0x2091,
+	0x8000, 0x2071, 0x0040, 0x702c, 0xd084, 0x01d8, 0x908c, 0x0780,
+	0x190c, 0x8086, 0xd09c, 0x11a8, 0x2071, 0x1800, 0x70c0, 0x90ea,
+	0x0020, 0x0278, 0x8001, 0x70c2, 0x702c, 0x2048, 0xa800, 0x702e,
+	0x9006, 0xa802, 0xa806, 0x2071, 0x0040, 0x2900, 0x7022, 0x702c,
+	0x0c28, 0x012e, 0x00ee, 0x00de, 0x0005, 0x0006, 0x9084, 0x0780,
+	0x190c, 0x8086, 0x000e, 0x0005, 0xa898, 0x9084, 0x0003, 0x05a8,
+	0x080c, 0xaed8, 0x05d8, 0x2900, 0x6016, 0xa864, 0x9084, 0x00ff,
+	0x9086, 0x0035, 0x1138, 0x6028, 0xc0fd, 0x602a, 0x2001, 0x196c,
+	0x2004, 0x0098, 0xa8a0, 0x9084, 0x00ff, 0xa99c, 0x918c, 0xff00,
+	0x9105, 0xa99c, 0x918c, 0x00ff, 0x080c, 0x26a2, 0x1540, 0x00b6,
+	0x080c, 0x6789, 0x2b00, 0x00be, 0x1510, 0x6012, 0x6023, 0x0001,
+	0x2009, 0x0040, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0035, 0x0110,
+	0x2009, 0x0041, 0x080c, 0xafcc, 0x0005, 0xa87b, 0x0101, 0x0126,
+	0x2091, 0x8000, 0x080c, 0x6f19, 0x012e, 0x0005, 0xa87b, 0x002c,
+	0x0126, 0x2091, 0x8000, 0x080c, 0x6f19, 0x012e, 0x0005, 0xa87b,
+	0x0028, 0x0126, 0x2091, 0x8000, 0x080c, 0x6f19, 0x012e, 0x080c,
+	0xaf2e, 0x0005, 0x00d6, 0x00c6, 0x0036, 0x0026, 0x0016, 0x00b6,
+	0x7007, 0x0001, 0xaa74, 0x9282, 0x0004, 0x1a04, 0x8077, 0xa97c,
+	0x9188, 0x1000, 0x2104, 0x905d, 0xb804, 0xd284, 0x0140, 0x05e8,
+	0x8007, 0x9084, 0x00ff, 0x9084, 0x0006, 0x1108, 0x04b0, 0x2b10,
+	0x080c, 0xaed8, 0x1118, 0x080c, 0xaf9f, 0x05a8, 0x6212, 0xa874,
+	0x0002, 0x8055, 0x805a, 0x805d, 0x8063, 0x2019, 0x0002, 0x080c,
+	0xe696, 0x0060, 0x080c, 0xe621, 0x0048, 0x2019, 0x0002, 0xa980,
+	0x080c, 0xe640, 0x0018, 0xa980, 0x080c, 0xe621, 0x080c, 0xaf2e,
+	0xa887, 0x0000, 0x0126, 0x2091, 0x8000, 0x080c, 0x6f19, 0x012e,
+	0x00be, 0x001e, 0x002e, 0x003e, 0x00ce, 0x00de, 0x0005, 0xa887,
+	0x0006, 0x0c80, 0xa887, 0x0002, 0x0c68, 0xa887, 0x0005, 0x0c50,
+	0xa887, 0x0004, 0x0c38, 0xa887, 0x0007, 0x0c20, 0x2091, 0x8000,
+	0x0e04, 0x8088, 0x0006, 0x0016, 0x2001, 0x8003, 0x0006, 0x0804,
+	0x0d8e, 0x2001, 0x1834, 0x2004, 0x9005, 0x0005, 0x0005, 0x00f6,
+	0x2079, 0x0300, 0x2001, 0x0200, 0x200c, 0xc1e5, 0xc1dc, 0x2102,
+	0x2009, 0x0218, 0x210c, 0xd1ec, 0x1120, 0x080c, 0x1648, 0x00fe,
+	0x0005, 0x2001, 0x020d, 0x2003, 0x0020, 0x781f, 0x0300, 0x00fe,
+	0x0005, 0x781c, 0xd08c, 0x0904, 0x8109, 0x68c0, 0x90aa, 0x0005,
+	0x0a04, 0x8731, 0x7d44, 0x7c40, 0xd59c, 0x190c, 0x0d85, 0x9584,
+	0x00f6, 0x1508, 0x9484, 0x7000, 0x0138, 0x908a, 0x2000, 0x1258,
+	0x9584, 0x0700, 0x8007, 0x04f0, 0x7000, 0x9084, 0xff00, 0x9086,
+	0x8100, 0x0db0, 0x00b0, 0x9484, 0x0fff, 0x1130, 0x7000, 0x9084,
+	0xff00, 0x9086, 0x8100, 0x11c0, 0x080c, 0xeb55, 0x080c, 0x8618,
+	0x7817, 0x0140, 0x00a8, 0x9584, 0x0076, 0x1118, 0x080c, 0x8674,
+	0x19c8, 0xd5a4, 0x0148, 0x0046, 0x0056, 0x080c, 0x8159, 0x080c,
+	0x21a6, 0x005e, 0x004e, 0x0020, 0x080c, 0xeb55, 0x7817, 0x0140,
+	0x080c, 0x76a5, 0x0168, 0x2001, 0x0111, 0x2004, 0xd08c, 0x0140,
+	0x6893, 0x0000, 0x2001, 0x0110, 0x2003, 0x0008, 0x2003, 0x0000,
+	0x0489, 0x0005, 0x0002, 0x8116, 0x8426, 0x8113, 0x8113, 0x8113,
+	0x8113, 0x8113, 0x8113, 0x7817, 0x0140, 0x0005, 0x7000, 0x908c,
+	0xff00, 0x9194, 0xf000, 0x810f, 0x9484, 0x0fff, 0x6892, 0x9286,
+	0x2000, 0x1150, 0x6800, 0x9086, 0x0001, 0x1118, 0x080c, 0x5890,
+	0x0070, 0x080c, 0x8179, 0x0058, 0x9286, 0x3000, 0x1118, 0x080c,
+	0x8360, 0x0028, 0x9286, 0x8000, 0x1110, 0x080c, 0x8545, 0x7817,
+	0x0140, 0x0005, 0x2001, 0x1810, 0x2004, 0xd08c, 0x0178, 0x2001,
+	0x1800, 0x2004, 0x9086, 0x0003, 0x1148, 0x0026, 0x0036, 0x2011,
+	0x8048, 0x2518, 0x080c, 0x4c2e, 0x003e, 0x002e, 0x0005, 0x0036,
+	0x0046, 0x0056, 0x00f6, 0x2079, 0x0200, 0x2019, 0xfffe, 0x7c30,
+	0x0050, 0x0036, 0x0046, 0x0056, 0x00f6, 0x2079, 0x0200, 0x7d44,
+	0x7c40, 0x2019, 0xffff, 0x2001, 0x1810, 0x2004, 0xd08c, 0x0160,
+	0x2001, 0x1800, 0x2004, 0x9086, 0x0003, 0x1130, 0x0026, 0x2011,
+	0x8048, 0x080c, 0x4c2e, 0x002e, 0x00fe, 0x005e, 0x004e, 0x003e,
+	0x0005, 0x00b6, 0x00c6, 0x7010, 0x9084, 0xff00, 0x8007, 0x9096,
+	0x0001, 0x0120, 0x9096, 0x0023, 0x1904, 0x8331, 0x9186, 0x0023,
+	0x15c0, 0x080c, 0x85e3, 0x0904, 0x8331, 0x6120, 0x9186, 0x0001,
+	0x0150, 0x9186, 0x0004, 0x0138, 0x9186, 0x0008, 0x0120, 0x9186,
+	0x000a, 0x1904, 0x8331, 0x7124, 0x610a, 0x7030, 0x908e, 0x0200,
+	0x1130, 0x2009, 0x0015, 0x080c, 0xafcc, 0x0804, 0x8331, 0x908e,
+	0x0214, 0x0118, 0x908e, 0x0210, 0x1130, 0x2009, 0x0015, 0x080c,
+	0xafcc, 0x0804, 0x8331, 0x908e, 0x0100, 0x1904, 0x8331, 0x7034,
+	0x9005, 0x1904, 0x8331, 0x2009, 0x0016, 0x080c, 0xafcc, 0x0804,
+	0x8331, 0x9186, 0x0022, 0x1904, 0x8331, 0x7030, 0x908e, 0x0300,
+	0x1580, 0x68dc, 0xd0a4, 0x0528, 0xc0b5, 0x68de, 0x7100, 0x918c,
+	0x00ff, 0x697e, 0x7004, 0x6882, 0x00f6, 0x2079, 0x0100, 0x79e6,
+	0x78ea, 0x0006, 0x9084, 0x00ff, 0x0016, 0x2008, 0x080c, 0x26eb,
+	0x7932, 0x7936, 0x001e, 0x000e, 0x00fe, 0x080c, 0x26a2, 0x695e,
+	0x703c, 0x00e6, 0x2071, 0x0140, 0x7086, 0x2071, 0x1800, 0x70b6,
+	0x00ee, 0x7034, 0x9005, 0x1904, 0x8331, 0x2009, 0x0017, 0x0804,
+	0x82e1, 0x908e, 0x0400, 0x1190, 0x7034, 0x9005, 0x1904, 0x8331,
+	0x080c, 0x76a5, 0x0120, 0x2009, 0x001d, 0x0804, 0x82e1, 0x68dc,
+	0xc0a5, 0x68de, 0x2009, 0x0030, 0x0804, 0x82e1, 0x908e, 0x0500,
+	0x1140, 0x7034, 0x9005, 0x1904, 0x8331, 0x2009, 0x0018, 0x0804,
+	0x82e1, 0x908e, 0x2010, 0x1120, 0x2009, 0x0019, 0x0804, 0x82e1,
+	0x908e, 0x2110, 0x1120, 0x2009, 0x001a, 0x0804, 0x82e1, 0x908e,
+	0x5200, 0x1140, 0x7034, 0x9005, 0x1904, 0x8331, 0x2009, 0x001b,
+	0x0804, 0x82e1, 0x908e, 0x5000, 0x1140, 0x7034, 0x9005, 0x1904,
+	0x8331, 0x2009, 0x001c, 0x0804, 0x82e1, 0x908e, 0x1300, 0x1120,
+	0x2009, 0x0034, 0x0804, 0x82e1, 0x908e, 0x1200, 0x1140, 0x7034,
+	0x9005, 0x1904, 0x8331, 0x2009, 0x0024, 0x0804, 0x82e1, 0x908c,
+	0xff00, 0x918e, 0x2400, 0x1170, 0x2009, 0x002d, 0x2001, 0x1810,
+	0x2004, 0xd09c, 0x0904, 0x82e1, 0x080c, 0xda84, 0x1904, 0x8331,
+	0x0804, 0x82df, 0x908c, 0xff00, 0x918e, 0x5300, 0x1120, 0x2009,
+	0x002a, 0x0804, 0x82e1, 0x908e, 0x0f00, 0x1120, 0x2009, 0x0020,
+	0x0804, 0x82e1, 0x908e, 0x6104, 0x1530, 0x2029, 0x0205, 0x2011,
+	0x026d, 0x8208, 0x2204, 0x9082, 0x0004, 0x8004, 0x8004, 0x20a8,
+	0x2011, 0x8015, 0x211c, 0x8108, 0x0046, 0x2124, 0x080c, 0x4c2e,
+	0x004e, 0x8108, 0x0f04, 0x8295, 0x9186, 0x0280, 0x1d88, 0x2504,
+	0x8000, 0x202a, 0x2009, 0x0260, 0x0c58, 0x202b, 0x0000, 0x2009,
+	0x0023, 0x0804, 0x82e1, 0x908e, 0x6000, 0x1120, 0x2009, 0x003f,
+	0x0804, 0x82e1, 0x908e, 0x5400, 0x1138, 0x080c, 0x86e1, 0x1904,
+	0x8331, 0x2009, 0x0046, 0x04a8, 0x908e, 0x5500, 0x1148, 0x080c,
+	0x8709, 0x1118, 0x2009, 0x0041, 0x0460, 0x2009, 0x0042, 0x0448,
+	0x908e, 0x7800, 0x1118, 0x2009, 0x0045, 0x0418, 0x908e, 0x1000,
+	0x1118, 0x2009, 0x004e, 0x00e8, 0x908e, 0x6300, 0x1118, 0x2009,
+	0x004a, 0x00b8, 0x908c, 0xff00, 0x918e, 0x5600, 0x1118, 0x2009,
+	0x004f, 0x0078, 0x908c, 0xff00, 0x918e, 0x5700, 0x1118, 0x2009,
+	0x0050, 0x0038, 0x2009, 0x001d, 0x6838, 0xd0d4, 0x0110, 0x2009,
+	0x004c, 0x0016, 0x2011, 0x0263, 0x2204, 0x8211, 0x220c, 0x080c,
+	0x26a2, 0x1904, 0x8334, 0x080c, 0x671e, 0x1904, 0x8334, 0xbe12,
+	0xbd16, 0x001e, 0x0016, 0x080c, 0x76a5, 0x01c0, 0x68dc, 0xd08c,
+	0x1148, 0x7000, 0x9084, 0x00ff, 0x1188, 0x7004, 0x9084, 0xff00,
+	0x1168, 0x0040, 0x687c, 0x9606, 0x1148, 0x6880, 0x9506, 0x9084,
+	0xff00, 0x1120, 0x9584, 0x00ff, 0xb886, 0x0080, 0xb884, 0x9005,
+	0x1168, 0x9186, 0x0046, 0x1150, 0x687c, 0x9606, 0x1138, 0x6880,
+	0x9506, 0x9084, 0xff00, 0x1110, 0x001e, 0x0098, 0x080c, 0xaed8,
+	0x01a8, 0x2b08, 0x6112, 0x6023, 0x0004, 0x7120, 0x610a, 0x001e,
+	0x9186, 0x004c, 0x1110, 0x6023, 0x000a, 0x0016, 0x001e, 0x080c,
+	0xafcc, 0x00ce, 0x00be, 0x0005, 0x001e, 0x0cd8, 0x2001, 0x180e,
+	0x2004, 0xd0ec, 0x0120, 0x2011, 0x8049, 0x080c, 0x4c2e, 0x080c,
+	0xaf9f, 0x0d90, 0x2b08, 0x6112, 0x6023, 0x0004, 0x7120, 0x610a,
+	0x001e, 0x0016, 0x9186, 0x0017, 0x0118, 0x9186, 0x0030, 0x1128,
+	0x6007, 0x0009, 0x6017, 0x2900, 0x0020, 0x6007, 0x0051, 0x6017,
+	0x0000, 0x602f, 0x0009, 0x6003, 0x0001, 0x080c, 0x942f, 0x08a0,
+	0x080c, 0x8750, 0x1158, 0x080c, 0x3447, 0x1140, 0x7010, 0x9084,
+	0xff00, 0x8007, 0x908e, 0x0008, 0x1108, 0x0009, 0x0005, 0x00b6,
+	0x00c6, 0x0046, 0x7000, 0x908c, 0xff00, 0x810f, 0x9186, 0x0033,
+	0x11e8, 0x080c, 0x85e3, 0x0904, 0x83be, 0x7124, 0x610a, 0x7030,
+	0x908e, 0x0200, 0x1140, 0x7034, 0x9005, 0x15c0, 0x2009, 0x0015,
+	0x080c, 0xafcc, 0x0498, 0x908e, 0x0100, 0x1580, 0x7034, 0x9005,
+	0x1568, 0x2009, 0x0016, 0x080c, 0xafcc, 0x0440, 0x9186, 0x0032,
+	0x1528, 0x7030, 0x908e, 0x1400, 0x1508, 0x2009, 0x0038, 0x0016,
+	0x2011, 0x0263, 0x2204, 0x8211, 0x220c, 0x080c, 0x26a2, 0x11a8,
+	0x080c, 0x671e, 0x1190, 0xbe12, 0xbd16, 0x080c, 0xaed8, 0x0168,
+	0x2b08, 0x6112, 0x080c, 0xd0b1, 0x6023, 0x0004, 0x7120, 0x610a,
+	0x001e, 0x080c, 0xafcc, 0x0010, 0x00ce, 0x001e, 0x004e, 0x00ce,
+	0x00be, 0x0005, 0x00b6, 0x0046, 0x00e6, 0x00d6, 0x2028, 0x2130,
+	0x9696, 0x00ff, 0x11b8, 0x9592, 0xfffc, 0x02a0, 0x9596, 0xfffd,
+	0x1120, 0x2009, 0x007f, 0x0804, 0x8420, 0x9596, 0xfffe, 0x1120,
+	0x2009, 0x007e, 0x0804, 0x8420, 0x9596, 0xfffc, 0x1118, 0x2009,
+	0x0080, 0x04f0, 0x2011, 0x0000, 0x2019, 0x1837, 0x231c, 0xd3ac,
+	0x0130, 0x9026, 0x20a9, 0x0800, 0x2071, 0x1000, 0x0030, 0x2021,
+	0x0081, 0x20a9, 0x077f, 0x2071, 0x1081, 0x2e1c, 0x93dd, 0x0000,
+	0x1140, 0x82ff, 0x11d0, 0x9496, 0x00ff, 0x01b8, 0x2410, 0xc2fd,
+	0x00a0, 0xbf10, 0x2600, 0x9706, 0xb814, 0x1120, 0x9546, 0x1110,
+	0x2408, 0x00b0, 0x9745, 0x1148, 0x94c6, 0x007e, 0x0130, 0x94c6,
+	0x007f, 0x0118, 0x94c6, 0x0080, 0x1d20, 0x8420, 0x8e70, 0x1f04,
+	0x83f5, 0x82ff, 0x1118, 0x9085, 0x0001, 0x0018, 0xc2fc, 0x2208,
+	0x9006, 0x00de, 0x00ee, 0x004e, 0x00be, 0x0005, 0x2001, 0x1837,
+	0x200c, 0x9184, 0x0080, 0x0110, 0xd18c, 0x0138, 0x7000, 0x908c,
+	0xff00, 0x810f, 0x9184, 0x000f, 0x001a, 0x7817, 0x0140, 0x0005,
+	0x8448, 0x8448, 0x8448, 0x85f5, 0x8448, 0x844b, 0x8470, 0x84f9,
+	0x8448, 0x8448, 0x8448, 0x8448, 0x8448, 0x8448, 0x8448, 0x8448,
+	0x7817, 0x0140, 0x0005, 0x00b6, 0x7110, 0xd1bc, 0x01e8, 0x7120,
+	0x2160, 0x9c8c, 0x0003, 0x11c0, 0x9c8a, 0x1ddc, 0x02a8, 0x6868,
+	0x9c02, 0x1290, 0x7008, 0x9084, 0x00ff, 0x6110, 0x2158, 0xb910,
+	0x9106, 0x1150, 0x700c, 0xb914, 0x9106, 0x1130, 0x7124, 0x610a,
+	0x2009, 0x0046, 0x080c, 0xafcc, 0x7817, 0x0140, 0x00be, 0x0005,
+	0x00b6, 0x00c6, 0x9484, 0x0fff, 0x0904, 0x84d5, 0x7110, 0xd1bc,
+	0x1904, 0x84d5, 0x7108, 0x700c, 0x2028, 0x918c, 0x00ff, 0x2130,
+	0x9094, 0xff00, 0x15c8, 0x81ff, 0x15b8, 0x9080, 0x3489, 0x200d,
+	0x918c, 0xff00, 0x810f, 0x2001, 0x0080, 0x9106, 0x0904, 0x84d5,
+	0x9182, 0x0801, 0x1a04, 0x84d5, 0x9190, 0x1000, 0x2204, 0x905d,
+	0x05e0, 0xbe12, 0xbd16, 0xb800, 0xd0ec, 0x15b8, 0xba04, 0x9294,
+	0xff00, 0x9286, 0x0600, 0x1190, 0x080c, 0xaed8, 0x0598, 0x2b08,
+	0x7028, 0x604e, 0x702c, 0x6052, 0x6112, 0x6023, 0x0006, 0x7120,
+	0x610a, 0x7130, 0x615e, 0x080c, 0xdd0b, 0x00f8, 0x080c, 0x6bd5,
+	0x1138, 0xb807, 0x0606, 0x0c40, 0x190c, 0x83c2, 0x11b0, 0x0880,
+	0x080c, 0xaed8, 0x2b08, 0x0188, 0x6112, 0x6023, 0x0004, 0x7120,
+	0x610a, 0x9286, 0x0400, 0x1118, 0x6007, 0x0005, 0x0010, 0x6007,
+	0x0001, 0x6003, 0x0001, 0x080c, 0x942f, 0x7817, 0x0140, 0x00ce,
+	0x00be, 0x0005, 0x2001, 0x180e, 0x2004, 0xd0ec, 0x0120, 0x2011,
+	0x8049, 0x080c, 0x4c2e, 0x080c, 0xaf9f, 0x0d78, 0x2b08, 0x6112,
+	0x6023, 0x0006, 0x7120, 0x610a, 0x7130, 0x615e, 0x6017, 0xf300,
+	0x6003, 0x0001, 0x6007, 0x0041, 0x2009, 0xa022, 0x080c, 0x9428,
+	0x08e0, 0x00b6, 0x7110, 0xd1bc, 0x05d0, 0x7020, 0x2060, 0x9c84,
+	0x0003, 0x15a8, 0x9c82, 0x1ddc, 0x0690, 0x6868, 0x9c02, 0x1678,
+	0x9484, 0x0fff, 0x9082, 0x000c, 0x0650, 0x7008, 0x9084, 0x00ff,
+	0x6110, 0x2158, 0xb910, 0x9106, 0x1510, 0x700c, 0xb914, 0x9106,
+	0x11f0, 0x7124, 0x610a, 0x601c, 0xd0fc, 0x11c8, 0x2001, 0x0271,
+	0x2004, 0x9005, 0x1180, 0x9484, 0x0fff, 0x9082, 0x000c, 0x0158,
+	0x0066, 0x2031, 0x0100, 0xa001, 0xa001, 0x8631, 0x1de0, 0x006e,
+	0x601c, 0xd0fc, 0x1120, 0x2009, 0x0045, 0x080c, 0xafcc, 0x7817,
+	0x0140, 0x00be, 0x0005, 0x6120, 0x9186, 0x0002, 0x0128, 0x9186,
+	0x0005, 0x0110, 0x9085, 0x0001, 0x0005, 0x080c, 0x8750, 0x1180,
+	0x080c, 0x3447, 0x1168, 0x7010, 0x9084, 0xff00, 0x8007, 0x9086,
+	0x0000, 0x1130, 0x9184, 0x000f, 0x908a, 0x0006, 0x1208, 0x000b,
+	0x0005, 0x855f, 0x8560, 0x855f, 0x855f, 0x85c5, 0x85d4, 0x0005,
+	0x00b6, 0x700c, 0x7108, 0x080c, 0x26a2, 0x1904, 0x85c3, 0x080c,
+	0x671e, 0x1904, 0x85c3, 0xbe12, 0xbd16, 0x7110, 0xd1bc, 0x0540,
+	0x702c, 0xd084, 0x1120, 0xb800, 0xd0bc, 0x1904, 0x85c3, 0x080c,
+	0x6bd5, 0x0148, 0x9086, 0x0004, 0x0130, 0x080c, 0x6bdd, 0x0118,
+	0x9086, 0x0004, 0x1588, 0x00c6, 0x080c, 0x85e3, 0x00ce, 0x05d8,
+	0x080c, 0xaed8, 0x2b08, 0x05b8, 0x6112, 0x080c, 0xd0b1, 0x6023,
+	0x0002, 0x7120, 0x610a, 0x2009, 0x0088, 0x080c, 0xafcc, 0x0458,
+	0x080c, 0x6bd5, 0x0148, 0x9086, 0x0004, 0x0130, 0x080c, 0x6bdd,
+	0x0118, 0x9086, 0x0004, 0x1180, 0x080c, 0xaed8, 0x2b08, 0x01d8,
+	0x6112, 0x080c, 0xd0b1, 0x6023, 0x0005, 0x7120, 0x610a, 0x2009,
+	0x0088, 0x080c, 0xafcc, 0x0078, 0x080c, 0xaed8, 0x2b08, 0x0158,
+	0x6112, 0x080c, 0xd0b1, 0x6023, 0x0004, 0x7120, 0x610a, 0x2009,
+	0x0001, 0x080c, 0xafcc, 0x00be, 0x0005, 0x7110, 0xd1bc, 0x0158,
+	0x00d1, 0x0148, 0x080c, 0x853b, 0x1130, 0x7124, 0x610a, 0x2009,
+	0x0089, 0x080c, 0xafcc, 0x0005, 0x7110, 0xd1bc, 0x0158, 0x0059,
+	0x0148, 0x080c, 0x853b, 0x1130, 0x7124, 0x610a, 0x2009, 0x008a,
+	0x080c, 0xafcc, 0x0005, 0x7020, 0x2060, 0x9c84, 0x0003, 0x1158,
+	0x9c82, 0x1ddc, 0x0240, 0x2001, 0x181a, 0x2004, 0x9c02, 0x1218,
+	0x9085, 0x0001, 0x0005, 0x9006, 0x0ce8, 0x00b6, 0x7110, 0xd1bc,
+	0x11d8, 0x7024, 0x2060, 0x9c84, 0x0003, 0x11b0, 0x9c82, 0x1ddc,
+	0x0298, 0x6868, 0x9c02, 0x1280, 0x7008, 0x9084, 0x00ff, 0x6110,
+	0x2158, 0xb910, 0x9106, 0x1140, 0x700c, 0xb914, 0x9106, 0x1120,
+	0x2009, 0x0051, 0x080c, 0xafcc, 0x7817, 0x0140, 0x00be, 0x0005,
+	0x2031, 0x0105, 0x0069, 0x0005, 0x2031, 0x0206, 0x0049, 0x0005,
+	0x2031, 0x0207, 0x0029, 0x0005, 0x2031, 0x0213, 0x0009, 0x0005,
+	0x00c6, 0x0096, 0x00f6, 0x7000, 0x9084, 0xf000, 0x9086, 0xc000,
+	0x05c0, 0x080c, 0xaed8, 0x05a8, 0x0066, 0x00c6, 0x0046, 0x2011,
+	0x0263, 0x2204, 0x8211, 0x220c, 0x080c, 0x26a2, 0x1590, 0x080c,
+	0x671e, 0x1578, 0xbe12, 0xbd16, 0x2b00, 0x004e, 0x00ce, 0x6012,
+	0x080c, 0xd0b1, 0x080c, 0x1059, 0x0500, 0x2900, 0x6062, 0x9006,
+	0xa802, 0xa866, 0xac6a, 0xa85c, 0x90f8, 0x001b, 0x20a9, 0x000e,
+	0xa860, 0x20e8, 0x20e1, 0x0000, 0x2fa0, 0x2e98, 0x4003, 0x006e,
+	0x6616, 0x6007, 0x003e, 0x6023, 0x0001, 0x6003, 0x0001, 0x080c,
+	0x942f, 0x00fe, 0x009e, 0x00ce, 0x0005, 0x080c, 0xaf2e, 0x006e,
+	0x0cc0, 0x004e, 0x00ce, 0x0cc8, 0x00c6, 0x7000, 0x908c, 0xff00,
+	0x9184, 0xf000, 0x810f, 0x9086, 0x2000, 0x1904, 0x86cb, 0x9186,
+	0x0022, 0x15f0, 0x2001, 0x0111, 0x2004, 0x9005, 0x1904, 0x86cd,
+	0x7030, 0x908e, 0x0400, 0x0904, 0x86cd, 0x908e, 0x6000, 0x05e8,
+	0x908e, 0x5400, 0x05d0, 0x908e, 0x0300, 0x11d8, 0x2009, 0x1837,
+	0x210c, 0xd18c, 0x1590, 0xd1a4, 0x1580, 0x080c, 0x6b93, 0x0588,
+	0x68b0, 0x9084, 0x00ff, 0x7100, 0x918c, 0x00ff, 0x9106, 0x1518,
+	0x6880, 0x69b0, 0x918c, 0xff00, 0x9105, 0x7104, 0x9106, 0x11d8,
+	0x00e0, 0x2009, 0x0103, 0x210c, 0xd1b4, 0x11a8, 0x908e, 0x5200,
+	0x09e8, 0x908e, 0x0500, 0x09d0, 0x908e, 0x5000, 0x09b8, 0x0058,
+	0x9186, 0x0023, 0x1140, 0x080c, 0x85e3, 0x0128, 0x6004, 0x9086,
+	0x0002, 0x0118, 0x0000, 0x9006, 0x0010, 0x9085, 0x0001, 0x00ce,
+	0x0005, 0x7030, 0x908e, 0x0300, 0x0118, 0x908e, 0x5200, 0x1d98,
+	0x2001, 0x1837, 0x2004, 0x9084, 0x0009, 0x9086, 0x0008, 0x0d68,
+	0x0c50, 0x0156, 0x0046, 0x0016, 0x0036, 0x7038, 0x2020, 0x8427,
+	0x94a4, 0x0007, 0xd484, 0x0148, 0x20a9, 0x0004, 0x2019, 0x1805,
+	0x2011, 0x027a, 0x080c, 0xbf2a, 0x1178, 0xd48c, 0x0148, 0x20a9,
+	0x0004, 0x2019, 0x1801, 0x2011, 0x027e, 0x080c, 0xbf2a, 0x1120,
+	0xd494, 0x0110, 0x9085, 0x0001, 0x003e, 0x001e, 0x004e, 0x015e,
+	0x0005, 0x0156, 0x0046, 0x0016, 0x0036, 0x7038, 0x2020, 0x8427,
+	0x94a4, 0x0007, 0xd484, 0x0148, 0x20a9, 0x0004, 0x2019, 0x1805,
+	0x2011, 0x0272, 0x080c, 0xbf2a, 0x1178, 0xd48c, 0x0148, 0x20a9,
+	0x0004, 0x2019, 0x1801, 0x2011, 0x0276, 0x080c, 0xbf2a, 0x1120,
+	0xd494, 0x0110, 0x9085, 0x0001, 0x003e, 0x001e, 0x004e, 0x015e,
+	0x0005, 0x00f6, 0x2079, 0x0200, 0x7800, 0xc0e5, 0xc0cc, 0x7802,
+	0x00fe, 0x0005, 0x00f6, 0x2079, 0x1800, 0x7834, 0xd084, 0x1130,
+	0x2079, 0x0200, 0x7800, 0x9085, 0x1200, 0x7802, 0x00fe, 0x0005,
+	0x00e6, 0x2071, 0x1800, 0x7034, 0xc084, 0x7036, 0x00ee, 0x0005,
+	0x0016, 0x2001, 0x1837, 0x200c, 0x9184, 0x0080, 0x0118, 0xd18c,
+	0x0118, 0x9006, 0x001e, 0x0005, 0x9085, 0x0001, 0x0cd8, 0x2071,
+	0x1a05, 0x7003, 0x0003, 0x700f, 0x0361, 0x9006, 0x701a, 0x707a,
+	0x7012, 0x7017, 0x1ddc, 0x7007, 0x0000, 0x7026, 0x702b, 0xa0aa,
+	0x7032, 0x7037, 0xa127, 0x7047, 0xffff, 0x704a, 0x704f, 0x56aa,
+	0x7052, 0x7063, 0x8907, 0x080c, 0x1072, 0x090c, 0x0d85, 0x2900,
+	0x7042, 0xa867, 0x0003, 0xa86f, 0x0100, 0xa8ab, 0xdcb0, 0x0005,
+	0x2071, 0x1a05, 0x1d04, 0x8823, 0x2091, 0x6000, 0x700c, 0x8001,
+	0x700e, 0x1590, 0x2001, 0x013c, 0x2004, 0x9005, 0x190c, 0x89b1,
+	0x2001, 0x1869, 0x2004, 0xd0c4, 0x0158, 0x3a00, 0xd08c, 0x1140,
+	0x20d1, 0x0000, 0x20d1, 0x0001, 0x20d1, 0x0000, 0x080c, 0x0d85,
+	0x700f, 0x0361, 0x7007, 0x0001, 0x0126, 0x2091, 0x8000, 0x2069,
+	0x1800, 0x69ec, 0xd1e4, 0x1138, 0xd1dc, 0x1118, 0x080c, 0x8975,
+	0x0010, 0x080c, 0x894c, 0x7048, 0x900d, 0x0148, 0x8109, 0x714a,
+	0x1130, 0x704c, 0x080f, 0x0018, 0x0126, 0x2091, 0x8000, 0x7024,
+	0x900d, 0x0188, 0x7020, 0x8001, 0x7022, 0x1168, 0x7023, 0x0009,
+	0x8109, 0x7126, 0x9186, 0x03e8, 0x1110, 0x7028, 0x080f, 0x81ff,
+	0x1110, 0x7028, 0x080f, 0x7030, 0x900d, 0x0180, 0x702c, 0x8001,
+	0x702e, 0x1160, 0x702f, 0x0009, 0x8109, 0x7132, 0x0128, 0x9184,
+	0x007f, 0x090c, 0xa1d5, 0x0010, 0x7034, 0x080f, 0x7044, 0x9005,
+	0x0118, 0x0310, 0x8001, 0x7046, 0x7054, 0x900d, 0x0168, 0x7050,
+	0x8001, 0x7052, 0x1148, 0x7053, 0x0009, 0x8109, 0x7156, 0x1120,
+	0x7158, 0x7156, 0x7060, 0x080f, 0x7018, 0x900d, 0x01d8, 0x0016,
+	0x7078, 0x900d, 0x0158, 0x7074, 0x8001, 0x7076, 0x1138, 0x7077,
+	0x0009, 0x8109, 0x717a, 0x1110, 0x707c, 0x080f, 0x001e, 0x7008,
+	0x8001, 0x700a, 0x1138, 0x700b, 0x0009, 0x8109, 0x711a, 0x1110,
+	0x701c, 0x080f, 0x012e, 0x7004, 0x0002, 0x884b, 0x884c, 0x8876,
+	0x00e6, 0x2071, 0x1a05, 0x7018, 0x9005, 0x1120, 0x711a, 0x721e,
+	0x700b, 0x0009, 0x00ee, 0x0005, 0x00e6, 0x0006, 0x2071, 0x1a05,
+	0x701c, 0x9206, 0x1120, 0x701a, 0x701e, 0x707a, 0x707e, 0x000e,
+	0x00ee, 0x0005, 0x00e6, 0x2071, 0x1a05, 0xb888, 0x9102, 0x0208,
+	0xb98a, 0x00ee, 0x0005, 0x0005, 0x00b6, 0x2031, 0x0010, 0x7110,
+	0x080c, 0x6789, 0x11a8, 0xb888, 0x8001, 0x0290, 0xb88a, 0x1180,
+	0x0126, 0x2091, 0x8000, 0x0066, 0xb8d0, 0x9005, 0x0138, 0x0026,
+	0xba3c, 0x0016, 0x080c, 0x68b4, 0x001e, 0x002e, 0x006e, 0x012e,
+	0x8108, 0x9182, 0x0800, 0x1220, 0x8631, 0x0128, 0x7112, 0x0c00,
+	0x900e, 0x7007, 0x0002, 0x7112, 0x00be, 0x0005, 0x2031, 0x0010,
+	0x7014, 0x2060, 0x0126, 0x2091, 0x8000, 0x6048, 0x9005, 0x0128,
+	0x8001, 0x604a, 0x1110, 0x080c, 0xcf32, 0x6018, 0x9005, 0x0904,
+	0x88ce, 0x00f6, 0x2079, 0x0300, 0x7918, 0xd1b4, 0x1904, 0x88e1,
+	0x781b, 0x2020, 0xa001, 0x7918, 0xd1b4, 0x0120, 0x781b, 0x2000,
+	0x0804, 0x88e1, 0x8001, 0x601a, 0x0106, 0x781b, 0x2000, 0xa001,
+	0x7918, 0xd1ac, 0x1dd0, 0x010e, 0x00fe, 0x1540, 0x6120, 0x9186,
+	0x0003, 0x0148, 0x9186, 0x0006, 0x0130, 0x9186, 0x0009, 0x11e0,
+	0x611c, 0xd1c4, 0x1100, 0x080c, 0xcc16, 0x01b0, 0x6014, 0x2048,
+	0xa884, 0x908a, 0x199a, 0x0280, 0x9082, 0x1999, 0xa886, 0x908a,
+	0x199a, 0x0210, 0x2001, 0x1999, 0x8003, 0x800b, 0x810b, 0x9108,
+	0x611a, 0x080c, 0xd36a, 0x0110, 0x080c, 0xc8f7, 0x012e, 0x9c88,
+	0x001c, 0x7116, 0x2001, 0x181a, 0x2004, 0x9102, 0x1228, 0x8631,
+	0x0138, 0x2160, 0x0804, 0x887a, 0x7017, 0x1ddc, 0x7007, 0x0000,
+	0x0005, 0x00fe, 0x0c58, 0x00e6, 0x2071, 0x1a05, 0x7027, 0x07d0,
+	0x7023, 0x0009, 0x00ee, 0x0005, 0x2001, 0x1a0e, 0x2003, 0x0000,
+	0x0005, 0x00e6, 0x2071, 0x1a05, 0x7132, 0x702f, 0x0009, 0x00ee,
+	0x0005, 0x2011, 0x1a11, 0x2013, 0x0000, 0x0005, 0x00e6, 0x2071,
+	0x1a05, 0x711a, 0x721e, 0x700b, 0x0009, 0x00ee, 0x0005, 0x0086,
+	0x0026, 0x705c, 0x8000, 0x705e, 0x2001, 0x1a15, 0x2044, 0xa06c,
+	0x9086, 0x0000, 0x0150, 0x7070, 0xa09a, 0x706c, 0xa096, 0x7068,
+	0xa092, 0x7064, 0xa08e, 0x080c, 0x114e, 0x002e, 0x008e, 0x0005,
+	0x0006, 0x0016, 0x0096, 0x00a6, 0x00b6, 0x00c6, 0x00d6, 0x00e6,
+	0x00f6, 0x0156, 0x080c, 0x8788, 0x015e, 0x00fe, 0x00ee, 0x00de,
+	0x00ce, 0x00be, 0x00ae, 0x009e, 0x001e, 0x000e, 0x0005, 0x00e6,
+	0x2071, 0x1a05, 0x717a, 0x727e, 0x7077, 0x0009, 0x00ee, 0x0005,
+	0x00e6, 0x0006, 0x2071, 0x1a05, 0x707c, 0x9206, 0x1110, 0x707a,
+	0x707e, 0x000e, 0x00ee, 0x0005, 0x2069, 0x1800, 0x69ec, 0xd1e4,
+	0x1518, 0x0026, 0xd1ec, 0x0140, 0x6a54, 0x6874, 0x9202, 0x0288,
+	0x8117, 0x9294, 0x00c1, 0x0088, 0x9184, 0x0007, 0x01a0, 0x8109,
+	0x9184, 0x0007, 0x0110, 0x69ee, 0x0070, 0x8107, 0x9084, 0x0007,
+	0x910d, 0x8107, 0x9106, 0x9094, 0x00c1, 0x9184, 0xff3e, 0x9205,
+	0x68ee, 0x080c, 0x0f24, 0x002e, 0x0005, 0x69e8, 0x9184, 0x003f,
+	0x05b8, 0x8109, 0x9184, 0x003f, 0x01a8, 0x6a54, 0x6874, 0x9202,
+	0x0220, 0xd1bc, 0x0168, 0xc1bc, 0x0018, 0xd1bc, 0x1148, 0xc1bd,
+	0x2110, 0x00e6, 0x2071, 0x1800, 0x080c, 0x0f46, 0x00ee, 0x0400,
+	0x69ea, 0x00f0, 0x0026, 0x8107, 0x9094, 0x0007, 0x0128, 0x8001,
+	0x8007, 0x9085, 0x0007, 0x0050, 0x2010, 0x8004, 0x8004, 0x8004,
+	0x9084, 0x0007, 0x9205, 0x8007, 0x9085, 0x0028, 0x9086, 0x0040,
+	0x2010, 0x00e6, 0x2071, 0x1800, 0x080c, 0x0f46, 0x00ee, 0x002e,
+	0x0005, 0x0016, 0x00c6, 0x2009, 0xfff4, 0x210d, 0x2061, 0x0100,
+	0x60f0, 0x9100, 0x60f3, 0x0000, 0x2009, 0xfff4, 0x200f, 0x1220,
+	0x8108, 0x2105, 0x8000, 0x200f, 0x00ce, 0x001e, 0x0005, 0x00c6,
+	0x2061, 0x1a74, 0x00ce, 0x0005, 0x9184, 0x000f, 0x8003, 0x8003,
+	0x8003, 0x9080, 0x1a74, 0x2060, 0x0005, 0xa884, 0x908a, 0x199a,
+	0x1638, 0x9005, 0x1150, 0x00c6, 0x2061, 0x1a74, 0x6014, 0x00ce,
+	0x9005, 0x1130, 0x2001, 0x001e, 0x0018, 0x908e, 0xffff, 0x01b0,
+	0x8003, 0x800b, 0x810b, 0x9108, 0x611a, 0xa87c, 0x908c, 0x00c0,
+	0x918e, 0x00c0, 0x0904, 0x8a8f, 0xd0b4, 0x1168, 0xd0bc, 0x1904,
+	0x8a68, 0x2009, 0x0006, 0x080c, 0x8abc, 0x0005, 0x900e, 0x0c60,
+	0x2001, 0x1999, 0x08b0, 0xd0fc, 0x05e0, 0x908c, 0x2023, 0x1568,
+	0x87ff, 0x1558, 0xa9a8, 0x81ff, 0x1540, 0x6124, 0x918c, 0x0500,
+	0x1520, 0x6100, 0x918e, 0x0007, 0x1500, 0x2009, 0x1869, 0x210c,
+	0xd184, 0x11d8, 0x6003, 0x0003, 0x6007, 0x0043, 0x6047, 0xb035,
+	0x080c, 0x1c90, 0xa87c, 0xc0dd, 0xa87e, 0x600f, 0x0000, 0x00f6,
+	0x2079, 0x0380, 0x7818, 0xd0bc, 0x1de8, 0x7833, 0x0013, 0x2c00,
+	0x7836, 0x781b, 0x8080, 0x00fe, 0x0005, 0x908c, 0x0003, 0x0120,
+	0x918e, 0x0003, 0x1904, 0x8ab6, 0x908c, 0x2020, 0x918e, 0x2020,
+	0x01a8, 0x6024, 0xd0d4, 0x11e8, 0x2009, 0x1869, 0x2104, 0xd084,
+	0x1138, 0x87ff, 0x1120, 0x2009, 0x0043, 0x0804, 0xafcc, 0x0005,
+	0x87ff, 0x1de8, 0x2009, 0x0042, 0x0804, 0xafcc, 0x6110, 0x00b6,
+	0x2158, 0xb900, 0x00be, 0xd1ac, 0x0d20, 0x6024, 0xc0cd, 0x6026,
+	0x0c00, 0xc0d4, 0x6026, 0xa890, 0x602e, 0xa88c, 0x6032, 0x08e0,
+	0xd0fc, 0x0160, 0x908c, 0x0003, 0x0120, 0x918e, 0x0003, 0x1904,
+	0x8ab6, 0x908c, 0x2020, 0x918e, 0x2020, 0x0170, 0x0076, 0x00f6,
+	0x2c78, 0x080c, 0x17ad, 0x00fe, 0x007e, 0x87ff, 0x1120, 0x2009,
+	0x0042, 0x080c, 0xafcc, 0x0005, 0x6110, 0x00b6, 0x2158, 0xb900,
+	0x00be, 0xd1ac, 0x0d58, 0x6124, 0xc1cd, 0x6126, 0x0c38, 0xd0fc,
+	0x0188, 0x908c, 0x2020, 0x918e, 0x2020, 0x01a8, 0x9084, 0x0003,
+	0x908e, 0x0002, 0x0148, 0x87ff, 0x1120, 0x2009, 0x0041, 0x080c,
+	0xafcc, 0x0005, 0x00b9, 0x0ce8, 0x87ff, 0x1dd8, 0x2009, 0x0043,
+	0x080c, 0xafcc, 0x0cb0, 0x6110, 0x00b6, 0x2158, 0xb900, 0x00be,
+	0xd1ac, 0x0d20, 0x6124, 0xc1cd, 0x6126, 0x0c00, 0x2009, 0x0004,
+	0x0019, 0x0005, 0x2009, 0x0001, 0x0096, 0x080c, 0xcc16, 0x0518,
+	0x6014, 0x2048, 0xa982, 0xa800, 0x6016, 0x9186, 0x0001, 0x1188,
+	0xa97c, 0x918c, 0x8100, 0x918e, 0x8100, 0x1158, 0x00c6, 0x2061,
+	0x1a74, 0x6200, 0xd28c, 0x1120, 0x6204, 0x8210, 0x0208, 0x6206,
+	0x00ce, 0x080c, 0x6d53, 0x6014, 0x904d, 0x0076, 0x2039, 0x0000,
+	0x190c, 0x89d5, 0x007e, 0x009e, 0x0005, 0x0156, 0x00c6, 0x2061,
+	0x1a74, 0x6000, 0x81ff, 0x0110, 0x9205, 0x0008, 0x9204, 0x6002,
+	0x00ce, 0x015e, 0x0005, 0x6800, 0xd08c, 0x1138, 0x6808, 0x9005,
+	0x0120, 0x8001, 0x680a, 0x9085, 0x0001, 0x0005, 0x2071, 0x1925,
+	0x7003, 0x0006, 0x7007, 0x0000, 0x700f, 0x0000, 0x7013, 0x0001,
+	0x080c, 0x1072, 0x090c, 0x0d85, 0xa867, 0x0006, 0xa86b, 0x0001,
+	0xa8ab, 0xdcb0, 0xa89f, 0x0000, 0x2900, 0x702e, 0x7033, 0x0000,
+	0x0005, 0x0126, 0x2091, 0x8000, 0x0096, 0x00e6, 0x2071, 0x1925,
+	0x702c, 0x2048, 0x6a2c, 0x721e, 0x6b30, 0x7322, 0x6834, 0x7026,
+	0xa896, 0x6838, 0x702a, 0xa89a, 0x6824, 0x7016, 0x683c, 0x701a,
+	0x2009, 0x0028, 0x200a, 0x9005, 0x0148, 0x900e, 0x9188, 0x000c,
+	0x8001, 0x1de0, 0x2100, 0x9210, 0x1208, 0x8318, 0xaa8e, 0xab92,
+	0x7010, 0xd084, 0x0168, 0xc084, 0x7007, 0x0001, 0x700f, 0x0000,
+	0x0006, 0x2009, 0x1b74, 0x2104, 0x9082, 0x0007, 0x200a, 0x000e,
+	0xc095, 0x7012, 0x2008, 0x2001, 0x003b, 0x080c, 0x16b9, 0x9006,
+	0x2071, 0x193e, 0x7002, 0x7006, 0x702a, 0x00ee, 0x009e, 0x012e,
+	0x0005, 0x2009, 0x1b74, 0x2104, 0x9080, 0x0007, 0x200a, 0x0005,
 	0x00e6, 0x0126, 0x0156, 0x2091, 0x8000, 0x2071, 0x1800, 0x7154,
 	0x2001, 0x0008, 0x910a, 0x0638, 0x2001, 0x187d, 0x20ac, 0x9006,
-	0x9080, 0x0008, 0x1f04, 0x8a08, 0x71c0, 0x9102, 0x02e0, 0x2071,
-	0x1877, 0x20a9, 0x0007, 0x00c6, 0x080c, 0xac5a, 0x6023, 0x0009,
+	0x9080, 0x0008, 0x1f04, 0x8b78, 0x71c0, 0x9102, 0x02e0, 0x2071,
+	0x1877, 0x20a9, 0x0007, 0x00c6, 0x080c, 0xaed8, 0x6023, 0x0009,
 	0x6003, 0x0004, 0x601f, 0x0101, 0x0089, 0x0126, 0x2091, 0x8000,
-	0x080c, 0x8b89, 0x012e, 0x1f04, 0x8a14, 0x9006, 0x00ce, 0x015e,
+	0x080c, 0x8cf9, 0x012e, 0x1f04, 0x8b84, 0x9006, 0x00ce, 0x015e,
 	0x012e, 0x00ee, 0x0005, 0x9085, 0x0001, 0x0cc8, 0x00e6, 0x00b6,
 	0x0096, 0x0086, 0x0056, 0x0046, 0x0026, 0x7118, 0x720c, 0x7620,
 	0x7004, 0xd084, 0x1128, 0x2021, 0x0024, 0x2029, 0x0002, 0x0020,
-	0x2021, 0x002c, 0x2029, 0x000a, 0x080c, 0x1047, 0x090c, 0x0d7d,
+	0x2021, 0x002c, 0x2029, 0x000a, 0x080c, 0x1059, 0x090c, 0x0d85,
 	0x2900, 0x6016, 0x2058, 0xac66, 0x9006, 0xa802, 0xa806, 0xa86a,
 	0xa87a, 0xa8aa, 0xa887, 0x0005, 0xa87f, 0x0020, 0x7008, 0xa89a,
 	0x7010, 0xa89e, 0xae8a, 0xa8af, 0xffff, 0xa8b3, 0x0000, 0x8109,
-	0x0160, 0x080c, 0x1047, 0x090c, 0x0d7d, 0xad66, 0x2b00, 0xa802,
+	0x0160, 0x080c, 0x1059, 0x090c, 0x0d85, 0xad66, 0x2b00, 0xa802,
 	0x2900, 0xb806, 0x2058, 0x8109, 0x1da0, 0x002e, 0x004e, 0x005e,
 	0x008e, 0x009e, 0x00be, 0x00ee, 0x0005, 0x2079, 0x0000, 0x2071,
-	0x1923, 0x7004, 0x004b, 0x700c, 0x0002, 0x8a80, 0x8a79, 0x8a79,
-	0x0005, 0x8a8a, 0x8ae0, 0x8ae0, 0x8ae0, 0x8ae1, 0x8af2, 0x8af2,
+	0x1925, 0x7004, 0x004b, 0x700c, 0x0002, 0x8bf0, 0x8be9, 0x8be9,
+	0x0005, 0x8bfa, 0x8c50, 0x8c50, 0x8c50, 0x8c51, 0x8c62, 0x8c62,
 	0x700c, 0x0cba, 0x0126, 0x2091, 0x8000, 0x78a0, 0x79a0, 0x9106,
-	0x1904, 0x8ad2, 0x7814, 0xd0bc, 0x1904, 0x8adb, 0x012e, 0x7018,
-	0x910a, 0x1128, 0x7030, 0x9005, 0x1904, 0x8b24, 0x0005, 0x1210,
+	0x1904, 0x8c42, 0x7814, 0xd0bc, 0x1904, 0x8c4b, 0x012e, 0x7018,
+	0x910a, 0x1128, 0x7030, 0x9005, 0x1904, 0x8c94, 0x0005, 0x1210,
 	0x7114, 0x910a, 0x9192, 0x000a, 0x0210, 0x2009, 0x000a, 0x2001,
-	0x1888, 0x2014, 0x2001, 0x1935, 0x2004, 0x9100, 0x9202, 0x0e50,
-	0x080c, 0x8c7d, 0x2200, 0x9102, 0x0208, 0x2208, 0x0096, 0x702c,
-	0x2048, 0xa873, 0x0001, 0xa976, 0x080c, 0x8d86, 0x2100, 0xa87e,
-	0xa86f, 0x0000, 0x009e, 0x0126, 0x2091, 0x8000, 0x2009, 0x1a20,
-	0x2104, 0xc085, 0x200a, 0x700f, 0x0002, 0x012e, 0x080c, 0x115b,
-	0x1de8, 0x0005, 0x78a0, 0x79a0, 0x9106, 0x0904, 0x8a92, 0x080c,
-	0x8c55, 0x012e, 0x0005, 0x7810, 0xc0c5, 0x7812, 0x0804, 0x8a92,
-	0x0005, 0x700c, 0x0002, 0x8ae6, 0x8ae9, 0x8ae8, 0x080c, 0x8a88,
+	0x1888, 0x2014, 0x2001, 0x1937, 0x2004, 0x9100, 0x9202, 0x0e50,
+	0x080c, 0x8df1, 0x2200, 0x9102, 0x0208, 0x2208, 0x0096, 0x702c,
+	0x2048, 0xa873, 0x0001, 0xa976, 0x080c, 0x8efa, 0x2100, 0xa87e,
+	0xa86f, 0x0000, 0x009e, 0x0126, 0x2091, 0x8000, 0x2009, 0x1a25,
+	0x2104, 0xc085, 0x200a, 0x700f, 0x0002, 0x012e, 0x080c, 0x116d,
+	0x1de8, 0x0005, 0x78a0, 0x79a0, 0x9106, 0x0904, 0x8c02, 0x080c,
+	0x8dc9, 0x012e, 0x0005, 0x7810, 0xc0c5, 0x7812, 0x0804, 0x8c02,
+	0x0005, 0x700c, 0x0002, 0x8c56, 0x8c59, 0x8c58, 0x080c, 0x8bf8,
 	0x0005, 0x8001, 0x700e, 0x0096, 0x702c, 0x2048, 0xa974, 0x009e,
 	0x0011, 0x0ca0, 0x0005, 0x0096, 0x702c, 0x2048, 0x7018, 0x9100,
 	0x7214, 0x921a, 0x1130, 0x701c, 0xa88e, 0x7020, 0xa892, 0x9006,
-	0x0068, 0x0006, 0x080c, 0x8d86, 0x2100, 0xaa8c, 0x9210, 0xaa8e,
+	0x0068, 0x0006, 0x080c, 0x8efa, 0x2100, 0xaa8c, 0x9210, 0xaa8e,
 	0x1220, 0xa890, 0x9081, 0x0000, 0xa892, 0x000e, 0x009e, 0x0126,
-	0x2091, 0x8000, 0x78a2, 0x701a, 0x080c, 0x8c55, 0x012e, 0x0005,
-	0x00e6, 0x2071, 0x1923, 0x700c, 0x0002, 0x8b22, 0x8b22, 0x8b20,
+	0x2091, 0x8000, 0x78a2, 0x701a, 0x080c, 0x8dc9, 0x012e, 0x0005,
+	0x00e6, 0x2071, 0x1925, 0x700c, 0x0002, 0x8c92, 0x8c92, 0x8c90,
 	0x700f, 0x0001, 0x00ee, 0x0005, 0x0126, 0x2091, 0x8000, 0x7030,
 	0x9005, 0x0508, 0x2078, 0x7814, 0x2048, 0xae88, 0x00b6, 0x2059,
-	0x0000, 0x080c, 0x8b92, 0x00be, 0x01b0, 0x00e6, 0x2071, 0x193c,
-	0x080c, 0x8bd9, 0x00ee, 0x0178, 0x0096, 0x080c, 0x1060, 0x2900,
-	0x009e, 0x0148, 0xa8aa, 0x04d1, 0x0041, 0x2001, 0x1946, 0x2003,
+	0x0000, 0x080c, 0x8d02, 0x00be, 0x01b0, 0x00e6, 0x2071, 0x193e,
+	0x080c, 0x8d49, 0x00ee, 0x0178, 0x0096, 0x080c, 0x1072, 0x2900,
+	0x009e, 0x0148, 0xa8aa, 0x04d1, 0x0041, 0x2001, 0x1948, 0x2003,
 	0x0000, 0x012e, 0x08c8, 0x012e, 0x0005, 0x00d6, 0x00c6, 0x0086,
 	0x00a6, 0x2940, 0x2650, 0x2600, 0x9005, 0x0180, 0xa864, 0x9084,
-	0x000f, 0x2068, 0x9d88, 0x1eab, 0x2165, 0x0056, 0x2029, 0x0000,
-	0x080c, 0x8d0b, 0x080c, 0x1e81, 0x1dd8, 0x005e, 0x00ae, 0x2001,
-	0x187f, 0x2004, 0xa88a, 0x00c6, 0x2f60, 0x080c, 0x1778, 0x00ce,
+	0x000f, 0x2068, 0x9d88, 0x1ee2, 0x2165, 0x0056, 0x2029, 0x0000,
+	0x080c, 0x8e7f, 0x080c, 0x1eb8, 0x1dd8, 0x005e, 0x00ae, 0x2001,
+	0x187f, 0x2004, 0xa88a, 0x00c6, 0x2f60, 0x080c, 0x17ad, 0x00ce,
 	0x781f, 0x0101, 0x7813, 0x0000, 0x0126, 0x2091, 0x8000, 0x080c,
-	0x8be8, 0x012e, 0x008e, 0x00ce, 0x00de, 0x0005, 0x7030, 0x9005,
-	0x0138, 0x2078, 0x780c, 0x7032, 0x2001, 0x1946, 0x2003, 0x0001,
-	0x0005, 0x00e6, 0x2071, 0x1923, 0x7030, 0x600e, 0x2c00, 0x7032,
-	0x00ee, 0x0005, 0x00d6, 0x00c6, 0x0026, 0x9b80, 0x8e54, 0x2005,
-	0x906d, 0x090c, 0x0d7d, 0x9b80, 0x8e4c, 0x2005, 0x9065, 0x090c,
-	0x0d7d, 0x6114, 0x2600, 0x9102, 0x0248, 0x6828, 0x9102, 0x02f0,
+	0x8d58, 0x012e, 0x008e, 0x00ce, 0x00de, 0x0005, 0x7030, 0x9005,
+	0x0138, 0x2078, 0x780c, 0x7032, 0x2001, 0x1948, 0x2003, 0x0001,
+	0x0005, 0x00e6, 0x2071, 0x1925, 0x7030, 0x600e, 0x2c00, 0x7032,
+	0x00ee, 0x0005, 0x00d6, 0x00c6, 0x0026, 0x9b80, 0x8fc8, 0x2005,
+	0x906d, 0x090c, 0x0d85, 0x9b80, 0x8fc0, 0x2005, 0x9065, 0x090c,
+	0x0d85, 0x6114, 0x2600, 0x9102, 0x0248, 0x6828, 0x9102, 0x02f0,
 	0x9085, 0x0001, 0x002e, 0x00ce, 0x00de, 0x0005, 0x6804, 0xd094,
 	0x0148, 0x6854, 0xd084, 0x1178, 0xc085, 0x6856, 0x2011, 0x8026,
-	0x080c, 0x4b52, 0x684c, 0x0096, 0x904d, 0x090c, 0x0d7d, 0xa804,
+	0x080c, 0x4c2e, 0x684c, 0x0096, 0x904d, 0x090c, 0x0d85, 0xa804,
 	0x8000, 0xa806, 0x009e, 0x9006, 0x2030, 0x0c20, 0x6854, 0xd08c,
-	0x1d08, 0xc08d, 0x6856, 0x2011, 0x8025, 0x080c, 0x4b52, 0x684c,
-	0x0096, 0x904d, 0x090c, 0x0d7d, 0xa800, 0x8000, 0xa802, 0x009e,
+	0x1d08, 0xc08d, 0x6856, 0x2011, 0x8025, 0x080c, 0x4c2e, 0x684c,
+	0x0096, 0x904d, 0x090c, 0x0d85, 0xa800, 0x8000, 0xa802, 0x009e,
 	0x0888, 0x7000, 0x2019, 0x0008, 0x8319, 0x7104, 0x9102, 0x1118,
 	0x2300, 0x9005, 0x0020, 0x0210, 0x9302, 0x0008, 0x8002, 0x0005,
-	0x00d6, 0x7814, 0x9005, 0x090c, 0x0d7d, 0x781c, 0x9084, 0x0101,
-	0x9086, 0x0101, 0x190c, 0x0d7d, 0x7827, 0x0000, 0x2069, 0x193c,
-	0x6804, 0x9080, 0x193e, 0x2f08, 0x2102, 0x6904, 0x8108, 0x9182,
-	0x0008, 0x0208, 0x900e, 0x6906, 0x9180, 0x193e, 0x2003, 0x0000,
+	0x00d6, 0x7814, 0x9005, 0x090c, 0x0d85, 0x781c, 0x9084, 0x0101,
+	0x9086, 0x0101, 0x190c, 0x0d85, 0x7827, 0x0000, 0x2069, 0x193e,
+	0x6804, 0x9080, 0x1940, 0x2f08, 0x2102, 0x6904, 0x8108, 0x9182,
+	0x0008, 0x0208, 0x900e, 0x6906, 0x9180, 0x1940, 0x2003, 0x0000,
 	0x00de, 0x0005, 0x0096, 0x00c6, 0x2060, 0x6014, 0x2048, 0xa8a8,
-	0x0096, 0x2048, 0x9005, 0x190c, 0x1079, 0x009e, 0xa8ab, 0x0000,
-	0x080c, 0x0ff9, 0x080c, 0xacb0, 0x00ce, 0x009e, 0x0005, 0x6020,
+	0x0096, 0x2048, 0x9005, 0x190c, 0x108b, 0x009e, 0xa8ab, 0x0000,
+	0x080c, 0x100b, 0x080c, 0xaf2e, 0x00ce, 0x009e, 0x0005, 0x6020,
 	0x9086, 0x0009, 0x1128, 0x601c, 0xd0c4, 0x0110, 0x9006, 0x0005,
 	0x9085, 0x0001, 0x0005, 0x6000, 0x9086, 0x0000, 0x0178, 0x6010,
-	0x9005, 0x0150, 0x00b6, 0x2058, 0x080c, 0x8f89, 0x00be, 0x6013,
+	0x9005, 0x0150, 0x00b6, 0x2058, 0x080c, 0x90fd, 0x00be, 0x6013,
 	0x0000, 0x601b, 0x0000, 0x0010, 0x2c00, 0x0861, 0x0005, 0x2009,
-	0x1927, 0x210c, 0xd194, 0x0005, 0x00e6, 0x2071, 0x1923, 0x7110,
-	0xc194, 0xd19c, 0x1118, 0xc185, 0x7007, 0x0000, 0x7112, 0x2001,
-	0x003b, 0x080c, 0x16a0, 0x00ee, 0x0005, 0x7814, 0xd0bc, 0x1108,
-	0x0005, 0x7810, 0xc0c5, 0x7812, 0x0cc0, 0x0096, 0x00d6, 0x9006,
-	0x7006, 0x700e, 0x701a, 0x701e, 0x7022, 0x7016, 0x702a, 0x7026,
-	0x702f, 0x0000, 0x080c, 0x8dd4, 0x0170, 0x080c, 0x8e09, 0x0158,
-	0x2900, 0x7002, 0x700a, 0x701a, 0x7013, 0x0001, 0x701f, 0x000a,
-	0x00de, 0x009e, 0x0005, 0x900e, 0x0cd8, 0x00e6, 0x0096, 0x0086,
-	0x00d6, 0x00c6, 0x2071, 0x1930, 0x721c, 0x2100, 0x9202, 0x1618,
-	0x080c, 0x8e09, 0x090c, 0x0d7d, 0x7018, 0x9005, 0x1160, 0x2900,
-	0x7002, 0x700a, 0x701a, 0x9006, 0x7006, 0x700e, 0xa806, 0xa802,
-	0x7012, 0x701e, 0x0038, 0x2040, 0xa806, 0x2900, 0xa002, 0x701a,
-	0xa803, 0x0000, 0x7010, 0x8000, 0x7012, 0x701c, 0x9080, 0x000a,
-	0x701e, 0x721c, 0x08d0, 0x721c, 0x00ce, 0x00de, 0x008e, 0x009e,
-	0x00ee, 0x0005, 0x0096, 0x0156, 0x0136, 0x0146, 0x00e6, 0x0126,
-	0x2091, 0x8000, 0x2071, 0x1930, 0x7300, 0x831f, 0x831e, 0x831e,
-	0x9384, 0x003f, 0x20e8, 0x939c, 0xffc0, 0x9398, 0x0003, 0x7104,
-	0x080c, 0x8d86, 0x810c, 0x2100, 0x9318, 0x8003, 0x2228, 0x2021,
-	0x0078, 0x9402, 0x9532, 0x0208, 0x2028, 0x2500, 0x8004, 0x20a8,
-	0x23a0, 0xa001, 0xa001, 0x4005, 0x2508, 0x080c, 0x8d8f, 0x2130,
-	0x7014, 0x9600, 0x7016, 0x2600, 0x711c, 0x9102, 0x701e, 0x7004,
-	0x9600, 0x2008, 0x9082, 0x000a, 0x1190, 0x7000, 0x2048, 0xa800,
-	0x9005, 0x1148, 0x2009, 0x0001, 0x0026, 0x080c, 0x8c7d, 0x002e,
-	0x7000, 0x2048, 0xa800, 0x7002, 0x7007, 0x0000, 0x0008, 0x7106,
-	0x2500, 0x9212, 0x1904, 0x8cbc, 0x012e, 0x00ee, 0x014e, 0x013e,
-	0x015e, 0x009e, 0x0005, 0x0016, 0x0026, 0x00e6, 0x0126, 0x2091,
-	0x8000, 0x9580, 0x8e4c, 0x2005, 0x9075, 0x090c, 0x0d7d, 0x080c,
-	0x8d61, 0x012e, 0x9580, 0x8e48, 0x2005, 0x9075, 0x090c, 0x0d7d,
-	0x0156, 0x0136, 0x01c6, 0x0146, 0x01d6, 0x831f, 0x831e, 0x831e,
-	0x9384, 0x003f, 0x20e0, 0x9384, 0xffc0, 0x9100, 0x2098, 0xa860,
-	0x20e8, 0xa95c, 0x2c05, 0x9100, 0x20a0, 0x20a9, 0x0002, 0x4003,
-	0x2e0c, 0x2d00, 0x0002, 0x8d4b, 0x8d4b, 0x8d4d, 0x8d4b, 0x8d4d,
-	0x8d4b, 0x8d4b, 0x8d4b, 0x8d4b, 0x8d4b, 0x8d53, 0x8d4b, 0x8d53,
-	0x8d4b, 0x8d4b, 0x8d4b, 0x080c, 0x0d7d, 0x4104, 0x20a9, 0x0002,
-	0x4002, 0x4003, 0x0028, 0x20a9, 0x0002, 0x4003, 0x4104, 0x4003,
-	0x01de, 0x014e, 0x01ce, 0x013e, 0x015e, 0x00ee, 0x002e, 0x001e,
-	0x0005, 0x0096, 0x7014, 0x8001, 0x7016, 0x710c, 0x2110, 0x00f1,
-	0x810c, 0x9188, 0x0003, 0x7308, 0x8210, 0x9282, 0x000a, 0x1198,
-	0x7008, 0x2048, 0xa800, 0x9005, 0x0158, 0x0006, 0x080c, 0x8e18,
-	0x009e, 0xa807, 0x0000, 0x2900, 0x700a, 0x7010, 0x8001, 0x7012,
-	0x700f, 0x0000, 0x0008, 0x720e, 0x009e, 0x0005, 0x0006, 0x810b,
-	0x810b, 0x2100, 0x810b, 0x9100, 0x2008, 0x000e, 0x0005, 0x0006,
-	0x0026, 0x2100, 0x9005, 0x0158, 0x9092, 0x000c, 0x0240, 0x900e,
-	0x8108, 0x9082, 0x000c, 0x1de0, 0x002e, 0x000e, 0x0005, 0x900e,
-	0x0cd8, 0x2d00, 0x90b8, 0x0008, 0x2031, 0x8dd2, 0x901e, 0x6808,
-	0x9005, 0x0108, 0x8318, 0x690c, 0x910a, 0x0248, 0x0140, 0x8318,
-	0x6810, 0x9112, 0x0220, 0x0118, 0x8318, 0x2208, 0x0cd0, 0x233a,
-	0x6804, 0xd084, 0x2300, 0x2021, 0x0001, 0x1150, 0x9082, 0x0003,
-	0x0967, 0x0a67, 0x8420, 0x9082, 0x0007, 0x0967, 0x0a67, 0x0cd0,
-	0x9082, 0x0002, 0x0967, 0x0a67, 0x8420, 0x9082, 0x0005, 0x0967,
-	0x0a67, 0x0cd0, 0x6c1a, 0x0005, 0x0096, 0x0046, 0x0126, 0x2091,
-	0x8000, 0x2b00, 0x9080, 0x8e50, 0x2005, 0x9005, 0x090c, 0x0d7d,
-	0x2004, 0x90a0, 0x000a, 0x080c, 0x1060, 0x01d0, 0x2900, 0x7026,
-	0xa803, 0x0000, 0xa807, 0x0000, 0x080c, 0x1060, 0x0188, 0x7024,
-	0xa802, 0xa807, 0x0000, 0x2900, 0x7026, 0x94a2, 0x000a, 0x0110,
-	0x0208, 0x0c90, 0x9085, 0x0001, 0x012e, 0x004e, 0x009e, 0x0005,
-	0x7024, 0x9005, 0x0dc8, 0x2048, 0xac00, 0x080c, 0x1079, 0x2400,
-	0x0cc0, 0x0126, 0x2091, 0x8000, 0x7024, 0x2048, 0x9005, 0x0130,
-	0xa800, 0x7026, 0xa803, 0x0000, 0xa807, 0x0000, 0x012e, 0x0005,
-	0x0126, 0x2091, 0x8000, 0x7024, 0xa802, 0x2900, 0x7026, 0x012e,
-	0x0005, 0x0096, 0x9e80, 0x0009, 0x2004, 0x9005, 0x0138, 0x2048,
-	0xa800, 0x0006, 0x080c, 0x1079, 0x000e, 0x0cb8, 0x009e, 0x0005,
-	0x0096, 0x7008, 0x9005, 0x0138, 0x2048, 0xa800, 0x0006, 0x080c,
-	0x1079, 0x000e, 0x0cb8, 0x9006, 0x7002, 0x700a, 0x7006, 0x700e,
-	0x701a, 0x701e, 0x7022, 0x702a, 0x7026, 0x702e, 0x009e, 0x0005,
-	0x1a6c, 0x0000, 0x0000, 0x0000, 0x1930, 0x0000, 0x0000, 0x0000,
-	0x1888, 0x0000, 0x0000, 0x0000, 0x1877, 0x0000, 0x0000, 0x0000,
-	0x00e6, 0x00c6, 0x00b6, 0x00a6, 0xa8a8, 0x2040, 0x2071, 0x1877,
-	0x080c, 0x8f74, 0xa067, 0x0023, 0x6010, 0x905d, 0x0904, 0x8f49,
-	0xb814, 0xa06e, 0xb910, 0xa172, 0xb9a0, 0xa176, 0x2001, 0x0003,
-	0xa07e, 0xa834, 0xa082, 0xa07b, 0x0000, 0xa898, 0x9005, 0x0118,
-	0xa078, 0xc085, 0xa07a, 0x2858, 0x2031, 0x0018, 0xa068, 0x908a,
-	0x0019, 0x1a0c, 0x0d7d, 0x2020, 0x2050, 0x2940, 0xa864, 0x90bc,
-	0x00ff, 0x908c, 0x000f, 0x91e0, 0x1eab, 0x2c65, 0x9786, 0x0024,
-	0x2c05, 0x1590, 0x908a, 0x0036, 0x1a0c, 0x0d7d, 0x9082, 0x001b,
-	0x0002, 0x8eb4, 0x8eb4, 0x8eb6, 0x8eb4, 0x8eb4, 0x8eb4, 0x8eb8,
-	0x8eb4, 0x8eb4, 0x8eb4, 0x8eba, 0x8eb4, 0x8eb4, 0x8eb4, 0x8ebc,
-	0x8eb4, 0x8eb4, 0x8eb4, 0x8ebe, 0x8eb4, 0x8eb4, 0x8eb4, 0x8ec0,
-	0x8eb4, 0x8eb4, 0x8eb4, 0x8ec2, 0x080c, 0x0d7d, 0xa180, 0x04b8,
-	0xa190, 0x04a8, 0xa1a0, 0x0498, 0xa1b0, 0x0488, 0xa1c0, 0x0478,
-	0xa1d0, 0x0468, 0xa1e0, 0x0458, 0x908a, 0x0034, 0x1a0c, 0x0d7d,
-	0x9082, 0x001b, 0x0002, 0x8ee6, 0x8ee4, 0x8ee4, 0x8ee4, 0x8ee4,
-	0x8ee4, 0x8ee8, 0x8ee4, 0x8ee4, 0x8ee4, 0x8ee4, 0x8ee4, 0x8eea,
-	0x8ee4, 0x8ee4, 0x8ee4, 0x8ee4, 0x8ee4, 0x8eec, 0x8ee4, 0x8ee4,
-	0x8ee4, 0x8ee4, 0x8ee4, 0x8eee, 0x080c, 0x0d7d, 0xa180, 0x0038,
-	0xa198, 0x0028, 0xa1b0, 0x0018, 0xa1c8, 0x0008, 0xa1e0, 0x2600,
-	0x0002, 0x8f0a, 0x8f0c, 0x8f0e, 0x8f10, 0x8f12, 0x8f14, 0x8f16,
-	0x8f18, 0x8f1a, 0x8f1c, 0x8f1e, 0x8f20, 0x8f22, 0x8f24, 0x8f26,
-	0x8f28, 0x8f2a, 0x8f2c, 0x8f2e, 0x8f30, 0x8f32, 0x8f34, 0x8f36,
-	0x8f38, 0x8f3a, 0x080c, 0x0d7d, 0xb9e2, 0x0468, 0xb9de, 0x0458,
-	0xb9da, 0x0448, 0xb9d6, 0x0438, 0xb9d2, 0x0428, 0xb9ce, 0x0418,
-	0xb9ca, 0x0408, 0xb9c6, 0x00f8, 0xb9c2, 0x00e8, 0xb9be, 0x00d8,
-	0xb9ba, 0x00c8, 0xb9b6, 0x00b8, 0xb9b2, 0x00a8, 0xb9ae, 0x0098,
-	0xb9aa, 0x0088, 0xb9a6, 0x0078, 0xb9a2, 0x0068, 0xb99e, 0x0058,
-	0xb99a, 0x0048, 0xb996, 0x0038, 0xb992, 0x0028, 0xb98e, 0x0018,
-	0xb98a, 0x0008, 0xb986, 0x8631, 0x8421, 0x0130, 0x080c, 0x1e81,
-	0x090c, 0x0d7d, 0x0804, 0x8e8e, 0x00ae, 0x00be, 0x00ce, 0x00ee,
-	0x0005, 0xa86c, 0xa06e, 0xa870, 0xa072, 0xa077, 0x00ff, 0x9006,
-	0x0804, 0x8e70, 0x0006, 0x0016, 0x00b6, 0x6010, 0x2058, 0xb810,
-	0x9005, 0x01b0, 0x2001, 0x1924, 0x2004, 0x9005, 0x0188, 0x2001,
-	0x1800, 0x2004, 0x9086, 0x0003, 0x1158, 0x0036, 0x0046, 0xbba0,
-	0x2021, 0x0004, 0x2011, 0x8014, 0x080c, 0x4b52, 0x004e, 0x003e,
-	0x00be, 0x001e, 0x000e, 0x0005, 0x9016, 0x710c, 0xa834, 0x910a,
-	0xa936, 0x7008, 0x9005, 0x0120, 0x8210, 0x910a, 0x0238, 0x0130,
-	0x7010, 0x8210, 0x910a, 0x0210, 0x0108, 0x0cd8, 0xaa8a, 0xa26a,
-	0x0005, 0x00f6, 0x00d6, 0x0036, 0x2079, 0x0300, 0x781b, 0x0200,
-	0x7818, 0xd094, 0x1dd8, 0x781b, 0x0202, 0xa001, 0xa001, 0x7818,
-	0xd094, 0x1da0, 0xb8ac, 0x9005, 0x01b8, 0x2068, 0x2079, 0x0000,
-	0x2c08, 0x911e, 0x1118, 0x680c, 0xb8ae, 0x0060, 0x9106, 0x0140,
-	0x2d00, 0x2078, 0x680c, 0x9005, 0x090c, 0x0d7d, 0x2068, 0x0cb0,
-	0x6b0c, 0x7b0e, 0x600f, 0x0000, 0x2079, 0x0300, 0x781b, 0x0200,
-	0x003e, 0x00de, 0x00fe, 0x0005, 0x00e6, 0x00d6, 0x0096, 0x00c6,
-	0x0036, 0x0126, 0x2091, 0x8000, 0x0156, 0x20a9, 0x01ff, 0x2071,
-	0x0300, 0x701b, 0x0200, 0x7018, 0xd094, 0x0110, 0x1f04, 0x8fc9,
-	0x701b, 0x0202, 0xa001, 0xa001, 0x7018, 0xd094, 0x1d90, 0xb8ac,
-	0x9005, 0x01e8, 0x2060, 0x600c, 0xb8ae, 0x6024, 0xc08d, 0x6026,
-	0x6003, 0x0004, 0x601b, 0x0000, 0x6013, 0x0000, 0x601f, 0x0101,
-	0x6014, 0x2048, 0xa88b, 0x0000, 0xa8a8, 0xa8ab, 0x0000, 0x904d,
-	0x090c, 0x0d7d, 0x080c, 0x1079, 0x080c, 0x8b89, 0x0c00, 0x2071,
-	0x0300, 0x701b, 0x0200, 0x015e, 0x012e, 0x003e, 0x00ce, 0x009e,
-	0x00de, 0x00ee, 0x0005, 0x00c6, 0x00b6, 0x0016, 0x0006, 0x0156,
-	0x080c, 0x2661, 0x015e, 0x11b0, 0x080c, 0x6632, 0x190c, 0x0d7d,
-	0x000e, 0x001e, 0xb912, 0xb816, 0x080c, 0xac5a, 0x0140, 0x2b00,
-	0x6012, 0x6023, 0x0001, 0x2009, 0x0001, 0x080c, 0xad4d, 0x00be,
-	0x00ce, 0x0005, 0x000e, 0x001e, 0x0cd0, 0x0066, 0x6000, 0x90b2,
-	0x0016, 0x1a0c, 0x0d7d, 0x0013, 0x006e, 0x0005, 0x903e, 0x903e,
-	0x903e, 0x9040, 0x9089, 0x903e, 0x903e, 0x903e, 0x90f0, 0x903e,
-	0x9128, 0x903e, 0x903e, 0x903e, 0x903e, 0x903e, 0x080c, 0x0d7d,
-	0x9182, 0x0040, 0x0002, 0x9053, 0x9053, 0x9053, 0x9053, 0x9053,
-	0x9053, 0x9053, 0x9053, 0x9053, 0x9055, 0x9066, 0x9053, 0x9053,
-	0x9053, 0x9053, 0x9077, 0x080c, 0x0d7d, 0x0096, 0x6114, 0x2148,
+	0x1929, 0x210c, 0xd194, 0x0005, 0x0126, 0x2091, 0x8000, 0x00e6,
+	0x2071, 0x1925, 0x7110, 0xc194, 0xd19c, 0x1118, 0xc185, 0x7007,
+	0x0000, 0x7112, 0x2001, 0x003b, 0x080c, 0x16b9, 0x00ee, 0x012e,
+	0x0005, 0x7814, 0xd0bc, 0x1108, 0x0005, 0x7810, 0xc0c5, 0x7812,
+	0x0cc0, 0x0096, 0x00d6, 0x9006, 0x7006, 0x700e, 0x701a, 0x701e,
+	0x7022, 0x7016, 0x702a, 0x7026, 0x702f, 0x0000, 0x080c, 0x8f48,
+	0x0170, 0x080c, 0x8f7d, 0x0158, 0x2900, 0x7002, 0x700a, 0x701a,
+	0x7013, 0x0001, 0x701f, 0x000a, 0x00de, 0x009e, 0x0005, 0x900e,
+	0x0cd8, 0x00e6, 0x0096, 0x0086, 0x00d6, 0x00c6, 0x2071, 0x1932,
+	0x721c, 0x2100, 0x9202, 0x1618, 0x080c, 0x8f7d, 0x090c, 0x0d85,
+	0x7018, 0x9005, 0x1160, 0x2900, 0x7002, 0x700a, 0x701a, 0x9006,
+	0x7006, 0x700e, 0xa806, 0xa802, 0x7012, 0x701e, 0x0038, 0x2040,
+	0xa806, 0x2900, 0xa002, 0x701a, 0xa803, 0x0000, 0x7010, 0x8000,
+	0x7012, 0x701c, 0x9080, 0x000a, 0x701e, 0x721c, 0x08d0, 0x721c,
+	0x00ce, 0x00de, 0x008e, 0x009e, 0x00ee, 0x0005, 0x0096, 0x0156,
+	0x0136, 0x0146, 0x00e6, 0x0126, 0x2091, 0x8000, 0x2071, 0x1932,
+	0x7300, 0x831f, 0x831e, 0x831e, 0x9384, 0x003f, 0x20e8, 0x939c,
+	0xffc0, 0x9398, 0x0003, 0x7104, 0x080c, 0x8efa, 0x810c, 0x2100,
+	0x9318, 0x8003, 0x2228, 0x2021, 0x0078, 0x9402, 0x9532, 0x0208,
+	0x2028, 0x2500, 0x8004, 0x20a8, 0x23a0, 0xa001, 0xa001, 0x4005,
+	0x2508, 0x080c, 0x8f03, 0x2130, 0x7014, 0x9600, 0x7016, 0x2600,
+	0x711c, 0x9102, 0x701e, 0x7004, 0x9600, 0x2008, 0x9082, 0x000a,
+	0x1190, 0x7000, 0x2048, 0xa800, 0x9005, 0x1148, 0x2009, 0x0001,
+	0x0026, 0x080c, 0x8df1, 0x002e, 0x7000, 0x2048, 0xa800, 0x7002,
+	0x7007, 0x0000, 0x0008, 0x7106, 0x2500, 0x9212, 0x1904, 0x8e30,
+	0x012e, 0x00ee, 0x014e, 0x013e, 0x015e, 0x009e, 0x0005, 0x0016,
+	0x0026, 0x00e6, 0x0126, 0x2091, 0x8000, 0x9580, 0x8fc0, 0x2005,
+	0x9075, 0x090c, 0x0d85, 0x080c, 0x8ed5, 0x012e, 0x9580, 0x8fbc,
+	0x2005, 0x9075, 0x090c, 0x0d85, 0x0156, 0x0136, 0x01c6, 0x0146,
+	0x01d6, 0x831f, 0x831e, 0x831e, 0x9384, 0x003f, 0x20e0, 0x9384,
+	0xffc0, 0x9100, 0x2098, 0xa860, 0x20e8, 0xa95c, 0x2c05, 0x9100,
+	0x20a0, 0x20a9, 0x0002, 0x4003, 0x2e0c, 0x2d00, 0x0002, 0x8ebf,
+	0x8ebf, 0x8ec1, 0x8ebf, 0x8ec1, 0x8ebf, 0x8ebf, 0x8ebf, 0x8ebf,
+	0x8ebf, 0x8ec7, 0x8ebf, 0x8ec7, 0x8ebf, 0x8ebf, 0x8ebf, 0x080c,
+	0x0d85, 0x4104, 0x20a9, 0x0002, 0x4002, 0x4003, 0x0028, 0x20a9,
+	0x0002, 0x4003, 0x4104, 0x4003, 0x01de, 0x014e, 0x01ce, 0x013e,
+	0x015e, 0x00ee, 0x002e, 0x001e, 0x0005, 0x0096, 0x7014, 0x8001,
+	0x7016, 0x710c, 0x2110, 0x00f1, 0x810c, 0x9188, 0x0003, 0x7308,
+	0x8210, 0x9282, 0x000a, 0x1198, 0x7008, 0x2048, 0xa800, 0x9005,
+	0x0158, 0x0006, 0x080c, 0x8f8c, 0x009e, 0xa807, 0x0000, 0x2900,
+	0x700a, 0x7010, 0x8001, 0x7012, 0x700f, 0x0000, 0x0008, 0x720e,
+	0x009e, 0x0005, 0x0006, 0x810b, 0x810b, 0x2100, 0x810b, 0x9100,
+	0x2008, 0x000e, 0x0005, 0x0006, 0x0026, 0x2100, 0x9005, 0x0158,
+	0x9092, 0x000c, 0x0240, 0x900e, 0x8108, 0x9082, 0x000c, 0x1de0,
+	0x002e, 0x000e, 0x0005, 0x900e, 0x0cd8, 0x2d00, 0x90b8, 0x0008,
+	0x2031, 0x8f46, 0x901e, 0x6808, 0x9005, 0x0108, 0x8318, 0x690c,
+	0x910a, 0x0248, 0x0140, 0x8318, 0x6810, 0x9112, 0x0220, 0x0118,
+	0x8318, 0x2208, 0x0cd0, 0x233a, 0x6804, 0xd084, 0x2300, 0x2021,
+	0x0001, 0x1150, 0x9082, 0x0003, 0x0967, 0x0a67, 0x8420, 0x9082,
+	0x0007, 0x0967, 0x0a67, 0x0cd0, 0x9082, 0x0002, 0x0967, 0x0a67,
+	0x8420, 0x9082, 0x0005, 0x0967, 0x0a67, 0x0cd0, 0x6c1a, 0x0005,
+	0x0096, 0x0046, 0x0126, 0x2091, 0x8000, 0x2b00, 0x9080, 0x8fc4,
+	0x2005, 0x9005, 0x090c, 0x0d85, 0x2004, 0x90a0, 0x000a, 0x080c,
+	0x1072, 0x01d0, 0x2900, 0x7026, 0xa803, 0x0000, 0xa807, 0x0000,
+	0x080c, 0x1072, 0x0188, 0x7024, 0xa802, 0xa807, 0x0000, 0x2900,
+	0x7026, 0x94a2, 0x000a, 0x0110, 0x0208, 0x0c90, 0x9085, 0x0001,
+	0x012e, 0x004e, 0x009e, 0x0005, 0x7024, 0x9005, 0x0dc8, 0x2048,
+	0xac00, 0x080c, 0x108b, 0x2400, 0x0cc0, 0x0126, 0x2091, 0x8000,
+	0x7024, 0x2048, 0x9005, 0x0130, 0xa800, 0x7026, 0xa803, 0x0000,
+	0xa807, 0x0000, 0x012e, 0x0005, 0x0126, 0x2091, 0x8000, 0x7024,
+	0xa802, 0x2900, 0x7026, 0x012e, 0x0005, 0x0096, 0x9e80, 0x0009,
+	0x2004, 0x9005, 0x0138, 0x2048, 0xa800, 0x0006, 0x080c, 0x108b,
+	0x000e, 0x0cb8, 0x009e, 0x0005, 0x0096, 0x7008, 0x9005, 0x0138,
+	0x2048, 0xa800, 0x0006, 0x080c, 0x108b, 0x000e, 0x0cb8, 0x9006,
+	0x7002, 0x700a, 0x7006, 0x700e, 0x701a, 0x701e, 0x7022, 0x702a,
+	0x7026, 0x702e, 0x009e, 0x0005, 0x1a72, 0x0000, 0x0000, 0x0000,
+	0x1932, 0x0000, 0x0000, 0x0000, 0x1888, 0x0000, 0x0000, 0x0000,
+	0x1877, 0x0000, 0x0000, 0x0000, 0x00e6, 0x00c6, 0x00b6, 0x00a6,
+	0xa8a8, 0x2040, 0x2071, 0x1877, 0x080c, 0x90e8, 0xa067, 0x0023,
+	0x6010, 0x905d, 0x0904, 0x90bd, 0xb814, 0xa06e, 0xb910, 0xa172,
+	0xb9a0, 0xa176, 0x2001, 0x0003, 0xa07e, 0xa834, 0xa082, 0xa07b,
+	0x0000, 0xa898, 0x9005, 0x0118, 0xa078, 0xc085, 0xa07a, 0x2858,
+	0x2031, 0x0018, 0xa068, 0x908a, 0x0019, 0x1a0c, 0x0d85, 0x2020,
+	0x2050, 0x2940, 0xa864, 0x90bc, 0x00ff, 0x908c, 0x000f, 0x91e0,
+	0x1ee2, 0x2c65, 0x9786, 0x0024, 0x2c05, 0x1590, 0x908a, 0x0036,
+	0x1a0c, 0x0d85, 0x9082, 0x001b, 0x0002, 0x9028, 0x9028, 0x902a,
+	0x9028, 0x9028, 0x9028, 0x902c, 0x9028, 0x9028, 0x9028, 0x902e,
+	0x9028, 0x9028, 0x9028, 0x9030, 0x9028, 0x9028, 0x9028, 0x9032,
+	0x9028, 0x9028, 0x9028, 0x9034, 0x9028, 0x9028, 0x9028, 0x9036,
+	0x080c, 0x0d85, 0xa180, 0x04b8, 0xa190, 0x04a8, 0xa1a0, 0x0498,
+	0xa1b0, 0x0488, 0xa1c0, 0x0478, 0xa1d0, 0x0468, 0xa1e0, 0x0458,
+	0x908a, 0x0034, 0x1a0c, 0x0d85, 0x9082, 0x001b, 0x0002, 0x905a,
+	0x9058, 0x9058, 0x9058, 0x9058, 0x9058, 0x905c, 0x9058, 0x9058,
+	0x9058, 0x9058, 0x9058, 0x905e, 0x9058, 0x9058, 0x9058, 0x9058,
+	0x9058, 0x9060, 0x9058, 0x9058, 0x9058, 0x9058, 0x9058, 0x9062,
+	0x080c, 0x0d85, 0xa180, 0x0038, 0xa198, 0x0028, 0xa1b0, 0x0018,
+	0xa1c8, 0x0008, 0xa1e0, 0x2600, 0x0002, 0x907e, 0x9080, 0x9082,
+	0x9084, 0x9086, 0x9088, 0x908a, 0x908c, 0x908e, 0x9090, 0x9092,
+	0x9094, 0x9096, 0x9098, 0x909a, 0x909c, 0x909e, 0x90a0, 0x90a2,
+	0x90a4, 0x90a6, 0x90a8, 0x90aa, 0x90ac, 0x90ae, 0x080c, 0x0d85,
+	0xb9e2, 0x0468, 0xb9de, 0x0458, 0xb9da, 0x0448, 0xb9d6, 0x0438,
+	0xb9d2, 0x0428, 0xb9ce, 0x0418, 0xb9ca, 0x0408, 0xb9c6, 0x00f8,
+	0xb9c2, 0x00e8, 0xb9be, 0x00d8, 0xb9ba, 0x00c8, 0xb9b6, 0x00b8,
+	0xb9b2, 0x00a8, 0xb9ae, 0x0098, 0xb9aa, 0x0088, 0xb9a6, 0x0078,
+	0xb9a2, 0x0068, 0xb99e, 0x0058, 0xb99a, 0x0048, 0xb996, 0x0038,
+	0xb992, 0x0028, 0xb98e, 0x0018, 0xb98a, 0x0008, 0xb986, 0x8631,
+	0x8421, 0x0130, 0x080c, 0x1eb8, 0x090c, 0x0d85, 0x0804, 0x9002,
+	0x00ae, 0x00be, 0x00ce, 0x00ee, 0x0005, 0xa86c, 0xa06e, 0xa870,
+	0xa072, 0xa077, 0x00ff, 0x9006, 0x0804, 0x8fe4, 0x0006, 0x0016,
+	0x00b6, 0x6010, 0x2058, 0xb810, 0x9005, 0x01b0, 0x2001, 0x1926,
+	0x2004, 0x9005, 0x0188, 0x2001, 0x1800, 0x2004, 0x9086, 0x0003,
+	0x1158, 0x0036, 0x0046, 0xbba0, 0x2021, 0x0004, 0x2011, 0x8014,
+	0x080c, 0x4c2e, 0x004e, 0x003e, 0x00be, 0x001e, 0x000e, 0x0005,
+	0x9016, 0x710c, 0xa834, 0x910a, 0xa936, 0x7008, 0x9005, 0x0120,
+	0x8210, 0x910a, 0x0238, 0x0130, 0x7010, 0x8210, 0x910a, 0x0210,
+	0x0108, 0x0cd8, 0xaa8a, 0xa26a, 0x0005, 0x00f6, 0x00d6, 0x0036,
+	0x2079, 0x0300, 0x781b, 0x0200, 0x7818, 0xd094, 0x1dd8, 0x781b,
+	0x0202, 0xa001, 0xa001, 0x7818, 0xd094, 0x1da0, 0xb8ac, 0x9005,
+	0x01b8, 0x2068, 0x2079, 0x0000, 0x2c08, 0x911e, 0x1118, 0x680c,
+	0xb8ae, 0x0060, 0x9106, 0x0140, 0x2d00, 0x2078, 0x680c, 0x9005,
+	0x090c, 0x0d85, 0x2068, 0x0cb0, 0x6b0c, 0x7b0e, 0x600f, 0x0000,
+	0x2079, 0x0300, 0x781b, 0x0200, 0x003e, 0x00de, 0x00fe, 0x0005,
+	0x00e6, 0x00d6, 0x0096, 0x00c6, 0x0036, 0x0126, 0x2091, 0x8000,
+	0x0156, 0x20a9, 0x01ff, 0x2071, 0x0300, 0x701b, 0x0200, 0x7018,
+	0xd094, 0x0110, 0x1f04, 0x913d, 0x701b, 0x0202, 0xa001, 0xa001,
+	0x7018, 0xd094, 0x1d90, 0xb8ac, 0x9005, 0x01e8, 0x2060, 0x600c,
+	0xb8ae, 0x6024, 0xc08d, 0x6026, 0x6003, 0x0004, 0x601b, 0x0000,
+	0x6013, 0x0000, 0x601f, 0x0101, 0x6014, 0x2048, 0xa88b, 0x0000,
+	0xa8a8, 0xa8ab, 0x0000, 0x904d, 0x090c, 0x0d85, 0x080c, 0x108b,
+	0x080c, 0x8cf9, 0x0c00, 0x2071, 0x0300, 0x701b, 0x0200, 0x015e,
+	0x012e, 0x003e, 0x00ce, 0x009e, 0x00de, 0x00ee, 0x0005, 0x00c6,
+	0x00b6, 0x0016, 0x0006, 0x0156, 0x080c, 0x26a2, 0x015e, 0x11b0,
+	0x080c, 0x671e, 0x190c, 0x0d85, 0x000e, 0x001e, 0xb912, 0xb816,
+	0x080c, 0xaed8, 0x0140, 0x2b00, 0x6012, 0x6023, 0x0001, 0x2009,
+	0x0001, 0x080c, 0xafcc, 0x00be, 0x00ce, 0x0005, 0x000e, 0x001e,
+	0x0cd0, 0x0066, 0x6000, 0x90b2, 0x0016, 0x1a0c, 0x0d85, 0x0013,
+	0x006e, 0x0005, 0x91b2, 0x91b2, 0x91b2, 0x91b4, 0x91fd, 0x91b2,
+	0x91b2, 0x91b2, 0x9264, 0x91b2, 0x929c, 0x91b2, 0x91b2, 0x91b2,
+	0x91b2, 0x91b2, 0x080c, 0x0d85, 0x9182, 0x0040, 0x0002, 0x91c7,
+	0x91c7, 0x91c7, 0x91c7, 0x91c7, 0x91c7, 0x91c7, 0x91c7, 0x91c7,
+	0x91c9, 0x91da, 0x91c7, 0x91c7, 0x91c7, 0x91c7, 0x91eb, 0x080c,
+	0x0d85, 0x0096, 0x6114, 0x2148, 0xa87b, 0x0000, 0x6010, 0x00b6,
+	0x2058, 0xb8bb, 0x0500, 0x00be, 0x080c, 0x6d18, 0x080c, 0xaf2e,
+	0x009e, 0x0005, 0x080c, 0x9859, 0x00d6, 0x6114, 0x080c, 0xcc16,
+	0x0130, 0x0096, 0x6114, 0x2148, 0x080c, 0x6f19, 0x009e, 0x00de,
+	0x080c, 0xaf2e, 0x0005, 0x080c, 0x9859, 0x080c, 0x3310, 0x6114,
+	0x0096, 0x2148, 0x080c, 0xcc16, 0x0120, 0xa87b, 0x0029, 0x080c,
+	0x6f19, 0x009e, 0x080c, 0xaf2e, 0x0005, 0x601b, 0x0000, 0x9182,
+	0x0040, 0x0096, 0x0002, 0x9218, 0x9218, 0x9218, 0x9218, 0x9218,
+	0x9218, 0x9218, 0x9218, 0x921a, 0x9218, 0x9218, 0x9218, 0x9260,
+	0x9218, 0x9218, 0x9218, 0x9218, 0x9218, 0x9218, 0x9221, 0x9218,
+	0x080c, 0x0d85, 0x6114, 0x2148, 0xa938, 0x918e, 0xffff, 0x0904,
+	0x9260, 0x6024, 0xd08c, 0x15c0, 0x00e6, 0x6114, 0x2148, 0x080c,
+	0x8fcc, 0x0096, 0xa8a8, 0x2048, 0x080c, 0x6cb0, 0x009e, 0xa8ab,
+	0x0000, 0x6010, 0x9005, 0x0128, 0x00b6, 0x2058, 0x080c, 0x90fd,
+	0x00be, 0xae88, 0x00b6, 0x2059, 0x0000, 0x080c, 0x8d02, 0x00be,
+	0x01e0, 0x2071, 0x193e, 0x080c, 0x8d49, 0x01b8, 0x9086, 0x0001,
+	0x1128, 0x2001, 0x1948, 0x2004, 0x9005, 0x1178, 0x0096, 0x080c,
+	0x1059, 0x2900, 0x009e, 0x0148, 0xa8aa, 0x00f6, 0x2c78, 0x080c,
+	0x8cbd, 0x00fe, 0x00ee, 0x009e, 0x0005, 0x080c, 0x8cf9, 0x0cd0,
+	0x080c, 0x9318, 0x009e, 0x0005, 0x9182, 0x0040, 0x0096, 0x0002,
+	0x9278, 0x9278, 0x9278, 0x927a, 0x9278, 0x9278, 0x9278, 0x929a,
+	0x9278, 0x9278, 0x9278, 0x9278, 0x9278, 0x9278, 0x9278, 0x9278,
+	0x080c, 0x0d85, 0x6003, 0x0003, 0x6106, 0x6014, 0x2048, 0xa8ac,
+	0xa836, 0xa8b0, 0xa83a, 0xa847, 0x0000, 0xa84b, 0x0000, 0xa884,
+	0x9092, 0x199a, 0x0210, 0x2001, 0x1999, 0x8003, 0x8013, 0x8213,
+	0x9210, 0x621a, 0x080c, 0x1c47, 0x2009, 0x8030, 0x080c, 0x946f,
+	0x009e, 0x0005, 0x080c, 0x0d85, 0x080c, 0x9859, 0x6114, 0x2148,
 	0xa87b, 0x0000, 0x6010, 0x00b6, 0x2058, 0xb8bb, 0x0500, 0x00be,
-	0x080c, 0x6bee, 0x080c, 0xacb0, 0x009e, 0x0005, 0x080c, 0x96d5,
-	0x00d6, 0x6114, 0x080c, 0xc97a, 0x0130, 0x0096, 0x6114, 0x2148,
-	0x080c, 0x6dee, 0x009e, 0x00de, 0x080c, 0xacb0, 0x0005, 0x080c,
-	0x96d5, 0x080c, 0x3240, 0x6114, 0x0096, 0x2148, 0x080c, 0xc97a,
-	0x0120, 0xa87b, 0x0029, 0x080c, 0x6dee, 0x009e, 0x080c, 0xacb0,
-	0x0005, 0x601b, 0x0000, 0x9182, 0x0040, 0x0096, 0x0002, 0x90a4,
-	0x90a4, 0x90a4, 0x90a4, 0x90a4, 0x90a4, 0x90a4, 0x90a4, 0x90a6,
-	0x90a4, 0x90a4, 0x90a4, 0x90ec, 0x90a4, 0x90a4, 0x90a4, 0x90a4,
-	0x90a4, 0x90a4, 0x90ad, 0x90a4, 0x080c, 0x0d7d, 0x6114, 0x2148,
-	0xa938, 0x918e, 0xffff, 0x0904, 0x90ec, 0x6024, 0xd08c, 0x15c0,
-	0x00e6, 0x6114, 0x2148, 0x080c, 0x8e58, 0x0096, 0xa8a8, 0x2048,
-	0x080c, 0x6b86, 0x009e, 0xa8ab, 0x0000, 0x6010, 0x9005, 0x0128,
-	0x00b6, 0x2058, 0x080c, 0x8f89, 0x00be, 0xae88, 0x00b6, 0x2059,
-	0x0000, 0x080c, 0x8b92, 0x00be, 0x01e0, 0x2071, 0x193c, 0x080c,
-	0x8bd9, 0x01b8, 0x9086, 0x0001, 0x1128, 0x2001, 0x1946, 0x2004,
-	0x9005, 0x1178, 0x0096, 0x080c, 0x1047, 0x2900, 0x009e, 0x0148,
-	0xa8aa, 0x00f6, 0x2c78, 0x080c, 0x8b4d, 0x00fe, 0x00ee, 0x009e,
-	0x0005, 0x080c, 0x8b89, 0x0cd0, 0x080c, 0x91a4, 0x009e, 0x0005,
-	0x9182, 0x0040, 0x0096, 0x0002, 0x9104, 0x9104, 0x9104, 0x9106,
-	0x9104, 0x9104, 0x9104, 0x9126, 0x9104, 0x9104, 0x9104, 0x9104,
-	0x9104, 0x9104, 0x9104, 0x9104, 0x080c, 0x0d7d, 0x6003, 0x0003,
-	0x6106, 0x6014, 0x2048, 0xa8ac, 0xa836, 0xa8b0, 0xa83a, 0xa847,
-	0x0000, 0xa84b, 0x0000, 0xa884, 0x9092, 0x199a, 0x0210, 0x2001,
-	0x1999, 0x8003, 0x8013, 0x8213, 0x9210, 0x621a, 0x080c, 0x1c10,
-	0x2009, 0x8030, 0x080c, 0x92f7, 0x009e, 0x0005, 0x080c, 0x0d7d,
-	0x080c, 0x96d5, 0x6114, 0x2148, 0xa87b, 0x0000, 0x6010, 0x00b6,
-	0x2058, 0xb8bb, 0x0500, 0x00be, 0x080c, 0x6dee, 0x080c, 0xacb0,
-	0x009e, 0x0005, 0x080c, 0xa91e, 0x6144, 0xd1fc, 0x0120, 0xd1ac,
-	0x1110, 0x6003, 0x0003, 0x6000, 0x908a, 0x0016, 0x1a0c, 0x0d7d,
-	0x0096, 0x0023, 0x009e, 0x080c, 0xa93a, 0x0005, 0x915e, 0x915e,
-	0x915e, 0x9160, 0x9171, 0x915e, 0x915e, 0x915e, 0x915e, 0x915e,
-	0x915e, 0x915e, 0x915e, 0x915e, 0x915e, 0x915e, 0x080c, 0x0d7d,
-	0x080c, 0xaab5, 0x6114, 0x2148, 0xa87b, 0x0006, 0x6010, 0x00b6,
-	0x2058, 0xb8bb, 0x0500, 0x00be, 0x080c, 0x6dee, 0x080c, 0xacb0,
-	0x0005, 0x0491, 0x0005, 0x080c, 0xa91e, 0x6000, 0x6144, 0xd1fc,
-	0x0130, 0xd1ac, 0x1120, 0x6003, 0x0003, 0x2009, 0x0003, 0x908a,
-	0x0016, 0x1a0c, 0x0d7d, 0x0096, 0x0033, 0x009e, 0x0106, 0x080c,
-	0xa93a, 0x010e, 0x0005, 0x919b, 0x919b, 0x919b, 0x919d, 0x91a4,
-	0x919b, 0x919b, 0x919b, 0x919b, 0x919b, 0x919b, 0x919b, 0x919b,
-	0x919b, 0x919b, 0x919b, 0x080c, 0x0d7d, 0x0036, 0x00e6, 0x080c,
-	0xaab5, 0x00ee, 0x003e, 0x0005, 0x6024, 0xd08c, 0x11f0, 0x00f6,
-	0x00e6, 0x601b, 0x0000, 0x6014, 0x2048, 0x6010, 0x9005, 0x0128,
-	0x00b6, 0x2058, 0x080c, 0x8f89, 0x00be, 0x2071, 0x193c, 0x080c,
-	0x8bd9, 0x0160, 0x2001, 0x187f, 0x2004, 0xa88a, 0x2031, 0x0000,
-	0x2c78, 0x080c, 0x8b4d, 0x00ee, 0x00fe, 0x0005, 0x0096, 0xa88b,
-	0x0000, 0xa8a8, 0x2048, 0x080c, 0x1079, 0x009e, 0xa8ab, 0x0000,
-	0x080c, 0x8b89, 0x0c80, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
-	0x0000, 0x0000, 0x0000, 0x0000, 0x187a, 0x0000, 0x0000, 0x0000,
-	0x0000, 0x0000, 0x0000, 0x0126, 0x2091, 0x8000, 0x0036, 0x0046,
-	0x20a9, 0x0010, 0x9006, 0x8004, 0x8086, 0x818e, 0x1208, 0x9200,
-	0x1f04, 0x91ec, 0x8086, 0x818e, 0x004e, 0x003e, 0x012e, 0x0005,
-	0x0126, 0x2091, 0x8000, 0x0076, 0x0156, 0x20a9, 0x0010, 0x9005,
-	0x01c8, 0x911a, 0x12b8, 0x8213, 0x818d, 0x0228, 0x911a, 0x1220,
-	0x1f04, 0x9203, 0x0028, 0x911a, 0x2308, 0x8210, 0x1f04, 0x9203,
-	0x0006, 0x3200, 0x9084, 0xefff, 0x2080, 0x000e, 0x015e, 0x007e,
-	0x012e, 0x0005, 0x0006, 0x3200, 0x9085, 0x1000, 0x0ca8, 0x0126,
-	0x2091, 0x2800, 0x2079, 0x19e6, 0x012e, 0x00d6, 0x2069, 0x19e6,
-	0x6803, 0x0005, 0x0156, 0x0146, 0x01d6, 0x20e9, 0x0000, 0x2069,
-	0x0200, 0x080c, 0xa713, 0x04a9, 0x080c, 0xa6fe, 0x0491, 0x080c,
-	0xa701, 0x0479, 0x080c, 0xa704, 0x0461, 0x080c, 0xa707, 0x0449,
-	0x080c, 0xa70a, 0x0431, 0x080c, 0xa70d, 0x0419, 0x080c, 0xa710,
-	0x0401, 0x01de, 0x014e, 0x015e, 0x6857, 0x0000, 0x00f6, 0x2079,
-	0x0380, 0x00f9, 0x7807, 0x0003, 0x7803, 0x0000, 0x7803, 0x0001,
-	0x2069, 0x0004, 0x2d04, 0x9084, 0xfffe, 0x9085, 0x8000, 0x206a,
-	0x2069, 0x0100, 0x6828, 0x9084, 0xfffc, 0x682a, 0x00fe, 0x00de,
+	0x080c, 0x6f19, 0x080c, 0xaf2e, 0x009e, 0x0005, 0x080c, 0xaae0,
+	0x6144, 0xd1fc, 0x0120, 0xd1ac, 0x1110, 0x6003, 0x0003, 0x6000,
+	0x908a, 0x0016, 0x1a0c, 0x0d85, 0x0096, 0x0023, 0x009e, 0x080c,
+	0xaafc, 0x0005, 0x92d2, 0x92d2, 0x92d2, 0x92d4, 0x92e5, 0x92d2,
+	0x92d2, 0x92d2, 0x92d2, 0x92d2, 0x92d2, 0x92d2, 0x92d2, 0x92d2,
+	0x92d2, 0x92d2, 0x080c, 0x0d85, 0x080c, 0xacaf, 0x6114, 0x2148,
+	0xa87b, 0x0006, 0x6010, 0x00b6, 0x2058, 0xb8bb, 0x0500, 0x00be,
+	0x080c, 0x6f19, 0x080c, 0xaf2e, 0x0005, 0x0491, 0x0005, 0x080c,
+	0xaae0, 0x6000, 0x6144, 0xd1fc, 0x0130, 0xd1ac, 0x1120, 0x6003,
+	0x0003, 0x2009, 0x0003, 0x908a, 0x0016, 0x1a0c, 0x0d85, 0x0096,
+	0x0033, 0x009e, 0x0106, 0x080c, 0xaafc, 0x010e, 0x0005, 0x930f,
+	0x930f, 0x930f, 0x9311, 0x9318, 0x930f, 0x930f, 0x930f, 0x930f,
+	0x930f, 0x930f, 0x930f, 0x930f, 0x930f, 0x930f, 0x930f, 0x080c,
+	0x0d85, 0x0036, 0x00e6, 0x080c, 0xacaf, 0x00ee, 0x003e, 0x0005,
+	0x6024, 0xd08c, 0x11f0, 0x00f6, 0x00e6, 0x601b, 0x0000, 0x6014,
+	0x2048, 0x6010, 0x9005, 0x0128, 0x00b6, 0x2058, 0x080c, 0x90fd,
+	0x00be, 0x2071, 0x193e, 0x080c, 0x8d49, 0x0160, 0x2001, 0x187f,
+	0x2004, 0xa88a, 0x2031, 0x0000, 0x2c78, 0x080c, 0x8cbd, 0x00ee,
+	0x00fe, 0x0005, 0x0096, 0xa88b, 0x0000, 0xa8a8, 0x2048, 0x080c,
+	0x108b, 0x009e, 0xa8ab, 0x0000, 0x080c, 0x8cf9, 0x0c80, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+	0x187a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0126,
+	0x2091, 0x8000, 0x0036, 0x0046, 0x20a9, 0x0010, 0x9006, 0x8004,
+	0x8086, 0x818e, 0x1208, 0x9200, 0x1f04, 0x9360, 0x8086, 0x818e,
+	0x004e, 0x003e, 0x012e, 0x0005, 0x0126, 0x2091, 0x8000, 0x0076,
+	0x0156, 0x20a9, 0x0010, 0x9005, 0x01c8, 0x911a, 0x12b8, 0x8213,
+	0x818d, 0x0228, 0x911a, 0x1220, 0x1f04, 0x9377, 0x0028, 0x911a,
+	0x2308, 0x8210, 0x1f04, 0x9377, 0x0006, 0x3200, 0x9084, 0xefff,
+	0x2080, 0x000e, 0x015e, 0x007e, 0x012e, 0x0005, 0x0006, 0x3200,
+	0x9085, 0x1000, 0x0ca8, 0x0126, 0x2091, 0x2800, 0x2079, 0x19e9,
+	0x012e, 0x00d6, 0x2069, 0x19e9, 0x6803, 0x0005, 0x0156, 0x0146,
+	0x01d6, 0x20e9, 0x0000, 0x2069, 0x0200, 0x080c, 0xa8d5, 0x04c9,
+	0x080c, 0xa8c0, 0x04b1, 0x080c, 0xa8c3, 0x0499, 0x080c, 0xa8c6,
+	0x0481, 0x080c, 0xa8c9, 0x0469, 0x080c, 0xa8cc, 0x0451, 0x080c,
+	0xa8cf, 0x0439, 0x080c, 0xa8d2, 0x0421, 0x01de, 0x014e, 0x015e,
+	0x6857, 0x0000, 0x00f6, 0x2079, 0x0380, 0x0419, 0x7807, 0x0003,
+	0x7803, 0x0000, 0x7803, 0x0001, 0x2069, 0x0004, 0x2d04, 0x9084,
+	0xfffe, 0x9085, 0x8000, 0x206a, 0x2069, 0x0100, 0x6828, 0x9084,
+	0xfffc, 0x682a, 0x00fe, 0x2001, 0x1b5e, 0x2003, 0x0000, 0x00de,
 	0x0005, 0x20a9, 0x0020, 0x20a1, 0x0240, 0x2001, 0x0000, 0x4004,
 	0x0005, 0x00c6, 0x7803, 0x0000, 0x9006, 0x7827, 0x0030, 0x782b,
-	0x0400, 0x7827, 0x0031, 0x782b, 0x1af1, 0x781f, 0xff00, 0x781b,
-	0xff00, 0x2061, 0x1ae6, 0x602f, 0x19e6, 0x6033, 0x1800, 0x6037,
-	0x1a02, 0x603b, 0x1eab, 0x603f, 0x1ebb, 0x6042, 0x6047, 0x1abc,
+	0x0400, 0x7827, 0x0031, 0x782b, 0x1af7, 0x781f, 0xff00, 0x781b,
+	0xff00, 0x2061, 0x1aec, 0x602f, 0x19e9, 0x6033, 0x1800, 0x6037,
+	0x1a05, 0x603b, 0x1ee2, 0x603f, 0x1ef2, 0x6042, 0x6047, 0x1ac2,
 	0x00ce, 0x0005, 0x2001, 0x0382, 0x2004, 0x9084, 0x0007, 0x9086,
 	0x0001, 0x01b0, 0x00c6, 0x6146, 0x600f, 0x0000, 0x2c08, 0x2061,
-	0x19e6, 0x602c, 0x8000, 0x602e, 0x601c, 0x9005, 0x0130, 0x9080,
+	0x19e9, 0x602c, 0x8000, 0x602e, 0x601c, 0x9005, 0x0130, 0x9080,
 	0x0003, 0x2102, 0x611e, 0x00ce, 0x0005, 0x6122, 0x611e, 0x0cd8,
-	0x6146, 0x2c08, 0x2001, 0x0012, 0x080c, 0xa90f, 0x0005, 0x0016,
+	0x6146, 0x2c08, 0x2001, 0x0012, 0x080c, 0xaad1, 0x0005, 0x0016,
 	0x2009, 0x8020, 0x6146, 0x2c08, 0x2001, 0x0382, 0x2004, 0x9084,
-	0x0007, 0x9086, 0x0001, 0x1128, 0x2001, 0x0019, 0x080c, 0xa90f,
-	0x0088, 0x00c6, 0x2061, 0x19e6, 0x602c, 0x8000, 0x602e, 0x600c,
+	0x0007, 0x9086, 0x0001, 0x1128, 0x2001, 0x0019, 0x080c, 0xaad1,
+	0x0088, 0x00c6, 0x2061, 0x19e9, 0x602c, 0x8000, 0x602e, 0x600c,
 	0x9005, 0x0128, 0x9080, 0x0003, 0x2102, 0x610e, 0x0010, 0x6112,
 	0x610e, 0x00ce, 0x001e, 0x0005, 0x2001, 0x0382, 0x2004, 0x9084,
 	0x0007, 0x9086, 0x0001, 0x0198, 0x00c6, 0x6146, 0x600f, 0x0000,
-	0x2c08, 0x2061, 0x19e6, 0x6044, 0x9005, 0x0130, 0x9080, 0x0003,
+	0x2c08, 0x2061, 0x19e9, 0x6044, 0x9005, 0x0130, 0x9080, 0x0003,
 	0x2102, 0x6146, 0x00ce, 0x0005, 0x614a, 0x6146, 0x0cd8, 0x6146,
-	0x600f, 0x0000, 0x2c08, 0x2001, 0x0013, 0x080c, 0xa90f, 0x0005,
-	0x6044, 0xd0dc, 0x0110, 0x080c, 0xa3ac, 0x0005, 0x00f6, 0x00e6,
+	0x600f, 0x0000, 0x2c08, 0x2001, 0x0013, 0x080c, 0xaad1, 0x0005,
+	0x6044, 0xd0dc, 0x0110, 0x080c, 0xa56e, 0x0005, 0x00f6, 0x00e6,
 	0x00d6, 0x00c6, 0x00b6, 0x0096, 0x0076, 0x0066, 0x0056, 0x0036,
-	0x0026, 0x0016, 0x0006, 0x0126, 0x902e, 0x2071, 0x19e6, 0x7648,
-	0x2660, 0x2678, 0x2091, 0x8000, 0x8cff, 0x0904, 0x9383, 0x6010,
-	0x2058, 0xb8a0, 0x9206, 0x1904, 0x937e, 0x87ff, 0x0120, 0x605c,
-	0x9106, 0x1904, 0x937e, 0x704c, 0x9c06, 0x1178, 0x0036, 0x2019,
-	0x0001, 0x080c, 0xa1b8, 0x703f, 0x0000, 0x9006, 0x704e, 0x706a,
-	0x7052, 0x706e, 0x003e, 0x2029, 0x0001, 0x0811, 0x7048, 0x9c36,
-	0x1110, 0x660c, 0x764a, 0x7044, 0x9c36, 0x1140, 0x2c00, 0x9f36,
-	0x0118, 0x2f00, 0x7046, 0x0010, 0x7047, 0x0000, 0x660c, 0x0066,
+	0x0026, 0x0016, 0x0006, 0x0126, 0x902e, 0x2071, 0x19e9, 0x7648,
+	0x2660, 0x2678, 0x2091, 0x8000, 0x8cff, 0x0904, 0x9502, 0x9c86,
+	0x1b56, 0x0904, 0x94fd, 0x6010, 0x2058, 0xb8a0, 0x9206, 0x1904,
+	0x94fd, 0x87ff, 0x0120, 0x605c, 0x9106, 0x1904, 0x94fd, 0x704c,
+	0x9c06, 0x1188, 0x0036, 0x2019, 0x0001, 0x080c, 0xa380, 0x703f,
+	0x0000, 0x9006, 0x704e, 0x706a, 0x7052, 0x706e, 0x080c, 0xadc0,
+	0x003e, 0x2029, 0x0001, 0x080c, 0x9478, 0x7048, 0x9c36, 0x1110,
+	0x660c, 0x764a, 0x7044, 0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118,
+	0x2f00, 0x7046, 0x0010, 0x7047, 0x0000, 0x660c, 0x0066, 0x2c00,
+	0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0x080c,
+	0xcc16, 0x01f0, 0x6014, 0x2048, 0x6020, 0x9086, 0x0003, 0x1588,
+	0x6004, 0x9086, 0x0040, 0x090c, 0xa56e, 0xa867, 0x0103, 0xab7a,
+	0xa877, 0x0000, 0x0016, 0x0036, 0x0076, 0x080c, 0xcf1b, 0x080c,
+	0xea83, 0x080c, 0x6f19, 0x007e, 0x003e, 0x001e, 0x080c, 0xce07,
+	0x080c, 0xaf69, 0x00ce, 0x0804, 0x9494, 0x2c78, 0x600c, 0x2060,
+	0x0804, 0x9494, 0x012e, 0x000e, 0x001e, 0x002e, 0x003e, 0x005e,
+	0x006e, 0x007e, 0x009e, 0x00be, 0x00ce, 0x00de, 0x00ee, 0x00fe,
+	0x0005, 0x6020, 0x9086, 0x0006, 0x1158, 0x0016, 0x0036, 0x0076,
+	0x080c, 0xea83, 0x080c, 0xe6cd, 0x007e, 0x003e, 0x001e, 0x08c0,
+	0x6020, 0x9086, 0x0009, 0x1168, 0xa87b, 0x0006, 0x0016, 0x0036,
+	0x0076, 0x080c, 0x6f19, 0x080c, 0xaf2e, 0x007e, 0x003e, 0x001e,
+	0x0848, 0x6020, 0x9086, 0x000a, 0x0904, 0x94e7, 0x0804, 0x94e0,
+	0x0006, 0x0066, 0x0096, 0x00c6, 0x00d6, 0x00f6, 0x9036, 0x0126,
+	0x2091, 0x8000, 0x2079, 0x19e9, 0x7848, 0x9065, 0x0904, 0x95a1,
+	0x600c, 0x0006, 0x600f, 0x0000, 0x784c, 0x9c06, 0x11b0, 0x0036,
+	0x2019, 0x0001, 0x080c, 0xa380, 0x783f, 0x0000, 0x901e, 0x7b4e,
+	0x7b6a, 0x7b52, 0x7b6e, 0x080c, 0xadc0, 0x003e, 0x000e, 0x9005,
+	0x1118, 0x600c, 0x600f, 0x0000, 0x0006, 0x9c86, 0x1b56, 0x05b0,
+	0x00e6, 0x2f70, 0x080c, 0x9478, 0x00ee, 0x080c, 0xcc16, 0x0548,
+	0x6014, 0x2048, 0x6020, 0x9086, 0x0003, 0x15a8, 0x3e08, 0x918e,
+	0x0002, 0x1188, 0x6010, 0x9005, 0x0170, 0x00b6, 0x2058, 0xb800,
+	0x00be, 0xd0bc, 0x0140, 0x6048, 0x9005, 0x11c0, 0x2001, 0x1989,
+	0x2004, 0x604a, 0x0098, 0x6004, 0x9086, 0x0040, 0x090c, 0xa56e,
+	0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0x6f0d, 0x080c,
+	0xce07, 0x6044, 0xc0fc, 0x6046, 0x080c, 0xaf69, 0x000e, 0x0804,
+	0x9545, 0x7e4a, 0x7e46, 0x012e, 0x00fe, 0x00de, 0x00ce, 0x009e,
+	0x006e, 0x000e, 0x0005, 0x6020, 0x9086, 0x0006, 0x1118, 0x080c,
+	0xe6cd, 0x0c38, 0x6020, 0x9086, 0x0009, 0x1130, 0xab7a, 0x080c,
+	0x6f19, 0x080c, 0xaf2e, 0x0c10, 0x6020, 0x9086, 0x000a, 0x0990,
+	0x0850, 0x0016, 0x0026, 0x0086, 0x9046, 0x00a9, 0x080c, 0x96b4,
+	0x008e, 0x002e, 0x001e, 0x0005, 0x00f6, 0x0126, 0x2079, 0x19e9,
+	0x2091, 0x8000, 0x080c, 0x96fd, 0x080c, 0x9793, 0x080c, 0x6916,
+	0x012e, 0x00fe, 0x0005, 0x00b6, 0x0096, 0x00f6, 0x00e6, 0x00d6,
+	0x00c6, 0x0066, 0x0016, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071,
+	0x19e9, 0x7620, 0x2660, 0x2678, 0x8cff, 0x0904, 0x9679, 0x6010,
+	0x2058, 0xb8a0, 0x9206, 0x1904, 0x9674, 0x88ff, 0x0120, 0x605c,
+	0x9106, 0x1904, 0x9674, 0x7030, 0x9c06, 0x1580, 0x2069, 0x0100,
+	0x6820, 0xd0a4, 0x0110, 0xd0cc, 0x1508, 0x080c, 0x88ec, 0x080c,
+	0xa08a, 0x68c3, 0x0000, 0x080c, 0xa56e, 0x7033, 0x0000, 0x0036,
+	0x2069, 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100,
+	0x080c, 0x2abb, 0x9006, 0x080c, 0x2abb, 0x2069, 0x0100, 0x6824,
+	0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x0040, 0x7008, 0xc0ad,
+	0x700a, 0x6003, 0x0009, 0x630a, 0x0804, 0x9674, 0x7020, 0x9c36,
+	0x1110, 0x660c, 0x7622, 0x701c, 0x9c36, 0x1140, 0x2c00, 0x9f36,
+	0x0118, 0x2f00, 0x701e, 0x0010, 0x701f, 0x0000, 0x660c, 0x0066,
 	0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000,
-	0x080c, 0xc97a, 0x01f0, 0x6014, 0x2048, 0x6020, 0x9086, 0x0003,
-	0x1588, 0x6004, 0x9086, 0x0040, 0x090c, 0xa3ac, 0xa867, 0x0103,
-	0xab7a, 0xa877, 0x0000, 0x0016, 0x0036, 0x0076, 0x080c, 0xcc7f,
-	0x080c, 0xe79d, 0x080c, 0x6dee, 0x007e, 0x003e, 0x001e, 0x080c,
-	0xcb6b, 0x080c, 0xaceb, 0x00ce, 0x0804, 0x931c, 0x2c78, 0x600c,
-	0x2060, 0x0804, 0x931c, 0x012e, 0x000e, 0x001e, 0x002e, 0x003e,
-	0x005e, 0x006e, 0x007e, 0x009e, 0x00be, 0x00ce, 0x00de, 0x00ee,
-	0x00fe, 0x0005, 0x6020, 0x9086, 0x0006, 0x1158, 0x0016, 0x0036,
-	0x0076, 0x080c, 0xe79d, 0x080c, 0xe3e8, 0x007e, 0x003e, 0x001e,
-	0x08c0, 0x6020, 0x9086, 0x0009, 0x1168, 0xa87b, 0x0006, 0x0016,
-	0x0036, 0x0076, 0x080c, 0x6dee, 0x080c, 0xacb0, 0x007e, 0x003e,
-	0x001e, 0x0848, 0x6020, 0x9086, 0x000a, 0x0904, 0x9368, 0x0804,
-	0x9361, 0x0006, 0x0066, 0x0096, 0x00c6, 0x00d6, 0x00f6, 0x9036,
-	0x0126, 0x2091, 0x8000, 0x2079, 0x19e6, 0x7848, 0x9065, 0x0904,
-	0x941d, 0x600c, 0x0006, 0x600f, 0x0000, 0x784c, 0x9c06, 0x11a0,
-	0x0036, 0x2019, 0x0001, 0x080c, 0xa1b8, 0x783f, 0x0000, 0x901e,
-	0x7b4e, 0x7b6a, 0x7b52, 0x7b6e, 0x003e, 0x000e, 0x9005, 0x1118,
-	0x600c, 0x600f, 0x0000, 0x0006, 0x00e6, 0x2f70, 0x080c, 0x9300,
-	0x00ee, 0x080c, 0xc97a, 0x0548, 0x6014, 0x2048, 0x6020, 0x9086,
-	0x0003, 0x15a8, 0x3e08, 0x918e, 0x0002, 0x1188, 0x6010, 0x9005,
-	0x0170, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x0140, 0x6048,
-	0x9005, 0x11c0, 0x2001, 0x1987, 0x2004, 0x604a, 0x0098, 0x6004,
-	0x9086, 0x0040, 0x090c, 0xa3ac, 0xa867, 0x0103, 0xab7a, 0xa877,
-	0x0000, 0x080c, 0x6de2, 0x080c, 0xcb6b, 0x6044, 0xc0fc, 0x6046,
-	0x080c, 0xaceb, 0x000e, 0x0804, 0x93c6, 0x7e4a, 0x7e46, 0x012e,
-	0x00fe, 0x00de, 0x00ce, 0x009e, 0x006e, 0x000e, 0x0005, 0x6020,
-	0x9086, 0x0006, 0x1118, 0x080c, 0xe3e8, 0x0c38, 0x6020, 0x9086,
-	0x0009, 0x1130, 0xab7a, 0x080c, 0x6dee, 0x080c, 0xacb0, 0x0c10,
-	0x6020, 0x9086, 0x000a, 0x0990, 0x0850, 0x0016, 0x0026, 0x0086,
-	0x9046, 0x00a9, 0x080c, 0x9530, 0x008e, 0x002e, 0x001e, 0x0005,
-	0x00f6, 0x0126, 0x2079, 0x19e6, 0x2091, 0x8000, 0x080c, 0x9579,
-	0x080c, 0x960f, 0x080c, 0x6820, 0x012e, 0x00fe, 0x0005, 0x00b6,
-	0x0096, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0016, 0x0006,
-	0x0126, 0x2091, 0x8000, 0x2071, 0x19e6, 0x7620, 0x2660, 0x2678,
-	0x8cff, 0x0904, 0x94f5, 0x6010, 0x2058, 0xb8a0, 0x9206, 0x1904,
-	0x94f0, 0x88ff, 0x0120, 0x605c, 0x9106, 0x1904, 0x94f0, 0x7030,
-	0x9c06, 0x1580, 0x2069, 0x0100, 0x6820, 0xd0a4, 0x0110, 0xd0cc,
-	0x1508, 0x080c, 0x8780, 0x080c, 0x9ed4, 0x68c3, 0x0000, 0x080c,
-	0xa3ac, 0x7033, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0x9384,
-	0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2a7a, 0x9006, 0x080c,
-	0x2a7a, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001,
-	0x003e, 0x0040, 0x7008, 0xc0ad, 0x700a, 0x6003, 0x0009, 0x630a,
-	0x0804, 0x94f0, 0x7020, 0x9c36, 0x1110, 0x660c, 0x7622, 0x701c,
-	0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x701e, 0x0010,
-	0x701f, 0x0000, 0x660c, 0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e,
-	0x0008, 0x2678, 0x600f, 0x0000, 0x6044, 0xc0fc, 0x6046, 0x6014,
-	0x2048, 0x080c, 0xc97a, 0x01e8, 0x6020, 0x9086, 0x0003, 0x1580,
-	0x080c, 0xcb91, 0x1118, 0x080c, 0xb693, 0x0098, 0xa867, 0x0103,
-	0xab7a, 0xa877, 0x0000, 0x0016, 0x0036, 0x0086, 0x080c, 0xcc7f,
-	0x080c, 0xe79d, 0x080c, 0x6dee, 0x008e, 0x003e, 0x001e, 0x080c,
-	0xcb6b, 0x080c, 0xaceb, 0x080c, 0xa282, 0x00ce, 0x0804, 0x9468,
-	0x2c78, 0x600c, 0x2060, 0x0804, 0x9468, 0x012e, 0x000e, 0x001e,
-	0x006e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x009e, 0x00be, 0x0005,
-	0x6020, 0x9086, 0x0006, 0x1158, 0x0016, 0x0036, 0x0086, 0x080c,
-	0xe79d, 0x080c, 0xe3e8, 0x008e, 0x003e, 0x001e, 0x08d0, 0x080c,
-	0xb693, 0x6020, 0x9086, 0x0002, 0x1160, 0x6004, 0x0006, 0x9086,
-	0x0085, 0x000e, 0x0904, 0x94d6, 0x9086, 0x008b, 0x0904, 0x94d6,
-	0x0840, 0x6020, 0x9086, 0x0005, 0x1920, 0x6004, 0x0006, 0x9086,
-	0x0085, 0x000e, 0x09c8, 0x9086, 0x008b, 0x09b0, 0x0804, 0x94e9,
-	0x0006, 0x00f6, 0x00e6, 0x0096, 0x00b6, 0x00c6, 0x0066, 0x0016,
-	0x0126, 0x2091, 0x8000, 0x9280, 0x1000, 0x2004, 0x905d, 0x2079,
-	0x19e6, 0x9036, 0x7828, 0x2060, 0x8cff, 0x0538, 0x6010, 0x9b06,
-	0x1500, 0x6043, 0xffff, 0x080c, 0xab00, 0x01d8, 0x610c, 0x0016,
-	0x080c, 0xa042, 0x6014, 0x2048, 0xa867, 0x0103, 0xab7a, 0xa877,
-	0x0000, 0x0016, 0x0036, 0x0086, 0x080c, 0xcc7f, 0x080c, 0xe79d,
-	0x080c, 0x6dee, 0x008e, 0x003e, 0x001e, 0x080c, 0xaceb, 0x00ce,
-	0x08d8, 0x2c30, 0x600c, 0x2060, 0x08b8, 0x080c, 0x683d, 0x012e,
-	0x001e, 0x006e, 0x00ce, 0x00be, 0x009e, 0x00ee, 0x00fe, 0x000e,
-	0x0005, 0x0096, 0x0006, 0x0066, 0x00c6, 0x00d6, 0x9036, 0x7820,
-	0x9065, 0x0904, 0x95e2, 0x600c, 0x0006, 0x6044, 0xc0fc, 0x6046,
-	0x600f, 0x0000, 0x7830, 0x9c06, 0x1598, 0x2069, 0x0100, 0x6820,
-	0xd0a4, 0x0110, 0xd0cc, 0x1508, 0x080c, 0x8780, 0x080c, 0x9ed4,
-	0x68c3, 0x0000, 0x080c, 0xa3ac, 0x7833, 0x0000, 0x0036, 0x2069,
-	0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c,
-	0x2a7a, 0x9006, 0x080c, 0x2a7a, 0x2069, 0x0100, 0x6824, 0xd084,
-	0x0110, 0x6827, 0x0001, 0x003e, 0x0058, 0x080c, 0x6a75, 0x1538,
-	0x6003, 0x0009, 0x630a, 0x7808, 0xc0ad, 0x780a, 0x2c30, 0x00f8,
-	0x6014, 0x2048, 0x080c, 0xc978, 0x01b0, 0x6020, 0x9086, 0x0003,
-	0x1508, 0x080c, 0xcb91, 0x1118, 0x080c, 0xb693, 0x0060, 0x080c,
-	0x6a75, 0x1168, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c,
-	0x6dee, 0x080c, 0xcb6b, 0x080c, 0xaceb, 0x080c, 0xa282, 0x000e,
-	0x0804, 0x9580, 0x7e22, 0x7e1e, 0x00de, 0x00ce, 0x006e, 0x000e,
-	0x009e, 0x0005, 0x6020, 0x9086, 0x0006, 0x1118, 0x080c, 0xe3e8,
-	0x0c50, 0x080c, 0xb693, 0x6020, 0x9086, 0x0002, 0x1150, 0x6004,
-	0x0006, 0x9086, 0x0085, 0x000e, 0x0990, 0x9086, 0x008b, 0x0978,
-	0x08d0, 0x6020, 0x9086, 0x0005, 0x19b0, 0x6004, 0x0006, 0x9086,
-	0x0085, 0x000e, 0x0d18, 0x9086, 0x008b, 0x0d00, 0x0860, 0x0006,
-	0x0096, 0x00b6, 0x00c6, 0x0066, 0x9036, 0x7828, 0x9065, 0x0510,
-	0x6010, 0x2058, 0x600c, 0x0006, 0x3e08, 0x918e, 0x0002, 0x1118,
-	0xb800, 0xd0bc, 0x11a8, 0x6043, 0xffff, 0x080c, 0xab00, 0x0180,
-	0x610c, 0x080c, 0xa042, 0x6014, 0x2048, 0xa867, 0x0103, 0xab7a,
-	0xa877, 0x0000, 0x080c, 0x6dee, 0x080c, 0xaceb, 0x000e, 0x08f0,
-	0x2c30, 0x0ce0, 0x006e, 0x00ce, 0x00be, 0x009e, 0x000e, 0x0005,
-	0x00e6, 0x00d6, 0x0096, 0x0066, 0x080c, 0x61a4, 0x11b0, 0x2071,
-	0x19e6, 0x7030, 0x9080, 0x0005, 0x2004, 0x904d, 0x0170, 0xa878,
-	0x9606, 0x1158, 0x2071, 0x19e6, 0x7030, 0x9035, 0x0130, 0x9080,
-	0x0005, 0x2004, 0x9906, 0x1108, 0x0029, 0x006e, 0x009e, 0x00de,
-	0x00ee, 0x0005, 0x00c6, 0x2660, 0x6043, 0xffff, 0x080c, 0xab00,
-	0x0178, 0x080c, 0xa042, 0x6014, 0x2048, 0xa867, 0x0103, 0xab7a,
-	0xa877, 0x0000, 0x080c, 0xcc7f, 0x080c, 0x6dee, 0x080c, 0xaceb,
-	0x00ce, 0x0005, 0x00b6, 0x00e6, 0x00c6, 0x080c, 0xa91e, 0x0106,
-	0x2071, 0x0101, 0x2e04, 0xc0c4, 0x2072, 0x6044, 0xd0fc, 0x1138,
-	0x010e, 0x090c, 0xa93a, 0x00ce, 0x00ee, 0x00be, 0x0005, 0x2071,
-	0x19e6, 0x7030, 0x9005, 0x0da0, 0x9c06, 0x190c, 0x0d7d, 0x7036,
-	0x080c, 0x8780, 0x7004, 0x9084, 0x0007, 0x0002, 0x96a8, 0x96aa,
-	0x96b1, 0x96bb, 0x96c9, 0x96a8, 0x96b6, 0x96a6, 0x080c, 0x0d7d,
-	0x0428, 0x0005, 0x080c, 0xaaeb, 0x7007, 0x0000, 0x7033, 0x0000,
-	0x00e8, 0x0066, 0x9036, 0x080c, 0xa042, 0x006e, 0x7007, 0x0000,
-	0x7033, 0x0000, 0x0098, 0x080c, 0xaad6, 0x0140, 0x080c, 0xaaeb,
-	0x0128, 0x0066, 0x9036, 0x080c, 0xa042, 0x006e, 0x7033, 0x0000,
-	0x0028, 0x080c, 0xaad6, 0x080c, 0xa3ac, 0x0000, 0x010e, 0x090c,
-	0xa93a, 0x00ce, 0x00ee, 0x00be, 0x0005, 0x00d6, 0x00c6, 0x080c,
-	0xa91e, 0x0106, 0x6044, 0xd0fc, 0x1130, 0x010e, 0x090c, 0xa93a,
-	0x00ce, 0x00de, 0x0005, 0x2069, 0x19e6, 0x684c, 0x9005, 0x0da8,
-	0x9c06, 0x190c, 0x0d7d, 0x6852, 0x00e6, 0x2d70, 0x080c, 0x9300,
-	0x00ee, 0x080c, 0x878d, 0x0016, 0x2009, 0x0040, 0x080c, 0x220a,
-	0x001e, 0x683c, 0x9084, 0x0003, 0x0002, 0x9703, 0x9704, 0x9722,
-	0x9701, 0x080c, 0x0d7d, 0x0460, 0x6868, 0x9086, 0x0001, 0x0190,
-	0x600c, 0x9015, 0x0160, 0x6a4a, 0x600f, 0x0000, 0x6044, 0xc0fc,
-	0x6046, 0x9006, 0x7042, 0x684e, 0x683f, 0x0000, 0x00c8, 0x684a,
-	0x6846, 0x0ca0, 0x686b, 0x0000, 0x6848, 0x9065, 0x0d78, 0x6003,
-	0x0002, 0x0c60, 0x9006, 0x686a, 0x6852, 0x686e, 0x600c, 0x9015,
-	0x0120, 0x6a4a, 0x600f, 0x0000, 0x0018, 0x684e, 0x684a, 0x6846,
-	0x684f, 0x0000, 0x010e, 0x090c, 0xa93a, 0x00ce, 0x00de, 0x0005,
-	0x0005, 0x6020, 0x9084, 0x000f, 0x000b, 0x0005, 0x974e, 0x9751,
-	0x9bbf, 0x9c58, 0x9751, 0x9bbf, 0x9c58, 0x974e, 0x9751, 0x974e,
-	0x974e, 0x974e, 0x974e, 0x974e, 0x974e, 0x974e, 0x080c, 0x967a,
-	0x0005, 0x00b6, 0x0156, 0x0136, 0x0146, 0x01c6, 0x01d6, 0x00c6,
-	0x00d6, 0x00e6, 0x00f6, 0x2069, 0x0200, 0x2071, 0x0240, 0x6004,
-	0x908a, 0x0053, 0x1a0c, 0x0d7d, 0x6110, 0x2158, 0xb984, 0x2c78,
-	0x2061, 0x0100, 0x619a, 0x908a, 0x0040, 0x1a04, 0x97bd, 0x005b,
-	0x00fe, 0x00ee, 0x00de, 0x00ce, 0x01de, 0x01ce, 0x014e, 0x013e,
-	0x015e, 0x00be, 0x0005, 0x9942, 0x997d, 0x99a6, 0x9a4e, 0x9a70,
-	0x9a76, 0x9a83, 0x9a8b, 0x9a97, 0x9a9d, 0x9aae, 0x9a9d, 0x9b06,
-	0x9a8b, 0x9b12, 0x9b18, 0x9a97, 0x9b18, 0x9b24, 0x97bb, 0x97bb,
-	0x97bb, 0x97bb, 0x97bb, 0x97bb, 0x97bb, 0x97bb, 0x97bb, 0x97bb,
-	0x97bb, 0xa063, 0xa086, 0xa097, 0xa0b7, 0xa0e9, 0x9a83, 0x97bb,
-	0x9a83, 0x9a9d, 0x97bb, 0x99a6, 0x9a4e, 0x97bb, 0xa4aa, 0x9a9d,
-	0x97bb, 0xa4c6, 0x9a9d, 0x97bb, 0x9a97, 0x993c, 0x97de, 0x97bb,
-	0xa4e2, 0xa54f, 0xa633, 0x97bb, 0xa640, 0x9a80, 0xa66b, 0x97bb,
-	0xa0f3, 0xa677, 0x97bb, 0x080c, 0x0d7d, 0x2100, 0x005b, 0x00fe,
+	0x6044, 0xc0fc, 0x6046, 0x6014, 0x2048, 0x080c, 0xcc16, 0x01e8,
+	0x6020, 0x9086, 0x0003, 0x1580, 0x080c, 0xce2d, 0x1118, 0x080c,
+	0xb91f, 0x0098, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x0016,
+	0x0036, 0x0086, 0x080c, 0xcf1b, 0x080c, 0xea83, 0x080c, 0x6f19,
+	0x008e, 0x003e, 0x001e, 0x080c, 0xce07, 0x080c, 0xaf69, 0x080c,
+	0xa441, 0x00ce, 0x0804, 0x95ec, 0x2c78, 0x600c, 0x2060, 0x0804,
+	0x95ec, 0x012e, 0x000e, 0x001e, 0x006e, 0x00ce, 0x00de, 0x00ee,
+	0x00fe, 0x009e, 0x00be, 0x0005, 0x6020, 0x9086, 0x0006, 0x1158,
+	0x0016, 0x0036, 0x0086, 0x080c, 0xea83, 0x080c, 0xe6cd, 0x008e,
+	0x003e, 0x001e, 0x08d0, 0x080c, 0xb91f, 0x6020, 0x9086, 0x0002,
+	0x1160, 0x6004, 0x0006, 0x9086, 0x0085, 0x000e, 0x0904, 0x965a,
+	0x9086, 0x008b, 0x0904, 0x965a, 0x0840, 0x6020, 0x9086, 0x0005,
+	0x1920, 0x6004, 0x0006, 0x9086, 0x0085, 0x000e, 0x09c8, 0x9086,
+	0x008b, 0x09b0, 0x0804, 0x966d, 0x0006, 0x00f6, 0x00e6, 0x0096,
+	0x00b6, 0x00c6, 0x0066, 0x0016, 0x0126, 0x2091, 0x8000, 0x9280,
+	0x1000, 0x2004, 0x905d, 0x2079, 0x19e9, 0x9036, 0x7828, 0x2060,
+	0x8cff, 0x0538, 0x6010, 0x9b06, 0x1500, 0x6043, 0xffff, 0x080c,
+	0xacfa, 0x01d8, 0x610c, 0x0016, 0x080c, 0xa20a, 0x6014, 0x2048,
+	0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x0016, 0x0036, 0x0086,
+	0x080c, 0xcf1b, 0x080c, 0xea83, 0x080c, 0x6f19, 0x008e, 0x003e,
+	0x001e, 0x080c, 0xaf69, 0x00ce, 0x08d8, 0x2c30, 0x600c, 0x2060,
+	0x08b8, 0x080c, 0x6933, 0x012e, 0x001e, 0x006e, 0x00ce, 0x00be,
+	0x009e, 0x00ee, 0x00fe, 0x000e, 0x0005, 0x0096, 0x0006, 0x0066,
+	0x00c6, 0x00d6, 0x9036, 0x7820, 0x9065, 0x0904, 0x9766, 0x600c,
+	0x0006, 0x6044, 0xc0fc, 0x6046, 0x600f, 0x0000, 0x7830, 0x9c06,
+	0x1598, 0x2069, 0x0100, 0x6820, 0xd0a4, 0x0110, 0xd0cc, 0x1508,
+	0x080c, 0x88ec, 0x080c, 0xa08a, 0x68c3, 0x0000, 0x080c, 0xa56e,
+	0x7833, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0x9384, 0x1000,
+	0x0138, 0x2001, 0x0100, 0x080c, 0x2abb, 0x9006, 0x080c, 0x2abb,
+	0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x003e,
+	0x0058, 0x080c, 0x6b6d, 0x1538, 0x6003, 0x0009, 0x630a, 0x7808,
+	0xc0ad, 0x780a, 0x2c30, 0x00f8, 0x6014, 0x2048, 0x080c, 0xcc14,
+	0x01b0, 0x6020, 0x9086, 0x0003, 0x1508, 0x080c, 0xce2d, 0x1118,
+	0x080c, 0xb91f, 0x0060, 0x080c, 0x6b6d, 0x1168, 0xa867, 0x0103,
+	0xab7a, 0xa877, 0x0000, 0x080c, 0x6f19, 0x080c, 0xce07, 0x080c,
+	0xaf69, 0x080c, 0xa441, 0x000e, 0x0804, 0x9704, 0x7e22, 0x7e1e,
+	0x00de, 0x00ce, 0x006e, 0x000e, 0x009e, 0x0005, 0x6020, 0x9086,
+	0x0006, 0x1118, 0x080c, 0xe6cd, 0x0c50, 0x080c, 0xb91f, 0x6020,
+	0x9086, 0x0002, 0x1150, 0x6004, 0x0006, 0x9086, 0x0085, 0x000e,
+	0x0990, 0x9086, 0x008b, 0x0978, 0x08d0, 0x6020, 0x9086, 0x0005,
+	0x19b0, 0x6004, 0x0006, 0x9086, 0x0085, 0x000e, 0x0d18, 0x9086,
+	0x008b, 0x0d00, 0x0860, 0x0006, 0x0096, 0x00b6, 0x00c6, 0x0066,
+	0x9036, 0x7828, 0x9065, 0x0510, 0x6010, 0x2058, 0x600c, 0x0006,
+	0x3e08, 0x918e, 0x0002, 0x1118, 0xb800, 0xd0bc, 0x11a8, 0x6043,
+	0xffff, 0x080c, 0xacfa, 0x0180, 0x610c, 0x080c, 0xa20a, 0x6014,
+	0x2048, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0x6f19,
+	0x080c, 0xaf69, 0x000e, 0x08f0, 0x2c30, 0x0ce0, 0x006e, 0x00ce,
+	0x00be, 0x009e, 0x000e, 0x0005, 0x00e6, 0x00d6, 0x0096, 0x0066,
+	0x080c, 0x6290, 0x11b0, 0x2071, 0x19e9, 0x7030, 0x9080, 0x0005,
+	0x2004, 0x904d, 0x0170, 0xa878, 0x9606, 0x1158, 0x2071, 0x19e9,
+	0x7030, 0x9035, 0x0130, 0x9080, 0x0005, 0x2004, 0x9906, 0x1108,
+	0x0029, 0x006e, 0x009e, 0x00de, 0x00ee, 0x0005, 0x00c6, 0x2660,
+	0x6043, 0xffff, 0x080c, 0xacfa, 0x0178, 0x080c, 0xa20a, 0x6014,
+	0x2048, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0xcf1b,
+	0x080c, 0x6f19, 0x080c, 0xaf69, 0x00ce, 0x0005, 0x00b6, 0x00e6,
+	0x00c6, 0x080c, 0xaae0, 0x0106, 0x2071, 0x0101, 0x2e04, 0xc0c4,
+	0x2072, 0x6044, 0xd0fc, 0x1138, 0x010e, 0x090c, 0xaafc, 0x00ce,
+	0x00ee, 0x00be, 0x0005, 0x2071, 0x19e9, 0x7030, 0x9005, 0x0da0,
+	0x9c06, 0x190c, 0x0d85, 0x7036, 0x080c, 0x88ec, 0x7004, 0x9084,
+	0x0007, 0x0002, 0x982c, 0x982e, 0x9835, 0x983f, 0x984d, 0x982c,
+	0x983a, 0x982a, 0x080c, 0x0d85, 0x0428, 0x0005, 0x080c, 0xace5,
+	0x7007, 0x0000, 0x7033, 0x0000, 0x00e8, 0x0066, 0x9036, 0x080c,
+	0xa20a, 0x006e, 0x7007, 0x0000, 0x7033, 0x0000, 0x0098, 0x080c,
+	0xacd0, 0x0140, 0x080c, 0xace5, 0x0128, 0x0066, 0x9036, 0x080c,
+	0xa20a, 0x006e, 0x7033, 0x0000, 0x0028, 0x080c, 0xacd0, 0x080c,
+	0xa56e, 0x0000, 0x010e, 0x090c, 0xaafc, 0x00ce, 0x00ee, 0x00be,
+	0x0005, 0x00d6, 0x00c6, 0x080c, 0xaae0, 0x0106, 0x6044, 0xd0fc,
+	0x1130, 0x010e, 0x090c, 0xaafc, 0x00ce, 0x00de, 0x0005, 0x2069,
+	0x19e9, 0x684c, 0x9005, 0x0da8, 0x9c06, 0x190c, 0x0d85, 0x6852,
+	0x00e6, 0x2d70, 0x080c, 0x9478, 0x00ee, 0x080c, 0x88f9, 0x0016,
+	0x2009, 0x0040, 0x080c, 0x2241, 0x001e, 0x683c, 0x9084, 0x0003,
+	0x0002, 0x9887, 0x9888, 0x98a7, 0x9885, 0x080c, 0x0d85, 0x0468,
+	0x6868, 0x9086, 0x0001, 0x0198, 0x600c, 0x9015, 0x0168, 0x6a4a,
+	0x600f, 0x0000, 0x6044, 0x9084, 0x7f7f, 0x6046, 0x9006, 0x7042,
+	0x684e, 0x683f, 0x0000, 0x00c8, 0x684a, 0x6846, 0x0c98, 0x686b,
+	0x0000, 0x6848, 0x9065, 0x0d70, 0x6003, 0x0002, 0x0c58, 0x9006,
+	0x686a, 0x6852, 0x686e, 0x600c, 0x9015, 0x0120, 0x6a4a, 0x600f,
+	0x0000, 0x0018, 0x684e, 0x684a, 0x6846, 0x080c, 0xadc0, 0x684f,
+	0x0000, 0x010e, 0x090c, 0xaafc, 0x00ce, 0x00de, 0x0005, 0x0005,
+	0x6020, 0x9084, 0x000f, 0x000b, 0x0005, 0x98d5, 0x98d8, 0x9d6a,
+	0x9e03, 0x98d8, 0x9d6a, 0x9e03, 0x98d5, 0x98d8, 0x98d5, 0x98d5,
+	0x98d5, 0x98d5, 0x98d5, 0x98d5, 0x98d5, 0x080c, 0x97fe, 0x0005,
+	0x00b6, 0x0156, 0x0136, 0x0146, 0x01c6, 0x01d6, 0x00c6, 0x00d6,
+	0x00e6, 0x00f6, 0x2069, 0x0200, 0x2071, 0x0240, 0x6004, 0x908a,
+	0x0053, 0x1a0c, 0x0d85, 0x6110, 0x2158, 0xb984, 0x2c78, 0x2061,
+	0x0100, 0x619a, 0x908a, 0x0040, 0x1a04, 0x9944, 0x005b, 0x00fe,
 	0x00ee, 0x00de, 0x00ce, 0x01de, 0x01ce, 0x014e, 0x013e, 0x015e,
-	0x00be, 0x0005, 0xa717, 0xa7c9, 0x97dc, 0x9805, 0x98b1, 0x98bc,
-	0x97dc, 0x9a83, 0x97dc, 0x9903, 0x990f, 0x9820, 0x97dc, 0x983b,
-	0x986f, 0xab56, 0xab9b, 0x9a9d, 0x080c, 0x0d7d, 0x00d6, 0x0096,
-	0x080c, 0x9b37, 0x7003, 0x2414, 0x7007, 0x0018, 0x700b, 0x0800,
-	0x7814, 0x2048, 0xa83c, 0x700e, 0xa850, 0x7022, 0xa854, 0x7026,
-	0x60c3, 0x0018, 0x080c, 0x9ea4, 0x009e, 0x00de, 0x0005, 0x7810,
-	0x00b6, 0x2058, 0xb8a0, 0x00be, 0x080c, 0xabe2, 0x1118, 0x9084,
+	0x00be, 0x0005, 0x9aed, 0x9b28, 0x9b51, 0x9bf9, 0x9c1b, 0x9c21,
+	0x9c2e, 0x9c36, 0x9c42, 0x9c48, 0x9c59, 0x9c48, 0x9cb1, 0x9c36,
+	0x9cbd, 0x9cc3, 0x9c42, 0x9cc3, 0x9ccf, 0x9942, 0x9942, 0x9942,
+	0x9942, 0x9942, 0x9942, 0x9942, 0x9942, 0x9942, 0x9942, 0x9942,
+	0xa22b, 0xa24e, 0xa25f, 0xa27f, 0xa2b1, 0x9c2e, 0x9942, 0x9c2e,
+	0x9c48, 0x9942, 0x9b51, 0x9bf9, 0x9942, 0xa66c, 0x9c48, 0x9942,
+	0xa688, 0x9c48, 0x9942, 0x9c42, 0x9ae7, 0x9965, 0x9942, 0xa6a4,
+	0xa711, 0xa7f5, 0x9942, 0xa802, 0x9c2b, 0xa82d, 0x9942, 0xa2bb,
+	0xa839, 0x9942, 0x080c, 0x0d85, 0x2100, 0x005b, 0x00fe, 0x00ee,
+	0x00de, 0x00ce, 0x01de, 0x01ce, 0x014e, 0x013e, 0x015e, 0x00be,
+	0x0005, 0xa8d9, 0xa98b, 0x9963, 0x999d, 0x9a49, 0x9a54, 0x9963,
+	0x9c2e, 0x9963, 0x9aae, 0x9aba, 0x99b8, 0x9963, 0x99d3, 0x9a07,
+	0xadd4, 0xae19, 0x9c48, 0x080c, 0x0d85, 0x00d6, 0x0096, 0x080c,
+	0x9ce2, 0x0026, 0x0036, 0x7814, 0x2048, 0xa958, 0xd1cc, 0x1138,
+	0x2009, 0x2414, 0x2011, 0x0018, 0x2019, 0x0018, 0x0030, 0x2009,
+	0x2410, 0x2011, 0x0014, 0x2019, 0x0014, 0x7102, 0x7206, 0x700b,
+	0x0800, 0xa83c, 0x700e, 0xa850, 0x7022, 0xa854, 0x7026, 0x63c2,
+	0x080c, 0xa05a, 0x003e, 0x002e, 0x009e, 0x00de, 0x0005, 0x7810,
+	0x00b6, 0x2058, 0xb8a0, 0x00be, 0x080c, 0xae60, 0x1118, 0x9084,
 	0xff80, 0x0110, 0x9085, 0x0001, 0x0005, 0x00d6, 0x0096, 0x080c,
-	0x9b37, 0x7003, 0x0500, 0x7814, 0x2048, 0xa874, 0x700a, 0xa878,
+	0x9ce2, 0x7003, 0x0500, 0x7814, 0x2048, 0xa874, 0x700a, 0xa878,
 	0x700e, 0xa87c, 0x7012, 0xa880, 0x7016, 0xa884, 0x701a, 0xa888,
-	0x701e, 0x60c3, 0x0010, 0x080c, 0x9ea4, 0x009e, 0x00de, 0x0005,
-	0x00d6, 0x0096, 0x080c, 0x9b37, 0x7003, 0x0500, 0x7814, 0x2048,
+	0x701e, 0x60c3, 0x0010, 0x080c, 0xa05a, 0x009e, 0x00de, 0x0005,
+	0x00d6, 0x0096, 0x080c, 0x9ce2, 0x7003, 0x0500, 0x7814, 0x2048,
 	0xa8cc, 0x700a, 0xa8d0, 0x700e, 0xa8d4, 0x7012, 0xa8d8, 0x7016,
-	0xa8dc, 0x701a, 0xa8e0, 0x701e, 0x60c3, 0x0010, 0x080c, 0x9ea4,
+	0xa8dc, 0x701a, 0xa8e0, 0x701e, 0x60c3, 0x0010, 0x080c, 0xa05a,
 	0x009e, 0x00de, 0x0005, 0x00d6, 0x0096, 0x0126, 0x2091, 0x8000,
-	0x080c, 0x9b37, 0x20e9, 0x0000, 0x2001, 0x19a2, 0x2003, 0x0000,
+	0x080c, 0x9ce2, 0x20e9, 0x0000, 0x2001, 0x19a4, 0x2003, 0x0000,
 	0x7814, 0x2048, 0xa814, 0x8003, 0x60c2, 0xa830, 0x20a8, 0xa860,
-	0x20e0, 0xa85c, 0x9080, 0x001b, 0x2098, 0x2001, 0x19a2, 0x0016,
-	0x200c, 0x2001, 0x0001, 0x080c, 0x21ef, 0x080c, 0xd72b, 0x9006,
-	0x080c, 0x21ef, 0x001e, 0xa804, 0x9005, 0x0110, 0x2048, 0x0c28,
-	0x04d9, 0x080c, 0x9ea4, 0x012e, 0x009e, 0x00de, 0x0005, 0x00d6,
-	0x0096, 0x0126, 0x2091, 0x8000, 0x080c, 0x9b82, 0x20e9, 0x0000,
-	0x2001, 0x19a2, 0x2003, 0x0000, 0x7814, 0x2048, 0xa86f, 0x0200,
+	0x20e0, 0xa85c, 0x9080, 0x001b, 0x2098, 0x2001, 0x19a4, 0x0016,
+	0x200c, 0x2001, 0x0001, 0x080c, 0x2226, 0x080c, 0xd9e6, 0x9006,
+	0x080c, 0x2226, 0x001e, 0xa804, 0x9005, 0x0110, 0x2048, 0x0c28,
+	0x04d9, 0x080c, 0xa05a, 0x012e, 0x009e, 0x00de, 0x0005, 0x00d6,
+	0x0096, 0x0126, 0x2091, 0x8000, 0x080c, 0x9d2d, 0x20e9, 0x0000,
+	0x2001, 0x19a4, 0x2003, 0x0000, 0x7814, 0x2048, 0xa86f, 0x0200,
 	0xa873, 0x0000, 0xa814, 0x8003, 0x60c2, 0xa830, 0x20a8, 0xa860,
-	0x20e0, 0xa85c, 0x9080, 0x001b, 0x2098, 0x2001, 0x19a2, 0x0016,
-	0x200c, 0x080c, 0xd72b, 0x001e, 0xa804, 0x9005, 0x0110, 0x2048,
-	0x0c60, 0x0051, 0x7814, 0x2048, 0x080c, 0x0ff9, 0x080c, 0x9ea4,
+	0x20e0, 0xa85c, 0x9080, 0x001b, 0x2098, 0x2001, 0x19a4, 0x0016,
+	0x200c, 0x080c, 0xd9e6, 0x001e, 0xa804, 0x9005, 0x0110, 0x2048,
+	0x0c60, 0x0051, 0x7814, 0x2048, 0x080c, 0x100b, 0x080c, 0xa05a,
 	0x012e, 0x009e, 0x00de, 0x0005, 0x60c0, 0x8004, 0x9084, 0x0003,
 	0x9005, 0x0130, 0x9082, 0x0004, 0x20a3, 0x0000, 0x8000, 0x1de0,
-	0x0005, 0x080c, 0x9b37, 0x7003, 0x7800, 0x7808, 0x8007, 0x700a,
-	0x60c3, 0x0008, 0x0804, 0x9ea4, 0x00d6, 0x00e6, 0x080c, 0x9b82,
-	0x7814, 0x9084, 0xff00, 0x2073, 0x0200, 0x8e70, 0x8e70, 0x9095,
-	0x0010, 0x2272, 0x8e70, 0x2073, 0x0034, 0x8e70, 0x2069, 0x1805,
-	0x20a9, 0x0004, 0x2d76, 0x8d68, 0x8e70, 0x1f04, 0x98d2, 0x2069,
-	0x1801, 0x20a9, 0x0004, 0x2d76, 0x8d68, 0x8e70, 0x1f04, 0x98db,
-	0x2069, 0x19b2, 0x9086, 0xdf00, 0x0110, 0x2069, 0x19cc, 0x20a9,
-	0x001a, 0x9e86, 0x0260, 0x1148, 0x00c6, 0x2061, 0x0200, 0x6010,
-	0x8000, 0x6012, 0x00ce, 0x2071, 0x0240, 0x2d04, 0x8007, 0x2072,
-	0x8d68, 0x8e70, 0x1f04, 0x98e9, 0x60c3, 0x004c, 0x080c, 0x9ea4,
-	0x00ee, 0x00de, 0x0005, 0x080c, 0x9b37, 0x7003, 0x6300, 0x7007,
-	0x0028, 0x7808, 0x700e, 0x60c3, 0x0008, 0x0804, 0x9ea4, 0x00d6,
-	0x0026, 0x0016, 0x080c, 0x9b82, 0x7003, 0x0200, 0x7814, 0x700e,
-	0x00e6, 0x9ef0, 0x0004, 0x2009, 0x0001, 0x2011, 0x000c, 0x2069,
-	0x1923, 0x6810, 0xd084, 0x1148, 0x2073, 0x0500, 0x8e70, 0x2073,
-	0x0000, 0x8e70, 0x8108, 0x9290, 0x0004, 0x2073, 0x0800, 0x8e70,
-	0x2073, 0x0000, 0x00ee, 0x7206, 0x710a, 0x62c2, 0x080c, 0x9ea4,
-	0x001e, 0x002e, 0x00de, 0x0005, 0x2001, 0x1818, 0x2004, 0x609a,
-	0x0804, 0x9ea4, 0x080c, 0x9b37, 0x7003, 0x5200, 0x2069, 0x1847,
-	0x6804, 0xd084, 0x0130, 0x6828, 0x0016, 0x080c, 0x2694, 0x710e,
-	0x001e, 0x20a9, 0x0004, 0x20e1, 0x0001, 0x2099, 0x1805, 0x20e9,
-	0x0000, 0x20a1, 0x0250, 0x4003, 0x20a9, 0x0004, 0x2099, 0x1801,
-	0x20a1, 0x0254, 0x4003, 0x080c, 0xabe2, 0x1120, 0xb8a0, 0x9082,
-	0x007f, 0x0248, 0x2001, 0x181f, 0x2004, 0x7032, 0x2001, 0x1820,
-	0x2004, 0x7036, 0x0030, 0x2001, 0x1818, 0x2004, 0x9084, 0x00ff,
-	0x7036, 0x60c3, 0x001c, 0x0804, 0x9ea4, 0x080c, 0x9b37, 0x7003,
-	0x0500, 0x080c, 0xabe2, 0x1120, 0xb8a0, 0x9082, 0x007f, 0x0248,
-	0x2001, 0x181f, 0x2004, 0x700a, 0x2001, 0x1820, 0x2004, 0x700e,
-	0x0030, 0x2001, 0x1818, 0x2004, 0x9084, 0x00ff, 0x700e, 0x20a9,
-	0x0004, 0x20e1, 0x0001, 0x2099, 0x1805, 0x20e9, 0x0000, 0x20a1,
-	0x0250, 0x4003, 0x60c3, 0x0010, 0x0804, 0x9ea4, 0x080c, 0x9b37,
-	0x9006, 0x080c, 0x6aa7, 0xb8a0, 0x9086, 0x007e, 0x1130, 0x7003,
-	0x0400, 0x620c, 0xc2b4, 0x620e, 0x0058, 0x7814, 0x0096, 0x904d,
-	0x0120, 0x9006, 0xa89a, 0xa8a6, 0xa8aa, 0x009e, 0x7003, 0x0300,
-	0xb8a0, 0x9086, 0x007e, 0x1904, 0x9a15, 0x00d6, 0x2069, 0x196b,
-	0x2001, 0x1837, 0x2004, 0xd0a4, 0x0188, 0x6800, 0x700a, 0x6808,
-	0x9084, 0x2000, 0x7012, 0x080c, 0xabf9, 0x680c, 0x7016, 0x701f,
-	0x2710, 0x6818, 0x7022, 0x681c, 0x7026, 0x0090, 0x6800, 0x700a,
-	0x6804, 0x700e, 0x6808, 0x080c, 0x753d, 0x1118, 0x9084, 0x37ff,
-	0x0010, 0x9084, 0x3fff, 0x7012, 0x080c, 0xabf9, 0x680c, 0x7016,
-	0x00de, 0x20a9, 0x0004, 0x20e1, 0x0001, 0x2099, 0x1805, 0x20e9,
-	0x0000, 0x20a1, 0x0256, 0x4003, 0x20a9, 0x0004, 0x2099, 0x1801,
-	0x20a1, 0x025a, 0x4003, 0x00d6, 0x080c, 0xa6fe, 0x2069, 0x1973,
-	0x2071, 0x024e, 0x6800, 0xc0dd, 0x7002, 0x080c, 0x5742, 0xd0e4,
-	0x0110, 0x680c, 0x700e, 0x00de, 0x04a8, 0x2001, 0x1837, 0x2004,
-	0xd0a4, 0x0170, 0x0016, 0x2001, 0x196c, 0x200c, 0x60e0, 0x9106,
-	0x0130, 0x2100, 0x60e3, 0x0000, 0x080c, 0x26d5, 0x61e2, 0x001e,
-	0x20e1, 0x0001, 0x2099, 0x196b, 0x20e9, 0x0000, 0x20a1, 0x024e,
-	0x20a9, 0x0008, 0x4003, 0x20a9, 0x0004, 0x2099, 0x1805, 0x20a1,
-	0x0256, 0x4003, 0x20a9, 0x0004, 0x2099, 0x1801, 0x20a1, 0x025a,
-	0x4003, 0x080c, 0xa6fe, 0x20a1, 0x024e, 0x20a9, 0x0008, 0x2099,
-	0x1973, 0x4003, 0x60c3, 0x0074, 0x0804, 0x9ea4, 0x080c, 0x9b37,
-	0x7003, 0x2010, 0x7007, 0x0014, 0x700b, 0x0800, 0x700f, 0x2000,
-	0x9006, 0x00f6, 0x2079, 0x1847, 0x7904, 0x00fe, 0xd1ac, 0x1110,
-	0x9085, 0x0020, 0xd1a4, 0x0110, 0x9085, 0x0010, 0x9085, 0x0002,
-	0x00d6, 0x0804, 0x9ae7, 0x7026, 0x60c3, 0x0014, 0x0804, 0x9ea4,
-	0x080c, 0x9b37, 0x7003, 0x5000, 0x0804, 0x99c0, 0x080c, 0x9b37,
-	0x7003, 0x2110, 0x7007, 0x0014, 0x60c3, 0x0014, 0x0804, 0x9ea4,
-	0x080c, 0x9b79, 0x0010, 0x080c, 0x9b82, 0x7003, 0x0200, 0x60c3,
-	0x0004, 0x0804, 0x9ea4, 0x080c, 0x9b82, 0x7003, 0x0100, 0x700b,
-	0x0003, 0x700f, 0x2a00, 0x60c3, 0x0008, 0x0804, 0x9ea4, 0x080c,
-	0x9b82, 0x7003, 0x0200, 0x0804, 0x99c0, 0x080c, 0x9b82, 0x7003,
-	0x0100, 0x782c, 0x9005, 0x0110, 0x700a, 0x0010, 0x700b, 0x0003,
-	0x7814, 0x700e, 0x60c3, 0x0008, 0x0804, 0x9ea4, 0x00d6, 0x080c,
-	0x9b82, 0x7003, 0x0210, 0x7007, 0x0014, 0x700b, 0x0800, 0xb894,
-	0x9086, 0x0014, 0x1198, 0xb99c, 0x9184, 0x0030, 0x0190, 0xb998,
-	0x9184, 0xc000, 0x1140, 0xd1ec, 0x0118, 0x700f, 0x2100, 0x0058,
-	0x700f, 0x0100, 0x0040, 0x700f, 0x0400, 0x0028, 0x700f, 0x0700,
-	0x0010, 0x700f, 0x0800, 0x00f6, 0x2079, 0x1847, 0x7904, 0x00fe,
-	0xd1ac, 0x1110, 0x9085, 0x0020, 0xd1a4, 0x0110, 0x9085, 0x0010,
-	0x2009, 0x1869, 0x210c, 0xd184, 0x1110, 0x9085, 0x0002, 0x0026,
-	0x2009, 0x1867, 0x210c, 0xd1e4, 0x0150, 0xc0c5, 0xbad4, 0xd28c,
-	0x1108, 0xc0cd, 0x9094, 0x0030, 0x9296, 0x0010, 0x0140, 0xd1ec,
-	0x0130, 0x9094, 0x0030, 0x9296, 0x0010, 0x0108, 0xc0bd, 0x002e,
-	0x7026, 0x60c3, 0x0014, 0x00de, 0x0804, 0x9ea4, 0x080c, 0x9b82,
-	0x7003, 0x0210, 0x7007, 0x0014, 0x700f, 0x0100, 0x60c3, 0x0014,
-	0x0804, 0x9ea4, 0x080c, 0x9b82, 0x7003, 0x0200, 0x0804, 0x9946,
-	0x080c, 0x9b82, 0x7003, 0x0100, 0x700b, 0x0003, 0x700f, 0x2a00,
-	0x60c3, 0x0008, 0x0804, 0x9ea4, 0x080c, 0x9b82, 0x7003, 0x0100,
-	0x700b, 0x000b, 0x60c3, 0x0008, 0x0804, 0x9ea4, 0x0026, 0x00d6,
-	0x0036, 0x0046, 0x2019, 0x3200, 0x2021, 0x0800, 0x0040, 0x0026,
-	0x00d6, 0x0036, 0x0046, 0x2019, 0x2200, 0x2021, 0x0100, 0x080c,
-	0xa713, 0xb810, 0x9305, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800,
-	0x687c, 0x700a, 0x6880, 0x700e, 0x9485, 0x0029, 0x7012, 0x004e,
-	0x003e, 0x00de, 0x080c, 0x9e98, 0x721a, 0x9f95, 0x0000, 0x7222,
-	0x7027, 0xffff, 0x2071, 0x024c, 0x002e, 0x0005, 0x0026, 0x080c,
-	0xa713, 0x7003, 0x02ff, 0x7007, 0xfffc, 0x00d6, 0x2069, 0x1800,
-	0x687c, 0x700a, 0x6880, 0x700e, 0x00de, 0x7013, 0x2029, 0x0c10,
-	0x7003, 0x0100, 0x7007, 0x0000, 0x700b, 0xfc02, 0x700f, 0x0000,
-	0x0005, 0x0026, 0x00d6, 0x0036, 0x0046, 0x2019, 0x3300, 0x2021,
-	0x0800, 0x0040, 0x0026, 0x00d6, 0x0036, 0x0046, 0x2019, 0x2300,
-	0x2021, 0x0100, 0x080c, 0xa713, 0xb810, 0x9305, 0x7002, 0xb814,
-	0x7006, 0x2069, 0x1800, 0xb810, 0x9005, 0x1140, 0xb814, 0x9005,
-	0x1128, 0x700b, 0x00ff, 0x700f, 0xfffe, 0x0020, 0x687c, 0x700a,
-	0x6880, 0x700e, 0x0000, 0x9485, 0x0098, 0x7012, 0x004e, 0x003e,
-	0x00de, 0x080c, 0x9e98, 0x721a, 0x7a08, 0x7222, 0x2f10, 0x7226,
-	0x2071, 0x024c, 0x002e, 0x0005, 0x080c, 0x9e98, 0x721a, 0x7a08,
-	0x7222, 0x7814, 0x7026, 0x2071, 0x024c, 0x002e, 0x0005, 0x00b6,
-	0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2069, 0x0200, 0x2071, 0x0240,
-	0x6004, 0x908a, 0x0085, 0x0a0c, 0x0d7d, 0x908a, 0x0092, 0x1a0c,
-	0x0d7d, 0x6110, 0x2158, 0xb984, 0x2c78, 0x2061, 0x0100, 0x619a,
-	0x9082, 0x0085, 0x0033, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be,
-	0x0005, 0x9bf0, 0x9bff, 0x9c0a, 0x9bee, 0x9bee, 0x9bee, 0x9bf0,
-	0x9bee, 0x9bee, 0x9bee, 0x9bee, 0x9bee, 0x9bee, 0x080c, 0x0d7d,
-	0x0411, 0x60c3, 0x0000, 0x0026, 0x080c, 0x29e5, 0x0228, 0x2011,
-	0x0101, 0x2204, 0xc0c5, 0x2012, 0x002e, 0x0804, 0x9ea4, 0x0431,
-	0x7808, 0x700a, 0x7814, 0x700e, 0x7017, 0xffff, 0x60c3, 0x000c,
-	0x0804, 0x9ea4, 0x04a1, 0x7003, 0x0003, 0x7007, 0x0300, 0x60c3,
-	0x0004, 0x0804, 0x9ea4, 0x0026, 0x080c, 0xa713, 0xb810, 0x9085,
-	0x8100, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, 0x687c, 0x700a,
-	0x6880, 0x700e, 0x7013, 0x0009, 0x0804, 0x9b52, 0x0026, 0x080c,
-	0xa713, 0xb810, 0x9085, 0x8400, 0x7002, 0xb814, 0x7006, 0x2069,
-	0x1800, 0x687c, 0x700a, 0x6880, 0x700e, 0x2001, 0x0099, 0x7a20,
-	0x9296, 0x0005, 0x0108, 0xc0bc, 0x7012, 0x0804, 0x9bb4, 0x0026,
-	0x080c, 0xa713, 0xb810, 0x9085, 0x8500, 0x7002, 0xb814, 0x7006,
-	0x2069, 0x1800, 0x687c, 0x700a, 0x6880, 0x700e, 0x2001, 0x0099,
-	0x7a20, 0x9296, 0x0005, 0x0108, 0xc0bc, 0x7012, 0x0804, 0x9bb4,
-	0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2c78, 0x2069, 0x0200,
-	0x2071, 0x0240, 0x7804, 0x908a, 0x0040, 0x0a0c, 0x0d7d, 0x908a,
-	0x0057, 0x1a0c, 0x0d7d, 0x7910, 0x2158, 0xb984, 0x2061, 0x0100,
-	0x619a, 0x9082, 0x0040, 0x0033, 0x00fe, 0x00ee, 0x00de, 0x00ce,
-	0x00be, 0x0005, 0x9c8d, 0x9c8d, 0x9c8d, 0x9cb3, 0x9c8d, 0x9c8d,
-	0x9c8d, 0x9c8d, 0x9c8d, 0x9c8d, 0x9c8d, 0xa25f, 0xa267, 0xa26f,
-	0xa277, 0x9c8d, 0x9c8d, 0x9c8d, 0xa257, 0x080c, 0x0d7d, 0x6813,
-	0x0008, 0xba8c, 0x8210, 0xb8d4, 0xd084, 0x0128, 0x7a52, 0x7b14,
-	0x7b4e, 0x722e, 0x732a, 0x9294, 0x00ff, 0xba8e, 0x8217, 0x721a,
-	0xba10, 0x9295, 0x0600, 0x7202, 0xba14, 0x7206, 0x2069, 0x1800,
-	0x6a7c, 0x720a, 0x6a80, 0x720e, 0x7013, 0x0829, 0x2f10, 0x7222,
-	0x7027, 0xffff, 0x0005, 0x0016, 0x7814, 0x9084, 0x0700, 0x8007,
-	0x0013, 0x001e, 0x0005, 0x9cc3, 0x9cc3, 0x9cc5, 0x9cc3, 0x9cc3,
-	0x9cc3, 0x9cdf, 0x9cc3, 0x080c, 0x0d7d, 0x7914, 0x918c, 0x08ff,
-	0x918d, 0xf600, 0x7916, 0x2009, 0x0003, 0x00b9, 0x2069, 0x1847,
-	0x6804, 0xd0bc, 0x0130, 0x682c, 0x9084, 0x00ff, 0x8007, 0x7032,
-	0x0010, 0x7033, 0x3f00, 0x60c3, 0x0001, 0x0804, 0x9ea4, 0x2009,
-	0x0003, 0x0019, 0x7033, 0x7f00, 0x0cb0, 0x0016, 0x080c, 0xa713,
-	0x001e, 0xb810, 0x9085, 0x0100, 0x7002, 0xb814, 0x7006, 0x2069,
-	0x1800, 0x6a7c, 0x720a, 0x6a80, 0x720e, 0x7013, 0x0888, 0x918d,
-	0x0008, 0x7116, 0x080c, 0x9e98, 0x721a, 0x7a08, 0x7222, 0x2f10,
-	0x7226, 0x0005, 0x00b6, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0056,
-	0x0046, 0x0036, 0x2061, 0x0100, 0x2071, 0x1800, 0x7160, 0x7810,
-	0x2058, 0x76dc, 0x96b4, 0x0028, 0x0110, 0x737c, 0x7480, 0x2500,
-	0x76dc, 0x96b4, 0x0028, 0x0140, 0x2001, 0x04ff, 0x6062, 0x6067,
-	0xffff, 0x636a, 0x646e, 0x0050, 0x2001, 0x00ff, 0x9085, 0x0400,
-	0x6062, 0x6067, 0xffff, 0x606b, 0x0000, 0x616e, 0xb8b8, 0x6073,
-	0x0530, 0x6077, 0x0008, 0xb88c, 0x8000, 0x9084, 0x00ff, 0xb88e,
-	0x8007, 0x9085, 0x0020, 0x607a, 0x607f, 0x0000, 0x2b00, 0x6082,
-	0x6087, 0xffff, 0x7814, 0x0096, 0x2048, 0xa848, 0x608a, 0xa844,
-	0x608e, 0xa838, 0x60c6, 0xa834, 0x60ca, 0x009e, 0xb86c, 0x60ce,
-	0x60ab, 0x0036, 0x60af, 0x95d5, 0x60d7, 0x0000, 0x2001, 0x1837,
-	0x2004, 0x9084, 0x0028, 0x0128, 0x609f, 0x0000, 0x2001, 0x0092,
-	0x0058, 0x6028, 0xc0bd, 0x602a, 0x609f, 0x00ff, 0x2011, 0xffff,
-	0x080c, 0x2ab4, 0x2001, 0x00b2, 0x2010, 0x900e, 0x080c, 0x2ac3,
-	0x2009, 0x07d0, 0x080c, 0x8785, 0x003e, 0x004e, 0x005e, 0x006e,
-	0x00ce, 0x00de, 0x00ee, 0x00be, 0x0005, 0x00b6, 0x00e6, 0x00d6,
-	0x00c6, 0x0066, 0x0056, 0x0046, 0x0036, 0x2061, 0x0100, 0x2071,
-	0x1800, 0x7160, 0x7810, 0x2058, 0xb8a0, 0x2028, 0x76dc, 0xd6ac,
-	0x1168, 0x9582, 0x007e, 0x1250, 0x2500, 0x9094, 0xff80, 0x1130,
-	0x9080, 0x33b9, 0x2015, 0x9294, 0x00ff, 0x0020, 0xb910, 0xba14,
-	0x737c, 0x7480, 0x70dc, 0xd0ac, 0x1130, 0x9582, 0x007e, 0x1218,
-	0x9584, 0xff80, 0x0138, 0x9185, 0x0400, 0x6062, 0x6266, 0x636a,
-	0x646e, 0x0030, 0x6063, 0x0400, 0x6266, 0x606b, 0x0000, 0x616e,
-	0xb8b8, 0x6072, 0x6077, 0x0000, 0xb864, 0xd0a4, 0x0110, 0x6077,
+	0x0005, 0x080c, 0x9ce2, 0x7003, 0x7800, 0x7808, 0x8007, 0x700a,
+	0x60c3, 0x0008, 0x0804, 0xa05a, 0x00d6, 0x00e6, 0x080c, 0x9d2d,
+	0x7814, 0x9084, 0xff00, 0x2073, 0x0200, 0x8e70, 0x8e70, 0x9096,
+	0xdf00, 0x0138, 0x9096, 0xe000, 0x0120, 0x2073, 0x0010, 0x8e70,
+	0x0030, 0x9095, 0x0010, 0x2272, 0x8e70, 0x2073, 0x0034, 0x8e70,
+	0x2069, 0x1805, 0x20a9, 0x0004, 0x2d76, 0x8d68, 0x8e70, 0x1f04,
+	0x9a74, 0x2069, 0x1801, 0x20a9, 0x0004, 0x2d76, 0x8d68, 0x8e70,
+	0x1f04, 0x9a7d, 0x9096, 0xdf00, 0x0130, 0x9096, 0xe000, 0x0118,
+	0x60c3, 0x0018, 0x00f0, 0x2069, 0x19b5, 0x9086, 0xdf00, 0x0110,
+	0x2069, 0x19cf, 0x20a9, 0x001a, 0x9e86, 0x0260, 0x1148, 0x00c6,
+	0x2061, 0x0200, 0x6010, 0x8000, 0x6012, 0x00ce, 0x2071, 0x0240,
+	0x2d04, 0x8007, 0x2072, 0x8d68, 0x8e70, 0x1f04, 0x9a94, 0x60c3,
+	0x004c, 0x080c, 0xa05a, 0x00ee, 0x00de, 0x0005, 0x080c, 0x9ce2,
+	0x7003, 0x6300, 0x7007, 0x0028, 0x7808, 0x700e, 0x60c3, 0x0008,
+	0x0804, 0xa05a, 0x00d6, 0x0026, 0x0016, 0x080c, 0x9d2d, 0x7003,
+	0x0200, 0x7814, 0x700e, 0x00e6, 0x9ef0, 0x0004, 0x2009, 0x0001,
+	0x2011, 0x000c, 0x2069, 0x1925, 0x6810, 0xd084, 0x1148, 0x2073,
+	0x0500, 0x8e70, 0x2073, 0x0000, 0x8e70, 0x8108, 0x9290, 0x0004,
+	0x2073, 0x0800, 0x8e70, 0x2073, 0x0000, 0x00ee, 0x7206, 0x710a,
+	0x62c2, 0x080c, 0xa05a, 0x001e, 0x002e, 0x00de, 0x0005, 0x2001,
+	0x1818, 0x2004, 0x609a, 0x0804, 0xa05a, 0x080c, 0x9ce2, 0x7003,
+	0x5200, 0x2069, 0x1847, 0x6804, 0xd084, 0x0130, 0x6828, 0x0016,
+	0x080c, 0x26d5, 0x710e, 0x001e, 0x20a9, 0x0004, 0x20e1, 0x0001,
+	0x2099, 0x1805, 0x20e9, 0x0000, 0x20a1, 0x0250, 0x4003, 0x20a9,
+	0x0004, 0x2099, 0x1801, 0x20a1, 0x0254, 0x4003, 0x080c, 0xae60,
+	0x1120, 0xb8a0, 0x9082, 0x007f, 0x0248, 0x2001, 0x181f, 0x2004,
+	0x7032, 0x2001, 0x1820, 0x2004, 0x7036, 0x0030, 0x2001, 0x1818,
+	0x2004, 0x9084, 0x00ff, 0x7036, 0x60c3, 0x001c, 0x0804, 0xa05a,
+	0x080c, 0x9ce2, 0x7003, 0x0500, 0x080c, 0xae60, 0x1120, 0xb8a0,
+	0x9082, 0x007f, 0x0248, 0x2001, 0x181f, 0x2004, 0x700a, 0x2001,
+	0x1820, 0x2004, 0x700e, 0x0030, 0x2001, 0x1818, 0x2004, 0x9084,
+	0x00ff, 0x700e, 0x20a9, 0x0004, 0x20e1, 0x0001, 0x2099, 0x1805,
+	0x20e9, 0x0000, 0x20a1, 0x0250, 0x4003, 0x60c3, 0x0010, 0x0804,
+	0xa05a, 0x080c, 0x9ce2, 0x9006, 0x080c, 0x6b9f, 0xb8a0, 0x9086,
+	0x007e, 0x1130, 0x7003, 0x0400, 0x620c, 0xc2b4, 0x620e, 0x0058,
+	0x7814, 0x0096, 0x904d, 0x0120, 0x9006, 0xa89a, 0xa8a6, 0xa8aa,
+	0x009e, 0x7003, 0x0300, 0xb8a0, 0x9086, 0x007e, 0x1904, 0x9bc0,
+	0x00d6, 0x2069, 0x196d, 0x2001, 0x1837, 0x2004, 0xd0a4, 0x0188,
+	0x6800, 0x700a, 0x6808, 0x9084, 0x2000, 0x7012, 0x080c, 0xae77,
+	0x680c, 0x7016, 0x701f, 0x2710, 0x6818, 0x7022, 0x681c, 0x7026,
+	0x0090, 0x6800, 0x700a, 0x6804, 0x700e, 0x6808, 0x080c, 0x76a5,
+	0x1118, 0x9084, 0x37ff, 0x0010, 0x9084, 0x3fff, 0x7012, 0x080c,
+	0xae77, 0x680c, 0x7016, 0x00de, 0x20a9, 0x0004, 0x20e1, 0x0001,
+	0x2099, 0x1805, 0x20e9, 0x0000, 0x20a1, 0x0256, 0x4003, 0x20a9,
+	0x0004, 0x2099, 0x1801, 0x20a1, 0x025a, 0x4003, 0x00d6, 0x080c,
+	0xa8c0, 0x2069, 0x1975, 0x2071, 0x024e, 0x6800, 0xc0dd, 0x7002,
+	0x080c, 0x582a, 0xd0e4, 0x0110, 0x680c, 0x700e, 0x00de, 0x04a8,
+	0x2001, 0x1837, 0x2004, 0xd0a4, 0x0170, 0x0016, 0x2001, 0x196e,
+	0x200c, 0x60e0, 0x9106, 0x0130, 0x2100, 0x60e3, 0x0000, 0x080c,
+	0x2716, 0x61e2, 0x001e, 0x20e1, 0x0001, 0x2099, 0x196d, 0x20e9,
+	0x0000, 0x20a1, 0x024e, 0x20a9, 0x0008, 0x4003, 0x20a9, 0x0004,
+	0x2099, 0x1805, 0x20a1, 0x0256, 0x4003, 0x20a9, 0x0004, 0x2099,
+	0x1801, 0x20a1, 0x025a, 0x4003, 0x080c, 0xa8c0, 0x20a1, 0x024e,
+	0x20a9, 0x0008, 0x2099, 0x1975, 0x4003, 0x60c3, 0x0074, 0x0804,
+	0xa05a, 0x080c, 0x9ce2, 0x7003, 0x2010, 0x7007, 0x0014, 0x700b,
+	0x0800, 0x700f, 0x2000, 0x9006, 0x00f6, 0x2079, 0x1847, 0x7904,
+	0x00fe, 0xd1ac, 0x1110, 0x9085, 0x0020, 0xd1a4, 0x0110, 0x9085,
+	0x0010, 0x9085, 0x0002, 0x00d6, 0x0804, 0x9c92, 0x7026, 0x60c3,
+	0x0014, 0x0804, 0xa05a, 0x080c, 0x9ce2, 0x7003, 0x5000, 0x0804,
+	0x9b6b, 0x080c, 0x9ce2, 0x7003, 0x2110, 0x7007, 0x0014, 0x60c3,
+	0x0014, 0x0804, 0xa05a, 0x080c, 0x9d24, 0x0010, 0x080c, 0x9d2d,
+	0x7003, 0x0200, 0x60c3, 0x0004, 0x0804, 0xa05a, 0x080c, 0x9d2d,
+	0x7003, 0x0100, 0x700b, 0x0003, 0x700f, 0x2a00, 0x60c3, 0x0008,
+	0x0804, 0xa05a, 0x080c, 0x9d2d, 0x7003, 0x0200, 0x0804, 0x9b6b,
+	0x080c, 0x9d2d, 0x7003, 0x0100, 0x782c, 0x9005, 0x0110, 0x700a,
+	0x0010, 0x700b, 0x0003, 0x7814, 0x700e, 0x60c3, 0x0008, 0x0804,
+	0xa05a, 0x00d6, 0x080c, 0x9d2d, 0x7003, 0x0210, 0x7007, 0x0014,
+	0x700b, 0x0800, 0xb894, 0x9086, 0x0014, 0x1198, 0xb99c, 0x9184,
+	0x0030, 0x0190, 0xb998, 0x9184, 0xc000, 0x1140, 0xd1ec, 0x0118,
+	0x700f, 0x2100, 0x0058, 0x700f, 0x0100, 0x0040, 0x700f, 0x0400,
+	0x0028, 0x700f, 0x0700, 0x0010, 0x700f, 0x0800, 0x00f6, 0x2079,
+	0x1847, 0x7904, 0x00fe, 0xd1ac, 0x1110, 0x9085, 0x0020, 0xd1a4,
+	0x0110, 0x9085, 0x0010, 0x2009, 0x1869, 0x210c, 0xd184, 0x1110,
+	0x9085, 0x0002, 0x0026, 0x2009, 0x1867, 0x210c, 0xd1e4, 0x0150,
+	0xc0c5, 0xbad4, 0xd28c, 0x1108, 0xc0cd, 0x9094, 0x0030, 0x9296,
+	0x0010, 0x0140, 0xd1ec, 0x0130, 0x9094, 0x0030, 0x9296, 0x0010,
+	0x0108, 0xc0bd, 0x002e, 0x7026, 0x60c3, 0x0014, 0x00de, 0x0804,
+	0xa05a, 0x080c, 0x9d2d, 0x7003, 0x0210, 0x7007, 0x0014, 0x700f,
+	0x0100, 0x60c3, 0x0014, 0x0804, 0xa05a, 0x080c, 0x9d2d, 0x7003,
+	0x0200, 0x0804, 0x9af1, 0x080c, 0x9d2d, 0x7003, 0x0100, 0x700b,
+	0x0003, 0x700f, 0x2a00, 0x60c3, 0x0008, 0x0804, 0xa05a, 0x080c,
+	0x9d2d, 0x7003, 0x0100, 0x700b, 0x000b, 0x60c3, 0x0008, 0x0804,
+	0xa05a, 0x0026, 0x00d6, 0x0036, 0x0046, 0x2019, 0x3200, 0x2021,
+	0x0800, 0x0040, 0x0026, 0x00d6, 0x0036, 0x0046, 0x2019, 0x2200,
+	0x2021, 0x0100, 0x080c, 0xa8d5, 0xb810, 0x9305, 0x7002, 0xb814,
+	0x7006, 0x2069, 0x1800, 0x687c, 0x700a, 0x6880, 0x700e, 0x9485,
+	0x0029, 0x7012, 0x004e, 0x003e, 0x00de, 0x080c, 0xa04e, 0x721a,
+	0x9f95, 0x0000, 0x7222, 0x7027, 0xffff, 0x2071, 0x024c, 0x002e,
+	0x0005, 0x0026, 0x080c, 0xa8d5, 0x7003, 0x02ff, 0x7007, 0xfffc,
+	0x00d6, 0x2069, 0x1800, 0x687c, 0x700a, 0x6880, 0x700e, 0x00de,
+	0x7013, 0x2029, 0x0c10, 0x7003, 0x0100, 0x7007, 0x0000, 0x700b,
+	0xfc02, 0x700f, 0x0000, 0x0005, 0x0026, 0x00d6, 0x0036, 0x0046,
+	0x2019, 0x3300, 0x2021, 0x0800, 0x0040, 0x0026, 0x00d6, 0x0036,
+	0x0046, 0x2019, 0x2300, 0x2021, 0x0100, 0x080c, 0xa8d5, 0xb810,
+	0x9305, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, 0xb810, 0x9005,
+	0x1140, 0xb814, 0x9005, 0x1128, 0x700b, 0x00ff, 0x700f, 0xfffe,
+	0x0020, 0x687c, 0x700a, 0x6880, 0x700e, 0x0000, 0x9485, 0x0098,
+	0x7012, 0x004e, 0x003e, 0x00de, 0x080c, 0xa04e, 0x721a, 0x7a08,
+	0x7222, 0x2f10, 0x7226, 0x2071, 0x024c, 0x002e, 0x0005, 0x080c,
+	0xa04e, 0x721a, 0x7a08, 0x7222, 0x7814, 0x7026, 0x2071, 0x024c,
+	0x002e, 0x0005, 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2069,
+	0x0200, 0x2071, 0x0240, 0x6004, 0x908a, 0x0085, 0x0a0c, 0x0d85,
+	0x908a, 0x0092, 0x1a0c, 0x0d85, 0x6110, 0x2158, 0xb984, 0x2c78,
+	0x2061, 0x0100, 0x619a, 0x9082, 0x0085, 0x0033, 0x00fe, 0x00ee,
+	0x00de, 0x00ce, 0x00be, 0x0005, 0x9d9b, 0x9daa, 0x9db5, 0x9d99,
+	0x9d99, 0x9d99, 0x9d9b, 0x9d99, 0x9d99, 0x9d99, 0x9d99, 0x9d99,
+	0x9d99, 0x080c, 0x0d85, 0x0411, 0x60c3, 0x0000, 0x0026, 0x080c,
+	0x2a26, 0x0228, 0x2011, 0x0101, 0x2204, 0xc0c5, 0x2012, 0x002e,
+	0x0804, 0xa05a, 0x0431, 0x7808, 0x700a, 0x7814, 0x700e, 0x7017,
+	0xffff, 0x60c3, 0x000c, 0x0804, 0xa05a, 0x04a1, 0x7003, 0x0003,
+	0x7007, 0x0300, 0x60c3, 0x0004, 0x0804, 0xa05a, 0x0026, 0x080c,
+	0xa8d5, 0xb810, 0x9085, 0x8100, 0x7002, 0xb814, 0x7006, 0x2069,
+	0x1800, 0x687c, 0x700a, 0x6880, 0x700e, 0x7013, 0x0009, 0x0804,
+	0x9cfd, 0x0026, 0x080c, 0xa8d5, 0xb810, 0x9085, 0x8400, 0x7002,
+	0xb814, 0x7006, 0x2069, 0x1800, 0x687c, 0x700a, 0x6880, 0x700e,
+	0x2001, 0x0099, 0x7a20, 0x9296, 0x0005, 0x0108, 0xc0bc, 0x7012,
+	0x0804, 0x9d5f, 0x0026, 0x080c, 0xa8d5, 0xb810, 0x9085, 0x8500,
+	0x7002, 0xb814, 0x7006, 0x2069, 0x1800, 0x687c, 0x700a, 0x6880,
+	0x700e, 0x2001, 0x0099, 0x7a20, 0x9296, 0x0005, 0x0108, 0xc0bc,
+	0x7012, 0x0804, 0x9d5f, 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6,
+	0x2c78, 0x2069, 0x0200, 0x2071, 0x0240, 0x7804, 0x908a, 0x0040,
+	0x0a0c, 0x0d85, 0x908a, 0x0057, 0x1a0c, 0x0d85, 0x7910, 0x2158,
+	0xb984, 0x2061, 0x0100, 0x619a, 0x9082, 0x0040, 0x0033, 0x00fe,
+	0x00ee, 0x00de, 0x00ce, 0x00be, 0x0005, 0x9e38, 0x9e38, 0x9e38,
+	0x9e69, 0x9e38, 0x9e38, 0x9e38, 0x9e38, 0x9e38, 0x9e38, 0x9e38,
+	0xa428, 0xa42d, 0xa432, 0xa437, 0x9e38, 0x9e38, 0x9e38, 0xa423,
+	0x080c, 0x0d85, 0x6813, 0x0008, 0xba8c, 0x8210, 0xb8d4, 0xd084,
+	0x0180, 0x2001, 0x1b73, 0x200c, 0x8108, 0x2102, 0x2001, 0x1b72,
+	0x201c, 0x1218, 0x8318, 0x2302, 0x0ea0, 0x7952, 0x712e, 0x7b4e,
+	0x732a, 0x9294, 0x00ff, 0xba8e, 0x8217, 0x721a, 0xba10, 0x9295,
+	0x0600, 0x7202, 0xba14, 0x7206, 0x2069, 0x1800, 0x6a7c, 0x720a,
+	0x6a80, 0x720e, 0x7013, 0x0829, 0x2f10, 0x7222, 0x7027, 0xffff,
+	0x0005, 0x0016, 0x7814, 0x9084, 0x0700, 0x8007, 0x0013, 0x001e,
+	0x0005, 0x9e79, 0x9e79, 0x9e7b, 0x9e79, 0x9e79, 0x9e79, 0x9e95,
+	0x9e79, 0x080c, 0x0d85, 0x7914, 0x918c, 0x08ff, 0x918d, 0xf600,
+	0x7916, 0x2009, 0x0003, 0x00b9, 0x2069, 0x1847, 0x6804, 0xd0bc,
+	0x0130, 0x682c, 0x9084, 0x00ff, 0x8007, 0x7032, 0x0010, 0x7033,
+	0x3f00, 0x60c3, 0x0001, 0x0804, 0xa05a, 0x2009, 0x0003, 0x0019,
+	0x7033, 0x7f00, 0x0cb0, 0x0016, 0x080c, 0xa8d5, 0x001e, 0xb810,
+	0x9085, 0x0100, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, 0x6a7c,
+	0x720a, 0x6a80, 0x720e, 0x7013, 0x0888, 0x918d, 0x0008, 0x7116,
+	0x080c, 0xa04e, 0x721a, 0x7a08, 0x7222, 0x2f10, 0x7226, 0x0005,
+	0x00b6, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0056, 0x0046, 0x0036,
+	0x2061, 0x0100, 0x2071, 0x1800, 0x7160, 0x7810, 0x2058, 0x76dc,
+	0x96b4, 0x0028, 0x0110, 0x737c, 0x7480, 0x2500, 0x76dc, 0x96b4,
+	0x0028, 0x0140, 0x2001, 0x04ff, 0x6062, 0x6067, 0xffff, 0x636a,
+	0x646e, 0x0050, 0x2001, 0x00ff, 0x9085, 0x0400, 0x6062, 0x6067,
+	0xffff, 0x606b, 0x0000, 0x616e, 0xb8b8, 0x6073, 0x0530, 0x6077,
 	0x0008, 0xb88c, 0x8000, 0x9084, 0x00ff, 0xb88e, 0x8007, 0x9085,
 	0x0020, 0x607a, 0x607f, 0x0000, 0x2b00, 0x6082, 0x6087, 0xffff,
 	0x7814, 0x0096, 0x2048, 0xa848, 0x608a, 0xa844, 0x608e, 0xa838,
 	0x60c6, 0xa834, 0x60ca, 0x009e, 0xb86c, 0x60ce, 0x60ab, 0x0036,
-	0x60af, 0x95d5, 0x60d7, 0x0000, 0xba84, 0x629e, 0x00f6, 0x2079,
-	0x0140, 0x7803, 0x0000, 0x00fe, 0x900e, 0x2011, 0x0092, 0x080c,
-	0x2ac3, 0x2009, 0x07d0, 0x080c, 0x8785, 0x003e, 0x004e, 0x005e,
-	0x006e, 0x00ce, 0x00de, 0x00ee, 0x00be, 0x0005, 0x00b6, 0x0096,
-	0x00e6, 0x00d6, 0x00c6, 0x0056, 0x0046, 0x0036, 0x2061, 0x0100,
-	0x2071, 0x1800, 0x7810, 0x2058, 0xb8a0, 0x2028, 0xb910, 0xba14,
-	0x737c, 0x7480, 0x7820, 0x0002, 0x9e23, 0x9e23, 0x9e23, 0x9e23,
-	0x9e23, 0x9e23, 0x9e23, 0x9e23, 0x9e23, 0x9e23, 0x9e25, 0x9e23,
-	0x9e23, 0x9e23, 0x9e23, 0x080c, 0x0d7d, 0xb884, 0x609e, 0x7814,
-	0x2048, 0xa87c, 0xd0fc, 0x0558, 0xaf90, 0x9784, 0xff00, 0x9105,
-	0x6062, 0x873f, 0x9784, 0xff00, 0x0006, 0x7814, 0x2048, 0xa878,
-	0xc0fc, 0x9005, 0x000e, 0x1160, 0xaf94, 0x87ff, 0x0198, 0x2039,
-	0x0098, 0x9705, 0x6072, 0x7808, 0x6082, 0x2f00, 0x6086, 0x0038,
-	0x9185, 0x2200, 0x6062, 0x6073, 0x0129, 0x6077, 0x0000, 0xb884,
-	0x609e, 0x0050, 0x2039, 0x0029, 0x9705, 0x6072, 0x0cc0, 0x9185,
-	0x0200, 0x6062, 0x6073, 0x2029, 0xa87c, 0xd0fc, 0x0118, 0xaf94,
-	0x87ff, 0x1120, 0x2f00, 0x6082, 0x7808, 0x6086, 0x6266, 0x636a,
-	0x646e, 0x6077, 0x0000, 0xb88c, 0x8000, 0x9084, 0x00ff, 0xb88e,
-	0x8007, 0x607a, 0x607f, 0x0000, 0xa848, 0x608a, 0xa844, 0x608e,
-	0xa838, 0x60c6, 0xa834, 0x60ca, 0xb86c, 0x60ce, 0x60af, 0x95d5,
-	0x60d7, 0x0000, 0x080c, 0xa6f3, 0x2009, 0x07d0, 0x60c4, 0x9084,
-	0xfff0, 0x9005, 0x0110, 0x2009, 0x1b58, 0x080c, 0x8785, 0x003e,
-	0x004e, 0x005e, 0x00ce, 0x00de, 0x00ee, 0x009e, 0x00be, 0x0005,
-	0x7a40, 0x9294, 0x00ff, 0x8217, 0x0005, 0x00d6, 0x2069, 0x19e6,
-	0x686b, 0x0001, 0x00de, 0x0005, 0x60a3, 0x0056, 0x60a7, 0x9575,
-	0x00f1, 0x080c, 0x8777, 0x0005, 0x0016, 0x2001, 0x180c, 0x200c,
-	0x9184, 0x0600, 0x9086, 0x0600, 0x0128, 0x0089, 0x080c, 0x8777,
-	0x001e, 0x0005, 0xc1e5, 0x2001, 0x180c, 0x2102, 0x2001, 0x19e7,
-	0x2003, 0x0000, 0x2001, 0x19f2, 0x2003, 0x0000, 0x0c88, 0x0006,
-	0x0016, 0x0026, 0x2009, 0x1804, 0x2011, 0x0009, 0x080c, 0x2ac3,
-	0x002e, 0x001e, 0x000e, 0x0005, 0x0016, 0x00c6, 0x0006, 0x080c,
-	0xa91e, 0x0106, 0x2061, 0x0100, 0x61a4, 0x60a7, 0x95f5, 0x0016,
-	0x0026, 0x2009, 0x1804, 0x2011, 0x0008, 0x080c, 0x2ac3, 0x002e,
-	0x001e, 0x010e, 0x090c, 0xa93a, 0x000e, 0xa001, 0xa001, 0xa001,
-	0x61a6, 0x00ce, 0x001e, 0x0005, 0x00c6, 0x00d6, 0x0016, 0x0026,
-	0x2061, 0x0100, 0x2069, 0x0140, 0x080c, 0x753d, 0x1510, 0x2001,
-	0x1a0b, 0x2004, 0x9005, 0x1904, 0x9f53, 0x080c, 0x75e2, 0x11a8,
-	0x2069, 0x0380, 0x6843, 0x0101, 0x6844, 0xd084, 0x1de8, 0x2061,
-	0x0100, 0x6020, 0xd0b4, 0x1120, 0x6024, 0xd084, 0x090c, 0x0d7d,
-	0x6843, 0x0100, 0x080c, 0x8777, 0x04b0, 0x00c6, 0x2061, 0x19e6,
-	0x00f0, 0x6904, 0x9194, 0x4000, 0x0598, 0x080c, 0x9ed4, 0x080c,
-	0x2a8a, 0x00c6, 0x2061, 0x19e6, 0x6134, 0x9192, 0x0008, 0x1278,
-	0x8108, 0x6136, 0x080c, 0xa91e, 0x6130, 0x080c, 0xa93a, 0x00ce,
-	0x81ff, 0x01c8, 0x080c, 0x8777, 0x080c, 0x9ec7, 0x00a0, 0x080c,
-	0xa91e, 0x6130, 0x91e5, 0x0000, 0x0150, 0x080c, 0xe897, 0x080c,
-	0x8780, 0x6003, 0x0001, 0x2009, 0x0014, 0x080c, 0xad4d, 0x080c,
-	0xa93a, 0x00ce, 0x0000, 0x002e, 0x001e, 0x00de, 0x00ce, 0x0005,
-	0x2001, 0x1a0b, 0x2004, 0x9005, 0x1db0, 0x00c6, 0x2061, 0x19e6,
-	0x6134, 0x9192, 0x0003, 0x1ad8, 0x8108, 0x6136, 0x00ce, 0x080c,
-	0x8777, 0x080c, 0x5f4d, 0x2009, 0x1846, 0x2114, 0x8210, 0x220a,
-	0x0c10, 0x0096, 0x00c6, 0x00d6, 0x00e6, 0x0016, 0x0026, 0x080c,
-	0x878d, 0x080c, 0xa91e, 0x2001, 0x0387, 0x2003, 0x0202, 0x2071,
-	0x19e6, 0x714c, 0x81ff, 0x0904, 0x9ffb, 0x2061, 0x0100, 0x2069,
-	0x0140, 0x080c, 0x753d, 0x1510, 0x0036, 0x2019, 0x0002, 0x080c,
-	0xa1b8, 0x003e, 0x714c, 0x2160, 0x080c, 0xe897, 0x2009, 0x004a,
-	0x6220, 0x9296, 0x0009, 0x1130, 0x6114, 0x2148, 0xa87b, 0x0006,
-	0x2009, 0x004a, 0x6003, 0x0003, 0x080c, 0xad4d, 0x2001, 0x0386,
-	0x2003, 0x5040, 0x080c, 0x75e2, 0x0804, 0x9ffb, 0x6904, 0xd1f4,
-	0x0904, 0xa008, 0x080c, 0x2a8a, 0x00c6, 0x704c, 0x9065, 0x090c,
-	0x0d7d, 0x6020, 0x00ce, 0x9086, 0x0006, 0x1518, 0x61c8, 0x60c4,
-	0x9105, 0x11f8, 0x2009, 0x180c, 0x2104, 0xd0d4, 0x01d0, 0x6214,
-	0x9294, 0x1800, 0x1128, 0x6224, 0x9294, 0x0002, 0x1560, 0x0010,
-	0xc0d4, 0x200a, 0x6014, 0x9084, 0xe7fd, 0x9085, 0x0010, 0x6016,
-	0x704c, 0x2060, 0x080c, 0x96d5, 0x2009, 0x0049, 0x080c, 0xad4d,
-	0x00d0, 0x0036, 0x2019, 0x0001, 0x080c, 0xa1b8, 0x003e, 0x714c,
-	0x2160, 0x080c, 0xe897, 0x2009, 0x004a, 0x6220, 0x9296, 0x0009,
+	0x60af, 0x95d5, 0x60d7, 0x0000, 0x2001, 0x1837, 0x2004, 0x9084,
+	0x0028, 0x0128, 0x609f, 0x0000, 0x2001, 0x0092, 0x0058, 0x6028,
+	0xc0bd, 0x602a, 0x609f, 0x00ff, 0x2011, 0xffff, 0x080c, 0x2af5,
+	0x2001, 0x00b2, 0x2010, 0x900e, 0x080c, 0x2b04, 0x2009, 0x07d0,
+	0x080c, 0x88f1, 0x003e, 0x004e, 0x005e, 0x006e, 0x00ce, 0x00de,
+	0x00ee, 0x00be, 0x0005, 0x00b6, 0x00e6, 0x00d6, 0x00c6, 0x0066,
+	0x0056, 0x0046, 0x0036, 0x2061, 0x0100, 0x2071, 0x1800, 0x7160,
+	0x7810, 0x2058, 0xb8a0, 0x2028, 0x76dc, 0xd6ac, 0x1168, 0x9582,
+	0x007e, 0x1250, 0x2500, 0x9094, 0xff80, 0x1130, 0x9080, 0x3489,
+	0x2015, 0x9294, 0x00ff, 0x0020, 0xb910, 0xba14, 0x737c, 0x7480,
+	0x70dc, 0xd0ac, 0x1130, 0x9582, 0x007e, 0x1218, 0x9584, 0xff80,
+	0x0138, 0x9185, 0x0400, 0x6062, 0x6266, 0x636a, 0x646e, 0x0030,
+	0x6063, 0x0400, 0x6266, 0x606b, 0x0000, 0x616e, 0xb8b8, 0x6072,
+	0x6077, 0x0000, 0xb864, 0xd0a4, 0x0110, 0x6077, 0x0008, 0xb88c,
+	0x8000, 0x9084, 0x00ff, 0xb88e, 0x8007, 0x9085, 0x0020, 0x607a,
+	0x607f, 0x0000, 0x2b00, 0x6082, 0x6087, 0xffff, 0x7814, 0x0096,
+	0x2048, 0xa848, 0x608a, 0xa844, 0x608e, 0xa838, 0x60c6, 0xa834,
+	0x60ca, 0x009e, 0xb86c, 0x60ce, 0x60ab, 0x0036, 0x60af, 0x95d5,
+	0x60d7, 0x0000, 0xba84, 0x629e, 0x00f6, 0x2079, 0x0140, 0x7803,
+	0x0000, 0x00fe, 0x900e, 0x2011, 0x0092, 0x080c, 0x2b04, 0x2009,
+	0x07d0, 0x080c, 0x88f1, 0x003e, 0x004e, 0x005e, 0x006e, 0x00ce,
+	0x00de, 0x00ee, 0x00be, 0x0005, 0x00b6, 0x0096, 0x00e6, 0x00d6,
+	0x00c6, 0x0056, 0x0046, 0x0036, 0x2061, 0x0100, 0x2071, 0x1800,
+	0x7810, 0x2058, 0xb8a0, 0x2028, 0xb910, 0xba14, 0x737c, 0x7480,
+	0x7820, 0x0002, 0x9fd9, 0x9fd9, 0x9fd9, 0x9fd9, 0x9fd9, 0x9fd9,
+	0x9fd9, 0x9fd9, 0x9fd9, 0x9fd9, 0x9fdb, 0x9fd9, 0x9fd9, 0x9fd9,
+	0x9fd9, 0x080c, 0x0d85, 0xb884, 0x609e, 0x7814, 0x2048, 0xa87c,
+	0xd0fc, 0x0558, 0xaf90, 0x9784, 0xff00, 0x9105, 0x6062, 0x873f,
+	0x9784, 0xff00, 0x0006, 0x7814, 0x2048, 0xa878, 0xc0fc, 0x9005,
+	0x000e, 0x1160, 0xaf94, 0x87ff, 0x0198, 0x2039, 0x0098, 0x9705,
+	0x6072, 0x7808, 0x6082, 0x2f00, 0x6086, 0x0038, 0x9185, 0x2200,
+	0x6062, 0x6073, 0x0129, 0x6077, 0x0000, 0xb884, 0x609e, 0x0050,
+	0x2039, 0x0029, 0x9705, 0x6072, 0x0cc0, 0x9185, 0x0200, 0x6062,
+	0x6073, 0x2029, 0xa87c, 0xd0fc, 0x0118, 0xaf94, 0x87ff, 0x1120,
+	0x2f00, 0x6082, 0x7808, 0x6086, 0x6266, 0x636a, 0x646e, 0x6077,
+	0x0000, 0xb88c, 0x8000, 0x9084, 0x00ff, 0xb88e, 0x8007, 0x607a,
+	0x607f, 0x0000, 0xa848, 0x608a, 0xa844, 0x608e, 0xa838, 0x60c6,
+	0xa834, 0x60ca, 0xb86c, 0x60ce, 0x60af, 0x95d5, 0x60d7, 0x0000,
+	0x080c, 0xa8b5, 0x2009, 0x07d0, 0x60c4, 0x9084, 0xfff0, 0x9005,
+	0x0110, 0x2009, 0x1b58, 0x080c, 0x88f1, 0x003e, 0x004e, 0x005e,
+	0x00ce, 0x00de, 0x00ee, 0x009e, 0x00be, 0x0005, 0x7a40, 0x9294,
+	0x00ff, 0x8217, 0x0005, 0x00d6, 0x2069, 0x19e9, 0x686b, 0x0001,
+	0x00de, 0x0005, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x00f1, 0x080c,
+	0x88e3, 0x0005, 0x0016, 0x2001, 0x180c, 0x200c, 0x9184, 0x0600,
+	0x9086, 0x0600, 0x0128, 0x0089, 0x080c, 0x88e3, 0x001e, 0x0005,
+	0xc1e5, 0x2001, 0x180c, 0x2102, 0x2001, 0x19ea, 0x2003, 0x0000,
+	0x2001, 0x19f5, 0x2003, 0x0000, 0x0c88, 0x0006, 0x0016, 0x0026,
+	0x2009, 0x1804, 0x2011, 0x0009, 0x080c, 0x2b04, 0x002e, 0x001e,
+	0x000e, 0x0005, 0x0016, 0x00c6, 0x0006, 0x080c, 0xaae0, 0x0106,
+	0x2061, 0x0100, 0x61a4, 0x60a7, 0x95f5, 0x0016, 0x0026, 0x2009,
+	0x1804, 0x2011, 0x0008, 0x080c, 0x2b04, 0x002e, 0x001e, 0x010e,
+	0x090c, 0xaafc, 0x000e, 0xa001, 0xa001, 0xa001, 0x61a6, 0x00ce,
+	0x001e, 0x0005, 0x00c6, 0x00d6, 0x0016, 0x0026, 0x2061, 0x0100,
+	0x2069, 0x0140, 0x080c, 0x76a5, 0x1510, 0x2001, 0x1a0e, 0x2004,
+	0x9005, 0x1904, 0xa109, 0x080c, 0x7747, 0x11a8, 0x2069, 0x0380,
+	0x6843, 0x0101, 0x6844, 0xd084, 0x1de8, 0x2061, 0x0100, 0x6020,
+	0xd0b4, 0x1120, 0x6024, 0xd084, 0x090c, 0x0d85, 0x6843, 0x0100,
+	0x080c, 0x88e3, 0x04b0, 0x00c6, 0x2061, 0x19e9, 0x00f0, 0x6904,
+	0x9194, 0x4000, 0x0598, 0x080c, 0xa08a, 0x080c, 0x2acb, 0x00c6,
+	0x2061, 0x19e9, 0x6134, 0x9192, 0x0008, 0x1278, 0x8108, 0x6136,
+	0x080c, 0xaae0, 0x6130, 0x080c, 0xaafc, 0x00ce, 0x81ff, 0x01c8,
+	0x080c, 0x88e3, 0x080c, 0xa07d, 0x00a0, 0x080c, 0xaae0, 0x6130,
+	0x91e5, 0x0000, 0x0150, 0x080c, 0xeb92, 0x080c, 0x88ec, 0x6003,
+	0x0001, 0x2009, 0x0014, 0x080c, 0xafcc, 0x080c, 0xaafc, 0x00ce,
+	0x0000, 0x002e, 0x001e, 0x00de, 0x00ce, 0x0005, 0x2001, 0x1a0e,
+	0x2004, 0x9005, 0x1db0, 0x00c6, 0x2061, 0x19e9, 0x6134, 0x9192,
+	0x0003, 0x1ad8, 0x8108, 0x6136, 0x00ce, 0x080c, 0x88e3, 0x080c,
+	0x6039, 0x2009, 0x1846, 0x2114, 0x8210, 0x220a, 0x0c10, 0x0096,
+	0x00c6, 0x00d6, 0x00e6, 0x0016, 0x0026, 0x080c, 0x88f9, 0x080c,
+	0xaae0, 0x2001, 0x0387, 0x2003, 0x0202, 0x2071, 0x19e9, 0x714c,
+	0x81ff, 0x0904, 0xa1c3, 0x2061, 0x0100, 0x2069, 0x0140, 0x080c,
+	0x76a5, 0x1518, 0x0036, 0x2019, 0x0002, 0x080c, 0xa380, 0x003e,
+	0x080c, 0xeb92, 0x704c, 0x9065, 0x0180, 0x2009, 0x004a, 0x6220,
+	0x9296, 0x0009, 0x1130, 0x6114, 0x2148, 0xa87b, 0x0006, 0x2009,
+	0x004a, 0x6003, 0x0003, 0x080c, 0xafcc, 0x2001, 0x0386, 0x2003,
+	0x5040, 0x080c, 0x7747, 0x0804, 0xa1c3, 0x6904, 0xd1f4, 0x0904,
+	0xa1d0, 0x080c, 0x2acb, 0x00c6, 0x704c, 0x9065, 0x090c, 0x0d85,
+	0x6020, 0x00ce, 0x9086, 0x0006, 0x1520, 0x61c8, 0x60c4, 0x9105,
+	0x1500, 0x714c, 0x9188, 0x0011, 0x2104, 0xd0e4, 0x01d0, 0x6214,
+	0x9294, 0x1800, 0x1128, 0x6224, 0x9294, 0x0002, 0x15e0, 0x0010,
+	0xc0e4, 0x200a, 0x6014, 0x9084, 0xe7fd, 0x9085, 0x0010, 0x6016,
+	0x704c, 0x2060, 0x080c, 0x9859, 0x2009, 0x0049, 0x080c, 0xafcc,
+	0x0450, 0x080c, 0xeb92, 0x704c, 0x9065, 0x9086, 0x1b56, 0x1158,
+	0x080c, 0xad9e, 0x1500, 0x2061, 0x1b56, 0x6064, 0x8000, 0x6066,
+	0x080c, 0x6039, 0x00c0, 0x0036, 0x2019, 0x0001, 0x080c, 0xa380,
+	0x003e, 0x714c, 0x2160, 0x2009, 0x004a, 0x6220, 0x9296, 0x0009,
 	0x1130, 0x6114, 0x2148, 0xa87b, 0x0006, 0x2009, 0x004a, 0x6003,
-	0x0003, 0x080c, 0xad4d, 0x2001, 0x0387, 0x2003, 0x0200, 0x080c,
-	0xa93a, 0x002e, 0x001e, 0x00ee, 0x00de, 0x00ce, 0x009e, 0x0005,
-	0xd1ec, 0x1904, 0x9fb2, 0x0804, 0x9fb4, 0x0026, 0x00e6, 0x2071,
-	0x19e6, 0x706c, 0xd084, 0x01e8, 0xc084, 0x706e, 0x714c, 0x81ff,
+	0x0003, 0x080c, 0xafcc, 0x2001, 0x0387, 0x2003, 0x0200, 0x080c,
+	0xaafc, 0x002e, 0x001e, 0x00ee, 0x00de, 0x00ce, 0x009e, 0x0005,
+	0xd1ec, 0x1904, 0xa169, 0x0804, 0xa16b, 0x0026, 0x00e6, 0x2071,
+	0x19e9, 0x706c, 0xd084, 0x01e8, 0xc084, 0x706e, 0x714c, 0x81ff,
 	0x01c0, 0x2071, 0x0100, 0x9188, 0x0008, 0x2114, 0x928e, 0x0006,
-	0x1138, 0x2009, 0x1984, 0x2011, 0x0012, 0x080c, 0x2ac3, 0x0048,
+	0x1138, 0x2009, 0x1984, 0x2011, 0x0012, 0x080c, 0x2b04, 0x0048,
 	0x928e, 0x0009, 0x0db0, 0x2009, 0x1984, 0x2011, 0x0016, 0x080c,
-	0x2ac3, 0x00ee, 0x002e, 0x0005, 0x9036, 0x2001, 0x19f0, 0x2004,
+	0x2b04, 0x00ee, 0x002e, 0x0005, 0x9036, 0x2001, 0x19f3, 0x2004,
 	0x9005, 0x0128, 0x9c06, 0x0128, 0x2c30, 0x600c, 0x0cc8, 0x9085,
-	0x0001, 0x0005, 0x00f6, 0x2079, 0x19e6, 0x610c, 0x9006, 0x600e,
+	0x0001, 0x0005, 0x00f6, 0x2079, 0x19e9, 0x610c, 0x9006, 0x600e,
 	0x6044, 0xc0fc, 0x6046, 0x86ff, 0x1140, 0x7824, 0x9c06, 0x1118,
 	0x7826, 0x782a, 0x0050, 0x792a, 0x0040, 0x00c6, 0x2660, 0x610e,
-	0x00ce, 0x7824, 0x9c06, 0x1108, 0x7e26, 0x080c, 0xa282, 0x080c,
-	0xcb6b, 0x00fe, 0x0005, 0x080c, 0x9b37, 0x7003, 0x1200, 0x7838,
+	0x00ce, 0x7824, 0x9c06, 0x1108, 0x7e26, 0x080c, 0xa441, 0x080c,
+	0xce07, 0x00fe, 0x0005, 0x080c, 0x9ce2, 0x7003, 0x1200, 0x7838,
 	0x7012, 0x783c, 0x7016, 0x00c6, 0x7820, 0x9086, 0x0004, 0x1148,
 	0x7810, 0x9005, 0x0130, 0x00b6, 0x2058, 0xb810, 0xb914, 0x00be,
 	0x0020, 0x2061, 0x1800, 0x607c, 0x6180, 0x9084, 0x00ff, 0x700a,
-	0x710e, 0x00ce, 0x60c3, 0x002c, 0x0804, 0x9ea4, 0x080c, 0x9b37,
+	0x710e, 0x00ce, 0x60c3, 0x002c, 0x0804, 0xa05a, 0x080c, 0x9ce2,
 	0x7003, 0x0f00, 0x7808, 0xd09c, 0x0128, 0xb810, 0x9084, 0x00ff,
-	0x700a, 0xb814, 0x700e, 0x60c3, 0x0008, 0x0804, 0x9ea4, 0x0156,
-	0x080c, 0x9b82, 0x7003, 0x0200, 0x080c, 0x8845, 0x20a9, 0x0006,
+	0x700a, 0xb814, 0x700e, 0x60c3, 0x0008, 0x0804, 0xa05a, 0x0156,
+	0x080c, 0x9d2d, 0x7003, 0x0200, 0x080c, 0x89b1, 0x20a9, 0x0006,
 	0x2011, 0xffec, 0x2019, 0xffed, 0x9ef0, 0x0002, 0x2305, 0x2072,
 	0x8e70, 0x2205, 0x2072, 0x8e70, 0x9398, 0x0002, 0x9290, 0x0002,
-	0x1f04, 0xa0a6, 0x60c3, 0x001c, 0x015e, 0x0804, 0x9ea4, 0x0016,
-	0x0026, 0x080c, 0x9b5e, 0x080c, 0x9b70, 0x9e80, 0x0004, 0x20e9,
+	0x1f04, 0xa26e, 0x60c3, 0x001c, 0x015e, 0x0804, 0xa05a, 0x0016,
+	0x0026, 0x080c, 0x9d09, 0x080c, 0x9d1b, 0x9e80, 0x0004, 0x20e9,
 	0x0000, 0x20a0, 0x7814, 0x0096, 0x2048, 0xa800, 0x2048, 0xa860,
 	0x20e0, 0xa85c, 0x9080, 0x0021, 0x2098, 0x009e, 0x7808, 0x9088,
 	0x0002, 0x21a8, 0x9192, 0x0010, 0x1250, 0x4003, 0x9080, 0x0004,
-	0x8003, 0x60c2, 0x080c, 0x9ea4, 0x002e, 0x001e, 0x0005, 0x20a9,
-	0x0010, 0x4003, 0x080c, 0xa6fe, 0x20a1, 0x0240, 0x22a8, 0x4003,
-	0x0c68, 0x080c, 0x9b37, 0x7003, 0x6200, 0x7808, 0x700e, 0x60c3,
-	0x0008, 0x0804, 0x9ea4, 0x0016, 0x0026, 0x080c, 0x9b37, 0x20e9,
+	0x8003, 0x60c2, 0x080c, 0xa05a, 0x002e, 0x001e, 0x0005, 0x20a9,
+	0x0010, 0x4003, 0x080c, 0xa8c0, 0x20a1, 0x0240, 0x22a8, 0x4003,
+	0x0c68, 0x080c, 0x9ce2, 0x7003, 0x6200, 0x7808, 0x700e, 0x60c3,
+	0x0008, 0x0804, 0xa05a, 0x0016, 0x0026, 0x080c, 0x9ce2, 0x20e9,
 	0x0000, 0x20a1, 0x024c, 0x7814, 0x0096, 0x2048, 0xa800, 0x2048,
 	0xa860, 0x20e0, 0xa85c, 0x9080, 0x0023, 0x2098, 0x009e, 0x7808,
-	0x9088, 0x0002, 0x21a8, 0x4003, 0x8003, 0x60c2, 0x080c, 0x9ea4,
+	0x9088, 0x0002, 0x21a8, 0x4003, 0x8003, 0x60c2, 0x080c, 0xa05a,
 	0x002e, 0x001e, 0x0005, 0x00e6, 0x00c6, 0x0006, 0x0126, 0x2091,
-	0x8000, 0x2071, 0x19e6, 0x7010, 0x2060, 0x8cff, 0x0188, 0x080c,
-	0xcb91, 0x1110, 0x080c, 0xb693, 0x600c, 0x0006, 0x080c, 0xce0d,
-	0x600f, 0x0000, 0x080c, 0xacb0, 0x080c, 0xa282, 0x00ce, 0x0c68,
+	0x8000, 0x2071, 0x19e9, 0x7010, 0x2060, 0x8cff, 0x0188, 0x080c,
+	0xce2d, 0x1110, 0x080c, 0xb91f, 0x600c, 0x0006, 0x080c, 0xd0a9,
+	0x600f, 0x0000, 0x080c, 0xaf2e, 0x080c, 0xa441, 0x00ce, 0x0c68,
 	0x2c00, 0x7012, 0x700e, 0x012e, 0x000e, 0x00ce, 0x00ee, 0x0005,
 	0x0126, 0x0156, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0026,
 	0x0016, 0x0006, 0x2091, 0x8000, 0x2001, 0x180c, 0x200c, 0x918c,
-	0xe7ff, 0x2102, 0x2069, 0x0100, 0x2079, 0x0140, 0x2071, 0x19e6,
-	0x7030, 0x2060, 0x8cff, 0x0548, 0x080c, 0x9ed4, 0x6ac0, 0x68c3,
-	0x0000, 0x080c, 0x8780, 0x00c6, 0x2061, 0x0100, 0x080c, 0xa84f,
-	0x00ce, 0x20a9, 0x01f4, 0x04b1, 0x080c, 0x967a, 0x6044, 0xd0ac,
-	0x1128, 0x2001, 0x1987, 0x2004, 0x604a, 0x0020, 0x2009, 0x0013,
-	0x080c, 0xad4d, 0x000e, 0x001e, 0x002e, 0x006e, 0x00ce, 0x00de,
+	0xe7ff, 0x2102, 0x2069, 0x0100, 0x2079, 0x0140, 0x2071, 0x19e9,
+	0x7030, 0x2060, 0x8cff, 0x0548, 0x080c, 0xa08a, 0x6ac0, 0x68c3,
+	0x0000, 0x080c, 0x88ec, 0x00c6, 0x2061, 0x0100, 0x080c, 0xaa11,
+	0x00ce, 0x20a9, 0x01f4, 0x04b1, 0x080c, 0x97fe, 0x6044, 0xd0ac,
+	0x1128, 0x2001, 0x1989, 0x2004, 0x604a, 0x0020, 0x2009, 0x0013,
+	0x080c, 0xafcc, 0x000e, 0x001e, 0x002e, 0x006e, 0x00ce, 0x00de,
 	0x00ee, 0x00fe, 0x015e, 0x012e, 0x0005, 0x2001, 0x1800, 0x2004,
-	0x9096, 0x0001, 0x0d78, 0x9096, 0x0004, 0x0d60, 0x080c, 0x8780,
+	0x9096, 0x0001, 0x0d78, 0x9096, 0x0004, 0x0d60, 0x080c, 0x88ec,
 	0x6814, 0x9084, 0x0001, 0x0110, 0x68a7, 0x95f5, 0x6817, 0x0008,
-	0x68c3, 0x0000, 0x2011, 0x5ef7, 0x080c, 0x86c8, 0x20a9, 0x01f4,
+	0x68c3, 0x0000, 0x2011, 0x5fe3, 0x080c, 0x8834, 0x20a9, 0x01f4,
 	0x0009, 0x08c0, 0x6824, 0xd094, 0x0140, 0x6827, 0x0004, 0x7804,
-	0x9084, 0x4000, 0x190c, 0x2a8a, 0x0090, 0xd084, 0x0118, 0x6827,
-	0x0001, 0x0010, 0x1f04, 0xa19a, 0x7804, 0x9084, 0x1000, 0x0138,
-	0x2001, 0x0100, 0x080c, 0x2a7a, 0x9006, 0x080c, 0x2a7a, 0x0005,
+	0x9084, 0x4000, 0x190c, 0x2acb, 0x0090, 0xd084, 0x0118, 0x6827,
+	0x0001, 0x0010, 0x1f04, 0xa362, 0x7804, 0x9084, 0x1000, 0x0138,
+	0x2001, 0x0100, 0x080c, 0x2abb, 0x9006, 0x080c, 0x2abb, 0x0005,
 	0x0126, 0x0156, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0026,
 	0x0016, 0x0006, 0x2091, 0x8000, 0x2001, 0x180c, 0x200c, 0x918c,
 	0xdbff, 0x2102, 0x2069, 0x0100, 0x2079, 0x0140, 0x2071, 0x0380,
-	0x701c, 0x0006, 0x701f, 0x0202, 0x2071, 0x19e6, 0x704c, 0x2060,
-	0x8cff, 0x0904, 0xa231, 0x9386, 0x0002, 0x1128, 0x6814, 0x9084,
-	0x0002, 0x0904, 0xa231, 0x68af, 0x95f5, 0x6817, 0x0010, 0x2009,
-	0x00fa, 0x8109, 0x1df0, 0x69c6, 0x68cb, 0x0008, 0x080c, 0x878d,
-	0x080c, 0x1e2e, 0x2001, 0x0032, 0x6920, 0xd1bc, 0x0130, 0x8001,
-	0x1dd8, 0x692c, 0x918d, 0x0008, 0x692e, 0x20a9, 0x03e8, 0x6824,
-	0xd094, 0x0140, 0x6827, 0x0004, 0x7804, 0x9084, 0x4000, 0x190c,
-	0x2a8a, 0x0090, 0xd08c, 0x0118, 0x6827, 0x0002, 0x0010, 0x1f04,
-	0xa1ff, 0x7804, 0x9084, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c,
-	0x2a7a, 0x9006, 0x080c, 0x2a7a, 0x6827, 0x4000, 0x6824, 0x83ff,
-	0x1180, 0x2009, 0x0049, 0x6020, 0x9086, 0x0009, 0x0150, 0x080c,
-	0x96d5, 0x6044, 0xd0ac, 0x1118, 0x6003, 0x0002, 0x0010, 0x080c,
-	0xad4d, 0x000e, 0x2071, 0x0380, 0xd08c, 0x1110, 0x701f, 0x0200,
-	0x000e, 0x001e, 0x002e, 0x006e, 0x00ce, 0x00de, 0x00ee, 0x00fe,
-	0x015e, 0x012e, 0x0005, 0x00d6, 0x0126, 0x2091, 0x8000, 0x2069,
-	0x19e6, 0x6a06, 0x012e, 0x00de, 0x0005, 0x00d6, 0x0126, 0x2091,
-	0x8000, 0x2069, 0x19e6, 0x6a3e, 0x012e, 0x00de, 0x0005, 0x080c,
-	0x9c8f, 0x785c, 0x7032, 0x7042, 0x7047, 0x1000, 0x00f8, 0x080c,
-	0x9c8f, 0x785c, 0x7032, 0x7042, 0x7047, 0x4000, 0x00b8, 0x080c,
-	0x9c8f, 0x785c, 0x7032, 0x7042, 0x7047, 0x2000, 0x0078, 0x080c,
-	0x9c8f, 0x785c, 0x7032, 0x7042, 0x7047, 0x0400, 0x0038, 0x080c,
-	0x9c8f, 0x785c, 0x7032, 0x7042, 0x7047, 0x0200, 0x60c3, 0x0020,
-	0x0804, 0x9ea4, 0x00e6, 0x2071, 0x19e6, 0x702c, 0x9005, 0x0110,
-	0x8001, 0x702e, 0x00ee, 0x0005, 0x00f6, 0x00e6, 0x00d6, 0x00c6,
-	0x0076, 0x0066, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x19e6,
-	0x7620, 0x2660, 0x2678, 0x2039, 0x0001, 0x87ff, 0x0904, 0xa327,
-	0x8cff, 0x0904, 0xa327, 0x6020, 0x9086, 0x0006, 0x1904, 0xa322,
-	0x88ff, 0x0138, 0x2800, 0x9c06, 0x1904, 0xa322, 0x2039, 0x0000,
-	0x0050, 0x6010, 0x9b06, 0x1904, 0xa322, 0x85ff, 0x0120, 0x605c,
-	0x9106, 0x1904, 0xa322, 0x7030, 0x9c06, 0x15b0, 0x2069, 0x0100,
-	0x68c0, 0x9005, 0x1160, 0x6824, 0xd084, 0x0148, 0x6827, 0x0001,
-	0x080c, 0x8780, 0x080c, 0xa3ac, 0x7033, 0x0000, 0x0428, 0x080c,
-	0x8780, 0x6820, 0xd0b4, 0x0110, 0x68a7, 0x95f5, 0x6817, 0x0008,
-	0x68c3, 0x0000, 0x080c, 0xa3ac, 0x7033, 0x0000, 0x0036, 0x2069,
-	0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c,
-	0x2a7a, 0x9006, 0x080c, 0x2a7a, 0x2069, 0x0100, 0x6824, 0xd084,
-	0x0110, 0x6827, 0x0001, 0x003e, 0x7020, 0x9c36, 0x1110, 0x660c,
-	0x7622, 0x701c, 0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00,
-	0x701e, 0x0010, 0x701f, 0x0000, 0x660c, 0x0066, 0x2c00, 0x9f06,
-	0x0110, 0x7e0e, 0x0008, 0x2678, 0x89ff, 0x1168, 0x600f, 0x0000,
-	0x6014, 0x0096, 0x2048, 0x080c, 0xc978, 0x0110, 0x080c, 0xe3e8,
-	0x009e, 0x080c, 0xaceb, 0x080c, 0xa282, 0x88ff, 0x1190, 0x00ce,
-	0x0804, 0xa29d, 0x2c78, 0x600c, 0x2060, 0x0804, 0xa29d, 0x9006,
-	0x012e, 0x000e, 0x006e, 0x007e, 0x00ce, 0x00de, 0x00ee, 0x00fe,
-	0x0005, 0x601b, 0x0000, 0x00ce, 0x98c5, 0x0001, 0x0c88, 0x00f6,
-	0x00e6, 0x00d6, 0x0096, 0x00c6, 0x0066, 0x0026, 0x0006, 0x0126,
-	0x2091, 0x8000, 0x2071, 0x19e6, 0x7648, 0x2660, 0x2678, 0x8cff,
-	0x0904, 0xa39b, 0x6020, 0x9086, 0x0006, 0x1904, 0xa396, 0x87ff,
-	0x0128, 0x2700, 0x9c06, 0x1904, 0xa396, 0x0040, 0x6010, 0x9b06,
-	0x15e8, 0x85ff, 0x0118, 0x605c, 0x9106, 0x15c0, 0x704c, 0x9c06,
-	0x1168, 0x0036, 0x2019, 0x0001, 0x080c, 0xa1b8, 0x703f, 0x0000,
-	0x9006, 0x704e, 0x706a, 0x7052, 0x706e, 0x003e, 0x7048, 0x9c36,
-	0x1110, 0x660c, 0x764a, 0x7044, 0x9c36, 0x1140, 0x2c00, 0x9f36,
-	0x0118, 0x2f00, 0x7046, 0x0010, 0x7047, 0x0000, 0x660c, 0x0066,
-	0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000,
-	0x6014, 0x2048, 0x080c, 0xc978, 0x0110, 0x080c, 0xe3e8, 0x080c,
-	0xaceb, 0x87ff, 0x1198, 0x00ce, 0x0804, 0xa347, 0x2c78, 0x600c,
-	0x2060, 0x0804, 0xa347, 0x9006, 0x012e, 0x000e, 0x002e, 0x006e,
-	0x00ce, 0x009e, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x601b, 0x0000,
-	0x00ce, 0x97bd, 0x0001, 0x0c80, 0x00e6, 0x2071, 0x19e6, 0x9006,
-	0x7032, 0x700a, 0x7004, 0x9086, 0x0003, 0x0158, 0x2001, 0x1800,
-	0x2004, 0x9086, 0x0002, 0x1118, 0x7007, 0x0005, 0x0010, 0x7007,
-	0x0000, 0x00ee, 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x0066, 0x0026,
-	0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x19e6, 0x2c10, 0x7648,
-	0x2660, 0x2678, 0x8cff, 0x0540, 0x2200, 0x9c06, 0x1508, 0x7048,
-	0x9c36, 0x1110, 0x660c, 0x764a, 0x7044, 0x9c36, 0x1140, 0x2c00,
-	0x9f36, 0x0118, 0x2f00, 0x7046, 0x0010, 0x7047, 0x0000, 0x660c,
-	0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000,
-	0x6004, 0x9086, 0x0040, 0x090c, 0x967a, 0x9085, 0x0001, 0x0020,
-	0x2c78, 0x600c, 0x2060, 0x08b0, 0x012e, 0x000e, 0x002e, 0x006e,
-	0x00ce, 0x00ee, 0x00fe, 0x0005, 0x0096, 0x00f6, 0x00e6, 0x00d6,
-	0x00c6, 0x0066, 0x0026, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071,
-	0x19e6, 0x7610, 0x2660, 0x2678, 0x8cff, 0x0904, 0xa499, 0x6010,
-	0x00b6, 0x2058, 0xb8a0, 0x00be, 0x9206, 0x1904, 0xa494, 0x7030,
-	0x9c06, 0x1520, 0x2069, 0x0100, 0x68c0, 0x9005, 0x0904, 0xa46b,
-	0x080c, 0x9ed4, 0x68c3, 0x0000, 0x080c, 0xa3ac, 0x7033, 0x0000,
-	0x0036, 0x2069, 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001,
-	0x0100, 0x080c, 0x2a7a, 0x9006, 0x080c, 0x2a7a, 0x2069, 0x0100,
-	0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x7010, 0x9c36,
-	0x1110, 0x660c, 0x7612, 0x700c, 0x9c36, 0x1140, 0x2c00, 0x9f36,
-	0x0118, 0x2f00, 0x700e, 0x0010, 0x700f, 0x0000, 0x660c, 0x0066,
-	0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000,
-	0x080c, 0xcb80, 0x1180, 0x080c, 0x326f, 0x080c, 0xcb91, 0x1518,
-	0x080c, 0xb693, 0x0400, 0x080c, 0xa3ac, 0x6824, 0xd084, 0x09b0,
-	0x6827, 0x0001, 0x0898, 0x080c, 0xcb91, 0x1118, 0x080c, 0xb693,
-	0x0090, 0x6014, 0x2048, 0x080c, 0xc978, 0x0168, 0x6020, 0x9086,
-	0x0003, 0x1508, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c,
-	0x6de2, 0x080c, 0xcb6b, 0x080c, 0xce0d, 0x080c, 0xaceb, 0x080c,
-	0xa282, 0x00ce, 0x0804, 0xa414, 0x2c78, 0x600c, 0x2060, 0x0804,
-	0xa414, 0x012e, 0x000e, 0x002e, 0x006e, 0x00ce, 0x00de, 0x00ee,
-	0x00fe, 0x009e, 0x0005, 0x6020, 0x9086, 0x0006, 0x1d20, 0x080c,
-	0xe3e8, 0x0c08, 0x00d6, 0x080c, 0x9b82, 0x7003, 0x0200, 0x7007,
-	0x0014, 0x60c3, 0x0014, 0x20e1, 0x0001, 0x2099, 0x1988, 0x20e9,
-	0x0000, 0x20a1, 0x0250, 0x20a9, 0x0004, 0x4003, 0x7023, 0x0004,
-	0x7027, 0x7878, 0x080c, 0x9ea4, 0x00de, 0x0005, 0x080c, 0x9b82,
-	0x700b, 0x0800, 0x7814, 0x9084, 0xff00, 0x700e, 0x7814, 0x9084,
-	0x00ff, 0x7022, 0x782c, 0x7026, 0x7860, 0x9084, 0x00ff, 0x9085,
-	0x0200, 0x7002, 0x7860, 0x9084, 0xff00, 0x8007, 0x7006, 0x60c2,
-	0x0804, 0x9ea4, 0x00b6, 0x00d6, 0x0016, 0x00d6, 0x2f68, 0x2009,
-	0x0035, 0x080c, 0xd013, 0x00de, 0x1904, 0xa547, 0x080c, 0x9b37,
-	0x7003, 0x1300, 0x782c, 0x080c, 0xa656, 0x2068, 0x6820, 0x9086,
-	0x0003, 0x0560, 0x7810, 0x2058, 0xbaa0, 0x080c, 0xabe2, 0x11d8,
-	0x9286, 0x007e, 0x1128, 0x700b, 0x00ff, 0x700f, 0xfffe, 0x0498,
-	0x9286, 0x007f, 0x1128, 0x700b, 0x00ff, 0x700f, 0xfffd, 0x0458,
-	0x9284, 0xff80, 0x0180, 0x9286, 0x0080, 0x1128, 0x700b, 0x00ff,
-	0x700f, 0xfffc, 0x0400, 0x92d8, 0x1000, 0x2b5c, 0xb810, 0x700a,
-	0xb814, 0x700e, 0x00c0, 0xb884, 0x700e, 0x00a8, 0x080c, 0xabe2,
-	0x1130, 0x7810, 0x2058, 0xb8a0, 0x9082, 0x007e, 0x0250, 0x00d6,
-	0x2069, 0x181f, 0x2d04, 0x700a, 0x8d68, 0x2d04, 0x700e, 0x00de,
-	0x0010, 0x6034, 0x700e, 0x7838, 0x7012, 0x783c, 0x7016, 0x60c3,
-	0x000c, 0x001e, 0x00de, 0x080c, 0x9ea4, 0x00be, 0x0005, 0x781b,
-	0x0001, 0x7803, 0x0006, 0x001e, 0x00de, 0x00be, 0x0005, 0x792c,
-	0x9180, 0x0008, 0x200c, 0x9186, 0x0006, 0x01c0, 0x9186, 0x0003,
-	0x0904, 0xa5c6, 0x9186, 0x0005, 0x0904, 0xa5ae, 0x9186, 0x0004,
-	0x05f0, 0x9186, 0x0008, 0x0904, 0xa5b7, 0x7807, 0x0037, 0x782f,
-	0x0003, 0x7817, 0x1700, 0x080c, 0xa633, 0x0005, 0x080c, 0xa5f4,
-	0x00d6, 0x0026, 0x792c, 0x2168, 0x2009, 0x4000, 0x6800, 0x6a44,
-	0xd2fc, 0x11f8, 0x0002, 0xa58e, 0xa599, 0xa590, 0xa599, 0xa595,
-	0xa58e, 0xa58e, 0xa599, 0xa599, 0xa599, 0xa599, 0xa58e, 0xa58e,
-	0xa58e, 0xa58e, 0xa58e, 0xa599, 0xa58e, 0xa599, 0x080c, 0x0d7d,
-	0x6824, 0xd0e4, 0x0110, 0xd0cc, 0x0110, 0x900e, 0x0010, 0x2009,
-	0x2000, 0x682c, 0x7022, 0x6830, 0x7026, 0x0804, 0xa5ed, 0x080c,
-	0xa5f4, 0x00d6, 0x0026, 0x792c, 0x2168, 0x2009, 0x4000, 0x6a00,
-	0x9286, 0x0002, 0x1108, 0x900e, 0x0804, 0xa5ed, 0x080c, 0xa5f4,
-	0x00d6, 0x0026, 0x792c, 0x2168, 0x2009, 0x4000, 0x04b0, 0x04e1,
-	0x00d6, 0x0026, 0x792c, 0x2168, 0x2009, 0x4000, 0x9286, 0x0005,
-	0x0118, 0x9286, 0x0002, 0x1108, 0x900e, 0x0438, 0x0469, 0x00d6,
-	0x0026, 0x792c, 0x2168, 0x6814, 0x6924, 0xc185, 0x6926, 0x0096,
-	0x2048, 0xa9ac, 0xa834, 0x9112, 0xa9b0, 0xa838, 0x009e, 0x9103,
-	0x7022, 0x7226, 0x792c, 0x9180, 0x0011, 0x2004, 0xd0fc, 0x1148,
-	0x9180, 0x0000, 0x2004, 0x908e, 0x0002, 0x0130, 0x908e, 0x0004,
-	0x0118, 0x2009, 0x4000, 0x0008, 0x900e, 0x712a, 0x60c3, 0x0018,
-	0x002e, 0x00de, 0x0804, 0x9ea4, 0x00b6, 0x0036, 0x0046, 0x0056,
-	0x0066, 0x080c, 0x9b82, 0x9006, 0x7003, 0x0200, 0x7938, 0x710a,
-	0x793c, 0x710e, 0x7810, 0x2058, 0xb8a0, 0x080c, 0xabe2, 0x1118,
-	0x9092, 0x007e, 0x0268, 0x00d6, 0x2069, 0x181f, 0x2d2c, 0x8d68,
-	0x2d34, 0x90d8, 0x1000, 0x2b5c, 0xbb10, 0xbc14, 0x00de, 0x0028,
-	0x901e, 0xbc84, 0x2029, 0x0000, 0x6634, 0x782c, 0x9080, 0x0008,
-	0x2004, 0x9086, 0x0003, 0x1128, 0x7512, 0x7616, 0x731a, 0x741e,
-	0x0020, 0x7312, 0x7416, 0x751a, 0x761e, 0x006e, 0x005e, 0x004e,
-	0x003e, 0x00be, 0x0005, 0x080c, 0x9b82, 0x7003, 0x0100, 0x782c,
-	0x700a, 0x7814, 0x700e, 0x700e, 0x60c3, 0x0008, 0x0804, 0x9ea4,
-	0x080c, 0x9b2e, 0x7003, 0x1400, 0x7838, 0x700a, 0x0079, 0x783c,
-	0x700e, 0x782c, 0x7012, 0x7830, 0x7016, 0x7834, 0x9084, 0x00ff,
-	0x8007, 0x701a, 0x60c3, 0x0010, 0x0804, 0x9ea4, 0x00e6, 0x2071,
-	0x0240, 0x0006, 0x00f6, 0x2078, 0x7810, 0x00b6, 0x2058, 0xb8d4,
-	0xd084, 0x0120, 0x784c, 0x702a, 0x7850, 0x702e, 0x00be, 0x00fe,
-	0x000e, 0x00ee, 0x0005, 0x080c, 0x9b79, 0x7003, 0x0100, 0x782c,
-	0x700a, 0x7814, 0x700e, 0x60c3, 0x0008, 0x0804, 0x9ea4, 0x00a9,
-	0x7914, 0x712a, 0x60c3, 0x0000, 0x60a7, 0x9575, 0x0026, 0x080c,
-	0x29e5, 0x0228, 0x2011, 0x0101, 0x2204, 0xc0c5, 0x2012, 0x002e,
-	0x080c, 0x9ec7, 0x080c, 0x8777, 0x0005, 0x0036, 0x0096, 0x00d6,
-	0x00e6, 0x7860, 0x2048, 0xaa7c, 0x9296, 0x00c0, 0x9294, 0xfffd,
-	0xaa7e, 0xaa80, 0x9294, 0x0300, 0xaa82, 0xa96c, 0x9194, 0x00ff,
-	0xab74, 0x9384, 0x00ff, 0x908d, 0xc200, 0xa96e, 0x9384, 0xff00,
-	0x9215, 0xaa76, 0xa870, 0xaa78, 0xa87a, 0xaa72, 0x00d6, 0x2069,
-	0x0200, 0x080c, 0xa713, 0x00de, 0x20e9, 0x0000, 0x20a1, 0x0240,
-	0x20a9, 0x000a, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x001b, 0x2098,
-	0x4003, 0x60a3, 0x0035, 0xaa68, 0x9294, 0x7000, 0x9286, 0x3000,
-	0x0110, 0x60a3, 0x0037, 0x00ee, 0x00de, 0x009e, 0x003e, 0x0005,
-	0x900e, 0x7814, 0x0096, 0x2048, 0xa87c, 0xd0fc, 0x01c0, 0x9084,
-	0x0003, 0x11a8, 0x2001, 0x180c, 0x2004, 0xd0bc, 0x0180, 0x7824,
-	0xd0cc, 0x1168, 0xd0c4, 0x1158, 0xa8a8, 0x9005, 0x1140, 0x2001,
-	0x180c, 0x200c, 0xc1d5, 0x2102, 0x2009, 0x19b1, 0x210c, 0x009e,
-	0x918d, 0x0092, 0x0010, 0x2009, 0x0096, 0x60ab, 0x0036, 0x0026,
-	0x2110, 0x900e, 0x080c, 0x2ac3, 0x002e, 0x0005, 0x2009, 0x0009,
-	0x00a0, 0x2009, 0x000a, 0x0088, 0x2009, 0x000b, 0x0070, 0x2009,
-	0x000c, 0x0058, 0x2009, 0x000d, 0x0040, 0x2009, 0x000e, 0x0028,
-	0x2009, 0x000f, 0x0010, 0x2009, 0x0008, 0x6912, 0x0005, 0x080c,
-	0x9b37, 0x0016, 0x0026, 0x0096, 0x00d6, 0x7814, 0x2048, 0x7013,
-	0x0138, 0x2001, 0x1837, 0x2004, 0x9084, 0x0028, 0x1138, 0x2001,
-	0x197b, 0x2004, 0x9086, 0xaaaa, 0x1904, 0xa7b8, 0x7003, 0x5400,
-	0x00c6, 0x2061, 0x1800, 0x607c, 0x9084, 0x00ff, 0xa998, 0x810f,
-	0x918c, 0xff00, 0x9105, 0x700a, 0x6080, 0x700e, 0xa998, 0x918c,
-	0xff00, 0x7112, 0x20a9, 0x0004, 0x2009, 0x1805, 0x2e10, 0x9290,
-	0x0006, 0x2104, 0x2012, 0x8108, 0x8210, 0x1f04, 0xa749, 0x20a9,
-	0x0004, 0x2009, 0x1801, 0x2104, 0x2012, 0x8108, 0x8210, 0x1f04,
-	0xa753, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0029, 0x2098, 0x2009,
-	0x0006, 0x20a9, 0x0001, 0x4002, 0x8007, 0x2012, 0x8210, 0x8109,
-	0x1dc0, 0x00d6, 0x2069, 0x0200, 0x080c, 0xa6fe, 0x00de, 0x2071,
-	0x0240, 0x2011, 0x0240, 0x2009, 0x0002, 0x20a9, 0x0001, 0x4002,
-	0x8007, 0x2012, 0x8210, 0x8109, 0x1dc0, 0x2009, 0x0008, 0x20a9,
-	0x0001, 0x4002, 0x8007, 0x2012, 0x8210, 0x8109, 0x1dc0, 0xa85c,
-	0x9080, 0x0031, 0x2098, 0x2009, 0x0008, 0x20a9, 0x0001, 0x4002,
-	0x8007, 0x2012, 0x8210, 0x8109, 0x1dc0, 0x00ce, 0x60c3, 0x004c,
-	0x60a3, 0x0056, 0x60a7, 0x9575, 0x2001, 0x1837, 0x2004, 0x9084,
-	0x0028, 0x1168, 0x080c, 0x753d, 0x0150, 0x6028, 0xc0bd, 0x602a,
-	0x2009, 0x1804, 0x2011, 0x0029, 0x080c, 0x2ac3, 0x0010, 0x080c,
-	0x9ea4, 0x080c, 0x8777, 0x00de, 0x009e, 0x002e, 0x001e, 0x0005,
-	0x00e6, 0x2071, 0x0240, 0x2001, 0x2200, 0x9085, 0x00ff, 0x7002,
-	0x7007, 0xffff, 0x2071, 0x0100, 0x709b, 0x00ff, 0x00ee, 0x0804,
-	0xa72e, 0x080c, 0x9b37, 0x0016, 0x0026, 0x0096, 0x00d6, 0x7814,
-	0x2048, 0x7013, 0x0138, 0x7003, 0x5500, 0x00c6, 0xa89c, 0x9084,
-	0x00ff, 0xa998, 0x810f, 0x918c, 0xff00, 0x9105, 0x700a, 0xa99c,
-	0x918c, 0xff00, 0xa8a0, 0x9084, 0x00ff, 0x9105, 0x700e, 0xa998,
-	0x918c, 0xff00, 0x2061, 0x1800, 0x607c, 0x9084, 0x00ff, 0x910d,
-	0x7112, 0x6180, 0x7116, 0x2009, 0x0008, 0xa860, 0x20e0, 0xa85c,
-	0x9080, 0x0029, 0x2098, 0x2e10, 0x9290, 0x0006, 0x20a9, 0x0001,
-	0x4002, 0x8007, 0x2012, 0x8210, 0x8109, 0x1dc0, 0x20a9, 0x0004,
-	0x2009, 0x1805, 0x2104, 0x2012, 0x8108, 0x8210, 0x1f04, 0xa80a,
-	0x20a9, 0x0002, 0x2009, 0x1801, 0x2104, 0x2012, 0x8108, 0x8210,
-	0x1f04, 0xa814, 0x00d6, 0x0016, 0x2069, 0x0200, 0x080c, 0xa6fe,
-	0x001e, 0x00de, 0x2071, 0x0240, 0x20a9, 0x0002, 0x2009, 0x1803,
-	0x2011, 0x0240, 0x2104, 0x2012, 0x8108, 0x8210, 0x1f04, 0xa82a,
-	0x2009, 0x0008, 0x4002, 0x8007, 0x2012, 0x8210, 0x8109, 0x1dd0,
-	0x9006, 0x20a9, 0x0008, 0x2012, 0x8210, 0x1f04, 0xa83b, 0x00ce,
-	0x60c3, 0x004c, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x080c, 0x9ea4,
-	0x080c, 0x8777, 0x00de, 0x009e, 0x002e, 0x001e, 0x0005, 0x00d6,
-	0x9290, 0x0018, 0x8214, 0x20e9, 0x0000, 0x2069, 0x0200, 0x6813,
-	0x0000, 0x22a8, 0x9284, 0x00e0, 0x0128, 0x20a9, 0x0020, 0x9292,
-	0x0020, 0x0008, 0x9016, 0x20a1, 0x0240, 0x9006, 0x4004, 0x82ff,
-	0x0120, 0x6810, 0x8000, 0x6812, 0x0c60, 0x00de, 0x0005, 0x00f6,
-	0x00e6, 0x00d6, 0x00c6, 0x00a6, 0x0096, 0x0066, 0x0126, 0x2091,
-	0x8000, 0x2071, 0x19e6, 0x7610, 0x2660, 0x2678, 0x8cff, 0x0904,
-	0xa8fb, 0x7030, 0x9c06, 0x1520, 0x2069, 0x0100, 0x68c0, 0x9005,
-	0x0904, 0xa8cd, 0x080c, 0x9ed4, 0x68c3, 0x0000, 0x080c, 0xa3ac,
+	0x701c, 0x0006, 0x701f, 0x0202, 0x2071, 0x19e9, 0x704c, 0x2060,
+	0x8cff, 0x0904, 0xa3fd, 0x080c, 0xad50, 0x0904, 0xa3fd, 0x9386,
+	0x0002, 0x1128, 0x6814, 0x9084, 0x0002, 0x0904, 0xa3fd, 0x68af,
+	0x95f5, 0x6817, 0x0010, 0x2009, 0x00fa, 0x8109, 0x1df0, 0x69c6,
+	0x68cb, 0x0008, 0x080c, 0x88f9, 0x080c, 0x1e65, 0x2001, 0x0032,
+	0x6920, 0xd1bc, 0x0130, 0x8001, 0x1dd8, 0x692c, 0x918d, 0x0008,
+	0x692e, 0x20a9, 0x03e8, 0x6824, 0xd094, 0x0140, 0x6827, 0x0004,
+	0x7804, 0x9084, 0x4000, 0x190c, 0x2acb, 0x0090, 0xd08c, 0x0118,
+	0x6827, 0x0002, 0x0010, 0x1f04, 0xa3cb, 0x7804, 0x9084, 0x1000,
+	0x0138, 0x2001, 0x0100, 0x080c, 0x2abb, 0x9006, 0x080c, 0x2abb,
+	0x6827, 0x4000, 0x6824, 0x83ff, 0x1180, 0x2009, 0x0049, 0x6020,
+	0x9086, 0x0009, 0x0150, 0x080c, 0x9859, 0x6044, 0xd0ac, 0x1118,
+	0x6003, 0x0002, 0x0010, 0x080c, 0xafcc, 0x000e, 0x2071, 0x0380,
+	0xd08c, 0x1110, 0x701f, 0x0200, 0x000e, 0x001e, 0x002e, 0x006e,
+	0x00ce, 0x00de, 0x00ee, 0x00fe, 0x015e, 0x012e, 0x0005, 0x00d6,
+	0x0126, 0x2091, 0x8000, 0x2069, 0x19e9, 0x6a06, 0x012e, 0x00de,
+	0x0005, 0x00d6, 0x0126, 0x2091, 0x8000, 0x2069, 0x19e9, 0x6a3e,
+	0x012e, 0x00de, 0x0005, 0x080c, 0x9e3a, 0x7047, 0x1000, 0x0098,
+	0x080c, 0x9e3a, 0x7047, 0x4000, 0x0070, 0x080c, 0x9e3a, 0x7047,
+	0x2000, 0x0048, 0x080c, 0x9e3a, 0x7047, 0x0400, 0x0020, 0x080c,
+	0x9e3a, 0x7047, 0x0200, 0x785c, 0x7032, 0x60c3, 0x0020, 0x0804,
+	0xa05a, 0x00e6, 0x2071, 0x19e9, 0x702c, 0x9005, 0x0110, 0x8001,
+	0x702e, 0x00ee, 0x0005, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0076,
+	0x0066, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x19e9, 0x7620,
+	0x2660, 0x2678, 0x2039, 0x0001, 0x87ff, 0x0904, 0xa4e6, 0x8cff,
+	0x0904, 0xa4e6, 0x6020, 0x9086, 0x0006, 0x1904, 0xa4e1, 0x88ff,
+	0x0138, 0x2800, 0x9c06, 0x1904, 0xa4e1, 0x2039, 0x0000, 0x0050,
+	0x6010, 0x9b06, 0x1904, 0xa4e1, 0x85ff, 0x0120, 0x605c, 0x9106,
+	0x1904, 0xa4e1, 0x7030, 0x9c06, 0x15b0, 0x2069, 0x0100, 0x68c0,
+	0x9005, 0x1160, 0x6824, 0xd084, 0x0148, 0x6827, 0x0001, 0x080c,
+	0x88ec, 0x080c, 0xa56e, 0x7033, 0x0000, 0x0428, 0x080c, 0x88ec,
+	0x6820, 0xd0b4, 0x0110, 0x68a7, 0x95f5, 0x6817, 0x0008, 0x68c3,
+	0x0000, 0x080c, 0xa56e, 0x7033, 0x0000, 0x0036, 0x2069, 0x0140,
+	0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2abb,
+	0x9006, 0x080c, 0x2abb, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110,
+	0x6827, 0x0001, 0x003e, 0x7020, 0x9c36, 0x1110, 0x660c, 0x7622,
+	0x701c, 0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x701e,
+	0x0010, 0x701f, 0x0000, 0x660c, 0x0066, 0x2c00, 0x9f06, 0x0110,
+	0x7e0e, 0x0008, 0x2678, 0x89ff, 0x1168, 0x600f, 0x0000, 0x6014,
+	0x0096, 0x2048, 0x080c, 0xcc14, 0x0110, 0x080c, 0xe6cd, 0x009e,
+	0x080c, 0xaf69, 0x080c, 0xa441, 0x88ff, 0x1190, 0x00ce, 0x0804,
+	0xa45c, 0x2c78, 0x600c, 0x2060, 0x0804, 0xa45c, 0x9006, 0x012e,
+	0x000e, 0x006e, 0x007e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x0005,
+	0x601b, 0x0000, 0x00ce, 0x98c5, 0x0001, 0x0c88, 0x00f6, 0x00e6,
+	0x00d6, 0x0096, 0x00c6, 0x0066, 0x0026, 0x0006, 0x0126, 0x2091,
+	0x8000, 0x2071, 0x19e9, 0x7648, 0x2660, 0x2678, 0x8cff, 0x0904,
+	0xa55d, 0x6020, 0x9086, 0x0006, 0x1904, 0xa558, 0x87ff, 0x0128,
+	0x2700, 0x9c06, 0x1904, 0xa558, 0x0048, 0x6010, 0x9b06, 0x1904,
+	0xa558, 0x85ff, 0x0118, 0x605c, 0x9106, 0x15d0, 0x704c, 0x9c06,
+	0x1178, 0x0036, 0x2019, 0x0001, 0x080c, 0xa380, 0x703f, 0x0000,
+	0x9006, 0x704e, 0x706a, 0x7052, 0x706e, 0x080c, 0xadc0, 0x003e,
+	0x7048, 0x9c36, 0x1110, 0x660c, 0x764a, 0x7044, 0x9c36, 0x1140,
+	0x2c00, 0x9f36, 0x0118, 0x2f00, 0x7046, 0x0010, 0x7047, 0x0000,
+	0x660c, 0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678,
+	0x600f, 0x0000, 0x6014, 0x2048, 0x080c, 0xcc14, 0x0110, 0x080c,
+	0xe6cd, 0x080c, 0xaf69, 0x87ff, 0x1198, 0x00ce, 0x0804, 0xa506,
+	0x2c78, 0x600c, 0x2060, 0x0804, 0xa506, 0x9006, 0x012e, 0x000e,
+	0x002e, 0x006e, 0x00ce, 0x009e, 0x00de, 0x00ee, 0x00fe, 0x0005,
+	0x601b, 0x0000, 0x00ce, 0x97bd, 0x0001, 0x0c80, 0x00e6, 0x2071,
+	0x19e9, 0x9006, 0x7032, 0x700a, 0x7004, 0x9086, 0x0003, 0x0158,
+	0x2001, 0x1800, 0x2004, 0x9086, 0x0002, 0x1118, 0x7007, 0x0005,
+	0x0010, 0x7007, 0x0000, 0x00ee, 0x0005, 0x00f6, 0x00e6, 0x00c6,
+	0x0066, 0x0026, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x19e9,
+	0x2c10, 0x7648, 0x2660, 0x2678, 0x8cff, 0x0540, 0x2200, 0x9c06,
+	0x1508, 0x7048, 0x9c36, 0x1110, 0x660c, 0x764a, 0x7044, 0x9c36,
+	0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x7046, 0x0010, 0x7047,
+	0x0000, 0x660c, 0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678,
+	0x600f, 0x0000, 0x6004, 0x9086, 0x0040, 0x090c, 0x97fe, 0x9085,
+	0x0001, 0x0020, 0x2c78, 0x600c, 0x2060, 0x08b0, 0x012e, 0x000e,
+	0x002e, 0x006e, 0x00ce, 0x00ee, 0x00fe, 0x0005, 0x0096, 0x00f6,
+	0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0026, 0x0006, 0x0126, 0x2091,
+	0x8000, 0x2071, 0x19e9, 0x7610, 0x2660, 0x2678, 0x8cff, 0x0904,
+	0xa65b, 0x6010, 0x00b6, 0x2058, 0xb8a0, 0x00be, 0x9206, 0x1904,
+	0xa656, 0x7030, 0x9c06, 0x1520, 0x2069, 0x0100, 0x68c0, 0x9005,
+	0x0904, 0xa62d, 0x080c, 0xa08a, 0x68c3, 0x0000, 0x080c, 0xa56e,
 	0x7033, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0x9384, 0x1000,
-	0x0138, 0x2001, 0x0100, 0x080c, 0x2a7a, 0x9006, 0x080c, 0x2a7a,
+	0x0138, 0x2001, 0x0100, 0x080c, 0x2abb, 0x9006, 0x080c, 0x2abb,
 	0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x003e,
 	0x7010, 0x9c36, 0x1110, 0x660c, 0x7612, 0x700c, 0x9c36, 0x1140,
 	0x2c00, 0x9f36, 0x0118, 0x2f00, 0x700e, 0x0010, 0x700f, 0x0000,
 	0x660c, 0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678,
-	0x600f, 0x0000, 0x080c, 0xcb80, 0x1180, 0x080c, 0x326f, 0x080c,
-	0xcb91, 0x1518, 0x080c, 0xb693, 0x0400, 0x080c, 0xa3ac, 0x6824,
-	0xd084, 0x09b0, 0x6827, 0x0001, 0x0898, 0x080c, 0xcb91, 0x1118,
-	0x080c, 0xb693, 0x0090, 0x6014, 0x2048, 0x080c, 0xc978, 0x0168,
-	0x6020, 0x9086, 0x0003, 0x1520, 0xa867, 0x0103, 0xab7a, 0xa877,
-	0x0000, 0x080c, 0x6dee, 0x080c, 0xcb6b, 0x080c, 0xce0d, 0x080c,
-	0xaceb, 0x080c, 0xa282, 0x00ce, 0x0804, 0xa87e, 0x2c78, 0x600c,
-	0x2060, 0x0804, 0xa87e, 0x7013, 0x0000, 0x700f, 0x0000, 0x012e,
-	0x006e, 0x009e, 0x00ae, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x0005,
-	0x6020, 0x9086, 0x0006, 0x1d08, 0x080c, 0xe3e8, 0x08f0, 0x00f6,
-	0x0036, 0x2079, 0x0380, 0x7b18, 0xd3bc, 0x1de8, 0x7832, 0x7936,
-	0x7a3a, 0x781b, 0x8080, 0x003e, 0x00fe, 0x0005, 0x0016, 0x2001,
-	0x0382, 0x2004, 0x9084, 0x0007, 0x9086, 0x0001, 0x1188, 0x2001,
-	0x0015, 0x0c29, 0x2009, 0x1000, 0x2001, 0x0382, 0x2004, 0x9084,
-	0x0007, 0x9086, 0x0003, 0x0120, 0x8109, 0x1db0, 0x080c, 0x0d7d,
-	0x001e, 0x0005, 0x2001, 0x0382, 0x2004, 0x9084, 0x0007, 0x9086,
-	0x0003, 0x1120, 0x2001, 0x0380, 0x2003, 0x0001, 0x0005, 0x0156,
-	0x0016, 0x0026, 0x00e6, 0x900e, 0x2071, 0x19e6, 0x0469, 0x0106,
-	0x0190, 0x7004, 0x9086, 0x0003, 0x0148, 0x20a9, 0x1000, 0x6044,
-	0xd0fc, 0x01d8, 0x1f04, 0xa957, 0x080c, 0x0d7d, 0x080c, 0xa91e,
-	0x6044, 0xd0fc, 0x0190, 0x7030, 0x9c06, 0x1148, 0x080c, 0x967a,
-	0x6044, 0xd0dc, 0x0150, 0xc0dc, 0x6046, 0x700a, 0x7042, 0x704c,
-	0x9c06, 0x190c, 0x0d7d, 0x080c, 0x96d5, 0x010e, 0x1919, 0x00ee,
-	0x002e, 0x001e, 0x015e, 0x0005, 0x2001, 0x0382, 0x2004, 0x9084,
-	0x0007, 0x9086, 0x0003, 0x0005, 0x0126, 0x2091, 0x2400, 0x7808,
-	0xd0a4, 0x190c, 0x0d76, 0xd09c, 0x0128, 0x7820, 0x908c, 0xf000,
-	0x11b8, 0x0012, 0x012e, 0x0005, 0xa9a4, 0xa9e2, 0xaa0c, 0xaa43,
-	0xaa53, 0xaa64, 0xaa73, 0xaa81, 0xaaae, 0xaab2, 0xa9a4, 0xa9a4,
-	0xa9a4, 0xa9a4, 0xa9a4, 0xa9a4, 0x080c, 0x0d7d, 0x012e, 0x0005,
-	0x2060, 0x6044, 0xd0bc, 0x0140, 0xc0bc, 0x6046, 0x6000, 0x908a,
-	0x0016, 0x1a0c, 0x0d7d, 0x0012, 0x012e, 0x0005, 0xa9c9, 0xa9cb,
-	0xa9c9, 0xa9d1, 0xa9c9, 0xa9c9, 0xa9c9, 0xa9c9, 0xa9c9, 0xa9cb,
-	0xa9c9, 0xa9cb, 0xa9c9, 0xa9cb, 0xa9c9, 0xa9c9, 0xa9c9, 0xa9cb,
-	0xa9c9, 0x080c, 0x0d7d, 0x2009, 0x0013, 0x080c, 0xad4d, 0x012e,
-	0x0005, 0x6014, 0x2048, 0xa87c, 0xd0dc, 0x0130, 0x080c, 0x894e,
-	0x080c, 0xacb0, 0x012e, 0x0005, 0x2009, 0x0049, 0x080c, 0xad4d,
-	0x012e, 0x0005, 0x080c, 0xa91e, 0x2001, 0x1a0b, 0x2003, 0x0000,
-	0x7030, 0x9065, 0x090c, 0x0d7d, 0x7034, 0x9092, 0xc350, 0x1258,
-	0x8000, 0x7036, 0x7004, 0x9086, 0x0003, 0x0110, 0x7007, 0x0000,
-	0x781f, 0x0808, 0x0058, 0x080c, 0xac0e, 0x0140, 0x080c, 0xe897,
-	0x6003, 0x0001, 0x2009, 0x0014, 0x080c, 0xad4d, 0x781f, 0x0100,
-	0x080c, 0xa93a, 0x012e, 0x0005, 0x080c, 0xa91e, 0x714c, 0x81ff,
-	0x1128, 0x2011, 0x1a0e, 0x2013, 0x0000, 0x0438, 0x2061, 0x0100,
-	0x7150, 0x9192, 0x7530, 0x12f0, 0x8108, 0x7152, 0x714c, 0x9188,
-	0x0008, 0x210c, 0x918e, 0x0006, 0x1138, 0x6014, 0x9084, 0x1984,
-	0x9085, 0x0012, 0x6016, 0x0088, 0x714c, 0x9188, 0x0008, 0x210c,
-	0x918e, 0x0009, 0x0d90, 0x6014, 0x9084, 0x1984, 0x9085, 0x0016,
-	0x6016, 0x0018, 0x706c, 0xc085, 0x706e, 0x781f, 0x0200, 0x080c,
-	0xa93a, 0x012e, 0x0005, 0x080c, 0xa91e, 0x714c, 0x2160, 0x6003,
-	0x0003, 0x2009, 0x004a, 0x080c, 0xad4d, 0x781f, 0x0200, 0x080c,
-	0xa93a, 0x012e, 0x0005, 0x7808, 0xd09c, 0x0de8, 0x7820, 0x2060,
-	0x6003, 0x0003, 0x080c, 0xa91e, 0x080c, 0x1db6, 0x781f, 0x0400,
-	0x080c, 0xa93a, 0x012e, 0x0005, 0x7808, 0xd09c, 0x0de8, 0x7820,
-	0x2060, 0x080c, 0xa91e, 0x080c, 0x1dfe, 0x781f, 0x0400, 0x080c,
-	0xa93a, 0x012e, 0x0005, 0x7030, 0x9065, 0x0148, 0x6044, 0xc0bc,
-	0x6046, 0x7104, 0x9186, 0x0003, 0x0110, 0x080c, 0x9739, 0x012e,
-	0x0005, 0x00f6, 0x703c, 0x9086, 0x0002, 0x0528, 0x704c, 0x907d,
-	0x0510, 0x7844, 0xc0bc, 0x7846, 0x7820, 0x9086, 0x0009, 0x0118,
-	0x080c, 0x9dfe, 0x00c0, 0x7828, 0xd0fc, 0x1118, 0x080c, 0x9d7d,
-	0x0090, 0x2001, 0x1837, 0x2004, 0x9084, 0x0028, 0x1130, 0x2001,
-	0x197b, 0x2004, 0x9086, 0xaaaa, 0x1120, 0x2001, 0x0387, 0x2003,
-	0x1000, 0x080c, 0x9d02, 0x00fe, 0x012e, 0x0005, 0x080c, 0x75e2,
-	0x012e, 0x0005, 0x080c, 0x0d7d, 0x0005, 0x00e6, 0x2071, 0x19e6,
-	0x6044, 0xc0bc, 0x6046, 0xd0fc, 0x01b8, 0x704c, 0x9c06, 0x1190,
-	0x2019, 0x0001, 0x080c, 0xa1b8, 0x704f, 0x0000, 0x2001, 0x0109,
-	0x2004, 0xd08c, 0x1138, 0x2001, 0x0108, 0x2004, 0xd0bc, 0x1110,
-	0x703f, 0x0000, 0x080c, 0xa3c3, 0x00ee, 0x0005, 0x0026, 0x7010,
-	0x9c06, 0x1178, 0x080c, 0xa282, 0x6044, 0xc0fc, 0x6046, 0x600c,
-	0x9015, 0x0120, 0x7212, 0x600f, 0x0000, 0x0010, 0x7212, 0x720e,
-	0x9006, 0x002e, 0x0005, 0x0026, 0x7020, 0x9c06, 0x1178, 0x080c,
-	0xa282, 0x6044, 0xc0fc, 0x6046, 0x600c, 0x9015, 0x0120, 0x7222,
-	0x600f, 0x0000, 0x0010, 0x7222, 0x721e, 0x9006, 0x002e, 0x0005,
-	0x00d6, 0x0036, 0x7830, 0x9c06, 0x1558, 0x2069, 0x0100, 0x68c0,
-	0x9005, 0x01f8, 0x080c, 0x8780, 0x080c, 0x9ed4, 0x68c3, 0x0000,
-	0x080c, 0xa3ac, 0x2069, 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138,
-	0x2001, 0x0100, 0x080c, 0x2a7a, 0x9006, 0x080c, 0x2a7a, 0x2069,
-	0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x9085, 0x0001,
-	0x0038, 0x7808, 0xc0ad, 0x780a, 0x6003, 0x0009, 0x630a, 0x9006,
-	0x003e, 0x00de, 0x0005, 0x0016, 0x0026, 0x0036, 0x6100, 0x2019,
-	0x0100, 0x2001, 0x0382, 0x2004, 0xd09c, 0x0190, 0x00c6, 0x0126,
-	0x2091, 0x2800, 0x0016, 0x0036, 0x080c, 0xa984, 0x003e, 0x001e,
-	0x012e, 0x00ce, 0x6200, 0x2200, 0x9106, 0x0d58, 0x2200, 0x0010,
-	0x8319, 0x1d38, 0x003e, 0x002e, 0x001e, 0x0005, 0x00d6, 0x0156,
-	0x080c, 0x9b82, 0x7a14, 0x82ff, 0x0138, 0x7003, 0x0100, 0x700b,
-	0x0003, 0x60c3, 0x0008, 0x0490, 0x7003, 0x0200, 0x7007, 0x0000,
-	0x2069, 0x1800, 0x901e, 0x6800, 0x9086, 0x0004, 0x1110, 0xc38d,
-	0x0060, 0x080c, 0x753d, 0x1110, 0xc3ad, 0x0008, 0xc3a5, 0x6adc,
-	0xd29c, 0x1110, 0xd2ac, 0x0108, 0xc39d, 0x730e, 0x080c, 0x8845,
-	0x20a9, 0x0006, 0x2011, 0xffec, 0x2019, 0xffed, 0x2071, 0x0250,
-	0x2305, 0x2072, 0x8e70, 0x2205, 0x2072, 0x8e70, 0x9398, 0x0002,
-	0x9290, 0x0002, 0x1f04, 0xab88, 0x60c3, 0x0020, 0x080c, 0x9ea4,
-	0x015e, 0x00de, 0x0005, 0x0156, 0x080c, 0x9b82, 0x7a14, 0x82ff,
-	0x0168, 0x9286, 0xffff, 0x0118, 0x9282, 0x000e, 0x1238, 0x7003,
-	0x0100, 0x700b, 0x0003, 0x60c3, 0x0008, 0x0488, 0x7003, 0x0200,
-	0x7007, 0x001c, 0x700f, 0x0001, 0x2011, 0x19bc, 0x2204, 0x8007,
-	0x701a, 0x8210, 0x2204, 0x8007, 0x701e, 0x0421, 0x1120, 0xb8a0,
-	0x9082, 0x007f, 0x0248, 0x2001, 0x181f, 0x2004, 0x7022, 0x2001,
-	0x1820, 0x2004, 0x7026, 0x0030, 0x2001, 0x1818, 0x2004, 0x9084,
-	0x00ff, 0x7026, 0x20a9, 0x0004, 0x20e1, 0x0001, 0x2099, 0x1805,
-	0x20e9, 0x0000, 0x20a1, 0x0256, 0x4003, 0x60c3, 0x001c, 0x015e,
-	0x0804, 0x9ea4, 0x0006, 0x2001, 0x1837, 0x2004, 0xd0ac, 0x000e,
-	0x0005, 0x2011, 0x0003, 0x080c, 0xa243, 0x2011, 0x0002, 0x080c,
-	0xa24d, 0x080c, 0xa138, 0x0036, 0x901e, 0x080c, 0xa1b8, 0x003e,
-	0x0005, 0x080c, 0x33b2, 0x0188, 0x0016, 0x00b6, 0x00c6, 0x7010,
-	0x9085, 0x0020, 0x7012, 0x2009, 0x007e, 0x080c, 0x6693, 0xb85c,
-	0xc0ac, 0xb85e, 0x00ce, 0x00be, 0x001e, 0x0005, 0x00d6, 0x00f6,
-	0x7104, 0x9186, 0x0004, 0x1120, 0x7410, 0x9e90, 0x0004, 0x0068,
-	0x9186, 0x0001, 0x1120, 0x7420, 0x9e90, 0x0008, 0x0030, 0x9186,
-	0x0002, 0x1508, 0x7428, 0x9e90, 0x000a, 0x6110, 0x2468, 0x680c,
-	0x907d, 0x01c8, 0x7810, 0x9106, 0x1128, 0x2f68, 0x780c, 0x907d,
-	0x1dc8, 0x0088, 0x780c, 0x680e, 0x7c0e, 0x2f12, 0x9006, 0x7032,
-	0x7036, 0x7004, 0x9086, 0x0003, 0x0110, 0x7007, 0x0000, 0x9006,
-	0x00fe, 0x00de, 0x0005, 0x9085, 0x0001, 0x0cd0, 0x2071, 0x188d,
-	0x7000, 0x9005, 0x0140, 0x2001, 0x0812, 0x2071, 0x1800, 0x7076,
-	0x707a, 0x706b, 0xffd4, 0x2071, 0x1800, 0x7074, 0x7056, 0x705b,
-	0x1ddc, 0x0005, 0x00e6, 0x0126, 0x2071, 0x1800, 0x2091, 0x8000,
-	0x7554, 0x9582, 0x0010, 0x0608, 0x7058, 0x2060, 0x6000, 0x9086,
-	0x0000, 0x0148, 0x9ce0, 0x001c, 0x7068, 0x9c02, 0x1208, 0x0cb0,
-	0x2061, 0x1ddc, 0x0c98, 0x6003, 0x0008, 0x8529, 0x7556, 0x9ca8,
-	0x001c, 0x7068, 0x9502, 0x1230, 0x755a, 0x9085, 0x0001, 0x012e,
-	0x00ee, 0x0005, 0x705b, 0x1ddc, 0x0cc0, 0x9006, 0x0cc0, 0x00e6,
-	0x2071, 0x1800, 0x7554, 0x9582, 0x0010, 0x0600, 0x7058, 0x2060,
-	0x6000, 0x9086, 0x0000, 0x0148, 0x9ce0, 0x001c, 0x7068, 0x9c02,
-	0x1208, 0x0cb0, 0x2061, 0x1ddc, 0x0c98, 0x6003, 0x0008, 0x8529,
-	0x7556, 0x9ca8, 0x001c, 0x7068, 0x9502, 0x1228, 0x755a, 0x9085,
-	0x0001, 0x00ee, 0x0005, 0x705b, 0x1ddc, 0x0cc8, 0x9006, 0x0cc8,
-	0x9c82, 0x1ddc, 0x0a0c, 0x0d7d, 0x2001, 0x181a, 0x2004, 0x9c02,
-	0x1a0c, 0x0d7d, 0x9006, 0x6006, 0x600a, 0x600e, 0x6016, 0x601a,
-	0x6012, 0x6023, 0x0000, 0x6003, 0x0000, 0x601e, 0x605e, 0x6062,
-	0x6026, 0x602a, 0x602e, 0x6032, 0x6036, 0x603a, 0x603e, 0x604a,
-	0x602a, 0x6046, 0x6042, 0x2061, 0x1800, 0x6054, 0x8000, 0x6056,
-	0x0005, 0x9006, 0x600e, 0x6016, 0x601a, 0x6012, 0x6022, 0x6002,
-	0x601e, 0x605e, 0x6062, 0x604a, 0x6046, 0x2061, 0x1800, 0x6054,
-	0x8000, 0x6056, 0x0005, 0x0006, 0x6000, 0x9086, 0x0000, 0x01d0,
-	0x601c, 0xd084, 0x190c, 0x1ac5, 0x6023, 0x0007, 0x2001, 0x1985,
-	0x2004, 0x0006, 0x9082, 0x0051, 0x000e, 0x0208, 0x8004, 0x601a,
-	0x080c, 0xe6a0, 0x604b, 0x0000, 0x6044, 0xd0fc, 0x1129, 0x9006,
-	0x6046, 0x6016, 0x000e, 0x0005, 0x080c, 0xa91e, 0x0106, 0x2001,
-	0x19f9, 0x2004, 0x9c06, 0x1130, 0x0036, 0x2019, 0x0001, 0x080c,
-	0xa1b8, 0x003e, 0x080c, 0xa3c3, 0x010e, 0x090c, 0xa93a, 0x0005,
+	0x600f, 0x0000, 0x080c, 0xce1c, 0x1180, 0x080c, 0x333f, 0x080c,
+	0xce2d, 0x1518, 0x080c, 0xb91f, 0x0400, 0x080c, 0xa56e, 0x6824,
+	0xd084, 0x09b0, 0x6827, 0x0001, 0x0898, 0x080c, 0xce2d, 0x1118,
+	0x080c, 0xb91f, 0x0090, 0x6014, 0x2048, 0x080c, 0xcc14, 0x0168,
+	0x6020, 0x9086, 0x0003, 0x1508, 0xa867, 0x0103, 0xab7a, 0xa877,
+	0x0000, 0x080c, 0x6f0d, 0x080c, 0xce07, 0x080c, 0xd0a9, 0x080c,
+	0xaf69, 0x080c, 0xa441, 0x00ce, 0x0804, 0xa5d6, 0x2c78, 0x600c,
+	0x2060, 0x0804, 0xa5d6, 0x012e, 0x000e, 0x002e, 0x006e, 0x00ce,
+	0x00de, 0x00ee, 0x00fe, 0x009e, 0x0005, 0x6020, 0x9086, 0x0006,
+	0x1d20, 0x080c, 0xe6cd, 0x0c08, 0x00d6, 0x080c, 0x9d2d, 0x7003,
+	0x0200, 0x7007, 0x0014, 0x60c3, 0x0014, 0x20e1, 0x0001, 0x2099,
+	0x198a, 0x20e9, 0x0000, 0x20a1, 0x0250, 0x20a9, 0x0004, 0x4003,
+	0x7023, 0x0004, 0x7027, 0x7878, 0x080c, 0xa05a, 0x00de, 0x0005,
+	0x080c, 0x9d2d, 0x700b, 0x0800, 0x7814, 0x9084, 0xff00, 0x700e,
+	0x7814, 0x9084, 0x00ff, 0x7022, 0x782c, 0x7026, 0x7860, 0x9084,
+	0x00ff, 0x9085, 0x0200, 0x7002, 0x7860, 0x9084, 0xff00, 0x8007,
+	0x7006, 0x60c2, 0x0804, 0xa05a, 0x00b6, 0x00d6, 0x0016, 0x00d6,
+	0x2f68, 0x2009, 0x0035, 0x080c, 0xd2b6, 0x00de, 0x1904, 0xa709,
+	0x080c, 0x9ce2, 0x7003, 0x1300, 0x782c, 0x080c, 0xa818, 0x2068,
+	0x6820, 0x9086, 0x0003, 0x0560, 0x7810, 0x2058, 0xbaa0, 0x080c,
+	0xae60, 0x11d8, 0x9286, 0x007e, 0x1128, 0x700b, 0x00ff, 0x700f,
+	0xfffe, 0x0498, 0x9286, 0x007f, 0x1128, 0x700b, 0x00ff, 0x700f,
+	0xfffd, 0x0458, 0x9284, 0xff80, 0x0180, 0x9286, 0x0080, 0x1128,
+	0x700b, 0x00ff, 0x700f, 0xfffc, 0x0400, 0x92d8, 0x1000, 0x2b5c,
+	0xb810, 0x700a, 0xb814, 0x700e, 0x00c0, 0xb884, 0x700e, 0x00a8,
+	0x080c, 0xae60, 0x1130, 0x7810, 0x2058, 0xb8a0, 0x9082, 0x007e,
+	0x0250, 0x00d6, 0x2069, 0x181f, 0x2d04, 0x700a, 0x8d68, 0x2d04,
+	0x700e, 0x00de, 0x0010, 0x6034, 0x700e, 0x7838, 0x7012, 0x783c,
+	0x7016, 0x60c3, 0x000c, 0x001e, 0x00de, 0x080c, 0xa05a, 0x00be,
+	0x0005, 0x781b, 0x0001, 0x7803, 0x0006, 0x001e, 0x00de, 0x00be,
+	0x0005, 0x792c, 0x9180, 0x0008, 0x200c, 0x9186, 0x0006, 0x01c0,
+	0x9186, 0x0003, 0x0904, 0xa788, 0x9186, 0x0005, 0x0904, 0xa770,
+	0x9186, 0x0004, 0x05f0, 0x9186, 0x0008, 0x0904, 0xa779, 0x7807,
+	0x0037, 0x782f, 0x0003, 0x7817, 0x1700, 0x080c, 0xa7f5, 0x0005,
+	0x080c, 0xa7b6, 0x00d6, 0x0026, 0x792c, 0x2168, 0x2009, 0x4000,
+	0x6800, 0x6a44, 0xd2fc, 0x11f8, 0x0002, 0xa750, 0xa75b, 0xa752,
+	0xa75b, 0xa757, 0xa750, 0xa750, 0xa75b, 0xa75b, 0xa75b, 0xa75b,
+	0xa750, 0xa750, 0xa750, 0xa750, 0xa750, 0xa75b, 0xa750, 0xa75b,
+	0x080c, 0x0d85, 0x6824, 0xd0e4, 0x0110, 0xd0cc, 0x0110, 0x900e,
+	0x0010, 0x2009, 0x2000, 0x682c, 0x7022, 0x6830, 0x7026, 0x0804,
+	0xa7af, 0x080c, 0xa7b6, 0x00d6, 0x0026, 0x792c, 0x2168, 0x2009,
+	0x4000, 0x6a00, 0x9286, 0x0002, 0x1108, 0x900e, 0x0804, 0xa7af,
+	0x080c, 0xa7b6, 0x00d6, 0x0026, 0x792c, 0x2168, 0x2009, 0x4000,
+	0x04b0, 0x04e1, 0x00d6, 0x0026, 0x792c, 0x2168, 0x2009, 0x4000,
+	0x9286, 0x0005, 0x0118, 0x9286, 0x0002, 0x1108, 0x900e, 0x0438,
+	0x0469, 0x00d6, 0x0026, 0x792c, 0x2168, 0x6814, 0x6924, 0xc185,
+	0x6926, 0x0096, 0x2048, 0xa9ac, 0xa834, 0x9112, 0xa9b0, 0xa838,
+	0x009e, 0x9103, 0x7022, 0x7226, 0x792c, 0x9180, 0x0011, 0x2004,
+	0xd0fc, 0x1148, 0x9180, 0x0000, 0x2004, 0x908e, 0x0002, 0x0130,
+	0x908e, 0x0004, 0x0118, 0x2009, 0x4000, 0x0008, 0x900e, 0x712a,
+	0x60c3, 0x0018, 0x002e, 0x00de, 0x0804, 0xa05a, 0x00b6, 0x0036,
+	0x0046, 0x0056, 0x0066, 0x080c, 0x9d2d, 0x9006, 0x7003, 0x0200,
+	0x7938, 0x710a, 0x793c, 0x710e, 0x7810, 0x2058, 0xb8a0, 0x080c,
+	0xae60, 0x1118, 0x9092, 0x007e, 0x0268, 0x00d6, 0x2069, 0x181f,
+	0x2d2c, 0x8d68, 0x2d34, 0x90d8, 0x1000, 0x2b5c, 0xbb10, 0xbc14,
+	0x00de, 0x0028, 0x901e, 0xbc84, 0x2029, 0x0000, 0x6634, 0x782c,
+	0x9080, 0x0008, 0x2004, 0x9086, 0x0003, 0x1128, 0x7512, 0x7616,
+	0x731a, 0x741e, 0x0020, 0x7312, 0x7416, 0x751a, 0x761e, 0x006e,
+	0x005e, 0x004e, 0x003e, 0x00be, 0x0005, 0x080c, 0x9d2d, 0x7003,
+	0x0100, 0x782c, 0x700a, 0x7814, 0x700e, 0x700e, 0x60c3, 0x0008,
+	0x0804, 0xa05a, 0x080c, 0x9cd9, 0x7003, 0x1400, 0x7838, 0x700a,
+	0x0079, 0x783c, 0x700e, 0x782c, 0x7012, 0x7830, 0x7016, 0x7834,
+	0x9084, 0x00ff, 0x8007, 0x701a, 0x60c3, 0x0010, 0x0804, 0xa05a,
+	0x00e6, 0x2071, 0x0240, 0x0006, 0x00f6, 0x2078, 0x7810, 0x00b6,
+	0x2058, 0xb8d4, 0xd084, 0x0120, 0x784c, 0x702a, 0x7850, 0x702e,
+	0x00be, 0x00fe, 0x000e, 0x00ee, 0x0005, 0x080c, 0x9d24, 0x7003,
+	0x0100, 0x782c, 0x700a, 0x7814, 0x700e, 0x60c3, 0x0008, 0x0804,
+	0xa05a, 0x00a9, 0x7914, 0x712a, 0x60c3, 0x0000, 0x60a7, 0x9575,
+	0x0026, 0x080c, 0x2a26, 0x0228, 0x2011, 0x0101, 0x2204, 0xc0c5,
+	0x2012, 0x002e, 0x080c, 0xa07d, 0x080c, 0x88e3, 0x0005, 0x0036,
+	0x0096, 0x00d6, 0x00e6, 0x7860, 0x2048, 0xaa7c, 0x9296, 0x00c0,
+	0x9294, 0x00fd, 0xaa7e, 0xaa80, 0x9294, 0x0300, 0xaa82, 0xa96c,
+	0x9194, 0x00ff, 0xab74, 0x9384, 0x00ff, 0x908d, 0xc200, 0xa96e,
+	0x9384, 0xff00, 0x9215, 0xaa76, 0xa870, 0xaa78, 0xa87a, 0xaa72,
+	0x00d6, 0x2069, 0x0200, 0x080c, 0xa8d5, 0x00de, 0x20e9, 0x0000,
+	0x20a1, 0x0240, 0x20a9, 0x000a, 0xa860, 0x20e0, 0xa85c, 0x9080,
+	0x001b, 0x2098, 0x4003, 0x60a3, 0x0035, 0xaa68, 0x9294, 0x7000,
+	0x9286, 0x3000, 0x0110, 0x60a3, 0x0037, 0x00ee, 0x00de, 0x009e,
+	0x003e, 0x0005, 0x900e, 0x7814, 0x0096, 0x2048, 0xa87c, 0xd0fc,
+	0x01c0, 0x9084, 0x0003, 0x11a8, 0x2001, 0x180c, 0x2004, 0xd0bc,
+	0x0180, 0x7824, 0xd0cc, 0x1168, 0xd0c4, 0x1158, 0xa8a8, 0x9005,
+	0x1140, 0x2001, 0x180c, 0x200c, 0xc1d5, 0x2102, 0x2009, 0x19b4,
+	0x210c, 0x009e, 0x918d, 0x0092, 0x0010, 0x2009, 0x0096, 0x60ab,
+	0x0036, 0x0026, 0x2110, 0x900e, 0x080c, 0x2b04, 0x002e, 0x0005,
+	0x2009, 0x0009, 0x00a0, 0x2009, 0x000a, 0x0088, 0x2009, 0x000b,
+	0x0070, 0x2009, 0x000c, 0x0058, 0x2009, 0x000d, 0x0040, 0x2009,
+	0x000e, 0x0028, 0x2009, 0x000f, 0x0010, 0x2009, 0x0008, 0x6912,
+	0x0005, 0x080c, 0x9ce2, 0x0016, 0x0026, 0x0096, 0x00d6, 0x7814,
+	0x2048, 0x7013, 0x0138, 0x2001, 0x1837, 0x2004, 0x9084, 0x0028,
+	0x1138, 0x2001, 0x197d, 0x2004, 0x9086, 0xaaaa, 0x1904, 0xa97a,
+	0x7003, 0x5400, 0x00c6, 0x2061, 0x1800, 0x607c, 0x9084, 0x00ff,
+	0xa998, 0x810f, 0x918c, 0xff00, 0x9105, 0x700a, 0x6080, 0x700e,
+	0xa998, 0x918c, 0xff00, 0x7112, 0x20a9, 0x0004, 0x2009, 0x1805,
+	0x2e10, 0x9290, 0x0006, 0x2104, 0x2012, 0x8108, 0x8210, 0x1f04,
+	0xa90b, 0x20a9, 0x0004, 0x2009, 0x1801, 0x2104, 0x2012, 0x8108,
+	0x8210, 0x1f04, 0xa915, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0029,
+	0x2098, 0x2009, 0x0006, 0x20a9, 0x0001, 0x4002, 0x8007, 0x2012,
+	0x8210, 0x8109, 0x1dc0, 0x00d6, 0x2069, 0x0200, 0x080c, 0xa8c0,
+	0x00de, 0x2071, 0x0240, 0x2011, 0x0240, 0x2009, 0x0002, 0x20a9,
+	0x0001, 0x4002, 0x8007, 0x2012, 0x8210, 0x8109, 0x1dc0, 0x2009,
+	0x0008, 0x20a9, 0x0001, 0x4002, 0x8007, 0x2012, 0x8210, 0x8109,
+	0x1dc0, 0xa85c, 0x9080, 0x0031, 0x2098, 0x2009, 0x0008, 0x20a9,
+	0x0001, 0x4002, 0x8007, 0x2012, 0x8210, 0x8109, 0x1dc0, 0x00ce,
+	0x60c3, 0x004c, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x2001, 0x1837,
+	0x2004, 0x9084, 0x0028, 0x1168, 0x080c, 0x76a5, 0x0150, 0x6028,
+	0xc0bd, 0x602a, 0x2009, 0x1804, 0x2011, 0x0029, 0x080c, 0x2b04,
+	0x0010, 0x080c, 0xa05a, 0x080c, 0x88e3, 0x00de, 0x009e, 0x002e,
+	0x001e, 0x0005, 0x00e6, 0x2071, 0x0240, 0x2001, 0x2200, 0x9085,
+	0x00ff, 0x7002, 0x7007, 0xffff, 0x2071, 0x0100, 0x709b, 0x00ff,
+	0x00ee, 0x0804, 0xa8f0, 0x080c, 0x9ce2, 0x0016, 0x0026, 0x0096,
+	0x00d6, 0x7814, 0x2048, 0x7013, 0x0138, 0x7003, 0x5500, 0x00c6,
+	0xa89c, 0x9084, 0x00ff, 0xa998, 0x810f, 0x918c, 0xff00, 0x9105,
+	0x700a, 0xa99c, 0x918c, 0xff00, 0xa8a0, 0x9084, 0x00ff, 0x9105,
+	0x700e, 0xa998, 0x918c, 0xff00, 0x2061, 0x1800, 0x607c, 0x9084,
+	0x00ff, 0x910d, 0x7112, 0x6180, 0x7116, 0x2009, 0x0008, 0xa860,
+	0x20e0, 0xa85c, 0x9080, 0x0029, 0x2098, 0x2e10, 0x9290, 0x0006,
+	0x20a9, 0x0001, 0x4002, 0x8007, 0x2012, 0x8210, 0x8109, 0x1dc0,
+	0x20a9, 0x0004, 0x2009, 0x1805, 0x2104, 0x2012, 0x8108, 0x8210,
+	0x1f04, 0xa9cc, 0x20a9, 0x0002, 0x2009, 0x1801, 0x2104, 0x2012,
+	0x8108, 0x8210, 0x1f04, 0xa9d6, 0x00d6, 0x0016, 0x2069, 0x0200,
+	0x080c, 0xa8c0, 0x001e, 0x00de, 0x2071, 0x0240, 0x20a9, 0x0002,
+	0x2009, 0x1803, 0x2011, 0x0240, 0x2104, 0x2012, 0x8108, 0x8210,
+	0x1f04, 0xa9ec, 0x2009, 0x0008, 0x4002, 0x8007, 0x2012, 0x8210,
+	0x8109, 0x1dd0, 0x9006, 0x20a9, 0x0008, 0x2012, 0x8210, 0x1f04,
+	0xa9fd, 0x00ce, 0x60c3, 0x004c, 0x60a3, 0x0056, 0x60a7, 0x9575,
+	0x080c, 0xa05a, 0x080c, 0x88e3, 0x00de, 0x009e, 0x002e, 0x001e,
+	0x0005, 0x00d6, 0x9290, 0x0018, 0x8214, 0x20e9, 0x0000, 0x2069,
+	0x0200, 0x6813, 0x0000, 0x22a8, 0x9284, 0x00e0, 0x0128, 0x20a9,
+	0x0020, 0x9292, 0x0020, 0x0008, 0x9016, 0x20a1, 0x0240, 0x9006,
+	0x4004, 0x82ff, 0x0120, 0x6810, 0x8000, 0x6812, 0x0c60, 0x00de,
+	0x0005, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x00a6, 0x0096, 0x0066,
+	0x0126, 0x2091, 0x8000, 0x2071, 0x19e9, 0x7610, 0x2660, 0x2678,
+	0x8cff, 0x0904, 0xaabd, 0x7030, 0x9c06, 0x1520, 0x2069, 0x0100,
+	0x68c0, 0x9005, 0x0904, 0xaa8f, 0x080c, 0xa08a, 0x68c3, 0x0000,
+	0x080c, 0xa56e, 0x7033, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04,
+	0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2abb, 0x9006,
+	0x080c, 0x2abb, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827,
+	0x0001, 0x003e, 0x7010, 0x9c36, 0x1110, 0x660c, 0x7612, 0x700c,
+	0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x700e, 0x0010,
+	0x700f, 0x0000, 0x660c, 0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e,
+	0x0008, 0x2678, 0x600f, 0x0000, 0x080c, 0xce1c, 0x1180, 0x080c,
+	0x333f, 0x080c, 0xce2d, 0x1518, 0x080c, 0xb91f, 0x0400, 0x080c,
+	0xa56e, 0x6824, 0xd084, 0x09b0, 0x6827, 0x0001, 0x0898, 0x080c,
+	0xce2d, 0x1118, 0x080c, 0xb91f, 0x0090, 0x6014, 0x2048, 0x080c,
+	0xcc14, 0x0168, 0x6020, 0x9086, 0x0003, 0x1520, 0xa867, 0x0103,
+	0xab7a, 0xa877, 0x0000, 0x080c, 0x6f19, 0x080c, 0xce07, 0x080c,
+	0xd0a9, 0x080c, 0xaf69, 0x080c, 0xa441, 0x00ce, 0x0804, 0xaa40,
+	0x2c78, 0x600c, 0x2060, 0x0804, 0xaa40, 0x7013, 0x0000, 0x700f,
+	0x0000, 0x012e, 0x006e, 0x009e, 0x00ae, 0x00ce, 0x00de, 0x00ee,
+	0x00fe, 0x0005, 0x6020, 0x9086, 0x0006, 0x1d08, 0x080c, 0xe6cd,
+	0x08f0, 0x00f6, 0x0036, 0x2079, 0x0380, 0x7b18, 0xd3bc, 0x1de8,
+	0x7832, 0x7936, 0x7a3a, 0x781b, 0x8080, 0x003e, 0x00fe, 0x0005,
+	0x0016, 0x2001, 0x0382, 0x2004, 0x9084, 0x0007, 0x9086, 0x0001,
+	0x1188, 0x2001, 0x0015, 0x0c29, 0x2009, 0x1000, 0x2001, 0x0382,
+	0x2004, 0x9084, 0x0007, 0x9086, 0x0003, 0x0120, 0x8109, 0x1db0,
+	0x080c, 0x0d85, 0x001e, 0x0005, 0x2001, 0x0382, 0x2004, 0x9084,
+	0x0007, 0x9086, 0x0003, 0x1120, 0x2001, 0x0380, 0x2003, 0x0001,
+	0x0005, 0x0156, 0x0016, 0x0026, 0x00e6, 0x900e, 0x2071, 0x19e9,
+	0x0469, 0x0106, 0x0190, 0x7004, 0x9086, 0x0003, 0x0148, 0x20a9,
+	0x1000, 0x6044, 0xd0fc, 0x01d8, 0x1f04, 0xab19, 0x080c, 0x0d85,
+	0x080c, 0xaae0, 0x6044, 0xd0fc, 0x0190, 0x7030, 0x9c06, 0x1148,
+	0x080c, 0x97fe, 0x6044, 0xd0dc, 0x0150, 0xc0dc, 0x6046, 0x700a,
+	0x7042, 0x704c, 0x9c06, 0x190c, 0x0d85, 0x080c, 0x9859, 0x010e,
+	0x1919, 0x00ee, 0x002e, 0x001e, 0x015e, 0x0005, 0x2001, 0x0382,
+	0x2004, 0x9084, 0x0007, 0x9086, 0x0003, 0x0005, 0x0126, 0x2091,
+	0x2400, 0x7808, 0xd0a4, 0x190c, 0x0d7e, 0xd09c, 0x0128, 0x7820,
+	0x908c, 0xf000, 0x11b8, 0x0012, 0x012e, 0x0005, 0xab66, 0xaba4,
+	0xabce, 0xac05, 0xac15, 0xac26, 0xac35, 0xac43, 0xac70, 0xac74,
+	0xab66, 0xab66, 0xac77, 0xac93, 0xab66, 0xab66, 0x080c, 0x0d85,
+	0x012e, 0x0005, 0x2060, 0x6044, 0xd0bc, 0x0140, 0xc0bc, 0x6046,
+	0x6000, 0x908a, 0x0016, 0x1a0c, 0x0d85, 0x0012, 0x012e, 0x0005,
+	0xab8b, 0xab8d, 0xab8b, 0xab93, 0xab8b, 0xab8b, 0xab8b, 0xab8b,
+	0xab8b, 0xab8d, 0xab8b, 0xab8d, 0xab8b, 0xab8d, 0xab8b, 0xab8b,
+	0xab8b, 0xab8d, 0xab8b, 0x080c, 0x0d85, 0x2009, 0x0013, 0x080c,
+	0xafcc, 0x012e, 0x0005, 0x6014, 0x2048, 0xa87c, 0xd0dc, 0x0130,
+	0x080c, 0x8aba, 0x080c, 0xaf2e, 0x012e, 0x0005, 0x2009, 0x0049,
+	0x080c, 0xafcc, 0x012e, 0x0005, 0x080c, 0xaae0, 0x2001, 0x1a0e,
+	0x2003, 0x0000, 0x7030, 0x9065, 0x090c, 0x0d85, 0x7034, 0x9092,
+	0xc350, 0x1258, 0x8000, 0x7036, 0x7004, 0x9086, 0x0003, 0x0110,
+	0x7007, 0x0000, 0x781f, 0x0808, 0x0058, 0x080c, 0xae8c, 0x0140,
+	0x080c, 0xeb92, 0x6003, 0x0001, 0x2009, 0x0014, 0x080c, 0xafcc,
+	0x781f, 0x0100, 0x080c, 0xaafc, 0x012e, 0x0005, 0x080c, 0xaae0,
+	0x714c, 0x81ff, 0x1128, 0x2011, 0x1a11, 0x2013, 0x0000, 0x0438,
+	0x2061, 0x0100, 0x7150, 0x9192, 0x7530, 0x12f0, 0x8108, 0x7152,
+	0x714c, 0x9188, 0x0008, 0x210c, 0x918e, 0x0006, 0x1138, 0x6014,
+	0x9084, 0x1984, 0x9085, 0x0012, 0x6016, 0x0088, 0x714c, 0x9188,
+	0x0008, 0x210c, 0x918e, 0x0009, 0x0d90, 0x6014, 0x9084, 0x1984,
+	0x9085, 0x0016, 0x6016, 0x0018, 0x706c, 0xc085, 0x706e, 0x781f,
+	0x0200, 0x080c, 0xaafc, 0x012e, 0x0005, 0x080c, 0xaae0, 0x714c,
+	0x2160, 0x6003, 0x0003, 0x2009, 0x004a, 0x080c, 0xafcc, 0x781f,
+	0x0200, 0x080c, 0xaafc, 0x012e, 0x0005, 0x7808, 0xd09c, 0x0de8,
+	0x7820, 0x2060, 0x6003, 0x0003, 0x080c, 0xaae0, 0x080c, 0x1ded,
+	0x781f, 0x0400, 0x080c, 0xaafc, 0x012e, 0x0005, 0x7808, 0xd09c,
+	0x0de8, 0x7820, 0x2060, 0x080c, 0xaae0, 0x080c, 0x1e35, 0x781f,
+	0x0400, 0x080c, 0xaafc, 0x012e, 0x0005, 0x7030, 0x9065, 0x0148,
+	0x6044, 0xc0bc, 0x6046, 0x7104, 0x9186, 0x0003, 0x0110, 0x080c,
+	0x98c0, 0x012e, 0x0005, 0x00f6, 0x703c, 0x9086, 0x0002, 0x0528,
+	0x704c, 0x907d, 0x0510, 0x7844, 0xc0bc, 0x7846, 0x7820, 0x9086,
+	0x0009, 0x0118, 0x080c, 0x9fb4, 0x00c0, 0x7828, 0xd0fc, 0x1118,
+	0x080c, 0x9f33, 0x0090, 0x2001, 0x1837, 0x2004, 0x9084, 0x0028,
+	0x1130, 0x2001, 0x197d, 0x2004, 0x9086, 0xaaaa, 0x1120, 0x2001,
+	0x0387, 0x2003, 0x1000, 0x080c, 0x9eb8, 0x00fe, 0x012e, 0x0005,
+	0x080c, 0x7747, 0x012e, 0x0005, 0x080c, 0x0d85, 0x0005, 0x2009,
+	0x1b67, 0x2104, 0xd0bc, 0x01a8, 0xc0bc, 0x200a, 0x2009, 0x010b,
+	0x2104, 0x9085, 0x0002, 0x200a, 0x2009, 0x0101, 0x2104, 0xc0ac,
+	0x200a, 0x2009, 0x0105, 0x2104, 0x9084, 0x1984, 0x9085, 0x8092,
+	0x200a, 0x012e, 0x0005, 0x2009, 0x010b, 0x2104, 0xd08c, 0x01a8,
+	0xc08c, 0x200a, 0x2001, 0x1848, 0x2004, 0xd094, 0x1130, 0x2009,
+	0x0101, 0x2104, 0x9085, 0x0020, 0x200a, 0x2009, 0x1b67, 0x200b,
+	0x0000, 0x2001, 0x001b, 0x080c, 0xaad1, 0x012e, 0x0005, 0x00e6,
+	0x2071, 0x19e9, 0x6044, 0xc0bc, 0x6046, 0xd0fc, 0x01b8, 0x704c,
+	0x9c06, 0x1190, 0x2019, 0x0001, 0x080c, 0xa380, 0x704f, 0x0000,
+	0x2001, 0x0109, 0x2004, 0xd08c, 0x1138, 0x2001, 0x0108, 0x2004,
+	0xd0bc, 0x1110, 0x703f, 0x0000, 0x080c, 0xa585, 0x00ee, 0x0005,
+	0x0026, 0x7010, 0x9c06, 0x1178, 0x080c, 0xa441, 0x6044, 0xc0fc,
+	0x6046, 0x600c, 0x9015, 0x0120, 0x7212, 0x600f, 0x0000, 0x0010,
+	0x7212, 0x720e, 0x9006, 0x002e, 0x0005, 0x0026, 0x7020, 0x9c06,
+	0x1178, 0x080c, 0xa441, 0x6044, 0xc0fc, 0x6046, 0x600c, 0x9015,
+	0x0120, 0x7222, 0x600f, 0x0000, 0x0010, 0x7222, 0x721e, 0x9006,
+	0x002e, 0x0005, 0x00d6, 0x0036, 0x7830, 0x9c06, 0x1558, 0x2069,
+	0x0100, 0x68c0, 0x9005, 0x01f8, 0x080c, 0x88ec, 0x080c, 0xa08a,
+	0x68c3, 0x0000, 0x080c, 0xa56e, 0x2069, 0x0140, 0x6b04, 0x9384,
+	0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2abb, 0x9006, 0x080c,
+	0x2abb, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001,
+	0x9085, 0x0001, 0x0038, 0x7808, 0xc0ad, 0x780a, 0x6003, 0x0009,
+	0x630a, 0x9006, 0x003e, 0x00de, 0x0005, 0x0016, 0x0026, 0x0036,
+	0x6100, 0x2019, 0x0100, 0x2001, 0x0382, 0x2004, 0xd09c, 0x0190,
+	0x00c6, 0x0126, 0x2091, 0x2800, 0x0016, 0x0036, 0x080c, 0xab46,
+	0x003e, 0x001e, 0x012e, 0x00ce, 0x6200, 0x2200, 0x9106, 0x0d58,
+	0x2200, 0x0010, 0x8319, 0x1d38, 0x003e, 0x002e, 0x001e, 0x0005,
+	0x00e6, 0x00d6, 0x00c6, 0x080c, 0xaae0, 0x0106, 0x2071, 0x19e9,
+	0x2069, 0x0100, 0x704c, 0x2060, 0x9086, 0x1b56, 0x15b8, 0x6814,
+	0xd08c, 0x0188, 0x6817, 0x0010, 0x2009, 0x0019, 0x8109, 0x1df0,
+	0x2001, 0x0032, 0x6920, 0xd1bc, 0x0130, 0x8001, 0x1dd8, 0x692c,
+	0x918d, 0x0008, 0x692e, 0x6824, 0xd08c, 0x0110, 0x6827, 0x0002,
+	0x68d0, 0x9005, 0x0118, 0x9082, 0x0005, 0x0238, 0x6060, 0x8000,
+	0x6062, 0x2001, 0x0391, 0x2003, 0x0400, 0x080c, 0x9859, 0x682c,
+	0x9084, 0xfffd, 0x682e, 0x2001, 0x1848, 0x2004, 0xd094, 0x1120,
+	0x6804, 0x9085, 0x0020, 0x6806, 0x2069, 0x0000, 0x010e, 0x090c,
+	0xaafc, 0x8dff, 0x00ce, 0x00de, 0x00ee, 0x0005, 0x00e6, 0x00d6,
+	0x00c6, 0x080c, 0xaae0, 0x0106, 0x2071, 0x19e9, 0x2069, 0x0100,
+	0x080c, 0xad50, 0x68d0, 0x9005, 0x0158, 0x9082, 0x0005, 0x1240,
+	0x080c, 0x2b55, 0x2001, 0x0391, 0x2003, 0x0400, 0x2069, 0x0000,
+	0x010e, 0x090c, 0xaafc, 0x8dff, 0x00ce, 0x00de, 0x00ee, 0x0005,
+	0x0016, 0x2001, 0x0134, 0x2004, 0x9005, 0x0140, 0x9082, 0x0005,
+	0x1228, 0x2001, 0x0391, 0x2003, 0x0404, 0x0020, 0x2001, 0x0391,
+	0x2003, 0x0400, 0x001e, 0x0005, 0x00d6, 0x0156, 0x080c, 0x9d2d,
+	0x7a14, 0x82ff, 0x0138, 0x7003, 0x0100, 0x700b, 0x0003, 0x60c3,
+	0x0008, 0x0490, 0x7003, 0x0200, 0x7007, 0x0000, 0x2069, 0x1800,
+	0x901e, 0x6800, 0x9086, 0x0004, 0x1110, 0xc38d, 0x0060, 0x080c,
+	0x76a5, 0x1110, 0xc3ad, 0x0008, 0xc3a5, 0x6adc, 0xd29c, 0x1110,
+	0xd2ac, 0x0108, 0xc39d, 0x730e, 0x080c, 0x89b1, 0x20a9, 0x0006,
+	0x2011, 0xffec, 0x2019, 0xffed, 0x2071, 0x0250, 0x2305, 0x2072,
+	0x8e70, 0x2205, 0x2072, 0x8e70, 0x9398, 0x0002, 0x9290, 0x0002,
+	0x1f04, 0xae06, 0x60c3, 0x0020, 0x080c, 0xa05a, 0x015e, 0x00de,
+	0x0005, 0x0156, 0x080c, 0x9d2d, 0x7a14, 0x82ff, 0x0168, 0x9286,
+	0xffff, 0x0118, 0x9282, 0x000e, 0x1238, 0x7003, 0x0100, 0x700b,
+	0x0003, 0x60c3, 0x0008, 0x0488, 0x7003, 0x0200, 0x7007, 0x001c,
+	0x700f, 0x0001, 0x2011, 0x19bf, 0x2204, 0x8007, 0x701a, 0x8210,
+	0x2204, 0x8007, 0x701e, 0x0421, 0x1120, 0xb8a0, 0x9082, 0x007f,
+	0x0248, 0x2001, 0x181f, 0x2004, 0x7022, 0x2001, 0x1820, 0x2004,
+	0x7026, 0x0030, 0x2001, 0x1818, 0x2004, 0x9084, 0x00ff, 0x7026,
+	0x20a9, 0x0004, 0x20e1, 0x0001, 0x2099, 0x1805, 0x20e9, 0x0000,
+	0x20a1, 0x0256, 0x4003, 0x60c3, 0x001c, 0x015e, 0x0804, 0xa05a,
+	0x0006, 0x2001, 0x1837, 0x2004, 0xd0ac, 0x000e, 0x0005, 0x2011,
+	0x0003, 0x080c, 0xa40f, 0x2011, 0x0002, 0x080c, 0xa419, 0x080c,
+	0xa300, 0x0036, 0x901e, 0x080c, 0xa380, 0x003e, 0x0005, 0x080c,
+	0x3482, 0x0188, 0x0016, 0x00b6, 0x00c6, 0x7010, 0x9085, 0x0020,
+	0x7012, 0x2009, 0x007e, 0x080c, 0x6789, 0xb85c, 0xc0ac, 0xb85e,
+	0x00ce, 0x00be, 0x001e, 0x0005, 0x00d6, 0x00f6, 0x7104, 0x9186,
+	0x0004, 0x1120, 0x7410, 0x9e90, 0x0004, 0x0068, 0x9186, 0x0001,
+	0x1120, 0x7420, 0x9e90, 0x0008, 0x0030, 0x9186, 0x0002, 0x1508,
+	0x7428, 0x9e90, 0x000a, 0x6110, 0x2468, 0x680c, 0x907d, 0x01c8,
+	0x7810, 0x9106, 0x1128, 0x2f68, 0x780c, 0x907d, 0x1dc8, 0x0088,
+	0x780c, 0x680e, 0x7c0e, 0x2f12, 0x9006, 0x7032, 0x7036, 0x7004,
+	0x9086, 0x0003, 0x0110, 0x7007, 0x0000, 0x9006, 0x00fe, 0x00de,
+	0x0005, 0x9085, 0x0001, 0x0cd0, 0x2071, 0x188d, 0x7000, 0x9005,
+	0x0140, 0x2001, 0x0812, 0x2071, 0x1800, 0x7076, 0x707a, 0x706b,
+	0xffd4, 0x2071, 0x1800, 0x7074, 0x7056, 0x705b, 0x1ddc, 0x0005,
 	0x00e6, 0x0126, 0x2071, 0x1800, 0x2091, 0x8000, 0x7554, 0x9582,
-	0x0001, 0x0608, 0x7058, 0x2060, 0x6000, 0x9086, 0x0000, 0x0148,
+	0x0010, 0x0608, 0x7058, 0x2060, 0x6000, 0x9086, 0x0000, 0x0148,
 	0x9ce0, 0x001c, 0x7068, 0x9c02, 0x1208, 0x0cb0, 0x2061, 0x1ddc,
 	0x0c98, 0x6003, 0x0008, 0x8529, 0x7556, 0x9ca8, 0x001c, 0x7068,
 	0x9502, 0x1230, 0x755a, 0x9085, 0x0001, 0x012e, 0x00ee, 0x0005,
-	0x705b, 0x1ddc, 0x0cc0, 0x9006, 0x0cc0, 0x6020, 0x9084, 0x000f,
-	0x0002, 0xad61, 0xad6b, 0xad86, 0xada1, 0xd0ee, 0xd10b, 0xd126,
-	0xad61, 0xad6b, 0x9025, 0xadbd, 0xad61, 0xad61, 0xad61, 0xad61,
-	0xad61, 0x9186, 0x0013, 0x1130, 0x6044, 0xd0fc, 0x0110, 0x080c,
-	0x967a, 0x0005, 0x0005, 0x0066, 0x6000, 0x90b2, 0x0016, 0x1a0c,
-	0x0d7d, 0x0013, 0x006e, 0x0005, 0xad84, 0xb4fd, 0xb6da, 0xad84,
-	0xb770, 0xb086, 0xad84, 0xad84, 0xb47f, 0xbcda, 0xad84, 0xad84,
-	0xad84, 0xad84, 0xad84, 0xad84, 0x080c, 0x0d7d, 0x0066, 0x6000,
-	0x90b2, 0x0016, 0x1a0c, 0x0d7d, 0x0013, 0x006e, 0x0005, 0xad9f,
-	0xc2f2, 0xad9f, 0xad9f, 0xad9f, 0xad9f, 0xad9f, 0xad9f, 0xc289,
-	0xc475, 0xad9f, 0xc32f, 0xc3b3, 0xc32f, 0xc3b3, 0xad9f, 0x080c,
-	0x0d7d, 0x6000, 0x9082, 0x0016, 0x1a0c, 0x0d7d, 0x6000, 0x0002,
-	0xadbb, 0xbd24, 0xbdbe, 0xbf3e, 0xbfad, 0xadbb, 0xadbb, 0xadbb,
-	0xbcf3, 0xc20a, 0xc20d, 0xadbb, 0xadbb, 0xadbb, 0xadbb, 0xc23d,
-	0xadbb, 0xadbb, 0xadbb, 0x080c, 0x0d7d, 0x0066, 0x6000, 0x90b2,
-	0x0016, 0x1a0c, 0x0d7d, 0x0013, 0x006e, 0x0005, 0xadd6, 0xadd6,
-	0xae14, 0xaeb3, 0xaf33, 0xadd6, 0xadd6, 0xadd6, 0xadd8, 0xadd6,
-	0xadd6, 0xadd6, 0xadd6, 0xadd6, 0xadd6, 0xadd6, 0x080c, 0x0d7d,
-	0x9186, 0x004c, 0x0560, 0x9186, 0x0003, 0x190c, 0x0d7d, 0x0096,
-	0x601c, 0xc0ed, 0x601e, 0x6003, 0x0003, 0x6106, 0x6014, 0x2048,
-	0xa87c, 0x9084, 0xa000, 0xc0b5, 0xa87e, 0xa8ac, 0xa836, 0xa8b0,
-	0xa83a, 0x9006, 0xa846, 0xa84a, 0xa884, 0x9092, 0x199a, 0x0210,
-	0x2001, 0x1999, 0x8003, 0x8013, 0x8213, 0x9210, 0x621a, 0x009e,
-	0x080c, 0x1c10, 0x2009, 0x8030, 0x080c, 0x92f7, 0x0005, 0x6010,
-	0x00b6, 0x2058, 0xbca0, 0x00be, 0x2c00, 0x080c, 0xaf55, 0x080c,
-	0xd0b3, 0x6003, 0x0007, 0x0005, 0x00d6, 0x0096, 0x00f6, 0x2079,
-	0x1800, 0x7a90, 0x6014, 0x2048, 0xa87c, 0xd0ec, 0x1110, 0x9290,
-	0x0018, 0xac78, 0xc4fc, 0x0046, 0xa8e0, 0x9005, 0x1140, 0xa8dc,
-	0x921a, 0x0140, 0x0220, 0xa87b, 0x0007, 0x2010, 0x0028, 0xa87b,
-	0x0015, 0x0010, 0xa87b, 0x0000, 0x8214, 0xa883, 0x0000, 0xaa02,
-	0x0006, 0x0016, 0x0026, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2400,
-	0x9005, 0x1108, 0x009a, 0x2100, 0x9086, 0x0015, 0x1118, 0x2001,
-	0x0001, 0x0038, 0x2100, 0x9086, 0x0016, 0x0118, 0x2001, 0x0001,
-	0x002a, 0x94a4, 0x0007, 0x8423, 0x9405, 0x0002, 0xae7b, 0xae7b,
-	0xae76, 0xae79, 0xae7b, 0xae73, 0xae66, 0xae66, 0xae66, 0xae66,
-	0xae66, 0xae66, 0xae66, 0xae66, 0xae66, 0xae66, 0x00fe, 0x00ee,
-	0x00de, 0x00ce, 0x002e, 0x001e, 0x000e, 0x004e, 0x00fe, 0x009e,
-	0x00de, 0x080c, 0x0d7d, 0x080c, 0xb92f, 0x0028, 0x080c, 0xba14,
-	0x0010, 0x080c, 0xbb0a, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x002e,
-	0x001e, 0x2c00, 0xa896, 0x000e, 0x080c, 0xb013, 0x0530, 0xa804,
-	0xa80e, 0x00a6, 0x2050, 0xb100, 0x00ae, 0x8006, 0x8006, 0x8007,
-	0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x0002, 0xaacc, 0xabd0,
-	0xacd4, 0xadd8, 0x2031, 0x0000, 0x2041, 0x12b0, 0x080c, 0xb1d4,
-	0x0160, 0x000e, 0x9005, 0x0120, 0x00fe, 0x009e, 0x00de, 0x0005,
-	0x00fe, 0x009e, 0x00de, 0x0804, 0xacb0, 0x2001, 0x002c, 0x900e,
-	0x080c, 0xb079, 0x0c70, 0x91b6, 0x0015, 0x0170, 0x91b6, 0x0016,
-	0x0158, 0x91b2, 0x0047, 0x0a0c, 0x0d7d, 0x91b2, 0x0050, 0x1a0c,
-	0x0d7d, 0x9182, 0x0047, 0x0042, 0x080c, 0xab33, 0x0120, 0x9086,
-	0x0002, 0x0904, 0xae14, 0x0005, 0xaed5, 0xaed5, 0xaed7, 0xaf09,
-	0xaed5, 0xaed5, 0xaed5, 0xaed5, 0xaf1c, 0x080c, 0x0d7d, 0x00d6,
-	0x0016, 0x0096, 0x6003, 0x0004, 0x6114, 0x2148, 0xa87c, 0xd0fc,
-	0x01c0, 0xa878, 0xc0fc, 0x9005, 0x1158, 0xa894, 0x9005, 0x0140,
-	0x2001, 0x0000, 0x900e, 0x080c, 0xb079, 0x080c, 0xacb0, 0x00a8,
-	0x6003, 0x0002, 0xa8a4, 0xa9a8, 0x9105, 0x1178, 0xa8ae, 0xa8b2,
-	0x0c78, 0xa87f, 0x0020, 0xa88c, 0xa88a, 0xa8a4, 0xa8ae, 0xa8a8,
-	0xa8b2, 0xa8c7, 0x0000, 0xa8cb, 0x0000, 0x009e, 0x001e, 0x00de,
-	0x0005, 0x080c, 0x96d5, 0x00d6, 0x0096, 0x6114, 0x2148, 0x080c,
-	0xc97a, 0x0120, 0xa87b, 0x0006, 0x080c, 0x6dee, 0x009e, 0x00de,
-	0x080c, 0xacb0, 0x0804, 0x9738, 0x080c, 0x96d5, 0x080c, 0x3240,
-	0x080c, 0xd0b0, 0x00d6, 0x0096, 0x6114, 0x2148, 0x080c, 0xc97a,
-	0x0120, 0xa87b, 0x0029, 0x080c, 0x6dee, 0x009e, 0x00de, 0x080c,
-	0xacb0, 0x0804, 0x9738, 0x9182, 0x0047, 0x0002, 0xaf43, 0xaf45,
-	0xaf43, 0xaf43, 0xaf43, 0xaf43, 0xaf43, 0xaf43, 0xaf43, 0xaf43,
-	0xaf43, 0xaf43, 0xaf45, 0x080c, 0x0d7d, 0x00d6, 0x0096, 0x601f,
-	0x0000, 0x6114, 0x2148, 0xa87b, 0x0000, 0xa883, 0x0000, 0x080c,
-	0x6dee, 0x009e, 0x00de, 0x0804, 0xacb0, 0x0026, 0x0036, 0x0056,
-	0x0066, 0x0096, 0x00a6, 0x00f6, 0x0006, 0x080c, 0x1047, 0x000e,
-	0x090c, 0x0d7d, 0xa960, 0x21e8, 0xa95c, 0x9188, 0x0019, 0x21a0,
-	0x900e, 0x20a9, 0x0020, 0x4104, 0xa87a, 0x2079, 0x1800, 0x7990,
-	0x9188, 0x0018, 0x918c, 0x0fff, 0xa972, 0xac76, 0x2950, 0x00a6,
-	0x2001, 0x0205, 0x2003, 0x0000, 0x901e, 0x2029, 0x0001, 0x9182,
-	0x0034, 0x1228, 0x2011, 0x001f, 0x080c, 0xc4f8, 0x04c0, 0x2130,
-	0x2009, 0x0034, 0x2011, 0x001f, 0x080c, 0xc4f8, 0x96b2, 0x0034,
-	0xb004, 0x904d, 0x0110, 0x080c, 0x0ff9, 0x080c, 0x1047, 0x01d0,
-	0x8528, 0xa867, 0x0110, 0xa86b, 0x0000, 0x2920, 0xb406, 0x968a,
-	0x003d, 0x1230, 0x2608, 0x2011, 0x001b, 0x080c, 0xc4f8, 0x00b8,
-	0x96b2, 0x003c, 0x2009, 0x003c, 0x2950, 0x2011, 0x001b, 0x080c,
-	0xc4f8, 0x0c18, 0x2001, 0x0205, 0x2003, 0x0000, 0x00ae, 0x852f,
-	0x95ad, 0x0050, 0xb566, 0xb070, 0xc0fd, 0xb072, 0x0048, 0x2001,
-	0x0205, 0x2003, 0x0000, 0x00ae, 0x852f, 0x95ad, 0x0050, 0xb566,
-	0x2a48, 0xa804, 0xa807, 0x0000, 0x0006, 0x080c, 0x6dee, 0x000e,
-	0x2048, 0x9005, 0x1db0, 0x00fe, 0x00ae, 0x009e, 0x006e, 0x005e,
-	0x003e, 0x002e, 0x0005, 0x00d6, 0x00f6, 0x0096, 0x0006, 0x080c,
-	0x1047, 0x000e, 0x090c, 0x0d7d, 0xa960, 0x21e8, 0xa95c, 0x9188,
-	0x0019, 0x21a0, 0x900e, 0x20a9, 0x0020, 0x4104, 0xaa66, 0xa87a,
-	0x2079, 0x1800, 0x7990, 0x810c, 0x9188, 0x000c, 0x9182, 0x001a,
-	0x0210, 0x2009, 0x001a, 0x21a8, 0x810b, 0xa972, 0xac76, 0x2e98,
-	0xa85c, 0x9080, 0x001f, 0x20a0, 0x2001, 0x0205, 0x200c, 0x918d,
-	0x0080, 0x2102, 0x4003, 0x2003, 0x0000, 0x080c, 0x6dee, 0x009e,
-	0x00fe, 0x00de, 0x0005, 0x0016, 0x00d6, 0x00f6, 0x0096, 0x0016,
-	0x2001, 0x0205, 0x200c, 0x918d, 0x0080, 0x2102, 0x001e, 0x2079,
-	0x0200, 0x2e98, 0xa87c, 0xd0ec, 0x0118, 0x9e80, 0x000c, 0x2098,
-	0x2021, 0x003e, 0x901e, 0x9282, 0x0020, 0x0218, 0x2011, 0x0020,
-	0x2018, 0x9486, 0x003e, 0x1170, 0x0096, 0x080c, 0x1047, 0x2900,
-	0x009e, 0x05c0, 0xa806, 0x2048, 0xa860, 0x20e8, 0xa85c, 0x9080,
-	0x0002, 0x20a0, 0x3300, 0x908e, 0x0260, 0x0140, 0x2009, 0x0280,
-	0x9102, 0x920a, 0x0218, 0x2010, 0x2100, 0x9318, 0x2200, 0x9402,
-	0x1228, 0x2400, 0x9202, 0x2410, 0x9318, 0x9006, 0x2020, 0x22a8,
-	0xa800, 0x9200, 0xa802, 0x20e1, 0x0000, 0x4003, 0x83ff, 0x0180,
-	0x3300, 0x9086, 0x0280, 0x1130, 0x7814, 0x8000, 0x9085, 0x0080,
-	0x7816, 0x2e98, 0x2310, 0x84ff, 0x0904, 0xb028, 0x0804, 0xb02a,
-	0x9085, 0x0001, 0x7817, 0x0000, 0x009e, 0x00fe, 0x00de, 0x001e,
-	0x0005, 0x00d6, 0x0036, 0x0096, 0x6314, 0x2348, 0xa87a, 0xa982,
-	0x080c, 0x6de2, 0x009e, 0x003e, 0x00de, 0x0005, 0x91b6, 0x0015,
-	0x1118, 0x080c, 0xacb0, 0x0030, 0x91b6, 0x0016, 0x190c, 0x0d7d,
-	0x080c, 0xacb0, 0x0005, 0x20a9, 0x000e, 0x20e1, 0x0000, 0x2e98,
-	0x6014, 0x0096, 0x2048, 0xa860, 0x20e8, 0xa85c, 0x20a0, 0x009e,
-	0x4003, 0x0136, 0x9080, 0x001b, 0x20a0, 0x2011, 0x0006, 0x20a9,
-	0x0001, 0x3418, 0x8318, 0x23a0, 0x4003, 0x3318, 0x8318, 0x2398,
-	0x8211, 0x1db8, 0x2011, 0x0006, 0x013e, 0x20a0, 0x3318, 0x8318,
-	0x2398, 0x4003, 0x3418, 0x8318, 0x23a0, 0x8211, 0x1db8, 0x0096,
-	0x080c, 0xc97a, 0x0130, 0x6014, 0x2048, 0xa807, 0x0000, 0xa867,
-	0x0103, 0x009e, 0x0804, 0xacb0, 0x0096, 0x00d6, 0x0036, 0x7330,
-	0x9386, 0x0200, 0x11a8, 0x6010, 0x00b6, 0x2058, 0xb8d7, 0x0000,
-	0x00be, 0x6014, 0x9005, 0x0130, 0x2048, 0xa807, 0x0000, 0xa867,
-	0x0103, 0xab32, 0x080c, 0xacb0, 0x003e, 0x00de, 0x009e, 0x0005,
-	0x0011, 0x1d48, 0x0cc8, 0x0006, 0x0016, 0x080c, 0xd09b, 0x0188,
-	0x6014, 0x9005, 0x1170, 0x600b, 0x0003, 0x601b, 0x0000, 0x604b,
-	0x0000, 0x2009, 0x0022, 0x080c, 0xb4d5, 0x9006, 0x001e, 0x000e,
-	0x0005, 0x9085, 0x0001, 0x0cd0, 0x0096, 0x0016, 0x20a9, 0x0014,
-	0x9e80, 0x000c, 0x20e1, 0x0000, 0x2098, 0x6014, 0x2048, 0xa860,
-	0x20e8, 0xa85c, 0x9080, 0x0002, 0x20a0, 0x4003, 0x2001, 0x0205,
-	0x2003, 0x0001, 0x2099, 0x0260, 0x20a9, 0x0016, 0x4003, 0x20a9,
-	0x000a, 0xa804, 0x2048, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0002,
-	0x20a0, 0x4003, 0x2001, 0x0205, 0x2003, 0x0002, 0x2099, 0x0260,
-	0x20a9, 0x0020, 0x4003, 0x2003, 0x0000, 0x6014, 0x2048, 0xa800,
-	0x2048, 0xa867, 0x0103, 0x080c, 0xacb0, 0x001e, 0x009e, 0x0005,
-	0x0096, 0x0016, 0x900e, 0x7030, 0x9086, 0x0100, 0x0140, 0x7038,
-	0x9084, 0x00ff, 0x800c, 0x703c, 0x9084, 0x00ff, 0x8004, 0x9080,
-	0x0004, 0x9108, 0x810b, 0x2011, 0x0002, 0x2019, 0x000c, 0x6014,
-	0x2048, 0x080c, 0xc4f8, 0x080c, 0xc97a, 0x0140, 0x6014, 0x2048,
-	0xa807, 0x0000, 0xa864, 0xa8e2, 0xa867, 0x0103, 0x080c, 0xacb0,
-	0x001e, 0x009e, 0x0005, 0x0016, 0x2009, 0x0000, 0x7030, 0x9086,
-	0x0200, 0x0110, 0x2009, 0x0001, 0x0096, 0x6014, 0x904d, 0x090c,
-	0x0d7d, 0xa97a, 0x080c, 0x6dee, 0x009e, 0x080c, 0xacb0, 0x001e,
-	0x0005, 0x0016, 0x0096, 0x7030, 0x9086, 0x0100, 0x1118, 0x2009,
-	0x0004, 0x0010, 0x7034, 0x800c, 0x810b, 0x2011, 0x000c, 0x2019,
-	0x000c, 0x6014, 0x2048, 0xa804, 0x0096, 0x9005, 0x0108, 0x2048,
-	0x080c, 0xc4f8, 0x009e, 0x080c, 0xc97a, 0x0148, 0xa804, 0x9005,
-	0x1158, 0xa807, 0x0000, 0xa864, 0xa8e2, 0xa867, 0x0103, 0x080c,
-	0xacb0, 0x009e, 0x001e, 0x0005, 0x0086, 0x2040, 0xa030, 0x8007,
-	0x9086, 0x0100, 0x1118, 0x080c, 0xb693, 0x00e0, 0xa034, 0x8007,
-	0x800c, 0x8806, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0,
-	0x9080, 0x000c, 0xa87b, 0x0000, 0xa883, 0x0000, 0xa897, 0x4000,
-	0xaaa0, 0xab9c, 0xaca8, 0xada4, 0x2031, 0x0000, 0x2041, 0x1296,
-	0x0019, 0x0d08, 0x008e, 0x0898, 0x0096, 0x0006, 0x080c, 0x1047,
-	0x000e, 0x01b0, 0xa8ab, 0x0dcb, 0xa876, 0x000e, 0xa8a2, 0x0006,
-	0xae6a, 0x2800, 0xa89e, 0xa97a, 0xaf72, 0xaa8e, 0xab92, 0xac96,
-	0xad9a, 0x0086, 0x2940, 0x080c, 0x113c, 0x008e, 0x9085, 0x0001,
-	0x009e, 0x0005, 0x00e6, 0x00d6, 0x0026, 0x7008, 0x9084, 0x00ff,
-	0x6210, 0x00b6, 0x2258, 0xba10, 0x00be, 0x9206, 0x1520, 0x700c,
-	0x6210, 0x00b6, 0x2258, 0xba14, 0x00be, 0x9206, 0x11e0, 0x604b,
-	0x0000, 0x2c68, 0x0016, 0x2009, 0x0035, 0x080c, 0xd013, 0x001e,
-	0x1158, 0x622c, 0x2268, 0x2071, 0x026c, 0x6b20, 0x9386, 0x0003,
-	0x0130, 0x9386, 0x0006, 0x0128, 0x080c, 0xacb0, 0x0020, 0x0039,
-	0x0010, 0x080c, 0xb30a, 0x002e, 0x00de, 0x00ee, 0x0005, 0x0096,
-	0x6814, 0x2048, 0x9186, 0x0015, 0x0904, 0xb2e9, 0x918e, 0x0016,
-	0x1904, 0xb308, 0x700c, 0x908c, 0xff00, 0x9186, 0x1700, 0x0120,
-	0x9186, 0x0300, 0x1904, 0xb2c3, 0x89ff, 0x1138, 0x6800, 0x9086,
-	0x000f, 0x0904, 0xb2a5, 0x0804, 0xb306, 0x6808, 0x9086, 0xffff,
-	0x1904, 0xb2eb, 0xa87c, 0x9084, 0x0060, 0x9086, 0x0020, 0x1150,
-	0xa8ac, 0xa934, 0x9106, 0x1904, 0xb2eb, 0xa8b0, 0xa938, 0x9106,
-	0x1904, 0xb2eb, 0x6824, 0xd084, 0x1904, 0xb2eb, 0xd0b4, 0x0158,
-	0x0016, 0x2001, 0x1985, 0x200c, 0x6018, 0x9102, 0x9082, 0x0005,
-	0x001e, 0x1a04, 0xb2eb, 0x080c, 0xcb6b, 0x6810, 0x0096, 0x2048,
-	0xa9a0, 0x009e, 0x685c, 0xa87a, 0xa976, 0x6864, 0xa882, 0xa87c,
-	0xc0dc, 0xc0f4, 0xc0d4, 0xa87e, 0x0026, 0x900e, 0x6a18, 0x2001,
-	0x000a, 0x080c, 0x91f8, 0xa884, 0x920a, 0x0208, 0x8011, 0xaa86,
-	0x82ff, 0x002e, 0x1138, 0x00c6, 0x2d60, 0x080c, 0xc683, 0x00ce,
-	0x0804, 0xb306, 0x00c6, 0xa868, 0xd0fc, 0x1118, 0x080c, 0x6124,
-	0x0010, 0x080c, 0x652f, 0x00ce, 0x1904, 0xb2eb, 0x00c6, 0x2d60,
-	0x080c, 0xacb0, 0x00ce, 0x0804, 0xb306, 0x00c6, 0x080c, 0xad20,
-	0x0198, 0x6017, 0x0000, 0x6810, 0x6012, 0x080c, 0xce15, 0x6023,
-	0x0003, 0x6904, 0x00c6, 0x2d60, 0x080c, 0xacb0, 0x00ce, 0x080c,
-	0xad4d, 0x00ce, 0x0804, 0xb306, 0x2001, 0x1987, 0x2004, 0x684a,
-	0x00ce, 0x0804, 0xb306, 0x7008, 0x9086, 0x000b, 0x11c8, 0x6010,
-	0x00b6, 0x2058, 0xb900, 0xc1bc, 0xb902, 0x00be, 0x00c6, 0x2d60,
-	0xa87b, 0x0003, 0x080c, 0xd055, 0x6007, 0x0085, 0x6003, 0x000b,
-	0x6023, 0x0002, 0x2009, 0x8020, 0x080c, 0x92b0, 0x00ce, 0x0430,
-	0x700c, 0x9086, 0x2a00, 0x1138, 0x2001, 0x1987, 0x2004, 0x684a,
-	0x00e8, 0x04c1, 0x00e8, 0x89ff, 0x090c, 0x0d7d, 0x00c6, 0x00d6,
-	0x2d60, 0xa867, 0x0103, 0xa87b, 0x0003, 0x080c, 0x6c04, 0x080c,
-	0xcb6b, 0x080c, 0xaceb, 0x0026, 0x6010, 0x00b6, 0x2058, 0xba3c,
-	0x080c, 0x67be, 0x00be, 0x002e, 0x00de, 0x00ce, 0x080c, 0xacb0,
-	0x009e, 0x0005, 0x9186, 0x0015, 0x1128, 0x2001, 0x1987, 0x2004,
-	0x684a, 0x0068, 0x918e, 0x0016, 0x1160, 0x00c6, 0x2d00, 0x2060,
-	0x080c, 0xe6a0, 0x080c, 0x894e, 0x080c, 0xacb0, 0x00ce, 0x080c,
-	0xacb0, 0x0005, 0x0026, 0x0036, 0x0046, 0x7228, 0xacb0, 0xabac,
-	0xd2f4, 0x0130, 0x2001, 0x1987, 0x2004, 0x684a, 0x0804, 0xb384,
-	0x00c6, 0x2d60, 0x080c, 0xc559, 0x00ce, 0x6804, 0x9086, 0x0050,
-	0x1168, 0x00c6, 0x2d00, 0x2060, 0x6003, 0x0001, 0x6007, 0x0050,
-	0x2009, 0x8023, 0x080c, 0x92b0, 0x00ce, 0x04f0, 0x6800, 0x9086,
-	0x000f, 0x01a8, 0x89ff, 0x090c, 0x0d7d, 0x6800, 0x9086, 0x0004,
-	0x1190, 0xa87c, 0xd0ac, 0x0178, 0xa843, 0x0fff, 0xa83f, 0x0fff,
-	0xa880, 0xc0fc, 0xa882, 0x2001, 0x0001, 0x6832, 0x0400, 0x2001,
-	0x0007, 0x6832, 0x00e0, 0xa87c, 0xd0b4, 0x1150, 0xd0ac, 0x0db8,
-	0x6824, 0xd0f4, 0x1d48, 0xa838, 0xa934, 0x9105, 0x0d80, 0x0c20,
-	0xd2ec, 0x1d68, 0x7024, 0x9306, 0x1118, 0x7020, 0x9406, 0x0d38,
-	0x7020, 0x683e, 0x7024, 0x683a, 0x2001, 0x0005, 0x6832, 0x080c,
-	0xccff, 0x080c, 0x9738, 0x0010, 0x080c, 0xacb0, 0x004e, 0x003e,
-	0x002e, 0x0005, 0x00e6, 0x00d6, 0x0026, 0x7008, 0x9084, 0x00ff,
-	0x6210, 0x00b6, 0x2258, 0xba10, 0x00be, 0x9206, 0x1904, 0xb3ef,
-	0x700c, 0x6210, 0x00b6, 0x2258, 0xba14, 0x00be, 0x9206, 0x1904,
-	0xb3ef, 0x6038, 0x2068, 0x6824, 0xc0dc, 0x6826, 0x6a20, 0x9286,
-	0x0007, 0x0904, 0xb3ef, 0x9286, 0x0002, 0x0904, 0xb3ef, 0x9286,
-	0x0000, 0x05e8, 0x6808, 0x633c, 0x9306, 0x15c8, 0x2071, 0x026c,
-	0x9186, 0x0015, 0x0570, 0x918e, 0x0016, 0x1100, 0x00c6, 0x6038,
-	0x2060, 0x6104, 0x9186, 0x004b, 0x01c0, 0x9186, 0x004c, 0x01a8,
-	0x9186, 0x004d, 0x0190, 0x9186, 0x004e, 0x0178, 0x9186, 0x0052,
-	0x0160, 0x6014, 0x0096, 0x2048, 0x080c, 0xc97a, 0x090c, 0x0d7d,
-	0xa87b, 0x0003, 0x009e, 0x080c, 0xd055, 0x6007, 0x0085, 0x6003,
-	0x000b, 0x6023, 0x0002, 0x2009, 0x8020, 0x080c, 0x92b0, 0x00ce,
-	0x0030, 0x6038, 0x2070, 0x2001, 0x1987, 0x2004, 0x704a, 0x080c,
-	0xacb0, 0x002e, 0x00de, 0x00ee, 0x0005, 0x00b6, 0x0096, 0x00f6,
-	0x6014, 0x2048, 0x6010, 0x2058, 0x91b6, 0x0015, 0x0130, 0xba08,
-	0xbb0c, 0xbc00, 0xc48c, 0xbc02, 0x0460, 0x0096, 0x0156, 0x0036,
-	0x0026, 0x2b48, 0x9e90, 0x0010, 0x2019, 0x000a, 0x20a9, 0x0004,
-	0x080c, 0xbca2, 0x002e, 0x003e, 0x015e, 0x009e, 0x1904, 0xb45e,
-	0x0096, 0x0156, 0x0036, 0x0026, 0x2b48, 0x9e90, 0x0014, 0x2019,
-	0x0006, 0x20a9, 0x0004, 0x080c, 0xbca2, 0x002e, 0x003e, 0x015e,
-	0x009e, 0x15a0, 0x7238, 0xba0a, 0x733c, 0xbb0e, 0xbc00, 0xc48d,
-	0xbc02, 0xa804, 0x9005, 0x1128, 0x00fe, 0x009e, 0x00be, 0x0804,
-	0xb0bf, 0x0096, 0x2048, 0xaa12, 0xab16, 0xac0a, 0x009e, 0x8006,
-	0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x0002,
-	0x2009, 0x002b, 0xaaa0, 0xab9c, 0xaca8, 0xada4, 0x2031, 0x0000,
-	0x2041, 0x1296, 0x080c, 0xb1d4, 0x0130, 0x00fe, 0x009e, 0x080c,
-	0xacb0, 0x00be, 0x0005, 0x080c, 0xb693, 0x0cb8, 0x2b78, 0x00f6,
-	0x080c, 0x3240, 0x080c, 0xd0b0, 0x00fe, 0x00c6, 0x080c, 0xac5a,
-	0x2f00, 0x6012, 0x6017, 0x0000, 0x6023, 0x0001, 0x6007, 0x0001,
-	0x6003, 0x0001, 0x2001, 0x0007, 0x080c, 0x65e3, 0x080c, 0x660f,
-	0x080c, 0x92b7, 0x080c, 0x9738, 0x00ce, 0x0804, 0xb431, 0x2100,
-	0x91b2, 0x0053, 0x1a0c, 0x0d7d, 0x91b2, 0x0040, 0x1a04, 0xb4e7,
-	0x0002, 0xb4d5, 0xb4d5, 0xb4cb, 0xb4d5, 0xb4d5, 0xb4d5, 0xb4c9,
-	0xb4c9, 0xb4c9, 0xb4c9, 0xb4c9, 0xb4c9, 0xb4c9, 0xb4c9, 0xb4c9,
-	0xb4c9, 0xb4c9, 0xb4c9, 0xb4c9, 0xb4c9, 0xb4c9, 0xb4c9, 0xb4c9,
-	0xb4c9, 0xb4c9, 0xb4c9, 0xb4c9, 0xb4c9, 0xb4c9, 0xb4c9, 0xb4c9,
-	0xb4d5, 0xb4c9, 0xb4d5, 0xb4d5, 0xb4c9, 0xb4c9, 0xb4c9, 0xb4c9,
-	0xb4c9, 0xb4cb, 0xb4c9, 0xb4c9, 0xb4c9, 0xb4c9, 0xb4c9, 0xb4c9,
-	0xb4c9, 0xb4c9, 0xb4c9, 0xb4d5, 0xb4d5, 0xb4c9, 0xb4c9, 0xb4c9,
-	0xb4c9, 0xb4c9, 0xb4c9, 0xb4c9, 0xb4c9, 0xb4c9, 0xb4d5, 0xb4c9,
-	0xb4c9, 0x080c, 0x0d7d, 0x0066, 0x00b6, 0x6610, 0x2658, 0xb8d4,
-	0xc08c, 0xb8d6, 0x00be, 0x006e, 0x0000, 0x6003, 0x0001, 0x6106,
-	0x9186, 0x0032, 0x0118, 0x080c, 0x92b7, 0x0010, 0x080c, 0x92b0,
-	0x0126, 0x2091, 0x8000, 0x080c, 0x9738, 0x012e, 0x0005, 0x2600,
-	0x0002, 0xb4d5, 0xb4d5, 0xb4fb, 0xb4d5, 0xb4d5, 0xb4fb, 0xb4fb,
-	0xb4fb, 0xb4fb, 0xb4d5, 0xb4fb, 0xb4d5, 0xb4fb, 0xb4d5, 0xb4fb,
-	0xb4fb, 0xb4fb, 0xb4fb, 0x080c, 0x0d7d, 0x6004, 0x90b2, 0x0053,
-	0x1a0c, 0x0d7d, 0x91b6, 0x0013, 0x0904, 0xb5d2, 0x91b6, 0x0027,
-	0x1904, 0xb57e, 0x080c, 0x967a, 0x6004, 0x080c, 0xcb80, 0x01b0,
-	0x080c, 0xcb91, 0x01a8, 0x908e, 0x0021, 0x0904, 0xb57b, 0x908e,
-	0x0022, 0x1130, 0x080c, 0xb0eb, 0x0904, 0xb577, 0x0804, 0xb578,
-	0x908e, 0x003d, 0x0904, 0xb57b, 0x0804, 0xb571, 0x080c, 0x326f,
-	0x2001, 0x0007, 0x080c, 0x65e3, 0x6010, 0x00b6, 0x2058, 0xb9a0,
-	0x00be, 0x080c, 0xb693, 0x9186, 0x007e, 0x1148, 0x2001, 0x1837,
-	0x2014, 0xc285, 0x080c, 0x753d, 0x1108, 0xc2ad, 0x2202, 0x080c,
-	0xa91e, 0x0036, 0x0026, 0x2019, 0x0028, 0x2110, 0x080c, 0xe7ac,
-	0x002e, 0x003e, 0x0016, 0x0026, 0x0036, 0x2110, 0x2019, 0x0028,
-	0x080c, 0x943d, 0x0076, 0x903e, 0x080c, 0x9306, 0x6010, 0x00b6,
-	0x905d, 0x0100, 0x00be, 0x2c08, 0x080c, 0xe167, 0x007e, 0x003e,
-	0x002e, 0x001e, 0x080c, 0xa93a, 0x080c, 0xd0b0, 0x0016, 0x080c,
-	0xce0d, 0x080c, 0xacb0, 0x001e, 0x080c, 0x3349, 0x080c, 0x9738,
-	0x0030, 0x080c, 0xce0d, 0x080c, 0xacb0, 0x080c, 0x9738, 0x0005,
-	0x080c, 0xb693, 0x0cb0, 0x080c, 0xb6cf, 0x0c98, 0x9186, 0x0015,
-	0x0118, 0x9186, 0x0016, 0x1140, 0x080c, 0xab33, 0x0d80, 0x9086,
-	0x0002, 0x0904, 0xb6da, 0x0c58, 0x9186, 0x0014, 0x1d40, 0x080c,
-	0x967a, 0x6004, 0x908e, 0x0022, 0x1118, 0x080c, 0xb0eb, 0x09f8,
-	0x080c, 0x3240, 0x080c, 0xd0b0, 0x080c, 0xcb80, 0x1190, 0x080c,
-	0x326f, 0x6010, 0x00b6, 0x2058, 0xb9a0, 0x00be, 0x080c, 0xb693,
-	0x9186, 0x007e, 0x1128, 0x2001, 0x1837, 0x200c, 0xc185, 0x2102,
-	0x0800, 0x080c, 0xcb91, 0x1120, 0x080c, 0xb693, 0x0804, 0xb571,
-	0x6004, 0x908e, 0x0032, 0x1160, 0x00e6, 0x00f6, 0x2071, 0x189e,
-	0x2079, 0x0000, 0x080c, 0x35ea, 0x00fe, 0x00ee, 0x0804, 0xb571,
-	0x6004, 0x908e, 0x0021, 0x0d40, 0x908e, 0x0022, 0x090c, 0xb693,
-	0x0804, 0xb571, 0x90b2, 0x0040, 0x1a04, 0xb673, 0x2008, 0x0002,
-	0xb61a, 0xb61b, 0xb61e, 0xb621, 0xb624, 0xb627, 0xb618, 0xb618,
-	0xb618, 0xb618, 0xb618, 0xb618, 0xb618, 0xb618, 0xb618, 0xb618,
-	0xb618, 0xb618, 0xb618, 0xb618, 0xb618, 0xb618, 0xb618, 0xb618,
-	0xb618, 0xb618, 0xb618, 0xb618, 0xb618, 0xb618, 0xb62a, 0xb635,
-	0xb618, 0xb636, 0xb635, 0xb618, 0xb618, 0xb618, 0xb618, 0xb618,
-	0xb635, 0xb635, 0xb618, 0xb618, 0xb618, 0xb618, 0xb618, 0xb618,
-	0xb618, 0xb618, 0xb65e, 0xb635, 0xb618, 0xb631, 0xb618, 0xb618,
-	0xb618, 0xb632, 0xb618, 0xb618, 0xb618, 0xb635, 0xb659, 0xb618,
-	0x080c, 0x0d7d, 0x00d0, 0x2001, 0x000b, 0x00f8, 0x2001, 0x0003,
-	0x00e0, 0x2001, 0x0005, 0x00c8, 0x2001, 0x0001, 0x00b0, 0x2001,
-	0x0009, 0x0098, 0x6003, 0x0005, 0x080c, 0xd0b3, 0x080c, 0x9738,
-	0x0058, 0x0018, 0x0010, 0x080c, 0x65e3, 0x04b8, 0x080c, 0xd0b3,
-	0x6003, 0x0004, 0x080c, 0x9738, 0x0005, 0x080c, 0x65e3, 0x6003,
-	0x0002, 0x0036, 0x2019, 0x1852, 0x2304, 0x9084, 0xff00, 0x1120,
-	0x2001, 0x1985, 0x201c, 0x0040, 0x8007, 0x909a, 0x0004, 0x0ec0,
-	0x8003, 0x801b, 0x831b, 0x9318, 0x631a, 0x003e, 0x080c, 0x9738,
-	0x0c18, 0x080c, 0xce0d, 0x080c, 0xacb0, 0x08f0, 0x00e6, 0x00f6,
-	0x2071, 0x189e, 0x2079, 0x0000, 0x080c, 0x35ea, 0x00fe, 0x00ee,
-	0x080c, 0x967a, 0x080c, 0xacb0, 0x0878, 0x6003, 0x0002, 0x080c,
-	0xd0b3, 0x0804, 0x9738, 0x2600, 0x2008, 0x0002, 0xb68a, 0xb66d,
-	0xb688, 0xb66d, 0xb66d, 0xb688, 0xb688, 0xb688, 0xb688, 0xb66d,
-	0xb688, 0xb66d, 0xb688, 0xb66d, 0xb688, 0xb688, 0xb688, 0xb688,
-	0x080c, 0x0d7d, 0x0096, 0x6014, 0x2048, 0x080c, 0x6dee, 0x009e,
-	0x080c, 0xacb0, 0x0005, 0x00e6, 0x0096, 0x0026, 0x0016, 0x080c,
-	0xc97a, 0x0568, 0x6014, 0x2048, 0xa864, 0x9086, 0x0139, 0x11a8,
-	0xa894, 0x9086, 0x0056, 0x1148, 0x080c, 0x54ca, 0x0130, 0x2001,
-	0x0000, 0x900e, 0x2011, 0x4000, 0x0028, 0x2001, 0x0030, 0x900e,
-	0x2011, 0x4005, 0x080c, 0xcf7a, 0x0090, 0xa868, 0xd0fc, 0x0178,
-	0xa807, 0x0000, 0x0016, 0x6004, 0x908e, 0x0021, 0x0168, 0x908e,
-	0x003d, 0x0150, 0x001e, 0xa867, 0x0103, 0xa833, 0x0100, 0x001e,
-	0x002e, 0x009e, 0x00ee, 0x0005, 0x001e, 0x0009, 0x0cc0, 0x0096,
-	0x6014, 0x2048, 0xa800, 0x2048, 0xa867, 0x0103, 0xa823, 0x8001,
-	0x009e, 0x0005, 0x00b6, 0x6610, 0x2658, 0xb804, 0x9084, 0x00ff,
-	0x90b2, 0x000c, 0x1a0c, 0x0d7d, 0x6604, 0x96b6, 0x004d, 0x1120,
-	0x080c, 0xce99, 0x0804, 0xb75f, 0x6604, 0x96b6, 0x0043, 0x1120,
-	0x080c, 0xcee2, 0x0804, 0xb75f, 0x6604, 0x96b6, 0x004b, 0x1120,
-	0x080c, 0xcf0e, 0x0804, 0xb75f, 0x6604, 0x96b6, 0x0033, 0x1120,
-	0x080c, 0xce2f, 0x0804, 0xb75f, 0x6604, 0x96b6, 0x0028, 0x1120,
-	0x080c, 0xcbcf, 0x0804, 0xb75f, 0x6604, 0x96b6, 0x0029, 0x1120,
-	0x080c, 0xcc10, 0x0804, 0xb75f, 0x6604, 0x96b6, 0x001f, 0x1120,
-	0x080c, 0xb093, 0x0804, 0xb75f, 0x6604, 0x96b6, 0x0000, 0x1118,
-	0x080c, 0xb3f5, 0x04e0, 0x6604, 0x96b6, 0x0022, 0x1118, 0x080c,
-	0xb0cc, 0x04a8, 0x6604, 0x96b6, 0x0035, 0x1118, 0x080c, 0xb1f2,
-	0x0470, 0x6604, 0x96b6, 0x0039, 0x1118, 0x080c, 0xb38a, 0x0438,
-	0x6604, 0x96b6, 0x003d, 0x1118, 0x080c, 0xb104, 0x0400, 0x6604,
-	0x96b6, 0x0044, 0x1118, 0x080c, 0xb140, 0x00c8, 0x6604, 0x96b6,
-	0x0049, 0x1118, 0x080c, 0xb181, 0x0090, 0x6604, 0x96b6, 0x0041,
-	0x1118, 0x080c, 0xb16b, 0x0058, 0x91b6, 0x0015, 0x1110, 0x0063,
-	0x0030, 0x91b6, 0x0016, 0x1128, 0x00be, 0x0804, 0xb9bb, 0x00be,
-	0x0005, 0x080c, 0xad6a, 0x0cd8, 0xb77c, 0xb77f, 0xb77c, 0xb7c6,
-	0xb77c, 0xb92f, 0xb9c8, 0xb77c, 0xb77c, 0xb991, 0xb77c, 0xb9a7,
-	0x0096, 0x601f, 0x0000, 0x6014, 0x2048, 0xa800, 0x2048, 0xa867,
-	0x0103, 0x009e, 0x0804, 0xacb0, 0xa001, 0xa001, 0x0005, 0x00e6,
-	0x2071, 0x1800, 0x7090, 0x9086, 0x0074, 0x1540, 0x080c, 0xe138,
-	0x11b0, 0x6010, 0x00b6, 0x2058, 0x7030, 0xd08c, 0x0128, 0xb800,
-	0xd0bc, 0x0110, 0xc0c5, 0xb802, 0x00f9, 0x00be, 0x2001, 0x0006,
-	0x080c, 0x65e3, 0x080c, 0x326f, 0x080c, 0xacb0, 0x0098, 0x2001,
-	0x000a, 0x080c, 0x65e3, 0x080c, 0x326f, 0x6003, 0x0001, 0x6007,
-	0x0001, 0x080c, 0x92b7, 0x080c, 0x9738, 0x0020, 0x2001, 0x0001,
-	0x080c, 0xb8ff, 0x00ee, 0x0005, 0x00d6, 0xb800, 0xd084, 0x0160,
-	0x9006, 0x080c, 0x65cf, 0x2069, 0x1847, 0x6804, 0xd0a4, 0x0120,
-	0x2001, 0x0006, 0x080c, 0x660f, 0x00de, 0x0005, 0x00b6, 0x0096,
-	0x00d6, 0x2011, 0x1824, 0x2204, 0x9086, 0x0074, 0x1904, 0xb8d4,
-	0x6010, 0x2058, 0xbaa0, 0x9286, 0x007e, 0x1120, 0x080c, 0xbb15,
-	0x0804, 0xb838, 0x080c, 0xbb0a, 0x6010, 0x2058, 0xbaa0, 0x9286,
-	0x0080, 0x1510, 0x6014, 0x9005, 0x01a8, 0x2048, 0xa864, 0x9084,
-	0x00ff, 0x9086, 0x0039, 0x1140, 0x2001, 0x0000, 0x900e, 0x2011,
-	0x4000, 0x080c, 0xcf7a, 0x0030, 0xa807, 0x0000, 0xa867, 0x0103,
-	0xa833, 0x0200, 0x2001, 0x0006, 0x080c, 0x65e3, 0x080c, 0x326f,
-	0x080c, 0xacb0, 0x0804, 0xb8d9, 0x080c, 0xb8e7, 0x6014, 0x9005,
-	0x0190, 0x2048, 0xa868, 0xd0f4, 0x01e8, 0xa864, 0x9084, 0x00ff,
-	0x9086, 0x0039, 0x1d08, 0x2001, 0x0000, 0x900e, 0x2011, 0x4000,
-	0x080c, 0xcf7a, 0x08f8, 0x080c, 0xb8dd, 0x0160, 0x9006, 0x080c,
-	0x65cf, 0x2001, 0x0004, 0x080c, 0x660f, 0x2001, 0x0007, 0x080c,
-	0x65e3, 0x08a0, 0x2001, 0x0004, 0x080c, 0x65e3, 0x6003, 0x0001,
-	0x6007, 0x0003, 0x080c, 0x92b7, 0x080c, 0x9738, 0x0804, 0xb8d9,
-	0xb85c, 0xd0e4, 0x01d8, 0x080c, 0xcda7, 0x080c, 0x753d, 0x0118,
-	0xd0dc, 0x1904, 0xb7fa, 0x2011, 0x1837, 0x2204, 0xc0ad, 0x2012,
-	0x2001, 0x196c, 0x2004, 0x00f6, 0x2079, 0x0100, 0x78e3, 0x0000,
-	0x080c, 0x26d5, 0x78e2, 0x00fe, 0x0804, 0xb7fa, 0x080c, 0xcde8,
-	0x2011, 0x1837, 0x2204, 0xc0a5, 0x2012, 0x0006, 0x080c, 0xe2c8,
-	0x000e, 0x1904, 0xb7fa, 0xc0b5, 0x2012, 0x2001, 0x0006, 0x080c,
-	0x65e3, 0x9006, 0x080c, 0x65cf, 0x00c6, 0x2001, 0x180f, 0x2004,
-	0xd09c, 0x0520, 0x00f6, 0x2079, 0x0100, 0x00e6, 0x2071, 0x1800,
-	0x700c, 0x9084, 0x00ff, 0x78e6, 0x707e, 0x7010, 0x78ea, 0x7082,
-	0x908c, 0x00ff, 0x00ee, 0x780c, 0xc0b5, 0x780e, 0x00fe, 0x080c,
-	0x26aa, 0x00f6, 0x2100, 0x900e, 0x080c, 0x2661, 0x795e, 0x00fe,
-	0x9186, 0x0081, 0x01d8, 0x2009, 0x0081, 0x00c8, 0x2009, 0x00ef,
-	0x00f6, 0x2079, 0x0100, 0x79ea, 0x7932, 0x7936, 0x780c, 0xc0b5,
-	0x780e, 0x00fe, 0x080c, 0x26aa, 0x00f6, 0x2079, 0x1800, 0x7982,
-	0x2100, 0x900e, 0x080c, 0x2661, 0x795e, 0x00fe, 0x8108, 0x080c,
-	0x6632, 0x2b00, 0x00ce, 0x1904, 0xb7fa, 0x6012, 0x2009, 0x180f,
-	0x210c, 0xd19c, 0x0150, 0x2009, 0x027c, 0x210c, 0x918c, 0x00ff,
-	0xb912, 0x2009, 0x027d, 0x210c, 0xb916, 0x2001, 0x0002, 0x080c,
-	0x65e3, 0x6023, 0x0001, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c,
-	0x92b7, 0x080c, 0x9738, 0x0028, 0x080c, 0xb693, 0x2001, 0x0001,
-	0x0431, 0x00de, 0x009e, 0x00be, 0x0005, 0x2001, 0x1810, 0x2004,
-	0xd0a4, 0x0120, 0x2001, 0x1848, 0x2004, 0xd0ac, 0x0005, 0x00e6,
-	0x080c, 0xe805, 0x0190, 0x2071, 0x0260, 0x7108, 0x720c, 0x918c,
-	0x00ff, 0x1118, 0x9284, 0xff00, 0x0140, 0x6010, 0x2058, 0xb8a0,
-	0x9084, 0xff80, 0x1110, 0xb912, 0xba16, 0x00ee, 0x0005, 0x2030,
-	0x9005, 0x0158, 0x2001, 0x0007, 0x080c, 0x65e3, 0x080c, 0x5752,
-	0x1120, 0x2001, 0x0007, 0x080c, 0x660f, 0x2600, 0x9005, 0x11b0,
-	0x6014, 0x0096, 0x2048, 0xa868, 0x009e, 0xd0fc, 0x1178, 0x0036,
-	0x0046, 0x6010, 0x00b6, 0x2058, 0xbba0, 0x00be, 0x2021, 0x0004,
-	0x2011, 0x8014, 0x080c, 0x4b52, 0x004e, 0x003e, 0x080c, 0x326f,
-	0x6020, 0x9086, 0x000a, 0x1108, 0x0005, 0x0804, 0xacb0, 0x00b6,
-	0x00e6, 0x0026, 0x0016, 0x2071, 0x1800, 0x7090, 0x9086, 0x0014,
-	0x1904, 0xb987, 0x080c, 0x5752, 0x1170, 0x6014, 0x9005, 0x1158,
-	0x0036, 0x0046, 0x6010, 0x2058, 0xbba0, 0x2021, 0x0006, 0x080c,
-	0x4d09, 0x004e, 0x003e, 0x00d6, 0x6010, 0x2058, 0x080c, 0x672e,
-	0x080c, 0xb7b4, 0x00de, 0x080c, 0xbbdb, 0x1588, 0x6010, 0x2058,
-	0xb890, 0x9005, 0x0560, 0x2001, 0x0006, 0x080c, 0x65e3, 0x0096,
-	0x6014, 0x904d, 0x01d0, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0039,
-	0x1140, 0x2001, 0x0000, 0x900e, 0x2011, 0x4000, 0x080c, 0xcf7a,
-	0x0060, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0029, 0x0130, 0xa807,
-	0x0000, 0xa867, 0x0103, 0xa833, 0x0200, 0x009e, 0x080c, 0x326f,
-	0x6020, 0x9086, 0x000a, 0x0140, 0x080c, 0xacb0, 0x0028, 0x080c,
-	0xb693, 0x9006, 0x080c, 0xb8ff, 0x001e, 0x002e, 0x00ee, 0x00be,
-	0x0005, 0x2011, 0x1824, 0x2204, 0x9086, 0x0014, 0x1160, 0x2001,
-	0x0002, 0x080c, 0x65e3, 0x6003, 0x0001, 0x6007, 0x0001, 0x080c,
-	0x92b7, 0x0804, 0x9738, 0x2001, 0x0001, 0x0804, 0xb8ff, 0x2030,
-	0x2011, 0x1824, 0x2204, 0x9086, 0x0004, 0x1148, 0x96b6, 0x000b,
-	0x1120, 0x2001, 0x0007, 0x080c, 0x65e3, 0x0804, 0xacb0, 0x2001,
-	0x0001, 0x0804, 0xb8ff, 0x0002, 0xb77c, 0xb9d3, 0xb77c, 0xba14,
-	0xb77c, 0xbac1, 0xb9c8, 0xb77c, 0xb77c, 0xbad5, 0xb77c, 0xbae7,
-	0x6604, 0x9686, 0x0003, 0x0904, 0xb92f, 0x96b6, 0x001e, 0x1110,
-	0x080c, 0xacb0, 0x0005, 0x00b6, 0x00d6, 0x00c6, 0x080c, 0xbaf9,
-	0x11a0, 0x9006, 0x080c, 0x65cf, 0x080c, 0x3240, 0x080c, 0xd0b0,
-	0x2001, 0x0002, 0x080c, 0x65e3, 0x6003, 0x0001, 0x6007, 0x0002,
-	0x080c, 0x92b7, 0x080c, 0x9738, 0x0418, 0x2009, 0x026e, 0x2104,
-	0x9086, 0x0009, 0x1160, 0x6010, 0x2058, 0xb840, 0x9084, 0x00ff,
-	0x9005, 0x0170, 0x8001, 0xb842, 0x601b, 0x000a, 0x0088, 0x2009,
-	0x026f, 0x2104, 0x9084, 0xff00, 0x9086, 0x1900, 0x1108, 0x08a0,
-	0x080c, 0x3240, 0x080c, 0xd0b0, 0x2001, 0x0001, 0x080c, 0xb8ff,
-	0x00ce, 0x00de, 0x00be, 0x0005, 0x0096, 0x00b6, 0x0026, 0x9016,
-	0x080c, 0xbb07, 0x00d6, 0x2069, 0x197b, 0x2d04, 0x9005, 0x0168,
-	0x6010, 0x2058, 0xb8a0, 0x9086, 0x007e, 0x1138, 0x2069, 0x1820,
-	0x2d04, 0x8000, 0x206a, 0x00de, 0x0010, 0x00de, 0x0088, 0x9006,
-	0x080c, 0x65cf, 0x2001, 0x0002, 0x080c, 0x65e3, 0x6003, 0x0001,
-	0x6007, 0x0002, 0x080c, 0x92b7, 0x080c, 0x9738, 0x0804, 0xba91,
-	0x080c, 0xc97a, 0x01b0, 0x6014, 0x2048, 0xa864, 0x2010, 0x9086,
-	0x0139, 0x1138, 0x6007, 0x0016, 0x2001, 0x0002, 0x080c, 0xcfd4,
-	0x00b0, 0x6014, 0x2048, 0xa864, 0xd0fc, 0x0118, 0x2001, 0x0001,
-	0x0ca8, 0x2001, 0x180e, 0x2004, 0xd0dc, 0x0148, 0x6010, 0x2058,
-	0xb840, 0x9084, 0x00ff, 0x9005, 0x1110, 0x9006, 0x0c38, 0x080c,
-	0xb693, 0x2009, 0x026e, 0x2134, 0x96b4, 0x00ff, 0x9686, 0x0005,
-	0x0520, 0x9686, 0x000b, 0x01c8, 0x2009, 0x026f, 0x2104, 0x9084,
-	0xff00, 0x1118, 0x9686, 0x0009, 0x01c0, 0x9086, 0x1900, 0x1168,
-	0x9686, 0x0009, 0x0190, 0x2001, 0x0004, 0x080c, 0x65e3, 0x2001,
-	0x0028, 0x601a, 0x6007, 0x0052, 0x0020, 0x2001, 0x0001, 0x080c,
-	0xb8ff, 0x002e, 0x00be, 0x009e, 0x0005, 0x9286, 0x0139, 0x0160,
-	0x6014, 0x2048, 0x080c, 0xc97a, 0x0140, 0xa864, 0x9086, 0x0139,
-	0x0118, 0xa868, 0xd0fc, 0x0108, 0x0c40, 0x6010, 0x2058, 0xb840,
-	0x9084, 0x00ff, 0x9005, 0x0138, 0x8001, 0xb842, 0x601b, 0x000a,
-	0x6007, 0x0016, 0x08f0, 0xb8a0, 0x9086, 0x007e, 0x1138, 0x00e6,
-	0x2071, 0x1800, 0x080c, 0x6025, 0x00ee, 0x0010, 0x080c, 0x3240,
-	0x0860, 0x080c, 0xbb07, 0x1160, 0x2001, 0x0004, 0x080c, 0x65e3,
-	0x6003, 0x0001, 0x6007, 0x0003, 0x080c, 0x92b7, 0x0804, 0x9738,
-	0x080c, 0xb693, 0x9006, 0x0804, 0xb8ff, 0x0489, 0x1160, 0x2001,
-	0x0008, 0x080c, 0x65e3, 0x6003, 0x0001, 0x6007, 0x0005, 0x080c,
-	0x92b7, 0x0804, 0x9738, 0x2001, 0x0001, 0x0804, 0xb8ff, 0x00f9,
-	0x1160, 0x2001, 0x000a, 0x080c, 0x65e3, 0x6003, 0x0001, 0x6007,
-	0x0001, 0x080c, 0x92b7, 0x0804, 0x9738, 0x2001, 0x0001, 0x0804,
-	0xb8ff, 0x2009, 0x026e, 0x2104, 0x9086, 0x0003, 0x1138, 0x2009,
-	0x026f, 0x2104, 0x9084, 0xff00, 0x9086, 0x2a00, 0x0005, 0x9085,
-	0x0001, 0x0005, 0x00b6, 0x00c6, 0x0016, 0x6110, 0x2158, 0x080c,
-	0x66a2, 0x001e, 0x00ce, 0x00be, 0x0005, 0x00b6, 0x00f6, 0x00e6,
-	0x00d6, 0x0036, 0x0016, 0x6010, 0x2058, 0x2009, 0x1837, 0x2104,
-	0x9085, 0x0003, 0x200a, 0x080c, 0xbbad, 0x0560, 0x2009, 0x1837,
-	0x2104, 0xc0cd, 0x200a, 0x080c, 0x6ad9, 0x0158, 0x9006, 0x2020,
-	0x2009, 0x002a, 0x080c, 0xe445, 0x2001, 0x180c, 0x200c, 0xc195,
-	0x2102, 0x2019, 0x002a, 0x2009, 0x0001, 0x080c, 0x3205, 0x00e6,
-	0x2071, 0x1800, 0x080c, 0x3011, 0x00ee, 0x00c6, 0x0156, 0x20a9,
-	0x0781, 0x2009, 0x007f, 0x080c, 0x3349, 0x8108, 0x1f04, 0xbb4b,
-	0x015e, 0x00ce, 0x080c, 0xbb0a, 0x2071, 0x0260, 0x2079, 0x0200,
-	0x7817, 0x0001, 0x2001, 0x1837, 0x200c, 0xc1c5, 0x7018, 0xd0fc,
-	0x0110, 0xd0dc, 0x0118, 0x7038, 0xd0dc, 0x1108, 0xc1c4, 0x7817,
-	0x0000, 0x2001, 0x1837, 0x2102, 0x2079, 0x0100, 0x2e04, 0x9084,
-	0x00ff, 0x2069, 0x181f, 0x206a, 0x78e6, 0x0006, 0x8e70, 0x2e04,
-	0x2069, 0x1820, 0x206a, 0x78ea, 0x7832, 0x7836, 0x2010, 0x9084,
-	0xff00, 0x001e, 0x9105, 0x2009, 0x182c, 0x200a, 0x2200, 0x9084,
-	0x00ff, 0x2008, 0x080c, 0x26aa, 0x080c, 0x753d, 0x0170, 0x2071,
-	0x0260, 0x2069, 0x1981, 0x7048, 0x206a, 0x704c, 0x6806, 0x7050,
-	0x680a, 0x7054, 0x680e, 0x080c, 0xcda7, 0x0040, 0x2001, 0x0006,
-	0x080c, 0x65e3, 0x080c, 0x326f, 0x080c, 0xacb0, 0x001e, 0x003e,
-	0x00de, 0x00ee, 0x00fe, 0x00be, 0x0005, 0x0096, 0x0026, 0x0036,
-	0x00e6, 0x0156, 0x2019, 0x182c, 0x231c, 0x83ff, 0x01f0, 0x2071,
-	0x0260, 0x7200, 0x9294, 0x00ff, 0x7004, 0x9084, 0xff00, 0x9205,
-	0x9306, 0x1198, 0x2011, 0x0276, 0x20a9, 0x0004, 0x2b48, 0x2019,
-	0x000a, 0x080c, 0xbca2, 0x1148, 0x2011, 0x027a, 0x20a9, 0x0004,
-	0x2019, 0x0006, 0x080c, 0xbca2, 0x1100, 0x015e, 0x00ee, 0x003e,
-	0x002e, 0x009e, 0x0005, 0x00e6, 0x2071, 0x0260, 0x7034, 0x9086,
-	0x0014, 0x11a8, 0x7038, 0x9086, 0x0800, 0x1188, 0x703c, 0xd0ec,
-	0x0160, 0x9084, 0x0f00, 0x9086, 0x0100, 0x1138, 0x7054, 0xd0a4,
-	0x1110, 0xd0ac, 0x0110, 0x9006, 0x0010, 0x9085, 0x0001, 0x00ee,
-	0x0005, 0x00e6, 0x0096, 0x00c6, 0x0076, 0x0056, 0x0046, 0x0026,
-	0x0006, 0x0126, 0x2091, 0x8000, 0x2029, 0x19f2, 0x252c, 0x2021,
-	0x19f9, 0x2424, 0x2061, 0x1ddc, 0x2071, 0x1800, 0x7254, 0x7074,
-	0x9202, 0x1a04, 0xbc6e, 0x080c, 0x8c1f, 0x0904, 0xbc67, 0x080c,
-	0xe476, 0x0904, 0xbc67, 0x6720, 0x9786, 0x0007, 0x0904, 0xbc67,
-	0x2500, 0x9c06, 0x0904, 0xbc67, 0x2400, 0x9c06, 0x0904, 0xbc67,
-	0x3e08, 0x9186, 0x0002, 0x1148, 0x6010, 0x9005, 0x0130, 0x00b6,
-	0x2058, 0xb800, 0x00be, 0xd0bc, 0x1590, 0x00c6, 0x6043, 0xffff,
-	0x6000, 0x9086, 0x0004, 0x1110, 0x080c, 0x1ac5, 0x9786, 0x000a,
-	0x0148, 0x080c, 0xcb91, 0x1130, 0x00ce, 0x080c, 0xb693, 0x080c,
-	0xaceb, 0x00e8, 0x6014, 0x2048, 0x080c, 0xc97a, 0x01a8, 0x9786,
-	0x0003, 0x1530, 0xa867, 0x0103, 0xa87c, 0xd0cc, 0x0130, 0x0096,
-	0xa878, 0x2048, 0x080c, 0x0ff9, 0x009e, 0xab7a, 0xa877, 0x0000,
-	0x080c, 0x6de2, 0x080c, 0xcb6b, 0x080c, 0xaceb, 0x00ce, 0x9ce0,
-	0x001c, 0x7068, 0x9c02, 0x1210, 0x0804, 0xbc0e, 0x012e, 0x000e,
-	0x002e, 0x004e, 0x005e, 0x007e, 0x00ce, 0x009e, 0x00ee, 0x0005,
-	0x9786, 0x0006, 0x1118, 0x080c, 0xe3e8, 0x0c30, 0x9786, 0x0009,
-	0x1148, 0x6000, 0x9086, 0x0004, 0x0d08, 0x2009, 0x004c, 0x080c,
-	0xad4d, 0x08e0, 0x9786, 0x000a, 0x0980, 0x0820, 0x220c, 0x2304,
-	0x9106, 0x1130, 0x8210, 0x8318, 0x1f04, 0xbc8e, 0x9006, 0x0005,
-	0x2304, 0x9102, 0x0218, 0x2001, 0x0001, 0x0008, 0x9006, 0x918d,
-	0x0001, 0x0005, 0x0136, 0x01c6, 0x0016, 0x8906, 0x8006, 0x8007,
-	0x908c, 0x003f, 0x21e0, 0x9084, 0xffc0, 0x9300, 0x2098, 0x3518,
-	0x20a9, 0x0001, 0x220c, 0x4002, 0x910e, 0x1140, 0x8210, 0x8319,
-	0x1dc8, 0x9006, 0x001e, 0x01ce, 0x013e, 0x0005, 0x220c, 0x9102,
-	0x0218, 0x2001, 0x0001, 0x0010, 0x2001, 0x0000, 0x918d, 0x0001,
-	0x001e, 0x01ce, 0x013e, 0x0005, 0x220c, 0x810f, 0x2304, 0x9106,
-	0x1130, 0x8210, 0x8318, 0x1f04, 0xbccc, 0x9006, 0x0005, 0x918d,
-	0x0001, 0x0005, 0x6004, 0x908a, 0x0053, 0x1a0c, 0x0d7d, 0x080c,
-	0xcb80, 0x0120, 0x080c, 0xcb91, 0x0158, 0x0028, 0x080c, 0x326f,
-	0x080c, 0xcb91, 0x0128, 0x080c, 0x967a, 0x080c, 0xacb0, 0x0005,
-	0x080c, 0xb693, 0x0cc0, 0x9182, 0x0057, 0x1220, 0x9182, 0x0040,
-	0x0208, 0x000a, 0x0005, 0xbd12, 0xbd12, 0xbd12, 0xbd12, 0xbd12,
-	0xbd12, 0xbd12, 0xbd12, 0xbd12, 0xbd12, 0xbd12, 0xbd14, 0xbd14,
-	0xbd14, 0xbd14, 0xbd12, 0xbd12, 0xbd12, 0xbd14, 0xbd12, 0xbd12,
-	0xbd12, 0xbd12, 0x080c, 0x0d7d, 0x600b, 0xffff, 0x6003, 0x000f,
-	0x6106, 0x0126, 0x2091, 0x8000, 0x080c, 0xd0b3, 0x2009, 0x8000,
-	0x080c, 0x92b0, 0x012e, 0x0005, 0x9186, 0x0013, 0x1128, 0x6004,
-	0x9082, 0x0040, 0x0804, 0xbd9c, 0x9186, 0x0027, 0x1520, 0x080c,
-	0x967a, 0x080c, 0x3240, 0x080c, 0xd0b0, 0x0096, 0x6114, 0x2148,
-	0x080c, 0xc97a, 0x0198, 0x080c, 0xcb91, 0x1118, 0x080c, 0xb693,
-	0x0068, 0xa867, 0x0103, 0xa87b, 0x0029, 0xa877, 0x0000, 0xa97c,
-	0xc1c5, 0xa97e, 0x080c, 0x6dee, 0x080c, 0xcb6b, 0x009e, 0x080c,
-	0xacb0, 0x0804, 0x9738, 0x9186, 0x0014, 0x1120, 0x6004, 0x9082,
-	0x0040, 0x0030, 0x9186, 0x0053, 0x0110, 0x080c, 0x0d7d, 0x0005,
-	0x0002, 0xbd7a, 0xbd78, 0xbd78, 0xbd78, 0xbd78, 0xbd78, 0xbd78,
-	0xbd78, 0xbd78, 0xbd78, 0xbd78, 0xbd93, 0xbd93, 0xbd93, 0xbd93,
-	0xbd78, 0xbd93, 0xbd78, 0xbd93, 0xbd78, 0xbd78, 0xbd78, 0xbd78,
-	0x080c, 0x0d7d, 0x080c, 0x967a, 0x0096, 0x6114, 0x2148, 0x080c,
-	0xc97a, 0x0168, 0xa867, 0x0103, 0xa87b, 0x0006, 0xa877, 0x0000,
-	0xa880, 0xc0ec, 0xa882, 0x080c, 0x6dee, 0x080c, 0xcb6b, 0x009e,
-	0x080c, 0xacb0, 0x0005, 0x080c, 0x967a, 0x080c, 0xcb91, 0x090c,
-	0xb693, 0x080c, 0xacb0, 0x0005, 0x0002, 0xbdb6, 0xbdb4, 0xbdb4,
-	0xbdb4, 0xbdb4, 0xbdb4, 0xbdb4, 0xbdb4, 0xbdb4, 0xbdb4, 0xbdb4,
-	0xbdb8, 0xbdb8, 0xbdb8, 0xbdb8, 0xbdb4, 0xbdba, 0xbdb4, 0xbdb8,
-	0xbdb4, 0xbdb4, 0xbdb4, 0xbdb4, 0x080c, 0x0d7d, 0x080c, 0x0d7d,
-	0x080c, 0x0d7d, 0x080c, 0xacb0, 0x0804, 0x9738, 0x9182, 0x0057,
-	0x1220, 0x9182, 0x0040, 0x0208, 0x000a, 0x0005, 0xbddd, 0xbddd,
-	0xbddd, 0xbddd, 0xbddd, 0xbe16, 0xbf05, 0xbddd, 0xbf11, 0xbddd,
-	0xbddd, 0xbddd, 0xbddd, 0xbddd, 0xbddd, 0xbddd, 0xbddd, 0xbddd,
-	0xbddd, 0xbf11, 0xbddf, 0xbddd, 0xbf0f, 0x080c, 0x0d7d, 0x00b6,
-	0x0096, 0x6114, 0x2148, 0x6010, 0x2058, 0xb800, 0xd0bc, 0x1508,
-	0xa87b, 0x0000, 0xa867, 0x0103, 0xa877, 0x0000, 0xa87c, 0xd0ac,
-	0x0128, 0xa834, 0xa938, 0x9115, 0x190c, 0xbf96, 0x080c, 0x6c04,
-	0x6210, 0x2258, 0xba3c, 0x82ff, 0x0110, 0x8211, 0xba3e, 0xb8d0,
-	0x9005, 0x0110, 0x080c, 0x67be, 0x080c, 0xacb0, 0x009e, 0x00be,
-	0x0005, 0xa87c, 0xd0ac, 0x09e0, 0xa838, 0xa934, 0x9105, 0x09c0,
-	0xa880, 0xd0bc, 0x19a8, 0x080c, 0xccc6, 0x0c80, 0x00b6, 0x0096,
-	0x6114, 0x2148, 0x601c, 0xd0fc, 0x1110, 0x7644, 0x0008, 0x9036,
-	0x96b4, 0x0fff, 0x86ff, 0x1590, 0x6010, 0x2058, 0xb800, 0xd0bc,
-	0x1904, 0xbef4, 0xa87b, 0x0000, 0xa867, 0x0103, 0xae76, 0xa87c,
-	0xd0ac, 0x0128, 0xa834, 0xa938, 0x9115, 0x190c, 0xbf96, 0x080c,
-	0x6c04, 0x6210, 0x2258, 0xba3c, 0x82ff, 0x0110, 0x8211, 0xba3e,
-	0xb8d0, 0x9005, 0x0110, 0x080c, 0x67be, 0x601c, 0xd0fc, 0x1148,
-	0x7044, 0xd0e4, 0x1904, 0xbed8, 0x080c, 0xacb0, 0x009e, 0x00be,
-	0x0005, 0x2009, 0x0211, 0x210c, 0x080c, 0x0d7d, 0x968c, 0x0c00,
-	0x0150, 0x6010, 0x2058, 0xb800, 0xd0bc, 0x1904, 0xbedc, 0x7348,
-	0xab92, 0x734c, 0xab8e, 0x968c, 0x00ff, 0x9186, 0x0002, 0x0508,
-	0x9186, 0x0028, 0x1118, 0xa87b, 0x001c, 0x00e8, 0xd6dc, 0x01a0,
-	0xa87b, 0x0015, 0xa87c, 0xd0ac, 0x0170, 0xa938, 0xaa34, 0x2100,
-	0x9205, 0x0148, 0x7048, 0x9106, 0x1118, 0x704c, 0x9206, 0x0118,
-	0xa992, 0xaa8e, 0xc6dc, 0x0038, 0xd6d4, 0x0118, 0xa87b, 0x0007,
-	0x0010, 0xa87b, 0x0000, 0xa867, 0x0103, 0xae76, 0x901e, 0xd6c4,
-	0x01d8, 0x9686, 0x0100, 0x1130, 0x7064, 0x9005, 0x1118, 0xc6c4,
-	0x0804, 0xbe22, 0x735c, 0xab86, 0x83ff, 0x0170, 0x938a, 0x0009,
-	0x0210, 0x2019, 0x0008, 0x0036, 0x2308, 0x2019, 0x0018, 0x2011,
-	0x0025, 0x080c, 0xc4f8, 0x003e, 0xd6cc, 0x0904, 0xbe37, 0x7154,
-	0xa98a, 0x81ff, 0x0904, 0xbe37, 0x9192, 0x0021, 0x1278, 0x8304,
-	0x9098, 0x0018, 0x2011, 0x0029, 0x080c, 0xc4f8, 0x2011, 0x0205,
-	0x2013, 0x0000, 0x080c, 0xd040, 0x0804, 0xbe37, 0xa868, 0xd0fc,
-	0x0120, 0x2009, 0x0020, 0xa98a, 0x0c50, 0x00a6, 0x2950, 0x080c,
-	0xc497, 0x00ae, 0x080c, 0xd040, 0x080c, 0xc4e8, 0x0804, 0xbe39,
-	0x080c, 0xcc89, 0x0804, 0xbe4e, 0xa87c, 0xd0ac, 0x0904, 0xbe5f,
-	0xa880, 0xd0bc, 0x1904, 0xbe5f, 0x7348, 0xa838, 0x9306, 0x11c8,
-	0x734c, 0xa834, 0x931e, 0x0904, 0xbe5f, 0xd6d4, 0x0190, 0xab38,
-	0x9305, 0x0904, 0xbe5f, 0x0068, 0xa87c, 0xd0ac, 0x0904, 0xbe2a,
-	0xa838, 0xa934, 0x9105, 0x0904, 0xbe2a, 0xa880, 0xd0bc, 0x1904,
-	0xbe2a, 0x080c, 0xccc6, 0x0804, 0xbe4e, 0x00f6, 0x2079, 0x026c,
-	0x7c04, 0x7b00, 0x7e0c, 0x7d08, 0x00fe, 0x0021, 0x0005, 0x0011,
-	0x0005, 0x0005, 0x0096, 0x6003, 0x0002, 0x6007, 0x0043, 0x6014,
-	0x2048, 0xa87c, 0xd0ac, 0x0128, 0x009e, 0x0005, 0x2130, 0x2228,
-	0x0058, 0x2400, 0xa9ac, 0x910a, 0x2300, 0xaab0, 0x9213, 0x2600,
-	0x9102, 0x2500, 0x9203, 0x0e90, 0xac46, 0xab4a, 0xae36, 0xad3a,
-	0x6044, 0xd0fc, 0x190c, 0xa947, 0x604b, 0x0000, 0x080c, 0x1c86,
-	0x1118, 0x6144, 0x080c, 0x92dc, 0x009e, 0x0005, 0x9182, 0x0057,
-	0x1220, 0x9182, 0x0040, 0x0208, 0x000a, 0x0005, 0xbf5d, 0xbf5d,
-	0xbf5d, 0xbf5d, 0xbf5d, 0xbf5d, 0xbf5d, 0xbf5d, 0xbf5d, 0xbf5d,
-	0xbf5f, 0xbf5d, 0xbf5d, 0xbf5d, 0xbf5d, 0xbf70, 0xbf5d, 0xbf5d,
-	0xbf5d, 0xbf5d, 0xbf94, 0xbf5d, 0xbf5d, 0x080c, 0x0d7d, 0x6004,
-	0x9086, 0x0040, 0x1110, 0x080c, 0x967a, 0x2019, 0x0001, 0x080c,
-	0xa1b8, 0x6003, 0x0002, 0x080c, 0xd0b8, 0x080c, 0x96d5, 0x0005,
-	0x6004, 0x9086, 0x0040, 0x1110, 0x080c, 0x967a, 0x2019, 0x0001,
-	0x080c, 0xa1b8, 0x080c, 0x96d5, 0x080c, 0x3240, 0x080c, 0xd0b0,
-	0x0096, 0x6114, 0x2148, 0x080c, 0xc97a, 0x0150, 0xa867, 0x0103,
-	0xa87b, 0x0029, 0xa877, 0x0000, 0x080c, 0x6dee, 0x080c, 0xcb6b,
-	0x009e, 0x080c, 0xacb0, 0x0005, 0x080c, 0x0d7d, 0xa87b, 0x0015,
-	0xd1fc, 0x0180, 0xa87b, 0x0007, 0x8002, 0x8000, 0x810a, 0x9189,
-	0x0000, 0x0006, 0x0016, 0x2009, 0x1a77, 0x2104, 0x8000, 0x200a,
-	0x001e, 0x000e, 0xa992, 0xa88e, 0x0005, 0x9182, 0x0057, 0x1220,
-	0x9182, 0x0040, 0x0208, 0x000a, 0x0005, 0xbfcc, 0xbfcc, 0xbfcc,
-	0xbfcc, 0xbfcc, 0xbfce, 0xbfcc, 0xbfcc, 0xc08b, 0xbfcc, 0xbfcc,
-	0xbfcc, 0xbfcc, 0xbfcc, 0xbfcc, 0xbfcc, 0xbfcc, 0xbfcc, 0xbfcc,
-	0xc1cb, 0xbfcc, 0xc1d5, 0xbfcc, 0x080c, 0x0d7d, 0x601c, 0xd0bc,
-	0x0178, 0xd084, 0x0168, 0xd0f4, 0x0120, 0xc084, 0x601e, 0x0804,
-	0xbdbe, 0x6114, 0x0096, 0x2148, 0xa87c, 0xc0e5, 0xa87e, 0x009e,
-	0x0076, 0x00a6, 0x00e6, 0x0096, 0x2071, 0x0260, 0x6114, 0x2150,
-	0x601c, 0xd0fc, 0x1110, 0x7644, 0x0008, 0x9036, 0xb676, 0x96b4,
-	0x0fff, 0xb77c, 0xc7e5, 0xb77e, 0x6210, 0x00b6, 0x2258, 0xba3c,
-	0x82ff, 0x0110, 0x8211, 0xba3e, 0x00be, 0x86ff, 0x0904, 0xc084,
-	0x9694, 0xff00, 0x9284, 0x0c00, 0x0120, 0x7048, 0xb092, 0x704c,
-	0xb08e, 0x9284, 0x0300, 0x0904, 0xc084, 0x9686, 0x0100, 0x1130,
-	0x7064, 0x9005, 0x1118, 0xc6c4, 0xb676, 0x0c38, 0x080c, 0x1047,
-	0x090c, 0x0d7d, 0x2900, 0xb07a, 0xb77c, 0x97bd, 0x0200, 0xb77e,
-	0xa867, 0x0103, 0xb068, 0xa86a, 0xb06c, 0xa86e, 0xb070, 0xa872,
-	0x7044, 0x9084, 0xf000, 0x9635, 0xae76, 0x968c, 0x0c00, 0x0120,
-	0x7348, 0xab92, 0x734c, 0xab8e, 0x968c, 0x00ff, 0x9186, 0x0002,
-	0x0180, 0x9186, 0x0028, 0x1118, 0xa87b, 0x001c, 0x0060, 0xd6dc,
-	0x0118, 0xa87b, 0x0015, 0x0038, 0xd6d4, 0x0118, 0xa87b, 0x0007,
-	0x0010, 0xa87b, 0x0000, 0xaf7e, 0xb080, 0xa882, 0xb084, 0xa886,
-	0x901e, 0xd6c4, 0x0190, 0x735c, 0xab86, 0x83ff, 0x0170, 0x938a,
-	0x0009, 0x0210, 0x2019, 0x0008, 0x0036, 0x2308, 0x2019, 0x0018,
-	0x2011, 0x0025, 0x080c, 0xc4f8, 0x003e, 0xd6cc, 0x01e8, 0x7154,
-	0xa98a, 0x81ff, 0x01c8, 0x9192, 0x0021, 0x1260, 0x8304, 0x9098,
-	0x0018, 0x2011, 0x0029, 0x080c, 0xc4f8, 0x2011, 0x0205, 0x2013,
-	0x0000, 0x0050, 0xb068, 0xd0fc, 0x0120, 0x2009, 0x0020, 0xa98a,
-	0x0c68, 0x2950, 0x080c, 0xc497, 0x080c, 0x1a93, 0x009e, 0x00ee,
-	0x00ae, 0x007e, 0x0005, 0x2001, 0x1987, 0x2004, 0x604a, 0x0096,
-	0x6114, 0x2148, 0xa83c, 0xa940, 0x9105, 0x1118, 0xa87c, 0xc0dc,
-	0xa87e, 0x6003, 0x0002, 0x080c, 0xd0c1, 0x0904, 0xc1c6, 0x604b,
-	0x0000, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x1500,
-	0xd1cc, 0x0904, 0xc18a, 0xa978, 0xa868, 0xd0fc, 0x0904, 0xc14b,
-	0x0016, 0xa87c, 0x0006, 0xa880, 0x0006, 0x00a6, 0x2150, 0xb174,
-	0x9184, 0x00ff, 0x90b6, 0x0002, 0x0904, 0xc118, 0x9086, 0x0028,
-	0x1904, 0xc104, 0xa87b, 0x001c, 0xb07b, 0x001c, 0x0804, 0xc120,
-	0x6024, 0xd0f4, 0x11d0, 0xa838, 0xaa34, 0x9205, 0x09c8, 0xa838,
-	0xaa90, 0x9206, 0x1120, 0xa88c, 0xaa34, 0x9206, 0x0988, 0x6024,
-	0xd0d4, 0x1148, 0xa9ac, 0xa834, 0x9102, 0x603a, 0xa9b0, 0xa838,
-	0x9103, 0x603e, 0x6024, 0xc0f5, 0x6026, 0x6010, 0x00b6, 0x2058,
-	0xb83c, 0x8000, 0xb83e, 0x00be, 0x601c, 0xc0fc, 0x601e, 0x9006,
-	0xa876, 0xa892, 0xa88e, 0xa87c, 0xc0e4, 0xa87e, 0xd0cc, 0x0140,
-	0xc0cc, 0xa87e, 0x0096, 0xa878, 0x2048, 0x080c, 0x0ff9, 0x009e,
-	0x080c, 0xccc6, 0x0804, 0xc1c6, 0xd1dc, 0x0158, 0xa87b, 0x0015,
-	0xb07b, 0x0015, 0x080c, 0xcf63, 0x0118, 0xb174, 0xc1dc, 0xb176,
-	0x0078, 0xd1d4, 0x0128, 0xa87b, 0x0007, 0xb07b, 0x0007, 0x0040,
-	0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938, 0x9115, 0x190c, 0xbf96,
-	0xa87c, 0xb07e, 0xa890, 0xb092, 0xa88c, 0xb08e, 0xa860, 0x20e8,
-	0xa85c, 0x9080, 0x0019, 0x20a0, 0x20a9, 0x0020, 0x8a06, 0x8006,
-	0x8007, 0x9094, 0x003f, 0x22e0, 0x9084, 0xffc0, 0x9080, 0x0019,
-	0x2098, 0x4003, 0x00ae, 0x000e, 0xa882, 0x000e, 0xc0cc, 0xa87e,
-	0x080c, 0xd040, 0x001e, 0xa874, 0x0006, 0x2148, 0x080c, 0x0ff9,
-	0x001e, 0x0804, 0xc1b7, 0x0016, 0x00a6, 0x2150, 0xb174, 0x9184,
-	0x00ff, 0x90b6, 0x0002, 0x01e0, 0x9086, 0x0028, 0x1128, 0xa87b,
-	0x001c, 0xb07b, 0x001c, 0x00e0, 0xd1dc, 0x0158, 0xa87b, 0x0015,
-	0xb07b, 0x0015, 0x080c, 0xcf63, 0x0118, 0xb174, 0xc1dc, 0xb176,
-	0x0078, 0xd1d4, 0x0128, 0xa87b, 0x0007, 0xb07b, 0x0007, 0x0040,
-	0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938, 0x9115, 0x190c, 0xbf96,
-	0xa890, 0xb092, 0xa88c, 0xb08e, 0xa87c, 0xb07e, 0x00ae, 0x080c,
-	0x0ff9, 0x009e, 0x080c, 0xd040, 0xa974, 0x0016, 0x080c, 0xc4e8,
-	0x001e, 0x0468, 0xa867, 0x0103, 0xa974, 0x9184, 0x00ff, 0x90b6,
-	0x0002, 0x01b0, 0x9086, 0x0028, 0x1118, 0xa87b, 0x001c, 0x00d0,
-	0xd1dc, 0x0148, 0xa87b, 0x0015, 0x080c, 0xcf63, 0x0118, 0xa974,
-	0xc1dc, 0xa976, 0x0078, 0xd1d4, 0x0118, 0xa87b, 0x0007, 0x0050,
-	0xa87b, 0x0000, 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938, 0x9115,
-	0x190c, 0xbf96, 0xa974, 0x0016, 0x080c, 0x6c04, 0x001e, 0x6010,
-	0x00b6, 0x2058, 0xba3c, 0xb8d0, 0x0016, 0x9005, 0x190c, 0x67be,
-	0x001e, 0x00be, 0xd1e4, 0x1120, 0x080c, 0xacb0, 0x009e, 0x0005,
-	0x080c, 0xcc89, 0x0cd8, 0x6114, 0x0096, 0x2148, 0xa97c, 0x080c,
-	0xd0c1, 0x190c, 0x1ab1, 0x009e, 0x0005, 0x0096, 0x6114, 0x2148,
-	0xa83c, 0xa940, 0x9105, 0x01e8, 0xa877, 0x0000, 0xa87b, 0x0000,
-	0xa867, 0x0103, 0x00b6, 0x6010, 0x2058, 0xa834, 0xa938, 0x9115,
-	0x11a0, 0x080c, 0x6c04, 0xba3c, 0x8211, 0x0208, 0xba3e, 0xb8d0,
-	0x9005, 0x0110, 0x080c, 0x67be, 0x080c, 0xacb0, 0x00be, 0x009e,
-	0x0005, 0xa87c, 0xc0dc, 0xa87e, 0x08f8, 0xb800, 0xd0bc, 0x1120,
-	0xa834, 0x080c, 0xbf96, 0x0c28, 0xa880, 0xd0bc, 0x1dc8, 0x080c,
-	0xccc6, 0x0c60, 0x080c, 0x967a, 0x0010, 0x080c, 0x96d5, 0x601c,
-	0xd084, 0x0110, 0x080c, 0x1ac5, 0x080c, 0xc97a, 0x01f0, 0x0096,
-	0x6114, 0x2148, 0x080c, 0xcb91, 0x1118, 0x080c, 0xb693, 0x00a0,
-	0xa867, 0x0103, 0x2009, 0x180c, 0x210c, 0xd18c, 0x1198, 0xd184,
-	0x1170, 0x6108, 0xa97a, 0x918e, 0x0029, 0x1110, 0x080c, 0xe79d,
-	0xa877, 0x0000, 0x080c, 0x6dee, 0x009e, 0x0804, 0xaceb, 0xa87b,
-	0x0004, 0x0cb0, 0xa87b, 0x0004, 0x0c98, 0x9182, 0x0057, 0x1220,
-	0x9182, 0x0040, 0x0208, 0x000a, 0x0005, 0xc25c, 0xc25c, 0xc25c,
-	0xc25c, 0xc25c, 0xc25e, 0xc25c, 0xc25c, 0xc25c, 0xc25c, 0xc25c,
-	0xc25c, 0xc25c, 0xc25c, 0xc25c, 0xc25c, 0xc25c, 0xc25c, 0xc25c,
-	0xc25c, 0xc282, 0xc25c, 0xc25c, 0x080c, 0x0d7d, 0x080c, 0x5746,
-	0x01f8, 0x6014, 0x7144, 0x918c, 0x0fff, 0x9016, 0xd1c4, 0x0118,
-	0x7264, 0x9294, 0x00ff, 0x0096, 0x904d, 0x0188, 0xa87b, 0x0000,
-	0xa864, 0x9086, 0x0139, 0x0128, 0xa867, 0x0103, 0xa976, 0xaa96,
-	0x0030, 0xa897, 0x4000, 0xa99a, 0xaa9e, 0x080c, 0x6dee, 0x009e,
-	0x0804, 0xacb0, 0x080c, 0x5746, 0x0dd8, 0x6014, 0x900e, 0x9016,
-	0x0c10, 0x9182, 0x0085, 0x0002, 0xc29b, 0xc299, 0xc299, 0xc2a7,
-	0xc299, 0xc299, 0xc299, 0xc299, 0xc299, 0xc299, 0xc299, 0xc299,
-	0xc299, 0x080c, 0x0d7d, 0x6003, 0x0001, 0x6106, 0x0126, 0x2091,
-	0x8000, 0x2009, 0x8020, 0x080c, 0x92b0, 0x012e, 0x0005, 0x0026,
-	0x0056, 0x00d6, 0x00e6, 0x2071, 0x0260, 0x7224, 0x6216, 0x7220,
-	0x080c, 0xc968, 0x01f8, 0x2268, 0x6800, 0x9086, 0x0000, 0x01d0,
-	0x6010, 0x6d10, 0x952e, 0x11b0, 0x00c6, 0x2d60, 0x00d6, 0x080c,
-	0xc559, 0x00de, 0x00ce, 0x0158, 0x702c, 0xd084, 0x1118, 0x080c,
-	0xc523, 0x0010, 0x6803, 0x0002, 0x6007, 0x0086, 0x0028, 0x080c,
-	0xc545, 0x0d90, 0x6007, 0x0087, 0x6003, 0x0001, 0x2009, 0x8020,
-	0x080c, 0x92b0, 0x7220, 0x080c, 0xc968, 0x0178, 0x6810, 0x00b6,
-	0x2058, 0xb800, 0x00be, 0xd0bc, 0x0140, 0x6824, 0xd0ec, 0x0128,
-	0x00c6, 0x2d60, 0x080c, 0xccc6, 0x00ce, 0x00ee, 0x00de, 0x005e,
-	0x002e, 0x0005, 0x9186, 0x0013, 0x1160, 0x6004, 0x908a, 0x0085,
-	0x0a0c, 0x0d7d, 0x908a, 0x0092, 0x1a0c, 0x0d7d, 0x9082, 0x0085,
-	0x00e2, 0x9186, 0x0027, 0x0120, 0x9186, 0x0014, 0x190c, 0x0d7d,
-	0x080c, 0x967a, 0x0096, 0x6014, 0x2048, 0x080c, 0xc97a, 0x0140,
-	0xa867, 0x0103, 0xa877, 0x0000, 0xa87b, 0x0029, 0x080c, 0x6dee,
-	0x009e, 0x080c, 0xaceb, 0x0804, 0x9738, 0xc32a, 0xc32c, 0xc32c,
-	0xc32a, 0xc32a, 0xc32a, 0xc32a, 0xc32a, 0xc32a, 0xc32a, 0xc32a,
-	0xc32a, 0xc32a, 0x080c, 0x0d7d, 0x080c, 0xaceb, 0x0005, 0x9186,
-	0x0013, 0x1130, 0x6004, 0x9082, 0x0085, 0x2008, 0x0804, 0xc37b,
-	0x9186, 0x0027, 0x1558, 0x080c, 0x967a, 0x080c, 0x3240, 0x080c,
-	0xd0b0, 0x0096, 0x6014, 0x2048, 0x080c, 0xc97a, 0x0150, 0xa867,
-	0x0103, 0xa877, 0x0000, 0xa87b, 0x0029, 0x080c, 0x6dee, 0x080c,
-	0xcb6b, 0x009e, 0x080c, 0xacb0, 0x0005, 0x9186, 0x0089, 0x0118,
-	0x9186, 0x008a, 0x1140, 0x080c, 0xab33, 0x0128, 0x9086, 0x000c,
-	0x0904, 0xc3b3, 0x0000, 0x080c, 0xad6a, 0x0c70, 0x9186, 0x0014,
-	0x1d60, 0x080c, 0x967a, 0x0096, 0x6014, 0x2048, 0x080c, 0xc97a,
-	0x0d00, 0xa867, 0x0103, 0xa877, 0x0000, 0xa87b, 0x0006, 0xa880,
-	0xc0ec, 0xa882, 0x0890, 0x0002, 0xc38b, 0xc389, 0xc389, 0xc389,
-	0xc389, 0xc389, 0xc39f, 0xc389, 0xc389, 0xc389, 0xc389, 0xc389,
-	0xc389, 0x080c, 0x0d7d, 0x6034, 0x908c, 0xff00, 0x810f, 0x9186,
-	0x0039, 0x0118, 0x9186, 0x0035, 0x1118, 0x2001, 0x1985, 0x0010,
-	0x2001, 0x1986, 0x2004, 0x601a, 0x6003, 0x000c, 0x0005, 0x6034,
-	0x908c, 0xff00, 0x810f, 0x9186, 0x0039, 0x0118, 0x9186, 0x0035,
-	0x1118, 0x2001, 0x1985, 0x0010, 0x2001, 0x1986, 0x2004, 0x601a,
-	0x6003, 0x000e, 0x0005, 0x9182, 0x0092, 0x1220, 0x9182, 0x0085,
-	0x0208, 0x0012, 0x0804, 0xad6a, 0xc3c9, 0xc3c9, 0xc3c9, 0xc3c9,
-	0xc3cb, 0xc418, 0xc3c9, 0xc3c9, 0xc3c9, 0xc3c9, 0xc3c9, 0xc3c9,
-	0xc3c9, 0x080c, 0x0d7d, 0x0096, 0x6010, 0x00b6, 0x2058, 0xb800,
-	0x00be, 0xd0bc, 0x0168, 0x6034, 0x908c, 0xff00, 0x810f, 0x9186,
-	0x0039, 0x0118, 0x9186, 0x0035, 0x1118, 0x009e, 0x0804, 0xc42c,
-	0x080c, 0xc97a, 0x1118, 0x080c, 0xcb6b, 0x0068, 0x6014, 0x2048,
-	0x080c, 0xd0c7, 0x1110, 0x080c, 0xcb6b, 0xa867, 0x0103, 0x080c,
-	0xd07b, 0x080c, 0x6dee, 0x00d6, 0x2c68, 0x080c, 0xac5a, 0x01d0,
-	0x6003, 0x0001, 0x6007, 0x001e, 0x600b, 0xffff, 0x2009, 0x026e,
-	0x210c, 0x613a, 0x2009, 0x026f, 0x210c, 0x613e, 0x6910, 0x6112,
-	0x080c, 0xce15, 0x695c, 0x615e, 0x6023, 0x0001, 0x2009, 0x8020,
-	0x080c, 0x92b0, 0x2d60, 0x00de, 0x080c, 0xacb0, 0x009e, 0x0005,
-	0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x05a0, 0x6034,
-	0x908c, 0xff00, 0x810f, 0x9186, 0x0035, 0x0130, 0x9186, 0x001e,
-	0x0118, 0x9186, 0x0039, 0x1538, 0x00d6, 0x2c68, 0x080c, 0xd013,
-	0x11f0, 0x080c, 0xac5a, 0x01d8, 0x6106, 0x6003, 0x0001, 0x6023,
-	0x0001, 0x6910, 0x6112, 0x692c, 0x612e, 0x6930, 0x6132, 0x6934,
-	0x918c, 0x00ff, 0x6136, 0x6938, 0x613a, 0x693c, 0x613e, 0x695c,
-	0x615e, 0x080c, 0xce15, 0x2009, 0x8020, 0x080c, 0x92b0, 0x2d60,
-	0x00de, 0x0804, 0xacb0, 0x0096, 0x6014, 0x2048, 0x080c, 0xc97a,
-	0x01c8, 0xa867, 0x0103, 0xa880, 0xd0b4, 0x0128, 0xc0ec, 0xa882,
-	0xa87b, 0x0006, 0x0048, 0xd0bc, 0x0118, 0xa87b, 0x0002, 0x0020,
-	0xa87b, 0x0005, 0x080c, 0xcc85, 0xa877, 0x0000, 0x080c, 0x6dee,
-	0x080c, 0xcb6b, 0x009e, 0x0804, 0xacb0, 0x0016, 0x0096, 0x6014,
-	0x2048, 0x080c, 0xc97a, 0x0140, 0xa867, 0x0103, 0xa87b, 0x0028,
-	0xa877, 0x0000, 0x080c, 0x6dee, 0x009e, 0x001e, 0x9186, 0x0013,
-	0x0158, 0x9186, 0x0014, 0x0130, 0x9186, 0x0027, 0x0118, 0x080c,
-	0xad6a, 0x0020, 0x080c, 0x967a, 0x080c, 0xaceb, 0x0005, 0x0056,
-	0x0066, 0x0096, 0x00a6, 0x2029, 0x0001, 0x9182, 0x0101, 0x1208,
-	0x0010, 0x2009, 0x0100, 0x2130, 0x8304, 0x9098, 0x0018, 0x2009,
-	0x0020, 0x2011, 0x0029, 0x080c, 0xc4f8, 0x96b2, 0x0020, 0xb004,
-	0x904d, 0x0110, 0x080c, 0x0ff9, 0x080c, 0x1047, 0x0520, 0x8528,
+	0x705b, 0x1ddc, 0x0cc0, 0x9006, 0x0cc0, 0x00e6, 0x2071, 0x1800,
+	0x7554, 0x9582, 0x0010, 0x0600, 0x7058, 0x2060, 0x6000, 0x9086,
+	0x0000, 0x0148, 0x9ce0, 0x001c, 0x7068, 0x9c02, 0x1208, 0x0cb0,
+	0x2061, 0x1ddc, 0x0c98, 0x6003, 0x0008, 0x8529, 0x7556, 0x9ca8,
+	0x001c, 0x7068, 0x9502, 0x1228, 0x755a, 0x9085, 0x0001, 0x00ee,
+	0x0005, 0x705b, 0x1ddc, 0x0cc8, 0x9006, 0x0cc8, 0x9c82, 0x1ddc,
+	0x0a0c, 0x0d85, 0x2001, 0x181a, 0x2004, 0x9c02, 0x1a0c, 0x0d85,
+	0x9006, 0x6006, 0x600a, 0x600e, 0x6016, 0x601a, 0x6012, 0x6023,
+	0x0000, 0x6003, 0x0000, 0x601e, 0x605e, 0x6062, 0x6026, 0x602a,
+	0x602e, 0x6032, 0x6036, 0x603a, 0x603e, 0x604a, 0x602a, 0x6046,
+	0x6042, 0x2061, 0x1800, 0x6054, 0x8000, 0x6056, 0x0005, 0x9006,
+	0x600e, 0x6016, 0x601a, 0x6012, 0x6022, 0x6002, 0x601e, 0x605e,
+	0x6062, 0x604a, 0x6046, 0x2061, 0x1800, 0x6054, 0x8000, 0x6056,
+	0x0005, 0x0006, 0x6000, 0x9086, 0x0000, 0x01d8, 0x601c, 0xd084,
+	0x190c, 0x1afc, 0x6023, 0x0007, 0x2001, 0x1987, 0x2004, 0x0006,
+	0x9082, 0x0051, 0x000e, 0x0208, 0x8004, 0x601a, 0x080c, 0xe985,
+	0x604b, 0x0000, 0x6044, 0xd0fc, 0x1131, 0x9006, 0x6046, 0x6016,
+	0x6012, 0x000e, 0x0005, 0x080c, 0xaae0, 0x0106, 0x2001, 0x19fc,
+	0x2004, 0x9c06, 0x1130, 0x0036, 0x2019, 0x0001, 0x080c, 0xa380,
+	0x003e, 0x080c, 0xa585, 0x010e, 0x090c, 0xaafc, 0x0005, 0x00e6,
+	0x0126, 0x2071, 0x1800, 0x2091, 0x8000, 0x7554, 0x9582, 0x0001,
+	0x0608, 0x7058, 0x2060, 0x6000, 0x9086, 0x0000, 0x0148, 0x9ce0,
+	0x001c, 0x7068, 0x9c02, 0x1208, 0x0cb0, 0x2061, 0x1ddc, 0x0c98,
+	0x6003, 0x0008, 0x8529, 0x7556, 0x9ca8, 0x001c, 0x7068, 0x9502,
+	0x1230, 0x755a, 0x9085, 0x0001, 0x012e, 0x00ee, 0x0005, 0x705b,
+	0x1ddc, 0x0cc0, 0x9006, 0x0cc0, 0x6020, 0x9084, 0x000f, 0x0002,
+	0xafe0, 0xafea, 0xb005, 0xb020, 0xd391, 0xd3ae, 0xd3c9, 0xafe0,
+	0xafea, 0x9199, 0xb03c, 0xafe0, 0xafe0, 0xafe0, 0xafe0, 0xafe0,
+	0x9186, 0x0013, 0x1130, 0x6044, 0xd0fc, 0x0110, 0x080c, 0x97fe,
+	0x0005, 0x0005, 0x0066, 0x6000, 0x90b2, 0x0016, 0x1a0c, 0x0d85,
+	0x0013, 0x006e, 0x0005, 0xb003, 0xb77f, 0xb966, 0xb003, 0xb9fc,
+	0xb305, 0xb003, 0xb003, 0xb701, 0xbf76, 0xb003, 0xb003, 0xb003,
+	0xb003, 0xb003, 0xb003, 0x080c, 0x0d85, 0x0066, 0x6000, 0x90b2,
+	0x0016, 0x1a0c, 0x0d85, 0x0013, 0x006e, 0x0005, 0xb01e, 0xc58e,
+	0xb01e, 0xb01e, 0xb01e, 0xb01e, 0xb01e, 0xb01e, 0xc525, 0xc711,
+	0xb01e, 0xc5cb, 0xc64f, 0xc5cb, 0xc64f, 0xb01e, 0x080c, 0x0d85,
+	0x6000, 0x9082, 0x0016, 0x1a0c, 0x0d85, 0x6000, 0x0002, 0xb03a,
+	0xbfc0, 0xc05a, 0xc1da, 0xc249, 0xb03a, 0xb03a, 0xb03a, 0xbf8f,
+	0xc4a6, 0xc4a9, 0xb03a, 0xb03a, 0xb03a, 0xb03a, 0xc4d9, 0xb03a,
+	0xb03a, 0xb03a, 0x080c, 0x0d85, 0x0066, 0x6000, 0x90b2, 0x0016,
+	0x1a0c, 0x0d85, 0x0013, 0x006e, 0x0005, 0xb055, 0xb055, 0xb093,
+	0xb132, 0xb1b2, 0xb055, 0xb055, 0xb055, 0xb057, 0xb055, 0xb055,
+	0xb055, 0xb055, 0xb055, 0xb055, 0xb055, 0x080c, 0x0d85, 0x9186,
+	0x004c, 0x0560, 0x9186, 0x0003, 0x190c, 0x0d85, 0x0096, 0x601c,
+	0xc0ed, 0x601e, 0x6003, 0x0003, 0x6106, 0x6014, 0x2048, 0xa87c,
+	0x9084, 0xa000, 0xc0b5, 0xa87e, 0xa8ac, 0xa836, 0xa8b0, 0xa83a,
+	0x9006, 0xa846, 0xa84a, 0xa884, 0x9092, 0x199a, 0x0210, 0x2001,
+	0x1999, 0x8003, 0x8013, 0x8213, 0x9210, 0x621a, 0x009e, 0x080c,
+	0x1c47, 0x2009, 0x8030, 0x080c, 0x946f, 0x0005, 0x6010, 0x00b6,
+	0x2058, 0xbca0, 0x00be, 0x2c00, 0x080c, 0xb1d4, 0x080c, 0xd356,
+	0x6003, 0x0007, 0x0005, 0x00d6, 0x0096, 0x00f6, 0x2079, 0x1800,
+	0x7a90, 0x6014, 0x2048, 0xa87c, 0xd0ec, 0x1110, 0x9290, 0x0018,
+	0xac78, 0xc4fc, 0x0046, 0xa8e0, 0x9005, 0x1140, 0xa8dc, 0x921a,
+	0x0140, 0x0220, 0xa87b, 0x0007, 0x2010, 0x0028, 0xa87b, 0x0015,
+	0x0010, 0xa87b, 0x0000, 0x8214, 0xa883, 0x0000, 0xaa02, 0x0006,
+	0x0016, 0x0026, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2400, 0x9005,
+	0x1108, 0x009a, 0x2100, 0x9086, 0x0015, 0x1118, 0x2001, 0x0001,
+	0x0038, 0x2100, 0x9086, 0x0016, 0x0118, 0x2001, 0x0001, 0x002a,
+	0x94a4, 0x0007, 0x8423, 0x9405, 0x0002, 0xb0fa, 0xb0fa, 0xb0f5,
+	0xb0f8, 0xb0fa, 0xb0f2, 0xb0e5, 0xb0e5, 0xb0e5, 0xb0e5, 0xb0e5,
+	0xb0e5, 0xb0e5, 0xb0e5, 0xb0e5, 0xb0e5, 0x00fe, 0x00ee, 0x00de,
+	0x00ce, 0x002e, 0x001e, 0x000e, 0x004e, 0x00fe, 0x009e, 0x00de,
+	0x080c, 0x0d85, 0x080c, 0xbbc9, 0x0028, 0x080c, 0xbcb0, 0x0010,
+	0x080c, 0xbda6, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x002e, 0x001e,
+	0x2c00, 0xa896, 0x000e, 0x080c, 0xb292, 0x0530, 0xa804, 0xa80e,
+	0x00a6, 0x2050, 0xb100, 0x00ae, 0x8006, 0x8006, 0x8007, 0x90bc,
+	0x003f, 0x9084, 0xffc0, 0x9080, 0x0002, 0xaacc, 0xabd0, 0xacd4,
+	0xadd8, 0x2031, 0x0000, 0x2041, 0x12c2, 0x080c, 0xb456, 0x0160,
+	0x000e, 0x9005, 0x0120, 0x00fe, 0x009e, 0x00de, 0x0005, 0x00fe,
+	0x009e, 0x00de, 0x0804, 0xaf2e, 0x2001, 0x002c, 0x900e, 0x080c,
+	0xb2f8, 0x0c70, 0x91b6, 0x0015, 0x0170, 0x91b6, 0x0016, 0x0158,
+	0x91b2, 0x0047, 0x0a0c, 0x0d85, 0x91b2, 0x0050, 0x1a0c, 0x0d85,
+	0x9182, 0x0047, 0x0042, 0x080c, 0xad2d, 0x0120, 0x9086, 0x0002,
+	0x0904, 0xb093, 0x0005, 0xb154, 0xb154, 0xb156, 0xb188, 0xb154,
+	0xb154, 0xb154, 0xb154, 0xb19b, 0x080c, 0x0d85, 0x00d6, 0x0016,
+	0x0096, 0x6003, 0x0004, 0x6114, 0x2148, 0xa87c, 0xd0fc, 0x01c0,
+	0xa878, 0xc0fc, 0x9005, 0x1158, 0xa894, 0x9005, 0x0140, 0x2001,
+	0x0000, 0x900e, 0x080c, 0xb2f8, 0x080c, 0xaf2e, 0x00a8, 0x6003,
+	0x0002, 0xa8a4, 0xa9a8, 0x9105, 0x1178, 0xa8ae, 0xa8b2, 0x0c78,
+	0xa87f, 0x0020, 0xa88c, 0xa88a, 0xa8a4, 0xa8ae, 0xa8a8, 0xa8b2,
+	0xa8c7, 0x0000, 0xa8cb, 0x0000, 0x009e, 0x001e, 0x00de, 0x0005,
+	0x080c, 0x9859, 0x00d6, 0x0096, 0x6114, 0x2148, 0x080c, 0xcc16,
+	0x0120, 0xa87b, 0x0006, 0x080c, 0x6f19, 0x009e, 0x00de, 0x080c,
+	0xaf2e, 0x0804, 0x98bf, 0x080c, 0x9859, 0x080c, 0x3310, 0x080c,
+	0xd353, 0x00d6, 0x0096, 0x6114, 0x2148, 0x080c, 0xcc16, 0x0120,
+	0xa87b, 0x0029, 0x080c, 0x6f19, 0x009e, 0x00de, 0x080c, 0xaf2e,
+	0x0804, 0x98bf, 0x9182, 0x0047, 0x0002, 0xb1c2, 0xb1c4, 0xb1c2,
+	0xb1c2, 0xb1c2, 0xb1c2, 0xb1c2, 0xb1c2, 0xb1c2, 0xb1c2, 0xb1c2,
+	0xb1c2, 0xb1c4, 0x080c, 0x0d85, 0x00d6, 0x0096, 0x601f, 0x0000,
+	0x6114, 0x2148, 0xa87b, 0x0000, 0xa883, 0x0000, 0x080c, 0x6f19,
+	0x009e, 0x00de, 0x0804, 0xaf2e, 0x0026, 0x0036, 0x0056, 0x0066,
+	0x0096, 0x00a6, 0x00f6, 0x0006, 0x080c, 0x1059, 0x000e, 0x090c,
+	0x0d85, 0xa960, 0x21e8, 0xa95c, 0x9188, 0x0019, 0x21a0, 0x900e,
+	0x20a9, 0x0020, 0x4104, 0xa87a, 0x2079, 0x1800, 0x7990, 0x9188,
+	0x0018, 0x918c, 0x0fff, 0xa972, 0xac76, 0x2950, 0x00a6, 0x2001,
+	0x0205, 0x2003, 0x0000, 0x901e, 0x2029, 0x0001, 0x9182, 0x0034,
+	0x1228, 0x2011, 0x001f, 0x080c, 0xc794, 0x04c0, 0x2130, 0x2009,
+	0x0034, 0x2011, 0x001f, 0x080c, 0xc794, 0x96b2, 0x0034, 0xb004,
+	0x904d, 0x0110, 0x080c, 0x100b, 0x080c, 0x1059, 0x01d0, 0x8528,
 	0xa867, 0x0110, 0xa86b, 0x0000, 0x2920, 0xb406, 0x968a, 0x003d,
-	0x1228, 0x2608, 0x2011, 0x001b, 0x0499, 0x00a8, 0x96b2, 0x003c,
-	0x2009, 0x003c, 0x2950, 0x2011, 0x001b, 0x0451, 0x0c28, 0x2001,
+	0x1230, 0x2608, 0x2011, 0x001b, 0x080c, 0xc794, 0x00b8, 0x96b2,
+	0x003c, 0x2009, 0x003c, 0x2950, 0x2011, 0x001b, 0x080c, 0xc794,
+	0x0c18, 0x2001, 0x0205, 0x2003, 0x0000, 0x00ae, 0x852f, 0x95ad,
+	0x0050, 0xb566, 0xb070, 0xc0fd, 0xb072, 0x0048, 0x2001, 0x0205,
+	0x2003, 0x0000, 0x00ae, 0x852f, 0x95ad, 0x0050, 0xb566, 0x2a48,
+	0xa804, 0xa807, 0x0000, 0x0006, 0x080c, 0x6f19, 0x000e, 0x2048,
+	0x9005, 0x1db0, 0x00fe, 0x00ae, 0x009e, 0x006e, 0x005e, 0x003e,
+	0x002e, 0x0005, 0x00d6, 0x00f6, 0x0096, 0x0006, 0x080c, 0x1059,
+	0x000e, 0x090c, 0x0d85, 0xa960, 0x21e8, 0xa95c, 0x9188, 0x0019,
+	0x21a0, 0x900e, 0x20a9, 0x0020, 0x4104, 0xaa66, 0xa87a, 0x2079,
+	0x1800, 0x7990, 0x810c, 0x9188, 0x000c, 0x9182, 0x001a, 0x0210,
+	0x2009, 0x001a, 0x21a8, 0x810b, 0xa972, 0xac76, 0x2e98, 0xa85c,
+	0x9080, 0x001f, 0x20a0, 0x2001, 0x0205, 0x200c, 0x918d, 0x0080,
+	0x2102, 0x4003, 0x2003, 0x0000, 0x080c, 0x6f19, 0x009e, 0x00fe,
+	0x00de, 0x0005, 0x0016, 0x00d6, 0x00f6, 0x0096, 0x0016, 0x2001,
+	0x0205, 0x200c, 0x918d, 0x0080, 0x2102, 0x001e, 0x2079, 0x0200,
+	0x2e98, 0xa87c, 0xd0ec, 0x0118, 0x9e80, 0x000c, 0x2098, 0x2021,
+	0x003e, 0x901e, 0x9282, 0x0020, 0x0218, 0x2011, 0x0020, 0x2018,
+	0x9486, 0x003e, 0x1170, 0x0096, 0x080c, 0x1059, 0x2900, 0x009e,
+	0x05c0, 0xa806, 0x2048, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0002,
+	0x20a0, 0x3300, 0x908e, 0x0260, 0x0140, 0x2009, 0x0280, 0x9102,
+	0x920a, 0x0218, 0x2010, 0x2100, 0x9318, 0x2200, 0x9402, 0x1228,
+	0x2400, 0x9202, 0x2410, 0x9318, 0x9006, 0x2020, 0x22a8, 0xa800,
+	0x9200, 0xa802, 0x20e1, 0x0000, 0x4003, 0x83ff, 0x0180, 0x3300,
+	0x9086, 0x0280, 0x1130, 0x7814, 0x8000, 0x9085, 0x0080, 0x7816,
+	0x2e98, 0x2310, 0x84ff, 0x0904, 0xb2a7, 0x0804, 0xb2a9, 0x9085,
+	0x0001, 0x7817, 0x0000, 0x009e, 0x00fe, 0x00de, 0x001e, 0x0005,
+	0x00d6, 0x0036, 0x0096, 0x6314, 0x2348, 0xa87a, 0xa982, 0x080c,
+	0x6f0d, 0x009e, 0x003e, 0x00de, 0x0005, 0x91b6, 0x0015, 0x1118,
+	0x080c, 0xaf2e, 0x0030, 0x91b6, 0x0016, 0x190c, 0x0d85, 0x080c,
+	0xaf2e, 0x0005, 0x20a9, 0x000e, 0x20e1, 0x0000, 0x2e98, 0x6014,
+	0x0096, 0x2048, 0xa860, 0x20e8, 0xa85c, 0x20a0, 0x009e, 0x4003,
+	0x9196, 0x0016, 0x01f0, 0x0136, 0x9080, 0x001b, 0x20a0, 0x2011,
+	0x0006, 0x20a9, 0x0001, 0x3418, 0x8318, 0x23a0, 0x4003, 0x3318,
+	0x8318, 0x2398, 0x8211, 0x1db8, 0x2011, 0x0006, 0x013e, 0x20a0,
+	0x3318, 0x8318, 0x2398, 0x4003, 0x3418, 0x8318, 0x23a0, 0x8211,
+	0x1db8, 0x0096, 0x080c, 0xcc16, 0x0130, 0x6014, 0x2048, 0xa807,
+	0x0000, 0xa867, 0x0103, 0x009e, 0x0804, 0xaf2e, 0x0096, 0x00d6,
+	0x0036, 0x7330, 0x9386, 0x0200, 0x11a8, 0x6010, 0x00b6, 0x2058,
+	0xb8d7, 0x0000, 0x00be, 0x6014, 0x9005, 0x0130, 0x2048, 0xa807,
+	0x0000, 0xa867, 0x0103, 0xab32, 0x080c, 0xaf2e, 0x003e, 0x00de,
+	0x009e, 0x0005, 0x0011, 0x1d48, 0x0cc8, 0x0006, 0x0016, 0x080c,
+	0xd33e, 0x0188, 0x6014, 0x9005, 0x1170, 0x600b, 0x0003, 0x601b,
+	0x0000, 0x604b, 0x0000, 0x2009, 0x0022, 0x080c, 0xb757, 0x9006,
+	0x001e, 0x000e, 0x0005, 0x9085, 0x0001, 0x0cd0, 0x0096, 0x0016,
+	0x20a9, 0x0014, 0x9e80, 0x000c, 0x20e1, 0x0000, 0x2098, 0x6014,
+	0x2048, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0002, 0x20a0, 0x4003,
+	0x2001, 0x0205, 0x2003, 0x0001, 0x2099, 0x0260, 0x20a9, 0x0016,
+	0x4003, 0x20a9, 0x000a, 0xa804, 0x2048, 0xa860, 0x20e8, 0xa85c,
+	0x9080, 0x0002, 0x20a0, 0x4003, 0x2001, 0x0205, 0x2003, 0x0002,
+	0x2099, 0x0260, 0x20a9, 0x0020, 0x4003, 0x2003, 0x0000, 0x6014,
+	0x2048, 0xa800, 0x2048, 0xa867, 0x0103, 0x080c, 0xaf2e, 0x001e,
+	0x009e, 0x0005, 0x0096, 0x0016, 0x900e, 0x7030, 0x9086, 0x0100,
+	0x0140, 0x7038, 0x9084, 0x00ff, 0x800c, 0x703c, 0x9084, 0x00ff,
+	0x8004, 0x9080, 0x0004, 0x9108, 0x810b, 0x2011, 0x0002, 0x2019,
+	0x000c, 0x6014, 0x2048, 0x080c, 0xc794, 0x080c, 0xcc16, 0x0140,
+	0x6014, 0x2048, 0xa807, 0x0000, 0xa864, 0xa8e2, 0xa867, 0x0103,
+	0x080c, 0xaf2e, 0x001e, 0x009e, 0x0005, 0x0016, 0x2009, 0x0000,
+	0x7030, 0x9086, 0x0200, 0x0110, 0x2009, 0x0001, 0x0096, 0x6014,
+	0x904d, 0x090c, 0x0d85, 0xa97a, 0x080c, 0x6f19, 0x009e, 0x080c,
+	0xaf2e, 0x001e, 0x0005, 0x0016, 0x0096, 0x7030, 0x9086, 0x0100,
+	0x1118, 0x2009, 0x0004, 0x0010, 0x7034, 0x800c, 0x810b, 0x2011,
+	0x000c, 0x2019, 0x000c, 0x6014, 0x2048, 0xa804, 0x0096, 0x9005,
+	0x0108, 0x2048, 0x080c, 0xc794, 0x009e, 0x080c, 0xcc16, 0x0148,
+	0xa804, 0x9005, 0x1158, 0xa807, 0x0000, 0xa864, 0xa8e2, 0xa867,
+	0x0103, 0x080c, 0xaf2e, 0x009e, 0x001e, 0x0005, 0x0086, 0x2040,
+	0xa030, 0x8007, 0x9086, 0x0100, 0x1118, 0x080c, 0xb91f, 0x00e0,
+	0xa034, 0x8007, 0x800c, 0x8806, 0x8006, 0x8007, 0x90bc, 0x003f,
+	0x9084, 0xffc0, 0x9080, 0x000c, 0xa87b, 0x0000, 0xa883, 0x0000,
+	0xa897, 0x4000, 0xaaa0, 0xab9c, 0xaca8, 0xada4, 0x2031, 0x0000,
+	0x2041, 0x12a8, 0x0019, 0x0d08, 0x008e, 0x0898, 0x0096, 0x0006,
+	0x080c, 0x1059, 0x000e, 0x01b0, 0xa8ab, 0x0dcb, 0xa876, 0x000e,
+	0xa8a2, 0x0006, 0xae6a, 0x2800, 0xa89e, 0xa97a, 0xaf72, 0xaa8e,
+	0xab92, 0xac96, 0xad9a, 0x0086, 0x2940, 0x080c, 0x114e, 0x008e,
+	0x9085, 0x0001, 0x009e, 0x0005, 0x00e6, 0x00d6, 0x0026, 0x7008,
+	0x9084, 0x00ff, 0x6210, 0x00b6, 0x2258, 0xba10, 0x00be, 0x9206,
+	0x1520, 0x700c, 0x6210, 0x00b6, 0x2258, 0xba14, 0x00be, 0x9206,
+	0x11e0, 0x604b, 0x0000, 0x2c68, 0x0016, 0x2009, 0x0035, 0x080c,
+	0xd2b6, 0x001e, 0x1158, 0x622c, 0x2268, 0x2071, 0x026c, 0x6b20,
+	0x9386, 0x0003, 0x0130, 0x9386, 0x0006, 0x0128, 0x080c, 0xaf2e,
+	0x0020, 0x0039, 0x0010, 0x080c, 0xb58c, 0x002e, 0x00de, 0x00ee,
+	0x0005, 0x0096, 0x6814, 0x2048, 0x9186, 0x0015, 0x0904, 0xb56b,
+	0x918e, 0x0016, 0x1904, 0xb58a, 0x700c, 0x908c, 0xff00, 0x9186,
+	0x1700, 0x0120, 0x9186, 0x0300, 0x1904, 0xb545, 0x89ff, 0x1138,
+	0x6800, 0x9086, 0x000f, 0x0904, 0xb527, 0x0804, 0xb588, 0x6808,
+	0x9086, 0xffff, 0x1904, 0xb56d, 0xa87c, 0x9084, 0x0060, 0x9086,
+	0x0020, 0x1150, 0xa8ac, 0xa934, 0x9106, 0x1904, 0xb56d, 0xa8b0,
+	0xa938, 0x9106, 0x1904, 0xb56d, 0x6824, 0xd084, 0x1904, 0xb56d,
+	0xd0b4, 0x0158, 0x0016, 0x2001, 0x1987, 0x200c, 0x6018, 0x9102,
+	0x9082, 0x0005, 0x001e, 0x1a04, 0xb56d, 0x080c, 0xce07, 0x6810,
+	0x0096, 0x2048, 0xa9a0, 0x009e, 0x685c, 0xa87a, 0xa976, 0x6864,
+	0xa882, 0xa87c, 0xc0dc, 0xc0f4, 0xc0d4, 0xa87e, 0x0026, 0x900e,
+	0x6a18, 0x2001, 0x000a, 0x080c, 0x936c, 0xa884, 0x920a, 0x0208,
+	0x8011, 0xaa86, 0x82ff, 0x002e, 0x1138, 0x00c6, 0x2d60, 0x080c,
+	0xc91f, 0x00ce, 0x0804, 0xb588, 0x00c6, 0xa868, 0xd0fc, 0x1118,
+	0x080c, 0x6210, 0x0010, 0x080c, 0x661b, 0x00ce, 0x1904, 0xb56d,
+	0x00c6, 0x2d60, 0x080c, 0xaf2e, 0x00ce, 0x0804, 0xb588, 0x00c6,
+	0x080c, 0xaf9f, 0x0198, 0x6017, 0x0000, 0x6810, 0x6012, 0x080c,
+	0xd0b1, 0x6023, 0x0003, 0x6904, 0x00c6, 0x2d60, 0x080c, 0xaf2e,
+	0x00ce, 0x080c, 0xafcc, 0x00ce, 0x0804, 0xb588, 0x2001, 0x1989,
+	0x2004, 0x684a, 0x00ce, 0x0804, 0xb588, 0x7008, 0x9086, 0x000b,
+	0x11c8, 0x6010, 0x00b6, 0x2058, 0xb900, 0xc1bc, 0xb902, 0x00be,
+	0x00c6, 0x2d60, 0xa87b, 0x0003, 0x080c, 0xd2f8, 0x6007, 0x0085,
+	0x6003, 0x000b, 0x6023, 0x0002, 0x2009, 0x8020, 0x080c, 0x9428,
+	0x00ce, 0x0430, 0x700c, 0x9086, 0x2a00, 0x1138, 0x2001, 0x1989,
+	0x2004, 0x684a, 0x00e8, 0x04c1, 0x00e8, 0x89ff, 0x090c, 0x0d85,
+	0x00c6, 0x00d6, 0x2d60, 0xa867, 0x0103, 0xa87b, 0x0003, 0x080c,
+	0x6d2e, 0x080c, 0xce07, 0x080c, 0xaf69, 0x0026, 0x6010, 0x00b6,
+	0x2058, 0xba3c, 0x080c, 0x68b4, 0x00be, 0x002e, 0x00de, 0x00ce,
+	0x080c, 0xaf2e, 0x009e, 0x0005, 0x9186, 0x0015, 0x1128, 0x2001,
+	0x1989, 0x2004, 0x684a, 0x0068, 0x918e, 0x0016, 0x1160, 0x00c6,
+	0x2d00, 0x2060, 0x080c, 0xe985, 0x080c, 0x8aba, 0x080c, 0xaf2e,
+	0x00ce, 0x080c, 0xaf2e, 0x0005, 0x0026, 0x0036, 0x0046, 0x7228,
+	0xacb0, 0xabac, 0xd2f4, 0x0130, 0x2001, 0x1989, 0x2004, 0x684a,
+	0x0804, 0xb606, 0x00c6, 0x2d60, 0x080c, 0xc7f5, 0x00ce, 0x6804,
+	0x9086, 0x0050, 0x1168, 0x00c6, 0x2d00, 0x2060, 0x6003, 0x0001,
+	0x6007, 0x0050, 0x2009, 0x8023, 0x080c, 0x9428, 0x00ce, 0x04f0,
+	0x6800, 0x9086, 0x000f, 0x01a8, 0x89ff, 0x090c, 0x0d85, 0x6800,
+	0x9086, 0x0004, 0x1190, 0xa87c, 0xd0ac, 0x0178, 0xa843, 0x0fff,
+	0xa83f, 0x0fff, 0xa880, 0xc0fc, 0xa882, 0x2001, 0x0001, 0x6832,
+	0x0400, 0x2001, 0x0007, 0x6832, 0x00e0, 0xa87c, 0xd0b4, 0x1150,
+	0xd0ac, 0x0db8, 0x6824, 0xd0f4, 0x1d48, 0xa838, 0xa934, 0x9105,
+	0x0d80, 0x0c20, 0xd2ec, 0x1d68, 0x7024, 0x9306, 0x1118, 0x7020,
+	0x9406, 0x0d38, 0x7020, 0x683e, 0x7024, 0x683a, 0x2001, 0x0005,
+	0x6832, 0x080c, 0xcf9b, 0x080c, 0x98bf, 0x0010, 0x080c, 0xaf2e,
+	0x004e, 0x003e, 0x002e, 0x0005, 0x00e6, 0x00d6, 0x0026, 0x7008,
+	0x9084, 0x00ff, 0x6210, 0x00b6, 0x2258, 0xba10, 0x00be, 0x9206,
+	0x1904, 0xb671, 0x700c, 0x6210, 0x00b6, 0x2258, 0xba14, 0x00be,
+	0x9206, 0x1904, 0xb671, 0x6038, 0x2068, 0x6824, 0xc0dc, 0x6826,
+	0x6a20, 0x9286, 0x0007, 0x0904, 0xb671, 0x9286, 0x0002, 0x0904,
+	0xb671, 0x9286, 0x0000, 0x05e8, 0x6808, 0x633c, 0x9306, 0x15c8,
+	0x2071, 0x026c, 0x9186, 0x0015, 0x0570, 0x918e, 0x0016, 0x1100,
+	0x00c6, 0x6038, 0x2060, 0x6104, 0x9186, 0x004b, 0x01c0, 0x9186,
+	0x004c, 0x01a8, 0x9186, 0x004d, 0x0190, 0x9186, 0x004e, 0x0178,
+	0x9186, 0x0052, 0x0160, 0x6014, 0x0096, 0x2048, 0x080c, 0xcc16,
+	0x090c, 0x0d85, 0xa87b, 0x0003, 0x009e, 0x080c, 0xd2f8, 0x6007,
+	0x0085, 0x6003, 0x000b, 0x6023, 0x0002, 0x2009, 0x8020, 0x080c,
+	0x9428, 0x00ce, 0x0030, 0x6038, 0x2070, 0x2001, 0x1989, 0x2004,
+	0x704a, 0x080c, 0xaf2e, 0x002e, 0x00de, 0x00ee, 0x0005, 0x00b6,
+	0x0096, 0x00f6, 0x6014, 0x2048, 0x6010, 0x2058, 0x91b6, 0x0015,
+	0x0130, 0xba08, 0xbb0c, 0xbc00, 0xc48c, 0xbc02, 0x0460, 0x0096,
+	0x0156, 0x0036, 0x0026, 0x2b48, 0x9e90, 0x0010, 0x2019, 0x000a,
+	0x20a9, 0x0004, 0x080c, 0xbf3e, 0x002e, 0x003e, 0x015e, 0x009e,
+	0x1904, 0xb6e0, 0x0096, 0x0156, 0x0036, 0x0026, 0x2b48, 0x9e90,
+	0x0014, 0x2019, 0x0006, 0x20a9, 0x0004, 0x080c, 0xbf3e, 0x002e,
+	0x003e, 0x015e, 0x009e, 0x15a0, 0x7238, 0xba0a, 0x733c, 0xbb0e,
+	0xbc00, 0xc48d, 0xbc02, 0xa804, 0x9005, 0x1128, 0x00fe, 0x009e,
+	0x00be, 0x0804, 0xb341, 0x0096, 0x2048, 0xaa12, 0xab16, 0xac0a,
+	0x009e, 0x8006, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0,
+	0x9080, 0x0002, 0x2009, 0x002b, 0xaaa0, 0xab9c, 0xaca8, 0xada4,
+	0x2031, 0x0000, 0x2041, 0x12a8, 0x080c, 0xb456, 0x0130, 0x00fe,
+	0x009e, 0x080c, 0xaf2e, 0x00be, 0x0005, 0x080c, 0xb91f, 0x0cb8,
+	0x2b78, 0x00f6, 0x080c, 0x3310, 0x080c, 0xd353, 0x00fe, 0x00c6,
+	0x080c, 0xaed8, 0x2f00, 0x6012, 0x6017, 0x0000, 0x6023, 0x0001,
+	0x6007, 0x0001, 0x6003, 0x0001, 0x2001, 0x0007, 0x080c, 0x66cf,
+	0x080c, 0x66fb, 0x080c, 0x942f, 0x080c, 0x98bf, 0x00ce, 0x0804,
+	0xb6b3, 0x2100, 0x91b2, 0x0053, 0x1a0c, 0x0d85, 0x91b2, 0x0040,
+	0x1a04, 0xb769, 0x0002, 0xb757, 0xb757, 0xb74d, 0xb757, 0xb757,
+	0xb757, 0xb74b, 0xb74b, 0xb74b, 0xb74b, 0xb74b, 0xb74b, 0xb74b,
+	0xb74b, 0xb74b, 0xb74b, 0xb74b, 0xb74b, 0xb74b, 0xb74b, 0xb74b,
+	0xb74b, 0xb74b, 0xb74b, 0xb74b, 0xb74b, 0xb74b, 0xb74b, 0xb74b,
+	0xb74b, 0xb74b, 0xb757, 0xb74b, 0xb757, 0xb757, 0xb74b, 0xb74b,
+	0xb74b, 0xb74b, 0xb74b, 0xb74d, 0xb74b, 0xb74b, 0xb74b, 0xb74b,
+	0xb74b, 0xb74b, 0xb74b, 0xb74b, 0xb74b, 0xb757, 0xb757, 0xb74b,
+	0xb74b, 0xb74b, 0xb74b, 0xb74b, 0xb74b, 0xb74b, 0xb74b, 0xb74b,
+	0xb757, 0xb74b, 0xb74b, 0x080c, 0x0d85, 0x0066, 0x00b6, 0x6610,
+	0x2658, 0xb8d4, 0xc08c, 0xb8d6, 0x00be, 0x006e, 0x0000, 0x6003,
+	0x0001, 0x6106, 0x9186, 0x0032, 0x0118, 0x080c, 0x942f, 0x0010,
+	0x080c, 0x9428, 0x0126, 0x2091, 0x8000, 0x080c, 0x98bf, 0x012e,
+	0x0005, 0x2600, 0x0002, 0xb757, 0xb757, 0xb77d, 0xb757, 0xb757,
+	0xb77d, 0xb77d, 0xb77d, 0xb77d, 0xb757, 0xb77d, 0xb757, 0xb77d,
+	0xb757, 0xb77d, 0xb77d, 0xb77d, 0xb77d, 0x080c, 0x0d85, 0x6004,
+	0x90b2, 0x0053, 0x1a0c, 0x0d85, 0x91b6, 0x0013, 0x0904, 0xb854,
+	0x91b6, 0x0027, 0x1904, 0xb800, 0x080c, 0x97fe, 0x6004, 0x080c,
+	0xce1c, 0x01b0, 0x080c, 0xce2d, 0x01a8, 0x908e, 0x0021, 0x0904,
+	0xb7fd, 0x908e, 0x0022, 0x1130, 0x080c, 0xb36d, 0x0904, 0xb7f9,
+	0x0804, 0xb7fa, 0x908e, 0x003d, 0x0904, 0xb7fd, 0x0804, 0xb7f3,
+	0x080c, 0x333f, 0x2001, 0x0007, 0x080c, 0x66cf, 0x6010, 0x00b6,
+	0x2058, 0xb9a0, 0x00be, 0x080c, 0xb91f, 0x9186, 0x007e, 0x1148,
+	0x2001, 0x1837, 0x2014, 0xc285, 0x080c, 0x76a5, 0x1108, 0xc2ad,
+	0x2202, 0x080c, 0xaae0, 0x0036, 0x0026, 0x2019, 0x0028, 0x2110,
+	0x080c, 0xea92, 0x002e, 0x003e, 0x0016, 0x0026, 0x0036, 0x2110,
+	0x2019, 0x0028, 0x080c, 0x95c1, 0x0076, 0x903e, 0x080c, 0x947e,
+	0x6010, 0x00b6, 0x905d, 0x0100, 0x00be, 0x2c08, 0x080c, 0xe440,
+	0x007e, 0x003e, 0x002e, 0x001e, 0x080c, 0xaafc, 0x080c, 0xd353,
+	0x0016, 0x080c, 0xd0a9, 0x080c, 0xaf2e, 0x001e, 0x080c, 0x3419,
+	0x080c, 0x98bf, 0x0030, 0x080c, 0xd0a9, 0x080c, 0xaf2e, 0x080c,
+	0x98bf, 0x0005, 0x080c, 0xb91f, 0x0cb0, 0x080c, 0xb95b, 0x0c98,
+	0x9186, 0x0015, 0x0118, 0x9186, 0x0016, 0x1140, 0x080c, 0xad2d,
+	0x0d80, 0x9086, 0x0002, 0x0904, 0xb966, 0x0c58, 0x9186, 0x0014,
+	0x1d40, 0x080c, 0x97fe, 0x6004, 0x908e, 0x0022, 0x1118, 0x080c,
+	0xb36d, 0x09f8, 0x080c, 0x3310, 0x080c, 0xd353, 0x080c, 0xce1c,
+	0x1190, 0x080c, 0x333f, 0x6010, 0x00b6, 0x2058, 0xb9a0, 0x00be,
+	0x080c, 0xb91f, 0x9186, 0x007e, 0x1128, 0x2001, 0x1837, 0x200c,
+	0xc185, 0x2102, 0x0800, 0x080c, 0xce2d, 0x1120, 0x080c, 0xb91f,
+	0x0804, 0xb7f3, 0x6004, 0x908e, 0x0032, 0x1160, 0x00e6, 0x00f6,
+	0x2071, 0x189e, 0x2079, 0x0000, 0x080c, 0x36ba, 0x00fe, 0x00ee,
+	0x0804, 0xb7f3, 0x6004, 0x908e, 0x0021, 0x0d40, 0x908e, 0x0022,
+	0x090c, 0xb91f, 0x0804, 0xb7f3, 0x90b2, 0x0040, 0x1a04, 0xb8ff,
+	0x2008, 0x0002, 0xb89c, 0xb89d, 0xb8a0, 0xb8a3, 0xb8a6, 0xb8b3,
+	0xb89a, 0xb89a, 0xb89a, 0xb89a, 0xb89a, 0xb89a, 0xb89a, 0xb89a,
+	0xb89a, 0xb89a, 0xb89a, 0xb89a, 0xb89a, 0xb89a, 0xb89a, 0xb89a,
+	0xb89a, 0xb89a, 0xb89a, 0xb89a, 0xb89a, 0xb89a, 0xb89a, 0xb89a,
+	0xb8b6, 0xb8c1, 0xb89a, 0xb8c2, 0xb8c1, 0xb89a, 0xb89a, 0xb89a,
+	0xb89a, 0xb89a, 0xb8c1, 0xb8c1, 0xb89a, 0xb89a, 0xb89a, 0xb89a,
+	0xb89a, 0xb89a, 0xb89a, 0xb89a, 0xb8ea, 0xb8c1, 0xb89a, 0xb8bd,
+	0xb89a, 0xb89a, 0xb89a, 0xb8be, 0xb89a, 0xb89a, 0xb89a, 0xb8c1,
+	0xb8e5, 0xb89a, 0x080c, 0x0d85, 0x0420, 0x2001, 0x000b, 0x0448,
+	0x2001, 0x0003, 0x0430, 0x2001, 0x0005, 0x0418, 0x6010, 0x00b6,
+	0x2058, 0xb804, 0x00be, 0x9084, 0x00ff, 0x9086, 0x0000, 0x11d8,
+	0x2001, 0x0001, 0x00b0, 0x2001, 0x0009, 0x0098, 0x6003, 0x0005,
+	0x080c, 0xd356, 0x080c, 0x98bf, 0x0058, 0x0018, 0x0010, 0x080c,
+	0x66cf, 0x04b8, 0x080c, 0xd356, 0x6003, 0x0004, 0x080c, 0x98bf,
+	0x0005, 0x080c, 0x66cf, 0x6003, 0x0002, 0x0036, 0x2019, 0x1852,
+	0x2304, 0x9084, 0xff00, 0x1120, 0x2001, 0x1987, 0x201c, 0x0040,
+	0x8007, 0x909a, 0x0004, 0x0ec0, 0x8003, 0x801b, 0x831b, 0x9318,
+	0x631a, 0x003e, 0x080c, 0x98bf, 0x0c18, 0x080c, 0xd0a9, 0x080c,
+	0xaf2e, 0x08f0, 0x00e6, 0x00f6, 0x2071, 0x189e, 0x2079, 0x0000,
+	0x080c, 0x36ba, 0x00fe, 0x00ee, 0x080c, 0x97fe, 0x080c, 0xaf2e,
+	0x0878, 0x6003, 0x0002, 0x080c, 0xd356, 0x0804, 0x98bf, 0x2600,
+	0x2008, 0x0002, 0xb916, 0xb8f9, 0xb914, 0xb8f9, 0xb8f9, 0xb914,
+	0xb914, 0xb914, 0xb914, 0xb8f9, 0xb914, 0xb8f9, 0xb914, 0xb8f9,
+	0xb914, 0xb914, 0xb914, 0xb914, 0x080c, 0x0d85, 0x0096, 0x6014,
+	0x2048, 0x080c, 0x6f19, 0x009e, 0x080c, 0xaf2e, 0x0005, 0x00e6,
+	0x0096, 0x0026, 0x0016, 0x080c, 0xcc16, 0x0568, 0x6014, 0x2048,
+	0xa864, 0x9086, 0x0139, 0x11a8, 0xa894, 0x9086, 0x0056, 0x1148,
+	0x080c, 0x55b2, 0x0130, 0x2001, 0x0000, 0x900e, 0x2011, 0x4000,
+	0x0028, 0x2001, 0x0030, 0x900e, 0x2011, 0x4005, 0x080c, 0xd21a,
+	0x0090, 0xa868, 0xd0fc, 0x0178, 0xa807, 0x0000, 0x0016, 0x6004,
+	0x908e, 0x0021, 0x0168, 0x908e, 0x003d, 0x0150, 0x001e, 0xa867,
+	0x0103, 0xa833, 0x0100, 0x001e, 0x002e, 0x009e, 0x00ee, 0x0005,
+	0x001e, 0x0009, 0x0cc0, 0x0096, 0x6014, 0x2048, 0xa800, 0x2048,
+	0xa867, 0x0103, 0xa823, 0x8001, 0x009e, 0x0005, 0x00b6, 0x6610,
+	0x2658, 0xb804, 0x9084, 0x00ff, 0x90b2, 0x000c, 0x1a0c, 0x0d85,
+	0x6604, 0x96b6, 0x004d, 0x1120, 0x080c, 0xd139, 0x0804, 0xb9eb,
+	0x6604, 0x96b6, 0x0043, 0x1120, 0x080c, 0xd182, 0x0804, 0xb9eb,
+	0x6604, 0x96b6, 0x004b, 0x1120, 0x080c, 0xd1ae, 0x0804, 0xb9eb,
+	0x6604, 0x96b6, 0x0033, 0x1120, 0x080c, 0xd0cb, 0x0804, 0xb9eb,
+	0x6604, 0x96b6, 0x0028, 0x1120, 0x080c, 0xce6b, 0x0804, 0xb9eb,
+	0x6604, 0x96b6, 0x0029, 0x1120, 0x080c, 0xceac, 0x0804, 0xb9eb,
+	0x6604, 0x96b6, 0x001f, 0x1120, 0x080c, 0xb312, 0x0804, 0xb9eb,
+	0x6604, 0x96b6, 0x0000, 0x1118, 0x080c, 0xb677, 0x04e0, 0x6604,
+	0x96b6, 0x0022, 0x1118, 0x080c, 0xb34e, 0x04a8, 0x6604, 0x96b6,
+	0x0035, 0x1118, 0x080c, 0xb474, 0x0470, 0x6604, 0x96b6, 0x0039,
+	0x1118, 0x080c, 0xb60c, 0x0438, 0x6604, 0x96b6, 0x003d, 0x1118,
+	0x080c, 0xb386, 0x0400, 0x6604, 0x96b6, 0x0044, 0x1118, 0x080c,
+	0xb3c2, 0x00c8, 0x6604, 0x96b6, 0x0049, 0x1118, 0x080c, 0xb403,
+	0x0090, 0x6604, 0x96b6, 0x0041, 0x1118, 0x080c, 0xb3ed, 0x0058,
+	0x91b6, 0x0015, 0x1110, 0x0063, 0x0030, 0x91b6, 0x0016, 0x1128,
+	0x00be, 0x0804, 0xbc55, 0x00be, 0x0005, 0x080c, 0xafe9, 0x0cd8,
+	0xba08, 0xba16, 0xba08, 0xba5d, 0xba08, 0xbbc9, 0xbc62, 0xba08,
+	0xba08, 0xbc2b, 0xba08, 0xbc41, 0x0096, 0x601f, 0x0000, 0x6014,
+	0x2048, 0xa800, 0x2048, 0xa867, 0x0103, 0x009e, 0x0804, 0xaf2e,
+	0xa001, 0xa001, 0x0005, 0x6604, 0x96b6, 0x0004, 0x1130, 0x2001,
+	0x0001, 0x080c, 0x66bb, 0x0804, 0xaf2e, 0x0005, 0x00e6, 0x2071,
+	0x1800, 0x7090, 0x9086, 0x0074, 0x1540, 0x080c, 0xe411, 0x11b0,
+	0x6010, 0x00b6, 0x2058, 0x7030, 0xd08c, 0x0128, 0xb800, 0xd0bc,
+	0x0110, 0xc0c5, 0xb802, 0x00f9, 0x00be, 0x2001, 0x0006, 0x080c,
+	0x66cf, 0x080c, 0x333f, 0x080c, 0xaf2e, 0x0098, 0x2001, 0x000a,
+	0x080c, 0x66cf, 0x080c, 0x333f, 0x6003, 0x0001, 0x6007, 0x0001,
+	0x080c, 0x942f, 0x080c, 0x98bf, 0x0020, 0x2001, 0x0001, 0x080c,
+	0xbb99, 0x00ee, 0x0005, 0x00d6, 0xb800, 0xd084, 0x0160, 0x9006,
+	0x080c, 0x66bb, 0x2069, 0x1847, 0x6804, 0xd0a4, 0x0120, 0x2001,
+	0x0006, 0x080c, 0x66fb, 0x00de, 0x0005, 0x00b6, 0x0096, 0x00d6,
+	0x2011, 0x1824, 0x2204, 0x9086, 0x0074, 0x1904, 0xbb6e, 0x6010,
+	0x2058, 0xbaa0, 0x9286, 0x007e, 0x1120, 0x080c, 0xbdb1, 0x0804,
+	0xbacf, 0x080c, 0xbda6, 0x6010, 0x2058, 0xbaa0, 0x9286, 0x0080,
+	0x1510, 0x6014, 0x9005, 0x01a8, 0x2048, 0xa864, 0x9084, 0x00ff,
+	0x9086, 0x0039, 0x1140, 0x2001, 0x0000, 0x900e, 0x2011, 0x4000,
+	0x080c, 0xd21a, 0x0030, 0xa807, 0x0000, 0xa867, 0x0103, 0xa833,
+	0x0200, 0x2001, 0x0006, 0x080c, 0x66cf, 0x080c, 0x333f, 0x080c,
+	0xaf2e, 0x0804, 0xbb73, 0x080c, 0xbb81, 0x6014, 0x9005, 0x0190,
+	0x2048, 0xa868, 0xd0f4, 0x01e8, 0xa864, 0x9084, 0x00ff, 0x9086,
+	0x0039, 0x1d08, 0x2001, 0x0000, 0x900e, 0x2011, 0x4000, 0x080c,
+	0xd21a, 0x08f8, 0x080c, 0xbb77, 0x0160, 0x9006, 0x080c, 0x66bb,
+	0x2001, 0x0004, 0x080c, 0x66fb, 0x2001, 0x0007, 0x080c, 0x66cf,
+	0x08a0, 0x2001, 0x0004, 0x080c, 0x66cf, 0x6003, 0x0001, 0x6007,
+	0x0003, 0x080c, 0x942f, 0x080c, 0x98bf, 0x0804, 0xbb73, 0xb85c,
+	0xd0e4, 0x01d8, 0x080c, 0xd043, 0x080c, 0x76a5, 0x0118, 0xd0dc,
+	0x1904, 0xba91, 0x2011, 0x1837, 0x2204, 0xc0ad, 0x2012, 0x2001,
+	0x196e, 0x2004, 0x00f6, 0x2079, 0x0100, 0x78e3, 0x0000, 0x080c,
+	0x2716, 0x78e2, 0x00fe, 0x0804, 0xba91, 0x080c, 0xd084, 0x2011,
+	0x1837, 0x2204, 0xc0a5, 0x2012, 0x0006, 0x080c, 0xe5a2, 0x000e,
+	0x1904, 0xba91, 0xc0b5, 0x2012, 0x2001, 0x0006, 0x080c, 0x66cf,
+	0x9006, 0x080c, 0x66bb, 0x00c6, 0x2001, 0x180f, 0x2004, 0xd09c,
+	0x0520, 0x00f6, 0x2079, 0x0100, 0x00e6, 0x2071, 0x1800, 0x700c,
+	0x9084, 0x00ff, 0x78e6, 0x707e, 0x7010, 0x78ea, 0x7082, 0x908c,
+	0x00ff, 0x00ee, 0x780c, 0xc0b5, 0x780e, 0x00fe, 0x080c, 0x26eb,
+	0x00f6, 0x2100, 0x900e, 0x080c, 0x26a2, 0x795e, 0x00fe, 0x9186,
+	0x0081, 0x01f0, 0x2009, 0x0081, 0x00e0, 0x2009, 0x00ef, 0x00f6,
+	0x2079, 0x0100, 0x79ea, 0x78e7, 0x0000, 0x7932, 0x7936, 0x780c,
+	0xc0b5, 0x780e, 0x00fe, 0x080c, 0x26eb, 0x00f6, 0x2079, 0x1800,
+	0x7982, 0x2100, 0x900e, 0x797e, 0x080c, 0x26a2, 0x795e, 0x00fe,
+	0x8108, 0x080c, 0x671e, 0x2b00, 0x00ce, 0x1904, 0xba91, 0x6012,
+	0x2009, 0x180f, 0x210c, 0xd19c, 0x0150, 0x2009, 0x027c, 0x210c,
+	0x918c, 0x00ff, 0xb912, 0x2009, 0x027d, 0x210c, 0xb916, 0x2001,
+	0x0002, 0x080c, 0x66cf, 0x6023, 0x0001, 0x6003, 0x0001, 0x6007,
+	0x0002, 0x080c, 0x942f, 0x080c, 0x98bf, 0x0028, 0x080c, 0xb91f,
+	0x2001, 0x0001, 0x0431, 0x00de, 0x009e, 0x00be, 0x0005, 0x2001,
+	0x1810, 0x2004, 0xd0a4, 0x0120, 0x2001, 0x1848, 0x2004, 0xd0ac,
+	0x0005, 0x00e6, 0x080c, 0xeaeb, 0x0190, 0x2071, 0x0260, 0x7108,
+	0x720c, 0x918c, 0x00ff, 0x1118, 0x9284, 0xff00, 0x0140, 0x6010,
+	0x2058, 0xb8a0, 0x9084, 0xff80, 0x1110, 0xb912, 0xba16, 0x00ee,
+	0x0005, 0x2030, 0x9005, 0x0158, 0x2001, 0x0007, 0x080c, 0x66cf,
+	0x080c, 0x583a, 0x1120, 0x2001, 0x0007, 0x080c, 0x66fb, 0x2600,
+	0x9005, 0x11b0, 0x6014, 0x0096, 0x2048, 0xa868, 0x009e, 0xd0fc,
+	0x1178, 0x0036, 0x0046, 0x6010, 0x00b6, 0x2058, 0xbba0, 0x00be,
+	0x2021, 0x0004, 0x2011, 0x8014, 0x080c, 0x4c2e, 0x004e, 0x003e,
+	0x080c, 0x333f, 0x6020, 0x9086, 0x000a, 0x1108, 0x0005, 0x0804,
+	0xaf2e, 0x00b6, 0x00e6, 0x0026, 0x0016, 0x2071, 0x1800, 0x7090,
+	0x9086, 0x0014, 0x1904, 0xbc21, 0x080c, 0x583a, 0x1170, 0x6014,
+	0x9005, 0x1158, 0x0036, 0x0046, 0x6010, 0x2058, 0xbba0, 0x2021,
+	0x0006, 0x080c, 0x4de5, 0x004e, 0x003e, 0x00d6, 0x6010, 0x2058,
+	0x080c, 0x6824, 0x080c, 0xba4b, 0x00de, 0x080c, 0xbe77, 0x1588,
+	0x6010, 0x2058, 0xb890, 0x9005, 0x0560, 0x2001, 0x0006, 0x080c,
+	0x66cf, 0x0096, 0x6014, 0x904d, 0x01d0, 0xa864, 0x9084, 0x00ff,
+	0x9086, 0x0039, 0x1140, 0x2001, 0x0000, 0x900e, 0x2011, 0x4000,
+	0x080c, 0xd21a, 0x0060, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0029,
+	0x0130, 0xa807, 0x0000, 0xa867, 0x0103, 0xa833, 0x0200, 0x009e,
+	0x080c, 0x333f, 0x6020, 0x9086, 0x000a, 0x0140, 0x080c, 0xaf2e,
+	0x0028, 0x080c, 0xb91f, 0x9006, 0x080c, 0xbb99, 0x001e, 0x002e,
+	0x00ee, 0x00be, 0x0005, 0x2011, 0x1824, 0x2204, 0x9086, 0x0014,
+	0x1160, 0x2001, 0x0002, 0x080c, 0x66cf, 0x6003, 0x0001, 0x6007,
+	0x0001, 0x080c, 0x942f, 0x0804, 0x98bf, 0x2001, 0x0001, 0x0804,
+	0xbb99, 0x2030, 0x2011, 0x1824, 0x2204, 0x9086, 0x0004, 0x1148,
+	0x96b6, 0x000b, 0x1120, 0x2001, 0x0007, 0x080c, 0x66cf, 0x0804,
+	0xaf2e, 0x2001, 0x0001, 0x0804, 0xbb99, 0x0002, 0xba08, 0xbc6d,
+	0xba08, 0xbcb0, 0xba08, 0xbd5d, 0xbc62, 0xba0b, 0xba08, 0xbd71,
+	0xba08, 0xbd83, 0x6604, 0x9686, 0x0003, 0x0904, 0xbbc9, 0x96b6,
+	0x001e, 0x1110, 0x080c, 0xaf2e, 0x0005, 0x00b6, 0x00d6, 0x00c6,
+	0x080c, 0xbd95, 0x11a0, 0x9006, 0x080c, 0x66bb, 0x080c, 0x3310,
+	0x080c, 0xd353, 0x2001, 0x0002, 0x080c, 0x66cf, 0x6003, 0x0001,
+	0x6007, 0x0002, 0x080c, 0x942f, 0x080c, 0x98bf, 0x0428, 0x2009,
+	0x026e, 0x2104, 0x9086, 0x0009, 0x1160, 0x6010, 0x2058, 0xb840,
+	0x9084, 0x00ff, 0x9005, 0x0180, 0x8001, 0xb842, 0x601b, 0x000a,
+	0x0098, 0x2009, 0x026f, 0x2104, 0x9084, 0xff00, 0x908e, 0x1900,
+	0x0158, 0x908e, 0x1e00, 0x0990, 0x080c, 0x3310, 0x080c, 0xd353,
+	0x2001, 0x0001, 0x080c, 0xbb99, 0x00ce, 0x00de, 0x00be, 0x0005,
+	0x0096, 0x00b6, 0x0026, 0x9016, 0x080c, 0xbda3, 0x00d6, 0x2069,
+	0x197d, 0x2d04, 0x9005, 0x0168, 0x6010, 0x2058, 0xb8a0, 0x9086,
+	0x007e, 0x1138, 0x2069, 0x1820, 0x2d04, 0x8000, 0x206a, 0x00de,
+	0x0010, 0x00de, 0x0088, 0x9006, 0x080c, 0x66bb, 0x2001, 0x0002,
+	0x080c, 0x66cf, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x942f,
+	0x080c, 0x98bf, 0x0804, 0xbd2d, 0x080c, 0xcc16, 0x01b0, 0x6014,
+	0x2048, 0xa864, 0x2010, 0x9086, 0x0139, 0x1138, 0x6007, 0x0016,
+	0x2001, 0x0002, 0x080c, 0xd277, 0x00b0, 0x6014, 0x2048, 0xa864,
+	0xd0fc, 0x0118, 0x2001, 0x0001, 0x0ca8, 0x2001, 0x180e, 0x2004,
+	0xd0dc, 0x0148, 0x6010, 0x2058, 0xb840, 0x9084, 0x00ff, 0x9005,
+	0x1110, 0x9006, 0x0c38, 0x080c, 0xb91f, 0x2009, 0x026e, 0x2134,
+	0x96b4, 0x00ff, 0x9686, 0x0005, 0x0520, 0x9686, 0x000b, 0x01c8,
+	0x2009, 0x026f, 0x2104, 0x9084, 0xff00, 0x1118, 0x9686, 0x0009,
+	0x01c0, 0x9086, 0x1900, 0x1168, 0x9686, 0x0009, 0x0190, 0x2001,
+	0x0004, 0x080c, 0x66cf, 0x2001, 0x0028, 0x601a, 0x6007, 0x0052,
+	0x0020, 0x2001, 0x0001, 0x080c, 0xbb99, 0x002e, 0x00be, 0x009e,
+	0x0005, 0x9286, 0x0139, 0x0160, 0x6014, 0x2048, 0x080c, 0xcc16,
+	0x0140, 0xa864, 0x9086, 0x0139, 0x0118, 0xa868, 0xd0fc, 0x0108,
+	0x0c40, 0x6010, 0x2058, 0xb840, 0x9084, 0x00ff, 0x9005, 0x0138,
+	0x8001, 0xb842, 0x601b, 0x000a, 0x6007, 0x0016, 0x08f0, 0xb8a0,
+	0x9086, 0x007e, 0x1138, 0x00e6, 0x2071, 0x1800, 0x080c, 0x6111,
+	0x00ee, 0x0010, 0x080c, 0x3310, 0x0860, 0x2001, 0x0004, 0x080c,
+	0x66cf, 0x080c, 0xbda3, 0x1140, 0x6003, 0x0001, 0x6007, 0x0003,
+	0x080c, 0x942f, 0x0804, 0x98bf, 0x080c, 0xb91f, 0x9006, 0x0804,
+	0xbb99, 0x0489, 0x1160, 0x2001, 0x0008, 0x080c, 0x66cf, 0x6003,
+	0x0001, 0x6007, 0x0005, 0x080c, 0x942f, 0x0804, 0x98bf, 0x2001,
+	0x0001, 0x0804, 0xbb99, 0x00f9, 0x1160, 0x2001, 0x000a, 0x080c,
+	0x66cf, 0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x942f, 0x0804,
+	0x98bf, 0x2001, 0x0001, 0x0804, 0xbb99, 0x2009, 0x026e, 0x2104,
+	0x9086, 0x0003, 0x1138, 0x2009, 0x026f, 0x2104, 0x9084, 0xff00,
+	0x9086, 0x2a00, 0x0005, 0x9085, 0x0001, 0x0005, 0x00b6, 0x00c6,
+	0x0016, 0x6110, 0x2158, 0x080c, 0x6798, 0x001e, 0x00ce, 0x00be,
+	0x0005, 0x00b6, 0x00f6, 0x00e6, 0x00d6, 0x0036, 0x0016, 0x6010,
+	0x2058, 0x2009, 0x1837, 0x2104, 0x9085, 0x0003, 0x200a, 0x080c,
+	0xbe49, 0x0560, 0x2009, 0x1837, 0x2104, 0xc0cd, 0x200a, 0x080c,
+	0x6bd1, 0x0158, 0x9006, 0x2020, 0x2009, 0x002a, 0x080c, 0xe72a,
+	0x2001, 0x180c, 0x200c, 0xc195, 0x2102, 0x2019, 0x002a, 0x2009,
+	0x0001, 0x080c, 0x32d5, 0x00e6, 0x2071, 0x1800, 0x080c, 0x30e1,
+	0x00ee, 0x00c6, 0x0156, 0x20a9, 0x0781, 0x2009, 0x007f, 0x080c,
+	0x3419, 0x8108, 0x1f04, 0xbde7, 0x015e, 0x00ce, 0x080c, 0xbda6,
+	0x2071, 0x0260, 0x2079, 0x0200, 0x7817, 0x0001, 0x2001, 0x1837,
+	0x200c, 0xc1c5, 0x7018, 0xd0fc, 0x0110, 0xd0dc, 0x0118, 0x7038,
+	0xd0dc, 0x1108, 0xc1c4, 0x7817, 0x0000, 0x2001, 0x1837, 0x2102,
+	0x2079, 0x0100, 0x2e04, 0x9084, 0x00ff, 0x2069, 0x181f, 0x206a,
+	0x78e6, 0x0006, 0x8e70, 0x2e04, 0x2069, 0x1820, 0x206a, 0x78ea,
+	0x7832, 0x7836, 0x2010, 0x9084, 0xff00, 0x001e, 0x9105, 0x2009,
+	0x182c, 0x200a, 0x2200, 0x9084, 0x00ff, 0x2008, 0x080c, 0x26eb,
+	0x080c, 0x76a5, 0x0170, 0x2071, 0x0260, 0x2069, 0x1983, 0x7048,
+	0x206a, 0x704c, 0x6806, 0x7050, 0x680a, 0x7054, 0x680e, 0x080c,
+	0xd043, 0x0040, 0x2001, 0x0006, 0x080c, 0x66cf, 0x080c, 0x333f,
+	0x080c, 0xaf2e, 0x001e, 0x003e, 0x00de, 0x00ee, 0x00fe, 0x00be,
+	0x0005, 0x0096, 0x0026, 0x0036, 0x00e6, 0x0156, 0x2019, 0x182c,
+	0x231c, 0x83ff, 0x01f0, 0x2071, 0x0260, 0x7200, 0x9294, 0x00ff,
+	0x7004, 0x9084, 0xff00, 0x9205, 0x9306, 0x1198, 0x2011, 0x0276,
+	0x20a9, 0x0004, 0x2b48, 0x2019, 0x000a, 0x080c, 0xbf3e, 0x1148,
+	0x2011, 0x027a, 0x20a9, 0x0004, 0x2019, 0x0006, 0x080c, 0xbf3e,
+	0x1100, 0x015e, 0x00ee, 0x003e, 0x002e, 0x009e, 0x0005, 0x00e6,
+	0x2071, 0x0260, 0x7034, 0x9086, 0x0014, 0x11a8, 0x7038, 0x9086,
+	0x0800, 0x1188, 0x703c, 0xd0ec, 0x0160, 0x9084, 0x0f00, 0x9086,
+	0x0100, 0x1138, 0x7054, 0xd0a4, 0x1110, 0xd0ac, 0x0110, 0x9006,
+	0x0010, 0x9085, 0x0001, 0x00ee, 0x0005, 0x00e6, 0x0096, 0x00c6,
+	0x0076, 0x0056, 0x0046, 0x0026, 0x0006, 0x0126, 0x2091, 0x8000,
+	0x2029, 0x19f5, 0x252c, 0x2021, 0x19fc, 0x2424, 0x2061, 0x1ddc,
+	0x2071, 0x1800, 0x7254, 0x7074, 0x9202, 0x1a04, 0xbf0a, 0x080c,
+	0x8d8f, 0x0904, 0xbf03, 0x080c, 0xe75b, 0x0904, 0xbf03, 0x6720,
+	0x9786, 0x0007, 0x0904, 0xbf03, 0x2500, 0x9c06, 0x0904, 0xbf03,
+	0x2400, 0x9c06, 0x0904, 0xbf03, 0x3e08, 0x9186, 0x0002, 0x1148,
+	0x6010, 0x9005, 0x0130, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc,
+	0x1590, 0x00c6, 0x6043, 0xffff, 0x6000, 0x9086, 0x0004, 0x1110,
+	0x080c, 0x1afc, 0x9786, 0x000a, 0x0148, 0x080c, 0xce2d, 0x1130,
+	0x00ce, 0x080c, 0xb91f, 0x080c, 0xaf69, 0x00e8, 0x6014, 0x2048,
+	0x080c, 0xcc16, 0x01a8, 0x9786, 0x0003, 0x1530, 0xa867, 0x0103,
+	0xa87c, 0xd0cc, 0x0130, 0x0096, 0xa878, 0x2048, 0x080c, 0x100b,
+	0x009e, 0xab7a, 0xa877, 0x0000, 0x080c, 0x6f0d, 0x080c, 0xce07,
+	0x080c, 0xaf69, 0x00ce, 0x9ce0, 0x001c, 0x7068, 0x9c02, 0x1210,
+	0x0804, 0xbeaa, 0x012e, 0x000e, 0x002e, 0x004e, 0x005e, 0x007e,
+	0x00ce, 0x009e, 0x00ee, 0x0005, 0x9786, 0x0006, 0x1118, 0x080c,
+	0xe6cd, 0x0c30, 0x9786, 0x0009, 0x1148, 0x6000, 0x9086, 0x0004,
+	0x0d08, 0x2009, 0x004c, 0x080c, 0xafcc, 0x08e0, 0x9786, 0x000a,
+	0x0980, 0x0820, 0x220c, 0x2304, 0x9106, 0x1130, 0x8210, 0x8318,
+	0x1f04, 0xbf2a, 0x9006, 0x0005, 0x2304, 0x9102, 0x0218, 0x2001,
+	0x0001, 0x0008, 0x9006, 0x918d, 0x0001, 0x0005, 0x0136, 0x01c6,
+	0x0016, 0x8906, 0x8006, 0x8007, 0x908c, 0x003f, 0x21e0, 0x9084,
+	0xffc0, 0x9300, 0x2098, 0x3518, 0x20a9, 0x0001, 0x220c, 0x4002,
+	0x910e, 0x1140, 0x8210, 0x8319, 0x1dc8, 0x9006, 0x001e, 0x01ce,
+	0x013e, 0x0005, 0x220c, 0x9102, 0x0218, 0x2001, 0x0001, 0x0010,
+	0x2001, 0x0000, 0x918d, 0x0001, 0x001e, 0x01ce, 0x013e, 0x0005,
+	0x220c, 0x810f, 0x2304, 0x9106, 0x1130, 0x8210, 0x8318, 0x1f04,
+	0xbf68, 0x9006, 0x0005, 0x918d, 0x0001, 0x0005, 0x6004, 0x908a,
+	0x0053, 0x1a0c, 0x0d85, 0x080c, 0xce1c, 0x0120, 0x080c, 0xce2d,
+	0x0158, 0x0028, 0x080c, 0x333f, 0x080c, 0xce2d, 0x0128, 0x080c,
+	0x97fe, 0x080c, 0xaf2e, 0x0005, 0x080c, 0xb91f, 0x0cc0, 0x9182,
+	0x0057, 0x1220, 0x9182, 0x0040, 0x0208, 0x000a, 0x0005, 0xbfae,
+	0xbfae, 0xbfae, 0xbfae, 0xbfae, 0xbfae, 0xbfae, 0xbfae, 0xbfae,
+	0xbfae, 0xbfae, 0xbfb0, 0xbfb0, 0xbfb0, 0xbfb0, 0xbfae, 0xbfae,
+	0xbfae, 0xbfb0, 0xbfae, 0xbfae, 0xbfae, 0xbfae, 0x080c, 0x0d85,
+	0x600b, 0xffff, 0x6003, 0x000f, 0x6106, 0x0126, 0x2091, 0x8000,
+	0x080c, 0xd356, 0x2009, 0x8000, 0x080c, 0x9428, 0x012e, 0x0005,
+	0x9186, 0x0013, 0x1128, 0x6004, 0x9082, 0x0040, 0x0804, 0xc038,
+	0x9186, 0x0027, 0x1520, 0x080c, 0x97fe, 0x080c, 0x3310, 0x080c,
+	0xd353, 0x0096, 0x6114, 0x2148, 0x080c, 0xcc16, 0x0198, 0x080c,
+	0xce2d, 0x1118, 0x080c, 0xb91f, 0x0068, 0xa867, 0x0103, 0xa87b,
+	0x0029, 0xa877, 0x0000, 0xa97c, 0xc1c5, 0xa97e, 0x080c, 0x6f19,
+	0x080c, 0xce07, 0x009e, 0x080c, 0xaf2e, 0x0804, 0x98bf, 0x9186,
+	0x0014, 0x1120, 0x6004, 0x9082, 0x0040, 0x0030, 0x9186, 0x0053,
+	0x0110, 0x080c, 0x0d85, 0x0005, 0x0002, 0xc016, 0xc014, 0xc014,
+	0xc014, 0xc014, 0xc014, 0xc014, 0xc014, 0xc014, 0xc014, 0xc014,
+	0xc02f, 0xc02f, 0xc02f, 0xc02f, 0xc014, 0xc02f, 0xc014, 0xc02f,
+	0xc014, 0xc014, 0xc014, 0xc014, 0x080c, 0x0d85, 0x080c, 0x97fe,
+	0x0096, 0x6114, 0x2148, 0x080c, 0xcc16, 0x0168, 0xa867, 0x0103,
+	0xa87b, 0x0006, 0xa877, 0x0000, 0xa880, 0xc0ec, 0xa882, 0x080c,
+	0x6f19, 0x080c, 0xce07, 0x009e, 0x080c, 0xaf2e, 0x0005, 0x080c,
+	0x97fe, 0x080c, 0xce2d, 0x090c, 0xb91f, 0x080c, 0xaf2e, 0x0005,
+	0x0002, 0xc052, 0xc050, 0xc050, 0xc050, 0xc050, 0xc050, 0xc050,
+	0xc050, 0xc050, 0xc050, 0xc050, 0xc054, 0xc054, 0xc054, 0xc054,
+	0xc050, 0xc056, 0xc050, 0xc054, 0xc050, 0xc050, 0xc050, 0xc050,
+	0x080c, 0x0d85, 0x080c, 0x0d85, 0x080c, 0x0d85, 0x080c, 0xaf2e,
+	0x0804, 0x98bf, 0x9182, 0x0057, 0x1220, 0x9182, 0x0040, 0x0208,
+	0x000a, 0x0005, 0xc079, 0xc079, 0xc079, 0xc079, 0xc079, 0xc0b2,
+	0xc1a1, 0xc079, 0xc1ad, 0xc079, 0xc079, 0xc079, 0xc079, 0xc079,
+	0xc079, 0xc079, 0xc079, 0xc079, 0xc079, 0xc1ad, 0xc07b, 0xc079,
+	0xc1ab, 0x080c, 0x0d85, 0x00b6, 0x0096, 0x6114, 0x2148, 0x6010,
+	0x2058, 0xb800, 0xd0bc, 0x1508, 0xa87b, 0x0000, 0xa867, 0x0103,
+	0xa877, 0x0000, 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938, 0x9115,
+	0x190c, 0xc232, 0x080c, 0x6d2e, 0x6210, 0x2258, 0xba3c, 0x82ff,
+	0x0110, 0x8211, 0xba3e, 0xb8d0, 0x9005, 0x0110, 0x080c, 0x68b4,
+	0x080c, 0xaf2e, 0x009e, 0x00be, 0x0005, 0xa87c, 0xd0ac, 0x09e0,
+	0xa838, 0xa934, 0x9105, 0x09c0, 0xa880, 0xd0bc, 0x19a8, 0x080c,
+	0xcf62, 0x0c80, 0x00b6, 0x0096, 0x6114, 0x2148, 0x601c, 0xd0fc,
+	0x1110, 0x7644, 0x0008, 0x9036, 0x96b4, 0x0fff, 0x86ff, 0x1590,
+	0x6010, 0x2058, 0xb800, 0xd0bc, 0x1904, 0xc190, 0xa87b, 0x0000,
+	0xa867, 0x0103, 0xae76, 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938,
+	0x9115, 0x190c, 0xc232, 0x080c, 0x6d2e, 0x6210, 0x2258, 0xba3c,
+	0x82ff, 0x0110, 0x8211, 0xba3e, 0xb8d0, 0x9005, 0x0110, 0x080c,
+	0x68b4, 0x601c, 0xd0fc, 0x1148, 0x7044, 0xd0e4, 0x1904, 0xc174,
+	0x080c, 0xaf2e, 0x009e, 0x00be, 0x0005, 0x2009, 0x0211, 0x210c,
+	0x080c, 0x0d85, 0x968c, 0x0c00, 0x0150, 0x6010, 0x2058, 0xb800,
+	0xd0bc, 0x1904, 0xc178, 0x7348, 0xab92, 0x734c, 0xab8e, 0x968c,
+	0x00ff, 0x9186, 0x0002, 0x0508, 0x9186, 0x0028, 0x1118, 0xa87b,
+	0x001c, 0x00e8, 0xd6dc, 0x01a0, 0xa87b, 0x0015, 0xa87c, 0xd0ac,
+	0x0170, 0xa938, 0xaa34, 0x2100, 0x9205, 0x0148, 0x7048, 0x9106,
+	0x1118, 0x704c, 0x9206, 0x0118, 0xa992, 0xaa8e, 0xc6dc, 0x0038,
+	0xd6d4, 0x0118, 0xa87b, 0x0007, 0x0010, 0xa87b, 0x0000, 0xa867,
+	0x0103, 0xae76, 0x901e, 0xd6c4, 0x01d8, 0x9686, 0x0100, 0x1130,
+	0x7064, 0x9005, 0x1118, 0xc6c4, 0x0804, 0xc0be, 0x735c, 0xab86,
+	0x83ff, 0x0170, 0x938a, 0x0009, 0x0210, 0x2019, 0x0008, 0x0036,
+	0x2308, 0x2019, 0x0018, 0x2011, 0x0025, 0x080c, 0xc794, 0x003e,
+	0xd6cc, 0x0904, 0xc0d3, 0x7154, 0xa98a, 0x81ff, 0x0904, 0xc0d3,
+	0x9192, 0x0021, 0x1278, 0x8304, 0x9098, 0x0018, 0x2011, 0x0029,
+	0x080c, 0xc794, 0x2011, 0x0205, 0x2013, 0x0000, 0x080c, 0xd2e3,
+	0x0804, 0xc0d3, 0xa868, 0xd0fc, 0x0120, 0x2009, 0x0020, 0xa98a,
+	0x0c50, 0x00a6, 0x2950, 0x080c, 0xc733, 0x00ae, 0x080c, 0xd2e3,
+	0x080c, 0xc784, 0x0804, 0xc0d5, 0x080c, 0xcf25, 0x0804, 0xc0ea,
+	0xa87c, 0xd0ac, 0x0904, 0xc0fb, 0xa880, 0xd0bc, 0x1904, 0xc0fb,
+	0x7348, 0xa838, 0x9306, 0x11c8, 0x734c, 0xa834, 0x931e, 0x0904,
+	0xc0fb, 0xd6d4, 0x0190, 0xab38, 0x9305, 0x0904, 0xc0fb, 0x0068,
+	0xa87c, 0xd0ac, 0x0904, 0xc0c6, 0xa838, 0xa934, 0x9105, 0x0904,
+	0xc0c6, 0xa880, 0xd0bc, 0x1904, 0xc0c6, 0x080c, 0xcf62, 0x0804,
+	0xc0ea, 0x00f6, 0x2079, 0x026c, 0x7c04, 0x7b00, 0x7e0c, 0x7d08,
+	0x00fe, 0x0021, 0x0005, 0x0011, 0x0005, 0x0005, 0x0096, 0x6003,
+	0x0002, 0x6007, 0x0043, 0x6014, 0x2048, 0xa87c, 0xd0ac, 0x0128,
+	0x009e, 0x0005, 0x2130, 0x2228, 0x0058, 0x2400, 0xa9ac, 0x910a,
+	0x2300, 0xaab0, 0x9213, 0x2600, 0x9102, 0x2500, 0x9203, 0x0e90,
+	0xac46, 0xab4a, 0xae36, 0xad3a, 0x6044, 0xd0fc, 0x190c, 0xab09,
+	0x604b, 0x0000, 0x080c, 0x1cbd, 0x1118, 0x6144, 0x080c, 0x9454,
+	0x009e, 0x0005, 0x9182, 0x0057, 0x1220, 0x9182, 0x0040, 0x0208,
+	0x000a, 0x0005, 0xc1f9, 0xc1f9, 0xc1f9, 0xc1f9, 0xc1f9, 0xc1f9,
+	0xc1f9, 0xc1f9, 0xc1f9, 0xc1f9, 0xc1fb, 0xc1f9, 0xc1f9, 0xc1f9,
+	0xc1f9, 0xc20c, 0xc1f9, 0xc1f9, 0xc1f9, 0xc1f9, 0xc230, 0xc1f9,
+	0xc1f9, 0x080c, 0x0d85, 0x6004, 0x9086, 0x0040, 0x1110, 0x080c,
+	0x97fe, 0x2019, 0x0001, 0x080c, 0xa380, 0x6003, 0x0002, 0x080c,
+	0xd35b, 0x080c, 0x9859, 0x0005, 0x6004, 0x9086, 0x0040, 0x1110,
+	0x080c, 0x97fe, 0x2019, 0x0001, 0x080c, 0xa380, 0x080c, 0x9859,
+	0x080c, 0x3310, 0x080c, 0xd353, 0x0096, 0x6114, 0x2148, 0x080c,
+	0xcc16, 0x0150, 0xa867, 0x0103, 0xa87b, 0x0029, 0xa877, 0x0000,
+	0x080c, 0x6f19, 0x080c, 0xce07, 0x009e, 0x080c, 0xaf2e, 0x0005,
+	0x080c, 0x0d85, 0xa87b, 0x0015, 0xd1fc, 0x0180, 0xa87b, 0x0007,
+	0x8002, 0x8000, 0x810a, 0x9189, 0x0000, 0x0006, 0x0016, 0x2009,
+	0x1a7d, 0x2104, 0x8000, 0x200a, 0x001e, 0x000e, 0xa992, 0xa88e,
+	0x0005, 0x9182, 0x0057, 0x1220, 0x9182, 0x0040, 0x0208, 0x000a,
+	0x0005, 0xc268, 0xc268, 0xc268, 0xc268, 0xc268, 0xc26a, 0xc268,
+	0xc268, 0xc327, 0xc268, 0xc268, 0xc268, 0xc268, 0xc268, 0xc268,
+	0xc268, 0xc268, 0xc268, 0xc268, 0xc467, 0xc268, 0xc471, 0xc268,
+	0x080c, 0x0d85, 0x601c, 0xd0bc, 0x0178, 0xd084, 0x0168, 0xd0f4,
+	0x0120, 0xc084, 0x601e, 0x0804, 0xc05a, 0x6114, 0x0096, 0x2148,
+	0xa87c, 0xc0e5, 0xa87e, 0x009e, 0x0076, 0x00a6, 0x00e6, 0x0096,
+	0x2071, 0x0260, 0x6114, 0x2150, 0x601c, 0xd0fc, 0x1110, 0x7644,
+	0x0008, 0x9036, 0xb676, 0x96b4, 0x0fff, 0xb77c, 0xc7e5, 0xb77e,
+	0x6210, 0x00b6, 0x2258, 0xba3c, 0x82ff, 0x0110, 0x8211, 0xba3e,
+	0x00be, 0x86ff, 0x0904, 0xc320, 0x9694, 0xff00, 0x9284, 0x0c00,
+	0x0120, 0x7048, 0xb092, 0x704c, 0xb08e, 0x9284, 0x0300, 0x0904,
+	0xc320, 0x9686, 0x0100, 0x1130, 0x7064, 0x9005, 0x1118, 0xc6c4,
+	0xb676, 0x0c38, 0x080c, 0x1059, 0x090c, 0x0d85, 0x2900, 0xb07a,
+	0xb77c, 0x97bd, 0x0200, 0xb77e, 0xa867, 0x0103, 0xb068, 0xa86a,
+	0xb06c, 0xa86e, 0xb070, 0xa872, 0x7044, 0x9084, 0xf000, 0x9635,
+	0xae76, 0x968c, 0x0c00, 0x0120, 0x7348, 0xab92, 0x734c, 0xab8e,
+	0x968c, 0x00ff, 0x9186, 0x0002, 0x0180, 0x9186, 0x0028, 0x1118,
+	0xa87b, 0x001c, 0x0060, 0xd6dc, 0x0118, 0xa87b, 0x0015, 0x0038,
+	0xd6d4, 0x0118, 0xa87b, 0x0007, 0x0010, 0xa87b, 0x0000, 0xaf7e,
+	0xb080, 0xa882, 0xb084, 0xa886, 0x901e, 0xd6c4, 0x0190, 0x735c,
+	0xab86, 0x83ff, 0x0170, 0x938a, 0x0009, 0x0210, 0x2019, 0x0008,
+	0x0036, 0x2308, 0x2019, 0x0018, 0x2011, 0x0025, 0x080c, 0xc794,
+	0x003e, 0xd6cc, 0x01e8, 0x7154, 0xa98a, 0x81ff, 0x01c8, 0x9192,
+	0x0021, 0x1260, 0x8304, 0x9098, 0x0018, 0x2011, 0x0029, 0x080c,
+	0xc794, 0x2011, 0x0205, 0x2013, 0x0000, 0x0050, 0xb068, 0xd0fc,
+	0x0120, 0x2009, 0x0020, 0xa98a, 0x0c68, 0x2950, 0x080c, 0xc733,
+	0x080c, 0x1ac8, 0x009e, 0x00ee, 0x00ae, 0x007e, 0x0005, 0x2001,
+	0x1989, 0x2004, 0x604a, 0x0096, 0x6114, 0x2148, 0xa83c, 0xa940,
+	0x9105, 0x1118, 0xa87c, 0xc0dc, 0xa87e, 0x6003, 0x0002, 0x080c,
+	0xd364, 0x0904, 0xc462, 0x604b, 0x0000, 0x6010, 0x00b6, 0x2058,
+	0xb800, 0x00be, 0xd0bc, 0x1500, 0xd1cc, 0x0904, 0xc426, 0xa978,
+	0xa868, 0xd0fc, 0x0904, 0xc3e7, 0x0016, 0xa87c, 0x0006, 0xa880,
+	0x0006, 0x00a6, 0x2150, 0xb174, 0x9184, 0x00ff, 0x90b6, 0x0002,
+	0x0904, 0xc3b4, 0x9086, 0x0028, 0x1904, 0xc3a0, 0xa87b, 0x001c,
+	0xb07b, 0x001c, 0x0804, 0xc3bc, 0x6024, 0xd0f4, 0x11d0, 0xa838,
+	0xaa34, 0x9205, 0x09c8, 0xa838, 0xaa90, 0x9206, 0x1120, 0xa88c,
+	0xaa34, 0x9206, 0x0988, 0x6024, 0xd0d4, 0x1148, 0xa9ac, 0xa834,
+	0x9102, 0x603a, 0xa9b0, 0xa838, 0x9103, 0x603e, 0x6024, 0xc0f5,
+	0x6026, 0x6010, 0x00b6, 0x2058, 0xb83c, 0x8000, 0xb83e, 0x00be,
+	0x601c, 0xc0fc, 0x601e, 0x9006, 0xa876, 0xa892, 0xa88e, 0xa87c,
+	0xc0e4, 0xa87e, 0xd0cc, 0x0140, 0xc0cc, 0xa87e, 0x0096, 0xa878,
+	0x2048, 0x080c, 0x100b, 0x009e, 0x080c, 0xcf62, 0x0804, 0xc462,
+	0xd1dc, 0x0158, 0xa87b, 0x0015, 0xb07b, 0x0015, 0x080c, 0xd203,
+	0x0118, 0xb174, 0xc1dc, 0xb176, 0x0078, 0xd1d4, 0x0128, 0xa87b,
+	0x0007, 0xb07b, 0x0007, 0x0040, 0xa87c, 0xd0ac, 0x0128, 0xa834,
+	0xa938, 0x9115, 0x190c, 0xc232, 0xa87c, 0xb07e, 0xa890, 0xb092,
+	0xa88c, 0xb08e, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0019, 0x20a0,
+	0x20a9, 0x0020, 0x8a06, 0x8006, 0x8007, 0x9094, 0x003f, 0x22e0,
+	0x9084, 0xffc0, 0x9080, 0x0019, 0x2098, 0x4003, 0x00ae, 0x000e,
+	0xa882, 0x000e, 0xc0cc, 0xa87e, 0x080c, 0xd2e3, 0x001e, 0xa874,
+	0x0006, 0x2148, 0x080c, 0x100b, 0x001e, 0x0804, 0xc453, 0x0016,
+	0x00a6, 0x2150, 0xb174, 0x9184, 0x00ff, 0x90b6, 0x0002, 0x01e0,
+	0x9086, 0x0028, 0x1128, 0xa87b, 0x001c, 0xb07b, 0x001c, 0x00e0,
+	0xd1dc, 0x0158, 0xa87b, 0x0015, 0xb07b, 0x0015, 0x080c, 0xd203,
+	0x0118, 0xb174, 0xc1dc, 0xb176, 0x0078, 0xd1d4, 0x0128, 0xa87b,
+	0x0007, 0xb07b, 0x0007, 0x0040, 0xa87c, 0xd0ac, 0x0128, 0xa834,
+	0xa938, 0x9115, 0x190c, 0xc232, 0xa890, 0xb092, 0xa88c, 0xb08e,
+	0xa87c, 0xb07e, 0x00ae, 0x080c, 0x100b, 0x009e, 0x080c, 0xd2e3,
+	0xa974, 0x0016, 0x080c, 0xc784, 0x001e, 0x0468, 0xa867, 0x0103,
+	0xa974, 0x9184, 0x00ff, 0x90b6, 0x0002, 0x01b0, 0x9086, 0x0028,
+	0x1118, 0xa87b, 0x001c, 0x00d0, 0xd1dc, 0x0148, 0xa87b, 0x0015,
+	0x080c, 0xd203, 0x0118, 0xa974, 0xc1dc, 0xa976, 0x0078, 0xd1d4,
+	0x0118, 0xa87b, 0x0007, 0x0050, 0xa87b, 0x0000, 0xa87c, 0xd0ac,
+	0x0128, 0xa834, 0xa938, 0x9115, 0x190c, 0xc232, 0xa974, 0x0016,
+	0x080c, 0x6d2e, 0x001e, 0x6010, 0x00b6, 0x2058, 0xba3c, 0xb8d0,
+	0x0016, 0x9005, 0x190c, 0x68b4, 0x001e, 0x00be, 0xd1e4, 0x1120,
+	0x080c, 0xaf2e, 0x009e, 0x0005, 0x080c, 0xcf25, 0x0cd8, 0x6114,
+	0x0096, 0x2148, 0xa97c, 0x080c, 0xd364, 0x190c, 0x1ae8, 0x009e,
+	0x0005, 0x0096, 0x6114, 0x2148, 0xa83c, 0xa940, 0x9105, 0x01e8,
+	0xa877, 0x0000, 0xa87b, 0x0000, 0xa867, 0x0103, 0x00b6, 0x6010,
+	0x2058, 0xa834, 0xa938, 0x9115, 0x11a0, 0x080c, 0x6d2e, 0xba3c,
+	0x8211, 0x0208, 0xba3e, 0xb8d0, 0x9005, 0x0110, 0x080c, 0x68b4,
+	0x080c, 0xaf2e, 0x00be, 0x009e, 0x0005, 0xa87c, 0xc0dc, 0xa87e,
+	0x08f8, 0xb800, 0xd0bc, 0x1120, 0xa834, 0x080c, 0xc232, 0x0c28,
+	0xa880, 0xd0bc, 0x1dc8, 0x080c, 0xcf62, 0x0c60, 0x080c, 0x97fe,
+	0x0010, 0x080c, 0x9859, 0x601c, 0xd084, 0x0110, 0x080c, 0x1afc,
+	0x080c, 0xcc16, 0x01f0, 0x0096, 0x6114, 0x2148, 0x080c, 0xce2d,
+	0x1118, 0x080c, 0xb91f, 0x00a0, 0xa867, 0x0103, 0x2009, 0x180c,
+	0x210c, 0xd18c, 0x1198, 0xd184, 0x1170, 0x6108, 0xa97a, 0x918e,
+	0x0029, 0x1110, 0x080c, 0xea83, 0xa877, 0x0000, 0x080c, 0x6f19,
+	0x009e, 0x0804, 0xaf69, 0xa87b, 0x0004, 0x0cb0, 0xa87b, 0x0004,
+	0x0c98, 0x9182, 0x0057, 0x1220, 0x9182, 0x0040, 0x0208, 0x000a,
+	0x0005, 0xc4f8, 0xc4f8, 0xc4f8, 0xc4f8, 0xc4f8, 0xc4fa, 0xc4f8,
+	0xc4f8, 0xc4f8, 0xc4f8, 0xc4f8, 0xc4f8, 0xc4f8, 0xc4f8, 0xc4f8,
+	0xc4f8, 0xc4f8, 0xc4f8, 0xc4f8, 0xc4f8, 0xc51e, 0xc4f8, 0xc4f8,
+	0x080c, 0x0d85, 0x080c, 0x582e, 0x01f8, 0x6014, 0x7144, 0x918c,
+	0x0fff, 0x9016, 0xd1c4, 0x0118, 0x7264, 0x9294, 0x00ff, 0x0096,
+	0x904d, 0x0188, 0xa87b, 0x0000, 0xa864, 0x9086, 0x0139, 0x0128,
+	0xa867, 0x0103, 0xa976, 0xaa96, 0x0030, 0xa897, 0x4000, 0xa99a,
+	0xaa9e, 0x080c, 0x6f19, 0x009e, 0x0804, 0xaf2e, 0x080c, 0x582e,
+	0x0dd8, 0x6014, 0x900e, 0x9016, 0x0c10, 0x9182, 0x0085, 0x0002,
+	0xc537, 0xc535, 0xc535, 0xc543, 0xc535, 0xc535, 0xc535, 0xc535,
+	0xc535, 0xc535, 0xc535, 0xc535, 0xc535, 0x080c, 0x0d85, 0x6003,
+	0x0001, 0x6106, 0x0126, 0x2091, 0x8000, 0x2009, 0x8020, 0x080c,
+	0x9428, 0x012e, 0x0005, 0x0026, 0x0056, 0x00d6, 0x00e6, 0x2071,
+	0x0260, 0x7224, 0x6216, 0x7220, 0x080c, 0xcc04, 0x01f8, 0x2268,
+	0x6800, 0x9086, 0x0000, 0x01d0, 0x6010, 0x6d10, 0x952e, 0x11b0,
+	0x00c6, 0x2d60, 0x00d6, 0x080c, 0xc7f5, 0x00de, 0x00ce, 0x0158,
+	0x702c, 0xd084, 0x1118, 0x080c, 0xc7bf, 0x0010, 0x6803, 0x0002,
+	0x6007, 0x0086, 0x0028, 0x080c, 0xc7e1, 0x0d90, 0x6007, 0x0087,
+	0x6003, 0x0001, 0x2009, 0x8020, 0x080c, 0x9428, 0x7220, 0x080c,
+	0xcc04, 0x0178, 0x6810, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc,
+	0x0140, 0x6824, 0xd0ec, 0x0128, 0x00c6, 0x2d60, 0x080c, 0xcf62,
+	0x00ce, 0x00ee, 0x00de, 0x005e, 0x002e, 0x0005, 0x9186, 0x0013,
+	0x1160, 0x6004, 0x908a, 0x0085, 0x0a0c, 0x0d85, 0x908a, 0x0092,
+	0x1a0c, 0x0d85, 0x9082, 0x0085, 0x00e2, 0x9186, 0x0027, 0x0120,
+	0x9186, 0x0014, 0x190c, 0x0d85, 0x080c, 0x97fe, 0x0096, 0x6014,
+	0x2048, 0x080c, 0xcc16, 0x0140, 0xa867, 0x0103, 0xa877, 0x0000,
+	0xa87b, 0x0029, 0x080c, 0x6f19, 0x009e, 0x080c, 0xaf69, 0x0804,
+	0x98bf, 0xc5c6, 0xc5c8, 0xc5c8, 0xc5c6, 0xc5c6, 0xc5c6, 0xc5c6,
+	0xc5c6, 0xc5c6, 0xc5c6, 0xc5c6, 0xc5c6, 0xc5c6, 0x080c, 0x0d85,
+	0x080c, 0xaf69, 0x0005, 0x9186, 0x0013, 0x1130, 0x6004, 0x9082,
+	0x0085, 0x2008, 0x0804, 0xc617, 0x9186, 0x0027, 0x1558, 0x080c,
+	0x97fe, 0x080c, 0x3310, 0x080c, 0xd353, 0x0096, 0x6014, 0x2048,
+	0x080c, 0xcc16, 0x0150, 0xa867, 0x0103, 0xa877, 0x0000, 0xa87b,
+	0x0029, 0x080c, 0x6f19, 0x080c, 0xce07, 0x009e, 0x080c, 0xaf2e,
+	0x0005, 0x9186, 0x0089, 0x0118, 0x9186, 0x008a, 0x1140, 0x080c,
+	0xad2d, 0x0128, 0x9086, 0x000c, 0x0904, 0xc64f, 0x0000, 0x080c,
+	0xafe9, 0x0c70, 0x9186, 0x0014, 0x1d60, 0x080c, 0x97fe, 0x0096,
+	0x6014, 0x2048, 0x080c, 0xcc16, 0x0d00, 0xa867, 0x0103, 0xa877,
+	0x0000, 0xa87b, 0x0006, 0xa880, 0xc0ec, 0xa882, 0x0890, 0x0002,
+	0xc627, 0xc625, 0xc625, 0xc625, 0xc625, 0xc625, 0xc63b, 0xc625,
+	0xc625, 0xc625, 0xc625, 0xc625, 0xc625, 0x080c, 0x0d85, 0x6034,
+	0x908c, 0xff00, 0x810f, 0x9186, 0x0039, 0x0118, 0x9186, 0x0035,
+	0x1118, 0x2001, 0x1987, 0x0010, 0x2001, 0x1988, 0x2004, 0x601a,
+	0x6003, 0x000c, 0x0005, 0x6034, 0x908c, 0xff00, 0x810f, 0x9186,
+	0x0039, 0x0118, 0x9186, 0x0035, 0x1118, 0x2001, 0x1987, 0x0010,
+	0x2001, 0x1988, 0x2004, 0x601a, 0x6003, 0x000e, 0x0005, 0x9182,
+	0x0092, 0x1220, 0x9182, 0x0085, 0x0208, 0x0012, 0x0804, 0xafe9,
+	0xc665, 0xc665, 0xc665, 0xc665, 0xc667, 0xc6b4, 0xc665, 0xc665,
+	0xc665, 0xc665, 0xc665, 0xc665, 0xc665, 0x080c, 0x0d85, 0x0096,
+	0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x0168, 0x6034,
+	0x908c, 0xff00, 0x810f, 0x9186, 0x0039, 0x0118, 0x9186, 0x0035,
+	0x1118, 0x009e, 0x0804, 0xc6c8, 0x080c, 0xcc16, 0x1118, 0x080c,
+	0xce07, 0x0068, 0x6014, 0x2048, 0x080c, 0xd36a, 0x1110, 0x080c,
+	0xce07, 0xa867, 0x0103, 0x080c, 0xd31e, 0x080c, 0x6f19, 0x00d6,
+	0x2c68, 0x080c, 0xaed8, 0x01d0, 0x6003, 0x0001, 0x6007, 0x001e,
+	0x600b, 0xffff, 0x2009, 0x026e, 0x210c, 0x613a, 0x2009, 0x026f,
+	0x210c, 0x613e, 0x6910, 0x6112, 0x080c, 0xd0b1, 0x695c, 0x615e,
+	0x6023, 0x0001, 0x2009, 0x8020, 0x080c, 0x9428, 0x2d60, 0x00de,
+	0x080c, 0xaf2e, 0x009e, 0x0005, 0x6010, 0x00b6, 0x2058, 0xb800,
+	0x00be, 0xd0bc, 0x05a0, 0x6034, 0x908c, 0xff00, 0x810f, 0x9186,
+	0x0035, 0x0130, 0x9186, 0x001e, 0x0118, 0x9186, 0x0039, 0x1538,
+	0x00d6, 0x2c68, 0x080c, 0xd2b6, 0x11f0, 0x080c, 0xaed8, 0x01d8,
+	0x6106, 0x6003, 0x0001, 0x6023, 0x0001, 0x6910, 0x6112, 0x692c,
+	0x612e, 0x6930, 0x6132, 0x6934, 0x918c, 0x00ff, 0x6136, 0x6938,
+	0x613a, 0x693c, 0x613e, 0x695c, 0x615e, 0x080c, 0xd0b1, 0x2009,
+	0x8020, 0x080c, 0x9428, 0x2d60, 0x00de, 0x0804, 0xaf2e, 0x0096,
+	0x6014, 0x2048, 0x080c, 0xcc16, 0x01c8, 0xa867, 0x0103, 0xa880,
+	0xd0b4, 0x0128, 0xc0ec, 0xa882, 0xa87b, 0x0006, 0x0048, 0xd0bc,
+	0x0118, 0xa87b, 0x0002, 0x0020, 0xa87b, 0x0005, 0x080c, 0xcf21,
+	0xa877, 0x0000, 0x080c, 0x6f19, 0x080c, 0xce07, 0x009e, 0x0804,
+	0xaf2e, 0x0016, 0x0096, 0x6014, 0x2048, 0x080c, 0xcc16, 0x0140,
+	0xa867, 0x0103, 0xa87b, 0x0028, 0xa877, 0x0000, 0x080c, 0x6f19,
+	0x009e, 0x001e, 0x9186, 0x0013, 0x0158, 0x9186, 0x0014, 0x0130,
+	0x9186, 0x0027, 0x0118, 0x080c, 0xafe9, 0x0020, 0x080c, 0x97fe,
+	0x080c, 0xaf69, 0x0005, 0x0056, 0x0066, 0x0096, 0x00a6, 0x2029,
+	0x0001, 0x9182, 0x0101, 0x1208, 0x0010, 0x2009, 0x0100, 0x2130,
+	0x8304, 0x9098, 0x0018, 0x2009, 0x0020, 0x2011, 0x0029, 0x080c,
+	0xc794, 0x96b2, 0x0020, 0xb004, 0x904d, 0x0110, 0x080c, 0x100b,
+	0x080c, 0x1059, 0x0520, 0x8528, 0xa867, 0x0110, 0xa86b, 0x0000,
+	0x2920, 0xb406, 0x968a, 0x003d, 0x1228, 0x2608, 0x2011, 0x001b,
+	0x0499, 0x00a8, 0x96b2, 0x003c, 0x2009, 0x003c, 0x2950, 0x2011,
+	0x001b, 0x0451, 0x0c28, 0x2001, 0x0205, 0x2003, 0x0000, 0x00ae,
+	0x852f, 0x95ad, 0x0003, 0xb566, 0x95ac, 0x0000, 0x0048, 0x2001,
 	0x0205, 0x2003, 0x0000, 0x00ae, 0x852f, 0x95ad, 0x0003, 0xb566,
-	0x95ac, 0x0000, 0x0048, 0x2001, 0x0205, 0x2003, 0x0000, 0x00ae,
-	0x852f, 0x95ad, 0x0003, 0xb566, 0x009e, 0x006e, 0x005e, 0x0005,
-	0x00a6, 0x89ff, 0x0158, 0xa804, 0x9055, 0x0130, 0xa807, 0x0000,
-	0x080c, 0x6dee, 0x2a48, 0x0cb8, 0x080c, 0x6dee, 0x00ae, 0x0005,
-	0x00f6, 0x2079, 0x0200, 0x7814, 0x9085, 0x0080, 0x7816, 0xd184,
-	0x0108, 0x8108, 0x810c, 0x20a9, 0x0001, 0xa860, 0x20e8, 0xa85c,
-	0x9200, 0x20a0, 0x20e1, 0x0000, 0x2300, 0x9e00, 0x2098, 0x4003,
-	0x8318, 0x9386, 0x0020, 0x1148, 0x2018, 0x2300, 0x9e00, 0x2098,
-	0x7814, 0x8000, 0x9085, 0x0080, 0x7816, 0x8109, 0x1d80, 0x7817,
-	0x0000, 0x00fe, 0x0005, 0x6920, 0x9186, 0x0003, 0x0118, 0x9186,
-	0x0002, 0x11d0, 0x00c6, 0x00d6, 0x00e6, 0x2d60, 0x0096, 0x6014,
-	0x2048, 0x080c, 0xc97a, 0x0150, 0x2001, 0x0006, 0xa980, 0xc1d5,
-	0x080c, 0x7022, 0x080c, 0x6de2, 0x080c, 0xcb6b, 0x009e, 0x080c,
-	0xaceb, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x00c6, 0x702c, 0xd084,
-	0x1170, 0x6008, 0x2060, 0x6020, 0x9086, 0x0002, 0x1140, 0x6104,
-	0x9186, 0x0085, 0x0118, 0x9186, 0x008b, 0x1108, 0x9006, 0x00ce,
-	0x0005, 0x0066, 0x0126, 0x2091, 0x8000, 0x2031, 0x0001, 0x6020,
-	0x9084, 0x000f, 0x0083, 0x012e, 0x006e, 0x0005, 0x0126, 0x2091,
-	0x8000, 0x0066, 0x2031, 0x0000, 0x6020, 0x9084, 0x000f, 0x001b,
-	0x006e, 0x012e, 0x0005, 0xc5ab, 0xc5ab, 0xc5a6, 0xc5cf, 0xc583,
-	0xc5a6, 0xc585, 0xc5a6, 0xc583, 0x9173, 0xc5a6, 0xc5a6, 0xc5a6,
-	0xc583, 0xc583, 0xc583, 0x080c, 0x0d7d, 0x6010, 0x9080, 0x0000,
-	0x2004, 0xd0bc, 0x190c, 0xc5cf, 0x0036, 0x6014, 0x0096, 0x2048,
-	0xa880, 0x009e, 0xd0cc, 0x0118, 0x2019, 0x000c, 0x0038, 0xd094,
-	0x0118, 0x2019, 0x000d, 0x0010, 0x2019, 0x0010, 0x080c, 0xdfa1,
-	0x6023, 0x0006, 0x6003, 0x0007, 0x003e, 0x0005, 0x9006, 0x0005,
-	0x9085, 0x0001, 0x0005, 0x0096, 0x86ff, 0x11e8, 0x6014, 0x2048,
-	0x080c, 0xc97a, 0x01d0, 0x6043, 0xffff, 0xa864, 0x9086, 0x0139,
-	0x1128, 0xa87b, 0x0005, 0xa883, 0x0000, 0x0028, 0x900e, 0x2001,
-	0x0005, 0x080c, 0x7022, 0x080c, 0xcc85, 0x080c, 0x6de2, 0x080c,
-	0xaceb, 0x9085, 0x0001, 0x009e, 0x0005, 0x9006, 0x0ce0, 0x080c,
-	0xa91e, 0x080c, 0xd0d5, 0x6000, 0x908a, 0x0016, 0x1a0c, 0x0d7d,
-	0x002b, 0x0106, 0x080c, 0xa93a, 0x010e, 0x0005, 0xc5ee, 0xc61e,
-	0xc5f0, 0xc645, 0xc619, 0xc5ee, 0xc5a6, 0xc5ab, 0xc5ab, 0xc5a6,
-	0xc5a6, 0xc5a6, 0xc5a6, 0xc5a6, 0xc5a6, 0xc5a6, 0x080c, 0x0d7d,
-	0x86ff, 0x1520, 0x6020, 0x9086, 0x0006, 0x0500, 0x0096, 0x6014,
-	0x2048, 0x080c, 0xc97a, 0x0168, 0xa87c, 0xd0cc, 0x0140, 0x0096,
-	0xc0cc, 0xa87e, 0xa878, 0x2048, 0x080c, 0x0ff9, 0x009e, 0x080c,
-	0xcc85, 0x009e, 0x080c, 0xd055, 0x6007, 0x0085, 0x6003, 0x000b,
-	0x6023, 0x0002, 0x2009, 0x8020, 0x080c, 0x9292, 0x9085, 0x0001,
-	0x0005, 0x0066, 0x080c, 0x1ac5, 0x006e, 0x0890, 0x00e6, 0x2071,
-	0x19e6, 0x7030, 0x9c06, 0x1120, 0x080c, 0xa138, 0x00ee, 0x0840,
-	0x6020, 0x9084, 0x000f, 0x9086, 0x0006, 0x1150, 0x0086, 0x0096,
-	0x2049, 0x0001, 0x2c40, 0x080c, 0xa28c, 0x009e, 0x008e, 0x0040,
-	0x0066, 0x080c, 0xa034, 0x190c, 0x0d7d, 0x080c, 0xa042, 0x006e,
-	0x00ee, 0x1904, 0xc5f0, 0x0804, 0xc5a6, 0x0036, 0x00e6, 0x2071,
-	0x19e6, 0x704c, 0x9c06, 0x1138, 0x901e, 0x080c, 0xa1b8, 0x00ee,
-	0x003e, 0x0804, 0xc5f0, 0x080c, 0xa3c3, 0x00ee, 0x003e, 0x1904,
-	0xc5f0, 0x0804, 0xc5a6, 0x00c6, 0x0066, 0x6020, 0x9084, 0x000f,
-	0x001b, 0x006e, 0x00ce, 0x0005, 0xc67b, 0xc74a, 0xc8b4, 0xc683,
-	0xaceb, 0xc67b, 0xdf93, 0xd0bd, 0xc74a, 0x913a, 0xc940, 0xc674,
-	0xc674, 0xc674, 0xc674, 0xc674, 0x080c, 0x0d7d, 0x080c, 0xcb91,
-	0x1110, 0x080c, 0xb693, 0x0005, 0x080c, 0x967a, 0x0804, 0xacb0,
-	0x601b, 0x0001, 0x0005, 0x080c, 0xc97a, 0x0130, 0x6014, 0x0096,
-	0x2048, 0x2c00, 0xa896, 0x009e, 0x080c, 0xa91e, 0x080c, 0xd0d5,
-	0x6000, 0x908a, 0x0016, 0x1a0c, 0x0d7d, 0x0013, 0x0804, 0xa93a,
-	0xc6a8, 0xc6aa, 0xc6d4, 0xc6e8, 0xc715, 0xc6a8, 0xc67b, 0xc67b,
-	0xc67b, 0xc6ef, 0xc6ef, 0xc6a8, 0xc6a8, 0xc6a8, 0xc6a8, 0xc6f9,
-	0x080c, 0x0d7d, 0x00e6, 0x6014, 0x0096, 0x2048, 0xa880, 0xc0b5,
-	0xa882, 0x009e, 0x2071, 0x19e6, 0x7030, 0x9c06, 0x01d0, 0x0066,
-	0x080c, 0xa034, 0x190c, 0x0d7d, 0x080c, 0xa042, 0x006e, 0x080c,
-	0xd055, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002, 0x2001,
-	0x1986, 0x2004, 0x601a, 0x2009, 0x8020, 0x080c, 0x9292, 0x00ee,
-	0x0005, 0x601b, 0x0001, 0x0cd8, 0x0096, 0x6014, 0x2048, 0xa880,
-	0xc0b5, 0xa882, 0x009e, 0x080c, 0xd055, 0x6007, 0x0085, 0x6003,
-	0x000b, 0x6023, 0x0002, 0x2009, 0x8020, 0x080c, 0x9292, 0x0005,
-	0x080c, 0xa91e, 0x080c, 0xaab5, 0x080c, 0xa93a, 0x0c28, 0x0096,
-	0x601b, 0x0001, 0x6014, 0x2048, 0xa880, 0xc0b5, 0xa882, 0x009e,
-	0x0005, 0x080c, 0x5746, 0x01b8, 0x6014, 0x0096, 0x904d, 0x0190,
-	0xa864, 0xa867, 0x0103, 0xa87b, 0x0006, 0x9086, 0x0139, 0x1150,
-	0xa867, 0x0139, 0xa87b, 0x0030, 0xa897, 0x4005, 0xa89b, 0x0004,
-	0x080c, 0x6dee, 0x009e, 0x0804, 0xacb0, 0x6014, 0x0096, 0x904d,
-	0x0560, 0xa97c, 0xd1e4, 0x1158, 0x611c, 0xd1fc, 0x0530, 0x6110,
-	0x00b6, 0x2158, 0xb93c, 0x8109, 0x0208, 0xb93e, 0x00be, 0x080c,
-	0xa93a, 0x2001, 0x180f, 0x2004, 0xd0c4, 0x0110, 0x009e, 0x0005,
-	0xa884, 0x009e, 0x8003, 0x800b, 0x810b, 0x9108, 0x611a, 0x2001,
-	0x0037, 0x2c08, 0x080c, 0x16a0, 0x6000, 0x9086, 0x0004, 0x1120,
-	0x2009, 0x0048, 0x080c, 0xad4d, 0x0005, 0x009e, 0x080c, 0x1ac5,
-	0x0804, 0xc6d4, 0x6000, 0x908a, 0x0016, 0x1a0c, 0x0d7d, 0x000b,
-	0x0005, 0xc761, 0xc680, 0xc763, 0xc761, 0xc763, 0xc763, 0xc67c,
-	0xc761, 0xc676, 0xc676, 0xc761, 0xc761, 0xc761, 0xc761, 0xc761,
-	0xc761, 0x080c, 0x0d7d, 0x6010, 0x00b6, 0x2058, 0xb804, 0x9084,
-	0x00ff, 0x00be, 0x908a, 0x000c, 0x1a0c, 0x0d7d, 0x00b6, 0x0013,
-	0x00be, 0x0005, 0xc77e, 0xc84b, 0xc780, 0xc7c0, 0xc780, 0xc7c0,
-	0xc780, 0xc78e, 0xc77e, 0xc7c0, 0xc77e, 0xc7af, 0x080c, 0x0d7d,
-	0x6004, 0x908e, 0x0016, 0x05c0, 0x908e, 0x0004, 0x05a8, 0x908e,
-	0x0002, 0x0590, 0x908e, 0x0052, 0x0904, 0xc847, 0x6004, 0x080c,
-	0xcb91, 0x0904, 0xc864, 0x908e, 0x0004, 0x1110, 0x080c, 0x326f,
-	0x908e, 0x0021, 0x0904, 0xc868, 0x908e, 0x0022, 0x0904, 0xc8af,
-	0x908e, 0x003d, 0x0904, 0xc868, 0x908e, 0x0039, 0x0904, 0xc86c,
-	0x908e, 0x0035, 0x0904, 0xc86c, 0x908e, 0x001e, 0x0178, 0x908e,
-	0x0001, 0x1140, 0x6010, 0x2058, 0xb804, 0x9084, 0x00ff, 0x9086,
-	0x0006, 0x0110, 0x080c, 0x3240, 0x080c, 0xb693, 0x0804, 0xaceb,
-	0x00c6, 0x00d6, 0x6104, 0x9186, 0x0016, 0x0904, 0xc838, 0x9186,
-	0x0002, 0x1904, 0xc80d, 0x2001, 0x1837, 0x2004, 0xd08c, 0x11c8,
-	0x080c, 0x753d, 0x11b0, 0x080c, 0xd09b, 0x0138, 0x080c, 0x7560,
-	0x1120, 0x080c, 0x7448, 0x0804, 0xc898, 0x2001, 0x197c, 0x2003,
-	0x0001, 0x2001, 0x1800, 0x2003, 0x0001, 0x080c, 0x746e, 0x0804,
-	0xc898, 0x6010, 0x2058, 0x2001, 0x1837, 0x2004, 0xd0ac, 0x1904,
-	0xc898, 0xb8a0, 0x9084, 0xff80, 0x1904, 0xc898, 0xb840, 0x9084,
-	0x00ff, 0x9005, 0x0190, 0x8001, 0xb842, 0x6017, 0x0000, 0x6023,
-	0x0007, 0x601b, 0x0398, 0x604b, 0x0000, 0x080c, 0xac5a, 0x0128,
-	0x2b00, 0x6012, 0x6023, 0x0001, 0x0458, 0x00de, 0x00ce, 0x6004,
-	0x908e, 0x0002, 0x11a0, 0x6010, 0x2058, 0xb8a0, 0x9086, 0x007e,
-	0x1170, 0x2009, 0x1837, 0x2104, 0xc085, 0x200a, 0x00e6, 0x2071,
-	0x1800, 0x080c, 0x6025, 0x00ee, 0x080c, 0xb693, 0x0030, 0x080c,
-	0xb693, 0x080c, 0x3240, 0x080c, 0xd0b0, 0x00e6, 0x0126, 0x2091,
-	0x8000, 0x080c, 0x326f, 0x012e, 0x00ee, 0x080c, 0xaceb, 0x0005,
-	0x2001, 0x0002, 0x080c, 0x65e3, 0x6003, 0x0001, 0x6007, 0x0002,
-	0x080c, 0x92b7, 0x080c, 0x9738, 0x00de, 0x00ce, 0x0c80, 0x080c,
-	0x326f, 0x0804, 0xc7bc, 0x00c6, 0x00d6, 0x6104, 0x9186, 0x0016,
-	0x0d38, 0x6010, 0x2058, 0xb840, 0x9084, 0x00ff, 0x9005, 0x0904,
-	0xc80d, 0x8001, 0xb842, 0x6003, 0x0001, 0x080c, 0x92b7, 0x080c,
-	0x9738, 0x00de, 0x00ce, 0x0898, 0x080c, 0xb693, 0x0804, 0xc7be,
-	0x080c, 0xb6cf, 0x0804, 0xc7be, 0x00d6, 0x2c68, 0x6104, 0x080c,
-	0xd013, 0x00de, 0x0118, 0x080c, 0xacb0, 0x0408, 0x6004, 0x8007,
-	0x6134, 0x918c, 0x00ff, 0x9105, 0x6036, 0x6007, 0x0085, 0x6003,
-	0x000b, 0x6023, 0x0002, 0x603c, 0x600a, 0x2001, 0x1986, 0x2004,
-	0x601a, 0x602c, 0x2c08, 0x2060, 0x6024, 0xd0b4, 0x0108, 0xc085,
-	0xc0b5, 0x6026, 0x2160, 0x2009, 0x8020, 0x080c, 0x92b0, 0x0005,
-	0x00de, 0x00ce, 0x080c, 0xb693, 0x080c, 0x3240, 0x00e6, 0x0126,
-	0x2091, 0x8000, 0x080c, 0x326f, 0x6017, 0x0000, 0x6023, 0x0007,
-	0x601b, 0x0398, 0x604b, 0x0000, 0x012e, 0x00ee, 0x0005, 0x080c,
-	0xb0eb, 0x1904, 0xc864, 0x0005, 0x6000, 0x908a, 0x0016, 0x1a0c,
-	0x0d7d, 0x0096, 0x00d6, 0x001b, 0x00de, 0x009e, 0x0005, 0xc8cf,
-	0xc8cf, 0xc8cf, 0xc8cf, 0xc8cf, 0xc8cf, 0xc8cf, 0xc8cf, 0xc8cf,
-	0xc67b, 0xc8cf, 0xc680, 0xc8d1, 0xc680, 0xc8eb, 0xc8cf, 0x080c,
-	0x0d7d, 0x6004, 0x9086, 0x008b, 0x01b0, 0x6034, 0x908c, 0xff00,
-	0x810f, 0x9186, 0x0035, 0x1130, 0x602c, 0x9080, 0x0009, 0x200c,
-	0xc185, 0x2102, 0x6007, 0x008b, 0x6003, 0x000d, 0x2009, 0x8020,
-	0x080c, 0x92b0, 0x0005, 0x080c, 0xd08f, 0x0118, 0x080c, 0xd0a2,
-	0x0010, 0x080c, 0xd0b0, 0x080c, 0xcb6b, 0x080c, 0xc97a, 0x0570,
-	0x080c, 0x3240, 0x080c, 0xc97a, 0x0168, 0x6014, 0x2048, 0xa867,
-	0x0103, 0xa87b, 0x0006, 0xa877, 0x0000, 0xa880, 0xc0ed, 0xa882,
-	0x080c, 0x6dee, 0x2c68, 0x080c, 0xac5a, 0x0150, 0x6810, 0x6012,
-	0x080c, 0xce15, 0x00c6, 0x2d60, 0x080c, 0xaceb, 0x00ce, 0x0008,
-	0x2d60, 0x6017, 0x0000, 0x6023, 0x0001, 0x6007, 0x0001, 0x6003,
-	0x0001, 0x080c, 0x92b7, 0x080c, 0x9738, 0x00c8, 0x080c, 0xd08f,
-	0x0138, 0x6034, 0x9086, 0x4000, 0x1118, 0x080c, 0x3240, 0x08d0,
-	0x6034, 0x908c, 0xff00, 0x810f, 0x9186, 0x0039, 0x0118, 0x9186,
-	0x0035, 0x1118, 0x080c, 0x3240, 0x0868, 0x080c, 0xaceb, 0x0005,
-	0x6000, 0x908a, 0x0016, 0x1a0c, 0x0d7d, 0x0002, 0xc956, 0xc956,
-	0xc958, 0xc958, 0xc958, 0xc956, 0xc956, 0xaceb, 0xc956, 0xc956,
-	0xc956, 0xc956, 0xc956, 0xc956, 0xc956, 0xc956, 0x080c, 0x0d7d,
-	0x080c, 0xa91e, 0x080c, 0xaab5, 0x080c, 0xa93a, 0x6114, 0x0096,
-	0x2148, 0xa87b, 0x0006, 0x080c, 0x6dee, 0x009e, 0x0804, 0xacb0,
-	0x9284, 0x0003, 0x1158, 0x9282, 0x1ddc, 0x0240, 0x2001, 0x181a,
-	0x2004, 0x9202, 0x1218, 0x9085, 0x0001, 0x0005, 0x9006, 0x0ce8,
-	0x0096, 0x0028, 0x0096, 0x0006, 0x6014, 0x2048, 0x000e, 0x0006,
-	0x9984, 0xf000, 0x9086, 0xf000, 0x0110, 0x080c, 0x10f2, 0x000e,
-	0x009e, 0x0005, 0x00e6, 0x00c6, 0x0036, 0x0006, 0x0126, 0x2091,
-	0x8000, 0x2061, 0x1ddc, 0x2071, 0x1800, 0x7354, 0x7074, 0x9302,
-	0x1640, 0x6020, 0x9206, 0x11f8, 0x080c, 0xd09b, 0x0180, 0x9286,
-	0x0001, 0x1168, 0x6004, 0x9086, 0x0004, 0x1148, 0x080c, 0x3240,
-	0x080c, 0xd0b0, 0x00c6, 0x080c, 0xaceb, 0x00ce, 0x0060, 0x080c,
-	0xcd87, 0x0148, 0x080c, 0xcb91, 0x1110, 0x080c, 0xb693, 0x00c6,
-	0x080c, 0xacb0, 0x00ce, 0x9ce0, 0x001c, 0x7068, 0x9c02, 0x1208,
-	0x08a0, 0x012e, 0x000e, 0x003e, 0x00ce, 0x00ee, 0x0005, 0x00e6,
-	0x00c6, 0x0016, 0x9188, 0x1000, 0x210c, 0x81ff, 0x0128, 0x2061,
-	0x1b34, 0x6112, 0x080c, 0x3240, 0x9006, 0x0010, 0x9085, 0x0001,
-	0x001e, 0x00ce, 0x00ee, 0x0005, 0x00c6, 0x0126, 0x2091, 0x8000,
-	0x080c, 0xac5a, 0x01b0, 0x665e, 0x2b00, 0x6012, 0x080c, 0x5746,
-	0x0118, 0x080c, 0xcaad, 0x0168, 0x080c, 0xce15, 0x6023, 0x0003,
-	0x2009, 0x004b, 0x080c, 0xad4d, 0x9085, 0x0001, 0x012e, 0x00ce,
-	0x0005, 0x9006, 0x0cd8, 0x00c6, 0x0126, 0x2091, 0x8000, 0xbaa0,
-	0x080c, 0xad20, 0x0580, 0x605f, 0x0000, 0x2b00, 0x6012, 0x080c,
-	0xce15, 0x6023, 0x0003, 0x0016, 0x080c, 0xa91e, 0x080c, 0x943d,
-	0x0076, 0x903e, 0x080c, 0x9306, 0x2c08, 0x080c, 0xe167, 0x007e,
-	0x080c, 0xa93a, 0x001e, 0xd184, 0x0128, 0x080c, 0xacb0, 0x9085,
-	0x0001, 0x0070, 0x080c, 0x5746, 0x0128, 0xd18c, 0x1170, 0x080c,
-	0xcaad, 0x0148, 0x2009, 0x004c, 0x080c, 0xad4d, 0x9085, 0x0001,
-	0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x2900, 0x6016, 0x0c90,
-	0x2009, 0x004d, 0x0010, 0x2009, 0x004e, 0x00f6, 0x00c6, 0x0046,
-	0x0016, 0x080c, 0xac5a, 0x2c78, 0x05a0, 0x7e5e, 0x2b00, 0x7812,
-	0x7823, 0x0003, 0x0016, 0x2021, 0x0005, 0x080c, 0xcabf, 0x001e,
-	0x9186, 0x004d, 0x0118, 0x9186, 0x004e, 0x0148, 0x2001, 0x197f,
-	0x200c, 0xd1fc, 0x0168, 0x2f60, 0x080c, 0xacb0, 0x00d0, 0x2001,
-	0x197e, 0x200c, 0xd1fc, 0x0120, 0x2f60, 0x080c, 0xacb0, 0x0088,
-	0x2f60, 0x080c, 0x5746, 0x0138, 0xd18c, 0x1118, 0x04f1, 0x0148,
-	0x0010, 0x2900, 0x7816, 0x001e, 0x0016, 0x080c, 0xad4d, 0x9085,
-	0x0001, 0x001e, 0x004e, 0x00ce, 0x00fe, 0x0005, 0x00f6, 0x00c6,
-	0x0046, 0x080c, 0xac5a, 0x2c78, 0x0508, 0x7e5e, 0x2b00, 0x7812,
-	0x7823, 0x0003, 0x0096, 0x2021, 0x0004, 0x0489, 0x009e, 0x2001,
-	0x197d, 0x200c, 0xd1fc, 0x0120, 0x2f60, 0x080c, 0xacb0, 0x0060,
-	0x2f60, 0x080c, 0x5746, 0x0120, 0xd18c, 0x1160, 0x0071, 0x0130,
-	0x2009, 0x0052, 0x080c, 0xad4d, 0x9085, 0x0001, 0x004e, 0x00ce,
-	0x00fe, 0x0005, 0x2900, 0x7816, 0x0c98, 0x00c6, 0x080c, 0x4af2,
-	0x00ce, 0x1120, 0x080c, 0xacb0, 0x9006, 0x0005, 0xa867, 0x0000,
-	0xa86b, 0x8000, 0x2900, 0x6016, 0x9085, 0x0001, 0x0005, 0x0096,
-	0x0076, 0x0126, 0x2091, 0x8000, 0x080c, 0xa91e, 0x080c, 0x6875,
-	0x0158, 0x2001, 0xcac6, 0x0006, 0x900e, 0x2400, 0x080c, 0x7022,
-	0x080c, 0x6dee, 0x000e, 0x0807, 0x2418, 0x080c, 0x9640, 0xbaa0,
-	0x0086, 0x2041, 0x0001, 0x2039, 0x0001, 0x2608, 0x080c, 0x9457,
-	0x008e, 0x080c, 0x9306, 0x2f08, 0x2648, 0x080c, 0xe167, 0xb93c,
-	0x81ff, 0x090c, 0x9530, 0x080c, 0xa93a, 0x012e, 0x007e, 0x009e,
-	0x0005, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xac5a, 0x0190,
-	0x660a, 0x2b08, 0x6112, 0x080c, 0xce15, 0x6023, 0x0001, 0x2900,
-	0x6016, 0x2009, 0x001f, 0x080c, 0xad4d, 0x9085, 0x0001, 0x012e,
-	0x00ce, 0x0005, 0x9006, 0x0cd8, 0x00c6, 0x0126, 0x2091, 0x8000,
-	0x080c, 0xad20, 0x01b8, 0x660a, 0x2b08, 0x6112, 0x080c, 0xce15,
-	0x6023, 0x0008, 0x2900, 0x6016, 0x00f6, 0x2c78, 0x080c, 0x1778,
-	0x00fe, 0x2009, 0x0021, 0x080c, 0xad4d, 0x9085, 0x0001, 0x012e,
-	0x00ce, 0x0005, 0x9006, 0x0cd8, 0x2009, 0x003d, 0x00c6, 0x0126,
-	0x0016, 0x2091, 0x8000, 0x080c, 0xac5a, 0x0198, 0x660a, 0x2b08,
-	0x6112, 0x080c, 0xce15, 0x6023, 0x0001, 0x2900, 0x6016, 0x001e,
-	0x0016, 0x080c, 0xad4d, 0x9085, 0x0001, 0x001e, 0x012e, 0x00ce,
-	0x0005, 0x9006, 0x0cd0, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c,
-	0xad20, 0x0188, 0x2b08, 0x6112, 0x080c, 0xce15, 0x6023, 0x0001,
-	0x2900, 0x6016, 0x2009, 0x0000, 0x080c, 0xad4d, 0x9085, 0x0001,
-	0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x2009, 0x0044, 0x0830,
-	0x2009, 0x0049, 0x0818, 0x0026, 0x00b6, 0x6210, 0x2258, 0xba3c,
-	0x82ff, 0x0118, 0x8211, 0xba3e, 0x1140, 0xb8d0, 0x9005, 0x0128,
-	0xb888, 0x9005, 0x1110, 0xb88b, 0x0001, 0x00be, 0x002e, 0x0005,
-	0x0006, 0x0016, 0x6004, 0x908e, 0x0002, 0x0140, 0x908e, 0x0003,
-	0x0128, 0x908e, 0x0004, 0x0110, 0x9085, 0x0001, 0x001e, 0x000e,
-	0x0005, 0x0006, 0x0086, 0x0096, 0x6020, 0x9086, 0x0004, 0x01a8,
-	0x6014, 0x904d, 0x080c, 0xc97a, 0x0180, 0xa864, 0x9086, 0x0139,
-	0x0170, 0x6020, 0x90c6, 0x0003, 0x0140, 0x90c6, 0x0002, 0x0128,
-	0xa868, 0xd0fc, 0x0110, 0x9006, 0x0010, 0x9085, 0x0001, 0x009e,
-	0x008e, 0x000e, 0x0005, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c,
-	0xad20, 0x0198, 0x2b08, 0x6112, 0x080c, 0xce15, 0x6023, 0x0001,
-	0x2900, 0x6016, 0x080c, 0x3240, 0x2009, 0x0028, 0x080c, 0xad4d,
-	0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x9186,
-	0x0015, 0x11a8, 0x2011, 0x1824, 0x2204, 0x9086, 0x0074, 0x1178,
-	0x00b6, 0x080c, 0xb8e7, 0x00be, 0x080c, 0xbb0a, 0x6003, 0x0001,
-	0x6007, 0x0029, 0x080c, 0x92b7, 0x080c, 0x9738, 0x0078, 0x6014,
-	0x0096, 0x2048, 0xa868, 0x009e, 0xd0fc, 0x0148, 0x2001, 0x0001,
-	0x080c, 0xcfd4, 0x080c, 0xb693, 0x080c, 0xacb0, 0x0005, 0x0096,
-	0x6014, 0x904d, 0x090c, 0x0d7d, 0xa87b, 0x0030, 0xa883, 0x0000,
-	0xa897, 0x4005, 0xa89b, 0x0004, 0xa867, 0x0139, 0x0126, 0x2091,
-	0x8000, 0x080c, 0x6dee, 0x012e, 0x009e, 0x080c, 0xacb0, 0x0c30,
-	0x0096, 0x9186, 0x0016, 0x1128, 0x2001, 0x0004, 0x080c, 0x65e3,
-	0x00e8, 0x9186, 0x0015, 0x1510, 0x2011, 0x1824, 0x2204, 0x9086,
-	0x0014, 0x11e0, 0x6010, 0x00b6, 0x2058, 0x080c, 0x672e, 0x00be,
-	0x080c, 0xbbdb, 0x1198, 0x6010, 0x00b6, 0x2058, 0xb890, 0x00be,
-	0x9005, 0x0160, 0x2001, 0x0006, 0x080c, 0x65e3, 0x6014, 0x2048,
-	0xa868, 0xd0fc, 0x0170, 0x080c, 0xb0bf, 0x0048, 0x6014, 0x2048,
-	0xa868, 0xd0fc, 0x0528, 0x080c, 0xb693, 0x080c, 0xacb0, 0x009e,
-	0x0005, 0x6014, 0x6310, 0x2358, 0x904d, 0x090c, 0x0d7d, 0xa87b,
-	0x0000, 0xa883, 0x0000, 0xa897, 0x4000, 0x900e, 0x080c, 0x6986,
-	0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0xa99a, 0x0126,
-	0x2091, 0x8000, 0x080c, 0x6dee, 0x012e, 0x080c, 0xacb0, 0x08f8,
-	0x6014, 0x904d, 0x090c, 0x0d7d, 0xa87b, 0x0030, 0xa883, 0x0000,
-	0xa897, 0x4005, 0xa89b, 0x0004, 0xa867, 0x0139, 0x0126, 0x2091,
-	0x8000, 0x080c, 0x6dee, 0x012e, 0x080c, 0xacb0, 0x0840, 0xa878,
-	0x9086, 0x0005, 0x1108, 0x0009, 0x0005, 0xa880, 0xc0ad, 0xa882,
-	0x0005, 0x604b, 0x0000, 0x6017, 0x0000, 0x6003, 0x0001, 0x6007,
-	0x0050, 0x2009, 0x8023, 0x080c, 0x92b0, 0x0005, 0x00c6, 0x6010,
-	0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x0130, 0x0066, 0x6020,
-	0x9084, 0x000f, 0x001b, 0x006e, 0x00ce, 0x0005, 0xc67b, 0xccb8,
-	0xccb8, 0xccbb, 0xe494, 0xe4af, 0xe4b2, 0xc67b, 0xc67b, 0xc67b,
-	0xc67b, 0xc67b, 0xc67b, 0xc67b, 0xc67b, 0xc67b, 0x080c, 0x0d7d,
-	0xa001, 0xa001, 0x0005, 0x0096, 0x6014, 0x904d, 0x0118, 0xa87c,
-	0xd0e4, 0x1110, 0x009e, 0x0010, 0x009e, 0x0005, 0x6010, 0x00b6,
-	0x2058, 0xb800, 0x00be, 0xd0bc, 0x0550, 0x2001, 0x1834, 0x2004,
-	0x9005, 0x1540, 0x00f6, 0x2c78, 0x080c, 0xac5a, 0x0508, 0x7810,
-	0x6012, 0x080c, 0xce15, 0x7820, 0x9086, 0x0003, 0x0128, 0x7808,
-	0x603a, 0x2f00, 0x603e, 0x0020, 0x7808, 0x603e, 0x2f00, 0x603a,
-	0x602e, 0x6023, 0x0001, 0x6007, 0x0035, 0x6003, 0x0001, 0x795c,
-	0x615e, 0x2009, 0x8020, 0x080c, 0x92b0, 0x2f60, 0x00fe, 0x0005,
-	0x2f60, 0x00fe, 0x2001, 0x1987, 0x2004, 0x604a, 0x0005, 0x0016,
-	0x0096, 0x6814, 0x2048, 0x681c, 0xd0fc, 0xc0fc, 0x681e, 0xa87c,
-	0x1108, 0xd0e4, 0x0180, 0xc0e4, 0xa87e, 0xa877, 0x0000, 0xa893,
-	0x0000, 0xa88f, 0x0000, 0xd0cc, 0x0130, 0xc0cc, 0xa87e, 0xa878,
-	0x2048, 0x080c, 0x0ff9, 0x6830, 0x6036, 0x908e, 0x0001, 0x0148,
-	0x6803, 0x0002, 0x9086, 0x0005, 0x0170, 0x9006, 0x602e, 0x6032,
-	0x00d0, 0x681c, 0xc085, 0x681e, 0x6803, 0x0004, 0x6824, 0xc0f4,
-	0x9085, 0x0c00, 0x6826, 0x6814, 0x2048, 0xa8ac, 0x6938, 0x9102,
-	0xa8b0, 0x693c, 0x9103, 0x1e48, 0x683c, 0x602e, 0x6838, 0x9084,
-	0xfffc, 0x683a, 0x6032, 0x2d00, 0x603a, 0x6808, 0x603e, 0x6910,
-	0x6112, 0x695c, 0x615e, 0x6023, 0x0001, 0x6007, 0x0039, 0x6003,
-	0x0001, 0x2009, 0x8020, 0x080c, 0x92b0, 0x009e, 0x001e, 0x0005,
-	0x6024, 0xd0d4, 0x0510, 0xd0f4, 0x11f8, 0x6038, 0x940a, 0x603c,
-	0x9303, 0x0230, 0x9105, 0x0120, 0x6024, 0xc0d4, 0xc0f5, 0x0098,
-	0x643a, 0x633e, 0xac3e, 0xab42, 0x0046, 0x0036, 0x2400, 0xacac,
-	0x9402, 0xa836, 0x2300, 0xabb0, 0x9303, 0xa83a, 0x003e, 0x004e,
-	0x6024, 0xc0d4, 0x0000, 0x6026, 0x0005, 0xd0f4, 0x1138, 0xa83c,
-	0x603a, 0xa840, 0x603e, 0x6024, 0xc0f5, 0x6026, 0x0005, 0x0006,
-	0x0016, 0x6004, 0x908e, 0x0034, 0x01b8, 0x908e, 0x0035, 0x01a0,
-	0x908e, 0x0036, 0x0188, 0x908e, 0x0037, 0x0170, 0x908e, 0x0038,
-	0x0158, 0x908e, 0x0039, 0x0140, 0x908e, 0x003a, 0x0128, 0x908e,
-	0x003b, 0x0110, 0x9085, 0x0001, 0x001e, 0x000e, 0x0005, 0x0006,
-	0x0016, 0x0026, 0x0036, 0x00e6, 0x2001, 0x1981, 0x200c, 0x8000,
-	0x2014, 0x2001, 0x0032, 0x080c, 0x91f8, 0x2001, 0x1985, 0x82ff,
-	0x1110, 0x2011, 0x0014, 0x2202, 0x2001, 0x1983, 0x200c, 0x8000,
-	0x2014, 0x2071, 0x196b, 0x711a, 0x721e, 0x2001, 0x0064, 0x080c,
-	0x91f8, 0x2001, 0x1986, 0x82ff, 0x1110, 0x2011, 0x0014, 0x2202,
-	0x2001, 0x1987, 0x9288, 0x000a, 0x2102, 0x2001, 0x0017, 0x080c,
-	0xa90f, 0x2001, 0x1a8b, 0x2102, 0x2001, 0x0032, 0x080c, 0x16a0,
-	0x080c, 0x6abe, 0x00ee, 0x003e, 0x002e, 0x001e, 0x000e, 0x0005,
-	0x0006, 0x0016, 0x00e6, 0x2001, 0x1985, 0x2003, 0x0028, 0x2001,
-	0x1986, 0x2003, 0x0014, 0x2071, 0x196b, 0x701b, 0x0000, 0x701f,
-	0x07d0, 0x2001, 0x1987, 0x2009, 0x001e, 0x2102, 0x2001, 0x0017,
-	0x080c, 0xa90f, 0x2001, 0x1a8b, 0x2102, 0x2001, 0x0032, 0x080c,
-	0x16a0, 0x00ee, 0x001e, 0x000e, 0x0005, 0x0096, 0x6060, 0x904d,
-	0x0110, 0x080c, 0x1079, 0x009e, 0x0005, 0x0005, 0x00c6, 0x0126,
-	0x2091, 0x8000, 0x080c, 0xac5a, 0x0180, 0x2b08, 0x6112, 0x0ca9,
-	0x6023, 0x0001, 0x2900, 0x6016, 0x2009, 0x0033, 0x080c, 0xad4d,
-	0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x0096,
-	0x00e6, 0x00f6, 0x2071, 0x1800, 0x9186, 0x0015, 0x1500, 0x7090,
-	0x9086, 0x0018, 0x11e0, 0x6014, 0x2048, 0xaa3c, 0xd2e4, 0x1160,
-	0x2c78, 0x080c, 0x97f7, 0x01d8, 0x707c, 0xaa50, 0x9206, 0x1160,
+	0x009e, 0x006e, 0x005e, 0x0005, 0x00a6, 0x89ff, 0x0158, 0xa804,
+	0x9055, 0x0130, 0xa807, 0x0000, 0x080c, 0x6f19, 0x2a48, 0x0cb8,
+	0x080c, 0x6f19, 0x00ae, 0x0005, 0x00f6, 0x2079, 0x0200, 0x7814,
+	0x9085, 0x0080, 0x7816, 0xd184, 0x0108, 0x8108, 0x810c, 0x20a9,
+	0x0001, 0xa860, 0x20e8, 0xa85c, 0x9200, 0x20a0, 0x20e1, 0x0000,
+	0x2300, 0x9e00, 0x2098, 0x4003, 0x8318, 0x9386, 0x0020, 0x1148,
+	0x2018, 0x2300, 0x9e00, 0x2098, 0x7814, 0x8000, 0x9085, 0x0080,
+	0x7816, 0x8109, 0x1d80, 0x7817, 0x0000, 0x00fe, 0x0005, 0x6920,
+	0x9186, 0x0003, 0x0118, 0x9186, 0x0002, 0x11d0, 0x00c6, 0x00d6,
+	0x00e6, 0x2d60, 0x0096, 0x6014, 0x2048, 0x080c, 0xcc16, 0x0150,
+	0x2001, 0x0006, 0xa980, 0xc1d5, 0x080c, 0x7165, 0x080c, 0x6f0d,
+	0x080c, 0xce07, 0x009e, 0x080c, 0xaf69, 0x00ee, 0x00de, 0x00ce,
+	0x0005, 0x00c6, 0x702c, 0xd084, 0x1170, 0x6008, 0x2060, 0x6020,
+	0x9086, 0x0002, 0x1140, 0x6104, 0x9186, 0x0085, 0x0118, 0x9186,
+	0x008b, 0x1108, 0x9006, 0x00ce, 0x0005, 0x0066, 0x0126, 0x2091,
+	0x8000, 0x2031, 0x0001, 0x6020, 0x9084, 0x000f, 0x0083, 0x012e,
+	0x006e, 0x0005, 0x0126, 0x2091, 0x8000, 0x0066, 0x2031, 0x0000,
+	0x6020, 0x9084, 0x000f, 0x001b, 0x006e, 0x012e, 0x0005, 0xc847,
+	0xc847, 0xc842, 0xc86b, 0xc81f, 0xc842, 0xc821, 0xc842, 0xc81f,
+	0x92e7, 0xc842, 0xc842, 0xc842, 0xc81f, 0xc81f, 0xc81f, 0x080c,
+	0x0d85, 0x6010, 0x9080, 0x0000, 0x2004, 0xd0bc, 0x190c, 0xc86b,
+	0x0036, 0x6014, 0x0096, 0x2048, 0xa880, 0x009e, 0xd0cc, 0x0118,
+	0x2019, 0x000c, 0x0038, 0xd094, 0x0118, 0x2019, 0x000d, 0x0010,
+	0x2019, 0x0010, 0x080c, 0xe27a, 0x6023, 0x0006, 0x6003, 0x0007,
+	0x003e, 0x0005, 0x9006, 0x0005, 0x9085, 0x0001, 0x0005, 0x0096,
+	0x86ff, 0x11e8, 0x6014, 0x2048, 0x080c, 0xcc16, 0x01d0, 0x6043,
+	0xffff, 0xa864, 0x9086, 0x0139, 0x1128, 0xa87b, 0x0005, 0xa883,
+	0x0000, 0x0028, 0x900e, 0x2001, 0x0005, 0x080c, 0x7165, 0x080c,
+	0xcf21, 0x080c, 0x6f0d, 0x080c, 0xaf69, 0x9085, 0x0001, 0x009e,
+	0x0005, 0x9006, 0x0ce0, 0x080c, 0xaae0, 0x080c, 0xd378, 0x6000,
+	0x908a, 0x0016, 0x1a0c, 0x0d85, 0x002b, 0x0106, 0x080c, 0xaafc,
+	0x010e, 0x0005, 0xc88a, 0xc8ba, 0xc88c, 0xc8e1, 0xc8b5, 0xc88a,
+	0xc842, 0xc847, 0xc847, 0xc842, 0xc842, 0xc842, 0xc842, 0xc842,
+	0xc842, 0xc842, 0x080c, 0x0d85, 0x86ff, 0x1520, 0x6020, 0x9086,
+	0x0006, 0x0500, 0x0096, 0x6014, 0x2048, 0x080c, 0xcc16, 0x0168,
+	0xa87c, 0xd0cc, 0x0140, 0x0096, 0xc0cc, 0xa87e, 0xa878, 0x2048,
+	0x080c, 0x100b, 0x009e, 0x080c, 0xcf21, 0x009e, 0x080c, 0xd2f8,
+	0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002, 0x2009, 0x8020,
+	0x080c, 0x940a, 0x9085, 0x0001, 0x0005, 0x0066, 0x080c, 0x1afc,
+	0x006e, 0x0890, 0x00e6, 0x2071, 0x19e9, 0x7030, 0x9c06, 0x1120,
+	0x080c, 0xa300, 0x00ee, 0x0840, 0x6020, 0x9084, 0x000f, 0x9086,
+	0x0006, 0x1150, 0x0086, 0x0096, 0x2049, 0x0001, 0x2c40, 0x080c,
+	0xa44b, 0x009e, 0x008e, 0x0040, 0x0066, 0x080c, 0xa1fc, 0x190c,
+	0x0d85, 0x080c, 0xa20a, 0x006e, 0x00ee, 0x1904, 0xc88c, 0x0804,
+	0xc842, 0x0036, 0x00e6, 0x2071, 0x19e9, 0x704c, 0x9c06, 0x1138,
+	0x901e, 0x080c, 0xa380, 0x00ee, 0x003e, 0x0804, 0xc88c, 0x080c,
+	0xa585, 0x00ee, 0x003e, 0x1904, 0xc88c, 0x0804, 0xc842, 0x00c6,
+	0x0066, 0x6020, 0x9084, 0x000f, 0x001b, 0x006e, 0x00ce, 0x0005,
+	0xc917, 0xc9e6, 0xcb50, 0xc91f, 0xaf69, 0xc917, 0xe26c, 0xd360,
+	0xc9e6, 0x92ae, 0xcbdc, 0xc910, 0xc910, 0xc910, 0xc910, 0xc910,
+	0x080c, 0x0d85, 0x080c, 0xce2d, 0x1110, 0x080c, 0xb91f, 0x0005,
+	0x080c, 0x97fe, 0x0804, 0xaf2e, 0x601b, 0x0001, 0x0005, 0x080c,
+	0xcc16, 0x0130, 0x6014, 0x0096, 0x2048, 0x2c00, 0xa896, 0x009e,
+	0x080c, 0xaae0, 0x080c, 0xd378, 0x6000, 0x908a, 0x0016, 0x1a0c,
+	0x0d85, 0x0013, 0x0804, 0xaafc, 0xc944, 0xc946, 0xc970, 0xc984,
+	0xc9b1, 0xc944, 0xc917, 0xc917, 0xc917, 0xc98b, 0xc98b, 0xc944,
+	0xc944, 0xc944, 0xc944, 0xc995, 0x080c, 0x0d85, 0x00e6, 0x6014,
+	0x0096, 0x2048, 0xa880, 0xc0b5, 0xa882, 0x009e, 0x2071, 0x19e9,
+	0x7030, 0x9c06, 0x01d0, 0x0066, 0x080c, 0xa1fc, 0x190c, 0x0d85,
+	0x080c, 0xa20a, 0x006e, 0x080c, 0xd2f8, 0x6007, 0x0085, 0x6003,
+	0x000b, 0x6023, 0x0002, 0x2001, 0x1988, 0x2004, 0x601a, 0x2009,
+	0x8020, 0x080c, 0x940a, 0x00ee, 0x0005, 0x601b, 0x0001, 0x0cd8,
+	0x0096, 0x6014, 0x2048, 0xa880, 0xc0b5, 0xa882, 0x009e, 0x080c,
+	0xd2f8, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002, 0x2009,
+	0x8020, 0x080c, 0x940a, 0x0005, 0x080c, 0xaae0, 0x080c, 0xacaf,
+	0x080c, 0xaafc, 0x0c28, 0x0096, 0x601b, 0x0001, 0x6014, 0x2048,
+	0xa880, 0xc0b5, 0xa882, 0x009e, 0x0005, 0x080c, 0x582e, 0x01b8,
+	0x6014, 0x0096, 0x904d, 0x0190, 0xa864, 0xa867, 0x0103, 0xa87b,
+	0x0006, 0x9086, 0x0139, 0x1150, 0xa867, 0x0139, 0xa87b, 0x0030,
+	0xa897, 0x4005, 0xa89b, 0x0004, 0x080c, 0x6f19, 0x009e, 0x0804,
+	0xaf2e, 0x6014, 0x0096, 0x904d, 0x0560, 0xa97c, 0xd1e4, 0x1158,
+	0x611c, 0xd1fc, 0x0530, 0x6110, 0x00b6, 0x2158, 0xb93c, 0x8109,
+	0x0208, 0xb93e, 0x00be, 0x080c, 0xaafc, 0x2001, 0x180f, 0x2004,
+	0xd0c4, 0x0110, 0x009e, 0x0005, 0xa884, 0x009e, 0x8003, 0x800b,
+	0x810b, 0x9108, 0x611a, 0x2001, 0x0037, 0x2c08, 0x080c, 0x16b9,
+	0x6000, 0x9086, 0x0004, 0x1120, 0x2009, 0x0048, 0x080c, 0xafcc,
+	0x0005, 0x009e, 0x080c, 0x1afc, 0x0804, 0xc970, 0x6000, 0x908a,
+	0x0016, 0x1a0c, 0x0d85, 0x000b, 0x0005, 0xc9fd, 0xc91c, 0xc9ff,
+	0xc9fd, 0xc9ff, 0xc9ff, 0xc918, 0xc9fd, 0xc912, 0xc912, 0xc9fd,
+	0xc9fd, 0xc9fd, 0xc9fd, 0xc9fd, 0xc9fd, 0x080c, 0x0d85, 0x6010,
+	0x00b6, 0x2058, 0xb804, 0x9084, 0x00ff, 0x00be, 0x908a, 0x000c,
+	0x1a0c, 0x0d85, 0x00b6, 0x0013, 0x00be, 0x0005, 0xca1a, 0xcae7,
+	0xca1c, 0xca5c, 0xca1c, 0xca5c, 0xca1c, 0xca2a, 0xca1a, 0xca5c,
+	0xca1a, 0xca4b, 0x080c, 0x0d85, 0x6004, 0x908e, 0x0016, 0x05c0,
+	0x908e, 0x0004, 0x05a8, 0x908e, 0x0002, 0x0590, 0x908e, 0x0052,
+	0x0904, 0xcae3, 0x6004, 0x080c, 0xce2d, 0x0904, 0xcb00, 0x908e,
+	0x0004, 0x1110, 0x080c, 0x333f, 0x908e, 0x0021, 0x0904, 0xcb04,
+	0x908e, 0x0022, 0x0904, 0xcb4b, 0x908e, 0x003d, 0x0904, 0xcb04,
+	0x908e, 0x0039, 0x0904, 0xcb08, 0x908e, 0x0035, 0x0904, 0xcb08,
+	0x908e, 0x001e, 0x0178, 0x908e, 0x0001, 0x1140, 0x6010, 0x2058,
+	0xb804, 0x9084, 0x00ff, 0x9086, 0x0006, 0x0110, 0x080c, 0x3310,
+	0x080c, 0xb91f, 0x0804, 0xaf69, 0x00c6, 0x00d6, 0x6104, 0x9186,
+	0x0016, 0x0904, 0xcad4, 0x9186, 0x0002, 0x1904, 0xcaa9, 0x2001,
+	0x1837, 0x2004, 0xd08c, 0x11c8, 0x080c, 0x76a5, 0x11b0, 0x080c,
+	0xd33e, 0x0138, 0x080c, 0x76c8, 0x1120, 0x080c, 0x75ae, 0x0804,
+	0xcb34, 0x2001, 0x197e, 0x2003, 0x0001, 0x2001, 0x1800, 0x2003,
+	0x0001, 0x080c, 0x75d4, 0x0804, 0xcb34, 0x6010, 0x2058, 0x2001,
+	0x1837, 0x2004, 0xd0ac, 0x1904, 0xcb34, 0xb8a0, 0x9084, 0xff80,
+	0x1904, 0xcb34, 0xb840, 0x9084, 0x00ff, 0x9005, 0x0190, 0x8001,
+	0xb842, 0x6017, 0x0000, 0x6023, 0x0007, 0x601b, 0x0398, 0x604b,
+	0x0000, 0x080c, 0xaed8, 0x0128, 0x2b00, 0x6012, 0x6023, 0x0001,
+	0x0458, 0x00de, 0x00ce, 0x6004, 0x908e, 0x0002, 0x11a0, 0x6010,
+	0x2058, 0xb8a0, 0x9086, 0x007e, 0x1170, 0x2009, 0x1837, 0x2104,
+	0xc085, 0x200a, 0x00e6, 0x2071, 0x1800, 0x080c, 0x6111, 0x00ee,
+	0x080c, 0xb91f, 0x0030, 0x080c, 0xb91f, 0x080c, 0x3310, 0x080c,
+	0xd353, 0x00e6, 0x0126, 0x2091, 0x8000, 0x080c, 0x333f, 0x012e,
+	0x00ee, 0x080c, 0xaf69, 0x0005, 0x2001, 0x0002, 0x080c, 0x66cf,
+	0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x942f, 0x080c, 0x98bf,
+	0x00de, 0x00ce, 0x0c80, 0x080c, 0x333f, 0x0804, 0xca58, 0x00c6,
+	0x00d6, 0x6104, 0x9186, 0x0016, 0x0d38, 0x6010, 0x2058, 0xb840,
+	0x9084, 0x00ff, 0x9005, 0x0904, 0xcaa9, 0x8001, 0xb842, 0x6003,
+	0x0001, 0x080c, 0x942f, 0x080c, 0x98bf, 0x00de, 0x00ce, 0x0898,
+	0x080c, 0xb91f, 0x0804, 0xca5a, 0x080c, 0xb95b, 0x0804, 0xca5a,
+	0x00d6, 0x2c68, 0x6104, 0x080c, 0xd2b6, 0x00de, 0x0118, 0x080c,
+	0xaf2e, 0x0408, 0x6004, 0x8007, 0x6134, 0x918c, 0x00ff, 0x9105,
+	0x6036, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002, 0x603c,
+	0x600a, 0x2001, 0x1988, 0x2004, 0x601a, 0x602c, 0x2c08, 0x2060,
+	0x6024, 0xd0b4, 0x0108, 0xc085, 0xc0b5, 0x6026, 0x2160, 0x2009,
+	0x8020, 0x080c, 0x9428, 0x0005, 0x00de, 0x00ce, 0x080c, 0xb91f,
+	0x080c, 0x3310, 0x00e6, 0x0126, 0x2091, 0x8000, 0x080c, 0x333f,
+	0x6017, 0x0000, 0x6023, 0x0007, 0x601b, 0x0398, 0x604b, 0x0000,
+	0x012e, 0x00ee, 0x0005, 0x080c, 0xb36d, 0x1904, 0xcb00, 0x0005,
+	0x6000, 0x908a, 0x0016, 0x1a0c, 0x0d85, 0x0096, 0x00d6, 0x001b,
+	0x00de, 0x009e, 0x0005, 0xcb6b, 0xcb6b, 0xcb6b, 0xcb6b, 0xcb6b,
+	0xcb6b, 0xcb6b, 0xcb6b, 0xcb6b, 0xc917, 0xcb6b, 0xc91c, 0xcb6d,
+	0xc91c, 0xcb87, 0xcb6b, 0x080c, 0x0d85, 0x6004, 0x9086, 0x008b,
+	0x01b0, 0x6034, 0x908c, 0xff00, 0x810f, 0x9186, 0x0035, 0x1130,
+	0x602c, 0x9080, 0x0009, 0x200c, 0xc185, 0x2102, 0x6007, 0x008b,
+	0x6003, 0x000d, 0x2009, 0x8020, 0x080c, 0x9428, 0x0005, 0x080c,
+	0xd332, 0x0118, 0x080c, 0xd345, 0x0010, 0x080c, 0xd353, 0x080c,
+	0xce07, 0x080c, 0xcc16, 0x0570, 0x080c, 0x3310, 0x080c, 0xcc16,
+	0x0168, 0x6014, 0x2048, 0xa867, 0x0103, 0xa87b, 0x0006, 0xa877,
+	0x0000, 0xa880, 0xc0ed, 0xa882, 0x080c, 0x6f19, 0x2c68, 0x080c,
+	0xaed8, 0x0150, 0x6810, 0x6012, 0x080c, 0xd0b1, 0x00c6, 0x2d60,
+	0x080c, 0xaf69, 0x00ce, 0x0008, 0x2d60, 0x6017, 0x0000, 0x6023,
+	0x0001, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c, 0x942f, 0x080c,
+	0x98bf, 0x00c8, 0x080c, 0xd332, 0x0138, 0x6034, 0x9086, 0x4000,
+	0x1118, 0x080c, 0x3310, 0x08d0, 0x6034, 0x908c, 0xff00, 0x810f,
+	0x9186, 0x0039, 0x0118, 0x9186, 0x0035, 0x1118, 0x080c, 0x3310,
+	0x0868, 0x080c, 0xaf69, 0x0005, 0x6000, 0x908a, 0x0016, 0x1a0c,
+	0x0d85, 0x0002, 0xcbf2, 0xcbf2, 0xcbf4, 0xcbf4, 0xcbf4, 0xcbf2,
+	0xcbf2, 0xaf69, 0xcbf2, 0xcbf2, 0xcbf2, 0xcbf2, 0xcbf2, 0xcbf2,
+	0xcbf2, 0xcbf2, 0x080c, 0x0d85, 0x080c, 0xaae0, 0x080c, 0xacaf,
+	0x080c, 0xaafc, 0x6114, 0x0096, 0x2148, 0xa87b, 0x0006, 0x080c,
+	0x6f19, 0x009e, 0x0804, 0xaf2e, 0x9284, 0x0003, 0x1158, 0x9282,
+	0x1ddc, 0x0240, 0x2001, 0x181a, 0x2004, 0x9202, 0x1218, 0x9085,
+	0x0001, 0x0005, 0x9006, 0x0ce8, 0x0096, 0x0028, 0x0096, 0x0006,
+	0x6014, 0x2048, 0x000e, 0x0006, 0x9984, 0xf000, 0x9086, 0xf000,
+	0x0110, 0x080c, 0x1104, 0x000e, 0x009e, 0x0005, 0x00e6, 0x00c6,
+	0x0036, 0x0006, 0x0126, 0x2091, 0x8000, 0x2061, 0x1ddc, 0x2071,
+	0x1800, 0x7354, 0x7074, 0x9302, 0x1640, 0x6020, 0x9206, 0x11f8,
+	0x080c, 0xd33e, 0x0180, 0x9286, 0x0001, 0x1168, 0x6004, 0x9086,
+	0x0004, 0x1148, 0x080c, 0x3310, 0x080c, 0xd353, 0x00c6, 0x080c,
+	0xaf69, 0x00ce, 0x0060, 0x080c, 0xd023, 0x0148, 0x080c, 0xce2d,
+	0x1110, 0x080c, 0xb91f, 0x00c6, 0x080c, 0xaf2e, 0x00ce, 0x9ce0,
+	0x001c, 0x7068, 0x9c02, 0x1208, 0x08a0, 0x012e, 0x000e, 0x003e,
+	0x00ce, 0x00ee, 0x0005, 0x00e6, 0x00c6, 0x0016, 0x9188, 0x1000,
+	0x210c, 0x81ff, 0x0128, 0x2061, 0x1b3a, 0x6112, 0x080c, 0x3310,
+	0x9006, 0x0010, 0x9085, 0x0001, 0x001e, 0x00ce, 0x00ee, 0x0005,
+	0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xaed8, 0x01b0, 0x665e,
+	0x2b00, 0x6012, 0x080c, 0x582e, 0x0118, 0x080c, 0xcd49, 0x0168,
+	0x080c, 0xd0b1, 0x6023, 0x0003, 0x2009, 0x004b, 0x080c, 0xafcc,
+	0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x00c6,
+	0x0126, 0x2091, 0x8000, 0xbaa0, 0x080c, 0xaf9f, 0x0580, 0x605f,
+	0x0000, 0x2b00, 0x6012, 0x080c, 0xd0b1, 0x6023, 0x0003, 0x0016,
+	0x080c, 0xaae0, 0x080c, 0x95c1, 0x0076, 0x903e, 0x080c, 0x947e,
+	0x2c08, 0x080c, 0xe440, 0x007e, 0x080c, 0xaafc, 0x001e, 0xd184,
+	0x0128, 0x080c, 0xaf2e, 0x9085, 0x0001, 0x0070, 0x080c, 0x582e,
+	0x0128, 0xd18c, 0x1170, 0x080c, 0xcd49, 0x0148, 0x2009, 0x004c,
+	0x080c, 0xafcc, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006,
+	0x0cd8, 0x2900, 0x6016, 0x0c90, 0x2009, 0x004d, 0x0010, 0x2009,
+	0x004e, 0x00f6, 0x00c6, 0x0046, 0x0016, 0x080c, 0xaed8, 0x2c78,
+	0x05a0, 0x7e5e, 0x2b00, 0x7812, 0x7823, 0x0003, 0x0016, 0x2021,
+	0x0005, 0x080c, 0xcd5b, 0x001e, 0x9186, 0x004d, 0x0118, 0x9186,
+	0x004e, 0x0148, 0x2001, 0x1981, 0x200c, 0xd1fc, 0x0168, 0x2f60,
+	0x080c, 0xaf2e, 0x00d0, 0x2001, 0x1980, 0x200c, 0xd1fc, 0x0120,
+	0x2f60, 0x080c, 0xaf2e, 0x0088, 0x2f60, 0x080c, 0x582e, 0x0138,
+	0xd18c, 0x1118, 0x04f1, 0x0148, 0x0010, 0x2900, 0x7816, 0x001e,
+	0x0016, 0x080c, 0xafcc, 0x9085, 0x0001, 0x001e, 0x004e, 0x00ce,
+	0x00fe, 0x0005, 0x00f6, 0x00c6, 0x0046, 0x080c, 0xaed8, 0x2c78,
+	0x0508, 0x7e5e, 0x2b00, 0x7812, 0x7823, 0x0003, 0x0096, 0x2021,
+	0x0004, 0x0489, 0x009e, 0x2001, 0x197f, 0x200c, 0xd1fc, 0x0120,
+	0x2f60, 0x080c, 0xaf2e, 0x0060, 0x2f60, 0x080c, 0x582e, 0x0120,
+	0xd18c, 0x1160, 0x0071, 0x0130, 0x2009, 0x0052, 0x080c, 0xafcc,
+	0x9085, 0x0001, 0x004e, 0x00ce, 0x00fe, 0x0005, 0x2900, 0x7816,
+	0x0c98, 0x00c6, 0x080c, 0x4bce, 0x00ce, 0x1120, 0x080c, 0xaf2e,
+	0x9006, 0x0005, 0xa867, 0x0000, 0xa86b, 0x8000, 0x2900, 0x6016,
+	0x9085, 0x0001, 0x0005, 0x0096, 0x0076, 0x0126, 0x2091, 0x8000,
+	0x080c, 0xaae0, 0x080c, 0x696b, 0x0158, 0x2001, 0xcd62, 0x0006,
+	0x900e, 0x2400, 0x080c, 0x7165, 0x080c, 0x6f19, 0x000e, 0x0807,
+	0x2418, 0x080c, 0x97c4, 0xbaa0, 0x0086, 0x2041, 0x0001, 0x2039,
+	0x0001, 0x2608, 0x080c, 0x95db, 0x008e, 0x080c, 0x947e, 0x2f08,
+	0x2648, 0x080c, 0xe440, 0xb93c, 0x81ff, 0x090c, 0x96b4, 0x080c,
+	0xaafc, 0x012e, 0x007e, 0x009e, 0x0005, 0x00c6, 0x0126, 0x2091,
+	0x8000, 0x080c, 0xaed8, 0x0190, 0x660a, 0x2b08, 0x6112, 0x080c,
+	0xd0b1, 0x6023, 0x0001, 0x2900, 0x6016, 0x2009, 0x001f, 0x080c,
+	0xafcc, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8,
+	0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xaf9f, 0x01b8, 0x660a,
+	0x2b08, 0x6112, 0x080c, 0xd0b1, 0x6023, 0x0008, 0x2900, 0x6016,
+	0x00f6, 0x2c78, 0x080c, 0x17ad, 0x00fe, 0x2009, 0x0021, 0x080c,
+	0xafcc, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8,
+	0x2009, 0x003d, 0x00c6, 0x0126, 0x0016, 0x2091, 0x8000, 0x080c,
+	0xaed8, 0x0198, 0x660a, 0x2b08, 0x6112, 0x080c, 0xd0b1, 0x6023,
+	0x0001, 0x2900, 0x6016, 0x001e, 0x0016, 0x080c, 0xafcc, 0x9085,
+	0x0001, 0x001e, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd0, 0x00c6,
+	0x0126, 0x2091, 0x8000, 0x080c, 0xaf9f, 0x0188, 0x2b08, 0x6112,
+	0x080c, 0xd0b1, 0x6023, 0x0001, 0x2900, 0x6016, 0x2009, 0x0000,
+	0x080c, 0xafcc, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006,
+	0x0cd8, 0x2009, 0x0044, 0x0830, 0x2009, 0x0049, 0x0818, 0x0026,
+	0x00b6, 0x6210, 0x2258, 0xba3c, 0x82ff, 0x0118, 0x8211, 0xba3e,
+	0x1140, 0xb8d0, 0x9005, 0x0128, 0xb888, 0x9005, 0x1110, 0xb88b,
+	0x0001, 0x00be, 0x002e, 0x0005, 0x0006, 0x0016, 0x6004, 0x908e,
+	0x0002, 0x0140, 0x908e, 0x0003, 0x0128, 0x908e, 0x0004, 0x0110,
+	0x9085, 0x0001, 0x001e, 0x000e, 0x0005, 0x0006, 0x0086, 0x0096,
+	0x6020, 0x9086, 0x0004, 0x01a8, 0x6014, 0x904d, 0x080c, 0xcc16,
+	0x0180, 0xa864, 0x9086, 0x0139, 0x0170, 0x6020, 0x90c6, 0x0003,
+	0x0140, 0x90c6, 0x0002, 0x0128, 0xa868, 0xd0fc, 0x0110, 0x9006,
+	0x0010, 0x9085, 0x0001, 0x009e, 0x008e, 0x000e, 0x0005, 0x00c6,
+	0x0126, 0x2091, 0x8000, 0x080c, 0xaf9f, 0x0198, 0x2b08, 0x6112,
+	0x080c, 0xd0b1, 0x6023, 0x0001, 0x2900, 0x6016, 0x080c, 0x3310,
+	0x2009, 0x0028, 0x080c, 0xafcc, 0x9085, 0x0001, 0x012e, 0x00ce,
+	0x0005, 0x9006, 0x0cd8, 0x9186, 0x0015, 0x11a8, 0x2011, 0x1824,
+	0x2204, 0x9086, 0x0074, 0x1178, 0x00b6, 0x080c, 0xbb81, 0x00be,
+	0x080c, 0xbda6, 0x6003, 0x0001, 0x6007, 0x0029, 0x080c, 0x942f,
+	0x080c, 0x98bf, 0x0078, 0x6014, 0x0096, 0x2048, 0xa868, 0x009e,
+	0xd0fc, 0x0148, 0x2001, 0x0001, 0x080c, 0xd277, 0x080c, 0xb91f,
+	0x080c, 0xaf2e, 0x0005, 0x0096, 0x6014, 0x904d, 0x090c, 0x0d85,
+	0xa87b, 0x0030, 0xa883, 0x0000, 0xa897, 0x4005, 0xa89b, 0x0004,
+	0xa867, 0x0139, 0x0126, 0x2091, 0x8000, 0x080c, 0x6f19, 0x012e,
+	0x009e, 0x080c, 0xaf2e, 0x0c30, 0x0096, 0x9186, 0x0016, 0x1128,
+	0x2001, 0x0004, 0x080c, 0x66cf, 0x00e8, 0x9186, 0x0015, 0x1510,
+	0x2011, 0x1824, 0x2204, 0x9086, 0x0014, 0x11e0, 0x6010, 0x00b6,
+	0x2058, 0x080c, 0x6824, 0x00be, 0x080c, 0xbe77, 0x1198, 0x6010,
+	0x00b6, 0x2058, 0xb890, 0x00be, 0x9005, 0x0160, 0x2001, 0x0006,
+	0x080c, 0x66cf, 0x6014, 0x2048, 0xa868, 0xd0fc, 0x0170, 0x080c,
+	0xb341, 0x0048, 0x6014, 0x2048, 0xa868, 0xd0fc, 0x0528, 0x080c,
+	0xb91f, 0x080c, 0xaf2e, 0x009e, 0x0005, 0x6014, 0x6310, 0x2358,
+	0x904d, 0x090c, 0x0d85, 0xa87b, 0x0000, 0xa883, 0x0000, 0xa897,
+	0x4000, 0x900e, 0x080c, 0x6a7c, 0x1108, 0xc185, 0xb800, 0xd0bc,
+	0x0108, 0xc18d, 0xa99a, 0x0126, 0x2091, 0x8000, 0x080c, 0x6f19,
+	0x012e, 0x080c, 0xaf2e, 0x08f8, 0x6014, 0x904d, 0x090c, 0x0d85,
+	0xa87b, 0x0030, 0xa883, 0x0000, 0xa897, 0x4005, 0xa89b, 0x0004,
+	0xa867, 0x0139, 0x0126, 0x2091, 0x8000, 0x080c, 0x6f19, 0x012e,
+	0x080c, 0xaf2e, 0x0840, 0xa878, 0x9086, 0x0005, 0x1108, 0x0009,
+	0x0005, 0xa880, 0xc0ad, 0xa882, 0x0005, 0x604b, 0x0000, 0x6017,
+	0x0000, 0x6003, 0x0001, 0x6007, 0x0050, 0x2009, 0x8023, 0x080c,
+	0x9428, 0x0005, 0x00c6, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be,
+	0xd0bc, 0x0130, 0x0066, 0x6020, 0x9084, 0x000f, 0x001b, 0x006e,
+	0x00ce, 0x0005, 0xc917, 0xcf54, 0xcf54, 0xcf57, 0xe779, 0xe794,
+	0xe797, 0xc917, 0xc917, 0xc917, 0xc917, 0xc917, 0xc917, 0xc917,
+	0xc917, 0xc917, 0x080c, 0x0d85, 0xa001, 0xa001, 0x0005, 0x0096,
+	0x6014, 0x904d, 0x0118, 0xa87c, 0xd0e4, 0x1110, 0x009e, 0x0010,
+	0x009e, 0x0005, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc,
+	0x0550, 0x2001, 0x1834, 0x2004, 0x9005, 0x1540, 0x00f6, 0x2c78,
+	0x080c, 0xaed8, 0x0508, 0x7810, 0x6012, 0x080c, 0xd0b1, 0x7820,
+	0x9086, 0x0003, 0x0128, 0x7808, 0x603a, 0x2f00, 0x603e, 0x0020,
+	0x7808, 0x603e, 0x2f00, 0x603a, 0x602e, 0x6023, 0x0001, 0x6007,
+	0x0035, 0x6003, 0x0001, 0x795c, 0x615e, 0x2009, 0x8020, 0x080c,
+	0x9428, 0x2f60, 0x00fe, 0x0005, 0x2f60, 0x00fe, 0x2001, 0x1989,
+	0x2004, 0x604a, 0x0005, 0x0016, 0x0096, 0x6814, 0x2048, 0x681c,
+	0xd0fc, 0xc0fc, 0x681e, 0xa87c, 0x1108, 0xd0e4, 0x0180, 0xc0e4,
+	0xa87e, 0xa877, 0x0000, 0xa893, 0x0000, 0xa88f, 0x0000, 0xd0cc,
+	0x0130, 0xc0cc, 0xa87e, 0xa878, 0x2048, 0x080c, 0x100b, 0x6830,
+	0x6036, 0x908e, 0x0001, 0x0148, 0x6803, 0x0002, 0x9086, 0x0005,
+	0x0170, 0x9006, 0x602e, 0x6032, 0x00d0, 0x681c, 0xc085, 0x681e,
+	0x6803, 0x0004, 0x6824, 0xc0f4, 0x9085, 0x0c00, 0x6826, 0x6814,
+	0x2048, 0xa8ac, 0x6938, 0x9102, 0xa8b0, 0x693c, 0x9103, 0x1e48,
+	0x683c, 0x602e, 0x6838, 0x9084, 0xfffc, 0x683a, 0x6032, 0x2d00,
+	0x603a, 0x6808, 0x603e, 0x6910, 0x6112, 0x695c, 0x615e, 0x6023,
+	0x0001, 0x6007, 0x0039, 0x6003, 0x0001, 0x2009, 0x8020, 0x080c,
+	0x9428, 0x009e, 0x001e, 0x0005, 0x6024, 0xd0d4, 0x0510, 0xd0f4,
+	0x11f8, 0x6038, 0x940a, 0x603c, 0x9303, 0x0230, 0x9105, 0x0120,
+	0x6024, 0xc0d4, 0xc0f5, 0x0098, 0x643a, 0x633e, 0xac3e, 0xab42,
+	0x0046, 0x0036, 0x2400, 0xacac, 0x9402, 0xa836, 0x2300, 0xabb0,
+	0x9303, 0xa83a, 0x003e, 0x004e, 0x6024, 0xc0d4, 0x0000, 0x6026,
+	0x0005, 0xd0f4, 0x1138, 0xa83c, 0x603a, 0xa840, 0x603e, 0x6024,
+	0xc0f5, 0x6026, 0x0005, 0x0006, 0x0016, 0x6004, 0x908e, 0x0034,
+	0x01b8, 0x908e, 0x0035, 0x01a0, 0x908e, 0x0036, 0x0188, 0x908e,
+	0x0037, 0x0170, 0x908e, 0x0038, 0x0158, 0x908e, 0x0039, 0x0140,
+	0x908e, 0x003a, 0x0128, 0x908e, 0x003b, 0x0110, 0x9085, 0x0001,
+	0x001e, 0x000e, 0x0005, 0x0006, 0x0016, 0x0026, 0x0036, 0x00e6,
+	0x2001, 0x1983, 0x200c, 0x8000, 0x2014, 0x2001, 0x0032, 0x080c,
+	0x936c, 0x2001, 0x1987, 0x82ff, 0x1110, 0x2011, 0x0014, 0x2202,
+	0x2001, 0x1985, 0x200c, 0x8000, 0x2014, 0x2071, 0x196d, 0x711a,
+	0x721e, 0x2001, 0x0064, 0x080c, 0x936c, 0x2001, 0x1988, 0x82ff,
+	0x1110, 0x2011, 0x0014, 0x2202, 0x2001, 0x1989, 0x9288, 0x000a,
+	0x2102, 0x2001, 0x0017, 0x080c, 0xaad1, 0x2001, 0x1a91, 0x2102,
+	0x2001, 0x0032, 0x080c, 0x16b9, 0x080c, 0x6bb6, 0x00ee, 0x003e,
+	0x002e, 0x001e, 0x000e, 0x0005, 0x0006, 0x0016, 0x00e6, 0x2001,
+	0x1987, 0x2003, 0x0028, 0x2001, 0x1988, 0x2003, 0x0014, 0x2071,
+	0x196d, 0x701b, 0x0000, 0x701f, 0x07d0, 0x2001, 0x1989, 0x2009,
+	0x001e, 0x2102, 0x2001, 0x0017, 0x080c, 0xaad1, 0x2001, 0x1a91,
+	0x2102, 0x2001, 0x0032, 0x080c, 0x16b9, 0x00ee, 0x001e, 0x000e,
+	0x0005, 0x0096, 0x6060, 0x904d, 0x0110, 0x080c, 0x108b, 0x009e,
+	0x0005, 0x0005, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xaed8,
+	0x0180, 0x2b08, 0x6112, 0x0ca9, 0x6023, 0x0001, 0x2900, 0x6016,
+	0x2009, 0x0033, 0x080c, 0xafcc, 0x9085, 0x0001, 0x012e, 0x00ce,
+	0x0005, 0x9006, 0x0cd8, 0x0096, 0x00e6, 0x00f6, 0x2071, 0x1800,
+	0x9186, 0x0015, 0x1520, 0x7090, 0x9086, 0x0018, 0x0120, 0x7090,
+	0x9086, 0x0014, 0x11e0, 0x6014, 0x2048, 0xaa3c, 0xd2e4, 0x1160,
+	0x2c78, 0x080c, 0x998f, 0x01d8, 0x707c, 0xaa50, 0x9206, 0x1160,
 	0x7080, 0xaa54, 0x9206, 0x1140, 0x6210, 0x00b6, 0x2258, 0xbaa0,
-	0x00be, 0x900e, 0x080c, 0x328f, 0x080c, 0xb0bf, 0x0020, 0x080c,
-	0xb693, 0x080c, 0xacb0, 0x00fe, 0x00ee, 0x009e, 0x0005, 0x7060,
+	0x00be, 0x900e, 0x080c, 0x335f, 0x080c, 0xb341, 0x0020, 0x080c,
+	0xb91f, 0x080c, 0xaf2e, 0x00fe, 0x00ee, 0x009e, 0x0005, 0x7060,
 	0xaa54, 0x9206, 0x0d48, 0x0c80, 0x00c6, 0x0126, 0x2091, 0x8000,
-	0x080c, 0xac5a, 0x0188, 0x2b08, 0x6112, 0x080c, 0xce15, 0x6023,
-	0x0001, 0x2900, 0x6016, 0x2009, 0x004d, 0x080c, 0xad4d, 0x9085,
+	0x080c, 0xaed8, 0x0188, 0x2b08, 0x6112, 0x080c, 0xd0b1, 0x6023,
+	0x0001, 0x2900, 0x6016, 0x2009, 0x004d, 0x080c, 0xafcc, 0x9085,
 	0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x00c6, 0x0126,
-	0x2091, 0x8000, 0x0016, 0x080c, 0xac5a, 0x0180, 0x2b08, 0x6112,
-	0x080c, 0xce15, 0x6023, 0x0001, 0x2900, 0x6016, 0x001e, 0x080c,
-	0xad4d, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x001e, 0x9006,
+	0x2091, 0x8000, 0x0016, 0x080c, 0xaed8, 0x0180, 0x2b08, 0x6112,
+	0x080c, 0xd0b1, 0x6023, 0x0001, 0x2900, 0x6016, 0x001e, 0x080c,
+	0xafcc, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x001e, 0x9006,
 	0x0cd0, 0x0016, 0x0026, 0x0036, 0x0046, 0x0056, 0x0066, 0x0096,
 	0x00e6, 0x00f6, 0x2071, 0x1800, 0x9186, 0x0015, 0x1568, 0x7190,
 	0x6014, 0x2048, 0xa814, 0x8003, 0x9106, 0x1530, 0x20e1, 0x0000,
-	0x2001, 0x199f, 0x2003, 0x0000, 0x6014, 0x2048, 0xa830, 0x20a8,
+	0x2001, 0x19a1, 0x2003, 0x0000, 0x6014, 0x2048, 0xa830, 0x20a8,
 	0x8906, 0x8006, 0x8007, 0x9094, 0x003f, 0x22e8, 0x9084, 0xffc0,
-	0x9080, 0x001b, 0x20a0, 0x2001, 0x199f, 0x0016, 0x200c, 0x080c,
-	0xd6df, 0x001e, 0xa804, 0x9005, 0x0110, 0x2048, 0x0c38, 0x6014,
-	0x2048, 0xa867, 0x0103, 0x0010, 0x080c, 0xb693, 0x080c, 0xacb0,
+	0x9080, 0x001b, 0x20a0, 0x2001, 0x19a1, 0x0016, 0x200c, 0x080c,
+	0xd998, 0x001e, 0xa804, 0x9005, 0x0110, 0x2048, 0x0c38, 0x6014,
+	0x2048, 0xa867, 0x0103, 0x0010, 0x080c, 0xb91f, 0x080c, 0xaf2e,
 	0x00fe, 0x00ee, 0x009e, 0x006e, 0x005e, 0x004e, 0x003e, 0x002e,
 	0x001e, 0x0005, 0x0096, 0x00e6, 0x00f6, 0x2071, 0x1800, 0x9186,
 	0x0015, 0x11b8, 0x7090, 0x9086, 0x0004, 0x1198, 0x6014, 0x2048,
-	0x2c78, 0x080c, 0x97f7, 0x01a8, 0x707c, 0xaa74, 0x9206, 0x1130,
-	0x7080, 0xaa78, 0x9206, 0x1110, 0x080c, 0x3240, 0x080c, 0xb0bf,
-	0x0020, 0x080c, 0xb693, 0x080c, 0xacb0, 0x00fe, 0x00ee, 0x009e,
+	0x2c78, 0x080c, 0x998f, 0x01a8, 0x707c, 0xaa74, 0x9206, 0x1130,
+	0x7080, 0xaa78, 0x9206, 0x1110, 0x080c, 0x3310, 0x080c, 0xb341,
+	0x0020, 0x080c, 0xb91f, 0x080c, 0xaf2e, 0x00fe, 0x00ee, 0x009e,
 	0x0005, 0x7060, 0xaa78, 0x9206, 0x0d78, 0x0c80, 0x0096, 0x00e6,
 	0x00f6, 0x2071, 0x1800, 0x9186, 0x0015, 0x1550, 0x7090, 0x9086,
-	0x0004, 0x1530, 0x6014, 0x2048, 0x2c78, 0x080c, 0x97f7, 0x05f0,
+	0x0004, 0x1530, 0x6014, 0x2048, 0x2c78, 0x080c, 0x998f, 0x05f0,
 	0x707c, 0xaacc, 0x9206, 0x1180, 0x7080, 0xaad0, 0x9206, 0x1160,
-	0x080c, 0x3240, 0x0016, 0xa998, 0xaab0, 0x9284, 0x1000, 0xc0fd,
-	0x080c, 0x56e7, 0x001e, 0x0010, 0x080c, 0x54ca, 0x080c, 0xc97a,
+	0x080c, 0x3310, 0x0016, 0xa998, 0xaab0, 0x9284, 0x1000, 0xc0fd,
+	0x080c, 0x57cf, 0x001e, 0x0010, 0x080c, 0x55b2, 0x080c, 0xcc16,
 	0x0508, 0xa87b, 0x0000, 0xa883, 0x0000, 0xa897, 0x4000, 0x0080,
-	0x080c, 0xc97a, 0x01b8, 0x6014, 0x2048, 0x080c, 0x54ca, 0x1d70,
+	0x080c, 0xcc16, 0x01b8, 0x6014, 0x2048, 0x080c, 0x55b2, 0x1d70,
 	0xa87b, 0x0030, 0xa883, 0x0000, 0xa897, 0x4005, 0xa89b, 0x0004,
-	0x0126, 0x2091, 0x8000, 0xa867, 0x0139, 0x080c, 0x6dee, 0x012e,
-	0x080c, 0xacb0, 0x00fe, 0x00ee, 0x009e, 0x0005, 0x7060, 0xaad0,
+	0x0126, 0x2091, 0x8000, 0xa867, 0x0139, 0x080c, 0x6f19, 0x012e,
+	0x080c, 0xaf2e, 0x00fe, 0x00ee, 0x009e, 0x0005, 0x7060, 0xaad0,
 	0x9206, 0x0930, 0x0888, 0x0016, 0x0026, 0xa87c, 0xd0ac, 0x0178,
 	0xa938, 0xaa34, 0x2100, 0x9205, 0x0150, 0xa890, 0x9106, 0x1118,
 	0xa88c, 0x9206, 0x0120, 0xa992, 0xaa8e, 0x9085, 0x0001, 0x002e,
-	0x001e, 0x0005, 0x00b6, 0x00d6, 0x0036, 0x080c, 0xc97a, 0x0904,
-	0xcfd0, 0x0096, 0x6314, 0x2348, 0xa87a, 0xa982, 0x929e, 0x4000,
+	0x001e, 0x0005, 0x00b6, 0x00d6, 0x0036, 0x080c, 0xcc16, 0x0904,
+	0xd273, 0x0096, 0x6314, 0x2348, 0xa87a, 0xa982, 0x929e, 0x4000,
 	0x1580, 0x6310, 0x00c6, 0x2358, 0x2009, 0x0000, 0xa868, 0xd0f4,
-	0x1140, 0x080c, 0x6986, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108,
+	0x1140, 0x080c, 0x6a7c, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108,
 	0xc18d, 0xaa96, 0xa99a, 0x20a9, 0x0004, 0xa860, 0x20e8, 0xa85c,
 	0x9080, 0x0031, 0x20a0, 0xb8c4, 0x20e0, 0xb8c8, 0x9080, 0x0006,
-	0x2098, 0x080c, 0x0fc4, 0x20a9, 0x0004, 0xa85c, 0x9080, 0x0035,
-	0x20a0, 0xb8c8, 0x9080, 0x000a, 0x2098, 0x080c, 0x0fc4, 0x00ce,
+	0x2098, 0x080c, 0x0fd6, 0x20a9, 0x0004, 0xa85c, 0x9080, 0x0035,
+	0x20a0, 0xb8c8, 0x9080, 0x000a, 0x2098, 0x080c, 0x0fd6, 0x00ce,
 	0x0090, 0xaa96, 0x3918, 0x9398, 0x0007, 0x231c, 0x6004, 0x9086,
 	0x0016, 0x0110, 0xa89b, 0x0004, 0xaba2, 0x6310, 0x2358, 0xb804,
-	0x9084, 0x00ff, 0xa89e, 0x080c, 0x6de2, 0x6017, 0x0000, 0x009e,
-	0x003e, 0x00de, 0x00be, 0x0005, 0x0026, 0x0036, 0x0046, 0x00b6,
-	0x0096, 0x00f6, 0x6214, 0x2248, 0x6210, 0x2258, 0x2079, 0x0260,
-	0x9096, 0x0000, 0x11a0, 0xb814, 0x9084, 0x00ff, 0x900e, 0x080c,
-	0x2661, 0x2118, 0x831f, 0x939c, 0xff00, 0x7838, 0x9084, 0x00ff,
-	0x931d, 0x7c3c, 0x2011, 0x8018, 0x080c, 0x4b52, 0x00a8, 0x9096,
-	0x0001, 0x1148, 0x89ff, 0x0180, 0xa89b, 0x000d, 0x7838, 0xa8a6,
-	0x783c, 0xa8aa, 0x0048, 0x9096, 0x0002, 0x1130, 0xa89b, 0x000d,
-	0x7838, 0xa8a6, 0x783c, 0xa8aa, 0x00fe, 0x009e, 0x00be, 0x004e,
-	0x003e, 0x002e, 0x0005, 0x00c6, 0x0026, 0x0016, 0x9186, 0x0035,
-	0x0110, 0x6a38, 0x0008, 0x6a2c, 0x080c, 0xc968, 0x01f0, 0x2260,
-	0x6120, 0x9186, 0x0003, 0x0118, 0x9186, 0x0006, 0x1190, 0x6838,
-	0x9206, 0x0140, 0x683c, 0x9206, 0x1160, 0x6108, 0x6838, 0x9106,
-	0x1140, 0x0020, 0x6008, 0x693c, 0x9106, 0x1118, 0x6010, 0x6910,
-	0x9106, 0x001e, 0x002e, 0x00ce, 0x0005, 0x9085, 0x0001, 0x0cc8,
-	0xa974, 0xd1cc, 0x0188, 0x918c, 0x00ff, 0x918e, 0x0002, 0x1160,
-	0xa9a8, 0x918c, 0x0f00, 0x810f, 0x918e, 0x0001, 0x1128, 0xa834,
-	0xa938, 0x9115, 0x190c, 0xbf96, 0x0005, 0x0036, 0x2019, 0x0001,
-	0x0010, 0x0036, 0x901e, 0x0499, 0x01e0, 0x080c, 0xc97a, 0x01c8,
-	0x080c, 0xcb6b, 0x6037, 0x4000, 0x6014, 0x6017, 0x0000, 0x0096,
-	0x2048, 0xa87c, 0x080c, 0xcb91, 0x1118, 0x080c, 0xb693, 0x0040,
-	0xa867, 0x0103, 0xa877, 0x0000, 0x83ff, 0x1129, 0x080c, 0x6dee,
-	0x009e, 0x003e, 0x0005, 0xa880, 0xd0b4, 0x0128, 0xa87b, 0x0006,
-	0xc0ec, 0xa882, 0x0048, 0xd0bc, 0x0118, 0xa87b, 0x0002, 0x0020,
-	0xa87b, 0x0005, 0x080c, 0xcc85, 0xa877, 0x0000, 0x0005, 0x2001,
-	0x1810, 0x2004, 0xd0ec, 0x0005, 0x0006, 0x2001, 0x1810, 0x2004,
-	0xd0f4, 0x000e, 0x0005, 0x0006, 0x2001, 0x1810, 0x2004, 0xd0e4,
-	0x000e, 0x0005, 0x0036, 0x0046, 0x6010, 0x00b6, 0x2058, 0xbba0,
-	0x00be, 0x2021, 0x0007, 0x080c, 0x4d09, 0x004e, 0x003e, 0x0005,
-	0x0c51, 0x1d81, 0x0005, 0x2001, 0x1985, 0x2004, 0x601a, 0x0005,
-	0x2001, 0x1987, 0x2004, 0x604a, 0x0005, 0x080c, 0xacb0, 0x0804,
-	0x9738, 0x611c, 0xd1fc, 0xa97c, 0x1108, 0xd1e4, 0x0005, 0x601c,
-	0xd0fc, 0xa87c, 0x1108, 0xd0e4, 0x0005, 0x601c, 0xd0fc, 0xc0fc,
-	0x601e, 0xa87c, 0x1108, 0xd0e4, 0x0005, 0x6044, 0xd0fc, 0x1138,
-	0xd0bc, 0x0198, 0xc0bc, 0x6046, 0x6003, 0x0002, 0x0070, 0xd0ac,
-	0x1160, 0xd0dc, 0x1128, 0x908c, 0x000f, 0x9186, 0x0005, 0x1118,
-	0x6003, 0x0003, 0x0010, 0x6003, 0x0001, 0x0005, 0x00b6, 0x0066,
-	0x6000, 0x90b2, 0x0016, 0x1a0c, 0x0d7d, 0x001b, 0x006e, 0x00be,
-	0x0005, 0xd109, 0xd83a, 0xd98b, 0xd109, 0xd109, 0xd109, 0xd109,
-	0xd109, 0xd140, 0xda0f, 0xd109, 0xd109, 0xd109, 0xd109, 0xd109,
-	0xd109, 0x080c, 0x0d7d, 0x0066, 0x6000, 0x90b2, 0x0016, 0x1a0c,
-	0x0d7d, 0x0013, 0x006e, 0x0005, 0xd124, 0xdf30, 0xd124, 0xd124,
-	0xd124, 0xd124, 0xd124, 0xd124, 0xdedf, 0xdf82, 0xd124, 0xe5cf,
-	0xe603, 0xe5cf, 0xe603, 0xd124, 0x080c, 0x0d7d, 0x6000, 0x9082,
-	0x0016, 0x1a0c, 0x0d7d, 0x6000, 0x000a, 0x0005, 0xd13e, 0xdbec,
-	0xdcb7, 0xdcda, 0xdd56, 0xd13e, 0xde51, 0xddde, 0xda19, 0xdeb7,
-	0xdecc, 0xd13e, 0xd13e, 0xd13e, 0xd13e, 0xd13e, 0x080c, 0x0d7d,
-	0x91b2, 0x0053, 0x1a0c, 0x0d7d, 0x2100, 0x91b2, 0x0040, 0x1a04,
-	0xd5b0, 0x0002, 0xd18a, 0xd37e, 0xd18a, 0xd18a, 0xd18a, 0xd387,
-	0xd18a, 0xd18a, 0xd18a, 0xd18a, 0xd18a, 0xd18a, 0xd18a, 0xd18a,
-	0xd18a, 0xd18a, 0xd18a, 0xd18a, 0xd18a, 0xd18a, 0xd18a, 0xd18a,
-	0xd18a, 0xd18c, 0xd1f3, 0xd202, 0xd266, 0xd291, 0xd30a, 0xd369,
-	0xd18a, 0xd18a, 0xd38a, 0xd18a, 0xd18a, 0xd39f, 0xd3ac, 0xd18a,
-	0xd18a, 0xd18a, 0xd18a, 0xd18a, 0xd452, 0xd18a, 0xd18a, 0xd466,
-	0xd18a, 0xd18a, 0xd421, 0xd18a, 0xd18a, 0xd18a, 0xd47e, 0xd18a,
-	0xd18a, 0xd18a, 0xd4fb, 0xd18a, 0xd18a, 0xd18a, 0xd18a, 0xd18a,
-	0xd18a, 0xd578, 0x080c, 0x0d7d, 0x080c, 0x6a9b, 0x1150, 0x2001,
-	0x1837, 0x2004, 0xd0cc, 0x1128, 0x9084, 0x0009, 0x9086, 0x0008,
-	0x1140, 0x6007, 0x0009, 0x602f, 0x0009, 0x6017, 0x0000, 0x0804,
-	0xd377, 0x080c, 0x6a37, 0x00e6, 0x00c6, 0x0036, 0x0026, 0x0016,
-	0x6210, 0x2258, 0xbaa0, 0x0026, 0x2019, 0x0029, 0x080c, 0xa91e,
-	0x080c, 0x943d, 0x0076, 0x903e, 0x080c, 0x9306, 0x2c08, 0x080c,
-	0xe167, 0x007e, 0x001e, 0x080c, 0xa93a, 0x001e, 0x002e, 0x003e,
-	0x00ce, 0x00ee, 0x6610, 0x2658, 0x080c, 0x66a2, 0xbe04, 0x9684,
-	0x00ff, 0x9082, 0x0006, 0x1268, 0x0016, 0x0026, 0x6210, 0x00b6,
-	0x2258, 0xbaa0, 0x00be, 0x2c08, 0x080c, 0xe82c, 0x002e, 0x001e,
-	0x1178, 0x080c, 0xe095, 0x1904, 0xd25e, 0x080c, 0xe031, 0x1120,
-	0x6007, 0x0008, 0x0804, 0xd377, 0x6007, 0x0009, 0x0804, 0xd377,
-	0x080c, 0xe2c8, 0x0128, 0x080c, 0xe095, 0x0d78, 0x0804, 0xd25e,
-	0x6017, 0x1900, 0x0c88, 0x080c, 0x3377, 0x1904, 0xd5ad, 0x6106,
-	0x080c, 0xdfe2, 0x6007, 0x0006, 0x0804, 0xd377, 0x6007, 0x0007,
-	0x0804, 0xd377, 0x080c, 0xe63f, 0x1904, 0xd5ad, 0x080c, 0x3377,
-	0x1904, 0xd5ad, 0x00d6, 0x6610, 0x2658, 0xbe04, 0x9684, 0x00ff,
-	0x9082, 0x0006, 0x1220, 0x2001, 0x0001, 0x080c, 0x65cf, 0x96b4,
-	0xff00, 0x8637, 0x9686, 0x0006, 0x0188, 0x9686, 0x0004, 0x0170,
-	0xbe04, 0x96b4, 0x00ff, 0x9686, 0x0006, 0x0140, 0x9686, 0x0004,
-	0x0128, 0x9686, 0x0005, 0x0110, 0x00de, 0x0480, 0x00e6, 0x2071,
-	0x0260, 0x7034, 0x9084, 0x0003, 0x1140, 0x7034, 0x9082, 0x0014,
-	0x0220, 0x7030, 0x9084, 0x0003, 0x0130, 0x00ee, 0x6017, 0x0000,
-	0x602f, 0x0007, 0x00b0, 0x00ee, 0x080c, 0xe0fd, 0x1190, 0x9686,
-	0x0006, 0x1140, 0x0026, 0x6210, 0x2258, 0xbaa0, 0x900e, 0x080c,
-	0x328f, 0x002e, 0x080c, 0x672e, 0x6007, 0x000a, 0x00de, 0x0804,
-	0xd377, 0x6007, 0x000b, 0x00de, 0x0804, 0xd377, 0x080c, 0x3240,
-	0x080c, 0xd0b0, 0x6007, 0x0001, 0x0804, 0xd377, 0x080c, 0xe63f,
-	0x1904, 0xd5ad, 0x080c, 0x3377, 0x1904, 0xd5ad, 0x2071, 0x0260,
-	0x7034, 0x90b4, 0x0003, 0x1948, 0x90b2, 0x0014, 0x0a30, 0x7030,
-	0x9084, 0x0003, 0x1910, 0x6610, 0x2658, 0xbe04, 0x9686, 0x0707,
-	0x09e8, 0x0026, 0x6210, 0x2258, 0xbaa0, 0x900e, 0x080c, 0x328f,
-	0x002e, 0x6007, 0x000c, 0x2001, 0x0001, 0x080c, 0xe80c, 0x0804,
-	0xd377, 0x080c, 0x6a9b, 0x1140, 0x2001, 0x1837, 0x2004, 0x9084,
-	0x0009, 0x9086, 0x0008, 0x1110, 0x0804, 0xd199, 0x080c, 0x6a37,
-	0x6610, 0x2658, 0xbe04, 0x9684, 0x00ff, 0x9082, 0x0006, 0x06c8,
-	0x1138, 0x0026, 0x2001, 0x0006, 0x080c, 0x660f, 0x002e, 0x0050,
-	0x96b4, 0xff00, 0x8637, 0x9686, 0x0004, 0x0120, 0x9686, 0x0006,
-	0x1904, 0xd25e, 0x080c, 0xe10a, 0x1120, 0x6007, 0x000e, 0x0804,
-	0xd377, 0x0046, 0x6410, 0x2458, 0xbca0, 0x0046, 0x080c, 0x3240,
-	0x080c, 0xd0b0, 0x004e, 0x0016, 0x9006, 0x2009, 0x1848, 0x210c,
-	0xd1a4, 0x0148, 0x2009, 0x0029, 0x080c, 0xe445, 0x6010, 0x2058,
-	0xb800, 0xc0e5, 0xb802, 0x001e, 0x004e, 0x6007, 0x0001, 0x0804,
-	0xd377, 0x2001, 0x0001, 0x080c, 0x65cf, 0x0156, 0x0016, 0x0026,
-	0x0036, 0x20a9, 0x0004, 0x2019, 0x1805, 0x2011, 0x0270, 0x080c,
-	0xbc8e, 0x003e, 0x002e, 0x001e, 0x015e, 0x9005, 0x0168, 0x96b4,
-	0xff00, 0x8637, 0x9682, 0x0004, 0x0a04, 0xd25e, 0x9682, 0x0007,
-	0x0a04, 0xd2ba, 0x0804, 0xd25e, 0x6017, 0x1900, 0x6007, 0x0009,
-	0x0804, 0xd377, 0x080c, 0x6a9b, 0x1140, 0x2001, 0x1837, 0x2004,
-	0x9084, 0x0009, 0x9086, 0x0008, 0x1110, 0x0804, 0xd199, 0x080c,
-	0x6a37, 0x6610, 0x2658, 0xbe04, 0x9684, 0x00ff, 0x0006, 0x9086,
-	0x0001, 0x000e, 0x0170, 0x9082, 0x0006, 0x0698, 0x0150, 0x96b4,
-	0xff00, 0x8637, 0x9686, 0x0004, 0x0120, 0x9686, 0x0006, 0x1904,
-	0xd25e, 0x080c, 0xe138, 0x1130, 0x080c, 0xe031, 0x1118, 0x6007,
-	0x0010, 0x04e8, 0x0046, 0x6410, 0x2458, 0xbca0, 0x0046, 0x080c,
-	0x3240, 0x080c, 0xd0b0, 0x004e, 0x0016, 0x9006, 0x2009, 0x1848,
-	0x210c, 0xd1a4, 0x0148, 0x2009, 0x0029, 0x080c, 0xe445, 0x6010,
-	0x2058, 0xb800, 0xc0e5, 0xb802, 0x001e, 0x004e, 0x6007, 0x0001,
-	0x00f0, 0x080c, 0xe2c8, 0x0140, 0x96b4, 0xff00, 0x8637, 0x9686,
-	0x0006, 0x0978, 0x0804, 0xd25e, 0x6017, 0x1900, 0x6007, 0x0009,
-	0x0070, 0x080c, 0x3377, 0x1904, 0xd5ad, 0x080c, 0xe63f, 0x1904,
-	0xd5ad, 0x080c, 0xd77a, 0x1904, 0xd25e, 0x6007, 0x0012, 0x6003,
-	0x0001, 0x080c, 0x92b7, 0x080c, 0x9738, 0x0005, 0x6007, 0x0001,
-	0x6003, 0x0001, 0x080c, 0x92b7, 0x080c, 0x9738, 0x0cb0, 0x6007,
-	0x0005, 0x0c68, 0x080c, 0xe63f, 0x1904, 0xd5ad, 0x080c, 0x3377,
-	0x1904, 0xd5ad, 0x080c, 0xd77a, 0x1904, 0xd25e, 0x6007, 0x0020,
-	0x6003, 0x0001, 0x080c, 0x92b7, 0x080c, 0x9738, 0x0005, 0x080c,
-	0x3377, 0x1904, 0xd5ad, 0x6007, 0x0023, 0x6003, 0x0001, 0x080c,
-	0x92b7, 0x080c, 0x9738, 0x0005, 0x080c, 0xe63f, 0x1904, 0xd5ad,
-	0x080c, 0x3377, 0x1904, 0xd5ad, 0x080c, 0xd77a, 0x1904, 0xd25e,
-	0x0016, 0x0026, 0x00e6, 0x2071, 0x0260, 0x2c08, 0x2011, 0x1820,
-	0x2214, 0x703c, 0x9206, 0x11e0, 0x2011, 0x181f, 0x2214, 0x7038,
-	0x9084, 0x00ff, 0x9206, 0x11a0, 0x7240, 0x080c, 0xc968, 0x0570,
-	0x2260, 0x6008, 0x9086, 0xffff, 0x0120, 0x7244, 0x6008, 0x9206,
-	0x1528, 0x6020, 0x9086, 0x0007, 0x1508, 0x080c, 0xacb0, 0x04a0,
-	0x7244, 0x9286, 0xffff, 0x0180, 0x2c08, 0x080c, 0xc968, 0x01b0,
-	0x2260, 0x7240, 0x6008, 0x9206, 0x1188, 0x6010, 0x9190, 0x0004,
-	0x2214, 0x9206, 0x01b8, 0x0050, 0x7240, 0x2c08, 0x9006, 0x080c,
-	0xe40f, 0x1180, 0x7244, 0x9286, 0xffff, 0x01b0, 0x2160, 0x6007,
-	0x0026, 0x6017, 0x1700, 0x7214, 0x9296, 0xffff, 0x1180, 0x6007,
-	0x0025, 0x0068, 0x6020, 0x9086, 0x0007, 0x1d80, 0x6004, 0x9086,
-	0x0024, 0x1110, 0x080c, 0xacb0, 0x2160, 0x6007, 0x0025, 0x6003,
-	0x0001, 0x080c, 0x92b7, 0x080c, 0x9738, 0x00ee, 0x002e, 0x001e,
-	0x0005, 0x2001, 0x0001, 0x080c, 0x65cf, 0x0156, 0x0016, 0x0026,
-	0x0036, 0x20a9, 0x0004, 0x2019, 0x1805, 0x2011, 0x0276, 0x080c,
-	0xbc8e, 0x003e, 0x002e, 0x001e, 0x015e, 0x0120, 0x6007, 0x0031,
-	0x0804, 0xd377, 0x080c, 0xb8ff, 0x080c, 0x753d, 0x1190, 0x0006,
-	0x0026, 0x0036, 0x080c, 0x7557, 0x1138, 0x080c, 0x7840, 0x080c,
-	0x6092, 0x080c, 0x746e, 0x0010, 0x080c, 0x7511, 0x003e, 0x002e,
-	0x000e, 0x0005, 0x080c, 0x3377, 0x1904, 0xd5ad, 0x080c, 0xd77a,
-	0x1904, 0xd25e, 0x6106, 0x080c, 0xd796, 0x1120, 0x6007, 0x002b,
-	0x0804, 0xd377, 0x6007, 0x002c, 0x0804, 0xd377, 0x080c, 0xe63f,
-	0x1904, 0xd5ad, 0x080c, 0x3377, 0x1904, 0xd5ad, 0x080c, 0xd77a,
-	0x1904, 0xd25e, 0x6106, 0x080c, 0xd79b, 0x1120, 0x6007, 0x002e,
-	0x0804, 0xd377, 0x6007, 0x002f, 0x0804, 0xd377, 0x080c, 0x3377,
-	0x1904, 0xd5ad, 0x00e6, 0x00d6, 0x00c6, 0x6010, 0x2058, 0xb904,
-	0x9184, 0x00ff, 0x9086, 0x0006, 0x0158, 0x9184, 0xff00, 0x8007,
-	0x9086, 0x0006, 0x0128, 0x00ce, 0x00de, 0x00ee, 0x0804, 0xd37e,
-	0x080c, 0x5742, 0xd0e4, 0x0904, 0xd4f8, 0x2071, 0x026c, 0x7010,
-	0x603a, 0x7014, 0x603e, 0x7108, 0x720c, 0x080c, 0x6ad9, 0x0140,
-	0x6010, 0x2058, 0xb810, 0x9106, 0x1118, 0xb814, 0x9206, 0x0510,
-	0x080c, 0x6ad5, 0x15b8, 0x2069, 0x1800, 0x6880, 0x9206, 0x1590,
-	0x687c, 0x9106, 0x1578, 0x7210, 0x080c, 0xc968, 0x0590, 0x080c,
-	0xd665, 0x0578, 0x080c, 0xe4c1, 0x0560, 0x622e, 0x6007, 0x0036,
-	0x6003, 0x0001, 0x2009, 0x8020, 0x080c, 0x92b0, 0x00ce, 0x00de,
-	0x00ee, 0x0005, 0x7214, 0x9286, 0xffff, 0x0150, 0x080c, 0xc968,
-	0x01c0, 0x9280, 0x0002, 0x2004, 0x7110, 0x9106, 0x1190, 0x08e0,
-	0x7210, 0x2c08, 0x9085, 0x0001, 0x080c, 0xe40f, 0x2c10, 0x2160,
-	0x0140, 0x0890, 0x6007, 0x0037, 0x602f, 0x0009, 0x6017, 0x1500,
-	0x08b8, 0x6007, 0x0037, 0x602f, 0x0003, 0x6017, 0x1700, 0x0880,
-	0x6007, 0x0012, 0x0868, 0x080c, 0x3377, 0x1904, 0xd5ad, 0x6010,
-	0x2058, 0xb804, 0x9084, 0xff00, 0x8007, 0x9086, 0x0006, 0x1904,
-	0xd37e, 0x00e6, 0x00d6, 0x00c6, 0x080c, 0x5742, 0xd0e4, 0x0904,
-	0xd570, 0x2069, 0x1800, 0x2071, 0x026c, 0x7008, 0x603a, 0x720c,
-	0x623e, 0x9286, 0xffff, 0x1150, 0x7208, 0x00c6, 0x2c08, 0x9085,
-	0x0001, 0x080c, 0xe40f, 0x2c10, 0x00ce, 0x05e8, 0x080c, 0xc968,
-	0x05d0, 0x7108, 0x9280, 0x0002, 0x2004, 0x9106, 0x15a0, 0x00c6,
-	0x0026, 0x2260, 0x080c, 0xc559, 0x002e, 0x00ce, 0x7118, 0x918c,
-	0xff00, 0x810f, 0x9186, 0x0001, 0x0178, 0x9186, 0x0005, 0x0118,
-	0x9186, 0x0007, 0x1198, 0x9280, 0x0005, 0x2004, 0x9005, 0x0170,
-	0x080c, 0xd665, 0x0904, 0xd4f1, 0x0056, 0x7510, 0x7614, 0x080c,
-	0xe4da, 0x005e, 0x00ce, 0x00de, 0x00ee, 0x0005, 0x6007, 0x003b,
-	0x602f, 0x0009, 0x6017, 0x2a00, 0x6003, 0x0001, 0x2009, 0x8020,
-	0x080c, 0x92b0, 0x0c78, 0x6007, 0x003b, 0x602f, 0x0003, 0x6017,
-	0x0300, 0x6003, 0x0001, 0x2009, 0x8020, 0x080c, 0x92b0, 0x0c10,
-	0x6007, 0x003b, 0x602f, 0x000b, 0x6017, 0x0000, 0x0804, 0xd4c8,
-	0x00e6, 0x0026, 0x080c, 0x6a9b, 0x0550, 0x080c, 0x6a37, 0x080c,
-	0xe6b1, 0x1518, 0x2071, 0x1800, 0x70dc, 0x9085, 0x0003, 0x70de,
-	0x00f6, 0x2079, 0x0100, 0x72b0, 0x9284, 0x00ff, 0x707e, 0x78e6,
-	0x9284, 0xff00, 0x7280, 0x9205, 0x7082, 0x78ea, 0x00fe, 0x70e7,
-	0x0000, 0x080c, 0x6ad9, 0x0120, 0x2011, 0x1a08, 0x2013, 0x07d0,
-	0xd0ac, 0x1128, 0x080c, 0x3011, 0x0010, 0x080c, 0xe6e3, 0x002e,
-	0x00ee, 0x080c, 0xacb0, 0x0804, 0xd37d, 0x080c, 0xacb0, 0x0005,
-	0x2600, 0x0002, 0xd5c4, 0xd5f5, 0xd606, 0xd5c4, 0xd5c4, 0xd5c6,
-	0xd617, 0xd5c4, 0xd5c4, 0xd5c4, 0xd5e3, 0xd5c4, 0xd5c4, 0xd5c4,
-	0xd622, 0xd62f, 0xd660, 0xd5c4, 0x080c, 0x0d7d, 0x080c, 0xe63f,
-	0x1d20, 0x080c, 0x3377, 0x1d08, 0x080c, 0xd77a, 0x1148, 0x7038,
-	0x6016, 0x6007, 0x0045, 0x6003, 0x0001, 0x080c, 0x92b7, 0x0005,
-	0x080c, 0x3240, 0x080c, 0xd0b0, 0x6007, 0x0001, 0x6003, 0x0001,
-	0x080c, 0x92b7, 0x0005, 0x080c, 0xe63f, 0x1938, 0x080c, 0x3377,
-	0x1920, 0x080c, 0xd77a, 0x1d60, 0x703c, 0x6016, 0x6007, 0x004a,
-	0x6003, 0x0001, 0x080c, 0x92b7, 0x0005, 0x080c, 0x3377, 0x1904,
-	0xd5ad, 0x2009, 0x0041, 0x080c, 0xe6ec, 0x6007, 0x0047, 0x6003,
-	0x0001, 0x080c, 0x92b7, 0x080c, 0x9738, 0x0005, 0x080c, 0x3377,
-	0x1904, 0xd5ad, 0x2009, 0x0042, 0x080c, 0xe6ec, 0x6007, 0x0047,
-	0x6003, 0x0001, 0x080c, 0x92b7, 0x080c, 0x9738, 0x0005, 0x080c,
-	0x3377, 0x1904, 0xd5ad, 0x2009, 0x0046, 0x080c, 0xe6ec, 0x080c,
-	0xacb0, 0x0005, 0x080c, 0xd682, 0x0904, 0xd5ad, 0x6007, 0x004e,
-	0x6003, 0x0001, 0x080c, 0x92b7, 0x080c, 0x9738, 0x0005, 0x6007,
-	0x004f, 0x6017, 0x0000, 0x7134, 0x918c, 0x00ff, 0x81ff, 0x0508,
-	0x9186, 0x0001, 0x1160, 0x7140, 0x2001, 0x19bc, 0x2004, 0x9106,
-	0x11b0, 0x7144, 0x2001, 0x19bd, 0x2004, 0x9106, 0x0190, 0x9186,
-	0x0002, 0x1168, 0x2011, 0x0276, 0x20a9, 0x0004, 0x6010, 0x0096,
-	0x2048, 0x2019, 0x000a, 0x080c, 0xbca2, 0x009e, 0x0110, 0x6017,
-	0x0001, 0x6003, 0x0001, 0x080c, 0x92b7, 0x080c, 0x9738, 0x0005,
-	0x6007, 0x0050, 0x703c, 0x6016, 0x0ca0, 0x0016, 0x00e6, 0x2071,
-	0x0260, 0x00b6, 0x00c6, 0x2260, 0x6010, 0x2058, 0xb8d4, 0xd084,
-	0x0150, 0x7128, 0x604c, 0x9106, 0x1120, 0x712c, 0x6050, 0x9106,
-	0x0110, 0x9006, 0x0010, 0x9085, 0x0001, 0x00ce, 0x00be, 0x00ee,
-	0x001e, 0x0005, 0x0016, 0x0096, 0x0086, 0x00e6, 0x01c6, 0x01d6,
-	0x0126, 0x2091, 0x8000, 0x2071, 0x1800, 0x7090, 0x908a, 0x00f9,
-	0x16e8, 0x20e1, 0x0000, 0x2001, 0x199f, 0x2003, 0x0000, 0x080c,
-	0x1060, 0x05a0, 0x2900, 0x6016, 0x7090, 0x8004, 0xa816, 0x908a,
-	0x001e, 0x02d0, 0xa833, 0x001e, 0x20a9, 0x001e, 0xa860, 0x20e8,
-	0xa85c, 0x9080, 0x001b, 0x20a0, 0x2001, 0x199f, 0x0016, 0x200c,
-	0x0471, 0x001e, 0x2940, 0x080c, 0x1060, 0x01c0, 0x2900, 0xa006,
-	0x2100, 0x81ff, 0x0180, 0x0c18, 0xa832, 0x20a8, 0xa860, 0x20e8,
-	0xa85c, 0x9080, 0x001b, 0x20a0, 0x2001, 0x199f, 0x0016, 0x200c,
-	0x00b1, 0x001e, 0x0000, 0x9085, 0x0001, 0x0048, 0x2071, 0x1800,
-	0x7093, 0x0000, 0x6014, 0x2048, 0x080c, 0x0ff9, 0x9006, 0x012e,
-	0x01de, 0x01ce, 0x00ee, 0x008e, 0x009e, 0x001e, 0x0005, 0x0006,
-	0x0016, 0x0026, 0x0036, 0x00c6, 0x918c, 0xffff, 0x11a8, 0x080c,
-	0x21e3, 0x2099, 0x026c, 0x2001, 0x0014, 0x3518, 0x9312, 0x1218,
-	0x23a8, 0x4003, 0x00f8, 0x20a8, 0x4003, 0x22a8, 0x8108, 0x080c,
-	0x21e3, 0x2099, 0x0260, 0x0ca8, 0x080c, 0x21e3, 0x2061, 0x199f,
-	0x6004, 0x2098, 0x6008, 0x3518, 0x9312, 0x1218, 0x23a8, 0x4003,
-	0x0048, 0x20a8, 0x4003, 0x22a8, 0x8108, 0x080c, 0x21e3, 0x2099,
-	0x0260, 0x0ca8, 0x2061, 0x199f, 0x2019, 0x0280, 0x3300, 0x931e,
-	0x0110, 0x6006, 0x0020, 0x2001, 0x0260, 0x6006, 0x8108, 0x2162,
-	0x9292, 0x0021, 0x9296, 0xffff, 0x620a, 0x00ce, 0x003e, 0x002e,
-	0x001e, 0x000e, 0x0005, 0x0006, 0x0016, 0x0026, 0x0036, 0x00c6,
-	0x81ff, 0x11b8, 0x080c, 0x21fb, 0x20a1, 0x024c, 0x2001, 0x0014,
-	0x3518, 0x9312, 0x1218, 0x23a8, 0x4003, 0x0418, 0x20a8, 0x4003,
-	0x82ff, 0x01f8, 0x22a8, 0x8108, 0x080c, 0x21fb, 0x20a1, 0x0240,
-	0x0c98, 0x080c, 0x21fb, 0x2061, 0x19a2, 0x6004, 0x20a0, 0x6008,
-	0x3518, 0x9312, 0x1218, 0x23a8, 0x4003, 0x0058, 0x20a8, 0x4003,
-	0x82ff, 0x0138, 0x22a8, 0x8108, 0x080c, 0x21fb, 0x20a1, 0x0240,
-	0x0c98, 0x2061, 0x19a2, 0x2019, 0x0260, 0x3400, 0x931e, 0x0110,
-	0x6006, 0x0020, 0x2001, 0x0240, 0x6006, 0x8108, 0x2162, 0x9292,
-	0x0021, 0x9296, 0xffff, 0x620a, 0x00ce, 0x003e, 0x002e, 0x001e,
-	0x000e, 0x0005, 0x00b6, 0x0066, 0x6610, 0x2658, 0xbe04, 0x96b4,
-	0xff00, 0x8637, 0x9686, 0x0006, 0x0170, 0x9686, 0x0004, 0x0158,
-	0xbe04, 0x96b4, 0x00ff, 0x9686, 0x0006, 0x0128, 0x9686, 0x0004,
-	0x0110, 0x9085, 0x0001, 0x006e, 0x00be, 0x0005, 0x00d6, 0x080c,
-	0xd810, 0x00de, 0x0005, 0x00d6, 0x080c, 0xd81d, 0x1520, 0x680c,
-	0x908c, 0xff00, 0x6820, 0x9084, 0x00ff, 0x9115, 0x6216, 0x6824,
-	0x602e, 0xd1e4, 0x0130, 0x9006, 0x080c, 0xe80c, 0x2009, 0x0001,
-	0x0078, 0xd1ec, 0x0180, 0x6920, 0x918c, 0x00ff, 0x6824, 0x080c,
-	0x2661, 0x1148, 0x2001, 0x0001, 0x080c, 0xe80c, 0x2110, 0x900e,
-	0x080c, 0x328f, 0x0018, 0x9085, 0x0001, 0x0008, 0x9006, 0x00de,
-	0x0005, 0x00b6, 0x00c6, 0x080c, 0xad20, 0x0598, 0x0016, 0x0026,
-	0x00c6, 0x2011, 0x0263, 0x2204, 0x8211, 0x220c, 0x080c, 0x2661,
-	0x1568, 0x080c, 0x6632, 0x1550, 0xbe12, 0xbd16, 0x00ce, 0x002e,
-	0x001e, 0x2b00, 0x6012, 0x080c, 0xe63f, 0x11c8, 0x080c, 0x3377,
-	0x11b0, 0x080c, 0xd77a, 0x0500, 0x2001, 0x0007, 0x080c, 0x65e3,
-	0x2001, 0x0007, 0x080c, 0x660f, 0x6017, 0x0000, 0x6023, 0x0001,
-	0x6007, 0x0001, 0x6003, 0x0001, 0x080c, 0x92b7, 0x0010, 0x080c,
-	0xacb0, 0x9085, 0x0001, 0x00ce, 0x00be, 0x0005, 0x080c, 0xacb0,
-	0x00ce, 0x002e, 0x001e, 0x0ca8, 0x080c, 0xacb0, 0x9006, 0x0c98,
-	0x2069, 0x026d, 0x6800, 0x9082, 0x0010, 0x1228, 0x6017, 0x0000,
-	0x9085, 0x0001, 0x0008, 0x9006, 0x0005, 0x6017, 0x0000, 0x2069,
-	0x026c, 0x6808, 0x9084, 0xff00, 0x9086, 0x0800, 0x1190, 0x6904,
-	0x9186, 0x0018, 0x0118, 0x9186, 0x0014, 0x1158, 0x810f, 0x6800,
-	0x9084, 0x00ff, 0x910d, 0x6162, 0x908e, 0x0014, 0x0110, 0x908e,
-	0x0010, 0x0005, 0x6004, 0x90b2, 0x0053, 0x1a0c, 0x0d7d, 0x91b6,
-	0x0013, 0x1130, 0x2008, 0x91b2, 0x0040, 0x1a04, 0xd95f, 0x0092,
-	0x91b6, 0x0027, 0x0120, 0x91b6, 0x0014, 0x190c, 0x0d7d, 0x2001,
-	0x0007, 0x080c, 0x660f, 0x080c, 0x967a, 0x080c, 0xaceb, 0x080c,
-	0x9738, 0x0005, 0xd89a, 0xd89c, 0xd89a, 0xd89a, 0xd89a, 0xd89c,
-	0xd8a9, 0xd95c, 0xd8f9, 0xd95c, 0xd90d, 0xd95c, 0xd8a9, 0xd95c,
-	0xd954, 0xd95c, 0xd954, 0xd95c, 0xd95c, 0xd89a, 0xd89a, 0xd89a,
-	0xd89a, 0xd89a, 0xd89a, 0xd89a, 0xd89a, 0xd89a, 0xd89a, 0xd89a,
-	0xd89c, 0xd89a, 0xd95c, 0xd89a, 0xd89a, 0xd95c, 0xd89a, 0xd959,
-	0xd95c, 0xd89a, 0xd89a, 0xd89a, 0xd89a, 0xd95c, 0xd95c, 0xd89a,
-	0xd95c, 0xd95c, 0xd89a, 0xd8a4, 0xd89a, 0xd89a, 0xd89a, 0xd89a,
-	0xd958, 0xd95c, 0xd89a, 0xd89a, 0xd95c, 0xd95c, 0xd89a, 0xd89a,
-	0xd89a, 0xd89a, 0x080c, 0x0d7d, 0x080c, 0xd0b3, 0x6003, 0x0002,
-	0x080c, 0x9738, 0x0804, 0xd95e, 0x9006, 0x080c, 0x65cf, 0x0804,
-	0xd95c, 0x080c, 0x6ad5, 0x1904, 0xd95c, 0x9006, 0x080c, 0x65cf,
-	0x6010, 0x2058, 0xb810, 0x9086, 0x00ff, 0x1140, 0x00f6, 0x2079,
-	0x1800, 0x78a8, 0x8000, 0x78aa, 0x00fe, 0x0428, 0x6010, 0x2058,
-	0xb884, 0x9005, 0x1178, 0x080c, 0xd09b, 0x1904, 0xd95c, 0x0036,
-	0x0046, 0xbba0, 0x2021, 0x0007, 0x080c, 0x4d09, 0x004e, 0x003e,
-	0x0804, 0xd95c, 0x080c, 0x33a8, 0x1904, 0xd95c, 0x2001, 0x1800,
-	0x2004, 0x9086, 0x0002, 0x1138, 0x00f6, 0x2079, 0x1800, 0x78a8,
-	0x8000, 0x78aa, 0x00fe, 0x2001, 0x0002, 0x080c, 0x65e3, 0x6023,
-	0x0001, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x92b7, 0x080c,
-	0x9738, 0x6110, 0x2158, 0x2009, 0x0001, 0x080c, 0x86d6, 0x0804,
-	0xd95e, 0x6610, 0x2658, 0xbe04, 0x96b4, 0xff00, 0x8637, 0x9686,
-	0x0006, 0x0904, 0xd95c, 0x9686, 0x0004, 0x0904, 0xd95c, 0x080c,
-	0x8f52, 0x2001, 0x0004, 0x0804, 0xd95a, 0x2001, 0x1800, 0x2004,
-	0x9086, 0x0003, 0x1158, 0x0036, 0x0046, 0x6010, 0x2058, 0xbba0,
-	0x2021, 0x0006, 0x080c, 0x4d09, 0x004e, 0x003e, 0x2001, 0x0006,
-	0x080c, 0xd978, 0x6610, 0x2658, 0xbe04, 0x0066, 0x96b4, 0xff00,
-	0x8637, 0x9686, 0x0006, 0x006e, 0x0168, 0x2001, 0x0006, 0x080c,
-	0x660f, 0x9284, 0x00ff, 0x908e, 0x0007, 0x1120, 0x2001, 0x0006,
-	0x080c, 0x65e3, 0x080c, 0x6ad5, 0x11f8, 0x2001, 0x1837, 0x2004,
-	0xd0a4, 0x01d0, 0xbe04, 0x96b4, 0x00ff, 0x9686, 0x0006, 0x01a0,
-	0x00f6, 0x2079, 0x1800, 0x78a8, 0x8000, 0x78aa, 0x00fe, 0x0804,
-	0xd8e3, 0x2001, 0x0004, 0x0030, 0x2001, 0x0006, 0x0409, 0x0020,
-	0x0018, 0x0010, 0x080c, 0x660f, 0x080c, 0xacb0, 0x0005, 0x2600,
-	0x0002, 0xd973, 0xd973, 0xd973, 0xd973, 0xd973, 0xd975, 0xd973,
-	0xd975, 0xd973, 0xd973, 0xd975, 0xd973, 0xd973, 0xd973, 0xd975,
-	0xd975, 0xd975, 0xd975, 0x080c, 0x0d7d, 0x080c, 0xacb0, 0x0005,
-	0x0016, 0x00b6, 0x00d6, 0x6110, 0x2158, 0xb900, 0xd184, 0x0138,
-	0x080c, 0x65e3, 0x9006, 0x080c, 0x65cf, 0x080c, 0x326f, 0x00de,
-	0x00be, 0x001e, 0x0005, 0x6610, 0x2658, 0xb804, 0x9084, 0xff00,
-	0x8007, 0x90b2, 0x000c, 0x1a0c, 0x0d7d, 0x91b6, 0x0015, 0x1110,
-	0x003b, 0x0028, 0x91b6, 0x0016, 0x190c, 0x0d7d, 0x006b, 0x0005,
-	0xb77c, 0xb77c, 0xb77c, 0xb77c, 0xda0d, 0xb77c, 0xd9f7, 0xd9b8,
-	0xb77c, 0xb77c, 0xb77c, 0xb77c, 0xb77c, 0xb77c, 0xb77c, 0xb77c,
-	0xda0d, 0xb77c, 0xd9f7, 0xd9fe, 0xb77c, 0xb77c, 0xb77c, 0xb77c,
-	0x00f6, 0x080c, 0x6ad5, 0x11d8, 0x080c, 0xd09b, 0x11c0, 0x6010,
-	0x905d, 0x01a8, 0xb884, 0x9005, 0x0190, 0x9006, 0x080c, 0x65cf,
-	0x2001, 0x0002, 0x080c, 0x65e3, 0x6023, 0x0001, 0x6003, 0x0001,
-	0x6007, 0x0002, 0x080c, 0x92b7, 0x080c, 0x9738, 0x00f0, 0x2011,
-	0x0263, 0x2204, 0x8211, 0x220c, 0x080c, 0x2661, 0x11b0, 0x080c,
-	0x6693, 0x0118, 0x080c, 0xacb0, 0x0080, 0xb810, 0x0006, 0xb814,
-	0x0006, 0xb884, 0x0006, 0x080c, 0x60ac, 0x000e, 0xb886, 0x000e,
-	0xb816, 0x000e, 0xb812, 0x080c, 0xacb0, 0x00fe, 0x0005, 0x6604,
-	0x96b6, 0x001e, 0x1110, 0x080c, 0xacb0, 0x0005, 0x080c, 0xbb07,
-	0x1148, 0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x92b7, 0x080c,
-	0x9738, 0x0010, 0x080c, 0xacb0, 0x0005, 0x0804, 0xacb0, 0x6004,
-	0x908a, 0x0053, 0x1a0c, 0x0d7d, 0x080c, 0x967a, 0x080c, 0xaceb,
-	0x0005, 0x9182, 0x0040, 0x0002, 0xda30, 0xda30, 0xda30, 0xda30,
-	0xda32, 0xda30, 0xda30, 0xda30, 0xda30, 0xda30, 0xda30, 0xda30,
-	0xda30, 0xda30, 0xda30, 0xda30, 0xda30, 0xda30, 0xda30, 0xda30,
-	0x080c, 0x0d7d, 0x0096, 0x00b6, 0x00d6, 0x00e6, 0x00f6, 0x0046,
-	0x0026, 0x6210, 0x2258, 0xb8bc, 0x9005, 0x11b0, 0x6007, 0x0044,
-	0x2071, 0x0260, 0x7444, 0x94a4, 0xff00, 0x0904, 0xda99, 0x080c,
-	0xe800, 0x1170, 0x9486, 0x2000, 0x1158, 0x2009, 0x0001, 0x2011,
-	0x0200, 0x080c, 0x8979, 0x0020, 0x9026, 0x080c, 0xe684, 0x0c30,
-	0x080c, 0x1047, 0x090c, 0x0d7d, 0x6003, 0x0007, 0xa867, 0x010d,
-	0x9006, 0xa802, 0xa86a, 0xac8a, 0x2c00, 0xa88e, 0x6008, 0xa8e2,
-	0x6010, 0x2058, 0xb8a0, 0x7130, 0xa97a, 0x0016, 0xa876, 0xa87f,
-	0x0000, 0xa883, 0x0000, 0xa887, 0x0036, 0x080c, 0x6dee, 0x001e,
-	0x080c, 0xe800, 0x1904, 0xdaf9, 0x9486, 0x2000, 0x1130, 0x2019,
-	0x0017, 0x080c, 0xe3b5, 0x0804, 0xdaf9, 0x9486, 0x0200, 0x1120,
-	0x080c, 0xe345, 0x0804, 0xdaf9, 0x9486, 0x0400, 0x0120, 0x9486,
-	0x1000, 0x1904, 0xdaf9, 0x2019, 0x0002, 0x080c, 0xe364, 0x0804,
-	0xdaf9, 0x2069, 0x1a6e, 0x6a00, 0xd284, 0x0904, 0xdb63, 0x9284,
-	0x0300, 0x1904, 0xdb5c, 0x6804, 0x9005, 0x0904, 0xdb44, 0x2d78,
-	0x6003, 0x0007, 0x080c, 0x1060, 0x0904, 0xdb05, 0x7800, 0xd08c,
-	0x1118, 0x7804, 0x8001, 0x7806, 0x6017, 0x0000, 0x2001, 0x180f,
-	0x2004, 0xd084, 0x1904, 0xdb67, 0x9006, 0xa802, 0xa867, 0x0116,
-	0xa86a, 0x6008, 0xa8e2, 0x2c00, 0xa87a, 0x6010, 0x2058, 0xb8a0,
-	0x7130, 0xa9b6, 0xa876, 0xb928, 0xa9ba, 0xb92c, 0xa9be, 0xb930,
-	0xa9c2, 0xb934, 0xa9c6, 0xa883, 0x003d, 0x7044, 0x9084, 0x0003,
-	0x9080, 0xdb01, 0x2005, 0xa87e, 0x20a9, 0x000a, 0x2001, 0x0270,
-	0xaa5c, 0x9290, 0x0021, 0x2009, 0x0205, 0x200b, 0x0080, 0x20e1,
-	0x0000, 0xab60, 0x23e8, 0x2098, 0x22a0, 0x4003, 0x200b, 0x0000,
-	0x2001, 0x027a, 0x200c, 0xa9b2, 0x8000, 0x200c, 0xa9ae, 0x080c,
-	0x6df1, 0x002e, 0x004e, 0x00fe, 0x00ee, 0x00de, 0x00be, 0x009e,
-	0x0005, 0x0000, 0x0080, 0x0040, 0x0000, 0x2001, 0x1810, 0x2004,
-	0xd084, 0x0120, 0x080c, 0x1047, 0x1904, 0xdaae, 0x6017, 0xf100,
-	0x6003, 0x0001, 0x6007, 0x0041, 0x2009, 0xa022, 0x080c, 0x92b0,
-	0x0c00, 0x2069, 0x0260, 0x6848, 0x9084, 0xff00, 0x9086, 0x1200,
-	0x1198, 0x686c, 0x9084, 0x00ff, 0x0016, 0x6114, 0x918c, 0xf700,
-	0x910d, 0x6116, 0x001e, 0x6003, 0x0001, 0x6007, 0x0043, 0x2009,
-	0xa025, 0x080c, 0x92b0, 0x0828, 0x6868, 0x602e, 0x686c, 0x6032,
-	0x6017, 0xf200, 0x6003, 0x0001, 0x6007, 0x0041, 0x2009, 0xa022,
-	0x080c, 0x92b0, 0x0804, 0xdaf9, 0x2001, 0x180e, 0x2004, 0xd0ec,
-	0x0120, 0x2011, 0x8049, 0x080c, 0x4b52, 0x6017, 0xf300, 0x0010,
-	0x6017, 0xf100, 0x6003, 0x0001, 0x6007, 0x0041, 0x2009, 0xa022,
-	0x080c, 0x92b0, 0x0804, 0xdaf9, 0x6017, 0xf500, 0x0c98, 0x6017,
-	0xf600, 0x0804, 0xdb19, 0x6017, 0xf200, 0x0804, 0xdb19, 0xa867,
-	0x0146, 0xa86b, 0x0000, 0x6008, 0xa886, 0x2c00, 0xa87a, 0x7044,
-	0x9084, 0x0003, 0x9080, 0xdb01, 0x2005, 0xa87e, 0x2928, 0x6010,
-	0x2058, 0xb8a0, 0xa876, 0xb828, 0xa88a, 0xb82c, 0xa88e, 0xb830,
-	0xa892, 0xb834, 0xa896, 0xa883, 0x003d, 0x2009, 0x0205, 0x2104,
-	0x9085, 0x0080, 0x200a, 0x20e1, 0x0000, 0x2011, 0x0210, 0x2214,
-	0x9294, 0x0fff, 0xaaa2, 0x9282, 0x0111, 0x1a0c, 0x0d7d, 0x8210,
-	0x821c, 0x2001, 0x026c, 0x2098, 0xa860, 0x20e8, 0xa85c, 0x9080,
-	0x0029, 0x20a0, 0x2011, 0xdbe3, 0x2041, 0x0001, 0x223d, 0x9784,
-	0x00ff, 0x9322, 0x1208, 0x2300, 0x20a8, 0x4003, 0x931a, 0x0530,
-	0x8210, 0xd7fc, 0x1130, 0x8d68, 0x2d0a, 0x2001, 0x0260, 0x2098,
-	0x0c68, 0x2950, 0x080c, 0x1060, 0x0170, 0x2900, 0xb002, 0xa867,
-	0x0147, 0xa86b, 0x0000, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x001b,
-	0x20a0, 0x8840, 0x08d8, 0x2548, 0xa800, 0x902d, 0x0118, 0x080c,
-	0x1079, 0x0cc8, 0x080c, 0x1079, 0x0804, 0xdb05, 0x2548, 0x8847,
-	0x9885, 0x0046, 0xa866, 0x2009, 0x0205, 0x200b, 0x0000, 0x080c,
-	0xe3e8, 0x0804, 0xdaf9, 0x8010, 0x0004, 0x801a, 0x0006, 0x8018,
-	0x0008, 0x8016, 0x000a, 0x8014, 0x9186, 0x0013, 0x1160, 0x6004,
-	0x908a, 0x0057, 0x1a0c, 0x0d7d, 0x9082, 0x0040, 0x0a0c, 0x0d7d,
-	0x2008, 0x0804, 0xdc6f, 0x9186, 0x0051, 0x0108, 0x0040, 0x080c,
-	0xab33, 0x01e8, 0x9086, 0x0002, 0x0904, 0xdcb7, 0x00c0, 0x9186,
-	0x0027, 0x0180, 0x9186, 0x0048, 0x0128, 0x9186, 0x0014, 0x0150,
-	0x190c, 0x0d7d, 0x080c, 0xab33, 0x0150, 0x9086, 0x0004, 0x0904,
-	0xdd56, 0x0028, 0x6004, 0x9082, 0x0040, 0x2008, 0x001a, 0x080c,
-	0xad6a, 0x0005, 0xdc36, 0xdc38, 0xdc38, 0xdc5f, 0xdc36, 0xdc36,
-	0xdc36, 0xdc36, 0xdc36, 0xdc36, 0xdc36, 0xdc36, 0xdc36, 0xdc36,
-	0xdc36, 0xdc36, 0xdc36, 0xdc36, 0xdc36, 0xdc36, 0x080c, 0x0d7d,
-	0x080c, 0x967a, 0x080c, 0x9738, 0x0036, 0x0096, 0x6014, 0x904d,
-	0x01d8, 0x080c, 0xc97a, 0x01c0, 0x6003, 0x0002, 0x6010, 0x00b6,
-	0x2058, 0xb800, 0x00be, 0xd0bc, 0x1178, 0x2019, 0x0004, 0x080c,
-	0xe3e8, 0x6017, 0x0000, 0x6018, 0x9005, 0x1120, 0x2001, 0x1986,
-	0x2004, 0x601a, 0x6003, 0x0007, 0x009e, 0x003e, 0x0005, 0x0096,
-	0x080c, 0x967a, 0x080c, 0x9738, 0x080c, 0xc97a, 0x0120, 0x6014,
-	0x2048, 0x080c, 0x1079, 0x080c, 0xaceb, 0x009e, 0x0005, 0x0002,
-	0xdc84, 0xdc99, 0xdc86, 0xdcae, 0xdc84, 0xdc84, 0xdc84, 0xdc84,
-	0xdc84, 0xdc84, 0xdc84, 0xdc84, 0xdc84, 0xdc84, 0xdc84, 0xdc84,
-	0xdc84, 0xdc84, 0xdc84, 0xdc84, 0x080c, 0x0d7d, 0x0096, 0x6014,
-	0x2048, 0xa87c, 0xd0b4, 0x0138, 0x6003, 0x0007, 0x2009, 0x0043,
-	0x080c, 0xad4d, 0x0010, 0x6003, 0x0004, 0x080c, 0x9738, 0x009e,
-	0x0005, 0x080c, 0xc97a, 0x0138, 0x6114, 0x0096, 0x2148, 0xa97c,
-	0x009e, 0xd1ec, 0x1138, 0x080c, 0x894e, 0x080c, 0xacb0, 0x080c,
-	0x9738, 0x0005, 0x080c, 0xe648, 0x0db0, 0x0cc8, 0x6003, 0x0001,
-	0x6007, 0x0041, 0x2009, 0xa022, 0x080c, 0x92b0, 0x0005, 0x9182,
-	0x0040, 0x0002, 0xdcce, 0xdcd0, 0xdcce, 0xdcce, 0xdcce, 0xdcce,
-	0xdcce, 0xdcce, 0xdcce, 0xdcce, 0xdcce, 0xdcce, 0xdcce, 0xdcce,
-	0xdcce, 0xdcce, 0xdcce, 0xdcd1, 0xdcce, 0xdcce, 0x080c, 0x0d7d,
-	0x0005, 0x00d6, 0x080c, 0x894e, 0x00de, 0x080c, 0xe6a0, 0x080c,
-	0xacb0, 0x0005, 0x9182, 0x0040, 0x0002, 0xdcf1, 0xdcf1, 0xdcf1,
-	0xdcf1, 0xdcf1, 0xdcf1, 0xdcf1, 0xdcf1, 0xdcf1, 0xdcf3, 0xdd1e,
-	0xdcf1, 0xdcf1, 0xdcf1, 0xdcf1, 0xdd1e, 0xdcf1, 0xdcf1, 0xdcf1,
-	0xdcf1, 0x080c, 0x0d7d, 0x6014, 0x0096, 0x2048, 0xa87c, 0xd0fc,
-	0x0168, 0x908c, 0x0003, 0x918e, 0x0002, 0x0180, 0x6144, 0xd1e4,
-	0x1168, 0x2009, 0x0041, 0x009e, 0x0804, 0xddde, 0x6003, 0x0007,
-	0x601b, 0x0000, 0x080c, 0x894e, 0x009e, 0x0005, 0x6014, 0x2048,
-	0xa97c, 0xd1ec, 0x1130, 0x080c, 0x894e, 0x080c, 0xacb0, 0x009e,
-	0x0005, 0x080c, 0xe648, 0x0db8, 0x009e, 0x0005, 0x2001, 0x180c,
-	0x200c, 0xc1d4, 0x2102, 0x0036, 0x080c, 0x96d5, 0x080c, 0x9738,
-	0x6014, 0x0096, 0x2048, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be,
-	0xd0bc, 0x0188, 0xa87c, 0x9084, 0x0003, 0x9086, 0x0002, 0x0140,
-	0xa8ac, 0x6330, 0x931a, 0x6332, 0xa8b0, 0x632c, 0x931b, 0x632e,
-	0x6003, 0x0002, 0x0080, 0x2019, 0x0004, 0x080c, 0xe3e8, 0x6018,
-	0x9005, 0x1128, 0x2001, 0x1986, 0x2004, 0x8003, 0x601a, 0x6017,
-	0x0000, 0x6003, 0x0007, 0x009e, 0x003e, 0x0005, 0x9182, 0x0040,
-	0x0002, 0xdd6d, 0xdd6d, 0xdd6d, 0xdd6d, 0xdd6d, 0xdd6d, 0xdd6d,
-	0xdd6d, 0xdd6f, 0xdd6d, 0xdd6d, 0xdd6d, 0xdd6d, 0xdd6d, 0xdd6d,
-	0xdd6d, 0xdd6d, 0xdd6d, 0xdd6d, 0xddba, 0x080c, 0x0d7d, 0x6014,
-	0x0096, 0x2048, 0xa834, 0xaa38, 0x6110, 0x00b6, 0x2158, 0xb900,
-	0x00be, 0xd1bc, 0x1190, 0x920d, 0x1518, 0xa87c, 0xd0fc, 0x0128,
-	0x2009, 0x0041, 0x009e, 0x0804, 0xddde, 0x6003, 0x0007, 0x601b,
-	0x0000, 0x080c, 0x894e, 0x009e, 0x0005, 0x6124, 0xd1f4, 0x1d58,
-	0x0006, 0x0046, 0xacac, 0x9422, 0xa9b0, 0x2200, 0x910b, 0x6030,
-	0x9420, 0x6432, 0x602c, 0x9109, 0x612e, 0x004e, 0x000e, 0x08d8,
-	0x6110, 0x00b6, 0x2158, 0xb900, 0x00be, 0xd1bc, 0x1178, 0x2009,
-	0x180e, 0x210c, 0xd19c, 0x0118, 0x6003, 0x0007, 0x0010, 0x6003,
-	0x0006, 0x00e9, 0x080c, 0x8950, 0x009e, 0x0005, 0x6003, 0x0002,
-	0x009e, 0x0005, 0x6024, 0xd0f4, 0x0128, 0x080c, 0x1697, 0x1904,
-	0xdd6f, 0x0005, 0x6014, 0x0096, 0x2048, 0xa834, 0xa938, 0x009e,
-	0x9105, 0x1120, 0x080c, 0x1697, 0x1904, 0xdd6f, 0x0005, 0xd2fc,
-	0x0140, 0x8002, 0x8000, 0x8212, 0x9291, 0x0000, 0x2009, 0x0009,
-	0x0010, 0x2009, 0x0015, 0xaa9a, 0xa896, 0x0005, 0x9182, 0x0040,
-	0x0208, 0x0062, 0x9186, 0x0013, 0x0120, 0x9186, 0x0014, 0x190c,
-	0x0d7d, 0x6024, 0xd0dc, 0x090c, 0x0d7d, 0x0005, 0xde02, 0xde0e,
-	0xde1a, 0xde26, 0xde02, 0xde02, 0xde02, 0xde02, 0xde09, 0xde04,
-	0xde04, 0xde02, 0xde02, 0xde02, 0xde02, 0xde04, 0xde02, 0xde04,
-	0xde02, 0xde09, 0x080c, 0x0d7d, 0x6024, 0xd0dc, 0x090c, 0x0d7d,
-	0x0005, 0x6014, 0x9005, 0x190c, 0x0d7d, 0x0005, 0x6003, 0x0001,
-	0x6106, 0x0126, 0x2091, 0x8000, 0x2009, 0xa022, 0x080c, 0x9292,
-	0x012e, 0x0005, 0x6003, 0x0004, 0x6106, 0x0126, 0x2091, 0x8000,
-	0x2009, 0xa001, 0x080c, 0x92b0, 0x012e, 0x0005, 0x6003, 0x0003,
-	0x6106, 0x080c, 0x1c59, 0x0126, 0x2091, 0x8000, 0x6014, 0x0096,
-	0x2048, 0xa87c, 0xd0fc, 0x0188, 0x9084, 0x0003, 0x9086, 0x0002,
-	0x01a0, 0x6024, 0xd0cc, 0x1148, 0xd0c4, 0x1138, 0xa8a8, 0x9005,
-	0x1120, 0x6144, 0x918d, 0xb035, 0x0018, 0x6144, 0x918d, 0xa035,
-	0x009e, 0x080c, 0x92f7, 0x012e, 0x0005, 0x6144, 0x918d, 0xa032,
-	0x0cb8, 0x0126, 0x2091, 0x8000, 0x0036, 0x0096, 0x9182, 0x0040,
-	0x0023, 0x009e, 0x003e, 0x012e, 0x0005, 0xde71, 0xde73, 0xde88,
-	0xdea2, 0xde71, 0xde71, 0xde71, 0xde71, 0xde71, 0xde71, 0xde71,
-	0xde71, 0xde71, 0xde71, 0xde71, 0xde71, 0xde71, 0xde71, 0xde71,
-	0xde71, 0x080c, 0x0d7d, 0x6014, 0x2048, 0xa87c, 0xd0fc, 0x0510,
-	0x909c, 0x0003, 0x939e, 0x0003, 0x01e8, 0x6003, 0x0001, 0x6106,
-	0x0126, 0x2091, 0x8000, 0x2009, 0xa022, 0x080c, 0x92b0, 0x0470,
-	0x6014, 0x2048, 0xa87c, 0xd0fc, 0x0168, 0x909c, 0x0003, 0x939e,
-	0x0003, 0x0140, 0x6003, 0x0001, 0x6106, 0x2009, 0xa001, 0x080c,
-	0x92b0, 0x00e0, 0x901e, 0x6316, 0x631a, 0x2019, 0x0004, 0x080c,
-	0xe3e8, 0x00a0, 0x6014, 0x2048, 0xa87c, 0xd0fc, 0x0d98, 0x909c,
-	0x0003, 0x939e, 0x0003, 0x0d70, 0x6003, 0x0003, 0x6106, 0x080c,
-	0x1c59, 0x6144, 0x918d, 0xa035, 0x080c, 0x92f7, 0x0005, 0x080c,
-	0x967a, 0x6114, 0x81ff, 0x0158, 0x0096, 0x2148, 0x080c, 0xe79d,
-	0x0036, 0x2019, 0x0029, 0x080c, 0xe3e8, 0x003e, 0x009e, 0x080c,
-	0xaceb, 0x080c, 0x9738, 0x0005, 0x080c, 0x96d5, 0x6114, 0x81ff,
-	0x0158, 0x0096, 0x2148, 0x080c, 0xe79d, 0x0036, 0x2019, 0x0029,
-	0x080c, 0xe3e8, 0x003e, 0x009e, 0x080c, 0xaceb, 0x0005, 0x9182,
-	0x0085, 0x0002, 0xdef1, 0xdeef, 0xdeef, 0xdefd, 0xdeef, 0xdeef,
-	0xdeef, 0xdeef, 0xdeef, 0xdeef, 0xdeef, 0xdeef, 0xdeef, 0x080c,
-	0x0d7d, 0x6003, 0x000b, 0x6106, 0x0126, 0x2091, 0x8000, 0x2009,
-	0x8020, 0x080c, 0x92b0, 0x012e, 0x0005, 0x0026, 0x00e6, 0x080c,
-	0xe63f, 0x0118, 0x080c, 0xacb0, 0x0440, 0x2071, 0x0260, 0x7224,
-	0x6216, 0x2001, 0x180e, 0x2004, 0xd0e4, 0x0150, 0x6010, 0x00b6,
-	0x2058, 0xbca0, 0x00be, 0x2c00, 0x2011, 0x014e, 0x080c, 0xafdb,
-	0x7220, 0x080c, 0xe27e, 0x0118, 0x6007, 0x0086, 0x0040, 0x6007,
-	0x0087, 0x7224, 0x9296, 0xffff, 0x1110, 0x6007, 0x0086, 0x6003,
-	0x0001, 0x2009, 0x8020, 0x080c, 0x92b0, 0x00ee, 0x002e, 0x0005,
-	0x9186, 0x0013, 0x1160, 0x6004, 0x908a, 0x0085, 0x0a0c, 0x0d7d,
-	0x908a, 0x0092, 0x1a0c, 0x0d7d, 0x9082, 0x0085, 0x00a2, 0x9186,
-	0x0027, 0x0130, 0x9186, 0x0014, 0x0118, 0x080c, 0xad6a, 0x0050,
-	0x2001, 0x0007, 0x080c, 0x660f, 0x080c, 0x967a, 0x080c, 0xaceb,
-	0x080c, 0x9738, 0x0005, 0xdf60, 0xdf62, 0xdf62, 0xdf60, 0xdf60,
-	0xdf60, 0xdf60, 0xdf60, 0xdf60, 0xdf60, 0xdf60, 0xdf60, 0xdf60,
-	0x080c, 0x0d7d, 0x080c, 0xaceb, 0x080c, 0x9738, 0x0005, 0x9182,
-	0x0085, 0x0a0c, 0x0d7d, 0x9182, 0x0092, 0x1a0c, 0x0d7d, 0x9182,
-	0x0085, 0x0002, 0xdf7f, 0xdf7f, 0xdf7f, 0xdf81, 0xdf7f, 0xdf7f,
-	0xdf7f, 0xdf7f, 0xdf7f, 0xdf7f, 0xdf7f, 0xdf7f, 0xdf7f, 0x080c,
-	0x0d7d, 0x0005, 0x9186, 0x0013, 0x0148, 0x9186, 0x0014, 0x0130,
-	0x9186, 0x0027, 0x0118, 0x080c, 0xad6a, 0x0020, 0x080c, 0x967a,
-	0x080c, 0xaceb, 0x0005, 0x0036, 0x080c, 0xe6a0, 0x604b, 0x0000,
-	0x2019, 0x000b, 0x0031, 0x6023, 0x0006, 0x6003, 0x0007, 0x003e,
-	0x0005, 0x0126, 0x0036, 0x2091, 0x8000, 0x080c, 0xa91e, 0x0106,
-	0x0086, 0x2c40, 0x0096, 0x904e, 0x080c, 0xa28c, 0x009e, 0x008e,
-	0x1558, 0x0076, 0x2c38, 0x080c, 0xa337, 0x007e, 0x1528, 0x6000,
-	0x9086, 0x0000, 0x0508, 0x6020, 0x9086, 0x0007, 0x01e8, 0x0096,
-	0x601c, 0xd084, 0x0140, 0x080c, 0xe6a0, 0x080c, 0xd0b3, 0x080c,
-	0x1ac5, 0x6023, 0x0007, 0x6014, 0x2048, 0x080c, 0xc97a, 0x0110,
-	0x080c, 0xe3e8, 0x009e, 0x9006, 0x6046, 0x6016, 0x080c, 0xe6a0,
-	0x6023, 0x0007, 0x080c, 0xd0b3, 0x010e, 0x090c, 0xa93a, 0x003e,
-	0x012e, 0x0005, 0x00f6, 0x00c6, 0x00b6, 0x0036, 0x0156, 0x2079,
-	0x0260, 0x7938, 0x783c, 0x080c, 0x2661, 0x15e8, 0x0016, 0x00c6,
-	0x080c, 0x6693, 0x15b0, 0x001e, 0x00c6, 0x2160, 0x080c, 0xd0b0,
-	0x00ce, 0x002e, 0x0026, 0x0016, 0x080c, 0xa91e, 0x2019, 0x0029,
-	0x080c, 0xa404, 0x080c, 0x943d, 0x0076, 0x903e, 0x080c, 0x9306,
-	0x007e, 0x001e, 0x0076, 0x903e, 0x080c, 0xe167, 0x007e, 0x080c,
-	0xa93a, 0x0026, 0xba04, 0x9294, 0xff00, 0x8217, 0x9286, 0x0006,
-	0x0118, 0x9286, 0x0004, 0x1118, 0xbaa0, 0x080c, 0x330b, 0x002e,
-	0xbc84, 0x001e, 0x080c, 0x60ac, 0xbe12, 0xbd16, 0xbc86, 0x9006,
-	0x0010, 0x00ce, 0x001e, 0x015e, 0x003e, 0x00be, 0x00ce, 0x00fe,
-	0x0005, 0x00c6, 0x00d6, 0x00b6, 0x0016, 0x2009, 0x1824, 0x2104,
-	0x9086, 0x0074, 0x1904, 0xe08a, 0x2069, 0x0260, 0x6944, 0x9182,
-	0x0100, 0x06e0, 0x6940, 0x9184, 0x8000, 0x0904, 0xe087, 0x2001,
-	0x197b, 0x2004, 0x9005, 0x1140, 0x6010, 0x2058, 0xb884, 0x9005,
-	0x0118, 0x9184, 0x0800, 0x0598, 0x6948, 0x918a, 0x0001, 0x0648,
-	0x080c, 0xe805, 0x0118, 0x6978, 0xd1fc, 0x11b8, 0x2009, 0x0205,
-	0x200b, 0x0001, 0x693c, 0x81ff, 0x1198, 0x6944, 0x9182, 0x0100,
-	0x02a8, 0x6940, 0x81ff, 0x1178, 0x6948, 0x918a, 0x0001, 0x0288,
-	0x6950, 0x918a, 0x0001, 0x0298, 0x00d0, 0x6017, 0x0100, 0x00a0,
-	0x6017, 0x0300, 0x0088, 0x6017, 0x0500, 0x0070, 0x6017, 0x0700,
-	0x0058, 0x6017, 0x0900, 0x0040, 0x6017, 0x0b00, 0x0028, 0x6017,
-	0x0f00, 0x0010, 0x6017, 0x2d00, 0x9085, 0x0001, 0x0008, 0x9006,
-	0x001e, 0x00be, 0x00de, 0x00ce, 0x0005, 0x00c6, 0x00b6, 0x0026,
-	0x0036, 0x0156, 0x6210, 0x2258, 0xbb04, 0x9394, 0x00ff, 0x9286,
-	0x0006, 0x0180, 0x9286, 0x0004, 0x0168, 0x9394, 0xff00, 0x8217,
-	0x9286, 0x0006, 0x0138, 0x9286, 0x0004, 0x0120, 0x080c, 0x66a2,
-	0x0804, 0xe0f6, 0x2011, 0x0276, 0x20a9, 0x0004, 0x0096, 0x2b48,
-	0x2019, 0x000a, 0x080c, 0xbca2, 0x009e, 0x15c8, 0x2011, 0x027a,
-	0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019, 0x0006, 0x080c, 0xbca2,
-	0x009e, 0x1568, 0x0046, 0x0016, 0xbaa0, 0x2220, 0x9006, 0x2009,
-	0x1848, 0x210c, 0xd1a4, 0x0138, 0x2009, 0x0029, 0x080c, 0xe445,
-	0xb800, 0xc0e5, 0xb802, 0x080c, 0xa91e, 0x2019, 0x0029, 0x080c,
-	0x943d, 0x0076, 0x2039, 0x0000, 0x080c, 0x9306, 0x2c08, 0x080c,
-	0xe167, 0x007e, 0x080c, 0xa93a, 0x2001, 0x0007, 0x080c, 0x660f,
-	0x2001, 0x0007, 0x080c, 0x65e3, 0x001e, 0x004e, 0x9006, 0x015e,
-	0x003e, 0x002e, 0x00be, 0x00ce, 0x0005, 0x00d6, 0x2069, 0x026e,
-	0x6800, 0x9086, 0x0800, 0x0118, 0x6017, 0x0000, 0x0008, 0x9006,
-	0x00de, 0x0005, 0x00b6, 0x00f6, 0x0016, 0x0026, 0x0036, 0x0156,
-	0x2079, 0x026c, 0x7930, 0x7834, 0x080c, 0x2661, 0x11d0, 0x080c,
-	0x6693, 0x11b8, 0x2011, 0x0270, 0x20a9, 0x0004, 0x0096, 0x2b48,
-	0x2019, 0x000a, 0x080c, 0xbca2, 0x009e, 0x1158, 0x2011, 0x0274,
-	0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019, 0x0006, 0x080c, 0xbca2,
-	0x009e, 0x015e, 0x003e, 0x002e, 0x001e, 0x00fe, 0x00be, 0x0005,
-	0x00b6, 0x0006, 0x0016, 0x0026, 0x0036, 0x0156, 0x2011, 0x0263,
-	0x2204, 0x8211, 0x220c, 0x080c, 0x2661, 0x11d0, 0x080c, 0x6693,
-	0x11b8, 0x2011, 0x0276, 0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019,
-	0x000a, 0x080c, 0xbca2, 0x009e, 0x1158, 0x2011, 0x027a, 0x20a9,
-	0x0004, 0x0096, 0x2b48, 0x2019, 0x0006, 0x080c, 0xbca2, 0x009e,
-	0x015e, 0x003e, 0x002e, 0x001e, 0x000e, 0x00be, 0x0005, 0x00e6,
-	0x00c6, 0x0086, 0x0076, 0x0066, 0x0056, 0x0046, 0x0026, 0x0126,
-	0x2091, 0x8000, 0x080c, 0xa97c, 0x0106, 0x190c, 0xa91e, 0x2740,
-	0x2029, 0x19f2, 0x252c, 0x2021, 0x19f9, 0x2424, 0x2061, 0x1ddc,
-	0x2071, 0x1800, 0x7654, 0x7074, 0x81ff, 0x0150, 0x0006, 0x9186,
-	0x1b34, 0x000e, 0x0128, 0x8001, 0x9602, 0x1a04, 0xe20c, 0x0018,
-	0x9606, 0x0904, 0xe20c, 0x080c, 0x8c1f, 0x0904, 0xe203, 0x2100,
-	0x9c06, 0x0904, 0xe203, 0x080c, 0xe486, 0x1904, 0xe203, 0x080c,
-	0xe822, 0x0904, 0xe203, 0x080c, 0xe476, 0x0904, 0xe203, 0x6720,
-	0x9786, 0x0001, 0x1148, 0x080c, 0x33a8, 0x0904, 0xe24e, 0x6004,
-	0x9086, 0x0000, 0x1904, 0xe24e, 0x9786, 0x0004, 0x0904, 0xe24e,
-	0x9786, 0x0007, 0x0904, 0xe203, 0x2500, 0x9c06, 0x0904, 0xe203,
-	0x2400, 0x9c06, 0x0904, 0xe203, 0x88ff, 0x0118, 0x605c, 0x9906,
-	0x15d0, 0x0096, 0x6043, 0xffff, 0x6000, 0x9086, 0x0004, 0x1120,
-	0x0016, 0x080c, 0x1ac5, 0x001e, 0x9786, 0x000a, 0x0148, 0x080c,
-	0xcb91, 0x1130, 0x080c, 0xb693, 0x009e, 0x080c, 0xaceb, 0x0418,
-	0x6014, 0x2048, 0x080c, 0xc97a, 0x01d8, 0x9786, 0x0003, 0x1588,
-	0xa867, 0x0103, 0xa87c, 0xd0cc, 0x0130, 0x0096, 0xa878, 0x2048,
-	0x080c, 0x0ff9, 0x009e, 0xab7a, 0xa877, 0x0000, 0x080c, 0xe79d,
-	0x0016, 0x080c, 0xcc7f, 0x080c, 0x6de2, 0x001e, 0x080c, 0xcb6b,
-	0x009e, 0x080c, 0xaceb, 0x9ce0, 0x001c, 0x2001, 0x181a, 0x2004,
-	0x9c02, 0x1210, 0x0804, 0xe180, 0x010e, 0x190c, 0xa93a, 0x012e,
-	0x002e, 0x004e, 0x005e, 0x006e, 0x007e, 0x008e, 0x00ce, 0x00ee,
-	0x0005, 0x9786, 0x0006, 0x1150, 0x9386, 0x0005, 0x0128, 0x080c,
-	0xe79d, 0x080c, 0xe3e8, 0x08e0, 0x009e, 0x08e8, 0x9786, 0x0009,
-	0x11f8, 0x6000, 0x9086, 0x0004, 0x01c0, 0x6000, 0x9086, 0x0003,
-	0x11a0, 0x080c, 0x96d5, 0x0096, 0x6114, 0x2148, 0x080c, 0xc97a,
-	0x0118, 0x6010, 0x080c, 0x6dee, 0x009e, 0x00c6, 0x080c, 0xacb0,
-	0x00ce, 0x0036, 0x080c, 0x9738, 0x003e, 0x009e, 0x0804, 0xe203,
-	0x9786, 0x000a, 0x0904, 0xe1f3, 0x0804, 0xe1e8, 0x81ff, 0x0904,
-	0xe203, 0x9180, 0x0001, 0x2004, 0x9086, 0x0018, 0x0138, 0x9180,
-	0x0001, 0x2004, 0x9086, 0x002d, 0x1904, 0xe203, 0x6000, 0x9086,
-	0x0002, 0x1904, 0xe203, 0x080c, 0xcb80, 0x0138, 0x080c, 0xcb91,
-	0x1904, 0xe203, 0x080c, 0xb693, 0x0038, 0x080c, 0x326f, 0x080c,
-	0xcb91, 0x1110, 0x080c, 0xb693, 0x080c, 0xaceb, 0x0804, 0xe203,
-	0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, 0x0005, 0x00c6, 0x00e6,
-	0x0016, 0x2c08, 0x2170, 0x9006, 0x080c, 0xe40f, 0x001e, 0x0120,
-	0x6020, 0x9084, 0x000f, 0x001b, 0x00ee, 0x00ce, 0x0005, 0xe29d,
-	0xe29d, 0xe29d, 0xe29d, 0xe29d, 0xe29d, 0xe29f, 0xe29d, 0xe29d,
-	0xe29d, 0xe29d, 0xaceb, 0xaceb, 0xe29d, 0x9006, 0x0005, 0x0036,
-	0x0046, 0x0016, 0x7010, 0x00b6, 0x2058, 0xbca0, 0x00be, 0x2c00,
-	0x2009, 0x0020, 0x080c, 0xe445, 0x001e, 0x004e, 0x2019, 0x0002,
-	0x080c, 0xdfa1, 0x003e, 0x9085, 0x0001, 0x0005, 0x0096, 0x080c,
-	0xc97a, 0x0140, 0x6014, 0x904d, 0x080c, 0xc566, 0x687b, 0x0005,
-	0x080c, 0x6dee, 0x009e, 0x080c, 0xaceb, 0x9085, 0x0001, 0x0005,
-	0x2001, 0x0001, 0x080c, 0x65cf, 0x0156, 0x0016, 0x0026, 0x0036,
-	0x20a9, 0x0004, 0x2019, 0x1805, 0x2011, 0x0276, 0x080c, 0xbc8e,
-	0x003e, 0x002e, 0x001e, 0x015e, 0x9005, 0x0005, 0x00f6, 0x00e6,
-	0x00c6, 0x0086, 0x0076, 0x0066, 0x00b6, 0x0126, 0x2091, 0x8000,
-	0x2740, 0x2061, 0x1ddc, 0x2079, 0x0001, 0x8fff, 0x0904, 0xe338,
-	0x2071, 0x1800, 0x7654, 0x7074, 0x8001, 0x9602, 0x1a04, 0xe338,
-	0x88ff, 0x0120, 0x2800, 0x9c06, 0x1590, 0x2078, 0x080c, 0xe476,
-	0x0570, 0x2400, 0x9c06, 0x0558, 0x6720, 0x9786, 0x0006, 0x1538,
-	0x9786, 0x0007, 0x0520, 0x88ff, 0x1140, 0x6010, 0x9b06, 0x11f8,
-	0x85ff, 0x0118, 0x605c, 0x9106, 0x11d0, 0x0096, 0x601c, 0xd084,
-	0x0140, 0x080c, 0xe6a0, 0x080c, 0xd0b3, 0x080c, 0x1ac5, 0x6023,
-	0x0007, 0x6014, 0x2048, 0x080c, 0xc97a, 0x0120, 0x0046, 0x080c,
-	0xe3e8, 0x004e, 0x009e, 0x080c, 0xaceb, 0x88ff, 0x1198, 0x9ce0,
-	0x001c, 0x2001, 0x181a, 0x2004, 0x9c02, 0x1210, 0x0804, 0xe2ed,
-	0x9006, 0x012e, 0x00be, 0x006e, 0x007e, 0x008e, 0x00ce, 0x00ee,
-	0x00fe, 0x0005, 0x98c5, 0x0001, 0x0ca0, 0x080c, 0xa91e, 0x00b6,
-	0x0076, 0x0056, 0x0086, 0x9046, 0x2029, 0x0001, 0x2c20, 0x2019,
-	0x0002, 0x6210, 0x2258, 0x0096, 0x904e, 0x080c, 0xa28c, 0x009e,
-	0x008e, 0x903e, 0x080c, 0xa337, 0x080c, 0xe2de, 0x005e, 0x007e,
-	0x00be, 0x080c, 0xa93a, 0x0005, 0x080c, 0xa91e, 0x00b6, 0x0046,
-	0x0056, 0x0076, 0x00c6, 0x0156, 0x2c20, 0x2128, 0x20a9, 0x007f,
-	0x900e, 0x0016, 0x0036, 0x080c, 0x6693, 0x1190, 0x0056, 0x0086,
-	0x9046, 0x2508, 0x2029, 0x0001, 0x0096, 0x904e, 0x080c, 0xa28c,
-	0x009e, 0x008e, 0x903e, 0x080c, 0xa337, 0x080c, 0xe2de, 0x005e,
-	0x003e, 0x001e, 0x8108, 0x1f04, 0xe371, 0x015e, 0x00ce, 0x007e,
-	0x005e, 0x004e, 0x00be, 0x080c, 0xa93a, 0x0005, 0x080c, 0xa91e,
-	0x00b6, 0x0076, 0x0056, 0x6210, 0x2258, 0x0086, 0x9046, 0x2029,
-	0x0001, 0x2019, 0x0048, 0x0096, 0x904e, 0x080c, 0xa28c, 0x009e,
-	0x008e, 0x903e, 0x080c, 0xa337, 0x2c20, 0x080c, 0xe2de, 0x005e,
-	0x007e, 0x00be, 0x080c, 0xa93a, 0x0005, 0x080c, 0xa91e, 0x00b6,
-	0x0046, 0x0056, 0x0076, 0x00c6, 0x0156, 0x2c20, 0x20a9, 0x0800,
-	0x900e, 0x0016, 0x0036, 0x080c, 0x6693, 0x11a0, 0x0086, 0x9046,
-	0x2828, 0x0046, 0x2021, 0x0001, 0x080c, 0xe684, 0x004e, 0x0096,
-	0x904e, 0x080c, 0xa28c, 0x009e, 0x008e, 0x903e, 0x080c, 0xa337,
-	0x080c, 0xe2de, 0x003e, 0x001e, 0x8108, 0x1f04, 0xe3c1, 0x015e,
-	0x00ce, 0x007e, 0x005e, 0x004e, 0x00be, 0x080c, 0xa93a, 0x0005,
-	0x0016, 0x00f6, 0x080c, 0xc978, 0x0198, 0xa864, 0x9084, 0x00ff,
-	0x9086, 0x0046, 0x0180, 0xa800, 0x907d, 0x0138, 0xa803, 0x0000,
-	0xab82, 0x080c, 0x6dee, 0x2f48, 0x0cb0, 0xab82, 0x080c, 0x6dee,
-	0x00fe, 0x001e, 0x0005, 0xa800, 0x907d, 0x0130, 0xa803, 0x0000,
-	0x080c, 0x6dee, 0x2f48, 0x0cb8, 0x080c, 0x6dee, 0x0c88, 0x00e6,
-	0x0046, 0x0036, 0x2061, 0x1ddc, 0x9005, 0x1138, 0x2071, 0x1800,
-	0x7454, 0x7074, 0x8001, 0x9402, 0x12f8, 0x2100, 0x9c06, 0x0188,
-	0x6000, 0x9086, 0x0000, 0x0168, 0x6008, 0x9206, 0x1150, 0x6320,
-	0x9386, 0x0009, 0x01b0, 0x6010, 0x91a0, 0x0004, 0x2424, 0x9406,
-	0x0140, 0x9ce0, 0x001c, 0x2001, 0x181a, 0x2004, 0x9c02, 0x1220,
-	0x0c20, 0x9085, 0x0001, 0x0008, 0x9006, 0x003e, 0x004e, 0x00ee,
-	0x0005, 0x631c, 0xd3c4, 0x1d68, 0x0c30, 0x0096, 0x0006, 0x080c,
-	0x1047, 0x000e, 0x090c, 0x0d7d, 0xaae2, 0xa867, 0x010d, 0xa88e,
-	0x0026, 0x2010, 0x080c, 0xc968, 0x2001, 0x0000, 0x0120, 0x2200,
-	0x9080, 0x0017, 0x2004, 0x002e, 0xa87a, 0x9186, 0x0020, 0x0110,
-	0xa8e3, 0xffff, 0xa986, 0xac76, 0xa87f, 0x0000, 0x2001, 0x198d,
-	0x2004, 0xa882, 0x9006, 0xa802, 0xa86a, 0xa88a, 0x0126, 0x2091,
-	0x8000, 0x080c, 0x6dee, 0x012e, 0x009e, 0x0005, 0x6700, 0x9786,
-	0x0000, 0x0158, 0x9786, 0x0001, 0x0140, 0x9786, 0x000a, 0x0128,
-	0x9786, 0x0009, 0x0110, 0x9085, 0x0001, 0x0005, 0x00e6, 0x6010,
-	0x9075, 0x0138, 0x00b6, 0x2058, 0xb8a0, 0x00be, 0x9206, 0x00ee,
-	0x0005, 0x9085, 0x0001, 0x0cd8, 0x0016, 0x6004, 0x908e, 0x001e,
-	0x11a0, 0x8007, 0x6134, 0x918c, 0x00ff, 0x9105, 0x6036, 0x6007,
-	0x0085, 0x6003, 0x000b, 0x6023, 0x0005, 0x2001, 0x1986, 0x2004,
-	0x601a, 0x2009, 0x8020, 0x080c, 0x92b0, 0x001e, 0x0005, 0xa001,
-	0xa001, 0x0005, 0x6024, 0xd0e4, 0x0158, 0xd0cc, 0x0118, 0x080c,
-	0xccc6, 0x0030, 0x080c, 0xe6a0, 0x080c, 0x894e, 0x080c, 0xacb0,
-	0x0005, 0x9280, 0x0008, 0x2004, 0x9084, 0x000f, 0x0002, 0xe4d5,
-	0xe4d5, 0xe4d5, 0xe4d7, 0xe4d5, 0xe4d7, 0xe4d7, 0xe4d5, 0xe4d7,
-	0xe4d5, 0xe4d5, 0xe4d5, 0xe4d5, 0xe4d5, 0x9006, 0x0005, 0x9085,
-	0x0001, 0x0005, 0x9280, 0x0008, 0x2004, 0x9084, 0x000f, 0x0002,
-	0xe4ee, 0xe4ee, 0xe4ee, 0xe4ee, 0xe4ee, 0xe4ee, 0xe4fb, 0xe4ee,
-	0xe4ee, 0xe4ee, 0xe4ee, 0xe4ee, 0xe4ee, 0xe4ee, 0x6007, 0x003b,
-	0x602f, 0x0009, 0x6017, 0x2a00, 0x6003, 0x0001, 0x2009, 0x8020,
-	0x080c, 0x92b0, 0x0005, 0x0096, 0x00c6, 0x2260, 0x080c, 0xe6a0,
-	0x604b, 0x0000, 0x6024, 0xc0f4, 0xc0e4, 0x6026, 0x603b, 0x0000,
-	0x00ce, 0x00d6, 0x2268, 0x9186, 0x0007, 0x1904, 0xe554, 0x6814,
-	0x9005, 0x0138, 0x2048, 0xa87c, 0xd0fc, 0x1118, 0x00de, 0x009e,
-	0x08a8, 0x6007, 0x003a, 0x6003, 0x0001, 0x2009, 0x8020, 0x080c,
-	0x92b0, 0x00c6, 0x2d60, 0x6100, 0x9186, 0x0002, 0x1904, 0xe5cb,
-	0x6014, 0x9005, 0x1138, 0x6000, 0x9086, 0x0007, 0x190c, 0x0d7d,
-	0x0804, 0xe5cb, 0x2048, 0x080c, 0xc97a, 0x1130, 0x0028, 0x2048,
-	0xa800, 0x9005, 0x1de0, 0x2900, 0x2048, 0xa87c, 0x9084, 0x0003,
-	0x9086, 0x0002, 0x1168, 0xa87c, 0xc0dc, 0xc0f4, 0xa87e, 0xa880,
-	0xc0fc, 0xa882, 0x2009, 0x0043, 0x080c, 0xddde, 0x0804, 0xe5cb,
-	0x2009, 0x0041, 0x0804, 0xe5c5, 0x9186, 0x0005, 0x15a0, 0x6814,
-	0x2048, 0xa87c, 0xd0bc, 0x1120, 0x00de, 0x009e, 0x0804, 0xe4ee,
-	0xd0b4, 0x0128, 0xd0fc, 0x090c, 0x0d7d, 0x0804, 0xe50f, 0x6007,
-	0x003a, 0x6003, 0x0001, 0x2009, 0x8020, 0x080c, 0x92b0, 0x00c6,
-	0x2d60, 0x6100, 0x9186, 0x0002, 0x0120, 0x9186, 0x0004, 0x1904,
-	0xe5cb, 0x6814, 0x2048, 0xa97c, 0xc1f4, 0xc1dc, 0xa97e, 0xa980,
-	0xc1fc, 0xc1bc, 0xa982, 0x00f6, 0x2c78, 0x080c, 0x1778, 0x00fe,
-	0x2009, 0x0042, 0x04d0, 0x0036, 0x080c, 0x1047, 0x090c, 0x0d7d,
-	0xa867, 0x010d, 0x9006, 0xa802, 0xa86a, 0xa88a, 0x2d18, 0xab8e,
-	0xa887, 0x0045, 0x2c00, 0xa892, 0x6038, 0xa8a2, 0x2360, 0x6024,
-	0xc0dd, 0x6026, 0x6010, 0x00b6, 0x2058, 0xb8a0, 0x00be, 0x2004,
-	0x635c, 0xab7a, 0xa876, 0x9006, 0xa87e, 0xa882, 0xad9a, 0xae96,
-	0xa89f, 0x0001, 0x080c, 0x6dee, 0x2019, 0x0045, 0x6008, 0x2068,
-	0x080c, 0xdfa1, 0x2d00, 0x600a, 0x6023, 0x0006, 0x6003, 0x0007,
-	0x901e, 0x631a, 0x634a, 0x003e, 0x0038, 0x604b, 0x0000, 0x6003,
-	0x0007, 0x080c, 0xddde, 0x00ce, 0x00de, 0x009e, 0x0005, 0x9186,
-	0x0013, 0x1128, 0x6004, 0x9082, 0x0085, 0x2008, 0x00c2, 0x9186,
-	0x0027, 0x1178, 0x080c, 0x967a, 0x0036, 0x0096, 0x6014, 0x2048,
-	0x2019, 0x0004, 0x080c, 0xe3e8, 0x009e, 0x003e, 0x080c, 0x9738,
-	0x0005, 0x9186, 0x0014, 0x0d70, 0x080c, 0xad6a, 0x0005, 0xe5fe,
-	0xe5fc, 0xe5fc, 0xe5fc, 0xe5fc, 0xe5fc, 0xe5fe, 0xe5fc, 0xe5fc,
-	0xe5fc, 0xe5fc, 0xe5fc, 0xe5fc, 0x080c, 0x0d7d, 0x6003, 0x000c,
-	0x080c, 0x9738, 0x0005, 0x9182, 0x0092, 0x1220, 0x9182, 0x0085,
-	0x0208, 0x001a, 0x080c, 0xad6a, 0x0005, 0xe61a, 0xe61a, 0xe61a,
-	0xe61a, 0xe61c, 0xe63c, 0xe61a, 0xe61a, 0xe61a, 0xe61a, 0xe61a,
-	0xe61a, 0xe61a, 0x080c, 0x0d7d, 0x00d6, 0x2c68, 0x080c, 0xac5a,
-	0x01b0, 0x6003, 0x0001, 0x6007, 0x001e, 0x2009, 0x026e, 0x210c,
-	0x613a, 0x2009, 0x026f, 0x210c, 0x613e, 0x600b, 0xffff, 0x6910,
-	0x6112, 0x6023, 0x0004, 0x2009, 0x8020, 0x080c, 0x92b0, 0x2d60,
-	0x080c, 0xacb0, 0x00de, 0x0005, 0x080c, 0xacb0, 0x0005, 0x00e6,
-	0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0ec, 0x00ee, 0x0005,
-	0x2009, 0x1867, 0x210c, 0xd1ec, 0x05b0, 0x6003, 0x0002, 0x6024,
-	0xc0e5, 0x6026, 0xd0cc, 0x0150, 0x2001, 0x1987, 0x2004, 0x604a,
-	0x2009, 0x1867, 0x210c, 0xd1f4, 0x1520, 0x00a0, 0x2009, 0x1867,
-	0x210c, 0xd1f4, 0x0128, 0x6024, 0xc0e4, 0x6026, 0x9006, 0x00d8,
-	0x2001, 0x1987, 0x200c, 0x2001, 0x1985, 0x2004, 0x9100, 0x9080,
-	0x000a, 0x604a, 0x6010, 0x00b6, 0x2058, 0xb8bc, 0x00be, 0x0008,
-	0x2104, 0x9005, 0x0118, 0x9088, 0x0003, 0x0cd0, 0x2c0a, 0x600f,
-	0x0000, 0x9085, 0x0001, 0x0005, 0x0016, 0x00c6, 0x00e6, 0x615c,
-	0xb8bc, 0x2060, 0x8cff, 0x0180, 0x84ff, 0x1118, 0x605c, 0x9106,
-	0x1138, 0x600c, 0x2072, 0x080c, 0x894e, 0x080c, 0xacb0, 0x0010,
-	0x9cf0, 0x0003, 0x2e64, 0x0c70, 0x00ee, 0x00ce, 0x001e, 0x0005,
-	0x00d6, 0x00b6, 0x6010, 0x2058, 0xb8bc, 0x2068, 0x9005, 0x0130,
-	0x9c06, 0x0110, 0x680c, 0x0cd0, 0x600c, 0x680e, 0x00be, 0x00de,
-	0x0005, 0x0026, 0x0036, 0x0156, 0x2011, 0x182c, 0x2204, 0x9084,
-	0x00ff, 0x2019, 0x026e, 0x2334, 0x9636, 0x1508, 0x8318, 0x2334,
-	0x2204, 0x9084, 0xff00, 0x9636, 0x11d0, 0x2011, 0x0270, 0x20a9,
-	0x0004, 0x6010, 0x0096, 0x2048, 0x2019, 0x000a, 0x080c, 0xbca2,
-	0x009e, 0x1168, 0x2011, 0x0274, 0x20a9, 0x0004, 0x6010, 0x0096,
-	0x2048, 0x2019, 0x0006, 0x080c, 0xbca2, 0x009e, 0x1100, 0x015e,
-	0x003e, 0x002e, 0x0005, 0x00e6, 0x2071, 0x1800, 0x080c, 0x6025,
-	0x080c, 0x3011, 0x00ee, 0x0005, 0x0096, 0x0026, 0x080c, 0x1047,
-	0x090c, 0x0d7d, 0xa85c, 0x9080, 0x001a, 0x20a0, 0x20a9, 0x000c,
-	0xa860, 0x20e8, 0x9006, 0x4004, 0x9186, 0x0046, 0x1118, 0xa867,
-	0x0136, 0x0038, 0xa867, 0x0138, 0x9186, 0x0041, 0x0110, 0xa87b,
-	0x0001, 0x7038, 0x9084, 0xff00, 0x7240, 0x9294, 0xff00, 0x8007,
-	0x9215, 0xaa9a, 0x9186, 0x0046, 0x1168, 0x7038, 0x9084, 0x00ff,
-	0x723c, 0x9294, 0xff00, 0x9215, 0xaa9e, 0x723c, 0x9294, 0x00ff,
-	0xaaa2, 0x0060, 0x7040, 0x9084, 0x00ff, 0x7244, 0x9294, 0xff00,
-	0x9215, 0xaa9e, 0x7244, 0x9294, 0x00ff, 0xaaa2, 0x9186, 0x0046,
-	0x1118, 0x9e90, 0x0012, 0x0010, 0x9e90, 0x001a, 0x2204, 0x8007,
-	0xa8a6, 0x8210, 0x2204, 0x8007, 0xa8aa, 0x8210, 0x2204, 0x8007,
-	0xa8ae, 0x8210, 0x2204, 0x8007, 0xa8b2, 0x8210, 0x9186, 0x0046,
-	0x11b8, 0x9e90, 0x0016, 0x2204, 0x8007, 0xa8b6, 0x8210, 0x2204,
-	0x8007, 0xa8ba, 0x8210, 0x2204, 0x8007, 0xa8be, 0x8210, 0x2204,
-	0x8007, 0xa8c2, 0x8210, 0x2011, 0x0205, 0x2013, 0x0001, 0x00b0,
-	0x9e90, 0x001e, 0x2204, 0x8007, 0xa8b6, 0x8210, 0x2204, 0x8007,
-	0xa8ba, 0x2011, 0x0205, 0x2013, 0x0001, 0x2011, 0x0260, 0x2204,
-	0x8007, 0xa8be, 0x8210, 0x2204, 0x8007, 0xa8c2, 0x9186, 0x0046,
-	0x1118, 0x2011, 0x0262, 0x0010, 0x2011, 0x026a, 0x0146, 0x01d6,
-	0x0036, 0x20a9, 0x0001, 0x2019, 0x0008, 0xa860, 0x20e8, 0xa85c,
-	0x9080, 0x0031, 0x20a0, 0x2204, 0x8007, 0x4004, 0x8210, 0x8319,
-	0x1dd0, 0x003e, 0x01ce, 0x013e, 0x2011, 0x0205, 0x2013, 0x0000,
-	0x002e, 0x080c, 0x6dee, 0x009e, 0x0005, 0x00e6, 0x6010, 0x00b6,
-	0x2058, 0xb800, 0x00be, 0xd0fc, 0x0108, 0x0011, 0x00ee, 0x0005,
-	0xa880, 0xc0e5, 0xa882, 0x0005, 0x00e6, 0x00d6, 0x00c6, 0x0076,
-	0x0066, 0x0056, 0x0046, 0x0026, 0x0016, 0x0126, 0x2091, 0x8000,
-	0x2029, 0x19f2, 0x252c, 0x2021, 0x19f9, 0x2424, 0x2061, 0x1ddc,
-	0x2071, 0x1800, 0x7654, 0x7074, 0x9606, 0x0578, 0x6720, 0x9786,
-	0x0001, 0x0118, 0x9786, 0x0008, 0x1500, 0x2500, 0x9c06, 0x01e8,
-	0x2400, 0x9c06, 0x01d0, 0x080c, 0xe476, 0x01b8, 0x080c, 0xe486,
-	0x11a0, 0x6000, 0x9086, 0x0004, 0x1120, 0x0016, 0x080c, 0x1ac5,
-	0x001e, 0x080c, 0xcb80, 0x1110, 0x080c, 0x326f, 0x080c, 0xcb91,
-	0x1110, 0x080c, 0xb693, 0x080c, 0xaceb, 0x9ce0, 0x001c, 0x2001,
-	0x181a, 0x2004, 0x9c02, 0x1208, 0x0858, 0x012e, 0x001e, 0x002e,
-	0x004e, 0x005e, 0x006e, 0x007e, 0x00ce, 0x00de, 0x00ee, 0x0005,
-	0x2001, 0x1810, 0x2004, 0xd0dc, 0x0005, 0x0006, 0x2001, 0x1837,
-	0x2004, 0xd09c, 0x000e, 0x0005, 0x0006, 0x0036, 0x0046, 0x080c,
-	0xd09b, 0x0168, 0x2019, 0xffff, 0x9005, 0x0128, 0x6010, 0x00b6,
-	0x2058, 0xbba0, 0x00be, 0x2021, 0x0004, 0x080c, 0x4d09, 0x004e,
-	0x003e, 0x000e, 0x6004, 0x9086, 0x0001, 0x1128, 0x080c, 0xa404,
-	0x080c, 0xaceb, 0x9006, 0x0005, 0x00e6, 0x00c6, 0x00b6, 0x0046,
-	0x2061, 0x1ddc, 0x2071, 0x1800, 0x7454, 0x7074, 0x8001, 0x9402,
-	0x12d8, 0x2100, 0x9c06, 0x0168, 0x6000, 0x9086, 0x0000, 0x0148,
-	0x6010, 0x2058, 0xb8a0, 0x9206, 0x1120, 0x6004, 0x9086, 0x0002,
-	0x0140, 0x9ce0, 0x001c, 0x2001, 0x181a, 0x2004, 0x9c02, 0x1220,
-	0x0c40, 0x9085, 0x0001, 0x0008, 0x9006, 0x004e, 0x00be, 0x00ce,
-	0x00ee, 0x0005, 0x0126, 0x0006, 0x00e6, 0x0016, 0x2091, 0x8000,
-	0x2071, 0x1840, 0xd5a4, 0x0118, 0x7004, 0x8000, 0x7006, 0xd5b4,
-	0x0118, 0x7000, 0x8000, 0x7002, 0xd5ac, 0x0178, 0x2500, 0x9084,
-	0x0007, 0x908e, 0x0003, 0x0148, 0x908e, 0x0004, 0x0130, 0x908e,
-	0x0005, 0x0118, 0x2071, 0xfff6, 0x0089, 0x001e, 0x00ee, 0x000e,
-	0x012e, 0x0005, 0x0126, 0x0006, 0x00e6, 0x2091, 0x8000, 0x2071,
-	0xffee, 0x0021, 0x00ee, 0x000e, 0x012e, 0x0005, 0x2e05, 0x8000,
-	0x2077, 0x1220, 0x8e70, 0x2e05, 0x8000, 0x2077, 0x0005, 0x00e6,
-	0x2071, 0xffec, 0x0c99, 0x00ee, 0x0005, 0x00e6, 0x2071, 0xfff0,
-	0x0c69, 0x00ee, 0x0005, 0x0126, 0x0006, 0x00e6, 0x2091, 0x8000,
-	0x2071, 0x1840, 0x7014, 0x8000, 0x7016, 0x00ee, 0x000e, 0x012e,
-	0x0005, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040,
-	0x0080, 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000,
-	0x8000, 0x3f07
+	0x9084, 0x00ff, 0xa89e, 0xa868, 0xc0f4, 0xa86a, 0x080c, 0x6f0d,
+	0x6017, 0x0000, 0x009e, 0x003e, 0x00de, 0x00be, 0x0005, 0x0026,
+	0x0036, 0x0046, 0x00b6, 0x0096, 0x00f6, 0x6214, 0x2248, 0x6210,
+	0x2258, 0x2079, 0x0260, 0x9096, 0x0000, 0x11a0, 0xb814, 0x9084,
+	0x00ff, 0x900e, 0x080c, 0x26a2, 0x2118, 0x831f, 0x939c, 0xff00,
+	0x7838, 0x9084, 0x00ff, 0x931d, 0x7c3c, 0x2011, 0x8018, 0x080c,
+	0x4c2e, 0x00a8, 0x9096, 0x0001, 0x1148, 0x89ff, 0x0180, 0xa89b,
+	0x000d, 0x7838, 0xa8a6, 0x783c, 0xa8aa, 0x0048, 0x9096, 0x0002,
+	0x1130, 0xa89b, 0x000d, 0x7838, 0xa8a6, 0x783c, 0xa8aa, 0x00fe,
+	0x009e, 0x00be, 0x004e, 0x003e, 0x002e, 0x0005, 0x00c6, 0x0026,
+	0x0016, 0x9186, 0x0035, 0x0110, 0x6a38, 0x0008, 0x6a2c, 0x080c,
+	0xcc04, 0x01f0, 0x2260, 0x6120, 0x9186, 0x0003, 0x0118, 0x9186,
+	0x0006, 0x1190, 0x6838, 0x9206, 0x0140, 0x683c, 0x9206, 0x1160,
+	0x6108, 0x6838, 0x9106, 0x1140, 0x0020, 0x6008, 0x693c, 0x9106,
+	0x1118, 0x6010, 0x6910, 0x9106, 0x001e, 0x002e, 0x00ce, 0x0005,
+	0x9085, 0x0001, 0x0cc8, 0xa974, 0xd1cc, 0x0188, 0x918c, 0x00ff,
+	0x918e, 0x0002, 0x1160, 0xa9a8, 0x918c, 0x0f00, 0x810f, 0x918e,
+	0x0001, 0x1128, 0xa834, 0xa938, 0x9115, 0x190c, 0xc232, 0x0005,
+	0x0036, 0x2019, 0x0001, 0x0010, 0x0036, 0x901e, 0x0499, 0x01e0,
+	0x080c, 0xcc16, 0x01c8, 0x080c, 0xce07, 0x6037, 0x4000, 0x6014,
+	0x6017, 0x0000, 0x0096, 0x2048, 0xa87c, 0x080c, 0xce2d, 0x1118,
+	0x080c, 0xb91f, 0x0040, 0xa867, 0x0103, 0xa877, 0x0000, 0x83ff,
+	0x1129, 0x080c, 0x6f19, 0x009e, 0x003e, 0x0005, 0xa880, 0xd0b4,
+	0x0128, 0xa87b, 0x0006, 0xc0ec, 0xa882, 0x0048, 0xd0bc, 0x0118,
+	0xa87b, 0x0002, 0x0020, 0xa87b, 0x0005, 0x080c, 0xcf21, 0xa877,
+	0x0000, 0x0005, 0x2001, 0x1810, 0x2004, 0xd0ec, 0x0005, 0x0006,
+	0x2001, 0x1810, 0x2004, 0xd0f4, 0x000e, 0x0005, 0x0006, 0x2001,
+	0x1810, 0x2004, 0xd0e4, 0x000e, 0x0005, 0x0036, 0x0046, 0x6010,
+	0x00b6, 0x2058, 0xbba0, 0x00be, 0x2021, 0x0007, 0x080c, 0x4de5,
+	0x004e, 0x003e, 0x0005, 0x0c51, 0x1d81, 0x0005, 0x2001, 0x1987,
+	0x2004, 0x601a, 0x0005, 0x2001, 0x1989, 0x2004, 0x604a, 0x0005,
+	0x080c, 0xaf2e, 0x0804, 0x98bf, 0x611c, 0xd1fc, 0xa97c, 0x1108,
+	0xd1e4, 0x0005, 0x601c, 0xd0fc, 0xa87c, 0x1108, 0xd0e4, 0x0005,
+	0x601c, 0xd0fc, 0xc0fc, 0x601e, 0xa87c, 0x1108, 0xd0e4, 0x0005,
+	0x6044, 0xd0fc, 0x1138, 0xd0bc, 0x0198, 0xc0bc, 0x6046, 0x6003,
+	0x0002, 0x0070, 0xd0ac, 0x1160, 0xd0dc, 0x1128, 0x908c, 0x000f,
+	0x9186, 0x0005, 0x1118, 0x6003, 0x0003, 0x0010, 0x6003, 0x0001,
+	0x0005, 0x00b6, 0x0066, 0x6000, 0x90b2, 0x0016, 0x1a0c, 0x0d85,
+	0x001b, 0x006e, 0x00be, 0x0005, 0xd3ac, 0xdaf5, 0xdc64, 0xd3ac,
+	0xd3ac, 0xd3ac, 0xd3ac, 0xd3ac, 0xd3e3, 0xdce8, 0xd3ac, 0xd3ac,
+	0xd3ac, 0xd3ac, 0xd3ac, 0xd3ac, 0x080c, 0x0d85, 0x0066, 0x6000,
+	0x90b2, 0x0016, 0x1a0c, 0x0d85, 0x0013, 0x006e, 0x0005, 0xd3c7,
+	0xe209, 0xd3c7, 0xd3c7, 0xd3c7, 0xd3c7, 0xd3c7, 0xd3c7, 0xe1b8,
+	0xe25b, 0xd3c7, 0xe8b4, 0xe8e8, 0xe8b4, 0xe8e8, 0xd3c7, 0x080c,
+	0x0d85, 0x6000, 0x9082, 0x0016, 0x1a0c, 0x0d85, 0x6000, 0x000a,
+	0x0005, 0xd3e1, 0xdec5, 0xdf90, 0xdfb3, 0xe02f, 0xd3e1, 0xe12a,
+	0xe0b7, 0xdcf2, 0xe190, 0xe1a5, 0xd3e1, 0xd3e1, 0xd3e1, 0xd3e1,
+	0xd3e1, 0x080c, 0x0d85, 0x91b2, 0x0053, 0x1a0c, 0x0d85, 0x2100,
+	0x91b2, 0x0040, 0x1a04, 0xd867, 0x0002, 0xd42d, 0xd635, 0xd42d,
+	0xd42d, 0xd42d, 0xd63e, 0xd42d, 0xd42d, 0xd42d, 0xd42d, 0xd42d,
+	0xd42d, 0xd42d, 0xd42d, 0xd42d, 0xd42d, 0xd42d, 0xd42d, 0xd42d,
+	0xd42d, 0xd42d, 0xd42d, 0xd42d, 0xd42f, 0xd496, 0xd4a5, 0xd509,
+	0xd534, 0xd5ad, 0xd620, 0xd42d, 0xd42d, 0xd641, 0xd42d, 0xd42d,
+	0xd656, 0xd663, 0xd42d, 0xd42d, 0xd42d, 0xd42d, 0xd42d, 0xd709,
+	0xd42d, 0xd42d, 0xd71d, 0xd42d, 0xd42d, 0xd6d8, 0xd42d, 0xd42d,
+	0xd42d, 0xd735, 0xd42d, 0xd42d, 0xd42d, 0xd7b2, 0xd42d, 0xd42d,
+	0xd42d, 0xd42d, 0xd42d, 0xd42d, 0xd82f, 0x080c, 0x0d85, 0x080c,
+	0x6b93, 0x1150, 0x2001, 0x1837, 0x2004, 0xd0cc, 0x1128, 0x9084,
+	0x0009, 0x9086, 0x0008, 0x1140, 0x6007, 0x0009, 0x602f, 0x0009,
+	0x6017, 0x0000, 0x0804, 0xd62e, 0x080c, 0x6b2f, 0x00e6, 0x00c6,
+	0x0036, 0x0026, 0x0016, 0x6210, 0x2258, 0xbaa0, 0x0026, 0x2019,
+	0x0029, 0x080c, 0xaae0, 0x080c, 0x95c1, 0x0076, 0x903e, 0x080c,
+	0x947e, 0x2c08, 0x080c, 0xe440, 0x007e, 0x001e, 0x080c, 0xaafc,
+	0x001e, 0x002e, 0x003e, 0x00ce, 0x00ee, 0x6610, 0x2658, 0x080c,
+	0x6798, 0xbe04, 0x9684, 0x00ff, 0x9082, 0x0006, 0x1268, 0x0016,
+	0x0026, 0x6210, 0x00b6, 0x2258, 0xbaa0, 0x00be, 0x2c08, 0x080c,
+	0xeb13, 0x002e, 0x001e, 0x1178, 0x080c, 0xe36e, 0x1904, 0xd501,
+	0x080c, 0xe30a, 0x1120, 0x6007, 0x0008, 0x0804, 0xd62e, 0x6007,
+	0x0009, 0x0804, 0xd62e, 0x080c, 0xe5a2, 0x0128, 0x080c, 0xe36e,
+	0x0d78, 0x0804, 0xd501, 0x6017, 0x1900, 0x0c88, 0x080c, 0x3447,
+	0x1904, 0xd864, 0x6106, 0x080c, 0xe2bb, 0x6007, 0x0006, 0x0804,
+	0xd62e, 0x6007, 0x0007, 0x0804, 0xd62e, 0x080c, 0xe924, 0x1904,
+	0xd864, 0x080c, 0x3447, 0x1904, 0xd864, 0x00d6, 0x6610, 0x2658,
+	0xbe04, 0x9684, 0x00ff, 0x9082, 0x0006, 0x1220, 0x2001, 0x0001,
+	0x080c, 0x66bb, 0x96b4, 0xff00, 0x8637, 0x9686, 0x0006, 0x0188,
+	0x9686, 0x0004, 0x0170, 0xbe04, 0x96b4, 0x00ff, 0x9686, 0x0006,
+	0x0140, 0x9686, 0x0004, 0x0128, 0x9686, 0x0005, 0x0110, 0x00de,
+	0x0480, 0x00e6, 0x2071, 0x0260, 0x7034, 0x9084, 0x0003, 0x1140,
+	0x7034, 0x9082, 0x0014, 0x0220, 0x7030, 0x9084, 0x0003, 0x0130,
+	0x00ee, 0x6017, 0x0000, 0x602f, 0x0007, 0x00b0, 0x00ee, 0x080c,
+	0xe3d6, 0x1190, 0x9686, 0x0006, 0x1140, 0x0026, 0x6210, 0x2258,
+	0xbaa0, 0x900e, 0x080c, 0x335f, 0x002e, 0x080c, 0x6824, 0x6007,
+	0x000a, 0x00de, 0x0804, 0xd62e, 0x6007, 0x000b, 0x00de, 0x0804,
+	0xd62e, 0x080c, 0x3310, 0x080c, 0xd353, 0x6007, 0x0001, 0x0804,
+	0xd62e, 0x080c, 0xe924, 0x1904, 0xd864, 0x080c, 0x3447, 0x1904,
+	0xd864, 0x2071, 0x0260, 0x7034, 0x90b4, 0x0003, 0x1948, 0x90b2,
+	0x0014, 0x0a30, 0x7030, 0x9084, 0x0003, 0x1910, 0x6610, 0x2658,
+	0xbe04, 0x9686, 0x0707, 0x09e8, 0x0026, 0x6210, 0x2258, 0xbaa0,
+	0x900e, 0x080c, 0x335f, 0x002e, 0x6007, 0x000c, 0x2001, 0x0001,
+	0x080c, 0xeaf2, 0x0804, 0xd62e, 0x080c, 0x6b93, 0x1140, 0x2001,
+	0x1837, 0x2004, 0x9084, 0x0009, 0x9086, 0x0008, 0x1110, 0x0804,
+	0xd43c, 0x080c, 0x6b2f, 0x6610, 0x2658, 0xbe04, 0x9684, 0x00ff,
+	0x9082, 0x0006, 0x06c8, 0x1138, 0x0026, 0x2001, 0x0006, 0x080c,
+	0x66fb, 0x002e, 0x0050, 0x96b4, 0xff00, 0x8637, 0x9686, 0x0004,
+	0x0120, 0x9686, 0x0006, 0x1904, 0xd501, 0x080c, 0xe3e3, 0x1120,
+	0x6007, 0x000e, 0x0804, 0xd62e, 0x0046, 0x6410, 0x2458, 0xbca0,
+	0x0046, 0x080c, 0x3310, 0x080c, 0xd353, 0x004e, 0x0016, 0x9006,
+	0x2009, 0x1848, 0x210c, 0xd1a4, 0x0148, 0x2009, 0x0029, 0x080c,
+	0xe72a, 0x6010, 0x2058, 0xb800, 0xc0e5, 0xb802, 0x001e, 0x004e,
+	0x6007, 0x0001, 0x0804, 0xd62e, 0x2001, 0x0001, 0x080c, 0x66bb,
+	0x0156, 0x0016, 0x0026, 0x0036, 0x20a9, 0x0004, 0x2019, 0x1805,
+	0x2011, 0x0270, 0x080c, 0xbf2a, 0x003e, 0x002e, 0x001e, 0x015e,
+	0x9005, 0x0168, 0x96b4, 0xff00, 0x8637, 0x9682, 0x0004, 0x0a04,
+	0xd501, 0x9682, 0x0007, 0x0a04, 0xd55d, 0x0804, 0xd501, 0x6017,
+	0x1900, 0x6007, 0x0009, 0x0804, 0xd62e, 0x080c, 0x6b93, 0x1140,
+	0x2001, 0x1837, 0x2004, 0x9084, 0x0009, 0x9086, 0x0008, 0x1110,
+	0x0804, 0xd43c, 0x080c, 0x6b2f, 0x6610, 0x2658, 0xbe04, 0x9684,
+	0x00ff, 0x0006, 0x0016, 0x908e, 0x0001, 0x0118, 0x908e, 0x0000,
+	0x1118, 0x001e, 0x000e, 0x0080, 0x001e, 0x000e, 0x9082, 0x0006,
+	0x06a0, 0x0150, 0x96b4, 0xff00, 0x8637, 0x9686, 0x0004, 0x0120,
+	0x9686, 0x0006, 0x1904, 0xd501, 0x080c, 0xe411, 0x1138, 0x080c,
+	0xe30a, 0x1120, 0x6007, 0x0010, 0x0804, 0xd62e, 0x0046, 0x6410,
+	0x2458, 0xbca0, 0x0046, 0x080c, 0x3310, 0x080c, 0xd353, 0x004e,
+	0x0016, 0x9006, 0x2009, 0x1848, 0x210c, 0xd1a4, 0x0148, 0x2009,
+	0x0029, 0x080c, 0xe72a, 0x6010, 0x2058, 0xb800, 0xc0e5, 0xb802,
+	0x001e, 0x004e, 0x6007, 0x0001, 0x0448, 0x080c, 0xe5a2, 0x0198,
+	0x0016, 0x968c, 0x00ff, 0x9186, 0x0002, 0x0160, 0x9186, 0x0003,
+	0x0148, 0x001e, 0x96b4, 0xff00, 0x8637, 0x9686, 0x0006, 0x0920,
+	0x0804, 0xd501, 0x001e, 0x6017, 0x1900, 0x6007, 0x0009, 0x0070,
+	0x080c, 0x3447, 0x1904, 0xd864, 0x080c, 0xe924, 0x1904, 0xd864,
+	0x080c, 0xda35, 0x1904, 0xd501, 0x6007, 0x0012, 0x6003, 0x0001,
+	0x080c, 0x942f, 0x080c, 0x98bf, 0x0005, 0x6007, 0x0001, 0x6003,
+	0x0001, 0x080c, 0x942f, 0x080c, 0x98bf, 0x0cb0, 0x6007, 0x0005,
+	0x0c68, 0x080c, 0xe924, 0x1904, 0xd864, 0x080c, 0x3447, 0x1904,
+	0xd864, 0x080c, 0xda35, 0x1904, 0xd501, 0x6007, 0x0020, 0x6003,
+	0x0001, 0x080c, 0x942f, 0x080c, 0x98bf, 0x0005, 0x080c, 0x3447,
+	0x1904, 0xd864, 0x6007, 0x0023, 0x6003, 0x0001, 0x080c, 0x942f,
+	0x080c, 0x98bf, 0x0005, 0x080c, 0xe924, 0x1904, 0xd864, 0x080c,
+	0x3447, 0x1904, 0xd864, 0x080c, 0xda35, 0x1904, 0xd501, 0x0016,
+	0x0026, 0x00e6, 0x2071, 0x0260, 0x2c08, 0x2011, 0x1820, 0x2214,
+	0x703c, 0x9206, 0x11e0, 0x2011, 0x181f, 0x2214, 0x7038, 0x9084,
+	0x00ff, 0x9206, 0x11a0, 0x7240, 0x080c, 0xcc04, 0x0570, 0x2260,
+	0x6008, 0x9086, 0xffff, 0x0120, 0x7244, 0x6008, 0x9206, 0x1528,
+	0x6020, 0x9086, 0x0007, 0x1508, 0x080c, 0xaf2e, 0x04a0, 0x7244,
+	0x9286, 0xffff, 0x0180, 0x2c08, 0x080c, 0xcc04, 0x01b0, 0x2260,
+	0x7240, 0x6008, 0x9206, 0x1188, 0x6010, 0x9190, 0x0004, 0x2214,
+	0x9206, 0x01b8, 0x0050, 0x7240, 0x2c08, 0x9006, 0x080c, 0xe6f4,
+	0x1180, 0x7244, 0x9286, 0xffff, 0x01b0, 0x2160, 0x6007, 0x0026,
+	0x6017, 0x1700, 0x7214, 0x9296, 0xffff, 0x1180, 0x6007, 0x0025,
+	0x0068, 0x6020, 0x9086, 0x0007, 0x1d80, 0x6004, 0x9086, 0x0024,
+	0x1110, 0x080c, 0xaf2e, 0x2160, 0x6007, 0x0025, 0x6003, 0x0001,
+	0x080c, 0x942f, 0x080c, 0x98bf, 0x00ee, 0x002e, 0x001e, 0x0005,
+	0x2001, 0x0001, 0x080c, 0x66bb, 0x0156, 0x0016, 0x0026, 0x0036,
+	0x20a9, 0x0004, 0x2019, 0x1805, 0x2011, 0x0276, 0x080c, 0xbf2a,
+	0x003e, 0x002e, 0x001e, 0x015e, 0x0120, 0x6007, 0x0031, 0x0804,
+	0xd62e, 0x080c, 0xbb99, 0x080c, 0x76a5, 0x1190, 0x0006, 0x0026,
+	0x0036, 0x080c, 0x76bf, 0x1138, 0x080c, 0x79a7, 0x080c, 0x617e,
+	0x080c, 0x75d4, 0x0010, 0x080c, 0x7679, 0x003e, 0x002e, 0x000e,
+	0x0005, 0x080c, 0x3447, 0x1904, 0xd864, 0x080c, 0xda35, 0x1904,
+	0xd501, 0x6106, 0x080c, 0xda51, 0x1120, 0x6007, 0x002b, 0x0804,
+	0xd62e, 0x6007, 0x002c, 0x0804, 0xd62e, 0x080c, 0xe924, 0x1904,
+	0xd864, 0x080c, 0x3447, 0x1904, 0xd864, 0x080c, 0xda35, 0x1904,
+	0xd501, 0x6106, 0x080c, 0xda56, 0x1120, 0x6007, 0x002e, 0x0804,
+	0xd62e, 0x6007, 0x002f, 0x0804, 0xd62e, 0x080c, 0x3447, 0x1904,
+	0xd864, 0x00e6, 0x00d6, 0x00c6, 0x6010, 0x2058, 0xb904, 0x9184,
+	0x00ff, 0x9086, 0x0006, 0x0158, 0x9184, 0xff00, 0x8007, 0x9086,
+	0x0006, 0x0128, 0x00ce, 0x00de, 0x00ee, 0x0804, 0xd635, 0x080c,
+	0x582a, 0xd0e4, 0x0904, 0xd7af, 0x2071, 0x026c, 0x7010, 0x603a,
+	0x7014, 0x603e, 0x7108, 0x720c, 0x080c, 0x6bd1, 0x0140, 0x6010,
+	0x2058, 0xb810, 0x9106, 0x1118, 0xb814, 0x9206, 0x0510, 0x080c,
+	0x6bcd, 0x15b8, 0x2069, 0x1800, 0x6880, 0x9206, 0x1590, 0x687c,
+	0x9106, 0x1578, 0x7210, 0x080c, 0xcc04, 0x0590, 0x080c, 0xd922,
+	0x0578, 0x080c, 0xe7a6, 0x0560, 0x622e, 0x6007, 0x0036, 0x6003,
+	0x0001, 0x2009, 0x8020, 0x080c, 0x9428, 0x00ce, 0x00de, 0x00ee,
+	0x0005, 0x7214, 0x9286, 0xffff, 0x0150, 0x080c, 0xcc04, 0x01c0,
+	0x9280, 0x0002, 0x2004, 0x7110, 0x9106, 0x1190, 0x08e0, 0x7210,
+	0x2c08, 0x9085, 0x0001, 0x080c, 0xe6f4, 0x2c10, 0x2160, 0x0140,
+	0x0890, 0x6007, 0x0037, 0x602f, 0x0009, 0x6017, 0x1500, 0x08b8,
+	0x6007, 0x0037, 0x602f, 0x0003, 0x6017, 0x1700, 0x0880, 0x6007,
+	0x0012, 0x0868, 0x080c, 0x3447, 0x1904, 0xd864, 0x6010, 0x2058,
+	0xb804, 0x9084, 0xff00, 0x8007, 0x9086, 0x0006, 0x1904, 0xd635,
+	0x00e6, 0x00d6, 0x00c6, 0x080c, 0x582a, 0xd0e4, 0x0904, 0xd827,
+	0x2069, 0x1800, 0x2071, 0x026c, 0x7008, 0x603a, 0x720c, 0x623e,
+	0x9286, 0xffff, 0x1150, 0x7208, 0x00c6, 0x2c08, 0x9085, 0x0001,
+	0x080c, 0xe6f4, 0x2c10, 0x00ce, 0x05e8, 0x080c, 0xcc04, 0x05d0,
+	0x7108, 0x9280, 0x0002, 0x2004, 0x9106, 0x15a0, 0x00c6, 0x0026,
+	0x2260, 0x080c, 0xc7f5, 0x002e, 0x00ce, 0x7118, 0x918c, 0xff00,
+	0x810f, 0x9186, 0x0001, 0x0178, 0x9186, 0x0005, 0x0118, 0x9186,
+	0x0007, 0x1198, 0x9280, 0x0005, 0x2004, 0x9005, 0x0170, 0x080c,
+	0xd922, 0x0904, 0xd7a8, 0x0056, 0x7510, 0x7614, 0x080c, 0xe7bf,
+	0x005e, 0x00ce, 0x00de, 0x00ee, 0x0005, 0x6007, 0x003b, 0x602f,
+	0x0009, 0x6017, 0x2a00, 0x6003, 0x0001, 0x2009, 0x8020, 0x080c,
+	0x9428, 0x0c78, 0x6007, 0x003b, 0x602f, 0x0003, 0x6017, 0x0300,
+	0x6003, 0x0001, 0x2009, 0x8020, 0x080c, 0x9428, 0x0c10, 0x6007,
+	0x003b, 0x602f, 0x000b, 0x6017, 0x0000, 0x0804, 0xd77f, 0x00e6,
+	0x0026, 0x080c, 0x6b93, 0x0550, 0x080c, 0x6b2f, 0x080c, 0xe995,
+	0x1518, 0x2071, 0x1800, 0x70dc, 0x9085, 0x0003, 0x70de, 0x00f6,
+	0x2079, 0x0100, 0x72b0, 0x9284, 0x00ff, 0x707e, 0x78e6, 0x9284,
+	0xff00, 0x7280, 0x9205, 0x7082, 0x78ea, 0x00fe, 0x70e7, 0x0000,
+	0x080c, 0x6bd1, 0x0120, 0x2011, 0x1a0b, 0x2013, 0x07d0, 0xd0ac,
+	0x1128, 0x080c, 0x30e1, 0x0010, 0x080c, 0xe9c9, 0x002e, 0x00ee,
+	0x080c, 0xaf2e, 0x0804, 0xd634, 0x080c, 0xaf2e, 0x0005, 0x2600,
+	0x0002, 0xd87b, 0xd8a9, 0xd8ba, 0xd87b, 0xd87b, 0xd87d, 0xd8cb,
+	0xd87b, 0xd87b, 0xd87b, 0xd897, 0xd87b, 0xd87b, 0xd87b, 0xd8d6,
+	0xd8ec, 0xd91d, 0xd87b, 0x080c, 0x0d85, 0x080c, 0xe924, 0x1d20,
+	0x080c, 0x3447, 0x1d08, 0x7038, 0x6016, 0x6007, 0x0045, 0x6003,
+	0x0001, 0x080c, 0x942f, 0x0005, 0x080c, 0x3310, 0x080c, 0xd353,
+	0x6007, 0x0001, 0x6003, 0x0001, 0x080c, 0x942f, 0x0005, 0x080c,
+	0xe924, 0x1950, 0x080c, 0x3447, 0x1938, 0x080c, 0xda35, 0x1d60,
+	0x703c, 0x6016, 0x6007, 0x004a, 0x6003, 0x0001, 0x080c, 0x942f,
+	0x0005, 0x080c, 0x3447, 0x1904, 0xd864, 0x2009, 0x0041, 0x080c,
+	0xe9d2, 0x6007, 0x0047, 0x6003, 0x0001, 0x080c, 0x942f, 0x080c,
+	0x98bf, 0x0005, 0x080c, 0x3447, 0x1904, 0xd864, 0x2009, 0x0042,
+	0x080c, 0xe9d2, 0x6007, 0x0047, 0x6003, 0x0001, 0x080c, 0x942f,
+	0x080c, 0x98bf, 0x0005, 0x080c, 0x3447, 0x1904, 0xd864, 0x2009,
+	0x0046, 0x080c, 0xe9d2, 0x080c, 0xaf2e, 0x0005, 0x2001, 0x1824,
+	0x2004, 0x9082, 0x00e1, 0x1268, 0x080c, 0xd93f, 0x0904, 0xd864,
+	0x6007, 0x004e, 0x6003, 0x0001, 0x080c, 0x942f, 0x080c, 0x98bf,
+	0x0005, 0x6007, 0x0012, 0x0cb0, 0x6007, 0x004f, 0x6017, 0x0000,
+	0x7134, 0x918c, 0x00ff, 0x81ff, 0x0508, 0x9186, 0x0001, 0x1160,
+	0x7140, 0x2001, 0x19bf, 0x2004, 0x9106, 0x11b0, 0x7144, 0x2001,
+	0x19c0, 0x2004, 0x9106, 0x0190, 0x9186, 0x0002, 0x1168, 0x2011,
+	0x0276, 0x20a9, 0x0004, 0x6010, 0x0096, 0x2048, 0x2019, 0x000a,
+	0x080c, 0xbf3e, 0x009e, 0x0110, 0x6017, 0x0001, 0x6003, 0x0001,
+	0x080c, 0x942f, 0x080c, 0x98bf, 0x0005, 0x6007, 0x0050, 0x703c,
+	0x6016, 0x0ca0, 0x0016, 0x00e6, 0x2071, 0x0260, 0x00b6, 0x00c6,
+	0x2260, 0x6010, 0x2058, 0xb8d4, 0xd084, 0x0150, 0x7128, 0x604c,
+	0x9106, 0x1120, 0x712c, 0x6050, 0x9106, 0x0110, 0x9006, 0x0010,
+	0x9085, 0x0001, 0x00ce, 0x00be, 0x00ee, 0x001e, 0x0005, 0x0016,
+	0x0096, 0x0086, 0x00e6, 0x01c6, 0x01d6, 0x0126, 0x2091, 0x8000,
+	0x2071, 0x1800, 0x20e1, 0x0000, 0x2001, 0x19a1, 0x2003, 0x0000,
+	0x080c, 0x1072, 0x05a0, 0x2900, 0x6016, 0x7090, 0x8004, 0xa816,
+	0x908a, 0x001e, 0x02d0, 0xa833, 0x001e, 0x20a9, 0x001e, 0xa860,
+	0x20e8, 0xa85c, 0x9080, 0x001b, 0x20a0, 0x2001, 0x19a1, 0x0016,
+	0x200c, 0x0471, 0x001e, 0x81ff, 0x01b8, 0x2940, 0x080c, 0x1072,
+	0x01b0, 0x2900, 0xa006, 0x2100, 0x0c18, 0xa832, 0x20a8, 0xa860,
+	0x20e8, 0xa85c, 0x9080, 0x001b, 0x20a0, 0x2001, 0x19a1, 0x0016,
+	0x200c, 0x00b1, 0x001e, 0x0000, 0x9085, 0x0001, 0x0048, 0x2071,
+	0x1800, 0x7093, 0x0000, 0x6014, 0x2048, 0x080c, 0x100b, 0x9006,
+	0x012e, 0x01de, 0x01ce, 0x00ee, 0x008e, 0x009e, 0x001e, 0x0005,
+	0x0006, 0x0016, 0x0026, 0x0036, 0x00c6, 0x918c, 0xffff, 0x11b0,
+	0x080c, 0x221a, 0x2099, 0x026c, 0x2001, 0x0014, 0x3518, 0x9312,
+	0x0108, 0x1218, 0x23a8, 0x4003, 0x0400, 0x20a8, 0x4003, 0x22a8,
+	0x8108, 0x080c, 0x221a, 0x2099, 0x0260, 0x0ca8, 0x080c, 0x221a,
+	0x2061, 0x19a1, 0x6004, 0x2098, 0x6008, 0x3518, 0x9312, 0x0108,
+	0x1218, 0x23a8, 0x4003, 0x0048, 0x20a8, 0x4003, 0x22a8, 0x8108,
+	0x080c, 0x221a, 0x2099, 0x0260, 0x0ca8, 0x2061, 0x19a1, 0x2019,
+	0x0280, 0x3300, 0x931e, 0x0110, 0x6006, 0x0020, 0x2001, 0x0260,
+	0x6006, 0x8108, 0x2162, 0x9292, 0x0021, 0x9296, 0xffff, 0x620a,
+	0x00ce, 0x003e, 0x002e, 0x001e, 0x000e, 0x0005, 0x0006, 0x0016,
+	0x0026, 0x0036, 0x00c6, 0x81ff, 0x11b8, 0x080c, 0x2232, 0x20a1,
+	0x024c, 0x2001, 0x0014, 0x3518, 0x9312, 0x1218, 0x23a8, 0x4003,
+	0x0418, 0x20a8, 0x4003, 0x82ff, 0x01f8, 0x22a8, 0x8108, 0x080c,
+	0x2232, 0x20a1, 0x0240, 0x0c98, 0x080c, 0x2232, 0x2061, 0x19a4,
+	0x6004, 0x20a0, 0x6008, 0x3518, 0x9312, 0x1218, 0x23a8, 0x4003,
+	0x0058, 0x20a8, 0x4003, 0x82ff, 0x0138, 0x22a8, 0x8108, 0x080c,
+	0x2232, 0x20a1, 0x0240, 0x0c98, 0x2061, 0x19a4, 0x2019, 0x0260,
+	0x3400, 0x931e, 0x0110, 0x6006, 0x0020, 0x2001, 0x0240, 0x6006,
+	0x8108, 0x2162, 0x9292, 0x0021, 0x9296, 0xffff, 0x620a, 0x00ce,
+	0x003e, 0x002e, 0x001e, 0x000e, 0x0005, 0x00b6, 0x0066, 0x6610,
+	0x2658, 0xbe04, 0x96b4, 0xff00, 0x8637, 0x9686, 0x0006, 0x0170,
+	0x9686, 0x0004, 0x0158, 0xbe04, 0x96b4, 0x00ff, 0x9686, 0x0006,
+	0x0128, 0x9686, 0x0004, 0x0110, 0x9085, 0x0001, 0x006e, 0x00be,
+	0x0005, 0x00d6, 0x080c, 0xdacb, 0x00de, 0x0005, 0x00d6, 0x080c,
+	0xdad8, 0x1520, 0x680c, 0x908c, 0xff00, 0x6820, 0x9084, 0x00ff,
+	0x9115, 0x6216, 0x6824, 0x602e, 0xd1e4, 0x0130, 0x9006, 0x080c,
+	0xeaf2, 0x2009, 0x0001, 0x0078, 0xd1ec, 0x0180, 0x6920, 0x918c,
+	0x00ff, 0x6824, 0x080c, 0x26a2, 0x1148, 0x2001, 0x0001, 0x080c,
+	0xeaf2, 0x2110, 0x900e, 0x080c, 0x335f, 0x0018, 0x9085, 0x0001,
+	0x0008, 0x9006, 0x00de, 0x0005, 0x00b6, 0x00c6, 0x080c, 0xaf9f,
+	0x0598, 0x0016, 0x0026, 0x00c6, 0x2011, 0x0263, 0x2204, 0x8211,
+	0x220c, 0x080c, 0x26a2, 0x1568, 0x080c, 0x671e, 0x1550, 0xbe12,
+	0xbd16, 0x00ce, 0x002e, 0x001e, 0x2b00, 0x6012, 0x080c, 0xe924,
+	0x11c8, 0x080c, 0x3447, 0x11b0, 0x080c, 0xda35, 0x0500, 0x2001,
+	0x0007, 0x080c, 0x66cf, 0x2001, 0x0007, 0x080c, 0x66fb, 0x6017,
+	0x0000, 0x6023, 0x0001, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c,
+	0x942f, 0x0010, 0x080c, 0xaf2e, 0x9085, 0x0001, 0x00ce, 0x00be,
+	0x0005, 0x080c, 0xaf2e, 0x00ce, 0x002e, 0x001e, 0x0ca8, 0x080c,
+	0xaf2e, 0x9006, 0x0c98, 0x2069, 0x026d, 0x6800, 0x9082, 0x0010,
+	0x1228, 0x6017, 0x0000, 0x9085, 0x0001, 0x0008, 0x9006, 0x0005,
+	0x6017, 0x0000, 0x2069, 0x026c, 0x6808, 0x9084, 0xff00, 0x9086,
+	0x0800, 0x1190, 0x6904, 0x9186, 0x0018, 0x0118, 0x9186, 0x0014,
+	0x1158, 0x810f, 0x6800, 0x9084, 0x00ff, 0x910d, 0x6162, 0x908e,
+	0x0014, 0x0110, 0x908e, 0x0010, 0x0005, 0x6004, 0x90b2, 0x0053,
+	0x1a0c, 0x0d85, 0x91b6, 0x0013, 0x1130, 0x2008, 0x91b2, 0x0040,
+	0x1a04, 0xdc38, 0x0402, 0x91b6, 0x0027, 0x0190, 0x9186, 0x0015,
+	0x0118, 0x9186, 0x0016, 0x1140, 0x080c, 0xad2d, 0x0120, 0x9086,
+	0x0002, 0x0904, 0xb966, 0x0005, 0x91b6, 0x0014, 0x190c, 0x0d85,
+	0x2001, 0x0007, 0x080c, 0x66fb, 0x080c, 0x97fe, 0x080c, 0xaf69,
+	0x080c, 0x98bf, 0x0005, 0xdb63, 0xdb65, 0xdb63, 0xdb63, 0xdb63,
+	0xdb65, 0xdb72, 0xdc35, 0xdbc2, 0xdc35, 0xdbe6, 0xdc35, 0xdb72,
+	0xdc35, 0xdc2d, 0xdc35, 0xdc2d, 0xdc35, 0xdc35, 0xdb63, 0xdb63,
+	0xdb63, 0xdb63, 0xdb63, 0xdb63, 0xdb63, 0xdb63, 0xdb63, 0xdb63,
+	0xdb63, 0xdb65, 0xdb63, 0xdc35, 0xdb63, 0xdb63, 0xdc35, 0xdb63,
+	0xdc32, 0xdc35, 0xdb63, 0xdb63, 0xdb63, 0xdb63, 0xdc35, 0xdc35,
+	0xdb63, 0xdc35, 0xdc35, 0xdb63, 0xdb6d, 0xdb63, 0xdb63, 0xdb63,
+	0xdb63, 0xdc31, 0xdc35, 0xdb63, 0xdb63, 0xdc35, 0xdc35, 0xdb63,
+	0xdb63, 0xdb63, 0xdb63, 0x080c, 0x0d85, 0x080c, 0xd356, 0x6003,
+	0x0002, 0x080c, 0x98bf, 0x0804, 0xdc37, 0x9006, 0x080c, 0x66bb,
+	0x0804, 0xdc35, 0x080c, 0x6bcd, 0x1904, 0xdc35, 0x9006, 0x080c,
+	0x66bb, 0x6010, 0x2058, 0xb810, 0x9086, 0x00ff, 0x1140, 0x00f6,
+	0x2079, 0x1800, 0x78a8, 0x8000, 0x78aa, 0x00fe, 0x0428, 0x6010,
+	0x2058, 0xb884, 0x9005, 0x1178, 0x080c, 0xd33e, 0x1904, 0xdc35,
+	0x0036, 0x0046, 0xbba0, 0x2021, 0x0007, 0x080c, 0x4de5, 0x004e,
+	0x003e, 0x0804, 0xdc35, 0x080c, 0x3478, 0x1904, 0xdc35, 0x2001,
+	0x1800, 0x2004, 0x9086, 0x0002, 0x1138, 0x00f6, 0x2079, 0x1800,
+	0x78a8, 0x8000, 0x78aa, 0x00fe, 0x2001, 0x0002, 0x080c, 0x66cf,
+	0x6023, 0x0001, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x942f,
+	0x080c, 0x98bf, 0x6110, 0x2158, 0x2009, 0x0001, 0x080c, 0x8842,
+	0x0804, 0xdc37, 0x6610, 0x2658, 0xbe04, 0x96b4, 0xff00, 0x8637,
+	0x9686, 0x0006, 0x0148, 0x9686, 0x0004, 0x0130, 0x080c, 0x90c6,
+	0x2001, 0x0004, 0x080c, 0x66fb, 0x080c, 0xeb41, 0x0904, 0xdc35,
+	0x2001, 0x0004, 0x080c, 0x66cf, 0x6023, 0x0001, 0x6003, 0x0001,
+	0x6007, 0x0003, 0x080c, 0x942f, 0x0804, 0xdc37, 0x2001, 0x1800,
+	0x2004, 0x9086, 0x0003, 0x1158, 0x0036, 0x0046, 0x6010, 0x2058,
+	0xbba0, 0x2021, 0x0006, 0x080c, 0x4de5, 0x004e, 0x003e, 0x2001,
+	0x0006, 0x080c, 0xdc51, 0x6610, 0x2658, 0xbe04, 0x0066, 0x96b4,
+	0xff00, 0x8637, 0x9686, 0x0006, 0x006e, 0x0168, 0x2001, 0x0006,
+	0x080c, 0x66fb, 0x9284, 0x00ff, 0x908e, 0x0007, 0x1120, 0x2001,
+	0x0006, 0x080c, 0x66cf, 0x080c, 0x6bcd, 0x11f8, 0x2001, 0x1837,
+	0x2004, 0xd0a4, 0x01d0, 0xbe04, 0x96b4, 0x00ff, 0x9686, 0x0006,
+	0x01a0, 0x00f6, 0x2079, 0x1800, 0x78a8, 0x8000, 0x78aa, 0x00fe,
+	0x0804, 0xdbac, 0x2001, 0x0004, 0x0030, 0x2001, 0x0006, 0x0409,
+	0x0020, 0x0018, 0x0010, 0x080c, 0x66fb, 0x080c, 0xaf2e, 0x0005,
+	0x2600, 0x0002, 0xdc4c, 0xdc4c, 0xdc4c, 0xdc4c, 0xdc4c, 0xdc4e,
+	0xdc4c, 0xdc4e, 0xdc4c, 0xdc4c, 0xdc4e, 0xdc4c, 0xdc4c, 0xdc4c,
+	0xdc4e, 0xdc4e, 0xdc4e, 0xdc4e, 0x080c, 0x0d85, 0x080c, 0xaf2e,
+	0x0005, 0x0016, 0x00b6, 0x00d6, 0x6110, 0x2158, 0xb900, 0xd184,
+	0x0138, 0x080c, 0x66cf, 0x9006, 0x080c, 0x66bb, 0x080c, 0x333f,
+	0x00de, 0x00be, 0x001e, 0x0005, 0x6610, 0x2658, 0xb804, 0x9084,
+	0xff00, 0x8007, 0x90b2, 0x000c, 0x1a0c, 0x0d85, 0x91b6, 0x0015,
+	0x1110, 0x003b, 0x0028, 0x91b6, 0x0016, 0x190c, 0x0d85, 0x006b,
+	0x0005, 0xba08, 0xba08, 0xba08, 0xba08, 0xdce6, 0xba08, 0xdcd0,
+	0xdc91, 0xba08, 0xba08, 0xba08, 0xba08, 0xba08, 0xba08, 0xba08,
+	0xba08, 0xdce6, 0xba08, 0xdcd0, 0xdcd7, 0xba08, 0xba08, 0xba08,
+	0xba08, 0x00f6, 0x080c, 0x6bcd, 0x11d8, 0x080c, 0xd33e, 0x11c0,
+	0x6010, 0x905d, 0x01a8, 0xb884, 0x9005, 0x0190, 0x9006, 0x080c,
+	0x66bb, 0x2001, 0x0002, 0x080c, 0x66cf, 0x6023, 0x0001, 0x6003,
+	0x0001, 0x6007, 0x0002, 0x080c, 0x942f, 0x080c, 0x98bf, 0x00f0,
+	0x2011, 0x0263, 0x2204, 0x8211, 0x220c, 0x080c, 0x26a2, 0x11b0,
+	0x080c, 0x6789, 0x0118, 0x080c, 0xaf2e, 0x0080, 0xb810, 0x0006,
+	0xb814, 0x0006, 0xb884, 0x0006, 0x080c, 0x6198, 0x000e, 0xb886,
+	0x000e, 0xb816, 0x000e, 0xb812, 0x080c, 0xaf2e, 0x00fe, 0x0005,
+	0x6604, 0x96b6, 0x001e, 0x1110, 0x080c, 0xaf2e, 0x0005, 0x080c,
+	0xbda3, 0x1148, 0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x942f,
+	0x080c, 0x98bf, 0x0010, 0x080c, 0xaf2e, 0x0005, 0x0804, 0xaf2e,
+	0x6004, 0x908a, 0x0053, 0x1a0c, 0x0d85, 0x080c, 0x97fe, 0x080c,
+	0xaf69, 0x0005, 0x9182, 0x0040, 0x0002, 0xdd09, 0xdd09, 0xdd09,
+	0xdd09, 0xdd0b, 0xdd09, 0xdd09, 0xdd09, 0xdd09, 0xdd09, 0xdd09,
+	0xdd09, 0xdd09, 0xdd09, 0xdd09, 0xdd09, 0xdd09, 0xdd09, 0xdd09,
+	0xdd09, 0x080c, 0x0d85, 0x0096, 0x00b6, 0x00d6, 0x00e6, 0x00f6,
+	0x0046, 0x0026, 0x6210, 0x2258, 0xb8bc, 0x9005, 0x11b0, 0x6007,
+	0x0044, 0x2071, 0x0260, 0x7444, 0x94a4, 0xff00, 0x0904, 0xdd72,
+	0x080c, 0xeae6, 0x1170, 0x9486, 0x2000, 0x1158, 0x2009, 0x0001,
+	0x2011, 0x0200, 0x080c, 0x8ae5, 0x0020, 0x9026, 0x080c, 0xe969,
+	0x0c30, 0x080c, 0x1059, 0x090c, 0x0d85, 0x6003, 0x0007, 0xa867,
+	0x010d, 0x9006, 0xa802, 0xa86a, 0xac8a, 0x2c00, 0xa88e, 0x6008,
+	0xa8e2, 0x6010, 0x2058, 0xb8a0, 0x7130, 0xa97a, 0x0016, 0xa876,
+	0xa87f, 0x0000, 0xa883, 0x0000, 0xa887, 0x0036, 0x080c, 0x6f19,
+	0x001e, 0x080c, 0xeae6, 0x1904, 0xddd2, 0x9486, 0x2000, 0x1130,
+	0x2019, 0x0017, 0x080c, 0xe696, 0x0804, 0xddd2, 0x9486, 0x0200,
+	0x1120, 0x080c, 0xe621, 0x0804, 0xddd2, 0x9486, 0x0400, 0x0120,
+	0x9486, 0x1000, 0x1904, 0xddd2, 0x2019, 0x0002, 0x080c, 0xe640,
+	0x0804, 0xddd2, 0x2069, 0x1a74, 0x6a00, 0xd284, 0x0904, 0xde3c,
+	0x9284, 0x0300, 0x1904, 0xde35, 0x6804, 0x9005, 0x0904, 0xde1d,
+	0x2d78, 0x6003, 0x0007, 0x080c, 0x1072, 0x0904, 0xddde, 0x7800,
+	0xd08c, 0x1118, 0x7804, 0x8001, 0x7806, 0x6017, 0x0000, 0x2001,
+	0x180f, 0x2004, 0xd084, 0x1904, 0xde40, 0x9006, 0xa802, 0xa867,
+	0x0116, 0xa86a, 0x6008, 0xa8e2, 0x2c00, 0xa87a, 0x6010, 0x2058,
+	0xb8a0, 0x7130, 0xa9b6, 0xa876, 0xb928, 0xa9ba, 0xb92c, 0xa9be,
+	0xb930, 0xa9c2, 0xb934, 0xa9c6, 0xa883, 0x003d, 0x7044, 0x9084,
+	0x0003, 0x9080, 0xddda, 0x2005, 0xa87e, 0x20a9, 0x000a, 0x2001,
+	0x0270, 0xaa5c, 0x9290, 0x0021, 0x2009, 0x0205, 0x200b, 0x0080,
+	0x20e1, 0x0000, 0xab60, 0x23e8, 0x2098, 0x22a0, 0x4003, 0x200b,
+	0x0000, 0x2001, 0x027a, 0x200c, 0xa9b2, 0x8000, 0x200c, 0xa9ae,
+	0x080c, 0x6f1c, 0x002e, 0x004e, 0x00fe, 0x00ee, 0x00de, 0x00be,
+	0x009e, 0x0005, 0x0000, 0x0080, 0x0040, 0x0000, 0x2001, 0x1810,
+	0x2004, 0xd084, 0x0120, 0x080c, 0x1059, 0x1904, 0xdd87, 0x6017,
+	0xf100, 0x6003, 0x0001, 0x6007, 0x0041, 0x2009, 0xa022, 0x080c,
+	0x9428, 0x0c00, 0x2069, 0x0260, 0x6848, 0x9084, 0xff00, 0x9086,
+	0x1200, 0x1198, 0x686c, 0x9084, 0x00ff, 0x0016, 0x6114, 0x918c,
+	0xf700, 0x910d, 0x6116, 0x001e, 0x6003, 0x0001, 0x6007, 0x0043,
+	0x2009, 0xa025, 0x080c, 0x9428, 0x0828, 0x6868, 0x602e, 0x686c,
+	0x6032, 0x6017, 0xf200, 0x6003, 0x0001, 0x6007, 0x0041, 0x2009,
+	0xa022, 0x080c, 0x9428, 0x0804, 0xddd2, 0x2001, 0x180e, 0x2004,
+	0xd0ec, 0x0120, 0x2011, 0x8049, 0x080c, 0x4c2e, 0x6017, 0xf300,
+	0x0010, 0x6017, 0xf100, 0x6003, 0x0001, 0x6007, 0x0041, 0x2009,
+	0xa022, 0x080c, 0x9428, 0x0804, 0xddd2, 0x6017, 0xf500, 0x0c98,
+	0x6017, 0xf600, 0x0804, 0xddf2, 0x6017, 0xf200, 0x0804, 0xddf2,
+	0xa867, 0x0146, 0xa86b, 0x0000, 0x6008, 0xa886, 0x2c00, 0xa87a,
+	0x7044, 0x9084, 0x0003, 0x9080, 0xddda, 0x2005, 0xa87e, 0x2928,
+	0x6010, 0x2058, 0xb8a0, 0xa876, 0xb828, 0xa88a, 0xb82c, 0xa88e,
+	0xb830, 0xa892, 0xb834, 0xa896, 0xa883, 0x003d, 0x2009, 0x0205,
+	0x2104, 0x9085, 0x0080, 0x200a, 0x20e1, 0x0000, 0x2011, 0x0210,
+	0x2214, 0x9294, 0x0fff, 0xaaa2, 0x9282, 0x0111, 0x1a0c, 0x0d85,
+	0x8210, 0x821c, 0x2001, 0x026c, 0x2098, 0xa860, 0x20e8, 0xa85c,
+	0x9080, 0x0029, 0x20a0, 0x2011, 0xdebc, 0x2041, 0x0001, 0x223d,
+	0x9784, 0x00ff, 0x9322, 0x1208, 0x2300, 0x20a8, 0x4003, 0x931a,
+	0x0530, 0x8210, 0xd7fc, 0x1130, 0x8d68, 0x2d0a, 0x2001, 0x0260,
+	0x2098, 0x0c68, 0x2950, 0x080c, 0x1072, 0x0170, 0x2900, 0xb002,
+	0xa867, 0x0147, 0xa86b, 0x0000, 0xa860, 0x20e8, 0xa85c, 0x9080,
+	0x001b, 0x20a0, 0x8840, 0x08d8, 0x2548, 0xa800, 0x902d, 0x0118,
+	0x080c, 0x108b, 0x0cc8, 0x080c, 0x108b, 0x0804, 0xddde, 0x2548,
+	0x8847, 0x9885, 0x0046, 0xa866, 0x2009, 0x0205, 0x200b, 0x0000,
+	0x080c, 0xe6cd, 0x0804, 0xddd2, 0x8010, 0x0004, 0x801a, 0x0006,
+	0x8018, 0x0008, 0x8016, 0x000a, 0x8014, 0x9186, 0x0013, 0x1160,
+	0x6004, 0x908a, 0x0057, 0x1a0c, 0x0d85, 0x9082, 0x0040, 0x0a0c,
+	0x0d85, 0x2008, 0x0804, 0xdf48, 0x9186, 0x0051, 0x0108, 0x0040,
+	0x080c, 0xad2d, 0x01e8, 0x9086, 0x0002, 0x0904, 0xdf90, 0x00c0,
+	0x9186, 0x0027, 0x0180, 0x9186, 0x0048, 0x0128, 0x9186, 0x0014,
+	0x0150, 0x190c, 0x0d85, 0x080c, 0xad2d, 0x0150, 0x9086, 0x0004,
+	0x0904, 0xe02f, 0x0028, 0x6004, 0x9082, 0x0040, 0x2008, 0x001a,
+	0x080c, 0xafe9, 0x0005, 0xdf0f, 0xdf11, 0xdf11, 0xdf38, 0xdf0f,
+	0xdf0f, 0xdf0f, 0xdf0f, 0xdf0f, 0xdf0f, 0xdf0f, 0xdf0f, 0xdf0f,
+	0xdf0f, 0xdf0f, 0xdf0f, 0xdf0f, 0xdf0f, 0xdf0f, 0xdf0f, 0x080c,
+	0x0d85, 0x080c, 0x97fe, 0x080c, 0x98bf, 0x0036, 0x0096, 0x6014,
+	0x904d, 0x01d8, 0x080c, 0xcc16, 0x01c0, 0x6003, 0x0002, 0x6010,
+	0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x1178, 0x2019, 0x0004,
+	0x080c, 0xe6cd, 0x6017, 0x0000, 0x6018, 0x9005, 0x1120, 0x2001,
+	0x1988, 0x2004, 0x601a, 0x6003, 0x0007, 0x009e, 0x003e, 0x0005,
+	0x0096, 0x080c, 0x97fe, 0x080c, 0x98bf, 0x080c, 0xcc16, 0x0120,
+	0x6014, 0x2048, 0x080c, 0x108b, 0x080c, 0xaf69, 0x009e, 0x0005,
+	0x0002, 0xdf5d, 0xdf72, 0xdf5f, 0xdf87, 0xdf5d, 0xdf5d, 0xdf5d,
+	0xdf5d, 0xdf5d, 0xdf5d, 0xdf5d, 0xdf5d, 0xdf5d, 0xdf5d, 0xdf5d,
+	0xdf5d, 0xdf5d, 0xdf5d, 0xdf5d, 0xdf5d, 0x080c, 0x0d85, 0x0096,
+	0x6014, 0x2048, 0xa87c, 0xd0b4, 0x0138, 0x6003, 0x0007, 0x2009,
+	0x0043, 0x080c, 0xafcc, 0x0010, 0x6003, 0x0004, 0x080c, 0x98bf,
+	0x009e, 0x0005, 0x080c, 0xcc16, 0x0138, 0x6114, 0x0096, 0x2148,
+	0xa97c, 0x009e, 0xd1ec, 0x1138, 0x080c, 0x8aba, 0x080c, 0xaf2e,
+	0x080c, 0x98bf, 0x0005, 0x080c, 0xe92d, 0x0db0, 0x0cc8, 0x6003,
+	0x0001, 0x6007, 0x0041, 0x2009, 0xa022, 0x080c, 0x9428, 0x0005,
+	0x9182, 0x0040, 0x0002, 0xdfa7, 0xdfa9, 0xdfa7, 0xdfa7, 0xdfa7,
+	0xdfa7, 0xdfa7, 0xdfa7, 0xdfa7, 0xdfa7, 0xdfa7, 0xdfa7, 0xdfa7,
+	0xdfa7, 0xdfa7, 0xdfa7, 0xdfa7, 0xdfaa, 0xdfa7, 0xdfa7, 0x080c,
+	0x0d85, 0x0005, 0x00d6, 0x080c, 0x8aba, 0x00de, 0x080c, 0xe985,
+	0x080c, 0xaf2e, 0x0005, 0x9182, 0x0040, 0x0002, 0xdfca, 0xdfca,
+	0xdfca, 0xdfca, 0xdfca, 0xdfca, 0xdfca, 0xdfca, 0xdfca, 0xdfcc,
+	0xdff7, 0xdfca, 0xdfca, 0xdfca, 0xdfca, 0xdff7, 0xdfca, 0xdfca,
+	0xdfca, 0xdfca, 0x080c, 0x0d85, 0x6014, 0x0096, 0x2048, 0xa87c,
+	0xd0fc, 0x0168, 0x908c, 0x0003, 0x918e, 0x0002, 0x0180, 0x6144,
+	0xd1e4, 0x1168, 0x2009, 0x0041, 0x009e, 0x0804, 0xe0b7, 0x6003,
+	0x0007, 0x601b, 0x0000, 0x080c, 0x8aba, 0x009e, 0x0005, 0x6014,
+	0x2048, 0xa97c, 0xd1ec, 0x1130, 0x080c, 0x8aba, 0x080c, 0xaf2e,
+	0x009e, 0x0005, 0x080c, 0xe92d, 0x0db8, 0x009e, 0x0005, 0x2001,
+	0x180c, 0x200c, 0xc1d4, 0x2102, 0x0036, 0x080c, 0x9859, 0x080c,
+	0x98bf, 0x6014, 0x0096, 0x2048, 0x6010, 0x00b6, 0x2058, 0xb800,
+	0x00be, 0xd0bc, 0x0188, 0xa87c, 0x9084, 0x0003, 0x9086, 0x0002,
+	0x0140, 0xa8ac, 0x6330, 0x931a, 0x6332, 0xa8b0, 0x632c, 0x931b,
+	0x632e, 0x6003, 0x0002, 0x0080, 0x2019, 0x0004, 0x080c, 0xe6cd,
+	0x6018, 0x9005, 0x1128, 0x2001, 0x1988, 0x2004, 0x8003, 0x601a,
+	0x6017, 0x0000, 0x6003, 0x0007, 0x009e, 0x003e, 0x0005, 0x9182,
+	0x0040, 0x0002, 0xe046, 0xe046, 0xe046, 0xe046, 0xe046, 0xe046,
+	0xe046, 0xe046, 0xe048, 0xe046, 0xe046, 0xe046, 0xe046, 0xe046,
+	0xe046, 0xe046, 0xe046, 0xe046, 0xe046, 0xe093, 0x080c, 0x0d85,
+	0x6014, 0x0096, 0x2048, 0xa834, 0xaa38, 0x6110, 0x00b6, 0x2158,
+	0xb900, 0x00be, 0xd1bc, 0x1190, 0x920d, 0x1518, 0xa87c, 0xd0fc,
+	0x0128, 0x2009, 0x0041, 0x009e, 0x0804, 0xe0b7, 0x6003, 0x0007,
+	0x601b, 0x0000, 0x080c, 0x8aba, 0x009e, 0x0005, 0x6124, 0xd1f4,
+	0x1d58, 0x0006, 0x0046, 0xacac, 0x9422, 0xa9b0, 0x2200, 0x910b,
+	0x6030, 0x9420, 0x6432, 0x602c, 0x9109, 0x612e, 0x004e, 0x000e,
+	0x08d8, 0x6110, 0x00b6, 0x2158, 0xb900, 0x00be, 0xd1bc, 0x1178,
+	0x2009, 0x180e, 0x210c, 0xd19c, 0x0118, 0x6003, 0x0007, 0x0010,
+	0x6003, 0x0006, 0x00e9, 0x080c, 0x8abc, 0x009e, 0x0005, 0x6003,
+	0x0002, 0x009e, 0x0005, 0x6024, 0xd0f4, 0x0128, 0x080c, 0x16b0,
+	0x1904, 0xe048, 0x0005, 0x6014, 0x0096, 0x2048, 0xa834, 0xa938,
+	0x009e, 0x9105, 0x1120, 0x080c, 0x16b0, 0x1904, 0xe048, 0x0005,
+	0xd2fc, 0x0140, 0x8002, 0x8000, 0x8212, 0x9291, 0x0000, 0x2009,
+	0x0009, 0x0010, 0x2009, 0x0015, 0xaa9a, 0xa896, 0x0005, 0x9182,
+	0x0040, 0x0208, 0x0062, 0x9186, 0x0013, 0x0120, 0x9186, 0x0014,
+	0x190c, 0x0d85, 0x6024, 0xd0dc, 0x090c, 0x0d85, 0x0005, 0xe0db,
+	0xe0e7, 0xe0f3, 0xe0ff, 0xe0db, 0xe0db, 0xe0db, 0xe0db, 0xe0e2,
+	0xe0dd, 0xe0dd, 0xe0db, 0xe0db, 0xe0db, 0xe0db, 0xe0dd, 0xe0db,
+	0xe0dd, 0xe0db, 0xe0e2, 0x080c, 0x0d85, 0x6024, 0xd0dc, 0x090c,
+	0x0d85, 0x0005, 0x6014, 0x9005, 0x190c, 0x0d85, 0x0005, 0x6003,
+	0x0001, 0x6106, 0x0126, 0x2091, 0x8000, 0x2009, 0xa022, 0x080c,
+	0x940a, 0x012e, 0x0005, 0x6003, 0x0004, 0x6106, 0x0126, 0x2091,
+	0x8000, 0x2009, 0xa001, 0x080c, 0x9428, 0x012e, 0x0005, 0x6003,
+	0x0003, 0x6106, 0x080c, 0x1c90, 0x0126, 0x2091, 0x8000, 0x6014,
+	0x0096, 0x2048, 0xa87c, 0xd0fc, 0x0188, 0x9084, 0x0003, 0x9086,
+	0x0002, 0x01a0, 0x6024, 0xd0cc, 0x1148, 0xd0c4, 0x1138, 0xa8a8,
+	0x9005, 0x1120, 0x6144, 0x918d, 0xb035, 0x0018, 0x6144, 0x918d,
+	0xa035, 0x009e, 0x080c, 0x946f, 0x012e, 0x0005, 0x6144, 0x918d,
+	0xa032, 0x0cb8, 0x0126, 0x2091, 0x8000, 0x0036, 0x0096, 0x9182,
+	0x0040, 0x0023, 0x009e, 0x003e, 0x012e, 0x0005, 0xe14a, 0xe14c,
+	0xe161, 0xe17b, 0xe14a, 0xe14a, 0xe14a, 0xe14a, 0xe14a, 0xe14a,
+	0xe14a, 0xe14a, 0xe14a, 0xe14a, 0xe14a, 0xe14a, 0xe14a, 0xe14a,
+	0xe14a, 0xe14a, 0x080c, 0x0d85, 0x6014, 0x2048, 0xa87c, 0xd0fc,
+	0x0510, 0x909c, 0x0003, 0x939e, 0x0003, 0x01e8, 0x6003, 0x0001,
+	0x6106, 0x0126, 0x2091, 0x8000, 0x2009, 0xa022, 0x080c, 0x9428,
+	0x0470, 0x6014, 0x2048, 0xa87c, 0xd0fc, 0x0168, 0x909c, 0x0003,
+	0x939e, 0x0003, 0x0140, 0x6003, 0x0001, 0x6106, 0x2009, 0xa001,
+	0x080c, 0x9428, 0x00e0, 0x901e, 0x6316, 0x631a, 0x2019, 0x0004,
+	0x080c, 0xe6cd, 0x00a0, 0x6014, 0x2048, 0xa87c, 0xd0fc, 0x0d98,
+	0x909c, 0x0003, 0x939e, 0x0003, 0x0d70, 0x6003, 0x0003, 0x6106,
+	0x080c, 0x1c90, 0x6144, 0x918d, 0xa035, 0x080c, 0x946f, 0x0005,
+	0x080c, 0x97fe, 0x6114, 0x81ff, 0x0158, 0x0096, 0x2148, 0x080c,
+	0xea83, 0x0036, 0x2019, 0x0029, 0x080c, 0xe6cd, 0x003e, 0x009e,
+	0x080c, 0xaf69, 0x080c, 0x98bf, 0x0005, 0x080c, 0x9859, 0x6114,
+	0x81ff, 0x0158, 0x0096, 0x2148, 0x080c, 0xea83, 0x0036, 0x2019,
+	0x0029, 0x080c, 0xe6cd, 0x003e, 0x009e, 0x080c, 0xaf69, 0x0005,
+	0x9182, 0x0085, 0x0002, 0xe1ca, 0xe1c8, 0xe1c8, 0xe1d6, 0xe1c8,
+	0xe1c8, 0xe1c8, 0xe1c8, 0xe1c8, 0xe1c8, 0xe1c8, 0xe1c8, 0xe1c8,
+	0x080c, 0x0d85, 0x6003, 0x000b, 0x6106, 0x0126, 0x2091, 0x8000,
+	0x2009, 0x8020, 0x080c, 0x9428, 0x012e, 0x0005, 0x0026, 0x00e6,
+	0x080c, 0xe924, 0x0118, 0x080c, 0xaf2e, 0x0440, 0x2071, 0x0260,
+	0x7224, 0x6216, 0x2001, 0x180e, 0x2004, 0xd0e4, 0x0150, 0x6010,
+	0x00b6, 0x2058, 0xbca0, 0x00be, 0x2c00, 0x2011, 0x014e, 0x080c,
+	0xb25a, 0x7220, 0x080c, 0xe558, 0x0118, 0x6007, 0x0086, 0x0040,
+	0x6007, 0x0087, 0x7224, 0x9296, 0xffff, 0x1110, 0x6007, 0x0086,
+	0x6003, 0x0001, 0x2009, 0x8020, 0x080c, 0x9428, 0x00ee, 0x002e,
+	0x0005, 0x9186, 0x0013, 0x1160, 0x6004, 0x908a, 0x0085, 0x0a0c,
+	0x0d85, 0x908a, 0x0092, 0x1a0c, 0x0d85, 0x9082, 0x0085, 0x00a2,
+	0x9186, 0x0027, 0x0130, 0x9186, 0x0014, 0x0118, 0x080c, 0xafe9,
+	0x0050, 0x2001, 0x0007, 0x080c, 0x66fb, 0x080c, 0x97fe, 0x080c,
+	0xaf69, 0x080c, 0x98bf, 0x0005, 0xe239, 0xe23b, 0xe23b, 0xe239,
+	0xe239, 0xe239, 0xe239, 0xe239, 0xe239, 0xe239, 0xe239, 0xe239,
+	0xe239, 0x080c, 0x0d85, 0x080c, 0xaf69, 0x080c, 0x98bf, 0x0005,
+	0x9182, 0x0085, 0x0a0c, 0x0d85, 0x9182, 0x0092, 0x1a0c, 0x0d85,
+	0x9182, 0x0085, 0x0002, 0xe258, 0xe258, 0xe258, 0xe25a, 0xe258,
+	0xe258, 0xe258, 0xe258, 0xe258, 0xe258, 0xe258, 0xe258, 0xe258,
+	0x080c, 0x0d85, 0x0005, 0x9186, 0x0013, 0x0148, 0x9186, 0x0014,
+	0x0130, 0x9186, 0x0027, 0x0118, 0x080c, 0xafe9, 0x0020, 0x080c,
+	0x97fe, 0x080c, 0xaf69, 0x0005, 0x0036, 0x080c, 0xe985, 0x604b,
+	0x0000, 0x2019, 0x000b, 0x0031, 0x6023, 0x0006, 0x6003, 0x0007,
+	0x003e, 0x0005, 0x0126, 0x0036, 0x2091, 0x8000, 0x080c, 0xaae0,
+	0x0106, 0x0086, 0x2c40, 0x0096, 0x904e, 0x080c, 0xa44b, 0x009e,
+	0x008e, 0x1558, 0x0076, 0x2c38, 0x080c, 0xa4f6, 0x007e, 0x1528,
+	0x6000, 0x9086, 0x0000, 0x0508, 0x6020, 0x9086, 0x0007, 0x01e8,
+	0x0096, 0x601c, 0xd084, 0x0140, 0x080c, 0xe985, 0x080c, 0xd356,
+	0x080c, 0x1afc, 0x6023, 0x0007, 0x6014, 0x2048, 0x080c, 0xcc16,
+	0x0110, 0x080c, 0xe6cd, 0x009e, 0x9006, 0x6046, 0x6016, 0x080c,
+	0xe985, 0x6023, 0x0007, 0x080c, 0xd356, 0x010e, 0x090c, 0xaafc,
+	0x003e, 0x012e, 0x0005, 0x00f6, 0x00c6, 0x00b6, 0x0036, 0x0156,
+	0x2079, 0x0260, 0x7938, 0x783c, 0x080c, 0x26a2, 0x15e8, 0x0016,
+	0x00c6, 0x080c, 0x6789, 0x15b0, 0x001e, 0x00c6, 0x2160, 0x080c,
+	0xd353, 0x00ce, 0x002e, 0x0026, 0x0016, 0x080c, 0xaae0, 0x2019,
+	0x0029, 0x080c, 0xa5c6, 0x080c, 0x95c1, 0x0076, 0x903e, 0x080c,
+	0x947e, 0x007e, 0x001e, 0x0076, 0x903e, 0x080c, 0xe440, 0x007e,
+	0x080c, 0xaafc, 0x0026, 0xba04, 0x9294, 0xff00, 0x8217, 0x9286,
+	0x0006, 0x0118, 0x9286, 0x0004, 0x1118, 0xbaa0, 0x080c, 0x33db,
+	0x002e, 0xbc84, 0x001e, 0x080c, 0x6198, 0xbe12, 0xbd16, 0xbc86,
+	0x9006, 0x0010, 0x00ce, 0x001e, 0x015e, 0x003e, 0x00be, 0x00ce,
+	0x00fe, 0x0005, 0x00c6, 0x00d6, 0x00b6, 0x0016, 0x2009, 0x1824,
+	0x2104, 0x9086, 0x0074, 0x1904, 0xe363, 0x2069, 0x0260, 0x6944,
+	0x9182, 0x0100, 0x06e0, 0x6940, 0x9184, 0x8000, 0x0904, 0xe360,
+	0x2001, 0x197d, 0x2004, 0x9005, 0x1140, 0x6010, 0x2058, 0xb884,
+	0x9005, 0x0118, 0x9184, 0x0800, 0x0598, 0x6948, 0x918a, 0x0001,
+	0x0648, 0x080c, 0xeaeb, 0x0118, 0x6978, 0xd1fc, 0x11b8, 0x2009,
+	0x0205, 0x200b, 0x0001, 0x693c, 0x81ff, 0x1198, 0x6944, 0x9182,
+	0x0100, 0x02a8, 0x6940, 0x81ff, 0x1178, 0x6948, 0x918a, 0x0001,
+	0x0288, 0x6950, 0x918a, 0x0001, 0x0298, 0x00d0, 0x6017, 0x0100,
+	0x00a0, 0x6017, 0x0300, 0x0088, 0x6017, 0x0500, 0x0070, 0x6017,
+	0x0700, 0x0058, 0x6017, 0x0900, 0x0040, 0x6017, 0x0b00, 0x0028,
+	0x6017, 0x0f00, 0x0010, 0x6017, 0x2d00, 0x9085, 0x0001, 0x0008,
+	0x9006, 0x001e, 0x00be, 0x00de, 0x00ce, 0x0005, 0x00c6, 0x00b6,
+	0x0026, 0x0036, 0x0156, 0x6210, 0x2258, 0xbb04, 0x9394, 0x00ff,
+	0x9286, 0x0006, 0x0180, 0x9286, 0x0004, 0x0168, 0x9394, 0xff00,
+	0x8217, 0x9286, 0x0006, 0x0138, 0x9286, 0x0004, 0x0120, 0x080c,
+	0x6798, 0x0804, 0xe3cf, 0x2011, 0x0276, 0x20a9, 0x0004, 0x0096,
+	0x2b48, 0x2019, 0x000a, 0x080c, 0xbf3e, 0x009e, 0x15c8, 0x2011,
+	0x027a, 0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019, 0x0006, 0x080c,
+	0xbf3e, 0x009e, 0x1568, 0x0046, 0x0016, 0xbaa0, 0x2220, 0x9006,
+	0x2009, 0x1848, 0x210c, 0xd1a4, 0x0138, 0x2009, 0x0029, 0x080c,
+	0xe72a, 0xb800, 0xc0e5, 0xb802, 0x080c, 0xaae0, 0x2019, 0x0029,
+	0x080c, 0x95c1, 0x0076, 0x2039, 0x0000, 0x080c, 0x947e, 0x2c08,
+	0x080c, 0xe440, 0x007e, 0x080c, 0xaafc, 0x2001, 0x0007, 0x080c,
+	0x66fb, 0x2001, 0x0007, 0x080c, 0x66cf, 0x001e, 0x004e, 0x9006,
+	0x015e, 0x003e, 0x002e, 0x00be, 0x00ce, 0x0005, 0x00d6, 0x2069,
+	0x026e, 0x6800, 0x9086, 0x0800, 0x0118, 0x6017, 0x0000, 0x0008,
+	0x9006, 0x00de, 0x0005, 0x00b6, 0x00f6, 0x0016, 0x0026, 0x0036,
+	0x0156, 0x2079, 0x026c, 0x7930, 0x7834, 0x080c, 0x26a2, 0x11d0,
+	0x080c, 0x6789, 0x11b8, 0x2011, 0x0270, 0x20a9, 0x0004, 0x0096,
+	0x2b48, 0x2019, 0x000a, 0x080c, 0xbf3e, 0x009e, 0x1158, 0x2011,
+	0x0274, 0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019, 0x0006, 0x080c,
+	0xbf3e, 0x009e, 0x015e, 0x003e, 0x002e, 0x001e, 0x00fe, 0x00be,
+	0x0005, 0x00b6, 0x0006, 0x0016, 0x0026, 0x0036, 0x0156, 0x2011,
+	0x0263, 0x2204, 0x8211, 0x220c, 0x080c, 0x26a2, 0x11d0, 0x080c,
+	0x6789, 0x11b8, 0x2011, 0x0276, 0x20a9, 0x0004, 0x0096, 0x2b48,
+	0x2019, 0x000a, 0x080c, 0xbf3e, 0x009e, 0x1158, 0x2011, 0x027a,
+	0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019, 0x0006, 0x080c, 0xbf3e,
+	0x009e, 0x015e, 0x003e, 0x002e, 0x001e, 0x000e, 0x00be, 0x0005,
+	0x00e6, 0x00c6, 0x0086, 0x0076, 0x0066, 0x0056, 0x0046, 0x0026,
+	0x0126, 0x2091, 0x8000, 0x080c, 0xab3e, 0x0106, 0x190c, 0xaae0,
+	0x2740, 0x2029, 0x19f5, 0x252c, 0x2021, 0x19fc, 0x2424, 0x2061,
+	0x1ddc, 0x2071, 0x1800, 0x7654, 0x7074, 0x81ff, 0x0150, 0x0006,
+	0x9186, 0x1b3a, 0x000e, 0x0128, 0x8001, 0x9602, 0x1a04, 0xe4e6,
+	0x0018, 0x9606, 0x0904, 0xe4e6, 0x080c, 0x8d8f, 0x0904, 0xe4dd,
+	0x2100, 0x9c06, 0x0904, 0xe4dd, 0x6720, 0x9786, 0x0007, 0x0904,
+	0xe4dd, 0x080c, 0xe76b, 0x1904, 0xe4dd, 0x080c, 0xeb09, 0x0904,
+	0xe4dd, 0x080c, 0xe75b, 0x0904, 0xe4dd, 0x6720, 0x9786, 0x0001,
+	0x1148, 0x080c, 0x3478, 0x0904, 0xe528, 0x6004, 0x9086, 0x0000,
+	0x1904, 0xe528, 0x9786, 0x0004, 0x0904, 0xe528, 0x2500, 0x9c06,
+	0x0904, 0xe4dd, 0x2400, 0x9c06, 0x0904, 0xe4dd, 0x88ff, 0x0118,
+	0x605c, 0x9906, 0x15d0, 0x0096, 0x6043, 0xffff, 0x6000, 0x9086,
+	0x0004, 0x1120, 0x0016, 0x080c, 0x1afc, 0x001e, 0x9786, 0x000a,
+	0x0148, 0x080c, 0xce2d, 0x1130, 0x080c, 0xb91f, 0x009e, 0x080c,
+	0xaf69, 0x0418, 0x6014, 0x2048, 0x080c, 0xcc16, 0x01d8, 0x9786,
+	0x0003, 0x1588, 0xa867, 0x0103, 0xa87c, 0xd0cc, 0x0130, 0x0096,
+	0xa878, 0x2048, 0x080c, 0x100b, 0x009e, 0xab7a, 0xa877, 0x0000,
+	0x080c, 0xea83, 0x0016, 0x080c, 0xcf1b, 0x080c, 0x6f0d, 0x001e,
+	0x080c, 0xce07, 0x009e, 0x080c, 0xaf69, 0x9ce0, 0x001c, 0x2001,
+	0x181a, 0x2004, 0x9c02, 0x1210, 0x0804, 0xe459, 0x010e, 0x190c,
+	0xaafc, 0x012e, 0x002e, 0x004e, 0x005e, 0x006e, 0x007e, 0x008e,
+	0x00ce, 0x00ee, 0x0005, 0x9786, 0x0006, 0x1150, 0x9386, 0x0005,
+	0x0128, 0x080c, 0xea83, 0x080c, 0xe6cd, 0x08e0, 0x009e, 0x08e8,
+	0x9786, 0x0009, 0x11f8, 0x6000, 0x9086, 0x0004, 0x01c0, 0x6000,
+	0x9086, 0x0003, 0x11a0, 0x080c, 0x9859, 0x0096, 0x6114, 0x2148,
+	0x080c, 0xcc16, 0x0118, 0x6010, 0x080c, 0x6f19, 0x009e, 0x00c6,
+	0x080c, 0xaf2e, 0x00ce, 0x0036, 0x080c, 0x98bf, 0x003e, 0x009e,
+	0x0804, 0xe4dd, 0x9786, 0x000a, 0x0904, 0xe4cd, 0x0804, 0xe4c2,
+	0x81ff, 0x0904, 0xe4dd, 0x9180, 0x0001, 0x2004, 0x9086, 0x0018,
+	0x0138, 0x9180, 0x0001, 0x2004, 0x9086, 0x002d, 0x1904, 0xe4dd,
+	0x6000, 0x9086, 0x0002, 0x1904, 0xe4dd, 0x080c, 0xce1c, 0x0138,
+	0x080c, 0xce2d, 0x1904, 0xe4dd, 0x080c, 0xb91f, 0x0038, 0x080c,
+	0x333f, 0x080c, 0xce2d, 0x1110, 0x080c, 0xb91f, 0x080c, 0xaf69,
+	0x0804, 0xe4dd, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, 0x0005,
+	0x00c6, 0x00e6, 0x0016, 0x2c08, 0x2170, 0x9006, 0x080c, 0xe6f4,
+	0x001e, 0x0120, 0x6020, 0x9084, 0x000f, 0x001b, 0x00ee, 0x00ce,
+	0x0005, 0xe577, 0xe577, 0xe577, 0xe577, 0xe577, 0xe577, 0xe579,
+	0xe577, 0xe577, 0xe577, 0xe577, 0xaf69, 0xaf69, 0xe577, 0x9006,
+	0x0005, 0x0036, 0x0046, 0x0016, 0x7010, 0x00b6, 0x2058, 0xbca0,
+	0x00be, 0x2c00, 0x2009, 0x0020, 0x080c, 0xe72a, 0x001e, 0x004e,
+	0x2019, 0x0002, 0x080c, 0xe27a, 0x003e, 0x9085, 0x0001, 0x0005,
+	0x0096, 0x080c, 0xcc16, 0x0140, 0x6014, 0x904d, 0x080c, 0xc802,
+	0x687b, 0x0005, 0x080c, 0x6f19, 0x009e, 0x080c, 0xaf69, 0x9085,
+	0x0001, 0x0005, 0x2001, 0x0001, 0x080c, 0x66bb, 0x0156, 0x0016,
+	0x0026, 0x0036, 0x20a9, 0x0004, 0x2019, 0x1805, 0x2011, 0x0276,
+	0x080c, 0xbf2a, 0x003e, 0x002e, 0x001e, 0x015e, 0x9005, 0x0005,
+	0x00f6, 0x00e6, 0x00c6, 0x0086, 0x0076, 0x0066, 0x00b6, 0x0126,
+	0x2091, 0x8000, 0x2740, 0x2061, 0x1ddc, 0x2079, 0x0001, 0x8fff,
+	0x0904, 0xe614, 0x2071, 0x1800, 0x7654, 0x7074, 0x8001, 0x9602,
+	0x1a04, 0xe614, 0x88ff, 0x0120, 0x2800, 0x9c06, 0x15a0, 0x2078,
+	0x080c, 0xe75b, 0x0580, 0x2400, 0x9c06, 0x0568, 0x6720, 0x9786,
+	0x0006, 0x1548, 0x9786, 0x0007, 0x0530, 0x88ff, 0x1150, 0xd58c,
+	0x1118, 0x6010, 0x9b06, 0x11f8, 0xd584, 0x0118, 0x605c, 0x9106,
+	0x11d0, 0x0096, 0x601c, 0xd084, 0x0140, 0x080c, 0xe985, 0x080c,
+	0xd356, 0x080c, 0x1afc, 0x6023, 0x0007, 0x6014, 0x2048, 0x080c,
+	0xcc16, 0x0120, 0x0046, 0x080c, 0xe6cd, 0x004e, 0x009e, 0x080c,
+	0xaf69, 0x88ff, 0x1198, 0x9ce0, 0x001c, 0x2001, 0x181a, 0x2004,
+	0x9c02, 0x1210, 0x0804, 0xe5c7, 0x9006, 0x012e, 0x00be, 0x006e,
+	0x007e, 0x008e, 0x00ce, 0x00ee, 0x00fe, 0x0005, 0x98c5, 0x0001,
+	0x0ca0, 0x080c, 0xaae0, 0x00b6, 0x0076, 0x0056, 0x0086, 0x9046,
+	0x2029, 0x0001, 0x2c20, 0x2019, 0x0002, 0x6210, 0x2258, 0x0096,
+	0x904e, 0x080c, 0xa44b, 0x009e, 0x008e, 0x903e, 0x080c, 0xa4f6,
+	0x080c, 0xe5b8, 0x005e, 0x007e, 0x00be, 0x080c, 0xaafc, 0x0005,
+	0x080c, 0xaae0, 0x00b6, 0x0046, 0x0056, 0x0076, 0x00c6, 0x0156,
+	0x2c20, 0x2128, 0x20a9, 0x007f, 0x900e, 0x0016, 0x0036, 0x080c,
+	0x6789, 0x1180, 0x0056, 0x0086, 0x9046, 0x2508, 0x2029, 0x0001,
+	0x0096, 0x904e, 0x080c, 0xa44b, 0x009e, 0x008e, 0x903e, 0x080c,
+	0xa4f6, 0x005e, 0x003e, 0x001e, 0x8108, 0x1f04, 0xe64d, 0x0036,
+	0x2508, 0x2029, 0x0003, 0x080c, 0xe5b8, 0x003e, 0x015e, 0x00ce,
+	0x007e, 0x005e, 0x004e, 0x00be, 0x080c, 0xaafc, 0x0005, 0x080c,
+	0xaae0, 0x00b6, 0x0076, 0x0056, 0x6210, 0x2258, 0x0086, 0x9046,
+	0x2029, 0x0001, 0x2019, 0x0048, 0x0096, 0x904e, 0x080c, 0xa44b,
+	0x009e, 0x008e, 0x903e, 0x080c, 0xa4f6, 0x2c20, 0x080c, 0xe5b8,
+	0x005e, 0x007e, 0x00be, 0x080c, 0xaafc, 0x0005, 0x080c, 0xaae0,
+	0x00b6, 0x0046, 0x0056, 0x0076, 0x00c6, 0x0156, 0x2c20, 0x20a9,
+	0x0800, 0x900e, 0x0016, 0x0036, 0x080c, 0x6789, 0x1190, 0x0086,
+	0x9046, 0x2828, 0x0046, 0x2021, 0x0001, 0x080c, 0xe969, 0x004e,
+	0x0096, 0x904e, 0x080c, 0xa44b, 0x009e, 0x008e, 0x903e, 0x080c,
+	0xa4f6, 0x003e, 0x001e, 0x8108, 0x1f04, 0xe6a2, 0x0036, 0x2029,
+	0x0002, 0x080c, 0xe5b8, 0x003e, 0x015e, 0x00ce, 0x007e, 0x005e,
+	0x004e, 0x00be, 0x080c, 0xaafc, 0x0005, 0x0016, 0x00f6, 0x080c,
+	0xcc14, 0x0198, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0046, 0x0180,
+	0xa800, 0x907d, 0x0138, 0xa803, 0x0000, 0xab82, 0x080c, 0x6f19,
+	0x2f48, 0x0cb0, 0xab82, 0x080c, 0x6f19, 0x00fe, 0x001e, 0x0005,
+	0xa800, 0x907d, 0x0130, 0xa803, 0x0000, 0x080c, 0x6f19, 0x2f48,
+	0x0cb8, 0x080c, 0x6f19, 0x0c88, 0x00e6, 0x0046, 0x0036, 0x2061,
+	0x1ddc, 0x9005, 0x1138, 0x2071, 0x1800, 0x7454, 0x7074, 0x8001,
+	0x9402, 0x12f8, 0x2100, 0x9c06, 0x0188, 0x6000, 0x9086, 0x0000,
+	0x0168, 0x6008, 0x9206, 0x1150, 0x6320, 0x9386, 0x0009, 0x01b0,
+	0x6010, 0x91a0, 0x0004, 0x2424, 0x9406, 0x0140, 0x9ce0, 0x001c,
+	0x2001, 0x181a, 0x2004, 0x9c02, 0x1220, 0x0c20, 0x9085, 0x0001,
+	0x0008, 0x9006, 0x003e, 0x004e, 0x00ee, 0x0005, 0x631c, 0xd3c4,
+	0x1d68, 0x0c30, 0x0096, 0x0006, 0x080c, 0x1059, 0x000e, 0x090c,
+	0x0d85, 0xaae2, 0xa867, 0x010d, 0xa88e, 0x0026, 0x2010, 0x080c,
+	0xcc04, 0x2001, 0x0000, 0x0120, 0x2200, 0x9080, 0x0017, 0x2004,
+	0x002e, 0xa87a, 0x9186, 0x0020, 0x0110, 0xa8e3, 0xffff, 0xa986,
+	0xac76, 0xa87f, 0x0000, 0x2001, 0x198f, 0x2004, 0xa882, 0x9006,
+	0xa802, 0xa86a, 0xa88a, 0x0126, 0x2091, 0x8000, 0x080c, 0x6f19,
+	0x012e, 0x009e, 0x0005, 0x6700, 0x9786, 0x0000, 0x0158, 0x9786,
+	0x0001, 0x0140, 0x9786, 0x000a, 0x0128, 0x9786, 0x0009, 0x0110,
+	0x9085, 0x0001, 0x0005, 0x00e6, 0x6010, 0x9075, 0x0138, 0x00b6,
+	0x2058, 0xb8a0, 0x00be, 0x9206, 0x00ee, 0x0005, 0x9085, 0x0001,
+	0x0cd8, 0x0016, 0x6004, 0x908e, 0x001e, 0x11a0, 0x8007, 0x6134,
+	0x918c, 0x00ff, 0x9105, 0x6036, 0x6007, 0x0085, 0x6003, 0x000b,
+	0x6023, 0x0005, 0x2001, 0x1988, 0x2004, 0x601a, 0x2009, 0x8020,
+	0x080c, 0x9428, 0x001e, 0x0005, 0xa001, 0xa001, 0x0005, 0x6024,
+	0xd0e4, 0x0158, 0xd0cc, 0x0118, 0x080c, 0xcf62, 0x0030, 0x080c,
+	0xe985, 0x080c, 0x8aba, 0x080c, 0xaf2e, 0x0005, 0x9280, 0x0008,
+	0x2004, 0x9084, 0x000f, 0x0002, 0xe7ba, 0xe7ba, 0xe7ba, 0xe7bc,
+	0xe7ba, 0xe7bc, 0xe7bc, 0xe7ba, 0xe7bc, 0xe7ba, 0xe7ba, 0xe7ba,
+	0xe7ba, 0xe7ba, 0x9006, 0x0005, 0x9085, 0x0001, 0x0005, 0x9280,
+	0x0008, 0x2004, 0x9084, 0x000f, 0x0002, 0xe7d3, 0xe7d3, 0xe7d3,
+	0xe7d3, 0xe7d3, 0xe7d3, 0xe7e0, 0xe7d3, 0xe7d3, 0xe7d3, 0xe7d3,
+	0xe7d3, 0xe7d3, 0xe7d3, 0x6007, 0x003b, 0x602f, 0x0009, 0x6017,
+	0x2a00, 0x6003, 0x0001, 0x2009, 0x8020, 0x080c, 0x9428, 0x0005,
+	0x0096, 0x00c6, 0x2260, 0x080c, 0xe985, 0x604b, 0x0000, 0x6024,
+	0xc0f4, 0xc0e4, 0x6026, 0x603b, 0x0000, 0x00ce, 0x00d6, 0x2268,
+	0x9186, 0x0007, 0x1904, 0xe839, 0x6814, 0x9005, 0x0138, 0x2048,
+	0xa87c, 0xd0fc, 0x1118, 0x00de, 0x009e, 0x08a8, 0x6007, 0x003a,
+	0x6003, 0x0001, 0x2009, 0x8020, 0x080c, 0x9428, 0x00c6, 0x2d60,
+	0x6100, 0x9186, 0x0002, 0x1904, 0xe8b0, 0x6014, 0x9005, 0x1138,
+	0x6000, 0x9086, 0x0007, 0x190c, 0x0d85, 0x0804, 0xe8b0, 0x2048,
+	0x080c, 0xcc16, 0x1130, 0x0028, 0x2048, 0xa800, 0x9005, 0x1de0,
+	0x2900, 0x2048, 0xa87c, 0x9084, 0x0003, 0x9086, 0x0002, 0x1168,
+	0xa87c, 0xc0dc, 0xc0f4, 0xa87e, 0xa880, 0xc0fc, 0xa882, 0x2009,
+	0x0043, 0x080c, 0xe0b7, 0x0804, 0xe8b0, 0x2009, 0x0041, 0x0804,
+	0xe8aa, 0x9186, 0x0005, 0x15a0, 0x6814, 0x2048, 0xa87c, 0xd0bc,
+	0x1120, 0x00de, 0x009e, 0x0804, 0xe7d3, 0xd0b4, 0x0128, 0xd0fc,
+	0x090c, 0x0d85, 0x0804, 0xe7f4, 0x6007, 0x003a, 0x6003, 0x0001,
+	0x2009, 0x8020, 0x080c, 0x9428, 0x00c6, 0x2d60, 0x6100, 0x9186,
+	0x0002, 0x0120, 0x9186, 0x0004, 0x1904, 0xe8b0, 0x6814, 0x2048,
+	0xa97c, 0xc1f4, 0xc1dc, 0xa97e, 0xa980, 0xc1fc, 0xc1bc, 0xa982,
+	0x00f6, 0x2c78, 0x080c, 0x17ad, 0x00fe, 0x2009, 0x0042, 0x04d0,
+	0x0036, 0x080c, 0x1059, 0x090c, 0x0d85, 0xa867, 0x010d, 0x9006,
+	0xa802, 0xa86a, 0xa88a, 0x2d18, 0xab8e, 0xa887, 0x0045, 0x2c00,
+	0xa892, 0x6038, 0xa8a2, 0x2360, 0x6024, 0xc0dd, 0x6026, 0x6010,
+	0x00b6, 0x2058, 0xb8a0, 0x00be, 0x2004, 0x635c, 0xab7a, 0xa876,
+	0x9006, 0xa87e, 0xa882, 0xad9a, 0xae96, 0xa89f, 0x0001, 0x080c,
+	0x6f19, 0x2019, 0x0045, 0x6008, 0x2068, 0x080c, 0xe27a, 0x2d00,
+	0x600a, 0x6023, 0x0006, 0x6003, 0x0007, 0x901e, 0x631a, 0x634a,
+	0x003e, 0x0038, 0x604b, 0x0000, 0x6003, 0x0007, 0x080c, 0xe0b7,
+	0x00ce, 0x00de, 0x009e, 0x0005, 0x9186, 0x0013, 0x1128, 0x6004,
+	0x9082, 0x0085, 0x2008, 0x00c2, 0x9186, 0x0027, 0x1178, 0x080c,
+	0x97fe, 0x0036, 0x0096, 0x6014, 0x2048, 0x2019, 0x0004, 0x080c,
+	0xe6cd, 0x009e, 0x003e, 0x080c, 0x98bf, 0x0005, 0x9186, 0x0014,
+	0x0d70, 0x080c, 0xafe9, 0x0005, 0xe8e3, 0xe8e1, 0xe8e1, 0xe8e1,
+	0xe8e1, 0xe8e1, 0xe8e3, 0xe8e1, 0xe8e1, 0xe8e1, 0xe8e1, 0xe8e1,
+	0xe8e1, 0x080c, 0x0d85, 0x6003, 0x000c, 0x080c, 0x98bf, 0x0005,
+	0x9182, 0x0092, 0x1220, 0x9182, 0x0085, 0x0208, 0x001a, 0x080c,
+	0xafe9, 0x0005, 0xe8ff, 0xe8ff, 0xe8ff, 0xe8ff, 0xe901, 0xe921,
+	0xe8ff, 0xe8ff, 0xe8ff, 0xe8ff, 0xe8ff, 0xe8ff, 0xe8ff, 0x080c,
+	0x0d85, 0x00d6, 0x2c68, 0x080c, 0xaed8, 0x01b0, 0x6003, 0x0001,
+	0x6007, 0x001e, 0x2009, 0x026e, 0x210c, 0x613a, 0x2009, 0x026f,
+	0x210c, 0x613e, 0x600b, 0xffff, 0x6910, 0x6112, 0x6023, 0x0004,
+	0x2009, 0x8020, 0x080c, 0x9428, 0x2d60, 0x080c, 0xaf2e, 0x00de,
+	0x0005, 0x080c, 0xaf2e, 0x0005, 0x00e6, 0x6010, 0x00b6, 0x2058,
+	0xb800, 0x00be, 0xd0ec, 0x00ee, 0x0005, 0x2009, 0x1867, 0x210c,
+	0xd1ec, 0x05b0, 0x6003, 0x0002, 0x6024, 0xc0e5, 0x6026, 0xd0cc,
+	0x0150, 0x2001, 0x1989, 0x2004, 0x604a, 0x2009, 0x1867, 0x210c,
+	0xd1f4, 0x1520, 0x00a0, 0x2009, 0x1867, 0x210c, 0xd1f4, 0x0128,
+	0x6024, 0xc0e4, 0x6026, 0x9006, 0x00d8, 0x2001, 0x1989, 0x200c,
+	0x2001, 0x1987, 0x2004, 0x9100, 0x9080, 0x000a, 0x604a, 0x6010,
+	0x00b6, 0x2058, 0xb8bc, 0x00be, 0x0008, 0x2104, 0x9005, 0x0118,
+	0x9088, 0x0003, 0x0cd0, 0x2c0a, 0x600f, 0x0000, 0x9085, 0x0001,
+	0x0005, 0x0016, 0x00c6, 0x00e6, 0x615c, 0xb8bc, 0x2060, 0x8cff,
+	0x0180, 0x84ff, 0x1118, 0x605c, 0x9106, 0x1138, 0x600c, 0x2072,
+	0x080c, 0x8aba, 0x080c, 0xaf2e, 0x0010, 0x9cf0, 0x0003, 0x2e64,
+	0x0c70, 0x00ee, 0x00ce, 0x001e, 0x0005, 0x00d6, 0x00b6, 0x6010,
+	0x2058, 0xb8bc, 0x906d, 0x0130, 0x9c06, 0x0110, 0x680c, 0x0cd0,
+	0x600c, 0x680e, 0x00be, 0x00de, 0x0005, 0x0026, 0x0036, 0x0156,
+	0x2011, 0x182c, 0x2204, 0x9084, 0x00ff, 0x2019, 0x026e, 0x2334,
+	0x96b4, 0x00ff, 0x9636, 0x1508, 0x8318, 0x2334, 0x2204, 0x9084,
+	0xff00, 0x9636, 0x11d0, 0x2011, 0x0270, 0x20a9, 0x0004, 0x6010,
+	0x0096, 0x2048, 0x2019, 0x000a, 0x080c, 0xbf3e, 0x009e, 0x1168,
+	0x2011, 0x0274, 0x20a9, 0x0004, 0x6010, 0x0096, 0x2048, 0x2019,
+	0x0006, 0x080c, 0xbf3e, 0x009e, 0x1100, 0x015e, 0x003e, 0x002e,
+	0x0005, 0x00e6, 0x2071, 0x1800, 0x080c, 0x6111, 0x080c, 0x30e1,
+	0x00ee, 0x0005, 0x0096, 0x0026, 0x080c, 0x1059, 0x090c, 0x0d85,
+	0xa85c, 0x9080, 0x001a, 0x20a0, 0x20a9, 0x000c, 0xa860, 0x20e8,
+	0x9006, 0x4004, 0x9186, 0x0046, 0x1118, 0xa867, 0x0136, 0x0038,
+	0xa867, 0x0138, 0x9186, 0x0041, 0x0110, 0xa87b, 0x0001, 0x7038,
+	0x9084, 0xff00, 0x7240, 0x9294, 0xff00, 0x8007, 0x9215, 0xaa9a,
+	0x9186, 0x0046, 0x1168, 0x7038, 0x9084, 0x00ff, 0x723c, 0x9294,
+	0xff00, 0x9215, 0xaa9e, 0x723c, 0x9294, 0x00ff, 0xaaa2, 0x0060,
+	0x7040, 0x9084, 0x00ff, 0x7244, 0x9294, 0xff00, 0x9215, 0xaa9e,
+	0x7244, 0x9294, 0x00ff, 0xaaa2, 0x9186, 0x0046, 0x1118, 0x9e90,
+	0x0012, 0x0010, 0x9e90, 0x001a, 0x2204, 0x8007, 0xa8a6, 0x8210,
+	0x2204, 0x8007, 0xa8aa, 0x8210, 0x2204, 0x8007, 0xa8ae, 0x8210,
+	0x2204, 0x8007, 0xa8b2, 0x8210, 0x9186, 0x0046, 0x11b8, 0x9e90,
+	0x0016, 0x2204, 0x8007, 0xa8b6, 0x8210, 0x2204, 0x8007, 0xa8ba,
+	0x8210, 0x2204, 0x8007, 0xa8be, 0x8210, 0x2204, 0x8007, 0xa8c2,
+	0x8210, 0x2011, 0x0205, 0x2013, 0x0001, 0x00b0, 0x9e90, 0x001e,
+	0x2204, 0x8007, 0xa8b6, 0x8210, 0x2204, 0x8007, 0xa8ba, 0x2011,
+	0x0205, 0x2013, 0x0001, 0x2011, 0x0260, 0x2204, 0x8007, 0xa8be,
+	0x8210, 0x2204, 0x8007, 0xa8c2, 0x9186, 0x0046, 0x1118, 0x2011,
+	0x0262, 0x0010, 0x2011, 0x026a, 0x0146, 0x01d6, 0x0036, 0x20a9,
+	0x0001, 0x2019, 0x0008, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0031,
+	0x20a0, 0x2204, 0x8007, 0x4004, 0x8210, 0x8319, 0x1dd0, 0x003e,
+	0x01ce, 0x013e, 0x2011, 0x0205, 0x2013, 0x0000, 0x002e, 0x080c,
+	0x6f19, 0x009e, 0x0005, 0x00e6, 0x6010, 0x00b6, 0x2058, 0xb800,
+	0x00be, 0xd0fc, 0x0108, 0x0011, 0x00ee, 0x0005, 0xa880, 0xc0e5,
+	0xa882, 0x0005, 0x00e6, 0x00d6, 0x00c6, 0x0076, 0x0066, 0x0056,
+	0x0046, 0x0026, 0x0016, 0x0126, 0x2091, 0x8000, 0x2029, 0x19f5,
+	0x252c, 0x2021, 0x19fc, 0x2424, 0x2061, 0x1ddc, 0x2071, 0x1800,
+	0x7654, 0x7074, 0x9606, 0x0578, 0x6720, 0x9786, 0x0001, 0x0118,
+	0x9786, 0x0008, 0x1500, 0x2500, 0x9c06, 0x01e8, 0x2400, 0x9c06,
+	0x01d0, 0x080c, 0xe75b, 0x01b8, 0x080c, 0xe76b, 0x11a0, 0x6000,
+	0x9086, 0x0004, 0x1120, 0x0016, 0x080c, 0x1afc, 0x001e, 0x080c,
+	0xce1c, 0x1110, 0x080c, 0x333f, 0x080c, 0xce2d, 0x1110, 0x080c,
+	0xb91f, 0x080c, 0xaf69, 0x9ce0, 0x001c, 0x2001, 0x181a, 0x2004,
+	0x9c02, 0x1208, 0x0858, 0x012e, 0x001e, 0x002e, 0x004e, 0x005e,
+	0x006e, 0x007e, 0x00ce, 0x00de, 0x00ee, 0x0005, 0x2001, 0x1810,
+	0x2004, 0xd0dc, 0x0005, 0x0006, 0x2001, 0x1837, 0x2004, 0xd09c,
+	0x000e, 0x0005, 0x0006, 0x0036, 0x0046, 0x080c, 0xd33e, 0x0168,
+	0x2019, 0xffff, 0x9005, 0x0128, 0x6010, 0x00b6, 0x2058, 0xbba0,
+	0x00be, 0x2021, 0x0004, 0x080c, 0x4de5, 0x004e, 0x003e, 0x000e,
+	0x0005, 0x6004, 0x9086, 0x0001, 0x1128, 0x080c, 0xa5c6, 0x080c,
+	0xaf69, 0x9006, 0x0005, 0x00e6, 0x00c6, 0x00b6, 0x0046, 0x2061,
+	0x1ddc, 0x2071, 0x1800, 0x7454, 0x7074, 0x8001, 0x9402, 0x12d8,
+	0x2100, 0x9c06, 0x0168, 0x6000, 0x9086, 0x0000, 0x0148, 0x6010,
+	0x2058, 0xb8a0, 0x9206, 0x1120, 0x6004, 0x9086, 0x0002, 0x0140,
+	0x9ce0, 0x001c, 0x2001, 0x181a, 0x2004, 0x9c02, 0x1220, 0x0c40,
+	0x9085, 0x0001, 0x0008, 0x9006, 0x004e, 0x00be, 0x00ce, 0x00ee,
+	0x0005, 0x2001, 0x1810, 0x2004, 0xd0a4, 0x0160, 0x2001, 0x1837,
+	0x2004, 0xd0a4, 0x0138, 0x2001, 0x1848, 0x2004, 0xd0a4, 0x1118,
+	0x9085, 0x0001, 0x0005, 0x9006, 0x0ce8, 0x0126, 0x0006, 0x00e6,
+	0x0016, 0x2091, 0x8000, 0x2071, 0x1840, 0xd5a4, 0x0118, 0x7004,
+	0x8000, 0x7006, 0xd5b4, 0x0118, 0x7000, 0x8000, 0x7002, 0xd5ac,
+	0x0178, 0x2500, 0x9084, 0x0007, 0x908e, 0x0003, 0x0148, 0x908e,
+	0x0004, 0x0130, 0x908e, 0x0005, 0x0118, 0x2071, 0xfff6, 0x0089,
+	0x001e, 0x00ee, 0x000e, 0x012e, 0x0005, 0x0126, 0x0006, 0x00e6,
+	0x2091, 0x8000, 0x2071, 0xffee, 0x0021, 0x00ee, 0x000e, 0x012e,
+	0x0005, 0x2e05, 0x8000, 0x2077, 0x1220, 0x8e70, 0x2e05, 0x8000,
+	0x2077, 0x0005, 0x00e6, 0x2071, 0xffec, 0x0c99, 0x00ee, 0x0005,
+	0x00e6, 0x2071, 0xfff0, 0x0c69, 0x00ee, 0x0005, 0x0126, 0x0006,
+	0x00e6, 0x2091, 0x8000, 0x2071, 0x1840, 0x7014, 0x8000, 0x7016,
+	0x00ee, 0x000e, 0x012e, 0x0005, 0x0001, 0x0002, 0x0004, 0x0008,
+	0x0010, 0x0020, 0x0040, 0x0080, 0x0100, 0x0200, 0x0400, 0x0800,
+	0x1000, 0x2000, 0x4000, 0x8000, 0x77f3
 };
 #ifdef UNIQUE_FW_NAME
-unsigned short fw2322ipx_length01 = 0xe0c2;
+unsigned short fw2322ipx_length01 = 0xe3bd;
 #else
-unsigned short risc_code_length01 = 0xe0c2;
+unsigned short risc_code_length01 = 0xe3bd;
 #endif
 
 /*
@@ -7256,334 +7351,341 @@ unsigned short risc_code_length01 = 0xe0
 
 unsigned long rseqipx_code_addr01 = 0x0001c000 ;
 unsigned short rseqipx_code01[] = { 
-0x000b, 0x0003, 0x0000, 0x09e6, 0x0001, 0xc000, 0x0008, 0x8064,
+0x000b, 0x0003, 0x0000, 0x0a20, 0x0001, 0xc000, 0x0008, 0x8064,
 	0x0000, 0x0010, 0x0000, 0x8066, 0x0008, 0x0101, 0x0003, 0xc007,
 	0x0008, 0x80e0, 0x0008, 0xff00, 0x0000, 0x80e2, 0x0008, 0xff00,
 	0x0008, 0x0162, 0x0000, 0x8066, 0x0008, 0xa101, 0x000b, 0xc00f,
-	0x0008, 0x0d02, 0x0000, 0x8060, 0x0000, 0x0400, 0x0003, 0x60c2,
-	0x0003, 0x5817, 0x000b, 0x7ae3, 0x000b, 0x521c, 0x000b, 0xc813,
-	0x0009, 0xbac0, 0x0000, 0x008a, 0x0003, 0x8813, 0x0000, 0x15fc,
+	0x0008, 0x0d02, 0x0000, 0x8060, 0x0000, 0x0400, 0x000b, 0x60c6,
+	0x0008, 0x80e0, 0x0000, 0x0100, 0x000b, 0x5819, 0x0003, 0x7af3,
+	0x000b, 0x522c, 0x000b, 0xc813, 0x0009, 0xbac0, 0x0000, 0x008a,
+	0x0003, 0x8813, 0x000a, 0x7042, 0x0003, 0x8813, 0x0000, 0x15fc,
 	0x000b, 0xb013, 0x0009, 0xc4c0, 0x0000, 0x7000, 0x0001, 0xffa0,
-	0x0000, 0x2000, 0x0003, 0x939b, 0x0008, 0x808c, 0x0000, 0x0001,
+	0x0000, 0x2000, 0x000b, 0x93b8, 0x0008, 0x808c, 0x0000, 0x0001,
 	0x0007, 0x0000, 0x0007, 0x0000, 0x0000, 0x40d4, 0x000a, 0x4047,
-	0x0008, 0x808c, 0x0000, 0x0002, 0x0007, 0x0000, 0x0003, 0x082e,
-	0x0000, 0x4022, 0x0003, 0x0034, 0x0008, 0x4122, 0x0009, 0xeac0,
-	0x0008, 0xff00, 0x0009, 0xffe0, 0x0008, 0x0500, 0x000b, 0x0bc2,
-	0x0002, 0x4447, 0x0003, 0x8bbf, 0x0008, 0x0bfe, 0x0001, 0x11a0,
-	0x000b, 0x13a1, 0x0001, 0x0ca0, 0x000b, 0x13a1, 0x0001, 0x9180,
+	0x0008, 0x808c, 0x0000, 0x0002, 0x0007, 0x0000, 0x000b, 0x0832,
+	0x0000, 0x4022, 0x0003, 0x0038, 0x0008, 0x4122, 0x0009, 0xeac0,
+	0x0008, 0xff00, 0x0009, 0xffe0, 0x0008, 0x0500, 0x000b, 0x0bdf,
+	0x0002, 0x4447, 0x0003, 0x8bdc, 0x0008, 0x0bfe, 0x0001, 0x11a0,
+	0x0003, 0x13be, 0x0001, 0x0ca0, 0x0003, 0x13be, 0x0001, 0x9180,
 	0x0000, 0x0004, 0x0000, 0x8060, 0x0000, 0x0400, 0x0008, 0x7f62,
-	0x0000, 0x8066, 0x0008, 0x0009, 0x000b, 0xc042, 0x0008, 0x808c,
+	0x0000, 0x8066, 0x0008, 0x0009, 0x0003, 0xc046, 0x0008, 0x808c,
 	0x0008, 0x0000, 0x0008, 0x0060, 0x0008, 0x8062, 0x0000, 0x0004,
-	0x0000, 0x8066, 0x0000, 0x0411, 0x0003, 0xc04a, 0x0000, 0x03fe,
-	0x0001, 0x43e0, 0x0003, 0x8b9e, 0x0009, 0xc2c0, 0x0008, 0x00ff,
-	0x0001, 0x02e0, 0x0003, 0x8b9e, 0x0001, 0x9180, 0x0008, 0x0005,
+	0x0000, 0x8066, 0x0000, 0x0411, 0x000b, 0xc04e, 0x0000, 0x03fe,
+	0x0001, 0x43e0, 0x000b, 0x8bbb, 0x0009, 0xc2c0, 0x0008, 0x00ff,
+	0x0001, 0x02e0, 0x000b, 0x8bbb, 0x0001, 0x9180, 0x0008, 0x0005,
 	0x0000, 0x8060, 0x0000, 0x0400, 0x0008, 0x7f62, 0x0000, 0x8066,
-	0x0000, 0x0019, 0x000b, 0xc059, 0x0002, 0x0240, 0x000b, 0x0b9b,
-	0x0008, 0x00fc, 0x0003, 0x339e, 0x000a, 0x0244, 0x000b, 0x086b,
-	0x000c, 0x01f5, 0x0001, 0x9180, 0x0000, 0x0007, 0x0008, 0x7f62,
+	0x0000, 0x0019, 0x0003, 0xc05d, 0x0002, 0x0240, 0x0003, 0x0bb8,
+	0x0008, 0x00fc, 0x000b, 0x33bb, 0x000a, 0x0244, 0x0003, 0x086f,
+	0x000c, 0x0205, 0x0001, 0x9180, 0x0000, 0x0007, 0x0008, 0x7f62,
 	0x0000, 0x8060, 0x0000, 0x0400, 0x0002, 0x0234, 0x0008, 0x7f04,
-	0x0000, 0x8066, 0x0000, 0x040a, 0x000b, 0xc06a, 0x000a, 0x0248,
-	0x000b, 0x0875, 0x0001, 0x9180, 0x0008, 0x0006, 0x0008, 0x7f62,
+	0x0000, 0x8066, 0x0000, 0x040a, 0x0003, 0xc06e, 0x000a, 0x0248,
+	0x000b, 0x0879, 0x0001, 0x9180, 0x0008, 0x0006, 0x0008, 0x7f62,
 	0x0008, 0x8002, 0x0008, 0x0003, 0x0000, 0x8066, 0x0000, 0x020a,
-	0x000b, 0xc074, 0x0000, 0x112a, 0x0008, 0x002e, 0x0008, 0x022c,
+	0x000b, 0xc078, 0x0000, 0x112a, 0x0008, 0x002e, 0x0008, 0x022c,
 	0x0002, 0x3a44, 0x0003, 0x8813, 0x0008, 0x808c, 0x0000, 0x0002,
 	0x0008, 0x1760, 0x0008, 0x8062, 0x0008, 0x000f, 0x0000, 0x8066,
-	0x0008, 0x0011, 0x000b, 0xc081, 0x0008, 0x01fe, 0x0009, 0x42e0,
-	0x000b, 0x8b8e, 0x0000, 0x00fe, 0x0001, 0x43e0, 0x000b, 0x8b8e,
+	0x0008, 0x0011, 0x0003, 0xc085, 0x0008, 0x01fe, 0x0009, 0x42e0,
+	0x0003, 0x8bab, 0x0000, 0x00fe, 0x0001, 0x43e0, 0x0003, 0x8bab,
 	0x0000, 0x1734, 0x0000, 0x1530, 0x0008, 0x1632, 0x0008, 0x0d2a,
 	0x0001, 0x9880, 0x0008, 0x0012, 0x0000, 0x8060, 0x0000, 0x0400,
-	0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x1e0a, 0x000b, 0xc093,
+	0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x1e0a, 0x0003, 0xc097,
 	0x0008, 0x808a, 0x0008, 0x0003, 0x0000, 0x1a60, 0x0008, 0x8062,
-	0x0000, 0x0002, 0x0003, 0x5899, 0x0000, 0x8066, 0x0000, 0x3679,
-	0x000b, 0xc09c, 0x000b, 0x589d, 0x0008, 0x8054, 0x0008, 0x0011,
+	0x0000, 0x0002, 0x000b, 0x589d, 0x0000, 0x8066, 0x0000, 0x3679,
+	0x000b, 0xc0a0, 0x000b, 0x58a1, 0x0008, 0x8054, 0x0008, 0x0011,
 	0x0000, 0x8074, 0x0008, 0x1010, 0x0008, 0x1efc, 0x0003, 0x3013,
-	0x0004, 0x00a6, 0x0003, 0x0013, 0x0000, 0x1c60, 0x0000, 0x1b62,
-	0x0000, 0x8066, 0x0008, 0x0231, 0x000b, 0xc0aa, 0x000b, 0x58ab,
-	0x0008, 0x0140, 0x0000, 0x0242, 0x0002, 0x1f43, 0x0003, 0x88b5,
+	0x0004, 0x00aa, 0x0003, 0x0013, 0x0000, 0x1c60, 0x0000, 0x1b62,
+	0x0000, 0x8066, 0x0008, 0x0231, 0x0003, 0xc0ae, 0x0003, 0x58af,
+	0x0008, 0x0140, 0x0000, 0x0242, 0x0002, 0x1f43, 0x0003, 0x88b9,
 	0x0000, 0x0d44, 0x0008, 0x0d46, 0x0008, 0x0348, 0x0008, 0x044a,
-	0x0003, 0x00b9, 0x0008, 0x0344, 0x0008, 0x0446, 0x0008, 0x0548,
-	0x0000, 0x064a, 0x000a, 0x1948, 0x000b, 0x08bc, 0x0008, 0x0d4a,
-	0x000b, 0x58bc, 0x0008, 0x8054, 0x0000, 0x0001, 0x0000, 0x8074,
-	0x0008, 0x2020, 0x000f, 0x4000, 0x0000, 0x4820, 0x0008, 0x0bfe,
-	0x0009, 0x10a0, 0x0003, 0x1123, 0x0001, 0x0ca0, 0x0003, 0x1123,
+	0x000b, 0x00bd, 0x0008, 0x0344, 0x0008, 0x0446, 0x0008, 0x0548,
+	0x0000, 0x064a, 0x000a, 0x1948, 0x0003, 0x08c0, 0x0008, 0x0d4a,
+	0x0003, 0x58c0, 0x0008, 0x8054, 0x0000, 0x0001, 0x0000, 0x8074,
+	0x0008, 0x2020, 0x000f, 0x4000, 0x0002, 0x7043, 0x0003, 0x8816,
+	0x0002, 0x7040, 0x000b, 0x8934, 0x0000, 0x4820, 0x0008, 0x0bfe,
+	0x0009, 0x10a0, 0x000b, 0x112b, 0x0001, 0x0ca0, 0x000b, 0x112b,
 	0x0000, 0x8060, 0x0000, 0x0400, 0x0009, 0x9080, 0x0000, 0x0008,
-	0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x0009, 0x000b, 0xc0cf,
-	0x0001, 0x80e0, 0x0008, 0x0003, 0x000b, 0x8923, 0x0000, 0x49b4,
-	0x0002, 0x4b4e, 0x000b, 0x892c, 0x0008, 0x808a, 0x0000, 0x0004,
-	0x0000, 0x18fe, 0x0001, 0x10e0, 0x000b, 0x88dd, 0x0002, 0x192f,
-	0x0008, 0x7f32, 0x0008, 0x15fe, 0x0001, 0x10e0, 0x000b, 0x88e2,
+	0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x0009, 0x000b, 0xc0d7,
+	0x0001, 0x80e0, 0x0008, 0x0003, 0x0003, 0x892b, 0x0000, 0x49b4,
+	0x0002, 0x4b4e, 0x0003, 0x893c, 0x0008, 0x808a, 0x0000, 0x0004,
+	0x0000, 0x18fe, 0x0001, 0x10e0, 0x0003, 0x88e5, 0x0002, 0x192f,
+	0x0008, 0x7f32, 0x0008, 0x15fe, 0x0001, 0x10e0, 0x0003, 0x88ea,
 	0x0002, 0x162f, 0x0008, 0x7f2c, 0x0000, 0x8060, 0x0000, 0x0400,
 	0x0009, 0x9080, 0x0000, 0x0007, 0x0008, 0x7f62, 0x0000, 0x8066,
-	0x0008, 0x0009, 0x0003, 0xc0e9, 0x000a, 0x004f, 0x000b, 0x891a,
-	0x000a, 0x0040, 0x0003, 0x0904, 0x0002, 0x004e, 0x0003, 0x0904,
+	0x0008, 0x0009, 0x0003, 0xc0f1, 0x000a, 0x004f, 0x0003, 0x8922,
+	0x000a, 0x0040, 0x000b, 0x090c, 0x0002, 0x004e, 0x000b, 0x090c,
 	0x0002, 0x0030, 0x0002, 0x7f2f, 0x0000, 0x7f00, 0x0000, 0x8066,
-	0x0008, 0x000a, 0x000b, 0xc0f5, 0x0008, 0x1010, 0x0004, 0x01dc,
-	0x000b, 0xb0fd, 0x000c, 0x0362, 0x000c, 0x01c6, 0x000b, 0x7814,
+	0x0008, 0x000a, 0x0003, 0xc0fd, 0x0008, 0x1010, 0x0004, 0x01ec,
+	0x000b, 0xb105, 0x0004, 0x0372, 0x0004, 0x01d6, 0x0003, 0x7816,
 	0x0003, 0x0013, 0x0000, 0x0806, 0x0008, 0x8010, 0x0000, 0x001f,
-	0x000c, 0x0362, 0x0000, 0x0310, 0x000c, 0x0362, 0x0003, 0x00fb,
+	0x0004, 0x0372, 0x0000, 0x0310, 0x0004, 0x0372, 0x0003, 0x0103,
 	0x000a, 0x002f, 0x0000, 0x7f00, 0x0000, 0x8066, 0x0008, 0x000a,
-	0x000b, 0xc108, 0x000c, 0x019f, 0x000a, 0x0040, 0x000b, 0x091d,
-	0x000c, 0x020c, 0x0000, 0x8000, 0x0000, 0x0002, 0x0000, 0x8060,
+	0x000b, 0xc110, 0x000c, 0x01af, 0x000a, 0x0040, 0x0003, 0x0925,
+	0x0004, 0x021c, 0x0000, 0x8000, 0x0000, 0x0002, 0x0000, 0x8060,
 	0x0000, 0x0400, 0x0009, 0x9080, 0x0008, 0x0006, 0x0008, 0x7f62,
-	0x0000, 0x8066, 0x0008, 0x000a, 0x000b, 0xc116, 0x0000, 0x8072,
-	0x0000, 0x4000, 0x0003, 0x00fb, 0x0008, 0x8010, 0x0008, 0x001e,
-	0x000b, 0x011f, 0x0008, 0x8010, 0x0008, 0x001d, 0x000c, 0x0362,
-	0x0008, 0x1010, 0x000c, 0x0362, 0x000b, 0x0014, 0x0002, 0x4b4e,
-	0x0003, 0x0929, 0x0008, 0x808a, 0x0000, 0x0004, 0x000b, 0x6129,
-	0x000f, 0x8000, 0x0008, 0x808a, 0x0000, 0x0004, 0x000b, 0x0014,
+	0x0000, 0x8066, 0x0008, 0x000a, 0x0003, 0xc11e, 0x0000, 0x8072,
+	0x0000, 0x4000, 0x0003, 0x0103, 0x0008, 0x8010, 0x0008, 0x001e,
+	0x0003, 0x0127, 0x0008, 0x8010, 0x0008, 0x001d, 0x0004, 0x0372,
+	0x0008, 0x1010, 0x0004, 0x0372, 0x0003, 0x0016, 0x0002, 0x4b4e,
+	0x0003, 0x0931, 0x0008, 0x808a, 0x0000, 0x0004, 0x000b, 0x6131,
+	0x000f, 0x8000, 0x0008, 0x808a, 0x0000, 0x0004, 0x0003, 0x0016,
+	0x0008, 0x808a, 0x0000, 0x0004, 0x0007, 0x0000, 0x0007, 0x0000,
+	0x0008, 0x80e0, 0x0008, 0x0202, 0x000b, 0x6134, 0x000b, 0x0014,
 	0x0000, 0x8060, 0x0000, 0x0400, 0x0009, 0x9080, 0x0008, 0x0011,
-	0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x0009, 0x0003, 0xc133,
-	0x000a, 0x004f, 0x0003, 0x8990, 0x0000, 0x8060, 0x0000, 0x0400,
+	0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x0009, 0x000b, 0xc143,
+	0x000a, 0x004f, 0x0003, 0x89a0, 0x0000, 0x8060, 0x0000, 0x0400,
 	0x0009, 0x9080, 0x0008, 0x0005, 0x0008, 0x7f62, 0x0000, 0x8066,
-	0x0008, 0x0009, 0x000b, 0xc13d, 0x0008, 0x0060, 0x0008, 0x8062,
-	0x0000, 0x001f, 0x0000, 0x8066, 0x0000, 0x0209, 0x000b, 0xc143,
-	0x000a, 0x014b, 0x000b, 0x0990, 0x0008, 0x8062, 0x0008, 0x000f,
-	0x0000, 0x8066, 0x0000, 0x0211, 0x000b, 0xc14a, 0x0008, 0x01fe,
-	0x0001, 0x02d0, 0x0003, 0x8990, 0x0004, 0x01a8, 0x000b, 0x0990,
+	0x0008, 0x0009, 0x0003, 0xc14d, 0x0008, 0x0060, 0x0008, 0x8062,
+	0x0000, 0x001f, 0x0000, 0x8066, 0x0000, 0x0209, 0x0003, 0xc153,
+	0x000a, 0x014b, 0x000b, 0x09a0, 0x0008, 0x8062, 0x0008, 0x000f,
+	0x0000, 0x8066, 0x0000, 0x0211, 0x0003, 0xc15a, 0x0008, 0x01fe,
+	0x0001, 0x02d0, 0x0003, 0x89a0, 0x000c, 0x01b8, 0x000b, 0x09a0,
 	0x0008, 0x03a0, 0x0008, 0x8004, 0x0000, 0x0002, 0x0000, 0x8006,
 	0x0000, 0x0043, 0x0008, 0x4908, 0x0008, 0x808a, 0x0000, 0x0004,
 	0x0000, 0x8060, 0x0000, 0x0400, 0x0009, 0x9080, 0x0008, 0x0000,
-	0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x041a, 0x0003, 0xc15f,
-	0x000b, 0xe160, 0x0008, 0x4908, 0x0008, 0x480a, 0x0008, 0x808a,
+	0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x041a, 0x0003, 0xc16f,
+	0x0003, 0xe170, 0x0008, 0x4908, 0x0008, 0x480a, 0x0008, 0x808a,
 	0x0000, 0x0004, 0x0008, 0x0060, 0x0008, 0x8062, 0x0008, 0x002b,
-	0x0000, 0x8066, 0x0000, 0x0411, 0x0003, 0xc16a, 0x0008, 0x04fe,
-	0x0009, 0x02a0, 0x0003, 0x9171, 0x0002, 0x0500, 0x000b, 0x098d,
-	0x0003, 0x0172, 0x0000, 0x05fe, 0x0001, 0x03a0, 0x000b, 0x118d,
+	0x0000, 0x8066, 0x0000, 0x0411, 0x000b, 0xc17a, 0x0008, 0x04fe,
+	0x0009, 0x02a0, 0x0003, 0x9181, 0x0002, 0x0500, 0x0003, 0x099d,
+	0x0003, 0x0182, 0x0000, 0x05fe, 0x0001, 0x03a0, 0x0003, 0x119d,
 	0x0000, 0x0d0c, 0x0008, 0x0d0e, 0x0008, 0x0d10, 0x0000, 0x0d12,
 	0x0008, 0x0060, 0x0008, 0x8062, 0x0000, 0x000d, 0x0000, 0x8066,
-	0x0008, 0x0832, 0x0003, 0xc17d, 0x0000, 0x800a, 0x0000, 0x8005,
+	0x0008, 0x0832, 0x0003, 0xc18d, 0x0000, 0x800a, 0x0000, 0x8005,
 	0x0000, 0x8060, 0x0000, 0x0400, 0x0009, 0x9080, 0x0008, 0x0011,
-	0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x0a12, 0x0003, 0xc187,
-	0x0008, 0x5006, 0x0008, 0x100e, 0x0004, 0x01b3, 0x000b, 0x7814,
-	0x0003, 0x0013, 0x0008, 0x0208, 0x0008, 0x030a, 0x0003, 0x0174,
-	0x000c, 0x019f, 0x0008, 0x808a, 0x0000, 0x0004, 0x0008, 0x8010,
-	0x0008, 0x0021, 0x000c, 0x0362, 0x0008, 0x1010, 0x000c, 0x0362,
-	0x0000, 0x4810, 0x000c, 0x0362, 0x0008, 0x4910, 0x000c, 0x0362,
-	0x0008, 0x808a, 0x0000, 0x0004, 0x000b, 0x0014, 0x0000, 0x8060,
+	0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x0a12, 0x000b, 0xc197,
+	0x0008, 0x5006, 0x0008, 0x100e, 0x000c, 0x01c3, 0x0003, 0x7816,
+	0x0003, 0x0013, 0x0008, 0x0208, 0x0008, 0x030a, 0x0003, 0x0184,
+	0x000c, 0x01af, 0x0008, 0x808a, 0x0000, 0x0004, 0x0008, 0x8010,
+	0x0008, 0x0021, 0x0004, 0x0372, 0x0008, 0x1010, 0x0004, 0x0372,
+	0x0000, 0x4810, 0x0004, 0x0372, 0x0008, 0x4910, 0x0004, 0x0372,
+	0x0008, 0x808a, 0x0000, 0x0004, 0x0003, 0x0016, 0x0000, 0x8060,
 	0x0000, 0x0400, 0x0009, 0x9080, 0x0000, 0x0002, 0x0008, 0x7f62,
-	0x0000, 0x8066, 0x0008, 0xb40a, 0x0003, 0xc1a6, 0x000f, 0x4000,
+	0x0000, 0x8066, 0x0008, 0xb40a, 0x000b, 0xc1b6, 0x000f, 0x4000,
 	0x0000, 0x8060, 0x0000, 0x0400, 0x0000, 0x0a62, 0x0000, 0x8066,
-	0x0000, 0x0411, 0x000b, 0xc1ad, 0x0002, 0x0210, 0x0001, 0xffc0,
+	0x0000, 0x0411, 0x0003, 0xc1bd, 0x0002, 0x0210, 0x0001, 0xffc0,
 	0x0000, 0x0007, 0x0009, 0x03e0, 0x000f, 0x4000, 0x0000, 0x8060,
 	0x0000, 0x0400, 0x0001, 0x8380, 0x0000, 0x0002, 0x0009, 0x0a80,
-	0x0008, 0x7f62, 0x0000, 0x8066, 0x0000, 0x0e0a, 0x0003, 0xc1bb,
+	0x0008, 0x7f62, 0x0000, 0x8066, 0x0000, 0x0e0a, 0x000b, 0xc1cb,
 	0x0002, 0x0300, 0x0001, 0xffc0, 0x0000, 0x0007, 0x0000, 0x7f06,
 	0x0002, 0x0a00, 0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x060a,
-	0x000b, 0xc1c4, 0x000f, 0x4000, 0x0000, 0x0da0, 0x0008, 0x0da2,
+	0x0003, 0xc1d4, 0x000f, 0x4000, 0x0000, 0x0da0, 0x0008, 0x0da2,
 	0x0008, 0x0da4, 0x0009, 0x8880, 0x0000, 0x0001, 0x0008, 0x7f62,
 	0x0000, 0x8060, 0x0000, 0x0400, 0x0000, 0x8066, 0x0008, 0xa012,
 	0x0000, 0x0da6, 0x0008, 0x0da8, 0x0000, 0x0daa, 0x0000, 0x0dac,
-	0x0003, 0xc1d4, 0x0009, 0x8880, 0x0008, 0x0009, 0x0008, 0x7f62,
-	0x0000, 0x8066, 0x0008, 0xa03a, 0x000b, 0xc1da, 0x000f, 0x4000,
+	0x0003, 0xc1e4, 0x0009, 0x8880, 0x0008, 0x0009, 0x0008, 0x7f62,
+	0x0000, 0x8066, 0x0008, 0xa03a, 0x000b, 0xc1ea, 0x000f, 0x4000,
 	0x0009, 0x8880, 0x0008, 0x0005, 0x0000, 0x8060, 0x0000, 0x0400,
-	0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x0009, 0x000b, 0xc1e3,
+	0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x0009, 0x0003, 0xc1f3,
 	0x0008, 0x0060, 0x0008, 0x8062, 0x0000, 0x000d, 0x0000, 0x8066,
-	0x0008, 0x0021, 0x000b, 0xc1e9, 0x0000, 0x00fe, 0x0001, 0x01d0,
-	0x000b, 0x89f2, 0x0008, 0x02fe, 0x0009, 0x03d0, 0x0003, 0x09f2,
+	0x0008, 0x0021, 0x0003, 0xc1f9, 0x0000, 0x00fe, 0x0001, 0x01d0,
+	0x000b, 0x8a02, 0x0008, 0x02fe, 0x0009, 0x03d0, 0x0003, 0x0a02,
 	0x0000, 0x0d06, 0x000f, 0x4000, 0x0000, 0x8006, 0x0000, 0x0001,
 	0x000f, 0x4000, 0x0008, 0x0060, 0x0008, 0x8062, 0x0008, 0x002b,
-	0x0000, 0x8066, 0x0008, 0xa041, 0x0003, 0xc1fa, 0x0002, 0x0243,
-	0x000b, 0x8a01, 0x0000, 0x54ac, 0x0000, 0x55ae, 0x0008, 0x0da8,
+	0x0000, 0x8066, 0x0008, 0xa041, 0x0003, 0xc20a, 0x0002, 0x0243,
+	0x0003, 0x8a11, 0x0000, 0x54ac, 0x0000, 0x55ae, 0x0008, 0x0da8,
 	0x0000, 0x0daa, 0x0000, 0x50b0, 0x0000, 0x51b2, 0x0000, 0x0db4,
 	0x0008, 0x0db6, 0x0008, 0x0060, 0x0008, 0x8062, 0x0000, 0x0007,
-	0x0000, 0x8066, 0x0008, 0xa452, 0x0003, 0xc20a, 0x000f, 0x4000,
-	0x000a, 0x3945, 0x000b, 0x8a16, 0x0000, 0x8072, 0x0008, 0x4040,
-	0x0007, 0x0000, 0x000a, 0x3945, 0x0003, 0x8a14, 0x000f, 0x4000,
+	0x0000, 0x8066, 0x0008, 0xa452, 0x000b, 0xc21a, 0x000f, 0x4000,
+	0x000a, 0x3945, 0x000b, 0x8a26, 0x0000, 0x8072, 0x0008, 0x4040,
+	0x0007, 0x0000, 0x000a, 0x3945, 0x0003, 0x8a24, 0x000f, 0x4000,
 	0x0000, 0x8072, 0x0000, 0x4000, 0x0007, 0x0000, 0x0007, 0x0000,
-	0x0007, 0x0000, 0x000a, 0x3945, 0x0003, 0x0a0e, 0x000b, 0x0216,
-	0x000a, 0x3a40, 0x000b, 0x8817, 0x0001, 0xabd0, 0x0008, 0x0000,
-	0x0000, 0x7f24, 0x000b, 0x5a21, 0x0008, 0x8054, 0x0000, 0x0002,
-	0x0002, 0x1242, 0x0003, 0x0a67, 0x000a, 0x3a45, 0x000b, 0x0a56,
-	0x000a, 0x1e10, 0x0000, 0x7f3c, 0x000b, 0x0a53, 0x0002, 0x1d00,
+	0x0007, 0x0000, 0x000a, 0x3945, 0x000b, 0x0a1e, 0x000b, 0x0226,
+	0x000a, 0x3a40, 0x0003, 0x8819, 0x0001, 0xabd0, 0x0008, 0x0000,
+	0x0000, 0x7f24, 0x0003, 0x5a31, 0x0008, 0x8054, 0x0000, 0x0002,
+	0x0002, 0x1242, 0x000b, 0x0a77, 0x000a, 0x3a45, 0x000b, 0x0a66,
+	0x000a, 0x1e10, 0x0000, 0x7f3c, 0x000b, 0x0a63, 0x0002, 0x1d00,
 	0x0000, 0x7f3a, 0x0000, 0x0d60, 0x0008, 0x7f62, 0x0000, 0x8066,
-	0x0008, 0x0009, 0x000b, 0xc231, 0x0008, 0x00fc, 0x000b, 0xb250,
+	0x0008, 0x0009, 0x0003, 0xc241, 0x0008, 0x00fc, 0x000b, 0xb260,
 	0x0000, 0x1c60, 0x0008, 0x8062, 0x0000, 0x0001, 0x0000, 0x8066,
-	0x0008, 0x0009, 0x0003, 0xc239, 0x0008, 0x00fc, 0x000b, 0x3377,
+	0x0008, 0x0009, 0x000b, 0xc249, 0x0008, 0x00fc, 0x0003, 0x3394,
 	0x0000, 0x0038, 0x0008, 0x0060, 0x0008, 0x8062, 0x0000, 0x0019,
-	0x0000, 0x8066, 0x0008, 0x0009, 0x0003, 0xc242, 0x0009, 0x80c0,
+	0x0000, 0x8066, 0x0008, 0x0009, 0x000b, 0xc252, 0x0009, 0x80c0,
 	0x0008, 0x00ff, 0x0008, 0x7f3e, 0x0000, 0x0d60, 0x0008, 0x0efe,
 	0x0001, 0x1f80, 0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x0009,
-	0x000b, 0xc24c, 0x0008, 0x003a, 0x0000, 0x1dfe, 0x0003, 0x022d,
-	0x0008, 0x0036, 0x0004, 0x00a6, 0x000b, 0x0267, 0x0000, 0x8074,
-	0x0000, 0x2000, 0x000b, 0x0267, 0x0002, 0x3a44, 0x000b, 0x0ba4,
+	0x0003, 0xc25c, 0x0008, 0x003a, 0x0000, 0x1dfe, 0x000b, 0x023d,
+	0x0008, 0x0036, 0x0004, 0x00aa, 0x0003, 0x0277, 0x0000, 0x8074,
+	0x0000, 0x2000, 0x0003, 0x0277, 0x0002, 0x3a44, 0x000b, 0x0bc1,
 	0x0000, 0x8074, 0x0000, 0x1000, 0x0001, 0xadd0, 0x0008, 0x0000,
-	0x0008, 0x7f0e, 0x0003, 0xb374, 0x0001, 0xa7d0, 0x0008, 0x0000,
+	0x0008, 0x7f0e, 0x000b, 0xb391, 0x0001, 0xa7d0, 0x0008, 0x0000,
 	0x0000, 0x7f00, 0x0009, 0xa6d0, 0x0008, 0x0000, 0x0009, 0x00d0,
-	0x0003, 0x8a77, 0x0000, 0x8074, 0x0008, 0x4040, 0x0003, 0x5a67,
-	0x000b, 0x521c, 0x000a, 0x3a46, 0x0003, 0x8a77, 0x0002, 0x3a47,
-	0x000b, 0x0a72, 0x0008, 0x8054, 0x0000, 0x0004, 0x0000, 0x8074,
-	0x0000, 0x8000, 0x0003, 0x02d7, 0x0009, 0x92c0, 0x0000, 0x0fc8,
-	0x000b, 0x0813, 0x000a, 0x1246, 0x0003, 0x8b6e, 0x0000, 0x1a60,
+	0x0003, 0x8a87, 0x0000, 0x8074, 0x0008, 0x4040, 0x000b, 0x5a77,
+	0x000b, 0x522c, 0x000a, 0x3a46, 0x0003, 0x8a87, 0x0002, 0x3a47,
+	0x000b, 0x0a82, 0x0008, 0x8054, 0x0000, 0x0004, 0x0000, 0x8074,
+	0x0000, 0x8000, 0x0003, 0x02e7, 0x0009, 0x92c0, 0x0000, 0x0fc8,
+	0x000b, 0x0813, 0x000a, 0x1246, 0x000b, 0x8b8b, 0x0000, 0x1a60,
 	0x0008, 0x8062, 0x0000, 0x0002, 0x0000, 0x8066, 0x0000, 0x367a,
-	0x000b, 0xc27c, 0x0009, 0x92c0, 0x0008, 0x0780, 0x000b, 0x8b88,
-	0x0002, 0x124b, 0x0003, 0x0a85, 0x0002, 0x2e4d, 0x0002, 0x2e4d,
-	0x0003, 0x0b74, 0x000a, 0x3a46, 0x0003, 0x8a95, 0x000b, 0x5a87,
-	0x0008, 0x8054, 0x0000, 0x0004, 0x000a, 0x1243, 0x0003, 0x0ad5,
-	0x0008, 0x8010, 0x0000, 0x000d, 0x000c, 0x0362, 0x000a, 0x1948,
-	0x0003, 0x0a92, 0x000c, 0x0357, 0x0000, 0x1810, 0x000c, 0x0362,
-	0x000b, 0x02d5, 0x000a, 0x1948, 0x000b, 0x0a99, 0x000a, 0x1243,
-	0x0003, 0x0b77, 0x000a, 0x194d, 0x0003, 0x0a9d, 0x000a, 0x1243,
-	0x0003, 0x0b7e, 0x0003, 0x5a9d, 0x0008, 0x8054, 0x0000, 0x0004,
-	0x000a, 0x192e, 0x0008, 0x7f32, 0x000a, 0x1947, 0x000b, 0x0acf,
-	0x0002, 0x194f, 0x0003, 0x0aad, 0x000c, 0x0357, 0x0000, 0x1810,
-	0x0004, 0x01dc, 0x0003, 0xb2c8, 0x000c, 0x0362, 0x000c, 0x01c6,
-	0x000b, 0x02d5, 0x0000, 0x1a60, 0x0008, 0x8062, 0x0000, 0x001f,
-	0x0000, 0x8066, 0x0008, 0x0009, 0x0003, 0xc2b2, 0x000a, 0x004c,
-	0x0003, 0x8acf, 0x0000, 0x8060, 0x0000, 0x0400, 0x0001, 0x9880,
+	0x000b, 0xc28c, 0x0009, 0x92c0, 0x0008, 0x0780, 0x000b, 0x8ba5,
+	0x0002, 0x124b, 0x000b, 0x0a95, 0x0002, 0x2e4d, 0x0002, 0x2e4d,
+	0x000b, 0x0b91, 0x000a, 0x3a46, 0x0003, 0x8aa5, 0x0003, 0x5a97,
+	0x0008, 0x8054, 0x0000, 0x0004, 0x000a, 0x1243, 0x0003, 0x0ae5,
+	0x0008, 0x8010, 0x0000, 0x000d, 0x0004, 0x0372, 0x000a, 0x1948,
+	0x0003, 0x0aa2, 0x000c, 0x0367, 0x0000, 0x1810, 0x0004, 0x0372,
+	0x000b, 0x02e5, 0x000a, 0x1948, 0x000b, 0x0aa9, 0x000a, 0x1243,
+	0x000b, 0x0b94, 0x000a, 0x194d, 0x0003, 0x0aad, 0x000a, 0x1243,
+	0x000b, 0x0b9b, 0x0003, 0x5aad, 0x0008, 0x8054, 0x0000, 0x0004,
+	0x000a, 0x192e, 0x0008, 0x7f32, 0x000a, 0x1947, 0x0003, 0x0adf,
+	0x0002, 0x194f, 0x000b, 0x0abd, 0x000c, 0x0367, 0x0000, 0x1810,
+	0x0004, 0x01ec, 0x000b, 0xb2d8, 0x0004, 0x0372, 0x0004, 0x01d6,
+	0x000b, 0x02e5, 0x0000, 0x1a60, 0x0008, 0x8062, 0x0000, 0x001f,
+	0x0000, 0x8066, 0x0008, 0x0009, 0x000b, 0xc2c2, 0x000a, 0x004c,
+	0x000b, 0x8adf, 0x0000, 0x8060, 0x0000, 0x0400, 0x0001, 0x9880,
 	0x0000, 0x0007, 0x0008, 0x7f62, 0x0000, 0x8066, 0x0000, 0x320a,
-	0x000b, 0xc2bc, 0x0000, 0x8060, 0x0000, 0x0400, 0x0001, 0x9880,
+	0x0003, 0xc2cc, 0x0000, 0x8060, 0x0000, 0x0400, 0x0001, 0x9880,
 	0x0008, 0x0012, 0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x1e0a,
-	0x000b, 0xc2c4, 0x0000, 0x1826, 0x0000, 0x1928, 0x000b, 0x02d5,
-	0x0000, 0x0806, 0x0008, 0x8010, 0x0000, 0x001f, 0x000c, 0x0362,
-	0x0000, 0x0310, 0x000c, 0x0362, 0x000b, 0x02d5, 0x000c, 0x0357,
-	0x0008, 0x8010, 0x0000, 0x0001, 0x000c, 0x0362, 0x0000, 0x1810,
-	0x000c, 0x0362, 0x0000, 0x8074, 0x0008, 0xf000, 0x0000, 0x0d30,
-	0x0002, 0x3a42, 0x0003, 0x8add, 0x0000, 0x15fc, 0x000b, 0xb07a,
+	0x0003, 0xc2d4, 0x0000, 0x1826, 0x0000, 0x1928, 0x000b, 0x02e5,
+	0x0000, 0x0806, 0x0008, 0x8010, 0x0000, 0x001f, 0x0004, 0x0372,
+	0x0000, 0x0310, 0x0004, 0x0372, 0x000b, 0x02e5, 0x000c, 0x0367,
+	0x0008, 0x8010, 0x0000, 0x0001, 0x0004, 0x0372, 0x0000, 0x1810,
+	0x0004, 0x0372, 0x0000, 0x8074, 0x0008, 0xf000, 0x0000, 0x0d30,
+	0x0002, 0x3a42, 0x0003, 0x8aed, 0x0000, 0x15fc, 0x0003, 0xb07e,
 	0x0003, 0x0013, 0x0000, 0x8074, 0x0000, 0x0501, 0x0008, 0x8010,
-	0x0008, 0x000c, 0x000c, 0x0362, 0x0003, 0x0013, 0x0009, 0xbbe0,
-	0x0008, 0x0030, 0x0003, 0x8af9, 0x0000, 0x18fe, 0x0009, 0x3ce0,
-	0x000b, 0x0af6, 0x0008, 0x15fe, 0x0009, 0x3ce0, 0x000b, 0x0af6,
-	0x0008, 0x13fe, 0x0009, 0x3ce0, 0x000b, 0x8af2, 0x0004, 0x0350,
-	0x0008, 0x0d26, 0x0003, 0x02f3, 0x000c, 0x0352, 0x0008, 0x8076,
-	0x0000, 0x0040, 0x000b, 0x034d, 0x0008, 0x8076, 0x0008, 0x0041,
-	0x000b, 0x034d, 0x0009, 0xbbe0, 0x0000, 0x0032, 0x000b, 0x8afe,
-	0x0008, 0x3c1e, 0x000b, 0x034d, 0x0009, 0xbbe0, 0x0000, 0x003b,
-	0x000b, 0x8b03, 0x0000, 0x3cdc, 0x000b, 0x034d, 0x0009, 0xbbe0,
-	0x0008, 0x0035, 0x000b, 0x8b09, 0x0000, 0x8072, 0x0000, 0x8000,
-	0x0003, 0x04b1, 0x0009, 0xbbe0, 0x0008, 0x0036, 0x0003, 0x0bd4,
-	0x0009, 0xbbe0, 0x0000, 0x0037, 0x000b, 0x8b2e, 0x0000, 0x18fe,
-	0x0009, 0x3ce0, 0x0003, 0x8af6, 0x0008, 0x8076, 0x0000, 0x0040,
+	0x0008, 0x000c, 0x0004, 0x0372, 0x0003, 0x0013, 0x0009, 0xbbe0,
+	0x0008, 0x0030, 0x000b, 0x8b09, 0x0000, 0x18fe, 0x0009, 0x3ce0,
+	0x0003, 0x0b06, 0x0008, 0x15fe, 0x0009, 0x3ce0, 0x0003, 0x0b06,
+	0x0008, 0x13fe, 0x0009, 0x3ce0, 0x0003, 0x8b02, 0x0004, 0x0360,
+	0x0008, 0x0d26, 0x000b, 0x0303, 0x000c, 0x0362, 0x0008, 0x8076,
+	0x0000, 0x0040, 0x0003, 0x035d, 0x0008, 0x8076, 0x0008, 0x0041,
+	0x0003, 0x035d, 0x0009, 0xbbe0, 0x0000, 0x0032, 0x0003, 0x8b0e,
+	0x0008, 0x3c1e, 0x0003, 0x035d, 0x0009, 0xbbe0, 0x0000, 0x003b,
+	0x0003, 0x8b13, 0x0000, 0x3cdc, 0x0003, 0x035d, 0x0009, 0xbbe0,
+	0x0008, 0x0035, 0x0003, 0x8b19, 0x0000, 0x8072, 0x0000, 0x8000,
+	0x000b, 0x04ce, 0x0009, 0xbbe0, 0x0008, 0x0036, 0x000b, 0x0bf1,
+	0x0009, 0xbbe0, 0x0000, 0x0037, 0x0003, 0x8b3e, 0x0000, 0x18fe,
+	0x0009, 0x3ce0, 0x000b, 0x8b06, 0x0008, 0x8076, 0x0000, 0x0040,
 	0x0000, 0x1a60, 0x0008, 0x8062, 0x0000, 0x000d, 0x0009, 0xa6d0,
 	0x0008, 0x0000, 0x0008, 0x7f04, 0x0001, 0xa7d0, 0x0008, 0x0000,
 	0x0000, 0x7f06, 0x0001, 0xa8d0, 0x0008, 0x0000, 0x0008, 0x7f08,
 	0x0009, 0xa9d0, 0x0008, 0x0000, 0x0000, 0x7f0a, 0x0000, 0x8066,
-	0x0000, 0x0422, 0x0003, 0xc325, 0x000c, 0x0357, 0x0008, 0x8054,
+	0x0000, 0x0422, 0x000b, 0xc335, 0x000c, 0x0367, 0x0008, 0x8054,
 	0x0000, 0x0004, 0x0000, 0x8074, 0x0008, 0xf000, 0x0000, 0x8072,
-	0x0000, 0x8000, 0x0003, 0x02d7, 0x0009, 0xbbe0, 0x0000, 0x0038,
-	0x0003, 0x8b40, 0x0000, 0x18fe, 0x0009, 0x3ce0, 0x000b, 0x0b3d,
-	0x0008, 0x15fe, 0x0009, 0x3ce0, 0x000b, 0x8aec, 0x000c, 0x0352,
+	0x0000, 0x8000, 0x0003, 0x02e7, 0x0009, 0xbbe0, 0x0000, 0x0038,
+	0x000b, 0x8b50, 0x0000, 0x18fe, 0x0009, 0x3ce0, 0x0003, 0x0b4d,
+	0x0008, 0x15fe, 0x0009, 0x3ce0, 0x0003, 0x8afc, 0x000c, 0x0362,
 	0x0008, 0x8076, 0x0000, 0x0040, 0x0000, 0x8072, 0x0000, 0x8000,
-	0x0003, 0x039b, 0x0008, 0x8076, 0x0008, 0x0042, 0x000b, 0x034d,
-	0x0009, 0xbbe0, 0x0000, 0x0016, 0x000b, 0x8b4d, 0x0000, 0x8074,
-	0x0008, 0x0808, 0x0002, 0x3a44, 0x0003, 0x8816, 0x0000, 0x8074,
+	0x000b, 0x03b8, 0x0008, 0x8076, 0x0008, 0x0042, 0x0003, 0x035d,
+	0x0009, 0xbbe0, 0x0000, 0x0016, 0x0003, 0x8b5d, 0x0000, 0x8074,
+	0x0008, 0x0808, 0x0002, 0x3a44, 0x000b, 0x8818, 0x0000, 0x8074,
 	0x0000, 0x0800, 0x0000, 0x8072, 0x0000, 0x8000, 0x000f, 0x8000,
 	0x0003, 0x0013, 0x0000, 0x8072, 0x0000, 0x8000, 0x0003, 0x0013,
-	0x0002, 0x1430, 0x000b, 0x0353, 0x000a, 0x3d30, 0x0000, 0x7f00,
-	0x0001, 0xbc80, 0x0000, 0x0007, 0x0003, 0x035b, 0x000a, 0x1930,
+	0x0002, 0x1430, 0x000b, 0x0363, 0x000a, 0x3d30, 0x0000, 0x7f00,
+	0x0001, 0xbc80, 0x0000, 0x0007, 0x0003, 0x036b, 0x000a, 0x1930,
 	0x0000, 0x7f00, 0x0001, 0x9880, 0x0000, 0x0007, 0x0000, 0x8060,
 	0x0000, 0x0400, 0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x000a,
-	0x000b, 0xc360, 0x000f, 0x4000, 0x000b, 0x2362, 0x0008, 0x0870,
-	0x000f, 0x4000, 0x0009, 0xbac0, 0x0008, 0x0090, 0x000b, 0x0b6b,
-	0x0000, 0x8074, 0x0000, 0x0706, 0x0003, 0x036d, 0x0000, 0x8074,
-	0x0000, 0x0703, 0x000f, 0x4000, 0x0008, 0x8010, 0x0000, 0x0023,
-	0x000b, 0x03a9, 0x0008, 0x8010, 0x0000, 0x0008, 0x000b, 0x03a9,
-	0x0008, 0x8010, 0x0008, 0x0022, 0x000b, 0x03a9, 0x000c, 0x0357,
-	0x0008, 0x8010, 0x0000, 0x0007, 0x000c, 0x0362, 0x0000, 0x1810,
-	0x000c, 0x0362, 0x0003, 0x03b3, 0x000c, 0x0357, 0x0008, 0x8010,
-	0x0008, 0x001b, 0x000c, 0x0362, 0x0000, 0x1810, 0x000c, 0x0362,
-	0x0000, 0x8074, 0x0000, 0xf080, 0x0000, 0x0d30, 0x0003, 0x0013,
-	0x0008, 0x8010, 0x0008, 0x0009, 0x000b, 0x03a9, 0x0008, 0x8010,
-	0x0008, 0x0005, 0x000b, 0x03a9, 0x000a, 0x1648, 0x000b, 0x8888,
-	0x0008, 0x808c, 0x0000, 0x0001, 0x0007, 0x0000, 0x0008, 0x8010,
-	0x0000, 0x0004, 0x000a, 0x4143, 0x0003, 0x0888, 0x0002, 0x3a44,
-	0x0003, 0x8813, 0x0008, 0x0d2a, 0x000b, 0x03a9, 0x0008, 0x8010,
-	0x0008, 0x0003, 0x0003, 0x03ab, 0x0008, 0x8010, 0x0000, 0x000b,
-	0x0003, 0x03ab, 0x0008, 0x8010, 0x0000, 0x0002, 0x0003, 0x03ab,
-	0x0002, 0x3a47, 0x000b, 0x8a67, 0x0008, 0x8010, 0x0008, 0x0006,
-	0x0003, 0x03ab, 0x0000, 0x8074, 0x0008, 0xf000, 0x000c, 0x0362,
-	0x0004, 0x0365, 0x000a, 0x3a40, 0x000b, 0x0813, 0x0008, 0x8010,
-	0x0008, 0x000c, 0x000c, 0x0362, 0x0003, 0x0013, 0x0000, 0x8074,
-	0x0000, 0xf080, 0x0000, 0x0d30, 0x0002, 0x2e4d, 0x0002, 0x2e4d,
-	0x000b, 0x0bbc, 0x0008, 0x8054, 0x0000, 0x0019, 0x0003, 0x0013,
-	0x0008, 0x8054, 0x0008, 0x0009, 0x0003, 0x0013, 0x0002, 0x3a44,
-	0x0003, 0x8813, 0x0003, 0x039e, 0x0008, 0x808c, 0x0008, 0x0000,
-	0x0002, 0x4447, 0x0003, 0x0be8, 0x0001, 0xc0c0, 0x0008, 0x00ff,
-	0x0009, 0xffe0, 0x0008, 0x00ff, 0x0003, 0x8bbf, 0x0001, 0xc1e0,
-	0x0008, 0xffff, 0x0003, 0x8bbf, 0x0008, 0x8010, 0x0000, 0x0013,
-	0x000c, 0x0362, 0x0000, 0x8074, 0x0008, 0x0202, 0x0003, 0x0013,
-	0x000a, 0x3a40, 0x0003, 0x8be5, 0x0000, 0x8074, 0x0000, 0x0200,
-	0x0000, 0x3d00, 0x0000, 0x3cfe, 0x0000, 0x8072, 0x0000, 0x8000,
-	0x0001, 0x43e0, 0x0003, 0x8be3, 0x0000, 0x42fe, 0x0001, 0xffc0,
-	0x0008, 0x00ff, 0x0009, 0x00e0, 0x000b, 0x0bbf, 0x0008, 0x0d08,
-	0x000b, 0x0438, 0x0000, 0x8072, 0x0000, 0x8000, 0x0003, 0x0013,
-	0x0004, 0x04ba, 0x0008, 0x808c, 0x0000, 0x0001, 0x0000, 0x04fc,
-	0x000b, 0x349d, 0x0000, 0x0460, 0x0008, 0x8062, 0x0000, 0x0001,
-	0x0000, 0x8066, 0x0008, 0x0009, 0x0003, 0xc3f2, 0x0000, 0x0004,
-	0x0009, 0x80c0, 0x0008, 0x00ff, 0x0000, 0x7f00, 0x0001, 0x80e0,
-	0x0000, 0x0004, 0x000b, 0x0c0c, 0x0001, 0x80e0, 0x0008, 0x0005,
-	0x000b, 0x0c0c, 0x0001, 0x80e0, 0x0008, 0x0006, 0x000b, 0x0c0c,
-	0x0001, 0x82c0, 0x0008, 0xff00, 0x0008, 0x7f04, 0x0009, 0x82e0,
-	0x0008, 0x0600, 0x000b, 0x0c0c, 0x0009, 0x82e0, 0x0008, 0x0500,
-	0x000b, 0x0c0c, 0x0009, 0x82e0, 0x0000, 0x0400, 0x000b, 0x8c9d,
-	0x0009, 0xc4c0, 0x0000, 0x7000, 0x0009, 0xffe0, 0x0000, 0x1000,
-	0x0003, 0x0c38, 0x0004, 0x04ab, 0x0002, 0x3941, 0x000b, 0x0c17,
-	0x0000, 0x8072, 0x0000, 0x0400, 0x0003, 0x0013, 0x0000, 0x0460,
-	0x0008, 0x80fe, 0x0008, 0x002b, 0x0008, 0x7f62, 0x0000, 0x8066,
-	0x0008, 0x2209, 0x0003, 0xc41d, 0x0008, 0x11fc, 0x0003, 0x3433,
-	0x0001, 0x9180, 0x0000, 0x0002, 0x0000, 0x8060, 0x0000, 0x0400,
-	0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x0609, 0x0003, 0xc427,
-	0x0000, 0x42fe, 0x0001, 0xffc0, 0x0008, 0xff00, 0x0009, 0x03e0,
-	0x0003, 0x8c30, 0x0000, 0x8072, 0x0000, 0x0400, 0x0003, 0x0052,
-	0x0001, 0x9180, 0x0008, 0x0003, 0x000b, 0x041a, 0x0000, 0x8072,
-	0x0000, 0x0400, 0x0008, 0x8010, 0x0000, 0x0010, 0x0003, 0x0490,
-	0x0004, 0x04ab, 0x0002, 0x3941, 0x0003, 0x0c3e, 0x0000, 0x8072,
-	0x0000, 0x0400, 0x0003, 0x0013, 0x0004, 0x0475, 0x0008, 0x11fc,
-	0x0003, 0xb446, 0x0000, 0x8072, 0x0000, 0x0400, 0x0008, 0x8010,
-	0x0000, 0x000e, 0x0003, 0x0490, 0x0000, 0x8060, 0x0000, 0x0400,
-	0x0000, 0x04fc, 0x0003, 0xb45b, 0x0008, 0x808c, 0x0008, 0x0000,
-	0x0001, 0x9180, 0x0008, 0x0005, 0x0008, 0x7f62, 0x0000, 0x8066,
-	0x0008, 0x0009, 0x000b, 0xc451, 0x0008, 0x0060, 0x0008, 0x8062,
-	0x0008, 0x001b, 0x0008, 0x4304, 0x0008, 0x4206, 0x0000, 0x8066,
-	0x0000, 0x0412, 0x0003, 0xc459, 0x0003, 0x0472, 0x0008, 0x808c,
-	0x0000, 0x0001, 0x0000, 0x0460, 0x0008, 0x8062, 0x0008, 0x002b,
-	0x0000, 0x8066, 0x0008, 0x0609, 0x000b, 0xc462, 0x0000, 0x8066,
-	0x0008, 0x220a, 0x0003, 0xc465, 0x0000, 0x42fe, 0x0001, 0xffc0,
-	0x0008, 0xff00, 0x0008, 0x7f04, 0x0000, 0x8060, 0x0000, 0x0400,
-	0x0001, 0x9180, 0x0000, 0x0002, 0x0008, 0x7f62, 0x0000, 0x8066,
-	0x0008, 0x041a, 0x0003, 0xc471, 0x0000, 0x8072, 0x0000, 0x0400,
-	0x0003, 0x0052, 0x0000, 0x8060, 0x0000, 0x0400, 0x0008, 0x6b62,
-	0x0000, 0x8066, 0x0000, 0x0411, 0x000b, 0xc47a, 0x0008, 0x02fe,
-	0x0009, 0x03e0, 0x000b, 0x8c80, 0x0000, 0x0d22, 0x000f, 0x4000,
-	0x0009, 0x8280, 0x0000, 0x0002, 0x0001, 0x6b80, 0x0008, 0x7f62,
-	0x0000, 0x8066, 0x0008, 0x2209, 0x000b, 0xc486, 0x000a, 0x0200,
-	0x0001, 0xffc0, 0x0000, 0x0007, 0x0000, 0x7f06, 0x0008, 0x6b62,
-	0x0000, 0x8066, 0x0008, 0x060a, 0x0003, 0xc48e, 0x000f, 0x4000,
-	0x0002, 0x3a44, 0x0003, 0x8813, 0x000a, 0x2f44, 0x000a, 0x2f44,
-	0x0003, 0x8b9e, 0x0008, 0x808a, 0x0008, 0x0003, 0x0000, 0x8074,
-	0x0000, 0xf080, 0x000b, 0x5c99, 0x0008, 0x8054, 0x0000, 0x0019,
-	0x0003, 0x0013, 0x0002, 0x3a44, 0x0003, 0x8813, 0x0008, 0x808c,
-	0x0008, 0x0000, 0x0008, 0x8010, 0x0008, 0x0011, 0x000c, 0x0362,
-	0x0000, 0x42fe, 0x0001, 0xffc0, 0x0008, 0x00ff, 0x0008, 0x7f10,
-	0x000c, 0x0362, 0x0008, 0x4310, 0x0003, 0x03ab, 0x0002, 0x3941,
-	0x0003, 0x0cae, 0x000f, 0x4000, 0x0000, 0x8072, 0x0008, 0x0404,
-	0x000f, 0x4000, 0x0008, 0x8010, 0x0008, 0x0012, 0x000c, 0x0362,
-	0x0004, 0x0475, 0x0000, 0x1110, 0x000c, 0x0362, 0x0008, 0x11fc,
-	0x000b, 0xb4b4, 0x0003, 0x0013, 0x0009, 0xc2c0, 0x0008, 0x00ff,
-	0x0000, 0x7f00, 0x0001, 0xc3c0, 0x0008, 0xff00, 0x0009, 0x00d0,
-	0x0003, 0x0cdf, 0x0000, 0x0d0a, 0x0001, 0x8580, 0x0000, 0x1000,
-	0x0008, 0x7f62, 0x0000, 0x8060, 0x0000, 0x0400, 0x0000, 0x8066,
-	0x0000, 0x0809, 0x0003, 0xc4c9, 0x0000, 0x04fc, 0x0003, 0x34d8,
-	0x0000, 0x0460, 0x0008, 0x8062, 0x0000, 0x0004, 0x0000, 0x8066,
-	0x0000, 0x0211, 0x0003, 0xc4d1, 0x0008, 0x01fe, 0x0009, 0x00e0,
-	0x0003, 0x8cd8, 0x0008, 0x02fe, 0x0001, 0x43e0, 0x000b, 0x0cde,
-	0x0002, 0x0500, 0x0000, 0x7f0a, 0x0009, 0xffe0, 0x0000, 0x0800,
-	0x000b, 0x8cc2, 0x0008, 0x0d08, 0x000f, 0x4000, 0x0008, 0x43fe,
-	0x0001, 0x3e80, 0x0000, 0x0d60, 0x0008, 0x7f62, 0x0000, 0x8066,
-	0x0000, 0x0809, 0x000b, 0xc4e5, 0x0000, 0x8060, 0x0000, 0x0400,
-	0x0001, 0x84c0, 0x0008, 0xff00, 0x0002, 0x7f70, 0x0009, 0xff80,
-	0x0000, 0x1000, 0x0008, 0x7f62, 0x0000, 0x8066, 0x0000, 0x0809,
-	0x0003, 0xc4f0, 0x000f, 0x4000, 0xe504, 0x3334
+	0x0003, 0xc370, 0x000f, 0x4000, 0x000b, 0x2375, 0x0008, 0x0870,
+	0x000f, 0x4000, 0x0002, 0x7040, 0x0003, 0x0b72, 0x000b, 0xe37f,
+	0x0008, 0x808a, 0x0000, 0x0004, 0x0007, 0x0000, 0x0007, 0x0000,
+	0x0008, 0x80e0, 0x0008, 0x0202, 0x000b, 0x6378, 0x0008, 0x80e0,
+	0x0000, 0x0100, 0x000b, 0x0372, 0x0009, 0xbac0, 0x0008, 0x0090,
+	0x0003, 0x0b88, 0x0000, 0x8074, 0x0000, 0x0706, 0x0003, 0x038a,
+	0x0000, 0x8074, 0x0000, 0x0703, 0x000f, 0x4000, 0x0008, 0x8010,
+	0x0000, 0x0023, 0x000b, 0x03c6, 0x0008, 0x8010, 0x0000, 0x0008,
+	0x000b, 0x03c6, 0x0008, 0x8010, 0x0008, 0x0022, 0x000b, 0x03c6,
+	0x000c, 0x0367, 0x0008, 0x8010, 0x0000, 0x0007, 0x0004, 0x0372,
+	0x0000, 0x1810, 0x0004, 0x0372, 0x0003, 0x03d0, 0x000c, 0x0367,
+	0x0008, 0x8010, 0x0008, 0x001b, 0x0004, 0x0372, 0x0000, 0x1810,
+	0x0004, 0x0372, 0x0000, 0x8074, 0x0000, 0xf080, 0x0000, 0x0d30,
+	0x0003, 0x0013, 0x0008, 0x8010, 0x0008, 0x0009, 0x000b, 0x03c6,
+	0x0008, 0x8010, 0x0008, 0x0005, 0x000b, 0x03c6, 0x000a, 0x1648,
+	0x0003, 0x888c, 0x0008, 0x808c, 0x0000, 0x0001, 0x0007, 0x0000,
+	0x0008, 0x8010, 0x0000, 0x0004, 0x000a, 0x4143, 0x000b, 0x088c,
+	0x0002, 0x3a44, 0x0003, 0x8813, 0x0008, 0x0d2a, 0x000b, 0x03c6,
+	0x0008, 0x8010, 0x0008, 0x0003, 0x0003, 0x03c8, 0x0008, 0x8010,
+	0x0000, 0x000b, 0x0003, 0x03c8, 0x0008, 0x8010, 0x0000, 0x0002,
+	0x0003, 0x03c8, 0x0002, 0x3a47, 0x0003, 0x8a77, 0x0008, 0x8010,
+	0x0008, 0x0006, 0x0003, 0x03c8, 0x0000, 0x8074, 0x0008, 0xf000,
+	0x0004, 0x0372, 0x0004, 0x0382, 0x000a, 0x3a40, 0x000b, 0x0813,
+	0x0008, 0x8010, 0x0008, 0x000c, 0x0004, 0x0372, 0x0003, 0x0013,
+	0x0000, 0x8074, 0x0000, 0xf080, 0x0000, 0x0d30, 0x0002, 0x2e4d,
+	0x0002, 0x2e4d, 0x000b, 0x0bd9, 0x0008, 0x8054, 0x0000, 0x0019,
+	0x0003, 0x0013, 0x0008, 0x8054, 0x0008, 0x0009, 0x0003, 0x0013,
+	0x0002, 0x3a44, 0x0003, 0x8813, 0x000b, 0x03bb, 0x0008, 0x808c,
+	0x0008, 0x0000, 0x0002, 0x4447, 0x000b, 0x0c05, 0x0001, 0xc0c0,
+	0x0008, 0x00ff, 0x0009, 0xffe0, 0x0008, 0x00ff, 0x0003, 0x8bdc,
+	0x0001, 0xc1e0, 0x0008, 0xffff, 0x0003, 0x8bdc, 0x0008, 0x8010,
+	0x0000, 0x0013, 0x0004, 0x0372, 0x0000, 0x8074, 0x0008, 0x0202,
+	0x0003, 0x0013, 0x000a, 0x3a40, 0x000b, 0x8c02, 0x0000, 0x8074,
+	0x0000, 0x0200, 0x0000, 0x3d00, 0x0000, 0x3cfe, 0x0000, 0x8072,
+	0x0000, 0x8000, 0x0001, 0x43e0, 0x0003, 0x8c00, 0x0000, 0x42fe,
+	0x0001, 0xffc0, 0x0008, 0x00ff, 0x0009, 0x00e0, 0x000b, 0x0bdc,
+	0x0008, 0x0d08, 0x0003, 0x0455, 0x0000, 0x8072, 0x0000, 0x8000,
+	0x0003, 0x0013, 0x000c, 0x04d7, 0x0008, 0x808c, 0x0000, 0x0001,
+	0x0000, 0x04fc, 0x000b, 0x34ba, 0x0000, 0x0460, 0x0008, 0x8062,
+	0x0000, 0x0001, 0x0000, 0x8066, 0x0008, 0x0009, 0x0003, 0xc40f,
+	0x0000, 0x0004, 0x0009, 0x80c0, 0x0008, 0x00ff, 0x0000, 0x7f00,
+	0x0001, 0x80e0, 0x0000, 0x0004, 0x0003, 0x0c29, 0x0001, 0x80e0,
+	0x0008, 0x0005, 0x0003, 0x0c29, 0x0001, 0x80e0, 0x0008, 0x0006,
+	0x0003, 0x0c29, 0x0001, 0x82c0, 0x0008, 0xff00, 0x0008, 0x7f04,
+	0x0009, 0x82e0, 0x0008, 0x0600, 0x0003, 0x0c29, 0x0009, 0x82e0,
+	0x0008, 0x0500, 0x0003, 0x0c29, 0x0009, 0x82e0, 0x0000, 0x0400,
+	0x000b, 0x8cba, 0x0009, 0xc4c0, 0x0000, 0x7000, 0x0009, 0xffe0,
+	0x0000, 0x1000, 0x000b, 0x0c55, 0x0004, 0x04c8, 0x0002, 0x3941,
+	0x0003, 0x0c34, 0x0000, 0x8072, 0x0000, 0x0400, 0x0003, 0x0013,
+	0x0000, 0x0460, 0x0008, 0x80fe, 0x0008, 0x002b, 0x0008, 0x7f62,
+	0x0000, 0x8066, 0x0008, 0x2209, 0x0003, 0xc43a, 0x0008, 0x11fc,
+	0x0003, 0x3450, 0x0001, 0x9180, 0x0000, 0x0002, 0x0000, 0x8060,
+	0x0000, 0x0400, 0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x0609,
+	0x0003, 0xc444, 0x0000, 0x42fe, 0x0001, 0xffc0, 0x0008, 0xff00,
+	0x0009, 0x03e0, 0x0003, 0x8c4d, 0x0000, 0x8072, 0x0000, 0x0400,
+	0x000b, 0x0056, 0x0001, 0x9180, 0x0008, 0x0003, 0x000b, 0x0437,
+	0x0000, 0x8072, 0x0000, 0x0400, 0x0008, 0x8010, 0x0000, 0x0010,
+	0x000b, 0x04ad, 0x0004, 0x04c8, 0x0002, 0x3941, 0x0003, 0x0c5b,
+	0x0000, 0x8072, 0x0000, 0x0400, 0x0003, 0x0013, 0x0004, 0x0492,
+	0x0008, 0x11fc, 0x000b, 0xb463, 0x0000, 0x8072, 0x0000, 0x0400,
+	0x0008, 0x8010, 0x0000, 0x000e, 0x000b, 0x04ad, 0x0000, 0x8060,
+	0x0000, 0x0400, 0x0000, 0x04fc, 0x000b, 0xb478, 0x0008, 0x808c,
+	0x0008, 0x0000, 0x0001, 0x9180, 0x0008, 0x0005, 0x0008, 0x7f62,
+	0x0000, 0x8066, 0x0008, 0x0009, 0x000b, 0xc46e, 0x0008, 0x0060,
+	0x0008, 0x8062, 0x0008, 0x001b, 0x0008, 0x4304, 0x0008, 0x4206,
+	0x0000, 0x8066, 0x0000, 0x0412, 0x000b, 0xc476, 0x000b, 0x048f,
+	0x0008, 0x808c, 0x0000, 0x0001, 0x0000, 0x0460, 0x0008, 0x8062,
+	0x0008, 0x002b, 0x0000, 0x8066, 0x0008, 0x0609, 0x000b, 0xc47f,
+	0x0000, 0x8066, 0x0008, 0x220a, 0x0003, 0xc482, 0x0000, 0x42fe,
+	0x0001, 0xffc0, 0x0008, 0xff00, 0x0008, 0x7f04, 0x0000, 0x8060,
+	0x0000, 0x0400, 0x0001, 0x9180, 0x0000, 0x0002, 0x0008, 0x7f62,
+	0x0000, 0x8066, 0x0008, 0x041a, 0x0003, 0xc48e, 0x0000, 0x8072,
+	0x0000, 0x0400, 0x000b, 0x0056, 0x0000, 0x8060, 0x0000, 0x0400,
+	0x0008, 0x6b62, 0x0000, 0x8066, 0x0000, 0x0411, 0x000b, 0xc497,
+	0x0008, 0x02fe, 0x0009, 0x03e0, 0x000b, 0x8c9d, 0x0000, 0x0d22,
+	0x000f, 0x4000, 0x0009, 0x8280, 0x0000, 0x0002, 0x0001, 0x6b80,
+	0x0008, 0x7f62, 0x0000, 0x8066, 0x0008, 0x2209, 0x0003, 0xc4a3,
+	0x000a, 0x0200, 0x0001, 0xffc0, 0x0000, 0x0007, 0x0000, 0x7f06,
+	0x0008, 0x6b62, 0x0000, 0x8066, 0x0008, 0x060a, 0x000b, 0xc4ab,
+	0x000f, 0x4000, 0x0002, 0x3a44, 0x0003, 0x8813, 0x000a, 0x2f44,
+	0x000a, 0x2f44, 0x000b, 0x8bbb, 0x0008, 0x808a, 0x0008, 0x0003,
+	0x0000, 0x8074, 0x0000, 0xf080, 0x0003, 0x5cb6, 0x0008, 0x8054,
+	0x0000, 0x0019, 0x0003, 0x0013, 0x0002, 0x3a44, 0x0003, 0x8813,
+	0x0008, 0x808c, 0x0008, 0x0000, 0x0008, 0x8010, 0x0008, 0x0011,
+	0x0004, 0x0372, 0x0000, 0x42fe, 0x0001, 0xffc0, 0x0008, 0x00ff,
+	0x0008, 0x7f10, 0x0004, 0x0372, 0x0008, 0x4310, 0x0003, 0x03c8,
+	0x0002, 0x3941, 0x0003, 0x0ccb, 0x000f, 0x4000, 0x0000, 0x8072,
+	0x0008, 0x0404, 0x000f, 0x4000, 0x0008, 0x8010, 0x0008, 0x0012,
+	0x0004, 0x0372, 0x0004, 0x0492, 0x0000, 0x1110, 0x0004, 0x0372,
+	0x0008, 0x11fc, 0x000b, 0xb4d1, 0x0003, 0x0013, 0x0009, 0xc2c0,
+	0x0008, 0x00ff, 0x0000, 0x7f00, 0x0001, 0xc3c0, 0x0008, 0xff00,
+	0x0009, 0x00d0, 0x000b, 0x0cfc, 0x0000, 0x0d0a, 0x0001, 0x8580,
+	0x0000, 0x1000, 0x0008, 0x7f62, 0x0000, 0x8060, 0x0000, 0x0400,
+	0x0000, 0x8066, 0x0000, 0x0809, 0x000b, 0xc4e6, 0x0000, 0x04fc,
+	0x0003, 0x34f5, 0x0000, 0x0460, 0x0008, 0x8062, 0x0000, 0x0004,
+	0x0000, 0x8066, 0x0000, 0x0211, 0x0003, 0xc4ee, 0x0008, 0x01fe,
+	0x0009, 0x00e0, 0x0003, 0x8cf5, 0x0008, 0x02fe, 0x0001, 0x43e0,
+	0x0003, 0x0cfb, 0x0002, 0x0500, 0x0000, 0x7f0a, 0x0009, 0xffe0,
+	0x0000, 0x0800, 0x000b, 0x8cdf, 0x0008, 0x0d08, 0x000f, 0x4000,
+	0x0008, 0x43fe, 0x0001, 0x3e80, 0x0000, 0x0d60, 0x0008, 0x7f62,
+	0x0000, 0x8066, 0x0000, 0x0809, 0x0003, 0xc502, 0x0000, 0x8060,
+	0x0000, 0x0400, 0x0001, 0x84c0, 0x0008, 0xff00, 0x0002, 0x7f70,
+	0x0009, 0xff80, 0x0000, 0x1000, 0x0008, 0x7f62, 0x0000, 0x8066,
+	0x0000, 0x0809, 0x0003, 0xc50d, 0x000f, 0x4000, 0xe5cd, 0x01ac
 };
-unsigned short rseqipx_code_length01 = 0x09e6;
+unsigned short rseqipx_code_length01 = 0x0a20;
 /*
  *
  */
 
 unsigned long xseqipx_code_addr01 = 0x0001e000 ;
 unsigned short xseqipx_code01[] = { 
-0x0013, 0x0003, 0x0000, 0x10d6, 0x0001, 0xe000, 0x0005, 0x0032,
+0x0013, 0x0003, 0x0000, 0x1246, 0x0001, 0xe000, 0x0005, 0x0032,
 	0x0000, 0x0010, 0x0015, 0x0033, 0x0010, 0xbb39, 0x000b, 0x8007,
-	0x0004, 0x010b, 0x0014, 0x011d, 0x0010, 0xc000, 0x0000, 0xc001,
+	0x0004, 0x0110, 0x0014, 0x0122, 0x0010, 0xc000, 0x0000, 0xc001,
 	0x0000, 0xc0b0, 0x0010, 0xc0b1, 0x0010, 0xc0b2, 0x0000, 0xc0b3,
 	0x0010, 0xc0b4, 0x0000, 0xc0b5, 0x0000, 0xc0b6, 0x0010, 0xc0b7,
 	0x0010, 0xc0b8, 0x0000, 0xc0b9, 0x0000, 0xc0ba, 0x0000, 0xc0c2,
@@ -7593,532 +7695,578 @@ unsigned short xseqipx_code01[] = { 
 	0x0010, 0xc0cf, 0x0015, 0x0039, 0x0010, 0xff00, 0x0015, 0x003a,
 	0x0010, 0xff00, 0x0005, 0x00d0, 0x0010, 0xff00, 0x0015, 0x00d1,
 	0x0010, 0xff00, 0x0012, 0x3a40, 0x000b, 0x1031, 0x0002, 0x7940,
-	0x001b, 0x112f, 0x0002, 0x3a42, 0x001b, 0x1035, 0x0003, 0xb035,
-	0x0013, 0xa1dc, 0x0002, 0x3a41, 0x001b, 0x1039, 0x0012, 0x7941,
-	0x001b, 0x1311, 0x0003, 0xe055, 0x0012, 0xd042, 0x0003, 0x103f,
-	0x0000, 0x75ff, 0x0002, 0xff41, 0x001b, 0x1055, 0x0000, 0x0cfe,
-	0x0003, 0x6049, 0x0002, 0x3a44, 0x000b, 0x1049, 0x0011, 0x02e8,
-	0x0010, 0x0000, 0x0013, 0x13a2, 0x0011, 0x02e8, 0x0010, 0x0005,
-	0x0003, 0x1432, 0x0012, 0x3a46, 0x001b, 0x1055, 0x0012, 0xd042,
-	0x0003, 0x1050, 0x0000, 0x75ff, 0x0012, 0xff40, 0x001b, 0x1055,
-	0x0000, 0x12fe, 0x0013, 0x6055, 0x0001, 0x0fe8, 0x0010, 0x0000,
-	0x0003, 0x163f, 0x0015, 0x0030, 0x0000, 0x0400, 0x0010, 0xc131,
-	0x0015, 0x0033, 0x0010, 0xb211, 0x001b, 0x805a, 0x0010, 0xb2ff,
-	0x0001, 0xb3e0, 0x001c, 0x10cd, 0x000b, 0xf02d, 0x0011, 0x3be8,
-	0x0000, 0x0010, 0x001b, 0x1072, 0x0000, 0x0afe, 0x000b, 0x6066,
-	0x0000, 0x3c0b, 0x0003, 0x006e, 0x0015, 0x0030, 0x0000, 0x0400,
-	0x0001, 0x0a88, 0x0010, 0x0003, 0x0000, 0xff31, 0x0015, 0x0033,
-	0x0010, 0x3c0a, 0x000b, 0x806d, 0x0010, 0x3c0a, 0x0002, 0x0c00,
-	0x0010, 0xff0c, 0x0013, 0x00ca, 0x0011, 0x3be8, 0x0010, 0x0012,
-	0x000b, 0x1085, 0x0010, 0x08fe, 0x001b, 0x6079, 0x0010, 0x3c09,
-	0x0013, 0x0081, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0888,
+	0x001b, 0x1134, 0x0002, 0x3a42, 0x001b, 0x1035, 0x0003, 0xb035,
+	0x0013, 0xa1df, 0x0002, 0x3a41, 0x001b, 0x1039, 0x0012, 0x7941,
+	0x001b, 0x1314, 0x0013, 0xe054, 0x0001, 0x0fe8, 0x0000, 0x0001,
+	0x0013, 0x1054, 0x0000, 0x0cfe, 0x0013, 0x6047, 0x0002, 0x3a44,
+	0x001b, 0x1047, 0x0011, 0x02e8, 0x0010, 0x0000, 0x0013, 0x13c7,
+	0x0011, 0x02e8, 0x0010, 0x0005, 0x0013, 0x1459, 0x0012, 0x3a46,
+	0x000b, 0x1054, 0x0011, 0x02e8, 0x0010, 0x0000, 0x0013, 0x104f,
+	0x0011, 0x02e8, 0x0010, 0x0005, 0x000b, 0x1054, 0x0000, 0x12fe,
+	0x0003, 0x6054, 0x0001, 0x0fe8, 0x0010, 0x0000, 0x0013, 0x168f,
+	0x0015, 0x0030, 0x0000, 0x0400, 0x0010, 0xc131, 0x0015, 0x0033,
+	0x0010, 0xb211, 0x001b, 0x8059, 0x0010, 0xb2ff, 0x0001, 0xb3e0,
+	0x000c, 0x10d2, 0x000b, 0xf02d, 0x0011, 0x3be8, 0x0000, 0x0010,
+	0x001b, 0x1071, 0x0000, 0x0afe, 0x000b, 0x6065, 0x0000, 0x3c0b,
+	0x0003, 0x006d, 0x0015, 0x0030, 0x0000, 0x0400, 0x0001, 0x0a88,
+	0x0010, 0x0003, 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0x3c0a,
+	0x001b, 0x806c, 0x0010, 0x3c0a, 0x0002, 0x0c00, 0x0010, 0xff0c,
+	0x0013, 0x00cf, 0x0011, 0x3be8, 0x0010, 0x0012, 0x001b, 0x1084,
+	0x0010, 0x08fe, 0x000b, 0x6078, 0x0010, 0x3c09, 0x0003, 0x0080,
+	0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0888, 0x0010, 0x0003,
+	0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0x3c0a, 0x000b, 0x807f,
+	0x0000, 0x3c08, 0x0002, 0x0c00, 0x0010, 0xff0c, 0x0013, 0x00cf,
+	0x0011, 0x3be8, 0x0000, 0x0013, 0x000b, 0x108a, 0x0000, 0x3cb0,
+	0x0004, 0x00e2, 0x0013, 0x00cf, 0x0011, 0x3be8, 0x0000, 0x0019,
+	0x000b, 0x109d, 0x0010, 0x04fe, 0x001b, 0x6091, 0x0010, 0x3c05,
+	0x0013, 0x0099, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0488,
 	0x0010, 0x0003, 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0x3c0a,
-	0x000b, 0x8080, 0x0000, 0x3c08, 0x0002, 0x0c00, 0x0010, 0xff0c,
-	0x0013, 0x00ca, 0x0011, 0x3be8, 0x0000, 0x0013, 0x001b, 0x108b,
-	0x0000, 0x3cb0, 0x0004, 0x00dd, 0x0013, 0x00ca, 0x0011, 0x3be8,
-	0x0000, 0x0019, 0x000b, 0x109e, 0x0010, 0x04fe, 0x001b, 0x6092,
-	0x0010, 0x3c05, 0x0013, 0x009a, 0x0015, 0x0030, 0x0000, 0x0400,
-	0x0011, 0x0488, 0x0010, 0x0003, 0x0000, 0xff31, 0x0015, 0x0033,
-	0x0010, 0x3c0a, 0x001b, 0x8099, 0x0000, 0x3c04, 0x0002, 0x0c00,
-	0x0010, 0xff0c, 0x0013, 0x00ca, 0x0011, 0x3be8, 0x0000, 0x0015,
-	0x001b, 0x10aa, 0x0014, 0x0114, 0x0004, 0x0126, 0x0015, 0x0039,
-	0x0000, 0x8000, 0x0017, 0x8000, 0x0004, 0x010b, 0x0014, 0x011d,
-	0x0004, 0x00f6, 0x0013, 0x002d, 0x0011, 0x3be8, 0x0000, 0x0016,
-	0x000b, 0x10bc, 0x0001, 0x0fe8, 0x0010, 0x0000, 0x0013, 0x10b6,
-	0x0001, 0x0fe8, 0x0000, 0x0002, 0x0013, 0x10b6, 0x0015, 0x0039,
-	0x0010, 0x1010, 0x0013, 0x00ca, 0x0015, 0x0039, 0x0000, 0x5040,
-	0x0015, 0x00b8, 0x0000, 0x0008, 0x0004, 0x0867, 0x0013, 0x00ca,
-	0x0011, 0x3be8, 0x0010, 0x0017, 0x000b, 0x10c1, 0x0010, 0x3cc3,
-	0x0013, 0x00ca, 0x0011, 0x3be8, 0x0010, 0x0018, 0x001b, 0x10c6,
-	0x0000, 0x3cc2, 0x0013, 0x00ca, 0x0005, 0x00ce, 0x0000, 0x0001,
-	0x0000, 0x3bcf, 0x0004, 0x0829, 0x0015, 0x0039, 0x0000, 0x8000,
-	0x0013, 0x002d, 0x0001, 0xb288, 0x0000, 0x0002, 0x0001, 0xc180,
-	0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009, 0x000b, 0x80d3,
-	0x0002, 0xb200, 0x0011, 0xffc8, 0x0000, 0x0007, 0x0010, 0xffb2,
-	0x0010, 0xc131, 0x0015, 0x0033, 0x0010, 0xb20a, 0x0001, 0xb0d0,
-	0x000b, 0x80dc, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0xb088,
-	0x0000, 0x0010, 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xb109,
-	0x001b, 0x80e4, 0x0001, 0xb1e8, 0x0010, 0xffff, 0x0003, 0x10f5,
-	0x0000, 0x11fe, 0x001b, 0x60ec, 0x0000, 0xb012, 0x0003, 0x00f4,
-	0x0015, 0x0030, 0x0000, 0x0400, 0x0001, 0x1188, 0x0010, 0x0003,
-	0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb00a, 0x001b, 0x80f3,
-	0x0000, 0xb011, 0x0017, 0x4000, 0x0015, 0x0030, 0x0000, 0x0400,
-	0x0011, 0xbc88, 0x0000, 0x001f, 0x0000, 0xff31, 0x0015, 0x0033,
-	0x0000, 0xc411, 0x000b, 0x80fd, 0x0011, 0xbc88, 0x0010, 0x0018,
-	0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xc609, 0x000b, 0x8103,
-	0x0011, 0xbc88, 0x0000, 0x0037, 0x0000, 0xff31, 0x0015, 0x0033,
-	0x0000, 0xc709, 0x000b, 0x8109, 0x0017, 0x4000, 0x0015, 0x0030,
-	0x0000, 0x0400, 0x0001, 0xbb88, 0x0000, 0x0001, 0x0000, 0xff31,
-	0x0015, 0x0033, 0x0000, 0x0269, 0x000b, 0x8112, 0x0017, 0x4000,
+	0x000b, 0x8098, 0x0000, 0x3c04, 0x0002, 0x0c00, 0x0010, 0xff0c,
+	0x0013, 0x00cf, 0x0011, 0x3be8, 0x0010, 0x001b, 0x001b, 0x10a3,
+	0x0015, 0x000f, 0x0010, 0x0000, 0x0013, 0x00cf, 0x0011, 0x3be8,
+	0x0000, 0x0015, 0x001b, 0x10af, 0x0004, 0x0119, 0x0014, 0x012b,
+	0x0015, 0x0039, 0x0000, 0x8000, 0x0017, 0x8000, 0x0004, 0x0110,
+	0x0014, 0x0122, 0x0014, 0x00fb, 0x0013, 0x002d, 0x0011, 0x3be8,
+	0x0000, 0x0016, 0x000b, 0x10c1, 0x0001, 0x0fe8, 0x0010, 0x0000,
+	0x0003, 0x10bb, 0x0001, 0x0fe8, 0x0000, 0x0002, 0x0003, 0x10bb,
+	0x0015, 0x0039, 0x0010, 0x1010, 0x0013, 0x00cf, 0x0015, 0x0039,
+	0x0000, 0x5040, 0x0015, 0x00b8, 0x0000, 0x0008, 0x0014, 0x091f,
+	0x0013, 0x00cf, 0x0011, 0x3be8, 0x0010, 0x0017, 0x001b, 0x10c6,
+	0x0010, 0x3cc3, 0x0013, 0x00cf, 0x0011, 0x3be8, 0x0010, 0x0018,
+	0x000b, 0x10cb, 0x0000, 0x3cc2, 0x0013, 0x00cf, 0x0005, 0x00ce,
+	0x0000, 0x0001, 0x0000, 0x3bcf, 0x0014, 0x08e1, 0x0015, 0x0039,
+	0x0000, 0x8000, 0x0013, 0x002d, 0x0001, 0xb288, 0x0000, 0x0002,
+	0x0001, 0xc180, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009,
+	0x001b, 0x80d8, 0x0002, 0xb200, 0x0011, 0xffc8, 0x0000, 0x0007,
+	0x0010, 0xffb2, 0x0010, 0xc131, 0x0015, 0x0033, 0x0010, 0xb20a,
+	0x0001, 0xb0d0, 0x001b, 0x80e1, 0x0015, 0x0030, 0x0000, 0x0400,
+	0x0011, 0xb088, 0x0000, 0x0010, 0x0000, 0xff31, 0x0015, 0x0033,
+	0x0010, 0xb109, 0x000b, 0x80e9, 0x0001, 0xb1e8, 0x0010, 0xffff,
+	0x0003, 0x10fa, 0x0000, 0x11fe, 0x001b, 0x60f1, 0x0000, 0xb012,
+	0x0013, 0x00f9, 0x0015, 0x0030, 0x0000, 0x0400, 0x0001, 0x1188,
+	0x0010, 0x0003, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb00a,
+	0x000b, 0x80f8, 0x0000, 0xb011, 0x0017, 0x4000, 0x0015, 0x0030,
+	0x0000, 0x0400, 0x0011, 0xbc88, 0x0000, 0x001f, 0x0000, 0xff31,
+	0x0015, 0x0033, 0x0000, 0xc411, 0x001b, 0x8102, 0x0011, 0xbc88,
+	0x0010, 0x0018, 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xc609,
+	0x001b, 0x8108, 0x0011, 0xbc88, 0x0000, 0x0037, 0x0000, 0xff31,
+	0x0015, 0x0033, 0x0000, 0xc709, 0x001b, 0x810e, 0x0017, 0x4000,
 	0x0015, 0x0030, 0x0000, 0x0400, 0x0001, 0xbb88, 0x0000, 0x0001,
-	0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0x026a, 0x000b, 0x811b,
+	0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0x0269, 0x000b, 0x8117,
 	0x0017, 0x4000, 0x0015, 0x0030, 0x0000, 0x0400, 0x0001, 0xbb88,
-	0x0010, 0x000f, 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0x0f59,
-	0x000b, 0x8124, 0x0017, 0x4000, 0x0015, 0x0030, 0x0000, 0x0400,
+	0x0000, 0x0001, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0x026a,
+	0x001b, 0x8120, 0x0017, 0x4000, 0x0015, 0x0030, 0x0000, 0x0400,
 	0x0001, 0xbb88, 0x0010, 0x000f, 0x0000, 0xff31, 0x0015, 0x0033,
-	0x0010, 0x0f5a, 0x000b, 0x812d, 0x0017, 0x4000, 0x0000, 0xd0ff,
-	0x0012, 0xff40, 0x000b, 0x1031, 0x0015, 0x00d1, 0x0010, 0x0101,
-	0x0013, 0x9134, 0x0005, 0x0079, 0x0000, 0x0001, 0x0013, 0x9137,
-	0x0015, 0x00d1, 0x0000, 0x0100, 0x0011, 0x02e8, 0x0000, 0x0002,
-	0x0003, 0x1161, 0x0011, 0x02e8, 0x0000, 0x0001, 0x0003, 0x1179,
-	0x0011, 0x02e8, 0x0000, 0x0004, 0x0003, 0x1197, 0x0011, 0x02e8,
-	0x0010, 0x0003, 0x0003, 0x11c8, 0x0005, 0x0002, 0x0010, 0x0000,
-	0x0000, 0xc00e, 0x0000, 0xc00d, 0x0010, 0xc003, 0x0015, 0x0030,
-	0x0000, 0x0400, 0x0001, 0xbd88, 0x0010, 0x0009, 0x0000, 0xff31,
-	0x0015, 0x0033, 0x0010, 0xc00a, 0x001b, 0x8152, 0x0000, 0xff31,
-	0x0015, 0x0033, 0x0010, 0xc00a, 0x000b, 0x8156, 0x0012, 0x3a45,
-	0x0003, 0x115e, 0x0015, 0x003a, 0x0000, 0x2000, 0x0015, 0x003a,
-	0x0010, 0x1010, 0x0014, 0x0853, 0x0012, 0xd042, 0x0013, 0x1031,
-	0x0013, 0x0050, 0x0012, 0x7849, 0x0003, 0x11d6, 0x0010, 0x0dfe,
-	0x0003, 0x6148, 0x0012, 0x0c10, 0x0010, 0xff0c, 0x0015, 0x0030,
-	0x0000, 0x0400, 0x0011, 0x0d88, 0x0010, 0x0003, 0x0000, 0xff31,
-	0x0015, 0x0033, 0x0000, 0xb309, 0x001b, 0x816e, 0x0010, 0xb3fe,
-	0x0013, 0x6176, 0x0010, 0xb30b, 0x0015, 0x0033, 0x0010, 0xc00a,
-	0x000b, 0x8174, 0x0013, 0x01cb, 0x0000, 0xc00b, 0x0010, 0xc00a,
-	0x0013, 0x01cb, 0x0000, 0x78b0, 0x0012, 0xb044, 0x0003, 0x11d6,
-	0x0002, 0xb049, 0x0003, 0x11d6, 0x0010, 0x71ff, 0x0012, 0xff38,
-	0x0010, 0xff71, 0x0010, 0x0dfe, 0x0013, 0x6146, 0x0012, 0x0c10,
-	0x0010, 0xff0c, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88,
-	0x0010, 0x0003, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb309,
-	0x001b, 0x818c, 0x0010, 0xb3fe, 0x0013, 0x6194, 0x0000, 0xb309,
-	0x0015, 0x0033, 0x0010, 0xc00a, 0x001b, 0x8192, 0x0013, 0x01cb,
-	0x0010, 0xc009, 0x0000, 0xc008, 0x0013, 0x01cb, 0x0000, 0x78b0,
-	0x0012, 0xb044, 0x0003, 0x11d6, 0x0002, 0xb049, 0x0003, 0x11d6,
-	0x0010, 0x71ff, 0x0012, 0xff38, 0x0010, 0xff71, 0x0010, 0x0dfe,
-	0x0013, 0x6146, 0x0012, 0x0c10, 0x0010, 0xff0c, 0x0015, 0x0030,
-	0x0000, 0x0400, 0x0011, 0x0d88, 0x0010, 0x0003, 0x0000, 0xff31,
-	0x0015, 0x0033, 0x0000, 0xb309, 0x000b, 0x81aa, 0x0010, 0xb3fe,
-	0x0003, 0x61b2, 0x0000, 0xb305, 0x0015, 0x0033, 0x0010, 0xc00a,
-	0x001b, 0x81b0, 0x0003, 0x01b4, 0x0010, 0xc005, 0x0000, 0xc004,
-	0x0002, 0x033f, 0x0002, 0xff27, 0x0000, 0x0db8, 0x0014, 0x0397,
-	0x0000, 0x0db8, 0x0004, 0x0867, 0x0015, 0x0030, 0x0000, 0x0400,
-	0x0011, 0xbc88, 0x0010, 0x0000, 0x0000, 0xff31, 0x0015, 0x0033,
-	0x0000, 0xb309, 0x001b, 0x81c1, 0x0011, 0xb3e8, 0x0000, 0x0002,
-	0x001b, 0x1146, 0x0005, 0x0002, 0x0010, 0x0005, 0x0003, 0x0148,
-	0x0012, 0x7849, 0x0003, 0x11d6, 0x0003, 0x0148, 0x0000, 0x0db8,
-	0x0012, 0x0345, 0x000b, 0x11d1, 0x0002, 0x033f, 0x0014, 0x0397,
-	0x0013, 0x0146, 0x0002, 0x033f, 0x0002, 0xff27, 0x0014, 0x0397,
-	0x0004, 0x0867, 0x0013, 0x0146, 0x0015, 0x00b8, 0x0000, 0x0001,
-	0x0015, 0x003a, 0x0010, 0x0101, 0x0004, 0x0867, 0x0013, 0x0157,
-	0x0001, 0x2bd8, 0x0010, 0x0000, 0x0000, 0xffba, 0x0003, 0xb1df,
-	0x0005, 0x002a, 0x0000, 0x0002, 0x0001, 0xbac8, 0x0000, 0x0700,
-	0x000b, 0x12cc, 0x0011, 0x15e8, 0x0000, 0x0002, 0x0013, 0x1242,
-	0x0011, 0x15e8, 0x0000, 0x0001, 0x0013, 0x11ee, 0x0005, 0x0015,
-	0x0010, 0x0000, 0x0013, 0x0225, 0x0005, 0x0015, 0x0010, 0x0000,
-	0x0002, 0xba43, 0x0003, 0x1226, 0x0003, 0xb1f2, 0x0005, 0x002a,
-	0x0000, 0x0004, 0x0012, 0xba42, 0x0003, 0x122c, 0x0012, 0x104b,
-	0x001b, 0x1225, 0x0000, 0x1a30, 0x0005, 0x0031, 0x0000, 0x0002,
-	0x0015, 0x0033, 0x0000, 0x1b2a, 0x001b, 0x81fe, 0x0011, 0x20d8,
-	0x0010, 0x0000, 0x0000, 0xffb0, 0x0001, 0x21d8, 0x0010, 0x0000,
-	0x0010, 0xffb1, 0x0001, 0x22d8, 0x0010, 0x0000, 0x0010, 0xffb2,
-	0x0011, 0x23d8, 0x0010, 0x0000, 0x0000, 0xffb3, 0x0001, 0x24d8,
-	0x0010, 0x0000, 0x0010, 0xffb4, 0x0011, 0x25d8, 0x0010, 0x0000,
-	0x0000, 0xffb5, 0x0001, 0x28d8, 0x0010, 0x0000, 0x0010, 0xffb8,
-	0x0011, 0x29d8, 0x0010, 0x0000, 0x0000, 0xffb9, 0x0000, 0x1a30,
-	0x0005, 0x0031, 0x0000, 0x0007, 0x0015, 0x0033, 0x0010, 0xb032,
-	0x001b, 0x821c, 0x0000, 0x1a30, 0x0005, 0x0031, 0x0010, 0x000f,
-	0x0015, 0x0033, 0x0010, 0xb812, 0x000b, 0x8222, 0x0005, 0x0015,
-	0x0010, 0x0000, 0x0013, 0x0035, 0x0000, 0x1efe, 0x0003, 0x623a,
-	0x0014, 0x0271, 0x0000, 0x1efe, 0x000c, 0x6271, 0x0013, 0x0225,
-	0x0000, 0x1a30, 0x0005, 0x0031, 0x0000, 0x0020, 0x0015, 0x0033,
-	0x0000, 0xb009, 0x001b, 0x8231, 0x0002, 0xb02f, 0x0000, 0xffb0,
-	0x0005, 0x0031, 0x0000, 0x0020, 0x0015, 0x0033, 0x0000, 0xb00a,
-	0x001b, 0x8238, 0x0003, 0x01f9, 0x0015, 0x00b8, 0x0010, 0x0005,
-	0x0004, 0x0867, 0x0000, 0x13b8, 0x0015, 0x003a, 0x0010, 0x0404,
-	0x0004, 0x0867, 0x0013, 0x0225, 0x0005, 0x0015, 0x0000, 0x0001,
-	0x0012, 0xba42, 0x0013, 0x1250, 0x0003, 0xb246, 0x0001, 0x2bd8,
-	0x0010, 0x0000, 0x0012, 0xff4f, 0x001b, 0x11dc, 0x0002, 0xba43,
-	0x001b, 0x122c, 0x0000, 0x1efe, 0x000c, 0x6271, 0x0013, 0x0225,
-	0x0001, 0x28d8, 0x0010, 0x0000, 0x0010, 0xffb8, 0x0011, 0x29d8,
-	0x0010, 0x0000, 0x0000, 0xffb9, 0x0014, 0x02e2, 0x0002, 0x3a42,
-	0x001b, 0x1225, 0x0000, 0x1c30, 0x0015, 0x00ff, 0x0000, 0x0002,
-	0x0002, 0x1f43, 0x001b, 0x1261, 0x0001, 0xff88, 0x0000, 0x0002,
-	0x0003, 0x0263, 0x0001, 0xff88, 0x0000, 0x0004, 0x0000, 0xff31,
-	0x0015, 0x0033, 0x0000, 0xb011, 0x000b, 0x8266, 0x0000, 0xb0ff,
-	0x0011, 0x16a0, 0x0000, 0xff16, 0x001b, 0x226d, 0x0002, 0xb100,
-	0x0013, 0x026e, 0x0010, 0xb1ff, 0x0001, 0x17a0, 0x0010, 0xff17,
-	0x0013, 0x022c, 0x0000, 0x16ff, 0x0001, 0x18a0, 0x0010, 0xff00,
-	0x000b, 0x2278, 0x0002, 0x1700, 0x0003, 0x12cb, 0x0013, 0x0279,
-	0x0010, 0x17ff, 0x0011, 0x19a0, 0x0003, 0x22cb, 0x0011, 0x00d0,
-	0x0003, 0x12cb, 0x0000, 0x1c30, 0x0000, 0x1b31, 0x0015, 0x0033,
-	0x0000, 0xb131, 0x000b, 0x8281, 0x0013, 0xb282, 0x0000, 0xb120,
-	0x0010, 0xb221, 0x0002, 0x1f43, 0x000b, 0x128e, 0x0010, 0xc022,
-	0x0000, 0xc023, 0x0000, 0xb324, 0x0000, 0xb425, 0x0010, 0xb3b5,
-	0x0000, 0xb4b6, 0x0013, 0x0292, 0x0000, 0xb322, 0x0000, 0xb423,
-	0x0000, 0xb524, 0x0010, 0xb625, 0x0003, 0xb292, 0x0005, 0x002a,
-	0x0000, 0x0001, 0x0012, 0x1500, 0x0000, 0xff15, 0x0000, 0x16ff,
-	0x0001, 0xb580, 0x0000, 0xff16, 0x001b, 0x229d, 0x0002, 0x1700,
-	0x0013, 0x029e, 0x0010, 0x17ff, 0x0001, 0xb680, 0x0010, 0xff17,
-	0x0012, 0x1e10, 0x0010, 0xff1e, 0x0013, 0x62cb, 0x0002, 0x1d00,
-	0x0010, 0xff1d, 0x0010, 0xc030, 0x0000, 0xff31, 0x0015, 0x0033,
-	0x0000, 0xb009, 0x000b, 0x82a9, 0x0010, 0xb0fe, 0x001b, 0x62ca,
-	0x0000, 0x1c30, 0x0005, 0x0031, 0x0000, 0x0001, 0x0015, 0x0033,
-	0x0000, 0xb009, 0x000b, 0x82b1, 0x0010, 0xb0fe, 0x001b, 0x62b7,
-	0x0005, 0x00ce, 0x0010, 0x0005, 0x0013, 0x0829, 0x0010, 0xb01c,
-	0x0000, 0x1c30, 0x0005, 0x0031, 0x0000, 0x0019, 0x0015, 0x0033,
-	0x0000, 0xb009, 0x000b, 0x82bd, 0x0001, 0xb0c8, 0x0010, 0x00ff,
-	0x0000, 0xff1f, 0x0010, 0xc030, 0x0011, 0xbe80, 0x0000, 0xff31,
-	0x0015, 0x0033, 0x0000, 0xb009, 0x000b, 0x82c6, 0x0000, 0xb01d,
-	0x0010, 0x1dff, 0x0003, 0x02a5, 0x0000, 0xb01b, 0x0017, 0x4000,
-	0x0002, 0x3a41, 0x0013, 0x12d4, 0x0003, 0xb2ce, 0x0005, 0x002a,
-	0x0000, 0x0004, 0x0005, 0x0015, 0x0010, 0x0000, 0x0013, 0x0225,
+	0x0010, 0x0f59, 0x001b, 0x8129, 0x0017, 0x4000, 0x0015, 0x0030,
+	0x0000, 0x0400, 0x0001, 0xbb88, 0x0010, 0x000f, 0x0000, 0xff31,
+	0x0015, 0x0033, 0x0010, 0x0f5a, 0x001b, 0x8132, 0x0017, 0x4000,
+	0x0000, 0xd0ff, 0x0012, 0xff40, 0x000b, 0x1031, 0x0015, 0x00d1,
+	0x0010, 0x0101, 0x0003, 0x9139, 0x0005, 0x0079, 0x0000, 0x0001,
+	0x0003, 0x913c, 0x0015, 0x00d1, 0x0000, 0x0100, 0x0011, 0x02e8,
+	0x0000, 0x0002, 0x0003, 0x1164, 0x0011, 0x02e8, 0x0000, 0x0001,
+	0x0003, 0x117c, 0x0011, 0x02e8, 0x0000, 0x0004, 0x0013, 0x119a,
+	0x0011, 0x02e8, 0x0010, 0x0003, 0x0003, 0x11cb, 0x0005, 0x0002,
+	0x0010, 0x0000, 0x0000, 0xc00e, 0x0000, 0xc00d, 0x0010, 0xc003,
+	0x0015, 0x0030, 0x0000, 0x0400, 0x0001, 0xbd88, 0x0010, 0x0009,
+	0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xc00a, 0x001b, 0x8157,
+	0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xc00a, 0x001b, 0x815b,
+	0x0012, 0x3a45, 0x0013, 0x1163, 0x0015, 0x003a, 0x0000, 0x2000,
+	0x0015, 0x003a, 0x0010, 0x1010, 0x0014, 0x090b, 0x0003, 0x004f,
+	0x0012, 0x7849, 0x0003, 0x11d9, 0x0010, 0x0dfe, 0x0003, 0x614d,
+	0x0012, 0x0c10, 0x0010, 0xff0c, 0x0015, 0x0030, 0x0000, 0x0400,
+	0x0011, 0x0d88, 0x0010, 0x0003, 0x0000, 0xff31, 0x0015, 0x0033,
+	0x0000, 0xb309, 0x000b, 0x8171, 0x0010, 0xb3fe, 0x0013, 0x6179,
+	0x0010, 0xb30b, 0x0015, 0x0033, 0x0010, 0xc00a, 0x000b, 0x8177,
+	0x0013, 0x01ce, 0x0000, 0xc00b, 0x0010, 0xc00a, 0x0013, 0x01ce,
+	0x0000, 0x78b0, 0x0012, 0xb044, 0x0003, 0x11d9, 0x0002, 0xb049,
+	0x0003, 0x11d9, 0x0010, 0x71ff, 0x0012, 0xff38, 0x0010, 0xff71,
+	0x0010, 0x0dfe, 0x0003, 0x614b, 0x0012, 0x0c10, 0x0010, 0xff0c,
+	0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88, 0x0010, 0x0003,
+	0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb309, 0x001b, 0x818f,
+	0x0010, 0xb3fe, 0x0013, 0x6197, 0x0000, 0xb309, 0x0015, 0x0033,
+	0x0010, 0xc00a, 0x000b, 0x8195, 0x0013, 0x01ce, 0x0010, 0xc009,
+	0x0000, 0xc008, 0x0013, 0x01ce, 0x0000, 0x78b0, 0x0012, 0xb044,
+	0x0003, 0x11d9, 0x0002, 0xb049, 0x0003, 0x11d9, 0x0010, 0x71ff,
+	0x0012, 0xff38, 0x0010, 0xff71, 0x0010, 0x0dfe, 0x0003, 0x614b,
+	0x0012, 0x0c10, 0x0010, 0xff0c, 0x0015, 0x0030, 0x0000, 0x0400,
+	0x0011, 0x0d88, 0x0010, 0x0003, 0x0000, 0xff31, 0x0015, 0x0033,
+	0x0000, 0xb309, 0x001b, 0x81ad, 0x0010, 0xb3fe, 0x0013, 0x61b5,
+	0x0000, 0xb305, 0x0015, 0x0033, 0x0010, 0xc00a, 0x001b, 0x81b3,
+	0x0003, 0x01b7, 0x0010, 0xc005, 0x0000, 0xc004, 0x0002, 0x033f,
+	0x0002, 0xff27, 0x0000, 0x0db8, 0x0014, 0x03bc, 0x0000, 0x0db8,
+	0x0014, 0x091f, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0xbc88,
+	0x0010, 0x0000, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb309,
+	0x001b, 0x81c4, 0x0011, 0xb3e8, 0x0000, 0x0002, 0x000b, 0x114b,
+	0x0005, 0x0002, 0x0010, 0x0005, 0x0003, 0x014d, 0x0012, 0x7849,
+	0x0003, 0x11d9, 0x0003, 0x014d, 0x0000, 0x0db8, 0x0012, 0x0345,
+	0x000b, 0x11d4, 0x0002, 0x033f, 0x0014, 0x03bc, 0x0003, 0x014b,
+	0x0002, 0x033f, 0x0002, 0xff27, 0x0014, 0x03bc, 0x0014, 0x091f,
+	0x0003, 0x014b, 0x0015, 0x00b8, 0x0000, 0x0001, 0x0015, 0x003a,
+	0x0010, 0x0101, 0x0014, 0x091f, 0x0003, 0x015c, 0x0001, 0x2bd8,
+	0x0010, 0x0000, 0x0000, 0xffba, 0x0013, 0xb1e2, 0x0005, 0x002a,
+	0x0000, 0x0002, 0x0001, 0xbac8, 0x0000, 0x0700, 0x000b, 0x12cf,
+	0x0011, 0x15e8, 0x0000, 0x0002, 0x0003, 0x1245, 0x0011, 0x15e8,
+	0x0000, 0x0001, 0x0003, 0x11f1, 0x0005, 0x0015, 0x0010, 0x0000,
+	0x0003, 0x0228, 0x0005, 0x0015, 0x0010, 0x0000, 0x0002, 0xba43,
+	0x0003, 0x1229, 0x0013, 0xb1f5, 0x0005, 0x002a, 0x0000, 0x0004,
+	0x0012, 0xba42, 0x0003, 0x122f, 0x0012, 0x104b, 0x000b, 0x1228,
 	0x0000, 0x1a30, 0x0005, 0x0031, 0x0000, 0x0002, 0x0015, 0x0033,
-	0x0000, 0x1b2a, 0x001b, 0x82d9, 0x0015, 0x00b8, 0x0000, 0x0004,
-	0x0004, 0x0867, 0x0000, 0x13b8, 0x0015, 0x003a, 0x0010, 0x0404,
-	0x0004, 0x0867, 0x0013, 0x0039, 0x0002, 0x1e00, 0x0010, 0xff1e,
-	0x0012, 0x1d10, 0x0010, 0xff1d, 0x0010, 0xc030, 0x0000, 0xff31,
-	0x0015, 0x0033, 0x0000, 0xb009, 0x001b, 0x82ea, 0x0010, 0xb0fe,
-	0x000b, 0x630f, 0x0000, 0x1cff, 0x0001, 0x1ae0, 0x0013, 0x12f9,
-	0x0000, 0x1c30, 0x0005, 0x0031, 0x0010, 0x0000, 0x0015, 0x0033,
-	0x0000, 0xb009, 0x000b, 0x82f5, 0x0010, 0xb0fe, 0x001b, 0x62f9,
-	0x0000, 0x1aff, 0x0000, 0xff1c, 0x0000, 0x1c30, 0x0005, 0x0031,
-	0x0000, 0x0019, 0x0015, 0x0033, 0x0000, 0xb009, 0x000b, 0x82ff,
-	0x0001, 0xb0c8, 0x0010, 0x000f, 0x0000, 0xff1f, 0x0001, 0xbf80,
+	0x0000, 0x1b2a, 0x001b, 0x8201, 0x0011, 0x20d8, 0x0010, 0x0000,
+	0x0000, 0xffb0, 0x0001, 0x21d8, 0x0010, 0x0000, 0x0010, 0xffb1,
+	0x0001, 0x22d8, 0x0010, 0x0000, 0x0010, 0xffb2, 0x0011, 0x23d8,
+	0x0010, 0x0000, 0x0000, 0xffb3, 0x0001, 0x24d8, 0x0010, 0x0000,
+	0x0010, 0xffb4, 0x0011, 0x25d8, 0x0010, 0x0000, 0x0000, 0xffb5,
+	0x0001, 0x28d8, 0x0010, 0x0000, 0x0010, 0xffb8, 0x0011, 0x29d8,
+	0x0010, 0x0000, 0x0000, 0xffb9, 0x0000, 0x1a30, 0x0005, 0x0031,
+	0x0000, 0x0007, 0x0015, 0x0033, 0x0010, 0xb032, 0x001b, 0x821f,
+	0x0000, 0x1a30, 0x0005, 0x0031, 0x0010, 0x000f, 0x0015, 0x0033,
+	0x0010, 0xb812, 0x001b, 0x8225, 0x0005, 0x0015, 0x0010, 0x0000,
+	0x0013, 0x0035, 0x0000, 0x1efe, 0x0013, 0x623d, 0x0014, 0x0274,
+	0x0000, 0x1efe, 0x000c, 0x6274, 0x0003, 0x0228, 0x0000, 0x1a30,
+	0x0005, 0x0031, 0x0000, 0x0020, 0x0015, 0x0033, 0x0000, 0xb009,
+	0x001b, 0x8234, 0x0002, 0xb02f, 0x0000, 0xffb0, 0x0005, 0x0031,
+	0x0000, 0x0020, 0x0015, 0x0033, 0x0000, 0xb00a, 0x001b, 0x823b,
+	0x0003, 0x01fc, 0x0015, 0x00b8, 0x0010, 0x0005, 0x0014, 0x091f,
+	0x0000, 0x13b8, 0x0015, 0x003a, 0x0010, 0x0404, 0x0014, 0x091f,
+	0x0003, 0x0228, 0x0005, 0x0015, 0x0000, 0x0001, 0x0012, 0xba42,
+	0x0013, 0x1253, 0x0003, 0xb249, 0x0001, 0x2bd8, 0x0010, 0x0000,
+	0x0012, 0xff4f, 0x001b, 0x11df, 0x0002, 0xba43, 0x001b, 0x122f,
+	0x0000, 0x1efe, 0x000c, 0x6274, 0x0003, 0x0228, 0x0001, 0x28d8,
+	0x0010, 0x0000, 0x0010, 0xffb8, 0x0011, 0x29d8, 0x0010, 0x0000,
+	0x0000, 0xffb9, 0x0004, 0x02e5, 0x0002, 0x3a42, 0x000b, 0x1228,
+	0x0000, 0x1c30, 0x0015, 0x00ff, 0x0000, 0x0002, 0x0002, 0x1f43,
+	0x001b, 0x1264, 0x0001, 0xff88, 0x0000, 0x0002, 0x0003, 0x0266,
+	0x0001, 0xff88, 0x0000, 0x0004, 0x0000, 0xff31, 0x0015, 0x0033,
+	0x0000, 0xb011, 0x000b, 0x8269, 0x0000, 0xb0ff, 0x0011, 0x16a0,
+	0x0000, 0xff16, 0x001b, 0x2270, 0x0002, 0xb100, 0x0003, 0x0271,
+	0x0010, 0xb1ff, 0x0001, 0x17a0, 0x0010, 0xff17, 0x0013, 0x022f,
+	0x0000, 0x16ff, 0x0001, 0x18a0, 0x0010, 0xff00, 0x000b, 0x227b,
+	0x0002, 0x1700, 0x0003, 0x12ce, 0x0013, 0x027c, 0x0010, 0x17ff,
+	0x0011, 0x19a0, 0x0003, 0x22ce, 0x0011, 0x00d0, 0x0003, 0x12ce,
+	0x0000, 0x1c30, 0x0000, 0x1b31, 0x0015, 0x0033, 0x0000, 0xb131,
+	0x000b, 0x8284, 0x0003, 0xb285, 0x0000, 0xb120, 0x0010, 0xb221,
+	0x0002, 0x1f43, 0x001b, 0x1291, 0x0010, 0xc022, 0x0000, 0xc023,
+	0x0000, 0xb324, 0x0000, 0xb425, 0x0010, 0xb3b5, 0x0000, 0xb4b6,
+	0x0003, 0x0295, 0x0000, 0xb322, 0x0000, 0xb423, 0x0000, 0xb524,
+	0x0010, 0xb625, 0x0013, 0xb295, 0x0005, 0x002a, 0x0000, 0x0001,
+	0x0012, 0x1500, 0x0000, 0xff15, 0x0000, 0x16ff, 0x0001, 0xb580,
+	0x0000, 0xff16, 0x000b, 0x22a0, 0x0002, 0x1700, 0x0013, 0x02a1,
+	0x0010, 0x17ff, 0x0001, 0xb680, 0x0010, 0xff17, 0x0012, 0x1e10,
+	0x0010, 0xff1e, 0x0013, 0x62ce, 0x0002, 0x1d00, 0x0010, 0xff1d,
+	0x0010, 0xc030, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009,
+	0x000b, 0x82ac, 0x0010, 0xb0fe, 0x000b, 0x62cd, 0x0000, 0x1c30,
+	0x0005, 0x0031, 0x0000, 0x0001, 0x0015, 0x0033, 0x0000, 0xb009,
+	0x000b, 0x82b4, 0x0010, 0xb0fe, 0x000b, 0x62ba, 0x0005, 0x00ce,
+	0x0010, 0x0005, 0x0003, 0x08e1, 0x0010, 0xb01c, 0x0000, 0x1c30,
+	0x0005, 0x0031, 0x0000, 0x0019, 0x0015, 0x0033, 0x0000, 0xb009,
+	0x000b, 0x82c0, 0x0001, 0xb0c8, 0x0010, 0x00ff, 0x0000, 0xff1f,
+	0x0010, 0xc030, 0x0011, 0xbe80, 0x0000, 0xff31, 0x0015, 0x0033,
+	0x0000, 0xb009, 0x000b, 0x82c9, 0x0000, 0xb01d, 0x0010, 0x1dff,
+	0x0013, 0x02a8, 0x0000, 0xb01b, 0x0017, 0x4000, 0x0002, 0x3a41,
+	0x0013, 0x12d7, 0x0013, 0xb2d1, 0x0005, 0x002a, 0x0000, 0x0004,
+	0x0005, 0x0015, 0x0010, 0x0000, 0x0003, 0x0228, 0x0000, 0x1a30,
+	0x0005, 0x0031, 0x0000, 0x0002, 0x0015, 0x0033, 0x0000, 0x1b2a,
+	0x001b, 0x82dc, 0x0015, 0x00b8, 0x0000, 0x0004, 0x0014, 0x091f,
+	0x0000, 0x13b8, 0x0015, 0x003a, 0x0010, 0x0404, 0x0014, 0x091f,
+	0x0013, 0x0039, 0x0002, 0x1e00, 0x0010, 0xff1e, 0x0012, 0x1d10,
 	0x0010, 0xff1d, 0x0010, 0xc030, 0x0000, 0xff31, 0x0015, 0x0033,
-	0x0000, 0xb009, 0x001b, 0x8309, 0x0010, 0xb0fe, 0x000b, 0x630f,
-	0x0005, 0x00ce, 0x0010, 0x0006, 0x0013, 0x0829, 0x0000, 0xb01b,
-	0x0017, 0x4000, 0x0010, 0x79b0, 0x0000, 0xd0ff, 0x0012, 0xff40,
-	0x001b, 0x1039, 0x0015, 0x00d1, 0x0010, 0x0101, 0x0013, 0x9317,
-	0x0005, 0x0079, 0x0000, 0x0002, 0x0003, 0x931a, 0x0015, 0x00d1,
-	0x0000, 0x0100, 0x0010, 0x13fe, 0x0003, 0x634f, 0x0012, 0xb04e,
-	0x001b, 0x136f, 0x0012, 0x784a, 0x0013, 0x1375, 0x0000, 0x75ff,
-	0x0011, 0xffc8, 0x0010, 0x1800, 0x000b, 0x1375, 0x0001, 0x0fe8,
-	0x0000, 0x0001, 0x001b, 0x1333, 0x0015, 0x0030, 0x0000, 0x0400,
-	0x0011, 0x1388, 0x0000, 0x000e, 0x0000, 0xff31, 0x0015, 0x0033,
-	0x0000, 0x8f0a, 0x000b, 0x8331, 0x0013, 0x037b, 0x0001, 0x0fe8,
-	0x0000, 0x0002, 0x000b, 0x133e, 0x0015, 0x0030, 0x0000, 0x0400,
-	0x0005, 0x0031, 0x0000, 0x001a, 0x0015, 0x0033, 0x0010, 0xc00a,
-	0x001b, 0x833c, 0x0013, 0x037b, 0x0001, 0x0fe8, 0x0010, 0x0000,
-	0x0013, 0x1345, 0x0005, 0x00ce, 0x0000, 0x0007, 0x0010, 0x0fcf,
-	0x0013, 0x0823, 0x0000, 0x13b8, 0x0002, 0x1045, 0x0003, 0x134d,
-	0x0012, 0x103f, 0x0002, 0xff27, 0x0014, 0x0397, 0x0004, 0x0867,
-	0x0003, 0x034f, 0x0012, 0x103f, 0x0014, 0x0397, 0x0015, 0x000f,
-	0x0010, 0x0000, 0x0002, 0x3944, 0x0013, 0x1358, 0x0015, 0x0039,
-	0x0000, 0x5040, 0x0015, 0x00b8, 0x0000, 0x0008, 0x0004, 0x0867,
+	0x0000, 0xb009, 0x000b, 0x82ed, 0x0010, 0xb0fe, 0x000b, 0x6312,
+	0x0000, 0x1cff, 0x0001, 0x1ae0, 0x0013, 0x12fc, 0x0000, 0x1c30,
+	0x0005, 0x0031, 0x0010, 0x0000, 0x0015, 0x0033, 0x0000, 0xb009,
+	0x001b, 0x82f8, 0x0010, 0xb0fe, 0x001b, 0x62fc, 0x0000, 0x1aff,
+	0x0000, 0xff1c, 0x0000, 0x1c30, 0x0005, 0x0031, 0x0000, 0x0019,
+	0x0015, 0x0033, 0x0000, 0xb009, 0x000b, 0x8302, 0x0001, 0xb0c8,
+	0x0010, 0x000f, 0x0000, 0xff1f, 0x0001, 0xbf80, 0x0010, 0xff1d,
+	0x0010, 0xc030, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009,
+	0x001b, 0x830c, 0x0010, 0xb0fe, 0x000b, 0x6312, 0x0005, 0x00ce,
+	0x0010, 0x0006, 0x0003, 0x08e1, 0x0000, 0xb01b, 0x0017, 0x4000,
+	0x0010, 0x79b0, 0x0000, 0xd0ff, 0x0012, 0xff40, 0x001b, 0x1039,
+	0x0015, 0x00d1, 0x0010, 0x0101, 0x0003, 0x931a, 0x0005, 0x0079,
+	0x0000, 0x0002, 0x0013, 0x931d, 0x0015, 0x00d1, 0x0000, 0x0100,
+	0x0010, 0x13fe, 0x0003, 0x636b, 0x0012, 0xb04e, 0x000b, 0x1394,
+	0x0000, 0x78b0, 0x0002, 0xb045, 0x0003, 0x139a, 0x0012, 0x784a,
+	0x0003, 0x139a, 0x0000, 0x75ff, 0x0011, 0xffc8, 0x0010, 0x1800,
+	0x001b, 0x139a, 0x0001, 0x0fe8, 0x0000, 0x0001, 0x001b, 0x1339,
+	0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x1388, 0x0000, 0x000e,
+	0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0x8f0a, 0x000b, 0x8337,
+	0x0013, 0x03a0, 0x0001, 0x0fe8, 0x0000, 0x0002, 0x001b, 0x1344,
+	0x0015, 0x0030, 0x0000, 0x0400, 0x0005, 0x0031, 0x0000, 0x001a,
+	0x0015, 0x0033, 0x0010, 0xc00a, 0x001b, 0x8342, 0x0013, 0x03a0,
+	0x0001, 0x0fe8, 0x0010, 0x0000, 0x0003, 0x134b, 0x0005, 0x00ce,
+	0x0000, 0x0007, 0x0010, 0x0fcf, 0x0003, 0x08db, 0x0002, 0xd142,
+	0x0013, 0x1361, 0x0015, 0x00d1, 0x0000, 0x0400, 0x0005, 0x0031,
+	0x0011, 0x1b6e, 0x0015, 0x0033, 0x0010, 0xb409, 0x001b, 0x8353,
+	0x0002, 0xb400, 0x0010, 0xffb4, 0x0005, 0x0031, 0x0011, 0x1b6e,
+	0x0015, 0x0033, 0x0010, 0xb40a, 0x001b, 0x835a, 0x0012, 0xd042,
+	0x0013, 0x136b, 0x0015, 0x00b8, 0x0000, 0x000d, 0x0014, 0x091f,
+	0x0003, 0x0054, 0x0000, 0x13b8, 0x0002, 0x1045, 0x0003, 0x1369,
+	0x0012, 0x103f, 0x0002, 0xff27, 0x0014, 0x03bc, 0x0014, 0x091f,
+	0x0003, 0x036b, 0x0012, 0x103f, 0x0014, 0x03bc, 0x0015, 0x000f,
+	0x0010, 0x0000, 0x0002, 0x3944, 0x0003, 0x1374, 0x0015, 0x0039,
+	0x0000, 0x5040, 0x0015, 0x00b8, 0x0000, 0x0008, 0x0014, 0x091f,
 	0x0015, 0x0030, 0x0000, 0x0400, 0x0001, 0xbd88, 0x0010, 0x000c,
-	0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xc00a, 0x001b, 0x835f,
-	0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xc00a, 0x001b, 0x8363,
-	0x0010, 0xc014, 0x0000, 0xc013, 0x0000, 0xc010, 0x0002, 0x3a47,
-	0x0013, 0x136e, 0x0015, 0x003a, 0x0000, 0x8000, 0x0015, 0x003a,
-	0x0010, 0x4040, 0x0014, 0x082e, 0x0013, 0x0039, 0x0015, 0x00b8,
-	0x0010, 0x0003, 0x0015, 0x003a, 0x0010, 0x0202, 0x0004, 0x0867,
-	0x0003, 0x0367, 0x0015, 0x00b8, 0x0000, 0x0002, 0x0015, 0x003a,
-	0x0010, 0x0202, 0x0004, 0x0867, 0x0003, 0x0367, 0x0015, 0x0030,
-	0x0000, 0x0400, 0x0011, 0x1388, 0x0010, 0x0003, 0x0000, 0xff31,
-	0x0015, 0x0033, 0x0000, 0xb009, 0x001b, 0x8382, 0x0011, 0x1388,
-	0x0010, 0x0003, 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xc00a,
-	0x001b, 0x8388, 0x0010, 0xb0fe, 0x0013, 0x638d, 0x0000, 0xb012,
-	0x0003, 0x038f, 0x0010, 0xc012, 0x0010, 0xc011, 0x0012, 0x104b,
-	0x0013, 0x1345, 0x0002, 0x103b, 0x0010, 0xff03, 0x0005, 0x0002,
-	0x0010, 0x0000, 0x0000, 0xc00d, 0x0003, 0x0345, 0x0000, 0xffb0,
-	0x0010, 0xc3b1, 0x0015, 0x0030, 0x0000, 0x0400, 0x0001, 0xb888,
-	0x0010, 0x0011, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb012,
-	0x001b, 0x83a0, 0x0017, 0x4000, 0x0012, 0x3a43, 0x0003, 0x13b1,
-	0x0015, 0x003a, 0x0000, 0x0800, 0x0010, 0x0db0, 0x0013, 0x63b1,
-	0x0000, 0x0bff, 0x0001, 0xb0e0, 0x0013, 0x13da, 0x0010, 0x09ff,
-	0x0001, 0xb0e0, 0x0003, 0x13be, 0x0010, 0x05ff, 0x0001, 0xb0e0,
-	0x0013, 0x13b5, 0x0000, 0xc00e, 0x0000, 0x05fe, 0x0013, 0x63bb,
-	0x0000, 0x050d, 0x0005, 0x0002, 0x0000, 0x0004, 0x0014, 0x043c,
-	0x0002, 0x3a47, 0x001b, 0x143b, 0x0003, 0x03d5, 0x0000, 0x09fe,
-	0x0013, 0x63d7, 0x0000, 0x090d, 0x0005, 0x0002, 0x0000, 0x0001,
-	0x0014, 0x0455, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88,
-	0x0000, 0x0004, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xba09,
-	0x000b, 0x83c8, 0x0011, 0x03c8, 0x0010, 0x000f, 0x0000, 0xffb6,
-	0x0011, 0xb6e8, 0x0000, 0x0001, 0x0003, 0x14ec, 0x0011, 0xb6e8,
-	0x0000, 0x0002, 0x0013, 0x150e, 0x0011, 0xb6e8, 0x0010, 0x0003,
-	0x0013, 0x15fd, 0x0014, 0x082e, 0x0013, 0x043b, 0x0010, 0x0bfe,
-	0x0013, 0x643b, 0x0010, 0x0b0d, 0x0005, 0x0002, 0x0000, 0x0002,
-	0x0014, 0x0455, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88,
-	0x0000, 0x0004, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xba09,
-	0x001b, 0x83e4, 0x0000, 0xb930, 0x0005, 0x0031, 0x0010, 0x0021,
-	0x0015, 0x0033, 0x0000, 0xb009, 0x000b, 0x83ea, 0x0001, 0xb0a8,
-	0x0000, 0x199a, 0x0003, 0x23f0, 0x0005, 0x00b0, 0x0000, 0x1999,
-	0x0012, 0xb050, 0x0000, 0xffb0, 0x0002, 0xff50, 0x0002, 0xff50,
-	0x0001, 0xb080, 0x0000, 0xffb0, 0x0015, 0x0030, 0x0000, 0x0400,
-	0x0011, 0x0d88, 0x0010, 0x0006, 0x0000, 0xff31, 0x0015, 0x0033,
-	0x0000, 0xb00a, 0x000b, 0x83fd, 0x0000, 0xb930, 0x0005, 0x0031,
-	0x0000, 0x0019, 0x0015, 0x0033, 0x0000, 0xb009, 0x000b, 0x8403,
-	0x0001, 0xb0c8, 0x0010, 0x00ff, 0x0001, 0xffe8, 0x0010, 0x0048,
-	0x001b, 0x1464, 0x0005, 0x0002, 0x0010, 0x0006, 0x0012, 0x0c10,
-	0x0010, 0xff0c, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88,
-	0x0010, 0x0003, 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xb109,
-	0x000b, 0x8414, 0x0000, 0xb10b, 0x001b, 0x6418, 0x0010, 0xb10a,
-	0x0015, 0x0033, 0x0010, 0xc00a, 0x001b, 0x841a, 0x0002, 0x032b,
-	0x0010, 0xff03, 0x0011, 0x0d88, 0x0010, 0x0011, 0x0000, 0xff31,
-	0x0015, 0x0033, 0x0010, 0x030a, 0x000b, 0x8422, 0x0000, 0x11fe,
-	0x001b, 0x6427, 0x0000, 0x0d12, 0x0003, 0x0430, 0x0015, 0x0030,
-	0x0000, 0x0400, 0x0001, 0x1188, 0x0010, 0x0003, 0x0000, 0xff31,
-	0x0010, 0x0db0, 0x0015, 0x0033, 0x0000, 0xb00a, 0x001b, 0x842f,
-	0x0000, 0x0d11, 0x0013, 0x043b, 0x0000, 0x05fe, 0x0013, 0x643b,
-	0x0005, 0x0002, 0x0000, 0x0004, 0x0000, 0x050d, 0x0014, 0x043c,
-	0x0002, 0x3a47, 0x001b, 0x143b, 0x0014, 0x082e, 0x0003, 0x0049,
-	0x0001, 0xc7c8, 0x0010, 0x0028, 0x001b, 0x1454, 0x0015, 0x0030,
-	0x0000, 0x0400, 0x0011, 0x0d88, 0x0010, 0x000a, 0x0000, 0xff31,
-	0x0015, 0x0033, 0x0000, 0xb009, 0x001b, 0x8446, 0x0002, 0xb04f,
-	0x0003, 0x1454, 0x0001, 0x0fe8, 0x0010, 0x0000, 0x0003, 0x1452,
-	0x0001, 0x0fe8, 0x0000, 0x0002, 0x0003, 0x1452, 0x0015, 0x003a,
-	0x0010, 0x8080, 0x0013, 0x0454, 0x0015, 0x003a, 0x0010, 0x4040,
-	0x0017, 0x4000, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88,
-	0x0010, 0x0011, 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0x0309,
-	0x000b, 0x845c, 0x0011, 0x0d88, 0x0010, 0x0005, 0x0000, 0xff31,
-	0x0015, 0x0033, 0x0000, 0xb909, 0x001b, 0x8462, 0x0017, 0x4000,
-	0x0005, 0x00b6, 0x0010, 0x0600, 0x0004, 0x062d, 0x0004, 0x04d6,
-	0x0000, 0xb05a, 0x0000, 0xb15b, 0x0005, 0x0054, 0x0010, 0x0829,
-	0x0010, 0x0d58, 0x0015, 0x0059, 0x0010, 0xffff, 0x0000, 0xb930,
-	0x0005, 0x0031, 0x0010, 0x001e, 0x0015, 0x0033, 0x0000, 0xb009,
-	0x000b, 0x8474, 0x0000, 0xb05c, 0x0005, 0x0031, 0x0000, 0x001f,
-	0x0015, 0x0033, 0x0000, 0xb009, 0x001b, 0x847a, 0x0001, 0xb0c8,
-	0x0010, 0x000f, 0x000b, 0x1481, 0x0015, 0x00ff, 0x0010, 0x0005,
-	0x0013, 0x0489, 0x0002, 0xb040, 0x0003, 0x1486, 0x0015, 0x00ff,
-	0x0000, 0x0004, 0x0013, 0x0489, 0x0001, 0xb0c8, 0x0010, 0x0006,
-	0x0002, 0xff60, 0x0010, 0xffb2, 0x0015, 0x0030, 0x0000, 0x0400,
-	0x0011, 0x0d88, 0x0000, 0x0019, 0x0000, 0xff31, 0x0015, 0x0033,
-	0x0010, 0xb109, 0x001b, 0x8491, 0x0012, 0xb170, 0x0011, 0xffc8,
-	0x0010, 0xff00, 0x0011, 0xb2d0, 0x0010, 0xff60, 0x0002, 0xb045,
-	0x0013, 0x149c, 0x0015, 0x00b2, 0x0000, 0x0002, 0x0003, 0x04a6,
-	0x0002, 0xb046, 0x0003, 0x14a1, 0x0015, 0x00b2, 0x0000, 0x0001,
-	0x0003, 0x04a6, 0x0015, 0x00b2, 0x0010, 0x0000, 0x0000, 0xc0b0,
-	0x0010, 0xc0b1, 0x0003, 0x04ac, 0x0000, 0xb930, 0x0005, 0x0031,
-	0x0010, 0x002b, 0x0015, 0x0033, 0x0000, 0xb011, 0x001b, 0x84ab,
-	0x0010, 0xb16a, 0x0010, 0xb06b, 0x0000, 0xb261, 0x0015, 0x0044,
-	0x0010, 0x0018, 0x0000, 0xb930, 0x0005, 0x0031, 0x0000, 0x0023,
-	0x0015, 0x0033, 0x0000, 0x6241, 0x001b, 0x84b6, 0x0003, 0x94b7,
-	0x0015, 0x00a0, 0x0000, 0x0020, 0x0012, 0xd041, 0x001b, 0x14ba,
-	0x0015, 0x00d1, 0x0010, 0x0202, 0x0003, 0x94be, 0x0000, 0x75ff,
-	0x0011, 0xffc8, 0x0000, 0x1804, 0x0001, 0xffd8, 0x0010, 0x0009,
-	0x0013, 0x94c4, 0x0000, 0xff75, 0x0003, 0x94c6, 0x0015, 0x00d1,
-	0x0000, 0x0200, 0x0015, 0x0030, 0x0000, 0x0400, 0x0001, 0xbd88,
-	0x0000, 0x0008, 0x0000, 0xff31, 0x0015, 0x00b1, 0x0010, 0x07d0,
-	0x0005, 0x00b0, 0x0010, 0x0009, 0x0015, 0x0033, 0x0000, 0xb012,
-	0x000b, 0x84d4, 0x0013, 0x043b, 0x0000, 0xba30, 0x0005, 0x0031,
-	0x0010, 0x0035, 0x0015, 0x0033, 0x0000, 0xb009, 0x000b, 0x84db,
-	0x0002, 0xb040, 0x0003, 0x14e9, 0x0010, 0xb9b0, 0x0010, 0xb7b1,
-	0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88, 0x0000, 0x0013,
-	0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb012, 0x000b, 0x84e7,
-	0x0003, 0x04eb, 0x0010, 0xc0b1, 0x0000, 0xc0b0, 0x0017, 0x4000,
-	0x0005, 0x00b6, 0x0010, 0x0500, 0x0004, 0x062d, 0x0005, 0x0054,
-	0x0010, 0x0889, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88,
+	0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xc00a, 0x001b, 0x837b,
+	0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xc00a, 0x000b, 0x837f,
+	0x0010, 0xc014, 0x0000, 0xc013, 0x0000, 0xc010, 0x0000, 0xa4ff,
+	0x0003, 0x638c, 0x0011, 0xffa8, 0x0010, 0x0005, 0x000b, 0x238c,
+	0x0015, 0x00d1, 0x0010, 0x0404, 0x0015, 0x003a, 0x0000, 0x8000,
+	0x0002, 0x3a47, 0x0003, 0x1393, 0x0015, 0x003a, 0x0000, 0x8000,
+	0x0015, 0x003a, 0x0010, 0x4040, 0x0004, 0x08e6, 0x0013, 0x0039,
+	0x0015, 0x00b8, 0x0010, 0x0003, 0x0015, 0x003a, 0x0010, 0x0202,
+	0x0014, 0x091f, 0x0003, 0x0383, 0x0015, 0x00b8, 0x0000, 0x0002,
+	0x0015, 0x003a, 0x0010, 0x0202, 0x0014, 0x091f, 0x0003, 0x0383,
+	0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x1388, 0x0010, 0x0003,
+	0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009, 0x000b, 0x83a7,
+	0x0011, 0x1388, 0x0010, 0x0003, 0x0000, 0xff31, 0x0015, 0x0033,
+	0x0010, 0xc00a, 0x000b, 0x83ad, 0x0010, 0xb0fe, 0x0013, 0x63b2,
+	0x0000, 0xb012, 0x0013, 0x03b4, 0x0010, 0xc012, 0x0010, 0xc011,
+	0x0012, 0x104b, 0x0003, 0x134b, 0x0002, 0x103b, 0x0010, 0xff03,
+	0x0005, 0x0002, 0x0010, 0x0000, 0x0000, 0xc00d, 0x0013, 0x034b,
+	0x0000, 0xffb0, 0x0010, 0xc3b1, 0x0015, 0x0030, 0x0000, 0x0400,
+	0x0001, 0xb888, 0x0010, 0x0011, 0x0000, 0xff31, 0x0015, 0x0033,
+	0x0000, 0xb012, 0x001b, 0x83c5, 0x0017, 0x4000, 0x0002, 0xd142,
+	0x001b, 0x147f, 0x0012, 0x3a43, 0x0003, 0x13d8, 0x0015, 0x003a,
+	0x0000, 0x0800, 0x0010, 0x0db0, 0x0013, 0x63d8, 0x0000, 0x0bff,
+	0x0001, 0xb0e0, 0x0003, 0x1401, 0x0010, 0x09ff, 0x0001, 0xb0e0,
+	0x0013, 0x13e5, 0x0010, 0x05ff, 0x0001, 0xb0e0, 0x0013, 0x13dc,
+	0x0000, 0xc00e, 0x0000, 0x05fe, 0x0013, 0x63e2, 0x0000, 0x050d,
+	0x0005, 0x0002, 0x0000, 0x0004, 0x0014, 0x0466, 0x0002, 0x3a47,
+	0x000b, 0x1465, 0x0013, 0x03fc, 0x0000, 0x09fe, 0x0003, 0x63fe,
+	0x0000, 0x090d, 0x0005, 0x0002, 0x0000, 0x0001, 0x0004, 0x0494,
+	0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88, 0x0000, 0x0004,
+	0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xba09, 0x000b, 0x83ef,
+	0x0011, 0x03c8, 0x0010, 0x000f, 0x0000, 0xffb6, 0x0011, 0xb6e8,
+	0x0000, 0x0001, 0x0003, 0x1539, 0x0011, 0xb6e8, 0x0000, 0x0002,
+	0x0013, 0x155b, 0x0011, 0xb6e8, 0x0010, 0x0003, 0x0003, 0x164d,
+	0x0004, 0x08e6, 0x0003, 0x0465, 0x0010, 0x0bfe, 0x0003, 0x6465,
+	0x0010, 0x0b0d, 0x0005, 0x0002, 0x0000, 0x0002, 0x0004, 0x0494,
+	0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88, 0x0000, 0x0004,
+	0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xba09, 0x001b, 0x840b,
+	0x0000, 0xb930, 0x0005, 0x0031, 0x0010, 0x0021, 0x0015, 0x0033,
+	0x0000, 0xb009, 0x000b, 0x8411, 0x0001, 0xb0a8, 0x0000, 0x199a,
+	0x0013, 0x2417, 0x0005, 0x00b0, 0x0000, 0x1999, 0x0012, 0xb050,
+	0x0000, 0xffb0, 0x0002, 0xff50, 0x0002, 0xff50, 0x0001, 0xb080,
+	0x0000, 0xffb0, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88,
+	0x0010, 0x0006, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb00a,
+	0x000b, 0x8424, 0x0000, 0xb930, 0x0005, 0x0031, 0x0000, 0x0019,
+	0x0015, 0x0033, 0x0000, 0xb009, 0x001b, 0x842a, 0x0001, 0xb0c8,
+	0x0010, 0x00ff, 0x0001, 0xffe8, 0x0010, 0x0048, 0x000b, 0x14a3,
+	0x0005, 0x0002, 0x0010, 0x0006, 0x0012, 0x0c10, 0x0010, 0xff0c,
+	0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88, 0x0010, 0x0003,
+	0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xb109, 0x001b, 0x843b,
+	0x0000, 0xb10b, 0x001b, 0x643f, 0x0010, 0xb10a, 0x0015, 0x0033,
+	0x0010, 0xc00a, 0x000b, 0x8441, 0x0002, 0x032b, 0x0010, 0xff03,
+	0x0011, 0x0d88, 0x0010, 0x0011, 0x0000, 0xff31, 0x0015, 0x0033,
+	0x0010, 0x030a, 0x001b, 0x8449, 0x0000, 0x11fe, 0x001b, 0x644e,
+	0x0000, 0x0d12, 0x0013, 0x0457, 0x0015, 0x0030, 0x0000, 0x0400,
+	0x0001, 0x1188, 0x0010, 0x0003, 0x0000, 0xff31, 0x0010, 0x0db0,
+	0x0015, 0x0033, 0x0000, 0xb00a, 0x000b, 0x8456, 0x0000, 0x0d11,
+	0x0003, 0x0465, 0x0002, 0xd142, 0x0013, 0x145c, 0x0013, 0x047f,
+	0x0000, 0x05fe, 0x0003, 0x6465, 0x0005, 0x0002, 0x0000, 0x0004,
+	0x0000, 0x050d, 0x0014, 0x0466, 0x0002, 0x3a47, 0x000b, 0x1465,
+	0x0004, 0x08e6, 0x0013, 0x0047, 0x0001, 0xc7c8, 0x0010, 0x0028,
+	0x000b, 0x147e, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88,
+	0x0010, 0x000a, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009,
+	0x001b, 0x8470, 0x0002, 0xb04f, 0x0013, 0x147e, 0x0001, 0x0fe8,
+	0x0010, 0x0000, 0x0003, 0x147c, 0x0001, 0x0fe8, 0x0000, 0x0002,
+	0x0003, 0x147c, 0x0015, 0x003a, 0x0010, 0x8080, 0x0003, 0x047e,
+	0x0015, 0x003a, 0x0010, 0x4040, 0x0017, 0x4000, 0x0000, 0x12fe,
+	0x001b, 0x604f, 0x0015, 0x0012, 0x0001, 0x1b56, 0x0015, 0x0011,
+	0x0001, 0x1b56, 0x0001, 0x1288, 0x0010, 0x0003, 0x0000, 0xff31,
+	0x0015, 0x0033, 0x0010, 0xc00a, 0x001b, 0x848a, 0x0005, 0x00b0,
+	0x0000, 0x8000, 0x0001, 0x1288, 0x0010, 0x0011, 0x0000, 0xff31,
+	0x0015, 0x0033, 0x0000, 0xb00a, 0x001b, 0x8492, 0x0003, 0x004f,
+	0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88, 0x0010, 0x0011,
+	0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0x0309, 0x001b, 0x849b,
+	0x0011, 0x0d88, 0x0010, 0x0005, 0x0000, 0xff31, 0x0015, 0x0033,
+	0x0000, 0xb909, 0x001b, 0x84a1, 0x0017, 0x4000, 0x0005, 0x00b6,
+	0x0010, 0x0600, 0x0004, 0x067d, 0x0014, 0x0515, 0x0000, 0xb05a,
+	0x0000, 0xb15b, 0x0005, 0x0054, 0x0010, 0x0829, 0x0010, 0x0d58,
+	0x0015, 0x0059, 0x0010, 0xffff, 0x0000, 0xb930, 0x0005, 0x0031,
+	0x0010, 0x001e, 0x0015, 0x0033, 0x0000, 0xb009, 0x001b, 0x84b3,
+	0x0000, 0xb05c, 0x0005, 0x0031, 0x0000, 0x001f, 0x0015, 0x0033,
+	0x0000, 0xb009, 0x001b, 0x84b9, 0x0001, 0xb0c8, 0x0010, 0x000f,
+	0x000b, 0x14c0, 0x0015, 0x00ff, 0x0010, 0x0005, 0x0013, 0x04c8,
+	0x0002, 0xb040, 0x0013, 0x14c5, 0x0015, 0x00ff, 0x0000, 0x0004,
+	0x0013, 0x04c8, 0x0001, 0xb0c8, 0x0010, 0x0006, 0x0002, 0xff60,
+	0x0010, 0xffb2, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88,
+	0x0000, 0x0019, 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xb109,
+	0x001b, 0x84d0, 0x0012, 0xb170, 0x0011, 0xffc8, 0x0010, 0xff00,
+	0x0011, 0xb2d0, 0x0010, 0xff60, 0x0002, 0xb045, 0x0013, 0x14db,
+	0x0015, 0x00b2, 0x0000, 0x0002, 0x0013, 0x04e5, 0x0002, 0xb046,
+	0x0003, 0x14e0, 0x0015, 0x00b2, 0x0000, 0x0001, 0x0013, 0x04e5,
+	0x0015, 0x00b2, 0x0010, 0x0000, 0x0000, 0xc0b0, 0x0010, 0xc0b1,
+	0x0003, 0x04eb, 0x0000, 0xb930, 0x0005, 0x0031, 0x0010, 0x002b,
+	0x0015, 0x0033, 0x0000, 0xb011, 0x001b, 0x84ea, 0x0010, 0xb16a,
+	0x0010, 0xb06b, 0x0000, 0xb261, 0x0015, 0x0044, 0x0010, 0x0018,
+	0x0000, 0xb930, 0x0005, 0x0031, 0x0000, 0x0023, 0x0015, 0x0033,
+	0x0000, 0x6241, 0x000b, 0x84f5, 0x0003, 0x94f6, 0x0015, 0x00a0,
+	0x0000, 0x0020, 0x0012, 0xd041, 0x000b, 0x14f9, 0x0015, 0x00d1,
+	0x0010, 0x0202, 0x0013, 0x94fd, 0x0000, 0x75ff, 0x0011, 0xffc8,
+	0x0000, 0x1804, 0x0001, 0xffd8, 0x0010, 0x0009, 0x0013, 0x9503,
+	0x0000, 0xff75, 0x0013, 0x9505, 0x0015, 0x00d1, 0x0000, 0x0200,
+	0x0015, 0x0030, 0x0000, 0x0400, 0x0001, 0xbd88, 0x0000, 0x0008,
+	0x0000, 0xff31, 0x0015, 0x00b1, 0x0010, 0x07d0, 0x0005, 0x00b0,
+	0x0010, 0x0009, 0x0015, 0x0033, 0x0000, 0xb012, 0x000b, 0x8513,
+	0x0003, 0x0465, 0x0000, 0xba30, 0x0005, 0x0031, 0x0010, 0x0035,
+	0x0015, 0x0033, 0x0000, 0xb009, 0x000b, 0x851a, 0x0002, 0xb040,
+	0x0003, 0x1536, 0x0015, 0x0030, 0x0000, 0x0400, 0x0005, 0x0031,
+	0x0001, 0x1b72, 0x0015, 0x0033, 0x0000, 0xb011, 0x000b, 0x8523,
+	0x0002, 0xb100, 0x0010, 0xffb1, 0x000b, 0x252a, 0x0012, 0xb000,
+	0x0000, 0xffb0, 0x0003, 0x2524, 0x0015, 0x0033, 0x0000, 0xb012,
+	0x000b, 0x852c, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88,
+	0x0000, 0x0013, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb012,
+	0x000b, 0x8534, 0x0003, 0x0538, 0x0010, 0xc0b1, 0x0000, 0xc0b0,
+	0x0017, 0x4000, 0x0005, 0x00b6, 0x0010, 0x0500, 0x0004, 0x067d,
+	0x0005, 0x0054, 0x0010, 0x0889, 0x0015, 0x0030, 0x0000, 0x0400,
+	0x0011, 0x0d88, 0x0000, 0x0002, 0x0000, 0xff31, 0x0015, 0x0033,
+	0x0000, 0xb009, 0x000b, 0x8545, 0x0010, 0xb058, 0x0000, 0x0d59,
+	0x0000, 0xb930, 0x0005, 0x0031, 0x0000, 0x0023, 0x0015, 0x0033,
+	0x0000, 0xb011, 0x001b, 0x854d, 0x0010, 0xb15c, 0x0010, 0xb05d,
+	0x0005, 0x0031, 0x0010, 0x002b, 0x0015, 0x0033, 0x0000, 0xb011,
+	0x000b, 0x8554, 0x0000, 0xb15e, 0x0000, 0xb05f, 0x0003, 0x9557,
+	0x0015, 0x00a0, 0x0010, 0x000c, 0x0003, 0x0662, 0x0005, 0x00b6,
+	0x0000, 0x0700, 0x0004, 0x067d, 0x0015, 0x0030, 0x0000, 0x0400,
+	0x0011, 0x0d88, 0x0010, 0x0009, 0x0000, 0xff31, 0x0015, 0x0033,
+	0x0010, 0xb709, 0x001b, 0x8565, 0x0012, 0xb749, 0x0013, 0x156b,
+	0x0005, 0x0054, 0x0010, 0x0889, 0x0003, 0x056d, 0x0005, 0x0054,
+	0x0010, 0x0898, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88,
 	0x0000, 0x0002, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009,
-	0x001b, 0x84f8, 0x0010, 0xb058, 0x0000, 0x0d59, 0x0000, 0xb930,
-	0x0005, 0x0031, 0x0000, 0x0023, 0x0015, 0x0033, 0x0000, 0xb011,
-	0x001b, 0x8500, 0x0010, 0xb15c, 0x0010, 0xb05d, 0x0005, 0x0031,
-	0x0010, 0x002b, 0x0015, 0x0033, 0x0000, 0xb011, 0x000b, 0x8507,
-	0x0000, 0xb15e, 0x0000, 0xb05f, 0x0013, 0x950a, 0x0015, 0x00a0,
-	0x0010, 0x000c, 0x0013, 0x0612, 0x0005, 0x00b6, 0x0000, 0x0700,
-	0x0004, 0x062d, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88,
-	0x0010, 0x0009, 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xb709,
-	0x001b, 0x8518, 0x0012, 0xb749, 0x0003, 0x151e, 0x0005, 0x0054,
-	0x0010, 0x0889, 0x0003, 0x0520, 0x0005, 0x0054, 0x0010, 0x0898,
-	0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88, 0x0000, 0x0002,
-	0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009, 0x001b, 0x8527,
-	0x0010, 0xb058, 0x0000, 0x0d59, 0x0001, 0xb9a8, 0x0010, 0x00f0,
-	0x001b, 0x254e, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88,
-	0x0010, 0x0005, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009,
-	0x000b, 0x8534, 0x0001, 0xb0c8, 0x0000, 0xf700, 0x0000, 0xffb0,
-	0x0011, 0xb0e8, 0x0000, 0xf100, 0x0003, 0x1595, 0x0011, 0xb0e8,
-	0x0000, 0xf200, 0x0003, 0x159a, 0x0011, 0xb0e8, 0x0010, 0xf300,
-	0x0013, 0x15bf, 0x0011, 0xb0e8, 0x0000, 0xf400, 0x0013, 0x15c4,
-	0x0011, 0xb0e8, 0x0010, 0xf500, 0x0003, 0x1595, 0x0011, 0xb0e8,
-	0x0010, 0xf600, 0x0013, 0x15d5, 0x0005, 0x00ce, 0x0010, 0x0009,
-	0x0000, 0xb0cf, 0x0013, 0x0823, 0x0000, 0xb930, 0x0005, 0x0031,
-	0x0000, 0x0025, 0x0015, 0x0033, 0x0000, 0xb039, 0x001b, 0x8553,
-	0x0012, 0xb749, 0x0013, 0x1558, 0x0002, 0xb52c, 0x0000, 0xffb5,
-	0x0000, 0xb162, 0x0000, 0xb063, 0x0005, 0x0031, 0x0000, 0x001f,
-	0x0015, 0x0033, 0x0000, 0xb309, 0x000b, 0x855e, 0x0001, 0xb3c8,
-	0x0010, 0x0003, 0x0003, 0x1566, 0x0010, 0xffb2, 0x0001, 0xffe8,
-	0x0010, 0x0003, 0x000b, 0x1568, 0x0000, 0xc2b7, 0x0003, 0x05f1,
-	0x0001, 0xb2e8, 0x0000, 0x0001, 0x0003, 0x156f, 0x0005, 0x00ce,
-	0x0010, 0x000a, 0x0010, 0xb2cf, 0x0013, 0x0823, 0x0010, 0xb465,
-	0x0010, 0xb667, 0x0015, 0x00b7, 0x0010, 0x0018, 0x0001, 0xb5c8,
-	0x0010, 0x0300, 0x0013, 0x1594, 0x0012, 0xb548, 0x0003, 0x157b,
-	0x0000, 0xb6ff, 0x0011, 0xb780, 0x0010, 0xffb7, 0x0002, 0xb549,
-	0x0013, 0x1580, 0x0010, 0xb4ff, 0x0011, 0xb780, 0x0010, 0xffb7,
-	0x0015, 0x0044, 0x0010, 0x0018, 0x0005, 0x0031, 0x0000, 0x002c,
-	0x0015, 0x0033, 0x0000, 0x6841, 0x000b, 0x8586, 0x0015, 0x0044,
-	0x0000, 0x0019, 0x0005, 0x0031, 0x0000, 0x0034, 0x0015, 0x0033,
-	0x0000, 0x5029, 0x001b, 0x858d, 0x0015, 0x0044, 0x0000, 0x0008,
-	0x0011, 0xb7c8, 0x0010, 0x0003, 0x0013, 0x1594, 0x0010, 0xff55,
-	0x0003, 0x05f1, 0x0005, 0x00b5, 0x0000, 0x0008, 0x0015, 0x00b7,
-	0x0010, 0x0018, 0x0003, 0x05f1, 0x0015, 0x0030, 0x0000, 0x0400,
-	0x0011, 0x0d88, 0x0000, 0x000b, 0x0000, 0xff31, 0x0015, 0x0033,
-	0x0000, 0xb011, 0x000b, 0x85a1, 0x0010, 0xb1ff, 0x0001, 0xb0d0,
-	0x0003, 0x15aa, 0x0005, 0x00b5, 0x0010, 0x0b02, 0x0010, 0xb062,
-	0x0010, 0xb163, 0x0013, 0x05ac, 0x0005, 0x00b5, 0x0000, 0x0302,
-	0x0015, 0x0065, 0x0010, 0x0012, 0x0005, 0x0067, 0x0000, 0x0008,
-	0x0015, 0x006c, 0x0000, 0x7000, 0x0005, 0x006d, 0x0010, 0x0500,
-	0x0015, 0x006f, 0x0010, 0x000a, 0x0015, 0x0044, 0x0000, 0x0001,
-	0x0005, 0x0052, 0x0000, 0x2500, 0x0015, 0x0044, 0x0000, 0x0008,
-	0x0015, 0x00b7, 0x0000, 0x0032, 0x0003, 0x05f1, 0x0005, 0x00b5,
-	0x0010, 0x0028, 0x0015, 0x00b7, 0x0010, 0x0018, 0x0003, 0x05f1,
-	0x0005, 0x00b5, 0x0000, 0x0100, 0x0005, 0x0067, 0x0000, 0x0008,
-	0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88, 0x0010, 0x0018,
-	0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009, 0x001b, 0x85cf,
-	0x0001, 0xb0c8, 0x0010, 0x00ff, 0x0015, 0x00b7, 0x0000, 0x0020,
-	0x0003, 0x05f1, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88,
+	0x001b, 0x8574, 0x0010, 0xb058, 0x0000, 0x0d59, 0x0001, 0xb9c8,
+	0x0010, 0xf000, 0x0001, 0xffe8, 0x0010, 0xf000, 0x000b, 0x159d,
+	0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88, 0x0010, 0x0005,
+	0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009, 0x000b, 0x8583,
+	0x0001, 0xb0c8, 0x0000, 0xf700, 0x0000, 0xffb0, 0x0011, 0xb0e8,
+	0x0000, 0xf100, 0x0003, 0x15e4, 0x0011, 0xb0e8, 0x0000, 0xf200,
+	0x0013, 0x15e9, 0x0011, 0xb0e8, 0x0010, 0xf300, 0x0013, 0x160e,
+	0x0011, 0xb0e8, 0x0000, 0xf400, 0x0013, 0x1613, 0x0011, 0xb0e8,
+	0x0010, 0xf500, 0x0003, 0x15e4, 0x0011, 0xb0e8, 0x0010, 0xf600,
+	0x0013, 0x1625, 0x0005, 0x00ce, 0x0010, 0x0009, 0x0000, 0xb0cf,
+	0x0003, 0x08db, 0x0000, 0xb930, 0x0005, 0x0031, 0x0000, 0x0025,
+	0x0015, 0x0033, 0x0000, 0xb039, 0x000b, 0x85a2, 0x0012, 0xb749,
+	0x0013, 0x15a7, 0x0002, 0xb52c, 0x0000, 0xffb5, 0x0000, 0xb162,
+	0x0000, 0xb063, 0x0005, 0x0031, 0x0000, 0x001f, 0x0015, 0x0033,
+	0x0000, 0xb309, 0x000b, 0x85ad, 0x0001, 0xb3c8, 0x0010, 0x0003,
+	0x0013, 0x15b5, 0x0010, 0xffb2, 0x0001, 0xffe8, 0x0010, 0x0003,
+	0x001b, 0x15b7, 0x0000, 0xc2b7, 0x0013, 0x0641, 0x0001, 0xb2e8,
+	0x0000, 0x0001, 0x0003, 0x15be, 0x0005, 0x00ce, 0x0010, 0x000a,
+	0x0010, 0xb2cf, 0x0003, 0x08db, 0x0010, 0xb465, 0x0010, 0xb667,
+	0x0015, 0x00b7, 0x0010, 0x0018, 0x0001, 0xb5c8, 0x0010, 0x0300,
+	0x0013, 0x15e3, 0x0012, 0xb548, 0x0003, 0x15ca, 0x0000, 0xb6ff,
+	0x0011, 0xb780, 0x0010, 0xffb7, 0x0002, 0xb549, 0x0003, 0x15cf,
+	0x0010, 0xb4ff, 0x0011, 0xb780, 0x0010, 0xffb7, 0x0015, 0x0044,
+	0x0010, 0x0018, 0x0005, 0x0031, 0x0000, 0x002c, 0x0015, 0x0033,
+	0x0000, 0x6841, 0x000b, 0x85d5, 0x0015, 0x0044, 0x0000, 0x0019,
+	0x0005, 0x0031, 0x0000, 0x0034, 0x0015, 0x0033, 0x0000, 0x5029,
+	0x000b, 0x85dc, 0x0015, 0x0044, 0x0000, 0x0008, 0x0011, 0xb7c8,
+	0x0010, 0x0003, 0x0013, 0x15e3, 0x0010, 0xff55, 0x0013, 0x0641,
+	0x0005, 0x00b5, 0x0000, 0x0008, 0x0015, 0x00b7, 0x0010, 0x0018,
+	0x0013, 0x0641, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88,
+	0x0000, 0x000b, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb011,
+	0x001b, 0x85f0, 0x0010, 0xb1ff, 0x0001, 0xb0d0, 0x0003, 0x15f9,
+	0x0005, 0x00b5, 0x0010, 0x0b02, 0x0010, 0xb062, 0x0010, 0xb163,
+	0x0003, 0x05fb, 0x0005, 0x00b5, 0x0000, 0x0302, 0x0015, 0x0065,
+	0x0010, 0x0012, 0x0005, 0x0067, 0x0000, 0x0008, 0x0015, 0x006c,
+	0x0000, 0x7000, 0x0005, 0x006d, 0x0010, 0x0500, 0x0015, 0x006f,
+	0x0010, 0x000a, 0x0015, 0x0044, 0x0000, 0x0001, 0x0005, 0x0052,
+	0x0000, 0x2500, 0x0015, 0x0044, 0x0000, 0x0008, 0x0015, 0x00b7,
+	0x0000, 0x0032, 0x0013, 0x0641, 0x0005, 0x00b5, 0x0010, 0x0028,
+	0x0015, 0x00b7, 0x0010, 0x0018, 0x0013, 0x0641, 0x0005, 0x00b5,
+	0x0000, 0x0100, 0x0005, 0x0067, 0x0000, 0x0008, 0x0015, 0x0030,
+	0x0000, 0x0400, 0x0011, 0x0d88, 0x0010, 0x0018, 0x0000, 0xff31,
+	0x0015, 0x0033, 0x0000, 0xb009, 0x001b, 0x861e, 0x0001, 0xb0c8,
+	0x0010, 0x00ff, 0x0010, 0xff69, 0x0015, 0x00b7, 0x0000, 0x0020,
+	0x0013, 0x0641, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88,
 	0x0010, 0x0005, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb609,
-	0x000b, 0x85dc, 0x0001, 0xb6c8, 0x0010, 0xff00, 0x0000, 0xffb0,
-	0x0015, 0x0033, 0x0000, 0xb00a, 0x001b, 0x85e2, 0x0001, 0xb6c8,
-	0x0010, 0x00ff, 0x0012, 0xff10, 0x001b, 0x15eb, 0x0000, 0xffb5,
-	0x0015, 0x00b7, 0x0010, 0x0018, 0x0003, 0x05f1, 0x0010, 0xff63,
+	0x000b, 0x862c, 0x0001, 0xb6c8, 0x0010, 0xff00, 0x0000, 0xffb0,
+	0x0015, 0x0033, 0x0000, 0xb00a, 0x000b, 0x8632, 0x0001, 0xb6c8,
+	0x0010, 0x00ff, 0x0012, 0xff10, 0x000b, 0x163b, 0x0000, 0xffb5,
+	0x0015, 0x00b7, 0x0010, 0x0018, 0x0013, 0x0641, 0x0010, 0xff63,
 	0x0005, 0x00b5, 0x0000, 0x0800, 0x0015, 0x00b7, 0x0010, 0x0018,
-	0x0003, 0x05f1, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88,
+	0x0013, 0x0641, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88,
 	0x0010, 0x0009, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009,
-	0x000b, 0x85f8, 0x0010, 0xb561, 0x0013, 0x95fa, 0x0010, 0xb7a0,
-	0x0013, 0x0612, 0x0005, 0x00b6, 0x0010, 0x0300, 0x0004, 0x062d,
+	0x001b, 0x8648, 0x0010, 0xb561, 0x0003, 0x964a, 0x0010, 0xb7a0,
+	0x0003, 0x0662, 0x0005, 0x00b6, 0x0010, 0x0300, 0x0004, 0x067d,
 	0x0005, 0x0054, 0x0010, 0x0819, 0x0010, 0x0d58, 0x0015, 0x0030,
 	0x0000, 0x0400, 0x0011, 0x0d88, 0x0000, 0x0002, 0x0000, 0xff31,
-	0x0015, 0x0033, 0x0000, 0xb009, 0x001b, 0x860a, 0x0000, 0xb059,
-	0x0013, 0x960c, 0x0010, 0xc0a0, 0x0010, 0x71ff, 0x0002, 0xff28,
-	0x0010, 0xff71, 0x0013, 0x0612, 0x0012, 0xd041, 0x001b, 0x1612,
+	0x0015, 0x0033, 0x0000, 0xb009, 0x001b, 0x865a, 0x0000, 0xb059,
+	0x0013, 0x965c, 0x0010, 0xc0a0, 0x0010, 0x71ff, 0x0002, 0xff28,
+	0x0010, 0xff71, 0x0003, 0x0662, 0x0012, 0xd041, 0x000b, 0x1662,
 	0x0015, 0x00d1, 0x0010, 0x0202, 0x0000, 0x75ff, 0x0011, 0xffc8,
-	0x0000, 0x1804, 0x0001, 0xffd8, 0x0010, 0x0009, 0x0013, 0x961b,
-	0x0000, 0xff75, 0x0013, 0x961d, 0x0015, 0x00d1, 0x0000, 0x0200,
+	0x0000, 0x1804, 0x0001, 0xffd8, 0x0010, 0x0009, 0x0003, 0x966b,
+	0x0000, 0xff75, 0x0003, 0x966d, 0x0015, 0x00d1, 0x0000, 0x0200,
 	0x0015, 0x0030, 0x0000, 0x0400, 0x0001, 0xbd88, 0x0000, 0x0008,
 	0x0000, 0xff31, 0x0005, 0x00b0, 0x0010, 0x0009, 0x0015, 0x00b1,
-	0x0010, 0x07d0, 0x0015, 0x0033, 0x0000, 0xb012, 0x001b, 0x862b,
-	0x0013, 0x043b, 0x0015, 0x0044, 0x0000, 0x0008, 0x0005, 0x0098,
-	0x0010, 0x0056, 0x0015, 0x0099, 0x0000, 0x9575, 0x0004, 0x07ea,
-	0x0000, 0xb096, 0x0012, 0xb270, 0x0010, 0xff56, 0x0014, 0x080c,
+	0x0010, 0x07d0, 0x0015, 0x0033, 0x0000, 0xb012, 0x001b, 0x867b,
+	0x0003, 0x0465, 0x0015, 0x0044, 0x0000, 0x0008, 0x0005, 0x0098,
+	0x0010, 0x0056, 0x0015, 0x0099, 0x0000, 0x9575, 0x0004, 0x08a2,
+	0x0000, 0xb096, 0x0012, 0xb270, 0x0010, 0xff56, 0x0004, 0x08c4,
 	0x0010, 0xb052, 0x0010, 0xb153, 0x0000, 0xb6ff, 0x0011, 0xb2d0,
-	0x0010, 0xff50, 0x0010, 0xb351, 0x0017, 0x4000, 0x0015, 0x0030,
-	0x0000, 0x0400, 0x0001, 0x1288, 0x0010, 0x0011, 0x0000, 0xff31,
-	0x0015, 0x0033, 0x0000, 0x1009, 0x000b, 0x8646, 0x0015, 0x000f,
-	0x0000, 0x0001, 0x0010, 0xc014, 0x0000, 0x1213, 0x0015, 0x0030,
-	0x0000, 0x0400, 0x0011, 0x1388, 0x0000, 0x0004, 0x0000, 0xff31,
-	0x0015, 0x0033, 0x0000, 0xba09, 0x000b, 0x8652, 0x0015, 0x0030,
-	0x0000, 0x0400, 0x0011, 0x1388, 0x0010, 0x0005, 0x0000, 0xff31,
-	0x0015, 0x0033, 0x0000, 0x1a09, 0x001b, 0x865a, 0x0012, 0x104b,
-	0x001b, 0x1663, 0x0000, 0x1a30, 0x0005, 0x0031, 0x0000, 0x000b,
-	0x0015, 0x0033, 0x0000, 0x1621, 0x000b, 0x8662, 0x0010, 0x15fe,
-	0x000b, 0x6682, 0x0004, 0x06a9, 0x0002, 0x3a42, 0x000b, 0x16a8,
-	0x0001, 0x10c8, 0x0010, 0x000f, 0x001b, 0x170b, 0x0015, 0x0030,
-	0x0000, 0x0400, 0x0011, 0x1388, 0x0000, 0x0008, 0x0000, 0xff31,
-	0x0015, 0x0033, 0x0000, 0xb009, 0x001b, 0x8672, 0x0011, 0xb0e8,
-	0x0010, 0x0009, 0x0013, 0x1679, 0x0011, 0xb0e8, 0x0000, 0x0001,
-	0x000b, 0x16a7, 0x0011, 0x1388, 0x0010, 0x000a, 0x0000, 0xff31,
-	0x0015, 0x0033, 0x0000, 0xb009, 0x001b, 0x867e, 0x0002, 0xb04f,
-	0x000b, 0x169e, 0x0003, 0x06a7, 0x0015, 0x0030, 0x0000, 0x0400,
-	0x0011, 0x1388, 0x0010, 0x0003, 0x0000, 0xff31, 0x0015, 0x0033,
-	0x0000, 0xb009, 0x000b, 0x8689, 0x0015, 0x0033, 0x0010, 0xc00a,
-	0x000b, 0x868c, 0x0010, 0xb0fe, 0x0003, 0x6691, 0x0000, 0xb012,
-	0x0013, 0x0693, 0x0010, 0xc012, 0x0010, 0xc011, 0x0015, 0x000f,
-	0x0010, 0x0000, 0x0002, 0x3944, 0x0003, 0x169c, 0x0015, 0x0039,
-	0x0000, 0x5040, 0x0015, 0x00b8, 0x0000, 0x0008, 0x0004, 0x0867,
-	0x0000, 0xc013, 0x0003, 0x06a8, 0x0010, 0x02fe, 0x0013, 0x66a3,
-	0x0015, 0x003a, 0x0010, 0x2020, 0x0003, 0x06a8, 0x0015, 0x003a,
-	0x0000, 0x2000, 0x0015, 0x003a, 0x0010, 0x1010, 0x0014, 0x0853,
-	0x0013, 0x0055, 0x0003, 0xb6a9, 0x0005, 0x002a, 0x0000, 0x0004,
+	0x0010, 0xff50, 0x0010, 0xb351, 0x0017, 0x4000, 0x0001, 0x12e8,
+	0x0001, 0x1b56, 0x0013, 0x183f, 0x0015, 0x00d1, 0x0000, 0x0400,
+	0x0015, 0x0030, 0x0000, 0x0400, 0x0001, 0x1288, 0x0010, 0x0011,
+	0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0x1009, 0x000b, 0x869b,
+	0x0015, 0x000f, 0x0000, 0x0001, 0x0010, 0xc014, 0x0000, 0x1213,
+	0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x1388, 0x0000, 0x0004,
+	0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xba09, 0x000b, 0x86a7,
+	0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x1388, 0x0010, 0x0005,
+	0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0x1a09, 0x001b, 0x86af,
+	0x0012, 0x104b, 0x001b, 0x16b8, 0x0000, 0x1a30, 0x0005, 0x0031,
+	0x0000, 0x000b, 0x0015, 0x0033, 0x0000, 0x1621, 0x001b, 0x86b7,
+	0x0010, 0x15fe, 0x000b, 0x66d7, 0x0014, 0x06fe, 0x0002, 0x3a42,
+	0x000b, 0x16fd, 0x0001, 0x10c8, 0x0010, 0x000f, 0x000b, 0x1760,
+	0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x1388, 0x0000, 0x0008,
+	0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009, 0x000b, 0x86c7,
+	0x0011, 0xb0e8, 0x0010, 0x0009, 0x0013, 0x16ce, 0x0011, 0xb0e8,
+	0x0000, 0x0001, 0x001b, 0x16fc, 0x0011, 0x1388, 0x0010, 0x000a,
+	0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009, 0x000b, 0x86d3,
+	0x0002, 0xb04f, 0x001b, 0x16f3, 0x0013, 0x06fc, 0x0015, 0x0030,
+	0x0000, 0x0400, 0x0011, 0x1388, 0x0010, 0x0003, 0x0000, 0xff31,
+	0x0015, 0x0033, 0x0000, 0xb009, 0x001b, 0x86de, 0x0015, 0x0033,
+	0x0010, 0xc00a, 0x001b, 0x86e1, 0x0010, 0xb0fe, 0x0003, 0x66e6,
+	0x0000, 0xb012, 0x0013, 0x06e8, 0x0010, 0xc012, 0x0010, 0xc011,
+	0x0015, 0x000f, 0x0010, 0x0000, 0x0002, 0x3944, 0x0013, 0x16f1,
+	0x0015, 0x0039, 0x0000, 0x5040, 0x0015, 0x00b8, 0x0000, 0x0008,
+	0x0014, 0x091f, 0x0000, 0xc013, 0x0003, 0x06fd, 0x0010, 0x02fe,
+	0x0003, 0x66f8, 0x0015, 0x003a, 0x0010, 0x2020, 0x0003, 0x06fd,
+	0x0015, 0x003a, 0x0000, 0x2000, 0x0015, 0x003a, 0x0010, 0x1010,
+	0x0014, 0x090b, 0x0003, 0x0054, 0x0013, 0xb6fe, 0x0005, 0x002a,
+	0x0000, 0x0004, 0x0000, 0xba30, 0x0005, 0x0031, 0x0010, 0x001b,
+	0x0015, 0x0033, 0x0000, 0xb009, 0x000b, 0x8706, 0x0000, 0xc02c,
+	0x0000, 0xb02d, 0x0012, 0x104b, 0x0013, 0x1721, 0x0000, 0x1a30,
+	0x0005, 0x0031, 0x0000, 0x0023, 0x0015, 0x0033, 0x0000, 0xb129,
+	0x001b, 0x8710, 0x0000, 0xb120, 0x0010, 0xb221, 0x0000, 0xb322,
+	0x0000, 0xb423, 0x0000, 0xb524, 0x0000, 0xc025, 0x0010, 0xb526,
+	0x0010, 0xc027, 0x0010, 0xb516, 0x0010, 0xc017, 0x0000, 0xb518,
+	0x0000, 0xc019, 0x0010, 0xc028, 0x0000, 0xc029, 0x0010, 0xc01e,
+	0x0013, 0x0757, 0x0012, 0x1044, 0x0003, 0x1751, 0x0002, 0x1034,
+	0x0000, 0xff10, 0x0000, 0x1a30, 0x0005, 0x0031, 0x0000, 0x0002,
+	0x0015, 0x0033, 0x0000, 0x1b29, 0x001b, 0x872a, 0x0000, 0x1c30,
+	0x0000, 0x1b31, 0x0015, 0x0033, 0x0000, 0xb131, 0x001b, 0x872f,
+	0x0002, 0x1f43, 0x000b, 0x1736, 0x0010, 0xb3b5, 0x0000, 0xb4b6,
+	0x0000, 0xc0b3, 0x0010, 0xc0b4, 0x0000, 0xb120, 0x0010, 0xb221,
+	0x0000, 0xb322, 0x0000, 0xb423, 0x0000, 0xb524, 0x0010, 0xb625,
+	0x0010, 0xb516, 0x0000, 0xb617, 0x0000, 0x1826, 0x0000, 0x1927,
+	0x0000, 0x1a30, 0x0005, 0x0031, 0x0010, 0x000f, 0x0015, 0x0033,
+	0x0000, 0xb011, 0x001b, 0x8745, 0x0000, 0xb028, 0x0000, 0xb129,
+	0x0012, 0x1e10, 0x0010, 0xff1e, 0x0013, 0x6757, 0x0002, 0x1d00,
+	0x0010, 0xff1d, 0x0004, 0x02a8, 0x0002, 0x3a42, 0x0003, 0x1757,
+	0x0003, 0x075f, 0x0000, 0x1a30, 0x0005, 0x0031, 0x0000, 0x0002,
+	0x0015, 0x0033, 0x0000, 0x1b79, 0x000b, 0x8756, 0x0003, 0xb757,
+	0x0005, 0x002a, 0x0000, 0x0001, 0x0005, 0x0015, 0x0000, 0x0001,
+	0x0000, 0x1efe, 0x0003, 0x675f, 0x0003, 0x0274, 0x0017, 0x4000,
 	0x0000, 0xba30, 0x0005, 0x0031, 0x0010, 0x001b, 0x0015, 0x0033,
-	0x0000, 0xb009, 0x001b, 0x86b1, 0x0000, 0xc02c, 0x0000, 0xb02d,
-	0x0012, 0x104b, 0x0003, 0x16cc, 0x0000, 0x1a30, 0x0005, 0x0031,
-	0x0000, 0x0023, 0x0015, 0x0033, 0x0000, 0xb129, 0x001b, 0x86bb,
-	0x0000, 0xb120, 0x0010, 0xb221, 0x0000, 0xb322, 0x0000, 0xb423,
-	0x0000, 0xb524, 0x0000, 0xc025, 0x0010, 0xb526, 0x0010, 0xc027,
-	0x0010, 0xb516, 0x0010, 0xc017, 0x0000, 0xb518, 0x0000, 0xc019,
-	0x0010, 0xc028, 0x0000, 0xc029, 0x0010, 0xc01e, 0x0013, 0x0702,
-	0x0012, 0x1044, 0x0003, 0x16fc, 0x0002, 0x1034, 0x0000, 0xff10,
-	0x0000, 0x1a30, 0x0005, 0x0031, 0x0000, 0x0002, 0x0015, 0x0033,
-	0x0000, 0x1b29, 0x000b, 0x86d5, 0x0000, 0x1c30, 0x0000, 0x1b31,
-	0x0015, 0x0033, 0x0000, 0xb131, 0x000b, 0x86da, 0x0002, 0x1f43,
-	0x001b, 0x16e1, 0x0010, 0xb3b5, 0x0000, 0xb4b6, 0x0000, 0xc0b3,
-	0x0010, 0xc0b4, 0x0000, 0xb120, 0x0010, 0xb221, 0x0000, 0xb322,
-	0x0000, 0xb423, 0x0000, 0xb524, 0x0010, 0xb625, 0x0010, 0xb516,
-	0x0000, 0xb617, 0x0000, 0x1826, 0x0000, 0x1927, 0x0000, 0x1a30,
-	0x0005, 0x0031, 0x0010, 0x000f, 0x0015, 0x0033, 0x0000, 0xb011,
-	0x001b, 0x86f0, 0x0000, 0xb028, 0x0000, 0xb129, 0x0012, 0x1e10,
-	0x0010, 0xff1e, 0x0013, 0x6702, 0x0002, 0x1d00, 0x0010, 0xff1d,
-	0x0014, 0x02a5, 0x0002, 0x3a42, 0x0003, 0x1702, 0x0003, 0x070a,
-	0x0000, 0x1a30, 0x0005, 0x0031, 0x0000, 0x0002, 0x0015, 0x0033,
-	0x0000, 0x1b79, 0x001b, 0x8701, 0x0003, 0xb702, 0x0005, 0x002a,
-	0x0000, 0x0001, 0x0005, 0x0015, 0x0000, 0x0001, 0x0000, 0x1efe,
-	0x0003, 0x670a, 0x0003, 0x0271, 0x0017, 0x4000, 0x0000, 0xba30,
-	0x0005, 0x0031, 0x0010, 0x001b, 0x0015, 0x0033, 0x0010, 0xb051,
-	0x001b, 0x8710, 0x0000, 0xb0a3, 0x0010, 0xb697, 0x0010, 0xb946,
-	0x0015, 0x00a5, 0x0000, 0x0010, 0x0015, 0x0030, 0x0000, 0x0400,
-	0x0011, 0x1388, 0x0000, 0x0002, 0x0000, 0xff31, 0x0015, 0x0033,
-	0x0000, 0xb509, 0x000b, 0x871d, 0x0014, 0x080c, 0x0004, 0x07fb,
-	0x0012, 0xb470, 0x0010, 0xffb4, 0x0010, 0xb48e, 0x0010, 0xb08a,
-	0x0010, 0xb18b, 0x0012, 0x104d, 0x0013, 0x1728, 0x0003, 0x0755,
-	0x0012, 0x104b, 0x0003, 0x173b, 0x0005, 0x008c, 0x0010, 0x0829,
-	0x0010, 0xc08d, 0x0001, 0xb2d8, 0x0010, 0x0600, 0x0010, 0xff88,
-	0x0010, 0xb389, 0x0000, 0x1390, 0x0010, 0xb591, 0x0000, 0xc08f,
-	0x0010, 0x1ab9, 0x0004, 0x04d6, 0x0003, 0x9736, 0x0010, 0xb092,
-	0x0010, 0xb193, 0x0003, 0x9739, 0x0003, 0x0750, 0x0005, 0x008c,
-	0x0000, 0x0809, 0x0015, 0x008d, 0x0000, 0x0008, 0x0001, 0xb2d8,
-	0x0000, 0x0100, 0x0010, 0xff88, 0x0010, 0xb389, 0x0000, 0x1390,
-	0x0010, 0xb591, 0x0000, 0xc08f, 0x0000, 0x1a30, 0x0005, 0x0031,
-	0x0010, 0x000f, 0x0015, 0x0033, 0x0000, 0xb011, 0x000b, 0x874b,
-	0x0013, 0x974c, 0x0000, 0xb192, 0x0000, 0xb093, 0x0013, 0x974f,
-	0x0010, 0x19a1, 0x0000, 0x18a2, 0x0015, 0x00b1, 0x0010, 0x0096,
-	0x0003, 0x07c6, 0x0000, 0xb590, 0x0010, 0x1391, 0x0001, 0x10c8,
-	0x0010, 0x000f, 0x0001, 0xffe8, 0x0010, 0x0005, 0x0003, 0x177c,
-	0x0001, 0xb2d8, 0x0000, 0x0700, 0x0010, 0xff88, 0x0010, 0xb389,
-	0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x1388, 0x0010, 0x0009,
-	0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009, 0x001b, 0x8767,
-	0x0002, 0xb049, 0x0013, 0x176f, 0x0005, 0x008c, 0x0010, 0x0889,
-	0x0015, 0x00b1, 0x0010, 0x0096, 0x0013, 0x0773, 0x0005, 0x008c,
-	0x0010, 0x0898, 0x0015, 0x00b1, 0x0000, 0x0092, 0x0010, 0xc08d,
-	0x0000, 0xc08f, 0x0013, 0x9775, 0x0000, 0xc092, 0x0010, 0xc093,
-	0x0003, 0x9778, 0x0010, 0x19a1, 0x0000, 0x18a2, 0x0003, 0x07c6,
+	0x0010, 0xb051, 0x000b, 0x8765, 0x0000, 0xb0a3, 0x0010, 0xb697,
+	0x0010, 0xb946, 0x0015, 0x00a5, 0x0000, 0x0010, 0x0015, 0x0030,
+	0x0000, 0x0400, 0x0011, 0x1388, 0x0000, 0x0002, 0x0000, 0xff31,
+	0x0015, 0x0033, 0x0000, 0xb509, 0x000b, 0x8772, 0x0004, 0x08c4,
+	0x0004, 0x08b3, 0x0012, 0xb470, 0x0010, 0xffb4, 0x0010, 0xb48e,
+	0x0010, 0xb08a, 0x0010, 0xb18b, 0x0012, 0x104d, 0x0013, 0x177d,
+	0x0003, 0x07aa, 0x0012, 0x104b, 0x0013, 0x1790, 0x0005, 0x008c,
+	0x0010, 0x0829, 0x0010, 0xc08d, 0x0001, 0xb2d8, 0x0010, 0x0600,
+	0x0010, 0xff88, 0x0010, 0xb389, 0x0000, 0x1390, 0x0010, 0xb591,
+	0x0000, 0xc08f, 0x0010, 0x1ab9, 0x0014, 0x0515, 0x0003, 0x978b,
+	0x0010, 0xb092, 0x0010, 0xb193, 0x0003, 0x978e, 0x0003, 0x07a5,
+	0x0005, 0x008c, 0x0000, 0x0809, 0x0015, 0x008d, 0x0000, 0x0008,
 	0x0001, 0xb2d8, 0x0000, 0x0100, 0x0010, 0xff88, 0x0010, 0xb389,
-	0x0005, 0x008c, 0x0010, 0x0880, 0x0015, 0x008d, 0x0000, 0x0008,
-	0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x1388, 0x0000, 0x000e,
-	0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009, 0x000b, 0x878b,
-	0x0010, 0xb08f, 0x0000, 0xb590, 0x0010, 0x1391, 0x0000, 0x1a30,
-	0x0005, 0x0031, 0x0000, 0x000d, 0x0015, 0x0033, 0x0000, 0xb021,
-	0x001b, 0x8794, 0x0003, 0x9795, 0x0010, 0xb392, 0x0010, 0xb293,
-	0x0013, 0x9798, 0x0000, 0xb1a1, 0x0010, 0xb0a2, 0x0015, 0x0030,
-	0x0000, 0x0400, 0x0011, 0x1388, 0x0000, 0x000b, 0x0000, 0xff31,
-	0x0015, 0x0033, 0x0010, 0xb211, 0x001b, 0x87a2, 0x0000, 0xb3ff,
-	0x0001, 0xb080, 0x0000, 0xffb3, 0x000b, 0x27a9, 0x0002, 0xb200,
-	0x0003, 0x07aa, 0x0010, 0xb2ff, 0x0011, 0xb180, 0x0010, 0xffb2,
-	0x0011, 0x1388, 0x0000, 0x000b, 0x0000, 0xff31, 0x0015, 0x0033,
-	0x0010, 0xb212, 0x000b, 0x87b1, 0x0015, 0x00b1, 0x0000, 0x0092,
-	0x0002, 0x104c, 0x0003, 0x17c4, 0x0011, 0xc2e8, 0x0010, 0x000c,
-	0x001b, 0x17bc, 0x0015, 0x00ff, 0x0000, 0x0800, 0x0013, 0x07c4,
-	0x0011, 0xc2e8, 0x0000, 0x0020, 0x001b, 0x17c2, 0x0015, 0x00ff,
-	0x0010, 0x1800, 0x0013, 0x07c4, 0x0015, 0x00ff, 0x0000, 0x1000,
-	0x0011, 0xb1d0, 0x0010, 0xffb1, 0x0015, 0x009a, 0x0010, 0x0036,
-	0x0005, 0x009b, 0x0000, 0x95d5, 0x0012, 0xd041, 0x000b, 0x17ca,
-	0x0015, 0x00d1, 0x0010, 0x0202, 0x0013, 0x97ce, 0x0012, 0x104e,
-	0x0003, 0x17d3, 0x0012, 0xb12f, 0x0010, 0xffb1, 0x0000, 0xb175,
-	0x0003, 0x97d4, 0x0015, 0x00d1, 0x0000, 0x0200, 0x0001, 0x19c8,
-	0x0010, 0xfff0, 0x000b, 0x17dd, 0x0015, 0x00b1, 0x0010, 0x07d0,
-	0x0013, 0x07df, 0x0015, 0x00b1, 0x0000, 0x1b58, 0x0005, 0x00b0,
-	0x0010, 0x0009, 0x0015, 0x0030, 0x0000, 0x0400, 0x0001, 0xbd88,
-	0x0000, 0x000b, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb012,
-	0x000b, 0x87e8, 0x0003, 0x06a8, 0x0000, 0xba30, 0x0005, 0x0031,
-	0x0010, 0x0021, 0x0015, 0x0033, 0x0010, 0xb019, 0x001b, 0x87ef,
+	0x0000, 0x1390, 0x0010, 0xb591, 0x0000, 0xc08f, 0x0000, 0x1a30,
+	0x0005, 0x0031, 0x0010, 0x000f, 0x0015, 0x0033, 0x0000, 0xb011,
+	0x000b, 0x87a0, 0x0013, 0x97a1, 0x0000, 0xb192, 0x0000, 0xb093,
+	0x0013, 0x97a4, 0x0010, 0x19a1, 0x0000, 0x18a2, 0x0015, 0x00b1,
+	0x0010, 0x0096, 0x0003, 0x081b, 0x0000, 0xb590, 0x0010, 0x1391,
+	0x0001, 0x10c8, 0x0010, 0x000f, 0x0001, 0xffe8, 0x0010, 0x0005,
+	0x0013, 0x17d1, 0x0001, 0xb2d8, 0x0000, 0x0700, 0x0010, 0xff88,
+	0x0010, 0xb389, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x1388,
+	0x0010, 0x0009, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009,
+	0x001b, 0x87bc, 0x0002, 0xb049, 0x0003, 0x17c4, 0x0005, 0x008c,
+	0x0010, 0x0889, 0x0015, 0x00b1, 0x0010, 0x0096, 0x0013, 0x07c8,
+	0x0005, 0x008c, 0x0010, 0x0898, 0x0015, 0x00b1, 0x0000, 0x0092,
+	0x0010, 0xc08d, 0x0000, 0xc08f, 0x0003, 0x97ca, 0x0000, 0xc092,
+	0x0010, 0xc093, 0x0013, 0x97cd, 0x0010, 0x19a1, 0x0000, 0x18a2,
+	0x0003, 0x081b, 0x0001, 0xb2d8, 0x0000, 0x0100, 0x0010, 0xff88,
+	0x0010, 0xb389, 0x0005, 0x008c, 0x0010, 0x0880, 0x0015, 0x008d,
+	0x0000, 0x0008, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x1388,
+	0x0000, 0x000e, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009,
+	0x001b, 0x87e0, 0x0010, 0xb08f, 0x0000, 0xb590, 0x0010, 0x1391,
+	0x0000, 0x1a30, 0x0005, 0x0031, 0x0000, 0x000d, 0x0015, 0x0033,
+	0x0000, 0xb021, 0x001b, 0x87e9, 0x0013, 0x97ea, 0x0010, 0xb392,
+	0x0010, 0xb293, 0x0003, 0x97ed, 0x0000, 0xb1a1, 0x0010, 0xb0a2,
+	0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x1388, 0x0000, 0x000b,
+	0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xb211, 0x001b, 0x87f7,
+	0x0000, 0xb3ff, 0x0001, 0xb080, 0x0000, 0xffb3, 0x001b, 0x27fe,
+	0x0002, 0xb200, 0x0003, 0x07ff, 0x0010, 0xb2ff, 0x0011, 0xb180,
+	0x0010, 0xffb2, 0x0011, 0x1388, 0x0000, 0x000b, 0x0000, 0xff31,
+	0x0015, 0x0033, 0x0010, 0xb212, 0x000b, 0x8806, 0x0015, 0x00b1,
+	0x0000, 0x0092, 0x0002, 0x104c, 0x0003, 0x1819, 0x0011, 0xc2e8,
+	0x0010, 0x000c, 0x000b, 0x1811, 0x0015, 0x00ff, 0x0000, 0x0800,
+	0x0013, 0x0819, 0x0011, 0xc2e8, 0x0000, 0x0020, 0x000b, 0x1817,
+	0x0015, 0x00ff, 0x0010, 0x1800, 0x0013, 0x0819, 0x0015, 0x00ff,
+	0x0000, 0x1000, 0x0011, 0xb1d0, 0x0010, 0xffb1, 0x0015, 0x009a,
+	0x0010, 0x0036, 0x0005, 0x009b, 0x0000, 0x95d5, 0x0012, 0xd041,
+	0x001b, 0x181f, 0x0015, 0x00d1, 0x0010, 0x0202, 0x0013, 0x9823,
+	0x0012, 0x104e, 0x0013, 0x1828, 0x0012, 0xb12f, 0x0010, 0xffb1,
+	0x0000, 0xb175, 0x0013, 0x9829, 0x0015, 0x00d1, 0x0000, 0x0200,
+	0x0001, 0x19c8, 0x0010, 0xfff0, 0x001b, 0x1832, 0x0015, 0x00b1,
+	0x0010, 0x07d0, 0x0013, 0x0834, 0x0015, 0x00b1, 0x0000, 0x1b58,
+	0x0005, 0x00b0, 0x0010, 0x0009, 0x0015, 0x0030, 0x0000, 0x0400,
+	0x0001, 0xbd88, 0x0000, 0x000b, 0x0000, 0xff31, 0x0015, 0x0033,
+	0x0000, 0xb012, 0x001b, 0x883d, 0x0003, 0x06fd, 0x0015, 0x0030,
+	0x0000, 0x0400, 0x0000, 0xa4ff, 0x0003, 0x688d, 0x0011, 0xffa8,
+	0x0010, 0x0005, 0x000b, 0x288d, 0x0005, 0x0031, 0x0011, 0x1b6d,
+	0x0015, 0x0033, 0x0010, 0xb211, 0x001b, 0x884a, 0x0002, 0xb200,
+	0x0010, 0xffb2, 0x0005, 0x0031, 0x0011, 0x1b6d, 0x0015, 0x0033,
+	0x0010, 0xb20a, 0x001b, 0x8851, 0x0015, 0x000f, 0x0000, 0x0001,
+	0x0000, 0x1213, 0x0005, 0x0010, 0x0000, 0x8000, 0x0015, 0x00a3,
+	0x0000, 0x0200, 0x0000, 0xc697, 0x0005, 0x0046, 0x0000, 0x0002,
+	0x0015, 0x00a5, 0x0000, 0x0010, 0x0011, 0xc4d8, 0x0000, 0x3200,
+	0x0010, 0xff88, 0x0000, 0xc589, 0x0010, 0xc48a, 0x0010, 0xc58b,
+	0x0010, 0xc08e, 0x0005, 0x008c, 0x0010, 0xe109, 0x0010, 0xc08d,
+	0x0015, 0x0090, 0x0001, 0x1b56, 0x0005, 0x0091, 0x0010, 0xffff,
+	0x0000, 0xb292, 0x0000, 0xb393, 0x0015, 0x009a, 0x0010, 0x0056,
+	0x0005, 0x009b, 0x0010, 0x95f5, 0x0012, 0xd042, 0x0003, 0x1880,
+	0x0005, 0x00b0, 0x0010, 0x8080, 0x0011, 0x1388, 0x0010, 0x0011,
+	0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb00a, 0x000b, 0x887b,
+	0x0015, 0x00b8, 0x0010, 0x000c, 0x0014, 0x091f, 0x0003, 0x0882,
+	0x0005, 0x0075, 0x0010, 0x8092, 0x0015, 0x00b1, 0x0010, 0x07d0,
+	0x0005, 0x00b0, 0x0010, 0x0009, 0x0001, 0xbd88, 0x0000, 0x000b,
+	0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb012, 0x000b, 0x888b,
+	0x0003, 0x06fd, 0x0015, 0x00d1, 0x0000, 0x0400, 0x0001, 0x1288,
+	0x0010, 0x0003, 0x0000, 0xff31, 0x0015, 0x0033, 0x0000, 0xb009,
+	0x001b, 0x8894, 0x0001, 0x1288, 0x0010, 0x0003, 0x0000, 0xff31,
+	0x0015, 0x0033, 0x0010, 0xc00a, 0x000b, 0x889a, 0x0010, 0xb0fe,
+	0x0003, 0x689f, 0x0000, 0xb012, 0x0003, 0x06fd, 0x0010, 0xc012,
+	0x0010, 0xc011, 0x0003, 0x06fd, 0x0000, 0xba30, 0x0005, 0x0031,
+	0x0010, 0x0021, 0x0015, 0x0033, 0x0010, 0xb019, 0x001b, 0x88a7,
 	0x0002, 0xb200, 0x0011, 0xffc8, 0x0010, 0x00ff, 0x0010, 0xffb2,
 	0x0010, 0xb2b7, 0x0005, 0x0031, 0x0000, 0x0023, 0x0015, 0x0033,
-	0x0010, 0xb20a, 0x000b, 0x87f9, 0x0017, 0x4000, 0x0000, 0xba30,
+	0x0010, 0xb20a, 0x000b, 0x88b1, 0x0017, 0x4000, 0x0000, 0xba30,
 	0x0005, 0x0031, 0x0000, 0x0023, 0x0015, 0x0033, 0x0010, 0xb409,
-	0x000b, 0x8800, 0x0002, 0xb400, 0x0011, 0xffc8, 0x0010, 0x00ff,
+	0x000b, 0x88b8, 0x0002, 0xb400, 0x0011, 0xffc8, 0x0010, 0x00ff,
 	0x0010, 0xffb4, 0x0010, 0xb4b7, 0x0005, 0x0031, 0x0000, 0x0023,
-	0x0015, 0x0033, 0x0010, 0xb40a, 0x000b, 0x880a, 0x0017, 0x4000,
-	0x0000, 0xba30, 0x0001, 0xc7c8, 0x0000, 0x0020, 0x000b, 0x1818,
+	0x0015, 0x0033, 0x0010, 0xb40a, 0x001b, 0x88c2, 0x0017, 0x4000,
+	0x0000, 0xba30, 0x0001, 0xc7c8, 0x0000, 0x0020, 0x001b, 0x18d0,
 	0x0005, 0x0031, 0x0010, 0x0028, 0x0015, 0x0033, 0x0010, 0xb209,
-	0x000b, 0x8814, 0x0011, 0xb2c8, 0x0000, 0xff80, 0x0013, 0x181b,
-	0x0010, 0xc4b0, 0x0010, 0xc5b1, 0x0003, 0x081d, 0x0010, 0xc6b1,
+	0x000b, 0x88cc, 0x0011, 0xb2c8, 0x0000, 0xff80, 0x0003, 0x18d3,
+	0x0010, 0xc4b0, 0x0010, 0xc5b1, 0x0013, 0x08d5, 0x0010, 0xc6b1,
 	0x0000, 0xc0b0, 0x0005, 0x0031, 0x0000, 0x0004, 0x0015, 0x0033,
-	0x0010, 0xb211, 0x000b, 0x8821, 0x0017, 0x4000, 0x0015, 0x00b8,
-	0x0010, 0x0009, 0x0015, 0x003a, 0x0010, 0x0707, 0x0004, 0x0867,
+	0x0010, 0xb211, 0x001b, 0x88d9, 0x0017, 0x4000, 0x0015, 0x00b8,
+	0x0010, 0x0009, 0x0015, 0x003a, 0x0010, 0x0707, 0x0014, 0x091f,
 	0x0013, 0x002d, 0x0015, 0x00b8, 0x0010, 0x0009, 0x0015, 0x003a,
-	0x0010, 0x0707, 0x0013, 0x0867, 0x0014, 0x0114, 0x0015, 0x0030,
+	0x0010, 0x0707, 0x0003, 0x091f, 0x0004, 0x0119, 0x0015, 0x0030,
 	0x0000, 0x0400, 0x0011, 0x0d88, 0x0000, 0x0004, 0x0000, 0xff31,
-	0x0015, 0x0033, 0x0000, 0xba09, 0x000b, 0x8836, 0x0004, 0x07ea,
+	0x0015, 0x0033, 0x0000, 0xba09, 0x000b, 0x88ee, 0x0004, 0x08a2,
 	0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88, 0x0000, 0x0010,
-	0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xb20a, 0x000b, 0x883f,
+	0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xb20a, 0x001b, 0x88f7,
 	0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x0d88, 0x0010, 0x0011,
-	0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0x0309, 0x000b, 0x8847,
+	0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0x0309, 0x000b, 0x88ff,
 	0x0002, 0x0327, 0x0010, 0xffb2, 0x0011, 0x0d88, 0x0010, 0x0011,
-	0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xb20a, 0x001b, 0x884f,
-	0x0015, 0x00b8, 0x0010, 0x0006, 0x0013, 0x0867, 0x0004, 0x0126,
-	0x0004, 0x07ea, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x1388,
+	0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xb20a, 0x000b, 0x8907,
+	0x0015, 0x00b8, 0x0010, 0x0006, 0x0003, 0x091f, 0x0014, 0x012b,
+	0x0004, 0x08a2, 0x0015, 0x0030, 0x0000, 0x0400, 0x0011, 0x1388,
 	0x0000, 0x0010, 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xb20a,
-	0x000b, 0x885c, 0x0012, 0x1027, 0x0010, 0xffb2, 0x0011, 0x1388,
+	0x001b, 0x8914, 0x0012, 0x1027, 0x0010, 0xffb2, 0x0011, 0x1388,
 	0x0010, 0x0011, 0x0000, 0xff31, 0x0015, 0x0033, 0x0010, 0xb20a,
-	0x001b, 0x8864, 0x0015, 0x00b8, 0x0000, 0x0007, 0x0003, 0x4867,
-	0x0000, 0xb838, 0x0017, 0x4000, 0xa2e7, 0x24ad
+	0x000b, 0x891c, 0x0015, 0x00b8, 0x0000, 0x0007, 0x0013, 0x491f,
+	0x0000, 0xb838, 0x0017, 0x4000, 0x9aec, 0x3b6c
 };
-unsigned short xseqipx_code_length01 = 0x10d6;
+unsigned short xseqipx_code_length01 = 0x1246;
diff --git a/drivers/scsi/qla2xxx/ql6312.c b/drivers/scsi/qla2xxx/ql6312.c
--- a/drivers/scsi/qla2xxx/ql6312.c
+++ b/drivers/scsi/qla2xxx/ql6312.c
@@ -1,6 +1,6 @@
 /*
  * QLogic ISP6312 device driver for Linux 2.6.x
- * Copyright (C) 2003-2004 QLogic Corporation (www.qlogic.com)
+ * Copyright (C) 2003-2005 QLogic Corporation (www.qlogic.com)
  *
  * Released under GPL v2.
  */
diff --git a/drivers/scsi/qla2xxx/ql6312_fw.c b/drivers/scsi/qla2xxx/ql6312_fw.c
--- a/drivers/scsi/qla2xxx/ql6312_fw.c
+++ b/drivers/scsi/qla2xxx/ql6312_fw.c
@@ -2,7 +2,7 @@
  *                  QLOGIC LINUX SOFTWARE
  *
  * QLogic ISP2x00 device driver for Linux 2.6.x
- * Copyright (C) 2003 QLogic Corporation
+ * Copyright (C) 2005 QLogic Corporation
  * (www.qlogic.com)
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -18,7 +18,7 @@
  ******************************************************************************/
 
 /*
- *	Firmware Version 3.03.08 (10:02 Nov 12, 2004)
+ *	Firmware Version 3.03.15 (10:00 May 26, 2005)
  */
 
 #ifdef UNIQUE_FW_NAME
@@ -28,15 +28,15 @@ unsigned short risc_code_version = 3*102
 #endif
 
 #ifdef UNIQUE_FW_NAME
-unsigned char fw2300flx_version_str[] = {3, 3, 8};
+unsigned char fw2300flx_version_str[] = {3, 3,15};
 #else
-unsigned char firmware_version[] = {3, 3, 8};
+unsigned char firmware_version[] = {3, 3,15};
 #endif
 
 #ifdef UNIQUE_FW_NAME
-#define fw2300flx_VERSION_STRING "3.03.08"
+#define fw2300flx_VERSION_STRING "3.03.15"
 #else
-#define FW_VERSION_STRING "3.03.08"
+#define FW_VERSION_STRING "3.03.15"
 #endif
 
 #ifdef UNIQUE_FW_NAME
@@ -50,12 +50,12 @@ unsigned short fw2300flx_code01[] = { 
 #else
 unsigned short risc_code01[] = { 
 #endif
-	0x0470, 0x0000, 0x0000, 0xdd79, 0x0000, 0x0003, 0x0003, 0x0008,
+	0x0470, 0x0000, 0x0000, 0xdb56, 0x0000, 0x0003, 0x0003, 0x000f,
 	0x0317, 0x2043, 0x4f50, 0x5952, 0x4947, 0x4854, 0x2032, 0x3030,
 	0x3120, 0x514c, 0x4f47, 0x4943, 0x2043, 0x4f52, 0x504f, 0x5241,
 	0x5449, 0x4f4e, 0x2049, 0x5350, 0x3233, 0x3030, 0x2046, 0x6972,
 	0x6d77, 0x6172, 0x6520, 0x2056, 0x6572, 0x7369, 0x6f6e, 0x2030,
-	0x332e, 0x3033, 0x2e30, 0x3820, 0x2020, 0x2020, 0x2400, 0x20a9,
+	0x332e, 0x3033, 0x2e31, 0x3520, 0x2020, 0x2020, 0x2400, 0x20a9,
 	0x000f, 0x2001, 0x0000, 0x400f, 0x2091, 0x2200, 0x20a9, 0x000f,
 	0x2001, 0x0000, 0x400f, 0x2091, 0x2400, 0x20a9, 0x000f, 0x2001,
 	0x0000, 0x400f, 0x2091, 0x2600, 0x20a9, 0x000f, 0x2001, 0x0000,
@@ -64,8 +64,8 @@ unsigned short risc_code01[] = { 
 	0x2c00, 0x20a9, 0x000f, 0x2001, 0x0000, 0x400f, 0x2091, 0x2e00,
 	0x20a9, 0x000f, 0x2001, 0x0000, 0x400f, 0x2091, 0x2000, 0x2001,
 	0x0000, 0x20c1, 0x0004, 0x20c9, 0x1bff, 0x2059, 0x0000, 0x2b78,
-	0x7883, 0x0004, 0x2089, 0x2cff, 0x2051, 0x1800, 0x2a70, 0x20e1,
-	0x0001, 0x20e9, 0x0001, 0x2009, 0x0000, 0x080c, 0x0e75, 0x2029,
+	0x7883, 0x0004, 0x2089, 0x2c1f, 0x2051, 0x1800, 0x2a70, 0x20e1,
+	0x0001, 0x20e9, 0x0001, 0x2009, 0x0000, 0x080c, 0x0e87, 0x2029,
 	0x2480, 0x2031, 0xffff, 0x2039, 0x2450, 0x2021, 0x0050, 0x20e9,
 	0x0001, 0x20a1, 0x0000, 0x20a9, 0x0800, 0x900e, 0x4104, 0x20e9,
 	0x0001, 0x20a1, 0x1000, 0x900e, 0x2001, 0x0cc0, 0x9084, 0x0fff,
@@ -77,1090 +77,1058 @@ unsigned short risc_code01[] = { 
 	0x8001, 0x9102, 0x0120, 0x0218, 0x20a8, 0x900e, 0x4104, 0x2009,
 	0x1800, 0x810d, 0x810d, 0x810d, 0x810d, 0x810d, 0x918c, 0x001f,
 	0x2001, 0x0001, 0x9112, 0x20e9, 0x0001, 0x20a1, 0x0800, 0x900e,
-	0x20a9, 0x0800, 0x4104, 0x8211, 0x1dd8, 0x080c, 0x0f49, 0x080c,
-	0x5f39, 0x080c, 0xa079, 0x080c, 0x1100, 0x080c, 0x12f8, 0x080c,
-	0x1af5, 0x080c, 0x0d8c, 0x080c, 0x1085, 0x080c, 0x33e9, 0x080c,
-	0x7518, 0x080c, 0x687e, 0x080c, 0x8215, 0x080c, 0x23bd, 0x080c,
-	0x8526, 0x080c, 0x7b99, 0x080c, 0x21e9, 0x080c, 0x231d, 0x080c,
-	0x23b2, 0x2091, 0x3009, 0x7883, 0x0000, 0x1004, 0x091d, 0x7880,
+	0x20a9, 0x0800, 0x4104, 0x8211, 0x1dd8, 0x080c, 0x0f5b, 0x080c,
+	0x5e3e, 0x080c, 0x9f6b, 0x080c, 0x1112, 0x080c, 0x130a, 0x080c,
+	0x1a79, 0x080c, 0x0d94, 0x080c, 0x1097, 0x080c, 0x3309, 0x080c,
+	0x748f, 0x080c, 0x6785, 0x080c, 0x8195, 0x080c, 0x22b7, 0x080c,
+	0x84a6, 0x080c, 0x7b19, 0x080c, 0x20e3, 0x080c, 0x2217, 0x080c,
+	0x22ac, 0x2091, 0x3009, 0x7883, 0x0000, 0x1004, 0x091d, 0x7880,
 	0x9086, 0x0002, 0x1190, 0x7883, 0x4000, 0x7837, 0x4000, 0x7833,
 	0x0010, 0x0e04, 0x0911, 0x2091, 0x5000, 0x2091, 0x4080, 0x2001,
-	0x0089, 0x2004, 0xd084, 0x190c, 0x11e0, 0x2071, 0x1800, 0x7003,
+	0x0089, 0x2004, 0xd084, 0x190c, 0x11f2, 0x2071, 0x1800, 0x7003,
 	0x0000, 0x2071, 0x1800, 0x7000, 0x908e, 0x0003, 0x1168, 0x080c,
-	0x4be4, 0x080c, 0x3410, 0x080c, 0x7580, 0x080c, 0x6d2e, 0x080c,
-	0x823e, 0x080c, 0x2c2c, 0x0c68, 0x000b, 0x0c88, 0x0940, 0x0941,
-	0x0ad8, 0x093e, 0x0b8f, 0x0d8b, 0x0d8b, 0x0d8b, 0x080c, 0x0dfa,
+	0x4add, 0x080c, 0x3330, 0x080c, 0x74f7, 0x080c, 0x6c83, 0x080c,
+	0x81be, 0x080c, 0x2b2c, 0x0c68, 0x000b, 0x0c88, 0x0940, 0x0941,
+	0x0ad8, 0x093e, 0x0b8f, 0x0d93, 0x0d93, 0x0d93, 0x080c, 0x0e02,
 	0x0005, 0x0126, 0x00f6, 0x2091, 0x8000, 0x7000, 0x9086, 0x0001,
-	0x1904, 0x0aab, 0x080c, 0x0eb7, 0x080c, 0x7207, 0x0150, 0x080c,
-	0x722a, 0x15a0, 0x2079, 0x0100, 0x7828, 0x9085, 0x1800, 0x782a,
-	0x0468, 0x080c, 0x7127, 0x7000, 0x9086, 0x0001, 0x1904, 0x0aab,
-	0x7094, 0x9086, 0x0028, 0x1904, 0x0aab, 0x080c, 0x81fe, 0x080c,
-	0x81f0, 0x2001, 0x0161, 0x2003, 0x0001, 0x2079, 0x0100, 0x7827,
-	0xffff, 0x7a28, 0x9295, 0x5e2f, 0x7a2a, 0x2011, 0x7076, 0x080c,
-	0x82da, 0x2011, 0x7069, 0x080c, 0x83ae, 0x2011, 0x5d94, 0x080c,
-	0x82da, 0x2011, 0x8030, 0x901e, 0x7392, 0x04d0, 0x080c, 0x5641,
-	0x2079, 0x0100, 0x7844, 0x9005, 0x1904, 0x0aab, 0x2011, 0x5d94,
-	0x080c, 0x82da, 0x2011, 0x7076, 0x080c, 0x82da, 0x2011, 0x7069,
-	0x080c, 0x83ae, 0x2001, 0x0265, 0x2001, 0x0205, 0x2003, 0x0000,
-	0x7840, 0x9084, 0xfffb, 0x7842, 0x2001, 0x197e, 0x2004, 0x9005,
-	0x1140, 0x00c6, 0x2061, 0x0100, 0x080c, 0x5ee1, 0x00ce, 0x0804,
-	0x0aab, 0x780f, 0x006b, 0x7a28, 0x080c, 0x720f, 0x0118, 0x9295,
+	0x1904, 0x0aab, 0x080c, 0x0ec9, 0x080c, 0x717f, 0x0150, 0x080c,
+	0x71a2, 0x15a0, 0x2079, 0x0100, 0x7828, 0x9085, 0x1800, 0x782a,
+	0x0468, 0x080c, 0x709f, 0x7000, 0x9086, 0x0001, 0x1904, 0x0aab,
+	0x7094, 0x9086, 0x0029, 0x1904, 0x0aab, 0x080c, 0x817e, 0x080c,
+	0x8170, 0x2001, 0x0161, 0x2003, 0x0001, 0x2079, 0x0100, 0x7827,
+	0xffff, 0x7a28, 0x9295, 0x5e2f, 0x7a2a, 0x2011, 0x6fee, 0x080c,
+	0x825a, 0x2011, 0x6fe1, 0x080c, 0x832e, 0x2011, 0x5c99, 0x080c,
+	0x825a, 0x2011, 0x8030, 0x901e, 0x7392, 0x04d0, 0x080c, 0x5546,
+	0x2079, 0x0100, 0x7844, 0x9005, 0x1904, 0x0aab, 0x2011, 0x5c99,
+	0x080c, 0x825a, 0x2011, 0x6fee, 0x080c, 0x825a, 0x2011, 0x6fe1,
+	0x080c, 0x832e, 0x2001, 0x0265, 0x2001, 0x0205, 0x2003, 0x0000,
+	0x7840, 0x9084, 0xfffb, 0x7842, 0x2001, 0x1980, 0x2004, 0x9005,
+	0x1140, 0x00c6, 0x2061, 0x0100, 0x080c, 0x5de6, 0x00ce, 0x0804,
+	0x0aab, 0x780f, 0x006b, 0x7a28, 0x080c, 0x7187, 0x0118, 0x9295,
 	0x5e2f, 0x0010, 0x9295, 0x402f, 0x7a2a, 0x2011, 0x8010, 0x73d4,
-	0x2001, 0x197f, 0x2003, 0x0001, 0x080c, 0x2a89, 0x080c, 0x4b1f,
+	0x2001, 0x1981, 0x2003, 0x0001, 0x080c, 0x2989, 0x080c, 0x4a18,
 	0x7244, 0xc284, 0x7246, 0x2001, 0x180c, 0x200c, 0xc1ac, 0xc1cc,
-	0x2102, 0x080c, 0x9904, 0x2011, 0x0004, 0x080c, 0xbe47, 0x080c,
-	0x66c2, 0x080c, 0x7207, 0x1120, 0x080c, 0x2af6, 0x02e0, 0x0400,
-	0x080c, 0x5ee8, 0x0140, 0x7093, 0x0001, 0x70cf, 0x0000, 0x080c,
-	0x580e, 0x0804, 0x0aab, 0x080c, 0x55db, 0xd094, 0x0188, 0x2011,
-	0x180c, 0x2204, 0xc0cd, 0x2012, 0x080c, 0x55df, 0xd0d4, 0x1118,
-	0x080c, 0x2af6, 0x1270, 0x2011, 0x180c, 0x2204, 0xc0bc, 0x0088,
-	0x080c, 0x55df, 0xd0d4, 0x1db8, 0x2011, 0x180c, 0x2204, 0xc0bd,
-	0x0040, 0x2011, 0x180c, 0x2204, 0xc0bd, 0x2012, 0x080c, 0x67bb,
-	0x0008, 0x2012, 0x080c, 0x6781, 0x0120, 0x7a0c, 0xc2b4, 0x7a0e,
-	0x00a8, 0x707b, 0x0000, 0x080c, 0x7207, 0x1130, 0x70ac, 0x9005,
-	0x1168, 0x080c, 0xc28a, 0x0050, 0x080c, 0xc28a, 0x70d8, 0xd09c,
-	0x1128, 0x70ac, 0x9005, 0x0110, 0x080c, 0x5ebe, 0x70e3, 0x0000,
-	0x70df, 0x0000, 0x70a3, 0x0000, 0x080c, 0x2afe, 0x0228, 0x2011,
-	0x0101, 0x2204, 0xc0c4, 0x2012, 0x72d8, 0x080c, 0x7207, 0x1178,
-	0x9016, 0x0016, 0x2009, 0x0002, 0x2019, 0x1945, 0x211a, 0x001e,
+	0x2102, 0x080c, 0x9803, 0x2011, 0x0004, 0x080c, 0xbd4b, 0x080c,
+	0x65c7, 0x080c, 0x717f, 0x1120, 0x080c, 0x29f6, 0x02e0, 0x0400,
+	0x080c, 0x5ded, 0x0140, 0x7093, 0x0001, 0x70cf, 0x0000, 0x080c,
+	0x5713, 0x0804, 0x0aab, 0x080c, 0x54dc, 0xd094, 0x0188, 0x2011,
+	0x180c, 0x2204, 0xc0cd, 0x2012, 0x080c, 0x54e0, 0xd0d4, 0x1118,
+	0x080c, 0x29f6, 0x1270, 0x2011, 0x180c, 0x2204, 0xc0bc, 0x0088,
+	0x080c, 0x54e0, 0xd0d4, 0x1db8, 0x2011, 0x180c, 0x2204, 0xc0bd,
+	0x0040, 0x2011, 0x180c, 0x2204, 0xc0bd, 0x2012, 0x080c, 0x66c2,
+	0x0008, 0x2012, 0x080c, 0x6688, 0x0120, 0x7a0c, 0xc2b4, 0x7a0e,
+	0x00a8, 0x707b, 0x0000, 0x080c, 0x717f, 0x1130, 0x70ac, 0x9005,
+	0x1168, 0x080c, 0xc18e, 0x0050, 0x080c, 0xc18e, 0x70d8, 0xd09c,
+	0x1128, 0x70ac, 0x9005, 0x0110, 0x080c, 0x5dc3, 0x70e3, 0x0000,
+	0x70df, 0x0000, 0x70a3, 0x0000, 0x080c, 0x29fe, 0x0228, 0x2011,
+	0x0101, 0x2204, 0xc0c4, 0x2012, 0x72d8, 0x080c, 0x717f, 0x1178,
+	0x9016, 0x0016, 0x2009, 0x0002, 0x2019, 0x1947, 0x211a, 0x001e,
 	0x705b, 0xffff, 0x705f, 0x00ef, 0x707f, 0x0000, 0x0020, 0x2019,
-	0x1945, 0x201b, 0x0000, 0x2079, 0x185b, 0x7804, 0xd0ac, 0x0108,
-	0xc295, 0x72da, 0x080c, 0x7207, 0x0118, 0x9296, 0x0004, 0x0548,
-	0x2011, 0x0001, 0x080c, 0xbe47, 0x70a7, 0x0000, 0x70ab, 0xffff,
+	0x1947, 0x201b, 0x0000, 0x2079, 0x185b, 0x7804, 0xd0ac, 0x0108,
+	0xc295, 0x72da, 0x080c, 0x717f, 0x0118, 0x9296, 0x0004, 0x0548,
+	0x2011, 0x0001, 0x080c, 0xbd4b, 0x70a7, 0x0000, 0x70ab, 0xffff,
 	0x7003, 0x0002, 0x2079, 0x0100, 0x7827, 0x0003, 0x7828, 0x9085,
-	0x0003, 0x782a, 0x00fe, 0x080c, 0x2f6c, 0x2011, 0x0005, 0x080c,
-	0x9a0f, 0x080c, 0x8c10, 0x080c, 0x7207, 0x0148, 0x00c6, 0x2061,
+	0x0003, 0x782a, 0x00fe, 0x080c, 0x2e8c, 0x2011, 0x0005, 0x080c,
+	0x990e, 0x080c, 0x8b90, 0x080c, 0x717f, 0x0148, 0x00c6, 0x2061,
 	0x0100, 0x0016, 0x2009, 0x0002, 0x61e2, 0x001e, 0x00ce, 0x012e,
 	0x0420, 0x70a7, 0x0000, 0x70ab, 0xffff, 0x7003, 0x0002, 0x00f6,
 	0x2079, 0x0100, 0x7827, 0x0003, 0x7828, 0x9085, 0x0003, 0x782a,
-	0x00fe, 0x2011, 0x0005, 0x080c, 0x9a0f, 0x080c, 0x8c10, 0x080c,
-	0x7207, 0x0148, 0x00c6, 0x2061, 0x0100, 0x0016, 0x2009, 0x0002,
+	0x00fe, 0x2011, 0x0005, 0x080c, 0x990e, 0x080c, 0x8b90, 0x080c,
+	0x717f, 0x0148, 0x00c6, 0x2061, 0x0100, 0x0016, 0x2009, 0x0002,
 	0x61e2, 0x001e, 0x00ce, 0x00fe, 0x012e, 0x0005, 0x00c6, 0x00b6,
-	0x080c, 0x7207, 0x1118, 0x20a9, 0x0800, 0x0010, 0x20a9, 0x0782,
-	0x080c, 0x7207, 0x1110, 0x900e, 0x0010, 0x2009, 0x007e, 0x86ff,
+	0x080c, 0x717f, 0x1118, 0x20a9, 0x0800, 0x0010, 0x20a9, 0x0782,
+	0x080c, 0x717f, 0x1110, 0x900e, 0x0010, 0x2009, 0x007e, 0x86ff,
 	0x0138, 0x9180, 0x1000, 0x2004, 0x905d, 0x0110, 0xb800, 0xd0bc,
-	0x090c, 0x3286, 0x8108, 0x1f04, 0x0abf, 0x707b, 0x0000, 0x707c,
+	0x090c, 0x31a6, 0x8108, 0x1f04, 0x0abf, 0x707b, 0x0000, 0x707c,
 	0x9084, 0x00ff, 0x707e, 0x70af, 0x0000, 0x00be, 0x00ce, 0x0005,
 	0x00b6, 0x0126, 0x2091, 0x8000, 0x7000, 0x9086, 0x0002, 0x1904,
-	0x0b8c, 0x70a8, 0x9086, 0xffff, 0x0130, 0x080c, 0x2f6c, 0x080c,
-	0x8c10, 0x0804, 0x0b8c, 0x70d8, 0xd0ac, 0x1110, 0xd09c, 0x0540,
+	0x0b8c, 0x70a8, 0x9086, 0xffff, 0x0130, 0x080c, 0x2e8c, 0x080c,
+	0x8b90, 0x0804, 0x0b8c, 0x70d8, 0xd0ac, 0x1110, 0xd09c, 0x0540,
 	0xd084, 0x0530, 0x0006, 0x2001, 0x0103, 0x2003, 0x002b, 0x000e,
-	0xd08c, 0x01f0, 0x70dc, 0x9086, 0xffff, 0x01b0, 0x080c, 0x30f7,
-	0x080c, 0x8c10, 0x70d8, 0xd094, 0x1904, 0x0b8c, 0x2011, 0x0001,
-	0x080c, 0xc539, 0x0110, 0x2011, 0x0003, 0x901e, 0x080c, 0x3131,
-	0x080c, 0x8c10, 0x0804, 0x0b8c, 0x70e0, 0x9005, 0x1904, 0x0b8c,
+	0xd08c, 0x01f0, 0x70dc, 0x9086, 0xffff, 0x01b0, 0x080c, 0x3017,
+	0x080c, 0x8b90, 0x70d8, 0xd094, 0x1904, 0x0b8c, 0x2011, 0x0001,
+	0x080c, 0xc444, 0x0110, 0x2011, 0x0003, 0x901e, 0x080c, 0x3051,
+	0x080c, 0x8b90, 0x0804, 0x0b8c, 0x70e0, 0x9005, 0x1904, 0x0b8c,
 	0x70a4, 0x9005, 0x1904, 0x0b8c, 0x70d8, 0xd0a4, 0x0118, 0xd0b4,
-	0x0904, 0x0b8c, 0x080c, 0x6781, 0x1904, 0x0b8c, 0x080c, 0x67d4,
-	0x1904, 0x0b8c, 0x080c, 0x67bb, 0x01c0, 0x0156, 0x00c6, 0x20a9,
-	0x007f, 0x900e, 0x0016, 0x080c, 0x649f, 0x1118, 0xb800, 0xd0ec,
+	0x0904, 0x0b8c, 0x080c, 0x6688, 0x1904, 0x0b8c, 0x080c, 0x66db,
+	0x1904, 0x0b8c, 0x080c, 0x66c2, 0x01c0, 0x0156, 0x00c6, 0x20a9,
+	0x007f, 0x900e, 0x0016, 0x080c, 0x63a4, 0x1118, 0xb800, 0xd0ec,
 	0x1138, 0x001e, 0x8108, 0x1f04, 0x0b32, 0x00ce, 0x015e, 0x0028,
 	0x001e, 0x00ce, 0x015e, 0x0804, 0x0b8c, 0x0006, 0x2001, 0x0103,
-	0x2003, 0x006b, 0x000e, 0x2011, 0x198b, 0x080c, 0x0fb9, 0x2011,
-	0x19a5, 0x080c, 0x0fb9, 0x7030, 0xc08c, 0x7032, 0x7003, 0x0003,
-	0x70ab, 0xffff, 0x080c, 0x0e99, 0x9006, 0x080c, 0x2717, 0x0036,
-	0x0046, 0x2019, 0xffff, 0x2021, 0x0006, 0x080c, 0x4cbc, 0x004e,
-	0x003e, 0x00f6, 0x2079, 0x0100, 0x080c, 0x722a, 0x0150, 0x080c,
-	0x7207, 0x7828, 0x0118, 0x9084, 0xe1ff, 0x0010, 0x9084, 0xffdf,
-	0x782a, 0x00fe, 0x2001, 0x19c0, 0x2004, 0x9086, 0x0005, 0x1120,
-	0x2011, 0x0000, 0x080c, 0x9a0f, 0x2011, 0x0000, 0x080c, 0x9a19,
-	0x080c, 0x8c10, 0x080c, 0x8ced, 0x012e, 0x00be, 0x0005, 0x0016,
+	0x2003, 0x006b, 0x000e, 0x2011, 0x198e, 0x080c, 0x0fcb, 0x2011,
+	0x19a8, 0x080c, 0x0fcb, 0x7030, 0xc08c, 0x7032, 0x7003, 0x0003,
+	0x70ab, 0xffff, 0x080c, 0x0eab, 0x9006, 0x080c, 0x2617, 0x0036,
+	0x0046, 0x2019, 0xffff, 0x2021, 0x0006, 0x080c, 0x4bb5, 0x004e,
+	0x003e, 0x00f6, 0x2079, 0x0100, 0x080c, 0x71a2, 0x0150, 0x080c,
+	0x717f, 0x7828, 0x0118, 0x9084, 0xe1ff, 0x0010, 0x9084, 0xffdf,
+	0x782a, 0x00fe, 0x2001, 0x19c3, 0x2004, 0x9086, 0x0005, 0x1120,
+	0x2011, 0x0000, 0x080c, 0x990e, 0x2011, 0x0000, 0x080c, 0x9918,
+	0x080c, 0x8b90, 0x080c, 0x8c6d, 0x012e, 0x00be, 0x0005, 0x0016,
 	0x0046, 0x00f6, 0x0126, 0x2091, 0x8000, 0x2079, 0x0100, 0x7904,
-	0x918c, 0xfffd, 0x7906, 0x2009, 0x00f7, 0x080c, 0x5ea7, 0x7940,
+	0x918c, 0xfffd, 0x7906, 0x2009, 0x00f7, 0x080c, 0x5dac, 0x7940,
 	0x918c, 0x0010, 0x7942, 0x7924, 0xd1b4, 0x0110, 0x7827, 0x0040,
 	0xd19c, 0x0110, 0x7827, 0x0008, 0x0006, 0x0036, 0x0156, 0x2001,
 	0x0100, 0x2004, 0x9086, 0x000a, 0x1904, 0x0c23, 0x7954, 0xd1ac,
-	0x1904, 0x0c23, 0x2001, 0x197f, 0x2004, 0x9005, 0x1518, 0x080c,
-	0x2b98, 0x1148, 0x2001, 0x0001, 0x080c, 0x2ab8, 0x2001, 0x0001,
-	0x080c, 0x2a9b, 0x00b8, 0x080c, 0x2ba0, 0x1138, 0x9006, 0x080c,
-	0x2ab8, 0x9006, 0x080c, 0x2a9b, 0x0068, 0x080c, 0x2ba8, 0x1d50,
-	0x2001, 0x1970, 0x2004, 0xd0fc, 0x0108, 0x0020, 0x080c, 0x28b2,
-	0x0804, 0x0d33, 0x080c, 0x7218, 0x0148, 0x080c, 0x722a, 0x1118,
-	0x080c, 0x7513, 0x0050, 0x080c, 0x720f, 0x0dd0, 0x080c, 0x750e,
-	0x080c, 0x7504, 0x080c, 0x7127, 0x0058, 0x080c, 0x7207, 0x0140,
-	0x2009, 0x00f8, 0x080c, 0x5ea7, 0x7843, 0x0090, 0x7843, 0x0010,
-	0x20a9, 0x09c4, 0x7820, 0xd09c, 0x1138, 0x080c, 0x7207, 0x0138,
-	0x7824, 0xd0ac, 0x1904, 0x0d38, 0x1f04, 0x0c02, 0x0070, 0x7824,
-	0x080c, 0x7221, 0x0118, 0xd0ac, 0x1904, 0x0d38, 0x9084, 0x1800,
-	0x0d98, 0x7003, 0x0001, 0x0804, 0x0d38, 0x2001, 0x0001, 0x080c,
-	0x2717, 0x0804, 0x0d5a, 0x2001, 0x197f, 0x2004, 0x9005, 0x1518,
-	0x080c, 0x2b98, 0x1148, 0x2001, 0x0001, 0x080c, 0x2ab8, 0x2001,
-	0x0001, 0x080c, 0x2a9b, 0x00b8, 0x080c, 0x2ba0, 0x1138, 0x9006,
-	0x080c, 0x2ab8, 0x9006, 0x080c, 0x2a9b, 0x0068, 0x080c, 0x2ba8,
-	0x1d50, 0x2001, 0x1970, 0x2004, 0xd0fc, 0x0108, 0x0020, 0x080c,
-	0x28b2, 0x0804, 0x0d33, 0x2001, 0x0100, 0x2004, 0x9086, 0x000a,
+	0x1904, 0x0c23, 0x2001, 0x1981, 0x2004, 0x9005, 0x1518, 0x080c,
+	0x2a98, 0x1148, 0x2001, 0x0001, 0x080c, 0x29b8, 0x2001, 0x0001,
+	0x080c, 0x299b, 0x00b8, 0x080c, 0x2aa0, 0x1138, 0x9006, 0x080c,
+	0x29b8, 0x9006, 0x080c, 0x299b, 0x0068, 0x080c, 0x2aa8, 0x1d50,
+	0x2001, 0x1972, 0x2004, 0xd0fc, 0x0108, 0x0020, 0x080c, 0x27b2,
+	0x0804, 0x0d3b, 0x080c, 0x7190, 0x0148, 0x080c, 0x71a2, 0x1118,
+	0x080c, 0x748a, 0x0050, 0x080c, 0x7187, 0x0dd0, 0x080c, 0x7485,
+	0x080c, 0x747b, 0x080c, 0x709f, 0x0058, 0x080c, 0x717f, 0x0140,
+	0x2009, 0x00f8, 0x080c, 0x5dac, 0x7843, 0x0090, 0x7843, 0x0010,
+	0x20a9, 0x09c4, 0x7820, 0xd09c, 0x1138, 0x080c, 0x717f, 0x0138,
+	0x7824, 0xd0ac, 0x1904, 0x0d40, 0x1f04, 0x0c02, 0x0070, 0x7824,
+	0x080c, 0x7199, 0x0118, 0xd0ac, 0x1904, 0x0d40, 0x9084, 0x1800,
+	0x0d98, 0x7003, 0x0001, 0x0804, 0x0d40, 0x2001, 0x0001, 0x080c,
+	0x2617, 0x0804, 0x0d62, 0x2001, 0x1981, 0x2004, 0x9005, 0x1518,
+	0x080c, 0x2a98, 0x1148, 0x2001, 0x0001, 0x080c, 0x29b8, 0x2001,
+	0x0001, 0x080c, 0x299b, 0x00b8, 0x080c, 0x2aa0, 0x1138, 0x9006,
+	0x080c, 0x29b8, 0x9006, 0x080c, 0x299b, 0x0068, 0x080c, 0x2aa8,
+	0x1d50, 0x2001, 0x1972, 0x2004, 0xd0fc, 0x0108, 0x0020, 0x080c,
+	0x27b2, 0x0804, 0x0d3b, 0x2001, 0x0100, 0x2004, 0x9086, 0x000a,
 	0x01f8, 0x7850, 0x9085, 0x0040, 0x7852, 0x7938, 0x7850, 0x9084,
-	0xfbcf, 0x7852, 0x080c, 0x2bb0, 0x9085, 0x2000, 0x7852, 0x793a,
-	0x20a9, 0x0046, 0x1d04, 0x0c62, 0x080c, 0x838e, 0x1f04, 0x0c62,
-	0x7850, 0x9085, 0x0400, 0x9084, 0xdfbf, 0x7852, 0x793a, 0x0060,
-	0x080c, 0x2cc2, 0x080c, 0x2cf5, 0x20a9, 0x003a, 0x1d04, 0x0c76,
-	0x080c, 0x838e, 0x1f04, 0x0c76, 0x080c, 0x7218, 0x0148, 0x080c,
-	0x722a, 0x1118, 0x080c, 0x7513, 0x0050, 0x080c, 0x720f, 0x0dd0,
-	0x080c, 0x750e, 0x080c, 0x7504, 0x080c, 0x7127, 0x0020, 0x2009,
-	0x00f8, 0x080c, 0x5ea7, 0x2001, 0x0100, 0x2004, 0x9086, 0x000a,
-	0x0168, 0x20a9, 0x0028, 0xa001, 0x1f04, 0x0c9b, 0x7850, 0x9085,
-	0x1400, 0x7852, 0x080c, 0x7207, 0x0158, 0x0030, 0x7850, 0xc0e5,
-	0x7852, 0x080c, 0x7207, 0x0120, 0x7843, 0x0090, 0x7843, 0x0010,
-	0x2021, 0xe678, 0x2019, 0xea60, 0x0d0c, 0x838e, 0x7820, 0xd09c,
-	0x1590, 0x080c, 0x7207, 0x0904, 0x0d17, 0x7824, 0xd0ac, 0x1904,
-	0x0d38, 0x080c, 0x722a, 0x1538, 0x0046, 0x2021, 0x0320, 0x8421,
-	0x1df0, 0x004e, 0x7827, 0x1800, 0x080c, 0x2bb0, 0x7824, 0x9084,
+	0xfbcf, 0x7852, 0x080c, 0x2ab0, 0x9085, 0x2000, 0x7852, 0x793a,
+	0x20a9, 0x0046, 0x1d04, 0x0c62, 0x080c, 0x830e, 0x1f04, 0x0c62,
+	0x7850, 0x9085, 0x0400, 0x9084, 0xdfbf, 0x7852, 0x793a, 0x00a0,
+	0x2009, 0x198a, 0x2104, 0x8000, 0x200a, 0x9084, 0x0001, 0x0120,
+	0x080c, 0x2bc2, 0x080c, 0x2bf5, 0x20a9, 0x003a, 0x1d04, 0x0c7e,
+	0x080c, 0x830e, 0x1f04, 0x0c7e, 0x080c, 0x7190, 0x0148, 0x080c,
+	0x71a2, 0x1118, 0x080c, 0x748a, 0x0050, 0x080c, 0x7187, 0x0dd0,
+	0x080c, 0x7485, 0x080c, 0x747b, 0x080c, 0x709f, 0x0020, 0x2009,
+	0x00f8, 0x080c, 0x5dac, 0x2001, 0x0100, 0x2004, 0x9086, 0x000a,
+	0x0168, 0x20a9, 0x0028, 0xa001, 0x1f04, 0x0ca3, 0x7850, 0x9085,
+	0x1400, 0x7852, 0x080c, 0x717f, 0x0158, 0x0030, 0x7850, 0xc0e5,
+	0x7852, 0x080c, 0x717f, 0x0120, 0x7843, 0x0090, 0x7843, 0x0010,
+	0x2021, 0xe678, 0x2019, 0xea60, 0x0d0c, 0x830e, 0x7820, 0xd09c,
+	0x1590, 0x080c, 0x717f, 0x0904, 0x0d1f, 0x7824, 0xd0ac, 0x1904,
+	0x0d40, 0x080c, 0x71a2, 0x1538, 0x0046, 0x2021, 0x0320, 0x8421,
+	0x1df0, 0x004e, 0x7827, 0x1800, 0x080c, 0x2ab0, 0x7824, 0x9084,
 	0x1800, 0x1168, 0x9484, 0x0fff, 0x1140, 0x2001, 0x1810, 0x2004,
-	0x9084, 0x9000, 0x0110, 0x080c, 0x0d68, 0x8421, 0x1160, 0x1d04,
-	0x0ce3, 0x080c, 0x838e, 0x080c, 0x750e, 0x080c, 0x7504, 0x7003,
-	0x0001, 0x0804, 0x0d38, 0x8319, 0x1938, 0x2001, 0x0100, 0x2004,
+	0x9084, 0x9000, 0x0110, 0x080c, 0x0d70, 0x8421, 0x1160, 0x1d04,
+	0x0ceb, 0x080c, 0x830e, 0x080c, 0x7485, 0x080c, 0x747b, 0x7003,
+	0x0001, 0x0804, 0x0d40, 0x8319, 0x1938, 0x2001, 0x0100, 0x2004,
 	0x9086, 0x000a, 0x1140, 0x2001, 0x1810, 0x2004, 0x9084, 0x9000,
-	0x0110, 0x080c, 0x0d68, 0x1d04, 0x0cff, 0x080c, 0x838e, 0x2009,
-	0x1973, 0x2104, 0x9005, 0x0118, 0x8001, 0x200a, 0x1178, 0x200b,
-	0x000a, 0x7827, 0x0048, 0x20a9, 0x0002, 0x080c, 0x2b91, 0x7924,
-	0x080c, 0x2bb0, 0xd19c, 0x0110, 0x080c, 0x2a89, 0x00e0, 0x080c,
-	0x7218, 0x1140, 0x94a2, 0x03e8, 0x1128, 0x080c, 0x71df, 0x7003,
-	0x0001, 0x00b0, 0x7827, 0x1800, 0x080c, 0x2bb0, 0x7824, 0x080c,
-	0x7221, 0x0110, 0xd0ac, 0x1160, 0x9084, 0x1800, 0x0904, 0x0ceb,
-	0x7003, 0x0001, 0x0028, 0x2001, 0x0001, 0x080c, 0x2717, 0x00c0,
+	0x0110, 0x080c, 0x0d70, 0x1d04, 0x0d07, 0x080c, 0x830e, 0x2009,
+	0x1975, 0x2104, 0x9005, 0x0118, 0x8001, 0x200a, 0x1178, 0x200b,
+	0x000a, 0x7827, 0x0048, 0x20a9, 0x0002, 0x080c, 0x2a91, 0x7924,
+	0x080c, 0x2ab0, 0xd19c, 0x0110, 0x080c, 0x2989, 0x00e0, 0x080c,
+	0x7190, 0x1140, 0x94a2, 0x03e8, 0x1128, 0x080c, 0x7157, 0x7003,
+	0x0001, 0x00b0, 0x7827, 0x1800, 0x080c, 0x2ab0, 0x7824, 0x080c,
+	0x7199, 0x0110, 0xd0ac, 0x1160, 0x9084, 0x1800, 0x0904, 0x0cf3,
+	0x7003, 0x0001, 0x0028, 0x2001, 0x0001, 0x080c, 0x2617, 0x00c0,
 	0x2001, 0x0100, 0x2004, 0x9086, 0x000a, 0x1118, 0x7850, 0xc0e4,
 	0x7852, 0x2009, 0x180c, 0x210c, 0xd19c, 0x1120, 0x7904, 0x918d,
 	0x0002, 0x7906, 0x7827, 0x0048, 0x7828, 0x9085, 0x0028, 0x782a,
 	0x2001, 0x0100, 0x2004, 0x9086, 0x000a, 0x0120, 0x7850, 0x9085,
-	0x0400, 0x7852, 0x2001, 0x197f, 0x2003, 0x0000, 0x9006, 0x78f2,
+	0x0400, 0x7852, 0x2001, 0x1981, 0x2003, 0x0000, 0x9006, 0x78f2,
 	0x015e, 0x003e, 0x000e, 0x012e, 0x00fe, 0x004e, 0x001e, 0x0005,
 	0x0006, 0x0016, 0x0036, 0x0046, 0x00b6, 0x00c6, 0x00d6, 0x00e6,
-	0x00f6, 0x0156, 0x0069, 0x0d0c, 0x838e, 0x015e, 0x00fe, 0x00ee,
+	0x00f6, 0x0156, 0x0069, 0x0d0c, 0x830e, 0x015e, 0x00fe, 0x00ee,
 	0x00de, 0x00ce, 0x00be, 0x004e, 0x003e, 0x001e, 0x000e, 0x0005,
 	0x00e6, 0x2071, 0x189c, 0x7004, 0x9086, 0x0001, 0x1110, 0x080c,
-	0x3410, 0x00ee, 0x0005, 0x0005, 0x2a70, 0x2061, 0x1983, 0x2063,
-	0x0003, 0x6007, 0x0003, 0x600b, 0x0008, 0x600f, 0x0317, 0x2001,
-	0x1954, 0x900e, 0x2102, 0x7192, 0x2001, 0x0100, 0x2004, 0x9082,
+	0x3330, 0x00ee, 0x0005, 0x0005, 0x2a70, 0x2061, 0x1985, 0x2063,
+	0x0003, 0x6007, 0x0003, 0x600b, 0x000f, 0x600f, 0x0317, 0x2001,
+	0x1956, 0x900e, 0x2102, 0x7192, 0x2001, 0x0100, 0x2004, 0x9082,
 	0x0002, 0x0218, 0x705b, 0xffff, 0x0008, 0x715a, 0x7063, 0xffff,
-	0x717a, 0x717e, 0x080c, 0xc28a, 0x70e7, 0x00c0, 0x2061, 0x1944,
+	0x717a, 0x717e, 0x080c, 0xc18e, 0x70e7, 0x00c0, 0x2061, 0x1946,
 	0x6003, 0x0909, 0x6106, 0x600b, 0x8800, 0x600f, 0x0200, 0x6013,
-	0x00ff, 0x6017, 0x000f, 0x611a, 0x601f, 0x07d0, 0x2061, 0x194c,
+	0x00ff, 0x6017, 0x000f, 0x611a, 0x601f, 0x07d0, 0x2061, 0x194e,
 	0x6003, 0x8000, 0x6106, 0x610a, 0x600f, 0x0200, 0x6013, 0x00ff,
-	0x6116, 0x601b, 0x0001, 0x611e, 0x2061, 0x1961, 0x6003, 0x514c,
+	0x6116, 0x601b, 0x0001, 0x611e, 0x2061, 0x1963, 0x6003, 0x514c,
 	0x6007, 0x4f47, 0x600b, 0x4943, 0x600f, 0x2020, 0x2001, 0x182b,
-	0x2102, 0x0005, 0x9016, 0x080c, 0x649f, 0x1178, 0xb804, 0x90c4,
+	0x2102, 0x0005, 0x9016, 0x080c, 0x63a4, 0x1178, 0xb804, 0x90c4,
 	0x00ff, 0x98c6, 0x0006, 0x0128, 0x90c4, 0xff00, 0x98c6, 0x0600,
 	0x1120, 0x9186, 0x0080, 0x0108, 0x8210, 0x8108, 0x9186, 0x0800,
 	0x1d50, 0x2208, 0x0005, 0x2091, 0x8000, 0x2079, 0x0000, 0x000e,
-	0x00f6, 0x0010, 0x2091, 0x8000, 0x0e04, 0x0dfc, 0x0006, 0x0016,
+	0x00f6, 0x0010, 0x2091, 0x8000, 0x0e04, 0x0e04, 0x0006, 0x0016,
 	0x2001, 0x8002, 0x0006, 0x2079, 0x0000, 0x000e, 0x7882, 0x7836,
 	0x001e, 0x798e, 0x000e, 0x788a, 0x000e, 0x7886, 0x3900, 0x789a,
-	0x7833, 0x0012, 0x2091, 0x5000, 0x0156, 0x00d6, 0x0036, 0x0026,
-	0x2079, 0x0300, 0x2069, 0x1a7c, 0x7a08, 0x226a, 0x2069, 0x1a7d,
-	0x7a18, 0x226a, 0x8d68, 0x7a1c, 0x226a, 0x782c, 0x2019, 0x1a8a,
-	0x201a, 0x2019, 0x1a8d, 0x9016, 0x7808, 0xd09c, 0x0168, 0x7820,
-	0x201a, 0x8210, 0x8318, 0x9386, 0x1aa2, 0x0108, 0x0ca8, 0x7808,
-	0xd09c, 0x0110, 0x2011, 0xdead, 0x2019, 0x1a8b, 0x782c, 0x201a,
-	0x8318, 0x221a, 0x7803, 0x0000, 0x2069, 0x1a5c, 0x901e, 0x20a9,
-	0x0020, 0x7b26, 0x7a28, 0x226a, 0x8d68, 0x8318, 0x1f04, 0x0e49,
-	0x002e, 0x003e, 0x00de, 0x015e, 0x2079, 0x1800, 0x7803, 0x0005,
-	0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x0180, 0x2001,
-	0x19f1, 0x2004, 0x9005, 0x0128, 0x2001, 0x008b, 0x2004, 0xd0fc,
-	0x0dd8, 0x2001, 0x008a, 0x2003, 0x0002, 0x2003, 0x1001, 0x080c,
-	0x55ea, 0x1108, 0x0099, 0x0cd8, 0x0005, 0x918c, 0x03ff, 0x2001,
-	0x0003, 0x2004, 0x9084, 0x0600, 0x1118, 0x918d, 0x6c00, 0x0010,
-	0x918d, 0x6400, 0x2001, 0x017f, 0x2102, 0x0005, 0x0026, 0x0126,
-	0x2011, 0x0080, 0x080c, 0x0f11, 0x20a9, 0x0900, 0x080c, 0x0f32,
-	0x2011, 0x0040, 0x080c, 0x0f11, 0x20a9, 0x0900, 0x080c, 0x0f32,
-	0x0c78, 0x0026, 0x080c, 0x0f1e, 0x1118, 0x2011, 0x0040, 0x0098,
-	0x2011, 0x010e, 0x2214, 0x9294, 0x0007, 0x9296, 0x0007, 0x0118,
-	0x2011, 0xa880, 0x0010, 0x2011, 0x6840, 0xd0e4, 0x70eb, 0x0000,
-	0x1120, 0x70eb, 0x0fa0, 0x080c, 0x0f23, 0x002e, 0x0005, 0x0026,
-	0x080c, 0x0f1e, 0x0128, 0xd0a4, 0x1138, 0x2011, 0xcdd5, 0x0010,
-	0x2011, 0x0080, 0x080c, 0x0f23, 0x002e, 0x0005, 0x0026, 0x70eb,
-	0x0000, 0x080c, 0x0f1e, 0x1148, 0x080c, 0x2ba8, 0x1118, 0x2011,
-	0x8484, 0x0058, 0x2011, 0x8282, 0x0040, 0x080c, 0x2ba8, 0x1118,
-	0x2011, 0xcdc5, 0x0010, 0x2011, 0xcac2, 0x080c, 0x0f23, 0x002e,
-	0x0005, 0x00e6, 0x0006, 0x2071, 0x1800, 0xd0b4, 0x70e4, 0x1110,
-	0xc0e4, 0x0048, 0x0006, 0x3b00, 0x9084, 0xff3f, 0x20d8, 0x000e,
-	0x70eb, 0x0000, 0xc0e5, 0x0079, 0x000e, 0x00ee, 0x0005, 0x00e6,
-	0x2071, 0x1800, 0xd0e4, 0x70e4, 0x1110, 0xc0dc, 0x0008, 0xc0dd,
-	0x0011, 0x00ee, 0x0005, 0x70e6, 0x7000, 0x9084, 0x0007, 0x000b,
-	0x0005, 0x0ee0, 0x0eb7, 0x0eb7, 0x0e99, 0x0ec6, 0x0eb7, 0x0eb7,
-	0x0ec6, 0x0016, 0x3b08, 0x3a00, 0x9104, 0x918d, 0x00c0, 0x21d8,
-	0x9084, 0xff3f, 0x9205, 0x20d0, 0x001e, 0x0005, 0x2001, 0x1839,
-	0x2004, 0xd0dc, 0x0005, 0x9e86, 0x1800, 0x190c, 0x0dfa, 0x70e4,
-	0xd0e4, 0x0108, 0xc2e5, 0x72e6, 0xd0e4, 0x1118, 0x9294, 0x00c0,
-	0x0c01, 0x0005, 0x1d04, 0x0f32, 0x2091, 0x6000, 0x1f04, 0x0f32,
-	0x0005, 0x890e, 0x810e, 0x810f, 0x9194, 0x003f, 0x918c, 0xffc0,
-	0x0005, 0x0006, 0x2200, 0x914d, 0x894f, 0x894d, 0x894d, 0x000e,
-	0x0005, 0x01d6, 0x0146, 0x0036, 0x0096, 0x2061, 0x188b, 0x600b,
-	0x0000, 0x600f, 0x0000, 0x6003, 0x0000, 0x6007, 0x0000, 0x2009,
-	0xffc0, 0x2105, 0x0006, 0x2001, 0xaaaa, 0x200f, 0x2019, 0x5555,
-	0x9016, 0x2049, 0x0bff, 0xab02, 0xa001, 0xa001, 0xa800, 0x9306,
-	0x1138, 0x2105, 0x9306, 0x0120, 0x8210, 0x99c8, 0x0400, 0x0c98,
-	0x000e, 0x200f, 0x2001, 0x189b, 0x928a, 0x000e, 0x1638, 0x928a,
-	0x0006, 0x2011, 0x0006, 0x1210, 0x2011, 0x0000, 0x2202, 0x9006,
-	0x2008, 0x82ff, 0x01b0, 0x8200, 0x600a, 0x600f, 0xffff, 0x6003,
-	0x0002, 0x6007, 0x0000, 0x0026, 0x2019, 0x0010, 0x9280, 0x0001,
-	0x20e8, 0x21a0, 0x21a8, 0x4104, 0x8319, 0x1de0, 0x8211, 0x1da0,
-	0x002e, 0x009e, 0x003e, 0x014e, 0x01de, 0x0005, 0x2011, 0x000e,
-	0x08e8, 0x0016, 0x0026, 0x0096, 0x3348, 0x080c, 0x0f39, 0x2100,
-	0x9300, 0x2098, 0x22e0, 0x009e, 0x002e, 0x001e, 0x0036, 0x3518,
-	0x20a9, 0x0001, 0x4002, 0x8007, 0x4004, 0x8319, 0x1dd8, 0x003e,
-	0x0005, 0x20e9, 0x0001, 0x71b4, 0x81ff, 0x11c0, 0x9006, 0x2009,
-	0x0200, 0x20a9, 0x0002, 0x9298, 0x0018, 0x23a0, 0x4001, 0x2009,
-	0x0700, 0x20a9, 0x0002, 0x9298, 0x0008, 0x23a0, 0x4001, 0x7078,
-	0x8007, 0x717c, 0x810f, 0x20a9, 0x0002, 0x4001, 0x9298, 0x000c,
-	0x23a0, 0x900e, 0x080c, 0x0dda, 0x2001, 0x0000, 0x810f, 0x20a9,
-	0x0002, 0x4001, 0x0005, 0x89ff, 0x0140, 0xa804, 0xa807, 0x0000,
-	0x0006, 0x080c, 0x1063, 0x009e, 0x0cb0, 0x0005, 0x00e6, 0x2071,
-	0x1800, 0x080c, 0x10dc, 0x090c, 0x0dfa, 0x00ee, 0x0005, 0x0086,
-	0x00e6, 0x0006, 0x0026, 0x0036, 0x0126, 0x2091, 0x8000, 0x00c9,
-	0x2071, 0x1800, 0x73bc, 0x702c, 0x9016, 0x9045, 0x0158, 0x8210,
-	0x9906, 0x090c, 0x0dfa, 0x2300, 0x9202, 0x0120, 0x1a0c, 0x0dfa,
-	0xa000, 0x0c98, 0x012e, 0x003e, 0x002e, 0x000e, 0x00ee, 0x008e,
-	0x0005, 0x0086, 0x00e6, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071,
-	0x190e, 0x7010, 0x9005, 0x0140, 0x7018, 0x9045, 0x0128, 0x9906,
-	0x090c, 0x0dfa, 0xa000, 0x0cc8, 0x012e, 0x000e, 0x00ee, 0x008e,
-	0x0005, 0x00e6, 0x2071, 0x1800, 0x0126, 0x2091, 0x8000, 0x70bc,
-	0x8001, 0x0270, 0x70be, 0x702c, 0x2048, 0x9085, 0x0001, 0xa800,
-	0x702e, 0xa803, 0x0000, 0xa807, 0x0000, 0x012e, 0x00ee, 0x0005,
-	0x904e, 0x0cd8, 0x00e6, 0x0126, 0x2091, 0x8000, 0x2071, 0x1800,
-	0x70bc, 0x90ca, 0x0040, 0x0268, 0x8001, 0x70be, 0x702c, 0x2048,
-	0xa800, 0x702e, 0xa803, 0x0000, 0xa807, 0x0000, 0x012e, 0x00ee,
-	0x0005, 0x904e, 0x0cd8, 0x00e6, 0x0126, 0x2091, 0x8000, 0x0016,
-	0x890e, 0x810e, 0x810f, 0x9184, 0x003f, 0xa862, 0x9184, 0xffc0,
-	0xa85e, 0x001e, 0x0020, 0x00e6, 0x0126, 0x2091, 0x8000, 0x2071,
-	0x1800, 0x702c, 0xa802, 0x2900, 0x702e, 0x70bc, 0x8000, 0x70be,
-	0x080c, 0x81f0, 0x012e, 0x00ee, 0x0005, 0x2071, 0x1800, 0x9026,
-	0x2009, 0x0000, 0x2049, 0x0400, 0x2900, 0x702e, 0x8940, 0x2800,
-	0xa802, 0xa95e, 0xa863, 0x0001, 0x8420, 0x9886, 0x0440, 0x0120,
-	0x2848, 0x9188, 0x0040, 0x0c90, 0x2071, 0x188b, 0x7000, 0x9005,
-	0x11a0, 0x2001, 0x0492, 0xa802, 0x2048, 0x2009, 0x2480, 0x8940,
-	0x2800, 0xa802, 0xa95e, 0xa863, 0x0001, 0x8420, 0x9886, 0x0800,
-	0x0120, 0x2848, 0x9188, 0x0040, 0x0c90, 0x2071, 0x188b, 0x7104,
-	0x7200, 0x82ff, 0x01d0, 0x7308, 0x8318, 0x831f, 0x831b, 0x831b,
-	0x7312, 0x8319, 0x2001, 0x0800, 0xa802, 0x2048, 0x8900, 0xa802,
-	0x2040, 0xa95e, 0xaa62, 0x8420, 0x2300, 0x9906, 0x0130, 0x2848,
-	0x9188, 0x0040, 0x9291, 0x0000, 0x0c88, 0xa803, 0x0000, 0x2071,
-	0x1800, 0x74ba, 0x74be, 0x0005, 0x00e6, 0x0016, 0x9984, 0xfc00,
-	0x01e8, 0x908c, 0xf800, 0x1168, 0x9982, 0x0400, 0x02b8, 0x9982,
-	0x0440, 0x0278, 0x9982, 0x0492, 0x0288, 0x9982, 0x0800, 0x1270,
-	0x0040, 0x9982, 0x0800, 0x0250, 0x2071, 0x188b, 0x7010, 0x9902,
-	0x1228, 0x9085, 0x0001, 0x001e, 0x00ee, 0x0005, 0x9006, 0x0cd8,
-	0x00e6, 0x2071, 0x19f0, 0x7007, 0x0000, 0x9006, 0x701e, 0x7022,
-	0x7002, 0x2071, 0x0000, 0x7010, 0x9085, 0x8044, 0x7012, 0x2071,
-	0x0080, 0x9006, 0x0006, 0x2001, 0x0100, 0x2004, 0x9086, 0x000a,
-	0x000e, 0x1158, 0x702b, 0x0060, 0x20a9, 0x0040, 0x7022, 0x1f04,
-	0x111e, 0x702b, 0x0060, 0x702b, 0x0020, 0x20a9, 0x0040, 0x7022,
-	0x1f04, 0x1127, 0x702b, 0x0020, 0x00ee, 0x0005, 0x0126, 0x2091,
-	0x8000, 0x00e6, 0xa06f, 0x0000, 0x2071, 0x19f0, 0x701c, 0x9088,
-	0x19fa, 0x280a, 0x8000, 0x9084, 0x003f, 0x701e, 0x7120, 0x9106,
-	0x090c, 0x0dfa, 0x7004, 0x9005, 0x1128, 0x00f6, 0x2079, 0x0080,
-	0x00a9, 0x00fe, 0x00ee, 0x012e, 0x0005, 0x0126, 0x2091, 0x8000,
-	0x00e6, 0x2071, 0x19f0, 0x7004, 0x9005, 0x1128, 0x00f6, 0x2079,
-	0x0080, 0x0021, 0x00fe, 0x00ee, 0x012e, 0x0005, 0x7004, 0x9086,
-	0x0000, 0x1110, 0x7007, 0x0006, 0x7000, 0x0002, 0x1170, 0x116e,
-	0x116e, 0x116e, 0x12e7, 0x12e7, 0x12e7, 0x12e7, 0x080c, 0x0dfa,
-	0x701c, 0x7120, 0x9106, 0x1148, 0x792c, 0x9184, 0x0001, 0x1120,
-	0xd1fc, 0x1110, 0x7007, 0x0000, 0x0005, 0x0096, 0x9180, 0x19fa,
-	0x2004, 0x700a, 0x2048, 0x8108, 0x918c, 0x003f, 0x7122, 0x782b,
-	0x0026, 0xa88c, 0x7802, 0xa890, 0x7806, 0xa894, 0x780a, 0xa898,
-	0x780e, 0xa878, 0x700e, 0xa870, 0x7016, 0xa874, 0x701a, 0xa868,
-	0x009e, 0xd084, 0x0120, 0x7007, 0x0001, 0x0029, 0x0005, 0x7007,
-	0x0002, 0x00b1, 0x0005, 0x0016, 0x0026, 0x710c, 0x2011, 0x0040,
-	0x9182, 0x0040, 0x1210, 0x2110, 0x9006, 0x700e, 0x7212, 0x8203,
-	0x7812, 0x782b, 0x0020, 0x782b, 0x0041, 0x002e, 0x001e, 0x0005,
-	0x0016, 0x0026, 0x0136, 0x0146, 0x0156, 0x7014, 0x20e0, 0x7018,
-	0x2098, 0x20e9, 0x0000, 0x20a1, 0x0088, 0x782b, 0x0026, 0x710c,
+	0x00d6, 0x2069, 0x0300, 0x6818, 0x78ae, 0x681c, 0x78b2, 0x6808,
+	0x78be, 0x00de, 0x7833, 0x0012, 0x2091, 0x5000, 0x0156, 0x00d6,
+	0x0036, 0x0026, 0x2079, 0x0300, 0x2069, 0x1a7a, 0x7a08, 0x226a,
+	0x2069, 0x1a7b, 0x7a18, 0x226a, 0x8d68, 0x7a1c, 0x226a, 0x782c,
+	0x2019, 0x1a88, 0x201a, 0x2019, 0x1a8b, 0x9016, 0x7808, 0xd09c,
+	0x0168, 0x7820, 0x201a, 0x8210, 0x8318, 0x9386, 0x1aa0, 0x0108,
+	0x0ca8, 0x7808, 0xd09c, 0x0110, 0x2011, 0xdead, 0x2019, 0x1a89,
+	0x782c, 0x201a, 0x8318, 0x221a, 0x7803, 0x0000, 0x2069, 0x1a5a,
+	0x901e, 0x20a9, 0x0020, 0x7b26, 0x7a28, 0x226a, 0x8d68, 0x8318,
+	0x1f04, 0x0e5b, 0x002e, 0x003e, 0x00de, 0x015e, 0x2079, 0x1800,
+	0x7803, 0x0005, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084,
+	0x0180, 0x2001, 0x19f6, 0x2004, 0x9005, 0x0128, 0x2001, 0x008b,
+	0x2004, 0xd0fc, 0x0dd8, 0x2001, 0x008a, 0x2003, 0x0002, 0x2003,
+	0x1001, 0x080c, 0x54eb, 0x1108, 0x0099, 0x0cd8, 0x0005, 0x918c,
+	0x03ff, 0x2001, 0x0003, 0x2004, 0x9084, 0x0600, 0x1118, 0x918d,
+	0x6c00, 0x0010, 0x918d, 0x6400, 0x2001, 0x017f, 0x2102, 0x0005,
+	0x0026, 0x0126, 0x2011, 0x0080, 0x080c, 0x0f23, 0x20a9, 0x0900,
+	0x080c, 0x0f44, 0x2011, 0x0040, 0x080c, 0x0f23, 0x20a9, 0x0900,
+	0x080c, 0x0f44, 0x0c78, 0x0026, 0x080c, 0x0f30, 0x1118, 0x2011,
+	0x0040, 0x0098, 0x2011, 0x010e, 0x2214, 0x9294, 0x0007, 0x9296,
+	0x0007, 0x0118, 0x2011, 0xa880, 0x0010, 0x2011, 0x6840, 0xd0e4,
+	0x70eb, 0x0000, 0x1120, 0x70eb, 0x0fa0, 0x080c, 0x0f35, 0x002e,
+	0x0005, 0x0026, 0x080c, 0x0f30, 0x0128, 0xd0a4, 0x1138, 0x2011,
+	0xcdd5, 0x0010, 0x2011, 0x0080, 0x080c, 0x0f35, 0x002e, 0x0005,
+	0x0026, 0x70eb, 0x0000, 0x080c, 0x0f30, 0x1148, 0x080c, 0x2aa8,
+	0x1118, 0x2011, 0x8484, 0x0058, 0x2011, 0x8282, 0x0040, 0x080c,
+	0x2aa8, 0x1118, 0x2011, 0xcdc5, 0x0010, 0x2011, 0xcac2, 0x080c,
+	0x0f35, 0x002e, 0x0005, 0x00e6, 0x0006, 0x2071, 0x1800, 0xd0b4,
+	0x70e4, 0x1110, 0xc0e4, 0x0048, 0x0006, 0x3b00, 0x9084, 0xff3f,
+	0x20d8, 0x000e, 0x70eb, 0x0000, 0xc0e5, 0x0079, 0x000e, 0x00ee,
+	0x0005, 0x00e6, 0x2071, 0x1800, 0xd0e4, 0x70e4, 0x1110, 0xc0dc,
+	0x0008, 0xc0dd, 0x0011, 0x00ee, 0x0005, 0x70e6, 0x7000, 0x9084,
+	0x0007, 0x000b, 0x0005, 0x0ef2, 0x0ec9, 0x0ec9, 0x0eab, 0x0ed8,
+	0x0ec9, 0x0ec9, 0x0ed8, 0x0016, 0x3b08, 0x3a00, 0x9104, 0x918d,
+	0x00c0, 0x21d8, 0x9084, 0xff3f, 0x9205, 0x20d0, 0x001e, 0x0005,
+	0x2001, 0x1839, 0x2004, 0xd0dc, 0x0005, 0x9e86, 0x1800, 0x190c,
+	0x0e02, 0x70e4, 0xd0e4, 0x0108, 0xc2e5, 0x72e6, 0xd0e4, 0x1118,
+	0x9294, 0x00c0, 0x0c01, 0x0005, 0x1d04, 0x0f44, 0x2091, 0x6000,
+	0x1f04, 0x0f44, 0x0005, 0x890e, 0x810e, 0x810f, 0x9194, 0x003f,
+	0x918c, 0xffc0, 0x0005, 0x0006, 0x2200, 0x914d, 0x894f, 0x894d,
+	0x894d, 0x000e, 0x0005, 0x01d6, 0x0146, 0x0036, 0x0096, 0x2061,
+	0x188b, 0x600b, 0x0000, 0x600f, 0x0000, 0x6003, 0x0000, 0x6007,
+	0x0000, 0x2009, 0xffc0, 0x2105, 0x0006, 0x2001, 0xaaaa, 0x200f,
+	0x2019, 0x5555, 0x9016, 0x2049, 0x0bff, 0xab02, 0xa001, 0xa001,
+	0xa800, 0x9306, 0x1138, 0x2105, 0x9306, 0x0120, 0x8210, 0x99c8,
+	0x0400, 0x0c98, 0x000e, 0x200f, 0x2001, 0x189b, 0x928a, 0x000e,
+	0x1638, 0x928a, 0x0006, 0x2011, 0x0006, 0x1210, 0x2011, 0x0000,
+	0x2202, 0x9006, 0x2008, 0x82ff, 0x01b0, 0x8200, 0x600a, 0x600f,
+	0xffff, 0x6003, 0x0002, 0x6007, 0x0000, 0x0026, 0x2019, 0x0010,
+	0x9280, 0x0001, 0x20e8, 0x21a0, 0x21a8, 0x4104, 0x8319, 0x1de0,
+	0x8211, 0x1da0, 0x002e, 0x009e, 0x003e, 0x014e, 0x01de, 0x0005,
+	0x2011, 0x000e, 0x08e8, 0x0016, 0x0026, 0x0096, 0x3348, 0x080c,
+	0x0f4b, 0x2100, 0x9300, 0x2098, 0x22e0, 0x009e, 0x002e, 0x001e,
+	0x0036, 0x3518, 0x20a9, 0x0001, 0x4002, 0x8007, 0x4004, 0x8319,
+	0x1dd8, 0x003e, 0x0005, 0x20e9, 0x0001, 0x71b4, 0x81ff, 0x11c0,
+	0x9006, 0x2009, 0x0200, 0x20a9, 0x0002, 0x9298, 0x0018, 0x23a0,
+	0x4001, 0x2009, 0x0700, 0x20a9, 0x0002, 0x9298, 0x0008, 0x23a0,
+	0x4001, 0x7078, 0x8007, 0x717c, 0x810f, 0x20a9, 0x0002, 0x4001,
+	0x9298, 0x000c, 0x23a0, 0x900e, 0x080c, 0x0de2, 0x2001, 0x0000,
+	0x810f, 0x20a9, 0x0002, 0x4001, 0x0005, 0x89ff, 0x0140, 0xa804,
+	0xa807, 0x0000, 0x0006, 0x080c, 0x1075, 0x009e, 0x0cb0, 0x0005,
+	0x00e6, 0x2071, 0x1800, 0x080c, 0x10ee, 0x090c, 0x0e02, 0x00ee,
+	0x0005, 0x0086, 0x00e6, 0x0006, 0x0026, 0x0036, 0x0126, 0x2091,
+	0x8000, 0x00c9, 0x2071, 0x1800, 0x73bc, 0x702c, 0x9016, 0x9045,
+	0x0158, 0x8210, 0x9906, 0x090c, 0x0e02, 0x2300, 0x9202, 0x0120,
+	0x1a0c, 0x0e02, 0xa000, 0x0c98, 0x012e, 0x003e, 0x002e, 0x000e,
+	0x00ee, 0x008e, 0x0005, 0x0086, 0x00e6, 0x0006, 0x0126, 0x2091,
+	0x8000, 0x2071, 0x190e, 0x7010, 0x9005, 0x0140, 0x7018, 0x9045,
+	0x0128, 0x9906, 0x090c, 0x0e02, 0xa000, 0x0cc8, 0x012e, 0x000e,
+	0x00ee, 0x008e, 0x0005, 0x00e6, 0x2071, 0x1800, 0x0126, 0x2091,
+	0x8000, 0x70bc, 0x8001, 0x0270, 0x70be, 0x702c, 0x2048, 0x9085,
+	0x0001, 0xa800, 0x702e, 0xa803, 0x0000, 0xa807, 0x0000, 0x012e,
+	0x00ee, 0x0005, 0x904e, 0x0cd8, 0x00e6, 0x0126, 0x2091, 0x8000,
+	0x2071, 0x1800, 0x70bc, 0x90ca, 0x0040, 0x0268, 0x8001, 0x70be,
+	0x702c, 0x2048, 0xa800, 0x702e, 0xa803, 0x0000, 0xa807, 0x0000,
+	0x012e, 0x00ee, 0x0005, 0x904e, 0x0cd8, 0x00e6, 0x0126, 0x2091,
+	0x8000, 0x0016, 0x890e, 0x810e, 0x810f, 0x9184, 0x003f, 0xa862,
+	0x9184, 0xffc0, 0xa85e, 0x001e, 0x0020, 0x00e6, 0x0126, 0x2091,
+	0x8000, 0x2071, 0x1800, 0x702c, 0xa802, 0x2900, 0x702e, 0x70bc,
+	0x8000, 0x70be, 0x080c, 0x8170, 0x012e, 0x00ee, 0x0005, 0x2071,
+	0x1800, 0x9026, 0x2009, 0x0000, 0x2049, 0x0400, 0x2900, 0x702e,
+	0x8940, 0x2800, 0xa802, 0xa95e, 0xa863, 0x0001, 0x8420, 0x9886,
+	0x0440, 0x0120, 0x2848, 0x9188, 0x0040, 0x0c90, 0x2071, 0x188b,
+	0x7000, 0x9005, 0x11a0, 0x2001, 0x0492, 0xa802, 0x2048, 0x2009,
+	0x2480, 0x8940, 0x2800, 0xa802, 0xa95e, 0xa863, 0x0001, 0x8420,
+	0x9886, 0x0800, 0x0120, 0x2848, 0x9188, 0x0040, 0x0c90, 0x2071,
+	0x188b, 0x7104, 0x7200, 0x82ff, 0x01d0, 0x7308, 0x8318, 0x831f,
+	0x831b, 0x831b, 0x7312, 0x8319, 0x2001, 0x0800, 0xa802, 0x2048,
+	0x8900, 0xa802, 0x2040, 0xa95e, 0xaa62, 0x8420, 0x2300, 0x9906,
+	0x0130, 0x2848, 0x9188, 0x0040, 0x9291, 0x0000, 0x0c88, 0xa803,
+	0x0000, 0x2071, 0x1800, 0x74ba, 0x74be, 0x0005, 0x00e6, 0x0016,
+	0x9984, 0xfc00, 0x01e8, 0x908c, 0xf800, 0x1168, 0x9982, 0x0400,
+	0x02b8, 0x9982, 0x0440, 0x0278, 0x9982, 0x0492, 0x0288, 0x9982,
+	0x0800, 0x1270, 0x0040, 0x9982, 0x0800, 0x0250, 0x2071, 0x188b,
+	0x7010, 0x9902, 0x1228, 0x9085, 0x0001, 0x001e, 0x00ee, 0x0005,
+	0x9006, 0x0cd8, 0x00e6, 0x2071, 0x19f5, 0x7007, 0x0000, 0x9006,
+	0x701e, 0x7022, 0x7002, 0x2071, 0x0000, 0x7010, 0x9085, 0x8044,
+	0x7012, 0x2071, 0x0080, 0x9006, 0x0006, 0x2001, 0x0100, 0x2004,
+	0x9086, 0x000a, 0x000e, 0x1158, 0x702b, 0x0060, 0x20a9, 0x0040,
+	0x7022, 0x1f04, 0x1130, 0x702b, 0x0060, 0x702b, 0x0020, 0x20a9,
+	0x0040, 0x7022, 0x1f04, 0x1139, 0x702b, 0x0020, 0x00ee, 0x0005,
+	0x0126, 0x2091, 0x8000, 0x00e6, 0xa06f, 0x0000, 0x2071, 0x19f5,
+	0x701c, 0x9088, 0x19ff, 0x280a, 0x8000, 0x9084, 0x003f, 0x701e,
+	0x7120, 0x9106, 0x090c, 0x0e02, 0x7004, 0x9005, 0x1128, 0x00f6,
+	0x2079, 0x0080, 0x00a9, 0x00fe, 0x00ee, 0x012e, 0x0005, 0x0126,
+	0x2091, 0x8000, 0x00e6, 0x2071, 0x19f5, 0x7004, 0x9005, 0x1128,
+	0x00f6, 0x2079, 0x0080, 0x0021, 0x00fe, 0x00ee, 0x012e, 0x0005,
+	0x7004, 0x9086, 0x0000, 0x1110, 0x7007, 0x0006, 0x7000, 0x0002,
+	0x1182, 0x1180, 0x1180, 0x1180, 0x12f9, 0x12f9, 0x12f9, 0x12f9,
+	0x080c, 0x0e02, 0x701c, 0x7120, 0x9106, 0x1148, 0x792c, 0x9184,
+	0x0001, 0x1120, 0xd1fc, 0x1110, 0x7007, 0x0000, 0x0005, 0x0096,
+	0x9180, 0x19ff, 0x2004, 0x700a, 0x2048, 0x8108, 0x918c, 0x003f,
+	0x7122, 0x782b, 0x0026, 0xa88c, 0x7802, 0xa890, 0x7806, 0xa894,
+	0x780a, 0xa898, 0x780e, 0xa878, 0x700e, 0xa870, 0x7016, 0xa874,
+	0x701a, 0xa868, 0x009e, 0xd084, 0x0120, 0x7007, 0x0001, 0x0029,
+	0x0005, 0x7007, 0x0002, 0x00b1, 0x0005, 0x0016, 0x0026, 0x710c,
 	0x2011, 0x0040, 0x9182, 0x0040, 0x1210, 0x2110, 0x9006, 0x700e,
-	0x22a8, 0x4006, 0x8203, 0x7812, 0x782b, 0x0020, 0x3300, 0x701a,
-	0x782b, 0x0001, 0x015e, 0x014e, 0x013e, 0x002e, 0x001e, 0x0005,
-	0x2009, 0x19f0, 0x2104, 0xc095, 0x200a, 0x080c, 0x114d, 0x0005,
-	0x0016, 0x00e6, 0x2071, 0x19f0, 0x00f6, 0x2079, 0x0080, 0x792c,
-	0xd1bc, 0x190c, 0x0df3, 0x782b, 0x0002, 0xd1fc, 0x0120, 0x918c,
-	0x0700, 0x7004, 0x0023, 0x00fe, 0x00ee, 0x001e, 0x0005, 0x115e,
-	0x1206, 0x123a, 0x0dfa, 0x0dfa, 0x12f3, 0x0dfa, 0x918c, 0x0700,
-	0x1550, 0x0136, 0x0146, 0x0156, 0x7014, 0x20e8, 0x7018, 0x20a0,
-	0x20e1, 0x0000, 0x2099, 0x0088, 0x782b, 0x0040, 0x7010, 0x20a8,
-	0x4005, 0x3400, 0x701a, 0x015e, 0x014e, 0x013e, 0x700c, 0x9005,
-	0x0578, 0x7800, 0x7802, 0x7804, 0x7806, 0x080c, 0x11a3, 0x0005,
-	0x7008, 0x0096, 0x2048, 0xa86f, 0x0100, 0x009e, 0x7007, 0x0000,
-	0x080c, 0x115e, 0x0005, 0x7008, 0x0096, 0x2048, 0xa86f, 0x0200,
-	0x009e, 0x0ca0, 0x918c, 0x0700, 0x1150, 0x700c, 0x9005, 0x0180,
-	0x7800, 0x7802, 0x7804, 0x7806, 0x080c, 0x11b8, 0x0005, 0x7008,
-	0x0096, 0x2048, 0xa86f, 0x0200, 0x009e, 0x7007, 0x0000, 0x0080,
-	0x0096, 0x7008, 0x2048, 0x7800, 0xa88e, 0x7804, 0xa892, 0x7808,
-	0xa896, 0x780c, 0xa89a, 0xa86f, 0x0100, 0x009e, 0x7007, 0x0000,
-	0x0096, 0x00d6, 0x7008, 0x2048, 0x2001, 0x18b7, 0x2004, 0x9906,
-	0x1128, 0xa89c, 0x080f, 0x00de, 0x009e, 0x00a0, 0x00de, 0x009e,
-	0x0096, 0x00d6, 0x7008, 0x2048, 0x0081, 0x0150, 0xa89c, 0x0086,
-	0x2940, 0x080f, 0x008e, 0x00de, 0x009e, 0x080c, 0x114d, 0x0005,
-	0x00de, 0x009e, 0x080c, 0x114d, 0x0005, 0xa8a8, 0xd08c, 0x0005,
-	0x0096, 0xa0a0, 0x904d, 0x090c, 0x0dfa, 0xa06c, 0x908e, 0x0100,
-	0x0130, 0xa87b, 0x0030, 0xa883, 0x0000, 0xa897, 0x4002, 0x080c,
-	0x6adc, 0xa09f, 0x0000, 0xa0a3, 0x0000, 0x2848, 0x080c, 0x1063,
-	0x009e, 0x0005, 0x00a6, 0xa0a0, 0x904d, 0x090c, 0x0dfa, 0xa06c,
-	0x908e, 0x0100, 0x0128, 0xa87b, 0x0001, 0xa883, 0x0000, 0x00c0,
-	0xa80c, 0x2050, 0xb004, 0x9005, 0x0198, 0xa80e, 0x2050, 0x8006,
-	0x8006, 0x8007, 0x908c, 0x003f, 0x9084, 0xffc0, 0x9080, 0x0002,
-	0xa076, 0xa172, 0xb000, 0xa07a, 0x2810, 0x080c, 0x112e, 0x00e8,
-	0xa97c, 0xa894, 0x0016, 0x0006, 0x080c, 0x6adc, 0x000e, 0x001e,
-	0xd1fc, 0x1138, 0xd1f4, 0x0128, 0x00c6, 0x2060, 0x080c, 0xa0e3,
-	0x00ce, 0x7008, 0x2048, 0xa89f, 0x0000, 0xa8a3, 0x0000, 0x080c,
-	0x1063, 0x7007, 0x0000, 0x080c, 0x114d, 0x00ae, 0x0005, 0x0126,
-	0x2091, 0x8000, 0x782b, 0x1001, 0x7007, 0x0005, 0x7000, 0xc094,
-	0x7002, 0x012e, 0x0005, 0x7007, 0x0000, 0x080c, 0x115e, 0x0005,
-	0x0126, 0x2091, 0x2200, 0x2079, 0x0300, 0x2071, 0x1a3a, 0x7003,
-	0x0000, 0x78bf, 0x00f6, 0x781b, 0x4800, 0x0419, 0x7803, 0x0003,
+	0x7212, 0x8203, 0x7812, 0x782b, 0x0020, 0x782b, 0x0041, 0x002e,
+	0x001e, 0x0005, 0x0016, 0x0026, 0x0136, 0x0146, 0x0156, 0x7014,
+	0x20e0, 0x7018, 0x2098, 0x20e9, 0x0000, 0x20a1, 0x0088, 0x782b,
+	0x0026, 0x710c, 0x2011, 0x0040, 0x9182, 0x0040, 0x1210, 0x2110,
+	0x9006, 0x700e, 0x22a8, 0x4006, 0x8203, 0x7812, 0x782b, 0x0020,
+	0x3300, 0x701a, 0x782b, 0x0001, 0x015e, 0x014e, 0x013e, 0x002e,
+	0x001e, 0x0005, 0x2009, 0x19f5, 0x2104, 0xc095, 0x200a, 0x080c,
+	0x115f, 0x0005, 0x0016, 0x00e6, 0x2071, 0x19f5, 0x00f6, 0x2079,
+	0x0080, 0x792c, 0xd1bc, 0x190c, 0x0dfb, 0x782b, 0x0002, 0xd1fc,
+	0x0120, 0x918c, 0x0700, 0x7004, 0x0023, 0x00fe, 0x00ee, 0x001e,
+	0x0005, 0x1170, 0x1218, 0x124c, 0x0e02, 0x0e02, 0x1305, 0x0e02,
+	0x918c, 0x0700, 0x1550, 0x0136, 0x0146, 0x0156, 0x7014, 0x20e8,
+	0x7018, 0x20a0, 0x20e1, 0x0000, 0x2099, 0x0088, 0x782b, 0x0040,
+	0x7010, 0x20a8, 0x4005, 0x3400, 0x701a, 0x015e, 0x014e, 0x013e,
+	0x700c, 0x9005, 0x0578, 0x7800, 0x7802, 0x7804, 0x7806, 0x080c,
+	0x11b5, 0x0005, 0x7008, 0x0096, 0x2048, 0xa86f, 0x0100, 0x009e,
+	0x7007, 0x0000, 0x080c, 0x1170, 0x0005, 0x7008, 0x0096, 0x2048,
+	0xa86f, 0x0200, 0x009e, 0x0ca0, 0x918c, 0x0700, 0x1150, 0x700c,
+	0x9005, 0x0180, 0x7800, 0x7802, 0x7804, 0x7806, 0x080c, 0x11ca,
+	0x0005, 0x7008, 0x0096, 0x2048, 0xa86f, 0x0200, 0x009e, 0x7007,
+	0x0000, 0x0080, 0x0096, 0x7008, 0x2048, 0x7800, 0xa88e, 0x7804,
+	0xa892, 0x7808, 0xa896, 0x780c, 0xa89a, 0xa86f, 0x0100, 0x009e,
+	0x7007, 0x0000, 0x0096, 0x00d6, 0x7008, 0x2048, 0x2001, 0x18b7,
+	0x2004, 0x9906, 0x1128, 0xa89c, 0x080f, 0x00de, 0x009e, 0x00a0,
+	0x00de, 0x009e, 0x0096, 0x00d6, 0x7008, 0x2048, 0x0081, 0x0150,
+	0xa89c, 0x0086, 0x2940, 0x080f, 0x008e, 0x00de, 0x009e, 0x080c,
+	0x115f, 0x0005, 0x00de, 0x009e, 0x080c, 0x115f, 0x0005, 0xa8a8,
+	0xd08c, 0x0005, 0x0096, 0xa0a0, 0x904d, 0x090c, 0x0e02, 0xa06c,
+	0x908e, 0x0100, 0x0130, 0xa87b, 0x0030, 0xa883, 0x0000, 0xa897,
+	0x4002, 0x080c, 0x6a16, 0xa09f, 0x0000, 0xa0a3, 0x0000, 0x2848,
+	0x080c, 0x1075, 0x009e, 0x0005, 0x00a6, 0xa0a0, 0x904d, 0x090c,
+	0x0e02, 0xa06c, 0x908e, 0x0100, 0x0128, 0xa87b, 0x0001, 0xa883,
+	0x0000, 0x00c0, 0xa80c, 0x2050, 0xb004, 0x9005, 0x0198, 0xa80e,
+	0x2050, 0x8006, 0x8006, 0x8007, 0x908c, 0x003f, 0x9084, 0xffc0,
+	0x9080, 0x0002, 0xa076, 0xa172, 0xb000, 0xa07a, 0x2810, 0x080c,
+	0x1140, 0x00e8, 0xa97c, 0xa894, 0x0016, 0x0006, 0x080c, 0x6a16,
+	0x000e, 0x001e, 0xd1fc, 0x1138, 0xd1f4, 0x0128, 0x00c6, 0x2060,
+	0x080c, 0x9fd5, 0x00ce, 0x7008, 0x2048, 0xa89f, 0x0000, 0xa8a3,
+	0x0000, 0x080c, 0x1075, 0x7007, 0x0000, 0x080c, 0x115f, 0x00ae,
+	0x0005, 0x0126, 0x2091, 0x8000, 0x782b, 0x1001, 0x7007, 0x0005,
+	0x7000, 0xc094, 0x7002, 0x012e, 0x0005, 0x7007, 0x0000, 0x080c,
+	0x1170, 0x0005, 0x0126, 0x2091, 0x2200, 0x2079, 0x0300, 0x2071,
+	0x1a3f, 0x7003, 0x0000, 0x78bf, 0x00f6, 0x0419, 0x7803, 0x0003,
 	0x780f, 0x0000, 0x2001, 0x0100, 0x2004, 0x9086, 0x000a, 0x0128,
-	0x20a9, 0x0254, 0x2061, 0xdc42, 0x0020, 0x20a9, 0x0241, 0x2061,
-	0xe0e8, 0x2c0d, 0x7912, 0xe104, 0x9ce0, 0x0002, 0x7916, 0x1f04,
-	0x1319, 0x7807, 0x0007, 0x7803, 0x0000, 0x7803, 0x0001, 0x012e,
+	0x20a9, 0x01e8, 0x2061, 0xdba9, 0x0020, 0x20a9, 0x01e8, 0x2061,
+	0xdf77, 0x2c0d, 0x7912, 0xe104, 0x9ce0, 0x0002, 0x7916, 0x1f04,
+	0x1329, 0x7807, 0x0007, 0x7803, 0x0000, 0x7803, 0x0001, 0x012e,
 	0x0005, 0x00c6, 0x7803, 0x0000, 0x7808, 0xd09c, 0x0110, 0x7820,
-	0x0cd8, 0x2001, 0x1a3b, 0x2003, 0x0000, 0x78ab, 0x0004, 0x78ac,
+	0x0cd8, 0x2001, 0x1a40, 0x2003, 0x0000, 0x78ab, 0x0004, 0x78ac,
 	0xd0ac, 0x1de8, 0x78ab, 0x0002, 0x7807, 0x0007, 0x7827, 0x0030,
-	0x782b, 0x0400, 0x7827, 0x0031, 0x782b, 0x1a5c, 0x781f, 0xff00,
-	0x781b, 0xb700, 0x2001, 0x0200, 0x2004, 0xd0dc, 0x0110, 0x781f,
-	0x0303, 0x2061, 0x1a5c, 0x602f, 0x1cd0, 0x2001, 0x1819, 0x2004,
-	0x9082, 0x1cd0, 0x6032, 0x603b, 0x1fc8, 0x2001, 0x32e9, 0xd0fc,
-	0x190c, 0x0dfa, 0x2001, 0x0003, 0x2004, 0xd0d4, 0x1118, 0x783f,
-	0x32e9, 0x0020, 0x9084, 0xc000, 0x783f, 0xb2e9, 0x00ce, 0x0005,
-	0x0126, 0x2091, 0x2200, 0x7908, 0x9184, 0x0070, 0x190c, 0x0df3,
-	0xd19c, 0x0158, 0x7820, 0x908c, 0xf000, 0x15e8, 0x908a, 0x0024,
-	0x1a0c, 0x0dfa, 0x0023, 0x012e, 0x0005, 0x012e, 0x0005, 0x13ab,
-	0x13ab, 0x13c2, 0x13c7, 0x13cb, 0x13d0, 0x13f8, 0x13fc, 0x140a,
-	0x140e, 0x13ab, 0x149a, 0x149e, 0x150e, 0x13ab, 0x13ab, 0x13ab,
-	0x13ab, 0x13ab, 0x13ab, 0x13ab, 0x13ab, 0x13ab, 0x13ab, 0x13ab,
-	0x13ab, 0x13ab, 0x13d2, 0x13ab, 0x13ab, 0x13ab, 0x13ab, 0x13ab,
-	0x13ab, 0x13af, 0x13ad, 0x080c, 0x0dfa, 0x080c, 0x0df3, 0x080c,
-	0x1515, 0x2009, 0x1a52, 0x2104, 0x8000, 0x200a, 0x080c, 0x7c6d,
-	0x080c, 0x19ff, 0x0005, 0x2009, 0x0048, 0x2060, 0x080c, 0xa15d,
-	0x012e, 0x0005, 0x7004, 0xc085, 0xc0b5, 0x7006, 0x0005, 0x7004,
-	0xc085, 0x7006, 0x0005, 0x080c, 0x1515, 0x080c, 0x166e, 0x0005,
-	0x080c, 0x0dfa, 0x080c, 0x1515, 0x2060, 0x6014, 0x0096, 0x2048,
-	0xa83b, 0xffff, 0x009e, 0x2009, 0x0048, 0x080c, 0xa15d, 0x2001,
-	0x015d, 0x2003, 0x0000, 0x2009, 0x03e8, 0x8109, 0x0160, 0x2001,
-	0x0201, 0x2004, 0x9005, 0x0dc8, 0x2001, 0x0218, 0x2004, 0xd0ec,
-	0x1110, 0x080c, 0x151a, 0x2001, 0x0307, 0x2003, 0x8000, 0x0005,
-	0x7004, 0xc095, 0x7006, 0x0005, 0x080c, 0x1515, 0x2060, 0x6014,
-	0x0096, 0x2048, 0xa83b, 0xffff, 0x009e, 0x2009, 0x0048, 0x080c,
-	0xa15d, 0x0005, 0x080c, 0x1515, 0x080c, 0x0dfa, 0x080c, 0x1515,
-	0x080c, 0x1485, 0x7827, 0x0018, 0x79ac, 0xd1dc, 0x0540, 0x7827,
-	0x0015, 0x7828, 0x782b, 0x0000, 0x9065, 0x0138, 0x2001, 0x020d,
-	0x2003, 0x0050, 0x2003, 0x0020, 0x0400, 0x7004, 0x9005, 0x1180,
-	0x78ab, 0x0004, 0x7827, 0x0018, 0x782b, 0x0000, 0xd1bc, 0x090c,
-	0x0dfa, 0x2001, 0x020d, 0x2003, 0x0050, 0x2003, 0x0020, 0x0490,
-	0x78ab, 0x0004, 0x7803, 0x0001, 0x080c, 0x149e, 0x0005, 0x7828,
-	0x782b, 0x0000, 0x9065, 0x090c, 0x0dfa, 0x6014, 0x2048, 0x78ab,
-	0x0004, 0x918c, 0x0700, 0x01a8, 0x080c, 0x7c6d, 0x080c, 0x19ff,
-	0x080c, 0xbe37, 0x0158, 0xa9ac, 0xa936, 0xa9b0, 0xa93a, 0xa83f,
-	0xffff, 0xa843, 0xffff, 0xa880, 0xc0bd, 0xa882, 0x080c, 0xba56,
-	0x0005, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x6024,
-	0x190c, 0xc223, 0x2029, 0x00c8, 0x8529, 0x0128, 0x2001, 0x0201,
-	0x2004, 0x9005, 0x0dc8, 0x7dbc, 0x080c, 0xdbeb, 0xd5a4, 0x1118,
-	0x080c, 0x151a, 0x0005, 0x080c, 0x7c6d, 0x080c, 0x19ff, 0x0005,
-	0x781f, 0x0300, 0x7803, 0x0001, 0x0005, 0x0016, 0x0066, 0x0076,
-	0x00f6, 0x2079, 0x0300, 0x7908, 0x918c, 0x0007, 0x9186, 0x0003,
-	0x0120, 0x2001, 0x0016, 0x080c, 0x158b, 0x00fe, 0x007e, 0x006e,
-	0x001e, 0x0005, 0x7004, 0xc09d, 0x7006, 0x0005, 0x7104, 0x9184,
-	0x0004, 0x190c, 0x0dfa, 0xd184, 0x11b1, 0xd19c, 0x0180, 0xc19c,
-	0x7106, 0x0016, 0x080c, 0x1651, 0x001e, 0x0148, 0x2001, 0x020d,
-	0x2003, 0x0050, 0x2003, 0x0020, 0x080c, 0x151a, 0x0005, 0x81ff,
-	0x190c, 0x0dfa, 0x0005, 0x2100, 0xc184, 0xc1b4, 0x7106, 0xd0b4,
-	0x0016, 0x00e6, 0x1904, 0x1503, 0x2071, 0x0200, 0x080c, 0x1645,
-	0x080c, 0x1651, 0x05a8, 0x6014, 0x9005, 0x05a8, 0x0096, 0x2048,
-	0xa864, 0x009e, 0x9084, 0x00ff, 0x908e, 0x0029, 0x0160, 0x908e,
-	0x0048, 0x1548, 0x601c, 0xd084, 0x11d8, 0x00f6, 0x2c78, 0x080c,
-	0x16db, 0x00fe, 0x00a8, 0x00f6, 0x2c78, 0x080c, 0x1825, 0x00fe,
-	0x2009, 0x01f4, 0x8109, 0x0160, 0x2001, 0x0201, 0x2004, 0x9005,
-	0x0dc8, 0x2001, 0x0218, 0x2004, 0xd0ec, 0x1110, 0x0419, 0x0040,
-	0x2001, 0x020d, 0x2003, 0x0020, 0x080c, 0x1329, 0x7803, 0x0001,
-	0x00ee, 0x001e, 0x0005, 0x080c, 0x1651, 0x0dd0, 0x2001, 0x020d,
-	0x2003, 0x0050, 0x2003, 0x0020, 0x0069, 0x0c90, 0x0031, 0x2060,
-	0x2009, 0x0053, 0x080c, 0xa15d, 0x0005, 0x7808, 0xd09c, 0x0de8,
-	0x7820, 0x0005, 0x080c, 0x1485, 0x00d6, 0x2069, 0x0200, 0x2009,
-	0x01f4, 0x8109, 0x0510, 0x6804, 0x9005, 0x0dd8, 0x2001, 0x015d,
-	0x2003, 0x0000, 0x79bc, 0xd1a4, 0x1528, 0x79b8, 0x918c, 0x0fff,
-	0x0180, 0x9182, 0x0841, 0x1268, 0x9188, 0x0007, 0x918c, 0x0ff8,
-	0x810c, 0x810c, 0x810c, 0x080c, 0x157d, 0x6827, 0x0001, 0x8109,
-	0x1dd0, 0x04d9, 0x6827, 0x0002, 0x04c1, 0x6804, 0x9005, 0x1130,
-	0x682c, 0xd0e4, 0x1500, 0x6804, 0x9005, 0x0de8, 0x79b8, 0xd1ec,
-	0x1130, 0x08c0, 0x080c, 0x7c6d, 0x080c, 0x19ff, 0x0090, 0x7827,
-	0x0015, 0x782b, 0x0000, 0x7827, 0x0018, 0x782b, 0x0000, 0x2001,
-	0x020d, 0x2003, 0x0020, 0x2001, 0x0307, 0x2003, 0x0300, 0x7803,
-	0x0001, 0x00de, 0x0005, 0x682c, 0x9084, 0x5400, 0x9086, 0x5400,
-	0x0d30, 0x7827, 0x0015, 0x782b, 0x0000, 0x7803, 0x0001, 0x6800,
-	0x9085, 0x1800, 0x6802, 0x00de, 0x0005, 0x6824, 0x9084, 0x0003,
-	0x1de0, 0x0005, 0x2001, 0x0030, 0x2c08, 0x621c, 0x0021, 0x7830,
-	0x9086, 0x0041, 0x0005, 0x00f6, 0x2079, 0x0300, 0x0006, 0x7808,
-	0xd09c, 0x0140, 0x0016, 0x0026, 0x00c6, 0x080c, 0x1370, 0x00ce,
-	0x002e, 0x001e, 0x000e, 0x0006, 0x7832, 0x7936, 0x7a3a, 0x781b,
-	0x8080, 0x0059, 0x1118, 0x000e, 0x00fe, 0x0005, 0x000e, 0x792c,
-	0x3900, 0x8000, 0x2004, 0x080c, 0x0dfa, 0x2009, 0x180c, 0x2104,
-	0xc0f4, 0x200a, 0x2009, 0xff00, 0x8109, 0x0904, 0x1609, 0x7a18,
-	0x9284, 0x0030, 0x0904, 0x1604, 0x9284, 0x0048, 0x9086, 0x0008,
-	0x1904, 0x1604, 0x2001, 0x0109, 0x2004, 0xd08c, 0x01f0, 0x0006,
-	0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x0126, 0x2091, 0x2800,
-	0x00f6, 0x0026, 0x0016, 0x2009, 0x1a55, 0x2104, 0x8000, 0x0208,
-	0x200a, 0x080c, 0x8632, 0x001e, 0x002e, 0x00fe, 0x012e, 0x015e,
-	0x014e, 0x013e, 0x01de, 0x01ce, 0x000e, 0x2001, 0x009b, 0x2004,
-	0xd0fc, 0x01d0, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146,
-	0x0156, 0x00f6, 0x0016, 0x2009, 0x1a56, 0x2104, 0x8000, 0x0208,
-	0x200a, 0x080c, 0x1dec, 0x001e, 0x00fe, 0x015e, 0x014e, 0x013e,
-	0x01de, 0x01ce, 0x012e, 0x000e, 0x7818, 0xd0bc, 0x1904, 0x15b4,
-	0x0005, 0x2001, 0x180c, 0x2004, 0xd0f4, 0x1528, 0x7a18, 0x9284,
-	0x0030, 0x0508, 0x9284, 0x0048, 0x9086, 0x0008, 0x11e0, 0x2001,
-	0x19ce, 0x2004, 0x9005, 0x01b8, 0x2001, 0x1a3d, 0x2004, 0x9086,
-	0x0000, 0x0188, 0x2009, 0x1a54, 0x2104, 0x8000, 0x0208, 0x200a,
-	0x080c, 0x96d4, 0x2009, 0x180c, 0x2104, 0xc0f5, 0x200a, 0x2009,
-	0xff00, 0x0804, 0x15b4, 0x9085, 0x0001, 0x0005, 0x7832, 0x7936,
-	0x7a3a, 0x781b, 0x8080, 0x080c, 0x15ad, 0x1108, 0x0005, 0x792c,
-	0x3900, 0x8000, 0x2004, 0x080c, 0x0dfa, 0x7037, 0x0001, 0x7150,
-	0x7037, 0x0002, 0x7050, 0x2060, 0xd1bc, 0x1110, 0x7054, 0x2060,
-	0x0005, 0x0006, 0x0046, 0x00e6, 0x2071, 0x0200, 0x7037, 0x0002,
-	0x7058, 0x9084, 0xff00, 0x8007, 0x9086, 0x00bc, 0x1158, 0x2021,
-	0x1a53, 0x2404, 0x8000, 0x0208, 0x2022, 0x080c, 0x7c6d, 0x080c,
-	0x19ff, 0x9006, 0x00ee, 0x004e, 0x000e, 0x0005, 0x0c11, 0x1108,
-	0x0005, 0x00e6, 0x0016, 0x2071, 0x0200, 0x0879, 0x6124, 0xd1dc,
-	0x01f8, 0x701c, 0xd08c, 0x0904, 0x16d0, 0x7017, 0x0000, 0x2001,
-	0x0264, 0x2004, 0xd0bc, 0x0904, 0x16d0, 0x2001, 0x0268, 0x00c6,
-	0x2064, 0x6104, 0x6038, 0x00ce, 0x918e, 0x0039, 0x1904, 0x16d0,
-	0x9c06, 0x15f0, 0x0126, 0x2091, 0x2600, 0x080c, 0x7bb4, 0x012e,
-	0x7358, 0x745c, 0x6014, 0x905d, 0x0598, 0x2b48, 0x6010, 0x00b6,
-	0x2058, 0xb800, 0x00be, 0xd0bc, 0x190c, 0xc1fe, 0xab42, 0xac3e,
-	0x2001, 0x187d, 0x2004, 0xd0b4, 0x1170, 0x601c, 0xd0e4, 0x1158,
-	0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x1120, 0xa83b,
-	0x7fff, 0xa837, 0xffff, 0x080c, 0x1fe8, 0x1190, 0x080c, 0x1882,
-	0x2a00, 0xa816, 0x0130, 0x2800, 0xa80e, 0x2c05, 0xa80a, 0x2c00,
-	0xa812, 0x7037, 0x0020, 0x781f, 0x0300, 0x001e, 0x00ee, 0x0005,
-	0x7037, 0x0050, 0x7037, 0x0020, 0x001e, 0x00ee, 0x080c, 0x151a,
-	0x0005, 0x080c, 0x0dfa, 0x0016, 0x2009, 0x00a0, 0x8109, 0xa001,
-	0xa001, 0xa001, 0x1dd8, 0x001e, 0x2ff0, 0x0126, 0x2091, 0x2200,
-	0x0016, 0x00c6, 0x3e60, 0x6014, 0x2048, 0x2940, 0x903e, 0x2730,
-	0xa864, 0x2068, 0xa81a, 0x9d84, 0x000f, 0x9088, 0x1fc8, 0x2165,
-	0x0002, 0x1710, 0x175d, 0x1710, 0x1710, 0x1710, 0x173f, 0x1710,
-	0x1714, 0x1709, 0x1754, 0x1710, 0x1710, 0x1710, 0x181a, 0x1728,
-	0x171e, 0xa964, 0x918c, 0x00ff, 0x918e, 0x0048, 0x0904, 0x1754,
-	0x9085, 0x0001, 0x0804, 0x1810, 0xa87c, 0xd0bc, 0x0dc8, 0xa890,
-	0xa842, 0xa88c, 0xa83e, 0xa888, 0x0804, 0x1764, 0xa87c, 0xd0bc,
-	0x0d78, 0xa890, 0xa842, 0xa88c, 0xa83e, 0xa888, 0x0804, 0x17b3,
-	0xa87c, 0xd0bc, 0x0d28, 0xa890, 0xa842, 0xa88c, 0xa83e, 0xa804,
-	0x9045, 0x090c, 0x0dfa, 0xa164, 0xa91a, 0x91ec, 0x000f, 0x9d80,
-	0x1fc8, 0x2065, 0xa888, 0xd19c, 0x1904, 0x17b3, 0x0428, 0xa87c,
-	0xd0ac, 0x0970, 0xa804, 0x9045, 0x090c, 0x0dfa, 0xa164, 0xa91a,
-	0x91ec, 0x000f, 0x9d80, 0x1fc8, 0x2065, 0x9006, 0xa842, 0xa83e,
-	0xd19c, 0x1904, 0x17b3, 0x0080, 0xa87c, 0xd0ac, 0x0904, 0x1710,
-	0x9006, 0xa842, 0xa83e, 0x0804, 0x17b3, 0xa87c, 0xd0ac, 0x0904,
-	0x1710, 0x9006, 0xa842, 0xa83e, 0x2c05, 0x908a, 0x0036, 0x1a0c,
-	0x0dfa, 0x9082, 0x001b, 0x0002, 0x1787, 0x1787, 0x1789, 0x1787,
-	0x1787, 0x1787, 0x178f, 0x1787, 0x1787, 0x1787, 0x1795, 0x1787,
-	0x1787, 0x1787, 0x179b, 0x1787, 0x1787, 0x1787, 0x17a1, 0x1787,
-	0x1787, 0x1787, 0x17a7, 0x1787, 0x1787, 0x1787, 0x17ad, 0x080c,
-	0x0dfa, 0xa574, 0xa478, 0xa37c, 0xa280, 0x0804, 0x17f8, 0xa584,
-	0xa488, 0xa38c, 0xa290, 0x0804, 0x17f8, 0xa594, 0xa498, 0xa39c,
-	0xa2a0, 0x0804, 0x17f8, 0xa5a4, 0xa4a8, 0xa3ac, 0xa2b0, 0x0804,
-	0x17f8, 0xa5b4, 0xa4b8, 0xa3bc, 0xa2c0, 0x0804, 0x17f8, 0xa5c4,
-	0xa4c8, 0xa3cc, 0xa2d0, 0x0804, 0x17f8, 0xa5d4, 0xa4d8, 0xa3dc,
-	0xa2e0, 0x0804, 0x17f8, 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0dfa,
-	0x9082, 0x001b, 0x0002, 0x17d6, 0x17d4, 0x17d4, 0x17d4, 0x17d4,
-	0x17d4, 0x17dd, 0x17d4, 0x17d4, 0x17d4, 0x17d4, 0x17d4, 0x17e4,
-	0x17d4, 0x17d4, 0x17d4, 0x17d4, 0x17d4, 0x17eb, 0x17d4, 0x17d4,
-	0x17d4, 0x17d4, 0x17d4, 0x17f2, 0x080c, 0x0dfa, 0xa56c, 0xa470,
-	0xa774, 0xa678, 0xa37c, 0xa280, 0x00d8, 0xa584, 0xa488, 0xa78c,
-	0xa690, 0xa394, 0xa298, 0x00a0, 0xa59c, 0xa4a0, 0xa7a4, 0xa6a8,
-	0xa3ac, 0xa2b0, 0x0068, 0xa5b4, 0xa4b8, 0xa7bc, 0xa6c0, 0xa3c4,
-	0xa2c8, 0x0030, 0xa5cc, 0xa4d0, 0xa7d4, 0xa6d8, 0xa3dc, 0xa2e0,
-	0xab2e, 0xaa32, 0xad1e, 0xac22, 0xaf26, 0xae2a, 0xa988, 0x8c60,
-	0x2c1d, 0xa8ac, 0xaab0, 0xa836, 0xaa3a, 0x8109, 0xa916, 0x1160,
-	0x3e60, 0x601c, 0xc085, 0x601e, 0xa87c, 0xc0dd, 0xa87e, 0x9006,
-	0x00ce, 0x001e, 0x012e, 0x0005, 0x2800, 0xa80e, 0xab0a, 0x2c00,
-	0xa812, 0x0c70, 0x0804, 0x1710, 0x0016, 0x2009, 0x00a0, 0x8109,
-	0xa001, 0xa001, 0xa001, 0x1dd8, 0x001e, 0x2ff0, 0x0126, 0x2091,
-	0x2200, 0x0016, 0x00c6, 0x3e60, 0x6014, 0x2048, 0x2940, 0xa80e,
-	0x2061, 0x1fc3, 0xa813, 0x1fc3, 0x2c05, 0xa80a, 0xa964, 0xa91a,
-	0xa87c, 0xd0ac, 0x090c, 0x0dfa, 0x9006, 0xa842, 0xa83e, 0x2c05,
-	0x908a, 0x0034, 0x1a0c, 0x0dfa, 0xadcc, 0xacd0, 0xafd4, 0xaed8,
-	0xabdc, 0xaae0, 0xab2e, 0xaa32, 0xad1e, 0xac22, 0xaf26, 0xae2a,
-	0xa8ac, 0xaab0, 0xa836, 0xaa3a, 0xa988, 0xa864, 0x9084, 0x00ff,
-	0x9086, 0x0008, 0x1120, 0x8109, 0xa916, 0x0128, 0x0080, 0x918a,
-	0x0002, 0xa916, 0x1160, 0x3e60, 0x601c, 0xc085, 0x601e, 0xa87c,
-	0xc0dd, 0xa87e, 0x9006, 0x00ce, 0x001e, 0x012e, 0x0005, 0xa804,
-	0x9045, 0x090c, 0x0dfa, 0xa80e, 0xa064, 0xa81a, 0x9084, 0x000f,
-	0x9080, 0x1fc8, 0x2015, 0x82ff, 0x090c, 0x0dfa, 0xaa12, 0x2205,
-	0xa80a, 0x0c08, 0x903e, 0x2730, 0xa880, 0xd0fc, 0x1190, 0x2d00,
-	0x0002, 0x1977, 0x18d9, 0x18d9, 0x1977, 0x1977, 0x1971, 0x1977,
-	0x18d9, 0x1928, 0x1928, 0x1928, 0x1977, 0x1977, 0x1977, 0x196e,
-	0x1928, 0xc0fc, 0xa882, 0xab2c, 0xaa30, 0xad1c, 0xac20, 0xdd9c,
-	0x0904, 0x1979, 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0dfa, 0x9082,
-	0x001b, 0x0002, 0x18c5, 0x18c3, 0x18c3, 0x18c3, 0x18c3, 0x18c3,
-	0x18c9, 0x18c3, 0x18c3, 0x18c3, 0x18c3, 0x18c3, 0x18cd, 0x18c3,
-	0x18c3, 0x18c3, 0x18c3, 0x18c3, 0x18d1, 0x18c3, 0x18c3, 0x18c3,
-	0x18c3, 0x18c3, 0x18d5, 0x080c, 0x0dfa, 0xa774, 0xa678, 0x0804,
-	0x1979, 0xa78c, 0xa690, 0x0804, 0x1979, 0xa7a4, 0xa6a8, 0x0804,
-	0x1979, 0xa7bc, 0xa6c0, 0x0804, 0x1979, 0xa7d4, 0xa6d8, 0x0804,
-	0x1979, 0x2c05, 0x908a, 0x0036, 0x1a0c, 0x0dfa, 0x9082, 0x001b,
-	0x0002, 0x18fc, 0x18fc, 0x18fe, 0x18fc, 0x18fc, 0x18fc, 0x1904,
-	0x18fc, 0x18fc, 0x18fc, 0x190a, 0x18fc, 0x18fc, 0x18fc, 0x1910,
-	0x18fc, 0x18fc, 0x18fc, 0x1916, 0x18fc, 0x18fc, 0x18fc, 0x191c,
-	0x18fc, 0x18fc, 0x18fc, 0x1922, 0x080c, 0x0dfa, 0xa574, 0xa478,
-	0xa37c, 0xa280, 0x0804, 0x1979, 0xa584, 0xa488, 0xa38c, 0xa290,
-	0x0804, 0x1979, 0xa594, 0xa498, 0xa39c, 0xa2a0, 0x0804, 0x1979,
-	0xa5a4, 0xa4a8, 0xa3ac, 0xa2b0, 0x0804, 0x1979, 0xa5b4, 0xa4b8,
-	0xa3bc, 0xa2c0, 0x0804, 0x1979, 0xa5c4, 0xa4c8, 0xa3cc, 0xa2d0,
-	0x0804, 0x1979, 0xa5d4, 0xa4d8, 0xa3dc, 0xa2e0, 0x0804, 0x1979,
-	0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0dfa, 0x9082, 0x001b, 0x0002,
-	0x194b, 0x1949, 0x1949, 0x1949, 0x1949, 0x1949, 0x1952, 0x1949,
-	0x1949, 0x1949, 0x1949, 0x1949, 0x1959, 0x1949, 0x1949, 0x1949,
-	0x1949, 0x1949, 0x1960, 0x1949, 0x1949, 0x1949, 0x1949, 0x1949,
-	0x1967, 0x080c, 0x0dfa, 0xa56c, 0xa470, 0xa774, 0xa678, 0xa37c,
-	0xa280, 0x0438, 0xa584, 0xa488, 0xa78c, 0xa690, 0xa394, 0xa298,
-	0x0400, 0xa59c, 0xa4a0, 0xa7a4, 0xa6a8, 0xa3ac, 0xa2b0, 0x00c8,
-	0xa5b4, 0xa4b8, 0xa7bc, 0xa6c0, 0xa3c4, 0xa2c8, 0x0090, 0xa5cc,
-	0xa4d0, 0xa7d4, 0xa6d8, 0xa3dc, 0xa2e0, 0x0058, 0x9d86, 0x000e,
-	0x1130, 0x080c, 0x1f80, 0x1904, 0x1882, 0x900e, 0x0050, 0x080c,
-	0x0dfa, 0xab2e, 0xaa32, 0xad1e, 0xac22, 0xaf26, 0xae2a, 0x080c,
-	0x1f80, 0x0005, 0x6014, 0x2048, 0x6118, 0x810c, 0x810c, 0x810c,
-	0x81ff, 0x1118, 0xa887, 0x0001, 0x0008, 0xa986, 0x601b, 0x0002,
-	0xa874, 0x9084, 0x00ff, 0x9084, 0x0008, 0x0150, 0x00e9, 0x6000,
-	0x9086, 0x0004, 0x1120, 0x2009, 0x0048, 0x080c, 0xa15d, 0x0005,
-	0xa974, 0xd1dc, 0x1108, 0x0005, 0xa934, 0xa88c, 0x9106, 0x1158,
-	0xa938, 0xa890, 0x9106, 0x1138, 0x601c, 0xc084, 0x601e, 0x2009,
-	0x0048, 0x0804, 0xa15d, 0x0005, 0x0126, 0x00c6, 0x2091, 0x2200,
-	0x00ce, 0x7908, 0x918c, 0x0007, 0x9186, 0x0000, 0x05b0, 0x9186,
-	0x0003, 0x0598, 0x6020, 0x6023, 0x0000, 0x0006, 0x2031, 0x0008,
-	0x00c6, 0x781f, 0x0808, 0x7808, 0xd09c, 0x0120, 0x080c, 0x1370,
-	0x8631, 0x1db8, 0x00ce, 0x781f, 0x0800, 0x2031, 0x0168, 0x00c6,
-	0x7808, 0xd09c, 0x190c, 0x1370, 0x00ce, 0x2001, 0x0038, 0x080c,
-	0x1a87, 0x7930, 0x9186, 0x0040, 0x0160, 0x9186, 0x0042, 0x190c,
-	0x0dfa, 0x2001, 0x001e, 0x8001, 0x1df0, 0x8631, 0x1d40, 0x080c,
-	0x1a96, 0x000e, 0x6022, 0x012e, 0x0005, 0x080c, 0x1a83, 0x7827,
-	0x0015, 0x7828, 0x9c06, 0x1db8, 0x782b, 0x0000, 0x0ca0, 0x00f6,
-	0x2079, 0x0300, 0x7803, 0x0000, 0x78ab, 0x0004, 0x00fe, 0x080c,
-	0x7207, 0x1188, 0x2001, 0x0138, 0x2003, 0x0000, 0x2001, 0x0160,
-	0x2003, 0x0000, 0x2011, 0x012c, 0xa001, 0xa001, 0x8211, 0x1de0,
-	0x0059, 0x0804, 0x72d2, 0x0479, 0x0039, 0x2001, 0x0160, 0x2502,
-	0x2001, 0x0138, 0x2202, 0x0005, 0x00e6, 0x2071, 0x0200, 0x080c,
-	0x2bbc, 0x2009, 0x003c, 0x080c, 0x230a, 0x2001, 0x015d, 0x2003,
-	0x0000, 0x7000, 0x9084, 0x003c, 0x1de0, 0x080c, 0x81f0, 0x70a0,
-	0x70a2, 0x7098, 0x709a, 0x709c, 0x709e, 0x2001, 0x020d, 0x2003,
-	0x0020, 0x00f6, 0x2079, 0x0300, 0x080c, 0x1329, 0x7803, 0x0001,
-	0x00fe, 0x00ee, 0x0005, 0x2001, 0x0138, 0x2014, 0x2003, 0x0000,
-	0x2001, 0x0160, 0x202c, 0x2003, 0x0000, 0x080c, 0x7207, 0x1108,
-	0x0005, 0x2021, 0x0260, 0x2001, 0x0141, 0x201c, 0xd3dc, 0x1168,
-	0x2001, 0x0109, 0x201c, 0x939c, 0x0048, 0x1160, 0x2001, 0x0111,
-	0x201c, 0x83ff, 0x1110, 0x8421, 0x1d70, 0x2001, 0x015d, 0x2003,
-	0x0000, 0x0005, 0x0046, 0x2021, 0x0019, 0x2003, 0x0048, 0xa001,
-	0xa001, 0x201c, 0x939c, 0x0048, 0x0120, 0x8421, 0x1db0, 0x004e,
-	0x0c60, 0x004e, 0x0c40, 0x601c, 0xc084, 0x601e, 0x0005, 0x2c08,
-	0x621c, 0x080c, 0x158b, 0x7930, 0x0005, 0x2c08, 0x621c, 0x080c,
-	0x1636, 0x7930, 0x0005, 0x8001, 0x1df0, 0x0005, 0x2031, 0x0064,
-	0x781c, 0x9084, 0x0007, 0x0170, 0x2001, 0x0038, 0x0c41, 0x9186,
-	0x0040, 0x0904, 0x1af4, 0x2001, 0x001e, 0x0c69, 0x8631, 0x1d80,
-	0x080c, 0x0dfa, 0x781f, 0x0202, 0x2001, 0x015d, 0x2003, 0x0000,
-	0x2001, 0x0dac, 0x0c01, 0x781c, 0xd084, 0x0110, 0x0861, 0x04e0,
-	0x2001, 0x0030, 0x0891, 0x9186, 0x0040, 0x0568, 0x781c, 0xd084,
-	0x1da8, 0x781f, 0x0101, 0x2001, 0x0014, 0x0869, 0x2001, 0x0037,
-	0x0821, 0x9186, 0x0040, 0x0140, 0x2001, 0x0030, 0x080c, 0x1a8d,
-	0x9186, 0x0040, 0x190c, 0x0dfa, 0x00d6, 0x2069, 0x0200, 0x692c,
-	0xd1f4, 0x1170, 0xd1c4, 0x0160, 0xd19c, 0x0130, 0x6800, 0x9085,
-	0x1800, 0x6802, 0x00de, 0x0080, 0x6908, 0x9184, 0x0007, 0x1db0,
-	0x00de, 0x781f, 0x0100, 0x791c, 0x9184, 0x0007, 0x090c, 0x0dfa,
-	0xa001, 0xa001, 0x781f, 0x0200, 0x0005, 0x0126, 0x2091, 0x2400,
-	0x2071, 0x1a3d, 0x2079, 0x0090, 0x012e, 0x0005, 0x9280, 0x0005,
-	0x2004, 0x2048, 0xa97c, 0xd1dc, 0x1904, 0x1b89, 0xa964, 0x9184,
-	0x0007, 0x0002, 0x1b12, 0x1b74, 0x1b29, 0x1b29, 0x1b29, 0x1b5c,
-	0x1b3c, 0x1b2b, 0x918c, 0x00ff, 0x9186, 0x0008, 0x1170, 0xa87c,
-	0xd0b4, 0x0904, 0x1da7, 0x9006, 0xa842, 0xa83e, 0xa988, 0x2900,
-	0xa85a, 0xa813, 0x1fc3, 0x0804, 0x1b85, 0x9186, 0x0048, 0x0904,
-	0x1b74, 0x080c, 0x0dfa, 0xa87c, 0xd0b4, 0x0904, 0x1da7, 0xa890,
-	0xa842, 0xa83a, 0xa88c, 0xa83e, 0xa836, 0xa8ac, 0xa846, 0xa8b0,
-	0xa84a, 0xa988, 0x0804, 0x1b7c, 0xa864, 0x9084, 0x00ff, 0x9086,
-	0x001e, 0x1d38, 0xa87c, 0xd0b4, 0x0904, 0x1da7, 0xa890, 0xa842,
-	0xa83a, 0xa88c, 0xa83e, 0xa836, 0xa8ac, 0xa846, 0xa8b0, 0xa84a,
-	0xa804, 0xa85a, 0x2040, 0xa064, 0x9084, 0x000f, 0x9080, 0x1fc8,
-	0x2005, 0xa812, 0xa988, 0x0448, 0x918c, 0x00ff, 0x9186, 0x0015,
-	0x1540, 0xa87c, 0xd0b4, 0x0904, 0x1da7, 0xa804, 0xa85a, 0x2040,
-	0xa064, 0x9084, 0x000f, 0x9080, 0x1fc8, 0x2005, 0xa812, 0xa988,
-	0x9006, 0xa842, 0xa83e, 0x0088, 0xa87c, 0xd0b4, 0x0904, 0x1da7,
-	0xa988, 0x9006, 0xa842, 0xa83e, 0x2900, 0xa85a, 0xa864, 0x9084,
-	0x000f, 0x9080, 0x1fc8, 0x2005, 0xa812, 0xa916, 0xa87c, 0xc0dd,
-	0xa87e, 0x0005, 0x00f6, 0x2079, 0x0090, 0x782c, 0xd0fc, 0x190c,
-	0x1dec, 0x00e6, 0x2071, 0x1a3d, 0x7000, 0x9005, 0x1904, 0x1bf2,
-	0x7206, 0x9280, 0x0005, 0x204c, 0x9280, 0x0004, 0x2004, 0x782b,
-	0x0004, 0x00f6, 0x2079, 0x0200, 0x7803, 0x0040, 0x00fe, 0x00b6,
-	0x2058, 0xb86c, 0x7836, 0xb890, 0x00be, 0x00f6, 0x2079, 0x0200,
-	0x7803, 0x0040, 0xa001, 0xa001, 0xa001, 0xa001, 0xa001, 0xa001,
-	0x781a, 0x2079, 0x0100, 0x8004, 0x78d6, 0x00fe, 0xa814, 0x2050,
-	0xa858, 0x2040, 0xa810, 0x2060, 0xa064, 0x90ec, 0x000f, 0xa944,
-	0x791a, 0x7116, 0xa848, 0x781e, 0x701a, 0x9006, 0x700e, 0x7012,
-	0x7004, 0xa940, 0xa838, 0x9106, 0x1500, 0xa93c, 0xa834, 0x9106,
-	0x11e0, 0x0006, 0x0016, 0xa938, 0xa834, 0x9105, 0x0118, 0x001e,
-	0x000e, 0x0098, 0x001e, 0x000e, 0x8aff, 0x01c8, 0x0126, 0x2091,
-	0x8000, 0x2009, 0x0306, 0x200b, 0x0808, 0x00d9, 0x0108, 0x00c9,
-	0x012e, 0x9006, 0x00ee, 0x00fe, 0x0005, 0x0036, 0x0046, 0xab38,
-	0xac34, 0x080c, 0x1fe8, 0x004e, 0x003e, 0x0d30, 0x0c98, 0x9085,
-	0x0001, 0x0c80, 0x2009, 0x0306, 0x200b, 0x4800, 0x7027, 0x0000,
-	0x0005, 0x0076, 0x0066, 0x0056, 0x0046, 0x0036, 0x0026, 0x8aff,
-	0x0904, 0x1da0, 0x700c, 0x7214, 0x923a, 0x7010, 0x7218, 0x9203,
-	0x0a04, 0x1d9f, 0x9705, 0x0904, 0x1d9f, 0x903e, 0x2730, 0xa880,
-	0xd0fc, 0x1190, 0x2d00, 0x0002, 0x1d34, 0x1c74, 0x1c74, 0x1d34,
-	0x1d34, 0x1d11, 0x1d34, 0x1c74, 0x1d18, 0x1cc3, 0x1cc3, 0x1d34,
-	0x1d34, 0x1d34, 0x1d0b, 0x1cc3, 0xc0fc, 0xa882, 0xab2c, 0xaa30,
-	0xad1c, 0xac20, 0xdd9c, 0x0904, 0x1d36, 0x2c05, 0x908a, 0x0034,
-	0x1a0c, 0x0dfa, 0x9082, 0x001b, 0x0002, 0x1c60, 0x1c5e, 0x1c5e,
-	0x1c5e, 0x1c5e, 0x1c5e, 0x1c64, 0x1c5e, 0x1c5e, 0x1c5e, 0x1c5e,
-	0x1c5e, 0x1c68, 0x1c5e, 0x1c5e, 0x1c5e, 0x1c5e, 0x1c5e, 0x1c6c,
-	0x1c5e, 0x1c5e, 0x1c5e, 0x1c5e, 0x1c5e, 0x1c70, 0x080c, 0x0dfa,
-	0xa774, 0xa678, 0x0804, 0x1d36, 0xa78c, 0xa690, 0x0804, 0x1d36,
-	0xa7a4, 0xa6a8, 0x0804, 0x1d36, 0xa7bc, 0xa6c0, 0x0804, 0x1d36,
-	0xa7d4, 0xa6d8, 0x0804, 0x1d36, 0x2c05, 0x908a, 0x0036, 0x1a0c,
-	0x0dfa, 0x9082, 0x001b, 0x0002, 0x1c97, 0x1c97, 0x1c99, 0x1c97,
-	0x1c97, 0x1c97, 0x1c9f, 0x1c97, 0x1c97, 0x1c97, 0x1ca5, 0x1c97,
-	0x1c97, 0x1c97, 0x1cab, 0x1c97, 0x1c97, 0x1c97, 0x1cb1, 0x1c97,
-	0x1c97, 0x1c97, 0x1cb7, 0x1c97, 0x1c97, 0x1c97, 0x1cbd, 0x080c,
-	0x0dfa, 0xa574, 0xa478, 0xa37c, 0xa280, 0x0804, 0x1d36, 0xa584,
-	0xa488, 0xa38c, 0xa290, 0x0804, 0x1d36, 0xa594, 0xa498, 0xa39c,
-	0xa2a0, 0x0804, 0x1d36, 0xa5a4, 0xa4a8, 0xa3ac, 0xa2b0, 0x0804,
-	0x1d36, 0xa5b4, 0xa4b8, 0xa3bc, 0xa2c0, 0x0804, 0x1d36, 0xa5c4,
-	0xa4c8, 0xa3cc, 0xa2d0, 0x0804, 0x1d36, 0xa5d4, 0xa4d8, 0xa3dc,
-	0xa2e0, 0x0804, 0x1d36, 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0dfa,
-	0x9082, 0x001b, 0x0002, 0x1ce6, 0x1ce4, 0x1ce4, 0x1ce4, 0x1ce4,
-	0x1ce4, 0x1cee, 0x1ce4, 0x1ce4, 0x1ce4, 0x1ce4, 0x1ce4, 0x1cf6,
-	0x1ce4, 0x1ce4, 0x1ce4, 0x1ce4, 0x1ce4, 0x1cfd, 0x1ce4, 0x1ce4,
-	0x1ce4, 0x1ce4, 0x1ce4, 0x1d04, 0x080c, 0x0dfa, 0xa56c, 0xa470,
-	0xa774, 0xa678, 0xa37c, 0xa280, 0x0804, 0x1d36, 0xa584, 0xa488,
-	0xa78c, 0xa690, 0xa394, 0xa298, 0x0804, 0x1d36, 0xa59c, 0xa4a0,
-	0xa7a4, 0xa6a8, 0xa3ac, 0xa2b0, 0x04c8, 0xa5b4, 0xa4b8, 0xa7bc,
-	0xa6c0, 0xa3c4, 0xa2c8, 0x0490, 0xa5cc, 0xa4d0, 0xa7d4, 0xa6d8,
-	0xa3dc, 0xa2e0, 0x0458, 0xa864, 0x9084, 0x00ff, 0x9086, 0x001e,
-	0x1518, 0x080c, 0x1f80, 0x1904, 0x1c0f, 0x900e, 0x0804, 0x1da0,
-	0xab64, 0x939c, 0x00ff, 0x9386, 0x0048, 0x1180, 0x00c6, 0x7004,
-	0x2060, 0x6004, 0x9086, 0x0043, 0x00ce, 0x0904, 0x1cc3, 0xab9c,
-	0x9016, 0xad8c, 0xac90, 0xaf94, 0xae98, 0x0040, 0x9386, 0x0008,
-	0x0904, 0x1cc3, 0x080c, 0x0dfa, 0x080c, 0x0dfa, 0x2009, 0x030f,
-	0x2104, 0xd0fc, 0x0530, 0x0066, 0x2009, 0x0306, 0x2104, 0x9084,
-	0x0030, 0x15c8, 0x2031, 0x1000, 0x200b, 0x4000, 0x2600, 0x9302,
-	0x928b, 0x0000, 0xa82e, 0xa932, 0x0278, 0x9105, 0x0168, 0x2011,
-	0x0000, 0x2618, 0x2600, 0x9500, 0xa81e, 0x9481, 0x0000, 0xa822,
-	0xa880, 0xc0fd, 0xa882, 0x0020, 0xa82f, 0x0000, 0xa833, 0x0000,
-	0x006e, 0x7b12, 0x7a16, 0x7d02, 0x7c06, 0x7f0a, 0x7e0e, 0x782b,
+	0x782b, 0x0400, 0x7827, 0x0031, 0x782b, 0x1a5a, 0x781f, 0xff00,
+	0x781b, 0xff00, 0x2001, 0x0200, 0x2004, 0xd0dc, 0x0110, 0x781f,
+	0x0303, 0x2061, 0x1a5a, 0x602f, 0x1cd0, 0x2001, 0x1819, 0x2004,
+	0x9082, 0x1cd0, 0x6032, 0x603b, 0x1ec2, 0x783f, 0x3209, 0x00ce,
+	0x0005, 0x0126, 0x2091, 0x2200, 0x7908, 0x9184, 0x0070, 0x190c,
+	0x0dfb, 0xd19c, 0x0158, 0x7820, 0x908c, 0xf000, 0x15e8, 0x908a,
+	0x0024, 0x1a0c, 0x0e02, 0x0023, 0x012e, 0x0005, 0x012e, 0x0005,
+	0x13ac, 0x13ac, 0x13c3, 0x13c8, 0x13cc, 0x13d1, 0x13f9, 0x13fd,
+	0x140b, 0x140f, 0x13ac, 0x149b, 0x149f, 0x150f, 0x13ac, 0x13ac,
+	0x13ac, 0x13ac, 0x13ac, 0x13ac, 0x13ac, 0x13ac, 0x13ac, 0x13ac,
+	0x13ac, 0x13ac, 0x13ac, 0x13d3, 0x13ac, 0x13ac, 0x13ac, 0x13ac,
+	0x13ac, 0x13ac, 0x13b0, 0x13ae, 0x080c, 0x0e02, 0x080c, 0x0dfb,
+	0x080c, 0x1516, 0x2009, 0x1a56, 0x2104, 0x8000, 0x200a, 0x080c,
+	0x7bed, 0x080c, 0x1983, 0x0005, 0x2009, 0x0048, 0x2060, 0x080c,
+	0xa053, 0x012e, 0x0005, 0x7004, 0xc085, 0xc0b5, 0x7006, 0x0005,
+	0x7004, 0xc085, 0x7006, 0x0005, 0x080c, 0x1516, 0x080c, 0x15f0,
+	0x0005, 0x080c, 0x0e02, 0x080c, 0x1516, 0x2060, 0x6014, 0x0096,
+	0x2048, 0xa83b, 0xffff, 0x009e, 0x2009, 0x0048, 0x080c, 0xa053,
+	0x2001, 0x015d, 0x2003, 0x0000, 0x2009, 0x03e8, 0x8109, 0x0160,
+	0x2001, 0x0201, 0x2004, 0x9005, 0x0dc8, 0x2001, 0x0218, 0x2004,
+	0xd0ec, 0x1110, 0x080c, 0x151b, 0x2001, 0x0307, 0x2003, 0x8000,
+	0x0005, 0x7004, 0xc095, 0x7006, 0x0005, 0x080c, 0x1516, 0x2060,
+	0x6014, 0x0096, 0x2048, 0xa83b, 0xffff, 0x009e, 0x2009, 0x0048,
+	0x080c, 0xa053, 0x0005, 0x080c, 0x1516, 0x080c, 0x0e02, 0x080c,
+	0x1516, 0x080c, 0x1486, 0x7827, 0x0018, 0x79ac, 0xd1dc, 0x0540,
+	0x7827, 0x0015, 0x7828, 0x782b, 0x0000, 0x9065, 0x0138, 0x2001,
+	0x020d, 0x2003, 0x0050, 0x2003, 0x0020, 0x0400, 0x7004, 0x9005,
+	0x1180, 0x78ab, 0x0004, 0x7827, 0x0018, 0x782b, 0x0000, 0xd1bc,
+	0x090c, 0x0e02, 0x2001, 0x020d, 0x2003, 0x0050, 0x2003, 0x0020,
+	0x0490, 0x78ab, 0x0004, 0x7803, 0x0001, 0x080c, 0x149f, 0x0005,
+	0x7828, 0x782b, 0x0000, 0x9065, 0x090c, 0x0e02, 0x6014, 0x2048,
+	0x78ab, 0x0004, 0x918c, 0x0700, 0x01a8, 0x080c, 0x7bed, 0x080c,
+	0x1983, 0x080c, 0xbd3b, 0x0158, 0xa9ac, 0xa936, 0xa9b0, 0xa93a,
+	0xa83f, 0xffff, 0xa843, 0xffff, 0xa880, 0xc0bd, 0xa882, 0x080c,
+	0xb974, 0x0005, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc,
+	0x6024, 0x190c, 0xc127, 0x2029, 0x00c8, 0x8529, 0x0128, 0x2001,
+	0x0201, 0x2004, 0x9005, 0x0dc8, 0x7dbc, 0x080c, 0xdb52, 0xd5a4,
+	0x1118, 0x080c, 0x151b, 0x0005, 0x080c, 0x7bed, 0x080c, 0x1983,
+	0x0005, 0x781f, 0x0300, 0x7803, 0x0001, 0x0005, 0x0016, 0x0066,
+	0x0076, 0x00f6, 0x2079, 0x0300, 0x7908, 0x918c, 0x0007, 0x9186,
+	0x0003, 0x0120, 0x2001, 0x0016, 0x080c, 0x158c, 0x00fe, 0x007e,
+	0x006e, 0x001e, 0x0005, 0x7004, 0xc09d, 0x7006, 0x0005, 0x7104,
+	0x9184, 0x0004, 0x190c, 0x0e02, 0xd184, 0x11b1, 0xd19c, 0x0180,
+	0xc19c, 0x7106, 0x0016, 0x080c, 0x15d3, 0x001e, 0x0148, 0x2001,
+	0x020d, 0x2003, 0x0050, 0x2003, 0x0020, 0x080c, 0x151b, 0x0005,
+	0x81ff, 0x190c, 0x0e02, 0x0005, 0x2100, 0xc184, 0xc1b4, 0x7106,
+	0xd0b4, 0x0016, 0x00e6, 0x1904, 0x1504, 0x2071, 0x0200, 0x080c,
+	0x15c7, 0x080c, 0x15d3, 0x05a8, 0x6014, 0x9005, 0x05a8, 0x0096,
+	0x2048, 0xa864, 0x009e, 0x9084, 0x00ff, 0x908e, 0x0029, 0x0160,
+	0x908e, 0x0048, 0x1548, 0x601c, 0xd084, 0x11d8, 0x00f6, 0x2c78,
+	0x080c, 0x165d, 0x00fe, 0x00a8, 0x00f6, 0x2c78, 0x080c, 0x17a7,
+	0x00fe, 0x2009, 0x01f4, 0x8109, 0x0160, 0x2001, 0x0201, 0x2004,
+	0x9005, 0x0dc8, 0x2001, 0x0218, 0x2004, 0xd0ec, 0x1110, 0x0419,
+	0x0040, 0x2001, 0x020d, 0x2003, 0x0020, 0x080c, 0x1339, 0x7803,
+	0x0001, 0x00ee, 0x001e, 0x0005, 0x080c, 0x15d3, 0x0dd0, 0x2001,
+	0x020d, 0x2003, 0x0050, 0x2003, 0x0020, 0x0069, 0x0c90, 0x0031,
+	0x2060, 0x2009, 0x0053, 0x080c, 0xa053, 0x0005, 0x7808, 0xd09c,
+	0x0de8, 0x7820, 0x0005, 0x080c, 0x1486, 0x00d6, 0x2069, 0x0200,
+	0x2009, 0x01f4, 0x8109, 0x0510, 0x6804, 0x9005, 0x0dd8, 0x2001,
+	0x015d, 0x2003, 0x0000, 0x79bc, 0xd1a4, 0x1528, 0x79b8, 0x918c,
+	0x0fff, 0x0180, 0x9182, 0x0841, 0x1268, 0x9188, 0x0007, 0x918c,
+	0x0ff8, 0x810c, 0x810c, 0x810c, 0x080c, 0x157e, 0x6827, 0x0001,
+	0x8109, 0x1dd0, 0x04d9, 0x6827, 0x0002, 0x04c1, 0x6804, 0x9005,
+	0x1130, 0x682c, 0xd0e4, 0x1500, 0x6804, 0x9005, 0x0de8, 0x79b8,
+	0xd1ec, 0x1130, 0x08c0, 0x080c, 0x7bed, 0x080c, 0x1983, 0x0090,
+	0x7827, 0x0015, 0x782b, 0x0000, 0x7827, 0x0018, 0x782b, 0x0000,
+	0x2001, 0x020d, 0x2003, 0x0020, 0x2001, 0x0307, 0x2003, 0x0300,
+	0x7803, 0x0001, 0x00de, 0x0005, 0x682c, 0x9084, 0x5400, 0x9086,
+	0x5400, 0x0d30, 0x7827, 0x0015, 0x782b, 0x0000, 0x7803, 0x0001,
+	0x6800, 0x9085, 0x1800, 0x6802, 0x00de, 0x0005, 0x6824, 0x9084,
+	0x0003, 0x1de0, 0x0005, 0x2001, 0x0030, 0x2c08, 0x621c, 0x0021,
+	0x7830, 0x9086, 0x0041, 0x0005, 0x00f6, 0x2079, 0x0300, 0x0006,
+	0x7808, 0xd09c, 0x0140, 0x0016, 0x0026, 0x00c6, 0x080c, 0x1371,
+	0x00ce, 0x002e, 0x001e, 0x000e, 0x0006, 0x7832, 0x7936, 0x7a3a,
+	0x781b, 0x8080, 0x0059, 0x1118, 0x000e, 0x00fe, 0x0005, 0x000e,
+	0x792c, 0x3900, 0x8000, 0x2004, 0x080c, 0x0e02, 0x2009, 0xff00,
+	0x8109, 0x0120, 0x7818, 0xd0bc, 0x1dd8, 0x0005, 0x9085, 0x0001,
+	0x0005, 0x7832, 0x7936, 0x7a3a, 0x781b, 0x8080, 0x0c79, 0x1108,
+	0x0005, 0x792c, 0x3900, 0x8000, 0x2004, 0x080c, 0x0e02, 0x7037,
+	0x0001, 0x7150, 0x7037, 0x0002, 0x7050, 0x2060, 0xd1bc, 0x1110,
+	0x7054, 0x2060, 0x0005, 0x0006, 0x0046, 0x00e6, 0x2071, 0x0200,
+	0x7037, 0x0002, 0x7058, 0x9084, 0xff00, 0x8007, 0x9086, 0x00bc,
+	0x1158, 0x2021, 0x1a57, 0x2404, 0x8000, 0x0208, 0x2022, 0x080c,
+	0x7bed, 0x080c, 0x1983, 0x9006, 0x00ee, 0x004e, 0x000e, 0x0005,
+	0x0c11, 0x1108, 0x0005, 0x00e6, 0x0016, 0x2071, 0x0200, 0x0879,
+	0x6124, 0xd1dc, 0x01f8, 0x701c, 0xd08c, 0x0904, 0x1652, 0x7017,
+	0x0000, 0x2001, 0x0264, 0x2004, 0xd0bc, 0x0904, 0x1652, 0x2001,
+	0x0268, 0x00c6, 0x2064, 0x6104, 0x6038, 0x00ce, 0x918e, 0x0039,
+	0x1904, 0x1652, 0x9c06, 0x15f0, 0x0126, 0x2091, 0x2600, 0x080c,
+	0x7b34, 0x012e, 0x7358, 0x745c, 0x6014, 0x905d, 0x0598, 0x2b48,
+	0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x190c, 0xc102,
+	0xab42, 0xac3e, 0x2001, 0x187d, 0x2004, 0xd0b4, 0x1170, 0x601c,
+	0xd0e4, 0x1158, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc,
+	0x1120, 0xa83b, 0x7fff, 0xa837, 0xffff, 0x080c, 0x1ee2, 0x1190,
+	0x080c, 0x1804, 0x2a00, 0xa816, 0x0130, 0x2800, 0xa80e, 0x2c05,
+	0xa80a, 0x2c00, 0xa812, 0x7037, 0x0020, 0x781f, 0x0300, 0x001e,
+	0x00ee, 0x0005, 0x7037, 0x0050, 0x7037, 0x0020, 0x001e, 0x00ee,
+	0x080c, 0x151b, 0x0005, 0x080c, 0x0e02, 0x0016, 0x2009, 0x00a0,
+	0x8109, 0xa001, 0xa001, 0xa001, 0x1dd8, 0x001e, 0x2ff0, 0x0126,
+	0x2091, 0x2200, 0x0016, 0x00c6, 0x3e60, 0x6014, 0x2048, 0x2940,
+	0x903e, 0x2730, 0xa864, 0x2068, 0xa81a, 0x9d84, 0x000f, 0x9088,
+	0x1ec2, 0x2165, 0x0002, 0x1692, 0x16df, 0x1692, 0x1692, 0x1692,
+	0x16c1, 0x1692, 0x1696, 0x168b, 0x16d6, 0x1692, 0x1692, 0x1692,
+	0x179c, 0x16aa, 0x16a0, 0xa964, 0x918c, 0x00ff, 0x918e, 0x0048,
+	0x0904, 0x16d6, 0x9085, 0x0001, 0x0804, 0x1792, 0xa87c, 0xd0bc,
+	0x0dc8, 0xa890, 0xa842, 0xa88c, 0xa83e, 0xa888, 0x0804, 0x16e6,
+	0xa87c, 0xd0bc, 0x0d78, 0xa890, 0xa842, 0xa88c, 0xa83e, 0xa888,
+	0x0804, 0x1735, 0xa87c, 0xd0bc, 0x0d28, 0xa890, 0xa842, 0xa88c,
+	0xa83e, 0xa804, 0x9045, 0x090c, 0x0e02, 0xa164, 0xa91a, 0x91ec,
+	0x000f, 0x9d80, 0x1ec2, 0x2065, 0xa888, 0xd19c, 0x1904, 0x1735,
+	0x0428, 0xa87c, 0xd0ac, 0x0970, 0xa804, 0x9045, 0x090c, 0x0e02,
+	0xa164, 0xa91a, 0x91ec, 0x000f, 0x9d80, 0x1ec2, 0x2065, 0x9006,
+	0xa842, 0xa83e, 0xd19c, 0x1904, 0x1735, 0x0080, 0xa87c, 0xd0ac,
+	0x0904, 0x1692, 0x9006, 0xa842, 0xa83e, 0x0804, 0x1735, 0xa87c,
+	0xd0ac, 0x0904, 0x1692, 0x9006, 0xa842, 0xa83e, 0x2c05, 0x908a,
+	0x0036, 0x1a0c, 0x0e02, 0x9082, 0x001b, 0x0002, 0x1709, 0x1709,
+	0x170b, 0x1709, 0x1709, 0x1709, 0x1711, 0x1709, 0x1709, 0x1709,
+	0x1717, 0x1709, 0x1709, 0x1709, 0x171d, 0x1709, 0x1709, 0x1709,
+	0x1723, 0x1709, 0x1709, 0x1709, 0x1729, 0x1709, 0x1709, 0x1709,
+	0x172f, 0x080c, 0x0e02, 0xa574, 0xa478, 0xa37c, 0xa280, 0x0804,
+	0x177a, 0xa584, 0xa488, 0xa38c, 0xa290, 0x0804, 0x177a, 0xa594,
+	0xa498, 0xa39c, 0xa2a0, 0x0804, 0x177a, 0xa5a4, 0xa4a8, 0xa3ac,
+	0xa2b0, 0x0804, 0x177a, 0xa5b4, 0xa4b8, 0xa3bc, 0xa2c0, 0x0804,
+	0x177a, 0xa5c4, 0xa4c8, 0xa3cc, 0xa2d0, 0x0804, 0x177a, 0xa5d4,
+	0xa4d8, 0xa3dc, 0xa2e0, 0x0804, 0x177a, 0x2c05, 0x908a, 0x0034,
+	0x1a0c, 0x0e02, 0x9082, 0x001b, 0x0002, 0x1758, 0x1756, 0x1756,
+	0x1756, 0x1756, 0x1756, 0x175f, 0x1756, 0x1756, 0x1756, 0x1756,
+	0x1756, 0x1766, 0x1756, 0x1756, 0x1756, 0x1756, 0x1756, 0x176d,
+	0x1756, 0x1756, 0x1756, 0x1756, 0x1756, 0x1774, 0x080c, 0x0e02,
+	0xa56c, 0xa470, 0xa774, 0xa678, 0xa37c, 0xa280, 0x00d8, 0xa584,
+	0xa488, 0xa78c, 0xa690, 0xa394, 0xa298, 0x00a0, 0xa59c, 0xa4a0,
+	0xa7a4, 0xa6a8, 0xa3ac, 0xa2b0, 0x0068, 0xa5b4, 0xa4b8, 0xa7bc,
+	0xa6c0, 0xa3c4, 0xa2c8, 0x0030, 0xa5cc, 0xa4d0, 0xa7d4, 0xa6d8,
+	0xa3dc, 0xa2e0, 0xab2e, 0xaa32, 0xad1e, 0xac22, 0xaf26, 0xae2a,
+	0xa988, 0x8c60, 0x2c1d, 0xa8ac, 0xaab0, 0xa836, 0xaa3a, 0x8109,
+	0xa916, 0x1160, 0x3e60, 0x601c, 0xc085, 0x601e, 0xa87c, 0xc0dd,
+	0xa87e, 0x9006, 0x00ce, 0x001e, 0x012e, 0x0005, 0x2800, 0xa80e,
+	0xab0a, 0x2c00, 0xa812, 0x0c70, 0x0804, 0x1692, 0x0016, 0x2009,
+	0x00a0, 0x8109, 0xa001, 0xa001, 0xa001, 0x1dd8, 0x001e, 0x2ff0,
+	0x0126, 0x2091, 0x2200, 0x0016, 0x00c6, 0x3e60, 0x6014, 0x2048,
+	0x2940, 0xa80e, 0x2061, 0x1ebd, 0xa813, 0x1ebd, 0x2c05, 0xa80a,
+	0xa964, 0xa91a, 0xa87c, 0xd0ac, 0x090c, 0x0e02, 0x9006, 0xa842,
+	0xa83e, 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0e02, 0xadcc, 0xacd0,
+	0xafd4, 0xaed8, 0xabdc, 0xaae0, 0xab2e, 0xaa32, 0xad1e, 0xac22,
+	0xaf26, 0xae2a, 0xa8ac, 0xaab0, 0xa836, 0xaa3a, 0xa988, 0xa864,
+	0x9084, 0x00ff, 0x9086, 0x0008, 0x1120, 0x8109, 0xa916, 0x0128,
+	0x0080, 0x918a, 0x0002, 0xa916, 0x1160, 0x3e60, 0x601c, 0xc085,
+	0x601e, 0xa87c, 0xc0dd, 0xa87e, 0x9006, 0x00ce, 0x001e, 0x012e,
+	0x0005, 0xa804, 0x9045, 0x090c, 0x0e02, 0xa80e, 0xa064, 0xa81a,
+	0x9084, 0x000f, 0x9080, 0x1ec2, 0x2015, 0x82ff, 0x090c, 0x0e02,
+	0xaa12, 0x2205, 0xa80a, 0x0c08, 0x903e, 0x2730, 0xa880, 0xd0fc,
+	0x1190, 0x2d00, 0x0002, 0x18f9, 0x185b, 0x185b, 0x18f9, 0x18f9,
+	0x18f3, 0x18f9, 0x185b, 0x18aa, 0x18aa, 0x18aa, 0x18f9, 0x18f9,
+	0x18f9, 0x18f0, 0x18aa, 0xc0fc, 0xa882, 0xab2c, 0xaa30, 0xad1c,
+	0xac20, 0xdd9c, 0x0904, 0x18fb, 0x2c05, 0x908a, 0x0034, 0x1a0c,
+	0x0e02, 0x9082, 0x001b, 0x0002, 0x1847, 0x1845, 0x1845, 0x1845,
+	0x1845, 0x1845, 0x184b, 0x1845, 0x1845, 0x1845, 0x1845, 0x1845,
+	0x184f, 0x1845, 0x1845, 0x1845, 0x1845, 0x1845, 0x1853, 0x1845,
+	0x1845, 0x1845, 0x1845, 0x1845, 0x1857, 0x080c, 0x0e02, 0xa774,
+	0xa678, 0x0804, 0x18fb, 0xa78c, 0xa690, 0x0804, 0x18fb, 0xa7a4,
+	0xa6a8, 0x0804, 0x18fb, 0xa7bc, 0xa6c0, 0x0804, 0x18fb, 0xa7d4,
+	0xa6d8, 0x0804, 0x18fb, 0x2c05, 0x908a, 0x0036, 0x1a0c, 0x0e02,
+	0x9082, 0x001b, 0x0002, 0x187e, 0x187e, 0x1880, 0x187e, 0x187e,
+	0x187e, 0x1886, 0x187e, 0x187e, 0x187e, 0x188c, 0x187e, 0x187e,
+	0x187e, 0x1892, 0x187e, 0x187e, 0x187e, 0x1898, 0x187e, 0x187e,
+	0x187e, 0x189e, 0x187e, 0x187e, 0x187e, 0x18a4, 0x080c, 0x0e02,
+	0xa574, 0xa478, 0xa37c, 0xa280, 0x0804, 0x18fb, 0xa584, 0xa488,
+	0xa38c, 0xa290, 0x0804, 0x18fb, 0xa594, 0xa498, 0xa39c, 0xa2a0,
+	0x0804, 0x18fb, 0xa5a4, 0xa4a8, 0xa3ac, 0xa2b0, 0x0804, 0x18fb,
+	0xa5b4, 0xa4b8, 0xa3bc, 0xa2c0, 0x0804, 0x18fb, 0xa5c4, 0xa4c8,
+	0xa3cc, 0xa2d0, 0x0804, 0x18fb, 0xa5d4, 0xa4d8, 0xa3dc, 0xa2e0,
+	0x0804, 0x18fb, 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0e02, 0x9082,
+	0x001b, 0x0002, 0x18cd, 0x18cb, 0x18cb, 0x18cb, 0x18cb, 0x18cb,
+	0x18d4, 0x18cb, 0x18cb, 0x18cb, 0x18cb, 0x18cb, 0x18db, 0x18cb,
+	0x18cb, 0x18cb, 0x18cb, 0x18cb, 0x18e2, 0x18cb, 0x18cb, 0x18cb,
+	0x18cb, 0x18cb, 0x18e9, 0x080c, 0x0e02, 0xa56c, 0xa470, 0xa774,
+	0xa678, 0xa37c, 0xa280, 0x0438, 0xa584, 0xa488, 0xa78c, 0xa690,
+	0xa394, 0xa298, 0x0400, 0xa59c, 0xa4a0, 0xa7a4, 0xa6a8, 0xa3ac,
+	0xa2b0, 0x00c8, 0xa5b4, 0xa4b8, 0xa7bc, 0xa6c0, 0xa3c4, 0xa2c8,
+	0x0090, 0xa5cc, 0xa4d0, 0xa7d4, 0xa6d8, 0xa3dc, 0xa2e0, 0x0058,
+	0x9d86, 0x000e, 0x1130, 0x080c, 0x1e80, 0x1904, 0x1804, 0x900e,
+	0x0050, 0x080c, 0x0e02, 0xab2e, 0xaa32, 0xad1e, 0xac22, 0xaf26,
+	0xae2a, 0x080c, 0x1e80, 0x0005, 0x6014, 0x2048, 0x6118, 0x81ff,
+	0x0148, 0x810c, 0x810c, 0x810c, 0x81ff, 0x1118, 0xa887, 0x0001,
+	0x0008, 0xa986, 0x601b, 0x0002, 0xa874, 0x9084, 0x00ff, 0x9084,
+	0x0008, 0x0150, 0x00e9, 0x6000, 0x9086, 0x0004, 0x1120, 0x2009,
+	0x0048, 0x080c, 0xa053, 0x0005, 0xa974, 0xd1dc, 0x1108, 0x0005,
+	0xa934, 0xa88c, 0x9106, 0x1158, 0xa938, 0xa890, 0x9106, 0x1138,
+	0x601c, 0xc084, 0x601e, 0x2009, 0x0048, 0x0804, 0xa053, 0x0005,
+	0x0126, 0x00c6, 0x2091, 0x2200, 0x00ce, 0x7908, 0x918c, 0x0007,
+	0x9186, 0x0000, 0x05b0, 0x9186, 0x0003, 0x0598, 0x6020, 0x6023,
+	0x0000, 0x0006, 0x2031, 0x0008, 0x00c6, 0x781f, 0x0808, 0x7808,
+	0xd09c, 0x0120, 0x080c, 0x1371, 0x8631, 0x1db8, 0x00ce, 0x781f,
+	0x0800, 0x2031, 0x0168, 0x00c6, 0x7808, 0xd09c, 0x190c, 0x1371,
+	0x00ce, 0x2001, 0x0038, 0x080c, 0x1a0b, 0x7930, 0x9186, 0x0040,
+	0x0160, 0x9186, 0x0042, 0x190c, 0x0e02, 0x2001, 0x001e, 0x8001,
+	0x1df0, 0x8631, 0x1d40, 0x080c, 0x1a1a, 0x000e, 0x6022, 0x012e,
+	0x0005, 0x080c, 0x1a07, 0x7827, 0x0015, 0x7828, 0x9c06, 0x1db8,
+	0x782b, 0x0000, 0x0ca0, 0x00f6, 0x2079, 0x0300, 0x7803, 0x0000,
+	0x78ab, 0x0004, 0x00fe, 0x080c, 0x717f, 0x1188, 0x2001, 0x0138,
+	0x2003, 0x0000, 0x2001, 0x0160, 0x2003, 0x0000, 0x2011, 0x012c,
+	0xa001, 0xa001, 0x8211, 0x1de0, 0x0059, 0x0804, 0x7247, 0x0479,
+	0x0039, 0x2001, 0x0160, 0x2502, 0x2001, 0x0138, 0x2202, 0x0005,
+	0x00e6, 0x2071, 0x0200, 0x080c, 0x2abc, 0x2009, 0x003c, 0x080c,
+	0x2204, 0x2001, 0x015d, 0x2003, 0x0000, 0x7000, 0x9084, 0x003c,
+	0x1de0, 0x080c, 0x8170, 0x70a0, 0x70a2, 0x7098, 0x709a, 0x709c,
+	0x709e, 0x2001, 0x020d, 0x2003, 0x0020, 0x00f6, 0x2079, 0x0300,
+	0x080c, 0x1339, 0x7803, 0x0001, 0x00fe, 0x00ee, 0x0005, 0x2001,
+	0x0138, 0x2014, 0x2003, 0x0000, 0x2001, 0x0160, 0x202c, 0x2003,
+	0x0000, 0x080c, 0x717f, 0x1108, 0x0005, 0x2021, 0x0260, 0x2001,
+	0x0141, 0x201c, 0xd3dc, 0x1168, 0x2001, 0x0109, 0x201c, 0x939c,
+	0x0048, 0x1160, 0x2001, 0x0111, 0x201c, 0x83ff, 0x1110, 0x8421,
+	0x1d70, 0x2001, 0x015d, 0x2003, 0x0000, 0x0005, 0x0046, 0x2021,
+	0x0019, 0x2003, 0x0048, 0xa001, 0xa001, 0x201c, 0x939c, 0x0048,
+	0x0120, 0x8421, 0x1db0, 0x004e, 0x0c60, 0x004e, 0x0c40, 0x601c,
+	0xc084, 0x601e, 0x0005, 0x2c08, 0x621c, 0x080c, 0x158c, 0x7930,
+	0x0005, 0x2c08, 0x621c, 0x080c, 0x15b9, 0x7930, 0x0005, 0x8001,
+	0x1df0, 0x0005, 0x2031, 0x0064, 0x781c, 0x9084, 0x0007, 0x0170,
+	0x2001, 0x0038, 0x0c41, 0x9186, 0x0040, 0x0904, 0x1a78, 0x2001,
+	0x001e, 0x0c69, 0x8631, 0x1d80, 0x080c, 0x0e02, 0x781f, 0x0202,
+	0x2001, 0x015d, 0x2003, 0x0000, 0x2001, 0x0dac, 0x0c01, 0x781c,
+	0xd084, 0x0110, 0x0861, 0x04e0, 0x2001, 0x0030, 0x0891, 0x9186,
+	0x0040, 0x0568, 0x781c, 0xd084, 0x1da8, 0x781f, 0x0101, 0x2001,
+	0x0014, 0x0869, 0x2001, 0x0037, 0x0821, 0x9186, 0x0040, 0x0140,
+	0x2001, 0x0030, 0x080c, 0x1a11, 0x9186, 0x0040, 0x190c, 0x0e02,
+	0x00d6, 0x2069, 0x0200, 0x692c, 0xd1f4, 0x1170, 0xd1c4, 0x0160,
+	0xd19c, 0x0130, 0x6800, 0x9085, 0x1800, 0x6802, 0x00de, 0x0080,
+	0x6908, 0x9184, 0x0007, 0x1db0, 0x00de, 0x781f, 0x0100, 0x791c,
+	0x9184, 0x0007, 0x090c, 0x0e02, 0xa001, 0xa001, 0x781f, 0x0200,
+	0x0005, 0x0126, 0x2091, 0x2400, 0x2071, 0x1a42, 0x2079, 0x0090,
+	0x012e, 0x0005, 0x9280, 0x0005, 0x2004, 0x2048, 0xa97c, 0xd1dc,
+	0x1904, 0x1b0d, 0xa964, 0x9184, 0x0007, 0x0002, 0x1a96, 0x1af8,
+	0x1aad, 0x1aad, 0x1aad, 0x1ae0, 0x1ac0, 0x1aaf, 0x918c, 0x00ff,
+	0x9186, 0x0008, 0x1170, 0xa87c, 0xd0b4, 0x0904, 0x1cc3, 0x9006,
+	0xa842, 0xa83e, 0xa988, 0x2900, 0xa85a, 0xa813, 0x1ebd, 0x0804,
+	0x1b09, 0x9186, 0x0048, 0x0904, 0x1af8, 0x080c, 0x0e02, 0xa87c,
+	0xd0b4, 0x0904, 0x1cc3, 0xa890, 0xa842, 0xa83a, 0xa88c, 0xa83e,
+	0xa836, 0xa8ac, 0xa846, 0xa8b0, 0xa84a, 0xa988, 0x0804, 0x1b00,
+	0xa864, 0x9084, 0x00ff, 0x9086, 0x001e, 0x1d38, 0xa87c, 0xd0b4,
+	0x0904, 0x1cc3, 0xa890, 0xa842, 0xa83a, 0xa88c, 0xa83e, 0xa836,
+	0xa8ac, 0xa846, 0xa8b0, 0xa84a, 0xa804, 0xa85a, 0x2040, 0xa064,
+	0x9084, 0x000f, 0x9080, 0x1ec2, 0x2005, 0xa812, 0xa988, 0x0448,
+	0x918c, 0x00ff, 0x9186, 0x0015, 0x1540, 0xa87c, 0xd0b4, 0x0904,
+	0x1cc3, 0xa804, 0xa85a, 0x2040, 0xa064, 0x9084, 0x000f, 0x9080,
+	0x1ec2, 0x2005, 0xa812, 0xa988, 0x9006, 0xa842, 0xa83e, 0x0088,
+	0xa87c, 0xd0b4, 0x0904, 0x1cc3, 0xa988, 0x9006, 0xa842, 0xa83e,
+	0x2900, 0xa85a, 0xa864, 0x9084, 0x000f, 0x9080, 0x1ec2, 0x2005,
+	0xa812, 0xa916, 0xa87c, 0xc0dd, 0xa87e, 0x0005, 0x00f6, 0x2079,
+	0x0090, 0x782c, 0xd0fc, 0x190c, 0x1d04, 0x00e6, 0x2071, 0x1a42,
+	0x7000, 0x9005, 0x1904, 0x1b65, 0x7206, 0x9280, 0x0005, 0x204c,
+	0x9280, 0x0004, 0x2004, 0x782b, 0x0004, 0x00f6, 0x2079, 0x0200,
+	0x7803, 0x0040, 0x00fe, 0x00b6, 0x2058, 0xb86c, 0x7836, 0xb890,
+	0x00be, 0x00f6, 0x2079, 0x0200, 0x7803, 0x0040, 0xa001, 0xa001,
+	0xa001, 0xa001, 0xa001, 0xa001, 0x781a, 0x78d7, 0x0000, 0x00fe,
+	0xa814, 0x2050, 0xa858, 0x2040, 0xa810, 0x2060, 0xa064, 0x90ec,
+	0x000f, 0xa944, 0x791a, 0x7116, 0xa848, 0x781e, 0x701a, 0x9006,
+	0x700e, 0x7012, 0x7004, 0xa940, 0xa838, 0x9106, 0x1188, 0xa93c,
+	0xa834, 0x9106, 0x1168, 0x8aff, 0x01a8, 0x0126, 0x2091, 0x8000,
+	0x00a1, 0x0108, 0x0091, 0x012e, 0x9006, 0x00ee, 0x00fe, 0x0005,
+	0x0036, 0x0046, 0xab38, 0xac34, 0x080c, 0x1ee2, 0x004e, 0x003e,
+	0x0d50, 0x0c98, 0x9085, 0x0001, 0x0c80, 0x0076, 0x0066, 0x0056,
+	0x0046, 0x0036, 0x0026, 0x8aff, 0x0904, 0x1cbc, 0x700c, 0x7214,
+	0x923a, 0x7010, 0x7218, 0x9203, 0x0a04, 0x1cbb, 0x9705, 0x0904,
+	0x1cbb, 0x903e, 0x2730, 0xa880, 0xd0fc, 0x1190, 0x2d00, 0x0002,
+	0x1c9f, 0x1be0, 0x1be0, 0x1c9f, 0x1c9f, 0x1c7d, 0x1c9f, 0x1be0,
+	0x1c83, 0x1c2f, 0x1c2f, 0x1c9f, 0x1c9f, 0x1c9f, 0x1c77, 0x1c2f,
+	0xc0fc, 0xa882, 0xab2c, 0xaa30, 0xad1c, 0xac20, 0xdd9c, 0x0904,
+	0x1ca1, 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0e02, 0x9082, 0x001b,
+	0x0002, 0x1bcc, 0x1bca, 0x1bca, 0x1bca, 0x1bca, 0x1bca, 0x1bd0,
+	0x1bca, 0x1bca, 0x1bca, 0x1bca, 0x1bca, 0x1bd4, 0x1bca, 0x1bca,
+	0x1bca, 0x1bca, 0x1bca, 0x1bd8, 0x1bca, 0x1bca, 0x1bca, 0x1bca,
+	0x1bca, 0x1bdc, 0x080c, 0x0e02, 0xa774, 0xa678, 0x0804, 0x1ca1,
+	0xa78c, 0xa690, 0x0804, 0x1ca1, 0xa7a4, 0xa6a8, 0x0804, 0x1ca1,
+	0xa7bc, 0xa6c0, 0x0804, 0x1ca1, 0xa7d4, 0xa6d8, 0x0804, 0x1ca1,
+	0x2c05, 0x908a, 0x0036, 0x1a0c, 0x0e02, 0x9082, 0x001b, 0x0002,
+	0x1c03, 0x1c03, 0x1c05, 0x1c03, 0x1c03, 0x1c03, 0x1c0b, 0x1c03,
+	0x1c03, 0x1c03, 0x1c11, 0x1c03, 0x1c03, 0x1c03, 0x1c17, 0x1c03,
+	0x1c03, 0x1c03, 0x1c1d, 0x1c03, 0x1c03, 0x1c03, 0x1c23, 0x1c03,
+	0x1c03, 0x1c03, 0x1c29, 0x080c, 0x0e02, 0xa574, 0xa478, 0xa37c,
+	0xa280, 0x0804, 0x1ca1, 0xa584, 0xa488, 0xa38c, 0xa290, 0x0804,
+	0x1ca1, 0xa594, 0xa498, 0xa39c, 0xa2a0, 0x0804, 0x1ca1, 0xa5a4,
+	0xa4a8, 0xa3ac, 0xa2b0, 0x0804, 0x1ca1, 0xa5b4, 0xa4b8, 0xa3bc,
+	0xa2c0, 0x0804, 0x1ca1, 0xa5c4, 0xa4c8, 0xa3cc, 0xa2d0, 0x0804,
+	0x1ca1, 0xa5d4, 0xa4d8, 0xa3dc, 0xa2e0, 0x0804, 0x1ca1, 0x2c05,
+	0x908a, 0x0034, 0x1a0c, 0x0e02, 0x9082, 0x001b, 0x0002, 0x1c52,
+	0x1c50, 0x1c50, 0x1c50, 0x1c50, 0x1c50, 0x1c5a, 0x1c50, 0x1c50,
+	0x1c50, 0x1c50, 0x1c50, 0x1c62, 0x1c50, 0x1c50, 0x1c50, 0x1c50,
+	0x1c50, 0x1c69, 0x1c50, 0x1c50, 0x1c50, 0x1c50, 0x1c50, 0x1c70,
+	0x080c, 0x0e02, 0xa56c, 0xa470, 0xa774, 0xa678, 0xa37c, 0xa280,
+	0x0804, 0x1ca1, 0xa584, 0xa488, 0xa78c, 0xa690, 0xa394, 0xa298,
+	0x0804, 0x1ca1, 0xa59c, 0xa4a0, 0xa7a4, 0xa6a8, 0xa3ac, 0xa2b0,
+	0x04c0, 0xa5b4, 0xa4b8, 0xa7bc, 0xa6c0, 0xa3c4, 0xa2c8, 0x0488,
+	0xa5cc, 0xa4d0, 0xa7d4, 0xa6d8, 0xa3dc, 0xa2e0, 0x0450, 0xa864,
+	0x9084, 0x00ff, 0x9086, 0x001e, 0x1510, 0x080c, 0x1e80, 0x1904,
+	0x1b7b, 0x900e, 0x04c8, 0xab64, 0x939c, 0x00ff, 0x9386, 0x0048,
+	0x1180, 0x00c6, 0x7004, 0x2060, 0x6004, 0x9086, 0x0043, 0x00ce,
+	0x0904, 0x1c2f, 0xab9c, 0x9016, 0xad8c, 0xac90, 0xaf94, 0xae98,
+	0x0040, 0x9386, 0x0008, 0x0904, 0x1c2f, 0x080c, 0x0e02, 0x080c,
+	0x0e02, 0x7b12, 0x7a16, 0x7d02, 0x7c06, 0x7f0a, 0x7e0e, 0x782b,
 	0x0001, 0x7000, 0x8000, 0x7002, 0xa83c, 0x9300, 0xa83e, 0xa840,
 	0x9201, 0xa842, 0x700c, 0x9300, 0x700e, 0x7010, 0x9201, 0x7012,
-	0x080c, 0x1f80, 0x0428, 0x2031, 0x0080, 0x9584, 0x007f, 0x0108,
-	0x9632, 0x7124, 0x7000, 0x9086, 0x0000, 0x1198, 0xc185, 0x7126,
-	0x2009, 0x0306, 0x2104, 0xd0b4, 0x1904, 0x1d46, 0x200b, 0x4040,
-	0x2009, 0x1a57, 0x2104, 0x8000, 0x0a04, 0x1d46, 0x200a, 0x0804,
-	0x1d46, 0xc18d, 0x7126, 0xd184, 0x1d58, 0x0804, 0x1d46, 0x9006,
-	0x002e, 0x003e, 0x004e, 0x005e, 0x006e, 0x007e, 0x0005, 0x080c,
-	0x0dfa, 0x0026, 0x2001, 0x0105, 0x2003, 0x0010, 0x782b, 0x0004,
-	0x7003, 0x0000, 0x7004, 0x0016, 0x080c, 0x1c02, 0x001e, 0x2060,
-	0x6014, 0x2048, 0x080c, 0xbe37, 0x0118, 0xa880, 0xc0bd, 0xa882,
+	0x080c, 0x1e80, 0x0008, 0x9006, 0x002e, 0x003e, 0x004e, 0x005e,
+	0x006e, 0x007e, 0x0005, 0x080c, 0x0e02, 0x0026, 0x2001, 0x0105,
+	0x2003, 0x0010, 0x782b, 0x0004, 0x7003, 0x0000, 0x7004, 0x2060,
+	0x6014, 0x2048, 0x080c, 0xbd3b, 0x0118, 0xa880, 0xc0bd, 0xa882,
 	0x6020, 0x9086, 0x0006, 0x1180, 0x2061, 0x0100, 0x62c8, 0x2001,
 	0x00fa, 0x8001, 0x1df0, 0x60c8, 0x9206, 0x1dc0, 0x60c4, 0xa89a,
-	0x60c8, 0xa896, 0x7004, 0x2060, 0x00c6, 0x080c, 0xba56, 0x00ce,
-	0x2001, 0x19ce, 0x2004, 0x9c06, 0x1160, 0x2009, 0x0040, 0x080c,
-	0x230a, 0x080c, 0x9b88, 0x2011, 0x0000, 0x080c, 0x9a19, 0x080c,
-	0x8ced, 0x002e, 0x0804, 0x1f30, 0x0126, 0x2091, 0x2400, 0xa858,
-	0x2040, 0x792c, 0x782b, 0x0002, 0x9184, 0x0700, 0x1904, 0x1da9,
-	0x7000, 0x0002, 0x1f30, 0x1dfe, 0x1e7e, 0x1f2e, 0x8001, 0x7002,
-	0x7027, 0x0000, 0xd19c, 0x1158, 0x8aff, 0x0904, 0x1e4b, 0x080c,
-	0x1c09, 0x0904, 0x1f30, 0x080c, 0x1c09, 0x0804, 0x1f30, 0x782b,
-	0x0004, 0xd194, 0x0148, 0xa880, 0xc0fc, 0xa882, 0x8aff, 0x1518,
-	0xa87c, 0xc0f5, 0xa87e, 0x00f8, 0x0026, 0x0036, 0xab3c, 0xaa40,
-	0x0016, 0x7910, 0xa82c, 0x9100, 0xa82e, 0x7914, 0xa830, 0x9101,
-	0xa832, 0x001e, 0x7810, 0x931a, 0x7814, 0x9213, 0x7800, 0xa81e,
-	0x7804, 0xa822, 0xab3e, 0xaa42, 0x003e, 0x002e, 0x080c, 0x1f9b,
-	0xa880, 0xc0fd, 0xa882, 0x2a00, 0xa816, 0x2800, 0xa85a, 0x2c00,
-	0xa812, 0x7003, 0x0000, 0x2009, 0x0306, 0x200b, 0x4800, 0x7027,
-	0x0000, 0x0804, 0x1f30, 0x00f6, 0x0026, 0x781c, 0x0006, 0x7818,
-	0x0006, 0x2079, 0x0100, 0x7a14, 0x9284, 0x1984, 0x9085, 0x0012,
-	0x7816, 0x0036, 0x2019, 0x1000, 0x8319, 0x090c, 0x0dfa, 0x7820,
-	0xd0bc, 0x1dd0, 0x003e, 0x79c8, 0x000e, 0x9102, 0x001e, 0x0006,
-	0x0016, 0x79c4, 0x000e, 0x9103, 0x78c6, 0x000e, 0x78ca, 0x9284,
-	0x1984, 0x9085, 0x0012, 0x7816, 0x002e, 0x00fe, 0x782b, 0x0008,
-	0x7003, 0x0000, 0x080c, 0x1c02, 0x0804, 0x1f30, 0x8001, 0x7002,
-	0x7024, 0x8004, 0x7026, 0xd194, 0x0170, 0x782c, 0xd0fc, 0x1904,
-	0x1df1, 0xd19c, 0x1904, 0x1f2c, 0x8aff, 0x0904, 0x1f30, 0x080c,
-	0x1c09, 0x0804, 0x1f30, 0x0026, 0x0036, 0xab3c, 0xaa40, 0x080c,
-	0x1f9b, 0xdd9c, 0x1904, 0x1eeb, 0x2c05, 0x908a, 0x0036, 0x1a0c,
-	0x0dfa, 0x9082, 0x001b, 0x0002, 0x1ebf, 0x1ebf, 0x1ec1, 0x1ebf,
-	0x1ebf, 0x1ebf, 0x1ec7, 0x1ebf, 0x1ebf, 0x1ebf, 0x1ecd, 0x1ebf,
-	0x1ebf, 0x1ebf, 0x1ed3, 0x1ebf, 0x1ebf, 0x1ebf, 0x1ed9, 0x1ebf,
-	0x1ebf, 0x1ebf, 0x1edf, 0x1ebf, 0x1ebf, 0x1ebf, 0x1ee5, 0x080c,
-	0x0dfa, 0xa07c, 0x931a, 0xa080, 0x9213, 0x0804, 0x1e20, 0xa08c,
-	0x931a, 0xa090, 0x9213, 0x0804, 0x1e20, 0xa09c, 0x931a, 0xa0a0,
-	0x9213, 0x0804, 0x1e20, 0xa0ac, 0x931a, 0xa0b0, 0x9213, 0x0804,
-	0x1e20, 0xa0bc, 0x931a, 0xa0c0, 0x9213, 0x0804, 0x1e20, 0xa0cc,
-	0x931a, 0xa0d0, 0x9213, 0x0804, 0x1e20, 0xa0dc, 0x931a, 0xa0e0,
-	0x9213, 0x0804, 0x1e20, 0x2c05, 0x908a, 0x0034, 0x1a0c, 0x0dfa,
-	0x9082, 0x001b, 0x0002, 0x1f0e, 0x1f0c, 0x1f0c, 0x1f0c, 0x1f0c,
-	0x1f0c, 0x1f14, 0x1f0c, 0x1f0c, 0x1f0c, 0x1f0c, 0x1f0c, 0x1f1a,
-	0x1f0c, 0x1f0c, 0x1f0c, 0x1f0c, 0x1f0c, 0x1f20, 0x1f0c, 0x1f0c,
-	0x1f0c, 0x1f0c, 0x1f0c, 0x1f26, 0x080c, 0x0dfa, 0xa07c, 0x931a,
-	0xa080, 0x9213, 0x0804, 0x1e20, 0xa094, 0x931a, 0xa098, 0x9213,
-	0x0804, 0x1e20, 0xa0ac, 0x931a, 0xa0b0, 0x9213, 0x0804, 0x1e20,
-	0xa0c4, 0x931a, 0xa0c8, 0x9213, 0x0804, 0x1e20, 0xa0dc, 0x931a,
-	0xa0e0, 0x9213, 0x0804, 0x1e20, 0x0804, 0x1e1c, 0x080c, 0x0dfa,
-	0x012e, 0x0005, 0x00f6, 0x00e6, 0x2071, 0x1a3d, 0x7000, 0x9086,
-	0x0000, 0x0904, 0x1f7b, 0x2079, 0x0090, 0x2009, 0x0207, 0x210c,
-	0xd194, 0x01b8, 0x2009, 0x020c, 0x210c, 0x9184, 0x0003, 0x0188,
-	0x080c, 0xdc34, 0x2001, 0x0133, 0x2004, 0x9005, 0x090c, 0x0dfa,
-	0x0016, 0x2009, 0x0040, 0x080c, 0x230a, 0x001e, 0x2001, 0x020c,
-	0x2102, 0x2009, 0x0206, 0x2104, 0x2009, 0x0203, 0x210c, 0x9106,
-	0x1120, 0x2009, 0x0040, 0x080c, 0x230a, 0x782c, 0xd0fc, 0x09a8,
-	0x080c, 0x1dec, 0x7000, 0x9086, 0x0000, 0x1978, 0x782b, 0x0004,
-	0x782c, 0xd0ac, 0x1de8, 0x2009, 0x0040, 0x080c, 0x230a, 0x782b,
-	0x0002, 0x7003, 0x0000, 0x080c, 0x1c02, 0x00ee, 0x00fe, 0x0005,
-	0xa880, 0xd0fc, 0x11a8, 0x8c60, 0x2c05, 0x9005, 0x0110, 0x8a51,
-	0x0005, 0xa004, 0x9005, 0x0168, 0xa85a, 0x2040, 0xa064, 0x9084,
-	0x000f, 0x9080, 0x1fc8, 0x2065, 0x8cff, 0x090c, 0x0dfa, 0x8a51,
-	0x0005, 0x2050, 0x0005, 0xa880, 0xd0fc, 0x11b8, 0x8a50, 0x8c61,
-	0x2c05, 0x9005, 0x1190, 0x2800, 0x9906, 0x0120, 0xa000, 0x9005,
-	0x1108, 0x2900, 0x2040, 0xa85a, 0xa064, 0x9084, 0x000f, 0x9080,
-	0x1fd8, 0x2065, 0x8cff, 0x090c, 0x0dfa, 0x0005, 0x0000, 0x001d,
-	0x0021, 0x0025, 0x0029, 0x002d, 0x0031, 0x0035, 0x0000, 0x001b,
-	0x0021, 0x0027, 0x002d, 0x0033, 0x0000, 0x0000, 0x0023, 0x0000,
-	0x0000, 0x1fbb, 0x1fb7, 0x0000, 0x0000, 0x1fc5, 0x0000, 0x1fbb,
-	0x1fc2, 0x1fc2, 0x1fbf, 0x0000, 0x0000, 0x0000, 0x1fc5, 0x1fc2,
-	0x0000, 0x1fbd, 0x1fbd, 0x0000, 0x0000, 0x1fc5, 0x0000, 0x1fbd,
-	0x1fc3, 0x1fc3, 0x1fc3, 0x0000, 0x0000, 0x0000, 0x1fc5, 0x1fc3,
-	0x00c6, 0x00d6, 0x0086, 0xab42, 0xac3e, 0xa888, 0x9055, 0x0904,
-	0x21c7, 0x2940, 0xa064, 0x90ec, 0x000f, 0x9084, 0x00ff, 0x9086,
-	0x0008, 0x1118, 0x2061, 0x1fc3, 0x00d0, 0x9de0, 0x1fc8, 0x9d86,
-	0x0007, 0x0130, 0x9d86, 0x000e, 0x0118, 0x9d86, 0x000f, 0x1120,
-	0xa08c, 0x9422, 0xa090, 0x931b, 0x2c05, 0x9065, 0x1140, 0x0310,
-	0x0804, 0x21c7, 0xa004, 0x9045, 0x0904, 0x21c7, 0x08d8, 0x2c05,
-	0x9005, 0x0904, 0x20af, 0xdd9c, 0x1904, 0x206b, 0x908a, 0x0036,
-	0x1a0c, 0x0dfa, 0x9082, 0x001b, 0x0002, 0x2040, 0x2040, 0x2042,
-	0x2040, 0x2040, 0x2040, 0x2048, 0x2040, 0x2040, 0x2040, 0x204e,
-	0x2040, 0x2040, 0x2040, 0x2054, 0x2040, 0x2040, 0x2040, 0x205a,
-	0x2040, 0x2040, 0x2040, 0x2060, 0x2040, 0x2040, 0x2040, 0x2066,
-	0x080c, 0x0dfa, 0xa07c, 0x9422, 0xa080, 0x931b, 0x0804, 0x20a5,
-	0xa08c, 0x9422, 0xa090, 0x931b, 0x0804, 0x20a5, 0xa09c, 0x9422,
-	0xa0a0, 0x931b, 0x0804, 0x20a5, 0xa0ac, 0x9422, 0xa0b0, 0x931b,
-	0x0804, 0x20a5, 0xa0bc, 0x9422, 0xa0c0, 0x931b, 0x0804, 0x20a5,
-	0xa0cc, 0x9422, 0xa0d0, 0x931b, 0x0804, 0x20a5, 0xa0dc, 0x9422,
-	0xa0e0, 0x931b, 0x04d0, 0x908a, 0x0034, 0x1a0c, 0x0dfa, 0x9082,
-	0x001b, 0x0002, 0x208d, 0x208b, 0x208b, 0x208b, 0x208b, 0x208b,
-	0x2092, 0x208b, 0x208b, 0x208b, 0x208b, 0x208b, 0x2097, 0x208b,
-	0x208b, 0x208b, 0x208b, 0x208b, 0x209c, 0x208b, 0x208b, 0x208b,
-	0x208b, 0x208b, 0x20a1, 0x080c, 0x0dfa, 0xa07c, 0x9422, 0xa080,
-	0x931b, 0x0098, 0xa094, 0x9422, 0xa098, 0x931b, 0x0070, 0xa0ac,
-	0x9422, 0xa0b0, 0x931b, 0x0048, 0xa0c4, 0x9422, 0xa0c8, 0x931b,
-	0x0020, 0xa0dc, 0x9422, 0xa0e0, 0x931b, 0x0630, 0x2300, 0x9405,
-	0x0160, 0x8a51, 0x0904, 0x21c7, 0x8c60, 0x0804, 0x2017, 0xa004,
-	0x9045, 0x0904, 0x21c7, 0x0804, 0x1ff2, 0x8a51, 0x0904, 0x21c7,
-	0x8c60, 0x2c05, 0x9005, 0x1158, 0xa004, 0x9045, 0x0904, 0x21c7,
-	0xa064, 0x90ec, 0x000f, 0x9de0, 0x1fc8, 0x2c05, 0x2060, 0xa880,
-	0xc0fc, 0xa882, 0x0804, 0x21bc, 0x2c05, 0x8422, 0x8420, 0x831a,
-	0x9399, 0x0000, 0xac2e, 0xab32, 0xdd9c, 0x1904, 0x2159, 0x9082,
-	0x001b, 0x0002, 0x20f5, 0x20f5, 0x20f7, 0x20f5, 0x20f5, 0x20f5,
-	0x2105, 0x20f5, 0x20f5, 0x20f5, 0x2113, 0x20f5, 0x20f5, 0x20f5,
-	0x2121, 0x20f5, 0x20f5, 0x20f5, 0x212f, 0x20f5, 0x20f5, 0x20f5,
-	0x213d, 0x20f5, 0x20f5, 0x20f5, 0x214b, 0x080c, 0x0dfa, 0xa17c,
-	0x2400, 0x9122, 0xa180, 0x2300, 0x911b, 0x0a0c, 0x0dfa, 0xa074,
-	0x9420, 0xa078, 0x9319, 0x0804, 0x21b7, 0xa18c, 0x2400, 0x9122,
-	0xa190, 0x2300, 0x911b, 0x0a0c, 0x0dfa, 0xa084, 0x9420, 0xa088,
-	0x9319, 0x0804, 0x21b7, 0xa19c, 0x2400, 0x9122, 0xa1a0, 0x2300,
-	0x911b, 0x0a0c, 0x0dfa, 0xa094, 0x9420, 0xa098, 0x9319, 0x0804,
-	0x21b7, 0xa1ac, 0x2400, 0x9122, 0xa1b0, 0x2300, 0x911b, 0x0a0c,
-	0x0dfa, 0xa0a4, 0x9420, 0xa0a8, 0x9319, 0x0804, 0x21b7, 0xa1bc,
-	0x2400, 0x9122, 0xa1c0, 0x2300, 0x911b, 0x0a0c, 0x0dfa, 0xa0b4,
-	0x9420, 0xa0b8, 0x9319, 0x0804, 0x21b7, 0xa1cc, 0x2400, 0x9122,
-	0xa1d0, 0x2300, 0x911b, 0x0a0c, 0x0dfa, 0xa0c4, 0x9420, 0xa0c8,
-	0x9319, 0x0804, 0x21b7, 0xa1dc, 0x2400, 0x9122, 0xa1e0, 0x2300,
-	0x911b, 0x0a0c, 0x0dfa, 0xa0d4, 0x9420, 0xa0d8, 0x9319, 0x0804,
-	0x21b7, 0x9082, 0x001b, 0x0002, 0x2177, 0x2175, 0x2175, 0x2175,
-	0x2175, 0x2175, 0x2184, 0x2175, 0x2175, 0x2175, 0x2175, 0x2175,
-	0x2191, 0x2175, 0x2175, 0x2175, 0x2175, 0x2175, 0x219e, 0x2175,
-	0x2175, 0x2175, 0x2175, 0x2175, 0x21ab, 0x080c, 0x0dfa, 0xa17c,
-	0x2400, 0x9122, 0xa180, 0x2300, 0x911b, 0x0a0c, 0x0dfa, 0xa06c,
-	0x9420, 0xa070, 0x9319, 0x0498, 0xa194, 0x2400, 0x9122, 0xa198,
-	0x2300, 0x911b, 0x0a0c, 0x0dfa, 0xa084, 0x9420, 0xa088, 0x9319,
-	0x0430, 0xa1ac, 0x2400, 0x9122, 0xa1b0, 0x2300, 0x911b, 0x0a0c,
-	0x0dfa, 0xa09c, 0x9420, 0xa0a0, 0x9319, 0x00c8, 0xa1c4, 0x2400,
-	0x9122, 0xa1c8, 0x2300, 0x911b, 0x0a0c, 0x0dfa, 0xa0b4, 0x9420,
-	0xa0b8, 0x9319, 0x0060, 0xa1dc, 0x2400, 0x9122, 0xa1e0, 0x2300,
-	0x911b, 0x0a0c, 0x0dfa, 0xa0cc, 0x9420, 0xa0d0, 0x9319, 0xac1e,
-	0xab22, 0xa880, 0xc0fd, 0xa882, 0x2800, 0xa85a, 0x2c00, 0xa812,
-	0x2a00, 0xa816, 0x000e, 0x000e, 0x000e, 0x9006, 0x0028, 0x008e,
-	0x00de, 0x00ce, 0x9085, 0x0001, 0x0005, 0x2001, 0x0005, 0x2004,
-	0xd0bc, 0x190c, 0x0df3, 0x9084, 0x0007, 0x0002, 0x21e8, 0x1dec,
-	0x21e8, 0x21de, 0x21e1, 0x21e4, 0x21e1, 0x21e4, 0x080c, 0x1dec,
-	0x0005, 0x080c, 0x11e8, 0x0005, 0x080c, 0x1dec, 0x080c, 0x11e8,
-	0x0005, 0x0126, 0x2091, 0x2600, 0x2079, 0x0200, 0x2071, 0x0260,
-	0x2069, 0x1800, 0x7817, 0x0000, 0x789b, 0x0814, 0x78a3, 0x0406,
-	0x789f, 0x0410, 0x2009, 0x013b, 0x200b, 0x0400, 0x781b, 0x0002,
-	0x783b, 0x001f, 0x7837, 0x0020, 0x7803, 0x1600, 0x012e, 0x0005,
-	0x2091, 0x2600, 0x781c, 0xd0a4, 0x190c, 0x2307, 0x7900, 0xd1dc,
-	0x1118, 0x9084, 0x0006, 0x001a, 0x9084, 0x000e, 0x0002, 0x222f,
-	0x2227, 0x7bb4, 0x2227, 0x2229, 0x2229, 0x2229, 0x2229, 0x7b9a,
-	0x2227, 0x222b, 0x2227, 0x2229, 0x2227, 0x2229, 0x2227, 0x080c,
-	0x0dfa, 0x0031, 0x0020, 0x080c, 0x7b9a, 0x080c, 0x7bb4, 0x0005,
-	0x0006, 0x0016, 0x0026, 0x080c, 0xdc34, 0x7930, 0x9184, 0x0003,
-	0x01c0, 0x2001, 0x19ce, 0x2004, 0x9005, 0x0170, 0x2001, 0x0133,
-	0x2004, 0x9005, 0x090c, 0x0dfa, 0x00c6, 0x2001, 0x19ce, 0x2064,
-	0x080c, 0xba56, 0x00ce, 0x00f8, 0x2009, 0x0040, 0x080c, 0x230a,
-	0x00d0, 0x9184, 0x0014, 0x01a0, 0x6a00, 0x9286, 0x0003, 0x0160,
-	0x080c, 0x7207, 0x1138, 0x080c, 0x7504, 0x080c, 0x5f2b, 0x080c,
-	0x7127, 0x0010, 0x080c, 0x5dea, 0x080c, 0x7c63, 0x0041, 0x0018,
-	0x9184, 0x9540, 0x1dc8, 0x002e, 0x001e, 0x000e, 0x0005, 0x00e6,
-	0x0036, 0x0046, 0x0056, 0x2071, 0x1a3a, 0x080c, 0x19ff, 0x005e,
-	0x004e, 0x003e, 0x00ee, 0x0005, 0x0126, 0x2091, 0x2e00, 0x2071,
-	0x1800, 0x7128, 0x2001, 0x1947, 0x2102, 0x2001, 0x194f, 0x2102,
-	0x2001, 0x013b, 0x2102, 0x2079, 0x0200, 0x2001, 0x0201, 0x789e,
-	0x78a3, 0x0200, 0x9198, 0x0007, 0x831c, 0x831c, 0x831c, 0x9398,
-	0x0005, 0x2320, 0x9182, 0x0204, 0x1230, 0x2011, 0x0008, 0x8423,
-	0x8423, 0x8423, 0x0488, 0x9182, 0x024c, 0x1240, 0x2011, 0x0007,
-	0x8403, 0x8003, 0x9400, 0x9400, 0x9420, 0x0430, 0x9182, 0x02bc,
-	0x1238, 0x2011, 0x0006, 0x8403, 0x8003, 0x9400, 0x9420, 0x00e0,
-	0x9182, 0x034c, 0x1230, 0x2011, 0x0005, 0x8403, 0x8003, 0x9420,
-	0x0098, 0x9182, 0x042c, 0x1228, 0x2011, 0x0004, 0x8423, 0x8423,
-	0x0058, 0x9182, 0x059c, 0x1228, 0x2011, 0x0003, 0x8403, 0x9420,
-	0x0018, 0x2011, 0x0002, 0x8423, 0x9482, 0x0228, 0x8002, 0x8020,
-	0x8301, 0x9402, 0x0110, 0x0208, 0x8321, 0x8217, 0x8203, 0x9405,
-	0x789a, 0x012e, 0x0005, 0x0006, 0x00d6, 0x2069, 0x0200, 0x6814,
-	0x9084, 0xffc0, 0x910d, 0x6916, 0x00de, 0x000e, 0x0005, 0x00d6,
-	0x2069, 0x0200, 0x9005, 0x6810, 0x0110, 0xc0a5, 0x0008, 0xc0a4,
-	0x6812, 0x00de, 0x0005, 0x0006, 0x00d6, 0x2069, 0x0200, 0x6810,
-	0x9084, 0xfff8, 0x910d, 0x6912, 0x00de, 0x000e, 0x0005, 0x7938,
-	0x080c, 0x0df3, 0x00f6, 0x2079, 0x0200, 0x7902, 0xa001, 0xa001,
-	0xa001, 0xa001, 0xa001, 0xa001, 0x7902, 0xa001, 0xa001, 0xa001,
-	0xa001, 0xa001, 0xa001, 0x00fe, 0x0005, 0x0126, 0x2091, 0x2800,
-	0x2061, 0x0100, 0x2071, 0x1800, 0x2009, 0x0000, 0x080c, 0x2bb6,
-	0x080c, 0x2a89, 0x2001, 0x0100, 0x2004, 0x9086, 0x000a, 0x0558,
-	0x6054, 0x8004, 0x8004, 0x8004, 0x8004, 0x9084, 0x000c, 0x6150,
-	0x918c, 0xfff3, 0x9105, 0x6052, 0x6050, 0x9084, 0xb17f, 0x9085,
-	0x2000, 0x6052, 0x2009, 0x1975, 0x2011, 0x1976, 0x6358, 0x939c,
-	0x38f0, 0x2320, 0x080c, 0x2af6, 0x1238, 0x939d, 0x4003, 0x94a5,
-	0x8603, 0x230a, 0x2412, 0x0030, 0x939d, 0x0203, 0x94a5, 0x8603,
-	0x230a, 0x2412, 0x0050, 0x2001, 0x1975, 0x2003, 0x0700, 0x2001,
-	0x1976, 0x2003, 0x0700, 0x080c, 0x2cc2, 0x9006, 0x080c, 0x2ab8,
-	0x9006, 0x080c, 0x2a9b, 0x20a9, 0x0012, 0x1d04, 0x236d, 0x2091,
-	0x6000, 0x1f04, 0x236d, 0x602f, 0x0100, 0x602f, 0x0000, 0x6050,
-	0x9085, 0x0400, 0x9084, 0xdfff, 0x6052, 0x6024, 0x6026, 0x080c,
-	0x27a7, 0x2009, 0x00ef, 0x6132, 0x6136, 0x080c, 0x27b7, 0x60e7,
-	0x0000, 0x61ea, 0x60e3, 0x0002, 0x604b, 0xf7f7, 0x6043, 0x0000,
-	0x602f, 0x0080, 0x602f, 0x0000, 0x6007, 0x149f, 0x60bb, 0x0000,
-	0x20a9, 0x0018, 0x60bf, 0x0000, 0x1f04, 0x239a, 0x60bb, 0x0000,
-	0x60bf, 0x0108, 0x60bf, 0x0012, 0x60bf, 0x0320, 0x60bf, 0x0018,
-	0x601b, 0x00f0, 0x601f, 0x001e, 0x600f, 0x006b, 0x602b, 0x402f,
-	0x012e, 0x0005, 0x00f6, 0x2079, 0x0140, 0x78c3, 0x0080, 0x78c3,
-	0x0083, 0x78c3, 0x0000, 0x00fe, 0x0005, 0x2001, 0x1834, 0x2003,
-	0x0000, 0x2001, 0x1833, 0x2003, 0x0001, 0x0005, 0x0126, 0x2091,
-	0x2800, 0x0006, 0x0016, 0x0026, 0x6124, 0x9184, 0x5e2c, 0x1118,
-	0x9184, 0x0007, 0x002a, 0x9195, 0x0004, 0x9284, 0x0007, 0x0002,
-	0x23fa, 0x23e0, 0x23e3, 0x23e6, 0x23eb, 0x23ed, 0x23f1, 0x23f5,
-	0x080c, 0x8563, 0x00b8, 0x080c, 0x8632, 0x00a0, 0x080c, 0x8632,
-	0x080c, 0x8563, 0x0078, 0x0099, 0x0068, 0x080c, 0x8563, 0x0079,
-	0x0048, 0x080c, 0x8632, 0x0059, 0x0028, 0x080c, 0x8632, 0x080c,
-	0x8563, 0x0029, 0x002e, 0x001e, 0x000e, 0x012e, 0x0005, 0x00a6,
-	0x6124, 0x6028, 0xd09c, 0x0118, 0xd19c, 0x1904, 0x2648, 0xd1f4,
-	0x190c, 0x0df3, 0x080c, 0x7207, 0x0904, 0x2455, 0x080c, 0xc539,
-	0x1120, 0x7000, 0x9086, 0x0003, 0x0570, 0x6024, 0x9084, 0x1800,
-	0x0550, 0x080c, 0x722a, 0x0118, 0x080c, 0x7218, 0x1520, 0x6027,
-	0x0020, 0x6043, 0x0000, 0x080c, 0xc539, 0x0168, 0x080c, 0x722a,
-	0x1150, 0x2001, 0x197f, 0x2003, 0x0001, 0x6027, 0x1800, 0x080c,
-	0x7076, 0x0804, 0x264b, 0x70a0, 0x9005, 0x1150, 0x70a3, 0x0001,
-	0x00d6, 0x2069, 0x0140, 0x080c, 0x725e, 0x00de, 0x1904, 0x264b,
-	0x080c, 0x750e, 0x0428, 0x080c, 0x722a, 0x1590, 0x6024, 0x9084,
-	0x1800, 0x1108, 0x0468, 0x080c, 0x750e, 0x080c, 0x7504, 0x080c,
-	0x5f2b, 0x080c, 0x7127, 0x0804, 0x2648, 0xd1ac, 0x1508, 0x6024,
-	0xd0dc, 0x1170, 0xd0e4, 0x1178, 0xd0d4, 0x1190, 0xd0cc, 0x0130,
-	0x7094, 0x9086, 0x0028, 0x1110, 0x080c, 0x73f3, 0x0804, 0x2648,
-	0x080c, 0x7509, 0x0048, 0x2001, 0x1955, 0x2003, 0x0002, 0x0020,
-	0x080c, 0x7359, 0x0804, 0x2648, 0x080c, 0x748d, 0x0804, 0x2648,
-	0xd1ac, 0x0904, 0x2569, 0x080c, 0x7207, 0x11c0, 0x6027, 0x0020,
-	0x0006, 0x0026, 0x0036, 0x080c, 0x7221, 0x1158, 0x080c, 0x7504,
-	0x080c, 0x5f2b, 0x080c, 0x7127, 0x003e, 0x002e, 0x000e, 0x00ae,
-	0x0005, 0x003e, 0x002e, 0x000e, 0x080c, 0x71df, 0x0016, 0x0046,
-	0x00c6, 0x644c, 0x9486, 0xf0f0, 0x1138, 0x2061, 0x0100, 0x644a,
-	0x6043, 0x0090, 0x6043, 0x0010, 0x74d6, 0x948c, 0xff00, 0x7038,
-	0xd084, 0x0178, 0x9186, 0xf800, 0x1160, 0x7044, 0xd084, 0x1148,
-	0xc085, 0x7046, 0x0036, 0x2418, 0x2011, 0x8016, 0x080c, 0x4b1f,
-	0x003e, 0x080c, 0xc532, 0x1904, 0x2546, 0x9196, 0xff00, 0x05a8,
-	0x705c, 0x9084, 0x00ff, 0x810f, 0x81ff, 0x0110, 0x9116, 0x0568,
-	0x7130, 0xd184, 0x1550, 0x080c, 0x32e4, 0x0128, 0xc18d, 0x7132,
-	0x080c, 0x67bb, 0x1510, 0x6240, 0x9294, 0x0010, 0x0130, 0x6248,
-	0x9294, 0xff00, 0x9296, 0xff00, 0x01c0, 0x7030, 0xd08c, 0x0904,
-	0x2546, 0x7038, 0xd08c, 0x1140, 0x2001, 0x180c, 0x200c, 0xd1ac,
-	0x1904, 0x2546, 0xc1ad, 0x2102, 0x0036, 0x73d4, 0x2011, 0x8013,
-	0x080c, 0x4b1f, 0x003e, 0x0804, 0x2546, 0x7038, 0xd08c, 0x1140,
-	0x2001, 0x180c, 0x200c, 0xd1ac, 0x1904, 0x2546, 0xc1ad, 0x2102,
-	0x0036, 0x73d4, 0x2011, 0x8013, 0x080c, 0x4b1f, 0x003e, 0x7130,
-	0xc185, 0x7132, 0x2011, 0x185c, 0x220c, 0x00f0, 0x0016, 0x2009,
-	0x0001, 0x2011, 0x0100, 0x080c, 0x84d1, 0x2019, 0x000e, 0x00c6,
-	0x2061, 0x0000, 0x080c, 0xd801, 0x00ce, 0x9484, 0x00ff, 0x9080,
-	0x32e9, 0x200d, 0x918c, 0xff00, 0x810f, 0x2120, 0x9006, 0x2009,
-	0x000e, 0x080c, 0xd885, 0x001e, 0xd1ac, 0x1148, 0x0016, 0x2009,
-	0x0002, 0x2019, 0x0004, 0x080c, 0x3156, 0x001e, 0x0078, 0x0156,
-	0x00b6, 0x20a9, 0x007f, 0x900e, 0x080c, 0x649f, 0x1110, 0x080c,
-	0x5f45, 0x8108, 0x1f04, 0x253c, 0x00be, 0x015e, 0x00ce, 0x004e,
-	0x080c, 0xa069, 0x60e3, 0x0000, 0x001e, 0x2001, 0x1800, 0x2014,
+	0x60c8, 0xa896, 0x7004, 0x2060, 0x00c6, 0x080c, 0xb974, 0x00ce,
+	0x2001, 0x19d1, 0x2004, 0x9c06, 0x1160, 0x2009, 0x0040, 0x080c,
+	0x2204, 0x080c, 0x9a7a, 0x2011, 0x0000, 0x080c, 0x9918, 0x080c,
+	0x8c6d, 0x002e, 0x0804, 0x1e32, 0x0126, 0x2091, 0x2400, 0xa858,
+	0x2040, 0x792c, 0x782b, 0x0002, 0x9184, 0x0700, 0x1904, 0x1cc5,
+	0x7000, 0x0002, 0x1e32, 0x1d16, 0x1d83, 0x1e30, 0x8001, 0x7002,
+	0xd19c, 0x1150, 0x8aff, 0x05b0, 0x080c, 0x1b75, 0x0904, 0x1e32,
+	0x080c, 0x1b75, 0x0804, 0x1e32, 0x782b, 0x0004, 0xd194, 0x0148,
+	0xa880, 0xc0fc, 0xa882, 0x8aff, 0x11d8, 0xa87c, 0xc0f5, 0xa87e,
+	0x00b8, 0x0026, 0x0036, 0xab3c, 0xaa40, 0x7810, 0xa82e, 0x931a,
+	0x7814, 0xa832, 0x9213, 0x7800, 0xa81e, 0x7804, 0xa822, 0xab3e,
+	0xaa42, 0x003e, 0x002e, 0x080c, 0x1e98, 0xa880, 0xc0fd, 0xa882,
+	0x2a00, 0xa816, 0x2800, 0xa85a, 0x2c00, 0xa812, 0x7003, 0x0000,
+	0x0804, 0x1e32, 0x00f6, 0x0026, 0x781c, 0x0006, 0x7818, 0x0006,
+	0x2079, 0x0100, 0x7a14, 0x9284, 0x1984, 0x9085, 0x0012, 0x7816,
+	0x0036, 0x2019, 0x1000, 0x8319, 0x090c, 0x0e02, 0x7820, 0xd0bc,
+	0x1dd0, 0x003e, 0x79c8, 0x000e, 0x9102, 0x001e, 0x0006, 0x0016,
+	0x79c4, 0x000e, 0x9103, 0x78c6, 0x000e, 0x78ca, 0x9284, 0x1984,
+	0x9085, 0x0012, 0x7816, 0x002e, 0x00fe, 0x782b, 0x0008, 0x7003,
+	0x0000, 0x0804, 0x1e32, 0x8001, 0x7002, 0xd194, 0x0170, 0x782c,
+	0xd0fc, 0x1904, 0x1d09, 0xd19c, 0x1904, 0x1e2e, 0x8aff, 0x0904,
+	0x1e32, 0x080c, 0x1b75, 0x0804, 0x1e32, 0x0026, 0x0036, 0xab3c,
+	0xaa40, 0x080c, 0x1e98, 0xdd9c, 0x1904, 0x1ded, 0x2c05, 0x908a,
+	0x0036, 0x1a0c, 0x0e02, 0x9082, 0x001b, 0x0002, 0x1dc1, 0x1dc1,
+	0x1dc3, 0x1dc1, 0x1dc1, 0x1dc1, 0x1dc9, 0x1dc1, 0x1dc1, 0x1dc1,
+	0x1dcf, 0x1dc1, 0x1dc1, 0x1dc1, 0x1dd5, 0x1dc1, 0x1dc1, 0x1dc1,
+	0x1ddb, 0x1dc1, 0x1dc1, 0x1dc1, 0x1de1, 0x1dc1, 0x1dc1, 0x1dc1,
+	0x1de7, 0x080c, 0x0e02, 0xa07c, 0x931a, 0xa080, 0x9213, 0x0804,
+	0x1d35, 0xa08c, 0x931a, 0xa090, 0x9213, 0x0804, 0x1d35, 0xa09c,
+	0x931a, 0xa0a0, 0x9213, 0x0804, 0x1d35, 0xa0ac, 0x931a, 0xa0b0,
+	0x9213, 0x0804, 0x1d35, 0xa0bc, 0x931a, 0xa0c0, 0x9213, 0x0804,
+	0x1d35, 0xa0cc, 0x931a, 0xa0d0, 0x9213, 0x0804, 0x1d35, 0xa0dc,
+	0x931a, 0xa0e0, 0x9213, 0x0804, 0x1d35, 0x2c05, 0x908a, 0x0034,
+	0x1a0c, 0x0e02, 0x9082, 0x001b, 0x0002, 0x1e10, 0x1e0e, 0x1e0e,
+	0x1e0e, 0x1e0e, 0x1e0e, 0x1e16, 0x1e0e, 0x1e0e, 0x1e0e, 0x1e0e,
+	0x1e0e, 0x1e1c, 0x1e0e, 0x1e0e, 0x1e0e, 0x1e0e, 0x1e0e, 0x1e22,
+	0x1e0e, 0x1e0e, 0x1e0e, 0x1e0e, 0x1e0e, 0x1e28, 0x080c, 0x0e02,
+	0xa07c, 0x931a, 0xa080, 0x9213, 0x0804, 0x1d35, 0xa094, 0x931a,
+	0xa098, 0x9213, 0x0804, 0x1d35, 0xa0ac, 0x931a, 0xa0b0, 0x9213,
+	0x0804, 0x1d35, 0xa0c4, 0x931a, 0xa0c8, 0x9213, 0x0804, 0x1d35,
+	0xa0dc, 0x931a, 0xa0e0, 0x9213, 0x0804, 0x1d35, 0x0804, 0x1d31,
+	0x080c, 0x0e02, 0x012e, 0x0005, 0x00f6, 0x00e6, 0x2071, 0x1a42,
+	0x7000, 0x9086, 0x0000, 0x0904, 0x1e7d, 0x2079, 0x0090, 0x2009,
+	0x0207, 0x210c, 0xd194, 0x01b8, 0x2009, 0x020c, 0x210c, 0x9184,
+	0x0003, 0x0188, 0x080c, 0xdb9b, 0x2001, 0x0133, 0x2004, 0x9005,
+	0x090c, 0x0e02, 0x0016, 0x2009, 0x0040, 0x080c, 0x2204, 0x001e,
+	0x2001, 0x020c, 0x2102, 0x2009, 0x0206, 0x2104, 0x2009, 0x0203,
+	0x210c, 0x9106, 0x1120, 0x2009, 0x0040, 0x080c, 0x2204, 0x782c,
+	0xd0fc, 0x09a8, 0x080c, 0x1d04, 0x7000, 0x9086, 0x0000, 0x1978,
+	0x782b, 0x0004, 0x782c, 0xd0ac, 0x1de8, 0x2009, 0x0040, 0x080c,
+	0x2204, 0x782b, 0x0002, 0x7003, 0x0000, 0x00ee, 0x00fe, 0x0005,
+	0x8c60, 0x2c05, 0x9005, 0x0110, 0x8a51, 0x0005, 0xa004, 0x9005,
+	0x0168, 0xa85a, 0x2040, 0xa064, 0x9084, 0x000f, 0x9080, 0x1ec2,
+	0x2065, 0x8cff, 0x090c, 0x0e02, 0x8a51, 0x0005, 0x2050, 0x0005,
+	0x8a50, 0x8c61, 0x2c05, 0x9005, 0x1190, 0x2800, 0x9906, 0x0120,
+	0xa000, 0x9005, 0x1108, 0x2900, 0x2040, 0xa85a, 0xa064, 0x9084,
+	0x000f, 0x9080, 0x1ed2, 0x2065, 0x8cff, 0x090c, 0x0e02, 0x0005,
+	0x0000, 0x001d, 0x0021, 0x0025, 0x0029, 0x002d, 0x0031, 0x0035,
+	0x0000, 0x001b, 0x0021, 0x0027, 0x002d, 0x0033, 0x0000, 0x0000,
+	0x0023, 0x0000, 0x0000, 0x1eb5, 0x1eb1, 0x0000, 0x0000, 0x1ebf,
+	0x0000, 0x1eb5, 0x1ebc, 0x1ebc, 0x1eb9, 0x0000, 0x0000, 0x0000,
+	0x1ebf, 0x1ebc, 0x0000, 0x1eb7, 0x1eb7, 0x0000, 0x0000, 0x1ebf,
+	0x0000, 0x1eb7, 0x1ebd, 0x1ebd, 0x1ebd, 0x0000, 0x0000, 0x0000,
+	0x1ebf, 0x1ebd, 0x00c6, 0x00d6, 0x0086, 0xab42, 0xac3e, 0xa888,
+	0x9055, 0x0904, 0x20c1, 0x2940, 0xa064, 0x90ec, 0x000f, 0x9084,
+	0x00ff, 0x9086, 0x0008, 0x1118, 0x2061, 0x1ebd, 0x00d0, 0x9de0,
+	0x1ec2, 0x9d86, 0x0007, 0x0130, 0x9d86, 0x000e, 0x0118, 0x9d86,
+	0x000f, 0x1120, 0xa08c, 0x9422, 0xa090, 0x931b, 0x2c05, 0x9065,
+	0x1140, 0x0310, 0x0804, 0x20c1, 0xa004, 0x9045, 0x0904, 0x20c1,
+	0x08d8, 0x2c05, 0x9005, 0x0904, 0x1fa9, 0xdd9c, 0x1904, 0x1f65,
+	0x908a, 0x0036, 0x1a0c, 0x0e02, 0x9082, 0x001b, 0x0002, 0x1f3a,
+	0x1f3a, 0x1f3c, 0x1f3a, 0x1f3a, 0x1f3a, 0x1f42, 0x1f3a, 0x1f3a,
+	0x1f3a, 0x1f48, 0x1f3a, 0x1f3a, 0x1f3a, 0x1f4e, 0x1f3a, 0x1f3a,
+	0x1f3a, 0x1f54, 0x1f3a, 0x1f3a, 0x1f3a, 0x1f5a, 0x1f3a, 0x1f3a,
+	0x1f3a, 0x1f60, 0x080c, 0x0e02, 0xa07c, 0x9422, 0xa080, 0x931b,
+	0x0804, 0x1f9f, 0xa08c, 0x9422, 0xa090, 0x931b, 0x0804, 0x1f9f,
+	0xa09c, 0x9422, 0xa0a0, 0x931b, 0x0804, 0x1f9f, 0xa0ac, 0x9422,
+	0xa0b0, 0x931b, 0x0804, 0x1f9f, 0xa0bc, 0x9422, 0xa0c0, 0x931b,
+	0x0804, 0x1f9f, 0xa0cc, 0x9422, 0xa0d0, 0x931b, 0x0804, 0x1f9f,
+	0xa0dc, 0x9422, 0xa0e0, 0x931b, 0x04d0, 0x908a, 0x0034, 0x1a0c,
+	0x0e02, 0x9082, 0x001b, 0x0002, 0x1f87, 0x1f85, 0x1f85, 0x1f85,
+	0x1f85, 0x1f85, 0x1f8c, 0x1f85, 0x1f85, 0x1f85, 0x1f85, 0x1f85,
+	0x1f91, 0x1f85, 0x1f85, 0x1f85, 0x1f85, 0x1f85, 0x1f96, 0x1f85,
+	0x1f85, 0x1f85, 0x1f85, 0x1f85, 0x1f9b, 0x080c, 0x0e02, 0xa07c,
+	0x9422, 0xa080, 0x931b, 0x0098, 0xa094, 0x9422, 0xa098, 0x931b,
+	0x0070, 0xa0ac, 0x9422, 0xa0b0, 0x931b, 0x0048, 0xa0c4, 0x9422,
+	0xa0c8, 0x931b, 0x0020, 0xa0dc, 0x9422, 0xa0e0, 0x931b, 0x0630,
+	0x2300, 0x9405, 0x0160, 0x8a51, 0x0904, 0x20c1, 0x8c60, 0x0804,
+	0x1f11, 0xa004, 0x9045, 0x0904, 0x20c1, 0x0804, 0x1eec, 0x8a51,
+	0x0904, 0x20c1, 0x8c60, 0x2c05, 0x9005, 0x1158, 0xa004, 0x9045,
+	0x0904, 0x20c1, 0xa064, 0x90ec, 0x000f, 0x9de0, 0x1ec2, 0x2c05,
+	0x2060, 0xa880, 0xc0fc, 0xa882, 0x0804, 0x20b6, 0x2c05, 0x8422,
+	0x8420, 0x831a, 0x9399, 0x0000, 0xac2e, 0xab32, 0xdd9c, 0x1904,
+	0x2053, 0x9082, 0x001b, 0x0002, 0x1fef, 0x1fef, 0x1ff1, 0x1fef,
+	0x1fef, 0x1fef, 0x1fff, 0x1fef, 0x1fef, 0x1fef, 0x200d, 0x1fef,
+	0x1fef, 0x1fef, 0x201b, 0x1fef, 0x1fef, 0x1fef, 0x2029, 0x1fef,
+	0x1fef, 0x1fef, 0x2037, 0x1fef, 0x1fef, 0x1fef, 0x2045, 0x080c,
+	0x0e02, 0xa17c, 0x2400, 0x9122, 0xa180, 0x2300, 0x911b, 0x0a0c,
+	0x0e02, 0xa074, 0x9420, 0xa078, 0x9319, 0x0804, 0x20b1, 0xa18c,
+	0x2400, 0x9122, 0xa190, 0x2300, 0x911b, 0x0a0c, 0x0e02, 0xa084,
+	0x9420, 0xa088, 0x9319, 0x0804, 0x20b1, 0xa19c, 0x2400, 0x9122,
+	0xa1a0, 0x2300, 0x911b, 0x0a0c, 0x0e02, 0xa094, 0x9420, 0xa098,
+	0x9319, 0x0804, 0x20b1, 0xa1ac, 0x2400, 0x9122, 0xa1b0, 0x2300,
+	0x911b, 0x0a0c, 0x0e02, 0xa0a4, 0x9420, 0xa0a8, 0x9319, 0x0804,
+	0x20b1, 0xa1bc, 0x2400, 0x9122, 0xa1c0, 0x2300, 0x911b, 0x0a0c,
+	0x0e02, 0xa0b4, 0x9420, 0xa0b8, 0x9319, 0x0804, 0x20b1, 0xa1cc,
+	0x2400, 0x9122, 0xa1d0, 0x2300, 0x911b, 0x0a0c, 0x0e02, 0xa0c4,
+	0x9420, 0xa0c8, 0x9319, 0x0804, 0x20b1, 0xa1dc, 0x2400, 0x9122,
+	0xa1e0, 0x2300, 0x911b, 0x0a0c, 0x0e02, 0xa0d4, 0x9420, 0xa0d8,
+	0x9319, 0x0804, 0x20b1, 0x9082, 0x001b, 0x0002, 0x2071, 0x206f,
+	0x206f, 0x206f, 0x206f, 0x206f, 0x207e, 0x206f, 0x206f, 0x206f,
+	0x206f, 0x206f, 0x208b, 0x206f, 0x206f, 0x206f, 0x206f, 0x206f,
+	0x2098, 0x206f, 0x206f, 0x206f, 0x206f, 0x206f, 0x20a5, 0x080c,
+	0x0e02, 0xa17c, 0x2400, 0x9122, 0xa180, 0x2300, 0x911b, 0x0a0c,
+	0x0e02, 0xa06c, 0x9420, 0xa070, 0x9319, 0x0498, 0xa194, 0x2400,
+	0x9122, 0xa198, 0x2300, 0x911b, 0x0a0c, 0x0e02, 0xa084, 0x9420,
+	0xa088, 0x9319, 0x0430, 0xa1ac, 0x2400, 0x9122, 0xa1b0, 0x2300,
+	0x911b, 0x0a0c, 0x0e02, 0xa09c, 0x9420, 0xa0a0, 0x9319, 0x00c8,
+	0xa1c4, 0x2400, 0x9122, 0xa1c8, 0x2300, 0x911b, 0x0a0c, 0x0e02,
+	0xa0b4, 0x9420, 0xa0b8, 0x9319, 0x0060, 0xa1dc, 0x2400, 0x9122,
+	0xa1e0, 0x2300, 0x911b, 0x0a0c, 0x0e02, 0xa0cc, 0x9420, 0xa0d0,
+	0x9319, 0xac1e, 0xab22, 0xa880, 0xc0fd, 0xa882, 0x2800, 0xa85a,
+	0x2c00, 0xa812, 0x2a00, 0xa816, 0x000e, 0x000e, 0x000e, 0x9006,
+	0x0028, 0x008e, 0x00de, 0x00ce, 0x9085, 0x0001, 0x0005, 0x2001,
+	0x0005, 0x2004, 0xd0bc, 0x190c, 0x0dfb, 0x9084, 0x0007, 0x0002,
+	0x20e2, 0x1d04, 0x20e2, 0x20d8, 0x20db, 0x20de, 0x20db, 0x20de,
+	0x080c, 0x1d04, 0x0005, 0x080c, 0x11fa, 0x0005, 0x080c, 0x1d04,
+	0x080c, 0x11fa, 0x0005, 0x0126, 0x2091, 0x2600, 0x2079, 0x0200,
+	0x2071, 0x0260, 0x2069, 0x1800, 0x7817, 0x0000, 0x789b, 0x0814,
+	0x78a3, 0x0406, 0x789f, 0x0410, 0x2009, 0x013b, 0x200b, 0x0400,
+	0x781b, 0x0002, 0x783b, 0x001f, 0x7837, 0x0020, 0x7803, 0x1600,
+	0x012e, 0x0005, 0x2091, 0x2600, 0x781c, 0xd0a4, 0x190c, 0x2201,
+	0x7900, 0xd1dc, 0x1118, 0x9084, 0x0006, 0x001a, 0x9084, 0x000e,
+	0x0002, 0x2129, 0x2121, 0x7b34, 0x2121, 0x2123, 0x2123, 0x2123,
+	0x2123, 0x7b1a, 0x2121, 0x2125, 0x2121, 0x2123, 0x2121, 0x2123,
+	0x2121, 0x080c, 0x0e02, 0x0031, 0x0020, 0x080c, 0x7b1a, 0x080c,
+	0x7b34, 0x0005, 0x0006, 0x0016, 0x0026, 0x080c, 0xdb9b, 0x7930,
+	0x9184, 0x0003, 0x01c0, 0x2001, 0x19d1, 0x2004, 0x9005, 0x0170,
+	0x2001, 0x0133, 0x2004, 0x9005, 0x090c, 0x0e02, 0x00c6, 0x2001,
+	0x19d1, 0x2064, 0x080c, 0xb974, 0x00ce, 0x00f8, 0x2009, 0x0040,
+	0x080c, 0x2204, 0x00d0, 0x9184, 0x0014, 0x01a0, 0x6a00, 0x9286,
+	0x0003, 0x0160, 0x080c, 0x717f, 0x1138, 0x080c, 0x747b, 0x080c,
+	0x5e30, 0x080c, 0x709f, 0x0010, 0x080c, 0x5cef, 0x080c, 0x7be3,
+	0x0041, 0x0018, 0x9184, 0x9540, 0x1dc8, 0x002e, 0x001e, 0x000e,
+	0x0005, 0x00e6, 0x0036, 0x0046, 0x0056, 0x2071, 0x1a3f, 0x080c,
+	0x1983, 0x005e, 0x004e, 0x003e, 0x00ee, 0x0005, 0x0126, 0x2091,
+	0x2e00, 0x2071, 0x1800, 0x7128, 0x2001, 0x1949, 0x2102, 0x2001,
+	0x1951, 0x2102, 0x2001, 0x013b, 0x2102, 0x2079, 0x0200, 0x2001,
+	0x0201, 0x789e, 0x78a3, 0x0200, 0x9198, 0x0007, 0x831c, 0x831c,
+	0x831c, 0x9398, 0x0005, 0x2320, 0x9182, 0x0204, 0x1230, 0x2011,
+	0x0008, 0x8423, 0x8423, 0x8423, 0x0488, 0x9182, 0x024c, 0x1240,
+	0x2011, 0x0007, 0x8403, 0x8003, 0x9400, 0x9400, 0x9420, 0x0430,
+	0x9182, 0x02bc, 0x1238, 0x2011, 0x0006, 0x8403, 0x8003, 0x9400,
+	0x9420, 0x00e0, 0x9182, 0x034c, 0x1230, 0x2011, 0x0005, 0x8403,
+	0x8003, 0x9420, 0x0098, 0x9182, 0x042c, 0x1228, 0x2011, 0x0004,
+	0x8423, 0x8423, 0x0058, 0x9182, 0x059c, 0x1228, 0x2011, 0x0003,
+	0x8403, 0x9420, 0x0018, 0x2011, 0x0002, 0x8423, 0x9482, 0x0228,
+	0x8002, 0x8020, 0x8301, 0x9402, 0x0110, 0x0208, 0x8321, 0x8217,
+	0x8203, 0x9405, 0x789a, 0x012e, 0x0005, 0x0006, 0x00d6, 0x2069,
+	0x0200, 0x6814, 0x9084, 0xffc0, 0x910d, 0x6916, 0x00de, 0x000e,
+	0x0005, 0x00d6, 0x2069, 0x0200, 0x9005, 0x6810, 0x0110, 0xc0a5,
+	0x0008, 0xc0a4, 0x6812, 0x00de, 0x0005, 0x0006, 0x00d6, 0x2069,
+	0x0200, 0x6810, 0x9084, 0xfff8, 0x910d, 0x6912, 0x00de, 0x000e,
+	0x0005, 0x7938, 0x080c, 0x0dfb, 0x00f6, 0x2079, 0x0200, 0x7902,
+	0xa001, 0xa001, 0xa001, 0xa001, 0xa001, 0xa001, 0x7902, 0xa001,
+	0xa001, 0xa001, 0xa001, 0xa001, 0xa001, 0x00fe, 0x0005, 0x0126,
+	0x2091, 0x2800, 0x2061, 0x0100, 0x2071, 0x1800, 0x2009, 0x0000,
+	0x080c, 0x2ab6, 0x080c, 0x2989, 0x2001, 0x0100, 0x2004, 0x9086,
+	0x000a, 0x0558, 0x6054, 0x8004, 0x8004, 0x8004, 0x8004, 0x9084,
+	0x000c, 0x6150, 0x918c, 0xfff3, 0x9105, 0x6052, 0x6050, 0x9084,
+	0xb17f, 0x9085, 0x2000, 0x6052, 0x2009, 0x1977, 0x2011, 0x1978,
+	0x6358, 0x939c, 0x38f0, 0x2320, 0x080c, 0x29f6, 0x1238, 0x939d,
+	0x4003, 0x94a5, 0x8603, 0x230a, 0x2412, 0x0030, 0x939d, 0x0203,
+	0x94a5, 0x8603, 0x230a, 0x2412, 0x0050, 0x2001, 0x1977, 0x2003,
+	0x0700, 0x2001, 0x1978, 0x2003, 0x0700, 0x080c, 0x2bc2, 0x9006,
+	0x080c, 0x29b8, 0x9006, 0x080c, 0x299b, 0x20a9, 0x0012, 0x1d04,
+	0x2267, 0x2091, 0x6000, 0x1f04, 0x2267, 0x602f, 0x0100, 0x602f,
+	0x0000, 0x6050, 0x9085, 0x0400, 0x9084, 0xdfff, 0x6052, 0x6024,
+	0x6026, 0x080c, 0x26a7, 0x2009, 0x00ef, 0x6132, 0x6136, 0x080c,
+	0x26b7, 0x60e7, 0x0000, 0x61ea, 0x60e3, 0x0002, 0x604b, 0xf7f7,
+	0x6043, 0x0000, 0x602f, 0x0080, 0x602f, 0x0000, 0x6007, 0x149f,
+	0x60bb, 0x0000, 0x20a9, 0x0018, 0x60bf, 0x0000, 0x1f04, 0x2294,
+	0x60bb, 0x0000, 0x60bf, 0x0108, 0x60bf, 0x0012, 0x60bf, 0x0320,
+	0x60bf, 0x0018, 0x601b, 0x00f0, 0x601f, 0x001e, 0x600f, 0x006b,
+	0x602b, 0x402f, 0x012e, 0x0005, 0x00f6, 0x2079, 0x0140, 0x78c3,
+	0x0080, 0x78c3, 0x0083, 0x78c3, 0x0000, 0x00fe, 0x0005, 0x2001,
+	0x1834, 0x2003, 0x0000, 0x2001, 0x1833, 0x2003, 0x0001, 0x0005,
+	0x0126, 0x2091, 0x2800, 0x0006, 0x0016, 0x0026, 0x6124, 0x9184,
+	0x5e2c, 0x1118, 0x9184, 0x0007, 0x002a, 0x9195, 0x0004, 0x9284,
+	0x0007, 0x0002, 0x22f4, 0x22da, 0x22dd, 0x22e0, 0x22e5, 0x22e7,
+	0x22eb, 0x22ef, 0x080c, 0x84e3, 0x00b8, 0x080c, 0x85b2, 0x00a0,
+	0x080c, 0x85b2, 0x080c, 0x84e3, 0x0078, 0x0099, 0x0068, 0x080c,
+	0x84e3, 0x0079, 0x0048, 0x080c, 0x85b2, 0x0059, 0x0028, 0x080c,
+	0x85b2, 0x080c, 0x84e3, 0x0029, 0x002e, 0x001e, 0x000e, 0x012e,
+	0x0005, 0x00a6, 0x6124, 0x6028, 0xd09c, 0x0118, 0xd19c, 0x1904,
+	0x2548, 0xd1f4, 0x190c, 0x0dfb, 0x080c, 0x717f, 0x0904, 0x234f,
+	0x080c, 0xc444, 0x1120, 0x7000, 0x9086, 0x0003, 0x0570, 0x6024,
+	0x9084, 0x1800, 0x0550, 0x080c, 0x71a2, 0x0118, 0x080c, 0x7190,
+	0x1520, 0x6027, 0x0020, 0x6043, 0x0000, 0x080c, 0xc444, 0x0168,
+	0x080c, 0x71a2, 0x1150, 0x2001, 0x1981, 0x2003, 0x0001, 0x6027,
+	0x1800, 0x080c, 0x6fee, 0x0804, 0x254b, 0x70a0, 0x9005, 0x1150,
+	0x70a3, 0x0001, 0x00d6, 0x2069, 0x0140, 0x080c, 0x71d3, 0x00de,
+	0x1904, 0x254b, 0x080c, 0x7485, 0x0428, 0x080c, 0x71a2, 0x1590,
+	0x6024, 0x9084, 0x1800, 0x1108, 0x0468, 0x080c, 0x7485, 0x080c,
+	0x747b, 0x080c, 0x5e30, 0x080c, 0x709f, 0x0804, 0x2548, 0xd1ac,
+	0x1508, 0x6024, 0xd0dc, 0x1170, 0xd0e4, 0x1178, 0xd0d4, 0x1190,
+	0xd0cc, 0x0130, 0x7094, 0x9086, 0x0029, 0x1110, 0x080c, 0x736a,
+	0x0804, 0x2548, 0x080c, 0x7480, 0x0048, 0x2001, 0x1957, 0x2003,
+	0x0002, 0x0020, 0x080c, 0x72ce, 0x0804, 0x2548, 0x080c, 0x7404,
+	0x0804, 0x2548, 0xd1ac, 0x0904, 0x2469, 0x080c, 0x717f, 0x11c0,
+	0x6027, 0x0020, 0x0006, 0x0026, 0x0036, 0x080c, 0x7199, 0x1158,
+	0x080c, 0x747b, 0x080c, 0x5e30, 0x080c, 0x709f, 0x003e, 0x002e,
+	0x000e, 0x00ae, 0x0005, 0x003e, 0x002e, 0x000e, 0x080c, 0x7157,
+	0x0016, 0x0046, 0x00c6, 0x644c, 0x9486, 0xf0f0, 0x1138, 0x2061,
+	0x0100, 0x644a, 0x6043, 0x0090, 0x6043, 0x0010, 0x74d6, 0x948c,
+	0xff00, 0x7038, 0xd084, 0x0178, 0x9186, 0xf800, 0x1160, 0x7044,
+	0xd084, 0x1148, 0xc085, 0x7046, 0x0036, 0x2418, 0x2011, 0x8016,
+	0x080c, 0x4a18, 0x003e, 0x080c, 0xc43d, 0x1904, 0x2446, 0x9196,
+	0xff00, 0x05a8, 0x705c, 0x9084, 0x00ff, 0x810f, 0x81ff, 0x0110,
+	0x9116, 0x0568, 0x7130, 0xd184, 0x1550, 0x080c, 0x3204, 0x0128,
+	0xc18d, 0x7132, 0x080c, 0x66c2, 0x1510, 0x6240, 0x9294, 0x0010,
+	0x0130, 0x6248, 0x9294, 0xff00, 0x9296, 0xff00, 0x01c0, 0x7030,
+	0xd08c, 0x0904, 0x2446, 0x7038, 0xd08c, 0x1140, 0x2001, 0x180c,
+	0x200c, 0xd1ac, 0x1904, 0x2446, 0xc1ad, 0x2102, 0x0036, 0x73d4,
+	0x2011, 0x8013, 0x080c, 0x4a18, 0x003e, 0x0804, 0x2446, 0x7038,
+	0xd08c, 0x1140, 0x2001, 0x180c, 0x200c, 0xd1ac, 0x1904, 0x2446,
+	0xc1ad, 0x2102, 0x0036, 0x73d4, 0x2011, 0x8013, 0x080c, 0x4a18,
+	0x003e, 0x7130, 0xc185, 0x7132, 0x2011, 0x185c, 0x220c, 0x00f0,
+	0x0016, 0x2009, 0x0001, 0x2011, 0x0100, 0x080c, 0x8451, 0x2019,
+	0x000e, 0x00c6, 0x2061, 0x0000, 0x080c, 0xd74e, 0x00ce, 0x9484,
+	0x00ff, 0x9080, 0x3209, 0x200d, 0x918c, 0xff00, 0x810f, 0x2120,
+	0x9006, 0x2009, 0x000e, 0x080c, 0xd7d6, 0x001e, 0xd1ac, 0x1148,
+	0x0016, 0x2009, 0x0002, 0x2019, 0x0004, 0x080c, 0x3076, 0x001e,
+	0x00a8, 0x0156, 0x00b6, 0x20a9, 0x007f, 0x900e, 0x080c, 0x63a4,
+	0x1140, 0x7030, 0xd084, 0x1118, 0xb800, 0xd0bc, 0x1110, 0x080c,
+	0x5e4a, 0x8108, 0x1f04, 0x2436, 0x00be, 0x015e, 0x00ce, 0x004e,
+	0x080c, 0x9f5b, 0x60e3, 0x0000, 0x001e, 0x2001, 0x1800, 0x2014,
 	0x9296, 0x0004, 0x1170, 0xd19c, 0x11a0, 0x2011, 0x180c, 0x2214,
 	0xd29c, 0x1120, 0x6204, 0x9295, 0x0002, 0x6206, 0x6228, 0xc29d,
 	0x622a, 0x2003, 0x0001, 0x2001, 0x1825, 0x2003, 0x0000, 0x6027,
-	0x0020, 0xd194, 0x0904, 0x2648, 0x0016, 0x6220, 0xd2b4, 0x0904,
-	0x25f1, 0x080c, 0x835a, 0x080c, 0x9656, 0x6027, 0x0004, 0x00f6,
-	0x2019, 0x19c8, 0x2304, 0x907d, 0x0904, 0x25c0, 0x7804, 0x9086,
+	0x0020, 0xd194, 0x0904, 0x2548, 0x0016, 0x6220, 0xd2b4, 0x0904,
+	0x24f1, 0x080c, 0x82da, 0x080c, 0x9605, 0x6027, 0x0004, 0x00f6,
+	0x2019, 0x19cb, 0x2304, 0x907d, 0x0904, 0x24c0, 0x7804, 0x9086,
 	0x0032, 0x15f0, 0x00d6, 0x00c6, 0x00e6, 0x0096, 0x2069, 0x0140,
 	0x782c, 0x685e, 0x7808, 0x685a, 0x6043, 0x0002, 0x2001, 0x0003,
 	0x8001, 0x1df0, 0x6043, 0x0000, 0x2001, 0x003c, 0x8001, 0x1df0,
-	0x080c, 0x2c98, 0x2001, 0x001e, 0x8001, 0x0240, 0x20a9, 0x0009,
-	0x080c, 0x2b91, 0x6904, 0xd1dc, 0x1140, 0x0cb0, 0x2001, 0x0100,
-	0x080c, 0x2c88, 0x9006, 0x080c, 0x2c88, 0x080c, 0x8b04, 0x080c,
-	0x8c10, 0x7814, 0x2048, 0xa867, 0x0103, 0x2f60, 0x080c, 0xa0e3,
+	0x080c, 0x2b98, 0x2001, 0x001e, 0x8001, 0x0240, 0x20a9, 0x0009,
+	0x080c, 0x2a91, 0x6904, 0xd1dc, 0x1140, 0x0cb0, 0x2001, 0x0100,
+	0x080c, 0x2b88, 0x9006, 0x080c, 0x2b88, 0x080c, 0x8a84, 0x080c,
+	0x8b90, 0x7814, 0x2048, 0xa867, 0x0103, 0x2f60, 0x080c, 0x9fd5,
 	0x009e, 0x00ee, 0x00ce, 0x00de, 0x00fe, 0x001e, 0x00ae, 0x0005,
 	0x00fe, 0x00d6, 0x2069, 0x0140, 0x6804, 0x9084, 0x4000, 0x0110,
-	0x080c, 0x2c98, 0x00de, 0x00c6, 0x2061, 0x19bf, 0x6028, 0x080c,
-	0xc539, 0x0120, 0x909a, 0x0003, 0x1258, 0x0018, 0x909a, 0x00c8,
-	0x1238, 0x8000, 0x602a, 0x00ce, 0x080c, 0x9632, 0x0804, 0x2647,
-	0x2061, 0x0100, 0x62c0, 0x080c, 0x9eef, 0x2019, 0x19c8, 0x2304,
-	0x9065, 0x0120, 0x2009, 0x0027, 0x080c, 0xa15d, 0x00ce, 0x0804,
-	0x2647, 0xd2bc, 0x0904, 0x2634, 0x080c, 0x8367, 0x6014, 0x9084,
+	0x080c, 0x2b98, 0x00de, 0x00c6, 0x2061, 0x19c2, 0x6028, 0x080c,
+	0xc444, 0x0120, 0x909a, 0x0003, 0x1258, 0x0018, 0x909a, 0x00c8,
+	0x1238, 0x8000, 0x602a, 0x00ce, 0x080c, 0x95e1, 0x0804, 0x2547,
+	0x2061, 0x0100, 0x62c0, 0x080c, 0x9de1, 0x2019, 0x19cb, 0x2304,
+	0x9065, 0x0120, 0x2009, 0x0027, 0x080c, 0xa053, 0x00ce, 0x0804,
+	0x2547, 0xd2bc, 0x0904, 0x2534, 0x080c, 0x82e7, 0x6014, 0x9084,
 	0x1984, 0x9085, 0x0010, 0x6016, 0x6027, 0x0004, 0x00d6, 0x2069,
-	0x0140, 0x6804, 0x9084, 0x4000, 0x0110, 0x080c, 0x2c98, 0x00de,
-	0x00c6, 0x2061, 0x19bf, 0x6044, 0x080c, 0xc539, 0x0120, 0x909a,
+	0x0140, 0x6804, 0x9084, 0x4000, 0x0110, 0x080c, 0x2b98, 0x00de,
+	0x00c6, 0x2061, 0x19c2, 0x6044, 0x080c, 0xc444, 0x0120, 0x909a,
 	0x0003, 0x1628, 0x0018, 0x909a, 0x00c8, 0x1608, 0x8000, 0x6046,
-	0x603c, 0x00ce, 0x9005, 0x0558, 0x2009, 0x07d0, 0x080c, 0x835f,
+	0x603c, 0x00ce, 0x9005, 0x0558, 0x2009, 0x07d0, 0x080c, 0x82df,
 	0x9080, 0x0008, 0x2004, 0x9086, 0x0006, 0x1138, 0x6114, 0x918c,
 	0x1984, 0x918d, 0x0012, 0x6116, 0x00d0, 0x6114, 0x918c, 0x1984,
 	0x918d, 0x0016, 0x6116, 0x0098, 0x6027, 0x0004, 0x0080, 0x0036,
-	0x2019, 0x0001, 0x080c, 0x999d, 0x003e, 0x2019, 0x19ce, 0x2304,
-	0x9065, 0x0120, 0x2009, 0x004f, 0x080c, 0xa15d, 0x00ce, 0x001e,
-	0xd19c, 0x0904, 0x2712, 0x7038, 0xd0ac, 0x1904, 0x26e7, 0x0016,
+	0x2019, 0x0001, 0x080c, 0x989c, 0x003e, 0x2019, 0x19d1, 0x2304,
+	0x9065, 0x0120, 0x2009, 0x004f, 0x080c, 0xa053, 0x00ce, 0x001e,
+	0xd19c, 0x0904, 0x2612, 0x7038, 0xd0ac, 0x1904, 0x25e7, 0x0016,
 	0x0156, 0x6027, 0x0008, 0x2001, 0x0100, 0x2004, 0x9086, 0x000a,
-	0x0904, 0x26c4, 0x6050, 0x9085, 0x0040, 0x6052, 0x6050, 0x9084,
-	0xfbcf, 0x6052, 0x080c, 0x2bb0, 0x9085, 0x2000, 0x6052, 0x20a9,
-	0x0012, 0x1d04, 0x2669, 0x080c, 0x838e, 0x1f04, 0x2669, 0x6050,
+	0x0904, 0x25c4, 0x6050, 0x9085, 0x0040, 0x6052, 0x6050, 0x9084,
+	0xfbcf, 0x6052, 0x080c, 0x2ab0, 0x9085, 0x2000, 0x6052, 0x20a9,
+	0x0012, 0x1d04, 0x2569, 0x080c, 0x830e, 0x1f04, 0x2569, 0x6050,
 	0x9085, 0x0400, 0x9084, 0xdfbf, 0x6052, 0x20a9, 0x0028, 0xa001,
-	0x1f04, 0x2677, 0x6150, 0x9185, 0x1400, 0x6052, 0x20a9, 0x0366,
-	0x1d04, 0x2680, 0x080c, 0x838e, 0x6020, 0xd09c, 0x1138, 0x015e,
-	0x6152, 0x001e, 0x6027, 0x0008, 0x0804, 0x2712, 0x080c, 0x2b78,
-	0x1f04, 0x2680, 0x015e, 0x6152, 0x001e, 0x6027, 0x0008, 0x0016,
-	0x6028, 0xc09c, 0x602a, 0x080c, 0xa069, 0x60e3, 0x0000, 0x080c,
-	0xdc13, 0x080c, 0xdc2e, 0x080c, 0x55df, 0xd0fc, 0x1138, 0x080c,
-	0xc532, 0x1120, 0x9085, 0x0001, 0x080c, 0x724e, 0x9006, 0x080c,
-	0x2c88, 0x2009, 0x0002, 0x080c, 0x2bb6, 0x00e6, 0x2071, 0x1800,
-	0x7003, 0x0004, 0x080c, 0x0ec6, 0x00ee, 0x6027, 0x0008, 0x080c,
-	0x0b8f, 0x001e, 0x0804, 0x2712, 0x080c, 0x2cc2, 0x080c, 0x2cf5,
-	0x6050, 0xc0e5, 0x6052, 0x20a9, 0x0367, 0x1f04, 0x26e5, 0x1d04,
-	0x26cf, 0x080c, 0x838e, 0x6020, 0xd09c, 0x1db8, 0x00f6, 0x2079,
-	0x0100, 0x080c, 0x2b06, 0x00fe, 0x1d80, 0x6050, 0xc0e4, 0x6052,
+	0x1f04, 0x2577, 0x6150, 0x9185, 0x1400, 0x6052, 0x20a9, 0x0366,
+	0x1d04, 0x2580, 0x080c, 0x830e, 0x6020, 0xd09c, 0x1138, 0x015e,
+	0x6152, 0x001e, 0x6027, 0x0008, 0x0804, 0x2612, 0x080c, 0x2a78,
+	0x1f04, 0x2580, 0x015e, 0x6152, 0x001e, 0x6027, 0x0008, 0x0016,
+	0x6028, 0xc09c, 0x602a, 0x080c, 0x9f5b, 0x60e3, 0x0000, 0x080c,
+	0xdb7a, 0x080c, 0xdb95, 0x080c, 0x54e0, 0xd0fc, 0x1138, 0x080c,
+	0xc43d, 0x1120, 0x9085, 0x0001, 0x080c, 0x71c3, 0x9006, 0x080c,
+	0x2b88, 0x2009, 0x0002, 0x080c, 0x2ab6, 0x00e6, 0x2071, 0x1800,
+	0x7003, 0x0004, 0x080c, 0x0ed8, 0x00ee, 0x6027, 0x0008, 0x080c,
+	0x0b8f, 0x001e, 0x0804, 0x2612, 0x080c, 0x2bc2, 0x080c, 0x2bf5,
+	0x6050, 0xc0e5, 0x6052, 0x20a9, 0x0367, 0x1f04, 0x25e5, 0x1d04,
+	0x25cf, 0x080c, 0x830e, 0x6020, 0xd09c, 0x1db8, 0x00f6, 0x2079,
+	0x0100, 0x080c, 0x2a06, 0x00fe, 0x1d80, 0x6050, 0xc0e4, 0x6052,
 	0x6027, 0x0008, 0x015e, 0x001e, 0x0468, 0x015e, 0x001e, 0x0016,
-	0x6028, 0xc09c, 0x602a, 0x080c, 0xa069, 0x60e3, 0x0000, 0x080c,
-	0xdc13, 0x080c, 0xdc2e, 0x080c, 0x55df, 0xd0fc, 0x1138, 0x080c,
-	0xc532, 0x1120, 0x9085, 0x0001, 0x080c, 0x724e, 0x9006, 0x080c,
-	0x2c88, 0x2009, 0x0002, 0x080c, 0x2bb6, 0x00e6, 0x2071, 0x1800,
-	0x7003, 0x0004, 0x080c, 0x0ec6, 0x00ee, 0x6027, 0x0008, 0x080c,
+	0x6028, 0xc09c, 0x602a, 0x080c, 0x9f5b, 0x60e3, 0x0000, 0x080c,
+	0xdb7a, 0x080c, 0xdb95, 0x080c, 0x54e0, 0xd0fc, 0x1138, 0x080c,
+	0xc43d, 0x1120, 0x9085, 0x0001, 0x080c, 0x71c3, 0x9006, 0x080c,
+	0x2b88, 0x2009, 0x0002, 0x080c, 0x2ab6, 0x00e6, 0x2071, 0x1800,
+	0x7003, 0x0004, 0x080c, 0x0ed8, 0x00ee, 0x6027, 0x0008, 0x080c,
 	0x0b8f, 0x001e, 0x918c, 0xffd0, 0x6126, 0x00ae, 0x0005, 0x0006,
 	0x0016, 0x0026, 0x0036, 0x00e6, 0x00f6, 0x0126, 0x2091, 0x8000,
-	0x2071, 0x1800, 0x71cc, 0x70ce, 0x9116, 0x0904, 0x2766, 0x81ff,
-	0x01a0, 0x2009, 0x0000, 0x080c, 0x2bb6, 0x2011, 0x8011, 0x2019,
+	0x2071, 0x1800, 0x71cc, 0x70ce, 0x9116, 0x0904, 0x2666, 0x81ff,
+	0x01a0, 0x2009, 0x0000, 0x080c, 0x2ab6, 0x2011, 0x8011, 0x2019,
 	0x010e, 0x231c, 0x939e, 0x0007, 0x1118, 0x2019, 0x0001, 0x0010,
-	0x2019, 0x0000, 0x080c, 0x4b1f, 0x0448, 0x2001, 0x1980, 0x200c,
+	0x2019, 0x0000, 0x080c, 0x4a18, 0x0448, 0x2001, 0x1982, 0x200c,
 	0x81ff, 0x1140, 0x2001, 0x0109, 0x2004, 0xd0b4, 0x0118, 0x2019,
-	0x0003, 0x0008, 0x2118, 0x2011, 0x8012, 0x080c, 0x4b1f, 0x080c,
-	0x0ec6, 0x080c, 0x55df, 0xd0fc, 0x1188, 0x080c, 0xc532, 0x1170,
-	0x00c6, 0x080c, 0x2802, 0x080c, 0x9904, 0x2061, 0x0100, 0x2019,
-	0x0028, 0x2009, 0x0002, 0x080c, 0x3156, 0x00ce, 0x012e, 0x00fe,
+	0x0003, 0x0008, 0x2118, 0x2011, 0x8012, 0x080c, 0x4a18, 0x080c,
+	0x0ed8, 0x080c, 0x54e0, 0xd0fc, 0x1188, 0x080c, 0xc43d, 0x1170,
+	0x00c6, 0x080c, 0x2702, 0x080c, 0x9803, 0x2061, 0x0100, 0x2019,
+	0x0028, 0x2009, 0x0002, 0x080c, 0x3076, 0x00ce, 0x012e, 0x00fe,
 	0x00ee, 0x003e, 0x002e, 0x001e, 0x000e, 0x0005, 0x2028, 0x918c,
 	0x00ff, 0x2130, 0x9094, 0xff00, 0x11f0, 0x2011, 0x1836, 0x2214,
 	0xd2ac, 0x11c8, 0x81ff, 0x01e8, 0x2011, 0x181e, 0x2204, 0x9106,
 	0x1190, 0x2011, 0x181f, 0x2214, 0x9294, 0xff00, 0x9584, 0xff00,
 	0x9206, 0x1148, 0x2011, 0x181f, 0x2214, 0x9294, 0x00ff, 0x9584,
-	0x00ff, 0x9206, 0x1120, 0x2500, 0x080c, 0x7ec0, 0x0048, 0x9584,
-	0x00ff, 0x9080, 0x32e9, 0x200d, 0x918c, 0xff00, 0x810f, 0x9006,
-	0x0005, 0x9080, 0x32e9, 0x200d, 0x918c, 0x00ff, 0x0005, 0x00d6,
+	0x00ff, 0x9206, 0x1120, 0x2500, 0x080c, 0x7e40, 0x0048, 0x9584,
+	0x00ff, 0x9080, 0x3209, 0x200d, 0x918c, 0xff00, 0x810f, 0x9006,
+	0x0005, 0x9080, 0x3209, 0x200d, 0x918c, 0x00ff, 0x0005, 0x00d6,
 	0x2069, 0x0140, 0x2001, 0x1817, 0x2003, 0x00ef, 0x20a9, 0x0010,
-	0x9006, 0x6852, 0x6856, 0x1f04, 0x27b2, 0x00de, 0x0005, 0x0006,
+	0x9006, 0x6852, 0x6856, 0x1f04, 0x26b2, 0x00de, 0x0005, 0x0006,
 	0x00d6, 0x0026, 0x2069, 0x0140, 0x2001, 0x1817, 0x2102, 0x8114,
 	0x8214, 0x8214, 0x8214, 0x20a9, 0x0010, 0x6853, 0x0000, 0x9006,
-	0x82ff, 0x1128, 0x9184, 0x000f, 0x9080, 0xe568, 0x2005, 0x6856,
-	0x8211, 0x1f04, 0x27c7, 0x002e, 0x00de, 0x000e, 0x0005, 0x00c6,
+	0x82ff, 0x1128, 0x9184, 0x000f, 0x9080, 0xe345, 0x2005, 0x6856,
+	0x8211, 0x1f04, 0x26c7, 0x002e, 0x00de, 0x000e, 0x0005, 0x00c6,
 	0x2061, 0x1800, 0x6030, 0x0110, 0xc09d, 0x0008, 0xc09c, 0x6032,
 	0x00ce, 0x0005, 0x0156, 0x00d6, 0x0026, 0x0016, 0x0006, 0x2069,
 	0x0140, 0x6980, 0x9116, 0x0180, 0x9112, 0x1230, 0x8212, 0x8210,
 	0x22a8, 0x2001, 0x0402, 0x0018, 0x22a8, 0x2001, 0x0404, 0x680e,
-	0x1f04, 0x27f7, 0x680f, 0x0000, 0x000e, 0x001e, 0x002e, 0x00de,
-	0x015e, 0x0005, 0x080c, 0x55db, 0xd0c4, 0x0150, 0xd0a4, 0x0140,
-	0x9006, 0x0046, 0x2020, 0x2009, 0x002e, 0x080c, 0xd885, 0x004e,
+	0x1f04, 0x26f7, 0x680f, 0x0000, 0x000e, 0x001e, 0x002e, 0x00de,
+	0x015e, 0x0005, 0x080c, 0x54dc, 0xd0c4, 0x0150, 0xd0a4, 0x0140,
+	0x9006, 0x0046, 0x2020, 0x2009, 0x002e, 0x080c, 0xd7d6, 0x004e,
 	0x0005, 0x00f6, 0x0016, 0x0026, 0x2079, 0x0140, 0x78c4, 0xd0dc,
-	0x0904, 0x286e, 0x080c, 0x2af6, 0x0660, 0x9084, 0x0700, 0x908e,
+	0x0904, 0x276e, 0x080c, 0x29f6, 0x0660, 0x9084, 0x0700, 0x908e,
 	0x0600, 0x1120, 0x2011, 0x4000, 0x900e, 0x0458, 0x908e, 0x0500,
 	0x1120, 0x2011, 0x8000, 0x900e, 0x0420, 0x908e, 0x0400, 0x1120,
 	0x9016, 0x2009, 0x0001, 0x00e8, 0x908e, 0x0300, 0x1120, 0x9016,
 	0x2009, 0x0002, 0x00b0, 0x908e, 0x0200, 0x1120, 0x9016, 0x2009,
 	0x0004, 0x0078, 0x908e, 0x0100, 0x1548, 0x9016, 0x2009, 0x0008,
 	0x0040, 0x9084, 0x0700, 0x908e, 0x0300, 0x1500, 0x2011, 0x0030,
-	0x0058, 0x2300, 0x9080, 0x0020, 0x2018, 0x080c, 0x84ff, 0x928c,
+	0x0058, 0x2300, 0x9080, 0x0020, 0x2018, 0x080c, 0x847f, 0x928c,
 	0xff00, 0x0110, 0x2011, 0x00ff, 0x2200, 0x8007, 0x9085, 0x004c,
-	0x78c2, 0x2009, 0x0138, 0x220a, 0x080c, 0x7207, 0x1118, 0x2009,
-	0x1945, 0x220a, 0x002e, 0x001e, 0x00fe, 0x0005, 0x78c3, 0x0000,
+	0x78c2, 0x2009, 0x0138, 0x220a, 0x080c, 0x717f, 0x1118, 0x2009,
+	0x1947, 0x220a, 0x002e, 0x001e, 0x00fe, 0x0005, 0x78c3, 0x0000,
 	0x0cc8, 0x0126, 0x2091, 0x2800, 0x0006, 0x0016, 0x0026, 0x2001,
 	0x0170, 0x200c, 0x8000, 0x2014, 0x9184, 0x0003, 0x0110, 0x080c,
-	0x0df3, 0x002e, 0x001e, 0x000e, 0x012e, 0x0005, 0x2001, 0x0171,
+	0x0dfb, 0x002e, 0x001e, 0x000e, 0x012e, 0x0005, 0x2001, 0x0171,
 	0x2004, 0xd0dc, 0x0168, 0x2001, 0x0170, 0x200c, 0x918c, 0x00ff,
 	0x918e, 0x004c, 0x1128, 0x200c, 0x918c, 0xff00, 0x810f, 0x0005,
 	0x900e, 0x2001, 0x0227, 0x2004, 0x8007, 0x9084, 0x00ff, 0x8004,
 	0x9108, 0x2001, 0x0226, 0x2004, 0x8007, 0x9084, 0x00ff, 0x8004,
 	0x9108, 0x0005, 0x0018, 0x000c, 0x0018, 0x0020, 0x1000, 0x0800,
 	0x1000, 0x1800, 0x0156, 0x0006, 0x0016, 0x0026, 0x00e6, 0x2001,
-	0x1968, 0x2004, 0x908a, 0x0007, 0x1a0c, 0x0dfa, 0x0033, 0x00ee,
-	0x002e, 0x001e, 0x000e, 0x015e, 0x0005, 0x28cc, 0x28ea, 0x290e,
-	0x2910, 0x2939, 0x293b, 0x293d, 0x2001, 0x0001, 0x080c, 0x2717,
-	0x080c, 0x2b6a, 0x2001, 0x196a, 0x2003, 0x0000, 0x7828, 0x9084,
-	0xe1d7, 0x782a, 0x9006, 0x20a9, 0x0009, 0x080c, 0x2b12, 0x2001,
-	0x1968, 0x2003, 0x0006, 0x2009, 0x001e, 0x2011, 0x293e, 0x080c,
-	0x836c, 0x0005, 0x2009, 0x196d, 0x200b, 0x0000, 0x2001, 0x1972,
-	0x2003, 0x0036, 0x2001, 0x1971, 0x2003, 0x002a, 0x2001, 0x196a,
-	0x2003, 0x0001, 0x9006, 0x080c, 0x2a9b, 0x2001, 0xffff, 0x20a9,
-	0x0009, 0x080c, 0x2b12, 0x2001, 0x1968, 0x2003, 0x0006, 0x2009,
-	0x001e, 0x2011, 0x293e, 0x080c, 0x836c, 0x0005, 0x080c, 0x0dfa,
-	0x2001, 0x1972, 0x2003, 0x0036, 0x2001, 0x196a, 0x2003, 0x0003,
+	0x196a, 0x2004, 0x908a, 0x0007, 0x1a0c, 0x0e02, 0x0033, 0x00ee,
+	0x002e, 0x001e, 0x000e, 0x015e, 0x0005, 0x27cc, 0x27ea, 0x280e,
+	0x2810, 0x2839, 0x283b, 0x283d, 0x2001, 0x0001, 0x080c, 0x2617,
+	0x080c, 0x2a6a, 0x2001, 0x196c, 0x2003, 0x0000, 0x7828, 0x9084,
+	0xe1d7, 0x782a, 0x9006, 0x20a9, 0x0009, 0x080c, 0x2a12, 0x2001,
+	0x196a, 0x2003, 0x0006, 0x2009, 0x001e, 0x2011, 0x283e, 0x080c,
+	0x82ec, 0x0005, 0x2009, 0x196f, 0x200b, 0x0000, 0x2001, 0x1974,
+	0x2003, 0x0036, 0x2001, 0x1973, 0x2003, 0x002a, 0x2001, 0x196c,
+	0x2003, 0x0001, 0x9006, 0x080c, 0x299b, 0x2001, 0xffff, 0x20a9,
+	0x0009, 0x080c, 0x2a12, 0x2001, 0x196a, 0x2003, 0x0006, 0x2009,
+	0x001e, 0x2011, 0x283e, 0x080c, 0x82ec, 0x0005, 0x080c, 0x0e02,
+	0x2001, 0x1974, 0x2003, 0x0036, 0x2001, 0x196c, 0x2003, 0x0003,
 	0x7a38, 0x9294, 0x0005, 0x9296, 0x0004, 0x0110, 0x9006, 0x0010,
-	0x2001, 0x0001, 0x080c, 0x2a9b, 0x2001, 0x196e, 0x2003, 0x0000,
-	0x2001, 0xffff, 0x20a9, 0x0009, 0x080c, 0x2b12, 0x2001, 0x1968,
-	0x2003, 0x0006, 0x2009, 0x001e, 0x2011, 0x293e, 0x080c, 0x836c,
-	0x0005, 0x080c, 0x0dfa, 0x080c, 0x0dfa, 0x0005, 0x0006, 0x0016,
+	0x2001, 0x0001, 0x080c, 0x299b, 0x2001, 0x1970, 0x2003, 0x0000,
+	0x2001, 0xffff, 0x20a9, 0x0009, 0x080c, 0x2a12, 0x2001, 0x196a,
+	0x2003, 0x0006, 0x2009, 0x001e, 0x2011, 0x283e, 0x080c, 0x82ec,
+	0x0005, 0x080c, 0x0e02, 0x080c, 0x0e02, 0x0005, 0x0006, 0x0016,
 	0x0026, 0x00e6, 0x00f6, 0x0156, 0x0126, 0x2091, 0x8000, 0x2079,
-	0x0100, 0x2001, 0x196a, 0x2004, 0x908a, 0x0007, 0x1a0c, 0x0dfa,
+	0x0100, 0x2001, 0x196c, 0x2004, 0x908a, 0x0007, 0x1a0c, 0x0e02,
 	0x0043, 0x012e, 0x015e, 0x00fe, 0x00ee, 0x002e, 0x001e, 0x000e,
-	0x0005, 0x2960, 0x2980, 0x29c0, 0x29f0, 0x2a14, 0x2a24, 0x2a26,
-	0x080c, 0x2b06, 0x11b0, 0x7850, 0x9084, 0xefff, 0x7852, 0x2009,
-	0x1970, 0x2104, 0x7a38, 0x9294, 0x0005, 0x9296, 0x0004, 0x0110,
-	0xc08d, 0x0008, 0xc085, 0x200a, 0x2001, 0x1968, 0x2003, 0x0001,
-	0x0030, 0x080c, 0x2a4a, 0x2001, 0xffff, 0x080c, 0x28db, 0x0005,
-	0x080c, 0x2a28, 0x05e0, 0x2009, 0x1971, 0x2104, 0x8001, 0x200a,
-	0x080c, 0x2b06, 0x1178, 0x7850, 0x9084, 0xefff, 0x7852, 0x7a38,
-	0x9294, 0x0005, 0x9296, 0x0005, 0x0518, 0x2009, 0x1970, 0x2104,
-	0xc085, 0x200a, 0x2009, 0x196d, 0x2104, 0x8000, 0x200a, 0x9086,
-	0x0005, 0x0118, 0x080c, 0x2a30, 0x00c0, 0x200b, 0x0000, 0x7a38,
+	0x0005, 0x2860, 0x2880, 0x28c0, 0x28f0, 0x2914, 0x2924, 0x2926,
+	0x080c, 0x2a06, 0x11b0, 0x7850, 0x9084, 0xefff, 0x7852, 0x2009,
+	0x1972, 0x2104, 0x7a38, 0x9294, 0x0005, 0x9296, 0x0004, 0x0110,
+	0xc08d, 0x0008, 0xc085, 0x200a, 0x2001, 0x196a, 0x2003, 0x0001,
+	0x0030, 0x080c, 0x294a, 0x2001, 0xffff, 0x080c, 0x27db, 0x0005,
+	0x080c, 0x2928, 0x05e0, 0x2009, 0x1973, 0x2104, 0x8001, 0x200a,
+	0x080c, 0x2a06, 0x1178, 0x7850, 0x9084, 0xefff, 0x7852, 0x7a38,
+	0x9294, 0x0005, 0x9296, 0x0005, 0x0518, 0x2009, 0x1972, 0x2104,
+	0xc085, 0x200a, 0x2009, 0x196f, 0x2104, 0x8000, 0x200a, 0x9086,
+	0x0005, 0x0118, 0x080c, 0x2930, 0x00c0, 0x200b, 0x0000, 0x7a38,
 	0x9294, 0x0006, 0x9296, 0x0004, 0x0110, 0x9006, 0x0010, 0x2001,
-	0x0001, 0x080c, 0x2ab8, 0x2001, 0x196a, 0x2003, 0x0002, 0x0028,
-	0x2001, 0x1968, 0x2003, 0x0003, 0x0010, 0x080c, 0x28fd, 0x0005,
-	0x080c, 0x2a28, 0x0560, 0x2009, 0x1971, 0x2104, 0x8001, 0x200a,
-	0x080c, 0x2b06, 0x1168, 0x7850, 0x9084, 0xefff, 0x7852, 0x2001,
-	0x1968, 0x2003, 0x0003, 0x2001, 0x1969, 0x2003, 0x0000, 0x00b8,
-	0x2009, 0x1971, 0x2104, 0x9005, 0x1118, 0x080c, 0x2a6d, 0x0010,
-	0x080c, 0x2a3d, 0x080c, 0x2a30, 0x2009, 0x196d, 0x200b, 0x0000,
-	0x2001, 0x196a, 0x2003, 0x0001, 0x080c, 0x28fd, 0x0000, 0x0005,
-	0x04b9, 0x0508, 0x080c, 0x2b06, 0x11b8, 0x7850, 0x9084, 0xefff,
-	0x7852, 0x2009, 0x196e, 0x2104, 0x8000, 0x200a, 0x9086, 0x0007,
-	0x0108, 0x0078, 0x2001, 0x1973, 0x2003, 0x000a, 0x2009, 0x1970,
-	0x2104, 0xc0fd, 0x200a, 0x0038, 0x0419, 0x2001, 0x196a, 0x2003,
-	0x0004, 0x080c, 0x2928, 0x0005, 0x0099, 0x0168, 0x080c, 0x2b06,
-	0x1138, 0x7850, 0x9084, 0xefff, 0x7852, 0x080c, 0x2914, 0x0018,
-	0x0079, 0x080c, 0x2928, 0x0005, 0x080c, 0x0dfa, 0x080c, 0x0dfa,
-	0x2009, 0x1972, 0x2104, 0x8001, 0x200a, 0x090c, 0x2a89, 0x0005,
+	0x0001, 0x080c, 0x29b8, 0x2001, 0x196c, 0x2003, 0x0002, 0x0028,
+	0x2001, 0x196a, 0x2003, 0x0003, 0x0010, 0x080c, 0x27fd, 0x0005,
+	0x080c, 0x2928, 0x0560, 0x2009, 0x1973, 0x2104, 0x8001, 0x200a,
+	0x080c, 0x2a06, 0x1168, 0x7850, 0x9084, 0xefff, 0x7852, 0x2001,
+	0x196a, 0x2003, 0x0003, 0x2001, 0x196b, 0x2003, 0x0000, 0x00b8,
+	0x2009, 0x1973, 0x2104, 0x9005, 0x1118, 0x080c, 0x296d, 0x0010,
+	0x080c, 0x293d, 0x080c, 0x2930, 0x2009, 0x196f, 0x200b, 0x0000,
+	0x2001, 0x196c, 0x2003, 0x0001, 0x080c, 0x27fd, 0x0000, 0x0005,
+	0x04b9, 0x0508, 0x080c, 0x2a06, 0x11b8, 0x7850, 0x9084, 0xefff,
+	0x7852, 0x2009, 0x1970, 0x2104, 0x8000, 0x200a, 0x9086, 0x0007,
+	0x0108, 0x0078, 0x2001, 0x1975, 0x2003, 0x000a, 0x2009, 0x1972,
+	0x2104, 0xc0fd, 0x200a, 0x0038, 0x0419, 0x2001, 0x196c, 0x2003,
+	0x0004, 0x080c, 0x2828, 0x0005, 0x0099, 0x0168, 0x080c, 0x2a06,
+	0x1138, 0x7850, 0x9084, 0xefff, 0x7852, 0x080c, 0x2814, 0x0018,
+	0x0079, 0x080c, 0x2828, 0x0005, 0x080c, 0x0e02, 0x080c, 0x0e02,
+	0x2009, 0x1974, 0x2104, 0x8001, 0x200a, 0x090c, 0x2989, 0x0005,
 	0x7a38, 0x9294, 0x0005, 0x9296, 0x0005, 0x0110, 0x9006, 0x0010,
-	0x2001, 0x0001, 0x080c, 0x2ab8, 0x0005, 0x7a38, 0x9294, 0x0006,
+	0x2001, 0x0001, 0x080c, 0x29b8, 0x0005, 0x7a38, 0x9294, 0x0006,
 	0x9296, 0x0006, 0x0110, 0x9006, 0x0010, 0x2001, 0x0001, 0x080c,
-	0x2a9b, 0x0005, 0x2009, 0x196d, 0x2104, 0x8000, 0x200a, 0x9086,
+	0x299b, 0x0005, 0x2009, 0x196f, 0x2104, 0x8000, 0x200a, 0x9086,
 	0x0005, 0x0108, 0x0068, 0x200b, 0x0000, 0x7a38, 0x9294, 0x0006,
 	0x9296, 0x0006, 0x0110, 0x9006, 0x0010, 0x2001, 0x0001, 0x04d9,
 	0x7a38, 0x9294, 0x0005, 0x9296, 0x0005, 0x0110, 0x9006, 0x0010,
-	0x2001, 0x0001, 0x080c, 0x2ab8, 0x0005, 0x0086, 0x2001, 0x1970,
-	0x2004, 0x9084, 0x7fff, 0x090c, 0x0dfa, 0x2009, 0x196f, 0x2144,
+	0x2001, 0x0001, 0x080c, 0x29b8, 0x0005, 0x0086, 0x2001, 0x1972,
+	0x2004, 0x9084, 0x7fff, 0x090c, 0x0e02, 0x2009, 0x1971, 0x2144,
 	0x8846, 0x280a, 0x9844, 0x0dd8, 0xd08c, 0x1120, 0xd084, 0x1120,
-	0x080c, 0x0dfa, 0x9006, 0x0010, 0x2001, 0x0001, 0x00a1, 0x008e,
-	0x0005, 0x0006, 0x0156, 0x2001, 0x1968, 0x20a9, 0x0009, 0x2003,
-	0x0000, 0x8000, 0x1f04, 0x2a8f, 0x2001, 0x196f, 0x2003, 0x8000,
+	0x080c, 0x0e02, 0x9006, 0x0010, 0x2001, 0x0001, 0x00a1, 0x008e,
+	0x0005, 0x0006, 0x0156, 0x2001, 0x196a, 0x20a9, 0x0009, 0x2003,
+	0x0000, 0x8000, 0x1f04, 0x298f, 0x2001, 0x1971, 0x2003, 0x8000,
 	0x015e, 0x000e, 0x0005, 0x00f6, 0x2079, 0x0100, 0x9085, 0x0000,
 	0x0158, 0x7838, 0x9084, 0xfff9, 0x9085, 0x0004, 0x783a, 0x2009,
-	0x1975, 0x210c, 0x795a, 0x0050, 0x7838, 0x9084, 0xfffb, 0x9085,
-	0x0006, 0x783a, 0x2009, 0x1976, 0x210c, 0x795a, 0x00fe, 0x0005,
+	0x1977, 0x210c, 0x795a, 0x0050, 0x7838, 0x9084, 0xfffb, 0x9085,
+	0x0006, 0x783a, 0x2009, 0x1978, 0x210c, 0x795a, 0x00fe, 0x0005,
 	0x00f6, 0x2079, 0x0100, 0x9085, 0x0000, 0x0188, 0x7838, 0x9084,
 	0xfffa, 0x9085, 0x0004, 0x783a, 0x2001, 0x0100, 0x2004, 0x9086,
 	0x000a, 0x1120, 0x7850, 0x9084, 0xfff0, 0x7852, 0x0428, 0x7838,
@@ -1171,43 +1139,43 @@ unsigned short risc_code01[] = { 
 	0x9085, 0x0000, 0x001e, 0x7852, 0x00fe, 0x0005, 0x0006, 0x2001,
 	0x0100, 0x2004, 0x9082, 0x0007, 0x000e, 0x0005, 0x0006, 0x2001,
 	0x0100, 0x2004, 0x9082, 0x0009, 0x000e, 0x0005, 0x0156, 0x20a9,
-	0x0064, 0x7820, 0x080c, 0x2bb0, 0xd09c, 0x1110, 0x1f04, 0x2b09,
+	0x0064, 0x7820, 0x080c, 0x2ab0, 0xd09c, 0x1110, 0x1f04, 0x2a09,
 	0x015e, 0x0005, 0x0126, 0x0016, 0x0006, 0x2091, 0x8000, 0x2001,
 	0x0100, 0x2004, 0x9086, 0x000a, 0x0170, 0x7850, 0x9085, 0x0040,
-	0x7852, 0x7850, 0x9084, 0xfbcf, 0x7852, 0x080c, 0x2bb0, 0x9085,
-	0x2000, 0x7852, 0x0020, 0x080c, 0x2cc2, 0x080c, 0x2cf5, 0x000e,
+	0x7852, 0x7850, 0x9084, 0xfbcf, 0x7852, 0x080c, 0x2ab0, 0x9085,
+	0x2000, 0x7852, 0x0020, 0x080c, 0x2bc2, 0x080c, 0x2bf5, 0x000e,
 	0x2008, 0x9186, 0x0000, 0x1118, 0x783b, 0x0007, 0x0090, 0x9186,
 	0x0001, 0x1118, 0x783b, 0x0006, 0x0060, 0x9186, 0x0002, 0x1118,
 	0x783b, 0x0005, 0x0030, 0x9186, 0x0003, 0x1118, 0x783b, 0x0004,
-	0x0000, 0x0006, 0x1d04, 0x2b4a, 0x080c, 0x838e, 0x1f04, 0x2b4a,
+	0x0000, 0x0006, 0x1d04, 0x2a4a, 0x080c, 0x830e, 0x1f04, 0x2a4a,
 	0x2001, 0x0100, 0x2004, 0x9086, 0x000a, 0x0160, 0x7850, 0x9085,
-	0x0400, 0x9084, 0xdfbf, 0x7852, 0x080c, 0x2bb0, 0x9085, 0x1000,
+	0x0400, 0x9084, 0xdfbf, 0x7852, 0x080c, 0x2ab0, 0x9085, 0x1000,
 	0x7852, 0x0020, 0x7850, 0x9085, 0x1000, 0x7852, 0x000e, 0x001e,
 	0x012e, 0x0005, 0x2001, 0x0100, 0x2004, 0x9086, 0x000a, 0x0128,
-	0x7850, 0x9084, 0xffcf, 0x7852, 0x0010, 0x080c, 0x2cf5, 0x0005,
+	0x7850, 0x9084, 0xffcf, 0x7852, 0x0010, 0x080c, 0x2bf5, 0x0005,
 	0x0006, 0x0156, 0x00f6, 0x2079, 0x0100, 0x20a9, 0x000a, 0x7854,
-	0xd0ac, 0x1130, 0x7820, 0xd0e4, 0x1140, 0x1f04, 0x2b82, 0x0028,
-	0x7854, 0xd08c, 0x1110, 0x1f04, 0x2b88, 0x00fe, 0x015e, 0x000e,
-	0x0005, 0x1d04, 0x2b91, 0x080c, 0x838e, 0x1f04, 0x2b91, 0x0005,
-	0x0006, 0x2001, 0x1974, 0x2004, 0x9086, 0x0000, 0x000e, 0x0005,
-	0x0006, 0x2001, 0x1974, 0x2004, 0x9086, 0x0001, 0x000e, 0x0005,
-	0x0006, 0x2001, 0x1974, 0x2004, 0x9086, 0x0002, 0x000e, 0x0005,
+	0xd0ac, 0x1130, 0x7820, 0xd0e4, 0x1140, 0x1f04, 0x2a82, 0x0028,
+	0x7854, 0xd08c, 0x1110, 0x1f04, 0x2a88, 0x00fe, 0x015e, 0x000e,
+	0x0005, 0x1d04, 0x2a91, 0x080c, 0x830e, 0x1f04, 0x2a91, 0x0005,
+	0x0006, 0x2001, 0x1976, 0x2004, 0x9086, 0x0000, 0x000e, 0x0005,
+	0x0006, 0x2001, 0x1976, 0x2004, 0x9086, 0x0001, 0x000e, 0x0005,
+	0x0006, 0x2001, 0x1976, 0x2004, 0x9086, 0x0002, 0x000e, 0x0005,
 	0xa001, 0xa001, 0xa001, 0xa001, 0xa001, 0x0005, 0x0006, 0x2001,
-	0x1980, 0x2102, 0x000e, 0x0005, 0x2009, 0x0171, 0x2104, 0xd0dc,
+	0x1982, 0x2102, 0x000e, 0x0005, 0x2009, 0x0171, 0x2104, 0xd0dc,
 	0x0140, 0x2009, 0x0170, 0x2104, 0x200b, 0x0080, 0xa001, 0xa001,
 	0x200a, 0x0005, 0x0036, 0x0046, 0x2001, 0x0141, 0x200c, 0x918c,
 	0xff00, 0x9186, 0x2100, 0x0140, 0x9186, 0x2000, 0x0170, 0x9186,
-	0x0100, 0x1904, 0x2c29, 0x0048, 0x0016, 0x2009, 0x1a5a, 0x2104,
+	0x0100, 0x1904, 0x2b29, 0x0048, 0x0016, 0x2009, 0x1a58, 0x2104,
 	0x8000, 0x0208, 0x200a, 0x001e, 0x04f0, 0x2009, 0x00a2, 0x080c,
-	0x0e75, 0x2019, 0x0160, 0x2324, 0x2011, 0x0003, 0x2009, 0x0169,
+	0x0e87, 0x2019, 0x0160, 0x2324, 0x2011, 0x0003, 0x2009, 0x0169,
 	0x2104, 0x9084, 0x0007, 0x210c, 0x918c, 0x0007, 0x910e, 0x1db0,
 	0x9086, 0x0003, 0x1548, 0x2304, 0x0066, 0x0076, 0x2031, 0x0002,
-	0x233c, 0x973e, 0x0148, 0x8631, 0x1dd8, 0x2031, 0x1a5b, 0x263c,
+	0x233c, 0x973e, 0x0148, 0x8631, 0x1dd8, 0x2031, 0x1a59, 0x263c,
 	0x8738, 0x0208, 0x2732, 0x2304, 0x007e, 0x006e, 0x9402, 0x02a0,
 	0x19d0, 0x8211, 0x19d8, 0x84ff, 0x0170, 0x2001, 0x0141, 0x200c,
 	0x918c, 0xff00, 0x9186, 0x0100, 0x0130, 0x2009, 0x180c, 0x2104,
-	0xc0dd, 0x200a, 0x0008, 0x0421, 0x2001, 0x1959, 0x200c, 0x080c,
-	0x0e75, 0x004e, 0x003e, 0x0005, 0x2001, 0x180c, 0x2004, 0xd0dc,
+	0xc0dd, 0x200a, 0x0008, 0x0421, 0x2001, 0x195b, 0x200c, 0x080c,
+	0x0e87, 0x004e, 0x003e, 0x0005, 0x2001, 0x180c, 0x2004, 0xd0dc,
 	0x01b0, 0x2001, 0x0160, 0x2004, 0x9005, 0x0140, 0x2001, 0x0141,
 	0x2004, 0x9084, 0xff00, 0x9086, 0x0100, 0x1148, 0x0126, 0x2091,
 	0x8000, 0x0016, 0x0026, 0x0021, 0x002e, 0x001e, 0x012e, 0x0005,
@@ -1219,208 +1187,212 @@ unsigned short risc_code01[] = { 
 	0x0dc0, 0x001e, 0x919c, 0xffe4, 0x9184, 0x0001, 0x0118, 0x9385,
 	0x0009, 0x6016, 0x9184, 0x0002, 0x0118, 0x9385, 0x0012, 0x6016,
 	0x003e, 0x2001, 0x180c, 0x200c, 0xc1dc, 0x2102, 0x00ce, 0x0005,
-	0x0016, 0x0026, 0x080c, 0x7221, 0x0108, 0xc0bc, 0x2009, 0x0140,
+	0x0016, 0x0026, 0x080c, 0x7199, 0x0108, 0xc0bc, 0x2009, 0x0140,
 	0x2114, 0x9294, 0x0001, 0x9215, 0x220a, 0x002e, 0x001e, 0x0005,
 	0x0016, 0x0026, 0x2009, 0x0140, 0x2114, 0x9294, 0x0001, 0x9285,
 	0x1000, 0x200a, 0x220a, 0x002e, 0x001e, 0x0005, 0x0016, 0x0026,
 	0x2009, 0x0140, 0x2114, 0x9294, 0x0001, 0x9215, 0x220a, 0x002e,
 	0x001e, 0x0005, 0x0006, 0x0016, 0x2009, 0x0140, 0x2104, 0x1128,
-	0x080c, 0x7221, 0x0110, 0xc0bc, 0x0008, 0xc0bd, 0x200a, 0x001e,
+	0x080c, 0x7199, 0x0110, 0xc0bc, 0x0008, 0xc0bd, 0x200a, 0x001e,
 	0x000e, 0x0005, 0x0016, 0x0026, 0x0036, 0x00c6, 0x2061, 0x0100,
 	0x6050, 0x9084, 0xfbff, 0x9085, 0x0040, 0x6052, 0x20a9, 0x0002,
-	0x080c, 0x2b91, 0x6050, 0x9085, 0x0400, 0x9084, 0xff9f, 0x6052,
-	0x20a9, 0x0005, 0x080c, 0x2b91, 0x6054, 0xd0bc, 0x090c, 0x0dfa,
-	0x20a9, 0x0005, 0x080c, 0x2b91, 0x6054, 0xd0ac, 0x090c, 0x0dfa,
-	0x2009, 0x1987, 0x9084, 0x7e00, 0x8007, 0x8004, 0x8004, 0x200a,
+	0x080c, 0x2a91, 0x6050, 0x9085, 0x0400, 0x9084, 0xff9f, 0x6052,
+	0x20a9, 0x0005, 0x080c, 0x2a91, 0x6054, 0xd0bc, 0x090c, 0x0e02,
+	0x20a9, 0x0005, 0x080c, 0x2a91, 0x6054, 0xd0ac, 0x090c, 0x0e02,
+	0x2009, 0x1989, 0x9084, 0x7e00, 0x8007, 0x8004, 0x8004, 0x200a,
 	0x00ce, 0x003e, 0x002e, 0x001e, 0x0005, 0x0006, 0x00c6, 0x2061,
-	0x0100, 0x6050, 0xc0cd, 0x6052, 0x00ce, 0x000e, 0x0005, 0x2f6b,
-	0x2f6b, 0x2d8f, 0x2d8f, 0x2d9b, 0x2d9b, 0x2da7, 0x2da7, 0x2db5,
-	0x2db5, 0x2dc1, 0x2dc1, 0x2dcf, 0x2dcf, 0x2ddd, 0x2ddd, 0x2def,
-	0x2def, 0x2dfb, 0x2dfb, 0x2e09, 0x2e09, 0x2e27, 0x2e27, 0x2e47,
-	0x2e47, 0x2e17, 0x2e17, 0x2e37, 0x2e37, 0x2e55, 0x2e55, 0x2ded,
-	0x2ded, 0x2ded, 0x2ded, 0x2ded, 0x2ded, 0x2ded, 0x2ded, 0x2ded,
-	0x2ded, 0x2ded, 0x2ded, 0x2ded, 0x2ded, 0x2ded, 0x2ded, 0x2ded,
-	0x2ded, 0x2ded, 0x2ded, 0x2ded, 0x2ded, 0x2ded, 0x2ded, 0x2ded,
-	0x2ded, 0x2ded, 0x2ded, 0x2ded, 0x2ded, 0x2ded, 0x2ded, 0x2e67,
-	0x2e67, 0x2e73, 0x2e73, 0x2e81, 0x2e81, 0x2e8f, 0x2e8f, 0x2e9f,
-	0x2e9f, 0x2ead, 0x2ead, 0x2ebd, 0x2ebd, 0x2ecd, 0x2ecd, 0x2edf,
-	0x2edf, 0x2eed, 0x2eed, 0x2efd, 0x2efd, 0x2f1f, 0x2f1f, 0x2f41,
-	0x2f41, 0x2f0d, 0x2f0d, 0x2f30, 0x2f30, 0x2f50, 0x2f50, 0x2ded,
-	0x2ded, 0x2ded, 0x2ded, 0x2ded, 0x2ded, 0x2ded, 0x2ded, 0x2ded,
-	0x2ded, 0x2ded, 0x2ded, 0x2ded, 0x2ded, 0x2ded, 0x2ded, 0x2ded,
-	0x2ded, 0x2ded, 0x2ded, 0x2ded, 0x2ded, 0x2ded, 0x2ded, 0x2ded,
-	0x2ded, 0x2ded, 0x2ded, 0x2ded, 0x2ded, 0x2ded, 0x2ded, 0x2ded,
-	0x2ded, 0x2ded, 0x2ded, 0x2ded, 0x2ded, 0x2ded, 0x2ded, 0x2ded,
-	0x2ded, 0x2ded, 0x2ded, 0x2ded, 0x2ded, 0x2ded, 0x2ded, 0x0106,
+	0x0100, 0x6050, 0xc0cd, 0x6052, 0x00ce, 0x000e, 0x0005, 0x0006,
+	0x0156, 0x6050, 0x9085, 0x0040, 0x6052, 0x6050, 0x9084, 0xfbcf,
+	0x6052, 0x080c, 0x2ab0, 0x9085, 0x2000, 0x6052, 0x20a9, 0x0012,
+	0x1d04, 0x2c10, 0x080c, 0x830e, 0x1f04, 0x2c10, 0x6050, 0x9085,
+	0x0400, 0x9084, 0xdfbf, 0x6052, 0x015e, 0x000e, 0x0005, 0x2e8b,
+	0x2e8b, 0x2caf, 0x2caf, 0x2cbb, 0x2cbb, 0x2cc7, 0x2cc7, 0x2cd5,
+	0x2cd5, 0x2ce1, 0x2ce1, 0x2cef, 0x2cef, 0x2cfd, 0x2cfd, 0x2d0f,
+	0x2d0f, 0x2d1b, 0x2d1b, 0x2d29, 0x2d29, 0x2d47, 0x2d47, 0x2d67,
+	0x2d67, 0x2d37, 0x2d37, 0x2d57, 0x2d57, 0x2d75, 0x2d75, 0x2d0d,
+	0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d,
+	0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d,
+	0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d,
+	0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d87,
+	0x2d87, 0x2d93, 0x2d93, 0x2da1, 0x2da1, 0x2daf, 0x2daf, 0x2dbf,
+	0x2dbf, 0x2dcd, 0x2dcd, 0x2ddd, 0x2ddd, 0x2ded, 0x2ded, 0x2dff,
+	0x2dff, 0x2e0d, 0x2e0d, 0x2e1d, 0x2e1d, 0x2e3f, 0x2e3f, 0x2e61,
+	0x2e61, 0x2e2d, 0x2e2d, 0x2e50, 0x2e50, 0x2e70, 0x2e70, 0x2d0d,
+	0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d,
+	0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d,
+	0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d,
+	0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d,
+	0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d,
+	0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x2d0d, 0x0106,
 	0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c,
-	0x23c6, 0x0804, 0x2f63, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
-	0x0136, 0x0146, 0x0156, 0x080c, 0x21cd, 0x0804, 0x2f63, 0x0106,
+	0x22c0, 0x0804, 0x2e83, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
+	0x0136, 0x0146, 0x0156, 0x080c, 0x20c7, 0x0804, 0x2e83, 0x0106,
 	0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c,
-	0x21cd, 0x080c, 0x23c6, 0x0804, 0x2f63, 0x0106, 0x0006, 0x0126,
-	0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2208, 0x0804,
-	0x2f63, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146,
-	0x0156, 0x080c, 0x23c6, 0x080c, 0x2208, 0x0804, 0x2f63, 0x0106,
+	0x20c7, 0x080c, 0x22c0, 0x0804, 0x2e83, 0x0106, 0x0006, 0x0126,
+	0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2102, 0x0804,
+	0x2e83, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146,
+	0x0156, 0x080c, 0x22c0, 0x080c, 0x2102, 0x0804, 0x2e83, 0x0106,
 	0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c,
-	0x21cd, 0x080c, 0x2208, 0x0804, 0x2f63, 0x0106, 0x0006, 0x0126,
-	0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x21cd, 0x080c,
-	0x23c6, 0x080c, 0x2208, 0x0804, 0x2f63, 0xa001, 0x0cf0, 0x0106,
+	0x20c7, 0x080c, 0x2102, 0x0804, 0x2e83, 0x0106, 0x0006, 0x0126,
+	0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x20c7, 0x080c,
+	0x22c0, 0x080c, 0x2102, 0x0804, 0x2e83, 0xa001, 0x0cf0, 0x0106,
 	0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c,
-	0x1370, 0x0804, 0x2f63, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
-	0x0136, 0x0146, 0x0156, 0x080c, 0x23c6, 0x080c, 0x1370, 0x0804,
-	0x2f63, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146,
-	0x0156, 0x080c, 0x21cd, 0x080c, 0x1370, 0x0804, 0x2f63, 0x0106,
+	0x1371, 0x0804, 0x2e83, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
+	0x0136, 0x0146, 0x0156, 0x080c, 0x22c0, 0x080c, 0x1371, 0x0804,
+	0x2e83, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146,
+	0x0156, 0x080c, 0x20c7, 0x080c, 0x1371, 0x0804, 0x2e83, 0x0106,
 	0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c,
-	0x23c6, 0x080c, 0x1370, 0x080c, 0x2208, 0x0804, 0x2f63, 0x0106,
+	0x22c0, 0x080c, 0x1371, 0x080c, 0x2102, 0x0804, 0x2e83, 0x0106,
 	0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c,
-	0x21cd, 0x080c, 0x23c6, 0x080c, 0x1370, 0x0804, 0x2f63, 0x0106,
+	0x20c7, 0x080c, 0x22c0, 0x080c, 0x1371, 0x0804, 0x2e83, 0x0106,
 	0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c,
-	0x21cd, 0x080c, 0x1370, 0x080c, 0x2208, 0x0804, 0x2f63, 0x0106,
+	0x20c7, 0x080c, 0x1371, 0x080c, 0x2102, 0x0804, 0x2e83, 0x0106,
 	0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c,
-	0x1370, 0x080c, 0x2208, 0x0804, 0x2f63, 0x0106, 0x0006, 0x0126,
-	0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x21cd, 0x080c,
-	0x23c6, 0x080c, 0x1370, 0x080c, 0x2208, 0x0804, 0x2f63, 0x0106,
+	0x1371, 0x080c, 0x2102, 0x0804, 0x2e83, 0x0106, 0x0006, 0x0126,
+	0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x20c7, 0x080c,
+	0x22c0, 0x080c, 0x1371, 0x080c, 0x2102, 0x0804, 0x2e83, 0x0106,
 	0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c,
-	0x2871, 0x0804, 0x2f63, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
-	0x0136, 0x0146, 0x0156, 0x080c, 0x2871, 0x080c, 0x23c6, 0x0804,
-	0x2f63, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146,
-	0x0156, 0x080c, 0x2871, 0x080c, 0x21cd, 0x0804, 0x2f63, 0x0106,
+	0x2771, 0x0804, 0x2e83, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6,
+	0x0136, 0x0146, 0x0156, 0x080c, 0x2771, 0x080c, 0x22c0, 0x0804,
+	0x2e83, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146,
+	0x0156, 0x080c, 0x2771, 0x080c, 0x20c7, 0x0804, 0x2e83, 0x0106,
 	0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c,
-	0x2871, 0x080c, 0x21cd, 0x080c, 0x23c6, 0x0804, 0x2f63, 0x0106,
+	0x2771, 0x080c, 0x20c7, 0x080c, 0x22c0, 0x0804, 0x2e83, 0x0106,
 	0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c,
-	0x2871, 0x080c, 0x2208, 0x0804, 0x2f63, 0x0106, 0x0006, 0x0126,
-	0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2871, 0x080c,
-	0x23c6, 0x080c, 0x2208, 0x0804, 0x2f63, 0x0106, 0x0006, 0x0126,
-	0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2871, 0x080c,
-	0x21cd, 0x080c, 0x2208, 0x0804, 0x2f63, 0x0106, 0x0006, 0x0126,
-	0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2871, 0x080c,
-	0x21cd, 0x080c, 0x23c6, 0x080c, 0x2208, 0x0804, 0x2f63, 0x0106,
+	0x2771, 0x080c, 0x2102, 0x0804, 0x2e83, 0x0106, 0x0006, 0x0126,
+	0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2771, 0x080c,
+	0x22c0, 0x080c, 0x2102, 0x0804, 0x2e83, 0x0106, 0x0006, 0x0126,
+	0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2771, 0x080c,
+	0x20c7, 0x080c, 0x2102, 0x0804, 0x2e83, 0x0106, 0x0006, 0x0126,
+	0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2771, 0x080c,
+	0x20c7, 0x080c, 0x22c0, 0x080c, 0x2102, 0x0804, 0x2e83, 0x0106,
 	0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c,
-	0x2871, 0x080c, 0x1370, 0x0804, 0x2f63, 0x0106, 0x0006, 0x0126,
-	0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2871, 0x080c,
-	0x23c6, 0x080c, 0x1370, 0x0804, 0x2f63, 0x0106, 0x0006, 0x0126,
-	0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2871, 0x080c,
-	0x21cd, 0x080c, 0x1370, 0x0804, 0x2f63, 0x0106, 0x0006, 0x0126,
-	0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2871, 0x080c,
-	0x23c6, 0x080c, 0x1370, 0x080c, 0x2208, 0x0804, 0x2f63, 0x0106,
+	0x2771, 0x080c, 0x1371, 0x0804, 0x2e83, 0x0106, 0x0006, 0x0126,
+	0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2771, 0x080c,
+	0x22c0, 0x080c, 0x1371, 0x0804, 0x2e83, 0x0106, 0x0006, 0x0126,
+	0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2771, 0x080c,
+	0x20c7, 0x080c, 0x1371, 0x0804, 0x2e83, 0x0106, 0x0006, 0x0126,
+	0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c, 0x2771, 0x080c,
+	0x22c0, 0x080c, 0x1371, 0x080c, 0x2102, 0x0804, 0x2e83, 0x0106,
 	0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156, 0x080c,
-	0x2871, 0x080c, 0x21cd, 0x080c, 0x23c6, 0x080c, 0x1370, 0x0498,
+	0x2771, 0x080c, 0x20c7, 0x080c, 0x22c0, 0x080c, 0x1371, 0x0498,
 	0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156,
-	0x080c, 0x2871, 0x080c, 0x21cd, 0x080c, 0x1370, 0x080c, 0x2208,
+	0x080c, 0x2771, 0x080c, 0x20c7, 0x080c, 0x1371, 0x080c, 0x2102,
 	0x0410, 0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146,
-	0x0156, 0x080c, 0x2871, 0x080c, 0x1370, 0x080c, 0x2208, 0x0098,
+	0x0156, 0x080c, 0x2771, 0x080c, 0x1371, 0x080c, 0x2102, 0x0098,
 	0x0106, 0x0006, 0x0126, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x0156,
-	0x080c, 0x2871, 0x080c, 0x21cd, 0x080c, 0x23c6, 0x080c, 0x1370,
-	0x080c, 0x2208, 0x0000, 0x015e, 0x014e, 0x013e, 0x01de, 0x01ce,
+	0x080c, 0x2771, 0x080c, 0x20c7, 0x080c, 0x22c0, 0x080c, 0x1371,
+	0x080c, 0x2102, 0x0000, 0x015e, 0x014e, 0x013e, 0x01de, 0x01ce,
 	0x012e, 0x000e, 0x010e, 0x000d, 0x00b6, 0x00c6, 0x0026, 0x0046,
-	0x9026, 0x080c, 0x6781, 0x1904, 0x3072, 0x72d8, 0x2001, 0x1954,
+	0x9026, 0x080c, 0x6688, 0x1904, 0x2f92, 0x72d8, 0x2001, 0x1956,
 	0x2004, 0x9005, 0x1110, 0xd29c, 0x0148, 0xd284, 0x1138, 0xd2bc,
-	0x1904, 0x3072, 0x080c, 0x3077, 0x0804, 0x3072, 0xd2cc, 0x1904,
-	0x3072, 0x080c, 0x7207, 0x1120, 0x70ab, 0xffff, 0x0804, 0x3072,
-	0xd294, 0x0120, 0x70ab, 0xffff, 0x0804, 0x3072, 0x080c, 0x32df,
-	0x0160, 0x080c, 0xc539, 0x0128, 0x2001, 0x1817, 0x203c, 0x0804,
-	0x3004, 0x70ab, 0xffff, 0x0804, 0x3072, 0x2001, 0x1817, 0x203c,
-	0x7290, 0xd284, 0x0904, 0x3004, 0xd28c, 0x1904, 0x3004, 0x0036,
+	0x1904, 0x2f92, 0x080c, 0x2f97, 0x0804, 0x2f92, 0xd2cc, 0x1904,
+	0x2f92, 0x080c, 0x717f, 0x1120, 0x70ab, 0xffff, 0x0804, 0x2f92,
+	0xd294, 0x0120, 0x70ab, 0xffff, 0x0804, 0x2f92, 0x080c, 0x31ff,
+	0x0160, 0x080c, 0xc444, 0x0128, 0x2001, 0x1817, 0x203c, 0x0804,
+	0x2f24, 0x70ab, 0xffff, 0x0804, 0x2f92, 0x2001, 0x1817, 0x203c,
+	0x7290, 0xd284, 0x0904, 0x2f24, 0xd28c, 0x1904, 0x2f24, 0x0036,
 	0x73a8, 0x938e, 0xffff, 0x1110, 0x2019, 0x0001, 0x8314, 0x92e0,
 	0x1c80, 0x2c04, 0x938c, 0x0001, 0x0120, 0x9084, 0xff00, 0x8007,
 	0x0010, 0x9084, 0x00ff, 0x970e, 0x05a8, 0x908e, 0x0000, 0x0590,
 	0x908e, 0x00ff, 0x1150, 0x7230, 0xd284, 0x1588, 0x7290, 0xc28d,
 	0x7292, 0x70ab, 0xffff, 0x003e, 0x0478, 0x0026, 0x2011, 0x0010,
-	0x080c, 0x67e7, 0x002e, 0x0118, 0x70ab, 0xffff, 0x0410, 0x900e,
-	0x080c, 0x276e, 0x080c, 0x643f, 0x11c0, 0x080c, 0x67c3, 0x1168,
-	0x7030, 0xd08c, 0x0130, 0xb800, 0xd0bc, 0x0138, 0x080c, 0x66bf,
-	0x0120, 0x080c, 0x3090, 0x0148, 0x0028, 0x080c, 0x31d0, 0x080c,
-	0x30bc, 0x0118, 0x8318, 0x0804, 0x2fb6, 0x73aa, 0x0010, 0x70ab,
-	0xffff, 0x003e, 0x0804, 0x3072, 0x9780, 0x32e9, 0x203d, 0x97bc,
+	0x080c, 0x66ee, 0x002e, 0x0118, 0x70ab, 0xffff, 0x0410, 0x900e,
+	0x080c, 0x266e, 0x080c, 0x6344, 0x11c0, 0x080c, 0x66ca, 0x1168,
+	0x7030, 0xd08c, 0x0130, 0xb800, 0xd0bc, 0x0138, 0x080c, 0x65c4,
+	0x0120, 0x080c, 0x2fb0, 0x0148, 0x0028, 0x080c, 0x30f0, 0x080c,
+	0x2fdc, 0x0118, 0x8318, 0x0804, 0x2ed6, 0x73aa, 0x0010, 0x70ab,
+	0xffff, 0x003e, 0x0804, 0x2f92, 0x9780, 0x3209, 0x203d, 0x97bc,
 	0xff00, 0x873f, 0x2041, 0x007e, 0x70a8, 0x9096, 0xffff, 0x1118,
 	0x900e, 0x28a8, 0x0050, 0x9812, 0x0220, 0x2008, 0x9802, 0x20a8,
-	0x0020, 0x70ab, 0xffff, 0x0804, 0x3072, 0x2700, 0x0156, 0x0016,
-	0x9106, 0x0904, 0x3067, 0x0026, 0x2011, 0x0010, 0x080c, 0x67e7,
-	0x002e, 0x0120, 0x2009, 0xffff, 0x0804, 0x306f, 0xc484, 0x080c,
-	0x649f, 0x0138, 0x080c, 0xc539, 0x1590, 0x080c, 0x643f, 0x15b8,
-	0x0008, 0xc485, 0x080c, 0x67c3, 0x1130, 0x7030, 0xd08c, 0x01f8,
-	0xb800, 0xd0bc, 0x11e0, 0x7290, 0xd28c, 0x0180, 0x080c, 0x67c3,
-	0x9082, 0x0006, 0x02e0, 0xd484, 0x1118, 0x080c, 0x6463, 0x0028,
-	0x080c, 0x325b, 0x01a0, 0x080c, 0x3286, 0x0088, 0x080c, 0x31d0,
-	0x080c, 0xc539, 0x1160, 0x080c, 0x30bc, 0x0188, 0x0040, 0x080c,
-	0xc539, 0x1118, 0x080c, 0x325b, 0x0110, 0x0451, 0x0140, 0x001e,
-	0x8108, 0x015e, 0x1f04, 0x301d, 0x70ab, 0xffff, 0x0018, 0x001e,
+	0x0020, 0x70ab, 0xffff, 0x0804, 0x2f92, 0x2700, 0x0156, 0x0016,
+	0x9106, 0x0904, 0x2f87, 0x0026, 0x2011, 0x0010, 0x080c, 0x66ee,
+	0x002e, 0x0120, 0x2009, 0xffff, 0x0804, 0x2f8f, 0xc484, 0x080c,
+	0x63a4, 0x0138, 0x080c, 0xc444, 0x1590, 0x080c, 0x6344, 0x15b8,
+	0x0008, 0xc485, 0x080c, 0x66ca, 0x1130, 0x7030, 0xd08c, 0x01f8,
+	0xb800, 0xd0bc, 0x11e0, 0x7290, 0xd28c, 0x0180, 0x080c, 0x66ca,
+	0x9082, 0x0006, 0x02e0, 0xd484, 0x1118, 0x080c, 0x6368, 0x0028,
+	0x080c, 0x317b, 0x01a0, 0x080c, 0x31a6, 0x0088, 0x080c, 0x30f0,
+	0x080c, 0xc444, 0x1160, 0x080c, 0x2fdc, 0x0188, 0x0040, 0x080c,
+	0xc444, 0x1118, 0x080c, 0x317b, 0x0110, 0x0451, 0x0140, 0x001e,
+	0x8108, 0x015e, 0x1f04, 0x2f3d, 0x70ab, 0xffff, 0x0018, 0x001e,
 	0x015e, 0x71aa, 0x004e, 0x002e, 0x00ce, 0x00be, 0x0005, 0x00c6,
-	0x0016, 0x70ab, 0x0001, 0x2009, 0x007e, 0x080c, 0x643f, 0x1168,
-	0xb813, 0x00ff, 0xb817, 0xfffe, 0x080c, 0x31d0, 0x04a9, 0x0128,
-	0x70d8, 0xc0bd, 0x70da, 0x080c, 0xc28a, 0x001e, 0x00ce, 0x0005,
+	0x0016, 0x70ab, 0x0001, 0x2009, 0x007e, 0x080c, 0x6344, 0x1168,
+	0xb813, 0x00ff, 0xb817, 0xfffe, 0x080c, 0x30f0, 0x04a9, 0x0128,
+	0x70d8, 0xc0bd, 0x70da, 0x080c, 0xc18e, 0x001e, 0x00ce, 0x0005,
 	0x0016, 0x0076, 0x00d6, 0x00c6, 0x2001, 0x1860, 0x2004, 0x9084,
-	0x00ff, 0xb842, 0x080c, 0xa130, 0x01d0, 0x2b00, 0x6012, 0x080c,
-	0xc2b3, 0x6023, 0x0001, 0x9006, 0x080c, 0x63dc, 0x2001, 0x0000,
-	0x080c, 0x63f0, 0x0126, 0x2091, 0x8000, 0x70a4, 0x8000, 0x70a6,
-	0x012e, 0x2009, 0x0004, 0x080c, 0xa15d, 0x9085, 0x0001, 0x00ce,
+	0x00ff, 0xb842, 0x080c, 0xa026, 0x01d0, 0x2b00, 0x6012, 0x080c,
+	0xc1b7, 0x6023, 0x0001, 0x9006, 0x080c, 0x62e1, 0x2001, 0x0000,
+	0x080c, 0x62f5, 0x0126, 0x2091, 0x8000, 0x70a4, 0x8000, 0x70a6,
+	0x012e, 0x2009, 0x0004, 0x080c, 0xa053, 0x9085, 0x0001, 0x00ce,
 	0x00de, 0x007e, 0x001e, 0x0005, 0x0016, 0x0076, 0x00d6, 0x00c6,
-	0x2001, 0x1860, 0x2004, 0x9084, 0x00ff, 0xb842, 0x080c, 0xa130,
+	0x2001, 0x1860, 0x2004, 0x9084, 0x00ff, 0xb842, 0x080c, 0xa026,
 	0x0548, 0x2b00, 0x6012, 0xb800, 0xc0c4, 0xb802, 0xb8a0, 0x9086,
 	0x007e, 0x0140, 0xb804, 0x9084, 0x00ff, 0x9086, 0x0006, 0x1110,
-	0x080c, 0x318b, 0x080c, 0xc2b3, 0x6023, 0x0001, 0x9006, 0x080c,
-	0x63dc, 0x2001, 0x0002, 0x080c, 0x63f0, 0x0126, 0x2091, 0x8000,
-	0x70a4, 0x8000, 0x70a6, 0x012e, 0x2009, 0x0002, 0x080c, 0xa15d,
+	0x080c, 0x30ab, 0x080c, 0xc1b7, 0x6023, 0x0001, 0x9006, 0x080c,
+	0x62e1, 0x2001, 0x0002, 0x080c, 0x62f5, 0x0126, 0x2091, 0x8000,
+	0x70a4, 0x8000, 0x70a6, 0x012e, 0x2009, 0x0002, 0x080c, 0xa053,
 	0x9085, 0x0001, 0x00ce, 0x00de, 0x007e, 0x001e, 0x0005, 0x00b6,
-	0x00c6, 0x0026, 0x2009, 0x0080, 0x080c, 0x643f, 0x1140, 0xb813,
+	0x00c6, 0x0026, 0x2009, 0x0080, 0x080c, 0x6344, 0x1140, 0xb813,
 	0x00ff, 0xb817, 0xfffc, 0x0039, 0x0110, 0x70df, 0xffff, 0x002e,
 	0x00ce, 0x00be, 0x0005, 0x0016, 0x0076, 0x00d6, 0x00c6, 0x080c,
-	0xa08d, 0x01d0, 0x2b00, 0x6012, 0x080c, 0xc2b3, 0x6023, 0x0001,
-	0x9006, 0x080c, 0x63dc, 0x2001, 0x0002, 0x080c, 0x63f0, 0x0126,
+	0x9f7f, 0x01d0, 0x2b00, 0x6012, 0x080c, 0xc1b7, 0x6023, 0x0001,
+	0x9006, 0x080c, 0x62e1, 0x2001, 0x0002, 0x080c, 0x62f5, 0x0126,
 	0x2091, 0x8000, 0x70e0, 0x8000, 0x70e2, 0x012e, 0x2009, 0x0002,
-	0x080c, 0xa15d, 0x9085, 0x0001, 0x00ce, 0x00de, 0x007e, 0x001e,
+	0x080c, 0xa053, 0x9085, 0x0001, 0x00ce, 0x00de, 0x007e, 0x001e,
 	0x0005, 0x00c6, 0x00d6, 0x0126, 0x2091, 0x8000, 0x2009, 0x007f,
-	0x080c, 0x643f, 0x11b8, 0xb813, 0x00ff, 0xb817, 0xfffd, 0xb8bf,
-	0x0004, 0x080c, 0xa08d, 0x0170, 0x2b00, 0x6012, 0x6316, 0x6023,
-	0x0001, 0x620a, 0x080c, 0xc2b3, 0x2009, 0x0022, 0x080c, 0xa15d,
+	0x080c, 0x6344, 0x11b8, 0xb813, 0x00ff, 0xb817, 0xfffd, 0xb8bf,
+	0x0004, 0x080c, 0x9f7f, 0x0170, 0x2b00, 0x6012, 0x6316, 0x6023,
+	0x0001, 0x620a, 0x080c, 0xc1b7, 0x2009, 0x0022, 0x080c, 0xa053,
 	0x9085, 0x0001, 0x012e, 0x00de, 0x00ce, 0x0005, 0x00e6, 0x00c6,
-	0x0066, 0x0036, 0x0026, 0x00b6, 0x21f0, 0x080c, 0x880e, 0x080c,
-	0x8798, 0x080c, 0x9f36, 0x080c, 0xb03a, 0x3e08, 0x2130, 0x81ff,
+	0x0066, 0x0036, 0x0026, 0x00b6, 0x21f0, 0x080c, 0x878e, 0x080c,
+	0x8718, 0x080c, 0x9e28, 0x080c, 0xaf75, 0x3e08, 0x2130, 0x81ff,
 	0x0120, 0x20a9, 0x007e, 0x900e, 0x0018, 0x20a9, 0x007f, 0x900e,
-	0x0016, 0x080c, 0x649f, 0x1140, 0x9686, 0x0002, 0x1118, 0xb800,
-	0xd0bc, 0x1110, 0x080c, 0x5f45, 0x001e, 0x8108, 0x1f04, 0x3170,
-	0x9686, 0x0001, 0x190c, 0x32b3, 0x00be, 0x002e, 0x003e, 0x006e,
+	0x0016, 0x080c, 0x63a4, 0x1140, 0x9686, 0x0002, 0x1118, 0xb800,
+	0xd0bc, 0x1110, 0x080c, 0x5e4a, 0x001e, 0x8108, 0x1f04, 0x3090,
+	0x9686, 0x0001, 0x190c, 0x31d3, 0x00be, 0x002e, 0x003e, 0x006e,
 	0x00ce, 0x00ee, 0x0005, 0x00e6, 0x00c6, 0x0046, 0x0036, 0x0026,
 	0x0016, 0x00b6, 0x6210, 0x2258, 0xbaa0, 0x0026, 0x2019, 0x0029,
-	0x080c, 0x8803, 0x0076, 0x2039, 0x0000, 0x080c, 0x86f1, 0x2c08,
-	0x080c, 0xd5f6, 0x007e, 0x001e, 0xba10, 0xbb14, 0xbcb0, 0x080c,
-	0x5f45, 0xba12, 0xbb16, 0xbcb2, 0x00be, 0x001e, 0x002e, 0x003e,
+	0x080c, 0x8783, 0x0076, 0x2039, 0x0000, 0x080c, 0x8671, 0x2c08,
+	0x080c, 0xd53b, 0x007e, 0x001e, 0xba10, 0xbb14, 0xbcb0, 0x080c,
+	0x5e4a, 0xba12, 0xbb16, 0xbcb2, 0x00be, 0x001e, 0x002e, 0x003e,
 	0x004e, 0x00ce, 0x00ee, 0x0005, 0x00e6, 0x0006, 0x00b6, 0x6010,
 	0x2058, 0xb8a0, 0x00be, 0x9086, 0x0080, 0x0150, 0x2071, 0x1800,
 	0x70a4, 0x9005, 0x0110, 0x8001, 0x70a6, 0x000e, 0x00ee, 0x0005,
 	0x2071, 0x1800, 0x70e0, 0x9005, 0x0dc0, 0x8001, 0x70e2, 0x0ca8,
 	0xb800, 0xc08c, 0xb802, 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x00b6,
 	0x0046, 0x0036, 0x0026, 0x0016, 0x0156, 0x2178, 0x81ff, 0x1118,
-	0x20a9, 0x0001, 0x0070, 0x080c, 0x55db, 0xd0c4, 0x0138, 0x0030,
-	0x9006, 0x2020, 0x2009, 0x002d, 0x080c, 0xd885, 0x20a9, 0x0800,
-	0x9016, 0x0026, 0x928e, 0x007e, 0x0904, 0x323a, 0x928e, 0x007f,
-	0x0904, 0x323a, 0x928e, 0x0080, 0x05e8, 0x9288, 0x1000, 0x210c,
-	0x81ff, 0x05c0, 0x8fff, 0x1148, 0x2001, 0x1966, 0x0006, 0x2003,
+	0x20a9, 0x0001, 0x0070, 0x080c, 0x54dc, 0xd0c4, 0x0138, 0x0030,
+	0x9006, 0x2020, 0x2009, 0x002d, 0x080c, 0xd7d6, 0x20a9, 0x0800,
+	0x9016, 0x0026, 0x928e, 0x007e, 0x0904, 0x315a, 0x928e, 0x007f,
+	0x0904, 0x315a, 0x928e, 0x0080, 0x05e8, 0x9288, 0x1000, 0x210c,
+	0x81ff, 0x05c0, 0x8fff, 0x1148, 0x2001, 0x1968, 0x0006, 0x2003,
 	0x0001, 0x04f1, 0x000e, 0x2003, 0x0000, 0x00b6, 0x00c6, 0x2158,
-	0x2001, 0x0001, 0x080c, 0x678d, 0x00ce, 0x00be, 0x2019, 0x0029,
-	0x080c, 0x8803, 0x0076, 0x2039, 0x0000, 0x080c, 0x86f1, 0x00b6,
+	0x2001, 0x0001, 0x080c, 0x6694, 0x00ce, 0x00be, 0x2019, 0x0029,
+	0x080c, 0x8783, 0x0076, 0x2039, 0x0000, 0x080c, 0x8671, 0x00b6,
 	0x00c6, 0x0026, 0x2158, 0xba04, 0x9294, 0x00ff, 0x9286, 0x0006,
 	0x1118, 0xb807, 0x0404, 0x0028, 0x2001, 0x0004, 0x8007, 0x9215,
-	0xba06, 0x002e, 0x00ce, 0x00be, 0x0016, 0x2c08, 0x080c, 0xd5f6,
-	0x001e, 0x007e, 0x002e, 0x8210, 0x1f04, 0x31f1, 0x015e, 0x001e,
+	0xba06, 0x002e, 0x00ce, 0x00be, 0x0016, 0x2c08, 0x080c, 0xd53b,
+	0x001e, 0x007e, 0x002e, 0x8210, 0x1f04, 0x3111, 0x015e, 0x001e,
 	0x002e, 0x003e, 0x004e, 0x00be, 0x00ce, 0x00ee, 0x00fe, 0x0005,
-	0x0046, 0x0026, 0x0016, 0x080c, 0x55db, 0xd0c4, 0x0140, 0xd0a4,
-	0x0130, 0x9006, 0x2220, 0x2009, 0x0029, 0x080c, 0xd885, 0x001e,
+	0x0046, 0x0026, 0x0016, 0x080c, 0x54dc, 0xd0c4, 0x0140, 0xd0a4,
+	0x0130, 0x9006, 0x2220, 0x2009, 0x0029, 0x080c, 0xd7d6, 0x001e,
 	0x002e, 0x004e, 0x0005, 0x0016, 0x0026, 0x0036, 0x00c6, 0x7290,
-	0x82ff, 0x01e8, 0x080c, 0x67bb, 0x11d0, 0x2100, 0x080c, 0x27a1,
+	0x82ff, 0x01e8, 0x080c, 0x66c2, 0x11d0, 0x2100, 0x080c, 0x26a1,
 	0x81ff, 0x01b8, 0x2019, 0x0001, 0x8314, 0x92e0, 0x1c80, 0x2c04,
 	0xd384, 0x0120, 0x9084, 0xff00, 0x8007, 0x0010, 0x9084, 0x00ff,
 	0x9116, 0x0138, 0x9096, 0x00ff, 0x0110, 0x8318, 0x0c68, 0x9085,
 	0x0001, 0x00ce, 0x003e, 0x002e, 0x001e, 0x0005, 0x0016, 0x00c6,
 	0x0126, 0x2091, 0x8000, 0x0036, 0x2019, 0x0029, 0x00a9, 0x003e,
 	0x9180, 0x1000, 0x2004, 0x9065, 0x0158, 0x0016, 0x00c6, 0x2061,
-	0x1a8a, 0x001e, 0x6112, 0x080c, 0x318b, 0x001e, 0x080c, 0x6463,
+	0x1a88, 0x001e, 0x6112, 0x080c, 0x30ab, 0x001e, 0x080c, 0x6368,
 	0x012e, 0x00ce, 0x001e, 0x0005, 0x0016, 0x0026, 0x2110, 0x080c,
-	0x9bc9, 0x080c, 0xdb3d, 0x002e, 0x001e, 0x0005, 0x2001, 0x1836,
-	0x2004, 0xd0cc, 0x0005, 0x00c6, 0x00b6, 0x080c, 0x7207, 0x1118,
-	0x20a9, 0x0800, 0x0010, 0x20a9, 0x0782, 0x080c, 0x7207, 0x1110,
+	0x9abb, 0x080c, 0xda8f, 0x002e, 0x001e, 0x0005, 0x2001, 0x1836,
+	0x2004, 0xd0cc, 0x0005, 0x00c6, 0x00b6, 0x080c, 0x717f, 0x1118,
+	0x20a9, 0x0800, 0x0010, 0x20a9, 0x0782, 0x080c, 0x717f, 0x1110,
 	0x900e, 0x0010, 0x2009, 0x007e, 0x9180, 0x1000, 0x2004, 0x905d,
-	0x0130, 0x86ff, 0x0110, 0xb800, 0xd0bc, 0x090c, 0x6463, 0x8108,
-	0x1f04, 0x32c4, 0x2061, 0x1800, 0x607b, 0x0000, 0x607c, 0x9084,
+	0x0130, 0x86ff, 0x0110, 0xb800, 0xd0bc, 0x090c, 0x6368, 0x8108,
+	0x1f04, 0x31e4, 0x2061, 0x1800, 0x607b, 0x0000, 0x607c, 0x9084,
 	0x00ff, 0x607e, 0x60af, 0x0000, 0x00be, 0x00ce, 0x0005, 0x2001,
 	0x187d, 0x2004, 0xd0bc, 0x0005, 0x2011, 0x185c, 0x2214, 0xd2ec,
 	0x0005, 0x7eef, 0x7de8, 0x7ce4, 0x80e2, 0x7be1, 0x80e0, 0x80dc,
@@ -1457,2363 +1429,2375 @@ unsigned short risc_code01[] = { 
 	0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
 	0x8000, 0x2071, 0x189c, 0x7003, 0x0002, 0x9006, 0x7016, 0x701a,
 	0x704a, 0x704e, 0x700e, 0x7042, 0x7046, 0x703b, 0x18b8, 0x703f,
-	0x18b8, 0x7007, 0x0001, 0x080c, 0x104a, 0x090c, 0x0dfa, 0x2900,
-	0x706a, 0xa867, 0x0002, 0xa8ab, 0xdcb0, 0x080c, 0x104a, 0x090c,
-	0x0dfa, 0x2900, 0x706e, 0xa867, 0x0002, 0xa8ab, 0xdcb0, 0x0005,
-	0x2071, 0x189c, 0x7004, 0x0002, 0x3418, 0x3419, 0x342c, 0x3440,
-	0x0005, 0x1004, 0x3429, 0x0e04, 0x3429, 0x2079, 0x0000, 0x0126,
+	0x18b8, 0x7007, 0x0001, 0x080c, 0x105c, 0x090c, 0x0e02, 0x2900,
+	0x706a, 0xa867, 0x0002, 0xa8ab, 0xdcb0, 0x080c, 0x105c, 0x090c,
+	0x0e02, 0x2900, 0x706e, 0xa867, 0x0002, 0xa8ab, 0xdcb0, 0x0005,
+	0x2071, 0x189c, 0x7004, 0x0002, 0x3338, 0x3339, 0x334c, 0x3360,
+	0x0005, 0x1004, 0x3349, 0x0e04, 0x3349, 0x2079, 0x0000, 0x0126,
 	0x2091, 0x8000, 0x700c, 0x9005, 0x1128, 0x700f, 0x0001, 0x012e,
 	0x0468, 0x0005, 0x012e, 0x0ce8, 0x2079, 0x0000, 0x2061, 0x18b6,
 	0x2c4c, 0xa86c, 0x908e, 0x0100, 0x0128, 0x9086, 0x0200, 0x0904,
-	0x3514, 0x0005, 0x7018, 0x2048, 0x2061, 0x1800, 0x701c, 0x0807,
+	0x3434, 0x0005, 0x7018, 0x2048, 0x2061, 0x1800, 0x701c, 0x0807,
 	0x7014, 0x2048, 0xa864, 0x9094, 0x00ff, 0x9296, 0x0029, 0x1120,
 	0xaa78, 0xd2fc, 0x0128, 0x0005, 0x9086, 0x0103, 0x0108, 0x0005,
 	0x2079, 0x0000, 0x2061, 0x1800, 0x701c, 0x0807, 0x2061, 0x1800,
 	0x7880, 0x908a, 0x0040, 0x1210, 0x61cc, 0x0042, 0x2100, 0x908a,
-	0x003f, 0x1a04, 0x3511, 0x61cc, 0x0804, 0x34a6, 0x34e8, 0x3520,
-	0x3511, 0x352a, 0x3534, 0x353a, 0x353e, 0x354e, 0x3552, 0x3568,
-	0x356e, 0x3574, 0x357f, 0x358a, 0x3599, 0x35a8, 0x35b6, 0x35cd,
-	0x35e8, 0x3511, 0x3691, 0x36cf, 0x3775, 0x3786, 0x37a9, 0x3511,
-	0x3511, 0x3511, 0x37e1, 0x37fd, 0x3806, 0x3835, 0x383b, 0x3511,
-	0x3881, 0x3511, 0x3511, 0x3511, 0x3511, 0x3511, 0x388c, 0x3895,
-	0x389d, 0x389f, 0x3511, 0x3511, 0x3511, 0x3511, 0x3511, 0x3511,
-	0x38cb, 0x3511, 0x3511, 0x3511, 0x3511, 0x3511, 0x38e8, 0x395c,
-	0x3511, 0x3511, 0x3511, 0x3511, 0x3511, 0x3511, 0x0002, 0x3986,
-	0x3989, 0x39e8, 0x3a01, 0x3a31, 0x3ccf, 0x3511, 0x519f, 0x3511,
-	0x3511, 0x3511, 0x3511, 0x3511, 0x3511, 0x3511, 0x3511, 0x3568,
-	0x356e, 0x4249, 0x55ff, 0x425f, 0x522e, 0x527f, 0x538a, 0x3511,
-	0x53ec, 0x5428, 0x5459, 0x5561, 0x5486, 0x54e1, 0x3511, 0x4263,
-	0x4408, 0x441e, 0x4443, 0x44a8, 0x451c, 0x453c, 0x45b3, 0x460f,
-	0x466b, 0x466e, 0x4693, 0x4741, 0x47a7, 0x47af, 0x48e1, 0x4a49,
-	0x4a7d, 0x4cc7, 0x3511, 0x4ce5, 0x4da2, 0x4e78, 0x3511, 0x3511,
-	0x3511, 0x3511, 0x4ede, 0x4ef9, 0x47af, 0x513f, 0x714c, 0x0000,
-	0x2021, 0x4000, 0x080c, 0x4afb, 0x0126, 0x2091, 0x8000, 0x0e04,
-	0x34f2, 0x0010, 0x012e, 0x0cc0, 0x7c36, 0x9486, 0x4000, 0x0118,
+	0x003f, 0x1a04, 0x3431, 0x61cc, 0x0804, 0x33c6, 0x3408, 0x3440,
+	0x3431, 0x344c, 0x3456, 0x345c, 0x3460, 0x3470, 0x3474, 0x348a,
+	0x3490, 0x3496, 0x34a1, 0x34ac, 0x34bb, 0x34ca, 0x34d8, 0x34ef,
+	0x350a, 0x3431, 0x35b3, 0x35f1, 0x3697, 0x36a8, 0x36cb, 0x3431,
+	0x3431, 0x3431, 0x3703, 0x371f, 0x3728, 0x3757, 0x375d, 0x3431,
+	0x37a3, 0x3431, 0x3431, 0x3431, 0x3431, 0x3431, 0x37ae, 0x37b7,
+	0x37bf, 0x37c1, 0x3431, 0x3431, 0x3431, 0x3431, 0x3431, 0x3431,
+	0x37ed, 0x3431, 0x3431, 0x3431, 0x3431, 0x3431, 0x380a, 0x387e,
+	0x3431, 0x3431, 0x3431, 0x3431, 0x3431, 0x3431, 0x0002, 0x38a8,
+	0x38ab, 0x390a, 0x3923, 0x3953, 0x3bf5, 0x3431, 0x509f, 0x3431,
+	0x3431, 0x3431, 0x3431, 0x3431, 0x3431, 0x3431, 0x3431, 0x348a,
+	0x3490, 0x4178, 0x5500, 0x418e, 0x512e, 0x5180, 0x528b, 0x3431,
+	0x52ed, 0x5329, 0x535a, 0x5462, 0x5387, 0x53e2, 0x3431, 0x4192,
+	0x4337, 0x434d, 0x4372, 0x43d7, 0x444b, 0x446b, 0x44e2, 0x453e,
+	0x459a, 0x459d, 0x45c2, 0x4637, 0x469d, 0x46a5, 0x47da, 0x4942,
+	0x4976, 0x4bc0, 0x3431, 0x4bde, 0x4c9b, 0x4d78, 0x3431, 0x3431,
+	0x3431, 0x3431, 0x4dde, 0x4df9, 0x46a5, 0x503f, 0x714c, 0x0000,
+	0x2021, 0x4000, 0x080c, 0x49f4, 0x0126, 0x2091, 0x8000, 0x0e04,
+	0x3412, 0x0010, 0x012e, 0x0cc0, 0x7c36, 0x9486, 0x4000, 0x0118,
 	0x7833, 0x0011, 0x0010, 0x7833, 0x0010, 0x7c82, 0x7986, 0x7a8a,
 	0x7b8e, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c,
-	0x11e0, 0x7007, 0x0001, 0x2091, 0x5000, 0x700f, 0x0000, 0x012e,
+	0x11f2, 0x7007, 0x0001, 0x2091, 0x5000, 0x700f, 0x0000, 0x012e,
 	0x0005, 0x2021, 0x4001, 0x08b0, 0x2021, 0x4002, 0x0898, 0x2021,
 	0x4003, 0x0880, 0x2021, 0x4005, 0x0868, 0x2021, 0x4006, 0x0850,
 	0x2039, 0x0001, 0x902e, 0x2520, 0x7b88, 0x7a8c, 0x7884, 0x7990,
-	0x0804, 0x4b08, 0x2039, 0x0001, 0x902e, 0x2520, 0x7b88, 0x7a8c,
-	0x7884, 0x7990, 0x0804, 0x4b0b, 0x7984, 0x7888, 0x2114, 0x200a,
-	0x0804, 0x34e8, 0x7984, 0x2114, 0x0804, 0x34e8, 0x20e1, 0x0000,
-	0x2099, 0x0021, 0x20e9, 0x0000, 0x20a1, 0x0021, 0x20a9, 0x001f,
-	0x4003, 0x7984, 0x7a88, 0x7b8c, 0x0804, 0x34e8, 0x7884, 0x2060,
-	0x0804, 0x359b, 0x2009, 0x0003, 0x2011, 0x0003, 0x2019, 0x0008,
-	0x789b, 0x0317, 0x7893, 0xffff, 0x2001, 0x188d, 0x2004, 0x9005,
-	0x0118, 0x7896, 0x0804, 0x34e8, 0x7897, 0x0001, 0x0804, 0x34e8,
-	0x2039, 0x0001, 0x7d98, 0x7c9c, 0x0804, 0x3524, 0x2039, 0x0001,
-	0x7d98, 0x7c9c, 0x0804, 0x352e, 0x79a0, 0x9182, 0x0040, 0x0210,
-	0x0804, 0x351d, 0x2138, 0x7d98, 0x7c9c, 0x0804, 0x3524, 0x79a0,
-	0x9182, 0x0040, 0x0210, 0x0804, 0x351d, 0x2138, 0x7d98, 0x7c9c,
-	0x0804, 0x352e, 0x79a0, 0x9182, 0x0040, 0x0210, 0x0804, 0x351d,
-	0x21e8, 0x7984, 0x7888, 0x20a9, 0x0001, 0x21a0, 0x4004, 0x0804,
-	0x34e8, 0x2061, 0x0800, 0xe10c, 0x9006, 0x2c15, 0x9200, 0x8c60,
-	0x8109, 0x1dd8, 0x2010, 0x9005, 0x0904, 0x34e8, 0x0804, 0x3517,
-	0x79a0, 0x9182, 0x0040, 0x0210, 0x0804, 0x351d, 0x21e0, 0x20a9,
-	0x0001, 0x7984, 0x2198, 0x4012, 0x0804, 0x34e8, 0x2069, 0x185b,
-	0x7884, 0x7990, 0x911a, 0x1a04, 0x351d, 0x8019, 0x0904, 0x351d,
-	0x684a, 0x6942, 0x788c, 0x6852, 0x7888, 0x6856, 0x9006, 0x685a,
-	0x685e, 0x080c, 0x7535, 0x0804, 0x34e8, 0x2069, 0x185b, 0x7884,
-	0x7994, 0x911a, 0x1a04, 0x351d, 0x8019, 0x0904, 0x351d, 0x684e,
-	0x6946, 0x788c, 0x6862, 0x7888, 0x6866, 0x9006, 0x686a, 0x686e,
-	0x0126, 0x2091, 0x8000, 0x080c, 0x68c1, 0x012e, 0x0804, 0x34e8,
-	0x902e, 0x2520, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x351a,
-	0x7984, 0x7b88, 0x7a8c, 0x20a9, 0x0005, 0x20e9, 0x0001, 0x20a1,
-	0x18a4, 0x4101, 0x080c, 0x4abf, 0x1120, 0x2009, 0x0002, 0x0804,
-	0x351a, 0x2009, 0x0020, 0xa85c, 0x9080, 0x0019, 0xaf60, 0x080c,
-	0x4b08, 0x701f, 0x360c, 0x0005, 0xa864, 0x2008, 0x9084, 0x00ff,
-	0x9096, 0x0011, 0x0168, 0x9096, 0x0019, 0x0150, 0x9096, 0x0015,
-	0x0138, 0x9096, 0x0048, 0x0120, 0x9096, 0x0029, 0x1904, 0x351a,
-	0x810f, 0x918c, 0x00ff, 0x0904, 0x351a, 0x7112, 0x7010, 0x8001,
-	0x0560, 0x7012, 0x080c, 0x4abf, 0x1120, 0x2009, 0x0002, 0x0804,
-	0x351a, 0x2009, 0x0020, 0x7068, 0x2040, 0xa28c, 0xa390, 0xa494,
-	0xa598, 0x9290, 0x0040, 0x9399, 0x0000, 0x94a1, 0x0000, 0x95a9,
-	0x0000, 0xa85c, 0x9080, 0x0019, 0xaf60, 0x080c, 0x4b08, 0x701f,
-	0x364a, 0x0005, 0xa864, 0x9084, 0x00ff, 0x9096, 0x0002, 0x0120,
-	0x9096, 0x000a, 0x1904, 0x351a, 0x0888, 0x7014, 0x2048, 0xa868,
-	0xc0fd, 0xa86a, 0xa864, 0x9084, 0x00ff, 0x9096, 0x0029, 0x1160,
-	0xc2fd, 0xaa7a, 0x080c, 0x6037, 0x0150, 0x0126, 0x2091, 0x8000,
-	0xa87a, 0xa982, 0x012e, 0x0050, 0x080c, 0x6355, 0x1128, 0x7007,
-	0x0003, 0x701f, 0x3676, 0x0005, 0x080c, 0x6d17, 0x0126, 0x2091,
-	0x8000, 0x20a9, 0x0005, 0x20e1, 0x0001, 0x2099, 0x18a4, 0x400a,
-	0x2100, 0x9210, 0x9399, 0x0000, 0x94a1, 0x0000, 0x95a9, 0x0000,
-	0xa85c, 0x9080, 0x0019, 0x2009, 0x0020, 0x012e, 0xaf60, 0x0804,
-	0x4b0b, 0x2091, 0x8000, 0x7837, 0x4000, 0x7833, 0x0010, 0x7883,
-	0x4000, 0x7887, 0x4953, 0x788b, 0x5020, 0x788f, 0x2020, 0x2009,
-	0x017f, 0x2104, 0x7892, 0x3f00, 0x7896, 0x2061, 0x0100, 0x6200,
-	0x2061, 0x0200, 0x603c, 0x8007, 0x9205, 0x789a, 0x2009, 0x04fd,
-	0x2104, 0x789e, 0x2091, 0x5000, 0x2091, 0x4080, 0x2001, 0x0089,
-	0x2004, 0xd084, 0x0180, 0x2001, 0x19f1, 0x2004, 0x9005, 0x0128,
-	0x2001, 0x008b, 0x2004, 0xd0fc, 0x0dd8, 0x2001, 0x008a, 0x2003,
-	0x0002, 0x2003, 0x1001, 0x2071, 0x0080, 0x0804, 0x0427, 0x81ff,
-	0x1904, 0x351a, 0x7984, 0x080c, 0x649f, 0x1904, 0x351d, 0x7e98,
-	0x9684, 0x3fff, 0x9082, 0x4000, 0x1a04, 0x351d, 0x7c88, 0x7d8c,
-	0x080c, 0x6602, 0x080c, 0x65d1, 0x0000, 0x1518, 0x2061, 0x1cd0,
+	0x81ff, 0x0d98, 0x0804, 0x4a01, 0x2039, 0x0001, 0x902e, 0x2520,
+	0x7b88, 0x7a8c, 0x7884, 0x7990, 0x0804, 0x4a04, 0x7984, 0x7888,
+	0x2114, 0x200a, 0x0804, 0x3408, 0x7984, 0x2114, 0x0804, 0x3408,
+	0x20e1, 0x0000, 0x2099, 0x0021, 0x20e9, 0x0000, 0x20a1, 0x0021,
+	0x20a9, 0x001f, 0x4003, 0x7984, 0x7a88, 0x7b8c, 0x0804, 0x3408,
+	0x7884, 0x2060, 0x0804, 0x34bd, 0x2009, 0x0003, 0x2011, 0x0003,
+	0x2019, 0x000f, 0x789b, 0x0317, 0x7893, 0xffff, 0x2001, 0x188d,
+	0x2004, 0x9005, 0x0118, 0x7896, 0x0804, 0x3408, 0x7897, 0x0001,
+	0x0804, 0x3408, 0x2039, 0x0001, 0x7d98, 0x7c9c, 0x0804, 0x3444,
+	0x2039, 0x0001, 0x7d98, 0x7c9c, 0x0804, 0x3450, 0x79a0, 0x9182,
+	0x0040, 0x0210, 0x0804, 0x343d, 0x2138, 0x7d98, 0x7c9c, 0x0804,
+	0x3444, 0x79a0, 0x9182, 0x0040, 0x0210, 0x0804, 0x343d, 0x2138,
+	0x7d98, 0x7c9c, 0x0804, 0x3450, 0x79a0, 0x9182, 0x0040, 0x0210,
+	0x0804, 0x343d, 0x21e8, 0x7984, 0x7888, 0x20a9, 0x0001, 0x21a0,
+	0x4004, 0x0804, 0x3408, 0x2061, 0x0800, 0xe10c, 0x9006, 0x2c15,
+	0x9200, 0x8c60, 0x8109, 0x1dd8, 0x2010, 0x9005, 0x0904, 0x3408,
+	0x0804, 0x3437, 0x79a0, 0x9182, 0x0040, 0x0210, 0x0804, 0x343d,
+	0x21e0, 0x20a9, 0x0001, 0x7984, 0x2198, 0x4012, 0x0804, 0x3408,
+	0x2069, 0x185b, 0x7884, 0x7990, 0x911a, 0x1a04, 0x343d, 0x8019,
+	0x0904, 0x343d, 0x684a, 0x6942, 0x788c, 0x6852, 0x7888, 0x6856,
+	0x9006, 0x685a, 0x685e, 0x080c, 0x74ac, 0x0804, 0x3408, 0x2069,
+	0x185b, 0x7884, 0x7994, 0x911a, 0x1a04, 0x343d, 0x8019, 0x0904,
+	0x343d, 0x684e, 0x6946, 0x788c, 0x6862, 0x7888, 0x6866, 0x9006,
+	0x686a, 0x686e, 0x0126, 0x2091, 0x8000, 0x080c, 0x67fa, 0x012e,
+	0x0804, 0x3408, 0x902e, 0x2520, 0x81ff, 0x0120, 0x2009, 0x0001,
+	0x0804, 0x343a, 0x7984, 0x7b88, 0x7a8c, 0x20a9, 0x0005, 0x20e9,
+	0x0001, 0x20a1, 0x18a4, 0x4101, 0x080c, 0x49b8, 0x1120, 0x2009,
+	0x0002, 0x0804, 0x343a, 0x2009, 0x0020, 0xa85c, 0x9080, 0x0019,
+	0xaf60, 0x080c, 0x4a01, 0x701f, 0x352e, 0x0005, 0xa864, 0x2008,
+	0x9084, 0x00ff, 0x9096, 0x0011, 0x0168, 0x9096, 0x0019, 0x0150,
+	0x9096, 0x0015, 0x0138, 0x9096, 0x0048, 0x0120, 0x9096, 0x0029,
+	0x1904, 0x343a, 0x810f, 0x918c, 0x00ff, 0x0904, 0x343a, 0x7112,
+	0x7010, 0x8001, 0x0560, 0x7012, 0x080c, 0x49b8, 0x1120, 0x2009,
+	0x0002, 0x0804, 0x343a, 0x2009, 0x0020, 0x7068, 0x2040, 0xa28c,
+	0xa390, 0xa494, 0xa598, 0x9290, 0x0040, 0x9399, 0x0000, 0x94a1,
+	0x0000, 0x95a9, 0x0000, 0xa85c, 0x9080, 0x0019, 0xaf60, 0x080c,
+	0x4a01, 0x701f, 0x356c, 0x0005, 0xa864, 0x9084, 0x00ff, 0x9096,
+	0x0002, 0x0120, 0x9096, 0x000a, 0x1904, 0x343a, 0x0888, 0x7014,
+	0x2048, 0xa868, 0xc0fd, 0xa86a, 0xa864, 0x9084, 0x00ff, 0x9096,
+	0x0029, 0x1160, 0xc2fd, 0xaa7a, 0x080c, 0x5f3c, 0x0150, 0x0126,
+	0x2091, 0x8000, 0xa87a, 0xa982, 0x012e, 0x0050, 0x080c, 0x625a,
+	0x1128, 0x7007, 0x0003, 0x701f, 0x3598, 0x0005, 0x080c, 0x6c6c,
+	0x0126, 0x2091, 0x8000, 0x20a9, 0x0005, 0x20e1, 0x0001, 0x2099,
+	0x18a4, 0x400a, 0x2100, 0x9210, 0x9399, 0x0000, 0x94a1, 0x0000,
+	0x95a9, 0x0000, 0xa85c, 0x9080, 0x0019, 0x2009, 0x0020, 0x012e,
+	0xaf60, 0x0804, 0x4a04, 0x2091, 0x8000, 0x7837, 0x4000, 0x7833,
+	0x0010, 0x7883, 0x4000, 0x7887, 0x4953, 0x788b, 0x5020, 0x788f,
+	0x2020, 0x2009, 0x017f, 0x2104, 0x7892, 0x3f00, 0x7896, 0x2061,
+	0x0100, 0x6200, 0x2061, 0x0200, 0x603c, 0x8007, 0x9205, 0x789a,
+	0x2009, 0x04fd, 0x2104, 0x789e, 0x2091, 0x5000, 0x2091, 0x4080,
+	0x2001, 0x0089, 0x2004, 0xd084, 0x0180, 0x2001, 0x19f6, 0x2004,
+	0x9005, 0x0128, 0x2001, 0x008b, 0x2004, 0xd0fc, 0x0dd8, 0x2001,
+	0x008a, 0x2003, 0x0002, 0x2003, 0x1001, 0x2071, 0x0080, 0x0804,
+	0x0427, 0x81ff, 0x1904, 0x343a, 0x7984, 0x080c, 0x63a4, 0x1904,
+	0x343d, 0x7e98, 0x9684, 0x3fff, 0x9082, 0x4000, 0x1a04, 0x343d,
+	0x7c88, 0x7d8c, 0x080c, 0x6507, 0x080c, 0x64d6, 0x0000, 0x1518,
+	0x2061, 0x1cd0, 0x0126, 0x2091, 0x8000, 0x6000, 0x9086, 0x0000,
+	0x0148, 0x6014, 0x904d, 0x0130, 0xa86c, 0x9406, 0x1118, 0xa870,
+	0x9506, 0x0150, 0x012e, 0x9ce0, 0x0018, 0x2001, 0x1819, 0x2004,
+	0x9c02, 0x1a04, 0x343a, 0x0c30, 0x080c, 0xb974, 0x012e, 0x0904,
+	0x343a, 0x0804, 0x3408, 0x900e, 0x2001, 0x0005, 0x080c, 0x6c6c,
+	0x0126, 0x2091, 0x8000, 0x080c, 0xc037, 0x080c, 0x6a23, 0x012e,
+	0x0804, 0x3408, 0x00a6, 0x2950, 0xb198, 0x080c, 0x63a4, 0x1904,
+	0x3684, 0xb6a4, 0x9684, 0x3fff, 0x9082, 0x4000, 0x16e8, 0xb49c,
+	0xb5a0, 0x080c, 0x6507, 0x080c, 0x64d6, 0x1520, 0x2061, 0x1cd0,
 	0x0126, 0x2091, 0x8000, 0x6000, 0x9086, 0x0000, 0x0148, 0x6014,
-	0x904d, 0x0130, 0xa86c, 0x9406, 0x1118, 0xa870, 0x9506, 0x0150,
-	0x012e, 0x9ce0, 0x0018, 0x2001, 0x1819, 0x2004, 0x9c02, 0x1a04,
-	0x351a, 0x0c30, 0x080c, 0xba56, 0x012e, 0x0904, 0x351a, 0x0804,
-	0x34e8, 0x900e, 0x2001, 0x0005, 0x080c, 0x6d17, 0x0126, 0x2091,
-	0x8000, 0x080c, 0xc133, 0x080c, 0x6ae9, 0x012e, 0x0804, 0x34e8,
-	0x00a6, 0x2950, 0xb198, 0x080c, 0x649f, 0x1904, 0x3762, 0xb6a4,
-	0x9684, 0x3fff, 0x9082, 0x4000, 0x16e8, 0xb49c, 0xb5a0, 0x080c,
-	0x6602, 0x080c, 0x65d1, 0x1520, 0x2061, 0x1cd0, 0x0126, 0x2091,
-	0x8000, 0x6000, 0x9086, 0x0000, 0x0148, 0x6014, 0x904d, 0x0130,
-	0xa86c, 0x9406, 0x1118, 0xa870, 0x9506, 0x0158, 0x012e, 0x9ce0,
-	0x0018, 0x2001, 0x1819, 0x2004, 0x9c02, 0x2009, 0x000d, 0x12b0,
-	0x0c28, 0x080c, 0xba56, 0x012e, 0x2009, 0x0003, 0x0178, 0x00e0,
-	0x900e, 0x2001, 0x0005, 0x080c, 0x6d17, 0x0126, 0x2091, 0x8000,
-	0x080c, 0xc133, 0x080c, 0x6adc, 0x012e, 0x0070, 0xb097, 0x4005,
-	0xb19a, 0x0010, 0xb097, 0x4006, 0x900e, 0x9085, 0x0001, 0x2001,
-	0x0030, 0x2a48, 0x00ae, 0x0005, 0xb097, 0x4000, 0x9006, 0x918d,
-	0x0001, 0x2008, 0x2a48, 0x00ae, 0x0005, 0x81ff, 0x1904, 0x351a,
-	0x080c, 0x4ad6, 0x0904, 0x351d, 0x080c, 0x6566, 0x0904, 0x351a,
-	0x080c, 0x6608, 0x0904, 0x351a, 0x0804, 0x4533, 0x81ff, 0x1904,
-	0x351a, 0x080c, 0x4af2, 0x0904, 0x351d, 0x080c, 0x6696, 0x0904,
-	0x351a, 0x2019, 0x0005, 0x79a8, 0x080c, 0x6623, 0x0904, 0x351a,
-	0x7888, 0x908a, 0x1000, 0x1a04, 0x351d, 0x8003, 0x800b, 0x810b,
-	0x9108, 0x080c, 0x82e8, 0x7984, 0xd184, 0x1904, 0x34e8, 0x0804,
-	0x4533, 0x0126, 0x2091, 0x8000, 0x81ff, 0x0118, 0x2009, 0x0001,
-	0x0450, 0x2029, 0x07ff, 0x6458, 0x2400, 0x9506, 0x01f8, 0x2508,
-	0x080c, 0x649f, 0x11d8, 0x080c, 0x6696, 0x1128, 0x2009, 0x0002,
-	0x62bc, 0x2518, 0x00c0, 0x2019, 0x0004, 0x900e, 0x080c, 0x6623,
-	0x1118, 0x2009, 0x0006, 0x0078, 0x7884, 0x908a, 0x1000, 0x1270,
-	0x8003, 0x800b, 0x810b, 0x9108, 0x080c, 0x82e8, 0x8529, 0x1ae0,
-	0x012e, 0x0804, 0x34e8, 0x012e, 0x0804, 0x351a, 0x012e, 0x0804,
-	0x351d, 0x080c, 0x4ad6, 0x0904, 0x351d, 0x080c, 0x6566, 0x0904,
-	0x351a, 0xbaa0, 0x2019, 0x0005, 0x00c6, 0x9066, 0x080c, 0x8803,
-	0x0076, 0x903e, 0x080c, 0x86f1, 0x900e, 0x080c, 0xd5f6, 0x007e,
-	0x00ce, 0x080c, 0x6602, 0x0804, 0x34e8, 0x080c, 0x4ad6, 0x0904,
-	0x351d, 0x080c, 0x6602, 0x2208, 0x0804, 0x34e8, 0x0156, 0x00d6,
-	0x00e6, 0x2069, 0x190e, 0x6810, 0x6914, 0x910a, 0x1208, 0x900e,
-	0x6816, 0x9016, 0x901e, 0x20a9, 0x007e, 0x2069, 0x1000, 0x2d04,
-	0x905d, 0x0118, 0xb84c, 0x0059, 0x9210, 0x8d68, 0x1f04, 0x3817,
-	0x2300, 0x9218, 0x00ee, 0x00de, 0x015e, 0x0804, 0x34e8, 0x00f6,
-	0x0016, 0x907d, 0x0138, 0x9006, 0x8000, 0x2f0c, 0x81ff, 0x0110,
-	0x2178, 0x0cd0, 0x001e, 0x00fe, 0x0005, 0x2069, 0x190e, 0x6910,
-	0x62b8, 0x0804, 0x34e8, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804,
-	0x351a, 0x0126, 0x2091, 0x8000, 0x080c, 0x55ef, 0x0128, 0x2009,
-	0x0007, 0x012e, 0x0804, 0x351a, 0x012e, 0x6158, 0x9190, 0x32e9,
-	0x2215, 0x9294, 0x00ff, 0x6378, 0x83ff, 0x0108, 0x627c, 0x67d8,
-	0x97c4, 0x000a, 0x98c6, 0x000a, 0x1118, 0x2031, 0x0001, 0x00e8,
-	0x97c4, 0x0022, 0x98c6, 0x0022, 0x1118, 0x2031, 0x0003, 0x00a8,
-	0x97c4, 0x0012, 0x98c6, 0x0012, 0x1118, 0x2031, 0x0002, 0x0068,
-	0x080c, 0x7207, 0x1118, 0x2031, 0x0004, 0x0038, 0xd79c, 0x0120,
-	0x2009, 0x0005, 0x0804, 0x351a, 0x9036, 0x7e9a, 0x7f9e, 0x0804,
-	0x34e8, 0x6148, 0x624c, 0x2019, 0x195e, 0x231c, 0x2001, 0x195f,
-	0x2004, 0x789a, 0x0804, 0x34e8, 0x0126, 0x2091, 0x8000, 0x6138,
-	0x623c, 0x6340, 0x012e, 0x0804, 0x34e8, 0x080c, 0x4af2, 0x0904,
-	0x351d, 0xba44, 0xbb38, 0x0804, 0x34e8, 0x080c, 0x0dfa, 0x080c,
-	0x4af2, 0x2110, 0x0904, 0x351d, 0xb804, 0x908c, 0x00ff, 0x918e,
-	0x0006, 0x0140, 0x9084, 0xff00, 0x9086, 0x0600, 0x2009, 0x0009,
-	0x1904, 0x351a, 0x0126, 0x2091, 0x8000, 0x2019, 0x0005, 0x00c6,
-	0x9066, 0x080c, 0x9bc9, 0x080c, 0x8803, 0x0076, 0x903e, 0x080c,
-	0x86f1, 0x900e, 0x080c, 0xd5f6, 0x007e, 0x00ce, 0xb807, 0x0407,
-	0x012e, 0x0804, 0x34e8, 0x6148, 0x624c, 0x7884, 0x604a, 0x7b88,
-	0x634e, 0x2069, 0x185b, 0x831f, 0x9305, 0x6816, 0x788c, 0x2069,
-	0x195e, 0x2d1c, 0x206a, 0x7e98, 0x9682, 0x0014, 0x1210, 0x2031,
-	0x07d0, 0x2069, 0x195f, 0x2d04, 0x266a, 0x789a, 0x0804, 0x34e8,
-	0x0126, 0x2091, 0x8000, 0x6138, 0x7884, 0x603a, 0x910e, 0xd1b4,
-	0x190c, 0x0ee1, 0xd0c4, 0x01a8, 0x00d6, 0x78a8, 0x2009, 0x1975,
-	0x200a, 0x78ac, 0x2011, 0x1976, 0x2012, 0x2069, 0x0100, 0x6838,
-	0x9086, 0x0007, 0x1118, 0x2214, 0x6a5a, 0x0010, 0x210c, 0x695a,
-	0x00de, 0x2001, 0x0100, 0x2004, 0x9086, 0x000a, 0x0168, 0x2011,
-	0x0114, 0x220c, 0x7888, 0xd08c, 0x0118, 0x918d, 0x0080, 0x0010,
-	0x918c, 0xff7f, 0x2112, 0x0060, 0x2011, 0x0116, 0x220c, 0x7888,
-	0xd08c, 0x0118, 0x918d, 0x0040, 0x0010, 0x918c, 0xff7f, 0x2112,
-	0x603c, 0x7988, 0x613e, 0x6140, 0x910d, 0x788c, 0x6042, 0x7a88,
-	0x9294, 0x1000, 0x9205, 0x910e, 0xd1e4, 0x190c, 0x0ef7, 0x6040,
-	0xd0cc, 0x0120, 0x78b0, 0x2011, 0x0114, 0x2012, 0x012e, 0x0804,
-	0x34e8, 0x00f6, 0x2079, 0x1800, 0x7a38, 0xa898, 0x9084, 0xfebf,
-	0x9215, 0xa89c, 0x9084, 0xfebf, 0x8002, 0x9214, 0x7838, 0x9084,
-	0x0140, 0x9215, 0x7a3a, 0xa897, 0x4000, 0x900e, 0x9085, 0x0001,
-	0x2001, 0x0000, 0x00fe, 0x0005, 0x7898, 0x9005, 0x01a8, 0x7888,
-	0x9025, 0x0904, 0x351d, 0x788c, 0x902d, 0x0904, 0x351d, 0x900e,
-	0x080c, 0x649f, 0x1120, 0xba44, 0xbb38, 0xbc46, 0xbd3a, 0x9186,
-	0x07ff, 0x0190, 0x8108, 0x0ca0, 0x080c, 0x4af2, 0x0904, 0x351d,
-	0x7888, 0x900d, 0x0904, 0x351d, 0x788c, 0x9005, 0x0904, 0x351d,
-	0xba44, 0xb946, 0xbb38, 0xb83a, 0x0804, 0x34e8, 0x2011, 0xbc09,
-	0x0010, 0x2011, 0xbc05, 0x080c, 0x55ef, 0x1904, 0x351a, 0x00c6,
-	0x2061, 0x0100, 0x7984, 0x9186, 0x00ff, 0x1130, 0x2001, 0x1817,
-	0x2004, 0x9085, 0xff00, 0x0088, 0x9182, 0x007f, 0x16e0, 0x9188,
-	0x32e9, 0x210d, 0x918c, 0x00ff, 0x2001, 0x1817, 0x2004, 0x0026,
-	0x9116, 0x002e, 0x0580, 0x810f, 0x9105, 0x0126, 0x2091, 0x8000,
-	0x0006, 0x080c, 0xa08d, 0x000e, 0x0510, 0x602e, 0x620a, 0x7984,
-	0x00b6, 0x080c, 0x6445, 0x2b08, 0x00be, 0x1500, 0x6112, 0x6023,
-	0x0001, 0x080c, 0x4abf, 0x01d0, 0x9006, 0xa866, 0x7007, 0x0003,
-	0xa832, 0xa868, 0xc0fd, 0xa86a, 0x701f, 0x39e1, 0x2900, 0x6016,
-	0x2009, 0x0032, 0x080c, 0xa15d, 0x012e, 0x00ce, 0x0005, 0x012e,
-	0x00ce, 0x0804, 0x351a, 0x00ce, 0x0804, 0x351d, 0x080c, 0xa0e3,
-	0x0cb0, 0xa830, 0x9086, 0x0100, 0x0904, 0x351a, 0x0804, 0x34e8,
-	0x2061, 0x1a48, 0x0126, 0x2091, 0x8000, 0x6000, 0xd084, 0x0170,
-	0x6104, 0x6208, 0x2061, 0x1800, 0x6350, 0x6070, 0x789a, 0x60bc,
-	0x789e, 0x60b8, 0x78aa, 0x012e, 0x0804, 0x34e8, 0x900e, 0x2110,
-	0x0c88, 0x81ff, 0x1904, 0x351a, 0x080c, 0x7207, 0x0904, 0x351a,
-	0x0126, 0x2091, 0x8000, 0x6250, 0x6070, 0x9202, 0x0248, 0x9085,
-	0x0001, 0x080c, 0x27d7, 0x080c, 0x580e, 0x012e, 0x0804, 0x34e8,
-	0x012e, 0x0804, 0x351d, 0x0006, 0x0016, 0x00c6, 0x00e6, 0x2001,
-	0x1981, 0x2070, 0x2061, 0x185b, 0x6008, 0x2072, 0x900e, 0x2011,
-	0x1400, 0x080c, 0x84ff, 0x7206, 0x00ee, 0x00ce, 0x001e, 0x000e,
-	0x0005, 0x0126, 0x2091, 0x8000, 0x81ff, 0x0128, 0x012e, 0x2021,
-	0x400b, 0x0804, 0x34ea, 0x7884, 0xd0fc, 0x0148, 0x2001, 0x002a,
-	0x2004, 0x9082, 0x00e1, 0x0288, 0x012e, 0x0804, 0x351d, 0x2001,
-	0x002a, 0x2004, 0x2069, 0x185b, 0x6908, 0x9102, 0x1230, 0x012e,
-	0x0804, 0x351d, 0x012e, 0x0804, 0x351a, 0x080c, 0xa062, 0x0dd0,
-	0x7884, 0xd0fc, 0x0904, 0x3aac, 0x00c6, 0x080c, 0x4abf, 0x00ce,
-	0x0d88, 0xa867, 0x0000, 0x7884, 0xa80a, 0x7898, 0xa80e, 0x789c,
-	0xa812, 0x2001, 0x002e, 0x2004, 0xa81a, 0x2001, 0x002f, 0x2004,
-	0xa81e, 0x2001, 0x0030, 0x2004, 0xa822, 0x2001, 0x0031, 0x2004,
-	0xa826, 0x2001, 0x0034, 0x2004, 0xa82a, 0x2001, 0x0035, 0x2004,
-	0xa82e, 0x2001, 0x002a, 0x2004, 0x9080, 0x0003, 0x9084, 0x00fc,
-	0x8004, 0xa816, 0x080c, 0x3c32, 0x0928, 0x7014, 0x2048, 0xad2c,
-	0xac28, 0xab1c, 0xaa18, 0xa930, 0xa808, 0xd0b4, 0x1120, 0x2029,
-	0x0000, 0x2021, 0x0000, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f,
-	0x9084, 0xffc0, 0x9080, 0x001b, 0x080c, 0x4b08, 0x701f, 0x3b6f,
-	0x7023, 0x0001, 0x012e, 0x0005, 0x0046, 0x0086, 0x0096, 0x00a6,
-	0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x080c, 0x3a1b, 0x2001,
-	0x1977, 0x2003, 0x0000, 0x2021, 0x000a, 0x2061, 0x0100, 0x6104,
-	0x0016, 0x60bb, 0x0000, 0x60bf, 0x32e1, 0x60bf, 0x0012, 0x080c,
-	0x3ca1, 0x080c, 0x3c60, 0x00f6, 0x00e6, 0x0086, 0x2940, 0x2071,
-	0x1a3d, 0x2079, 0x0090, 0x00d6, 0x2069, 0x0000, 0x6884, 0xd0b4,
-	0x0140, 0x2001, 0x0035, 0x2004, 0x780e, 0x2001, 0x0034, 0x2004,
-	0x780a, 0x00de, 0x2011, 0x0001, 0x080c, 0x408d, 0x008e, 0x00ee,
-	0x00fe, 0x080c, 0x3fba, 0x080c, 0x3e7f, 0x05b8, 0x2001, 0x020b,
-	0x2004, 0x9084, 0x0140, 0x1db8, 0x080c, 0x4101, 0x00f6, 0x2079,
-	0x0300, 0x78bc, 0x00fe, 0x908c, 0x0070, 0x1560, 0x2071, 0x0200,
-	0x7037, 0x0000, 0x7050, 0x9084, 0xff00, 0x9086, 0x3200, 0x1510,
-	0x7037, 0x0001, 0x7050, 0x9084, 0xff00, 0x9086, 0xe100, 0x11d0,
-	0x7037, 0x0000, 0x7054, 0x7037, 0x0000, 0x715c, 0x9106, 0x1190,
-	0x2001, 0x181f, 0x2004, 0x9106, 0x1168, 0x00c6, 0x2061, 0x0100,
-	0x6024, 0x9084, 0x1e00, 0x00ce, 0x0138, 0x080c, 0x3e89, 0x080c,
-	0x3c5b, 0x0058, 0x080c, 0x3c5b, 0x080c, 0x4025, 0x080c, 0x3fb0,
-	0x2001, 0x020b, 0x2004, 0xd0e4, 0x0dd8, 0x2001, 0x032a, 0x2003,
-	0x0004, 0x2061, 0x0100, 0x6027, 0x0002, 0x001e, 0x6106, 0x2011,
-	0x020d, 0x2013, 0x0020, 0x60bb, 0x0000, 0x60bf, 0x0108, 0x60bf,
-	0x0012, 0x2001, 0x0004, 0x200c, 0x918c, 0xfffd, 0x2102, 0x080c,
-	0x12f8, 0x2009, 0x0028, 0x080c, 0x230a, 0x2001, 0x0227, 0x200c,
-	0x2102, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x00ae, 0x009e,
-	0x008e, 0x004e, 0x2001, 0x1977, 0x2004, 0x9005, 0x1118, 0x012e,
-	0x0804, 0x34e8, 0x012e, 0x2021, 0x400c, 0x0804, 0x34ea, 0x0016,
-	0x0026, 0x0036, 0x0046, 0x0056, 0x0076, 0x0086, 0x0096, 0x00d6,
-	0x0156, 0x7014, 0x2048, 0x7020, 0x20a8, 0x8000, 0x7022, 0xa804,
-	0x9005, 0x0904, 0x3bcb, 0x2048, 0x1f04, 0x3b7f, 0x7068, 0x2040,
-	0xa28c, 0xa390, 0xa494, 0xa598, 0xa930, 0xa808, 0xd0b4, 0x1120,
-	0x2029, 0x0000, 0x2021, 0x0000, 0x0096, 0x7014, 0x2048, 0xa864,
-	0x009e, 0x9086, 0x0103, 0x0170, 0x8906, 0x8006, 0x8007, 0x90bc,
-	0x003f, 0x9084, 0xffc0, 0x9080, 0x001b, 0x080c, 0x4b08, 0x701f,
-	0x3b6f, 0x00b0, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084,
-	0xffc0, 0x9080, 0x001b, 0x21a8, 0x27e0, 0x2098, 0x27e8, 0x20a0,
-	0x0006, 0x080c, 0x0fae, 0x000e, 0x080c, 0x4b0b, 0x701f, 0x3b6f,
-	0x015e, 0x00de, 0x009e, 0x008e, 0x007e, 0x005e, 0x004e, 0x003e,
-	0x002e, 0x001e, 0x0005, 0x7014, 0x2048, 0xa864, 0x9086, 0x0103,
-	0x1118, 0x701f, 0x3c30, 0x0450, 0x7014, 0x2048, 0xa868, 0xc0fd,
-	0xa86a, 0x2009, 0x007f, 0x080c, 0x643f, 0x0110, 0x9006, 0x0030,
-	0xb813, 0x00ff, 0xb817, 0xfffd, 0x080c, 0xc302, 0x015e, 0x00de,
+	0x904d, 0x0130, 0xa86c, 0x9406, 0x1118, 0xa870, 0x9506, 0x0158,
+	0x012e, 0x9ce0, 0x0018, 0x2001, 0x1819, 0x2004, 0x9c02, 0x2009,
+	0x000d, 0x12b0, 0x0c28, 0x080c, 0xb974, 0x012e, 0x2009, 0x0003,
+	0x0178, 0x00e0, 0x900e, 0x2001, 0x0005, 0x080c, 0x6c6c, 0x0126,
+	0x2091, 0x8000, 0x080c, 0xc037, 0x080c, 0x6a16, 0x012e, 0x0070,
+	0xb097, 0x4005, 0xb19a, 0x0010, 0xb097, 0x4006, 0x900e, 0x9085,
+	0x0001, 0x2001, 0x0030, 0x2a48, 0x00ae, 0x0005, 0xb097, 0x4000,
+	0x9006, 0x918d, 0x0001, 0x2008, 0x2a48, 0x00ae, 0x0005, 0x81ff,
+	0x1904, 0x343a, 0x080c, 0x49cf, 0x0904, 0x343d, 0x080c, 0x646b,
+	0x0904, 0x343a, 0x080c, 0x650d, 0x0904, 0x343a, 0x0804, 0x4462,
+	0x81ff, 0x1904, 0x343a, 0x080c, 0x49eb, 0x0904, 0x343d, 0x080c,
+	0x659b, 0x0904, 0x343a, 0x2019, 0x0005, 0x79a8, 0x080c, 0x6528,
+	0x0904, 0x343a, 0x7888, 0x908a, 0x1000, 0x1a04, 0x343d, 0x8003,
+	0x800b, 0x810b, 0x9108, 0x080c, 0x8268, 0x79a8, 0xd184, 0x1904,
+	0x3408, 0x0804, 0x4462, 0x0126, 0x2091, 0x8000, 0x81ff, 0x0118,
+	0x2009, 0x0001, 0x0450, 0x2029, 0x07ff, 0x6458, 0x2400, 0x9506,
+	0x01f8, 0x2508, 0x080c, 0x63a4, 0x11d8, 0x080c, 0x659b, 0x1128,
+	0x2009, 0x0002, 0x62bc, 0x2518, 0x00c0, 0x2019, 0x0004, 0x900e,
+	0x080c, 0x6528, 0x1118, 0x2009, 0x0006, 0x0078, 0x7884, 0x908a,
+	0x1000, 0x1270, 0x8003, 0x800b, 0x810b, 0x9108, 0x080c, 0x8268,
+	0x8529, 0x1ae0, 0x012e, 0x0804, 0x3408, 0x012e, 0x0804, 0x343a,
+	0x012e, 0x0804, 0x343d, 0x080c, 0x49cf, 0x0904, 0x343d, 0x080c,
+	0x646b, 0x0904, 0x343a, 0xbaa0, 0x2019, 0x0005, 0x00c6, 0x9066,
+	0x080c, 0x8783, 0x0076, 0x903e, 0x080c, 0x8671, 0x900e, 0x080c,
+	0xd53b, 0x007e, 0x00ce, 0x080c, 0x6507, 0x0804, 0x3408, 0x080c,
+	0x49cf, 0x0904, 0x343d, 0x080c, 0x6507, 0x2208, 0x0804, 0x3408,
+	0x0156, 0x00d6, 0x00e6, 0x2069, 0x190e, 0x6810, 0x6914, 0x910a,
+	0x1208, 0x900e, 0x6816, 0x9016, 0x901e, 0x20a9, 0x007e, 0x2069,
+	0x1000, 0x2d04, 0x905d, 0x0118, 0xb84c, 0x0059, 0x9210, 0x8d68,
+	0x1f04, 0x3739, 0x2300, 0x9218, 0x00ee, 0x00de, 0x015e, 0x0804,
+	0x3408, 0x00f6, 0x0016, 0x907d, 0x0138, 0x9006, 0x8000, 0x2f0c,
+	0x81ff, 0x0110, 0x2178, 0x0cd0, 0x001e, 0x00fe, 0x0005, 0x2069,
+	0x190e, 0x6910, 0x62b8, 0x0804, 0x3408, 0x81ff, 0x0120, 0x2009,
+	0x0001, 0x0804, 0x343a, 0x0126, 0x2091, 0x8000, 0x080c, 0x54f0,
+	0x0128, 0x2009, 0x0007, 0x012e, 0x0804, 0x343a, 0x012e, 0x6158,
+	0x9190, 0x3209, 0x2215, 0x9294, 0x00ff, 0x6378, 0x83ff, 0x0108,
+	0x627c, 0x67d8, 0x97c4, 0x000a, 0x98c6, 0x000a, 0x1118, 0x2031,
+	0x0001, 0x00e8, 0x97c4, 0x0022, 0x98c6, 0x0022, 0x1118, 0x2031,
+	0x0003, 0x00a8, 0x97c4, 0x0012, 0x98c6, 0x0012, 0x1118, 0x2031,
+	0x0002, 0x0068, 0x080c, 0x717f, 0x1118, 0x2031, 0x0004, 0x0038,
+	0xd79c, 0x0120, 0x2009, 0x0005, 0x0804, 0x343a, 0x9036, 0x7e9a,
+	0x7f9e, 0x0804, 0x3408, 0x6148, 0x624c, 0x2019, 0x1960, 0x231c,
+	0x2001, 0x1961, 0x2004, 0x789a, 0x0804, 0x3408, 0x0126, 0x2091,
+	0x8000, 0x6138, 0x623c, 0x6340, 0x012e, 0x0804, 0x3408, 0x080c,
+	0x49eb, 0x0904, 0x343d, 0xba44, 0xbb38, 0x0804, 0x3408, 0x080c,
+	0x0e02, 0x080c, 0x49eb, 0x2110, 0x0904, 0x343d, 0xb804, 0x908c,
+	0x00ff, 0x918e, 0x0006, 0x0140, 0x9084, 0xff00, 0x9086, 0x0600,
+	0x2009, 0x0009, 0x1904, 0x343a, 0x0126, 0x2091, 0x8000, 0x2019,
+	0x0005, 0x00c6, 0x9066, 0x080c, 0x9abb, 0x080c, 0x8783, 0x0076,
+	0x903e, 0x080c, 0x8671, 0x900e, 0x080c, 0xd53b, 0x007e, 0x00ce,
+	0xb807, 0x0407, 0x012e, 0x0804, 0x3408, 0x6148, 0x624c, 0x7884,
+	0x604a, 0x7b88, 0x634e, 0x2069, 0x185b, 0x831f, 0x9305, 0x6816,
+	0x788c, 0x2069, 0x1960, 0x2d1c, 0x206a, 0x7e98, 0x9682, 0x0014,
+	0x1210, 0x2031, 0x07d0, 0x2069, 0x1961, 0x2d04, 0x266a, 0x789a,
+	0x0804, 0x3408, 0x0126, 0x2091, 0x8000, 0x6138, 0x7884, 0x603a,
+	0x910e, 0xd1b4, 0x190c, 0x0ef3, 0xd0c4, 0x01a8, 0x00d6, 0x78a8,
+	0x2009, 0x1977, 0x200a, 0x78ac, 0x2011, 0x1978, 0x2012, 0x2069,
+	0x0100, 0x6838, 0x9086, 0x0007, 0x1118, 0x2214, 0x6a5a, 0x0010,
+	0x210c, 0x695a, 0x00de, 0x2001, 0x0100, 0x2004, 0x9086, 0x000a,
+	0x0168, 0x2011, 0x0114, 0x220c, 0x7888, 0xd08c, 0x0118, 0x918d,
+	0x0080, 0x0010, 0x918c, 0xff7f, 0x2112, 0x0060, 0x2011, 0x0116,
+	0x220c, 0x7888, 0xd08c, 0x0118, 0x918d, 0x0040, 0x0010, 0x918c,
+	0xff7f, 0x2112, 0x603c, 0x7988, 0x613e, 0x6140, 0x910d, 0x788c,
+	0x6042, 0x7a88, 0x9294, 0x1000, 0x9205, 0x910e, 0xd1e4, 0x190c,
+	0x0f09, 0x6040, 0xd0cc, 0x0120, 0x78b0, 0x2011, 0x0114, 0x2012,
+	0x012e, 0x0804, 0x3408, 0x00f6, 0x2079, 0x1800, 0x7a38, 0xa898,
+	0x9084, 0xfebf, 0x9215, 0xa89c, 0x9084, 0xfebf, 0x8002, 0x9214,
+	0x7838, 0x9084, 0x0140, 0x9215, 0x7a3a, 0xa897, 0x4000, 0x900e,
+	0x9085, 0x0001, 0x2001, 0x0000, 0x00fe, 0x0005, 0x7898, 0x9005,
+	0x01a8, 0x7888, 0x9025, 0x0904, 0x343d, 0x788c, 0x902d, 0x0904,
+	0x343d, 0x900e, 0x080c, 0x63a4, 0x1120, 0xba44, 0xbb38, 0xbc46,
+	0xbd3a, 0x9186, 0x07ff, 0x0190, 0x8108, 0x0ca0, 0x080c, 0x49eb,
+	0x0904, 0x343d, 0x7888, 0x900d, 0x0904, 0x343d, 0x788c, 0x9005,
+	0x0904, 0x343d, 0xba44, 0xb946, 0xbb38, 0xb83a, 0x0804, 0x3408,
+	0x2011, 0xbc09, 0x0010, 0x2011, 0xbc05, 0x080c, 0x54f0, 0x1904,
+	0x343a, 0x00c6, 0x2061, 0x0100, 0x7984, 0x9186, 0x00ff, 0x1130,
+	0x2001, 0x1817, 0x2004, 0x9085, 0xff00, 0x0088, 0x9182, 0x007f,
+	0x16e0, 0x9188, 0x3209, 0x210d, 0x918c, 0x00ff, 0x2001, 0x1817,
+	0x2004, 0x0026, 0x9116, 0x002e, 0x0580, 0x810f, 0x9105, 0x0126,
+	0x2091, 0x8000, 0x0006, 0x080c, 0x9f7f, 0x000e, 0x0510, 0x602e,
+	0x620a, 0x7984, 0x00b6, 0x080c, 0x634a, 0x2b08, 0x00be, 0x1500,
+	0x6112, 0x6023, 0x0001, 0x080c, 0x49b8, 0x01d0, 0x9006, 0xa866,
+	0x7007, 0x0003, 0xa832, 0xa868, 0xc0fd, 0xa86a, 0x701f, 0x3903,
+	0x2900, 0x6016, 0x2009, 0x0032, 0x080c, 0xa053, 0x012e, 0x00ce,
+	0x0005, 0x012e, 0x00ce, 0x0804, 0x343a, 0x00ce, 0x0804, 0x343d,
+	0x080c, 0x9fd5, 0x0cb0, 0xa830, 0x9086, 0x0100, 0x0904, 0x343a,
+	0x0804, 0x3408, 0x2061, 0x1a4c, 0x0126, 0x2091, 0x8000, 0x6000,
+	0xd084, 0x0170, 0x6104, 0x6208, 0x2061, 0x1800, 0x6350, 0x6070,
+	0x789a, 0x60bc, 0x789e, 0x60b8, 0x78aa, 0x012e, 0x0804, 0x3408,
+	0x900e, 0x2110, 0x0c88, 0x81ff, 0x1904, 0x343a, 0x080c, 0x717f,
+	0x0904, 0x343a, 0x0126, 0x2091, 0x8000, 0x6250, 0x6070, 0x9202,
+	0x0248, 0x9085, 0x0001, 0x080c, 0x26d7, 0x080c, 0x5713, 0x012e,
+	0x0804, 0x3408, 0x012e, 0x0804, 0x343d, 0x0006, 0x0016, 0x00c6,
+	0x00e6, 0x2001, 0x1983, 0x2070, 0x2061, 0x185b, 0x6008, 0x2072,
+	0x900e, 0x2011, 0x1400, 0x080c, 0x847f, 0x7206, 0x00ee, 0x00ce,
+	0x001e, 0x000e, 0x0005, 0x0126, 0x2091, 0x8000, 0x81ff, 0x0128,
+	0x012e, 0x2021, 0x400b, 0x0804, 0x340a, 0x7884, 0xd0fc, 0x0158,
+	0x2001, 0x002a, 0x2004, 0x9005, 0x0180, 0x9082, 0x00e1, 0x0298,
+	0x012e, 0x0804, 0x343d, 0x2001, 0x002a, 0x2004, 0x9005, 0x0128,
+	0x2069, 0x185b, 0x6908, 0x9102, 0x1230, 0x012e, 0x0804, 0x343d,
+	0x012e, 0x0804, 0x343a, 0x080c, 0x9f54, 0x0dd0, 0x7884, 0xd0fc,
+	0x0904, 0x39d2, 0x00c6, 0x080c, 0x49b8, 0x00ce, 0x0d88, 0xa867,
+	0x0000, 0x7884, 0xa80a, 0x7898, 0xa80e, 0x789c, 0xa812, 0x2001,
+	0x002e, 0x2004, 0xa81a, 0x2001, 0x002f, 0x2004, 0xa81e, 0x2001,
+	0x0030, 0x2004, 0xa822, 0x2001, 0x0031, 0x2004, 0xa826, 0x2001,
+	0x0034, 0x2004, 0xa82a, 0x2001, 0x0035, 0x2004, 0xa82e, 0x2001,
+	0x002a, 0x2004, 0x9080, 0x0003, 0x9084, 0x00fc, 0x8004, 0xa816,
+	0x080c, 0x3b58, 0x0928, 0x7014, 0x2048, 0xad2c, 0xac28, 0xab1c,
+	0xaa18, 0xa930, 0xa808, 0xd0b4, 0x1120, 0x2029, 0x0000, 0x2021,
+	0x0000, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0,
+	0x9080, 0x001b, 0x080c, 0x4a01, 0x701f, 0x3a95, 0x7023, 0x0001,
+	0x012e, 0x0005, 0x0046, 0x0086, 0x0096, 0x00a6, 0x00b6, 0x00c6,
+	0x00d6, 0x00e6, 0x00f6, 0x080c, 0x393d, 0x2001, 0x1979, 0x2003,
+	0x0000, 0x2021, 0x000a, 0x2061, 0x0100, 0x6104, 0x0016, 0x60bb,
+	0x0000, 0x60bf, 0x32e1, 0x60bf, 0x0012, 0x080c, 0x3bc7, 0x080c,
+	0x3b86, 0x00f6, 0x00e6, 0x0086, 0x2940, 0x2071, 0x1a42, 0x2079,
+	0x0090, 0x00d6, 0x2069, 0x0000, 0x6884, 0xd0b4, 0x0140, 0x2001,
+	0x0035, 0x2004, 0x780e, 0x2001, 0x0034, 0x2004, 0x780a, 0x00de,
+	0x2011, 0x0001, 0x080c, 0x3fbc, 0x008e, 0x00ee, 0x00fe, 0x080c,
+	0x3ee9, 0x080c, 0x3dae, 0x05b8, 0x2001, 0x020b, 0x2004, 0x9084,
+	0x0140, 0x1db8, 0x080c, 0x4030, 0x00f6, 0x2079, 0x0300, 0x78bc,
+	0x00fe, 0x908c, 0x0070, 0x1560, 0x2071, 0x0200, 0x7037, 0x0000,
+	0x7050, 0x9084, 0xff00, 0x9086, 0x3200, 0x1510, 0x7037, 0x0001,
+	0x7050, 0x9084, 0xff00, 0x9086, 0xe100, 0x11d0, 0x7037, 0x0000,
+	0x7054, 0x7037, 0x0000, 0x715c, 0x9106, 0x1190, 0x2001, 0x181f,
+	0x2004, 0x9106, 0x1168, 0x00c6, 0x2061, 0x0100, 0x6024, 0x9084,
+	0x1e00, 0x00ce, 0x0138, 0x080c, 0x3db8, 0x080c, 0x3b81, 0x0058,
+	0x080c, 0x3b81, 0x080c, 0x3f54, 0x080c, 0x3edf, 0x2001, 0x020b,
+	0x2004, 0xd0e4, 0x0dd8, 0x2001, 0x032a, 0x2003, 0x0004, 0x2061,
+	0x0100, 0x6027, 0x0002, 0x001e, 0x6106, 0x2011, 0x020d, 0x2013,
+	0x0020, 0x60bb, 0x0000, 0x60bf, 0x0108, 0x60bf, 0x0012, 0x2001,
+	0x0004, 0x200c, 0x918c, 0xfffd, 0x2102, 0x080c, 0x130a, 0x2009,
+	0x0028, 0x080c, 0x2204, 0x2001, 0x0227, 0x200c, 0x2102, 0x00fe,
+	0x00ee, 0x00de, 0x00ce, 0x00be, 0x00ae, 0x009e, 0x008e, 0x004e,
+	0x2001, 0x1979, 0x2004, 0x9005, 0x1118, 0x012e, 0x0804, 0x3408,
+	0x012e, 0x2021, 0x400c, 0x0804, 0x340a, 0x0016, 0x0026, 0x0036,
+	0x0046, 0x0056, 0x0076, 0x0086, 0x0096, 0x00d6, 0x0156, 0x7014,
+	0x2048, 0x7020, 0x20a8, 0x8000, 0x7022, 0xa804, 0x9005, 0x0904,
+	0x3af1, 0x2048, 0x1f04, 0x3aa5, 0x7068, 0x2040, 0xa28c, 0xa390,
+	0xa494, 0xa598, 0xa930, 0xa808, 0xd0b4, 0x1120, 0x2029, 0x0000,
+	0x2021, 0x0000, 0x0096, 0x7014, 0x2048, 0xa864, 0x009e, 0x9086,
+	0x0103, 0x0170, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084,
+	0xffc0, 0x9080, 0x001b, 0x080c, 0x4a01, 0x701f, 0x3a95, 0x00b0,
+	0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080,
+	0x001b, 0x21a8, 0x27e0, 0x2098, 0x27e8, 0x20a0, 0x0006, 0x080c,
+	0x0fc0, 0x000e, 0x080c, 0x4a04, 0x701f, 0x3a95, 0x015e, 0x00de,
 	0x009e, 0x008e, 0x007e, 0x005e, 0x004e, 0x003e, 0x002e, 0x001e,
-	0x0904, 0x351a, 0x0016, 0x0026, 0x0036, 0x0046, 0x0056, 0x0076,
-	0x0086, 0x0096, 0x00d6, 0x0156, 0x701f, 0x3c02, 0x7007, 0x0003,
-	0x0804, 0x3bc0, 0xa830, 0x9086, 0x0100, 0x2021, 0x400c, 0x0904,
-	0x34ea, 0x0076, 0xad10, 0xac0c, 0xab24, 0xaa20, 0xa930, 0xa808,
-	0xd0b4, 0x1120, 0x2029, 0x0000, 0x2021, 0x0000, 0x8906, 0x8006,
-	0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x001b, 0x21a8,
-	0x27e0, 0x2098, 0x27e8, 0x20a0, 0x0006, 0x080c, 0x0fae, 0x000e,
-	0x080c, 0x4b0b, 0x007e, 0x701f, 0x3b6f, 0x7023, 0x0001, 0x0005,
-	0x0804, 0x34e8, 0x0156, 0x00c6, 0xa814, 0x908a, 0x001e, 0x0218,
-	0xa833, 0x001e, 0x0010, 0xa832, 0x0078, 0x81ff, 0x0168, 0x0016,
-	0x080c, 0x4abf, 0x001e, 0x0130, 0xa800, 0x2040, 0xa008, 0xa80a,
-	0x2100, 0x0c58, 0x9006, 0x0010, 0x9085, 0x0001, 0x00ce, 0x015e,
-	0x0005, 0x0006, 0x00f6, 0x2079, 0x0000, 0x7880, 0x9086, 0x0044,
-	0x00fe, 0x000e, 0x0005, 0x2001, 0x1977, 0x2003, 0x0001, 0x0005,
-	0x00f6, 0x00e6, 0x00c6, 0x2061, 0x0200, 0x2001, 0x1982, 0x2004,
-	0x601a, 0x2061, 0x0100, 0x2001, 0x1981, 0x2004, 0x60ce, 0x6104,
-	0xc1ac, 0x6106, 0x080c, 0x4abf, 0xa813, 0x0019, 0xa817, 0x0001,
-	0x2900, 0xa85a, 0x2001, 0x002e, 0x2004, 0xa866, 0x2001, 0x002f,
-	0x2004, 0xa86a, 0x2061, 0x0090, 0x2079, 0x0100, 0x2001, 0x1981,
-	0x2004, 0x6036, 0x2009, 0x0040, 0x080c, 0x230a, 0x2001, 0x002a,
-	0x2004, 0x9084, 0xfff8, 0xa86e, 0x601a, 0xa873, 0x0000, 0x601f,
-	0x0000, 0x78ca, 0x9006, 0x600a, 0x600e, 0x00ce, 0x00ee, 0x00fe,
-	0x0005, 0x00e6, 0x080c, 0x4abf, 0x2940, 0xa013, 0x0019, 0xa017,
-	0x0001, 0x2800, 0xa05a, 0x2001, 0x0030, 0x2004, 0xa866, 0x2001,
-	0x0031, 0x2004, 0xa86a, 0x2001, 0x002a, 0x2004, 0x9084, 0xfff8,
-	0xa86e, 0xa873, 0x0000, 0x2001, 0x032a, 0x2003, 0x0004, 0x2001,
-	0x0300, 0x2003, 0x0000, 0x2001, 0x020d, 0x2003, 0x0000, 0x2001,
-	0x0004, 0x200c, 0x918d, 0x0002, 0x2102, 0x00ee, 0x0005, 0x0126,
-	0x2091, 0x8000, 0x81ff, 0x0148, 0x080c, 0x2ba8, 0x1130, 0x9006,
-	0x080c, 0x2ab8, 0x9006, 0x080c, 0x2a9b, 0x7884, 0x9084, 0x0007,
-	0x0002, 0x3cec, 0x3cfb, 0x3d0a, 0x3ce9, 0x3ce9, 0x3ce9, 0x3ce9,
-	0x3ce9, 0x012e, 0x0804, 0x351d, 0x2001, 0x0100, 0x2004, 0x9086,
-	0x000a, 0x0db8, 0x2009, 0x0114, 0x2104, 0x9085, 0x0800, 0x200a,
-	0x080c, 0x3ed3, 0x00f0, 0x2001, 0x0100, 0x2004, 0x9086, 0x000a,
-	0x0d40, 0x2009, 0x0114, 0x2104, 0x9085, 0x4000, 0x200a, 0x080c,
-	0x3ed3, 0x0078, 0x080c, 0x7207, 0x1128, 0x012e, 0x2009, 0x0016,
-	0x0804, 0x351a, 0x81ff, 0x0128, 0x012e, 0x2021, 0x400b, 0x0804,
-	0x34ea, 0x0086, 0x0096, 0x00a6, 0x00b6, 0x00c6, 0x00d6, 0x00e6,
-	0x00f6, 0x080c, 0x3a1b, 0x2009, 0x0101, 0x210c, 0x0016, 0x7ec8,
-	0x7dcc, 0x9006, 0x2068, 0x2060, 0x2058, 0x080c, 0x41dc, 0x080c,
-	0x412c, 0x903e, 0x2720, 0x00f6, 0x00e6, 0x0086, 0x2940, 0x2071,
-	0x1a3d, 0x2079, 0x0090, 0x00d6, 0x2069, 0x0000, 0x6884, 0xd0b4,
-	0x0120, 0x68d4, 0x780e, 0x68d0, 0x780a, 0x00de, 0x2011, 0x0001,
-	0x080c, 0x408d, 0x080c, 0x2bb0, 0x080c, 0x2bb0, 0x080c, 0x2bb0,
-	0x080c, 0x2bb0, 0x080c, 0x408d, 0x008e, 0x00ee, 0x00fe, 0x080c,
-	0x3fba, 0x2009, 0x9c40, 0x8109, 0x11b0, 0x080c, 0x3e89, 0x2001,
-	0x0004, 0x200c, 0x918c, 0xfffd, 0x2102, 0x001e, 0x00fe, 0x00ee,
-	0x00de, 0x00ce, 0x00be, 0x00ae, 0x009e, 0x008e, 0x2009, 0x0017,
-	0x080c, 0x351a, 0x0cf8, 0x2001, 0x020b, 0x2004, 0x9084, 0x0140,
-	0x1d10, 0x00f6, 0x2079, 0x0000, 0x7884, 0x00fe, 0xd0bc, 0x0178,
-	0x2001, 0x0201, 0x200c, 0x81ff, 0x0150, 0x080c, 0x3f98, 0x2d00,
-	0x9c05, 0x9b05, 0x0120, 0x080c, 0x3e89, 0x0804, 0x3e29, 0x080c,
-	0x4101, 0x080c, 0x4025, 0x080c, 0x3f7b, 0x080c, 0x3fb0, 0x00f6,
-	0x2079, 0x0100, 0x7824, 0xd0ac, 0x0130, 0x8b58, 0x080c, 0x3e89,
-	0x00fe, 0x0804, 0x3e29, 0x00fe, 0x080c, 0x3e7f, 0x1150, 0x8d68,
-	0x2001, 0x0032, 0x2602, 0x2001, 0x0033, 0x2502, 0x080c, 0x3e89,
-	0x0080, 0x87ff, 0x0138, 0x2001, 0x0201, 0x2004, 0x9005, 0x1908,
-	0x8739, 0x0038, 0x2001, 0x1a3a, 0x2004, 0x9086, 0x0000, 0x1904,
-	0x3d79, 0x2001, 0x032f, 0x2003, 0x00f6, 0x8631, 0x1208, 0x8529,
-	0x2500, 0x9605, 0x0904, 0x3e29, 0x7884, 0xd0bc, 0x0128, 0x2d00,
-	0x9c05, 0x9b05, 0x1904, 0x3e29, 0xa013, 0x0019, 0x2001, 0x032a,
-	0x2003, 0x0004, 0x7884, 0xd0ac, 0x1148, 0x2001, 0x1a3a, 0x2003,
-	0x0003, 0x2001, 0x032a, 0x2003, 0x0009, 0x0030, 0xa017, 0x0001,
-	0x78b4, 0x9005, 0x0108, 0xa016, 0x2800, 0xa05a, 0x2009, 0x0040,
-	0x080c, 0x230a, 0x2900, 0xa85a, 0xa813, 0x0019, 0x7884, 0xd0a4,
-	0x1180, 0xa817, 0x0000, 0x00c6, 0x20a9, 0x0004, 0x2061, 0x0090,
-	0x602b, 0x0008, 0x2001, 0x0203, 0x2004, 0x1f04, 0x3e00, 0x00ce,
-	0x0030, 0xa817, 0x0001, 0x78b0, 0x9005, 0x0108, 0xa816, 0x00f6,
-	0x00c6, 0x2079, 0x0100, 0x2061, 0x0090, 0x7827, 0x0002, 0x2001,
-	0x002a, 0x2004, 0x9084, 0xfff8, 0x601a, 0x0006, 0x2001, 0x002b,
-	0x2004, 0x601e, 0x78c6, 0x000e, 0x78ca, 0x00ce, 0x00fe, 0x0804,
-	0x3d33, 0x001e, 0x00c6, 0x2001, 0x032a, 0x2003, 0x0004, 0x2061,
-	0x0100, 0x6027, 0x0002, 0x6106, 0x2011, 0x020d, 0x2013, 0x0020,
-	0x2001, 0x0004, 0x200c, 0x918c, 0xfffd, 0x2102, 0x080c, 0x12f8,
-	0x7884, 0x9084, 0x0003, 0x9086, 0x0002, 0x0508, 0x2009, 0x0028,
-	0x080c, 0x230a, 0x2001, 0x0227, 0x200c, 0x2102, 0x6050, 0x0006,
-	0x2001, 0x0100, 0x2004, 0x9086, 0x000a, 0x000e, 0x0118, 0x9084,
-	0xb7ef, 0x0020, 0x9084, 0xb7ff, 0x080c, 0x2cf5, 0x6052, 0x602f,
-	0x0000, 0x604b, 0xf7f7, 0x6043, 0x0090, 0x6043, 0x0010, 0x00ce,
-	0x2d08, 0x2c10, 0x2b18, 0x2b00, 0x9c05, 0x9d05, 0x00fe, 0x00ee,
-	0x00de, 0x00ce, 0x00be, 0x00ae, 0x009e, 0x008e, 0x1118, 0x012e,
-	0x0804, 0x34e8, 0x012e, 0x2021, 0x400c, 0x0804, 0x34ea, 0x9085,
-	0x0001, 0x1d04, 0x3e88, 0x2091, 0x6000, 0x8420, 0x9486, 0x0064,
-	0x0005, 0x2001, 0x0105, 0x2003, 0x0010, 0x2001, 0x032a, 0x2003,
-	0x0004, 0x2001, 0x1a3a, 0x2003, 0x0000, 0x0071, 0x2009, 0x0048,
-	0x080c, 0x230a, 0x2001, 0x0227, 0x2024, 0x2402, 0x2001, 0x0109,
-	0x2003, 0x4000, 0x9026, 0x0005, 0x00f6, 0x00e6, 0x2071, 0x1a3d,
-	0x7000, 0x9086, 0x0000, 0x0520, 0x2079, 0x0090, 0x2009, 0x0206,
-	0x2104, 0x2009, 0x0203, 0x210c, 0x9106, 0x1120, 0x2009, 0x0040,
-	0x080c, 0x230a, 0x782c, 0xd0fc, 0x0d88, 0x080c, 0x4101, 0x7000,
-	0x9086, 0x0000, 0x1d58, 0x782b, 0x0004, 0x782c, 0xd0ac, 0x1de8,
-	0x2009, 0x0040, 0x080c, 0x230a, 0x782b, 0x0002, 0x7003, 0x0000,
-	0x00ee, 0x00fe, 0x0005, 0x2001, 0x0100, 0x2004, 0x9086, 0x000a,
-	0x15d0, 0x00f6, 0x2079, 0x0100, 0x2001, 0x1817, 0x200c, 0x7932,
-	0x7936, 0x080c, 0x27b7, 0x080c, 0x2cc2, 0x080c, 0x2cf5, 0x784b,
-	0xf7f7, 0x7843, 0x0090, 0x7843, 0x0010, 0x7850, 0xc0e5, 0x7852,
-	0x2019, 0x61a8, 0x7820, 0xd09c, 0x0110, 0x8319, 0x1dd8, 0x7850,
-	0xc0e4, 0x7852, 0x7827, 0x0048, 0x7843, 0x0040, 0x2019, 0x01f4,
-	0xa001, 0xa001, 0x8319, 0x1de0, 0x2001, 0x0100, 0x080c, 0x2c88,
-	0x7827, 0x0020, 0x7843, 0x0000, 0x9006, 0x080c, 0x2c88, 0x7827,
-	0x0048, 0x00fe, 0x0005, 0x00f6, 0x2079, 0x0100, 0x2001, 0x1817,
-	0x200c, 0x7932, 0x7936, 0x080c, 0x27b7, 0x7850, 0x9084, 0xfbff,
-	0x9085, 0x0030, 0x7852, 0x2019, 0x01f4, 0x8319, 0x1df0, 0x9084,
-	0xffcf, 0x9085, 0x2000, 0x7852, 0x20a9, 0x0046, 0x1d04, 0x3f2e,
-	0x2091, 0x6000, 0x1f04, 0x3f2e, 0x7850, 0x9085, 0x0400, 0x9084,
-	0xdfff, 0x7852, 0x2001, 0x0021, 0x2004, 0x9084, 0x0003, 0x9086,
-	0x0001, 0x1120, 0x7850, 0x9084, 0xdfff, 0x7852, 0x784b, 0xf7f7,
-	0x7843, 0x0090, 0x7843, 0x0010, 0x20a9, 0x0028, 0xa001, 0x1f04,
-	0x3f4e, 0x7850, 0x9085, 0x1400, 0x7852, 0x2019, 0x61a8, 0x7854,
-	0xa001, 0xa001, 0xd08c, 0x1110, 0x8319, 0x1dc8, 0x7827, 0x0048,
-	0x7850, 0x9085, 0x0400, 0x7852, 0x7843, 0x0040, 0x2019, 0x01f4,
-	0xa001, 0xa001, 0x8319, 0x1de0, 0x2001, 0x0100, 0x080c, 0x2c88,
-	0x7827, 0x0020, 0x7843, 0x0000, 0x9006, 0x080c, 0x2c88, 0x7827,
-	0x0048, 0x00fe, 0x0005, 0x7884, 0xd0ac, 0x11c8, 0x00f6, 0x00e6,
-	0x2071, 0x1a3a, 0x2079, 0x0320, 0x2001, 0x0201, 0x2004, 0x9005,
-	0x0160, 0x7000, 0x9086, 0x0000, 0x1140, 0x0051, 0xd0bc, 0x0108,
-	0x8738, 0x7003, 0x0003, 0x782b, 0x0019, 0x00ee, 0x00fe, 0x0005,
-	0x00f6, 0x2079, 0x0300, 0x78bc, 0x00fe, 0x908c, 0x0070, 0x0178,
-	0x2009, 0x0032, 0x260a, 0x2009, 0x0033, 0x250a, 0xd0b4, 0x0108,
-	0x8c60, 0xd0ac, 0x0108, 0x8d68, 0xd0a4, 0x0108, 0x8b58, 0x0005,
-	0x00f6, 0x2079, 0x0200, 0x781c, 0xd084, 0x0110, 0x7837, 0x0050,
-	0x00fe, 0x0005, 0x00e6, 0x2071, 0x0100, 0x2001, 0x1982, 0x2004,
-	0x70e2, 0x080c, 0x3c51, 0x1188, 0x2001, 0x181f, 0x2004, 0x2009,
-	0x181e, 0x210c, 0x918c, 0x00ff, 0x706e, 0x716a, 0x7066, 0x918d,
-	0x3200, 0x7162, 0x7073, 0xe109, 0x0080, 0x702c, 0x9085, 0x0002,
-	0x702e, 0x2009, 0x1817, 0x210c, 0x716e, 0x7063, 0x0100, 0x7166,
-	0x719e, 0x706b, 0x0000, 0x7073, 0x0809, 0x7077, 0x0008, 0x7078,
-	0x9080, 0x0100, 0x707a, 0x7080, 0x8000, 0x7082, 0x7087, 0xaaaa,
-	0x9006, 0x708a, 0x708e, 0x707e, 0x70d6, 0x70ab, 0x0036, 0x70af,
-	0x95d5, 0x7014, 0x9084, 0x1984, 0x9085, 0x0092, 0x7016, 0x080c,
-	0x4101, 0x00f6, 0x2071, 0x1a3a, 0x2079, 0x0320, 0x00d6, 0x2069,
-	0x0000, 0x6884, 0xd0b4, 0x0120, 0x689c, 0x780e, 0x6898, 0x780a,
-	0x00de, 0x2009, 0x03e8, 0x8109, 0x1df0, 0x792c, 0xd1fc, 0x0110,
-	0x782b, 0x0004, 0x2011, 0x0011, 0x080c, 0x408d, 0x2011, 0x0001,
-	0x080c, 0x408d, 0x00fe, 0x00ee, 0x0005, 0x00f6, 0x00e6, 0x2071,
-	0x1a3a, 0x2079, 0x0320, 0x792c, 0xd1fc, 0x0904, 0x408a, 0x782b,
-	0x0002, 0x9026, 0xd19c, 0x1904, 0x4086, 0x7000, 0x0002, 0x408a,
-	0x403b, 0x406b, 0x4086, 0xd1bc, 0x1170, 0xd1dc, 0x1190, 0x8001,
-	0x7002, 0x2011, 0x0001, 0x080c, 0x408d, 0x0904, 0x408a, 0x080c,
-	0x408d, 0x0804, 0x408a, 0x00f6, 0x2079, 0x0300, 0x78bf, 0x0000,
-	0x00fe, 0x7810, 0x7914, 0x782b, 0x0004, 0x7812, 0x7916, 0x2001,
-	0x0201, 0x200c, 0x81ff, 0x0de8, 0x080c, 0x3f98, 0x2009, 0x0001,
-	0x00f6, 0x2079, 0x0300, 0x78b8, 0x00fe, 0xd0ec, 0x0110, 0x2009,
-	0x0011, 0x792a, 0x00f8, 0x8001, 0x7002, 0x9184, 0x0880, 0x1140,
-	0x782c, 0xd0fc, 0x1904, 0x402f, 0x2011, 0x0001, 0x00b1, 0x0090,
-	0xa010, 0x9092, 0x0004, 0x9086, 0x0015, 0x1120, 0xa000, 0xa05a,
-	0x2011, 0x0031, 0xa212, 0xd1dc, 0x1960, 0x0828, 0x782b, 0x0004,
-	0x7003, 0x0000, 0x00ee, 0x00fe, 0x0005, 0xa014, 0x9005, 0x0550,
-	0x8001, 0x0036, 0x0096, 0xa016, 0xa058, 0x2048, 0xa010, 0x2009,
-	0x0031, 0x911a, 0x831c, 0x831c, 0x938a, 0x0007, 0x1a0c, 0x0dfa,
-	0x9398, 0x40bb, 0x231d, 0x083f, 0x9080, 0x0004, 0x7a2a, 0x7100,
-	0x8108, 0x7102, 0x009e, 0x003e, 0x908a, 0x0035, 0x1140, 0x0096,
-	0xa058, 0x2048, 0xa804, 0xa05a, 0x2001, 0x0019, 0x009e, 0xa012,
-	0x9085, 0x0001, 0x0005, 0x40f8, 0x40ef, 0x40e6, 0x40dd, 0x40d4,
-	0x40cb, 0x40c2, 0xa964, 0x7902, 0xa968, 0x7906, 0xa96c, 0x7912,
-	0xa970, 0x7916, 0x0005, 0xa974, 0x7902, 0xa978, 0x7906, 0xa97c,
-	0x7912, 0xa980, 0x7916, 0x0005, 0xa984, 0x7902, 0xa988, 0x7906,
-	0xa98c, 0x7912, 0xa990, 0x7916, 0x0005, 0xa994, 0x7902, 0xa998,
-	0x7906, 0xa99c, 0x7912, 0xa9a0, 0x7916, 0x0005, 0xa9a4, 0x7902,
-	0xa9a8, 0x7906, 0xa9ac, 0x7912, 0xa9b0, 0x7916, 0x0005, 0xa9b4,
-	0x7902, 0xa9b8, 0x7906, 0xa9bc, 0x7912, 0xa9c0, 0x7916, 0x0005,
-	0xa9c4, 0x7902, 0xa9c8, 0x7906, 0xa9cc, 0x7912, 0xa9d0, 0x7916,
-	0x0005, 0x00f6, 0x00e6, 0x0086, 0x2071, 0x1a3d, 0x2079, 0x0090,
-	0x792c, 0xd1fc, 0x01e8, 0x782b, 0x0002, 0x2940, 0x9026, 0x7000,
-	0x0002, 0x4128, 0x4114, 0x411f, 0x8001, 0x7002, 0xd19c, 0x1180,
-	0x2011, 0x0001, 0x080c, 0x408d, 0x190c, 0x408d, 0x0048, 0x8001,
-	0x7002, 0x782c, 0xd0fc, 0x1d38, 0x2011, 0x0001, 0x080c, 0x408d,
-	0x008e, 0x00ee, 0x00fe, 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x0086,
-	0x2061, 0x0200, 0x2001, 0x1982, 0x2004, 0x601a, 0x2061, 0x0100,
-	0x2001, 0x1981, 0x2004, 0x60ce, 0x6104, 0xc1ac, 0x6106, 0x2001,
-	0x002c, 0x2004, 0x9005, 0x0520, 0x2038, 0x2001, 0x002e, 0x2024,
-	0x2001, 0x002f, 0x201c, 0x080c, 0x4abf, 0xa813, 0x0019, 0xaf16,
-	0x2900, 0xa85a, 0x978a, 0x0007, 0x0220, 0x2138, 0x2009, 0x0007,
-	0x0010, 0x2708, 0x903e, 0x0096, 0xa858, 0x2048, 0xa85c, 0x9080,
-	0x0019, 0x009e, 0x080c, 0x41a4, 0x1d68, 0x2900, 0xa85a, 0x00d0,
-	0x080c, 0x4abf, 0xa813, 0x0019, 0xa817, 0x0001, 0x2900, 0xa85a,
+	0x0005, 0x7014, 0x2048, 0xa864, 0x9086, 0x0103, 0x1118, 0x701f,
+	0x3b56, 0x0450, 0x7014, 0x2048, 0xa868, 0xc0fd, 0xa86a, 0x2009,
+	0x007f, 0x080c, 0x6344, 0x0110, 0x9006, 0x0030, 0xb813, 0x00ff,
+	0xb817, 0xfffd, 0x080c, 0xc20a, 0x015e, 0x00de, 0x009e, 0x008e,
+	0x007e, 0x005e, 0x004e, 0x003e, 0x002e, 0x001e, 0x0904, 0x343a,
+	0x0016, 0x0026, 0x0036, 0x0046, 0x0056, 0x0076, 0x0086, 0x0096,
+	0x00d6, 0x0156, 0x701f, 0x3b28, 0x7007, 0x0003, 0x0804, 0x3ae6,
+	0xa830, 0x9086, 0x0100, 0x2021, 0x400c, 0x0904, 0x340a, 0x0076,
+	0xad10, 0xac0c, 0xab24, 0xaa20, 0xa930, 0xa808, 0xd0b4, 0x1120,
+	0x2029, 0x0000, 0x2021, 0x0000, 0x8906, 0x8006, 0x8007, 0x90bc,
+	0x003f, 0x9084, 0xffc0, 0x9080, 0x001b, 0x21a8, 0x27e0, 0x2098,
+	0x27e8, 0x20a0, 0x0006, 0x080c, 0x0fc0, 0x000e, 0x080c, 0x4a04,
+	0x007e, 0x701f, 0x3a95, 0x7023, 0x0001, 0x0005, 0x0804, 0x3408,
+	0x0156, 0x00c6, 0xa814, 0x908a, 0x001e, 0x0218, 0xa833, 0x001e,
+	0x0010, 0xa832, 0x0078, 0x81ff, 0x0168, 0x0016, 0x080c, 0x49b8,
+	0x001e, 0x0130, 0xa800, 0x2040, 0xa008, 0xa80a, 0x2100, 0x0c58,
+	0x9006, 0x0010, 0x9085, 0x0001, 0x00ce, 0x015e, 0x0005, 0x0006,
+	0x00f6, 0x2079, 0x0000, 0x7880, 0x9086, 0x0044, 0x00fe, 0x000e,
+	0x0005, 0x2001, 0x1979, 0x2003, 0x0001, 0x0005, 0x00f6, 0x00e6,
+	0x00c6, 0x2061, 0x0200, 0x2001, 0x1984, 0x2004, 0x601a, 0x2061,
+	0x0100, 0x2001, 0x1983, 0x2004, 0x60ce, 0x6104, 0xc1ac, 0x6106,
+	0x080c, 0x49b8, 0xa813, 0x0019, 0xa817, 0x0001, 0x2900, 0xa85a,
 	0x2001, 0x002e, 0x2004, 0xa866, 0x2001, 0x002f, 0x2004, 0xa86a,
-	0x2001, 0x002a, 0x2004, 0x9084, 0xfff8, 0xa86e, 0x2001, 0x002b,
-	0x2004, 0xa872, 0x2061, 0x0090, 0x2079, 0x0100, 0x2001, 0x1981,
-	0x2004, 0x6036, 0x2009, 0x0040, 0x080c, 0x230a, 0x2001, 0x002a,
+	0x2061, 0x0090, 0x2079, 0x0100, 0x2001, 0x1983, 0x2004, 0x6036,
+	0x2009, 0x0040, 0x080c, 0x2204, 0x2001, 0x002a, 0x2004, 0x9084,
+	0xfff8, 0xa86e, 0x601a, 0xa873, 0x0000, 0x601f, 0x0000, 0x78ca,
+	0x9006, 0x600a, 0x600e, 0x00ce, 0x00ee, 0x00fe, 0x0005, 0x00e6,
+	0x080c, 0x49b8, 0x2940, 0xa013, 0x0019, 0xa017, 0x0001, 0x2800,
+	0xa05a, 0x2001, 0x0030, 0x2004, 0xa866, 0x2001, 0x0031, 0x2004,
+	0xa86a, 0x2001, 0x002a, 0x2004, 0x9084, 0xfff8, 0xa86e, 0xa873,
+	0x0000, 0x2001, 0x032a, 0x2003, 0x0004, 0x2001, 0x0300, 0x2003,
+	0x0000, 0x2001, 0x020d, 0x2003, 0x0000, 0x2001, 0x0004, 0x200c,
+	0x918d, 0x0002, 0x2102, 0x00ee, 0x0005, 0x0126, 0x2091, 0x8000,
+	0x81ff, 0x0148, 0x080c, 0x2aa8, 0x1130, 0x9006, 0x080c, 0x29b8,
+	0x9006, 0x080c, 0x299b, 0x7884, 0x9084, 0x0007, 0x0002, 0x3c12,
+	0x3c21, 0x3c30, 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, 0x3c0f, 0x012e,
+	0x0804, 0x343d, 0x2001, 0x0100, 0x2004, 0x9086, 0x000a, 0x0db8,
+	0x2009, 0x0114, 0x2104, 0x9085, 0x0800, 0x200a, 0x080c, 0x3e02,
+	0x00f0, 0x2001, 0x0100, 0x2004, 0x9086, 0x000a, 0x0d40, 0x2009,
+	0x0114, 0x2104, 0x9085, 0x4000, 0x200a, 0x080c, 0x3e02, 0x0078,
+	0x080c, 0x717f, 0x1128, 0x012e, 0x2009, 0x0016, 0x0804, 0x343a,
+	0x81ff, 0x0128, 0x012e, 0x2021, 0x400b, 0x0804, 0x340a, 0x6000,
+	0x9086, 0x0003, 0x1db8, 0x2001, 0x0141, 0x2004, 0xd0dc, 0x0d90,
+	0x0086, 0x0096, 0x00a6, 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6,
+	0x080c, 0x393d, 0x2009, 0x0101, 0x210c, 0x0016, 0x7ec8, 0x7dcc,
+	0x9006, 0x2068, 0x2060, 0x2058, 0x080c, 0x410b, 0x080c, 0x405b,
+	0x903e, 0x2720, 0x00f6, 0x00e6, 0x0086, 0x2940, 0x2071, 0x1a42,
+	0x2079, 0x0090, 0x00d6, 0x2069, 0x0000, 0x6884, 0xd0b4, 0x0120,
+	0x68d4, 0x780e, 0x68d0, 0x780a, 0x00de, 0x2011, 0x0001, 0x080c,
+	0x3fbc, 0x080c, 0x2ab0, 0x080c, 0x2ab0, 0x080c, 0x2ab0, 0x080c,
+	0x2ab0, 0x080c, 0x3fbc, 0x008e, 0x00ee, 0x00fe, 0x080c, 0x3ee9,
+	0x2009, 0x9c40, 0x8109, 0x11b0, 0x080c, 0x3db8, 0x2001, 0x0004,
+	0x200c, 0x918c, 0xfffd, 0x2102, 0x001e, 0x00fe, 0x00ee, 0x00de,
+	0x00ce, 0x00be, 0x00ae, 0x009e, 0x008e, 0x2009, 0x0017, 0x080c,
+	0x343a, 0x0cf8, 0x2001, 0x020b, 0x2004, 0x9084, 0x0140, 0x1d10,
+	0x00f6, 0x2079, 0x0000, 0x7884, 0x00fe, 0xd0bc, 0x0178, 0x2001,
+	0x0201, 0x200c, 0x81ff, 0x0150, 0x080c, 0x3ec7, 0x2d00, 0x9c05,
+	0x9b05, 0x0120, 0x080c, 0x3db8, 0x0804, 0x3d58, 0x080c, 0x4030,
+	0x080c, 0x3f54, 0x080c, 0x3eaa, 0x080c, 0x3edf, 0x00f6, 0x2079,
+	0x0100, 0x7824, 0xd0ac, 0x0130, 0x8b58, 0x080c, 0x3db8, 0x00fe,
+	0x0804, 0x3d58, 0x00fe, 0x080c, 0x3dae, 0x1150, 0x8d68, 0x2001,
+	0x0032, 0x2602, 0x2001, 0x0033, 0x2502, 0x080c, 0x3db8, 0x0080,
+	0x87ff, 0x0138, 0x2001, 0x0201, 0x2004, 0x9005, 0x1908, 0x8739,
+	0x0038, 0x2001, 0x1a3f, 0x2004, 0x9086, 0x0000, 0x1904, 0x3ca8,
+	0x2001, 0x032f, 0x2003, 0x00f6, 0x8631, 0x1208, 0x8529, 0x2500,
+	0x9605, 0x0904, 0x3d58, 0x7884, 0xd0bc, 0x0128, 0x2d00, 0x9c05,
+	0x9b05, 0x1904, 0x3d58, 0xa013, 0x0019, 0x2001, 0x032a, 0x2003,
+	0x0004, 0x7884, 0xd0ac, 0x1148, 0x2001, 0x1a3f, 0x2003, 0x0003,
+	0x2001, 0x032a, 0x2003, 0x0009, 0x0030, 0xa017, 0x0001, 0x78b4,
+	0x9005, 0x0108, 0xa016, 0x2800, 0xa05a, 0x2009, 0x0040, 0x080c,
+	0x2204, 0x2900, 0xa85a, 0xa813, 0x0019, 0x7884, 0xd0a4, 0x1180,
+	0xa817, 0x0000, 0x00c6, 0x20a9, 0x0004, 0x2061, 0x0090, 0x602b,
+	0x0008, 0x2001, 0x0203, 0x2004, 0x1f04, 0x3d2f, 0x00ce, 0x0030,
+	0xa817, 0x0001, 0x78b0, 0x9005, 0x0108, 0xa816, 0x00f6, 0x00c6,
+	0x2079, 0x0100, 0x2061, 0x0090, 0x7827, 0x0002, 0x2001, 0x002a,
 	0x2004, 0x9084, 0xfff8, 0x601a, 0x0006, 0x2001, 0x002b, 0x2004,
-	0x601e, 0x78c6, 0x000e, 0x78ca, 0x9006, 0x600a, 0x600e, 0x008e,
-	0x00ce, 0x00ee, 0x00fe, 0x0005, 0x00e6, 0x2071, 0x0080, 0xaa60,
-	0x22e8, 0x20a0, 0x20e1, 0x0000, 0x2099, 0x0088, 0x702b, 0x0026,
-	0x7402, 0x7306, 0x9006, 0x700a, 0x700e, 0x810b, 0x810b, 0x21a8,
-	0x810b, 0x7112, 0x702b, 0x0041, 0x702c, 0xd0fc, 0x0de8, 0x702b,
-	0x0002, 0x702b, 0x0040, 0x4005, 0x7400, 0x7304, 0x87ff, 0x0190,
-	0x0086, 0x0096, 0x2940, 0x0086, 0x080c, 0x4abf, 0x008e, 0xa058,
-	0x00a6, 0x2050, 0x2900, 0xb006, 0xa05a, 0x00ae, 0x009e, 0x008e,
-	0x9085, 0x0001, 0x00ee, 0x0005, 0x00e6, 0x2001, 0x002d, 0x2004,
-	0x9005, 0x0528, 0x2038, 0x2001, 0x0030, 0x2024, 0x2001, 0x0031,
-	0x201c, 0x080c, 0x4abf, 0x2940, 0xa813, 0x0019, 0xaf16, 0x2900,
+	0x601e, 0x78c6, 0x000e, 0x78ca, 0x00ce, 0x00fe, 0x0804, 0x3c62,
+	0x001e, 0x00c6, 0x2001, 0x032a, 0x2003, 0x0004, 0x2061, 0x0100,
+	0x6027, 0x0002, 0x6106, 0x2011, 0x020d, 0x2013, 0x0020, 0x2001,
+	0x0004, 0x200c, 0x918c, 0xfffd, 0x2102, 0x080c, 0x130a, 0x7884,
+	0x9084, 0x0003, 0x9086, 0x0002, 0x0508, 0x2009, 0x0028, 0x080c,
+	0x2204, 0x2001, 0x0227, 0x200c, 0x2102, 0x6050, 0x0006, 0x2001,
+	0x0100, 0x2004, 0x9086, 0x000a, 0x000e, 0x0118, 0x9084, 0xb7ef,
+	0x0020, 0x9084, 0xb7ff, 0x080c, 0x2bf5, 0x6052, 0x602f, 0x0000,
+	0x604b, 0xf7f7, 0x6043, 0x0090, 0x6043, 0x0010, 0x00ce, 0x2d08,
+	0x2c10, 0x2b18, 0x2b00, 0x9c05, 0x9d05, 0x00fe, 0x00ee, 0x00de,
+	0x00ce, 0x00be, 0x00ae, 0x009e, 0x008e, 0x1118, 0x012e, 0x0804,
+	0x3408, 0x012e, 0x2021, 0x400c, 0x0804, 0x340a, 0x9085, 0x0001,
+	0x1d04, 0x3db7, 0x2091, 0x6000, 0x8420, 0x9486, 0x0064, 0x0005,
+	0x2001, 0x0105, 0x2003, 0x0010, 0x2001, 0x032a, 0x2003, 0x0004,
+	0x2001, 0x1a3f, 0x2003, 0x0000, 0x0071, 0x2009, 0x0048, 0x080c,
+	0x2204, 0x2001, 0x0227, 0x2024, 0x2402, 0x2001, 0x0109, 0x2003,
+	0x4000, 0x9026, 0x0005, 0x00f6, 0x00e6, 0x2071, 0x1a42, 0x7000,
+	0x9086, 0x0000, 0x0520, 0x2079, 0x0090, 0x2009, 0x0206, 0x2104,
+	0x2009, 0x0203, 0x210c, 0x9106, 0x1120, 0x2009, 0x0040, 0x080c,
+	0x2204, 0x782c, 0xd0fc, 0x0d88, 0x080c, 0x4030, 0x7000, 0x9086,
+	0x0000, 0x1d58, 0x782b, 0x0004, 0x782c, 0xd0ac, 0x1de8, 0x2009,
+	0x0040, 0x080c, 0x2204, 0x782b, 0x0002, 0x7003, 0x0000, 0x00ee,
+	0x00fe, 0x0005, 0x2001, 0x0100, 0x2004, 0x9086, 0x000a, 0x15d0,
+	0x00f6, 0x2079, 0x0100, 0x2001, 0x1817, 0x200c, 0x7932, 0x7936,
+	0x080c, 0x26b7, 0x080c, 0x2bc2, 0x080c, 0x2bf5, 0x784b, 0xf7f7,
+	0x7843, 0x0090, 0x7843, 0x0010, 0x7850, 0xc0e5, 0x7852, 0x2019,
+	0x61a8, 0x7820, 0xd09c, 0x0110, 0x8319, 0x1dd8, 0x7850, 0xc0e4,
+	0x7852, 0x7827, 0x0048, 0x7843, 0x0040, 0x2019, 0x01f4, 0xa001,
+	0xa001, 0x8319, 0x1de0, 0x2001, 0x0100, 0x080c, 0x2b88, 0x7827,
+	0x0020, 0x7843, 0x0000, 0x9006, 0x080c, 0x2b88, 0x7827, 0x0048,
+	0x00fe, 0x0005, 0x00f6, 0x2079, 0x0100, 0x2001, 0x1817, 0x200c,
+	0x7932, 0x7936, 0x080c, 0x26b7, 0x7850, 0x9084, 0xfbff, 0x9085,
+	0x0030, 0x7852, 0x2019, 0x01f4, 0x8319, 0x1df0, 0x9084, 0xffcf,
+	0x9085, 0x2000, 0x7852, 0x20a9, 0x0046, 0x1d04, 0x3e5d, 0x2091,
+	0x6000, 0x1f04, 0x3e5d, 0x7850, 0x9085, 0x0400, 0x9084, 0xdfff,
+	0x7852, 0x2001, 0x0021, 0x2004, 0x9084, 0x0003, 0x9086, 0x0001,
+	0x1120, 0x7850, 0x9084, 0xdfff, 0x7852, 0x784b, 0xf7f7, 0x7843,
+	0x0090, 0x7843, 0x0010, 0x20a9, 0x0028, 0xa001, 0x1f04, 0x3e7d,
+	0x7850, 0x9085, 0x1400, 0x7852, 0x2019, 0x61a8, 0x7854, 0xa001,
+	0xa001, 0xd08c, 0x1110, 0x8319, 0x1dc8, 0x7827, 0x0048, 0x7850,
+	0x9085, 0x0400, 0x7852, 0x7843, 0x0040, 0x2019, 0x01f4, 0xa001,
+	0xa001, 0x8319, 0x1de0, 0x2001, 0x0100, 0x080c, 0x2b88, 0x7827,
+	0x0020, 0x7843, 0x0000, 0x9006, 0x080c, 0x2b88, 0x7827, 0x0048,
+	0x00fe, 0x0005, 0x7884, 0xd0ac, 0x11c8, 0x00f6, 0x00e6, 0x2071,
+	0x1a3f, 0x2079, 0x0320, 0x2001, 0x0201, 0x2004, 0x9005, 0x0160,
+	0x7000, 0x9086, 0x0000, 0x1140, 0x0051, 0xd0bc, 0x0108, 0x8738,
+	0x7003, 0x0003, 0x782b, 0x0019, 0x00ee, 0x00fe, 0x0005, 0x00f6,
+	0x2079, 0x0300, 0x78bc, 0x00fe, 0x908c, 0x0070, 0x0178, 0x2009,
+	0x0032, 0x260a, 0x2009, 0x0033, 0x250a, 0xd0b4, 0x0108, 0x8c60,
+	0xd0ac, 0x0108, 0x8d68, 0xd0a4, 0x0108, 0x8b58, 0x0005, 0x00f6,
+	0x2079, 0x0200, 0x781c, 0xd084, 0x0110, 0x7837, 0x0050, 0x00fe,
+	0x0005, 0x00e6, 0x2071, 0x0100, 0x2001, 0x1984, 0x2004, 0x70e2,
+	0x080c, 0x3b77, 0x1188, 0x2001, 0x181f, 0x2004, 0x2009, 0x181e,
+	0x210c, 0x918c, 0x00ff, 0x706e, 0x716a, 0x7066, 0x918d, 0x3200,
+	0x7162, 0x7073, 0xe109, 0x0080, 0x702c, 0x9085, 0x0002, 0x702e,
+	0x2009, 0x1817, 0x210c, 0x716e, 0x7063, 0x0100, 0x7166, 0x719e,
+	0x706b, 0x0000, 0x7073, 0x0809, 0x7077, 0x0008, 0x7078, 0x9080,
+	0x0100, 0x707a, 0x7080, 0x8000, 0x7082, 0x7087, 0xaaaa, 0x9006,
+	0x708a, 0x708e, 0x707e, 0x70d6, 0x70ab, 0x0036, 0x70af, 0x95d5,
+	0x7014, 0x9084, 0x1984, 0x9085, 0x0092, 0x7016, 0x080c, 0x4030,
+	0x00f6, 0x2071, 0x1a3f, 0x2079, 0x0320, 0x00d6, 0x2069, 0x0000,
+	0x6884, 0xd0b4, 0x0120, 0x689c, 0x780e, 0x6898, 0x780a, 0x00de,
+	0x2009, 0x03e8, 0x8109, 0x1df0, 0x792c, 0xd1fc, 0x0110, 0x782b,
+	0x0004, 0x2011, 0x0011, 0x080c, 0x3fbc, 0x2011, 0x0001, 0x080c,
+	0x3fbc, 0x00fe, 0x00ee, 0x0005, 0x00f6, 0x00e6, 0x2071, 0x1a3f,
+	0x2079, 0x0320, 0x792c, 0xd1fc, 0x0904, 0x3fb9, 0x782b, 0x0002,
+	0x9026, 0xd19c, 0x1904, 0x3fb5, 0x7000, 0x0002, 0x3fb9, 0x3f6a,
+	0x3f9a, 0x3fb5, 0xd1bc, 0x1170, 0xd1dc, 0x1190, 0x8001, 0x7002,
+	0x2011, 0x0001, 0x080c, 0x3fbc, 0x0904, 0x3fb9, 0x080c, 0x3fbc,
+	0x0804, 0x3fb9, 0x00f6, 0x2079, 0x0300, 0x78bf, 0x0000, 0x00fe,
+	0x7810, 0x7914, 0x782b, 0x0004, 0x7812, 0x7916, 0x2001, 0x0201,
+	0x200c, 0x81ff, 0x0de8, 0x080c, 0x3ec7, 0x2009, 0x0001, 0x00f6,
+	0x2079, 0x0300, 0x78b8, 0x00fe, 0xd0ec, 0x0110, 0x2009, 0x0011,
+	0x792a, 0x00f8, 0x8001, 0x7002, 0x9184, 0x0880, 0x1140, 0x782c,
+	0xd0fc, 0x1904, 0x3f5e, 0x2011, 0x0001, 0x00b1, 0x0090, 0xa010,
+	0x9092, 0x0004, 0x9086, 0x0015, 0x1120, 0xa000, 0xa05a, 0x2011,
+	0x0031, 0xa212, 0xd1dc, 0x1960, 0x0828, 0x782b, 0x0004, 0x7003,
+	0x0000, 0x00ee, 0x00fe, 0x0005, 0xa014, 0x9005, 0x0550, 0x8001,
+	0x0036, 0x0096, 0xa016, 0xa058, 0x2048, 0xa010, 0x2009, 0x0031,
+	0x911a, 0x831c, 0x831c, 0x938a, 0x0007, 0x1a0c, 0x0e02, 0x9398,
+	0x3fea, 0x231d, 0x083f, 0x9080, 0x0004, 0x7a2a, 0x7100, 0x8108,
+	0x7102, 0x009e, 0x003e, 0x908a, 0x0035, 0x1140, 0x0096, 0xa058,
+	0x2048, 0xa804, 0xa05a, 0x2001, 0x0019, 0x009e, 0xa012, 0x9085,
+	0x0001, 0x0005, 0x4027, 0x401e, 0x4015, 0x400c, 0x4003, 0x3ffa,
+	0x3ff1, 0xa964, 0x7902, 0xa968, 0x7906, 0xa96c, 0x7912, 0xa970,
+	0x7916, 0x0005, 0xa974, 0x7902, 0xa978, 0x7906, 0xa97c, 0x7912,
+	0xa980, 0x7916, 0x0005, 0xa984, 0x7902, 0xa988, 0x7906, 0xa98c,
+	0x7912, 0xa990, 0x7916, 0x0005, 0xa994, 0x7902, 0xa998, 0x7906,
+	0xa99c, 0x7912, 0xa9a0, 0x7916, 0x0005, 0xa9a4, 0x7902, 0xa9a8,
+	0x7906, 0xa9ac, 0x7912, 0xa9b0, 0x7916, 0x0005, 0xa9b4, 0x7902,
+	0xa9b8, 0x7906, 0xa9bc, 0x7912, 0xa9c0, 0x7916, 0x0005, 0xa9c4,
+	0x7902, 0xa9c8, 0x7906, 0xa9cc, 0x7912, 0xa9d0, 0x7916, 0x0005,
+	0x00f6, 0x00e6, 0x0086, 0x2071, 0x1a42, 0x2079, 0x0090, 0x792c,
+	0xd1fc, 0x01e8, 0x782b, 0x0002, 0x2940, 0x9026, 0x7000, 0x0002,
+	0x4057, 0x4043, 0x404e, 0x8001, 0x7002, 0xd19c, 0x1180, 0x2011,
+	0x0001, 0x080c, 0x3fbc, 0x190c, 0x3fbc, 0x0048, 0x8001, 0x7002,
+	0x782c, 0xd0fc, 0x1d38, 0x2011, 0x0001, 0x080c, 0x3fbc, 0x008e,
+	0x00ee, 0x00fe, 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x0086, 0x2061,
+	0x0200, 0x2001, 0x1984, 0x2004, 0x601a, 0x2061, 0x0100, 0x2001,
+	0x1983, 0x2004, 0x60ce, 0x6104, 0xc1ac, 0x6106, 0x2001, 0x002c,
+	0x2004, 0x9005, 0x0520, 0x2038, 0x2001, 0x002e, 0x2024, 0x2001,
+	0x002f, 0x201c, 0x080c, 0x49b8, 0xa813, 0x0019, 0xaf16, 0x2900,
 	0xa85a, 0x978a, 0x0007, 0x0220, 0x2138, 0x2009, 0x0007, 0x0010,
 	0x2708, 0x903e, 0x0096, 0xa858, 0x2048, 0xa85c, 0x9080, 0x0019,
-	0x009e, 0x080c, 0x41a4, 0x1d68, 0x2900, 0xa85a, 0x00d8, 0x080c,
-	0x4abf, 0x2940, 0xa013, 0x0019, 0xa017, 0x0001, 0x2800, 0xa05a,
-	0x2001, 0x0030, 0x2004, 0xa066, 0x2001, 0x0031, 0x2004, 0xa06a,
-	0x2001, 0x002a, 0x2004, 0x9084, 0xfff8, 0xa06e, 0x2001, 0x002b,
-	0x2004, 0xa072, 0x2001, 0x032a, 0x2003, 0x0004, 0x7884, 0xd0ac,
-	0x1180, 0x2001, 0x0101, 0x200c, 0x918d, 0x0200, 0x2102, 0xa017,
-	0x0000, 0x2001, 0x1a3a, 0x2003, 0x0003, 0x2001, 0x032a, 0x2003,
-	0x0009, 0x2001, 0x0300, 0x2003, 0x0000, 0x2001, 0x020d, 0x2003,
-	0x0000, 0x2001, 0x0004, 0x200c, 0x918d, 0x0002, 0x2102, 0x00ee,
-	0x0005, 0x0126, 0x2091, 0x8000, 0x20a9, 0x001b, 0x20a1, 0x1840,
-	0x20e9, 0x0001, 0x9006, 0x4004, 0x2009, 0x013c, 0x200a, 0x012e,
-	0x7880, 0x9086, 0x0052, 0x0108, 0x0005, 0x0804, 0x34e8, 0x7d98,
-	0x7c9c, 0x0804, 0x35ea, 0x080c, 0x7207, 0x190c, 0x5ef0, 0x2069,
-	0x185b, 0x2d00, 0x2009, 0x0030, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98,
-	0x2039, 0x0001, 0x080c, 0x4b08, 0x701f, 0x4277, 0x0005, 0x080c,
-	0x55ea, 0x1130, 0x3b00, 0x3a08, 0xc194, 0xc095, 0x20d8, 0x21d0,
-	0x2069, 0x185b, 0x6800, 0x9005, 0x0904, 0x351d, 0x6804, 0xd094,
-	0x00c6, 0x2061, 0x0100, 0x6104, 0x0138, 0x6200, 0x9292, 0x0005,
-	0x0218, 0x918c, 0xffdf, 0x0010, 0x918d, 0x0020, 0x6106, 0x00ce,
-	0xd08c, 0x00c6, 0x2061, 0x0100, 0x6104, 0x0118, 0x918d, 0x0010,
-	0x0010, 0x918c, 0xffef, 0x6106, 0x00ce, 0xd084, 0x0158, 0x6a28,
-	0x928a, 0x007f, 0x1a04, 0x351d, 0x9288, 0x32e9, 0x210d, 0x918c,
-	0x00ff, 0x6162, 0xd0dc, 0x0130, 0x6828, 0x908a, 0x007f, 0x1a04,
-	0x351d, 0x605a, 0x6888, 0x9084, 0x0030, 0x8004, 0x8004, 0x8004,
-	0x8004, 0x0006, 0x2009, 0x1989, 0x9080, 0x28aa, 0x2005, 0x200a,
-	0x000e, 0x2009, 0x198a, 0x9080, 0x28ae, 0x2005, 0x200a, 0x6808,
-	0x908a, 0x0100, 0x0a04, 0x351d, 0x908a, 0x0841, 0x1a04, 0x351d,
-	0x9084, 0x0007, 0x1904, 0x351d, 0x680c, 0x9005, 0x0904, 0x351d,
-	0x6810, 0x9005, 0x0904, 0x351d, 0x6848, 0x6940, 0x910a, 0x1a04,
-	0x351d, 0x8001, 0x0904, 0x351d, 0x684c, 0x6944, 0x910a, 0x1a04,
-	0x351d, 0x8001, 0x0904, 0x351d, 0x2009, 0x1959, 0x200b, 0x0000,
-	0x2001, 0x187d, 0x2004, 0xd0c4, 0x0140, 0x7884, 0x200a, 0x2009,
-	0x017f, 0x200a, 0x3b00, 0xc085, 0x20d8, 0x6814, 0x908c, 0x00ff,
-	0x614a, 0x8007, 0x9084, 0x00ff, 0x604e, 0x080c, 0x7535, 0x080c,
-	0x688c, 0x080c, 0x68c1, 0x6808, 0x602a, 0x080c, 0x227c, 0x2009,
-	0x0170, 0x200b, 0x0080, 0xa001, 0xa001, 0x200b, 0x0000, 0x0036,
-	0x6b08, 0x080c, 0x2811, 0x003e, 0x6000, 0x9086, 0x0000, 0x1904,
-	0x43f8, 0x6818, 0x691c, 0x6a20, 0x6b24, 0x8007, 0x810f, 0x8217,
-	0x831f, 0x6016, 0x611a, 0x621e, 0x6322, 0x6c04, 0xd4f4, 0x0148,
-	0x6830, 0x6934, 0x6a38, 0x6b3c, 0x8007, 0x810f, 0x8217, 0x831f,
-	0x0010, 0x9084, 0xf0ff, 0x6006, 0x610a, 0x620e, 0x6312, 0x8007,
-	0x810f, 0x8217, 0x831f, 0x20a9, 0x0004, 0x20a1, 0x198b, 0x20e9,
-	0x0001, 0x4001, 0x20a9, 0x0004, 0x20a1, 0x19a5, 0x20e9, 0x0001,
-	0x4001, 0x080c, 0x83e3, 0x00c6, 0x900e, 0x20a9, 0x0001, 0x6b70,
-	0xd384, 0x01c8, 0x0020, 0x839d, 0x12b0, 0x3508, 0x8109, 0x080c,
-	0x7af8, 0x6878, 0x6016, 0x6874, 0x2008, 0x9084, 0xff00, 0x8007,
-	0x600a, 0x9184, 0x00ff, 0x6006, 0x8108, 0x1118, 0x6003, 0x0003,
-	0x0010, 0x6003, 0x0001, 0x1f04, 0x4363, 0x00ce, 0x00c6, 0x2061,
-	0x1974, 0x2063, 0x0001, 0x9006, 0x080c, 0x2ab8, 0x9006, 0x080c,
-	0x2a9b, 0x0000, 0x00ce, 0x00e6, 0x2c70, 0x080c, 0x0ec6, 0x00ee,
-	0x6888, 0xd0ec, 0x0198, 0x2001, 0x0100, 0x2004, 0x9086, 0x000a,
-	0x0138, 0x2011, 0x0114, 0x2204, 0x9085, 0x0100, 0x2012, 0x0030,
-	0x2011, 0x0114, 0x2204, 0x9085, 0x0180, 0x2012, 0x6a80, 0x9284,
-	0x0030, 0x9086, 0x0030, 0x1128, 0x9294, 0xffcf, 0x9295, 0x0020,
-	0x6a82, 0x2001, 0x1954, 0x6a80, 0x9294, 0x0030, 0x928e, 0x0000,
-	0x0170, 0x928e, 0x0010, 0x0118, 0x928e, 0x0020, 0x0140, 0x2003,
-	0xaaaa, 0x080c, 0x2886, 0x2001, 0x1945, 0x2102, 0x0008, 0x2102,
-	0x00c6, 0x2061, 0x0100, 0x602f, 0x0040, 0x602f, 0x0000, 0x00ce,
-	0x080c, 0x7207, 0x0128, 0x080c, 0x4ed2, 0x0110, 0x080c, 0x27d7,
-	0x60d0, 0x9005, 0x01c0, 0x6003, 0x0001, 0x2009, 0x43e0, 0x00d0,
-	0x080c, 0x7207, 0x1168, 0x2011, 0x7076, 0x080c, 0x82da, 0x2011,
-	0x7069, 0x080c, 0x83ae, 0x080c, 0x7509, 0x080c, 0x7127, 0x0040,
-	0x080c, 0x5dea, 0x0028, 0x6003, 0x0004, 0x2009, 0x43f8, 0x0010,
-	0x0804, 0x34e8, 0x2001, 0x0170, 0x2004, 0x9084, 0x00ff, 0x9086,
-	0x004c, 0x1118, 0x2091, 0x30bd, 0x0817, 0x2091, 0x303d, 0x0817,
-	0x6000, 0x9086, 0x0000, 0x0904, 0x351a, 0x2069, 0x185b, 0x7890,
-	0x6842, 0x7894, 0x6846, 0x2d00, 0x2009, 0x0030, 0x7a8c, 0x7b88,
-	0x7c9c, 0x7d98, 0x2039, 0x0001, 0x0804, 0x4b0b, 0x9006, 0x080c,
-	0x27d7, 0x81ff, 0x1904, 0x351a, 0x080c, 0x7207, 0x11b0, 0x080c,
-	0x7504, 0x080c, 0x5f2b, 0x080c, 0x32e4, 0x0118, 0x6130, 0xc18d,
-	0x6132, 0x080c, 0xc539, 0x0130, 0x080c, 0x722a, 0x1118, 0x080c,
-	0x71df, 0x0038, 0x080c, 0x7127, 0x0020, 0x080c, 0x5ef0, 0x080c,
-	0x5dea, 0x0804, 0x34e8, 0x81ff, 0x1904, 0x351a, 0x080c, 0x7207,
-	0x1110, 0x0804, 0x351a, 0x6190, 0x81ff, 0x01a8, 0x704f, 0x0000,
-	0x2001, 0x1c80, 0x2009, 0x0040, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98,
-	0x0126, 0x2091, 0x8000, 0x2039, 0x0001, 0x080c, 0x4b0b, 0x701f,
-	0x34e6, 0x012e, 0x0005, 0x704f, 0x0001, 0x00d6, 0x2069, 0x1c80,
-	0x20a9, 0x0040, 0x20e9, 0x0001, 0x20a1, 0x1c80, 0x2019, 0xffff,
-	0x4304, 0x6558, 0x9588, 0x32e9, 0x210d, 0x918c, 0x00ff, 0x216a,
-	0x900e, 0x2011, 0x0002, 0x2100, 0x9506, 0x01a8, 0x080c, 0x649f,
-	0x1190, 0xb814, 0x821c, 0x0238, 0x9398, 0x1c80, 0x9085, 0xff00,
-	0x8007, 0x201a, 0x0038, 0x9398, 0x1c80, 0x2324, 0x94a4, 0xff00,
-	0x9405, 0x201a, 0x8210, 0x8108, 0x9182, 0x0080, 0x1208, 0x0c18,
-	0x8201, 0x8007, 0x2d0c, 0x9105, 0x206a, 0x00de, 0x20a9, 0x0040,
-	0x20a1, 0x1c80, 0x2099, 0x1c80, 0x080c, 0x5e7b, 0x0804, 0x4450,
-	0x080c, 0x4af2, 0x0904, 0x351d, 0x080c, 0x4abf, 0x1120, 0x2009,
-	0x0002, 0x0804, 0x351a, 0x080c, 0x55db, 0xd0b4, 0x0558, 0x7884,
-	0x908e, 0x007e, 0x0538, 0x908e, 0x007f, 0x0520, 0x908e, 0x0080,
-	0x0508, 0x080c, 0x32df, 0x1148, 0xb800, 0xd08c, 0x11d8, 0xb804,
-	0x9084, 0x00ff, 0x9086, 0x0006, 0x11a8, 0xa867, 0x0000, 0xa868,
-	0xc0fd, 0xa86a, 0x080c, 0xc002, 0x1120, 0x2009, 0x0003, 0x0804,
-	0x351a, 0x7007, 0x0003, 0x701f, 0x44de, 0x0005, 0x080c, 0x4af2,
-	0x0904, 0x351d, 0x20a9, 0x002b, 0xb8b4, 0x20e0, 0xb8b8, 0x2098,
-	0xa860, 0x20e8, 0xa85c, 0x9080, 0x0002, 0x20a0, 0x4003, 0x20a9,
-	0x0008, 0x9080, 0x0006, 0x20a0, 0xb8b4, 0x20e0, 0xb8b8, 0x9080,
-	0x0006, 0x2098, 0x080c, 0x0fae, 0x0070, 0x20a9, 0x0004, 0xa85c,
-	0x9080, 0x000a, 0x20a0, 0xb8b4, 0x20e0, 0xb8b8, 0x9080, 0x000a,
-	0x2098, 0x080c, 0x0fae, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f,
-	0x9084, 0xffc0, 0x9080, 0x0002, 0x2009, 0x002b, 0x7a8c, 0x7b88,
-	0x7c9c, 0x7d98, 0x0804, 0x4b0b, 0x81ff, 0x1904, 0x351a, 0x080c,
-	0x4ad6, 0x0904, 0x351d, 0x080c, 0x6611, 0x0904, 0x351a, 0x0058,
-	0xa878, 0x9005, 0x0120, 0x2009, 0x0004, 0x0804, 0x351a, 0xa974,
-	0xaa94, 0x0804, 0x34e8, 0x080c, 0x55e3, 0x0904, 0x34e8, 0x701f,
-	0x4528, 0x7007, 0x0003, 0x0005, 0x81ff, 0x1904, 0x351a, 0x7888,
-	0x908a, 0x1000, 0x1a04, 0x351d, 0x080c, 0x4af2, 0x0904, 0x351d,
-	0x080c, 0x67c3, 0x0120, 0x080c, 0x67cb, 0x1904, 0x351d, 0x080c,
-	0x6696, 0x0904, 0x351a, 0x2019, 0x0004, 0x900e, 0x080c, 0x6623,
-	0x0904, 0x351a, 0x7984, 0x7a88, 0x04c9, 0x08a8, 0xa89c, 0x908a,
-	0x1000, 0x12f8, 0x080c, 0x4af0, 0x01e0, 0x080c, 0x67c3, 0x0118,
-	0x080c, 0x67cb, 0x11b0, 0x080c, 0x6696, 0x2009, 0x0002, 0x0168,
-	0x2009, 0x0002, 0x2019, 0x0004, 0x080c, 0x6623, 0x2009, 0x0003,
-	0x0120, 0xa998, 0xaa9c, 0x00d1, 0x0060, 0xa897, 0x4005, 0xa99a,
-	0x0010, 0xa897, 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030,
-	0x0005, 0xa897, 0x4000, 0x080c, 0x55e3, 0x0110, 0x9006, 0x0018,
-	0x900e, 0x9085, 0x0001, 0x2001, 0x0000, 0x0005, 0x9186, 0x00ff,
-	0x0110, 0x0071, 0x0060, 0x2029, 0x007e, 0x2061, 0x1800, 0x6458,
-	0x2400, 0x9506, 0x0110, 0x2508, 0x0019, 0x8529, 0x1ec8, 0x0005,
-	0x080c, 0x649f, 0x1138, 0x2200, 0x8003, 0x800b, 0x810b, 0x9108,
-	0x080c, 0x82e8, 0x0005, 0x81ff, 0x1904, 0x351a, 0x798c, 0x2001,
-	0x1958, 0x918c, 0x8000, 0x2102, 0x080c, 0x4ad6, 0x0904, 0x351d,
-	0x080c, 0x67c3, 0x0120, 0x080c, 0x67cb, 0x1904, 0x351d, 0x080c,
-	0x6566, 0x0904, 0x351a, 0x080c, 0x661a, 0x0904, 0x351a, 0x2001,
-	0x1958, 0x2004, 0xd0fc, 0x1904, 0x34e8, 0x0804, 0x4533, 0xa9a0,
-	0x2001, 0x1958, 0x918c, 0x8000, 0xc18d, 0x2102, 0x080c, 0x4ae3,
-	0x01a0, 0x080c, 0x67c3, 0x0118, 0x080c, 0x67cb, 0x1170, 0x080c,
-	0x6566, 0x2009, 0x0002, 0x0128, 0x080c, 0x661a, 0x1170, 0x2009,
-	0x0003, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e,
-	0x9085, 0x0001, 0x2001, 0x0030, 0x0005, 0xa897, 0x4000, 0x2001,
-	0x1958, 0x2004, 0xd0fc, 0x1128, 0x080c, 0x55e3, 0x0110, 0x9006,
-	0x0018, 0x900e, 0x9085, 0x0001, 0x2001, 0x0000, 0x0005, 0x81ff,
-	0x1904, 0x351a, 0x798c, 0x2001, 0x1957, 0x918c, 0x8000, 0x2102,
-	0x080c, 0x4ad6, 0x0904, 0x351d, 0x080c, 0x67c3, 0x0120, 0x080c,
-	0x67cb, 0x1904, 0x351d, 0x080c, 0x6566, 0x0904, 0x351a, 0x080c,
-	0x6608, 0x0904, 0x351a, 0x2001, 0x1957, 0x2004, 0xd0fc, 0x1904,
-	0x34e8, 0x0804, 0x4533, 0xa9a0, 0x2001, 0x1957, 0x918c, 0x8000,
-	0xc18d, 0x2102, 0x080c, 0x4ae3, 0x01a0, 0x080c, 0x67c3, 0x0118,
-	0x080c, 0x67cb, 0x1170, 0x080c, 0x6566, 0x2009, 0x0002, 0x0128,
-	0x080c, 0x6608, 0x1170, 0x2009, 0x0003, 0xa897, 0x4005, 0xa99a,
-	0x0010, 0xa897, 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030,
-	0x0005, 0xa897, 0x4000, 0x2001, 0x1957, 0x2004, 0xd0fc, 0x1128,
-	0x080c, 0x55e3, 0x0110, 0x9006, 0x0018, 0x900e, 0x9085, 0x0001,
-	0x2001, 0x0000, 0x0005, 0x6100, 0x0804, 0x34e8, 0x080c, 0x4af2,
-	0x0904, 0x351d, 0x080c, 0x55ef, 0x1904, 0x351a, 0x79a8, 0xd184,
-	0x1158, 0xb834, 0x8007, 0x789e, 0xb830, 0x8007, 0x789a, 0xbb2c,
-	0x831f, 0xba28, 0x8217, 0x0050, 0xb824, 0x8007, 0x789e, 0xb820,
-	0x8007, 0x789a, 0xbb1c, 0x831f, 0xba18, 0x8217, 0xb900, 0x918c,
-	0x0202, 0x0804, 0x34e8, 0x78a8, 0x909c, 0x0003, 0xd0ac, 0x1158,
-	0xd0b4, 0x1148, 0x939a, 0x0003, 0x1a04, 0x351a, 0x6258, 0x7884,
-	0x9206, 0x1904, 0x46eb, 0x2031, 0x1848, 0x2009, 0x013c, 0x2136,
-	0x2001, 0x1840, 0x2009, 0x000c, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98,
-	0x2039, 0x0001, 0x0006, 0x78a8, 0x9084, 0x0080, 0x11f8, 0x0006,
-	0x0036, 0x2001, 0x1a57, 0x201c, 0x7b9a, 0x2003, 0x0000, 0x2001,
-	0x1a58, 0x201c, 0x7b9e, 0x2003, 0x0000, 0x2001, 0x1a59, 0x201c,
-	0x7ba2, 0x2003, 0x0000, 0x2001, 0x1a53, 0x201c, 0x7baa, 0x2003,
-	0x0000, 0x003e, 0x000e, 0x000e, 0x0804, 0x4b0b, 0x000e, 0x2031,
-	0x0000, 0x2061, 0x18b6, 0x2c44, 0xa66a, 0xa17a, 0xa772, 0xa076,
-	0xa28e, 0xa392, 0xa496, 0xa59a, 0x080c, 0x112e, 0x7007, 0x0002,
-	0x701f, 0x470b, 0x0005, 0x81ff, 0x1904, 0x351a, 0x080c, 0x4af2,
-	0x0904, 0x351d, 0x080c, 0x67c3, 0x1904, 0x351a, 0x00c6, 0x080c,
-	0x4abf, 0x00ce, 0x0904, 0x351a, 0xa867, 0x0000, 0xa868, 0xc0fd,
-	0xa86a, 0x7ea8, 0x080c, 0xbfa8, 0x0904, 0x351a, 0x7007, 0x0003,
-	0x701f, 0x472b, 0x0005, 0x080c, 0x4249, 0x0006, 0x0036, 0x2001,
-	0x1a57, 0x201c, 0x7b9a, 0x2003, 0x0000, 0x2001, 0x1a58, 0x201c,
-	0x7b9e, 0x2003, 0x0000, 0x2001, 0x1a59, 0x201c, 0x7ba2, 0x2003,
-	0x0000, 0x2001, 0x1a53, 0x201c, 0x7baa, 0x2003, 0x0000, 0x003e,
-	0x000e, 0x0804, 0x34e8, 0xa830, 0x9086, 0x0100, 0x0904, 0x351a,
-	0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080,
-	0x001b, 0x2009, 0x000c, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x0804,
-	0x4b0b, 0x9006, 0x080c, 0x27d7, 0x78a8, 0x9084, 0x00ff, 0x9086,
-	0x00ff, 0x0118, 0x81ff, 0x1904, 0x351a, 0x080c, 0x7207, 0x0110,
-	0x080c, 0x5ef0, 0x7888, 0x908a, 0x1000, 0x1a04, 0x351d, 0x7984,
-	0x9186, 0x00ff, 0x0138, 0x9182, 0x007f, 0x1a04, 0x351d, 0x2100,
-	0x080c, 0x27a1, 0x0026, 0x00c6, 0x0126, 0x2091, 0x8000, 0x2061,
-	0x19d2, 0x601b, 0x0000, 0x601f, 0x0000, 0x6073, 0x0000, 0x6077,
-	0x0000, 0x080c, 0x7207, 0x1158, 0x080c, 0x7504, 0x080c, 0x5f2b,
-	0x9085, 0x0001, 0x080c, 0x724e, 0x080c, 0x7127, 0x00d0, 0x080c,
-	0xa069, 0x2061, 0x0100, 0x2001, 0x1817, 0x2004, 0x9084, 0x00ff,
-	0x810f, 0x9105, 0x604a, 0x6043, 0x0090, 0x6043, 0x0010, 0x2009,
-	0x1971, 0x200b, 0x0000, 0x2009, 0x002d, 0x2011, 0x5e16, 0x080c,
-	0x836c, 0x7984, 0x080c, 0x7207, 0x1110, 0x2009, 0x00ff, 0x7a88,
-	0x080c, 0x4596, 0x012e, 0x00ce, 0x002e, 0x0804, 0x34e8, 0x7984,
-	0x080c, 0x643f, 0x2b08, 0x1904, 0x351d, 0x0804, 0x34e8, 0x81ff,
-	0x0120, 0x2009, 0x0001, 0x0804, 0x351a, 0x60d8, 0xd0ac, 0x1130,
-	0xd09c, 0x1120, 0x2009, 0x0005, 0x0804, 0x351a, 0x080c, 0x4abf,
-	0x1120, 0x2009, 0x0002, 0x0804, 0x351a, 0x7984, 0x9192, 0x0021,
-	0x1a04, 0x351d, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0xa85c, 0x9080,
-	0x0019, 0x702a, 0xaf60, 0x7736, 0x080c, 0x4b08, 0x701f, 0x47df,
-	0x7880, 0x9086, 0x006e, 0x0110, 0x701f, 0x5084, 0x0005, 0x2009,
-	0x0080, 0x080c, 0x649f, 0x1118, 0x080c, 0x67c3, 0x0120, 0x2021,
-	0x400a, 0x0804, 0x34ea, 0x00d6, 0x0096, 0xa964, 0xaa6c, 0xab70,
-	0xac74, 0xad78, 0xae7c, 0xa884, 0x90be, 0x0100, 0x0904, 0x4878,
-	0x90be, 0x0112, 0x0904, 0x4878, 0x90be, 0x0113, 0x0904, 0x4878,
-	0x90be, 0x0114, 0x0904, 0x4878, 0x90be, 0x0117, 0x0904, 0x4878,
-	0x90be, 0x011a, 0x0904, 0x4878, 0x90be, 0x011c, 0x0904, 0x4878,
-	0x90be, 0x0121, 0x0904, 0x485f, 0x90be, 0x0131, 0x0904, 0x485f,
-	0x90be, 0x0171, 0x0904, 0x4878, 0x90be, 0x0173, 0x0904, 0x4878,
-	0x90be, 0x01a1, 0x1128, 0xa894, 0x8007, 0xa896, 0x0804, 0x4883,
-	0x90be, 0x0212, 0x0904, 0x486c, 0x90be, 0x0213, 0x05e8, 0x90be,
-	0x0214, 0x0500, 0x90be, 0x0217, 0x0188, 0x90be, 0x021a, 0x1120,
-	0xa89c, 0x8007, 0xa89e, 0x04e0, 0x90be, 0x021f, 0x05c8, 0x90be,
-	0x0300, 0x05b0, 0x009e, 0x00de, 0x0804, 0x351d, 0x7028, 0x9080,
-	0x0010, 0x2098, 0x20a0, 0x7034, 0x20e0, 0x20e8, 0x20a9, 0x0007,
-	0x080c, 0x48c1, 0x7028, 0x9080, 0x000e, 0x2098, 0x20a0, 0x7034,
-	0x20e0, 0x20e8, 0x20a9, 0x0001, 0x080c, 0x48c1, 0x00c8, 0x7028,
-	0x9080, 0x000c, 0x2098, 0x20a0, 0x7034, 0x20e0, 0x20e8, 0x20a9,
-	0x0001, 0x080c, 0x48ce, 0x00b8, 0x7028, 0x9080, 0x000e, 0x2098,
-	0x20a0, 0x7034, 0x20e0, 0x20e8, 0x20a9, 0x0001, 0x080c, 0x48ce,
-	0x7028, 0x9080, 0x000c, 0x2098, 0x20a0, 0x7034, 0x20e0, 0x20e8,
-	0x20a9, 0x0001, 0x04f1, 0x00c6, 0x080c, 0x4abf, 0x0550, 0xa868,
-	0xc0fd, 0xa86a, 0xa867, 0x0119, 0x9006, 0xa882, 0xa87f, 0x0020,
-	0xa88b, 0x0001, 0x810b, 0xa9ae, 0xa8b2, 0xaab6, 0xabba, 0xacbe,
-	0xadc2, 0xa9c6, 0xa8ca, 0x00ce, 0x009e, 0x00de, 0xa866, 0xa822,
-	0xa868, 0xc0fd, 0xa86a, 0xa804, 0x2048, 0x080c, 0xbfc3, 0x1120,
-	0x2009, 0x0003, 0x0804, 0x351a, 0x7007, 0x0003, 0x701f, 0x48b8,
-	0x0005, 0x00ce, 0x009e, 0x00de, 0x2009, 0x0002, 0x0804, 0x351a,
-	0xa820, 0x9086, 0x8001, 0x1904, 0x34e8, 0x2009, 0x0004, 0x0804,
-	0x351a, 0x0016, 0x0026, 0x3510, 0x20a9, 0x0002, 0x4002, 0x4104,
-	0x4004, 0x8211, 0x1dc8, 0x002e, 0x001e, 0x0005, 0x0016, 0x0026,
-	0x0036, 0x0046, 0x3520, 0x20a9, 0x0004, 0x4002, 0x4304, 0x4204,
-	0x4104, 0x4004, 0x8421, 0x1db8, 0x004e, 0x003e, 0x002e, 0x001e,
-	0x0005, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x351a, 0x60d8,
-	0xd0ac, 0x1160, 0xd09c, 0x0120, 0x2009, 0x0016, 0x0804, 0x351a,
-	0xd09c, 0x1120, 0x2009, 0x0005, 0x0804, 0x351a, 0x7984, 0x78a8,
-	0x2040, 0x080c, 0xa062, 0x1120, 0x9182, 0x007f, 0x0a04, 0x351d,
-	0x9186, 0x00ff, 0x0904, 0x351d, 0x9182, 0x0800, 0x1a04, 0x351d,
-	0x7a8c, 0x7b88, 0x6078, 0x9306, 0x1158, 0x607c, 0x924e, 0x0904,
-	0x351d, 0x080c, 0xa062, 0x1120, 0x99cc, 0xff00, 0x0904, 0x351d,
-	0x0126, 0x2091, 0x8000, 0x9386, 0xffff, 0x0178, 0x0026, 0x2011,
-	0x8008, 0x080c, 0x67e7, 0x002e, 0x0140, 0x918d, 0x8000, 0x080c,
-	0x6831, 0x1118, 0x2001, 0x4009, 0x0458, 0x080c, 0x49d9, 0x0560,
-	0x90c6, 0x4000, 0x1170, 0x00c6, 0x0006, 0x900e, 0x080c, 0x66bf,
-	0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x000e, 0x00ce,
-	0x00b8, 0x90c6, 0x4007, 0x1110, 0x2408, 0x0090, 0x90c6, 0x4008,
-	0x1118, 0x2708, 0x2610, 0x0060, 0x90c6, 0x4009, 0x1108, 0x0040,
-	0x90c6, 0x4006, 0x1108, 0x0020, 0x2001, 0x4005, 0x2009, 0x000a,
-	0x2020, 0x012e, 0x0804, 0x34ea, 0x2b00, 0x7026, 0x0016, 0x00b6,
-	0x00c6, 0x00e6, 0x2c70, 0x080c, 0xa130, 0x0904, 0x49a6, 0x2b00,
-	0x6012, 0x080c, 0xc2b3, 0x2e58, 0x00ee, 0x00e6, 0x00c6, 0x080c,
-	0x4abf, 0x00ce, 0x2b70, 0x1158, 0x080c, 0xa0e3, 0x00ee, 0x00ce,
-	0x00be, 0x001e, 0x012e, 0x2009, 0x0002, 0x0804, 0x351a, 0x900e,
-	0xa966, 0xa96a, 0x2900, 0x6016, 0xa932, 0xa868, 0xc0fd, 0xd88c,
-	0x0108, 0xc0f5, 0xa86a, 0x080c, 0x318b, 0x6023, 0x0001, 0x9006,
-	0x080c, 0x63dc, 0x2001, 0x0002, 0x080c, 0x63f0, 0x2009, 0x0002,
-	0x080c, 0xa15d, 0x78a8, 0xd094, 0x0138, 0x00ee, 0x7024, 0x00e6,
-	0x2058, 0xb8bc, 0xc08d, 0xb8be, 0x9085, 0x0001, 0x00ee, 0x00ce,
-	0x00be, 0x001e, 0x012e, 0x1120, 0x2009, 0x0003, 0x0804, 0x351a,
-	0x7007, 0x0003, 0x701f, 0x49b5, 0x0005, 0xa830, 0x2008, 0x918e,
-	0xdead, 0x1120, 0x2021, 0x4009, 0x0804, 0x34ea, 0x9086, 0x0100,
-	0x7024, 0x2058, 0x1138, 0x2009, 0x0004, 0xba04, 0x9294, 0x00ff,
-	0x0804, 0x552f, 0x900e, 0xa868, 0xd0f4, 0x1904, 0x34e8, 0x080c,
-	0x66bf, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x0804,
-	0x34e8, 0x00e6, 0x00d6, 0x0096, 0x83ff, 0x0904, 0x4a21, 0x902e,
-	0x080c, 0xa062, 0x0130, 0x9026, 0x20a9, 0x0800, 0x2071, 0x1000,
-	0x0030, 0x2021, 0x007f, 0x20a9, 0x0781, 0x2071, 0x107f, 0x2e04,
-	0x9005, 0x11b0, 0x2100, 0x9406, 0x15e8, 0x2428, 0x94ce, 0x007f,
-	0x1120, 0x92ce, 0xfffd, 0x1528, 0x0030, 0x94ce, 0x0080, 0x1130,
-	0x92ce, 0xfffc, 0x11f0, 0x93ce, 0x00ff, 0x11d8, 0xc5fd, 0x0450,
-	0x2058, 0xbf10, 0x2700, 0x9306, 0x11b8, 0xbe14, 0x2600, 0x9206,
-	0x1198, 0x2400, 0x9106, 0x1150, 0xd884, 0x0568, 0xd894, 0x1558,
-	0x080c, 0x67c3, 0x1540, 0x2001, 0x4000, 0x0430, 0x2001, 0x4007,
-	0x0418, 0x2001, 0x4006, 0x0400, 0x2400, 0x9106, 0x1158, 0xbe14,
-	0x87ff, 0x1128, 0x86ff, 0x0948, 0x080c, 0xa062, 0x1930, 0x2001,
-	0x4008, 0x0090, 0x8420, 0x8e70, 0x1f04, 0x49ef, 0x85ff, 0x1130,
-	0x2001, 0x4009, 0x0048, 0x2001, 0x0001, 0x0030, 0x080c, 0x643f,
-	0x1dd0, 0xbb12, 0xba16, 0x9006, 0x9005, 0x009e, 0x00de, 0x00ee,
-	0x0005, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x351a, 0x080c,
-	0x4abf, 0x1120, 0x2009, 0x0002, 0x0804, 0x351a, 0xa867, 0x0000,
-	0xa868, 0xc0fd, 0xa86a, 0x7884, 0x9005, 0x0904, 0x351d, 0x9096,
-	0x00ff, 0x0120, 0x9092, 0x0004, 0x1a04, 0x351d, 0x2010, 0x2918,
-	0x080c, 0x3131, 0x1120, 0x2009, 0x0003, 0x0804, 0x351a, 0x7007,
-	0x0003, 0x701f, 0x4a74, 0x0005, 0xa830, 0x9086, 0x0100, 0x1904,
-	0x34e8, 0x2009, 0x0004, 0x0804, 0x351a, 0x7984, 0x080c, 0xa062,
-	0x1120, 0x9182, 0x007f, 0x0a04, 0x351d, 0x9186, 0x00ff, 0x0904,
-	0x351d, 0x9182, 0x0800, 0x1a04, 0x351d, 0x2001, 0x9400, 0x080c,
-	0x558a, 0x1904, 0x351a, 0x0804, 0x34e8, 0xa998, 0x080c, 0xa062,
-	0x1118, 0x9182, 0x007f, 0x0280, 0x9186, 0x00ff, 0x0168, 0x9182,
-	0x0800, 0x1250, 0x2001, 0x9400, 0x080c, 0x558a, 0x11a8, 0x0060,
+	0x009e, 0x080c, 0x40d3, 0x1d68, 0x2900, 0xa85a, 0x00d0, 0x080c,
+	0x49b8, 0xa813, 0x0019, 0xa817, 0x0001, 0x2900, 0xa85a, 0x2001,
+	0x002e, 0x2004, 0xa866, 0x2001, 0x002f, 0x2004, 0xa86a, 0x2001,
+	0x002a, 0x2004, 0x9084, 0xfff8, 0xa86e, 0x2001, 0x002b, 0x2004,
+	0xa872, 0x2061, 0x0090, 0x2079, 0x0100, 0x2001, 0x1983, 0x2004,
+	0x6036, 0x2009, 0x0040, 0x080c, 0x2204, 0x2001, 0x002a, 0x2004,
+	0x9084, 0xfff8, 0x601a, 0x0006, 0x2001, 0x002b, 0x2004, 0x601e,
+	0x78c6, 0x000e, 0x78ca, 0x9006, 0x600a, 0x600e, 0x008e, 0x00ce,
+	0x00ee, 0x00fe, 0x0005, 0x00e6, 0x2071, 0x0080, 0xaa60, 0x22e8,
+	0x20a0, 0x20e1, 0x0000, 0x2099, 0x0088, 0x702b, 0x0026, 0x7402,
+	0x7306, 0x9006, 0x700a, 0x700e, 0x810b, 0x810b, 0x21a8, 0x810b,
+	0x7112, 0x702b, 0x0041, 0x702c, 0xd0fc, 0x0de8, 0x702b, 0x0002,
+	0x702b, 0x0040, 0x4005, 0x7400, 0x7304, 0x87ff, 0x0190, 0x0086,
+	0x0096, 0x2940, 0x0086, 0x080c, 0x49b8, 0x008e, 0xa058, 0x00a6,
+	0x2050, 0x2900, 0xb006, 0xa05a, 0x00ae, 0x009e, 0x008e, 0x9085,
+	0x0001, 0x00ee, 0x0005, 0x00e6, 0x2001, 0x002d, 0x2004, 0x9005,
+	0x0528, 0x2038, 0x2001, 0x0030, 0x2024, 0x2001, 0x0031, 0x201c,
+	0x080c, 0x49b8, 0x2940, 0xa813, 0x0019, 0xaf16, 0x2900, 0xa85a,
+	0x978a, 0x0007, 0x0220, 0x2138, 0x2009, 0x0007, 0x0010, 0x2708,
+	0x903e, 0x0096, 0xa858, 0x2048, 0xa85c, 0x9080, 0x0019, 0x009e,
+	0x080c, 0x40d3, 0x1d68, 0x2900, 0xa85a, 0x00d8, 0x080c, 0x49b8,
+	0x2940, 0xa013, 0x0019, 0xa017, 0x0001, 0x2800, 0xa05a, 0x2001,
+	0x0030, 0x2004, 0xa066, 0x2001, 0x0031, 0x2004, 0xa06a, 0x2001,
+	0x002a, 0x2004, 0x9084, 0xfff8, 0xa06e, 0x2001, 0x002b, 0x2004,
+	0xa072, 0x2001, 0x032a, 0x2003, 0x0004, 0x7884, 0xd0ac, 0x1180,
+	0x2001, 0x0101, 0x200c, 0x918d, 0x0200, 0x2102, 0xa017, 0x0000,
+	0x2001, 0x1a3f, 0x2003, 0x0003, 0x2001, 0x032a, 0x2003, 0x0009,
+	0x2001, 0x0300, 0x2003, 0x0000, 0x2001, 0x020d, 0x2003, 0x0000,
+	0x2001, 0x0004, 0x200c, 0x918d, 0x0002, 0x2102, 0x00ee, 0x0005,
+	0x0126, 0x2091, 0x8000, 0x20a9, 0x001b, 0x20a1, 0x1840, 0x20e9,
+	0x0001, 0x9006, 0x4004, 0x2009, 0x013c, 0x200a, 0x012e, 0x7880,
+	0x9086, 0x0052, 0x0108, 0x0005, 0x0804, 0x3408, 0x7d98, 0x7c9c,
+	0x0804, 0x350c, 0x080c, 0x717f, 0x190c, 0x5df5, 0x2069, 0x185b,
+	0x2d00, 0x2009, 0x0030, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x2039,
+	0x0001, 0x080c, 0x4a01, 0x701f, 0x41a6, 0x0005, 0x080c, 0x54eb,
+	0x1130, 0x3b00, 0x3a08, 0xc194, 0xc095, 0x20d8, 0x21d0, 0x2069,
+	0x185b, 0x6800, 0x9005, 0x0904, 0x343d, 0x6804, 0xd094, 0x00c6,
+	0x2061, 0x0100, 0x6104, 0x0138, 0x6200, 0x9292, 0x0005, 0x0218,
+	0x918c, 0xffdf, 0x0010, 0x918d, 0x0020, 0x6106, 0x00ce, 0xd08c,
+	0x00c6, 0x2061, 0x0100, 0x6104, 0x0118, 0x918d, 0x0010, 0x0010,
+	0x918c, 0xffef, 0x6106, 0x00ce, 0xd084, 0x0158, 0x6a28, 0x928a,
+	0x007f, 0x1a04, 0x343d, 0x9288, 0x3209, 0x210d, 0x918c, 0x00ff,
+	0x6162, 0xd0dc, 0x0130, 0x6828, 0x908a, 0x007f, 0x1a04, 0x343d,
+	0x605a, 0x6888, 0x9084, 0x0030, 0x8004, 0x8004, 0x8004, 0x8004,
+	0x0006, 0x2009, 0x198c, 0x9080, 0x27aa, 0x2005, 0x200a, 0x000e,
+	0x2009, 0x198d, 0x9080, 0x27ae, 0x2005, 0x200a, 0x6808, 0x908a,
+	0x0100, 0x0a04, 0x343d, 0x908a, 0x0841, 0x1a04, 0x343d, 0x9084,
+	0x0007, 0x1904, 0x343d, 0x680c, 0x9005, 0x0904, 0x343d, 0x6810,
+	0x9005, 0x0904, 0x343d, 0x6848, 0x6940, 0x910a, 0x1a04, 0x343d,
+	0x8001, 0x0904, 0x343d, 0x684c, 0x6944, 0x910a, 0x1a04, 0x343d,
+	0x8001, 0x0904, 0x343d, 0x2009, 0x195b, 0x200b, 0x0000, 0x2001,
+	0x187d, 0x2004, 0xd0c4, 0x0140, 0x7884, 0x200a, 0x2008, 0x080c,
+	0x0e87, 0x3b00, 0xc085, 0x20d8, 0x6814, 0x908c, 0x00ff, 0x614a,
+	0x8007, 0x9084, 0x00ff, 0x604e, 0x080c, 0x74ac, 0x080c, 0x6797,
+	0x080c, 0x67fa, 0x6808, 0x602a, 0x080c, 0x2176, 0x2009, 0x0170,
+	0x200b, 0x0080, 0xa001, 0xa001, 0x200b, 0x0000, 0x0036, 0x6b08,
+	0x080c, 0x2711, 0x003e, 0x6000, 0x9086, 0x0000, 0x1904, 0x4327,
+	0x6818, 0x691c, 0x6a20, 0x6b24, 0x8007, 0x810f, 0x8217, 0x831f,
+	0x6016, 0x611a, 0x621e, 0x6322, 0x6c04, 0xd4f4, 0x0148, 0x6830,
+	0x6934, 0x6a38, 0x6b3c, 0x8007, 0x810f, 0x8217, 0x831f, 0x0010,
+	0x9084, 0xf0ff, 0x6006, 0x610a, 0x620e, 0x6312, 0x8007, 0x810f,
+	0x8217, 0x831f, 0x20a9, 0x0004, 0x20a1, 0x198e, 0x20e9, 0x0001,
+	0x4001, 0x20a9, 0x0004, 0x20a1, 0x19a8, 0x20e9, 0x0001, 0x4001,
+	0x080c, 0x8363, 0x00c6, 0x900e, 0x20a9, 0x0001, 0x6b70, 0xd384,
+	0x01c8, 0x0020, 0x839d, 0x12b0, 0x3508, 0x8109, 0x080c, 0x7a78,
+	0x6878, 0x6016, 0x6874, 0x2008, 0x9084, 0xff00, 0x8007, 0x600a,
+	0x9184, 0x00ff, 0x6006, 0x8108, 0x1118, 0x6003, 0x0003, 0x0010,
+	0x6003, 0x0001, 0x1f04, 0x4292, 0x00ce, 0x00c6, 0x2061, 0x1976,
+	0x2063, 0x0001, 0x9006, 0x080c, 0x29b8, 0x9006, 0x080c, 0x299b,
+	0x0000, 0x00ce, 0x00e6, 0x2c70, 0x080c, 0x0ed8, 0x00ee, 0x6888,
+	0xd0ec, 0x0198, 0x2001, 0x0100, 0x2004, 0x9086, 0x000a, 0x0138,
+	0x2011, 0x0114, 0x2204, 0x9085, 0x0100, 0x2012, 0x0030, 0x2011,
+	0x0114, 0x2204, 0x9085, 0x0180, 0x2012, 0x6a80, 0x9284, 0x0030,
+	0x9086, 0x0030, 0x1128, 0x9294, 0xffcf, 0x9295, 0x0020, 0x6a82,
+	0x2001, 0x1956, 0x6a80, 0x9294, 0x0030, 0x928e, 0x0000, 0x0170,
+	0x928e, 0x0010, 0x0118, 0x928e, 0x0020, 0x0140, 0x2003, 0xaaaa,
+	0x080c, 0x2786, 0x2001, 0x1947, 0x2102, 0x0008, 0x2102, 0x00c6,
+	0x2061, 0x0100, 0x602f, 0x0040, 0x602f, 0x0000, 0x00ce, 0x080c,
+	0x717f, 0x0128, 0x080c, 0x4dd2, 0x0110, 0x080c, 0x26d7, 0x60d0,
+	0x9005, 0x01c0, 0x6003, 0x0001, 0x2009, 0x430f, 0x00d0, 0x080c,
+	0x717f, 0x1168, 0x2011, 0x6fee, 0x080c, 0x825a, 0x2011, 0x6fe1,
+	0x080c, 0x832e, 0x080c, 0x7480, 0x080c, 0x709f, 0x0040, 0x080c,
+	0x5cef, 0x0028, 0x6003, 0x0004, 0x2009, 0x4327, 0x0010, 0x0804,
+	0x3408, 0x2001, 0x0170, 0x2004, 0x9084, 0x00ff, 0x9086, 0x004c,
+	0x1118, 0x2091, 0x30bd, 0x0817, 0x2091, 0x303d, 0x0817, 0x6000,
+	0x9086, 0x0000, 0x0904, 0x343a, 0x2069, 0x185b, 0x7890, 0x6842,
+	0x7894, 0x6846, 0x2d00, 0x2009, 0x0030, 0x7a8c, 0x7b88, 0x7c9c,
+	0x7d98, 0x2039, 0x0001, 0x0804, 0x4a04, 0x9006, 0x080c, 0x26d7,
+	0x81ff, 0x1904, 0x343a, 0x080c, 0x717f, 0x11b0, 0x080c, 0x747b,
+	0x080c, 0x5e30, 0x080c, 0x3204, 0x0118, 0x6130, 0xc18d, 0x6132,
+	0x080c, 0xc444, 0x0130, 0x080c, 0x71a2, 0x1118, 0x080c, 0x7157,
+	0x0038, 0x080c, 0x709f, 0x0020, 0x080c, 0x5df5, 0x080c, 0x5cef,
+	0x0804, 0x3408, 0x81ff, 0x1904, 0x343a, 0x080c, 0x717f, 0x1110,
+	0x0804, 0x343a, 0x0126, 0x2091, 0x8000, 0x6190, 0x81ff, 0x0190,
+	0x704f, 0x0000, 0x2001, 0x1c80, 0x2009, 0x0040, 0x7a8c, 0x7b88,
+	0x7c9c, 0x7d98, 0x2039, 0x0001, 0x080c, 0x4a04, 0x701f, 0x3406,
+	0x012e, 0x0005, 0x704f, 0x0001, 0x00d6, 0x2069, 0x1c80, 0x20a9,
+	0x0040, 0x20e9, 0x0001, 0x20a1, 0x1c80, 0x2019, 0xffff, 0x4304,
+	0x6558, 0x9588, 0x3209, 0x210d, 0x918c, 0x00ff, 0x216a, 0x900e,
+	0x2011, 0x0002, 0x2100, 0x9506, 0x01a8, 0x080c, 0x63a4, 0x1190,
+	0xb814, 0x821c, 0x0238, 0x9398, 0x1c80, 0x9085, 0xff00, 0x8007,
+	0x201a, 0x0038, 0x9398, 0x1c80, 0x2324, 0x94a4, 0xff00, 0x9405,
+	0x201a, 0x8210, 0x8108, 0x9182, 0x0080, 0x1208, 0x0c18, 0x8201,
+	0x8007, 0x2d0c, 0x9105, 0x206a, 0x00de, 0x20a9, 0x0040, 0x20a1,
+	0x1c80, 0x2099, 0x1c80, 0x080c, 0x5d80, 0x0804, 0x4382, 0x080c,
+	0x49eb, 0x0904, 0x343d, 0x080c, 0x49b8, 0x1120, 0x2009, 0x0002,
+	0x0804, 0x343a, 0x080c, 0x54dc, 0xd0b4, 0x0558, 0x7884, 0x908e,
+	0x007e, 0x0538, 0x908e, 0x007f, 0x0520, 0x908e, 0x0080, 0x0508,
+	0x080c, 0x31ff, 0x1148, 0xb800, 0xd08c, 0x11d8, 0xb804, 0x9084,
+	0x00ff, 0x9086, 0x0006, 0x11a8, 0xa867, 0x0000, 0xa868, 0xc0fd,
+	0xa86a, 0x080c, 0xbf06, 0x1120, 0x2009, 0x0003, 0x0804, 0x343a,
+	0x7007, 0x0003, 0x701f, 0x440d, 0x0005, 0x080c, 0x49eb, 0x0904,
+	0x343d, 0x20a9, 0x002b, 0xb8b4, 0x20e0, 0xb8b8, 0x2098, 0xa860,
+	0x20e8, 0xa85c, 0x9080, 0x0002, 0x20a0, 0x4003, 0x20a9, 0x0008,
+	0x9080, 0x0006, 0x20a0, 0xb8b4, 0x20e0, 0xb8b8, 0x9080, 0x0006,
+	0x2098, 0x080c, 0x0fc0, 0x0070, 0x20a9, 0x0004, 0xa85c, 0x9080,
+	0x000a, 0x20a0, 0xb8b4, 0x20e0, 0xb8b8, 0x9080, 0x000a, 0x2098,
+	0x080c, 0x0fc0, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084,
+	0xffc0, 0x9080, 0x0002, 0x2009, 0x002b, 0x7a8c, 0x7b88, 0x7c9c,
+	0x7d98, 0x0804, 0x4a04, 0x81ff, 0x1904, 0x343a, 0x080c, 0x49cf,
+	0x0904, 0x343d, 0x080c, 0x6516, 0x0904, 0x343a, 0x0058, 0xa878,
+	0x9005, 0x0120, 0x2009, 0x0004, 0x0804, 0x343a, 0xa974, 0xaa94,
+	0x0804, 0x3408, 0x080c, 0x54e4, 0x0904, 0x3408, 0x701f, 0x4457,
+	0x7007, 0x0003, 0x0005, 0x81ff, 0x1904, 0x343a, 0x7888, 0x908a,
+	0x1000, 0x1a04, 0x343d, 0x080c, 0x49eb, 0x0904, 0x343d, 0x080c,
+	0x66ca, 0x0120, 0x080c, 0x66d2, 0x1904, 0x343d, 0x080c, 0x659b,
+	0x0904, 0x343a, 0x2019, 0x0004, 0x900e, 0x080c, 0x6528, 0x0904,
+	0x343a, 0x7984, 0x7a88, 0x04c9, 0x08a8, 0xa89c, 0x908a, 0x1000,
+	0x12f8, 0x080c, 0x49e9, 0x01e0, 0x080c, 0x66ca, 0x0118, 0x080c,
+	0x66d2, 0x11b0, 0x080c, 0x659b, 0x2009, 0x0002, 0x0168, 0x2009,
+	0x0002, 0x2019, 0x0004, 0x080c, 0x6528, 0x2009, 0x0003, 0x0120,
+	0xa998, 0xaa9c, 0x00d1, 0x0060, 0xa897, 0x4005, 0xa99a, 0x0010,
+	0xa897, 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x0005,
+	0xa897, 0x4000, 0x080c, 0x54e4, 0x0110, 0x9006, 0x0018, 0x900e,
+	0x9085, 0x0001, 0x2001, 0x0000, 0x0005, 0x9186, 0x00ff, 0x0110,
+	0x0071, 0x0060, 0x2029, 0x007e, 0x2061, 0x1800, 0x6458, 0x2400,
+	0x9506, 0x0110, 0x2508, 0x0019, 0x8529, 0x1ec8, 0x0005, 0x080c,
+	0x63a4, 0x1138, 0x2200, 0x8003, 0x800b, 0x810b, 0x9108, 0x080c,
+	0x8268, 0x0005, 0x81ff, 0x1904, 0x343a, 0x798c, 0x2001, 0x195a,
+	0x918c, 0x8000, 0x2102, 0x080c, 0x49cf, 0x0904, 0x343d, 0x080c,
+	0x66ca, 0x0120, 0x080c, 0x66d2, 0x1904, 0x343d, 0x080c, 0x646b,
+	0x0904, 0x343a, 0x080c, 0x651f, 0x0904, 0x343a, 0x2001, 0x195a,
+	0x2004, 0xd0fc, 0x1904, 0x3408, 0x0804, 0x4462, 0xa9a0, 0x2001,
+	0x195a, 0x918c, 0x8000, 0xc18d, 0x2102, 0x080c, 0x49dc, 0x01a0,
+	0x080c, 0x66ca, 0x0118, 0x080c, 0x66d2, 0x1170, 0x080c, 0x646b,
+	0x2009, 0x0002, 0x0128, 0x080c, 0x651f, 0x1170, 0x2009, 0x0003,
 	0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e, 0x9085,
-	0x0001, 0x2001, 0x0030, 0x0005, 0xa897, 0x4000, 0x900e, 0x9085,
-	0x0001, 0x2001, 0x0000, 0x0005, 0x2009, 0x000a, 0x0c48, 0x080c,
-	0x1031, 0x0198, 0x9006, 0xa802, 0x7014, 0x9005, 0x1120, 0x2900,
-	0x7016, 0x701a, 0x0040, 0x7018, 0xa802, 0x0086, 0x2040, 0x2900,
-	0xa006, 0x701a, 0x008e, 0x9085, 0x0001, 0x0005, 0x7984, 0x080c,
-	0x649f, 0x1130, 0x7e88, 0x9684, 0x3fff, 0x9082, 0x4000, 0x0208,
-	0x905e, 0x8bff, 0x0005, 0xa998, 0x080c, 0x649f, 0x1130, 0xae9c,
-	0x9684, 0x3fff, 0x9082, 0x4000, 0x0208, 0x905e, 0x8bff, 0x0005,
-	0xae98, 0x0008, 0x7e84, 0x2608, 0x080c, 0x649f, 0x1108, 0x0008,
-	0x905e, 0x8bff, 0x0005, 0x0016, 0x7114, 0x81ff, 0x0128, 0x2148,
-	0xa904, 0x080c, 0x1063, 0x0cc8, 0x7116, 0x711a, 0x001e, 0x0005,
-	0x2031, 0x0001, 0x0010, 0x2031, 0x0000, 0x2061, 0x18b6, 0x2c44,
-	0xa66a, 0xa17a, 0xa772, 0xa076, 0xa28e, 0xa392, 0xa496, 0xa59a,
-	0x080c, 0x112e, 0x7007, 0x0002, 0x701f, 0x34e8, 0x0005, 0x00f6,
-	0x0126, 0x2091, 0x8000, 0x2079, 0x0000, 0x2001, 0x18ae, 0x2004,
-	0x9005, 0x1190, 0x0e04, 0x4b3c, 0x7a36, 0x7833, 0x0012, 0x7a82,
-	0x7b86, 0x7c8a, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084,
-	0x190c, 0x11e0, 0x0804, 0x4ba2, 0x0016, 0x0086, 0x0096, 0x00c6,
-	0x00e6, 0x2071, 0x189c, 0x7044, 0x9005, 0x1540, 0x7148, 0x9182,
-	0x0010, 0x0288, 0x7038, 0x2060, 0x080c, 0x1031, 0x0904, 0x4b9a,
-	0xa84b, 0x0000, 0x2900, 0x7046, 0x2001, 0x0002, 0x9080, 0x1fc8,
-	0x2005, 0xa846, 0x0098, 0x7038, 0x90e0, 0x0004, 0x2001, 0x18b8,
-	0x9c82, 0x18f8, 0x0210, 0x2061, 0x18b8, 0x2c00, 0x703a, 0x7148,
-	0x81ff, 0x1108, 0x703e, 0x8108, 0x714a, 0x0460, 0x7148, 0x8108,
-	0x714a, 0x7044, 0x2040, 0xa144, 0x2105, 0x0016, 0x908a, 0x0036,
-	0x1a0c, 0x0dfa, 0x2060, 0x001e, 0x8108, 0x2105, 0x9005, 0xa146,
-	0x1520, 0x080c, 0x1031, 0x1130, 0x8109, 0xa946, 0x7148, 0x8109,
-	0x714a, 0x00d8, 0x9006, 0xa806, 0xa84a, 0xa046, 0x2800, 0xa802,
-	0x2900, 0xa006, 0x7046, 0x2001, 0x0002, 0x9080, 0x1fc8, 0x2005,
-	0xa846, 0x0058, 0x2262, 0x6306, 0x640a, 0x00ee, 0x00ce, 0x009e,
-	0x008e, 0x001e, 0x012e, 0x00fe, 0x0005, 0x2c00, 0x9082, 0x001b,
-	0x0002, 0x4bc4, 0x4bc4, 0x4bc6, 0x4bc4, 0x4bc4, 0x4bc4, 0x4bca,
-	0x4bc4, 0x4bc4, 0x4bc4, 0x4bce, 0x4bc4, 0x4bc4, 0x4bc4, 0x4bd2,
-	0x4bc4, 0x4bc4, 0x4bc4, 0x4bd6, 0x4bc4, 0x4bc4, 0x4bc4, 0x4bda,
-	0x4bc4, 0x4bc4, 0x4bc4, 0x4bdf, 0x080c, 0x0dfa, 0xa276, 0xa37a,
-	0xa47e, 0x0898, 0xa286, 0xa38a, 0xa48e, 0x0878, 0xa296, 0xa39a,
-	0xa49e, 0x0858, 0xa2a6, 0xa3aa, 0xa4ae, 0x0838, 0xa2b6, 0xa3ba,
-	0xa4be, 0x0818, 0xa2c6, 0xa3ca, 0xa4ce, 0x0804, 0x4b9d, 0xa2d6,
-	0xa3da, 0xa4de, 0x0804, 0x4b9d, 0x00e6, 0x2071, 0x189c, 0x7048,
-	0x9005, 0x0904, 0x4c76, 0x0126, 0x2091, 0x8000, 0x0e04, 0x4c75,
-	0x00f6, 0x2079, 0x0000, 0x00c6, 0x0096, 0x0086, 0x0076, 0x9006,
-	0x2038, 0x7040, 0x2048, 0x9005, 0x0500, 0xa948, 0x2105, 0x0016,
-	0x908a, 0x0036, 0x1a0c, 0x0dfa, 0x2060, 0x001e, 0x8108, 0x2105,
-	0x9005, 0xa94a, 0x1904, 0x4c78, 0xa804, 0x9005, 0x090c, 0x0dfa,
-	0x7042, 0x2938, 0x2040, 0xa003, 0x0000, 0x2001, 0x0002, 0x9080,
-	0x1fc8, 0x2005, 0xa04a, 0x0804, 0x4c78, 0x703c, 0x2060, 0x2c14,
-	0x6304, 0x6408, 0x650c, 0x2200, 0x7836, 0x7833, 0x0012, 0x7882,
-	0x2300, 0x7886, 0x2400, 0x788a, 0x2091, 0x4080, 0x2001, 0x0089,
-	0x2004, 0xd084, 0x190c, 0x11e0, 0x87ff, 0x0118, 0x2748, 0x080c,
-	0x1063, 0x7048, 0x8001, 0x704a, 0x9005, 0x1170, 0x7040, 0x2048,
-	0x9005, 0x0128, 0x080c, 0x1063, 0x9006, 0x7042, 0x7046, 0x703b,
-	0x18b8, 0x703f, 0x18b8, 0x0420, 0x7040, 0x9005, 0x1508, 0x7238,
-	0x2c00, 0x9206, 0x0148, 0x9c80, 0x0004, 0x90fa, 0x18f8, 0x0210,
-	0x2001, 0x18b8, 0x703e, 0x00a0, 0x9006, 0x703e, 0x703a, 0x7044,
-	0x9005, 0x090c, 0x0dfa, 0x2048, 0xa800, 0x9005, 0x1de0, 0x2900,
-	0x7042, 0x2001, 0x0002, 0x9080, 0x1fc8, 0x2005, 0xa84a, 0x0000,
-	0x007e, 0x008e, 0x009e, 0x00ce, 0x00fe, 0x012e, 0x00ee, 0x0005,
-	0x2c00, 0x9082, 0x001b, 0x0002, 0x4c97, 0x4c97, 0x4c99, 0x4c97,
-	0x4c97, 0x4c97, 0x4c9e, 0x4c97, 0x4c97, 0x4c97, 0x4ca3, 0x4c97,
-	0x4c97, 0x4c97, 0x4ca8, 0x4c97, 0x4c97, 0x4c97, 0x4cad, 0x4c97,
-	0x4c97, 0x4c97, 0x4cb2, 0x4c97, 0x4c97, 0x4c97, 0x4cb7, 0x080c,
-	0x0dfa, 0xaa74, 0xab78, 0xac7c, 0x0804, 0x4c23, 0xaa84, 0xab88,
-	0xac8c, 0x0804, 0x4c23, 0xaa94, 0xab98, 0xac9c, 0x0804, 0x4c23,
-	0xaaa4, 0xaba8, 0xacac, 0x0804, 0x4c23, 0xaab4, 0xabb8, 0xacbc,
-	0x0804, 0x4c23, 0xaac4, 0xabc8, 0xaccc, 0x0804, 0x4c23, 0xaad4,
-	0xabd8, 0xacdc, 0x0804, 0x4c23, 0x0026, 0x080c, 0x55db, 0xd0c4,
-	0x0120, 0x2011, 0x8014, 0x080c, 0x4b1f, 0x002e, 0x0005, 0x81ff,
-	0x1904, 0x351a, 0x0126, 0x2091, 0x8000, 0x6030, 0xc08d, 0xc085,
-	0xc0ac, 0x6032, 0x080c, 0x7207, 0x1158, 0x080c, 0x7504, 0x080c,
-	0x5f2b, 0x9085, 0x0001, 0x080c, 0x724e, 0x080c, 0x7127, 0x0010,
-	0x080c, 0x5dea, 0x012e, 0x0804, 0x34e8, 0x81ff, 0x0120, 0x2009,
-	0x0001, 0x0804, 0x351a, 0x080c, 0x55ef, 0x0120, 0x2009, 0x0007,
-	0x0804, 0x351a, 0x080c, 0x67bb, 0x0120, 0x2009, 0x0008, 0x0804,
-	0x351a, 0x0026, 0x2011, 0x0010, 0x080c, 0x67e7, 0x002e, 0x0140,
-	0x7984, 0x080c, 0x6831, 0x1120, 0x2009, 0x4009, 0x0804, 0x351a,
-	0x7984, 0x080c, 0x643f, 0x1904, 0x351d, 0x080c, 0x4af2, 0x0904,
-	0x351d, 0x2b00, 0x7026, 0x080c, 0x67c3, 0x7888, 0x1170, 0x9084,
-	0x0005, 0x1158, 0x900e, 0x080c, 0x66bf, 0x1108, 0xc185, 0xb800,
-	0xd0bc, 0x0108, 0xc18d, 0x0804, 0x34e8, 0x080c, 0x4abf, 0x0904,
-	0x351a, 0x9006, 0xa866, 0xa832, 0xa868, 0xc0fd, 0xa86a, 0x080c,
-	0xc061, 0x0904, 0x351a, 0x7888, 0xd094, 0x0118, 0xb8bc, 0xc08d,
-	0xb8be, 0x7007, 0x0003, 0x701f, 0x4d87, 0x0005, 0x2061, 0x1800,
-	0x080c, 0x55ef, 0x2009, 0x0007, 0x1560, 0x080c, 0x67bb, 0x0118,
-	0x2009, 0x0008, 0x0430, 0xa998, 0x080c, 0x643f, 0x1530, 0x080c,
-	0x4af0, 0x0518, 0x080c, 0x67c3, 0xa89c, 0x1168, 0x9084, 0x0005,
-	0x1150, 0x900e, 0x080c, 0x66bf, 0x1108, 0xc185, 0xb800, 0xd0bc,
-	0x0108, 0xc18d, 0x00d0, 0xa868, 0xc0fc, 0xa86a, 0x080c, 0xc061,
-	0x11e0, 0xa89c, 0xd094, 0x0118, 0xb8bc, 0xc08d, 0xb8be, 0x2009,
-	0x0003, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e,
-	0x9085, 0x0001, 0x2001, 0x0030, 0x0005, 0xa897, 0x4000, 0xa99a,
-	0x9006, 0x918d, 0x0001, 0x2008, 0x0005, 0x9006, 0x0005, 0xa830,
-	0x2008, 0x918e, 0xdead, 0x1120, 0x2021, 0x4009, 0x0804, 0x34ea,
-	0x9086, 0x0100, 0x7024, 0x2058, 0x1110, 0x0804, 0x552f, 0x900e,
-	0x080c, 0x66bf, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d,
-	0x0804, 0x34e8, 0x080c, 0x55ef, 0x0120, 0x2009, 0x0007, 0x0804,
-	0x351a, 0x7f84, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x080c, 0x4abf,
-	0x1120, 0x2009, 0x0002, 0x0804, 0x351a, 0x900e, 0x2130, 0x7126,
-	0x7132, 0xa860, 0x20e8, 0x7036, 0xa85c, 0x9080, 0x0005, 0x702a,
-	0x20a0, 0x080c, 0x649f, 0x1904, 0x4e25, 0x080c, 0x67c3, 0x0120,
-	0x080c, 0x67cb, 0x1904, 0x4e25, 0x080c, 0x67bb, 0x1130, 0x080c,
-	0x66bf, 0x1118, 0xd79c, 0x0904, 0x4e25, 0xd794, 0x1110, 0xd784,
-	0x01a8, 0xb8b4, 0x20e0, 0xb8b8, 0x9080, 0x0006, 0x2098, 0x3400,
-	0xd794, 0x0160, 0x20a9, 0x0008, 0x4003, 0x2098, 0x20a0, 0x3d00,
-	0x20e0, 0x20a9, 0x0002, 0x080c, 0x48ce, 0x0048, 0x20a9, 0x0004,
-	0x4003, 0x2098, 0x20a0, 0x3d00, 0x20e0, 0x080c, 0x48ce, 0x4104,
+	0x0001, 0x2001, 0x0030, 0x0005, 0xa897, 0x4000, 0x2001, 0x195a,
+	0x2004, 0xd0fc, 0x1128, 0x080c, 0x54e4, 0x0110, 0x9006, 0x0018,
+	0x900e, 0x9085, 0x0001, 0x2001, 0x0000, 0x0005, 0x81ff, 0x1904,
+	0x343a, 0x798c, 0x2001, 0x1959, 0x918c, 0x8000, 0x2102, 0x080c,
+	0x49cf, 0x0904, 0x343d, 0x080c, 0x66ca, 0x0120, 0x080c, 0x66d2,
+	0x1904, 0x343d, 0x080c, 0x646b, 0x0904, 0x343a, 0x080c, 0x650d,
+	0x0904, 0x343a, 0x2001, 0x1959, 0x2004, 0xd0fc, 0x1904, 0x3408,
+	0x0804, 0x4462, 0xa9a0, 0x2001, 0x1959, 0x918c, 0x8000, 0xc18d,
+	0x2102, 0x080c, 0x49dc, 0x01a0, 0x080c, 0x66ca, 0x0118, 0x080c,
+	0x66d2, 0x1170, 0x080c, 0x646b, 0x2009, 0x0002, 0x0128, 0x080c,
+	0x650d, 0x1170, 0x2009, 0x0003, 0xa897, 0x4005, 0xa99a, 0x0010,
+	0xa897, 0x4006, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x0005,
+	0xa897, 0x4000, 0x2001, 0x1959, 0x2004, 0xd0fc, 0x1128, 0x080c,
+	0x54e4, 0x0110, 0x9006, 0x0018, 0x900e, 0x9085, 0x0001, 0x2001,
+	0x0000, 0x0005, 0x6100, 0x0804, 0x3408, 0x080c, 0x49eb, 0x0904,
+	0x343d, 0x080c, 0x54f0, 0x1904, 0x343a, 0x79a8, 0xd184, 0x1158,
+	0xb834, 0x8007, 0x789e, 0xb830, 0x8007, 0x789a, 0xbb2c, 0x831f,
+	0xba28, 0x8217, 0x0050, 0xb824, 0x8007, 0x789e, 0xb820, 0x8007,
+	0x789a, 0xbb1c, 0x831f, 0xba18, 0x8217, 0xb900, 0x918c, 0x0202,
+	0x0804, 0x3408, 0x78a8, 0x909c, 0x0003, 0xd0ac, 0x1150, 0xd0b4,
+	0x1140, 0x939a, 0x0003, 0x1a04, 0x343a, 0x6258, 0x7884, 0x9206,
+	0x1560, 0x2031, 0x1848, 0x2009, 0x013c, 0x2136, 0x2001, 0x1840,
+	0x2009, 0x000c, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x2039, 0x0001,
+	0x0006, 0x78a8, 0x9084, 0x0080, 0x1118, 0x000e, 0x0804, 0x4a04,
+	0x000e, 0x2031, 0x0000, 0x2061, 0x18b6, 0x2c44, 0xa66a, 0xa17a,
+	0xa772, 0xa076, 0xa28e, 0xa392, 0xa496, 0xa59a, 0x080c, 0x1140,
+	0x7007, 0x0002, 0x701f, 0x461d, 0x0005, 0x81ff, 0x1904, 0x343a,
+	0x080c, 0x49eb, 0x0904, 0x343d, 0x080c, 0x66ca, 0x1904, 0x343a,
+	0x00c6, 0x080c, 0x49b8, 0x00ce, 0x0904, 0x343a, 0xa867, 0x0000,
+	0xa868, 0xc0fd, 0xa86a, 0x7ea8, 0x080c, 0xbeac, 0x0904, 0x343a,
+	0x7007, 0x0003, 0x701f, 0x4621, 0x0005, 0x080c, 0x4178, 0x0804,
+	0x3408, 0xa830, 0x9086, 0x0100, 0x0904, 0x343a, 0x8906, 0x8006,
+	0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x001b, 0x2009,
+	0x000c, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x0804, 0x4a04, 0x9006,
+	0x080c, 0x26d7, 0x78a8, 0x9084, 0x00ff, 0x9086, 0x00ff, 0x0118,
+	0x81ff, 0x1904, 0x343a, 0x080c, 0x717f, 0x0110, 0x080c, 0x5df5,
+	0x7888, 0x908a, 0x1000, 0x1a04, 0x343d, 0x7984, 0x9186, 0x00ff,
+	0x0138, 0x9182, 0x007f, 0x1a04, 0x343d, 0x2100, 0x080c, 0x26a1,
+	0x0026, 0x00c6, 0x0126, 0x2091, 0x8000, 0x2061, 0x19d5, 0x601b,
+	0x0000, 0x601f, 0x0000, 0x607b, 0x0000, 0x607f, 0x0000, 0x080c,
+	0x717f, 0x1158, 0x080c, 0x747b, 0x080c, 0x5e30, 0x9085, 0x0001,
+	0x080c, 0x71c3, 0x080c, 0x709f, 0x00d0, 0x080c, 0x9f5b, 0x2061,
+	0x0100, 0x2001, 0x1817, 0x2004, 0x9084, 0x00ff, 0x810f, 0x9105,
+	0x604a, 0x6043, 0x0090, 0x6043, 0x0010, 0x2009, 0x1973, 0x200b,
+	0x0000, 0x2009, 0x002d, 0x2011, 0x5d1b, 0x080c, 0x82ec, 0x7984,
+	0x080c, 0x717f, 0x1110, 0x2009, 0x00ff, 0x7a88, 0x080c, 0x44c5,
+	0x012e, 0x00ce, 0x002e, 0x0804, 0x3408, 0x7984, 0x080c, 0x6344,
+	0x2b08, 0x1904, 0x343d, 0x0804, 0x3408, 0x81ff, 0x0120, 0x2009,
+	0x0001, 0x0804, 0x343a, 0x60d8, 0xd0ac, 0x1130, 0xd09c, 0x1120,
+	0x2009, 0x0005, 0x0804, 0x343a, 0x080c, 0x49b8, 0x1120, 0x2009,
+	0x0002, 0x0804, 0x343a, 0x7984, 0x81ff, 0x0904, 0x343d, 0x9192,
+	0x0021, 0x1a04, 0x343d, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0xa85c,
+	0x9080, 0x0019, 0x702a, 0xaf60, 0x7736, 0x080c, 0x4a01, 0x701f,
+	0x46d8, 0x7880, 0x9086, 0x006e, 0x0110, 0x701f, 0x4f84, 0x0005,
+	0x2009, 0x0080, 0x080c, 0x63a4, 0x1118, 0x080c, 0x66ca, 0x0120,
+	0x2021, 0x400a, 0x0804, 0x340a, 0x00d6, 0x0096, 0xa964, 0xaa6c,
+	0xab70, 0xac74, 0xad78, 0xae7c, 0xa884, 0x90be, 0x0100, 0x0904,
+	0x4771, 0x90be, 0x0112, 0x0904, 0x4771, 0x90be, 0x0113, 0x0904,
+	0x4771, 0x90be, 0x0114, 0x0904, 0x4771, 0x90be, 0x0117, 0x0904,
+	0x4771, 0x90be, 0x011a, 0x0904, 0x4771, 0x90be, 0x011c, 0x0904,
+	0x4771, 0x90be, 0x0121, 0x0904, 0x4758, 0x90be, 0x0131, 0x0904,
+	0x4758, 0x90be, 0x0171, 0x0904, 0x4771, 0x90be, 0x0173, 0x0904,
+	0x4771, 0x90be, 0x01a1, 0x1128, 0xa894, 0x8007, 0xa896, 0x0804,
+	0x477c, 0x90be, 0x0212, 0x0904, 0x4765, 0x90be, 0x0213, 0x05e8,
+	0x90be, 0x0214, 0x0500, 0x90be, 0x0217, 0x0188, 0x90be, 0x021a,
+	0x1120, 0xa89c, 0x8007, 0xa89e, 0x04e0, 0x90be, 0x021f, 0x05c8,
+	0x90be, 0x0300, 0x05b0, 0x009e, 0x00de, 0x0804, 0x343d, 0x7028,
+	0x9080, 0x0010, 0x2098, 0x20a0, 0x7034, 0x20e0, 0x20e8, 0x20a9,
+	0x0007, 0x080c, 0x47ba, 0x7028, 0x9080, 0x000e, 0x2098, 0x20a0,
+	0x7034, 0x20e0, 0x20e8, 0x20a9, 0x0001, 0x080c, 0x47ba, 0x00c8,
+	0x7028, 0x9080, 0x000c, 0x2098, 0x20a0, 0x7034, 0x20e0, 0x20e8,
+	0x20a9, 0x0001, 0x080c, 0x47c7, 0x00b8, 0x7028, 0x9080, 0x000e,
+	0x2098, 0x20a0, 0x7034, 0x20e0, 0x20e8, 0x20a9, 0x0001, 0x080c,
+	0x47c7, 0x7028, 0x9080, 0x000c, 0x2098, 0x20a0, 0x7034, 0x20e0,
+	0x20e8, 0x20a9, 0x0001, 0x04f1, 0x00c6, 0x080c, 0x49b8, 0x0550,
+	0xa868, 0xc0fd, 0xa86a, 0xa867, 0x0119, 0x9006, 0xa882, 0xa87f,
+	0x0020, 0xa88b, 0x0001, 0x810b, 0xa9ae, 0xa8b2, 0xaab6, 0xabba,
+	0xacbe, 0xadc2, 0xa9c6, 0xa8ca, 0x00ce, 0x009e, 0x00de, 0xa866,
+	0xa822, 0xa868, 0xc0fd, 0xa86a, 0xa804, 0x2048, 0x080c, 0xbec7,
+	0x1120, 0x2009, 0x0003, 0x0804, 0x343a, 0x7007, 0x0003, 0x701f,
+	0x47b1, 0x0005, 0x00ce, 0x009e, 0x00de, 0x2009, 0x0002, 0x0804,
+	0x343a, 0xa820, 0x9086, 0x8001, 0x1904, 0x3408, 0x2009, 0x0004,
+	0x0804, 0x343a, 0x0016, 0x0026, 0x3510, 0x20a9, 0x0002, 0x4002,
+	0x4104, 0x4004, 0x8211, 0x1dc8, 0x002e, 0x001e, 0x0005, 0x0016,
+	0x0026, 0x0036, 0x0046, 0x3520, 0x20a9, 0x0004, 0x4002, 0x4304,
+	0x4204, 0x4104, 0x4004, 0x8421, 0x1db8, 0x004e, 0x003e, 0x002e,
+	0x001e, 0x0005, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x343a,
+	0x60d8, 0xd0ac, 0x1160, 0xd09c, 0x0120, 0x2009, 0x0016, 0x0804,
+	0x343a, 0xd09c, 0x1120, 0x2009, 0x0005, 0x0804, 0x343a, 0x7984,
+	0x78a8, 0x2040, 0x080c, 0x9f54, 0x1120, 0x9182, 0x007f, 0x0a04,
+	0x343d, 0x9186, 0x00ff, 0x0904, 0x343d, 0x9182, 0x0800, 0x1a04,
+	0x343d, 0x7a8c, 0x7b88, 0x6078, 0x9306, 0x1158, 0x607c, 0x924e,
+	0x0904, 0x343d, 0x080c, 0x9f54, 0x1120, 0x99cc, 0xff00, 0x0904,
+	0x343d, 0x0126, 0x2091, 0x8000, 0x9386, 0x00ff, 0x0178, 0x0026,
+	0x2011, 0x8008, 0x080c, 0x66ee, 0x002e, 0x0140, 0x918d, 0x8000,
+	0x080c, 0x6738, 0x1118, 0x2001, 0x4009, 0x0458, 0x080c, 0x48d2,
+	0x0560, 0x90c6, 0x4000, 0x1170, 0x00c6, 0x0006, 0x900e, 0x080c,
+	0x65c4, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0x000e,
+	0x00ce, 0x00b8, 0x90c6, 0x4007, 0x1110, 0x2408, 0x0090, 0x90c6,
+	0x4008, 0x1118, 0x2708, 0x2610, 0x0060, 0x90c6, 0x4009, 0x1108,
+	0x0040, 0x90c6, 0x4006, 0x1108, 0x0020, 0x2001, 0x4005, 0x2009,
+	0x000a, 0x2020, 0x012e, 0x0804, 0x340a, 0x2b00, 0x7026, 0x0016,
+	0x00b6, 0x00c6, 0x00e6, 0x2c70, 0x080c, 0xa026, 0x0904, 0x489f,
+	0x2b00, 0x6012, 0x080c, 0xc1b7, 0x2e58, 0x00ee, 0x00e6, 0x00c6,
+	0x080c, 0x49b8, 0x00ce, 0x2b70, 0x1158, 0x080c, 0x9fd5, 0x00ee,
+	0x00ce, 0x00be, 0x001e, 0x012e, 0x2009, 0x0002, 0x0804, 0x343a,
+	0x900e, 0xa966, 0xa96a, 0x2900, 0x6016, 0xa932, 0xa868, 0xc0fd,
+	0xd88c, 0x0108, 0xc0f5, 0xa86a, 0x080c, 0x30ab, 0x6023, 0x0001,
+	0x9006, 0x080c, 0x62e1, 0x2001, 0x0002, 0x080c, 0x62f5, 0x2009,
+	0x0002, 0x080c, 0xa053, 0x78a8, 0xd094, 0x0138, 0x00ee, 0x7024,
+	0x00e6, 0x2058, 0xb8bc, 0xc08d, 0xb8be, 0x9085, 0x0001, 0x00ee,
+	0x00ce, 0x00be, 0x001e, 0x012e, 0x1120, 0x2009, 0x0003, 0x0804,
+	0x343a, 0x7007, 0x0003, 0x701f, 0x48ae, 0x0005, 0xa830, 0x2008,
+	0x918e, 0xdead, 0x1120, 0x2021, 0x4009, 0x0804, 0x340a, 0x9086,
+	0x0100, 0x7024, 0x2058, 0x1138, 0x2009, 0x0004, 0xba04, 0x9294,
+	0x00ff, 0x0804, 0x5430, 0x900e, 0xa868, 0xd0f4, 0x1904, 0x3408,
+	0x080c, 0x65c4, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d,
+	0x0804, 0x3408, 0x00e6, 0x00d6, 0x0096, 0x83ff, 0x0904, 0x491a,
+	0x902e, 0x080c, 0x9f54, 0x0130, 0x9026, 0x20a9, 0x0800, 0x2071,
+	0x1000, 0x0030, 0x2021, 0x007f, 0x20a9, 0x0781, 0x2071, 0x107f,
+	0x2e04, 0x9005, 0x11b0, 0x2100, 0x9406, 0x15e8, 0x2428, 0x94ce,
+	0x007f, 0x1120, 0x92ce, 0xfffd, 0x1528, 0x0030, 0x94ce, 0x0080,
+	0x1130, 0x92ce, 0xfffc, 0x11f0, 0x93ce, 0x00ff, 0x11d8, 0xc5fd,
+	0x0450, 0x2058, 0xbf10, 0x2700, 0x9306, 0x11b8, 0xbe14, 0x2600,
+	0x9206, 0x1198, 0x2400, 0x9106, 0x1150, 0xd884, 0x0568, 0xd894,
+	0x1558, 0x080c, 0x66ca, 0x1540, 0x2001, 0x4000, 0x0430, 0x2001,
+	0x4007, 0x0418, 0x2001, 0x4006, 0x0400, 0x2400, 0x9106, 0x1158,
+	0xbe14, 0x87ff, 0x1128, 0x86ff, 0x0948, 0x080c, 0x9f54, 0x1930,
+	0x2001, 0x4008, 0x0090, 0x8420, 0x8e70, 0x1f04, 0x48e8, 0x85ff,
+	0x1130, 0x2001, 0x4009, 0x0048, 0x2001, 0x0001, 0x0030, 0x080c,
+	0x6344, 0x1dd0, 0xbb12, 0xba16, 0x9006, 0x9005, 0x009e, 0x00de,
+	0x00ee, 0x0005, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x343a,
+	0x080c, 0x49b8, 0x1120, 0x2009, 0x0002, 0x0804, 0x343a, 0xa867,
+	0x0000, 0xa868, 0xc0fd, 0xa86a, 0x7884, 0x9005, 0x0904, 0x343d,
+	0x9096, 0x00ff, 0x0120, 0x9092, 0x0004, 0x1a04, 0x343d, 0x2010,
+	0x2918, 0x080c, 0x3051, 0x1120, 0x2009, 0x0003, 0x0804, 0x343a,
+	0x7007, 0x0003, 0x701f, 0x496d, 0x0005, 0xa830, 0x9086, 0x0100,
+	0x1904, 0x3408, 0x2009, 0x0004, 0x0804, 0x343a, 0x7984, 0x080c,
+	0x9f54, 0x1120, 0x9182, 0x007f, 0x0a04, 0x343d, 0x9186, 0x00ff,
+	0x0904, 0x343d, 0x9182, 0x0800, 0x1a04, 0x343d, 0x2001, 0x9400,
+	0x080c, 0x548b, 0x1904, 0x343a, 0x0804, 0x3408, 0xa998, 0x080c,
+	0x9f54, 0x1118, 0x9182, 0x007f, 0x0280, 0x9186, 0x00ff, 0x0168,
+	0x9182, 0x0800, 0x1250, 0x2001, 0x9400, 0x080c, 0x548b, 0x11a8,
+	0x0060, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e,
+	0x9085, 0x0001, 0x2001, 0x0030, 0x0005, 0xa897, 0x4000, 0x900e,
+	0x9085, 0x0001, 0x2001, 0x0000, 0x0005, 0x2009, 0x000a, 0x0c48,
+	0x080c, 0x1043, 0x0198, 0x9006, 0xa802, 0x7014, 0x9005, 0x1120,
+	0x2900, 0x7016, 0x701a, 0x0040, 0x7018, 0xa802, 0x0086, 0x2040,
+	0x2900, 0xa006, 0x701a, 0x008e, 0x9085, 0x0001, 0x0005, 0x7984,
+	0x080c, 0x63a4, 0x1130, 0x7e88, 0x9684, 0x3fff, 0x9082, 0x4000,
+	0x0208, 0x905e, 0x8bff, 0x0005, 0xa998, 0x080c, 0x63a4, 0x1130,
+	0xae9c, 0x9684, 0x3fff, 0x9082, 0x4000, 0x0208, 0x905e, 0x8bff,
+	0x0005, 0xae98, 0x0008, 0x7e84, 0x2608, 0x080c, 0x63a4, 0x1108,
+	0x0008, 0x905e, 0x8bff, 0x0005, 0x0016, 0x7114, 0x81ff, 0x0128,
+	0x2148, 0xa904, 0x080c, 0x1075, 0x0cc8, 0x7116, 0x711a, 0x001e,
+	0x0005, 0x2031, 0x0001, 0x0010, 0x2031, 0x0000, 0x2061, 0x18b6,
+	0x2c44, 0xa66a, 0xa17a, 0xa772, 0xa076, 0xa28e, 0xa392, 0xa496,
+	0xa59a, 0x080c, 0x1140, 0x7007, 0x0002, 0x701f, 0x3408, 0x0005,
+	0x00f6, 0x0126, 0x2091, 0x8000, 0x2079, 0x0000, 0x2001, 0x18ae,
+	0x2004, 0x9005, 0x1190, 0x0e04, 0x4a35, 0x7a36, 0x7833, 0x0012,
+	0x7a82, 0x7b86, 0x7c8a, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004,
+	0xd084, 0x190c, 0x11f2, 0x0804, 0x4a9b, 0x0016, 0x0086, 0x0096,
+	0x00c6, 0x00e6, 0x2071, 0x189c, 0x7044, 0x9005, 0x1540, 0x7148,
+	0x9182, 0x0010, 0x0288, 0x7038, 0x2060, 0x080c, 0x1043, 0x0904,
+	0x4a93, 0xa84b, 0x0000, 0x2900, 0x7046, 0x2001, 0x0002, 0x9080,
+	0x1ec2, 0x2005, 0xa846, 0x0098, 0x7038, 0x90e0, 0x0004, 0x2001,
+	0x18b8, 0x9c82, 0x18f8, 0x0210, 0x2061, 0x18b8, 0x2c00, 0x703a,
+	0x7148, 0x81ff, 0x1108, 0x703e, 0x8108, 0x714a, 0x0460, 0x7148,
+	0x8108, 0x714a, 0x7044, 0x2040, 0xa144, 0x2105, 0x0016, 0x908a,
+	0x0036, 0x1a0c, 0x0e02, 0x2060, 0x001e, 0x8108, 0x2105, 0x9005,
+	0xa146, 0x1520, 0x080c, 0x1043, 0x1130, 0x8109, 0xa946, 0x7148,
+	0x8109, 0x714a, 0x00d8, 0x9006, 0xa806, 0xa84a, 0xa046, 0x2800,
+	0xa802, 0x2900, 0xa006, 0x7046, 0x2001, 0x0002, 0x9080, 0x1ec2,
+	0x2005, 0xa846, 0x0058, 0x2262, 0x6306, 0x640a, 0x00ee, 0x00ce,
+	0x009e, 0x008e, 0x001e, 0x012e, 0x00fe, 0x0005, 0x2c00, 0x9082,
+	0x001b, 0x0002, 0x4abd, 0x4abd, 0x4abf, 0x4abd, 0x4abd, 0x4abd,
+	0x4ac3, 0x4abd, 0x4abd, 0x4abd, 0x4ac7, 0x4abd, 0x4abd, 0x4abd,
+	0x4acb, 0x4abd, 0x4abd, 0x4abd, 0x4acf, 0x4abd, 0x4abd, 0x4abd,
+	0x4ad3, 0x4abd, 0x4abd, 0x4abd, 0x4ad8, 0x080c, 0x0e02, 0xa276,
+	0xa37a, 0xa47e, 0x0898, 0xa286, 0xa38a, 0xa48e, 0x0878, 0xa296,
+	0xa39a, 0xa49e, 0x0858, 0xa2a6, 0xa3aa, 0xa4ae, 0x0838, 0xa2b6,
+	0xa3ba, 0xa4be, 0x0818, 0xa2c6, 0xa3ca, 0xa4ce, 0x0804, 0x4a96,
+	0xa2d6, 0xa3da, 0xa4de, 0x0804, 0x4a96, 0x00e6, 0x2071, 0x189c,
+	0x7048, 0x9005, 0x0904, 0x4b6f, 0x0126, 0x2091, 0x8000, 0x0e04,
+	0x4b6e, 0x00f6, 0x2079, 0x0000, 0x00c6, 0x0096, 0x0086, 0x0076,
+	0x9006, 0x2038, 0x7040, 0x2048, 0x9005, 0x0500, 0xa948, 0x2105,
+	0x0016, 0x908a, 0x0036, 0x1a0c, 0x0e02, 0x2060, 0x001e, 0x8108,
+	0x2105, 0x9005, 0xa94a, 0x1904, 0x4b71, 0xa804, 0x9005, 0x090c,
+	0x0e02, 0x7042, 0x2938, 0x2040, 0xa003, 0x0000, 0x2001, 0x0002,
+	0x9080, 0x1ec2, 0x2005, 0xa04a, 0x0804, 0x4b71, 0x703c, 0x2060,
+	0x2c14, 0x6304, 0x6408, 0x650c, 0x2200, 0x7836, 0x7833, 0x0012,
+	0x7882, 0x2300, 0x7886, 0x2400, 0x788a, 0x2091, 0x4080, 0x2001,
+	0x0089, 0x2004, 0xd084, 0x190c, 0x11f2, 0x87ff, 0x0118, 0x2748,
+	0x080c, 0x1075, 0x7048, 0x8001, 0x704a, 0x9005, 0x1170, 0x7040,
+	0x2048, 0x9005, 0x0128, 0x080c, 0x1075, 0x9006, 0x7042, 0x7046,
+	0x703b, 0x18b8, 0x703f, 0x18b8, 0x0420, 0x7040, 0x9005, 0x1508,
+	0x7238, 0x2c00, 0x9206, 0x0148, 0x9c80, 0x0004, 0x90fa, 0x18f8,
+	0x0210, 0x2001, 0x18b8, 0x703e, 0x00a0, 0x9006, 0x703e, 0x703a,
+	0x7044, 0x9005, 0x090c, 0x0e02, 0x2048, 0xa800, 0x9005, 0x1de0,
+	0x2900, 0x7042, 0x2001, 0x0002, 0x9080, 0x1ec2, 0x2005, 0xa84a,
+	0x0000, 0x007e, 0x008e, 0x009e, 0x00ce, 0x00fe, 0x012e, 0x00ee,
+	0x0005, 0x2c00, 0x9082, 0x001b, 0x0002, 0x4b90, 0x4b90, 0x4b92,
+	0x4b90, 0x4b90, 0x4b90, 0x4b97, 0x4b90, 0x4b90, 0x4b90, 0x4b9c,
+	0x4b90, 0x4b90, 0x4b90, 0x4ba1, 0x4b90, 0x4b90, 0x4b90, 0x4ba6,
+	0x4b90, 0x4b90, 0x4b90, 0x4bab, 0x4b90, 0x4b90, 0x4b90, 0x4bb0,
+	0x080c, 0x0e02, 0xaa74, 0xab78, 0xac7c, 0x0804, 0x4b1c, 0xaa84,
+	0xab88, 0xac8c, 0x0804, 0x4b1c, 0xaa94, 0xab98, 0xac9c, 0x0804,
+	0x4b1c, 0xaaa4, 0xaba8, 0xacac, 0x0804, 0x4b1c, 0xaab4, 0xabb8,
+	0xacbc, 0x0804, 0x4b1c, 0xaac4, 0xabc8, 0xaccc, 0x0804, 0x4b1c,
+	0xaad4, 0xabd8, 0xacdc, 0x0804, 0x4b1c, 0x0026, 0x080c, 0x54dc,
+	0xd0c4, 0x0120, 0x2011, 0x8014, 0x080c, 0x4a18, 0x002e, 0x0005,
+	0x81ff, 0x1904, 0x343a, 0x0126, 0x2091, 0x8000, 0x6030, 0xc08d,
+	0xc085, 0xc0ac, 0x6032, 0x080c, 0x717f, 0x1158, 0x080c, 0x747b,
+	0x080c, 0x5e30, 0x9085, 0x0001, 0x080c, 0x71c3, 0x080c, 0x709f,
+	0x0010, 0x080c, 0x5cef, 0x012e, 0x0804, 0x3408, 0x81ff, 0x0120,
+	0x2009, 0x0001, 0x0804, 0x343a, 0x080c, 0x54f0, 0x0120, 0x2009,
+	0x0007, 0x0804, 0x343a, 0x080c, 0x66c2, 0x0120, 0x2009, 0x0008,
+	0x0804, 0x343a, 0x0026, 0x2011, 0x0010, 0x080c, 0x66ee, 0x002e,
+	0x0140, 0x7984, 0x080c, 0x6738, 0x1120, 0x2009, 0x4009, 0x0804,
+	0x343a, 0x7984, 0x080c, 0x6344, 0x1904, 0x343d, 0x080c, 0x49eb,
+	0x0904, 0x343d, 0x2b00, 0x7026, 0x080c, 0x66ca, 0x7888, 0x1170,
+	0x9084, 0x0005, 0x1158, 0x900e, 0x080c, 0x65c4, 0x1108, 0xc185,
+	0xb800, 0xd0bc, 0x0108, 0xc18d, 0x0804, 0x3408, 0x080c, 0x49b8,
+	0x0904, 0x343a, 0x9006, 0xa866, 0xa832, 0xa868, 0xc0fd, 0xa86a,
+	0x080c, 0xbf65, 0x0904, 0x343a, 0x7888, 0xd094, 0x0118, 0xb8bc,
+	0xc08d, 0xb8be, 0x7007, 0x0003, 0x701f, 0x4c80, 0x0005, 0x2061,
+	0x1800, 0x080c, 0x54f0, 0x2009, 0x0007, 0x1560, 0x080c, 0x66c2,
+	0x0118, 0x2009, 0x0008, 0x0430, 0xa998, 0x080c, 0x6344, 0x1530,
+	0x080c, 0x49e9, 0x0518, 0x080c, 0x66ca, 0xa89c, 0x1168, 0x9084,
+	0x0005, 0x1150, 0x900e, 0x080c, 0x65c4, 0x1108, 0xc185, 0xb800,
+	0xd0bc, 0x0108, 0xc18d, 0x00d0, 0xa868, 0xc0fc, 0xa86a, 0x080c,
+	0xbf65, 0x11e0, 0xa89c, 0xd094, 0x0118, 0xb8bc, 0xc08d, 0xb8be,
+	0x2009, 0x0003, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006,
+	0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x0005, 0xa897, 0x4000,
+	0xa99a, 0x9006, 0x918d, 0x0001, 0x2008, 0x0005, 0x9006, 0x0005,
+	0xa830, 0x2008, 0x918e, 0xdead, 0x1120, 0x2021, 0x4009, 0x0804,
+	0x340a, 0x9086, 0x0100, 0x7024, 0x2058, 0x1110, 0x0804, 0x5430,
+	0x900e, 0x080c, 0x65c4, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108,
+	0xc18d, 0x0804, 0x3408, 0x080c, 0x54f0, 0x0120, 0x2009, 0x0007,
+	0x0804, 0x343a, 0x7f84, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x080c,
+	0x49b8, 0x1120, 0x2009, 0x0002, 0x0804, 0x343a, 0x900e, 0x2130,
+	0x7126, 0x7132, 0xa860, 0x20e8, 0x7036, 0xa85c, 0x9080, 0x0005,
+	0x702a, 0x20a0, 0x080c, 0x63a4, 0x1904, 0x4d25, 0x080c, 0x66ca,
+	0x0120, 0x080c, 0x66d2, 0x1904, 0x4d25, 0x080c, 0x66c2, 0x1130,
+	0x080c, 0x65c4, 0x1118, 0xd79c, 0x0904, 0x4d25, 0xd794, 0x1110,
+	0xd784, 0x01a8, 0xb8b4, 0x20e0, 0xb8b8, 0x9080, 0x0006, 0x2098,
+	0x3400, 0xd794, 0x0198, 0x20a9, 0x0008, 0x4003, 0x2098, 0x20a0,
+	0x3d00, 0x20e0, 0x20a9, 0x0002, 0x080c, 0x47c7, 0x0080, 0xb8b4,
+	0x20e0, 0xb8b8, 0x9080, 0x000a, 0x2098, 0x3400, 0x20a9, 0x0004,
+	0x4003, 0x2098, 0x20a0, 0x3d00, 0x20e0, 0x080c, 0x47c7, 0x4104,
 	0xd794, 0x0528, 0xb8b4, 0x20e0, 0xb8b8, 0x2060, 0x9c80, 0x0000,
 	0x2098, 0x20a9, 0x0002, 0x4003, 0x9c80, 0x0003, 0x2098, 0x20a9,
 	0x0001, 0x4005, 0x9c80, 0x0004, 0x2098, 0x3400, 0x20a9, 0x0002,
-	0x4003, 0x2098, 0x20a0, 0x3d00, 0x20e0, 0x080c, 0x48c1, 0x9c80,
+	0x4003, 0x2098, 0x20a0, 0x3d00, 0x20e0, 0x080c, 0x47ba, 0x9c80,
 	0x0026, 0x2098, 0xb8b4, 0x20e0, 0x20a9, 0x0002, 0x4003, 0xd794,
-	0x0110, 0x96b0, 0x000b, 0x96b0, 0x0005, 0x8108, 0x080c, 0xa062,
+	0x0110, 0x96b0, 0x000b, 0x96b0, 0x0005, 0x8108, 0x080c, 0x9f54,
 	0x0118, 0x9186, 0x0800, 0x0040, 0xd78c, 0x0120, 0x9186, 0x0800,
 	0x0170, 0x0018, 0x9186, 0x007e, 0x0150, 0xd794, 0x0118, 0x9686,
-	0x0020, 0x0010, 0x9686, 0x0028, 0x0150, 0x0804, 0x4dc1, 0x86ff,
-	0x1120, 0x7124, 0x810b, 0x0804, 0x34e8, 0x7033, 0x0001, 0x7122,
+	0x0020, 0x0010, 0x9686, 0x0028, 0x0150, 0x0804, 0x4cba, 0x86ff,
+	0x1120, 0x7124, 0x810b, 0x0804, 0x3408, 0x7033, 0x0001, 0x7122,
 	0x7024, 0x9600, 0x7026, 0x772e, 0x2061, 0x18b6, 0x2c44, 0xa06b,
 	0x0000, 0xa67a, 0x7034, 0xa072, 0x7028, 0xa076, 0xa28e, 0xa392,
-	0xa496, 0xa59a, 0x080c, 0x112e, 0x7007, 0x0002, 0x701f, 0x4e61,
+	0xa496, 0xa59a, 0x080c, 0x1140, 0x7007, 0x0002, 0x701f, 0x4d61,
 	0x0005, 0x7030, 0x9005, 0x1180, 0x7120, 0x7028, 0x20a0, 0x772c,
 	0x9036, 0x7034, 0x20e8, 0x2061, 0x18b6, 0x2c44, 0xa28c, 0xa390,
-	0xa494, 0xa598, 0x0804, 0x4dc1, 0x7124, 0x810b, 0x0804, 0x34e8,
+	0xa494, 0xa598, 0x0804, 0x4cba, 0x7124, 0x810b, 0x0804, 0x3408,
 	0x2029, 0x007e, 0x7984, 0x7a88, 0x7b8c, 0x7c98, 0x9184, 0xff00,
-	0x8007, 0x90e2, 0x0020, 0x0a04, 0x351d, 0x9502, 0x0a04, 0x351d,
-	0x9184, 0x00ff, 0x90e2, 0x0020, 0x0a04, 0x351d, 0x9502, 0x0a04,
-	0x351d, 0x9284, 0xff00, 0x8007, 0x90e2, 0x0020, 0x0a04, 0x351d,
-	0x9502, 0x0a04, 0x351d, 0x9284, 0x00ff, 0x90e2, 0x0020, 0x0a04,
-	0x351d, 0x9502, 0x0a04, 0x351d, 0x9384, 0xff00, 0x8007, 0x90e2,
-	0x0020, 0x0a04, 0x351d, 0x9502, 0x0a04, 0x351d, 0x9384, 0x00ff,
-	0x90e2, 0x0020, 0x0a04, 0x351d, 0x9502, 0x0a04, 0x351d, 0x9484,
-	0xff00, 0x8007, 0x90e2, 0x0020, 0x0a04, 0x351d, 0x9502, 0x0a04,
-	0x351d, 0x9484, 0x00ff, 0x90e2, 0x0020, 0x0a04, 0x351d, 0x9502,
-	0x0a04, 0x351d, 0x2061, 0x1961, 0x6102, 0x6206, 0x630a, 0x640e,
-	0x0804, 0x34e8, 0x0006, 0x080c, 0x55db, 0xd0cc, 0x000e, 0x0005,
-	0x0006, 0x080c, 0x55df, 0xd0bc, 0x000e, 0x0005, 0x6170, 0x7a84,
-	0x6300, 0x82ff, 0x1118, 0x7986, 0x0804, 0x34e8, 0x83ff, 0x1904,
-	0x351d, 0x2001, 0xfff0, 0x9200, 0x1a04, 0x351d, 0x2019, 0xffff,
-	0x6074, 0x9302, 0x9200, 0x0a04, 0x351d, 0x7986, 0x6272, 0x0804,
-	0x34e8, 0x080c, 0x55ef, 0x1904, 0x351a, 0x7c88, 0x7d84, 0x7e98,
-	0x7f8c, 0x080c, 0x4abf, 0x0904, 0x351a, 0x900e, 0x901e, 0x7326,
+	0x8007, 0x90e2, 0x0020, 0x0a04, 0x343d, 0x9502, 0x0a04, 0x343d,
+	0x9184, 0x00ff, 0x90e2, 0x0020, 0x0a04, 0x343d, 0x9502, 0x0a04,
+	0x343d, 0x9284, 0xff00, 0x8007, 0x90e2, 0x0020, 0x0a04, 0x343d,
+	0x9502, 0x0a04, 0x343d, 0x9284, 0x00ff, 0x90e2, 0x0020, 0x0a04,
+	0x343d, 0x9502, 0x0a04, 0x343d, 0x9384, 0xff00, 0x8007, 0x90e2,
+	0x0020, 0x0a04, 0x343d, 0x9502, 0x0a04, 0x343d, 0x9384, 0x00ff,
+	0x90e2, 0x0020, 0x0a04, 0x343d, 0x9502, 0x0a04, 0x343d, 0x9484,
+	0xff00, 0x8007, 0x90e2, 0x0020, 0x0a04, 0x343d, 0x9502, 0x0a04,
+	0x343d, 0x9484, 0x00ff, 0x90e2, 0x0020, 0x0a04, 0x343d, 0x9502,
+	0x0a04, 0x343d, 0x2061, 0x1963, 0x6102, 0x6206, 0x630a, 0x640e,
+	0x0804, 0x3408, 0x0006, 0x080c, 0x54dc, 0xd0cc, 0x000e, 0x0005,
+	0x0006, 0x080c, 0x54e0, 0xd0bc, 0x000e, 0x0005, 0x6170, 0x7a84,
+	0x6300, 0x82ff, 0x1118, 0x7986, 0x0804, 0x3408, 0x83ff, 0x1904,
+	0x343d, 0x2001, 0xfff0, 0x9200, 0x1a04, 0x343d, 0x2019, 0xffff,
+	0x6074, 0x9302, 0x9200, 0x0a04, 0x343d, 0x7986, 0x6272, 0x0804,
+	0x3408, 0x080c, 0x54f0, 0x1904, 0x343a, 0x7c88, 0x7d84, 0x7e98,
+	0x7f8c, 0x080c, 0x49b8, 0x0904, 0x343a, 0x900e, 0x901e, 0x7326,
 	0x7332, 0xa860, 0x20e8, 0x7036, 0xa85c, 0x9080, 0x0003, 0x702a,
-	0x20a0, 0x91d8, 0x1000, 0x2b5c, 0x8bff, 0x0178, 0x080c, 0x67c3,
-	0x0118, 0x080c, 0x67cb, 0x1148, 0x20a9, 0x0001, 0xb814, 0x4004,
+	0x20a0, 0x91d8, 0x1000, 0x2b5c, 0x8bff, 0x0178, 0x080c, 0x66ca,
+	0x0118, 0x080c, 0x66d2, 0x1148, 0x20a9, 0x0001, 0xb814, 0x4004,
 	0xb810, 0x4004, 0x4104, 0x9398, 0x0003, 0x8108, 0x9182, 0x0800,
 	0x0120, 0x9386, 0x003c, 0x0170, 0x0c20, 0x83ff, 0x1148, 0x7224,
-	0x900e, 0x2001, 0x0003, 0x080c, 0x84ff, 0x2208, 0x0804, 0x34e8,
+	0x900e, 0x2001, 0x0003, 0x080c, 0x847f, 0x2208, 0x0804, 0x3408,
 	0x7033, 0x0001, 0x7122, 0x7024, 0x9300, 0x7026, 0x2061, 0x18b6,
 	0x2c44, 0xa06b, 0x0000, 0xa37a, 0x7028, 0xa076, 0x7034, 0xa072,
-	0xa48e, 0xa592, 0xa696, 0xa79a, 0x080c, 0x112e, 0x7007, 0x0002,
-	0x701f, 0x4f53, 0x0005, 0x7030, 0x9005, 0x1178, 0x7120, 0x7028,
+	0xa48e, 0xa592, 0xa696, 0xa79a, 0x080c, 0x1140, 0x7007, 0x0002,
+	0x701f, 0x4e53, 0x0005, 0x7030, 0x9005, 0x1178, 0x7120, 0x7028,
 	0x20a0, 0x901e, 0x7034, 0x20e8, 0x2061, 0x18b6, 0x2c44, 0xa48c,
-	0xa590, 0xa694, 0xa798, 0x0804, 0x4f11, 0x7224, 0x900e, 0x2001,
-	0x0003, 0x080c, 0x84ff, 0x2208, 0x0804, 0x34e8, 0x00f6, 0x00e6,
-	0x080c, 0x55ef, 0x2009, 0x0007, 0x1904, 0x4fe6, 0x2071, 0x189c,
-	0x745c, 0x84ff, 0x2009, 0x000e, 0x1904, 0x4fe6, 0xac9c, 0xad98,
-	0xaea4, 0xafa0, 0x0096, 0x080c, 0x104a, 0x2009, 0x0002, 0x0904,
-	0x4fe6, 0x2900, 0x705e, 0x900e, 0x901e, 0x7356, 0x7362, 0xa860,
+	0xa590, 0xa694, 0xa798, 0x0804, 0x4e11, 0x7224, 0x900e, 0x2001,
+	0x0003, 0x080c, 0x847f, 0x2208, 0x0804, 0x3408, 0x00f6, 0x00e6,
+	0x080c, 0x54f0, 0x2009, 0x0007, 0x1904, 0x4ee6, 0x2071, 0x189c,
+	0x745c, 0x84ff, 0x2009, 0x000e, 0x1904, 0x4ee6, 0xac9c, 0xad98,
+	0xaea4, 0xafa0, 0x0096, 0x080c, 0x105c, 0x2009, 0x0002, 0x0904,
+	0x4ee6, 0x2900, 0x705e, 0x900e, 0x901e, 0x7356, 0x7362, 0xa860,
 	0x7066, 0xa85c, 0x9080, 0x0003, 0x705a, 0x20a0, 0x91d8, 0x1000,
-	0x2b5c, 0x8bff, 0x0178, 0x080c, 0x67c3, 0x0118, 0x080c, 0x67cb,
+	0x2b5c, 0x8bff, 0x0178, 0x080c, 0x66ca, 0x0118, 0x080c, 0x66d2,
 	0x1148, 0xb814, 0x20a9, 0x0001, 0x4004, 0xb810, 0x4004, 0x4104,
 	0x9398, 0x0003, 0x8108, 0x9182, 0x0800, 0x0120, 0x9386, 0x003c,
 	0x01e8, 0x0c20, 0x83ff, 0x11c0, 0x7254, 0x900e, 0x2001, 0x0003,
-	0x080c, 0x84ff, 0x2208, 0x009e, 0xa897, 0x4000, 0xa99a, 0x715c,
-	0x81ff, 0x090c, 0x0dfa, 0x2148, 0x080c, 0x1063, 0x9006, 0x705e,
+	0x080c, 0x847f, 0x2208, 0x009e, 0xa897, 0x4000, 0xa99a, 0x715c,
+	0x81ff, 0x090c, 0x0e02, 0x2148, 0x080c, 0x1075, 0x9006, 0x705e,
 	0x918d, 0x0001, 0x2008, 0x0418, 0x7063, 0x0001, 0x7152, 0x7054,
 	0x9300, 0x7056, 0x2061, 0x18b7, 0x2c44, 0xa37a, 0x7058, 0xa076,
-	0x7064, 0xa072, 0xa48e, 0xa592, 0xa696, 0xa79a, 0xa09f, 0x4ff2,
-	0x000e, 0xa0a2, 0x080c, 0x112e, 0x9006, 0x0048, 0x009e, 0xa897,
+	0x7064, 0xa072, 0xa48e, 0xa592, 0xa696, 0xa79a, 0xa09f, 0x4ef2,
+	0x000e, 0xa0a2, 0x080c, 0x1140, 0x9006, 0x0048, 0x009e, 0xa897,
 	0x4005, 0xa99a, 0x900e, 0x9085, 0x0001, 0x2001, 0x0030, 0x00ee,
-	0x00fe, 0x0005, 0x00f6, 0xa0a0, 0x904d, 0x090c, 0x0dfa, 0x00e6,
+	0x00fe, 0x0005, 0x00f6, 0xa0a0, 0x904d, 0x090c, 0x0e02, 0x00e6,
 	0x2071, 0x189c, 0xa06c, 0x908e, 0x0100, 0x0138, 0xa87b, 0x0030,
 	0xa883, 0x0000, 0xa897, 0x4002, 0x00d8, 0x7060, 0x9005, 0x1158,
 	0x7150, 0x7058, 0x20a0, 0x901e, 0x7064, 0x20e8, 0xa48c, 0xa590,
 	0xa694, 0xa798, 0x0428, 0xa87b, 0x0000, 0xa883, 0x0000, 0xa897,
-	0x4000, 0x7254, 0x900e, 0x2001, 0x0003, 0x080c, 0x84ff, 0xaa9a,
-	0x715c, 0x81ff, 0x090c, 0x0dfa, 0x2148, 0x080c, 0x1063, 0x705f,
-	0x0000, 0xa0a0, 0x2048, 0x0126, 0x2091, 0x8000, 0x080c, 0x6ae9,
+	0x4000, 0x7254, 0x900e, 0x2001, 0x0003, 0x080c, 0x847f, 0xaa9a,
+	0x715c, 0x81ff, 0x090c, 0x0e02, 0x2148, 0x080c, 0x1075, 0x705f,
+	0x0000, 0xa0a0, 0x2048, 0x0126, 0x2091, 0x8000, 0x080c, 0x6a23,
 	0x012e, 0xa09f, 0x0000, 0xa0a3, 0x0000, 0x00ee, 0x00fe, 0x0005,
-	0x91d8, 0x1000, 0x2b5c, 0x8bff, 0x0178, 0x080c, 0x67c3, 0x0118,
-	0x080c, 0x67cb, 0x1148, 0xb814, 0x20a9, 0x0001, 0x4004, 0xb810,
+	0x91d8, 0x1000, 0x2b5c, 0x8bff, 0x0178, 0x080c, 0x66ca, 0x0118,
+	0x080c, 0x66d2, 0x1148, 0xb814, 0x20a9, 0x0001, 0x4004, 0xb810,
 	0x4004, 0x4104, 0x9398, 0x0003, 0x8108, 0x9182, 0x0800, 0x0120,
 	0x9386, 0x003c, 0x0518, 0x0c20, 0x83ff, 0x11f0, 0x7154, 0x810c,
-	0xa99a, 0xa897, 0x4000, 0x715c, 0x81ff, 0x090c, 0x0dfa, 0x2148,
-	0x080c, 0x1063, 0x9006, 0x705e, 0x918d, 0x0001, 0x2008, 0xa0a0,
-	0x2048, 0x0126, 0x2091, 0x8000, 0x080c, 0x6ae9, 0x012e, 0xa09f,
+	0xa99a, 0xa897, 0x4000, 0x715c, 0x81ff, 0x090c, 0x0e02, 0x2148,
+	0x080c, 0x1075, 0x9006, 0x705e, 0x918d, 0x0001, 0x2008, 0xa0a0,
+	0x2048, 0x0126, 0x2091, 0x8000, 0x080c, 0x6a23, 0x012e, 0xa09f,
 	0x0000, 0xa0a3, 0x0000, 0x0070, 0x7063, 0x0001, 0x7152, 0x7054,
 	0x9300, 0x7056, 0xa37a, 0xa48e, 0xa592, 0xa696, 0xa79a, 0x080c,
-	0x112e, 0x9006, 0x00ee, 0x0005, 0x0096, 0xa88c, 0x90be, 0x7000,
+	0x1140, 0x9006, 0x00ee, 0x0005, 0x0096, 0xa88c, 0x90be, 0x7000,
 	0x0148, 0x90be, 0x7100, 0x0130, 0x90be, 0x7200, 0x0118, 0x009e,
-	0x0804, 0x351d, 0xa884, 0xa988, 0x080c, 0x276e, 0x1518, 0x080c,
-	0x643f, 0x1500, 0x7126, 0xbe12, 0xbd16, 0xae7c, 0x080c, 0x4abf,
-	0x01c8, 0x080c, 0x4abf, 0x01b0, 0x009e, 0xa867, 0x0000, 0xa868,
-	0xc0fd, 0xa86a, 0xa823, 0x0000, 0xa804, 0x2048, 0x080c, 0xbfe3,
-	0x1120, 0x2009, 0x0003, 0x0804, 0x351a, 0x7007, 0x0003, 0x701f,
-	0x50bf, 0x0005, 0x009e, 0x2009, 0x0002, 0x0804, 0x351a, 0x7124,
-	0x080c, 0x3286, 0xa820, 0x9086, 0x8001, 0x1120, 0x2009, 0x0004,
-	0x0804, 0x351a, 0x2900, 0x7022, 0xa804, 0x0096, 0x2048, 0x8906,
+	0x0804, 0x343d, 0xa884, 0xa988, 0x080c, 0x266e, 0x1518, 0x080c,
+	0x6344, 0x1500, 0x7126, 0xbe12, 0xbd16, 0xae7c, 0x080c, 0x49b8,
+	0x01c8, 0x080c, 0x49b8, 0x01b0, 0x009e, 0xa867, 0x0000, 0xa868,
+	0xc0fd, 0xa86a, 0xa823, 0x0000, 0xa804, 0x2048, 0x080c, 0xbee7,
+	0x1120, 0x2009, 0x0003, 0x0804, 0x343a, 0x7007, 0x0003, 0x701f,
+	0x4fbf, 0x0005, 0x009e, 0x2009, 0x0002, 0x0804, 0x343a, 0x7124,
+	0x080c, 0x31a6, 0xa820, 0x9086, 0x8001, 0x1120, 0x2009, 0x0004,
+	0x0804, 0x343a, 0x2900, 0x7022, 0xa804, 0x0096, 0x2048, 0x8906,
 	0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x009e, 0x9080,
 	0x0002, 0x0076, 0x0006, 0x2098, 0x20a0, 0x27e0, 0x27e8, 0x20a9,
-	0x002a, 0x080c, 0x0fae, 0xaa6c, 0xab70, 0xac74, 0xad78, 0x2061,
+	0x002a, 0x080c, 0x0fc0, 0xaa6c, 0xab70, 0xac74, 0xad78, 0x2061,
 	0x18b6, 0x2c44, 0xa06b, 0x0000, 0xae64, 0xaf8c, 0x97c6, 0x7000,
 	0x0118, 0x97c6, 0x7100, 0x1148, 0x96c2, 0x0004, 0x0600, 0x2009,
-	0x0004, 0x000e, 0x007e, 0x0804, 0x4b0b, 0x97c6, 0x7200, 0x11b8,
+	0x0004, 0x000e, 0x007e, 0x0804, 0x4a04, 0x97c6, 0x7200, 0x11b8,
 	0x96c2, 0x0054, 0x02a0, 0x000e, 0x007e, 0x2061, 0x18b6, 0x2c44,
 	0xa076, 0xa772, 0xa07b, 0x002a, 0xa28e, 0xa392, 0xa496, 0xa59a,
-	0x080c, 0x112e, 0x7007, 0x0002, 0x701f, 0x511b, 0x0005, 0x000e,
-	0x007e, 0x0804, 0x351d, 0x7020, 0x2048, 0xa804, 0x2048, 0xa804,
+	0x080c, 0x1140, 0x7007, 0x0002, 0x701f, 0x501b, 0x0005, 0x000e,
+	0x007e, 0x0804, 0x343d, 0x7020, 0x2048, 0xa804, 0x2048, 0xa804,
 	0x2048, 0x8906, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0,
 	0x9080, 0x0002, 0x2098, 0x20a0, 0x27e0, 0x27e8, 0x20a9, 0x002a,
-	0x080c, 0x0fae, 0x2100, 0x2238, 0x2061, 0x18b6, 0x2c44, 0xa28c,
-	0xa390, 0xa494, 0xa598, 0x2009, 0x002a, 0x0804, 0x4b0b, 0x81ff,
-	0x1904, 0x351a, 0x798c, 0x2001, 0x1956, 0x918c, 0x8000, 0x2102,
-	0x080c, 0x4ad6, 0x0904, 0x351d, 0x080c, 0x67c3, 0x0120, 0x080c,
-	0x67cb, 0x1904, 0x351d, 0x080c, 0x6566, 0x0904, 0x351a, 0x0126,
-	0x2091, 0x8000, 0x080c, 0x662c, 0x012e, 0x0904, 0x351a, 0x2001,
-	0x1956, 0x2004, 0xd0fc, 0x1904, 0x34e8, 0x0804, 0x4533, 0xa9a0,
-	0x2001, 0x1956, 0x918c, 0x8000, 0xc18d, 0x2102, 0x080c, 0x4ae3,
-	0x01a0, 0x080c, 0x67c3, 0x0118, 0x080c, 0x67cb, 0x1170, 0x080c,
-	0x6566, 0x2009, 0x0002, 0x0128, 0x080c, 0x662c, 0x1170, 0x2009,
+	0x080c, 0x0fc0, 0x2100, 0x2238, 0x2061, 0x18b6, 0x2c44, 0xa28c,
+	0xa390, 0xa494, 0xa598, 0x2009, 0x002a, 0x0804, 0x4a04, 0x81ff,
+	0x1904, 0x343a, 0x798c, 0x2001, 0x1958, 0x918c, 0x8000, 0x2102,
+	0x080c, 0x49cf, 0x0904, 0x343d, 0x080c, 0x66ca, 0x0120, 0x080c,
+	0x66d2, 0x1904, 0x343d, 0x080c, 0x646b, 0x0904, 0x343a, 0x0126,
+	0x2091, 0x8000, 0x080c, 0x6531, 0x012e, 0x0904, 0x343a, 0x2001,
+	0x1958, 0x2004, 0xd0fc, 0x1904, 0x3408, 0x0804, 0x4462, 0xa9a0,
+	0x2001, 0x1958, 0x918c, 0x8000, 0xc18d, 0x2102, 0x080c, 0x49dc,
+	0x01a0, 0x080c, 0x66ca, 0x0118, 0x080c, 0x66d2, 0x1170, 0x080c,
+	0x646b, 0x2009, 0x0002, 0x0128, 0x080c, 0x6531, 0x1170, 0x2009,
 	0x0003, 0xa897, 0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e,
 	0x9085, 0x0001, 0x2001, 0x0030, 0x0005, 0xa897, 0x4000, 0x2001,
-	0x1956, 0x2004, 0xd0fc, 0x1128, 0x080c, 0x55e3, 0x0110, 0x9006,
+	0x1958, 0x2004, 0xd0fc, 0x1128, 0x080c, 0x54e4, 0x0110, 0x9006,
 	0x0018, 0x900e, 0x9085, 0x0001, 0x2001, 0x0000, 0x0005, 0x78a8,
-	0xd08c, 0x1118, 0xd084, 0x0904, 0x44a8, 0x080c, 0x4af2, 0x0904,
-	0x351d, 0x080c, 0x4abf, 0x1120, 0x2009, 0x0002, 0x0804, 0x351a,
-	0x080c, 0x67c3, 0x0130, 0x908e, 0x0004, 0x0118, 0x908e, 0x0005,
+	0xd08c, 0x1118, 0xd084, 0x0904, 0x43d7, 0x080c, 0x49eb, 0x0904,
+	0x343d, 0x080c, 0x49b8, 0x1120, 0x2009, 0x0002, 0x0804, 0x343a,
+	0x080c, 0x66ca, 0x0130, 0x908e, 0x0004, 0x0118, 0x908e, 0x0005,
 	0x15a0, 0x78a8, 0xd08c, 0x0120, 0xb800, 0xc08c, 0xb802, 0x0028,
-	0x080c, 0x55db, 0xd0b4, 0x0904, 0x44e2, 0x7884, 0x908e, 0x007e,
-	0x0904, 0x44e2, 0x908e, 0x007f, 0x0904, 0x44e2, 0x908e, 0x0080,
-	0x0904, 0x44e2, 0xb800, 0xd08c, 0x1904, 0x44e2, 0xa867, 0x0000,
-	0xa868, 0xc0fd, 0xa86a, 0x080c, 0xc002, 0x1120, 0x2009, 0x0003,
-	0x0804, 0x351a, 0x7007, 0x0003, 0x701f, 0x51e7, 0x0005, 0x080c,
-	0x4af2, 0x0904, 0x351d, 0x0804, 0x44e2, 0x080c, 0x32df, 0x0108,
+	0x080c, 0x54dc, 0xd0b4, 0x0904, 0x4411, 0x7884, 0x908e, 0x007e,
+	0x0904, 0x4411, 0x908e, 0x007f, 0x0904, 0x4411, 0x908e, 0x0080,
+	0x0904, 0x4411, 0xb800, 0xd08c, 0x1904, 0x4411, 0xa867, 0x0000,
+	0xa868, 0xc0fd, 0xa86a, 0x080c, 0xbf06, 0x1120, 0x2009, 0x0003,
+	0x0804, 0x343a, 0x7007, 0x0003, 0x701f, 0x50e7, 0x0005, 0x080c,
+	0x49eb, 0x0904, 0x343d, 0x0804, 0x4411, 0x080c, 0x31ff, 0x0108,
 	0x0005, 0x2009, 0x1833, 0x210c, 0x81ff, 0x0120, 0x2009, 0x0001,
-	0x0804, 0x351a, 0x080c, 0x55ef, 0x0120, 0x2009, 0x0007, 0x0804,
-	0x351a, 0x080c, 0x67bb, 0x0120, 0x2009, 0x0008, 0x0804, 0x351a,
-	0xb89c, 0xd0a4, 0x1118, 0xd0ac, 0x1904, 0x44e2, 0x9006, 0xa866,
-	0xa832, 0xa868, 0xc0fd, 0xa86a, 0x080c, 0xc061, 0x1120, 0x2009,
-	0x0003, 0x0804, 0x351a, 0x7007, 0x0003, 0x701f, 0x5220, 0x0005,
-	0xa830, 0x9086, 0x0100, 0x1120, 0x2009, 0x0004, 0x0804, 0x552f,
-	0x080c, 0x4af2, 0x0904, 0x351d, 0x0804, 0x51b9, 0x81ff, 0x2009,
-	0x0001, 0x1904, 0x351a, 0x080c, 0x55ef, 0x2009, 0x0007, 0x1904,
-	0x351a, 0x080c, 0x67bb, 0x0120, 0x2009, 0x0008, 0x0804, 0x351a,
-	0x080c, 0x4af2, 0x0904, 0x351d, 0x080c, 0x67c3, 0x2009, 0x0009,
-	0x1904, 0x351a, 0x080c, 0x4abf, 0x2009, 0x0002, 0x0904, 0x351a,
-	0x9006, 0xa866, 0xa832, 0xa868, 0xc0fd, 0xa86a, 0x7988, 0x9194,
-	0xff00, 0x918c, 0x00ff, 0x9006, 0x82ff, 0x1128, 0xc0ed, 0xa952,
-	0x798c, 0xa956, 0x0038, 0x928e, 0x0100, 0x1904, 0x351d, 0xc0e5,
-	0xa952, 0xa956, 0xa83e, 0x080c, 0xc2b4, 0x2009, 0x0003, 0x0904,
-	0x351a, 0x7007, 0x0003, 0x701f, 0x5276, 0x0005, 0xa830, 0x9086,
-	0x0100, 0x2009, 0x0004, 0x0904, 0x351a, 0x0804, 0x34e8, 0x7aa8,
-	0x9284, 0xc000, 0x0148, 0xd2ec, 0x01a0, 0x080c, 0x55ef, 0x1188,
-	0x2009, 0x0014, 0x0804, 0x351a, 0xd2dc, 0x1578, 0x81ff, 0x2009,
-	0x0001, 0x1904, 0x351a, 0x080c, 0x55ef, 0x2009, 0x0007, 0x1904,
-	0x351a, 0xd2f4, 0x0138, 0x9284, 0x5000, 0xc0d5, 0x080c, 0x55b5,
-	0x0804, 0x34e8, 0xd2fc, 0x0160, 0x080c, 0x4af2, 0x0904, 0x351d,
-	0x7984, 0x9284, 0x9000, 0xc0d5, 0x080c, 0x558a, 0x0804, 0x34e8,
-	0x080c, 0x4af2, 0x0904, 0x351d, 0xb804, 0x9084, 0x00ff, 0x9086,
-	0x0006, 0x2009, 0x0009, 0x1904, 0x5365, 0x080c, 0x4abf, 0x2009,
-	0x0002, 0x0904, 0x5365, 0xa85c, 0x9080, 0x001b, 0xaf60, 0x2009,
-	0x0008, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x080c, 0x4b08, 0x701f,
-	0x52d2, 0x0005, 0xa86c, 0x9086, 0x0500, 0x1138, 0xa870, 0x9005,
-	0x1120, 0xa874, 0x9084, 0xff00, 0x0110, 0x1904, 0x351d, 0xa866,
-	0xa832, 0xa868, 0xc0fd, 0xa86a, 0x080c, 0x4af2, 0x1110, 0x0804,
-	0x351d, 0x2009, 0x0043, 0x080c, 0xc31c, 0x2009, 0x0003, 0x0904,
-	0x5365, 0x7007, 0x0003, 0x701f, 0x52f6, 0x0005, 0xa830, 0x9086,
-	0x0100, 0x2009, 0x0004, 0x0904, 0x5365, 0x7984, 0x7aa8, 0x9284,
-	0x1000, 0xe085, 0x080c, 0x558a, 0x0804, 0x34e8, 0x00c6, 0xaab0,
-	0x9284, 0xc000, 0x0148, 0xd2ec, 0x0170, 0x080c, 0x55ef, 0x1158,
-	0x2009, 0x0014, 0x0804, 0x5354, 0x2061, 0x1800, 0x080c, 0x55ef,
-	0x2009, 0x0007, 0x15c8, 0xd2f4, 0x0130, 0x9284, 0x5000, 0xc0d5,
-	0x080c, 0x55b5, 0x0058, 0xd2fc, 0x0180, 0x080c, 0x4af0, 0x0590,
-	0xa998, 0x9284, 0x9000, 0xc0d5, 0x080c, 0x558a, 0xa87b, 0x0000,
-	0xa883, 0x0000, 0xa897, 0x4000, 0x0438, 0x080c, 0x4af0, 0x0510,
-	0x080c, 0x67c3, 0x2009, 0x0009, 0x11b8, 0xa8c4, 0x9086, 0x0500,
-	0x11c8, 0xa8c8, 0x9005, 0x11b0, 0xa8cc, 0x9084, 0xff00, 0x1190,
-	0x080c, 0x4af0, 0x1108, 0x0070, 0x2009, 0x004b, 0x080c, 0xc31c,
-	0x2009, 0x0003, 0x0108, 0x0078, 0x0431, 0x19c0, 0xa897, 0x4005,
-	0xa99a, 0x0010, 0xa897, 0x4006, 0x900e, 0x9085, 0x0001, 0x2001,
-	0x0030, 0x00ce, 0x0005, 0x9006, 0x0ce0, 0x7aa8, 0xd2dc, 0x0904,
-	0x351a, 0x0016, 0x7984, 0x9284, 0x1000, 0xc0fd, 0x080c, 0x558a,
-	0x001e, 0x1904, 0x351a, 0x0804, 0x34e8, 0x00f6, 0x2d78, 0xaab0,
-	0x0021, 0x00fe, 0x0005, 0xaab0, 0xc2d5, 0xd2dc, 0x0150, 0x0016,
-	0xa998, 0x9284, 0x1400, 0xc0fd, 0x080c, 0x558a, 0x001e, 0x9085,
-	0x0001, 0x0005, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x351a,
-	0x080c, 0x55ef, 0x0120, 0x2009, 0x0007, 0x0804, 0x351a, 0x7984,
-	0x7ea8, 0x96b4, 0x00ff, 0x080c, 0x649f, 0x1904, 0x351d, 0x9186,
-	0x007f, 0x0138, 0x080c, 0x67c3, 0x0120, 0x2009, 0x0009, 0x0804,
-	0x351a, 0x080c, 0x4abf, 0x1120, 0x2009, 0x0002, 0x0804, 0x351a,
-	0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x2001, 0x0100, 0x8007,
-	0xa80a, 0x080c, 0xc01c, 0x1120, 0x2009, 0x0003, 0x0804, 0x351a,
-	0x7007, 0x0003, 0x701f, 0x53c5, 0x0005, 0xa808, 0x8007, 0x9086,
-	0x0100, 0x1120, 0x2009, 0x0004, 0x0804, 0x351a, 0xa8e0, 0xa866,
-	0xa810, 0x8007, 0x9084, 0x00ff, 0x800c, 0xa814, 0x8007, 0x9084,
-	0x00ff, 0x8004, 0x9080, 0x0002, 0x9108, 0x8906, 0x8006, 0x8007,
-	0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x0004, 0x7a8c, 0x7b88,
-	0x7c9c, 0x7d98, 0x0804, 0x4b0b, 0x080c, 0x4abf, 0x1120, 0x2009,
-	0x0002, 0x0804, 0x351a, 0x7984, 0x9194, 0xff00, 0x918c, 0x00ff,
-	0x8217, 0x82ff, 0x1118, 0x7023, 0x198b, 0x0040, 0x92c6, 0x0001,
-	0x1118, 0x7023, 0x19a5, 0x0010, 0x0804, 0x351d, 0x2009, 0x001a,
+	0x0804, 0x343a, 0x080c, 0x54f0, 0x0120, 0x2009, 0x0007, 0x0804,
+	0x343a, 0x080c, 0x66c2, 0x0120, 0x2009, 0x0008, 0x0804, 0x343a,
+	0xb89c, 0xd0a4, 0x1118, 0xd0ac, 0x1904, 0x4411, 0x9006, 0xa866,
+	0xa832, 0xa868, 0xc0fd, 0xa86a, 0x080c, 0xbf65, 0x1120, 0x2009,
+	0x0003, 0x0804, 0x343a, 0x7007, 0x0003, 0x701f, 0x5120, 0x0005,
+	0xa830, 0x9086, 0x0100, 0x1120, 0x2009, 0x0004, 0x0804, 0x5430,
+	0x080c, 0x49eb, 0x0904, 0x343d, 0x0804, 0x50b9, 0x81ff, 0x2009,
+	0x0001, 0x1904, 0x343a, 0x080c, 0x54f0, 0x2009, 0x0007, 0x1904,
+	0x343a, 0x080c, 0x66c2, 0x0120, 0x2009, 0x0008, 0x0804, 0x343a,
+	0x080c, 0x49eb, 0x0904, 0x343d, 0x080c, 0x66ca, 0x2009, 0x0009,
+	0x1904, 0x343a, 0x080c, 0x49b8, 0x2009, 0x0002, 0x0904, 0x343a,
+	0x9006, 0xa866, 0xa832, 0xa868, 0xc0fd, 0xa86a, 0x7988, 0xa95a,
+	0x9194, 0xfd00, 0x918c, 0x00ff, 0x9006, 0x82ff, 0x1128, 0xc0ed,
+	0xa952, 0x798c, 0xa956, 0x0038, 0x928e, 0x0100, 0x1904, 0x343d,
+	0xc0e5, 0xa952, 0xa956, 0xa83e, 0x080c, 0xc1b8, 0x2009, 0x0003,
+	0x0904, 0x343a, 0x7007, 0x0003, 0x701f, 0x5177, 0x0005, 0xa830,
+	0x9086, 0x0100, 0x2009, 0x0004, 0x0904, 0x343a, 0x0804, 0x3408,
+	0x7aa8, 0x9284, 0xc000, 0x0148, 0xd2ec, 0x01a0, 0x080c, 0x54f0,
+	0x1188, 0x2009, 0x0014, 0x0804, 0x343a, 0xd2dc, 0x1578, 0x81ff,
+	0x2009, 0x0001, 0x1904, 0x343a, 0x080c, 0x54f0, 0x2009, 0x0007,
+	0x1904, 0x343a, 0xd2f4, 0x0138, 0x9284, 0x5000, 0xc0d5, 0x080c,
+	0x54b6, 0x0804, 0x3408, 0xd2fc, 0x0160, 0x080c, 0x49eb, 0x0904,
+	0x343d, 0x7984, 0x9284, 0x9000, 0xc0d5, 0x080c, 0x548b, 0x0804,
+	0x3408, 0x080c, 0x49eb, 0x0904, 0x343d, 0xb804, 0x9084, 0x00ff,
+	0x9086, 0x0006, 0x2009, 0x0009, 0x1904, 0x5266, 0x080c, 0x49b8,
+	0x2009, 0x0002, 0x0904, 0x5266, 0xa85c, 0x9080, 0x001b, 0xaf60,
+	0x2009, 0x0008, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0x080c, 0x4a01,
+	0x701f, 0x51d3, 0x0005, 0xa86c, 0x9086, 0x0500, 0x1138, 0xa870,
+	0x9005, 0x1120, 0xa874, 0x9084, 0xff00, 0x0110, 0x1904, 0x343d,
+	0xa866, 0xa832, 0xa868, 0xc0fd, 0xa86a, 0x080c, 0x49eb, 0x1110,
+	0x0804, 0x343d, 0x2009, 0x0043, 0x080c, 0xc224, 0x2009, 0x0003,
+	0x0904, 0x5266, 0x7007, 0x0003, 0x701f, 0x51f7, 0x0005, 0xa830,
+	0x9086, 0x0100, 0x2009, 0x0004, 0x0904, 0x5266, 0x7984, 0x7aa8,
+	0x9284, 0x1000, 0xc0d5, 0x080c, 0x548b, 0x0804, 0x3408, 0x00c6,
+	0xaab0, 0x9284, 0xc000, 0x0148, 0xd2ec, 0x0170, 0x080c, 0x54f0,
+	0x1158, 0x2009, 0x0014, 0x0804, 0x5255, 0x2061, 0x1800, 0x080c,
+	0x54f0, 0x2009, 0x0007, 0x15c8, 0xd2f4, 0x0130, 0x9284, 0x5000,
+	0xc0d5, 0x080c, 0x54b6, 0x0058, 0xd2fc, 0x0180, 0x080c, 0x49e9,
+	0x0590, 0xa998, 0x9284, 0x9000, 0xc0d5, 0x080c, 0x548b, 0xa87b,
+	0x0000, 0xa883, 0x0000, 0xa897, 0x4000, 0x0438, 0x080c, 0x49e9,
+	0x0510, 0x080c, 0x66ca, 0x2009, 0x0009, 0x11b8, 0xa8c4, 0x9086,
+	0x0500, 0x11c8, 0xa8c8, 0x9005, 0x11b0, 0xa8cc, 0x9084, 0xff00,
+	0x1190, 0x080c, 0x49e9, 0x1108, 0x0070, 0x2009, 0x004b, 0x080c,
+	0xc224, 0x2009, 0x0003, 0x0108, 0x0078, 0x0431, 0x19c0, 0xa897,
+	0x4005, 0xa99a, 0x0010, 0xa897, 0x4006, 0x900e, 0x9085, 0x0001,
+	0x2001, 0x0030, 0x00ce, 0x0005, 0x9006, 0x0ce0, 0x7aa8, 0xd2dc,
+	0x0904, 0x343a, 0x0016, 0x7984, 0x9284, 0x1000, 0xc0fd, 0x080c,
+	0x548b, 0x001e, 0x1904, 0x343a, 0x0804, 0x3408, 0x00f6, 0x2d78,
+	0xaab0, 0x0021, 0x00fe, 0x0005, 0xaab0, 0xc2d5, 0xd2dc, 0x0150,
+	0x0016, 0xa998, 0x9284, 0x1400, 0xc0fd, 0x080c, 0x548b, 0x001e,
+	0x9085, 0x0001, 0x0005, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804,
+	0x343a, 0x080c, 0x54f0, 0x0120, 0x2009, 0x0007, 0x0804, 0x343a,
+	0x7984, 0x7ea8, 0x96b4, 0x00ff, 0x080c, 0x63a4, 0x1904, 0x343d,
+	0x9186, 0x007f, 0x0138, 0x080c, 0x66ca, 0x0120, 0x2009, 0x0009,
+	0x0804, 0x343a, 0x080c, 0x49b8, 0x1120, 0x2009, 0x0002, 0x0804,
+	0x343a, 0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x2001, 0x0100,
+	0x8007, 0xa80a, 0x080c, 0xbf20, 0x1120, 0x2009, 0x0003, 0x0804,
+	0x343a, 0x7007, 0x0003, 0x701f, 0x52c6, 0x0005, 0xa808, 0x8007,
+	0x9086, 0x0100, 0x1120, 0x2009, 0x0004, 0x0804, 0x343a, 0xa8e0,
+	0xa866, 0xa810, 0x8007, 0x9084, 0x00ff, 0x800c, 0xa814, 0x8007,
+	0x9084, 0x00ff, 0x8004, 0x9080, 0x0002, 0x9108, 0x8906, 0x8006,
+	0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x0004, 0x7a8c,
+	0x7b88, 0x7c9c, 0x7d98, 0x0804, 0x4a04, 0x080c, 0x49b8, 0x1120,
+	0x2009, 0x0002, 0x0804, 0x343a, 0x7984, 0x9194, 0xff00, 0x918c,
+	0x00ff, 0x8217, 0x82ff, 0x1118, 0x7023, 0x198e, 0x0040, 0x92c6,
+	0x0001, 0x1118, 0x7023, 0x19a8, 0x0010, 0x0804, 0x343d, 0x2009,
+	0x001a, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0xa85c, 0x9080, 0x0019,
+	0xaf60, 0x080c, 0x4a01, 0x701f, 0x5316, 0x0005, 0x2001, 0x182d,
+	0x2003, 0x0001, 0xa85c, 0x9080, 0x0019, 0x2098, 0xa860, 0x20e0,
+	0x20a9, 0x001a, 0x7020, 0x20a0, 0x20e9, 0x0001, 0x4003, 0x0804,
+	0x3408, 0x080c, 0x49b8, 0x1120, 0x2009, 0x0002, 0x0804, 0x343a,
+	0x7984, 0x9194, 0xff00, 0x918c, 0x00ff, 0x8217, 0x82ff, 0x1118,
+	0x2099, 0x198e, 0x0040, 0x92c6, 0x0001, 0x1118, 0x2099, 0x19a8,
+	0x0010, 0x0804, 0x343d, 0xa85c, 0x9080, 0x0019, 0x20a0, 0xa860,
+	0x20e8, 0x20a9, 0x001a, 0x20e1, 0x0001, 0x4003, 0x2009, 0x001a,
 	0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0xa85c, 0x9080, 0x0019, 0xaf60,
-	0x080c, 0x4b08, 0x701f, 0x5415, 0x0005, 0x2001, 0x182d, 0x2003,
-	0x0001, 0xa85c, 0x9080, 0x0019, 0x2098, 0xa860, 0x20e0, 0x20a9,
-	0x001a, 0x7020, 0x20a0, 0x20e9, 0x0001, 0x4003, 0x0804, 0x34e8,
-	0x080c, 0x4abf, 0x1120, 0x2009, 0x0002, 0x0804, 0x351a, 0x7984,
-	0x9194, 0xff00, 0x918c, 0x00ff, 0x8217, 0x82ff, 0x1118, 0x2099,
-	0x198b, 0x0040, 0x92c6, 0x0001, 0x1118, 0x2099, 0x19a5, 0x0010,
-	0x0804, 0x351d, 0xa85c, 0x9080, 0x0019, 0x20a0, 0xa860, 0x20e8,
-	0x20a9, 0x001a, 0x20e1, 0x0001, 0x4003, 0x2009, 0x001a, 0x7a8c,
-	0x7b88, 0x7c9c, 0x7d98, 0xa85c, 0x9080, 0x0019, 0xaf60, 0x0804,
-	0x4b0b, 0x7884, 0x908a, 0x1000, 0x1a04, 0x351d, 0x0126, 0x2091,
-	0x8000, 0x8003, 0x800b, 0x810b, 0x9108, 0x00c6, 0x2061, 0x19d2,
-	0x6142, 0x00ce, 0x012e, 0x0804, 0x34e8, 0x00c6, 0x080c, 0x7207,
-	0x1160, 0x080c, 0x7504, 0x080c, 0x5f2b, 0x9085, 0x0001, 0x080c,
-	0x724e, 0x080c, 0x7127, 0x080c, 0x0dfa, 0x2061, 0x1800, 0x6030,
-	0xc09d, 0x6032, 0x080c, 0x5dea, 0x00ce, 0x0005, 0x00c6, 0x2001,
-	0x1800, 0x2004, 0x908e, 0x0000, 0x0904, 0x351a, 0x7884, 0x9005,
-	0x0188, 0x7888, 0x2061, 0x1974, 0x2c0c, 0x2062, 0x080c, 0x2b98,
-	0x01a0, 0x080c, 0x2ba0, 0x0188, 0x080c, 0x2ba8, 0x0170, 0x2162,
-	0x0804, 0x351d, 0x2061, 0x0100, 0x6038, 0x9086, 0x0007, 0x1118,
-	0x2009, 0x0001, 0x0010, 0x2009, 0x0000, 0x7884, 0x9086, 0x0002,
-	0x1568, 0x2061, 0x0100, 0x6028, 0xc09c, 0x602a, 0x0026, 0x2011,
-	0x0003, 0x080c, 0x9a0f, 0x2011, 0x0002, 0x080c, 0x9a19, 0x002e,
-	0x080c, 0x9927, 0x0036, 0x901e, 0x080c, 0x999d, 0x003e, 0x60e3,
-	0x0000, 0x080c, 0xdc13, 0x080c, 0xdc2e, 0x9085, 0x0001, 0x080c,
-	0x724e, 0x9006, 0x080c, 0x2c88, 0x2001, 0x1800, 0x2003, 0x0004,
-	0x2001, 0x197f, 0x2003, 0x0000, 0x6027, 0x0008, 0x00ce, 0x0804,
-	0x34e8, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x351a, 0x080c,
-	0x55ef, 0x0120, 0x2009, 0x0007, 0x0804, 0x351a, 0x7984, 0x7ea8,
-	0x96b4, 0x00ff, 0x080c, 0x649f, 0x1904, 0x351d, 0x9186, 0x007f,
-	0x0138, 0x080c, 0x67c3, 0x0120, 0x2009, 0x0009, 0x0804, 0x351a,
-	0x080c, 0x4abf, 0x1120, 0x2009, 0x0002, 0x0804, 0x351a, 0xa867,
-	0x0000, 0xa868, 0xc0fd, 0xa86a, 0x080c, 0xc01f, 0x1120, 0x2009,
-	0x0003, 0x0804, 0x351a, 0x7007, 0x0003, 0x701f, 0x5518, 0x0005,
-	0xa830, 0x9086, 0x0100, 0x1120, 0x2009, 0x0004, 0x0804, 0x351a,
-	0xa8e0, 0xa866, 0xa834, 0x8007, 0x800c, 0xa85c, 0x9080, 0x000c,
-	0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0xaf60, 0x0804, 0x4b0b, 0xa898,
-	0x9086, 0x000d, 0x1904, 0x351a, 0x2021, 0x4005, 0x0126, 0x2091,
-	0x8000, 0x0e04, 0x553c, 0x0010, 0x012e, 0x0cc0, 0x7c36, 0x9486,
-	0x4000, 0x0118, 0x7833, 0x0011, 0x0010, 0x7833, 0x0010, 0x7883,
-	0x4005, 0xa998, 0x7986, 0xa9a4, 0x799a, 0xa9a8, 0x799e, 0x080c,
-	0x4afb, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c,
-	0x11e0, 0x7007, 0x0001, 0x2091, 0x5000, 0x700f, 0x0000, 0x012e,
-	0x0005, 0x0126, 0x2091, 0x8000, 0x00c6, 0x2061, 0x19d2, 0x7984,
-	0x6152, 0x614e, 0x6057, 0x0000, 0x604b, 0x0009, 0x7898, 0x606a,
-	0x789c, 0x6066, 0x7888, 0x6062, 0x788c, 0x605e, 0x2001, 0x19e0,
-	0x2044, 0x2001, 0x19e7, 0xa076, 0xa060, 0xa072, 0xa07b, 0x0001,
-	0xa07f, 0x0002, 0xa06b, 0x0000, 0xa09f, 0x0000, 0x00ce, 0x012e,
-	0x0804, 0x34e8, 0x0126, 0x2091, 0x8000, 0x00b6, 0x00c6, 0x90e4,
-	0xc000, 0x0168, 0x0006, 0xd0d4, 0x0130, 0x0036, 0x2019, 0x0029,
-	0x080c, 0x32a4, 0x003e, 0x080c, 0xbe84, 0x000e, 0x1198, 0xd0e4,
-	0x0160, 0x9180, 0x1000, 0x2004, 0x905d, 0x0160, 0x080c, 0x5f45,
-	0x080c, 0xa062, 0x0110, 0xb817, 0x0000, 0x9006, 0x00ce, 0x00be,
-	0x012e, 0x0005, 0x9085, 0x0001, 0x0cc8, 0x0126, 0x2091, 0x8000,
-	0x0156, 0x2010, 0x900e, 0x20a9, 0x0800, 0x0016, 0x9180, 0x1000,
-	0x2004, 0x9005, 0x0188, 0x9186, 0x007e, 0x0170, 0x9186, 0x007f,
-	0x0158, 0x9186, 0x0080, 0x0140, 0x9186, 0x00ff, 0x0128, 0x0026,
-	0x2200, 0x080c, 0x558a, 0x002e, 0x001e, 0x8108, 0x1f04, 0x55bd,
-	0x015e, 0x012e, 0x0005, 0x2001, 0x185c, 0x2004, 0x0005, 0x2001,
-	0x187b, 0x2004, 0x0005, 0x0006, 0x2001, 0x1810, 0x2004, 0xd0d4,
-	0x000e, 0x0005, 0x2001, 0x180e, 0x2004, 0xd0b4, 0x0005, 0x2001,
-	0x1800, 0x2004, 0x9086, 0x0003, 0x0005, 0x0016, 0x00e6, 0x2071,
-	0x189c, 0x7108, 0x910d, 0x710a, 0x00ee, 0x001e, 0x0005, 0x79a4,
-	0x9182, 0x0081, 0x1a04, 0x351d, 0x810c, 0x0016, 0x080c, 0x4abf,
-	0x0170, 0x080c, 0x0f39, 0x2100, 0x2238, 0x7d84, 0x7c88, 0x7b8c,
-	0x7a90, 0x001e, 0x080c, 0x4b08, 0x701f, 0x561b, 0x0005, 0x2009,
-	0x0002, 0x0804, 0x351a, 0x2079, 0x0000, 0x7d94, 0x7c98, 0x7ba8,
-	0x7aac, 0x79a4, 0x810c, 0x2061, 0x18b6, 0x2c44, 0xa770, 0xa074,
-	0x2071, 0x189c, 0x080c, 0x4b0b, 0x701f, 0x562f, 0x0005, 0x2061,
-	0x18b6, 0x2c44, 0x0016, 0x0026, 0xa270, 0xa174, 0x080c, 0x0f41,
-	0x002e, 0x001e, 0x080c, 0x0fee, 0x9006, 0xa802, 0xa806, 0x0804,
-	0x34e8, 0x0126, 0x0156, 0x0136, 0x0146, 0x01c6, 0x01d6, 0x00c6,
-	0x00d6, 0x00e6, 0x00f6, 0x2061, 0x0100, 0x2069, 0x0200, 0x2071,
-	0x1800, 0x6044, 0xd0a4, 0x11e8, 0xd084, 0x0118, 0x080c, 0x57ea,
-	0x0068, 0xd08c, 0x0118, 0x080c, 0x56f3, 0x0040, 0xd094, 0x0118,
-	0x080c, 0x56c3, 0x0018, 0xd09c, 0x0108, 0x0099, 0x00fe, 0x00ee,
-	0x00de, 0x00ce, 0x01de, 0x01ce, 0x014e, 0x013e, 0x015e, 0x012e,
-	0x0005, 0x0016, 0x6128, 0xd19c, 0x1110, 0xc19d, 0x612a, 0x001e,
-	0x0c68, 0x0006, 0x7094, 0x9005, 0x000e, 0x0120, 0x7097, 0x0000,
-	0x708f, 0x0000, 0x624c, 0x9286, 0xf0f0, 0x1150, 0x6048, 0x9086,
-	0xf0f0, 0x0130, 0x624a, 0x6043, 0x0090, 0x6043, 0x0010, 0x0490,
-	0x9294, 0xff00, 0x9296, 0xf700, 0x0178, 0x7138, 0xd1a4, 0x1160,
-	0x6240, 0x9295, 0x0100, 0x6242, 0x9294, 0x0010, 0x0128, 0x2009,
-	0x00f7, 0x080c, 0x5ea7, 0x00f0, 0x6040, 0x9084, 0x0010, 0x9085,
-	0x0140, 0x6042, 0x6043, 0x0000, 0x7083, 0x0000, 0x709f, 0x0001,
-	0x70c3, 0x0000, 0x70db, 0x0000, 0x2009, 0x1c80, 0x200b, 0x0000,
-	0x7093, 0x0000, 0x7087, 0x000f, 0x2009, 0x000f, 0x2011, 0x5d8d,
-	0x080c, 0x836c, 0x0005, 0x2001, 0x187d, 0x2004, 0xd08c, 0x0110,
-	0x705b, 0xffff, 0x7084, 0x9005, 0x1528, 0x2011, 0x5d8d, 0x080c,
-	0x82da, 0x6040, 0x9094, 0x0010, 0x9285, 0x0020, 0x6042, 0x20a9,
-	0x00c8, 0x6044, 0xd08c, 0x1168, 0x1f04, 0x56d9, 0x6242, 0x7097,
-	0x0000, 0x6040, 0x9094, 0x0010, 0x9285, 0x0080, 0x6042, 0x6242,
-	0x0048, 0x6242, 0x7097, 0x0000, 0x708b, 0x0000, 0x9006, 0x080c,
-	0x5f30, 0x0000, 0x0005, 0x7088, 0x908a, 0x0003, 0x1a0c, 0x0dfa,
-	0x000b, 0x0005, 0x56fd, 0x574e, 0x57e9, 0x00f6, 0x0016, 0x6900,
-	0x918c, 0x0800, 0x708b, 0x0001, 0x2001, 0x015d, 0x2003, 0x0000,
-	0x6803, 0x00fc, 0x20a9, 0x0004, 0x6800, 0x9084, 0x00fc, 0x0120,
-	0x1f04, 0x570c, 0x080c, 0x0dfa, 0x68a0, 0x68a2, 0x689c, 0x689e,
-	0x6898, 0x689a, 0xa001, 0x918d, 0x1600, 0x6902, 0x001e, 0x6837,
-	0x0020, 0x080c, 0x5f0c, 0x2079, 0x1c00, 0x7833, 0x1101, 0x7837,
-	0x0000, 0x20e1, 0x0001, 0x2099, 0x1805, 0x20e9, 0x0001, 0x20a1,
-	0x1c0e, 0x20a9, 0x0004, 0x4003, 0x080c, 0x9eeb, 0x20e1, 0x0001,
-	0x2099, 0x1c00, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, 0x0014,
-	0x4003, 0x60c3, 0x000c, 0x600f, 0x0000, 0x080c, 0x5dbe, 0x00fe,
-	0x9006, 0x708e, 0x6043, 0x0008, 0x6042, 0x0005, 0x00f6, 0x708c,
-	0x708f, 0x0000, 0x9025, 0x0904, 0x57c6, 0x6020, 0xd0b4, 0x1904,
-	0x57c4, 0x719c, 0x81ff, 0x0904, 0x57b2, 0x9486, 0x000c, 0x1904,
-	0x57bf, 0x9480, 0x0018, 0x8004, 0x20a8, 0x080c, 0x5f05, 0x2011,
-	0x0260, 0x2019, 0x1c00, 0x220c, 0x2304, 0x9106, 0x11e8, 0x8210,
-	0x8318, 0x1f04, 0x576b, 0x6043, 0x0004, 0x2061, 0x0140, 0x605b,
-	0xbc94, 0x605f, 0xf0f0, 0x2061, 0x0100, 0x6043, 0x0006, 0x708b,
-	0x0002, 0x7097, 0x0002, 0x2009, 0x07d0, 0x2011, 0x5d94, 0x080c,
-	0x836c, 0x080c, 0x5f0c, 0x04c0, 0x080c, 0x5f05, 0x2079, 0x0260,
-	0x7930, 0x918e, 0x1101, 0x1558, 0x7834, 0x9005, 0x1540, 0x7900,
-	0x918c, 0x00ff, 0x1118, 0x7804, 0x9005, 0x0190, 0x080c, 0x5f05,
-	0x2011, 0x026e, 0x2019, 0x1805, 0x20a9, 0x0004, 0x220c, 0x2304,
-	0x9102, 0x0230, 0x11a0, 0x8210, 0x8318, 0x1f04, 0x57a6, 0x0078,
-	0x709f, 0x0000, 0x080c, 0x5f05, 0x20e1, 0x0000, 0x2099, 0x0260,
-	0x20e9, 0x0001, 0x20a1, 0x1c00, 0x20a9, 0x0014, 0x4003, 0x6043,
-	0x0008, 0x6043, 0x0000, 0x0010, 0x00fe, 0x0005, 0x6040, 0x9085,
-	0x0100, 0x6042, 0x6020, 0xd0b4, 0x1db8, 0x080c, 0x9eeb, 0x20e1,
-	0x0001, 0x2099, 0x1c00, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9,
-	0x0014, 0x4003, 0x60c3, 0x000c, 0x2011, 0x19c9, 0x2013, 0x0000,
-	0x708f, 0x0000, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x080c, 0x964d,
-	0x08d8, 0x0005, 0x7094, 0x908a, 0x001d, 0x1a0c, 0x0dfa, 0x000b,
-	0x0005, 0x581b, 0x582e, 0x5857, 0x5877, 0x589d, 0x58cc, 0x58f2,
-	0x592a, 0x5950, 0x597e, 0x59b9, 0x59f1, 0x5a0f, 0x5a3a, 0x5a5c,
-	0x5a77, 0x5a81, 0x5ab5, 0x5adb, 0x5b0a, 0x5b30, 0x5b68, 0x5bac,
-	0x5be9, 0x5c0a, 0x5c63, 0x5c85, 0x5cb3, 0x5cb3, 0x00c6, 0x2061,
-	0x1800, 0x6003, 0x0007, 0x2061, 0x0100, 0x6004, 0x9084, 0xfff9,
-	0x6006, 0x00ce, 0x0005, 0x2061, 0x0140, 0x605b, 0xbc94, 0x605f,
-	0xf0f0, 0x2061, 0x0100, 0x6043, 0x0002, 0x7097, 0x0001, 0x2009,
-	0x07d0, 0x2011, 0x5d94, 0x080c, 0x836c, 0x0005, 0x00f6, 0x708c,
-	0x9086, 0x0014, 0x1510, 0x6042, 0x6020, 0xd0b4, 0x11f0, 0x080c,
-	0x5f05, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1102, 0x11a0, 0x7834,
-	0x9005, 0x1188, 0x7a38, 0xd2fc, 0x0128, 0x70c0, 0x9005, 0x1110,
-	0x70c3, 0x0001, 0x2011, 0x5d94, 0x080c, 0x82da, 0x7097, 0x0010,
-	0x080c, 0x5a81, 0x0010, 0x708f, 0x0000, 0x00fe, 0x0005, 0x00f6,
-	0x7097, 0x0003, 0x6043, 0x0004, 0x2011, 0x5d94, 0x080c, 0x82da,
-	0x080c, 0x5e89, 0x2079, 0x0240, 0x7833, 0x1102, 0x7837, 0x0000,
-	0x20a9, 0x0008, 0x9f88, 0x000e, 0x200b, 0x0000, 0x8108, 0x1f04,
-	0x586c, 0x60c3, 0x0014, 0x080c, 0x5dbe, 0x00fe, 0x0005, 0x00f6,
-	0x708c, 0x9005, 0x0500, 0x2011, 0x5d94, 0x080c, 0x82da, 0x9086,
-	0x0014, 0x11b8, 0x080c, 0x5f05, 0x2079, 0x0260, 0x7a30, 0x9296,
-	0x1102, 0x1178, 0x7834, 0x9005, 0x1160, 0x7a38, 0xd2fc, 0x0128,
-	0x70c0, 0x9005, 0x1110, 0x70c3, 0x0001, 0x7097, 0x0004, 0x0029,
-	0x0010, 0x080c, 0x5ee1, 0x00fe, 0x0005, 0x00f6, 0x7097, 0x0005,
-	0x080c, 0x5e89, 0x2079, 0x0240, 0x7833, 0x1103, 0x7837, 0x0000,
-	0x080c, 0x5f05, 0x080c, 0x5ee8, 0x1170, 0x7080, 0x9005, 0x1158,
-	0x7158, 0x9186, 0xffff, 0x0138, 0x2011, 0x0008, 0x080c, 0x5d41,
-	0x0168, 0x080c, 0x5ebe, 0x20a9, 0x0008, 0x20e1, 0x0000, 0x2099,
-	0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003, 0x60c3, 0x0014,
-	0x080c, 0x5dbe, 0x00fe, 0x0005, 0x00f6, 0x708c, 0x9005, 0x0500,
-	0x2011, 0x5d94, 0x080c, 0x82da, 0x9086, 0x0014, 0x11b8, 0x080c,
-	0x5f05, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1103, 0x1178, 0x7834,
+	0x0804, 0x4a04, 0x7884, 0x908a, 0x1000, 0x1a04, 0x343d, 0x0126,
+	0x2091, 0x8000, 0x8003, 0x800b, 0x810b, 0x9108, 0x00c6, 0x2061,
+	0x19d5, 0x614a, 0x00ce, 0x012e, 0x0804, 0x3408, 0x00c6, 0x080c,
+	0x717f, 0x1160, 0x080c, 0x747b, 0x080c, 0x5e30, 0x9085, 0x0001,
+	0x080c, 0x71c3, 0x080c, 0x709f, 0x080c, 0x0e02, 0x2061, 0x1800,
+	0x6030, 0xc09d, 0x6032, 0x080c, 0x5cef, 0x00ce, 0x0005, 0x00c6,
+	0x2001, 0x1800, 0x2004, 0x908e, 0x0000, 0x0904, 0x343a, 0x7884,
+	0x9005, 0x0188, 0x7888, 0x2061, 0x1976, 0x2c0c, 0x2062, 0x080c,
+	0x2a98, 0x01a0, 0x080c, 0x2aa0, 0x0188, 0x080c, 0x2aa8, 0x0170,
+	0x2162, 0x0804, 0x343d, 0x2061, 0x0100, 0x6038, 0x9086, 0x0007,
+	0x1118, 0x2009, 0x0001, 0x0010, 0x2009, 0x0000, 0x7884, 0x9086,
+	0x0002, 0x1568, 0x2061, 0x0100, 0x6028, 0xc09c, 0x602a, 0x0026,
+	0x2011, 0x0003, 0x080c, 0x990e, 0x2011, 0x0002, 0x080c, 0x9918,
+	0x002e, 0x080c, 0x9826, 0x0036, 0x901e, 0x080c, 0x989c, 0x003e,
+	0x60e3, 0x0000, 0x080c, 0xdb7a, 0x080c, 0xdb95, 0x9085, 0x0001,
+	0x080c, 0x71c3, 0x9006, 0x080c, 0x2b88, 0x2001, 0x1800, 0x2003,
+	0x0004, 0x2001, 0x1981, 0x2003, 0x0000, 0x6027, 0x0008, 0x00ce,
+	0x0804, 0x3408, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804, 0x343a,
+	0x080c, 0x54f0, 0x0120, 0x2009, 0x0007, 0x0804, 0x343a, 0x7984,
+	0x7ea8, 0x96b4, 0x00ff, 0x080c, 0x63a4, 0x1904, 0x343d, 0x9186,
+	0x007f, 0x0138, 0x080c, 0x66ca, 0x0120, 0x2009, 0x0009, 0x0804,
+	0x343a, 0x080c, 0x49b8, 0x1120, 0x2009, 0x0002, 0x0804, 0x343a,
+	0xa867, 0x0000, 0xa868, 0xc0fd, 0xa86a, 0x080c, 0xbf23, 0x1120,
+	0x2009, 0x0003, 0x0804, 0x343a, 0x7007, 0x0003, 0x701f, 0x5419,
+	0x0005, 0xa830, 0x9086, 0x0100, 0x1120, 0x2009, 0x0004, 0x0804,
+	0x343a, 0xa8e0, 0xa866, 0xa834, 0x8007, 0x800c, 0xa85c, 0x9080,
+	0x000c, 0x7a8c, 0x7b88, 0x7c9c, 0x7d98, 0xaf60, 0x0804, 0x4a04,
+	0xa898, 0x9086, 0x000d, 0x1904, 0x343a, 0x2021, 0x4005, 0x0126,
+	0x2091, 0x8000, 0x0e04, 0x543d, 0x0010, 0x012e, 0x0cc0, 0x7c36,
+	0x9486, 0x4000, 0x0118, 0x7833, 0x0011, 0x0010, 0x7833, 0x0010,
+	0x7883, 0x4005, 0xa998, 0x7986, 0xa9a4, 0x799a, 0xa9a8, 0x799e,
+	0x080c, 0x49f4, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084,
+	0x190c, 0x11f2, 0x7007, 0x0001, 0x2091, 0x5000, 0x700f, 0x0000,
+	0x012e, 0x0005, 0x0126, 0x2091, 0x8000, 0x00c6, 0x2061, 0x19d5,
+	0x7984, 0x615a, 0x6156, 0x605f, 0x0000, 0x6053, 0x0009, 0x7898,
+	0x6072, 0x789c, 0x606e, 0x7888, 0x606a, 0x788c, 0x6066, 0x2001,
+	0x19e5, 0x2044, 0x2001, 0x19ec, 0xa076, 0xa060, 0xa072, 0xa07b,
+	0x0001, 0xa07f, 0x0002, 0xa06b, 0x0000, 0xa09f, 0x0000, 0x00ce,
+	0x012e, 0x0804, 0x3408, 0x0126, 0x2091, 0x8000, 0x00b6, 0x00c6,
+	0x90e4, 0xc000, 0x0168, 0x0006, 0xd0d4, 0x0130, 0x0036, 0x2019,
+	0x0029, 0x080c, 0x31c4, 0x003e, 0x080c, 0xbd88, 0x000e, 0x1198,
+	0xd0e4, 0x0160, 0x9180, 0x1000, 0x2004, 0x905d, 0x0160, 0x080c,
+	0x5e4a, 0x080c, 0x9f54, 0x0110, 0xb817, 0x0000, 0x9006, 0x00ce,
+	0x00be, 0x012e, 0x0005, 0x9085, 0x0001, 0x0cc8, 0x0126, 0x2091,
+	0x8000, 0x0156, 0x2010, 0x900e, 0x20a9, 0x0800, 0x0016, 0x9180,
+	0x1000, 0x2004, 0x9005, 0x0188, 0x9186, 0x007e, 0x0170, 0x9186,
+	0x007f, 0x0158, 0x9186, 0x0080, 0x0140, 0x9186, 0x00ff, 0x0128,
+	0x0026, 0x2200, 0x080c, 0x548b, 0x002e, 0x001e, 0x8108, 0x1f04,
+	0x54be, 0x015e, 0x012e, 0x0005, 0x2001, 0x185c, 0x2004, 0x0005,
+	0x2001, 0x187b, 0x2004, 0x0005, 0x0006, 0x2001, 0x1810, 0x2004,
+	0xd0d4, 0x000e, 0x0005, 0x2001, 0x180e, 0x2004, 0xd0b4, 0x0005,
+	0x2001, 0x1800, 0x2004, 0x9086, 0x0003, 0x0005, 0x0016, 0x00e6,
+	0x2071, 0x189c, 0x7108, 0x910d, 0x710a, 0x00ee, 0x001e, 0x0005,
+	0x79a4, 0x81ff, 0x0904, 0x343d, 0x9182, 0x0081, 0x1a04, 0x343d,
+	0x810c, 0x0016, 0x080c, 0x49b8, 0x0170, 0x080c, 0x0f4b, 0x2100,
+	0x2238, 0x7d84, 0x7c88, 0x7b8c, 0x7a90, 0x001e, 0x080c, 0x4a01,
+	0x701f, 0x5520, 0x0005, 0x001e, 0x2009, 0x0002, 0x0804, 0x343a,
+	0x2079, 0x0000, 0x7d94, 0x7c98, 0x7ba8, 0x7aac, 0x79a4, 0x810c,
+	0x2061, 0x18b6, 0x2c44, 0xa770, 0xa074, 0x2071, 0x189c, 0x080c,
+	0x4a04, 0x701f, 0x5534, 0x0005, 0x2061, 0x18b6, 0x2c44, 0x0016,
+	0x0026, 0xa270, 0xa174, 0x080c, 0x0f53, 0x002e, 0x001e, 0x080c,
+	0x1000, 0x9006, 0xa802, 0xa806, 0x0804, 0x3408, 0x0126, 0x0156,
+	0x0136, 0x0146, 0x01c6, 0x01d6, 0x00c6, 0x00d6, 0x00e6, 0x00f6,
+	0x2061, 0x0100, 0x2069, 0x0200, 0x2071, 0x1800, 0x6044, 0xd0a4,
+	0x11e8, 0xd084, 0x0118, 0x080c, 0x56ef, 0x0068, 0xd08c, 0x0118,
+	0x080c, 0x55f8, 0x0040, 0xd094, 0x0118, 0x080c, 0x55c8, 0x0018,
+	0xd09c, 0x0108, 0x0099, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x01de,
+	0x01ce, 0x014e, 0x013e, 0x015e, 0x012e, 0x0005, 0x0016, 0x6128,
+	0xd19c, 0x1110, 0xc19d, 0x612a, 0x001e, 0x0c68, 0x0006, 0x7094,
+	0x9005, 0x000e, 0x0120, 0x7097, 0x0000, 0x708f, 0x0000, 0x624c,
+	0x9286, 0xf0f0, 0x1150, 0x6048, 0x9086, 0xf0f0, 0x0130, 0x624a,
+	0x6043, 0x0090, 0x6043, 0x0010, 0x0490, 0x9294, 0xff00, 0x9296,
+	0xf700, 0x0178, 0x7138, 0xd1a4, 0x1160, 0x6240, 0x9295, 0x0100,
+	0x6242, 0x9294, 0x0010, 0x0128, 0x2009, 0x00f7, 0x080c, 0x5dac,
+	0x00f0, 0x6040, 0x9084, 0x0010, 0x9085, 0x0140, 0x6042, 0x6043,
+	0x0000, 0x7083, 0x0000, 0x709f, 0x0001, 0x70c3, 0x0000, 0x70db,
+	0x0000, 0x2009, 0x1c80, 0x200b, 0x0000, 0x7093, 0x0000, 0x7087,
+	0x000f, 0x2009, 0x000f, 0x2011, 0x5c92, 0x080c, 0x82ec, 0x0005,
+	0x2001, 0x187d, 0x2004, 0xd08c, 0x0110, 0x705b, 0xffff, 0x7084,
+	0x9005, 0x1528, 0x2011, 0x5c92, 0x080c, 0x825a, 0x6040, 0x9094,
+	0x0010, 0x9285, 0x0020, 0x6042, 0x20a9, 0x00c8, 0x6044, 0xd08c,
+	0x1168, 0x1f04, 0x55de, 0x6242, 0x7097, 0x0000, 0x6040, 0x9094,
+	0x0010, 0x9285, 0x0080, 0x6042, 0x6242, 0x0048, 0x6242, 0x7097,
+	0x0000, 0x708b, 0x0000, 0x9006, 0x080c, 0x5e35, 0x0000, 0x0005,
+	0x7088, 0x908a, 0x0003, 0x1a0c, 0x0e02, 0x000b, 0x0005, 0x5602,
+	0x5653, 0x56ee, 0x00f6, 0x0016, 0x6900, 0x918c, 0x0800, 0x708b,
+	0x0001, 0x2001, 0x015d, 0x2003, 0x0000, 0x6803, 0x00fc, 0x20a9,
+	0x0004, 0x6800, 0x9084, 0x00fc, 0x0120, 0x1f04, 0x5611, 0x080c,
+	0x0e02, 0x68a0, 0x68a2, 0x689c, 0x689e, 0x6898, 0x689a, 0xa001,
+	0x918d, 0x1600, 0x6902, 0x001e, 0x6837, 0x0020, 0x080c, 0x5e11,
+	0x2079, 0x1c00, 0x7833, 0x1101, 0x7837, 0x0000, 0x20e1, 0x0001,
+	0x2099, 0x1805, 0x20e9, 0x0001, 0x20a1, 0x1c0e, 0x20a9, 0x0004,
+	0x4003, 0x080c, 0x9ddd, 0x20e1, 0x0001, 0x2099, 0x1c00, 0x20e9,
+	0x0000, 0x20a1, 0x0240, 0x20a9, 0x0014, 0x4003, 0x60c3, 0x000c,
+	0x600f, 0x0000, 0x080c, 0x5cc3, 0x00fe, 0x9006, 0x708e, 0x6043,
+	0x0008, 0x6042, 0x0005, 0x00f6, 0x708c, 0x708f, 0x0000, 0x9025,
+	0x0904, 0x56cb, 0x6020, 0xd0b4, 0x1904, 0x56c9, 0x719c, 0x81ff,
+	0x0904, 0x56b7, 0x9486, 0x000c, 0x1904, 0x56c4, 0x9480, 0x0018,
+	0x8004, 0x20a8, 0x080c, 0x5e0a, 0x2011, 0x0260, 0x2019, 0x1c00,
+	0x220c, 0x2304, 0x9106, 0x11e8, 0x8210, 0x8318, 0x1f04, 0x5670,
+	0x6043, 0x0004, 0x2061, 0x0140, 0x605b, 0xbc94, 0x605f, 0xf0f0,
+	0x2061, 0x0100, 0x6043, 0x0006, 0x708b, 0x0002, 0x7097, 0x0002,
+	0x2009, 0x07d0, 0x2011, 0x5c99, 0x080c, 0x82ec, 0x080c, 0x5e11,
+	0x04c0, 0x080c, 0x5e0a, 0x2079, 0x0260, 0x7930, 0x918e, 0x1101,
+	0x1558, 0x7834, 0x9005, 0x1540, 0x7900, 0x918c, 0x00ff, 0x1118,
+	0x7804, 0x9005, 0x0190, 0x080c, 0x5e0a, 0x2011, 0x026e, 0x2019,
+	0x1805, 0x20a9, 0x0004, 0x220c, 0x2304, 0x9102, 0x0230, 0x11a0,
+	0x8210, 0x8318, 0x1f04, 0x56ab, 0x0078, 0x709f, 0x0000, 0x080c,
+	0x5e0a, 0x20e1, 0x0000, 0x2099, 0x0260, 0x20e9, 0x0001, 0x20a1,
+	0x1c00, 0x20a9, 0x0014, 0x4003, 0x6043, 0x0008, 0x6043, 0x0000,
+	0x0010, 0x00fe, 0x0005, 0x6040, 0x9085, 0x0100, 0x6042, 0x6020,
+	0xd0b4, 0x1db8, 0x080c, 0x9ddd, 0x20e1, 0x0001, 0x2099, 0x1c00,
+	0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, 0x0014, 0x4003, 0x60c3,
+	0x000c, 0x2011, 0x19cc, 0x2013, 0x0000, 0x708f, 0x0000, 0x60a3,
+	0x0056, 0x60a7, 0x9575, 0x080c, 0x95fc, 0x08d8, 0x0005, 0x7094,
+	0x908a, 0x001d, 0x1a0c, 0x0e02, 0x000b, 0x0005, 0x5720, 0x5733,
+	0x575c, 0x577c, 0x57a2, 0x57d1, 0x57f7, 0x582f, 0x5855, 0x5883,
+	0x58be, 0x58f6, 0x5914, 0x593f, 0x5961, 0x597c, 0x5986, 0x59ba,
+	0x59e0, 0x5a0f, 0x5a35, 0x5a6d, 0x5ab1, 0x5aee, 0x5b0f, 0x5b68,
+	0x5b8a, 0x5bb8, 0x5bb8, 0x00c6, 0x2061, 0x1800, 0x6003, 0x0007,
+	0x2061, 0x0100, 0x6004, 0x9084, 0xfff9, 0x6006, 0x00ce, 0x0005,
+	0x2061, 0x0140, 0x605b, 0xbc94, 0x605f, 0xf0f0, 0x2061, 0x0100,
+	0x6043, 0x0002, 0x7097, 0x0001, 0x2009, 0x07d0, 0x2011, 0x5c99,
+	0x080c, 0x82ec, 0x0005, 0x00f6, 0x708c, 0x9086, 0x0014, 0x1510,
+	0x6042, 0x6020, 0xd0b4, 0x11f0, 0x080c, 0x5e0a, 0x2079, 0x0260,
+	0x7a30, 0x9296, 0x1102, 0x11a0, 0x7834, 0x9005, 0x1188, 0x7a38,
+	0xd2fc, 0x0128, 0x70c0, 0x9005, 0x1110, 0x70c3, 0x0001, 0x2011,
+	0x5c99, 0x080c, 0x825a, 0x7097, 0x0010, 0x080c, 0x5986, 0x0010,
+	0x708f, 0x0000, 0x00fe, 0x0005, 0x00f6, 0x7097, 0x0003, 0x6043,
+	0x0004, 0x2011, 0x5c99, 0x080c, 0x825a, 0x080c, 0x5d8e, 0x2079,
+	0x0240, 0x7833, 0x1102, 0x7837, 0x0000, 0x20a9, 0x0008, 0x9f88,
+	0x000e, 0x200b, 0x0000, 0x8108, 0x1f04, 0x5771, 0x60c3, 0x0014,
+	0x080c, 0x5cc3, 0x00fe, 0x0005, 0x00f6, 0x708c, 0x9005, 0x0500,
+	0x2011, 0x5c99, 0x080c, 0x825a, 0x9086, 0x0014, 0x11b8, 0x080c,
+	0x5e0a, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1102, 0x1178, 0x7834,
 	0x9005, 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c0, 0x9005, 0x1110,
-	0x70c3, 0x0001, 0x7097, 0x0006, 0x0029, 0x0010, 0x080c, 0x5ee1,
-	0x00fe, 0x0005, 0x00f6, 0x7097, 0x0007, 0x080c, 0x5e89, 0x2079,
-	0x0240, 0x7833, 0x1104, 0x7837, 0x0000, 0x080c, 0x5f05, 0x080c,
-	0x5ee8, 0x11b8, 0x7080, 0x9005, 0x11a0, 0x7160, 0x9186, 0xffff,
-	0x0180, 0x9180, 0x32e9, 0x200d, 0x918c, 0xff00, 0x810f, 0x2011,
-	0x0008, 0x080c, 0x5d41, 0x0180, 0x080c, 0x4ed8, 0x0110, 0x080c,
-	0x27d7, 0x20a9, 0x0008, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9,
-	0x0000, 0x20a1, 0x024e, 0x4003, 0x60c3, 0x0014, 0x080c, 0x5dbe,
-	0x00fe, 0x0005, 0x00f6, 0x708c, 0x9005, 0x0500, 0x2011, 0x5d94,
-	0x080c, 0x82da, 0x9086, 0x0014, 0x11b8, 0x080c, 0x5f05, 0x2079,
-	0x0260, 0x7a30, 0x9296, 0x1104, 0x1178, 0x7834, 0x9005, 0x1160,
-	0x7a38, 0xd2fc, 0x0128, 0x70c0, 0x9005, 0x1110, 0x70c3, 0x0001,
-	0x7097, 0x0008, 0x0029, 0x0010, 0x080c, 0x5ee1, 0x00fe, 0x0005,
-	0x00f6, 0x7097, 0x0009, 0x080c, 0x5e89, 0x2079, 0x0240, 0x7833,
-	0x1105, 0x7837, 0x0100, 0x080c, 0x5ee8, 0x1150, 0x7080, 0x9005,
-	0x1138, 0x080c, 0x5cb4, 0x1188, 0x9085, 0x0001, 0x080c, 0x27d7,
-	0x20a9, 0x0008, 0x080c, 0x5f05, 0x20e1, 0x0000, 0x2099, 0x026e,
-	0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003, 0x60c3, 0x0014, 0x080c,
-	0x5dbe, 0x0010, 0x080c, 0x580e, 0x00fe, 0x0005, 0x00f6, 0x708c,
-	0x9005, 0x05a8, 0x2011, 0x5d94, 0x080c, 0x82da, 0x9086, 0x0014,
-	0x1560, 0x080c, 0x5f05, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1105,
-	0x1520, 0x7834, 0x9084, 0x0100, 0x2011, 0x0100, 0x921e, 0x1160,
-	0x7a38, 0xd2fc, 0x0128, 0x70c0, 0x9005, 0x1110, 0x70c3, 0x0001,
-	0x7097, 0x000a, 0x00b1, 0x0098, 0x9005, 0x1178, 0x7a38, 0xd2fc,
-	0x0128, 0x70c0, 0x9005, 0x1110, 0x70c3, 0x0001, 0x7093, 0x0000,
-	0x7097, 0x000e, 0x080c, 0x5a5c, 0x0010, 0x080c, 0x5ee1, 0x00fe,
-	0x0005, 0x00f6, 0x7097, 0x000b, 0x2011, 0x1c0e, 0x20e9, 0x0001,
-	0x22a0, 0x20a9, 0x0040, 0x2019, 0xffff, 0x4304, 0x080c, 0x5e89,
-	0x2079, 0x0240, 0x7833, 0x1106, 0x7837, 0x0000, 0x080c, 0x5ee8,
-	0x0118, 0x2013, 0x0000, 0x0020, 0x705c, 0x9085, 0x0100, 0x2012,
-	0x20a9, 0x0040, 0x2009, 0x024e, 0x2011, 0x1c0e, 0x220e, 0x8210,
-	0x8108, 0x9186, 0x0260, 0x1128, 0x6810, 0x8000, 0x6812, 0x2009,
-	0x0240, 0x1f04, 0x59de, 0x60c3, 0x0084, 0x080c, 0x5dbe, 0x00fe,
-	0x0005, 0x00f6, 0x708c, 0x9005, 0x01c0, 0x2011, 0x5d94, 0x080c,
-	0x82da, 0x9086, 0x0084, 0x1178, 0x080c, 0x5f05, 0x2079, 0x0260,
-	0x7a30, 0x9296, 0x1106, 0x1138, 0x7834, 0x9005, 0x1120, 0x7097,
-	0x000c, 0x0029, 0x0010, 0x080c, 0x5ee1, 0x00fe, 0x0005, 0x00f6,
-	0x7097, 0x000d, 0x080c, 0x5e89, 0x2079, 0x0240, 0x7833, 0x1107,
-	0x7837, 0x0000, 0x080c, 0x5f05, 0x20a9, 0x0040, 0x2011, 0x026e,
-	0x2009, 0x024e, 0x220e, 0x8210, 0x8108, 0x9186, 0x0260, 0x1150,
-	0x6810, 0x8000, 0x6812, 0x2009, 0x0240, 0x6814, 0x8000, 0x6816,
-	0x2011, 0x0260, 0x1f04, 0x5a22, 0x60c3, 0x0084, 0x080c, 0x5dbe,
-	0x00fe, 0x0005, 0x00f6, 0x708c, 0x9005, 0x01e0, 0x2011, 0x5d94,
-	0x080c, 0x82da, 0x9086, 0x0084, 0x1198, 0x080c, 0x5f05, 0x2079,
-	0x0260, 0x7a30, 0x9296, 0x1107, 0x1158, 0x7834, 0x9005, 0x1140,
-	0x7093, 0x0001, 0x080c, 0x5e5b, 0x7097, 0x000e, 0x0029, 0x0010,
-	0x080c, 0x5ee1, 0x00fe, 0x0005, 0x918d, 0x0001, 0x080c, 0x5f30,
-	0x7097, 0x000f, 0x708f, 0x0000, 0x2061, 0x0140, 0x605b, 0xbc85,
-	0x605f, 0xb5b5, 0x2061, 0x0100, 0x6043, 0x0005, 0x6043, 0x0004,
-	0x2009, 0x07d0, 0x2011, 0x5d94, 0x080c, 0x82ce, 0x0005, 0x708c,
-	0x9005, 0x0130, 0x2011, 0x5d94, 0x080c, 0x82da, 0x7097, 0x0000,
-	0x0005, 0x7097, 0x0011, 0x080c, 0x9eeb, 0x080c, 0x5f05, 0x20e1,
-	0x0000, 0x2099, 0x0260, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x748c,
-	0x9480, 0x0018, 0x9080, 0x0007, 0x9084, 0x03f8, 0x8004, 0x20a8,
-	0x4003, 0x080c, 0x5ee8, 0x11a0, 0x7178, 0x81ff, 0x0188, 0x900e,
-	0x707c, 0x9084, 0x00ff, 0x0160, 0x080c, 0x276e, 0x9186, 0x007e,
-	0x0138, 0x9186, 0x0080, 0x0120, 0x2011, 0x0008, 0x080c, 0x5d41,
-	0x60c3, 0x0014, 0x080c, 0x5dbe, 0x0005, 0x00f6, 0x708c, 0x9005,
-	0x0500, 0x2011, 0x5d94, 0x080c, 0x82da, 0x9086, 0x0014, 0x11b8,
-	0x080c, 0x5f05, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1103, 0x1178,
-	0x7834, 0x9005, 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70c0, 0x9005,
-	0x1110, 0x70c3, 0x0001, 0x7097, 0x0012, 0x0029, 0x0010, 0x708f,
-	0x0000, 0x00fe, 0x0005, 0x00f6, 0x7097, 0x0013, 0x080c, 0x5e97,
-	0x2079, 0x0240, 0x7833, 0x1103, 0x7837, 0x0000, 0x080c, 0x5f05,
-	0x080c, 0x5ee8, 0x1170, 0x7080, 0x9005, 0x1158, 0x7158, 0x9186,
-	0xffff, 0x0138, 0x2011, 0x0008, 0x080c, 0x5d41, 0x0168, 0x080c,
-	0x5ebe, 0x20a9, 0x0008, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9,
-	0x0000, 0x20a1, 0x024e, 0x4003, 0x60c3, 0x0014, 0x080c, 0x5dbe,
-	0x00fe, 0x0005, 0x00f6, 0x708c, 0x9005, 0x0500, 0x2011, 0x5d94,
-	0x080c, 0x82da, 0x9086, 0x0014, 0x11b8, 0x080c, 0x5f05, 0x2079,
-	0x0260, 0x7a30, 0x9296, 0x1104, 0x1178, 0x7834, 0x9005, 0x1160,
+	0x70c3, 0x0001, 0x7097, 0x0004, 0x0029, 0x0010, 0x080c, 0x5de6,
+	0x00fe, 0x0005, 0x00f6, 0x7097, 0x0005, 0x080c, 0x5d8e, 0x2079,
+	0x0240, 0x7833, 0x1103, 0x7837, 0x0000, 0x080c, 0x5e0a, 0x080c,
+	0x5ded, 0x1170, 0x7080, 0x9005, 0x1158, 0x7158, 0x9186, 0xffff,
+	0x0138, 0x2011, 0x0008, 0x080c, 0x5c46, 0x0168, 0x080c, 0x5dc3,
+	0x20a9, 0x0008, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000,
+	0x20a1, 0x024e, 0x4003, 0x60c3, 0x0014, 0x080c, 0x5cc3, 0x00fe,
+	0x0005, 0x00f6, 0x708c, 0x9005, 0x0500, 0x2011, 0x5c99, 0x080c,
+	0x825a, 0x9086, 0x0014, 0x11b8, 0x080c, 0x5e0a, 0x2079, 0x0260,
+	0x7a30, 0x9296, 0x1103, 0x1178, 0x7834, 0x9005, 0x1160, 0x7a38,
+	0xd2fc, 0x0128, 0x70c0, 0x9005, 0x1110, 0x70c3, 0x0001, 0x7097,
+	0x0006, 0x0029, 0x0010, 0x080c, 0x5de6, 0x00fe, 0x0005, 0x00f6,
+	0x7097, 0x0007, 0x080c, 0x5d8e, 0x2079, 0x0240, 0x7833, 0x1104,
+	0x7837, 0x0000, 0x080c, 0x5e0a, 0x080c, 0x5ded, 0x11b8, 0x7080,
+	0x9005, 0x11a0, 0x7160, 0x9186, 0xffff, 0x0180, 0x9180, 0x3209,
+	0x200d, 0x918c, 0xff00, 0x810f, 0x2011, 0x0008, 0x080c, 0x5c46,
+	0x0180, 0x080c, 0x4dd8, 0x0110, 0x080c, 0x26d7, 0x20a9, 0x0008,
+	0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e,
+	0x4003, 0x60c3, 0x0014, 0x080c, 0x5cc3, 0x00fe, 0x0005, 0x00f6,
+	0x708c, 0x9005, 0x0500, 0x2011, 0x5c99, 0x080c, 0x825a, 0x9086,
+	0x0014, 0x11b8, 0x080c, 0x5e0a, 0x2079, 0x0260, 0x7a30, 0x9296,
+	0x1104, 0x1178, 0x7834, 0x9005, 0x1160, 0x7a38, 0xd2fc, 0x0128,
+	0x70c0, 0x9005, 0x1110, 0x70c3, 0x0001, 0x7097, 0x0008, 0x0029,
+	0x0010, 0x080c, 0x5de6, 0x00fe, 0x0005, 0x00f6, 0x7097, 0x0009,
+	0x080c, 0x5d8e, 0x2079, 0x0240, 0x7833, 0x1105, 0x7837, 0x0100,
+	0x080c, 0x5ded, 0x1150, 0x7080, 0x9005, 0x1138, 0x080c, 0x5bb9,
+	0x1188, 0x9085, 0x0001, 0x080c, 0x26d7, 0x20a9, 0x0008, 0x080c,
+	0x5e0a, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1,
+	0x024e, 0x4003, 0x60c3, 0x0014, 0x080c, 0x5cc3, 0x0010, 0x080c,
+	0x5713, 0x00fe, 0x0005, 0x00f6, 0x708c, 0x9005, 0x05a8, 0x2011,
+	0x5c99, 0x080c, 0x825a, 0x9086, 0x0014, 0x1560, 0x080c, 0x5e0a,
+	0x2079, 0x0260, 0x7a30, 0x9296, 0x1105, 0x1520, 0x7834, 0x9084,
+	0x0100, 0x2011, 0x0100, 0x921e, 0x1160, 0x7a38, 0xd2fc, 0x0128,
+	0x70c0, 0x9005, 0x1110, 0x70c3, 0x0001, 0x7097, 0x000a, 0x00b1,
+	0x0098, 0x9005, 0x1178, 0x7a38, 0xd2fc, 0x0128, 0x70c0, 0x9005,
+	0x1110, 0x70c3, 0x0001, 0x7093, 0x0000, 0x7097, 0x000e, 0x080c,
+	0x5961, 0x0010, 0x080c, 0x5de6, 0x00fe, 0x0005, 0x00f6, 0x7097,
+	0x000b, 0x2011, 0x1c0e, 0x20e9, 0x0001, 0x22a0, 0x20a9, 0x0040,
+	0x2019, 0xffff, 0x4304, 0x080c, 0x5d8e, 0x2079, 0x0240, 0x7833,
+	0x1106, 0x7837, 0x0000, 0x080c, 0x5ded, 0x0118, 0x2013, 0x0000,
+	0x0020, 0x705c, 0x9085, 0x0100, 0x2012, 0x20a9, 0x0040, 0x2009,
+	0x024e, 0x2011, 0x1c0e, 0x220e, 0x8210, 0x8108, 0x9186, 0x0260,
+	0x1128, 0x6810, 0x8000, 0x6812, 0x2009, 0x0240, 0x1f04, 0x58e3,
+	0x60c3, 0x0084, 0x080c, 0x5cc3, 0x00fe, 0x0005, 0x00f6, 0x708c,
+	0x9005, 0x01c0, 0x2011, 0x5c99, 0x080c, 0x825a, 0x9086, 0x0084,
+	0x1178, 0x080c, 0x5e0a, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1106,
+	0x1138, 0x7834, 0x9005, 0x1120, 0x7097, 0x000c, 0x0029, 0x0010,
+	0x080c, 0x5de6, 0x00fe, 0x0005, 0x00f6, 0x7097, 0x000d, 0x080c,
+	0x5d8e, 0x2079, 0x0240, 0x7833, 0x1107, 0x7837, 0x0000, 0x080c,
+	0x5e0a, 0x20a9, 0x0040, 0x2011, 0x026e, 0x2009, 0x024e, 0x220e,
+	0x8210, 0x8108, 0x9186, 0x0260, 0x1150, 0x6810, 0x8000, 0x6812,
+	0x2009, 0x0240, 0x6814, 0x8000, 0x6816, 0x2011, 0x0260, 0x1f04,
+	0x5927, 0x60c3, 0x0084, 0x080c, 0x5cc3, 0x00fe, 0x0005, 0x00f6,
+	0x708c, 0x9005, 0x01e0, 0x2011, 0x5c99, 0x080c, 0x825a, 0x9086,
+	0x0084, 0x1198, 0x080c, 0x5e0a, 0x2079, 0x0260, 0x7a30, 0x9296,
+	0x1107, 0x1158, 0x7834, 0x9005, 0x1140, 0x7093, 0x0001, 0x080c,
+	0x5d60, 0x7097, 0x000e, 0x0029, 0x0010, 0x080c, 0x5de6, 0x00fe,
+	0x0005, 0x918d, 0x0001, 0x080c, 0x5e35, 0x7097, 0x000f, 0x708f,
+	0x0000, 0x2061, 0x0140, 0x605b, 0xbc85, 0x605f, 0xb5b5, 0x2061,
+	0x0100, 0x6043, 0x0005, 0x6043, 0x0004, 0x2009, 0x07d0, 0x2011,
+	0x5c99, 0x080c, 0x824e, 0x0005, 0x708c, 0x9005, 0x0130, 0x2011,
+	0x5c99, 0x080c, 0x825a, 0x7097, 0x0000, 0x0005, 0x7097, 0x0011,
+	0x080c, 0x9ddd, 0x080c, 0x5e0a, 0x20e1, 0x0000, 0x2099, 0x0260,
+	0x20e9, 0x0000, 0x20a1, 0x0240, 0x748c, 0x9480, 0x0018, 0x9080,
+	0x0007, 0x9084, 0x03f8, 0x8004, 0x20a8, 0x4003, 0x080c, 0x5ded,
+	0x11a0, 0x7178, 0x81ff, 0x0188, 0x900e, 0x707c, 0x9084, 0x00ff,
+	0x0160, 0x080c, 0x266e, 0x9186, 0x007e, 0x0138, 0x9186, 0x0080,
+	0x0120, 0x2011, 0x0008, 0x080c, 0x5c46, 0x60c3, 0x0014, 0x080c,
+	0x5cc3, 0x0005, 0x00f6, 0x708c, 0x9005, 0x0500, 0x2011, 0x5c99,
+	0x080c, 0x825a, 0x9086, 0x0014, 0x11b8, 0x080c, 0x5e0a, 0x2079,
+	0x0260, 0x7a30, 0x9296, 0x1103, 0x1178, 0x7834, 0x9005, 0x1160,
 	0x7a38, 0xd2fc, 0x0128, 0x70c0, 0x9005, 0x1110, 0x70c3, 0x0001,
-	0x7097, 0x0014, 0x0029, 0x0010, 0x708f, 0x0000, 0x00fe, 0x0005,
-	0x00f6, 0x7097, 0x0015, 0x080c, 0x5e97, 0x2079, 0x0240, 0x7833,
-	0x1104, 0x7837, 0x0000, 0x080c, 0x5f05, 0x080c, 0x5ee8, 0x11b8,
-	0x7080, 0x9005, 0x11a0, 0x7160, 0x9186, 0xffff, 0x0180, 0x9180,
-	0x32e9, 0x200d, 0x918c, 0xff00, 0x810f, 0x2011, 0x0008, 0x080c,
-	0x5d41, 0x0180, 0x080c, 0x4ed8, 0x0110, 0x080c, 0x27d7, 0x20a9,
-	0x0008, 0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1,
-	0x024e, 0x4003, 0x60c3, 0x0014, 0x080c, 0x5dbe, 0x00fe, 0x0005,
-	0x00f6, 0x708c, 0x9005, 0x05f0, 0x2011, 0x5d94, 0x080c, 0x82da,
-	0x9086, 0x0014, 0x15a8, 0x080c, 0x5f05, 0x2079, 0x0260, 0x7a30,
-	0x9296, 0x1105, 0x1568, 0x7834, 0x9084, 0x0100, 0x2011, 0x0100,
-	0x921e, 0x1168, 0x9085, 0x0001, 0x080c, 0x5f30, 0x7a38, 0xd2fc,
-	0x0128, 0x70c0, 0x9005, 0x1110, 0x70c3, 0x0001, 0x0080, 0x9005,
-	0x11b8, 0x7a38, 0xd2fc, 0x0128, 0x70c0, 0x9005, 0x1110, 0x70c3,
-	0x0001, 0x9085, 0x0001, 0x080c, 0x5f30, 0x7093, 0x0000, 0x7a38,
-	0xd2f4, 0x0110, 0x70db, 0x0008, 0x7097, 0x0016, 0x0029, 0x0010,
-	0x708f, 0x0000, 0x00fe, 0x0005, 0x080c, 0x9eeb, 0x080c, 0x5f05,
-	0x20e1, 0x0000, 0x2099, 0x0260, 0x20e9, 0x0000, 0x20a1, 0x0240,
-	0x20a9, 0x000e, 0x4003, 0x2011, 0x026d, 0x2204, 0x9084, 0x0100,
-	0x2011, 0x024d, 0x2012, 0x2011, 0x026e, 0x7097, 0x0017, 0x080c,
-	0x5ee8, 0x1150, 0x7080, 0x9005, 0x1138, 0x080c, 0x5cb4, 0x1188,
-	0x9085, 0x0001, 0x080c, 0x27d7, 0x20a9, 0x0008, 0x080c, 0x5f05,
+	0x7097, 0x0012, 0x0029, 0x0010, 0x708f, 0x0000, 0x00fe, 0x0005,
+	0x00f6, 0x7097, 0x0013, 0x080c, 0x5d9c, 0x2079, 0x0240, 0x7833,
+	0x1103, 0x7837, 0x0000, 0x080c, 0x5e0a, 0x080c, 0x5ded, 0x1170,
+	0x7080, 0x9005, 0x1158, 0x7158, 0x9186, 0xffff, 0x0138, 0x2011,
+	0x0008, 0x080c, 0x5c46, 0x0168, 0x080c, 0x5dc3, 0x20a9, 0x0008,
 	0x20e1, 0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e,
-	0x4003, 0x60c3, 0x0014, 0x080c, 0x5dbe, 0x0010, 0x080c, 0x580e,
-	0x0005, 0x00f6, 0x708c, 0x9005, 0x01d8, 0x2011, 0x5d94, 0x080c,
-	0x82da, 0x9086, 0x0084, 0x1190, 0x080c, 0x5f05, 0x2079, 0x0260,
-	0x7a30, 0x9296, 0x1106, 0x1150, 0x7834, 0x9005, 0x1138, 0x9006,
-	0x080c, 0x5f30, 0x7097, 0x0018, 0x0029, 0x0010, 0x708f, 0x0000,
-	0x00fe, 0x0005, 0x00f6, 0x7097, 0x0019, 0x080c, 0x5e97, 0x2079,
-	0x0240, 0x7833, 0x1106, 0x7837, 0x0000, 0x080c, 0x5f05, 0x2009,
-	0x026e, 0x2039, 0x1c0e, 0x20a9, 0x0040, 0x213e, 0x8738, 0x8108,
-	0x9186, 0x0280, 0x1128, 0x6814, 0x8000, 0x6816, 0x2009, 0x0260,
-	0x1f04, 0x5c1d, 0x2039, 0x1c0e, 0x080c, 0x5ee8, 0x11e8, 0x2728,
-	0x2514, 0x8207, 0x9084, 0x00ff, 0x8000, 0x2018, 0x9294, 0x00ff,
-	0x8007, 0x9205, 0x202a, 0x705c, 0x2310, 0x8214, 0x92a0, 0x1c0e,
-	0x2414, 0x938c, 0x0001, 0x0118, 0x9294, 0xff00, 0x0018, 0x9294,
-	0x00ff, 0x8007, 0x9215, 0x2222, 0x20a9, 0x0040, 0x2009, 0x024e,
-	0x270e, 0x8738, 0x8108, 0x9186, 0x0260, 0x1128, 0x6810, 0x8000,
-	0x6812, 0x2009, 0x0240, 0x1f04, 0x5c50, 0x60c3, 0x0084, 0x080c,
-	0x5dbe, 0x00fe, 0x0005, 0x00f6, 0x708c, 0x9005, 0x01e0, 0x2011,
-	0x5d94, 0x080c, 0x82da, 0x9086, 0x0084, 0x1198, 0x080c, 0x5f05,
-	0x2079, 0x0260, 0x7a30, 0x9296, 0x1107, 0x1158, 0x7834, 0x9005,
-	0x1140, 0x7093, 0x0001, 0x080c, 0x5e5b, 0x7097, 0x001a, 0x0029,
-	0x0010, 0x708f, 0x0000, 0x00fe, 0x0005, 0x9085, 0x0001, 0x080c,
-	0x5f30, 0x7097, 0x001b, 0x080c, 0x9eeb, 0x080c, 0x5f05, 0x2011,
-	0x0260, 0x2009, 0x0240, 0x748c, 0x9480, 0x0018, 0x9080, 0x0007,
-	0x9084, 0x03f8, 0x8004, 0x20a8, 0x220e, 0x8210, 0x8108, 0x9186,
-	0x0260, 0x1150, 0x6810, 0x8000, 0x6812, 0x2009, 0x0240, 0x6814,
-	0x8000, 0x6816, 0x2011, 0x0260, 0x1f04, 0x5c9c, 0x60c3, 0x0084,
-	0x080c, 0x5dbe, 0x0005, 0x0005, 0x0086, 0x0096, 0x2029, 0x185c,
-	0x252c, 0x20a9, 0x0008, 0x2041, 0x1c0e, 0x20e9, 0x0001, 0x28a0,
-	0x080c, 0x5f05, 0x20e1, 0x0000, 0x2099, 0x026e, 0x4003, 0x20a9,
-	0x0008, 0x2011, 0x0007, 0xd5d4, 0x0108, 0x9016, 0x2800, 0x9200,
-	0x200c, 0x91a6, 0xffff, 0x1148, 0xd5d4, 0x0110, 0x8210, 0x0008,
-	0x8211, 0x1f04, 0x5cce, 0x0804, 0x5d3d, 0x82ff, 0x1160, 0xd5d4,
-	0x0120, 0x91a6, 0x3fff, 0x0d90, 0x0020, 0x91a6, 0x3fff, 0x0904,
-	0x5d3d, 0x918d, 0xc000, 0x20a9, 0x0010, 0x2019, 0x0001, 0xd5d4,
-	0x0110, 0x2019, 0x0010, 0x2120, 0xd5d4, 0x0110, 0x8423, 0x0008,
-	0x8424, 0x1240, 0xd5d4, 0x0110, 0x8319, 0x0008, 0x8318, 0x1f04,
-	0x5cf4, 0x04d8, 0x23a8, 0x2021, 0x0001, 0x8426, 0x8425, 0x1f04,
-	0x5d06, 0x2328, 0x8529, 0x92be, 0x0007, 0x0158, 0x0006, 0x2039,
-	0x0007, 0x2200, 0x973a, 0x000e, 0x27a8, 0x95a8, 0x0010, 0x1f04,
-	0x5d15, 0x755a, 0x95c8, 0x32e9, 0x292d, 0x95ac, 0x00ff, 0x757e,
-	0x6532, 0x6536, 0x0016, 0x2508, 0x080c, 0x27b7, 0x001e, 0x60e7,
-	0x0000, 0x65ea, 0x2018, 0x2304, 0x9405, 0x201a, 0x7083, 0x0001,
-	0x20e9, 0x0000, 0x20a1, 0x024e, 0x20e1, 0x0001, 0x2898, 0x20a9,
-	0x0008, 0x4003, 0x9085, 0x0001, 0x0008, 0x9006, 0x009e, 0x008e,
-	0x0005, 0x0156, 0x01c6, 0x01d6, 0x0136, 0x0146, 0x22a8, 0x20e1,
-	0x0000, 0x2099, 0x026e, 0x20e9, 0x0000, 0x2011, 0x024e, 0x22a0,
-	0x4003, 0x014e, 0x013e, 0x01de, 0x01ce, 0x015e, 0x2118, 0x9026,
-	0x2001, 0x0007, 0x939a, 0x0010, 0x0218, 0x8420, 0x8001, 0x0cd0,
-	0x2118, 0x84ff, 0x0120, 0x939a, 0x0010, 0x8421, 0x1de0, 0x2021,
-	0x0001, 0x83ff, 0x0118, 0x8423, 0x8319, 0x1de8, 0x9238, 0x2029,
-	0x026e, 0x9528, 0x2504, 0x942c, 0x11b8, 0x9405, 0x203a, 0x715a,
-	0x91a0, 0x32e9, 0x242d, 0x95ac, 0x00ff, 0x757e, 0x6532, 0x6536,
-	0x0016, 0x2508, 0x080c, 0x27b7, 0x001e, 0x60e7, 0x0000, 0x65ea,
-	0x7083, 0x0001, 0x9084, 0x0000, 0x0005, 0x00e6, 0x2071, 0x1800,
-	0x7087, 0x0000, 0x00ee, 0x0005, 0x00e6, 0x00f6, 0x2079, 0x0100,
-	0x2071, 0x0140, 0x080c, 0x5e4a, 0x080c, 0x9656, 0x7004, 0x9084,
-	0x4000, 0x0110, 0x080c, 0x2c98, 0x0126, 0x2091, 0x8000, 0x2071,
-	0x1825, 0x2073, 0x0000, 0x7840, 0x0026, 0x0016, 0x2009, 0x00f7,
-	0x080c, 0x5ea7, 0x001e, 0x9094, 0x0010, 0x9285, 0x0080, 0x7842,
-	0x7a42, 0x002e, 0x012e, 0x00fe, 0x00ee, 0x0005, 0x0126, 0x2091,
-	0x8000, 0x080c, 0x2afe, 0x0228, 0x2011, 0x0101, 0x2204, 0xc0c5,
-	0x2012, 0x2011, 0x19c9, 0x2013, 0x0000, 0x708f, 0x0000, 0x012e,
-	0x60a3, 0x0056, 0x60a7, 0x9575, 0x080c, 0x964d, 0x6144, 0xd184,
-	0x0120, 0x7194, 0x918d, 0x2000, 0x0018, 0x7188, 0x918d, 0x1000,
-	0x2011, 0x1971, 0x2112, 0x2009, 0x07d0, 0x2011, 0x5d94, 0x080c,
-	0x836c, 0x0005, 0x0016, 0x0026, 0x00c6, 0x0126, 0x2091, 0x8000,
-	0x080c, 0xa069, 0x2009, 0x00f7, 0x080c, 0x5ea7, 0x2061, 0x19d2,
-	0x900e, 0x611a, 0x611e, 0x6172, 0x6176, 0x2061, 0x1800, 0x6003,
-	0x0001, 0x2061, 0x0100, 0x6043, 0x0090, 0x6043, 0x0010, 0x2009,
-	0x1971, 0x200b, 0x0000, 0x2009, 0x002d, 0x2011, 0x5e16, 0x080c,
-	0x82ce, 0x012e, 0x00ce, 0x002e, 0x001e, 0x0005, 0x00e6, 0x0006,
-	0x0126, 0x2091, 0x8000, 0x0471, 0x2071, 0x0100, 0x080c, 0x9656,
-	0x2071, 0x0140, 0x7004, 0x9084, 0x4000, 0x0110, 0x080c, 0x2c98,
-	0x080c, 0x720f, 0x0188, 0x080c, 0x722a, 0x1170, 0x080c, 0x750e,
-	0x0016, 0x080c, 0x2886, 0x2001, 0x1945, 0x2102, 0x001e, 0x080c,
-	0x7509, 0x080c, 0x7127, 0x0050, 0x2009, 0x0001, 0x080c, 0x2bb6,
-	0x2001, 0x0001, 0x080c, 0x2717, 0x080c, 0x5dea, 0x012e, 0x000e,
-	0x00ee, 0x0005, 0x2001, 0x180e, 0x2004, 0xd0bc, 0x0158, 0x0026,
-	0x0036, 0x2011, 0x8017, 0x2001, 0x1971, 0x201c, 0x080c, 0x4b1f,
-	0x003e, 0x002e, 0x0005, 0x20a9, 0x0012, 0x20e9, 0x0001, 0x20a1,
-	0x1c80, 0x080c, 0x5f05, 0x20e9, 0x0000, 0x2099, 0x026e, 0x0099,
-	0x20a9, 0x0020, 0x080c, 0x5eff, 0x2099, 0x0260, 0x20a1, 0x1c92,
-	0x0051, 0x20a9, 0x000e, 0x080c, 0x5f02, 0x2099, 0x0260, 0x20a1,
-	0x1cb2, 0x0009, 0x0005, 0x0016, 0x0026, 0x3410, 0x3308, 0x2104,
-	0x8007, 0x2012, 0x8108, 0x8210, 0x1f04, 0x5e7f, 0x002e, 0x001e,
-	0x0005, 0x080c, 0x9eeb, 0x20e1, 0x0001, 0x2099, 0x1c00, 0x20e9,
-	0x0000, 0x20a1, 0x0240, 0x20a9, 0x000c, 0x4003, 0x0005, 0x080c,
-	0x9eeb, 0x080c, 0x5f05, 0x20e1, 0x0000, 0x2099, 0x0260, 0x20e9,
-	0x0000, 0x20a1, 0x0240, 0x20a9, 0x000c, 0x4003, 0x0005, 0x00c6,
-	0x0006, 0x2061, 0x0100, 0x810f, 0x2001, 0x1833, 0x2004, 0x9005,
-	0x1138, 0x2001, 0x1817, 0x2004, 0x9084, 0x00ff, 0x9105, 0x0010,
-	0x9185, 0x00f7, 0x604a, 0x000e, 0x00ce, 0x0005, 0x0016, 0x0046,
-	0x080c, 0x67bf, 0x0158, 0x9006, 0x2020, 0x2009, 0x002a, 0x080c,
-	0xd885, 0x2001, 0x180c, 0x200c, 0xc195, 0x2102, 0x2019, 0x002a,
-	0x900e, 0x080c, 0x3156, 0x080c, 0xc539, 0x0140, 0x0036, 0x2019,
-	0xffff, 0x2021, 0x0007, 0x080c, 0x4cbc, 0x003e, 0x004e, 0x001e,
-	0x0005, 0x080c, 0x5dea, 0x7097, 0x0000, 0x708f, 0x0000, 0x0005,
-	0x0006, 0x2001, 0x180c, 0x2004, 0xd09c, 0x0100, 0x000e, 0x0005,
-	0x0006, 0x0016, 0x0126, 0x2091, 0x8000, 0x2001, 0x0101, 0x200c,
-	0x918d, 0x0006, 0x2102, 0x012e, 0x001e, 0x000e, 0x0005, 0x2009,
-	0x0001, 0x0020, 0x2009, 0x0002, 0x0008, 0x900e, 0x6814, 0x9084,
-	0xffc0, 0x910d, 0x6916, 0x0005, 0x00f6, 0x0156, 0x0146, 0x01d6,
-	0x9006, 0x20a9, 0x0080, 0x20e9, 0x0001, 0x20a1, 0x1c00, 0x4004,
-	0x2079, 0x1c00, 0x7803, 0x2200, 0x7807, 0x00ef, 0x780f, 0x00ef,
-	0x7813, 0x0138, 0x7823, 0xffff, 0x7827, 0xffff, 0x01de, 0x014e,
-	0x015e, 0x00fe, 0x0005, 0x2001, 0x1800, 0x2003, 0x0001, 0x0005,
-	0x2001, 0x197e, 0x0118, 0x2003, 0x0001, 0x0010, 0x2003, 0x0000,
-	0x0005, 0x0156, 0x20a9, 0x0800, 0x2009, 0x1000, 0x9006, 0x200a,
-	0x8108, 0x1f04, 0x5f3f, 0x015e, 0x0005, 0x00d6, 0x0036, 0x0156,
-	0x0136, 0x0146, 0x2069, 0x185b, 0x9006, 0xb802, 0xb8be, 0xb807,
-	0x0707, 0xb80a, 0xb80e, 0xb812, 0x9198, 0x32e9, 0x231d, 0x939c,
-	0x00ff, 0xbb16, 0x0016, 0x0026, 0xb8b2, 0x080c, 0xa062, 0x1120,
-	0x9192, 0x007e, 0x1208, 0xbbb2, 0x20a9, 0x0004, 0xb8b4, 0x20e8,
-	0xb9b8, 0x9198, 0x0006, 0x9006, 0x23a0, 0x4004, 0x20a9, 0x0004,
-	0x9198, 0x000a, 0x23a0, 0x4004, 0x002e, 0x001e, 0xb83e, 0xb842,
-	0xb84e, 0xb852, 0xb856, 0xb85a, 0xb85e, 0xb862, 0xb866, 0xb86a,
-	0xb86f, 0x0100, 0xb872, 0xb876, 0xb87a, 0xb88a, 0xb88e, 0xb893,
-	0x0008, 0xb896, 0xb89a, 0xb89e, 0xb8ae, 0xb9a2, 0x0096, 0xb8a4,
-	0x904d, 0x0110, 0x080c, 0x1063, 0xb8a7, 0x0000, 0x009e, 0x9006,
-	0xb84a, 0x6810, 0xb83a, 0x680c, 0xb846, 0x6814, 0x9084, 0x00ff,
-	0xb842, 0x014e, 0x013e, 0x015e, 0x003e, 0x00de, 0x0005, 0x0126,
-	0x2091, 0x8000, 0xa974, 0xae78, 0x9684, 0x3fff, 0x9082, 0x4000,
-	0x1a04, 0x6015, 0x9182, 0x0800, 0x1a04, 0x6019, 0x2001, 0x180c,
-	0x2004, 0x9084, 0x0003, 0x1904, 0x601f, 0x9188, 0x1000, 0x2104,
-	0x905d, 0x0518, 0xb804, 0x9084, 0x00ff, 0x908e, 0x0006, 0x1508,
-	0xb8a4, 0x900d, 0x1904, 0x6031, 0xb850, 0x900d, 0x1148, 0xa802,
-	0x2900, 0xb852, 0xb84e, 0x080c, 0x8696, 0x9006, 0x012e, 0x0005,
-	0x00a6, 0x2150, 0x2900, 0xb002, 0xa803, 0x0000, 0x00ae, 0xb852,
-	0x0c90, 0x2001, 0x0005, 0x900e, 0x04b8, 0x2001, 0x0028, 0x900e,
-	0x0498, 0x9082, 0x0006, 0x1290, 0x080c, 0xa062, 0x1160, 0xb8a0,
-	0x9084, 0xff80, 0x1140, 0xb900, 0xd1fc, 0x0990, 0x2001, 0x0029,
-	0x2009, 0x1000, 0x0408, 0x2001, 0x0028, 0x00a8, 0x2009, 0x180c,
-	0x210c, 0xd18c, 0x0118, 0x2001, 0x0004, 0x0068, 0xd184, 0x0118,
-	0x2001, 0x0004, 0x0040, 0x2001, 0x0029, 0xb900, 0xd1fc, 0x0118,
-	0x2009, 0x1000, 0x0048, 0x900e, 0x0038, 0x2001, 0x0029, 0x900e,
-	0x0018, 0x2001, 0x0029, 0x900e, 0x9005, 0x012e, 0x0005, 0x2001,
-	0x180c, 0x2004, 0xd084, 0x19d0, 0x9188, 0x1000, 0x2104, 0x905d,
-	0x09a8, 0x080c, 0x67c3, 0x1990, 0xb800, 0xd0bc, 0x0978, 0x0804,
-	0x5fc8, 0x080c, 0x663b, 0x0904, 0x5fe1, 0x0804, 0x5fcc, 0x00b6,
-	0x00e6, 0x0126, 0x2091, 0x8000, 0xa974, 0x9182, 0x0800, 0x1a04,
-	0x60b5, 0x9188, 0x1000, 0x2104, 0x905d, 0x0904, 0x608d, 0xb8a0,
-	0x9086, 0x007f, 0x0190, 0xa87c, 0xd0fc, 0x1178, 0x080c, 0x67cb,
-	0x0160, 0xa994, 0x81ff, 0x0130, 0x908e, 0x0004, 0x0130, 0x908e,
-	0x0005, 0x0118, 0x080c, 0x67c3, 0x1598, 0xa87c, 0xd0fc, 0x01e0,
-	0xa894, 0x9005, 0x01c8, 0x2060, 0x0026, 0x2010, 0x080c, 0xbe25,
-	0x002e, 0x1120, 0x2001, 0x0008, 0x0804, 0x60b7, 0x6020, 0x9086,
-	0x000a, 0x0120, 0x2001, 0x0008, 0x0804, 0x60b7, 0x601a, 0x6003,
-	0x0008, 0x2900, 0x6016, 0x0058, 0x080c, 0xa08d, 0x05e8, 0x2b00,
-	0x6012, 0x2900, 0x6016, 0x600b, 0xffff, 0x6023, 0x000a, 0x2009,
-	0x0003, 0x080c, 0xa15d, 0x9006, 0x0458, 0x2001, 0x0028, 0x0438,
-	0x9082, 0x0006, 0x1290, 0x080c, 0xa062, 0x1160, 0xb8a0, 0x9084,
-	0xff80, 0x1140, 0xb900, 0xd1fc, 0x0900, 0x2001, 0x0029, 0x2009,
-	0x1000, 0x00a8, 0x2001, 0x0028, 0x0090, 0x2009, 0x180c, 0x210c,
-	0xd18c, 0x0118, 0x2001, 0x0004, 0x0050, 0xd184, 0x0118, 0x2001,
-	0x0004, 0x0028, 0x2001, 0x0029, 0x0010, 0x2001, 0x0029, 0x9005,
-	0x012e, 0x00ee, 0x00be, 0x0005, 0x2001, 0x002c, 0x0cc0, 0x00f6,
-	0x00b6, 0x0126, 0x2091, 0x8000, 0xa8e0, 0x9005, 0x1550, 0xa8dc,
-	0x9082, 0x0101, 0x1630, 0xa8c8, 0x9005, 0x1518, 0xa8c4, 0x9082,
-	0x0101, 0x12f8, 0xa974, 0x2079, 0x1800, 0x9182, 0x0800, 0x12e8,
-	0x7830, 0x9084, 0x0003, 0x1130, 0xaa98, 0xab94, 0xa878, 0x9084,
-	0x0007, 0x00ea, 0x7930, 0xd18c, 0x0118, 0x2001, 0x0004, 0x0038,
-	0xd184, 0x0118, 0x2001, 0x0004, 0x0010, 0x2001, 0x0029, 0x900e,
-	0x0038, 0x2001, 0x002c, 0x900e, 0x0018, 0x2001, 0x0029, 0x900e,
-	0x9006, 0x0008, 0x9005, 0x012e, 0x00be, 0x00fe, 0x0005, 0x614c,
-	0x6107, 0x611e, 0x614c, 0x614c, 0x614c, 0x614c, 0x614c, 0x2100,
-	0x9082, 0x007e, 0x1278, 0x080c, 0x643f, 0x0148, 0x9046, 0xb810,
-	0x9306, 0x1904, 0x6154, 0xb814, 0x9206, 0x15f0, 0x0028, 0xbb12,
-	0xba16, 0x0010, 0x080c, 0x49d9, 0x0150, 0x04b0, 0x080c, 0x649f,
-	0x1598, 0xb810, 0x9306, 0x1580, 0xb814, 0x9206, 0x1568, 0x080c,
-	0xa08d, 0x0530, 0x2b00, 0x6012, 0x080c, 0xc2b3, 0x2900, 0x6016,
-	0x600b, 0xffff, 0x6023, 0x000a, 0xa878, 0x9086, 0x0001, 0x1170,
-	0x080c, 0x318b, 0x9006, 0x080c, 0x63dc, 0x2001, 0x0002, 0x080c,
-	0x63f0, 0x2001, 0x0200, 0xb86e, 0xb893, 0x0002, 0x2009, 0x0003,
-	0x080c, 0xa15d, 0x9006, 0x0068, 0x2001, 0x0001, 0x900e, 0x0038,
-	0x2001, 0x002c, 0x900e, 0x0018, 0x2001, 0x0028, 0x900e, 0x9005,
-	0x0000, 0x012e, 0x00be, 0x00fe, 0x0005, 0x00b6, 0x00f6, 0x00e6,
-	0x0126, 0x2091, 0x8000, 0xa894, 0x90c6, 0x0015, 0x0904, 0x632d,
-	0x90c6, 0x0056, 0x0904, 0x6331, 0x90c6, 0x0066, 0x0904, 0x6335,
-	0x90c6, 0x0067, 0x0904, 0x6339, 0x90c6, 0x0068, 0x0904, 0x633d,
-	0x90c6, 0x0071, 0x0904, 0x6341, 0x90c6, 0x0074, 0x0904, 0x6345,
-	0x90c6, 0x007c, 0x0904, 0x6349, 0x90c6, 0x007e, 0x0904, 0x634d,
-	0x90c6, 0x0037, 0x0904, 0x6351, 0x9016, 0x2079, 0x1800, 0xa974,
-	0x9186, 0x00ff, 0x0904, 0x6328, 0x9182, 0x0800, 0x1a04, 0x6328,
-	0x080c, 0x649f, 0x1198, 0xb804, 0x9084, 0x00ff, 0x9082, 0x0006,
-	0x1268, 0xa894, 0x90c6, 0x006f, 0x0148, 0x080c, 0xa062, 0x1904,
-	0x6311, 0xb8a0, 0x9084, 0xff80, 0x1904, 0x6311, 0xa894, 0x90c6,
-	0x006f, 0x0158, 0x90c6, 0x005e, 0x0904, 0x6271, 0x90c6, 0x0064,
-	0x0904, 0x629a, 0x2008, 0x0804, 0x6234, 0xa998, 0xa8b0, 0x2040,
-	0x080c, 0xa062, 0x1120, 0x9182, 0x007f, 0x0a04, 0x6234, 0x9186,
-	0x00ff, 0x0904, 0x6234, 0x9182, 0x0800, 0x1a04, 0x6234, 0xaaa0,
-	0xab9c, 0x7878, 0x9306, 0x11a8, 0x787c, 0x0096, 0x924e, 0x1128,
-	0x2208, 0x2310, 0x009e, 0x0804, 0x6234, 0x080c, 0xa062, 0x1140,
-	0x99cc, 0xff00, 0x009e, 0x1128, 0x2208, 0x2310, 0x0804, 0x6234,
-	0x009e, 0x080c, 0x49d9, 0x0904, 0x623d, 0x900e, 0x9016, 0x90c6,
-	0x4000, 0x1558, 0x0006, 0x080c, 0x66bf, 0x1108, 0xc185, 0xb800,
-	0xd0bc, 0x0108, 0xc18d, 0x20a9, 0x0004, 0xa860, 0x20e8, 0xa85c,
-	0x9080, 0x0031, 0x20a0, 0xb8b4, 0x20e0, 0xb8b8, 0x9080, 0x0006,
-	0x2098, 0x080c, 0x0fae, 0x20a9, 0x0004, 0xa860, 0x20e8, 0xa85c,
-	0x9080, 0x0035, 0x20a0, 0xb8b4, 0x20e0, 0xb8b8, 0x9080, 0x000a,
-	0x2098, 0x080c, 0x0fae, 0x000e, 0x00c8, 0x90c6, 0x4007, 0x1110,
-	0x2408, 0x00a0, 0x90c6, 0x4008, 0x1118, 0x2708, 0x2610, 0x0070,
-	0x90c6, 0x4009, 0x1108, 0x0050, 0x90c6, 0x4006, 0x0138, 0x2001,
-	0x4005, 0x2009, 0x000a, 0x0010, 0x2001, 0x4006, 0xa896, 0xa99a,
-	0xaa9e, 0x2001, 0x0030, 0x900e, 0x0470, 0x080c, 0xa08d, 0x1130,
-	0x2001, 0x4005, 0x2009, 0x0003, 0x9016, 0x0c80, 0x2b00, 0x6012,
-	0x080c, 0xc2b3, 0x2900, 0x6016, 0x6023, 0x0001, 0xa868, 0xd88c,
-	0x0108, 0xc0f5, 0xa86a, 0x0126, 0x2091, 0x8000, 0x080c, 0x318b,
-	0x012e, 0x9006, 0x080c, 0x63dc, 0x2001, 0x0002, 0x080c, 0x63f0,
-	0x2009, 0x0002, 0x080c, 0xa15d, 0xa8b0, 0xd094, 0x0118, 0xb8bc,
-	0xc08d, 0xb8be, 0x9006, 0x9005, 0x012e, 0x00ee, 0x00fe, 0x00be,
-	0x0005, 0x080c, 0x55ef, 0x0118, 0x2009, 0x0007, 0x00f8, 0xa998,
-	0xaeb0, 0x080c, 0x649f, 0x1904, 0x622f, 0x9186, 0x007f, 0x0130,
-	0x080c, 0x67c3, 0x0118, 0x2009, 0x0009, 0x0080, 0x0096, 0x080c,
-	0x1031, 0x1120, 0x009e, 0x2009, 0x0002, 0x0040, 0x2900, 0x009e,
-	0xa806, 0x080c, 0xc01f, 0x19b0, 0x2009, 0x0003, 0x2001, 0x4005,
-	0x0804, 0x6236, 0xa998, 0xaeb0, 0x080c, 0x649f, 0x1904, 0x622f,
-	0x0096, 0x080c, 0x1031, 0x1128, 0x009e, 0x2009, 0x0002, 0x0804,
-	0x62ee, 0x2900, 0x009e, 0xa806, 0x0096, 0x2048, 0x20a9, 0x002b,
-	0xb8b4, 0x20e0, 0xb8b8, 0x2098, 0xa860, 0x20e8, 0xa85c, 0x9080,
-	0x0002, 0x20a0, 0x4003, 0x20a9, 0x0008, 0x9080, 0x0006, 0x20a0,
-	0xbbb8, 0x9398, 0x0006, 0x2398, 0x080c, 0x0fae, 0x009e, 0xa87b,
-	0x0000, 0xa883, 0x0000, 0xa897, 0x4000, 0xd684, 0x1168, 0x080c,
-	0x55db, 0xd0b4, 0x1118, 0xa89b, 0x000b, 0x00e0, 0xb800, 0xd08c,
-	0x0118, 0xa89b, 0x000c, 0x00b0, 0x080c, 0x67c3, 0x0118, 0xa89b,
-	0x0009, 0x0080, 0x080c, 0x55ef, 0x0118, 0xa89b, 0x0007, 0x0050,
-	0x080c, 0xc002, 0x1904, 0x626a, 0x2009, 0x0003, 0x2001, 0x4005,
-	0x0804, 0x6236, 0xa87b, 0x0030, 0xa897, 0x4005, 0xa804, 0x8006,
-	0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x0002,
-	0x2009, 0x002b, 0xaaa0, 0xab9c, 0xaca8, 0xada4, 0x2031, 0x0000,
-	0x2041, 0x1288, 0x080c, 0xa5e6, 0x1904, 0x626a, 0x2009, 0x0002,
-	0x08e8, 0x2001, 0x0028, 0x900e, 0x0804, 0x626b, 0x2009, 0x180c,
-	0x210c, 0xd18c, 0x0118, 0x2001, 0x0004, 0x0038, 0xd184, 0x0118,
-	0x2001, 0x0004, 0x0010, 0x2001, 0x0029, 0x900e, 0x0804, 0x626b,
-	0x2001, 0x0029, 0x900e, 0x0804, 0x626b, 0x080c, 0x3718, 0x0804,
-	0x626c, 0x080c, 0x5306, 0x0804, 0x626c, 0x080c, 0x455e, 0x0804,
-	0x626c, 0x080c, 0x45d7, 0x0804, 0x626c, 0x080c, 0x4633, 0x0804,
-	0x626c, 0x080c, 0x4a95, 0x0804, 0x626c, 0x080c, 0x4d3e, 0x0804,
-	0x626c, 0x080c, 0x4f6e, 0x0804, 0x626c, 0x080c, 0x5167, 0x0804,
-	0x626c, 0x080c, 0x3941, 0x0804, 0x626c, 0x00b6, 0xa974, 0xae78,
-	0x9684, 0x3fff, 0x9082, 0x4000, 0x1618, 0x9182, 0x0800, 0x1268,
-	0x9188, 0x1000, 0x2104, 0x905d, 0x0140, 0x080c, 0x67c3, 0x1148,
-	0x00e9, 0x080c, 0x65ca, 0x9006, 0x00b0, 0x2001, 0x0028, 0x900e,
-	0x0090, 0x9082, 0x0006, 0x1240, 0xb900, 0xd1fc, 0x0d88, 0x2001,
-	0x0029, 0x2009, 0x1000, 0x0038, 0x2001, 0x0029, 0x900e, 0x0018,
-	0x2001, 0x0029, 0x900e, 0x9005, 0x00be, 0x0005, 0x0126, 0x2091,
-	0x8000, 0xb850, 0x900d, 0x0150, 0x2900, 0x0096, 0x2148, 0xa802,
-	0x009e, 0xa803, 0x0000, 0xb852, 0x012e, 0x0005, 0x2900, 0xb852,
-	0xb84e, 0xa803, 0x0000, 0x0cc0, 0x0126, 0x2091, 0x8000, 0xb84c,
-	0x9005, 0x0170, 0x00e6, 0x2071, 0x19bf, 0x7004, 0x9086, 0x0002,
-	0x0168, 0x00ee, 0xb84c, 0xa802, 0x2900, 0xb84e, 0x012e, 0x0005,
-	0x2900, 0xb852, 0xb84e, 0xa803, 0x0000, 0x0cc0, 0x701c, 0x9b06,
-	0x1d80, 0xb84c, 0x00a6, 0x2050, 0xb000, 0xa802, 0x2900, 0xb002,
-	0x00ae, 0x00ee, 0x012e, 0x0005, 0x0126, 0x2091, 0x8000, 0xb84c,
+	0x4003, 0x60c3, 0x0014, 0x080c, 0x5cc3, 0x00fe, 0x0005, 0x00f6,
+	0x708c, 0x9005, 0x0500, 0x2011, 0x5c99, 0x080c, 0x825a, 0x9086,
+	0x0014, 0x11b8, 0x080c, 0x5e0a, 0x2079, 0x0260, 0x7a30, 0x9296,
+	0x1104, 0x1178, 0x7834, 0x9005, 0x1160, 0x7a38, 0xd2fc, 0x0128,
+	0x70c0, 0x9005, 0x1110, 0x70c3, 0x0001, 0x7097, 0x0014, 0x0029,
+	0x0010, 0x708f, 0x0000, 0x00fe, 0x0005, 0x00f6, 0x7097, 0x0015,
+	0x080c, 0x5d9c, 0x2079, 0x0240, 0x7833, 0x1104, 0x7837, 0x0000,
+	0x080c, 0x5e0a, 0x080c, 0x5ded, 0x11b8, 0x7080, 0x9005, 0x11a0,
+	0x7160, 0x9186, 0xffff, 0x0180, 0x9180, 0x3209, 0x200d, 0x918c,
+	0xff00, 0x810f, 0x2011, 0x0008, 0x080c, 0x5c46, 0x0180, 0x080c,
+	0x4dd8, 0x0110, 0x080c, 0x26d7, 0x20a9, 0x0008, 0x20e1, 0x0000,
+	0x2099, 0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003, 0x60c3,
+	0x0014, 0x080c, 0x5cc3, 0x00fe, 0x0005, 0x00f6, 0x708c, 0x9005,
+	0x05f0, 0x2011, 0x5c99, 0x080c, 0x825a, 0x9086, 0x0014, 0x15a8,
+	0x080c, 0x5e0a, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1105, 0x1568,
+	0x7834, 0x9084, 0x0100, 0x2011, 0x0100, 0x921e, 0x1168, 0x9085,
+	0x0001, 0x080c, 0x5e35, 0x7a38, 0xd2fc, 0x0128, 0x70c0, 0x9005,
+	0x1110, 0x70c3, 0x0001, 0x0080, 0x9005, 0x11b8, 0x7a38, 0xd2fc,
+	0x0128, 0x70c0, 0x9005, 0x1110, 0x70c3, 0x0001, 0x9085, 0x0001,
+	0x080c, 0x5e35, 0x7093, 0x0000, 0x7a38, 0xd2f4, 0x0110, 0x70db,
+	0x0008, 0x7097, 0x0016, 0x0029, 0x0010, 0x708f, 0x0000, 0x00fe,
+	0x0005, 0x080c, 0x9ddd, 0x080c, 0x5e0a, 0x20e1, 0x0000, 0x2099,
+	0x0260, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, 0x000e, 0x4003,
+	0x2011, 0x026d, 0x2204, 0x9084, 0x0100, 0x2011, 0x024d, 0x2012,
+	0x2011, 0x026e, 0x7097, 0x0017, 0x080c, 0x5ded, 0x1150, 0x7080,
+	0x9005, 0x1138, 0x080c, 0x5bb9, 0x1188, 0x9085, 0x0001, 0x080c,
+	0x26d7, 0x20a9, 0x0008, 0x080c, 0x5e0a, 0x20e1, 0x0000, 0x2099,
+	0x026e, 0x20e9, 0x0000, 0x20a1, 0x024e, 0x4003, 0x60c3, 0x0014,
+	0x080c, 0x5cc3, 0x0010, 0x080c, 0x5713, 0x0005, 0x00f6, 0x708c,
+	0x9005, 0x01d8, 0x2011, 0x5c99, 0x080c, 0x825a, 0x9086, 0x0084,
+	0x1190, 0x080c, 0x5e0a, 0x2079, 0x0260, 0x7a30, 0x9296, 0x1106,
+	0x1150, 0x7834, 0x9005, 0x1138, 0x9006, 0x080c, 0x5e35, 0x7097,
+	0x0018, 0x0029, 0x0010, 0x708f, 0x0000, 0x00fe, 0x0005, 0x00f6,
+	0x7097, 0x0019, 0x080c, 0x5d9c, 0x2079, 0x0240, 0x7833, 0x1106,
+	0x7837, 0x0000, 0x080c, 0x5e0a, 0x2009, 0x026e, 0x2039, 0x1c0e,
+	0x20a9, 0x0040, 0x213e, 0x8738, 0x8108, 0x9186, 0x0280, 0x1128,
+	0x6814, 0x8000, 0x6816, 0x2009, 0x0260, 0x1f04, 0x5b22, 0x2039,
+	0x1c0e, 0x080c, 0x5ded, 0x11e8, 0x2728, 0x2514, 0x8207, 0x9084,
+	0x00ff, 0x8000, 0x2018, 0x9294, 0x00ff, 0x8007, 0x9205, 0x202a,
+	0x705c, 0x2310, 0x8214, 0x92a0, 0x1c0e, 0x2414, 0x938c, 0x0001,
+	0x0118, 0x9294, 0xff00, 0x0018, 0x9294, 0x00ff, 0x8007, 0x9215,
+	0x2222, 0x20a9, 0x0040, 0x2009, 0x024e, 0x270e, 0x8738, 0x8108,
+	0x9186, 0x0260, 0x1128, 0x6810, 0x8000, 0x6812, 0x2009, 0x0240,
+	0x1f04, 0x5b55, 0x60c3, 0x0084, 0x080c, 0x5cc3, 0x00fe, 0x0005,
+	0x00f6, 0x708c, 0x9005, 0x01e0, 0x2011, 0x5c99, 0x080c, 0x825a,
+	0x9086, 0x0084, 0x1198, 0x080c, 0x5e0a, 0x2079, 0x0260, 0x7a30,
+	0x9296, 0x1107, 0x1158, 0x7834, 0x9005, 0x1140, 0x7093, 0x0001,
+	0x080c, 0x5d60, 0x7097, 0x001a, 0x0029, 0x0010, 0x708f, 0x0000,
+	0x00fe, 0x0005, 0x9085, 0x0001, 0x080c, 0x5e35, 0x7097, 0x001b,
+	0x080c, 0x9ddd, 0x080c, 0x5e0a, 0x2011, 0x0260, 0x2009, 0x0240,
+	0x748c, 0x9480, 0x0018, 0x9080, 0x0007, 0x9084, 0x03f8, 0x8004,
+	0x20a8, 0x220e, 0x8210, 0x8108, 0x9186, 0x0260, 0x1150, 0x6810,
+	0x8000, 0x6812, 0x2009, 0x0240, 0x6814, 0x8000, 0x6816, 0x2011,
+	0x0260, 0x1f04, 0x5ba1, 0x60c3, 0x0084, 0x080c, 0x5cc3, 0x0005,
+	0x0005, 0x0086, 0x0096, 0x2029, 0x185c, 0x252c, 0x20a9, 0x0008,
+	0x2041, 0x1c0e, 0x20e9, 0x0001, 0x28a0, 0x080c, 0x5e0a, 0x20e1,
+	0x0000, 0x2099, 0x026e, 0x4003, 0x20a9, 0x0008, 0x2011, 0x0007,
+	0xd5d4, 0x0108, 0x9016, 0x2800, 0x9200, 0x200c, 0x91a6, 0xffff,
+	0x1148, 0xd5d4, 0x0110, 0x8210, 0x0008, 0x8211, 0x1f04, 0x5bd3,
+	0x0804, 0x5c42, 0x82ff, 0x1160, 0xd5d4, 0x0120, 0x91a6, 0x3fff,
+	0x0d90, 0x0020, 0x91a6, 0x3fff, 0x0904, 0x5c42, 0x918d, 0xc000,
+	0x20a9, 0x0010, 0x2019, 0x0001, 0xd5d4, 0x0110, 0x2019, 0x0010,
+	0x2120, 0xd5d4, 0x0110, 0x8423, 0x0008, 0x8424, 0x1240, 0xd5d4,
+	0x0110, 0x8319, 0x0008, 0x8318, 0x1f04, 0x5bf9, 0x04d8, 0x23a8,
+	0x2021, 0x0001, 0x8426, 0x8425, 0x1f04, 0x5c0b, 0x2328, 0x8529,
+	0x92be, 0x0007, 0x0158, 0x0006, 0x2039, 0x0007, 0x2200, 0x973a,
+	0x000e, 0x27a8, 0x95a8, 0x0010, 0x1f04, 0x5c1a, 0x755a, 0x95c8,
+	0x3209, 0x292d, 0x95ac, 0x00ff, 0x757e, 0x6532, 0x6536, 0x0016,
+	0x2508, 0x080c, 0x26b7, 0x001e, 0x60e7, 0x0000, 0x65ea, 0x2018,
+	0x2304, 0x9405, 0x201a, 0x7083, 0x0001, 0x20e9, 0x0000, 0x20a1,
+	0x024e, 0x20e1, 0x0001, 0x2898, 0x20a9, 0x0008, 0x4003, 0x9085,
+	0x0001, 0x0008, 0x9006, 0x009e, 0x008e, 0x0005, 0x0156, 0x01c6,
+	0x01d6, 0x0136, 0x0146, 0x22a8, 0x20e1, 0x0000, 0x2099, 0x026e,
+	0x20e9, 0x0000, 0x2011, 0x024e, 0x22a0, 0x4003, 0x014e, 0x013e,
+	0x01de, 0x01ce, 0x015e, 0x2118, 0x9026, 0x2001, 0x0007, 0x939a,
+	0x0010, 0x0218, 0x8420, 0x8001, 0x0cd0, 0x2118, 0x84ff, 0x0120,
+	0x939a, 0x0010, 0x8421, 0x1de0, 0x2021, 0x0001, 0x83ff, 0x0118,
+	0x8423, 0x8319, 0x1de8, 0x9238, 0x2029, 0x026e, 0x9528, 0x2504,
+	0x942c, 0x11b8, 0x9405, 0x203a, 0x715a, 0x91a0, 0x3209, 0x242d,
+	0x95ac, 0x00ff, 0x757e, 0x6532, 0x6536, 0x0016, 0x2508, 0x080c,
+	0x26b7, 0x001e, 0x60e7, 0x0000, 0x65ea, 0x7083, 0x0001, 0x9084,
+	0x0000, 0x0005, 0x00e6, 0x2071, 0x1800, 0x7087, 0x0000, 0x00ee,
+	0x0005, 0x00e6, 0x00f6, 0x2079, 0x0100, 0x2071, 0x0140, 0x080c,
+	0x5d4f, 0x080c, 0x9605, 0x7004, 0x9084, 0x4000, 0x0110, 0x080c,
+	0x2b98, 0x0126, 0x2091, 0x8000, 0x2071, 0x1825, 0x2073, 0x0000,
+	0x7840, 0x0026, 0x0016, 0x2009, 0x00f7, 0x080c, 0x5dac, 0x001e,
+	0x9094, 0x0010, 0x9285, 0x0080, 0x7842, 0x7a42, 0x002e, 0x012e,
+	0x00fe, 0x00ee, 0x0005, 0x0126, 0x2091, 0x8000, 0x080c, 0x29fe,
+	0x0228, 0x2011, 0x0101, 0x2204, 0xc0c5, 0x2012, 0x2011, 0x19cc,
+	0x2013, 0x0000, 0x708f, 0x0000, 0x012e, 0x60a3, 0x0056, 0x60a7,
+	0x9575, 0x080c, 0x95fc, 0x6144, 0xd184, 0x0120, 0x7194, 0x918d,
+	0x2000, 0x0018, 0x7188, 0x918d, 0x1000, 0x2011, 0x1973, 0x2112,
+	0x2009, 0x07d0, 0x2011, 0x5c99, 0x080c, 0x82ec, 0x0005, 0x0016,
+	0x0026, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0x9f5b, 0x2009,
+	0x00f7, 0x080c, 0x5dac, 0x2061, 0x19d5, 0x900e, 0x611a, 0x611e,
+	0x617a, 0x617e, 0x2061, 0x1800, 0x6003, 0x0001, 0x2061, 0x0100,
+	0x6043, 0x0090, 0x6043, 0x0010, 0x2009, 0x1973, 0x200b, 0x0000,
+	0x2009, 0x002d, 0x2011, 0x5d1b, 0x080c, 0x824e, 0x012e, 0x00ce,
+	0x002e, 0x001e, 0x0005, 0x00e6, 0x0006, 0x0126, 0x2091, 0x8000,
+	0x0471, 0x2071, 0x0100, 0x080c, 0x9605, 0x2071, 0x0140, 0x7004,
+	0x9084, 0x4000, 0x0110, 0x080c, 0x2b98, 0x080c, 0x7187, 0x0188,
+	0x080c, 0x71a2, 0x1170, 0x080c, 0x7485, 0x0016, 0x080c, 0x2786,
+	0x2001, 0x1947, 0x2102, 0x001e, 0x080c, 0x7480, 0x080c, 0x709f,
+	0x0050, 0x2009, 0x0001, 0x080c, 0x2ab6, 0x2001, 0x0001, 0x080c,
+	0x2617, 0x080c, 0x5cef, 0x012e, 0x000e, 0x00ee, 0x0005, 0x2001,
+	0x180e, 0x2004, 0xd0bc, 0x0158, 0x0026, 0x0036, 0x2011, 0x8017,
+	0x2001, 0x1973, 0x201c, 0x080c, 0x4a18, 0x003e, 0x002e, 0x0005,
+	0x20a9, 0x0012, 0x20e9, 0x0001, 0x20a1, 0x1c80, 0x080c, 0x5e0a,
+	0x20e9, 0x0000, 0x2099, 0x026e, 0x0099, 0x20a9, 0x0020, 0x080c,
+	0x5e04, 0x2099, 0x0260, 0x20a1, 0x1c92, 0x0051, 0x20a9, 0x000e,
+	0x080c, 0x5e07, 0x2099, 0x0260, 0x20a1, 0x1cb2, 0x0009, 0x0005,
+	0x0016, 0x0026, 0x3410, 0x3308, 0x2104, 0x8007, 0x2012, 0x8108,
+	0x8210, 0x1f04, 0x5d84, 0x002e, 0x001e, 0x0005, 0x080c, 0x9ddd,
+	0x20e1, 0x0001, 0x2099, 0x1c00, 0x20e9, 0x0000, 0x20a1, 0x0240,
+	0x20a9, 0x000c, 0x4003, 0x0005, 0x080c, 0x9ddd, 0x080c, 0x5e0a,
+	0x20e1, 0x0000, 0x2099, 0x0260, 0x20e9, 0x0000, 0x20a1, 0x0240,
+	0x20a9, 0x000c, 0x4003, 0x0005, 0x00c6, 0x0006, 0x2061, 0x0100,
+	0x810f, 0x2001, 0x1833, 0x2004, 0x9005, 0x1138, 0x2001, 0x1817,
+	0x2004, 0x9084, 0x00ff, 0x9105, 0x0010, 0x9185, 0x00f7, 0x604a,
+	0x000e, 0x00ce, 0x0005, 0x0016, 0x0046, 0x080c, 0x66c6, 0x0158,
+	0x9006, 0x2020, 0x2009, 0x002a, 0x080c, 0xd7d6, 0x2001, 0x180c,
+	0x200c, 0xc195, 0x2102, 0x2019, 0x002a, 0x900e, 0x080c, 0x3076,
+	0x080c, 0xc444, 0x0140, 0x0036, 0x2019, 0xffff, 0x2021, 0x0007,
+	0x080c, 0x4bb5, 0x003e, 0x004e, 0x001e, 0x0005, 0x080c, 0x5cef,
+	0x7097, 0x0000, 0x708f, 0x0000, 0x0005, 0x0006, 0x2001, 0x180c,
+	0x2004, 0xd09c, 0x0100, 0x000e, 0x0005, 0x0006, 0x0016, 0x0126,
+	0x2091, 0x8000, 0x2001, 0x0101, 0x200c, 0x918d, 0x0006, 0x2102,
+	0x012e, 0x001e, 0x000e, 0x0005, 0x2009, 0x0001, 0x0020, 0x2009,
+	0x0002, 0x0008, 0x900e, 0x6814, 0x9084, 0xffc0, 0x910d, 0x6916,
+	0x0005, 0x00f6, 0x0156, 0x0146, 0x01d6, 0x9006, 0x20a9, 0x0080,
+	0x20e9, 0x0001, 0x20a1, 0x1c00, 0x4004, 0x2079, 0x1c00, 0x7803,
+	0x2200, 0x7807, 0x00ef, 0x780f, 0x00ef, 0x7813, 0x0138, 0x7823,
+	0xffff, 0x7827, 0xffff, 0x01de, 0x014e, 0x015e, 0x00fe, 0x0005,
+	0x2001, 0x1800, 0x2003, 0x0001, 0x0005, 0x2001, 0x1980, 0x0118,
+	0x2003, 0x0001, 0x0010, 0x2003, 0x0000, 0x0005, 0x0156, 0x20a9,
+	0x0800, 0x2009, 0x1000, 0x9006, 0x200a, 0x8108, 0x1f04, 0x5e44,
+	0x015e, 0x0005, 0x00d6, 0x0036, 0x0156, 0x0136, 0x0146, 0x2069,
+	0x185b, 0x9006, 0xb802, 0xb8be, 0xb807, 0x0707, 0xb80a, 0xb80e,
+	0xb812, 0x9198, 0x3209, 0x231d, 0x939c, 0x00ff, 0xbb16, 0x0016,
+	0x0026, 0xb8b2, 0x080c, 0x9f54, 0x1120, 0x9192, 0x007e, 0x1208,
+	0xbbb2, 0x20a9, 0x0004, 0xb8b4, 0x20e8, 0xb9b8, 0x9198, 0x0006,
+	0x9006, 0x23a0, 0x4004, 0x20a9, 0x0004, 0x9198, 0x000a, 0x23a0,
+	0x4004, 0x002e, 0x001e, 0xb83e, 0xb842, 0xb84e, 0xb852, 0xb856,
+	0xb85a, 0xb85e, 0xb862, 0xb866, 0xb86a, 0xb86f, 0x0100, 0xb872,
+	0xb876, 0xb87a, 0xb88a, 0xb88e, 0xb893, 0x0008, 0xb896, 0xb89a,
+	0xb89e, 0xb8ae, 0xb9a2, 0x0096, 0xb8a4, 0x904d, 0x0110, 0x080c,
+	0x1075, 0xb8a7, 0x0000, 0x009e, 0x9006, 0xb84a, 0x6810, 0xb83a,
+	0x680c, 0xb846, 0x6814, 0x9084, 0x00ff, 0xb842, 0x014e, 0x013e,
+	0x015e, 0x003e, 0x00de, 0x0005, 0x0126, 0x2091, 0x8000, 0xa974,
+	0xae78, 0x9684, 0x3fff, 0x9082, 0x4000, 0x1a04, 0x5f1a, 0x9182,
+	0x0800, 0x1a04, 0x5f1e, 0x2001, 0x180c, 0x2004, 0x9084, 0x0003,
+	0x1904, 0x5f24, 0x9188, 0x1000, 0x2104, 0x905d, 0x0518, 0xb804,
+	0x9084, 0x00ff, 0x908e, 0x0006, 0x1508, 0xb8a4, 0x900d, 0x1904,
+	0x5f36, 0xb850, 0x900d, 0x1148, 0xa802, 0x2900, 0xb852, 0xb84e,
+	0x080c, 0x8616, 0x9006, 0x012e, 0x0005, 0x00a6, 0x2150, 0x2900,
+	0xb002, 0xa803, 0x0000, 0x00ae, 0xb852, 0x0c90, 0x2001, 0x0005,
+	0x900e, 0x04b8, 0x2001, 0x0028, 0x900e, 0x0498, 0x9082, 0x0006,
+	0x1290, 0x080c, 0x9f54, 0x1160, 0xb8a0, 0x9084, 0xff80, 0x1140,
+	0xb900, 0xd1fc, 0x0990, 0x2001, 0x0029, 0x2009, 0x1000, 0x0408,
+	0x2001, 0x0028, 0x00a8, 0x2009, 0x180c, 0x210c, 0xd18c, 0x0118,
+	0x2001, 0x0004, 0x0068, 0xd184, 0x0118, 0x2001, 0x0004, 0x0040,
+	0x2001, 0x0029, 0xb900, 0xd1fc, 0x0118, 0x2009, 0x1000, 0x0048,
+	0x900e, 0x0038, 0x2001, 0x0029, 0x900e, 0x0018, 0x2001, 0x0029,
+	0x900e, 0x9005, 0x012e, 0x0005, 0x2001, 0x180c, 0x2004, 0xd084,
+	0x19d0, 0x9188, 0x1000, 0x2104, 0x905d, 0x09a8, 0x080c, 0x66ca,
+	0x1990, 0xb800, 0xd0bc, 0x0978, 0x0804, 0x5ecd, 0x080c, 0x6540,
+	0x0904, 0x5ee6, 0x0804, 0x5ed1, 0x00b6, 0x00e6, 0x0126, 0x2091,
+	0x8000, 0xa974, 0x9182, 0x0800, 0x1a04, 0x5fba, 0x9188, 0x1000,
+	0x2104, 0x905d, 0x0904, 0x5f92, 0xb8a0, 0x9086, 0x007f, 0x0190,
+	0xa87c, 0xd0fc, 0x1178, 0x080c, 0x66d2, 0x0160, 0xa994, 0x81ff,
+	0x0130, 0x908e, 0x0004, 0x0130, 0x908e, 0x0005, 0x0118, 0x080c,
+	0x66ca, 0x1598, 0xa87c, 0xd0fc, 0x01e0, 0xa894, 0x9005, 0x01c8,
+	0x2060, 0x0026, 0x2010, 0x080c, 0xbd29, 0x002e, 0x1120, 0x2001,
+	0x0008, 0x0804, 0x5fbc, 0x6020, 0x9086, 0x000a, 0x0120, 0x2001,
+	0x0008, 0x0804, 0x5fbc, 0x601a, 0x6003, 0x0008, 0x2900, 0x6016,
+	0x0058, 0x080c, 0x9f7f, 0x05e8, 0x2b00, 0x6012, 0x2900, 0x6016,
+	0x600b, 0xffff, 0x6023, 0x000a, 0x2009, 0x0003, 0x080c, 0xa053,
+	0x9006, 0x0458, 0x2001, 0x0028, 0x0438, 0x9082, 0x0006, 0x1290,
+	0x080c, 0x9f54, 0x1160, 0xb8a0, 0x9084, 0xff80, 0x1140, 0xb900,
+	0xd1fc, 0x0900, 0x2001, 0x0029, 0x2009, 0x1000, 0x00a8, 0x2001,
+	0x0028, 0x0090, 0x2009, 0x180c, 0x210c, 0xd18c, 0x0118, 0x2001,
+	0x0004, 0x0050, 0xd184, 0x0118, 0x2001, 0x0004, 0x0028, 0x2001,
+	0x0029, 0x0010, 0x2001, 0x0029, 0x9005, 0x012e, 0x00ee, 0x00be,
+	0x0005, 0x2001, 0x002c, 0x0cc0, 0x00f6, 0x00b6, 0x0126, 0x2091,
+	0x8000, 0xa8e0, 0x9005, 0x1550, 0xa8dc, 0x9082, 0x0101, 0x1630,
+	0xa8c8, 0x9005, 0x1518, 0xa8c4, 0x9082, 0x0101, 0x12f8, 0xa974,
+	0x2079, 0x1800, 0x9182, 0x0800, 0x12e8, 0x7830, 0x9084, 0x0003,
+	0x1130, 0xaa98, 0xab94, 0xa878, 0x9084, 0x0007, 0x00ea, 0x7930,
+	0xd18c, 0x0118, 0x2001, 0x0004, 0x0038, 0xd184, 0x0118, 0x2001,
+	0x0004, 0x0010, 0x2001, 0x0029, 0x900e, 0x0038, 0x2001, 0x002c,
+	0x900e, 0x0018, 0x2001, 0x0029, 0x900e, 0x9006, 0x0008, 0x9005,
+	0x012e, 0x00be, 0x00fe, 0x0005, 0x6051, 0x600c, 0x6023, 0x6051,
+	0x6051, 0x6051, 0x6051, 0x6051, 0x2100, 0x9082, 0x007e, 0x1278,
+	0x080c, 0x6344, 0x0148, 0x9046, 0xb810, 0x9306, 0x1904, 0x6059,
+	0xb814, 0x9206, 0x15f0, 0x0028, 0xbb12, 0xba16, 0x0010, 0x080c,
+	0x48d2, 0x0150, 0x04b0, 0x080c, 0x63a4, 0x1598, 0xb810, 0x9306,
+	0x1580, 0xb814, 0x9206, 0x1568, 0x080c, 0x9f7f, 0x0530, 0x2b00,
+	0x6012, 0x080c, 0xc1b7, 0x2900, 0x6016, 0x600b, 0xffff, 0x6023,
+	0x000a, 0xa878, 0x9086, 0x0001, 0x1170, 0x080c, 0x30ab, 0x9006,
+	0x080c, 0x62e1, 0x2001, 0x0002, 0x080c, 0x62f5, 0x2001, 0x0200,
+	0xb86e, 0xb893, 0x0002, 0x2009, 0x0003, 0x080c, 0xa053, 0x9006,
+	0x0068, 0x2001, 0x0001, 0x900e, 0x0038, 0x2001, 0x002c, 0x900e,
+	0x0018, 0x2001, 0x0028, 0x900e, 0x9005, 0x0000, 0x012e, 0x00be,
+	0x00fe, 0x0005, 0x00b6, 0x00f6, 0x00e6, 0x0126, 0x2091, 0x8000,
+	0xa894, 0x90c6, 0x0015, 0x0904, 0x6232, 0x90c6, 0x0056, 0x0904,
+	0x6236, 0x90c6, 0x0066, 0x0904, 0x623a, 0x90c6, 0x0067, 0x0904,
+	0x623e, 0x90c6, 0x0068, 0x0904, 0x6242, 0x90c6, 0x0071, 0x0904,
+	0x6246, 0x90c6, 0x0074, 0x0904, 0x624a, 0x90c6, 0x007c, 0x0904,
+	0x624e, 0x90c6, 0x007e, 0x0904, 0x6252, 0x90c6, 0x0037, 0x0904,
+	0x6256, 0x9016, 0x2079, 0x1800, 0xa974, 0x9186, 0x00ff, 0x0904,
+	0x622d, 0x9182, 0x0800, 0x1a04, 0x622d, 0x080c, 0x63a4, 0x1198,
+	0xb804, 0x9084, 0x00ff, 0x9082, 0x0006, 0x1268, 0xa894, 0x90c6,
+	0x006f, 0x0148, 0x080c, 0x9f54, 0x1904, 0x6216, 0xb8a0, 0x9084,
+	0xff80, 0x1904, 0x6216, 0xa894, 0x90c6, 0x006f, 0x0158, 0x90c6,
+	0x005e, 0x0904, 0x6176, 0x90c6, 0x0064, 0x0904, 0x619f, 0x2008,
+	0x0804, 0x6139, 0xa998, 0xa8b0, 0x2040, 0x080c, 0x9f54, 0x1120,
+	0x9182, 0x007f, 0x0a04, 0x6139, 0x9186, 0x00ff, 0x0904, 0x6139,
+	0x9182, 0x0800, 0x1a04, 0x6139, 0xaaa0, 0xab9c, 0x7878, 0x9306,
+	0x11a8, 0x787c, 0x0096, 0x924e, 0x1128, 0x2208, 0x2310, 0x009e,
+	0x0804, 0x6139, 0x080c, 0x9f54, 0x1140, 0x99cc, 0xff00, 0x009e,
+	0x1128, 0x2208, 0x2310, 0x0804, 0x6139, 0x009e, 0x080c, 0x48d2,
+	0x0904, 0x6142, 0x900e, 0x9016, 0x90c6, 0x4000, 0x1558, 0x0006,
+	0x080c, 0x65c4, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d,
+	0x20a9, 0x0004, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0031, 0x20a0,
+	0xb8b4, 0x20e0, 0xb8b8, 0x9080, 0x0006, 0x2098, 0x080c, 0x0fc0,
+	0x20a9, 0x0004, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0035, 0x20a0,
+	0xb8b4, 0x20e0, 0xb8b8, 0x9080, 0x000a, 0x2098, 0x080c, 0x0fc0,
+	0x000e, 0x00c8, 0x90c6, 0x4007, 0x1110, 0x2408, 0x00a0, 0x90c6,
+	0x4008, 0x1118, 0x2708, 0x2610, 0x0070, 0x90c6, 0x4009, 0x1108,
+	0x0050, 0x90c6, 0x4006, 0x0138, 0x2001, 0x4005, 0x2009, 0x000a,
+	0x0010, 0x2001, 0x4006, 0xa896, 0xa99a, 0xaa9e, 0x2001, 0x0030,
+	0x900e, 0x0470, 0x080c, 0x9f7f, 0x1130, 0x2001, 0x4005, 0x2009,
+	0x0003, 0x9016, 0x0c80, 0x2b00, 0x6012, 0x080c, 0xc1b7, 0x2900,
+	0x6016, 0x6023, 0x0001, 0xa868, 0xd88c, 0x0108, 0xc0f5, 0xa86a,
+	0x0126, 0x2091, 0x8000, 0x080c, 0x30ab, 0x012e, 0x9006, 0x080c,
+	0x62e1, 0x2001, 0x0002, 0x080c, 0x62f5, 0x2009, 0x0002, 0x080c,
+	0xa053, 0xa8b0, 0xd094, 0x0118, 0xb8bc, 0xc08d, 0xb8be, 0x9006,
+	0x9005, 0x012e, 0x00ee, 0x00fe, 0x00be, 0x0005, 0x080c, 0x54f0,
+	0x0118, 0x2009, 0x0007, 0x00f8, 0xa998, 0xaeb0, 0x080c, 0x63a4,
+	0x1904, 0x6134, 0x9186, 0x007f, 0x0130, 0x080c, 0x66ca, 0x0118,
+	0x2009, 0x0009, 0x0080, 0x0096, 0x080c, 0x1043, 0x1120, 0x009e,
+	0x2009, 0x0002, 0x0040, 0x2900, 0x009e, 0xa806, 0x080c, 0xbf23,
+	0x19b0, 0x2009, 0x0003, 0x2001, 0x4005, 0x0804, 0x613b, 0xa998,
+	0xaeb0, 0x080c, 0x63a4, 0x1904, 0x6134, 0x0096, 0x080c, 0x1043,
+	0x1128, 0x009e, 0x2009, 0x0002, 0x0804, 0x61f3, 0x2900, 0x009e,
+	0xa806, 0x0096, 0x2048, 0x20a9, 0x002b, 0xb8b4, 0x20e0, 0xb8b8,
+	0x2098, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0002, 0x20a0, 0x4003,
+	0x20a9, 0x0008, 0x9080, 0x0006, 0x20a0, 0xbbb8, 0x9398, 0x0006,
+	0x2398, 0x080c, 0x0fc0, 0x009e, 0xa87b, 0x0000, 0xa883, 0x0000,
+	0xa897, 0x4000, 0xd684, 0x1168, 0x080c, 0x54dc, 0xd0b4, 0x1118,
+	0xa89b, 0x000b, 0x00e0, 0xb800, 0xd08c, 0x0118, 0xa89b, 0x000c,
+	0x00b0, 0x080c, 0x66ca, 0x0118, 0xa89b, 0x0009, 0x0080, 0x080c,
+	0x54f0, 0x0118, 0xa89b, 0x0007, 0x0050, 0x080c, 0xbf06, 0x1904,
+	0x616f, 0x2009, 0x0003, 0x2001, 0x4005, 0x0804, 0x613b, 0xa87b,
+	0x0030, 0xa897, 0x4005, 0xa804, 0x8006, 0x8006, 0x8007, 0x90bc,
+	0x003f, 0x9084, 0xffc0, 0x9080, 0x0002, 0x2009, 0x002b, 0xaaa0,
+	0xab9c, 0xaca8, 0xada4, 0x2031, 0x0000, 0x2041, 0x129a, 0x080c,
+	0xa4df, 0x1904, 0x616f, 0x2009, 0x0002, 0x08e8, 0x2001, 0x0028,
+	0x900e, 0x0804, 0x6170, 0x2009, 0x180c, 0x210c, 0xd18c, 0x0118,
+	0x2001, 0x0004, 0x0038, 0xd184, 0x0118, 0x2001, 0x0004, 0x0010,
+	0x2001, 0x0029, 0x900e, 0x0804, 0x6170, 0x2001, 0x0029, 0x900e,
+	0x0804, 0x6170, 0x080c, 0x363a, 0x0804, 0x6171, 0x080c, 0x5207,
+	0x0804, 0x6171, 0x080c, 0x448d, 0x0804, 0x6171, 0x080c, 0x4506,
+	0x0804, 0x6171, 0x080c, 0x4562, 0x0804, 0x6171, 0x080c, 0x498e,
+	0x0804, 0x6171, 0x080c, 0x4c37, 0x0804, 0x6171, 0x080c, 0x4e6e,
+	0x0804, 0x6171, 0x080c, 0x5067, 0x0804, 0x6171, 0x080c, 0x3863,
+	0x0804, 0x6171, 0x00b6, 0xa974, 0xae78, 0x9684, 0x3fff, 0x9082,
+	0x4000, 0x1618, 0x9182, 0x0800, 0x1268, 0x9188, 0x1000, 0x2104,
+	0x905d, 0x0140, 0x080c, 0x66ca, 0x1148, 0x00e9, 0x080c, 0x64cf,
+	0x9006, 0x00b0, 0x2001, 0x0028, 0x900e, 0x0090, 0x9082, 0x0006,
+	0x1240, 0xb900, 0xd1fc, 0x0d88, 0x2001, 0x0029, 0x2009, 0x1000,
+	0x0038, 0x2001, 0x0029, 0x900e, 0x0018, 0x2001, 0x0029, 0x900e,
+	0x9005, 0x00be, 0x0005, 0x0126, 0x2091, 0x8000, 0xb850, 0x900d,
+	0x0150, 0x2900, 0x0096, 0x2148, 0xa802, 0x009e, 0xa803, 0x0000,
+	0xb852, 0x012e, 0x0005, 0x2900, 0xb852, 0xb84e, 0xa803, 0x0000,
+	0x0cc0, 0x0126, 0x2091, 0x8000, 0xb84c, 0x9005, 0x0170, 0x00e6,
+	0x2071, 0x19c2, 0x7004, 0x9086, 0x0002, 0x0168, 0x00ee, 0xb84c,
+	0xa802, 0x2900, 0xb84e, 0x012e, 0x0005, 0x2900, 0xb852, 0xb84e,
+	0xa803, 0x0000, 0x0cc0, 0x701c, 0x9b06, 0x1d80, 0xb84c, 0x00a6,
+	0x2050, 0xb000, 0xa802, 0x2900, 0xb002, 0x00ae, 0x00ee, 0x012e,
+	0x0005, 0x0126, 0x2091, 0x8000, 0xb84c, 0x904d, 0x0130, 0xa800,
+	0x9005, 0x1108, 0xb852, 0xb84e, 0x9905, 0x012e, 0x0005, 0xb84c,
 	0x904d, 0x0130, 0xa800, 0x9005, 0x1108, 0xb852, 0xb84e, 0x9905,
-	0x012e, 0x0005, 0xb84c, 0x904d, 0x0130, 0xa800, 0x9005, 0x1108,
-	0xb852, 0xb84e, 0x9905, 0x0005, 0x00b6, 0x0126, 0x00c6, 0x0026,
-	0x2091, 0x8000, 0x6210, 0x2258, 0xba00, 0x9005, 0x0110, 0xc285,
-	0x0008, 0xc284, 0xba02, 0x002e, 0x00ce, 0x012e, 0x00be, 0x0005,
-	0x00b6, 0x0126, 0x00c6, 0x2091, 0x8000, 0x6210, 0x2258, 0xba04,
-	0x0006, 0x9086, 0x0006, 0x1170, 0xb89c, 0xd0ac, 0x0158, 0x080c,
-	0x67bf, 0x0140, 0x9284, 0xff00, 0x8007, 0x9086, 0x0007, 0x1110,
-	0x2011, 0x0600, 0x000e, 0x9294, 0xff00, 0x9215, 0xba06, 0x0006,
-	0x9086, 0x0006, 0x1120, 0xba90, 0x82ff, 0x090c, 0x0dfa, 0x000e,
-	0x00ce, 0x012e, 0x00be, 0x0005, 0x00b6, 0x0126, 0x00c6, 0x2091,
-	0x8000, 0x6210, 0x2258, 0xba04, 0x0006, 0x9086, 0x0006, 0x1168,
-	0xb89c, 0xd0a4, 0x0150, 0x080c, 0x67bb, 0x1138, 0x9284, 0x00ff,
-	0x9086, 0x0007, 0x1110, 0x2011, 0x0006, 0x000e, 0x9294, 0x00ff,
-	0x8007, 0x9215, 0xba06, 0x00ce, 0x012e, 0x00be, 0x0005, 0x9182,
-	0x0800, 0x0218, 0x9085, 0x0001, 0x0005, 0x00d6, 0x0026, 0x9190,
-	0x1000, 0x2204, 0x905d, 0x1180, 0x0096, 0x080c, 0x1031, 0x2958,
-	0x009e, 0x0160, 0x2b00, 0x2012, 0xb85c, 0xb8ba, 0xb860, 0xb8b6,
-	0x9006, 0xb8a6, 0x080c, 0x5f45, 0x9006, 0x0010, 0x9085, 0x0001,
-	0x002e, 0x00de, 0x0005, 0x00b6, 0x0096, 0x0126, 0x2091, 0x8000,
-	0x0026, 0x9182, 0x0800, 0x0218, 0x9085, 0x0001, 0x0458, 0x00d6,
-	0x9190, 0x1000, 0x2204, 0x905d, 0x0518, 0x2013, 0x0000, 0xb8a4,
-	0x904d, 0x0110, 0x080c, 0x1063, 0x00d6, 0x00c6, 0xb8ac, 0x2060,
-	0x8cff, 0x0168, 0x600c, 0x0006, 0x6014, 0x2048, 0x080c, 0xbe37,
-	0x0110, 0x080c, 0x0fe3, 0x080c, 0xa0e3, 0x00ce, 0x0c88, 0x00ce,
-	0x00de, 0x2b48, 0xb8b8, 0xb85e, 0xb8b4, 0xb862, 0x080c, 0x1073,
-	0x00de, 0x9006, 0x002e, 0x012e, 0x009e, 0x00be, 0x0005, 0x0016,
-	0x9182, 0x0800, 0x0218, 0x9085, 0x0001, 0x0030, 0x9188, 0x1000,
-	0x2104, 0x905d, 0x0dc0, 0x9006, 0x001e, 0x0005, 0x00d6, 0x0156,
-	0x0136, 0x0146, 0x9006, 0xb80a, 0xb80e, 0xb800, 0xc08c, 0xb802,
-	0x080c, 0x7207, 0x1510, 0xb8a0, 0x9086, 0x007e, 0x0120, 0x080c,
-	0xa062, 0x11d8, 0x0078, 0x7040, 0xd0e4, 0x01b8, 0x00c6, 0x2061,
-	0x195a, 0x7048, 0x2062, 0x704c, 0x6006, 0x7050, 0x600a, 0x7054,
-	0x600e, 0x00ce, 0x703c, 0x2069, 0x0140, 0x9005, 0x1110, 0x2001,
-	0x0001, 0x6886, 0x2069, 0x1800, 0x68b2, 0x7040, 0xb85e, 0x7048,
-	0xb862, 0x704c, 0xb866, 0x20e1, 0x0000, 0x2099, 0x0276, 0xb8b4,
-	0x20e8, 0xb8b8, 0x9088, 0x000a, 0x21a0, 0x20a9, 0x0004, 0x4003,
-	0x2099, 0x027a, 0x9088, 0x0006, 0x21a0, 0x20a9, 0x0004, 0x4003,
-	0x2069, 0x0200, 0x6817, 0x0001, 0x7040, 0xb86a, 0x7144, 0xb96e,
-	0x7048, 0xb872, 0x7050, 0xb876, 0x2069, 0x0200, 0x6817, 0x0000,
-	0xb8a0, 0x9086, 0x007e, 0x1110, 0x7144, 0xb96e, 0x9182, 0x0211,
-	0x1218, 0x2009, 0x0008, 0x0400, 0x9182, 0x0259, 0x1218, 0x2009,
-	0x0007, 0x00d0, 0x9182, 0x02c1, 0x1218, 0x2009, 0x0006, 0x00a0,
-	0x9182, 0x0349, 0x1218, 0x2009, 0x0005, 0x0070, 0x9182, 0x0421,
-	0x1218, 0x2009, 0x0004, 0x0040, 0x9182, 0x0581, 0x1218, 0x2009,
-	0x0003, 0x0010, 0x2009, 0x0002, 0xb992, 0x014e, 0x013e, 0x015e,
-	0x00de, 0x0005, 0x0016, 0x0026, 0x00e6, 0x2071, 0x0260, 0x7034,
-	0xb896, 0x703c, 0xb89a, 0x7054, 0xb89e, 0x0036, 0xbbbc, 0xc384,
-	0xba00, 0x2009, 0x187b, 0x210c, 0xd0bc, 0x0120, 0xd1ec, 0x0110,
-	0xc2ad, 0x0008, 0xc2ac, 0xd0c4, 0x0148, 0xd1e4, 0x0138, 0xc2bd,
-	0xd0cc, 0x0128, 0xd38c, 0x1108, 0xc385, 0x0008, 0xc2bc, 0xba02,
-	0xbbbe, 0x003e, 0x00ee, 0x002e, 0x001e, 0x0005, 0x0096, 0x0126,
-	0x2091, 0x8000, 0xb8a4, 0x904d, 0x0578, 0xa900, 0x81ff, 0x15c0,
-	0xaa04, 0x9282, 0x0010, 0x16c8, 0x0136, 0x0146, 0x01c6, 0x01d6,
-	0x8906, 0x8006, 0x8007, 0x908c, 0x003f, 0x21e0, 0x9084, 0xffc0,
-	0x9080, 0x0004, 0x2098, 0x2009, 0x0010, 0x20a9, 0x0001, 0x4002,
-	0x9086, 0xffff, 0x0120, 0x8109, 0x1dd0, 0x080c, 0x0dfa, 0x3c00,
-	0x20e8, 0x3300, 0x8001, 0x20a0, 0x4604, 0x8210, 0xaa06, 0x01de,
-	0x01ce, 0x014e, 0x013e, 0x0060, 0x080c, 0x1031, 0x0170, 0x2900,
-	0xb8a6, 0xa803, 0x0000, 0x080c, 0x665b, 0xa807, 0x0001, 0xae12,
-	0x9085, 0x0001, 0x012e, 0x009e, 0x0005, 0x9006, 0x0cd8, 0x0126,
-	0x2091, 0x8000, 0x0096, 0xb8a4, 0x904d, 0x0188, 0xa800, 0x9005,
-	0x1150, 0x080c, 0x666a, 0x1158, 0xa804, 0x908a, 0x0002, 0x0218,
-	0x8001, 0xa806, 0x0020, 0x080c, 0x1063, 0xb8a7, 0x0000, 0x009e,
-	0x012e, 0x0005, 0x0126, 0x2091, 0x8000, 0x080c, 0x8696, 0x012e,
-	0x0005, 0x901e, 0x0010, 0x2019, 0x0001, 0x900e, 0x0126, 0x2091,
-	0x8000, 0xb84c, 0x2048, 0xb800, 0xd0dc, 0x1170, 0x89ff, 0x0500,
-	0x83ff, 0x0120, 0xa878, 0x9606, 0x0158, 0x0030, 0xa86c, 0x9406,
-	0x1118, 0xa870, 0x9506, 0x0120, 0x2908, 0xa800, 0x2048, 0x0c70,
-	0x080c, 0x9a4e, 0xaa00, 0xb84c, 0x9906, 0x1110, 0xba4e, 0x0020,
-	0x00a6, 0x2150, 0xb202, 0x00ae, 0x82ff, 0x1110, 0xb952, 0x89ff,
-	0x012e, 0x0005, 0x9016, 0x0489, 0x1110, 0x2011, 0x0001, 0x0005,
-	0x080c, 0x66bf, 0x0128, 0x080c, 0xbef4, 0x0010, 0x9085, 0x0001,
-	0x0005, 0x080c, 0x66bf, 0x0128, 0x080c, 0xbe99, 0x0010, 0x9085,
-	0x0001, 0x0005, 0x080c, 0x66bf, 0x0128, 0x080c, 0xbef1, 0x0010,
-	0x9085, 0x0001, 0x0005, 0x080c, 0x66bf, 0x0128, 0x080c, 0xbeb8,
-	0x0010, 0x9085, 0x0001, 0x0005, 0x080c, 0x66bf, 0x0128, 0x080c,
-	0xbf37, 0x0010, 0x9085, 0x0001, 0x0005, 0xb8a4, 0x900d, 0x1118,
-	0x9085, 0x0001, 0x0005, 0x0136, 0x01c6, 0xa800, 0x9005, 0x11b8,
-	0x890e, 0x810e, 0x810f, 0x9184, 0x003f, 0x20e0, 0x9184, 0xffc0,
-	0x9080, 0x0004, 0x2098, 0x20a9, 0x0001, 0x2009, 0x0010, 0x4002,
-	0x9606, 0x0128, 0x8109, 0x1dd8, 0x9085, 0x0001, 0x0008, 0x9006,
-	0x01ce, 0x013e, 0x0005, 0x0146, 0x01d6, 0xa860, 0x20e8, 0xa85c,
-	0x9080, 0x0004, 0x20a0, 0x20a9, 0x0010, 0x2009, 0xffff, 0x4104,
-	0x01de, 0x014e, 0x0136, 0x01c6, 0xa800, 0x9005, 0x11b8, 0x890e,
-	0x810e, 0x810f, 0x9184, 0x003f, 0x20e0, 0x9184, 0xffc0, 0x9080,
-	0x0004, 0x2098, 0x20a9, 0x0001, 0x2009, 0x0010, 0x4002, 0x9606,
-	0x0128, 0x8109, 0x1dd8, 0x9085, 0x0001, 0x0068, 0x0146, 0x01d6,
-	0x3300, 0x8001, 0x20a0, 0x3c00, 0x20e8, 0x2001, 0xffff, 0x4004,
-	0x01de, 0x014e, 0x9006, 0x01ce, 0x013e, 0x0005, 0x0096, 0x0126,
-	0x2091, 0x8000, 0xb8a4, 0x904d, 0x1128, 0x080c, 0x1031, 0x0168,
-	0x2900, 0xb8a6, 0x080c, 0x665b, 0xa803, 0x0001, 0xa807, 0x0000,
-	0x9085, 0x0001, 0x012e, 0x009e, 0x0005, 0x9006, 0x0cd8, 0x0096,
-	0x0126, 0x2091, 0x8000, 0xb8a4, 0x904d, 0x0130, 0xb8a7, 0x0000,
-	0x080c, 0x1063, 0x9085, 0x0001, 0x012e, 0x009e, 0x0005, 0xb89c,
-	0xd0a4, 0x0005, 0x00b6, 0x00f6, 0x080c, 0x7207, 0x01b0, 0x71c0,
-	0x81ff, 0x1198, 0x71d8, 0xd19c, 0x0180, 0x2001, 0x007e, 0x9080,
-	0x1000, 0x2004, 0x905d, 0x0148, 0xb804, 0x9084, 0x00ff, 0x9086,
-	0x0006, 0x1118, 0xb800, 0xc0ed, 0xb802, 0x2079, 0x185b, 0x7804,
-	0x00d0, 0x0156, 0x20a9, 0x007f, 0x900e, 0x0016, 0x080c, 0x649f,
-	0x1168, 0xb804, 0x9084, 0xff00, 0x8007, 0x9096, 0x0004, 0x0118,
-	0x9086, 0x0006, 0x1118, 0xb800, 0xc0ed, 0xb802, 0x001e, 0x8108,
-	0x1f04, 0x66e5, 0x015e, 0x080c, 0x6781, 0x0120, 0x2001, 0x195d,
-	0x200c, 0x0030, 0x2079, 0x185b, 0x7804, 0x0030, 0x2009, 0x07d0,
-	0x2011, 0x670f, 0x080c, 0x836c, 0x00fe, 0x00be, 0x0005, 0x00b6,
-	0x2011, 0x670f, 0x080c, 0x82da, 0x080c, 0x6781, 0x01d8, 0x2001,
-	0x107e, 0x2004, 0x2058, 0xb900, 0xc1ec, 0xb902, 0x080c, 0x67bf,
-	0x0130, 0x2009, 0x07d0, 0x2011, 0x670f, 0x080c, 0x836c, 0x00e6,
-	0x2071, 0x1800, 0x9006, 0x707a, 0x705c, 0x707e, 0x080c, 0x2f6c,
-	0x00ee, 0x04b0, 0x0156, 0x00c6, 0x20a9, 0x007f, 0x900e, 0x0016,
-	0x080c, 0x649f, 0x1538, 0xb800, 0xd0ec, 0x0520, 0x0046, 0xbaa0,
-	0x2220, 0x9006, 0x2009, 0x0029, 0x080c, 0xd885, 0xb800, 0xc0e5,
-	0xc0ec, 0xb802, 0x080c, 0x67bb, 0x2001, 0x0707, 0x1128, 0xb804,
-	0x9084, 0x00ff, 0x9085, 0x0700, 0xb806, 0x2019, 0x0029, 0x080c,
-	0x8803, 0x0076, 0x903e, 0x080c, 0x86f1, 0x900e, 0x080c, 0xd5f6,
-	0x007e, 0x004e, 0x001e, 0x8108, 0x1f04, 0x6737, 0x00ce, 0x015e,
-	0x00be, 0x0005, 0x00b6, 0x6010, 0x2058, 0xb800, 0xc0ec, 0xb802,
-	0x00be, 0x0005, 0x7810, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0ac,
-	0x0005, 0x6010, 0x00b6, 0x905d, 0x0108, 0xb800, 0x00be, 0xd0bc,
-	0x0005, 0x00b6, 0x00f6, 0x2001, 0x107e, 0x2004, 0x905d, 0x0110,
-	0xb800, 0xd0ec, 0x00fe, 0x00be, 0x0005, 0x0126, 0x0026, 0x2091,
-	0x8000, 0x0006, 0xbaa0, 0x9290, 0x1000, 0x2204, 0x9b06, 0x190c,
-	0x0dfa, 0x000e, 0xba00, 0x9005, 0x0110, 0xc2fd, 0x0008, 0xc2fc,
-	0xba02, 0x002e, 0x012e, 0x0005, 0x2011, 0x1836, 0x2204, 0xd0cc,
-	0x0138, 0x2001, 0x195b, 0x200c, 0x2011, 0x67b1, 0x080c, 0x836c,
-	0x0005, 0x2011, 0x67b1, 0x080c, 0x82da, 0x2011, 0x1836, 0x2204,
-	0xc0cc, 0x2012, 0x0005, 0x080c, 0x55db, 0xd0ac, 0x0005, 0x080c,
-	0x55db, 0xd0a4, 0x0005, 0x0016, 0xb904, 0x9184, 0x00ff, 0x908e,
-	0x0006, 0x001e, 0x0005, 0x0016, 0xb904, 0x9184, 0xff00, 0x8007,
-	0x908e, 0x0006, 0x001e, 0x0005, 0x00b6, 0x00f6, 0x080c, 0xc539,
-	0x0158, 0x70d8, 0x9084, 0x0028, 0x0138, 0x2001, 0x107f, 0x2004,
-	0x905d, 0x0110, 0xb8bc, 0xd094, 0x00fe, 0x00be, 0x0005, 0x0006,
-	0x0016, 0x0036, 0x0046, 0x0076, 0x00b6, 0x2001, 0x1817, 0x203c,
-	0x9780, 0x32e9, 0x203d, 0x97bc, 0xff00, 0x873f, 0x9006, 0x2018,
-	0x2008, 0x9284, 0x8000, 0x0110, 0x2019, 0x0001, 0x9294, 0x7fff,
-	0x2100, 0x9706, 0x0190, 0x91a0, 0x1000, 0x2404, 0x905d, 0x0168,
-	0xb804, 0x9084, 0x00ff, 0x9086, 0x0006, 0x1138, 0x83ff, 0x0118,
-	0xb89c, 0xd0a4, 0x0110, 0x8211, 0x0158, 0x8108, 0x83ff, 0x0120,
-	0x9182, 0x0800, 0x0e28, 0x0068, 0x9182, 0x007e, 0x0e08, 0x0048,
-	0x00be, 0x007e, 0x004e, 0x003e, 0x001e, 0x9085, 0x0001, 0x000e,
-	0x0005, 0x00be, 0x007e, 0x004e, 0x003e, 0x001e, 0x9006, 0x000e,
-	0x0005, 0x0046, 0x0056, 0x0076, 0x00b6, 0x2100, 0x9084, 0x7fff,
-	0x9080, 0x1000, 0x2004, 0x905d, 0x0130, 0xb804, 0x9084, 0x00ff,
-	0x9086, 0x0006, 0x0550, 0x9184, 0x8000, 0x0580, 0x2001, 0x1817,
-	0x203c, 0x9780, 0x32e9, 0x203d, 0x97bc, 0xff00, 0x873f, 0x9006,
-	0x2020, 0x2400, 0x9706, 0x01a0, 0x94a8, 0x1000, 0x2504, 0x905d,
-	0x0178, 0xb804, 0x9084, 0x00ff, 0x9086, 0x0006, 0x1148, 0xb89c,
-	0xd0a4, 0x0130, 0xb814, 0x9206, 0x1118, 0xb810, 0x9306, 0x0128,
-	0x8420, 0x9482, 0x0800, 0x0e28, 0x0048, 0x918c, 0x7fff, 0x00be,
-	0x007e, 0x005e, 0x004e, 0x9085, 0x0001, 0x0005, 0x918c, 0x7fff,
-	0x00be, 0x007e, 0x005e, 0x004e, 0x9006, 0x0005, 0x2071, 0x190e,
-	0x7003, 0x0001, 0x7007, 0x0000, 0x9006, 0x7012, 0x7016, 0x701a,
-	0x701e, 0x700a, 0x7046, 0x0005, 0x0016, 0x00e6, 0x2071, 0x1921,
-	0x900e, 0x710a, 0x080c, 0x55db, 0xd0fc, 0x1140, 0x080c, 0x55db,
-	0x900e, 0xd09c, 0x0108, 0x8108, 0x7102, 0x0400, 0x2001, 0x187b,
-	0x200c, 0x9184, 0x0007, 0x9006, 0x0002, 0x6896, 0x6896, 0x6896,
-	0x6896, 0x6896, 0x68ad, 0x68bb, 0x6896, 0x7003, 0x0003, 0x2009,
-	0x187c, 0x210c, 0x9184, 0xff00, 0x8007, 0x9005, 0x1110, 0x2001,
-	0x0002, 0x7006, 0x0018, 0x7003, 0x0005, 0x0c88, 0x00ee, 0x001e,
-	0x0005, 0x00e6, 0x2071, 0x0050, 0x684c, 0x9005, 0x1150, 0x00e6,
-	0x2071, 0x190e, 0x7028, 0xc085, 0x702a, 0x00ee, 0x9085, 0x0001,
-	0x0488, 0x6844, 0x9005, 0x0158, 0x080c, 0x7576, 0x6a60, 0x9200,
-	0x7002, 0x6864, 0x9101, 0x7006, 0x9006, 0x7012, 0x7016, 0x6860,
-	0x7002, 0x6864, 0x7006, 0x6868, 0x700a, 0x686c, 0x700e, 0x6844,
-	0x9005, 0x1110, 0x7012, 0x7016, 0x684c, 0x701a, 0x701c, 0x9085,
-	0x0040, 0x701e, 0x7037, 0x0019, 0x702b, 0x0001, 0x00e6, 0x2071,
-	0x190e, 0x7028, 0xc084, 0x702a, 0x7007, 0x0001, 0x700b, 0x0000,
-	0x00ee, 0x9006, 0x00ee, 0x0005, 0xa868, 0xd0fc, 0x11d8, 0x00e6,
-	0x0026, 0x2001, 0x1921, 0x2004, 0x9005, 0x0904, 0x6aee, 0xa87c,
-	0xd0bc, 0x1904, 0x6aee, 0xa978, 0xa874, 0x9105, 0x1904, 0x6aee,
-	0x2001, 0x1921, 0x2004, 0x0002, 0x6aee, 0x6947, 0x6983, 0x6983,
-	0x6aee, 0x6983, 0x0005, 0xa868, 0xd0fc, 0x1500, 0x00e6, 0x0026,
-	0x2009, 0x1921, 0x210c, 0x81ff, 0x0904, 0x6aee, 0xa87c, 0xd0cc,
-	0x0904, 0x6aee, 0xa880, 0x9084, 0x00ff, 0x9086, 0x0001, 0x1904,
-	0x6aee, 0x9186, 0x0003, 0x0904, 0x6983, 0x9186, 0x0005, 0x0904,
-	0x6983, 0xa84f, 0x8021, 0xa853, 0x0017, 0x0028, 0x0005, 0xa84f,
-	0x8020, 0xa853, 0x0016, 0x2071, 0x190e, 0x701c, 0x9005, 0x1904,
-	0x6ca2, 0x0e04, 0x6ced, 0x2071, 0x0000, 0xa84c, 0x7082, 0xa850,
-	0x7032, 0xa86c, 0x7086, 0x7036, 0xa870, 0x708a, 0x2091, 0x4080,
-	0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11e0, 0x2071, 0x1800,
-	0x2011, 0x0001, 0xa804, 0x900d, 0x702c, 0x1158, 0xa802, 0x2900,
-	0x702e, 0x70bc, 0x9200, 0x70be, 0x080c, 0x81f0, 0x002e, 0x00ee,
-	0x0005, 0x0096, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff,
-	0x1dc8, 0x009e, 0x0c58, 0xa84f, 0x0000, 0x00f6, 0x2079, 0x0050,
-	0x2071, 0x190e, 0xa803, 0x0000, 0x7010, 0x9005, 0x1904, 0x6a72,
-	0x782c, 0x908c, 0x0780, 0x190c, 0x6e16, 0x8004, 0x8004, 0x8004,
-	0x9084, 0x0003, 0x0002, 0x69a1, 0x6a72, 0x69c6, 0x6a0d, 0x080c,
-	0x0dfa, 0x2071, 0x1800, 0x2900, 0x7822, 0xa804, 0x900d, 0x1170,
-	0x2071, 0x19d2, 0x703c, 0x9005, 0x1328, 0x2001, 0x1922, 0x2004,
-	0x8005, 0x703e, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x9016, 0x702c,
-	0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e,
-	0x70bc, 0x9200, 0x70be, 0x080c, 0x81f0, 0x0c10, 0x2071, 0x1800,
-	0x2900, 0x7822, 0xa804, 0x900d, 0x1580, 0x7824, 0x00e6, 0x2071,
-	0x0040, 0x712c, 0xd19c, 0x1148, 0x2009, 0x182f, 0x210c, 0x918a,
-	0x0040, 0x0218, 0x7022, 0x00ee, 0x0058, 0x00ee, 0x2048, 0x702c,
-	0xa802, 0x2900, 0x702e, 0x70bc, 0x8000, 0x70be, 0x080c, 0x81f0,
-	0x782c, 0x9094, 0x0780, 0x190c, 0x6e16, 0xd0a4, 0x19f0, 0x2071,
-	0x19d2, 0x703c, 0x9005, 0x1328, 0x2001, 0x1922, 0x2004, 0x8005,
-	0x703e, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x9016, 0x702c, 0x2148,
-	0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70bc,
-	0x9200, 0x70be, 0x080c, 0x81f0, 0x0800, 0x0096, 0x00e6, 0x7824,
-	0x2048, 0x2071, 0x1800, 0x702c, 0xa802, 0x2900, 0x702e, 0x70bc,
-	0x8000, 0x70be, 0x080c, 0x81f0, 0x782c, 0x9094, 0x0780, 0x190c,
-	0x6e16, 0xd0a4, 0x1d60, 0x00ee, 0x782c, 0x9094, 0x0780, 0x190c,
-	0x6e16, 0xd09c, 0x11a0, 0x009e, 0x2900, 0x7822, 0xa804, 0x900d,
-	0x1560, 0x2071, 0x19d2, 0x703c, 0x9005, 0x1328, 0x2001, 0x1922,
-	0x2004, 0x8005, 0x703e, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x009e,
-	0x2908, 0x7010, 0x8000, 0x7012, 0x7018, 0x904d, 0x711a, 0x0110,
-	0xa902, 0x0008, 0x711e, 0x2148, 0xa804, 0x900d, 0x1170, 0x2071,
-	0x19d2, 0x703c, 0x9005, 0x1328, 0x2001, 0x1922, 0x2004, 0x8005,
-	0x703e, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x2071, 0x1800, 0x9016,
-	0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8,
-	0x702e, 0x70bc, 0x9200, 0x70be, 0x080c, 0x81f0, 0x00fe, 0x002e,
-	0x00ee, 0x0005, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018, 0x904d,
-	0x711a, 0x0110, 0xa902, 0x0008, 0x711e, 0x2148, 0xa804, 0x900d,
-	0x1904, 0x6ac7, 0x782c, 0x9094, 0x0780, 0x190c, 0x6e16, 0xd09c,
-	0x1198, 0x701c, 0x904d, 0x0180, 0x7010, 0x8001, 0x7012, 0x1108,
-	0x701a, 0xa800, 0x701e, 0x2900, 0x7822, 0x782c, 0x9094, 0x0780,
-	0x190c, 0x6e16, 0xd09c, 0x0d68, 0x782c, 0x9094, 0x0780, 0x190c,
-	0x6e16, 0xd0a4, 0x01b0, 0x00e6, 0x7824, 0x2048, 0x2071, 0x1800,
+	0x0005, 0x00b6, 0x0126, 0x00c6, 0x0026, 0x2091, 0x8000, 0x6210,
+	0x2258, 0xba00, 0x9005, 0x0110, 0xc285, 0x0008, 0xc284, 0xba02,
+	0x002e, 0x00ce, 0x012e, 0x00be, 0x0005, 0x00b6, 0x0126, 0x00c6,
+	0x2091, 0x8000, 0x6210, 0x2258, 0xba04, 0x0006, 0x9086, 0x0006,
+	0x1170, 0xb89c, 0xd0ac, 0x0158, 0x080c, 0x66c6, 0x0140, 0x9284,
+	0xff00, 0x8007, 0x9086, 0x0007, 0x1110, 0x2011, 0x0600, 0x000e,
+	0x9294, 0xff00, 0x9215, 0xba06, 0x0006, 0x9086, 0x0006, 0x1120,
+	0xba90, 0x82ff, 0x090c, 0x0e02, 0x000e, 0x00ce, 0x012e, 0x00be,
+	0x0005, 0x00b6, 0x0126, 0x00c6, 0x2091, 0x8000, 0x6210, 0x2258,
+	0xba04, 0x0006, 0x9086, 0x0006, 0x1168, 0xb89c, 0xd0a4, 0x0150,
+	0x080c, 0x66c2, 0x1138, 0x9284, 0x00ff, 0x9086, 0x0007, 0x1110,
+	0x2011, 0x0006, 0x000e, 0x9294, 0x00ff, 0x8007, 0x9215, 0xba06,
+	0x00ce, 0x012e, 0x00be, 0x0005, 0x9182, 0x0800, 0x0218, 0x9085,
+	0x0001, 0x0005, 0x00d6, 0x0026, 0x9190, 0x1000, 0x2204, 0x905d,
+	0x1180, 0x0096, 0x080c, 0x1043, 0x2958, 0x009e, 0x0160, 0x2b00,
+	0x2012, 0xb85c, 0xb8ba, 0xb860, 0xb8b6, 0x9006, 0xb8a6, 0x080c,
+	0x5e4a, 0x9006, 0x0010, 0x9085, 0x0001, 0x002e, 0x00de, 0x0005,
+	0x00b6, 0x0096, 0x0126, 0x2091, 0x8000, 0x0026, 0x9182, 0x0800,
+	0x0218, 0x9085, 0x0001, 0x0458, 0x00d6, 0x9190, 0x1000, 0x2204,
+	0x905d, 0x0518, 0x2013, 0x0000, 0xb8a4, 0x904d, 0x0110, 0x080c,
+	0x1075, 0x00d6, 0x00c6, 0xb8ac, 0x2060, 0x8cff, 0x0168, 0x600c,
+	0x0006, 0x6014, 0x2048, 0x080c, 0xbd3b, 0x0110, 0x080c, 0x0ff5,
+	0x080c, 0x9fd5, 0x00ce, 0x0c88, 0x00ce, 0x00de, 0x2b48, 0xb8b8,
+	0xb85e, 0xb8b4, 0xb862, 0x080c, 0x1085, 0x00de, 0x9006, 0x002e,
+	0x012e, 0x009e, 0x00be, 0x0005, 0x0016, 0x9182, 0x0800, 0x0218,
+	0x9085, 0x0001, 0x0030, 0x9188, 0x1000, 0x2104, 0x905d, 0x0dc0,
+	0x9006, 0x001e, 0x0005, 0x00d6, 0x0156, 0x0136, 0x0146, 0x9006,
+	0xb80a, 0xb80e, 0xb800, 0xc08c, 0xb802, 0x080c, 0x717f, 0x1510,
+	0xb8a0, 0x9086, 0x007e, 0x0120, 0x080c, 0x9f54, 0x11d8, 0x0078,
+	0x7040, 0xd0e4, 0x01b8, 0x00c6, 0x2061, 0x195c, 0x7048, 0x2062,
+	0x704c, 0x6006, 0x7050, 0x600a, 0x7054, 0x600e, 0x00ce, 0x703c,
+	0x2069, 0x0140, 0x9005, 0x1110, 0x2001, 0x0001, 0x6886, 0x2069,
+	0x1800, 0x68b2, 0x7040, 0xb85e, 0x7048, 0xb862, 0x704c, 0xb866,
+	0x20e1, 0x0000, 0x2099, 0x0276, 0xb8b4, 0x20e8, 0xb8b8, 0x9088,
+	0x000a, 0x21a0, 0x20a9, 0x0004, 0x4003, 0x2099, 0x027a, 0x9088,
+	0x0006, 0x21a0, 0x20a9, 0x0004, 0x4003, 0x2069, 0x0200, 0x6817,
+	0x0001, 0x7040, 0xb86a, 0x7144, 0xb96e, 0x7048, 0xb872, 0x7050,
+	0xb876, 0x2069, 0x0200, 0x6817, 0x0000, 0xb8a0, 0x9086, 0x007e,
+	0x1110, 0x7144, 0xb96e, 0x9182, 0x0211, 0x1218, 0x2009, 0x0008,
+	0x0400, 0x9182, 0x0259, 0x1218, 0x2009, 0x0007, 0x00d0, 0x9182,
+	0x02c1, 0x1218, 0x2009, 0x0006, 0x00a0, 0x9182, 0x0349, 0x1218,
+	0x2009, 0x0005, 0x0070, 0x9182, 0x0421, 0x1218, 0x2009, 0x0004,
+	0x0040, 0x9182, 0x0581, 0x1218, 0x2009, 0x0003, 0x0010, 0x2009,
+	0x0002, 0xb992, 0x014e, 0x013e, 0x015e, 0x00de, 0x0005, 0x0016,
+	0x0026, 0x00e6, 0x2071, 0x0260, 0x7034, 0xb896, 0x703c, 0xb89a,
+	0x7054, 0xb89e, 0x0036, 0xbbbc, 0xc384, 0xba00, 0x2009, 0x187b,
+	0x210c, 0xd0bc, 0x0120, 0xd1ec, 0x0110, 0xc2ad, 0x0008, 0xc2ac,
+	0xd0c4, 0x0148, 0xd1e4, 0x0138, 0xc2bd, 0xd0cc, 0x0128, 0xd38c,
+	0x1108, 0xc385, 0x0008, 0xc2bc, 0xba02, 0xbbbe, 0x003e, 0x00ee,
+	0x002e, 0x001e, 0x0005, 0x0096, 0x0126, 0x2091, 0x8000, 0xb8a4,
+	0x904d, 0x0578, 0xa900, 0x81ff, 0x15c0, 0xaa04, 0x9282, 0x0010,
+	0x16c8, 0x0136, 0x0146, 0x01c6, 0x01d6, 0x8906, 0x8006, 0x8007,
+	0x908c, 0x003f, 0x21e0, 0x9084, 0xffc0, 0x9080, 0x0004, 0x2098,
+	0x2009, 0x0010, 0x20a9, 0x0001, 0x4002, 0x9086, 0xffff, 0x0120,
+	0x8109, 0x1dd0, 0x080c, 0x0e02, 0x3c00, 0x20e8, 0x3300, 0x8001,
+	0x20a0, 0x4604, 0x8210, 0xaa06, 0x01de, 0x01ce, 0x014e, 0x013e,
+	0x0060, 0x080c, 0x1043, 0x0170, 0x2900, 0xb8a6, 0xa803, 0x0000,
+	0x080c, 0x6560, 0xa807, 0x0001, 0xae12, 0x9085, 0x0001, 0x012e,
+	0x009e, 0x0005, 0x9006, 0x0cd8, 0x0126, 0x2091, 0x8000, 0x0096,
+	0xb8a4, 0x904d, 0x0188, 0xa800, 0x9005, 0x1150, 0x080c, 0x656f,
+	0x1158, 0xa804, 0x908a, 0x0002, 0x0218, 0x8001, 0xa806, 0x0020,
+	0x080c, 0x1075, 0xb8a7, 0x0000, 0x009e, 0x012e, 0x0005, 0x0126,
+	0x2091, 0x8000, 0x080c, 0x8616, 0x012e, 0x0005, 0x901e, 0x0010,
+	0x2019, 0x0001, 0x900e, 0x0126, 0x2091, 0x8000, 0xb84c, 0x2048,
+	0xb800, 0xd0dc, 0x1170, 0x89ff, 0x0500, 0x83ff, 0x0120, 0xa878,
+	0x9606, 0x0158, 0x0030, 0xa86c, 0x9406, 0x1118, 0xa870, 0x9506,
+	0x0120, 0x2908, 0xa800, 0x2048, 0x0c70, 0x080c, 0x9940, 0xaa00,
+	0xb84c, 0x9906, 0x1110, 0xba4e, 0x0020, 0x00a6, 0x2150, 0xb202,
+	0x00ae, 0x82ff, 0x1110, 0xb952, 0x89ff, 0x012e, 0x0005, 0x9016,
+	0x0489, 0x1110, 0x2011, 0x0001, 0x0005, 0x080c, 0x65c4, 0x0128,
+	0x080c, 0xbdf8, 0x0010, 0x9085, 0x0001, 0x0005, 0x080c, 0x65c4,
+	0x0128, 0x080c, 0xbd9d, 0x0010, 0x9085, 0x0001, 0x0005, 0x080c,
+	0x65c4, 0x0128, 0x080c, 0xbdf5, 0x0010, 0x9085, 0x0001, 0x0005,
+	0x080c, 0x65c4, 0x0128, 0x080c, 0xbdbc, 0x0010, 0x9085, 0x0001,
+	0x0005, 0x080c, 0x65c4, 0x0128, 0x080c, 0xbe3b, 0x0010, 0x9085,
+	0x0001, 0x0005, 0xb8a4, 0x900d, 0x1118, 0x9085, 0x0001, 0x0005,
+	0x0136, 0x01c6, 0xa800, 0x9005, 0x11b8, 0x890e, 0x810e, 0x810f,
+	0x9184, 0x003f, 0x20e0, 0x9184, 0xffc0, 0x9080, 0x0004, 0x2098,
+	0x20a9, 0x0001, 0x2009, 0x0010, 0x4002, 0x9606, 0x0128, 0x8109,
+	0x1dd8, 0x9085, 0x0001, 0x0008, 0x9006, 0x01ce, 0x013e, 0x0005,
+	0x0146, 0x01d6, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0004, 0x20a0,
+	0x20a9, 0x0010, 0x2009, 0xffff, 0x4104, 0x01de, 0x014e, 0x0136,
+	0x01c6, 0xa800, 0x9005, 0x11b8, 0x890e, 0x810e, 0x810f, 0x9184,
+	0x003f, 0x20e0, 0x9184, 0xffc0, 0x9080, 0x0004, 0x2098, 0x20a9,
+	0x0001, 0x2009, 0x0010, 0x4002, 0x9606, 0x0128, 0x8109, 0x1dd8,
+	0x9085, 0x0001, 0x0068, 0x0146, 0x01d6, 0x3300, 0x8001, 0x20a0,
+	0x3c00, 0x20e8, 0x2001, 0xffff, 0x4004, 0x01de, 0x014e, 0x9006,
+	0x01ce, 0x013e, 0x0005, 0x0096, 0x0126, 0x2091, 0x8000, 0xb8a4,
+	0x904d, 0x1128, 0x080c, 0x1043, 0x0168, 0x2900, 0xb8a6, 0x080c,
+	0x6560, 0xa803, 0x0001, 0xa807, 0x0000, 0x9085, 0x0001, 0x012e,
+	0x009e, 0x0005, 0x9006, 0x0cd8, 0x0096, 0x0126, 0x2091, 0x8000,
+	0xb8a4, 0x904d, 0x0130, 0xb8a7, 0x0000, 0x080c, 0x1075, 0x9085,
+	0x0001, 0x012e, 0x009e, 0x0005, 0xb89c, 0xd0a4, 0x0005, 0x00b6,
+	0x00f6, 0x080c, 0x717f, 0x01b0, 0x71c0, 0x81ff, 0x1198, 0x71d8,
+	0xd19c, 0x0180, 0x2001, 0x007e, 0x9080, 0x1000, 0x2004, 0x905d,
+	0x0148, 0xb804, 0x9084, 0x00ff, 0x9086, 0x0006, 0x1118, 0xb800,
+	0xc0ed, 0xb802, 0x2079, 0x185b, 0x7804, 0x00d0, 0x0156, 0x20a9,
+	0x007f, 0x900e, 0x0016, 0x080c, 0x63a4, 0x1168, 0xb804, 0x9084,
+	0xff00, 0x8007, 0x9096, 0x0004, 0x0118, 0x9086, 0x0006, 0x1118,
+	0xb800, 0xc0ed, 0xb802, 0x001e, 0x8108, 0x1f04, 0x65ea, 0x015e,
+	0x080c, 0x6688, 0x0120, 0x2001, 0x195f, 0x200c, 0x0030, 0x2079,
+	0x185b, 0x7804, 0x0030, 0x2009, 0x07d0, 0x2011, 0x6614, 0x080c,
+	0x82ec, 0x00fe, 0x00be, 0x0005, 0x00b6, 0x2011, 0x6614, 0x080c,
+	0x825a, 0x080c, 0x6688, 0x01d8, 0x2001, 0x107e, 0x2004, 0x2058,
+	0xb900, 0xc1ec, 0xb902, 0x080c, 0x66c6, 0x0130, 0x2009, 0x07d0,
+	0x2011, 0x6614, 0x080c, 0x82ec, 0x00e6, 0x2071, 0x1800, 0x9006,
+	0x707a, 0x705c, 0x707e, 0x080c, 0x2e8c, 0x00ee, 0x04c0, 0x0156,
+	0x00c6, 0x20a9, 0x007f, 0x900e, 0x0016, 0x080c, 0x63a4, 0x1548,
+	0xb800, 0xd0ec, 0x0530, 0xd0bc, 0x1520, 0x0046, 0xbaa0, 0x2220,
+	0x9006, 0x2009, 0x0029, 0x080c, 0xd7d6, 0xb800, 0xc0e5, 0xc0ec,
+	0xb802, 0x080c, 0x66c2, 0x2001, 0x0707, 0x1128, 0xb804, 0x9084,
+	0x00ff, 0x9085, 0x0700, 0xb806, 0x2019, 0x0029, 0x080c, 0x8783,
+	0x0076, 0x903e, 0x080c, 0x8671, 0x900e, 0x080c, 0xd53b, 0x007e,
+	0x004e, 0x001e, 0x8108, 0x1f04, 0x663c, 0x00ce, 0x015e, 0x00be,
+	0x0005, 0x00b6, 0x6010, 0x2058, 0xb800, 0xc0ec, 0xb802, 0x00be,
+	0x0005, 0x7810, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0ac, 0x0005,
+	0x6010, 0x00b6, 0x905d, 0x0108, 0xb800, 0x00be, 0xd0bc, 0x0005,
+	0x00b6, 0x00f6, 0x2001, 0x107e, 0x2004, 0x905d, 0x0110, 0xb800,
+	0xd0ec, 0x00fe, 0x00be, 0x0005, 0x0126, 0x0026, 0x2091, 0x8000,
+	0x0006, 0xbaa0, 0x9290, 0x1000, 0x2204, 0x9b06, 0x190c, 0x0e02,
+	0x000e, 0xba00, 0x9005, 0x0110, 0xc2fd, 0x0008, 0xc2fc, 0xba02,
+	0x002e, 0x012e, 0x0005, 0x2011, 0x1836, 0x2204, 0xd0cc, 0x0138,
+	0x2001, 0x195d, 0x200c, 0x2011, 0x66b8, 0x080c, 0x82ec, 0x0005,
+	0x2011, 0x66b8, 0x080c, 0x825a, 0x2011, 0x1836, 0x2204, 0xc0cc,
+	0x2012, 0x0005, 0x080c, 0x54dc, 0xd0ac, 0x0005, 0x080c, 0x54dc,
+	0xd0a4, 0x0005, 0x0016, 0xb904, 0x9184, 0x00ff, 0x908e, 0x0006,
+	0x001e, 0x0005, 0x0016, 0xb904, 0x9184, 0xff00, 0x8007, 0x908e,
+	0x0006, 0x001e, 0x0005, 0x00b6, 0x00f6, 0x080c, 0xc444, 0x0158,
+	0x70d8, 0x9084, 0x0028, 0x0138, 0x2001, 0x107f, 0x2004, 0x905d,
+	0x0110, 0xb8bc, 0xd094, 0x00fe, 0x00be, 0x0005, 0x0006, 0x0016,
+	0x0036, 0x0046, 0x0076, 0x00b6, 0x2001, 0x1817, 0x203c, 0x9780,
+	0x3209, 0x203d, 0x97bc, 0xff00, 0x873f, 0x9006, 0x2018, 0x2008,
+	0x9284, 0x8000, 0x0110, 0x2019, 0x0001, 0x9294, 0x7fff, 0x2100,
+	0x9706, 0x0190, 0x91a0, 0x1000, 0x2404, 0x905d, 0x0168, 0xb804,
+	0x9084, 0x00ff, 0x9086, 0x0006, 0x1138, 0x83ff, 0x0118, 0xb89c,
+	0xd0a4, 0x0110, 0x8211, 0x0158, 0x8108, 0x83ff, 0x0120, 0x9182,
+	0x0800, 0x0e28, 0x0068, 0x9182, 0x007e, 0x0e08, 0x0048, 0x00be,
+	0x007e, 0x004e, 0x003e, 0x001e, 0x9085, 0x0001, 0x000e, 0x0005,
+	0x00be, 0x007e, 0x004e, 0x003e, 0x001e, 0x9006, 0x000e, 0x0005,
+	0x0046, 0x0056, 0x0076, 0x00b6, 0x2100, 0x9084, 0x7fff, 0x9080,
+	0x1000, 0x2004, 0x905d, 0x0130, 0xb804, 0x9084, 0x00ff, 0x9086,
+	0x0006, 0x0550, 0x9184, 0x8000, 0x0580, 0x2001, 0x1817, 0x203c,
+	0x9780, 0x3209, 0x203d, 0x97bc, 0xff00, 0x873f, 0x9006, 0x2020,
+	0x2400, 0x9706, 0x01a0, 0x94a8, 0x1000, 0x2504, 0x905d, 0x0178,
+	0xb804, 0x9084, 0x00ff, 0x9086, 0x0006, 0x1148, 0xb89c, 0xd0a4,
+	0x0130, 0xb814, 0x9206, 0x1118, 0xb810, 0x9306, 0x0128, 0x8420,
+	0x9482, 0x0800, 0x0e28, 0x0048, 0x918c, 0x7fff, 0x00be, 0x007e,
+	0x005e, 0x004e, 0x9085, 0x0001, 0x0005, 0x918c, 0x7fff, 0x00be,
+	0x007e, 0x005e, 0x004e, 0x9006, 0x0005, 0x2071, 0x190e, 0x7003,
+	0x0001, 0x7007, 0x0000, 0x9006, 0x7012, 0x7016, 0x701a, 0x701e,
+	0x700a, 0x7046, 0x2001, 0x1920, 0x2003, 0x0000, 0x0005, 0x0016,
+	0x00e6, 0x2071, 0x1923, 0x900e, 0x710a, 0x080c, 0x54dc, 0xd0fc,
+	0x1140, 0x080c, 0x54dc, 0x900e, 0xd09c, 0x0108, 0x8108, 0x7102,
+	0x0438, 0x2001, 0x187b, 0x200c, 0x9184, 0x0007, 0x9006, 0x0002,
+	0x67a1, 0x67a1, 0x67a1, 0x67a1, 0x67a1, 0x67b8, 0x67cd, 0x67db,
+	0x7003, 0x0003, 0x2009, 0x187c, 0x210c, 0x9184, 0xff00, 0x908e,
+	0xff00, 0x0140, 0x8007, 0x9005, 0x1110, 0x2001, 0x0002, 0x8003,
+	0x7006, 0x0030, 0x7007, 0x0001, 0x0018, 0x7003, 0x0005, 0x0c50,
+	0x2071, 0x190e, 0x704f, 0x0000, 0x2071, 0x1800, 0x70ef, 0x0001,
+	0x00ee, 0x001e, 0x0005, 0x7003, 0x0000, 0x2071, 0x190e, 0x2009,
+	0x187c, 0x210c, 0x9184, 0x7f00, 0x8007, 0x908c, 0x000f, 0x0160,
+	0x714e, 0x8004, 0x8004, 0x8004, 0x8004, 0x2071, 0x1800, 0x908c,
+	0x0007, 0x0128, 0x70ee, 0x0c20, 0x704f, 0x000f, 0x0c90, 0x70ef,
+	0x0005, 0x08f0, 0x00e6, 0x2071, 0x0050, 0x684c, 0x9005, 0x1150,
+	0x00e6, 0x2071, 0x190e, 0x7028, 0xc085, 0x702a, 0x00ee, 0x9085,
+	0x0001, 0x0488, 0x6844, 0x9005, 0x0158, 0x080c, 0x74ed, 0x6a60,
+	0x9200, 0x7002, 0x6864, 0x9101, 0x7006, 0x9006, 0x7012, 0x7016,
+	0x6860, 0x7002, 0x6864, 0x7006, 0x6868, 0x700a, 0x686c, 0x700e,
+	0x6844, 0x9005, 0x1110, 0x7012, 0x7016, 0x684c, 0x701a, 0x701c,
+	0x9085, 0x0040, 0x701e, 0x7037, 0x0019, 0x702b, 0x0001, 0x00e6,
+	0x2071, 0x190e, 0x7028, 0xc084, 0x702a, 0x7007, 0x0001, 0x700b,
+	0x0000, 0x00ee, 0x9006, 0x00ee, 0x0005, 0xa868, 0xd0fc, 0x1508,
+	0x00e6, 0x0026, 0x2001, 0x1923, 0x2004, 0x9015, 0x0904, 0x6a29,
+	0xa978, 0xa874, 0x9105, 0x1904, 0x6a29, 0x9286, 0x0003, 0x0904,
+	0x68c2, 0x9286, 0x0005, 0x0904, 0x68c2, 0xa87c, 0xd0bc, 0x1904,
+	0x6a29, 0x2200, 0x0002, 0x6a29, 0x6886, 0x68c2, 0x68c2, 0x6a29,
+	0x68c2, 0x0005, 0xa868, 0xd0fc, 0x1500, 0x00e6, 0x0026, 0x2009,
+	0x1923, 0x210c, 0x81ff, 0x0904, 0x6a29, 0xa880, 0x9084, 0x00ff,
+	0x9086, 0x0001, 0x1904, 0x6a29, 0x9186, 0x0003, 0x0904, 0x68c2,
+	0x9186, 0x0005, 0x0904, 0x68c2, 0xa87c, 0xd0cc, 0x0904, 0x6a29,
+	0xa84f, 0x8021, 0xa853, 0x0017, 0x0028, 0x0005, 0xa84f, 0x8020,
+	0xa853, 0x0016, 0x2071, 0x190e, 0x701c, 0x9005, 0x1904, 0x6bf7,
+	0x0e04, 0x6c42, 0x2071, 0x0000, 0xa84c, 0x7082, 0xa850, 0x7032,
+	0xa86c, 0x7086, 0x7036, 0xa870, 0x708a, 0x2091, 0x4080, 0x2001,
+	0x0089, 0x2004, 0xd084, 0x190c, 0x11f2, 0x2071, 0x1800, 0x2011,
+	0x0001, 0xa804, 0x900d, 0x702c, 0x1158, 0xa802, 0x2900, 0x702e,
+	0x70bc, 0x9200, 0x70be, 0x080c, 0x8170, 0x002e, 0x00ee, 0x0005,
+	0x0096, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8,
+	0x009e, 0x0c58, 0xa84f, 0x0000, 0x00f6, 0x2079, 0x0050, 0x2071,
+	0x190e, 0xa803, 0x0000, 0x7010, 0x9005, 0x1904, 0x69ad, 0x782c,
+	0x908c, 0x0780, 0x190c, 0x6d6b, 0x8004, 0x8004, 0x8004, 0x9084,
+	0x0003, 0x0002, 0x68e0, 0x69ad, 0x6904, 0x694a, 0x080c, 0x0e02,
+	0x2071, 0x1800, 0x2900, 0x7822, 0xa804, 0x900d, 0x1168, 0x2071,
+	0x19d5, 0x7044, 0x9005, 0x1320, 0x2001, 0x1924, 0x2004, 0x7046,
+	0x00fe, 0x002e, 0x00ee, 0x0005, 0x9016, 0x702c, 0x2148, 0xa904,
+	0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70bc, 0x9200,
+	0x70be, 0x080c, 0x8170, 0x0c18, 0x2071, 0x1800, 0x2900, 0x7822,
+	0xa804, 0x900d, 0x1578, 0x7824, 0x00e6, 0x2071, 0x0040, 0x712c,
+	0xd19c, 0x1148, 0x2009, 0x182f, 0x210c, 0x918a, 0x0040, 0x0218,
+	0x7022, 0x00ee, 0x0058, 0x00ee, 0x2048, 0x702c, 0xa802, 0x2900,
+	0x702e, 0x70bc, 0x8000, 0x70be, 0x080c, 0x8170, 0x782c, 0x9094,
+	0x0780, 0x190c, 0x6d6b, 0xd0a4, 0x19f0, 0x2071, 0x19d5, 0x7044,
+	0x9005, 0x1320, 0x2001, 0x1924, 0x2004, 0x7046, 0x00fe, 0x002e,
+	0x00ee, 0x0005, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210,
+	0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70bc, 0x9200, 0x70be, 0x080c,
+	0x8170, 0x0808, 0x0096, 0x00e6, 0x7824, 0x2048, 0x2071, 0x1800,
 	0x702c, 0xa802, 0x2900, 0x702e, 0x70bc, 0x8000, 0x70be, 0x080c,
-	0x81f0, 0x782c, 0x9094, 0x0780, 0x190c, 0x6e16, 0xd0a4, 0x1d60,
-	0x00ee, 0x2071, 0x19d2, 0x703c, 0x9005, 0x1328, 0x2001, 0x1922,
-	0x2004, 0x8005, 0x703e, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x00e6,
+	0x8170, 0x782c, 0x9094, 0x0780, 0x190c, 0x6d6b, 0xd0a4, 0x1d60,
+	0x00ee, 0x782c, 0x9094, 0x0780, 0x190c, 0x6d6b, 0xd09c, 0x1198,
+	0x009e, 0x2900, 0x7822, 0xa804, 0x900d, 0x1550, 0x2071, 0x19d5,
+	0x7044, 0x9005, 0x1320, 0x2001, 0x1924, 0x2004, 0x7046, 0x00fe,
+	0x002e, 0x00ee, 0x0005, 0x009e, 0x2908, 0x7010, 0x8000, 0x7012,
+	0x7018, 0x904d, 0x711a, 0x0110, 0xa902, 0x0008, 0x711e, 0x2148,
+	0xa804, 0x900d, 0x1168, 0x2071, 0x19d5, 0x7044, 0x9005, 0x1320,
+	0x2001, 0x1924, 0x2004, 0x7046, 0x00fe, 0x002e, 0x00ee, 0x0005,
 	0x2071, 0x1800, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210,
 	0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70bc, 0x9200, 0x70be, 0x080c,
-	0x81f0, 0x00ee, 0x0804, 0x6a82, 0xa868, 0xd0fc, 0x1904, 0x6b2a,
-	0x0096, 0xa804, 0xa807, 0x0000, 0x904d, 0x190c, 0x0fe3, 0x009e,
-	0x0018, 0xa868, 0xd0fc, 0x15f0, 0x00e6, 0x0026, 0xa84f, 0x0000,
-	0x00f6, 0x2079, 0x0050, 0x2071, 0x1800, 0x70e8, 0x8001, 0x01d0,
-	0x1678, 0x2071, 0x190e, 0xa803, 0x0000, 0x7010, 0x9005, 0x1904,
-	0x6c20, 0x782c, 0x908c, 0x0780, 0x190c, 0x6e16, 0x8004, 0x8004,
-	0x8004, 0x9084, 0x0003, 0x0002, 0x6b2b, 0x6c20, 0x6b46, 0x6bb3,
-	0x080c, 0x0dfa, 0x70eb, 0x0fa0, 0x71e4, 0x8107, 0x9106, 0x9094,
-	0x00c0, 0x9184, 0xff3f, 0x9205, 0x70e6, 0x3b08, 0x3a00, 0x9104,
-	0x918d, 0x00c0, 0x21d8, 0x9084, 0xff3f, 0x9205, 0x20d0, 0x0888,
-	0x70ea, 0x0878, 0x0005, 0x2071, 0x1800, 0x2900, 0x7822, 0xa804,
-	0x900d, 0x1120, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x9016, 0x702c,
-	0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e,
-	0x70bc, 0x9200, 0x70be, 0x080c, 0x81f0, 0x0c60, 0x2071, 0x1800,
-	0x2900, 0x7822, 0xa804, 0x900d, 0x1904, 0x6ba2, 0x7830, 0x8007,
-	0x9084, 0x001f, 0x9082, 0x0001, 0x1220, 0x00fe, 0x002e, 0x00ee,
-	0x0005, 0x7824, 0x00e6, 0x2071, 0x0040, 0x712c, 0xd19c, 0x1148,
-	0x2009, 0x182f, 0x210c, 0x918a, 0x0040, 0x0218, 0x7022, 0x00ee,
-	0x0058, 0x00ee, 0x2048, 0x702c, 0xa802, 0x2900, 0x702e, 0x70bc,
-	0x8000, 0x70be, 0x080c, 0x81f0, 0x782c, 0x9094, 0x0780, 0x190c,
-	0x6e16, 0xd0a4, 0x19f0, 0x0e04, 0x6b99, 0x7838, 0x7938, 0x910e,
+	0x8170, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x2908, 0x7010, 0x8000,
+	0x7012, 0x7018, 0x904d, 0x711a, 0x0110, 0xa902, 0x0008, 0x711e,
+	0x2148, 0xa804, 0x900d, 0x1904, 0x6a01, 0x782c, 0x9094, 0x0780,
+	0x190c, 0x6d6b, 0xd09c, 0x1198, 0x701c, 0x904d, 0x0180, 0x7010,
+	0x8001, 0x7012, 0x1108, 0x701a, 0xa800, 0x701e, 0x2900, 0x7822,
+	0x782c, 0x9094, 0x0780, 0x190c, 0x6d6b, 0xd09c, 0x0d68, 0x782c,
+	0x9094, 0x0780, 0x190c, 0x6d6b, 0xd0a4, 0x01b0, 0x00e6, 0x7824,
+	0x2048, 0x2071, 0x1800, 0x702c, 0xa802, 0x2900, 0x702e, 0x70bc,
+	0x8000, 0x70be, 0x080c, 0x8170, 0x782c, 0x9094, 0x0780, 0x190c,
+	0x6d6b, 0xd0a4, 0x1d60, 0x00ee, 0x2071, 0x19d5, 0x7044, 0x9005,
+	0x1320, 0x2001, 0x1924, 0x2004, 0x7046, 0x00fe, 0x002e, 0x00ee,
+	0x0005, 0x00e6, 0x2071, 0x1800, 0x9016, 0x702c, 0x2148, 0xa904,
+	0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70bc, 0x9200,
+	0x70be, 0x080c, 0x8170, 0x00ee, 0x0804, 0x69bd, 0xa868, 0xd0fc,
+	0x1904, 0x6a77, 0x0096, 0xa804, 0xa807, 0x0000, 0x904d, 0x190c,
+	0x0ff5, 0x009e, 0x0020, 0xa868, 0xd0fc, 0x1904, 0x6a77, 0x00e6,
+	0x0026, 0xa84f, 0x0000, 0x00f6, 0x2079, 0x0050, 0x2071, 0x1800,
+	0x70e8, 0x8001, 0x0558, 0x1a04, 0x6a74, 0x2071, 0x190e, 0xa803,
+	0x0000, 0xa864, 0x9084, 0x00ff, 0x908e, 0x0016, 0x01a8, 0x7010,
+	0x9005, 0x1904, 0x6b73, 0x782c, 0x908c, 0x0780, 0x190c, 0x6d6b,
+	0x8004, 0x8004, 0x8004, 0x9084, 0x0003, 0x0002, 0x6a78, 0x6b73,
+	0x6a93, 0x6b04, 0x080c, 0x0e02, 0x2009, 0x1923, 0x2104, 0x0002,
+	0x6a3f, 0x6a3f, 0x6a3f, 0x68cb, 0x6a3f, 0x68cb, 0x70eb, 0x0fa0,
+	0x71e4, 0x8107, 0x9106, 0x9094, 0x00c0, 0x9184, 0xff3f, 0x9205,
+	0x70e6, 0x3b08, 0x3a00, 0x9104, 0x918d, 0x00c0, 0x21d8, 0x9084,
+	0xff3f, 0x9205, 0x20d0, 0x0808, 0x70ea, 0x0804, 0x6a35, 0x0005,
+	0x2071, 0x1800, 0x2900, 0x7822, 0xa804, 0x900d, 0x1120, 0x00fe,
+	0x002e, 0x00ee, 0x0005, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802,
+	0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70bc, 0x9200, 0x70be,
+	0x080c, 0x8170, 0x0c60, 0x2071, 0x1800, 0x2900, 0x7822, 0xa804,
+	0x900d, 0x1904, 0x6af3, 0x7830, 0x8007, 0x908c, 0x001f, 0x70ec,
+	0x9102, 0x1220, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x7824, 0x00e6,
+	0x2071, 0x0040, 0x712c, 0xd19c, 0x1148, 0x2009, 0x182f, 0x210c,
+	0x918a, 0x0040, 0x0218, 0x7022, 0x00ee, 0x0058, 0x00ee, 0x2048,
+	0x702c, 0xa802, 0x2900, 0x702e, 0x70bc, 0x8000, 0x70be, 0x080c,
+	0x8170, 0x782c, 0x9094, 0x0780, 0x190c, 0x6d6b, 0xd0a4, 0x19f0,
+	0x0e04, 0x6aea, 0x7838, 0x7938, 0x910e, 0x1de0, 0x00d6, 0x2069,
+	0x0000, 0x6836, 0x6833, 0x0013, 0x00de, 0x2001, 0x191f, 0x200c,
+	0xc184, 0x2102, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084,
+	0x190c, 0x11f2, 0x2001, 0x1920, 0x2003, 0x0000, 0x00fe, 0x002e,
+	0x00ee, 0x0005, 0x2001, 0x191f, 0x200c, 0xc185, 0x2102, 0x00fe,
+	0x002e, 0x00ee, 0x0005, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802,
+	0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70bc, 0x9200, 0x70be,
+	0x080c, 0x8170, 0x0804, 0x6aa6, 0x0096, 0x00e6, 0x7824, 0x2048,
+	0x2071, 0x1800, 0x702c, 0xa802, 0x2900, 0x702e, 0x70bc, 0x8000,
+	0x70be, 0x080c, 0x8170, 0x782c, 0x9094, 0x0780, 0x190c, 0x6d6b,
+	0xd0a4, 0x1d60, 0x00ee, 0x0e04, 0x6b46, 0x7838, 0x7938, 0x910e,
 	0x1de0, 0x00d6, 0x2069, 0x0000, 0x6836, 0x6833, 0x0013, 0x00de,
-	0x2001, 0x191f, 0x200c, 0xc184, 0x2102, 0x2091, 0x4080, 0x2001,
-	0x0089, 0x2004, 0xd084, 0x190c, 0x11e0, 0x00fe, 0x002e, 0x00ee,
-	0x0005, 0x2001, 0x191f, 0x200c, 0xc185, 0x2102, 0x00fe, 0x002e,
-	0x00ee, 0x0005, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210,
-	0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70bc, 0x9200, 0x70be, 0x080c,
-	0x81f0, 0x0804, 0x6b59, 0x0096, 0x00e6, 0x7824, 0x2048, 0x2071,
-	0x1800, 0x702c, 0xa802, 0x2900, 0x702e, 0x70bc, 0x8000, 0x70be,
-	0x080c, 0x81f0, 0x782c, 0x9094, 0x0780, 0x190c, 0x6e16, 0xd0a4,
-	0x1d60, 0x00ee, 0x0e04, 0x6bf3, 0x7838, 0x7938, 0x910e, 0x1de0,
-	0x00d6, 0x2069, 0x0000, 0x6836, 0x6833, 0x0013, 0x00de, 0x7044,
-	0xc084, 0x7046, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084,
-	0x190c, 0x11e0, 0x782c, 0x9094, 0x0780, 0x190c, 0x6e16, 0xd09c,
-	0x1170, 0x009e, 0x2900, 0x7822, 0xa804, 0x900d, 0x11e0, 0x00fe,
-	0x002e, 0x00ee, 0x0005, 0x7044, 0xc085, 0x7046, 0x0c58, 0x009e,
-	0x2908, 0x7010, 0x8000, 0x7012, 0x7018, 0x904d, 0x711a, 0x0110,
-	0xa902, 0x0008, 0x711e, 0x2148, 0xa804, 0x900d, 0x1120, 0x00fe,
-	0x002e, 0x00ee, 0x0005, 0x2071, 0x1800, 0x9016, 0x702c, 0x2148,
-	0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70bc,
-	0x9200, 0x70be, 0x080c, 0x81f0, 0x00fe, 0x002e, 0x00ee, 0x0005,
-	0x2908, 0x7010, 0x8000, 0x7012, 0x7018, 0x904d, 0x711a, 0x0110,
-	0xa902, 0x0008, 0x711e, 0x2148, 0xa804, 0x900d, 0x1904, 0x6c8d,
-	0x782c, 0x9094, 0x0780, 0x190c, 0x6e16, 0xd09c, 0x11b0, 0x701c,
-	0x904d, 0x0198, 0xa84c, 0x9005, 0x1180, 0x7010, 0x8001, 0x7012,
-	0x1108, 0x701a, 0xa800, 0x701e, 0x2900, 0x7822, 0x782c, 0x9094,
-	0x0780, 0x190c, 0x6e16, 0xd09c, 0x0d50, 0x782c, 0x9094, 0x0780,
-	0x190c, 0x6e16, 0xd0a4, 0x05a8, 0x00e6, 0x7824, 0x2048, 0x2071,
-	0x1800, 0x702c, 0xa802, 0x2900, 0x702e, 0x70bc, 0x8000, 0x70be,
-	0x080c, 0x81f0, 0x782c, 0x9094, 0x0780, 0x190c, 0x6e16, 0xd0a4,
-	0x1d60, 0x00ee, 0x0e04, 0x6c86, 0x7838, 0x7938, 0x910e, 0x1de0,
-	0x00d6, 0x2069, 0x0000, 0x6836, 0x6833, 0x0013, 0x00de, 0x7044,
-	0xc084, 0x7046, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084,
-	0x190c, 0x11e0, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x7044, 0xc085,
-	0x7046, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x00e6, 0x2071, 0x1800,
+	0x7044, 0xc084, 0x7046, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004,
+	0xd084, 0x190c, 0x11f2, 0x704b, 0x0000, 0x782c, 0x9094, 0x0780,
+	0x190c, 0x6d6b, 0xd09c, 0x1170, 0x009e, 0x2900, 0x7822, 0xa804,
+	0x900d, 0x11e0, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x7044, 0xc085,
+	0x7046, 0x0c58, 0x009e, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018,
+	0x904d, 0x711a, 0x0110, 0xa902, 0x0008, 0x711e, 0x2148, 0xa804,
+	0x900d, 0x1120, 0x00fe, 0x002e, 0x00ee, 0x0005, 0x2071, 0x1800,
 	0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900, 0x81ff,
-	0x1dc8, 0x702e, 0x70bc, 0x9200, 0x70be, 0x080c, 0x81f0, 0x00ee,
-	0x0804, 0x6c30, 0x2071, 0x190e, 0xa803, 0x0000, 0x2908, 0x7010,
-	0x8000, 0x7012, 0x7018, 0x904d, 0x711a, 0x0110, 0xa902, 0x0008,
-	0x711e, 0x2148, 0xa804, 0x900d, 0x1128, 0x1e04, 0x6ccd, 0x002e,
-	0x00ee, 0x0005, 0x2071, 0x1800, 0x9016, 0x702c, 0x2148, 0xa904,
-	0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70bc, 0x9200,
-	0x70be, 0x080c, 0x81f0, 0x0e04, 0x6cb7, 0x2071, 0x190e, 0x701c,
-	0x2048, 0xa84c, 0x900d, 0x0d18, 0x2071, 0x0000, 0x7182, 0xa850,
-	0x7032, 0xa86c, 0x7086, 0x7036, 0xa870, 0x708a, 0x2091, 0x4080,
-	0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11e0, 0x2071, 0x190e,
-	0x080c, 0x6e02, 0x002e, 0x00ee, 0x0005, 0x2071, 0x190e, 0xa803,
-	0x0000, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018, 0x904d, 0x711a,
-	0x0110, 0xa902, 0x0008, 0x711e, 0x2148, 0xa804, 0x900d, 0x1118,
-	0x002e, 0x00ee, 0x0005, 0x2071, 0x1800, 0x9016, 0x702c, 0x2148,
+	0x1dc8, 0x702e, 0x70bc, 0x9200, 0x70be, 0x080c, 0x8170, 0x00fe,
+	0x002e, 0x00ee, 0x0005, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018,
+	0x904d, 0x711a, 0x0110, 0xa902, 0x0008, 0x711e, 0x2148, 0xa804,
+	0x900d, 0x1904, 0x6be2, 0x782c, 0x9094, 0x0780, 0x190c, 0x6d6b,
+	0xd09c, 0x11b0, 0x701c, 0x904d, 0x0198, 0xa84c, 0x9005, 0x1180,
+	0x7010, 0x8001, 0x7012, 0x1108, 0x701a, 0xa800, 0x701e, 0x2900,
+	0x7822, 0x782c, 0x9094, 0x0780, 0x190c, 0x6d6b, 0xd09c, 0x0d50,
+	0x782c, 0x9094, 0x0780, 0x190c, 0x6d6b, 0xd0a4, 0x05b8, 0x00e6,
+	0x7824, 0x2048, 0x2071, 0x1800, 0x702c, 0xa802, 0x2900, 0x702e,
+	0x70bc, 0x8000, 0x70be, 0x080c, 0x8170, 0x782c, 0x9094, 0x0780,
+	0x190c, 0x6d6b, 0xd0a4, 0x1d60, 0x00ee, 0x0e04, 0x6bdb, 0x7838,
+	0x7938, 0x910e, 0x1de0, 0x00d6, 0x2069, 0x0000, 0x6836, 0x6833,
+	0x0013, 0x00de, 0x7044, 0xc084, 0x7046, 0x2091, 0x4080, 0x2001,
+	0x0089, 0x2004, 0xd084, 0x190c, 0x11f2, 0x704b, 0x0000, 0x00fe,
+	0x002e, 0x00ee, 0x0005, 0x7044, 0xc085, 0x7046, 0x00fe, 0x002e,
+	0x00ee, 0x0005, 0x00e6, 0x2071, 0x1800, 0x9016, 0x702c, 0x2148,
 	0xa904, 0xa802, 0x8210, 0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70bc,
-	0x9200, 0x70be, 0x080c, 0x81f0, 0x002e, 0x00ee, 0x0005, 0x0006,
-	0xa87c, 0x0006, 0xa867, 0x0103, 0x20a9, 0x001c, 0xa860, 0x20e8,
-	0xa85c, 0x9080, 0x001d, 0x20a0, 0x9006, 0x4004, 0x000e, 0x9084,
-	0x00ff, 0xa87e, 0x000e, 0xa87a, 0xa982, 0x0005, 0x2071, 0x190e,
-	0x7004, 0x0002, 0x6d3a, 0x6d3b, 0x6e01, 0x6d3b, 0x6d38, 0x6e01,
-	0x080c, 0x0dfa, 0x0005, 0x2001, 0x1921, 0x2004, 0x0002, 0x6d45,
-	0x6d45, 0x6d9a, 0x6d9b, 0x6d45, 0x6d9b, 0x0126, 0x2091, 0x8000,
-	0x1e0c, 0x6e21, 0x701c, 0x904d, 0x01e0, 0xa84c, 0x9005, 0x01d8,
-	0x0e04, 0x6d69, 0xa94c, 0x2071, 0x0000, 0x7182, 0xa850, 0x7032,
-	0xa86c, 0x7086, 0x7036, 0xa870, 0x708a, 0x2091, 0x4080, 0x2001,
-	0x0089, 0x2004, 0xd084, 0x190c, 0x11e0, 0x2071, 0x190e, 0x080c,
-	0x6e02, 0x012e, 0x0470, 0x2001, 0x005b, 0x2004, 0x9094, 0x0780,
-	0x190c, 0x6e16, 0xd09c, 0x2071, 0x190e, 0x1510, 0x2071, 0x190e,
-	0x700f, 0x0001, 0xa964, 0x9184, 0x00ff, 0x9086, 0x0003, 0x1130,
-	0x810f, 0x918c, 0x00ff, 0x8101, 0x0108, 0x710e, 0x2900, 0x00d6,
-	0x2069, 0x0050, 0x6822, 0x00de, 0x2071, 0x190e, 0x701c, 0x2048,
-	0x7010, 0x8001, 0x7012, 0xa800, 0x701e, 0x9005, 0x1108, 0x701a,
-	0x012e, 0x0005, 0x0005, 0x00d6, 0x2008, 0x2069, 0x19d2, 0x683c,
-	0x9005, 0x0760, 0x0158, 0x9186, 0x0003, 0x0540, 0x2001, 0x1814,
-	0x2004, 0x2009, 0x1aa2, 0x210c, 0x9102, 0x1500, 0x0126, 0x2091,
-	0x8000, 0x2069, 0x0050, 0x693c, 0x6838, 0x9106, 0x0190, 0x0e04,
-	0x6dcd, 0x2069, 0x0000, 0x6837, 0x8040, 0x6833, 0x0012, 0x6883,
-	0x8040, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084, 0x190c,
-	0x11e0, 0x2069, 0x19d2, 0x683f, 0xffff, 0x012e, 0x00de, 0x0126,
-	0x2091, 0x8000, 0x1e0c, 0x6e82, 0x701c, 0x904d, 0x0540, 0x2001,
-	0x005b, 0x2004, 0x9094, 0x0780, 0x15c9, 0xd09c, 0x1500, 0x2071,
-	0x190e, 0x700f, 0x0001, 0xa964, 0x9184, 0x00ff, 0x9086, 0x0003,
-	0x1130, 0x810f, 0x918c, 0x00ff, 0x8101, 0x0108, 0x710e, 0x2900,
-	0x00d6, 0x2069, 0x0050, 0x6822, 0x00de, 0x701c, 0x2048, 0x7010,
-	0x8001, 0x7012, 0xa800, 0x701e, 0x9005, 0x1108, 0x701a, 0x012e,
-	0x0005, 0x0005, 0x0126, 0x2091, 0x8000, 0x701c, 0x904d, 0x0160,
-	0x7010, 0x8001, 0x7012, 0xa800, 0x701e, 0x9005, 0x1108, 0x701a,
-	0x012e, 0x080c, 0x1063, 0x0005, 0x012e, 0x0005, 0x2091, 0x8000,
-	0x0e04, 0x6e18, 0x0006, 0x0016, 0x2001, 0x8004, 0x0006, 0x0804,
-	0x0e03, 0x0096, 0x00f6, 0x2079, 0x0050, 0x7044, 0xd084, 0x01c0,
-	0xc084, 0x7046, 0x7838, 0x7938, 0x910e, 0x1de0, 0x00d6, 0x2069,
-	0x0000, 0x6836, 0x6833, 0x0013, 0x00de, 0x2091, 0x4080, 0x2001,
-	0x0089, 0x2004, 0xd084, 0x190c, 0x11e0, 0x00fe, 0x009e, 0x0005,
-	0x782c, 0x9094, 0x0780, 0x1991, 0xd0a4, 0x0db8, 0x00e6, 0x2071,
-	0x1800, 0x7824, 0x00e6, 0x2071, 0x0040, 0x712c, 0xd19c, 0x1148,
-	0x2009, 0x182f, 0x210c, 0x918a, 0x0040, 0x0218, 0x7022, 0x00ee,
-	0x0058, 0x00ee, 0x2048, 0x702c, 0xa802, 0x2900, 0x702e, 0x70bc,
-	0x8000, 0x70be, 0x080c, 0x81f0, 0x782c, 0x9094, 0x0780, 0x190c,
-	0x6e16, 0xd0a4, 0x19f0, 0x7838, 0x7938, 0x910e, 0x1de0, 0x00d6,
-	0x2069, 0x0000, 0x6836, 0x6833, 0x0013, 0x00de, 0x2091, 0x4080,
-	0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11e0, 0x00ee, 0x00fe,
-	0x009e, 0x0005, 0x00f6, 0x2079, 0x0050, 0x7044, 0xd084, 0x01b8,
-	0xc084, 0x7046, 0x7838, 0x7938, 0x910e, 0x1de0, 0x00d6, 0x2069,
-	0x0000, 0x6836, 0x6833, 0x0013, 0x00de, 0x2091, 0x4080, 0x2001,
-	0x0089, 0x2004, 0xd084, 0x190c, 0x11e0, 0x00fe, 0x0005, 0x782c,
-	0x9094, 0x0780, 0x190c, 0x6e16, 0xd0a4, 0x0db8, 0x00e6, 0x2071,
-	0x1800, 0x7824, 0x2048, 0x702c, 0xa802, 0x2900, 0x702e, 0x70bc,
-	0x8000, 0x70be, 0x080c, 0x81f0, 0x782c, 0x9094, 0x0780, 0x190c,
-	0x6e16, 0xd0a4, 0x1d70, 0x00d6, 0x2069, 0x0050, 0x693c, 0x2069,
-	0x1921, 0x6808, 0x690a, 0x2069, 0x19d2, 0x9102, 0x1118, 0x683c,
-	0x9005, 0x1328, 0x2001, 0x1922, 0x200c, 0x810d, 0x693e, 0x00de,
-	0x00ee, 0x00fe, 0x0005, 0x7094, 0x908a, 0x0029, 0x1a0c, 0x0dfa,
-	0x9082, 0x001d, 0x001b, 0x6027, 0x1e00, 0x0005, 0x6faa, 0x6f30,
-	0x6f4c, 0x6f76, 0x6f99, 0x6fd9, 0x6feb, 0x6f4c, 0x6fc1, 0x6eeb,
-	0x6f19, 0x6eea, 0x0005, 0x00d6, 0x2069, 0x0200, 0x6804, 0x9005,
-	0x1180, 0x6808, 0x9005, 0x1518, 0x7097, 0x0028, 0x2069, 0x1967,
-	0x2d04, 0x7002, 0x080c, 0x7359, 0x6028, 0x9085, 0x0600, 0x602a,
-	0x00b0, 0x7097, 0x0028, 0x2069, 0x1967, 0x2d04, 0x7002, 0x6028,
-	0x9085, 0x0600, 0x602a, 0x00e6, 0x0036, 0x0046, 0x0056, 0x2071,
-	0x1a3a, 0x080c, 0x19ff, 0x005e, 0x004e, 0x003e, 0x00ee, 0x00de,
-	0x0005, 0x00d6, 0x2069, 0x0200, 0x6804, 0x9005, 0x1178, 0x6808,
-	0x9005, 0x1160, 0x7097, 0x0028, 0x2069, 0x1967, 0x2d04, 0x7002,
-	0x080c, 0x73f3, 0x6028, 0x9085, 0x0600, 0x602a, 0x00de, 0x0005,
-	0x0006, 0x2001, 0x0090, 0x080c, 0x2c88, 0x000e, 0x6124, 0xd1e4,
-	0x1190, 0x080c, 0x7058, 0xd1d4, 0x1160, 0xd1dc, 0x1138, 0xd1cc,
-	0x0150, 0x7097, 0x0020, 0x080c, 0x7058, 0x0028, 0x7097, 0x001d,
-	0x0010, 0x7097, 0x001f, 0x0005, 0x2001, 0x0088, 0x080c, 0x2c88,
-	0x6124, 0xd1cc, 0x11e8, 0xd1dc, 0x11c0, 0xd1e4, 0x1198, 0x9184,
-	0x1e00, 0x11d8, 0x080c, 0x1a24, 0x60e3, 0x0001, 0x600c, 0xc0b4,
-	0x600e, 0x080c, 0x7233, 0x2001, 0x0080, 0x080c, 0x2c88, 0x7097,
-	0x0028, 0x0058, 0x7097, 0x001e, 0x0040, 0x7097, 0x001d, 0x0028,
-	0x7097, 0x0020, 0x0010, 0x7097, 0x001f, 0x0005, 0x080c, 0x1a24,
-	0x60e3, 0x0001, 0x600c, 0xc0b4, 0x600e, 0x080c, 0x7233, 0x2001,
-	0x0080, 0x080c, 0x2c88, 0x6124, 0xd1d4, 0x1180, 0xd1dc, 0x1158,
-	0xd1e4, 0x1130, 0x9184, 0x1e00, 0x1158, 0x7097, 0x0028, 0x0040,
+	0x9200, 0x70be, 0x080c, 0x8170, 0x00ee, 0x0804, 0x6b83, 0x2071,
+	0x190e, 0xa803, 0x0000, 0x2908, 0x7010, 0x8000, 0x7012, 0x7018,
+	0x904d, 0x711a, 0x0110, 0xa902, 0x0008, 0x711e, 0x2148, 0xa804,
+	0x900d, 0x1128, 0x1e04, 0x6c22, 0x002e, 0x00ee, 0x0005, 0x2071,
+	0x1800, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210, 0x2900,
+	0x81ff, 0x1dc8, 0x702e, 0x70bc, 0x9200, 0x70be, 0x080c, 0x8170,
+	0x0e04, 0x6c0c, 0x2071, 0x190e, 0x701c, 0x2048, 0xa84c, 0x900d,
+	0x0d18, 0x2071, 0x0000, 0x7182, 0xa850, 0x7032, 0xa86c, 0x7086,
+	0x7036, 0xa870, 0x708a, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004,
+	0xd084, 0x190c, 0x11f2, 0x2071, 0x190e, 0x080c, 0x6d57, 0x002e,
+	0x00ee, 0x0005, 0x2071, 0x190e, 0xa803, 0x0000, 0x2908, 0x7010,
+	0x8000, 0x7012, 0x7018, 0x904d, 0x711a, 0x0110, 0xa902, 0x0008,
+	0x711e, 0x2148, 0xa804, 0x900d, 0x1118, 0x002e, 0x00ee, 0x0005,
+	0x2071, 0x1800, 0x9016, 0x702c, 0x2148, 0xa904, 0xa802, 0x8210,
+	0x2900, 0x81ff, 0x1dc8, 0x702e, 0x70bc, 0x9200, 0x70be, 0x080c,
+	0x8170, 0x002e, 0x00ee, 0x0005, 0x0006, 0xa87c, 0x0006, 0xa867,
+	0x0103, 0x20a9, 0x001c, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x001d,
+	0x20a0, 0x9006, 0x4004, 0x000e, 0x9084, 0x00ff, 0xa87e, 0x000e,
+	0xa87a, 0xa982, 0x0005, 0x2071, 0x190e, 0x7004, 0x0002, 0x6c8f,
+	0x6c90, 0x6d56, 0x6c90, 0x6c8d, 0x6d56, 0x080c, 0x0e02, 0x0005,
+	0x2001, 0x1923, 0x2004, 0x0002, 0x6c9a, 0x6c9a, 0x6cef, 0x6cf0,
+	0x6c9a, 0x6cf0, 0x0126, 0x2091, 0x8000, 0x1e0c, 0x6d76, 0x701c,
+	0x904d, 0x01e0, 0xa84c, 0x9005, 0x01d8, 0x0e04, 0x6cbe, 0xa94c,
+	0x2071, 0x0000, 0x7182, 0xa850, 0x7032, 0xa86c, 0x7086, 0x7036,
+	0xa870, 0x708a, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084,
+	0x190c, 0x11f2, 0x2071, 0x190e, 0x080c, 0x6d57, 0x012e, 0x0470,
+	0x2001, 0x005b, 0x2004, 0x9094, 0x0780, 0x190c, 0x6d6b, 0xd09c,
+	0x2071, 0x190e, 0x1510, 0x2071, 0x190e, 0x700f, 0x0001, 0xa964,
+	0x9184, 0x00ff, 0x9086, 0x0003, 0x1130, 0x810f, 0x918c, 0x00ff,
+	0x8101, 0x0108, 0x710e, 0x2900, 0x00d6, 0x2069, 0x0050, 0x6822,
+	0x00de, 0x2071, 0x190e, 0x701c, 0x2048, 0x7010, 0x8001, 0x7012,
+	0xa800, 0x701e, 0x9005, 0x1108, 0x701a, 0x012e, 0x0005, 0x0005,
+	0x00d6, 0x2008, 0x2069, 0x19d5, 0x6844, 0x9005, 0x0760, 0x0158,
+	0x9186, 0x0003, 0x0540, 0x2001, 0x1814, 0x2004, 0x2009, 0x1aa2,
+	0x210c, 0x9102, 0x1500, 0x0126, 0x2091, 0x8000, 0x2069, 0x0050,
+	0x693c, 0x6838, 0x9106, 0x0190, 0x0e04, 0x6d22, 0x2069, 0x0000,
+	0x6837, 0x8040, 0x6833, 0x0012, 0x6883, 0x8040, 0x2091, 0x4080,
+	0x2001, 0x0089, 0x2004, 0xd084, 0x190c, 0x11f2, 0x2069, 0x19d5,
+	0x6847, 0xffff, 0x012e, 0x00de, 0x0126, 0x2091, 0x8000, 0x1e0c,
+	0x6de1, 0x701c, 0x904d, 0x0540, 0x2001, 0x005b, 0x2004, 0x9094,
+	0x0780, 0x15c9, 0xd09c, 0x1500, 0x2071, 0x190e, 0x700f, 0x0001,
+	0xa964, 0x9184, 0x00ff, 0x9086, 0x0003, 0x1130, 0x810f, 0x918c,
+	0x00ff, 0x8101, 0x0108, 0x710e, 0x2900, 0x00d6, 0x2069, 0x0050,
+	0x6822, 0x00de, 0x701c, 0x2048, 0x7010, 0x8001, 0x7012, 0xa800,
+	0x701e, 0x9005, 0x1108, 0x701a, 0x012e, 0x0005, 0x0005, 0x0126,
+	0x2091, 0x8000, 0x701c, 0x904d, 0x0160, 0x7010, 0x8001, 0x7012,
+	0xa800, 0x701e, 0x9005, 0x1108, 0x701a, 0x012e, 0x080c, 0x1075,
+	0x0005, 0x012e, 0x0005, 0x2091, 0x8000, 0x0e04, 0x6d6d, 0x0006,
+	0x0016, 0x2001, 0x8004, 0x0006, 0x0804, 0x0e0b, 0x0096, 0x00f6,
+	0x2079, 0x0050, 0x7044, 0xd084, 0x01d0, 0xc084, 0x7046, 0x7838,
+	0x7938, 0x910e, 0x1de0, 0x00d6, 0x2069, 0x0000, 0x6836, 0x6833,
+	0x0013, 0x00de, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004, 0xd084,
+	0x190c, 0x11f2, 0x704b, 0x0000, 0x00fe, 0x009e, 0x0005, 0x782c,
+	0x9094, 0x0780, 0x1981, 0xd0a4, 0x0db8, 0x7148, 0x704c, 0x8108,
+	0x714a, 0x9102, 0x0e88, 0x00e6, 0x2071, 0x1800, 0x7824, 0x00e6,
+	0x2071, 0x0040, 0x712c, 0xd19c, 0x1148, 0x2009, 0x182f, 0x210c,
+	0x918a, 0x0040, 0x0218, 0x7022, 0x00ee, 0x0058, 0x00ee, 0x2048,
+	0x702c, 0xa802, 0x2900, 0x702e, 0x70bc, 0x8000, 0x70be, 0x080c,
+	0x8170, 0x782c, 0x9094, 0x0780, 0x190c, 0x6d6b, 0xd0a4, 0x19f0,
+	0x7838, 0x7938, 0x910e, 0x1de0, 0x00d6, 0x2069, 0x0000, 0x6836,
+	0x6833, 0x0013, 0x00de, 0x2091, 0x4080, 0x2001, 0x0089, 0x2004,
+	0xd084, 0x190c, 0x11f2, 0x00ee, 0x704b, 0x0000, 0x00fe, 0x009e,
+	0x0005, 0x00f6, 0x2079, 0x0050, 0x7044, 0xd084, 0x01b8, 0xc084,
+	0x7046, 0x7838, 0x7938, 0x910e, 0x1de0, 0x00d6, 0x2069, 0x0000,
+	0x6836, 0x6833, 0x0013, 0x00de, 0x2091, 0x4080, 0x2001, 0x0089,
+	0x2004, 0xd084, 0x190c, 0x11f2, 0x00fe, 0x0005, 0x782c, 0x9094,
+	0x0780, 0x190c, 0x6d6b, 0xd0a4, 0x0db8, 0x00e6, 0x2071, 0x1800,
+	0x7824, 0x2048, 0x702c, 0xa802, 0x2900, 0x702e, 0x70bc, 0x8000,
+	0x70be, 0x080c, 0x8170, 0x782c, 0x9094, 0x0780, 0x190c, 0x6d6b,
+	0xd0a4, 0x1d70, 0x00d6, 0x2069, 0x0050, 0x693c, 0x2069, 0x1923,
+	0x6808, 0x690a, 0x2069, 0x19d5, 0x9102, 0x1118, 0x6844, 0x9005,
+	0x1320, 0x2001, 0x1924, 0x200c, 0x6946, 0x00de, 0x00ee, 0x00fe,
+	0x0005, 0x7094, 0x908a, 0x002a, 0x1a0c, 0x0e02, 0x9082, 0x001d,
+	0x001b, 0x6027, 0x1e00, 0x0005, 0x6f22, 0x6e8f, 0x6eab, 0x6ed5,
+	0x6f11, 0x6f51, 0x6f63, 0x6eab, 0x6f39, 0x6e4a, 0x6e78, 0x6efb,
+	0x6e49, 0x0005, 0x00d6, 0x2069, 0x0200, 0x6804, 0x9005, 0x1180,
+	0x6808, 0x9005, 0x1518, 0x7097, 0x0029, 0x2069, 0x1969, 0x2d04,
+	0x7002, 0x080c, 0x72ce, 0x6028, 0x9085, 0x0600, 0x602a, 0x00b0,
+	0x7097, 0x0029, 0x2069, 0x1969, 0x2d04, 0x7002, 0x6028, 0x9085,
+	0x0600, 0x602a, 0x00e6, 0x0036, 0x0046, 0x0056, 0x2071, 0x1a3f,
+	0x080c, 0x1983, 0x005e, 0x004e, 0x003e, 0x00ee, 0x00de, 0x0005,
+	0x00d6, 0x2069, 0x0200, 0x6804, 0x9005, 0x1178, 0x6808, 0x9005,
+	0x1160, 0x7097, 0x0029, 0x2069, 0x1969, 0x2d04, 0x7002, 0x080c,
+	0x736a, 0x6028, 0x9085, 0x0600, 0x602a, 0x00de, 0x0005, 0x0006,
+	0x2001, 0x0090, 0x080c, 0x2b88, 0x000e, 0x6124, 0xd1e4, 0x1190,
+	0x080c, 0x6fd0, 0xd1d4, 0x1160, 0xd1dc, 0x1138, 0xd1cc, 0x0150,
+	0x7097, 0x0020, 0x080c, 0x6fd0, 0x0028, 0x7097, 0x001d, 0x0010,
+	0x7097, 0x001f, 0x0005, 0x2001, 0x0088, 0x080c, 0x2b88, 0x6124,
+	0xd1cc, 0x11e8, 0xd1dc, 0x11c0, 0xd1e4, 0x1198, 0x9184, 0x1e00,
+	0x11d8, 0x080c, 0x19a8, 0x60e3, 0x0001, 0x600c, 0xc0b4, 0x600e,
+	0x080c, 0x71ab, 0x2001, 0x0080, 0x080c, 0x2b88, 0x7097, 0x0029,
+	0x0058, 0x7097, 0x001e, 0x0040, 0x7097, 0x001d, 0x0028, 0x7097,
+	0x0020, 0x0010, 0x7097, 0x001f, 0x0005, 0x080c, 0x19a8, 0x60e3,
+	0x0001, 0x600c, 0xc0b4, 0x600e, 0x080c, 0x71ab, 0x2001, 0x0080,
+	0x080c, 0x2b88, 0x6124, 0xd1d4, 0x1198, 0xd1dc, 0x1170, 0xd1e4,
+	0x1148, 0x9184, 0x1e00, 0x1118, 0x7097, 0x0029, 0x0058, 0x7097,
+	0x0028, 0x0040, 0x7097, 0x001e, 0x0028, 0x7097, 0x001d, 0x0010,
+	0x7097, 0x001f, 0x0005, 0x6124, 0xd1d4, 0x1180, 0xd1dc, 0x1158,
+	0xd1e4, 0x1130, 0x9184, 0x1e00, 0x1158, 0x7097, 0x0029, 0x0040,
 	0x7097, 0x001e, 0x0028, 0x7097, 0x001d, 0x0010, 0x7097, 0x001f,
-	0x0005, 0x2001, 0x00a0, 0x080c, 0x2c88, 0x6124, 0xd1dc, 0x1138,
-	0xd1e4, 0x0138, 0x080c, 0x1a24, 0x7097, 0x001e, 0x0010, 0x7097,
-	0x001d, 0x0005, 0x080c, 0x70db, 0x6124, 0xd1dc, 0x1188, 0x080c,
-	0x7058, 0x0016, 0x080c, 0x1a24, 0x001e, 0xd1d4, 0x1128, 0xd1e4,
-	0x0138, 0x7097, 0x001e, 0x0020, 0x7097, 0x001f, 0x080c, 0x7058,
-	0x0005, 0x0006, 0x2001, 0x00a0, 0x080c, 0x2c88, 0x000e, 0x6124,
+	0x0005, 0x2001, 0x00a0, 0x080c, 0x2b88, 0x6124, 0xd1dc, 0x1138,
+	0xd1e4, 0x0138, 0x080c, 0x19a8, 0x7097, 0x001e, 0x0010, 0x7097,
+	0x001d, 0x0005, 0x080c, 0x7053, 0x6124, 0xd1dc, 0x1188, 0x080c,
+	0x6fd0, 0x0016, 0x080c, 0x19a8, 0x001e, 0xd1d4, 0x1128, 0xd1e4,
+	0x0138, 0x7097, 0x001e, 0x0020, 0x7097, 0x001f, 0x080c, 0x6fd0,
+	0x0005, 0x0006, 0x2001, 0x00a0, 0x080c, 0x2b88, 0x000e, 0x6124,
 	0xd1d4, 0x1160, 0xd1cc, 0x1150, 0xd1dc, 0x1128, 0xd1e4, 0x0140,
 	0x7097, 0x001e, 0x0028, 0x7097, 0x001d, 0x0010, 0x7097, 0x0021,
-	0x0005, 0x080c, 0x70db, 0x6124, 0xd1d4, 0x1150, 0xd1dc, 0x1128,
+	0x0005, 0x080c, 0x7053, 0x6124, 0xd1d4, 0x1150, 0xd1dc, 0x1128,
 	0xd1e4, 0x0140, 0x7097, 0x001e, 0x0028, 0x7097, 0x001d, 0x0010,
-	0x7097, 0x001f, 0x0005, 0x0006, 0x2001, 0x0090, 0x080c, 0x2c88,
+	0x7097, 0x001f, 0x0005, 0x0006, 0x2001, 0x0090, 0x080c, 0x2b88,
 	0x000e, 0x6124, 0xd1d4, 0x1178, 0xd1cc, 0x1150, 0xd1dc, 0x1128,
 	0xd1e4, 0x0158, 0x7097, 0x001e, 0x0040, 0x7097, 0x001d, 0x0028,
 	0x7097, 0x0020, 0x0010, 0x7097, 0x001f, 0x0005, 0x0016, 0x00c6,
 	0x00d6, 0x00e6, 0x0126, 0x2061, 0x0100, 0x2069, 0x0140, 0x2071,
-	0x1800, 0x2091, 0x8000, 0x080c, 0x7207, 0x11d8, 0x2001, 0x180c,
+	0x1800, 0x2091, 0x8000, 0x080c, 0x717f, 0x11d8, 0x2001, 0x180c,
 	0x200c, 0xd1b4, 0x01b0, 0xc1b4, 0x2102, 0x6027, 0x0200, 0x080c,
-	0x2bb0, 0x6024, 0xd0cc, 0x0148, 0x2001, 0x00a0, 0x080c, 0x2c88,
-	0x080c, 0x7504, 0x080c, 0x5f2b, 0x0428, 0x6028, 0xc0cd, 0x602a,
-	0x0408, 0x080c, 0x7221, 0x0150, 0x080c, 0x7218, 0x1138, 0x2001,
-	0x0001, 0x080c, 0x2717, 0x080c, 0x71df, 0x00a0, 0x080c, 0x70d8,
-	0x0178, 0x2001, 0x0001, 0x080c, 0x2717, 0x7094, 0x9086, 0x001e,
+	0x2ab0, 0x6024, 0xd0cc, 0x0148, 0x2001, 0x00a0, 0x080c, 0x2b88,
+	0x080c, 0x747b, 0x080c, 0x5e30, 0x0428, 0x6028, 0xc0cd, 0x602a,
+	0x0408, 0x080c, 0x7199, 0x0150, 0x080c, 0x7190, 0x1138, 0x2001,
+	0x0001, 0x080c, 0x2617, 0x080c, 0x7157, 0x00a0, 0x080c, 0x7050,
+	0x0178, 0x2001, 0x0001, 0x080c, 0x2617, 0x7094, 0x9086, 0x001e,
 	0x0120, 0x7094, 0x9086, 0x0022, 0x1118, 0x7097, 0x0025, 0x0010,
 	0x7097, 0x0021, 0x012e, 0x00ee, 0x00de, 0x00ce, 0x001e, 0x0005,
-	0x0026, 0x2011, 0x7069, 0x080c, 0x83ae, 0x002e, 0x0016, 0x0026,
-	0x2009, 0x0064, 0x2011, 0x7069, 0x080c, 0x83a5, 0x002e, 0x001e,
-	0x0005, 0x00e6, 0x00f6, 0x0016, 0x080c, 0x9656, 0x2071, 0x1800,
-	0x080c, 0x7006, 0x001e, 0x00fe, 0x00ee, 0x0005, 0x0016, 0x0026,
-	0x0036, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x0126, 0x080c, 0x9656,
-	0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0x1800, 0x2091, 0x8000,
-	0x6028, 0xc09c, 0x602a, 0x2011, 0x0003, 0x080c, 0x9a0f, 0x2011,
-	0x0002, 0x080c, 0x9a19, 0x080c, 0x9927, 0x080c, 0x835a, 0x0036,
-	0x901e, 0x080c, 0x999d, 0x003e, 0x60e3, 0x0000, 0x080c, 0xdc13,
-	0x080c, 0xdc2e, 0x2009, 0x0004, 0x080c, 0x2bb6, 0x080c, 0x2a89,
-	0x2001, 0x1800, 0x2003, 0x0004, 0x6027, 0x0008, 0x2011, 0x7069,
-	0x080c, 0x83ae, 0x080c, 0x7221, 0x0118, 0x9006, 0x080c, 0x2c88,
-	0x080c, 0x0b8f, 0x2001, 0x0001, 0x080c, 0x2717, 0x012e, 0x00fe,
+	0x0026, 0x2011, 0x6fe1, 0x080c, 0x832e, 0x002e, 0x0016, 0x0026,
+	0x2009, 0x0064, 0x2011, 0x6fe1, 0x080c, 0x8325, 0x002e, 0x001e,
+	0x0005, 0x00e6, 0x00f6, 0x0016, 0x080c, 0x9605, 0x2071, 0x1800,
+	0x080c, 0x6f7e, 0x001e, 0x00fe, 0x00ee, 0x0005, 0x0016, 0x0026,
+	0x0036, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x0126, 0x2071, 0x1800,
+	0x080c, 0x9605, 0x2061, 0x0100, 0x2069, 0x0140, 0x2091, 0x8000,
+	0x6028, 0xc09c, 0x602a, 0x2011, 0x0003, 0x080c, 0x990e, 0x2011,
+	0x0002, 0x080c, 0x9918, 0x080c, 0x9826, 0x080c, 0x82da, 0x0036,
+	0x901e, 0x080c, 0x989c, 0x003e, 0x60e3, 0x0000, 0x080c, 0xdb7a,
+	0x080c, 0xdb95, 0x2009, 0x0004, 0x080c, 0x2ab6, 0x080c, 0x2989,
+	0x2001, 0x1800, 0x2003, 0x0004, 0x6027, 0x0008, 0x2011, 0x6fe1,
+	0x080c, 0x832e, 0x080c, 0x7199, 0x0118, 0x9006, 0x080c, 0x2b88,
+	0x080c, 0x0b8f, 0x2001, 0x0001, 0x080c, 0x2617, 0x012e, 0x00fe,
 	0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e, 0x001e, 0x0005, 0x0026,
-	0x00e6, 0x2011, 0x7076, 0x2071, 0x19d2, 0x701c, 0x9206, 0x1118,
+	0x00e6, 0x2011, 0x6fee, 0x2071, 0x19d5, 0x701c, 0x9206, 0x1118,
 	0x7018, 0x9005, 0x0110, 0x9085, 0x0001, 0x00ee, 0x002e, 0x0005,
 	0x6020, 0xd09c, 0x0005, 0x6800, 0x9084, 0xfffe, 0x9086, 0x00c0,
-	0x01b8, 0x2001, 0x00c0, 0x080c, 0x2c88, 0x0156, 0x20a9, 0x002d,
-	0x1d04, 0x70e8, 0x2091, 0x6000, 0x1f04, 0x70e8, 0x015e, 0x00d6,
+	0x01b8, 0x2001, 0x00c0, 0x080c, 0x2b88, 0x0156, 0x20a9, 0x002d,
+	0x1d04, 0x7060, 0x2091, 0x6000, 0x1f04, 0x7060, 0x015e, 0x00d6,
 	0x2069, 0x1800, 0x6898, 0x8001, 0x0220, 0x0118, 0x689a, 0x00de,
 	0x0005, 0x689b, 0x0014, 0x68e4, 0xd0dc, 0x0dc8, 0x6800, 0x9086,
-	0x0001, 0x1da8, 0x080c, 0x83ba, 0x0c90, 0x00c6, 0x00d6, 0x00e6,
-	0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0x1800, 0x080c, 0x7513,
-	0x2001, 0x1945, 0x2003, 0x0000, 0x9006, 0x7096, 0x60e2, 0x6886,
-	0x080c, 0x27e2, 0x9006, 0x080c, 0x2c88, 0x080c, 0x5dea, 0x6027,
+	0x0001, 0x1da8, 0x080c, 0x833a, 0x0c90, 0x00c6, 0x00d6, 0x00e6,
+	0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0x1800, 0x080c, 0x748a,
+	0x2001, 0x1947, 0x2003, 0x0000, 0x9006, 0x7096, 0x60e2, 0x6886,
+	0x080c, 0x26e2, 0x9006, 0x080c, 0x2b88, 0x080c, 0x5cef, 0x6027,
 	0xffff, 0x602b, 0x182f, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x00c6,
 	0x00d6, 0x00e6, 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0x1800,
-	0x2001, 0x1955, 0x200c, 0x9186, 0x0000, 0x0158, 0x9186, 0x0001,
+	0x2001, 0x1957, 0x200c, 0x9186, 0x0000, 0x0158, 0x9186, 0x0001,
 	0x0158, 0x9186, 0x0002, 0x0158, 0x9186, 0x0003, 0x0158, 0x0804,
-	0x71cf, 0x7097, 0x0022, 0x0040, 0x7097, 0x0021, 0x0028, 0x7097,
+	0x7147, 0x7097, 0x0022, 0x0040, 0x7097, 0x0021, 0x0028, 0x7097,
 	0x0023, 0x0010, 0x7097, 0x0024, 0x60e3, 0x0000, 0x6887, 0x0001,
-	0x2001, 0x0001, 0x080c, 0x27e2, 0x0026, 0x080c, 0xa069, 0x002e,
+	0x2001, 0x0001, 0x080c, 0x26e2, 0x0026, 0x080c, 0x9f5b, 0x002e,
 	0x7000, 0x908e, 0x0004, 0x0118, 0x602b, 0x0028, 0x0010, 0x602b,
 	0x0020, 0x0156, 0x0126, 0x2091, 0x8000, 0x20a9, 0x0005, 0x6024,
-	0xd0ac, 0x0150, 0x012e, 0x015e, 0x080c, 0xc539, 0x0118, 0x9006,
-	0x080c, 0x2cb2, 0x0804, 0x71db, 0x6800, 0x9084, 0x00a1, 0xc0bd,
-	0x6802, 0x080c, 0x2bb0, 0x6904, 0xd1d4, 0x1140, 0x2001, 0x0100,
-	0x080c, 0x2c88, 0x1f04, 0x7167, 0x080c, 0x725e, 0x012e, 0x015e,
-	0x080c, 0x7218, 0x0538, 0x6044, 0x9005, 0x01f8, 0x2001, 0x0100,
+	0xd0ac, 0x0150, 0x012e, 0x015e, 0x080c, 0xc444, 0x0118, 0x9006,
+	0x080c, 0x2bb2, 0x0804, 0x7153, 0x6800, 0x9084, 0x00a1, 0xc0bd,
+	0x6802, 0x080c, 0x2ab0, 0x6904, 0xd1d4, 0x1140, 0x2001, 0x0100,
+	0x080c, 0x2b88, 0x1f04, 0x70df, 0x080c, 0x71d3, 0x012e, 0x015e,
+	0x080c, 0x7190, 0x0538, 0x6044, 0x9005, 0x01f8, 0x2001, 0x0100,
 	0x2004, 0x9086, 0x000a, 0x0158, 0x2011, 0x0114, 0x2204, 0x9085,
 	0x0100, 0x2012, 0x6050, 0x0006, 0x9085, 0x0020, 0x6052, 0x080c,
-	0x725e, 0x9006, 0x8001, 0x1df0, 0x2001, 0x0100, 0x2004, 0x9086,
+	0x71d3, 0x9006, 0x8001, 0x1df0, 0x2001, 0x0100, 0x2004, 0x9086,
 	0x000a, 0x0140, 0x000e, 0x6052, 0x0028, 0x6804, 0xd0d4, 0x1110,
-	0x080c, 0x725e, 0x080c, 0xc539, 0x0118, 0x9006, 0x080c, 0x2cb2,
+	0x080c, 0x71d3, 0x080c, 0xc444, 0x0118, 0x9006, 0x080c, 0x2bb2,
 	0x0016, 0x0026, 0x7000, 0x908e, 0x0004, 0x0130, 0x2009, 0x00c8,
-	0x2011, 0x7076, 0x080c, 0x836c, 0x002e, 0x001e, 0x080c, 0x81e7,
-	0x7034, 0xc085, 0x7036, 0x2001, 0x1955, 0x2003, 0x0004, 0x080c,
-	0x6ed3, 0x080c, 0x7218, 0x0138, 0x6804, 0xd0d4, 0x1120, 0xd0dc,
-	0x1100, 0x080c, 0x7509, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x00c6,
+	0x2011, 0x6fee, 0x080c, 0x82ec, 0x002e, 0x001e, 0x080c, 0x8167,
+	0x7034, 0xc085, 0x7036, 0x2001, 0x1957, 0x2003, 0x0004, 0x080c,
+	0x6e31, 0x080c, 0x7190, 0x0138, 0x6804, 0xd0d4, 0x1120, 0xd0dc,
+	0x1100, 0x080c, 0x7480, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x00c6,
 	0x00d6, 0x00e6, 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0x1800,
-	0x080c, 0x81fe, 0x080c, 0x81f0, 0x080c, 0x7513, 0x2001, 0x1945,
-	0x2003, 0x0000, 0x9006, 0x7096, 0x60e2, 0x6886, 0x080c, 0x27e2,
-	0x9006, 0x080c, 0x2c88, 0x6043, 0x0090, 0x6043, 0x0010, 0x6027,
+	0x080c, 0x817e, 0x080c, 0x8170, 0x080c, 0x748a, 0x2001, 0x1947,
+	0x2003, 0x0000, 0x9006, 0x7096, 0x60e2, 0x6886, 0x080c, 0x26e2,
+	0x9006, 0x080c, 0x2b88, 0x6043, 0x0090, 0x6043, 0x0010, 0x6027,
 	0xffff, 0x602b, 0x182f, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x0006,
-	0x2001, 0x1954, 0x2004, 0x9086, 0xaaaa, 0x000e, 0x0005, 0x0006,
-	0x080c, 0x55df, 0x9084, 0x0030, 0x9086, 0x0000, 0x000e, 0x0005,
-	0x0006, 0x080c, 0x55df, 0x9084, 0x0030, 0x9086, 0x0030, 0x000e,
-	0x0005, 0x0006, 0x080c, 0x55df, 0x9084, 0x0030, 0x9086, 0x0010,
-	0x000e, 0x0005, 0x0006, 0x080c, 0x55df, 0x9084, 0x0030, 0x9086,
+	0x2001, 0x1956, 0x2004, 0x9086, 0xaaaa, 0x000e, 0x0005, 0x0006,
+	0x080c, 0x54e0, 0x9084, 0x0030, 0x9086, 0x0000, 0x000e, 0x0005,
+	0x0006, 0x080c, 0x54e0, 0x9084, 0x0030, 0x9086, 0x0030, 0x000e,
+	0x0005, 0x0006, 0x080c, 0x54e0, 0x9084, 0x0030, 0x9086, 0x0010,
+	0x000e, 0x0005, 0x0006, 0x080c, 0x54e0, 0x9084, 0x0030, 0x9086,
 	0x0020, 0x000e, 0x0005, 0x0036, 0x0016, 0x2001, 0x180c, 0x2004,
-	0x908c, 0x0013, 0x0180, 0x0020, 0x080c, 0x2802, 0x900e, 0x0028,
-	0x080c, 0x67bb, 0x1dc8, 0x2009, 0x0002, 0x2019, 0x0028, 0x080c,
-	0x3156, 0x9006, 0x0019, 0x001e, 0x003e, 0x0005, 0x00e6, 0x2071,
-	0x180c, 0x2e04, 0x0130, 0x080c, 0xc532, 0x1128, 0x9085, 0x0010,
-	0x0010, 0x9084, 0xffef, 0x2072, 0x00ee, 0x0005, 0x6050, 0x0006,
-	0x60ec, 0x0006, 0x600c, 0x0006, 0x6004, 0x0006, 0x6028, 0x0006,
-	0x2001, 0x0100, 0x2004, 0x9086, 0x000a, 0x0510, 0x0016, 0x6138,
-	0x6050, 0x9084, 0xfbff, 0x9085, 0x2000, 0x6052, 0x613a, 0x20a9,
-	0x0012, 0x1d04, 0x7279, 0x2091, 0x6000, 0x1f04, 0x7279, 0x602f,
-	0x0100, 0x602f, 0x0000, 0x6050, 0x9085, 0x0400, 0x9084, 0xdfff,
-	0x6052, 0x613a, 0x001e, 0x602f, 0x0040, 0x602f, 0x0000, 0x00a0,
-	0x080c, 0x2cc2, 0x080c, 0x2cf5, 0x602f, 0x0100, 0x602f, 0x0000,
-	0x602f, 0x0040, 0x602f, 0x0000, 0x20a9, 0x0002, 0x080c, 0x2b91,
-	0x0026, 0x6027, 0x0040, 0x002e, 0x000e, 0x602a, 0x000e, 0x6006,
-	0x000e, 0x600e, 0x000e, 0x60ee, 0x60e3, 0x0000, 0x6887, 0x0001,
-	0x2001, 0x0001, 0x080c, 0x27e2, 0x2001, 0x00a0, 0x0006, 0x080c,
-	0xc539, 0x000e, 0x0130, 0x080c, 0x2ca6, 0x9006, 0x080c, 0x2cb2,
-	0x0010, 0x080c, 0x2c88, 0x000e, 0x6052, 0x6050, 0x0006, 0xc0e5,
-	0x6052, 0x00f6, 0x2079, 0x0100, 0x080c, 0x2b06, 0x00fe, 0x000e,
-	0x6052, 0x0005, 0x0156, 0x0016, 0x0026, 0x0036, 0x00c6, 0x00d6,
-	0x00e6, 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0x1800, 0x6020,
-	0x9084, 0x0080, 0x0138, 0x2001, 0x180c, 0x200c, 0xc1c5, 0x2102,
-	0x0804, 0x734b, 0x2001, 0x180c, 0x200c, 0xc1c4, 0x2102, 0x6028,
-	0x9084, 0xe1ff, 0x602a, 0x6027, 0x0200, 0x2001, 0x0090, 0x080c,
-	0x2c88, 0x20a9, 0x0366, 0x6024, 0xd0cc, 0x1518, 0x1d04, 0x72fb,
-	0x2091, 0x6000, 0x1f04, 0x72fb, 0x2011, 0x0003, 0x080c, 0x9a0f,
-	0x2011, 0x0002, 0x080c, 0x9a19, 0x080c, 0x9927, 0x901e, 0x080c,
-	0x999d, 0x2001, 0x00a0, 0x080c, 0x2c88, 0x080c, 0x7504, 0x080c,
-	0x5f2b, 0x080c, 0xc539, 0x0110, 0x080c, 0x0d68, 0x9085, 0x0001,
-	0x0480, 0x080c, 0x1a24, 0x60e3, 0x0000, 0x2001, 0x0002, 0x080c,
-	0x27e2, 0x60e2, 0x2001, 0x0080, 0x080c, 0x2c88, 0x20a9, 0x0366,
-	0x6027, 0x1e00, 0x2009, 0x1e00, 0x080c, 0x2bb0, 0x6024, 0x910c,
-	0x0138, 0x1d04, 0x7330, 0x2091, 0x6000, 0x1f04, 0x7330, 0x0820,
-	0x6028, 0x9085, 0x1e00, 0x602a, 0x70b0, 0x9005, 0x1118, 0x6887,
-	0x0001, 0x0008, 0x6886, 0x080c, 0xc539, 0x0110, 0x080c, 0x0d68,
-	0x9006, 0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e, 0x001e, 0x015e,
-	0x0005, 0x0156, 0x0016, 0x0026, 0x0036, 0x00c6, 0x00d6, 0x00e6,
-	0x2061, 0x0100, 0x2071, 0x1800, 0x7000, 0x9086, 0x0003, 0x1168,
-	0x2001, 0x020b, 0x2004, 0x9084, 0x5540, 0x9086, 0x5540, 0x1128,
-	0x2069, 0x1a50, 0x2d04, 0x8000, 0x206a, 0x2069, 0x0140, 0x6020,
-	0x9084, 0x00c0, 0x0120, 0x6884, 0x9005, 0x1904, 0x73be, 0x2001,
-	0x0088, 0x080c, 0x2c88, 0x9006, 0x60e2, 0x6886, 0x080c, 0x27e2,
-	0x2069, 0x0200, 0x6804, 0x9005, 0x1118, 0x6808, 0x9005, 0x01c0,
-	0x6028, 0x9084, 0xfbff, 0x602a, 0x6027, 0x0400, 0x2069, 0x1967,
-	0x7000, 0x206a, 0x7097, 0x0026, 0x7003, 0x0001, 0x20a9, 0x0002,
-	0x1d04, 0x73a0, 0x2091, 0x6000, 0x1f04, 0x73a0, 0x0804, 0x73eb,
-	0x2069, 0x0140, 0x20a9, 0x0384, 0x6027, 0x1e00, 0x2009, 0x1e00,
-	0x080c, 0x2bb0, 0x6024, 0x910c, 0x0508, 0x9084, 0x1a00, 0x11f0,
-	0x1d04, 0x73ac, 0x2091, 0x6000, 0x1f04, 0x73ac, 0x2011, 0x0003,
-	0x080c, 0x9a0f, 0x2011, 0x0002, 0x080c, 0x9a19, 0x080c, 0x9927,
-	0x901e, 0x080c, 0x999d, 0x2001, 0x00a0, 0x080c, 0x2c88, 0x080c,
-	0x7504, 0x080c, 0x5f2b, 0x9085, 0x0001, 0x00a8, 0x2001, 0x0080,
-	0x080c, 0x2c88, 0x2069, 0x0140, 0x60e3, 0x0000, 0x70b0, 0x9005,
-	0x1118, 0x6887, 0x0001, 0x0008, 0x6886, 0x2001, 0x0002, 0x080c,
-	0x27e2, 0x60e2, 0x9006, 0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e,
-	0x001e, 0x015e, 0x0005, 0x0156, 0x0016, 0x0026, 0x0036, 0x00c6,
-	0x00d6, 0x00e6, 0x2061, 0x0100, 0x2071, 0x1800, 0x6020, 0x9084,
-	0x00c0, 0x01c8, 0x2011, 0x0003, 0x080c, 0x9a0f, 0x2011, 0x0002,
-	0x080c, 0x9a19, 0x080c, 0x9927, 0x901e, 0x080c, 0x999d, 0x2069,
-	0x0140, 0x2001, 0x00a0, 0x080c, 0x2c88, 0x080c, 0x7504, 0x080c,
-	0x5f2b, 0x0804, 0x7485, 0x2001, 0x180c, 0x200c, 0xd1b4, 0x1160,
-	0xc1b5, 0x2102, 0x080c, 0x705e, 0x2069, 0x0140, 0x2001, 0x0080,
-	0x080c, 0x2c88, 0x60e3, 0x0000, 0x2069, 0x0200, 0x6804, 0x9005,
-	0x1118, 0x6808, 0x9005, 0x0180, 0x6028, 0x9084, 0xfdff, 0x602a,
-	0x6027, 0x0200, 0x2069, 0x1967, 0x7000, 0x206a, 0x7097, 0x0027,
-	0x7003, 0x0001, 0x0804, 0x7485, 0x6027, 0x1e00, 0x2009, 0x1e00,
-	0x080c, 0x2bb0, 0x6024, 0x910c, 0x01c8, 0x9084, 0x1c00, 0x11b0,
-	0x1d04, 0x7444, 0x0006, 0x0016, 0x00c6, 0x00d6, 0x00e6, 0x080c,
-	0x823e, 0x00ee, 0x00de, 0x00ce, 0x001e, 0x000e, 0x00e6, 0x2071,
-	0x19d2, 0x7070, 0x00ee, 0x9005, 0x19f8, 0x00f8, 0x0026, 0x2011,
-	0x7076, 0x080c, 0x82da, 0x2011, 0x7069, 0x080c, 0x83ae, 0x002e,
-	0x2069, 0x0140, 0x60e3, 0x0000, 0x70b0, 0x9005, 0x1118, 0x6887,
-	0x0001, 0x0008, 0x6886, 0x2001, 0x0002, 0x080c, 0x27e2, 0x60e2,
-	0x2001, 0x180c, 0x200c, 0xc1b4, 0x2102, 0x00ee, 0x00de, 0x00ce,
-	0x003e, 0x002e, 0x001e, 0x015e, 0x0005, 0x0156, 0x0016, 0x0026,
-	0x0036, 0x0046, 0x00c6, 0x00e6, 0x2061, 0x0100, 0x2071, 0x1800,
-	0x080c, 0xc532, 0x1904, 0x74f2, 0x7130, 0xd184, 0x1170, 0x080c,
-	0x32e4, 0x0138, 0xc18d, 0x7132, 0x2011, 0x185c, 0x2214, 0xd2ac,
-	0x1120, 0x7030, 0xd08c, 0x0904, 0x74f2, 0x2011, 0x185c, 0x220c,
-	0x0438, 0x0016, 0x2019, 0x000e, 0x080c, 0xd801, 0x0156, 0x00b6,
-	0x20a9, 0x007f, 0x900e, 0x9186, 0x007e, 0x01a0, 0x9186, 0x0080,
-	0x0188, 0x080c, 0x649f, 0x1170, 0x2120, 0x9006, 0x0016, 0x2009,
-	0x000e, 0x080c, 0xd885, 0x2009, 0x0001, 0x2011, 0x0100, 0x080c,
-	0x84d1, 0x001e, 0x8108, 0x1f04, 0x74bb, 0x00be, 0x015e, 0x001e,
-	0xd1ac, 0x1148, 0x0016, 0x2009, 0x0002, 0x2019, 0x0004, 0x080c,
-	0x3156, 0x001e, 0x0078, 0x0156, 0x00b6, 0x20a9, 0x007f, 0x900e,
-	0x080c, 0x649f, 0x1110, 0x080c, 0x5f45, 0x8108, 0x1f04, 0x74e8,
-	0x00be, 0x015e, 0x080c, 0x1a24, 0x080c, 0xa069, 0x60e3, 0x0000,
-	0x080c, 0x5f2b, 0x080c, 0x7127, 0x00ee, 0x00ce, 0x004e, 0x003e,
-	0x002e, 0x001e, 0x015e, 0x0005, 0x2001, 0x1955, 0x2003, 0x0001,
-	0x0005, 0x2001, 0x1955, 0x2003, 0x0000, 0x0005, 0x2001, 0x1954,
-	0x2003, 0xaaaa, 0x0005, 0x2001, 0x1954, 0x2003, 0x0000, 0x0005,
-	0x2071, 0x18f8, 0x7003, 0x0000, 0x7007, 0x0000, 0x080c, 0x104a,
-	0x090c, 0x0dfa, 0xa8ab, 0xdcb0, 0x2900, 0x704e, 0x080c, 0x104a,
-	0x090c, 0x0dfa, 0xa8ab, 0xdcb0, 0x2900, 0x7052, 0xa867, 0x0000,
-	0xa86b, 0x0001, 0xa89f, 0x0000, 0x0005, 0x00e6, 0x2071, 0x0040,
-	0x6848, 0x9005, 0x1118, 0x9085, 0x0001, 0x04b0, 0x6840, 0x9005,
-	0x0150, 0x04a1, 0x6a50, 0x9200, 0x7002, 0x6854, 0x9101, 0x7006,
-	0x9006, 0x7012, 0x7016, 0x6850, 0x7002, 0x6854, 0x7006, 0x6858,
-	0x700a, 0x685c, 0x700e, 0x6840, 0x9005, 0x1110, 0x7012, 0x7016,
-	0x6848, 0x701a, 0x701c, 0x9085, 0x0040, 0x701e, 0x2001, 0x0019,
-	0x7036, 0x702b, 0x0001, 0x2001, 0x0004, 0x200c, 0x918c, 0xfff7,
-	0x918d, 0x8000, 0x2102, 0x00d6, 0x2069, 0x18f8, 0x6807, 0x0001,
-	0x00de, 0x080c, 0x7afd, 0x9006, 0x00ee, 0x0005, 0x900e, 0x0156,
-	0x20a9, 0x0006, 0x8003, 0x818d, 0x1f04, 0x757a, 0x015e, 0x0005,
-	0x2079, 0x0040, 0x2071, 0x18f8, 0x7004, 0x0002, 0x7590, 0x7591,
-	0x75c9, 0x7624, 0x7765, 0x758e, 0x758e, 0x778f, 0x080c, 0x0dfa,
-	0x0005, 0x2079, 0x0040, 0x782c, 0x908c, 0x0780, 0x190c, 0x7b89,
-	0xd0a4, 0x01f8, 0x7824, 0x2048, 0x9006, 0xa802, 0xa806, 0xa864,
-	0x9084, 0x00ff, 0x908a, 0x0040, 0x0610, 0x00c0, 0x2001, 0x1800,
-	0x200c, 0x9186, 0x0003, 0x1168, 0x7004, 0x0002, 0x75b9, 0x7593,
-	0x75b9, 0x75b7, 0x75b9, 0x75b9, 0x75b9, 0x75b9, 0x75b9, 0x080c,
-	0x7624, 0x782c, 0xd09c, 0x090c, 0x7afd, 0x0005, 0x9082, 0x005a,
-	0x1218, 0x2100, 0x003b, 0x0c10, 0x080c, 0x765a, 0x0c90, 0x00e3,
-	0x08e8, 0x0005, 0x765a, 0x765a, 0x765a, 0x765a, 0x765a, 0x765a,
-	0x765a, 0x765a, 0x767c, 0x765a, 0x765a, 0x765a, 0x765a, 0x765a,
-	0x765a, 0x765a, 0x765a, 0x765a, 0x765a, 0x765a, 0x765a, 0x765a,
-	0x765a, 0x765a, 0x765a, 0x765a, 0x765a, 0x765a, 0x7666, 0x765a,
-	0x7864, 0x765a, 0x765a, 0x765a, 0x767c, 0x765a, 0x7666, 0x78a5,
-	0x78e6, 0x792d, 0x7941, 0x765a, 0x765a, 0x767c, 0x7666, 0x765a,
-	0x765a, 0x7739, 0x79ec, 0x7a07, 0x765a, 0x767c, 0x765a, 0x765a,
-	0x765a, 0x765a, 0x772f, 0x7a07, 0x765a, 0x765a, 0x765a, 0x765a,
-	0x765a, 0x765a, 0x765a, 0x765a, 0x765a, 0x7690, 0x765a, 0x765a,
-	0x765a, 0x765a, 0x765a, 0x765a, 0x765a, 0x765a, 0x765a, 0x7b2d,
-	0x765a, 0x765a, 0x765a, 0x765a, 0x765a, 0x76a4, 0x765a, 0x765a,
-	0x765a, 0x765a, 0x765a, 0x765a, 0x2079, 0x0040, 0x7004, 0x9086,
-	0x0003, 0x1198, 0x782c, 0x080c, 0x7b26, 0xd0a4, 0x0170, 0x7824,
-	0x2048, 0x9006, 0xa802, 0xa806, 0xa864, 0x9084, 0x00ff, 0x908a,
-	0x001a, 0x1210, 0x002b, 0x0c50, 0x00e9, 0x080c, 0x7afd, 0x0005,
-	0x765a, 0x7666, 0x7850, 0x765a, 0x7666, 0x765a, 0x7666, 0x7666,
-	0x765a, 0x7666, 0x7850, 0x7666, 0x7666, 0x7666, 0x7666, 0x7666,
-	0x765a, 0x7666, 0x7850, 0x765a, 0x765a, 0x7666, 0x765a, 0x765a,
-	0x765a, 0x7666, 0x00e6, 0x2071, 0x18f8, 0x2009, 0x0400, 0x0071,
-	0x00ee, 0x0005, 0x2009, 0x1000, 0x0049, 0x0005, 0x2009, 0x2000,
-	0x0029, 0x0005, 0x2009, 0x0800, 0x0009, 0x0005, 0x7007, 0x0001,
-	0xa868, 0x9084, 0x00ff, 0x9105, 0xa86a, 0x0126, 0x2091, 0x8000,
-	0x080c, 0x6ae9, 0x012e, 0x0005, 0xa864, 0x8007, 0x9084, 0x00ff,
-	0x0d08, 0x8001, 0x1120, 0x7007, 0x0001, 0x0804, 0x780e, 0x7007,
-	0x0003, 0x7012, 0x2900, 0x7016, 0x701a, 0x704b, 0x780e, 0x0005,
-	0xa864, 0x8007, 0x9084, 0x00ff, 0x0968, 0x8001, 0x1120, 0x7007,
-	0x0001, 0x0804, 0x7829, 0x7007, 0x0003, 0x7012, 0x2900, 0x7016,
-	0x701a, 0x704b, 0x7829, 0x0005, 0xa864, 0x8007, 0x9084, 0x00ff,
-	0x9086, 0x0001, 0x1904, 0x7662, 0x7007, 0x0001, 0x2009, 0x1833,
-	0x210c, 0x81ff, 0x1904, 0x7706, 0xa994, 0x9186, 0x006f, 0x0188,
-	0x9186, 0x0074, 0x15b0, 0x0026, 0x2011, 0x0010, 0x080c, 0x67e7,
-	0x002e, 0x0578, 0x0016, 0xa998, 0x080c, 0x6831, 0x001e, 0x1548,
-	0x0400, 0x080c, 0x7207, 0x0140, 0xa897, 0x4005, 0xa89b, 0x0016,
-	0x2001, 0x0030, 0x900e, 0x0438, 0x0026, 0x2011, 0x8008, 0x080c,
-	0x67e7, 0x002e, 0x01b0, 0x0016, 0x0026, 0x0036, 0xa998, 0xaaa0,
-	0xab9c, 0x918d, 0x8000, 0x080c, 0x6831, 0x003e, 0x002e, 0x001e,
-	0x1140, 0xa897, 0x4005, 0xa89b, 0x4009, 0x2001, 0x0030, 0x900e,
-	0x0050, 0xa868, 0x9084, 0x00ff, 0xa86a, 0xa883, 0x0000, 0x080c,
-	0x615d, 0x1108, 0x0005, 0x0126, 0x2091, 0x8000, 0xa867, 0x0139,
-	0xa87a, 0xa982, 0x080c, 0x6ae9, 0x012e, 0x0ca0, 0xa994, 0x9186,
-	0x0071, 0x0904, 0x76b4, 0x9186, 0x0064, 0x0904, 0x76b4, 0x9186,
-	0x007c, 0x0904, 0x76b4, 0x9186, 0x0028, 0x0904, 0x76b4, 0x9186,
-	0x0038, 0x0904, 0x76b4, 0x9186, 0x0078, 0x0904, 0x76b4, 0x9186,
-	0x005f, 0x0904, 0x76b4, 0x9186, 0x0056, 0x0904, 0x76b4, 0xa897,
-	0x4005, 0xa89b, 0x0001, 0x2001, 0x0030, 0x900e, 0x0860, 0xa87c,
-	0x9084, 0x00c0, 0x9086, 0x00c0, 0x1120, 0x7007, 0x0001, 0x0804,
-	0x7a1e, 0x2900, 0x7016, 0x701a, 0x20a9, 0x0004, 0xa860, 0x20e0,
-	0xa85c, 0x9080, 0x0030, 0x2098, 0x7050, 0x2040, 0xa060, 0x20e8,
-	0xa05c, 0x9080, 0x0023, 0x20a0, 0x4003, 0xa888, 0x7012, 0x9082,
-	0x0401, 0x1a04, 0x766a, 0xaab4, 0x928a, 0x0002, 0x1a04, 0x766a,
-	0x82ff, 0x1138, 0xa8b8, 0xa9bc, 0x9105, 0x0118, 0x2001, 0x77cc,
-	0x0018, 0x9280, 0x77c2, 0x2005, 0x7056, 0x7010, 0x9015, 0x0904,
-	0x77ad, 0x080c, 0x104a, 0x1118, 0x7007, 0x0004, 0x0005, 0x2900,
-	0x7022, 0x7054, 0x2060, 0xe000, 0xa866, 0x7050, 0x2040, 0xa95c,
-	0xe004, 0x9100, 0xa076, 0xa860, 0xa072, 0xe008, 0x920a, 0x1210,
-	0x900e, 0x2200, 0x7112, 0xe20c, 0x8003, 0x800b, 0x9296, 0x0004,
-	0x0108, 0x9108, 0xa17a, 0x810b, 0xa17e, 0x080c, 0x112e, 0xa06c,
-	0x908e, 0x0100, 0x0170, 0x9086, 0x0200, 0x0118, 0x7007, 0x0007,
-	0x0005, 0x7020, 0x2048, 0x080c, 0x1063, 0x7014, 0x2048, 0x0804,
-	0x766a, 0x7020, 0x2048, 0x7018, 0xa802, 0xa807, 0x0000, 0x2908,
-	0x2048, 0xa906, 0x711a, 0x0804, 0x7765, 0x7014, 0x2048, 0x7007,
-	0x0001, 0xa8b4, 0x9005, 0x1128, 0xa8b8, 0xa9bc, 0x9105, 0x0108,
-	0x00b9, 0xa864, 0x9084, 0x00ff, 0x9086, 0x001e, 0x0904, 0x7a1e,
-	0x0804, 0x780e, 0x77c4, 0x77c8, 0x0002, 0x001d, 0x0007, 0x0004,
-	0x000a, 0x001b, 0x0005, 0x0006, 0x000a, 0x001d, 0x0005, 0x0004,
-	0x0076, 0x0066, 0xafb8, 0xaebc, 0xa804, 0x2050, 0xb0c0, 0xb0e2,
-	0xb0bc, 0xb0de, 0xb0b8, 0xb0d2, 0xb0b4, 0xb0ce, 0xb6da, 0xb7d6,
-	0xb0b0, 0xb0ca, 0xb0ac, 0xb0c6, 0xb0a8, 0xb0ba, 0xb0a4, 0xb0b6,
-	0xb6c2, 0xb7be, 0xb0a0, 0xb0b2, 0xb09c, 0xb0ae, 0xb098, 0xb0a2,
-	0xb094, 0xb09e, 0xb6aa, 0xb7a6, 0xb090, 0xb09a, 0xb08c, 0xb096,
-	0xb088, 0xb08a, 0xb084, 0xb086, 0xb692, 0xb78e, 0xb080, 0xb082,
-	0xb07c, 0xb07e, 0xb078, 0xb072, 0xb074, 0xb06e, 0xb67a, 0xb776,
-	0xb004, 0x9055, 0x1958, 0x006e, 0x007e, 0x0005, 0x2009, 0x1833,
-	0x210c, 0x81ff, 0x1178, 0x080c, 0x5fa7, 0x1108, 0x0005, 0x080c,
-	0x6d17, 0x0126, 0x2091, 0x8000, 0x080c, 0xc12d, 0x080c, 0x6ae9,
-	0x012e, 0x0ca0, 0x080c, 0xc532, 0x1d70, 0x2001, 0x0028, 0x900e,
-	0x0c70, 0x2009, 0x1833, 0x210c, 0x81ff, 0x11d8, 0xa888, 0x9005,
-	0x01e0, 0xa883, 0x0000, 0xa87c, 0xd0f4, 0x0120, 0x080c, 0x60bf,
-	0x1138, 0x0005, 0x9006, 0xa87a, 0x080c, 0x6037, 0x1108, 0x0005,
-	0x0126, 0x2091, 0x8000, 0xa87a, 0xa982, 0x080c, 0x6ae9, 0x012e,
+	0x908c, 0x0013, 0x0168, 0x0020, 0x080c, 0x2702, 0x900e, 0x0010,
+	0x2009, 0x0002, 0x2019, 0x0028, 0x080c, 0x3076, 0x9006, 0x0019,
+	0x001e, 0x003e, 0x0005, 0x00e6, 0x2071, 0x180c, 0x2e04, 0x0130,
+	0x080c, 0xc43d, 0x1128, 0x9085, 0x0010, 0x0010, 0x9084, 0xffef,
+	0x2072, 0x00ee, 0x0005, 0x6050, 0x0006, 0x60ec, 0x0006, 0x600c,
+	0x0006, 0x6004, 0x0006, 0x6028, 0x0006, 0x2001, 0x0100, 0x2004,
+	0x9086, 0x000a, 0x0510, 0x0016, 0x6138, 0x6050, 0x9084, 0xfbff,
+	0x9085, 0x2000, 0x6052, 0x613a, 0x20a9, 0x0012, 0x1d04, 0x71ee,
+	0x2091, 0x6000, 0x1f04, 0x71ee, 0x602f, 0x0100, 0x602f, 0x0000,
+	0x6050, 0x9085, 0x0400, 0x9084, 0xdfff, 0x6052, 0x613a, 0x001e,
+	0x602f, 0x0040, 0x602f, 0x0000, 0x00a0, 0x080c, 0x2bc2, 0x080c,
+	0x2bf5, 0x602f, 0x0100, 0x602f, 0x0000, 0x602f, 0x0040, 0x602f,
+	0x0000, 0x20a9, 0x0002, 0x080c, 0x2a91, 0x0026, 0x6027, 0x0040,
+	0x002e, 0x000e, 0x602a, 0x000e, 0x6006, 0x000e, 0x600e, 0x000e,
+	0x60ee, 0x60e3, 0x0000, 0x6887, 0x0001, 0x2001, 0x0001, 0x080c,
+	0x26e2, 0x2001, 0x00a0, 0x0006, 0x080c, 0xc444, 0x000e, 0x0130,
+	0x080c, 0x2ba6, 0x9006, 0x080c, 0x2bb2, 0x0010, 0x080c, 0x2b88,
+	0x000e, 0x6052, 0x6050, 0x0006, 0xc0e5, 0x6052, 0x00f6, 0x2079,
+	0x0100, 0x080c, 0x2a06, 0x00fe, 0x000e, 0x6052, 0x0005, 0x0156,
+	0x0016, 0x0026, 0x0036, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100,
+	0x2069, 0x0140, 0x2071, 0x1800, 0x6020, 0x9084, 0x0080, 0x0138,
+	0x2001, 0x180c, 0x200c, 0xc1c5, 0x2102, 0x0804, 0x72c0, 0x2001,
+	0x180c, 0x200c, 0xc1c4, 0x2102, 0x6028, 0x9084, 0xe1ff, 0x602a,
+	0x6027, 0x0200, 0x2001, 0x0090, 0x080c, 0x2b88, 0x20a9, 0x0366,
+	0x6024, 0xd0cc, 0x1518, 0x1d04, 0x7270, 0x2091, 0x6000, 0x1f04,
+	0x7270, 0x2011, 0x0003, 0x080c, 0x990e, 0x2011, 0x0002, 0x080c,
+	0x9918, 0x080c, 0x9826, 0x901e, 0x080c, 0x989c, 0x2001, 0x00a0,
+	0x080c, 0x2b88, 0x080c, 0x747b, 0x080c, 0x5e30, 0x080c, 0xc444,
+	0x0110, 0x080c, 0x0d70, 0x9085, 0x0001, 0x0480, 0x080c, 0x19a8,
+	0x60e3, 0x0000, 0x2001, 0x0002, 0x080c, 0x26e2, 0x60e2, 0x2001,
+	0x0080, 0x080c, 0x2b88, 0x20a9, 0x0366, 0x6027, 0x1e00, 0x2009,
+	0x1e00, 0x080c, 0x2ab0, 0x6024, 0x910c, 0x0138, 0x1d04, 0x72a5,
+	0x2091, 0x6000, 0x1f04, 0x72a5, 0x0820, 0x6028, 0x9085, 0x1e00,
+	0x602a, 0x70b0, 0x9005, 0x1118, 0x6887, 0x0001, 0x0008, 0x6886,
+	0x080c, 0xc444, 0x0110, 0x080c, 0x0d70, 0x9006, 0x00ee, 0x00de,
+	0x00ce, 0x003e, 0x002e, 0x001e, 0x015e, 0x0005, 0x0156, 0x0016,
+	0x0026, 0x0036, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2071,
+	0x1800, 0x7000, 0x9086, 0x0003, 0x1168, 0x2001, 0x020b, 0x2004,
+	0x9084, 0x5540, 0x9086, 0x5540, 0x1128, 0x2069, 0x1a54, 0x2d04,
+	0x8000, 0x206a, 0x2069, 0x0140, 0x6020, 0x9084, 0x00c0, 0x0120,
+	0x6884, 0x9005, 0x1904, 0x7333, 0x2001, 0x0088, 0x080c, 0x2b88,
+	0x9006, 0x60e2, 0x6886, 0x080c, 0x26e2, 0x2069, 0x0200, 0x6804,
+	0x9005, 0x1118, 0x6808, 0x9005, 0x01c0, 0x6028, 0x9084, 0xfbff,
+	0x602a, 0x6027, 0x0400, 0x2069, 0x1969, 0x7000, 0x206a, 0x7097,
+	0x0026, 0x7003, 0x0001, 0x20a9, 0x0002, 0x1d04, 0x7315, 0x2091,
+	0x6000, 0x1f04, 0x7315, 0x0804, 0x7362, 0x2069, 0x0140, 0x20a9,
+	0x0384, 0x6027, 0x1e00, 0x2009, 0x1e00, 0x080c, 0x2ab0, 0x6024,
+	0x910c, 0x0508, 0x9084, 0x1a00, 0x11f0, 0x1d04, 0x7321, 0x2091,
+	0x6000, 0x1f04, 0x7321, 0x2011, 0x0003, 0x080c, 0x990e, 0x2011,
+	0x0002, 0x080c, 0x9918, 0x080c, 0x9826, 0x901e, 0x080c, 0x989c,
+	0x2001, 0x00a0, 0x080c, 0x2b88, 0x080c, 0x747b, 0x080c, 0x5e30,
+	0x9085, 0x0001, 0x00b8, 0x080c, 0x19a8, 0x2001, 0x0080, 0x080c,
+	0x2b88, 0x2069, 0x0140, 0x60e3, 0x0000, 0x70b0, 0x9005, 0x1118,
+	0x6887, 0x0001, 0x0008, 0x6886, 0x2001, 0x0002, 0x080c, 0x26e2,
+	0x60e2, 0x9006, 0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e, 0x001e,
+	0x015e, 0x0005, 0x0156, 0x0016, 0x0026, 0x0036, 0x00c6, 0x00d6,
+	0x00e6, 0x2061, 0x0100, 0x2071, 0x1800, 0x6020, 0x9084, 0x00c0,
+	0x01c8, 0x2011, 0x0003, 0x080c, 0x990e, 0x2011, 0x0002, 0x080c,
+	0x9918, 0x080c, 0x9826, 0x901e, 0x080c, 0x989c, 0x2069, 0x0140,
+	0x2001, 0x00a0, 0x080c, 0x2b88, 0x080c, 0x747b, 0x080c, 0x5e30,
+	0x0804, 0x73fc, 0x2001, 0x180c, 0x200c, 0xd1b4, 0x1160, 0xc1b5,
+	0x2102, 0x080c, 0x6fd6, 0x2069, 0x0140, 0x2001, 0x0080, 0x080c,
+	0x2b88, 0x60e3, 0x0000, 0x2069, 0x0200, 0x6804, 0x9005, 0x1118,
+	0x6808, 0x9005, 0x0180, 0x6028, 0x9084, 0xfdff, 0x602a, 0x6027,
+	0x0200, 0x2069, 0x1969, 0x7000, 0x206a, 0x7097, 0x0027, 0x7003,
+	0x0001, 0x0804, 0x73fc, 0x6027, 0x1e00, 0x2009, 0x1e00, 0x080c,
+	0x2ab0, 0x6024, 0x910c, 0x01c8, 0x9084, 0x1c00, 0x11b0, 0x1d04,
+	0x73bb, 0x0006, 0x0016, 0x00c6, 0x00d6, 0x00e6, 0x080c, 0x81be,
+	0x00ee, 0x00de, 0x00ce, 0x001e, 0x000e, 0x00e6, 0x2071, 0x19d5,
+	0x7078, 0x00ee, 0x9005, 0x19f8, 0x00f8, 0x0026, 0x2011, 0x6fee,
+	0x080c, 0x825a, 0x2011, 0x6fe1, 0x080c, 0x832e, 0x002e, 0x2069,
+	0x0140, 0x60e3, 0x0000, 0x70b0, 0x9005, 0x1118, 0x6887, 0x0001,
+	0x0008, 0x6886, 0x2001, 0x0002, 0x080c, 0x26e2, 0x60e2, 0x2001,
+	0x180c, 0x200c, 0xc1b4, 0x2102, 0x00ee, 0x00de, 0x00ce, 0x003e,
+	0x002e, 0x001e, 0x015e, 0x0005, 0x0156, 0x0016, 0x0026, 0x0036,
+	0x0046, 0x00c6, 0x00e6, 0x2061, 0x0100, 0x2071, 0x1800, 0x080c,
+	0xc43d, 0x1904, 0x7469, 0x7130, 0xd184, 0x1170, 0x080c, 0x3204,
+	0x0138, 0xc18d, 0x7132, 0x2011, 0x185c, 0x2214, 0xd2ac, 0x1120,
+	0x7030, 0xd08c, 0x0904, 0x7469, 0x2011, 0x185c, 0x220c, 0x0438,
+	0x0016, 0x2019, 0x000e, 0x080c, 0xd74e, 0x0156, 0x00b6, 0x20a9,
+	0x007f, 0x900e, 0x9186, 0x007e, 0x01a0, 0x9186, 0x0080, 0x0188,
+	0x080c, 0x63a4, 0x1170, 0x2120, 0x9006, 0x0016, 0x2009, 0x000e,
+	0x080c, 0xd7d6, 0x2009, 0x0001, 0x2011, 0x0100, 0x080c, 0x8451,
+	0x001e, 0x8108, 0x1f04, 0x7432, 0x00be, 0x015e, 0x001e, 0xd1ac,
+	0x1148, 0x0016, 0x2009, 0x0002, 0x2019, 0x0004, 0x080c, 0x3076,
+	0x001e, 0x0078, 0x0156, 0x00b6, 0x20a9, 0x007f, 0x900e, 0x080c,
+	0x63a4, 0x1110, 0x080c, 0x5e4a, 0x8108, 0x1f04, 0x745f, 0x00be,
+	0x015e, 0x080c, 0x19a8, 0x080c, 0x9f5b, 0x60e3, 0x0000, 0x080c,
+	0x5e30, 0x080c, 0x709f, 0x00ee, 0x00ce, 0x004e, 0x003e, 0x002e,
+	0x001e, 0x015e, 0x0005, 0x2001, 0x1957, 0x2003, 0x0001, 0x0005,
+	0x2001, 0x1957, 0x2003, 0x0000, 0x0005, 0x2001, 0x1956, 0x2003,
+	0xaaaa, 0x0005, 0x2001, 0x1956, 0x2003, 0x0000, 0x0005, 0x2071,
+	0x18f8, 0x7003, 0x0000, 0x7007, 0x0000, 0x080c, 0x105c, 0x090c,
+	0x0e02, 0xa8ab, 0xdcb0, 0x2900, 0x704e, 0x080c, 0x105c, 0x090c,
+	0x0e02, 0xa8ab, 0xdcb0, 0x2900, 0x7052, 0xa867, 0x0000, 0xa86b,
+	0x0001, 0xa89f, 0x0000, 0x0005, 0x00e6, 0x2071, 0x0040, 0x6848,
+	0x9005, 0x1118, 0x9085, 0x0001, 0x04b0, 0x6840, 0x9005, 0x0150,
+	0x04a1, 0x6a50, 0x9200, 0x7002, 0x6854, 0x9101, 0x7006, 0x9006,
+	0x7012, 0x7016, 0x6850, 0x7002, 0x6854, 0x7006, 0x6858, 0x700a,
+	0x685c, 0x700e, 0x6840, 0x9005, 0x1110, 0x7012, 0x7016, 0x6848,
+	0x701a, 0x701c, 0x9085, 0x0040, 0x701e, 0x2001, 0x0019, 0x7036,
+	0x702b, 0x0001, 0x2001, 0x0004, 0x200c, 0x918c, 0xfff7, 0x918d,
+	0x8000, 0x2102, 0x00d6, 0x2069, 0x18f8, 0x6807, 0x0001, 0x00de,
+	0x080c, 0x7a7d, 0x9006, 0x00ee, 0x0005, 0x900e, 0x0156, 0x20a9,
+	0x0006, 0x8003, 0x818d, 0x1f04, 0x74f1, 0x015e, 0x0005, 0x2079,
+	0x0040, 0x2071, 0x18f8, 0x7004, 0x0002, 0x7507, 0x7508, 0x7540,
+	0x759b, 0x76e0, 0x7505, 0x7505, 0x770a, 0x080c, 0x0e02, 0x0005,
+	0x2079, 0x0040, 0x782c, 0x908c, 0x0780, 0x190c, 0x7b09, 0xd0a4,
+	0x01f8, 0x7824, 0x2048, 0x9006, 0xa802, 0xa806, 0xa864, 0x9084,
+	0x00ff, 0x908a, 0x0040, 0x0610, 0x00c0, 0x2001, 0x1800, 0x200c,
+	0x9186, 0x0003, 0x1168, 0x7004, 0x0002, 0x7530, 0x750a, 0x7530,
+	0x752e, 0x7530, 0x7530, 0x7530, 0x7530, 0x7530, 0x080c, 0x759b,
+	0x782c, 0xd09c, 0x090c, 0x7a7d, 0x0005, 0x9082, 0x005a, 0x1218,
+	0x2100, 0x003b, 0x0c10, 0x080c, 0x75d1, 0x0c90, 0x00e3, 0x08e8,
+	0x0005, 0x75d1, 0x75d1, 0x75d1, 0x75d1, 0x75d1, 0x75d1, 0x75d1,
+	0x75d1, 0x75f3, 0x75d1, 0x75d1, 0x75d1, 0x75d1, 0x75d1, 0x75d1,
+	0x75d1, 0x75d1, 0x75d1, 0x75d1, 0x75d1, 0x75d1, 0x75d1, 0x75d1,
+	0x75d1, 0x75d1, 0x75d1, 0x75d1, 0x75d1, 0x75dd, 0x75d1, 0x77e4,
+	0x75d1, 0x75d1, 0x75d1, 0x75f3, 0x75d1, 0x75dd, 0x7825, 0x7866,
+	0x78ad, 0x78c1, 0x75d1, 0x75d1, 0x75f3, 0x75dd, 0x75d1, 0x75d1,
+	0x76b4, 0x796c, 0x7987, 0x75d1, 0x75f3, 0x75d1, 0x75d1, 0x75d1,
+	0x75d1, 0x76aa, 0x7987, 0x75d1, 0x75d1, 0x75d1, 0x75d1, 0x75d1,
+	0x75d1, 0x75d1, 0x75d1, 0x75d1, 0x7607, 0x75d1, 0x75d1, 0x75d1,
+	0x75d1, 0x75d1, 0x75d1, 0x75d1, 0x75d1, 0x75d1, 0x7aad, 0x75d1,
+	0x75d1, 0x75d1, 0x75d1, 0x75d1, 0x761b, 0x75d1, 0x75d1, 0x75d1,
+	0x75d1, 0x75d1, 0x75d1, 0x2079, 0x0040, 0x7004, 0x9086, 0x0003,
+	0x1198, 0x782c, 0x080c, 0x7aa6, 0xd0a4, 0x0170, 0x7824, 0x2048,
+	0x9006, 0xa802, 0xa806, 0xa864, 0x9084, 0x00ff, 0x908a, 0x001a,
+	0x1210, 0x002b, 0x0c50, 0x00e9, 0x080c, 0x7a7d, 0x0005, 0x75d1,
+	0x75dd, 0x77d0, 0x75d1, 0x75dd, 0x75d1, 0x75dd, 0x75dd, 0x75d1,
+	0x75dd, 0x77d0, 0x75dd, 0x75dd, 0x75dd, 0x75dd, 0x75dd, 0x75d1,
+	0x75dd, 0x77d0, 0x75d1, 0x75d1, 0x75dd, 0x75d1, 0x75d1, 0x75d1,
+	0x75dd, 0x00e6, 0x2071, 0x18f8, 0x2009, 0x0400, 0x0071, 0x00ee,
+	0x0005, 0x2009, 0x1000, 0x0049, 0x0005, 0x2009, 0x2000, 0x0029,
+	0x0005, 0x2009, 0x0800, 0x0009, 0x0005, 0x7007, 0x0001, 0xa868,
+	0x9084, 0x00ff, 0x9105, 0xa86a, 0x0126, 0x2091, 0x8000, 0x080c,
+	0x6a23, 0x012e, 0x0005, 0xa864, 0x8007, 0x9084, 0x00ff, 0x0d08,
+	0x8001, 0x1120, 0x7007, 0x0001, 0x0804, 0x7789, 0x7007, 0x0003,
+	0x7012, 0x2900, 0x7016, 0x701a, 0x704b, 0x7789, 0x0005, 0xa864,
+	0x8007, 0x9084, 0x00ff, 0x0968, 0x8001, 0x1120, 0x7007, 0x0001,
+	0x0804, 0x77a4, 0x7007, 0x0003, 0x7012, 0x2900, 0x7016, 0x701a,
+	0x704b, 0x77a4, 0x0005, 0xa864, 0x8007, 0x9084, 0x00ff, 0x9086,
+	0x0001, 0x1904, 0x75d9, 0x7007, 0x0001, 0x2009, 0x1833, 0x210c,
+	0x81ff, 0x1904, 0x7681, 0xa99c, 0x9186, 0x00ff, 0x05e8, 0xa994,
+	0x9186, 0x006f, 0x0188, 0x9186, 0x0074, 0x15b0, 0x0026, 0x2011,
+	0x0010, 0x080c, 0x66ee, 0x002e, 0x0578, 0x0016, 0xa998, 0x080c,
+	0x6738, 0x001e, 0x1548, 0x0400, 0x080c, 0x717f, 0x0140, 0xa897,
+	0x4005, 0xa89b, 0x0016, 0x2001, 0x0030, 0x900e, 0x0438, 0x0026,
+	0x2011, 0x8008, 0x080c, 0x66ee, 0x002e, 0x01b0, 0x0016, 0x0026,
+	0x0036, 0xa998, 0xaaa0, 0xab9c, 0x918d, 0x8000, 0x080c, 0x6738,
+	0x003e, 0x002e, 0x001e, 0x1140, 0xa897, 0x4005, 0xa89b, 0x4009,
+	0x2001, 0x0030, 0x900e, 0x0050, 0xa868, 0x9084, 0x00ff, 0xa86a,
+	0xa883, 0x0000, 0x080c, 0x6062, 0x1108, 0x0005, 0x0126, 0x2091,
+	0x8000, 0xa867, 0x0139, 0xa87a, 0xa982, 0x080c, 0x6a23, 0x012e,
+	0x0ca0, 0xa994, 0x9186, 0x0071, 0x0904, 0x762b, 0x9186, 0x0064,
+	0x0904, 0x762b, 0x9186, 0x007c, 0x0904, 0x762b, 0x9186, 0x0028,
+	0x0904, 0x762b, 0x9186, 0x0038, 0x0904, 0x762b, 0x9186, 0x0078,
+	0x0904, 0x762b, 0x9186, 0x005f, 0x0904, 0x762b, 0x9186, 0x0056,
+	0x0904, 0x762b, 0xa897, 0x4005, 0xa89b, 0x0001, 0x2001, 0x0030,
+	0x900e, 0x0860, 0xa87c, 0x9084, 0x00c0, 0x9086, 0x00c0, 0x1120,
+	0x7007, 0x0001, 0x0804, 0x799e, 0x2900, 0x7016, 0x701a, 0x20a9,
+	0x0004, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0030, 0x2098, 0x7050,
+	0x2040, 0xa060, 0x20e8, 0xa05c, 0x9080, 0x0023, 0x20a0, 0x4003,
+	0xa888, 0x7012, 0x9082, 0x0401, 0x1a04, 0x75e1, 0xaab4, 0x928a,
+	0x0002, 0x1a04, 0x75e1, 0x82ff, 0x1138, 0xa8b8, 0xa9bc, 0x9105,
+	0x0118, 0x2001, 0x7747, 0x0018, 0x9280, 0x773d, 0x2005, 0x7056,
+	0x7010, 0x9015, 0x0904, 0x7728, 0x080c, 0x105c, 0x1118, 0x7007,
+	0x0004, 0x0005, 0x2900, 0x7022, 0x7054, 0x2060, 0xe000, 0xa866,
+	0x7050, 0x2040, 0xa95c, 0xe004, 0x9100, 0xa076, 0xa860, 0xa072,
+	0xe008, 0x920a, 0x1210, 0x900e, 0x2200, 0x7112, 0xe20c, 0x8003,
+	0x800b, 0x9296, 0x0004, 0x0108, 0x9108, 0xa17a, 0x810b, 0xa17e,
+	0x080c, 0x1140, 0xa06c, 0x908e, 0x0100, 0x0170, 0x9086, 0x0200,
+	0x0118, 0x7007, 0x0007, 0x0005, 0x7020, 0x2048, 0x080c, 0x1075,
+	0x7014, 0x2048, 0x0804, 0x75e1, 0x7020, 0x2048, 0x7018, 0xa802,
+	0xa807, 0x0000, 0x2908, 0x2048, 0xa906, 0x711a, 0x0804, 0x76e0,
+	0x7014, 0x2048, 0x7007, 0x0001, 0xa8b4, 0x9005, 0x1128, 0xa8b8,
+	0xa9bc, 0x9105, 0x0108, 0x00b9, 0xa864, 0x9084, 0x00ff, 0x9086,
+	0x001e, 0x0904, 0x799e, 0x0804, 0x7789, 0x773f, 0x7743, 0x0002,
+	0x001d, 0x0007, 0x0004, 0x000a, 0x001b, 0x0005, 0x0006, 0x000a,
+	0x001d, 0x0005, 0x0004, 0x0076, 0x0066, 0xafb8, 0xaebc, 0xa804,
+	0x2050, 0xb0c0, 0xb0e2, 0xb0bc, 0xb0de, 0xb0b8, 0xb0d2, 0xb0b4,
+	0xb0ce, 0xb6da, 0xb7d6, 0xb0b0, 0xb0ca, 0xb0ac, 0xb0c6, 0xb0a8,
+	0xb0ba, 0xb0a4, 0xb0b6, 0xb6c2, 0xb7be, 0xb0a0, 0xb0b2, 0xb09c,
+	0xb0ae, 0xb098, 0xb0a2, 0xb094, 0xb09e, 0xb6aa, 0xb7a6, 0xb090,
+	0xb09a, 0xb08c, 0xb096, 0xb088, 0xb08a, 0xb084, 0xb086, 0xb692,
+	0xb78e, 0xb080, 0xb082, 0xb07c, 0xb07e, 0xb078, 0xb072, 0xb074,
+	0xb06e, 0xb67a, 0xb776, 0xb004, 0x9055, 0x1958, 0x006e, 0x007e,
+	0x0005, 0x2009, 0x1833, 0x210c, 0x81ff, 0x1178, 0x080c, 0x5eac,
+	0x1108, 0x0005, 0x080c, 0x6c6c, 0x0126, 0x2091, 0x8000, 0x080c,
+	0xc031, 0x080c, 0x6a23, 0x012e, 0x0ca0, 0x080c, 0xc43d, 0x1d70,
+	0x2001, 0x0028, 0x900e, 0x0c70, 0x0419, 0x11d8, 0xa888, 0x9005,
+	0x01e0, 0xa883, 0x0000, 0xa87c, 0xd0f4, 0x0120, 0x080c, 0x5fc4,
+	0x1138, 0x0005, 0x9006, 0xa87a, 0x080c, 0x5f3c, 0x1108, 0x0005,
+	0x0126, 0x2091, 0x8000, 0xa87a, 0xa982, 0x080c, 0x6a23, 0x012e,
 	0x0cb0, 0x2001, 0x0028, 0x900e, 0x0c98, 0x2001, 0x0000, 0x0c80,
+	0x00c6, 0x2061, 0x1800, 0x60cc, 0x9005, 0x0100, 0x00ce, 0x0005,
 	0x7018, 0xa802, 0x2908, 0x2048, 0xa906, 0x711a, 0x7010, 0x8001,
 	0x7012, 0x0118, 0x7007, 0x0003, 0x0030, 0x7014, 0x2048, 0x7007,
 	0x0001, 0x7048, 0x080f, 0x0005, 0x00b6, 0x7007, 0x0001, 0xa974,
 	0xa878, 0x9084, 0x00ff, 0x9096, 0x0004, 0x0540, 0x20a9, 0x0001,
 	0x9096, 0x0001, 0x0190, 0x900e, 0x20a9, 0x0800, 0x9096, 0x0002,
-	0x0160, 0x9005, 0x11d8, 0xa974, 0x080c, 0x649f, 0x11b8, 0x0066,
-	0xae80, 0x080c, 0x65af, 0x006e, 0x0088, 0x0046, 0x2011, 0x180c,
-	0x2224, 0xc484, 0x2412, 0x004e, 0x00c6, 0x080c, 0x649f, 0x1110,
-	0x080c, 0x66af, 0x8108, 0x1f04, 0x788d, 0x00ce, 0xa87c, 0xd084,
-	0x1120, 0x080c, 0x1063, 0x00be, 0x0005, 0x0126, 0x2091, 0x8000,
-	0x080c, 0x6ae9, 0x012e, 0x00be, 0x0005, 0x0126, 0x2091, 0x8000,
-	0x7007, 0x0001, 0x080c, 0x67bf, 0x0580, 0x2061, 0x1a48, 0x6100,
+	0x0160, 0x9005, 0x11d8, 0xa974, 0x080c, 0x63a4, 0x11b8, 0x0066,
+	0xae80, 0x080c, 0x64b4, 0x006e, 0x0088, 0x0046, 0x2011, 0x180c,
+	0x2224, 0xc484, 0x2412, 0x004e, 0x00c6, 0x080c, 0x63a4, 0x1110,
+	0x080c, 0x65b4, 0x8108, 0x1f04, 0x780d, 0x00ce, 0xa87c, 0xd084,
+	0x1120, 0x080c, 0x1075, 0x00be, 0x0005, 0x0126, 0x2091, 0x8000,
+	0x080c, 0x6a23, 0x012e, 0x00be, 0x0005, 0x0126, 0x2091, 0x8000,
+	0x7007, 0x0001, 0x080c, 0x66c6, 0x0580, 0x2061, 0x1a4c, 0x6100,
 	0xd184, 0x0178, 0xa888, 0x9084, 0x00ff, 0x1550, 0x6000, 0xd084,
 	0x0520, 0x6004, 0x9005, 0x1538, 0x6003, 0x0000, 0x600b, 0x0000,
 	0x00c8, 0x2011, 0x0001, 0xa890, 0x9005, 0x1110, 0x2001, 0x001e,
 	0x8000, 0x6016, 0xa888, 0x9084, 0x00ff, 0x0178, 0x6006, 0xa888,
 	0x8007, 0x9084, 0x00ff, 0x0148, 0x600a, 0xa888, 0x8000, 0x1108,
-	0xc28d, 0x6202, 0x012e, 0x0804, 0x7ae7, 0x012e, 0x0804, 0x7ae1,
-	0x012e, 0x0804, 0x7adb, 0x012e, 0x0804, 0x7ade, 0x0126, 0x2091,
-	0x8000, 0x7007, 0x0001, 0x080c, 0x67bf, 0x05e0, 0x2061, 0x1a48,
+	0xc28d, 0x6202, 0x012e, 0x0804, 0x7a67, 0x012e, 0x0804, 0x7a61,
+	0x012e, 0x0804, 0x7a5b, 0x012e, 0x0804, 0x7a5e, 0x0126, 0x2091,
+	0x8000, 0x7007, 0x0001, 0x080c, 0x66c6, 0x05e0, 0x2061, 0x1a4c,
 	0x6000, 0xd084, 0x05b8, 0x6204, 0x6308, 0xd08c, 0x1530, 0xac78,
 	0x9484, 0x0003, 0x0170, 0xa988, 0x918c, 0x00ff, 0x8001, 0x1120,
 	0x2100, 0x9210, 0x0620, 0x0028, 0x8001, 0x1508, 0x2100, 0x9212,
 	0x02f0, 0x9484, 0x000c, 0x0188, 0xa988, 0x810f, 0x918c, 0x00ff,
 	0x9082, 0x0004, 0x1120, 0x2100, 0x9318, 0x0288, 0x0030, 0x9082,
 	0x0004, 0x1168, 0x2100, 0x931a, 0x0250, 0xa890, 0x9005, 0x0110,
-	0x8000, 0x6016, 0x6206, 0x630a, 0x012e, 0x0804, 0x7ae7, 0x012e,
-	0x0804, 0x7ae4, 0x012e, 0x0804, 0x7ae1, 0x0126, 0x2091, 0x8000,
-	0x7007, 0x0001, 0x2061, 0x1a48, 0x6300, 0xd38c, 0x1120, 0x6308,
-	0x8318, 0x0220, 0x630a, 0x012e, 0x0804, 0x7af5, 0x012e, 0x0804,
-	0x7ae4, 0x00b6, 0x0126, 0x00c6, 0x2091, 0x8000, 0x7007, 0x0001,
-	0xa87c, 0xd0ac, 0x0148, 0x00c6, 0x2061, 0x1a48, 0x6000, 0x9084,
+	0x8000, 0x6016, 0x6206, 0x630a, 0x012e, 0x0804, 0x7a67, 0x012e,
+	0x0804, 0x7a64, 0x012e, 0x0804, 0x7a61, 0x0126, 0x2091, 0x8000,
+	0x7007, 0x0001, 0x2061, 0x1a4c, 0x6300, 0xd38c, 0x1120, 0x6308,
+	0x8318, 0x0220, 0x630a, 0x012e, 0x0804, 0x7a75, 0x012e, 0x0804,
+	0x7a64, 0x00b6, 0x0126, 0x00c6, 0x2091, 0x8000, 0x7007, 0x0001,
+	0xa87c, 0xd0ac, 0x0148, 0x00c6, 0x2061, 0x1a4c, 0x6000, 0x9084,
 	0xfcff, 0x6002, 0x00ce, 0x0440, 0xa888, 0x9005, 0x05d8, 0xa88c,
 	0x9065, 0x0598, 0x2001, 0x1833, 0x2004, 0x9005, 0x0118, 0x080c,
-	0xa113, 0x0068, 0x6017, 0xf400, 0x605b, 0x0000, 0xa97c, 0xd1a4,
-	0x0110, 0xa980, 0x615a, 0x2009, 0x0041, 0x080c, 0xa15d, 0xa988,
+	0xa007, 0x0068, 0x6017, 0xf400, 0x605b, 0x0000, 0xa97c, 0xd1a4,
+	0x0110, 0xa980, 0x615a, 0x2009, 0x0041, 0x080c, 0xa053, 0xa988,
 	0x918c, 0xff00, 0x9186, 0x2000, 0x1138, 0x0026, 0x900e, 0x2011,
-	0xfdff, 0x080c, 0x84d1, 0x002e, 0xa87c, 0xd0c4, 0x0148, 0x2061,
-	0x1a48, 0x6000, 0xd08c, 0x1120, 0x6008, 0x8000, 0x0208, 0x600a,
-	0x00ce, 0x012e, 0x00be, 0x0804, 0x7ae7, 0x00ce, 0x012e, 0x00be,
-	0x0804, 0x7ae1, 0xa984, 0x9186, 0x002e, 0x0d30, 0x9186, 0x002d,
+	0xfdff, 0x080c, 0x8451, 0x002e, 0xa87c, 0xd0c4, 0x0148, 0x2061,
+	0x1a4c, 0x6000, 0xd08c, 0x1120, 0x6008, 0x8000, 0x0208, 0x600a,
+	0x00ce, 0x012e, 0x00be, 0x0804, 0x7a67, 0x00ce, 0x012e, 0x00be,
+	0x0804, 0x7a61, 0xa984, 0x9186, 0x002e, 0x0d30, 0x9186, 0x002d,
 	0x0d18, 0x9186, 0x0045, 0x0510, 0x9186, 0x002a, 0x1130, 0x2001,
 	0x180c, 0x200c, 0xc194, 0x2102, 0x08b8, 0x9186, 0x0020, 0x0158,
-	0x9186, 0x0029, 0x1d10, 0xa974, 0x080c, 0x649f, 0x1968, 0xb800,
+	0x9186, 0x0029, 0x1d10, 0xa974, 0x080c, 0x63a4, 0x1968, 0xb800,
 	0xc0e4, 0xb802, 0x0848, 0xa88c, 0x9065, 0x09b8, 0x6007, 0x0024,
-	0x2001, 0x195e, 0x2004, 0x601a, 0x0804, 0x797c, 0xa88c, 0x9065,
+	0x2001, 0x1960, 0x2004, 0x601a, 0x0804, 0x78fc, 0xa88c, 0x9065,
 	0x0960, 0x00e6, 0xa890, 0x9075, 0x2001, 0x1833, 0x2004, 0x9005,
-	0x0150, 0x080c, 0xa113, 0x8eff, 0x0118, 0x2e60, 0x080c, 0xa113,
-	0x00ee, 0x0804, 0x797c, 0x6024, 0xc0dc, 0xc0d5, 0x6026, 0x2e60,
+	0x0150, 0x080c, 0xa007, 0x8eff, 0x0118, 0x2e60, 0x080c, 0xa007,
+	0x00ee, 0x0804, 0x78fc, 0x6024, 0xc0dc, 0xc0d5, 0x6026, 0x2e60,
 	0x6007, 0x003a, 0xa8a0, 0x9005, 0x0130, 0x6007, 0x003b, 0xa8a4,
-	0x602e, 0xa8a8, 0x6016, 0x6003, 0x0001, 0x080c, 0x8679, 0x080c,
-	0x8c10, 0x00ee, 0x0804, 0x797c, 0x2061, 0x1a48, 0x6000, 0xd084,
-	0x0190, 0xd08c, 0x1904, 0x7af5, 0x0126, 0x2091, 0x8000, 0x6204,
-	0x8210, 0x0220, 0x6206, 0x012e, 0x0804, 0x7af5, 0x012e, 0xa883,
-	0x0016, 0x0804, 0x7aee, 0xa883, 0x0007, 0x0804, 0x7aee, 0xa864,
+	0x602e, 0xa8a8, 0x6016, 0x6003, 0x0001, 0x080c, 0x85f9, 0x080c,
+	0x8b90, 0x00ee, 0x0804, 0x78fc, 0x2061, 0x1a4c, 0x6000, 0xd084,
+	0x0190, 0xd08c, 0x1904, 0x7a75, 0x0126, 0x2091, 0x8000, 0x6204,
+	0x8210, 0x0220, 0x6206, 0x012e, 0x0804, 0x7a75, 0x012e, 0xa883,
+	0x0016, 0x0804, 0x7a6e, 0xa883, 0x0007, 0x0804, 0x7a6e, 0xa864,
 	0x8007, 0x9084, 0x00ff, 0x0130, 0x8001, 0x1138, 0x7007, 0x0001,
-	0x0069, 0x0005, 0x080c, 0x7662, 0x0040, 0x7007, 0x0003, 0x7012,
-	0x2900, 0x7016, 0x701a, 0x704b, 0x7a1e, 0x0005, 0x00b6, 0x00e6,
+	0x0069, 0x0005, 0x080c, 0x75d9, 0x0040, 0x7007, 0x0003, 0x7012,
+	0x2900, 0x7016, 0x701a, 0x704b, 0x799e, 0x0005, 0x00b6, 0x00e6,
 	0x0126, 0x2091, 0x8000, 0x903e, 0x2061, 0x1800, 0x61cc, 0x81ff,
-	0x1904, 0x7aa0, 0x6130, 0xd194, 0x1904, 0x7aca, 0xa878, 0x2070,
-	0x9e82, 0x1cd0, 0x0a04, 0x7a94, 0x6064, 0x9e02, 0x1a04, 0x7a94,
-	0x7120, 0x9186, 0x0006, 0x1904, 0x7a86, 0x7010, 0x905d, 0x0904,
-	0x7aa0, 0xb800, 0xd0e4, 0x1904, 0x7ac4, 0x2061, 0x1a48, 0x6100,
+	0x1904, 0x7a20, 0x6130, 0xd194, 0x1904, 0x7a4a, 0xa878, 0x2070,
+	0x9e82, 0x1cd0, 0x0a04, 0x7a14, 0x6064, 0x9e02, 0x1a04, 0x7a14,
+	0x7120, 0x9186, 0x0006, 0x1904, 0x7a06, 0x7010, 0x905d, 0x0904,
+	0x7a20, 0xb800, 0xd0e4, 0x1904, 0x7a44, 0x2061, 0x1a4c, 0x6100,
 	0x9184, 0x0301, 0x9086, 0x0001, 0x15a0, 0x7024, 0xd0dc, 0x1904,
-	0x7acd, 0xa883, 0x0000, 0xa803, 0x0000, 0x2908, 0x7014, 0x9005,
-	0x1198, 0x7116, 0xa87c, 0xd0f4, 0x1904, 0x7ad0, 0x080c, 0x55db,
-	0xd09c, 0x1118, 0xa87c, 0xc0cc, 0xa87e, 0x2e60, 0x080c, 0x83f1,
+	0x7a4d, 0xa883, 0x0000, 0xa803, 0x0000, 0x2908, 0x7014, 0x9005,
+	0x1198, 0x7116, 0xa87c, 0xd0f4, 0x1904, 0x7a50, 0x080c, 0x54dc,
+	0xd09c, 0x1118, 0xa87c, 0xc0cc, 0xa87e, 0x2e60, 0x080c, 0x8371,
 	0x012e, 0x00ee, 0x00be, 0x0005, 0x2048, 0xa800, 0x9005, 0x1de0,
-	0xa902, 0x2148, 0xa87c, 0xd0f4, 0x1904, 0x7ad0, 0x012e, 0x00ee,
+	0xa902, 0x2148, 0xa87c, 0xd0f4, 0x1904, 0x7a50, 0x012e, 0x00ee,
 	0x00be, 0x0005, 0x012e, 0x00ee, 0xa883, 0x0006, 0x00be, 0x0804,
-	0x7aee, 0xd184, 0x0db8, 0xd1c4, 0x1190, 0x00a0, 0xa974, 0x080c,
-	0x649f, 0x15d0, 0xb800, 0xd0e4, 0x15b8, 0x7120, 0x9186, 0x0007,
+	0x7a6e, 0xd184, 0x0db8, 0xd1c4, 0x1190, 0x00a0, 0xa974, 0x080c,
+	0x63a4, 0x15d0, 0xb800, 0xd0e4, 0x15b8, 0x7120, 0x9186, 0x0007,
 	0x1118, 0xa883, 0x0002, 0x0490, 0xa883, 0x0008, 0x0478, 0xa883,
 	0x000e, 0x0460, 0xa883, 0x0017, 0x0448, 0xa883, 0x0035, 0x0430,
-	0x080c, 0x55df, 0xd0fc, 0x01e8, 0xa878, 0x2070, 0x9e82, 0x1cd0,
+	0x080c, 0x54e0, 0xd0fc, 0x01e8, 0xa878, 0x2070, 0x9e82, 0x1cd0,
 	0x02c0, 0x6064, 0x9e02, 0x12a8, 0x7120, 0x9186, 0x0006, 0x1188,
 	0x7010, 0x905d, 0x0170, 0xb800, 0xd0bc, 0x0158, 0x2039, 0x0001,
-	0x7000, 0x9086, 0x0007, 0x1904, 0x7a2a, 0x7003, 0x0002, 0x0804,
-	0x7a2a, 0xa883, 0x0028, 0x0010, 0xa883, 0x0029, 0x012e, 0x00ee,
+	0x7000, 0x9086, 0x0007, 0x1904, 0x79aa, 0x7003, 0x0002, 0x0804,
+	0x79aa, 0xa883, 0x0028, 0x0010, 0xa883, 0x0029, 0x012e, 0x00ee,
 	0x00be, 0x0420, 0xa883, 0x002a, 0x0cc8, 0xa883, 0x0045, 0x0cb0,
-	0x2e60, 0x2019, 0x0002, 0x601b, 0x0014, 0x080c, 0xd440, 0x012e,
+	0x2e60, 0x2019, 0x0002, 0x601b, 0x0014, 0x080c, 0xd385, 0x012e,
 	0x00ee, 0x00be, 0x0005, 0x2009, 0x003e, 0x0058, 0x2009, 0x0004,
 	0x0040, 0x2009, 0x0006, 0x0028, 0x2009, 0x0016, 0x0010, 0x2009,
 	0x0001, 0xa884, 0x9084, 0xff00, 0x9105, 0xa886, 0x0126, 0x2091,
-	0x8000, 0x080c, 0x6ae9, 0x012e, 0x0005, 0x080c, 0x1063, 0x0005,
-	0x00d6, 0x080c, 0x83e8, 0x00de, 0x0005, 0x00d6, 0x00e6, 0x0126,
+	0x8000, 0x080c, 0x6a23, 0x012e, 0x0005, 0x080c, 0x1075, 0x0005,
+	0x00d6, 0x080c, 0x8368, 0x00de, 0x0005, 0x00d6, 0x00e6, 0x0126,
 	0x2091, 0x8000, 0x2071, 0x0040, 0x702c, 0xd084, 0x01d8, 0x908c,
-	0x0780, 0x190c, 0x7b89, 0xd09c, 0x11a8, 0x2071, 0x1800, 0x70bc,
+	0x0780, 0x190c, 0x7b09, 0xd09c, 0x11a8, 0x2071, 0x1800, 0x70bc,
 	0x90ea, 0x0040, 0x0278, 0x8001, 0x70be, 0x702c, 0x2048, 0xa800,
 	0x702e, 0x9006, 0xa802, 0xa806, 0x2071, 0x0040, 0x2900, 0x7022,
 	0x702c, 0x0c28, 0x012e, 0x00ee, 0x00de, 0x0005, 0x0006, 0x9084,
-	0x0780, 0x190c, 0x7b89, 0x000e, 0x0005, 0x00d6, 0x00c6, 0x0036,
+	0x0780, 0x190c, 0x7b09, 0x000e, 0x0005, 0x00d6, 0x00c6, 0x0036,
 	0x0026, 0x0016, 0x00b6, 0x7007, 0x0001, 0xaa74, 0x9282, 0x0004,
-	0x1a04, 0x7b7a, 0xa97c, 0x9188, 0x1000, 0x2104, 0x905d, 0xb804,
+	0x1a04, 0x7afa, 0xa97c, 0x9188, 0x1000, 0x2104, 0x905d, 0xb804,
 	0xd284, 0x0140, 0x05e8, 0x8007, 0x9084, 0x00ff, 0x9084, 0x0006,
-	0x1108, 0x04b0, 0x2b10, 0x080c, 0xa08d, 0x1118, 0x080c, 0xa130,
-	0x05a8, 0x6212, 0xa874, 0x0002, 0x7b58, 0x7b5d, 0x7b60, 0x7b66,
-	0x2019, 0x0002, 0x080c, 0xd801, 0x0060, 0x080c, 0xd79d, 0x0048,
-	0x2019, 0x0002, 0xa980, 0x080c, 0xd7b8, 0x0018, 0xa980, 0x080c,
-	0xd79d, 0x080c, 0xa0e3, 0xa887, 0x0000, 0x0126, 0x2091, 0x8000,
-	0x080c, 0x6ae9, 0x012e, 0x00be, 0x001e, 0x002e, 0x003e, 0x00ce,
+	0x1108, 0x04b0, 0x2b10, 0x080c, 0x9f7f, 0x1118, 0x080c, 0xa026,
+	0x05a8, 0x6212, 0xa874, 0x0002, 0x7ad8, 0x7add, 0x7ae0, 0x7ae6,
+	0x2019, 0x0002, 0x080c, 0xd74e, 0x0060, 0x080c, 0xd6e5, 0x0048,
+	0x2019, 0x0002, 0xa980, 0x080c, 0xd700, 0x0018, 0xa980, 0x080c,
+	0xd6e5, 0x080c, 0x9fd5, 0xa887, 0x0000, 0x0126, 0x2091, 0x8000,
+	0x080c, 0x6a23, 0x012e, 0x00be, 0x001e, 0x002e, 0x003e, 0x00ce,
 	0x00de, 0x0005, 0xa887, 0x0006, 0x0c80, 0xa887, 0x0002, 0x0c68,
 	0xa887, 0x0005, 0x0c50, 0xa887, 0x0004, 0x0c38, 0xa887, 0x0007,
-	0x0c20, 0x2091, 0x8000, 0x0e04, 0x7b8b, 0x0006, 0x0016, 0x2001,
-	0x8003, 0x0006, 0x0804, 0x0e03, 0x2001, 0x1833, 0x2004, 0x9005,
+	0x0c20, 0x2091, 0x8000, 0x0e04, 0x7b0b, 0x0006, 0x0016, 0x2001,
+	0x8003, 0x0006, 0x0804, 0x0e0b, 0x2001, 0x1833, 0x2004, 0x9005,
 	0x0005, 0x0005, 0x00f6, 0x2079, 0x0300, 0x2001, 0x0200, 0x200c,
 	0xc1e5, 0xc1dc, 0x2102, 0x2009, 0x0218, 0x210c, 0xd1ec, 0x1120,
-	0x080c, 0x151a, 0x00fe, 0x0005, 0x2001, 0x020d, 0x2003, 0x0020,
-	0x781f, 0x0300, 0x00fe, 0x0005, 0x781c, 0xd08c, 0x0904, 0x7c0b,
-	0x68bc, 0x90aa, 0x0005, 0x0a04, 0x81e7, 0x7d44, 0x7c40, 0x9584,
+	0x080c, 0x151b, 0x00fe, 0x0005, 0x2001, 0x020d, 0x2003, 0x0020,
+	0x781f, 0x0300, 0x00fe, 0x0005, 0x781c, 0xd08c, 0x0904, 0x7b8b,
+	0x68bc, 0x90aa, 0x0005, 0x0a04, 0x8167, 0x7d44, 0x7c40, 0x9584,
 	0x00f6, 0x1510, 0x9484, 0x7000, 0x0140, 0x908a, 0x2000, 0x1260,
-	0x9584, 0x0700, 0x8007, 0x0804, 0x7c12, 0x7000, 0x9084, 0xff00,
+	0x9584, 0x0700, 0x8007, 0x0804, 0x7b92, 0x7000, 0x9084, 0xff00,
 	0x9086, 0x8100, 0x0da8, 0x00b0, 0x9484, 0x0fff, 0x1130, 0x7000,
-	0x9084, 0xff00, 0x9086, 0x8100, 0x11c0, 0x080c, 0xdbeb, 0x080c,
-	0x811c, 0x7817, 0x0140, 0x00a8, 0x9584, 0x0076, 0x1118, 0x080c,
-	0x817a, 0x19c0, 0xd5a4, 0x0148, 0x0046, 0x0056, 0x080c, 0x7c6d,
-	0x080c, 0x226f, 0x005e, 0x004e, 0x0020, 0x080c, 0xdbeb, 0x7817,
-	0x0140, 0x080c, 0x7207, 0x0168, 0x2001, 0x0111, 0x2004, 0xd08c,
+	0x9084, 0xff00, 0x9086, 0x8100, 0x11c0, 0x080c, 0xdb52, 0x080c,
+	0x809c, 0x7817, 0x0140, 0x00a8, 0x9584, 0x0076, 0x1118, 0x080c,
+	0x80fa, 0x19c0, 0xd5a4, 0x0148, 0x0046, 0x0056, 0x080c, 0x7bed,
+	0x080c, 0x2169, 0x005e, 0x004e, 0x0020, 0x080c, 0xdb52, 0x7817,
+	0x0140, 0x080c, 0x717f, 0x0168, 0x2001, 0x0111, 0x2004, 0xd08c,
 	0x0140, 0x688f, 0x0000, 0x2001, 0x0110, 0x2003, 0x0008, 0x2003,
-	0x0000, 0x080c, 0x7c4e, 0x2001, 0x19c8, 0x2004, 0x9005, 0x090c,
-	0x8c10, 0x0005, 0x0002, 0x7c24, 0x7f24, 0x7c1b, 0x7c1b, 0x7c1b,
-	0x7c1b, 0x7c1b, 0x7c1b, 0x7817, 0x0140, 0x2001, 0x19c8, 0x2004,
-	0x9005, 0x090c, 0x8c10, 0x0005, 0x7000, 0x908c, 0xff00, 0x9194,
+	0x0000, 0x080c, 0x7bce, 0x2001, 0x19cb, 0x2004, 0x9005, 0x090c,
+	0x8b90, 0x0005, 0x0002, 0x7ba4, 0x7ea4, 0x7b9b, 0x7b9b, 0x7b9b,
+	0x7b9b, 0x7b9b, 0x7b9b, 0x7817, 0x0140, 0x2001, 0x19cb, 0x2004,
+	0x9005, 0x090c, 0x8b90, 0x0005, 0x7000, 0x908c, 0xff00, 0x9194,
 	0xf000, 0x810f, 0x9484, 0x0fff, 0x688e, 0x9286, 0x2000, 0x1150,
-	0x6800, 0x9086, 0x0001, 0x1118, 0x080c, 0x5641, 0x0070, 0x080c,
-	0x7c8d, 0x0058, 0x9286, 0x3000, 0x1118, 0x080c, 0x7e5c, 0x0028,
-	0x9286, 0x8000, 0x1110, 0x080c, 0x8043, 0x7817, 0x0140, 0x2001,
-	0x19c8, 0x2004, 0x9005, 0x090c, 0x8c10, 0x0005, 0x2001, 0x1810,
+	0x6800, 0x9086, 0x0001, 0x1118, 0x080c, 0x5546, 0x0070, 0x080c,
+	0x7c0d, 0x0058, 0x9286, 0x3000, 0x1118, 0x080c, 0x7ddc, 0x0028,
+	0x9286, 0x8000, 0x1110, 0x080c, 0x7fc3, 0x7817, 0x0140, 0x2001,
+	0x19cb, 0x2004, 0x9005, 0x090c, 0x8b90, 0x0005, 0x2001, 0x1810,
 	0x2004, 0xd08c, 0x0178, 0x2001, 0x1800, 0x2004, 0x9086, 0x0003,
-	0x1148, 0x0026, 0x0036, 0x2011, 0x8048, 0x2518, 0x080c, 0x4b1f,
+	0x1148, 0x0026, 0x0036, 0x2011, 0x8048, 0x2518, 0x080c, 0x4a18,
 	0x003e, 0x002e, 0x0005, 0x0036, 0x0046, 0x0056, 0x00f6, 0x2079,
 	0x0200, 0x2019, 0xfffe, 0x7c30, 0x0050, 0x0036, 0x0046, 0x0056,
 	0x00f6, 0x2079, 0x0200, 0x7d44, 0x7c40, 0x2019, 0xffff, 0x2001,
 	0x1810, 0x2004, 0xd08c, 0x0160, 0x2001, 0x1800, 0x2004, 0x9086,
-	0x0003, 0x1130, 0x0026, 0x2011, 0x8048, 0x080c, 0x4b1f, 0x002e,
+	0x0003, 0x1130, 0x0026, 0x2011, 0x8048, 0x080c, 0x4a18, 0x002e,
 	0x00fe, 0x005e, 0x004e, 0x003e, 0x0005, 0x00b6, 0x00c6, 0x7010,
 	0x9084, 0xff00, 0x8007, 0x9096, 0x0001, 0x0120, 0x9096, 0x0023,
-	0x1904, 0x7e2d, 0x9186, 0x0023, 0x15c0, 0x080c, 0x80e1, 0x0904,
-	0x7e2d, 0x6120, 0x9186, 0x0001, 0x0150, 0x9186, 0x0004, 0x0138,
-	0x9186, 0x0008, 0x0120, 0x9186, 0x000a, 0x1904, 0x7e2d, 0x7124,
+	0x1904, 0x7dad, 0x9186, 0x0023, 0x15c0, 0x080c, 0x8061, 0x0904,
+	0x7dad, 0x6120, 0x9186, 0x0001, 0x0150, 0x9186, 0x0004, 0x0138,
+	0x9186, 0x0008, 0x0120, 0x9186, 0x000a, 0x1904, 0x7dad, 0x7124,
 	0x610a, 0x7030, 0x908e, 0x0200, 0x1130, 0x2009, 0x0015, 0x080c,
-	0xa15d, 0x0804, 0x7e2d, 0x908e, 0x0214, 0x0118, 0x908e, 0x0210,
-	0x1130, 0x2009, 0x0015, 0x080c, 0xa15d, 0x0804, 0x7e2d, 0x908e,
-	0x0100, 0x1904, 0x7e2d, 0x7034, 0x9005, 0x1904, 0x7e2d, 0x2009,
-	0x0016, 0x080c, 0xa15d, 0x0804, 0x7e2d, 0x9186, 0x0022, 0x1904,
-	0x7e2d, 0x7030, 0x908e, 0x0300, 0x1580, 0x68d8, 0xd0a4, 0x0528,
+	0xa053, 0x0804, 0x7dad, 0x908e, 0x0214, 0x0118, 0x908e, 0x0210,
+	0x1130, 0x2009, 0x0015, 0x080c, 0xa053, 0x0804, 0x7dad, 0x908e,
+	0x0100, 0x1904, 0x7dad, 0x7034, 0x9005, 0x1904, 0x7dad, 0x2009,
+	0x0016, 0x080c, 0xa053, 0x0804, 0x7dad, 0x9186, 0x0022, 0x1904,
+	0x7dad, 0x7030, 0x908e, 0x0300, 0x1580, 0x68d8, 0xd0a4, 0x0528,
 	0xc0b5, 0x68da, 0x7100, 0x918c, 0x00ff, 0x697a, 0x7004, 0x687e,
 	0x00f6, 0x2079, 0x0100, 0x79e6, 0x78ea, 0x0006, 0x9084, 0x00ff,
-	0x0016, 0x2008, 0x080c, 0x27b7, 0x7932, 0x7936, 0x001e, 0x000e,
-	0x00fe, 0x080c, 0x276e, 0x695a, 0x703c, 0x00e6, 0x2071, 0x0140,
+	0x0016, 0x2008, 0x080c, 0x26b7, 0x7932, 0x7936, 0x001e, 0x000e,
+	0x00fe, 0x080c, 0x266e, 0x695a, 0x703c, 0x00e6, 0x2071, 0x0140,
 	0x7086, 0x2071, 0x1800, 0x70b2, 0x00ee, 0x7034, 0x9005, 0x1904,
-	0x7e2d, 0x2009, 0x0017, 0x0804, 0x7ddd, 0x908e, 0x0400, 0x1190,
-	0x7034, 0x9005, 0x1904, 0x7e2d, 0x080c, 0x7207, 0x0120, 0x2009,
-	0x001d, 0x0804, 0x7ddd, 0x68d8, 0xc0a5, 0x68da, 0x2009, 0x0030,
-	0x0804, 0x7ddd, 0x908e, 0x0500, 0x1140, 0x7034, 0x9005, 0x1904,
-	0x7e2d, 0x2009, 0x0018, 0x0804, 0x7ddd, 0x908e, 0x2010, 0x1120,
-	0x2009, 0x0019, 0x0804, 0x7ddd, 0x908e, 0x2110, 0x1120, 0x2009,
-	0x001a, 0x0804, 0x7ddd, 0x908e, 0x5200, 0x1140, 0x7034, 0x9005,
-	0x1904, 0x7e2d, 0x2009, 0x001b, 0x0804, 0x7ddd, 0x908e, 0x5000,
-	0x1140, 0x7034, 0x9005, 0x1904, 0x7e2d, 0x2009, 0x001c, 0x0804,
-	0x7ddd, 0x908e, 0x1300, 0x1120, 0x2009, 0x0034, 0x0804, 0x7ddd,
-	0x908e, 0x1200, 0x1140, 0x7034, 0x9005, 0x1904, 0x7e2d, 0x2009,
-	0x0024, 0x0804, 0x7ddd, 0x908c, 0xff00, 0x918e, 0x2400, 0x1170,
-	0x2009, 0x002d, 0x2001, 0x1810, 0x2004, 0xd09c, 0x0904, 0x7ddd,
-	0x080c, 0xcc07, 0x1904, 0x7e2d, 0x0804, 0x7ddb, 0x908c, 0xff00,
-	0x918e, 0x5300, 0x1120, 0x2009, 0x002a, 0x0804, 0x7ddd, 0x908e,
-	0x0f00, 0x1120, 0x2009, 0x0020, 0x0804, 0x7ddd, 0x908e, 0x6104,
+	0x7dad, 0x2009, 0x0017, 0x0804, 0x7d5d, 0x908e, 0x0400, 0x1190,
+	0x7034, 0x9005, 0x1904, 0x7dad, 0x080c, 0x717f, 0x0120, 0x2009,
+	0x001d, 0x0804, 0x7d5d, 0x68d8, 0xc0a5, 0x68da, 0x2009, 0x0030,
+	0x0804, 0x7d5d, 0x908e, 0x0500, 0x1140, 0x7034, 0x9005, 0x1904,
+	0x7dad, 0x2009, 0x0018, 0x0804, 0x7d5d, 0x908e, 0x2010, 0x1120,
+	0x2009, 0x0019, 0x0804, 0x7d5d, 0x908e, 0x2110, 0x1120, 0x2009,
+	0x001a, 0x0804, 0x7d5d, 0x908e, 0x5200, 0x1140, 0x7034, 0x9005,
+	0x1904, 0x7dad, 0x2009, 0x001b, 0x0804, 0x7d5d, 0x908e, 0x5000,
+	0x1140, 0x7034, 0x9005, 0x1904, 0x7dad, 0x2009, 0x001c, 0x0804,
+	0x7d5d, 0x908e, 0x1300, 0x1120, 0x2009, 0x0034, 0x0804, 0x7d5d,
+	0x908e, 0x1200, 0x1140, 0x7034, 0x9005, 0x1904, 0x7dad, 0x2009,
+	0x0024, 0x0804, 0x7d5d, 0x908c, 0xff00, 0x918e, 0x2400, 0x1170,
+	0x2009, 0x002d, 0x2001, 0x1810, 0x2004, 0xd09c, 0x0904, 0x7d5d,
+	0x080c, 0xcb4c, 0x1904, 0x7dad, 0x0804, 0x7d5b, 0x908c, 0xff00,
+	0x918e, 0x5300, 0x1120, 0x2009, 0x002a, 0x0804, 0x7d5d, 0x908e,
+	0x0f00, 0x1120, 0x2009, 0x0020, 0x0804, 0x7d5d, 0x908e, 0x6104,
 	0x1528, 0x2029, 0x0205, 0x2011, 0x026d, 0x8208, 0x2204, 0x9082,
 	0x0004, 0x8004, 0x8004, 0x20a8, 0x2011, 0x8015, 0x211c, 0x8108,
-	0x0046, 0x2124, 0x080c, 0x4b1f, 0x004e, 0x8108, 0x0f04, 0x7da9,
+	0x0046, 0x2124, 0x080c, 0x4a18, 0x004e, 0x8108, 0x0f04, 0x7d29,
 	0x9186, 0x0280, 0x1d88, 0x2504, 0x8000, 0x202a, 0x2009, 0x0260,
 	0x0c58, 0x202b, 0x0000, 0x2009, 0x0023, 0x0478, 0x908e, 0x6000,
 	0x1118, 0x2009, 0x003f, 0x0448, 0x908e, 0x7800, 0x1118, 0x2009,
@@ -3822,132 +3806,132 @@ unsigned short risc_code01[] = { 
 	0x918e, 0x5600, 0x1118, 0x2009, 0x004f, 0x0078, 0x908c, 0xff00,
 	0x918e, 0x5700, 0x1118, 0x2009, 0x0050, 0x0038, 0x2009, 0x001d,
 	0x6838, 0xd0d4, 0x0110, 0x2009, 0x004c, 0x0016, 0x2011, 0x0263,
-	0x2204, 0x8211, 0x220c, 0x080c, 0x276e, 0x1904, 0x7e30, 0x080c,
-	0x643f, 0x1904, 0x7e30, 0xbe12, 0xbd16, 0x001e, 0x0016, 0x080c,
-	0x7207, 0x01c0, 0x68d8, 0xd08c, 0x1148, 0x7000, 0x9084, 0x00ff,
+	0x2204, 0x8211, 0x220c, 0x080c, 0x266e, 0x1904, 0x7db0, 0x080c,
+	0x6344, 0x1904, 0x7db0, 0xbe12, 0xbd16, 0x001e, 0x0016, 0x080c,
+	0x717f, 0x01c0, 0x68d8, 0xd08c, 0x1148, 0x7000, 0x9084, 0x00ff,
 	0x1188, 0x7004, 0x9084, 0xff00, 0x1168, 0x0040, 0x6878, 0x9606,
 	0x1148, 0x687c, 0x9506, 0x9084, 0xff00, 0x1120, 0x9584, 0x00ff,
 	0xb8b2, 0x0080, 0xb8b0, 0x9005, 0x1168, 0x9186, 0x0046, 0x1150,
 	0x6878, 0x9606, 0x1138, 0x687c, 0x9506, 0x9084, 0xff00, 0x1110,
-	0x001e, 0x0098, 0x080c, 0xa08d, 0x01a8, 0x2b08, 0x6112, 0x6023,
+	0x001e, 0x0098, 0x080c, 0x9f7f, 0x01a8, 0x2b08, 0x6112, 0x6023,
 	0x0004, 0x7120, 0x610a, 0x001e, 0x9186, 0x004c, 0x1110, 0x6023,
-	0x000a, 0x0016, 0x001e, 0x080c, 0xa15d, 0x00ce, 0x00be, 0x0005,
+	0x000a, 0x0016, 0x001e, 0x080c, 0xa053, 0x00ce, 0x00be, 0x0005,
 	0x001e, 0x0cd8, 0x2001, 0x180e, 0x2004, 0xd0ec, 0x0120, 0x2011,
-	0x8049, 0x080c, 0x4b1f, 0x080c, 0xa130, 0x0d90, 0x2b08, 0x6112,
+	0x8049, 0x080c, 0x4a18, 0x080c, 0xa026, 0x0d90, 0x2b08, 0x6112,
 	0x6023, 0x0004, 0x7120, 0x610a, 0x001e, 0x0016, 0x9186, 0x0017,
 	0x0118, 0x9186, 0x0030, 0x1128, 0x6007, 0x0009, 0x6017, 0x2900,
 	0x0020, 0x6007, 0x0051, 0x6017, 0x0000, 0x602f, 0x0009, 0x6003,
-	0x0001, 0x080c, 0x86c1, 0x08a0, 0x080c, 0x8206, 0x1158, 0x080c,
-	0x32ae, 0x1140, 0x7010, 0x9084, 0xff00, 0x8007, 0x908e, 0x0008,
+	0x0001, 0x080c, 0x8641, 0x08a0, 0x080c, 0x8186, 0x1158, 0x080c,
+	0x31ce, 0x1140, 0x7010, 0x9084, 0xff00, 0x8007, 0x908e, 0x0008,
 	0x1108, 0x0009, 0x0005, 0x00b6, 0x00c6, 0x0046, 0x7000, 0x908c,
-	0xff00, 0x810f, 0x9186, 0x0033, 0x11e8, 0x080c, 0x80e1, 0x0904,
-	0x7ebc, 0x7124, 0x610a, 0x7030, 0x908e, 0x0200, 0x1140, 0x7034,
-	0x9005, 0x15d0, 0x2009, 0x0015, 0x080c, 0xa15d, 0x04a8, 0x908e,
+	0xff00, 0x810f, 0x9186, 0x0033, 0x11e8, 0x080c, 0x8061, 0x0904,
+	0x7e3c, 0x7124, 0x610a, 0x7030, 0x908e, 0x0200, 0x1140, 0x7034,
+	0x9005, 0x15d0, 0x2009, 0x0015, 0x080c, 0xa053, 0x04a8, 0x908e,
 	0x0100, 0x1590, 0x7034, 0x9005, 0x1578, 0x2009, 0x0016, 0x080c,
-	0xa15d, 0x0450, 0x9186, 0x0032, 0x1538, 0x7030, 0x908e, 0x1400,
+	0xa053, 0x0450, 0x9186, 0x0032, 0x1538, 0x7030, 0x908e, 0x1400,
 	0x1518, 0x2009, 0x0038, 0x0016, 0x2011, 0x0263, 0x2204, 0x8211,
-	0x220c, 0x080c, 0x276e, 0x11b8, 0x080c, 0x643f, 0x11a0, 0xbe12,
-	0xbd16, 0x080c, 0xa08d, 0x0178, 0x2b08, 0x6112, 0x080c, 0xc2b3,
-	0x6023, 0x0004, 0x7120, 0x610a, 0x001e, 0x080c, 0xa15d, 0x080c,
-	0x8c10, 0x0010, 0x00ce, 0x001e, 0x004e, 0x00ce, 0x00be, 0x0005,
+	0x220c, 0x080c, 0x266e, 0x11b8, 0x080c, 0x6344, 0x11a0, 0xbe12,
+	0xbd16, 0x080c, 0x9f7f, 0x0178, 0x2b08, 0x6112, 0x080c, 0xc1b7,
+	0x6023, 0x0004, 0x7120, 0x610a, 0x001e, 0x080c, 0xa053, 0x080c,
+	0x8b90, 0x0010, 0x00ce, 0x001e, 0x004e, 0x00ce, 0x00be, 0x0005,
 	0x00b6, 0x0046, 0x00e6, 0x00d6, 0x2028, 0x2130, 0x9696, 0x00ff,
 	0x11b8, 0x9592, 0xfffc, 0x02a0, 0x9596, 0xfffd, 0x1120, 0x2009,
-	0x007f, 0x0804, 0x7f1e, 0x9596, 0xfffe, 0x1120, 0x2009, 0x007e,
-	0x0804, 0x7f1e, 0x9596, 0xfffc, 0x1118, 0x2009, 0x0080, 0x04f0,
+	0x007f, 0x0804, 0x7e9e, 0x9596, 0xfffe, 0x1120, 0x2009, 0x007e,
+	0x0804, 0x7e9e, 0x9596, 0xfffc, 0x1118, 0x2009, 0x0080, 0x04f0,
 	0x2011, 0x0000, 0x2019, 0x1836, 0x231c, 0xd3ac, 0x0130, 0x9026,
 	0x20a9, 0x0800, 0x2071, 0x1000, 0x0030, 0x2021, 0x0081, 0x20a9,
 	0x077f, 0x2071, 0x1081, 0x2e1c, 0x93dd, 0x0000, 0x1140, 0x82ff,
 	0x11d0, 0x9496, 0x00ff, 0x01b8, 0x2410, 0xc2fd, 0x00a0, 0xbf10,
 	0x2600, 0x9706, 0xb814, 0x1120, 0x9546, 0x1110, 0x2408, 0x00b0,
 	0x9745, 0x1148, 0x94c6, 0x007e, 0x0130, 0x94c6, 0x007f, 0x0118,
-	0x94c6, 0x0080, 0x1d20, 0x8420, 0x8e70, 0x1f04, 0x7ef3, 0x82ff,
+	0x94c6, 0x0080, 0x1d20, 0x8420, 0x8e70, 0x1f04, 0x7e73, 0x82ff,
 	0x1118, 0x9085, 0x0001, 0x0018, 0xc2fc, 0x2208, 0x9006, 0x00de,
 	0x00ee, 0x004e, 0x00be, 0x0005, 0x2001, 0x1836, 0x200c, 0x9184,
 	0x0080, 0x0110, 0xd18c, 0x0138, 0x7000, 0x908c, 0xff00, 0x810f,
-	0x9184, 0x000f, 0x004a, 0x7817, 0x0140, 0x2001, 0x19c8, 0x2004,
-	0x9005, 0x090c, 0x8c10, 0x0005, 0x7f4c, 0x7f4c, 0x7f4c, 0x80f3,
-	0x7f4c, 0x7f55, 0x7f80, 0x800e, 0x7f4c, 0x7f4c, 0x7f4c, 0x7f4c,
-	0x7f4c, 0x7f4c, 0x7f4c, 0x7f4c, 0x7817, 0x0140, 0x2001, 0x19c8,
-	0x2004, 0x9005, 0x090c, 0x8c10, 0x0005, 0x00b6, 0x7110, 0xd1bc,
+	0x9184, 0x000f, 0x004a, 0x7817, 0x0140, 0x2001, 0x19cb, 0x2004,
+	0x9005, 0x090c, 0x8b90, 0x0005, 0x7ecc, 0x7ecc, 0x7ecc, 0x8073,
+	0x7ecc, 0x7ed5, 0x7f00, 0x7f8e, 0x7ecc, 0x7ecc, 0x7ecc, 0x7ecc,
+	0x7ecc, 0x7ecc, 0x7ecc, 0x7ecc, 0x7817, 0x0140, 0x2001, 0x19cb,
+	0x2004, 0x9005, 0x090c, 0x8b90, 0x0005, 0x00b6, 0x7110, 0xd1bc,
 	0x01e8, 0x7120, 0x2160, 0x9c8c, 0x0007, 0x11c0, 0x9c8a, 0x1cd0,
 	0x02a8, 0x6864, 0x9c02, 0x1290, 0x7008, 0x9084, 0x00ff, 0x6110,
 	0x2158, 0xb910, 0x9106, 0x1150, 0x700c, 0xb914, 0x9106, 0x1130,
-	0x7124, 0x610a, 0x2009, 0x0046, 0x080c, 0xa15d, 0x7817, 0x0140,
-	0x2001, 0x19c8, 0x2004, 0x9005, 0x090c, 0x8c10, 0x00be, 0x0005,
-	0x00b6, 0x00c6, 0x9484, 0x0fff, 0x0904, 0x7fe4, 0x7110, 0xd1bc,
-	0x1904, 0x7fe4, 0x7108, 0x700c, 0x2028, 0x918c, 0x00ff, 0x2130,
-	0x9094, 0xff00, 0x15b0, 0x81ff, 0x15a0, 0x9080, 0x32e9, 0x200d,
-	0x918c, 0xff00, 0x810f, 0x2001, 0x0080, 0x9106, 0x0904, 0x7fe4,
-	0x080c, 0x643f, 0x1904, 0x7fe4, 0xbe12, 0xbd16, 0xb800, 0xd0ec,
+	0x7124, 0x610a, 0x2009, 0x0046, 0x080c, 0xa053, 0x7817, 0x0140,
+	0x2001, 0x19cb, 0x2004, 0x9005, 0x090c, 0x8b90, 0x00be, 0x0005,
+	0x00b6, 0x00c6, 0x9484, 0x0fff, 0x0904, 0x7f64, 0x7110, 0xd1bc,
+	0x1904, 0x7f64, 0x7108, 0x700c, 0x2028, 0x918c, 0x00ff, 0x2130,
+	0x9094, 0xff00, 0x15b0, 0x81ff, 0x15a0, 0x9080, 0x3209, 0x200d,
+	0x918c, 0xff00, 0x810f, 0x2001, 0x0080, 0x9106, 0x0904, 0x7f64,
+	0x080c, 0x6344, 0x1904, 0x7f64, 0xbe12, 0xbd16, 0xb800, 0xd0ec,
 	0x15d8, 0xba04, 0x9294, 0xff00, 0x9286, 0x0600, 0x11a0, 0x080c,
-	0xa08d, 0x05e8, 0x2b08, 0x7028, 0x6046, 0x702c, 0x604a, 0x6112,
+	0x9f7f, 0x05e8, 0x2b08, 0x7028, 0x6046, 0x702c, 0x604a, 0x6112,
 	0x6023, 0x0006, 0x7120, 0x610a, 0x7130, 0x6156, 0x2009, 0x0044,
-	0x080c, 0xce65, 0x0408, 0x080c, 0x67c3, 0x1138, 0xb807, 0x0606,
-	0x0c30, 0x190c, 0x7ec0, 0x11c0, 0x0898, 0x080c, 0xa08d, 0x2b08,
+	0x080c, 0xcdcd, 0x0408, 0x080c, 0x66ca, 0x1138, 0xb807, 0x0606,
+	0x0c30, 0x190c, 0x7e40, 0x11c0, 0x0898, 0x080c, 0x9f7f, 0x2b08,
 	0x0198, 0x6112, 0x6023, 0x0004, 0x7120, 0x610a, 0x9286, 0x0400,
 	0x1118, 0x6007, 0x0005, 0x0010, 0x6007, 0x0001, 0x6003, 0x0001,
-	0x080c, 0x86c1, 0x080c, 0x8c10, 0x7817, 0x0140, 0x2001, 0x19c8,
-	0x2004, 0x9005, 0x090c, 0x8c10, 0x00ce, 0x00be, 0x0005, 0x2001,
-	0x180e, 0x2004, 0xd0ec, 0x0120, 0x2011, 0x8049, 0x080c, 0x4b1f,
-	0x080c, 0xa130, 0x0d48, 0x2b08, 0x6112, 0x6023, 0x0006, 0x7120,
+	0x080c, 0x8641, 0x080c, 0x8b90, 0x7817, 0x0140, 0x2001, 0x19cb,
+	0x2004, 0x9005, 0x090c, 0x8b90, 0x00ce, 0x00be, 0x0005, 0x2001,
+	0x180e, 0x2004, 0xd0ec, 0x0120, 0x2011, 0x8049, 0x080c, 0x4a18,
+	0x080c, 0xa026, 0x0d48, 0x2b08, 0x6112, 0x6023, 0x0006, 0x7120,
 	0x610a, 0x7130, 0x6156, 0x6017, 0xf300, 0x6003, 0x0001, 0x6007,
-	0x0041, 0x080c, 0x8679, 0x080c, 0x8c10, 0x08b0, 0x00b6, 0x7110,
+	0x0041, 0x080c, 0x85f9, 0x080c, 0x8b90, 0x08b0, 0x00b6, 0x7110,
 	0xd1bc, 0x01e8, 0x7020, 0x2060, 0x9c84, 0x0007, 0x11c0, 0x9c82,
 	0x1cd0, 0x02a8, 0x6864, 0x9c02, 0x1290, 0x7008, 0x9084, 0x00ff,
 	0x6110, 0x2158, 0xb910, 0x9106, 0x1150, 0x700c, 0xb914, 0x9106,
-	0x1130, 0x7124, 0x610a, 0x2009, 0x0045, 0x080c, 0xa15d, 0x7817,
-	0x0140, 0x2001, 0x19c8, 0x2004, 0x9005, 0x090c, 0x8c10, 0x00be,
+	0x1130, 0x7124, 0x610a, 0x2009, 0x0045, 0x080c, 0xa053, 0x7817,
+	0x0140, 0x2001, 0x19cb, 0x2004, 0x9005, 0x090c, 0x8b90, 0x00be,
 	0x0005, 0x6120, 0x9186, 0x0002, 0x0128, 0x9186, 0x0005, 0x0110,
-	0x9085, 0x0001, 0x0005, 0x080c, 0x8206, 0x1180, 0x080c, 0x32ae,
+	0x9085, 0x0001, 0x0005, 0x080c, 0x8186, 0x1180, 0x080c, 0x31ce,
 	0x1168, 0x7010, 0x9084, 0xff00, 0x8007, 0x9086, 0x0000, 0x1130,
-	0x9184, 0x000f, 0x908a, 0x0006, 0x1208, 0x000b, 0x0005, 0x805d,
-	0x805e, 0x805d, 0x805d, 0x80c3, 0x80d2, 0x0005, 0x00b6, 0x700c,
-	0x7108, 0x080c, 0x276e, 0x1904, 0x80c1, 0x080c, 0x643f, 0x1904,
-	0x80c1, 0xbe12, 0xbd16, 0x7110, 0xd1bc, 0x0540, 0x702c, 0xd084,
-	0x1120, 0xb800, 0xd0bc, 0x1904, 0x80c1, 0x080c, 0x67c3, 0x0148,
-	0x9086, 0x0004, 0x0130, 0x080c, 0x67cb, 0x0118, 0x9086, 0x0004,
-	0x1588, 0x00c6, 0x080c, 0x80e1, 0x00ce, 0x05d8, 0x080c, 0xa08d,
-	0x2b08, 0x05b8, 0x6112, 0x080c, 0xc2b3, 0x6023, 0x0002, 0x7120,
-	0x610a, 0x2009, 0x0088, 0x080c, 0xa15d, 0x0458, 0x080c, 0x67c3,
-	0x0148, 0x9086, 0x0004, 0x0130, 0x080c, 0x67cb, 0x0118, 0x9086,
-	0x0004, 0x1180, 0x080c, 0xa08d, 0x2b08, 0x01d8, 0x6112, 0x080c,
-	0xc2b3, 0x6023, 0x0005, 0x7120, 0x610a, 0x2009, 0x0088, 0x080c,
-	0xa15d, 0x0078, 0x080c, 0xa08d, 0x2b08, 0x0158, 0x6112, 0x080c,
-	0xc2b3, 0x6023, 0x0004, 0x7120, 0x610a, 0x2009, 0x0001, 0x080c,
-	0xa15d, 0x00be, 0x0005, 0x7110, 0xd1bc, 0x0158, 0x00d1, 0x0148,
-	0x080c, 0x8039, 0x1130, 0x7124, 0x610a, 0x2009, 0x0089, 0x080c,
-	0xa15d, 0x0005, 0x7110, 0xd1bc, 0x0158, 0x0059, 0x0148, 0x080c,
-	0x8039, 0x1130, 0x7124, 0x610a, 0x2009, 0x008a, 0x080c, 0xa15d,
+	0x9184, 0x000f, 0x908a, 0x0006, 0x1208, 0x000b, 0x0005, 0x7fdd,
+	0x7fde, 0x7fdd, 0x7fdd, 0x8043, 0x8052, 0x0005, 0x00b6, 0x700c,
+	0x7108, 0x080c, 0x266e, 0x1904, 0x8041, 0x080c, 0x6344, 0x1904,
+	0x8041, 0xbe12, 0xbd16, 0x7110, 0xd1bc, 0x0540, 0x702c, 0xd084,
+	0x1120, 0xb800, 0xd0bc, 0x1904, 0x8041, 0x080c, 0x66ca, 0x0148,
+	0x9086, 0x0004, 0x0130, 0x080c, 0x66d2, 0x0118, 0x9086, 0x0004,
+	0x1588, 0x00c6, 0x080c, 0x8061, 0x00ce, 0x05d8, 0x080c, 0x9f7f,
+	0x2b08, 0x05b8, 0x6112, 0x080c, 0xc1b7, 0x6023, 0x0002, 0x7120,
+	0x610a, 0x2009, 0x0088, 0x080c, 0xa053, 0x0458, 0x080c, 0x66ca,
+	0x0148, 0x9086, 0x0004, 0x0130, 0x080c, 0x66d2, 0x0118, 0x9086,
+	0x0004, 0x1180, 0x080c, 0x9f7f, 0x2b08, 0x01d8, 0x6112, 0x080c,
+	0xc1b7, 0x6023, 0x0005, 0x7120, 0x610a, 0x2009, 0x0088, 0x080c,
+	0xa053, 0x0078, 0x080c, 0x9f7f, 0x2b08, 0x0158, 0x6112, 0x080c,
+	0xc1b7, 0x6023, 0x0004, 0x7120, 0x610a, 0x2009, 0x0001, 0x080c,
+	0xa053, 0x00be, 0x0005, 0x7110, 0xd1bc, 0x0158, 0x00d1, 0x0148,
+	0x080c, 0x7fb9, 0x1130, 0x7124, 0x610a, 0x2009, 0x0089, 0x080c,
+	0xa053, 0x0005, 0x7110, 0xd1bc, 0x0158, 0x0059, 0x0148, 0x080c,
+	0x7fb9, 0x1130, 0x7124, 0x610a, 0x2009, 0x008a, 0x080c, 0xa053,
 	0x0005, 0x7020, 0x2060, 0x9c84, 0x0007, 0x1158, 0x9c82, 0x1cd0,
 	0x0240, 0x2001, 0x1819, 0x2004, 0x9c02, 0x1218, 0x9085, 0x0001,
 	0x0005, 0x9006, 0x0ce8, 0x00b6, 0x7110, 0xd1bc, 0x11d8, 0x7024,
 	0x2060, 0x9c84, 0x0007, 0x11b0, 0x9c82, 0x1cd0, 0x0298, 0x6864,
 	0x9c02, 0x1280, 0x7008, 0x9084, 0x00ff, 0x6110, 0x2158, 0xb910,
 	0x9106, 0x1140, 0x700c, 0xb914, 0x9106, 0x1120, 0x2009, 0x0051,
-	0x080c, 0xa15d, 0x7817, 0x0140, 0x2001, 0x19c8, 0x2004, 0x9005,
-	0x090c, 0x8c10, 0x00be, 0x0005, 0x2031, 0x0105, 0x0069, 0x0005,
+	0x080c, 0xa053, 0x7817, 0x0140, 0x2001, 0x19cb, 0x2004, 0x9005,
+	0x090c, 0x8b90, 0x00be, 0x0005, 0x2031, 0x0105, 0x0069, 0x0005,
 	0x2031, 0x0206, 0x0049, 0x0005, 0x2031, 0x0207, 0x0029, 0x0005,
 	0x2031, 0x0213, 0x0009, 0x0005, 0x00c6, 0x0096, 0x00f6, 0x7000,
-	0x9084, 0xf000, 0x9086, 0xc000, 0x05d0, 0x080c, 0xa08d, 0x05b8,
+	0x9084, 0xf000, 0x9086, 0xc000, 0x05d0, 0x080c, 0x9f7f, 0x05b8,
 	0x0066, 0x00c6, 0x0046, 0x2011, 0x0263, 0x2204, 0x8211, 0x220c,
-	0x080c, 0x276e, 0x15a0, 0x080c, 0x643f, 0x1588, 0xbe12, 0xbd16,
-	0x2b00, 0x004e, 0x00ce, 0x6012, 0x080c, 0xc2b3, 0x080c, 0x1031,
+	0x080c, 0x266e, 0x15a0, 0x080c, 0x6344, 0x1588, 0xbe12, 0xbd16,
+	0x2b00, 0x004e, 0x00ce, 0x6012, 0x080c, 0xc1b7, 0x080c, 0x1043,
 	0x0510, 0x2900, 0x605a, 0x9006, 0xa802, 0xa866, 0xac6a, 0xa85c,
 	0x90f8, 0x001b, 0x20a9, 0x000e, 0xa860, 0x20e8, 0x20e1, 0x0000,
 	0x2fa0, 0x2e98, 0x4003, 0x006e, 0x6616, 0x6007, 0x003e, 0x6023,
-	0x0001, 0x6003, 0x0001, 0x080c, 0x86c1, 0x080c, 0x8c10, 0x00fe,
-	0x009e, 0x00ce, 0x0005, 0x080c, 0xa0e3, 0x006e, 0x0cc0, 0x004e,
+	0x0001, 0x6003, 0x0001, 0x080c, 0x8641, 0x080c, 0x8b90, 0x00fe,
+	0x009e, 0x00ce, 0x0005, 0x080c, 0x9fd5, 0x006e, 0x0cc0, 0x004e,
 	0x00ce, 0x0cc8, 0x00c6, 0x7000, 0x908c, 0xff00, 0x9184, 0xf000,
-	0x810f, 0x9086, 0x2000, 0x1904, 0x81d1, 0x9186, 0x0022, 0x15f0,
-	0x2001, 0x0111, 0x2004, 0x9005, 0x1904, 0x81d3, 0x7030, 0x908e,
-	0x0400, 0x0904, 0x81d3, 0x908e, 0x6000, 0x05e8, 0x908e, 0x5400,
+	0x810f, 0x9086, 0x2000, 0x1904, 0x8151, 0x9186, 0x0022, 0x15f0,
+	0x2001, 0x0111, 0x2004, 0x9005, 0x1904, 0x8153, 0x7030, 0x908e,
+	0x0400, 0x0904, 0x8153, 0x908e, 0x6000, 0x05e8, 0x908e, 0x5400,
 	0x05d0, 0x908e, 0x0300, 0x11d8, 0x2009, 0x1836, 0x210c, 0xd18c,
-	0x1590, 0xd1a4, 0x1580, 0x080c, 0x6781, 0x0588, 0x68ac, 0x9084,
+	0x1590, 0xd1a4, 0x1580, 0x080c, 0x6688, 0x0588, 0x68ac, 0x9084,
 	0x00ff, 0x7100, 0x918c, 0x00ff, 0x9106, 0x1518, 0x687c, 0x69ac,
 	0x918c, 0xff00, 0x9105, 0x7104, 0x9106, 0x11d8, 0x00e0, 0x2009,
 	0x0103, 0x210c, 0xd1b4, 0x11a8, 0x908e, 0x5200, 0x09e8, 0x908e,
 	0x0500, 0x09d0, 0x908e, 0x5000, 0x09b8, 0x0058, 0x9186, 0x0023,
-	0x1140, 0x080c, 0x80e1, 0x0128, 0x6004, 0x9086, 0x0002, 0x0118,
+	0x1140, 0x080c, 0x8061, 0x0128, 0x6004, 0x9086, 0x0002, 0x0118,
 	0x0000, 0x9006, 0x0010, 0x9085, 0x0001, 0x00ce, 0x0005, 0x7030,
 	0x908e, 0x0300, 0x0118, 0x908e, 0x5200, 0x1d98, 0x2001, 0x1836,
 	0x2004, 0x9084, 0x0009, 0x9086, 0x0008, 0x0d68, 0x0c50, 0x00f6,
@@ -3956,3192 +3940,3139 @@ unsigned short risc_code01[] = { 
 	0x7800, 0x9085, 0x1200, 0x7802, 0x00fe, 0x0005, 0x00e6, 0x2071,
 	0x1800, 0x7034, 0xc084, 0x7036, 0x00ee, 0x0005, 0x0016, 0x2001,
 	0x1836, 0x200c, 0x9184, 0x0080, 0x0118, 0xd18c, 0x0118, 0x9006,
-	0x001e, 0x0005, 0x9085, 0x0001, 0x0cd8, 0x2071, 0x19d2, 0x7003,
-	0x0003, 0x700f, 0x0361, 0x9006, 0x701a, 0x7072, 0x7012, 0x7017,
-	0x1cd0, 0x7007, 0x0000, 0x7026, 0x702b, 0x966c, 0x7032, 0x7037,
-	0x96d4, 0x703f, 0xffff, 0x7042, 0x7047, 0x546d, 0x704a, 0x705b,
-	0x8375, 0x080c, 0x104a, 0x090c, 0x0dfa, 0x2900, 0x703a, 0xa867,
-	0x0003, 0xa86f, 0x0100, 0xa8ab, 0xdcb0, 0x0005, 0x2071, 0x19d2,
-	0x1d04, 0x82c9, 0x2091, 0x6000, 0x700c, 0x8001, 0x700e, 0x1510,
+	0x001e, 0x0005, 0x9085, 0x0001, 0x0cd8, 0x2071, 0x19d5, 0x7003,
+	0x0003, 0x700f, 0x0361, 0x9006, 0x701a, 0x707a, 0x7012, 0x7017,
+	0x1cd0, 0x7007, 0x0000, 0x7026, 0x702b, 0x961b, 0x7032, 0x7037,
+	0x9683, 0x7047, 0xffff, 0x704a, 0x704f, 0x536e, 0x7052, 0x7063,
+	0x82f5, 0x080c, 0x105c, 0x090c, 0x0e02, 0x2900, 0x7042, 0xa867,
+	0x0003, 0xa86f, 0x0100, 0xa8ab, 0xdcb0, 0x0005, 0x2071, 0x19d5,
+	0x1d04, 0x8249, 0x2091, 0x6000, 0x700c, 0x8001, 0x700e, 0x1510,
 	0x2001, 0x187d, 0x2004, 0xd0c4, 0x0158, 0x3a00, 0xd08c, 0x1140,
-	0x20d1, 0x0000, 0x20d1, 0x0001, 0x20d1, 0x0000, 0x080c, 0x0dfa,
+	0x20d1, 0x0000, 0x20d1, 0x0001, 0x20d1, 0x0000, 0x080c, 0x0e02,
 	0x700f, 0x0361, 0x7007, 0x0001, 0x0126, 0x2091, 0x8000, 0x080c,
-	0x83ba, 0x7040, 0x900d, 0x0148, 0x8109, 0x7142, 0x1130, 0x7044,
+	0x833a, 0x7048, 0x900d, 0x0148, 0x8109, 0x714a, 0x1130, 0x704c,
 	0x080f, 0x0018, 0x0126, 0x2091, 0x8000, 0x7024, 0x900d, 0x0188,
 	0x7020, 0x8001, 0x7022, 0x1168, 0x7023, 0x0009, 0x8109, 0x7126,
 	0x9186, 0x03e8, 0x1110, 0x7028, 0x080f, 0x81ff, 0x1110, 0x7028,
 	0x080f, 0x7030, 0x900d, 0x0180, 0x702c, 0x8001, 0x702e, 0x1160,
 	0x702f, 0x0009, 0x8109, 0x7132, 0x0128, 0x9184, 0x007f, 0x090c,
-	0x9802, 0x0010, 0x7034, 0x080f, 0x703c, 0x9005, 0x0118, 0x0310,
-	0x8001, 0x703e, 0x704c, 0x900d, 0x0168, 0x7048, 0x8001, 0x704a,
-	0x1148, 0x704b, 0x0009, 0x8109, 0x714e, 0x1120, 0x7150, 0x714e,
-	0x7058, 0x080f, 0x7018, 0x900d, 0x01d8, 0x0016, 0x7070, 0x900d,
-	0x0158, 0x706c, 0x8001, 0x706e, 0x1138, 0x706f, 0x0009, 0x8109,
-	0x7172, 0x1110, 0x7074, 0x080f, 0x001e, 0x7008, 0x8001, 0x700a,
+	0x9701, 0x0010, 0x7034, 0x080f, 0x7044, 0x9005, 0x0118, 0x0310,
+	0x8001, 0x7046, 0x7054, 0x900d, 0x0168, 0x7050, 0x8001, 0x7052,
+	0x1148, 0x7053, 0x0009, 0x8109, 0x7156, 0x1120, 0x7158, 0x7156,
+	0x7060, 0x080f, 0x7018, 0x900d, 0x01d8, 0x0016, 0x7078, 0x900d,
+	0x0158, 0x7074, 0x8001, 0x7076, 0x1138, 0x7077, 0x0009, 0x8109,
+	0x717a, 0x1110, 0x707c, 0x080f, 0x001e, 0x7008, 0x8001, 0x700a,
 	0x1138, 0x700b, 0x0009, 0x8109, 0x711a, 0x1110, 0x701c, 0x080f,
-	0x012e, 0x7004, 0x0002, 0x82f1, 0x82f2, 0x830e, 0x00e6, 0x2071,
-	0x19d2, 0x7018, 0x9005, 0x1120, 0x711a, 0x721e, 0x700b, 0x0009,
-	0x00ee, 0x0005, 0x00e6, 0x0006, 0x2071, 0x19d2, 0x701c, 0x9206,
-	0x1120, 0x701a, 0x701e, 0x7072, 0x7076, 0x000e, 0x00ee, 0x0005,
-	0x00e6, 0x2071, 0x19d2, 0xb888, 0x9102, 0x0208, 0xb98a, 0x00ee,
-	0x0005, 0x0005, 0x00b6, 0x7110, 0x080c, 0x649f, 0x1168, 0xb888,
+	0x012e, 0x7004, 0x0002, 0x8271, 0x8272, 0x828e, 0x00e6, 0x2071,
+	0x19d5, 0x7018, 0x9005, 0x1120, 0x711a, 0x721e, 0x700b, 0x0009,
+	0x00ee, 0x0005, 0x00e6, 0x0006, 0x2071, 0x19d5, 0x701c, 0x9206,
+	0x1120, 0x701a, 0x701e, 0x707a, 0x707e, 0x000e, 0x00ee, 0x0005,
+	0x00e6, 0x2071, 0x19d5, 0xb888, 0x9102, 0x0208, 0xb98a, 0x00ee,
+	0x0005, 0x0005, 0x00b6, 0x7110, 0x080c, 0x63a4, 0x1168, 0xb888,
 	0x8001, 0x0250, 0xb88a, 0x1140, 0x0126, 0x2091, 0x8000, 0x0016,
-	0x080c, 0x8c10, 0x001e, 0x012e, 0x8108, 0x9182, 0x0800, 0x0218,
+	0x080c, 0x8b90, 0x001e, 0x012e, 0x8108, 0x9182, 0x0800, 0x0218,
 	0x900e, 0x7007, 0x0002, 0x7112, 0x00be, 0x0005, 0x7014, 0x2060,
 	0x0126, 0x2091, 0x8000, 0x6040, 0x9005, 0x0128, 0x8001, 0x6042,
-	0x1110, 0x080c, 0xc144, 0x6018, 0x9005, 0x0528, 0x8001, 0x601a,
+	0x1110, 0x080c, 0xc048, 0x6018, 0x9005, 0x0528, 0x8001, 0x601a,
 	0x1510, 0x6120, 0x9186, 0x0003, 0x0118, 0x9186, 0x0006, 0x11c8,
-	0x080c, 0xbe37, 0x01b0, 0x6014, 0x2048, 0xa884, 0x908a, 0x199a,
+	0x080c, 0xbd3b, 0x01b0, 0x6014, 0x2048, 0xa884, 0x908a, 0x199a,
 	0x0280, 0x9082, 0x1999, 0xa886, 0x908a, 0x199a, 0x0210, 0x2001,
 	0x1999, 0x8003, 0x800b, 0x810b, 0x9108, 0x611a, 0xa87c, 0xd0e4,
-	0x0110, 0x080c, 0xbb23, 0x012e, 0x9c88, 0x0018, 0x7116, 0x2001,
+	0x0110, 0x080c, 0xba41, 0x012e, 0x9c88, 0x0018, 0x7116, 0x2001,
 	0x1819, 0x2004, 0x9102, 0x0220, 0x7017, 0x1cd0, 0x7007, 0x0000,
-	0x0005, 0x00e6, 0x2071, 0x19d2, 0x7027, 0x07d0, 0x7023, 0x0009,
-	0x00ee, 0x0005, 0x2001, 0x19db, 0x2003, 0x0000, 0x0005, 0x00e6,
-	0x2071, 0x19d2, 0x7132, 0x702f, 0x0009, 0x00ee, 0x0005, 0x2011,
-	0x19de, 0x2013, 0x0000, 0x0005, 0x00e6, 0x2071, 0x19d2, 0x711a,
-	0x721e, 0x700b, 0x0009, 0x00ee, 0x0005, 0x0086, 0x0026, 0x7054,
-	0x8000, 0x7056, 0x2001, 0x19e0, 0x2044, 0xa06c, 0x9086, 0x0000,
-	0x0150, 0x7068, 0xa09a, 0x7064, 0xa096, 0x7060, 0xa092, 0x705c,
-	0xa08e, 0x080c, 0x112e, 0x002e, 0x008e, 0x0005, 0x0006, 0x0016,
+	0x0005, 0x00e6, 0x2071, 0x19d5, 0x7027, 0x07d0, 0x7023, 0x0009,
+	0x00ee, 0x0005, 0x2001, 0x19de, 0x2003, 0x0000, 0x0005, 0x00e6,
+	0x2071, 0x19d5, 0x7132, 0x702f, 0x0009, 0x00ee, 0x0005, 0x2011,
+	0x19e1, 0x2013, 0x0000, 0x0005, 0x00e6, 0x2071, 0x19d5, 0x711a,
+	0x721e, 0x700b, 0x0009, 0x00ee, 0x0005, 0x0086, 0x0026, 0x705c,
+	0x8000, 0x705e, 0x2001, 0x19e5, 0x2044, 0xa06c, 0x9086, 0x0000,
+	0x0150, 0x7070, 0xa09a, 0x706c, 0xa096, 0x7068, 0xa092, 0x7064,
+	0xa08e, 0x080c, 0x1140, 0x002e, 0x008e, 0x0005, 0x0006, 0x0016,
 	0x0096, 0x00a6, 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x0156,
-	0x080c, 0x823e, 0x015e, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be,
-	0x00ae, 0x009e, 0x001e, 0x000e, 0x0005, 0x00e6, 0x2071, 0x19d2,
-	0x7172, 0x7276, 0x706f, 0x0009, 0x00ee, 0x0005, 0x00e6, 0x0006,
-	0x2071, 0x19d2, 0x7074, 0x9206, 0x1110, 0x7072, 0x7076, 0x000e,
+	0x080c, 0x81be, 0x015e, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be,
+	0x00ae, 0x009e, 0x001e, 0x000e, 0x0005, 0x00e6, 0x2071, 0x19d5,
+	0x717a, 0x727e, 0x7077, 0x0009, 0x00ee, 0x0005, 0x00e6, 0x0006,
+	0x2071, 0x19d5, 0x707c, 0x9206, 0x1110, 0x707a, 0x707e, 0x000e,
 	0x00ee, 0x0005, 0x2069, 0x1800, 0x69e4, 0xd1e4, 0x1518, 0x0026,
 	0xd1ec, 0x0140, 0x6a50, 0x6870, 0x9202, 0x0288, 0x8117, 0x9294,
 	0x00c0, 0x0088, 0x9184, 0x0007, 0x01a0, 0x8109, 0x9184, 0x0007,
 	0x0110, 0x69e6, 0x0070, 0x8107, 0x9084, 0x0007, 0x910d, 0x8107,
 	0x9106, 0x9094, 0x00c0, 0x9184, 0xff3f, 0x9205, 0x68e6, 0x080c,
-	0x0f11, 0x002e, 0x0005, 0x00c6, 0x2061, 0x1a48, 0x00ce, 0x0005,
-	0x9184, 0x000f, 0x8003, 0x8003, 0x8003, 0x9080, 0x1a48, 0x2060,
+	0x0f23, 0x002e, 0x0005, 0x00c6, 0x2061, 0x1a4c, 0x00ce, 0x0005,
+	0x9184, 0x000f, 0x8003, 0x8003, 0x8003, 0x9080, 0x1a4c, 0x2060,
 	0x0005, 0xa884, 0x908a, 0x199a, 0x1638, 0x9005, 0x1150, 0x00c6,
-	0x2061, 0x1a48, 0x6014, 0x00ce, 0x9005, 0x1130, 0x2001, 0x001e,
+	0x2061, 0x1a4c, 0x6014, 0x00ce, 0x9005, 0x1130, 0x2001, 0x001e,
 	0x0018, 0x908e, 0xffff, 0x01b0, 0x8003, 0x800b, 0x810b, 0x9108,
-	0x611a, 0xa87c, 0x908c, 0x00c0, 0x918e, 0x00c0, 0x0904, 0x847b,
-	0xd0b4, 0x1168, 0xd0bc, 0x1904, 0x8454, 0x2009, 0x0006, 0x080c,
-	0x84a8, 0x0005, 0x900e, 0x0c60, 0x2001, 0x1999, 0x08b0, 0xd0fc,
-	0x0160, 0x908c, 0x0003, 0x0120, 0x918e, 0x0003, 0x1904, 0x84a2,
+	0x611a, 0xa87c, 0x908c, 0x00c0, 0x918e, 0x00c0, 0x0904, 0x83fb,
+	0xd0b4, 0x1168, 0xd0bc, 0x1904, 0x83d4, 0x2009, 0x0006, 0x080c,
+	0x8428, 0x0005, 0x900e, 0x0c60, 0x2001, 0x1999, 0x08b0, 0xd0fc,
+	0x0160, 0x908c, 0x0003, 0x0120, 0x918e, 0x0003, 0x1904, 0x8422,
 	0x908c, 0x2020, 0x918e, 0x2020, 0x01a8, 0x6024, 0xd0d4, 0x11e8,
 	0x2009, 0x187d, 0x2104, 0xd084, 0x1138, 0x87ff, 0x1120, 0x2009,
-	0x0043, 0x0804, 0xa15d, 0x0005, 0x87ff, 0x1de8, 0x2009, 0x0042,
-	0x0804, 0xa15d, 0x6110, 0x00b6, 0x2158, 0xb900, 0x00be, 0xd1ac,
+	0x0043, 0x0804, 0xa053, 0x0005, 0x87ff, 0x1de8, 0x2009, 0x0042,
+	0x0804, 0xa053, 0x6110, 0x00b6, 0x2158, 0xb900, 0x00be, 0xd1ac,
 	0x0d20, 0x6024, 0xc0cd, 0x6026, 0x0c00, 0xc0d4, 0x6026, 0xa890,
 	0x602e, 0xa88c, 0x6032, 0x08e0, 0xd0fc, 0x0160, 0x908c, 0x0003,
-	0x0120, 0x918e, 0x0003, 0x1904, 0x84a2, 0x908c, 0x2020, 0x918e,
-	0x2020, 0x0170, 0x0076, 0x00f6, 0x2c78, 0x080c, 0x16db, 0x00fe,
-	0x007e, 0x87ff, 0x1120, 0x2009, 0x0042, 0x080c, 0xa15d, 0x0005,
+	0x0120, 0x918e, 0x0003, 0x1904, 0x8422, 0x908c, 0x2020, 0x918e,
+	0x2020, 0x0170, 0x0076, 0x00f6, 0x2c78, 0x080c, 0x165d, 0x00fe,
+	0x007e, 0x87ff, 0x1120, 0x2009, 0x0042, 0x080c, 0xa053, 0x0005,
 	0x6110, 0x00b6, 0x2158, 0xb900, 0x00be, 0xd1ac, 0x0d58, 0x6124,
 	0xc1cd, 0x6126, 0x0c38, 0xd0fc, 0x0188, 0x908c, 0x2020, 0x918e,
 	0x2020, 0x01a8, 0x9084, 0x0003, 0x908e, 0x0002, 0x0148, 0x87ff,
-	0x1120, 0x2009, 0x0041, 0x080c, 0xa15d, 0x0005, 0x00b9, 0x0ce8,
-	0x87ff, 0x1dd8, 0x2009, 0x0043, 0x080c, 0xa15d, 0x0cb0, 0x6110,
+	0x1120, 0x2009, 0x0041, 0x080c, 0xa053, 0x0005, 0x00b9, 0x0ce8,
+	0x87ff, 0x1dd8, 0x2009, 0x0043, 0x080c, 0xa053, 0x0cb0, 0x6110,
 	0x00b6, 0x2158, 0xb900, 0x00be, 0xd1ac, 0x0d20, 0x6124, 0xc1cd,
 	0x6126, 0x0c00, 0x2009, 0x0004, 0x0019, 0x0005, 0x2009, 0x0001,
-	0x0096, 0x080c, 0xbe37, 0x0518, 0x6014, 0x2048, 0xa982, 0xa800,
+	0x0096, 0x080c, 0xbd3b, 0x0518, 0x6014, 0x2048, 0xa982, 0xa800,
 	0x6016, 0x9186, 0x0001, 0x1188, 0xa97c, 0x918c, 0x8100, 0x918e,
-	0x8100, 0x1158, 0x00c6, 0x2061, 0x1a48, 0x6200, 0xd28c, 0x1120,
-	0x6204, 0x8210, 0x0208, 0x6206, 0x00ce, 0x080c, 0x6923, 0x6014,
-	0x904d, 0x0076, 0x2039, 0x0000, 0x190c, 0x83f1, 0x007e, 0x009e,
-	0x0005, 0x0156, 0x00c6, 0x2061, 0x1a48, 0x6000, 0x81ff, 0x0110,
+	0x8100, 0x1158, 0x00c6, 0x2061, 0x1a4c, 0x6200, 0xd28c, 0x1120,
+	0x6204, 0x8210, 0x0208, 0x6206, 0x00ce, 0x080c, 0x6862, 0x6014,
+	0x904d, 0x0076, 0x2039, 0x0000, 0x190c, 0x8371, 0x007e, 0x009e,
+	0x0005, 0x0156, 0x00c6, 0x2061, 0x1a4c, 0x6000, 0x81ff, 0x0110,
 	0x9205, 0x0008, 0x9204, 0x6002, 0x00ce, 0x015e, 0x0005, 0x6800,
 	0xd08c, 0x1138, 0x6808, 0x9005, 0x0120, 0x8001, 0x680a, 0x9085,
 	0x0001, 0x0005, 0x0126, 0x2091, 0x8000, 0x0036, 0x0046, 0x20a9,
 	0x0010, 0x9006, 0x8004, 0x8086, 0x818e, 0x1208, 0x9200, 0x1f04,
-	0x84f3, 0x8086, 0x818e, 0x004e, 0x003e, 0x012e, 0x0005, 0x0126,
+	0x8473, 0x8086, 0x818e, 0x004e, 0x003e, 0x012e, 0x0005, 0x0126,
 	0x2091, 0x8000, 0x0076, 0x0156, 0x20a9, 0x0010, 0x9005, 0x01c8,
 	0x911a, 0x12b8, 0x8213, 0x818d, 0x0228, 0x911a, 0x1220, 0x1f04,
-	0x850a, 0x0028, 0x911a, 0x2308, 0x8210, 0x1f04, 0x850a, 0x0006,
+	0x848a, 0x0028, 0x911a, 0x2308, 0x8210, 0x1f04, 0x848a, 0x0006,
 	0x3200, 0x9084, 0xefff, 0x2080, 0x000e, 0x015e, 0x007e, 0x012e,
 	0x0005, 0x0006, 0x3200, 0x9085, 0x1000, 0x0ca8, 0x0126, 0x2091,
-	0x2800, 0x2079, 0x19bf, 0x012e, 0x00d6, 0x2069, 0x19bf, 0x6803,
+	0x2800, 0x2079, 0x19c2, 0x012e, 0x00d6, 0x2069, 0x19c2, 0x6803,
 	0x0005, 0x0156, 0x0146, 0x01d6, 0x20e9, 0x0000, 0x2069, 0x0200,
-	0x080c, 0x9eeb, 0x0401, 0x080c, 0x9ed6, 0x00e9, 0x080c, 0x9ed9,
-	0x00d1, 0x080c, 0x9edc, 0x00b9, 0x080c, 0x9edf, 0x00a1, 0x080c,
-	0x9ee2, 0x0089, 0x080c, 0x9ee5, 0x0071, 0x080c, 0x9ee8, 0x0059,
+	0x080c, 0x9ddd, 0x0401, 0x080c, 0x9dc8, 0x00e9, 0x080c, 0x9dcb,
+	0x00d1, 0x080c, 0x9dce, 0x00b9, 0x080c, 0x9dd1, 0x00a1, 0x080c,
+	0x9dd4, 0x0089, 0x080c, 0x9dd7, 0x0071, 0x080c, 0x9dda, 0x0059,
 	0x01de, 0x014e, 0x015e, 0x2069, 0x0004, 0x2d04, 0x9085, 0x8001,
 	0x206a, 0x00de, 0x0005, 0x20a9, 0x0020, 0x20a1, 0x0240, 0x2001,
 	0x0000, 0x4004, 0x0005, 0x00c6, 0x6027, 0x0001, 0x7804, 0x9084,
-	0x0007, 0x0002, 0x8574, 0x8598, 0x85d9, 0x857a, 0x8598, 0x8574,
-	0x8572, 0x8572, 0x080c, 0x0dfa, 0x080c, 0x835a, 0x080c, 0x8c10,
+	0x0007, 0x0002, 0x84f4, 0x8518, 0x8559, 0x84fa, 0x8518, 0x84f4,
+	0x84f2, 0x84f2, 0x080c, 0x0e02, 0x080c, 0x82da, 0x080c, 0x8b90,
 	0x00ce, 0x0005, 0x62c0, 0x82ff, 0x1110, 0x00ce, 0x0005, 0x2011,
-	0x5d94, 0x080c, 0x82da, 0x7828, 0x9092, 0x00c8, 0x1228, 0x8000,
-	0x782a, 0x080c, 0x5dd4, 0x0c88, 0x62c0, 0x080c, 0x9eef, 0x080c,
-	0x5d94, 0x7807, 0x0003, 0x7827, 0x0000, 0x782b, 0x0000, 0x0c28,
-	0x080c, 0x835a, 0x6220, 0xd2a4, 0x0170, 0xd2cc, 0x0160, 0x782b,
-	0x0000, 0x7824, 0x9065, 0x090c, 0x0dfa, 0x2009, 0x0013, 0x080c,
-	0xa15d, 0x00ce, 0x0005, 0x00c6, 0x7824, 0x9065, 0x090c, 0x0dfa,
+	0x5c99, 0x080c, 0x825a, 0x7828, 0x9092, 0x00c8, 0x1228, 0x8000,
+	0x782a, 0x080c, 0x5cd9, 0x0c88, 0x62c0, 0x080c, 0x9de1, 0x080c,
+	0x5c99, 0x7807, 0x0003, 0x7827, 0x0000, 0x782b, 0x0000, 0x0c28,
+	0x080c, 0x82da, 0x6220, 0xd2a4, 0x0170, 0xd2cc, 0x0160, 0x782b,
+	0x0000, 0x7824, 0x9065, 0x090c, 0x0e02, 0x2009, 0x0013, 0x080c,
+	0xa053, 0x00ce, 0x0005, 0x00c6, 0x7824, 0x9065, 0x090c, 0x0e02,
 	0x7828, 0x9092, 0xc350, 0x12c0, 0x8000, 0x782a, 0x00ce, 0x080c,
-	0x2afe, 0x0278, 0x00c6, 0x7924, 0x2160, 0x6010, 0x906d, 0x090c,
-	0x0dfa, 0x7807, 0x0000, 0x7827, 0x0000, 0x00ce, 0x080c, 0x8c10,
-	0x0c00, 0x080c, 0x9632, 0x08e8, 0x2011, 0x0130, 0x2214, 0x080c,
-	0x9eef, 0x080c, 0xdc28, 0x2009, 0x0014, 0x080c, 0xa15d, 0x00ce,
-	0x0880, 0x2001, 0x19db, 0x2003, 0x0000, 0x62c0, 0x82ff, 0x1160,
-	0x782b, 0x0000, 0x7824, 0x9065, 0x090c, 0x0dfa, 0x2009, 0x0013,
-	0x080c, 0xa1af, 0x00ce, 0x0005, 0x00b6, 0x00c6, 0x00d6, 0x7824,
-	0x9005, 0x090c, 0x0dfa, 0x7828, 0x9092, 0xc350, 0x1648, 0x8000,
-	0x782a, 0x00de, 0x00ce, 0x00be, 0x080c, 0x2afe, 0x02f0, 0x00b6,
-	0x00c6, 0x00d6, 0x781c, 0x905d, 0x090c, 0x0dfa, 0xb800, 0xc0dc,
-	0xb802, 0x7924, 0x2160, 0x080c, 0xa0e3, 0xb93c, 0x81ff, 0x090c,
-	0x0dfa, 0x8109, 0xb93e, 0x7807, 0x0000, 0x7827, 0x0000, 0x00de,
-	0x00ce, 0x00be, 0x080c, 0x8c10, 0x0868, 0x080c, 0x9632, 0x0850,
-	0x2011, 0x0130, 0x2214, 0x080c, 0x9eef, 0x080c, 0xdc28, 0x7824,
-	0x9065, 0x2009, 0x0014, 0x080c, 0xa15d, 0x00de, 0x00ce, 0x00be,
-	0x0804, 0x85ea, 0x00c6, 0x2001, 0x009b, 0x2004, 0xd0fc, 0x190c,
-	0x1dec, 0x6024, 0x6027, 0x0002, 0xd0f4, 0x1580, 0x62c8, 0x60c4,
+	0x29fe, 0x0278, 0x00c6, 0x7924, 0x2160, 0x6010, 0x906d, 0x090c,
+	0x0e02, 0x7807, 0x0000, 0x7827, 0x0000, 0x00ce, 0x080c, 0x8b90,
+	0x0c00, 0x080c, 0x95e1, 0x08e8, 0x2011, 0x0130, 0x2214, 0x080c,
+	0x9de1, 0x080c, 0xdb8f, 0x2009, 0x0014, 0x080c, 0xa053, 0x00ce,
+	0x0880, 0x2001, 0x19de, 0x2003, 0x0000, 0x62c0, 0x82ff, 0x1160,
+	0x782b, 0x0000, 0x7824, 0x9065, 0x090c, 0x0e02, 0x2009, 0x0013,
+	0x080c, 0xa0a5, 0x00ce, 0x0005, 0x00b6, 0x00c6, 0x00d6, 0x7824,
+	0x9005, 0x090c, 0x0e02, 0x7828, 0x9092, 0xc350, 0x1648, 0x8000,
+	0x782a, 0x00de, 0x00ce, 0x00be, 0x080c, 0x29fe, 0x02f0, 0x00b6,
+	0x00c6, 0x00d6, 0x781c, 0x905d, 0x090c, 0x0e02, 0xb800, 0xc0dc,
+	0xb802, 0x7924, 0x2160, 0x080c, 0x9fd5, 0xb93c, 0x81ff, 0x090c,
+	0x0e02, 0x8109, 0xb93e, 0x7807, 0x0000, 0x7827, 0x0000, 0x00de,
+	0x00ce, 0x00be, 0x080c, 0x8b90, 0x0868, 0x080c, 0x95e1, 0x0850,
+	0x2011, 0x0130, 0x2214, 0x080c, 0x9de1, 0x080c, 0xdb8f, 0x7824,
+	0x9065, 0x2009, 0x0014, 0x080c, 0xa053, 0x00de, 0x00ce, 0x00be,
+	0x0804, 0x856a, 0x00c6, 0x2001, 0x009b, 0x2004, 0xd0fc, 0x190c,
+	0x1d04, 0x6024, 0x6027, 0x0002, 0xd0f4, 0x1580, 0x62c8, 0x60c4,
 	0x9205, 0x1170, 0x783c, 0x9065, 0x0130, 0x2009, 0x0049, 0x080c,
-	0xa15d, 0x00ce, 0x0005, 0x2011, 0x19de, 0x2013, 0x0000, 0x0cc8,
+	0xa053, 0x00ce, 0x0005, 0x2011, 0x19e1, 0x2013, 0x0000, 0x0cc8,
 	0x793c, 0x81ff, 0x0dc0, 0x7944, 0x9192, 0x7530, 0x12f0, 0x8108,
 	0x7946, 0x793c, 0x9188, 0x0008, 0x210c, 0x918e, 0x0006, 0x1138,
 	0x6014, 0x9084, 0x1984, 0x9085, 0x0012, 0x6016, 0x0c10, 0x6014,
 	0x9084, 0x1984, 0x9085, 0x0016, 0x6016, 0x08d8, 0x793c, 0x2160,
-	0x2009, 0x004a, 0x080c, 0xa15d, 0x08a0, 0x7848, 0xc085, 0x784a,
+	0x2009, 0x004a, 0x080c, 0xa053, 0x08a0, 0x7848, 0xc085, 0x784a,
 	0x0880, 0x0006, 0x0016, 0x00c6, 0x0126, 0x2091, 0x8000, 0x600f,
-	0x0000, 0x2c08, 0x2061, 0x19bf, 0x6020, 0x8000, 0x6022, 0x6010,
+	0x0000, 0x2c08, 0x2061, 0x19c2, 0x6020, 0x8000, 0x6022, 0x6010,
 	0x9005, 0x0148, 0x9080, 0x0003, 0x2102, 0x6112, 0x012e, 0x00ce,
 	0x001e, 0x000e, 0x0005, 0x6116, 0x6112, 0x0cc0, 0x00d6, 0x2069,
-	0x19bf, 0xb800, 0xd0d4, 0x0168, 0x6820, 0x8000, 0x6822, 0x9086,
-	0x0001, 0x1110, 0x2b00, 0x681e, 0x00de, 0x0804, 0x8c10, 0x00de,
+	0x19c2, 0xb800, 0xd0d4, 0x0168, 0x6820, 0x8000, 0x6822, 0x9086,
+	0x0001, 0x1110, 0x2b00, 0x681e, 0x00de, 0x0804, 0x8b90, 0x00de,
 	0x0005, 0xc0d5, 0xb802, 0x6818, 0x9005, 0x0168, 0xb856, 0xb85b,
 	0x0000, 0x0086, 0x0006, 0x2b00, 0x681a, 0x008e, 0xa05a, 0x008e,
-	0x2069, 0x19bf, 0x0c08, 0xb856, 0xb85a, 0x2b00, 0x681a, 0x681e,
+	0x2069, 0x19c2, 0x0c08, 0xb856, 0xb85a, 0x2b00, 0x681a, 0x681e,
 	0x08d8, 0x0006, 0x0016, 0x00c6, 0x0126, 0x2091, 0x8000, 0x600f,
-	0x0000, 0x2c08, 0x2061, 0x19bf, 0x6020, 0x8000, 0x6022, 0x6008,
+	0x0000, 0x2c08, 0x2061, 0x19c2, 0x6020, 0x8000, 0x6022, 0x6008,
 	0x9005, 0x0148, 0x9080, 0x0003, 0x2102, 0x610a, 0x012e, 0x00ce,
 	0x001e, 0x000e, 0x0005, 0x610e, 0x610a, 0x0cc0, 0x00c6, 0x600f,
-	0x0000, 0x2c08, 0x2061, 0x19bf, 0x6034, 0x9005, 0x0130, 0x9080,
+	0x0000, 0x2c08, 0x2061, 0x19c2, 0x6034, 0x9005, 0x0130, 0x9080,
 	0x0003, 0x2102, 0x6136, 0x00ce, 0x0005, 0x613a, 0x6136, 0x00ce,
 	0x0005, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x00b6, 0x0096, 0x0076,
 	0x0066, 0x0056, 0x0036, 0x0026, 0x0016, 0x0006, 0x0126, 0x902e,
-	0x2071, 0x19bf, 0x7638, 0x2660, 0x2678, 0x2091, 0x8000, 0x8cff,
-	0x0904, 0x876d, 0x6010, 0x2058, 0xb8a0, 0x9206, 0x1904, 0x8768,
-	0x87ff, 0x0120, 0x6054, 0x9106, 0x1904, 0x8768, 0x703c, 0x9c06,
-	0x1178, 0x0036, 0x2019, 0x0001, 0x080c, 0x999d, 0x7033, 0x0000,
+	0x2071, 0x19c2, 0x7638, 0x2660, 0x2678, 0x2091, 0x8000, 0x8cff,
+	0x0904, 0x86ed, 0x6010, 0x2058, 0xb8a0, 0x9206, 0x1904, 0x86e8,
+	0x87ff, 0x0120, 0x6054, 0x9106, 0x1904, 0x86e8, 0x703c, 0x9c06,
+	0x1178, 0x0036, 0x2019, 0x0001, 0x080c, 0x989c, 0x7033, 0x0000,
 	0x9006, 0x703e, 0x7042, 0x7046, 0x704a, 0x003e, 0x2029, 0x0001,
 	0x7038, 0x9c36, 0x1110, 0x660c, 0x763a, 0x7034, 0x9c36, 0x1140,
 	0x2c00, 0x9f36, 0x0118, 0x2f00, 0x7036, 0x0010, 0x7037, 0x0000,
 	0x660c, 0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678,
-	0x600f, 0x0000, 0x080c, 0xbe37, 0x01f0, 0x6014, 0x2048, 0x6020,
-	0x9086, 0x0003, 0x15b8, 0x6004, 0x9086, 0x0040, 0x090c, 0x9b78,
+	0x600f, 0x0000, 0x080c, 0xbd3b, 0x01f0, 0x6014, 0x2048, 0x6020,
+	0x9086, 0x0003, 0x15b8, 0x6004, 0x9086, 0x0040, 0x090c, 0x9a6a,
 	0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x0016, 0x0036, 0x0076,
-	0x080c, 0xc12d, 0x080c, 0xdb2e, 0x080c, 0x6ae9, 0x007e, 0x003e,
-	0x001e, 0x080c, 0xc022, 0x080c, 0xa113, 0x00ce, 0x0804, 0x8707,
-	0x2c78, 0x600c, 0x2060, 0x0804, 0x8707, 0x85ff, 0x0120, 0x0036,
-	0x080c, 0x8ced, 0x003e, 0x012e, 0x000e, 0x001e, 0x002e, 0x003e,
+	0x080c, 0xc031, 0x080c, 0xda80, 0x080c, 0x6a23, 0x007e, 0x003e,
+	0x001e, 0x080c, 0xbf26, 0x080c, 0xa007, 0x00ce, 0x0804, 0x8687,
+	0x2c78, 0x600c, 0x2060, 0x0804, 0x8687, 0x85ff, 0x0120, 0x0036,
+	0x080c, 0x8c6d, 0x003e, 0x012e, 0x000e, 0x001e, 0x002e, 0x003e,
 	0x005e, 0x006e, 0x007e, 0x009e, 0x00be, 0x00ce, 0x00de, 0x00ee,
 	0x00fe, 0x0005, 0x6020, 0x9086, 0x0006, 0x1158, 0x0016, 0x0036,
-	0x0076, 0x080c, 0xdb2e, 0x080c, 0xd830, 0x007e, 0x003e, 0x001e,
-	0x0890, 0x6020, 0x9086, 0x000a, 0x0904, 0x8752, 0x0804, 0x874b,
+	0x0076, 0x080c, 0xda80, 0x080c, 0xd781, 0x007e, 0x003e, 0x001e,
+	0x0890, 0x6020, 0x9086, 0x000a, 0x0904, 0x86d2, 0x0804, 0x86cb,
 	0x0006, 0x0066, 0x0096, 0x00c6, 0x00d6, 0x00f6, 0x9036, 0x0126,
-	0x2091, 0x8000, 0x2079, 0x19bf, 0x7838, 0x9065, 0x0904, 0x87ed,
+	0x2091, 0x8000, 0x2079, 0x19c2, 0x7838, 0x9065, 0x0904, 0x876d,
 	0x600c, 0x0006, 0x600f, 0x0000, 0x783c, 0x9c06, 0x1168, 0x0036,
-	0x2019, 0x0001, 0x080c, 0x999d, 0x7833, 0x0000, 0x901e, 0x7b3e,
-	0x7b42, 0x7b46, 0x7b4a, 0x003e, 0x080c, 0xbe37, 0x0548, 0x6014,
+	0x2019, 0x0001, 0x080c, 0x989c, 0x7833, 0x0000, 0x901e, 0x7b3e,
+	0x7b42, 0x7b46, 0x7b4a, 0x003e, 0x080c, 0xbd3b, 0x0548, 0x6014,
 	0x2048, 0x6020, 0x9086, 0x0003, 0x1590, 0x3e08, 0x918e, 0x0002,
 	0x1188, 0x6010, 0x9005, 0x0170, 0x00b6, 0x2058, 0xb800, 0x00be,
-	0xd0bc, 0x0140, 0x6040, 0x9005, 0x11a8, 0x2001, 0x1960, 0x2004,
-	0x6042, 0x0080, 0x6004, 0x9086, 0x0040, 0x090c, 0x9b78, 0xa867,
-	0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0x6adc, 0x080c, 0xc022,
-	0x080c, 0xa113, 0x000e, 0x0804, 0x87a5, 0x7e3a, 0x7e36, 0x012e,
+	0xd0bc, 0x0140, 0x6040, 0x9005, 0x11a8, 0x2001, 0x1962, 0x2004,
+	0x6042, 0x0080, 0x6004, 0x9086, 0x0040, 0x090c, 0x9a6a, 0xa867,
+	0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0x6a16, 0x080c, 0xbf26,
+	0x080c, 0xa007, 0x000e, 0x0804, 0x8725, 0x7e3a, 0x7e36, 0x012e,
 	0x00fe, 0x00de, 0x00ce, 0x009e, 0x006e, 0x000e, 0x0005, 0x6020,
-	0x9086, 0x0006, 0x1118, 0x080c, 0xd830, 0x0c50, 0x6020, 0x9086,
+	0x9086, 0x0006, 0x1118, 0x080c, 0xd781, 0x0c50, 0x6020, 0x9086,
 	0x000a, 0x09f8, 0x08b8, 0x0016, 0x0026, 0x0086, 0x9046, 0x0099,
-	0x080c, 0x88ee, 0x008e, 0x002e, 0x001e, 0x0005, 0x00f6, 0x0126,
-	0x2079, 0x19bf, 0x2091, 0x8000, 0x080c, 0x8985, 0x080c, 0x8a15,
+	0x080c, 0x886e, 0x008e, 0x002e, 0x001e, 0x0005, 0x00f6, 0x0126,
+	0x2079, 0x19c2, 0x2091, 0x8000, 0x080c, 0x8905, 0x080c, 0x8995,
 	0x012e, 0x00fe, 0x0005, 0x00b6, 0x0096, 0x00f6, 0x00e6, 0x00d6,
 	0x00c6, 0x0066, 0x0016, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071,
-	0x19bf, 0x7614, 0x2660, 0x2678, 0x8cff, 0x0904, 0x88b3, 0x6010,
-	0x2058, 0xb8a0, 0x9206, 0x1904, 0x88ae, 0x88ff, 0x0120, 0x6054,
-	0x9106, 0x1904, 0x88ae, 0x7024, 0x9c06, 0x1568, 0x2069, 0x0100,
-	0x6820, 0xd0a4, 0x0110, 0xd0cc, 0x1508, 0x080c, 0x835a, 0x080c,
-	0x9656, 0x68c3, 0x0000, 0x080c, 0x9b78, 0x7027, 0x0000, 0x0036,
+	0x19c2, 0x7614, 0x2660, 0x2678, 0x8cff, 0x0904, 0x8833, 0x6010,
+	0x2058, 0xb8a0, 0x9206, 0x1904, 0x882e, 0x88ff, 0x0120, 0x6054,
+	0x9106, 0x1904, 0x882e, 0x7024, 0x9c06, 0x1568, 0x2069, 0x0100,
+	0x6820, 0xd0a4, 0x0110, 0xd0cc, 0x1508, 0x080c, 0x82da, 0x080c,
+	0x9605, 0x68c3, 0x0000, 0x080c, 0x9a6a, 0x7027, 0x0000, 0x0036,
 	0x2069, 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100,
-	0x080c, 0x2c88, 0x9006, 0x080c, 0x2c88, 0x2069, 0x0100, 0x6824,
+	0x080c, 0x2b88, 0x9006, 0x080c, 0x2b88, 0x2069, 0x0100, 0x6824,
 	0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x0028, 0x6003, 0x0009,
-	0x630a, 0x0804, 0x88ae, 0x7014, 0x9c36, 0x1110, 0x660c, 0x7616,
+	0x630a, 0x0804, 0x882e, 0x7014, 0x9c36, 0x1110, 0x660c, 0x7616,
 	0x7010, 0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x7012,
 	0x0010, 0x7013, 0x0000, 0x660c, 0x0066, 0x2c00, 0x9f06, 0x0110,
 	0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0x6014, 0x2048, 0x080c,
-	0xbe37, 0x01e8, 0x6020, 0x9086, 0x0003, 0x1580, 0x080c, 0xc03f,
-	0x1118, 0x080c, 0xaa81, 0x0098, 0xa867, 0x0103, 0xab7a, 0xa877,
-	0x0000, 0x0016, 0x0036, 0x0086, 0x080c, 0xc12d, 0x080c, 0xdb2e,
-	0x080c, 0x6ae9, 0x008e, 0x003e, 0x001e, 0x080c, 0xc022, 0x080c,
-	0xa113, 0x080c, 0x9a4e, 0x00ce, 0x0804, 0x882c, 0x2c78, 0x600c,
-	0x2060, 0x0804, 0x882c, 0x012e, 0x000e, 0x001e, 0x006e, 0x00ce,
+	0xbd3b, 0x01e8, 0x6020, 0x9086, 0x0003, 0x1580, 0x080c, 0xbf43,
+	0x1118, 0x080c, 0xa995, 0x0098, 0xa867, 0x0103, 0xab7a, 0xa877,
+	0x0000, 0x0016, 0x0036, 0x0086, 0x080c, 0xc031, 0x080c, 0xda80,
+	0x080c, 0x6a23, 0x008e, 0x003e, 0x001e, 0x080c, 0xbf26, 0x080c,
+	0xa007, 0x080c, 0x9940, 0x00ce, 0x0804, 0x87ac, 0x2c78, 0x600c,
+	0x2060, 0x0804, 0x87ac, 0x012e, 0x000e, 0x001e, 0x006e, 0x00ce,
 	0x00de, 0x00ee, 0x00fe, 0x009e, 0x00be, 0x0005, 0x6020, 0x9086,
-	0x0006, 0x1158, 0x0016, 0x0036, 0x0086, 0x080c, 0xdb2e, 0x080c,
-	0xd830, 0x008e, 0x003e, 0x001e, 0x08d0, 0x080c, 0xaa81, 0x6020,
+	0x0006, 0x1158, 0x0016, 0x0036, 0x0086, 0x080c, 0xda80, 0x080c,
+	0xd781, 0x008e, 0x003e, 0x001e, 0x08d0, 0x080c, 0xa995, 0x6020,
 	0x9086, 0x0002, 0x1160, 0x6004, 0x0006, 0x9086, 0x0085, 0x000e,
-	0x0904, 0x8894, 0x9086, 0x008b, 0x0904, 0x8894, 0x0840, 0x6020,
+	0x0904, 0x8814, 0x9086, 0x008b, 0x0904, 0x8814, 0x0840, 0x6020,
 	0x9086, 0x0005, 0x1920, 0x6004, 0x0006, 0x9086, 0x0085, 0x000e,
-	0x09c8, 0x9086, 0x008b, 0x09b0, 0x0804, 0x88a7, 0x00b6, 0x00a6,
+	0x09c8, 0x9086, 0x008b, 0x09b0, 0x0804, 0x8827, 0x00b6, 0x00a6,
 	0x0096, 0x00c6, 0x0006, 0x0126, 0x2091, 0x8000, 0x9280, 0x1000,
-	0x2004, 0x905d, 0x0904, 0x897e, 0x00f6, 0x00e6, 0x00d6, 0x0066,
-	0x2071, 0x19bf, 0xbe54, 0x7018, 0x9b06, 0x1108, 0x761a, 0x701c,
+	0x2004, 0x905d, 0x0904, 0x88fe, 0x00f6, 0x00e6, 0x00d6, 0x0066,
+	0x2071, 0x19c2, 0xbe54, 0x7018, 0x9b06, 0x1108, 0x761a, 0x701c,
 	0x9b06, 0x1130, 0x86ff, 0x1118, 0x7018, 0x701e, 0x0008, 0x761e,
 	0xb858, 0x904d, 0x0108, 0xae56, 0x96d5, 0x0000, 0x0110, 0x2900,
 	0xb05a, 0xb857, 0x0000, 0xb85b, 0x0000, 0xb800, 0xc0d4, 0xc0dc,
-	0xb802, 0x080c, 0x63d2, 0x0904, 0x897a, 0x7624, 0x86ff, 0x0904,
-	0x8969, 0x9680, 0x0005, 0x2004, 0x9906, 0x15d8, 0x00d6, 0x2069,
-	0x0100, 0x68c0, 0x9005, 0x0560, 0x080c, 0x835a, 0x080c, 0x9656,
-	0x68c3, 0x0000, 0x080c, 0x9b78, 0x7027, 0x0000, 0x0036, 0x2069,
+	0xb802, 0x080c, 0x62d7, 0x0904, 0x88fa, 0x7624, 0x86ff, 0x0904,
+	0x88e9, 0x9680, 0x0005, 0x2004, 0x9906, 0x15d8, 0x00d6, 0x2069,
+	0x0100, 0x68c0, 0x9005, 0x0560, 0x080c, 0x82da, 0x080c, 0x9605,
+	0x68c3, 0x0000, 0x080c, 0x9a6a, 0x7027, 0x0000, 0x0036, 0x2069,
 	0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c,
-	0x2c88, 0x9006, 0x080c, 0x2c88, 0x2069, 0x0100, 0x6824, 0xd084,
+	0x2b88, 0x9006, 0x080c, 0x2b88, 0x2069, 0x0100, 0x6824, 0xd084,
 	0x0110, 0x6827, 0x0001, 0x003e, 0x00de, 0x00c6, 0xb83c, 0x9005,
-	0x0110, 0x8001, 0xb83e, 0x2660, 0x080c, 0xa113, 0x00ce, 0x0048,
+	0x0110, 0x8001, 0xb83e, 0x2660, 0x080c, 0xa007, 0x00ce, 0x0048,
 	0x00de, 0x00c6, 0x2660, 0x6003, 0x0009, 0x630a, 0x00ce, 0x0804,
-	0x8921, 0x89ff, 0x0158, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000,
-	0x080c, 0xc12d, 0x080c, 0xdb2e, 0x080c, 0x6ae9, 0x080c, 0x9a4e,
-	0x0804, 0x8921, 0x006e, 0x00de, 0x00ee, 0x00fe, 0x012e, 0x000e,
+	0x88a1, 0x89ff, 0x0158, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000,
+	0x080c, 0xc031, 0x080c, 0xda80, 0x080c, 0x6a23, 0x080c, 0x9940,
+	0x0804, 0x88a1, 0x006e, 0x00de, 0x00ee, 0x00fe, 0x012e, 0x000e,
 	0x00ce, 0x009e, 0x00ae, 0x00be, 0x0005, 0x0096, 0x0006, 0x0066,
-	0x00c6, 0x00d6, 0x9036, 0x7814, 0x9065, 0x0904, 0x89e8, 0x600c,
+	0x00c6, 0x00d6, 0x9036, 0x7814, 0x9065, 0x0904, 0x8968, 0x600c,
 	0x0006, 0x600f, 0x0000, 0x7824, 0x9c06, 0x1580, 0x2069, 0x0100,
-	0x6820, 0xd0a4, 0x0110, 0xd0cc, 0x1508, 0x080c, 0x835a, 0x080c,
-	0x9656, 0x68c3, 0x0000, 0x080c, 0x9b78, 0x7827, 0x0000, 0x0036,
+	0x6820, 0xd0a4, 0x0110, 0xd0cc, 0x1508, 0x080c, 0x82da, 0x080c,
+	0x9605, 0x68c3, 0x0000, 0x080c, 0x9a6a, 0x7827, 0x0000, 0x0036,
 	0x2069, 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100,
-	0x080c, 0x2c88, 0x9006, 0x080c, 0x2c88, 0x2069, 0x0100, 0x6824,
-	0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x0040, 0x080c, 0x6779,
+	0x080c, 0x2b88, 0x9006, 0x080c, 0x2b88, 0x2069, 0x0100, 0x6824,
+	0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x0040, 0x080c, 0x6680,
 	0x1520, 0x6003, 0x0009, 0x630a, 0x2c30, 0x00f8, 0x6014, 0x2048,
-	0x080c, 0xbe35, 0x01b0, 0x6020, 0x9086, 0x0003, 0x1508, 0x080c,
-	0xc03f, 0x1118, 0x080c, 0xaa81, 0x0060, 0x080c, 0x6779, 0x1168,
-	0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0x6ae9, 0x080c,
-	0xc022, 0x080c, 0xa113, 0x080c, 0x9a4e, 0x000e, 0x0804, 0x898c,
+	0x080c, 0xbd39, 0x01b0, 0x6020, 0x9086, 0x0003, 0x1508, 0x080c,
+	0xbf43, 0x1118, 0x080c, 0xa995, 0x0060, 0x080c, 0x6680, 0x1168,
+	0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0x6a23, 0x080c,
+	0xbf26, 0x080c, 0xa007, 0x080c, 0x9940, 0x000e, 0x0804, 0x890c,
 	0x7e16, 0x7e12, 0x00de, 0x00ce, 0x006e, 0x000e, 0x009e, 0x0005,
-	0x6020, 0x9086, 0x0006, 0x1118, 0x080c, 0xd830, 0x0c50, 0x080c,
-	0xaa81, 0x6020, 0x9086, 0x0002, 0x1150, 0x6004, 0x0006, 0x9086,
+	0x6020, 0x9086, 0x0006, 0x1118, 0x080c, 0xd781, 0x0c50, 0x080c,
+	0xa995, 0x6020, 0x9086, 0x0002, 0x1150, 0x6004, 0x0006, 0x9086,
 	0x0085, 0x000e, 0x0990, 0x9086, 0x008b, 0x0978, 0x08d0, 0x6020,
 	0x9086, 0x0005, 0x19b0, 0x6004, 0x0006, 0x9086, 0x0085, 0x000e,
 	0x0d18, 0x9086, 0x008b, 0x0d00, 0x0860, 0x0006, 0x0066, 0x0096,
-	0x00b6, 0x00c6, 0x00d6, 0x7818, 0x905d, 0x0904, 0x8a95, 0xb854,
+	0x00b6, 0x00c6, 0x00d6, 0x7818, 0x905d, 0x0904, 0x8a15, 0xb854,
 	0x0006, 0x9006, 0xb856, 0xb85a, 0xb800, 0xc0d4, 0xc0dc, 0xb802,
-	0x080c, 0x63d2, 0x0904, 0x8a92, 0x7e24, 0x86ff, 0x0904, 0x8a85,
-	0x9680, 0x0005, 0x2004, 0x9906, 0x1904, 0x8a85, 0x00d6, 0x2069,
-	0x0100, 0x68c0, 0x9005, 0x0904, 0x8a7c, 0x080c, 0x835a, 0x080c,
-	0x9656, 0x68c3, 0x0000, 0x080c, 0x9b78, 0x7827, 0x0000, 0x0036,
+	0x080c, 0x62d7, 0x0904, 0x8a12, 0x7e24, 0x86ff, 0x0904, 0x8a05,
+	0x9680, 0x0005, 0x2004, 0x9906, 0x1904, 0x8a05, 0x00d6, 0x2069,
+	0x0100, 0x68c0, 0x9005, 0x0904, 0x89fc, 0x080c, 0x82da, 0x080c,
+	0x9605, 0x68c3, 0x0000, 0x080c, 0x9a6a, 0x7827, 0x0000, 0x0036,
 	0x2069, 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100,
-	0x080c, 0x2c88, 0x9006, 0x080c, 0x2c88, 0x2069, 0x0100, 0x6824,
+	0x080c, 0x2b88, 0x9006, 0x080c, 0x2b88, 0x2069, 0x0100, 0x6824,
 	0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x00de, 0x00c6, 0x3e08,
 	0x918e, 0x0002, 0x1168, 0xb800, 0xd0bc, 0x0150, 0x9680, 0x0010,
-	0x200c, 0x81ff, 0x1518, 0x2009, 0x1960, 0x210c, 0x2102, 0x00f0,
+	0x200c, 0x81ff, 0x1518, 0x2009, 0x1962, 0x210c, 0x2102, 0x00f0,
 	0xb83c, 0x9005, 0x0110, 0x8001, 0xb83e, 0x2660, 0x600f, 0x0000,
-	0x080c, 0xa113, 0x00ce, 0x0048, 0x00de, 0x00c6, 0x2660, 0x6003,
-	0x0009, 0x630a, 0x00ce, 0x0804, 0x8a28, 0x89ff, 0x0138, 0xa867,
-	0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0x6ae9, 0x080c, 0x9a4e,
-	0x0804, 0x8a28, 0x000e, 0x0804, 0x8a1c, 0x781e, 0x781a, 0x00de,
+	0x080c, 0xa007, 0x00ce, 0x0048, 0x00de, 0x00c6, 0x2660, 0x6003,
+	0x0009, 0x630a, 0x00ce, 0x0804, 0x89a8, 0x89ff, 0x0138, 0xa867,
+	0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0x6a23, 0x080c, 0x9940,
+	0x0804, 0x89a8, 0x000e, 0x0804, 0x899c, 0x781e, 0x781a, 0x00de,
 	0x00ce, 0x00be, 0x009e, 0x006e, 0x000e, 0x0005, 0x00e6, 0x00d6,
 	0x0096, 0x0066, 0xb800, 0xd0dc, 0x01a0, 0xb84c, 0x904d, 0x0188,
-	0xa878, 0x9606, 0x1170, 0x2071, 0x19bf, 0x7024, 0x9035, 0x0148,
+	0xa878, 0x9606, 0x1170, 0x2071, 0x19c2, 0x7024, 0x9035, 0x0148,
 	0x9080, 0x0005, 0x2004, 0x9906, 0x1120, 0xb800, 0xc0dc, 0xb802,
 	0x0029, 0x006e, 0x009e, 0x00de, 0x00ee, 0x0005, 0x00f6, 0x2079,
 	0x0100, 0x78c0, 0x9005, 0x1138, 0x00c6, 0x2660, 0x6003, 0x0009,
-	0x630a, 0x00ce, 0x04b8, 0x080c, 0x9656, 0x78c3, 0x0000, 0x080c,
-	0x9b78, 0x7027, 0x0000, 0x0036, 0x2079, 0x0140, 0x7b04, 0x9384,
-	0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2c88, 0x9006, 0x080c,
-	0x2c88, 0x2079, 0x0100, 0x7824, 0xd084, 0x0110, 0x7827, 0x0001,
-	0x080c, 0x9b78, 0x003e, 0x080c, 0x63d2, 0x00c6, 0xb83c, 0x9005,
-	0x0110, 0x8001, 0xb83e, 0x2660, 0x080c, 0xa0e3, 0x00ce, 0xa867,
-	0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0xc12d, 0x080c, 0x6ae9,
-	0x080c, 0x9a4e, 0x00fe, 0x0005, 0x00b6, 0x00e6, 0x00c6, 0x2011,
+	0x630a, 0x00ce, 0x04b8, 0x080c, 0x9605, 0x78c3, 0x0000, 0x080c,
+	0x9a6a, 0x7027, 0x0000, 0x0036, 0x2079, 0x0140, 0x7b04, 0x9384,
+	0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2b88, 0x9006, 0x080c,
+	0x2b88, 0x2079, 0x0100, 0x7824, 0xd084, 0x0110, 0x7827, 0x0001,
+	0x080c, 0x9a6a, 0x003e, 0x080c, 0x62d7, 0x00c6, 0xb83c, 0x9005,
+	0x0110, 0x8001, 0xb83e, 0x2660, 0x080c, 0x9fd5, 0x00ce, 0xa867,
+	0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0xc031, 0x080c, 0x6a23,
+	0x080c, 0x9940, 0x00fe, 0x0005, 0x00b6, 0x00e6, 0x00c6, 0x2011,
 	0x0101, 0x2204, 0xc0c4, 0x2012, 0x2001, 0x180c, 0x2014, 0xc2e4,
-	0x2202, 0x2071, 0x19bf, 0x7004, 0x9084, 0x0007, 0x0002, 0x8b21,
-	0x8b25, 0x8b43, 0x8b6c, 0x8baa, 0x8b21, 0x8b3c, 0x8b1f, 0x080c,
-	0x0dfa, 0x00ce, 0x00ee, 0x00be, 0x0005, 0x7024, 0x9065, 0x0148,
+	0x2202, 0x2071, 0x19c2, 0x7004, 0x9084, 0x0007, 0x0002, 0x8aa1,
+	0x8aa5, 0x8ac3, 0x8aec, 0x8b2a, 0x8aa1, 0x8abc, 0x8a9f, 0x080c,
+	0x0e02, 0x00ce, 0x00ee, 0x00be, 0x0005, 0x7024, 0x9065, 0x0148,
 	0x7020, 0x8001, 0x7022, 0x600c, 0x9015, 0x0158, 0x7216, 0x600f,
 	0x0000, 0x7007, 0x0000, 0x7027, 0x0000, 0x00ce, 0x00ee, 0x00be,
 	0x0005, 0x7216, 0x7212, 0x0ca8, 0x7007, 0x0000, 0x7027, 0x0000,
-	0x7020, 0x9005, 0x0070, 0x6010, 0x2058, 0x080c, 0x63d2, 0xb800,
+	0x7020, 0x9005, 0x0070, 0x6010, 0x2058, 0x080c, 0x62d7, 0xb800,
 	0xc0dc, 0xb802, 0x7007, 0x0000, 0x7027, 0x0000, 0x7020, 0x8001,
 	0x7022, 0x1148, 0x2001, 0x180c, 0x2014, 0xd2ec, 0x1180, 0x00ce,
 	0x00ee, 0x00be, 0x0005, 0xb854, 0x9015, 0x0120, 0x721e, 0x080c,
-	0x8c10, 0x0ca8, 0x7218, 0x721e, 0x080c, 0x8c10, 0x0c80, 0xc2ec,
-	0x2202, 0x080c, 0x8ced, 0x0c58, 0x7024, 0x9065, 0x05b8, 0x700c,
-	0x9c06, 0x1160, 0x080c, 0x9a4e, 0x600c, 0x9015, 0x0120, 0x720e,
+	0x8b90, 0x0ca8, 0x7218, 0x721e, 0x080c, 0x8b90, 0x0c80, 0xc2ec,
+	0x2202, 0x080c, 0x8c6d, 0x0c58, 0x7024, 0x9065, 0x05b8, 0x700c,
+	0x9c06, 0x1160, 0x080c, 0x9940, 0x600c, 0x9015, 0x0120, 0x720e,
 	0x600f, 0x0000, 0x0448, 0x720e, 0x720a, 0x0430, 0x7014, 0x9c06,
-	0x1160, 0x080c, 0x9a4e, 0x600c, 0x9015, 0x0120, 0x7216, 0x600f,
+	0x1160, 0x080c, 0x9940, 0x600c, 0x9015, 0x0120, 0x7216, 0x600f,
 	0x0000, 0x00d0, 0x7216, 0x7212, 0x00b8, 0x6020, 0x9086, 0x0003,
-	0x1198, 0x6010, 0x2058, 0x080c, 0x63d2, 0xb800, 0xc0dc, 0xb802,
-	0x080c, 0x9a4e, 0x701c, 0x9065, 0x0138, 0xb854, 0x9015, 0x0110,
+	0x1198, 0x6010, 0x2058, 0x080c, 0x62d7, 0xb800, 0xc0dc, 0xb802,
+	0x080c, 0x9940, 0x701c, 0x9065, 0x0138, 0xb854, 0x9015, 0x0110,
 	0x721e, 0x0010, 0x7218, 0x721e, 0x7027, 0x0000, 0x00ce, 0x00ee,
-	0x00be, 0x0005, 0x7024, 0x9065, 0x0140, 0x080c, 0x9a4e, 0x600c,
-	0x9015, 0x0158, 0x720e, 0x600f, 0x0000, 0x080c, 0x9b78, 0x7027,
+	0x00be, 0x0005, 0x7024, 0x9065, 0x0140, 0x080c, 0x9940, 0x600c,
+	0x9015, 0x0158, 0x720e, 0x600f, 0x0000, 0x080c, 0x9a6a, 0x7027,
 	0x0000, 0x00ce, 0x00ee, 0x00be, 0x0005, 0x720e, 0x720a, 0x0ca8,
-	0x00d6, 0x2069, 0x19bf, 0x6830, 0x9084, 0x0003, 0x0002, 0x8bcd,
-	0x8bcf, 0x8bf3, 0x8bcb, 0x080c, 0x0dfa, 0x00de, 0x0005, 0x00c6,
+	0x00d6, 0x2069, 0x19c2, 0x6830, 0x9084, 0x0003, 0x0002, 0x8b4d,
+	0x8b4f, 0x8b73, 0x8b4b, 0x080c, 0x0e02, 0x00de, 0x0005, 0x00c6,
 	0x6840, 0x9086, 0x0001, 0x01b8, 0x683c, 0x9065, 0x0130, 0x600c,
 	0x9015, 0x0170, 0x6a3a, 0x600f, 0x0000, 0x6833, 0x0000, 0x683f,
-	0x0000, 0x2011, 0x19de, 0x2013, 0x0000, 0x00ce, 0x00de, 0x0005,
+	0x0000, 0x2011, 0x19e1, 0x2013, 0x0000, 0x00ce, 0x00de, 0x0005,
 	0x683a, 0x6836, 0x0c90, 0x6843, 0x0000, 0x6838, 0x9065, 0x0d68,
 	0x6003, 0x0003, 0x0c50, 0x00c6, 0x9006, 0x6842, 0x6846, 0x684a,
 	0x683c, 0x9065, 0x0160, 0x600c, 0x9015, 0x0130, 0x6a3a, 0x600f,
 	0x0000, 0x683f, 0x0000, 0x0018, 0x683e, 0x683a, 0x6836, 0x00ce,
 	0x00de, 0x0005, 0x2001, 0x180c, 0x200c, 0xc1e5, 0x2102, 0x0005,
 	0x2001, 0x180c, 0x200c, 0xd1ec, 0x0120, 0xc1ec, 0x2102, 0x080c,
-	0x8ced, 0x2001, 0x19cb, 0x2004, 0x9086, 0x0001, 0x0d58, 0x00d6,
-	0x2069, 0x19bf, 0x6804, 0x9084, 0x0007, 0x0002, 0x8c30, 0x8cd5,
-	0x8cd5, 0x8cd5, 0x8cd5, 0x8cd7, 0x8cd5, 0x8c2e, 0x080c, 0x0dfa,
+	0x8c6d, 0x2001, 0x19ce, 0x2004, 0x9086, 0x0001, 0x0d58, 0x00d6,
+	0x2069, 0x19c2, 0x6804, 0x9084, 0x0007, 0x0002, 0x8bb0, 0x8c55,
+	0x8c55, 0x8c55, 0x8c55, 0x8c57, 0x8c55, 0x8bae, 0x080c, 0x0e02,
 	0x6820, 0x9005, 0x1110, 0x00de, 0x0005, 0x00c6, 0x680c, 0x9065,
-	0x0150, 0x6807, 0x0004, 0x6826, 0x682b, 0x0000, 0x080c, 0x8d44,
+	0x0150, 0x6807, 0x0004, 0x6826, 0x682b, 0x0000, 0x080c, 0x8cc4,
 	0x00ce, 0x00de, 0x0005, 0x6814, 0x9065, 0x0150, 0x6807, 0x0001,
-	0x6826, 0x682b, 0x0000, 0x080c, 0x8d44, 0x00ce, 0x00de, 0x0005,
-	0x00b6, 0x00e6, 0x6a1c, 0x92dd, 0x0000, 0x0904, 0x8cbf, 0xb84c,
+	0x6826, 0x682b, 0x0000, 0x080c, 0x8cc4, 0x00ce, 0x00de, 0x0005,
+	0x00b6, 0x00e6, 0x6a1c, 0x92dd, 0x0000, 0x0904, 0x8c3f, 0xb84c,
 	0x900d, 0x0118, 0xb888, 0x9005, 0x01a0, 0xb854, 0x905d, 0x0120,
-	0x920e, 0x0904, 0x8cbf, 0x0028, 0x6818, 0x920e, 0x0904, 0x8cbf,
+	0x920e, 0x0904, 0x8c3f, 0x0028, 0x6818, 0x920e, 0x0904, 0x8c3f,
 	0x2058, 0xb84c, 0x900d, 0x0d88, 0xb888, 0x9005, 0x1d70, 0x2b00,
-	0x681e, 0xbb3c, 0xb838, 0x9302, 0x1e40, 0x080c, 0xa0ba, 0x0904,
-	0x8cbf, 0x8318, 0xbb3e, 0x6116, 0x2b10, 0x6212, 0x0096, 0x2148,
+	0x681e, 0xbb3c, 0xb838, 0x9302, 0x1e40, 0x080c, 0x9fac, 0x0904,
+	0x8c3f, 0x8318, 0xbb3e, 0x6116, 0x2b10, 0x6212, 0x0096, 0x2148,
 	0xa880, 0x9084, 0x00ff, 0x605e, 0xa883, 0x0000, 0xa884, 0x009e,
 	0x908a, 0x199a, 0x0210, 0x2001, 0x1999, 0x8003, 0x801b, 0x831b,
 	0x9318, 0x631a, 0x6114, 0x0096, 0x2148, 0xa964, 0x009e, 0x918c,
 	0x00ff, 0x918e, 0x0048, 0x0538, 0x00f6, 0x2c78, 0x2061, 0x0100,
-	0xbab0, 0x629a, 0x2069, 0x0200, 0x2071, 0x0240, 0x080c, 0x9286,
-	0x2069, 0x19bf, 0xbb00, 0xc3dd, 0xbb02, 0x6807, 0x0002, 0x2f18,
+	0xbab0, 0x629a, 0x2069, 0x0200, 0x2071, 0x0240, 0x080c, 0x922a,
+	0x2069, 0x19c2, 0xbb00, 0xc3dd, 0xbb02, 0x6807, 0x0002, 0x2f18,
 	0x6b26, 0x682b, 0x0000, 0x7823, 0x0003, 0x7803, 0x0001, 0x7807,
 	0x0040, 0x00fe, 0x00ee, 0x00be, 0x00ce, 0x00de, 0x0005, 0x00ee,
 	0x00be, 0x00ce, 0x0cd0, 0x6807, 0x0006, 0x2c18, 0x6b26, 0x6820,
-	0x8001, 0x6822, 0x682b, 0x0000, 0x080c, 0x63d2, 0x080c, 0x9f0f,
+	0x8001, 0x6822, 0x682b, 0x0000, 0x080c, 0x62d7, 0x080c, 0x9e01,
 	0x00ee, 0x00be, 0x00ce, 0x00de, 0x0005, 0x00de, 0x0005, 0x00c6,
 	0x680c, 0x9065, 0x0138, 0x6807, 0x0004, 0x6826, 0x682b, 0x0000,
-	0x080c, 0x8d44, 0x00ce, 0x00de, 0x0005, 0x2001, 0x180c, 0x2014,
+	0x080c, 0x8cc4, 0x00ce, 0x00de, 0x0005, 0x2001, 0x180c, 0x2014,
 	0xc2ed, 0x2202, 0x00de, 0x00fe, 0x0005, 0x00f6, 0x00d6, 0x2069,
-	0x19bf, 0x6830, 0x9086, 0x0000, 0x1548, 0x2001, 0x180c, 0x2014,
-	0xd2e4, 0x0130, 0xc2e4, 0x2202, 0x080c, 0x8c1f, 0x2069, 0x19bf,
+	0x19c2, 0x6830, 0x9086, 0x0000, 0x1548, 0x2001, 0x180c, 0x2014,
+	0xd2e4, 0x0130, 0xc2e4, 0x2202, 0x080c, 0x8b9f, 0x2069, 0x19c2,
 	0x2001, 0x180c, 0x200c, 0xd1c4, 0x11e0, 0x6838, 0x907d, 0x01b0,
 	0x6a04, 0x9296, 0x0000, 0x1568, 0x6833, 0x0001, 0x683e, 0x6847,
 	0x0000, 0x684b, 0x0000, 0x0126, 0x00f6, 0x2091, 0x2400, 0x002e,
-	0x080c, 0x1b8a, 0x1158, 0x012e, 0x080c, 0x94b3, 0x00de, 0x00fe,
-	0x0005, 0xc1c4, 0x2102, 0x080c, 0x72d2, 0x08f8, 0x012e, 0x6843,
+	0x080c, 0x1b0e, 0x1158, 0x012e, 0x080c, 0x9462, 0x00de, 0x00fe,
+	0x0005, 0xc1c4, 0x2102, 0x080c, 0x7247, 0x08f8, 0x012e, 0x6843,
 	0x0000, 0x7803, 0x0002, 0x780c, 0x9015, 0x0140, 0x6a3a, 0x780f,
 	0x0000, 0x6833, 0x0000, 0x683f, 0x0000, 0x0c40, 0x683a, 0x6836,
-	0x0cc0, 0x6a04, 0x9296, 0x0006, 0x1904, 0x8ce5, 0x6a30, 0x9296,
-	0x0000, 0x0950, 0x0804, 0x8ce5, 0x6020, 0x9084, 0x000f, 0x000b,
-	0x0005, 0x8d58, 0x8d5d, 0x91b6, 0x924f, 0x8d5d, 0x91b6, 0x924f,
-	0x8d58, 0x8d5d, 0x8d58, 0x8d58, 0x8d58, 0x8d58, 0x8d58, 0x8d58,
-	0x080c, 0x8b04, 0x080c, 0x8c10, 0x0005, 0x00b6, 0x0156, 0x0136,
+	0x0cc0, 0x6a04, 0x9296, 0x0006, 0x1904, 0x8c65, 0x6a30, 0x9296,
+	0x0000, 0x0950, 0x0804, 0x8c65, 0x6020, 0x9084, 0x000f, 0x000b,
+	0x0005, 0x8cd8, 0x8cdd, 0x915a, 0x91f3, 0x8cdd, 0x915a, 0x91f3,
+	0x8cd8, 0x8cdd, 0x8cd8, 0x8cd8, 0x8cd8, 0x8cd8, 0x8cd8, 0x8cd8,
+	0x080c, 0x8a84, 0x080c, 0x8b90, 0x0005, 0x00b6, 0x0156, 0x0136,
 	0x0146, 0x01c6, 0x01d6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2069,
-	0x0200, 0x2071, 0x0240, 0x6004, 0x908a, 0x0053, 0x1a0c, 0x0dfa,
+	0x0200, 0x2071, 0x0240, 0x6004, 0x908a, 0x0053, 0x1a0c, 0x0e02,
 	0x6110, 0x2158, 0xb9b0, 0x2c78, 0x2061, 0x0100, 0x619a, 0x908a,
-	0x0040, 0x1a04, 0x8dc9, 0x005b, 0x00fe, 0x00ee, 0x00de, 0x00ce,
-	0x01de, 0x01ce, 0x014e, 0x013e, 0x015e, 0x00be, 0x0005, 0x8f40,
-	0x8f7b, 0x8fa4, 0x9047, 0x9068, 0x906e, 0x907b, 0x9083, 0x908f,
-	0x9095, 0x90a6, 0x9095, 0x90fd, 0x9083, 0x9109, 0x910f, 0x908f,
-	0x910f, 0x911b, 0x8dc7, 0x8dc7, 0x8dc7, 0x8dc7, 0x8dc7, 0x8dc7,
-	0x8dc7, 0x8dc7, 0x8dc7, 0x8dc7, 0x8dc7, 0x9854, 0x9877, 0x9888,
-	0x98a8, 0x98da, 0x907b, 0x8dc7, 0x907b, 0x9095, 0x8dc7, 0x8fa4,
-	0x9047, 0x8dc7, 0x9c6f, 0x9095, 0x8dc7, 0x9c8b, 0x9095, 0x8dc7,
-	0x908f, 0x8f3a, 0x8dea, 0x8dc7, 0x9ca7, 0x9d14, 0x9def, 0x8dc7,
-	0x9dfc, 0x9078, 0x9e27, 0x8dc7, 0x98e4, 0x9e54, 0x8dc7, 0x080c,
-	0x0dfa, 0x2100, 0x005b, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x01de,
-	0x01ce, 0x014e, 0x013e, 0x015e, 0x00be, 0x0005, 0x8de8, 0x8de8,
-	0x8de8, 0x8e11, 0x8ebd, 0x8ec8, 0x8de8, 0x8de8, 0x8de8, 0x8f0f,
-	0x8f1b, 0x8e2c, 0x8de8, 0x8e47, 0x8e7b, 0x9fd6, 0xa01b, 0x9095,
-	0x080c, 0x0dfa, 0x00d6, 0x0096, 0x080c, 0x912e, 0x7003, 0x2414,
-	0x7007, 0x0018, 0x700b, 0x0800, 0x7814, 0x2048, 0xa83c, 0x700e,
-	0xa850, 0x7022, 0xa854, 0x7026, 0x60c3, 0x0018, 0x080c, 0x962a,
-	0x009e, 0x00de, 0x0005, 0x7810, 0x00b6, 0x2058, 0xb8a0, 0x00be,
-	0x080c, 0xa062, 0x1118, 0x9084, 0xff80, 0x0110, 0x9085, 0x0001,
-	0x0005, 0x00d6, 0x0096, 0x080c, 0x912e, 0x7003, 0x0500, 0x7814,
-	0x2048, 0xa874, 0x700a, 0xa878, 0x700e, 0xa87c, 0x7012, 0xa880,
-	0x7016, 0xa884, 0x701a, 0xa888, 0x701e, 0x60c3, 0x0010, 0x080c,
-	0x962a, 0x009e, 0x00de, 0x0005, 0x00d6, 0x0096, 0x080c, 0x912e,
-	0x7003, 0x0500, 0x7814, 0x2048, 0xa8cc, 0x700a, 0xa8d0, 0x700e,
-	0xa8d4, 0x7012, 0xa8d8, 0x7016, 0xa8dc, 0x701a, 0xa8e0, 0x701e,
-	0x60c3, 0x0010, 0x080c, 0x962a, 0x009e, 0x00de, 0x0005, 0x00d6,
-	0x0096, 0x0126, 0x2091, 0x8000, 0x080c, 0x912e, 0x20e9, 0x0000,
-	0x2001, 0x197b, 0x2003, 0x0000, 0x7814, 0x2048, 0xa814, 0x8003,
-	0x60c2, 0xa830, 0x20a8, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x001b,
-	0x2098, 0x2001, 0x197b, 0x0016, 0x200c, 0x2001, 0x0001, 0x080c,
-	0x22ef, 0x080c, 0xcb69, 0x9006, 0x080c, 0x22ef, 0x001e, 0xa804,
-	0x9005, 0x0110, 0x2048, 0x0c28, 0x04d9, 0x080c, 0x962a, 0x012e,
-	0x009e, 0x00de, 0x0005, 0x00d6, 0x0096, 0x0126, 0x2091, 0x8000,
-	0x080c, 0x9179, 0x20e9, 0x0000, 0x2001, 0x197b, 0x2003, 0x0000,
-	0x7814, 0x2048, 0xa86f, 0x0200, 0xa873, 0x0000, 0xa814, 0x8003,
-	0x60c2, 0xa830, 0x20a8, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x001b,
-	0x2098, 0x2001, 0x197b, 0x0016, 0x200c, 0x080c, 0xcb69, 0x001e,
-	0xa804, 0x9005, 0x0110, 0x2048, 0x0c60, 0x0051, 0x7814, 0x2048,
-	0x080c, 0x0fe3, 0x080c, 0x962a, 0x012e, 0x009e, 0x00de, 0x0005,
-	0x60c0, 0x8004, 0x9084, 0x0003, 0x9005, 0x0130, 0x9082, 0x0004,
-	0x20a3, 0x0000, 0x8000, 0x1de0, 0x0005, 0x080c, 0x912e, 0x7003,
-	0x7800, 0x7808, 0x8007, 0x700a, 0x60c3, 0x0008, 0x0804, 0x962a,
-	0x00d6, 0x00e6, 0x080c, 0x9179, 0x7814, 0x9084, 0xff00, 0x2073,
-	0x0200, 0x8e70, 0x8e70, 0x9095, 0x0010, 0x2272, 0x8e70, 0x2073,
-	0x0034, 0x8e70, 0x2069, 0x1805, 0x20a9, 0x0004, 0x2d76, 0x8d68,
-	0x8e70, 0x1f04, 0x8ede, 0x2069, 0x1801, 0x20a9, 0x0004, 0x2d76,
-	0x8d68, 0x8e70, 0x1f04, 0x8ee7, 0x2069, 0x198b, 0x9086, 0xdf00,
-	0x0110, 0x2069, 0x19a5, 0x20a9, 0x001a, 0x9e86, 0x0260, 0x1148,
-	0x00c6, 0x2061, 0x0200, 0x6010, 0x8000, 0x6012, 0x00ce, 0x2071,
-	0x0240, 0x2d04, 0x8007, 0x2072, 0x8d68, 0x8e70, 0x1f04, 0x8ef5,
-	0x60c3, 0x004c, 0x080c, 0x962a, 0x00ee, 0x00de, 0x0005, 0x080c,
-	0x912e, 0x7003, 0x6300, 0x7007, 0x0028, 0x7808, 0x700e, 0x60c3,
-	0x0008, 0x0804, 0x962a, 0x00d6, 0x0026, 0x0016, 0x080c, 0x9179,
-	0x7003, 0x0200, 0x7814, 0x700e, 0x00e6, 0x9ef0, 0x0004, 0x2009,
-	0x0001, 0x2011, 0x000c, 0x2073, 0x0800, 0x8e70, 0x2073, 0x0000,
-	0x00ee, 0x7206, 0x710a, 0x62c2, 0x080c, 0x962a, 0x001e, 0x002e,
-	0x00de, 0x0005, 0x2001, 0x1817, 0x2004, 0x609a, 0x0804, 0x962a,
-	0x080c, 0x912e, 0x7003, 0x5200, 0x2069, 0x185b, 0x6804, 0xd084,
-	0x0130, 0x6828, 0x0016, 0x080c, 0x27a1, 0x710e, 0x001e, 0x20a9,
+	0x0040, 0x1a04, 0x8d49, 0x005b, 0x00fe, 0x00ee, 0x00de, 0x00ce,
+	0x01de, 0x01ce, 0x014e, 0x013e, 0x015e, 0x00be, 0x0005, 0x8ee4,
+	0x8f1f, 0x8f48, 0x8feb, 0x900c, 0x9012, 0x901f, 0x9027, 0x9033,
+	0x9039, 0x904a, 0x9039, 0x90a1, 0x9027, 0x90ad, 0x90b3, 0x9033,
+	0x90b3, 0x90bf, 0x8d47, 0x8d47, 0x8d47, 0x8d47, 0x8d47, 0x8d47,
+	0x8d47, 0x8d47, 0x8d47, 0x8d47, 0x8d47, 0x9753, 0x9776, 0x9787,
+	0x97a7, 0x97d9, 0x901f, 0x8d47, 0x901f, 0x9039, 0x8d47, 0x8f48,
+	0x8feb, 0x8d47, 0x9b61, 0x9039, 0x8d47, 0x9b7d, 0x9039, 0x8d47,
+	0x9033, 0x8ede, 0x8d6a, 0x8d47, 0x9b99, 0x9c06, 0x9ce1, 0x8d47,
+	0x9cee, 0x901c, 0x9d19, 0x8d47, 0x97e3, 0x9d46, 0x8d47, 0x080c,
+	0x0e02, 0x2100, 0x005b, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x01de,
+	0x01ce, 0x014e, 0x013e, 0x015e, 0x00be, 0x0005, 0x8d68, 0x8d68,
+	0x8d68, 0x8da2, 0x8e4e, 0x8e59, 0x8d68, 0x8d68, 0x8d68, 0x8eb3,
+	0x8ebf, 0x8dbd, 0x8d68, 0x8dd8, 0x8e0c, 0x9ec8, 0x9f0d, 0x9039,
+	0x080c, 0x0e02, 0x00d6, 0x0096, 0x080c, 0x90d2, 0x0026, 0x0036,
+	0x7814, 0x2048, 0xa958, 0xd1cc, 0x1138, 0x2009, 0x2414, 0x2011,
+	0x0018, 0x2019, 0x0018, 0x0030, 0x2009, 0x2410, 0x2011, 0x0014,
+	0x2019, 0x0014, 0x7102, 0x7206, 0x700b, 0x0800, 0xa83c, 0x700e,
+	0xa850, 0x7022, 0xa854, 0x7026, 0x63c2, 0x080c, 0x95d9, 0x003e,
+	0x002e, 0x009e, 0x00de, 0x0005, 0x7810, 0x00b6, 0x2058, 0xb8a0,
+	0x00be, 0x080c, 0x9f54, 0x1118, 0x9084, 0xff80, 0x0110, 0x9085,
+	0x0001, 0x0005, 0x00d6, 0x0096, 0x080c, 0x90d2, 0x7003, 0x0500,
+	0x7814, 0x2048, 0xa874, 0x700a, 0xa878, 0x700e, 0xa87c, 0x7012,
+	0xa880, 0x7016, 0xa884, 0x701a, 0xa888, 0x701e, 0x60c3, 0x0010,
+	0x080c, 0x95d9, 0x009e, 0x00de, 0x0005, 0x00d6, 0x0096, 0x080c,
+	0x90d2, 0x7003, 0x0500, 0x7814, 0x2048, 0xa8cc, 0x700a, 0xa8d0,
+	0x700e, 0xa8d4, 0x7012, 0xa8d8, 0x7016, 0xa8dc, 0x701a, 0xa8e0,
+	0x701e, 0x60c3, 0x0010, 0x080c, 0x95d9, 0x009e, 0x00de, 0x0005,
+	0x00d6, 0x0096, 0x0126, 0x2091, 0x8000, 0x080c, 0x90d2, 0x20e9,
+	0x0000, 0x2001, 0x197d, 0x2003, 0x0000, 0x7814, 0x2048, 0xa814,
+	0x8003, 0x60c2, 0xa830, 0x20a8, 0xa860, 0x20e0, 0xa85c, 0x9080,
+	0x001b, 0x2098, 0x2001, 0x197d, 0x0016, 0x200c, 0x2001, 0x0001,
+	0x080c, 0x21e9, 0x080c, 0xcaae, 0x9006, 0x080c, 0x21e9, 0x001e,
+	0xa804, 0x9005, 0x0110, 0x2048, 0x0c28, 0x04d9, 0x080c, 0x95d9,
+	0x012e, 0x009e, 0x00de, 0x0005, 0x00d6, 0x0096, 0x0126, 0x2091,
+	0x8000, 0x080c, 0x911d, 0x20e9, 0x0000, 0x2001, 0x197d, 0x2003,
+	0x0000, 0x7814, 0x2048, 0xa86f, 0x0200, 0xa873, 0x0000, 0xa814,
+	0x8003, 0x60c2, 0xa830, 0x20a8, 0xa860, 0x20e0, 0xa85c, 0x9080,
+	0x001b, 0x2098, 0x2001, 0x197d, 0x0016, 0x200c, 0x080c, 0xcaae,
+	0x001e, 0xa804, 0x9005, 0x0110, 0x2048, 0x0c60, 0x0051, 0x7814,
+	0x2048, 0x080c, 0x0ff5, 0x080c, 0x95d9, 0x012e, 0x009e, 0x00de,
+	0x0005, 0x60c0, 0x8004, 0x9084, 0x0003, 0x9005, 0x0130, 0x9082,
+	0x0004, 0x20a3, 0x0000, 0x8000, 0x1de0, 0x0005, 0x080c, 0x90d2,
+	0x7003, 0x7800, 0x7808, 0x8007, 0x700a, 0x60c3, 0x0008, 0x0804,
+	0x95d9, 0x00d6, 0x00e6, 0x080c, 0x911d, 0x7814, 0x9084, 0xff00,
+	0x2073, 0x0200, 0x8e70, 0x8e70, 0x9096, 0xdf00, 0x0138, 0x9096,
+	0xe000, 0x0120, 0x2073, 0x0010, 0x8e70, 0x0030, 0x9095, 0x0010,
+	0x2272, 0x8e70, 0x2073, 0x0034, 0x8e70, 0x2069, 0x1805, 0x20a9,
+	0x0004, 0x2d76, 0x8d68, 0x8e70, 0x1f04, 0x8e79, 0x2069, 0x1801,
+	0x20a9, 0x0004, 0x2d76, 0x8d68, 0x8e70, 0x1f04, 0x8e82, 0x9096,
+	0xdf00, 0x0130, 0x9096, 0xe000, 0x0118, 0x60c3, 0x0018, 0x00f0,
+	0x2069, 0x198e, 0x9086, 0xdf00, 0x0110, 0x2069, 0x19a8, 0x20a9,
+	0x001a, 0x9e86, 0x0260, 0x1148, 0x00c6, 0x2061, 0x0200, 0x6010,
+	0x8000, 0x6012, 0x00ce, 0x2071, 0x0240, 0x2d04, 0x8007, 0x2072,
+	0x8d68, 0x8e70, 0x1f04, 0x8e99, 0x60c3, 0x004c, 0x080c, 0x95d9,
+	0x00ee, 0x00de, 0x0005, 0x080c, 0x90d2, 0x7003, 0x6300, 0x7007,
+	0x0028, 0x7808, 0x700e, 0x60c3, 0x0008, 0x0804, 0x95d9, 0x00d6,
+	0x0026, 0x0016, 0x080c, 0x911d, 0x7003, 0x0200, 0x7814, 0x700e,
+	0x00e6, 0x9ef0, 0x0004, 0x2009, 0x0001, 0x2011, 0x000c, 0x2073,
+	0x0800, 0x8e70, 0x2073, 0x0000, 0x00ee, 0x7206, 0x710a, 0x62c2,
+	0x080c, 0x95d9, 0x001e, 0x002e, 0x00de, 0x0005, 0x2001, 0x1817,
+	0x2004, 0x609a, 0x0804, 0x95d9, 0x080c, 0x90d2, 0x7003, 0x5200,
+	0x2069, 0x185b, 0x6804, 0xd084, 0x0130, 0x6828, 0x0016, 0x080c,
+	0x26a1, 0x710e, 0x001e, 0x20a9, 0x0004, 0x20e1, 0x0001, 0x2099,
+	0x1805, 0x20e9, 0x0000, 0x20a1, 0x0250, 0x4003, 0x20a9, 0x0004,
+	0x2099, 0x1801, 0x20a1, 0x0254, 0x4003, 0x080c, 0x9f54, 0x1120,
+	0xb8a0, 0x9082, 0x007f, 0x0248, 0x2001, 0x181e, 0x2004, 0x7032,
+	0x2001, 0x181f, 0x2004, 0x7036, 0x0030, 0x2001, 0x1817, 0x2004,
+	0x9084, 0x00ff, 0x7036, 0x60c3, 0x001c, 0x0804, 0x95d9, 0x080c,
+	0x90d2, 0x7003, 0x0500, 0x080c, 0x9f54, 0x1120, 0xb8a0, 0x9082,
+	0x007f, 0x0248, 0x2001, 0x181e, 0x2004, 0x700a, 0x2001, 0x181f,
+	0x2004, 0x700e, 0x0030, 0x2001, 0x1817, 0x2004, 0x9084, 0x00ff,
+	0x700e, 0x20a9, 0x0004, 0x20e1, 0x0001, 0x2099, 0x1805, 0x20e9,
+	0x0000, 0x20a1, 0x0250, 0x4003, 0x60c3, 0x0010, 0x0804, 0x95d9,
+	0x080c, 0x90d2, 0x9006, 0x080c, 0x6694, 0xb8a0, 0x9086, 0x007e,
+	0x1130, 0x7003, 0x0400, 0x620c, 0xc2b4, 0x620e, 0x0058, 0x7814,
+	0x0096, 0x904d, 0x0120, 0x9006, 0xa89a, 0xa8a6, 0xa8aa, 0x009e,
+	0x7003, 0x0300, 0xb8a0, 0x9086, 0x007e, 0x1904, 0x8fb3, 0x00d6,
+	0x2069, 0x1946, 0x2001, 0x1836, 0x2004, 0xd0a4, 0x0178, 0x6800,
+	0x700a, 0x6808, 0x9084, 0x2000, 0x7012, 0x680c, 0x7016, 0x701f,
+	0x2710, 0x6818, 0x7022, 0x681c, 0x7026, 0x0080, 0x6800, 0x700a,
+	0x6804, 0x700e, 0x6808, 0x080c, 0x717f, 0x1118, 0x9084, 0x37ff,
+	0x0010, 0x9084, 0x3fff, 0x7012, 0x680c, 0x7016, 0x00de, 0x20a9,
 	0x0004, 0x20e1, 0x0001, 0x2099, 0x1805, 0x20e9, 0x0000, 0x20a1,
-	0x0250, 0x4003, 0x20a9, 0x0004, 0x2099, 0x1801, 0x20a1, 0x0254,
-	0x4003, 0x080c, 0xa062, 0x1120, 0xb8a0, 0x9082, 0x007f, 0x0248,
-	0x2001, 0x181e, 0x2004, 0x7032, 0x2001, 0x181f, 0x2004, 0x7036,
-	0x0030, 0x2001, 0x1817, 0x2004, 0x9084, 0x00ff, 0x7036, 0x60c3,
-	0x001c, 0x0804, 0x962a, 0x080c, 0x912e, 0x7003, 0x0500, 0x080c,
-	0xa062, 0x1120, 0xb8a0, 0x9082, 0x007f, 0x0248, 0x2001, 0x181e,
-	0x2004, 0x700a, 0x2001, 0x181f, 0x2004, 0x700e, 0x0030, 0x2001,
-	0x1817, 0x2004, 0x9084, 0x00ff, 0x700e, 0x20a9, 0x0004, 0x20e1,
-	0x0001, 0x2099, 0x1805, 0x20e9, 0x0000, 0x20a1, 0x0250, 0x4003,
-	0x60c3, 0x0010, 0x0804, 0x962a, 0x080c, 0x912e, 0x9006, 0x080c,
-	0x678d, 0xb8a0, 0x9086, 0x007e, 0x1130, 0x7003, 0x0400, 0x620c,
-	0xc2b4, 0x620e, 0x0058, 0x7814, 0x0096, 0x904d, 0x0120, 0x9006,
-	0xa89a, 0xa8a6, 0xa8aa, 0x009e, 0x7003, 0x0300, 0xb8a0, 0x9086,
-	0x007e, 0x1904, 0x900f, 0x00d6, 0x2069, 0x1944, 0x2001, 0x1836,
-	0x2004, 0xd0a4, 0x0178, 0x6800, 0x700a, 0x6808, 0x9084, 0x2000,
-	0x7012, 0x680c, 0x7016, 0x701f, 0x2710, 0x6818, 0x7022, 0x681c,
-	0x7026, 0x0080, 0x6800, 0x700a, 0x6804, 0x700e, 0x6808, 0x080c,
-	0x7207, 0x1118, 0x9084, 0x37ff, 0x0010, 0x9084, 0x3fff, 0x7012,
-	0x680c, 0x7016, 0x00de, 0x20a9, 0x0004, 0x20e1, 0x0001, 0x2099,
-	0x1805, 0x20e9, 0x0000, 0x20a1, 0x0256, 0x4003, 0x20a9, 0x0004,
-	0x2099, 0x1801, 0x20a1, 0x025a, 0x4003, 0x00d6, 0x080c, 0x9ed6,
-	0x2069, 0x194c, 0x2071, 0x024e, 0x6800, 0xc0dd, 0x7002, 0x080c,
-	0x55df, 0xd0e4, 0x0110, 0x680c, 0x700e, 0x00de, 0x04a0, 0x2001,
-	0x1836, 0x2004, 0xd0a4, 0x0168, 0x0016, 0x2009, 0x0002, 0x60e0,
-	0x9106, 0x0130, 0x2100, 0x60e3, 0x0000, 0x080c, 0x27e2, 0x61e2,
-	0x001e, 0x20e1, 0x0001, 0x2099, 0x1944, 0x20e9, 0x0000, 0x20a1,
-	0x024e, 0x20a9, 0x0008, 0x4003, 0x20a9, 0x0004, 0x2099, 0x1805,
-	0x20a1, 0x0256, 0x4003, 0x20a9, 0x0004, 0x2099, 0x1801, 0x20a1,
-	0x025a, 0x4003, 0x080c, 0x9ed6, 0x20a1, 0x024e, 0x20a9, 0x0008,
-	0x2099, 0x194c, 0x4003, 0x60c3, 0x0074, 0x0804, 0x962a, 0x080c,
-	0x912e, 0x7003, 0x2010, 0x7007, 0x0014, 0x700b, 0x0800, 0x700f,
-	0x2000, 0x9006, 0x00f6, 0x2079, 0x185b, 0x7904, 0x00fe, 0xd1ac,
-	0x1110, 0x9085, 0x0020, 0x0010, 0x9085, 0x0010, 0x9085, 0x0002,
-	0x00d6, 0x0804, 0x90de, 0x7026, 0x60c3, 0x0014, 0x0804, 0x962a,
-	0x080c, 0x912e, 0x7003, 0x5000, 0x0804, 0x8fbe, 0x080c, 0x912e,
-	0x7003, 0x2110, 0x7007, 0x0014, 0x60c3, 0x0014, 0x0804, 0x962a,
-	0x080c, 0x9170, 0x0010, 0x080c, 0x9179, 0x7003, 0x0200, 0x60c3,
-	0x0004, 0x0804, 0x962a, 0x080c, 0x9179, 0x7003, 0x0100, 0x700b,
-	0x0003, 0x700f, 0x2a00, 0x60c3, 0x0008, 0x0804, 0x962a, 0x080c,
-	0x9179, 0x7003, 0x0200, 0x0804, 0x8fbe, 0x080c, 0x9179, 0x7003,
-	0x0100, 0x782c, 0x9005, 0x0110, 0x700a, 0x0010, 0x700b, 0x0003,
-	0x7814, 0x700e, 0x60c3, 0x0008, 0x0804, 0x962a, 0x00d6, 0x080c,
-	0x9179, 0x7003, 0x0210, 0x7007, 0x0014, 0x700b, 0x0800, 0xb894,
-	0x9086, 0x0014, 0x1198, 0xb99c, 0x9184, 0x0030, 0x0190, 0xb998,
-	0x9184, 0xc000, 0x1140, 0xd1ec, 0x0118, 0x700f, 0x2100, 0x0058,
-	0x700f, 0x0100, 0x0040, 0x700f, 0x0400, 0x0028, 0x700f, 0x0700,
-	0x0010, 0x700f, 0x0800, 0x00f6, 0x2079, 0x185b, 0x7904, 0x00fe,
-	0xd1ac, 0x1110, 0x9085, 0x0020, 0x0010, 0x9085, 0x0010, 0x2009,
-	0x187d, 0x210c, 0xd184, 0x1110, 0x9085, 0x0002, 0x0026, 0x2009,
-	0x187b, 0x210c, 0xd1e4, 0x0150, 0xc0c5, 0xbabc, 0xd28c, 0x1108,
-	0xc0cd, 0x9094, 0x0030, 0x9296, 0x0010, 0x0140, 0xd1ec, 0x0130,
-	0x9094, 0x0030, 0x9296, 0x0010, 0x0108, 0xc0bd, 0x002e, 0x7026,
-	0x60c3, 0x0014, 0x00de, 0x0804, 0x962a, 0x080c, 0x9179, 0x7003,
-	0x0210, 0x7007, 0x0014, 0x700f, 0x0100, 0x60c3, 0x0014, 0x0804,
-	0x962a, 0x080c, 0x9179, 0x7003, 0x0200, 0x0804, 0x8f44, 0x080c,
-	0x9179, 0x7003, 0x0100, 0x700b, 0x0003, 0x700f, 0x2a00, 0x60c3,
-	0x0008, 0x0804, 0x962a, 0x080c, 0x9179, 0x7003, 0x0100, 0x700b,
-	0x000b, 0x60c3, 0x0008, 0x0804, 0x962a, 0x0026, 0x00d6, 0x0036,
-	0x0046, 0x2019, 0x3200, 0x2021, 0x0800, 0x0040, 0x0026, 0x00d6,
-	0x0036, 0x0046, 0x2019, 0x2200, 0x2021, 0x0100, 0x080c, 0x9eeb,
-	0xb810, 0x9305, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, 0x6878,
-	0x700a, 0x687c, 0x700e, 0x9485, 0x0029, 0x7012, 0x004e, 0x003e,
-	0x00de, 0x080c, 0x9618, 0x721a, 0x9f95, 0x0000, 0x7222, 0x7027,
-	0xffff, 0x2071, 0x024c, 0x002e, 0x0005, 0x0026, 0x080c, 0x9eeb,
-	0x7003, 0x02ff, 0x7007, 0xfffc, 0x00d6, 0x2069, 0x1800, 0x6878,
-	0x700a, 0x687c, 0x700e, 0x00de, 0x7013, 0x2029, 0x0c10, 0x7003,
-	0x0100, 0x7007, 0x0000, 0x700b, 0xfc02, 0x700f, 0x0000, 0x0005,
-	0x0026, 0x00d6, 0x0036, 0x0046, 0x2019, 0x3300, 0x2021, 0x0800,
-	0x0040, 0x0026, 0x00d6, 0x0036, 0x0046, 0x2019, 0x2300, 0x2021,
-	0x0100, 0x080c, 0x9eeb, 0xb810, 0x9305, 0x7002, 0xb814, 0x7006,
-	0x2069, 0x1800, 0xb810, 0x9005, 0x1140, 0xb814, 0x9005, 0x1128,
-	0x700b, 0x00ff, 0x700f, 0xfffe, 0x0020, 0x6878, 0x700a, 0x687c,
-	0x700e, 0x0000, 0x9485, 0x0098, 0x7012, 0x004e, 0x003e, 0x00de,
-	0x080c, 0x9618, 0x721a, 0x7a08, 0x7222, 0x2f10, 0x7226, 0x2071,
-	0x024c, 0x002e, 0x0005, 0x080c, 0x9618, 0x721a, 0x7a08, 0x7222,
-	0x7814, 0x7026, 0x2071, 0x024c, 0x002e, 0x0005, 0x00b6, 0x00c6,
-	0x00d6, 0x00e6, 0x00f6, 0x2069, 0x0200, 0x2071, 0x0240, 0x6004,
-	0x908a, 0x0085, 0x0a0c, 0x0dfa, 0x908a, 0x0092, 0x1a0c, 0x0dfa,
-	0x6110, 0x2158, 0xb9b0, 0x2c78, 0x2061, 0x0100, 0x619a, 0x9082,
-	0x0085, 0x0033, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be, 0x0005,
-	0x91e7, 0x91f6, 0x9201, 0x91e5, 0x91e5, 0x91e5, 0x91e7, 0x91e5,
-	0x91e5, 0x91e5, 0x91e5, 0x91e5, 0x91e5, 0x080c, 0x0dfa, 0x0411,
-	0x60c3, 0x0000, 0x0026, 0x080c, 0x2afe, 0x0228, 0x2011, 0x0101,
-	0x2204, 0xc0c5, 0x2012, 0x002e, 0x0804, 0x962a, 0x0431, 0x7808,
-	0x700a, 0x7814, 0x700e, 0x7017, 0xffff, 0x60c3, 0x000c, 0x0804,
-	0x962a, 0x04a1, 0x7003, 0x0003, 0x7007, 0x0300, 0x60c3, 0x0004,
-	0x0804, 0x962a, 0x0026, 0x080c, 0x9eeb, 0xb810, 0x9085, 0x8100,
+	0x0256, 0x4003, 0x20a9, 0x0004, 0x2099, 0x1801, 0x20a1, 0x025a,
+	0x4003, 0x00d6, 0x080c, 0x9dc8, 0x2069, 0x194e, 0x2071, 0x024e,
+	0x6800, 0xc0dd, 0x7002, 0x080c, 0x54e0, 0xd0e4, 0x0110, 0x680c,
+	0x700e, 0x00de, 0x04a0, 0x2001, 0x1836, 0x2004, 0xd0a4, 0x0168,
+	0x0016, 0x2009, 0x0002, 0x60e0, 0x9106, 0x0130, 0x2100, 0x60e3,
+	0x0000, 0x080c, 0x26e2, 0x61e2, 0x001e, 0x20e1, 0x0001, 0x2099,
+	0x1946, 0x20e9, 0x0000, 0x20a1, 0x024e, 0x20a9, 0x0008, 0x4003,
+	0x20a9, 0x0004, 0x2099, 0x1805, 0x20a1, 0x0256, 0x4003, 0x20a9,
+	0x0004, 0x2099, 0x1801, 0x20a1, 0x025a, 0x4003, 0x080c, 0x9dc8,
+	0x20a1, 0x024e, 0x20a9, 0x0008, 0x2099, 0x194e, 0x4003, 0x60c3,
+	0x0074, 0x0804, 0x95d9, 0x080c, 0x90d2, 0x7003, 0x2010, 0x7007,
+	0x0014, 0x700b, 0x0800, 0x700f, 0x2000, 0x9006, 0x00f6, 0x2079,
+	0x185b, 0x7904, 0x00fe, 0xd1ac, 0x1110, 0x9085, 0x0020, 0x0010,
+	0x9085, 0x0010, 0x9085, 0x0002, 0x00d6, 0x0804, 0x9082, 0x7026,
+	0x60c3, 0x0014, 0x0804, 0x95d9, 0x080c, 0x90d2, 0x7003, 0x5000,
+	0x0804, 0x8f62, 0x080c, 0x90d2, 0x7003, 0x2110, 0x7007, 0x0014,
+	0x60c3, 0x0014, 0x0804, 0x95d9, 0x080c, 0x9114, 0x0010, 0x080c,
+	0x911d, 0x7003, 0x0200, 0x60c3, 0x0004, 0x0804, 0x95d9, 0x080c,
+	0x911d, 0x7003, 0x0100, 0x700b, 0x0003, 0x700f, 0x2a00, 0x60c3,
+	0x0008, 0x0804, 0x95d9, 0x080c, 0x911d, 0x7003, 0x0200, 0x0804,
+	0x8f62, 0x080c, 0x911d, 0x7003, 0x0100, 0x782c, 0x9005, 0x0110,
+	0x700a, 0x0010, 0x700b, 0x0003, 0x7814, 0x700e, 0x60c3, 0x0008,
+	0x0804, 0x95d9, 0x00d6, 0x080c, 0x911d, 0x7003, 0x0210, 0x7007,
+	0x0014, 0x700b, 0x0800, 0xb894, 0x9086, 0x0014, 0x1198, 0xb99c,
+	0x9184, 0x0030, 0x0190, 0xb998, 0x9184, 0xc000, 0x1140, 0xd1ec,
+	0x0118, 0x700f, 0x2100, 0x0058, 0x700f, 0x0100, 0x0040, 0x700f,
+	0x0400, 0x0028, 0x700f, 0x0700, 0x0010, 0x700f, 0x0800, 0x00f6,
+	0x2079, 0x185b, 0x7904, 0x00fe, 0xd1ac, 0x1110, 0x9085, 0x0020,
+	0x0010, 0x9085, 0x0010, 0x2009, 0x187d, 0x210c, 0xd184, 0x1110,
+	0x9085, 0x0002, 0x0026, 0x2009, 0x187b, 0x210c, 0xd1e4, 0x0150,
+	0xc0c5, 0xbabc, 0xd28c, 0x1108, 0xc0cd, 0x9094, 0x0030, 0x9296,
+	0x0010, 0x0140, 0xd1ec, 0x0130, 0x9094, 0x0030, 0x9296, 0x0010,
+	0x0108, 0xc0bd, 0x002e, 0x7026, 0x60c3, 0x0014, 0x00de, 0x0804,
+	0x95d9, 0x080c, 0x911d, 0x7003, 0x0210, 0x7007, 0x0014, 0x700f,
+	0x0100, 0x60c3, 0x0014, 0x0804, 0x95d9, 0x080c, 0x911d, 0x7003,
+	0x0200, 0x0804, 0x8ee8, 0x080c, 0x911d, 0x7003, 0x0100, 0x700b,
+	0x0003, 0x700f, 0x2a00, 0x60c3, 0x0008, 0x0804, 0x95d9, 0x080c,
+	0x911d, 0x7003, 0x0100, 0x700b, 0x000b, 0x60c3, 0x0008, 0x0804,
+	0x95d9, 0x0026, 0x00d6, 0x0036, 0x0046, 0x2019, 0x3200, 0x2021,
+	0x0800, 0x0040, 0x0026, 0x00d6, 0x0036, 0x0046, 0x2019, 0x2200,
+	0x2021, 0x0100, 0x080c, 0x9ddd, 0xb810, 0x9305, 0x7002, 0xb814,
+	0x7006, 0x2069, 0x1800, 0x6878, 0x700a, 0x687c, 0x700e, 0x9485,
+	0x0029, 0x7012, 0x004e, 0x003e, 0x00de, 0x080c, 0x95c7, 0x721a,
+	0x9f95, 0x0000, 0x7222, 0x7027, 0xffff, 0x2071, 0x024c, 0x002e,
+	0x0005, 0x0026, 0x080c, 0x9ddd, 0x7003, 0x02ff, 0x7007, 0xfffc,
+	0x00d6, 0x2069, 0x1800, 0x6878, 0x700a, 0x687c, 0x700e, 0x00de,
+	0x7013, 0x2029, 0x0c10, 0x7003, 0x0100, 0x7007, 0x0000, 0x700b,
+	0xfc02, 0x700f, 0x0000, 0x0005, 0x0026, 0x00d6, 0x0036, 0x0046,
+	0x2019, 0x3300, 0x2021, 0x0800, 0x0040, 0x0026, 0x00d6, 0x0036,
+	0x0046, 0x2019, 0x2300, 0x2021, 0x0100, 0x080c, 0x9ddd, 0xb810,
+	0x9305, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800, 0xb810, 0x9005,
+	0x1140, 0xb814, 0x9005, 0x1128, 0x700b, 0x00ff, 0x700f, 0xfffe,
+	0x0020, 0x6878, 0x700a, 0x687c, 0x700e, 0x0000, 0x9485, 0x0098,
+	0x7012, 0x004e, 0x003e, 0x00de, 0x080c, 0x95c7, 0x721a, 0x7a08,
+	0x7222, 0x2f10, 0x7226, 0x2071, 0x024c, 0x002e, 0x0005, 0x080c,
+	0x95c7, 0x721a, 0x7a08, 0x7222, 0x7814, 0x7026, 0x2071, 0x024c,
+	0x002e, 0x0005, 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2069,
+	0x0200, 0x2071, 0x0240, 0x6004, 0x908a, 0x0085, 0x0a0c, 0x0e02,
+	0x908a, 0x0092, 0x1a0c, 0x0e02, 0x6110, 0x2158, 0xb9b0, 0x2c78,
+	0x2061, 0x0100, 0x619a, 0x9082, 0x0085, 0x0033, 0x00fe, 0x00ee,
+	0x00de, 0x00ce, 0x00be, 0x0005, 0x918b, 0x919a, 0x91a5, 0x9189,
+	0x9189, 0x9189, 0x918b, 0x9189, 0x9189, 0x9189, 0x9189, 0x9189,
+	0x9189, 0x080c, 0x0e02, 0x0411, 0x60c3, 0x0000, 0x0026, 0x080c,
+	0x29fe, 0x0228, 0x2011, 0x0101, 0x2204, 0xc0c5, 0x2012, 0x002e,
+	0x0804, 0x95d9, 0x0431, 0x7808, 0x700a, 0x7814, 0x700e, 0x7017,
+	0xffff, 0x60c3, 0x000c, 0x0804, 0x95d9, 0x04a1, 0x7003, 0x0003,
+	0x7007, 0x0300, 0x60c3, 0x0004, 0x0804, 0x95d9, 0x0026, 0x080c,
+	0x9ddd, 0xb810, 0x9085, 0x8100, 0x7002, 0xb814, 0x7006, 0x2069,
+	0x1800, 0x6878, 0x700a, 0x687c, 0x700e, 0x7013, 0x0009, 0x0804,
+	0x90ed, 0x0026, 0x080c, 0x9ddd, 0xb810, 0x9085, 0x8400, 0x7002,
+	0xb814, 0x7006, 0x2069, 0x1800, 0x6878, 0x700a, 0x687c, 0x700e,
+	0x2001, 0x0099, 0x7a20, 0x9296, 0x0005, 0x0108, 0xc0bc, 0x7012,
+	0x0804, 0x914f, 0x0026, 0x080c, 0x9ddd, 0xb810, 0x9085, 0x8500,
 	0x7002, 0xb814, 0x7006, 0x2069, 0x1800, 0x6878, 0x700a, 0x687c,
-	0x700e, 0x7013, 0x0009, 0x0804, 0x9149, 0x0026, 0x080c, 0x9eeb,
-	0xb810, 0x9085, 0x8400, 0x7002, 0xb814, 0x7006, 0x2069, 0x1800,
-	0x6878, 0x700a, 0x687c, 0x700e, 0x2001, 0x0099, 0x7a20, 0x9296,
-	0x0005, 0x0108, 0xc0bc, 0x7012, 0x0804, 0x91ab, 0x0026, 0x080c,
-	0x9eeb, 0xb810, 0x9085, 0x8500, 0x7002, 0xb814, 0x7006, 0x2069,
-	0x1800, 0x6878, 0x700a, 0x687c, 0x700e, 0x2001, 0x0099, 0x7a20,
-	0x9296, 0x0005, 0x0108, 0xc0bc, 0x7012, 0x0804, 0x91ab, 0x00b6,
-	0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2c78, 0x2069, 0x0200, 0x2071,
-	0x0240, 0x7804, 0x908a, 0x0040, 0x0a0c, 0x0dfa, 0x908a, 0x0054,
-	0x1a0c, 0x0dfa, 0x7910, 0x2158, 0xb9b0, 0x2061, 0x0100, 0x619a,
-	0x9082, 0x0040, 0x0033, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x00be,
-	0x0005, 0x9286, 0x9342, 0x9315, 0x9464, 0x9284, 0x9284, 0x9284,
-	0x9284, 0x9284, 0x9284, 0x9284, 0x9a2b, 0x9a33, 0x9a3b, 0x9a43,
-	0x9284, 0x9e33, 0x9284, 0x9a23, 0x080c, 0x0dfa, 0x0096, 0x780b,
-	0xffff, 0x080c, 0x92f1, 0x7914, 0x2148, 0xa978, 0x7956, 0xae64,
-	0x96b4, 0x00ff, 0x9686, 0x0008, 0x1148, 0xa8b4, 0x7032, 0xa8b8,
-	0x7036, 0xa8bc, 0x703a, 0xa8c0, 0x703e, 0x0008, 0x7132, 0xa97c,
-	0x9184, 0x000f, 0x1118, 0x2001, 0x0005, 0x0040, 0xd184, 0x0118,
-	0x2001, 0x0004, 0x0018, 0x9084, 0x0006, 0x8004, 0x2010, 0x785c,
-	0x9084, 0x00ff, 0x8007, 0x9205, 0x7042, 0xd1ac, 0x0158, 0x7047,
-	0x0002, 0x9686, 0x0008, 0x1118, 0x080c, 0x181c, 0x0010, 0x080c,
-	0x16db, 0x0050, 0xd1b4, 0x0118, 0x7047, 0x0001, 0x0028, 0x7047,
-	0x0000, 0x9016, 0x2230, 0x0010, 0xaab0, 0xaeac, 0x726a, 0x766e,
-	0x20a9, 0x0008, 0x20e9, 0x0000, 0xa860, 0x20e0, 0xa85c, 0x9080,
-	0x0023, 0x2098, 0x20a1, 0x0252, 0x2069, 0x0200, 0x6813, 0x0018,
-	0x4003, 0x6813, 0x0008, 0x60c3, 0x0020, 0x6017, 0x0009, 0x2001,
-	0x19db, 0x2003, 0x07d0, 0x2001, 0x19da, 0x2003, 0x0009, 0x009e,
-	0x0005, 0x6813, 0x0008, 0xba8c, 0x8210, 0xb8bc, 0xd084, 0x0128,
-	0x7a4a, 0x7b14, 0x7b46, 0x722e, 0x732a, 0x9294, 0x00ff, 0xba8e,
-	0x8217, 0x721a, 0xba10, 0x9295, 0x0600, 0x7202, 0xba14, 0x7206,
-	0x2069, 0x1800, 0x6a78, 0x720a, 0x6a7c, 0x720e, 0x7013, 0x0829,
-	0x2f10, 0x7222, 0x7027, 0xffff, 0x0005, 0x00d6, 0x0096, 0x0081,
-	0x7814, 0x2048, 0xa890, 0x7002, 0xa88c, 0x7006, 0xa8b0, 0x700a,
-	0xa8ac, 0x700e, 0x60c3, 0x000c, 0x009e, 0x00de, 0x0804, 0x962a,
-	0x6813, 0x0008, 0xb810, 0x9085, 0x0500, 0x7002, 0xb814, 0x7006,
-	0x2069, 0x1800, 0x6878, 0x700a, 0x687c, 0x700e, 0x7013, 0x0889,
-	0x080c, 0x9618, 0x721a, 0x7a08, 0x7222, 0x2f10, 0x7226, 0x2071,
-	0x024c, 0x0005, 0x00d6, 0x0096, 0x080c, 0x9442, 0x7814, 0x2048,
-	0x080c, 0xbe35, 0x1130, 0x7814, 0x9084, 0x0700, 0x8007, 0x0033,
-	0x0010, 0x9006, 0x001b, 0x009e, 0x00de, 0x0005, 0x9360, 0x93c9,
-	0x93d9, 0x93ff, 0x940b, 0x941c, 0x9424, 0x935e, 0x080c, 0x0dfa,
-	0x0016, 0x0036, 0xa97c, 0x918c, 0x0003, 0x0118, 0x9186, 0x0003,
-	0x1198, 0xaba8, 0x7824, 0xd0cc, 0x1168, 0x7316, 0xa898, 0x701a,
-	0xa894, 0x701e, 0x003e, 0x001e, 0x2001, 0x1989, 0x2004, 0x60c2,
-	0x0804, 0x962a, 0xc3e5, 0x0c88, 0x9186, 0x0001, 0x190c, 0x0dfa,
-	0xaba8, 0x7824, 0xd0cc, 0x1904, 0x93c6, 0x7316, 0xa898, 0x701a,
-	0xa894, 0x701e, 0xa8a4, 0x7026, 0xa8ac, 0x702e, 0x2009, 0x0018,
-	0x9384, 0x0300, 0x0570, 0xd3c4, 0x0110, 0xa8ac, 0x9108, 0xd3cc,
-	0x0110, 0xa8a4, 0x9108, 0x6810, 0x9085, 0x0010, 0x6812, 0x2011,
-	0x0258, 0x20e9, 0x0000, 0x22a0, 0x0156, 0x20a9, 0x0008, 0xa860,
-	0x20e0, 0xa85c, 0x9080, 0x002c, 0x2098, 0x4003, 0x6810, 0x8000,
-	0x6812, 0x2011, 0x0240, 0x22a0, 0x20a9, 0x0005, 0x4003, 0x6810,
-	0xc084, 0x6812, 0x015e, 0x9184, 0x0003, 0x0118, 0x2019, 0x0245,
-	0x201a, 0x61c2, 0x003e, 0x001e, 0x0804, 0x962a, 0xc3e5, 0x0804,
-	0x9385, 0x2011, 0x0008, 0x2001, 0x180f, 0x2004, 0xd0a4, 0x0110,
-	0x2011, 0x0028, 0x7824, 0xd0cc, 0x1110, 0x7216, 0x0470, 0x0ce8,
-	0xc2e5, 0x2011, 0x0302, 0x0016, 0x782c, 0x701a, 0x7930, 0x711e,
-	0x9105, 0x0108, 0xc2dd, 0x001e, 0x7824, 0xd0cc, 0x0108, 0xc2e5,
-	0x7216, 0x7027, 0x0012, 0x702f, 0x0008, 0x7043, 0x7000, 0x7047,
-	0x0500, 0x704f, 0x000a, 0x2069, 0x0200, 0x6813, 0x0009, 0x2071,
-	0x0240, 0x700b, 0x2500, 0x60c3, 0x0032, 0x0804, 0x962a, 0x2011,
-	0x0028, 0x7824, 0xd0cc, 0x1128, 0x7216, 0x60c3, 0x0018, 0x0804,
-	0x962a, 0x0cd0, 0xc2e5, 0x2011, 0x0100, 0x7824, 0xd0cc, 0x0108,
-	0xc2e5, 0x7216, 0x702f, 0x0008, 0x7858, 0x9084, 0x00ff, 0x7036,
-	0x60c3, 0x0020, 0x0804, 0x962a, 0x2011, 0x0008, 0x7824, 0xd0cc,
-	0x0108, 0xc2e5, 0x7216, 0x0c08, 0x0036, 0x7b14, 0x9384, 0xff00,
-	0x7816, 0x9384, 0x00ff, 0x8001, 0x1138, 0x7824, 0xd0cc, 0x0108,
-	0xc2e5, 0x7216, 0x003e, 0x0888, 0x0046, 0x2021, 0x0800, 0x0006,
-	0x7824, 0xd0cc, 0x000e, 0x0108, 0xc4e5, 0x7416, 0x004e, 0x701e,
-	0x003e, 0x0818, 0x00d6, 0x6813, 0x0008, 0xb810, 0x9085, 0x0700,
-	0x7002, 0xb814, 0x7006, 0x2069, 0x1800, 0x6878, 0x700a, 0x687c,
-	0x700e, 0x7824, 0xd0cc, 0x1168, 0x7013, 0x0898, 0x080c, 0x9618,
-	0x721a, 0x7a08, 0x7222, 0x2f10, 0x7226, 0x2071, 0x024c, 0x00de,
-	0x0005, 0x7013, 0x0889, 0x0c90, 0x0016, 0x7814, 0x9084, 0x0700,
-	0x8007, 0x0013, 0x001e, 0x0005, 0x9474, 0x9474, 0x9476, 0x9474,
-	0x9474, 0x9474, 0x9490, 0x9474, 0x080c, 0x0dfa, 0x7914, 0x918c,
-	0x08ff, 0x918d, 0xf600, 0x7916, 0x2009, 0x0003, 0x00b9, 0x2069,
-	0x185b, 0x6804, 0xd0bc, 0x0130, 0x682c, 0x9084, 0x00ff, 0x8007,
-	0x7032, 0x0010, 0x7033, 0x3f00, 0x60c3, 0x0001, 0x0804, 0x962a,
-	0x2009, 0x0003, 0x0019, 0x7033, 0x7f00, 0x0cb0, 0x0016, 0x080c,
-	0x9eeb, 0x001e, 0xb810, 0x9085, 0x0100, 0x7002, 0xb814, 0x7006,
-	0x2069, 0x1800, 0x6a78, 0x720a, 0x6a7c, 0x720e, 0x7013, 0x0888,
-	0x918d, 0x0008, 0x7116, 0x080c, 0x9618, 0x721a, 0x7a08, 0x7222,
-	0x2f10, 0x7226, 0x0005, 0x00b6, 0x0096, 0x00e6, 0x00d6, 0x00c6,
-	0x0056, 0x0046, 0x0036, 0x2061, 0x0100, 0x2071, 0x1800, 0x7810,
-	0x2058, 0xb8a0, 0x2028, 0xb910, 0xba14, 0x7378, 0x747c, 0x7820,
-	0x90be, 0x0006, 0x0904, 0x9587, 0x90be, 0x000a, 0x1904, 0x9543,
-	0xb8b0, 0x609e, 0x7814, 0x2048, 0xa87c, 0xd0fc, 0x0558, 0xaf90,
-	0x9784, 0xff00, 0x9105, 0x6062, 0x873f, 0x9784, 0xff00, 0x0006,
-	0x7814, 0x2048, 0xa878, 0xc0fc, 0x9005, 0x000e, 0x1160, 0xaf94,
-	0x87ff, 0x0198, 0x2039, 0x0098, 0x9705, 0x6072, 0x7808, 0x6082,
-	0x2f00, 0x6086, 0x0038, 0x9185, 0x2200, 0x6062, 0x6073, 0x0129,
-	0x6077, 0x0000, 0xb8b0, 0x609e, 0x0050, 0x2039, 0x0029, 0x9705,
-	0x6072, 0x0cc0, 0x9185, 0x0200, 0x6062, 0x6073, 0x2029, 0xa87c,
-	0xd0fc, 0x0118, 0xaf94, 0x87ff, 0x1120, 0x2f00, 0x6082, 0x7808,
-	0x6086, 0x6266, 0x636a, 0x646e, 0x6077, 0x0000, 0xb88c, 0x8000,
-	0x9084, 0x00ff, 0xb88e, 0x8007, 0x607a, 0x607f, 0x0000, 0xa838,
-	0x608a, 0xa834, 0x608e, 0xa848, 0x60c6, 0xa844, 0x60ca, 0xb86c,
-	0x60ce, 0x60af, 0x95d5, 0x60d7, 0x0000, 0x080c, 0x9ed0, 0x2009,
-	0x07d0, 0x60c4, 0x9084, 0xfff0, 0x9005, 0x0110, 0x2009, 0x1b58,
-	0x080c, 0x835f, 0x003e, 0x004e, 0x005e, 0x00ce, 0x00de, 0x00ee,
-	0x009e, 0x00be, 0x0005, 0x7804, 0x9086, 0x0040, 0x0904, 0x95c3,
-	0x9185, 0x0100, 0x6062, 0x6266, 0x636a, 0x646e, 0x6073, 0x0809,
-	0x6077, 0x0008, 0x60af, 0x95d5, 0x60d7, 0x0000, 0xb88c, 0x8000,
-	0x9084, 0x00ff, 0xb88e, 0x8007, 0x607a, 0x607f, 0x0000, 0x2f00,
-	0x6082, 0x7808, 0x6086, 0x7814, 0x2048, 0xa838, 0x608a, 0xa834,
-	0x608e, 0xa848, 0x60c6, 0xa844, 0x60ca, 0xb86c, 0x60ce, 0xbab0,
-	0x629e, 0x080c, 0x9ed0, 0x2009, 0x07d0, 0x60c4, 0x9084, 0xfff0,
-	0x9005, 0x0110, 0x2009, 0x1b58, 0x080c, 0x835f, 0x003e, 0x004e,
-	0x005e, 0x00ce, 0x00de, 0x00ee, 0x009e, 0x00be, 0x0005, 0x7814,
-	0x2048, 0xa87c, 0x9084, 0x0003, 0x9086, 0x0002, 0x0904, 0x95df,
-	0x9185, 0x0100, 0x6062, 0x6266, 0x636a, 0x646e, 0x6073, 0x0880,
-	0x6077, 0x0008, 0xb88c, 0x8000, 0x9084, 0x00ff, 0xb88e, 0x8007,
-	0x607a, 0x7838, 0x607e, 0x2f00, 0x6086, 0x7808, 0x6082, 0xa890,
-	0x608a, 0xa88c, 0x608e, 0xa8b0, 0x60c6, 0xa8ac, 0x60ca, 0xa8ac,
-	0x7930, 0x9108, 0x7932, 0xa8b0, 0x792c, 0x9109, 0x792e, 0xb86c,
-	0x60ce, 0x60af, 0x95d5, 0x60d7, 0x0000, 0xbab0, 0x629e, 0x080c,
-	0x9ead, 0x0804, 0x9573, 0xb8bc, 0xd084, 0x0148, 0xb88c, 0x7814,
-	0x2048, 0xb88c, 0x784a, 0xa836, 0x2900, 0xa83a, 0xb046, 0x9185,
-	0x0600, 0x6062, 0x6266, 0x636a, 0x646e, 0x6073, 0x0829, 0x6077,
-	0x0000, 0x60af, 0x9575, 0x60d7, 0x0000, 0x0804, 0x9556, 0x9185,
-	0x0700, 0x6062, 0x6266, 0x636a, 0x646e, 0x7824, 0xd0cc, 0x7826,
-	0x0118, 0x6073, 0x0889, 0x0010, 0x6073, 0x0898, 0x6077, 0x0000,
-	0xb88c, 0x8000, 0x9084, 0x00ff, 0xb88e, 0x8007, 0x607a, 0x607f,
-	0x0000, 0x2f00, 0x6086, 0x7808, 0x6082, 0xa838, 0x608a, 0xa834,
-	0x608e, 0xa848, 0x60c6, 0xa844, 0x60ca, 0xb86c, 0x60ce, 0x60af,
-	0x95d5, 0x60d7, 0x0000, 0xbab0, 0x629e, 0x7824, 0xd0cc, 0x0120,
-	0x080c, 0x9ed0, 0x0804, 0x9573, 0x080c, 0x9ead, 0x0804, 0x9573,
-	0x7a10, 0x00b6, 0x2258, 0xba8c, 0x8210, 0x9294, 0x00ff, 0xba8e,
-	0x00be, 0x8217, 0x0005, 0x00d6, 0x2069, 0x19bf, 0x6843, 0x0001,
-	0x00de, 0x0005, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x00f1, 0x080c,
-	0x8351, 0x0005, 0x0016, 0x2001, 0x180c, 0x200c, 0x9184, 0x0600,
-	0x9086, 0x0600, 0x0128, 0x0089, 0x080c, 0x8351, 0x001e, 0x0005,
-	0xc1e5, 0x2001, 0x180c, 0x2102, 0x2001, 0x19c0, 0x2003, 0x0000,
-	0x2001, 0x19c8, 0x2003, 0x0000, 0x0c88, 0x0006, 0x6014, 0x9084,
-	0x1804, 0x9085, 0x0009, 0x6016, 0x000e, 0x0005, 0x0016, 0x00c6,
-	0x0006, 0x2061, 0x0100, 0x61a4, 0x60a7, 0x95f5, 0x6014, 0x9084,
-	0x1804, 0x9085, 0x0008, 0x6016, 0x000e, 0xa001, 0xa001, 0xa001,
-	0x61a6, 0x00ce, 0x001e, 0x0005, 0x00c6, 0x00d6, 0x0016, 0x0026,
-	0x2061, 0x0100, 0x2069, 0x0140, 0x080c, 0x7207, 0x11c0, 0x2001,
-	0x19db, 0x2004, 0x9005, 0x15d0, 0x080c, 0x72d2, 0x1160, 0x2061,
-	0x0100, 0x6020, 0xd0b4, 0x1120, 0x6024, 0xd084, 0x090c, 0x0dfa,
-	0x080c, 0x8351, 0x0458, 0x00c6, 0x2061, 0x19bf, 0x00c8, 0x6904,
-	0x9194, 0x4000, 0x0540, 0x0811, 0x080c, 0x2c98, 0x00c6, 0x2061,
-	0x19bf, 0x6128, 0x9192, 0x0008, 0x1258, 0x8108, 0x612a, 0x6124,
-	0x00ce, 0x81ff, 0x0198, 0x080c, 0x8351, 0x080c, 0x964d, 0x0070,
-	0x6124, 0x91e5, 0x0000, 0x0140, 0x080c, 0xdc28, 0x080c, 0x835a,
-	0x2009, 0x0014, 0x080c, 0xa15d, 0x00ce, 0x0000, 0x002e, 0x001e,
-	0x00de, 0x00ce, 0x0005, 0x2001, 0x19db, 0x2004, 0x9005, 0x1db0,
-	0x00c6, 0x2061, 0x19bf, 0x6128, 0x9192, 0x0003, 0x1e08, 0x8108,
-	0x612a, 0x00ce, 0x080c, 0x8351, 0x080c, 0x5dea, 0x2009, 0x185a,
-	0x2114, 0x8210, 0x220a, 0x0c10, 0x0096, 0x00c6, 0x00d6, 0x00e6,
-	0x0016, 0x0026, 0x080c, 0x8367, 0x2071, 0x19bf, 0x713c, 0x81ff,
-	0x0904, 0x974a, 0x2061, 0x0100, 0x2069, 0x0140, 0x080c, 0x7207,
-	0x1190, 0x0036, 0x2019, 0x0002, 0x080c, 0x999d, 0x003e, 0x713c,
-	0x2160, 0x080c, 0xdc28, 0x2009, 0x004a, 0x080c, 0xa15d, 0x080c,
-	0x72d2, 0x0804, 0x974a, 0x080c, 0x9756, 0x0904, 0x974a, 0x6904,
-	0xd1f4, 0x0904, 0x9751, 0x080c, 0x2c98, 0x00c6, 0x703c, 0x9065,
-	0x090c, 0x0dfa, 0x6020, 0x00ce, 0x9086, 0x0006, 0x1568, 0x61c8,
-	0x60c4, 0x9105, 0x1548, 0x2009, 0x180c, 0x2104, 0xd0d4, 0x0520,
-	0x6214, 0x9294, 0x1800, 0x1128, 0x6224, 0x9294, 0x0002, 0x1550,
-	0x0070, 0xc0d4, 0x200a, 0x0006, 0x2001, 0x0100, 0x2004, 0x9086,
-	0x000a, 0x000e, 0x0120, 0xd0cc, 0x0110, 0x080c, 0x2bca, 0x6014,
-	0x9084, 0xe7fd, 0x9085, 0x0010, 0x6016, 0x703c, 0x2060, 0x2009,
-	0x0049, 0x080c, 0xa15d, 0x0070, 0x0036, 0x2019, 0x0001, 0x080c,
-	0x999d, 0x003e, 0x713c, 0x2160, 0x080c, 0xdc28, 0x2009, 0x004a,
-	0x080c, 0xa15d, 0x002e, 0x001e, 0x00ee, 0x00de, 0x00ce, 0x009e,
-	0x0005, 0xd1ec, 0x1904, 0x9703, 0x0804, 0x9705, 0x00d6, 0x00c6,
-	0x0096, 0x703c, 0x9065, 0x090c, 0x0dfa, 0x2001, 0x0306, 0x200c,
-	0x9184, 0x0030, 0x0904, 0x97ff, 0x9184, 0x0048, 0x9086, 0x0008,
-	0x1904, 0x97ff, 0x2009, 0x0206, 0x2104, 0x2009, 0x0203, 0x210c,
-	0x9106, 0x1904, 0x97ff, 0x2009, 0x022a, 0x2104, 0x2009, 0x022f,
-	0x210c, 0x9116, 0x9084, 0x03ff, 0x918c, 0x03ff, 0x9294, 0x0400,
-	0x0110, 0x9102, 0x0030, 0x2010, 0x2100, 0x9202, 0x2009, 0x0228,
-	0x9102, 0x9082, 0x0005, 0x0250, 0x2008, 0x2001, 0x013b, 0x2004,
-	0x8004, 0x8004, 0x8004, 0x9102, 0x1a04, 0x97ff, 0x2009, 0x1a58,
-	0x2104, 0x8000, 0x0208, 0x200a, 0x2069, 0x0100, 0x6914, 0x918c,
-	0x0184, 0x918d, 0x0010, 0x6916, 0x69c8, 0x2011, 0x0020, 0x68c8,
-	0x9106, 0x1570, 0x8211, 0x1dd8, 0x2001, 0x0306, 0x2003, 0x4800,
-	0x2001, 0x009a, 0x2003, 0x0004, 0x2001, 0x1a3d, 0x2003, 0x0000,
-	0x2001, 0x1a46, 0x2003, 0x0000, 0x6a88, 0x698c, 0x2200, 0x9105,
-	0x1120, 0x2c10, 0x080c, 0x1afe, 0x0040, 0x6014, 0x2048, 0xaa3a,
-	0xa936, 0x6ac4, 0x69c8, 0xa946, 0xaa4a, 0x0126, 0x00c6, 0x2091,
-	0x2400, 0x002e, 0x080c, 0x1b8a, 0x190c, 0x0dfa, 0x012e, 0x0090,
-	0x2009, 0x1a59, 0x2104, 0x8000, 0x0208, 0x200a, 0x69c8, 0x2011,
-	0x0020, 0x8211, 0x1df0, 0x68c8, 0x9106, 0x1dc0, 0x69c4, 0x68c8,
-	0x9105, 0x0160, 0x6824, 0xd08c, 0x0110, 0x6827, 0x0002, 0x7048,
-	0xc085, 0x704a, 0x0079, 0x7048, 0xc084, 0x704a, 0x2009, 0x07d0,
-	0x080c, 0x835f, 0x9006, 0x009e, 0x00ce, 0x00de, 0x0005, 0x9085,
-	0x0001, 0x0cc8, 0x0026, 0x00e6, 0x2071, 0x19bf, 0x7048, 0xd084,
-	0x01c0, 0x713c, 0x81ff, 0x01a8, 0x2071, 0x0100, 0x9188, 0x0008,
-	0x2114, 0x928e, 0x0006, 0x1138, 0x7014, 0x9084, 0x1984, 0x9085,
-	0x0012, 0x7016, 0x0030, 0x7014, 0x9084, 0x1984, 0x9085, 0x0016,
-	0x7016, 0x00ee, 0x002e, 0x0005, 0x00b6, 0x00e6, 0x00d6, 0x00c6,
-	0x0066, 0x0056, 0x0046, 0x0006, 0x0126, 0x2091, 0x8000, 0x6010,
-	0x2058, 0xbca0, 0x2071, 0x19bf, 0x7018, 0x2058, 0x8bff, 0x0190,
-	0xb8a0, 0x9406, 0x0118, 0xb854, 0x2058, 0x0cc0, 0x6014, 0x0096,
-	0x2048, 0xac6c, 0xad70, 0xae78, 0x009e, 0x080c, 0x65d1, 0x0110,
-	0x9085, 0x0001, 0x012e, 0x000e, 0x004e, 0x005e, 0x006e, 0x00ce,
-	0x00de, 0x00ee, 0x00be, 0x0005, 0x080c, 0x912e, 0x7003, 0x1200,
-	0x7838, 0x7012, 0x783c, 0x7016, 0x00c6, 0x7820, 0x9086, 0x0004,
-	0x1148, 0x7810, 0x9005, 0x0130, 0x00b6, 0x2058, 0xb810, 0xb914,
-	0x00be, 0x0020, 0x2061, 0x1800, 0x6078, 0x617c, 0x9084, 0x00ff,
-	0x700a, 0x710e, 0x00ce, 0x60c3, 0x002c, 0x0804, 0x962a, 0x080c,
-	0x912e, 0x7003, 0x0f00, 0x7808, 0xd09c, 0x0128, 0xb810, 0x9084,
-	0x00ff, 0x700a, 0xb814, 0x700e, 0x60c3, 0x0008, 0x0804, 0x962a,
-	0x0156, 0x080c, 0x9179, 0x7003, 0x0200, 0x2011, 0x1848, 0x63f0,
-	0x2312, 0x20a9, 0x0006, 0x2011, 0x1840, 0x2019, 0x1841, 0x9ef0,
-	0x0002, 0x2376, 0x8e70, 0x2276, 0x8e70, 0x9398, 0x0002, 0x9290,
-	0x0002, 0x1f04, 0x9899, 0x60c3, 0x001c, 0x015e, 0x0804, 0x962a,
-	0x0016, 0x0026, 0x080c, 0x9155, 0x080c, 0x9167, 0x9e80, 0x0004,
-	0x20e9, 0x0000, 0x20a0, 0x7814, 0x0096, 0x2048, 0xa800, 0x2048,
-	0xa860, 0x20e0, 0xa85c, 0x9080, 0x0021, 0x2098, 0x009e, 0x7808,
-	0x9088, 0x0002, 0x21a8, 0x9192, 0x0010, 0x1250, 0x4003, 0x9080,
-	0x0004, 0x8003, 0x60c2, 0x080c, 0x962a, 0x002e, 0x001e, 0x0005,
-	0x20a9, 0x0010, 0x4003, 0x080c, 0x9ed6, 0x20a1, 0x0240, 0x22a8,
-	0x4003, 0x0c68, 0x080c, 0x912e, 0x7003, 0x6200, 0x7808, 0x700e,
-	0x60c3, 0x0008, 0x0804, 0x962a, 0x0016, 0x0026, 0x080c, 0x912e,
-	0x20e9, 0x0000, 0x20a1, 0x024c, 0x7814, 0x0096, 0x2048, 0xa800,
-	0x2048, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x0023, 0x2098, 0x009e,
-	0x7808, 0x9088, 0x0002, 0x21a8, 0x4003, 0x8003, 0x60c2, 0x080c,
-	0x962a, 0x002e, 0x001e, 0x0005, 0x00e6, 0x00c6, 0x0006, 0x0126,
-	0x2091, 0x8000, 0x2071, 0x19bf, 0x700c, 0x2060, 0x8cff, 0x0178,
-	0x080c, 0xc03f, 0x1110, 0x080c, 0xaa81, 0x600c, 0x0006, 0x080c,
-	0xc2ab, 0x080c, 0xa0e3, 0x080c, 0x9a4e, 0x00ce, 0x0c78, 0x2c00,
-	0x700e, 0x700a, 0x012e, 0x000e, 0x00ce, 0x00ee, 0x0005, 0x0126,
-	0x0156, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0026, 0x0016,
-	0x0006, 0x2091, 0x8000, 0x2001, 0x180c, 0x200c, 0x918c, 0xe7ff,
-	0x2102, 0x2069, 0x0100, 0x2079, 0x0140, 0x2071, 0x19bf, 0x7024,
-	0x2060, 0x8cff, 0x01f8, 0x080c, 0x9656, 0x6ac0, 0x68c3, 0x0000,
-	0x080c, 0x835a, 0x00c6, 0x2061, 0x0100, 0x080c, 0x9eef, 0x00ce,
-	0x20a9, 0x01f4, 0x0461, 0x2009, 0x0013, 0x080c, 0xa15d, 0x000e,
-	0x001e, 0x002e, 0x006e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x015e,
-	0x012e, 0x0005, 0x2001, 0x1800, 0x2004, 0x9096, 0x0001, 0x0d78,
-	0x9096, 0x0004, 0x0d60, 0x080c, 0x835a, 0x6814, 0x9084, 0x0001,
-	0x0110, 0x68a7, 0x95f5, 0x6817, 0x0008, 0x68c3, 0x0000, 0x2011,
-	0x5d94, 0x080c, 0x82da, 0x20a9, 0x01f4, 0x0009, 0x08c0, 0x6824,
-	0xd094, 0x0140, 0x6827, 0x0004, 0x7804, 0x9084, 0x4000, 0x190c,
-	0x2c98, 0x0090, 0xd084, 0x0118, 0x6827, 0x0001, 0x0010, 0x1f04,
-	0x997f, 0x7804, 0x9084, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c,
-	0x2c88, 0x9006, 0x080c, 0x2c88, 0x0005, 0x0126, 0x0156, 0x00f6,
-	0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0026, 0x0016, 0x0006, 0x2091,
-	0x8000, 0x2001, 0x180c, 0x200c, 0x918c, 0xdbff, 0x2102, 0x2069,
-	0x0100, 0x2079, 0x0140, 0x2071, 0x19bf, 0x703c, 0x2060, 0x8cff,
-	0x0904, 0x9a04, 0x9386, 0x0002, 0x1128, 0x6814, 0x9084, 0x0002,
-	0x0904, 0x9a04, 0x68af, 0x95f5, 0x6817, 0x0010, 0x2009, 0x00fa,
-	0x8109, 0x1df0, 0x69c6, 0x68cb, 0x0008, 0x080c, 0x8367, 0x080c,
-	0x1f32, 0x2001, 0x0032, 0x6920, 0xd1bc, 0x0130, 0x8001, 0x1dd8,
-	0x692c, 0x918d, 0x0008, 0x692e, 0x20a9, 0x03e8, 0x6824, 0xd094,
-	0x0140, 0x6827, 0x0004, 0x7804, 0x9084, 0x4000, 0x190c, 0x2c98,
-	0x0090, 0xd08c, 0x0118, 0x6827, 0x0002, 0x0010, 0x1f04, 0x99de,
-	0x7804, 0x9084, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2c88,
-	0x9006, 0x080c, 0x2c88, 0x6827, 0x4000, 0x6824, 0x83ff, 0x1120,
-	0x2009, 0x0049, 0x080c, 0xa15d, 0x000e, 0x001e, 0x002e, 0x006e,
-	0x00ce, 0x00de, 0x00ee, 0x00fe, 0x015e, 0x012e, 0x0005, 0x00d6,
-	0x0126, 0x2091, 0x8000, 0x2069, 0x19bf, 0x6a06, 0x012e, 0x00de,
-	0x0005, 0x00d6, 0x0126, 0x2091, 0x8000, 0x2069, 0x19bf, 0x6a32,
-	0x012e, 0x00de, 0x0005, 0x080c, 0x92f1, 0x7854, 0x7032, 0x7042,
-	0x7047, 0x1000, 0x00f8, 0x080c, 0x92f1, 0x7854, 0x7032, 0x7042,
-	0x7047, 0x4000, 0x00b8, 0x080c, 0x92f1, 0x7854, 0x7032, 0x7042,
-	0x7047, 0x2000, 0x0078, 0x080c, 0x92f1, 0x7854, 0x7032, 0x7042,
-	0x7047, 0x0400, 0x0038, 0x080c, 0x92f1, 0x7854, 0x7032, 0x7042,
-	0x7047, 0x0200, 0x60c3, 0x0020, 0x0804, 0x962a, 0x00e6, 0x2071,
-	0x19bf, 0x7020, 0x9005, 0x0110, 0x8001, 0x7022, 0x00ee, 0x0005,
-	0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0076, 0x0066, 0x0006, 0x0126,
-	0x2091, 0x8000, 0x2071, 0x19bf, 0x7614, 0x2660, 0x2678, 0x2039,
-	0x0001, 0x87ff, 0x0904, 0x9af3, 0x8cff, 0x0904, 0x9af3, 0x6020,
-	0x9086, 0x0006, 0x1904, 0x9aee, 0x88ff, 0x0138, 0x2800, 0x9c06,
-	0x1904, 0x9aee, 0x2039, 0x0000, 0x0050, 0x6010, 0x9b06, 0x1904,
-	0x9aee, 0x85ff, 0x0120, 0x6054, 0x9106, 0x1904, 0x9aee, 0x7024,
-	0x9c06, 0x15b0, 0x2069, 0x0100, 0x68c0, 0x9005, 0x1160, 0x6824,
-	0xd084, 0x0148, 0x6827, 0x0001, 0x080c, 0x835a, 0x080c, 0x9b78,
-	0x7027, 0x0000, 0x0428, 0x080c, 0x835a, 0x6820, 0xd0b4, 0x0110,
-	0x68a7, 0x95f5, 0x6817, 0x0008, 0x68c3, 0x0000, 0x080c, 0x9b78,
-	0x7027, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0x9384, 0x1000,
-	0x0138, 0x2001, 0x0100, 0x080c, 0x2c88, 0x9006, 0x080c, 0x2c88,
-	0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x003e,
-	0x7014, 0x9c36, 0x1110, 0x660c, 0x7616, 0x7010, 0x9c36, 0x1140,
-	0x2c00, 0x9f36, 0x0118, 0x2f00, 0x7012, 0x0010, 0x7013, 0x0000,
-	0x660c, 0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678,
-	0x89ff, 0x1168, 0x600f, 0x0000, 0x6014, 0x0096, 0x2048, 0x080c,
-	0xbe35, 0x0110, 0x080c, 0xd830, 0x009e, 0x080c, 0xa113, 0x080c,
-	0x9a4e, 0x88ff, 0x1190, 0x00ce, 0x0804, 0x9a69, 0x2c78, 0x600c,
-	0x2060, 0x0804, 0x9a69, 0x9006, 0x012e, 0x000e, 0x006e, 0x007e,
-	0x00ce, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x601b, 0x0000, 0x00ce,
-	0x98c5, 0x0001, 0x0c88, 0x00f6, 0x00e6, 0x00d6, 0x0096, 0x00c6,
-	0x0066, 0x0026, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x19bf,
-	0x7638, 0x2660, 0x2678, 0x8cff, 0x0904, 0x9b67, 0x6020, 0x9086,
-	0x0006, 0x1904, 0x9b62, 0x87ff, 0x0128, 0x2700, 0x9c06, 0x1904,
-	0x9b62, 0x0040, 0x6010, 0x9b06, 0x15e8, 0x85ff, 0x0118, 0x6054,
-	0x9106, 0x15c0, 0x703c, 0x9c06, 0x1168, 0x0036, 0x2019, 0x0001,
-	0x080c, 0x999d, 0x7033, 0x0000, 0x9006, 0x703e, 0x7042, 0x7046,
-	0x704a, 0x003e, 0x7038, 0x9c36, 0x1110, 0x660c, 0x763a, 0x7034,
-	0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x7036, 0x0010,
-	0x7037, 0x0000, 0x660c, 0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e,
-	0x0008, 0x2678, 0x600f, 0x0000, 0x6014, 0x2048, 0x080c, 0xbe35,
-	0x0110, 0x080c, 0xd830, 0x080c, 0xa113, 0x87ff, 0x1198, 0x00ce,
-	0x0804, 0x9b13, 0x2c78, 0x600c, 0x2060, 0x0804, 0x9b13, 0x9006,
-	0x012e, 0x000e, 0x002e, 0x006e, 0x00ce, 0x009e, 0x00de, 0x00ee,
-	0x00fe, 0x0005, 0x601b, 0x0000, 0x00ce, 0x97bd, 0x0001, 0x0c80,
-	0x00e6, 0x2071, 0x19bf, 0x2001, 0x1800, 0x2004, 0x9086, 0x0002,
-	0x1118, 0x7007, 0x0005, 0x0010, 0x7007, 0x0000, 0x00ee, 0x0005,
-	0x00f6, 0x00e6, 0x00c6, 0x0066, 0x0026, 0x0006, 0x0126, 0x2091,
-	0x8000, 0x2071, 0x19bf, 0x2c10, 0x7638, 0x2660, 0x2678, 0x8cff,
-	0x0540, 0x2200, 0x9c06, 0x1508, 0x7038, 0x9c36, 0x1110, 0x660c,
+	0x700e, 0x2001, 0x0099, 0x7a20, 0x9296, 0x0005, 0x0108, 0xc0bc,
+	0x7012, 0x0804, 0x914f, 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6,
+	0x2c78, 0x2069, 0x0200, 0x2071, 0x0240, 0x7804, 0x908a, 0x0040,
+	0x0a0c, 0x0e02, 0x908a, 0x0054, 0x1a0c, 0x0e02, 0x7910, 0x2158,
+	0xb9b0, 0x2061, 0x0100, 0x619a, 0x9082, 0x0040, 0x0033, 0x00fe,
+	0x00ee, 0x00de, 0x00ce, 0x00be, 0x0005, 0x922a, 0x92f1, 0x92c4,
+	0x9413, 0x9228, 0x9228, 0x9228, 0x9228, 0x9228, 0x9228, 0x9228,
+	0x9927, 0x992c, 0x9931, 0x9936, 0x9228, 0x9d25, 0x9228, 0x9922,
+	0x080c, 0x0e02, 0x0096, 0x780b, 0xffff, 0x080c, 0x9295, 0x7914,
+	0x2148, 0xa978, 0x7956, 0xae64, 0x96b4, 0x00ff, 0x9686, 0x0008,
+	0x1148, 0xa8b4, 0x7032, 0xa8b8, 0x7036, 0xa8bc, 0x703a, 0xa8c0,
+	0x703e, 0x0008, 0x7132, 0xa97c, 0x9184, 0x000f, 0x1118, 0x2001,
+	0x0005, 0x0040, 0xd184, 0x0118, 0x2001, 0x0004, 0x0018, 0x9084,
+	0x0006, 0x8004, 0x2010, 0x785c, 0x9084, 0x00ff, 0x8007, 0x9205,
+	0x7042, 0xd1ac, 0x0158, 0x7047, 0x0002, 0x9686, 0x0008, 0x1118,
+	0x080c, 0x179e, 0x0010, 0x080c, 0x165d, 0x0050, 0xd1b4, 0x0118,
+	0x7047, 0x0001, 0x0028, 0x7047, 0x0000, 0x9016, 0x2230, 0x0010,
+	0xaab0, 0xaeac, 0x726a, 0x766e, 0x20a9, 0x0008, 0x20e9, 0x0000,
+	0xa860, 0x20e0, 0xa85c, 0x9080, 0x0023, 0x2098, 0x20a1, 0x0252,
+	0x2069, 0x0200, 0x6813, 0x0018, 0x4003, 0x6813, 0x0008, 0x60c3,
+	0x0020, 0x6017, 0x0009, 0x2001, 0x19de, 0x2003, 0x07d0, 0x2001,
+	0x19dd, 0x2003, 0x0009, 0x009e, 0x0005, 0x6813, 0x0008, 0xba8c,
+	0x8210, 0xb8bc, 0xd084, 0x0180, 0x2001, 0x1aa1, 0x200c, 0x8108,
+	0x2102, 0x2001, 0x1aa0, 0x201c, 0x1218, 0x8318, 0x2302, 0x0ea0,
+	0x794a, 0x712e, 0x7b46, 0x732a, 0x9294, 0x00ff, 0xba8e, 0x8217,
+	0x721a, 0xba10, 0x9295, 0x0600, 0x7202, 0xba14, 0x7206, 0x2069,
+	0x1800, 0x6a78, 0x720a, 0x6a7c, 0x720e, 0x7013, 0x0829, 0x2f10,
+	0x7222, 0x7027, 0xffff, 0x0005, 0x00d6, 0x0096, 0x0081, 0x7814,
+	0x2048, 0xa890, 0x7002, 0xa88c, 0x7006, 0xa8b0, 0x700a, 0xa8ac,
+	0x700e, 0x60c3, 0x000c, 0x009e, 0x00de, 0x0804, 0x95d9, 0x6813,
+	0x0008, 0xb810, 0x9085, 0x0500, 0x7002, 0xb814, 0x7006, 0x2069,
+	0x1800, 0x6878, 0x700a, 0x687c, 0x700e, 0x7013, 0x0889, 0x080c,
+	0x95c7, 0x721a, 0x7a08, 0x7222, 0x2f10, 0x7226, 0x2071, 0x024c,
+	0x0005, 0x00d6, 0x0096, 0x080c, 0x93f1, 0x7814, 0x2048, 0x080c,
+	0xbd39, 0x1130, 0x7814, 0x9084, 0x0700, 0x8007, 0x0033, 0x0010,
+	0x9006, 0x001b, 0x009e, 0x00de, 0x0005, 0x930f, 0x9378, 0x9388,
+	0x93ae, 0x93ba, 0x93cb, 0x93d3, 0x930d, 0x080c, 0x0e02, 0x0016,
+	0x0036, 0xa97c, 0x918c, 0x0003, 0x0118, 0x9186, 0x0003, 0x1198,
+	0xaba8, 0x7824, 0xd0cc, 0x1168, 0x7316, 0xa898, 0x701a, 0xa894,
+	0x701e, 0x003e, 0x001e, 0x2001, 0x198c, 0x2004, 0x60c2, 0x0804,
+	0x95d9, 0xc3e5, 0x0c88, 0x9186, 0x0001, 0x190c, 0x0e02, 0xaba8,
+	0x7824, 0xd0cc, 0x1904, 0x9375, 0x7316, 0xa898, 0x701a, 0xa894,
+	0x701e, 0xa8a4, 0x7026, 0xa8ac, 0x702e, 0x2009, 0x0018, 0x9384,
+	0x0300, 0x0570, 0xd3c4, 0x0110, 0xa8ac, 0x9108, 0xd3cc, 0x0110,
+	0xa8a4, 0x9108, 0x6810, 0x9085, 0x0010, 0x6812, 0x2011, 0x0258,
+	0x20e9, 0x0000, 0x22a0, 0x0156, 0x20a9, 0x0008, 0xa860, 0x20e0,
+	0xa85c, 0x9080, 0x002c, 0x2098, 0x4003, 0x6810, 0x8000, 0x6812,
+	0x2011, 0x0240, 0x22a0, 0x20a9, 0x0005, 0x4003, 0x6810, 0xc0a4,
+	0x6812, 0x015e, 0x9184, 0x0003, 0x0118, 0x2019, 0x0245, 0x201a,
+	0x61c2, 0x003e, 0x001e, 0x0804, 0x95d9, 0xc3e5, 0x0804, 0x9334,
+	0x2011, 0x0008, 0x2001, 0x180f, 0x2004, 0xd0a4, 0x0110, 0x2011,
+	0x0028, 0x7824, 0xd0cc, 0x1110, 0x7216, 0x0470, 0x0ce8, 0xc2e5,
+	0x2011, 0x0302, 0x0016, 0x782c, 0x701a, 0x7930, 0x711e, 0x9105,
+	0x0108, 0xc2dd, 0x001e, 0x7824, 0xd0cc, 0x0108, 0xc2e5, 0x7216,
+	0x7027, 0x0012, 0x702f, 0x0008, 0x7043, 0x7000, 0x7047, 0x0500,
+	0x704f, 0x000a, 0x2069, 0x0200, 0x6813, 0x0009, 0x2071, 0x0240,
+	0x700b, 0x2500, 0x60c3, 0x0032, 0x0804, 0x95d9, 0x2011, 0x0028,
+	0x7824, 0xd0cc, 0x1128, 0x7216, 0x60c3, 0x0018, 0x0804, 0x95d9,
+	0x0cd0, 0xc2e5, 0x2011, 0x0100, 0x7824, 0xd0cc, 0x0108, 0xc2e5,
+	0x7216, 0x702f, 0x0008, 0x7858, 0x9084, 0x00ff, 0x7036, 0x60c3,
+	0x0020, 0x0804, 0x95d9, 0x2011, 0x0008, 0x7824, 0xd0cc, 0x0108,
+	0xc2e5, 0x7216, 0x0c08, 0x0036, 0x7b14, 0x9384, 0xff00, 0x7816,
+	0x9384, 0x00ff, 0x8001, 0x1138, 0x7824, 0xd0cc, 0x0108, 0xc2e5,
+	0x7216, 0x003e, 0x0888, 0x0046, 0x2021, 0x0800, 0x0006, 0x7824,
+	0xd0cc, 0x000e, 0x0108, 0xc4e5, 0x7416, 0x004e, 0x701e, 0x003e,
+	0x0818, 0x00d6, 0x6813, 0x0008, 0xb810, 0x9085, 0x0700, 0x7002,
+	0xb814, 0x7006, 0x2069, 0x1800, 0x6878, 0x700a, 0x687c, 0x700e,
+	0x7824, 0xd0cc, 0x1168, 0x7013, 0x0898, 0x080c, 0x95c7, 0x721a,
+	0x7a08, 0x7222, 0x2f10, 0x7226, 0x2071, 0x024c, 0x00de, 0x0005,
+	0x7013, 0x0889, 0x0c90, 0x0016, 0x7814, 0x9084, 0x0700, 0x8007,
+	0x0013, 0x001e, 0x0005, 0x9423, 0x9423, 0x9425, 0x9423, 0x9423,
+	0x9423, 0x943f, 0x9423, 0x080c, 0x0e02, 0x7914, 0x918c, 0x08ff,
+	0x918d, 0xf600, 0x7916, 0x2009, 0x0003, 0x00b9, 0x2069, 0x185b,
+	0x6804, 0xd0bc, 0x0130, 0x682c, 0x9084, 0x00ff, 0x8007, 0x7032,
+	0x0010, 0x7033, 0x3f00, 0x60c3, 0x0001, 0x0804, 0x95d9, 0x2009,
+	0x0003, 0x0019, 0x7033, 0x7f00, 0x0cb0, 0x0016, 0x080c, 0x9ddd,
+	0x001e, 0xb810, 0x9085, 0x0100, 0x7002, 0xb814, 0x7006, 0x2069,
+	0x1800, 0x6a78, 0x720a, 0x6a7c, 0x720e, 0x7013, 0x0888, 0x918d,
+	0x0008, 0x7116, 0x080c, 0x95c7, 0x721a, 0x7a08, 0x7222, 0x2f10,
+	0x7226, 0x0005, 0x00b6, 0x0096, 0x00e6, 0x00d6, 0x00c6, 0x0056,
+	0x0046, 0x0036, 0x2061, 0x0100, 0x2071, 0x1800, 0x7810, 0x2058,
+	0xb8a0, 0x2028, 0xb910, 0xba14, 0x7378, 0x747c, 0x7820, 0x90be,
+	0x0006, 0x0904, 0x9536, 0x90be, 0x000a, 0x1904, 0x94f2, 0xb8b0,
+	0x609e, 0x7814, 0x2048, 0xa87c, 0xd0fc, 0x0558, 0xaf90, 0x9784,
+	0xff00, 0x9105, 0x6062, 0x873f, 0x9784, 0xff00, 0x0006, 0x7814,
+	0x2048, 0xa878, 0xc0fc, 0x9005, 0x000e, 0x1160, 0xaf94, 0x87ff,
+	0x0198, 0x2039, 0x0098, 0x9705, 0x6072, 0x7808, 0x6082, 0x2f00,
+	0x6086, 0x0038, 0x9185, 0x2200, 0x6062, 0x6073, 0x0129, 0x6077,
+	0x0000, 0xb8b0, 0x609e, 0x0050, 0x2039, 0x0029, 0x9705, 0x6072,
+	0x0cc0, 0x9185, 0x0200, 0x6062, 0x6073, 0x2029, 0xa87c, 0xd0fc,
+	0x0118, 0xaf94, 0x87ff, 0x1120, 0x2f00, 0x6082, 0x7808, 0x6086,
+	0x6266, 0x636a, 0x646e, 0x6077, 0x0000, 0xb88c, 0x8000, 0x9084,
+	0x00ff, 0xb88e, 0x8007, 0x607a, 0x607f, 0x0000, 0xa838, 0x608a,
+	0xa834, 0x608e, 0xa848, 0x60c6, 0xa844, 0x60ca, 0xb86c, 0x60ce,
+	0x60af, 0x95d5, 0x60d7, 0x0000, 0x080c, 0x9dc2, 0x2009, 0x07d0,
+	0x60c4, 0x9084, 0xfff0, 0x9005, 0x0110, 0x2009, 0x1b58, 0x080c,
+	0x82df, 0x003e, 0x004e, 0x005e, 0x00ce, 0x00de, 0x00ee, 0x009e,
+	0x00be, 0x0005, 0x7804, 0x9086, 0x0040, 0x0904, 0x9572, 0x9185,
+	0x0100, 0x6062, 0x6266, 0x636a, 0x646e, 0x6073, 0x0809, 0x6077,
+	0x0008, 0x60af, 0x95d5, 0x60d7, 0x0000, 0xb88c, 0x8000, 0x9084,
+	0x00ff, 0xb88e, 0x8007, 0x607a, 0x607f, 0x0000, 0x2f00, 0x6082,
+	0x7808, 0x6086, 0x7814, 0x2048, 0xa838, 0x608a, 0xa834, 0x608e,
+	0xa848, 0x60c6, 0xa844, 0x60ca, 0xb86c, 0x60ce, 0xbab0, 0x629e,
+	0x080c, 0x9dc2, 0x2009, 0x07d0, 0x60c4, 0x9084, 0xfff0, 0x9005,
+	0x0110, 0x2009, 0x1b58, 0x080c, 0x82df, 0x003e, 0x004e, 0x005e,
+	0x00ce, 0x00de, 0x00ee, 0x009e, 0x00be, 0x0005, 0x7814, 0x2048,
+	0xa87c, 0x9084, 0x0003, 0x9086, 0x0002, 0x0904, 0x958e, 0x9185,
+	0x0100, 0x6062, 0x6266, 0x636a, 0x646e, 0x6073, 0x0880, 0x6077,
+	0x0008, 0xb88c, 0x8000, 0x9084, 0x00ff, 0xb88e, 0x8007, 0x607a,
+	0x7838, 0x607e, 0x2f00, 0x6086, 0x7808, 0x6082, 0xa890, 0x608a,
+	0xa88c, 0x608e, 0xa8b0, 0x60c6, 0xa8ac, 0x60ca, 0xa8ac, 0x7930,
+	0x9108, 0x7932, 0xa8b0, 0x792c, 0x9109, 0x792e, 0xb86c, 0x60ce,
+	0x60af, 0x95d5, 0x60d7, 0x0000, 0xbab0, 0x629e, 0x080c, 0x9d9f,
+	0x0804, 0x9522, 0xb8bc, 0xd084, 0x0148, 0xb88c, 0x7814, 0x2048,
+	0xb88c, 0x784a, 0xa836, 0x2900, 0xa83a, 0xb046, 0x9185, 0x0600,
+	0x6062, 0x6266, 0x636a, 0x646e, 0x6073, 0x0829, 0x6077, 0x0000,
+	0x60af, 0x9575, 0x60d7, 0x0000, 0x0804, 0x9505, 0x9185, 0x0700,
+	0x6062, 0x6266, 0x636a, 0x646e, 0x7824, 0xd0cc, 0x7826, 0x0118,
+	0x6073, 0x0889, 0x0010, 0x6073, 0x0898, 0x6077, 0x0000, 0xb88c,
+	0x8000, 0x9084, 0x00ff, 0xb88e, 0x8007, 0x607a, 0x607f, 0x0000,
+	0x2f00, 0x6086, 0x7808, 0x6082, 0xa838, 0x608a, 0xa834, 0x608e,
+	0xa848, 0x60c6, 0xa844, 0x60ca, 0xb86c, 0x60ce, 0x60af, 0x95d5,
+	0x60d7, 0x0000, 0xbab0, 0x629e, 0x7824, 0xd0cc, 0x0120, 0x080c,
+	0x9dc2, 0x0804, 0x9522, 0x080c, 0x9d9f, 0x0804, 0x9522, 0x7a10,
+	0x00b6, 0x2258, 0xba8c, 0x8210, 0x9294, 0x00ff, 0xba8e, 0x00be,
+	0x8217, 0x0005, 0x00d6, 0x2069, 0x19c2, 0x6843, 0x0001, 0x00de,
+	0x0005, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x00f1, 0x080c, 0x82d1,
+	0x0005, 0x0016, 0x2001, 0x180c, 0x200c, 0x9184, 0x0600, 0x9086,
+	0x0600, 0x0128, 0x0089, 0x080c, 0x82d1, 0x001e, 0x0005, 0xc1e5,
+	0x2001, 0x180c, 0x2102, 0x2001, 0x19c3, 0x2003, 0x0000, 0x2001,
+	0x19cb, 0x2003, 0x0000, 0x0c88, 0x0006, 0x6014, 0x9084, 0x1804,
+	0x9085, 0x0009, 0x6016, 0x000e, 0x0005, 0x0016, 0x00c6, 0x0006,
+	0x2061, 0x0100, 0x61a4, 0x60a7, 0x95f5, 0x6014, 0x9084, 0x1804,
+	0x9085, 0x0008, 0x6016, 0x000e, 0xa001, 0xa001, 0xa001, 0x61a6,
+	0x00ce, 0x001e, 0x0005, 0x00c6, 0x00d6, 0x0016, 0x0026, 0x2061,
+	0x0100, 0x2069, 0x0140, 0x080c, 0x717f, 0x11c0, 0x2001, 0x19de,
+	0x2004, 0x9005, 0x15d0, 0x080c, 0x7247, 0x1160, 0x2061, 0x0100,
+	0x6020, 0xd0b4, 0x1120, 0x6024, 0xd084, 0x090c, 0x0e02, 0x080c,
+	0x82d1, 0x0458, 0x00c6, 0x2061, 0x19c2, 0x00c8, 0x6904, 0x9194,
+	0x4000, 0x0540, 0x0811, 0x080c, 0x2b98, 0x00c6, 0x2061, 0x19c2,
+	0x6128, 0x9192, 0x0008, 0x1258, 0x8108, 0x612a, 0x6124, 0x00ce,
+	0x81ff, 0x0198, 0x080c, 0x82d1, 0x080c, 0x95fc, 0x0070, 0x6124,
+	0x91e5, 0x0000, 0x0140, 0x080c, 0xdb8f, 0x080c, 0x82da, 0x2009,
+	0x0014, 0x080c, 0xa053, 0x00ce, 0x0000, 0x002e, 0x001e, 0x00de,
+	0x00ce, 0x0005, 0x2001, 0x19de, 0x2004, 0x9005, 0x1db0, 0x00c6,
+	0x2061, 0x19c2, 0x6128, 0x9192, 0x0003, 0x1e08, 0x8108, 0x612a,
+	0x00ce, 0x080c, 0x82d1, 0x080c, 0x5cef, 0x2009, 0x185a, 0x2114,
+	0x8210, 0x220a, 0x0c10, 0x0096, 0x00c6, 0x00d6, 0x00e6, 0x0016,
+	0x0026, 0x080c, 0x82e7, 0x2071, 0x19c2, 0x713c, 0x81ff, 0x0904,
+	0x96f5, 0x2061, 0x0100, 0x2069, 0x0140, 0x080c, 0x717f, 0x1190,
+	0x0036, 0x2019, 0x0002, 0x080c, 0x989c, 0x003e, 0x713c, 0x2160,
+	0x080c, 0xdb8f, 0x2009, 0x004a, 0x080c, 0xa053, 0x080c, 0x7247,
+	0x0804, 0x96f5, 0x6904, 0xd1f4, 0x0904, 0x96fc, 0x080c, 0x2b98,
+	0x00c6, 0x703c, 0x9065, 0x090c, 0x0e02, 0x6020, 0x00ce, 0x9086,
+	0x0006, 0x1568, 0x61c8, 0x60c4, 0x9105, 0x1548, 0x2009, 0x180c,
+	0x2104, 0xd0d4, 0x0520, 0x6214, 0x9294, 0x1800, 0x1128, 0x6224,
+	0x9294, 0x0002, 0x1550, 0x0070, 0xc0d4, 0x200a, 0x0006, 0x2001,
+	0x0100, 0x2004, 0x9086, 0x000a, 0x000e, 0x0120, 0xd0cc, 0x0110,
+	0x080c, 0x2aca, 0x6014, 0x9084, 0xe7fd, 0x9085, 0x0010, 0x6016,
+	0x703c, 0x2060, 0x2009, 0x0049, 0x080c, 0xa053, 0x0070, 0x0036,
+	0x2019, 0x0001, 0x080c, 0x989c, 0x003e, 0x713c, 0x2160, 0x080c,
+	0xdb8f, 0x2009, 0x004a, 0x080c, 0xa053, 0x002e, 0x001e, 0x00ee,
+	0x00de, 0x00ce, 0x009e, 0x0005, 0xd1ec, 0x1904, 0x96ae, 0x0804,
+	0x96b0, 0x0026, 0x00e6, 0x2071, 0x19c2, 0x7048, 0xd084, 0x01c0,
+	0x713c, 0x81ff, 0x01a8, 0x2071, 0x0100, 0x9188, 0x0008, 0x2114,
+	0x928e, 0x0006, 0x1138, 0x7014, 0x9084, 0x1984, 0x9085, 0x0012,
+	0x7016, 0x0030, 0x7014, 0x9084, 0x1984, 0x9085, 0x0016, 0x7016,
+	0x00ee, 0x002e, 0x0005, 0x00b6, 0x00e6, 0x00d6, 0x00c6, 0x0066,
+	0x0056, 0x0046, 0x0006, 0x0126, 0x2091, 0x8000, 0x6010, 0x2058,
+	0xbca0, 0x2071, 0x19c2, 0x7018, 0x2058, 0x8bff, 0x0190, 0xb8a0,
+	0x9406, 0x0118, 0xb854, 0x2058, 0x0cc0, 0x6014, 0x0096, 0x2048,
+	0xac6c, 0xad70, 0xae78, 0x009e, 0x080c, 0x64d6, 0x0110, 0x9085,
+	0x0001, 0x012e, 0x000e, 0x004e, 0x005e, 0x006e, 0x00ce, 0x00de,
+	0x00ee, 0x00be, 0x0005, 0x080c, 0x90d2, 0x7003, 0x1200, 0x7838,
+	0x7012, 0x783c, 0x7016, 0x00c6, 0x7820, 0x9086, 0x0004, 0x1148,
+	0x7810, 0x9005, 0x0130, 0x00b6, 0x2058, 0xb810, 0xb914, 0x00be,
+	0x0020, 0x2061, 0x1800, 0x6078, 0x617c, 0x9084, 0x00ff, 0x700a,
+	0x710e, 0x00ce, 0x60c3, 0x002c, 0x0804, 0x95d9, 0x080c, 0x90d2,
+	0x7003, 0x0f00, 0x7808, 0xd09c, 0x0128, 0xb810, 0x9084, 0x00ff,
+	0x700a, 0xb814, 0x700e, 0x60c3, 0x0008, 0x0804, 0x95d9, 0x0156,
+	0x080c, 0x911d, 0x7003, 0x0200, 0x2011, 0x1848, 0x63f0, 0x2312,
+	0x20a9, 0x0006, 0x2011, 0x1840, 0x2019, 0x1841, 0x9ef0, 0x0002,
+	0x2376, 0x8e70, 0x2276, 0x8e70, 0x9398, 0x0002, 0x9290, 0x0002,
+	0x1f04, 0x9798, 0x60c3, 0x001c, 0x015e, 0x0804, 0x95d9, 0x0016,
+	0x0026, 0x080c, 0x90f9, 0x080c, 0x910b, 0x9e80, 0x0004, 0x20e9,
+	0x0000, 0x20a0, 0x7814, 0x0096, 0x2048, 0xa800, 0x2048, 0xa860,
+	0x20e0, 0xa85c, 0x9080, 0x0021, 0x2098, 0x009e, 0x7808, 0x9088,
+	0x0002, 0x21a8, 0x9192, 0x0010, 0x1250, 0x4003, 0x9080, 0x0004,
+	0x8003, 0x60c2, 0x080c, 0x95d9, 0x002e, 0x001e, 0x0005, 0x20a9,
+	0x0010, 0x4003, 0x080c, 0x9dc8, 0x20a1, 0x0240, 0x22a8, 0x4003,
+	0x0c68, 0x080c, 0x90d2, 0x7003, 0x6200, 0x7808, 0x700e, 0x60c3,
+	0x0008, 0x0804, 0x95d9, 0x0016, 0x0026, 0x080c, 0x90d2, 0x20e9,
+	0x0000, 0x20a1, 0x024c, 0x7814, 0x0096, 0x2048, 0xa800, 0x2048,
+	0xa860, 0x20e0, 0xa85c, 0x9080, 0x0023, 0x2098, 0x009e, 0x7808,
+	0x9088, 0x0002, 0x21a8, 0x4003, 0x8003, 0x60c2, 0x080c, 0x95d9,
+	0x002e, 0x001e, 0x0005, 0x00e6, 0x00c6, 0x0006, 0x0126, 0x2091,
+	0x8000, 0x2071, 0x19c2, 0x700c, 0x2060, 0x8cff, 0x0178, 0x080c,
+	0xbf43, 0x1110, 0x080c, 0xa995, 0x600c, 0x0006, 0x080c, 0xc1af,
+	0x080c, 0x9fd5, 0x080c, 0x9940, 0x00ce, 0x0c78, 0x2c00, 0x700e,
+	0x700a, 0x012e, 0x000e, 0x00ce, 0x00ee, 0x0005, 0x0126, 0x0156,
+	0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0026, 0x0016, 0x0006,
+	0x2091, 0x8000, 0x2001, 0x180c, 0x200c, 0x918c, 0xe7ff, 0x2102,
+	0x2069, 0x0100, 0x2079, 0x0140, 0x2071, 0x19c2, 0x7024, 0x2060,
+	0x8cff, 0x01f8, 0x080c, 0x9605, 0x6ac0, 0x68c3, 0x0000, 0x080c,
+	0x82da, 0x00c6, 0x2061, 0x0100, 0x080c, 0x9de1, 0x00ce, 0x20a9,
+	0x01f4, 0x0461, 0x2009, 0x0013, 0x080c, 0xa053, 0x000e, 0x001e,
+	0x002e, 0x006e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x015e, 0x012e,
+	0x0005, 0x2001, 0x1800, 0x2004, 0x9096, 0x0001, 0x0d78, 0x9096,
+	0x0004, 0x0d60, 0x080c, 0x82da, 0x6814, 0x9084, 0x0001, 0x0110,
+	0x68a7, 0x95f5, 0x6817, 0x0008, 0x68c3, 0x0000, 0x2011, 0x5c99,
+	0x080c, 0x825a, 0x20a9, 0x01f4, 0x0009, 0x08c0, 0x6824, 0xd094,
+	0x0140, 0x6827, 0x0004, 0x7804, 0x9084, 0x4000, 0x190c, 0x2b98,
+	0x0090, 0xd084, 0x0118, 0x6827, 0x0001, 0x0010, 0x1f04, 0x987e,
+	0x7804, 0x9084, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2b88,
+	0x9006, 0x080c, 0x2b88, 0x0005, 0x0126, 0x0156, 0x00f6, 0x00e6,
+	0x00d6, 0x00c6, 0x0066, 0x0026, 0x0016, 0x0006, 0x2091, 0x8000,
+	0x2001, 0x180c, 0x200c, 0x918c, 0xdbff, 0x2102, 0x2069, 0x0100,
+	0x2079, 0x0140, 0x2071, 0x19c2, 0x703c, 0x2060, 0x8cff, 0x0904,
+	0x9903, 0x9386, 0x0002, 0x1128, 0x6814, 0x9084, 0x0002, 0x0904,
+	0x9903, 0x68af, 0x95f5, 0x6817, 0x0010, 0x2009, 0x00fa, 0x8109,
+	0x1df0, 0x69c6, 0x68cb, 0x0008, 0x080c, 0x82e7, 0x080c, 0x1e34,
+	0x2001, 0x0032, 0x6920, 0xd1bc, 0x0130, 0x8001, 0x1dd8, 0x692c,
+	0x918d, 0x0008, 0x692e, 0x20a9, 0x03e8, 0x6824, 0xd094, 0x0140,
+	0x6827, 0x0004, 0x7804, 0x9084, 0x4000, 0x190c, 0x2b98, 0x0090,
+	0xd08c, 0x0118, 0x6827, 0x0002, 0x0010, 0x1f04, 0x98dd, 0x7804,
+	0x9084, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2b88, 0x9006,
+	0x080c, 0x2b88, 0x6827, 0x4000, 0x6824, 0x83ff, 0x1120, 0x2009,
+	0x0049, 0x080c, 0xa053, 0x000e, 0x001e, 0x002e, 0x006e, 0x00ce,
+	0x00de, 0x00ee, 0x00fe, 0x015e, 0x012e, 0x0005, 0x00d6, 0x0126,
+	0x2091, 0x8000, 0x2069, 0x19c2, 0x6a06, 0x012e, 0x00de, 0x0005,
+	0x00d6, 0x0126, 0x2091, 0x8000, 0x2069, 0x19c2, 0x6a32, 0x012e,
+	0x00de, 0x0005, 0x080c, 0x9295, 0x7047, 0x1000, 0x0098, 0x080c,
+	0x9295, 0x7047, 0x4000, 0x0070, 0x080c, 0x9295, 0x7047, 0x2000,
+	0x0048, 0x080c, 0x9295, 0x7047, 0x0400, 0x0020, 0x080c, 0x9295,
+	0x7047, 0x0200, 0x7854, 0x7032, 0x60c3, 0x0020, 0x0804, 0x95d9,
+	0x00e6, 0x2071, 0x19c2, 0x7020, 0x9005, 0x0110, 0x8001, 0x7022,
+	0x00ee, 0x0005, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0076, 0x0066,
+	0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x19c2, 0x7614, 0x2660,
+	0x2678, 0x2039, 0x0001, 0x87ff, 0x0904, 0x99e5, 0x8cff, 0x0904,
+	0x99e5, 0x6020, 0x9086, 0x0006, 0x1904, 0x99e0, 0x88ff, 0x0138,
+	0x2800, 0x9c06, 0x1904, 0x99e0, 0x2039, 0x0000, 0x0050, 0x6010,
+	0x9b06, 0x1904, 0x99e0, 0x85ff, 0x0120, 0x6054, 0x9106, 0x1904,
+	0x99e0, 0x7024, 0x9c06, 0x15b0, 0x2069, 0x0100, 0x68c0, 0x9005,
+	0x1160, 0x6824, 0xd084, 0x0148, 0x6827, 0x0001, 0x080c, 0x82da,
+	0x080c, 0x9a6a, 0x7027, 0x0000, 0x0428, 0x080c, 0x82da, 0x6820,
+	0xd0b4, 0x0110, 0x68a7, 0x95f5, 0x6817, 0x0008, 0x68c3, 0x0000,
+	0x080c, 0x9a6a, 0x7027, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04,
+	0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2b88, 0x9006,
+	0x080c, 0x2b88, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827,
+	0x0001, 0x003e, 0x7014, 0x9c36, 0x1110, 0x660c, 0x7616, 0x7010,
+	0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x7012, 0x0010,
+	0x7013, 0x0000, 0x660c, 0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e,
+	0x0008, 0x2678, 0x89ff, 0x1168, 0x600f, 0x0000, 0x6014, 0x0096,
+	0x2048, 0x080c, 0xbd39, 0x0110, 0x080c, 0xd781, 0x009e, 0x080c,
+	0xa007, 0x080c, 0x9940, 0x88ff, 0x1190, 0x00ce, 0x0804, 0x995b,
+	0x2c78, 0x600c, 0x2060, 0x0804, 0x995b, 0x9006, 0x012e, 0x000e,
+	0x006e, 0x007e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x601b,
+	0x0000, 0x00ce, 0x98c5, 0x0001, 0x0c88, 0x00f6, 0x00e6, 0x00d6,
+	0x0096, 0x00c6, 0x0066, 0x0026, 0x0006, 0x0126, 0x2091, 0x8000,
+	0x2071, 0x19c2, 0x7638, 0x2660, 0x2678, 0x8cff, 0x0904, 0x9a59,
+	0x6020, 0x9086, 0x0006, 0x1904, 0x9a54, 0x87ff, 0x0128, 0x2700,
+	0x9c06, 0x1904, 0x9a54, 0x0040, 0x6010, 0x9b06, 0x15e8, 0x85ff,
+	0x0118, 0x6054, 0x9106, 0x15c0, 0x703c, 0x9c06, 0x1168, 0x0036,
+	0x2019, 0x0001, 0x080c, 0x989c, 0x7033, 0x0000, 0x9006, 0x703e,
+	0x7042, 0x7046, 0x704a, 0x003e, 0x7038, 0x9c36, 0x1110, 0x660c,
 	0x763a, 0x7034, 0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00,
-	0x7036, 0x0010, 0x7037, 0x0000, 0x660c, 0x2c00, 0x9f06, 0x0110,
-	0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0x6004, 0x9086, 0x0040,
-	0x090c, 0x8b04, 0x9085, 0x0001, 0x0020, 0x2c78, 0x600c, 0x2060,
-	0x08b0, 0x012e, 0x000e, 0x002e, 0x006e, 0x00ce, 0x00ee, 0x00fe,
-	0x0005, 0x0096, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0026,
-	0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x19bf, 0x760c, 0x2660,
-	0x2678, 0x8cff, 0x0904, 0x9c5e, 0x6010, 0x00b6, 0x2058, 0xb8a0,
-	0x00be, 0x9206, 0x1904, 0x9c59, 0x7024, 0x9c06, 0x1520, 0x2069,
-	0x0100, 0x68c0, 0x9005, 0x0904, 0x9c30, 0x080c, 0x9656, 0x68c3,
-	0x0000, 0x080c, 0x9b78, 0x7027, 0x0000, 0x0036, 0x2069, 0x0140,
-	0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2c88,
-	0x9006, 0x080c, 0x2c88, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110,
-	0x6827, 0x0001, 0x003e, 0x700c, 0x9c36, 0x1110, 0x660c, 0x760e,
-	0x7008, 0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x700a,
-	0x0010, 0x700b, 0x0000, 0x660c, 0x0066, 0x2c00, 0x9f06, 0x0110,
-	0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0x080c, 0xc02e, 0x1180,
-	0x080c, 0x31b4, 0x080c, 0xc03f, 0x1518, 0x080c, 0xaa81, 0x0400,
-	0x080c, 0x9b78, 0x6824, 0xd084, 0x09b0, 0x6827, 0x0001, 0x0898,
-	0x080c, 0xc03f, 0x1118, 0x080c, 0xaa81, 0x0090, 0x6014, 0x2048,
-	0x080c, 0xbe35, 0x0168, 0x6020, 0x9086, 0x0003, 0x1508, 0xa867,
-	0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0x6adc, 0x080c, 0xc022,
-	0x080c, 0xc2ab, 0x080c, 0xa113, 0x080c, 0x9a4e, 0x00ce, 0x0804,
-	0x9bd9, 0x2c78, 0x600c, 0x2060, 0x0804, 0x9bd9, 0x012e, 0x000e,
-	0x002e, 0x006e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x009e, 0x0005,
-	0x6020, 0x9086, 0x0006, 0x1d20, 0x080c, 0xd830, 0x0c08, 0x00d6,
-	0x080c, 0x9179, 0x7003, 0x0200, 0x7007, 0x0014, 0x60c3, 0x0014,
-	0x20e1, 0x0001, 0x2099, 0x1961, 0x20e9, 0x0000, 0x20a1, 0x0250,
-	0x20a9, 0x0004, 0x4003, 0x7023, 0x0004, 0x7027, 0x7878, 0x080c,
-	0x962a, 0x00de, 0x0005, 0x080c, 0x9179, 0x700b, 0x0800, 0x7814,
-	0x9084, 0xff00, 0x700e, 0x7814, 0x9084, 0x00ff, 0x7022, 0x782c,
-	0x7026, 0x7858, 0x9084, 0x00ff, 0x9085, 0x0200, 0x7002, 0x7858,
-	0x9084, 0xff00, 0x8007, 0x7006, 0x60c2, 0x0804, 0x962a, 0x00b6,
-	0x00d6, 0x0016, 0x00d6, 0x2f68, 0x2009, 0x0035, 0x080c, 0xc4b1,
-	0x00de, 0x1904, 0x9d0c, 0x080c, 0x912e, 0x7003, 0x1300, 0x782c,
-	0x080c, 0x9e12, 0x2068, 0x6820, 0x9086, 0x0003, 0x0560, 0x7810,
-	0x2058, 0xbaa0, 0x080c, 0xa062, 0x11d8, 0x9286, 0x007e, 0x1128,
-	0x700b, 0x00ff, 0x700f, 0xfffe, 0x0498, 0x9286, 0x007f, 0x1128,
-	0x700b, 0x00ff, 0x700f, 0xfffd, 0x0458, 0x9284, 0xff80, 0x0180,
-	0x9286, 0x0080, 0x1128, 0x700b, 0x00ff, 0x700f, 0xfffc, 0x0400,
-	0x92d8, 0x1000, 0x2b5c, 0xb810, 0x700a, 0xb814, 0x700e, 0x00c0,
-	0x6098, 0x700e, 0x00a8, 0x080c, 0xa062, 0x1130, 0x7810, 0x2058,
-	0xb8a0, 0x9082, 0x007e, 0x0250, 0x00d6, 0x2069, 0x181e, 0x2d04,
-	0x700a, 0x8d68, 0x2d04, 0x700e, 0x00de, 0x0010, 0x6034, 0x700e,
-	0x7838, 0x7012, 0x783c, 0x7016, 0x60c3, 0x000c, 0x001e, 0x00de,
-	0x080c, 0x962a, 0x00be, 0x0005, 0x781b, 0x0001, 0x7803, 0x0006,
-	0x001e, 0x00de, 0x00be, 0x0005, 0x792c, 0x9180, 0x0008, 0x200c,
-	0x9186, 0x0006, 0x01c0, 0x9186, 0x0003, 0x0904, 0x9d87, 0x9186,
-	0x0005, 0x0904, 0x9d6f, 0x9186, 0x0004, 0x05d8, 0x9186, 0x0008,
-	0x0904, 0x9d78, 0x7807, 0x0037, 0x782f, 0x0003, 0x7817, 0x1700,
-	0x080c, 0x9def, 0x0005, 0x080c, 0x9db0, 0x00d6, 0x0026, 0x792c,
-	0x2168, 0x2009, 0x4000, 0x6800, 0x0002, 0x9d50, 0x9d5b, 0x9d52,
-	0x9d5b, 0x9d57, 0x9d50, 0x9d50, 0x9d5b, 0x9d5b, 0x9d5b, 0x9d5b,
-	0x9d50, 0x9d50, 0x9d50, 0x9d50, 0x9d50, 0x9d5b, 0x9d50, 0x9d5b,
-	0x080c, 0x0dfa, 0x6824, 0xd0e4, 0x0110, 0xd0cc, 0x0110, 0x900e,
-	0x0010, 0x2009, 0x2000, 0x682c, 0x7022, 0x6830, 0x7026, 0x0804,
-	0x9da9, 0x080c, 0x9db0, 0x00d6, 0x0026, 0x792c, 0x2168, 0x2009,
-	0x4000, 0x6a00, 0x9286, 0x0002, 0x1108, 0x900e, 0x04d0, 0x080c,
-	0x9db0, 0x00d6, 0x0026, 0x792c, 0x2168, 0x2009, 0x4000, 0x0488,
-	0x04b9, 0x00d6, 0x0026, 0x792c, 0x2168, 0x2009, 0x4000, 0x9286,
-	0x0005, 0x0118, 0x9286, 0x0002, 0x1108, 0x900e, 0x0410, 0x0441,
-	0x00d6, 0x0026, 0x792c, 0x2168, 0x6814, 0x6924, 0xc185, 0x6926,
-	0x0096, 0x2048, 0xa9ac, 0xa834, 0x9112, 0xa9b0, 0xa838, 0x009e,
-	0x9103, 0x7022, 0x7226, 0x792c, 0x9180, 0x0000, 0x2004, 0x908e,
-	0x0002, 0x0130, 0x908e, 0x0004, 0x0118, 0x2009, 0x4000, 0x0008,
-	0x900e, 0x712a, 0x60c3, 0x0018, 0x002e, 0x00de, 0x0804, 0x962a,
-	0x00b6, 0x0036, 0x0046, 0x0056, 0x0066, 0x080c, 0x9179, 0x9006,
-	0x7003, 0x0200, 0x7938, 0x710a, 0x793c, 0x710e, 0x7810, 0x2058,
-	0xb8a0, 0x080c, 0xa062, 0x1118, 0x9092, 0x007e, 0x0268, 0x00d6,
-	0x2069, 0x181e, 0x2d2c, 0x8d68, 0x2d34, 0x90d8, 0x1000, 0x2b5c,
-	0xbb10, 0xbc14, 0x00de, 0x0028, 0x901e, 0x6498, 0x2029, 0x0000,
-	0x6634, 0x782c, 0x9080, 0x0008, 0x2004, 0x9086, 0x0003, 0x1128,
-	0x7512, 0x7616, 0x731a, 0x741e, 0x0020, 0x7312, 0x7416, 0x751a,
-	0x761e, 0x006e, 0x005e, 0x004e, 0x003e, 0x00be, 0x0005, 0x080c,
-	0x9179, 0x7003, 0x0100, 0x782c, 0x700a, 0x7814, 0x700e, 0x700e,
-	0x60c3, 0x0008, 0x0804, 0x962a, 0x080c, 0x9125, 0x7003, 0x1400,
-	0x7838, 0x700a, 0x0079, 0x783c, 0x700e, 0x782c, 0x7012, 0x7830,
-	0x7016, 0x7834, 0x9084, 0x00ff, 0x8007, 0x701a, 0x60c3, 0x0010,
-	0x0804, 0x962a, 0x00e6, 0x2071, 0x0240, 0x0006, 0x00f6, 0x2078,
-	0x7810, 0x00b6, 0x2058, 0xb8bc, 0xd084, 0x0120, 0x7844, 0x702a,
-	0x7848, 0x702e, 0x00be, 0x00fe, 0x000e, 0x00ee, 0x0005, 0x080c,
-	0x9170, 0x7003, 0x0100, 0x782c, 0x700a, 0x7814, 0x700e, 0x60c3,
-	0x0008, 0x0804, 0x962a, 0x0021, 0x60c3, 0x0000, 0x0804, 0x962a,
-	0x00d6, 0x080c, 0x9eeb, 0xb810, 0x9085, 0x0300, 0x7002, 0xb814,
-	0x7006, 0x2069, 0x1800, 0x6878, 0x700a, 0x687c, 0x700e, 0x7013,
-	0x0819, 0x080c, 0x9618, 0x721a, 0x2f10, 0x7222, 0x7a08, 0x7226,
-	0x2071, 0x024c, 0x00de, 0x0005, 0x00a9, 0x7914, 0x712a, 0x60c3,
-	0x0000, 0x60a7, 0x9575, 0x0026, 0x080c, 0x2afe, 0x0228, 0x2011,
-	0x0101, 0x2204, 0xc0c5, 0x2012, 0x002e, 0x080c, 0x964d, 0x080c,
-	0x8351, 0x0005, 0x0036, 0x0096, 0x00d6, 0x00e6, 0x7858, 0x2048,
-	0xaa7c, 0x9296, 0x00c0, 0x9294, 0xfffd, 0xaa7e, 0xaa80, 0x9294,
-	0x0300, 0xaa82, 0xa96c, 0x9194, 0x00ff, 0xab74, 0x9384, 0x00ff,
-	0x908d, 0xc200, 0xa96e, 0x9384, 0xff00, 0x9215, 0xaa76, 0xa870,
-	0xaa78, 0xa87a, 0xaa72, 0x00d6, 0x2069, 0x0200, 0x080c, 0x9eeb,
-	0x00de, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9, 0x000a, 0xa860,
-	0x20e0, 0xa85c, 0x9080, 0x001b, 0x2098, 0x4003, 0x60a3, 0x0035,
-	0xaa68, 0x9294, 0x7000, 0x9286, 0x3000, 0x0110, 0x60a3, 0x0037,
-	0x00ee, 0x00de, 0x009e, 0x003e, 0x0005, 0x900e, 0x7814, 0x0096,
-	0x2048, 0xa87c, 0xd0fc, 0x01c0, 0x9084, 0x0003, 0x11a8, 0x2001,
-	0x180c, 0x2004, 0xd0bc, 0x0180, 0x7824, 0xd0cc, 0x1168, 0xd0c4,
-	0x1158, 0xa8a8, 0x9005, 0x1140, 0x2001, 0x180c, 0x200c, 0xc1d5,
-	0x2102, 0x2009, 0x198a, 0x210c, 0x009e, 0x918d, 0x0092, 0x0010,
-	0x2009, 0x0096, 0x60ab, 0x0036, 0x6116, 0x0005, 0x2009, 0x0009,
-	0x00a0, 0x2009, 0x000a, 0x0088, 0x2009, 0x000b, 0x0070, 0x2009,
-	0x000c, 0x0058, 0x2009, 0x000d, 0x0040, 0x2009, 0x000e, 0x0028,
-	0x2009, 0x000f, 0x0010, 0x2009, 0x0008, 0x6912, 0x0005, 0x00d6,
-	0x9290, 0x0018, 0x8214, 0x20e9, 0x0000, 0x2069, 0x0200, 0x6813,
-	0x0000, 0x22a8, 0x9284, 0x00e0, 0x0128, 0x20a9, 0x0020, 0x9292,
-	0x0020, 0x0008, 0x9016, 0x20a1, 0x0240, 0x9006, 0x4004, 0x82ff,
-	0x0120, 0x6810, 0x8000, 0x6812, 0x0c60, 0x00de, 0x0005, 0x00d6,
-	0x0096, 0x6014, 0x2048, 0xa878, 0x6056, 0x9006, 0xa836, 0xa83a,
-	0xa99c, 0xa946, 0xa84a, 0x6023, 0x0003, 0x6007, 0x0040, 0x6003,
-	0x0003, 0x600b, 0xffff, 0xa817, 0x0001, 0xa842, 0xa83e, 0x2900,
-	0xa85a, 0xa813, 0x1fc6, 0x080c, 0x86de, 0x0126, 0x2091, 0x8000,
-	0x080c, 0x8ced, 0x012e, 0x009e, 0x00de, 0x0005, 0x00f6, 0x00e6,
-	0x00d6, 0x00c6, 0x00a6, 0x0096, 0x0066, 0x0126, 0x2091, 0x8000,
-	0x2071, 0x19bf, 0x760c, 0x2660, 0x2678, 0x8cff, 0x0904, 0x9fc2,
-	0x7024, 0x9c06, 0x1520, 0x2069, 0x0100, 0x68c0, 0x9005, 0x0904,
-	0x9f94, 0x080c, 0x9656, 0x68c3, 0x0000, 0x080c, 0x9b78, 0x7027,
-	0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138,
-	0x2001, 0x0100, 0x080c, 0x2c88, 0x9006, 0x080c, 0x2c88, 0x2069,
-	0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x700c,
-	0x9c36, 0x1110, 0x660c, 0x760e, 0x7008, 0x9c36, 0x1140, 0x2c00,
-	0x9f36, 0x0118, 0x2f00, 0x700a, 0x0010, 0x700b, 0x0000, 0x660c,
-	0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f,
-	0x0000, 0x080c, 0xc02e, 0x1180, 0x080c, 0x31b4, 0x080c, 0xc03f,
-	0x1518, 0x080c, 0xaa81, 0x0400, 0x080c, 0x9b78, 0x6824, 0xd084,
-	0x09b0, 0x6827, 0x0001, 0x0898, 0x080c, 0xc03f, 0x1118, 0x080c,
-	0xaa81, 0x0090, 0x6014, 0x2048, 0x080c, 0xbe35, 0x0168, 0x6020,
-	0x9086, 0x0003, 0x1520, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000,
-	0x080c, 0x6ae9, 0x080c, 0xc022, 0x080c, 0xc2ab, 0x080c, 0xa113,
-	0x080c, 0x9a4e, 0x00ce, 0x0804, 0x9f45, 0x2c78, 0x600c, 0x2060,
-	0x0804, 0x9f45, 0x700f, 0x0000, 0x700b, 0x0000, 0x012e, 0x006e,
-	0x009e, 0x00ae, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x6020,
-	0x9086, 0x0006, 0x1d08, 0x080c, 0xd830, 0x08f0, 0x00d6, 0x0156,
-	0x080c, 0x9179, 0x7a14, 0x82ff, 0x0138, 0x7003, 0x0100, 0x700b,
-	0x0003, 0x60c3, 0x0008, 0x0490, 0x7003, 0x0200, 0x7007, 0x0000,
-	0x2069, 0x1800, 0x901e, 0x6800, 0x9086, 0x0004, 0x1110, 0xc38d,
-	0x0060, 0x080c, 0x7207, 0x1110, 0xc3ad, 0x0008, 0xc3a5, 0x6ad8,
-	0xd29c, 0x1110, 0xd2ac, 0x0108, 0xc39d, 0x730e, 0x2011, 0x1848,
-	0x63f0, 0x2312, 0x20a9, 0x0006, 0x2011, 0x1840, 0x2019, 0x1841,
-	0x2071, 0x0250, 0x2376, 0x8e70, 0x2276, 0x8e70, 0x9398, 0x0002,
-	0x9290, 0x0002, 0x1f04, 0xa00a, 0x60c3, 0x0020, 0x080c, 0x962a,
-	0x015e, 0x00de, 0x0005, 0x0156, 0x080c, 0x9179, 0x7a14, 0x82ff,
-	0x0168, 0x9286, 0xffff, 0x0118, 0x9282, 0x000e, 0x1238, 0x7003,
-	0x0100, 0x700b, 0x0003, 0x60c3, 0x0008, 0x0488, 0x7003, 0x0200,
-	0x7007, 0x001c, 0x700f, 0x0001, 0x2011, 0x1995, 0x2204, 0x8007,
-	0x701a, 0x8210, 0x2204, 0x8007, 0x701e, 0x0421, 0x1120, 0xb8a0,
-	0x9082, 0x007f, 0x0248, 0x2001, 0x181e, 0x2004, 0x7022, 0x2001,
-	0x181f, 0x2004, 0x7026, 0x0030, 0x2001, 0x1817, 0x2004, 0x9084,
-	0x00ff, 0x7026, 0x20a9, 0x0004, 0x20e1, 0x0001, 0x2099, 0x1805,
-	0x20e9, 0x0000, 0x20a1, 0x0256, 0x4003, 0x60c3, 0x001c, 0x015e,
-	0x0804, 0x962a, 0x0006, 0x2001, 0x1836, 0x2004, 0xd0ac, 0x000e,
-	0x0005, 0x2011, 0x0003, 0x080c, 0x9a0f, 0x2011, 0x0002, 0x080c,
-	0x9a19, 0x080c, 0x9927, 0x0036, 0x901e, 0x080c, 0x999d, 0x003e,
-	0x0005, 0x2071, 0x188b, 0x7000, 0x9005, 0x0140, 0x2001, 0x0976,
-	0x2071, 0x1800, 0x7072, 0x7076, 0x7067, 0xffe0, 0x2071, 0x1800,
-	0x7070, 0x7052, 0x7057, 0x1cd0, 0x0005, 0x00e6, 0x0126, 0x2071,
-	0x1800, 0x2091, 0x8000, 0x7550, 0x9582, 0x0010, 0x0608, 0x7054,
-	0x2060, 0x6000, 0x9086, 0x0000, 0x0148, 0x9ce0, 0x0018, 0x7064,
-	0x9c02, 0x1208, 0x0cb0, 0x2061, 0x1cd0, 0x0c98, 0x6003, 0x0008,
-	0x8529, 0x7552, 0x9ca8, 0x0018, 0x7064, 0x9502, 0x1230, 0x7556,
-	0x9085, 0x0001, 0x012e, 0x00ee, 0x0005, 0x7057, 0x1cd0, 0x0cc0,
-	0x9006, 0x0cc0, 0x00e6, 0x2071, 0x1800, 0x7550, 0x9582, 0x0010,
-	0x0600, 0x7054, 0x2060, 0x6000, 0x9086, 0x0000, 0x0148, 0x9ce0,
+	0x7036, 0x0010, 0x7037, 0x0000, 0x660c, 0x0066, 0x2c00, 0x9f06,
+	0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0x6014, 0x2048,
+	0x080c, 0xbd39, 0x0110, 0x080c, 0xd781, 0x080c, 0xa007, 0x87ff,
+	0x1198, 0x00ce, 0x0804, 0x9a05, 0x2c78, 0x600c, 0x2060, 0x0804,
+	0x9a05, 0x9006, 0x012e, 0x000e, 0x002e, 0x006e, 0x00ce, 0x009e,
+	0x00de, 0x00ee, 0x00fe, 0x0005, 0x601b, 0x0000, 0x00ce, 0x97bd,
+	0x0001, 0x0c80, 0x00e6, 0x2071, 0x19c2, 0x2001, 0x1800, 0x2004,
+	0x9086, 0x0002, 0x1118, 0x7007, 0x0005, 0x0010, 0x7007, 0x0000,
+	0x00ee, 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x0066, 0x0026, 0x0006,
+	0x0126, 0x2091, 0x8000, 0x2071, 0x19c2, 0x2c10, 0x7638, 0x2660,
+	0x2678, 0x8cff, 0x0540, 0x2200, 0x9c06, 0x1508, 0x7038, 0x9c36,
+	0x1110, 0x660c, 0x763a, 0x7034, 0x9c36, 0x1140, 0x2c00, 0x9f36,
+	0x0118, 0x2f00, 0x7036, 0x0010, 0x7037, 0x0000, 0x660c, 0x2c00,
+	0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0x6004,
+	0x9086, 0x0040, 0x090c, 0x8a84, 0x9085, 0x0001, 0x0020, 0x2c78,
+	0x600c, 0x2060, 0x08b0, 0x012e, 0x000e, 0x002e, 0x006e, 0x00ce,
+	0x00ee, 0x00fe, 0x0005, 0x0096, 0x00f6, 0x00e6, 0x00d6, 0x00c6,
+	0x0066, 0x0026, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0x19c2,
+	0x760c, 0x2660, 0x2678, 0x8cff, 0x0904, 0x9b50, 0x6010, 0x00b6,
+	0x2058, 0xb8a0, 0x00be, 0x9206, 0x1904, 0x9b4b, 0x7024, 0x9c06,
+	0x1520, 0x2069, 0x0100, 0x68c0, 0x9005, 0x0904, 0x9b22, 0x080c,
+	0x9605, 0x68c3, 0x0000, 0x080c, 0x9a6a, 0x7027, 0x0000, 0x0036,
+	0x2069, 0x0140, 0x6b04, 0x9384, 0x1000, 0x0138, 0x2001, 0x0100,
+	0x080c, 0x2b88, 0x9006, 0x080c, 0x2b88, 0x2069, 0x0100, 0x6824,
+	0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x700c, 0x9c36, 0x1110,
+	0x660c, 0x760e, 0x7008, 0x9c36, 0x1140, 0x2c00, 0x9f36, 0x0118,
+	0x2f00, 0x700a, 0x0010, 0x700b, 0x0000, 0x660c, 0x0066, 0x2c00,
+	0x9f06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0x080c,
+	0xbf32, 0x1180, 0x080c, 0x30d4, 0x080c, 0xbf43, 0x1518, 0x080c,
+	0xa995, 0x0400, 0x080c, 0x9a6a, 0x6824, 0xd084, 0x09b0, 0x6827,
+	0x0001, 0x0898, 0x080c, 0xbf43, 0x1118, 0x080c, 0xa995, 0x0090,
+	0x6014, 0x2048, 0x080c, 0xbd39, 0x0168, 0x6020, 0x9086, 0x0003,
+	0x1508, 0xa867, 0x0103, 0xab7a, 0xa877, 0x0000, 0x080c, 0x6a16,
+	0x080c, 0xbf26, 0x080c, 0xc1af, 0x080c, 0xa007, 0x080c, 0x9940,
+	0x00ce, 0x0804, 0x9acb, 0x2c78, 0x600c, 0x2060, 0x0804, 0x9acb,
+	0x012e, 0x000e, 0x002e, 0x006e, 0x00ce, 0x00de, 0x00ee, 0x00fe,
+	0x009e, 0x0005, 0x6020, 0x9086, 0x0006, 0x1d20, 0x080c, 0xd781,
+	0x0c08, 0x00d6, 0x080c, 0x911d, 0x7003, 0x0200, 0x7007, 0x0014,
+	0x60c3, 0x0014, 0x20e1, 0x0001, 0x2099, 0x1963, 0x20e9, 0x0000,
+	0x20a1, 0x0250, 0x20a9, 0x0004, 0x4003, 0x7023, 0x0004, 0x7027,
+	0x7878, 0x080c, 0x95d9, 0x00de, 0x0005, 0x080c, 0x911d, 0x700b,
+	0x0800, 0x7814, 0x9084, 0xff00, 0x700e, 0x7814, 0x9084, 0x00ff,
+	0x7022, 0x782c, 0x7026, 0x7858, 0x9084, 0x00ff, 0x9085, 0x0200,
+	0x7002, 0x7858, 0x9084, 0xff00, 0x8007, 0x7006, 0x60c2, 0x0804,
+	0x95d9, 0x00b6, 0x00d6, 0x0016, 0x00d6, 0x2f68, 0x2009, 0x0035,
+	0x080c, 0xc3bc, 0x00de, 0x1904, 0x9bfe, 0x080c, 0x90d2, 0x7003,
+	0x1300, 0x782c, 0x080c, 0x9d04, 0x2068, 0x6820, 0x9086, 0x0003,
+	0x0560, 0x7810, 0x2058, 0xbaa0, 0x080c, 0x9f54, 0x11d8, 0x9286,
+	0x007e, 0x1128, 0x700b, 0x00ff, 0x700f, 0xfffe, 0x0498, 0x9286,
+	0x007f, 0x1128, 0x700b, 0x00ff, 0x700f, 0xfffd, 0x0458, 0x9284,
+	0xff80, 0x0180, 0x9286, 0x0080, 0x1128, 0x700b, 0x00ff, 0x700f,
+	0xfffc, 0x0400, 0x92d8, 0x1000, 0x2b5c, 0xb810, 0x700a, 0xb814,
+	0x700e, 0x00c0, 0x6098, 0x700e, 0x00a8, 0x080c, 0x9f54, 0x1130,
+	0x7810, 0x2058, 0xb8a0, 0x9082, 0x007e, 0x0250, 0x00d6, 0x2069,
+	0x181e, 0x2d04, 0x700a, 0x8d68, 0x2d04, 0x700e, 0x00de, 0x0010,
+	0x6034, 0x700e, 0x7838, 0x7012, 0x783c, 0x7016, 0x60c3, 0x000c,
+	0x001e, 0x00de, 0x080c, 0x95d9, 0x00be, 0x0005, 0x781b, 0x0001,
+	0x7803, 0x0006, 0x001e, 0x00de, 0x00be, 0x0005, 0x792c, 0x9180,
+	0x0008, 0x200c, 0x9186, 0x0006, 0x01c0, 0x9186, 0x0003, 0x0904,
+	0x9c79, 0x9186, 0x0005, 0x0904, 0x9c61, 0x9186, 0x0004, 0x05d8,
+	0x9186, 0x0008, 0x0904, 0x9c6a, 0x7807, 0x0037, 0x782f, 0x0003,
+	0x7817, 0x1700, 0x080c, 0x9ce1, 0x0005, 0x080c, 0x9ca2, 0x00d6,
+	0x0026, 0x792c, 0x2168, 0x2009, 0x4000, 0x6800, 0x0002, 0x9c42,
+	0x9c4d, 0x9c44, 0x9c4d, 0x9c49, 0x9c42, 0x9c42, 0x9c4d, 0x9c4d,
+	0x9c4d, 0x9c4d, 0x9c42, 0x9c42, 0x9c42, 0x9c42, 0x9c42, 0x9c4d,
+	0x9c42, 0x9c4d, 0x080c, 0x0e02, 0x6824, 0xd0e4, 0x0110, 0xd0cc,
+	0x0110, 0x900e, 0x0010, 0x2009, 0x2000, 0x682c, 0x7022, 0x6830,
+	0x7026, 0x0804, 0x9c9b, 0x080c, 0x9ca2, 0x00d6, 0x0026, 0x792c,
+	0x2168, 0x2009, 0x4000, 0x6a00, 0x9286, 0x0002, 0x1108, 0x900e,
+	0x04d0, 0x080c, 0x9ca2, 0x00d6, 0x0026, 0x792c, 0x2168, 0x2009,
+	0x4000, 0x0488, 0x04b9, 0x00d6, 0x0026, 0x792c, 0x2168, 0x2009,
+	0x4000, 0x9286, 0x0005, 0x0118, 0x9286, 0x0002, 0x1108, 0x900e,
+	0x0410, 0x0441, 0x00d6, 0x0026, 0x792c, 0x2168, 0x6814, 0x6924,
+	0xc185, 0x6926, 0x0096, 0x2048, 0xa9ac, 0xa834, 0x9112, 0xa9b0,
+	0xa838, 0x009e, 0x9103, 0x7022, 0x7226, 0x792c, 0x9180, 0x0000,
+	0x2004, 0x908e, 0x0002, 0x0130, 0x908e, 0x0004, 0x0118, 0x2009,
+	0x4000, 0x0008, 0x900e, 0x712a, 0x60c3, 0x0018, 0x002e, 0x00de,
+	0x0804, 0x95d9, 0x00b6, 0x0036, 0x0046, 0x0056, 0x0066, 0x080c,
+	0x911d, 0x9006, 0x7003, 0x0200, 0x7938, 0x710a, 0x793c, 0x710e,
+	0x7810, 0x2058, 0xb8a0, 0x080c, 0x9f54, 0x1118, 0x9092, 0x007e,
+	0x0268, 0x00d6, 0x2069, 0x181e, 0x2d2c, 0x8d68, 0x2d34, 0x90d8,
+	0x1000, 0x2b5c, 0xbb10, 0xbc14, 0x00de, 0x0028, 0x901e, 0x6498,
+	0x2029, 0x0000, 0x6634, 0x782c, 0x9080, 0x0008, 0x2004, 0x9086,
+	0x0003, 0x1128, 0x7512, 0x7616, 0x731a, 0x741e, 0x0020, 0x7312,
+	0x7416, 0x751a, 0x761e, 0x006e, 0x005e, 0x004e, 0x003e, 0x00be,
+	0x0005, 0x080c, 0x911d, 0x7003, 0x0100, 0x782c, 0x700a, 0x7814,
+	0x700e, 0x700e, 0x60c3, 0x0008, 0x0804, 0x95d9, 0x080c, 0x90c9,
+	0x7003, 0x1400, 0x7838, 0x700a, 0x0079, 0x783c, 0x700e, 0x782c,
+	0x7012, 0x7830, 0x7016, 0x7834, 0x9084, 0x00ff, 0x8007, 0x701a,
+	0x60c3, 0x0010, 0x0804, 0x95d9, 0x00e6, 0x2071, 0x0240, 0x0006,
+	0x00f6, 0x2078, 0x7810, 0x00b6, 0x2058, 0xb8bc, 0xd084, 0x0120,
+	0x7844, 0x702a, 0x7848, 0x702e, 0x00be, 0x00fe, 0x000e, 0x00ee,
+	0x0005, 0x080c, 0x9114, 0x7003, 0x0100, 0x782c, 0x700a, 0x7814,
+	0x700e, 0x60c3, 0x0008, 0x0804, 0x95d9, 0x0021, 0x60c3, 0x0000,
+	0x0804, 0x95d9, 0x00d6, 0x080c, 0x9ddd, 0xb810, 0x9085, 0x0300,
+	0x7002, 0xb814, 0x7006, 0x2069, 0x1800, 0x6878, 0x700a, 0x687c,
+	0x700e, 0x7013, 0x0819, 0x080c, 0x95c7, 0x721a, 0x2f10, 0x7222,
+	0x7a08, 0x7226, 0x2071, 0x024c, 0x00de, 0x0005, 0x00a9, 0x7914,
+	0x712a, 0x60c3, 0x0000, 0x60a7, 0x9575, 0x0026, 0x080c, 0x29fe,
+	0x0228, 0x2011, 0x0101, 0x2204, 0xc0c5, 0x2012, 0x002e, 0x080c,
+	0x95fc, 0x080c, 0x82d1, 0x0005, 0x0036, 0x0096, 0x00d6, 0x00e6,
+	0x7858, 0x2048, 0xaa7c, 0x9296, 0x00c0, 0x9294, 0x00fd, 0xaa7e,
+	0xaa80, 0x9294, 0x0300, 0xaa82, 0xa96c, 0x9194, 0x00ff, 0xab74,
+	0x9384, 0x00ff, 0x908d, 0xc200, 0xa96e, 0x9384, 0xff00, 0x9215,
+	0xaa76, 0xa870, 0xaa78, 0xa87a, 0xaa72, 0x00d6, 0x2069, 0x0200,
+	0x080c, 0x9ddd, 0x00de, 0x20e9, 0x0000, 0x20a1, 0x0240, 0x20a9,
+	0x000a, 0xa860, 0x20e0, 0xa85c, 0x9080, 0x001b, 0x2098, 0x4003,
+	0x60a3, 0x0035, 0xaa68, 0x9294, 0x7000, 0x9286, 0x3000, 0x0110,
+	0x60a3, 0x0037, 0x00ee, 0x00de, 0x009e, 0x003e, 0x0005, 0x900e,
+	0x7814, 0x0096, 0x2048, 0xa87c, 0xd0fc, 0x01c0, 0x9084, 0x0003,
+	0x11a8, 0x2001, 0x180c, 0x2004, 0xd0bc, 0x0180, 0x7824, 0xd0cc,
+	0x1168, 0xd0c4, 0x1158, 0xa8a8, 0x9005, 0x1140, 0x2001, 0x180c,
+	0x200c, 0xc1d5, 0x2102, 0x2009, 0x198d, 0x210c, 0x009e, 0x918d,
+	0x0092, 0x0010, 0x2009, 0x0096, 0x60ab, 0x0036, 0x6116, 0x0005,
+	0x2009, 0x0009, 0x00a0, 0x2009, 0x000a, 0x0088, 0x2009, 0x000b,
+	0x0070, 0x2009, 0x000c, 0x0058, 0x2009, 0x000d, 0x0040, 0x2009,
+	0x000e, 0x0028, 0x2009, 0x000f, 0x0010, 0x2009, 0x0008, 0x6912,
+	0x0005, 0x00d6, 0x9290, 0x0018, 0x8214, 0x20e9, 0x0000, 0x2069,
+	0x0200, 0x6813, 0x0000, 0x22a8, 0x9284, 0x00e0, 0x0128, 0x20a9,
+	0x0020, 0x9292, 0x0020, 0x0008, 0x9016, 0x20a1, 0x0240, 0x9006,
+	0x4004, 0x82ff, 0x0120, 0x6810, 0x8000, 0x6812, 0x0c60, 0x00de,
+	0x0005, 0x00d6, 0x0096, 0x6014, 0x2048, 0xa878, 0x6056, 0x9006,
+	0xa836, 0xa83a, 0xa99c, 0xa946, 0xa84a, 0x6023, 0x0003, 0x6007,
+	0x0040, 0x6003, 0x0003, 0x600b, 0xffff, 0xa817, 0x0001, 0xa842,
+	0xa83e, 0x2900, 0xa85a, 0xa813, 0x1ec0, 0x080c, 0x865e, 0x0126,
+	0x2091, 0x8000, 0x080c, 0x8c6d, 0x012e, 0x009e, 0x00de, 0x0005,
+	0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x00a6, 0x0096, 0x0066, 0x0126,
+	0x2091, 0x8000, 0x2071, 0x19c2, 0x760c, 0x2660, 0x2678, 0x8cff,
+	0x0904, 0x9eb4, 0x7024, 0x9c06, 0x1520, 0x2069, 0x0100, 0x68c0,
+	0x9005, 0x0904, 0x9e86, 0x080c, 0x9605, 0x68c3, 0x0000, 0x080c,
+	0x9a6a, 0x7027, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0x9384,
+	0x1000, 0x0138, 0x2001, 0x0100, 0x080c, 0x2b88, 0x9006, 0x080c,
+	0x2b88, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001,
+	0x003e, 0x700c, 0x9c36, 0x1110, 0x660c, 0x760e, 0x7008, 0x9c36,
+	0x1140, 0x2c00, 0x9f36, 0x0118, 0x2f00, 0x700a, 0x0010, 0x700b,
+	0x0000, 0x660c, 0x0066, 0x2c00, 0x9f06, 0x0110, 0x7e0e, 0x0008,
+	0x2678, 0x600f, 0x0000, 0x080c, 0xbf32, 0x1180, 0x080c, 0x30d4,
+	0x080c, 0xbf43, 0x1518, 0x080c, 0xa995, 0x0400, 0x080c, 0x9a6a,
+	0x6824, 0xd084, 0x09b0, 0x6827, 0x0001, 0x0898, 0x080c, 0xbf43,
+	0x1118, 0x080c, 0xa995, 0x0090, 0x6014, 0x2048, 0x080c, 0xbd39,
+	0x0168, 0x6020, 0x9086, 0x0003, 0x1520, 0xa867, 0x0103, 0xab7a,
+	0xa877, 0x0000, 0x080c, 0x6a23, 0x080c, 0xbf26, 0x080c, 0xc1af,
+	0x080c, 0xa007, 0x080c, 0x9940, 0x00ce, 0x0804, 0x9e37, 0x2c78,
+	0x600c, 0x2060, 0x0804, 0x9e37, 0x700f, 0x0000, 0x700b, 0x0000,
+	0x012e, 0x006e, 0x009e, 0x00ae, 0x00ce, 0x00de, 0x00ee, 0x00fe,
+	0x0005, 0x6020, 0x9086, 0x0006, 0x1d08, 0x080c, 0xd781, 0x08f0,
+	0x00d6, 0x0156, 0x080c, 0x911d, 0x7a14, 0x82ff, 0x0138, 0x7003,
+	0x0100, 0x700b, 0x0003, 0x60c3, 0x0008, 0x0490, 0x7003, 0x0200,
+	0x7007, 0x0000, 0x2069, 0x1800, 0x901e, 0x6800, 0x9086, 0x0004,
+	0x1110, 0xc38d, 0x0060, 0x080c, 0x717f, 0x1110, 0xc3ad, 0x0008,
+	0xc3a5, 0x6ad8, 0xd29c, 0x1110, 0xd2ac, 0x0108, 0xc39d, 0x730e,
+	0x2011, 0x1848, 0x63f0, 0x2312, 0x20a9, 0x0006, 0x2011, 0x1840,
+	0x2019, 0x1841, 0x2071, 0x0250, 0x2376, 0x8e70, 0x2276, 0x8e70,
+	0x9398, 0x0002, 0x9290, 0x0002, 0x1f04, 0x9efc, 0x60c3, 0x0020,
+	0x080c, 0x95d9, 0x015e, 0x00de, 0x0005, 0x0156, 0x080c, 0x911d,
+	0x7a14, 0x82ff, 0x0168, 0x9286, 0xffff, 0x0118, 0x9282, 0x000e,
+	0x1238, 0x7003, 0x0100, 0x700b, 0x0003, 0x60c3, 0x0008, 0x0488,
+	0x7003, 0x0200, 0x7007, 0x001c, 0x700f, 0x0001, 0x2011, 0x1998,
+	0x2204, 0x8007, 0x701a, 0x8210, 0x2204, 0x8007, 0x701e, 0x0421,
+	0x1120, 0xb8a0, 0x9082, 0x007f, 0x0248, 0x2001, 0x181e, 0x2004,
+	0x7022, 0x2001, 0x181f, 0x2004, 0x7026, 0x0030, 0x2001, 0x1817,
+	0x2004, 0x9084, 0x00ff, 0x7026, 0x20a9, 0x0004, 0x20e1, 0x0001,
+	0x2099, 0x1805, 0x20e9, 0x0000, 0x20a1, 0x0256, 0x4003, 0x60c3,
+	0x001c, 0x015e, 0x0804, 0x95d9, 0x0006, 0x2001, 0x1836, 0x2004,
+	0xd0ac, 0x000e, 0x0005, 0x2011, 0x0003, 0x080c, 0x990e, 0x2011,
+	0x0002, 0x080c, 0x9918, 0x080c, 0x9826, 0x0036, 0x901e, 0x080c,
+	0x989c, 0x003e, 0x0005, 0x2071, 0x188b, 0x7000, 0x9005, 0x0140,
+	0x2001, 0x0976, 0x2071, 0x1800, 0x7072, 0x7076, 0x7067, 0xffe0,
+	0x2071, 0x1800, 0x7070, 0x7052, 0x7057, 0x1cd0, 0x0005, 0x00e6,
+	0x0126, 0x2071, 0x1800, 0x2091, 0x8000, 0x7550, 0x9582, 0x0010,
+	0x0608, 0x7054, 0x2060, 0x6000, 0x9086, 0x0000, 0x0148, 0x9ce0,
 	0x0018, 0x7064, 0x9c02, 0x1208, 0x0cb0, 0x2061, 0x1cd0, 0x0c98,
 	0x6003, 0x0008, 0x8529, 0x7552, 0x9ca8, 0x0018, 0x7064, 0x9502,
-	0x1228, 0x7556, 0x9085, 0x0001, 0x00ee, 0x0005, 0x7057, 0x1cd0,
-	0x0cc8, 0x9006, 0x0cc8, 0x9c82, 0x1cd0, 0x0a0c, 0x0dfa, 0x2001,
-	0x1819, 0x2004, 0x9c02, 0x1a0c, 0x0dfa, 0x9006, 0x6006, 0x600a,
-	0x600e, 0x6016, 0x601a, 0x6012, 0x6023, 0x0000, 0x6003, 0x0000,
-	0x601e, 0x6056, 0x605a, 0x6026, 0x602a, 0x602e, 0x6032, 0x6036,
-	0x603a, 0x603e, 0x6042, 0x2061, 0x1800, 0x6050, 0x8000, 0x6052,
-	0x9086, 0x0001, 0x0108, 0x0005, 0x0126, 0x2091, 0x8000, 0x080c,
-	0x8c10, 0x012e, 0x0cc0, 0x0006, 0x6000, 0x9086, 0x0000, 0x01b0,
-	0x601c, 0xd084, 0x190c, 0x19b4, 0x6017, 0x0000, 0x6023, 0x0007,
-	0x2001, 0x195e, 0x2004, 0x0006, 0x9082, 0x0051, 0x000e, 0x0208,
-	0x8004, 0x601a, 0x080c, 0xdae2, 0x6043, 0x0000, 0x000e, 0x0005,
-	0x00e6, 0x0126, 0x2071, 0x1800, 0x2091, 0x8000, 0x7550, 0x9582,
-	0x0001, 0x0608, 0x7054, 0x2060, 0x6000, 0x9086, 0x0000, 0x0148,
-	0x9ce0, 0x0018, 0x7064, 0x9c02, 0x1208, 0x0cb0, 0x2061, 0x1cd0,
-	0x0c98, 0x6003, 0x0008, 0x8529, 0x7552, 0x9ca8, 0x0018, 0x7064,
-	0x9502, 0x1230, 0x7556, 0x9085, 0x0001, 0x012e, 0x00ee, 0x0005,
-	0x7057, 0x1cd0, 0x0cc0, 0x9006, 0x0cc0, 0x6020, 0x9084, 0x000f,
-	0x0002, 0xa170, 0xa179, 0xa194, 0xa1af, 0xc55f, 0xc57c, 0xc597,
-	0xa170, 0xa179, 0xa170, 0xa1cb, 0xa170, 0xa170, 0xa170, 0xa170,
-	0x9186, 0x0013, 0x1128, 0x080c, 0x8b04, 0x080c, 0x8c10, 0x0005,
-	0x0005, 0x0066, 0x6000, 0x90b2, 0x0016, 0x1a0c, 0x0dfa, 0x0013,
-	0x006e, 0x0005, 0xa192, 0xa8f8, 0xaac8, 0xa192, 0xab56, 0xa4ae,
-	0xa192, 0xa192, 0xa87a, 0xb0fa, 0xa192, 0xa192, 0xa192, 0xa192,
-	0xa192, 0xa192, 0x080c, 0x0dfa, 0x0066, 0x6000, 0x90b2, 0x0016,
-	0x1a0c, 0x0dfa, 0x0013, 0x006e, 0x0005, 0xa1ad, 0xb7e1, 0xa1ad,
-	0xa1ad, 0xa1ad, 0xa1ad, 0xa1ad, 0xa1ad, 0xb778, 0xb963, 0xa1ad,
-	0xb822, 0xb8a1, 0xb822, 0xb8a1, 0xa1ad, 0x080c, 0x0dfa, 0x6000,
-	0x9082, 0x0016, 0x1a0c, 0x0dfa, 0x6000, 0x0002, 0xa1c9, 0xb141,
-	0xb226, 0xb356, 0xb505, 0xa1c9, 0xa1c9, 0xa1c9, 0xb115, 0xb704,
-	0xb707, 0xa1c9, 0xa1c9, 0xa1c9, 0xa1c9, 0xb736, 0xa1c9, 0xa1c9,
-	0xa1c9, 0x080c, 0x0dfa, 0x0066, 0x6000, 0x90b2, 0x0016, 0x1a0c,
-	0x0dfa, 0x0013, 0x006e, 0x0005, 0xa1e4, 0xa1e4, 0xa227, 0xa2c6,
-	0xa35b, 0xa1e4, 0xa1e4, 0xa1e4, 0xa1e6, 0xa1e4, 0xa1e4, 0xa1e4,
-	0xa1e4, 0xa1e4, 0xa1e4, 0xa1e4, 0x080c, 0x0dfa, 0x9186, 0x004c,
-	0x0588, 0x9186, 0x0003, 0x190c, 0x0dfa, 0x0096, 0x601c, 0xc0ed,
-	0x601e, 0x6003, 0x0003, 0x6106, 0x6014, 0x2048, 0xa87c, 0x9084,
-	0xa000, 0xc0b5, 0xa87e, 0xa8ac, 0xa846, 0xa8b0, 0xa84a, 0x9006,
-	0xa836, 0xa83a, 0xa884, 0x9092, 0x199a, 0x0210, 0x2001, 0x1999,
-	0x8003, 0x8013, 0x8213, 0x9210, 0x621a, 0x009e, 0x2c10, 0x080c,
-	0x1afe, 0x080c, 0x86de, 0x0126, 0x2091, 0x8000, 0x080c, 0x8ced,
-	0x012e, 0x0005, 0x6010, 0x00b6, 0x2058, 0xbca0, 0x00be, 0x2c00,
-	0x080c, 0xa37d, 0x080c, 0xc551, 0x6003, 0x0007, 0x0005, 0x00d6,
-	0x0096, 0x00f6, 0x2079, 0x1800, 0x7a8c, 0x6014, 0x2048, 0xa87c,
-	0xd0ec, 0x1110, 0x9290, 0x0018, 0xac78, 0xc4fc, 0x0046, 0xa8e0,
-	0x9005, 0x1140, 0xa8dc, 0x921a, 0x0140, 0x0220, 0xa87b, 0x0007,
-	0x2010, 0x0028, 0xa87b, 0x0015, 0x0010, 0xa87b, 0x0000, 0x8214,
-	0xa883, 0x0000, 0xaa02, 0x0006, 0x0016, 0x0026, 0x00c6, 0x00d6,
-	0x00e6, 0x00f6, 0x2400, 0x9005, 0x1108, 0x009a, 0x2100, 0x9086,
-	0x0015, 0x1118, 0x2001, 0x0001, 0x0038, 0x2100, 0x9086, 0x0016,
-	0x0118, 0x2001, 0x0001, 0x002a, 0x94a4, 0x0007, 0x8423, 0x9405,
-	0x0002, 0xa28e, 0xa28e, 0xa289, 0xa28c, 0xa28e, 0xa286, 0xa279,
-	0xa279, 0xa279, 0xa279, 0xa279, 0xa279, 0xa279, 0xa279, 0xa279,
-	0xa279, 0x00fe, 0x00ee, 0x00de, 0x00ce, 0x002e, 0x001e, 0x000e,
-	0x004e, 0x00fe, 0x009e, 0x00de, 0x080c, 0x0dfa, 0x080c, 0xad39,
-	0x0028, 0x080c, 0xae5c, 0x0010, 0x080c, 0xaf4b, 0x00fe, 0x00ee,
-	0x00de, 0x00ce, 0x002e, 0x001e, 0x2c00, 0xa896, 0x000e, 0x080c,
-	0xa43b, 0x0530, 0xa804, 0xa80e, 0x00a6, 0x2050, 0xb100, 0x00ae,
-	0x8006, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080,
-	0x0002, 0xaacc, 0xabd0, 0xacd4, 0xadd8, 0x2031, 0x0000, 0x2041,
-	0x12a2, 0x080c, 0xa5e6, 0x0160, 0x000e, 0x9005, 0x0120, 0x00fe,
-	0x009e, 0x00de, 0x0005, 0x00fe, 0x009e, 0x00de, 0x0804, 0xa0e3,
-	0x2001, 0x002c, 0x900e, 0x080c, 0xa4a1, 0x0c70, 0x91b6, 0x0015,
-	0x0170, 0x91b6, 0x0016, 0x0158, 0x91b2, 0x0047, 0x0a0c, 0x0dfa,
-	0x91b2, 0x0050, 0x1a0c, 0x0dfa, 0x9182, 0x0047, 0x00ca, 0x2001,
-	0x0109, 0x2004, 0xd08c, 0x0198, 0x0126, 0x2091, 0x2800, 0x0006,
-	0x0016, 0x0026, 0x080c, 0x8632, 0x002e, 0x001e, 0x000e, 0x012e,
-	0xa001, 0x6000, 0x9086, 0x0002, 0x1110, 0x0804, 0xa227, 0x0005,
-	0xa2f9, 0xa2f9, 0xa2fb, 0xa331, 0xa2f9, 0xa2f9, 0xa2f9, 0xa2f9,
-	0xa344, 0x080c, 0x0dfa, 0x00d6, 0x0016, 0x0096, 0x080c, 0x8bc0,
-	0x080c, 0x8ced, 0x6003, 0x0004, 0x6114, 0x2148, 0xa87c, 0xd0fc,
-	0x01c0, 0xa878, 0xc0fc, 0x9005, 0x1158, 0xa894, 0x9005, 0x0140,
-	0x2001, 0x0000, 0x900e, 0x080c, 0xa4a1, 0x080c, 0xa0e3, 0x00a8,
-	0x6003, 0x0002, 0xa8a4, 0xa9a8, 0x9105, 0x1178, 0xa8ae, 0xa8b2,
-	0x0c78, 0xa87f, 0x0020, 0xa88c, 0xa88a, 0xa8a4, 0xa8ae, 0xa8a8,
-	0xa8b2, 0xa8c7, 0x0000, 0xa8cb, 0x0000, 0x009e, 0x001e, 0x00de,
-	0x0005, 0x080c, 0x8bc0, 0x00d6, 0x0096, 0x6114, 0x2148, 0x080c,
-	0xbe37, 0x0120, 0xa87b, 0x0006, 0x080c, 0x6ae9, 0x009e, 0x00de,
-	0x080c, 0xa0e3, 0x0804, 0x8ced, 0x080c, 0x8bc0, 0x080c, 0x318b,
-	0x080c, 0xc54e, 0x00d6, 0x0096, 0x6114, 0x2148, 0x080c, 0xbe37,
-	0x0120, 0xa87b, 0x0029, 0x080c, 0x6ae9, 0x009e, 0x00de, 0x080c,
-	0xa0e3, 0x0804, 0x8ced, 0x9182, 0x0047, 0x0002, 0xa36b, 0xa36d,
-	0xa36b, 0xa36b, 0xa36b, 0xa36b, 0xa36b, 0xa36b, 0xa36b, 0xa36b,
-	0xa36b, 0xa36b, 0xa36d, 0x080c, 0x0dfa, 0x00d6, 0x0096, 0x080c,
-	0x1582, 0x6114, 0x2148, 0xa87b, 0x0000, 0xa883, 0x0000, 0x080c,
-	0x6ae9, 0x009e, 0x00de, 0x0804, 0xa0e3, 0x0026, 0x0036, 0x0056,
-	0x0066, 0x0096, 0x00a6, 0x00f6, 0x0006, 0x080c, 0x1031, 0x000e,
-	0x090c, 0x0dfa, 0xa960, 0x21e8, 0xa95c, 0x9188, 0x0019, 0x21a0,
-	0x900e, 0x20a9, 0x0020, 0x4104, 0xa87a, 0x2079, 0x1800, 0x798c,
-	0x9188, 0x0018, 0x918c, 0x0fff, 0xa972, 0xac76, 0x2950, 0x00a6,
-	0x2001, 0x0205, 0x2003, 0x0000, 0x901e, 0x2029, 0x0001, 0x9182,
-	0x0034, 0x1228, 0x2011, 0x001f, 0x080c, 0xb9e8, 0x04c0, 0x2130,
-	0x2009, 0x0034, 0x2011, 0x001f, 0x080c, 0xb9e8, 0x96b2, 0x0034,
-	0xb004, 0x904d, 0x0110, 0x080c, 0x0fe3, 0x080c, 0x1031, 0x01d0,
-	0x8528, 0xa867, 0x0110, 0xa86b, 0x0000, 0x2920, 0xb406, 0x968a,
-	0x003d, 0x1230, 0x2608, 0x2011, 0x001b, 0x080c, 0xb9e8, 0x00b8,
-	0x96b2, 0x003c, 0x2009, 0x003c, 0x2950, 0x2011, 0x001b, 0x080c,
-	0xb9e8, 0x0c18, 0x2001, 0x0205, 0x2003, 0x0000, 0x00ae, 0x852f,
-	0x95ad, 0x0050, 0xb566, 0xb070, 0xc0fd, 0xb072, 0x0048, 0x2001,
-	0x0205, 0x2003, 0x0000, 0x00ae, 0x852f, 0x95ad, 0x0050, 0xb566,
-	0x2a48, 0xa804, 0xa807, 0x0000, 0x0006, 0x080c, 0x6ae9, 0x000e,
-	0x2048, 0x9005, 0x1db0, 0x00fe, 0x00ae, 0x009e, 0x006e, 0x005e,
-	0x003e, 0x002e, 0x0005, 0x00d6, 0x00f6, 0x0096, 0x0006, 0x080c,
-	0x1031, 0x000e, 0x090c, 0x0dfa, 0xa960, 0x21e8, 0xa95c, 0x9188,
-	0x0019, 0x21a0, 0x900e, 0x20a9, 0x0020, 0x4104, 0xaa66, 0xa87a,
-	0x2079, 0x1800, 0x798c, 0x810c, 0x9188, 0x000c, 0x9182, 0x001a,
-	0x0210, 0x2009, 0x001a, 0x21a8, 0x810b, 0xa972, 0xac76, 0x2e98,
-	0xa85c, 0x9080, 0x001f, 0x20a0, 0x2001, 0x0205, 0x200c, 0x918d,
-	0x0080, 0x2102, 0x4003, 0x2003, 0x0000, 0x080c, 0x6ae9, 0x009e,
-	0x00fe, 0x00de, 0x0005, 0x0016, 0x00d6, 0x00f6, 0x0096, 0x0016,
-	0x2001, 0x0205, 0x200c, 0x918d, 0x0080, 0x2102, 0x001e, 0x2079,
-	0x0200, 0x2e98, 0xa87c, 0xd0ec, 0x0118, 0x9e80, 0x000c, 0x2098,
-	0x2021, 0x003e, 0x901e, 0x9282, 0x0020, 0x0218, 0x2011, 0x0020,
-	0x2018, 0x9486, 0x003e, 0x1170, 0x0096, 0x080c, 0x1031, 0x2900,
-	0x009e, 0x05c0, 0xa806, 0x2048, 0xa860, 0x20e8, 0xa85c, 0x9080,
-	0x0002, 0x20a0, 0x3300, 0x908e, 0x0260, 0x0140, 0x2009, 0x0280,
-	0x9102, 0x920a, 0x0218, 0x2010, 0x2100, 0x9318, 0x2200, 0x9402,
-	0x1228, 0x2400, 0x9202, 0x2410, 0x9318, 0x9006, 0x2020, 0x22a8,
-	0xa800, 0x9200, 0xa802, 0x20e1, 0x0000, 0x4003, 0x83ff, 0x0180,
-	0x3300, 0x9086, 0x0280, 0x1130, 0x7814, 0x8000, 0x9085, 0x0080,
-	0x7816, 0x2e98, 0x2310, 0x84ff, 0x0904, 0xa450, 0x0804, 0xa452,
-	0x9085, 0x0001, 0x7817, 0x0000, 0x009e, 0x00fe, 0x00de, 0x001e,
-	0x0005, 0x00d6, 0x0036, 0x0096, 0x6314, 0x2348, 0xa87a, 0xa982,
-	0x080c, 0x6adc, 0x009e, 0x003e, 0x00de, 0x0005, 0x91b6, 0x0015,
-	0x1118, 0x080c, 0xa0e3, 0x0030, 0x91b6, 0x0016, 0x190c, 0x0dfa,
-	0x080c, 0xa0e3, 0x0005, 0x20a9, 0x000e, 0x20e1, 0x0000, 0x2e98,
-	0x6014, 0x0096, 0x2048, 0xa860, 0x20e8, 0xa85c, 0x20a0, 0x009e,
-	0x4003, 0x0136, 0x9080, 0x001b, 0x20a0, 0x2011, 0x0006, 0x20a9,
-	0x0001, 0x3418, 0x8318, 0x23a0, 0x4003, 0x3318, 0x8318, 0x2398,
-	0x8211, 0x1db8, 0x2011, 0x0006, 0x013e, 0x20a0, 0x3318, 0x8318,
-	0x2398, 0x4003, 0x3418, 0x8318, 0x23a0, 0x8211, 0x1db8, 0x0096,
-	0x080c, 0xbe37, 0x0130, 0x6014, 0x2048, 0xa807, 0x0000, 0xa867,
-	0x0103, 0x009e, 0x0804, 0xa0e3, 0x0096, 0x00d6, 0x0036, 0x7330,
-	0x9386, 0x0200, 0x11a8, 0x6010, 0x00b6, 0x2058, 0xb8bf, 0x0000,
-	0x00be, 0x6014, 0x9005, 0x0130, 0x2048, 0xa807, 0x0000, 0xa867,
-	0x0103, 0xab32, 0x080c, 0xa0e3, 0x003e, 0x00de, 0x009e, 0x0005,
-	0x0011, 0x1d48, 0x0cc8, 0x0006, 0x0016, 0x080c, 0xc539, 0x0188,
-	0x6014, 0x9005, 0x1170, 0x600b, 0x0003, 0x601b, 0x0000, 0x6043,
-	0x0000, 0x2009, 0x0022, 0x080c, 0xa8d0, 0x9006, 0x001e, 0x000e,
-	0x0005, 0x9085, 0x0001, 0x0cd0, 0x0096, 0x0016, 0x20a9, 0x0014,
-	0x9e80, 0x000c, 0x20e1, 0x0000, 0x2098, 0x6014, 0x2048, 0xa860,
-	0x20e8, 0xa85c, 0x9080, 0x0002, 0x20a0, 0x4003, 0x2001, 0x0205,
-	0x2003, 0x0001, 0x2099, 0x0260, 0x20a9, 0x0016, 0x4003, 0x20a9,
-	0x000a, 0xa804, 0x2048, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0002,
-	0x20a0, 0x4003, 0x2001, 0x0205, 0x2003, 0x0002, 0x2099, 0x0260,
-	0x20a9, 0x0020, 0x4003, 0x2003, 0x0000, 0x6014, 0x2048, 0xa800,
-	0x2048, 0xa867, 0x0103, 0x080c, 0xa0e3, 0x001e, 0x009e, 0x0005,
-	0x0096, 0x0016, 0x900e, 0x7030, 0x9086, 0x0100, 0x0140, 0x7038,
-	0x9084, 0x00ff, 0x800c, 0x703c, 0x9084, 0x00ff, 0x8004, 0x9080,
-	0x0004, 0x9108, 0x810b, 0x2011, 0x0002, 0x2019, 0x000c, 0x6014,
-	0x2048, 0x080c, 0xb9e8, 0x080c, 0xbe37, 0x0140, 0x6014, 0x2048,
-	0xa807, 0x0000, 0xa864, 0xa8e2, 0xa867, 0x0103, 0x080c, 0xa0e3,
-	0x001e, 0x009e, 0x0005, 0x0016, 0x0096, 0x7030, 0x9086, 0x0100,
-	0x1118, 0x2009, 0x0004, 0x0010, 0x7034, 0x800c, 0x810b, 0x2011,
-	0x000c, 0x2019, 0x000c, 0x6014, 0x2048, 0xa804, 0x0096, 0x9005,
-	0x0108, 0x2048, 0x080c, 0xb9e8, 0x009e, 0x080c, 0xbe37, 0x0148,
-	0xa804, 0x9005, 0x1158, 0xa807, 0x0000, 0xa864, 0xa8e2, 0xa867,
-	0x0103, 0x080c, 0xa0e3, 0x009e, 0x001e, 0x0005, 0x0086, 0x2040,
-	0xa030, 0x8007, 0x9086, 0x0100, 0x1118, 0x080c, 0xaa81, 0x00e0,
-	0xa034, 0x8007, 0x800c, 0x8806, 0x8006, 0x8007, 0x90bc, 0x003f,
-	0x9084, 0xffc0, 0x9080, 0x000c, 0xa87b, 0x0000, 0xa883, 0x0000,
-	0xa897, 0x4000, 0xaaa0, 0xab9c, 0xaca8, 0xada4, 0x2031, 0x0000,
-	0x2041, 0x1288, 0x0019, 0x0d08, 0x008e, 0x0898, 0x0096, 0x0006,
-	0x080c, 0x1031, 0x000e, 0x01b0, 0xa8ab, 0x0dcb, 0xa876, 0x000e,
-	0xa8a2, 0x0006, 0xae6a, 0x2800, 0xa89e, 0xa97a, 0xaf72, 0xaa8e,
-	0xab92, 0xac96, 0xad9a, 0x0086, 0x2940, 0x080c, 0x112e, 0x008e,
-	0x9085, 0x0001, 0x009e, 0x0005, 0x00e6, 0x00d6, 0x0026, 0x7008,
-	0x9084, 0x00ff, 0x6210, 0x00b6, 0x2258, 0xba10, 0x00be, 0x9206,
-	0x1520, 0x700c, 0x6210, 0x00b6, 0x2258, 0xba14, 0x00be, 0x9206,
-	0x11e0, 0x6043, 0x0000, 0x2c68, 0x0016, 0x2009, 0x0035, 0x080c,
-	0xc4b1, 0x001e, 0x1158, 0x622c, 0x2268, 0x2071, 0x026c, 0x6b20,
-	0x9386, 0x0003, 0x0130, 0x9386, 0x0006, 0x0128, 0x080c, 0xa0e3,
-	0x0020, 0x0039, 0x0010, 0x080c, 0xa705, 0x002e, 0x00de, 0x00ee,
-	0x0005, 0x0096, 0x6814, 0x2048, 0x9186, 0x0015, 0x0904, 0xa6ed,
-	0x918e, 0x0016, 0x1904, 0xa703, 0x700c, 0x908c, 0xff00, 0x9186,
-	0x1700, 0x0120, 0x9186, 0x0300, 0x1904, 0xa6c7, 0x89ff, 0x1138,
-	0x6800, 0x9086, 0x000f, 0x0904, 0xa6aa, 0x0804, 0xa701, 0x6808,
-	0x9086, 0xffff, 0x1904, 0xa6ef, 0xa87c, 0x9084, 0x0060, 0x9086,
-	0x0020, 0x1128, 0xa83c, 0xa940, 0x9105, 0x1904, 0xa6ef, 0x6824,
-	0xd084, 0x1904, 0xa6ef, 0xd0b4, 0x0158, 0x0016, 0x2001, 0x195e,
-	0x200c, 0x6018, 0x9102, 0x9082, 0x0005, 0x001e, 0x1a04, 0xa6ef,
-	0x080c, 0xc022, 0x685c, 0xa882, 0xa87c, 0xc0dc, 0xc0f4, 0xc0d4,
-	0xa87e, 0x0026, 0x900e, 0x6a18, 0x2001, 0x000a, 0x080c, 0x84ff,
-	0xa884, 0x920a, 0x0208, 0x8011, 0xaa86, 0x82ff, 0x002e, 0x1138,
-	0x00c6, 0x2d60, 0x080c, 0xbb4a, 0x00ce, 0x0804, 0xa701, 0x00c6,
-	0xa868, 0xd0fc, 0x1118, 0x080c, 0x5fa7, 0x0010, 0x080c, 0x6355,
-	0x00ce, 0x1904, 0xa6ef, 0x00c6, 0x2d60, 0x080c, 0xa0e3, 0x00ce,
-	0x0804, 0xa701, 0x00c6, 0x080c, 0xa130, 0x0198, 0x6017, 0x0000,
-	0x6810, 0x6012, 0x080c, 0xc2b3, 0x6023, 0x0003, 0x6904, 0x00c6,
-	0x2d60, 0x080c, 0xa0e3, 0x00ce, 0x080c, 0xa15d, 0x00ce, 0x0804,
-	0xa701, 0x2001, 0x1960, 0x2004, 0x6842, 0x00ce, 0x04d0, 0x7008,
-	0x9086, 0x000b, 0x11c8, 0x6010, 0x00b6, 0x2058, 0xb900, 0xc1bc,
-	0xb902, 0x00be, 0x00c6, 0x2d60, 0xa87b, 0x0003, 0x080c, 0xc4f3,
-	0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002, 0x080c, 0x8679,
-	0x080c, 0x8c10, 0x00ce, 0x00e8, 0x700c, 0x9086, 0x2a00, 0x1138,
-	0x2001, 0x1960, 0x2004, 0x6842, 0x00a0, 0x0479, 0x00a0, 0x89ff,
-	0x090c, 0x0dfa, 0x00c6, 0x00d6, 0x2d60, 0xa867, 0x0103, 0xa87b,
-	0x0003, 0x080c, 0x6904, 0x080c, 0xc022, 0x080c, 0xa113, 0x00de,
-	0x00ce, 0x080c, 0xa0e3, 0x009e, 0x0005, 0x9186, 0x0015, 0x1128,
-	0x2001, 0x1960, 0x2004, 0x6842, 0x0068, 0x918e, 0x0016, 0x1160,
-	0x00c6, 0x2d00, 0x2060, 0x080c, 0xdae2, 0x080c, 0x84a6, 0x080c,
-	0xa0e3, 0x00ce, 0x080c, 0xa0e3, 0x0005, 0x0026, 0x0036, 0x0046,
-	0x7228, 0xacb0, 0xabac, 0xd2f4, 0x0130, 0x2001, 0x1960, 0x2004,
-	0x6842, 0x0804, 0xa77f, 0x00c6, 0x2d60, 0x080c, 0xba49, 0x00ce,
-	0x6804, 0x9086, 0x0050, 0x1168, 0x00c6, 0x2d00, 0x2060, 0x6003,
-	0x0001, 0x6007, 0x0050, 0x080c, 0x8679, 0x080c, 0x8c10, 0x00ce,
-	0x04f0, 0x6800, 0x9086, 0x000f, 0x01a8, 0x89ff, 0x090c, 0x0dfa,
-	0x6800, 0x9086, 0x0004, 0x1190, 0xa87c, 0xd0ac, 0x0178, 0xa843,
-	0x0fff, 0xa83f, 0x0fff, 0xa880, 0xc0fc, 0xa882, 0x2001, 0x0001,
-	0x6832, 0x0400, 0x2001, 0x0007, 0x6832, 0x00e0, 0xa87c, 0xd0b4,
-	0x1150, 0xd0ac, 0x0db8, 0x6824, 0xd0f4, 0x1d48, 0xa838, 0xa934,
-	0x9105, 0x0d80, 0x0c20, 0xd2ec, 0x1d68, 0x7024, 0x9306, 0x1118,
-	0x7020, 0x9406, 0x0d38, 0x7020, 0x683e, 0x7024, 0x683a, 0x2001,
-	0x0005, 0x6832, 0x080c, 0xc1aa, 0x080c, 0x8c10, 0x0010, 0x080c,
-	0xa0e3, 0x004e, 0x003e, 0x002e, 0x0005, 0x00e6, 0x00d6, 0x0026,
+	0x1230, 0x7556, 0x9085, 0x0001, 0x012e, 0x00ee, 0x0005, 0x7057,
+	0x1cd0, 0x0cc0, 0x9006, 0x0cc0, 0x00e6, 0x2071, 0x1800, 0x7550,
+	0x9582, 0x0010, 0x0600, 0x7054, 0x2060, 0x6000, 0x9086, 0x0000,
+	0x0148, 0x9ce0, 0x0018, 0x7064, 0x9c02, 0x1208, 0x0cb0, 0x2061,
+	0x1cd0, 0x0c98, 0x6003, 0x0008, 0x8529, 0x7552, 0x9ca8, 0x0018,
+	0x7064, 0x9502, 0x1228, 0x7556, 0x9085, 0x0001, 0x00ee, 0x0005,
+	0x7057, 0x1cd0, 0x0cc8, 0x9006, 0x0cc8, 0x9c82, 0x1cd0, 0x0a0c,
+	0x0e02, 0x2001, 0x1819, 0x2004, 0x9c02, 0x1a0c, 0x0e02, 0x9006,
+	0x6006, 0x600a, 0x600e, 0x6016, 0x601a, 0x6012, 0x6023, 0x0000,
+	0x6003, 0x0000, 0x601e, 0x6056, 0x605a, 0x6026, 0x602a, 0x602e,
+	0x6032, 0x6036, 0x603a, 0x603e, 0x6042, 0x2061, 0x1800, 0x6050,
+	0x8000, 0x6052, 0x9086, 0x0001, 0x0108, 0x0005, 0x0126, 0x2091,
+	0x8000, 0x0016, 0x080c, 0x8b90, 0x001e, 0x012e, 0x0cb0, 0x0006,
+	0x6000, 0x9086, 0x0000, 0x01c0, 0x601c, 0xd084, 0x190c, 0x1938,
+	0x6017, 0x0000, 0x6023, 0x0007, 0x2001, 0x1960, 0x2004, 0x0006,
+	0x9082, 0x0051, 0x000e, 0x0208, 0x8004, 0x601a, 0x080c, 0xda33,
+	0x6043, 0x0000, 0x6013, 0x0000, 0x000e, 0x0005, 0x00e6, 0x0126,
+	0x2071, 0x1800, 0x2091, 0x8000, 0x7550, 0x9582, 0x0001, 0x0608,
+	0x7054, 0x2060, 0x6000, 0x9086, 0x0000, 0x0148, 0x9ce0, 0x0018,
+	0x7064, 0x9c02, 0x1208, 0x0cb0, 0x2061, 0x1cd0, 0x0c98, 0x6003,
+	0x0008, 0x8529, 0x7552, 0x9ca8, 0x0018, 0x7064, 0x9502, 0x1230,
+	0x7556, 0x9085, 0x0001, 0x012e, 0x00ee, 0x0005, 0x7057, 0x1cd0,
+	0x0cc0, 0x9006, 0x0cc0, 0x6020, 0x9084, 0x000f, 0x0002, 0xa066,
+	0xa06f, 0xa08a, 0xa0a5, 0xc48c, 0xc4a9, 0xc4c4, 0xa066, 0xa06f,
+	0xa066, 0xa0c1, 0xa066, 0xa066, 0xa066, 0xa066, 0x9186, 0x0013,
+	0x1128, 0x080c, 0x8a84, 0x080c, 0x8b90, 0x0005, 0x0005, 0x0066,
+	0x6000, 0x90b2, 0x0016, 0x1a0c, 0x0e02, 0x0013, 0x006e, 0x0005,
+	0xa088, 0xa7f1, 0xa9dc, 0xa088, 0xaa6a, 0xa3a4, 0xa088, 0xa088,
+	0xa773, 0xb035, 0xa088, 0xa088, 0xa088, 0xa088, 0xa088, 0xa088,
+	0x080c, 0x0e02, 0x0066, 0x6000, 0x90b2, 0x0016, 0x1a0c, 0x0e02,
+	0x0013, 0x006e, 0x0005, 0xa0a3, 0xb6ff, 0xa0a3, 0xa0a3, 0xa0a3,
+	0xa0a3, 0xa0a3, 0xa0a3, 0xb696, 0xb881, 0xa0a3, 0xb740, 0xb7bf,
+	0xb740, 0xb7bf, 0xa0a3, 0x080c, 0x0e02, 0x6000, 0x9082, 0x0016,
+	0x1a0c, 0x0e02, 0x6000, 0x0002, 0xa0bf, 0xb07c, 0xb144, 0xb274,
+	0xb423, 0xa0bf, 0xa0bf, 0xa0bf, 0xb050, 0xb622, 0xb625, 0xa0bf,
+	0xa0bf, 0xa0bf, 0xa0bf, 0xb654, 0xa0bf, 0xa0bf, 0xa0bf, 0x080c,
+	0x0e02, 0x0066, 0x6000, 0x90b2, 0x0016, 0x1a0c, 0x0e02, 0x0013,
+	0x006e, 0x0005, 0xa0da, 0xa0da, 0xa11d, 0xa1bc, 0xa251, 0xa0da,
+	0xa0da, 0xa0da, 0xa0dc, 0xa0da, 0xa0da, 0xa0da, 0xa0da, 0xa0da,
+	0xa0da, 0xa0da, 0x080c, 0x0e02, 0x9186, 0x004c, 0x0588, 0x9186,
+	0x0003, 0x190c, 0x0e02, 0x0096, 0x601c, 0xc0ed, 0x601e, 0x6003,
+	0x0003, 0x6106, 0x6014, 0x2048, 0xa87c, 0x9084, 0xa000, 0xc0b5,
+	0xa87e, 0xa8ac, 0xa846, 0xa8b0, 0xa84a, 0x9006, 0xa836, 0xa83a,
+	0xa884, 0x9092, 0x199a, 0x0210, 0x2001, 0x1999, 0x8003, 0x8013,
+	0x8213, 0x9210, 0x621a, 0x009e, 0x2c10, 0x080c, 0x1a82, 0x080c,
+	0x865e, 0x0126, 0x2091, 0x8000, 0x080c, 0x8c6d, 0x012e, 0x0005,
+	0x6010, 0x00b6, 0x2058, 0xbca0, 0x00be, 0x2c00, 0x080c, 0xa273,
+	0x080c, 0xc45c, 0x6003, 0x0007, 0x0005, 0x00d6, 0x0096, 0x00f6,
+	0x2079, 0x1800, 0x7a8c, 0x6014, 0x2048, 0xa87c, 0xd0ec, 0x1110,
+	0x9290, 0x0018, 0xac78, 0xc4fc, 0x0046, 0xa8e0, 0x9005, 0x1140,
+	0xa8dc, 0x921a, 0x0140, 0x0220, 0xa87b, 0x0007, 0x2010, 0x0028,
+	0xa87b, 0x0015, 0x0010, 0xa87b, 0x0000, 0x8214, 0xa883, 0x0000,
+	0xaa02, 0x0006, 0x0016, 0x0026, 0x00c6, 0x00d6, 0x00e6, 0x00f6,
+	0x2400, 0x9005, 0x1108, 0x009a, 0x2100, 0x9086, 0x0015, 0x1118,
+	0x2001, 0x0001, 0x0038, 0x2100, 0x9086, 0x0016, 0x0118, 0x2001,
+	0x0001, 0x002a, 0x94a4, 0x0007, 0x8423, 0x9405, 0x0002, 0xa184,
+	0xa184, 0xa17f, 0xa182, 0xa184, 0xa17c, 0xa16f, 0xa16f, 0xa16f,
+	0xa16f, 0xa16f, 0xa16f, 0xa16f, 0xa16f, 0xa16f, 0xa16f, 0x00fe,
+	0x00ee, 0x00de, 0x00ce, 0x002e, 0x001e, 0x000e, 0x004e, 0x00fe,
+	0x009e, 0x00de, 0x080c, 0x0e02, 0x080c, 0xac67, 0x0028, 0x080c,
+	0xad98, 0x0010, 0x080c, 0xae86, 0x00fe, 0x00ee, 0x00de, 0x00ce,
+	0x002e, 0x001e, 0x2c00, 0xa896, 0x000e, 0x080c, 0xa331, 0x0530,
+	0xa804, 0xa80e, 0x00a6, 0x2050, 0xb100, 0x00ae, 0x8006, 0x8006,
+	0x8007, 0x90bc, 0x003f, 0x9084, 0xffc0, 0x9080, 0x0002, 0xaacc,
+	0xabd0, 0xacd4, 0xadd8, 0x2031, 0x0000, 0x2041, 0x12b4, 0x080c,
+	0xa4df, 0x0160, 0x000e, 0x9005, 0x0120, 0x00fe, 0x009e, 0x00de,
+	0x0005, 0x00fe, 0x009e, 0x00de, 0x0804, 0x9fd5, 0x2001, 0x002c,
+	0x900e, 0x080c, 0xa397, 0x0c70, 0x91b6, 0x0015, 0x0170, 0x91b6,
+	0x0016, 0x0158, 0x91b2, 0x0047, 0x0a0c, 0x0e02, 0x91b2, 0x0050,
+	0x1a0c, 0x0e02, 0x9182, 0x0047, 0x00ca, 0x2001, 0x0109, 0x2004,
+	0xd08c, 0x0198, 0x0126, 0x2091, 0x2800, 0x0006, 0x0016, 0x0026,
+	0x080c, 0x85b2, 0x002e, 0x001e, 0x000e, 0x012e, 0xa001, 0x6000,
+	0x9086, 0x0002, 0x1110, 0x0804, 0xa11d, 0x0005, 0xa1ef, 0xa1ef,
+	0xa1f1, 0xa227, 0xa1ef, 0xa1ef, 0xa1ef, 0xa1ef, 0xa23a, 0x080c,
+	0x0e02, 0x00d6, 0x0016, 0x0096, 0x080c, 0x8b40, 0x080c, 0x8c6d,
+	0x6003, 0x0004, 0x6114, 0x2148, 0xa87c, 0xd0fc, 0x01c0, 0xa878,
+	0xc0fc, 0x9005, 0x1158, 0xa894, 0x9005, 0x0140, 0x2001, 0x0000,
+	0x900e, 0x080c, 0xa397, 0x080c, 0x9fd5, 0x00a8, 0x6003, 0x0002,
+	0xa8a4, 0xa9a8, 0x9105, 0x1178, 0xa8ae, 0xa8b2, 0x0c78, 0xa87f,
+	0x0020, 0xa88c, 0xa88a, 0xa8a4, 0xa8ae, 0xa8a8, 0xa8b2, 0xa8c7,
+	0x0000, 0xa8cb, 0x0000, 0x009e, 0x001e, 0x00de, 0x0005, 0x080c,
+	0x8b40, 0x00d6, 0x0096, 0x6114, 0x2148, 0x080c, 0xbd3b, 0x0120,
+	0xa87b, 0x0006, 0x080c, 0x6a23, 0x009e, 0x00de, 0x080c, 0x9fd5,
+	0x0804, 0x8c6d, 0x080c, 0x8b40, 0x080c, 0x30ab, 0x080c, 0xc459,
+	0x00d6, 0x0096, 0x6114, 0x2148, 0x080c, 0xbd3b, 0x0120, 0xa87b,
+	0x0029, 0x080c, 0x6a23, 0x009e, 0x00de, 0x080c, 0x9fd5, 0x0804,
+	0x8c6d, 0x9182, 0x0047, 0x0002, 0xa261, 0xa263, 0xa261, 0xa261,
+	0xa261, 0xa261, 0xa261, 0xa261, 0xa261, 0xa261, 0xa261, 0xa261,
+	0xa263, 0x080c, 0x0e02, 0x00d6, 0x0096, 0x080c, 0x1583, 0x6114,
+	0x2148, 0xa87b, 0x0000, 0xa883, 0x0000, 0x080c, 0x6a23, 0x009e,
+	0x00de, 0x0804, 0x9fd5, 0x0026, 0x0036, 0x0056, 0x0066, 0x0096,
+	0x00a6, 0x00f6, 0x0006, 0x080c, 0x1043, 0x000e, 0x090c, 0x0e02,
+	0xa960, 0x21e8, 0xa95c, 0x9188, 0x0019, 0x21a0, 0x900e, 0x20a9,
+	0x0020, 0x4104, 0xa87a, 0x2079, 0x1800, 0x798c, 0x9188, 0x0018,
+	0x918c, 0x0fff, 0xa972, 0xac76, 0x2950, 0x00a6, 0x2001, 0x0205,
+	0x2003, 0x0000, 0x901e, 0x2029, 0x0001, 0x9182, 0x0034, 0x1228,
+	0x2011, 0x001f, 0x080c, 0xb906, 0x04c0, 0x2130, 0x2009, 0x0034,
+	0x2011, 0x001f, 0x080c, 0xb906, 0x96b2, 0x0034, 0xb004, 0x904d,
+	0x0110, 0x080c, 0x0ff5, 0x080c, 0x1043, 0x01d0, 0x8528, 0xa867,
+	0x0110, 0xa86b, 0x0000, 0x2920, 0xb406, 0x968a, 0x003d, 0x1230,
+	0x2608, 0x2011, 0x001b, 0x080c, 0xb906, 0x00b8, 0x96b2, 0x003c,
+	0x2009, 0x003c, 0x2950, 0x2011, 0x001b, 0x080c, 0xb906, 0x0c18,
+	0x2001, 0x0205, 0x2003, 0x0000, 0x00ae, 0x852f, 0x95ad, 0x0050,
+	0xb566, 0xb070, 0xc0fd, 0xb072, 0x0048, 0x2001, 0x0205, 0x2003,
+	0x0000, 0x00ae, 0x852f, 0x95ad, 0x0050, 0xb566, 0x2a48, 0xa804,
+	0xa807, 0x0000, 0x0006, 0x080c, 0x6a23, 0x000e, 0x2048, 0x9005,
+	0x1db0, 0x00fe, 0x00ae, 0x009e, 0x006e, 0x005e, 0x003e, 0x002e,
+	0x0005, 0x00d6, 0x00f6, 0x0096, 0x0006, 0x080c, 0x1043, 0x000e,
+	0x090c, 0x0e02, 0xa960, 0x21e8, 0xa95c, 0x9188, 0x0019, 0x21a0,
+	0x900e, 0x20a9, 0x0020, 0x4104, 0xaa66, 0xa87a, 0x2079, 0x1800,
+	0x798c, 0x810c, 0x9188, 0x000c, 0x9182, 0x001a, 0x0210, 0x2009,
+	0x001a, 0x21a8, 0x810b, 0xa972, 0xac76, 0x2e98, 0xa85c, 0x9080,
+	0x001f, 0x20a0, 0x2001, 0x0205, 0x200c, 0x918d, 0x0080, 0x2102,
+	0x4003, 0x2003, 0x0000, 0x080c, 0x6a23, 0x009e, 0x00fe, 0x00de,
+	0x0005, 0x0016, 0x00d6, 0x00f6, 0x0096, 0x0016, 0x2001, 0x0205,
+	0x200c, 0x918d, 0x0080, 0x2102, 0x001e, 0x2079, 0x0200, 0x2e98,
+	0xa87c, 0xd0ec, 0x0118, 0x9e80, 0x000c, 0x2098, 0x2021, 0x003e,
+	0x901e, 0x9282, 0x0020, 0x0218, 0x2011, 0x0020, 0x2018, 0x9486,
+	0x003e, 0x1170, 0x0096, 0x080c, 0x1043, 0x2900, 0x009e, 0x05c0,
+	0xa806, 0x2048, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0002, 0x20a0,
+	0x3300, 0x908e, 0x0260, 0x0140, 0x2009, 0x0280, 0x9102, 0x920a,
+	0x0218, 0x2010, 0x2100, 0x9318, 0x2200, 0x9402, 0x1228, 0x2400,
+	0x9202, 0x2410, 0x9318, 0x9006, 0x2020, 0x22a8, 0xa800, 0x9200,
+	0xa802, 0x20e1, 0x0000, 0x4003, 0x83ff, 0x0180, 0x3300, 0x9086,
+	0x0280, 0x1130, 0x7814, 0x8000, 0x9085, 0x0080, 0x7816, 0x2e98,
+	0x2310, 0x84ff, 0x0904, 0xa346, 0x0804, 0xa348, 0x9085, 0x0001,
+	0x7817, 0x0000, 0x009e, 0x00fe, 0x00de, 0x001e, 0x0005, 0x00d6,
+	0x0036, 0x0096, 0x6314, 0x2348, 0xa87a, 0xa982, 0x080c, 0x6a16,
+	0x009e, 0x003e, 0x00de, 0x0005, 0x91b6, 0x0015, 0x1118, 0x080c,
+	0x9fd5, 0x0030, 0x91b6, 0x0016, 0x190c, 0x0e02, 0x080c, 0x9fd5,
+	0x0005, 0x20a9, 0x000e, 0x20e1, 0x0000, 0x2e98, 0x6014, 0x0096,
+	0x2048, 0xa860, 0x20e8, 0xa85c, 0x20a0, 0x009e, 0x4003, 0x9196,
+	0x0016, 0x01f0, 0x0136, 0x9080, 0x001b, 0x20a0, 0x2011, 0x0006,
+	0x20a9, 0x0001, 0x3418, 0x8318, 0x23a0, 0x4003, 0x3318, 0x8318,
+	0x2398, 0x8211, 0x1db8, 0x2011, 0x0006, 0x013e, 0x20a0, 0x3318,
+	0x8318, 0x2398, 0x4003, 0x3418, 0x8318, 0x23a0, 0x8211, 0x1db8,
+	0x0096, 0x080c, 0xbd3b, 0x0130, 0x6014, 0x2048, 0xa807, 0x0000,
+	0xa867, 0x0103, 0x009e, 0x0804, 0x9fd5, 0x0096, 0x00d6, 0x0036,
+	0x7330, 0x9386, 0x0200, 0x11a8, 0x6010, 0x00b6, 0x2058, 0xb8bf,
+	0x0000, 0x00be, 0x6014, 0x9005, 0x0130, 0x2048, 0xa807, 0x0000,
+	0xa867, 0x0103, 0xab32, 0x080c, 0x9fd5, 0x003e, 0x00de, 0x009e,
+	0x0005, 0x0011, 0x1d48, 0x0cc8, 0x0006, 0x0016, 0x080c, 0xc444,
+	0x0188, 0x6014, 0x9005, 0x1170, 0x600b, 0x0003, 0x601b, 0x0000,
+	0x6043, 0x0000, 0x2009, 0x0022, 0x080c, 0xa7c9, 0x9006, 0x001e,
+	0x000e, 0x0005, 0x9085, 0x0001, 0x0cd0, 0x0096, 0x0016, 0x20a9,
+	0x0014, 0x9e80, 0x000c, 0x20e1, 0x0000, 0x2098, 0x6014, 0x2048,
+	0xa860, 0x20e8, 0xa85c, 0x9080, 0x0002, 0x20a0, 0x4003, 0x2001,
+	0x0205, 0x2003, 0x0001, 0x2099, 0x0260, 0x20a9, 0x0016, 0x4003,
+	0x20a9, 0x000a, 0xa804, 0x2048, 0xa860, 0x20e8, 0xa85c, 0x9080,
+	0x0002, 0x20a0, 0x4003, 0x2001, 0x0205, 0x2003, 0x0002, 0x2099,
+	0x0260, 0x20a9, 0x0020, 0x4003, 0x2003, 0x0000, 0x6014, 0x2048,
+	0xa800, 0x2048, 0xa867, 0x0103, 0x080c, 0x9fd5, 0x001e, 0x009e,
+	0x0005, 0x0096, 0x0016, 0x900e, 0x7030, 0x9086, 0x0100, 0x0140,
+	0x7038, 0x9084, 0x00ff, 0x800c, 0x703c, 0x9084, 0x00ff, 0x8004,
+	0x9080, 0x0004, 0x9108, 0x810b, 0x2011, 0x0002, 0x2019, 0x000c,
+	0x6014, 0x2048, 0x080c, 0xb906, 0x080c, 0xbd3b, 0x0140, 0x6014,
+	0x2048, 0xa807, 0x0000, 0xa864, 0xa8e2, 0xa867, 0x0103, 0x080c,
+	0x9fd5, 0x001e, 0x009e, 0x0005, 0x0016, 0x0096, 0x7030, 0x9086,
+	0x0100, 0x1118, 0x2009, 0x0004, 0x0010, 0x7034, 0x800c, 0x810b,
+	0x2011, 0x000c, 0x2019, 0x000c, 0x6014, 0x2048, 0xa804, 0x0096,
+	0x9005, 0x0108, 0x2048, 0x080c, 0xb906, 0x009e, 0x080c, 0xbd3b,
+	0x0148, 0xa804, 0x9005, 0x1158, 0xa807, 0x0000, 0xa864, 0xa8e2,
+	0xa867, 0x0103, 0x080c, 0x9fd5, 0x009e, 0x001e, 0x0005, 0x0086,
+	0x2040, 0xa030, 0x8007, 0x9086, 0x0100, 0x1118, 0x080c, 0xa995,
+	0x00e0, 0xa034, 0x8007, 0x800c, 0x8806, 0x8006, 0x8007, 0x90bc,
+	0x003f, 0x9084, 0xffc0, 0x9080, 0x000c, 0xa87b, 0x0000, 0xa883,
+	0x0000, 0xa897, 0x4000, 0xaaa0, 0xab9c, 0xaca8, 0xada4, 0x2031,
+	0x0000, 0x2041, 0x129a, 0x0019, 0x0d08, 0x008e, 0x0898, 0x0096,
+	0x0006, 0x080c, 0x1043, 0x000e, 0x01b0, 0xa8ab, 0x0dcb, 0xa876,
+	0x000e, 0xa8a2, 0x0006, 0xae6a, 0x2800, 0xa89e, 0xa97a, 0xaf72,
+	0xaa8e, 0xab92, 0xac96, 0xad9a, 0x0086, 0x2940, 0x080c, 0x1140,
+	0x008e, 0x9085, 0x0001, 0x009e, 0x0005, 0x00e6, 0x00d6, 0x0026,
 	0x7008, 0x9084, 0x00ff, 0x6210, 0x00b6, 0x2258, 0xba10, 0x00be,
-	0x9206, 0x1904, 0xa7ea, 0x700c, 0x6210, 0x00b6, 0x2258, 0xba14,
-	0x00be, 0x9206, 0x1904, 0xa7ea, 0x6038, 0x2068, 0x6824, 0xc0dc,
-	0x6826, 0x6a20, 0x9286, 0x0007, 0x0904, 0xa7ea, 0x9286, 0x0002,
-	0x0904, 0xa7ea, 0x9286, 0x0000, 0x05e8, 0x6808, 0x633c, 0x9306,
-	0x15c8, 0x2071, 0x026c, 0x9186, 0x0015, 0x0570, 0x918e, 0x0016,
-	0x1100, 0x00c6, 0x6038, 0x2060, 0x6104, 0x9186, 0x004b, 0x01c0,
-	0x9186, 0x004c, 0x01a8, 0x9186, 0x004d, 0x0190, 0x9186, 0x004e,
-	0x0178, 0x9186, 0x0052, 0x0160, 0x6014, 0x0096, 0x2048, 0x080c,
-	0xbe37, 0x090c, 0x0dfa, 0xa87b, 0x0003, 0x009e, 0x080c, 0xc4f3,
-	0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002, 0x080c, 0x8679,
-	0x080c, 0x8c10, 0x00ce, 0x0030, 0x6038, 0x2070, 0x2001, 0x1960,
-	0x2004, 0x7042, 0x080c, 0xa0e3, 0x002e, 0x00de, 0x00ee, 0x0005,
-	0x00b6, 0x0096, 0x00f6, 0x6014, 0x2048, 0x6010, 0x2058, 0x91b6,
-	0x0015, 0x0130, 0xba08, 0xbb0c, 0xbc00, 0xc48c, 0xbc02, 0x0460,
-	0x0096, 0x0156, 0x0036, 0x0026, 0x2b48, 0x9e90, 0x0010, 0x2019,
-	0x000a, 0x20a9, 0x0004, 0x080c, 0xb0d0, 0x002e, 0x003e, 0x015e,
-	0x009e, 0x1904, 0xa859, 0x0096, 0x0156, 0x0036, 0x0026, 0x2b48,
-	0x9e90, 0x0014, 0x2019, 0x0006, 0x20a9, 0x0004, 0x080c, 0xb0d0,
-	0x002e, 0x003e, 0x015e, 0x009e, 0x15a0, 0x7238, 0xba0a, 0x733c,
-	0xbb0e, 0xbc00, 0xc48d, 0xbc02, 0xa804, 0x9005, 0x1128, 0x00fe,
-	0x009e, 0x00be, 0x0804, 0xa4e7, 0x0096, 0x2048, 0xaa12, 0xab16,
-	0xac0a, 0x009e, 0x8006, 0x8006, 0x8007, 0x90bc, 0x003f, 0x9084,
-	0xffc0, 0x9080, 0x0002, 0x2009, 0x002b, 0xaaa0, 0xab9c, 0xaca8,
-	0xada4, 0x2031, 0x0000, 0x2041, 0x1288, 0x080c, 0xa5e6, 0x0130,
-	0x00fe, 0x009e, 0x080c, 0xa0e3, 0x00be, 0x0005, 0x080c, 0xaa81,
-	0x0cb8, 0x2b78, 0x00f6, 0x080c, 0x318b, 0x080c, 0xc54e, 0x00fe,
-	0x00c6, 0x080c, 0xa08d, 0x2f00, 0x6012, 0x6017, 0x0000, 0x6023,
-	0x0001, 0x6007, 0x0001, 0x6003, 0x0001, 0x2001, 0x0007, 0x080c,
-	0x63f0, 0x080c, 0x641c, 0x080c, 0x86c1, 0x080c, 0x8c10, 0x00ce,
-	0x0804, 0xa82c, 0x2100, 0x91b2, 0x0053, 0x1a0c, 0x0dfa, 0x91b2,
-	0x0040, 0x1a04, 0xa8e2, 0x0002, 0xa8d0, 0xa8d0, 0xa8c6, 0xa8d0,
-	0xa8d0, 0xa8d0, 0xa8c4, 0xa8c4, 0xa8c4, 0xa8c4, 0xa8c4, 0xa8c4,
-	0xa8c4, 0xa8c4, 0xa8c4, 0xa8c4, 0xa8c4, 0xa8c4, 0xa8c4, 0xa8c4,
-	0xa8c4, 0xa8c4, 0xa8c4, 0xa8c4, 0xa8c4, 0xa8c4, 0xa8c4, 0xa8c4,
-	0xa8c4, 0xa8c4, 0xa8c4, 0xa8d0, 0xa8c4, 0xa8d0, 0xa8d0, 0xa8c4,
-	0xa8c4, 0xa8c4, 0xa8c4, 0xa8c4, 0xa8c6, 0xa8c4, 0xa8c4, 0xa8c4,
-	0xa8c4, 0xa8c4, 0xa8c4, 0xa8c4, 0xa8c4, 0xa8c4, 0xa8d0, 0xa8d0,
-	0xa8c4, 0xa8c4, 0xa8c4, 0xa8c4, 0xa8c4, 0xa8c4, 0xa8c4, 0xa8c4,
-	0xa8c4, 0xa8d0, 0xa8c4, 0xa8c4, 0x080c, 0x0dfa, 0x0066, 0x00b6,
-	0x6610, 0x2658, 0xb8bc, 0xc08c, 0xb8be, 0x00be, 0x006e, 0x0000,
-	0x6003, 0x0001, 0x6106, 0x9186, 0x0032, 0x0118, 0x080c, 0x86c1,
-	0x0010, 0x080c, 0x8679, 0x0126, 0x2091, 0x8000, 0x080c, 0x8c10,
-	0x012e, 0x0005, 0x2600, 0x0002, 0xa8f6, 0xa8f6, 0xa8f6, 0xa8d0,
-	0xa8d0, 0xa8f6, 0xa8f6, 0xa8f6, 0xa8f6, 0xa8d0, 0xa8f6, 0xa8d0,
-	0xa8f6, 0xa8d0, 0xa8f6, 0xa8f6, 0xa8f6, 0xa8f6, 0x080c, 0x0dfa,
-	0x6004, 0x90b2, 0x0053, 0x1a0c, 0x0dfa, 0x91b6, 0x0013, 0x0904,
-	0xa9ba, 0x91b6, 0x0027, 0x1904, 0xa975, 0x080c, 0x8b04, 0x6004,
-	0x080c, 0xc02e, 0x01b0, 0x080c, 0xc03f, 0x01a8, 0x908e, 0x0021,
-	0x0904, 0xa972, 0x908e, 0x0022, 0x1130, 0x080c, 0xa513, 0x0904,
-	0xa96e, 0x0804, 0xa96f, 0x908e, 0x003d, 0x0904, 0xa972, 0x0804,
-	0xa968, 0x080c, 0x31b4, 0x2001, 0x0007, 0x080c, 0x63f0, 0x6010,
-	0x00b6, 0x2058, 0xb9a0, 0x00be, 0x080c, 0xaa81, 0x9186, 0x007e,
-	0x1148, 0x2001, 0x1836, 0x2014, 0xc285, 0x080c, 0x7207, 0x1108,
-	0xc2ad, 0x2202, 0x0036, 0x0026, 0x2019, 0x0028, 0x2110, 0x080c,
-	0xdb3d, 0x002e, 0x003e, 0x0016, 0x0026, 0x0036, 0x2110, 0x2019,
-	0x0028, 0x080c, 0x8803, 0x0076, 0x903e, 0x080c, 0x86f1, 0x6010,
-	0x00b6, 0x905d, 0x0100, 0x00be, 0x2c08, 0x080c, 0xd5f6, 0x007e,
-	0x003e, 0x002e, 0x001e, 0x080c, 0xc54e, 0x0016, 0x080c, 0xc2ab,
-	0x080c, 0xa0e3, 0x001e, 0x080c, 0x3286, 0x080c, 0x8c10, 0x0030,
-	0x080c, 0xc2ab, 0x080c, 0xa0e3, 0x080c, 0x8c10, 0x0005, 0x080c,
-	0xaa81, 0x0cb0, 0x080c, 0xaabd, 0x0c98, 0x9186, 0x0014, 0x1db0,
-	0x080c, 0x8b04, 0x6004, 0x908e, 0x0022, 0x1118, 0x080c, 0xa513,
-	0x0d68, 0x080c, 0x318b, 0x080c, 0xc54e, 0x080c, 0xc02e, 0x1190,
-	0x080c, 0x31b4, 0x6010, 0x00b6, 0x2058, 0xb9a0, 0x00be, 0x080c,
-	0xaa81, 0x9186, 0x007e, 0x1128, 0x2001, 0x1836, 0x200c, 0xc185,
-	0x2102, 0x0870, 0x080c, 0xc03f, 0x1118, 0x080c, 0xaa81, 0x0840,
-	0x6004, 0x908e, 0x0032, 0x1160, 0x00e6, 0x00f6, 0x2071, 0x189c,
-	0x2079, 0x0000, 0x080c, 0x351a, 0x00fe, 0x00ee, 0x0804, 0xa968,
-	0x6004, 0x908e, 0x0021, 0x0d48, 0x908e, 0x0022, 0x090c, 0xaa81,
-	0x0804, 0xa968, 0x90b2, 0x0040, 0x1a04, 0xaa6a, 0x2008, 0x0002,
-	0xaa02, 0xaa03, 0xaa06, 0xaa09, 0xaa0c, 0xaa0f, 0xaa00, 0xaa00,
-	0xaa00, 0xaa00, 0xaa00, 0xaa00, 0xaa00, 0xaa00, 0xaa00, 0xaa00,
-	0xaa00, 0xaa00, 0xaa00, 0xaa00, 0xaa00, 0xaa00, 0xaa00, 0xaa00,
-	0xaa00, 0xaa00, 0xaa00, 0xaa00, 0xaa00, 0xaa00, 0xaa12, 0xaa1f,
-	0xaa00, 0xaa21, 0xaa1f, 0xaa00, 0xaa00, 0xaa00, 0xaa00, 0xaa00,
-	0xaa1f, 0xaa1f, 0xaa00, 0xaa00, 0xaa00, 0xaa00, 0xaa00, 0xaa00,
-	0xaa00, 0xaa00, 0xaa51, 0xaa1f, 0xaa00, 0xaa1b, 0xaa00, 0xaa00,
-	0xaa00, 0xaa1c, 0xaa00, 0xaa00, 0xaa00, 0xaa1f, 0xaa48, 0xaa00,
-	0x080c, 0x0dfa, 0x00e0, 0x2001, 0x000b, 0x0420, 0x2001, 0x0003,
-	0x0408, 0x2001, 0x0005, 0x00f0, 0x2001, 0x0001, 0x00d8, 0x2001,
-	0x0009, 0x00c0, 0x080c, 0x8b04, 0x6003, 0x0005, 0x080c, 0xc551,
-	0x080c, 0x8c10, 0x0070, 0x0018, 0x0010, 0x080c, 0x63f0, 0x0804,
-	0xaa62, 0x080c, 0x8b04, 0x080c, 0xc551, 0x6003, 0x0004, 0x080c,
-	0x8c10, 0x0005, 0x080c, 0x63f0, 0x080c, 0x8b04, 0x6003, 0x0002,
-	0x0036, 0x2019, 0x1866, 0x2304, 0x9084, 0xff00, 0x1120, 0x2001,
-	0x195e, 0x201c, 0x0040, 0x8007, 0x909a, 0x0004, 0x0ec0, 0x8003,
-	0x801b, 0x831b, 0x9318, 0x631a, 0x003e, 0x080c, 0x8c10, 0x0c08,
-	0x080c, 0x8b04, 0x080c, 0xc2ab, 0x080c, 0xa0e3, 0x080c, 0x8c10,
-	0x08c0, 0x00e6, 0x00f6, 0x2071, 0x189c, 0x2079, 0x0000, 0x080c,
-	0x351a, 0x00fe, 0x00ee, 0x080c, 0x8b04, 0x080c, 0xa0e3, 0x080c,
-	0x8c10, 0x0838, 0x080c, 0x8b04, 0x6003, 0x0002, 0x080c, 0xc551,
-	0x0804, 0x8c10, 0x2600, 0x2008, 0x0002, 0xaa7f, 0xaa7f, 0xaa7f,
-	0xaa62, 0xaa62, 0xaa7f, 0xaa7f, 0xaa7f, 0xaa7f, 0xaa62, 0xaa7f,
-	0xaa62, 0xaa7f, 0xaa62, 0xaa7f, 0xaa7f, 0xaa7f, 0xaa7f, 0x080c,
-	0x0dfa, 0x00e6, 0x0096, 0x0026, 0x0016, 0x080c, 0xbe37, 0x0568,
-	0x6014, 0x2048, 0xa864, 0x9086, 0x0139, 0x11a8, 0xa894, 0x9086,
-	0x0056, 0x1148, 0x080c, 0x5375, 0x0130, 0x2001, 0x0000, 0x900e,
-	0x2011, 0x4000, 0x0028, 0x2001, 0x0030, 0x900e, 0x2011, 0x4005,
-	0x080c, 0xc418, 0x0090, 0xa868, 0xd0fc, 0x0178, 0xa807, 0x0000,
-	0x0016, 0x6004, 0x908e, 0x0021, 0x0168, 0x908e, 0x003d, 0x0150,
-	0x001e, 0xa867, 0x0103, 0xa833, 0x0100, 0x001e, 0x002e, 0x009e,
-	0x00ee, 0x0005, 0x001e, 0x0009, 0x0cc0, 0x0096, 0x6014, 0x2048,
-	0xa800, 0x2048, 0xa867, 0x0103, 0xa823, 0x8001, 0x009e, 0x0005,
-	0x00b6, 0x6610, 0x2658, 0xb804, 0x9084, 0x00ff, 0x90b2, 0x000c,
-	0x1a0c, 0x0dfa, 0x6604, 0x96b6, 0x004d, 0x1120, 0x080c, 0xc337,
-	0x0804, 0xab45, 0x6604, 0x96b6, 0x0043, 0x1120, 0x080c, 0xc380,
-	0x0804, 0xab45, 0x6604, 0x96b6, 0x004b, 0x1120, 0x080c, 0xc3ac,
-	0x0804, 0xab45, 0x6604, 0x96b6, 0x0033, 0x1120, 0x080c, 0xc2cd,
-	0x0804, 0xab45, 0x6604, 0x96b6, 0x0028, 0x1120, 0x080c, 0xc07d,
-	0x0804, 0xab45, 0x6604, 0x96b6, 0x0029, 0x1120, 0x080c, 0xc0be,
-	0x0804, 0xab45, 0x6604, 0x96b6, 0x001f, 0x1118, 0x080c, 0xa4bb,
-	0x04e0, 0x6604, 0x96b6, 0x0000, 0x1118, 0x080c, 0xa7f0, 0x04a8,
-	0x6604, 0x96b6, 0x0022, 0x1118, 0x080c, 0xa4f4, 0x0470, 0x6604,
-	0x96b6, 0x0035, 0x1118, 0x080c, 0xa604, 0x0438, 0x6604, 0x96b6,
-	0x0039, 0x1118, 0x080c, 0xa785, 0x0400, 0x6604, 0x96b6, 0x003d,
-	0x1118, 0x080c, 0xa52c, 0x00c8, 0x6604, 0x96b6, 0x0044, 0x1118,
-	0x080c, 0xa568, 0x0090, 0x6604, 0x96b6, 0x0049, 0x1118, 0x080c,
-	0xa593, 0x0058, 0x91b6, 0x0015, 0x1110, 0x0063, 0x0030, 0x91b6,
-	0x0016, 0x1128, 0x00be, 0x0804, 0xae05, 0x00be, 0x0005, 0x080c,
-	0xa178, 0x0cd8, 0xab62, 0xab65, 0xab62, 0xaba9, 0xab62, 0xad39,
-	0xae12, 0xab62, 0xab62, 0xaddf, 0xab62, 0xadf3, 0x0096, 0x080c,
-	0x1582, 0x6014, 0x2048, 0xa800, 0x2048, 0xa867, 0x0103, 0x009e,
-	0x0804, 0xa0e3, 0xa001, 0xa001, 0x0005, 0x00e6, 0x2071, 0x1800,
-	0x708c, 0x9086, 0x0074, 0x1540, 0x080c, 0xd5c7, 0x11b0, 0x6010,
-	0x00b6, 0x2058, 0x7030, 0xd08c, 0x0128, 0xb800, 0xd0bc, 0x0110,
-	0xc0c5, 0xb802, 0x00e9, 0x00be, 0x2001, 0x0006, 0x080c, 0x63f0,
-	0x080c, 0x31b4, 0x080c, 0xa0e3, 0x0088, 0x2001, 0x000a, 0x080c,
-	0x63f0, 0x080c, 0x31b4, 0x6003, 0x0001, 0x6007, 0x0001, 0x080c,
-	0x86c1, 0x080c, 0x8c10, 0x0010, 0x080c, 0xad24, 0x00ee, 0x0005,
-	0x00d6, 0xb800, 0xd084, 0x0158, 0x9006, 0x080c, 0x63dc, 0x2069,
-	0x185b, 0x6804, 0x0020, 0x2001, 0x0006, 0x080c, 0x641c, 0x00de,
-	0x0005, 0x00b6, 0x0096, 0x00d6, 0x2011, 0x1823, 0x2204, 0x9086,
-	0x0074, 0x1904, 0xacfb, 0x6010, 0x2058, 0xbaa0, 0x9286, 0x007e,
-	0x1120, 0x080c, 0xaf56, 0x0804, 0xac60, 0x00d6, 0x080c, 0x7207,
-	0x0198, 0x0026, 0x2011, 0x0010, 0x080c, 0x67e7, 0x002e, 0x05c8,
-	0x080c, 0x55ef, 0x1540, 0x6014, 0x2048, 0xa807, 0x0000, 0xa867,
-	0x0103, 0xa833, 0xdead, 0x00f8, 0x0026, 0x2011, 0x8008, 0x080c,
-	0x67e7, 0x002e, 0x0530, 0x6014, 0x2048, 0xa864, 0x9084, 0x00ff,
-	0x9086, 0x0039, 0x1140, 0x2001, 0x0030, 0x900e, 0x2011, 0x4009,
-	0x080c, 0xc418, 0x0040, 0x6014, 0x2048, 0xa807, 0x0000, 0xa867,
-	0x0103, 0xa833, 0xdead, 0x6010, 0x2058, 0xb9a0, 0x0016, 0x080c,
-	0x31b4, 0x080c, 0xa0e3, 0x001e, 0x080c, 0x3286, 0x00de, 0x0804,
-	0xacfe, 0x00de, 0x080c, 0xaf4b, 0x6010, 0x2058, 0xbaa0, 0x9286,
-	0x0080, 0x1510, 0x6014, 0x9005, 0x01a8, 0x2048, 0xa864, 0x9084,
-	0x00ff, 0x9086, 0x0039, 0x1140, 0x2001, 0x0000, 0x900e, 0x2011,
-	0x4000, 0x080c, 0xc418, 0x0030, 0xa807, 0x0000, 0xa867, 0x0103,
-	0xa833, 0x0200, 0x2001, 0x0006, 0x080c, 0x63f0, 0x080c, 0x31b4,
-	0x080c, 0xa0e3, 0x0804, 0xacfe, 0x080c, 0xad0c, 0x6014, 0x9005,
-	0x0190, 0x2048, 0xa868, 0xd0f4, 0x01e8, 0xa864, 0x9084, 0x00ff,
-	0x9086, 0x0039, 0x1d08, 0x2001, 0x0000, 0x900e, 0x2011, 0x4000,
-	0x080c, 0xc418, 0x08f8, 0x080c, 0xad02, 0x0160, 0x9006, 0x080c,
-	0x63dc, 0x2001, 0x0004, 0x080c, 0x641c, 0x2001, 0x0007, 0x080c,
-	0x63f0, 0x08a0, 0x2001, 0x0004, 0x080c, 0x63f0, 0x6003, 0x0001,
-	0x6007, 0x0003, 0x080c, 0x86c1, 0x080c, 0x8c10, 0x0804, 0xacfe,
-	0xb85c, 0xd0e4, 0x01d0, 0x080c, 0xc24d, 0x080c, 0x7207, 0x0118,
-	0xd0dc, 0x1904, 0xac22, 0x2011, 0x1836, 0x2204, 0xc0ad, 0x2012,
-	0x2001, 0x0002, 0x00f6, 0x2079, 0x0100, 0x78e3, 0x0000, 0x080c,
-	0x27e2, 0x78e2, 0x00fe, 0x0804, 0xac22, 0x080c, 0xc28a, 0x2011,
-	0x1836, 0x2204, 0xc0a5, 0x2012, 0x0006, 0x080c, 0xd720, 0x000e,
-	0x1904, 0xac22, 0xc0b5, 0x2012, 0x2001, 0x0006, 0x080c, 0x63f0,
-	0x9006, 0x080c, 0x63dc, 0x00c6, 0x2001, 0x180f, 0x2004, 0xd09c,
-	0x0520, 0x00f6, 0x2079, 0x0100, 0x00e6, 0x2071, 0x1800, 0x700c,
-	0x9084, 0x00ff, 0x78e6, 0x707a, 0x7010, 0x78ea, 0x707e, 0x908c,
-	0x00ff, 0x00ee, 0x780c, 0xc0b5, 0x780e, 0x00fe, 0x080c, 0x27b7,
-	0x00f6, 0x2100, 0x900e, 0x080c, 0x276e, 0x795a, 0x00fe, 0x9186,
-	0x0081, 0x01d8, 0x2009, 0x0081, 0x00c8, 0x2009, 0x00ef, 0x00f6,
-	0x2079, 0x0100, 0x79ea, 0x7932, 0x7936, 0x780c, 0xc0b5, 0x780e,
-	0x00fe, 0x080c, 0x27b7, 0x00f6, 0x2079, 0x1800, 0x797e, 0x2100,
-	0x900e, 0x080c, 0x276e, 0x795a, 0x00fe, 0x8108, 0x080c, 0x643f,
-	0x2b00, 0x00ce, 0x1904, 0xac22, 0x6012, 0x2009, 0x180f, 0x210c,
-	0xd19c, 0x0150, 0x2009, 0x027c, 0x210c, 0x918c, 0x00ff, 0xb912,
-	0x2009, 0x027d, 0x210c, 0xb916, 0x2001, 0x0002, 0x080c, 0x63f0,
-	0x6023, 0x0001, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x86c1,
-	0x080c, 0x8c10, 0x0018, 0x080c, 0xaa81, 0x0431, 0x00de, 0x009e,
-	0x00be, 0x0005, 0x2001, 0x1810, 0x2004, 0xd0a4, 0x0120, 0x2001,
-	0x185c, 0x2004, 0xd0ac, 0x0005, 0x00e6, 0x080c, 0xdb96, 0x0190,
-	0x2071, 0x0260, 0x7108, 0x720c, 0x918c, 0x00ff, 0x1118, 0x9284,
-	0xff00, 0x0140, 0x6010, 0x2058, 0xb8a0, 0x9084, 0xff80, 0x1110,
-	0xb912, 0xba16, 0x00ee, 0x0005, 0x2030, 0x2001, 0x0007, 0x080c,
-	0x63f0, 0x080c, 0x55ef, 0x1120, 0x2001, 0x0007, 0x080c, 0x641c,
-	0x080c, 0x31b4, 0x6020, 0x9086, 0x000a, 0x1108, 0x0005, 0x0804,
-	0xa0e3, 0x00b6, 0x00e6, 0x0026, 0x0016, 0x2071, 0x1800, 0x708c,
-	0x9086, 0x0014, 0x1904, 0xadd6, 0x00d6, 0x080c, 0x7207, 0x0198,
-	0x0026, 0x2011, 0x0010, 0x080c, 0x67e7, 0x002e, 0x05c8, 0x080c,
-	0x55ef, 0x1540, 0x6014, 0x2048, 0xa807, 0x0000, 0xa867, 0x0103,
-	0xa833, 0xdead, 0x00f8, 0x0026, 0x2011, 0x8008, 0x080c, 0x67e7,
-	0x002e, 0x0530, 0x6014, 0x2048, 0xa864, 0x9084, 0x00ff, 0x9086,
-	0x0039, 0x1140, 0x2001, 0x0030, 0x900e, 0x2011, 0x4009, 0x080c,
-	0xc418, 0x0040, 0x6014, 0x2048, 0xa807, 0x0000, 0xa867, 0x0103,
-	0xa833, 0xdead, 0x6010, 0x2058, 0xb9a0, 0x0016, 0x080c, 0x31b4,
-	0x080c, 0xa0e3, 0x001e, 0x080c, 0x3286, 0x00de, 0x0804, 0xadda,
-	0x00de, 0x080c, 0x55ef, 0x1170, 0x6014, 0x9005, 0x1158, 0x0036,
-	0x0046, 0x6010, 0x2058, 0xbba0, 0x2021, 0x0006, 0x080c, 0x4cbc,
-	0x004e, 0x003e, 0x00d6, 0x6010, 0x2058, 0x080c, 0x653a, 0x080c,
-	0xab98, 0x00de, 0x080c, 0xb01c, 0x1588, 0x6010, 0x2058, 0xb890,
-	0x9005, 0x0560, 0x2001, 0x0006, 0x080c, 0x63f0, 0x0096, 0x6014,
-	0x904d, 0x01d0, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, 0x1140,
-	0x2001, 0x0000, 0x900e, 0x2011, 0x4000, 0x080c, 0xc418, 0x0060,
-	0xa864, 0x9084, 0x00ff, 0x9086, 0x0029, 0x0130, 0xa807, 0x0000,
-	0xa867, 0x0103, 0xa833, 0x0200, 0x009e, 0x080c, 0x31b4, 0x6020,
-	0x9086, 0x000a, 0x0138, 0x080c, 0xa0e3, 0x0020, 0x080c, 0xaa81,
-	0x080c, 0xad24, 0x001e, 0x002e, 0x00ee, 0x00be, 0x0005, 0x2011,
-	0x1823, 0x2204, 0x9086, 0x0014, 0x1160, 0x2001, 0x0002, 0x080c,
-	0x63f0, 0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x86c1, 0x0804,
-	0x8c10, 0x0804, 0xad24, 0x2030, 0x2011, 0x1823, 0x2204, 0x9086,
-	0x0004, 0x1148, 0x96b6, 0x000b, 0x1120, 0x2001, 0x0007, 0x080c,
-	0x63f0, 0x0804, 0xa0e3, 0x0804, 0xad24, 0x0002, 0xab62, 0xae1d,
-	0xab62, 0xae5c, 0xab62, 0xaf07, 0xae12, 0xab62, 0xab62, 0xaf1a,
-	0xab62, 0xaf2a, 0x6604, 0x9686, 0x0003, 0x0904, 0xad39, 0x96b6,
-	0x001e, 0x1110, 0x080c, 0xa0e3, 0x0005, 0x00b6, 0x00d6, 0x00c6,
-	0x080c, 0xaf3a, 0x11a0, 0x9006, 0x080c, 0x63dc, 0x080c, 0x318b,
-	0x080c, 0xc54e, 0x2001, 0x0002, 0x080c, 0x63f0, 0x6003, 0x0001,
-	0x6007, 0x0002, 0x080c, 0x86c1, 0x080c, 0x8c10, 0x0408, 0x2009,
-	0x026e, 0x2104, 0x9086, 0x0009, 0x1160, 0x6010, 0x2058, 0xb840,
-	0x9084, 0x00ff, 0x9005, 0x0170, 0x8001, 0xb842, 0x601b, 0x000a,
-	0x0078, 0x2009, 0x026f, 0x2104, 0x9084, 0xff00, 0x9086, 0x1900,
-	0x1108, 0x08a0, 0x080c, 0x318b, 0x080c, 0xc54e, 0x080c, 0xad24,
-	0x00ce, 0x00de, 0x00be, 0x0005, 0x0096, 0x00b6, 0x0026, 0x9016,
-	0x080c, 0xaf48, 0x00d6, 0x2069, 0x1954, 0x2d04, 0x9005, 0x0168,
-	0x6010, 0x2058, 0xb8a0, 0x9086, 0x007e, 0x1138, 0x2069, 0x181f,
-	0x2d04, 0x8000, 0x206a, 0x00de, 0x0010, 0x00de, 0x0088, 0x9006,
-	0x080c, 0x63dc, 0x2001, 0x0002, 0x080c, 0x63f0, 0x6003, 0x0001,
-	0x6007, 0x0002, 0x080c, 0x86c1, 0x080c, 0x8c10, 0x0804, 0xaed7,
-	0x080c, 0xbe37, 0x01b0, 0x6014, 0x2048, 0xa864, 0x2010, 0x9086,
-	0x0139, 0x1138, 0x6007, 0x0016, 0x2001, 0x0002, 0x080c, 0xc472,
-	0x00b0, 0x6014, 0x2048, 0xa864, 0xd0fc, 0x0118, 0x2001, 0x0001,
-	0x0ca8, 0x2001, 0x180e, 0x2004, 0xd0dc, 0x0148, 0x6010, 0x2058,
-	0xb840, 0x9084, 0x00ff, 0x9005, 0x1110, 0x9006, 0x0c38, 0x080c,
-	0xaa81, 0x2009, 0x026e, 0x2134, 0x96b4, 0x00ff, 0x9686, 0x0005,
-	0x0510, 0x9686, 0x000b, 0x01c8, 0x2009, 0x026f, 0x2104, 0x9084,
-	0xff00, 0x1118, 0x9686, 0x0009, 0x01b0, 0x9086, 0x1900, 0x1168,
-	0x9686, 0x0009, 0x0180, 0x2001, 0x0004, 0x080c, 0x63f0, 0x2001,
-	0x0028, 0x601a, 0x6007, 0x0052, 0x0010, 0x080c, 0xad24, 0x002e,
-	0x00be, 0x009e, 0x0005, 0x9286, 0x0139, 0x0160, 0x6014, 0x2048,
-	0x080c, 0xbe37, 0x0140, 0xa864, 0x9086, 0x0139, 0x0118, 0xa868,
-	0xd0fc, 0x0108, 0x0c50, 0x6010, 0x2058, 0xb840, 0x9084, 0x00ff,
-	0x9005, 0x0138, 0x8001, 0xb842, 0x601b, 0x000a, 0x6007, 0x0016,
-	0x08f0, 0xb8a0, 0x9086, 0x007e, 0x1138, 0x00e6, 0x2071, 0x1800,
-	0x080c, 0x5ebe, 0x00ee, 0x0010, 0x080c, 0x318b, 0x0870, 0x080c,
-	0xaf48, 0x1160, 0x2001, 0x0004, 0x080c, 0x63f0, 0x6003, 0x0001,
-	0x6007, 0x0003, 0x080c, 0x86c1, 0x0804, 0x8c10, 0x080c, 0xaa81,
-	0x0804, 0xad24, 0x0469, 0x1160, 0x2001, 0x0008, 0x080c, 0x63f0,
-	0x6003, 0x0001, 0x6007, 0x0005, 0x080c, 0x86c1, 0x0804, 0x8c10,
-	0x0804, 0xad24, 0x00e9, 0x1160, 0x2001, 0x000a, 0x080c, 0x63f0,
-	0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x86c1, 0x0804, 0x8c10,
-	0x0804, 0xad24, 0x2009, 0x026e, 0x2104, 0x9086, 0x0003, 0x1138,
-	0x2009, 0x026f, 0x2104, 0x9084, 0xff00, 0x9086, 0x2a00, 0x0005,
-	0x9085, 0x0001, 0x0005, 0x00b6, 0x00c6, 0x0016, 0x6110, 0x2158,
-	0x080c, 0x64ae, 0x001e, 0x00ce, 0x00be, 0x0005, 0x00b6, 0x00f6,
-	0x00e6, 0x00d6, 0x0036, 0x0016, 0x6010, 0x2058, 0x2009, 0x1836,
-	0x2104, 0x9085, 0x0003, 0x200a, 0x080c, 0xafee, 0x0560, 0x2009,
-	0x1836, 0x2104, 0xc0cd, 0x200a, 0x080c, 0x67bf, 0x0158, 0x9006,
-	0x2020, 0x2009, 0x002a, 0x080c, 0xd885, 0x2001, 0x180c, 0x200c,
-	0xc195, 0x2102, 0x2019, 0x002a, 0x2009, 0x0001, 0x080c, 0x3156,
-	0x00e6, 0x2071, 0x1800, 0x080c, 0x2f6c, 0x00ee, 0x00c6, 0x0156,
-	0x20a9, 0x0781, 0x2009, 0x007f, 0x080c, 0x3286, 0x8108, 0x1f04,
-	0xaf8c, 0x015e, 0x00ce, 0x080c, 0xaf4b, 0x2071, 0x0260, 0x2079,
-	0x0200, 0x7817, 0x0001, 0x2001, 0x1836, 0x200c, 0xc1c5, 0x7018,
-	0xd0fc, 0x0110, 0xd0dc, 0x0118, 0x7038, 0xd0dc, 0x1108, 0xc1c4,
-	0x7817, 0x0000, 0x2001, 0x1836, 0x2102, 0x2079, 0x0100, 0x2e04,
-	0x9084, 0x00ff, 0x2069, 0x181e, 0x206a, 0x78e6, 0x0006, 0x8e70,
-	0x2e04, 0x2069, 0x181f, 0x206a, 0x78ea, 0x7832, 0x7836, 0x2010,
-	0x9084, 0xff00, 0x001e, 0x9105, 0x2009, 0x182b, 0x200a, 0x2200,
-	0x9084, 0x00ff, 0x2008, 0x080c, 0x27b7, 0x080c, 0x7207, 0x0170,
-	0x2071, 0x0260, 0x2069, 0x195a, 0x7048, 0x206a, 0x704c, 0x6806,
-	0x7050, 0x680a, 0x7054, 0x680e, 0x080c, 0xc24d, 0x0040, 0x2001,
-	0x0006, 0x080c, 0x63f0, 0x080c, 0x31b4, 0x080c, 0xa0e3, 0x001e,
-	0x003e, 0x00de, 0x00ee, 0x00fe, 0x00be, 0x0005, 0x0096, 0x0026,
-	0x0036, 0x00e6, 0x0156, 0x2019, 0x182b, 0x231c, 0x83ff, 0x01f0,
-	0x2071, 0x0260, 0x7200, 0x9294, 0x00ff, 0x7004, 0x9084, 0xff00,
-	0x9205, 0x9306, 0x1198, 0x2011, 0x0276, 0x20a9, 0x0004, 0x2b48,
-	0x2019, 0x000a, 0x080c, 0xb0d0, 0x1148, 0x2011, 0x027a, 0x20a9,
-	0x0004, 0x2019, 0x0006, 0x080c, 0xb0d0, 0x1100, 0x015e, 0x00ee,
-	0x003e, 0x002e, 0x009e, 0x0005, 0x00e6, 0x2071, 0x0260, 0x7034,
-	0x9086, 0x0014, 0x11a8, 0x7038, 0x9086, 0x0800, 0x1188, 0x703c,
-	0xd0ec, 0x0160, 0x9084, 0x0f00, 0x9086, 0x0100, 0x1138, 0x7054,
-	0xd0a4, 0x1110, 0xd0ac, 0x0110, 0x9006, 0x0010, 0x9085, 0x0001,
-	0x00ee, 0x0005, 0x00e6, 0x0096, 0x00c6, 0x0076, 0x0056, 0x0046,
-	0x0026, 0x0006, 0x0126, 0x2091, 0x8000, 0x2029, 0x19c8, 0x252c,
-	0x2021, 0x19ce, 0x2424, 0x2061, 0x1cd0, 0x2071, 0x1800, 0x7250,
-	0x7070, 0x9202, 0x1a04, 0xb0a8, 0x080c, 0xd8b6, 0x0904, 0xb0a1,
-	0x6720, 0x9786, 0x0007, 0x0904, 0xb0a1, 0x2500, 0x9c06, 0x0904,
-	0xb0a1, 0x2400, 0x9c06, 0x05e8, 0x3e08, 0x9186, 0x0002, 0x1148,
-	0x6010, 0x9005, 0x0130, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc,
-	0x1580, 0x00c6, 0x6000, 0x9086, 0x0004, 0x1110, 0x080c, 0x19b4,
-	0x9786, 0x000a, 0x0148, 0x080c, 0xc03f, 0x1130, 0x00ce, 0x080c,
-	0xaa81, 0x080c, 0xa113, 0x00e8, 0x6014, 0x2048, 0x080c, 0xbe37,
-	0x01a8, 0x9786, 0x0003, 0x1530, 0xa867, 0x0103, 0xa87c, 0xd0cc,
-	0x0130, 0x0096, 0xa878, 0x2048, 0x080c, 0x0fe3, 0x009e, 0xab7a,
-	0xa877, 0x0000, 0x080c, 0x6adc, 0x080c, 0xc022, 0x080c, 0xa113,
-	0x00ce, 0x9ce0, 0x0018, 0x7064, 0x9c02, 0x1210, 0x0804, 0xb04f,
-	0x012e, 0x000e, 0x002e, 0x004e, 0x005e, 0x007e, 0x00ce, 0x009e,
-	0x00ee, 0x0005, 0x9786, 0x0006, 0x1118, 0x080c, 0xd830, 0x0c30,
-	0x9786, 0x000a, 0x09e0, 0x0880, 0x220c, 0x2304, 0x9106, 0x1130,
-	0x8210, 0x8318, 0x1f04, 0xb0bc, 0x9006, 0x0005, 0x2304, 0x9102,
-	0x0218, 0x2001, 0x0001, 0x0008, 0x9006, 0x918d, 0x0001, 0x0005,
-	0x0136, 0x01c6, 0x0016, 0x8906, 0x8006, 0x8007, 0x908c, 0x003f,
-	0x21e0, 0x9084, 0xffc0, 0x9300, 0x2098, 0x3518, 0x20a9, 0x0001,
-	0x220c, 0x4002, 0x910e, 0x1140, 0x8210, 0x8319, 0x1dc8, 0x9006,
-	0x001e, 0x01ce, 0x013e, 0x0005, 0x220c, 0x9102, 0x0218, 0x2001,
-	0x0001, 0x0010, 0x2001, 0x0000, 0x918d, 0x0001, 0x001e, 0x01ce,
-	0x013e, 0x0005, 0x6004, 0x908a, 0x0053, 0x1a0c, 0x0dfa, 0x080c,
-	0xc02e, 0x0120, 0x080c, 0xc03f, 0x0168, 0x0028, 0x080c, 0x31b4,
-	0x080c, 0xc03f, 0x0138, 0x080c, 0x8b04, 0x080c, 0xa0e3, 0x080c,
-	0x8c10, 0x0005, 0x080c, 0xaa81, 0x0cb0, 0x9182, 0x0054, 0x1220,
-	0x9182, 0x0040, 0x0208, 0x000a, 0x0005, 0xb131, 0xb131, 0xb131,
-	0xb131, 0xb131, 0xb131, 0xb131, 0xb131, 0xb131, 0xb131, 0xb131,
-	0xb133, 0xb133, 0xb133, 0xb133, 0xb131, 0xb131, 0xb131, 0xb133,
-	0xb131, 0x080c, 0x0dfa, 0x600b, 0xffff, 0x6003, 0x0001, 0x6106,
-	0x080c, 0x8679, 0x0126, 0x2091, 0x8000, 0x080c, 0x8c10, 0x012e,
-	0x0005, 0x9186, 0x0013, 0x1128, 0x6004, 0x9082, 0x0040, 0x0804,
-	0xb1e8, 0x9186, 0x0027, 0x1520, 0x080c, 0x8b04, 0x080c, 0x318b,
-	0x080c, 0xc54e, 0x0096, 0x6114, 0x2148, 0x080c, 0xbe37, 0x0198,
-	0x080c, 0xc03f, 0x1118, 0x080c, 0xaa81, 0x0068, 0xa867, 0x0103,
-	0xa87b, 0x0029, 0xa877, 0x0000, 0xa97c, 0xc1c5, 0xa97e, 0x080c,
-	0x6ae9, 0x080c, 0xc022, 0x009e, 0x080c, 0xa0e3, 0x0804, 0x8c10,
-	0x9186, 0x0014, 0x1120, 0x6004, 0x9082, 0x0040, 0x04a0, 0x9186,
-	0x0046, 0x0150, 0x9186, 0x0045, 0x0138, 0x9186, 0x0053, 0x0120,
-	0x9186, 0x0048, 0x190c, 0x0dfa, 0x2001, 0x0109, 0x2004, 0xd084,
-	0x0508, 0x0126, 0x2091, 0x2800, 0x0006, 0x0016, 0x0026, 0x0036,
-	0x00f6, 0x00e6, 0x00c6, 0x2079, 0x19bf, 0x2071, 0x1800, 0x2061,
-	0x0100, 0x080c, 0x8563, 0x00ce, 0x00ee, 0x00fe, 0x003e, 0x002e,
-	0x001e, 0x000e, 0x012e, 0xa001, 0x6000, 0x9086, 0x0002, 0x1110,
-	0x0804, 0xb226, 0x0005, 0x0002, 0xb1c2, 0xb1c0, 0xb1c0, 0xb1c0,
-	0xb1c0, 0xb1c0, 0xb1c0, 0xb1c0, 0xb1c0, 0xb1c0, 0xb1c0, 0xb1dd,
-	0xb1dd, 0xb1dd, 0xb1dd, 0xb1c0, 0xb1dd, 0xb1c0, 0xb1dd, 0xb1c0,
-	0x080c, 0x0dfa, 0x080c, 0x8b04, 0x0096, 0x6114, 0x2148, 0x080c,
-	0xbe37, 0x0168, 0xa867, 0x0103, 0xa87b, 0x0006, 0xa877, 0x0000,
-	0xa880, 0xc0ec, 0xa882, 0x080c, 0x6ae9, 0x080c, 0xc022, 0x009e,
-	0x080c, 0xa0e3, 0x080c, 0x8c10, 0x0005, 0x080c, 0x8b04, 0x080c,
-	0xc03f, 0x090c, 0xaa81, 0x080c, 0xa0e3, 0x080c, 0x8c10, 0x0005,
-	0x0002, 0xb1ff, 0xb1fd, 0xb1fd, 0xb1fd, 0xb1fd, 0xb1fd, 0xb1fd,
-	0xb1fd, 0xb1fd, 0xb1fd, 0xb1fd, 0xb216, 0xb216, 0xb216, 0xb216,
-	0xb1fd, 0xb220, 0xb1fd, 0xb216, 0xb1fd, 0x080c, 0x0dfa, 0x0096,
-	0x080c, 0x8b04, 0x6014, 0x2048, 0x2001, 0x1960, 0x2004, 0x6042,
-	0xa97c, 0xd1ac, 0x0140, 0x6003, 0x0004, 0xa87c, 0x9085, 0x0400,
-	0xa87e, 0x009e, 0x0005, 0x6003, 0x0002, 0x0cb8, 0x080c, 0x8b04,
-	0x080c, 0xc551, 0x080c, 0xc556, 0x6003, 0x000f, 0x0804, 0x8c10,
-	0x080c, 0x8b04, 0x080c, 0xa0e3, 0x0804, 0x8c10, 0x9182, 0x0054,
-	0x1220, 0x9182, 0x0040, 0x0208, 0x000a, 0x0005, 0xb242, 0xb242,
-	0xb242, 0xb242, 0xb242, 0xb244, 0xb321, 0xb242, 0xb355, 0xb242,
-	0xb242, 0xb242, 0xb242, 0xb242, 0xb242, 0xb242, 0xb242, 0xb242,
-	0xb242, 0xb355, 0x080c, 0x0dfa, 0x00b6, 0x0096, 0x6114, 0x2148,
-	0x7644, 0x96b4, 0x0fff, 0x86ff, 0x1528, 0x6010, 0x2058, 0xb800,
-	0xd0bc, 0x1904, 0xb310, 0xa87b, 0x0000, 0xa867, 0x0103, 0xae76,
-	0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938, 0x9115, 0x190c, 0xb4ee,
-	0x080c, 0x6904, 0x6210, 0x2258, 0xba3c, 0x82ff, 0x0110, 0x8211,
-	0xba3e, 0x7044, 0xd0e4, 0x1904, 0xb2f4, 0x080c, 0xa0e3, 0x009e,
-	0x00be, 0x0005, 0x968c, 0x0c00, 0x0150, 0x6010, 0x2058, 0xb800,
-	0xd0bc, 0x1904, 0xb2f8, 0x7348, 0xab92, 0x734c, 0xab8e, 0x968c,
-	0x00ff, 0x9186, 0x0002, 0x0508, 0x9186, 0x0028, 0x1118, 0xa87b,
-	0x001c, 0x00e8, 0xd6dc, 0x01a0, 0xa87b, 0x0015, 0xa87c, 0xd0ac,
-	0x0170, 0xa938, 0xaa34, 0x2100, 0x9205, 0x0148, 0x7048, 0x9106,
-	0x1118, 0x704c, 0x9206, 0x0118, 0xa992, 0xaa8e, 0xc6dc, 0x0038,
-	0xd6d4, 0x0118, 0xa87b, 0x0007, 0x0010, 0xa87b, 0x0000, 0xa867,
-	0x0103, 0xae76, 0x901e, 0xd6c4, 0x01d8, 0x9686, 0x0100, 0x1130,
-	0x7064, 0x9005, 0x1118, 0xc6c4, 0x0804, 0xb24b, 0x735c, 0xab86,
-	0x83ff, 0x0170, 0x938a, 0x0009, 0x0210, 0x2019, 0x0008, 0x0036,
-	0x2308, 0x2019, 0x0018, 0x2011, 0x0025, 0x080c, 0xb9e8, 0x003e,
-	0xd6cc, 0x0904, 0xb260, 0x7154, 0xa98a, 0x81ff, 0x0904, 0xb260,
-	0x9192, 0x0021, 0x1278, 0x8304, 0x9098, 0x0018, 0x2011, 0x0029,
-	0x080c, 0xb9e8, 0x2011, 0x0205, 0x2013, 0x0000, 0x080c, 0xc4de,
-	0x0804, 0xb260, 0xa868, 0xd0fc, 0x0120, 0x2009, 0x0020, 0xa98a,
-	0x0c50, 0x00a6, 0x2950, 0x080c, 0xb987, 0x00ae, 0x080c, 0xc4de,
-	0x080c, 0xb9d8, 0x0804, 0xb262, 0x080c, 0xc137, 0x0804, 0xb26f,
-	0xa87c, 0xd0ac, 0x0904, 0xb27b, 0xa880, 0xd0bc, 0x1904, 0xb27b,
-	0x7348, 0xa838, 0x9306, 0x11c8, 0x734c, 0xa834, 0x931e, 0x0904,
-	0xb27b, 0xd6d4, 0x0190, 0xab38, 0x9305, 0x0904, 0xb27b, 0x0068,
-	0xa87c, 0xd0ac, 0x0904, 0xb253, 0xa838, 0xa934, 0x9105, 0x0904,
-	0xb253, 0xa880, 0xd0bc, 0x1904, 0xb253, 0x080c, 0xc171, 0x0804,
-	0xb26f, 0x0096, 0x00f6, 0x6003, 0x0003, 0x6007, 0x0043, 0x2079,
-	0x026c, 0x7c04, 0x7b00, 0x7e0c, 0x7d08, 0x6014, 0x2048, 0xa87c,
-	0xd0ac, 0x0140, 0x6003, 0x0002, 0x00fe, 0x009e, 0x0005, 0x2130,
-	0x2228, 0x0058, 0x2400, 0xa9ac, 0x910a, 0x2300, 0xaab0, 0x9213,
-	0x2600, 0x9102, 0x2500, 0x9203, 0x0e90, 0xac36, 0xab3a, 0xae46,
-	0xad4a, 0x00fe, 0x6043, 0x0000, 0x2c10, 0x080c, 0x1afe, 0x080c,
-	0x86de, 0x080c, 0x8ced, 0x009e, 0x0005, 0x0005, 0x9182, 0x0054,
-	0x1220, 0x9182, 0x0040, 0x0208, 0x000a, 0x0005, 0xb372, 0xb372,
-	0xb372, 0xb372, 0xb372, 0xb374, 0xb40a, 0xb372, 0xb372, 0xb421,
-	0xb4b1, 0xb372, 0xb372, 0xb372, 0xb372, 0xb4c6, 0xb372, 0xb372,
-	0xb372, 0xb372, 0x080c, 0x0dfa, 0x0076, 0x00a6, 0x00e6, 0x0096,
-	0x2071, 0x0260, 0x6114, 0x2150, 0x7644, 0xb676, 0x96b4, 0x0fff,
-	0xb77c, 0xc7e5, 0xb77e, 0x6210, 0x00b6, 0x2258, 0xba3c, 0x82ff,
-	0x0110, 0x8211, 0xba3e, 0x00be, 0x86ff, 0x0904, 0xb405, 0x9694,
-	0xff00, 0x9284, 0x0c00, 0x0120, 0x7048, 0xb092, 0x704c, 0xb08e,
-	0x9284, 0x0300, 0x0904, 0xb405, 0x080c, 0x1031, 0x090c, 0x0dfa,
-	0x2900, 0xb07a, 0xb77c, 0xc7cd, 0xb77e, 0xa867, 0x0103, 0xb068,
-	0xa86a, 0xb06c, 0xa86e, 0xb070, 0xa872, 0xae76, 0x968c, 0x0c00,
-	0x0120, 0x7348, 0xab92, 0x734c, 0xab8e, 0x968c, 0x00ff, 0x9186,
-	0x0002, 0x0180, 0x9186, 0x0028, 0x1118, 0xa87b, 0x001c, 0x0060,
-	0xd6dc, 0x0118, 0xa87b, 0x0015, 0x0038, 0xd6d4, 0x0118, 0xa87b,
-	0x0007, 0x0010, 0xa87b, 0x0000, 0xaf7e, 0xb080, 0xa882, 0xb084,
-	0xa886, 0x901e, 0xd6c4, 0x0190, 0x735c, 0xab86, 0x83ff, 0x0170,
+	0x9206, 0x1520, 0x700c, 0x6210, 0x00b6, 0x2258, 0xba14, 0x00be,
+	0x9206, 0x11e0, 0x6043, 0x0000, 0x2c68, 0x0016, 0x2009, 0x0035,
+	0x080c, 0xc3bc, 0x001e, 0x1158, 0x622c, 0x2268, 0x2071, 0x026c,
+	0x6b20, 0x9386, 0x0003, 0x0130, 0x9386, 0x0006, 0x0128, 0x080c,
+	0x9fd5, 0x0020, 0x0039, 0x0010, 0x080c, 0xa5fe, 0x002e, 0x00de,
+	0x00ee, 0x0005, 0x0096, 0x6814, 0x2048, 0x9186, 0x0015, 0x0904,
+	0xa5e6, 0x918e, 0x0016, 0x1904, 0xa5fc, 0x700c, 0x908c, 0xff00,
+	0x9186, 0x1700, 0x0120, 0x9186, 0x0300, 0x1904, 0xa5c0, 0x89ff,
+	0x1138, 0x6800, 0x9086, 0x000f, 0x0904, 0xa5a3, 0x0804, 0xa5fa,
+	0x6808, 0x9086, 0xffff, 0x1904, 0xa5e8, 0xa87c, 0x9084, 0x0060,
+	0x9086, 0x0020, 0x1128, 0xa83c, 0xa940, 0x9105, 0x1904, 0xa5e8,
+	0x6824, 0xd084, 0x1904, 0xa5e8, 0xd0b4, 0x0158, 0x0016, 0x2001,
+	0x1960, 0x200c, 0x6018, 0x9102, 0x9082, 0x0005, 0x001e, 0x1a04,
+	0xa5e8, 0x080c, 0xbf26, 0x685c, 0xa882, 0xa87c, 0xc0dc, 0xc0f4,
+	0xc0d4, 0xa87e, 0x0026, 0x900e, 0x6a18, 0x2001, 0x000a, 0x080c,
+	0x847f, 0xa884, 0x920a, 0x0208, 0x8011, 0xaa86, 0x82ff, 0x002e,
+	0x1138, 0x00c6, 0x2d60, 0x080c, 0xba68, 0x00ce, 0x0804, 0xa5fa,
+	0x00c6, 0xa868, 0xd0fc, 0x1118, 0x080c, 0x5eac, 0x0010, 0x080c,
+	0x625a, 0x00ce, 0x1904, 0xa5e8, 0x00c6, 0x2d60, 0x080c, 0x9fd5,
+	0x00ce, 0x0804, 0xa5fa, 0x00c6, 0x080c, 0xa026, 0x0198, 0x6017,
+	0x0000, 0x6810, 0x6012, 0x080c, 0xc1b7, 0x6023, 0x0003, 0x6904,
+	0x00c6, 0x2d60, 0x080c, 0x9fd5, 0x00ce, 0x080c, 0xa053, 0x00ce,
+	0x0804, 0xa5fa, 0x2001, 0x1962, 0x2004, 0x6842, 0x00ce, 0x04d0,
+	0x7008, 0x9086, 0x000b, 0x11c8, 0x6010, 0x00b6, 0x2058, 0xb900,
+	0xc1bc, 0xb902, 0x00be, 0x00c6, 0x2d60, 0xa87b, 0x0003, 0x080c,
+	0xc3fe, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002, 0x080c,
+	0x85f9, 0x080c, 0x8b90, 0x00ce, 0x00e8, 0x700c, 0x9086, 0x2a00,
+	0x1138, 0x2001, 0x1962, 0x2004, 0x6842, 0x00a0, 0x0479, 0x00a0,
+	0x89ff, 0x090c, 0x0e02, 0x00c6, 0x00d6, 0x2d60, 0xa867, 0x0103,
+	0xa87b, 0x0003, 0x080c, 0x683d, 0x080c, 0xbf26, 0x080c, 0xa007,
+	0x00de, 0x00ce, 0x080c, 0x9fd5, 0x009e, 0x0005, 0x9186, 0x0015,
+	0x1128, 0x2001, 0x1962, 0x2004, 0x6842, 0x0068, 0x918e, 0x0016,
+	0x1160, 0x00c6, 0x2d00, 0x2060, 0x080c, 0xda33, 0x080c, 0x8426,
+	0x080c, 0x9fd5, 0x00ce, 0x080c, 0x9fd5, 0x0005, 0x0026, 0x0036,
+	0x0046, 0x7228, 0xacb0, 0xabac, 0xd2f4, 0x0130, 0x2001, 0x1962,
+	0x2004, 0x6842, 0x0804, 0xa678, 0x00c6, 0x2d60, 0x080c, 0xb967,
+	0x00ce, 0x6804, 0x9086, 0x0050, 0x1168, 0x00c6, 0x2d00, 0x2060,
+	0x6003, 0x0001, 0x6007, 0x0050, 0x080c, 0x85f9, 0x080c, 0x8b90,
+	0x00ce, 0x04f0, 0x6800, 0x9086, 0x000f, 0x01a8, 0x89ff, 0x090c,
+	0x0e02, 0x6800, 0x9086, 0x0004, 0x1190, 0xa87c, 0xd0ac, 0x0178,
+	0xa843, 0x0fff, 0xa83f, 0x0fff, 0xa880, 0xc0fc, 0xa882, 0x2001,
+	0x0001, 0x6832, 0x0400, 0x2001, 0x0007, 0x6832, 0x00e0, 0xa87c,
+	0xd0b4, 0x1150, 0xd0ac, 0x0db8, 0x6824, 0xd0f4, 0x1d48, 0xa838,
+	0xa934, 0x9105, 0x0d80, 0x0c20, 0xd2ec, 0x1d68, 0x7024, 0x9306,
+	0x1118, 0x7020, 0x9406, 0x0d38, 0x7020, 0x683e, 0x7024, 0x683a,
+	0x2001, 0x0005, 0x6832, 0x080c, 0xc0ae, 0x080c, 0x8b90, 0x0010,
+	0x080c, 0x9fd5, 0x004e, 0x003e, 0x002e, 0x0005, 0x00e6, 0x00d6,
+	0x0026, 0x7008, 0x9084, 0x00ff, 0x6210, 0x00b6, 0x2258, 0xba10,
+	0x00be, 0x9206, 0x1904, 0xa6e3, 0x700c, 0x6210, 0x00b6, 0x2258,
+	0xba14, 0x00be, 0x9206, 0x1904, 0xa6e3, 0x6038, 0x2068, 0x6824,
+	0xc0dc, 0x6826, 0x6a20, 0x9286, 0x0007, 0x0904, 0xa6e3, 0x9286,
+	0x0002, 0x0904, 0xa6e3, 0x9286, 0x0000, 0x05e8, 0x6808, 0x633c,
+	0x9306, 0x15c8, 0x2071, 0x026c, 0x9186, 0x0015, 0x0570, 0x918e,
+	0x0016, 0x1100, 0x00c6, 0x6038, 0x2060, 0x6104, 0x9186, 0x004b,
+	0x01c0, 0x9186, 0x004c, 0x01a8, 0x9186, 0x004d, 0x0190, 0x9186,
+	0x004e, 0x0178, 0x9186, 0x0052, 0x0160, 0x6014, 0x0096, 0x2048,
+	0x080c, 0xbd3b, 0x090c, 0x0e02, 0xa87b, 0x0003, 0x009e, 0x080c,
+	0xc3fe, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002, 0x080c,
+	0x85f9, 0x080c, 0x8b90, 0x00ce, 0x0030, 0x6038, 0x2070, 0x2001,
+	0x1962, 0x2004, 0x7042, 0x080c, 0x9fd5, 0x002e, 0x00de, 0x00ee,
+	0x0005, 0x00b6, 0x0096, 0x00f6, 0x6014, 0x2048, 0x6010, 0x2058,
+	0x91b6, 0x0015, 0x0130, 0xba08, 0xbb0c, 0xbc00, 0xc48c, 0xbc02,
+	0x0460, 0x0096, 0x0156, 0x0036, 0x0026, 0x2b48, 0x9e90, 0x0010,
+	0x2019, 0x000a, 0x20a9, 0x0004, 0x080c, 0xb00b, 0x002e, 0x003e,
+	0x015e, 0x009e, 0x1904, 0xa752, 0x0096, 0x0156, 0x0036, 0x0026,
+	0x2b48, 0x9e90, 0x0014, 0x2019, 0x0006, 0x20a9, 0x0004, 0x080c,
+	0xb00b, 0x002e, 0x003e, 0x015e, 0x009e, 0x15a0, 0x7238, 0xba0a,
+	0x733c, 0xbb0e, 0xbc00, 0xc48d, 0xbc02, 0xa804, 0x9005, 0x1128,
+	0x00fe, 0x009e, 0x00be, 0x0804, 0xa3e0, 0x0096, 0x2048, 0xaa12,
+	0xab16, 0xac0a, 0x009e, 0x8006, 0x8006, 0x8007, 0x90bc, 0x003f,
+	0x9084, 0xffc0, 0x9080, 0x0002, 0x2009, 0x002b, 0xaaa0, 0xab9c,
+	0xaca8, 0xada4, 0x2031, 0x0000, 0x2041, 0x129a, 0x080c, 0xa4df,
+	0x0130, 0x00fe, 0x009e, 0x080c, 0x9fd5, 0x00be, 0x0005, 0x080c,
+	0xa995, 0x0cb8, 0x2b78, 0x00f6, 0x080c, 0x30ab, 0x080c, 0xc459,
+	0x00fe, 0x00c6, 0x080c, 0x9f7f, 0x2f00, 0x6012, 0x6017, 0x0000,
+	0x6023, 0x0001, 0x6007, 0x0001, 0x6003, 0x0001, 0x2001, 0x0007,
+	0x080c, 0x62f5, 0x080c, 0x6321, 0x080c, 0x8641, 0x080c, 0x8b90,
+	0x00ce, 0x0804, 0xa725, 0x2100, 0x91b2, 0x0053, 0x1a0c, 0x0e02,
+	0x91b2, 0x0040, 0x1a04, 0xa7db, 0x0002, 0xa7c9, 0xa7c9, 0xa7bf,
+	0xa7c9, 0xa7c9, 0xa7c9, 0xa7bd, 0xa7bd, 0xa7bd, 0xa7bd, 0xa7bd,
+	0xa7bd, 0xa7bd, 0xa7bd, 0xa7bd, 0xa7bd, 0xa7bd, 0xa7bd, 0xa7bd,
+	0xa7bd, 0xa7bd, 0xa7bd, 0xa7bd, 0xa7bd, 0xa7bd, 0xa7bd, 0xa7bd,
+	0xa7bd, 0xa7bd, 0xa7bd, 0xa7bd, 0xa7c9, 0xa7bd, 0xa7c9, 0xa7c9,
+	0xa7bd, 0xa7bd, 0xa7bd, 0xa7bd, 0xa7bd, 0xa7bf, 0xa7bd, 0xa7bd,
+	0xa7bd, 0xa7bd, 0xa7bd, 0xa7bd, 0xa7bd, 0xa7bd, 0xa7bd, 0xa7c9,
+	0xa7c9, 0xa7bd, 0xa7bd, 0xa7bd, 0xa7bd, 0xa7bd, 0xa7bd, 0xa7bd,
+	0xa7bd, 0xa7bd, 0xa7c9, 0xa7bd, 0xa7bd, 0x080c, 0x0e02, 0x0066,
+	0x00b6, 0x6610, 0x2658, 0xb8bc, 0xc08c, 0xb8be, 0x00be, 0x006e,
+	0x0000, 0x6003, 0x0001, 0x6106, 0x9186, 0x0032, 0x0118, 0x080c,
+	0x8641, 0x0010, 0x080c, 0x85f9, 0x0126, 0x2091, 0x8000, 0x080c,
+	0x8b90, 0x012e, 0x0005, 0x2600, 0x0002, 0xa7ef, 0xa7ef, 0xa7ef,
+	0xa7c9, 0xa7c9, 0xa7ef, 0xa7ef, 0xa7ef, 0xa7ef, 0xa7c9, 0xa7ef,
+	0xa7c9, 0xa7ef, 0xa7c9, 0xa7ef, 0xa7ef, 0xa7ef, 0xa7ef, 0x080c,
+	0x0e02, 0x6004, 0x90b2, 0x0053, 0x1a0c, 0x0e02, 0x91b6, 0x0013,
+	0x0904, 0xa8c4, 0x91b6, 0x0027, 0x1904, 0xa86e, 0x080c, 0x8a84,
+	0x6004, 0x080c, 0xbf32, 0x01b0, 0x080c, 0xbf43, 0x01a8, 0x908e,
+	0x0021, 0x0904, 0xa86b, 0x908e, 0x0022, 0x1130, 0x080c, 0xa40c,
+	0x0904, 0xa867, 0x0804, 0xa868, 0x908e, 0x003d, 0x0904, 0xa86b,
+	0x0804, 0xa861, 0x080c, 0x30d4, 0x2001, 0x0007, 0x080c, 0x62f5,
+	0x6010, 0x00b6, 0x2058, 0xb9a0, 0x00be, 0x080c, 0xa995, 0x9186,
+	0x007e, 0x1148, 0x2001, 0x1836, 0x2014, 0xc285, 0x080c, 0x717f,
+	0x1108, 0xc2ad, 0x2202, 0x0036, 0x0026, 0x2019, 0x0028, 0x2110,
+	0x080c, 0xda8f, 0x002e, 0x003e, 0x0016, 0x0026, 0x0036, 0x2110,
+	0x2019, 0x0028, 0x080c, 0x8783, 0x0076, 0x903e, 0x080c, 0x8671,
+	0x6010, 0x00b6, 0x905d, 0x0100, 0x00be, 0x2c08, 0x080c, 0xd53b,
+	0x007e, 0x003e, 0x002e, 0x001e, 0x080c, 0xc459, 0x0016, 0x080c,
+	0xc1af, 0x080c, 0x9fd5, 0x001e, 0x080c, 0x31a6, 0x080c, 0x8b90,
+	0x0030, 0x080c, 0xc1af, 0x080c, 0x9fd5, 0x080c, 0x8b90, 0x0005,
+	0x080c, 0xa995, 0x0cb0, 0x080c, 0xa9d1, 0x0c98, 0x9186, 0x0015,
+	0x0118, 0x9186, 0x0016, 0x1148, 0x080c, 0xc46a, 0x0d80, 0x6000,
+	0x9086, 0x0002, 0x0904, 0xa9dc, 0x0c50, 0x9186, 0x0014, 0x1d38,
+	0x080c, 0x8a84, 0x6004, 0x908e, 0x0022, 0x1118, 0x080c, 0xa40c,
+	0x09f0, 0x080c, 0x30ab, 0x080c, 0xc459, 0x080c, 0xbf32, 0x1198,
+	0x080c, 0x30d4, 0x6010, 0x00b6, 0x2058, 0xb9a0, 0x00be, 0x080c,
+	0xa995, 0x9186, 0x007e, 0x1128, 0x2001, 0x1836, 0x200c, 0xc185,
+	0x2102, 0x0804, 0xa861, 0x080c, 0xbf43, 0x1120, 0x080c, 0xa995,
+	0x0804, 0xa861, 0x6004, 0x908e, 0x0032, 0x1160, 0x00e6, 0x00f6,
+	0x2071, 0x189c, 0x2079, 0x0000, 0x080c, 0x343a, 0x00fe, 0x00ee,
+	0x0804, 0xa861, 0x6004, 0x908e, 0x0021, 0x0d40, 0x908e, 0x0022,
+	0x090c, 0xa995, 0x0804, 0xa861, 0x90b2, 0x0040, 0x1a04, 0xa97e,
+	0x2008, 0x0002, 0xa90c, 0xa90d, 0xa910, 0xa913, 0xa916, 0xa923,
+	0xa90a, 0xa90a, 0xa90a, 0xa90a, 0xa90a, 0xa90a, 0xa90a, 0xa90a,
+	0xa90a, 0xa90a, 0xa90a, 0xa90a, 0xa90a, 0xa90a, 0xa90a, 0xa90a,
+	0xa90a, 0xa90a, 0xa90a, 0xa90a, 0xa90a, 0xa90a, 0xa90a, 0xa90a,
+	0xa926, 0xa933, 0xa90a, 0xa935, 0xa933, 0xa90a, 0xa90a, 0xa90a,
+	0xa90a, 0xa90a, 0xa933, 0xa933, 0xa90a, 0xa90a, 0xa90a, 0xa90a,
+	0xa90a, 0xa90a, 0xa90a, 0xa90a, 0xa965, 0xa933, 0xa90a, 0xa92f,
+	0xa90a, 0xa90a, 0xa90a, 0xa930, 0xa90a, 0xa90a, 0xa90a, 0xa933,
+	0xa95c, 0xa90a, 0x080c, 0x0e02, 0x0430, 0x2001, 0x000b, 0x0470,
+	0x2001, 0x0003, 0x0458, 0x2001, 0x0005, 0x0440, 0x6010, 0x00b6,
+	0x2058, 0xb804, 0x00be, 0x9084, 0x00ff, 0x9086, 0x0000, 0x1500,
+	0x2001, 0x0001, 0x00d8, 0x2001, 0x0009, 0x00c0, 0x080c, 0x8a84,
+	0x6003, 0x0005, 0x080c, 0xc45c, 0x080c, 0x8b90, 0x0070, 0x0018,
+	0x0010, 0x080c, 0x62f5, 0x0804, 0xa976, 0x080c, 0x8a84, 0x080c,
+	0xc45c, 0x6003, 0x0004, 0x080c, 0x8b90, 0x0005, 0x080c, 0x62f5,
+	0x080c, 0x8a84, 0x6003, 0x0002, 0x0036, 0x2019, 0x1866, 0x2304,
+	0x9084, 0xff00, 0x1120, 0x2001, 0x1960, 0x201c, 0x0040, 0x8007,
+	0x909a, 0x0004, 0x0ec0, 0x8003, 0x801b, 0x831b, 0x9318, 0x631a,
+	0x003e, 0x080c, 0x8b90, 0x0c08, 0x080c, 0x8a84, 0x080c, 0xc1af,
+	0x080c, 0x9fd5, 0x080c, 0x8b90, 0x08c0, 0x00e6, 0x00f6, 0x2071,
+	0x189c, 0x2079, 0x0000, 0x080c, 0x343a, 0x00fe, 0x00ee, 0x080c,
+	0x8a84, 0x080c, 0x9fd5, 0x080c, 0x8b90, 0x0838, 0x080c, 0x8a84,
+	0x6003, 0x0002, 0x080c, 0xc45c, 0x0804, 0x8b90, 0x2600, 0x2008,
+	0x0002, 0xa993, 0xa993, 0xa993, 0xa976, 0xa976, 0xa993, 0xa993,
+	0xa993, 0xa993, 0xa976, 0xa993, 0xa976, 0xa993, 0xa976, 0xa993,
+	0xa993, 0xa993, 0xa993, 0x080c, 0x0e02, 0x00e6, 0x0096, 0x0026,
+	0x0016, 0x080c, 0xbd3b, 0x0568, 0x6014, 0x2048, 0xa864, 0x9086,
+	0x0139, 0x11a8, 0xa894, 0x9086, 0x0056, 0x1148, 0x080c, 0x5276,
+	0x0130, 0x2001, 0x0000, 0x900e, 0x2011, 0x4000, 0x0028, 0x2001,
+	0x0030, 0x900e, 0x2011, 0x4005, 0x080c, 0xc320, 0x0090, 0xa868,
+	0xd0fc, 0x0178, 0xa807, 0x0000, 0x0016, 0x6004, 0x908e, 0x0021,
+	0x0168, 0x908e, 0x003d, 0x0150, 0x001e, 0xa867, 0x0103, 0xa833,
+	0x0100, 0x001e, 0x002e, 0x009e, 0x00ee, 0x0005, 0x001e, 0x0009,
+	0x0cc0, 0x0096, 0x6014, 0x2048, 0xa800, 0x2048, 0xa867, 0x0103,
+	0xa823, 0x8001, 0x009e, 0x0005, 0x00b6, 0x6610, 0x2658, 0xb804,
+	0x9084, 0x00ff, 0x90b2, 0x000c, 0x1a0c, 0x0e02, 0x6604, 0x96b6,
+	0x004d, 0x1120, 0x080c, 0xc23f, 0x0804, 0xaa59, 0x6604, 0x96b6,
+	0x0043, 0x1120, 0x080c, 0xc288, 0x0804, 0xaa59, 0x6604, 0x96b6,
+	0x004b, 0x1120, 0x080c, 0xc2b4, 0x0804, 0xaa59, 0x6604, 0x96b6,
+	0x0033, 0x1120, 0x080c, 0xc1d1, 0x0804, 0xaa59, 0x6604, 0x96b6,
+	0x0028, 0x1120, 0x080c, 0xbf81, 0x0804, 0xaa59, 0x6604, 0x96b6,
+	0x0029, 0x1120, 0x080c, 0xbfc2, 0x0804, 0xaa59, 0x6604, 0x96b6,
+	0x001f, 0x1118, 0x080c, 0xa3b1, 0x04e0, 0x6604, 0x96b6, 0x0000,
+	0x1118, 0x080c, 0xa6e9, 0x04a8, 0x6604, 0x96b6, 0x0022, 0x1118,
+	0x080c, 0xa3ed, 0x0470, 0x6604, 0x96b6, 0x0035, 0x1118, 0x080c,
+	0xa4fd, 0x0438, 0x6604, 0x96b6, 0x0039, 0x1118, 0x080c, 0xa67e,
+	0x0400, 0x6604, 0x96b6, 0x003d, 0x1118, 0x080c, 0xa425, 0x00c8,
+	0x6604, 0x96b6, 0x0044, 0x1118, 0x080c, 0xa461, 0x0090, 0x6604,
+	0x96b6, 0x0049, 0x1118, 0x080c, 0xa48c, 0x0058, 0x91b6, 0x0015,
+	0x1110, 0x0063, 0x0030, 0x91b6, 0x0016, 0x1128, 0x00be, 0x0804,
+	0xad3f, 0x00be, 0x0005, 0x080c, 0xa06e, 0x0cd8, 0xaa76, 0xaa84,
+	0xaa76, 0xaac8, 0xaa76, 0xac67, 0xad4c, 0xaa76, 0xaa76, 0xad19,
+	0xaa76, 0xad2d, 0x0096, 0x080c, 0x1583, 0x6014, 0x2048, 0xa800,
+	0x2048, 0xa867, 0x0103, 0x009e, 0x0804, 0x9fd5, 0xa001, 0xa001,
+	0x0005, 0x6604, 0x96b6, 0x0004, 0x1130, 0x2001, 0x0001, 0x080c,
+	0x62e1, 0x0804, 0x9fd5, 0x0005, 0x00e6, 0x2071, 0x1800, 0x708c,
+	0x9086, 0x0074, 0x1540, 0x080c, 0xd50c, 0x11b0, 0x6010, 0x00b6,
+	0x2058, 0x7030, 0xd08c, 0x0128, 0xb800, 0xd0bc, 0x0110, 0xc0c5,
+	0xb802, 0x00e9, 0x00be, 0x2001, 0x0006, 0x080c, 0x62f5, 0x080c,
+	0x30d4, 0x080c, 0x9fd5, 0x0088, 0x2001, 0x000a, 0x080c, 0x62f5,
+	0x080c, 0x30d4, 0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x8641,
+	0x080c, 0x8b90, 0x0010, 0x080c, 0xac52, 0x00ee, 0x0005, 0x00d6,
+	0xb800, 0xd084, 0x0158, 0x9006, 0x080c, 0x62e1, 0x2069, 0x185b,
+	0x6804, 0x0020, 0x2001, 0x0006, 0x080c, 0x6321, 0x00de, 0x0005,
+	0x00b6, 0x0096, 0x00d6, 0x2011, 0x1823, 0x2204, 0x9086, 0x0074,
+	0x1904, 0xac29, 0x6010, 0x2058, 0xbaa0, 0x9286, 0x007e, 0x1120,
+	0x080c, 0xae91, 0x0804, 0xab8b, 0x00d6, 0x080c, 0x717f, 0x01a0,
+	0x0026, 0x2011, 0x0010, 0x080c, 0x66ee, 0x002e, 0x0904, 0xab2c,
+	0x080c, 0x54f0, 0x1598, 0x6014, 0x2048, 0xa807, 0x0000, 0xa867,
+	0x0103, 0xa833, 0xdead, 0x0450, 0x6010, 0x00b6, 0x2058, 0xb910,
+	0x00be, 0x9186, 0x00ff, 0x0580, 0x0026, 0x2011, 0x8008, 0x080c,
+	0x66ee, 0x002e, 0x0548, 0x6014, 0x9005, 0x090c, 0x0e02, 0x2048,
+	0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, 0x1140, 0x2001, 0x0030,
+	0x900e, 0x2011, 0x4009, 0x080c, 0xc320, 0x0040, 0x6014, 0x2048,
+	0xa807, 0x0000, 0xa867, 0x0103, 0xa833, 0xdead, 0x6010, 0x2058,
+	0xb9a0, 0x0016, 0x080c, 0x30d4, 0x080c, 0x9fd5, 0x001e, 0x080c,
+	0x31a6, 0x00de, 0x0804, 0xac2c, 0x00de, 0x080c, 0xae86, 0x6010,
+	0x2058, 0xbaa0, 0x9286, 0x0080, 0x1510, 0x6014, 0x9005, 0x01a8,
+	0x2048, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, 0x1140, 0x2001,
+	0x0000, 0x900e, 0x2011, 0x4000, 0x080c, 0xc320, 0x0030, 0xa807,
+	0x0000, 0xa867, 0x0103, 0xa833, 0x0200, 0x2001, 0x0006, 0x080c,
+	0x62f5, 0x080c, 0x30d4, 0x080c, 0x9fd5, 0x0804, 0xac2c, 0x080c,
+	0xac3a, 0x6014, 0x9005, 0x0190, 0x2048, 0xa868, 0xd0f4, 0x01e8,
+	0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, 0x1d08, 0x2001, 0x0000,
+	0x900e, 0x2011, 0x4000, 0x080c, 0xc320, 0x08f8, 0x080c, 0xac30,
+	0x0160, 0x9006, 0x080c, 0x62e1, 0x2001, 0x0004, 0x080c, 0x6321,
+	0x2001, 0x0007, 0x080c, 0x62f5, 0x08a0, 0x2001, 0x0004, 0x080c,
+	0x62f5, 0x6003, 0x0001, 0x6007, 0x0003, 0x080c, 0x8641, 0x080c,
+	0x8b90, 0x0804, 0xac2c, 0xb85c, 0xd0e4, 0x01d0, 0x080c, 0xc151,
+	0x080c, 0x717f, 0x0118, 0xd0dc, 0x1904, 0xab4d, 0x2011, 0x1836,
+	0x2204, 0xc0ad, 0x2012, 0x2001, 0x0002, 0x00f6, 0x2079, 0x0100,
+	0x78e3, 0x0000, 0x080c, 0x26e2, 0x78e2, 0x00fe, 0x0804, 0xab4d,
+	0x080c, 0xc18e, 0x2011, 0x1836, 0x2204, 0xc0a5, 0x2012, 0x0006,
+	0x080c, 0xd666, 0x000e, 0x1904, 0xab4d, 0xc0b5, 0x2012, 0x2001,
+	0x0006, 0x080c, 0x62f5, 0x9006, 0x080c, 0x62e1, 0x00c6, 0x2001,
+	0x180f, 0x2004, 0xd09c, 0x0520, 0x00f6, 0x2079, 0x0100, 0x00e6,
+	0x2071, 0x1800, 0x700c, 0x9084, 0x00ff, 0x78e6, 0x707a, 0x7010,
+	0x78ea, 0x707e, 0x908c, 0x00ff, 0x00ee, 0x780c, 0xc0b5, 0x780e,
+	0x00fe, 0x080c, 0x26b7, 0x00f6, 0x2100, 0x900e, 0x080c, 0x266e,
+	0x795a, 0x00fe, 0x9186, 0x0081, 0x01f0, 0x2009, 0x0081, 0x00e0,
+	0x2009, 0x00ef, 0x00f6, 0x2079, 0x0100, 0x79ea, 0x78e7, 0x0000,
+	0x7932, 0x7936, 0x780c, 0xc0b5, 0x780e, 0x00fe, 0x080c, 0x26b7,
+	0x00f6, 0x2079, 0x1800, 0x797e, 0x2100, 0x900e, 0x797a, 0x080c,
+	0x266e, 0x795a, 0x00fe, 0x8108, 0x080c, 0x6344, 0x2b00, 0x00ce,
+	0x1904, 0xab4d, 0x6012, 0x2009, 0x180f, 0x210c, 0xd19c, 0x0150,
+	0x2009, 0x027c, 0x210c, 0x918c, 0x00ff, 0xb912, 0x2009, 0x027d,
+	0x210c, 0xb916, 0x2001, 0x0002, 0x080c, 0x62f5, 0x6023, 0x0001,
+	0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x8641, 0x080c, 0x8b90,
+	0x0018, 0x080c, 0xa995, 0x0431, 0x00de, 0x009e, 0x00be, 0x0005,
+	0x2001, 0x1810, 0x2004, 0xd0a4, 0x0120, 0x2001, 0x185c, 0x2004,
+	0xd0ac, 0x0005, 0x00e6, 0x080c, 0xdae8, 0x0190, 0x2071, 0x0260,
+	0x7108, 0x720c, 0x918c, 0x00ff, 0x1118, 0x9284, 0xff00, 0x0140,
+	0x6010, 0x2058, 0xb8a0, 0x9084, 0xff80, 0x1110, 0xb912, 0xba16,
+	0x00ee, 0x0005, 0x2030, 0x2001, 0x0007, 0x080c, 0x62f5, 0x080c,
+	0x54f0, 0x1120, 0x2001, 0x0007, 0x080c, 0x6321, 0x080c, 0x30d4,
+	0x6020, 0x9086, 0x000a, 0x1108, 0x0005, 0x0804, 0x9fd5, 0x00b6,
+	0x00e6, 0x0026, 0x0016, 0x2071, 0x1800, 0x708c, 0x9086, 0x0014,
+	0x1904, 0xad10, 0x00d6, 0x080c, 0x717f, 0x01a0, 0x0026, 0x2011,
+	0x0010, 0x080c, 0x66ee, 0x002e, 0x0904, 0xacc2, 0x080c, 0x54f0,
+	0x1598, 0x6014, 0x2048, 0xa807, 0x0000, 0xa867, 0x0103, 0xa833,
+	0xdead, 0x0450, 0x6010, 0x00b6, 0x2058, 0xb910, 0x00be, 0x9186,
+	0x00ff, 0x0580, 0x0026, 0x2011, 0x8008, 0x080c, 0x66ee, 0x002e,
+	0x0548, 0x6014, 0x9005, 0x090c, 0x0e02, 0x2048, 0xa864, 0x9084,
+	0x00ff, 0x9086, 0x0039, 0x1140, 0x2001, 0x0030, 0x900e, 0x2011,
+	0x4009, 0x080c, 0xc320, 0x0040, 0x6014, 0x2048, 0xa807, 0x0000,
+	0xa867, 0x0103, 0xa833, 0xdead, 0x6010, 0x2058, 0xb9a0, 0x0016,
+	0x080c, 0x30d4, 0x080c, 0x9fd5, 0x001e, 0x080c, 0x31a6, 0x00de,
+	0x0804, 0xad14, 0x00de, 0x080c, 0x54f0, 0x1170, 0x6014, 0x9005,
+	0x1158, 0x0036, 0x0046, 0x6010, 0x2058, 0xbba0, 0x2021, 0x0006,
+	0x080c, 0x4bb5, 0x004e, 0x003e, 0x00d6, 0x6010, 0x2058, 0x080c,
+	0x643f, 0x080c, 0xaab7, 0x00de, 0x080c, 0xaf57, 0x1588, 0x6010,
+	0x2058, 0xb890, 0x9005, 0x0560, 0x2001, 0x0006, 0x080c, 0x62f5,
+	0x0096, 0x6014, 0x904d, 0x01d0, 0xa864, 0x9084, 0x00ff, 0x9086,
+	0x0039, 0x1140, 0x2001, 0x0000, 0x900e, 0x2011, 0x4000, 0x080c,
+	0xc320, 0x0060, 0xa864, 0x9084, 0x00ff, 0x9086, 0x0029, 0x0130,
+	0xa807, 0x0000, 0xa867, 0x0103, 0xa833, 0x0200, 0x009e, 0x080c,
+	0x30d4, 0x6020, 0x9086, 0x000a, 0x0138, 0x080c, 0x9fd5, 0x0020,
+	0x080c, 0xa995, 0x080c, 0xac52, 0x001e, 0x002e, 0x00ee, 0x00be,
+	0x0005, 0x2011, 0x1823, 0x2204, 0x9086, 0x0014, 0x1160, 0x2001,
+	0x0002, 0x080c, 0x62f5, 0x6003, 0x0001, 0x6007, 0x0001, 0x080c,
+	0x8641, 0x0804, 0x8b90, 0x0804, 0xac52, 0x2030, 0x2011, 0x1823,
+	0x2204, 0x9086, 0x0004, 0x1148, 0x96b6, 0x000b, 0x1120, 0x2001,
+	0x0007, 0x080c, 0x62f5, 0x0804, 0x9fd5, 0x0804, 0xac52, 0x0002,
+	0xaa76, 0xad57, 0xaa76, 0xad98, 0xaa76, 0xae43, 0xad4c, 0xaa79,
+	0xaa76, 0xae55, 0xaa76, 0xae65, 0x6604, 0x9686, 0x0003, 0x0904,
+	0xac67, 0x96b6, 0x001e, 0x1110, 0x080c, 0x9fd5, 0x0005, 0x00b6,
+	0x00d6, 0x00c6, 0x080c, 0xae75, 0x11a0, 0x9006, 0x080c, 0x62e1,
+	0x080c, 0x30ab, 0x080c, 0xc459, 0x2001, 0x0002, 0x080c, 0x62f5,
+	0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x8641, 0x080c, 0x8b90,
+	0x0418, 0x2009, 0x026e, 0x2104, 0x9086, 0x0009, 0x1160, 0x6010,
+	0x2058, 0xb840, 0x9084, 0x00ff, 0x9005, 0x0180, 0x8001, 0xb842,
+	0x601b, 0x000a, 0x0088, 0x2009, 0x026f, 0x2104, 0x9084, 0xff00,
+	0x908e, 0x1900, 0x0148, 0x908e, 0x1e00, 0x0990, 0x080c, 0x30ab,
+	0x080c, 0xc459, 0x080c, 0xac52, 0x00ce, 0x00de, 0x00be, 0x0005,
+	0x0096, 0x00b6, 0x0026, 0x9016, 0x080c, 0xae83, 0x00d6, 0x2069,
+	0x1956, 0x2d04, 0x9005, 0x0168, 0x6010, 0x2058, 0xb8a0, 0x9086,
+	0x007e, 0x1138, 0x2069, 0x181f, 0x2d04, 0x8000, 0x206a, 0x00de,
+	0x0010, 0x00de, 0x0088, 0x9006, 0x080c, 0x62e1, 0x2001, 0x0002,
+	0x080c, 0x62f5, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x8641,
+	0x080c, 0x8b90, 0x0804, 0xae13, 0x080c, 0xbd3b, 0x01b0, 0x6014,
+	0x2048, 0xa864, 0x2010, 0x9086, 0x0139, 0x1138, 0x6007, 0x0016,
+	0x2001, 0x0002, 0x080c, 0xc37d, 0x00b0, 0x6014, 0x2048, 0xa864,
+	0xd0fc, 0x0118, 0x2001, 0x0001, 0x0ca8, 0x2001, 0x180e, 0x2004,
+	0xd0dc, 0x0148, 0x6010, 0x2058, 0xb840, 0x9084, 0x00ff, 0x9005,
+	0x1110, 0x9006, 0x0c38, 0x080c, 0xa995, 0x2009, 0x026e, 0x2134,
+	0x96b4, 0x00ff, 0x9686, 0x0005, 0x0510, 0x9686, 0x000b, 0x01c8,
+	0x2009, 0x026f, 0x2104, 0x9084, 0xff00, 0x1118, 0x9686, 0x0009,
+	0x01b0, 0x9086, 0x1900, 0x1168, 0x9686, 0x0009, 0x0180, 0x2001,
+	0x0004, 0x080c, 0x62f5, 0x2001, 0x0028, 0x601a, 0x6007, 0x0052,
+	0x0010, 0x080c, 0xac52, 0x002e, 0x00be, 0x009e, 0x0005, 0x9286,
+	0x0139, 0x0160, 0x6014, 0x2048, 0x080c, 0xbd3b, 0x0140, 0xa864,
+	0x9086, 0x0139, 0x0118, 0xa868, 0xd0fc, 0x0108, 0x0c50, 0x6010,
+	0x2058, 0xb840, 0x9084, 0x00ff, 0x9005, 0x0138, 0x8001, 0xb842,
+	0x601b, 0x000a, 0x6007, 0x0016, 0x08f0, 0xb8a0, 0x9086, 0x007e,
+	0x1138, 0x00e6, 0x2071, 0x1800, 0x080c, 0x5dc3, 0x00ee, 0x0010,
+	0x080c, 0x30ab, 0x0870, 0x2001, 0x0004, 0x080c, 0x62f5, 0x04d9,
+	0x1140, 0x6003, 0x0001, 0x6007, 0x0003, 0x080c, 0x8641, 0x0804,
+	0x8b90, 0x080c, 0xa995, 0x0804, 0xac52, 0x0469, 0x1160, 0x2001,
+	0x0008, 0x080c, 0x62f5, 0x6003, 0x0001, 0x6007, 0x0005, 0x080c,
+	0x8641, 0x0804, 0x8b90, 0x0804, 0xac52, 0x00e9, 0x1160, 0x2001,
+	0x000a, 0x080c, 0x62f5, 0x6003, 0x0001, 0x6007, 0x0001, 0x080c,
+	0x8641, 0x0804, 0x8b90, 0x0804, 0xac52, 0x2009, 0x026e, 0x2104,
+	0x9086, 0x0003, 0x1138, 0x2009, 0x026f, 0x2104, 0x9084, 0xff00,
+	0x9086, 0x2a00, 0x0005, 0x9085, 0x0001, 0x0005, 0x00b6, 0x00c6,
+	0x0016, 0x6110, 0x2158, 0x080c, 0x63b3, 0x001e, 0x00ce, 0x00be,
+	0x0005, 0x00b6, 0x00f6, 0x00e6, 0x00d6, 0x0036, 0x0016, 0x6010,
+	0x2058, 0x2009, 0x1836, 0x2104, 0x9085, 0x0003, 0x200a, 0x080c,
+	0xaf29, 0x0560, 0x2009, 0x1836, 0x2104, 0xc0cd, 0x200a, 0x080c,
+	0x66c6, 0x0158, 0x9006, 0x2020, 0x2009, 0x002a, 0x080c, 0xd7d6,
+	0x2001, 0x180c, 0x200c, 0xc195, 0x2102, 0x2019, 0x002a, 0x2009,
+	0x0001, 0x080c, 0x3076, 0x00e6, 0x2071, 0x1800, 0x080c, 0x2e8c,
+	0x00ee, 0x00c6, 0x0156, 0x20a9, 0x0781, 0x2009, 0x007f, 0x080c,
+	0x31a6, 0x8108, 0x1f04, 0xaec7, 0x015e, 0x00ce, 0x080c, 0xae86,
+	0x2071, 0x0260, 0x2079, 0x0200, 0x7817, 0x0001, 0x2001, 0x1836,
+	0x200c, 0xc1c5, 0x7018, 0xd0fc, 0x0110, 0xd0dc, 0x0118, 0x7038,
+	0xd0dc, 0x1108, 0xc1c4, 0x7817, 0x0000, 0x2001, 0x1836, 0x2102,
+	0x2079, 0x0100, 0x2e04, 0x9084, 0x00ff, 0x2069, 0x181e, 0x206a,
+	0x78e6, 0x0006, 0x8e70, 0x2e04, 0x2069, 0x181f, 0x206a, 0x78ea,
+	0x7832, 0x7836, 0x2010, 0x9084, 0xff00, 0x001e, 0x9105, 0x2009,
+	0x182b, 0x200a, 0x2200, 0x9084, 0x00ff, 0x2008, 0x080c, 0x26b7,
+	0x080c, 0x717f, 0x0170, 0x2071, 0x0260, 0x2069, 0x195c, 0x7048,
+	0x206a, 0x704c, 0x6806, 0x7050, 0x680a, 0x7054, 0x680e, 0x080c,
+	0xc151, 0x0040, 0x2001, 0x0006, 0x080c, 0x62f5, 0x080c, 0x30d4,
+	0x080c, 0x9fd5, 0x001e, 0x003e, 0x00de, 0x00ee, 0x00fe, 0x00be,
+	0x0005, 0x0096, 0x0026, 0x0036, 0x00e6, 0x0156, 0x2019, 0x182b,
+	0x231c, 0x83ff, 0x01f0, 0x2071, 0x0260, 0x7200, 0x9294, 0x00ff,
+	0x7004, 0x9084, 0xff00, 0x9205, 0x9306, 0x1198, 0x2011, 0x0276,
+	0x20a9, 0x0004, 0x2b48, 0x2019, 0x000a, 0x080c, 0xb00b, 0x1148,
+	0x2011, 0x027a, 0x20a9, 0x0004, 0x2019, 0x0006, 0x080c, 0xb00b,
+	0x1100, 0x015e, 0x00ee, 0x003e, 0x002e, 0x009e, 0x0005, 0x00e6,
+	0x2071, 0x0260, 0x7034, 0x9086, 0x0014, 0x11a8, 0x7038, 0x9086,
+	0x0800, 0x1188, 0x703c, 0xd0ec, 0x0160, 0x9084, 0x0f00, 0x9086,
+	0x0100, 0x1138, 0x7054, 0xd0a4, 0x1110, 0xd0ac, 0x0110, 0x9006,
+	0x0010, 0x9085, 0x0001, 0x00ee, 0x0005, 0x00e6, 0x0096, 0x00c6,
+	0x0076, 0x0056, 0x0046, 0x0026, 0x0006, 0x0126, 0x2091, 0x8000,
+	0x2029, 0x19cb, 0x252c, 0x2021, 0x19d1, 0x2424, 0x2061, 0x1cd0,
+	0x2071, 0x1800, 0x7250, 0x7070, 0x9202, 0x1a04, 0xafe3, 0x080c,
+	0xd807, 0x0904, 0xafdc, 0x6720, 0x9786, 0x0007, 0x0904, 0xafdc,
+	0x2500, 0x9c06, 0x0904, 0xafdc, 0x2400, 0x9c06, 0x05e8, 0x3e08,
+	0x9186, 0x0002, 0x1148, 0x6010, 0x9005, 0x0130, 0x00b6, 0x2058,
+	0xb800, 0x00be, 0xd0bc, 0x1580, 0x00c6, 0x6000, 0x9086, 0x0004,
+	0x1110, 0x080c, 0x1938, 0x9786, 0x000a, 0x0148, 0x080c, 0xbf43,
+	0x1130, 0x00ce, 0x080c, 0xa995, 0x080c, 0xa007, 0x00e8, 0x6014,
+	0x2048, 0x080c, 0xbd3b, 0x01a8, 0x9786, 0x0003, 0x1530, 0xa867,
+	0x0103, 0xa87c, 0xd0cc, 0x0130, 0x0096, 0xa878, 0x2048, 0x080c,
+	0x0ff5, 0x009e, 0xab7a, 0xa877, 0x0000, 0x080c, 0x6a16, 0x080c,
+	0xbf26, 0x080c, 0xa007, 0x00ce, 0x9ce0, 0x0018, 0x7064, 0x9c02,
+	0x1210, 0x0804, 0xaf8a, 0x012e, 0x000e, 0x002e, 0x004e, 0x005e,
+	0x007e, 0x00ce, 0x009e, 0x00ee, 0x0005, 0x9786, 0x0006, 0x1118,
+	0x080c, 0xd781, 0x0c30, 0x9786, 0x000a, 0x09e0, 0x0880, 0x220c,
+	0x2304, 0x9106, 0x1130, 0x8210, 0x8318, 0x1f04, 0xaff7, 0x9006,
+	0x0005, 0x2304, 0x9102, 0x0218, 0x2001, 0x0001, 0x0008, 0x9006,
+	0x918d, 0x0001, 0x0005, 0x0136, 0x01c6, 0x0016, 0x8906, 0x8006,
+	0x8007, 0x908c, 0x003f, 0x21e0, 0x9084, 0xffc0, 0x9300, 0x2098,
+	0x3518, 0x20a9, 0x0001, 0x220c, 0x4002, 0x910e, 0x1140, 0x8210,
+	0x8319, 0x1dc8, 0x9006, 0x001e, 0x01ce, 0x013e, 0x0005, 0x220c,
+	0x9102, 0x0218, 0x2001, 0x0001, 0x0010, 0x2001, 0x0000, 0x918d,
+	0x0001, 0x001e, 0x01ce, 0x013e, 0x0005, 0x6004, 0x908a, 0x0053,
+	0x1a0c, 0x0e02, 0x080c, 0xbf32, 0x0120, 0x080c, 0xbf43, 0x0168,
+	0x0028, 0x080c, 0x30d4, 0x080c, 0xbf43, 0x0138, 0x080c, 0x8a84,
+	0x080c, 0x9fd5, 0x080c, 0x8b90, 0x0005, 0x080c, 0xa995, 0x0cb0,
+	0x9182, 0x0054, 0x1220, 0x9182, 0x0040, 0x0208, 0x000a, 0x0005,
+	0xb06c, 0xb06c, 0xb06c, 0xb06c, 0xb06c, 0xb06c, 0xb06c, 0xb06c,
+	0xb06c, 0xb06c, 0xb06c, 0xb06e, 0xb06e, 0xb06e, 0xb06e, 0xb06c,
+	0xb06c, 0xb06c, 0xb06e, 0xb06c, 0x080c, 0x0e02, 0x600b, 0xffff,
+	0x6003, 0x0001, 0x6106, 0x080c, 0x85f9, 0x0126, 0x2091, 0x8000,
+	0x080c, 0x8b90, 0x012e, 0x0005, 0x9186, 0x0013, 0x1128, 0x6004,
+	0x9082, 0x0040, 0x0804, 0xb106, 0x9186, 0x0027, 0x1520, 0x080c,
+	0x8a84, 0x080c, 0x30ab, 0x080c, 0xc459, 0x0096, 0x6114, 0x2148,
+	0x080c, 0xbd3b, 0x0198, 0x080c, 0xbf43, 0x1118, 0x080c, 0xa995,
+	0x0068, 0xa867, 0x0103, 0xa87b, 0x0029, 0xa877, 0x0000, 0xa97c,
+	0xc1c5, 0xa97e, 0x080c, 0x6a23, 0x080c, 0xbf26, 0x009e, 0x080c,
+	0x9fd5, 0x0804, 0x8b90, 0x9186, 0x0014, 0x1120, 0x6004, 0x9082,
+	0x0040, 0x00b8, 0x9186, 0x0046, 0x0150, 0x9186, 0x0045, 0x0138,
+	0x9186, 0x0053, 0x0120, 0x9186, 0x0048, 0x190c, 0x0e02, 0x080c,
+	0xc46a, 0x0130, 0x6000, 0x9086, 0x0002, 0x1110, 0x0804, 0xb144,
+	0x0005, 0x0002, 0xb0e0, 0xb0de, 0xb0de, 0xb0de, 0xb0de, 0xb0de,
+	0xb0de, 0xb0de, 0xb0de, 0xb0de, 0xb0de, 0xb0fb, 0xb0fb, 0xb0fb,
+	0xb0fb, 0xb0de, 0xb0fb, 0xb0de, 0xb0fb, 0xb0de, 0x080c, 0x0e02,
+	0x080c, 0x8a84, 0x0096, 0x6114, 0x2148, 0x080c, 0xbd3b, 0x0168,
+	0xa867, 0x0103, 0xa87b, 0x0006, 0xa877, 0x0000, 0xa880, 0xc0ec,
+	0xa882, 0x080c, 0x6a23, 0x080c, 0xbf26, 0x009e, 0x080c, 0x9fd5,
+	0x080c, 0x8b90, 0x0005, 0x080c, 0x8a84, 0x080c, 0xbf43, 0x090c,
+	0xa995, 0x080c, 0x9fd5, 0x080c, 0x8b90, 0x0005, 0x0002, 0xb11d,
+	0xb11b, 0xb11b, 0xb11b, 0xb11b, 0xb11b, 0xb11b, 0xb11b, 0xb11b,
+	0xb11b, 0xb11b, 0xb134, 0xb134, 0xb134, 0xb134, 0xb11b, 0xb13e,
+	0xb11b, 0xb134, 0xb11b, 0x080c, 0x0e02, 0x0096, 0x080c, 0x8a84,
+	0x6014, 0x2048, 0x2001, 0x1962, 0x2004, 0x6042, 0xa97c, 0xd1ac,
+	0x0140, 0x6003, 0x0004, 0xa87c, 0x9085, 0x0400, 0xa87e, 0x009e,
+	0x0005, 0x6003, 0x0002, 0x0cb8, 0x080c, 0x8a84, 0x080c, 0xc45c,
+	0x080c, 0xc461, 0x6003, 0x000f, 0x0804, 0x8b90, 0x080c, 0x8a84,
+	0x080c, 0x9fd5, 0x0804, 0x8b90, 0x9182, 0x0054, 0x1220, 0x9182,
+	0x0040, 0x0208, 0x000a, 0x0005, 0xb160, 0xb160, 0xb160, 0xb160,
+	0xb160, 0xb162, 0xb23f, 0xb160, 0xb273, 0xb160, 0xb160, 0xb160,
+	0xb160, 0xb160, 0xb160, 0xb160, 0xb160, 0xb160, 0xb160, 0xb273,
+	0x080c, 0x0e02, 0x00b6, 0x0096, 0x6114, 0x2148, 0x7644, 0x96b4,
+	0x0fff, 0x86ff, 0x1528, 0x6010, 0x2058, 0xb800, 0xd0bc, 0x1904,
+	0xb22e, 0xa87b, 0x0000, 0xa867, 0x0103, 0xae76, 0xa87c, 0xd0ac,
+	0x0128, 0xa834, 0xa938, 0x9115, 0x190c, 0xb40c, 0x080c, 0x683d,
+	0x6210, 0x2258, 0xba3c, 0x82ff, 0x0110, 0x8211, 0xba3e, 0x7044,
+	0xd0e4, 0x1904, 0xb212, 0x080c, 0x9fd5, 0x009e, 0x00be, 0x0005,
+	0x968c, 0x0c00, 0x0150, 0x6010, 0x2058, 0xb800, 0xd0bc, 0x1904,
+	0xb216, 0x7348, 0xab92, 0x734c, 0xab8e, 0x968c, 0x00ff, 0x9186,
+	0x0002, 0x0508, 0x9186, 0x0028, 0x1118, 0xa87b, 0x001c, 0x00e8,
+	0xd6dc, 0x01a0, 0xa87b, 0x0015, 0xa87c, 0xd0ac, 0x0170, 0xa938,
+	0xaa34, 0x2100, 0x9205, 0x0148, 0x7048, 0x9106, 0x1118, 0x704c,
+	0x9206, 0x0118, 0xa992, 0xaa8e, 0xc6dc, 0x0038, 0xd6d4, 0x0118,
+	0xa87b, 0x0007, 0x0010, 0xa87b, 0x0000, 0xa867, 0x0103, 0xae76,
+	0x901e, 0xd6c4, 0x01d8, 0x9686, 0x0100, 0x1130, 0x7064, 0x9005,
+	0x1118, 0xc6c4, 0x0804, 0xb169, 0x735c, 0xab86, 0x83ff, 0x0170,
 	0x938a, 0x0009, 0x0210, 0x2019, 0x0008, 0x0036, 0x2308, 0x2019,
-	0x0018, 0x2011, 0x0025, 0x080c, 0xb9e8, 0x003e, 0xd6cc, 0x01e8,
-	0x7154, 0xa98a, 0x81ff, 0x01c8, 0x9192, 0x0021, 0x1260, 0x8304,
-	0x9098, 0x0018, 0x2011, 0x0029, 0x080c, 0xb9e8, 0x2011, 0x0205,
-	0x2013, 0x0000, 0x0050, 0xb068, 0xd0fc, 0x0120, 0x2009, 0x0020,
-	0xa98a, 0x0c68, 0x2950, 0x080c, 0xb987, 0x009e, 0x00ee, 0x00ae,
-	0x007e, 0x0005, 0x00f6, 0x00a6, 0x6003, 0x0003, 0x2079, 0x026c,
-	0x7c04, 0x7b00, 0x7e0c, 0x7d08, 0x6014, 0x2050, 0xb436, 0xb33a,
-	0xb646, 0xb54a, 0x00ae, 0x00fe, 0x2c10, 0x080c, 0x1afe, 0x0804,
-	0x9623, 0x6003, 0x0002, 0x6004, 0x9086, 0x0040, 0x11c8, 0x0096,
-	0x6014, 0x2048, 0xa87c, 0xd0ac, 0x0160, 0x601c, 0xd084, 0x1130,
-	0x00f6, 0x2c00, 0x2078, 0x080c, 0x16db, 0x00fe, 0x6003, 0x0004,
-	0x0010, 0x6003, 0x0002, 0x009e, 0x080c, 0x8b04, 0x080c, 0x8c10,
-	0x0096, 0x2001, 0x1960, 0x2004, 0x6042, 0x080c, 0x8bc0, 0x080c,
-	0x8ced, 0x6114, 0x2148, 0xa97c, 0xd1e4, 0x0904, 0xb4ac, 0xd1cc,
-	0x05c8, 0xa978, 0xa868, 0xd0fc, 0x0540, 0x0016, 0xa87c, 0x0006,
-	0xa880, 0x0006, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0019, 0x20a0,
-	0x810e, 0x810e, 0x810f, 0x9184, 0x003f, 0x20e0, 0x9184, 0xffc0,
-	0x9080, 0x0019, 0x2098, 0x0156, 0x20a9, 0x0020, 0x4003, 0x015e,
-	0x000e, 0xa882, 0x000e, 0xc0cc, 0xa87e, 0x001e, 0xa874, 0x0006,
-	0x2148, 0x080c, 0x0fe3, 0x001e, 0x0458, 0x0016, 0x080c, 0x0fe3,
-	0x009e, 0xa87c, 0xc0cc, 0xa87e, 0xa974, 0x0016, 0x080c, 0xb9d8,
-	0x001e, 0x00f0, 0xa867, 0x0103, 0xa974, 0x9184, 0x00ff, 0x90b6,
-	0x0002, 0x0180, 0x9086, 0x0028, 0x1118, 0xa87b, 0x001c, 0x0060,
-	0xd1dc, 0x0118, 0xa87b, 0x0015, 0x0038, 0xd1d4, 0x0118, 0xa87b,
-	0x0007, 0x0010, 0xa87b, 0x0000, 0x0016, 0x080c, 0x6904, 0x001e,
-	0xd1e4, 0x1120, 0x080c, 0xa0e3, 0x009e, 0x0005, 0x080c, 0xc137,
-	0x0cd8, 0x6004, 0x9086, 0x0040, 0x1120, 0x080c, 0x8b04, 0x080c,
-	0x8c10, 0x2019, 0x0001, 0x080c, 0x999d, 0x6003, 0x0002, 0x080c,
-	0xc556, 0x080c, 0x8bc0, 0x080c, 0x8ced, 0x0005, 0x6004, 0x9086,
-	0x0040, 0x1120, 0x080c, 0x8b04, 0x080c, 0x8c10, 0x2019, 0x0001,
-	0x080c, 0x999d, 0x080c, 0x8bc0, 0x080c, 0x318b, 0x080c, 0xc54e,
-	0x0096, 0x6114, 0x2148, 0x080c, 0xbe37, 0x0150, 0xa867, 0x0103,
-	0xa87b, 0x0029, 0xa877, 0x0000, 0x080c, 0x6ae9, 0x080c, 0xc022,
-	0x009e, 0x080c, 0xa0e3, 0x080c, 0x8ced, 0x0005, 0xa87b, 0x0015,
-	0xd1fc, 0x0180, 0xa87b, 0x0007, 0x8002, 0x8000, 0x810a, 0x9189,
-	0x0000, 0x0006, 0x0016, 0x2009, 0x1a51, 0x2104, 0x8000, 0x200a,
-	0x001e, 0x000e, 0xa992, 0xa88e, 0x0005, 0x9182, 0x0054, 0x1220,
-	0x9182, 0x0040, 0x0208, 0x000a, 0x0005, 0xb521, 0xb521, 0xb521,
-	0xb521, 0xb521, 0xb523, 0xb521, 0xb521, 0xb5c9, 0xb521, 0xb521,
-	0xb521, 0xb521, 0xb521, 0xb521, 0xb521, 0xb521, 0xb521, 0xb521,
-	0xb6fb, 0x080c, 0x0dfa, 0x0076, 0x00a6, 0x00e6, 0x0096, 0x2071,
-	0x0260, 0x6114, 0x2150, 0x7644, 0xb676, 0x96b4, 0x0fff, 0xb77c,
-	0xc7e5, 0xb77e, 0x6210, 0x00b6, 0x2258, 0xba3c, 0x82ff, 0x0110,
-	0x8211, 0xba3e, 0x00be, 0x86ff, 0x0904, 0xb5c2, 0x9694, 0xff00,
-	0x9284, 0x0c00, 0x0120, 0x7048, 0xb092, 0x704c, 0xb08e, 0x9284,
-	0x0300, 0x0904, 0xb5c2, 0x9686, 0x0100, 0x1130, 0x7064, 0x9005,
-	0x1118, 0xc6c4, 0xb676, 0x0c38, 0x080c, 0x1031, 0x090c, 0x0dfa,
-	0x2900, 0xb07a, 0xb77c, 0x97bd, 0x0200, 0xb77e, 0xa867, 0x0103,
-	0xb068, 0xa86a, 0xb06c, 0xa86e, 0xb070, 0xa872, 0x7044, 0x9084,
-	0xf000, 0x9635, 0xae76, 0x968c, 0x0c00, 0x0120, 0x7348, 0xab92,
-	0x734c, 0xab8e, 0x968c, 0x00ff, 0x9186, 0x0002, 0x0180, 0x9186,
-	0x0028, 0x1118, 0xa87b, 0x001c, 0x0060, 0xd6dc, 0x0118, 0xa87b,
-	0x0015, 0x0038, 0xd6d4, 0x0118, 0xa87b, 0x0007, 0x0010, 0xa87b,
-	0x0000, 0xaf7e, 0xb080, 0xa882, 0xb084, 0xa886, 0x901e, 0xd6c4,
-	0x0190, 0x735c, 0xab86, 0x83ff, 0x0170, 0x938a, 0x0009, 0x0210,
-	0x2019, 0x0008, 0x0036, 0x2308, 0x2019, 0x0018, 0x2011, 0x0025,
-	0x080c, 0xb9e8, 0x003e, 0xd6cc, 0x01e8, 0x7154, 0xa98a, 0x81ff,
-	0x01c8, 0x9192, 0x0021, 0x1260, 0x8304, 0x9098, 0x0018, 0x2011,
-	0x0029, 0x080c, 0xb9e8, 0x2011, 0x0205, 0x2013, 0x0000, 0x0050,
-	0xb068, 0xd0fc, 0x0120, 0x2009, 0x0020, 0xa98a, 0x0c68, 0x2950,
-	0x080c, 0xb987, 0x080c, 0x1982, 0x009e, 0x00ee, 0x00ae, 0x007e,
-	0x0005, 0x2001, 0x1960, 0x2004, 0x6042, 0x0096, 0x6114, 0x2148,
-	0xa83c, 0xa940, 0x9105, 0x1118, 0xa87c, 0xc0dc, 0xa87e, 0x6003,
-	0x0002, 0xa97c, 0xd1e4, 0x0904, 0xb6f6, 0x6043, 0x0000, 0x6010,
-	0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x1500, 0xd1cc, 0x0904,
-	0xb6c5, 0xa978, 0xa868, 0xd0fc, 0x0904, 0xb686, 0x0016, 0xa87c,
-	0x0006, 0xa880, 0x0006, 0x00a6, 0x2150, 0xb174, 0x9184, 0x00ff,
-	0x90b6, 0x0002, 0x0904, 0xb653, 0x9086, 0x0028, 0x1904, 0xb63f,
-	0xa87b, 0x001c, 0xb07b, 0x001c, 0x0804, 0xb65b, 0x6024, 0xd0f4,
-	0x11d0, 0xa838, 0xaa34, 0x9205, 0x09c8, 0xa838, 0xaa90, 0x9206,
-	0x1120, 0xa88c, 0xaa34, 0x9206, 0x0988, 0x6024, 0xd0d4, 0x1148,
-	0xa9ac, 0xa834, 0x9102, 0x603a, 0xa9b0, 0xa838, 0x9103, 0x603e,
-	0x6024, 0xc0f5, 0x6026, 0x6010, 0x00b6, 0x2058, 0xb83c, 0x8000,
-	0xb83e, 0x00be, 0x9006, 0xa876, 0xa892, 0xa88e, 0xa87c, 0xc0e4,
-	0xa87e, 0xd0cc, 0x0140, 0xc0cc, 0xa87e, 0x0096, 0xa878, 0x2048,
-	0x080c, 0x0fe3, 0x009e, 0x080c, 0xc171, 0x0804, 0xb6f6, 0xd1dc,
-	0x0158, 0xa87b, 0x0015, 0xb07b, 0x0015, 0x080c, 0xc401, 0x0118,
-	0xb174, 0xc1dc, 0xb176, 0x0078, 0xd1d4, 0x0128, 0xa87b, 0x0007,
-	0xb07b, 0x0007, 0x0040, 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938,
-	0x9115, 0x190c, 0xb4ee, 0xa87c, 0xb07e, 0xa890, 0xb092, 0xa88c,
-	0xb08e, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0019, 0x20a0, 0x20a9,
-	0x0020, 0x8a06, 0x8006, 0x8007, 0x9094, 0x003f, 0x22e0, 0x9084,
-	0xffc0, 0x9080, 0x0019, 0x2098, 0x4003, 0x00ae, 0x000e, 0xa882,
-	0x000e, 0xc0cc, 0xa87e, 0x080c, 0xc4de, 0x001e, 0xa874, 0x0006,
-	0x2148, 0x080c, 0x0fe3, 0x001e, 0x0804, 0xb6f2, 0x0016, 0x00a6,
-	0x2150, 0xb174, 0x9184, 0x00ff, 0x90b6, 0x0002, 0x01e0, 0x9086,
-	0x0028, 0x1128, 0xa87b, 0x001c, 0xb07b, 0x001c, 0x00e0, 0xd1dc,
-	0x0158, 0xa87b, 0x0015, 0xb07b, 0x0015, 0x080c, 0xc401, 0x0118,
-	0xb174, 0xc1dc, 0xb176, 0x0078, 0xd1d4, 0x0128, 0xa87b, 0x0007,
-	0xb07b, 0x0007, 0x0040, 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938,
-	0x9115, 0x190c, 0xb4ee, 0xa890, 0xb092, 0xa88c, 0xb08e, 0xa87c,
-	0xb07e, 0x00ae, 0x080c, 0x0fe3, 0x009e, 0x080c, 0xc4de, 0xa974,
-	0x0016, 0x080c, 0xb9d8, 0x001e, 0x0468, 0xa867, 0x0103, 0xa974,
-	0x9184, 0x00ff, 0x90b6, 0x0002, 0x01b0, 0x9086, 0x0028, 0x1118,
-	0xa87b, 0x001c, 0x00d0, 0xd1dc, 0x0148, 0xa87b, 0x0015, 0x080c,
-	0xc401, 0x0118, 0xa974, 0xc1dc, 0xa976, 0x0078, 0xd1d4, 0x0118,
-	0xa87b, 0x0007, 0x0050, 0xa87b, 0x0000, 0xa87c, 0xd0ac, 0x0128,
-	0xa834, 0xa938, 0x9115, 0x190c, 0xb4ee, 0xa974, 0x0016, 0x080c,
-	0x6904, 0x001e, 0xd1e4, 0x1120, 0x080c, 0xa0e3, 0x009e, 0x0005,
-	0x080c, 0xc137, 0x0cd8, 0x6114, 0x0096, 0x2148, 0xa97c, 0xd1e4,
-	0x190c, 0x19a0, 0x009e, 0x0005, 0x080c, 0x8b04, 0x0010, 0x080c,
-	0x8bc0, 0x080c, 0xbe37, 0x01f0, 0x0096, 0x6114, 0x2148, 0x080c,
-	0xc03f, 0x1118, 0x080c, 0xaa81, 0x00a0, 0xa867, 0x0103, 0x2009,
-	0x180c, 0x210c, 0xd18c, 0x11b8, 0xd184, 0x1190, 0x6108, 0xa97a,
-	0x918e, 0x0029, 0x1110, 0x080c, 0xdb2e, 0xa877, 0x0000, 0x080c,
-	0x6ae9, 0x009e, 0x080c, 0xa0e3, 0x080c, 0x8c10, 0x0804, 0x8ced,
-	0xa87b, 0x0004, 0x0c90, 0xa87b, 0x0004, 0x0c78, 0x9182, 0x0054,
-	0x1220, 0x9182, 0x0040, 0x0208, 0x000a, 0x0005, 0xb752, 0xb752,
-	0xb752, 0xb752, 0xb752, 0xb754, 0xb752, 0xb752, 0xb752, 0xb752,
-	0xb752, 0xb752, 0xb752, 0xb752, 0xb752, 0xb752, 0xb752, 0xb752,
-	0xb752, 0xb752, 0x080c, 0x0dfa, 0x080c, 0x55e3, 0x01f8, 0x6014,
-	0x7144, 0x918c, 0x0fff, 0x9016, 0xd1c4, 0x0118, 0x7264, 0x9294,
-	0x00ff, 0x0096, 0x904d, 0x0188, 0xa87b, 0x0000, 0xa864, 0x9086,
-	0x0139, 0x0128, 0xa867, 0x0103, 0xa976, 0xaa96, 0x0030, 0xa897,
-	0x4000, 0xa99a, 0xaa9e, 0x080c, 0x6ae9, 0x009e, 0x0804, 0xa0e3,
-	0x9182, 0x0085, 0x0002, 0xb78a, 0xb788, 0xb788, 0xb796, 0xb788,
-	0xb788, 0xb788, 0xb788, 0xb788, 0xb788, 0xb788, 0xb788, 0xb788,
-	0x080c, 0x0dfa, 0x6003, 0x0001, 0x6106, 0x080c, 0x8679, 0x0126,
-	0x2091, 0x8000, 0x080c, 0x8c10, 0x012e, 0x0005, 0x0026, 0x0056,
-	0x00d6, 0x00e6, 0x2071, 0x0260, 0x7224, 0x6216, 0x7220, 0x080c,
-	0xbe25, 0x01f8, 0x2268, 0x6800, 0x9086, 0x0000, 0x01d0, 0x6010,
-	0x6d10, 0x952e, 0x11b0, 0x00c6, 0x2d60, 0x00d6, 0x080c, 0xba49,
-	0x00de, 0x00ce, 0x0158, 0x702c, 0xd084, 0x1118, 0x080c, 0xba13,
-	0x0010, 0x6803, 0x0002, 0x6007, 0x0086, 0x0028, 0x080c, 0xba35,
-	0x0d90, 0x6007, 0x0087, 0x6003, 0x0001, 0x080c, 0x8679, 0x080c,
-	0x8c10, 0x7220, 0x080c, 0xbe25, 0x0178, 0x6810, 0x00b6, 0x2058,
-	0xb800, 0x00be, 0xd0bc, 0x0140, 0x6824, 0xd0ec, 0x0128, 0x00c6,
-	0x2d60, 0x080c, 0xc171, 0x00ce, 0x00ee, 0x00de, 0x005e, 0x002e,
-	0x0005, 0x9186, 0x0013, 0x1160, 0x6004, 0x908a, 0x0085, 0x0a0c,
-	0x0dfa, 0x908a, 0x0092, 0x1a0c, 0x0dfa, 0x9082, 0x0085, 0x00e2,
-	0x9186, 0x0027, 0x0120, 0x9186, 0x0014, 0x190c, 0x0dfa, 0x080c,
-	0x8b04, 0x0096, 0x6014, 0x2048, 0x080c, 0xbe37, 0x0140, 0xa867,
-	0x0103, 0xa877, 0x0000, 0xa87b, 0x0029, 0x080c, 0x6ae9, 0x009e,
-	0x080c, 0xa113, 0x0804, 0x8c10, 0xb819, 0xb81b, 0xb81b, 0xb819,
-	0xb819, 0xb819, 0xb819, 0xb819, 0xb819, 0xb819, 0xb819, 0xb819,
-	0xb819, 0x080c, 0x0dfa, 0x080c, 0x8b04, 0x080c, 0xa113, 0x080c,
-	0x8c10, 0x0005, 0x9186, 0x0013, 0x1128, 0x6004, 0x9082, 0x0085,
-	0x2008, 0x04b8, 0x9186, 0x0027, 0x11f8, 0x080c, 0x8b04, 0x080c,
-	0x318b, 0x080c, 0xc54e, 0x0096, 0x6014, 0x2048, 0x080c, 0xbe37,
-	0x0150, 0xa867, 0x0103, 0xa877, 0x0000, 0xa87b, 0x0029, 0x080c,
-	0x6ae9, 0x080c, 0xc022, 0x009e, 0x080c, 0xa0e3, 0x080c, 0x8c10,
-	0x0005, 0x080c, 0xa178, 0x0ce0, 0x9186, 0x0014, 0x1dd0, 0x080c,
-	0x8b04, 0x0096, 0x6014, 0x2048, 0x080c, 0xbe37, 0x0d60, 0xa867,
-	0x0103, 0xa877, 0x0000, 0xa87b, 0x0006, 0xa880, 0xc0ec, 0xa882,
-	0x08f0, 0x0002, 0xb871, 0xb86f, 0xb86f, 0xb86f, 0xb86f, 0xb86f,
-	0xb889, 0xb86f, 0xb86f, 0xb86f, 0xb86f, 0xb86f, 0xb86f, 0x080c,
-	0x0dfa, 0x080c, 0x8b04, 0x6034, 0x908c, 0xff00, 0x810f, 0x9186,
-	0x0039, 0x0118, 0x9186, 0x0035, 0x1118, 0x2001, 0x195e, 0x0010,
-	0x2001, 0x195f, 0x2004, 0x601a, 0x6003, 0x000c, 0x080c, 0x8c10,
-	0x0005, 0x080c, 0x8b04, 0x6034, 0x908c, 0xff00, 0x810f, 0x9186,
-	0x0039, 0x0118, 0x9186, 0x0035, 0x1118, 0x2001, 0x195e, 0x0010,
-	0x2001, 0x195f, 0x2004, 0x601a, 0x6003, 0x000e, 0x080c, 0x8c10,
-	0x0005, 0x9182, 0x0092, 0x1220, 0x9182, 0x0085, 0x0208, 0x0012,
-	0x0804, 0xa178, 0xb8b7, 0xb8b7, 0xb8b7, 0xb8b7, 0xb8b9, 0xb906,
-	0xb8b7, 0xb8b7, 0xb8b7, 0xb8b7, 0xb8b7, 0xb8b7, 0xb8b7, 0x080c,
-	0x0dfa, 0x0096, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc,
-	0x0168, 0x6034, 0x908c, 0xff00, 0x810f, 0x9186, 0x0039, 0x0118,
-	0x9186, 0x0035, 0x1118, 0x009e, 0x0804, 0xb91a, 0x080c, 0xbe37,
-	0x1118, 0x080c, 0xc022, 0x0068, 0x6014, 0x2048, 0xa87c, 0xd0e4,
-	0x1110, 0x080c, 0xc022, 0xa867, 0x0103, 0x080c, 0xc519, 0x080c,
-	0x6ae9, 0x00d6, 0x2c68, 0x080c, 0xa08d, 0x01d0, 0x6003, 0x0001,
-	0x6007, 0x001e, 0x600b, 0xffff, 0x2009, 0x026e, 0x210c, 0x613a,
-	0x2009, 0x026f, 0x210c, 0x613e, 0x6910, 0x6112, 0x080c, 0xc2b3,
-	0x6954, 0x6156, 0x6023, 0x0001, 0x080c, 0x8679, 0x080c, 0x8c10,
-	0x2d60, 0x00de, 0x080c, 0xa0e3, 0x009e, 0x0005, 0x6010, 0x00b6,
-	0x2058, 0xb800, 0x00be, 0xd0bc, 0x05a0, 0x6034, 0x908c, 0xff00,
-	0x810f, 0x9186, 0x0035, 0x0130, 0x9186, 0x001e, 0x0118, 0x9186,
-	0x0039, 0x1538, 0x00d6, 0x2c68, 0x080c, 0xc4b1, 0x11f0, 0x080c,
-	0xa08d, 0x01d8, 0x6106, 0x6003, 0x0001, 0x6023, 0x0001, 0x6910,
-	0x6112, 0x692c, 0x612e, 0x6930, 0x6132, 0x6934, 0x918c, 0x00ff,
-	0x6136, 0x6938, 0x613a, 0x693c, 0x613e, 0x6954, 0x6156, 0x080c,
-	0xc2b3, 0x080c, 0x8679, 0x080c, 0x8c10, 0x2d60, 0x00de, 0x0804,
-	0xa0e3, 0x0096, 0x6014, 0x2048, 0x080c, 0xbe37, 0x01c8, 0xa867,
-	0x0103, 0xa880, 0xd0b4, 0x0128, 0xc0ec, 0xa882, 0xa87b, 0x0006,
-	0x0048, 0xd0bc, 0x0118, 0xa87b, 0x0002, 0x0020, 0xa87b, 0x0005,
-	0x080c, 0xc133, 0xa877, 0x0000, 0x080c, 0x6ae9, 0x080c, 0xc022,
-	0x009e, 0x0804, 0xa0e3, 0x0016, 0x0096, 0x6014, 0x2048, 0x080c,
-	0xbe37, 0x0140, 0xa867, 0x0103, 0xa87b, 0x0028, 0xa877, 0x0000,
-	0x080c, 0x6ae9, 0x009e, 0x001e, 0x9186, 0x0013, 0x0148, 0x9186,
-	0x0014, 0x0130, 0x9186, 0x0027, 0x0118, 0x080c, 0xa178, 0x0030,
-	0x080c, 0x8b04, 0x080c, 0xa113, 0x080c, 0x8c10, 0x0005, 0x0056,
-	0x0066, 0x0096, 0x00a6, 0x2029, 0x0001, 0x9182, 0x0101, 0x1208,
-	0x0010, 0x2009, 0x0100, 0x2130, 0x8304, 0x9098, 0x0018, 0x2009,
-	0x0020, 0x2011, 0x0029, 0x080c, 0xb9e8, 0x96b2, 0x0020, 0xb004,
-	0x904d, 0x0110, 0x080c, 0x0fe3, 0x080c, 0x1031, 0x0520, 0x8528,
-	0xa867, 0x0110, 0xa86b, 0x0000, 0x2920, 0xb406, 0x968a, 0x003d,
-	0x1228, 0x2608, 0x2011, 0x001b, 0x0499, 0x00a8, 0x96b2, 0x003c,
-	0x2009, 0x003c, 0x2950, 0x2011, 0x001b, 0x0451, 0x0c28, 0x2001,
-	0x0205, 0x2003, 0x0000, 0x00ae, 0x852f, 0x95ad, 0x0003, 0xb566,
-	0x95ac, 0x0000, 0x0048, 0x2001, 0x0205, 0x2003, 0x0000, 0x00ae,
-	0x852f, 0x95ad, 0x0003, 0xb566, 0x009e, 0x006e, 0x005e, 0x0005,
-	0x00a6, 0x89ff, 0x0158, 0xa804, 0x9055, 0x0130, 0xa807, 0x0000,
-	0x080c, 0x6ae9, 0x2a48, 0x0cb8, 0x080c, 0x6ae9, 0x00ae, 0x0005,
-	0x00f6, 0x2079, 0x0200, 0x7814, 0x9085, 0x0080, 0x7816, 0xd184,
-	0x0108, 0x8108, 0x810c, 0x20a9, 0x0001, 0xa860, 0x20e8, 0xa85c,
-	0x9200, 0x20a0, 0x20e1, 0x0000, 0x2300, 0x9e00, 0x2098, 0x4003,
-	0x8318, 0x9386, 0x0020, 0x1148, 0x2018, 0x2300, 0x9e00, 0x2098,
-	0x7814, 0x8000, 0x9085, 0x0080, 0x7816, 0x8109, 0x1d80, 0x7817,
-	0x0000, 0x00fe, 0x0005, 0x6920, 0x9186, 0x0003, 0x0118, 0x9186,
-	0x0002, 0x11d0, 0x00c6, 0x00d6, 0x00e6, 0x2d60, 0x0096, 0x6014,
-	0x2048, 0x080c, 0xbe37, 0x0150, 0x2001, 0x0006, 0xa980, 0xc1d5,
-	0x080c, 0x6d17, 0x080c, 0x6adc, 0x080c, 0xc022, 0x009e, 0x080c,
-	0xa113, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x00c6, 0x702c, 0xd084,
-	0x1170, 0x6008, 0x2060, 0x6020, 0x9086, 0x0002, 0x1140, 0x6104,
-	0x9186, 0x0085, 0x0118, 0x9186, 0x008b, 0x1108, 0x9006, 0x00ce,
-	0x0005, 0x0066, 0x0126, 0x2091, 0x8000, 0x2031, 0x0001, 0x6020,
-	0x9084, 0x000f, 0x0083, 0x012e, 0x006e, 0x0005, 0x0126, 0x2091,
-	0x8000, 0x0066, 0x2031, 0x0000, 0x6020, 0x9084, 0x000f, 0x001b,
-	0x006e, 0x012e, 0x0005, 0xba84, 0xba84, 0xba7f, 0xbaa6, 0xba72,
-	0xba7f, 0xbaa6, 0xba7f, 0xba72, 0xba72, 0xba7f, 0xba7f, 0xba7f,
-	0xba72, 0xba72, 0x080c, 0x0dfa, 0x0036, 0x2019, 0x0010, 0x080c,
-	0xd440, 0x6023, 0x0006, 0x6003, 0x0007, 0x003e, 0x0005, 0x9006,
-	0x0005, 0x9085, 0x0001, 0x0005, 0x0096, 0x86ff, 0x11d8, 0x6014,
-	0x2048, 0x080c, 0xbe37, 0x01c0, 0xa864, 0x9086, 0x0139, 0x1128,
-	0xa87b, 0x0005, 0xa883, 0x0000, 0x0028, 0x900e, 0x2001, 0x0005,
-	0x080c, 0x6d17, 0x080c, 0xc133, 0x080c, 0x6adc, 0x080c, 0xa113,
-	0x9085, 0x0001, 0x009e, 0x0005, 0x9006, 0x0ce0, 0x6000, 0x908a,
-	0x0016, 0x1a0c, 0x0dfa, 0x0002, 0xbabc, 0xbaec, 0xbabe, 0xbb0d,
-	0xbae7, 0xbabc, 0xba7f, 0xba84, 0xba84, 0xba7f, 0xba7f, 0xba7f,
-	0xba7f, 0xba7f, 0xba7f, 0xba7f, 0x080c, 0x0dfa, 0x86ff, 0x1520,
-	0x6020, 0x9086, 0x0006, 0x0500, 0x0096, 0x6014, 0x2048, 0x080c,
-	0xbe37, 0x0168, 0xa87c, 0xd0cc, 0x0140, 0x0096, 0xc0cc, 0xa87e,
-	0xa878, 0x2048, 0x080c, 0x0fe3, 0x009e, 0x080c, 0xc133, 0x009e,
-	0x080c, 0xc4f3, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002,
-	0x080c, 0x8679, 0x080c, 0x8c10, 0x9085, 0x0001, 0x0005, 0x0066,
-	0x080c, 0x19b4, 0x006e, 0x0890, 0x00e6, 0x2071, 0x19bf, 0x7024,
-	0x9c06, 0x1120, 0x080c, 0x9927, 0x00ee, 0x0840, 0x6020, 0x9084,
-	0x000f, 0x9086, 0x0006, 0x1150, 0x0086, 0x0096, 0x2049, 0x0001,
-	0x2c40, 0x080c, 0x9a58, 0x009e, 0x008e, 0x0010, 0x080c, 0x9824,
-	0x00ee, 0x1904, 0xbabe, 0x0804, 0xba7f, 0x0036, 0x00e6, 0x2071,
-	0x19bf, 0x703c, 0x9c06, 0x1138, 0x901e, 0x080c, 0x999d, 0x00ee,
-	0x003e, 0x0804, 0xbabe, 0x080c, 0x9b88, 0x00ee, 0x003e, 0x1904,
-	0xbabe, 0x0804, 0xba7f, 0x00c6, 0x6020, 0x9084, 0x000f, 0x0013,
-	0x00ce, 0x0005, 0xbb40, 0xbc0b, 0xbd75, 0xbb4a, 0xa113, 0xbb40,
-	0xd432, 0xc55b, 0xbc0b, 0xbb39, 0xbe01, 0xbb39, 0xbb39, 0xbb39,
-	0xbb39, 0x080c, 0x0dfa, 0x080c, 0xc03f, 0x1110, 0x080c, 0xaa81,
-	0x0005, 0x080c, 0x8b04, 0x080c, 0x8c10, 0x0804, 0xa0e3, 0x601b,
-	0x0001, 0x0005, 0x080c, 0xbe37, 0x0130, 0x6014, 0x0096, 0x2048,
-	0x2c00, 0xa896, 0x009e, 0x6000, 0x908a, 0x0016, 0x1a0c, 0x0dfa,
-	0x0002, 0xbb69, 0xbb6b, 0xbb8f, 0xbba3, 0xbbc9, 0xbb69, 0xbb40,
-	0xbb40, 0xbb40, 0xbba3, 0xbba3, 0xbb69, 0xbb69, 0xbb69, 0xbb69,
-	0xbbad, 0x080c, 0x0dfa, 0x00e6, 0x6014, 0x0096, 0x2048, 0xa880,
-	0xc0b5, 0xa882, 0x009e, 0x2071, 0x19bf, 0x7024, 0x9c06, 0x01a0,
-	0x080c, 0x9824, 0x080c, 0xc4f3, 0x6007, 0x0085, 0x6003, 0x000b,
-	0x6023, 0x0002, 0x2001, 0x195f, 0x2004, 0x601a, 0x080c, 0x8679,
-	0x080c, 0x8c10, 0x00ee, 0x0005, 0x601b, 0x0001, 0x0cd8, 0x0096,
-	0x6014, 0x2048, 0xa880, 0xc0b5, 0xa882, 0x009e, 0x080c, 0xc4f3,
-	0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002, 0x080c, 0x8679,
-	0x080c, 0x8c10, 0x0005, 0x0096, 0x601b, 0x0001, 0x6014, 0x2048,
-	0xa880, 0xc0b5, 0xa882, 0x009e, 0x0005, 0x080c, 0x55e3, 0x01b8,
-	0x6014, 0x0096, 0x904d, 0x0190, 0xa864, 0xa867, 0x0103, 0xa87b,
-	0x0006, 0x9086, 0x0139, 0x1150, 0xa867, 0x0139, 0xa87b, 0x0030,
-	0xa897, 0x4005, 0xa89b, 0x0004, 0x080c, 0x6ae9, 0x009e, 0x0804,
-	0xa0e3, 0x6014, 0x0096, 0x904d, 0x05c8, 0xa97c, 0xd1e4, 0x05b0,
-	0x2001, 0x180f, 0x2004, 0xd0c4, 0x0110, 0x009e, 0x0005, 0xa884,
-	0x009e, 0x8003, 0x800b, 0x810b, 0x9108, 0x611a, 0x2001, 0x0030,
-	0x2c08, 0x080c, 0x158b, 0x2001, 0x030c, 0x2004, 0x9086, 0x0041,
-	0x11a0, 0x6014, 0x0096, 0x904d, 0x090c, 0x0dfa, 0xa880, 0xd0f4,
-	0x1130, 0xc0f5, 0xa882, 0x009e, 0x601b, 0x0002, 0x0070, 0x009e,
-	0x2001, 0x0037, 0x2c08, 0x080c, 0x158b, 0x6000, 0x9086, 0x0004,
-	0x1120, 0x2009, 0x0048, 0x080c, 0xa15d, 0x0005, 0x009e, 0x080c,
-	0x19b4, 0x0804, 0xbb8f, 0x6000, 0x908a, 0x0016, 0x1a0c, 0x0dfa,
-	0x000b, 0x0005, 0xbc22, 0xbb47, 0xbc24, 0xbc22, 0xbc24, 0xbc24,
-	0xbb41, 0xbc22, 0xbb3b, 0xbb3b, 0xbc22, 0xbc22, 0xbc22, 0xbc22,
-	0xbc22, 0xbc22, 0x080c, 0x0dfa, 0x6010, 0x00b6, 0x2058, 0xb804,
-	0x9084, 0x00ff, 0x00be, 0x908a, 0x000c, 0x1a0c, 0x0dfa, 0x00b6,
-	0x0013, 0x00be, 0x0005, 0xbc3f, 0xbd0c, 0xbc41, 0xbc81, 0xbc41,
-	0xbc81, 0xbc41, 0xbc4f, 0xbc3f, 0xbc81, 0xbc3f, 0xbc70, 0x080c,
-	0x0dfa, 0x6004, 0x908e, 0x0016, 0x05c0, 0x908e, 0x0004, 0x05a8,
-	0x908e, 0x0002, 0x0590, 0x908e, 0x0052, 0x0904, 0xbd08, 0x6004,
-	0x080c, 0xc03f, 0x0904, 0xbd25, 0x908e, 0x0004, 0x1110, 0x080c,
-	0x31b4, 0x908e, 0x0021, 0x0904, 0xbd29, 0x908e, 0x0022, 0x0904,
-	0xbd70, 0x908e, 0x003d, 0x0904, 0xbd29, 0x908e, 0x0039, 0x0904,
-	0xbd2d, 0x908e, 0x0035, 0x0904, 0xbd2d, 0x908e, 0x001e, 0x0178,
-	0x908e, 0x0001, 0x1140, 0x6010, 0x2058, 0xb804, 0x9084, 0x00ff,
-	0x9086, 0x0006, 0x0110, 0x080c, 0x318b, 0x080c, 0xaa81, 0x0804,
-	0xa113, 0x00c6, 0x00d6, 0x6104, 0x9186, 0x0016, 0x0904, 0xbcf9,
-	0x9186, 0x0002, 0x1904, 0xbcce, 0x2001, 0x1836, 0x2004, 0xd08c,
-	0x11c8, 0x080c, 0x7207, 0x11b0, 0x080c, 0xc539, 0x0138, 0x080c,
-	0x722a, 0x1120, 0x080c, 0x7105, 0x0804, 0xbd59, 0x2001, 0x1955,
-	0x2003, 0x0001, 0x2001, 0x1800, 0x2003, 0x0001, 0x080c, 0x7127,
-	0x0804, 0xbd59, 0x6010, 0x2058, 0x2001, 0x1836, 0x2004, 0xd0ac,
-	0x1904, 0xbd59, 0xb8a0, 0x9084, 0xff80, 0x1904, 0xbd59, 0xb840,
-	0x9084, 0x00ff, 0x9005, 0x0190, 0x8001, 0xb842, 0x6017, 0x0000,
-	0x6023, 0x0007, 0x601b, 0x0398, 0x6043, 0x0000, 0x080c, 0xa08d,
-	0x0128, 0x2b00, 0x6012, 0x6023, 0x0001, 0x0458, 0x00de, 0x00ce,
-	0x6004, 0x908e, 0x0002, 0x11a0, 0x6010, 0x2058, 0xb8a0, 0x9086,
-	0x007e, 0x1170, 0x2009, 0x1836, 0x2104, 0xc085, 0x200a, 0x00e6,
-	0x2071, 0x1800, 0x080c, 0x5ebe, 0x00ee, 0x080c, 0xaa81, 0x0030,
-	0x080c, 0xaa81, 0x080c, 0x318b, 0x080c, 0xc54e, 0x00e6, 0x0126,
-	0x2091, 0x8000, 0x080c, 0x31b4, 0x012e, 0x00ee, 0x080c, 0xa113,
-	0x0005, 0x2001, 0x0002, 0x080c, 0x63f0, 0x6003, 0x0001, 0x6007,
-	0x0002, 0x080c, 0x86c1, 0x080c, 0x8c10, 0x00de, 0x00ce, 0x0c80,
-	0x080c, 0x31b4, 0x0804, 0xbc7d, 0x00c6, 0x00d6, 0x6104, 0x9186,
-	0x0016, 0x0d38, 0x6010, 0x2058, 0xb840, 0x9084, 0x00ff, 0x9005,
-	0x0904, 0xbcce, 0x8001, 0xb842, 0x6003, 0x0001, 0x080c, 0x86c1,
-	0x080c, 0x8c10, 0x00de, 0x00ce, 0x0898, 0x080c, 0xaa81, 0x0804,
-	0xbc7f, 0x080c, 0xaabd, 0x0804, 0xbc7f, 0x00d6, 0x2c68, 0x6104,
-	0x080c, 0xc4b1, 0x00de, 0x0118, 0x080c, 0xa0e3, 0x0408, 0x6004,
-	0x8007, 0x6134, 0x918c, 0x00ff, 0x9105, 0x6036, 0x6007, 0x0085,
-	0x6003, 0x000b, 0x6023, 0x0002, 0x603c, 0x600a, 0x2001, 0x195f,
-	0x2004, 0x601a, 0x602c, 0x2c08, 0x2060, 0x6024, 0xd0b4, 0x0108,
-	0xc085, 0xc0b5, 0x6026, 0x2160, 0x080c, 0x8679, 0x080c, 0x8c10,
-	0x0005, 0x00de, 0x00ce, 0x080c, 0xaa81, 0x080c, 0x318b, 0x00e6,
-	0x0126, 0x2091, 0x8000, 0x080c, 0x31b4, 0x6017, 0x0000, 0x6023,
-	0x0007, 0x601b, 0x0398, 0x6043, 0x0000, 0x012e, 0x00ee, 0x0005,
-	0x080c, 0xa513, 0x1904, 0xbd25, 0x0005, 0x6000, 0x908a, 0x0016,
-	0x1a0c, 0x0dfa, 0x0096, 0x00d6, 0x001b, 0x00de, 0x009e, 0x0005,
-	0xbd90, 0xbd90, 0xbd90, 0xbd90, 0xbd90, 0xbd90, 0xbd90, 0xbd90,
-	0xbd90, 0xbb40, 0xbd90, 0xbb47, 0xbd92, 0xbb47, 0xbdac, 0xbd90,
-	0x080c, 0x0dfa, 0x6004, 0x9086, 0x008b, 0x01b0, 0x6034, 0x908c,
-	0xff00, 0x810f, 0x9186, 0x0035, 0x1130, 0x602c, 0x9080, 0x0009,
-	0x200c, 0xc185, 0x2102, 0x6007, 0x008b, 0x6003, 0x000d, 0x080c,
-	0x8679, 0x080c, 0x8c10, 0x0005, 0x080c, 0xc52d, 0x0118, 0x080c,
-	0xc540, 0x0010, 0x080c, 0xc54e, 0x080c, 0xc022, 0x080c, 0xbe37,
-	0x0570, 0x080c, 0x318b, 0x080c, 0xbe37, 0x0168, 0x6014, 0x2048,
-	0xa867, 0x0103, 0xa87b, 0x0006, 0xa877, 0x0000, 0xa880, 0xc0ed,
-	0xa882, 0x080c, 0x6ae9, 0x2c68, 0x080c, 0xa08d, 0x0150, 0x6810,
-	0x6012, 0x080c, 0xc2b3, 0x00c6, 0x2d60, 0x080c, 0xa113, 0x00ce,
-	0x0008, 0x2d60, 0x6017, 0x0000, 0x6023, 0x0001, 0x6007, 0x0001,
-	0x6003, 0x0001, 0x080c, 0x86c1, 0x080c, 0x8c10, 0x00c8, 0x080c,
-	0xc52d, 0x0138, 0x6034, 0x9086, 0x4000, 0x1118, 0x080c, 0x318b,
-	0x08d0, 0x6034, 0x908c, 0xff00, 0x810f, 0x9186, 0x0039, 0x0118,
-	0x9186, 0x0035, 0x1118, 0x080c, 0x318b, 0x0868, 0x080c, 0xa113,
-	0x0005, 0x6000, 0x908a, 0x0016, 0x1a0c, 0x0dfa, 0x0002, 0xbe17,
-	0xbe17, 0xbe19, 0xbe19, 0xbe19, 0xbe17, 0xbe17, 0xa113, 0xbe17,
-	0xbe17, 0xbe17, 0xbe17, 0xbe17, 0xbe17, 0xbe17, 0xbe17, 0x080c,
-	0x0dfa, 0x080c, 0x9b88, 0x6114, 0x0096, 0x2148, 0xa87b, 0x0006,
-	0x080c, 0x6ae9, 0x009e, 0x0804, 0xa0e3, 0x9284, 0x0007, 0x1158,
-	0x9282, 0x1cd0, 0x0240, 0x2001, 0x1819, 0x2004, 0x9202, 0x1218,
-	0x9085, 0x0001, 0x0005, 0x9006, 0x0ce8, 0x0096, 0x0028, 0x0096,
-	0x0006, 0x6014, 0x2048, 0x000e, 0x0006, 0x9984, 0xf000, 0x9086,
-	0xf000, 0x0110, 0x080c, 0x10dc, 0x000e, 0x009e, 0x0005, 0x00e6,
-	0x00c6, 0x0036, 0x0006, 0x0126, 0x2091, 0x8000, 0x2061, 0x1cd0,
-	0x2071, 0x1800, 0x7350, 0x7070, 0x9302, 0x1640, 0x6020, 0x9206,
-	0x11f8, 0x080c, 0xc539, 0x0180, 0x9286, 0x0001, 0x1168, 0x6004,
-	0x9086, 0x0004, 0x1148, 0x080c, 0x318b, 0x080c, 0xc54e, 0x00c6,
-	0x080c, 0xa113, 0x00ce, 0x0060, 0x080c, 0xc22d, 0x0148, 0x080c,
-	0xc03f, 0x1110, 0x080c, 0xaa81, 0x00c6, 0x080c, 0xa0e3, 0x00ce,
-	0x9ce0, 0x0018, 0x7064, 0x9c02, 0x1208, 0x08a0, 0x012e, 0x000e,
-	0x003e, 0x00ce, 0x00ee, 0x0005, 0x00e6, 0x00c6, 0x0016, 0x9188,
-	0x1000, 0x210c, 0x81ff, 0x0128, 0x2061, 0x1a8a, 0x6112, 0x080c,
-	0x318b, 0x9006, 0x0010, 0x9085, 0x0001, 0x001e, 0x00ce, 0x00ee,
-	0x0005, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xa08d, 0x01b0,
-	0x6656, 0x2b00, 0x6012, 0x080c, 0x55e3, 0x0118, 0x080c, 0xbf66,
-	0x0168, 0x080c, 0xc2b3, 0x6023, 0x0003, 0x2009, 0x004b, 0x080c,
-	0xa15d, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8,
-	0x00c6, 0x0126, 0x2091, 0x8000, 0xbaa0, 0x080c, 0xa130, 0x0560,
-	0x6057, 0x0000, 0x2b00, 0x6012, 0x080c, 0xc2b3, 0x6023, 0x0003,
-	0x0016, 0x080c, 0x8803, 0x0076, 0x903e, 0x080c, 0x86f1, 0x2c08,
-	0x080c, 0xd5f6, 0x007e, 0x001e, 0xd184, 0x0128, 0x080c, 0xa0e3,
-	0x9085, 0x0001, 0x0070, 0x080c, 0x55e3, 0x0128, 0xd18c, 0x1170,
-	0x080c, 0xbf66, 0x0148, 0x2009, 0x004c, 0x080c, 0xa15d, 0x9085,
-	0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x2900, 0x6016,
-	0x0c90, 0x2009, 0x004d, 0x0010, 0x2009, 0x004e, 0x00f6, 0x00c6,
-	0x0046, 0x0016, 0x080c, 0xa08d, 0x2c78, 0x05a0, 0x7e56, 0x2b00,
-	0x7812, 0x7823, 0x0003, 0x0016, 0x2021, 0x0005, 0x080c, 0xbf78,
-	0x001e, 0x9186, 0x004d, 0x0118, 0x9186, 0x004e, 0x0148, 0x2001,
-	0x1958, 0x200c, 0xd1fc, 0x0168, 0x2f60, 0x080c, 0xa0e3, 0x00d0,
-	0x2001, 0x1957, 0x200c, 0xd1fc, 0x0120, 0x2f60, 0x080c, 0xa0e3,
-	0x0088, 0x2f60, 0x080c, 0x55e3, 0x0138, 0xd18c, 0x1118, 0x04f1,
-	0x0148, 0x0010, 0x2900, 0x7816, 0x001e, 0x0016, 0x080c, 0xa15d,
-	0x9085, 0x0001, 0x001e, 0x004e, 0x00ce, 0x00fe, 0x0005, 0x00f6,
-	0x00c6, 0x0046, 0x080c, 0xa08d, 0x2c78, 0x0508, 0x7e56, 0x2b00,
-	0x7812, 0x7823, 0x0003, 0x0096, 0x2021, 0x0004, 0x0489, 0x009e,
-	0x2001, 0x1956, 0x200c, 0xd1fc, 0x0120, 0x2f60, 0x080c, 0xa0e3,
-	0x0060, 0x2f60, 0x080c, 0x55e3, 0x0120, 0xd18c, 0x1160, 0x0071,
-	0x0130, 0x2009, 0x0052, 0x080c, 0xa15d, 0x9085, 0x0001, 0x004e,
-	0x00ce, 0x00fe, 0x0005, 0x2900, 0x7816, 0x0c98, 0x00c6, 0x080c,
-	0x4abf, 0x00ce, 0x1120, 0x080c, 0xa0e3, 0x9006, 0x0005, 0xa867,
-	0x0000, 0xa86b, 0x8000, 0x2900, 0x6016, 0x9085, 0x0001, 0x0005,
-	0x0096, 0x0076, 0x0126, 0x2091, 0x8000, 0x080c, 0x65d3, 0x0158,
-	0x2001, 0xbf7d, 0x0006, 0x900e, 0x2400, 0x080c, 0x6d17, 0x080c,
-	0x6ae9, 0x000e, 0x0807, 0x2418, 0x080c, 0x8a9e, 0xbaa0, 0x0086,
-	0x2041, 0x0001, 0x2039, 0x0001, 0x2608, 0x080c, 0x881b, 0x008e,
-	0x080c, 0x86f1, 0x2f08, 0x2648, 0x080c, 0xd5f6, 0xb93c, 0x81ff,
-	0x090c, 0x88ee, 0x080c, 0x8c10, 0x012e, 0x007e, 0x009e, 0x0005,
-	0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xa08d, 0x0190, 0x660a,
-	0x2b08, 0x6112, 0x080c, 0xc2b3, 0x6023, 0x0001, 0x2900, 0x6016,
-	0x2009, 0x001f, 0x080c, 0xa15d, 0x9085, 0x0001, 0x012e, 0x00ce,
-	0x0005, 0x9006, 0x0cd8, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c,
-	0xa130, 0x01b8, 0x660a, 0x2b08, 0x6112, 0x080c, 0xc2b3, 0x6023,
-	0x0008, 0x2900, 0x6016, 0x00f6, 0x2c78, 0x080c, 0x16db, 0x00fe,
-	0x2009, 0x0021, 0x080c, 0xa15d, 0x9085, 0x0001, 0x012e, 0x00ce,
-	0x0005, 0x9006, 0x0cd8, 0x2009, 0x003d, 0x00c6, 0x0126, 0x0016,
-	0x2091, 0x8000, 0x080c, 0xa08d, 0x0198, 0x660a, 0x2b08, 0x6112,
-	0x080c, 0xc2b3, 0x6023, 0x0001, 0x2900, 0x6016, 0x001e, 0x0016,
-	0x080c, 0xa15d, 0x9085, 0x0001, 0x001e, 0x012e, 0x00ce, 0x0005,
-	0x9006, 0x0cd0, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xa130,
-	0x0188, 0x2b08, 0x6112, 0x080c, 0xc2b3, 0x6023, 0x0001, 0x2900,
-	0x6016, 0x2009, 0x0000, 0x080c, 0xa15d, 0x9085, 0x0001, 0x012e,
-	0x00ce, 0x0005, 0x9006, 0x0cd8, 0x2009, 0x0044, 0x0830, 0x2009,
-	0x0049, 0x0818, 0x0026, 0x00b6, 0x6210, 0x2258, 0xba3c, 0x82ff,
-	0x0110, 0x8211, 0xba3e, 0x00be, 0x002e, 0x0005, 0x0006, 0x0016,
-	0x6004, 0x908e, 0x0002, 0x0140, 0x908e, 0x0003, 0x0128, 0x908e,
-	0x0004, 0x0110, 0x9085, 0x0001, 0x001e, 0x000e, 0x0005, 0x0006,
-	0x0086, 0x0096, 0x6020, 0x9086, 0x0004, 0x01a8, 0x6014, 0x904d,
-	0x080c, 0xbe37, 0x0180, 0xa864, 0x9086, 0x0139, 0x0170, 0x6020,
-	0x90c6, 0x0003, 0x0140, 0x90c6, 0x0002, 0x0128, 0xa868, 0xd0fc,
-	0x0110, 0x9006, 0x0010, 0x9085, 0x0001, 0x009e, 0x008e, 0x000e,
-	0x0005, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xa130, 0x0198,
-	0x2b08, 0x6112, 0x080c, 0xc2b3, 0x6023, 0x0001, 0x2900, 0x6016,
-	0x080c, 0x318b, 0x2009, 0x0028, 0x080c, 0xa15d, 0x9085, 0x0001,
-	0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x9186, 0x0015, 0x11a8,
-	0x2011, 0x1823, 0x2204, 0x9086, 0x0074, 0x1178, 0x00b6, 0x080c,
-	0xad0c, 0x00be, 0x080c, 0xaf4b, 0x6003, 0x0001, 0x6007, 0x0029,
-	0x080c, 0x86c1, 0x080c, 0x8c10, 0x0078, 0x6014, 0x0096, 0x2048,
-	0xa868, 0x009e, 0xd0fc, 0x0148, 0x2001, 0x0001, 0x080c, 0xc472,
-	0x080c, 0xaa81, 0x080c, 0xa0e3, 0x0005, 0x0096, 0x6014, 0x904d,
-	0x090c, 0x0dfa, 0xa87b, 0x0030, 0xa883, 0x0000, 0xa897, 0x4005,
-	0xa89b, 0x0004, 0xa867, 0x0139, 0x0126, 0x2091, 0x8000, 0x080c,
-	0x6ae9, 0x012e, 0x009e, 0x080c, 0xa0e3, 0x0c30, 0x0096, 0x9186,
-	0x0016, 0x1128, 0x2001, 0x0004, 0x080c, 0x63f0, 0x00e8, 0x9186,
-	0x0015, 0x1510, 0x2011, 0x1823, 0x2204, 0x9086, 0x0014, 0x11e0,
-	0x6010, 0x00b6, 0x2058, 0x080c, 0x653a, 0x00be, 0x080c, 0xb01c,
-	0x1198, 0x6010, 0x00b6, 0x2058, 0xb890, 0x00be, 0x9005, 0x0160,
-	0x2001, 0x0006, 0x080c, 0x63f0, 0x6014, 0x2048, 0xa868, 0xd0fc,
-	0x0170, 0x080c, 0xa4e7, 0x0048, 0x6014, 0x2048, 0xa868, 0xd0fc,
-	0x0528, 0x080c, 0xaa81, 0x080c, 0xa0e3, 0x009e, 0x0005, 0x6014,
-	0x6310, 0x2358, 0x904d, 0x090c, 0x0dfa, 0xa87b, 0x0000, 0xa883,
-	0x0000, 0xa897, 0x4000, 0x900e, 0x080c, 0x66bf, 0x1108, 0xc185,
-	0xb800, 0xd0bc, 0x0108, 0xc18d, 0xa99a, 0x0126, 0x2091, 0x8000,
-	0x080c, 0x6ae9, 0x012e, 0x080c, 0xa0e3, 0x08f8, 0x6014, 0x904d,
-	0x090c, 0x0dfa, 0xa87b, 0x0030, 0xa883, 0x0000, 0xa897, 0x4005,
-	0xa89b, 0x0004, 0xa867, 0x0139, 0x0126, 0x2091, 0x8000, 0x080c,
-	0x6ae9, 0x012e, 0x080c, 0xa0e3, 0x0840, 0xa878, 0x9086, 0x0005,
-	0x1108, 0x0009, 0x0005, 0xa880, 0xc0ad, 0xa882, 0x0005, 0x6043,
-	0x0000, 0x6017, 0x0000, 0x6003, 0x0001, 0x6007, 0x0050, 0x080c,
-	0x8679, 0x080c, 0x8c10, 0x0005, 0x00c6, 0x6010, 0x00b6, 0x2058,
-	0xb800, 0x00be, 0xd0bc, 0x0120, 0x6020, 0x9084, 0x000f, 0x0013,
-	0x00ce, 0x0005, 0xbb40, 0xc163, 0xc163, 0xc166, 0xd8d4, 0xd8ef,
-	0xd8f2, 0xbb40, 0xbb40, 0xbb40, 0xbb40, 0xbb40, 0xbb40, 0xbb40,
-	0xbb40, 0x080c, 0x0dfa, 0xa001, 0xa001, 0x0005, 0x0096, 0x6014,
-	0x904d, 0x0118, 0xa87c, 0xd0e4, 0x1110, 0x009e, 0x0010, 0x009e,
-	0x0005, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x0550,
-	0x2001, 0x1833, 0x2004, 0x9005, 0x1540, 0x00f6, 0x2c78, 0x080c,
-	0xa08d, 0x0508, 0x7810, 0x6012, 0x080c, 0xc2b3, 0x7820, 0x9086,
-	0x0003, 0x0128, 0x7808, 0x603a, 0x2f00, 0x603e, 0x0020, 0x7808,
-	0x603e, 0x2f00, 0x603a, 0x602e, 0x6023, 0x0001, 0x6007, 0x0035,
-	0x6003, 0x0001, 0x7954, 0x6156, 0x080c, 0x8679, 0x080c, 0x8c10,
-	0x2f60, 0x00fe, 0x0005, 0x2f60, 0x00fe, 0x2001, 0x1960, 0x2004,
-	0x6042, 0x0005, 0x0016, 0x0096, 0x6814, 0x2048, 0xa87c, 0xd0e4,
-	0x0180, 0xc0e4, 0xa87e, 0xa877, 0x0000, 0xa893, 0x0000, 0xa88f,
-	0x0000, 0xd0cc, 0x0130, 0xc0cc, 0xa87e, 0xa878, 0x2048, 0x080c,
-	0x0fe3, 0x6830, 0x6036, 0x908e, 0x0001, 0x0148, 0x6803, 0x0002,
-	0x9086, 0x0005, 0x0170, 0x9006, 0x602e, 0x6032, 0x00d0, 0x681c,
-	0xc085, 0x681e, 0x6803, 0x0004, 0x6824, 0xc0f4, 0x9085, 0x0c00,
-	0x6826, 0x6814, 0x2048, 0xa8ac, 0x6938, 0x9102, 0xa8b0, 0x693c,
-	0x9103, 0x1e48, 0x683c, 0x602e, 0x6838, 0x9084, 0xfffc, 0x683a,
-	0x6032, 0x2d00, 0x603a, 0x6808, 0x603e, 0x6910, 0x6112, 0x6954,
-	0x6156, 0x6023, 0x0001, 0x6007, 0x0039, 0x6003, 0x0001, 0x080c,
-	0x8679, 0x080c, 0x8c10, 0x009e, 0x001e, 0x0005, 0x6024, 0xd0d4,
-	0x0510, 0xd0f4, 0x11f8, 0x6038, 0x940a, 0x603c, 0x9303, 0x0230,
-	0x9105, 0x0120, 0x6024, 0xc0d4, 0xc0f5, 0x0098, 0x643a, 0x633e,
-	0xac3e, 0xab42, 0x0046, 0x0036, 0x2400, 0xacac, 0x9402, 0xa836,
-	0x2300, 0xabb0, 0x9303, 0xa83a, 0x003e, 0x004e, 0x6024, 0xc0d4,
-	0x0000, 0x6026, 0x0005, 0xd0f4, 0x1138, 0xa83c, 0x603a, 0xa840,
-	0x603e, 0x6024, 0xc0f5, 0x6026, 0x0005, 0x0006, 0x0016, 0x6004,
-	0x908e, 0x0034, 0x01b8, 0x908e, 0x0035, 0x01a0, 0x908e, 0x0036,
-	0x0188, 0x908e, 0x0037, 0x0170, 0x908e, 0x0038, 0x0158, 0x908e,
-	0x0039, 0x0140, 0x908e, 0x003a, 0x0128, 0x908e, 0x003b, 0x0110,
-	0x9085, 0x0001, 0x001e, 0x000e, 0x0005, 0x0006, 0x0016, 0x0026,
-	0x0036, 0x00e6, 0x2001, 0x195a, 0x200c, 0x8000, 0x2014, 0x2001,
-	0x0032, 0x080c, 0x84ff, 0x2001, 0x195e, 0x82ff, 0x1110, 0x2011,
-	0x0014, 0x2202, 0x2001, 0x195c, 0x200c, 0x8000, 0x2014, 0x2071,
-	0x1944, 0x711a, 0x721e, 0x2001, 0x0064, 0x080c, 0x84ff, 0x2001,
-	0x195f, 0x82ff, 0x1110, 0x2011, 0x0014, 0x2202, 0x2001, 0x1960,
-	0x9288, 0x000a, 0x2102, 0x2001, 0x1a6b, 0x2102, 0x2001, 0x0032,
-	0x080c, 0x158b, 0x080c, 0x67a4, 0x00ee, 0x003e, 0x002e, 0x001e,
-	0x000e, 0x0005, 0x0006, 0x0016, 0x00e6, 0x2001, 0x195e, 0x2003,
-	0x0028, 0x2001, 0x195f, 0x2003, 0x0014, 0x2071, 0x1944, 0x701b,
-	0x0000, 0x701f, 0x07d0, 0x2001, 0x1960, 0x2009, 0x001e, 0x2102,
-	0x2001, 0x1a6b, 0x2102, 0x2001, 0x0032, 0x080c, 0x158b, 0x00ee,
-	0x001e, 0x000e, 0x0005, 0x0096, 0x6058, 0x904d, 0x0110, 0x080c,
-	0x1063, 0x009e, 0x0005, 0x0005, 0x00c6, 0x0126, 0x2091, 0x8000,
-	0x080c, 0xa08d, 0x0180, 0x2b08, 0x6112, 0x0ca9, 0x6023, 0x0001,
-	0x2900, 0x6016, 0x2009, 0x0033, 0x080c, 0xa15d, 0x9085, 0x0001,
-	0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x0096, 0x00e6, 0x00f6,
-	0x2071, 0x1800, 0x9186, 0x0015, 0x1500, 0x708c, 0x9086, 0x0018,
+	0x0018, 0x2011, 0x0025, 0x080c, 0xb906, 0x003e, 0xd6cc, 0x0904,
+	0xb17e, 0x7154, 0xa98a, 0x81ff, 0x0904, 0xb17e, 0x9192, 0x0021,
+	0x1278, 0x8304, 0x9098, 0x0018, 0x2011, 0x0029, 0x080c, 0xb906,
+	0x2011, 0x0205, 0x2013, 0x0000, 0x080c, 0xc3e9, 0x0804, 0xb17e,
+	0xa868, 0xd0fc, 0x0120, 0x2009, 0x0020, 0xa98a, 0x0c50, 0x00a6,
+	0x2950, 0x080c, 0xb8a5, 0x00ae, 0x080c, 0xc3e9, 0x080c, 0xb8f6,
+	0x0804, 0xb180, 0x080c, 0xc03b, 0x0804, 0xb18d, 0xa87c, 0xd0ac,
+	0x0904, 0xb199, 0xa880, 0xd0bc, 0x1904, 0xb199, 0x7348, 0xa838,
+	0x9306, 0x11c8, 0x734c, 0xa834, 0x931e, 0x0904, 0xb199, 0xd6d4,
+	0x0190, 0xab38, 0x9305, 0x0904, 0xb199, 0x0068, 0xa87c, 0xd0ac,
+	0x0904, 0xb171, 0xa838, 0xa934, 0x9105, 0x0904, 0xb171, 0xa880,
+	0xd0bc, 0x1904, 0xb171, 0x080c, 0xc075, 0x0804, 0xb18d, 0x0096,
+	0x00f6, 0x6003, 0x0003, 0x6007, 0x0043, 0x2079, 0x026c, 0x7c04,
+	0x7b00, 0x7e0c, 0x7d08, 0x6014, 0x2048, 0xa87c, 0xd0ac, 0x0140,
+	0x6003, 0x0002, 0x00fe, 0x009e, 0x0005, 0x2130, 0x2228, 0x0058,
+	0x2400, 0xa9ac, 0x910a, 0x2300, 0xaab0, 0x9213, 0x2600, 0x9102,
+	0x2500, 0x9203, 0x0e90, 0xac36, 0xab3a, 0xae46, 0xad4a, 0x00fe,
+	0x6043, 0x0000, 0x2c10, 0x080c, 0x1a82, 0x080c, 0x865e, 0x080c,
+	0x8c6d, 0x009e, 0x0005, 0x0005, 0x9182, 0x0054, 0x1220, 0x9182,
+	0x0040, 0x0208, 0x000a, 0x0005, 0xb290, 0xb290, 0xb290, 0xb290,
+	0xb290, 0xb292, 0xb328, 0xb290, 0xb290, 0xb33f, 0xb3cf, 0xb290,
+	0xb290, 0xb290, 0xb290, 0xb3e4, 0xb290, 0xb290, 0xb290, 0xb290,
+	0x080c, 0x0e02, 0x0076, 0x00a6, 0x00e6, 0x0096, 0x2071, 0x0260,
+	0x6114, 0x2150, 0x7644, 0xb676, 0x96b4, 0x0fff, 0xb77c, 0xc7e5,
+	0xb77e, 0x6210, 0x00b6, 0x2258, 0xba3c, 0x82ff, 0x0110, 0x8211,
+	0xba3e, 0x00be, 0x86ff, 0x0904, 0xb323, 0x9694, 0xff00, 0x9284,
+	0x0c00, 0x0120, 0x7048, 0xb092, 0x704c, 0xb08e, 0x9284, 0x0300,
+	0x0904, 0xb323, 0x080c, 0x1043, 0x090c, 0x0e02, 0x2900, 0xb07a,
+	0xb77c, 0xc7cd, 0xb77e, 0xa867, 0x0103, 0xb068, 0xa86a, 0xb06c,
+	0xa86e, 0xb070, 0xa872, 0xae76, 0x968c, 0x0c00, 0x0120, 0x7348,
+	0xab92, 0x734c, 0xab8e, 0x968c, 0x00ff, 0x9186, 0x0002, 0x0180,
+	0x9186, 0x0028, 0x1118, 0xa87b, 0x001c, 0x0060, 0xd6dc, 0x0118,
+	0xa87b, 0x0015, 0x0038, 0xd6d4, 0x0118, 0xa87b, 0x0007, 0x0010,
+	0xa87b, 0x0000, 0xaf7e, 0xb080, 0xa882, 0xb084, 0xa886, 0x901e,
+	0xd6c4, 0x0190, 0x735c, 0xab86, 0x83ff, 0x0170, 0x938a, 0x0009,
+	0x0210, 0x2019, 0x0008, 0x0036, 0x2308, 0x2019, 0x0018, 0x2011,
+	0x0025, 0x080c, 0xb906, 0x003e, 0xd6cc, 0x01e8, 0x7154, 0xa98a,
+	0x81ff, 0x01c8, 0x9192, 0x0021, 0x1260, 0x8304, 0x9098, 0x0018,
+	0x2011, 0x0029, 0x080c, 0xb906, 0x2011, 0x0205, 0x2013, 0x0000,
+	0x0050, 0xb068, 0xd0fc, 0x0120, 0x2009, 0x0020, 0xa98a, 0x0c68,
+	0x2950, 0x080c, 0xb8a5, 0x009e, 0x00ee, 0x00ae, 0x007e, 0x0005,
+	0x00f6, 0x00a6, 0x6003, 0x0003, 0x2079, 0x026c, 0x7c04, 0x7b00,
+	0x7e0c, 0x7d08, 0x6014, 0x2050, 0xb436, 0xb33a, 0xb646, 0xb54a,
+	0x00ae, 0x00fe, 0x2c10, 0x080c, 0x1a82, 0x0804, 0x95d2, 0x6003,
+	0x0002, 0x6004, 0x9086, 0x0040, 0x11c8, 0x0096, 0x6014, 0x2048,
+	0xa87c, 0xd0ac, 0x0160, 0x601c, 0xd084, 0x1130, 0x00f6, 0x2c00,
+	0x2078, 0x080c, 0x165d, 0x00fe, 0x6003, 0x0004, 0x0010, 0x6003,
+	0x0002, 0x009e, 0x080c, 0x8a84, 0x080c, 0x8b90, 0x0096, 0x2001,
+	0x1962, 0x2004, 0x6042, 0x080c, 0x8b40, 0x080c, 0x8c6d, 0x6114,
+	0x2148, 0xa97c, 0xd1e4, 0x0904, 0xb3ca, 0xd1cc, 0x05c8, 0xa978,
+	0xa868, 0xd0fc, 0x0540, 0x0016, 0xa87c, 0x0006, 0xa880, 0x0006,
+	0xa860, 0x20e8, 0xa85c, 0x9080, 0x0019, 0x20a0, 0x810e, 0x810e,
+	0x810f, 0x9184, 0x003f, 0x20e0, 0x9184, 0xffc0, 0x9080, 0x0019,
+	0x2098, 0x0156, 0x20a9, 0x0020, 0x4003, 0x015e, 0x000e, 0xa882,
+	0x000e, 0xc0cc, 0xa87e, 0x001e, 0xa874, 0x0006, 0x2148, 0x080c,
+	0x0ff5, 0x001e, 0x0458, 0x0016, 0x080c, 0x0ff5, 0x009e, 0xa87c,
+	0xc0cc, 0xa87e, 0xa974, 0x0016, 0x080c, 0xb8f6, 0x001e, 0x00f0,
+	0xa867, 0x0103, 0xa974, 0x9184, 0x00ff, 0x90b6, 0x0002, 0x0180,
+	0x9086, 0x0028, 0x1118, 0xa87b, 0x001c, 0x0060, 0xd1dc, 0x0118,
+	0xa87b, 0x0015, 0x0038, 0xd1d4, 0x0118, 0xa87b, 0x0007, 0x0010,
+	0xa87b, 0x0000, 0x0016, 0x080c, 0x683d, 0x001e, 0xd1e4, 0x1120,
+	0x080c, 0x9fd5, 0x009e, 0x0005, 0x080c, 0xc03b, 0x0cd8, 0x6004,
+	0x9086, 0x0040, 0x1120, 0x080c, 0x8a84, 0x080c, 0x8b90, 0x2019,
+	0x0001, 0x080c, 0x989c, 0x6003, 0x0002, 0x080c, 0xc461, 0x080c,
+	0x8b40, 0x080c, 0x8c6d, 0x0005, 0x6004, 0x9086, 0x0040, 0x1120,
+	0x080c, 0x8a84, 0x080c, 0x8b90, 0x2019, 0x0001, 0x080c, 0x989c,
+	0x080c, 0x8b40, 0x080c, 0x30ab, 0x080c, 0xc459, 0x0096, 0x6114,
+	0x2148, 0x080c, 0xbd3b, 0x0150, 0xa867, 0x0103, 0xa87b, 0x0029,
+	0xa877, 0x0000, 0x080c, 0x6a23, 0x080c, 0xbf26, 0x009e, 0x080c,
+	0x9fd5, 0x080c, 0x8c6d, 0x0005, 0xa87b, 0x0015, 0xd1fc, 0x0180,
+	0xa87b, 0x0007, 0x8002, 0x8000, 0x810a, 0x9189, 0x0000, 0x0006,
+	0x0016, 0x2009, 0x1a55, 0x2104, 0x8000, 0x200a, 0x001e, 0x000e,
+	0xa992, 0xa88e, 0x0005, 0x9182, 0x0054, 0x1220, 0x9182, 0x0040,
+	0x0208, 0x000a, 0x0005, 0xb43f, 0xb43f, 0xb43f, 0xb43f, 0xb43f,
+	0xb441, 0xb43f, 0xb43f, 0xb4e7, 0xb43f, 0xb43f, 0xb43f, 0xb43f,
+	0xb43f, 0xb43f, 0xb43f, 0xb43f, 0xb43f, 0xb43f, 0xb619, 0x080c,
+	0x0e02, 0x0076, 0x00a6, 0x00e6, 0x0096, 0x2071, 0x0260, 0x6114,
+	0x2150, 0x7644, 0xb676, 0x96b4, 0x0fff, 0xb77c, 0xc7e5, 0xb77e,
+	0x6210, 0x00b6, 0x2258, 0xba3c, 0x82ff, 0x0110, 0x8211, 0xba3e,
+	0x00be, 0x86ff, 0x0904, 0xb4e0, 0x9694, 0xff00, 0x9284, 0x0c00,
+	0x0120, 0x7048, 0xb092, 0x704c, 0xb08e, 0x9284, 0x0300, 0x0904,
+	0xb4e0, 0x9686, 0x0100, 0x1130, 0x7064, 0x9005, 0x1118, 0xc6c4,
+	0xb676, 0x0c38, 0x080c, 0x1043, 0x090c, 0x0e02, 0x2900, 0xb07a,
+	0xb77c, 0x97bd, 0x0200, 0xb77e, 0xa867, 0x0103, 0xb068, 0xa86a,
+	0xb06c, 0xa86e, 0xb070, 0xa872, 0x7044, 0x9084, 0xf000, 0x9635,
+	0xae76, 0x968c, 0x0c00, 0x0120, 0x7348, 0xab92, 0x734c, 0xab8e,
+	0x968c, 0x00ff, 0x9186, 0x0002, 0x0180, 0x9186, 0x0028, 0x1118,
+	0xa87b, 0x001c, 0x0060, 0xd6dc, 0x0118, 0xa87b, 0x0015, 0x0038,
+	0xd6d4, 0x0118, 0xa87b, 0x0007, 0x0010, 0xa87b, 0x0000, 0xaf7e,
+	0xb080, 0xa882, 0xb084, 0xa886, 0x901e, 0xd6c4, 0x0190, 0x735c,
+	0xab86, 0x83ff, 0x0170, 0x938a, 0x0009, 0x0210, 0x2019, 0x0008,
+	0x0036, 0x2308, 0x2019, 0x0018, 0x2011, 0x0025, 0x080c, 0xb906,
+	0x003e, 0xd6cc, 0x01e8, 0x7154, 0xa98a, 0x81ff, 0x01c8, 0x9192,
+	0x0021, 0x1260, 0x8304, 0x9098, 0x0018, 0x2011, 0x0029, 0x080c,
+	0xb906, 0x2011, 0x0205, 0x2013, 0x0000, 0x0050, 0xb068, 0xd0fc,
+	0x0120, 0x2009, 0x0020, 0xa98a, 0x0c68, 0x2950, 0x080c, 0xb8a5,
+	0x080c, 0x1904, 0x009e, 0x00ee, 0x00ae, 0x007e, 0x0005, 0x2001,
+	0x1962, 0x2004, 0x6042, 0x0096, 0x6114, 0x2148, 0xa83c, 0xa940,
+	0x9105, 0x1118, 0xa87c, 0xc0dc, 0xa87e, 0x6003, 0x0002, 0xa97c,
+	0xd1e4, 0x0904, 0xb614, 0x6043, 0x0000, 0x6010, 0x00b6, 0x2058,
+	0xb800, 0x00be, 0xd0bc, 0x1500, 0xd1cc, 0x0904, 0xb5e3, 0xa978,
+	0xa868, 0xd0fc, 0x0904, 0xb5a4, 0x0016, 0xa87c, 0x0006, 0xa880,
+	0x0006, 0x00a6, 0x2150, 0xb174, 0x9184, 0x00ff, 0x90b6, 0x0002,
+	0x0904, 0xb571, 0x9086, 0x0028, 0x1904, 0xb55d, 0xa87b, 0x001c,
+	0xb07b, 0x001c, 0x0804, 0xb579, 0x6024, 0xd0f4, 0x11d0, 0xa838,
+	0xaa34, 0x9205, 0x09c8, 0xa838, 0xaa90, 0x9206, 0x1120, 0xa88c,
+	0xaa34, 0x9206, 0x0988, 0x6024, 0xd0d4, 0x1148, 0xa9ac, 0xa834,
+	0x9102, 0x603a, 0xa9b0, 0xa838, 0x9103, 0x603e, 0x6024, 0xc0f5,
+	0x6026, 0x6010, 0x00b6, 0x2058, 0xb83c, 0x8000, 0xb83e, 0x00be,
+	0x9006, 0xa876, 0xa892, 0xa88e, 0xa87c, 0xc0e4, 0xa87e, 0xd0cc,
+	0x0140, 0xc0cc, 0xa87e, 0x0096, 0xa878, 0x2048, 0x080c, 0x0ff5,
+	0x009e, 0x080c, 0xc075, 0x0804, 0xb614, 0xd1dc, 0x0158, 0xa87b,
+	0x0015, 0xb07b, 0x0015, 0x080c, 0xc309, 0x0118, 0xb174, 0xc1dc,
+	0xb176, 0x0078, 0xd1d4, 0x0128, 0xa87b, 0x0007, 0xb07b, 0x0007,
+	0x0040, 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938, 0x9115, 0x190c,
+	0xb40c, 0xa87c, 0xb07e, 0xa890, 0xb092, 0xa88c, 0xb08e, 0xa860,
+	0x20e8, 0xa85c, 0x9080, 0x0019, 0x20a0, 0x20a9, 0x0020, 0x8a06,
+	0x8006, 0x8007, 0x9094, 0x003f, 0x22e0, 0x9084, 0xffc0, 0x9080,
+	0x0019, 0x2098, 0x4003, 0x00ae, 0x000e, 0xa882, 0x000e, 0xc0cc,
+	0xa87e, 0x080c, 0xc3e9, 0x001e, 0xa874, 0x0006, 0x2148, 0x080c,
+	0x0ff5, 0x001e, 0x0804, 0xb610, 0x0016, 0x00a6, 0x2150, 0xb174,
+	0x9184, 0x00ff, 0x90b6, 0x0002, 0x01e0, 0x9086, 0x0028, 0x1128,
+	0xa87b, 0x001c, 0xb07b, 0x001c, 0x00e0, 0xd1dc, 0x0158, 0xa87b,
+	0x0015, 0xb07b, 0x0015, 0x080c, 0xc309, 0x0118, 0xb174, 0xc1dc,
+	0xb176, 0x0078, 0xd1d4, 0x0128, 0xa87b, 0x0007, 0xb07b, 0x0007,
+	0x0040, 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938, 0x9115, 0x190c,
+	0xb40c, 0xa890, 0xb092, 0xa88c, 0xb08e, 0xa87c, 0xb07e, 0x00ae,
+	0x080c, 0x0ff5, 0x009e, 0x080c, 0xc3e9, 0xa974, 0x0016, 0x080c,
+	0xb8f6, 0x001e, 0x0468, 0xa867, 0x0103, 0xa974, 0x9184, 0x00ff,
+	0x90b6, 0x0002, 0x01b0, 0x9086, 0x0028, 0x1118, 0xa87b, 0x001c,
+	0x00d0, 0xd1dc, 0x0148, 0xa87b, 0x0015, 0x080c, 0xc309, 0x0118,
+	0xa974, 0xc1dc, 0xa976, 0x0078, 0xd1d4, 0x0118, 0xa87b, 0x0007,
+	0x0050, 0xa87b, 0x0000, 0xa87c, 0xd0ac, 0x0128, 0xa834, 0xa938,
+	0x9115, 0x190c, 0xb40c, 0xa974, 0x0016, 0x080c, 0x683d, 0x001e,
+	0xd1e4, 0x1120, 0x080c, 0x9fd5, 0x009e, 0x0005, 0x080c, 0xc03b,
+	0x0cd8, 0x6114, 0x0096, 0x2148, 0xa97c, 0xd1e4, 0x190c, 0x1924,
+	0x009e, 0x0005, 0x080c, 0x8a84, 0x0010, 0x080c, 0x8b40, 0x080c,
+	0xbd3b, 0x01f0, 0x0096, 0x6114, 0x2148, 0x080c, 0xbf43, 0x1118,
+	0x080c, 0xa995, 0x00a0, 0xa867, 0x0103, 0x2009, 0x180c, 0x210c,
+	0xd18c, 0x11b8, 0xd184, 0x1190, 0x6108, 0xa97a, 0x918e, 0x0029,
+	0x1110, 0x080c, 0xda80, 0xa877, 0x0000, 0x080c, 0x6a23, 0x009e,
+	0x080c, 0x9fd5, 0x080c, 0x8b90, 0x0804, 0x8c6d, 0xa87b, 0x0004,
+	0x0c90, 0xa87b, 0x0004, 0x0c78, 0x9182, 0x0054, 0x1220, 0x9182,
+	0x0040, 0x0208, 0x000a, 0x0005, 0xb670, 0xb670, 0xb670, 0xb670,
+	0xb670, 0xb672, 0xb670, 0xb670, 0xb670, 0xb670, 0xb670, 0xb670,
+	0xb670, 0xb670, 0xb670, 0xb670, 0xb670, 0xb670, 0xb670, 0xb670,
+	0x080c, 0x0e02, 0x080c, 0x54e4, 0x01f8, 0x6014, 0x7144, 0x918c,
+	0x0fff, 0x9016, 0xd1c4, 0x0118, 0x7264, 0x9294, 0x00ff, 0x0096,
+	0x904d, 0x0188, 0xa87b, 0x0000, 0xa864, 0x9086, 0x0139, 0x0128,
+	0xa867, 0x0103, 0xa976, 0xaa96, 0x0030, 0xa897, 0x4000, 0xa99a,
+	0xaa9e, 0x080c, 0x6a23, 0x009e, 0x0804, 0x9fd5, 0x9182, 0x0085,
+	0x0002, 0xb6a8, 0xb6a6, 0xb6a6, 0xb6b4, 0xb6a6, 0xb6a6, 0xb6a6,
+	0xb6a6, 0xb6a6, 0xb6a6, 0xb6a6, 0xb6a6, 0xb6a6, 0x080c, 0x0e02,
+	0x6003, 0x0001, 0x6106, 0x080c, 0x85f9, 0x0126, 0x2091, 0x8000,
+	0x080c, 0x8b90, 0x012e, 0x0005, 0x0026, 0x0056, 0x00d6, 0x00e6,
+	0x2071, 0x0260, 0x7224, 0x6216, 0x7220, 0x080c, 0xbd29, 0x01f8,
+	0x2268, 0x6800, 0x9086, 0x0000, 0x01d0, 0x6010, 0x6d10, 0x952e,
+	0x11b0, 0x00c6, 0x2d60, 0x00d6, 0x080c, 0xb967, 0x00de, 0x00ce,
+	0x0158, 0x702c, 0xd084, 0x1118, 0x080c, 0xb931, 0x0010, 0x6803,
+	0x0002, 0x6007, 0x0086, 0x0028, 0x080c, 0xb953, 0x0d90, 0x6007,
+	0x0087, 0x6003, 0x0001, 0x080c, 0x85f9, 0x080c, 0x8b90, 0x7220,
+	0x080c, 0xbd29, 0x0178, 0x6810, 0x00b6, 0x2058, 0xb800, 0x00be,
+	0xd0bc, 0x0140, 0x6824, 0xd0ec, 0x0128, 0x00c6, 0x2d60, 0x080c,
+	0xc075, 0x00ce, 0x00ee, 0x00de, 0x005e, 0x002e, 0x0005, 0x9186,
+	0x0013, 0x1160, 0x6004, 0x908a, 0x0085, 0x0a0c, 0x0e02, 0x908a,
+	0x0092, 0x1a0c, 0x0e02, 0x9082, 0x0085, 0x00e2, 0x9186, 0x0027,
+	0x0120, 0x9186, 0x0014, 0x190c, 0x0e02, 0x080c, 0x8a84, 0x0096,
+	0x6014, 0x2048, 0x080c, 0xbd3b, 0x0140, 0xa867, 0x0103, 0xa877,
+	0x0000, 0xa87b, 0x0029, 0x080c, 0x6a23, 0x009e, 0x080c, 0xa007,
+	0x0804, 0x8b90, 0xb737, 0xb739, 0xb739, 0xb737, 0xb737, 0xb737,
+	0xb737, 0xb737, 0xb737, 0xb737, 0xb737, 0xb737, 0xb737, 0x080c,
+	0x0e02, 0x080c, 0x8a84, 0x080c, 0xa007, 0x080c, 0x8b90, 0x0005,
+	0x9186, 0x0013, 0x1128, 0x6004, 0x9082, 0x0085, 0x2008, 0x04b8,
+	0x9186, 0x0027, 0x11f8, 0x080c, 0x8a84, 0x080c, 0x30ab, 0x080c,
+	0xc459, 0x0096, 0x6014, 0x2048, 0x080c, 0xbd3b, 0x0150, 0xa867,
+	0x0103, 0xa877, 0x0000, 0xa87b, 0x0029, 0x080c, 0x6a23, 0x080c,
+	0xbf26, 0x009e, 0x080c, 0x9fd5, 0x080c, 0x8b90, 0x0005, 0x080c,
+	0xa06e, 0x0ce0, 0x9186, 0x0014, 0x1dd0, 0x080c, 0x8a84, 0x0096,
+	0x6014, 0x2048, 0x080c, 0xbd3b, 0x0d60, 0xa867, 0x0103, 0xa877,
+	0x0000, 0xa87b, 0x0006, 0xa880, 0xc0ec, 0xa882, 0x08f0, 0x0002,
+	0xb78f, 0xb78d, 0xb78d, 0xb78d, 0xb78d, 0xb78d, 0xb7a7, 0xb78d,
+	0xb78d, 0xb78d, 0xb78d, 0xb78d, 0xb78d, 0x080c, 0x0e02, 0x080c,
+	0x8a84, 0x6034, 0x908c, 0xff00, 0x810f, 0x9186, 0x0039, 0x0118,
+	0x9186, 0x0035, 0x1118, 0x2001, 0x1960, 0x0010, 0x2001, 0x1961,
+	0x2004, 0x601a, 0x6003, 0x000c, 0x080c, 0x8b90, 0x0005, 0x080c,
+	0x8a84, 0x6034, 0x908c, 0xff00, 0x810f, 0x9186, 0x0039, 0x0118,
+	0x9186, 0x0035, 0x1118, 0x2001, 0x1960, 0x0010, 0x2001, 0x1961,
+	0x2004, 0x601a, 0x6003, 0x000e, 0x080c, 0x8b90, 0x0005, 0x9182,
+	0x0092, 0x1220, 0x9182, 0x0085, 0x0208, 0x0012, 0x0804, 0xa06e,
+	0xb7d5, 0xb7d5, 0xb7d5, 0xb7d5, 0xb7d7, 0xb824, 0xb7d5, 0xb7d5,
+	0xb7d5, 0xb7d5, 0xb7d5, 0xb7d5, 0xb7d5, 0x080c, 0x0e02, 0x0096,
+	0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x0168, 0x6034,
+	0x908c, 0xff00, 0x810f, 0x9186, 0x0039, 0x0118, 0x9186, 0x0035,
+	0x1118, 0x009e, 0x0804, 0xb838, 0x080c, 0xbd3b, 0x1118, 0x080c,
+	0xbf26, 0x0068, 0x6014, 0x2048, 0xa87c, 0xd0e4, 0x1110, 0x080c,
+	0xbf26, 0xa867, 0x0103, 0x080c, 0xc424, 0x080c, 0x6a23, 0x00d6,
+	0x2c68, 0x080c, 0x9f7f, 0x01d0, 0x6003, 0x0001, 0x6007, 0x001e,
+	0x600b, 0xffff, 0x2009, 0x026e, 0x210c, 0x613a, 0x2009, 0x026f,
+	0x210c, 0x613e, 0x6910, 0x6112, 0x080c, 0xc1b7, 0x6954, 0x6156,
+	0x6023, 0x0001, 0x080c, 0x85f9, 0x080c, 0x8b90, 0x2d60, 0x00de,
+	0x080c, 0x9fd5, 0x009e, 0x0005, 0x6010, 0x00b6, 0x2058, 0xb800,
+	0x00be, 0xd0bc, 0x05a0, 0x6034, 0x908c, 0xff00, 0x810f, 0x9186,
+	0x0035, 0x0130, 0x9186, 0x001e, 0x0118, 0x9186, 0x0039, 0x1538,
+	0x00d6, 0x2c68, 0x080c, 0xc3bc, 0x11f0, 0x080c, 0x9f7f, 0x01d8,
+	0x6106, 0x6003, 0x0001, 0x6023, 0x0001, 0x6910, 0x6112, 0x692c,
+	0x612e, 0x6930, 0x6132, 0x6934, 0x918c, 0x00ff, 0x6136, 0x6938,
+	0x613a, 0x693c, 0x613e, 0x6954, 0x6156, 0x080c, 0xc1b7, 0x080c,
+	0x85f9, 0x080c, 0x8b90, 0x2d60, 0x00de, 0x0804, 0x9fd5, 0x0096,
+	0x6014, 0x2048, 0x080c, 0xbd3b, 0x01c8, 0xa867, 0x0103, 0xa880,
+	0xd0b4, 0x0128, 0xc0ec, 0xa882, 0xa87b, 0x0006, 0x0048, 0xd0bc,
+	0x0118, 0xa87b, 0x0002, 0x0020, 0xa87b, 0x0005, 0x080c, 0xc037,
+	0xa877, 0x0000, 0x080c, 0x6a23, 0x080c, 0xbf26, 0x009e, 0x0804,
+	0x9fd5, 0x0016, 0x0096, 0x6014, 0x2048, 0x080c, 0xbd3b, 0x0140,
+	0xa867, 0x0103, 0xa87b, 0x0028, 0xa877, 0x0000, 0x080c, 0x6a23,
+	0x009e, 0x001e, 0x9186, 0x0013, 0x0148, 0x9186, 0x0014, 0x0130,
+	0x9186, 0x0027, 0x0118, 0x080c, 0xa06e, 0x0030, 0x080c, 0x8a84,
+	0x080c, 0xa007, 0x080c, 0x8b90, 0x0005, 0x0056, 0x0066, 0x0096,
+	0x00a6, 0x2029, 0x0001, 0x9182, 0x0101, 0x1208, 0x0010, 0x2009,
+	0x0100, 0x2130, 0x8304, 0x9098, 0x0018, 0x2009, 0x0020, 0x2011,
+	0x0029, 0x080c, 0xb906, 0x96b2, 0x0020, 0xb004, 0x904d, 0x0110,
+	0x080c, 0x0ff5, 0x080c, 0x1043, 0x0520, 0x8528, 0xa867, 0x0110,
+	0xa86b, 0x0000, 0x2920, 0xb406, 0x968a, 0x003d, 0x1228, 0x2608,
+	0x2011, 0x001b, 0x0499, 0x00a8, 0x96b2, 0x003c, 0x2009, 0x003c,
+	0x2950, 0x2011, 0x001b, 0x0451, 0x0c28, 0x2001, 0x0205, 0x2003,
+	0x0000, 0x00ae, 0x852f, 0x95ad, 0x0003, 0xb566, 0x95ac, 0x0000,
+	0x0048, 0x2001, 0x0205, 0x2003, 0x0000, 0x00ae, 0x852f, 0x95ad,
+	0x0003, 0xb566, 0x009e, 0x006e, 0x005e, 0x0005, 0x00a6, 0x89ff,
+	0x0158, 0xa804, 0x9055, 0x0130, 0xa807, 0x0000, 0x080c, 0x6a23,
+	0x2a48, 0x0cb8, 0x080c, 0x6a23, 0x00ae, 0x0005, 0x00f6, 0x2079,
+	0x0200, 0x7814, 0x9085, 0x0080, 0x7816, 0xd184, 0x0108, 0x8108,
+	0x810c, 0x20a9, 0x0001, 0xa860, 0x20e8, 0xa85c, 0x9200, 0x20a0,
+	0x20e1, 0x0000, 0x2300, 0x9e00, 0x2098, 0x4003, 0x8318, 0x9386,
+	0x0020, 0x1148, 0x2018, 0x2300, 0x9e00, 0x2098, 0x7814, 0x8000,
+	0x9085, 0x0080, 0x7816, 0x8109, 0x1d80, 0x7817, 0x0000, 0x00fe,
+	0x0005, 0x6920, 0x9186, 0x0003, 0x0118, 0x9186, 0x0002, 0x11d0,
+	0x00c6, 0x00d6, 0x00e6, 0x2d60, 0x0096, 0x6014, 0x2048, 0x080c,
+	0xbd3b, 0x0150, 0x2001, 0x0006, 0xa980, 0xc1d5, 0x080c, 0x6c6c,
+	0x080c, 0x6a16, 0x080c, 0xbf26, 0x009e, 0x080c, 0xa007, 0x00ee,
+	0x00de, 0x00ce, 0x0005, 0x00c6, 0x702c, 0xd084, 0x1170, 0x6008,
+	0x2060, 0x6020, 0x9086, 0x0002, 0x1140, 0x6104, 0x9186, 0x0085,
+	0x0118, 0x9186, 0x008b, 0x1108, 0x9006, 0x00ce, 0x0005, 0x0066,
+	0x0126, 0x2091, 0x8000, 0x2031, 0x0001, 0x6020, 0x9084, 0x000f,
+	0x0083, 0x012e, 0x006e, 0x0005, 0x0126, 0x2091, 0x8000, 0x0066,
+	0x2031, 0x0000, 0x6020, 0x9084, 0x000f, 0x001b, 0x006e, 0x012e,
+	0x0005, 0xb9a2, 0xb9a2, 0xb99d, 0xb9c4, 0xb990, 0xb99d, 0xb9c4,
+	0xb99d, 0xb990, 0xb990, 0xb99d, 0xb99d, 0xb99d, 0xb990, 0xb990,
+	0x080c, 0x0e02, 0x0036, 0x2019, 0x0010, 0x080c, 0xd385, 0x6023,
+	0x0006, 0x6003, 0x0007, 0x003e, 0x0005, 0x9006, 0x0005, 0x9085,
+	0x0001, 0x0005, 0x0096, 0x86ff, 0x11d8, 0x6014, 0x2048, 0x080c,
+	0xbd3b, 0x01c0, 0xa864, 0x9086, 0x0139, 0x1128, 0xa87b, 0x0005,
+	0xa883, 0x0000, 0x0028, 0x900e, 0x2001, 0x0005, 0x080c, 0x6c6c,
+	0x080c, 0xc037, 0x080c, 0x6a16, 0x080c, 0xa007, 0x9085, 0x0001,
+	0x009e, 0x0005, 0x9006, 0x0ce0, 0x6000, 0x908a, 0x0016, 0x1a0c,
+	0x0e02, 0x0002, 0xb9da, 0xba0a, 0xb9dc, 0xba2b, 0xba05, 0xb9da,
+	0xb99d, 0xb9a2, 0xb9a2, 0xb99d, 0xb99d, 0xb99d, 0xb99d, 0xb99d,
+	0xb99d, 0xb99d, 0x080c, 0x0e02, 0x86ff, 0x1520, 0x6020, 0x9086,
+	0x0006, 0x0500, 0x0096, 0x6014, 0x2048, 0x080c, 0xbd3b, 0x0168,
+	0xa87c, 0xd0cc, 0x0140, 0x0096, 0xc0cc, 0xa87e, 0xa878, 0x2048,
+	0x080c, 0x0ff5, 0x009e, 0x080c, 0xc037, 0x009e, 0x080c, 0xc3fe,
+	0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002, 0x080c, 0x85f9,
+	0x080c, 0x8b90, 0x9085, 0x0001, 0x0005, 0x0066, 0x080c, 0x1938,
+	0x006e, 0x0890, 0x00e6, 0x2071, 0x19c2, 0x7024, 0x9c06, 0x1120,
+	0x080c, 0x9826, 0x00ee, 0x0840, 0x6020, 0x9084, 0x000f, 0x9086,
+	0x0006, 0x1150, 0x0086, 0x0096, 0x2049, 0x0001, 0x2c40, 0x080c,
+	0x994a, 0x009e, 0x008e, 0x0010, 0x080c, 0x9723, 0x00ee, 0x1904,
+	0xb9dc, 0x0804, 0xb99d, 0x0036, 0x00e6, 0x2071, 0x19c2, 0x703c,
+	0x9c06, 0x1138, 0x901e, 0x080c, 0x989c, 0x00ee, 0x003e, 0x0804,
+	0xb9dc, 0x080c, 0x9a7a, 0x00ee, 0x003e, 0x1904, 0xb9dc, 0x0804,
+	0xb99d, 0x00c6, 0x6020, 0x9084, 0x000f, 0x0013, 0x00ce, 0x0005,
+	0xba5e, 0xbb0f, 0xbc79, 0xba68, 0xa007, 0xba5e, 0xd377, 0xc466,
+	0xbb0f, 0xba57, 0xbd05, 0xba57, 0xba57, 0xba57, 0xba57, 0x080c,
+	0x0e02, 0x080c, 0xbf43, 0x1110, 0x080c, 0xa995, 0x0005, 0x080c,
+	0x8a84, 0x080c, 0x8b90, 0x0804, 0x9fd5, 0x601b, 0x0001, 0x0005,
+	0x080c, 0xbd3b, 0x0130, 0x6014, 0x0096, 0x2048, 0x2c00, 0xa896,
+	0x009e, 0x6000, 0x908a, 0x0016, 0x1a0c, 0x0e02, 0x0002, 0xba87,
+	0xba89, 0xbaad, 0xbac1, 0xbae7, 0xba87, 0xba5e, 0xba5e, 0xba5e,
+	0xbac1, 0xbac1, 0xba87, 0xba87, 0xba87, 0xba87, 0xbacb, 0x080c,
+	0x0e02, 0x00e6, 0x6014, 0x0096, 0x2048, 0xa880, 0xc0b5, 0xa882,
+	0x009e, 0x2071, 0x19c2, 0x7024, 0x9c06, 0x01a0, 0x080c, 0x9723,
+	0x080c, 0xc3fe, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002,
+	0x2001, 0x1961, 0x2004, 0x601a, 0x080c, 0x85f9, 0x080c, 0x8b90,
+	0x00ee, 0x0005, 0x601b, 0x0001, 0x0cd8, 0x0096, 0x6014, 0x2048,
+	0xa880, 0xc0b5, 0xa882, 0x009e, 0x080c, 0xc3fe, 0x6007, 0x0085,
+	0x6003, 0x000b, 0x6023, 0x0002, 0x080c, 0x85f9, 0x080c, 0x8b90,
+	0x0005, 0x0096, 0x601b, 0x0001, 0x6014, 0x2048, 0xa880, 0xc0b5,
+	0xa882, 0x009e, 0x0005, 0x080c, 0x54e4, 0x01b8, 0x6014, 0x0096,
+	0x904d, 0x0190, 0xa864, 0xa867, 0x0103, 0xa87b, 0x0006, 0x9086,
+	0x0139, 0x1150, 0xa867, 0x0139, 0xa87b, 0x0030, 0xa897, 0x4005,
+	0xa89b, 0x0004, 0x080c, 0x6a23, 0x009e, 0x0804, 0x9fd5, 0x6014,
+	0x0096, 0x904d, 0x01f8, 0xa97c, 0xd1e4, 0x01e0, 0x2001, 0x180f,
+	0x2004, 0xd0c4, 0x0110, 0x009e, 0x0005, 0xa884, 0x009e, 0x8003,
+	0x800b, 0x810b, 0x9108, 0x611a, 0x2001, 0x0037, 0x2c08, 0x080c,
+	0x158c, 0x6000, 0x9086, 0x0004, 0x1120, 0x2009, 0x0048, 0x080c,
+	0xa053, 0x0005, 0x009e, 0x080c, 0x1938, 0x0804, 0xbaad, 0x6000,
+	0x908a, 0x0016, 0x1a0c, 0x0e02, 0x000b, 0x0005, 0xbb26, 0xba65,
+	0xbb28, 0xbb26, 0xbb28, 0xbb28, 0xba5f, 0xbb26, 0xba59, 0xba59,
+	0xbb26, 0xbb26, 0xbb26, 0xbb26, 0xbb26, 0xbb26, 0x080c, 0x0e02,
+	0x6010, 0x00b6, 0x2058, 0xb804, 0x9084, 0x00ff, 0x00be, 0x908a,
+	0x000c, 0x1a0c, 0x0e02, 0x00b6, 0x0013, 0x00be, 0x0005, 0xbb43,
+	0xbc10, 0xbb45, 0xbb85, 0xbb45, 0xbb85, 0xbb45, 0xbb53, 0xbb43,
+	0xbb85, 0xbb43, 0xbb74, 0x080c, 0x0e02, 0x6004, 0x908e, 0x0016,
+	0x05c0, 0x908e, 0x0004, 0x05a8, 0x908e, 0x0002, 0x0590, 0x908e,
+	0x0052, 0x0904, 0xbc0c, 0x6004, 0x080c, 0xbf43, 0x0904, 0xbc29,
+	0x908e, 0x0004, 0x1110, 0x080c, 0x30d4, 0x908e, 0x0021, 0x0904,
+	0xbc2d, 0x908e, 0x0022, 0x0904, 0xbc74, 0x908e, 0x003d, 0x0904,
+	0xbc2d, 0x908e, 0x0039, 0x0904, 0xbc31, 0x908e, 0x0035, 0x0904,
+	0xbc31, 0x908e, 0x001e, 0x0178, 0x908e, 0x0001, 0x1140, 0x6010,
+	0x2058, 0xb804, 0x9084, 0x00ff, 0x9086, 0x0006, 0x0110, 0x080c,
+	0x30ab, 0x080c, 0xa995, 0x0804, 0xa007, 0x00c6, 0x00d6, 0x6104,
+	0x9186, 0x0016, 0x0904, 0xbbfd, 0x9186, 0x0002, 0x1904, 0xbbd2,
+	0x2001, 0x1836, 0x2004, 0xd08c, 0x11c8, 0x080c, 0x717f, 0x11b0,
+	0x080c, 0xc444, 0x0138, 0x080c, 0x71a2, 0x1120, 0x080c, 0x707d,
+	0x0804, 0xbc5d, 0x2001, 0x1957, 0x2003, 0x0001, 0x2001, 0x1800,
+	0x2003, 0x0001, 0x080c, 0x709f, 0x0804, 0xbc5d, 0x6010, 0x2058,
+	0x2001, 0x1836, 0x2004, 0xd0ac, 0x1904, 0xbc5d, 0xb8a0, 0x9084,
+	0xff80, 0x1904, 0xbc5d, 0xb840, 0x9084, 0x00ff, 0x9005, 0x0190,
+	0x8001, 0xb842, 0x6017, 0x0000, 0x6023, 0x0007, 0x601b, 0x0398,
+	0x6043, 0x0000, 0x080c, 0x9f7f, 0x0128, 0x2b00, 0x6012, 0x6023,
+	0x0001, 0x0458, 0x00de, 0x00ce, 0x6004, 0x908e, 0x0002, 0x11a0,
+	0x6010, 0x2058, 0xb8a0, 0x9086, 0x007e, 0x1170, 0x2009, 0x1836,
+	0x2104, 0xc085, 0x200a, 0x00e6, 0x2071, 0x1800, 0x080c, 0x5dc3,
+	0x00ee, 0x080c, 0xa995, 0x0030, 0x080c, 0xa995, 0x080c, 0x30ab,
+	0x080c, 0xc459, 0x00e6, 0x0126, 0x2091, 0x8000, 0x080c, 0x30d4,
+	0x012e, 0x00ee, 0x080c, 0xa007, 0x0005, 0x2001, 0x0002, 0x080c,
+	0x62f5, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x8641, 0x080c,
+	0x8b90, 0x00de, 0x00ce, 0x0c80, 0x080c, 0x30d4, 0x0804, 0xbb81,
+	0x00c6, 0x00d6, 0x6104, 0x9186, 0x0016, 0x0d38, 0x6010, 0x2058,
+	0xb840, 0x9084, 0x00ff, 0x9005, 0x0904, 0xbbd2, 0x8001, 0xb842,
+	0x6003, 0x0001, 0x080c, 0x8641, 0x080c, 0x8b90, 0x00de, 0x00ce,
+	0x0898, 0x080c, 0xa995, 0x0804, 0xbb83, 0x080c, 0xa9d1, 0x0804,
+	0xbb83, 0x00d6, 0x2c68, 0x6104, 0x080c, 0xc3bc, 0x00de, 0x0118,
+	0x080c, 0x9fd5, 0x0408, 0x6004, 0x8007, 0x6134, 0x918c, 0x00ff,
+	0x9105, 0x6036, 0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0002,
+	0x603c, 0x600a, 0x2001, 0x1961, 0x2004, 0x601a, 0x602c, 0x2c08,
+	0x2060, 0x6024, 0xd0b4, 0x0108, 0xc085, 0xc0b5, 0x6026, 0x2160,
+	0x080c, 0x85f9, 0x080c, 0x8b90, 0x0005, 0x00de, 0x00ce, 0x080c,
+	0xa995, 0x080c, 0x30ab, 0x00e6, 0x0126, 0x2091, 0x8000, 0x080c,
+	0x30d4, 0x6017, 0x0000, 0x6023, 0x0007, 0x601b, 0x0398, 0x6043,
+	0x0000, 0x012e, 0x00ee, 0x0005, 0x080c, 0xa40c, 0x1904, 0xbc29,
+	0x0005, 0x6000, 0x908a, 0x0016, 0x1a0c, 0x0e02, 0x0096, 0x00d6,
+	0x001b, 0x00de, 0x009e, 0x0005, 0xbc94, 0xbc94, 0xbc94, 0xbc94,
+	0xbc94, 0xbc94, 0xbc94, 0xbc94, 0xbc94, 0xba5e, 0xbc94, 0xba65,
+	0xbc96, 0xba65, 0xbcb0, 0xbc94, 0x080c, 0x0e02, 0x6004, 0x9086,
+	0x008b, 0x01b0, 0x6034, 0x908c, 0xff00, 0x810f, 0x9186, 0x0035,
+	0x1130, 0x602c, 0x9080, 0x0009, 0x200c, 0xc185, 0x2102, 0x6007,
+	0x008b, 0x6003, 0x000d, 0x080c, 0x85f9, 0x080c, 0x8b90, 0x0005,
+	0x080c, 0xc438, 0x0118, 0x080c, 0xc44b, 0x0010, 0x080c, 0xc459,
+	0x080c, 0xbf26, 0x080c, 0xbd3b, 0x0570, 0x080c, 0x30ab, 0x080c,
+	0xbd3b, 0x0168, 0x6014, 0x2048, 0xa867, 0x0103, 0xa87b, 0x0006,
+	0xa877, 0x0000, 0xa880, 0xc0ed, 0xa882, 0x080c, 0x6a23, 0x2c68,
+	0x080c, 0x9f7f, 0x0150, 0x6810, 0x6012, 0x080c, 0xc1b7, 0x00c6,
+	0x2d60, 0x080c, 0xa007, 0x00ce, 0x0008, 0x2d60, 0x6017, 0x0000,
+	0x6023, 0x0001, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c, 0x8641,
+	0x080c, 0x8b90, 0x00c8, 0x080c, 0xc438, 0x0138, 0x6034, 0x9086,
+	0x4000, 0x1118, 0x080c, 0x30ab, 0x08d0, 0x6034, 0x908c, 0xff00,
+	0x810f, 0x9186, 0x0039, 0x0118, 0x9186, 0x0035, 0x1118, 0x080c,
+	0x30ab, 0x0868, 0x080c, 0xa007, 0x0005, 0x6000, 0x908a, 0x0016,
+	0x1a0c, 0x0e02, 0x0002, 0xbd1b, 0xbd1b, 0xbd1d, 0xbd1d, 0xbd1d,
+	0xbd1b, 0xbd1b, 0xa007, 0xbd1b, 0xbd1b, 0xbd1b, 0xbd1b, 0xbd1b,
+	0xbd1b, 0xbd1b, 0xbd1b, 0x080c, 0x0e02, 0x080c, 0x9a7a, 0x6114,
+	0x0096, 0x2148, 0xa87b, 0x0006, 0x080c, 0x6a23, 0x009e, 0x0804,
+	0x9fd5, 0x9284, 0x0007, 0x1158, 0x9282, 0x1cd0, 0x0240, 0x2001,
+	0x1819, 0x2004, 0x9202, 0x1218, 0x9085, 0x0001, 0x0005, 0x9006,
+	0x0ce8, 0x0096, 0x0028, 0x0096, 0x0006, 0x6014, 0x2048, 0x000e,
+	0x0006, 0x9984, 0xf000, 0x9086, 0xf000, 0x0110, 0x080c, 0x10ee,
+	0x000e, 0x009e, 0x0005, 0x00e6, 0x00c6, 0x0036, 0x0006, 0x0126,
+	0x2091, 0x8000, 0x2061, 0x1cd0, 0x2071, 0x1800, 0x7350, 0x7070,
+	0x9302, 0x1640, 0x6020, 0x9206, 0x11f8, 0x080c, 0xc444, 0x0180,
+	0x9286, 0x0001, 0x1168, 0x6004, 0x9086, 0x0004, 0x1148, 0x080c,
+	0x30ab, 0x080c, 0xc459, 0x00c6, 0x080c, 0xa007, 0x00ce, 0x0060,
+	0x080c, 0xc131, 0x0148, 0x080c, 0xbf43, 0x1110, 0x080c, 0xa995,
+	0x00c6, 0x080c, 0x9fd5, 0x00ce, 0x9ce0, 0x0018, 0x7064, 0x9c02,
+	0x1208, 0x08a0, 0x012e, 0x000e, 0x003e, 0x00ce, 0x00ee, 0x0005,
+	0x00e6, 0x00c6, 0x0016, 0x9188, 0x1000, 0x210c, 0x81ff, 0x0128,
+	0x2061, 0x1a88, 0x6112, 0x080c, 0x30ab, 0x9006, 0x0010, 0x9085,
+	0x0001, 0x001e, 0x00ce, 0x00ee, 0x0005, 0x00c6, 0x0126, 0x2091,
+	0x8000, 0x080c, 0x9f7f, 0x01b0, 0x6656, 0x2b00, 0x6012, 0x080c,
+	0x54e4, 0x0118, 0x080c, 0xbe6a, 0x0168, 0x080c, 0xc1b7, 0x6023,
+	0x0003, 0x2009, 0x004b, 0x080c, 0xa053, 0x9085, 0x0001, 0x012e,
+	0x00ce, 0x0005, 0x9006, 0x0cd8, 0x00c6, 0x0126, 0x2091, 0x8000,
+	0xbaa0, 0x080c, 0xa026, 0x0560, 0x6057, 0x0000, 0x2b00, 0x6012,
+	0x080c, 0xc1b7, 0x6023, 0x0003, 0x0016, 0x080c, 0x8783, 0x0076,
+	0x903e, 0x080c, 0x8671, 0x2c08, 0x080c, 0xd53b, 0x007e, 0x001e,
+	0xd184, 0x0128, 0x080c, 0x9fd5, 0x9085, 0x0001, 0x0070, 0x080c,
+	0x54e4, 0x0128, 0xd18c, 0x1170, 0x080c, 0xbe6a, 0x0148, 0x2009,
+	0x004c, 0x080c, 0xa053, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005,
+	0x9006, 0x0cd8, 0x2900, 0x6016, 0x0c90, 0x2009, 0x004d, 0x0010,
+	0x2009, 0x004e, 0x00f6, 0x00c6, 0x0046, 0x0016, 0x080c, 0x9f7f,
+	0x2c78, 0x05a0, 0x7e56, 0x2b00, 0x7812, 0x7823, 0x0003, 0x0016,
+	0x2021, 0x0005, 0x080c, 0xbe7c, 0x001e, 0x9186, 0x004d, 0x0118,
+	0x9186, 0x004e, 0x0148, 0x2001, 0x195a, 0x200c, 0xd1fc, 0x0168,
+	0x2f60, 0x080c, 0x9fd5, 0x00d0, 0x2001, 0x1959, 0x200c, 0xd1fc,
+	0x0120, 0x2f60, 0x080c, 0x9fd5, 0x0088, 0x2f60, 0x080c, 0x54e4,
+	0x0138, 0xd18c, 0x1118, 0x04f1, 0x0148, 0x0010, 0x2900, 0x7816,
+	0x001e, 0x0016, 0x080c, 0xa053, 0x9085, 0x0001, 0x001e, 0x004e,
+	0x00ce, 0x00fe, 0x0005, 0x00f6, 0x00c6, 0x0046, 0x080c, 0x9f7f,
+	0x2c78, 0x0508, 0x7e56, 0x2b00, 0x7812, 0x7823, 0x0003, 0x0096,
+	0x2021, 0x0004, 0x0489, 0x009e, 0x2001, 0x1958, 0x200c, 0xd1fc,
+	0x0120, 0x2f60, 0x080c, 0x9fd5, 0x0060, 0x2f60, 0x080c, 0x54e4,
+	0x0120, 0xd18c, 0x1160, 0x0071, 0x0130, 0x2009, 0x0052, 0x080c,
+	0xa053, 0x9085, 0x0001, 0x004e, 0x00ce, 0x00fe, 0x0005, 0x2900,
+	0x7816, 0x0c98, 0x00c6, 0x080c, 0x49b8, 0x00ce, 0x1120, 0x080c,
+	0x9fd5, 0x9006, 0x0005, 0xa867, 0x0000, 0xa86b, 0x8000, 0x2900,
+	0x6016, 0x9085, 0x0001, 0x0005, 0x0096, 0x0076, 0x0126, 0x2091,
+	0x8000, 0x080c, 0x64d8, 0x0158, 0x2001, 0xbe81, 0x0006, 0x900e,
+	0x2400, 0x080c, 0x6c6c, 0x080c, 0x6a23, 0x000e, 0x0807, 0x2418,
+	0x080c, 0x8a1e, 0xbaa0, 0x0086, 0x2041, 0x0001, 0x2039, 0x0001,
+	0x2608, 0x080c, 0x879b, 0x008e, 0x080c, 0x8671, 0x2f08, 0x2648,
+	0x080c, 0xd53b, 0xb93c, 0x81ff, 0x090c, 0x886e, 0x080c, 0x8b90,
+	0x012e, 0x007e, 0x009e, 0x0005, 0x00c6, 0x0126, 0x2091, 0x8000,
+	0x080c, 0x9f7f, 0x0190, 0x660a, 0x2b08, 0x6112, 0x080c, 0xc1b7,
+	0x6023, 0x0001, 0x2900, 0x6016, 0x2009, 0x001f, 0x080c, 0xa053,
+	0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x00c6,
+	0x0126, 0x2091, 0x8000, 0x080c, 0xa026, 0x01b8, 0x660a, 0x2b08,
+	0x6112, 0x080c, 0xc1b7, 0x6023, 0x0008, 0x2900, 0x6016, 0x00f6,
+	0x2c78, 0x080c, 0x165d, 0x00fe, 0x2009, 0x0021, 0x080c, 0xa053,
+	0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8, 0x2009,
+	0x003d, 0x00c6, 0x0126, 0x0016, 0x2091, 0x8000, 0x080c, 0x9f7f,
+	0x0198, 0x660a, 0x2b08, 0x6112, 0x080c, 0xc1b7, 0x6023, 0x0001,
+	0x2900, 0x6016, 0x001e, 0x0016, 0x080c, 0xa053, 0x9085, 0x0001,
+	0x001e, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd0, 0x00c6, 0x0126,
+	0x2091, 0x8000, 0x080c, 0xa026, 0x0188, 0x2b08, 0x6112, 0x080c,
+	0xc1b7, 0x6023, 0x0001, 0x2900, 0x6016, 0x2009, 0x0000, 0x080c,
+	0xa053, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006, 0x0cd8,
+	0x2009, 0x0044, 0x0830, 0x2009, 0x0049, 0x0818, 0x0026, 0x00b6,
+	0x6210, 0x2258, 0xba3c, 0x82ff, 0x0110, 0x8211, 0xba3e, 0x00be,
+	0x002e, 0x0005, 0x0006, 0x0016, 0x6004, 0x908e, 0x0002, 0x0140,
+	0x908e, 0x0003, 0x0128, 0x908e, 0x0004, 0x0110, 0x9085, 0x0001,
+	0x001e, 0x000e, 0x0005, 0x0006, 0x0086, 0x0096, 0x6020, 0x9086,
+	0x0004, 0x01a8, 0x6014, 0x904d, 0x080c, 0xbd3b, 0x0180, 0xa864,
+	0x9086, 0x0139, 0x0170, 0x6020, 0x90c6, 0x0003, 0x0140, 0x90c6,
+	0x0002, 0x0128, 0xa868, 0xd0fc, 0x0110, 0x9006, 0x0010, 0x9085,
+	0x0001, 0x009e, 0x008e, 0x000e, 0x0005, 0x00c6, 0x0126, 0x2091,
+	0x8000, 0x080c, 0xa026, 0x0198, 0x2b08, 0x6112, 0x080c, 0xc1b7,
+	0x6023, 0x0001, 0x2900, 0x6016, 0x080c, 0x30ab, 0x2009, 0x0028,
+	0x080c, 0xa053, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006,
+	0x0cd8, 0x9186, 0x0015, 0x11a8, 0x2011, 0x1823, 0x2204, 0x9086,
+	0x0074, 0x1178, 0x00b6, 0x080c, 0xac3a, 0x00be, 0x080c, 0xae86,
+	0x6003, 0x0001, 0x6007, 0x0029, 0x080c, 0x8641, 0x080c, 0x8b90,
+	0x0078, 0x6014, 0x0096, 0x2048, 0xa868, 0x009e, 0xd0fc, 0x0148,
+	0x2001, 0x0001, 0x080c, 0xc37d, 0x080c, 0xa995, 0x080c, 0x9fd5,
+	0x0005, 0x0096, 0x6014, 0x904d, 0x090c, 0x0e02, 0xa87b, 0x0030,
+	0xa883, 0x0000, 0xa897, 0x4005, 0xa89b, 0x0004, 0xa867, 0x0139,
+	0x0126, 0x2091, 0x8000, 0x080c, 0x6a23, 0x012e, 0x009e, 0x080c,
+	0x9fd5, 0x0c30, 0x0096, 0x9186, 0x0016, 0x1128, 0x2001, 0x0004,
+	0x080c, 0x62f5, 0x00e8, 0x9186, 0x0015, 0x1510, 0x2011, 0x1823,
+	0x2204, 0x9086, 0x0014, 0x11e0, 0x6010, 0x00b6, 0x2058, 0x080c,
+	0x643f, 0x00be, 0x080c, 0xaf57, 0x1198, 0x6010, 0x00b6, 0x2058,
+	0xb890, 0x00be, 0x9005, 0x0160, 0x2001, 0x0006, 0x080c, 0x62f5,
+	0x6014, 0x2048, 0xa868, 0xd0fc, 0x0170, 0x080c, 0xa3e0, 0x0048,
+	0x6014, 0x2048, 0xa868, 0xd0fc, 0x0528, 0x080c, 0xa995, 0x080c,
+	0x9fd5, 0x009e, 0x0005, 0x6014, 0x6310, 0x2358, 0x904d, 0x090c,
+	0x0e02, 0xa87b, 0x0000, 0xa883, 0x0000, 0xa897, 0x4000, 0x900e,
+	0x080c, 0x65c4, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d,
+	0xa99a, 0x0126, 0x2091, 0x8000, 0x080c, 0x6a23, 0x012e, 0x080c,
+	0x9fd5, 0x08f8, 0x6014, 0x904d, 0x090c, 0x0e02, 0xa87b, 0x0030,
+	0xa883, 0x0000, 0xa897, 0x4005, 0xa89b, 0x0004, 0xa867, 0x0139,
+	0x0126, 0x2091, 0x8000, 0x080c, 0x6a23, 0x012e, 0x080c, 0x9fd5,
+	0x0840, 0xa878, 0x9086, 0x0005, 0x1108, 0x0009, 0x0005, 0xa880,
+	0xc0ad, 0xa882, 0x0005, 0x6043, 0x0000, 0x6017, 0x0000, 0x6003,
+	0x0001, 0x6007, 0x0050, 0x080c, 0x85f9, 0x080c, 0x8b90, 0x0005,
+	0x00c6, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x0120,
+	0x6020, 0x9084, 0x000f, 0x0013, 0x00ce, 0x0005, 0xba5e, 0xc067,
+	0xc067, 0xc06a, 0xd825, 0xd840, 0xd843, 0xba5e, 0xba5e, 0xba5e,
+	0xba5e, 0xba5e, 0xba5e, 0xba5e, 0xba5e, 0x080c, 0x0e02, 0xa001,
+	0xa001, 0x0005, 0x0096, 0x6014, 0x904d, 0x0118, 0xa87c, 0xd0e4,
+	0x1110, 0x009e, 0x0010, 0x009e, 0x0005, 0x6010, 0x00b6, 0x2058,
+	0xb800, 0x00be, 0xd0bc, 0x0550, 0x2001, 0x1833, 0x2004, 0x9005,
+	0x1540, 0x00f6, 0x2c78, 0x080c, 0x9f7f, 0x0508, 0x7810, 0x6012,
+	0x080c, 0xc1b7, 0x7820, 0x9086, 0x0003, 0x0128, 0x7808, 0x603a,
+	0x2f00, 0x603e, 0x0020, 0x7808, 0x603e, 0x2f00, 0x603a, 0x602e,
+	0x6023, 0x0001, 0x6007, 0x0035, 0x6003, 0x0001, 0x7954, 0x6156,
+	0x080c, 0x85f9, 0x080c, 0x8b90, 0x2f60, 0x00fe, 0x0005, 0x2f60,
+	0x00fe, 0x2001, 0x1962, 0x2004, 0x6042, 0x0005, 0x0016, 0x0096,
+	0x6814, 0x2048, 0xa87c, 0xd0e4, 0x0180, 0xc0e4, 0xa87e, 0xa877,
+	0x0000, 0xa893, 0x0000, 0xa88f, 0x0000, 0xd0cc, 0x0130, 0xc0cc,
+	0xa87e, 0xa878, 0x2048, 0x080c, 0x0ff5, 0x6830, 0x6036, 0x908e,
+	0x0001, 0x0148, 0x6803, 0x0002, 0x9086, 0x0005, 0x0170, 0x9006,
+	0x602e, 0x6032, 0x00d0, 0x681c, 0xc085, 0x681e, 0x6803, 0x0004,
+	0x6824, 0xc0f4, 0x9085, 0x0c00, 0x6826, 0x6814, 0x2048, 0xa8ac,
+	0x6938, 0x9102, 0xa8b0, 0x693c, 0x9103, 0x1e48, 0x683c, 0x602e,
+	0x6838, 0x9084, 0xfffc, 0x683a, 0x6032, 0x2d00, 0x603a, 0x6808,
+	0x603e, 0x6910, 0x6112, 0x6954, 0x6156, 0x6023, 0x0001, 0x6007,
+	0x0039, 0x6003, 0x0001, 0x080c, 0x85f9, 0x080c, 0x8b90, 0x009e,
+	0x001e, 0x0005, 0x6024, 0xd0d4, 0x0510, 0xd0f4, 0x11f8, 0x6038,
+	0x940a, 0x603c, 0x9303, 0x0230, 0x9105, 0x0120, 0x6024, 0xc0d4,
+	0xc0f5, 0x0098, 0x643a, 0x633e, 0xac3e, 0xab42, 0x0046, 0x0036,
+	0x2400, 0xacac, 0x9402, 0xa836, 0x2300, 0xabb0, 0x9303, 0xa83a,
+	0x003e, 0x004e, 0x6024, 0xc0d4, 0x0000, 0x6026, 0x0005, 0xd0f4,
+	0x1138, 0xa83c, 0x603a, 0xa840, 0x603e, 0x6024, 0xc0f5, 0x6026,
+	0x0005, 0x0006, 0x0016, 0x6004, 0x908e, 0x0034, 0x01b8, 0x908e,
+	0x0035, 0x01a0, 0x908e, 0x0036, 0x0188, 0x908e, 0x0037, 0x0170,
+	0x908e, 0x0038, 0x0158, 0x908e, 0x0039, 0x0140, 0x908e, 0x003a,
+	0x0128, 0x908e, 0x003b, 0x0110, 0x9085, 0x0001, 0x001e, 0x000e,
+	0x0005, 0x0006, 0x0016, 0x0026, 0x0036, 0x00e6, 0x2001, 0x195c,
+	0x200c, 0x8000, 0x2014, 0x2001, 0x0032, 0x080c, 0x847f, 0x2001,
+	0x1960, 0x82ff, 0x1110, 0x2011, 0x0014, 0x2202, 0x2001, 0x195e,
+	0x200c, 0x8000, 0x2014, 0x2071, 0x1946, 0x711a, 0x721e, 0x2001,
+	0x0064, 0x080c, 0x847f, 0x2001, 0x1961, 0x82ff, 0x1110, 0x2011,
+	0x0014, 0x2202, 0x2001, 0x1962, 0x9288, 0x000a, 0x2102, 0x2001,
+	0x1a69, 0x2102, 0x2001, 0x0032, 0x080c, 0x158c, 0x080c, 0x66ab,
+	0x00ee, 0x003e, 0x002e, 0x001e, 0x000e, 0x0005, 0x0006, 0x0016,
+	0x00e6, 0x2001, 0x1960, 0x2003, 0x0028, 0x2001, 0x1961, 0x2003,
+	0x0014, 0x2071, 0x1946, 0x701b, 0x0000, 0x701f, 0x07d0, 0x2001,
+	0x1962, 0x2009, 0x001e, 0x2102, 0x2001, 0x1a69, 0x2102, 0x2001,
+	0x0032, 0x080c, 0x158c, 0x00ee, 0x001e, 0x000e, 0x0005, 0x0096,
+	0x6058, 0x904d, 0x0110, 0x080c, 0x1075, 0x009e, 0x0005, 0x0005,
+	0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0x9f7f, 0x0180, 0x2b08,
+	0x6112, 0x0ca9, 0x6023, 0x0001, 0x2900, 0x6016, 0x2009, 0x0033,
+	0x080c, 0xa053, 0x9085, 0x0001, 0x012e, 0x00ce, 0x0005, 0x9006,
+	0x0cd8, 0x0096, 0x00e6, 0x00f6, 0x2071, 0x1800, 0x9186, 0x0015,
+	0x1520, 0x708c, 0x9086, 0x0018, 0x0120, 0x708c, 0x9086, 0x0014,
 	0x11e0, 0x6014, 0x2048, 0xaa3c, 0xd2e4, 0x1160, 0x2c78, 0x080c,
-	0x8e03, 0x01d8, 0x7078, 0xaa50, 0x9206, 0x1160, 0x707c, 0xaa54,
+	0x8d94, 0x01d8, 0x7078, 0xaa50, 0x9206, 0x1160, 0x707c, 0xaa54,
 	0x9206, 0x1140, 0x6210, 0x00b6, 0x2258, 0xbaa0, 0x00be, 0x900e,
-	0x080c, 0x31d4, 0x080c, 0xa4e7, 0x0020, 0x080c, 0xaa81, 0x080c,
-	0xa0e3, 0x00fe, 0x00ee, 0x009e, 0x0005, 0x705c, 0xaa54, 0x9206,
-	0x0d48, 0x0c80, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0xa08d,
-	0x0188, 0x2b08, 0x6112, 0x080c, 0xc2b3, 0x6023, 0x0001, 0x2900,
-	0x6016, 0x2009, 0x004d, 0x080c, 0xa15d, 0x9085, 0x0001, 0x012e,
+	0x080c, 0x30f4, 0x080c, 0xa3e0, 0x0020, 0x080c, 0xa995, 0x080c,
+	0x9fd5, 0x00fe, 0x00ee, 0x009e, 0x0005, 0x705c, 0xaa54, 0x9206,
+	0x0d48, 0x0c80, 0x00c6, 0x0126, 0x2091, 0x8000, 0x080c, 0x9f7f,
+	0x0188, 0x2b08, 0x6112, 0x080c, 0xc1b7, 0x6023, 0x0001, 0x2900,
+	0x6016, 0x2009, 0x004d, 0x080c, 0xa053, 0x9085, 0x0001, 0x012e,
 	0x00ce, 0x0005, 0x9006, 0x0cd8, 0x00c6, 0x0126, 0x2091, 0x8000,
-	0x0016, 0x080c, 0xa08d, 0x0180, 0x2b08, 0x6112, 0x080c, 0xc2b3,
-	0x6023, 0x0001, 0x2900, 0x6016, 0x001e, 0x080c, 0xa15d, 0x9085,
+	0x0016, 0x080c, 0x9f7f, 0x0180, 0x2b08, 0x6112, 0x080c, 0xc1b7,
+	0x6023, 0x0001, 0x2900, 0x6016, 0x001e, 0x080c, 0xa053, 0x9085,
 	0x0001, 0x012e, 0x00ce, 0x0005, 0x001e, 0x9006, 0x0cd0, 0x0016,
 	0x0026, 0x0036, 0x0046, 0x0056, 0x0066, 0x0096, 0x00e6, 0x00f6,
 	0x2071, 0x1800, 0x9186, 0x0015, 0x1568, 0x718c, 0x6014, 0x2048,
-	0xa814, 0x8003, 0x9106, 0x1530, 0x20e1, 0x0000, 0x2001, 0x1978,
+	0xa814, 0x8003, 0x9106, 0x1530, 0x20e1, 0x0000, 0x2001, 0x197a,
 	0x2003, 0x0000, 0x6014, 0x2048, 0xa830, 0x20a8, 0x8906, 0x8006,
 	0x8007, 0x9094, 0x003f, 0x22e8, 0x9084, 0xffc0, 0x9080, 0x001b,
-	0x20a0, 0x2001, 0x1978, 0x0016, 0x200c, 0x080c, 0xcb1d, 0x001e,
+	0x20a0, 0x2001, 0x197a, 0x0016, 0x200c, 0x080c, 0xca60, 0x001e,
 	0xa804, 0x9005, 0x0110, 0x2048, 0x0c38, 0x6014, 0x2048, 0xa867,
-	0x0103, 0x0010, 0x080c, 0xaa81, 0x080c, 0xa0e3, 0x00fe, 0x00ee,
+	0x0103, 0x0010, 0x080c, 0xa995, 0x080c, 0x9fd5, 0x00fe, 0x00ee,
 	0x009e, 0x006e, 0x005e, 0x004e, 0x003e, 0x002e, 0x001e, 0x0005,
 	0x0096, 0x00e6, 0x00f6, 0x2071, 0x1800, 0x9186, 0x0015, 0x11b8,
 	0x708c, 0x9086, 0x0004, 0x1198, 0x6014, 0x2048, 0x2c78, 0x080c,
-	0x8e03, 0x01a8, 0x7078, 0xaa74, 0x9206, 0x1130, 0x707c, 0xaa78,
-	0x9206, 0x1110, 0x080c, 0x318b, 0x080c, 0xa4e7, 0x0020, 0x080c,
-	0xaa81, 0x080c, 0xa0e3, 0x00fe, 0x00ee, 0x009e, 0x0005, 0x705c,
+	0x8d94, 0x01a8, 0x7078, 0xaa74, 0x9206, 0x1130, 0x707c, 0xaa78,
+	0x9206, 0x1110, 0x080c, 0x30ab, 0x080c, 0xa3e0, 0x0020, 0x080c,
+	0xa995, 0x080c, 0x9fd5, 0x00fe, 0x00ee, 0x009e, 0x0005, 0x705c,
 	0xaa78, 0x9206, 0x0d78, 0x0c80, 0x0096, 0x00e6, 0x00f6, 0x2071,
 	0x1800, 0x9186, 0x0015, 0x1550, 0x708c, 0x9086, 0x0004, 0x1530,
-	0x6014, 0x2048, 0x2c78, 0x080c, 0x8e03, 0x05f0, 0x7078, 0xaacc,
-	0x9206, 0x1180, 0x707c, 0xaad0, 0x9206, 0x1160, 0x080c, 0x318b,
-	0x0016, 0xa998, 0xaab0, 0x9284, 0x1000, 0xc0fd, 0x080c, 0x558a,
-	0x001e, 0x0010, 0x080c, 0x5375, 0x080c, 0xbe37, 0x0508, 0xa87b,
-	0x0000, 0xa883, 0x0000, 0xa897, 0x4000, 0x0080, 0x080c, 0xbe37,
-	0x01b8, 0x6014, 0x2048, 0x080c, 0x5375, 0x1d70, 0xa87b, 0x0030,
+	0x6014, 0x2048, 0x2c78, 0x080c, 0x8d94, 0x05f0, 0x7078, 0xaacc,
+	0x9206, 0x1180, 0x707c, 0xaad0, 0x9206, 0x1160, 0x080c, 0x30ab,
+	0x0016, 0xa998, 0xaab0, 0x9284, 0x1000, 0xc0fd, 0x080c, 0x548b,
+	0x001e, 0x0010, 0x080c, 0x5276, 0x080c, 0xbd3b, 0x0508, 0xa87b,
+	0x0000, 0xa883, 0x0000, 0xa897, 0x4000, 0x0080, 0x080c, 0xbd3b,
+	0x01b8, 0x6014, 0x2048, 0x080c, 0x5276, 0x1d70, 0xa87b, 0x0030,
 	0xa883, 0x0000, 0xa897, 0x4005, 0xa89b, 0x0004, 0x0126, 0x2091,
-	0x8000, 0xa867, 0x0139, 0x080c, 0x6ae9, 0x012e, 0x080c, 0xa0e3,
+	0x8000, 0xa867, 0x0139, 0x080c, 0x6a23, 0x012e, 0x080c, 0x9fd5,
 	0x00fe, 0x00ee, 0x009e, 0x0005, 0x705c, 0xaad0, 0x9206, 0x0930,
 	0x0888, 0x0016, 0x0026, 0xa87c, 0xd0ac, 0x0178, 0xa938, 0xaa34,
 	0x2100, 0x9205, 0x0150, 0xa890, 0x9106, 0x1118, 0xa88c, 0x9206,
 	0x0120, 0xa992, 0xaa8e, 0x9085, 0x0001, 0x002e, 0x001e, 0x0005,
-	0x00b6, 0x00d6, 0x0036, 0x080c, 0xbe37, 0x0904, 0xc46e, 0x0096,
+	0x00b6, 0x00d6, 0x0036, 0x080c, 0xbd3b, 0x0904, 0xc379, 0x0096,
 	0x6314, 0x2348, 0xa87a, 0xa982, 0x929e, 0x4000, 0x1580, 0x6310,
 	0x00c6, 0x2358, 0x2009, 0x0000, 0xa868, 0xd0f4, 0x1140, 0x080c,
-	0x66bf, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0xaa96,
+	0x65c4, 0x1108, 0xc185, 0xb800, 0xd0bc, 0x0108, 0xc18d, 0xaa96,
 	0xa99a, 0x20a9, 0x0004, 0xa860, 0x20e8, 0xa85c, 0x9080, 0x0031,
 	0x20a0, 0xb8b4, 0x20e0, 0xb8b8, 0x9080, 0x0006, 0x2098, 0x080c,
-	0x0fae, 0x20a9, 0x0004, 0xa85c, 0x9080, 0x0035, 0x20a0, 0xb8b8,
-	0x9080, 0x000a, 0x2098, 0x080c, 0x0fae, 0x00ce, 0x0090, 0xaa96,
+	0x0fc0, 0x20a9, 0x0004, 0xa85c, 0x9080, 0x0035, 0x20a0, 0xb8b8,
+	0x9080, 0x000a, 0x2098, 0x080c, 0x0fc0, 0x00ce, 0x0090, 0xaa96,
 	0x3918, 0x9398, 0x0007, 0x231c, 0x6004, 0x9086, 0x0016, 0x0110,
 	0xa89b, 0x0004, 0xaba2, 0x6310, 0x2358, 0xb804, 0x9084, 0x00ff,
-	0xa89e, 0x080c, 0x6adc, 0x6017, 0x0000, 0x009e, 0x003e, 0x00de,
-	0x00be, 0x0005, 0x0026, 0x0036, 0x0046, 0x00b6, 0x0096, 0x00f6,
-	0x6214, 0x2248, 0x6210, 0x2258, 0x2079, 0x0260, 0x9096, 0x0000,
-	0x11a0, 0xb814, 0x9084, 0x00ff, 0x900e, 0x080c, 0x276e, 0x2118,
-	0x831f, 0x939c, 0xff00, 0x7838, 0x9084, 0x00ff, 0x931d, 0x7c3c,
-	0x2011, 0x8018, 0x080c, 0x4b1f, 0x00a8, 0x9096, 0x0001, 0x1148,
-	0x89ff, 0x0180, 0xa89b, 0x000d, 0x7838, 0xa8a6, 0x783c, 0xa8aa,
-	0x0048, 0x9096, 0x0002, 0x1130, 0xa89b, 0x000d, 0x7838, 0xa8a6,
-	0x783c, 0xa8aa, 0x00fe, 0x009e, 0x00be, 0x004e, 0x003e, 0x002e,
-	0x0005, 0x00c6, 0x0026, 0x0016, 0x9186, 0x0035, 0x0110, 0x6a38,
-	0x0008, 0x6a2c, 0x080c, 0xbe25, 0x01f0, 0x2260, 0x6120, 0x9186,
-	0x0003, 0x0118, 0x9186, 0x0006, 0x1190, 0x6838, 0x9206, 0x0140,
-	0x683c, 0x9206, 0x1160, 0x6108, 0x6838, 0x9106, 0x1140, 0x0020,
-	0x6008, 0x693c, 0x9106, 0x1118, 0x6010, 0x6910, 0x9106, 0x001e,
-	0x002e, 0x00ce, 0x0005, 0x9085, 0x0001, 0x0cc8, 0xa974, 0xd1cc,
-	0x0188, 0x918c, 0x00ff, 0x918e, 0x0002, 0x1160, 0xa9a8, 0x918c,
-	0x0f00, 0x810f, 0x918e, 0x0001, 0x1128, 0xa834, 0xa938, 0x9115,
-	0x190c, 0xb4ee, 0x0005, 0x0036, 0x2019, 0x0001, 0x0010, 0x0036,
-	0x901e, 0x0499, 0x01e0, 0x080c, 0xbe37, 0x01c8, 0x080c, 0xc022,
-	0x6037, 0x4000, 0x6014, 0x6017, 0x0000, 0x0096, 0x2048, 0xa87c,
-	0x080c, 0xc03f, 0x1118, 0x080c, 0xaa81, 0x0040, 0xa867, 0x0103,
-	0xa877, 0x0000, 0x83ff, 0x1129, 0x080c, 0x6ae9, 0x009e, 0x003e,
-	0x0005, 0xa880, 0xd0b4, 0x0128, 0xa87b, 0x0006, 0xc0ec, 0xa882,
-	0x0048, 0xd0bc, 0x0118, 0xa87b, 0x0002, 0x0020, 0xa87b, 0x0005,
-	0x080c, 0xc133, 0xa877, 0x0000, 0x0005, 0x2001, 0x1810, 0x2004,
-	0xd0ec, 0x0005, 0x0006, 0x2001, 0x1810, 0x2004, 0xd0f4, 0x000e,
-	0x0005, 0x0006, 0x2001, 0x1810, 0x2004, 0xd0e4, 0x000e, 0x0005,
-	0x0036, 0x0046, 0x6010, 0x00b6, 0x2058, 0xbba0, 0x00be, 0x2021,
-	0x0007, 0x080c, 0x4cbc, 0x004e, 0x003e, 0x0005, 0x0c51, 0x1d81,
-	0x0005, 0x2001, 0x195e, 0x2004, 0x601a, 0x0005, 0x2001, 0x1960,
-	0x2004, 0x6042, 0x0005, 0x080c, 0xa0e3, 0x0804, 0x8c10, 0x00b6,
-	0x0066, 0x6000, 0x90b2, 0x0016, 0x1a0c, 0x0dfa, 0x001b, 0x006e,
-	0x00be, 0x0005, 0xc57a, 0xcc7a, 0xcdd5, 0xc57a, 0xc57a, 0xc57a,
-	0xc57a, 0xc57a, 0xc5b1, 0xce59, 0xc57a, 0xc57a, 0xc57a, 0xc57a,
-	0xc57a, 0xc57a, 0x080c, 0x0dfa, 0x0066, 0x6000, 0x90b2, 0x0016,
-	0x1a0c, 0x0dfa, 0x0013, 0x006e, 0x0005, 0xc595, 0xd3cb, 0xc595,
-	0xc595, 0xc595, 0xc595, 0xc595, 0xc595, 0xd378, 0xd41f, 0xc595,
-	0xda0f, 0xda45, 0xda0f, 0xda45, 0xc595, 0x080c, 0x0dfa, 0x6000,
-	0x9082, 0x0016, 0x1a0c, 0x0dfa, 0x6000, 0x000a, 0x0005, 0xc5af,
-	0xd037, 0xd129, 0xd14c, 0xd20c, 0xc5af, 0xd2eb, 0xd294, 0xce65,
-	0xd34e, 0xd363, 0xc5af, 0xc5af, 0xc5af, 0xc5af, 0xc5af, 0x080c,
-	0x0dfa, 0x91b2, 0x0053, 0x1a0c, 0x0dfa, 0x2100, 0x91b2, 0x0040,
-	0x1a04, 0xca1b, 0x0002, 0xc5fb, 0xc7e9, 0xc5fb, 0xc5fb, 0xc5fb,
-	0xc7f2, 0xc5fb, 0xc5fb, 0xc5fb, 0xc5fb, 0xc5fb, 0xc5fb, 0xc5fb,
-	0xc5fb, 0xc5fb, 0xc5fb, 0xc5fb, 0xc5fb, 0xc5fb, 0xc5fb, 0xc5fb,
-	0xc5fb, 0xc5fb, 0xc5fd, 0xc660, 0xc66f, 0xc6d3, 0xc6fe, 0xc776,
-	0xc7d4, 0xc5fb, 0xc5fb, 0xc7f5, 0xc5fb, 0xc5fb, 0xc80a, 0xc817,
-	0xc5fb, 0xc5fb, 0xc5fb, 0xc5fb, 0xc5fb, 0xc8bd, 0xc5fb, 0xc5fb,
-	0xc8d1, 0xc5fb, 0xc5fb, 0xc88c, 0xc5fb, 0xc5fb, 0xc5fb, 0xc8e9,
-	0xc5fb, 0xc5fb, 0xc5fb, 0xc966, 0xc5fb, 0xc5fb, 0xc5fb, 0xc5fb,
-	0xc5fb, 0xc5fb, 0xc9e3, 0x080c, 0x0dfa, 0x080c, 0x6781, 0x1150,
-	0x2001, 0x1836, 0x2004, 0xd0cc, 0x1128, 0x9084, 0x0009, 0x9086,
-	0x0008, 0x1140, 0x6007, 0x0009, 0x602f, 0x0009, 0x6017, 0x0000,
-	0x0804, 0xc7e2, 0x080c, 0x676a, 0x00e6, 0x00c6, 0x0036, 0x0026,
-	0x0016, 0x6210, 0x2258, 0xbaa0, 0x0026, 0x2019, 0x0029, 0x080c,
-	0x8803, 0x0076, 0x903e, 0x080c, 0x86f1, 0x2c08, 0x080c, 0xd5f6,
-	0x007e, 0x001e, 0x001e, 0x002e, 0x003e, 0x00ce, 0x00ee, 0x6610,
-	0x2658, 0x080c, 0x64ae, 0xbe04, 0x9684, 0x00ff, 0x9082, 0x0006,
-	0x1268, 0x0016, 0x0026, 0x6210, 0x00b6, 0x2258, 0xbaa0, 0x00be,
-	0x2c08, 0x080c, 0xdbbd, 0x002e, 0x001e, 0x1178, 0x080c, 0xd529,
-	0x1904, 0xc6cb, 0x080c, 0xd4c5, 0x1120, 0x6007, 0x0008, 0x0804,
-	0xc7e2, 0x6007, 0x0009, 0x0804, 0xc7e2, 0x080c, 0xd720, 0x0128,
-	0x080c, 0xd529, 0x0d78, 0x0804, 0xc6cb, 0x6017, 0x1900, 0x0c88,
-	0x080c, 0x32ae, 0x1904, 0xca18, 0x6106, 0x080c, 0xd47a, 0x6007,
-	0x0006, 0x0804, 0xc7e2, 0x6007, 0x0007, 0x0804, 0xc7e2, 0x080c,
-	0xda81, 0x1904, 0xca18, 0x080c, 0x32ae, 0x1904, 0xca18, 0x00d6,
-	0x6610, 0x2658, 0xbe04, 0x9684, 0x00ff, 0x9082, 0x0006, 0x1220,
-	0x2001, 0x0001, 0x080c, 0x63dc, 0x96b4, 0xff00, 0x8637, 0x9686,
-	0x0006, 0x0188, 0x9686, 0x0004, 0x0170, 0xbe04, 0x96b4, 0x00ff,
-	0x9686, 0x0006, 0x0140, 0x9686, 0x0004, 0x0128, 0x9686, 0x0005,
-	0x0110, 0x00de, 0x0480, 0x00e6, 0x2071, 0x0260, 0x7034, 0x9084,
-	0x0003, 0x1140, 0x7034, 0x9082, 0x0014, 0x0220, 0x7030, 0x9084,
-	0x0003, 0x0130, 0x00ee, 0x6017, 0x0000, 0x602f, 0x0007, 0x00b0,
-	0x00ee, 0x080c, 0xd58c, 0x1190, 0x9686, 0x0006, 0x1140, 0x0026,
-	0x6210, 0x2258, 0xbaa0, 0x900e, 0x080c, 0x31d4, 0x002e, 0x080c,
-	0x653a, 0x6007, 0x000a, 0x00de, 0x0804, 0xc7e2, 0x6007, 0x000b,
-	0x00de, 0x0804, 0xc7e2, 0x080c, 0x318b, 0x080c, 0xc54e, 0x6007,
-	0x0001, 0x0804, 0xc7e2, 0x080c, 0xda81, 0x1904, 0xca18, 0x080c,
-	0x32ae, 0x1904, 0xca18, 0x2071, 0x0260, 0x7034, 0x90b4, 0x0003,
-	0x1948, 0x90b2, 0x0014, 0x0a30, 0x7030, 0x9084, 0x0003, 0x1910,
-	0x6610, 0x2658, 0xbe04, 0x9686, 0x0707, 0x09e8, 0x0026, 0x6210,
-	0x2258, 0xbaa0, 0x900e, 0x080c, 0x31d4, 0x002e, 0x6007, 0x000c,
-	0x2001, 0x0001, 0x080c, 0xdb9d, 0x0804, 0xc7e2, 0x080c, 0x6781,
-	0x1140, 0x2001, 0x1836, 0x2004, 0x9084, 0x0009, 0x9086, 0x0008,
-	0x1110, 0x0804, 0xc60a, 0x080c, 0x676a, 0x6610, 0x2658, 0xbe04,
-	0x9684, 0x00ff, 0x9082, 0x0006, 0x06c0, 0x1138, 0x0026, 0x2001,
-	0x0006, 0x080c, 0x641c, 0x002e, 0x0050, 0x96b4, 0xff00, 0x8637,
-	0x9686, 0x0004, 0x0120, 0x9686, 0x0006, 0x1904, 0xc6cb, 0x080c,
-	0xd599, 0x1120, 0x6007, 0x000e, 0x0804, 0xc7e2, 0x0046, 0x6410,
-	0x2458, 0xbca0, 0x0046, 0x080c, 0x318b, 0x080c, 0xc54e, 0x004e,
-	0x0016, 0x9006, 0x2009, 0x185c, 0x210c, 0x0048, 0x2009, 0x0029,
-	0x080c, 0xd885, 0x6010, 0x2058, 0xb800, 0xc0e5, 0xb802, 0x001e,
-	0x004e, 0x6007, 0x0001, 0x0804, 0xc7e2, 0x2001, 0x0001, 0x080c,
-	0x63dc, 0x0156, 0x0016, 0x0026, 0x0036, 0x20a9, 0x0004, 0x2019,
-	0x1805, 0x2011, 0x0270, 0x080c, 0xb0bc, 0x003e, 0x002e, 0x001e,
-	0x015e, 0x9005, 0x0168, 0x96b4, 0xff00, 0x8637, 0x9682, 0x0004,
-	0x0a04, 0xc6cb, 0x9682, 0x0007, 0x0a04, 0xc727, 0x0804, 0xc6cb,
-	0x6017, 0x1900, 0x6007, 0x0009, 0x0804, 0xc7e2, 0x080c, 0x6781,
-	0x1140, 0x2001, 0x1836, 0x2004, 0x9084, 0x0009, 0x9086, 0x0008,
-	0x1110, 0x0804, 0xc60a, 0x080c, 0x676a, 0x6610, 0x2658, 0xbe04,
-	0x9684, 0x00ff, 0x0006, 0x9086, 0x0001, 0x000e, 0x0170, 0x9082,
-	0x0006, 0x0690, 0x0150, 0x96b4, 0xff00, 0x8637, 0x9686, 0x0004,
-	0x0120, 0x9686, 0x0006, 0x1904, 0xc6cb, 0x080c, 0xd5c7, 0x1130,
-	0x080c, 0xd4c5, 0x1118, 0x6007, 0x0010, 0x04e0, 0x0046, 0x6410,
-	0x2458, 0xbca0, 0x0046, 0x080c, 0x318b, 0x080c, 0xc54e, 0x004e,
-	0x0016, 0x9006, 0x2009, 0x185c, 0x210c, 0x0048, 0x2009, 0x0029,
-	0x080c, 0xd885, 0x6010, 0x2058, 0xb800, 0xc0e5, 0xb802, 0x001e,
-	0x004e, 0x6007, 0x0001, 0x00f0, 0x080c, 0xd720, 0x0140, 0x96b4,
-	0xff00, 0x8637, 0x9686, 0x0006, 0x0980, 0x0804, 0xc6cb, 0x6017,
-	0x1900, 0x6007, 0x0009, 0x0070, 0x080c, 0x32ae, 0x1904, 0xca18,
-	0x080c, 0xda81, 0x1904, 0xca18, 0x080c, 0xcbb8, 0x1904, 0xc6cb,
-	0x6007, 0x0012, 0x6003, 0x0001, 0x080c, 0x86c1, 0x080c, 0x8c10,
-	0x0005, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c, 0x86c1, 0x080c,
-	0x8c10, 0x0cb0, 0x6007, 0x0005, 0x0c68, 0x080c, 0xda81, 0x1904,
-	0xca18, 0x080c, 0x32ae, 0x1904, 0xca18, 0x080c, 0xcbb8, 0x1904,
-	0xc6cb, 0x6007, 0x0020, 0x6003, 0x0001, 0x080c, 0x86c1, 0x080c,
-	0x8c10, 0x0005, 0x080c, 0x32ae, 0x1904, 0xca18, 0x6007, 0x0023,
-	0x6003, 0x0001, 0x080c, 0x86c1, 0x080c, 0x8c10, 0x0005, 0x080c,
-	0xda81, 0x1904, 0xca18, 0x080c, 0x32ae, 0x1904, 0xca18, 0x080c,
-	0xcbb8, 0x1904, 0xc6cb, 0x0016, 0x0026, 0x00e6, 0x2071, 0x0260,
-	0x2c08, 0x2011, 0x181f, 0x2214, 0x703c, 0x9206, 0x11e0, 0x2011,
-	0x181e, 0x2214, 0x7038, 0x9084, 0x00ff, 0x9206, 0x11a0, 0x7240,
-	0x080c, 0xbe25, 0x0570, 0x2260, 0x6008, 0x9086, 0xffff, 0x0120,
-	0x7244, 0x6008, 0x9206, 0x1528, 0x6020, 0x9086, 0x0007, 0x1508,
-	0x080c, 0xa0e3, 0x04a0, 0x7244, 0x9286, 0xffff, 0x0180, 0x2c08,
-	0x080c, 0xbe25, 0x01b0, 0x2260, 0x7240, 0x6008, 0x9206, 0x1188,
-	0x6010, 0x9190, 0x0004, 0x2214, 0x9206, 0x01b8, 0x0050, 0x7240,
-	0x2c08, 0x9006, 0x080c, 0xd857, 0x1180, 0x7244, 0x9286, 0xffff,
-	0x01b0, 0x2160, 0x6007, 0x0026, 0x6017, 0x1700, 0x7214, 0x9296,
-	0xffff, 0x1180, 0x6007, 0x0025, 0x0068, 0x6020, 0x9086, 0x0007,
-	0x1d80, 0x6004, 0x9086, 0x0024, 0x1110, 0x080c, 0xa0e3, 0x2160,
-	0x6007, 0x0025, 0x6003, 0x0001, 0x080c, 0x86c1, 0x080c, 0x8c10,
-	0x00ee, 0x002e, 0x001e, 0x0005, 0x2001, 0x0001, 0x080c, 0x63dc,
-	0x0156, 0x0016, 0x0026, 0x0036, 0x20a9, 0x0004, 0x2019, 0x1805,
-	0x2011, 0x0276, 0x080c, 0xb0bc, 0x003e, 0x002e, 0x001e, 0x015e,
-	0x0120, 0x6007, 0x0031, 0x0804, 0xc7e2, 0x080c, 0xad24, 0x080c,
-	0x7207, 0x1190, 0x0006, 0x0026, 0x0036, 0x080c, 0x7221, 0x1138,
-	0x080c, 0x7504, 0x080c, 0x5f2b, 0x080c, 0x7127, 0x0010, 0x080c,
-	0x71df, 0x003e, 0x002e, 0x000e, 0x0005, 0x080c, 0x32ae, 0x1904,
-	0xca18, 0x080c, 0xcbb8, 0x1904, 0xc6cb, 0x6106, 0x080c, 0xcbd4,
-	0x1120, 0x6007, 0x002b, 0x0804, 0xc7e2, 0x6007, 0x002c, 0x0804,
-	0xc7e2, 0x080c, 0xda81, 0x1904, 0xca18, 0x080c, 0x32ae, 0x1904,
-	0xca18, 0x080c, 0xcbb8, 0x1904, 0xc6cb, 0x6106, 0x080c, 0xcbd9,
-	0x1120, 0x6007, 0x002e, 0x0804, 0xc7e2, 0x6007, 0x002f, 0x0804,
-	0xc7e2, 0x080c, 0x32ae, 0x1904, 0xca18, 0x00e6, 0x00d6, 0x00c6,
-	0x6010, 0x2058, 0xb904, 0x9184, 0x00ff, 0x9086, 0x0006, 0x0158,
-	0x9184, 0xff00, 0x8007, 0x9086, 0x0006, 0x0128, 0x00ce, 0x00de,
-	0x00ee, 0x0804, 0xc7e9, 0x080c, 0x55df, 0xd0e4, 0x0904, 0xc963,
-	0x2071, 0x026c, 0x7010, 0x603a, 0x7014, 0x603e, 0x7108, 0x720c,
-	0x080c, 0x67bf, 0x0140, 0x6010, 0x2058, 0xb810, 0x9106, 0x1118,
-	0xb814, 0x9206, 0x0510, 0x080c, 0x67bb, 0x15b8, 0x2069, 0x1800,
-	0x687c, 0x9206, 0x1590, 0x6878, 0x9106, 0x1578, 0x7210, 0x080c,
-	0xbe25, 0x0590, 0x080c, 0xcaa3, 0x0578, 0x080c, 0xd901, 0x0560,
-	0x622e, 0x6007, 0x0036, 0x6003, 0x0001, 0x080c, 0x8679, 0x080c,
-	0x8c10, 0x00ce, 0x00de, 0x00ee, 0x0005, 0x7214, 0x9286, 0xffff,
-	0x0150, 0x080c, 0xbe25, 0x01c0, 0x9280, 0x0002, 0x2004, 0x7110,
-	0x9106, 0x1190, 0x08e0, 0x7210, 0x2c08, 0x9085, 0x0001, 0x080c,
-	0xd857, 0x2c10, 0x2160, 0x0140, 0x0890, 0x6007, 0x0037, 0x602f,
-	0x0009, 0x6017, 0x1500, 0x08b8, 0x6007, 0x0037, 0x602f, 0x0003,
-	0x6017, 0x1700, 0x0880, 0x6007, 0x0012, 0x0868, 0x080c, 0x32ae,
-	0x1904, 0xca18, 0x6010, 0x2058, 0xb804, 0x9084, 0xff00, 0x8007,
-	0x9086, 0x0006, 0x1904, 0xc7e9, 0x00e6, 0x00d6, 0x00c6, 0x080c,
-	0x55df, 0xd0e4, 0x0904, 0xc9db, 0x2069, 0x1800, 0x2071, 0x026c,
-	0x7008, 0x603a, 0x720c, 0x623e, 0x9286, 0xffff, 0x1150, 0x7208,
-	0x00c6, 0x2c08, 0x9085, 0x0001, 0x080c, 0xd857, 0x2c10, 0x00ce,
-	0x05e8, 0x080c, 0xbe25, 0x05d0, 0x7108, 0x9280, 0x0002, 0x2004,
-	0x9106, 0x15a0, 0x00c6, 0x0026, 0x2260, 0x080c, 0xba49, 0x002e,
-	0x00ce, 0x7118, 0x918c, 0xff00, 0x810f, 0x9186, 0x0001, 0x0178,
-	0x9186, 0x0005, 0x0118, 0x9186, 0x0007, 0x1198, 0x9280, 0x0005,
-	0x2004, 0x9005, 0x0170, 0x080c, 0xcaa3, 0x0904, 0xc95c, 0x0056,
-	0x7510, 0x7614, 0x080c, 0xd91a, 0x005e, 0x00ce, 0x00de, 0x00ee,
-	0x0005, 0x6007, 0x003b, 0x602f, 0x0009, 0x6017, 0x2a00, 0x6003,
-	0x0001, 0x080c, 0x8679, 0x080c, 0x8c10, 0x0c78, 0x6007, 0x003b,
-	0x602f, 0x0003, 0x6017, 0x0300, 0x6003, 0x0001, 0x080c, 0x8679,
-	0x080c, 0x8c10, 0x0c10, 0x6007, 0x003b, 0x602f, 0x000b, 0x6017,
-	0x0000, 0x0804, 0xc933, 0x00e6, 0x0026, 0x080c, 0x6781, 0x0550,
-	0x080c, 0x676a, 0x080c, 0xdaf3, 0x1518, 0x2071, 0x1800, 0x70d8,
-	0x9085, 0x0003, 0x70da, 0x00f6, 0x2079, 0x0100, 0x72ac, 0x9284,
-	0x00ff, 0x707a, 0x78e6, 0x9284, 0xff00, 0x727c, 0x9205, 0x707e,
-	0x78ea, 0x00fe, 0x70e3, 0x0000, 0x080c, 0x67bf, 0x0120, 0x2011,
-	0x19d8, 0x2013, 0x07d0, 0xd0ac, 0x1128, 0x080c, 0x2f6c, 0x0010,
-	0x080c, 0xdb25, 0x002e, 0x00ee, 0x080c, 0xa0e3, 0x0804, 0xc7e8,
-	0x080c, 0xa0e3, 0x0005, 0x2600, 0x0002, 0xca2f, 0xca2f, 0xca2f,
-	0xca2f, 0xca2f, 0xca31, 0xca2f, 0xca2f, 0xca2f, 0xca2f, 0xca4e,
-	0xca2f, 0xca2f, 0xca2f, 0xca60, 0xca6d, 0xca9e, 0xca2f, 0x080c,
-	0x0dfa, 0x080c, 0xda81, 0x1d20, 0x080c, 0x32ae, 0x1d08, 0x080c,
-	0xcbb8, 0x1148, 0x7038, 0x6016, 0x6007, 0x0045, 0x6003, 0x0001,
-	0x080c, 0x86c1, 0x0005, 0x080c, 0x318b, 0x080c, 0xc54e, 0x6007,
-	0x0001, 0x6003, 0x0001, 0x080c, 0x86c1, 0x0005, 0x080c, 0xda81,
-	0x1938, 0x080c, 0x32ae, 0x1920, 0x080c, 0xcbb8, 0x1d60, 0x703c,
-	0x6016, 0x6007, 0x004a, 0x6003, 0x0001, 0x080c, 0x86c1, 0x0005,
-	0x080c, 0xcac0, 0x0904, 0xca18, 0x6007, 0x004e, 0x6003, 0x0001,
-	0x080c, 0x86c1, 0x080c, 0x8c10, 0x0005, 0x6007, 0x004f, 0x6017,
-	0x0000, 0x7134, 0x918c, 0x00ff, 0x81ff, 0x0508, 0x9186, 0x0001,
-	0x1160, 0x7140, 0x2001, 0x1995, 0x2004, 0x9106, 0x11b0, 0x7144,
-	0x2001, 0x1996, 0x2004, 0x9106, 0x0190, 0x9186, 0x0002, 0x1168,
-	0x2011, 0x0276, 0x20a9, 0x0004, 0x6010, 0x0096, 0x2048, 0x2019,
-	0x000a, 0x080c, 0xb0d0, 0x009e, 0x0110, 0x6017, 0x0001, 0x6003,
-	0x0001, 0x080c, 0x86c1, 0x080c, 0x8c10, 0x0005, 0x6007, 0x0050,
-	0x703c, 0x6016, 0x0ca0, 0x0016, 0x00e6, 0x2071, 0x0260, 0x00b6,
-	0x00c6, 0x2260, 0x6010, 0x2058, 0xb8bc, 0xd084, 0x0150, 0x7128,
-	0x6044, 0x9106, 0x1120, 0x712c, 0x6048, 0x9106, 0x0110, 0x9006,
-	0x0010, 0x9085, 0x0001, 0x00ce, 0x00be, 0x00ee, 0x001e, 0x0005,
-	0x0016, 0x0096, 0x0086, 0x00e6, 0x01c6, 0x01d6, 0x0126, 0x2091,
-	0x8000, 0x2071, 0x1800, 0x708c, 0x908a, 0x00f9, 0x16e8, 0x20e1,
-	0x0000, 0x2001, 0x1978, 0x2003, 0x0000, 0x080c, 0x104a, 0x05a0,
-	0x2900, 0x6016, 0x708c, 0x8004, 0xa816, 0x908a, 0x001e, 0x02d0,
-	0xa833, 0x001e, 0x20a9, 0x001e, 0xa860, 0x20e8, 0xa85c, 0x9080,
-	0x001b, 0x20a0, 0x2001, 0x1978, 0x0016, 0x200c, 0x0471, 0x001e,
-	0x2940, 0x080c, 0x104a, 0x01c0, 0x2900, 0xa006, 0x2100, 0x81ff,
-	0x0180, 0x0c18, 0xa832, 0x20a8, 0xa860, 0x20e8, 0xa85c, 0x9080,
-	0x001b, 0x20a0, 0x2001, 0x1978, 0x0016, 0x200c, 0x00b1, 0x001e,
-	0x0000, 0x9085, 0x0001, 0x0048, 0x2071, 0x1800, 0x708f, 0x0000,
-	0x6014, 0x2048, 0x080c, 0x0fe3, 0x9006, 0x012e, 0x01de, 0x01ce,
-	0x00ee, 0x008e, 0x009e, 0x001e, 0x0005, 0x0006, 0x0016, 0x0026,
-	0x0036, 0x00c6, 0x918c, 0xffff, 0x11a8, 0x080c, 0x22e3, 0x2099,
-	0x026c, 0x2001, 0x0014, 0x3518, 0x9312, 0x1218, 0x23a8, 0x4003,
-	0x00f8, 0x20a8, 0x4003, 0x22a8, 0x8108, 0x080c, 0x22e3, 0x2099,
-	0x0260, 0x0ca8, 0x080c, 0x22e3, 0x2061, 0x1978, 0x6004, 0x2098,
-	0x6008, 0x3518, 0x9312, 0x1218, 0x23a8, 0x4003, 0x0048, 0x20a8,
-	0x4003, 0x22a8, 0x8108, 0x080c, 0x22e3, 0x2099, 0x0260, 0x0ca8,
-	0x2061, 0x1978, 0x2019, 0x0280, 0x3300, 0x931e, 0x0110, 0x6006,
-	0x0020, 0x2001, 0x0260, 0x6006, 0x8108, 0x2162, 0x9292, 0x0021,
-	0x9296, 0xffff, 0x620a, 0x00ce, 0x003e, 0x002e, 0x001e, 0x000e,
-	0x0005, 0x0006, 0x0016, 0x0026, 0x0036, 0x00c6, 0x81ff, 0x11b8,
-	0x080c, 0x22fb, 0x20a1, 0x024c, 0x2001, 0x0014, 0x3518, 0x9312,
-	0x1218, 0x23a8, 0x4003, 0x0418, 0x20a8, 0x4003, 0x82ff, 0x01f8,
-	0x22a8, 0x8108, 0x080c, 0x22fb, 0x20a1, 0x0240, 0x0c98, 0x080c,
-	0x22fb, 0x2061, 0x197b, 0x6004, 0x20a0, 0x6008, 0x3518, 0x9312,
-	0x1218, 0x23a8, 0x4003, 0x0058, 0x20a8, 0x4003, 0x82ff, 0x0138,
-	0x22a8, 0x8108, 0x080c, 0x22fb, 0x20a1, 0x0240, 0x0c98, 0x2061,
-	0x197b, 0x2019, 0x0260, 0x3400, 0x931e, 0x0110, 0x6006, 0x0020,
-	0x2001, 0x0240, 0x6006, 0x8108, 0x2162, 0x9292, 0x0021, 0x9296,
-	0xffff, 0x620a, 0x00ce, 0x003e, 0x002e, 0x001e, 0x000e, 0x0005,
-	0x00b6, 0x0066, 0x6610, 0x2658, 0xbe04, 0x96b4, 0xff00, 0x8637,
-	0x9686, 0x0006, 0x0170, 0x9686, 0x0004, 0x0158, 0xbe04, 0x96b4,
-	0x00ff, 0x9686, 0x0006, 0x0128, 0x9686, 0x0004, 0x0110, 0x9085,
-	0x0001, 0x006e, 0x00be, 0x0005, 0x00d6, 0x080c, 0xcc50, 0x00de,
-	0x0005, 0x00d6, 0x080c, 0xcc5d, 0x1520, 0x680c, 0x908c, 0xff00,
-	0x6820, 0x9084, 0x00ff, 0x9115, 0x6216, 0x6824, 0x602e, 0xd1e4,
-	0x0130, 0x9006, 0x080c, 0xdb9d, 0x2009, 0x0001, 0x0078, 0xd1ec,
-	0x0180, 0x6920, 0x918c, 0x00ff, 0x6824, 0x080c, 0x276e, 0x1148,
-	0x2001, 0x0001, 0x080c, 0xdb9d, 0x2110, 0x900e, 0x080c, 0x31d4,
-	0x0018, 0x9085, 0x0001, 0x0008, 0x9006, 0x00de, 0x0005, 0x00b6,
-	0x00c6, 0x080c, 0xa130, 0x05a8, 0x0016, 0x0026, 0x00c6, 0x2011,
-	0x0263, 0x2204, 0x8211, 0x220c, 0x080c, 0x276e, 0x1578, 0x080c,
-	0x643f, 0x1560, 0xbe12, 0xbd16, 0x00ce, 0x002e, 0x001e, 0x2b00,
-	0x6012, 0x080c, 0xda81, 0x11d8, 0x080c, 0x32ae, 0x11c0, 0x080c,
-	0xcbb8, 0x0510, 0x2001, 0x0007, 0x080c, 0x63f0, 0x2001, 0x0007,
-	0x080c, 0x641c, 0x6017, 0x0000, 0x6023, 0x0001, 0x6007, 0x0001,
-	0x6003, 0x0001, 0x080c, 0x86c1, 0x080c, 0x8c10, 0x0010, 0x080c,
-	0xa0e3, 0x9085, 0x0001, 0x00ce, 0x00be, 0x0005, 0x080c, 0xa0e3,
-	0x00ce, 0x002e, 0x001e, 0x0ca8, 0x080c, 0xa0e3, 0x9006, 0x0c98,
-	0x2069, 0x026d, 0x6800, 0x9082, 0x0010, 0x1228, 0x6017, 0x0000,
-	0x9085, 0x0001, 0x0008, 0x9006, 0x0005, 0x6017, 0x0000, 0x2069,
-	0x026c, 0x6808, 0x9084, 0xff00, 0x9086, 0x0800, 0x1190, 0x6904,
-	0x9186, 0x0018, 0x0118, 0x9186, 0x0014, 0x1158, 0x810f, 0x6800,
-	0x9084, 0x00ff, 0x910d, 0x615a, 0x908e, 0x0014, 0x0110, 0x908e,
-	0x0010, 0x0005, 0x6004, 0x90b2, 0x0053, 0x1a0c, 0x0dfa, 0x91b6,
-	0x0013, 0x1130, 0x2008, 0x91b2, 0x0040, 0x1a04, 0xcda5, 0x0092,
-	0x91b6, 0x0027, 0x0120, 0x91b6, 0x0014, 0x190c, 0x0dfa, 0x2001,
-	0x0007, 0x080c, 0x641c, 0x080c, 0x8b04, 0x080c, 0xa113, 0x080c,
-	0x8c10, 0x0005, 0xccda, 0xccdc, 0xccda, 0xccda, 0xccda, 0xccdc,
-	0xcceb, 0xcd9e, 0xcd3d, 0xcd9e, 0xcd4f, 0xcd9e, 0xcceb, 0xcd9e,
-	0xcd96, 0xcd9e, 0xcd96, 0xcd9e, 0xcd9e, 0xccda, 0xccda, 0xccda,
-	0xccda, 0xccda, 0xccda, 0xccda, 0xccda, 0xccda, 0xccda, 0xccda,
-	0xccdc, 0xccda, 0xcd9e, 0xccda, 0xccda, 0xcd9e, 0xccda, 0xcd9b,
-	0xcd9e, 0xccda, 0xccda, 0xccda, 0xccda, 0xcd9e, 0xcd9e, 0xccda,
-	0xcd9e, 0xcd9e, 0xccda, 0xcce6, 0xccda, 0xccda, 0xccda, 0xccda,
-	0xcd9a, 0xcd9e, 0xccda, 0xccda, 0xcd9e, 0xcd9e, 0xccda, 0xccda,
-	0xccda, 0xccda, 0x080c, 0x0dfa, 0x080c, 0x8b04, 0x080c, 0xc551,
-	0x6003, 0x0002, 0x080c, 0x8c10, 0x0804, 0xcda4, 0x9006, 0x080c,
-	0x63dc, 0x0804, 0xcd9e, 0x080c, 0x67bb, 0x1904, 0xcd9e, 0x9006,
-	0x080c, 0x63dc, 0x6010, 0x2058, 0xb810, 0x9086, 0x00ff, 0x1140,
-	0x00f6, 0x2079, 0x1800, 0x78a4, 0x8000, 0x78a6, 0x00fe, 0x0428,
-	0x6010, 0x2058, 0xb8b0, 0x9005, 0x1178, 0x080c, 0xc539, 0x1904,
-	0xcd9e, 0x0036, 0x0046, 0xbba0, 0x2021, 0x0007, 0x080c, 0x4cbc,
-	0x004e, 0x003e, 0x0804, 0xcd9e, 0x080c, 0x32df, 0x1904, 0xcd9e,
-	0x2001, 0x1800, 0x2004, 0x9086, 0x0002, 0x1138, 0x00f6, 0x2079,
-	0x1800, 0x78a4, 0x8000, 0x78a6, 0x00fe, 0x2001, 0x0002, 0x080c,
-	0x63f0, 0x080c, 0x8b04, 0x6023, 0x0001, 0x6003, 0x0001, 0x6007,
-	0x0002, 0x080c, 0x86c1, 0x080c, 0x8c10, 0x6110, 0x2158, 0x2009,
-	0x0001, 0x080c, 0x82e8, 0x0804, 0xcda4, 0x6610, 0x2658, 0xbe04,
-	0x96b4, 0xff00, 0x8637, 0x9686, 0x0006, 0x0904, 0xcd9e, 0x9686,
-	0x0004, 0x0904, 0xcd9e, 0x2001, 0x0004, 0x0804, 0xcd9c, 0x2001,
+	0xa89e, 0xa868, 0xc0f4, 0xa86a, 0x080c, 0x6a16, 0x6017, 0x0000,
+	0x009e, 0x003e, 0x00de, 0x00be, 0x0005, 0x0026, 0x0036, 0x0046,
+	0x00b6, 0x0096, 0x00f6, 0x6214, 0x2248, 0x6210, 0x2258, 0x2079,
+	0x0260, 0x9096, 0x0000, 0x11a0, 0xb814, 0x9084, 0x00ff, 0x900e,
+	0x080c, 0x266e, 0x2118, 0x831f, 0x939c, 0xff00, 0x7838, 0x9084,
+	0x00ff, 0x931d, 0x7c3c, 0x2011, 0x8018, 0x080c, 0x4a18, 0x00a8,
+	0x9096, 0x0001, 0x1148, 0x89ff, 0x0180, 0xa89b, 0x000d, 0x7838,
+	0xa8a6, 0x783c, 0xa8aa, 0x0048, 0x9096, 0x0002, 0x1130, 0xa89b,
+	0x000d, 0x7838, 0xa8a6, 0x783c, 0xa8aa, 0x00fe, 0x009e, 0x00be,
+	0x004e, 0x003e, 0x002e, 0x0005, 0x00c6, 0x0026, 0x0016, 0x9186,
+	0x0035, 0x0110, 0x6a38, 0x0008, 0x6a2c, 0x080c, 0xbd29, 0x01f0,
+	0x2260, 0x6120, 0x9186, 0x0003, 0x0118, 0x9186, 0x0006, 0x1190,
+	0x6838, 0x9206, 0x0140, 0x683c, 0x9206, 0x1160, 0x6108, 0x6838,
+	0x9106, 0x1140, 0x0020, 0x6008, 0x693c, 0x9106, 0x1118, 0x6010,
+	0x6910, 0x9106, 0x001e, 0x002e, 0x00ce, 0x0005, 0x9085, 0x0001,
+	0x0cc8, 0xa974, 0xd1cc, 0x0188, 0x918c, 0x00ff, 0x918e, 0x0002,
+	0x1160, 0xa9a8, 0x918c, 0x0f00, 0x810f, 0x918e, 0x0001, 0x1128,
+	0xa834, 0xa938, 0x9115, 0x190c, 0xb40c, 0x0005, 0x0036, 0x2019,
+	0x0001, 0x0010, 0x0036, 0x901e, 0x0499, 0x01e0, 0x080c, 0xbd3b,
+	0x01c8, 0x080c, 0xbf26, 0x6037, 0x4000, 0x6014, 0x6017, 0x0000,
+	0x0096, 0x2048, 0xa87c, 0x080c, 0xbf43, 0x1118, 0x080c, 0xa995,
+	0x0040, 0xa867, 0x0103, 0xa877, 0x0000, 0x83ff, 0x1129, 0x080c,
+	0x6a23, 0x009e, 0x003e, 0x0005, 0xa880, 0xd0b4, 0x0128, 0xa87b,
+	0x0006, 0xc0ec, 0xa882, 0x0048, 0xd0bc, 0x0118, 0xa87b, 0x0002,
+	0x0020, 0xa87b, 0x0005, 0x080c, 0xc037, 0xa877, 0x0000, 0x0005,
+	0x2001, 0x1810, 0x2004, 0xd0ec, 0x0005, 0x0006, 0x2001, 0x1810,
+	0x2004, 0xd0f4, 0x000e, 0x0005, 0x0006, 0x2001, 0x1810, 0x2004,
+	0xd0e4, 0x000e, 0x0005, 0x0036, 0x0046, 0x6010, 0x00b6, 0x2058,
+	0xbba0, 0x00be, 0x2021, 0x0007, 0x080c, 0x4bb5, 0x004e, 0x003e,
+	0x0005, 0x0c51, 0x1d81, 0x0005, 0x2001, 0x1960, 0x2004, 0x601a,
+	0x0005, 0x2001, 0x1962, 0x2004, 0x6042, 0x0005, 0x080c, 0x9fd5,
+	0x0804, 0x8b90, 0x2001, 0x0109, 0x2004, 0xd084, 0x01e0, 0x0126,
+	0x2091, 0x2800, 0x0006, 0x0016, 0x0026, 0x0036, 0x00f6, 0x00e6,
+	0x00c6, 0x2079, 0x19c2, 0x2071, 0x1800, 0x2061, 0x0100, 0x080c,
+	0x84e3, 0x00ce, 0x00ee, 0x00fe, 0x003e, 0x002e, 0x001e, 0x000e,
+	0x012e, 0x9085, 0x0001, 0x0005, 0x00b6, 0x0066, 0x6000, 0x90b2,
+	0x0016, 0x1a0c, 0x0e02, 0x001b, 0x006e, 0x00be, 0x0005, 0xc4a7,
+	0xcbbf, 0xcd3d, 0xc4a7, 0xc4a7, 0xc4a7, 0xc4a7, 0xc4a7, 0xc4de,
+	0xcdc1, 0xc4a7, 0xc4a7, 0xc4a7, 0xc4a7, 0xc4a7, 0xc4a7, 0x080c,
+	0x0e02, 0x0066, 0x6000, 0x90b2, 0x0016, 0x1a0c, 0x0e02, 0x0013,
+	0x006e, 0x0005, 0xc4c2, 0xd310, 0xc4c2, 0xc4c2, 0xc4c2, 0xc4c2,
+	0xc4c2, 0xc4c2, 0xd2bd, 0xd364, 0xc4c2, 0xd960, 0xd996, 0xd960,
+	0xd996, 0xc4c2, 0x080c, 0x0e02, 0x6000, 0x9082, 0x0016, 0x1a0c,
+	0x0e02, 0x6000, 0x000a, 0x0005, 0xc4dc, 0xcf9f, 0xd06e, 0xd091,
+	0xd151, 0xc4dc, 0xd230, 0xd1d9, 0xcdcd, 0xd293, 0xd2a8, 0xc4dc,
+	0xc4dc, 0xc4dc, 0xc4dc, 0xc4dc, 0x080c, 0x0e02, 0x91b2, 0x0053,
+	0x1a0c, 0x0e02, 0x2100, 0x91b2, 0x0040, 0x1a04, 0xc95c, 0x0002,
+	0xc528, 0xc72a, 0xc528, 0xc528, 0xc528, 0xc733, 0xc528, 0xc528,
+	0xc528, 0xc528, 0xc528, 0xc528, 0xc528, 0xc528, 0xc528, 0xc528,
+	0xc528, 0xc528, 0xc528, 0xc528, 0xc528, 0xc528, 0xc528, 0xc52a,
+	0xc58d, 0xc59c, 0xc600, 0xc62b, 0xc6a3, 0xc715, 0xc528, 0xc528,
+	0xc736, 0xc528, 0xc528, 0xc74b, 0xc758, 0xc528, 0xc528, 0xc528,
+	0xc528, 0xc528, 0xc7fe, 0xc528, 0xc528, 0xc812, 0xc528, 0xc528,
+	0xc7cd, 0xc528, 0xc528, 0xc528, 0xc82a, 0xc528, 0xc528, 0xc528,
+	0xc8a7, 0xc528, 0xc528, 0xc528, 0xc528, 0xc528, 0xc528, 0xc924,
+	0x080c, 0x0e02, 0x080c, 0x6688, 0x1150, 0x2001, 0x1836, 0x2004,
+	0xd0cc, 0x1128, 0x9084, 0x0009, 0x9086, 0x0008, 0x1140, 0x6007,
+	0x0009, 0x602f, 0x0009, 0x6017, 0x0000, 0x0804, 0xc723, 0x080c,
+	0x6671, 0x00e6, 0x00c6, 0x0036, 0x0026, 0x0016, 0x6210, 0x2258,
+	0xbaa0, 0x0026, 0x2019, 0x0029, 0x080c, 0x8783, 0x0076, 0x903e,
+	0x080c, 0x8671, 0x2c08, 0x080c, 0xd53b, 0x007e, 0x001e, 0x001e,
+	0x002e, 0x003e, 0x00ce, 0x00ee, 0x6610, 0x2658, 0x080c, 0x63b3,
+	0xbe04, 0x9684, 0x00ff, 0x9082, 0x0006, 0x1268, 0x0016, 0x0026,
+	0x6210, 0x00b6, 0x2258, 0xbaa0, 0x00be, 0x2c08, 0x080c, 0xdb10,
+	0x002e, 0x001e, 0x1178, 0x080c, 0xd46e, 0x1904, 0xc5f8, 0x080c,
+	0xd40a, 0x1120, 0x6007, 0x0008, 0x0804, 0xc723, 0x6007, 0x0009,
+	0x0804, 0xc723, 0x080c, 0xd666, 0x0128, 0x080c, 0xd46e, 0x0d78,
+	0x0804, 0xc5f8, 0x6017, 0x1900, 0x0c88, 0x080c, 0x31ce, 0x1904,
+	0xc959, 0x6106, 0x080c, 0xd3bf, 0x6007, 0x0006, 0x0804, 0xc723,
+	0x6007, 0x0007, 0x0804, 0xc723, 0x080c, 0xd9d2, 0x1904, 0xc959,
+	0x080c, 0x31ce, 0x1904, 0xc959, 0x00d6, 0x6610, 0x2658, 0xbe04,
+	0x9684, 0x00ff, 0x9082, 0x0006, 0x1220, 0x2001, 0x0001, 0x080c,
+	0x62e1, 0x96b4, 0xff00, 0x8637, 0x9686, 0x0006, 0x0188, 0x9686,
+	0x0004, 0x0170, 0xbe04, 0x96b4, 0x00ff, 0x9686, 0x0006, 0x0140,
+	0x9686, 0x0004, 0x0128, 0x9686, 0x0005, 0x0110, 0x00de, 0x0480,
+	0x00e6, 0x2071, 0x0260, 0x7034, 0x9084, 0x0003, 0x1140, 0x7034,
+	0x9082, 0x0014, 0x0220, 0x7030, 0x9084, 0x0003, 0x0130, 0x00ee,
+	0x6017, 0x0000, 0x602f, 0x0007, 0x00b0, 0x00ee, 0x080c, 0xd4d1,
+	0x1190, 0x9686, 0x0006, 0x1140, 0x0026, 0x6210, 0x2258, 0xbaa0,
+	0x900e, 0x080c, 0x30f4, 0x002e, 0x080c, 0x643f, 0x6007, 0x000a,
+	0x00de, 0x0804, 0xc723, 0x6007, 0x000b, 0x00de, 0x0804, 0xc723,
+	0x080c, 0x30ab, 0x080c, 0xc459, 0x6007, 0x0001, 0x0804, 0xc723,
+	0x080c, 0xd9d2, 0x1904, 0xc959, 0x080c, 0x31ce, 0x1904, 0xc959,
+	0x2071, 0x0260, 0x7034, 0x90b4, 0x0003, 0x1948, 0x90b2, 0x0014,
+	0x0a30, 0x7030, 0x9084, 0x0003, 0x1910, 0x6610, 0x2658, 0xbe04,
+	0x9686, 0x0707, 0x09e8, 0x0026, 0x6210, 0x2258, 0xbaa0, 0x900e,
+	0x080c, 0x30f4, 0x002e, 0x6007, 0x000c, 0x2001, 0x0001, 0x080c,
+	0xdaef, 0x0804, 0xc723, 0x080c, 0x6688, 0x1140, 0x2001, 0x1836,
+	0x2004, 0x9084, 0x0009, 0x9086, 0x0008, 0x1110, 0x0804, 0xc537,
+	0x080c, 0x6671, 0x6610, 0x2658, 0xbe04, 0x9684, 0x00ff, 0x9082,
+	0x0006, 0x06c0, 0x1138, 0x0026, 0x2001, 0x0006, 0x080c, 0x6321,
+	0x002e, 0x0050, 0x96b4, 0xff00, 0x8637, 0x9686, 0x0004, 0x0120,
+	0x9686, 0x0006, 0x1904, 0xc5f8, 0x080c, 0xd4de, 0x1120, 0x6007,
+	0x000e, 0x0804, 0xc723, 0x0046, 0x6410, 0x2458, 0xbca0, 0x0046,
+	0x080c, 0x30ab, 0x080c, 0xc459, 0x004e, 0x0016, 0x9006, 0x2009,
+	0x185c, 0x210c, 0x0048, 0x2009, 0x0029, 0x080c, 0xd7d6, 0x6010,
+	0x2058, 0xb800, 0xc0e5, 0xb802, 0x001e, 0x004e, 0x6007, 0x0001,
+	0x0804, 0xc723, 0x2001, 0x0001, 0x080c, 0x62e1, 0x0156, 0x0016,
+	0x0026, 0x0036, 0x20a9, 0x0004, 0x2019, 0x1805, 0x2011, 0x0270,
+	0x080c, 0xaff7, 0x003e, 0x002e, 0x001e, 0x015e, 0x9005, 0x0168,
+	0x96b4, 0xff00, 0x8637, 0x9682, 0x0004, 0x0a04, 0xc5f8, 0x9682,
+	0x0007, 0x0a04, 0xc654, 0x0804, 0xc5f8, 0x6017, 0x1900, 0x6007,
+	0x0009, 0x0804, 0xc723, 0x080c, 0x6688, 0x1140, 0x2001, 0x1836,
+	0x2004, 0x9084, 0x0009, 0x9086, 0x0008, 0x1110, 0x0804, 0xc537,
+	0x080c, 0x6671, 0x6610, 0x2658, 0xbe04, 0x9684, 0x00ff, 0x0006,
+	0x0016, 0x908e, 0x0001, 0x0118, 0x908e, 0x0000, 0x1118, 0x001e,
+	0x000e, 0x0080, 0x001e, 0x000e, 0x9082, 0x0006, 0x0698, 0x0150,
+	0x96b4, 0xff00, 0x8637, 0x9686, 0x0004, 0x0120, 0x9686, 0x0006,
+	0x1904, 0xc5f8, 0x080c, 0xd50c, 0x1138, 0x080c, 0xd40a, 0x1120,
+	0x6007, 0x0010, 0x0804, 0xc723, 0x0046, 0x6410, 0x2458, 0xbca0,
+	0x0046, 0x080c, 0x30ab, 0x080c, 0xc459, 0x004e, 0x0016, 0x9006,
+	0x2009, 0x185c, 0x210c, 0x0048, 0x2009, 0x0029, 0x080c, 0xd7d6,
+	0x6010, 0x2058, 0xb800, 0xc0e5, 0xb802, 0x001e, 0x004e, 0x6007,
+	0x0001, 0x0448, 0x080c, 0xd666, 0x0198, 0x0016, 0x968c, 0x00ff,
+	0x9186, 0x0002, 0x0160, 0x9186, 0x0003, 0x0148, 0x001e, 0x96b4,
+	0xff00, 0x8637, 0x9686, 0x0006, 0x0928, 0x0804, 0xc5f8, 0x001e,
+	0x6017, 0x1900, 0x6007, 0x0009, 0x0070, 0x080c, 0x31ce, 0x1904,
+	0xc959, 0x080c, 0xd9d2, 0x1904, 0xc959, 0x080c, 0xcafd, 0x1904,
+	0xc5f8, 0x6007, 0x0012, 0x6003, 0x0001, 0x080c, 0x8641, 0x080c,
+	0x8b90, 0x0005, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c, 0x8641,
+	0x080c, 0x8b90, 0x0cb0, 0x6007, 0x0005, 0x0c68, 0x080c, 0xd9d2,
+	0x1904, 0xc959, 0x080c, 0x31ce, 0x1904, 0xc959, 0x080c, 0xcafd,
+	0x1904, 0xc5f8, 0x6007, 0x0020, 0x6003, 0x0001, 0x080c, 0x8641,
+	0x080c, 0x8b90, 0x0005, 0x080c, 0x31ce, 0x1904, 0xc959, 0x6007,
+	0x0023, 0x6003, 0x0001, 0x080c, 0x8641, 0x080c, 0x8b90, 0x0005,
+	0x080c, 0xd9d2, 0x1904, 0xc959, 0x080c, 0x31ce, 0x1904, 0xc959,
+	0x080c, 0xcafd, 0x1904, 0xc5f8, 0x0016, 0x0026, 0x00e6, 0x2071,
+	0x0260, 0x2c08, 0x2011, 0x181f, 0x2214, 0x703c, 0x9206, 0x11e0,
+	0x2011, 0x181e, 0x2214, 0x7038, 0x9084, 0x00ff, 0x9206, 0x11a0,
+	0x7240, 0x080c, 0xbd29, 0x0570, 0x2260, 0x6008, 0x9086, 0xffff,
+	0x0120, 0x7244, 0x6008, 0x9206, 0x1528, 0x6020, 0x9086, 0x0007,
+	0x1508, 0x080c, 0x9fd5, 0x04a0, 0x7244, 0x9286, 0xffff, 0x0180,
+	0x2c08, 0x080c, 0xbd29, 0x01b0, 0x2260, 0x7240, 0x6008, 0x9206,
+	0x1188, 0x6010, 0x9190, 0x0004, 0x2214, 0x9206, 0x01b8, 0x0050,
+	0x7240, 0x2c08, 0x9006, 0x080c, 0xd7a8, 0x1180, 0x7244, 0x9286,
+	0xffff, 0x01b0, 0x2160, 0x6007, 0x0026, 0x6017, 0x1700, 0x7214,
+	0x9296, 0xffff, 0x1180, 0x6007, 0x0025, 0x0068, 0x6020, 0x9086,
+	0x0007, 0x1d80, 0x6004, 0x9086, 0x0024, 0x1110, 0x080c, 0x9fd5,
+	0x2160, 0x6007, 0x0025, 0x6003, 0x0001, 0x080c, 0x8641, 0x080c,
+	0x8b90, 0x00ee, 0x002e, 0x001e, 0x0005, 0x2001, 0x0001, 0x080c,
+	0x62e1, 0x0156, 0x0016, 0x0026, 0x0036, 0x20a9, 0x0004, 0x2019,
+	0x1805, 0x2011, 0x0276, 0x080c, 0xaff7, 0x003e, 0x002e, 0x001e,
+	0x015e, 0x0120, 0x6007, 0x0031, 0x0804, 0xc723, 0x080c, 0xac52,
+	0x080c, 0x717f, 0x1190, 0x0006, 0x0026, 0x0036, 0x080c, 0x7199,
+	0x1138, 0x080c, 0x747b, 0x080c, 0x5e30, 0x080c, 0x709f, 0x0010,
+	0x080c, 0x7157, 0x003e, 0x002e, 0x000e, 0x0005, 0x080c, 0x31ce,
+	0x1904, 0xc959, 0x080c, 0xcafd, 0x1904, 0xc5f8, 0x6106, 0x080c,
+	0xcb19, 0x1120, 0x6007, 0x002b, 0x0804, 0xc723, 0x6007, 0x002c,
+	0x0804, 0xc723, 0x080c, 0xd9d2, 0x1904, 0xc959, 0x080c, 0x31ce,
+	0x1904, 0xc959, 0x080c, 0xcafd, 0x1904, 0xc5f8, 0x6106, 0x080c,
+	0xcb1e, 0x1120, 0x6007, 0x002e, 0x0804, 0xc723, 0x6007, 0x002f,
+	0x0804, 0xc723, 0x080c, 0x31ce, 0x1904, 0xc959, 0x00e6, 0x00d6,
+	0x00c6, 0x6010, 0x2058, 0xb904, 0x9184, 0x00ff, 0x9086, 0x0006,
+	0x0158, 0x9184, 0xff00, 0x8007, 0x9086, 0x0006, 0x0128, 0x00ce,
+	0x00de, 0x00ee, 0x0804, 0xc72a, 0x080c, 0x54e0, 0xd0e4, 0x0904,
+	0xc8a4, 0x2071, 0x026c, 0x7010, 0x603a, 0x7014, 0x603e, 0x7108,
+	0x720c, 0x080c, 0x66c6, 0x0140, 0x6010, 0x2058, 0xb810, 0x9106,
+	0x1118, 0xb814, 0x9206, 0x0510, 0x080c, 0x66c2, 0x15b8, 0x2069,
+	0x1800, 0x687c, 0x9206, 0x1590, 0x6878, 0x9106, 0x1578, 0x7210,
+	0x080c, 0xbd29, 0x0590, 0x080c, 0xc9ea, 0x0578, 0x080c, 0xd852,
+	0x0560, 0x622e, 0x6007, 0x0036, 0x6003, 0x0001, 0x080c, 0x85f9,
+	0x080c, 0x8b90, 0x00ce, 0x00de, 0x00ee, 0x0005, 0x7214, 0x9286,
+	0xffff, 0x0150, 0x080c, 0xbd29, 0x01c0, 0x9280, 0x0002, 0x2004,
+	0x7110, 0x9106, 0x1190, 0x08e0, 0x7210, 0x2c08, 0x9085, 0x0001,
+	0x080c, 0xd7a8, 0x2c10, 0x2160, 0x0140, 0x0890, 0x6007, 0x0037,
+	0x602f, 0x0009, 0x6017, 0x1500, 0x08b8, 0x6007, 0x0037, 0x602f,
+	0x0003, 0x6017, 0x1700, 0x0880, 0x6007, 0x0012, 0x0868, 0x080c,
+	0x31ce, 0x1904, 0xc959, 0x6010, 0x2058, 0xb804, 0x9084, 0xff00,
+	0x8007, 0x9086, 0x0006, 0x1904, 0xc72a, 0x00e6, 0x00d6, 0x00c6,
+	0x080c, 0x54e0, 0xd0e4, 0x0904, 0xc91c, 0x2069, 0x1800, 0x2071,
+	0x026c, 0x7008, 0x603a, 0x720c, 0x623e, 0x9286, 0xffff, 0x1150,
+	0x7208, 0x00c6, 0x2c08, 0x9085, 0x0001, 0x080c, 0xd7a8, 0x2c10,
+	0x00ce, 0x05e8, 0x080c, 0xbd29, 0x05d0, 0x7108, 0x9280, 0x0002,
+	0x2004, 0x9106, 0x15a0, 0x00c6, 0x0026, 0x2260, 0x080c, 0xb967,
+	0x002e, 0x00ce, 0x7118, 0x918c, 0xff00, 0x810f, 0x9186, 0x0001,
+	0x0178, 0x9186, 0x0005, 0x0118, 0x9186, 0x0007, 0x1198, 0x9280,
+	0x0005, 0x2004, 0x9005, 0x0170, 0x080c, 0xc9ea, 0x0904, 0xc89d,
+	0x0056, 0x7510, 0x7614, 0x080c, 0xd86b, 0x005e, 0x00ce, 0x00de,
+	0x00ee, 0x0005, 0x6007, 0x003b, 0x602f, 0x0009, 0x6017, 0x2a00,
+	0x6003, 0x0001, 0x080c, 0x85f9, 0x080c, 0x8b90, 0x0c78, 0x6007,
+	0x003b, 0x602f, 0x0003, 0x6017, 0x0300, 0x6003, 0x0001, 0x080c,
+	0x85f9, 0x080c, 0x8b90, 0x0c10, 0x6007, 0x003b, 0x602f, 0x000b,
+	0x6017, 0x0000, 0x0804, 0xc874, 0x00e6, 0x0026, 0x080c, 0x6688,
+	0x0550, 0x080c, 0x6671, 0x080c, 0xda43, 0x1518, 0x2071, 0x1800,
+	0x70d8, 0x9085, 0x0003, 0x70da, 0x00f6, 0x2079, 0x0100, 0x72ac,
+	0x9284, 0x00ff, 0x707a, 0x78e6, 0x9284, 0xff00, 0x727c, 0x9205,
+	0x707e, 0x78ea, 0x00fe, 0x70e3, 0x0000, 0x080c, 0x66c6, 0x0120,
+	0x2011, 0x19db, 0x2013, 0x07d0, 0xd0ac, 0x1128, 0x080c, 0x2e8c,
+	0x0010, 0x080c, 0xda77, 0x002e, 0x00ee, 0x080c, 0x9fd5, 0x0804,
+	0xc729, 0x080c, 0x9fd5, 0x0005, 0x2600, 0x0002, 0xc970, 0xc970,
+	0xc970, 0xc970, 0xc970, 0xc972, 0xc970, 0xc970, 0xc970, 0xc970,
+	0xc98c, 0xc970, 0xc970, 0xc970, 0xc99e, 0xc9b4, 0xc9e5, 0xc970,
+	0x080c, 0x0e02, 0x080c, 0xd9d2, 0x1d20, 0x080c, 0x31ce, 0x1d08,
+	0x7038, 0x6016, 0x6007, 0x0045, 0x6003, 0x0001, 0x080c, 0x8641,
+	0x0005, 0x080c, 0x30ab, 0x080c, 0xc459, 0x6007, 0x0001, 0x6003,
+	0x0001, 0x080c, 0x8641, 0x0005, 0x080c, 0xd9d2, 0x1950, 0x080c,
+	0x31ce, 0x1938, 0x080c, 0xcafd, 0x1d60, 0x703c, 0x6016, 0x6007,
+	0x004a, 0x6003, 0x0001, 0x080c, 0x8641, 0x0005, 0x2001, 0x1823,
+	0x2004, 0x9082, 0x00e1, 0x1268, 0x080c, 0xca07, 0x0904, 0xc959,
+	0x6007, 0x004e, 0x6003, 0x0001, 0x080c, 0x8641, 0x080c, 0x8b90,
+	0x0005, 0x6007, 0x0012, 0x0cb0, 0x6007, 0x004f, 0x6017, 0x0000,
+	0x7134, 0x918c, 0x00ff, 0x81ff, 0x0508, 0x9186, 0x0001, 0x1160,
+	0x7140, 0x2001, 0x1998, 0x2004, 0x9106, 0x11b0, 0x7144, 0x2001,
+	0x1999, 0x2004, 0x9106, 0x0190, 0x9186, 0x0002, 0x1168, 0x2011,
+	0x0276, 0x20a9, 0x0004, 0x6010, 0x0096, 0x2048, 0x2019, 0x000a,
+	0x080c, 0xb00b, 0x009e, 0x0110, 0x6017, 0x0001, 0x6003, 0x0001,
+	0x080c, 0x8641, 0x080c, 0x8b90, 0x0005, 0x6007, 0x0050, 0x703c,
+	0x6016, 0x0ca0, 0x0016, 0x00e6, 0x2071, 0x0260, 0x00b6, 0x00c6,
+	0x2260, 0x6010, 0x2058, 0xb8bc, 0xd084, 0x0150, 0x7128, 0x6044,
+	0x9106, 0x1120, 0x712c, 0x6048, 0x9106, 0x0110, 0x9006, 0x0010,
+	0x9085, 0x0001, 0x00ce, 0x00be, 0x00ee, 0x001e, 0x0005, 0x0016,
+	0x0096, 0x0086, 0x00e6, 0x01c6, 0x01d6, 0x0126, 0x2091, 0x8000,
+	0x2071, 0x1800, 0x20e1, 0x0000, 0x2001, 0x197a, 0x2003, 0x0000,
+	0x080c, 0x105c, 0x05a0, 0x2900, 0x6016, 0x708c, 0x8004, 0xa816,
+	0x908a, 0x001e, 0x02d0, 0xa833, 0x001e, 0x20a9, 0x001e, 0xa860,
+	0x20e8, 0xa85c, 0x9080, 0x001b, 0x20a0, 0x2001, 0x197a, 0x0016,
+	0x200c, 0x0471, 0x001e, 0x81ff, 0x01b8, 0x2940, 0x080c, 0x105c,
+	0x01b0, 0x2900, 0xa006, 0x2100, 0x0c18, 0xa832, 0x20a8, 0xa860,
+	0x20e8, 0xa85c, 0x9080, 0x001b, 0x20a0, 0x2001, 0x197a, 0x0016,
+	0x200c, 0x00b1, 0x001e, 0x0000, 0x9085, 0x0001, 0x0048, 0x2071,
+	0x1800, 0x708f, 0x0000, 0x6014, 0x2048, 0x080c, 0x0ff5, 0x9006,
+	0x012e, 0x01de, 0x01ce, 0x00ee, 0x008e, 0x009e, 0x001e, 0x0005,
+	0x0006, 0x0016, 0x0026, 0x0036, 0x00c6, 0x918c, 0xffff, 0x11b0,
+	0x080c, 0x21dd, 0x2099, 0x026c, 0x2001, 0x0014, 0x3518, 0x9312,
+	0x0108, 0x1218, 0x23a8, 0x4003, 0x0400, 0x20a8, 0x4003, 0x22a8,
+	0x8108, 0x080c, 0x21dd, 0x2099, 0x0260, 0x0ca8, 0x080c, 0x21dd,
+	0x2061, 0x197a, 0x6004, 0x2098, 0x6008, 0x3518, 0x9312, 0x0108,
+	0x1218, 0x23a8, 0x4003, 0x0048, 0x20a8, 0x4003, 0x22a8, 0x8108,
+	0x080c, 0x21dd, 0x2099, 0x0260, 0x0ca8, 0x2061, 0x197a, 0x2019,
+	0x0280, 0x3300, 0x931e, 0x0110, 0x6006, 0x0020, 0x2001, 0x0260,
+	0x6006, 0x8108, 0x2162, 0x9292, 0x0021, 0x9296, 0xffff, 0x620a,
+	0x00ce, 0x003e, 0x002e, 0x001e, 0x000e, 0x0005, 0x0006, 0x0016,
+	0x0026, 0x0036, 0x00c6, 0x81ff, 0x11b8, 0x080c, 0x21f5, 0x20a1,
+	0x024c, 0x2001, 0x0014, 0x3518, 0x9312, 0x1218, 0x23a8, 0x4003,
+	0x0418, 0x20a8, 0x4003, 0x82ff, 0x01f8, 0x22a8, 0x8108, 0x080c,
+	0x21f5, 0x20a1, 0x0240, 0x0c98, 0x080c, 0x21f5, 0x2061, 0x197d,
+	0x6004, 0x20a0, 0x6008, 0x3518, 0x9312, 0x1218, 0x23a8, 0x4003,
+	0x0058, 0x20a8, 0x4003, 0x82ff, 0x0138, 0x22a8, 0x8108, 0x080c,
+	0x21f5, 0x20a1, 0x0240, 0x0c98, 0x2061, 0x197d, 0x2019, 0x0260,
+	0x3400, 0x931e, 0x0110, 0x6006, 0x0020, 0x2001, 0x0240, 0x6006,
+	0x8108, 0x2162, 0x9292, 0x0021, 0x9296, 0xffff, 0x620a, 0x00ce,
+	0x003e, 0x002e, 0x001e, 0x000e, 0x0005, 0x00b6, 0x0066, 0x6610,
+	0x2658, 0xbe04, 0x96b4, 0xff00, 0x8637, 0x9686, 0x0006, 0x0170,
+	0x9686, 0x0004, 0x0158, 0xbe04, 0x96b4, 0x00ff, 0x9686, 0x0006,
+	0x0128, 0x9686, 0x0004, 0x0110, 0x9085, 0x0001, 0x006e, 0x00be,
+	0x0005, 0x00d6, 0x080c, 0xcb95, 0x00de, 0x0005, 0x00d6, 0x080c,
+	0xcba2, 0x1520, 0x680c, 0x908c, 0xff00, 0x6820, 0x9084, 0x00ff,
+	0x9115, 0x6216, 0x6824, 0x602e, 0xd1e4, 0x0130, 0x9006, 0x080c,
+	0xdaef, 0x2009, 0x0001, 0x0078, 0xd1ec, 0x0180, 0x6920, 0x918c,
+	0x00ff, 0x6824, 0x080c, 0x266e, 0x1148, 0x2001, 0x0001, 0x080c,
+	0xdaef, 0x2110, 0x900e, 0x080c, 0x30f4, 0x0018, 0x9085, 0x0001,
+	0x0008, 0x9006, 0x00de, 0x0005, 0x00b6, 0x00c6, 0x080c, 0xa026,
+	0x05a8, 0x0016, 0x0026, 0x00c6, 0x2011, 0x0263, 0x2204, 0x8211,
+	0x220c, 0x080c, 0x266e, 0x1578, 0x080c, 0x6344, 0x1560, 0xbe12,
+	0xbd16, 0x00ce, 0x002e, 0x001e, 0x2b00, 0x6012, 0x080c, 0xd9d2,
+	0x11d8, 0x080c, 0x31ce, 0x11c0, 0x080c, 0xcafd, 0x0510, 0x2001,
+	0x0007, 0x080c, 0x62f5, 0x2001, 0x0007, 0x080c, 0x6321, 0x6017,
+	0x0000, 0x6023, 0x0001, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c,
+	0x8641, 0x080c, 0x8b90, 0x0010, 0x080c, 0x9fd5, 0x9085, 0x0001,
+	0x00ce, 0x00be, 0x0005, 0x080c, 0x9fd5, 0x00ce, 0x002e, 0x001e,
+	0x0ca8, 0x080c, 0x9fd5, 0x9006, 0x0c98, 0x2069, 0x026d, 0x6800,
+	0x9082, 0x0010, 0x1228, 0x6017, 0x0000, 0x9085, 0x0001, 0x0008,
+	0x9006, 0x0005, 0x6017, 0x0000, 0x2069, 0x026c, 0x6808, 0x9084,
+	0xff00, 0x9086, 0x0800, 0x1190, 0x6904, 0x9186, 0x0018, 0x0118,
+	0x9186, 0x0014, 0x1158, 0x810f, 0x6800, 0x9084, 0x00ff, 0x910d,
+	0x615a, 0x908e, 0x0014, 0x0110, 0x908e, 0x0010, 0x0005, 0x6004,
+	0x90b2, 0x0053, 0x1a0c, 0x0e02, 0x91b6, 0x0013, 0x1130, 0x2008,
+	0x91b2, 0x0040, 0x1a04, 0xcd0d, 0x040a, 0x91b6, 0x0027, 0x0198,
+	0x9186, 0x0015, 0x0118, 0x9186, 0x0016, 0x1148, 0x080c, 0xc46a,
+	0x0128, 0x6000, 0x9086, 0x0002, 0x0904, 0xa9dc, 0x0005, 0x91b6,
+	0x0014, 0x190c, 0x0e02, 0x2001, 0x0007, 0x080c, 0x6321, 0x080c,
+	0x8a84, 0x080c, 0xa007, 0x080c, 0x8b90, 0x0005, 0xcc2e, 0xcc30,
+	0xcc2e, 0xcc2e, 0xcc2e, 0xcc30, 0xcc3f, 0xcd06, 0xcc91, 0xcd06,
+	0xccb7, 0xcd06, 0xcc3f, 0xcd06, 0xccfe, 0xcd06, 0xccfe, 0xcd06,
+	0xcd06, 0xcc2e, 0xcc2e, 0xcc2e, 0xcc2e, 0xcc2e, 0xcc2e, 0xcc2e,
+	0xcc2e, 0xcc2e, 0xcc2e, 0xcc2e, 0xcc30, 0xcc2e, 0xcd06, 0xcc2e,
+	0xcc2e, 0xcd06, 0xcc2e, 0xcd03, 0xcd06, 0xcc2e, 0xcc2e, 0xcc2e,
+	0xcc2e, 0xcd06, 0xcd06, 0xcc2e, 0xcd06, 0xcd06, 0xcc2e, 0xcc3a,
+	0xcc2e, 0xcc2e, 0xcc2e, 0xcc2e, 0xcd02, 0xcd06, 0xcc2e, 0xcc2e,
+	0xcd06, 0xcd06, 0xcc2e, 0xcc2e, 0xcc2e, 0xcc2e, 0x080c, 0x0e02,
+	0x080c, 0x8a84, 0x080c, 0xc45c, 0x6003, 0x0002, 0x080c, 0x8b90,
+	0x0804, 0xcd0c, 0x9006, 0x080c, 0x62e1, 0x0804, 0xcd06, 0x080c,
+	0x66c2, 0x1904, 0xcd06, 0x9006, 0x080c, 0x62e1, 0x6010, 0x2058,
+	0xb810, 0x9086, 0x00ff, 0x1140, 0x00f6, 0x2079, 0x1800, 0x78a4,
+	0x8000, 0x78a6, 0x00fe, 0x0428, 0x6010, 0x2058, 0xb8b0, 0x9005,
+	0x1178, 0x080c, 0xc444, 0x1904, 0xcd06, 0x0036, 0x0046, 0xbba0,
+	0x2021, 0x0007, 0x080c, 0x4bb5, 0x004e, 0x003e, 0x0804, 0xcd06,
+	0x080c, 0x31ff, 0x1904, 0xcd06, 0x2001, 0x1800, 0x2004, 0x9086,
+	0x0002, 0x1138, 0x00f6, 0x2079, 0x1800, 0x78a4, 0x8000, 0x78a6,
+	0x00fe, 0x2001, 0x0002, 0x080c, 0x62f5, 0x080c, 0x8a84, 0x6023,
+	0x0001, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x8641, 0x080c,
+	0x8b90, 0x6110, 0x2158, 0x2009, 0x0001, 0x080c, 0x8268, 0x0804,
+	0xcd0c, 0x6610, 0x2658, 0xbe04, 0x96b4, 0xff00, 0x8637, 0x9686,
+	0x0006, 0x0138, 0x9686, 0x0004, 0x0120, 0x2001, 0x0004, 0x080c,
+	0x6321, 0x080c, 0xdb3e, 0x0904, 0xcd06, 0x080c, 0x8a84, 0x2001,
+	0x0004, 0x080c, 0x62f5, 0x6023, 0x0001, 0x6003, 0x0001, 0x6007,
+	0x0003, 0x080c, 0x8641, 0x080c, 0x8b90, 0x0804, 0xcd0c, 0x2001,
 	0x1800, 0x2004, 0x9086, 0x0003, 0x1158, 0x0036, 0x0046, 0x6010,
-	0x2058, 0xbba0, 0x2021, 0x0006, 0x080c, 0x4cbc, 0x004e, 0x003e,
-	0x2001, 0x0006, 0x080c, 0xcdc2, 0x6610, 0x2658, 0xbe04, 0x0066,
+	0x2058, 0xbba0, 0x2021, 0x0006, 0x080c, 0x4bb5, 0x004e, 0x003e,
+	0x2001, 0x0006, 0x080c, 0xcd2a, 0x6610, 0x2658, 0xbe04, 0x0066,
 	0x96b4, 0xff00, 0x8637, 0x9686, 0x0006, 0x006e, 0x0168, 0x2001,
-	0x0006, 0x080c, 0x641c, 0x9284, 0x00ff, 0x908e, 0x0007, 0x1120,
-	0x2001, 0x0006, 0x080c, 0x63f0, 0x080c, 0x67bb, 0x11f8, 0x2001,
+	0x0006, 0x080c, 0x6321, 0x9284, 0x00ff, 0x908e, 0x0007, 0x1120,
+	0x2001, 0x0006, 0x080c, 0x62f5, 0x080c, 0x66c2, 0x11f8, 0x2001,
 	0x1836, 0x2004, 0xd0a4, 0x01d0, 0xbe04, 0x96b4, 0x00ff, 0x9686,
 	0x0006, 0x01a0, 0x00f6, 0x2079, 0x1800, 0x78a4, 0x8000, 0x78a6,
-	0x00fe, 0x0804, 0xcd25, 0x2001, 0x0004, 0x0030, 0x2001, 0x0006,
-	0x0449, 0x0020, 0x0018, 0x0010, 0x080c, 0x641c, 0x080c, 0x8b04,
-	0x080c, 0xa0e3, 0x080c, 0x8c10, 0x0005, 0x2600, 0x0002, 0xcdb9,
-	0xcdb9, 0xcdb9, 0xcdb9, 0xcdb9, 0xcdbb, 0xcdb9, 0xcdb9, 0xcdb9,
-	0xcdb9, 0xcdbb, 0xcdb9, 0xcdb9, 0xcdb9, 0xcdbb, 0xcdbb, 0xcdbb,
-	0xcdbb, 0x080c, 0x0dfa, 0x080c, 0x8b04, 0x080c, 0xa0e3, 0x080c,
-	0x8c10, 0x0005, 0x0016, 0x00b6, 0x00d6, 0x6110, 0x2158, 0xb900,
-	0xd184, 0x0138, 0x080c, 0x63f0, 0x9006, 0x080c, 0x63dc, 0x080c,
-	0x31b4, 0x00de, 0x00be, 0x001e, 0x0005, 0x6610, 0x2658, 0xb804,
-	0x9084, 0xff00, 0x8007, 0x90b2, 0x000c, 0x1a0c, 0x0dfa, 0x91b6,
-	0x0015, 0x1110, 0x003b, 0x0028, 0x91b6, 0x0016, 0x190c, 0x0dfa,
-	0x006b, 0x0005, 0xab62, 0xab62, 0xab62, 0xab62, 0xce57, 0xab62,
-	0xce41, 0xce02, 0xab62, 0xab62, 0xab62, 0xab62, 0xab62, 0xab62,
-	0xab62, 0xab62, 0xce57, 0xab62, 0xce41, 0xce48, 0xab62, 0xab62,
-	0xab62, 0xab62, 0x00f6, 0x080c, 0x67bb, 0x11d8, 0x080c, 0xc539,
+	0x00fe, 0x0804, 0xcc79, 0x2001, 0x0004, 0x0030, 0x2001, 0x0006,
+	0x0449, 0x0020, 0x0018, 0x0010, 0x080c, 0x6321, 0x080c, 0x8a84,
+	0x080c, 0x9fd5, 0x080c, 0x8b90, 0x0005, 0x2600, 0x0002, 0xcd21,
+	0xcd21, 0xcd21, 0xcd21, 0xcd21, 0xcd23, 0xcd21, 0xcd21, 0xcd21,
+	0xcd21, 0xcd23, 0xcd21, 0xcd21, 0xcd21, 0xcd23, 0xcd23, 0xcd23,
+	0xcd23, 0x080c, 0x0e02, 0x080c, 0x8a84, 0x080c, 0x9fd5, 0x080c,
+	0x8b90, 0x0005, 0x0016, 0x00b6, 0x00d6, 0x6110, 0x2158, 0xb900,
+	0xd184, 0x0138, 0x080c, 0x62f5, 0x9006, 0x080c, 0x62e1, 0x080c,
+	0x30d4, 0x00de, 0x00be, 0x001e, 0x0005, 0x6610, 0x2658, 0xb804,
+	0x9084, 0xff00, 0x8007, 0x90b2, 0x000c, 0x1a0c, 0x0e02, 0x91b6,
+	0x0015, 0x1110, 0x003b, 0x0028, 0x91b6, 0x0016, 0x190c, 0x0e02,
+	0x006b, 0x0005, 0xaa76, 0xaa76, 0xaa76, 0xaa76, 0xcdbf, 0xaa76,
+	0xcda9, 0xcd6a, 0xaa76, 0xaa76, 0xaa76, 0xaa76, 0xaa76, 0xaa76,
+	0xaa76, 0xaa76, 0xcdbf, 0xaa76, 0xcda9, 0xcdb0, 0xaa76, 0xaa76,
+	0xaa76, 0xaa76, 0x00f6, 0x080c, 0x66c2, 0x11d8, 0x080c, 0xc444,
 	0x11c0, 0x6010, 0x905d, 0x01a8, 0xb8b0, 0x9005, 0x0190, 0x9006,
-	0x080c, 0x63dc, 0x2001, 0x0002, 0x080c, 0x63f0, 0x6023, 0x0001,
-	0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x86c1, 0x080c, 0x8c10,
-	0x00f0, 0x2011, 0x0263, 0x2204, 0x8211, 0x220c, 0x080c, 0x276e,
-	0x11b0, 0x080c, 0x649f, 0x0118, 0x080c, 0xa0e3, 0x0080, 0xb810,
-	0x0006, 0xb814, 0x0006, 0xb8b0, 0x0006, 0x080c, 0x5f45, 0x000e,
-	0xb8b2, 0x000e, 0xb816, 0x000e, 0xb812, 0x080c, 0xa0e3, 0x00fe,
-	0x0005, 0x6604, 0x96b6, 0x001e, 0x1110, 0x080c, 0xa0e3, 0x0005,
-	0x080c, 0xaf48, 0x1148, 0x6003, 0x0001, 0x6007, 0x0001, 0x080c,
-	0x86c1, 0x080c, 0x8c10, 0x0010, 0x080c, 0xa0e3, 0x0005, 0x0804,
-	0xa0e3, 0x6004, 0x908a, 0x0053, 0x1a0c, 0x0dfa, 0x080c, 0x8b04,
-	0x080c, 0xa113, 0x080c, 0x8c10, 0x0005, 0x9182, 0x0040, 0x0002,
-	0xce7c, 0xce7c, 0xce7c, 0xce7c, 0xce7e, 0xce7c, 0xce7c, 0xce7c,
-	0xce7c, 0xce7c, 0xce7c, 0xce7c, 0xce7c, 0xce7c, 0xce7c, 0xce7c,
-	0xce7c, 0xce7c, 0xce7c, 0xce7c, 0x080c, 0x0dfa, 0x0096, 0x00b6,
+	0x080c, 0x62e1, 0x2001, 0x0002, 0x080c, 0x62f5, 0x6023, 0x0001,
+	0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x8641, 0x080c, 0x8b90,
+	0x00f0, 0x2011, 0x0263, 0x2204, 0x8211, 0x220c, 0x080c, 0x266e,
+	0x11b0, 0x080c, 0x63a4, 0x0118, 0x080c, 0x9fd5, 0x0080, 0xb810,
+	0x0006, 0xb814, 0x0006, 0xb8b0, 0x0006, 0x080c, 0x5e4a, 0x000e,
+	0xb8b2, 0x000e, 0xb816, 0x000e, 0xb812, 0x080c, 0x9fd5, 0x00fe,
+	0x0005, 0x6604, 0x96b6, 0x001e, 0x1110, 0x080c, 0x9fd5, 0x0005,
+	0x080c, 0xae83, 0x1148, 0x6003, 0x0001, 0x6007, 0x0001, 0x080c,
+	0x8641, 0x080c, 0x8b90, 0x0010, 0x080c, 0x9fd5, 0x0005, 0x0804,
+	0x9fd5, 0x6004, 0x908a, 0x0053, 0x1a0c, 0x0e02, 0x080c, 0x8a84,
+	0x080c, 0xa007, 0x080c, 0x8b90, 0x0005, 0x9182, 0x0040, 0x0002,
+	0xcde4, 0xcde4, 0xcde4, 0xcde4, 0xcde6, 0xcde4, 0xcde4, 0xcde4,
+	0xcde4, 0xcde4, 0xcde4, 0xcde4, 0xcde4, 0xcde4, 0xcde4, 0xcde4,
+	0xcde4, 0xcde4, 0xcde4, 0xcde4, 0x080c, 0x0e02, 0x0096, 0x00b6,
 	0x00d6, 0x00e6, 0x00f6, 0x0046, 0x0026, 0x6210, 0x2258, 0xb8ac,
 	0x9005, 0x11a8, 0x6106, 0x2071, 0x0260, 0x7444, 0x94a4, 0xff00,
-	0x0904, 0xcee4, 0x080c, 0xdb91, 0x1170, 0x9486, 0x2000, 0x1158,
-	0x2009, 0x0001, 0x2011, 0x0200, 0x080c, 0x84d1, 0x0020, 0x9026,
-	0x080c, 0xdac6, 0x0c38, 0x080c, 0x1031, 0x090c, 0x0dfa, 0x6003,
+	0x0904, 0xce4c, 0x080c, 0xdae3, 0x1170, 0x9486, 0x2000, 0x1158,
+	0x2009, 0x0001, 0x2011, 0x0200, 0x080c, 0x8451, 0x0020, 0x9026,
+	0x080c, 0xda17, 0x0c38, 0x080c, 0x1043, 0x090c, 0x0e02, 0x6003,
 	0x0007, 0xa867, 0x010d, 0x9006, 0xa802, 0xa86a, 0xac8a, 0x2c00,
 	0xa88e, 0x6008, 0xa8e2, 0x6010, 0x2058, 0xb8a0, 0x7130, 0xa97a,
 	0x0016, 0xa876, 0xa87f, 0x0000, 0xa883, 0x0000, 0xa887, 0x0036,
-	0x080c, 0x6ae9, 0x001e, 0x080c, 0xdb91, 0x1904, 0xcf44, 0x9486,
-	0x2000, 0x1130, 0x2019, 0x0017, 0x080c, 0xd801, 0x0804, 0xcf44,
-	0x9486, 0x0200, 0x1120, 0x080c, 0xd79d, 0x0804, 0xcf44, 0x9486,
-	0x0400, 0x0120, 0x9486, 0x1000, 0x1904, 0xcf44, 0x2019, 0x0002,
-	0x080c, 0xd7b8, 0x0804, 0xcf44, 0x2069, 0x1a48, 0x6a00, 0xd284,
-	0x0904, 0xcfae, 0x9284, 0x0300, 0x1904, 0xcfa7, 0x6804, 0x9005,
-	0x0904, 0xcf8f, 0x2d78, 0x6003, 0x0007, 0x080c, 0x104a, 0x0904,
-	0xcf50, 0x7800, 0xd08c, 0x1118, 0x7804, 0x8001, 0x7806, 0x6017,
-	0x0000, 0x2001, 0x180f, 0x2004, 0xd084, 0x1904, 0xcfb2, 0x9006,
+	0x080c, 0x6a23, 0x001e, 0x080c, 0xdae3, 0x1904, 0xceac, 0x9486,
+	0x2000, 0x1130, 0x2019, 0x0017, 0x080c, 0xd74e, 0x0804, 0xceac,
+	0x9486, 0x0200, 0x1120, 0x080c, 0xd6e5, 0x0804, 0xceac, 0x9486,
+	0x0400, 0x0120, 0x9486, 0x1000, 0x1904, 0xceac, 0x2019, 0x0002,
+	0x080c, 0xd700, 0x0804, 0xceac, 0x2069, 0x1a4c, 0x6a00, 0xd284,
+	0x0904, 0xcf16, 0x9284, 0x0300, 0x1904, 0xcf0f, 0x6804, 0x9005,
+	0x0904, 0xcef7, 0x2d78, 0x6003, 0x0007, 0x080c, 0x105c, 0x0904,
+	0xceb8, 0x7800, 0xd08c, 0x1118, 0x7804, 0x8001, 0x7806, 0x6017,
+	0x0000, 0x2001, 0x180f, 0x2004, 0xd084, 0x1904, 0xcf1a, 0x9006,
 	0xa802, 0xa867, 0x0116, 0xa86a, 0x6008, 0xa8e2, 0x2c00, 0xa87a,
 	0x6010, 0x2058, 0xb8a0, 0x7130, 0xa9b6, 0xa876, 0xb928, 0xa9ba,
 	0xb92c, 0xa9be, 0xb930, 0xa9c2, 0xb934, 0xa9c6, 0xa883, 0x003d,
-	0x7044, 0x9084, 0x0003, 0x9080, 0xcf4c, 0x2005, 0xa87e, 0x20a9,
+	0x7044, 0x9084, 0x0003, 0x9080, 0xceb4, 0x2005, 0xa87e, 0x20a9,
 	0x000a, 0x2001, 0x0270, 0xaa5c, 0x9290, 0x0021, 0x2009, 0x0205,
 	0x200b, 0x0080, 0x20e1, 0x0000, 0xab60, 0x23e8, 0x2098, 0x22a0,
 	0x4003, 0x200b, 0x0000, 0x2001, 0x027a, 0x200c, 0xa9b2, 0x8000,
-	0x200c, 0xa9ae, 0x080c, 0x6ae9, 0x002e, 0x004e, 0x00fe, 0x00ee,
+	0x200c, 0xa9ae, 0x080c, 0x6a23, 0x002e, 0x004e, 0x00fe, 0x00ee,
 	0x00de, 0x00be, 0x009e, 0x0005, 0x0000, 0x0080, 0x0040, 0x0000,
-	0x2001, 0x1810, 0x2004, 0xd084, 0x0120, 0x080c, 0x1031, 0x1904,
-	0xcef9, 0x6017, 0xf100, 0x6003, 0x0001, 0x6007, 0x0041, 0x080c,
-	0x8679, 0x080c, 0x8c10, 0x0c00, 0x2069, 0x0260, 0x6848, 0x9084,
+	0x2001, 0x1810, 0x2004, 0xd084, 0x0120, 0x080c, 0x1043, 0x1904,
+	0xce61, 0x6017, 0xf100, 0x6003, 0x0001, 0x6007, 0x0041, 0x080c,
+	0x85f9, 0x080c, 0x8b90, 0x0c00, 0x2069, 0x0260, 0x6848, 0x9084,
 	0xff00, 0x9086, 0x1200, 0x1198, 0x686c, 0x9084, 0x00ff, 0x0016,
 	0x6114, 0x918c, 0xf700, 0x910d, 0x6116, 0x001e, 0x6003, 0x0001,
-	0x6007, 0x0043, 0x080c, 0x8679, 0x080c, 0x8c10, 0x0828, 0x6868,
+	0x6007, 0x0043, 0x080c, 0x85f9, 0x080c, 0x8b90, 0x0828, 0x6868,
 	0x602e, 0x686c, 0x6032, 0x6017, 0xf200, 0x6003, 0x0001, 0x6007,
-	0x0041, 0x080c, 0x8679, 0x080c, 0x8c10, 0x0804, 0xcf44, 0x2001,
-	0x180e, 0x2004, 0xd0ec, 0x0120, 0x2011, 0x8049, 0x080c, 0x4b1f,
+	0x0041, 0x080c, 0x85f9, 0x080c, 0x8b90, 0x0804, 0xceac, 0x2001,
+	0x180e, 0x2004, 0xd0ec, 0x0120, 0x2011, 0x8049, 0x080c, 0x4a18,
 	0x6017, 0xf300, 0x0010, 0x6017, 0xf100, 0x6003, 0x0001, 0x6007,
-	0x0041, 0x080c, 0x8679, 0x080c, 0x8c10, 0x0804, 0xcf44, 0x6017,
-	0xf500, 0x0c98, 0x6017, 0xf600, 0x0804, 0xcf64, 0x6017, 0xf200,
-	0x0804, 0xcf64, 0xa867, 0x0146, 0xa86b, 0x0000, 0x6008, 0xa886,
-	0x2c00, 0xa87a, 0x7044, 0x9084, 0x0003, 0x9080, 0xcf4c, 0x2005,
+	0x0041, 0x080c, 0x85f9, 0x080c, 0x8b90, 0x0804, 0xceac, 0x6017,
+	0xf500, 0x0c98, 0x6017, 0xf600, 0x0804, 0xcecc, 0x6017, 0xf200,
+	0x0804, 0xcecc, 0xa867, 0x0146, 0xa86b, 0x0000, 0x6008, 0xa886,
+	0x2c00, 0xa87a, 0x7044, 0x9084, 0x0003, 0x9080, 0xceb4, 0x2005,
 	0xa87e, 0x2928, 0x6010, 0x2058, 0xb8a0, 0xa876, 0xb828, 0xa88a,
 	0xb82c, 0xa88e, 0xb830, 0xa892, 0xb834, 0xa896, 0xa883, 0x003d,
 	0x2009, 0x0205, 0x2104, 0x9085, 0x0080, 0x200a, 0x20e1, 0x0000,
 	0x2011, 0x0210, 0x2214, 0x9294, 0x0fff, 0xaaa2, 0x9282, 0x0111,
-	0x1a0c, 0x0dfa, 0x8210, 0x821c, 0x2001, 0x026c, 0x2098, 0xa860,
-	0x20e8, 0xa85c, 0x9080, 0x0029, 0x20a0, 0x2011, 0xd02e, 0x2041,
+	0x1a0c, 0x0e02, 0x8210, 0x821c, 0x2001, 0x026c, 0x2098, 0xa860,
+	0x20e8, 0xa85c, 0x9080, 0x0029, 0x20a0, 0x2011, 0xcf96, 0x2041,
 	0x0001, 0x223d, 0x9784, 0x00ff, 0x9322, 0x1208, 0x2300, 0x20a8,
 	0x4003, 0x931a, 0x0530, 0x8210, 0xd7fc, 0x1130, 0x8d68, 0x2d0a,
-	0x2001, 0x0260, 0x2098, 0x0c68, 0x2950, 0x080c, 0x104a, 0x0170,
+	0x2001, 0x0260, 0x2098, 0x0c68, 0x2950, 0x080c, 0x105c, 0x0170,
 	0x2900, 0xb002, 0xa867, 0x0147, 0xa86b, 0x0000, 0xa860, 0x20e8,
 	0xa85c, 0x9080, 0x001b, 0x20a0, 0x8840, 0x08d8, 0x2548, 0xa800,
-	0x902d, 0x0118, 0x080c, 0x1063, 0x0cc8, 0x080c, 0x1063, 0x0804,
-	0xcf50, 0x2548, 0x8847, 0x9885, 0x0046, 0xa866, 0x2009, 0x0205,
-	0x200b, 0x0000, 0x080c, 0xd830, 0x0804, 0xcf44, 0x8010, 0x0004,
+	0x902d, 0x0118, 0x080c, 0x1075, 0x0cc8, 0x080c, 0x1075, 0x0804,
+	0xceb8, 0x2548, 0x8847, 0x9885, 0x0046, 0xa866, 0x2009, 0x0205,
+	0x200b, 0x0000, 0x080c, 0xd781, 0x0804, 0xceac, 0x8010, 0x0004,
 	0x801a, 0x0006, 0x8018, 0x0008, 0x8016, 0x000a, 0x8014, 0x9186,
-	0x0013, 0x1160, 0x6004, 0x908a, 0x0054, 0x1a0c, 0x0dfa, 0x9082,
-	0x0040, 0x0a0c, 0x0dfa, 0x2008, 0x0804, 0xd0e0, 0x9186, 0x0051,
-	0x0108, 0x00c0, 0x2001, 0x0109, 0x2004, 0xd084, 0x0904, 0xd090,
-	0x0126, 0x2091, 0x2800, 0x0006, 0x0016, 0x0026, 0x080c, 0x8563,
-	0x002e, 0x001e, 0x000e, 0x012e, 0x6000, 0x9086, 0x0002, 0x1580,
-	0x0804, 0xd129, 0x9186, 0x0027, 0x0530, 0x9186, 0x0048, 0x0128,
-	0x9186, 0x0014, 0x0500, 0x190c, 0x0dfa, 0x2001, 0x0109, 0x2004,
-	0xd084, 0x01f0, 0x00c6, 0x0126, 0x2091, 0x2800, 0x00c6, 0x2061,
-	0x0100, 0x0006, 0x0016, 0x0026, 0x080c, 0x8563, 0x002e, 0x001e,
-	0x000e, 0x00ce, 0x012e, 0x00ce, 0x6000, 0x9086, 0x0004, 0x190c,
-	0x0dfa, 0x0804, 0xd20c, 0x6004, 0x9082, 0x0040, 0x2008, 0x001a,
-	0x080c, 0xa178, 0x0005, 0xd0a7, 0xd0a9, 0xd0a9, 0xd0d0, 0xd0a7,
-	0xd0a7, 0xd0a7, 0xd0a7, 0xd0a7, 0xd0a7, 0xd0a7, 0xd0a7, 0xd0a7,
-	0xd0a7, 0xd0a7, 0xd0a7, 0xd0a7, 0xd0a7, 0xd0a7, 0xd0a7, 0x080c,
-	0x0dfa, 0x080c, 0x8b04, 0x080c, 0x8c10, 0x0036, 0x0096, 0x6014,
-	0x904d, 0x01d8, 0x080c, 0xbe37, 0x01c0, 0x6003, 0x0002, 0x6010,
-	0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x1178, 0x2019, 0x0004,
-	0x080c, 0xd830, 0x6017, 0x0000, 0x6018, 0x9005, 0x1120, 0x2001,
-	0x195f, 0x2004, 0x601a, 0x6003, 0x0007, 0x009e, 0x003e, 0x0005,
-	0x0096, 0x080c, 0x8b04, 0x080c, 0x8c10, 0x080c, 0xbe37, 0x0120,
-	0x6014, 0x2048, 0x080c, 0x1063, 0x080c, 0xa113, 0x009e, 0x0005,
-	0x0002, 0xd0f5, 0xd10c, 0xd0f7, 0xd123, 0xd0f5, 0xd0f5, 0xd0f5,
-	0xd0f5, 0xd0f5, 0xd0f5, 0xd0f5, 0xd0f5, 0xd0f5, 0xd0f5, 0xd0f5,
-	0xd0f5, 0xd0f5, 0xd0f5, 0xd0f5, 0xd0f5, 0x080c, 0x0dfa, 0x0096,
-	0x080c, 0x8b04, 0x6014, 0x2048, 0xa87c, 0xd0b4, 0x0138, 0x6003,
-	0x0007, 0x2009, 0x0043, 0x080c, 0xa15d, 0x0010, 0x6003, 0x0004,
-	0x080c, 0x8c10, 0x009e, 0x0005, 0x080c, 0x8b04, 0x080c, 0xbe37,
-	0x0138, 0x6114, 0x0096, 0x2148, 0xa97c, 0x009e, 0xd1ec, 0x1138,
-	0x080c, 0x84a6, 0x080c, 0xa0e3, 0x080c, 0x8c10, 0x0005, 0x080c,
-	0xda8a, 0x0db0, 0x0cc8, 0x080c, 0x8b04, 0x2009, 0x0041, 0x0804,
-	0xd294, 0x9182, 0x0040, 0x0002, 0xd140, 0xd142, 0xd140, 0xd140,
-	0xd140, 0xd140, 0xd140, 0xd140, 0xd140, 0xd140, 0xd140, 0xd140,
-	0xd140, 0xd140, 0xd140, 0xd140, 0xd140, 0xd143, 0xd140, 0xd140,
-	0x080c, 0x0dfa, 0x0005, 0x00d6, 0x080c, 0x84a6, 0x00de, 0x080c,
-	0xdae2, 0x080c, 0xa0e3, 0x0005, 0x9182, 0x0040, 0x0002, 0xd163,
-	0xd163, 0xd163, 0xd163, 0xd163, 0xd163, 0xd163, 0xd163, 0xd163,
-	0xd165, 0xd1d4, 0xd163, 0xd163, 0xd163, 0xd163, 0xd1d4, 0xd163,
-	0xd163, 0xd163, 0xd163, 0x080c, 0x0dfa, 0x2001, 0x0105, 0x2004,
-	0x9084, 0x1800, 0x01c8, 0x2001, 0x0132, 0x200c, 0x2001, 0x0131,
-	0x2004, 0x9105, 0x1904, 0xd1d4, 0x2009, 0x180c, 0x2104, 0xd0d4,
-	0x0904, 0xd1d4, 0xc0d4, 0x200a, 0x2009, 0x0105, 0x2104, 0x9084,
-	0xe7fd, 0x9085, 0x0010, 0x200a, 0x2001, 0x187b, 0x2004, 0xd0e4,
-	0x1528, 0x603b, 0x0000, 0x080c, 0x8bc0, 0x6014, 0x0096, 0x2048,
-	0xa87c, 0xd0fc, 0x0188, 0x908c, 0x0003, 0x918e, 0x0002, 0x0508,
-	0x2001, 0x180c, 0x2004, 0xd0d4, 0x11e0, 0x080c, 0x8ced, 0x2009,
-	0x0041, 0x009e, 0x0804, 0xd294, 0x080c, 0x8ced, 0x6003, 0x0007,
-	0x601b, 0x0000, 0x080c, 0x84a6, 0x009e, 0x0005, 0x2001, 0x0100,
-	0x2004, 0x9082, 0x0005, 0x0aa8, 0x2001, 0x011f, 0x2004, 0x603a,
-	0x0890, 0x2001, 0x180c, 0x200c, 0xc1d4, 0x2102, 0xd1cc, 0x0110,
-	0x080c, 0x2bca, 0x080c, 0x8ced, 0x6014, 0x2048, 0xa97c, 0xd1ec,
-	0x1130, 0x080c, 0x84a6, 0x080c, 0xa0e3, 0x009e, 0x0005, 0x080c,
-	0xda8a, 0x0db8, 0x009e, 0x0005, 0x2001, 0x180c, 0x200c, 0xc1d4,
-	0x2102, 0x0036, 0x080c, 0x8bc0, 0x080c, 0x8ced, 0x6014, 0x0096,
-	0x2048, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0bc, 0x0188,
-	0xa87c, 0x9084, 0x0003, 0x9086, 0x0002, 0x0140, 0xa8ac, 0x6330,
-	0x931a, 0x6332, 0xa8b0, 0x632c, 0x931b, 0x632e, 0x6003, 0x0002,
-	0x0080, 0x2019, 0x0004, 0x080c, 0xd830, 0x6018, 0x9005, 0x1128,
-	0x2001, 0x195f, 0x2004, 0x8003, 0x601a, 0x6017, 0x0000, 0x6003,
-	0x0007, 0x009e, 0x003e, 0x0005, 0x9182, 0x0040, 0x0002, 0xd223,
-	0xd223, 0xd223, 0xd223, 0xd223, 0xd223, 0xd223, 0xd223, 0xd225,
-	0xd223, 0xd223, 0xd223, 0xd223, 0xd223, 0xd223, 0xd223, 0xd223,
-	0xd223, 0xd223, 0xd270, 0x080c, 0x0dfa, 0x6014, 0x0096, 0x2048,
-	0xa834, 0xaa38, 0x6110, 0x00b6, 0x2158, 0xb900, 0x00be, 0xd1bc,
-	0x1190, 0x920d, 0x1518, 0xa87c, 0xd0fc, 0x0128, 0x2009, 0x0041,
-	0x009e, 0x0804, 0xd294, 0x6003, 0x0007, 0x601b, 0x0000, 0x080c,
-	0x84a6, 0x009e, 0x0005, 0x6124, 0xd1f4, 0x1d58, 0x0006, 0x0046,
-	0xacac, 0x9422, 0xa9b0, 0x2200, 0x910b, 0x6030, 0x9420, 0x6432,
-	0x602c, 0x9109, 0x612e, 0x004e, 0x000e, 0x08d8, 0x6110, 0x00b6,
-	0x2158, 0xb900, 0x00be, 0xd1bc, 0x1178, 0x2009, 0x180e, 0x210c,
-	0xd19c, 0x0118, 0x6003, 0x0007, 0x0010, 0x6003, 0x0006, 0x00e9,
-	0x080c, 0x84a8, 0x009e, 0x0005, 0x6003, 0x0002, 0x009e, 0x0005,
-	0x6024, 0xd0f4, 0x0128, 0x080c, 0x1582, 0x1904, 0xd225, 0x0005,
-	0x6014, 0x0096, 0x2048, 0xa834, 0xa938, 0x009e, 0x9105, 0x1120,
-	0x080c, 0x1582, 0x1904, 0xd225, 0x0005, 0xd2fc, 0x0140, 0x8002,
-	0x8000, 0x8212, 0x9291, 0x0000, 0x2009, 0x0009, 0x0010, 0x2009,
-	0x0015, 0xaa9a, 0xa896, 0x0005, 0x9182, 0x0040, 0x0208, 0x0062,
-	0x9186, 0x0013, 0x0120, 0x9186, 0x0014, 0x190c, 0x0dfa, 0x6024,
-	0xd0dc, 0x090c, 0x0dfa, 0x0005, 0xd2b8, 0xd2c4, 0xd2d0, 0xd2dc,
-	0xd2b8, 0xd2b8, 0xd2b8, 0xd2b8, 0xd2bf, 0xd2ba, 0xd2ba, 0xd2b8,
-	0xd2b8, 0xd2b8, 0xd2b8, 0xd2ba, 0xd2b8, 0xd2ba, 0xd2b8, 0xd2bf,
-	0x080c, 0x0dfa, 0x6024, 0xd0dc, 0x090c, 0x0dfa, 0x0005, 0x6014,
-	0x9005, 0x190c, 0x0dfa, 0x0005, 0x6003, 0x0001, 0x6106, 0x080c,
-	0x8679, 0x0126, 0x2091, 0x8000, 0x080c, 0x8c10, 0x012e, 0x0005,
-	0x6003, 0x0001, 0x6106, 0x080c, 0x8679, 0x0126, 0x2091, 0x8000,
-	0x080c, 0x8c10, 0x012e, 0x0005, 0x6003, 0x0003, 0x6106, 0x2c10,
-	0x080c, 0x1afe, 0x0126, 0x2091, 0x8000, 0x080c, 0x86de, 0x080c,
-	0x8ced, 0x012e, 0x0005, 0x0126, 0x2091, 0x8000, 0x0036, 0x0096,
-	0x9182, 0x0040, 0x0023, 0x009e, 0x003e, 0x012e, 0x0005, 0xd30b,
-	0xd30d, 0xd31f, 0xd339, 0xd30b, 0xd30b, 0xd30b, 0xd30b, 0xd30b,
-	0xd30b, 0xd30b, 0xd30b, 0xd30b, 0xd30b, 0xd30b, 0xd30b, 0xd30b,
-	0xd30b, 0xd30b, 0xd30b, 0x080c, 0x0dfa, 0x6014, 0x2048, 0xa87c,
-	0xd0fc, 0x01f8, 0x909c, 0x0003, 0x939e, 0x0003, 0x01d0, 0x6003,
-	0x0001, 0x6106, 0x080c, 0x8679, 0x080c, 0x8c10, 0x0470, 0x6014,
-	0x2048, 0xa87c, 0xd0fc, 0x0168, 0x909c, 0x0003, 0x939e, 0x0003,
-	0x0140, 0x6003, 0x0001, 0x6106, 0x080c, 0x8679, 0x080c, 0x8c10,
-	0x00e0, 0x901e, 0x6316, 0x631a, 0x2019, 0x0004, 0x080c, 0xd830,
-	0x00a0, 0x6014, 0x2048, 0xa87c, 0xd0fc, 0x0d98, 0x909c, 0x0003,
-	0x939e, 0x0003, 0x0d70, 0x6003, 0x0003, 0x6106, 0x2c10, 0x080c,
-	0x1afe, 0x080c, 0x86de, 0x080c, 0x8ced, 0x0005, 0x080c, 0x8b04,
-	0x6114, 0x81ff, 0x0158, 0x0096, 0x2148, 0x080c, 0xdb2e, 0x0036,
-	0x2019, 0x0029, 0x080c, 0xd830, 0x003e, 0x009e, 0x080c, 0xa113,
-	0x080c, 0x8c10, 0x0005, 0x080c, 0x8bc0, 0x6114, 0x81ff, 0x0158,
-	0x0096, 0x2148, 0x080c, 0xdb2e, 0x0036, 0x2019, 0x0029, 0x080c,
-	0xd830, 0x003e, 0x009e, 0x080c, 0xa113, 0x080c, 0x8ced, 0x0005,
-	0x9182, 0x0085, 0x0002, 0xd38a, 0xd388, 0xd388, 0xd396, 0xd388,
-	0xd388, 0xd388, 0xd388, 0xd388, 0xd388, 0xd388, 0xd388, 0xd388,
-	0x080c, 0x0dfa, 0x6003, 0x000b, 0x6106, 0x080c, 0x8679, 0x0126,
-	0x2091, 0x8000, 0x080c, 0x8c10, 0x012e, 0x0005, 0x0026, 0x00e6,
-	0x080c, 0xda81, 0x0118, 0x080c, 0xa0e3, 0x0450, 0x2071, 0x0260,
-	0x7224, 0x6216, 0x2001, 0x180e, 0x2004, 0xd0e4, 0x0150, 0x6010,
-	0x00b6, 0x2058, 0xbca0, 0x00be, 0x2c00, 0x2011, 0x014e, 0x080c,
-	0xa403, 0x7220, 0x080c, 0xd6d6, 0x0118, 0x6007, 0x0086, 0x0040,
-	0x6007, 0x0087, 0x7224, 0x9296, 0xffff, 0x1110, 0x6007, 0x0086,
-	0x6003, 0x0001, 0x080c, 0x8679, 0x080c, 0x8c10, 0x080c, 0x8ced,
-	0x00ee, 0x002e, 0x0005, 0x9186, 0x0013, 0x1160, 0x6004, 0x908a,
-	0x0085, 0x0a0c, 0x0dfa, 0x908a, 0x0092, 0x1a0c, 0x0dfa, 0x9082,
-	0x0085, 0x00a2, 0x9186, 0x0027, 0x0130, 0x9186, 0x0014, 0x0118,
-	0x080c, 0xa178, 0x0050, 0x2001, 0x0007, 0x080c, 0x641c, 0x080c,
-	0x8b04, 0x080c, 0xa113, 0x080c, 0x8c10, 0x0005, 0xd3fb, 0xd3fd,
-	0xd3fd, 0xd3fb, 0xd3fb, 0xd3fb, 0xd3fb, 0xd3fb, 0xd3fb, 0xd3fb,
-	0xd3fb, 0xd3fb, 0xd3fb, 0x080c, 0x0dfa, 0x080c, 0x8b04, 0x080c,
-	0xa113, 0x080c, 0x8c10, 0x0005, 0x9182, 0x0085, 0x0a0c, 0x0dfa,
-	0x9182, 0x0092, 0x1a0c, 0x0dfa, 0x9182, 0x0085, 0x0002, 0xd41c,
-	0xd41c, 0xd41c, 0xd41e, 0xd41c, 0xd41c, 0xd41c, 0xd41c, 0xd41c,
-	0xd41c, 0xd41c, 0xd41c, 0xd41c, 0x080c, 0x0dfa, 0x0005, 0x9186,
-	0x0013, 0x0148, 0x9186, 0x0014, 0x0130, 0x9186, 0x0027, 0x0118,
-	0x080c, 0xa178, 0x0030, 0x080c, 0x8b04, 0x080c, 0xa113, 0x080c,
-	0x8c10, 0x0005, 0x0036, 0x080c, 0xdae2, 0x6043, 0x0000, 0x2019,
-	0x000b, 0x0031, 0x6023, 0x0006, 0x6003, 0x0007, 0x003e, 0x0005,
-	0x0126, 0x0036, 0x2091, 0x8000, 0x0086, 0x2c40, 0x0096, 0x904e,
-	0x080c, 0x9a58, 0x009e, 0x008e, 0x1550, 0x0076, 0x2c38, 0x080c,
-	0x9b03, 0x007e, 0x1520, 0x6000, 0x9086, 0x0000, 0x0500, 0x6020,
-	0x9086, 0x0007, 0x01e0, 0x0096, 0x601c, 0xd084, 0x0140, 0x080c,
-	0xdae2, 0x080c, 0xc551, 0x080c, 0x19b4, 0x6023, 0x0007, 0x6014,
-	0x2048, 0x080c, 0xbe37, 0x0110, 0x080c, 0xd830, 0x009e, 0x6017,
-	0x0000, 0x080c, 0xdae2, 0x6023, 0x0007, 0x080c, 0xc551, 0x003e,
-	0x012e, 0x0005, 0x00f6, 0x00c6, 0x00b6, 0x0036, 0x0156, 0x2079,
-	0x0260, 0x7938, 0x783c, 0x080c, 0x276e, 0x15c8, 0x0016, 0x00c6,
-	0x080c, 0x649f, 0x1590, 0x001e, 0x00c6, 0x2160, 0x080c, 0xc54e,
-	0x00ce, 0x002e, 0x0026, 0x0016, 0x2019, 0x0029, 0x080c, 0x9bc9,
-	0x080c, 0x8803, 0x0076, 0x903e, 0x080c, 0x86f1, 0x007e, 0x001e,
-	0x0076, 0x903e, 0x080c, 0xd5f6, 0x007e, 0x0026, 0xba04, 0x9294,
-	0xff00, 0x8217, 0x9286, 0x0006, 0x0118, 0x9286, 0x0004, 0x1118,
-	0xbaa0, 0x080c, 0x3248, 0x002e, 0xbcb0, 0x001e, 0x080c, 0x5f45,
-	0xbe12, 0xbd16, 0xbcb2, 0x9006, 0x0010, 0x00ce, 0x001e, 0x015e,
-	0x003e, 0x00be, 0x00ce, 0x00fe, 0x0005, 0x00c6, 0x00d6, 0x00b6,
-	0x0016, 0x2009, 0x1823, 0x2104, 0x9086, 0x0074, 0x1904, 0xd51e,
-	0x2069, 0x0260, 0x6944, 0x9182, 0x0100, 0x06e0, 0x6940, 0x9184,
-	0x8000, 0x0904, 0xd51b, 0x2001, 0x1954, 0x2004, 0x9005, 0x1140,
-	0x6010, 0x2058, 0xb8b0, 0x9005, 0x0118, 0x9184, 0x0800, 0x0598,
-	0x6948, 0x918a, 0x0001, 0x0648, 0x080c, 0xdb96, 0x0118, 0x6978,
-	0xd1fc, 0x11b8, 0x2009, 0x0205, 0x200b, 0x0001, 0x693c, 0x81ff,
-	0x1198, 0x6944, 0x9182, 0x0100, 0x02a8, 0x6940, 0x81ff, 0x1178,
-	0x6948, 0x918a, 0x0001, 0x0288, 0x6950, 0x918a, 0x0001, 0x0298,
-	0x00d0, 0x6017, 0x0100, 0x00a0, 0x6017, 0x0300, 0x0088, 0x6017,
-	0x0500, 0x0070, 0x6017, 0x0700, 0x0058, 0x6017, 0x0900, 0x0040,
-	0x6017, 0x0b00, 0x0028, 0x6017, 0x0f00, 0x0010, 0x6017, 0x2d00,
-	0x9085, 0x0001, 0x0008, 0x9006, 0x001e, 0x00be, 0x00de, 0x00ce,
-	0x0005, 0x00c6, 0x00b6, 0x0026, 0x0036, 0x0156, 0x6210, 0x2258,
-	0xbb04, 0x9394, 0x00ff, 0x9286, 0x0006, 0x0180, 0x9286, 0x0004,
-	0x0168, 0x9394, 0xff00, 0x8217, 0x9286, 0x0006, 0x0138, 0x9286,
-	0x0004, 0x0120, 0x080c, 0x64ae, 0x0804, 0xd585, 0x2011, 0x0276,
-	0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019, 0x000a, 0x080c, 0xb0d0,
-	0x009e, 0x15a0, 0x2011, 0x027a, 0x20a9, 0x0004, 0x0096, 0x2b48,
-	0x2019, 0x0006, 0x080c, 0xb0d0, 0x009e, 0x1540, 0x0046, 0x0016,
-	0xbaa0, 0x2220, 0x9006, 0x2009, 0x185c, 0x210c, 0x0038, 0x2009,
-	0x0029, 0x080c, 0xd885, 0xb800, 0xc0e5, 0xb802, 0x2019, 0x0029,
-	0x080c, 0x8803, 0x0076, 0x2039, 0x0000, 0x080c, 0x86f1, 0x2c08,
-	0x080c, 0xd5f6, 0x007e, 0x2001, 0x0007, 0x080c, 0x641c, 0x2001,
-	0x0007, 0x080c, 0x63f0, 0x001e, 0x004e, 0x9006, 0x015e, 0x003e,
-	0x002e, 0x00be, 0x00ce, 0x0005, 0x00d6, 0x2069, 0x026e, 0x6800,
-	0x9086, 0x0800, 0x0118, 0x6017, 0x0000, 0x0008, 0x9006, 0x00de,
-	0x0005, 0x00b6, 0x00f6, 0x0016, 0x0026, 0x0036, 0x0156, 0x2079,
-	0x026c, 0x7930, 0x7834, 0x080c, 0x276e, 0x11d0, 0x080c, 0x649f,
-	0x11b8, 0x2011, 0x0270, 0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019,
-	0x000a, 0x080c, 0xb0d0, 0x009e, 0x1158, 0x2011, 0x0274, 0x20a9,
-	0x0004, 0x0096, 0x2b48, 0x2019, 0x0006, 0x080c, 0xb0d0, 0x009e,
-	0x015e, 0x003e, 0x002e, 0x001e, 0x00fe, 0x00be, 0x0005, 0x00b6,
-	0x0006, 0x0016, 0x0026, 0x0036, 0x0156, 0x2011, 0x0263, 0x2204,
-	0x8211, 0x220c, 0x080c, 0x276e, 0x11d0, 0x080c, 0x649f, 0x11b8,
-	0x2011, 0x0276, 0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019, 0x000a,
-	0x080c, 0xb0d0, 0x009e, 0x1158, 0x2011, 0x027a, 0x20a9, 0x0004,
-	0x0096, 0x2b48, 0x2019, 0x0006, 0x080c, 0xb0d0, 0x009e, 0x015e,
-	0x003e, 0x002e, 0x001e, 0x000e, 0x00be, 0x0005, 0x00e6, 0x00c6,
-	0x0086, 0x0076, 0x0066, 0x0056, 0x0046, 0x0026, 0x0126, 0x2091,
-	0x8000, 0x2740, 0x2029, 0x19c8, 0x252c, 0x2021, 0x19ce, 0x2424,
-	0x2061, 0x1cd0, 0x2071, 0x1800, 0x7650, 0x7070, 0x81ff, 0x0150,
-	0x0006, 0x9186, 0x1a8a, 0x000e, 0x0128, 0x8001, 0x9602, 0x1a04,
-	0xd68f, 0x0018, 0x9606, 0x0904, 0xd68f, 0x2100, 0x9c06, 0x0904,
-	0xd686, 0x080c, 0xd8c6, 0x1904, 0xd686, 0x080c, 0xdbb3, 0x0904,
-	0xd686, 0x080c, 0xd8b6, 0x0904, 0xd686, 0x6720, 0x9786, 0x0001,
-	0x1148, 0x080c, 0x32df, 0x0904, 0xd6aa, 0x6004, 0x9086, 0x0000,
-	0x1904, 0xd6aa, 0x9786, 0x0004, 0x0904, 0xd6aa, 0x9786, 0x0007,
-	0x0904, 0xd686, 0x2500, 0x9c06, 0x0904, 0xd686, 0x2400, 0x9c06,
-	0x05e8, 0x88ff, 0x0118, 0x6054, 0x9906, 0x15c0, 0x0096, 0x6000,
-	0x9086, 0x0004, 0x1120, 0x0016, 0x080c, 0x19b4, 0x001e, 0x9786,
-	0x000a, 0x0148, 0x080c, 0xc03f, 0x1130, 0x080c, 0xaa81, 0x009e,
-	0x080c, 0xa113, 0x0418, 0x6014, 0x2048, 0x080c, 0xbe37, 0x01d8,
-	0x9786, 0x0003, 0x1570, 0xa867, 0x0103, 0xa87c, 0xd0cc, 0x0130,
-	0x0096, 0xa878, 0x2048, 0x080c, 0x0fe3, 0x009e, 0xab7a, 0xa877,
-	0x0000, 0x080c, 0xdb2e, 0x0016, 0x080c, 0xc12d, 0x080c, 0x6adc,
-	0x001e, 0x080c, 0xc022, 0x009e, 0x080c, 0xa113, 0x9ce0, 0x0018,
-	0x2001, 0x1819, 0x2004, 0x9c02, 0x1210, 0x0804, 0xd60a, 0x012e,
-	0x002e, 0x004e, 0x005e, 0x006e, 0x007e, 0x008e, 0x00ce, 0x00ee,
-	0x0005, 0x9786, 0x0006, 0x1150, 0x9386, 0x0005, 0x0128, 0x080c,
-	0xdb2e, 0x080c, 0xd830, 0x08f8, 0x009e, 0x0c00, 0x9786, 0x000a,
-	0x0968, 0x0808, 0x81ff, 0x09d0, 0x9180, 0x0001, 0x2004, 0x9086,
-	0x0018, 0x0130, 0x9180, 0x0001, 0x2004, 0x9086, 0x002d, 0x1970,
-	0x6000, 0x9086, 0x0002, 0x1950, 0x080c, 0xc02e, 0x0130, 0x080c,
-	0xc03f, 0x1920, 0x080c, 0xaa81, 0x0038, 0x080c, 0x31b4, 0x080c,
-	0xc03f, 0x1110, 0x080c, 0xaa81, 0x080c, 0xa113, 0x0804, 0xd686,
-	0xa864, 0x9084, 0x00ff, 0x9086, 0x0039, 0x0005, 0x00c6, 0x00e6,
-	0x0016, 0x2c08, 0x2170, 0x9006, 0x080c, 0xd857, 0x001e, 0x0120,
-	0x6020, 0x9084, 0x000f, 0x001b, 0x00ee, 0x00ce, 0x0005, 0xd6f5,
-	0xd6f5, 0xd6f5, 0xd6f5, 0xd6f5, 0xd6f5, 0xd6f7, 0xd6f5, 0xd6f5,
-	0xd6f5, 0xd6f5, 0xa113, 0xa113, 0xd6f5, 0x9006, 0x0005, 0x0036,
-	0x0046, 0x0016, 0x7010, 0x00b6, 0x2058, 0xbca0, 0x00be, 0x2c00,
-	0x2009, 0x0020, 0x080c, 0xd885, 0x001e, 0x004e, 0x2019, 0x0002,
-	0x080c, 0xd440, 0x003e, 0x9085, 0x0001, 0x0005, 0x0096, 0x080c,
-	0xbe37, 0x0140, 0x6014, 0x904d, 0x080c, 0xba56, 0x687b, 0x0005,
-	0x080c, 0x6ae9, 0x009e, 0x080c, 0xa113, 0x9085, 0x0001, 0x0005,
-	0x2001, 0x0001, 0x080c, 0x63dc, 0x0156, 0x0016, 0x0026, 0x0036,
-	0x20a9, 0x0004, 0x2019, 0x1805, 0x2011, 0x0276, 0x080c, 0xb0bc,
-	0x003e, 0x002e, 0x001e, 0x015e, 0x9005, 0x0005, 0x00f6, 0x00e6,
-	0x00c6, 0x0086, 0x0076, 0x0066, 0x00b6, 0x0126, 0x2091, 0x8000,
-	0x2740, 0x2061, 0x1cd0, 0x2079, 0x0001, 0x8fff, 0x0904, 0xd790,
-	0x2071, 0x1800, 0x7650, 0x7070, 0x8001, 0x9602, 0x1a04, 0xd790,
-	0x88ff, 0x0120, 0x2800, 0x9c06, 0x1590, 0x2078, 0x080c, 0xd8b6,
-	0x0570, 0x2400, 0x9c06, 0x0558, 0x6720, 0x9786, 0x0006, 0x1538,
-	0x9786, 0x0007, 0x0520, 0x88ff, 0x1140, 0x6010, 0x9b06, 0x11f8,
-	0x85ff, 0x0118, 0x6054, 0x9106, 0x11d0, 0x0096, 0x601c, 0xd084,
-	0x0140, 0x080c, 0xdae2, 0x080c, 0xc551, 0x080c, 0x19b4, 0x6023,
-	0x0007, 0x6014, 0x2048, 0x080c, 0xbe37, 0x0120, 0x0046, 0x080c,
-	0xd830, 0x004e, 0x009e, 0x080c, 0xa113, 0x88ff, 0x1198, 0x9ce0,
-	0x0018, 0x2001, 0x1819, 0x2004, 0x9c02, 0x1210, 0x0804, 0xd745,
+	0x0013, 0x1160, 0x6004, 0x908a, 0x0054, 0x1a0c, 0x0e02, 0x9082,
+	0x0040, 0x0a0c, 0x0e02, 0x2008, 0x0804, 0xd025, 0x9186, 0x0051,
+	0x0108, 0x0048, 0x080c, 0xc46a, 0x0500, 0x6000, 0x9086, 0x0002,
+	0x11e0, 0x0804, 0xd06e, 0x9186, 0x0027, 0x0190, 0x9186, 0x0048,
+	0x0128, 0x9186, 0x0014, 0x0160, 0x190c, 0x0e02, 0x080c, 0xc46a,
+	0x0160, 0x6000, 0x9086, 0x0004, 0x190c, 0x0e02, 0x0804, 0xd151,
+	0x6004, 0x9082, 0x0040, 0x2008, 0x001a, 0x080c, 0xa06e, 0x0005,
+	0xcfec, 0xcfee, 0xcfee, 0xd015, 0xcfec, 0xcfec, 0xcfec, 0xcfec,
+	0xcfec, 0xcfec, 0xcfec, 0xcfec, 0xcfec, 0xcfec, 0xcfec, 0xcfec,
+	0xcfec, 0xcfec, 0xcfec, 0xcfec, 0x080c, 0x0e02, 0x080c, 0x8a84,
+	0x080c, 0x8b90, 0x0036, 0x0096, 0x6014, 0x904d, 0x01d8, 0x080c,
+	0xbd3b, 0x01c0, 0x6003, 0x0002, 0x6010, 0x00b6, 0x2058, 0xb800,
+	0x00be, 0xd0bc, 0x1178, 0x2019, 0x0004, 0x080c, 0xd781, 0x6017,
+	0x0000, 0x6018, 0x9005, 0x1120, 0x2001, 0x1961, 0x2004, 0x601a,
+	0x6003, 0x0007, 0x009e, 0x003e, 0x0005, 0x0096, 0x080c, 0x8a84,
+	0x080c, 0x8b90, 0x080c, 0xbd3b, 0x0120, 0x6014, 0x2048, 0x080c,
+	0x1075, 0x080c, 0xa007, 0x009e, 0x0005, 0x0002, 0xd03a, 0xd051,
+	0xd03c, 0xd068, 0xd03a, 0xd03a, 0xd03a, 0xd03a, 0xd03a, 0xd03a,
+	0xd03a, 0xd03a, 0xd03a, 0xd03a, 0xd03a, 0xd03a, 0xd03a, 0xd03a,
+	0xd03a, 0xd03a, 0x080c, 0x0e02, 0x0096, 0x080c, 0x8a84, 0x6014,
+	0x2048, 0xa87c, 0xd0b4, 0x0138, 0x6003, 0x0007, 0x2009, 0x0043,
+	0x080c, 0xa053, 0x0010, 0x6003, 0x0004, 0x080c, 0x8b90, 0x009e,
+	0x0005, 0x080c, 0x8a84, 0x080c, 0xbd3b, 0x0138, 0x6114, 0x0096,
+	0x2148, 0xa97c, 0x009e, 0xd1ec, 0x1138, 0x080c, 0x8426, 0x080c,
+	0x9fd5, 0x080c, 0x8b90, 0x0005, 0x080c, 0xd9db, 0x0db0, 0x0cc8,
+	0x080c, 0x8a84, 0x2009, 0x0041, 0x0804, 0xd1d9, 0x9182, 0x0040,
+	0x0002, 0xd085, 0xd087, 0xd085, 0xd085, 0xd085, 0xd085, 0xd085,
+	0xd085, 0xd085, 0xd085, 0xd085, 0xd085, 0xd085, 0xd085, 0xd085,
+	0xd085, 0xd085, 0xd088, 0xd085, 0xd085, 0x080c, 0x0e02, 0x0005,
+	0x00d6, 0x080c, 0x8426, 0x00de, 0x080c, 0xda33, 0x080c, 0x9fd5,
+	0x0005, 0x9182, 0x0040, 0x0002, 0xd0a8, 0xd0a8, 0xd0a8, 0xd0a8,
+	0xd0a8, 0xd0a8, 0xd0a8, 0xd0a8, 0xd0a8, 0xd0aa, 0xd119, 0xd0a8,
+	0xd0a8, 0xd0a8, 0xd0a8, 0xd119, 0xd0a8, 0xd0a8, 0xd0a8, 0xd0a8,
+	0x080c, 0x0e02, 0x2001, 0x0105, 0x2004, 0x9084, 0x1800, 0x01c8,
+	0x2001, 0x0132, 0x200c, 0x2001, 0x0131, 0x2004, 0x9105, 0x1904,
+	0xd119, 0x2009, 0x180c, 0x2104, 0xd0d4, 0x0904, 0xd119, 0xc0d4,
+	0x200a, 0x2009, 0x0105, 0x2104, 0x9084, 0xe7fd, 0x9085, 0x0010,
+	0x200a, 0x2001, 0x187b, 0x2004, 0xd0e4, 0x1528, 0x603b, 0x0000,
+	0x080c, 0x8b40, 0x6014, 0x0096, 0x2048, 0xa87c, 0xd0fc, 0x0188,
+	0x908c, 0x0003, 0x918e, 0x0002, 0x0508, 0x2001, 0x180c, 0x2004,
+	0xd0d4, 0x11e0, 0x080c, 0x8c6d, 0x2009, 0x0041, 0x009e, 0x0804,
+	0xd1d9, 0x080c, 0x8c6d, 0x6003, 0x0007, 0x601b, 0x0000, 0x080c,
+	0x8426, 0x009e, 0x0005, 0x2001, 0x0100, 0x2004, 0x9082, 0x0005,
+	0x0aa8, 0x2001, 0x011f, 0x2004, 0x603a, 0x0890, 0x2001, 0x180c,
+	0x200c, 0xc1d4, 0x2102, 0xd1cc, 0x0110, 0x080c, 0x2aca, 0x080c,
+	0x8c6d, 0x6014, 0x2048, 0xa97c, 0xd1ec, 0x1130, 0x080c, 0x8426,
+	0x080c, 0x9fd5, 0x009e, 0x0005, 0x080c, 0xd9db, 0x0db8, 0x009e,
+	0x0005, 0x2001, 0x180c, 0x200c, 0xc1d4, 0x2102, 0x0036, 0x080c,
+	0x8b40, 0x080c, 0x8c6d, 0x6014, 0x0096, 0x2048, 0x6010, 0x00b6,
+	0x2058, 0xb800, 0x00be, 0xd0bc, 0x0188, 0xa87c, 0x9084, 0x0003,
+	0x9086, 0x0002, 0x0140, 0xa8ac, 0x6330, 0x931a, 0x6332, 0xa8b0,
+	0x632c, 0x931b, 0x632e, 0x6003, 0x0002, 0x0080, 0x2019, 0x0004,
+	0x080c, 0xd781, 0x6018, 0x9005, 0x1128, 0x2001, 0x1961, 0x2004,
+	0x8003, 0x601a, 0x6017, 0x0000, 0x6003, 0x0007, 0x009e, 0x003e,
+	0x0005, 0x9182, 0x0040, 0x0002, 0xd168, 0xd168, 0xd168, 0xd168,
+	0xd168, 0xd168, 0xd168, 0xd168, 0xd16a, 0xd168, 0xd168, 0xd168,
+	0xd168, 0xd168, 0xd168, 0xd168, 0xd168, 0xd168, 0xd168, 0xd1b5,
+	0x080c, 0x0e02, 0x6014, 0x0096, 0x2048, 0xa834, 0xaa38, 0x6110,
+	0x00b6, 0x2158, 0xb900, 0x00be, 0xd1bc, 0x1190, 0x920d, 0x1518,
+	0xa87c, 0xd0fc, 0x0128, 0x2009, 0x0041, 0x009e, 0x0804, 0xd1d9,
+	0x6003, 0x0007, 0x601b, 0x0000, 0x080c, 0x8426, 0x009e, 0x0005,
+	0x6124, 0xd1f4, 0x1d58, 0x0006, 0x0046, 0xacac, 0x9422, 0xa9b0,
+	0x2200, 0x910b, 0x6030, 0x9420, 0x6432, 0x602c, 0x9109, 0x612e,
+	0x004e, 0x000e, 0x08d8, 0x6110, 0x00b6, 0x2158, 0xb900, 0x00be,
+	0xd1bc, 0x1178, 0x2009, 0x180e, 0x210c, 0xd19c, 0x0118, 0x6003,
+	0x0007, 0x0010, 0x6003, 0x0006, 0x00e9, 0x080c, 0x8428, 0x009e,
+	0x0005, 0x6003, 0x0002, 0x009e, 0x0005, 0x6024, 0xd0f4, 0x0128,
+	0x080c, 0x1583, 0x1904, 0xd16a, 0x0005, 0x6014, 0x0096, 0x2048,
+	0xa834, 0xa938, 0x009e, 0x9105, 0x1120, 0x080c, 0x1583, 0x1904,
+	0xd16a, 0x0005, 0xd2fc, 0x0140, 0x8002, 0x8000, 0x8212, 0x9291,
+	0x0000, 0x2009, 0x0009, 0x0010, 0x2009, 0x0015, 0xaa9a, 0xa896,
+	0x0005, 0x9182, 0x0040, 0x0208, 0x0062, 0x9186, 0x0013, 0x0120,
+	0x9186, 0x0014, 0x190c, 0x0e02, 0x6024, 0xd0dc, 0x090c, 0x0e02,
+	0x0005, 0xd1fd, 0xd209, 0xd215, 0xd221, 0xd1fd, 0xd1fd, 0xd1fd,
+	0xd1fd, 0xd204, 0xd1ff, 0xd1ff, 0xd1fd, 0xd1fd, 0xd1fd, 0xd1fd,
+	0xd1ff, 0xd1fd, 0xd1ff, 0xd1fd, 0xd204, 0x080c, 0x0e02, 0x6024,
+	0xd0dc, 0x090c, 0x0e02, 0x0005, 0x6014, 0x9005, 0x190c, 0x0e02,
+	0x0005, 0x6003, 0x0001, 0x6106, 0x080c, 0x85f9, 0x0126, 0x2091,
+	0x8000, 0x080c, 0x8b90, 0x012e, 0x0005, 0x6003, 0x0001, 0x6106,
+	0x080c, 0x85f9, 0x0126, 0x2091, 0x8000, 0x080c, 0x8b90, 0x012e,
+	0x0005, 0x6003, 0x0003, 0x6106, 0x2c10, 0x080c, 0x1a82, 0x0126,
+	0x2091, 0x8000, 0x080c, 0x865e, 0x080c, 0x8c6d, 0x012e, 0x0005,
+	0x0126, 0x2091, 0x8000, 0x0036, 0x0096, 0x9182, 0x0040, 0x0023,
+	0x009e, 0x003e, 0x012e, 0x0005, 0xd250, 0xd252, 0xd264, 0xd27e,
+	0xd250, 0xd250, 0xd250, 0xd250, 0xd250, 0xd250, 0xd250, 0xd250,
+	0xd250, 0xd250, 0xd250, 0xd250, 0xd250, 0xd250, 0xd250, 0xd250,
+	0x080c, 0x0e02, 0x6014, 0x2048, 0xa87c, 0xd0fc, 0x01f8, 0x909c,
+	0x0003, 0x939e, 0x0003, 0x01d0, 0x6003, 0x0001, 0x6106, 0x080c,
+	0x85f9, 0x080c, 0x8b90, 0x0470, 0x6014, 0x2048, 0xa87c, 0xd0fc,
+	0x0168, 0x909c, 0x0003, 0x939e, 0x0003, 0x0140, 0x6003, 0x0001,
+	0x6106, 0x080c, 0x85f9, 0x080c, 0x8b90, 0x00e0, 0x901e, 0x6316,
+	0x631a, 0x2019, 0x0004, 0x080c, 0xd781, 0x00a0, 0x6014, 0x2048,
+	0xa87c, 0xd0fc, 0x0d98, 0x909c, 0x0003, 0x939e, 0x0003, 0x0d70,
+	0x6003, 0x0003, 0x6106, 0x2c10, 0x080c, 0x1a82, 0x080c, 0x865e,
+	0x080c, 0x8c6d, 0x0005, 0x080c, 0x8a84, 0x6114, 0x81ff, 0x0158,
+	0x0096, 0x2148, 0x080c, 0xda80, 0x0036, 0x2019, 0x0029, 0x080c,
+	0xd781, 0x003e, 0x009e, 0x080c, 0xa007, 0x080c, 0x8b90, 0x0005,
+	0x080c, 0x8b40, 0x6114, 0x81ff, 0x0158, 0x0096, 0x2148, 0x080c,
+	0xda80, 0x0036, 0x2019, 0x0029, 0x080c, 0xd781, 0x003e, 0x009e,
+	0x080c, 0xa007, 0x080c, 0x8c6d, 0x0005, 0x9182, 0x0085, 0x0002,
+	0xd2cf, 0xd2cd, 0xd2cd, 0xd2db, 0xd2cd, 0xd2cd, 0xd2cd, 0xd2cd,
+	0xd2cd, 0xd2cd, 0xd2cd, 0xd2cd, 0xd2cd, 0x080c, 0x0e02, 0x6003,
+	0x000b, 0x6106, 0x080c, 0x85f9, 0x0126, 0x2091, 0x8000, 0x080c,
+	0x8b90, 0x012e, 0x0005, 0x0026, 0x00e6, 0x080c, 0xd9d2, 0x0118,
+	0x080c, 0x9fd5, 0x0450, 0x2071, 0x0260, 0x7224, 0x6216, 0x2001,
+	0x180e, 0x2004, 0xd0e4, 0x0150, 0x6010, 0x00b6, 0x2058, 0xbca0,
+	0x00be, 0x2c00, 0x2011, 0x014e, 0x080c, 0xa2f9, 0x7220, 0x080c,
+	0xd61c, 0x0118, 0x6007, 0x0086, 0x0040, 0x6007, 0x0087, 0x7224,
+	0x9296, 0xffff, 0x1110, 0x6007, 0x0086, 0x6003, 0x0001, 0x080c,
+	0x85f9, 0x080c, 0x8b90, 0x080c, 0x8c6d, 0x00ee, 0x002e, 0x0005,
+	0x9186, 0x0013, 0x1160, 0x6004, 0x908a, 0x0085, 0x0a0c, 0x0e02,
+	0x908a, 0x0092, 0x1a0c, 0x0e02, 0x9082, 0x0085, 0x00a2, 0x9186,
+	0x0027, 0x0130, 0x9186, 0x0014, 0x0118, 0x080c, 0xa06e, 0x0050,
+	0x2001, 0x0007, 0x080c, 0x6321, 0x080c, 0x8a84, 0x080c, 0xa007,
+	0x080c, 0x8b90, 0x0005, 0xd340, 0xd342, 0xd342, 0xd340, 0xd340,
+	0xd340, 0xd340, 0xd340, 0xd340, 0xd340, 0xd340, 0xd340, 0xd340,
+	0x080c, 0x0e02, 0x080c, 0x8a84, 0x080c, 0xa007, 0x080c, 0x8b90,
+	0x0005, 0x9182, 0x0085, 0x0a0c, 0x0e02, 0x9182, 0x0092, 0x1a0c,
+	0x0e02, 0x9182, 0x0085, 0x0002, 0xd361, 0xd361, 0xd361, 0xd363,
+	0xd361, 0xd361, 0xd361, 0xd361, 0xd361, 0xd361, 0xd361, 0xd361,
+	0xd361, 0x080c, 0x0e02, 0x0005, 0x9186, 0x0013, 0x0148, 0x9186,
+	0x0014, 0x0130, 0x9186, 0x0027, 0x0118, 0x080c, 0xa06e, 0x0030,
+	0x080c, 0x8a84, 0x080c, 0xa007, 0x080c, 0x8b90, 0x0005, 0x0036,
+	0x080c, 0xda33, 0x6043, 0x0000, 0x2019, 0x000b, 0x0031, 0x6023,
+	0x0006, 0x6003, 0x0007, 0x003e, 0x0005, 0x0126, 0x0036, 0x2091,
+	0x8000, 0x0086, 0x2c40, 0x0096, 0x904e, 0x080c, 0x994a, 0x009e,
+	0x008e, 0x1550, 0x0076, 0x2c38, 0x080c, 0x99f5, 0x007e, 0x1520,
+	0x6000, 0x9086, 0x0000, 0x0500, 0x6020, 0x9086, 0x0007, 0x01e0,
+	0x0096, 0x601c, 0xd084, 0x0140, 0x080c, 0xda33, 0x080c, 0xc45c,
+	0x080c, 0x1938, 0x6023, 0x0007, 0x6014, 0x2048, 0x080c, 0xbd3b,
+	0x0110, 0x080c, 0xd781, 0x009e, 0x6017, 0x0000, 0x080c, 0xda33,
+	0x6023, 0x0007, 0x080c, 0xc45c, 0x003e, 0x012e, 0x0005, 0x00f6,
+	0x00c6, 0x00b6, 0x0036, 0x0156, 0x2079, 0x0260, 0x7938, 0x783c,
+	0x080c, 0x266e, 0x15c8, 0x0016, 0x00c6, 0x080c, 0x63a4, 0x1590,
+	0x001e, 0x00c6, 0x2160, 0x080c, 0xc459, 0x00ce, 0x002e, 0x0026,
+	0x0016, 0x2019, 0x0029, 0x080c, 0x9abb, 0x080c, 0x8783, 0x0076,
+	0x903e, 0x080c, 0x8671, 0x007e, 0x001e, 0x0076, 0x903e, 0x080c,
+	0xd53b, 0x007e, 0x0026, 0xba04, 0x9294, 0xff00, 0x8217, 0x9286,
+	0x0006, 0x0118, 0x9286, 0x0004, 0x1118, 0xbaa0, 0x080c, 0x3168,
+	0x002e, 0xbcb0, 0x001e, 0x080c, 0x5e4a, 0xbe12, 0xbd16, 0xbcb2,
+	0x9006, 0x0010, 0x00ce, 0x001e, 0x015e, 0x003e, 0x00be, 0x00ce,
+	0x00fe, 0x0005, 0x00c6, 0x00d6, 0x00b6, 0x0016, 0x2009, 0x1823,
+	0x2104, 0x9086, 0x0074, 0x1904, 0xd463, 0x2069, 0x0260, 0x6944,
+	0x9182, 0x0100, 0x06e0, 0x6940, 0x9184, 0x8000, 0x0904, 0xd460,
+	0x2001, 0x1956, 0x2004, 0x9005, 0x1140, 0x6010, 0x2058, 0xb8b0,
+	0x9005, 0x0118, 0x9184, 0x0800, 0x0598, 0x6948, 0x918a, 0x0001,
+	0x0648, 0x080c, 0xdae8, 0x0118, 0x6978, 0xd1fc, 0x11b8, 0x2009,
+	0x0205, 0x200b, 0x0001, 0x693c, 0x81ff, 0x1198, 0x6944, 0x9182,
+	0x0100, 0x02a8, 0x6940, 0x81ff, 0x1178, 0x6948, 0x918a, 0x0001,
+	0x0288, 0x6950, 0x918a, 0x0001, 0x0298, 0x00d0, 0x6017, 0x0100,
+	0x00a0, 0x6017, 0x0300, 0x0088, 0x6017, 0x0500, 0x0070, 0x6017,
+	0x0700, 0x0058, 0x6017, 0x0900, 0x0040, 0x6017, 0x0b00, 0x0028,
+	0x6017, 0x0f00, 0x0010, 0x6017, 0x2d00, 0x9085, 0x0001, 0x0008,
+	0x9006, 0x001e, 0x00be, 0x00de, 0x00ce, 0x0005, 0x00c6, 0x00b6,
+	0x0026, 0x0036, 0x0156, 0x6210, 0x2258, 0xbb04, 0x9394, 0x00ff,
+	0x9286, 0x0006, 0x0180, 0x9286, 0x0004, 0x0168, 0x9394, 0xff00,
+	0x8217, 0x9286, 0x0006, 0x0138, 0x9286, 0x0004, 0x0120, 0x080c,
+	0x63b3, 0x0804, 0xd4ca, 0x2011, 0x0276, 0x20a9, 0x0004, 0x0096,
+	0x2b48, 0x2019, 0x000a, 0x080c, 0xb00b, 0x009e, 0x15a0, 0x2011,
+	0x027a, 0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019, 0x0006, 0x080c,
+	0xb00b, 0x009e, 0x1540, 0x0046, 0x0016, 0xbaa0, 0x2220, 0x9006,
+	0x2009, 0x185c, 0x210c, 0x0038, 0x2009, 0x0029, 0x080c, 0xd7d6,
+	0xb800, 0xc0e5, 0xb802, 0x2019, 0x0029, 0x080c, 0x8783, 0x0076,
+	0x2039, 0x0000, 0x080c, 0x8671, 0x2c08, 0x080c, 0xd53b, 0x007e,
+	0x2001, 0x0007, 0x080c, 0x6321, 0x2001, 0x0007, 0x080c, 0x62f5,
+	0x001e, 0x004e, 0x9006, 0x015e, 0x003e, 0x002e, 0x00be, 0x00ce,
+	0x0005, 0x00d6, 0x2069, 0x026e, 0x6800, 0x9086, 0x0800, 0x0118,
+	0x6017, 0x0000, 0x0008, 0x9006, 0x00de, 0x0005, 0x00b6, 0x00f6,
+	0x0016, 0x0026, 0x0036, 0x0156, 0x2079, 0x026c, 0x7930, 0x7834,
+	0x080c, 0x266e, 0x11d0, 0x080c, 0x63a4, 0x11b8, 0x2011, 0x0270,
+	0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019, 0x000a, 0x080c, 0xb00b,
+	0x009e, 0x1158, 0x2011, 0x0274, 0x20a9, 0x0004, 0x0096, 0x2b48,
+	0x2019, 0x0006, 0x080c, 0xb00b, 0x009e, 0x015e, 0x003e, 0x002e,
+	0x001e, 0x00fe, 0x00be, 0x0005, 0x00b6, 0x0006, 0x0016, 0x0026,
+	0x0036, 0x0156, 0x2011, 0x0263, 0x2204, 0x8211, 0x220c, 0x080c,
+	0x266e, 0x11d0, 0x080c, 0x63a4, 0x11b8, 0x2011, 0x0276, 0x20a9,
+	0x0004, 0x0096, 0x2b48, 0x2019, 0x000a, 0x080c, 0xb00b, 0x009e,
+	0x1158, 0x2011, 0x027a, 0x20a9, 0x0004, 0x0096, 0x2b48, 0x2019,
+	0x0006, 0x080c, 0xb00b, 0x009e, 0x015e, 0x003e, 0x002e, 0x001e,
+	0x000e, 0x00be, 0x0005, 0x00e6, 0x00c6, 0x0086, 0x0076, 0x0066,
+	0x0056, 0x0046, 0x0026, 0x0126, 0x2091, 0x8000, 0x2740, 0x2029,
+	0x19cb, 0x252c, 0x2021, 0x19d1, 0x2424, 0x2061, 0x1cd0, 0x2071,
+	0x1800, 0x7650, 0x7070, 0x81ff, 0x0150, 0x0006, 0x9186, 0x1a88,
+	0x000e, 0x0128, 0x8001, 0x9602, 0x1a04, 0xd5d5, 0x0018, 0x9606,
+	0x0904, 0xd5d5, 0x2100, 0x9c06, 0x0904, 0xd5cc, 0x6720, 0x9786,
+	0x0007, 0x0904, 0xd5cc, 0x080c, 0xd817, 0x1904, 0xd5cc, 0x080c,
+	0xdb06, 0x0904, 0xd5cc, 0x080c, 0xd807, 0x0904, 0xd5cc, 0x6720,
+	0x9786, 0x0001, 0x1148, 0x080c, 0x31ff, 0x0904, 0xd5f0, 0x6004,
+	0x9086, 0x0000, 0x1904, 0xd5f0, 0x9786, 0x0004, 0x0904, 0xd5f0,
+	0x2500, 0x9c06, 0x0904, 0xd5cc, 0x2400, 0x9c06, 0x05e8, 0x88ff,
+	0x0118, 0x6054, 0x9906, 0x15c0, 0x0096, 0x6000, 0x9086, 0x0004,
+	0x1120, 0x0016, 0x080c, 0x1938, 0x001e, 0x9786, 0x000a, 0x0148,
+	0x080c, 0xbf43, 0x1130, 0x080c, 0xa995, 0x009e, 0x080c, 0xa007,
+	0x0418, 0x6014, 0x2048, 0x080c, 0xbd3b, 0x01d8, 0x9786, 0x0003,
+	0x1570, 0xa867, 0x0103, 0xa87c, 0xd0cc, 0x0130, 0x0096, 0xa878,
+	0x2048, 0x080c, 0x0ff5, 0x009e, 0xab7a, 0xa877, 0x0000, 0x080c,
+	0xda80, 0x0016, 0x080c, 0xc031, 0x080c, 0x6a16, 0x001e, 0x080c,
+	0xbf26, 0x009e, 0x080c, 0xa007, 0x9ce0, 0x0018, 0x2001, 0x1819,
+	0x2004, 0x9c02, 0x1210, 0x0804, 0xd54f, 0x012e, 0x002e, 0x004e,
+	0x005e, 0x006e, 0x007e, 0x008e, 0x00ce, 0x00ee, 0x0005, 0x9786,
+	0x0006, 0x1150, 0x9386, 0x0005, 0x0128, 0x080c, 0xda80, 0x080c,
+	0xd781, 0x08f8, 0x009e, 0x0c00, 0x9786, 0x000a, 0x0968, 0x0808,
+	0x81ff, 0x09d0, 0x9180, 0x0001, 0x2004, 0x9086, 0x0018, 0x0130,
+	0x9180, 0x0001, 0x2004, 0x9086, 0x002d, 0x1970, 0x6000, 0x9086,
+	0x0002, 0x1950, 0x080c, 0xbf32, 0x0130, 0x080c, 0xbf43, 0x1920,
+	0x080c, 0xa995, 0x0038, 0x080c, 0x30d4, 0x080c, 0xbf43, 0x1110,
+	0x080c, 0xa995, 0x080c, 0xa007, 0x0804, 0xd5cc, 0xa864, 0x9084,
+	0x00ff, 0x9086, 0x0039, 0x0005, 0x00c6, 0x00e6, 0x0016, 0x2c08,
+	0x2170, 0x9006, 0x080c, 0xd7a8, 0x001e, 0x0120, 0x6020, 0x9084,
+	0x000f, 0x001b, 0x00ee, 0x00ce, 0x0005, 0xd63b, 0xd63b, 0xd63b,
+	0xd63b, 0xd63b, 0xd63b, 0xd63d, 0xd63b, 0xd63b, 0xd63b, 0xd63b,
+	0xa007, 0xa007, 0xd63b, 0x9006, 0x0005, 0x0036, 0x0046, 0x0016,
+	0x7010, 0x00b6, 0x2058, 0xbca0, 0x00be, 0x2c00, 0x2009, 0x0020,
+	0x080c, 0xd7d6, 0x001e, 0x004e, 0x2019, 0x0002, 0x080c, 0xd385,
+	0x003e, 0x9085, 0x0001, 0x0005, 0x0096, 0x080c, 0xbd3b, 0x0140,
+	0x6014, 0x904d, 0x080c, 0xb974, 0x687b, 0x0005, 0x080c, 0x6a23,
+	0x009e, 0x080c, 0xa007, 0x9085, 0x0001, 0x0005, 0x2001, 0x0001,
+	0x080c, 0x62e1, 0x0156, 0x0016, 0x0026, 0x0036, 0x20a9, 0x0004,
+	0x2019, 0x1805, 0x2011, 0x0276, 0x080c, 0xaff7, 0x003e, 0x002e,
+	0x001e, 0x015e, 0x9005, 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x0086,
+	0x0076, 0x0066, 0x00b6, 0x0126, 0x2091, 0x8000, 0x2740, 0x2061,
+	0x1cd0, 0x2079, 0x0001, 0x8fff, 0x0904, 0xd6d8, 0x2071, 0x1800,
+	0x7650, 0x7070, 0x8001, 0x9602, 0x1a04, 0xd6d8, 0x88ff, 0x0120,
+	0x2800, 0x9c06, 0x15a0, 0x2078, 0x080c, 0xd807, 0x0580, 0x2400,
+	0x9c06, 0x0568, 0x6720, 0x9786, 0x0006, 0x1548, 0x9786, 0x0007,
+	0x0530, 0x88ff, 0x1150, 0xd58c, 0x1118, 0x6010, 0x9b06, 0x11f8,
+	0xd584, 0x0118, 0x6054, 0x9106, 0x11d0, 0x0096, 0x601c, 0xd084,
+	0x0140, 0x080c, 0xda33, 0x080c, 0xc45c, 0x080c, 0x1938, 0x6023,
+	0x0007, 0x6014, 0x2048, 0x080c, 0xbd3b, 0x0120, 0x0046, 0x080c,
+	0xd781, 0x004e, 0x009e, 0x080c, 0xa007, 0x88ff, 0x1198, 0x9ce0,
+	0x0018, 0x2001, 0x1819, 0x2004, 0x9c02, 0x1210, 0x0804, 0xd68b,
 	0x9006, 0x012e, 0x00be, 0x006e, 0x007e, 0x008e, 0x00ce, 0x00ee,
 	0x00fe, 0x0005, 0x98c5, 0x0001, 0x0ca0, 0x00b6, 0x0076, 0x0056,
 	0x0086, 0x9046, 0x2029, 0x0001, 0x2c20, 0x2019, 0x0002, 0x6210,
-	0x2258, 0x0096, 0x904e, 0x080c, 0x9a58, 0x009e, 0x008e, 0x903e,
-	0x080c, 0x9b03, 0x080c, 0xd736, 0x005e, 0x007e, 0x00be, 0x0005,
+	0x2258, 0x0096, 0x904e, 0x080c, 0x994a, 0x009e, 0x008e, 0x903e,
+	0x080c, 0x99f5, 0x080c, 0xd67c, 0x005e, 0x007e, 0x00be, 0x0005,
 	0x00b6, 0x0046, 0x0056, 0x0076, 0x00c6, 0x0156, 0x2c20, 0x2128,
-	0x20a9, 0x007f, 0x900e, 0x0016, 0x0036, 0x080c, 0x649f, 0x1190,
+	0x20a9, 0x007f, 0x900e, 0x0016, 0x0036, 0x080c, 0x63a4, 0x1180,
 	0x0056, 0x0086, 0x9046, 0x2508, 0x2029, 0x0001, 0x0096, 0x904e,
-	0x080c, 0x9a58, 0x009e, 0x008e, 0x903e, 0x080c, 0x9b03, 0x080c,
-	0xd736, 0x005e, 0x003e, 0x001e, 0x8108, 0x1f04, 0xd7c3, 0x015e,
-	0x00ce, 0x007e, 0x005e, 0x004e, 0x00be, 0x0005, 0x00b6, 0x0076,
-	0x0056, 0x6210, 0x2258, 0x0086, 0x9046, 0x2029, 0x0001, 0x2019,
-	0x0048, 0x0096, 0x904e, 0x080c, 0x9a58, 0x009e, 0x008e, 0x903e,
-	0x080c, 0x9b03, 0x2c20, 0x080c, 0xd736, 0x005e, 0x007e, 0x00be,
-	0x0005, 0x00b6, 0x0046, 0x0056, 0x0076, 0x00c6, 0x0156, 0x2c20,
-	0x20a9, 0x0800, 0x900e, 0x0016, 0x0036, 0x080c, 0x649f, 0x11a0,
-	0x0086, 0x9046, 0x2828, 0x0046, 0x2021, 0x0001, 0x080c, 0xdac6,
-	0x004e, 0x0096, 0x904e, 0x080c, 0x9a58, 0x009e, 0x008e, 0x903e,
-	0x080c, 0x9b03, 0x080c, 0xd736, 0x003e, 0x001e, 0x8108, 0x1f04,
-	0xd80b, 0x015e, 0x00ce, 0x007e, 0x005e, 0x004e, 0x00be, 0x0005,
-	0x0016, 0x00f6, 0x080c, 0xbe35, 0x0198, 0xa864, 0x9084, 0x00ff,
-	0x9086, 0x0046, 0x0180, 0xa800, 0x907d, 0x0138, 0xa803, 0x0000,
-	0xab82, 0x080c, 0x6ae9, 0x2f48, 0x0cb0, 0xab82, 0x080c, 0x6ae9,
-	0x00fe, 0x001e, 0x0005, 0xa800, 0x907d, 0x0130, 0xa803, 0x0000,
-	0x080c, 0x6ae9, 0x2f48, 0x0cb8, 0x080c, 0x6ae9, 0x0c88, 0x00e6,
-	0x0046, 0x0036, 0x2061, 0x1cd0, 0x9005, 0x1138, 0x2071, 0x1800,
+	0x080c, 0x994a, 0x009e, 0x008e, 0x903e, 0x080c, 0x99f5, 0x005e,
+	0x003e, 0x001e, 0x8108, 0x1f04, 0xd70b, 0x0036, 0x2508, 0x2029,
+	0x0003, 0x080c, 0xd67c, 0x003e, 0x015e, 0x00ce, 0x007e, 0x005e,
+	0x004e, 0x00be, 0x0005, 0x00b6, 0x0076, 0x0056, 0x6210, 0x2258,
+	0x0086, 0x9046, 0x2029, 0x0001, 0x2019, 0x0048, 0x0096, 0x904e,
+	0x080c, 0x994a, 0x009e, 0x008e, 0x903e, 0x080c, 0x99f5, 0x2c20,
+	0x080c, 0xd67c, 0x005e, 0x007e, 0x00be, 0x0005, 0x00b6, 0x0046,
+	0x0056, 0x0076, 0x00c6, 0x0156, 0x2c20, 0x20a9, 0x0800, 0x900e,
+	0x0016, 0x0036, 0x080c, 0x63a4, 0x1190, 0x0086, 0x9046, 0x2828,
+	0x0046, 0x2021, 0x0001, 0x080c, 0xda17, 0x004e, 0x0096, 0x904e,
+	0x080c, 0x994a, 0x009e, 0x008e, 0x903e, 0x080c, 0x99f5, 0x003e,
+	0x001e, 0x8108, 0x1f04, 0xd758, 0x0036, 0x2029, 0x0002, 0x080c,
+	0xd67c, 0x003e, 0x015e, 0x00ce, 0x007e, 0x005e, 0x004e, 0x00be,
+	0x0005, 0x0016, 0x00f6, 0x080c, 0xbd39, 0x0198, 0xa864, 0x9084,
+	0x00ff, 0x9086, 0x0046, 0x0180, 0xa800, 0x907d, 0x0138, 0xa803,
+	0x0000, 0xab82, 0x080c, 0x6a23, 0x2f48, 0x0cb0, 0xab82, 0x080c,
+	0x6a23, 0x00fe, 0x001e, 0x0005, 0xa800, 0x907d, 0x0130, 0xa803,
+	0x0000, 0x080c, 0x6a23, 0x2f48, 0x0cb8, 0x080c, 0x6a23, 0x0c88,
+	0x00e6, 0x0046, 0x0036, 0x2061, 0x1cd0, 0x9005, 0x1138, 0x2071,
+	0x1800, 0x7450, 0x7070, 0x8001, 0x9402, 0x12d8, 0x2100, 0x9c06,
+	0x0168, 0x6000, 0x9086, 0x0000, 0x0148, 0x6008, 0x9206, 0x1130,
+	0x6010, 0x91a0, 0x0004, 0x2424, 0x9406, 0x0140, 0x9ce0, 0x0018,
+	0x2001, 0x1819, 0x2004, 0x9c02, 0x1220, 0x0c40, 0x9085, 0x0001,
+	0x0008, 0x9006, 0x003e, 0x004e, 0x00ee, 0x0005, 0x0096, 0x0006,
+	0x080c, 0x1043, 0x000e, 0x090c, 0x0e02, 0xaae2, 0xa867, 0x010d,
+	0xa88e, 0x0026, 0x2010, 0x080c, 0xbd29, 0x2001, 0x0000, 0x0120,
+	0x2200, 0x9080, 0x0015, 0x2004, 0x002e, 0xa87a, 0x9186, 0x0020,
+	0x0110, 0xa8e3, 0xffff, 0xa986, 0xac76, 0xa87f, 0x0000, 0x2001,
+	0x1968, 0x2004, 0xa882, 0x9006, 0xa802, 0xa86a, 0xa88a, 0x0126,
+	0x2091, 0x8000, 0x080c, 0x6a23, 0x012e, 0x009e, 0x0005, 0x6700,
+	0x9786, 0x0000, 0x0158, 0x9786, 0x0001, 0x0140, 0x9786, 0x000a,
+	0x0128, 0x9786, 0x0009, 0x0110, 0x9085, 0x0001, 0x0005, 0x00e6,
+	0x6010, 0x9075, 0x0138, 0x00b6, 0x2058, 0xb8a0, 0x00be, 0x9206,
+	0x00ee, 0x0005, 0x9085, 0x0001, 0x0cd8, 0x0016, 0x6004, 0x908e,
+	0x001e, 0x11a0, 0x8007, 0x6134, 0x918c, 0x00ff, 0x9105, 0x6036,
+	0x6007, 0x0085, 0x6003, 0x000b, 0x6023, 0x0005, 0x2001, 0x1961,
+	0x2004, 0x601a, 0x080c, 0x85f9, 0x080c, 0x8b90, 0x001e, 0x0005,
+	0xa001, 0xa001, 0x0005, 0x6024, 0xd0e4, 0x0158, 0xd0cc, 0x0118,
+	0x080c, 0xc075, 0x0030, 0x080c, 0xda33, 0x080c, 0x8426, 0x080c,
+	0x9fd5, 0x0005, 0x9280, 0x0008, 0x2004, 0x9084, 0x000f, 0x0002,
+	0xd866, 0xd866, 0xd866, 0xd868, 0xd866, 0xd868, 0xd868, 0xd866,
+	0xd868, 0xd866, 0xd866, 0xd866, 0xd866, 0xd866, 0x9006, 0x0005,
+	0x9085, 0x0001, 0x0005, 0x9280, 0x0008, 0x2004, 0x9084, 0x000f,
+	0x0002, 0xd87f, 0xd87f, 0xd87f, 0xd87f, 0xd87f, 0xd87f, 0xd88c,
+	0xd87f, 0xd87f, 0xd87f, 0xd87f, 0xd87f, 0xd87f, 0xd87f, 0x6007,
+	0x003b, 0x602f, 0x0009, 0x6017, 0x2a00, 0x6003, 0x0001, 0x080c,
+	0x85f9, 0x080c, 0x8b90, 0x0005, 0x0096, 0x00c6, 0x2260, 0x080c,
+	0xda33, 0x6043, 0x0000, 0x6024, 0xc0f4, 0xc0e4, 0x6026, 0x603b,
+	0x0000, 0x00ce, 0x00d6, 0x2268, 0x9186, 0x0007, 0x1904, 0xd8e5,
+	0x6814, 0x9005, 0x0138, 0x2048, 0xa87c, 0xd0fc, 0x1118, 0x00de,
+	0x009e, 0x08a8, 0x6007, 0x003a, 0x6003, 0x0001, 0x080c, 0x85f9,
+	0x080c, 0x8b90, 0x00c6, 0x2d60, 0x6100, 0x9186, 0x0002, 0x1904,
+	0xd95c, 0x6014, 0x9005, 0x1138, 0x6000, 0x9086, 0x0007, 0x190c,
+	0x0e02, 0x0804, 0xd95c, 0x2048, 0x080c, 0xbd3b, 0x1130, 0x0028,
+	0x2048, 0xa800, 0x9005, 0x1de0, 0x2900, 0x2048, 0xa87c, 0x9084,
+	0x0003, 0x9086, 0x0002, 0x1168, 0xa87c, 0xc0dc, 0xc0f4, 0xa87e,
+	0xa880, 0xc0fc, 0xa882, 0x2009, 0x0043, 0x080c, 0xd1d9, 0x0804,
+	0xd95c, 0x2009, 0x0041, 0x0804, 0xd956, 0x9186, 0x0005, 0x15a0,
+	0x6814, 0x2048, 0xa87c, 0xd0bc, 0x1120, 0x00de, 0x009e, 0x0804,
+	0xd87f, 0xd0b4, 0x0128, 0xd0fc, 0x090c, 0x0e02, 0x0804, 0xd8a0,
+	0x6007, 0x003a, 0x6003, 0x0001, 0x080c, 0x85f9, 0x080c, 0x8b90,
+	0x00c6, 0x2d60, 0x6100, 0x9186, 0x0002, 0x0120, 0x9186, 0x0004,
+	0x1904, 0xd95c, 0x6814, 0x2048, 0xa97c, 0xc1f4, 0xc1dc, 0xa97e,
+	0xa980, 0xc1fc, 0xc1bc, 0xa982, 0x00f6, 0x2c78, 0x080c, 0x165d,
+	0x00fe, 0x2009, 0x0042, 0x04d0, 0x0036, 0x080c, 0x1043, 0x090c,
+	0x0e02, 0xa867, 0x010d, 0x9006, 0xa802, 0xa86a, 0xa88a, 0x2d18,
+	0xab8e, 0xa887, 0x0045, 0x2c00, 0xa892, 0x6038, 0xa8a2, 0x2360,
+	0x6024, 0xc0dd, 0x6026, 0x6010, 0x00b6, 0x2058, 0xb8a0, 0x00be,
+	0x2004, 0x6354, 0xab7a, 0xa876, 0x9006, 0xa87e, 0xa882, 0xad9a,
+	0xae96, 0xa89f, 0x0001, 0x080c, 0x6a23, 0x2019, 0x0045, 0x6008,
+	0x2068, 0x080c, 0xd385, 0x2d00, 0x600a, 0x6023, 0x0006, 0x6003,
+	0x0007, 0x901e, 0x631a, 0x6342, 0x003e, 0x0038, 0x6043, 0x0000,
+	0x6003, 0x0007, 0x080c, 0xd1d9, 0x00ce, 0x00de, 0x009e, 0x0005,
+	0x9186, 0x0013, 0x1128, 0x6004, 0x9082, 0x0085, 0x2008, 0x00c2,
+	0x9186, 0x0027, 0x1178, 0x080c, 0x8a84, 0x0036, 0x0096, 0x6014,
+	0x2048, 0x2019, 0x0004, 0x080c, 0xd781, 0x009e, 0x003e, 0x080c,
+	0x8b90, 0x0005, 0x9186, 0x0014, 0x0d70, 0x080c, 0xa06e, 0x0005,
+	0xd98f, 0xd98d, 0xd98d, 0xd98d, 0xd98d, 0xd98d, 0xd98f, 0xd98d,
+	0xd98d, 0xd98d, 0xd98d, 0xd98d, 0xd98d, 0x080c, 0x0e02, 0x080c,
+	0x8a84, 0x6003, 0x000c, 0x080c, 0x8b90, 0x0005, 0x9182, 0x0092,
+	0x1220, 0x9182, 0x0085, 0x0208, 0x001a, 0x080c, 0xa06e, 0x0005,
+	0xd9ad, 0xd9ad, 0xd9ad, 0xd9ad, 0xd9af, 0xd9cf, 0xd9ad, 0xd9ad,
+	0xd9ad, 0xd9ad, 0xd9ad, 0xd9ad, 0xd9ad, 0x080c, 0x0e02, 0x00d6,
+	0x2c68, 0x080c, 0x9f7f, 0x01b0, 0x6003, 0x0001, 0x6007, 0x001e,
+	0x2009, 0x026e, 0x210c, 0x613a, 0x2009, 0x026f, 0x210c, 0x613e,
+	0x600b, 0xffff, 0x6910, 0x6112, 0x6023, 0x0004, 0x080c, 0x85f9,
+	0x080c, 0x8b90, 0x2d60, 0x080c, 0x9fd5, 0x00de, 0x0005, 0x080c,
+	0x9fd5, 0x0005, 0x00e6, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be,
+	0xd0ec, 0x00ee, 0x0005, 0x2009, 0x187b, 0x210c, 0xd1ec, 0x05b0,
+	0x6003, 0x0002, 0x6024, 0xc0e5, 0x6026, 0xd0cc, 0x0150, 0x2001,
+	0x1962, 0x2004, 0x6042, 0x2009, 0x187b, 0x210c, 0xd1f4, 0x1520,
+	0x00a0, 0x2009, 0x187b, 0x210c, 0xd1f4, 0x0128, 0x6024, 0xc0e4,
+	0x6026, 0x9006, 0x00d8, 0x2001, 0x1962, 0x200c, 0x2001, 0x1960,
+	0x2004, 0x9100, 0x9080, 0x000a, 0x6042, 0x6010, 0x00b6, 0x2058,
+	0xb8ac, 0x00be, 0x0008, 0x2104, 0x9005, 0x0118, 0x9088, 0x0003,
+	0x0cd0, 0x2c0a, 0x600f, 0x0000, 0x9085, 0x0001, 0x0005, 0x0016,
+	0x00c6, 0x00e6, 0x6154, 0xb8ac, 0x2060, 0x8cff, 0x0180, 0x84ff,
+	0x1118, 0x6054, 0x9106, 0x1138, 0x600c, 0x2072, 0x080c, 0x8426,
+	0x080c, 0x9fd5, 0x0010, 0x9cf0, 0x0003, 0x2e64, 0x0c70, 0x00ee,
+	0x00ce, 0x001e, 0x0005, 0x00d6, 0x00b6, 0x6010, 0x2058, 0xb8ac,
+	0x906d, 0x0130, 0x9c06, 0x0110, 0x680c, 0x0cd0, 0x600c, 0x680e,
+	0x00be, 0x00de, 0x0005, 0x0026, 0x0036, 0x0156, 0x2011, 0x182b,
+	0x2204, 0x9084, 0x00ff, 0x2019, 0x026e, 0x2334, 0x96b4, 0x00ff,
+	0x9636, 0x1508, 0x8318, 0x2334, 0x2204, 0x9084, 0xff00, 0x9636,
+	0x11d0, 0x2011, 0x0270, 0x20a9, 0x0004, 0x6010, 0x0096, 0x2048,
+	0x2019, 0x000a, 0x080c, 0xb00b, 0x009e, 0x1168, 0x2011, 0x0274,
+	0x20a9, 0x0004, 0x6010, 0x0096, 0x2048, 0x2019, 0x0006, 0x080c,
+	0xb00b, 0x009e, 0x1100, 0x015e, 0x003e, 0x002e, 0x0005, 0x00e6,
+	0x2071, 0x1800, 0x080c, 0x5dc3, 0x080c, 0x2e8c, 0x00ee, 0x0005,
+	0x00e6, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0fc, 0x0108,
+	0x0011, 0x00ee, 0x0005, 0xa880, 0xc0e5, 0xa882, 0x0005, 0x00e6,
+	0x00d6, 0x00c6, 0x0076, 0x0066, 0x0056, 0x0046, 0x0026, 0x0016,
+	0x0126, 0x2091, 0x8000, 0x2029, 0x19cb, 0x252c, 0x2021, 0x19d1,
+	0x2424, 0x2061, 0x1cd0, 0x2071, 0x1800, 0x7650, 0x7070, 0x9606,
+	0x0578, 0x6720, 0x9786, 0x0001, 0x0118, 0x9786, 0x0008, 0x1500,
+	0x2500, 0x9c06, 0x01e8, 0x2400, 0x9c06, 0x01d0, 0x080c, 0xd807,
+	0x01b8, 0x080c, 0xd817, 0x11a0, 0x6000, 0x9086, 0x0004, 0x1120,
+	0x0016, 0x080c, 0x1938, 0x001e, 0x080c, 0xbf32, 0x1110, 0x080c,
+	0x30d4, 0x080c, 0xbf43, 0x1110, 0x080c, 0xa995, 0x080c, 0xa007,
+	0x9ce0, 0x0018, 0x2001, 0x1819, 0x2004, 0x9c02, 0x1208, 0x0858,
+	0x012e, 0x001e, 0x002e, 0x004e, 0x005e, 0x006e, 0x007e, 0x00ce,
+	0x00de, 0x00ee, 0x0005, 0x2001, 0x1810, 0x2004, 0xd0dc, 0x0005,
+	0x0006, 0x2001, 0x1836, 0x2004, 0xd09c, 0x000e, 0x0005, 0x0006,
+	0x0036, 0x0046, 0x080c, 0xc444, 0x0168, 0x2019, 0xffff, 0x9005,
+	0x0128, 0x6010, 0x00b6, 0x2058, 0xbba0, 0x00be, 0x2021, 0x0004,
+	0x080c, 0x4bb5, 0x004e, 0x003e, 0x000e, 0x0005, 0x6004, 0x9086,
+	0x0001, 0x1128, 0x080c, 0x9abb, 0x080c, 0xa007, 0x9006, 0x0005,
+	0x00e6, 0x00c6, 0x00b6, 0x0046, 0x2061, 0x1cd0, 0x2071, 0x1800,
 	0x7450, 0x7070, 0x8001, 0x9402, 0x12d8, 0x2100, 0x9c06, 0x0168,
-	0x6000, 0x9086, 0x0000, 0x0148, 0x6008, 0x9206, 0x1130, 0x6010,
-	0x91a0, 0x0004, 0x2424, 0x9406, 0x0140, 0x9ce0, 0x0018, 0x2001,
+	0x6000, 0x9086, 0x0000, 0x0148, 0x6010, 0x2058, 0xb8a0, 0x9206,
+	0x1120, 0x6004, 0x9086, 0x0002, 0x0140, 0x9ce0, 0x0018, 0x2001,
 	0x1819, 0x2004, 0x9c02, 0x1220, 0x0c40, 0x9085, 0x0001, 0x0008,
-	0x9006, 0x003e, 0x004e, 0x00ee, 0x0005, 0x0096, 0x0006, 0x080c,
-	0x1031, 0x000e, 0x090c, 0x0dfa, 0xaae2, 0xa867, 0x010d, 0xa88e,
-	0x0026, 0x2010, 0x080c, 0xbe25, 0x2001, 0x0000, 0x0120, 0x2200,
-	0x9080, 0x0015, 0x2004, 0x002e, 0xa87a, 0x9186, 0x0020, 0x0110,
-	0xa8e3, 0xffff, 0xa986, 0xac76, 0xa87f, 0x0000, 0x2001, 0x1966,
-	0x2004, 0xa882, 0x9006, 0xa802, 0xa86a, 0xa88a, 0x0126, 0x2091,
-	0x8000, 0x080c, 0x6ae9, 0x012e, 0x009e, 0x0005, 0x6700, 0x9786,
-	0x0000, 0x0158, 0x9786, 0x0001, 0x0140, 0x9786, 0x000a, 0x0128,
-	0x9786, 0x0009, 0x0110, 0x9085, 0x0001, 0x0005, 0x00e6, 0x6010,
-	0x9075, 0x0138, 0x00b6, 0x2058, 0xb8a0, 0x00be, 0x9206, 0x00ee,
-	0x0005, 0x9085, 0x0001, 0x0cd8, 0x0016, 0x6004, 0x908e, 0x001e,
-	0x11a0, 0x8007, 0x6134, 0x918c, 0x00ff, 0x9105, 0x6036, 0x6007,
-	0x0085, 0x6003, 0x000b, 0x6023, 0x0005, 0x2001, 0x195f, 0x2004,
-	0x601a, 0x080c, 0x8679, 0x080c, 0x8c10, 0x001e, 0x0005, 0xa001,
-	0xa001, 0x0005, 0x6024, 0xd0e4, 0x0158, 0xd0cc, 0x0118, 0x080c,
-	0xc171, 0x0030, 0x080c, 0xdae2, 0x080c, 0x84a6, 0x080c, 0xa0e3,
-	0x0005, 0x9280, 0x0008, 0x2004, 0x9084, 0x000f, 0x0002, 0xd915,
-	0xd915, 0xd915, 0xd917, 0xd915, 0xd917, 0xd917, 0xd915, 0xd917,
-	0xd915, 0xd915, 0xd915, 0xd915, 0xd915, 0x9006, 0x0005, 0x9085,
-	0x0001, 0x0005, 0x9280, 0x0008, 0x2004, 0x9084, 0x000f, 0x0002,
-	0xd92e, 0xd92e, 0xd92e, 0xd92e, 0xd92e, 0xd92e, 0xd93b, 0xd92e,
-	0xd92e, 0xd92e, 0xd92e, 0xd92e, 0xd92e, 0xd92e, 0x6007, 0x003b,
-	0x602f, 0x0009, 0x6017, 0x2a00, 0x6003, 0x0001, 0x080c, 0x8679,
-	0x080c, 0x8c10, 0x0005, 0x0096, 0x00c6, 0x2260, 0x080c, 0xdae2,
-	0x6043, 0x0000, 0x6024, 0xc0f4, 0xc0e4, 0x6026, 0x603b, 0x0000,
-	0x00ce, 0x00d6, 0x2268, 0x9186, 0x0007, 0x1904, 0xd994, 0x6814,
-	0x9005, 0x0138, 0x2048, 0xa87c, 0xd0fc, 0x1118, 0x00de, 0x009e,
-	0x08a8, 0x6007, 0x003a, 0x6003, 0x0001, 0x080c, 0x8679, 0x080c,
-	0x8c10, 0x00c6, 0x2d60, 0x6100, 0x9186, 0x0002, 0x1904, 0xda0b,
-	0x6014, 0x9005, 0x1138, 0x6000, 0x9086, 0x0007, 0x190c, 0x0dfa,
-	0x0804, 0xda0b, 0x2048, 0x080c, 0xbe37, 0x1130, 0x0028, 0x2048,
-	0xa800, 0x9005, 0x1de0, 0x2900, 0x2048, 0xa87c, 0x9084, 0x0003,
-	0x9086, 0x0002, 0x1168, 0xa87c, 0xc0dc, 0xc0f4, 0xa87e, 0xa880,
-	0xc0fc, 0xa882, 0x2009, 0x0043, 0x080c, 0xd294, 0x0804, 0xda0b,
-	0x2009, 0x0041, 0x0804, 0xda05, 0x9186, 0x0005, 0x15a0, 0x6814,
-	0x2048, 0xa87c, 0xd0bc, 0x1120, 0x00de, 0x009e, 0x0804, 0xd92e,
-	0xd0b4, 0x0128, 0xd0fc, 0x090c, 0x0dfa, 0x0804, 0xd94f, 0x6007,
-	0x003a, 0x6003, 0x0001, 0x080c, 0x8679, 0x080c, 0x8c10, 0x00c6,
-	0x2d60, 0x6100, 0x9186, 0x0002, 0x0120, 0x9186, 0x0004, 0x1904,
-	0xda0b, 0x6814, 0x2048, 0xa97c, 0xc1f4, 0xc1dc, 0xa97e, 0xa980,
-	0xc1fc, 0xc1bc, 0xa982, 0x00f6, 0x2c78, 0x080c, 0x16db, 0x00fe,
-	0x2009, 0x0042, 0x04d0, 0x0036, 0x080c, 0x1031, 0x090c, 0x0dfa,
-	0xa867, 0x010d, 0x9006, 0xa802, 0xa86a, 0xa88a, 0x2d18, 0xab8e,
-	0xa887, 0x0045, 0x2c00, 0xa892, 0x6038, 0xa8a2, 0x2360, 0x6024,
-	0xc0dd, 0x6026, 0x6010, 0x00b6, 0x2058, 0xb8a0, 0x00be, 0x2004,
-	0x6354, 0xab7a, 0xa876, 0x9006, 0xa87e, 0xa882, 0xad9a, 0xae96,
-	0xa89f, 0x0001, 0x080c, 0x6ae9, 0x2019, 0x0045, 0x6008, 0x2068,
-	0x080c, 0xd440, 0x2d00, 0x600a, 0x6023, 0x0006, 0x6003, 0x0007,
-	0x901e, 0x631a, 0x6342, 0x003e, 0x0038, 0x6043, 0x0000, 0x6003,
-	0x0007, 0x080c, 0xd294, 0x00ce, 0x00de, 0x009e, 0x0005, 0x9186,
-	0x0013, 0x1128, 0x6004, 0x9082, 0x0085, 0x2008, 0x00c2, 0x9186,
-	0x0027, 0x1178, 0x080c, 0x8b04, 0x0036, 0x0096, 0x6014, 0x2048,
-	0x2019, 0x0004, 0x080c, 0xd830, 0x009e, 0x003e, 0x080c, 0x8c10,
-	0x0005, 0x9186, 0x0014, 0x0d70, 0x080c, 0xa178, 0x0005, 0xda3e,
-	0xda3c, 0xda3c, 0xda3c, 0xda3c, 0xda3c, 0xda3e, 0xda3c, 0xda3c,
-	0xda3c, 0xda3c, 0xda3c, 0xda3c, 0x080c, 0x0dfa, 0x080c, 0x8b04,
-	0x6003, 0x000c, 0x080c, 0x8c10, 0x0005, 0x9182, 0x0092, 0x1220,
-	0x9182, 0x0085, 0x0208, 0x001a, 0x080c, 0xa178, 0x0005, 0xda5c,
-	0xda5c, 0xda5c, 0xda5c, 0xda5e, 0xda7e, 0xda5c, 0xda5c, 0xda5c,
-	0xda5c, 0xda5c, 0xda5c, 0xda5c, 0x080c, 0x0dfa, 0x00d6, 0x2c68,
-	0x080c, 0xa08d, 0x01b0, 0x6003, 0x0001, 0x6007, 0x001e, 0x2009,
-	0x026e, 0x210c, 0x613a, 0x2009, 0x026f, 0x210c, 0x613e, 0x600b,
-	0xffff, 0x6910, 0x6112, 0x6023, 0x0004, 0x080c, 0x8679, 0x080c,
-	0x8c10, 0x2d60, 0x080c, 0xa0e3, 0x00de, 0x0005, 0x080c, 0xa0e3,
-	0x0005, 0x00e6, 0x6010, 0x00b6, 0x2058, 0xb800, 0x00be, 0xd0ec,
-	0x00ee, 0x0005, 0x2009, 0x187b, 0x210c, 0xd1ec, 0x05b0, 0x6003,
-	0x0002, 0x6024, 0xc0e5, 0x6026, 0xd0cc, 0x0150, 0x2001, 0x1960,
-	0x2004, 0x6042, 0x2009, 0x187b, 0x210c, 0xd1f4, 0x1520, 0x00a0,
-	0x2009, 0x187b, 0x210c, 0xd1f4, 0x0128, 0x6024, 0xc0e4, 0x6026,
-	0x9006, 0x00d8, 0x2001, 0x1960, 0x200c, 0x2001, 0x195e, 0x2004,
-	0x9100, 0x9080, 0x000a, 0x6042, 0x6010, 0x00b6, 0x2058, 0xb8ac,
-	0x00be, 0x0008, 0x2104, 0x9005, 0x0118, 0x9088, 0x0003, 0x0cd0,
-	0x2c0a, 0x600f, 0x0000, 0x9085, 0x0001, 0x0005, 0x0016, 0x00c6,
-	0x00e6, 0x6154, 0xb8ac, 0x2060, 0x8cff, 0x0180, 0x84ff, 0x1118,
-	0x6054, 0x9106, 0x1138, 0x600c, 0x2072, 0x080c, 0x84a6, 0x080c,
-	0xa0e3, 0x0010, 0x9cf0, 0x0003, 0x2e64, 0x0c70, 0x00ee, 0x00ce,
-	0x001e, 0x0005, 0x00d6, 0x00b6, 0x6010, 0x2058, 0xb8ac, 0x2068,
-	0x9005, 0x0130, 0x9c06, 0x0110, 0x680c, 0x0cd0, 0x600c, 0x680e,
-	0x00be, 0x00de, 0x0005, 0x0026, 0x0036, 0x0156, 0x2011, 0x182b,
-	0x2204, 0x9084, 0x00ff, 0x2019, 0x026e, 0x2334, 0x9636, 0x1508,
-	0x8318, 0x2334, 0x2204, 0x9084, 0xff00, 0x9636, 0x11d0, 0x2011,
-	0x0270, 0x20a9, 0x0004, 0x6010, 0x0096, 0x2048, 0x2019, 0x000a,
-	0x080c, 0xb0d0, 0x009e, 0x1168, 0x2011, 0x0274, 0x20a9, 0x0004,
-	0x6010, 0x0096, 0x2048, 0x2019, 0x0006, 0x080c, 0xb0d0, 0x009e,
-	0x1100, 0x015e, 0x003e, 0x002e, 0x0005, 0x00e6, 0x2071, 0x1800,
-	0x080c, 0x5ebe, 0x080c, 0x2f6c, 0x00ee, 0x0005, 0x00e6, 0x6010,
-	0x00b6, 0x2058, 0xb800, 0x00be, 0xd0fc, 0x0108, 0x0011, 0x00ee,
-	0x0005, 0xa880, 0xc0e5, 0xa882, 0x0005, 0x00e6, 0x00d6, 0x00c6,
-	0x0076, 0x0066, 0x0056, 0x0046, 0x0026, 0x0016, 0x0126, 0x2091,
-	0x8000, 0x2029, 0x19c8, 0x252c, 0x2021, 0x19ce, 0x2424, 0x2061,
-	0x1cd0, 0x2071, 0x1800, 0x7650, 0x7070, 0x9606, 0x0578, 0x6720,
-	0x9786, 0x0001, 0x0118, 0x9786, 0x0008, 0x1500, 0x2500, 0x9c06,
-	0x01e8, 0x2400, 0x9c06, 0x01d0, 0x080c, 0xd8b6, 0x01b8, 0x080c,
-	0xd8c6, 0x11a0, 0x6000, 0x9086, 0x0004, 0x1120, 0x0016, 0x080c,
-	0x19b4, 0x001e, 0x080c, 0xc02e, 0x1110, 0x080c, 0x31b4, 0x080c,
-	0xc03f, 0x1110, 0x080c, 0xaa81, 0x080c, 0xa113, 0x9ce0, 0x0018,
-	0x2001, 0x1819, 0x2004, 0x9c02, 0x1208, 0x0858, 0x012e, 0x001e,
-	0x002e, 0x004e, 0x005e, 0x006e, 0x007e, 0x00ce, 0x00de, 0x00ee,
-	0x0005, 0x2001, 0x1810, 0x2004, 0xd0dc, 0x0005, 0x0006, 0x2001,
-	0x1836, 0x2004, 0xd09c, 0x000e, 0x0005, 0x0006, 0x0036, 0x0046,
-	0x080c, 0xc539, 0x0168, 0x2019, 0xffff, 0x9005, 0x0128, 0x6010,
-	0x00b6, 0x2058, 0xbba0, 0x00be, 0x2021, 0x0004, 0x080c, 0x4cbc,
-	0x004e, 0x003e, 0x000e, 0x6004, 0x9086, 0x0001, 0x1128, 0x080c,
-	0x9bc9, 0x080c, 0xa113, 0x9006, 0x0005, 0x00e6, 0x00c6, 0x00b6,
-	0x0046, 0x2061, 0x1cd0, 0x2071, 0x1800, 0x7450, 0x7070, 0x8001,
-	0x9402, 0x12d8, 0x2100, 0x9c06, 0x0168, 0x6000, 0x9086, 0x0000,
-	0x0148, 0x6010, 0x2058, 0xb8a0, 0x9206, 0x1120, 0x6004, 0x9086,
-	0x0002, 0x0140, 0x9ce0, 0x0018, 0x2001, 0x1819, 0x2004, 0x9c02,
-	0x1220, 0x0c40, 0x9085, 0x0001, 0x0008, 0x9006, 0x004e, 0x00be,
-	0x00ce, 0x00ee, 0x0005, 0x0126, 0x0006, 0x00e6, 0x0016, 0x2091,
-	0x8000, 0x2071, 0x1840, 0xd5a4, 0x0118, 0x7054, 0x8000, 0x7056,
-	0xd5b4, 0x0118, 0x7050, 0x8000, 0x7052, 0xd5ac, 0x0178, 0x2500,
-	0x9084, 0x0007, 0x908e, 0x0003, 0x0148, 0x908e, 0x0004, 0x0130,
-	0x908e, 0x0005, 0x0118, 0x2071, 0x184a, 0x0089, 0x001e, 0x00ee,
-	0x000e, 0x012e, 0x0005, 0x0126, 0x0006, 0x00e6, 0x2091, 0x8000,
-	0x2071, 0x1842, 0x0021, 0x00ee, 0x000e, 0x012e, 0x0005, 0x2e04,
-	0x8000, 0x2072, 0x1220, 0x8e70, 0x2e04, 0x8000, 0x2072, 0x0005,
-	0x00e6, 0x2071, 0x1840, 0x0c99, 0x00ee, 0x0005, 0x00e6, 0x2071,
-	0x1844, 0x0c69, 0x00ee, 0x0005, 0x0126, 0x0006, 0x00e6, 0x2091,
-	0x8000, 0x2071, 0x1840, 0x7064, 0x8000, 0x7066, 0x00ee, 0x000e,
-	0x012e, 0x0005, 0x0003, 0x000b, 0x04a6, 0x0000, 0xc000, 0x0001,
-	0x8064, 0x0008, 0x0010, 0x0000, 0x8066, 0x0000, 0x0101, 0x0008,
-	0x4407, 0x0003, 0x8060, 0x0000, 0x0400, 0x0000, 0x580d, 0x000b,
-	0x798e, 0x0003, 0x50db, 0x000b, 0x4c0a, 0x0003, 0xbac0, 0x0009,
-	0x008a, 0x0000, 0x0c0a, 0x000b, 0x15fe, 0x0008, 0x340a, 0x0003,
-	0xc4c0, 0x0009, 0x7000, 0x0000, 0xffa0, 0x0001, 0x2000, 0x0000,
-	0x1627, 0x0003, 0x808c, 0x0008, 0x0001, 0x0000, 0x0000, 0x0007,
-	0x4047, 0x000a, 0x808c, 0x0008, 0x0002, 0x0000, 0x0821, 0x0003,
-	0x4022, 0x0000, 0x0022, 0x000b, 0x4122, 0x0008, 0x4447, 0x0002,
-	0x0e4f, 0x000b, 0x0bfe, 0x0008, 0x11a0, 0x0001, 0x122d, 0x000b,
-	0x0ca0, 0x0001, 0x122d, 0x000b, 0x9180, 0x0001, 0x0004, 0x0000,
-	0x8060, 0x0000, 0x0400, 0x0000, 0x7f62, 0x0008, 0x8066, 0x0000,
-	0x0009, 0x0008, 0x4430, 0x000b, 0x808c, 0x0008, 0x0000, 0x0008,
-	0x0060, 0x0008, 0x8062, 0x0008, 0x0004, 0x0000, 0x8066, 0x0000,
-	0x0411, 0x0000, 0x4438, 0x0003, 0x03fe, 0x0000, 0x43e0, 0x0001,
-	0x0e2a, 0x000b, 0xc2c0, 0x0009, 0x00ff, 0x0008, 0x02e0, 0x0001,
-	0x0e2a, 0x000b, 0x9180, 0x0001, 0x0005, 0x0008, 0x8060, 0x0000,
-	0x0400, 0x0000, 0x7f62, 0x0008, 0x8066, 0x0000, 0x0019, 0x0000,
-	0x4447, 0x000b, 0x0240, 0x0002, 0x0a27, 0x000b, 0x00fe, 0x0000,
-	0x322a, 0x000b, 0x112a, 0x0000, 0x002e, 0x0008, 0x022c, 0x0008,
-	0x3a44, 0x0002, 0x0c0a, 0x000b, 0x808c, 0x0008, 0x0002, 0x0000,
-	0x1760, 0x0008, 0x8062, 0x0008, 0x000f, 0x0008, 0x8066, 0x0000,
-	0x0011, 0x0008, 0x4458, 0x0003, 0x01fe, 0x0008, 0x42e0, 0x0009,
-	0x0e1d, 0x0003, 0x00fe, 0x0000, 0x43e0, 0x0001, 0x0e1d, 0x0003,
-	0x1734, 0x0000, 0x1530, 0x0000, 0x1632, 0x0008, 0x0d2a, 0x0008,
-	0x9880, 0x0001, 0x0010, 0x0000, 0x8060, 0x0000, 0x0400, 0x0000,
-	0x7f62, 0x0008, 0x8066, 0x0000, 0x1e0a, 0x0008, 0x446a, 0x000b,
-	0x808a, 0x0008, 0x0003, 0x0008, 0x1a60, 0x0000, 0x8062, 0x0008,
-	0x0002, 0x0000, 0x5870, 0x000b, 0x8066, 0x0000, 0x3679, 0x0000,
-	0x4473, 0x0003, 0x5874, 0x0003, 0x3efe, 0x0008, 0x7f4f, 0x0002,
-	0x087a, 0x000b, 0x0d00, 0x0000, 0x0082, 0x0004, 0x8054, 0x0008,
-	0x0011, 0x0008, 0x8074, 0x0000, 0x1010, 0x0008, 0x1efe, 0x0000,
-	0x300a, 0x000b, 0x00b8, 0x0004, 0x000a, 0x000b, 0x00fe, 0x0000,
-	0x348a, 0x000b, 0x1a60, 0x0000, 0x8062, 0x0008, 0x0007, 0x0000,
-	0x8066, 0x0000, 0x0231, 0x0008, 0x4489, 0x0003, 0x03fe, 0x0000,
-	0x04d0, 0x0001, 0x0cb0, 0x0003, 0x82c0, 0x0001, 0x1f00, 0x0000,
-	0xffa0, 0x0001, 0x0400, 0x0000, 0x089f, 0x0003, 0x14b0, 0x0003,
-	0x01fe, 0x0008, 0x0580, 0x0009, 0x7f06, 0x0000, 0x02fe, 0x0008,
-	0xffc0, 0x0001, 0x00ff, 0x0008, 0x0690, 0x0001, 0x109f, 0x0003,
-	0x7f08, 0x0008, 0x84c0, 0x0001, 0xff00, 0x0008, 0x08b0, 0x000b,
-	0x00fe, 0x0000, 0x34a6, 0x0003, 0x8072, 0x0000, 0x1010, 0x0008,
-	0x3944, 0x0002, 0x08a1, 0x000b, 0x00aa, 0x000b, 0x8072, 0x0000,
-	0x2020, 0x0008, 0x3945, 0x000a, 0x08a6, 0x0003, 0x3946, 0x000a,
-	0x0cb7, 0x000b, 0x0000, 0x0007, 0x3943, 0x000a, 0x08b7, 0x0003,
-	0x00aa, 0x000b, 0x00fe, 0x0000, 0x34b5, 0x000b, 0x8072, 0x0000,
-	0x1000, 0x0000, 0x00b7, 0x000b, 0x8072, 0x0000, 0x2000, 0x0000,
-	0x4000, 0x000f, 0x1c60, 0x0000, 0x1b62, 0x0000, 0x8066, 0x0000,
-	0x0231, 0x0008, 0x44bc, 0x0003, 0x58bd, 0x0003, 0x0140, 0x0008,
-	0x0242, 0x0000, 0x1f43, 0x0002, 0x0ccb, 0x0003, 0x0d44, 0x0000,
-	0x0d46, 0x0008, 0x0348, 0x0008, 0x044a, 0x0008, 0x030a, 0x0008,
-	0x040c, 0x0000, 0x0d06, 0x0000, 0x0d08, 0x0008, 0x00cf, 0x000b,
-	0x0344, 0x0008, 0x0446, 0x0008, 0x0548, 0x0008, 0x064a, 0x0000,
-	0x58cf, 0x0003, 0x3efe, 0x0008, 0x7f4f, 0x0002, 0x08d6, 0x000b,
-	0x8000, 0x0000, 0x0001, 0x0000, 0x0082, 0x0004, 0x8054, 0x0008,
-	0x0001, 0x0000, 0x8074, 0x0000, 0x2020, 0x0008, 0x4000, 0x000f,
-	0x3a40, 0x000a, 0x0c0d, 0x0003, 0x2b24, 0x0008, 0x2b24, 0x0008,
-	0x58df, 0x000b, 0x8054, 0x0008, 0x0002, 0x0000, 0x1242, 0x0002,
-	0x092d, 0x000b, 0x3a45, 0x000a, 0x091c, 0x0003, 0x8072, 0x0000,
-	0x1000, 0x0000, 0x3945, 0x000a, 0x08ec, 0x000b, 0x8072, 0x0000,
-	0x3010, 0x0000, 0x1e10, 0x000a, 0x7f3c, 0x0000, 0x0917, 0x000b,
-	0x1d00, 0x0002, 0x7f3a, 0x0000, 0x0d60, 0x0000, 0x7f62, 0x0008,
-	0x8066, 0x0000, 0x0009, 0x0008, 0x44f5, 0x000b, 0x00fe, 0x0000,
-	0x3514, 0x000b, 0x1c60, 0x0000, 0x8062, 0x0008, 0x0001, 0x0000,
-	0x8066, 0x0000, 0x0009, 0x0008, 0x44fd, 0x0003, 0x00fe, 0x0000,
-	0x3204, 0x000b, 0x0038, 0x0000, 0x0060, 0x0008, 0x8062, 0x0008,
-	0x0019, 0x0000, 0x8066, 0x0000, 0x0009, 0x0008, 0x4506, 0x0003,
-	0x80c0, 0x0009, 0x00ff, 0x0008, 0x7f3e, 0x0008, 0x0d60, 0x0000,
-	0x0efe, 0x0008, 0x1f80, 0x0001, 0x7f62, 0x0008, 0x8066, 0x0000,
-	0x0009, 0x0008, 0x4510, 0x000b, 0x003a, 0x0008, 0x1dfe, 0x0000,
-	0x00f1, 0x0003, 0x0036, 0x0008, 0x00b8, 0x0004, 0x012d, 0x0003,
-	0x8074, 0x0000, 0x2000, 0x0000, 0x8072, 0x0000, 0x2000, 0x0000,
-	0x012d, 0x0003, 0x3a44, 0x0002, 0x0a30, 0x000b, 0x8074, 0x0000,
-	0x1000, 0x0000, 0x8072, 0x0000, 0x1000, 0x0000, 0x2d0e, 0x0000,
-	0x2d0e, 0x0000, 0x3601, 0x0003, 0x26fe, 0x0008, 0x26fe, 0x0008,
-	0x2700, 0x0008, 0x2700, 0x0008, 0x00d0, 0x0009, 0x0d3f, 0x0003,
-	0x8074, 0x0000, 0x4040, 0x0008, 0x592d, 0x000b, 0x50db, 0x000b,
-	0x3a46, 0x000a, 0x0d3f, 0x0003, 0x3a47, 0x0002, 0x093a, 0x000b,
-	0x8054, 0x0008, 0x0004, 0x0000, 0x8074, 0x0000, 0x8000, 0x0000,
-	0x8072, 0x0000, 0x3000, 0x0008, 0x0182, 0x0003, 0x92c0, 0x0009,
-	0x0fc8, 0x0000, 0x080a, 0x0003, 0x1246, 0x000a, 0x0dfb, 0x000b,
-	0x1a60, 0x0000, 0x8062, 0x0008, 0x0002, 0x0000, 0x8066, 0x0000,
-	0x362a, 0x0000, 0x4544, 0x0003, 0x2000, 0x0000, 0x2000, 0x0000,
-	0x2102, 0x0000, 0x2102, 0x0000, 0x2204, 0x0000, 0x2204, 0x0000,
-	0x2306, 0x0000, 0x2306, 0x0000, 0x2408, 0x0000, 0x2408, 0x0000,
-	0x250a, 0x0000, 0x250a, 0x0000, 0x260c, 0x0000, 0x260c, 0x0000,
-	0x270e, 0x0000, 0x270e, 0x0000, 0x2810, 0x0000, 0x2810, 0x0000,
-	0x2912, 0x0000, 0x2912, 0x0000, 0x1a60, 0x0000, 0x8062, 0x0008,
-	0x0007, 0x0000, 0x8066, 0x0000, 0x0052, 0x0000, 0x455e, 0x000b,
-	0x92c0, 0x0009, 0x0780, 0x0008, 0x0e17, 0x0003, 0x124b, 0x0002,
-	0x0967, 0x0003, 0x2e4d, 0x0002, 0x2e4d, 0x0002, 0x0a01, 0x0003,
-	0x3a46, 0x000a, 0x0d74, 0x0003, 0x5969, 0x000b, 0x8054, 0x0008,
-	0x0004, 0x0000, 0x1243, 0x000a, 0x097e, 0x000b, 0x8010, 0x0008,
-	0x000d, 0x0000, 0x01ef, 0x0004, 0x1810, 0x0000, 0x01ef, 0x0004,
-	0x017e, 0x0003, 0x194d, 0x000a, 0x0978, 0x000b, 0x1243, 0x000a,
-	0x0a0b, 0x0003, 0x5978, 0x000b, 0x8054, 0x0008, 0x0004, 0x0000,
-	0x01e4, 0x000c, 0x1810, 0x0000, 0x01ef, 0x0004, 0x8074, 0x0000,
-	0xf000, 0x0008, 0x8072, 0x0000, 0x3000, 0x0008, 0x0d30, 0x0000,
-	0x3a42, 0x0002, 0x0d88, 0x0003, 0x15fe, 0x0008, 0x3451, 0x000b,
-	0x000a, 0x000b, 0x8074, 0x0000, 0x0501, 0x0000, 0x8010, 0x0008,
-	0x000c, 0x0008, 0x01ef, 0x0004, 0x000a, 0x000b, 0xbbe0, 0x0009,
-	0x0030, 0x0008, 0x0d9e, 0x000b, 0x18fe, 0x0000, 0x3ce0, 0x0009,
-	0x099b, 0x0003, 0x15fe, 0x0008, 0x3ce0, 0x0009, 0x099b, 0x0003,
-	0x01df, 0x0004, 0x8076, 0x0008, 0x0040, 0x0000, 0x01dc, 0x000b,
-	0x8076, 0x0008, 0x0041, 0x0008, 0x01dc, 0x000b, 0xbbe0, 0x0009,
-	0x0032, 0x0000, 0x0da3, 0x0003, 0x3c1e, 0x0008, 0x01dc, 0x000b,
-	0xbbe0, 0x0009, 0x0037, 0x0000, 0x0dc1, 0x000b, 0x18fe, 0x0000,
-	0x3ce0, 0x0009, 0x0d9b, 0x000b, 0x8076, 0x0008, 0x0040, 0x0000,
-	0x1a60, 0x0000, 0x8062, 0x0008, 0x000d, 0x0000, 0x2604, 0x0008,
-	0x2604, 0x0008, 0x2706, 0x0008, 0x2706, 0x0008, 0x2808, 0x0000,
-	0x2808, 0x0000, 0x290a, 0x0000, 0x290a, 0x0000, 0x8066, 0x0000,
-	0x0422, 0x0000, 0x45b8, 0x0003, 0x01e4, 0x000c, 0x8054, 0x0008,
-	0x0004, 0x0000, 0x8074, 0x0000, 0xf000, 0x0008, 0x8072, 0x0000,
-	0xb000, 0x0000, 0x0182, 0x0003, 0xbbe0, 0x0009, 0x0038, 0x0000,
-	0x0dd3, 0x000b, 0x18fe, 0x0000, 0x3ce0, 0x0009, 0x09d0, 0x0003,
-	0x15fe, 0x0008, 0x3ce0, 0x0009, 0x0d97, 0x000b, 0x01df, 0x0004,
-	0x8076, 0x0008, 0x0040, 0x0000, 0x8072, 0x0000, 0x8000, 0x0000,
-	0x0227, 0x0003, 0x8076, 0x0008, 0x0042, 0x0008, 0x01dc, 0x000b,
-	0xbbe0, 0x0009, 0x0016, 0x0000, 0x0ddc, 0x000b, 0x3a44, 0x0002,
-	0x0c0c, 0x000b, 0x8072, 0x0000, 0x8000, 0x0000, 0x8000, 0x000f,
-	0x000a, 0x000b, 0x8072, 0x0000, 0x8000, 0x0000, 0x000a, 0x000b,
-	0x3d30, 0x000a, 0x7f00, 0x0000, 0xbc80, 0x0001, 0x0007, 0x0000,
-	0x01e8, 0x0003, 0x1930, 0x000a, 0x7f00, 0x0000, 0x9880, 0x0001,
-	0x0007, 0x0000, 0x8060, 0x0000, 0x0400, 0x0000, 0x7f62, 0x0008,
-	0x8066, 0x0000, 0x000a, 0x0008, 0x45ed, 0x0003, 0x4000, 0x000f,
-	0x21ef, 0x0003, 0x0870, 0x0008, 0x4000, 0x000f, 0xbac0, 0x0009,
-	0x0090, 0x0008, 0x09f8, 0x0003, 0x8074, 0x0000, 0x0706, 0x0000,
-	0x01fa, 0x0003, 0x8074, 0x0000, 0x0703, 0x0000, 0x4000, 0x000f,
-	0x8010, 0x0008, 0x0023, 0x0000, 0x0235, 0x0003, 0x8010, 0x0008,
-	0x0008, 0x0000, 0x0235, 0x0003, 0x8010, 0x0008, 0x0022, 0x0008,
-	0x0235, 0x0003, 0x01e4, 0x000c, 0x8010, 0x0008, 0x0007, 0x0000,
-	0x01ef, 0x0004, 0x1810, 0x0000, 0x01ef, 0x0004, 0x0241, 0x0003,
-	0x01e4, 0x000c, 0x8010, 0x0008, 0x001b, 0x0008, 0x01ef, 0x0004,
-	0x1810, 0x0000, 0x01ef, 0x0004, 0x8074, 0x0000, 0xf080, 0x0000,
-	0x8072, 0x0000, 0x3000, 0x0008, 0x0d30, 0x0000, 0x000a, 0x000b,
-	0x8010, 0x0008, 0x0009, 0x0008, 0x0235, 0x0003, 0x8010, 0x0008,
-	0x0005, 0x0008, 0x0235, 0x0003, 0x808c, 0x0008, 0x0001, 0x0000,
-	0x8010, 0x0008, 0x0004, 0x0000, 0x4143, 0x000a, 0x085f, 0x0003,
-	0x3a44, 0x0002, 0x0c0a, 0x000b, 0x0d2a, 0x0008, 0x0235, 0x0003,
-	0x8010, 0x0008, 0x0003, 0x0008, 0x0239, 0x0003, 0x8010, 0x0008,
-	0x000b, 0x0000, 0x0239, 0x0003, 0x8010, 0x0008, 0x0002, 0x0000,
-	0x0239, 0x0003, 0x3a47, 0x0002, 0x0d2d, 0x0003, 0x8010, 0x0008,
-	0x0006, 0x0008, 0x0239, 0x0003, 0x8074, 0x0000, 0xf000, 0x0008,
-	0x8072, 0x0000, 0x3000, 0x0008, 0x01ef, 0x0004, 0x01f2, 0x0004,
-	0x3a40, 0x000a, 0x080a, 0x0003, 0x8010, 0x0008, 0x000c, 0x0008,
-	0x01ef, 0x0004, 0x000a, 0x000b, 0x8074, 0x0000, 0xf080, 0x0000,
-	0x8072, 0x0000, 0x3000, 0x0008, 0x0d30, 0x0000, 0x2e4d, 0x0002,
-	0x2e4d, 0x0002, 0x0a4c, 0x0003, 0x8054, 0x0008, 0x0019, 0x0000,
-	0x000a, 0x000b, 0x8054, 0x0008, 0x0009, 0x0008, 0x000a, 0x000b,
-	0x3a44, 0x0002, 0x0c0a, 0x000b, 0x022a, 0x000b, 0x15b6, 0xf4ac,
-	0x0003, 0x000b, 0x0480, 0x0000, 0xc000, 0x0001, 0x8064, 0x0008,
-	0x0010, 0x0000, 0x8066, 0x0000, 0x0101, 0x0008, 0xc007, 0x0003,
-	0x8060, 0x0000, 0x0400, 0x0000, 0x580d, 0x000b, 0x7977, 0x0003,
-	0x50db, 0x000b, 0xc80a, 0x0003, 0xbac0, 0x0009, 0x008a, 0x0000,
-	0x880a, 0x000b, 0x15fe, 0x0008, 0xb00a, 0x0003, 0xc4c0, 0x0009,
-	0x7000, 0x0000, 0xffa0, 0x0001, 0x2000, 0x0000, 0x9214, 0x0003,
-	0x808c, 0x0008, 0x0001, 0x0000, 0x0000, 0x0007, 0x4047, 0x000a,
-	0x808c, 0x0008, 0x0002, 0x0000, 0x0821, 0x0003, 0x4022, 0x0000,
-	0x0022, 0x000b, 0x4122, 0x0008, 0x4447, 0x0002, 0x8a3c, 0x0003,
-	0x0bfe, 0x0008, 0x11a0, 0x0001, 0x121a, 0x0003, 0x0ca0, 0x0001,
-	0x121a, 0x0003, 0x9180, 0x0001, 0x0004, 0x0000, 0x8060, 0x0000,
-	0x0400, 0x0000, 0x7f62, 0x0008, 0x8066, 0x0000, 0x0009, 0x0008,
-	0xc030, 0x000b, 0x808c, 0x0008, 0x0000, 0x0008, 0x0060, 0x0008,
-	0x8062, 0x0008, 0x0004, 0x0000, 0x8066, 0x0000, 0x0411, 0x0000,
-	0xc038, 0x0003, 0x03fe, 0x0000, 0x43e0, 0x0001, 0x8a17, 0x0003,
-	0xc2c0, 0x0009, 0x00ff, 0x0008, 0x02e0, 0x0001, 0x8a17, 0x0003,
-	0x9180, 0x0001, 0x0005, 0x0008, 0x8060, 0x0000, 0x0400, 0x0000,
-	0x7f62, 0x0008, 0x8066, 0x0000, 0x0019, 0x0000, 0xc047, 0x000b,
-	0x0240, 0x0002, 0x0a14, 0x000b, 0x00fe, 0x0000, 0x3217, 0x0003,
-	0x112a, 0x0000, 0x002e, 0x0008, 0x022c, 0x0008, 0x3a44, 0x0002,
-	0x880a, 0x000b, 0x808c, 0x0008, 0x0002, 0x0000, 0x1760, 0x0008,
-	0x8062, 0x0008, 0x000f, 0x0008, 0x8066, 0x0000, 0x0011, 0x0008,
-	0xc058, 0x0003, 0x01fe, 0x0008, 0x42e0, 0x0009, 0x8a0a, 0x0003,
-	0x00fe, 0x0000, 0x43e0, 0x0001, 0x8a0a, 0x0003, 0x1734, 0x0000,
-	0x1530, 0x0000, 0x1632, 0x0008, 0x0d2a, 0x0008, 0x9880, 0x0001,
-	0x0010, 0x0000, 0x8060, 0x0000, 0x0400, 0x0000, 0x7f62, 0x0008,
-	0x8066, 0x0000, 0x1e0a, 0x0008, 0xc06a, 0x000b, 0x808a, 0x0008,
-	0x0003, 0x0008, 0x1a60, 0x0000, 0x8062, 0x0008, 0x0002, 0x0000,
-	0x5870, 0x000b, 0x8066, 0x0000, 0x3679, 0x0000, 0xc073, 0x0003,
-	0x5874, 0x0003, 0x3efe, 0x0008, 0x7f4f, 0x0002, 0x087a, 0x000b,
-	0x0d00, 0x0000, 0x0082, 0x0004, 0x8054, 0x0008, 0x0011, 0x0008,
-	0x8074, 0x0000, 0x1010, 0x0008, 0x1efe, 0x0000, 0x300a, 0x000b,
-	0x00b8, 0x0004, 0x000a, 0x000b, 0x00fe, 0x0000, 0xb08a, 0x000b,
-	0x1a60, 0x0000, 0x8062, 0x0008, 0x0007, 0x0000, 0x8066, 0x0000,
-	0x0231, 0x0008, 0xc089, 0x0003, 0x03fe, 0x0000, 0x04d0, 0x0001,
-	0x88b0, 0x0003, 0x82c0, 0x0001, 0x1f00, 0x0000, 0xffa0, 0x0001,
-	0x0400, 0x0000, 0x089f, 0x0003, 0x90b0, 0x0003, 0x01fe, 0x0008,
-	0x0580, 0x0009, 0x7f06, 0x0000, 0x02fe, 0x0008, 0xffc0, 0x0001,
-	0x00ff, 0x0008, 0x0690, 0x0001, 0x109f, 0x0003, 0x7f08, 0x0008,
-	0x84c0, 0x0001, 0xff00, 0x0008, 0x08b0, 0x000b, 0x00fe, 0x0000,
-	0xb0a6, 0x0003, 0x8072, 0x0000, 0x1010, 0x0008, 0x3944, 0x0002,
-	0x08a1, 0x000b, 0x00aa, 0x000b, 0x8072, 0x0000, 0x2020, 0x0008,
-	0x3945, 0x000a, 0x08a6, 0x0003, 0x3946, 0x000a, 0x88b7, 0x000b,
-	0x0000, 0x0007, 0x3943, 0x000a, 0x08b7, 0x0003, 0x00aa, 0x000b,
-	0x00fe, 0x0000, 0xb0b5, 0x000b, 0x8072, 0x0000, 0x1000, 0x0000,
-	0x00b7, 0x000b, 0x8072, 0x0000, 0x2000, 0x0000, 0x4000, 0x000f,
-	0x1c60, 0x0000, 0x1b62, 0x0000, 0x8066, 0x0000, 0x0231, 0x0008,
-	0xc0bc, 0x0003, 0x58bd, 0x0003, 0x0140, 0x0008, 0x0242, 0x0000,
-	0x1f43, 0x0002, 0x88cb, 0x0003, 0x0d44, 0x0000, 0x0d46, 0x0008,
-	0x0348, 0x0008, 0x044a, 0x0008, 0x030a, 0x0008, 0x040c, 0x0000,
-	0x0d06, 0x0000, 0x0d08, 0x0008, 0x00cf, 0x000b, 0x0344, 0x0008,
-	0x0446, 0x0008, 0x0548, 0x0008, 0x064a, 0x0000, 0x58cf, 0x0003,
-	0x3efe, 0x0008, 0x7f4f, 0x0002, 0x08d6, 0x000b, 0x8000, 0x0000,
-	0x0001, 0x0000, 0x0082, 0x0004, 0x8054, 0x0008, 0x0001, 0x0000,
-	0x8074, 0x0000, 0x2020, 0x0008, 0x4000, 0x000f, 0x3a40, 0x000a,
-	0x880d, 0x0003, 0xabd0, 0x0001, 0x0000, 0x0008, 0x7f24, 0x0000,
-	0x58e0, 0x000b, 0x8054, 0x0008, 0x0002, 0x0000, 0x1242, 0x0002,
-	0x0930, 0x000b, 0x3a45, 0x000a, 0x091d, 0x000b, 0x8072, 0x0000,
-	0x1000, 0x0000, 0x3945, 0x000a, 0x08ed, 0x0003, 0x8072, 0x0000,
-	0x3010, 0x0000, 0x1e10, 0x000a, 0x7f3c, 0x0000, 0x0918, 0x000b,
-	0x1d00, 0x0002, 0x7f3a, 0x0000, 0x0d60, 0x0000, 0x7f62, 0x0008,
-	0x8066, 0x0000, 0x0009, 0x0008, 0xc0f6, 0x000b, 0x00fe, 0x0000,
-	0xb115, 0x0003, 0x1c60, 0x0000, 0x8062, 0x0008, 0x0001, 0x0000,
-	0x8066, 0x0000, 0x0009, 0x0008, 0xc0fe, 0x0003, 0x00fe, 0x0000,
-	0x31f1, 0x000b, 0x0038, 0x0000, 0x0060, 0x0008, 0x8062, 0x0008,
-	0x0019, 0x0000, 0x8066, 0x0000, 0x0009, 0x0008, 0xc107, 0x000b,
-	0x80c0, 0x0009, 0x00ff, 0x0008, 0x7f3e, 0x0008, 0x0d60, 0x0000,
-	0x0efe, 0x0008, 0x1f80, 0x0001, 0x7f62, 0x0008, 0x8066, 0x0000,
-	0x0009, 0x0008, 0xc111, 0x0003, 0x003a, 0x0008, 0x1dfe, 0x0000,
-	0x00f2, 0x0003, 0x0036, 0x0008, 0x00b8, 0x0004, 0x0130, 0x0003,
-	0x8074, 0x0000, 0x2000, 0x0000, 0x8072, 0x0000, 0x2000, 0x0000,
-	0x0130, 0x0003, 0x3a44, 0x0002, 0x0a1d, 0x000b, 0x8074, 0x0000,
-	0x1000, 0x0000, 0x8072, 0x0000, 0x1000, 0x0000, 0xadd0, 0x0001,
-	0x0000, 0x0008, 0x7f0e, 0x0008, 0xb1ee, 0x000b, 0xa7d0, 0x0001,
-	0x0000, 0x0008, 0x7f00, 0x0000, 0xa6d0, 0x0009, 0x0000, 0x0008,
-	0x00d0, 0x0009, 0x8942, 0x0003, 0x8074, 0x0000, 0x4040, 0x0008,
-	0x5930, 0x000b, 0x50db, 0x000b, 0x3a46, 0x000a, 0x8942, 0x0003,
-	0x3a47, 0x0002, 0x093d, 0x0003, 0x8054, 0x0008, 0x0004, 0x0000,
-	0x8074, 0x0000, 0x8000, 0x0000, 0x8072, 0x0000, 0x3000, 0x0008,
-	0x016b, 0x000b, 0x92c0, 0x0009, 0x0fc8, 0x0000, 0x080a, 0x0003,
-	0x1246, 0x000a, 0x89e8, 0x0003, 0x1a60, 0x0000, 0x8062, 0x0008,
-	0x0002, 0x0000, 0x8066, 0x0000, 0x367a, 0x0000, 0xc147, 0x0003,
-	0x92c0, 0x0009, 0x0780, 0x0008, 0x8a04, 0x000b, 0x124b, 0x0002,
-	0x0950, 0x000b, 0x2e4d, 0x0002, 0x2e4d, 0x0002, 0x09ee, 0x000b,
-	0x3a46, 0x000a, 0x895d, 0x000b, 0x5952, 0x0003, 0x8054, 0x0008,
-	0x0004, 0x0000, 0x1243, 0x000a, 0x0967, 0x0003, 0x8010, 0x0008,
-	0x000d, 0x0000, 0x01dc, 0x0004, 0x1810, 0x0000, 0x01dc, 0x0004,
-	0x0167, 0x000b, 0x194d, 0x000a, 0x0961, 0x0003, 0x1243, 0x000a,
-	0x09f8, 0x0003, 0x5961, 0x0003, 0x8054, 0x0008, 0x0004, 0x0000,
-	0x01d1, 0x000c, 0x1810, 0x0000, 0x01dc, 0x0004, 0x8074, 0x0000,
-	0xf000, 0x0008, 0x8072, 0x0000, 0x3000, 0x0008, 0x0d30, 0x0000,
-	0x3a42, 0x0002, 0x8971, 0x0003, 0x15fe, 0x0008, 0xb051, 0x000b,
-	0x000a, 0x000b, 0x8074, 0x0000, 0x0501, 0x0000, 0x8010, 0x0008,
-	0x000c, 0x0008, 0x01dc, 0x0004, 0x000a, 0x000b, 0xbbe0, 0x0009,
-	0x0030, 0x0008, 0x8987, 0x0003, 0x18fe, 0x0000, 0x3ce0, 0x0009,
-	0x0984, 0x000b, 0x15fe, 0x0008, 0x3ce0, 0x0009, 0x0984, 0x000b,
-	0x01cc, 0x000c, 0x8076, 0x0008, 0x0040, 0x0000, 0x01c9, 0x0003,
-	0x8076, 0x0008, 0x0041, 0x0008, 0x01c9, 0x0003, 0xbbe0, 0x0009,
-	0x0032, 0x0000, 0x898c, 0x000b, 0x3c1e, 0x0008, 0x01c9, 0x0003,
-	0xbbe0, 0x0009, 0x0037, 0x0000, 0x89ae, 0x000b, 0x18fe, 0x0000,
-	0x3ce0, 0x0009, 0x8984, 0x0003, 0x8076, 0x0008, 0x0040, 0x0000,
-	0x1a60, 0x0000, 0x8062, 0x0008, 0x000d, 0x0000, 0xa6d0, 0x0009,
-	0x0000, 0x0008, 0x7f04, 0x0008, 0xa7d0, 0x0001, 0x0000, 0x0008,
-	0x7f06, 0x0000, 0xa8d0, 0x0001, 0x0000, 0x0008, 0x7f08, 0x0008,
-	0xa9d0, 0x0009, 0x0000, 0x0008, 0x7f0a, 0x0000, 0x8066, 0x0000,
-	0x0422, 0x0000, 0xc1a5, 0x0003, 0x01d1, 0x000c, 0x8054, 0x0008,
-	0x0004, 0x0000, 0x8074, 0x0000, 0xf000, 0x0008, 0x8072, 0x0000,
-	0xb000, 0x0000, 0x016b, 0x000b, 0xbbe0, 0x0009, 0x0038, 0x0000,
-	0x89c0, 0x0003, 0x18fe, 0x0000, 0x3ce0, 0x0009, 0x09bd, 0x000b,
-	0x15fe, 0x0008, 0x3ce0, 0x0009, 0x8980, 0x000b, 0x01cc, 0x000c,
-	0x8076, 0x0008, 0x0040, 0x0000, 0x8072, 0x0000, 0x8000, 0x0000,
-	0x0214, 0x0003, 0x8076, 0x0008, 0x0042, 0x0008, 0x01c9, 0x0003,
-	0xbbe0, 0x0009, 0x0016, 0x0000, 0x89c9, 0x0003, 0x3a44, 0x0002,
-	0x880c, 0x000b, 0x8072, 0x0000, 0x8000, 0x0000, 0x8000, 0x000f,
-	0x000a, 0x000b, 0x8072, 0x0000, 0x8000, 0x0000, 0x000a, 0x000b,
-	0x3d30, 0x000a, 0x7f00, 0x0000, 0xbc80, 0x0001, 0x0007, 0x0000,
-	0x01d5, 0x000b, 0x1930, 0x000a, 0x7f00, 0x0000, 0x9880, 0x0001,
-	0x0007, 0x0000, 0x8060, 0x0000, 0x0400, 0x0000, 0x7f62, 0x0008,
-	0x8066, 0x0000, 0x000a, 0x0008, 0xc1da, 0x000b, 0x4000, 0x000f,
-	0x21dc, 0x0003, 0x0870, 0x0008, 0x4000, 0x000f, 0xbac0, 0x0009,
-	0x0090, 0x0008, 0x09e5, 0x0003, 0x8074, 0x0000, 0x0706, 0x0000,
-	0x01e7, 0x0003, 0x8074, 0x0000, 0x0703, 0x0000, 0x4000, 0x000f,
-	0x8010, 0x0008, 0x0023, 0x0000, 0x0222, 0x0003, 0x8010, 0x0008,
-	0x0008, 0x0000, 0x0222, 0x0003, 0x8010, 0x0008, 0x0022, 0x0008,
-	0x0222, 0x0003, 0x01d1, 0x000c, 0x8010, 0x0008, 0x0007, 0x0000,
-	0x01dc, 0x0004, 0x1810, 0x0000, 0x01dc, 0x0004, 0x022e, 0x0003,
-	0x01d1, 0x000c, 0x8010, 0x0008, 0x001b, 0x0008, 0x01dc, 0x0004,
-	0x1810, 0x0000, 0x01dc, 0x0004, 0x8074, 0x0000, 0xf080, 0x0000,
-	0x8072, 0x0000, 0x3000, 0x0008, 0x0d30, 0x0000, 0x000a, 0x000b,
-	0x8010, 0x0008, 0x0009, 0x0008, 0x0222, 0x0003, 0x8010, 0x0008,
-	0x0005, 0x0008, 0x0222, 0x0003, 0x808c, 0x0008, 0x0001, 0x0000,
-	0x8010, 0x0008, 0x0004, 0x0000, 0x4143, 0x000a, 0x085f, 0x0003,
-	0x3a44, 0x0002, 0x880a, 0x000b, 0x0d2a, 0x0008, 0x0222, 0x0003,
-	0x8010, 0x0008, 0x0003, 0x0008, 0x0226, 0x000b, 0x8010, 0x0008,
-	0x000b, 0x0000, 0x0226, 0x000b, 0x8010, 0x0008, 0x0002, 0x0000,
-	0x0226, 0x000b, 0x3a47, 0x0002, 0x8930, 0x0003, 0x8010, 0x0008,
-	0x0006, 0x0008, 0x0226, 0x000b, 0x8074, 0x0000, 0xf000, 0x0008,
-	0x8072, 0x0000, 0x3000, 0x0008, 0x01dc, 0x0004, 0x01df, 0x0004,
-	0x3a40, 0x000a, 0x080a, 0x0003, 0x8010, 0x0008, 0x000c, 0x0008,
-	0x01dc, 0x0004, 0x000a, 0x000b, 0x8074, 0x0000, 0xf080, 0x0000,
-	0x8072, 0x0000, 0x3000, 0x0008, 0x0d30, 0x0000, 0x2e4d, 0x0002,
-	0x2e4d, 0x0002, 0x0a39, 0x000b, 0x8054, 0x0008, 0x0019, 0x0000,
-	0x000a, 0x000b, 0x8054, 0x0008, 0x0009, 0x0008, 0x000a, 0x000b,
-	0x3a44, 0x0002, 0x880a, 0x000b, 0x0217, 0x0003, 0xf4e5, 0xf482,
-	0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
-	0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000,
-	0x6870
+	0x9006, 0x004e, 0x00be, 0x00ce, 0x00ee, 0x0005, 0x2001, 0x1810,
+	0x2004, 0xd0a4, 0x0160, 0x2001, 0x1836, 0x2004, 0xd0a4, 0x0138,
+	0x2001, 0x185c, 0x2004, 0xd0a4, 0x1118, 0x9085, 0x0001, 0x0005,
+	0x9006, 0x0ce8, 0x0126, 0x0006, 0x00e6, 0x0016, 0x2091, 0x8000,
+	0x2071, 0x1840, 0xd5a4, 0x0118, 0x7054, 0x8000, 0x7056, 0xd5b4,
+	0x0118, 0x7050, 0x8000, 0x7052, 0xd5ac, 0x0178, 0x2500, 0x9084,
+	0x0007, 0x908e, 0x0003, 0x0148, 0x908e, 0x0004, 0x0130, 0x908e,
+	0x0005, 0x0118, 0x2071, 0x184a, 0x0089, 0x001e, 0x00ee, 0x000e,
+	0x012e, 0x0005, 0x0126, 0x0006, 0x00e6, 0x2091, 0x8000, 0x2071,
+	0x1842, 0x0021, 0x00ee, 0x000e, 0x012e, 0x0005, 0x2e04, 0x8000,
+	0x2072, 0x1220, 0x8e70, 0x2e04, 0x8000, 0x2072, 0x0005, 0x00e6,
+	0x2071, 0x1840, 0x0c99, 0x00ee, 0x0005, 0x00e6, 0x2071, 0x1844,
+	0x0c69, 0x00ee, 0x0005, 0x0126, 0x0006, 0x00e6, 0x2091, 0x8000,
+	0x2071, 0x1840, 0x7064, 0x8000, 0x7066, 0x00ee, 0x000e, 0x012e,
+	0x0005, 0x0003, 0x000b, 0x03ce, 0x0000, 0xc000, 0x0001, 0x8064,
+	0x0008, 0x0010, 0x0000, 0x8066, 0x0000, 0x0101, 0x0008, 0x4407,
+	0x0003, 0x8060, 0x0000, 0x0400, 0x0000, 0x580d, 0x000b, 0x7924,
+	0x0003, 0x5096, 0x000b, 0x4c0a, 0x0003, 0xbac0, 0x0009, 0x008a,
+	0x0000, 0x0c0a, 0x000b, 0x15fe, 0x0008, 0x340a, 0x0003, 0xc4c0,
+	0x0009, 0x7000, 0x0000, 0xffa0, 0x0001, 0x2000, 0x0000, 0x15bf,
+	0x000b, 0x808c, 0x0008, 0x0001, 0x0000, 0x0000, 0x0007, 0x4047,
+	0x000a, 0x808c, 0x0008, 0x0002, 0x0000, 0x0821, 0x0003, 0x4022,
+	0x0000, 0x0022, 0x000b, 0x4122, 0x0008, 0x4447, 0x0002, 0x0de3,
+	0x000b, 0x0bfe, 0x0008, 0x11a0, 0x0001, 0x11c5, 0x000b, 0x0ca0,
+	0x0001, 0x11c5, 0x000b, 0x9180, 0x0001, 0x0004, 0x0000, 0x8060,
+	0x0000, 0x0400, 0x0000, 0x7f62, 0x0008, 0x8066, 0x0000, 0x0009,
+	0x0008, 0x4430, 0x000b, 0x808c, 0x0008, 0x0000, 0x0008, 0x0060,
+	0x0008, 0x8062, 0x0008, 0x0004, 0x0000, 0x8066, 0x0000, 0x0411,
+	0x0000, 0x4438, 0x0003, 0x03fe, 0x0000, 0x43e0, 0x0001, 0x0dc2,
+	0x000b, 0xc2c0, 0x0009, 0x00ff, 0x0008, 0x02e0, 0x0001, 0x0dc2,
+	0x000b, 0x9180, 0x0001, 0x0005, 0x0008, 0x8060, 0x0000, 0x0400,
+	0x0000, 0x7f62, 0x0008, 0x8066, 0x0000, 0x0019, 0x0000, 0x4447,
+	0x000b, 0x0240, 0x0002, 0x09bf, 0x0003, 0x00fe, 0x0000, 0x31c2,
+	0x000b, 0x112a, 0x0000, 0x002e, 0x0008, 0x022c, 0x0008, 0x3a44,
+	0x0002, 0x0c0a, 0x000b, 0x808c, 0x0008, 0x0002, 0x0000, 0x1760,
+	0x0008, 0x8062, 0x0008, 0x000f, 0x0008, 0x8066, 0x0000, 0x0011,
+	0x0008, 0x4458, 0x0003, 0x01fe, 0x0008, 0x42e0, 0x0009, 0x0db5,
+	0x000b, 0x00fe, 0x0000, 0x43e0, 0x0001, 0x0db5, 0x000b, 0x1734,
+	0x0000, 0x1530, 0x0000, 0x1632, 0x0008, 0x0d2a, 0x0008, 0x9880,
+	0x0001, 0x0010, 0x0000, 0x8060, 0x0000, 0x0400, 0x0000, 0x7f62,
+	0x0008, 0x8066, 0x0000, 0x1e0a, 0x0008, 0x446a, 0x000b, 0x808a,
+	0x0008, 0x0003, 0x0008, 0x1a60, 0x0000, 0x8062, 0x0008, 0x0002,
+	0x0000, 0x5870, 0x000b, 0x8066, 0x0000, 0x3679, 0x0000, 0x4473,
+	0x0003, 0x5874, 0x0003, 0x8054, 0x0008, 0x0011, 0x0008, 0x8074,
+	0x0000, 0x1010, 0x0008, 0x1efe, 0x0000, 0x300a, 0x000b, 0x007d,
+	0x0004, 0x000a, 0x000b, 0x1c60, 0x0000, 0x1b62, 0x0000, 0x8066,
+	0x0000, 0x0231, 0x0008, 0x4481, 0x000b, 0x5882, 0x0003, 0x0140,
+	0x0008, 0x0242, 0x0000, 0x1f43, 0x0002, 0x0c8c, 0x0003, 0x0d44,
+	0x0000, 0x0d46, 0x0008, 0x0348, 0x0008, 0x044a, 0x0008, 0x0090,
+	0x000b, 0x0344, 0x0008, 0x0446, 0x0008, 0x0548, 0x0008, 0x064a,
+	0x0000, 0x5890, 0x0003, 0x8054, 0x0008, 0x0001, 0x0000, 0x8074,
+	0x0000, 0x2020, 0x0008, 0x4000, 0x000f, 0x3a40, 0x000a, 0x0c0d,
+	0x0003, 0xabd0, 0x0001, 0x0000, 0x0008, 0x7f24, 0x0000, 0x589b,
+	0x000b, 0x8054, 0x0008, 0x0002, 0x0000, 0x1242, 0x0002, 0x08e1,
+	0x0003, 0x3a45, 0x000a, 0x08d0, 0x000b, 0x1e10, 0x000a, 0x7f3c,
+	0x0000, 0x08cd, 0x000b, 0x1d00, 0x0002, 0x7f3a, 0x0000, 0x0d60,
+	0x0000, 0x7f62, 0x0008, 0x8066, 0x0000, 0x0009, 0x0008, 0x44ab,
+	0x0003, 0x00fe, 0x0000, 0x34ca, 0x0003, 0x1c60, 0x0000, 0x8062,
+	0x0008, 0x0001, 0x0000, 0x8066, 0x0000, 0x0009, 0x0008, 0x44b3,
+	0x0003, 0x00fe, 0x0000, 0x319e, 0x000b, 0x0038, 0x0000, 0x0060,
+	0x0008, 0x8062, 0x0008, 0x0019, 0x0000, 0x8066, 0x0000, 0x0009,
+	0x0008, 0x44bc, 0x0003, 0x80c0, 0x0009, 0x00ff, 0x0008, 0x7f3e,
+	0x0008, 0x0d60, 0x0000, 0x0efe, 0x0008, 0x1f80, 0x0001, 0x7f62,
+	0x0008, 0x8066, 0x0000, 0x0009, 0x0008, 0x44c6, 0x000b, 0x003a,
+	0x0008, 0x1dfe, 0x0000, 0x00a7, 0x0003, 0x0036, 0x0008, 0x007d,
+	0x0004, 0x00e1, 0x000b, 0x8074, 0x0000, 0x2000, 0x0000, 0x00e1,
+	0x000b, 0x3a44, 0x0002, 0x09c8, 0x0003, 0x8074, 0x0000, 0x1000,
+	0x0000, 0xadd0, 0x0001, 0x0000, 0x0008, 0x7f0e, 0x0008, 0x359b,
+	0x0003, 0xa7d0, 0x0001, 0x0000, 0x0008, 0x7f00, 0x0000, 0xa6d0,
+	0x0009, 0x0000, 0x0008, 0x00d0, 0x0009, 0x0cf1, 0x0003, 0x8074,
+	0x0000, 0x4040, 0x0008, 0x58e1, 0x0003, 0x5096, 0x000b, 0x3a46,
+	0x000a, 0x0cf1, 0x0003, 0x3a47, 0x0002, 0x08ec, 0x000b, 0x8054,
+	0x0008, 0x0004, 0x0000, 0x8074, 0x0000, 0x8000, 0x0000, 0x0118,
+	0x0003, 0x92c0, 0x0009, 0x0fc8, 0x0000, 0x080a, 0x0003, 0x1246,
+	0x000a, 0x0d95, 0x0003, 0x1a60, 0x0000, 0x8062, 0x0008, 0x0002,
+	0x0000, 0x8066, 0x0000, 0x367a, 0x0000, 0x44f6, 0x000b, 0x92c0,
+	0x0009, 0x0780, 0x0008, 0x0daf, 0x0003, 0x124b, 0x0002, 0x08ff,
+	0x0003, 0x2e4d, 0x0002, 0x2e4d, 0x0002, 0x099b, 0x0003, 0x3a46,
+	0x000a, 0x0d0c, 0x0003, 0x5901, 0x0003, 0x8054, 0x0008, 0x0004,
+	0x0000, 0x1243, 0x000a, 0x0916, 0x0003, 0x8010, 0x0008, 0x000d,
+	0x0000, 0x0189, 0x0004, 0x1810, 0x0000, 0x0189, 0x0004, 0x0116,
+	0x000b, 0x194d, 0x000a, 0x0910, 0x0003, 0x1243, 0x000a, 0x09a5,
+	0x000b, 0x5910, 0x0003, 0x8054, 0x0008, 0x0004, 0x0000, 0x017e,
+	0x000c, 0x1810, 0x0000, 0x0189, 0x0004, 0x8074, 0x0000, 0xf000,
+	0x0008, 0x0d30, 0x0000, 0x3a42, 0x0002, 0x0d1e, 0x0003, 0x15fe,
+	0x0008, 0x3451, 0x000b, 0x000a, 0x000b, 0x8074, 0x0000, 0x0501,
+	0x0000, 0x8010, 0x0008, 0x000c, 0x0008, 0x0189, 0x0004, 0x000a,
+	0x000b, 0xbbe0, 0x0009, 0x0030, 0x0008, 0x0d34, 0x000b, 0x18fe,
+	0x0000, 0x3ce0, 0x0009, 0x0931, 0x0003, 0x15fe, 0x0008, 0x3ce0,
+	0x0009, 0x0931, 0x0003, 0x0179, 0x0004, 0x8076, 0x0008, 0x0040,
+	0x0000, 0x0176, 0x000b, 0x8076, 0x0008, 0x0041, 0x0008, 0x0176,
+	0x000b, 0xbbe0, 0x0009, 0x0032, 0x0000, 0x0d39, 0x0003, 0x3c1e,
+	0x0008, 0x0176, 0x000b, 0xbbe0, 0x0009, 0x0037, 0x0000, 0x0d5b,
+	0x000b, 0x18fe, 0x0000, 0x3ce0, 0x0009, 0x0d31, 0x000b, 0x8076,
+	0x0008, 0x0040, 0x0000, 0x1a60, 0x0000, 0x8062, 0x0008, 0x000d,
+	0x0000, 0xa6d0, 0x0009, 0x0000, 0x0008, 0x7f04, 0x0008, 0xa7d0,
+	0x0001, 0x0000, 0x0008, 0x7f06, 0x0000, 0xa8d0, 0x0001, 0x0000,
+	0x0008, 0x7f08, 0x0008, 0xa9d0, 0x0009, 0x0000, 0x0008, 0x7f0a,
+	0x0000, 0x8066, 0x0000, 0x0422, 0x0000, 0x4552, 0x000b, 0x017e,
+	0x000c, 0x8054, 0x0008, 0x0004, 0x0000, 0x8074, 0x0000, 0xf000,
+	0x0008, 0x8072, 0x0000, 0x8000, 0x0000, 0x0118, 0x0003, 0xbbe0,
+	0x0009, 0x0038, 0x0000, 0x0d6d, 0x000b, 0x18fe, 0x0000, 0x3ce0,
+	0x0009, 0x096a, 0x000b, 0x15fe, 0x0008, 0x3ce0, 0x0009, 0x0d2d,
+	0x0003, 0x0179, 0x0004, 0x8076, 0x0008, 0x0040, 0x0000, 0x8072,
+	0x0000, 0x8000, 0x0000, 0x01bf, 0x000b, 0x8076, 0x0008, 0x0042,
+	0x0008, 0x0176, 0x000b, 0xbbe0, 0x0009, 0x0016, 0x0000, 0x0d76,
+	0x000b, 0x3a44, 0x0002, 0x0c0c, 0x000b, 0x8072, 0x0000, 0x8000,
+	0x0000, 0x8000, 0x000f, 0x000a, 0x000b, 0x8072, 0x0000, 0x8000,
+	0x0000, 0x000a, 0x000b, 0x3d30, 0x000a, 0x7f00, 0x0000, 0xbc80,
+	0x0001, 0x0007, 0x0000, 0x0182, 0x0003, 0x1930, 0x000a, 0x7f00,
+	0x0000, 0x9880, 0x0001, 0x0007, 0x0000, 0x8060, 0x0000, 0x0400,
+	0x0000, 0x7f62, 0x0008, 0x8066, 0x0000, 0x000a, 0x0008, 0x4587,
+	0x0003, 0x4000, 0x000f, 0x2189, 0x0003, 0x0870, 0x0008, 0x4000,
+	0x000f, 0xbac0, 0x0009, 0x0090, 0x0008, 0x0992, 0x0003, 0x8074,
+	0x0000, 0x0706, 0x0000, 0x0194, 0x000b, 0x8074, 0x0000, 0x0703,
+	0x0000, 0x4000, 0x000f, 0x8010, 0x0008, 0x0023, 0x0000, 0x01cd,
+	0x000b, 0x8010, 0x0008, 0x0008, 0x0000, 0x01cd, 0x000b, 0x8010,
+	0x0008, 0x0022, 0x0008, 0x01cd, 0x000b, 0x017e, 0x000c, 0x8010,
+	0x0008, 0x0007, 0x0000, 0x0189, 0x0004, 0x1810, 0x0000, 0x0189,
+	0x0004, 0x01d7, 0x0003, 0x017e, 0x000c, 0x8010, 0x0008, 0x001b,
+	0x0008, 0x0189, 0x0004, 0x1810, 0x0000, 0x0189, 0x0004, 0x8074,
+	0x0000, 0xf080, 0x0000, 0x0d30, 0x0000, 0x000a, 0x000b, 0x8010,
+	0x0008, 0x0009, 0x0008, 0x01cd, 0x000b, 0x8010, 0x0008, 0x0005,
+	0x0008, 0x01cd, 0x000b, 0x808c, 0x0008, 0x0001, 0x0000, 0x8010,
+	0x0008, 0x0004, 0x0000, 0x4143, 0x000a, 0x085f, 0x0003, 0x3a44,
+	0x0002, 0x0c0a, 0x000b, 0x0d2a, 0x0008, 0x01cd, 0x000b, 0x8010,
+	0x0008, 0x0003, 0x0008, 0x01cf, 0x0003, 0x8010, 0x0008, 0x000b,
+	0x0000, 0x01cf, 0x0003, 0x8010, 0x0008, 0x0002, 0x0000, 0x01cf,
+	0x0003, 0x3a47, 0x0002, 0x0ce1, 0x000b, 0x8010, 0x0008, 0x0006,
+	0x0008, 0x01cf, 0x0003, 0x8074, 0x0000, 0xf000, 0x0008, 0x0189,
+	0x0004, 0x018c, 0x0004, 0x3a40, 0x000a, 0x080a, 0x0003, 0x8010,
+	0x0008, 0x000c, 0x0008, 0x0189, 0x0004, 0x000a, 0x000b, 0x8074,
+	0x0000, 0xf080, 0x0000, 0x0d30, 0x0000, 0x2e4d, 0x0002, 0x2e4d,
+	0x0002, 0x09e0, 0x0003, 0x8054, 0x0008, 0x0019, 0x0000, 0x000a,
+	0x000b, 0x8054, 0x0008, 0x0009, 0x0008, 0x000a, 0x000b, 0x3a44,
+	0x0002, 0x0c0a, 0x000b, 0x01c2, 0x000b, 0x0a0b, 0xf5dd, 0x0003,
+	0x000b, 0x03ce, 0x0000, 0xc000, 0x0001, 0x8064, 0x0008, 0x0010,
+	0x0000, 0x8066, 0x0000, 0x0101, 0x0008, 0xc007, 0x0003, 0x8060,
+	0x0000, 0x0400, 0x0000, 0x580d, 0x000b, 0x7924, 0x0003, 0x5096,
+	0x000b, 0xc80a, 0x0003, 0xbac0, 0x0009, 0x008a, 0x0000, 0x880a,
+	0x000b, 0x15fe, 0x0008, 0xb00a, 0x0003, 0xc4c0, 0x0009, 0x7000,
+	0x0000, 0xffa0, 0x0001, 0x2000, 0x0000, 0x91bf, 0x000b, 0x808c,
+	0x0008, 0x0001, 0x0000, 0x0000, 0x0007, 0x4047, 0x000a, 0x808c,
+	0x0008, 0x0002, 0x0000, 0x0821, 0x0003, 0x4022, 0x0000, 0x0022,
+	0x000b, 0x4122, 0x0008, 0x4447, 0x0002, 0x89e3, 0x000b, 0x0bfe,
+	0x0008, 0x11a0, 0x0001, 0x11c5, 0x000b, 0x0ca0, 0x0001, 0x11c5,
+	0x000b, 0x9180, 0x0001, 0x0004, 0x0000, 0x8060, 0x0000, 0x0400,
+	0x0000, 0x7f62, 0x0008, 0x8066, 0x0000, 0x0009, 0x0008, 0xc030,
+	0x000b, 0x808c, 0x0008, 0x0000, 0x0008, 0x0060, 0x0008, 0x8062,
+	0x0008, 0x0004, 0x0000, 0x8066, 0x0000, 0x0411, 0x0000, 0xc038,
+	0x0003, 0x03fe, 0x0000, 0x43e0, 0x0001, 0x89c2, 0x000b, 0xc2c0,
+	0x0009, 0x00ff, 0x0008, 0x02e0, 0x0001, 0x89c2, 0x000b, 0x9180,
+	0x0001, 0x0005, 0x0008, 0x8060, 0x0000, 0x0400, 0x0000, 0x7f62,
+	0x0008, 0x8066, 0x0000, 0x0019, 0x0000, 0xc047, 0x000b, 0x0240,
+	0x0002, 0x09bf, 0x0003, 0x00fe, 0x0000, 0x31c2, 0x000b, 0x112a,
+	0x0000, 0x002e, 0x0008, 0x022c, 0x0008, 0x3a44, 0x0002, 0x880a,
+	0x000b, 0x808c, 0x0008, 0x0002, 0x0000, 0x1760, 0x0008, 0x8062,
+	0x0008, 0x000f, 0x0008, 0x8066, 0x0000, 0x0011, 0x0008, 0xc058,
+	0x0003, 0x01fe, 0x0008, 0x42e0, 0x0009, 0x89b5, 0x000b, 0x00fe,
+	0x0000, 0x43e0, 0x0001, 0x89b5, 0x000b, 0x1734, 0x0000, 0x1530,
+	0x0000, 0x1632, 0x0008, 0x0d2a, 0x0008, 0x9880, 0x0001, 0x0010,
+	0x0000, 0x8060, 0x0000, 0x0400, 0x0000, 0x7f62, 0x0008, 0x8066,
+	0x0000, 0x1e0a, 0x0008, 0xc06a, 0x000b, 0x808a, 0x0008, 0x0003,
+	0x0008, 0x1a60, 0x0000, 0x8062, 0x0008, 0x0002, 0x0000, 0x5870,
+	0x000b, 0x8066, 0x0000, 0x3679, 0x0000, 0xc073, 0x0003, 0x5874,
+	0x0003, 0x8054, 0x0008, 0x0011, 0x0008, 0x8074, 0x0000, 0x1010,
+	0x0008, 0x1efe, 0x0000, 0x300a, 0x000b, 0x007d, 0x0004, 0x000a,
+	0x000b, 0x1c60, 0x0000, 0x1b62, 0x0000, 0x8066, 0x0000, 0x0231,
+	0x0008, 0xc081, 0x000b, 0x5882, 0x0003, 0x0140, 0x0008, 0x0242,
+	0x0000, 0x1f43, 0x0002, 0x888c, 0x0003, 0x0d44, 0x0000, 0x0d46,
+	0x0008, 0x0348, 0x0008, 0x044a, 0x0008, 0x0090, 0x000b, 0x0344,
+	0x0008, 0x0446, 0x0008, 0x0548, 0x0008, 0x064a, 0x0000, 0x5890,
+	0x0003, 0x8054, 0x0008, 0x0001, 0x0000, 0x8074, 0x0000, 0x2020,
+	0x0008, 0x4000, 0x000f, 0x3a40, 0x000a, 0x880d, 0x0003, 0xabd0,
+	0x0001, 0x0000, 0x0008, 0x7f24, 0x0000, 0x589b, 0x000b, 0x8054,
+	0x0008, 0x0002, 0x0000, 0x1242, 0x0002, 0x08e1, 0x0003, 0x3a45,
+	0x000a, 0x08d0, 0x000b, 0x1e10, 0x000a, 0x7f3c, 0x0000, 0x08cd,
+	0x000b, 0x1d00, 0x0002, 0x7f3a, 0x0000, 0x0d60, 0x0000, 0x7f62,
+	0x0008, 0x8066, 0x0000, 0x0009, 0x0008, 0xc0ab, 0x0003, 0x00fe,
+	0x0000, 0xb0ca, 0x0003, 0x1c60, 0x0000, 0x8062, 0x0008, 0x0001,
+	0x0000, 0x8066, 0x0000, 0x0009, 0x0008, 0xc0b3, 0x0003, 0x00fe,
+	0x0000, 0x319e, 0x000b, 0x0038, 0x0000, 0x0060, 0x0008, 0x8062,
+	0x0008, 0x0019, 0x0000, 0x8066, 0x0000, 0x0009, 0x0008, 0xc0bc,
+	0x0003, 0x80c0, 0x0009, 0x00ff, 0x0008, 0x7f3e, 0x0008, 0x0d60,
+	0x0000, 0x0efe, 0x0008, 0x1f80, 0x0001, 0x7f62, 0x0008, 0x8066,
+	0x0000, 0x0009, 0x0008, 0xc0c6, 0x000b, 0x003a, 0x0008, 0x1dfe,
+	0x0000, 0x00a7, 0x0003, 0x0036, 0x0008, 0x007d, 0x0004, 0x00e1,
+	0x000b, 0x8074, 0x0000, 0x2000, 0x0000, 0x00e1, 0x000b, 0x3a44,
+	0x0002, 0x09c8, 0x0003, 0x8074, 0x0000, 0x1000, 0x0000, 0xadd0,
+	0x0001, 0x0000, 0x0008, 0x7f0e, 0x0008, 0xb19b, 0x0003, 0xa7d0,
+	0x0001, 0x0000, 0x0008, 0x7f00, 0x0000, 0xa6d0, 0x0009, 0x0000,
+	0x0008, 0x00d0, 0x0009, 0x88f1, 0x0003, 0x8074, 0x0000, 0x4040,
+	0x0008, 0x58e1, 0x0003, 0x5096, 0x000b, 0x3a46, 0x000a, 0x88f1,
+	0x0003, 0x3a47, 0x0002, 0x08ec, 0x000b, 0x8054, 0x0008, 0x0004,
+	0x0000, 0x8074, 0x0000, 0x8000, 0x0000, 0x0118, 0x0003, 0x92c0,
+	0x0009, 0x0fc8, 0x0000, 0x080a, 0x0003, 0x1246, 0x000a, 0x8995,
+	0x0003, 0x1a60, 0x0000, 0x8062, 0x0008, 0x0002, 0x0000, 0x8066,
+	0x0000, 0x367a, 0x0000, 0xc0f6, 0x000b, 0x92c0, 0x0009, 0x0780,
+	0x0008, 0x89af, 0x0003, 0x124b, 0x0002, 0x08ff, 0x0003, 0x2e4d,
+	0x0002, 0x2e4d, 0x0002, 0x099b, 0x0003, 0x3a46, 0x000a, 0x890c,
+	0x0003, 0x5901, 0x0003, 0x8054, 0x0008, 0x0004, 0x0000, 0x1243,
+	0x000a, 0x0916, 0x0003, 0x8010, 0x0008, 0x000d, 0x0000, 0x0189,
+	0x0004, 0x1810, 0x0000, 0x0189, 0x0004, 0x0116, 0x000b, 0x194d,
+	0x000a, 0x0910, 0x0003, 0x1243, 0x000a, 0x09a5, 0x000b, 0x5910,
+	0x0003, 0x8054, 0x0008, 0x0004, 0x0000, 0x017e, 0x000c, 0x1810,
+	0x0000, 0x0189, 0x0004, 0x8074, 0x0000, 0xf000, 0x0008, 0x0d30,
+	0x0000, 0x3a42, 0x0002, 0x891e, 0x0003, 0x15fe, 0x0008, 0xb051,
+	0x000b, 0x000a, 0x000b, 0x8074, 0x0000, 0x0501, 0x0000, 0x8010,
+	0x0008, 0x000c, 0x0008, 0x0189, 0x0004, 0x000a, 0x000b, 0xbbe0,
+	0x0009, 0x0030, 0x0008, 0x8934, 0x000b, 0x18fe, 0x0000, 0x3ce0,
+	0x0009, 0x0931, 0x0003, 0x15fe, 0x0008, 0x3ce0, 0x0009, 0x0931,
+	0x0003, 0x0179, 0x0004, 0x8076, 0x0008, 0x0040, 0x0000, 0x0176,
+	0x000b, 0x8076, 0x0008, 0x0041, 0x0008, 0x0176, 0x000b, 0xbbe0,
+	0x0009, 0x0032, 0x0000, 0x8939, 0x0003, 0x3c1e, 0x0008, 0x0176,
+	0x000b, 0xbbe0, 0x0009, 0x0037, 0x0000, 0x895b, 0x000b, 0x18fe,
+	0x0000, 0x3ce0, 0x0009, 0x8931, 0x000b, 0x8076, 0x0008, 0x0040,
+	0x0000, 0x1a60, 0x0000, 0x8062, 0x0008, 0x000d, 0x0000, 0xa6d0,
+	0x0009, 0x0000, 0x0008, 0x7f04, 0x0008, 0xa7d0, 0x0001, 0x0000,
+	0x0008, 0x7f06, 0x0000, 0xa8d0, 0x0001, 0x0000, 0x0008, 0x7f08,
+	0x0008, 0xa9d0, 0x0009, 0x0000, 0x0008, 0x7f0a, 0x0000, 0x8066,
+	0x0000, 0x0422, 0x0000, 0xc152, 0x000b, 0x017e, 0x000c, 0x8054,
+	0x0008, 0x0004, 0x0000, 0x8074, 0x0000, 0xf000, 0x0008, 0x8072,
+	0x0000, 0x8000, 0x0000, 0x0118, 0x0003, 0xbbe0, 0x0009, 0x0038,
+	0x0000, 0x896d, 0x000b, 0x18fe, 0x0000, 0x3ce0, 0x0009, 0x096a,
+	0x000b, 0x15fe, 0x0008, 0x3ce0, 0x0009, 0x892d, 0x0003, 0x0179,
+	0x0004, 0x8076, 0x0008, 0x0040, 0x0000, 0x8072, 0x0000, 0x8000,
+	0x0000, 0x01bf, 0x000b, 0x8076, 0x0008, 0x0042, 0x0008, 0x0176,
+	0x000b, 0xbbe0, 0x0009, 0x0016, 0x0000, 0x8976, 0x000b, 0x3a44,
+	0x0002, 0x880c, 0x000b, 0x8072, 0x0000, 0x8000, 0x0000, 0x8000,
+	0x000f, 0x000a, 0x000b, 0x8072, 0x0000, 0x8000, 0x0000, 0x000a,
+	0x000b, 0x3d30, 0x000a, 0x7f00, 0x0000, 0xbc80, 0x0001, 0x0007,
+	0x0000, 0x0182, 0x0003, 0x1930, 0x000a, 0x7f00, 0x0000, 0x9880,
+	0x0001, 0x0007, 0x0000, 0x8060, 0x0000, 0x0400, 0x0000, 0x7f62,
+	0x0008, 0x8066, 0x0000, 0x000a, 0x0008, 0xc187, 0x0003, 0x4000,
+	0x000f, 0x2189, 0x0003, 0x0870, 0x0008, 0x4000, 0x000f, 0xbac0,
+	0x0009, 0x0090, 0x0008, 0x0992, 0x0003, 0x8074, 0x0000, 0x0706,
+	0x0000, 0x0194, 0x000b, 0x8074, 0x0000, 0x0703, 0x0000, 0x4000,
+	0x000f, 0x8010, 0x0008, 0x0023, 0x0000, 0x01cd, 0x000b, 0x8010,
+	0x0008, 0x0008, 0x0000, 0x01cd, 0x000b, 0x8010, 0x0008, 0x0022,
+	0x0008, 0x01cd, 0x000b, 0x017e, 0x000c, 0x8010, 0x0008, 0x0007,
+	0x0000, 0x0189, 0x0004, 0x1810, 0x0000, 0x0189, 0x0004, 0x01d7,
+	0x0003, 0x017e, 0x000c, 0x8010, 0x0008, 0x001b, 0x0008, 0x0189,
+	0x0004, 0x1810, 0x0000, 0x0189, 0x0004, 0x8074, 0x0000, 0xf080,
+	0x0000, 0x0d30, 0x0000, 0x000a, 0x000b, 0x8010, 0x0008, 0x0009,
+	0x0008, 0x01cd, 0x000b, 0x8010, 0x0008, 0x0005, 0x0008, 0x01cd,
+	0x000b, 0x808c, 0x0008, 0x0001, 0x0000, 0x8010, 0x0008, 0x0004,
+	0x0000, 0x4143, 0x000a, 0x085f, 0x0003, 0x3a44, 0x0002, 0x880a,
+	0x000b, 0x0d2a, 0x0008, 0x01cd, 0x000b, 0x8010, 0x0008, 0x0003,
+	0x0008, 0x01cf, 0x0003, 0x8010, 0x0008, 0x000b, 0x0000, 0x01cf,
+	0x0003, 0x8010, 0x0008, 0x0002, 0x0000, 0x01cf, 0x0003, 0x3a47,
+	0x0002, 0x88e1, 0x000b, 0x8010, 0x0008, 0x0006, 0x0008, 0x01cf,
+	0x0003, 0x8074, 0x0000, 0xf000, 0x0008, 0x0189, 0x0004, 0x018c,
+	0x0004, 0x3a40, 0x000a, 0x080a, 0x0003, 0x8010, 0x0008, 0x000c,
+	0x0008, 0x0189, 0x0004, 0x000a, 0x000b, 0x8074, 0x0000, 0xf080,
+	0x0000, 0x0d30, 0x0000, 0x2e4d, 0x0002, 0x2e4d, 0x0002, 0x09e0,
+	0x0003, 0x8054, 0x0008, 0x0019, 0x0000, 0x000a, 0x000b, 0x8054,
+	0x0008, 0x0009, 0x0008, 0x000a, 0x000b, 0x3a44, 0x0002, 0x880a,
+	0x000b, 0x01c2, 0x000b, 0x460b, 0xf5c6, 0x0001, 0x0002, 0x0004,
+	0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100, 0x0200, 0x0400,
+	0x0800, 0x1000, 0x2000, 0x4000, 0x8000, 0xdac8
 };
 #ifdef UNIQUE_FW_NAME
-unsigned short fw2300flx_length01 = 0xdd79;
+unsigned short fw2300flx_length01 = 0xdb56;
 #else
-unsigned short risc_code_length01 = 0xdd79;
+unsigned short risc_code_length01 = 0xdb56;
 #endif
 
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -63,23 +63,29 @@ qla2x00_sysfs_write_fw_dump(struct kobje
 			    ha->host_no);
 
 			vfree(ha->fw_dump_buffer);
-			free_pages((unsigned long)ha->fw_dump,
-			    ha->fw_dump_order);
+			if (!IS_QLA24XX(ha) && !IS_QLA25XX(ha))
+				free_pages((unsigned long)ha->fw_dump,
+				    ha->fw_dump_order);
 
 			ha->fw_dump_reading = 0;
 			ha->fw_dump_buffer = NULL;
 			ha->fw_dump = NULL;
+			ha->fw_dumped = 0;
 		}
 		break;
 	case 1:
-		if (ha->fw_dump != NULL && !ha->fw_dump_reading) {
+		if ((ha->fw_dump || ha->fw_dumped) && !ha->fw_dump_reading) {
 			ha->fw_dump_reading = 1;
 
-			dump_size = FW_DUMP_SIZE_1M;
-			if (ha->fw_memory_size < 0x20000) 
-				dump_size = FW_DUMP_SIZE_128K;
-			else if (ha->fw_memory_size < 0x80000) 
-				dump_size = FW_DUMP_SIZE_512K;
+			if (IS_QLA24XX(ha) || IS_QLA25XX(ha))
+				dump_size = FW_DUMP_SIZE_24XX;
+			else {
+				dump_size = FW_DUMP_SIZE_1M;
+				if (ha->fw_memory_size < 0x20000)
+					dump_size = FW_DUMP_SIZE_128K;
+				else if (ha->fw_memory_size < 0x80000)
+					dump_size = FW_DUMP_SIZE_512K;
+			}
 			ha->fw_dump_buffer = (char *)vmalloc(dump_size);
 			if (ha->fw_dump_buffer == NULL) {
 				qla_printk(KERN_WARNING, ha,
@@ -93,10 +99,7 @@ qla2x00_sysfs_write_fw_dump(struct kobje
 			    "Firmware dump ready for read on (%ld).\n",
 			    ha->host_no);
 			memset(ha->fw_dump_buffer, 0, dump_size);
-			if (IS_QLA2100(ha) || IS_QLA2200(ha))
- 				qla2100_ascii_fw_dump(ha);
- 			else
- 				qla2300_ascii_fw_dump(ha);
+			ha->isp_ops.ascii_fw_dump(ha);
 			ha->fw_dump_buffer_len = strlen(ha->fw_dump_buffer);
 		}
 		break;
@@ -121,23 +124,15 @@ qla2x00_sysfs_read_nvram(struct kobject 
 {
 	struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj,
 	    struct device, kobj)));
-	uint16_t	*witer;
 	unsigned long	flags;
-	uint16_t	cnt;
 
-	if (!capable(CAP_SYS_ADMIN) || off != 0 || count != sizeof(nvram_t))
+	if (!capable(CAP_SYS_ADMIN) || off != 0 || count != ha->nvram_size)
 		return 0;
 
 	/* Read NVRAM. */
 	spin_lock_irqsave(&ha->hardware_lock, flags);
-	qla2x00_lock_nvram_access(ha);
- 	witer = (uint16_t *)buf;
- 	for (cnt = 0; cnt < count / 2; cnt++) {
-		*witer = cpu_to_le16(qla2x00_get_nvram_word(ha,
-		    cnt+ha->nvram_base));
-		witer++;
- 	}
-	qla2x00_unlock_nvram_access(ha);
+	ha->isp_ops.read_nvram(ha, (uint8_t *)buf, ha->nvram_base,
+	    ha->nvram_size);
 	spin_unlock_irqrestore(&ha->hardware_lock, flags);
 
 	return (count);
@@ -149,34 +144,38 @@ qla2x00_sysfs_write_nvram(struct kobject
 {
 	struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj,
 	    struct device, kobj)));
-	uint8_t		*iter;
-	uint16_t	*witer;
 	unsigned long	flags;
 	uint16_t	cnt;
-	uint8_t		chksum;
 
-	if (!capable(CAP_SYS_ADMIN) || off != 0 || count != sizeof(nvram_t))
+	if (!capable(CAP_SYS_ADMIN) || off != 0 || count != ha->nvram_size)
 		return 0;
 
 	/* Checksum NVRAM. */
-	iter = (uint8_t *)buf;
-	chksum = 0;
-	for (cnt = 0; cnt < count - 1; cnt++)
-		chksum += *iter++;
-	chksum = ~chksum + 1;
-	*iter = chksum;
+	if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) {
+		uint32_t *iter;
+		uint32_t chksum;
+
+		iter = (uint32_t *)buf;
+		chksum = 0;
+		for (cnt = 0; cnt < ((count >> 2) - 1); cnt++)
+			chksum += le32_to_cpu(*iter++);
+		chksum = ~chksum + 1;
+		*iter = cpu_to_le32(chksum);
+	} else {
+		uint8_t *iter;
+		uint8_t chksum;
+
+		iter = (uint8_t *)buf;
+		chksum = 0;
+		for (cnt = 0; cnt < count - 1; cnt++)
+			chksum += *iter++;
+		chksum = ~chksum + 1;
+		*iter = chksum;
+	}
 
 	/* Write NVRAM. */
 	spin_lock_irqsave(&ha->hardware_lock, flags);
-	qla2x00_lock_nvram_access(ha);
-	qla2x00_release_nvram_protection(ha);
- 	witer = (uint16_t *)buf;
-	for (cnt = 0; cnt < count / 2; cnt++) {
-		qla2x00_write_nvram_word(ha, cnt+ha->nvram_base,
-		    cpu_to_le16(*witer));
-		witer++;
-	}
-	qla2x00_unlock_nvram_access(ha);
+	ha->isp_ops.write_nvram(ha, (uint8_t *)buf, ha->nvram_base, count);
 	spin_unlock_irqrestore(&ha->hardware_lock, flags);
 
 	return (count);
@@ -188,7 +187,7 @@ static struct bin_attribute sysfs_nvram_
 		.mode = S_IRUSR | S_IWUSR,
 		.owner = THIS_MODULE,
 	},
-	.size = sizeof(nvram_t),
+	.size = 0,
 	.read = qla2x00_sysfs_read_nvram,
 	.write = qla2x00_sysfs_write_nvram,
 };
@@ -199,6 +198,7 @@ qla2x00_alloc_sysfs_attr(scsi_qla_host_t
 	struct Scsi_Host *host = ha->host;
 
 	sysfs_create_bin_file(&host->shost_gendev.kobj, &sysfs_fw_dump_attr);
+	sysfs_nvram_attr.size = ha->nvram_size;
 	sysfs_create_bin_file(&host->shost_gendev.kobj, &sysfs_nvram_attr);
 }
 
diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c
--- a/drivers/scsi/qla2xxx/qla_dbg.c
+++ b/drivers/scsi/qla2xxx/qla_dbg.c
@@ -2,7 +2,7 @@
  *                  QLOGIC LINUX SOFTWARE
  *
  * QLogic ISP2x00 device driver for Linux 2.6.x
- * Copyright (C) 2003-2004 QLogic Corporation
+ * Copyright (C) 2003-2005 QLogic Corporation
  * (www.qlogic.com)
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -36,7 +36,7 @@ qla2300_fw_dump(scsi_qla_host_t *ha, int
 	uint16_t	mb0, mb2;
 
 	uint32_t	stat;
-	device_reg_t __iomem *reg = ha->iobase;
+	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
 	uint16_t __iomem *dmp_reg;
 	unsigned long	flags;
 	struct qla2300_fw_dump	*fw;
@@ -74,7 +74,7 @@ qla2300_fw_dump(scsi_qla_host_t *ha, int
 	fw->hccr = RD_REG_WORD(&reg->hccr);
 
 	/* Pause RISC. */
-	WRT_REG_WORD(&reg->hccr, HCCR_PAUSE_RISC); 
+	WRT_REG_WORD(&reg->hccr, HCCR_PAUSE_RISC);
 	if (IS_QLA2300(ha)) {
 		for (cnt = 30000;
 		    (RD_REG_WORD(&reg->hccr) & HCCR_RISC_PAUSE) == 0 &&
@@ -91,85 +91,85 @@ qla2300_fw_dump(scsi_qla_host_t *ha, int
 
 	if (rval == QLA_SUCCESS) {
 		dmp_reg = (uint16_t __iomem *)(reg + 0);
-		for (cnt = 0; cnt < sizeof(fw->pbiu_reg) / 2; cnt++) 
+		for (cnt = 0; cnt < sizeof(fw->pbiu_reg) / 2; cnt++)
 			fw->pbiu_reg[cnt] = RD_REG_WORD(dmp_reg++);
 
 		dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x10);
-		for (cnt = 0; cnt < sizeof(fw->risc_host_reg) / 2; cnt++) 
+		for (cnt = 0; cnt < sizeof(fw->risc_host_reg) / 2; cnt++)
 			fw->risc_host_reg[cnt] = RD_REG_WORD(dmp_reg++);
 
 		dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x40);
-		for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++) 
+		for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++)
 			fw->mailbox_reg[cnt] = RD_REG_WORD(dmp_reg++);
 
 		WRT_REG_WORD(&reg->ctrl_status, 0x40);
 		dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
-		for (cnt = 0; cnt < sizeof(fw->resp_dma_reg) / 2; cnt++) 
+		for (cnt = 0; cnt < sizeof(fw->resp_dma_reg) / 2; cnt++)
 			fw->resp_dma_reg[cnt] = RD_REG_WORD(dmp_reg++);
 
 		WRT_REG_WORD(&reg->ctrl_status, 0x50);
 		dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
-		for (cnt = 0; cnt < sizeof(fw->dma_reg) / 2; cnt++) 
+		for (cnt = 0; cnt < sizeof(fw->dma_reg) / 2; cnt++)
 			fw->dma_reg[cnt] = RD_REG_WORD(dmp_reg++);
 
 		WRT_REG_WORD(&reg->ctrl_status, 0x00);
 		dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0xA0);
-		for (cnt = 0; cnt < sizeof(fw->risc_hdw_reg) / 2; cnt++) 
+		for (cnt = 0; cnt < sizeof(fw->risc_hdw_reg) / 2; cnt++)
 			fw->risc_hdw_reg[cnt] = RD_REG_WORD(dmp_reg++);
 
-		WRT_REG_WORD(&reg->pcr, 0x2000); 
+		WRT_REG_WORD(&reg->pcr, 0x2000);
 		dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
-		for (cnt = 0; cnt < sizeof(fw->risc_gp0_reg) / 2; cnt++) 
+		for (cnt = 0; cnt < sizeof(fw->risc_gp0_reg) / 2; cnt++)
 			fw->risc_gp0_reg[cnt] = RD_REG_WORD(dmp_reg++);
 
-		WRT_REG_WORD(&reg->pcr, 0x2200); 
+		WRT_REG_WORD(&reg->pcr, 0x2200);
 		dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
-		for (cnt = 0; cnt < sizeof(fw->risc_gp1_reg) / 2; cnt++) 
+		for (cnt = 0; cnt < sizeof(fw->risc_gp1_reg) / 2; cnt++)
 			fw->risc_gp1_reg[cnt] = RD_REG_WORD(dmp_reg++);
 
-		WRT_REG_WORD(&reg->pcr, 0x2400); 
+		WRT_REG_WORD(&reg->pcr, 0x2400);
 		dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
-		for (cnt = 0; cnt < sizeof(fw->risc_gp2_reg) / 2; cnt++) 
+		for (cnt = 0; cnt < sizeof(fw->risc_gp2_reg) / 2; cnt++)
 			fw->risc_gp2_reg[cnt] = RD_REG_WORD(dmp_reg++);
 
-		WRT_REG_WORD(&reg->pcr, 0x2600); 
+		WRT_REG_WORD(&reg->pcr, 0x2600);
 		dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
-		for (cnt = 0; cnt < sizeof(fw->risc_gp3_reg) / 2; cnt++) 
+		for (cnt = 0; cnt < sizeof(fw->risc_gp3_reg) / 2; cnt++)
 			fw->risc_gp3_reg[cnt] = RD_REG_WORD(dmp_reg++);
 
-		WRT_REG_WORD(&reg->pcr, 0x2800); 
+		WRT_REG_WORD(&reg->pcr, 0x2800);
 		dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
-		for (cnt = 0; cnt < sizeof(fw->risc_gp4_reg) / 2; cnt++) 
+		for (cnt = 0; cnt < sizeof(fw->risc_gp4_reg) / 2; cnt++)
 			fw->risc_gp4_reg[cnt] = RD_REG_WORD(dmp_reg++);
 
-		WRT_REG_WORD(&reg->pcr, 0x2A00); 
+		WRT_REG_WORD(&reg->pcr, 0x2A00);
 		dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
-		for (cnt = 0; cnt < sizeof(fw->risc_gp5_reg) / 2; cnt++) 
+		for (cnt = 0; cnt < sizeof(fw->risc_gp5_reg) / 2; cnt++)
 			fw->risc_gp5_reg[cnt] = RD_REG_WORD(dmp_reg++);
 
-		WRT_REG_WORD(&reg->pcr, 0x2C00); 
+		WRT_REG_WORD(&reg->pcr, 0x2C00);
 		dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
-		for (cnt = 0; cnt < sizeof(fw->risc_gp6_reg) / 2; cnt++) 
+		for (cnt = 0; cnt < sizeof(fw->risc_gp6_reg) / 2; cnt++)
 			fw->risc_gp6_reg[cnt] = RD_REG_WORD(dmp_reg++);
 
-		WRT_REG_WORD(&reg->pcr, 0x2E00); 
+		WRT_REG_WORD(&reg->pcr, 0x2E00);
 		dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
-		for (cnt = 0; cnt < sizeof(fw->risc_gp7_reg) / 2; cnt++) 
+		for (cnt = 0; cnt < sizeof(fw->risc_gp7_reg) / 2; cnt++)
 			fw->risc_gp7_reg[cnt] = RD_REG_WORD(dmp_reg++);
 
-		WRT_REG_WORD(&reg->ctrl_status, 0x10); 
+		WRT_REG_WORD(&reg->ctrl_status, 0x10);
 		dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
-		for (cnt = 0; cnt < sizeof(fw->frame_buf_hdw_reg) / 2; cnt++) 
+		for (cnt = 0; cnt < sizeof(fw->frame_buf_hdw_reg) / 2; cnt++)
 			fw->frame_buf_hdw_reg[cnt] = RD_REG_WORD(dmp_reg++);
 
-		WRT_REG_WORD(&reg->ctrl_status, 0x20); 
+		WRT_REG_WORD(&reg->ctrl_status, 0x20);
 		dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
-		for (cnt = 0; cnt < sizeof(fw->fpm_b0_reg) / 2; cnt++) 
+		for (cnt = 0; cnt < sizeof(fw->fpm_b0_reg) / 2; cnt++)
 			fw->fpm_b0_reg[cnt] = RD_REG_WORD(dmp_reg++);
 
-		WRT_REG_WORD(&reg->ctrl_status, 0x30); 
+		WRT_REG_WORD(&reg->ctrl_status, 0x30);
 		dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
-		for (cnt = 0; cnt < sizeof(fw->fpm_b1_reg) / 2; cnt++) 
+		for (cnt = 0; cnt < sizeof(fw->fpm_b1_reg) / 2; cnt++)
 			fw->fpm_b1_reg[cnt] = RD_REG_WORD(dmp_reg++);
 
 		/* Reset RISC. */
@@ -405,7 +405,7 @@ qla2300_ascii_fw_dump(scsi_qla_host_t *h
 	fw = ha->fw_dump;
 
 	qla_uprintf(&uiter, "%s Firmware Version %s\n", ha->model_number,
-	    qla2x00_get_fw_version_str(ha, fw_info));
+	    ha->isp_ops.fw_version_str(ha, fw_info));
 
 	qla_uprintf(&uiter, "\n[==>BEG]\n");
 
@@ -587,7 +587,7 @@ qla2100_fw_dump(scsi_qla_host_t *ha, int
 	uint32_t	cnt, timer;
 	uint16_t	risc_address;
 	uint16_t	mb0, mb2;
-	device_reg_t __iomem *reg = ha->iobase;
+	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
 	uint16_t __iomem *dmp_reg;
 	unsigned long	flags;
 	struct qla2100_fw_dump	*fw;
@@ -622,7 +622,7 @@ qla2100_fw_dump(scsi_qla_host_t *ha, int
 	fw->hccr = RD_REG_WORD(&reg->hccr);
 
 	/* Pause RISC. */
-	WRT_REG_WORD(&reg->hccr, HCCR_PAUSE_RISC); 
+	WRT_REG_WORD(&reg->hccr, HCCR_PAUSE_RISC);
 	for (cnt = 30000; (RD_REG_WORD(&reg->hccr) & HCCR_RISC_PAUSE) == 0 &&
 	    rval == QLA_SUCCESS; cnt--) {
 		if (cnt)
@@ -632,7 +632,7 @@ qla2100_fw_dump(scsi_qla_host_t *ha, int
 	}
 	if (rval == QLA_SUCCESS) {
 		dmp_reg = (uint16_t __iomem *)(reg + 0);
-		for (cnt = 0; cnt < sizeof(fw->pbiu_reg) / 2; cnt++) 
+		for (cnt = 0; cnt < sizeof(fw->pbiu_reg) / 2; cnt++)
 			fw->pbiu_reg[cnt] = RD_REG_WORD(dmp_reg++);
 
 		dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x10);
@@ -644,67 +644,67 @@ qla2100_fw_dump(scsi_qla_host_t *ha, int
 		}
 
 		dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x20);
-		for (cnt = 0; cnt < sizeof(fw->dma_reg) / 2; cnt++) 
+		for (cnt = 0; cnt < sizeof(fw->dma_reg) / 2; cnt++)
 			fw->dma_reg[cnt] = RD_REG_WORD(dmp_reg++);
 
 		WRT_REG_WORD(&reg->ctrl_status, 0x00);
 		dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0xA0);
-		for (cnt = 0; cnt < sizeof(fw->risc_hdw_reg) / 2; cnt++) 
+		for (cnt = 0; cnt < sizeof(fw->risc_hdw_reg) / 2; cnt++)
 			fw->risc_hdw_reg[cnt] = RD_REG_WORD(dmp_reg++);
 
-		WRT_REG_WORD(&reg->pcr, 0x2000); 
+		WRT_REG_WORD(&reg->pcr, 0x2000);
 		dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
-		for (cnt = 0; cnt < sizeof(fw->risc_gp0_reg) / 2; cnt++) 
+		for (cnt = 0; cnt < sizeof(fw->risc_gp0_reg) / 2; cnt++)
 			fw->risc_gp0_reg[cnt] = RD_REG_WORD(dmp_reg++);
 
-		WRT_REG_WORD(&reg->pcr, 0x2100); 
+		WRT_REG_WORD(&reg->pcr, 0x2100);
 		dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
-		for (cnt = 0; cnt < sizeof(fw->risc_gp1_reg) / 2; cnt++) 
+		for (cnt = 0; cnt < sizeof(fw->risc_gp1_reg) / 2; cnt++)
 			fw->risc_gp1_reg[cnt] = RD_REG_WORD(dmp_reg++);
 
-		WRT_REG_WORD(&reg->pcr, 0x2200); 
+		WRT_REG_WORD(&reg->pcr, 0x2200);
 		dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
-		for (cnt = 0; cnt < sizeof(fw->risc_gp2_reg) / 2; cnt++) 
+		for (cnt = 0; cnt < sizeof(fw->risc_gp2_reg) / 2; cnt++)
 			fw->risc_gp2_reg[cnt] = RD_REG_WORD(dmp_reg++);
 
-		WRT_REG_WORD(&reg->pcr, 0x2300); 
+		WRT_REG_WORD(&reg->pcr, 0x2300);
 		dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
-		for (cnt = 0; cnt < sizeof(fw->risc_gp3_reg) / 2; cnt++) 
+		for (cnt = 0; cnt < sizeof(fw->risc_gp3_reg) / 2; cnt++)
 			fw->risc_gp3_reg[cnt] = RD_REG_WORD(dmp_reg++);
 
-		WRT_REG_WORD(&reg->pcr, 0x2400); 
+		WRT_REG_WORD(&reg->pcr, 0x2400);
 		dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
-		for (cnt = 0; cnt < sizeof(fw->risc_gp4_reg) / 2; cnt++) 
+		for (cnt = 0; cnt < sizeof(fw->risc_gp4_reg) / 2; cnt++)
 			fw->risc_gp4_reg[cnt] = RD_REG_WORD(dmp_reg++);
 
-		WRT_REG_WORD(&reg->pcr, 0x2500); 
+		WRT_REG_WORD(&reg->pcr, 0x2500);
 		dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
-		for (cnt = 0; cnt < sizeof(fw->risc_gp5_reg) / 2; cnt++) 
+		for (cnt = 0; cnt < sizeof(fw->risc_gp5_reg) / 2; cnt++)
 			fw->risc_gp5_reg[cnt] = RD_REG_WORD(dmp_reg++);
 
-		WRT_REG_WORD(&reg->pcr, 0x2600); 
+		WRT_REG_WORD(&reg->pcr, 0x2600);
 		dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
-		for (cnt = 0; cnt < sizeof(fw->risc_gp6_reg) / 2; cnt++) 
+		for (cnt = 0; cnt < sizeof(fw->risc_gp6_reg) / 2; cnt++)
 			fw->risc_gp6_reg[cnt] = RD_REG_WORD(dmp_reg++);
 
-		WRT_REG_WORD(&reg->pcr, 0x2700); 
+		WRT_REG_WORD(&reg->pcr, 0x2700);
 		dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
-		for (cnt = 0; cnt < sizeof(fw->risc_gp7_reg) / 2; cnt++) 
+		for (cnt = 0; cnt < sizeof(fw->risc_gp7_reg) / 2; cnt++)
 			fw->risc_gp7_reg[cnt] = RD_REG_WORD(dmp_reg++);
 
-		WRT_REG_WORD(&reg->ctrl_status, 0x10); 
+		WRT_REG_WORD(&reg->ctrl_status, 0x10);
 		dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
-		for (cnt = 0; cnt < sizeof(fw->frame_buf_hdw_reg) / 2; cnt++) 
+		for (cnt = 0; cnt < sizeof(fw->frame_buf_hdw_reg) / 2; cnt++)
 			fw->frame_buf_hdw_reg[cnt] = RD_REG_WORD(dmp_reg++);
 
-		WRT_REG_WORD(&reg->ctrl_status, 0x20); 
+		WRT_REG_WORD(&reg->ctrl_status, 0x20);
 		dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
-		for (cnt = 0; cnt < sizeof(fw->fpm_b0_reg) / 2; cnt++) 
+		for (cnt = 0; cnt < sizeof(fw->fpm_b0_reg) / 2; cnt++)
 			fw->fpm_b0_reg[cnt] = RD_REG_WORD(dmp_reg++);
 
-		WRT_REG_WORD(&reg->ctrl_status, 0x30); 
+		WRT_REG_WORD(&reg->ctrl_status, 0x30);
 		dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
-		for (cnt = 0; cnt < sizeof(fw->fpm_b1_reg) / 2; cnt++) 
+		for (cnt = 0; cnt < sizeof(fw->fpm_b1_reg) / 2; cnt++)
 			fw->fpm_b1_reg[cnt] = RD_REG_WORD(dmp_reg++);
 
 		/* Reset the ISP. */
@@ -723,7 +723,7 @@ qla2100_fw_dump(scsi_qla_host_t *ha, int
 	if (rval == QLA_SUCCESS && (IS_QLA2200(ha) || (IS_QLA2100(ha) &&
 	    (RD_REG_WORD(&reg->mctr) & (BIT_1 | BIT_0)) != 0))) {
 
-		WRT_REG_WORD(&reg->hccr, HCCR_PAUSE_RISC); 
+		WRT_REG_WORD(&reg->hccr, HCCR_PAUSE_RISC);
 		for (cnt = 30000;
 		    (RD_REG_WORD(&reg->hccr) & HCCR_RISC_PAUSE) == 0 &&
 		    rval == QLA_SUCCESS; cnt--) {
@@ -819,7 +819,7 @@ qla2100_ascii_fw_dump(scsi_qla_host_t *h
 	fw = ha->fw_dump;
 
 	qla_uprintf(&uiter, "%s Firmware Version %s\n", ha->model_number,
-	    qla2x00_get_fw_version_str(ha, fw_info));
+	    ha->isp_ops.fw_version_str(ha, fw_info));
 
 	qla_uprintf(&uiter, "\n[==>BEG]\n");
 
@@ -964,7 +964,7 @@ qla_uprintf(char **uiter, char *fmt, ...
 	int	iter, len;
 	char	buf[128];
 	va_list	args;
- 
+
 	va_start(args, fmt);
 	len = vsprintf(buf, fmt, args);
 	va_end(args);
@@ -975,16 +975,959 @@ qla_uprintf(char **uiter, char *fmt, ...
 	return (len);
 }
 
-//FIXME
+
+void
+qla24xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked)
+{
+	int		rval;
+	uint32_t	cnt, timer;
+	uint32_t	risc_address;
+	uint16_t	mb[4];
+
+	uint32_t	stat;
+	struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
+	uint32_t __iomem *dmp_reg;
+	uint32_t	*iter_reg;
+	uint16_t __iomem *mbx_reg;
+	unsigned long	flags;
+	struct qla24xx_fw_dump *fw;
+	uint32_t	ext_mem_cnt;
+
+	risc_address = ext_mem_cnt = 0;
+	memset(mb, 0, sizeof(mb));
+	flags = 0;
+
+	if (!hardware_locked)
+		spin_lock_irqsave(&ha->hardware_lock, flags);
+
+	if (!ha->fw_dump24) {
+		qla_printk(KERN_WARNING, ha,
+		    "No buffer available for dump!!!\n");
+		goto qla24xx_fw_dump_failed;
+	}
+
+	if (ha->fw_dumped) {
+		qla_printk(KERN_WARNING, ha,
+		    "Firmware has been previously dumped (%p) -- ignoring "
+		    "request...\n", ha->fw_dump24);
+		goto qla24xx_fw_dump_failed;
+	}
+	fw = (struct qla24xx_fw_dump *) ha->fw_dump24;
+
+	rval = QLA_SUCCESS;
+	fw->hccr = RD_REG_DWORD(&reg->hccr);
+
+	/* Pause RISC. */
+	if ((fw->hccr & HCCRX_RISC_PAUSE) == 0) {
+		WRT_REG_DWORD(&reg->hccr, HCCRX_SET_RISC_RESET |
+		    HCCRX_CLR_HOST_INT);
+		RD_REG_DWORD(&reg->hccr);		/* PCI Posting. */
+		WRT_REG_DWORD(&reg->hccr, HCCRX_SET_RISC_PAUSE);
+		for (cnt = 30000;
+		    (RD_REG_DWORD(&reg->hccr) & HCCRX_RISC_PAUSE) == 0 &&
+		    rval == QLA_SUCCESS; cnt--) {
+			if (cnt)
+				udelay(100);
+			else
+				rval = QLA_FUNCTION_TIMEOUT;
+		}
+	}
+
+	/* Disable interrupts. */
+	WRT_REG_DWORD(&reg->ictrl, 0);
+	RD_REG_DWORD(&reg->ictrl);
+
+	if (rval == QLA_SUCCESS) {
+		/* Host interface registers. */
+		dmp_reg = (uint32_t __iomem *)(reg + 0);
+		for (cnt = 0; cnt < sizeof(fw->host_reg) / 4; cnt++)
+			fw->host_reg[cnt] = RD_REG_DWORD(dmp_reg++);
+
+		/* Mailbox registers. */
+		mbx_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);
+		for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++)
+			fw->mailbox_reg[cnt] = RD_REG_WORD(mbx_reg++);
+
+		/* Transfer sequence registers. */
+		iter_reg = fw->xseq_gp_reg;
+		WRT_REG_DWORD(&reg->iobase_addr, 0xBF00);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < 16; cnt++)
+			*iter_reg++ = RD_REG_DWORD(dmp_reg++);
+
+		WRT_REG_DWORD(&reg->iobase_addr, 0xBF10);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < 16; cnt++)
+			*iter_reg++ = RD_REG_DWORD(dmp_reg++);
+
+		WRT_REG_DWORD(&reg->iobase_addr, 0xBF20);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < 16; cnt++)
+			*iter_reg++ = RD_REG_DWORD(dmp_reg++);
+
+		WRT_REG_DWORD(&reg->iobase_addr, 0xBF30);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < 16; cnt++)
+			*iter_reg++ = RD_REG_DWORD(dmp_reg++);
+
+		WRT_REG_DWORD(&reg->iobase_addr, 0xBF40);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < 16; cnt++)
+			*iter_reg++ = RD_REG_DWORD(dmp_reg++);
+
+		WRT_REG_DWORD(&reg->iobase_addr, 0xBF50);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < 16; cnt++)
+			*iter_reg++ = RD_REG_DWORD(dmp_reg++);
+
+		WRT_REG_DWORD(&reg->iobase_addr, 0xBF60);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < 16; cnt++)
+			*iter_reg++ = RD_REG_DWORD(dmp_reg++);
+
+		WRT_REG_DWORD(&reg->iobase_addr, 0xBF70);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < 16; cnt++)
+			*iter_reg++ = RD_REG_DWORD(dmp_reg++);
+
+		WRT_REG_DWORD(&reg->iobase_addr, 0xBFE0);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < sizeof(fw->xseq_0_reg) / 4; cnt++)
+			fw->xseq_0_reg[cnt] = RD_REG_DWORD(dmp_reg++);
+
+		WRT_REG_DWORD(&reg->iobase_addr, 0xBFF0);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < sizeof(fw->xseq_1_reg) / 4; cnt++)
+			fw->xseq_1_reg[cnt] = RD_REG_DWORD(dmp_reg++);
+
+		/* Receive sequence registers. */
+		iter_reg = fw->rseq_gp_reg;
+		WRT_REG_DWORD(&reg->iobase_addr, 0xFF00);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < 16; cnt++)
+			*iter_reg++ = RD_REG_DWORD(dmp_reg++);
+
+		WRT_REG_DWORD(&reg->iobase_addr, 0xFF10);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < 16; cnt++)
+			*iter_reg++ = RD_REG_DWORD(dmp_reg++);
+
+		WRT_REG_DWORD(&reg->iobase_addr, 0xFF20);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < 16; cnt++)
+			*iter_reg++ = RD_REG_DWORD(dmp_reg++);
+
+		WRT_REG_DWORD(&reg->iobase_addr, 0xFF30);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < 16; cnt++)
+			*iter_reg++ = RD_REG_DWORD(dmp_reg++);
+
+		WRT_REG_DWORD(&reg->iobase_addr, 0xFF40);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < 16; cnt++)
+			*iter_reg++ = RD_REG_DWORD(dmp_reg++);
+
+		WRT_REG_DWORD(&reg->iobase_addr, 0xFF50);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < 16; cnt++)
+			*iter_reg++ = RD_REG_DWORD(dmp_reg++);
+
+		WRT_REG_DWORD(&reg->iobase_addr, 0xFF60);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < 16; cnt++)
+			*iter_reg++ = RD_REG_DWORD(dmp_reg++);
+
+		WRT_REG_DWORD(&reg->iobase_addr, 0xFF70);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < 16; cnt++)
+			*iter_reg++ = RD_REG_DWORD(dmp_reg++);
+
+		WRT_REG_DWORD(&reg->iobase_addr, 0xFFD0);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < sizeof(fw->rseq_0_reg) / 4; cnt++)
+			fw->rseq_0_reg[cnt] = RD_REG_DWORD(dmp_reg++);
+
+		WRT_REG_DWORD(&reg->iobase_addr, 0xFFE0);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < sizeof(fw->rseq_1_reg) / 4; cnt++)
+			fw->rseq_1_reg[cnt] = RD_REG_DWORD(dmp_reg++);
+
+		WRT_REG_DWORD(&reg->iobase_addr, 0xFFF0);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < sizeof(fw->rseq_2_reg) / 4; cnt++)
+			fw->rseq_2_reg[cnt] = RD_REG_DWORD(dmp_reg++);
+
+		/* Command DMA registers. */
+		WRT_REG_DWORD(&reg->iobase_addr, 0x7100);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < sizeof(fw->cmd_dma_reg) / 4; cnt++)
+			fw->cmd_dma_reg[cnt] = RD_REG_DWORD(dmp_reg++);
+
+		/* Queues. */
+		iter_reg = fw->req0_dma_reg;
+		WRT_REG_DWORD(&reg->iobase_addr, 0x7200);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < 8; cnt++)
+			*iter_reg++ = RD_REG_DWORD(dmp_reg++);
+
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xE4);
+		for (cnt = 0; cnt < 7; cnt++)
+			*iter_reg++ = RD_REG_DWORD(dmp_reg++);
+
+		iter_reg = fw->resp0_dma_reg;
+		WRT_REG_DWORD(&reg->iobase_addr, 0x7300);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < 8; cnt++)
+			*iter_reg++ = RD_REG_DWORD(dmp_reg++);
+
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xE4);
+		for (cnt = 0; cnt < 7; cnt++)
+			*iter_reg++ = RD_REG_DWORD(dmp_reg++);
+
+		iter_reg = fw->req1_dma_reg;
+		WRT_REG_DWORD(&reg->iobase_addr, 0x7400);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < 8; cnt++)
+			*iter_reg++ = RD_REG_DWORD(dmp_reg++);
+
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xE4);
+		for (cnt = 0; cnt < 7; cnt++)
+			*iter_reg++ = RD_REG_DWORD(dmp_reg++);
+
+		/* Transmit DMA registers. */
+		iter_reg = fw->xmt0_dma_reg;
+		WRT_REG_DWORD(&reg->iobase_addr, 0x7600);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < 16; cnt++)
+			*iter_reg++ = RD_REG_DWORD(dmp_reg++);
+
+		WRT_REG_DWORD(&reg->iobase_addr, 0x7610);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < 16; cnt++)
+			*iter_reg++ = RD_REG_DWORD(dmp_reg++);
+
+		iter_reg = fw->xmt1_dma_reg;
+		WRT_REG_DWORD(&reg->iobase_addr, 0x7620);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < 16; cnt++)
+			*iter_reg++ = RD_REG_DWORD(dmp_reg++);
+
+		WRT_REG_DWORD(&reg->iobase_addr, 0x7630);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < 16; cnt++)
+			*iter_reg++ = RD_REG_DWORD(dmp_reg++);
+
+		iter_reg = fw->xmt2_dma_reg;
+		WRT_REG_DWORD(&reg->iobase_addr, 0x7640);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < 16; cnt++)
+			*iter_reg++ = RD_REG_DWORD(dmp_reg++);
+
+		WRT_REG_DWORD(&reg->iobase_addr, 0x7650);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < 16; cnt++)
+			*iter_reg++ = RD_REG_DWORD(dmp_reg++);
+
+		iter_reg = fw->xmt3_dma_reg;
+		WRT_REG_DWORD(&reg->iobase_addr, 0x7660);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < 16; cnt++)
+			*iter_reg++ = RD_REG_DWORD(dmp_reg++);
+
+		WRT_REG_DWORD(&reg->iobase_addr, 0x7670);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < 16; cnt++)
+			*iter_reg++ = RD_REG_DWORD(dmp_reg++);
+
+		iter_reg = fw->xmt4_dma_reg;
+		WRT_REG_DWORD(&reg->iobase_addr, 0x7680);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < 16; cnt++)
+			*iter_reg++ = RD_REG_DWORD(dmp_reg++);
+
+		WRT_REG_DWORD(&reg->iobase_addr, 0x7690);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < 16; cnt++)
+			*iter_reg++ = RD_REG_DWORD(dmp_reg++);
+
+		WRT_REG_DWORD(&reg->iobase_addr, 0x76A0);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < sizeof(fw->xmt_data_dma_reg) / 4; cnt++)
+			fw->xmt_data_dma_reg[cnt] = RD_REG_DWORD(dmp_reg++);
+
+		/* Receive DMA registers. */
+		iter_reg = fw->rcvt0_data_dma_reg;
+		WRT_REG_DWORD(&reg->iobase_addr, 0x7700);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < 16; cnt++)
+			*iter_reg++ = RD_REG_DWORD(dmp_reg++);
+
+		WRT_REG_DWORD(&reg->iobase_addr, 0x7710);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < 16; cnt++)
+			*iter_reg++ = RD_REG_DWORD(dmp_reg++);
+
+		iter_reg = fw->rcvt1_data_dma_reg;
+		WRT_REG_DWORD(&reg->iobase_addr, 0x7720);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < 16; cnt++)
+			*iter_reg++ = RD_REG_DWORD(dmp_reg++);
+
+		WRT_REG_DWORD(&reg->iobase_addr, 0x7730);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < 16; cnt++)
+			*iter_reg++ = RD_REG_DWORD(dmp_reg++);
+
+		/* RISC registers. */
+		iter_reg = fw->risc_gp_reg;
+		WRT_REG_DWORD(&reg->iobase_addr, 0x0F00);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < 16; cnt++)
+			*iter_reg++ = RD_REG_DWORD(dmp_reg++);
+
+		WRT_REG_DWORD(&reg->iobase_addr, 0x0F10);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < 16; cnt++)
+			*iter_reg++ = RD_REG_DWORD(dmp_reg++);
+
+		WRT_REG_DWORD(&reg->iobase_addr, 0x0F20);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < 16; cnt++)
+			*iter_reg++ = RD_REG_DWORD(dmp_reg++);
+
+		WRT_REG_DWORD(&reg->iobase_addr, 0x0F30);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < 16; cnt++)
+			*iter_reg++ = RD_REG_DWORD(dmp_reg++);
+
+		WRT_REG_DWORD(&reg->iobase_addr, 0x0F40);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < 16; cnt++)
+			*iter_reg++ = RD_REG_DWORD(dmp_reg++);
+
+		WRT_REG_DWORD(&reg->iobase_addr, 0x0F50);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < 16; cnt++)
+			*iter_reg++ = RD_REG_DWORD(dmp_reg++);
+
+		WRT_REG_DWORD(&reg->iobase_addr, 0x0F60);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < 16; cnt++)
+			*iter_reg++ = RD_REG_DWORD(dmp_reg++);
+
+		WRT_REG_DWORD(&reg->iobase_addr, 0x0F70);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < 16; cnt++)
+			*iter_reg++ = RD_REG_DWORD(dmp_reg++);
+
+		WRT_REG_DWORD(&reg->iobase_addr, 0x0F70);
+		RD_REG_DWORD(&reg->iobase_addr);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0);
+		WRT_REG_DWORD(dmp_reg, 0xB0000000);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC);
+		fw->shadow_reg[0] = RD_REG_DWORD(dmp_reg);
+
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0);
+		WRT_REG_DWORD(dmp_reg, 0xB0100000);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC);
+		fw->shadow_reg[1] = RD_REG_DWORD(dmp_reg);
+
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0);
+		WRT_REG_DWORD(dmp_reg, 0xB0200000);
+		dmp_reg = (uint32_t *)((uint8_t *)reg + 0xFC);
+		fw->shadow_reg[2] = RD_REG_DWORD(dmp_reg);
+
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0);
+		WRT_REG_DWORD(dmp_reg, 0xB0300000);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC);
+		fw->shadow_reg[3] = RD_REG_DWORD(dmp_reg);
+
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0);
+		WRT_REG_DWORD(dmp_reg, 0xB0400000);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC);
+		fw->shadow_reg[4] = RD_REG_DWORD(dmp_reg);
+
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0);
+		WRT_REG_DWORD(dmp_reg, 0xB0500000);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC);
+		fw->shadow_reg[5] = RD_REG_DWORD(dmp_reg);
+
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0);
+		WRT_REG_DWORD(dmp_reg, 0xB0600000);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC);
+		fw->shadow_reg[6] = RD_REG_DWORD(dmp_reg);
+
+		/* Local memory controller registers. */
+		iter_reg = fw->lmc_reg;
+		WRT_REG_DWORD(&reg->iobase_addr, 0x3000);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < 16; cnt++)
+			*iter_reg++ = RD_REG_DWORD(dmp_reg++);
+
+		WRT_REG_DWORD(&reg->iobase_addr, 0x3010);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < 16; cnt++)
+			*iter_reg++ = RD_REG_DWORD(dmp_reg++);
+
+		WRT_REG_DWORD(&reg->iobase_addr, 0x3020);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < 16; cnt++)
+			*iter_reg++ = RD_REG_DWORD(dmp_reg++);
+
+		WRT_REG_DWORD(&reg->iobase_addr, 0x3030);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < 16; cnt++)
+			*iter_reg++ = RD_REG_DWORD(dmp_reg++);
+
+		WRT_REG_DWORD(&reg->iobase_addr, 0x3040);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < 16; cnt++)
+			*iter_reg++ = RD_REG_DWORD(dmp_reg++);
+
+		WRT_REG_DWORD(&reg->iobase_addr, 0x3050);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < 16; cnt++)
+			*iter_reg++ = RD_REG_DWORD(dmp_reg++);
+
+		WRT_REG_DWORD(&reg->iobase_addr, 0x3060);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < 16; cnt++)
+			*iter_reg++ = RD_REG_DWORD(dmp_reg++);
+
+		/* Fibre Protocol Module registers. */
+		iter_reg = fw->fpm_hdw_reg;
+		WRT_REG_DWORD(&reg->iobase_addr, 0x4000);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < 16; cnt++)
+			*iter_reg++ = RD_REG_DWORD(dmp_reg++);
+
+		WRT_REG_DWORD(&reg->iobase_addr, 0x4010);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < 16; cnt++)
+			*iter_reg++ = RD_REG_DWORD(dmp_reg++);
+
+		WRT_REG_DWORD(&reg->iobase_addr, 0x4020);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < 16; cnt++)
+			*iter_reg++ = RD_REG_DWORD(dmp_reg++);
+
+		WRT_REG_DWORD(&reg->iobase_addr, 0x4030);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < 16; cnt++)
+			*iter_reg++ = RD_REG_DWORD(dmp_reg++);
+
+		WRT_REG_DWORD(&reg->iobase_addr, 0x4040);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < 16; cnt++)
+			*iter_reg++ = RD_REG_DWORD(dmp_reg++);
+
+		WRT_REG_DWORD(&reg->iobase_addr, 0x4050);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < 16; cnt++)
+			*iter_reg++ = RD_REG_DWORD(dmp_reg++);
+
+		WRT_REG_DWORD(&reg->iobase_addr, 0x4060);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < 16; cnt++)
+			*iter_reg++ = RD_REG_DWORD(dmp_reg++);
+
+		WRT_REG_DWORD(&reg->iobase_addr, 0x4070);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < 16; cnt++)
+			*iter_reg++ = RD_REG_DWORD(dmp_reg++);
+
+		WRT_REG_DWORD(&reg->iobase_addr, 0x4080);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < 16; cnt++)
+			*iter_reg++ = RD_REG_DWORD(dmp_reg++);
+
+		WRT_REG_DWORD(&reg->iobase_addr, 0x4090);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < 16; cnt++)
+			*iter_reg++ = RD_REG_DWORD(dmp_reg++);
+
+		WRT_REG_DWORD(&reg->iobase_addr, 0x40A0);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < 16; cnt++)
+			*iter_reg++ = RD_REG_DWORD(dmp_reg++);
+
+		WRT_REG_DWORD(&reg->iobase_addr, 0x40B0);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < 16; cnt++)
+			*iter_reg++ = RD_REG_DWORD(dmp_reg++);
+
+		/* Frame Buffer registers. */
+		iter_reg = fw->fb_hdw_reg;
+		WRT_REG_DWORD(&reg->iobase_addr, 0x6000);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < 16; cnt++)
+			*iter_reg++ = RD_REG_DWORD(dmp_reg++);
+
+		WRT_REG_DWORD(&reg->iobase_addr, 0x6010);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < 16; cnt++)
+			*iter_reg++ = RD_REG_DWORD(dmp_reg++);
+
+		WRT_REG_DWORD(&reg->iobase_addr, 0x6020);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < 16; cnt++)
+			*iter_reg++ = RD_REG_DWORD(dmp_reg++);
+
+		WRT_REG_DWORD(&reg->iobase_addr, 0x6030);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < 16; cnt++)
+			*iter_reg++ = RD_REG_DWORD(dmp_reg++);
+
+		WRT_REG_DWORD(&reg->iobase_addr, 0x6040);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < 16; cnt++)
+			*iter_reg++ = RD_REG_DWORD(dmp_reg++);
+
+		WRT_REG_DWORD(&reg->iobase_addr, 0x6100);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < 16; cnt++)
+			*iter_reg++ = RD_REG_DWORD(dmp_reg++);
+
+		WRT_REG_DWORD(&reg->iobase_addr, 0x6130);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < 16; cnt++)
+			*iter_reg++ = RD_REG_DWORD(dmp_reg++);
+
+		WRT_REG_DWORD(&reg->iobase_addr, 0x6150);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < 16; cnt++)
+			*iter_reg++ = RD_REG_DWORD(dmp_reg++);
+
+		WRT_REG_DWORD(&reg->iobase_addr, 0x6170);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < 16; cnt++)
+			*iter_reg++ = RD_REG_DWORD(dmp_reg++);
+
+		WRT_REG_DWORD(&reg->iobase_addr, 0x6190);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < 16; cnt++)
+			*iter_reg++ = RD_REG_DWORD(dmp_reg++);
+
+		WRT_REG_DWORD(&reg->iobase_addr, 0x61B0);
+		dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0);
+		for (cnt = 0; cnt < 16; cnt++)
+			*iter_reg++ = RD_REG_DWORD(dmp_reg++);
+
+		/* Reset RISC. */
+		WRT_REG_DWORD(&reg->ctrl_status,
+		    CSRX_DMA_SHUTDOWN|MWB_4096_BYTES);
+		for (cnt = 0; cnt < 30000; cnt++) {
+			if ((RD_REG_DWORD(&reg->ctrl_status) &
+			    CSRX_DMA_ACTIVE) == 0)
+				break;
+
+			udelay(10);
+		}
+
+		WRT_REG_DWORD(&reg->ctrl_status,
+		    CSRX_ISP_SOFT_RESET|CSRX_DMA_SHUTDOWN|MWB_4096_BYTES);
+		RD_REG_DWORD(&reg->ctrl_status);
+
+		/* Wait for firmware to complete NVRAM accesses. */
+		udelay(5);
+		mb[0] = (uint32_t) RD_REG_WORD(&reg->mailbox0);
+		for (cnt = 10000 ; cnt && mb[0]; cnt--) {
+			udelay(5);
+			mb[0] = (uint32_t) RD_REG_WORD(&reg->mailbox0);
+			barrier();
+		}
+
+		udelay(20);
+		for (cnt = 0; cnt < 30000; cnt++) {
+			if ((RD_REG_DWORD(&reg->ctrl_status) &
+			    CSRX_ISP_SOFT_RESET) == 0)
+				break;
+
+			udelay(10);
+		}
+		WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_RESET);
+		RD_REG_DWORD(&reg->hccr);             /* PCI Posting. */
+	}
+
+	for (cnt = 30000; RD_REG_WORD(&reg->mailbox0) != 0 &&
+	    rval == QLA_SUCCESS; cnt--) {
+		if (cnt)
+			udelay(100);
+		else
+			rval = QLA_FUNCTION_TIMEOUT;
+	}
+
+	/* Memory. */
+	if (rval == QLA_SUCCESS) {
+		/* Code RAM. */
+		risc_address = 0x20000;
+		WRT_REG_WORD(&reg->mailbox0, MBC_READ_RAM_EXTENDED);
+		clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
+	}
+	for (cnt = 0; cnt < sizeof(fw->code_ram) / 4 && rval == QLA_SUCCESS;
+	    cnt++, risc_address++) {
+		WRT_REG_WORD(&reg->mailbox1, LSW(risc_address));
+		WRT_REG_WORD(&reg->mailbox8, MSW(risc_address));
+		RD_REG_WORD(&reg->mailbox8);
+		WRT_REG_DWORD(&reg->hccr, HCCRX_SET_HOST_INT);
+
+		for (timer = 6000000; timer; timer--) {
+			/* Check for pending interrupts. */
+			stat = RD_REG_DWORD(&reg->host_status);
+			if (stat & HSRX_RISC_INT) {
+				stat &= 0xff;
+
+				if (stat == 0x1 || stat == 0x2 ||
+				    stat == 0x10 || stat == 0x11) {
+					set_bit(MBX_INTERRUPT,
+					    &ha->mbx_cmd_flags);
+
+					mb[0] = RD_REG_WORD(&reg->mailbox0);
+					mb[2] = RD_REG_WORD(&reg->mailbox2);
+					mb[3] = RD_REG_WORD(&reg->mailbox3);
+
+					WRT_REG_DWORD(&reg->hccr,
+					    HCCRX_CLR_RISC_INT);
+					RD_REG_DWORD(&reg->hccr);
+					break;
+				}
+
+				/* Clear this intr; it wasn't a mailbox intr */
+				WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_INT);
+				RD_REG_DWORD(&reg->hccr);
+			}
+			udelay(5);
+		}
+
+		if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) {
+			rval = mb[0] & MBS_MASK;
+			fw->code_ram[cnt] = (mb[3] << 16) | mb[2];
+		} else {
+			rval = QLA_FUNCTION_FAILED;
+		}
+	}
+
+	if (rval == QLA_SUCCESS) {
+		/* External Memory. */
+		risc_address = 0x100000;
+		ext_mem_cnt = ha->fw_memory_size - 0x100000 + 1;
+		WRT_REG_WORD(&reg->mailbox0, MBC_READ_RAM_EXTENDED);
+		clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
+	}
+	for (cnt = 0; cnt < ext_mem_cnt && rval == QLA_SUCCESS;
+	    cnt++, risc_address++) {
+		WRT_REG_WORD(&reg->mailbox1, LSW(risc_address));
+		WRT_REG_WORD(&reg->mailbox8, MSW(risc_address));
+		RD_REG_WORD(&reg->mailbox8);
+		WRT_REG_DWORD(&reg->hccr, HCCRX_SET_HOST_INT);
+
+		for (timer = 6000000; timer; timer--) {
+			/* Check for pending interrupts. */
+			stat = RD_REG_DWORD(&reg->host_status);
+			if (stat & HSRX_RISC_INT) {
+				stat &= 0xff;
+
+				if (stat == 0x1 || stat == 0x2 ||
+				    stat == 0x10 || stat == 0x11) {
+					set_bit(MBX_INTERRUPT,
+					    &ha->mbx_cmd_flags);
+
+					mb[0] = RD_REG_WORD(&reg->mailbox0);
+					mb[2] = RD_REG_WORD(&reg->mailbox2);
+					mb[3] = RD_REG_WORD(&reg->mailbox3);
+
+					WRT_REG_DWORD(&reg->hccr,
+					    HCCRX_CLR_RISC_INT);
+					RD_REG_DWORD(&reg->hccr);
+					break;
+				}
+
+				/* Clear this intr; it wasn't a mailbox intr */
+				WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_INT);
+				RD_REG_DWORD(&reg->hccr);
+			}
+			udelay(5);
+		}
+
+		if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) {
+			rval = mb[0] & MBS_MASK;
+			fw->ext_mem[cnt] = (mb[3] << 16) | mb[2];
+		} else {
+			rval = QLA_FUNCTION_FAILED;
+		}
+	}
+
+	if (rval != QLA_SUCCESS) {
+		qla_printk(KERN_WARNING, ha,
+		    "Failed to dump firmware (%x)!!!\n", rval);
+		ha->fw_dumped = 0;
+
+	} else {
+		qla_printk(KERN_INFO, ha,
+		    "Firmware dump saved to temp buffer (%ld/%p).\n",
+		    ha->host_no, ha->fw_dump24);
+		ha->fw_dumped = 1;
+	}
+
+qla24xx_fw_dump_failed:
+	if (!hardware_locked)
+		spin_unlock_irqrestore(&ha->hardware_lock, flags);
+}
+
+void
+qla24xx_ascii_fw_dump(scsi_qla_host_t *ha)
+{
+	uint32_t cnt;
+	char *uiter;
+	struct qla24xx_fw_dump *fw;
+	uint32_t ext_mem_cnt;
+
+	uiter = ha->fw_dump_buffer;
+	fw = ha->fw_dump24;
+
+	qla_uprintf(&uiter, "ISP FW Version %d.%02d.%02d Attributes %04x\n",
+	    ha->fw_major_version, ha->fw_minor_version,
+	    ha->fw_subminor_version, ha->fw_attributes);
+
+	qla_uprintf(&uiter, "\nHCCR Register\n%04x\n", fw->hccr);
+
+	qla_uprintf(&uiter, "\nHost Interface Registers");
+	for (cnt = 0; cnt < sizeof(fw->host_reg) / 4; cnt++) {
+		if (cnt % 8 == 0)
+			qla_uprintf(&uiter, "\n");
+
+		qla_uprintf(&uiter, "%08x ", fw->host_reg[cnt]);
+	}
+
+	qla_uprintf(&uiter, "\n\nMailbox Registers");
+	for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++) {
+		if (cnt % 8 == 0)
+			qla_uprintf(&uiter, "\n");
+
+		qla_uprintf(&uiter, "%08x ", fw->mailbox_reg[cnt]);
+	}
+
+	qla_uprintf(&uiter, "\n\nXSEQ GP Registers");
+	for (cnt = 0; cnt < sizeof(fw->xseq_gp_reg) / 4; cnt++) {
+		if (cnt % 8 == 0)
+			qla_uprintf(&uiter, "\n");
+
+		qla_uprintf(&uiter, "%08x ", fw->xseq_gp_reg[cnt]);
+	}
+
+	qla_uprintf(&uiter, "\n\nXSEQ-0 Registers");
+	for (cnt = 0; cnt < sizeof(fw->xseq_0_reg) / 4; cnt++) {
+		if (cnt % 8 == 0)
+			qla_uprintf(&uiter, "\n");
+
+		qla_uprintf(&uiter, "%08x ", fw->xseq_0_reg[cnt]);
+	}
+
+	qla_uprintf(&uiter, "\n\nXSEQ-1 Registers");
+	for (cnt = 0; cnt < sizeof(fw->xseq_1_reg) / 4; cnt++) {
+		if (cnt % 8 == 0)
+			qla_uprintf(&uiter, "\n");
+
+		qla_uprintf(&uiter, "%08x ", fw->xseq_1_reg[cnt]);
+	}
+
+	qla_uprintf(&uiter, "\n\nRSEQ GP Registers");
+	for (cnt = 0; cnt < sizeof(fw->rseq_gp_reg) / 4; cnt++) {
+		if (cnt % 8 == 0)
+			qla_uprintf(&uiter, "\n");
+
+		qla_uprintf(&uiter, "%08x ", fw->rseq_gp_reg[cnt]);
+	}
+
+	qla_uprintf(&uiter, "\n\nRSEQ-0 Registers");
+	for (cnt = 0; cnt < sizeof(fw->rseq_0_reg) / 4; cnt++) {
+		if (cnt % 8 == 0)
+			qla_uprintf(&uiter, "\n");
+
+		qla_uprintf(&uiter, "%08x ", fw->rseq_0_reg[cnt]);
+	}
+
+	qla_uprintf(&uiter, "\n\nRSEQ-1 Registers");
+	for (cnt = 0; cnt < sizeof(fw->rseq_1_reg) / 4; cnt++) {
+		if (cnt % 8 == 0)
+			qla_uprintf(&uiter, "\n");
+
+		qla_uprintf(&uiter, "%08x ", fw->rseq_1_reg[cnt]);
+	}
+
+	qla_uprintf(&uiter, "\n\nRSEQ-2 Registers");
+	for (cnt = 0; cnt < sizeof(fw->rseq_2_reg) / 4; cnt++) {
+		if (cnt % 8 == 0)
+			qla_uprintf(&uiter, "\n");
+
+		qla_uprintf(&uiter, "%08x ", fw->rseq_2_reg[cnt]);
+	}
+
+	qla_uprintf(&uiter, "\n\nCommand DMA Registers");
+	for (cnt = 0; cnt < sizeof(fw->cmd_dma_reg) / 4; cnt++) {
+		if (cnt % 8 == 0)
+			qla_uprintf(&uiter, "\n");
+
+		qla_uprintf(&uiter, "%08x ", fw->cmd_dma_reg[cnt]);
+	}
+
+	qla_uprintf(&uiter, "\n\nRequest0 Queue DMA Channel Registers");
+	for (cnt = 0; cnt < sizeof(fw->req0_dma_reg) / 4; cnt++) {
+		if (cnt % 8 == 0)
+			qla_uprintf(&uiter, "\n");
+
+		qla_uprintf(&uiter, "%08x ", fw->req0_dma_reg[cnt]);
+	}
+
+	qla_uprintf(&uiter, "\n\nResponse0 Queue DMA Channel Registers");
+	for (cnt = 0; cnt < sizeof(fw->resp0_dma_reg) / 4; cnt++) {
+		if (cnt % 8 == 0)
+			qla_uprintf(&uiter, "\n");
+
+		qla_uprintf(&uiter, "%08x ", fw->resp0_dma_reg[cnt]);
+	}
+
+	qla_uprintf(&uiter, "\n\nRequest1 Queue DMA Channel Registers");
+	for (cnt = 0; cnt < sizeof(fw->req1_dma_reg) / 4; cnt++) {
+		if (cnt % 8 == 0)
+			qla_uprintf(&uiter, "\n");
+
+		qla_uprintf(&uiter, "%08x ", fw->req1_dma_reg[cnt]);
+	}
+
+	qla_uprintf(&uiter, "\n\nXMT0 Data DMA Registers");
+	for (cnt = 0; cnt < sizeof(fw->xmt0_dma_reg) / 4; cnt++) {
+		if (cnt % 8 == 0)
+			qla_uprintf(&uiter, "\n");
+
+		qla_uprintf(&uiter, "%08x ", fw->xmt0_dma_reg[cnt]);
+	}
+
+	qla_uprintf(&uiter, "\n\nXMT1 Data DMA Registers");
+	for (cnt = 0; cnt < sizeof(fw->xmt1_dma_reg) / 4; cnt++) {
+		if (cnt % 8 == 0)
+			qla_uprintf(&uiter, "\n");
+
+		qla_uprintf(&uiter, "%08x ", fw->xmt1_dma_reg[cnt]);
+	}
+
+	qla_uprintf(&uiter, "\n\nXMT2 Data DMA Registers");
+	for (cnt = 0; cnt < sizeof(fw->xmt2_dma_reg) / 4; cnt++) {
+		if (cnt % 8 == 0)
+			qla_uprintf(&uiter, "\n");
+
+		qla_uprintf(&uiter, "%08x ", fw->xmt2_dma_reg[cnt]);
+	}
+
+	qla_uprintf(&uiter, "\n\nXMT3 Data DMA Registers");
+	for (cnt = 0; cnt < sizeof(fw->xmt3_dma_reg) / 4; cnt++) {
+		if (cnt % 8 == 0)
+			qla_uprintf(&uiter, "\n");
+
+		qla_uprintf(&uiter, "%08x ", fw->xmt3_dma_reg[cnt]);
+	}
+
+	qla_uprintf(&uiter, "\n\nXMT4 Data DMA Registers");
+	for (cnt = 0; cnt < sizeof(fw->xmt4_dma_reg) / 4; cnt++) {
+		if (cnt % 8 == 0)
+			qla_uprintf(&uiter, "\n");
+
+		qla_uprintf(&uiter, "%08x ", fw->xmt4_dma_reg[cnt]);
+	}
+
+	qla_uprintf(&uiter, "\n\nXMT Data DMA Common Registers");
+	for (cnt = 0; cnt < sizeof(fw->xmt_data_dma_reg) / 4; cnt++) {
+		if (cnt % 8 == 0)
+			qla_uprintf(&uiter, "\n");
+
+		qla_uprintf(&uiter, "%08x ", fw->xmt_data_dma_reg[cnt]);
+	}
+
+	qla_uprintf(&uiter, "\n\nRCV Thread 0 Data DMA Registers");
+	for (cnt = 0; cnt < sizeof(fw->rcvt0_data_dma_reg) / 4; cnt++) {
+		if (cnt % 8 == 0)
+			qla_uprintf(&uiter, "\n");
+
+		qla_uprintf(&uiter, "%08x ", fw->rcvt0_data_dma_reg[cnt]);
+	}
+
+	qla_uprintf(&uiter, "\n\nRCV Thread 1 Data DMA Registers");
+	for (cnt = 0; cnt < sizeof(fw->rcvt1_data_dma_reg) / 4; cnt++) {
+		if (cnt % 8 == 0)
+			qla_uprintf(&uiter, "\n");
+
+		qla_uprintf(&uiter, "%08x ", fw->rcvt1_data_dma_reg[cnt]);
+	}
+
+	qla_uprintf(&uiter, "\n\nRISC GP Registers");
+	for (cnt = 0; cnt < sizeof(fw->risc_gp_reg) / 4; cnt++) {
+		if (cnt % 8 == 0)
+			qla_uprintf(&uiter, "\n");
+
+		qla_uprintf(&uiter, "%08x ", fw->risc_gp_reg[cnt]);
+	}
+
+	qla_uprintf(&uiter, "\n\nShadow Registers");
+	for (cnt = 0; cnt < sizeof(fw->shadow_reg) / 4; cnt++) {
+		if (cnt % 8 == 0)
+			qla_uprintf(&uiter, "\n");
+
+		qla_uprintf(&uiter, "%08x ", fw->shadow_reg[cnt]);
+	}
+
+	qla_uprintf(&uiter, "\n\nLMC Registers");
+	for (cnt = 0; cnt < sizeof(fw->lmc_reg) / 4; cnt++) {
+		if (cnt % 8 == 0)
+			qla_uprintf(&uiter, "\n");
+
+		qla_uprintf(&uiter, "%08x ", fw->lmc_reg[cnt]);
+	}
+
+	qla_uprintf(&uiter, "\n\nFPM Hardware Registers");
+	for (cnt = 0; cnt < sizeof(fw->fpm_hdw_reg) / 4; cnt++) {
+		if (cnt % 8 == 0)
+			qla_uprintf(&uiter, "\n");
+
+		qla_uprintf(&uiter, "%08x ", fw->fpm_hdw_reg[cnt]);
+	}
+
+	qla_uprintf(&uiter, "\n\nFB Hardware Registers");
+	for (cnt = 0; cnt < sizeof(fw->fb_hdw_reg) / 4; cnt++) {
+		if (cnt % 8 == 0)
+			qla_uprintf(&uiter, "\n");
+
+		qla_uprintf(&uiter, "%08x ", fw->fb_hdw_reg[cnt]);
+	}
+
+	qla_uprintf(&uiter, "\n\nCode RAM");
+	for (cnt = 0; cnt < sizeof (fw->code_ram) / 4; cnt++) {
+		if (cnt % 8 == 0) {
+			qla_uprintf(&uiter, "\n%08x: ", cnt + 0x20000);
+		}
+		qla_uprintf(&uiter, "%08x ", fw->code_ram[cnt]);
+	}
+
+	qla_uprintf(&uiter, "\n\nExternal Memory");
+	ext_mem_cnt = ha->fw_memory_size - 0x100000 + 1;
+	for (cnt = 0; cnt < ext_mem_cnt; cnt++) {
+		if (cnt % 8 == 0) {
+			qla_uprintf(&uiter, "\n%08x: ", cnt + 0x100000);
+		}
+		qla_uprintf(&uiter, "%08x ", fw->ext_mem[cnt]);
+	}
+
+	qla_uprintf(&uiter, "\n[<==END] ISP Debug Dump");
+}
+
 
 /****************************************************************************/
 /*                         Driver Debug Functions.                          */
 /****************************************************************************/
 
-void 
-qla2x00_dump_regs(scsi_qla_host_t *ha) 
+void
+qla2x00_dump_regs(scsi_qla_host_t *ha)
 {
-	device_reg_t __iomem *reg = ha->iobase;
+	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
 
 	printk("Mailbox registers:\n");
 	printk("scsi(%ld): mbox 0 0x%04x \n",
@@ -1003,7 +1946,7 @@ qla2x00_dump_regs(scsi_qla_host_t *ha) 
 
 
 void
-qla2x00_dump_buffer(uint8_t * b, uint32_t size) 
+qla2x00_dump_buffer(uint8_t * b, uint32_t size)
 {
 	uint32_t cnt;
 	uint8_t c;
@@ -1029,11 +1972,11 @@ qla2x00_dump_buffer(uint8_t * b, uint32_
 /**************************************************************************
  *   qla2x00_print_scsi_cmd
  *	 Dumps out info about the scsi cmd and srb.
- *   Input	 
+ *   Input
  *	 cmd : struct scsi_cmnd
  **************************************************************************/
 void
-qla2x00_print_scsi_cmd(struct scsi_cmnd * cmd) 
+qla2x00_print_scsi_cmd(struct scsi_cmnd * cmd)
 {
 	int i;
 	struct scsi_qla_host *ha;
@@ -1056,15 +1999,29 @@ qla2x00_print_scsi_cmd(struct scsi_cmnd 
 	    cmd->request_buffer, cmd->request_bufflen);
 	printk("  tag=%d, transfersize=0x%x\n",
 	    cmd->tag, cmd->transfersize);
-	printk("  serial_number=%lx, SP=%p\n", cmd->serial_number, sp); 
+	printk("  serial_number=%lx, SP=%p\n", cmd->serial_number, sp);
 	printk("  data direction=%d\n", cmd->sc_data_direction);
 
 	if (!sp)
 		return;
 
 	printk("  sp flags=0x%x\n", sp->flags);
-	printk("  r_start=0x%lx, u_start=0x%lx, f_start=0x%lx, state=%d\n",
-	    sp->r_start, sp->u_start, sp->f_start, sp->state);
+	printk("  state=%d\n", sp->state);
+}
+
+void
+qla2x00_dump_pkt(void *pkt)
+{
+	uint32_t i;
+	uint8_t *data = (uint8_t *) pkt;
+
+	for (i = 0; i < 64; i++) {
+		if (!(i % 4))
+			printk("\n%02x: ", i);
+
+		printk("%02x ", data[i]);
+	}
+	printk("\n");
 }
 
 #if defined(QL_DEBUG_ROUTINES)
@@ -1079,8 +2036,8 @@ qla2x00_print_scsi_cmd(struct scsi_cmnd 
  *       count   = number of words.
  */
 void
-qla2x00_formatted_dump_buffer(char *string, uint8_t * buffer, 
-				uint8_t wd_size, uint32_t count) 
+qla2x00_formatted_dump_buffer(char *string, uint8_t * buffer,
+				uint8_t wd_size, uint32_t count)
 {
 	uint32_t cnt;
 	uint16_t *buf16;
diff --git a/drivers/scsi/qla2xxx/qla_dbg.h b/drivers/scsi/qla2xxx/qla_dbg.h
--- a/drivers/scsi/qla2xxx/qla_dbg.h
+++ b/drivers/scsi/qla2xxx/qla_dbg.h
@@ -2,7 +2,7 @@
  *                  QLOGIC LINUX SOFTWARE
  *
  * QLogic ISP2x00 device driver for Linux 2.6.x
- * Copyright (C) 2003-2004 QLogic Corporation
+ * Copyright (C) 2003-2005 QLogic Corporation
  * (www.qlogic.com)
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -230,4 +230,36 @@ struct qla2100_fw_dump {
 	uint16_t risc_ram[0xf000];
 };
 
+#define FW_DUMP_SIZE_24XX	0x2B0000
 
+struct qla24xx_fw_dump {
+	uint32_t hccr;
+	uint32_t host_reg[32];
+	uint16_t mailbox_reg[32];
+	uint32_t xseq_gp_reg[128];
+	uint32_t xseq_0_reg[16];
+	uint32_t xseq_1_reg[16];
+	uint32_t rseq_gp_reg[128];
+	uint32_t rseq_0_reg[16];
+	uint32_t rseq_1_reg[16];
+	uint32_t rseq_2_reg[16];
+	uint32_t cmd_dma_reg[16];
+	uint32_t req0_dma_reg[15];
+	uint32_t resp0_dma_reg[15];
+	uint32_t req1_dma_reg[15];
+	uint32_t xmt0_dma_reg[32];
+	uint32_t xmt1_dma_reg[32];
+	uint32_t xmt2_dma_reg[32];
+	uint32_t xmt3_dma_reg[32];
+	uint32_t xmt4_dma_reg[32];
+	uint32_t xmt_data_dma_reg[16];
+	uint32_t rcvt0_data_dma_reg[32];
+	uint32_t rcvt1_data_dma_reg[32];
+	uint32_t risc_gp_reg[128];
+	uint32_t shadow_reg[7];
+	uint32_t lmc_reg[112];
+	uint32_t fpm_hdw_reg[192];
+	uint32_t fb_hdw_reg[176];
+	uint32_t code_ram[0x2000];
+	uint32_t ext_mem[1];
+};
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -2,7 +2,7 @@
 *                  QLOGIC LINUX SOFTWARE
 *
 * QLogic ISP2x00 device driver for Linux 2.6.x
-* Copyright (C) 2003-2004 QLogic Corporation
+* Copyright (C) 2003-2005 QLogic Corporation
 * (www.qlogic.com)
 *
 * This program is free software; you can redistribute it and/or modify it
@@ -33,6 +33,7 @@
 #include <linux/mempool.h>
 #include <linux/spinlock.h>
 #include <linux/completion.h>
+#include <linux/interrupt.h>
 #include <asm/semaphore.h>
 
 #include <scsi/scsi.h>
@@ -40,27 +41,6 @@
 #include <scsi/scsi_device.h>
 #include <scsi/scsi_cmnd.h>
 
-/* XXX(hch): move to pci_ids.h */
-#ifndef PCI_DEVICE_ID_QLOGIC_ISP2300
-#define PCI_DEVICE_ID_QLOGIC_ISP2300	0x2300
-#endif
-
-#ifndef PCI_DEVICE_ID_QLOGIC_ISP2312
-#define PCI_DEVICE_ID_QLOGIC_ISP2312	0x2312
-#endif
-
-#ifndef PCI_DEVICE_ID_QLOGIC_ISP2322
-#define PCI_DEVICE_ID_QLOGIC_ISP2322	0x2322
-#endif
-
-#ifndef PCI_DEVICE_ID_QLOGIC_ISP6312
-#define PCI_DEVICE_ID_QLOGIC_ISP6312	0x6312
-#endif
-
-#ifndef PCI_DEVICE_ID_QLOGIC_ISP6322
-#define PCI_DEVICE_ID_QLOGIC_ISP6322	0x6322
-#endif
-
 #if defined(CONFIG_SCSI_QLA21XX) || defined(CONFIG_SCSI_QLA21XX_MODULE)
 #define IS_QLA2100(ha)	((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2100)
 #else
@@ -95,9 +75,28 @@
 #define IS_QLA6322(ha)	0
 #endif
 
+#if defined(CONFIG_SCSI_QLA24XX) || defined(CONFIG_SCSI_QLA24XX_MODULE)
+#define IS_QLA2422(ha)	((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2422)
+#define IS_QLA2432(ha)	((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2432)
+#else
+#define IS_QLA2422(ha)	0
+#define IS_QLA2432(ha)	0
+#endif
+
+#if defined(CONFIG_SCSI_QLA25XX) || defined(CONFIG_SCSI_QLA25XX_MODULE)
+#define IS_QLA2512(ha)	((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2512)
+#define IS_QLA2522(ha)	((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2522)
+#else
+#define IS_QLA2512(ha)	0
+#define IS_QLA2522(ha)	0
+#endif
+
 #define IS_QLA23XX(ha)	(IS_QLA2300(ha) || IS_QLA2312(ha) || IS_QLA2322(ha) || \
     			 IS_QLA6312(ha) || IS_QLA6322(ha))
 
+#define IS_QLA24XX(ha)	(IS_QLA2422(ha) || IS_QLA2432(ha))
+#define IS_QLA25XX(ha)	(IS_QLA2512(ha) || IS_QLA2522(ha))
+
 /*
  * Only non-ISP2[12]00 have extended addressing support in the firmware.
  */
@@ -117,7 +116,7 @@
 
 #include "qla_settings.h"
 
-/* 
+/*
  * Data bit definitions
  */
 #define BIT_0	0x1
@@ -182,7 +181,7 @@
  */
 #define WWN_SIZE		8	/* Size of WWPN, WWN & WWNN */
 #define MAX_FIBRE_DEVICES	512
-#define MAX_FIBRE_LUNS  	256
+#define MAX_FIBRE_LUNS  	0xFFFF
 #define	MAX_RSCN_COUNT		32
 #define	MAX_HOST_COUNT		16
 
@@ -192,11 +191,10 @@
 #define MAX_BUSES		1  /* We only have one bus today */
 #define MAX_TARGETS_2100	MAX_FIBRE_DEVICES
 #define MAX_TARGETS_2200	MAX_FIBRE_DEVICES
-#define MAX_TARGETS		MAX_FIBRE_DEVICES
 #define MIN_LUNS		8
 #define MAX_LUNS		MAX_FIBRE_LUNS
-#define MAX_CMDS_PER_LUN	255 
-                                    
+#define MAX_CMDS_PER_LUN	255
+
 /*
  * Fibre Channel device definitions.
  */
@@ -211,10 +209,18 @@
 #define MANAGEMENT_SERVER	0xfe
 #define BROADCAST		0xff
 
-#define RESERVED_LOOP_ID(x)	((x > LAST_LOCAL_LOOP_ID && \
-				 x < SNS_FIRST_LOOP_ID) || \
-				 x == MANAGEMENT_SERVER || \
-				 x == BROADCAST)
+/*
+ * There is no correspondence between an N-PORT id and an AL_PA.  Therefore the
+ * valid range of an N-PORT id is 0 through 0x7ef.
+ */
+#define NPH_LAST_HANDLE		0x7ef
+#define NPH_SNS			0x7fc		/*  FFFFFC */
+#define NPH_FABRIC_CONTROLLER	0x7fd		/*  FFFFFD */
+#define NPH_F_PORT		0x7fe		/*  FFFFFE */
+#define NPH_IP_BROADCAST	0x7ff		/*  FFFFFF */
+
+#define MAX_CMDSZ	16		/* SCSI maximum CDB size. */
+#include "qla_fw.h"
 
 /*
  * Timeout timer counts in seconds
@@ -231,11 +237,12 @@
 #define REQUEST_ENTRY_CNT_2100		128	/* Number of request entries. */
 #define REQUEST_ENTRY_CNT_2200		2048	/* Number of request entries. */
 #define REQUEST_ENTRY_CNT_2XXX_EXT_MEM	4096	/* Number of request entries. */
+#define REQUEST_ENTRY_CNT_24XX		4096	/* Number of request entries. */
 #define RESPONSE_ENTRY_CNT_2100		64	/* Number of response entries.*/
 #define RESPONSE_ENTRY_CNT_2300		512	/* Number of response entries.*/
 
 /*
- * SCSI Request Block 
+ * SCSI Request Block
  */
 typedef struct srb {
 	struct list_head list;
@@ -246,37 +253,18 @@ typedef struct srb {
 	struct scsi_cmnd *cmd;		/* Linux SCSI command pkt */
 
 	struct timer_list timer;	/* Command timer */
-	atomic_t ref_count;	/* Reference count for this structure */			
+	atomic_t ref_count;	/* Reference count for this structure */
 	uint16_t flags;
 
 	/* Request state */
 	uint16_t state;
 
-	/* Timing counts. */
-	unsigned long e_start;		/* Start of extend timeout */
-	unsigned long r_start;		/* Start of request */
-	unsigned long u_start;		/* When sent to RISC */
-	unsigned long f_start;		/* When placed in FO queue*/
-
 	/* Single transfer DMA context */
 	dma_addr_t dma_handle;
 
 	uint32_t request_sense_length;
 	uint8_t *request_sense_ptr;
 
-	int ext_history;
-
-	/* Suspend delay */
-	int delay;
-
-	/* Raw completion info for use by failover ? */
-	uint8_t	fo_retry_cnt;		/* Retry count this request */
-	uint8_t	err_id;			/* error id */
-#define SRB_ERR_PORT	1		/* Request failed -- "port down" */
-#define SRB_ERR_LOOP	2		/* Request failed -- "loop down" */
-#define SRB_ERR_DEVICE	3		/* Request failed -- "device error" */
-#define SRB_ERR_OTHER	4
-
 	/* SRB magic number */
 	uint16_t magic;
 #define SRB_MAGIC       0x10CB
@@ -318,24 +306,24 @@ typedef struct srb {
 /*
  * ISP I/O Register Set structure definitions.
  */
-typedef volatile struct {
-	volatile uint16_t flash_address; /* Flash BIOS address */
-	volatile uint16_t flash_data;	/* Flash BIOS data */
+struct device_reg_2xxx {
+	uint16_t flash_address; 	/* Flash BIOS address */
+	uint16_t flash_data;		/* Flash BIOS data */
 	uint16_t unused_1[1];		/* Gap */
-	volatile uint16_t ctrl_status;	/* Control/Status */
-#define CSR_FLASH_64K_BANK	BIT_3	/* Flash upper 64K bank select */ 
+	uint16_t ctrl_status;		/* Control/Status */
+#define CSR_FLASH_64K_BANK	BIT_3	/* Flash upper 64K bank select */
 #define CSR_FLASH_ENABLE	BIT_1	/* Flash BIOS Read/Write enable */
 #define CSR_ISP_SOFT_RESET	BIT_0	/* ISP soft reset */
 
-	volatile uint16_t ictrl;	/* Interrupt control */
+	uint16_t ictrl;			/* Interrupt control */
 #define ICR_EN_INT		BIT_15	/* ISP enable interrupts. */
 #define ICR_EN_RISC		BIT_3	/* ISP enable RISC interrupts. */
 
-	volatile uint16_t istatus;	/* Interrupt status */
+	uint16_t istatus;		/* Interrupt status */
 #define ISR_RISC_INT		BIT_3	/* RISC interrupt */
 
-	volatile uint16_t semaphore;	/* Semaphore */
-	volatile uint16_t nvram;	/* NVRAM register. */
+	uint16_t semaphore;		/* Semaphore */
+	uint16_t nvram;			/* NVRAM register. */
 #define NVR_DESELECT		0
 #define NVR_BUSY		BIT_15
 #define NVR_WRT_ENABLE		BIT_14	/* Write enable */
@@ -347,78 +335,78 @@ typedef volatile struct {
 
 	union {
 		struct {
-			volatile uint16_t mailbox0;
-			volatile uint16_t mailbox1;
-			volatile uint16_t mailbox2;
-			volatile uint16_t mailbox3;
-			volatile uint16_t mailbox4;
-			volatile uint16_t mailbox5;
-			volatile uint16_t mailbox6;
-			volatile uint16_t mailbox7;
-			uint16_t unused_2[59];		/* Gap */
+			uint16_t mailbox0;
+			uint16_t mailbox1;
+			uint16_t mailbox2;
+			uint16_t mailbox3;
+			uint16_t mailbox4;
+			uint16_t mailbox5;
+			uint16_t mailbox6;
+			uint16_t mailbox7;
+			uint16_t unused_2[59];	/* Gap */
 		} __attribute__((packed)) isp2100;
 		struct {
-							/* Request Queue */
-			volatile uint16_t req_q_in;	/*  In-Pointer */
-			volatile uint16_t req_q_out;	/*  Out-Pointer */
-							/* Response Queue */
-			volatile uint16_t rsp_q_in;	/*  In-Pointer */
-			volatile uint16_t rsp_q_out;	/*  Out-Pointer */
+						/* Request Queue */
+			uint16_t req_q_in;	/*  In-Pointer */
+			uint16_t req_q_out;	/*  Out-Pointer */
+						/* Response Queue */
+			uint16_t rsp_q_in;	/*  In-Pointer */
+			uint16_t rsp_q_out;	/*  Out-Pointer */
 
 						/* RISC to Host Status */
-			volatile uint32_t host_status;	
+			uint32_t host_status;
 #define HSR_RISC_INT		BIT_15	/* RISC interrupt */
 #define HSR_RISC_PAUSED		BIT_8	/* RISC Paused */
 
 					/* Host to Host Semaphore */
-			volatile uint16_t host_semaphore; 
-			uint16_t unused_3[17];		/* Gap */
-			volatile uint16_t mailbox0;
-			volatile uint16_t mailbox1;
-			volatile uint16_t mailbox2;
-			volatile uint16_t mailbox3;
-			volatile uint16_t mailbox4;
-			volatile uint16_t mailbox5;
-			volatile uint16_t mailbox6;
-			volatile uint16_t mailbox7;
-			volatile uint16_t mailbox8;
-			volatile uint16_t mailbox9;
-			volatile uint16_t mailbox10;
-			volatile uint16_t mailbox11;
-			volatile uint16_t mailbox12;
-			volatile uint16_t mailbox13;
-			volatile uint16_t mailbox14;
-			volatile uint16_t mailbox15;
-			volatile uint16_t mailbox16;
-			volatile uint16_t mailbox17;
-			volatile uint16_t mailbox18;
-			volatile uint16_t mailbox19;
-			volatile uint16_t mailbox20;
-			volatile uint16_t mailbox21;
-			volatile uint16_t mailbox22;
-			volatile uint16_t mailbox23;
-			volatile uint16_t mailbox24;
-			volatile uint16_t mailbox25;
-			volatile uint16_t mailbox26;
-			volatile uint16_t mailbox27;
-			volatile uint16_t mailbox28;
-			volatile uint16_t mailbox29;
-			volatile uint16_t mailbox30;
-			volatile uint16_t mailbox31;
-			volatile uint16_t fb_cmd;
-			uint16_t unused_4[10];		/* Gap */
+			uint16_t host_semaphore;
+			uint16_t unused_3[17];	/* Gap */
+			uint16_t mailbox0;
+			uint16_t mailbox1;
+			uint16_t mailbox2;
+			uint16_t mailbox3;
+			uint16_t mailbox4;
+			uint16_t mailbox5;
+			uint16_t mailbox6;
+			uint16_t mailbox7;
+			uint16_t mailbox8;
+			uint16_t mailbox9;
+			uint16_t mailbox10;
+			uint16_t mailbox11;
+			uint16_t mailbox12;
+			uint16_t mailbox13;
+			uint16_t mailbox14;
+			uint16_t mailbox15;
+			uint16_t mailbox16;
+			uint16_t mailbox17;
+			uint16_t mailbox18;
+			uint16_t mailbox19;
+			uint16_t mailbox20;
+			uint16_t mailbox21;
+			uint16_t mailbox22;
+			uint16_t mailbox23;
+			uint16_t mailbox24;
+			uint16_t mailbox25;
+			uint16_t mailbox26;
+			uint16_t mailbox27;
+			uint16_t mailbox28;
+			uint16_t mailbox29;
+			uint16_t mailbox30;
+			uint16_t mailbox31;
+			uint16_t fb_cmd;
+			uint16_t unused_4[10];	/* Gap */
 		} __attribute__((packed)) isp2300;
 	} u;
 
-	volatile uint16_t fpm_diag_config;
+	uint16_t fpm_diag_config;
 	uint16_t unused_5[0x6];		/* Gap */
-	volatile uint16_t pcr;		/* Processor Control Register. */
+	uint16_t pcr;			/* Processor Control Register. */
 	uint16_t unused_6[0x5];		/* Gap */
-	volatile uint16_t mctr;		/* Memory Configuration and Timing. */
+	uint16_t mctr;			/* Memory Configuration and Timing. */
 	uint16_t unused_7[0x3];		/* Gap */
-	volatile uint16_t fb_cmd_2100;	/* Unused on 23XX */
+	uint16_t fb_cmd_2100;		/* Unused on 23XX */
 	uint16_t unused_8[0x3];		/* Gap */
-	volatile uint16_t hccr;		/* Host command & control register. */
+	uint16_t hccr;			/* Host command & control register. */
 #define HCCR_HOST_INT		BIT_7	/* Host interrupt bit */
 #define HCCR_RISC_PAUSE		BIT_5	/* Pause mode bit */
 					/* HCCR commands */
@@ -432,8 +420,8 @@ typedef volatile struct {
 #define HCCR_ENABLE_PARITY	0xA000	/* Enable PARITY interrupt */
 
 	uint16_t unused_9[5];		/* Gap */
-	volatile uint16_t gpiod;	/* GPIO Data register. */
-	volatile uint16_t gpioe;	/* GPIO Enable register. */
+	uint16_t gpiod;			/* GPIO Data register. */
+	uint16_t gpioe;			/* GPIO Enable register. */
 #define GPIO_LED_MASK			0x00C0
 #define GPIO_LED_GREEN_OFF_AMBER_OFF	0x0000
 #define GPIO_LED_GREEN_ON_AMBER_OFF	0x0040
@@ -442,25 +430,30 @@ typedef volatile struct {
 
 	union {
 		struct {
-			uint16_t unused_10[8];		/* Gap */
-			volatile uint16_t mailbox8;
-			volatile uint16_t mailbox9;
-			volatile uint16_t mailbox10;
-			volatile uint16_t mailbox11;
-			volatile uint16_t mailbox12;
-			volatile uint16_t mailbox13;
-			volatile uint16_t mailbox14;
-			volatile uint16_t mailbox15;
-			volatile uint16_t mailbox16;
-			volatile uint16_t mailbox17;
-			volatile uint16_t mailbox18;
-			volatile uint16_t mailbox19;
-			volatile uint16_t mailbox20;
-			volatile uint16_t mailbox21;
-			volatile uint16_t mailbox22;
-			volatile uint16_t mailbox23;	/* Also probe reg. */
+			uint16_t unused_10[8];	/* Gap */
+			uint16_t mailbox8;
+			uint16_t mailbox9;
+			uint16_t mailbox10;
+			uint16_t mailbox11;
+			uint16_t mailbox12;
+			uint16_t mailbox13;
+			uint16_t mailbox14;
+			uint16_t mailbox15;
+			uint16_t mailbox16;
+			uint16_t mailbox17;
+			uint16_t mailbox18;
+			uint16_t mailbox19;
+			uint16_t mailbox20;
+			uint16_t mailbox21;
+			uint16_t mailbox22;
+			uint16_t mailbox23;	/* Also probe reg. */
 		} __attribute__((packed)) isp2200;
 	} u_end;
+};
+
+typedef union {
+		struct device_reg_2xxx isp;
+		struct device_reg_24xx isp24;
 } device_reg_t;
 
 #define ISP_REQ_Q_IN(ha, reg) \
@@ -543,6 +536,8 @@ typedef struct {
 #define MBS_LOOP_ID_USED		0x4008
 #define MBS_ALL_IDS_IN_USE		0x4009
 #define MBS_NOT_LOGGED_IN		0x400A
+#define MBS_LINK_DOWN_ERROR		0x400B
+#define MBS_DIAG_ECHO_TEST_ERROR	0x400C
 
 /*
  * ISP mailbox asynchronous event status codes
@@ -594,7 +589,7 @@ typedef struct {
 #define FO1_CTIO_RETRY			BIT_3
 #define FO1_DISABLE_LIP_F7_SW		BIT_4
 #define FO1_DISABLE_100MS_LOS_WAIT	BIT_5
-#define FO1_DISABLE_GPIO6_7		BIT_6
+#define FO1_DISABLE_GPIO6_7		BIT_6	/* LED bits */
 #define FO1_AE_ON_LOOP_INIT_ERR		BIT_7
 #define FO1_SET_EMPHASIS_SWING		BIT_8
 #define FO1_AE_AUTO_BYPASS		BIT_9
@@ -609,6 +604,15 @@ typedef struct {
 #define FO3_ENABLE_EMERG_IOCB		BIT_0
 #define FO3_AE_RND_ERROR		BIT_1
 
+/* 24XX additional firmware options */
+#define ADD_FO_COUNT			3
+#define ADD_FO1_DISABLE_GPIO_LED_CTRL	BIT_6	/* LED bits */
+#define ADD_FO1_ENABLE_PUREX_IOCB	BIT_10
+
+#define ADD_FO2_ENABLE_SEL_CLS2		BIT_5
+
+#define ADD_FO3_NO_ABT_ON_LINK_DOWN	BIT_14
+
 /*
  * ISP mailbox commands
  */
@@ -677,6 +681,22 @@ typedef struct {
 #define MBC_SEND_LFA_COMMAND		0x7D	/* Send Loop Fabric Address */
 #define MBC_LUN_RESET			0x7E	/* Send LUN reset */
 
+/*
+ * ISP24xx mailbox commands
+ */
+#define MBC_SERDES_PARAMS		0x10	/* Serdes Tx Parameters. */
+#define MBC_GET_IOCB_STATUS		0x12	/* Get IOCB status command. */
+#define MBC_GET_TIMEOUT_PARAMS		0x22	/* Get FW timeouts. */
+#define MBC_GEN_SYSTEM_ERROR		0x2a	/* Generate System Error. */
+#define MBC_SET_TIMEOUT_PARAMS		0x32	/* Set FW timeouts. */
+#define MBC_MID_INITIALIZE_FIRMWARE	0x48	/* MID Initialize firmware. */
+#define MBC_MID_GET_VP_DATABASE		0x49	/* MID Get VP Database. */
+#define MBC_MID_GET_VP_ENTRY		0x4a	/* MID Get VP Entry. */
+#define MBC_HOST_MEMORY_COPY		0x53	/* Host Memory Copy. */
+#define MBC_SEND_RNFT_ELS		0x5e	/* Send RNFT ELS request */
+#define MBC_GET_LINK_PRIV_STATS		0x6d	/* Get link & private data. */
+#define MBC_SET_VENDOR_ID		0x76	/* Set Vendor ID. */
+
 /* Firmware return data sizes */
 #define FCAL_MAP_SIZE	128
 
@@ -906,6 +926,9 @@ typedef struct {
 /*
  * Get Link Status mailbox command return buffer.
  */
+#define GLSO_SEND_RPS	BIT_0
+#define GLSO_USE_DID	BIT_3
+
 typedef struct {
 	uint32_t	link_fail_cnt;
 	uint32_t	loss_sync_cnt;
@@ -1031,7 +1054,7 @@ typedef struct {
 	 * LSB BIT 5 = Rx Sensitivity 1G bit 1
 	 * LSB BIT 6 = Rx Sensitivity 1G bit 2
 	 * LSB BIT 7 = Rx Sensitivity 1G bit 3
-	 *            
+	 *
 	 * MSB BIT 0 = Tx Sensitivity 2G bit 0
 	 * MSB BIT 1 = Tx Sensitivity 2G bit 1
 	 * MSB BIT 2 = Tx Sensitivity 2G bit 2
@@ -1049,7 +1072,7 @@ typedef struct {
 	 * LSB BIT 5 = Output Swing 2G bit 0
 	 * LSB BIT 6 = Output Swing 2G bit 1
 	 * LSB BIT 7 = Output Swing 2G bit 2
-	 *            
+	 *
 	 * MSB BIT 0 = Output Emphasis 2G bit 0
 	 * MSB BIT 1 = Output Emphasis 2G bit 1
 	 * MSB BIT 2 = Output Enable
@@ -1200,7 +1223,6 @@ do {							\
  * ISP queue - command entry structure definition.
  */
 #define COMMAND_TYPE	0x11		/* Command entry */
-#define MAX_CMDSZ	16		/* SCSI maximum CDB size. */
 typedef struct {
 	uint8_t entry_type;		/* Entry type. */
 	uint8_t entry_count;		/* Entry count. */
@@ -1323,11 +1345,16 @@ typedef struct {
 /*
  * Status entry entry status
  */
+#define RF_RQ_DMA_ERROR	BIT_6		/* Request Queue DMA error. */
 #define RF_INV_E_ORDER	BIT_5		/* Invalid entry order. */
 #define RF_INV_E_COUNT	BIT_4		/* Invalid entry count. */
 #define RF_INV_E_PARAM	BIT_3		/* Invalid entry parameter. */
 #define RF_INV_E_TYPE	BIT_2		/* Invalid entry type. */
 #define RF_BUSY		BIT_1		/* Busy */
+#define RF_MASK		(RF_RQ_DMA_ERROR | RF_INV_E_ORDER | RF_INV_E_COUNT | \
+			 RF_INV_E_PARAM | RF_INV_E_TYPE | RF_BUSY)
+#define RF_MASK_24XX	(RF_INV_E_ORDER | RF_INV_E_COUNT | RF_INV_E_PARAM | \
+			 RF_INV_E_TYPE)
 
 /*
  * Status entry SCSI status bit definitions.
@@ -1542,9 +1569,6 @@ typedef struct {
 	port_id_t d_id;
 	uint8_t node_name[WWN_SIZE];
 	uint8_t port_name[WWN_SIZE];
-	uint32_t type;
-#define SW_TYPE_IP	BIT_1
-#define SW_TYPE_SCSI	BIT_0
 } sw_info_t;
 
 /*
@@ -1559,6 +1583,8 @@ typedef struct {
 	union {
 		cmd_a64_entry_t cmd;
 		sts_entry_t rsp;
+		struct cmd_type_7 cmd24;
+		struct sts_entry_24xx rsp24;
 	} p;
 	uint8_t inq[INQ_DATA_SIZE];
 } inq_cmd_rsp_t;
@@ -1594,10 +1620,13 @@ typedef struct {
 	union {
 		cmd_a64_entry_t cmd;
 		sts_entry_t rsp;
+		struct cmd_type_7 cmd24;
+		struct sts_entry_24xx rsp24;
 	} p;
 	rpt_lun_lst_t list;
 } rpt_lun_cmd_rsp_t;
 
+
 /*
  * Fibre channel port type.
  */
@@ -1685,6 +1714,7 @@ typedef struct fc_port {
 #define FCF_FAILOVER_DISABLE	BIT_22
 #define FCF_DSXXX_DEVICE	BIT_23
 #define FCF_AA_EVA_DEVICE	BIT_24
+#define FCF_AA_MSA_DEVICE	BIT_25
 
 /* No loop ID flag. */
 #define FC_NO_LOOP_ID		0x1000
@@ -1956,19 +1986,63 @@ struct qla_board_info {
 
 	char isp_name[8];
 	struct qla_fw_info *fw_info;
+	char *fw_fname;
+	struct scsi_host_template *sht;
 };
 
 /* Return data from MBC_GET_ID_LIST call. */
 struct gid_list_info {
 	uint8_t	al_pa;
 	uint8_t	area;
-	uint8_t	domain;		
+	uint8_t	domain;
 	uint8_t	loop_id_2100;	/* ISP2100/ISP2200 -- 4 bytes. */
 	uint16_t loop_id;	/* ISP23XX         -- 6 bytes. */
+	uint16_t reserved_1;	/* ISP24XX         -- 8 bytes. */
 };
 #define GID_LIST_SIZE (sizeof(struct gid_list_info) * MAX_FIBRE_DEVICES)
 
 /*
+ * ISP operations
+ */
+struct isp_operations {
+
+	int (*pci_config) (struct scsi_qla_host *);
+	void (*reset_chip) (struct scsi_qla_host *);
+	int (*chip_diag) (struct scsi_qla_host *);
+	void (*config_rings) (struct scsi_qla_host *);
+	void (*reset_adapter) (struct scsi_qla_host *);
+	int (*nvram_config) (struct scsi_qla_host *);
+	void (*update_fw_options) (struct scsi_qla_host *);
+	int (*load_risc) (struct scsi_qla_host *, uint32_t *);
+
+	char * (*pci_info_str) (struct scsi_qla_host *, char *);
+	char * (*fw_version_str) (struct scsi_qla_host *, char *);
+
+	irqreturn_t (*intr_handler) (int, void *, struct pt_regs *);
+	void (*enable_intrs) (struct scsi_qla_host *);
+	void (*disable_intrs) (struct scsi_qla_host *);
+
+	int (*abort_command) (struct scsi_qla_host *, srb_t *);
+	int (*abort_target) (struct fc_port *);
+	int (*fabric_login) (struct scsi_qla_host *, uint16_t, uint8_t,
+		uint8_t, uint8_t, uint16_t *, uint8_t);
+	int (*fabric_logout) (struct scsi_qla_host *, uint16_t, uint8_t,
+	    uint8_t, uint8_t);
+
+	uint16_t (*calc_req_entries) (uint16_t);
+	void (*build_iocbs) (srb_t *, cmd_entry_t *, uint16_t);
+	void * (*prep_ms_iocb) (struct scsi_qla_host *, uint32_t, uint32_t);
+
+	uint8_t * (*read_nvram) (struct scsi_qla_host *, uint8_t *,
+		uint32_t, uint32_t);
+	int (*write_nvram) (struct scsi_qla_host *, uint8_t *, uint32_t,
+		uint32_t);
+
+	void (*fw_dump) (struct scsi_qla_host *, int);
+	void (*ascii_fw_dump) (struct scsi_qla_host *);
+};
+
+/*
  * Linux Host Adapter structure
  */
 typedef struct scsi_qla_host {
@@ -1998,6 +2072,8 @@ typedef struct scsi_qla_host {
 		uint32_t	enable_lip_full_login	:1;
 		uint32_t	enable_target_reset	:1;
 		uint32_t	enable_led_scheme	:1;
+		uint32_t	msi_enabled		:1;
+		uint32_t	msix_enabled		:1;
 	} flags;
 
 	atomic_t	loop_state;
@@ -2032,8 +2108,9 @@ typedef struct scsi_qla_host {
 #define ISP_ABORT_RETRY         20      /* ISP aborted. */
 #define FCPORT_RESCAN_NEEDED	21      /* IO descriptor processing needed */
 #define IODESC_PROCESS_NEEDED	22      /* IO descriptor processing needed */
-#define IOCTL_ERROR_RECOVERY	23      
+#define IOCTL_ERROR_RECOVERY	23
 #define LOOP_RESET_NEEDED	24
+#define BEACON_BLINK_NEEDED	25
 
 	uint32_t	device_flags;
 #define DFLG_LOCAL_DEVICES		BIT_0
@@ -2046,7 +2123,7 @@ typedef struct scsi_qla_host {
 #define SRB_MIN_REQ	128
 	mempool_t	*srb_mempool;
 
-	/* This spinlock is used to protect "io transactions", you must	
+	/* This spinlock is used to protect "io transactions", you must
 	 * aquire it before doing any IO to the card, eg with RD_REG*() and
 	 * WRT_REG*() for the duration of your entire commandtransaction.
 	 *
@@ -2073,32 +2150,16 @@ typedef struct scsi_qla_host {
 	response_t      *response_ring_ptr; /* Current address. */
 	uint16_t        rsp_ring_index;     /* Current index. */
 	uint16_t	response_q_length;
-    
-	uint16_t	(*calc_request_entries)(uint16_t);
-	void		(*build_scsi_iocbs)(srb_t *, cmd_entry_t *, uint16_t);
+
+	struct isp_operations isp_ops;
 
 	/* Outstandings ISP commands. */
 	srb_t		*outstanding_cmds[MAX_OUTSTANDING_COMMANDS];
-	uint32_t	current_outstanding_cmd; 
+	uint32_t	current_outstanding_cmd;
 	srb_t		*status_srb;	/* Status continuation entry. */
 
-	unsigned long	last_irq_cpu;	/* cpu where we got our last irq */
-
 	uint16_t           revision;
 	uint8_t           ports;
-	u_long            actthreads;
-	u_long            ipreq_cnt;
-	u_long            qthreads;
-
-	uint32_t        total_isr_cnt;		/* Interrupt count */
-	uint32_t        total_isp_aborts;	/* controller err cnt */
-	uint32_t        total_lip_cnt;		/* LIP cnt */
-	uint32_t	total_dev_errs;		/* device error cnt */
-	uint32_t	total_ios;		/* IO cnt */
-	uint64_t	total_bytes;		/* xfr byte cnt */
-	uint32_t	total_mbx_timeout;	/* mailbox timeout cnt */
-	uint32_t 	total_loop_resync; 	/* loop resyn cnt */
-	uint32_t	dropped_frame_error_cnt;
 
 	/* ISP configuration data. */
 	uint16_t	loop_id;		/* Host adapter loop id */
@@ -2123,9 +2184,7 @@ typedef struct scsi_qla_host {
 #define LOOP_P2P  2
 #define P2P_LOOP  3
 
-        uint8_t		marker_needed; 
-	uint8_t		sns_retry_cnt;
-	uint8_t		mem_err;
+        uint8_t		marker_needed;
 
 	uint8_t		interrupts_on;
 
@@ -2135,22 +2194,18 @@ typedef struct scsi_qla_host {
 	uint8_t		serial2;
 
 	/* NVRAM configuration data */
+	uint16_t	nvram_size;
 	uint16_t	nvram_base;
 
 	uint16_t	loop_reset_delay;
-	uint16_t	minimum_timeout;
 	uint8_t		retry_count;
 	uint8_t		login_timeout;
 	uint16_t	r_a_tov;
 	int		port_down_retry_count;
-	uint8_t		loop_down_timeout;
 	uint8_t		mbx_count;
-	uint16_t	max_probe_luns;
-	uint16_t	max_luns;
-	uint16_t	max_targets;
 	uint16_t	last_loop_id;
 
-        uint32_t	login_retry_count; 
+        uint32_t	login_retry_count;
 
 	/* Fibre Channel Device List. */
 	struct list_head	fcports;
@@ -2181,7 +2236,6 @@ typedef struct scsi_qla_host {
 	uint8_t dpc_active;                  /* DPC routine is active */
 
 	/* Timeout timers. */
-	uint8_t         queue_restart_timer;   
 	uint8_t         loop_down_abort_time;    /* port down timer */
 	atomic_t        loop_down_timer;         /* loop down timer */
 	uint8_t         link_down_timeout;       /* link down timeout */
@@ -2191,16 +2245,18 @@ typedef struct scsi_qla_host {
 
 	dma_addr_t	gid_list_dma;
 	struct gid_list_info *gid_list;
+	int		gid_list_info_size;
 
 	dma_addr_t	rlc_rsp_dma;
 	rpt_lun_cmd_rsp_t *rlc_rsp;
 
-	/* Small DMA pool allocations -- maximum 256 bytes in length. */ 
+	/* Small DMA pool allocations -- maximum 256 bytes in length. */
 #define DMA_POOL_SIZE	256
 	struct dma_pool *s_dma_pool;
 
 	dma_addr_t	init_cb_dma;
-	init_cb_t       *init_cb;
+	init_cb_t	*init_cb;
+	int		init_cb_size;
 
 	dma_addr_t	iodesc_pd_dma;
 	port_database_t *iodesc_pd;
@@ -2222,26 +2278,14 @@ typedef struct scsi_qla_host {
 	uint32_t	mbx_flags;
 #define  MBX_IN_PROGRESS	BIT_0
 #define  MBX_BUSY		BIT_1	/* Got the Access */
-#define  MBX_SLEEPING_ON_SEM	BIT_2 
+#define  MBX_SLEEPING_ON_SEM	BIT_2
 #define  MBX_POLLING_FOR_COMP	BIT_3
 #define  MBX_COMPLETED		BIT_4
-#define  MBX_TIMEDOUT		BIT_5 
+#define  MBX_TIMEDOUT		BIT_5
 #define  MBX_ACCESS_TIMEDOUT	BIT_6
 
 	mbx_cmd_t 	mc;
 
-	uint8_t	*cmdline;
-
-	uint32_t failover_type;
-	uint32_t failback_delay;
-	unsigned long   cfg_flags;
-#define	CFG_ACTIVE	0	/* CFG during a failover, event update, or ioctl */
-#define	CFG_FAILOVER	1	/* CFG during path change */
-
-	uint32_t	binding_type;
-#define BIND_BY_PORT_NAME	0
-#define BIND_BY_PORT_ID		1
-
 	/* Basic firmware related information. */
 	struct qla_board_info	*brd_info;
 	uint16_t	fw_major_version;
@@ -2253,6 +2297,7 @@ typedef struct scsi_qla_host {
 
 	uint16_t	fw_options[16];		/* slots: 1,2,3,10,11 */
 	uint8_t		fw_seriallink_options[4];
+	uint16_t	fw_seriallink_options24[4];
 
 	/* Firmware dump information. */
 	void		*fw_dump;
@@ -2261,8 +2306,12 @@ typedef struct scsi_qla_host {
 	char		*fw_dump_buffer;
 	int		fw_dump_buffer_len;
 
+	int		fw_dumped;
+	void		*fw_dump24;
+	int		fw_dump24_len;
+
 	uint8_t		host_str[16];
-	uint16_t	pci_attr;
+	uint32_t	pci_attr;
 
 	uint16_t	product_id[4];
 
@@ -2270,16 +2319,10 @@ typedef struct scsi_qla_host {
 #define BINZERO		"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
 	char		*model_desc;
 
-	uint8_t     node_name[WWN_SIZE];
-	uint8_t     nvram_version; 
+	uint8_t		*node_name;
+	uint8_t		*port_name;
 	uint32_t    isp_abort_cnt;
 
-	/* Adapter I/O statistics for failover */
-	uint64_t	IosRequested;
-	uint64_t	BytesRequested;
-	uint64_t	IosExecuted;
-	uint64_t	BytesExecuted;
-
 	/* Needed for BEACON */
 	uint16_t	beacon_blink_led;
 	uint16_t	beacon_green_on;
@@ -2299,7 +2342,7 @@ typedef struct scsi_qla_host {
 	  test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags) || \
 	  test_bit(LOOP_RESYNC_ACTIVE, &ha->dpc_flags)) || \
 	 atomic_read(&ha->loop_state) == LOOP_DOWN)
-				 
+
 #define LOOP_RDY(ha)	(!LOOP_NOT_READY(ha))
 
 #define TGT_Q(ha, t) (ha->otgt[t])
diff --git a/drivers/scsi/qla2xxx/qla_devtbl.h b/drivers/scsi/qla2xxx/qla_devtbl.h
--- a/drivers/scsi/qla2xxx/qla_devtbl.h
+++ b/drivers/scsi/qla2xxx/qla_devtbl.h
@@ -1,4 +1,4 @@
-#define QLA_MODEL_NAMES         0x32
+#define QLA_MODEL_NAMES         0x44
 
 /*
  * Adapter model names.
@@ -53,7 +53,25 @@ static char *qla2x00_model_name[QLA_MODE
 	" ",		/* 0x12e */
 	"QLA210",	/* 0x12f */
 	"EMC 250",	/* 0x130 */
-	"HP A7538A"	/* 0x131 */
+	"HP A7538A",	/* 0x131 */
+	"QLA210",	/* 0x132 */
+	"QLA2460",	/* 0x133 */
+	"QLA2462",	/* 0x134 */
+	"QMC2462",	/* 0x135 */
+	"QMC2462S",	/* 0x136 */
+	"QLE2460",	/* 0x137 */
+	"QLE2462",	/* 0x138 */
+	"QME2462",	/* 0x139 */
+	"QLA2440",	/* 0x13a */
+	"QLA2442",	/* 0x13b */
+	"QSM2442",	/* 0x13c */
+	"QSM2462",	/* 0x13d */
+	"QLE210",	/* 0x13e */
+	"QLE220",	/* 0x13f */
+	"QLA2460",	/* 0x140 */
+	"QLA2462",	/* 0x141 */
+	"QLE2460",	/* 0x142 */
+	"QLE2462"	/* 0x143 */
 };
 
 static char *qla2x00_model_desc[QLA_MODEL_NAMES] = {
@@ -78,8 +96,8 @@ static char *qla2x00_model_desc[QLA_MODE
 	" ",						/* 0x112 */
 	" ",						/* 0x113 */
 	" ",						/* 0x114 */
-	"133MHz PCI-X to 2Gb FC Single Channel",	/* 0x115 */
-	"133MHz PCI-X to 2Gb FC Dual Channel",		/* 0x116 */
+	"133MHz PCI-X to 2Gb FC, Single Channel",	/* 0x115 */
+	"133MHz PCI-X to 2Gb FC, Dual Channel",		/* 0x116 */
 	"PCI-Express to 2Gb FC, Single Channel",	/* 0x117 */
 	"PCI-Express to 2Gb FC, Dual Channel",		/* 0x118 */
 	"133MHz PCI-X to 2Gb FC Optical",		/* 0x119 */
@@ -106,5 +124,23 @@ static char *qla2x00_model_desc[QLA_MODE
 	" ",						/* 0x12e */
 	"133MHz PCI-X to 2Gb FC SFF",			/* 0x12f */
 	"133MHz PCI-X to 2Gb FC SFF",			/* 0x130 */
-	"HP 1p2g QLA2340"				/* 0x131 */
+	"HP 1p2g QLA2340",				/* 0x131 */
+	"133MHz PCI-X to 2Gb FC, Single Channel",	/* 0x132 */
+	"PCI-X 2.0 to 4Gb FC, Single Channel",		/* 0x133 */
+	"PCI-X 2.0 to 4Gb FC, Dual Channel",		/* 0x134 */
+	"IBM eServer BC 4Gb FC Expansion Card",		/* 0x135 */
+	"IBM eServer BC 4Gb FC Expansion Card SFF",	/* 0x136 */
+	"PCI-Express to 4Gb FC, Single Channel",	/* 0x137 */
+	"PCI-Express to 4Gb FC, Dual Channel",		/* 0x138 */
+	"Dell PCI-Express to 4Gb FC, Dual Channel",	/* 0x139 */
+	"PCI-X 1.0 to 4Gb FC, Single Channel",		/* 0x13a */
+	"PCI-X 1.0 to 4Gb FC, Dual Channel",		/* 0x13b */
+	"Server I/O Module 4Gb FC, Single Channel",	/* 0x13c */
+	"Server I/O Module 4Gb FC, Single Channel",	/* 0x13d */
+	"PCI-Express to 2Gb FC, Single Channel",	/* 0x13e */
+	"PCI-Express to 4Gb FC, Single Channel",	/* 0x13f */
+	"Sun PCI-X 2.0 to 4Gb FC, Single Channel",	/* 0x140 */
+	"Sun PCI-X 2.0 to 4Gb FC, Dual Channel",	/* 0x141 */
+	"Sun PCI-Express to 2Gb FC, Single Channel",	/* 0x142 */
+	"Sun PCI-Express to 4Gb FC, Single Channel"	/* 0x143 */
 };
diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/qla_fw.h
new file mode 100644
--- /dev/null
+++ b/drivers/scsi/qla2xxx/qla_fw.h
@@ -0,0 +1,1073 @@
+
+/********************************************************************************
+*                  QLOGIC LINUX SOFTWARE
+*
+* QLogic ISP2x00 device driver for Linux 2.6.x
+* Copyright (C) 2003-2005 QLogic Corporation
+* (www.qlogic.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.
+**
+******************************************************************************/
+
+#ifndef __QLA_FW_H
+#define __QLA_FW_H
+
+#define RISC_SADDRESS		0x100000
+#define MBS_CHECKSUM_ERROR	0x4010
+
+/*
+ * Firmware Options.
+ */
+#define FO1_ENABLE_PUREX	BIT_10
+#define FO1_DISABLE_LED_CTRL	BIT_6
+#define FO2_ENABLE_SEL_CLASS2	BIT_5
+#define FO3_NO_ABTS_ON_LINKDOWN	BIT_14
+
+/*
+ * Port Database structure definition for ISP 24xx.
+ */
+#define PDO_FORCE_ADISC		BIT_1
+#define PDO_FORCE_PLOGI		BIT_0
+
+
+#define	PORT_DATABASE_24XX_SIZE		64
+struct port_database_24xx {
+	uint16_t flags;
+#define PDF_TASK_RETRY_ID	BIT_14
+#define PDF_FC_TAPE		BIT_7
+#define PDF_ACK0_CAPABLE	BIT_6
+#define PDF_FCP2_CONF		BIT_5
+#define PDF_CLASS_2		BIT_4
+#define PDF_HARD_ADDR		BIT_1
+
+	uint8_t current_login_state;
+	uint8_t last_login_state;
+#define PDS_PLOGI_PENDING	0x03
+#define PDS_PLOGI_COMPLETE	0x04
+#define PDS_PRLI_PENDING	0x05
+#define PDS_PRLI_COMPLETE	0x06
+#define PDS_PORT_UNAVAILABLE	0x07
+#define PDS_PRLO_PENDING	0x09
+#define PDS_LOGO_PENDING	0x11
+#define PDS_PRLI2_PENDING	0x12
+
+	uint8_t hard_address[3];
+	uint8_t reserved_1;
+
+	uint8_t port_id[3];
+	uint8_t sequence_id;
+
+	uint16_t port_timer;
+
+	uint16_t nport_handle;			/* N_PORT handle. */
+
+	uint16_t receive_data_size;
+	uint16_t reserved_2;
+
+	uint8_t prli_svc_param_word_0[2];	/* Big endian */
+						/* Bits 15-0 of word 0 */
+	uint8_t prli_svc_param_word_3[2];	/* Big endian */
+						/* Bits 15-0 of word 3 */
+
+	uint8_t port_name[WWN_SIZE];
+	uint8_t node_name[WWN_SIZE];
+
+	uint8_t reserved_3[24];
+};
+
+struct nvram_24xx {
+	/* NVRAM header. */
+	uint8_t id[4];
+	uint16_t nvram_version;
+	uint16_t reserved_0;
+
+	/* Firmware Initialization Control Block. */
+	uint16_t version;
+	uint16_t reserved_1;
+	uint16_t frame_payload_size;
+	uint16_t execution_throttle;
+	uint16_t exchange_count;
+	uint16_t hard_address;
+
+	uint8_t port_name[WWN_SIZE];
+	uint8_t node_name[WWN_SIZE];
+
+	uint16_t login_retry_count;
+	uint16_t link_down_on_nos;
+	uint16_t interrupt_delay_timer;
+	uint16_t login_timeout;
+
+	uint32_t firmware_options_1;
+	uint32_t firmware_options_2;
+	uint32_t firmware_options_3;
+
+	/* Offset 56. */
+
+	/*
+	 * BIT 0     = Control Enable
+	 * BIT 1-15  =
+	 *
+	 * BIT 0-7   = Reserved
+	 * BIT 8-10  = Output Swing 1G
+	 * BIT 11-13 = Output Emphasis 1G
+	 * BIT 14-15 = Reserved
+	 *
+	 * BIT 0-7   = Reserved
+	 * BIT 8-10  = Output Swing 2G
+	 * BIT 11-13 = Output Emphasis 2G
+	 * BIT 14-15 = Reserved
+	 *
+	 * BIT 0-7   = Reserved
+	 * BIT 8-10  = Output Swing 4G
+	 * BIT 11-13 = Output Emphasis 4G
+	 * BIT 14-15 = Reserved
+	 */
+	uint16_t seriallink_options[4];
+
+	uint16_t reserved_2[16];
+
+	/* Offset 96. */
+	uint16_t reserved_3[16];
+
+	/* PCIe table entries. */
+	uint16_t reserved_4[16];
+
+	/* Offset 160. */
+	uint16_t reserved_5[16];
+
+	/* Offset 192. */
+	uint16_t reserved_6[16];
+
+	/* Offset 224. */
+	uint16_t reserved_7[16];
+
+	/*
+	 * BIT 0  = Enable spinup delay
+	 * BIT 1  = Disable BIOS
+	 * BIT 2  = Enable Memory Map BIOS
+	 * BIT 3  = Enable Selectable Boot
+	 * BIT 4  = Disable RISC code load
+	 * BIT 5  =
+	 * BIT 6  =
+	 * BIT 7  =
+	 *
+	 * BIT 8  =
+	 * BIT 9  =
+	 * BIT 10 = Enable lip full login
+	 * BIT 11 = Enable target reset
+	 * BIT 12 =
+	 * BIT 13 =
+	 * BIT 14 =
+	 * BIT 15 = Enable alternate WWN
+	 *
+	 * BIT 16-31 =
+	 */
+	uint32_t host_p;
+
+	uint8_t alternate_port_name[WWN_SIZE];
+	uint8_t alternate_node_name[WWN_SIZE];
+
+	uint8_t boot_port_name[WWN_SIZE];
+	uint16_t boot_lun_number;
+	uint16_t reserved_8;
+
+	uint8_t alt1_boot_port_name[WWN_SIZE];
+	uint16_t alt1_boot_lun_number;
+	uint16_t reserved_9;
+
+	uint8_t alt2_boot_port_name[WWN_SIZE];
+	uint16_t alt2_boot_lun_number;
+	uint16_t reserved_10;
+
+	uint8_t alt3_boot_port_name[WWN_SIZE];
+	uint16_t alt3_boot_lun_number;
+	uint16_t reserved_11;
+
+	/*
+	 * BIT 0 = Selective Login
+	 * BIT 1 = Alt-Boot Enable
+	 * BIT 2 = Reserved
+	 * BIT 3 = Boot Order List
+	 * BIT 4 = Reserved
+	 * BIT 5 = Selective LUN
+	 * BIT 6 = Reserved
+	 * BIT 7-31 =
+	 */
+	uint32_t efi_parameters;
+
+	uint8_t reset_delay;
+	uint8_t reserved_12;
+	uint16_t reserved_13;
+
+	uint16_t boot_id_number;
+	uint16_t reserved_14;
+
+	uint16_t max_luns_per_target;
+	uint16_t reserved_15;
+
+	uint16_t port_down_retry_count;
+	uint16_t link_down_timeout;
+
+	/* FCode parameters. */
+	uint16_t fcode_parameter;
+
+	uint16_t reserved_16[3];
+
+	/* Offset 352. */
+	uint8_t prev_drv_ver_major;
+	uint8_t prev_drv_ver_submajob;
+	uint8_t prev_drv_ver_minor;
+	uint8_t prev_drv_ver_subminor;
+
+	uint16_t prev_bios_ver_major;
+	uint16_t prev_bios_ver_minor;
+
+	uint16_t prev_efi_ver_major;
+	uint16_t prev_efi_ver_minor;
+
+	uint16_t prev_fw_ver_major;
+	uint8_t prev_fw_ver_minor;
+	uint8_t prev_fw_ver_subminor;
+
+	uint16_t reserved_17[8];
+
+	/* Offset 384. */
+	uint16_t reserved_18[16];
+
+	/* Offset 416. */
+	uint16_t reserved_19[16];
+
+	/* Offset 448. */
+	uint16_t reserved_20[16];
+
+	/* Offset 480. */
+	uint8_t model_name[16];
+
+	uint16_t reserved_21[2];
+
+	/* Offset 500. */
+	/* HW Parameter Block. */
+	uint16_t pcie_table_sig;
+	uint16_t pcie_table_offset;
+
+	uint16_t subsystem_vendor_id;
+	uint16_t subsystem_device_id;
+
+	uint32_t checksum;
+};
+
+/*
+ * ISP Initialization Control Block.
+ * Little endian except where noted.
+ */
+#define	ICB_VERSION 1
+struct init_cb_24xx {
+	uint16_t version;
+	uint16_t reserved_1;
+
+	uint16_t frame_payload_size;
+	uint16_t execution_throttle;
+	uint16_t exchange_count;
+
+	uint16_t hard_address;
+
+	uint8_t port_name[WWN_SIZE];		/* Big endian. */
+	uint8_t node_name[WWN_SIZE];		/* Big endian. */
+
+	uint16_t response_q_inpointer;
+	uint16_t request_q_outpointer;
+
+	uint16_t login_retry_count;
+
+	uint16_t prio_request_q_outpointer;
+
+	uint16_t response_q_length;
+	uint16_t request_q_length;
+
+	uint16_t link_down_timeout;		/* Milliseconds. */
+
+	uint16_t prio_request_q_length;
+
+	uint32_t request_q_address[2];
+	uint32_t response_q_address[2];
+	uint32_t prio_request_q_address[2];
+
+	uint8_t reserved_2[8];
+
+	uint16_t atio_q_inpointer;
+	uint16_t atio_q_length;
+	uint32_t atio_q_address[2];
+
+	uint16_t interrupt_delay_timer;		/* 100us increments. */
+	uint16_t login_timeout;
+
+	/*
+	 * BIT 0  = Enable Hard Loop Id
+	 * BIT 1  = Enable Fairness
+	 * BIT 2  = Enable Full-Duplex
+	 * BIT 3  = Reserved
+	 * BIT 4  = Enable Target Mode
+	 * BIT 5  = Disable Initiator Mode
+	 * BIT 6  = Reserved
+	 * BIT 7  = Reserved
+	 *
+	 * BIT 8  = Reserved
+	 * BIT 9  = Non Participating LIP
+	 * BIT 10 = Descending Loop ID Search
+	 * BIT 11 = Acquire Loop ID in LIPA
+	 * BIT 12 = Reserved
+	 * BIT 13 = Full Login after LIP
+	 * BIT 14 = Node Name Option
+	 * BIT 15-31 = Reserved
+	 */
+	uint32_t firmware_options_1;
+
+	/*
+	 * BIT 0  = Operation Mode bit 0
+	 * BIT 1  = Operation Mode bit 1
+	 * BIT 2  = Operation Mode bit 2
+	 * BIT 3  = Operation Mode bit 3
+	 * BIT 4  = Connection Options bit 0
+	 * BIT 5  = Connection Options bit 1
+	 * BIT 6  = Connection Options bit 2
+	 * BIT 7  = Enable Non part on LIHA failure
+	 *
+	 * BIT 8  = Enable Class 2
+	 * BIT 9  = Enable ACK0
+	 * BIT 10 = Reserved
+	 * BIT 11 = Enable FC-SP Security
+	 * BIT 12 = FC Tape Enable
+	 * BIT 13-31 = Reserved
+	 */
+	uint32_t firmware_options_2;
+
+	/*
+	 * BIT 0  = Reserved
+	 * BIT 1  = Soft ID only
+	 * BIT 2  = Reserved
+	 * BIT 3  = Reserved
+	 * BIT 4  = FCP RSP Payload bit 0
+	 * BIT 5  = FCP RSP Payload bit 1
+	 * BIT 6  = Enable Receive Out-of-Order data frame handling
+	 * BIT 7  = Disable Automatic PLOGI on Local Loop
+	 *
+	 * BIT 8  = Reserved
+	 * BIT 9  = Enable Out-of-Order FCP_XFER_RDY relative offset handling
+	 * BIT 10 = Reserved
+	 * BIT 11 = Reserved
+	 * BIT 12 = Reserved
+	 * BIT 13 = Data Rate bit 0
+	 * BIT 14 = Data Rate bit 1
+	 * BIT 15 = Data Rate bit 2
+	 * BIT 16-31 = Reserved
+	 */
+	uint32_t firmware_options_3;
+
+	uint8_t  reserved_3[24];
+};
+
+/*
+ * ISP queue - command entry structure definition.
+ */
+#define COMMAND_TYPE_6	0x48		/* Command Type 6 entry */
+struct cmd_type_6 {
+	uint8_t entry_type;		/* Entry type. */
+	uint8_t entry_count;		/* Entry count. */
+	uint8_t sys_define;		/* System defined. */
+	uint8_t entry_status;		/* Entry Status. */
+
+	uint32_t handle;		/* System handle. */
+
+	uint16_t nport_handle;		/* N_PORT handle. */
+	uint16_t timeout;		/* Command timeout. */
+
+	uint16_t dseg_count;		/* Data segment count. */
+
+	uint16_t fcp_rsp_dsd_len;	/* FCP_RSP DSD length. */
+
+	uint8_t lun[8];			/* FCP LUN (BE). */
+
+	uint16_t control_flags;		/* Control flags. */
+#define CF_DATA_SEG_DESCR_ENABLE	BIT_2
+#define CF_READ_DATA			BIT_1
+#define CF_WRITE_DATA			BIT_0
+
+	uint16_t fcp_cmnd_dseg_len;		/* Data segment length. */
+	uint32_t fcp_cmnd_dseg_address[2];	/* Data segment address. */
+
+	uint32_t fcp_rsp_dseg_address[2];	/* Data segment address. */
+
+	uint32_t byte_count;		/* Total byte count. */
+
+	uint8_t port_id[3];		/* PortID of destination port. */
+	uint8_t vp_index;
+
+	uint32_t fcp_data_dseg_address[2];	/* Data segment address. */
+	uint16_t fcp_data_dseg_len;		/* Data segment length. */
+	uint16_t reserved_1;			/* MUST be set to 0. */
+};
+
+#define COMMAND_TYPE_7	0x18		/* Command Type 7 entry */
+struct cmd_type_7 {
+	uint8_t entry_type;		/* Entry type. */
+	uint8_t entry_count;		/* Entry count. */
+	uint8_t sys_define;		/* System defined. */
+	uint8_t entry_status;		/* Entry Status. */
+
+	uint32_t handle;		/* System handle. */
+
+	uint16_t nport_handle;		/* N_PORT handle. */
+	uint16_t timeout;		/* Command timeout. */
+#define FW_MAX_TIMEOUT		0x1999
+
+	uint16_t dseg_count;		/* Data segment count. */
+	uint16_t reserved_1;
+
+	uint8_t lun[8];			/* FCP LUN (BE). */
+
+	uint16_t task_mgmt_flags;	/* Task management flags. */
+#define TMF_CLEAR_ACA		BIT_14
+#define TMF_TARGET_RESET	BIT_13
+#define TMF_LUN_RESET		BIT_12
+#define TMF_CLEAR_TASK_SET	BIT_10
+#define TMF_ABORT_TASK_SET	BIT_9
+#define TMF_READ_DATA		BIT_1
+#define TMF_WRITE_DATA		BIT_0
+
+	uint8_t task;
+#define TSK_SIMPLE		0
+#define TSK_HEAD_OF_QUEUE	1
+#define TSK_ORDERED		2
+#define TSK_ACA			4
+#define TSK_UNTAGGED		5
+
+	uint8_t crn;
+
+	uint8_t fcp_cdb[MAX_CMDSZ]; 	/* SCSI command words. */
+	uint32_t byte_count;		/* Total byte count. */
+
+	uint8_t port_id[3];		/* PortID of destination port. */
+	uint8_t vp_index;
+
+	uint32_t dseg_0_address[2];	/* Data segment 0 address. */
+	uint32_t dseg_0_len;		/* Data segment 0 length. */
+};
+
+/*
+ * ISP queue - status entry structure definition.
+ */
+#define	STATUS_TYPE	0x03		/* Status entry. */
+struct sts_entry_24xx {
+	uint8_t entry_type;		/* Entry type. */
+	uint8_t entry_count;		/* Entry count. */
+	uint8_t sys_define;		/* System defined. */
+	uint8_t entry_status;		/* Entry Status. */
+
+	uint32_t handle;		/* System handle. */
+
+	uint16_t comp_status;		/* Completion status. */
+	uint16_t ox_id;			/* OX_ID used by the firmware. */
+
+	uint32_t residual_len;		/* Residual transfer length. */
+
+	uint16_t reserved_1;
+	uint16_t state_flags;		/* State flags. */
+#define SF_TRANSFERRED_DATA	BIT_11
+#define SF_FCP_RSP_DMA		BIT_0
+
+	uint16_t reserved_2;
+	uint16_t scsi_status;		/* SCSI status. */
+#define SS_CONFIRMATION_REQ		BIT_12
+
+	uint32_t rsp_residual_count;	/* FCP RSP residual count. */
+
+	uint32_t sense_len;		/* FCP SENSE length. */
+	uint32_t rsp_data_len;		/* FCP response data length. */
+
+	uint8_t data[28];		/* FCP response/sense information. */
+};
+
+/*
+ * Status entry completion status
+ */
+#define CS_DATA_REASSEMBLY_ERROR 0x11	/* Data Reassembly Error.. */
+#define CS_ABTS_BY_TARGET	0x13	/* Target send ABTS to abort IOCB. */
+#define CS_FW_RESOURCE		0x2C	/* Firmware Resource Unavailable. */
+#define CS_TASK_MGMT_OVERRUN	0x30	/* Task management overrun (8+). */
+#define CS_ABORT_BY_TARGET	0x47	/* Abort By Target. */
+
+/*
+ * ISP queue - marker entry structure definition.
+ */
+#define MARKER_TYPE	0x04		/* Marker entry. */
+struct mrk_entry_24xx {
+	uint8_t entry_type;		/* Entry type. */
+	uint8_t entry_count;		/* Entry count. */
+	uint8_t handle_count;		/* Handle count. */
+	uint8_t entry_status;		/* Entry Status. */
+
+	uint32_t handle;		/* System handle. */
+
+	uint16_t nport_handle;		/* N_PORT handle. */
+
+	uint8_t modifier;		/* Modifier (7-0). */
+#define MK_SYNC_ID_LUN	0		/* Synchronize ID/LUN */
+#define MK_SYNC_ID	1		/* Synchronize ID */
+#define MK_SYNC_ALL	2		/* Synchronize all ID/LUN */
+	uint8_t reserved_1;
+
+	uint8_t reserved_2;
+	uint8_t vp_index;
+
+	uint16_t reserved_3;
+
+	uint8_t lun[8];			/* FCP LUN (BE). */
+	uint8_t reserved_4[40];
+};
+
+/*
+ * ISP queue - CT Pass-Through entry structure definition.
+ */
+#define CT_IOCB_TYPE		0x29	/* CT Pass-Through IOCB entry */
+struct ct_entry_24xx {
+	uint8_t entry_type;		/* Entry type. */
+	uint8_t entry_count;		/* Entry count. */
+	uint8_t sys_define;		/* System Defined. */
+	uint8_t entry_status;		/* Entry Status. */
+
+	uint32_t handle;		/* System handle. */
+
+	uint16_t comp_status;		/* Completion status. */
+
+	uint16_t nport_handle;		/* N_PORT handle. */
+
+	uint16_t cmd_dsd_count;
+
+	uint8_t vp_index;
+	uint8_t reserved_1;
+
+	uint16_t timeout;		/* Command timeout. */
+	uint16_t reserved_2;
+
+	uint16_t rsp_dsd_count;
+
+	uint8_t reserved_3[10];
+
+	uint32_t rsp_byte_count;
+	uint32_t cmd_byte_count;
+
+	uint32_t dseg_0_address[2];	/* Data segment 0 address. */
+	uint32_t dseg_0_len;		/* Data segment 0 length. */
+	uint32_t dseg_1_address[2];	/* Data segment 1 address. */
+	uint32_t dseg_1_len;		/* Data segment 1 length. */
+};
+
+/*
+ * ISP queue - ELS Pass-Through entry structure definition.
+ */
+#define ELS_IOCB_TYPE		0x53	/* ELS Pass-Through IOCB entry */
+struct els_entry_24xx {
+	uint8_t entry_type;		/* Entry type. */
+	uint8_t entry_count;		/* Entry count. */
+	uint8_t sys_define;		/* System Defined. */
+	uint8_t entry_status;		/* Entry Status. */
+
+	uint32_t handle;		/* System handle. */
+
+	uint16_t reserved_1;
+
+	uint16_t nport_handle;		/* N_PORT handle. */
+
+	uint16_t tx_dsd_count;
+
+	uint8_t vp_index;
+	uint8_t sof_type;
+#define EST_SOFI3		(1 << 4)
+#define EST_SOFI2		(3 << 4)
+
+	uint32_t rx_xchg_address[2];	/* Receive exchange address. */
+	uint16_t rx_dsd_count;
+
+	uint8_t opcode;
+	uint8_t reserved_2;
+
+	uint8_t port_id[3];
+	uint8_t reserved_3;
+
+	uint16_t reserved_4;
+
+	uint16_t control_flags;		/* Control flags. */
+#define ECF_PAYLOAD_DESCR_MASK	(BIT_15|BIT_14|BIT_13)
+#define EPD_ELS_COMMAND		(0 << 13)
+#define EPD_ELS_ACC		(1 << 13)
+#define EPD_ELS_RJT		(2 << 13)
+#define EPD_RX_XCHG		(3 << 13)
+#define ECF_CLR_PASSTHRU_PEND	BIT_12
+#define ECF_INCL_FRAME_HDR	BIT_11
+
+	uint32_t rx_byte_count;
+	uint32_t tx_byte_count;
+
+	uint32_t tx_address[2];		/* Data segment 0 address. */
+	uint32_t tx_len;		/* Data segment 0 length. */
+	uint32_t rx_address[2];		/* Data segment 1 address. */
+	uint32_t rx_len;		/* Data segment 1 length. */
+};
+
+/*
+ * ISP queue - Mailbox Command entry structure definition.
+ */
+#define MBX_IOCB_TYPE	0x39
+struct mbx_entry_24xx {
+	uint8_t entry_type;		/* Entry type. */
+	uint8_t entry_count;		/* Entry count. */
+	uint8_t handle_count;		/* Handle count. */
+	uint8_t entry_status;		/* Entry Status. */
+
+	uint32_t handle;		/* System handle. */
+
+	uint16_t mbx[28];
+};
+
+
+#define LOGINOUT_PORT_IOCB_TYPE	0x52	/* Login/Logout Port entry. */
+struct logio_entry_24xx {
+	uint8_t entry_type;		/* Entry type. */
+	uint8_t entry_count;		/* Entry count. */
+	uint8_t sys_define;		/* System defined. */
+	uint8_t entry_status;		/* Entry Status. */
+
+	uint32_t handle;		/* System handle. */
+
+	uint16_t comp_status;		/* Completion status. */
+#define CS_LOGIO_ERROR		0x31	/* Login/Logout IOCB error. */
+
+	uint16_t nport_handle;		/* N_PORT handle. */
+
+	uint16_t control_flags;		/* Control flags. */
+					/* Modifiers. */
+#define LCF_FCP2_OVERRIDE	BIT_9	/* Set/Reset word 3 of PRLI. */
+#define LCF_CLASS_2		BIT_8	/* Enable class 2 during PLOGI. */
+#define LCF_FREE_NPORT		BIT_7	/* Release NPORT handle after LOGO. */
+#define LCF_EXPL_LOGO		BIT_6	/* Perform an explicit LOGO. */
+#define LCF_SKIP_PRLI		BIT_5	/* Skip PRLI after PLOGI. */
+#define LCF_IMPL_LOGO_ALL	BIT_5	/* Implicit LOGO to all ports. */
+#define LCF_COND_PLOGI		BIT_4	/* PLOGI only if not logged-in. */
+#define LCF_IMPL_LOGO		BIT_4	/* Perform an implicit LOGO. */
+#define LCF_IMPL_PRLO		BIT_4	/* Perform an implicit PRLO. */
+					/* Commands. */
+#define LCF_COMMAND_PLOGI	0x00	/* PLOGI. */
+#define LCF_COMMAND_PRLI	0x01	/* PRLI. */
+#define LCF_COMMAND_PDISC	0x02	/* PDISC. */
+#define LCF_COMMAND_ADISC	0x03	/* ADISC. */
+#define LCF_COMMAND_LOGO	0x08	/* LOGO. */
+#define LCF_COMMAND_PRLO	0x09	/* PRLO. */
+#define LCF_COMMAND_TPRLO	0x0A	/* TPRLO. */
+
+	uint8_t vp_index;
+	uint8_t reserved_1;
+
+	uint8_t port_id[3];		/* PortID of destination port. */
+
+	uint8_t rsp_size;		/* Response size in 32bit words. */
+
+	uint32_t io_parameter[11];	/* General I/O parameters. */
+#define LSC_SCODE_NOLINK	0x01
+#define LSC_SCODE_NOIOCB	0x02
+#define LSC_SCODE_NOXCB		0x03
+#define LSC_SCODE_CMD_FAILED	0x04
+#define LSC_SCODE_NOFABRIC	0x05
+#define LSC_SCODE_FW_NOT_READY	0x07
+#define LSC_SCODE_NOT_LOGGED_IN	0x09
+#define LSC_SCODE_NOPCB		0x0A
+
+#define LSC_SCODE_ELS_REJECT	0x18
+#define LSC_SCODE_CMD_PARAM_ERR	0x19
+#define LSC_SCODE_PORTID_USED	0x1A
+#define LSC_SCODE_NPORT_USED	0x1B
+#define LSC_SCODE_NONPORT	0x1C
+#define LSC_SCODE_LOGGED_IN	0x1D
+#define LSC_SCODE_NOFLOGI_ACC	0x1F
+};
+
+#define TSK_MGMT_IOCB_TYPE	0x14
+struct tsk_mgmt_entry {
+	uint8_t entry_type;		/* Entry type. */
+	uint8_t entry_count;		/* Entry count. */
+	uint8_t handle_count;		/* Handle count. */
+	uint8_t entry_status;		/* Entry Status. */
+
+	uint32_t handle;		/* System handle. */
+
+	uint16_t nport_handle;		/* N_PORT handle. */
+
+	uint16_t reserved_1;
+
+	uint16_t delay;			/* Activity delay in seconds. */
+
+	uint16_t timeout;		/* Command timeout. */
+
+	uint8_t lun[8];			/* FCP LUN (BE). */
+
+	uint32_t control_flags;		/* Control Flags. */
+#define TCF_NOTMCMD_TO_TARGET	BIT_31
+#define TCF_LUN_RESET		BIT_4
+#define TCF_ABORT_TASK_SET	BIT_3
+#define TCF_CLEAR_TASK_SET	BIT_2
+#define TCF_TARGET_RESET	BIT_1
+#define TCF_CLEAR_ACA		BIT_0
+
+	uint8_t reserved_2[20];
+
+	uint8_t port_id[3];		/* PortID of destination port. */
+	uint8_t vp_index;
+
+	uint8_t reserved_3[12];
+};
+
+#define ABORT_IOCB_TYPE	0x33
+struct abort_entry_24xx {
+	uint8_t entry_type;		/* Entry type. */
+	uint8_t entry_count;		/* Entry count. */
+	uint8_t handle_count;		/* Handle count. */
+	uint8_t entry_status;		/* Entry Status. */
+
+	uint32_t handle;		/* System handle. */
+
+	uint16_t nport_handle;		/* N_PORT handle. */
+					/* or Completion status. */
+
+	uint16_t options;		/* Options. */
+#define AOF_NO_ABTS		BIT_0	/* Do not send any ABTS. */
+
+	uint32_t handle_to_abort;	/* System handle to abort. */
+
+	uint8_t reserved_1[32];
+
+	uint8_t port_id[3];		/* PortID of destination port. */
+	uint8_t vp_index;
+
+	uint8_t reserved_2[12];
+};
+
+/*
+ * ISP I/O Register Set structure definitions.
+ */
+struct device_reg_24xx {
+	uint32_t flash_addr;		/* Flash/NVRAM BIOS address. */
+#define FARX_DATA_FLAG	BIT_31
+#define FARX_ACCESS_FLASH_CONF	0x7FFD0000
+#define FARX_ACCESS_FLASH_DATA	0x7FF00000
+#define FARX_ACCESS_NVRAM_CONF	0x7FFF0000
+#define FARX_ACCESS_NVRAM_DATA	0x7FFE0000
+
+#define FA_NVRAM_FUNC0_ADDR	0x80
+#define FA_NVRAM_FUNC1_ADDR	0x180
+
+#define FA_NVRAM_VPD_SIZE	0x80
+#define FA_NVRAM_VPD0_ADDR	0x00
+#define FA_NVRAM_VPD1_ADDR	0x100
+					/*
+					 * RISC code begins at offset 512KB
+					 * within flash. Consisting of two
+					 * contiguous RISC code segments.
+					 */
+#define FA_RISC_CODE_ADDR	0x20000
+#define FA_RISC_CODE_SEGMENTS	2
+
+	uint32_t flash_data;		/* Flash/NVRAM BIOS data. */
+
+	uint32_t ctrl_status;		/* Control/Status. */
+#define CSRX_FLASH_ACCESS_ERROR	BIT_18	/* Flash/NVRAM Access Error. */
+#define CSRX_DMA_ACTIVE		BIT_17	/* DMA Active status. */
+#define CSRX_DMA_SHUTDOWN	BIT_16	/* DMA Shutdown control status. */
+#define CSRX_FUNCTION		BIT_15	/* Function number. */
+					/* PCI-X Bus Mode. */
+#define CSRX_PCIX_BUS_MODE_MASK	(BIT_11|BIT_10|BIT_9|BIT_8)
+#define PBM_PCI_33MHZ		(0 << 8)
+#define PBM_PCIX_M1_66MHZ	(1 << 8)
+#define PBM_PCIX_M1_100MHZ	(2 << 8)
+#define PBM_PCIX_M1_133MHZ	(3 << 8)
+#define PBM_PCIX_M2_66MHZ	(5 << 8)
+#define PBM_PCIX_M2_100MHZ	(6 << 8)
+#define PBM_PCIX_M2_133MHZ	(7 << 8)
+#define PBM_PCI_66MHZ		(8 << 8)
+					/* Max Write Burst byte count. */
+#define CSRX_MAX_WRT_BURST_MASK	(BIT_5|BIT_4)
+#define MWB_512_BYTES		(0 << 4)
+#define MWB_1024_BYTES		(1 << 4)
+#define MWB_2048_BYTES		(2 << 4)
+#define MWB_4096_BYTES		(3 << 4)
+
+#define CSRX_64BIT_SLOT		BIT_2	/* PCI 64-Bit Bus Slot. */
+#define CSRX_FLASH_ENABLE	BIT_1	/* Flash BIOS Read/Write enable. */
+#define CSRX_ISP_SOFT_RESET	BIT_0	/* ISP soft reset. */
+
+	uint32_t ictrl;			/* Interrupt control. */
+#define ICRX_EN_RISC_INT	BIT_3	/* Enable RISC interrupts on PCI. */
+
+	uint32_t istatus;		/* Interrupt status. */
+#define ISRX_RISC_INT		BIT_3	/* RISC interrupt. */
+
+	uint32_t unused_1[2];		/* Gap. */
+
+					/* Request Queue. */
+	uint32_t req_q_in;		/*  In-Pointer. */
+	uint32_t req_q_out;		/*  Out-Pointer. */
+					/* Response Queue. */
+	uint32_t rsp_q_in;		/*  In-Pointer. */
+	uint32_t rsp_q_out;		/*  Out-Pointer. */
+					/* Priority Request Queue. */
+	uint32_t preq_q_in;		/*  In-Pointer. */
+	uint32_t preq_q_out;		/*  Out-Pointer. */
+
+	uint32_t unused_2[2];		/* Gap. */
+
+					/* ATIO Queue. */
+	uint32_t atio_q_in;		/*  In-Pointer. */
+	uint32_t atio_q_out;		/*  Out-Pointer. */
+
+	uint32_t host_status;
+#define HSRX_RISC_INT		BIT_15	/* RISC to Host interrupt. */
+#define HSRX_RISC_PAUSED	BIT_8	/* RISC Paused. */
+
+	uint32_t hccr;			/* Host command & control register. */
+					/* HCCR statuses. */
+#define HCCRX_HOST_INT		BIT_6	/* Host to RISC interrupt bit. */
+#define HCCRX_RISC_RESET	BIT_5	/* RISC Reset mode bit. */
+#define HCCRX_RISC_PAUSE	BIT_4	/* RISC Pause mode bit. */
+					/* HCCR commands. */
+					/* NOOP. */
+#define HCCRX_NOOP		0x00000000
+					/* Set RISC Reset. */
+#define HCCRX_SET_RISC_RESET	0x10000000
+					/* Clear RISC Reset. */
+#define HCCRX_CLR_RISC_RESET	0x20000000
+					/* Set RISC Pause. */
+#define HCCRX_SET_RISC_PAUSE	0x30000000
+					/* Releases RISC Pause. */
+#define HCCRX_REL_RISC_PAUSE	0x40000000
+					/* Set HOST to RISC interrupt. */
+#define HCCRX_SET_HOST_INT	0x50000000
+					/* Clear HOST to RISC interrupt. */
+#define HCCRX_CLR_HOST_INT	0x60000000
+					/* Clear RISC to PCI interrupt. */
+#define HCCRX_CLR_RISC_INT	0xA0000000
+
+	uint32_t gpiod;			/* GPIO Data register. */
+					/* LED update mask. */
+#define GPDX_LED_UPDATE_MASK	(BIT_20|BIT_19|BIT_18)
+					/* Data update mask. */
+#define GPDX_DATA_UPDATE_MASK	(BIT_17|BIT_16)
+					/* LED control mask. */
+#define GPDX_LED_COLOR_MASK	(BIT_4|BIT_3|BIT_2)
+					/* LED bit values. Color names as
+					 * referenced in fw spec.
+					 */
+#define GPDX_LED_YELLOW_ON	BIT_2
+#define GPDX_LED_GREEN_ON	BIT_3
+#define GPDX_LED_AMBER_ON	BIT_4
+					/* Data in/out. */
+#define GPDX_DATA_INOUT		(BIT_1|BIT_0)
+
+	uint32_t gpioe;			/* GPIO Enable register. */
+					/* Enable update mask. */
+#define GPEX_ENABLE_UPDATE_MASK	(BIT_17|BIT_16)
+					/* Enable. */
+#define GPEX_ENABLE		(BIT_1|BIT_0)
+
+	uint32_t iobase_addr;		/* I/O Bus Base Address register. */
+
+	uint32_t unused_3[10];		/* Gap. */
+
+	uint16_t mailbox0;
+	uint16_t mailbox1;
+	uint16_t mailbox2;
+	uint16_t mailbox3;
+	uint16_t mailbox4;
+	uint16_t mailbox5;
+	uint16_t mailbox6;
+	uint16_t mailbox7;
+	uint16_t mailbox8;
+	uint16_t mailbox9;
+	uint16_t mailbox10;
+	uint16_t mailbox11;
+	uint16_t mailbox12;
+	uint16_t mailbox13;
+	uint16_t mailbox14;
+	uint16_t mailbox15;
+	uint16_t mailbox16;
+	uint16_t mailbox17;
+	uint16_t mailbox18;
+	uint16_t mailbox19;
+	uint16_t mailbox20;
+	uint16_t mailbox21;
+	uint16_t mailbox22;
+	uint16_t mailbox23;
+	uint16_t mailbox24;
+	uint16_t mailbox25;
+	uint16_t mailbox26;
+	uint16_t mailbox27;
+	uint16_t mailbox28;
+	uint16_t mailbox29;
+	uint16_t mailbox30;
+	uint16_t mailbox31;
+};
+
+/* MID Support ***************************************************************/
+
+#define MAX_MID_VPS	125
+
+struct mid_conf_entry_24xx {
+	uint16_t reserved_1;
+
+	/*
+	 * BIT 0  = Enable Hard Loop Id
+	 * BIT 1  = Acquire Loop ID in LIPA
+	 * BIT 2  = ID not Acquired
+	 * BIT 3  = Enable VP
+	 * BIT 4  = Enable Initiator Mode
+	 * BIT 5  = Disable Target Mode
+	 * BIT 6-7 = Reserved
+	 */
+	uint8_t options;
+
+	uint8_t hard_address;
+
+	uint8_t port_name[WWN_SIZE];
+	uint8_t node_name[WWN_SIZE];
+};
+
+struct mid_init_cb_24xx {
+	struct init_cb_24xx init_cb;
+
+	uint16_t count;
+	uint16_t options;
+
+	struct mid_conf_entry_24xx entries[MAX_MID_VPS];
+};
+
+
+struct mid_db_entry_24xx {
+	uint16_t status;
+#define MDBS_NON_PARTIC		BIT_3
+#define MDBS_ID_ACQUIRED	BIT_1
+#define MDBS_ENABLED		BIT_0
+
+	uint8_t options;
+	uint8_t hard_address;
+
+	uint8_t port_name[WWN_SIZE];
+	uint8_t node_name[WWN_SIZE];
+
+	uint8_t port_id[3];
+	uint8_t reserved_1;
+};
+
+struct mid_db_24xx {
+	struct mid_db_entry_24xx entries[MAX_MID_VPS];
+};
+
+#define VP_CTRL_IOCB_TYPE	0x30	/* Vitual Port Control entry. */
+struct vp_ctrl_entry_24xx {
+	uint8_t entry_type;		/* Entry type. */
+	uint8_t entry_count;		/* Entry count. */
+	uint8_t sys_define;		/* System defined. */
+	uint8_t entry_status;		/* Entry Status. */
+
+	uint32_t handle;		/* System handle. */
+
+	uint16_t vp_idx_failed;
+
+	uint16_t comp_status;		/* Completion status. */
+#define CS_VCE_ACQ_ID_ERROR	0x02	/* Error while acquireing ID. */
+#define CS_VCE_BUSY		0x05	/* Firmware not ready to accept cmd. */
+
+	uint16_t command;
+#define VCE_COMMAND_ENABLE_VPS	0x00	/* Enable VPs. */
+#define VCE_COMMAND_DISABLE_VPS	0x08	/* Disable VPs. */
+#define VCE_COMMAND_DISABLE_VPS_REINIT	0x09 /* Disable VPs and reinit link. */
+#define VCE_COMMAND_DISABLE_VPS_LOGO	0x0a /* Disable VPs and LOGO ports. */
+
+	uint16_t vp_count;
+
+	uint8_t vp_idx_map[16];
+
+	uint8_t reserved_4[32];
+};
+
+#define VP_CONFIG_IOCB_TYPE	0x31	/* Vitual Port Config entry. */
+struct vp_config_entry_24xx {
+	uint8_t entry_type;		/* Entry type. */
+	uint8_t entry_count;		/* Entry count. */
+	uint8_t sys_define;		/* System defined. */
+	uint8_t entry_status;		/* Entry Status. */
+
+	uint32_t handle;		/* System handle. */
+
+	uint16_t reserved_1;
+
+	uint16_t comp_status;		/* Completion status. */
+#define CS_VCT_STS_ERROR	0x01	/* Specified VPs were not disabled. */
+#define CS_VCT_CNT_ERROR	0x02	/* Invalid VP count. */
+#define CS_VCT_ERROR		0x03	/* Unknown error. */
+#define CS_VCT_IDX_ERROR	0x02	/* Invalid VP index. */
+#define CS_VCT_BUSY		0x05	/* Firmware not ready to accept cmd. */
+
+	uint8_t command;
+#define VCT_COMMAND_MOD_VPS	0x00	/* Enable VPs. */
+#define VCT_COMMAND_MOD_ENABLE_VPS 0x08	/* Disable VPs. */
+
+	uint8_t vp_count;
+
+	uint8_t vp_idx1;
+	uint8_t vp_idx2;
+
+	uint8_t options_idx1;
+	uint8_t hard_address_idx1;
+	uint16_t reserved_2;
+	uint8_t port_name_idx1[WWN_SIZE];
+	uint8_t node_name_idx1[WWN_SIZE];
+
+	uint8_t options_idx2;
+	uint8_t hard_address_idx2;
+	uint16_t reserved_3;
+	uint8_t port_name_idx2[WWN_SIZE];
+	uint8_t node_name_idx2[WWN_SIZE];
+
+	uint8_t reserved_4[8];
+};
+
+#define VP_RPT_ID_IOCB_TYPE	0x32	/* Report ID Acquisition entry. */
+struct vp_rpt_id_entry_24xx {
+	uint8_t entry_type;		/* Entry type. */
+	uint8_t entry_count;		/* Entry count. */
+	uint8_t sys_define;		/* System defined. */
+	uint8_t entry_status;		/* Entry Status. */
+
+	uint32_t handle;		/* System handle. */
+
+	uint16_t vp_count;		/* Format 0 -- | VP setup | VP acq |. */
+					/* Format 1 -- | VP count |. */
+	uint16_t vp_idx;		/* Format 0 -- Reserved. */
+					/* Format 1 -- VP status and index. */
+
+	uint8_t port_id[3];
+	uint8_t format;
+
+	uint8_t vp_idx_map[16];
+
+	uint8_t reserved_4[32];
+};
+
+/* END MID Support ***********************************************************/
+#endif
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -2,7 +2,7 @@
 *                  QLOGIC LINUX SOFTWARE
 *
 * QLogic ISP2x00 device driver for Linux 2.6.x
-* Copyright (C) 2003-2004 QLogic Corporation
+* Copyright (C) 2003-2005 QLogic Corporation
 * (www.qlogic.com)
 *
 * This program is free software; you can redistribute it and/or modify it
@@ -32,6 +32,26 @@ extern int qla2x00_probe_one(struct pci_
  * Global Function Prototypes in qla_init.c source file.
  */
 extern int qla2x00_initialize_adapter(scsi_qla_host_t *);
+
+extern int qla2100_pci_config(struct scsi_qla_host *);
+extern int qla2300_pci_config(struct scsi_qla_host *);
+extern int qla24xx_pci_config(scsi_qla_host_t *);
+extern void qla2x00_reset_chip(struct scsi_qla_host *);
+extern void qla24xx_reset_chip(struct scsi_qla_host *);
+extern int qla2x00_chip_diag(struct scsi_qla_host *);
+extern int qla24xx_chip_diag(struct scsi_qla_host *);
+extern void qla2x00_config_rings(struct scsi_qla_host *);
+extern void qla24xx_config_rings(struct scsi_qla_host *);
+extern void qla2x00_reset_adapter(struct scsi_qla_host *);
+extern void qla24xx_reset_adapter(struct scsi_qla_host *);
+extern int qla2x00_nvram_config(struct scsi_qla_host *);
+extern int qla24xx_nvram_config(struct scsi_qla_host *);
+extern void qla2x00_update_fw_options(struct scsi_qla_host *);
+extern void qla24xx_update_fw_options(scsi_qla_host_t *);
+extern int qla2x00_load_risc(struct scsi_qla_host *, uint32_t *);
+extern int qla24xx_load_risc_flash(scsi_qla_host_t *, uint32_t *);
+extern int qla24xx_load_risc_hotplug(scsi_qla_host_t *, uint32_t *);
+
 extern fc_port_t *qla2x00_alloc_fcport(scsi_qla_host_t *, int);
 
 extern int qla2x00_loop_resync(scsi_qla_host_t *);
@@ -53,27 +73,13 @@ extern void qla2x00_reg_remote_port(scsi
  */
 extern char qla2x00_version_str[];
 
-extern int num_hosts;
-extern int apiHBAInstance;
-
-extern struct _qla2x00stats qla2x00_stats;
-extern int ql2xretrycount;
 extern int ql2xlogintimeout;
 extern int qlport_down_retry;
-extern int ql2xmaxqdepth;
-extern int displayConfig;
 extern int ql2xplogiabsentdevice;
 extern int ql2xenablezio;
 extern int ql2xintrdelaytimer;
 extern int ql2xloginretrycount;
 
-extern int ConfigRequired;
-
-extern int Bind;
-extern int ql2xsuspendcount;
-#if defined(MODULE)
-extern char *ql2xopts;
-#endif
 extern void qla2x00_sp_compl(scsi_qla_host_t *, srb_t *);
 
 extern char *qla2x00_get_fw_version_str(struct scsi_qla_host *, char *);
@@ -97,6 +103,7 @@ extern uint16_t qla2x00_calc_iocbs_64(ui
 extern void qla2x00_build_scsi_iocbs_32(srb_t *, cmd_entry_t *, uint16_t);
 extern void qla2x00_build_scsi_iocbs_64(srb_t *, cmd_entry_t *, uint16_t);
 extern int qla2x00_start_scsi(srb_t *sp);
+extern int qla24xx_start_scsi(srb_t *sp);
 int qla2x00_marker(scsi_qla_host_t *, uint16_t, uint16_t, uint8_t);
 int __qla2x00_marker(scsi_qla_host_t *, uint16_t, uint16_t, uint8_t);
 
@@ -107,10 +114,10 @@ extern int
 qla2x00_load_ram(scsi_qla_host_t *, dma_addr_t, uint16_t, uint16_t);
 
 extern int
-qla2x00_load_ram_ext(scsi_qla_host_t *, dma_addr_t, uint32_t, uint16_t);
+qla2x00_load_ram_ext(scsi_qla_host_t *, dma_addr_t, uint32_t, uint32_t);
 
 extern int
-qla2x00_execute_fw(scsi_qla_host_t *);
+qla2x00_execute_fw(scsi_qla_host_t *, uint32_t);
 
 extern void
 qla2x00_get_fw_version(scsi_qla_host_t *, uint16_t *,
@@ -126,7 +133,7 @@ extern int
 qla2x00_mbx_reg_test(scsi_qla_host_t *);
 
 extern int
-qla2x00_verify_checksum(scsi_qla_host_t *);
+qla2x00_verify_checksum(scsi_qla_host_t *, uint32_t);
 
 extern int
 qla2x00_issue_iocb(scsi_qla_host_t *, void *, dma_addr_t, size_t);
@@ -136,7 +143,7 @@ qla2x00_abort_command(scsi_qla_host_t *,
 
 #if USE_ABORT_TGT
 extern int
-qla2x00_abort_target(fc_port_t *fcport);
+qla2x00_abort_target(fc_port_t *);
 #endif
 
 extern int
@@ -170,12 +177,18 @@ qla2x00_send_sns(scsi_qla_host_t *, dma_
 extern int
 qla2x00_login_fabric(scsi_qla_host_t *, uint16_t, uint8_t, uint8_t, uint8_t,
     uint16_t *, uint8_t);
+extern int
+qla24xx_login_fabric(scsi_qla_host_t *, uint16_t, uint8_t, uint8_t, uint8_t,
+    uint16_t *, uint8_t);
 
 extern int
 qla2x00_login_local_device(scsi_qla_host_t *, uint16_t, uint16_t *, uint8_t);
 
 extern int
-qla2x00_fabric_logout(scsi_qla_host_t *ha, uint16_t loop_id);
+qla2x00_fabric_logout(scsi_qla_host_t *, uint16_t, uint8_t, uint8_t, uint8_t);
+
+extern int
+qla24xx_fabric_logout(scsi_qla_host_t *, uint16_t, uint8_t, uint8_t, uint8_t);
 
 extern int
 qla2x00_full_login_lip(scsi_qla_host_t *ha);
@@ -190,11 +203,24 @@ qla2x00_get_resource_cnts(scsi_qla_host_
 extern int
 qla2x00_get_fcal_position_map(scsi_qla_host_t *ha, char *pos_map);
 
+extern int qla24xx_abort_command(scsi_qla_host_t *, srb_t *);
+extern int qla24xx_abort_target(fc_port_t *);
+
+extern int qla2x00_system_error(scsi_qla_host_t *);
+
+extern int
+qla2x00_get_serdes_params(scsi_qla_host_t *, uint16_t *, uint16_t *,
+    uint16_t *);
+
+extern int
+qla2x00_set_serdes_params(scsi_qla_host_t *, uint16_t, uint16_t, uint16_t);
+
 /*
  * Global Function Prototypes in qla_isr.c source file.
  */
 extern irqreturn_t qla2100_intr_handler(int, void *, struct pt_regs *);
 extern irqreturn_t qla2300_intr_handler(int, void *, struct pt_regs *);
+extern irqreturn_t qla24xx_intr_handler(int, void *, struct pt_regs *);
 extern void qla2x00_process_response_queue(struct scsi_qla_host *);
 
 /*
@@ -205,20 +231,36 @@ extern void qla2x00_unlock_nvram_access(
 extern void qla2x00_release_nvram_protection(scsi_qla_host_t *);
 extern uint16_t qla2x00_get_nvram_word(scsi_qla_host_t *, uint32_t);
 extern void qla2x00_write_nvram_word(scsi_qla_host_t *, uint32_t, uint16_t);
+extern uint32_t *qla24xx_read_flash_data(scsi_qla_host_t *, uint32_t *,
+    uint32_t, uint32_t);
+extern uint8_t *qla2x00_read_nvram_data(scsi_qla_host_t *, uint8_t *, uint32_t,
+    uint32_t);
+extern uint8_t *qla24xx_read_nvram_data(scsi_qla_host_t *, uint8_t *, uint32_t,
+    uint32_t);
+extern int qla2x00_write_nvram_data(scsi_qla_host_t *, uint8_t *, uint32_t,
+    uint32_t);
+extern int qla24xx_write_nvram_data(scsi_qla_host_t *, uint8_t *, uint32_t,
+    uint32_t);
+
 /*
  * Global Function Prototypes in qla_dbg.c source file.
  */
 extern void qla2100_fw_dump(scsi_qla_host_t *, int);
 extern void qla2300_fw_dump(scsi_qla_host_t *, int);
+extern void qla24xx_fw_dump(scsi_qla_host_t *, int);
 extern void qla2100_ascii_fw_dump(scsi_qla_host_t *);
 extern void qla2300_ascii_fw_dump(scsi_qla_host_t *);
+extern void qla24xx_ascii_fw_dump(scsi_qla_host_t *);
 extern void qla2x00_dump_regs(scsi_qla_host_t *);
 extern void qla2x00_dump_buffer(uint8_t *, uint32_t);
 extern void qla2x00_print_scsi_cmd(struct scsi_cmnd *);
+extern void qla2x00_dump_pkt(void *);
 
 /*
  * Global Function Prototypes in qla_gs.c source file.
  */
+extern void *qla2x00_prep_ms_iocb(scsi_qla_host_t *, uint32_t, uint32_t);
+extern void *qla24xx_prep_ms_iocb(scsi_qla_host_t *, uint32_t, uint32_t);
 extern int qla2x00_ga_nxt(scsi_qla_host_t *, fc_port_t *);
 extern int qla2x00_gid_pt(scsi_qla_host_t *, sw_info_t *);
 extern int qla2x00_gpn_id(scsi_qla_host_t *, sw_info_t *);
diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c
--- a/drivers/scsi/qla2xxx/qla_gs.c
+++ b/drivers/scsi/qla2xxx/qla_gs.c
@@ -2,7 +2,7 @@
  *                  QLOGIC LINUX SOFTWARE
  *
  * QLogic ISP2x00 device driver for Linux 2.6.x
- * Copyright (C) 2003-2004 QLogic Corporation
+ * Copyright (C) 2003-2005 QLogic Corporation
  * (www.qlogic.com)
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -18,9 +18,6 @@
  */
 #include "qla_def.h"
 
-static inline ms_iocb_entry_t *
-qla2x00_prep_ms_iocb(scsi_qla_host_t *, uint32_t, uint32_t);
-
 static inline struct ct_sns_req *
 qla2x00_prep_ct_req(struct ct_sns_req *, uint16_t, uint16_t);
 
@@ -35,14 +32,14 @@ static int qla2x00_sns_rft_id(scsi_qla_h
 static int qla2x00_sns_rnn_id(scsi_qla_host_t *);
 
 /**
- * qla2x00_prep_ms_iocb() - Prepare common MS IOCB fields for SNS CT query.
+ * qla2x00_prep_ms_iocb() - Prepare common MS/CT IOCB fields for SNS CT query.
  * @ha: HA context
  * @req_size: request size in bytes
  * @rsp_size: response size in bytes
  *
  * Returns a pointer to the @ha's ms_iocb.
  */
-static inline ms_iocb_entry_t *
+void *
 qla2x00_prep_ms_iocb(scsi_qla_host_t *ha, uint32_t req_size, uint32_t rsp_size)
 {
 	ms_iocb_entry_t *ms_pkt;
@@ -72,6 +69,42 @@ qla2x00_prep_ms_iocb(scsi_qla_host_t *ha
 }
 
 /**
+ * qla24xx_prep_ms_iocb() - Prepare common CT IOCB fields for SNS CT query.
+ * @ha: HA context
+ * @req_size: request size in bytes
+ * @rsp_size: response size in bytes
+ *
+ * Returns a pointer to the @ha's ms_iocb.
+ */
+void *
+qla24xx_prep_ms_iocb(scsi_qla_host_t *ha, uint32_t req_size, uint32_t rsp_size)
+{
+	struct ct_entry_24xx *ct_pkt;
+
+	ct_pkt = (struct ct_entry_24xx *)ha->ms_iocb;
+	memset(ct_pkt, 0, sizeof(struct ct_entry_24xx));
+
+	ct_pkt->entry_type = CT_IOCB_TYPE;
+	ct_pkt->entry_count = 1;
+	ct_pkt->nport_handle = __constant_cpu_to_le16(NPH_SNS);
+	ct_pkt->timeout = __constant_cpu_to_le16(25);
+	ct_pkt->cmd_dsd_count = __constant_cpu_to_le16(1);
+	ct_pkt->rsp_dsd_count = __constant_cpu_to_le16(1);
+	ct_pkt->rsp_byte_count = cpu_to_le32(rsp_size);
+	ct_pkt->cmd_byte_count = cpu_to_le32(req_size);
+
+	ct_pkt->dseg_0_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
+	ct_pkt->dseg_0_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
+	ct_pkt->dseg_0_len = ct_pkt->cmd_byte_count;
+
+	ct_pkt->dseg_1_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
+	ct_pkt->dseg_1_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
+	ct_pkt->dseg_1_len = ct_pkt->rsp_byte_count;
+
+	return (ct_pkt);
+}
+
+/**
  * qla2x00_prep_ct_req() - Prepare common CT request fields for SNS query.
  * @ct_req: CT request buffer
  * @cmd: GS command
@@ -93,6 +126,47 @@ qla2x00_prep_ct_req(struct ct_sns_req *c
 	return (ct_req);
 }
 
+static int
+qla2x00_chk_ms_status(scsi_qla_host_t *ha, ms_iocb_entry_t *ms_pkt,
+    struct ct_sns_rsp *ct_rsp, const char *routine)
+{
+	int rval;
+	uint16_t comp_status;
+
+	rval = QLA_FUNCTION_FAILED;
+	if (ms_pkt->entry_status != 0) {
+		DEBUG2_3(printk("scsi(%ld): %s failed, error status (%x).\n",
+		    ha->host_no, routine, ms_pkt->entry_status));
+	} else {
+		if (IS_QLA24XX(ha) || IS_QLA25XX(ha))
+			comp_status =
+			    ((struct ct_entry_24xx *)ms_pkt)->comp_status;
+		else
+			comp_status = le16_to_cpu(ms_pkt->status);
+		switch (comp_status) {
+		case CS_COMPLETE:
+		case CS_DATA_UNDERRUN:
+		case CS_DATA_OVERRUN:		/* Overrun? */
+			if (ct_rsp->header.response !=
+			    __constant_cpu_to_be16(CT_ACCEPT_RESPONSE)) {
+				DEBUG2_3(printk("scsi(%ld): %s failed, "
+				    "rejected request:\n", ha->host_no,
+				    routine));
+				DEBUG2_3(qla2x00_dump_buffer(
+				    (uint8_t *)&ct_rsp->header,
+				    sizeof(struct ct_rsp_hdr)));
+			} else
+				rval = QLA_SUCCESS;
+			break;
+		default:
+			DEBUG2_3(printk("scsi(%ld): %s failed, completion "
+			    "status (%x).\n", ha->host_no, routine,
+			    comp_status));
+			break;
+		}
+	}
+	return rval;
+}
 
 /**
  * qla2x00_ga_nxt() - SNS scan for fabric devices via GA_NXT command.
@@ -116,7 +190,7 @@ qla2x00_ga_nxt(scsi_qla_host_t *ha, fc_p
 
 	/* Issue GA_NXT */
 	/* Prepare common MS IOCB */
-	ms_pkt = qla2x00_prep_ms_iocb(ha, GA_NXT_REQ_SIZE, GA_NXT_RSP_SIZE);
+	ms_pkt = ha->isp_ops.prep_ms_iocb(ha, GA_NXT_REQ_SIZE, GA_NXT_RSP_SIZE);
 
 	/* Prepare CT request */
 	ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, GA_NXT_CMD,
@@ -135,12 +209,8 @@ qla2x00_ga_nxt(scsi_qla_host_t *ha, fc_p
 		/*EMPTY*/
 		DEBUG2_3(printk("scsi(%ld): GA_NXT issue IOCB failed (%d).\n",
 		    ha->host_no, rval));
-	} else if (ct_rsp->header.response !=
-	    __constant_cpu_to_be16(CT_ACCEPT_RESPONSE)) {
-		DEBUG2_3(printk("scsi(%ld): GA_NXT failed, rejected request, "
-		    "ga_nxt_rsp:\n", ha->host_no));
-		DEBUG2_3(qla2x00_dump_buffer((uint8_t *)&ct_rsp->header,
-		    sizeof(struct ct_rsp_hdr)));
+	} else if (qla2x00_chk_ms_status(ha, ms_pkt, ct_rsp, "GA_NXT") !=
+	    QLA_SUCCESS) {
 		rval = QLA_FUNCTION_FAILED;
 	} else {
 		/* Populate fc_port_t entry. */
@@ -206,7 +276,7 @@ qla2x00_gid_pt(scsi_qla_host_t *ha, sw_i
 
 	/* Issue GID_PT */
 	/* Prepare common MS IOCB */
-	ms_pkt = qla2x00_prep_ms_iocb(ha, GID_PT_REQ_SIZE, GID_PT_RSP_SIZE);
+	ms_pkt = ha->isp_ops.prep_ms_iocb(ha, GID_PT_REQ_SIZE, GID_PT_RSP_SIZE);
 
 	/* Prepare CT request */
 	ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, GID_PT_CMD,
@@ -223,12 +293,8 @@ qla2x00_gid_pt(scsi_qla_host_t *ha, sw_i
 		/*EMPTY*/
 		DEBUG2_3(printk("scsi(%ld): GID_PT issue IOCB failed (%d).\n",
 		    ha->host_no, rval));
-	} else if (ct_rsp->header.response !=
-	    __constant_cpu_to_be16(CT_ACCEPT_RESPONSE)) {
-		DEBUG2_3(printk("scsi(%ld): GID_PT failed, rejected request, "
-		    "gid_pt_rsp:\n", ha->host_no));
-		DEBUG2_3(qla2x00_dump_buffer((uint8_t *)&ct_rsp->header,
-		    sizeof(struct ct_rsp_hdr)));
+	} else if (qla2x00_chk_ms_status(ha, ms_pkt, ct_rsp, "GID_PT") !=
+	    QLA_SUCCESS) {
 		rval = QLA_FUNCTION_FAILED;
 	} else {
 		/* Set port IDs in switch info list. */
@@ -251,7 +317,7 @@ qla2x00_gid_pt(scsi_qla_host_t *ha, sw_i
 		 * single call.  Return a failed status, and let GA_NXT handle
 		 * the overload.
 		 */
-		if (i == MAX_FIBRE_DEVICES) 
+		if (i == MAX_FIBRE_DEVICES)
 			rval = QLA_FUNCTION_FAILED;
 	}
 
@@ -282,7 +348,7 @@ qla2x00_gpn_id(scsi_qla_host_t *ha, sw_i
 	for (i = 0; i < MAX_FIBRE_DEVICES; i++) {
 		/* Issue GPN_ID */
 		/* Prepare common MS IOCB */
-		ms_pkt = qla2x00_prep_ms_iocb(ha, GPN_ID_REQ_SIZE,
+		ms_pkt = ha->isp_ops.prep_ms_iocb(ha, GPN_ID_REQ_SIZE,
 		    GPN_ID_RSP_SIZE);
 
 		/* Prepare CT request */
@@ -302,12 +368,8 @@ qla2x00_gpn_id(scsi_qla_host_t *ha, sw_i
 			/*EMPTY*/
 			DEBUG2_3(printk("scsi(%ld): GPN_ID issue IOCB failed "
 			    "(%d).\n", ha->host_no, rval));
-		} else if (ct_rsp->header.response !=
-		    __constant_cpu_to_be16(CT_ACCEPT_RESPONSE)) {
-			DEBUG2_3(printk("scsi(%ld): GPN_ID failed, rejected "
-			    "request, gpn_id_rsp:\n", ha->host_no));
-			DEBUG2_3(qla2x00_dump_buffer((uint8_t *)&ct_rsp->header,
-			    sizeof(struct ct_rsp_hdr)));
+		} else if (qla2x00_chk_ms_status(ha, ms_pkt, ct_rsp,
+		    "GPN_ID") != QLA_SUCCESS) {
 			rval = QLA_FUNCTION_FAILED;
 		} else {
 			/* Save portname */
@@ -347,7 +409,7 @@ qla2x00_gnn_id(scsi_qla_host_t *ha, sw_i
 	for (i = 0; i < MAX_FIBRE_DEVICES; i++) {
 		/* Issue GNN_ID */
 		/* Prepare common MS IOCB */
-		ms_pkt = qla2x00_prep_ms_iocb(ha, GNN_ID_REQ_SIZE,
+		ms_pkt = ha->isp_ops.prep_ms_iocb(ha, GNN_ID_REQ_SIZE,
 		    GNN_ID_RSP_SIZE);
 
 		/* Prepare CT request */
@@ -367,12 +429,8 @@ qla2x00_gnn_id(scsi_qla_host_t *ha, sw_i
 			/*EMPTY*/
 			DEBUG2_3(printk("scsi(%ld): GNN_ID issue IOCB failed "
 			    "(%d).\n", ha->host_no, rval));
-		} else if (ct_rsp->header.response !=
-		    __constant_cpu_to_be16(CT_ACCEPT_RESPONSE)) {
-			DEBUG2_3(printk("scsi(%ld): GNN_ID failed, rejected "
-			    "request, gnn_id_rsp:\n", ha->host_no));
-			DEBUG2_3(qla2x00_dump_buffer((uint8_t *)&ct_rsp->header,
-			    sizeof(struct ct_rsp_hdr)));
+		} else if (qla2x00_chk_ms_status(ha, ms_pkt, ct_rsp,
+		    "GNN_ID") != QLA_SUCCESS) {
 			rval = QLA_FUNCTION_FAILED;
 		} else {
 			/* Save nodename */
@@ -425,7 +483,7 @@ qla2x00_rft_id(scsi_qla_host_t *ha)
 
 	/* Issue RFT_ID */
 	/* Prepare common MS IOCB */
-	ms_pkt = qla2x00_prep_ms_iocb(ha, RFT_ID_REQ_SIZE, RFT_ID_RSP_SIZE);
+	ms_pkt = ha->isp_ops.prep_ms_iocb(ha, RFT_ID_REQ_SIZE, RFT_ID_RSP_SIZE);
 
 	/* Prepare CT request */
 	ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, RFT_ID_CMD,
@@ -446,12 +504,8 @@ qla2x00_rft_id(scsi_qla_host_t *ha)
 		/*EMPTY*/
 		DEBUG2_3(printk("scsi(%ld): RFT_ID issue IOCB failed (%d).\n",
 		    ha->host_no, rval));
-	} else if (ct_rsp->header.response !=
-	    __constant_cpu_to_be16(CT_ACCEPT_RESPONSE)) {
-		DEBUG2_3(printk("scsi(%ld): RFT_ID failed, rejected "
-		    "request, rft_id_rsp:\n", ha->host_no));
-		DEBUG2_3(qla2x00_dump_buffer((uint8_t *)&ct_rsp->header,
-		    sizeof(struct ct_rsp_hdr)));
+	} else if (qla2x00_chk_ms_status(ha, ms_pkt, ct_rsp, "RFT_ID") !=
+	    QLA_SUCCESS) {
 		rval = QLA_FUNCTION_FAILED;
 	} else {
 		DEBUG2(printk("scsi(%ld): RFT_ID exiting normally.\n",
@@ -484,7 +538,7 @@ qla2x00_rff_id(scsi_qla_host_t *ha)
 
 	/* Issue RFF_ID */
 	/* Prepare common MS IOCB */
-	ms_pkt = qla2x00_prep_ms_iocb(ha, RFF_ID_REQ_SIZE, RFF_ID_RSP_SIZE);
+	ms_pkt = ha->isp_ops.prep_ms_iocb(ha, RFF_ID_REQ_SIZE, RFF_ID_RSP_SIZE);
 
 	/* Prepare CT request */
 	ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, RFF_ID_CMD,
@@ -505,12 +559,8 @@ qla2x00_rff_id(scsi_qla_host_t *ha)
 		/*EMPTY*/
 		DEBUG2_3(printk("scsi(%ld): RFF_ID issue IOCB failed (%d).\n",
 		    ha->host_no, rval));
-	} else if (ct_rsp->header.response !=
-	    __constant_cpu_to_be16(CT_ACCEPT_RESPONSE)) {
-		DEBUG2_3(printk("scsi(%ld): RFF_ID failed, rejected "
-		    "request, rff_id_rsp:\n", ha->host_no));
-		DEBUG2_3(qla2x00_dump_buffer((uint8_t *)&ct_rsp->header,
-		    sizeof(struct ct_rsp_hdr)));
+	} else if (qla2x00_chk_ms_status(ha, ms_pkt, ct_rsp, "RFF_ID") !=
+	    QLA_SUCCESS) {
 		rval = QLA_FUNCTION_FAILED;
 	} else {
 		DEBUG2(printk("scsi(%ld): RFF_ID exiting normally.\n",
@@ -541,7 +591,7 @@ qla2x00_rnn_id(scsi_qla_host_t *ha)
 
 	/* Issue RNN_ID */
 	/* Prepare common MS IOCB */
-	ms_pkt = qla2x00_prep_ms_iocb(ha, RNN_ID_REQ_SIZE, RNN_ID_RSP_SIZE);
+	ms_pkt = ha->isp_ops.prep_ms_iocb(ha, RNN_ID_REQ_SIZE, RNN_ID_RSP_SIZE);
 
 	/* Prepare CT request */
 	ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, RNN_ID_CMD,
@@ -553,7 +603,7 @@ qla2x00_rnn_id(scsi_qla_host_t *ha)
 	ct_req->req.rnn_id.port_id[1] = ha->d_id.b.area;
 	ct_req->req.rnn_id.port_id[2] = ha->d_id.b.al_pa;
 
-	memcpy(ct_req->req.rnn_id.node_name, ha->init_cb->node_name, WWN_SIZE);
+	memcpy(ct_req->req.rnn_id.node_name, ha->node_name, WWN_SIZE);
 
 	/* Execute MS IOCB */
 	rval = qla2x00_issue_iocb(ha, ha->ms_iocb, ha->ms_iocb_dma,
@@ -562,12 +612,8 @@ qla2x00_rnn_id(scsi_qla_host_t *ha)
 		/*EMPTY*/
 		DEBUG2_3(printk("scsi(%ld): RNN_ID issue IOCB failed (%d).\n",
 		    ha->host_no, rval));
-	} else if (ct_rsp->header.response !=
-	    __constant_cpu_to_be16(CT_ACCEPT_RESPONSE)) {
-		DEBUG2_3(printk("scsi(%ld): RNN_ID failed, rejected "
-		    "request, rnn_id_rsp:\n", ha->host_no));
-		DEBUG2_3(qla2x00_dump_buffer((uint8_t *)&ct_rsp->header,
-		    sizeof(struct ct_rsp_hdr)));
+	} else if (qla2x00_chk_ms_status(ha, ms_pkt, ct_rsp, "RNN_ID") !=
+	    QLA_SUCCESS) {
 		rval = QLA_FUNCTION_FAILED;
 	} else {
 		DEBUG2(printk("scsi(%ld): RNN_ID exiting normally.\n",
@@ -603,7 +649,7 @@ qla2x00_rsnn_nn(scsi_qla_host_t *ha)
 	/* Issue RSNN_NN */
 	/* Prepare common MS IOCB */
 	/*   Request size adjusted after CT preparation */
-	ms_pkt = qla2x00_prep_ms_iocb(ha, 0, RSNN_NN_RSP_SIZE);
+	ms_pkt = ha->isp_ops.prep_ms_iocb(ha, 0, RSNN_NN_RSP_SIZE);
 
 	/* Prepare CT request */
 	ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, RSNN_NN_CMD,
@@ -611,8 +657,8 @@ qla2x00_rsnn_nn(scsi_qla_host_t *ha)
 	ct_rsp = &ha->ct_sns->p.rsp;
 
 	/* Prepare CT arguments -- node_name, symbolic node_name, size */
-	memcpy(ct_req->req.rsnn_nn.node_name, ha->init_cb->node_name, WWN_SIZE);
-	
+	memcpy(ct_req->req.rsnn_nn.node_name, ha->node_name, WWN_SIZE);
+
 	/* Prepare the Symbolic Node Name */
 	/* Board type */
 	snn = ct_req->req.rsnn_nn.sym_node_name;
@@ -641,12 +687,8 @@ qla2x00_rsnn_nn(scsi_qla_host_t *ha)
 		/*EMPTY*/
 		DEBUG2_3(printk("scsi(%ld): RSNN_NN issue IOCB failed (%d).\n",
 		    ha->host_no, rval));
-	} else if (ct_rsp->header.response !=
-	    __constant_cpu_to_be16(CT_ACCEPT_RESPONSE)) {
-		DEBUG2_3(printk("scsi(%ld): RSNN_NN failed, rejected "
-		    "request, rsnn_id_rsp:\n", ha->host_no));
-		DEBUG2_3(qla2x00_dump_buffer((uint8_t *)&ct_rsp->header,
-		    sizeof(struct ct_rsp_hdr)));
+	} else if (qla2x00_chk_ms_status(ha, ms_pkt, ct_rsp, "RSNN_NN") !=
+	    QLA_SUCCESS) {
 		rval = QLA_FUNCTION_FAILED;
 	} else {
 		DEBUG2(printk("scsi(%ld): RSNN_NN exiting normally.\n",
@@ -821,7 +863,7 @@ qla2x00_sns_gid_pt(scsi_qla_host_t *ha, 
 		 * single call.  Return a failed status, and let GA_NXT handle
 		 * the overload.
 		 */
-		if (i == MAX_FIBRE_DEVICES) 
+		if (i == MAX_FIBRE_DEVICES)
 			rval = QLA_FUNCTION_FAILED;
 	}
 
@@ -1028,14 +1070,14 @@ qla2x00_sns_rnn_id(scsi_qla_host_t *ha)
 	sns_cmd->p.cmd.param[1] = ha->d_id.b.area;
 	sns_cmd->p.cmd.param[2] = ha->d_id.b.domain;
 
-	sns_cmd->p.cmd.param[4] = ha->init_cb->node_name[7];
-	sns_cmd->p.cmd.param[5] = ha->init_cb->node_name[6];
-	sns_cmd->p.cmd.param[6] = ha->init_cb->node_name[5];
-	sns_cmd->p.cmd.param[7] = ha->init_cb->node_name[4];
-	sns_cmd->p.cmd.param[8] = ha->init_cb->node_name[3];
-	sns_cmd->p.cmd.param[9] = ha->init_cb->node_name[2];
-	sns_cmd->p.cmd.param[10] = ha->init_cb->node_name[1];
-	sns_cmd->p.cmd.param[11] = ha->init_cb->node_name[0];
+	sns_cmd->p.cmd.param[4] = ha->node_name[7];
+	sns_cmd->p.cmd.param[5] = ha->node_name[6];
+	sns_cmd->p.cmd.param[6] = ha->node_name[5];
+	sns_cmd->p.cmd.param[7] = ha->node_name[4];
+	sns_cmd->p.cmd.param[8] = ha->node_name[3];
+	sns_cmd->p.cmd.param[9] = ha->node_name[2];
+	sns_cmd->p.cmd.param[10] = ha->node_name[1];
+	sns_cmd->p.cmd.param[11] = ha->node_name[0];
 
 	/* Execute SNS command. */
 	rval = qla2x00_send_sns(ha, ha->sns_cmd_dma, RNN_ID_SNS_CMD_SIZE / 2,
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -2,7 +2,7 @@
  *                  QLOGIC LINUX SOFTWARE
  *
  * QLogic ISP2x00 device driver for Linux 2.6.x
- * Copyright (C) 2003-2004 QLogic Corporation
+ * Copyright (C) 2003-2005 QLogic Corporation
  * (www.qlogic.com)
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -19,6 +19,8 @@
 #include "qla_def.h"
 
 #include <linux/delay.h>
+#include <linux/vmalloc.h>
+#include <linux/firmware.h>
 #include <scsi/scsi_transport_fc.h>
 
 #include "qla_devtbl.h"
@@ -34,17 +36,13 @@
 /*
 *  QLogic ISP2x00 Hardware Support Function Prototypes.
 */
-static int qla2x00_pci_config(scsi_qla_host_t *);
 static int qla2x00_isp_firmware(scsi_qla_host_t *);
-static void qla2x00_reset_chip(scsi_qla_host_t *);
-static int qla2x00_chip_diag(scsi_qla_host_t *);
 static void qla2x00_resize_request_q(scsi_qla_host_t *);
 static int qla2x00_setup_chip(scsi_qla_host_t *);
 static void qla2x00_init_response_q_entries(scsi_qla_host_t *);
 static int qla2x00_init_rings(scsi_qla_host_t *);
 static int qla2x00_fw_ready(scsi_qla_host_t *);
 static int qla2x00_configure_hba(scsi_qla_host_t *);
-static int qla2x00_nvram_config(scsi_qla_host_t *);
 static int qla2x00_configure_loop(scsi_qla_host_t *);
 static int qla2x00_configure_local_loop(scsi_qla_host_t *);
 static void qla2x00_update_fcport(scsi_qla_host_t *, fc_port_t *);
@@ -55,7 +53,6 @@ static int qla2x00_fabric_dev_login(scsi
     uint16_t *);
 
 static int qla2x00_restart_isp(scsi_qla_host_t *);
-static void qla2x00_reset_adapter(scsi_qla_host_t *);
 
 /****************************************************************************/
 /*                QLogic ISP2x00 Hardware Support Functions.                */
@@ -85,26 +82,26 @@ qla2x00_initialize_adapter(scsi_qla_host
 	atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME);
 	atomic_set(&ha->loop_state, LOOP_DOWN);
 	ha->device_flags = 0;
-	ha->sns_retry_cnt = 0;
 	ha->dpc_flags = 0;
-	ha->failback_delay = 0;
 	ha->flags.management_server_logged_in = 0;
 	ha->marker_needed = 0;
 	ha->mbx_flags = 0;
 	ha->isp_abort_cnt = 0;
 	ha->beacon_blink_led = 0;
 
-	rval = qla2x00_pci_config(ha);
+	qla_printk(KERN_INFO, ha, "Configuring PCI space...\n");
+	rval = ha->isp_ops.pci_config(ha);
 	if (rval) {
 		DEBUG2(printk("scsi(%ld): Unable to configure PCI space=n",
 		    ha->host_no));
 		return (rval);
 	}
 
-	qla2x00_reset_chip(ha);
+	ha->isp_ops.reset_chip(ha);
 
 	qla_printk(KERN_INFO, ha, "Configure NVRAM parameters...\n");
-	qla2x00_nvram_config(ha);
+
+	ha->isp_ops.nvram_config(ha);
 
 	qla_printk(KERN_INFO, ha, "Verifying loaded RISC code...\n");
 
@@ -117,7 +114,7 @@ qla2x00_initialize_adapter(scsi_qla_host
 
 		/* If firmware needs to be loaded */
 		if (qla2x00_isp_firmware(ha) != QLA_SUCCESS) {
-			if ((rval = qla2x00_chip_diag(ha)) == QLA_SUCCESS) {
+			if ((rval = ha->isp_ops.chip_diag(ha)) == QLA_SUCCESS) {
 				rval = qla2x00_setup_chip(ha);
 			}
 		}
@@ -126,16 +123,19 @@ qla2x00_initialize_adapter(scsi_qla_host
 		    (rval = qla2x00_init_rings(ha)) == QLA_SUCCESS) {
 check_fw_ready_again:
 			/*
-			 * Wait for a successful LIP up to a maximum 
+			 * Wait for a successful LIP up to a maximum
 			 * of (in seconds): RISC login timeout value,
 			 * RISC retry count value, and port down retry
-			 * value OR a minimum of 4 seconds OR If no 
+			 * value OR a minimum of 4 seconds OR If no
 			 * cable, only 5 seconds.
 			 */
 			rval = qla2x00_fw_ready(ha);
 			if (rval == QLA_SUCCESS) {
 				clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags);
 
+				/* Issue a marker after FW becomes ready. */
+				qla2x00_marker(ha, 0, 0, MK_SYNC_ALL);
+
 				/*
 				 * Wait at most MAX_TARGET RSCNs for a stable
 				 * link.
@@ -171,8 +171,6 @@ check_fw_ready_again:
 
 				if (wait_time == 0)
 					rval = QLA_FUNCTION_FAILED;
-				if (ha->mem_err)
-					restart_risc = 1;
 			} else if (ha->device_flags & DFLG_NO_CABLE)
 				/* If no cable, then all is good. */
 				rval = QLA_SUCCESS;
@@ -181,7 +179,6 @@ check_fw_ready_again:
 
 	if (rval == QLA_SUCCESS) {
 		clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags);
-		ha->marker_needed = 1;
 		qla2x00_marker(ha, 0, 0, MK_SYNC_ALL);
 		ha->marker_needed = 0;
 
@@ -194,110 +191,190 @@ check_fw_ready_again:
 }
 
 /**
- * qla2x00_pci_config() - Setup device PCI configuration registers.
+ * qla2100_pci_config() - Setup ISP21xx PCI configuration registers.
  * @ha: HA context
  *
  * Returns 0 on success.
  */
-static int
-qla2x00_pci_config(scsi_qla_host_t *ha)
+int
+qla2100_pci_config(scsi_qla_host_t *ha)
 {
-	uint16_t	w, mwi;
-	unsigned long   flags = 0;
-	uint32_t	cnt;
-
-	qla_printk(KERN_INFO, ha, "Configuring PCI space...\n");
+	uint16_t w, mwi;
+	unsigned long flags;
+	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
 
-	/* 
-	 * Turn on PCI master; for system BIOSes that don't turn it on by
-	 * default.
-	 */
 	pci_set_master(ha->pdev);
 	mwi = 0;
 	if (pci_set_mwi(ha->pdev))
 		mwi = PCI_COMMAND_INVALIDATE;
 	pci_read_config_word(ha->pdev, PCI_REVISION_ID, &ha->revision);
 
-	if (!ha->iobase)
-		return (QLA_FUNCTION_FAILED);
-
-	/*
-	 * We want to respect framework's setting of PCI configuration space
-	 * command register and also want to make sure that all bits of
-	 * interest to us are properly set in command register.
-	 */
 	pci_read_config_word(ha->pdev, PCI_COMMAND, &w);
 	w |= mwi | (PCI_COMMAND_PARITY | PCI_COMMAND_SERR);
+	pci_write_config_word(ha->pdev, PCI_COMMAND, w);
+
+	/* Reset expansion ROM address decode enable */
+	pci_read_config_word(ha->pdev, PCI_ROM_ADDRESS, &w);
+	w &= ~PCI_ROM_ADDRESS_ENABLE;
+	pci_write_config_word(ha->pdev, PCI_ROM_ADDRESS, w);
 
 	/* Get PCI bus information. */
 	spin_lock_irqsave(&ha->hardware_lock, flags);
-	ha->pci_attr = RD_REG_WORD(&ha->iobase->ctrl_status);
+	ha->pci_attr = RD_REG_WORD(&reg->ctrl_status);
 	spin_unlock_irqrestore(&ha->hardware_lock, flags);
 
-	if (!IS_QLA2100(ha) && !IS_QLA2200(ha)) {
-		pci_write_config_byte(ha->pdev, PCI_LATENCY_TIMER, 0x80);
+	return QLA_SUCCESS;
+}
+
+/**
+ * qla2300_pci_config() - Setup ISP23xx PCI configuration registers.
+ * @ha: HA context
+ *
+ * Returns 0 on success.
+ */
+int
+qla2300_pci_config(scsi_qla_host_t *ha)
+{
+	uint16_t	w, mwi;
+	unsigned long   flags = 0;
+	uint32_t	cnt;
+	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
 
-		/* PCI Specification Revision 2.3 changes */
-		if (IS_QLA2322(ha) || IS_QLA6322(ha))
-			/* Command Register - Reset Interrupt Disable. */
-			w &= ~PCI_COMMAND_INTX_DISABLE;
+	pci_set_master(ha->pdev);
+	mwi = 0;
+	if (pci_set_mwi(ha->pdev))
+		mwi = PCI_COMMAND_INVALIDATE;
+	pci_read_config_word(ha->pdev, PCI_REVISION_ID, &ha->revision);
 
-		/*
-		 * If this is a 2300 card and not 2312, reset the
-		 * COMMAND_INVALIDATE due to a bug in the 2300. Unfortunately,
-		 * the 2310 also reports itself as a 2300 so we need to get the
-		 * fb revision level -- a 6 indicates it really is a 2300 and
-		 * not a 2310.
-		 */
-		if (IS_QLA2300(ha)) {
-			spin_lock_irqsave(&ha->hardware_lock, flags);
+	pci_read_config_word(ha->pdev, PCI_COMMAND, &w);
+	w |= mwi | (PCI_COMMAND_PARITY | PCI_COMMAND_SERR);
 
-			/* Pause RISC. */
-			WRT_REG_WORD(&ha->iobase->hccr, HCCR_PAUSE_RISC);
-			for (cnt = 0; cnt < 30000; cnt++) {
-				if ((RD_REG_WORD(&ha->iobase->hccr) &
-				    HCCR_RISC_PAUSE) != 0)
-					break;
-	
-				udelay(10);
-			}
+	if (IS_QLA2322(ha) || IS_QLA6322(ha))
+		w &= ~PCI_COMMAND_INTX_DISABLE;
 
-			/* Select FPM registers. */
-			WRT_REG_WORD(&ha->iobase->ctrl_status, 0x20);
-			RD_REG_WORD(&ha->iobase->ctrl_status);
+	/*
+	 * If this is a 2300 card and not 2312, reset the
+	 * COMMAND_INVALIDATE due to a bug in the 2300. Unfortunately,
+	 * the 2310 also reports itself as a 2300 so we need to get the
+	 * fb revision level -- a 6 indicates it really is a 2300 and
+	 * not a 2310.
+	 */
+	if (IS_QLA2300(ha)) {
+		spin_lock_irqsave(&ha->hardware_lock, flags);
 
-			/* Get the fb rev level */
-			ha->fb_rev = RD_FB_CMD_REG(ha, ha->iobase);
+		/* Pause RISC. */
+		WRT_REG_WORD(&reg->hccr, HCCR_PAUSE_RISC);
+		for (cnt = 0; cnt < 30000; cnt++) {
+			if ((RD_REG_WORD(&reg->hccr) & HCCR_RISC_PAUSE) != 0)
+				break;
 
-			if (ha->fb_rev == FPM_2300)
-				w &= ~PCI_COMMAND_INVALIDATE;
+			udelay(10);
+		}
 
-			/* Deselect FPM registers. */
-			WRT_REG_WORD(&ha->iobase->ctrl_status, 0x0);
-			RD_REG_WORD(&ha->iobase->ctrl_status);
+		/* Select FPM registers. */
+		WRT_REG_WORD(&reg->ctrl_status, 0x20);
+		RD_REG_WORD(&reg->ctrl_status);
 
-			/* Release RISC module. */
-			WRT_REG_WORD(&ha->iobase->hccr, HCCR_RELEASE_RISC);
-			for (cnt = 0; cnt < 30000; cnt++) {
-				if ((RD_REG_WORD(&ha->iobase->hccr) &
-				    HCCR_RISC_PAUSE) == 0)
-					break;
-	
-				udelay(10);
-			}
+		/* Get the fb rev level */
+		ha->fb_rev = RD_FB_CMD_REG(ha, reg);
 
-			spin_unlock_irqrestore(&ha->hardware_lock, flags);
+		if (ha->fb_rev == FPM_2300)
+			w &= ~PCI_COMMAND_INVALIDATE;
+
+		/* Deselect FPM registers. */
+		WRT_REG_WORD(&reg->ctrl_status, 0x0);
+		RD_REG_WORD(&reg->ctrl_status);
+
+		/* Release RISC module. */
+		WRT_REG_WORD(&reg->hccr, HCCR_RELEASE_RISC);
+		for (cnt = 0; cnt < 30000; cnt++) {
+			if ((RD_REG_WORD(&reg->hccr) & HCCR_RISC_PAUSE) == 0)
+				break;
+
+			udelay(10);
 		}
+
+		spin_unlock_irqrestore(&ha->hardware_lock, flags);
 	}
+	pci_write_config_word(ha->pdev, PCI_COMMAND, w);
+
+	pci_write_config_byte(ha->pdev, PCI_LATENCY_TIMER, 0x80);
+
+	/* Reset expansion ROM address decode enable */
+	pci_read_config_word(ha->pdev, PCI_ROM_ADDRESS, &w);
+	w &= ~PCI_ROM_ADDRESS_ENABLE;
+	pci_write_config_word(ha->pdev, PCI_ROM_ADDRESS, w);
+
+	/* Get PCI bus information. */
+	spin_lock_irqsave(&ha->hardware_lock, flags);
+	ha->pci_attr = RD_REG_WORD(&reg->ctrl_status);
+	spin_unlock_irqrestore(&ha->hardware_lock, flags);
+
+	return QLA_SUCCESS;
+}
+
+/**
+ * qla24xx_pci_config() - Setup ISP24xx PCI configuration registers.
+ * @ha: HA context
+ *
+ * Returns 0 on success.
+ */
+int
+qla24xx_pci_config(scsi_qla_host_t *ha)
+{
+	uint16_t w, mwi;
+	unsigned long flags = 0;
+	struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
+	int pcix_cmd_reg, pcie_dctl_reg;
+
+	pci_set_master(ha->pdev);
+	mwi = 0;
+	if (pci_set_mwi(ha->pdev))
+		mwi = PCI_COMMAND_INVALIDATE;
+	pci_read_config_word(ha->pdev, PCI_REVISION_ID, &ha->revision);
 
+	pci_read_config_word(ha->pdev, PCI_COMMAND, &w);
+	w |= mwi | (PCI_COMMAND_PARITY | PCI_COMMAND_SERR);
+	w &= ~PCI_COMMAND_INTX_DISABLE;
 	pci_write_config_word(ha->pdev, PCI_COMMAND, w);
 
+	pci_write_config_byte(ha->pdev, PCI_LATENCY_TIMER, 0x80);
+
+	/* PCI-X -- adjust Maximum Memory Read Byte Count (2048). */
+	pcix_cmd_reg = pci_find_capability(ha->pdev, PCI_CAP_ID_PCIX);
+	if (pcix_cmd_reg) {
+		uint16_t pcix_cmd;
+
+		pcix_cmd_reg += PCI_X_CMD;
+		pci_read_config_word(ha->pdev, pcix_cmd_reg, &pcix_cmd);
+		pcix_cmd &= ~PCI_X_CMD_MAX_READ;
+		pcix_cmd |= 0x0008;
+		pci_write_config_word(ha->pdev, pcix_cmd_reg, pcix_cmd);
+	}
+
+	/* PCIe -- adjust Maximum Read Request Size (2048). */
+	pcie_dctl_reg = pci_find_capability(ha->pdev, PCI_CAP_ID_EXP);
+	if (pcie_dctl_reg) {
+		uint16_t pcie_dctl;
+
+		pcie_dctl_reg += PCI_EXP_DEVCTL;
+		pci_read_config_word(ha->pdev, pcie_dctl_reg, &pcie_dctl);
+		pcie_dctl &= ~PCI_EXP_DEVCTL_READRQ;
+		pcie_dctl |= 0x4000;
+		pci_write_config_word(ha->pdev, pcie_dctl_reg, pcie_dctl);
+	}
+
 	/* Reset expansion ROM address decode enable */
 	pci_read_config_word(ha->pdev, PCI_ROM_ADDRESS, &w);
 	w &= ~PCI_ROM_ADDRESS_ENABLE;
 	pci_write_config_word(ha->pdev, PCI_ROM_ADDRESS, w);
 
-	return (QLA_SUCCESS);
+	/* Get PCI bus information. */
+	spin_lock_irqsave(&ha->hardware_lock, flags);
+	ha->pci_attr = RD_REG_DWORD(&reg->ctrl_status);
+	spin_unlock_irqrestore(&ha->hardware_lock, flags);
+
+	return QLA_SUCCESS;
 }
 
 /**
@@ -312,7 +389,7 @@ qla2x00_isp_firmware(scsi_qla_host_t *ha
 	int  rval;
 
 	/* Assume loading risc code */
-	rval = QLA_FUNCTION_FAILED; 
+	rval = QLA_FUNCTION_FAILED;
 
 	if (ha->flags.disable_risc_code_load) {
 		DEBUG2(printk("scsi(%ld): RISC CODE NOT loaded\n",
@@ -320,7 +397,9 @@ qla2x00_isp_firmware(scsi_qla_host_t *ha
 		qla_printk(KERN_INFO, ha, "RISC CODE NOT loaded\n");
 
 		/* Verify checksum of loaded RISC code. */
-		rval = qla2x00_verify_checksum(ha);
+		rval = qla2x00_verify_checksum(ha,
+		    IS_QLA24XX(ha) || IS_QLA25XX(ha) ? RISC_SADDRESS :
+		    *ha->brd_info->fw_info[0].fwstart);
 	}
 
 	if (rval) {
@@ -337,17 +416,16 @@ qla2x00_isp_firmware(scsi_qla_host_t *ha
  *
  * Returns 0 on success.
  */
-static void
-qla2x00_reset_chip(scsi_qla_host_t *ha) 
+void
+qla2x00_reset_chip(scsi_qla_host_t *ha)
 {
 	unsigned long   flags = 0;
-	device_reg_t __iomem *reg = ha->iobase;
+	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
 	uint32_t	cnt;
 	unsigned long	mbx_flags = 0;
 	uint16_t	cmd;
 
-	/* Disable ISP interrupts. */
-	qla2x00_disable_intrs(ha);
+	ha->isp_ops.disable_intrs(ha);
 
 	spin_lock_irqsave(&ha->hardware_lock, flags);
 
@@ -486,16 +564,95 @@ qla2x00_reset_chip(scsi_qla_host_t *ha) 
 }
 
 /**
+ * qla24xx_reset_risc() - Perform full reset of ISP24xx RISC.
+ * @ha: HA context
+ *
+ * Returns 0 on success.
+ */
+static inline void
+qla24xx_reset_risc(scsi_qla_host_t *ha)
+{
+	unsigned long flags = 0;
+	struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
+	uint32_t cnt, d2;
+
+	spin_lock_irqsave(&ha->hardware_lock, flags);
+
+	/* Reset RISC. */
+	WRT_REG_DWORD(&reg->ctrl_status, CSRX_DMA_SHUTDOWN|MWB_4096_BYTES);
+	for (cnt = 0; cnt < 30000; cnt++) {
+		if ((RD_REG_DWORD(&reg->ctrl_status) & CSRX_DMA_ACTIVE) == 0)
+			break;
+
+		udelay(10);
+	}
+
+	WRT_REG_DWORD(&reg->ctrl_status,
+	    CSRX_ISP_SOFT_RESET|CSRX_DMA_SHUTDOWN|MWB_4096_BYTES);
+	RD_REG_DWORD(&reg->ctrl_status);
+
+	/* Wait for firmware to complete NVRAM accesses. */
+	udelay(5);
+	d2 = (uint32_t) RD_REG_WORD(&reg->mailbox0);
+	for (cnt = 10000 ; cnt && d2; cnt--) {
+		udelay(5);
+		d2 = (uint32_t) RD_REG_WORD(&reg->mailbox0);
+		barrier();
+	}
+
+	udelay(20);
+	d2 = RD_REG_DWORD(&reg->ctrl_status);
+	for (cnt = 6000000 ; cnt && (d2 & CSRX_ISP_SOFT_RESET); cnt--) {
+		udelay(5);
+		d2 = RD_REG_DWORD(&reg->ctrl_status);
+		barrier();
+	}
+
+	WRT_REG_DWORD(&reg->hccr, HCCRX_SET_RISC_RESET);
+	RD_REG_DWORD(&reg->hccr);
+
+	WRT_REG_DWORD(&reg->hccr, HCCRX_REL_RISC_PAUSE);
+	RD_REG_DWORD(&reg->hccr);
+
+	WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_RESET);
+	RD_REG_DWORD(&reg->hccr);
+
+	d2 = (uint32_t) RD_REG_WORD(&reg->mailbox0);
+	for (cnt = 6000000 ; cnt && d2; cnt--) {
+		udelay(5);
+		d2 = (uint32_t) RD_REG_WORD(&reg->mailbox0);
+		barrier();
+	}
+
+	spin_unlock_irqrestore(&ha->hardware_lock, flags);
+}
+
+/**
+ * qla24xx_reset_chip() - Reset ISP24xx chip.
+ * @ha: HA context
+ *
+ * Returns 0 on success.
+ */
+void
+qla24xx_reset_chip(scsi_qla_host_t *ha)
+{
+	ha->isp_ops.disable_intrs(ha);
+
+	/* Perform RISC reset. */
+	qla24xx_reset_risc(ha);
+}
+
+/**
  * qla2x00_chip_diag() - Test chip for proper operation.
  * @ha: HA context
  *
  * Returns 0 on success.
  */
-static int
+int
 qla2x00_chip_diag(scsi_qla_host_t *ha)
 {
 	int		rval;
-	device_reg_t __iomem *reg = ha->iobase;
+	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
 	unsigned long	flags = 0;
 	uint16_t	data;
 	uint32_t	cnt;
@@ -540,7 +697,7 @@ qla2x00_chip_diag(scsi_qla_host_t *ha)
 		for (cnt = 6000000; cnt && (data == MBS_BUSY); cnt--) {
 			udelay(5);
 			data = RD_MAILBOX_REG(ha, reg, 0);
-			barrier(); 
+			barrier();
 		}
 	} else
 		udelay(10);
@@ -611,6 +768,51 @@ chip_diag_failed:
 }
 
 /**
+ * qla24xx_chip_diag() - Test ISP24xx for proper operation.
+ * @ha: HA context
+ *
+ * Returns 0 on success.
+ */
+int
+qla24xx_chip_diag(scsi_qla_host_t *ha)
+{
+	int rval;
+
+	/* Perform RISC reset. */
+	qla24xx_reset_risc(ha);
+
+	ha->fw_transfer_size = REQUEST_ENTRY_SIZE * 1024;
+
+	rval = qla2x00_mbx_reg_test(ha);
+	if (rval) {
+		DEBUG(printk("scsi(%ld): Failed mailbox send register test\n",
+		    ha->host_no));
+		qla_printk(KERN_WARNING, ha,
+		    "Failed mailbox send register test\n");
+	} else {
+		/* Flag a successful rval */
+		rval = QLA_SUCCESS;
+	}
+
+	return rval;
+}
+
+static void
+qla2x00_alloc_fw_dump(scsi_qla_host_t *ha)
+{
+	ha->fw_dumped = 0;
+	ha->fw_dump24_len = sizeof(struct qla24xx_fw_dump);
+	ha->fw_dump24_len += (ha->fw_memory_size - 0x100000) * sizeof(uint32_t);
+	ha->fw_dump24 = vmalloc(ha->fw_dump24_len);
+	if (ha->fw_dump24)
+		qla_printk(KERN_INFO, ha, "Allocated (%d KB) for firmware "
+		    "dump...\n", ha->fw_dump24_len / 1024);
+	else
+		qla_printk(KERN_WARNING, ha, "Unable to allocate (%d KB) for "
+		    "firmware dump!!!\n", ha->fw_dump24_len / 1024);
+}
+
+/**
  * qla2x00_resize_request_q() - Resize request queue given available ISP memory.
  * @ha: HA context
  *
@@ -629,6 +831,9 @@ qla2x00_resize_request_q(scsi_qla_host_t
 	if (IS_QLA2100(ha) || IS_QLA2200(ha))
 		return;
 
+	if (IS_QLA24XX(ha) || IS_QLA25XX(ha))
+		qla2x00_alloc_fw_dump(ha);
+
 	/* Retrieve IOCB counts available to the firmware. */
 	rval = qla2x00_get_resource_cnts(ha, NULL, NULL, NULL, &fw_iocb_cnt);
 	if (rval)
@@ -672,87 +877,22 @@ qla2x00_resize_request_q(scsi_qla_host_t
 static int
 qla2x00_setup_chip(scsi_qla_host_t *ha)
 {
-	int		rval;
-	uint16_t	cnt;
-	uint16_t	*risc_code;
-	unsigned long	risc_address;
-	unsigned long	risc_code_size;
-	int		num;
-	int		i;
-	uint16_t	*req_ring;
-	struct qla_fw_info *fw_iter;
-
-	rval = QLA_SUCCESS;
+	int rval;
+	uint32_t srisc_address = 0;
 
 	/* Load firmware sequences */
-	fw_iter = ha->brd_info->fw_info;
-	while (fw_iter->addressing != FW_INFO_ADDR_NOMORE) {
-		risc_code = fw_iter->fwcode;
-		risc_code_size = *fw_iter->fwlen;
-
-		if (fw_iter->addressing == FW_INFO_ADDR_NORMAL) {
-			risc_address = *fw_iter->fwstart;
-		} else {
-			/* Extended address */
-			risc_address = *fw_iter->lfwstart;
-		}
-
-		num = 0;
-		rval = 0;
-		while (risc_code_size > 0 && !rval) {
-			cnt = (uint16_t)(ha->fw_transfer_size >> 1);
-			if (cnt > risc_code_size)
-				cnt = risc_code_size;
-
-			DEBUG7(printk("scsi(%ld): Loading risc segment@ "
-			    "addr %p, number of bytes 0x%x, offset 0x%lx.\n",
-			    ha->host_no, risc_code, cnt, risc_address));
-
-			req_ring = (uint16_t *)ha->request_ring;
-			for (i = 0; i < cnt; i++)
-				req_ring[i] = cpu_to_le16(risc_code[i]);
-
-			if (fw_iter->addressing == FW_INFO_ADDR_NORMAL) {
-				rval = qla2x00_load_ram(ha,
-				    ha->request_dma, risc_address, cnt);
-			} else {
-				rval = qla2x00_load_ram_ext(ha,
-				    ha->request_dma, risc_address, cnt);
-			}
-			if (rval) {
-				DEBUG(printk("scsi(%ld): [ERROR] Failed to "
-				    "load segment %d of firmware\n",
-				    ha->host_no, num));
-				qla_printk(KERN_WARNING, ha,
-				    "[ERROR] Failed to load "
-				    "segment %d of firmware\n", num);
-
-				qla2x00_dump_regs(ha);
-				break;
-			}
-
-			risc_code += cnt;
-			risc_address += cnt;
-			risc_code_size -= cnt;
-			num++;
-		}
-
-		/* Next firmware sequence */
-		fw_iter++;
-	}
-
-	/* Verify checksum of loaded RISC code. */
-	if (!rval) {
+	rval = ha->isp_ops.load_risc(ha, &srisc_address);
+	if (rval == QLA_SUCCESS) {
 		DEBUG(printk("scsi(%ld): Verifying Checksum of loaded RISC "
 		    "code.\n", ha->host_no));
 
-		rval = qla2x00_verify_checksum(ha);
+		rval = qla2x00_verify_checksum(ha, srisc_address);
 		if (rval == QLA_SUCCESS) {
 			/* Start firmware execution. */
 			DEBUG(printk("scsi(%ld): Checksum OK, start "
 			    "firmware.\n", ha->host_no));
 
-			rval = qla2x00_execute_fw(ha);
+			rval = qla2x00_execute_fw(ha, srisc_address);
 			/* Retrieve firmware information. */
 			if (rval == QLA_SUCCESS && ha->fw_major_version == 0) {
 				qla2x00_get_fw_version(ha,
@@ -806,7 +946,7 @@ qla2x00_init_response_q_entries(scsi_qla
  *
  * Returns 0 on success.
  */
-static void
+void
 qla2x00_update_fw_options(scsi_qla_host_t *ha)
 {
 	uint16_t swing, emphasis, tx_sens, rx_sens;
@@ -832,7 +972,7 @@ qla2x00_update_fw_options(scsi_qla_host_
 		emphasis = (ha->fw_seriallink_options[2] &
 		    (BIT_4 | BIT_3)) >> 3;
 		tx_sens = ha->fw_seriallink_options[0] &
-		    (BIT_3 | BIT_2 | BIT_1 | BIT_0); 
+		    (BIT_3 | BIT_2 | BIT_1 | BIT_0);
 		rx_sens = (ha->fw_seriallink_options[0] &
 		    (BIT_7 | BIT_6 | BIT_5 | BIT_4)) >> 4;
 		ha->fw_options[10] = (emphasis << 14) | (swing << 8);
@@ -850,7 +990,7 @@ qla2x00_update_fw_options(scsi_qla_host_
 		    (BIT_7 | BIT_6 | BIT_5)) >> 5;
 		emphasis = ha->fw_seriallink_options[3] & (BIT_1 | BIT_0);
 		tx_sens = ha->fw_seriallink_options[1] &
-		    (BIT_3 | BIT_2 | BIT_1 | BIT_0); 
+		    (BIT_3 | BIT_2 | BIT_1 | BIT_0);
 		rx_sens = (ha->fw_seriallink_options[1] &
 		    (BIT_7 | BIT_6 | BIT_5 | BIT_4)) >> 4;
 		ha->fw_options[11] = (emphasis << 14) | (swing << 8);
@@ -876,6 +1016,69 @@ qla2x00_update_fw_options(scsi_qla_host_
 	qla2x00_set_fw_options(ha, ha->fw_options);
 }
 
+void
+qla24xx_update_fw_options(scsi_qla_host_t *ha)
+{
+	int rval;
+
+	/* Update Serial Link options. */
+	if ((ha->fw_seriallink_options24[0] & BIT_0) == 0)
+		return;
+
+	rval = qla2x00_set_serdes_params(ha, ha->fw_seriallink_options24[1],
+	    ha->fw_seriallink_options24[2], ha->fw_seriallink_options24[3]);
+	if (rval != QLA_SUCCESS) {
+		qla_printk(KERN_WARNING, ha,
+		    "Unable to update Serial Link options (%x).\n", rval);
+	}
+}
+
+void
+qla2x00_config_rings(struct scsi_qla_host *ha)
+{
+	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
+
+	/* Setup ring parameters in initialization control block. */
+	ha->init_cb->request_q_outpointer = __constant_cpu_to_le16(0);
+	ha->init_cb->response_q_inpointer = __constant_cpu_to_le16(0);
+	ha->init_cb->request_q_length = cpu_to_le16(ha->request_q_length);
+	ha->init_cb->response_q_length = cpu_to_le16(ha->response_q_length);
+	ha->init_cb->request_q_address[0] = cpu_to_le32(LSD(ha->request_dma));
+	ha->init_cb->request_q_address[1] = cpu_to_le32(MSD(ha->request_dma));
+	ha->init_cb->response_q_address[0] = cpu_to_le32(LSD(ha->response_dma));
+	ha->init_cb->response_q_address[1] = cpu_to_le32(MSD(ha->response_dma));
+
+	WRT_REG_WORD(ISP_REQ_Q_IN(ha, reg), 0);
+	WRT_REG_WORD(ISP_REQ_Q_OUT(ha, reg), 0);
+	WRT_REG_WORD(ISP_RSP_Q_IN(ha, reg), 0);
+	WRT_REG_WORD(ISP_RSP_Q_OUT(ha, reg), 0);
+	RD_REG_WORD(ISP_RSP_Q_OUT(ha, reg));		/* PCI Posting. */
+}
+
+void
+qla24xx_config_rings(struct scsi_qla_host *ha)
+{
+	struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
+	struct init_cb_24xx *icb;
+
+	/* Setup ring parameters in initialization control block. */
+	icb = (struct init_cb_24xx *)ha->init_cb;
+	icb->request_q_outpointer = __constant_cpu_to_le16(0);
+	icb->response_q_inpointer = __constant_cpu_to_le16(0);
+	icb->request_q_length = cpu_to_le16(ha->request_q_length);
+	icb->response_q_length = cpu_to_le16(ha->response_q_length);
+	icb->request_q_address[0] = cpu_to_le32(LSD(ha->request_dma));
+	icb->request_q_address[1] = cpu_to_le32(MSD(ha->request_dma));
+	icb->response_q_address[0] = cpu_to_le32(LSD(ha->response_dma));
+	icb->response_q_address[1] = cpu_to_le32(MSD(ha->response_dma));
+
+	WRT_REG_DWORD(&reg->req_q_in, 0);
+	WRT_REG_DWORD(&reg->req_q_out, 0);
+	WRT_REG_DWORD(&reg->rsp_q_in, 0);
+	WRT_REG_DWORD(&reg->rsp_q_out, 0);
+	RD_REG_DWORD(&reg->rsp_q_out);
+}
+
 /**
  * qla2x00_init_rings() - Initializes firmware.
  * @ha: HA context
@@ -891,7 +1094,6 @@ qla2x00_init_rings(scsi_qla_host_t *ha)
 	int	rval;
 	unsigned long flags = 0;
 	int cnt;
-	device_reg_t __iomem *reg = ha->iobase;
 
 	spin_lock_irqsave(&ha->hardware_lock, flags);
 
@@ -912,32 +1114,18 @@ qla2x00_init_rings(scsi_qla_host_t *ha)
 	ha->response_ring_ptr = ha->response_ring;
 	ha->rsp_ring_index    = 0;
 
-	/* Setup ring parameters in initialization control block. */
-	ha->init_cb->request_q_outpointer = __constant_cpu_to_le16(0);
-	ha->init_cb->response_q_inpointer = __constant_cpu_to_le16(0);
-	ha->init_cb->request_q_length = cpu_to_le16(ha->request_q_length);
-	ha->init_cb->response_q_length = cpu_to_le16(ha->response_q_length);
-	ha->init_cb->request_q_address[0] = cpu_to_le32(LSD(ha->request_dma));
-	ha->init_cb->request_q_address[1] = cpu_to_le32(MSD(ha->request_dma));
-	ha->init_cb->response_q_address[0] = cpu_to_le32(LSD(ha->response_dma));
-	ha->init_cb->response_q_address[1] = cpu_to_le32(MSD(ha->response_dma));
-
 	/* Initialize response queue entries */
 	qla2x00_init_response_q_entries(ha);
 
- 	WRT_REG_WORD(ISP_REQ_Q_IN(ha, reg), 0);
- 	WRT_REG_WORD(ISP_REQ_Q_OUT(ha, reg), 0);
- 	WRT_REG_WORD(ISP_RSP_Q_IN(ha, reg), 0);
- 	WRT_REG_WORD(ISP_RSP_Q_OUT(ha, reg), 0);
-	RD_REG_WORD(ISP_RSP_Q_OUT(ha, reg));		/* PCI Posting. */
+	ha->isp_ops.config_rings(ha);
 
 	spin_unlock_irqrestore(&ha->hardware_lock, flags);
 
 	/* Update any ISP specific firmware options before initialization. */
-	qla2x00_update_fw_options(ha);
+	ha->isp_ops.update_fw_options(ha);
 
 	DEBUG(printk("scsi(%ld): Issue init firmware.\n", ha->host_no));
-	rval = qla2x00_init_firmware(ha, sizeof(init_cb_t));
+	rval = qla2x00_init_firmware(ha, ha->init_cb_size);
 	if (rval) {
 		DEBUG2_3(printk("scsi(%ld): Init firmware **** FAILED ****.\n",
 		    ha->host_no));
@@ -967,7 +1155,7 @@ qla2x00_fw_ready(scsi_qla_host_t *ha)
 	rval = QLA_SUCCESS;
 
 	/* 20 seconds for loop down. */
-	min_wait = 20;		
+	min_wait = 20;
 
 	/*
 	 * Firmware should take at most one RATOV to login, plus 5 seconds for
@@ -1013,8 +1201,8 @@ qla2x00_fw_ready(scsi_qla_host_t *ha)
 			    (fw_state >= FSTATE_LOSS_OF_SYNC ||
 				fw_state == FSTATE_WAIT_AL_PA)) {
 				/* Loop down. Timeout on min_wait for states
-				 * other than Wait for Login. 
-				 */	
+				 * other than Wait for Login.
+				 */
 				if (time_after_eq(jiffies, mtime)) {
 					qla_printk(KERN_INFO, ha,
 					    "Cable is unplugged...\n");
@@ -1169,41 +1357,36 @@ qla2x00_configure_hba(scsi_qla_host_t *h
 * Returns:
 *      0 = success.
 */
-static int
+int
 qla2x00_nvram_config(scsi_qla_host_t *ha)
 {
-	int   rval;
-	uint8_t   chksum = 0;
-	uint16_t  cnt;
-	uint8_t   *dptr1, *dptr2;
-	init_cb_t *icb   = ha->init_cb;
-	nvram_t *nv    = (nvram_t *)ha->request_ring;
-	uint16_t  *wptr  = (uint16_t *)ha->request_ring;
-	device_reg_t __iomem *reg = ha->iobase;
-	uint8_t  timer_mode;
+	int             rval;
+	uint8_t         chksum = 0;
+	uint16_t        cnt;
+	uint8_t         *dptr1, *dptr2;
+	init_cb_t       *icb = ha->init_cb;
+	nvram_t         *nv = (nvram_t *)ha->request_ring;
+	uint8_t         *ptr = (uint8_t *)ha->request_ring;
+	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
+	uint8_t         timer_mode;
 
 	rval = QLA_SUCCESS;
 
 	/* Determine NVRAM starting address. */
+	ha->nvram_size = sizeof(nvram_t);
 	ha->nvram_base = 0;
 	if (!IS_QLA2100(ha) && !IS_QLA2200(ha) && !IS_QLA2300(ha))
 		if ((RD_REG_WORD(&reg->ctrl_status) >> 14) == 1)
 			ha->nvram_base = 0x80;
 
 	/* Get NVRAM data and calculate checksum. */
-	qla2x00_lock_nvram_access(ha);
-	for (cnt = 0; cnt < sizeof(nvram_t)/2; cnt++) {
-		*wptr = cpu_to_le16(qla2x00_get_nvram_word(ha,
-		    (cnt+ha->nvram_base)));
-		chksum += (uint8_t)*wptr;
-		chksum += (uint8_t)(*wptr >> 8);
-		wptr++;
-	}
-	qla2x00_unlock_nvram_access(ha);
+	ha->isp_ops.read_nvram(ha, ptr, ha->nvram_base, ha->nvram_size);
+	for (cnt = 0, chksum = 0; cnt < ha->nvram_size; cnt++)
+		chksum += *ptr++;
 
 	DEBUG5(printk("scsi(%ld): Contents of NVRAM\n", ha->host_no));
 	DEBUG5(qla2x00_dump_buffer((uint8_t *)ha->request_ring,
-	    sizeof(nvram_t)));
+	    ha->nvram_size));
 
 	/* Bad NVRAM data, set defaults parameters. */
 	if (chksum || nv->id[0] != 'I' || nv->id[1] != 'S' ||
@@ -1218,7 +1401,7 @@ qla2x00_nvram_config(scsi_qla_host_t *ha
 		/*
 		 * Set default initialization control block.
 		 */
-		memset(nv, 0, sizeof(nvram_t));
+		memset(nv, 0, ha->nvram_size);
 		nv->parameter_block_version = ICB_VERSION;
 
 		if (IS_QLA23XX(ha)) {
@@ -1278,7 +1461,7 @@ qla2x00_nvram_config(scsi_qla_host_t *ha
 #endif
 
 	/* Reset Initialization control block */
-	memset(icb, 0, sizeof(init_cb_t));
+	memset(icb, 0, ha->init_cb_size);
 
 	/*
 	 * Setup driver NVRAM options.
@@ -1291,6 +1474,7 @@ qla2x00_nvram_config(scsi_qla_host_t *ha
 	if (IS_QLA23XX(ha)) {
 		nv->firmware_options[0] |= BIT_2;
 		nv->firmware_options[0] &= ~BIT_3;
+		nv->add_firmware_options[1] |= BIT_5 | BIT_4;
 
 		if (IS_QLA2300(ha)) {
 			if (ha->fb_rev == FPM_2310) {
@@ -1372,8 +1556,6 @@ qla2x00_nvram_config(scsi_qla_host_t *ha
 	/*
 	 * Set host adapter parameters.
 	 */
-	ha->nvram_version = nv->nvram_version;
-
 	ha->flags.disable_risc_code_load = ((nv->host_p[0] & BIT_4) ? 1 : 0);
 	/* Always load RISC code on non ISP2[12]00 chips. */
 	if (!IS_QLA2100(ha) && !IS_QLA2200(ha))
@@ -1393,7 +1575,8 @@ qla2x00_nvram_config(scsi_qla_host_t *ha
 	ha->serial0 = icb->port_name[5];
 	ha->serial1 = icb->port_name[6];
 	ha->serial2 = icb->port_name[7];
-	memcpy(ha->node_name, icb->node_name, WWN_SIZE);
+	ha->node_name = icb->node_name;
+	ha->port_name = icb->port_name;
 
 	icb->execution_throttle = __constant_cpu_to_le16(0xFFFF);
 
@@ -1410,13 +1593,8 @@ qla2x00_nvram_config(scsi_qla_host_t *ha
 	/* Set minimum RATOV to 200 tenths of a second. */
 	ha->r_a_tov = 200;
 
-	ha->minimum_timeout =
-	    (ha->login_timeout * ha->retry_count) + nv->port_down_retry_count;
 	ha->loop_reset_delay = nv->reset_delay;
 
-	/* Will get the value from NVRAM. */
-	ha->loop_down_timeout = LOOP_DOWN_TIMEOUT;
-
 	/* Link Down Timeout = 0:
 	 *
 	 * 	When Port Down timer expires we will start returning
@@ -1426,20 +1604,15 @@ qla2x00_nvram_config(scsi_qla_host_t *ha
 	 *
 	 *	 The driver waits for the link to come up after link down
 	 *	 before returning I/Os to OS with "DID_NO_CONNECT".
-	 */						
+	 */
 	if (nv->link_down_timeout == 0) {
 		ha->loop_down_abort_time =
-		    (LOOP_DOWN_TIME - ha->loop_down_timeout);
+		    (LOOP_DOWN_TIME - LOOP_DOWN_TIMEOUT);
 	} else {
 		ha->link_down_timeout =	 nv->link_down_timeout;
 		ha->loop_down_abort_time =
 		    (LOOP_DOWN_TIME - ha->link_down_timeout);
-	} 
-
-	ha->max_luns = MAX_LUNS;
-	ha->max_probe_luns = le16_to_cpu(nv->max_luns_per_target);
-	if (ha->max_probe_luns == 0)
-		ha->max_probe_luns = MIN_LUNS;
+	}
 
 	/*
 	 * Need enough time to try and get the port back.
@@ -1457,16 +1630,6 @@ qla2x00_nvram_config(scsi_qla_host_t *ha
 	if (ql2xloginretrycount)
 		ha->login_retry_count = ql2xloginretrycount;
 
-	ha->binding_type = Bind;
-	if (ha->binding_type != BIND_BY_PORT_NAME &&
-	    ha->binding_type != BIND_BY_PORT_ID) {
-		qla_printk(KERN_WARNING, ha,
-		    "Invalid binding type specified (%d), "
-		    "defaulting to BIND_BY_PORT_NAME!!!\n", ha->binding_type);
-
-		ha->binding_type = BIND_BY_PORT_NAME;
-	}
-
 	icb->lun_enables = __constant_cpu_to_le16(0);
 	icb->command_resource_count = 0;
 	icb->immediate_notify_resource_count = 0;
@@ -1551,7 +1714,7 @@ qla2x00_alloc_fcport(scsi_qla_host_t *ha
  *      2 = database was full and device was not configured.
  */
 static int
-qla2x00_configure_loop(scsi_qla_host_t *ha) 
+qla2x00_configure_loop(scsi_qla_host_t *ha)
 {
 	int  rval;
 	unsigned long flags, save_flags;
@@ -1578,7 +1741,6 @@ qla2x00_configure_loop(scsi_qla_host_t *
 	 */
 	clear_bit(LOCAL_LOOP_UPDATE, &ha->dpc_flags);
 	clear_bit(RSCN_UPDATE, &ha->dpc_flags);
-	ha->mem_err = 0 ;
 
 	/* Determine what we need to do */
 	if (ha->current_topology == ISP_CFG_FL &&
@@ -1660,7 +1822,7 @@ qla2x00_configure_loop(scsi_qla_host_t *
  *	0 = success.
  */
 static int
-qla2x00_configure_local_loop(scsi_qla_host_t *ha) 
+qla2x00_configure_local_loop(scsi_qla_host_t *ha)
 {
 	int		rval, rval2;
 	int		found_devs;
@@ -1723,15 +1885,13 @@ qla2x00_configure_local_loop(scsi_qla_ho
 		domain = ((struct gid_list_info *)id_iter)->domain;
 		area = ((struct gid_list_info *)id_iter)->area;
 		al_pa = ((struct gid_list_info *)id_iter)->al_pa;
-		if (IS_QLA2100(ha) || IS_QLA2200(ha)) {
+		if (IS_QLA2100(ha) || IS_QLA2200(ha))
 			loop_id = (uint16_t)
 			    ((struct gid_list_info *)id_iter)->loop_id_2100;
-			id_iter += 4;
-		} else {
+		else
 			loop_id = le16_to_cpu(
 			    ((struct gid_list_info *)id_iter)->loop_id);
-			id_iter += 6;
-		}
+		id_iter += ha->gid_list_info_size;
 
 		/* Bypass reserved domain fields. */
 		if ((domain & 0xf0) == 0xf0)
@@ -1817,16 +1977,16 @@ cleanup_allocation:
 }
 
 static void
-qla2x00_probe_for_all_luns(scsi_qla_host_t *ha) 
+qla2x00_probe_for_all_luns(scsi_qla_host_t *ha)
 {
 	fc_port_t	*fcport;
 
-	qla2x00_mark_all_devices_lost(ha); 
+	qla2x00_mark_all_devices_lost(ha);
  	list_for_each_entry(fcport, &ha->fcports, list) {
 		if (fcport->port_type != FCT_TARGET)
 			continue;
 
-		qla2x00_update_fcport(ha, fcport); 
+		qla2x00_update_fcport(ha, fcport);
 	}
 }
 
@@ -1908,20 +2068,24 @@ qla2x00_reg_remote_port(scsi_qla_host_t 
 	rport_ids.port_id = fcport->d_id.b.domain << 16 |
 	    fcport->d_id.b.area << 8 | fcport->d_id.b.al_pa;
 	rport_ids.roles = FC_RPORT_ROLE_UNKNOWN;
+	fcport->rport = rport = fc_remote_port_add(ha->host, 0, &rport_ids);
+	if (!rport) {
+		qla_printk(KERN_WARNING, ha,
+		    "Unable to allocate fc remote port!\n");
+		return;
+	}
+	rport->dd_data = fcport;
+
+	rport_ids.roles = FC_RPORT_ROLE_UNKNOWN;
 	if (fcport->port_type == FCT_INITIATOR)
 		rport_ids.roles |= FC_RPORT_ROLE_FCP_INITIATOR;
 	if (fcport->port_type == FCT_TARGET)
 		rport_ids.roles |= FC_RPORT_ROLE_FCP_TARGET;
+	fc_remote_port_rolechg(rport, rport_ids.roles);
 
-	fcport->rport = rport = fc_remote_port_add(ha->host, 0, &rport_ids);
-	if (!rport)
-		qla_printk(KERN_WARNING, ha,
-		    "Unable to allocate fc remote port!\n");
-
-	if (rport->scsi_target_id != -1 && rport->scsi_target_id < MAX_TARGETS)
+	if (rport->scsi_target_id != -1 &&
+	    rport->scsi_target_id < ha->host->max_id)
 		fcport->os_target_id = rport->scsi_target_id;
-
-	rport->dd_data = fcport;
 }
 
 /*
@@ -1942,10 +2106,15 @@ qla2x00_configure_fabric(scsi_qla_host_t
 	fc_port_t	*fcport, *fcptemp;
 	uint16_t	next_loopid;
 	uint16_t	mb[MAILBOX_REGISTER_COUNT];
+	uint16_t	loop_id;
 	LIST_HEAD(new_fcports);
 
 	/* If FL port exists, then SNS is present */
-	rval = qla2x00_get_port_name(ha, SNS_FL_PORT, NULL, 0);
+	if (IS_QLA24XX(ha) || IS_QLA25XX(ha))
+		loop_id = NPH_F_PORT;
+	else
+		loop_id = SNS_FL_PORT;
+	rval = qla2x00_get_port_name(ha, loop_id, NULL, 0);
 	if (rval != QLA_SUCCESS) {
 		DEBUG2(printk("scsi(%ld): MBC_GET_PORT_NAME Failed, No FL "
 		    "Port\n", ha->host_no));
@@ -1962,12 +2131,16 @@ qla2x00_configure_fabric(scsi_qla_host_t
 	}
 	do {
 		/* Ensure we are logged into the SNS. */
-		qla2x00_login_fabric(ha, SIMPLE_NAME_SERVER, 0xff, 0xff, 0xfc,
-		    mb, BIT_1 | BIT_0);
+		if (IS_QLA24XX(ha) || IS_QLA25XX(ha))
+			loop_id = NPH_SNS;
+		else
+			loop_id = SIMPLE_NAME_SERVER;
+		ha->isp_ops.fabric_login(ha, loop_id, 0xff, 0xff,
+		    0xfc, mb, BIT_1 | BIT_0);
 		if (mb[0] != MBS_COMMAND_COMPLETE) {
 			DEBUG2(qla_printk(KERN_INFO, ha,
 			    "Failed SNS login: loop_id=%x mb[0]=%x mb[1]=%x "
-			    "mb[2]=%x mb[6]=%x mb[7]=%x\n", SIMPLE_NAME_SERVER,
+			    "mb[2]=%x mb[6]=%x mb[7]=%x\n", loop_id,
 			    mb[0], mb[1], mb[2], mb[6], mb[7]));
 			return (QLA_SUCCESS);
 		}
@@ -2017,8 +2190,11 @@ qla2x00_configure_fabric(scsi_qla_host_t
 				    fcport->port_type != FCT_INITIATOR &&
 				    fcport->port_type != FCT_BROADCAST) {
 
-					qla2x00_fabric_logout(ha,
-					    fcport->loop_id);
+					ha->isp_ops.fabric_logout(ha,
+					    fcport->loop_id,
+					    fcport->d_id.b.domain,
+					    fcport->d_id.b.area,
+					    fcport->d_id.b.al_pa);
 					fcport->loop_id = FC_NO_LOOP_ID;
 				}
 			}
@@ -2048,7 +2224,6 @@ qla2x00_configure_fabric(scsi_qla_host_t
 					break;
 				}
 			}
-
 			/* Login and update database */
 			qla2x00_fabric_dev_login(ha, fcport, &next_loopid);
 		}
@@ -2162,9 +2337,8 @@ qla2x00_find_all_fabric_devs(scsi_qla_ho
 
 	/* Starting free loop ID. */
 	loop_id = ha->min_external_loopid;
-
 	for (; loop_id <= ha->last_loop_id; loop_id++) {
-		if (RESERVED_LOOP_ID(loop_id))
+		if (qla2x00_is_reserved_id(ha, loop_id))
 			continue;
 
 		if (atomic_read(&ha->loop_down_timer) ||
@@ -2263,7 +2437,9 @@ qla2x00_find_all_fabric_devs(scsi_qla_ho
 			    (fcport->flags & FCF_TAPE_PRESENT) == 0 &&
 			    fcport->port_type != FCT_INITIATOR &&
 			    fcport->port_type != FCT_BROADCAST) {
-				qla2x00_fabric_logout(ha, fcport->loop_id);
+				ha->isp_ops.fabric_logout(ha, fcport->loop_id,
+				    fcport->d_id.b.domain, fcport->d_id.b.area,
+				    fcport->d_id.b.al_pa);
 				fcport->loop_id = FC_NO_LOOP_ID;
 			}
 
@@ -2334,7 +2510,7 @@ qla2x00_find_new_loop_id(scsi_qla_host_t
 		}
 
 		/* Skip reserved loop IDs. */
-		while (RESERVED_LOOP_ID(dev->loop_id)) {
+		while (qla2x00_is_reserved_id(ha, dev->loop_id)) {
 			dev->loop_id++;
 		}
 
@@ -2385,7 +2561,7 @@ qla2x00_find_new_loop_id(scsi_qla_host_t
  *	Kernel context.
  */
 static int
-qla2x00_device_resync(scsi_qla_host_t *ha) 
+qla2x00_device_resync(scsi_qla_host_t *ha)
 {
 	int	rval;
 	int	rval2;
@@ -2446,6 +2622,7 @@ qla2x00_device_resync(scsi_qla_host_t *h
 		case 0:
 			if (!IS_QLA2100(ha) && !IS_QLA2200(ha) &&
 			    !IS_QLA6312(ha) && !IS_QLA6322(ha) &&
+			    !IS_QLA24XX(ha) && !IS_QLA25XX(ha) &&
 			    ha->flags.init_done) {
 				/* Handle port RSCN via asyncronous IOCBs */
 				rval2 = qla2x00_handle_port_rscn(ha, rscn_entry,
@@ -2514,15 +2691,24 @@ qla2x00_fabric_dev_login(scsi_qla_host_t
 {
 	int	rval;
 	int	retry;
+	uint8_t opts;
 
 	rval = QLA_SUCCESS;
 	retry = 0;
 
 	rval = qla2x00_fabric_login(ha, fcport, next_loopid);
 	if (rval == QLA_SUCCESS) {
-		rval = qla2x00_get_port_database(ha, fcport, 0);
+		/* Send an ADISC to tape devices.*/
+		opts = 0;
+		if (fcport->flags & FCF_TAPE_PRESENT)
+			opts |= BIT_1;
+		rval = qla2x00_get_port_database(ha, fcport, opts);
 		if (rval != QLA_SUCCESS) {
-			qla2x00_fabric_logout(ha, fcport->loop_id);
+			ha->isp_ops.fabric_logout(ha, fcport->loop_id,
+			    fcport->d_id.b.domain, fcport->d_id.b.area,
+			    fcport->d_id.b.al_pa);
+			qla2x00_mark_device_lost(ha, fcport, 1);
+
 		} else {
 			qla2x00_update_fcport(ha, fcport);
 		}
@@ -2564,16 +2750,16 @@ qla2x00_fabric_login(scsi_qla_host_t *ha
 		    fcport->d_id.b.area, fcport->d_id.b.al_pa));
 
 		/* Login fcport on switch. */
-		qla2x00_login_fabric(ha, fcport->loop_id,
+		ha->isp_ops.fabric_login(ha, fcport->loop_id,
 		    fcport->d_id.b.domain, fcport->d_id.b.area,
 		    fcport->d_id.b.al_pa, mb, BIT_0);
 		if (mb[0] == MBS_PORT_ID_USED) {
 			/*
 			 * Device has another loop ID.  The firmware team
-			 * recommends us to perform an implicit login with the
-			 * specified ID again. The ID we just used is save here
-			 * so we return with an ID that can be tried by the
-			 * next login.
+			 * recommends the driver perform an implicit login with
+			 * the specified ID again. The ID we just used is save
+			 * here so we return with an ID that can be tried by
+			 * the next login.
 			 */
 			retry++;
 			tmp_loopid = fcport->loop_id;
@@ -2627,7 +2813,9 @@ qla2x00_fabric_login(scsi_qla_host_t *ha
 			 * dead.
 			 */
 			*next_loopid = fcport->loop_id;
-			qla2x00_fabric_logout(ha, fcport->loop_id);
+			ha->isp_ops.fabric_logout(ha, fcport->loop_id,
+			    fcport->d_id.b.domain, fcport->d_id.b.area,
+			    fcport->d_id.b.al_pa);
 			qla2x00_mark_device_lost(ha, fcport, 1);
 
 			rval = 1;
@@ -2637,13 +2825,15 @@ qla2x00_fabric_login(scsi_qla_host_t *ha
 			 * unrecoverable / not handled error
 			 */
 			DEBUG2(printk("%s(%ld): failed=%x port_id=%02x%02x%02x "
- 			    "loop_id=%x jiffies=%lx.\n", 
- 			    __func__, ha->host_no, mb[0], 
+ 			    "loop_id=%x jiffies=%lx.\n",
+ 			    __func__, ha->host_no, mb[0],
 			    fcport->d_id.b.domain, fcport->d_id.b.area,
 			    fcport->d_id.b.al_pa, fcport->loop_id, jiffies));
 
 			*next_loopid = fcport->loop_id;
-			qla2x00_fabric_logout(ha, fcport->loop_id);
+			ha->isp_ops.fabric_logout(ha, fcport->loop_id,
+			    fcport->d_id.b.domain, fcport->d_id.b.area,
+			    fcport->d_id.b.al_pa);
 			fcport->loop_id = FC_NO_LOOP_ID;
 			atomic_set(&fcport->state, FCS_DEVICE_DEAD);
 
@@ -2699,7 +2889,7 @@ qla2x00_local_device_login(scsi_qla_host
  *      0 = success
  */
 int
-qla2x00_loop_resync(scsi_qla_host_t *ha) 
+qla2x00_loop_resync(scsi_qla_host_t *ha)
 {
 	int   rval;
 	uint32_t wait_time;
@@ -2707,21 +2897,17 @@ qla2x00_loop_resync(scsi_qla_host_t *ha)
 	rval = QLA_SUCCESS;
 
 	atomic_set(&ha->loop_state, LOOP_UPDATE);
-	qla2x00_stats.loop_resync++;
 	clear_bit(ISP_ABORT_RETRY, &ha->dpc_flags);
 	if (ha->flags.online) {
 		if (!(rval = qla2x00_fw_ready(ha))) {
 			/* Wait at most MAX_TARGET RSCNs for a stable link. */
 			wait_time = 256;
 			do {
-				/* v2.19.05b6 */
 				atomic_set(&ha->loop_state, LOOP_UPDATE);
 
-				/*
-				 * Issue marker command only when we are going
-				 * to start the I/O .
-				 */
-				ha->marker_needed = 1;
+				/* Issue a marker after FW becomes ready. */
+				qla2x00_marker(ha, 0, 0, MK_SYNC_ALL);
+				ha->marker_needed = 0;
 
 				/* Remap devices on Loop. */
 				clear_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags);
@@ -2762,7 +2948,7 @@ qla2x00_rescan_fcports(scsi_qla_host_t *
 
 		rescan_done = 1;
 	}
-	qla2x00_probe_for_all_luns(ha); 
+	qla2x00_probe_for_all_luns(ha);
 }
 
 /*
@@ -2786,13 +2972,10 @@ qla2x00_abort_isp(scsi_qla_host_t *ha)
 	if (ha->flags.online) {
 		ha->flags.online = 0;
 		clear_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
-		qla2x00_stats.ispAbort++;
-		ha->total_isp_aborts++;  /* used by ioctl */
-		ha->sns_retry_cnt = 0;
 
 		qla_printk(KERN_INFO, ha,
 		    "Performing ISP error recovery - ha= %p.\n", ha);
-		qla2x00_reset_chip(ha);
+		ha->isp_ops.reset_chip(ha);
 
 		atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME);
 		if (atomic_read(&ha->loop_state) != LOOP_DOWN) {
@@ -2810,8 +2993,6 @@ qla2x00_abort_isp(scsi_qla_host_t *ha)
 			sp = ha->outstanding_cmds[cnt];
 			if (sp) {
 				ha->outstanding_cmds[cnt] = NULL;
-				if (ha->actthreads)
-					ha->actthreads--;
 				sp->flags = 0;
 				sp->cmd->result = DID_RESET << 16;
 				sp->cmd->host_scribble = (unsigned char *)NULL;
@@ -2820,7 +3001,7 @@ qla2x00_abort_isp(scsi_qla_host_t *ha)
 		}
 		spin_unlock_irqrestore(&ha->hardware_lock, flags);
 
-		qla2x00_nvram_config(ha);
+		ha->isp_ops.nvram_config(ha);
 
 		if (!qla2x00_restart_isp(ha)) {
 			clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags);
@@ -2835,10 +3016,9 @@ qla2x00_abort_isp(scsi_qla_host_t *ha)
 
 			ha->flags.online = 1;
 
-			/* Enable ISP interrupts. */
-			qla2x00_enable_intrs(ha);
+			ha->isp_ops.enable_intrs(ha);
 
-			ha->isp_abort_cnt = 0; 
+			ha->isp_abort_cnt = 0;
 			clear_bit(ISP_ABORT_RETRY, &ha->dpc_flags);
 		} else {	/* failed the ISP abort */
 			ha->flags.online = 1;
@@ -2847,11 +3027,11 @@ qla2x00_abort_isp(scsi_qla_host_t *ha)
  					qla_printk(KERN_WARNING, ha,
 					    "ISP error recovery failed - "
 					    "board disabled\n");
-					/* 
+					/*
 					 * The next call disables the board
 					 * completely.
 					 */
-					qla2x00_reset_adapter(ha);
+					ha->isp_ops.reset_adapter(ha);
 					ha->flags.online = 0;
 					clear_bit(ISP_ABORT_RETRY,
 					    &ha->dpc_flags);
@@ -2859,7 +3039,7 @@ qla2x00_abort_isp(scsi_qla_host_t *ha)
 				} else { /* schedule another ISP abort */
 					ha->isp_abort_cnt--;
 					DEBUG(printk("qla%ld: ISP abort - "
-					    "retry remainning %d\n",
+					    "retry remaining %d\n",
 					    ha->host_no, ha->isp_abort_cnt);)
 					status = 1;
 				}
@@ -2872,7 +3052,7 @@ qla2x00_abort_isp(scsi_qla_host_t *ha)
 				status = 1;
 			}
 		}
-		       
+
 	}
 
 	if (status) {
@@ -2901,43 +3081,52 @@ static int
 qla2x00_restart_isp(scsi_qla_host_t *ha)
 {
 	uint8_t		status = 0;
-	device_reg_t __iomem *reg = ha->iobase;
+	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
 	unsigned long	flags = 0;
 	uint32_t wait_time;
 
 	/* If firmware needs to be loaded */
 	if (qla2x00_isp_firmware(ha)) {
 		ha->flags.online = 0;
-		if (!(status = qla2x00_chip_diag(ha))) {
+		if (!(status = ha->isp_ops.chip_diag(ha))) {
 			if (IS_QLA2100(ha) || IS_QLA2200(ha)) {
 				status = qla2x00_setup_chip(ha);
 				goto done;
 			}
 
-			reg = ha->iobase;
-
 			spin_lock_irqsave(&ha->hardware_lock, flags);
 
-			/* Disable SRAM, Instruction RAM and GP RAM parity. */
-			WRT_REG_WORD(&reg->hccr, (HCCR_ENABLE_PARITY + 0x0));
-			RD_REG_WORD(&reg->hccr);	/* PCI Posting. */
+			if (!IS_QLA24XX(ha) && !IS_QLA25XX(ha)) {
+				/*
+				 * Disable SRAM, Instruction RAM and GP RAM
+				 * parity.
+				 */
+				WRT_REG_WORD(&reg->hccr,
+				    (HCCR_ENABLE_PARITY + 0x0));
+				RD_REG_WORD(&reg->hccr);
+			}
 
 			spin_unlock_irqrestore(&ha->hardware_lock, flags);
-	
+
 			status = qla2x00_setup_chip(ha);
 
 			spin_lock_irqsave(&ha->hardware_lock, flags);
- 
- 			/* Enable proper parity */
- 			if (IS_QLA2300(ha))
- 				/* SRAM parity */
- 				WRT_REG_WORD(&reg->hccr,
- 				    (HCCR_ENABLE_PARITY + 0x1));
- 			else
- 				/* SRAM, Instruction RAM and GP RAM parity */
- 				WRT_REG_WORD(&reg->hccr,
- 				    (HCCR_ENABLE_PARITY + 0x7));
-			RD_REG_WORD(&reg->hccr);	/* PCI Posting. */
+
+			if (!IS_QLA24XX(ha) && !IS_QLA25XX(ha)) {
+				/* Enable proper parity */
+				if (IS_QLA2300(ha))
+					/* SRAM parity */
+					WRT_REG_WORD(&reg->hccr,
+					    (HCCR_ENABLE_PARITY + 0x1));
+				else
+					/*
+					 * SRAM, Instruction RAM and GP RAM
+					 * parity.
+					 */
+					WRT_REG_WORD(&reg->hccr,
+					    (HCCR_ENABLE_PARITY + 0x7));
+				RD_REG_WORD(&reg->hccr);
+			}
 
 			spin_unlock_irqrestore(&ha->hardware_lock, flags);
 		}
@@ -2948,9 +3137,11 @@ qla2x00_restart_isp(scsi_qla_host_t *ha)
 		clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags);
 		if (!(status = qla2x00_fw_ready(ha))) {
 			DEBUG(printk("%s(): Start configure loop, "
-					"status = %d\n",
-					__func__,
-					status);)
+			    "status = %d\n", __func__, status);)
+
+			/* Issue a marker after FW becomes ready. */
+			qla2x00_marker(ha, 0, 0, MK_SYNC_ALL);
+
 			ha->flags.online = 1;
 			/* Wait at most MAX_TARGET RSCNs for a stable link. */
 			wait_time = 256;
@@ -2965,7 +3156,7 @@ qla2x00_restart_isp(scsi_qla_host_t *ha)
 		}
 
 		/* if no cable then assume it's good */
-		if ((ha->device_flags & DFLG_NO_CABLE)) 
+		if ((ha->device_flags & DFLG_NO_CABLE))
 			status = 0;
 
 		DEBUG(printk("%s(): Configure loop done, status = 0x%x\n",
@@ -2982,16 +3173,15 @@ qla2x00_restart_isp(scsi_qla_host_t *ha)
 * Input:
 *      ha = adapter block pointer.
 */
-static void
+void
 qla2x00_reset_adapter(scsi_qla_host_t *ha)
 {
 	unsigned long flags = 0;
-	device_reg_t __iomem *reg = ha->iobase;
+	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
 
 	ha->flags.online = 0;
-	qla2x00_disable_intrs(ha);
+	ha->isp_ops.disable_intrs(ha);
 
-	/* Reset RISC processor. */
 	spin_lock_irqsave(&ha->hardware_lock, flags);
 	WRT_REG_WORD(&reg->hccr, HCCR_RESET_RISC);
 	RD_REG_WORD(&reg->hccr);			/* PCI Posting. */
@@ -2999,3 +3189,505 @@ qla2x00_reset_adapter(scsi_qla_host_t *h
 	RD_REG_WORD(&reg->hccr);			/* PCI Posting. */
 	spin_unlock_irqrestore(&ha->hardware_lock, flags);
 }
+
+void
+qla24xx_reset_adapter(scsi_qla_host_t *ha)
+{
+	unsigned long flags = 0;
+	struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
+
+	ha->flags.online = 0;
+	ha->isp_ops.disable_intrs(ha);
+
+	spin_lock_irqsave(&ha->hardware_lock, flags);
+	WRT_REG_DWORD(&reg->hccr, HCCRX_SET_RISC_RESET);
+	RD_REG_DWORD(&reg->hccr);
+	WRT_REG_DWORD(&reg->hccr, HCCRX_REL_RISC_PAUSE);
+	RD_REG_DWORD(&reg->hccr);
+	spin_unlock_irqrestore(&ha->hardware_lock, flags);
+}
+
+int
+qla24xx_nvram_config(scsi_qla_host_t *ha)
+{
+	int   rval;
+	struct init_cb_24xx *icb;
+	struct nvram_24xx *nv;
+	uint32_t *dptr;
+	uint8_t  *dptr1, *dptr2;
+	uint32_t chksum;
+	uint16_t cnt;
+
+	rval = QLA_SUCCESS;
+	icb = (struct init_cb_24xx *)ha->init_cb;
+	nv = (struct nvram_24xx *)ha->request_ring;
+
+	/* Determine NVRAM starting address. */
+	ha->nvram_size = sizeof(struct nvram_24xx);
+	ha->nvram_base = FA_NVRAM_FUNC0_ADDR;
+	if (PCI_FUNC(ha->pdev->devfn))
+		ha->nvram_base = FA_NVRAM_FUNC1_ADDR;
+
+	/* Get NVRAM data and calculate checksum. */
+	dptr = (uint32_t *)nv;
+	ha->isp_ops.read_nvram(ha, (uint8_t *)dptr, ha->nvram_base,
+	    ha->nvram_size);
+	for (cnt = 0, chksum = 0; cnt < ha->nvram_size >> 2; cnt++)
+		chksum += le32_to_cpu(*dptr++);
+
+	DEBUG5(printk("scsi(%ld): Contents of NVRAM\n", ha->host_no));
+	DEBUG5(qla2x00_dump_buffer((uint8_t *)ha->request_ring,
+	    ha->nvram_size));
+
+	/* Bad NVRAM data, set defaults parameters. */
+	if (chksum || nv->id[0] != 'I' || nv->id[1] != 'S' || nv->id[2] != 'P'
+	    || nv->id[3] != ' ' ||
+	    nv->nvram_version < __constant_cpu_to_le16(ICB_VERSION)) {
+		/* Reset NVRAM data. */
+		qla_printk(KERN_WARNING, ha, "Inconsistent NVRAM detected: "
+		    "checksum=0x%x id=%c version=0x%x.\n", chksum, nv->id[0],
+		    le16_to_cpu(nv->nvram_version));
+		qla_printk(KERN_WARNING, ha, "Falling back to functioning (yet "
+		    "invalid -- WWPN) defaults.\n");
+
+		/*
+		 * Set default initialization control block.
+		 */
+		memset(nv, 0, ha->nvram_size);
+		nv->nvram_version = __constant_cpu_to_le16(ICB_VERSION);
+		nv->version = __constant_cpu_to_le16(ICB_VERSION);
+		nv->frame_payload_size = __constant_cpu_to_le16(2048);
+		nv->execution_throttle = __constant_cpu_to_le16(0xFFFF);
+		nv->exchange_count = __constant_cpu_to_le16(0);
+		nv->hard_address = __constant_cpu_to_le16(124);
+		nv->port_name[0] = 0x21;
+		nv->port_name[1] = 0x00 + PCI_FUNC(ha->pdev->devfn);
+		nv->port_name[2] = 0x00;
+		nv->port_name[3] = 0xe0;
+		nv->port_name[4] = 0x8b;
+		nv->port_name[5] = 0x1c;
+		nv->port_name[6] = 0x55;
+		nv->port_name[7] = 0x86;
+		nv->node_name[0] = 0x20;
+		nv->node_name[1] = 0x00;
+		nv->node_name[2] = 0x00;
+		nv->node_name[3] = 0xe0;
+		nv->node_name[4] = 0x8b;
+		nv->node_name[5] = 0x1c;
+		nv->node_name[6] = 0x55;
+		nv->node_name[7] = 0x86;
+		nv->login_retry_count = __constant_cpu_to_le16(8);
+		nv->link_down_timeout = __constant_cpu_to_le16(200);
+		nv->interrupt_delay_timer = __constant_cpu_to_le16(0);
+		nv->login_timeout = __constant_cpu_to_le16(0);
+		nv->firmware_options_1 =
+		    __constant_cpu_to_le32(BIT_14|BIT_13|BIT_2|BIT_1);
+		nv->firmware_options_2 = __constant_cpu_to_le32(2 << 4);
+		nv->firmware_options_2 |= __constant_cpu_to_le32(BIT_12);
+		nv->firmware_options_3 = __constant_cpu_to_le32(2 << 13);
+		nv->host_p = __constant_cpu_to_le32(BIT_11|BIT_10);
+		nv->efi_parameters = __constant_cpu_to_le32(0);
+		nv->reset_delay = 5;
+		nv->max_luns_per_target = __constant_cpu_to_le16(128);
+		nv->port_down_retry_count = __constant_cpu_to_le16(30);
+		nv->link_down_timeout = __constant_cpu_to_le16(30);
+
+		rval = 1;
+	}
+
+	/* Reset Initialization control block */
+	memset(icb, 0, sizeof(struct init_cb_24xx));
+
+	/* Copy 1st segment. */
+	dptr1 = (uint8_t *)icb;
+	dptr2 = (uint8_t *)&nv->version;
+	cnt = (uint8_t *)&icb->response_q_inpointer - (uint8_t *)&icb->version;
+	while (cnt--)
+		*dptr1++ = *dptr2++;
+
+	icb->login_retry_count = nv->login_retry_count;
+	icb->link_down_timeout = nv->link_down_timeout;
+
+	/* Copy 2nd segment. */
+	dptr1 = (uint8_t *)&icb->interrupt_delay_timer;
+	dptr2 = (uint8_t *)&nv->interrupt_delay_timer;
+	cnt = (uint8_t *)&icb->reserved_3 -
+	    (uint8_t *)&icb->interrupt_delay_timer;
+	while (cnt--)
+		*dptr1++ = *dptr2++;
+
+	/*
+	 * Setup driver NVRAM options.
+	 */
+	if (memcmp(nv->model_name, BINZERO, sizeof(nv->model_name)) != 0) {
+		char *st, *en;
+		uint16_t index;
+
+		strncpy(ha->model_number, nv->model_name,
+		    sizeof(nv->model_name));
+		st = en = ha->model_number;
+		en += sizeof(nv->model_name) - 1;
+		while (en > st) {
+			if (*en != 0x20 && *en != 0x00)
+				break;
+			*en-- = '\0';
+		}
+
+		index = (ha->pdev->subsystem_device & 0xff);
+		if (index < QLA_MODEL_NAMES)
+			ha->model_desc = qla2x00_model_desc[index];
+	} else
+		strcpy(ha->model_number, "QLA2462");
+
+	/* Prepare nodename */
+	if ((icb->firmware_options_1 & BIT_14) == 0) {
+		/*
+		 * Firmware will apply the following mask if the nodename was
+		 * not provided.
+		 */
+		memcpy(icb->node_name, icb->port_name, WWN_SIZE);
+		icb->node_name[0] &= 0xF0;
+	}
+
+	/* Set host adapter parameters. */
+	ha->flags.disable_risc_code_load = 0;
+	ha->flags.enable_lip_reset = 1;
+	ha->flags.enable_lip_full_login = 1;
+	ha->flags.enable_target_reset = 1;
+	ha->flags.enable_led_scheme = 0;
+
+	ha->operating_mode =
+	    (icb->firmware_options_2 & (BIT_6 | BIT_5 | BIT_4)) >> 4;
+
+	memcpy(ha->fw_seriallink_options24, nv->seriallink_options,
+	    sizeof(ha->fw_seriallink_options24));
+
+	/* save HBA serial number */
+	ha->serial0 = icb->port_name[5];
+	ha->serial1 = icb->port_name[6];
+	ha->serial2 = icb->port_name[7];
+	ha->node_name = icb->node_name;
+	ha->port_name = icb->port_name;
+
+	ha->retry_count = le16_to_cpu(nv->login_retry_count);
+
+	/* Set minimum login_timeout to 4 seconds. */
+	if (le16_to_cpu(nv->login_timeout) < ql2xlogintimeout)
+		nv->login_timeout = cpu_to_le16(ql2xlogintimeout);
+	if (le16_to_cpu(nv->login_timeout) < 4)
+		nv->login_timeout = __constant_cpu_to_le16(4);
+	ha->login_timeout = le16_to_cpu(nv->login_timeout);
+	icb->login_timeout = cpu_to_le16(nv->login_timeout);
+
+	/* Set minimum RATOV to 200 tenths of a second. */
+	ha->r_a_tov = 200;
+
+	ha->loop_reset_delay = nv->reset_delay;
+
+	/* Link Down Timeout = 0:
+	 *
+	 * 	When Port Down timer expires we will start returning
+	 *	I/O's to OS with "DID_NO_CONNECT".
+	 *
+	 * Link Down Timeout != 0:
+	 *
+	 *	 The driver waits for the link to come up after link down
+	 *	 before returning I/Os to OS with "DID_NO_CONNECT".
+	 */
+	if (le16_to_cpu(nv->link_down_timeout) == 0) {
+		ha->loop_down_abort_time =
+		    (LOOP_DOWN_TIME - LOOP_DOWN_TIMEOUT);
+	} else {
+		ha->link_down_timeout =	le16_to_cpu(nv->link_down_timeout);
+		ha->loop_down_abort_time =
+		    (LOOP_DOWN_TIME - ha->link_down_timeout);
+	}
+
+	/* Need enough time to try and get the port back. */
+	ha->port_down_retry_count = le16_to_cpu(nv->port_down_retry_count);
+	if (qlport_down_retry)
+		ha->port_down_retry_count = qlport_down_retry;
+
+	/* Set login_retry_count */
+	ha->login_retry_count  = le16_to_cpu(nv->login_retry_count);
+	if (ha->port_down_retry_count ==
+	    le16_to_cpu(nv->port_down_retry_count) &&
+	    ha->port_down_retry_count > 3)
+		ha->login_retry_count = ha->port_down_retry_count;
+	else if (ha->port_down_retry_count > (int)ha->login_retry_count)
+		ha->login_retry_count = ha->port_down_retry_count;
+	if (ql2xloginretrycount)
+		ha->login_retry_count = ql2xloginretrycount;
+
+	if (rval) {
+		DEBUG2_3(printk(KERN_WARNING
+		    "scsi(%ld): NVRAM configuration failed!\n", ha->host_no));
+	}
+	return (rval);
+}
+
+int
+qla2x00_load_risc(scsi_qla_host_t *ha, uint32_t *srisc_addr)
+{
+	int		rval;
+	uint16_t	cnt;
+	uint16_t	*risc_code;
+	unsigned long	risc_address;
+	unsigned long	risc_code_size;
+	int		num;
+	int		i;
+	uint16_t	*req_ring;
+	struct qla_fw_info *fw_iter;
+
+	rval = QLA_SUCCESS;
+
+	/* Load firmware sequences */
+	fw_iter = ha->brd_info->fw_info;
+	*srisc_addr = *ha->brd_info->fw_info->fwstart;
+	while (fw_iter->addressing != FW_INFO_ADDR_NOMORE) {
+		risc_code = fw_iter->fwcode;
+		risc_code_size = *fw_iter->fwlen;
+
+		if (fw_iter->addressing == FW_INFO_ADDR_NORMAL) {
+			risc_address = *fw_iter->fwstart;
+		} else {
+			/* Extended address */
+			risc_address = *fw_iter->lfwstart;
+		}
+
+		num = 0;
+		rval = 0;
+		while (risc_code_size > 0 && !rval) {
+			cnt = (uint16_t)(ha->fw_transfer_size >> 1);
+			if (cnt > risc_code_size)
+				cnt = risc_code_size;
+
+			DEBUG7(printk("scsi(%ld): Loading risc segment@ "
+			    "addr %p, number of bytes 0x%x, offset 0x%lx.\n",
+			    ha->host_no, risc_code, cnt, risc_address));
+
+			req_ring = (uint16_t *)ha->request_ring;
+			for (i = 0; i < cnt; i++)
+				req_ring[i] = cpu_to_le16(risc_code[i]);
+
+			if (fw_iter->addressing == FW_INFO_ADDR_NORMAL) {
+				rval = qla2x00_load_ram(ha, ha->request_dma,
+				    risc_address, cnt);
+			} else {
+				rval = qla2x00_load_ram_ext(ha,
+				    ha->request_dma, risc_address, cnt);
+			}
+			if (rval) {
+				DEBUG(printk("scsi(%ld): [ERROR] Failed to "
+				    "load segment %d of firmware\n",
+				    ha->host_no, num));
+				qla_printk(KERN_WARNING, ha,
+				    "[ERROR] Failed to load segment %d of "
+				    "firmware\n", num);
+
+				qla2x00_dump_regs(ha);
+				break;
+			}
+
+			risc_code += cnt;
+			risc_address += cnt;
+			risc_code_size -= cnt;
+			num++;
+		}
+
+		/* Next firmware sequence */
+		fw_iter++;
+	}
+
+	return (rval);
+}
+
+int
+qla24xx_load_risc_flash(scsi_qla_host_t *ha, uint32_t *srisc_addr)
+{
+	int	rval;
+	int	segments, fragment;
+	uint32_t faddr;
+	uint32_t *dcode, dlen;
+	uint32_t risc_addr;
+	uint32_t risc_size;
+	uint32_t i;
+
+	rval = QLA_SUCCESS;
+
+	segments = FA_RISC_CODE_SEGMENTS;
+	faddr = FA_RISC_CODE_ADDR;
+	dcode = (uint32_t *)ha->request_ring;
+	*srisc_addr = 0;
+
+	/* Validate firmware image by checking version. */
+	qla24xx_read_flash_data(ha, dcode, faddr + 4, 4);
+	for (i = 0; i < 4; i++)
+		dcode[i] = be32_to_cpu(dcode[i]);
+	if ((dcode[0] == 0xffffffff && dcode[1] == 0xffffffff &&
+	    dcode[2] == 0xffffffff && dcode[3] == 0xffffffff) ||
+	    (dcode[0] == 0 && dcode[1] == 0 && dcode[2] == 0 &&
+		dcode[3] == 0)) {
+		qla_printk(KERN_WARNING, ha,
+		    "Unable to verify integrity of flash firmware image!\n");
+		qla_printk(KERN_WARNING, ha,
+		    "Firmware data: %08x %08x %08x %08x!\n", dcode[0],
+		    dcode[1], dcode[2], dcode[3]);
+
+		return QLA_FUNCTION_FAILED;
+	}
+
+	while (segments && rval == QLA_SUCCESS) {
+		/* Read segment's load information. */
+		qla24xx_read_flash_data(ha, dcode, faddr, 4);
+
+		risc_addr = be32_to_cpu(dcode[2]);
+		*srisc_addr = *srisc_addr == 0 ? risc_addr : *srisc_addr;
+		risc_size = be32_to_cpu(dcode[3]);
+
+		fragment = 0;
+		while (risc_size > 0 && rval == QLA_SUCCESS) {
+			dlen = (uint32_t)(ha->fw_transfer_size >> 2);
+			if (dlen > risc_size)
+				dlen = risc_size;
+
+			DEBUG7(printk("scsi(%ld): Loading risc segment@ risc "
+			    "addr %x, number of dwords 0x%x, offset 0x%x.\n",
+			    ha->host_no, risc_addr, dlen, faddr));
+
+			qla24xx_read_flash_data(ha, dcode, faddr, dlen);
+			for (i = 0; i < dlen; i++)
+				dcode[i] = swab32(dcode[i]);
+
+			rval = qla2x00_load_ram_ext(ha, ha->request_dma,
+			    risc_addr, dlen);
+			if (rval) {
+				DEBUG(printk("scsi(%ld):[ERROR] Failed to load "
+				    "segment %d of firmware\n", ha->host_no,
+				    fragment));
+				qla_printk(KERN_WARNING, ha,
+				    "[ERROR] Failed to load segment %d of "
+				    "firmware\n", fragment);
+				break;
+			}
+
+			faddr += dlen;
+			risc_addr += dlen;
+			risc_size -= dlen;
+			fragment++;
+		}
+
+		/* Next segment. */
+		segments--;
+	}
+
+	return rval;
+}
+
+int
+qla24xx_load_risc_hotplug(scsi_qla_host_t *ha, uint32_t *srisc_addr)
+{
+	int	rval;
+	int	segments, fragment;
+	uint32_t *dcode, dlen;
+	uint32_t risc_addr;
+	uint32_t risc_size;
+	uint32_t i;
+	const struct firmware *fw_entry;
+	uint32_t *fwcode, fwclen;
+
+	if (request_firmware(&fw_entry, ha->brd_info->fw_fname,
+	    &ha->pdev->dev)) {
+		qla_printk(KERN_ERR, ha,
+		    "Firmware image file not available: '%s'\n",
+		    ha->brd_info->fw_fname);
+		return QLA_FUNCTION_FAILED;
+	}
+
+	rval = QLA_SUCCESS;
+
+	segments = FA_RISC_CODE_SEGMENTS;
+	dcode = (uint32_t *)ha->request_ring;
+	*srisc_addr = 0;
+	fwcode = (uint32_t *)fw_entry->data;
+	fwclen = 0;
+
+	/* Validate firmware image by checking version. */
+	if (fw_entry->size < 8 * sizeof(uint32_t)) {
+		qla_printk(KERN_WARNING, ha,
+		    "Unable to verify integrity of flash firmware image "
+		    "(%Zd)!\n", fw_entry->size);
+		goto fail_fw_integrity;
+	}
+	for (i = 0; i < 4; i++)
+		dcode[i] = be32_to_cpu(fwcode[i + 4]);
+	if ((dcode[0] == 0xffffffff && dcode[1] == 0xffffffff &&
+	    dcode[2] == 0xffffffff && dcode[3] == 0xffffffff) ||
+	    (dcode[0] == 0 && dcode[1] == 0 && dcode[2] == 0 &&
+		dcode[3] == 0)) {
+		qla_printk(KERN_WARNING, ha,
+		    "Unable to verify integrity of flash firmware image!\n");
+		qla_printk(KERN_WARNING, ha,
+		    "Firmware data: %08x %08x %08x %08x!\n", dcode[0],
+		    dcode[1], dcode[2], dcode[3]);
+		goto fail_fw_integrity;
+	}
+
+	while (segments && rval == QLA_SUCCESS) {
+		risc_addr = be32_to_cpu(fwcode[2]);
+		*srisc_addr = *srisc_addr == 0 ? risc_addr : *srisc_addr;
+		risc_size = be32_to_cpu(fwcode[3]);
+
+		/* Validate firmware image size. */
+		fwclen += risc_size * sizeof(uint32_t);
+		if (fw_entry->size < fwclen) {
+			qla_printk(KERN_WARNING, ha,
+			    "Unable to verify integrity of flash firmware "
+			    "image (%Zd)!\n", fw_entry->size);
+			goto fail_fw_integrity;
+		}
+
+		fragment = 0;
+		while (risc_size > 0 && rval == QLA_SUCCESS) {
+			dlen = (uint32_t)(ha->fw_transfer_size >> 2);
+			if (dlen > risc_size)
+				dlen = risc_size;
+
+			DEBUG7(printk("scsi(%ld): Loading risc segment@ risc "
+			    "addr %x, number of dwords 0x%x.\n", ha->host_no,
+			    risc_addr, dlen));
+
+			for (i = 0; i < dlen; i++)
+				dcode[i] = swab32(fwcode[i]);
+
+			rval = qla2x00_load_ram_ext(ha, ha->request_dma,
+			    risc_addr, dlen);
+			if (rval) {
+				DEBUG(printk("scsi(%ld):[ERROR] Failed to load "
+				    "segment %d of firmware\n", ha->host_no,
+				    fragment));
+				qla_printk(KERN_WARNING, ha,
+				    "[ERROR] Failed to load segment %d of "
+				    "firmware\n", fragment);
+				break;
+			}
+
+			fwcode += dlen;
+			risc_addr += dlen;
+			risc_size -= dlen;
+			fragment++;
+		}
+
+		/* Next segment. */
+		segments--;
+	}
+
+	release_firmware(fw_entry);
+	return rval;
+
+fail_fw_integrity:
+
+	release_firmware(fw_entry);
+	return QLA_FUNCTION_FAILED;
+
+}
diff --git a/drivers/scsi/qla2xxx/qla_inline.h b/drivers/scsi/qla2xxx/qla_inline.h
--- a/drivers/scsi/qla2xxx/qla_inline.h
+++ b/drivers/scsi/qla2xxx/qla_inline.h
@@ -2,7 +2,7 @@
  *                  QLOGIC LINUX SOFTWARE
  *
  * QLogic ISP2x00 device driver for Linux 2.6.x
- * Copyright (C) 2003-2004 QLogic Corporation
+ * Copyright (C) 2003-2005 QLogic Corporation
  * (www.qlogic.com)
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -30,7 +30,7 @@ static __inline__ uint16_t qla2x00_debou
  *      register value.
  */
 static __inline__ uint16_t
-qla2x00_debounce_register(volatile uint16_t __iomem *addr) 
+qla2x00_debounce_register(volatile uint16_t __iomem *addr)
 {
 	volatile uint16_t first;
 	volatile uint16_t second;
@@ -78,7 +78,7 @@ static __inline__ int qla2x00_normalize_
  *	ffffabc1ffffeeee	(0x100000000 + e_addr)
  *	ffffabc100000000	(0x100000000 + e_addr) & ~(0xffffffff)
  *	ffffabc100000000	(ne_addr)
- *	
+ *
  * Compute length of second DMA segment:
  *
  *	00000000ffffeeee	(e_addr & 0xffffffff)
@@ -114,77 +114,10 @@ qla2x00_normalize_dma_addr(
 }
 
 static __inline__ void qla2x00_poll(scsi_qla_host_t *);
-static inline void 
+static inline void
 qla2x00_poll(scsi_qla_host_t *ha)
 {
-	if (IS_QLA2100(ha) || IS_QLA2200(ha))
-		qla2100_intr_handler(0, ha, NULL);
-	else
-		qla2300_intr_handler(0, ha, NULL);
-}
-
-
-static __inline__ void qla2x00_enable_intrs(scsi_qla_host_t *);
-static __inline__ void qla2x00_disable_intrs(scsi_qla_host_t *);
-
-static inline void 
-qla2x00_enable_intrs(scsi_qla_host_t *ha)
-{
-	unsigned long flags = 0;
-	device_reg_t __iomem *reg = ha->iobase;
-
-	spin_lock_irqsave(&ha->hardware_lock, flags);
-	ha->interrupts_on = 1;
-	/* enable risc and host interrupts */
-	WRT_REG_WORD(&reg->ictrl, ICR_EN_INT | ICR_EN_RISC);
-	RD_REG_WORD(&reg->ictrl);
-	spin_unlock_irqrestore(&ha->hardware_lock, flags);
-
-}
-
-static inline void 
-qla2x00_disable_intrs(scsi_qla_host_t *ha)
-{
-	unsigned long flags = 0;
-	device_reg_t __iomem *reg = ha->iobase;
-
-	spin_lock_irqsave(&ha->hardware_lock, flags);
-	ha->interrupts_on = 0;
-	/* disable risc and host interrupts */
-	WRT_REG_WORD(&reg->ictrl, 0);
-	RD_REG_WORD(&reg->ictrl);
-	spin_unlock_irqrestore(&ha->hardware_lock, flags);
-}
-
-
-static __inline__ int qla2x00_is_wwn_zero(uint8_t *);
-
-/*
- * qla2x00_is_wwn_zero - Check for zero node name
- *
- * Input:
- *      wwn = Pointer to WW name to check
- *
- * Returns:
- *      1 if name is 0x00 else 0
- *
- * Context:
- *      Kernel context.
- */
-static __inline__ int
-qla2x00_is_wwn_zero(uint8_t *wwn)
-{
-	int cnt;
-
-	for (cnt = 0; cnt < WWN_SIZE ; cnt++, wwn++) {
-		if (*wwn != 0)
-			break;
-	}
-	/* if zero return 1 */
-	if (cnt == WWN_SIZE)
-		return (1);
-	else
-		return (0);
+	ha->isp_ops.intr_handler(0, ha, NULL);
 }
 
 static __inline__ void qla2x00_check_fabric_devices(scsi_qla_host_t *);
@@ -192,7 +125,7 @@ static __inline__ void qla2x00_check_fab
  * This routine will wait for fabric devices for
  * the reset delay.
  */
-static __inline__ void qla2x00_check_fabric_devices(scsi_qla_host_t *ha) 
+static __inline__ void qla2x00_check_fabric_devices(scsi_qla_host_t *ha)
 {
 	uint16_t	fw_state;
 
@@ -225,51 +158,27 @@ qla2x00_issue_marker(scsi_qla_host_t *ha
 	return (QLA_SUCCESS);
 }
 
-static __inline__ void qla2x00_add_timer_to_cmd(srb_t *, int);
-static __inline__ void qla2x00_delete_timer_from_cmd(srb_t *);
-
-/**************************************************************************
-*   qla2x00_add_timer_to_cmd
-*
-* Description:
-*       Creates a timer for the specified command. The timeout is usually
-*       the command time from kernel minus 2 secs.
-*
-* Input:
-*     sp - pointer to validate
-*
-* Returns:
-*     None.
-**************************************************************************/
-static inline void
-qla2x00_add_timer_to_cmd(srb_t *sp, int timeout)
+static inline uint8_t *host_to_fcp_swap(uint8_t *, uint32_t);
+static inline uint8_t *
+host_to_fcp_swap(uint8_t *fcp, uint32_t bsize)
 {
-	init_timer(&sp->timer);
-	sp->timer.expires = jiffies + timeout * HZ;
-	sp->timer.data = (unsigned long) sp;
-	sp->timer.function = (void (*) (unsigned long))qla2x00_cmd_timeout;
-	add_timer(&sp->timer);
+       uint32_t *ifcp = (uint32_t *) fcp;
+       uint32_t *ofcp = (uint32_t *) fcp;
+       uint32_t iter = bsize >> 2;
+
+       for (; iter ; iter--)
+               *ofcp++ = swab32(*ifcp++);
+
+       return fcp;
 }
 
-/**************************************************************************
-*   qla2x00_delete_timer_from_cmd
-*
-* Description:
-*       Delete the timer for the specified command.
-*
-* Input:
-*     sp - pointer to validate
-*
-* Returns:
-*     None.
-**************************************************************************/
-static inline void 
-qla2x00_delete_timer_from_cmd(srb_t *sp)
+static inline int qla2x00_is_reserved_id(scsi_qla_host_t *, uint16_t);
+static inline int
+qla2x00_is_reserved_id(scsi_qla_host_t *ha, uint16_t loop_id)
 {
-	if (sp->timer.function != NULL) {
-		del_timer(&sp->timer);
-		sp->timer.function =  NULL;
-		sp->timer.data = (unsigned long) NULL;
-	}
-}
+	if (IS_QLA24XX(ha) || IS_QLA25XX(ha))
+		return (loop_id > NPH_LAST_HANDLE);
 
+	return ((loop_id > ha->last_loop_id && loop_id < SNS_FIRST_LOOP_ID) ||
+	    loop_id == MANAGEMENT_SERVER || loop_id == BROADCAST);
+};
diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c
--- a/drivers/scsi/qla2xxx/qla_iocb.c
+++ b/drivers/scsi/qla2xxx/qla_iocb.c
@@ -2,7 +2,7 @@
  *                  QLOGIC LINUX SOFTWARE
  *
  * QLogic ISP2x00 device driver for Linux 2.6.x
- * Copyright (C) 2003-2004 QLogic Corporation
+ * Copyright (C) 2003-2005 QLogic Corporation
  * (www.qlogic.com)
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -315,13 +315,13 @@ qla2x00_start_scsi(srb_t *sp)
 	uint16_t	cnt;
 	uint16_t	req_cnt;
 	uint16_t	tot_dsds;
-	device_reg_t __iomem *reg;
+	struct device_reg_2xxx __iomem *reg;
 	char		tag[2];
 
 	/* Setup device pointers. */
 	ret = 0;
 	ha = sp->ha;
-	reg = ha->iobase;
+	reg = &ha->iobase->isp;
 	cmd = sp->cmd;
 	/* So we know we haven't pci_map'ed anything yet */
 	tot_dsds = 0;
@@ -369,7 +369,7 @@ qla2x00_start_scsi(srb_t *sp)
 	}
 
 	/* Calculate the number of request entries needed. */
-	req_cnt = (ha->calc_request_entries)(tot_dsds);
+	req_cnt = ha->isp_ops.calc_req_entries(tot_dsds);
 	if (ha->req_q_cnt < (req_cnt + 2)) {
 		cnt = RD_REG_WORD_RELAXED(ISP_REQ_Q_OUT(ha, reg));
 		if (ha->req_ring_index < cnt)
@@ -419,7 +419,7 @@ qla2x00_start_scsi(srb_t *sp)
 	cmd_pkt->byte_count = cpu_to_le32((uint32_t)cmd->request_bufflen);
 
 	/* Build IOCB segments */
-	(ha->build_scsi_iocbs)(sp, cmd_pkt, tot_dsds);
+	ha->isp_ops.build_iocbs(sp, cmd_pkt, tot_dsds);
 
 	/* Set total data segment count. */
 	cmd_pkt->entry_count = (uint8_t)req_cnt;
@@ -433,11 +433,8 @@ qla2x00_start_scsi(srb_t *sp)
 	} else
 		ha->request_ring_ptr++;
 
-	ha->actthreads++;
-	ha->total_ios++;
 	sp->flags |= SRB_DMA_VALID;
 	sp->state = SRB_ACTIVE_STATE;
-	sp->u_start = jiffies;
 
 	/* Set chip new ring index. */
 	WRT_REG_WORD(ISP_REQ_Q_IN(ha, reg), ha->req_ring_index);
@@ -475,31 +472,39 @@ int
 __qla2x00_marker(scsi_qla_host_t *ha, uint16_t loop_id, uint16_t lun,
     uint8_t type)
 {
-	mrk_entry_t	*pkt;
+	mrk_entry_t *mrk;
+	struct mrk_entry_24xx *mrk24;
 
-	pkt = (mrk_entry_t *)qla2x00_req_pkt(ha);
-	if (pkt == NULL) {
-		DEBUG2_3(printk("%s(): **** FAILED ****\n", __func__));
+	mrk24 = NULL;
+	mrk = (mrk_entry_t *)qla2x00_req_pkt(ha);
+	if (mrk == NULL) {
+		DEBUG2_3(printk("%s(%ld): failed to allocate Marker IOCB.\n",
+		    __func__, ha->host_no));
 
 		return (QLA_FUNCTION_FAILED);
 	}
 
-	pkt->entry_type = MARKER_TYPE;
-	pkt->modifier = type;
-
+	mrk->entry_type = MARKER_TYPE;
+	mrk->modifier = type;
 	if (type != MK_SYNC_ALL) {
-		pkt->lun = cpu_to_le16(lun);
-		SET_TARGET_ID(ha, pkt->target, loop_id);
+		if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) {
+			mrk24 = (struct mrk_entry_24xx *) mrk;
+			mrk24->nport_handle = cpu_to_le16(loop_id);
+			mrk24->lun[1] = LSB(lun);
+			mrk24->lun[2] = MSB(lun);
+		} else {
+			SET_TARGET_ID(ha, mrk->target, loop_id);
+			mrk->lun = cpu_to_le16(lun);
+		}
 	}
 	wmb();
 
-	/* Issue command to ISP */
 	qla2x00_isp_cmd(ha);
 
 	return (QLA_SUCCESS);
 }
 
-int 
+int
 qla2x00_marker(scsi_qla_host_t *ha, uint16_t loop_id, uint16_t lun,
     uint8_t type)
 {
@@ -535,7 +540,12 @@ qla2x00_req_pkt(scsi_qla_host_t *ha)
 	for (timer = HZ; timer; timer--) {
 		if ((req_cnt + 2) >= ha->req_q_cnt) {
 			/* Calculate number of free request entries. */
-			cnt = qla2x00_debounce_register(ISP_REQ_Q_OUT(ha, reg));
+			if (IS_QLA24XX(ha) || IS_QLA25XX(ha))
+				cnt = (uint16_t)RD_REG_DWORD(
+				    &reg->isp24.req_q_out);
+			else
+				cnt = qla2x00_debounce_register(
+				    ISP_REQ_Q_OUT(ha, &reg->isp));
 			if  (ha->req_ring_index < cnt)
 				ha->req_q_cnt = cnt - ha->req_ring_index;
 			else
@@ -604,6 +614,286 @@ qla2x00_isp_cmd(scsi_qla_host_t *ha)
 		ha->request_ring_ptr++;
 
 	/* Set chip new ring index. */
-	WRT_REG_WORD(ISP_REQ_Q_IN(ha, reg), ha->req_ring_index);
-	RD_REG_WORD_RELAXED(ISP_REQ_Q_IN(ha, reg));	/* PCI Posting. */
+	if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) {
+		WRT_REG_DWORD(&reg->isp24.req_q_in, ha->req_ring_index);
+		RD_REG_DWORD_RELAXED(&reg->isp24.req_q_in);
+	} else {
+		WRT_REG_WORD(ISP_REQ_Q_IN(ha, &reg->isp), ha->req_ring_index);
+		RD_REG_WORD_RELAXED(ISP_REQ_Q_IN(ha, &reg->isp));
+	}
+
+}
+
+/**
+ * qla24xx_calc_iocbs() - Determine number of Command Type 3 and
+ * Continuation Type 1 IOCBs to allocate.
+ *
+ * @dsds: number of data segment decriptors needed
+ *
+ * Returns the number of IOCB entries needed to store @dsds.
+ */
+static inline uint16_t
+qla24xx_calc_iocbs(uint16_t dsds)
+{
+	uint16_t iocbs;
+
+	iocbs = 1;
+	if (dsds > 1) {
+		iocbs += (dsds - 1) / 5;
+		if ((dsds - 1) % 5)
+			iocbs++;
+	}
+	return iocbs;
+}
+
+/**
+ * qla24xx_build_scsi_iocbs() - Build IOCB command utilizing Command Type 7
+ * IOCB types.
+ *
+ * @sp: SRB command to process
+ * @cmd_pkt: Command type 3 IOCB
+ * @tot_dsds: Total number of segments to transfer
+ */
+static inline void
+qla24xx_build_scsi_iocbs(srb_t *sp, struct cmd_type_7 *cmd_pkt,
+    uint16_t tot_dsds)
+{
+	uint16_t	avail_dsds;
+	uint32_t	*cur_dsd;
+	scsi_qla_host_t	*ha;
+	struct scsi_cmnd *cmd;
+
+	cmd = sp->cmd;
+
+	/* Update entry type to indicate Command Type 3 IOCB */
+	*((uint32_t *)(&cmd_pkt->entry_type)) =
+	    __constant_cpu_to_le32(COMMAND_TYPE_7);
+
+	/* No data transfer */
+	if (cmd->request_bufflen == 0 || cmd->sc_data_direction == DMA_NONE) {
+		cmd_pkt->byte_count = __constant_cpu_to_le32(0);
+		return;
+	}
+
+	ha = sp->ha;
+
+	/* Set transfer direction */
+	if (cmd->sc_data_direction == DMA_TO_DEVICE)
+		cmd_pkt->task_mgmt_flags =
+		    __constant_cpu_to_le16(TMF_WRITE_DATA);
+	else if (cmd->sc_data_direction == DMA_FROM_DEVICE)
+		cmd_pkt->task_mgmt_flags =
+		    __constant_cpu_to_le16(TMF_READ_DATA);
+
+	/* One DSD is available in the Command Type 3 IOCB */
+	avail_dsds = 1;
+	cur_dsd = (uint32_t *)&cmd_pkt->dseg_0_address;
+
+	/* Load data segments */
+	if (cmd->use_sg != 0) {
+		struct	scatterlist *cur_seg;
+		struct	scatterlist *end_seg;
+
+		cur_seg = (struct scatterlist *)cmd->request_buffer;
+		end_seg = cur_seg + tot_dsds;
+		while (cur_seg < end_seg) {
+			dma_addr_t	sle_dma;
+			cont_a64_entry_t *cont_pkt;
+
+			/* Allocate additional continuation packets? */
+			if (avail_dsds == 0) {
+				/*
+				 * Five DSDs are available in the Continuation
+				 * Type 1 IOCB.
+				 */
+				cont_pkt = qla2x00_prep_cont_type1_iocb(ha);
+				cur_dsd = (uint32_t *)cont_pkt->dseg_0_address;
+				avail_dsds = 5;
+			}
+
+			sle_dma = sg_dma_address(cur_seg);
+			*cur_dsd++ = cpu_to_le32(LSD(sle_dma));
+			*cur_dsd++ = cpu_to_le32(MSD(sle_dma));
+			*cur_dsd++ = cpu_to_le32(sg_dma_len(cur_seg));
+			avail_dsds--;
+
+			cur_seg++;
+		}
+	} else {
+		*cur_dsd++ = cpu_to_le32(LSD(sp->dma_handle));
+		*cur_dsd++ = cpu_to_le32(MSD(sp->dma_handle));
+		*cur_dsd++ = cpu_to_le32(cmd->request_bufflen);
+	}
+}
+
+
+/**
+ * qla24xx_start_scsi() - Send a SCSI command to the ISP
+ * @sp: command to send to the ISP
+ *
+ * Returns non-zero if a failure occured, else zero.
+ */
+int
+qla24xx_start_scsi(srb_t *sp)
+{
+	int		ret;
+	unsigned long   flags;
+	scsi_qla_host_t	*ha;
+	struct scsi_cmnd *cmd;
+	uint32_t	*clr_ptr;
+	uint32_t        index;
+	uint32_t	handle;
+	struct cmd_type_7 *cmd_pkt;
+	struct scatterlist *sg;
+	uint16_t	cnt;
+	uint16_t	req_cnt;
+	uint16_t	tot_dsds;
+	struct device_reg_24xx __iomem *reg;
+	char		tag[2];
+
+	/* Setup device pointers. */
+	ret = 0;
+	ha = sp->ha;
+	reg = &ha->iobase->isp24;
+	cmd = sp->cmd;
+	/* So we know we haven't pci_map'ed anything yet */
+	tot_dsds = 0;
+
+	/* Send marker if required */
+	if (ha->marker_needed != 0) {
+		if (qla2x00_marker(ha, 0, 0, MK_SYNC_ALL) != QLA_SUCCESS) {
+			return QLA_FUNCTION_FAILED;
+		}
+		ha->marker_needed = 0;
+	}
+
+	/* Acquire ring specific lock */
+	spin_lock_irqsave(&ha->hardware_lock, flags);
+
+	/* Check for room in outstanding command list. */
+	handle = ha->current_outstanding_cmd;
+	for (index = 1; index < MAX_OUTSTANDING_COMMANDS; index++) {
+		handle++;
+		if (handle == MAX_OUTSTANDING_COMMANDS)
+			handle = 1;
+		if (ha->outstanding_cmds[handle] == 0)
+			break;
+	}
+	if (index == MAX_OUTSTANDING_COMMANDS)
+		goto queuing_error;
+
+	/* Map the sg table so we have an accurate count of sg entries needed */
+	if (cmd->use_sg) {
+		sg = (struct scatterlist *) cmd->request_buffer;
+		tot_dsds = pci_map_sg(ha->pdev, sg, cmd->use_sg,
+		    cmd->sc_data_direction);
+		if (tot_dsds == 0)
+			goto queuing_error;
+	} else if (cmd->request_bufflen) {
+		dma_addr_t      req_dma;
+
+		req_dma = pci_map_single(ha->pdev, cmd->request_buffer,
+		    cmd->request_bufflen, cmd->sc_data_direction);
+		if (dma_mapping_error(req_dma))
+			goto queuing_error;
+
+		sp->dma_handle = req_dma;
+		tot_dsds = 1;
+	}
+
+	req_cnt = qla24xx_calc_iocbs(tot_dsds);
+	if (ha->req_q_cnt < (req_cnt + 2)) {
+		cnt = (uint16_t)RD_REG_DWORD_RELAXED(&reg->req_q_out);
+		if (ha->req_ring_index < cnt)
+			ha->req_q_cnt = cnt - ha->req_ring_index;
+		else
+			ha->req_q_cnt = ha->request_q_length -
+				(ha->req_ring_index - cnt);
+	}
+	if (ha->req_q_cnt < (req_cnt + 2)) {
+		if  (cmd->use_sg)
+			pci_unmap_sg(ha->pdev, sg, cmd->use_sg,
+					cmd->sc_data_direction);
+		goto queuing_error;
+	}
+
+	/* Build command packet. */
+	ha->current_outstanding_cmd = handle;
+	ha->outstanding_cmds[handle] = sp;
+	sp->ha = ha;
+	sp->cmd->host_scribble = (unsigned char *)(unsigned long)handle;
+	ha->req_q_cnt -= req_cnt;
+
+	cmd_pkt = (struct cmd_type_7 *)ha->request_ring_ptr;
+	cmd_pkt->handle = handle;
+
+	/* Zero out remaining portion of packet. */
+	clr_ptr = (uint32_t *)cmd_pkt + 2;
+	memset(clr_ptr, 0, REQUEST_ENTRY_SIZE - 8);
+	cmd_pkt->dseg_count = cpu_to_le16(tot_dsds);
+
+	/* Set NPORT-ID and LUN number*/
+	cmd_pkt->nport_handle = cpu_to_le16(sp->fcport->loop_id);
+	cmd_pkt->port_id[0] = sp->fcport->d_id.b.al_pa;
+	cmd_pkt->port_id[1] = sp->fcport->d_id.b.area;
+	cmd_pkt->port_id[2] = sp->fcport->d_id.b.domain;
+
+	cmd_pkt->lun[1] = LSB(sp->cmd->device->lun);
+	cmd_pkt->lun[2] = MSB(sp->cmd->device->lun);
+
+	/* Update tagged queuing modifier -- default is TSK_SIMPLE (0). */
+	if (scsi_populate_tag_msg(cmd, tag)) {
+		switch (tag[0]) {
+		case MSG_HEAD_TAG:
+			cmd_pkt->task = TSK_HEAD_OF_QUEUE;
+			break;
+		case MSG_ORDERED_TAG:
+			cmd_pkt->task = TSK_ORDERED;
+			break;
+		}
+	}
+
+	/* Load SCSI command packet. */
+	memcpy(cmd_pkt->fcp_cdb, cmd->cmnd, cmd->cmd_len);
+	host_to_fcp_swap(cmd_pkt->fcp_cdb, sizeof(cmd_pkt->fcp_cdb));
+
+	cmd_pkt->byte_count = cpu_to_le32((uint32_t)cmd->request_bufflen);
+
+	/* Build IOCB segments */
+	qla24xx_build_scsi_iocbs(sp, cmd_pkt, tot_dsds);
+
+	/* Set total data segment count. */
+	cmd_pkt->entry_count = (uint8_t)req_cnt;
+	wmb();
+
+	/* Adjust ring index. */
+	ha->req_ring_index++;
+	if (ha->req_ring_index == ha->request_q_length) {
+		ha->req_ring_index = 0;
+		ha->request_ring_ptr = ha->request_ring;
+	} else
+		ha->request_ring_ptr++;
+
+	sp->flags |= SRB_DMA_VALID;
+	sp->state = SRB_ACTIVE_STATE;
+
+	/* Set chip new ring index. */
+	WRT_REG_DWORD(&reg->req_q_in, ha->req_ring_index);
+	RD_REG_DWORD_RELAXED(&reg->req_q_in);		/* PCI Posting. */
+
+	spin_unlock_irqrestore(&ha->hardware_lock, flags);
+	return QLA_SUCCESS;
+
+queuing_error:
+	if (cmd->use_sg && tot_dsds) {
+		sg = (struct scatterlist *) cmd->request_buffer;
+		pci_unmap_sg(ha->pdev, sg, cmd->use_sg,
+		    cmd->sc_data_direction);
+	} else if (tot_dsds) {
+		pci_unmap_single(ha->pdev, sp->dma_handle,
+		    cmd->request_bufflen, cmd->sc_data_direction);
+	}
+	spin_unlock_irqrestore(&ha->hardware_lock, flags);
+
+	return QLA_FUNCTION_FAILED;
 }
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -2,7 +2,7 @@
  *                  QLOGIC LINUX SOFTWARE
  *
  * QLogic ISP2x00 device driver for Linux 2.6.x
- * Copyright (C) 2003-2004 QLogic Corporation
+ * Copyright (C) 2003-2005 QLogic Corporation
  * (www.qlogic.com)
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -19,14 +19,17 @@
 #include "qla_def.h"
 
 static void qla2x00_mbx_completion(scsi_qla_host_t *, uint16_t);
-static void qla2x00_async_event(scsi_qla_host_t *, uint32_t);
+static void qla2x00_async_event(scsi_qla_host_t *, uint16_t *);
 static void qla2x00_process_completed_request(struct scsi_qla_host *, uint32_t);
 void qla2x00_process_response_queue(struct scsi_qla_host *);
-static void qla2x00_status_entry(scsi_qla_host_t *, sts_entry_t *);
+static void qla2x00_status_entry(scsi_qla_host_t *, void *);
 static void qla2x00_status_cont_entry(scsi_qla_host_t *, sts_cont_entry_t *);
 static void qla2x00_error_entry(scsi_qla_host_t *, sts_entry_t *);
 static void qla2x00_ms_entry(scsi_qla_host_t *, ms_iocb_entry_t *);
 
+void qla24xx_process_response_queue(scsi_qla_host_t *);
+static void qla24xx_ms_entry(scsi_qla_host_t *, struct ct_entry_24xx *);
+
 /**
  * qla2100_intr_handler() - Process interrupts for the ISP2100 and ISP2200.
  * @irq:
@@ -41,11 +44,11 @@ irqreturn_t
 qla2100_intr_handler(int irq, void *dev_id, struct pt_regs *regs)
 {
 	scsi_qla_host_t	*ha;
-	device_reg_t __iomem *reg;
+	struct device_reg_2xxx __iomem *reg;
 	int		status;
 	unsigned long	flags;
 	unsigned long	iter;
-	uint32_t	mbx;
+	uint16_t	mb[4];
 
 	ha = (scsi_qla_host_t *) dev_id;
 	if (!ha) {
@@ -54,7 +57,7 @@ qla2100_intr_handler(int irq, void *dev_
 		return (IRQ_NONE);
 	}
 
-	reg = ha->iobase;
+	reg = &ha->iobase->isp;
 	status = 0;
 
 	spin_lock_irqsave(&ha->hardware_lock, flags);
@@ -67,17 +70,20 @@ qla2100_intr_handler(int irq, void *dev_
 			RD_REG_WORD(&reg->hccr);
 
 			/* Get mailbox data. */
-			mbx = RD_MAILBOX_REG(ha, reg, 0);
-			if (mbx > 0x3fff && mbx < 0x8000) {
-				qla2x00_mbx_completion(ha, (uint16_t)mbx);
+			mb[0] = RD_MAILBOX_REG(ha, reg, 0);
+			if (mb[0] > 0x3fff && mb[0] < 0x8000) {
+				qla2x00_mbx_completion(ha, mb[0]);
 				status |= MBX_INTERRUPT;
-			} else if (mbx > 0x7fff && mbx < 0xc000) {
-				qla2x00_async_event(ha, mbx);
+			} else if (mb[0] > 0x7fff && mb[0] < 0xc000) {
+				mb[1] = RD_MAILBOX_REG(ha, reg, 1);
+				mb[2] = RD_MAILBOX_REG(ha, reg, 2);
+				mb[3] = RD_MAILBOX_REG(ha, reg, 3);
+				qla2x00_async_event(ha, mb);
 			} else {
 				/*EMPTY*/
 				DEBUG2(printk("scsi(%ld): Unrecognized "
-				    "interrupt type (%d)\n",
-				    ha->host_no, mbx));
+				    "interrupt type (%d).\n",
+				    ha->host_no, mb[0]));
 			}
 			/* Release mailbox registers. */
 			WRT_REG_WORD(&reg->semaphore, 0);
@@ -91,9 +97,6 @@ qla2100_intr_handler(int irq, void *dev_
 	}
 	spin_unlock_irqrestore(&ha->hardware_lock, flags);
 
-	ha->last_irq_cpu = _smp_processor_id();
-	ha->total_isr_cnt++;
-
 	if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) &&
 	    (status & MBX_INTERRUPT) && ha->flags.mbox_int) {
 		spin_lock_irqsave(&ha->mbx_reg_lock, flags);
@@ -121,13 +124,13 @@ irqreturn_t
 qla2300_intr_handler(int irq, void *dev_id, struct pt_regs *regs)
 {
 	scsi_qla_host_t	*ha;
-	device_reg_t __iomem *reg;
+	struct device_reg_2xxx __iomem *reg;
 	int		status;
 	unsigned long	flags;
 	unsigned long	iter;
 	uint32_t	stat;
-	uint32_t	mbx;
 	uint16_t	hccr;
+	uint16_t	mb[4];
 
 	ha = (scsi_qla_host_t *) dev_id;
 	if (!ha) {
@@ -136,7 +139,7 @@ qla2300_intr_handler(int irq, void *dev_
 		return (IRQ_NONE);
 	}
 
-	reg = ha->iobase;
+	reg = &ha->iobase->isp;
 	status = 0;
 
 	spin_lock_irqsave(&ha->hardware_lock, flags);
@@ -149,7 +152,7 @@ qla2300_intr_handler(int irq, void *dev_
 				    "Parity error -- HCCR=%x.\n", hccr);
 			else
 				qla_printk(KERN_INFO, ha,
-				    "RISC paused -- HCCR=%x\n", hccr);
+				    "RISC paused -- HCCR=%x.\n", hccr);
 
 			/*
 			 * Issue a "HARD" reset in order for the RISC
@@ -163,35 +166,41 @@ qla2300_intr_handler(int irq, void *dev_
 		} else if ((stat & HSR_RISC_INT) == 0)
 			break;
 
-		mbx = MSW(stat);
 		switch (stat & 0xff) {
-		case 0x13:
-			qla2x00_process_response_queue(ha);
-			break;
 		case 0x1:
 		case 0x2:
 		case 0x10:
 		case 0x11:
-			qla2x00_mbx_completion(ha, (uint16_t)mbx);
+			qla2x00_mbx_completion(ha, MSW(stat));
 			status |= MBX_INTERRUPT;
 
 			/* Release mailbox registers. */
 			WRT_REG_WORD(&reg->semaphore, 0);
 			break;
 		case 0x12:
-			qla2x00_async_event(ha, mbx);
+			mb[0] = MSW(stat);
+			mb[1] = RD_MAILBOX_REG(ha, reg, 1);
+			mb[2] = RD_MAILBOX_REG(ha, reg, 2);
+			mb[3] = RD_MAILBOX_REG(ha, reg, 3);
+			qla2x00_async_event(ha, mb);
+			break;
+		case 0x13:
+			qla2x00_process_response_queue(ha);
 			break;
 		case 0x15:
-			mbx = mbx << 16 | MBA_CMPLT_1_16BIT;
-			qla2x00_async_event(ha, mbx);
+			mb[0] = MBA_CMPLT_1_16BIT;
+			mb[1] = MSW(stat);
+			qla2x00_async_event(ha, mb);
 			break;
 		case 0x16:
-			mbx = mbx << 16 | MBA_SCSI_COMPLETION;
-			qla2x00_async_event(ha, mbx);
+			mb[0] = MBA_SCSI_COMPLETION;
+			mb[1] = MSW(stat);
+			mb[2] = RD_MAILBOX_REG(ha, reg, 2);
+			qla2x00_async_event(ha, mb);
 			break;
 		default:
 			DEBUG2(printk("scsi(%ld): Unrecognized interrupt type "
-			    "(%d)\n",
+			    "(%d).\n",
 			    ha->host_no, stat & 0xff));
 			break;
 		}
@@ -200,9 +209,6 @@ qla2300_intr_handler(int irq, void *dev_
 	}
 	spin_unlock_irqrestore(&ha->hardware_lock, flags);
 
-	ha->last_irq_cpu = _smp_processor_id();
-	ha->total_isr_cnt++;
-
 	if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) &&
 	    (status & MBX_INTERRUPT) && ha->flags.mbox_int) {
 		spin_lock_irqsave(&ha->mbx_reg_lock, flags);
@@ -226,7 +232,7 @@ qla2x00_mbx_completion(scsi_qla_host_t *
 {
 	uint16_t	cnt;
 	uint16_t __iomem *wptr;
-	device_reg_t __iomem *reg = ha->iobase;
+	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
 
 	/* Load return mailbox registers. */
 	ha->flags.mbox_int = 1;
@@ -234,13 +240,13 @@ qla2x00_mbx_completion(scsi_qla_host_t *
 	wptr = (uint16_t __iomem *)MAILBOX_REG(ha, reg, 1);
 
 	for (cnt = 1; cnt < ha->mbx_count; cnt++) {
-		if (IS_QLA2200(ha) && cnt == 8) 
+		if (IS_QLA2200(ha) && cnt == 8)
 			wptr = (uint16_t __iomem *)MAILBOX_REG(ha, reg, 8);
 		if (cnt == 4 || cnt == 5)
 			ha->mailbox_out[cnt] = qla2x00_debounce_register(wptr);
 		else
 			ha->mailbox_out[cnt] = RD_REG_WORD(wptr);
-	
+
 		wptr++;
 	}
 
@@ -256,78 +262,65 @@ qla2x00_mbx_completion(scsi_qla_host_t *
 /**
  * qla2x00_async_event() - Process aynchronous events.
  * @ha: SCSI driver HA context
- * @mb0: Mailbox0 register
+ * @mb: Mailbox registers (0 - 3)
  */
 static void
-qla2x00_async_event(scsi_qla_host_t *ha, uint32_t mbx)
+qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
 {
-	static char	*link_speeds[5] = { "1", "2", "4", "?", "10" };
+#define LS_UNKNOWN	2
+	static char	*link_speeds[5] = { "1", "2", "?", "4", "10" };
 	char		*link_speed;
-	uint16_t	mb[4];
 	uint16_t	handle_cnt;
 	uint16_t	cnt;
 	uint32_t	handles[5];
-	device_reg_t __iomem *reg = ha->iobase;
+	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
 	uint32_t	rscn_entry, host_pid;
 	uint8_t		rscn_queue_index;
 
 	/* Setup to process RIO completion. */
 	handle_cnt = 0;
-	mb[0] = LSW(mbx);
 	switch (mb[0]) {
 	case MBA_SCSI_COMPLETION:
-		if (IS_QLA2100(ha) || IS_QLA2200(ha))
-			handles[0] = le32_to_cpu(
-			    ((uint32_t)(RD_MAILBOX_REG(ha, reg, 2) << 16)) |
-			    RD_MAILBOX_REG(ha, reg, 1));
-		else
-			handles[0] = le32_to_cpu(
-			    ((uint32_t)(RD_MAILBOX_REG(ha, reg, 2) << 16)) |
-			    MSW(mbx));
+		handles[0] = le32_to_cpu((uint32_t)((mb[2] << 16) | mb[1]));
 		handle_cnt = 1;
 		break;
 	case MBA_CMPLT_1_16BIT:
-		if (IS_QLA2100(ha) || IS_QLA2200(ha))
-			handles[0] = (uint32_t)RD_MAILBOX_REG(ha, reg, 1);
-		else
-			handles[0] = MSW(mbx);
+		handles[0] = mb[1];
 		handle_cnt = 1;
 		mb[0] = MBA_SCSI_COMPLETION;
 		break;
 	case MBA_CMPLT_2_16BIT:
-		handles[0] = (uint32_t)RD_MAILBOX_REG(ha, reg, 1);
-		handles[1] = (uint32_t)RD_MAILBOX_REG(ha, reg, 2);
+		handles[0] = mb[1];
+		handles[1] = mb[2];
 		handle_cnt = 2;
 		mb[0] = MBA_SCSI_COMPLETION;
 		break;
 	case MBA_CMPLT_3_16BIT:
-		handles[0] = (uint32_t)RD_MAILBOX_REG(ha, reg, 1);
-		handles[1] = (uint32_t)RD_MAILBOX_REG(ha, reg, 2);
-		handles[2] = (uint32_t)RD_MAILBOX_REG(ha, reg, 3);
+		handles[0] = mb[1];
+		handles[1] = mb[2];
+		handles[2] = mb[3];
 		handle_cnt = 3;
 		mb[0] = MBA_SCSI_COMPLETION;
 		break;
 	case MBA_CMPLT_4_16BIT:
-		handles[0] = (uint32_t)RD_MAILBOX_REG(ha, reg, 1);
-		handles[1] = (uint32_t)RD_MAILBOX_REG(ha, reg, 2);
-		handles[2] = (uint32_t)RD_MAILBOX_REG(ha, reg, 3);
+		handles[0] = mb[1];
+		handles[1] = mb[2];
+		handles[2] = mb[3];
 		handles[3] = (uint32_t)RD_MAILBOX_REG(ha, reg, 6);
 		handle_cnt = 4;
 		mb[0] = MBA_SCSI_COMPLETION;
 		break;
 	case MBA_CMPLT_5_16BIT:
-		handles[0] = (uint32_t)RD_MAILBOX_REG(ha, reg, 1);
-		handles[1] = (uint32_t)RD_MAILBOX_REG(ha, reg, 2);
-		handles[2] = (uint32_t)RD_MAILBOX_REG(ha, reg, 3);
+		handles[0] = mb[1];
+		handles[1] = mb[2];
+		handles[2] = mb[3];
 		handles[3] = (uint32_t)RD_MAILBOX_REG(ha, reg, 6);
 		handles[4] = (uint32_t)RD_MAILBOX_REG(ha, reg, 7);
 		handle_cnt = 5;
 		mb[0] = MBA_SCSI_COMPLETION;
 		break;
 	case MBA_CMPLT_2_32BIT:
-		handles[0] = le32_to_cpu(
-		    ((uint32_t)(RD_MAILBOX_REG(ha, reg, 2) << 16)) |
-		    RD_MAILBOX_REG(ha, reg, 1));
+		handles[0] = le32_to_cpu((uint32_t)((mb[2] << 16) | mb[1]));
 		handles[1] = le32_to_cpu(
 		    ((uint32_t)(RD_MAILBOX_REG(ha, reg, 7) << 16)) |
 		    RD_MAILBOX_REG(ha, reg, 6));
@@ -362,12 +355,17 @@ qla2x00_async_event(scsi_qla_host_t *ha,
 		    "ISP System Error - mbx1=%xh mbx2=%xh mbx3=%xh.\n",
 		    mb[1], mb[2], mb[3]);
 
-		if (IS_QLA2100(ha) || IS_QLA2200(ha))
-			qla2100_fw_dump(ha, 1);
-		else
-	    		qla2300_fw_dump(ha, 1);
+		ha->isp_ops.fw_dump(ha, 1);
 
-		if (mb[1] == 0) {
+		if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) {
+			if (mb[1] == 0 && mb[2] == 0) {
+				qla_printk(KERN_ERR, ha,
+				    "Unrecoverable Hardware Error: adapter "
+				    "marked OFFLINE!\n");
+				ha->flags.online = 0;
+			} else
+				set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
+		} else if (mb[1] == 0) {
 			qla_printk(KERN_INFO, ha,
 			    "Unrecoverable Hardware Error: adapter marked "
 			    "OFFLINE!\n");
@@ -398,8 +396,6 @@ qla2x00_async_event(scsi_qla_host_t *ha,
 		break;
 
 	case MBA_LIP_OCCURRED:		/* Loop Initialization Procedure */
-		mb[1] = RD_MAILBOX_REG(ha, reg, 1);
-
 		DEBUG2(printk("scsi(%ld): LIP occured (%x).\n", ha->host_no,
 		    mb[1]));
 		qla_printk(KERN_INFO, ha, "LIP occured (%x).\n", mb[1]);
@@ -417,17 +413,14 @@ qla2x00_async_event(scsi_qla_host_t *ha,
 		/* Update AEN queue. */
 		qla2x00_enqueue_aen(ha, MBA_LIP_OCCURRED, NULL);
 
-		ha->total_lip_cnt++;
 		break;
 
 	case MBA_LOOP_UP:		/* Loop Up Event */
-		mb[1] = RD_MAILBOX_REG(ha, reg, 1);
-
 		ha->link_data_rate = 0;
 		if (IS_QLA2100(ha) || IS_QLA2200(ha)) {
 			link_speed = link_speeds[0];
 		} else {
-			link_speed = link_speeds[3];
+			link_speed = link_speeds[LS_UNKNOWN];
 			if (mb[1] < 5)
 				link_speed = link_speeds[mb[1]];
 			ha->link_data_rate = mb[1];
@@ -445,9 +438,9 @@ qla2x00_async_event(scsi_qla_host_t *ha,
 		break;
 
 	case MBA_LOOP_DOWN:		/* Loop Down Event */
-		DEBUG2(printk("scsi(%ld): Asynchronous LOOP DOWN.\n",
-		    ha->host_no));
-		qla_printk(KERN_INFO, ha, "LOOP DOWN detected.\n");
+		DEBUG2(printk("scsi(%ld): Asynchronous LOOP DOWN (%x).\n",
+		    ha->host_no, mb[1]));
+		qla_printk(KERN_INFO, ha, "LOOP DOWN detected (%x).\n", mb[1]);
 
 		if (atomic_read(&ha->loop_state) != LOOP_DOWN) {
 			atomic_set(&ha->loop_state, LOOP_DOWN);
@@ -464,8 +457,6 @@ qla2x00_async_event(scsi_qla_host_t *ha,
 		break;
 
 	case MBA_LIP_RESET:		/* LIP reset occurred */
-		mb[1] = RD_MAILBOX_REG(ha, reg, 1);
-
 		DEBUG2(printk("scsi(%ld): Asynchronous LIP RESET (%x).\n",
 		    ha->host_no, mb[1]));
 		qla_printk(KERN_INFO, ha,
@@ -485,7 +476,6 @@ qla2x00_async_event(scsi_qla_host_t *ha,
 		/* Update AEN queue. */
 		qla2x00_enqueue_aen(ha, MBA_LIP_RESET, NULL);
 
-		ha->total_lip_cnt++;
 		break;
 
 	case MBA_POINT_TO_POINT:	/* Point-to-Point */
@@ -517,8 +507,6 @@ qla2x00_async_event(scsi_qla_host_t *ha,
 		if (IS_QLA2100(ha))
 			break;
 
-		mb[1] = RD_MAILBOX_REG(ha, reg, 1);
-
 		DEBUG2(printk("scsi(%ld): Asynchronous Change In Connection "
 		    "received.\n",
 		    ha->host_no));
@@ -526,7 +514,7 @@ qla2x00_async_event(scsi_qla_host_t *ha,
 		    "Configuration change detected: value=%x.\n", mb[1]);
 
 		if (atomic_read(&ha->loop_state) != LOOP_DOWN) {
-			atomic_set(&ha->loop_state, LOOP_DOWN);  
+			atomic_set(&ha->loop_state, LOOP_DOWN);
 			if (!atomic_read(&ha->loop_down_timer))
 				atomic_set(&ha->loop_down_timer,
 				    LOOP_DOWN_TIME);
@@ -538,16 +526,14 @@ qla2x00_async_event(scsi_qla_host_t *ha,
 		break;
 
 	case MBA_PORT_UPDATE:		/* Port database update */
-		mb[1] = RD_MAILBOX_REG(ha, reg, 1);
-		mb[2] = RD_MAILBOX_REG(ha, reg, 2);
-
 		/*
 		 * If a single remote port just logged into (or logged out of)
 		 * us, create a new entry in our rscn fcports list and handle
 		 * the event like an RSCN.
 		 */
 		if (!IS_QLA2100(ha) && !IS_QLA2200(ha) && !IS_QLA6312(ha) &&
-		    !IS_QLA6322(ha) && ha->flags.init_done && mb[1] != 0xffff &&
+		    !IS_QLA6322(ha) && !IS_QLA24XX(ha) && !IS_QLA25XX(ha) &&
+		    ha->flags.init_done && mb[1] != 0xffff &&
 		    ((ha->operating_mode == P2P && mb[1] != 0) ||
 		    (ha->operating_mode != P2P && mb[1] !=
 			SNS_FIRST_LOOP_ID)) && (mb[2] == 6 || mb[2] == 7)) {
@@ -558,8 +544,9 @@ qla2x00_async_event(scsi_qla_host_t *ha,
 			rscn_fcport = qla2x00_alloc_rscn_fcport(ha, GFP_ATOMIC);
 			if (rscn_fcport) {
 				DEBUG14(printk("scsi(%ld): Port Update -- "
-				    "creating RSCN fcport %p for %x/%x.\n",
-				    ha->host_no, rscn_fcport, mb[1], mb[2]));
+				    "creating RSCN fcport %p for %x/%x/%x.\n",
+				    ha->host_no, rscn_fcport, mb[1], mb[2],
+				    mb[3]));
 
 				rscn_fcport->loop_id = mb[1];
 				rscn_fcport->d_id.b24 = INVALID_PORT_ID;
@@ -588,15 +575,16 @@ qla2x00_async_event(scsi_qla_host_t *ha,
 		if (atomic_read(&ha->loop_state) != LOOP_DOWN &&
 		    atomic_read(&ha->loop_state) != LOOP_DEAD) {
 			DEBUG2(printk("scsi(%ld): Asynchronous PORT UPDATE "
-			    "ignored.\n", ha->host_no));
+			    "ignored %04x/%04x/%04x.\n", ha->host_no, mb[1],
+			    mb[2], mb[3]));
 			break;
 		}
 
 		DEBUG2(printk("scsi(%ld): Asynchronous PORT UPDATE.\n",
 		    ha->host_no));
 		DEBUG(printk(KERN_INFO
-		    "scsi(%ld): Port database changed %04x %04x.\n",
-		    ha->host_no, mb[1], mb[2]));
+		    "scsi(%ld): Port database changed %04x %04x %04x.\n",
+		    ha->host_no, mb[1], mb[2], mb[3]));
 
 		/*
 		 * Mark all devices as missing so we will login again.
@@ -615,9 +603,6 @@ qla2x00_async_event(scsi_qla_host_t *ha,
 		break;
 
 	case MBA_RSCN_UPDATE:		/* State Change Registration */
-		mb[1] = RD_MAILBOX_REG(ha, reg, 1);
-		mb[2] = RD_MAILBOX_REG(ha, reg, 2);
-
 		DEBUG2(printk("scsi(%ld): Asynchronous RSCR UPDATE.\n",
 		    ha->host_no));
 		DEBUG(printk(KERN_INFO
@@ -666,6 +651,11 @@ qla2x00_async_event(scsi_qla_host_t *ha,
 
 		qla2x00_process_response_queue(ha);
 		break;
+
+	case MBA_DISCARD_RND_FRAME:
+		DEBUG2(printk("scsi(%ld): Discard RND Frame -- %04x %04x "
+		    "%04x.\n", ha->host_no, mb[1], mb[2], mb[3]));
+		break;
 	}
 }
 
@@ -695,14 +685,11 @@ qla2x00_process_completed_request(struct
 		/* Free outstanding command slot. */
 		ha->outstanding_cmds[index] = NULL;
 
-		if (ha->actthreads)
-			ha->actthreads--;
 		CMD_COMPL_STATUS(sp->cmd) = 0L;
 		CMD_SCSI_STATUS(sp->cmd) = 0L;
 
 		/* Save ISP completion status */
 		sp->cmd->result = DID_OK << 16;
-		sp->fo_retry_cnt = 0;
 		qla2x00_sp_compl(ha, sp);
 	} else {
 		DEBUG2(printk("scsi(%ld): Invalid ISP SCSI completion handle\n",
@@ -721,7 +708,7 @@ qla2x00_process_completed_request(struct
 void
 qla2x00_process_response_queue(struct scsi_qla_host *ha)
 {
-	device_reg_t __iomem *reg = ha->iobase;
+	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
 	sts_entry_t	*pkt;
 	uint16_t        handle_cnt;
 	uint16_t        cnt;
@@ -815,31 +802,41 @@ qla2x00_process_response_queue(struct sc
  * @pkt: Entry pointer
  */
 static void
-qla2x00_status_entry(scsi_qla_host_t *ha, sts_entry_t *pkt)
+qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt)
 {
-	unsigned	b, t, l;
 	srb_t		*sp;
 	fc_port_t	*fcport;
 	struct scsi_cmnd *cp;
+	sts_entry_t *sts;
+	struct sts_entry_24xx *sts24;
 	uint16_t	comp_status;
 	uint16_t	scsi_status;
 	uint8_t		lscsi_status;
 	int32_t		resid;
-	uint8_t		sense_sz = 0;
-	uint16_t	rsp_info_len;
+	uint32_t	sense_len, rsp_info_len, resid_len;
+	uint8_t		*rsp_info, *sense_data;
+
+	sts = (sts_entry_t *) pkt;
+	sts24 = (struct sts_entry_24xx *) pkt;
+	if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) {
+		comp_status = le16_to_cpu(sts24->comp_status);
+		scsi_status = le16_to_cpu(sts24->scsi_status) & SS_MASK;
+	} else {
+		comp_status = le16_to_cpu(sts->comp_status);
+		scsi_status = le16_to_cpu(sts->scsi_status) & SS_MASK;
+	}
 
 	/* Fast path completion. */
-	if (le16_to_cpu(pkt->comp_status) == CS_COMPLETE &&
-	    (le16_to_cpu(pkt->scsi_status) & SS_MASK) == 0) {
-		qla2x00_process_completed_request(ha, pkt->handle);
+	if (comp_status == CS_COMPLETE && scsi_status == 0) {
+		qla2x00_process_completed_request(ha, sts->handle);
 
 		return;
 	}
 
 	/* Validate handle. */
-	if (pkt->handle < MAX_OUTSTANDING_COMMANDS) {
-		sp = ha->outstanding_cmds[pkt->handle];
-		ha->outstanding_cmds[pkt->handle] = NULL;
+	if (sts->handle < MAX_OUTSTANDING_COMMANDS) {
+		sp = ha->outstanding_cmds[sts->handle];
+		ha->outstanding_cmds[sts->handle] = NULL;
 	} else
 		sp = NULL;
 
@@ -849,7 +846,7 @@ qla2x00_status_entry(scsi_qla_host_t *ha
 		qla_printk(KERN_WARNING, ha, "Status Entry invalid handle.\n");
 
 		set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
-		if (ha->dpc_wait && !ha->dpc_active) 
+		if (ha->dpc_wait && !ha->dpc_active)
 			up(ha->dpc_wait);
 
 		return;
@@ -858,43 +855,49 @@ qla2x00_status_entry(scsi_qla_host_t *ha
 	if (cp == NULL) {
 		DEBUG2(printk("scsi(%ld): Command already returned back to OS "
 		    "pkt->handle=%d sp=%p sp->state:%d\n",
-		    ha->host_no, pkt->handle, sp, sp->state));
+		    ha->host_no, sts->handle, sp, sp->state));
 		qla_printk(KERN_WARNING, ha,
 		    "Command is NULL: already returned to OS (sp=%p)\n", sp);
 
 		return;
 	}
 
-	if (ha->actthreads)
-		ha->actthreads--;
-
-	comp_status = le16_to_cpu(pkt->comp_status);
-	/* Mask of reserved bits 12-15, before we examine the scsi status */
-	scsi_status = le16_to_cpu(pkt->scsi_status) & SS_MASK;
-	lscsi_status = scsi_status & STATUS_MASK;
-
-	CMD_ENTRY_STATUS(cp) = pkt->entry_status;
+  	lscsi_status = scsi_status & STATUS_MASK;
+	CMD_ENTRY_STATUS(cp) = sts->entry_status;
 	CMD_COMPL_STATUS(cp) = comp_status;
 	CMD_SCSI_STATUS(cp) = scsi_status;
 
-	/* Generate LU queue on cntrl, target, LUN */
-	b = cp->device->channel;
-	t = cp->device->id;
-	l = cp->device->lun,
-
 	fcport = sp->fcport;
 
+	sense_len = rsp_info_len = resid_len = 0;
+	if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) {
+		sense_len = le32_to_cpu(sts24->sense_len);
+		rsp_info_len = le32_to_cpu(sts24->rsp_data_len);
+		resid_len = le32_to_cpu(sts24->rsp_residual_count);
+		rsp_info = sts24->data;
+		sense_data = sts24->data;
+		host_to_fcp_swap(sts24->data, sizeof(sts24->data));
+	} else {
+		sense_len = le16_to_cpu(sts->req_sense_length);
+		rsp_info_len = le16_to_cpu(sts->rsp_info_len);
+		resid_len = le32_to_cpu(sts->residual_length);
+		rsp_info = sts->rsp_info;
+		sense_data = sts->req_sense_data;
+	}
+
 	/* Check for any FCP transport errors. */
 	if (scsi_status & SS_RESPONSE_INFO_LEN_VALID) {
-		rsp_info_len = le16_to_cpu(pkt->rsp_info_len);
-		if (rsp_info_len > 3 && pkt->rsp_info[3]) {
+		/* Sense data lies beyond any FCP RESPONSE data. */
+		if (IS_QLA24XX(ha) || IS_QLA25XX(ha))
+			sense_data += rsp_info_len;
+		if (rsp_info_len > 3 && rsp_info[3]) {
 			DEBUG2(printk("scsi(%ld:%d:%d:%d) FCP I/O protocol "
 			    "failure (%x/%02x%02x%02x%02x%02x%02x%02x%02x)..."
-			    "retrying command\n", ha->host_no, b, t, l,
-			    rsp_info_len, pkt->rsp_info[0], pkt->rsp_info[1],
-			    pkt->rsp_info[2], pkt->rsp_info[3],
-			    pkt->rsp_info[4], pkt->rsp_info[5],
-			    pkt->rsp_info[6], pkt->rsp_info[7]));
+			    "retrying command\n", ha->host_no,
+			    cp->device->channel, cp->device->id,
+			    cp->device->lun, rsp_info_len, rsp_info[0],
+			    rsp_info[1], rsp_info[2], rsp_info[3], rsp_info[4],
+			    rsp_info[5], rsp_info[6], rsp_info[7]));
 
 			cp->result = DID_BUS_BUSY << 16;
 			qla2x00_sp_compl(ha, sp);
@@ -912,7 +915,7 @@ qla2x00_status_entry(scsi_qla_host_t *ha
 			break;
 		}
 		if (scsi_status & (SS_RESIDUAL_UNDER | SS_RESIDUAL_OVER)) {
-			resid = le32_to_cpu(pkt->residual_length);
+			resid = resid_len;
 			cp->resid = resid;
 			CMD_RESID_LEN(cp) = resid;
 		}
@@ -921,39 +924,34 @@ qla2x00_status_entry(scsi_qla_host_t *ha
 		if (lscsi_status != SS_CHECK_CONDITION)
 			break;
 
-		/*
-		 * Copy Sense Data into sense buffer
-		 */
+		/* Copy Sense Data into sense buffer. */
 		memset(cp->sense_buffer, 0, sizeof(cp->sense_buffer));
 
 		if (!(scsi_status & SS_SENSE_LEN_VALID))
 			break;
 
-		if (le16_to_cpu(pkt->req_sense_length) <
-		    sizeof(cp->sense_buffer))
-			sense_sz = le16_to_cpu(pkt->req_sense_length);
-		else
-			sense_sz = sizeof(cp->sense_buffer);
+		if (sense_len >= sizeof(cp->sense_buffer))
+			sense_len = sizeof(cp->sense_buffer);
 
-		CMD_ACTUAL_SNSLEN(cp) = sense_sz;
-		sp->request_sense_length = sense_sz;
+		CMD_ACTUAL_SNSLEN(cp) = sense_len;
+		sp->request_sense_length = sense_len;
 		sp->request_sense_ptr = cp->sense_buffer;
 
 		if (sp->request_sense_length > 32)
-			sense_sz = 32;
+			sense_len = 32;
 
-		memcpy(cp->sense_buffer, pkt->req_sense_data, sense_sz);
+		memcpy(cp->sense_buffer, sense_data, sense_len);
 
-		sp->request_sense_ptr += sense_sz;
-		sp->request_sense_length -= sense_sz;
+		sp->request_sense_ptr += sense_len;
+		sp->request_sense_length -= sense_len;
 		if (sp->request_sense_length != 0)
 			ha->status_srb = sp;
 
 		DEBUG5(printk("%s(): Check condition Sense data, "
-		    "scsi(%ld:%d:%d:%d) cmd=%p pid=%ld\n",
-		    __func__, ha->host_no, b, t, l, cp,
-		    cp->serial_number));
-		if (sense_sz)
+		    "scsi(%ld:%d:%d:%d) cmd=%p pid=%ld\n", __func__,
+		    ha->host_no, cp->device->channel, cp->device->id,
+		    cp->device->lun, cp, cp->serial_number));
+		if (sense_len)
 			DEBUG5(qla2x00_dump_buffer(cp->sense_buffer,
 			    CMD_ACTUAL_SNSLEN(cp)));
 		break;
@@ -961,16 +959,17 @@ qla2x00_status_entry(scsi_qla_host_t *ha
 	case CS_DATA_UNDERRUN:
 		DEBUG2(printk(KERN_INFO
 		    "scsi(%ld:%d:%d) UNDERRUN status detected 0x%x-0x%x.\n",
-		    ha->host_no, t, l, comp_status, scsi_status));
+		    ha->host_no, cp->device->id, cp->device->lun, comp_status,
+		    scsi_status));
 
-		resid = le32_to_cpu(pkt->residual_length);
+		resid = resid_len;
 		if (scsi_status & SS_RESIDUAL_UNDER) {
 			cp->resid = resid;
 			CMD_RESID_LEN(cp) = resid;
 		}
 
 		/*
-		 * Check to see if SCSI Status is non zero. If so report SCSI 
+		 * Check to see if SCSI Status is non zero. If so report SCSI
 		 * Status.
 		 */
 		if (lscsi_status != 0) {
@@ -985,31 +984,30 @@ qla2x00_status_entry(scsi_qla_host_t *ha
 			if (!(scsi_status & SS_SENSE_LEN_VALID))
 				break;
 
-			if (le16_to_cpu(pkt->req_sense_length) <
-			    sizeof(cp->sense_buffer))
-				sense_sz = le16_to_cpu(pkt->req_sense_length);
-			else
-				sense_sz = sizeof(cp->sense_buffer);
+			if (sense_len >= sizeof(cp->sense_buffer))
+				sense_len = sizeof(cp->sense_buffer);
 
-			CMD_ACTUAL_SNSLEN(cp) = sense_sz;
-			sp->request_sense_length = sense_sz;
+			CMD_ACTUAL_SNSLEN(cp) = sense_len;
+			sp->request_sense_length = sense_len;
 			sp->request_sense_ptr = cp->sense_buffer;
 
-			if (sp->request_sense_length > 32) 
-				sense_sz = 32;
+			if (sp->request_sense_length > 32)
+				sense_len = 32;
 
-			memcpy(cp->sense_buffer, pkt->req_sense_data, sense_sz);
+			memcpy(cp->sense_buffer, sense_data, sense_len);
 
-			sp->request_sense_ptr += sense_sz;
-			sp->request_sense_length -= sense_sz;
+			sp->request_sense_ptr += sense_len;
+			sp->request_sense_length -= sense_len;
 			if (sp->request_sense_length != 0)
 				ha->status_srb = sp;
 
 			DEBUG5(printk("%s(): Check condition Sense data, "
 			    "scsi(%ld:%d:%d:%d) cmd=%p pid=%ld\n",
-			    __func__, ha->host_no, b, t, l, cp,
+			    __func__, ha->host_no, cp->device->channel,
+			    cp->device->id, cp->device->lun, cp,
 			    cp->serial_number));
-			if (sense_sz)
+
+			if (sense_len)
 				DEBUG5(qla2x00_dump_buffer(cp->sense_buffer,
 				    CMD_ACTUAL_SNSLEN(cp)));
 		} else {
@@ -1021,12 +1019,12 @@ qla2x00_status_entry(scsi_qla_host_t *ha
 			if (!(scsi_status & SS_RESIDUAL_UNDER)) {
 				DEBUG2(printk("scsi(%ld:%d:%d:%d) Dropped "
 				    "frame(s) detected (%x of %x bytes)..."
-				    "retrying command.\n",
-				    ha->host_no, b, t, l, resid,
+				    "retrying command.\n", ha->host_no,
+				    cp->device->channel, cp->device->id,
+				    cp->device->lun, resid,
 				    cp->request_bufflen));
 
 				cp->result = DID_BUS_BUSY << 16;
-				ha->dropped_frame_error_cnt++;
 				break;
 			}
 
@@ -1036,8 +1034,9 @@ qla2x00_status_entry(scsi_qla_host_t *ha
 				qla_printk(KERN_INFO, ha,
 				    "scsi(%ld:%d:%d:%d): Mid-layer underflow "
 				    "detected (%x of %x bytes)...returning "
-				    "error status.\n",
-				    ha->host_no, b, t, l, resid,
+				    "error status.\n", ha->host_no,
+				    cp->device->channel, cp->device->id,
+				    cp->device->lun, resid,
 				    cp->request_bufflen);
 
 				cp->result = DID_ERROR << 16;
@@ -1052,7 +1051,8 @@ qla2x00_status_entry(scsi_qla_host_t *ha
 	case CS_DATA_OVERRUN:
 		DEBUG2(printk(KERN_INFO
 		    "scsi(%ld:%d:%d): OVERRUN status detected 0x%x-0x%x\n",
-		    ha->host_no, t, l, comp_status, scsi_status));
+		    ha->host_no, cp->device->id, cp->device->lun, comp_status,
+		    scsi_status));
 		DEBUG2(printk(KERN_INFO
 		    "CDB: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
 		    cp->cmnd[0], cp->cmnd[1], cp->cmnd[2], cp->cmnd[3],
@@ -1060,8 +1060,7 @@ qla2x00_status_entry(scsi_qla_host_t *ha
 		DEBUG2(printk(KERN_INFO
 		    "PID=0x%lx req=0x%x xtra=0x%x -- returning DID_ERROR "
 		    "status!\n",
-		    cp->serial_number, cp->request_bufflen,
-		    le32_to_cpu(pkt->residual_length)));
+		    cp->serial_number, cp->request_bufflen, resid_len));
 
 		cp->result = DID_ERROR << 16;
 		break;
@@ -1078,7 +1077,8 @@ qla2x00_status_entry(scsi_qla_host_t *ha
 		 */
 		DEBUG2(printk("scsi(%ld:%d:%d): status_entry: Port Down "
 		    "pid=%ld, compl status=0x%x, port state=0x%x\n",
-		    ha->host_no, t, l, cp->serial_number, comp_status,
+		    ha->host_no, cp->device->id, cp->device->lun,
+		    cp->serial_number, comp_status,
 		    atomic_read(&fcport->state)));
 
 		cp->result = DID_BUS_BUSY << 16;
@@ -1096,7 +1096,7 @@ qla2x00_status_entry(scsi_qla_host_t *ha
 		break;
 
 	case CS_ABORTED:
-		/* 
+		/*
 		 * hv2.19.12 - DID_ABORT does not retry the request if we
 		 * aborted this request then abort otherwise it must be a
 		 * reset.
@@ -1109,17 +1109,25 @@ qla2x00_status_entry(scsi_qla_host_t *ha
 		break;
 
 	case CS_TIMEOUT:
+		cp->result = DID_BUS_BUSY << 16;
+
+		if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) {
+			DEBUG2(printk(KERN_INFO
+			    "scsi(%ld:%d:%d:%d): TIMEOUT status detected "
+			    "0x%x-0x%x\n", ha->host_no, cp->device->channel,
+			    cp->device->id, cp->device->lun, comp_status,
+			    scsi_status));
+			break;
+		}
 		DEBUG2(printk(KERN_INFO
 		    "scsi(%ld:%d:%d:%d): TIMEOUT status detected 0x%x-0x%x "
-		    "sflags=%x.\n", ha->host_no, b, t, l, comp_status,
-		    scsi_status, le16_to_cpu(pkt->status_flags)));
+		    "sflags=%x.\n", ha->host_no, cp->device->channel,
+		    cp->device->id, cp->device->lun, comp_status, scsi_status,
+		    le16_to_cpu(sts->status_flags)));
 
-		cp->result = DID_BUS_BUSY << 16;
-
-		/* Check to see if logout occurred */
-		if ((le16_to_cpu(pkt->status_flags) & SF_LOGOUT_SENT)) {
+		/* Check to see if logout occurred. */
+		if ((le16_to_cpu(sts->status_flags) & SF_LOGOUT_SENT))
 			qla2x00_mark_device_lost(ha, fcport, 1);
-		}
 		break;
 
 	case CS_QUEUE_FULL:
@@ -1129,14 +1137,13 @@ qla2x00_status_entry(scsi_qla_host_t *ha
 
 		/* SCSI Mid-Layer handles device queue full */
 
-		cp->result = DID_OK << 16 | lscsi_status; 
+		cp->result = DID_OK << 16 | lscsi_status;
 
 		break;
 
 	default:
 		DEBUG3(printk("scsi(%ld): Error detected (unknown status) "
-		    "0x%x-0x%x.\n",
-		    ha->host_no, comp_status, scsi_status));
+		    "0x%x-0x%x.\n", ha->host_no, comp_status, scsi_status));
 		qla_printk(KERN_INFO, ha,
 		    "Unknown status detected 0x%x-0x%x.\n",
 		    comp_status, scsi_status);
@@ -1171,7 +1178,7 @@ qla2x00_status_cont_entry(scsi_qla_host_
 			    "sp=%p sp->state:%d\n", __func__, sp, sp->state));
 			qla_printk(KERN_INFO, ha,
 			    "cmd is NULL: already returned to OS (sp=%p)\n",
-			    sp); 
+			    sp);
 
 			ha->status_srb = NULL;
 			return;
@@ -1184,6 +1191,8 @@ qla2x00_status_cont_entry(scsi_qla_host_
 		}
 
 		/* Move sense data. */
+		if (IS_QLA24XX(ha) || IS_QLA25XX(ha))
+			host_to_fcp_swap(pkt->data, sizeof(pkt->data));
 		memcpy(sp->request_sense_ptr, pkt->data, sense_sz);
 		DEBUG5(qla2x00_dump_buffer(sp->request_sense_ptr, sense_sz));
 
@@ -1204,7 +1213,7 @@ qla2x00_status_cont_entry(scsi_qla_host_
  * @pkt: Entry pointer
  */
 static void
-qla2x00_error_entry(scsi_qla_host_t *ha, sts_entry_t *pkt) 
+qla2x00_error_entry(scsi_qla_host_t *ha, sts_entry_t *pkt)
 {
 	srb_t *sp;
 
@@ -1214,7 +1223,7 @@ qla2x00_error_entry(scsi_qla_host_t *ha,
 	else if (pkt->entry_status & RF_INV_E_COUNT)
 		qla_printk(KERN_ERR, ha, "%s: Invalid Entry Count\n", __func__);
 	else if (pkt->entry_status & RF_INV_E_PARAM)
-		qla_printk(KERN_ERR, ha, 
+		qla_printk(KERN_ERR, ha,
 		    "%s: Invalid Entry Parameter\n", __func__);
 	else if (pkt->entry_status & RF_INV_E_TYPE)
 		qla_printk(KERN_ERR, ha, "%s: Invalid Entry Type\n", __func__);
@@ -1233,8 +1242,7 @@ qla2x00_error_entry(scsi_qla_host_t *ha,
 	if (sp) {
 		/* Free outstanding command slot. */
 		ha->outstanding_cmds[pkt->handle] = NULL;
-		if (ha->actthreads)
-			ha->actthreads--;
+
 		/* Bad payload or header */
 		if (pkt->entry_status &
 		    (RF_INV_E_ORDER | RF_INV_E_COUNT |
@@ -1247,15 +1255,15 @@ qla2x00_error_entry(scsi_qla_host_t *ha,
 		}
 		qla2x00_sp_compl(ha, sp);
 
-	} else if (pkt->entry_type == COMMAND_A64_TYPE ||
-	    pkt->entry_type == COMMAND_TYPE) {
+	} else if (pkt->entry_type == COMMAND_A64_TYPE || pkt->entry_type ==
+	    COMMAND_TYPE || pkt->entry_type == COMMAND_TYPE_7) {
 		DEBUG2(printk("scsi(%ld): Error entry - invalid handle\n",
 		    ha->host_no));
 		qla_printk(KERN_WARNING, ha,
 		    "Error entry - invalid handle\n");
 
 		set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
-		if (ha->dpc_wait && !ha->dpc_active) 
+		if (ha->dpc_wait && !ha->dpc_active)
 			up(ha->dpc_wait);
 	}
 }
@@ -1266,7 +1274,7 @@ qla2x00_error_entry(scsi_qla_host_t *ha,
  * @index: Response queue out pointer
  */
 static void
-qla2x00_ms_entry(scsi_qla_host_t *ha, ms_iocb_entry_t *pkt) 
+qla2x00_ms_entry(scsi_qla_host_t *ha, ms_iocb_entry_t *pkt)
 {
 	srb_t          *sp;
 
@@ -1296,3 +1304,229 @@ qla2x00_ms_entry(scsi_qla_host_t *ha, ms
 
 	qla2x00_sp_compl(ha, sp);
 }
+
+
+/**
+ * qla24xx_mbx_completion() - Process mailbox command completions.
+ * @ha: SCSI driver HA context
+ * @mb0: Mailbox0 register
+ */
+static void
+qla24xx_mbx_completion(scsi_qla_host_t *ha, uint16_t mb0)
+{
+	uint16_t	cnt;
+	uint16_t __iomem *wptr;
+	struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
+
+	/* Load return mailbox registers. */
+	ha->flags.mbox_int = 1;
+	ha->mailbox_out[0] = mb0;
+	wptr = (uint16_t __iomem *)&reg->mailbox1;
+
+	for (cnt = 1; cnt < ha->mbx_count; cnt++) {
+		ha->mailbox_out[cnt] = RD_REG_WORD(wptr);
+		wptr++;
+	}
+
+	if (ha->mcp) {
+		DEBUG3(printk("%s(%ld): Got mailbox completion. cmd=%x.\n",
+		    __func__, ha->host_no, ha->mcp->mb[0]));
+	} else {
+		DEBUG2_3(printk("%s(%ld): MBX pointer ERROR!\n",
+		    __func__, ha->host_no));
+	}
+}
+
+/**
+ * qla24xx_process_response_queue() - Process response queue entries.
+ * @ha: SCSI driver HA context
+ */
+void
+qla24xx_process_response_queue(struct scsi_qla_host *ha)
+{
+	struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
+	struct sts_entry_24xx *pkt;
+
+	if (!ha->flags.online)
+		return;
+
+	while (ha->response_ring_ptr->signature != RESPONSE_PROCESSED) {
+		pkt = (struct sts_entry_24xx *)ha->response_ring_ptr;
+
+		ha->rsp_ring_index++;
+		if (ha->rsp_ring_index == ha->response_q_length) {
+			ha->rsp_ring_index = 0;
+			ha->response_ring_ptr = ha->response_ring;
+		} else {
+			ha->response_ring_ptr++;
+		}
+
+		if (pkt->entry_status != 0) {
+			DEBUG3(printk(KERN_INFO
+			    "scsi(%ld): Process error entry.\n", ha->host_no));
+
+			qla2x00_error_entry(ha, (sts_entry_t *) pkt);
+			((response_t *)pkt)->signature = RESPONSE_PROCESSED;
+			wmb();
+			continue;
+		}
+
+		switch (pkt->entry_type) {
+		case STATUS_TYPE:
+			qla2x00_status_entry(ha, pkt);
+			break;
+		case STATUS_CONT_TYPE:
+			qla2x00_status_cont_entry(ha, (sts_cont_entry_t *)pkt);
+			break;
+		case MS_IOCB_TYPE:
+			qla24xx_ms_entry(ha, (struct ct_entry_24xx *)pkt);
+			break;
+		default:
+			/* Type Not Supported. */
+			DEBUG4(printk(KERN_WARNING
+			    "scsi(%ld): Received unknown response pkt type %x "
+			    "entry status=%x.\n",
+			    ha->host_no, pkt->entry_type, pkt->entry_status));
+			break;
+		}
+		((response_t *)pkt)->signature = RESPONSE_PROCESSED;
+		wmb();
+	}
+
+	/* Adjust ring index */
+	WRT_REG_DWORD(&reg->rsp_q_out, ha->rsp_ring_index);
+}
+
+/**
+ * qla24xx_intr_handler() - Process interrupts for the ISP23xx and ISP63xx.
+ * @irq:
+ * @dev_id: SCSI driver HA context
+ * @regs:
+ *
+ * Called by system whenever the host adapter generates an interrupt.
+ *
+ * Returns handled flag.
+ */
+irqreturn_t
+qla24xx_intr_handler(int irq, void *dev_id, struct pt_regs *regs)
+{
+	scsi_qla_host_t	*ha;
+	struct device_reg_24xx __iomem *reg;
+	int		status;
+	unsigned long	flags;
+	unsigned long	iter;
+	uint32_t	stat;
+	uint32_t	hccr;
+	uint16_t	mb[4];
+
+	ha = (scsi_qla_host_t *) dev_id;
+	if (!ha) {
+		printk(KERN_INFO
+		    "%s(): NULL host pointer\n", __func__);
+		return IRQ_NONE;
+	}
+
+	reg = &ha->iobase->isp24;
+	status = 0;
+
+	spin_lock_irqsave(&ha->hardware_lock, flags);
+	for (iter = 50; iter--; ) {
+		stat = RD_REG_DWORD(&reg->host_status);
+		if (stat & HSRX_RISC_PAUSED) {
+			hccr = RD_REG_DWORD(&reg->hccr);
+
+			qla_printk(KERN_INFO, ha, "RISC paused -- HCCR=%x, "
+			    "Dumping firmware!\n", hccr);
+			qla24xx_fw_dump(ha, 1);
+
+			set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
+			break;
+		} else if ((stat & HSRX_RISC_INT) == 0)
+			break;
+
+		switch (stat & 0xff) {
+		case 0x1:
+		case 0x2:
+		case 0x10:
+		case 0x11:
+			qla24xx_mbx_completion(ha, MSW(stat));
+			status |= MBX_INTERRUPT;
+
+			break;
+		case 0x12:
+			mb[0] = MSW(stat);
+			mb[1] = RD_REG_WORD(&reg->mailbox1);
+			mb[2] = RD_REG_WORD(&reg->mailbox2);
+			mb[3] = RD_REG_WORD(&reg->mailbox3);
+			qla2x00_async_event(ha, mb);
+			break;
+		case 0x13:
+			qla24xx_process_response_queue(ha);
+			break;
+		default:
+			DEBUG2(printk("scsi(%ld): Unrecognized interrupt type "
+			    "(%d).\n",
+			    ha->host_no, stat & 0xff));
+			break;
+		}
+		WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_INT);
+		RD_REG_DWORD_RELAXED(&reg->hccr);
+	}
+	spin_unlock_irqrestore(&ha->hardware_lock, flags);
+
+	if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) &&
+	    (status & MBX_INTERRUPT) && ha->flags.mbox_int) {
+		spin_lock_irqsave(&ha->mbx_reg_lock, flags);
+
+		set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
+		up(&ha->mbx_intr_sem);
+
+		spin_unlock_irqrestore(&ha->mbx_reg_lock, flags);
+	}
+
+	return IRQ_HANDLED;
+}
+
+/**
+ * qla24xx_ms_entry() - Process a Management Server entry.
+ * @ha: SCSI driver HA context
+ * @index: Response queue out pointer
+ */
+static void
+qla24xx_ms_entry(scsi_qla_host_t *ha, struct ct_entry_24xx *pkt)
+{
+	srb_t          *sp;
+
+	DEBUG3(printk("%s(%ld): pkt=%p pkthandle=%d.\n",
+	    __func__, ha->host_no, pkt, pkt->handle));
+
+	DEBUG9(printk("%s: ct pkt dump:\n", __func__);)
+	DEBUG9(qla2x00_dump_buffer((void *)pkt, sizeof(struct ct_entry_24xx));)
+
+	/* Validate handle. */
+ 	if (pkt->handle < MAX_OUTSTANDING_COMMANDS)
+ 		sp = ha->outstanding_cmds[pkt->handle];
+	else
+		sp = NULL;
+
+	if (sp == NULL) {
+		DEBUG2(printk("scsi(%ld): MS entry - invalid handle\n",
+		    ha->host_no));
+		DEBUG10(printk("scsi(%ld): MS entry - invalid handle\n",
+		    ha->host_no));
+		qla_printk(KERN_WARNING, ha, "MS entry - invalid handle %d\n",
+		    pkt->handle);
+
+		set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
+		return;
+	}
+
+	CMD_COMPL_STATUS(sp->cmd) = le16_to_cpu(pkt->comp_status);
+	CMD_ENTRY_STATUS(sp->cmd) = pkt->entry_status;
+
+	/* Free outstanding command slot. */
+	ha->outstanding_cmds[pkt->handle] = NULL;
+
+	qla2x00_sp_compl(ha, sp);
+}
+
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -2,7 +2,7 @@
  *                  QLOGIC LINUX SOFTWARE
  *
  * QLogic ISP2x00 device driver for Linux 2.6.x
- * Copyright (C) 2003-2004 QLogic Corporation
+ * Copyright (C) 2003-2005 QLogic Corporation
  * (www.qlogic.com)
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -60,7 +60,7 @@ qla2x00_mailbox_command(scsi_qla_host_t 
 	unsigned long    flags = 0;
 	device_reg_t __iomem *reg = ha->iobase;
 	struct timer_list	tmp_intr_timer;
-	uint8_t		abort_active = test_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags);
+	uint8_t		abort_active;
 	uint8_t		io_lock_on = ha->flags.init_done;
 	uint16_t	command;
 	uint16_t	*iptr;
@@ -71,19 +71,20 @@ qla2x00_mailbox_command(scsi_qla_host_t 
 	unsigned long	wait_time;
 
 	rval = QLA_SUCCESS;
+	abort_active = test_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags);
+
+	DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no);)
 
-	DEBUG11(printk("qla2x00_mailbox_command(%ld): entered.\n",
-	    ha->host_no);)
 	/*
-	 * Wait for active mailbox commands to finish by waiting at most
-	 * tov seconds. This is to serialize actual issuing of mailbox cmds
-	 * during non ISP abort time.
+	 * Wait for active mailbox commands to finish by waiting at most tov
+	 * seconds. This is to serialize actual issuing of mailbox cmds during
+	 * non ISP abort time.
 	 */
 	if (!abort_active) {
 		if (qla2x00_down_timeout(&ha->mbx_cmd_sem, mcp->tov * HZ)) {
 			/* Timeout occurred. Return error. */
-			DEBUG2_3_11(printk("qla2x00_mailbox_command(%ld): cmd "
-			    "access timeout. Exiting.\n", ha->host_no);)
+			DEBUG2_3_11(printk("%s(%ld): cmd access timeout. "
+			    "Exiting.\n", __func__, ha->host_no);)
 			return QLA_FUNCTION_TIMEOUT;
 		}
 	}
@@ -96,13 +97,16 @@ qla2x00_mailbox_command(scsi_qla_host_t 
 	if (!abort_active)
 		spin_lock_irqsave(&ha->mbx_reg_lock, mbx_flags);
 
-	DEBUG11(printk("scsi%d: prepare to issue mbox cmd=0x%x.\n",
-	    (int)ha->host_no, mcp->mb[0]);)
+	DEBUG11(printk("scsi(%ld): prepare to issue mbox cmd=0x%x.\n",
+	    ha->host_no, mcp->mb[0]);)
 
 	spin_lock_irqsave(&ha->hardware_lock, flags);
 
 	/* Load mailbox registers. */
-	optr = (uint16_t __iomem *)MAILBOX_REG(ha, reg, 0);
+	if (IS_QLA24XX(ha) || IS_QLA25XX(ha))
+		optr = (uint16_t __iomem *)&reg->isp24.mailbox0;
+	else
+		optr = (uint16_t __iomem *)MAILBOX_REG(ha, &reg->isp, 0);
 
 	iptr = mcp->mb;
 	command = mcp->mb[0];
@@ -110,7 +114,8 @@ qla2x00_mailbox_command(scsi_qla_host_t 
 
 	for (cnt = 0; cnt < ha->mbx_count; cnt++) {
 		if (IS_QLA2200(ha) && cnt == 8)
-			optr = (uint16_t __iomem *)MAILBOX_REG(ha, reg, 8);
+			optr =
+			    (uint16_t __iomem *)MAILBOX_REG(ha, &reg->isp, 8);
 		if (mboxes & BIT_0)
 			WRT_REG_WORD(optr, *iptr);
 
@@ -120,16 +125,15 @@ qla2x00_mailbox_command(scsi_qla_host_t 
 	}
 
 #if defined(QL_DEBUG_LEVEL_1)
-	printk("qla2x00_mailbox_command: Loaded MBX registers "
-	    "(displayed in bytes) = \n");
+	printk("%s(%ld): Loaded MBX registers (displayed in bytes) = \n",
+	    __func__, ha->host_no);
 	qla2x00_dump_buffer((uint8_t *)mcp->mb, 16);
 	printk("\n");
 	qla2x00_dump_buffer(((uint8_t *)mcp->mb + 0x10), 16);
 	printk("\n");
 	qla2x00_dump_buffer(((uint8_t *)mcp->mb + 0x20), 8);
 	printk("\n");
-	printk("qla2x00_mailbox_command: I/O address = %lx.\n",
-	    (u_long)optr);
+	printk("%s(%ld): I/O address = %p.\n", __func__, ha->host_no, optr);
 	qla2x00_dump_regs(ha);
 #endif
 
@@ -138,17 +142,15 @@ qla2x00_mailbox_command(scsi_qla_host_t 
 	clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
 
 	/* Unlock mbx registers and wait for interrupt */
-
-	DEBUG11(printk("qla2x00_mailbox_command: going to unlock irq & "
-	    "waiting for interrupt. jiffies=%lx.\n", jiffies);)
+	DEBUG11(printk("%s(%ld): going to unlock irq & waiting for interrupt. "
+	    "jiffies=%lx.\n", __func__, ha->host_no, jiffies);)
 
 	/* Wait for mbx cmd completion until timeout */
 
 	if (!abort_active && io_lock_on) {
 		/* sleep on completion semaphore */
-		DEBUG11(printk("qla2x00_mailbox_command(%ld): "
-		    "INTERRUPT MODE. Initializing timer.\n",
-		    ha->host_no);)
+		DEBUG11(printk("%s(%ld): INTERRUPT MODE. Initializing timer.\n",
+		    __func__, ha->host_no);)
 
 		init_timer(&tmp_intr_timer);
 		tmp_intr_timer.data = (unsigned long)&ha->mbx_intr_sem;
@@ -156,16 +158,19 @@ qla2x00_mailbox_command(scsi_qla_host_t 
 		tmp_intr_timer.function =
 		    (void (*)(unsigned long))qla2x00_mbx_sem_timeout;
 
-		DEBUG11(printk("qla2x00_mailbox_command(%ld): "
-		    "Adding timer.\n", ha->host_no);)
+		DEBUG11(printk("%s(%ld): Adding timer.\n", __func__,
+		    ha->host_no);)
 		add_timer(&tmp_intr_timer);
 
-		DEBUG11(printk("qla2x00_mailbox_command: going to "
-		    "unlock & sleep. time=0x%lx.\n", jiffies);)
+		DEBUG11(printk("%s(%ld): going to unlock & sleep. "
+		    "time=0x%lx.\n", __func__, ha->host_no, jiffies);)
 
 		set_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags);
 
-		WRT_REG_WORD(&reg->hccr, HCCR_SET_HOST_INT);
+		if (IS_QLA24XX(ha) || IS_QLA25XX(ha))
+			WRT_REG_DWORD(&reg->isp24.hccr, HCCRX_SET_HOST_INT);
+		else
+			WRT_REG_WORD(&reg->isp.hccr, HCCR_SET_HOST_INT);
 		spin_unlock_irqrestore(&ha->hardware_lock, flags);
 
 		if (!abort_active)
@@ -176,19 +181,20 @@ qla2x00_mailbox_command(scsi_qla_host_t 
 		 */
 		down(&ha->mbx_intr_sem);
 
-		DEBUG11(printk("qla2x00_mailbox_command:"
-		    "waking up."
-		    "time=0x%lx\n", jiffies);)
+		DEBUG11(printk("%s(%ld): waking up. time=0x%lx\n", __func__,
+		    ha->host_no, jiffies);)
 		clear_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags);
 
 		/* delete the timer */
 		del_timer(&tmp_intr_timer);
 	} else {
+		DEBUG3_11(printk("%s(%ld): cmd=%x POLLING MODE.\n", __func__,
+		    ha->host_no, command);)
 
-		DEBUG3_11(printk("qla2x00_mailbox_command(%ld): cmd=%x "
-			"POLLING MODE.\n", ha->host_no, command);)
-
-		WRT_REG_WORD(&reg->hccr, HCCR_SET_HOST_INT);
+		if (IS_QLA24XX(ha) || IS_QLA25XX(ha))
+			WRT_REG_DWORD(&reg->isp24.hccr, HCCRX_SET_HOST_INT);
+		else
+			WRT_REG_WORD(&reg->isp.hccr, HCCR_SET_HOST_INT);
 		spin_unlock_irqrestore(&ha->hardware_lock, flags);
 		if (!abort_active)
 			spin_unlock_irqrestore(&ha->mbx_reg_lock, mbx_flags);
@@ -212,17 +218,15 @@ qla2x00_mailbox_command(scsi_qla_host_t 
 	if (ha->flags.mbox_int) {
 		uint16_t *iptr2;
 
-		DEBUG3_11(printk("qla2x00_mailbox_cmd: cmd %x completed.\n",
-		    command);)
+		DEBUG3_11(printk("%s(%ld): cmd %x completed.\n", __func__,
+		    ha->host_no, command);)
 
 		/* Got interrupt. Clear the flag. */
 		ha->flags.mbox_int = 0;
 		clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
 
-		if (ha->mailbox_out[0] != MBS_COMMAND_COMPLETE) {
-			qla2x00_stats.mboxerr++;
+		if (ha->mailbox_out[0] != MBS_COMMAND_COMPLETE)
 			rval = QLA_FUNCTION_FAILED;
-		}
 
 		/* Load return mailbox registers. */
 		iptr2 = mcp->mb;
@@ -240,17 +244,25 @@ qla2x00_mailbox_command(scsi_qla_host_t 
 
 #if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3) || \
 		defined(QL_DEBUG_LEVEL_11)
-		printk("qla2x00_mailbox_command(%ld): **** MB Command Timeout "
-		    "for cmd %x ****\n", ha->host_no, command);
-		printk("qla2x00_mailbox_command: icontrol=%x jiffies=%lx\n",
-		    RD_REG_WORD(&reg->ictrl), jiffies);
-		printk("qla2x00_mailbox_command: *** mailbox[0] = 0x%x ***\n",
-		    RD_REG_WORD(optr));
+		uint16_t mb0;
+		uint32_t ictrl;
+
+		if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) {
+			mb0 = RD_REG_WORD(&reg->isp24.mailbox0);
+			ictrl = RD_REG_DWORD(&reg->isp24.ictrl);
+		} else {
+			mb0 = RD_MAILBOX_REG(ha, reg->isp, 0);
+			ictrl = RD_REG_WORD(&reg->isp.ictrl);
+		}
+		printk("%s(%ld): **** MB Command Timeout for cmd %x ****\n",
+		    __func__, ha->host_no, command);
+		printk("%s(%ld): icontrol=%x jiffies=%lx\n", __func__,
+		    ha->host_no, ictrl, jiffies);
+		printk("%s(%ld): *** mailbox[0] = 0x%x ***\n", __func__,
+		    ha->host_no, mb0);
 		qla2x00_dump_regs(ha);
 #endif
 
-		qla2x00_stats.mboxtout++;
-		ha->total_mbx_timeout++;
 		rval = QLA_FUNCTION_TIMEOUT;
 	}
 
@@ -263,36 +275,34 @@ qla2x00_mailbox_command(scsi_qla_host_t 
 	ha->mcp = NULL;
 
 	if (!abort_active) {
-		DEBUG11(printk("qla2x00_mailbox_cmd: checking for additional "
-		    "resp interrupt.\n");)
+		DEBUG11(printk("%s(%ld): checking for additional resp "
+		    "interrupt.\n", __func__, ha->host_no);)
 
 		/* polling mode for non isp_abort commands. */
 		qla2x00_poll(ha);
 	}
 
-	if (rval == QLA_FUNCTION_TIMEOUT) {
+	if (rval == QLA_FUNCTION_TIMEOUT &&
+	    mcp->mb[0] != MBC_GEN_SYSTEM_ERROR) {
 		if (!io_lock_on || (mcp->flags & IOCTL_CMD)) {
 			/* not in dpc. schedule it for dpc to take over. */
-			DEBUG(printk("qla2x00_mailbox_command(%ld): timeout "
-			    "schedule isp_abort_needed.\n",
-			    ha->host_no);)
-			DEBUG2_3_11(printk("qla2x00_mailbox_command(%ld): "
-			    "timeout schedule isp_abort_needed.\n",
-			    ha->host_no);)
+			DEBUG(printk("%s(%ld): timeout schedule "
+			    "isp_abort_needed.\n", __func__, ha->host_no);)
+			DEBUG2_3_11(printk("%s(%ld): timeout schedule "
+			    "isp_abort_needed.\n", __func__, ha->host_no);)
 			qla_printk(KERN_WARNING, ha,
 			    "Mailbox command timeout occured. Scheduling ISP "
 			    "abort.\n");
 			set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
-			if (ha->dpc_wait && !ha->dpc_active) 
+			if (ha->dpc_wait && !ha->dpc_active)
 				up(ha->dpc_wait);
 
 		} else if (!abort_active) {
-
 			/* call abort directly since we are in the DPC thread */
-			DEBUG(printk("qla2x00_mailbox_command(%ld): timeout "
-			    "calling abort_isp\n", ha->host_no);)
-			DEBUG2_3_11(printk("qla2x00_mailbox_command(%ld): "
-			    "timeout calling abort_isp\n", ha->host_no);)
+			DEBUG(printk("%s(%ld): timeout calling abort_isp\n",
+			    __func__, ha->host_no);)
+			DEBUG2_3_11(printk("%s(%ld): timeout calling "
+			    "abort_isp\n", __func__, ha->host_no);)
 			qla_printk(KERN_WARNING, ha,
 			    "Mailbox command timeout occured. Issuing ISP "
 			    "abort.\n");
@@ -300,15 +310,14 @@ qla2x00_mailbox_command(scsi_qla_host_t 
 			set_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags);
 			clear_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
 			if (qla2x00_abort_isp(ha)) {
-				/* failed. retry later. */
+				/* Failed. retry later. */
 				set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
 			}
 			clear_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags);
-
-			DEBUG(printk("qla2x00_mailbox_command: finished "
-			    "abort_isp\n");)
-			DEBUG2_3_11(printk("qla2x00_mailbox_command: finished "
-			    "abort_isp\n");)
+			DEBUG(printk("%s(%ld): finished abort_isp\n", __func__,
+			    ha->host_no);)
+			DEBUG2_3_11(printk("%s(%ld): finished abort_isp\n",
+			    __func__, ha->host_no);)
 		}
 	}
 
@@ -317,17 +326,13 @@ qla2x00_mailbox_command(scsi_qla_host_t 
 		up(&ha->mbx_cmd_sem);
 
 	if (rval) {
-		DEBUG2_3_11(printk("qla2x00_mailbox_command(%ld): **** FAILED. "
-		    "mbx0=%x, mbx1=%x, mbx2=%x, cmd=%x ****\n",
-		ha->host_no, mcp->mb[0], mcp->mb[1], mcp->mb[2], command);)
+		DEBUG2_3_11(printk("%s(%ld): **** FAILED. mbx0=%x, mbx1=%x, "
+		    "mbx2=%x, cmd=%x ****\n", __func__, ha->host_no,
+		    mcp->mb[0], mcp->mb[1], mcp->mb[2], command);)
 	} else {
-		DEBUG11(printk("qla2x00_mailbox_command(%ld): done.\n",
-		    ha->host_no);)
+		DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no);)
 	}
 
-	DEBUG11(printk("qla2x00_mailbox_command(%ld): exiting.\n",
-	    ha->host_no);)
-
 	return rval;
 }
 
@@ -422,64 +427,40 @@ qla2x00_load_ram(scsi_qla_host_t *ha, dm
  */
 int
 qla2x00_load_ram_ext(scsi_qla_host_t *ha, dma_addr_t req_dma,
-    uint32_t risc_addr, uint16_t risc_code_size)
+    uint32_t risc_addr, uint32_t risc_code_size)
 {
 	int rval;
 	mbx_cmd_t mc;
 	mbx_cmd_t *mcp = &mc;
-	uint32_t	req_len;
-	dma_addr_t	nml_dma;
-	uint32_t	nml_len;
-	uint32_t	normalized;
 
 	DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no));
 
-	req_len = risc_code_size;
-	nml_dma = 0;
-	nml_len = 0;
-
-	normalized = qla2x00_normalize_dma_addr(&req_dma, &req_len, &nml_dma,
-	    &nml_len);
-
-	/* Load first segment */
 	mcp->mb[0] = MBC_LOAD_RISC_RAM_EXTENDED;
 	mcp->mb[1] = LSW(risc_addr);
 	mcp->mb[2] = MSW(req_dma);
 	mcp->mb[3] = LSW(req_dma);
-	mcp->mb[4] = (uint16_t)req_len;
 	mcp->mb[6] = MSW(MSD(req_dma));
 	mcp->mb[7] = LSW(MSD(req_dma));
 	mcp->mb[8] = MSW(risc_addr);
-	mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
+	mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
+	if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) {
+		mcp->mb[4] = MSW(risc_code_size);
+		mcp->mb[5] = LSW(risc_code_size);
+		mcp->out_mb |= MBX_5|MBX_4;
+	} else {
+		mcp->mb[4] = LSW(risc_code_size);
+		mcp->out_mb |= MBX_4;
+	}
+
 	mcp->in_mb = MBX_0;
 	mcp->tov = 30;
 	mcp->flags = 0;
 	rval = qla2x00_mailbox_command(ha, mcp);
 
-	/* Load second segment - if necessary */
-	if (normalized && (rval == QLA_SUCCESS)) {
-		risc_addr += req_len;
-		mcp->mb[0] = MBC_LOAD_RISC_RAM_EXTENDED;
-		mcp->mb[1] = LSW(risc_addr);
-		mcp->mb[2] = MSW(nml_dma);
-		mcp->mb[3] = LSW(nml_dma);
-		mcp->mb[4] = (uint16_t)nml_len;
-		mcp->mb[6] = MSW(MSD(nml_dma));
-		mcp->mb[7] = LSW(MSD(nml_dma));
-		mcp->mb[8] = MSW(risc_addr);
-		mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
-		mcp->in_mb = MBX_0;
-		mcp->tov = 30;
-		mcp->flags = 0;
-		rval = qla2x00_mailbox_command(ha, mcp);
-	}
-
 	if (rval != QLA_SUCCESS) {
-		/*EMPTY*/
-		DEBUG2_3_11(printk("%s(%ld): failed=%x mb[0]=%x.\n",
-		    __func__, ha->host_no, rval, mcp->mb[0]));
+		DEBUG2_3_11(printk("%s(%ld): failed=%x mb[0]=%x.\n", __func__,
+		    ha->host_no, rval, mcp->mb[0]));
 	} else {
-		/*EMPTY*/
 		DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no));
 	}
 
@@ -488,42 +469,62 @@ qla2x00_load_ram_ext(scsi_qla_host_t *ha
 
 /*
  * qla2x00_execute_fw
- *	Start adapter firmware.
+ *     Start adapter firmware.
  *
  * Input:
- *	ha = adapter block pointer.
- *	TARGET_QUEUE_LOCK must be released.
- *	ADAPTER_STATE_LOCK must be released.
+ *     ha = adapter block pointer.
+ *     TARGET_QUEUE_LOCK must be released.
+ *     ADAPTER_STATE_LOCK must be released.
  *
  * Returns:
- *	qla2x00 local function return status code.
+ *     qla2x00 local function return status code.
  *
  * Context:
- *	Kernel context.
+ *     Kernel context.
  */
 int
-qla2x00_execute_fw(scsi_qla_host_t *ha)
+qla2x00_execute_fw(scsi_qla_host_t *ha, uint32_t risc_addr)
 {
 	int rval;
 	mbx_cmd_t mc;
 	mbx_cmd_t *mcp = &mc;
 
-	DEBUG11(printk("qla2x00_execute_fw(%ld): entered.\n", ha->host_no);)
+	DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no);)
 
 	mcp->mb[0] = MBC_EXECUTE_FIRMWARE;
-	mcp->mb[1] = *ha->brd_info->fw_info[0].fwstart;
-	mcp->out_mb = MBX_1|MBX_0;
-	if (IS_QLA2322(ha) || IS_QLA6322(ha)) {
-		mcp->mb[2] = 0;
-		mcp->out_mb |= MBX_2;
+	mcp->out_mb = MBX_0;
+	mcp->in_mb = MBX_0;
+	if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) {
+		mcp->mb[1] = MSW(risc_addr);
+		mcp->mb[2] = LSW(risc_addr);
+		mcp->mb[3] = 0;
+		mcp->out_mb |= MBX_3|MBX_2|MBX_1;
+		mcp->in_mb |= MBX_1;
+	} else {
+		mcp->mb[1] = LSW(risc_addr);
+		mcp->out_mb |= MBX_1;
+		if (IS_QLA2322(ha) || IS_QLA6322(ha)) {
+			mcp->mb[2] = 0;
+			mcp->out_mb |= MBX_2;
+		}
 	}
 
-	mcp->in_mb = MBX_0;
 	mcp->tov = 30;
 	mcp->flags = 0;
 	rval = qla2x00_mailbox_command(ha, mcp);
 
-	DEBUG11(printk("qla2x00_execute_fw(%ld): done.\n", ha->host_no);)
+	if (rval != QLA_SUCCESS) {
+		DEBUG2_3_11(printk("%s(%ld): failed=%x mb[0]=%x.\n", __func__,
+		    ha->host_no, rval, mcp->mb[0]));
+	} else {
+		if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) {
+			DEBUG11(printk("%s(%ld): done exchanges=%x.\n",
+			    __func__, ha->host_no, mcp->mb[1]);)
+		} else {
+			DEBUG11(printk("%s(%ld): done.\n", __func__,
+			    ha->host_no);)
+		}
+	}
 
 	return rval;
 }
@@ -616,6 +617,7 @@ qla2x00_get_fw_options(scsi_qla_host_t *
 		DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__,
 		    ha->host_no, rval));
 	} else {
+		fwopts[0] = mcp->mb[0];
 		fwopts[1] = mcp->mb[1];
 		fwopts[2] = mcp->mb[2];
 		fwopts[3] = mcp->mb[3];
@@ -654,19 +656,26 @@ qla2x00_set_fw_options(scsi_qla_host_t *
 	mcp->mb[1] = fwopts[1];
 	mcp->mb[2] = fwopts[2];
 	mcp->mb[3] = fwopts[3];
-	mcp->mb[10] = fwopts[10];
-	mcp->mb[11] = fwopts[11];
-	mcp->mb[12] = 0;	/* Undocumented, but used */
-	mcp->out_mb = MBX_12|MBX_11|MBX_10|MBX_3|MBX_2|MBX_1|MBX_0;
+	mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
 	mcp->in_mb = MBX_0;
+	if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) {
+		mcp->in_mb |= MBX_1;
+	} else {
+		mcp->mb[10] = fwopts[10];
+		mcp->mb[11] = fwopts[11];
+		mcp->mb[12] = 0;	/* Undocumented, but used */
+		mcp->out_mb |= MBX_12|MBX_11|MBX_10;
+	}
 	mcp->tov = 30;
 	mcp->flags = 0;
 	rval = qla2x00_mailbox_command(ha, mcp);
 
+	fwopts[0] = mcp->mb[0];
+
 	if (rval != QLA_SUCCESS) {
 		/*EMPTY*/
-		DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__,
-		    ha->host_no, rval));
+		DEBUG2_3_11(printk("%s(%ld): failed=%x (%x/%x).\n", __func__,
+		    ha->host_no, rval, mcp->mb[0], mcp->mb[1]));
 	} else {
 		/*EMPTY*/
 		DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no));
@@ -751,31 +760,38 @@ qla2x00_mbx_reg_test(scsi_qla_host_t *ha
  *	Kernel context.
  */
 int
-qla2x00_verify_checksum(scsi_qla_host_t *ha)
+qla2x00_verify_checksum(scsi_qla_host_t *ha, uint32_t risc_addr)
 {
 	int rval;
 	mbx_cmd_t mc;
 	mbx_cmd_t *mcp = &mc;
 
-	DEBUG11(printk("qla2x00_verify_checksum(%ld): entered.\n",
-	    ha->host_no);)
+	DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no);)
 
 	mcp->mb[0] = MBC_VERIFY_CHECKSUM;
-	mcp->mb[1] = *ha->brd_info->fw_info[0].fwstart;
-	mcp->out_mb = MBX_1|MBX_0;
-	mcp->in_mb = MBX_2|MBX_0;
+	mcp->out_mb = MBX_0;
+	mcp->in_mb = MBX_0;
+	if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) {
+		mcp->mb[1] = MSW(risc_addr);
+		mcp->mb[2] = LSW(risc_addr);
+		mcp->out_mb |= MBX_2|MBX_1;
+		mcp->in_mb |= MBX_2|MBX_1;
+	} else {
+		mcp->mb[1] = LSW(risc_addr);
+		mcp->out_mb |= MBX_1;
+		mcp->in_mb |= MBX_1;
+	}
+
 	mcp->tov = 30;
 	mcp->flags = 0;
 	rval = qla2x00_mailbox_command(ha, mcp);
 
 	if (rval != QLA_SUCCESS) {
-		/*EMPTY*/
-		DEBUG2_3_11(printk("qla2x00_verify_checksum(%ld): failed=%x.\n",
-		    ha->host_no, rval);)
+		DEBUG2_3_11(printk("%s(%ld): failed=%x chk sum=%x.\n", __func__,
+		    ha->host_no, rval, (IS_QLA24XX(ha) || IS_QLA25XX(ha) ?
+		    (mcp->mb[2] << 16) | mcp->mb[1]: mcp->mb[1]));)
 	} else {
-		/*EMPTY*/
-		DEBUG11(printk("qla2x00_verify_checksum(%ld): done.\n",
-		    ha->host_no);)
+		DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no);)
 	}
 
 	return rval;
@@ -821,12 +837,16 @@ qla2x00_issue_iocb(scsi_qla_host_t *ha, 
 
 	if (rval != QLA_SUCCESS) {
 		/*EMPTY*/
-		DEBUG(printk("qla2x00_issue_iocb(%ld): failed rval 0x%x",
-		    ha->host_no,rval);)
-		DEBUG2(printk("qla2x00_issue_iocb(%ld): failed rval 0x%x",
-		    ha->host_no,rval);)
+		DEBUG(printk("qla2x00_issue_iocb(%ld): failed rval 0x%x\n",
+		    ha->host_no, rval);)
+		DEBUG2(printk("qla2x00_issue_iocb(%ld): failed rval 0x%x\n",
+		    ha->host_no, rval);)
 	} else {
-		/*EMPTY*/
+		sts_entry_t *sts_entry = (sts_entry_t *) buffer;
+
+		/* Mask reserved bits. */
+		sts_entry->entry_status &=
+		    IS_QLA24XX(ha) || IS_QLA25XX(ha) ? RF_MASK_24XX :RF_MASK;
 	}
 
 	return rval;
@@ -922,41 +942,40 @@ qla2x00_abort_target(fc_port_t *fcport)
 	int        rval;
 	mbx_cmd_t  mc;
 	mbx_cmd_t  *mcp = &mc;
+	scsi_qla_host_t *ha;
 
-	DEBUG11(printk("qla2x00_abort_target(%ld): entered.\n",
-	    fcport->ha->host_no);)
-
-	if (fcport == NULL) {
-		/* no target to abort */
+	if (fcport == NULL)
 		return 0;
-	}
 
+	DEBUG11(printk("%s(%ld): entered.\n", __func__, fcport->ha->host_no);)
+
+	ha = fcport->ha;
 	mcp->mb[0] = MBC_ABORT_TARGET;
 	mcp->out_mb = MBX_2|MBX_1|MBX_0;
-	if (HAS_EXTENDED_IDS(fcport->ha)) {
+	if (HAS_EXTENDED_IDS(ha)) {
 		mcp->mb[1] = fcport->loop_id;
 		mcp->mb[10] = 0;
 		mcp->out_mb |= MBX_10;
 	} else {
 		mcp->mb[1] = fcport->loop_id << 8;
 	}
-	mcp->mb[2] = fcport->ha->loop_reset_delay;
+	mcp->mb[2] = ha->loop_reset_delay;
 
 	mcp->in_mb = MBX_0;
 	mcp->tov = 30;
 	mcp->flags = 0;
-	rval = qla2x00_mailbox_command(fcport->ha, mcp);
+	rval = qla2x00_mailbox_command(ha, mcp);
 
 	/* Issue marker command. */
-	fcport->ha->marker_needed = 1;
+	ha->marker_needed = 1;
 
 	if (rval != QLA_SUCCESS) {
 		DEBUG2_3_11(printk("qla2x00_abort_target(%ld): failed=%x.\n",
-		    fcport->ha->host_no, rval);)
+		    ha->host_no, rval);)
 	} else {
 		/*EMPTY*/
 		DEBUG11(printk("qla2x00_abort_target(%ld): done.\n",
-		    fcport->ha->host_no);)
+		    ha->host_no);)
 	}
 
 	return rval;
@@ -1206,82 +1225,117 @@ qla2x00_get_port_database(scsi_qla_host_
 	mbx_cmd_t mc;
 	mbx_cmd_t *mcp = &mc;
 	port_database_t *pd;
+	struct port_database_24xx *pd24;
 	dma_addr_t pd_dma;
 
-	DEBUG11(printk("qla2x00_get_port_database(%ld): entered.\n",
-	    ha->host_no);)
+	DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no);)
 
-	pd = dma_pool_alloc(ha->s_dma_pool, GFP_ATOMIC, &pd_dma);
+	pd24 = NULL;
+	pd = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &pd_dma);
 	if (pd  == NULL) {
-		DEBUG2_3_11(printk("qla2x00_get_port_database(%ld): **** "
-		    "Mem Alloc Failed ****", ha->host_no);)
+		DEBUG2_3(printk("%s(%ld): failed to allocate Port Database "
+		    "structure.\n", __func__, ha->host_no));
 		return QLA_MEMORY_ALLOC_FAILED;
 	}
-	memset(pd, 0, PORT_DATABASE_SIZE);
+	memset(pd, 0, max(PORT_DATABASE_SIZE, PORT_DATABASE_24XX_SIZE));
 
-	if (opt != 0)
+	mcp->mb[0] = MBC_GET_PORT_DATABASE;
+	if (opt != 0 && !IS_QLA24XX(ha) && !IS_QLA25XX(ha))
 		mcp->mb[0] = MBC_ENHANCED_GET_PORT_DATABASE;
-	else
-		mcp->mb[0] = MBC_GET_PORT_DATABASE;
-	mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
-	if (HAS_EXTENDED_IDS(ha)) {
-		mcp->mb[1] = fcport->loop_id;
-		mcp->mb[10] = opt;
-		mcp->out_mb |= MBX_10;
-	} else {
-		mcp->mb[1] = fcport->loop_id << 8 | opt;
-	}
 	mcp->mb[2] = MSW(pd_dma);
 	mcp->mb[3] = LSW(pd_dma);
 	mcp->mb[6] = MSW(MSD(pd_dma));
 	mcp->mb[7] = LSW(MSD(pd_dma));
-
+	mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
 	mcp->in_mb = MBX_0;
-	mcp->buf_size = PORT_DATABASE_SIZE;
+	if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) {
+		mcp->mb[1] = fcport->loop_id;
+		mcp->mb[10] = opt;
+		mcp->out_mb |= MBX_10|MBX_1;
+		mcp->in_mb |= MBX_1;
+	} else if (HAS_EXTENDED_IDS(ha)) {
+		mcp->mb[1] = fcport->loop_id;
+		mcp->mb[10] = opt;
+		mcp->out_mb |= MBX_10|MBX_1;
+	} else {
+		mcp->mb[1] = fcport->loop_id << 8 | opt;
+		mcp->out_mb |= MBX_1;
+	}
+	mcp->buf_size = (IS_QLA24XX(ha) || IS_QLA25XX(ha) ?
+	    PORT_DATABASE_24XX_SIZE : PORT_DATABASE_SIZE);
 	mcp->flags = MBX_DMA_IN;
 	mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
 	rval = qla2x00_mailbox_command(ha, mcp);
 	if (rval != QLA_SUCCESS)
 		goto gpd_error_out;
 
-	/* Check for logged in state. */
-	if (pd->master_state != PD_STATE_PORT_LOGGED_IN &&
-	    pd->slave_state != PD_STATE_PORT_LOGGED_IN) {
-		rval = QLA_FUNCTION_FAILED;
-		goto gpd_error_out;
-	}
+	if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) {
+		pd24 = (struct port_database_24xx *) pd;
 
-	/* Names are little-endian. */
-	memcpy(fcport->node_name, pd->node_name, WWN_SIZE);
-	memcpy(fcport->port_name, pd->port_name, WWN_SIZE);
-
-	/* Get port_id of device. */
-	fcport->d_id.b.al_pa = pd->port_id[2];
-	fcport->d_id.b.area = pd->port_id[3];
-	fcport->d_id.b.domain = pd->port_id[0];
-	fcport->d_id.b.rsvd_1 = 0;
-
-	/* Check for device require authentication. */
-	pd->common_features & BIT_5 ? (fcport->flags |= FCF_AUTH_REQ) :
-	    (fcport->flags &= ~FCF_AUTH_REQ);
-
-	/* If not target must be initiator or unknown type. */
-	if ((pd->prli_svc_param_word_3[0] & BIT_4) == 0)
-		fcport->port_type = FCT_INITIATOR;
-	else
-		fcport->port_type = FCT_TARGET;
+		/* Check for logged in state. */
+		if (pd24->current_login_state != PDS_PRLI_COMPLETE &&
+		    pd24->last_login_state != PDS_PRLI_COMPLETE) {
+			DEBUG2(printk("%s(%ld): Unable to verify "
+			    "login-state (%x/%x) for loop_id %x\n",
+			    __func__, ha->host_no,
+			    pd24->current_login_state,
+			    pd24->last_login_state, fcport->loop_id));
+			rval = QLA_FUNCTION_FAILED;
+			goto gpd_error_out;
+		}
+
+		/* Names are little-endian. */
+		memcpy(fcport->node_name, pd24->node_name, WWN_SIZE);
+		memcpy(fcport->port_name, pd24->port_name, WWN_SIZE);
+
+		/* Get port_id of device. */
+		fcport->d_id.b.domain = pd24->port_id[0];
+		fcport->d_id.b.area = pd24->port_id[1];
+		fcport->d_id.b.al_pa = pd24->port_id[2];
+		fcport->d_id.b.rsvd_1 = 0;
+
+		/* If not target must be initiator or unknown type. */
+		if ((pd24->prli_svc_param_word_3[0] & BIT_4) == 0)
+			fcport->port_type = FCT_INITIATOR;
+		else
+			fcport->port_type = FCT_TARGET;
+	} else {
+		/* Check for logged in state. */
+		if (pd->master_state != PD_STATE_PORT_LOGGED_IN &&
+		    pd->slave_state != PD_STATE_PORT_LOGGED_IN) {
+			rval = QLA_FUNCTION_FAILED;
+			goto gpd_error_out;
+		}
+
+		/* Names are little-endian. */
+		memcpy(fcport->node_name, pd->node_name, WWN_SIZE);
+		memcpy(fcport->port_name, pd->port_name, WWN_SIZE);
+
+		/* Get port_id of device. */
+		fcport->d_id.b.domain = pd->port_id[0];
+		fcport->d_id.b.area = pd->port_id[3];
+		fcport->d_id.b.al_pa = pd->port_id[2];
+		fcport->d_id.b.rsvd_1 = 0;
+
+		/* Check for device require authentication. */
+		pd->common_features & BIT_5 ? (fcport->flags |= FCF_AUTH_REQ) :
+		    (fcport->flags &= ~FCF_AUTH_REQ);
+
+		/* If not target must be initiator or unknown type. */
+		if ((pd->prli_svc_param_word_3[0] & BIT_4) == 0)
+			fcport->port_type = FCT_INITIATOR;
+		else
+			fcport->port_type = FCT_TARGET;
+	}
 
 gpd_error_out:
 	dma_pool_free(ha->s_dma_pool, pd, pd_dma);
 
 	if (rval != QLA_SUCCESS) {
-		/*EMPTY*/
-		DEBUG2_3_11(printk("qla2x00_get_port_database(%ld): "
-		    "failed=%x.\n", ha->host_no, rval);)
+		DEBUG2_3_11(printk("%s(%ld): failed=%x mb[0]=%x mb[1]=%x.\n",
+		    __func__, ha->host_no, rval, mcp->mb[0], mcp->mb[1]));
 	} else {
-		/*EMPTY*/
-		DEBUG11(printk("qla2x00_get_port_database(%ld): done.\n",
-		    ha->host_no);)
+		DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no));
 	}
 
 	return rval;
@@ -1426,21 +1480,27 @@ qla2x00_lip_reset(scsi_qla_host_t *ha)
 	mbx_cmd_t mc;
 	mbx_cmd_t *mcp = &mc;
 
-	DEBUG11(printk("qla2x00_lip_reset(%ld): entered.\n",
-	    ha->host_no);)
+	DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no);)
 
-	mcp->mb[0] = MBC_LIP_RESET;
-	mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
-	if (HAS_EXTENDED_IDS(ha)) {
-		mcp->mb[1] = 0x00ff;
-		mcp->mb[10] = 0;
-		mcp->out_mb |= MBX_10;
-	} else {
-		mcp->mb[1] = 0xff00;
+	if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) {
+		mcp->mb[0] = MBC_LIP_FULL_LOGIN;
+		mcp->mb[1] = BIT_0;
+		mcp->mb[2] = 0xff;
+		mcp->mb[3] = 0;
+		mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
+	} else {
+		mcp->mb[0] = MBC_LIP_RESET;
+		mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
+		if (HAS_EXTENDED_IDS(ha)) {
+			mcp->mb[1] = 0x00ff;
+			mcp->mb[10] = 0;
+			mcp->out_mb |= MBX_10;
+		} else {
+			mcp->mb[1] = 0xff00;
+		}
+		mcp->mb[2] = ha->loop_reset_delay;
+		mcp->mb[3] = 0;
 	}
-	mcp->mb[2] = ha->loop_reset_delay;
-	mcp->mb[3] = 0;
-
 	mcp->in_mb = MBX_0;
 	mcp->tov = 30;
 	mcp->flags = 0;
@@ -1448,11 +1508,11 @@ qla2x00_lip_reset(scsi_qla_host_t *ha)
 
 	if (rval != QLA_SUCCESS) {
 		/*EMPTY*/
-		DEBUG2_3_11(printk("qla2x00_lip_reset(%ld): failed=%x.\n",
-		    ha->host_no, rval);)
+		DEBUG2_3_11(printk("%s(%ld): failed=%x.\n",
+		    __func__, ha->host_no, rval);)
 	} else {
 		/*EMPTY*/
-		DEBUG11(printk("qla2x00_lip_reset(%ld): done.\n", ha->host_no);)
+		DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no);)
 	}
 
 	return rval;
@@ -1517,6 +1577,97 @@ qla2x00_send_sns(scsi_qla_host_t *ha, dm
 	return rval;
 }
 
+int
+qla24xx_login_fabric(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t domain,
+    uint8_t area, uint8_t al_pa, uint16_t *mb, uint8_t opt)
+{
+	int		rval;
+
+	struct logio_entry_24xx *lg;
+	dma_addr_t	lg_dma;
+	uint32_t	iop[2];
+
+	DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no);)
+
+	lg = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &lg_dma);
+	if (lg == NULL) {
+		DEBUG2_3(printk("%s(%ld): failed to allocate Login IOCB.\n",
+		    __func__, ha->host_no));
+		return QLA_MEMORY_ALLOC_FAILED;
+	}
+	memset(lg, 0, sizeof(struct logio_entry_24xx));
+
+	lg->entry_type = LOGINOUT_PORT_IOCB_TYPE;
+	lg->entry_count = 1;
+	lg->nport_handle = cpu_to_le16(loop_id);
+	lg->control_flags = __constant_cpu_to_le16(LCF_COMMAND_PLOGI);
+	if (opt & BIT_0)
+		lg->control_flags |= __constant_cpu_to_le16(LCF_COND_PLOGI);
+	lg->port_id[0] = al_pa;
+	lg->port_id[1] = area;
+	lg->port_id[2] = domain;
+	rval = qla2x00_issue_iocb(ha, lg, lg_dma, 0);
+	if (rval != QLA_SUCCESS) {
+		DEBUG2_3_11(printk("%s(%ld): failed to issue Login IOCB "
+		    "(%x).\n", __func__, ha->host_no, rval);)
+	} else if (lg->entry_status != 0) {
+		DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB "
+		    "-- error status (%x).\n", __func__, ha->host_no,
+		    lg->entry_status));
+		rval = QLA_FUNCTION_FAILED;
+	} else if (lg->comp_status != __constant_cpu_to_le16(CS_COMPLETE)) {
+		iop[0] = le32_to_cpu(lg->io_parameter[0]);
+		iop[1] = le32_to_cpu(lg->io_parameter[1]);
+
+		DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB "
+		    "-- completion status (%x)  ioparam=%x/%x.\n", __func__,
+		    ha->host_no, le16_to_cpu(lg->comp_status), iop[0],
+		    iop[1]));
+
+		switch (iop[0]) {
+		case LSC_SCODE_PORTID_USED:
+			mb[0] = MBS_PORT_ID_USED;
+			mb[1] = LSW(iop[1]);
+			break;
+		case LSC_SCODE_NPORT_USED:
+			mb[0] = MBS_LOOP_ID_USED;
+			break;
+		case LSC_SCODE_NOLINK:
+		case LSC_SCODE_NOIOCB:
+		case LSC_SCODE_NOXCB:
+		case LSC_SCODE_CMD_FAILED:
+		case LSC_SCODE_NOFABRIC:
+		case LSC_SCODE_FW_NOT_READY:
+		case LSC_SCODE_NOT_LOGGED_IN:
+		case LSC_SCODE_NOPCB:
+		case LSC_SCODE_ELS_REJECT:
+		case LSC_SCODE_CMD_PARAM_ERR:
+		case LSC_SCODE_NONPORT:
+		case LSC_SCODE_LOGGED_IN:
+		case LSC_SCODE_NOFLOGI_ACC:
+		default:
+			mb[0] = MBS_COMMAND_ERROR;
+			break;
+		}
+	} else {
+		DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no);)
+
+		iop[0] = le32_to_cpu(lg->io_parameter[0]);
+
+		mb[0] = MBS_COMMAND_COMPLETE;
+		mb[1] = 0;
+		if (iop[0] & BIT_4) {
+			if (iop[0] & BIT_8)
+				mb[1] |= BIT_1;
+		} else
+			mb[1] = BIT_0;
+	}
+
+	dma_pool_free(ha->s_dma_pool, lg, lg_dma);
+
+	return rval;
+}
+
 /*
  * qla2x00_login_fabric
  *	Issue login fabric port mailbox command.
@@ -1602,18 +1753,18 @@ qla2x00_login_fabric(scsi_qla_host_t *ha
 /*
  * qla2x00_login_local_device
  *           Issue login loop port mailbox command.
- *    
+ *
  * Input:
  *           ha = adapter block pointer.
  *           loop_id = device loop ID.
  *           opt = command options.
- *          
+ *
  * Returns:
  *            Return status code.
- *             
+ *
  * Context:
  *            Kernel context.
- *             
+ *
  */
 int
 qla2x00_login_local_device(scsi_qla_host_t *ha, uint16_t loop_id,
@@ -1669,6 +1820,57 @@ qla2x00_login_local_device(scsi_qla_host
 	return (rval);
 }
 
+int
+qla24xx_fabric_logout(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t domain,
+    uint8_t area, uint8_t al_pa)
+{
+	int		rval;
+	struct logio_entry_24xx *lg;
+	dma_addr_t	lg_dma;
+
+	DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no);)
+
+	lg = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &lg_dma);
+	if (lg == NULL) {
+		DEBUG2_3(printk("%s(%ld): failed to allocate Logout IOCB.\n",
+		    __func__, ha->host_no));
+		return QLA_MEMORY_ALLOC_FAILED;
+	}
+	memset(lg, 0, sizeof(struct logio_entry_24xx));
+
+	lg->entry_type = LOGINOUT_PORT_IOCB_TYPE;
+	lg->entry_count = 1;
+	lg->nport_handle = cpu_to_le16(loop_id);
+	lg->control_flags =
+	    __constant_cpu_to_le16(LCF_COMMAND_LOGO|LCF_EXPL_LOGO);
+	lg->port_id[0] = al_pa;
+	lg->port_id[1] = area;
+	lg->port_id[2] = domain;
+	rval = qla2x00_issue_iocb(ha, lg, lg_dma, 0);
+	if (rval != QLA_SUCCESS) {
+		DEBUG2_3_11(printk("%s(%ld): failed to issue Logout IOCB "
+		    "(%x).\n", __func__, ha->host_no, rval);)
+	} else if (lg->entry_status != 0) {
+		DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB "
+		    "-- error status (%x).\n", __func__, ha->host_no,
+		    lg->entry_status));
+		rval = QLA_FUNCTION_FAILED;
+	} else if (lg->comp_status != __constant_cpu_to_le16(CS_COMPLETE)) {
+		DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB "
+		    "-- completion status (%x)  ioparam=%x/%x.\n", __func__,
+		    ha->host_no, le16_to_cpu(lg->comp_status),
+		    le32_to_cpu(lg->io_parameter[0]),
+		    le32_to_cpu(lg->io_parameter[1]));)
+	} else {
+		/*EMPTY*/
+		DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no);)
+	}
+
+	dma_pool_free(ha->s_dma_pool, lg, lg_dma);
+
+	return rval;
+}
+
 /*
  * qla2x00_fabric_logout
  *	Issue logout fabric port mailbox command.
@@ -1686,7 +1888,8 @@ qla2x00_login_local_device(scsi_qla_host
  *	Kernel context.
  */
 int
-qla2x00_fabric_logout(scsi_qla_host_t *ha, uint16_t loop_id)
+qla2x00_fabric_logout(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t domain,
+    uint8_t area, uint8_t al_pa)
 {
 	int rval;
 	mbx_cmd_t mc;
@@ -1750,7 +1953,7 @@ qla2x00_full_login_lip(scsi_qla_host_t *
 
 	mcp->mb[0] = MBC_LIP_FULL_LOGIN;
 	mcp->mb[1] = 0;
-	mcp->mb[2] = 0;
+	mcp->mb[2] = 0xff;
 	mcp->mb[3] = 0;
 	mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
 	mcp->in_mb = MBX_0;
@@ -1761,7 +1964,7 @@ qla2x00_full_login_lip(scsi_qla_host_t *
 	if (rval != QLA_SUCCESS) {
 		/*EMPTY*/
 		DEBUG2_3_11(printk("qla2x00_full_login_lip(%ld): failed=%x.\n",
-		    ha->instance, rval);)
+		    ha->host_no, rval);)
 	} else {
 		/*EMPTY*/
 		DEBUG11(printk("qla2x00_full_login_lip(%ld): done.\n",
@@ -1798,11 +2001,20 @@ qla2x00_get_id_list(scsi_qla_host_t *ha,
 		return QLA_FUNCTION_FAILED;
 
 	mcp->mb[0] = MBC_GET_ID_LIST;
-	mcp->mb[1] = MSW(id_list_dma);
-	mcp->mb[2] = LSW(id_list_dma);
-	mcp->mb[3] = MSW(MSD(id_list_dma));
-	mcp->mb[6] = LSW(MSD(id_list_dma));
-	mcp->out_mb = MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
+	mcp->out_mb = MBX_0;
+	if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) {
+		mcp->mb[2] = MSW(id_list_dma);
+		mcp->mb[3] = LSW(id_list_dma);
+		mcp->mb[6] = MSW(MSD(id_list_dma));
+		mcp->mb[7] = LSW(MSD(id_list_dma));
+		mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2;
+	} else {
+		mcp->mb[1] = MSW(id_list_dma);
+		mcp->mb[2] = LSW(id_list_dma);
+		mcp->mb[3] = MSW(MSD(id_list_dma));
+		mcp->mb[6] = LSW(MSD(id_list_dma));
+		mcp->out_mb |= MBX_6|MBX_3|MBX_2|MBX_1;
+	}
 	mcp->in_mb = MBX_1|MBX_0;
 	mcp->tov = 30;
 	mcp->flags = 0;
@@ -1858,7 +2070,7 @@ qla2x00_get_resource_cnts(scsi_qla_host_
 	} else {
 		DEBUG11(printk("%s(%ld): done. mb1=%x mb2=%x mb3=%x mb6=%x "
 		    "mb7=%x mb10=%x.\n", __func__, ha->host_no,
-		    mcp->mb[1], mcp->mb[2], mcp->mb[3], mcp->mb[6], mcp->mb[7], 
+		    mcp->mb[1], mcp->mb[2], mcp->mb[3], mcp->mb[6], mcp->mb[7],
 		    mcp->mb[10]));
 
 		if (cur_xchg_cnt)
@@ -1938,4 +2150,318 @@ qla2x00_get_fcal_position_map(scsi_qla_h
 
 	return rval;
 }
+
+uint8_t
+qla24xx_get_isp_stats(scsi_qla_host_t *ha, uint32_t *dwbuf, uint32_t dwords,
+    uint16_t *status)
+{
+	int rval;
+	mbx_cmd_t mc;
+	mbx_cmd_t *mcp = &mc;
+	uint32_t *sbuf, *siter;
+	dma_addr_t sbuf_dma;
+
+	DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no);)
+
+	if (dwords > (DMA_POOL_SIZE / 4)) {
+		DEBUG2_3_11(printk("%s(%ld): Unabled to retrieve %d DWORDs "
+		    "(max %d).\n", __func__, ha->host_no, dwords,
+		    DMA_POOL_SIZE / 4));
+		return BIT_0;
+	}
+	sbuf = dma_pool_alloc(ha->s_dma_pool, GFP_ATOMIC, &sbuf_dma);
+	if (sbuf == NULL) {
+		DEBUG2_3_11(printk("%s(%ld): Failed to allocate memory.\n",
+		    __func__, ha->host_no));
+		return BIT_0;
+	}
+	memset(sbuf, 0, DMA_POOL_SIZE);
+
+	mcp->mb[0] = MBC_GET_LINK_PRIV_STATS;
+	mcp->mb[2] = MSW(sbuf_dma);
+	mcp->mb[3] = LSW(sbuf_dma);
+	mcp->mb[6] = MSW(MSD(sbuf_dma));
+	mcp->mb[7] = LSW(MSD(sbuf_dma));
+	mcp->mb[8] = dwords;
+	mcp->mb[10] = 0;
+	mcp->out_mb = MBX_10|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
+	mcp->in_mb = MBX_2|MBX_1|MBX_0;
+	mcp->tov = 30;
+	mcp->flags = IOCTL_CMD;
+	rval = qla2x00_mailbox_command(ha, mcp);
+
+	if (rval == QLA_SUCCESS) {
+		if (mcp->mb[0] != MBS_COMMAND_COMPLETE) {
+			DEBUG2_3_11(printk("%s(%ld): cmd failed. mbx0=%x.\n",
+			    __func__, ha->host_no, mcp->mb[0]));
+			status[0] = mcp->mb[0];
+			rval = BIT_1;
+		} else {
+			/* Copy over data -- firmware data is LE. */
+			siter = sbuf;
+			while (dwords--)
+				*dwbuf++ = le32_to_cpu(*siter++);
+		}
+	} else {
+		/* Failed. */
+		DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__,
+		    ha->host_no, rval));
+		rval = BIT_1;
+	}
+
+	dma_pool_free(ha->s_dma_pool, sbuf, sbuf_dma);
+
+	return rval;
+}
 #endif
+
+int
+qla24xx_abort_command(scsi_qla_host_t *ha, srb_t *sp)
+{
+	int		rval;
+	fc_port_t	*fcport;
+	unsigned long   flags = 0;
+
+	struct abort_entry_24xx *abt;
+	dma_addr_t	abt_dma;
+	uint32_t	handle;
+
+	DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no);)
+
+	fcport = sp->fcport;
+	if (atomic_read(&ha->loop_state) == LOOP_DOWN ||
+	    atomic_read(&fcport->state) == FCS_DEVICE_LOST) {
+		return QLA_FUNCTION_FAILED;
+	}
+
+	spin_lock_irqsave(&ha->hardware_lock, flags);
+	for (handle = 1; handle < MAX_OUTSTANDING_COMMANDS; handle++) {
+		if (ha->outstanding_cmds[handle] == sp)
+			break;
+	}
+	spin_unlock_irqrestore(&ha->hardware_lock, flags);
+	if (handle == MAX_OUTSTANDING_COMMANDS) {
+		/* Command not found. */
+		return QLA_FUNCTION_FAILED;
+	}
+
+	abt = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &abt_dma);
+	if (abt == NULL) {
+		DEBUG2_3(printk("%s(%ld): failed to allocate Abort IOCB.\n",
+		    __func__, ha->host_no));
+		return QLA_MEMORY_ALLOC_FAILED;
+	}
+	memset(abt, 0, sizeof(struct abort_entry_24xx));
+
+	abt->entry_type = ABORT_IOCB_TYPE;
+	abt->entry_count = 1;
+	abt->nport_handle = cpu_to_le16(fcport->loop_id);
+	abt->handle_to_abort = handle;
+	abt->port_id[0] = fcport->d_id.b.al_pa;
+	abt->port_id[1] = fcport->d_id.b.area;
+	abt->port_id[2] = fcport->d_id.b.domain;
+	rval = qla2x00_issue_iocb(ha, abt, abt_dma, 0);
+	if (rval != QLA_SUCCESS) {
+		DEBUG2_3_11(printk("%s(%ld): failed to issue IOCB (%x).\n",
+		    __func__, ha->host_no, rval);)
+	} else if (abt->entry_status != 0) {
+		DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB "
+		    "-- error status (%x).\n", __func__, ha->host_no,
+		    abt->entry_status));
+		rval = QLA_FUNCTION_FAILED;
+	} else if (abt->nport_handle != __constant_cpu_to_le16(0)) {
+		DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB "
+		    "-- completion status (%x).\n", __func__, ha->host_no,
+		    le16_to_cpu(abt->nport_handle));)
+		rval = QLA_FUNCTION_FAILED;
+	} else {
+		DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no);)
+		sp->flags |= SRB_ABORT_PENDING;
+	}
+
+	dma_pool_free(ha->s_dma_pool, abt, abt_dma);
+
+	return rval;
+}
+
+struct tsk_mgmt_cmd {
+	union {
+		struct tsk_mgmt_entry tsk;
+		struct sts_entry_24xx sts;
+	} p;
+};
+
+int
+qla24xx_abort_target(fc_port_t *fcport)
+{
+	int		rval;
+	struct tsk_mgmt_cmd *tsk;
+	dma_addr_t	tsk_dma;
+	scsi_qla_host_t *ha;
+
+	if (fcport == NULL)
+		return 0;
+
+	DEBUG11(printk("%s(%ld): entered.\n", __func__, fcport->ha->host_no);)
+
+	ha = fcport->ha;
+	tsk = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &tsk_dma);
+	if (tsk == NULL) {
+		DEBUG2_3(printk("%s(%ld): failed to allocate Task Management "
+		    "IOCB.\n", __func__, ha->host_no));
+		return QLA_MEMORY_ALLOC_FAILED;
+	}
+	memset(tsk, 0, sizeof(struct tsk_mgmt_cmd));
+
+	tsk->p.tsk.entry_type = TSK_MGMT_IOCB_TYPE;
+	tsk->p.tsk.entry_count = 1;
+	tsk->p.tsk.nport_handle = cpu_to_le16(fcport->loop_id);
+	tsk->p.tsk.timeout = __constant_cpu_to_le16(25);
+	tsk->p.tsk.control_flags = __constant_cpu_to_le32(TCF_TARGET_RESET);
+	tsk->p.tsk.port_id[0] = fcport->d_id.b.al_pa;
+	tsk->p.tsk.port_id[1] = fcport->d_id.b.area;
+	tsk->p.tsk.port_id[2] = fcport->d_id.b.domain;
+	rval = qla2x00_issue_iocb(ha, tsk, tsk_dma, 0);
+	if (rval != QLA_SUCCESS) {
+		DEBUG2_3_11(printk("%s(%ld): failed to issue Target Reset IOCB "
+		    "(%x).\n", __func__, ha->host_no, rval);)
+		goto atarget_done;
+	} else if (tsk->p.sts.entry_status != 0) {
+		DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB "
+		    "-- error status (%x).\n", __func__, ha->host_no,
+		    tsk->p.sts.entry_status));
+		rval = QLA_FUNCTION_FAILED;
+		goto atarget_done;
+	} else if (tsk->p.sts.comp_status !=
+	    __constant_cpu_to_le16(CS_COMPLETE)) {
+		DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB "
+		    "-- completion status (%x).\n", __func__,
+		    ha->host_no, le16_to_cpu(tsk->p.sts.comp_status));)
+		rval = QLA_FUNCTION_FAILED;
+		goto atarget_done;
+	}
+
+	/* Issue marker IOCB. */
+	rval = qla2x00_marker(ha, fcport->loop_id, 0, MK_SYNC_ID);
+	if (rval != QLA_SUCCESS) {
+		DEBUG2_3_11(printk("%s(%ld): failed to issue Marker IOCB "
+		    "(%x).\n", __func__, ha->host_no, rval);)
+	} else {
+		DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no);)
+	}
+
+atarget_done:
+	dma_pool_free(ha->s_dma_pool, tsk, tsk_dma);
+
+	return rval;
+}
+
+int
+qla2x00_system_error(scsi_qla_host_t *ha)
+{
+	int rval;
+	mbx_cmd_t mc;
+	mbx_cmd_t *mcp = &mc;
+
+	if (!IS_QLA24XX(ha) && !IS_QLA25XX(ha))
+		return QLA_FUNCTION_FAILED;
+
+	DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no));
+
+	mcp->mb[0] = MBC_GEN_SYSTEM_ERROR;
+	mcp->out_mb = MBX_0;
+	mcp->in_mb = MBX_0;
+	mcp->tov = 5;
+	mcp->flags = 0;
+	rval = qla2x00_mailbox_command(ha, mcp);
+
+	if (rval != QLA_SUCCESS) {
+		DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__,
+		    ha->host_no, rval));
+	} else {
+		DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no));
+	}
+
+	return rval;
+}
+
+/**
+ * qla2x00_get_serdes_params() -
+ * @ha: HA context
+ *
+ * Returns
+ */
+int
+qla2x00_get_serdes_params(scsi_qla_host_t *ha, uint16_t *sw_em_1g,
+    uint16_t *sw_em_2g, uint16_t *sw_em_4g)
+{
+	int rval;
+	mbx_cmd_t mc;
+	mbx_cmd_t *mcp = &mc;
+
+	DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no));
+
+	mcp->mb[0] = MBC_SERDES_PARAMS;
+	mcp->mb[1] = 0;
+	mcp->out_mb = MBX_1|MBX_0;
+	mcp->in_mb = MBX_4|MBX_3|MBX_2|MBX_0;
+	mcp->tov = 30;
+	mcp->flags = 0;
+	rval = qla2x00_mailbox_command(ha, mcp);
+
+	if (rval != QLA_SUCCESS) {
+		/*EMPTY*/
+		DEBUG2_3_11(printk("%s(%ld): failed=%x (%x).\n", __func__,
+		    ha->host_no, rval, mcp->mb[0]));
+	} else {
+		DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no));
+
+		if (sw_em_1g)
+			*sw_em_1g = mcp->mb[2];
+		if (sw_em_2g)
+			*sw_em_2g = mcp->mb[3];
+		if (sw_em_4g)
+			*sw_em_4g = mcp->mb[4];
+	}
+
+	return rval;
+}
+
+/**
+ * qla2x00_set_serdes_params() -
+ * @ha: HA context
+ *
+ * Returns
+ */
+int
+qla2x00_set_serdes_params(scsi_qla_host_t *ha, uint16_t sw_em_1g,
+    uint16_t sw_em_2g, uint16_t sw_em_4g)
+{
+	int rval;
+	mbx_cmd_t mc;
+	mbx_cmd_t *mcp = &mc;
+
+	DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no));
+
+	mcp->mb[0] = MBC_SERDES_PARAMS;
+	mcp->mb[1] = BIT_0;
+	mcp->mb[2] = sw_em_1g;
+	mcp->mb[3] = sw_em_2g;
+	mcp->mb[4] = sw_em_4g;
+	mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
+	mcp->in_mb = MBX_0;
+	mcp->tov = 30;
+	mcp->flags = 0;
+	rval = qla2x00_mailbox_command(ha, mcp);
+
+	if (rval != QLA_SUCCESS) {
+		/*EMPTY*/
+		DEBUG2_3_11(printk("%s(%ld): failed=%x (%x).\n", __func__,
+		    ha->host_no, rval, mcp->mb[0]));
+	} else {
+		/*EMPTY*/
+		DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no));
+	}
+
+	return rval;
+}
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -2,7 +2,7 @@
  *                  QLOGIC LINUX SOFTWARE
  *
  * QLogic ISP2x00 device driver for Linux 2.6.x
- * Copyright (C) 2003-2004 QLogic Corporation
+ * Copyright (C) 2003-2005 QLogic Corporation
  * (www.qlogic.com)
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -36,27 +36,12 @@ char qla2x00_version_str[40];
 /*
  * SRB allocation cache
  */
-char srb_cachep_name[16];
-kmem_cache_t *srb_cachep;
-
-/*
- * Stats for all adpaters.
- */
-struct _qla2x00stats qla2x00_stats;
+static kmem_cache_t *srb_cachep;
 
 /*
  * Ioctl related information.
  */
-int num_hosts;
-int apiHBAInstance;
-
-/*
- * Module parameter information and variables
- */
-int ql2xmaxqdepth;
-module_param(ql2xmaxqdepth, int, S_IRUGO|S_IWUSR);
-MODULE_PARM_DESC(ql2xmaxqdepth,
-		"Maximum queue depth to report for target devices.");
+static int num_hosts;
 
 int ql2xlogintimeout = 20;
 module_param(ql2xlogintimeout, int, S_IRUGO|S_IRUSR);
@@ -69,12 +54,6 @@ MODULE_PARM_DESC(qlport_down_retry,
 		"Maximum number of command retries to a port that returns"
 		"a PORT-DOWN status.");
 
-int ql2xretrycount = 20;
-module_param(ql2xretrycount, int, S_IRUGO|S_IWUSR);
-MODULE_PARM_DESC(ql2xretrycount,
-		"Maximum number of mid-layer retries allowed for a command.  "
-		"Default value is 20, ");
-
 int ql2xplogiabsentdevice;
 module_param(ql2xplogiabsentdevice, int, S_IRUGO|S_IWUSR);
 MODULE_PARM_DESC(ql2xplogiabsentdevice,
@@ -85,7 +64,7 @@ MODULE_PARM_DESC(ql2xplogiabsentdevice,
 int ql2xenablezio = 0;
 module_param(ql2xenablezio, int, S_IRUGO|S_IRUSR);
 MODULE_PARM_DESC(ql2xenablezio,
-		"Option to enable ZIO:If 1 then enable it otherwise" 
+		"Option to enable ZIO:If 1 then enable it otherwise"
 		" use the default set in the NVRAM."
 		" Default is 0 : disabled");
 
@@ -95,42 +74,30 @@ MODULE_PARM_DESC(ql2xintrdelaytimer,
 		"ZIO: Waiting time for Firmware before it generates an "
 		"interrupt to the host to notify completion of request.");
 
-int ConfigRequired;
-module_param(ConfigRequired, int, S_IRUGO|S_IRUSR);
-MODULE_PARM_DESC(ConfigRequired,
-		"If 1, then only configured devices passed in through the"
-		"ql2xopts parameter will be presented to the OS");
-
-int Bind = BIND_BY_PORT_NAME;
-module_param(Bind, int, S_IRUGO|S_IRUSR);
-MODULE_PARM_DESC(Bind,
-		"Target persistent binding method: "
-		"0 by Portname (default); 1 by PortID; 2 by Nodename. ");
-
-int ql2xsuspendcount = SUSPEND_COUNT;
-module_param(ql2xsuspendcount, int, S_IRUGO|S_IWUSR);
-MODULE_PARM_DESC(ql2xsuspendcount,
-		"Number of 6-second suspend iterations to perform while a "
-		"target returns a <NOT READY> status.  Default is 10 "
-		"iterations.");
-
 int ql2xloginretrycount = 0;
 module_param(ql2xloginretrycount, int, S_IRUGO|S_IRUSR);
 MODULE_PARM_DESC(ql2xloginretrycount,
 		"Specify an alternate value for the NVRAM login retry count.");
 
+int ql2xfwloadbin;
+module_param(ql2xfwloadbin, int, S_IRUGO|S_IRUSR);
+MODULE_PARM_DESC(ql2xfwloadbin,
+		"Load ISP2xxx firmware image via hotplug.");
+
 static void qla2x00_free_device(scsi_qla_host_t *);
 
 static void qla2x00_config_dma_addressing(scsi_qla_host_t *ha);
 
 /*
- * SCSI host template entry points 
+ * SCSI host template entry points
  */
 static int qla2xxx_slave_configure(struct scsi_device * device);
 static int qla2xxx_slave_alloc(struct scsi_device *);
 static void qla2xxx_slave_destroy(struct scsi_device *);
 static int qla2x00_queuecommand(struct scsi_cmnd *cmd,
 		void (*fn)(struct scsi_cmnd *));
+static int qla24xx_queuecommand(struct scsi_cmnd *cmd,
+		void (*fn)(struct scsi_cmnd *));
 static int qla2xxx_eh_abort(struct scsi_cmnd *);
 static int qla2xxx_eh_device_reset(struct scsi_cmnd *);
 static int qla2xxx_eh_bus_reset(struct scsi_cmnd *);
@@ -164,6 +131,28 @@ static struct scsi_host_template qla2x00
 	.max_sectors		= 0xFFFF,
 };
 
+static struct scsi_host_template qla24xx_driver_template = {
+	.module			= THIS_MODULE,
+	.name			= "qla2xxx",
+	.queuecommand		= qla24xx_queuecommand,
+
+	.eh_abort_handler	= qla2xxx_eh_abort,
+	.eh_device_reset_handler = qla2xxx_eh_device_reset,
+	.eh_bus_reset_handler	= qla2xxx_eh_bus_reset,
+	.eh_host_reset_handler	= qla2xxx_eh_host_reset,
+
+	.slave_configure	= qla2xxx_slave_configure,
+
+	.slave_alloc		= qla2xxx_slave_alloc,
+	.slave_destroy		= qla2xxx_slave_destroy,
+	.this_id		= -1,
+	.cmd_per_lun		= 3,
+	.use_clustering		= ENABLE_CLUSTERING,
+	.sg_tablesize		= SG_ALL,
+
+	.max_sectors		= 0xFFFF,
+};
+
 static struct scsi_transport_template *qla2xxx_transport_template = NULL;
 
 /* TODO Convert to inlines
@@ -211,14 +200,13 @@ static uint8_t qla2x00_mem_alloc(scsi_ql
 static void qla2x00_mem_free(scsi_qla_host_t *ha);
 static int qla2x00_allocate_sp_pool( scsi_qla_host_t *ha);
 static void qla2x00_free_sp_pool(scsi_qla_host_t *ha);
-static srb_t *qla2x00_get_new_sp(scsi_qla_host_t *);
 static void qla2x00_sp_free_dma(scsi_qla_host_t *, srb_t *);
 void qla2x00_sp_compl(scsi_qla_host_t *ha, srb_t *);
 
 /* -------------------------------------------------------------------------- */
 
 static char *
-qla2x00_get_pci_info_str(struct scsi_qla_host *ha, char *str)
+qla2x00_pci_info_str(struct scsi_qla_host *ha, char *str)
 {
 	static char *pci_bus_modes[] = {
 		"33", "66", "100", "133",
@@ -240,11 +228,59 @@ qla2x00_get_pci_info_str(struct scsi_qla
 	return (str);
 }
 
+static char *
+qla24xx_pci_info_str(struct scsi_qla_host *ha, char *str)
+{
+	static char *pci_bus_modes[] = { "33", "66", "100", "133", };
+	uint32_t pci_bus;
+	int pcie_reg;
+
+	pcie_reg = pci_find_capability(ha->pdev, PCI_CAP_ID_EXP);
+	if (pcie_reg) {
+		char lwstr[6];
+		uint16_t pcie_lstat, lspeed, lwidth;
+
+		pcie_reg += 0x12;
+		pci_read_config_word(ha->pdev, pcie_reg, &pcie_lstat);
+		lspeed = pcie_lstat & (BIT_0 | BIT_1 | BIT_2 | BIT_3);
+		lwidth = (pcie_lstat &
+		    (BIT_4 | BIT_5 | BIT_6 | BIT_7 | BIT_8 | BIT_9)) >> 4;
+
+		strcpy(str, "PCIe (");
+		if (lspeed == 1)
+			strcat(str, "2.5Gb/s ");
+		else
+			strcat(str, "<unknown> ");
+		snprintf(lwstr, sizeof(lwstr), "x%d)", lwidth);
+		strcat(str, lwstr);
+
+		return str;
+	}
+
+	strcpy(str, "PCI");
+	pci_bus = (ha->pci_attr & CSRX_PCIX_BUS_MODE_MASK) >> 8;
+	if (pci_bus == 0 || pci_bus == 8) {
+		strcat(str, " (");
+		strcat(str, pci_bus_modes[pci_bus >> 3]);
+	} else {
+		strcat(str, "-X ");
+		if (pci_bus & BIT_2)
+			strcat(str, "Mode 2");
+		else
+			strcat(str, "Mode 1");
+		strcat(str, " (");
+		strcat(str, pci_bus_modes[pci_bus & ~BIT_2]);
+	}
+	strcat(str, " MHz)");
+
+	return str;
+}
+
 char *
-qla2x00_get_fw_version_str(struct scsi_qla_host *ha, char *str)
+qla2x00_fw_version_str(struct scsi_qla_host *ha, char *str)
 {
 	char un_str[10];
-	
+
 	sprintf(str, "%d.%02d.%02d ", ha->fw_major_version,
 	    ha->fw_minor_version,
 	    ha->fw_subminor_version);
@@ -278,25 +314,45 @@ qla2x00_get_fw_version_str(struct scsi_q
 	return (str);
 }
 
-/**************************************************************************
-* qla2x00_queuecommand
-*
-* Description:
-*     Queue a command to the controller.
-*
-* Input:
-*     cmd - pointer to Scsi cmd structure
-*     fn - pointer to Scsi done function
-*
-* Returns:
-*   0 - Always
-*
-* Note:
-* The mid-level driver tries to ensures that queuecommand never gets invoked
-* concurrently with itself or the interrupt handler (although the
-* interrupt handler may call this routine as part of request-completion
-* handling).
-**************************************************************************/
+char *
+qla24xx_fw_version_str(struct scsi_qla_host *ha, char *str)
+{
+	sprintf(str, "%d.%02d.%02d ", ha->fw_major_version,
+	    ha->fw_minor_version,
+	    ha->fw_subminor_version);
+
+	if (ha->fw_attributes & BIT_0)
+		strcat(str, "[Class 2] ");
+	if (ha->fw_attributes & BIT_1)
+		strcat(str, "[IP] ");
+	if (ha->fw_attributes & BIT_2)
+		strcat(str, "[Multi-ID] ");
+	if (ha->fw_attributes & BIT_13)
+		strcat(str, "[Experimental]");
+	return str;
+}
+
+static inline srb_t *
+qla2x00_get_new_sp(scsi_qla_host_t *ha, fc_port_t *fcport,
+    struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
+{
+	srb_t *sp;
+
+	sp = mempool_alloc(ha->srb_mempool, GFP_ATOMIC);
+	if (!sp)
+		return sp;
+
+	atomic_set(&sp->ref_count, 1);
+	sp->ha = ha;
+	sp->fcport = fcport;
+	sp->cmd = cmd;
+	sp->flags = 0;
+	CMD_SP(cmd) = (void *)sp;
+	cmd->scsi_done = done;
+
+	return sp;
+}
+
 static int
 qla2x00_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
 {
@@ -321,19 +377,9 @@ qla2x00_queuecommand(struct scsi_cmnd *c
 
 	spin_unlock_irq(ha->host->host_lock);
 
-	/* Allocate a command packet from the "sp" pool. */
-	if ((sp = qla2x00_get_new_sp(ha)) == NULL) {
+	sp = qla2x00_get_new_sp(ha, fcport, cmd, done);
+	if (!sp)
 		goto qc_host_busy_lock;
-	}
-
-	sp->ha = ha;
-	sp->fcport = fcport;
-	sp->cmd = cmd;
-	sp->flags = 0;
-	sp->err_id = 0;
-
-	CMD_SP(cmd) = (void *)sp;
-	cmd->scsi_done = done;
 
 	rval = qla2x00_start_scsi(sp);
 	if (rval != QLA_SUCCESS)
@@ -355,7 +401,6 @@ qla2x00_queuecommand(struct scsi_cmnd *c
 
 qc_host_busy_free_sp:
 	qla2x00_sp_free_dma(ha, sp);
-	CMD_SP(cmd) = NULL;
 	mempool_free(sp, ha->srb_mempool);
 
 qc_host_busy_lock:
@@ -370,6 +415,60 @@ qc_fail_command:
 	return 0;
 }
 
+
+static int
+qla24xx_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
+{
+	scsi_qla_host_t *ha = to_qla_host(cmd->device->host);
+	fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata;
+	srb_t *sp;
+	int rval;
+
+	if (!fcport) {
+		cmd->result = DID_NO_CONNECT << 16;
+		goto qc24_fail_command;
+	}
+
+	if (atomic_read(&fcport->state) != FCS_ONLINE) {
+		if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD ||
+		    atomic_read(&ha->loop_state) == LOOP_DEAD) {
+			cmd->result = DID_NO_CONNECT << 16;
+			goto qc24_fail_command;
+		}
+		goto qc24_host_busy;
+	}
+
+	spin_unlock_irq(ha->host->host_lock);
+
+	sp = qla2x00_get_new_sp(ha, fcport, cmd, done);
+	if (!sp)
+		goto qc24_host_busy_lock;
+
+	rval = qla24xx_start_scsi(sp);
+	if (rval != QLA_SUCCESS)
+		goto qc24_host_busy_free_sp;
+
+	spin_lock_irq(ha->host->host_lock);
+
+	return 0;
+
+qc24_host_busy_free_sp:
+	qla2x00_sp_free_dma(ha, sp);
+	mempool_free(sp, ha->srb_mempool);
+
+qc24_host_busy_lock:
+	spin_lock_irq(ha->host->host_lock);
+
+qc24_host_busy:
+	return SCSI_MLQUEUE_HOST_BUSY;
+
+qc24_fail_command:
+	done(cmd);
+
+	return 0;
+}
+
+
 /*
  * qla2x00_eh_wait_on_command
  *    Waits for the command to be returned by the Firmware for some
@@ -408,14 +507,14 @@ qla2x00_eh_wait_on_command(scsi_qla_host
 
 /*
  * qla2x00_wait_for_hba_online
- *    Wait till the HBA is online after going through 
+ *    Wait till the HBA is online after going through
  *    <= MAX_RETRIES_OF_ISP_ABORT  or
  *    finally HBA is disabled ie marked offline
  *
  * Input:
  *     ha - pointer to host adapter structure
- * 
- * Note:    
+ *
+ * Note:
  *    Does context switching-Release SPIN_LOCK
  *    (if any) before calling this routine.
  *
@@ -423,13 +522,13 @@ qla2x00_eh_wait_on_command(scsi_qla_host
  *    Success (Adapter is online) : 0
  *    Failed  (Adapter is offline/disabled) : 1
  */
-static int 
+static int
 qla2x00_wait_for_hba_online(scsi_qla_host_t *ha)
 {
-	int 	 return_status;
-	unsigned long wait_online;
+	int		return_status;
+	unsigned long	wait_online;
 
-	wait_online = jiffies + (MAX_LOOP_TIMEOUT * HZ); 
+	wait_online = jiffies + (MAX_LOOP_TIMEOUT * HZ);
 	while (((test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags)) ||
 	    test_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags) ||
 	    test_bit(ISP_ABORT_RETRY, &ha->dpc_flags) ||
@@ -437,8 +536,8 @@ qla2x00_wait_for_hba_online(scsi_qla_hos
 
 		msleep(1000);
 	}
-	if (ha->flags.online) 
-		return_status = QLA_SUCCESS; 
+	if (ha->flags.online)
+		return_status = QLA_SUCCESS;
 	else
 		return_status = QLA_FUNCTION_FAILED;
 
@@ -450,31 +549,30 @@ qla2x00_wait_for_hba_online(scsi_qla_hos
 /*
  * qla2x00_wait_for_loop_ready
  *    Wait for MAX_LOOP_TIMEOUT(5 min) value for loop
- *    to be in LOOP_READY state.	 
+ *    to be in LOOP_READY state.
  * Input:
  *     ha - pointer to host adapter structure
- * 
- * Note:    
+ *
+ * Note:
  *    Does context switching-Release SPIN_LOCK
  *    (if any) before calling this routine.
- *    
+ *
  *
  * Return:
  *    Success (LOOP_READY) : 0
  *    Failed  (LOOP_NOT_READY) : 1
  */
-static inline int 
+static inline int
 qla2x00_wait_for_loop_ready(scsi_qla_host_t *ha)
 {
 	int 	 return_status = QLA_SUCCESS;
 	unsigned long loop_timeout ;
 
 	/* wait for 5 min at the max for loop to be ready */
-	loop_timeout = jiffies + (MAX_LOOP_TIMEOUT * HZ); 
+	loop_timeout = jiffies + (MAX_LOOP_TIMEOUT * HZ);
 
 	while ((!atomic_read(&ha->loop_down_timer) &&
 	    atomic_read(&ha->loop_state) == LOOP_DOWN) ||
-	    test_bit(CFG_ACTIVE, &ha->cfg_flags) ||
 	    atomic_read(&ha->loop_state) != LOOP_READY) {
 		msleep(1000);
 		if (time_after_eq(jiffies, loop_timeout)) {
@@ -482,7 +580,7 @@ qla2x00_wait_for_loop_ready(scsi_qla_hos
 			break;
 		}
 	}
-	return (return_status);	
+	return (return_status);
 }
 
 /**************************************************************************
@@ -519,7 +617,6 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
 	serial = cmd->serial_number;
 
 	/* Check active list for command command. */
-	spin_unlock_irq(ha->host->host_lock);
 	spin_lock_irqsave(&ha->hardware_lock, flags);
 	for (i = 1; i < MAX_OUTSTANDING_COMMANDS; i++) {
 		sp = ha->outstanding_cmds[i];
@@ -536,7 +633,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
 		DEBUG3(qla2x00_print_scsi_cmd(cmd);)
 
 		spin_unlock_irqrestore(&ha->hardware_lock, flags);
-		if (qla2x00_abort_command(ha, sp)) {
+		if (ha->isp_ops.abort_command(ha, sp)) {
 			DEBUG2(printk("%s(%ld): abort_command "
 			    "mbx failed.\n", __func__, ha->host_no));
 		} else {
@@ -553,14 +650,13 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
 	/* Wait for the command to be returned. */
 	if (ret == SUCCESS) {
 		if (qla2x00_eh_wait_on_command(ha, cmd) != QLA_SUCCESS) {
-			qla_printk(KERN_ERR, ha, 
+			qla_printk(KERN_ERR, ha,
 			    "scsi(%ld:%d:%d): Abort handler timed out -- %lx "
 			    "%x.\n", ha->host_no, id, lun, serial, ret);
 		}
 	}
-	spin_lock_irq(ha->host->host_lock);
 
-	qla_printk(KERN_INFO, ha, 
+	qla_printk(KERN_INFO, ha,
 	    "scsi(%ld:%d:%d): Abort command issued -- %lx %x.\n", ha->host_no,
 	    id, lun, serial, ret);
 
@@ -575,7 +671,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
 *
 * Input:
 *    ha - pointer to scsi_qla_host structure.
-*    t  - target 	
+*    t  - target
 * Returns:
 *    Either SUCCESS or FAILED.
 *
@@ -624,7 +720,7 @@ qla2x00_eh_wait_for_pending_target_comma
 *    executing commands.
 *
 *    NOTE: The use of SP is undefined within this context.  Do *NOT*
-*          attempt to use this value, even if you determine it is 
+*          attempt to use this value, even if you determine it is
 *          non-null.
 *
 * Input:
@@ -658,12 +754,8 @@ qla2xxx_eh_device_reset(struct scsi_cmnd
 	qla_printk(KERN_INFO, ha,
 	    "scsi(%ld:%d:%d): DEVICE RESET ISSUED.\n", ha->host_no, id, lun);
 
-	spin_unlock_irq(ha->host->host_lock);
-
-	if (qla2x00_wait_for_hba_online(ha) != QLA_SUCCESS) {
-		spin_lock_irq(ha->host->host_lock);
+	if (qla2x00_wait_for_hba_online(ha) != QLA_SUCCESS)
 		goto eh_dev_reset_done;
-	}
 
 	if (qla2x00_wait_for_loop_ready(ha) == QLA_SUCCESS) {
 		if (qla2x00_device_reset(ha, fcport) == 0)
@@ -672,7 +764,7 @@ qla2xxx_eh_device_reset(struct scsi_cmnd
 #if defined(LOGOUT_AFTER_DEVICE_RESET)
 		if (ret == SUCCESS) {
 			if (fcport->flags & FC_FABRIC_DEVICE) {
-				qla2x00_fabric_logout(ha, fcport->loop_id);
+				ha->isp_ops.fabric_logout(ha, fcport->loop_id);
 				qla2x00_mark_device_lost(ha, fcport);
 			}
 		}
@@ -704,7 +796,7 @@ qla2xxx_eh_device_reset(struct scsi_cmnd
 			    "commands\n", __func__, ha->host_no));
 			qla_printk(KERN_INFO, ha,
 			    "%s: failed while waiting for commands\n",
-			    __func__); 
+			    __func__);
 
 			goto eh_dev_reset_done;
 		}
@@ -714,8 +806,6 @@ qla2xxx_eh_device_reset(struct scsi_cmnd
 	    "scsi(%ld:%d:%d): DEVICE RESET SUCCEEDED.\n", ha->host_no, id, lun);
 
 eh_dev_reset_done:
-	spin_lock_irq(ha->host->host_lock);
-
 	return ret;
 }
 
@@ -805,8 +895,6 @@ qla2xxx_eh_bus_reset(struct scsi_cmnd *c
 	qla_printk(KERN_INFO, ha,
 	    "scsi(%ld:%d:%d): LOOP RESET ISSUED.\n", ha->host_no, id, lun);
 
-	spin_unlock_irq(ha->host->host_lock);
-
 	if (qla2x00_wait_for_hba_online(ha) != QLA_SUCCESS) {
 		DEBUG2(printk("%s failed:board disabled\n",__func__));
 		goto eh_bus_reset_done;
@@ -828,8 +916,6 @@ eh_bus_reset_done:
 	qla_printk(KERN_INFO, ha, "%s: reset %s\n", __func__,
 	    (ret == FAILED) ? "failed" : "succeded");
 
-	spin_lock_irq(ha->host->host_lock);
-
 	return ret;
 }
 
@@ -871,14 +957,12 @@ qla2xxx_eh_host_reset(struct scsi_cmnd *
 	qla_printk(KERN_INFO, ha,
 	    "scsi(%ld:%d:%d): ADAPTER RESET ISSUED.\n", ha->host_no, id, lun);
 
-	spin_unlock_irq(ha->host->host_lock);
-
 	if (qla2x00_wait_for_hba_online(ha) != QLA_SUCCESS)
 		goto eh_host_reset_lock;
 
 	/*
 	 * Fixme-may be dpc thread is active and processing
-	 * loop_resync,so wait a while for it to 
+	 * loop_resync,so wait a while for it to
 	 * be completed and then issue big hammer.Otherwise
 	 * it may cause I/O failure as big hammer marks the
 	 * devices as lost kicking of the port_down_timer
@@ -893,7 +977,7 @@ qla2xxx_eh_host_reset(struct scsi_cmnd *
 
 		if (qla2x00_wait_for_hba_online(ha) != QLA_SUCCESS)
 			goto eh_host_reset_lock;
-	} 
+	}
 	clear_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags);
 
 	/* Waiting for our command in done_queue to be returned to OS.*/
@@ -901,8 +985,6 @@ qla2xxx_eh_host_reset(struct scsi_cmnd *
 		ret = SUCCESS;
 
 eh_host_reset_lock:
-	spin_lock_irq(ha->host->host_lock);
-
 	qla_printk(KERN_INFO, ha, "%s: reset %s\n", __func__,
 	    (ret == FAILED) ? "failed" : "succeded");
 
@@ -941,7 +1023,7 @@ qla2x00_loop_reset(scsi_qla_host_t *ha)
 	}
 
 	if (status == QLA_SUCCESS &&
-		((!ha->flags.enable_target_reset && 
+		((!ha->flags.enable_target_reset &&
 		  !ha->flags.enable_lip_reset) ||
 		ha->flags.enable_lip_full_login)) {
 
@@ -983,32 +1065,18 @@ static int
 qla2x00_device_reset(scsi_qla_host_t *ha, fc_port_t *reset_fcport)
 {
 	/* Abort Target command will clear Reservation */
-	return qla2x00_abort_target(reset_fcport);
+	return ha->isp_ops.abort_target(reset_fcport);
 }
 
 static int
 qla2xxx_slave_alloc(struct scsi_device *sdev)
 {
-	scsi_qla_host_t *ha = to_qla_host(sdev->host);
 	struct fc_rport *rport = starget_to_rport(scsi_target(sdev));
-	fc_port_t *fcport;
-	int found;
 
 	if (!rport)
 		return -ENXIO;
 
-	found = 0;
-	list_for_each_entry(fcport, &ha->fcports, list) {
-		if (rport->port_name ==
-		    be64_to_cpu(*(uint64_t *)fcport->port_name)) {
-			found++;
-			break;
-		}
-	}
-	if (!found)
-		return -ENXIO;
-
-	sdev->hostdata = fcport;
+	sdev->hostdata = rport->dd_data;
 
 	return 0;
 }
@@ -1047,8 +1115,6 @@ qla2x00_config_dma_addressing(scsi_qla_h
 {
 	/* Assume 32bit DMA address */
 	ha->flags.enable_64bit_addressing = 0;
-	ha->calc_request_entries = qla2x00_calc_iocbs_32;
-	ha->build_scsi_iocbs = qla2x00_build_scsi_iocbs_32;
 
 	/*
 	 * Given the two variants pci_set_dma_mask(), allow the compiler to
@@ -1057,12 +1123,12 @@ qla2x00_config_dma_addressing(scsi_qla_h
 	if (sizeof(dma_addr_t) > 4) {
 		if (pci_set_dma_mask(ha->pdev, DMA_64BIT_MASK) == 0) {
 			ha->flags.enable_64bit_addressing = 1;
-			ha->calc_request_entries = qla2x00_calc_iocbs_64;
-			ha->build_scsi_iocbs = qla2x00_build_scsi_iocbs_64;
+			ha->isp_ops.calc_req_entries = qla2x00_calc_iocbs_64;
+			ha->isp_ops.build_iocbs = qla2x00_build_scsi_iocbs_64;
 
 			if (pci_set_consistent_dma_mask(ha->pdev,
 			    DMA_64BIT_MASK)) {
-				qla_printk(KERN_DEBUG, ha, 
+				qla_printk(KERN_DEBUG, ha,
 				    "Failed to set 64 bit PCI consistent mask; "
 				    "using 32 bit.\n");
 				pci_set_consistent_dma_mask(ha->pdev,
@@ -1145,12 +1211,67 @@ iospace_error_exit:
 	return (-ENOMEM);
 }
 
+static void
+qla2x00_enable_intrs(scsi_qla_host_t *ha)
+{
+	unsigned long flags = 0;
+	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
+
+	spin_lock_irqsave(&ha->hardware_lock, flags);
+	ha->interrupts_on = 1;
+	/* enable risc and host interrupts */
+	WRT_REG_WORD(&reg->ictrl, ICR_EN_INT | ICR_EN_RISC);
+	RD_REG_WORD(&reg->ictrl);
+	spin_unlock_irqrestore(&ha->hardware_lock, flags);
+
+}
+
+static void
+qla2x00_disable_intrs(scsi_qla_host_t *ha)
+{
+	unsigned long flags = 0;
+	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
+
+	spin_lock_irqsave(&ha->hardware_lock, flags);
+	ha->interrupts_on = 0;
+	/* disable risc and host interrupts */
+	WRT_REG_WORD(&reg->ictrl, 0);
+	RD_REG_WORD(&reg->ictrl);
+	spin_unlock_irqrestore(&ha->hardware_lock, flags);
+}
+
+static void
+qla24xx_enable_intrs(scsi_qla_host_t *ha)
+{
+	unsigned long flags = 0;
+	struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
+
+	spin_lock_irqsave(&ha->hardware_lock, flags);
+	ha->interrupts_on = 1;
+	WRT_REG_DWORD(&reg->ictrl, ICRX_EN_RISC_INT);
+	RD_REG_DWORD(&reg->ictrl);
+	spin_unlock_irqrestore(&ha->hardware_lock, flags);
+}
+
+static void
+qla24xx_disable_intrs(scsi_qla_host_t *ha)
+{
+	unsigned long flags = 0;
+	struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
+
+	spin_lock_irqsave(&ha->hardware_lock, flags);
+	ha->interrupts_on = 0;
+	WRT_REG_DWORD(&reg->ictrl, 0);
+	RD_REG_DWORD(&reg->ictrl);
+	spin_unlock_irqrestore(&ha->hardware_lock, flags);
+}
+
 /*
  * PCI driver interface
  */
 int qla2x00_probe_one(struct pci_dev *pdev, struct qla_board_info *brd_info)
 {
-	int	ret;
+	int	ret = -ENODEV;
 	device_reg_t __iomem *reg;
 	struct Scsi_Host *host;
 	scsi_qla_host_t *ha;
@@ -1161,10 +1282,10 @@ int qla2x00_probe_one(struct pci_dev *pd
 	fc_port_t *fcport;
 
 	if (pci_enable_device(pdev))
-		return -1;
+		goto probe_out;
 
-	host = scsi_host_alloc(&qla2x00_driver_template,
-	    sizeof(scsi_qla_host_t));
+	host = scsi_host_alloc(brd_info->sht ? brd_info->sht:
+	    &qla2x00_driver_template, sizeof(scsi_qla_host_t));
 	if (host == NULL) {
 		printk(KERN_WARNING
 		    "qla2xxx: Couldn't allocate host from scsi layer!\n");
@@ -1183,51 +1304,102 @@ int qla2x00_probe_one(struct pci_dev *pd
 
 	/* Configure PCI I/O space */
 	ret = qla2x00_iospace_config(ha);
-	if (ret != 0) {
-		goto probe_alloc_failed;
-	}
-
-	/* Sanitize the information from PCI BIOS. */
-	host->irq = pdev->irq;
+	if (ret)
+		goto probe_failed;
 
 	qla_printk(KERN_INFO, ha,
 	    "Found an %s, irq %d, iobase 0x%p\n", ha->brd_info->isp_name,
-	    host->irq, ha->iobase);
+	    pdev->irq, ha->iobase);
 
 	spin_lock_init(&ha->hardware_lock);
 
-	/* 4.23 Initialize /proc/scsi/qla2x00 counters */
-	ha->actthreads = 0;
-	ha->qthreads   = 0;
-	ha->total_isr_cnt = 0;
-	ha->total_isp_aborts = 0;
-	ha->total_lip_cnt = 0;
-	ha->total_dev_errs = 0;
-	ha->total_ios = 0;
-	ha->total_bytes = 0;
-
 	ha->prev_topology = 0;
 	ha->ports = MAX_BUSES;
+	ha->init_cb_size = sizeof(init_cb_t);
 
+	/* Assign ISP specific operations. */
+	ha->isp_ops.pci_config		= qla2100_pci_config;
+	ha->isp_ops.reset_chip		= qla2x00_reset_chip;
+	ha->isp_ops.chip_diag		= qla2x00_chip_diag;
+	ha->isp_ops.config_rings	= qla2x00_config_rings;
+	ha->isp_ops.reset_adapter	= qla2x00_reset_adapter;
+	ha->isp_ops.nvram_config	= qla2x00_nvram_config;
+	ha->isp_ops.update_fw_options	= qla2x00_update_fw_options;
+	ha->isp_ops.load_risc		= qla2x00_load_risc;
+	ha->isp_ops.pci_info_str	= qla2x00_pci_info_str;
+	ha->isp_ops.fw_version_str	= qla2x00_fw_version_str;
+	ha->isp_ops.intr_handler	= qla2100_intr_handler;
+	ha->isp_ops.enable_intrs	= qla2x00_enable_intrs;
+	ha->isp_ops.disable_intrs	= qla2x00_disable_intrs;
+	ha->isp_ops.abort_command	= qla2x00_abort_command;
+	ha->isp_ops.abort_target	= qla2x00_abort_target;
+	ha->isp_ops.fabric_login	= qla2x00_login_fabric;
+	ha->isp_ops.fabric_logout	= qla2x00_fabric_logout;
+	ha->isp_ops.calc_req_entries	= qla2x00_calc_iocbs_32;
+	ha->isp_ops.build_iocbs		= qla2x00_build_scsi_iocbs_32;
+	ha->isp_ops.prep_ms_iocb	= qla2x00_prep_ms_iocb;
+	ha->isp_ops.read_nvram		= qla2x00_read_nvram_data;
+	ha->isp_ops.write_nvram		= qla2x00_write_nvram_data;
+	ha->isp_ops.fw_dump		= qla2100_fw_dump;
+	ha->isp_ops.ascii_fw_dump	= qla2100_ascii_fw_dump;
 	if (IS_QLA2100(ha)) {
-		ha->max_targets = MAX_TARGETS_2100;
+		host->max_id = MAX_TARGETS_2100;
 		ha->mbx_count = MAILBOX_REGISTER_COUNT_2100;
 		ha->request_q_length = REQUEST_ENTRY_CNT_2100;
 		ha->response_q_length = RESPONSE_ENTRY_CNT_2100;
 		ha->last_loop_id = SNS_LAST_LOOP_ID_2100;
 		host->sg_tablesize = 32;
+		ha->gid_list_info_size = 4;
 	} else if (IS_QLA2200(ha)) {
-		ha->max_targets = MAX_TARGETS_2200;
+		host->max_id = MAX_TARGETS_2200;
 		ha->mbx_count = MAILBOX_REGISTER_COUNT;
 		ha->request_q_length = REQUEST_ENTRY_CNT_2200;
 		ha->response_q_length = RESPONSE_ENTRY_CNT_2100;
 		ha->last_loop_id = SNS_LAST_LOOP_ID_2100;
-	} else /*if (IS_QLA2300(ha))*/ {
-		ha->max_targets = MAX_TARGETS_2200;
+		ha->gid_list_info_size = 4;
+	} else if (IS_QLA23XX(ha)) {
+		host->max_id = MAX_TARGETS_2200;
 		ha->mbx_count = MAILBOX_REGISTER_COUNT;
 		ha->request_q_length = REQUEST_ENTRY_CNT_2200;
 		ha->response_q_length = RESPONSE_ENTRY_CNT_2300;
 		ha->last_loop_id = SNS_LAST_LOOP_ID_2300;
+		ha->isp_ops.pci_config = qla2300_pci_config;
+		ha->isp_ops.intr_handler = qla2300_intr_handler;
+		ha->isp_ops.fw_dump = qla2300_fw_dump;
+		ha->isp_ops.ascii_fw_dump = qla2300_ascii_fw_dump;
+		ha->gid_list_info_size = 6;
+	} else if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) {
+		host->max_id = MAX_TARGETS_2200;
+		ha->mbx_count = MAILBOX_REGISTER_COUNT;
+		ha->request_q_length = REQUEST_ENTRY_CNT_24XX;
+		ha->response_q_length = RESPONSE_ENTRY_CNT_2300;
+		ha->last_loop_id = SNS_LAST_LOOP_ID_2300;
+		ha->init_cb_size = sizeof(struct init_cb_24xx);
+		ha->isp_ops.pci_config = qla24xx_pci_config;
+		ha->isp_ops.reset_chip = qla24xx_reset_chip;
+		ha->isp_ops.chip_diag = qla24xx_chip_diag;
+		ha->isp_ops.config_rings = qla24xx_config_rings;
+		ha->isp_ops.reset_adapter = qla24xx_reset_adapter;
+		ha->isp_ops.nvram_config = qla24xx_nvram_config;
+		ha->isp_ops.update_fw_options = qla24xx_update_fw_options;
+		ha->isp_ops.load_risc = qla24xx_load_risc_flash;
+		if (ql2xfwloadbin)
+			ha->isp_ops.load_risc = qla24xx_load_risc_hotplug;
+		ha->isp_ops.pci_info_str = qla24xx_pci_info_str;
+		ha->isp_ops.fw_version_str = qla24xx_fw_version_str;
+		ha->isp_ops.intr_handler = qla24xx_intr_handler;
+		ha->isp_ops.enable_intrs = qla24xx_enable_intrs;
+		ha->isp_ops.disable_intrs = qla24xx_disable_intrs;
+		ha->isp_ops.abort_command = qla24xx_abort_command;
+		ha->isp_ops.abort_target = qla24xx_abort_target;
+		ha->isp_ops.fabric_login = qla24xx_login_fabric;
+		ha->isp_ops.fabric_logout = qla24xx_fabric_logout;
+		ha->isp_ops.prep_ms_iocb = qla24xx_prep_ms_iocb;
+		ha->isp_ops.read_nvram = qla24xx_read_nvram_data;
+		ha->isp_ops.write_nvram = qla24xx_write_nvram_data;
+		ha->isp_ops.fw_dump = qla24xx_fw_dump;
+		ha->isp_ops.ascii_fw_dump = qla24xx_ascii_fw_dump;
+		ha->gid_list_info_size = 8;
 	}
 	host->can_queue = ha->request_q_length + 128;
 
@@ -1258,23 +1430,10 @@ int qla2x00_probe_one(struct pci_dev *pd
 		qla_printk(KERN_WARNING, ha,
 		    "[ERROR] Failed to allocate memory for adapter\n");
 
-		goto probe_alloc_failed;
+		ret = -ENOMEM;
+		goto probe_failed;
 	}
 
-	pci_set_drvdata(pdev, ha);
-	host->this_id = 255;
-	host->cmd_per_lun = 3;
-	host->unique_id = ha->instance;
-	host->max_cmd_len = MAX_CMDSZ;
-	host->max_channel = ha->ports - 1;
-	host->max_id = ha->max_targets;
-	host->max_lun = ha->max_luns;
-	host->transportt = qla2xxx_transport_template;
-	if (scsi_add_host(host, &pdev->dev))
-		goto probe_alloc_failed;
-
-	qla2x00_alloc_sysfs_attr(ha);
-
 	if (qla2x00_initialize_adapter(ha) &&
 	    !(ha->device_flags & DFLG_NO_CABLE)) {
 
@@ -1285,11 +1444,10 @@ int qla2x00_probe_one(struct pci_dev *pd
 		    "Adapter flags %x.\n",
 		    ha->host_no, ha->device_flags));
 
+		ret = -ENODEV;
 		goto probe_failed;
 	}
 
-	qla2x00_init_host_attr(ha);
-
 	/*
 	 * Startup the kernel thread for this host adapter
 	 */
@@ -1299,22 +1457,28 @@ int qla2x00_probe_one(struct pci_dev *pd
 		qla_printk(KERN_WARNING, ha,
 		    "Unable to start DPC thread!\n");
 
+		ret = -ENODEV;
 		goto probe_failed;
 	}
 	wait_for_completion(&ha->dpc_inited);
 
-	if (IS_QLA2100(ha) || IS_QLA2200(ha))
-		ret = request_irq(host->irq, qla2100_intr_handler,
-		    SA_INTERRUPT|SA_SHIRQ, ha->brd_info->drv_name, ha);
-	else
-		ret = request_irq(host->irq, qla2300_intr_handler,
-		    SA_INTERRUPT|SA_SHIRQ, ha->brd_info->drv_name, ha);
-	if (ret != 0) {
+	host->this_id = 255;
+	host->cmd_per_lun = 3;
+	host->unique_id = ha->instance;
+	host->max_cmd_len = MAX_CMDSZ;
+	host->max_channel = ha->ports - 1;
+	host->max_lun = MAX_LUNS;
+	host->transportt = qla2xxx_transport_template;
+
+	ret = request_irq(pdev->irq, ha->isp_ops.intr_handler,
+	    SA_INTERRUPT|SA_SHIRQ, ha->brd_info->drv_name, ha);
+	if (ret) {
 		qla_printk(KERN_WARNING, ha,
 		    "Failed to reserve interrupt %d already in use.\n",
-		    host->irq);
+		    pdev->irq);
 		goto probe_failed;
 	}
+	host->irq = pdev->irq;
 
 	/* Initialized the timer */
 	qla2x00_start_timer(ha, qla2x00_timer, WATCH_INTERVAL);
@@ -1322,30 +1486,33 @@ int qla2x00_probe_one(struct pci_dev *pd
 	DEBUG2(printk("DEBUG: detect hba %ld at address = %p\n",
 	    ha->host_no, ha));
 
-	reg = ha->iobase;
-
-	/* Disable ISP interrupts. */
-	qla2x00_disable_intrs(ha);
+	ha->isp_ops.disable_intrs(ha);
 
-	/* Ensure mailbox registers are free. */
 	spin_lock_irqsave(&ha->hardware_lock, flags);
-	WRT_REG_WORD(&reg->semaphore, 0);
-	WRT_REG_WORD(&reg->hccr, HCCR_CLR_RISC_INT);
-	WRT_REG_WORD(&reg->hccr, HCCR_CLR_HOST_INT);
-
-	/* Enable proper parity */
-	if (!IS_QLA2100(ha) && !IS_QLA2200(ha)) {
-		if (IS_QLA2300(ha))
-			/* SRAM parity */
-			WRT_REG_WORD(&reg->hccr, (HCCR_ENABLE_PARITY + 0x1));
-		else
-			/* SRAM, Instruction RAM and GP RAM parity */
-			WRT_REG_WORD(&reg->hccr, (HCCR_ENABLE_PARITY + 0x7));
+	reg = ha->iobase;
+	if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) {
+		WRT_REG_DWORD(&reg->isp24.hccr, HCCRX_CLR_HOST_INT);
+		WRT_REG_DWORD(&reg->isp24.hccr, HCCRX_CLR_RISC_INT);
+	} else {
+		WRT_REG_WORD(&reg->isp.semaphore, 0);
+		WRT_REG_WORD(&reg->isp.hccr, HCCR_CLR_RISC_INT);
+		WRT_REG_WORD(&reg->isp.hccr, HCCR_CLR_HOST_INT);
+
+		/* Enable proper parity */
+		if (!IS_QLA2100(ha) && !IS_QLA2200(ha)) {
+			if (IS_QLA2300(ha))
+				/* SRAM parity */
+				WRT_REG_WORD(&reg->isp.hccr,
+				    (HCCR_ENABLE_PARITY + 0x1));
+			else
+				/* SRAM, Instruction RAM and GP RAM parity */
+				WRT_REG_WORD(&reg->isp.hccr,
+				    (HCCR_ENABLE_PARITY + 0x7));
+		}
 	}
 	spin_unlock_irqrestore(&ha->hardware_lock, flags);
 
-	/* Enable chip interrupts. */
-	qla2x00_enable_intrs(ha);
+	ha->isp_ops.enable_intrs(ha);
 
 	/* v2.19.5b6 */
 	/*
@@ -1363,17 +1530,26 @@ int qla2x00_probe_one(struct pci_dev *pd
 		msleep(10);
 	}
 
+	pci_set_drvdata(pdev, ha);
 	ha->flags.init_done = 1;
 	num_hosts++;
 
+	ret = scsi_add_host(host, &pdev->dev);
+	if (ret)
+		goto probe_failed;
+
+	qla2x00_alloc_sysfs_attr(ha);
+
+	qla2x00_init_host_attr(ha);
+
 	qla_printk(KERN_INFO, ha, "\n"
 	    " QLogic Fibre Channel HBA Driver: %s\n"
 	    "  QLogic %s - %s\n"
 	    "  %s: %s @ %s hdma%c, host#=%ld, fw=%s\n", qla2x00_version_str,
 	    ha->model_number, ha->model_desc ? ha->model_desc: "",
-	    ha->brd_info->isp_name, qla2x00_get_pci_info_str(ha, pci_info),
-	    pci_name(ha->pdev), ha->flags.enable_64bit_addressing ? '+': '-',
-	    ha->host_no, qla2x00_get_fw_version_str(ha, fw_str));
+	    ha->brd_info->isp_name, ha->isp_ops.pci_info_str(ha, pci_info),
+	    pci_name(pdev), ha->flags.enable_64bit_addressing ? '+': '-',
+	    ha->host_no, ha->isp_ops.fw_version_str(ha, fw_str));
 
 	/* Go with fc_rport registration. */
 	list_for_each_entry(fcport, &ha->fcports, list)
@@ -1384,9 +1560,6 @@ int qla2x00_probe_one(struct pci_dev *pd
 probe_failed:
 	fc_remove_host(ha->host);
 
-	scsi_remove_host(host);
-
-probe_alloc_failed:
 	qla2x00_free_device(ha);
 
 	scsi_host_put(host);
@@ -1394,7 +1567,8 @@ probe_alloc_failed:
 probe_disable_device:
 	pci_disable_device(pdev);
 
-	return -1;
+probe_out:
+	return ret;
 }
 EXPORT_SYMBOL_GPL(qla2x00_probe_one);
 
@@ -1429,7 +1603,7 @@ qla2x00_free_device(scsi_qla_host_t *ha)
 
 	/* turn-off interrupts on the card */
 	if (ha->interrupts_on)
-		qla2x00_disable_intrs(ha);
+		ha->isp_ops.disable_intrs(ha);
 
 	/* Disable timer */
 	if (ha->timer_active)
@@ -1481,7 +1655,7 @@ void qla2x00_mark_device_lost(scsi_qla_h
 {
 	if (atomic_read(&fcport->state) == FCS_ONLINE && fcport->rport)
 		fc_remote_port_block(fcport->rport);
-	/* 
+	/*
 	 * We may need to retry the login, so don't change the state of the
 	 * port but do the retries.
 	 */
@@ -1526,7 +1700,7 @@ void qla2x00_mark_device_lost(scsi_qla_h
  * Context:
  */
 void
-qla2x00_mark_all_devices_lost(scsi_qla_host_t *ha) 
+qla2x00_mark_all_devices_lost(scsi_qla_host_t *ha)
 {
 	fc_port_t *fcport;
 
@@ -1643,7 +1817,7 @@ qla2x00_mem_alloc(scsi_qla_host_t *ha)
 
 			continue;
 		}
-		memset(ha->init_cb, 0, sizeof(init_cb_t));
+		memset(ha->init_cb, 0, ha->init_cb_size);
 
 		/* Get consistent memory allocated for Get Port Database cmd */
 		ha->iodesc_pd = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL,
@@ -1855,10 +2029,13 @@ qla2x00_mem_free(scsi_qla_host_t *ha)
 	if (ha->fw_dump)
 		free_pages((unsigned long)ha->fw_dump, ha->fw_dump_order);
 
-	if (ha->fw_dump_buffer)
-		vfree(ha->fw_dump_buffer);
+	vfree(ha->fw_dump24);
+
+	vfree(ha->fw_dump_buffer);
 
 	ha->fw_dump = NULL;
+	ha->fw_dump24 = NULL;
+	ha->fw_dumped = 0;
 	ha->fw_dump_reading = 0;
 	ha->fw_dump_buffer = NULL;
 }
@@ -1873,11 +2050,11 @@ qla2x00_mem_free(scsi_qla_host_t *ha)
  *
  * Context:
  *      Kernel context.
- * 
+ *
  * Note: Sets the ref_count for non Null sp to one.
  */
 static int
-qla2x00_allocate_sp_pool(scsi_qla_host_t *ha) 
+qla2x00_allocate_sp_pool(scsi_qla_host_t *ha)
 {
 	int      rval;
 
@@ -1893,10 +2070,10 @@ qla2x00_allocate_sp_pool(scsi_qla_host_t
 
 /*
  *  This routine frees all adapter allocated memory.
- *  
+ *
  */
 static void
-qla2x00_free_sp_pool( scsi_qla_host_t *ha) 
+qla2x00_free_sp_pool( scsi_qla_host_t *ha)
 {
 	if (ha->srb_mempool) {
 		mempool_destroy(ha->srb_mempool);
@@ -2018,9 +2195,11 @@ qla2x00_do_dpc(void *data)
 					if (fcport->flags & FCF_FABRIC_DEVICE) {
 						if (fcport->flags &
 						    FCF_TAPE_PRESENT)
-							qla2x00_fabric_logout(
-							    ha,
-							    fcport->loop_id);
+							ha->isp_ops.fabric_logout(
+							    ha, fcport->loop_id,
+							    fcport->d_id.b.domain,
+							    fcport->d_id.b.area,
+							    fcport->d_id.b.al_pa);
 						status = qla2x00_fabric_login(
 						    ha, fcport, &next_loopid);
 					} else
@@ -2033,7 +2212,7 @@ qla2x00_do_dpc(void *data)
 
 						DEBUG(printk("scsi(%ld): port login OK: logged in ID 0x%x\n",
 						    ha->host_no, fcport->loop_id));
-						
+
 						fcport->port_login_retry_count =
 						    ha->port_down_retry_count * PORT_RETRY_TIME;
 						atomic_set(&fcport->state, FCS_ONLINE);
@@ -2064,7 +2243,7 @@ qla2x00_do_dpc(void *data)
 			clear_bit(LOGIN_RETRY_NEEDED, &ha->dpc_flags);
 			DEBUG(printk("scsi(%ld): qla2x00_login_retry()\n",
 			    ha->host_no));
-				
+
 			set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags);
 
 			DEBUG(printk("scsi(%ld): qla2x00_login_retry - end\n",
@@ -2101,7 +2280,7 @@ qla2x00_do_dpc(void *data)
 		}
 
 		if (!ha->interrupts_on)
-			qla2x00_enable_intrs(ha);
+			ha->isp_ops.enable_intrs(ha);
 
 		ha->dpc_active = 0;
 	} /* End of while(1) */
@@ -2125,7 +2304,7 @@ qla2x00_do_dpc(void *data)
 *      ha  = adapter block pointer.
 */
 static void
-qla2x00_rst_aen(scsi_qla_host_t *ha) 
+qla2x00_rst_aen(scsi_qla_host_t *ha)
 {
 	if (ha->flags.online && !ha->flags.reset_active &&
 	    !atomic_read(&ha->loop_down_timer) &&
@@ -2143,25 +2322,6 @@ qla2x00_rst_aen(scsi_qla_host_t *ha) 
 	}
 }
 
-
-/*
- * This routine will allocate SP from the free queue
- * input:
- *        scsi_qla_host_t *
- * output:
- *        srb_t * or NULL
- */
-static srb_t *
-qla2x00_get_new_sp(scsi_qla_host_t *ha)
-{
-	srb_t *sp;
-
-	sp = mempool_alloc(ha->srb_mempool, GFP_ATOMIC);
-	if (sp)
-		atomic_set(&sp->ref_count, 1);
-	return (sp);
-}
-
 static void
 qla2x00_sp_free_dma(scsi_qla_host_t *ha, srb_t *sp)
 {
@@ -2177,6 +2337,7 @@ qla2x00_sp_free_dma(scsi_qla_host_t *ha,
 		}
 		sp->flags &= ~SRB_DMA_VALID;
 	}
+	CMD_SP(cmd) = NULL;
 }
 
 void
@@ -2186,7 +2347,6 @@ qla2x00_sp_compl(scsi_qla_host_t *ha, sr
 
 	qla2x00_sp_free_dma(ha, sp);
 
-	CMD_SP(cmd) = NULL;
 	mempool_free(sp, ha->srb_mempool);
 
 	cmd->scsi_done(cmd);
@@ -2215,7 +2375,7 @@ qla2x00_timer(scsi_qla_host_t *ha)
 	 *
 	 * Whenever, a port is in the LOST state we start decrementing its port
 	 * down timer every second until it reaches zero. Once  it reaches zero
-	 * the port it marked DEAD. 
+	 * the port it marked DEAD.
 	 */
 	t = 0;
 	list_for_each_entry(fcport, &ha->fcports, list) {
@@ -2227,11 +2387,11 @@ qla2x00_timer(scsi_qla_host_t *ha)
 			if (atomic_read(&fcport->port_down_timer) == 0)
 				continue;
 
-			if (atomic_dec_and_test(&fcport->port_down_timer) != 0) 
+			if (atomic_dec_and_test(&fcport->port_down_timer) != 0)
 				atomic_set(&fcport->state, FCS_DEVICE_DEAD);
-			
+
 			DEBUG(printk("scsi(%ld): fcport-%d - port retry count: "
-			    "%d remainning\n",
+			    "%d remaining\n",
 			    ha->host_no,
 			    t, atomic_read(&fcport->port_down_timer)));
 		}
@@ -2251,7 +2411,7 @@ qla2x00_timer(scsi_qla_host_t *ha)
 			    ha->host_no));
 
 			if (!IS_QLA2100(ha) && ha->link_down_timeout)
-				atomic_set(&ha->loop_state, LOOP_DEAD); 
+				atomic_set(&ha->loop_state, LOOP_DEAD);
 
 			/* Schedule an ISP abort to return any tape commands. */
 			spin_lock_irqsave(&ha->hardware_lock, cpu_flags);
@@ -2294,7 +2454,7 @@ qla2x00_timer(scsi_qla_host_t *ha)
 				set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
 			}
 		}
-		DEBUG3(printk("scsi(%ld): Loop Down - seconds remainning %d\n",
+		DEBUG3(printk("scsi(%ld): Loop Down - seconds remaining %d\n",
 		    ha->host_no,
 		    atomic_read(&ha->loop_down_timer)));
 	}
@@ -2331,15 +2491,70 @@ qla2x00_down_timeout(struct semaphore *s
 	return -ETIMEDOUT;
 }
 
+static struct qla_board_info qla_board_tbl[] = {
+	{
+		.drv_name	= "qla2400",
+		.isp_name	= "ISP2422",
+		.fw_fname	= "ql2400_fw.bin",
+		.sht		= &qla24xx_driver_template,
+	},
+	{
+		.drv_name	= "qla2400",
+		.isp_name	= "ISP2432",
+		.fw_fname	= "ql2400_fw.bin",
+		.sht		= &qla24xx_driver_template,
+	},
+};
+
+static struct pci_device_id qla2xxx_pci_tbl[] = {
+	{
+		.vendor		= PCI_VENDOR_ID_QLOGIC,
+		.device		= PCI_DEVICE_ID_QLOGIC_ISP2422,
+		.subvendor	= PCI_ANY_ID,
+		.subdevice	= PCI_ANY_ID,
+		.driver_data	= (unsigned long)&qla_board_tbl[0],
+	},
+	{
+		.vendor		= PCI_VENDOR_ID_QLOGIC,
+		.device		= PCI_DEVICE_ID_QLOGIC_ISP2432,
+		.subvendor	= PCI_ANY_ID,
+		.subdevice	= PCI_ANY_ID,
+		.driver_data	= (unsigned long)&qla_board_tbl[1],
+	},
+	{0, 0},
+};
+MODULE_DEVICE_TABLE(pci, qla2xxx_pci_tbl);
+
+static int __devinit
+qla2xxx_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
+{
+	return qla2x00_probe_one(pdev,
+	    (struct qla_board_info *)id->driver_data);
+}
+
+static void __devexit
+qla2xxx_remove_one(struct pci_dev *pdev)
+{
+	qla2x00_remove_one(pdev);
+}
+
+static struct pci_driver qla2xxx_pci_driver = {
+	.name		= "qla2xxx",
+	.id_table	= qla2xxx_pci_tbl,
+	.probe		= qla2xxx_probe_one,
+	.remove		= __devexit_p(qla2xxx_remove_one),
+};
+
 /**
  * qla2x00_module_init - Module initialization.
  **/
 static int __init
 qla2x00_module_init(void)
 {
+	int ret = 0;
+
 	/* Allocate cache for SRBs. */
-	sprintf(srb_cachep_name, "qla2xxx_srbs");
-	srb_cachep = kmem_cache_create(srb_cachep_name, sizeof(srb_t), 0,
+	srb_cachep = kmem_cache_create("qla2xxx_srbs", sizeof(srb_t), 0,
 	    SLAB_HWCACHE_ALIGN, NULL, NULL);
 	if (srb_cachep == NULL) {
 		printk(KERN_ERR
@@ -2358,7 +2573,12 @@ qla2x00_module_init(void)
 		return -ENODEV;
 
 	printk(KERN_INFO "QLogic Fibre Channel HBA Driver\n");
-	return 0;
+	ret = pci_module_init(&qla2xxx_pci_driver);
+	if (ret) {
+		kmem_cache_destroy(srb_cachep);
+		fc_release_transport(qla2xxx_transport_template);
+	}
+	return ret;
 }
 
 /**
@@ -2367,16 +2587,8 @@ qla2x00_module_init(void)
 static void __exit
 qla2x00_module_exit(void)
 {
-	/* Free SRBs cache. */
-	if (srb_cachep != NULL) {
-		if (kmem_cache_destroy(srb_cachep) != 0) {
-			printk(KERN_ERR
-			    "qla2xxx: Unable to free SRB cache...Memory pools "
-			    "still active?\n");
-		}
-		srb_cachep = NULL;
-	}
-
+	pci_unregister_driver(&qla2xxx_pci_driver);
+	kmem_cache_destroy(srb_cachep);
 	fc_release_transport(qla2xxx_transport_template);
 }
 
diff --git a/drivers/scsi/qla2xxx/qla_rscn.c b/drivers/scsi/qla2xxx/qla_rscn.c
--- a/drivers/scsi/qla2xxx/qla_rscn.c
+++ b/drivers/scsi/qla2xxx/qla_rscn.c
@@ -2,7 +2,7 @@
  *                  QLOGIC LINUX SOFTWARE
  *
  * QLogic ISP2x00 device driver for Linux 2.6.x
- * Copyright (C) 2003-2004 QLogic Corporation
+ * Copyright (C) 2003-2005 QLogic Corporation
  * (www.qlogic.com)
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -82,7 +82,7 @@ static int qla2x00_send_login_iocb(scsi_
 static int qla2x00_send_login_iocb_cb(scsi_qla_host_t *, struct io_descriptor *,
     struct mbx_entry *);
 
-/** 
+/**
  * Mailbox IOCB callback array.
  **/
 static int (*iocb_function_cb_list[LAST_IOCB_CB])
@@ -95,7 +95,7 @@ static int (*iocb_function_cb_list[LAST_
 };
 
 
-/** 
+/**
  * Generic IO descriptor handle routines.
  **/
 
@@ -169,7 +169,7 @@ qla2x00_handle_to_iodesc(scsi_qla_host_t
 }
 
 
-/** 
+/**
  * IO descriptor allocation routines.
  **/
 
@@ -248,7 +248,7 @@ qla2x00_init_io_descriptors(scsi_qla_hos
 }
 
 
-/** 
+/**
  * IO descriptor timer routines.
  **/
 
@@ -299,7 +299,7 @@ qla2x00_add_iodesc_timer(struct io_descr
 	add_timer(&iodesc->timer);
 }
 
-/** 
+/**
  * IO descriptor support routines.
  **/
 
@@ -333,7 +333,7 @@ qla2x00_update_login_fcport(scsi_qla_hos
 }
 
 
-/** 
+/**
  * Mailbox IOCB commands.
  **/
 
@@ -348,7 +348,7 @@ static inline struct mbx_entry *
 qla2x00_get_mbx_iocb_entry(scsi_qla_host_t *ha, uint32_t handle)
 {
 	uint16_t cnt;
-	device_reg_t __iomem *reg = ha->iobase;
+	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
 	struct mbx_entry *mbxentry;
 
 	mbxentry = NULL;
@@ -383,7 +383,7 @@ qla2x00_get_mbx_iocb_entry(scsi_qla_host
  * Returns QLA_SUCCESS if the IOCB was issued.
  */
 static int
-qla2x00_send_abort_iocb(scsi_qla_host_t *ha, struct io_descriptor *iodesc, 
+qla2x00_send_abort_iocb(scsi_qla_host_t *ha, struct io_descriptor *iodesc,
     uint32_t handle_to_abort, int ha_locked)
 {
 	unsigned long flags = 0;
@@ -720,7 +720,7 @@ qla2x00_send_login_iocb_cb(scsi_qla_host
 	/* Only process the last command. */
 	if (remote_fcport->iodesc_idx_sent != iodesc->idx) {
 		DEBUG14(printk("scsi(%ld): Login IOCB -- ignoring, sent to "
-		    "[%02x%02x%02x], expected %x, received %x.\n", 
+		    "[%02x%02x%02x], expected %x, received %x.\n",
 		    ha->host_no, iodesc->d_id.b.domain, iodesc->d_id.b.area,
 		    iodesc->d_id.b.al_pa, remote_fcport->iodesc_idx_sent,
 		    iodesc->idx));
@@ -754,9 +754,9 @@ qla2x00_send_login_iocb_cb(scsi_qla_host
 
 		DEBUG14(printk("scsi(%ld): Login IOCB -- status=%x mb1=%x pn="
 		    "%02x%02x%02x%02x%02x%02x%02x%02x.\n", ha->host_no, status,
-		    mb[1], mbxstat->port_name[0], mbxstat->port_name[1], 
-		    mbxstat->port_name[2], mbxstat->port_name[3], 
-		    mbxstat->port_name[4], mbxstat->port_name[5], 
+		    mb[1], mbxstat->port_name[0], mbxstat->port_name[1],
+		    mbxstat->port_name[2], mbxstat->port_name[3],
+		    mbxstat->port_name[4], mbxstat->port_name[5],
 		    mbxstat->port_name[6], mbxstat->port_name[7]));
 
 		memcpy(remote_fcport->node_name, mbxstat->node_name, WWN_SIZE);
@@ -1052,7 +1052,7 @@ qla2x00_send_login_iocb_cb(scsi_qla_host
 }
 
 
-/** 
+/**
  * IO descriptor processing routines.
  **/
 
@@ -1136,7 +1136,7 @@ qla2x00_handle_port_rscn(scsi_qla_host_t
 		    remote_fcport = rscn_fcport;
 	}
 
-	/* 
+	/*
 	 * If the port is already in our fcport list and online, send an ADISC
 	 * to see if it's still alive.  Issue login if a new fcport or the known
 	 * fcport is currently offline.
@@ -1191,7 +1191,7 @@ qla2x00_handle_port_rscn(scsi_qla_host_t
 			}
 			return (QLA_SUCCESS);
 		}
-		
+
 		/* Send ADISC if the fcport is online */
 		if (atomic_read(&remote_fcport->state) == FCS_ONLINE ||
 		    remote_fcport->iodesc_idx_sent == IODESC_ADISC_NEEDED) {
@@ -1229,7 +1229,7 @@ qla2x00_handle_port_rscn(scsi_qla_host_t
 			 * abort.
 			 */
 			uint32_t handle_to_abort;
-			
+
 			iodesc = &ha->io_descriptors[
 				remote_fcport->iodesc_idx_sent];
 			qla2x00_remove_iodesc_timer(iodesc);
diff --git a/drivers/scsi/qla2xxx/qla_settings.h b/drivers/scsi/qla2xxx/qla_settings.h
--- a/drivers/scsi/qla2xxx/qla_settings.h
+++ b/drivers/scsi/qla2xxx/qla_settings.h
@@ -2,7 +2,7 @@
  *                  QLOGIC LINUX SOFTWARE
  *
  * QLogic ISP2x00 device driver for Linux 2.6.x
- * Copyright (C) 2003-2004 QLogic Corporation
+ * Copyright (C) 2003-2005 QLogic Corporation
  * (www.qlogic.com)
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -22,33 +22,8 @@
  */
 #define DEBUG_QLA2100		0	/* For Debug of qla2x00 */
 
-#define STOP_ON_RESET		0
 #define USE_ABORT_TGT		1	/* Use Abort Target mbx cmd */
 
-#define VSA			0	/* Volume Set Addressing */
-
-/* Failover options */
-#define MAX_RECOVERYTIME	10	/*
-					 * Max suspend time for a lun recovery
-					 * time
-					 */
-#define MAX_FAILBACKTIME	5	/* Max suspend time before fail back */
-
-#define QLA_CMD_TIMER_DELTA	3
-
-/* 
- * When a lun is suspended for the "Not Ready" condition then it will suspend
- * the lun for increments of 6 sec delays.  SUSPEND_COUNT is that count.
- */
-#define SUSPEND_COUNT		10	/* 6 secs * 10 retries = 60 secs */
-
-/*
- * Defines the time in seconds that the driver extends the command timeout to
- * get around the problem where the mid-layer only allows 5 retries for
- * commands that return BUS_BUSY
- */
-#define EXTEND_CMD_TIMEOUT	60
-
 #define MAX_RETRIES_OF_ISP_ABORT	5
 
 /* Max time to wait for the loop to be in LOOP_READY state */
diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c
--- a/drivers/scsi/qla2xxx/qla_sup.c
+++ b/drivers/scsi/qla2xxx/qla_sup.c
@@ -2,7 +2,7 @@
  *                  QLOGIC LINUX SOFTWARE
  *
  * QLogic ISP2x00 device driver for Linux 2.6.x
- * Copyright (C) 2003-2004 QLogic Corporation
+ * Copyright (C) 2003-2005 QLogic Corporation
  * (www.qlogic.com)
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -31,14 +31,14 @@ static void qla2x00_nv_write(scsi_qla_ho
  */
 
 /**
- * qla2x00_lock_nvram_access() - 
+ * qla2x00_lock_nvram_access() -
  * @ha: HA context
  */
 void
 qla2x00_lock_nvram_access(scsi_qla_host_t *ha)
 {
 	uint16_t data;
-	device_reg_t __iomem *reg = ha->iobase;
+	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
 
 	if (!IS_QLA2100(ha) && !IS_QLA2200(ha) && !IS_QLA2300(ha)) {
 		data = RD_REG_WORD(&reg->nvram);
@@ -64,13 +64,13 @@ qla2x00_lock_nvram_access(scsi_qla_host_
 }
 
 /**
- * qla2x00_unlock_nvram_access() - 
+ * qla2x00_unlock_nvram_access() -
  * @ha: HA context
  */
 void
 qla2x00_unlock_nvram_access(scsi_qla_host_t *ha)
 {
-	device_reg_t __iomem *reg = ha->iobase;
+	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
 
 	if (!IS_QLA2100(ha) && !IS_QLA2200(ha) && !IS_QLA2300(ha)) {
 		WRT_REG_WORD(&reg->u.isp2300.host_semaphore, 0);
@@ -79,56 +79,6 @@ qla2x00_unlock_nvram_access(scsi_qla_hos
 }
 
 /**
- * qla2x00_release_nvram_protection() - 
- * @ha: HA context
- */
-void
-qla2x00_release_nvram_protection(scsi_qla_host_t *ha)
-{
-	device_reg_t __iomem *reg;
-	uint32_t word;
-
-	reg = ha->iobase;
-
-	/* Release NVRAM write protection. */
-	if (IS_QLA2322(ha) || IS_QLA6322(ha)) {
-		/* Write enable. */
-		qla2x00_nv_write(ha, NVR_DATA_OUT);
-		qla2x00_nv_write(ha, 0);
-		qla2x00_nv_write(ha, 0);
-		for (word = 0; word < 8; word++)
-			qla2x00_nv_write(ha, NVR_DATA_OUT);
-
-		qla2x00_nv_deselect(ha);
-
-		/* Enable protection register. */
-		qla2x00_nv_write(ha, NVR_PR_ENABLE | NVR_DATA_OUT);
-		qla2x00_nv_write(ha, NVR_PR_ENABLE);
-		qla2x00_nv_write(ha, NVR_PR_ENABLE);
-		for (word = 0; word < 8; word++)
-			qla2x00_nv_write(ha, NVR_DATA_OUT | NVR_PR_ENABLE);
-
-		qla2x00_nv_deselect(ha);
-
-		/* Clear protection register (ffff is cleared). */
-		qla2x00_nv_write(ha, NVR_PR_ENABLE | NVR_DATA_OUT);
-		qla2x00_nv_write(ha, NVR_PR_ENABLE | NVR_DATA_OUT);
-		qla2x00_nv_write(ha, NVR_PR_ENABLE | NVR_DATA_OUT);
-		for (word = 0; word < 8; word++)
-			qla2x00_nv_write(ha, NVR_DATA_OUT | NVR_PR_ENABLE);
-
-		qla2x00_nv_deselect(ha);
-
-		/* Wait for NVRAM to become ready. */
-		WRT_REG_WORD(&reg->nvram, NVR_SELECT);
-		do {
-			NVRAM_DELAY();
-			word = RD_REG_WORD(&reg->nvram);
-		} while ((word & NVR_DATA_IN) == 0);
-	}
-}
-
-/**
  * qla2x00_get_nvram_word() - Calculates word position in NVRAM and calls the
  *	request routine to get the word from NVRAM.
  * @ha: HA context
@@ -161,7 +111,7 @@ qla2x00_write_nvram_word(scsi_qla_host_t
 	int count;
 	uint16_t word;
 	uint32_t nv_cmd;
-	device_reg_t __iomem *reg = ha->iobase;
+	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
 
 	qla2x00_nv_write(ha, NVR_DATA_OUT);
 	qla2x00_nv_write(ha, 0);
@@ -204,6 +154,64 @@ qla2x00_write_nvram_word(scsi_qla_host_t
 	qla2x00_nv_deselect(ha);
 }
 
+static int
+qla2x00_write_nvram_word_tmo(scsi_qla_host_t *ha, uint32_t addr, uint16_t data,
+    uint32_t tmo)
+{
+	int ret, count;
+	uint16_t word;
+	uint32_t nv_cmd;
+	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
+
+	ret = QLA_SUCCESS;
+
+	qla2x00_nv_write(ha, NVR_DATA_OUT);
+	qla2x00_nv_write(ha, 0);
+	qla2x00_nv_write(ha, 0);
+
+	for (word = 0; word < 8; word++)
+		qla2x00_nv_write(ha, NVR_DATA_OUT);
+
+	qla2x00_nv_deselect(ha);
+
+	/* Write data */
+	nv_cmd = (addr << 16) | NV_WRITE_OP;
+	nv_cmd |= data;
+	nv_cmd <<= 5;
+	for (count = 0; count < 27; count++) {
+		if (nv_cmd & BIT_31)
+			qla2x00_nv_write(ha, NVR_DATA_OUT);
+		else
+			qla2x00_nv_write(ha, 0);
+
+		nv_cmd <<= 1;
+	}
+
+	qla2x00_nv_deselect(ha);
+
+	/* Wait for NVRAM to become ready */
+	WRT_REG_WORD(&reg->nvram, NVR_SELECT);
+	do {
+		NVRAM_DELAY();
+		word = RD_REG_WORD(&reg->nvram);
+		if (!--tmo) {
+			ret = QLA_FUNCTION_FAILED;
+			break;
+		}
+	} while ((word & NVR_DATA_IN) == 0);
+
+	qla2x00_nv_deselect(ha);
+
+	/* Disable writes */
+	qla2x00_nv_write(ha, NVR_DATA_OUT);
+	for (count = 0; count < 10; count++)
+		qla2x00_nv_write(ha, 0);
+
+	qla2x00_nv_deselect(ha);
+
+	return ret;
+}
+
 /**
  * qla2x00_nvram_request() - Sends read command to NVRAM and gets data from
  *	NVRAM.
@@ -223,7 +231,7 @@ static uint16_t
 qla2x00_nvram_request(scsi_qla_host_t *ha, uint32_t nv_cmd)
 {
 	uint8_t		cnt;
-	device_reg_t __iomem *reg = ha->iobase;
+	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
 	uint16_t	data = 0;
 	uint16_t	reg_data;
 
@@ -265,7 +273,7 @@ qla2x00_nvram_request(scsi_qla_host_t *h
 static void
 qla2x00_nv_deselect(scsi_qla_host_t *ha)
 {
-	device_reg_t __iomem *reg = ha->iobase;
+	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
 
 	WRT_REG_WORD(&reg->nvram, NVR_DESELECT);
 	RD_REG_WORD(&reg->nvram);		/* PCI Posting. */
@@ -280,7 +288,7 @@ qla2x00_nv_deselect(scsi_qla_host_t *ha)
 static void
 qla2x00_nv_write(scsi_qla_host_t *ha, uint16_t data)
 {
-	device_reg_t __iomem *reg = ha->iobase;
+	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
 
 	WRT_REG_WORD(&reg->nvram, data | NVR_SELECT | NVR_WRT_ENABLE);
 	RD_REG_WORD(&reg->nvram);		/* PCI Posting. */
@@ -294,3 +302,435 @@ qla2x00_nv_write(scsi_qla_host_t *ha, ui
 	NVRAM_DELAY();
 }
 
+/**
+ * qla2x00_clear_nvram_protection() -
+ * @ha: HA context
+ */
+static int
+qla2x00_clear_nvram_protection(scsi_qla_host_t *ha)
+{
+	int ret, stat;
+	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
+	uint32_t word;
+	uint16_t wprot, wprot_old;
+
+	/* Clear NVRAM write protection. */
+	ret = QLA_FUNCTION_FAILED;
+	wprot_old = cpu_to_le16(qla2x00_get_nvram_word(ha, 0));
+	stat = qla2x00_write_nvram_word_tmo(ha, 0,
+	    __constant_cpu_to_le16(0x1234), 100000);
+	wprot = cpu_to_le16(qla2x00_get_nvram_word(ha, 0));
+	if (stat != QLA_SUCCESS || wprot != __constant_cpu_to_le16(0x1234)) {
+		/* Write enable. */
+		qla2x00_nv_write(ha, NVR_DATA_OUT);
+		qla2x00_nv_write(ha, 0);
+		qla2x00_nv_write(ha, 0);
+		for (word = 0; word < 8; word++)
+			qla2x00_nv_write(ha, NVR_DATA_OUT);
+
+		qla2x00_nv_deselect(ha);
+
+		/* Enable protection register. */
+		qla2x00_nv_write(ha, NVR_PR_ENABLE | NVR_DATA_OUT);
+		qla2x00_nv_write(ha, NVR_PR_ENABLE);
+		qla2x00_nv_write(ha, NVR_PR_ENABLE);
+		for (word = 0; word < 8; word++)
+			qla2x00_nv_write(ha, NVR_DATA_OUT | NVR_PR_ENABLE);
+
+		qla2x00_nv_deselect(ha);
+
+		/* Clear protection register (ffff is cleared). */
+		qla2x00_nv_write(ha, NVR_PR_ENABLE | NVR_DATA_OUT);
+		qla2x00_nv_write(ha, NVR_PR_ENABLE | NVR_DATA_OUT);
+		qla2x00_nv_write(ha, NVR_PR_ENABLE | NVR_DATA_OUT);
+		for (word = 0; word < 8; word++)
+			qla2x00_nv_write(ha, NVR_DATA_OUT | NVR_PR_ENABLE);
+
+		qla2x00_nv_deselect(ha);
+
+		/* Wait for NVRAM to become ready. */
+		WRT_REG_WORD(&reg->nvram, NVR_SELECT);
+		do {
+			NVRAM_DELAY();
+			word = RD_REG_WORD(&reg->nvram);
+		} while ((word & NVR_DATA_IN) == 0);
+
+		ret = QLA_SUCCESS;
+	} else
+		qla2x00_write_nvram_word(ha, 0, wprot_old);
+
+	return ret;
+}
+
+static void
+qla2x00_set_nvram_protection(scsi_qla_host_t *ha, int stat)
+{
+	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
+	uint32_t word;
+
+	if (stat != QLA_SUCCESS)
+		return;
+
+	/* Set NVRAM write protection. */
+	/* Write enable. */
+	qla2x00_nv_write(ha, NVR_DATA_OUT);
+	qla2x00_nv_write(ha, 0);
+	qla2x00_nv_write(ha, 0);
+	for (word = 0; word < 8; word++)
+		qla2x00_nv_write(ha, NVR_DATA_OUT);
+
+	qla2x00_nv_deselect(ha);
+
+	/* Enable protection register. */
+	qla2x00_nv_write(ha, NVR_PR_ENABLE | NVR_DATA_OUT);
+	qla2x00_nv_write(ha, NVR_PR_ENABLE);
+	qla2x00_nv_write(ha, NVR_PR_ENABLE);
+	for (word = 0; word < 8; word++)
+		qla2x00_nv_write(ha, NVR_DATA_OUT | NVR_PR_ENABLE);
+
+	qla2x00_nv_deselect(ha);
+
+	/* Enable protection register. */
+	qla2x00_nv_write(ha, NVR_PR_ENABLE | NVR_DATA_OUT);
+	qla2x00_nv_write(ha, NVR_PR_ENABLE);
+	qla2x00_nv_write(ha, NVR_PR_ENABLE | NVR_DATA_OUT);
+	for (word = 0; word < 8; word++)
+		qla2x00_nv_write(ha, NVR_PR_ENABLE);
+
+	qla2x00_nv_deselect(ha);
+
+	/* Wait for NVRAM to become ready. */
+	WRT_REG_WORD(&reg->nvram, NVR_SELECT);
+	do {
+		NVRAM_DELAY();
+		word = RD_REG_WORD(&reg->nvram);
+	} while ((word & NVR_DATA_IN) == 0);
+}
+
+
+/*****************************************************************************/
+/* Flash Manipulation Routines                                               */
+/*****************************************************************************/
+
+static inline uint32_t
+flash_conf_to_access_addr(uint32_t faddr)
+{
+	return FARX_ACCESS_FLASH_CONF | faddr;
+}
+
+static inline uint32_t
+flash_data_to_access_addr(uint32_t faddr)
+{
+	return FARX_ACCESS_FLASH_DATA | faddr;
+}
+
+static inline uint32_t
+nvram_conf_to_access_addr(uint32_t naddr)
+{
+	return FARX_ACCESS_NVRAM_CONF | naddr;
+}
+
+static inline uint32_t
+nvram_data_to_access_addr(uint32_t naddr)
+{
+	return FARX_ACCESS_NVRAM_DATA | naddr;
+}
+
+uint32_t
+qla24xx_read_flash_dword(scsi_qla_host_t *ha, uint32_t addr)
+{
+	int rval;
+	uint32_t cnt, data;
+	struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
+
+	WRT_REG_DWORD(&reg->flash_addr, addr & ~FARX_DATA_FLAG);
+	/* Wait for READ cycle to complete. */
+	rval = QLA_SUCCESS;
+	for (cnt = 3000;
+	    (RD_REG_DWORD(&reg->flash_addr) & FARX_DATA_FLAG) == 0 &&
+	    rval == QLA_SUCCESS; cnt--) {
+		if (cnt)
+			udelay(10);
+		else
+			rval = QLA_FUNCTION_TIMEOUT;
+	}
+
+	/* TODO: What happens if we time out? */
+	data = 0xDEADDEAD;
+	if (rval == QLA_SUCCESS)
+		data = RD_REG_DWORD(&reg->flash_data);
+
+	return data;
+}
+
+uint32_t *
+qla24xx_read_flash_data(scsi_qla_host_t *ha, uint32_t *dwptr, uint32_t faddr,
+    uint32_t dwords)
+{
+	uint32_t i;
+	struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
+
+	/* Pause RISC. */
+	WRT_REG_DWORD(&reg->hccr, HCCRX_SET_RISC_PAUSE);
+	RD_REG_DWORD(&reg->hccr);		/* PCI Posting. */
+
+	/* Dword reads to flash. */
+	for (i = 0; i < dwords; i++, faddr++)
+		dwptr[i] = cpu_to_le32(qla24xx_read_flash_dword(ha,
+		    flash_data_to_access_addr(faddr)));
+
+	/* Release RISC pause. */
+	WRT_REG_DWORD(&reg->hccr, HCCRX_REL_RISC_PAUSE);
+	RD_REG_DWORD(&reg->hccr);		/* PCI Posting. */
+
+	return dwptr;
+}
+
+int
+qla24xx_write_flash_dword(scsi_qla_host_t *ha, uint32_t addr, uint32_t data)
+{
+	int rval;
+	uint32_t cnt;
+	struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
+
+	WRT_REG_DWORD(&reg->flash_data, data);
+	RD_REG_DWORD(&reg->flash_data);		/* PCI Posting. */
+	WRT_REG_DWORD(&reg->flash_addr, addr | FARX_DATA_FLAG);
+	/* Wait for Write cycle to complete. */
+	rval = QLA_SUCCESS;
+	for (cnt = 500000; (RD_REG_DWORD(&reg->flash_addr) & FARX_DATA_FLAG) &&
+	    rval == QLA_SUCCESS; cnt--) {
+		if (cnt)
+			udelay(10);
+		else
+			rval = QLA_FUNCTION_TIMEOUT;
+	}
+	return rval;
+}
+
+void
+qla24xx_get_flash_manufacturer(scsi_qla_host_t *ha, uint8_t *man_id,
+    uint8_t *flash_id)
+{
+	uint32_t ids;
+
+	ids = qla24xx_read_flash_dword(ha, flash_data_to_access_addr(0xd03ab));
+	*man_id = LSB(ids);
+	*flash_id = MSB(ids);
+}
+
+int
+qla24xx_write_flash_data(scsi_qla_host_t *ha, uint32_t *dwptr, uint32_t faddr,
+    uint32_t dwords)
+{
+	int ret;
+	uint32_t liter;
+	uint32_t sec_mask, rest_addr, conf_addr;
+	uint32_t fdata;
+	uint8_t	man_id, flash_id;
+	struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
+
+	ret = QLA_SUCCESS;
+
+	/* Pause RISC. */
+	WRT_REG_DWORD(&reg->hccr, HCCRX_SET_RISC_PAUSE);
+	RD_REG_DWORD(&reg->hccr);		/* PCI Posting. */
+
+	qla24xx_get_flash_manufacturer(ha, &man_id, &flash_id);
+	DEBUG9(printk("%s(%ld): Flash man_id=%d flash_id=%d\n", __func__,
+	    ha->host_no, man_id, flash_id));
+
+	conf_addr = flash_conf_to_access_addr(0x03d8);
+	switch (man_id) {
+	case 0xbf: /* STT flash. */
+		rest_addr = 0x1fff;
+		sec_mask = 0x3e000;
+		if (flash_id == 0x80)
+			conf_addr = flash_conf_to_access_addr(0x0352);
+		break;
+	case 0x13: /* ST M25P80. */
+		rest_addr = 0x3fff;
+		sec_mask = 0x3c000;
+		break;
+	default:
+		/* Default to 64 kb sector size. */
+		rest_addr = 0x3fff;
+		sec_mask = 0x3c000;
+		break;
+	}
+
+	/* Enable flash write. */
+	WRT_REG_DWORD(&reg->ctrl_status,
+	    RD_REG_DWORD(&reg->ctrl_status) | CSRX_FLASH_ENABLE);
+	RD_REG_DWORD(&reg->ctrl_status);	/* PCI Posting. */
+
+	/* Disable flash write-protection. */
+	qla24xx_write_flash_dword(ha, flash_conf_to_access_addr(0x101), 0);
+
+	do {    /* Loop once to provide quick error exit. */
+		for (liter = 0; liter < dwords; liter++, faddr++, dwptr++) {
+			/* Are we at the beginning of a sector? */
+			if ((faddr & rest_addr) == 0) {
+				fdata = (faddr & sec_mask) << 2;
+				ret = qla24xx_write_flash_dword(ha, conf_addr,
+				    (fdata & 0xff00) |((fdata << 16) &
+				    0xff0000) | ((fdata >> 16) & 0xff));
+				if (ret != QLA_SUCCESS) {
+					DEBUG9(printk("%s(%ld) Unable to flash "
+					    "sector: address=%x.\n", __func__,
+					    ha->host_no, faddr));
+					break;
+				}
+			}
+			ret = qla24xx_write_flash_dword(ha,
+			    flash_data_to_access_addr(faddr),
+			    cpu_to_le32(*dwptr));
+			if (ret != QLA_SUCCESS) {
+				DEBUG9(printk("%s(%ld) Unable to program flash "
+				    "address=%x data=%x.\n", __func__,
+				    ha->host_no, faddr, *dwptr));
+				break;
+			}
+		}
+	} while (0);
+
+	/* Disable flash write. */
+	WRT_REG_DWORD(&reg->ctrl_status,
+	    RD_REG_DWORD(&reg->ctrl_status) & ~CSRX_FLASH_ENABLE);
+	RD_REG_DWORD(&reg->ctrl_status);	/* PCI Posting. */
+
+	/* Release RISC pause. */
+	WRT_REG_DWORD(&reg->hccr, HCCRX_REL_RISC_PAUSE);
+	RD_REG_DWORD(&reg->hccr);		/* PCI Posting. */
+
+	return ret;
+}
+
+uint8_t *
+qla2x00_read_nvram_data(scsi_qla_host_t *ha, uint8_t *buf, uint32_t naddr,
+    uint32_t bytes)
+{
+	uint32_t i;
+	uint16_t *wptr;
+
+	/* Word reads to NVRAM via registers. */
+	wptr = (uint16_t *)buf;
+	qla2x00_lock_nvram_access(ha);
+	for (i = 0; i < bytes >> 1; i++, naddr++)
+		wptr[i] = cpu_to_le16(qla2x00_get_nvram_word(ha,
+		    naddr));
+	qla2x00_unlock_nvram_access(ha);
+
+	return buf;
+}
+
+uint8_t *
+qla24xx_read_nvram_data(scsi_qla_host_t *ha, uint8_t *buf, uint32_t naddr,
+    uint32_t bytes)
+{
+	uint32_t i;
+	uint32_t *dwptr;
+	struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
+
+	/* Pause RISC. */
+	WRT_REG_DWORD(&reg->hccr, HCCRX_SET_RISC_PAUSE);
+	RD_REG_DWORD(&reg->hccr);	/* PCI Posting. */
+
+	/* Dword reads to flash. */
+	dwptr = (uint32_t *)buf;
+	for (i = 0; i < bytes >> 2; i++, naddr++)
+		dwptr[i] = cpu_to_le32(qla24xx_read_flash_dword(ha,
+		    nvram_data_to_access_addr(naddr)));
+
+	/* Release RISC pause. */
+	WRT_REG_DWORD(&reg->hccr, HCCRX_REL_RISC_PAUSE);
+	RD_REG_DWORD(&reg->hccr);	/* PCI Posting. */
+
+	return buf;
+}
+
+int
+qla2x00_write_nvram_data(scsi_qla_host_t *ha, uint8_t *buf, uint32_t naddr,
+    uint32_t bytes)
+{
+	int ret, stat;
+	uint32_t i;
+	uint16_t *wptr;
+
+	ret = QLA_SUCCESS;
+
+	qla2x00_lock_nvram_access(ha);
+
+	/* Disable NVRAM write-protection. */
+	stat = qla2x00_clear_nvram_protection(ha);
+
+	wptr = (uint16_t *)buf;
+	for (i = 0; i < bytes >> 1; i++, naddr++) {
+		qla2x00_write_nvram_word(ha, naddr,
+		    cpu_to_le16(*wptr));
+		wptr++;
+	}
+
+	/* Enable NVRAM write-protection. */
+	qla2x00_set_nvram_protection(ha, stat);
+
+	qla2x00_unlock_nvram_access(ha);
+
+	return ret;
+}
+
+int
+qla24xx_write_nvram_data(scsi_qla_host_t *ha, uint8_t *buf, uint32_t naddr,
+    uint32_t bytes)
+{
+	int ret;
+	uint32_t i;
+	uint32_t *dwptr;
+	struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
+
+	ret = QLA_SUCCESS;
+
+	/* Pause RISC. */
+	WRT_REG_DWORD(&reg->hccr, HCCRX_SET_RISC_PAUSE);
+	RD_REG_DWORD(&reg->hccr);		/* PCI Posting. */
+
+	/* Enable flash write. */
+	WRT_REG_DWORD(&reg->ctrl_status,
+	    RD_REG_DWORD(&reg->ctrl_status) | CSRX_FLASH_ENABLE);
+	RD_REG_DWORD(&reg->ctrl_status);	/* PCI Posting. */
+
+	/* Disable NVRAM write-protection. */
+	qla24xx_write_flash_dword(ha, nvram_conf_to_access_addr(0x101),
+	    0);
+	qla24xx_write_flash_dword(ha, nvram_conf_to_access_addr(0x101),
+	    0);
+
+	/* Dword writes to flash. */
+	dwptr = (uint32_t *)buf;
+	for (i = 0; i < bytes >> 2; i++, naddr++, dwptr++) {
+		ret = qla24xx_write_flash_dword(ha,
+		    nvram_data_to_access_addr(naddr),
+		    cpu_to_le32(*dwptr));
+		if (ret != QLA_SUCCESS) {
+			DEBUG9(printk("%s(%ld) Unable to program "
+			    "nvram address=%x data=%x.\n", __func__,
+			    ha->host_no, naddr, *dwptr));
+			break;
+		}
+	}
+
+	/* Enable NVRAM write-protection. */
+	qla24xx_write_flash_dword(ha, nvram_conf_to_access_addr(0x101),
+	    0x8c);
+
+	/* Disable flash write. */
+	WRT_REG_DWORD(&reg->ctrl_status,
+	    RD_REG_DWORD(&reg->ctrl_status) & ~CSRX_FLASH_ENABLE);
+	RD_REG_DWORD(&reg->ctrl_status);	/* PCI Posting. */
+
+	/* Release RISC pause. */
+	WRT_REG_DWORD(&reg->hccr, HCCRX_REL_RISC_PAUSE);
+	RD_REG_DWORD(&reg->hccr);		/* PCI Posting. */
+
+	return ret;
+}
diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h
--- a/drivers/scsi/qla2xxx/qla_version.h
+++ b/drivers/scsi/qla2xxx/qla_version.h
@@ -2,7 +2,7 @@
  *                  QLOGIC LINUX SOFTWARE
  *
  * QLogic ISP2x00 device driver for Linux 2.6.x
- * Copyright (C) 2003-2004 QLogic Corporation
+ * Copyright (C) 2003-2005 QLogic Corporation
  * (www.qlogic.com)
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -17,11 +17,11 @@
  *
  ******************************************************************************/
 /*
- * Driver version 
+ * Driver version
  */
-#define QLA2XXX_VERSION      "8.00.02b5-k"
+#define QLA2XXX_VERSION      "8.01.00b5-k"
 
 #define QLA_DRIVER_MAJOR_VER	8
-#define QLA_DRIVER_MINOR_VER	0
-#define QLA_DRIVER_PATCH_VER	2
+#define QLA_DRIVER_MINOR_VER	1
+#define QLA_DRIVER_PATCH_VER	0
 #define QLA_DRIVER_BETA_VER	5
diff --git a/drivers/scsi/qlogicfas.c b/drivers/scsi/qlogicfas.c
--- a/drivers/scsi/qlogicfas.c
+++ b/drivers/scsi/qlogicfas.c
@@ -191,8 +191,6 @@ static Scsi_Host_Template qlogicfas_driv
 	.queuecommand		= qlogicfas408_queuecommand,
 	.eh_abort_handler	= qlogicfas408_abort,
 	.eh_bus_reset_handler	= qlogicfas408_bus_reset,
-	.eh_device_reset_handler= qlogicfas408_device_reset,
-	.eh_host_reset_handler	= qlogicfas408_host_reset,
 	.bios_param		= qlogicfas408_biosparam,
 	.can_queue		= 1,
 	.this_id		= -1,
diff --git a/drivers/scsi/qlogicfas408.c b/drivers/scsi/qlogicfas408.c
--- a/drivers/scsi/qlogicfas408.c
+++ b/drivers/scsi/qlogicfas408.c
@@ -511,27 +511,15 @@ int qlogicfas408_abort(Scsi_Cmnd * cmd)
 int qlogicfas408_bus_reset(Scsi_Cmnd * cmd)
 {
 	struct qlogicfas408_priv *priv = get_priv_by_cmd(cmd);
-	priv->qabort = 2;
-	ql_zap(priv);
-	return SUCCESS;
-}
+	unsigned long flags;
 
-/* 
- *	Reset SCSI host controller
- */
-
-int qlogicfas408_host_reset(Scsi_Cmnd * cmd)
-{
-	return FAILED;
-}
+	priv->qabort = 2;
 
-/* 
- *	Reset SCSI device
- */
+	spin_lock_irqsave(cmd->device->host->host_lock, flags);
+	ql_zap(priv);
+	spin_unlock_irqrestore(cmd->device->host->host_lock, flags);
 
-int qlogicfas408_device_reset(Scsi_Cmnd * cmd)
-{
-	return FAILED;
+	return SUCCESS;
 }
 
 /*
@@ -626,8 +614,6 @@ EXPORT_SYMBOL(qlogicfas408_info);
 EXPORT_SYMBOL(qlogicfas408_queuecommand);
 EXPORT_SYMBOL(qlogicfas408_abort);
 EXPORT_SYMBOL(qlogicfas408_bus_reset);
-EXPORT_SYMBOL(qlogicfas408_device_reset);
-EXPORT_SYMBOL(qlogicfas408_host_reset);
 EXPORT_SYMBOL(qlogicfas408_biosparam);
 EXPORT_SYMBOL(qlogicfas408_ihandl);
 EXPORT_SYMBOL(qlogicfas408_get_chip_type);
diff --git a/drivers/scsi/qlogicfas408.h b/drivers/scsi/qlogicfas408.h
--- a/drivers/scsi/qlogicfas408.h
+++ b/drivers/scsi/qlogicfas408.h
@@ -109,8 +109,6 @@ int qlogicfas408_biosparam(struct scsi_d
 			sector_t capacity, int ip[]);
 int qlogicfas408_abort(Scsi_Cmnd * cmd);
 int qlogicfas408_bus_reset(Scsi_Cmnd * cmd);
-int qlogicfas408_host_reset(Scsi_Cmnd * cmd);
-int qlogicfas408_device_reset(Scsi_Cmnd * cmd);
 const char *qlogicfas408_info(struct Scsi_Host *host);
 int qlogicfas408_get_chip_type(int qbase, int int_type);
 void qlogicfas408_setup(int qbase, int id, int int_type);
diff --git a/drivers/scsi/qlogicfc.c b/drivers/scsi/qlogicfc.c
--- a/drivers/scsi/qlogicfc.c
+++ b/drivers/scsi/qlogicfc.c
@@ -746,7 +746,6 @@ static int isp2x00_detect(Scsi_Host_Temp
 			        printk("qlogicfc%d : could not register host.\n", hosts);
 				continue;
 			}
- 			scsi_set_device(host, &pdev->dev);
 			host->max_id = QLOGICFC_MAX_ID + 1;
 			host->max_lun = QLOGICFC_MAX_LUN;
 			hostdata = (struct isp2x00_hostdata *) host->hostdata;
diff --git a/drivers/scsi/qlogicisp.c b/drivers/scsi/qlogicisp.c
--- a/drivers/scsi/qlogicisp.c
+++ b/drivers/scsi/qlogicisp.c
@@ -694,7 +694,6 @@ static int isp1020_detect(Scsi_Host_Temp
 		memset(hostdata, 0, sizeof(struct isp1020_hostdata));
 
 		hostdata->pci_dev = pdev;
-		scsi_set_device(host, &pdev->dev);
 
 		if (isp1020_init(host))
 			goto fail_and_unregister;
diff --git a/drivers/scsi/sata_promise.c b/drivers/scsi/sata_promise.c
--- a/drivers/scsi/sata_promise.c
+++ b/drivers/scsi/sata_promise.c
@@ -40,7 +40,7 @@
 #include "sata_promise.h"
 
 #define DRV_NAME	"sata_promise"
-#define DRV_VERSION	"1.01"
+#define DRV_VERSION	"1.02"
 
 
 enum {
@@ -59,6 +59,7 @@ enum {
 
 	board_2037x		= 0,	/* FastTrak S150 TX2plus */
 	board_20319		= 1,	/* FastTrak S150 TX4 */
+	board_20619		= 2,	/* FastTrak TX4000 */
 
 	PDC_HAS_PATA		= (1 << 1), /* PDC20375 has PATA */
 
@@ -147,6 +148,17 @@ static struct ata_port_info pdc_port_inf
 		.udma_mask	= 0x7f, /* udma0-6 ; FIXME */
 		.port_ops	= &pdc_ata_ops,
 	},
+
+	/* board_20619 */
+	{
+		.sht		= &pdc_ata_sht,
+		.host_flags	= ATA_FLAG_NO_LEGACY | ATA_FLAG_SRST |
+				  ATA_FLAG_MMIO | ATA_FLAG_SLAVE_POSS,
+		.pio_mask	= 0x1f, /* pio0-4 */
+		.mwdma_mask	= 0x07, /* mwdma0-2 */
+		.udma_mask	= 0x7f, /* udma0-6 ; FIXME */
+		.port_ops	= &pdc_ata_ops,
+	},
 };
 
 static struct pci_device_id pdc_ata_pci_tbl[] = {
@@ -172,6 +184,9 @@ static struct pci_device_id pdc_ata_pci_
 	{ PCI_VENDOR_ID_PROMISE, 0x3d18, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
 	  board_20319 },
 
+	{ PCI_VENDOR_ID_PROMISE, 0x6629, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+	  board_20619 },
+
 	{ }	/* terminate list */
 };
 
@@ -636,6 +651,15 @@ static int pdc_ata_init_one (struct pci_
 	case board_2037x:
        		probe_ent->n_ports = 2;
 		break;
+	case board_20619:
+		probe_ent->n_ports = 4;
+
+		pdc_ata_setup_port(&probe_ent->port[2], base + 0x300);
+		pdc_ata_setup_port(&probe_ent->port[3], base + 0x380);
+
+		probe_ent->port[2].scr_addr = base + 0x600;
+		probe_ent->port[3].scr_addr = base + 0x700;
+                break;
 	default:
 		BUG();
 		break;
@@ -676,7 +700,7 @@ static void __exit pdc_ata_exit(void)
 
 
 MODULE_AUTHOR("Jeff Garzik");
-MODULE_DESCRIPTION("Promise SATA TX2/TX4 low-level driver");
+MODULE_DESCRIPTION("Promise ATA TX2/TX4/TX4000 low-level driver");
 MODULE_LICENSE("GPL");
 MODULE_DEVICE_TABLE(pci, pdc_ata_pci_tbl);
 MODULE_VERSION(DRV_VERSION);
diff --git a/drivers/scsi/sata_svw.c b/drivers/scsi/sata_svw.c
--- a/drivers/scsi/sata_svw.c
+++ b/drivers/scsi/sata_svw.c
@@ -49,7 +49,7 @@
 #endif /* CONFIG_PPC_OF */
 
 #define DRV_NAME	"sata_svw"
-#define DRV_VERSION	"1.05"
+#define DRV_VERSION	"1.06"
 
 /* Taskfile registers offsets */
 #define K2_SATA_TF_CMD_OFFSET		0x00
@@ -344,6 +344,7 @@ static int k2_sata_init_one (struct pci_
 	void *mmio_base;
 	int pci_dev_busy = 0;
 	int rc;
+	int i;
 
 	if (!printed_version++)
 		printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n");
@@ -421,11 +422,11 @@ static int k2_sata_init_one (struct pci_
 	probe_ent->mwdma_mask = 0x7;
 	probe_ent->udma_mask = 0x7f;
 
-	/* We have 4 ports per PCI function */
-	k2_sata_setup_port(&probe_ent->port[0], base + 0 * K2_SATA_PORT_OFFSET);
-	k2_sata_setup_port(&probe_ent->port[1], base + 1 * K2_SATA_PORT_OFFSET);
-	k2_sata_setup_port(&probe_ent->port[2], base + 2 * K2_SATA_PORT_OFFSET);
-	k2_sata_setup_port(&probe_ent->port[3], base + 3 * K2_SATA_PORT_OFFSET);
+	/* different controllers have different number of ports - currently 4 or 8 */
+	/* All ports are on the same function. Multi-function device is no
+	 * longer available. This should not be seen in any system. */
+	for (i = 0; i < ent->driver_data; i++)
+		k2_sata_setup_port(&probe_ent->port[i], base + i * K2_SATA_PORT_OFFSET);
 
 	pci_set_master(pdev);
 
@@ -445,11 +446,17 @@ err_out:
 	return rc;
 }
 
-
+/* 0x240 is device ID for Apple K2 device
+ * 0x241 is device ID for Serverworks Frodo4
+ * 0x242 is device ID for Serverworks Frodo8
+ * 0x24a is device ID for BCM5785 (aka HT1000) HT southbridge integrated SATA
+ * controller
+ * */
 static struct pci_device_id k2_sata_pci_tbl[] = {
-	{ 0x1166, 0x0240, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
-	{ 0x1166, 0x0241, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
-	{ 0x1166, 0x0242, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+	{ 0x1166, 0x0240, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 },
+	{ 0x1166, 0x0241, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 },
+	{ 0x1166, 0x0242, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8 },
+	{ 0x1166, 0x024a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 },
 	{ }
 };
 
diff --git a/drivers/scsi/sata_sx4.c b/drivers/scsi/sata_sx4.c
--- a/drivers/scsi/sata_sx4.c
+++ b/drivers/scsi/sata_sx4.c
@@ -468,7 +468,7 @@ static void pdc20621_dma_prep(struct ata
 	for (i = 0; i < last; i++) {
 		buf[idx++] = cpu_to_le32(sg_dma_address(&sg[i]));
 		buf[idx++] = cpu_to_le32(sg_dma_len(&sg[i]));
-		total_len += sg[i].length;
+		total_len += sg_dma_len(&sg[i]);
 	}
 	buf[idx - 1] |= cpu_to_le32(ATA_PRD_EOT);
 	sgt_len = idx * 4;
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -68,6 +68,8 @@
 #include "scsi_priv.h"
 #include "scsi_logging.h"
 
+static void scsi_done(struct scsi_cmnd *cmd);
+static int scsi_retry_command(struct scsi_cmnd *cmd);
 
 /*
  * Definitions and constants.
@@ -111,6 +113,7 @@ const char *const scsi_device_types[MAX_
 	"Unknown          ",
 	"RAID             ",
 	"Enclosure        ",
+	"Direct-Access-RBC",
 };
 EXPORT_SYMBOL(scsi_device_types);
 
@@ -257,8 +260,6 @@ struct scsi_cmnd *scsi_get_command(struc
 
 		memset(cmd, 0, sizeof(*cmd));
 		cmd->device = dev;
-		cmd->state = SCSI_STATE_UNUSED;
-		cmd->owner = SCSI_OWNER_NOBODY;
 		init_timer(&cmd->eh_timeout);
 		INIT_LIST_HEAD(&cmd->list);
 		spin_lock_irqsave(&dev->list_lock, flags);
@@ -608,10 +609,6 @@ int scsi_dispatch_cmd(struct scsi_cmnd *
 	 * We will use a queued command if possible, otherwise we will
 	 * emulate the queuing and calling of completion function ourselves.
 	 */
-
-	cmd->state = SCSI_STATE_QUEUED;
-	cmd->owner = SCSI_OWNER_LOWLEVEL;
-
 	atomic_inc(&cmd->device->iorequest_cnt);
 
 	/*
@@ -638,10 +635,12 @@ int scsi_dispatch_cmd(struct scsi_cmnd *
 	}
 	spin_unlock_irqrestore(host->host_lock, flags);
 	if (rtn) {
-		atomic_inc(&cmd->device->iodone_cnt);
-		scsi_queue_insert(cmd,
-				(rtn == SCSI_MLQUEUE_DEVICE_BUSY) ?
-				 rtn : SCSI_MLQUEUE_HOST_BUSY);
+		if (scsi_delete_timer(cmd)) {
+			atomic_inc(&cmd->device->iodone_cnt);
+			scsi_queue_insert(cmd,
+					  (rtn == SCSI_MLQUEUE_DEVICE_BUSY) ?
+					  rtn : SCSI_MLQUEUE_HOST_BUSY);
+		}
 		SCSI_LOG_MLQUEUE(3,
 		    printk("queuecommand : request rejected\n"));
 	}
@@ -679,7 +678,6 @@ void scsi_init_cmd_from_req(struct scsi_
 {
 	sreq->sr_command = cmd;
 
-	cmd->owner = SCSI_OWNER_MIDLEVEL;
 	cmd->cmd_len = sreq->sr_cmd_len;
 	cmd->use_sg = sreq->sr_use_sg;
 
@@ -715,7 +713,6 @@ void scsi_init_cmd_from_req(struct scsi_
 	/*
 	 * Start the timer ticking.
 	 */
-	cmd->abort_reason = 0;
 	cmd->result = 0;
 
 	SCSI_LOG_MLQUEUE(3, printk("Leaving scsi_init_cmd_from_req()\n"));
@@ -739,7 +736,7 @@ static DEFINE_PER_CPU(struct list_head, 
  *
  * This function is interrupt context safe.
  */
-void scsi_done(struct scsi_cmnd *cmd)
+static void scsi_done(struct scsi_cmnd *cmd)
 {
 	/*
 	 * We don't have to worry about this one timing out any more.
@@ -764,8 +761,6 @@ void __scsi_done(struct scsi_cmnd *cmd)
 	 * Set the serial numbers back to zero
 	 */
 	cmd->serial_number = 0;
-	cmd->state = SCSI_STATE_BHQUEUE;
-	cmd->owner = SCSI_OWNER_BH_HANDLER;
 
 	atomic_inc(&cmd->device->iodone_cnt);
 	if (cmd->result)
@@ -834,7 +829,7 @@ static void scsi_softirq(struct softirq_
  *              level drivers should not become re-entrant as a result of
  *              this.
  */
-int scsi_retry_command(struct scsi_cmnd *cmd)
+static int scsi_retry_command(struct scsi_cmnd *cmd)
 {
 	/*
 	 * Restore the SCSI command state.
@@ -886,9 +881,6 @@ void scsi_finish_command(struct scsi_cmn
 	SCSI_LOG_MLCOMPLETE(4, printk("Notifying upper driver of completion "
 				"for device %d %x\n", sdev->id, cmd->result));
 
-	cmd->owner = SCSI_OWNER_HIGHLEVEL;
-	cmd->state = SCSI_STATE_FINISHED;
-
 	/*
 	 * We can get here with use_sg=0, causing a panic in the upper level
 	 */
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -1783,7 +1783,7 @@ static void __exit scsi_debug_exit(void)
 device_initcall(scsi_debug_init);
 module_exit(scsi_debug_exit);
 
-void pseudo_0_release(struct device * dev)
+static void pseudo_0_release(struct device * dev)
 {
 	if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
 		printk(KERN_INFO "scsi_debug: pseudo_0_release() called\n");
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -73,12 +73,7 @@ int scsi_eh_scmd_add(struct scsi_cmnd *s
 
 	spin_lock_irqsave(shost->host_lock, flags);
 
-	scsi_eh_eflags_set(scmd, eh_flag);
-	/*
-	 * FIXME: Can we stop setting owner and state.
-	 */
-	scmd->owner = SCSI_OWNER_ERROR_HANDLER;
-	scmd->state = SCSI_STATE_FAILED;
+	scmd->eh_eflags |= eh_flag;
 	list_add_tail(&scmd->eh_entry, &shost->eh_cmd_q);
 	set_bit(SHOST_RECOVERY, &shost->shost_state);
 	shost->host_failed++;
@@ -233,8 +228,7 @@ static inline void scsi_eh_prt_fail_stat
 		list_for_each_entry(scmd, work_q, eh_entry) {
 			if (scmd->device == sdev) {
 				++total_failures;
-				if (scsi_eh_eflags_chk(scmd,
-						       SCSI_EH_CANCEL_CMD))
+				if (scmd->eh_eflags & SCSI_EH_CANCEL_CMD)
 					++cmd_cancel;
 				else 
 					++cmd_failed;
@@ -430,12 +424,11 @@ static int scsi_eh_completed_normally(st
  **/
 static void scsi_eh_times_out(struct scsi_cmnd *scmd)
 {
-	scsi_eh_eflags_set(scmd, SCSI_EH_REC_TIMEOUT);
+	scmd->eh_eflags |= SCSI_EH_REC_TIMEOUT;
 	SCSI_LOG_ERROR_RECOVERY(3, printk("%s: scmd:%p\n", __FUNCTION__,
 					  scmd));
 
-	if (scmd->device->host->eh_action)
-		up(scmd->device->host->eh_action);
+	up(scmd->device->host->eh_action);
 }
 
 /**
@@ -452,13 +445,11 @@ static void scsi_eh_done(struct scsi_cmn
 	 */
 	if (del_timer(&scmd->eh_timeout)) {
 		scmd->request->rq_status = RQ_SCSI_DONE;
-		scmd->owner = SCSI_OWNER_ERROR_HANDLER;
 
 		SCSI_LOG_ERROR_RECOVERY(3, printk("%s scmd: %p result: %x\n",
 					   __FUNCTION__, scmd, scmd->result));
 
-		if (scmd->device->host->eh_action)
-			up(scmd->device->host->eh_action);
+		up(scmd->device->host->eh_action);
 	}
 }
 
@@ -486,8 +477,6 @@ static int scsi_send_eh_cmnd(struct scsi
 	 * we will use a queued command if possible, otherwise we will
 	 * emulate the queuing and calling of completion function ourselves.
 	 */
-	scmd->owner = SCSI_OWNER_LOWLEVEL;
-
 	if (sdev->scsi_level <= SCSI_2)
 		scmd->cmnd[1] = (scmd->cmnd[1] & 0x1f) |
 			(sdev->lun << 5 & 0xe0);
@@ -514,9 +503,8 @@ static int scsi_send_eh_cmnd(struct scsi
 	 * see if timeout.  if so, tell the host to forget about it.
 	 * in other words, we don't want a callback any more.
 	 */
-	if (scsi_eh_eflags_chk(scmd, SCSI_EH_REC_TIMEOUT)) {
-		scsi_eh_eflags_clr(scmd,  SCSI_EH_REC_TIMEOUT);
-		scmd->owner = SCSI_OWNER_LOWLEVEL;
+	if (scmd->eh_eflags & SCSI_EH_REC_TIMEOUT) {
+		scmd->eh_eflags &= ~SCSI_EH_REC_TIMEOUT;
 
 		/*
 		 * as far as the low level driver is
@@ -528,14 +516,10 @@ static int scsi_send_eh_cmnd(struct scsi
 		 * abort a timed out command or not.  not sure how
 		 * we should treat them differently anyways.
 		 */
-		spin_lock_irqsave(shost->host_lock, flags);
 		if (shost->hostt->eh_abort_handler)
 			shost->hostt->eh_abort_handler(scmd);
-		spin_unlock_irqrestore(shost->host_lock, flags);
 			
 		scmd->request->rq_status = RQ_SCSI_DONE;
-		scmd->owner = SCSI_OWNER_ERROR_HANDLER;
-			
 		rtn = FAILED;
 	}
 
@@ -645,9 +629,7 @@ static void scsi_eh_finish_cmd(struct sc
 			       struct list_head *done_q)
 {
 	scmd->device->host->host_failed--;
-	scmd->state = SCSI_STATE_BHQUEUE;
-
-	scsi_eh_eflags_clr_all(scmd);
+	scmd->eh_eflags = 0;
 
 	/*
 	 * set this back so that the upper level can correctly free up
@@ -680,13 +662,11 @@ static void scsi_eh_finish_cmd(struct sc
 static int scsi_eh_get_sense(struct list_head *work_q,
 			     struct list_head *done_q)
 {
-	struct list_head *lh, *lh_sf;
-	struct scsi_cmnd *scmd;
+	struct scsi_cmnd *scmd, *next;
 	int rtn;
 
-	list_for_each_safe(lh, lh_sf, work_q) {
-		scmd = list_entry(lh, struct scsi_cmnd, eh_entry);
-		if (scsi_eh_eflags_chk(scmd, SCSI_EH_CANCEL_CMD) ||
+	list_for_each_entry_safe(scmd, next, work_q, eh_entry) {
+		if ((scmd->eh_eflags & SCSI_EH_CANCEL_CMD) ||
 		    SCSI_SENSE_VALID(scmd))
 			continue;
 
@@ -737,11 +717,8 @@ static int scsi_eh_get_sense(struct list
  **/
 static int scsi_try_to_abort_cmd(struct scsi_cmnd *scmd)
 {
-	unsigned long flags;
-	int rtn = FAILED;
-
 	if (!scmd->device->host->hostt->eh_abort_handler)
-		return rtn;
+		return FAILED;
 
 	/*
 	 * scsi_done was called just after the command timed out and before
@@ -749,14 +726,7 @@ static int scsi_try_to_abort_cmd(struct 
 	 */
 	if (scmd->serial_number == 0)
 		return SUCCESS;
-
-	scmd->owner = SCSI_OWNER_LOWLEVEL;
-
-	spin_lock_irqsave(scmd->device->host->host_lock, flags);
-	rtn = scmd->device->host->hostt->eh_abort_handler(scmd);
-	spin_unlock_irqrestore(scmd->device->host->host_lock, flags);
-
-	return rtn;
+	return scmd->device->host->hostt->eh_abort_handler(scmd);
 }
 
 /**
@@ -770,6 +740,7 @@ static int scsi_eh_tur(struct scsi_cmnd 
 {
 	static unsigned char tur_command[6] = {TEST_UNIT_READY, 0, 0, 0, 0, 0};
 	int retry_cnt = 1, rtn;
+	int saved_result;
 
 retry_tur:
 	memcpy(scmd->cmnd, tur_command, sizeof(tur_command));
@@ -780,6 +751,7 @@ retry_tur:
 	 */
 	memset(scmd->sense_buffer, 0, sizeof(scmd->sense_buffer));
 
+	saved_result = scmd->result;
 	scmd->request_buffer = NULL;
 	scmd->request_bufflen = 0;
 	scmd->use_sg = 0;
@@ -794,6 +766,7 @@ retry_tur:
 	 * the original request, so let's restore the original data. (db)
 	 */
 	scsi_setup_cmd_retry(scmd);
+	scmd->result = saved_result;
 
 	/*
 	 * hey, we are done.  let's look to see what happened.
@@ -823,20 +796,18 @@ retry_tur:
 static int scsi_eh_abort_cmds(struct list_head *work_q,
 			      struct list_head *done_q)
 {
-	struct list_head *lh, *lh_sf;
-	struct scsi_cmnd *scmd;
+	struct scsi_cmnd *scmd, *next;
 	int rtn;
 
-	list_for_each_safe(lh, lh_sf, work_q) {
-		scmd = list_entry(lh, struct scsi_cmnd, eh_entry);
-		if (!scsi_eh_eflags_chk(scmd, SCSI_EH_CANCEL_CMD))
+	list_for_each_entry_safe(scmd, next, work_q, eh_entry) {
+		if (!(scmd->eh_eflags & SCSI_EH_CANCEL_CMD))
 			continue;
 		SCSI_LOG_ERROR_RECOVERY(3, printk("%s: aborting cmd:"
 						  "0x%p\n", current->comm,
 						  scmd));
 		rtn = scsi_try_to_abort_cmd(scmd);
 		if (rtn == SUCCESS) {
-			scsi_eh_eflags_clr(scmd,  SCSI_EH_CANCEL_CMD);
+			scmd->eh_eflags &= ~SCSI_EH_CANCEL_CMD;
 			if (!scsi_device_online(scmd->device) ||
 			    !scsi_eh_tur(scmd)) {
 				scsi_eh_finish_cmd(scmd, done_q);
@@ -865,18 +836,12 @@ static int scsi_eh_abort_cmds(struct lis
  **/
 static int scsi_try_bus_device_reset(struct scsi_cmnd *scmd)
 {
-	unsigned long flags;
-	int rtn = FAILED;
+	int rtn;
 
 	if (!scmd->device->host->hostt->eh_device_reset_handler)
-		return rtn;
-
-	scmd->owner = SCSI_OWNER_LOWLEVEL;
+		return FAILED;
 
-	spin_lock_irqsave(scmd->device->host->host_lock, flags);
 	rtn = scmd->device->host->hostt->eh_device_reset_handler(scmd);
-	spin_unlock_irqrestore(scmd->device->host->host_lock, flags);
-
 	if (rtn == SUCCESS) {
 		scmd->device->was_reset = 1;
 		scmd->device->expecting_cc_ua = 1;
@@ -896,6 +861,7 @@ static int scsi_eh_try_stu(struct scsi_c
 {
 	static unsigned char stu_command[6] = {START_STOP, 0, 0, 0, 1, 0};
 	int rtn;
+	int saved_result;
 
 	if (!scmd->device->allow_restart)
 		return 1;
@@ -908,6 +874,7 @@ static int scsi_eh_try_stu(struct scsi_c
 	 */
 	memset(scmd->sense_buffer, 0, sizeof(scmd->sense_buffer));
 
+	saved_result = scmd->result;
 	scmd->request_buffer = NULL;
 	scmd->request_bufflen = 0;
 	scmd->use_sg = 0;
@@ -922,6 +889,7 @@ static int scsi_eh_try_stu(struct scsi_c
 	 * the original request, so let's restore the original data. (db)
 	 */
 	scsi_setup_cmd_retry(scmd);
+	scmd->result = saved_result;
 
 	/*
 	 * hey, we are done.  let's look to see what happened.
@@ -946,8 +914,7 @@ static int scsi_eh_stu(struct Scsi_Host 
 			      struct list_head *work_q,
 			      struct list_head *done_q)
 {
-	struct list_head *lh, *lh_sf;
-	struct scsi_cmnd *scmd, *stu_scmd;
+	struct scsi_cmnd *scmd, *stu_scmd, *next;
 	struct scsi_device *sdev;
 
 	shost_for_each_device(sdev, shost) {
@@ -968,8 +935,8 @@ static int scsi_eh_stu(struct Scsi_Host 
 		if (!scsi_eh_try_stu(stu_scmd)) {
 			if (!scsi_device_online(sdev) ||
 			    !scsi_eh_tur(stu_scmd)) {
-				list_for_each_safe(lh, lh_sf, work_q) {
-					scmd = list_entry(lh, struct scsi_cmnd, eh_entry);
+				list_for_each_entry_safe(scmd, next,
+							  work_q, eh_entry) {
 					if (scmd->device == sdev)
 						scsi_eh_finish_cmd(scmd, done_q);
 				}
@@ -1000,8 +967,7 @@ static int scsi_eh_bus_device_reset(stru
 				    struct list_head *work_q,
 				    struct list_head *done_q)
 {
-	struct list_head *lh, *lh_sf;
-	struct scsi_cmnd *scmd, *bdr_scmd;
+	struct scsi_cmnd *scmd, *bdr_scmd, *next;
 	struct scsi_device *sdev;
 	int rtn;
 
@@ -1023,11 +989,8 @@ static int scsi_eh_bus_device_reset(stru
 		if (rtn == SUCCESS) {
 			if (!scsi_device_online(sdev) ||
 			    !scsi_eh_tur(bdr_scmd)) {
-				list_for_each_safe(lh, lh_sf,
-						   work_q) {
-					scmd = list_entry(lh, struct
-							  scsi_cmnd,
-							  eh_entry);
+				list_for_each_entry_safe(scmd, next,
+							 work_q, eh_entry) {
 					if (scmd->device == sdev)
 						scsi_eh_finish_cmd(scmd,
 								   done_q);
@@ -1056,14 +1019,11 @@ static int scsi_try_bus_reset(struct scs
 
 	SCSI_LOG_ERROR_RECOVERY(3, printk("%s: Snd Bus RST\n",
 					  __FUNCTION__));
-	scmd->owner = SCSI_OWNER_LOWLEVEL;
 
 	if (!scmd->device->host->hostt->eh_bus_reset_handler)
 		return FAILED;
 
-	spin_lock_irqsave(scmd->device->host->host_lock, flags);
 	rtn = scmd->device->host->hostt->eh_bus_reset_handler(scmd);
-	spin_unlock_irqrestore(scmd->device->host->host_lock, flags);
 
 	if (rtn == SUCCESS) {
 		if (!scmd->device->host->hostt->skip_settle_delay)
@@ -1087,14 +1047,11 @@ static int scsi_try_host_reset(struct sc
 
 	SCSI_LOG_ERROR_RECOVERY(3, printk("%s: Snd Host RST\n",
 					  __FUNCTION__));
-	scmd->owner = SCSI_OWNER_LOWLEVEL;
 
 	if (!scmd->device->host->hostt->eh_host_reset_handler)
 		return FAILED;
 
-	spin_lock_irqsave(scmd->device->host->host_lock, flags);
 	rtn = scmd->device->host->hostt->eh_host_reset_handler(scmd);
-	spin_unlock_irqrestore(scmd->device->host->host_lock, flags);
 
 	if (rtn == SUCCESS) {
 		if (!scmd->device->host->hostt->skip_settle_delay)
@@ -1116,9 +1073,7 @@ static int scsi_eh_bus_reset(struct Scsi
 			     struct list_head *work_q,
 			     struct list_head *done_q)
 {
-	struct list_head *lh, *lh_sf;
-	struct scsi_cmnd *scmd;
-	struct scsi_cmnd *chan_scmd;
+	struct scsi_cmnd *scmd, *chan_scmd, *next;
 	unsigned int channel;
 	int rtn;
 
@@ -1149,9 +1104,7 @@ static int scsi_eh_bus_reset(struct Scsi
 						  channel));
 		rtn = scsi_try_bus_reset(chan_scmd);
 		if (rtn == SUCCESS) {
-			list_for_each_safe(lh, lh_sf, work_q) {
-				scmd = list_entry(lh, struct scsi_cmnd,
-						  eh_entry);
+			list_for_each_entry_safe(scmd, next, work_q, eh_entry) {
 				if (channel == scmd->device->channel)
 					if (!scsi_device_online(scmd->device) ||
 					    !scsi_eh_tur(scmd))
@@ -1176,9 +1129,8 @@ static int scsi_eh_bus_reset(struct Scsi
 static int scsi_eh_host_reset(struct list_head *work_q,
 			      struct list_head *done_q)
 {
+	struct scsi_cmnd *scmd, *next;
 	int rtn;
-	struct list_head *lh, *lh_sf;
-	struct scsi_cmnd *scmd;
 
 	if (!list_empty(work_q)) {
 		scmd = list_entry(work_q->next,
@@ -1189,8 +1141,7 @@ static int scsi_eh_host_reset(struct lis
 
 		rtn = scsi_try_host_reset(scmd);
 		if (rtn == SUCCESS) {
-			list_for_each_safe(lh, lh_sf, work_q) {
-				scmd = list_entry(lh, struct scsi_cmnd, eh_entry);
+			list_for_each_entry_safe(scmd, next, work_q, eh_entry) {
 				if (!scsi_device_online(scmd->device) ||
 				    (!scsi_eh_try_stu(scmd) && !scsi_eh_tur(scmd)) ||
 				    !scsi_eh_tur(scmd))
@@ -1214,11 +1165,9 @@ static int scsi_eh_host_reset(struct lis
 static void scsi_eh_offline_sdevs(struct list_head *work_q,
 				  struct list_head *done_q)
 {
-	struct list_head *lh, *lh_sf;
-	struct scsi_cmnd *scmd;
+	struct scsi_cmnd *scmd, *next;
 
-	list_for_each_safe(lh, lh_sf, work_q) {
-		scmd = list_entry(lh, struct scsi_cmnd, eh_entry);
+	list_for_each_entry_safe(scmd, next, work_q, eh_entry) {
 		printk(KERN_INFO "scsi: Device offlined - not"
 		       		" ready after error recovery: host"
 				" %d channel %d id %d lun %d\n",
@@ -1227,7 +1176,7 @@ static void scsi_eh_offline_sdevs(struct
 				scmd->device->id,
 				scmd->device->lun);
 		scsi_device_set_state(scmd->device, SDEV_OFFLINE);
-		if (scsi_eh_eflags_chk(scmd, SCSI_EH_CANCEL_CMD)) {
+		if (scmd->eh_eflags & SCSI_EH_CANCEL_CMD) {
 			/*
 			 * FIXME: Handle lost cmds.
 			 */
@@ -1546,12 +1495,10 @@ static void scsi_eh_ready_devs(struct Sc
  **/
 static void scsi_eh_flush_done_q(struct list_head *done_q)
 {
-	struct list_head *lh, *lh_sf;
-	struct scsi_cmnd *scmd;
+	struct scsi_cmnd *scmd, *next;
 
-	list_for_each_safe(lh, lh_sf, done_q) {
-		scmd = list_entry(lh, struct scsi_cmnd, eh_entry);
-		list_del_init(lh);
+	list_for_each_entry_safe(scmd, next, done_q, eh_entry) {
+		list_del_init(&scmd->eh_entry);
 		if (scsi_device_online(scmd->device) &&
 		    !blk_noretry_request(scmd->request) &&
 		    (++scmd->retries < scmd->allowed)) {
@@ -1561,6 +1508,11 @@ static void scsi_eh_flush_done_q(struct 
 							  scmd));
 				scsi_queue_insert(scmd, SCSI_MLQUEUE_EH_RETRY);
 		} else {
+			/*
+			 * If just we got sense for the device (called
+			 * scsi_eh_get_sense), scmd->result is already
+			 * set, do not set DRIVER_TIMEOUT.
+			 */
 			if (!scmd->result)
 				scmd->result |= (DRIVER_TIMEOUT << 24);
 			SCSI_LOG_ERROR_RECOVERY(3, printk("%s: flush finish"
@@ -1825,9 +1777,7 @@ scsi_reset_provider(struct scsi_device *
 	scmd->request = &req;
 	memset(&scmd->eh_timeout, 0, sizeof(scmd->eh_timeout));
 	scmd->request->rq_status      	= RQ_SCSI_BUSY;
-	scmd->state                   	= SCSI_STATE_INITIALIZING;
-	scmd->owner	     		= SCSI_OWNER_MIDLEVEL;
-    
+
 	memset(&scmd->cmnd, '\0', sizeof(scmd->cmnd));
     
 	scmd->scsi_done		= scsi_reset_provider_done_command;
@@ -1836,7 +1786,6 @@ scsi_reset_provider(struct scsi_device *
 	scmd->bufflen			= 0;
 	scmd->request_buffer		= NULL;
 	scmd->request_bufflen		= 0;
-	scmd->abort_reason		= DID_ABORT;
 
 	scmd->cmd_len			= 0;
 
@@ -1870,7 +1819,6 @@ scsi_reset_provider(struct scsi_device *
 		rtn = FAILED;
 	}
 
-	scsi_delete_timer(scmd);
 	scsi_next_command(scmd);
 	return rtn;
 }
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -44,7 +44,7 @@ struct scsi_host_sg_pool {
 #endif
 
 #define SP(x) { x, "sgpool-" #x } 
-struct scsi_host_sg_pool scsi_sg_pools[] = { 
+static struct scsi_host_sg_pool scsi_sg_pools[] = {
 	SP(8),
 	SP(16),
 	SP(32),
@@ -92,10 +92,12 @@ int scsi_insert_special_req(struct scsi_
 	 */
 	sreq->sr_request->flags &= ~REQ_DONTPREP;
 	blk_insert_request(sreq->sr_device->request_queue, sreq->sr_request,
-		       	   at_head, sreq, 0);
+		       	   at_head, sreq);
 	return 0;
 }
 
+static void scsi_run_queue(struct request_queue *q);
+
 /*
  * Function:    scsi_queue_insert()
  *
@@ -119,18 +121,14 @@ int scsi_queue_insert(struct scsi_cmnd *
 {
 	struct Scsi_Host *host = cmd->device->host;
 	struct scsi_device *device = cmd->device;
+	struct request_queue *q = device->request_queue;
+	unsigned long flags;
 
 	SCSI_LOG_MLQUEUE(1,
 		 printk("Inserting command %p into mlqueue\n", cmd));
 
 	/*
-	 * We are inserting the command into the ml queue.  First, we
-	 * cancel the timer, so it doesn't time out.
-	 */
-	scsi_delete_timer(cmd);
-
-	/*
-	 * Next, set the appropriate busy bit for the device/host.
+	 * Set the appropriate busy bit for the device/host.
 	 *
 	 * If the host/device isn't busy, assume that something actually
 	 * completed, and that we should be able to queue a command now.
@@ -148,29 +146,28 @@ int scsi_queue_insert(struct scsi_cmnd *
 		device->device_blocked = device->max_device_blocked;
 
 	/*
-	 * Register the fact that we own the thing for now.
-	 */
-	cmd->state = SCSI_STATE_MLQUEUE;
-	cmd->owner = SCSI_OWNER_MIDLEVEL;
-
-	/*
 	 * Decrement the counters, since these commands are no longer
 	 * active on the host/device.
 	 */
 	scsi_device_unbusy(device);
 
 	/*
-	 * Insert this command at the head of the queue for it's device.
-	 * It will go before all other commands that are already in the queue.
+	 * Requeue this command.  It will go before all other commands
+	 * that are already in the queue.
 	 *
 	 * NOTE: there is magic here about the way the queue is plugged if
 	 * we have no outstanding commands.
 	 * 
-	 * Although this *doesn't* plug the queue, it does call the request
+	 * Although we *don't* plug the queue, we call the request
 	 * function.  The SCSI request function detects the blocked condition
 	 * and plugs the queue appropriately.
-	 */
-	blk_insert_request(device->request_queue, cmd->request, 1, cmd, 1);
+         */
+	spin_lock_irqsave(q->queue_lock, flags);
+	blk_requeue_request(q, cmd->request);
+	spin_unlock_irqrestore(q->queue_lock, flags);
+
+	scsi_run_queue(q);
+
 	return 0;
 }
 
@@ -296,9 +293,7 @@ EXPORT_SYMBOL(scsi_wait_req);
  */
 static int scsi_init_cmd_errh(struct scsi_cmnd *cmd)
 {
-	cmd->owner = SCSI_OWNER_MIDLEVEL;
 	cmd->serial_number = 0;
-	cmd->abort_reason = 0;
 
 	memset(cmd->sense_buffer, 0, sizeof cmd->sense_buffer);
 
@@ -319,7 +314,6 @@ static int scsi_init_cmd_errh(struct scs
 	memcpy(cmd->data_cmnd, cmd->cmnd, sizeof(cmd->cmnd));
 	cmd->buffer = cmd->request_buffer;
 	cmd->bufflen = cmd->request_bufflen;
-	cmd->abort_reason = 0;
 
 	return 1;
 }
@@ -485,8 +479,13 @@ static void scsi_run_queue(struct reques
  */
 static void scsi_requeue_command(struct request_queue *q, struct scsi_cmnd *cmd)
 {
+	unsigned long flags;
+
 	cmd->request->flags &= ~REQ_DONTPREP;
-	blk_insert_request(q, cmd->request, 1, cmd, 1);
+
+	spin_lock_irqsave(q->queue_lock, flags);
+	blk_requeue_request(q, cmd->request);
+	spin_unlock_irqrestore(q->queue_lock, flags);
 
 	scsi_run_queue(q);
 }
@@ -615,8 +614,6 @@ static struct scatterlist *scsi_alloc_sg
 
 	sgp = scsi_sg_pools + cmd->sglist_len;
 	sgl = mempool_alloc(sgp->pool, gfp_mask);
-	if (sgl)
-		memset(sgl, 0, sgp->size);
 	return sgl;
 }
 
@@ -624,7 +621,7 @@ static void scsi_free_sgtable(struct sca
 {
 	struct scsi_host_sg_pool *sgp;
 
-	BUG_ON(index > SG_MEMPOOL_NR);
+	BUG_ON(index >= SG_MEMPOOL_NR);
 
 	sgp = scsi_sg_pools + index;
 	mempool_free(sgl, sgp->pool);
@@ -941,10 +938,8 @@ static int scsi_init_io(struct scsi_cmnd
 	 * if sg table allocation fails, requeue request later.
 	 */
 	sgpnt = scsi_alloc_sgtable(cmd, GFP_ATOMIC);
-	if (unlikely(!sgpnt)) {
-		req->flags |= REQ_SPECIAL;
+	if (unlikely(!sgpnt))
 		return BLKPREP_DEFER;
-	}
 
 	cmd->request_buffer = (char *) sgpnt;
 	cmd->request_bufflen = req->nr_sectors << 9;
diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h
--- a/drivers/scsi/scsi_priv.h
+++ b/drivers/scsi/scsi_priv.h
@@ -13,17 +13,6 @@ struct Scsi_Host;
 
 
 /*
- * These are the values that the owner field can take.
- * They are used as an indication of who the command belongs to.
- */
-#define SCSI_OWNER_HIGHLEVEL      0x100
-#define SCSI_OWNER_MIDLEVEL       0x101
-#define SCSI_OWNER_LOWLEVEL       0x102
-#define SCSI_OWNER_ERROR_HANDLER  0x103
-#define SCSI_OWNER_BH_HANDLER     0x104
-#define SCSI_OWNER_NOBODY         0x105
-
-/*
  * Magic values for certain scsi structs. Shouldn't ever be used.
  */
 #define SCSI_CMND_MAGIC		0xE25C23A5
@@ -32,15 +21,6 @@ struct Scsi_Host;
 /*
  * Scsi Error Handler Flags
  */
-#define scsi_eh_eflags_chk(scp, flags) \
-	((scp)->eh_eflags & (flags))
-#define scsi_eh_eflags_set(scp, flags) \
-	do { (scp)->eh_eflags |= (flags); } while(0)
-#define scsi_eh_eflags_clr(scp, flags) \
-	do { (scp)->eh_eflags &= ~(flags); } while(0)
-#define scsi_eh_eflags_clr_all(scp) \
-	(scp->eh_eflags = 0)
-
 #define SCSI_EH_CANCEL_CMD	0x0001	/* Cancel this cmd */
 #define SCSI_EH_REC_TIMEOUT	0x0002	/* EH retry timed out */
 
@@ -61,8 +41,6 @@ extern void scsi_exit_hosts(void);
 extern int scsi_dispatch_cmd(struct scsi_cmnd *cmd);
 extern int scsi_setup_command_freelist(struct Scsi_Host *shost);
 extern void scsi_destroy_command_freelist(struct Scsi_Host *shost);
-extern void scsi_done(struct scsi_cmnd *cmd);
-extern int scsi_retry_command(struct scsi_cmnd *cmd);
 extern int scsi_insert_special_req(struct scsi_request *sreq, int);
 extern void scsi_init_cmd_from_req(struct scsi_cmnd *cmd,
 		struct scsi_request *sreq);
@@ -136,7 +114,6 @@ extern void scsi_exit_sysctl(void);
 #endif /* CONFIG_SYSCTL */
 
 /* scsi_sysfs.c */
-extern void scsi_device_dev_release(struct device *);
 extern int scsi_sysfs_add_sdev(struct scsi_device *);
 extern int scsi_sysfs_add_host(struct Scsi_Host *);
 extern int scsi_sysfs_register(void);
@@ -145,7 +122,6 @@ extern void scsi_sysfs_device_initialize
 extern int scsi_sysfs_target_initialize(struct scsi_device *);
 extern struct scsi_transport_template blank_transport_template;
 
-extern struct class sdev_class;
 extern struct bus_type scsi_bus_type;
 
 /* 
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -293,6 +293,10 @@ static void scsi_target_dev_release(stru
 {
 	struct device *parent = dev->parent;
 	struct scsi_target *starget = to_scsi_target(dev);
+	struct Scsi_Host *shost = dev_to_shost(parent);
+
+	if (shost->hostt->target_destroy)
+		shost->hostt->target_destroy(starget);
 	kfree(starget);
 	put_device(parent);
 }
@@ -332,9 +336,23 @@ static struct scsi_target *scsi_alloc_ta
 	unsigned long flags;
 	const int size = sizeof(struct scsi_target)
 		+ shost->transportt->target_size;
-	struct scsi_target *starget = kmalloc(size, GFP_ATOMIC);
+	struct scsi_target *starget;
 	struct scsi_target *found_target;
 
+	/*
+	 * Obtain the real parent from the transport. The transport
+	 * is allowed to fail (no error) if there is nothing at that
+	 * target id.
+	 */
+	if (shost->transportt->target_parent) {
+		spin_lock_irqsave(shost->host_lock, flags);
+		parent = shost->transportt->target_parent(shost, channel, id);
+		spin_unlock_irqrestore(shost->host_lock, flags);
+		if (!parent)
+			return NULL;
+	}
+
+	starget = kmalloc(size, GFP_KERNEL);
 	if (!starget) {
 		printk(KERN_ERR "%s: allocation failure\n", __FUNCTION__);
 		return NULL;
@@ -360,9 +378,23 @@ static struct scsi_target *scsi_alloc_ta
 	list_add_tail(&starget->siblings, &shost->__targets);
 	spin_unlock_irqrestore(shost->host_lock, flags);
 	/* allocate and add */
-	transport_setup_device(&starget->dev);
-	device_add(&starget->dev);
-	transport_add_device(&starget->dev);
+	transport_setup_device(dev);
+	device_add(dev);
+	transport_add_device(dev);
+	if (shost->hostt->target_alloc) {
+		int error = shost->hostt->target_alloc(starget);
+
+		if(error) {
+			dev_printk(KERN_ERR, dev, "target allocation failed, error %d\n", error);
+			/* don't want scsi_target_reap to do the final
+			 * put because it will be under the host lock */
+			get_device(dev);
+			scsi_target_reap(starget);
+			put_device(dev);
+			return NULL;
+		}
+	}
+
 	return starget;
 
  found:
@@ -625,6 +657,7 @@ static int scsi_add_lun(struct scsi_devi
 	case TYPE_MEDIUM_CHANGER:
 	case TYPE_ENCLOSURE:
 	case TYPE_COMM:
+	case TYPE_RBC:
 		sdev->writeable = 1;
 		break;
 	case TYPE_WORM:
@@ -737,7 +770,8 @@ static int scsi_add_lun(struct scsi_devi
 	 * register it and tell the rest of the kernel
 	 * about it.
 	 */
-	scsi_sysfs_add_sdev(sdev);
+	if (scsi_sysfs_add_sdev(sdev) != 0)
+		return SCSI_SCAN_NO_RESPONSE;
 
 	return SCSI_SCAN_LUN_PRESENT;
 }
@@ -981,6 +1015,38 @@ static int scsilun_to_int(struct scsi_lu
 }
 
 /**
+ * int_to_scsilun: reverts an int into a scsi_lun
+ * @int:        integer to be reverted
+ * @scsilun:	struct scsi_lun to be set.
+ *
+ * Description:
+ *     Reverts the functionality of the scsilun_to_int, which packed
+ *     an 8-byte lun value into an int. This routine unpacks the int
+ *     back into the lun value.
+ *     Note: the scsilun_to_int() routine does not truly handle all
+ *     8bytes of the lun value. This functions restores only as much
+ *     as was set by the routine.
+ *
+ * Notes:
+ *     Given an integer : 0x0b030a04,  this function returns a
+ *     scsi_lun of : struct scsi_lun of: 0a 04 0b 03 00 00 00 00
+ *
+ **/
+void int_to_scsilun(unsigned int lun, struct scsi_lun *scsilun)
+{
+	int i;
+
+	memset(scsilun->scsi_lun, 0, sizeof(scsilun->scsi_lun));
+
+	for (i = 0; i < sizeof(lun); i += 2) {
+		scsilun->scsi_lun[i] = (lun >> 8) & 0xFF;
+		scsilun->scsi_lun[i+1] = lun & 0xFF;
+		lun = lun >> 16;
+	}
+}
+EXPORT_SYMBOL(int_to_scsilun);
+
+/**
  * scsi_report_lun_scan - Scan using SCSI REPORT LUN results
  * @sdevscan:	scan the host, channel, and id of this Scsi_Device
  *
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
--- a/drivers/scsi/scsi_sysfs.c
+++ b/drivers/scsi/scsi_sysfs.c
@@ -150,7 +150,7 @@ static void scsi_device_cls_release(stru
 	put_device(&sdev->sdev_gendev);
 }
 
-void scsi_device_dev_release(struct device *dev)
+static void scsi_device_dev_release(struct device *dev)
 {
 	struct scsi_device *sdev;
 	struct device *parent;
@@ -185,7 +185,7 @@ void scsi_device_dev_release(struct devi
 		put_device(parent);
 }
 
-struct class sdev_class = {
+static struct class sdev_class = {
 	.name		= "scsi_device",
 	.release	= scsi_device_cls_release,
 };
@@ -230,7 +230,7 @@ void scsi_sysfs_unregister(void)
  */
 #define sdev_show_function(field, format_string)				\
 static ssize_t								\
-sdev_show_##field (struct device *dev, char *buf)				\
+sdev_show_##field (struct device *dev, struct device_attribute *attr, char *buf)				\
 {									\
 	struct scsi_device *sdev;					\
 	sdev = to_scsi_device(dev);					\
@@ -254,7 +254,7 @@ static DEVICE_ATTR(field, S_IRUGO, sdev_
 	sdev_show_function(field, format_string)				\
 									\
 static ssize_t								\
-sdev_store_##field (struct device *dev, const char *buf, size_t count)	\
+sdev_store_##field (struct device *dev, struct device_attribute *attr, const char *buf, size_t count)	\
 {									\
 	struct scsi_device *sdev;					\
 	sdev = to_scsi_device(dev);					\
@@ -274,7 +274,7 @@ static DEVICE_ATTR(field, S_IRUGO | S_IW
 	sdev_show_function(field, "%d\n")					\
 									\
 static ssize_t								\
-sdev_store_##field (struct device *dev, const char *buf, size_t count)	\
+sdev_store_##field (struct device *dev, struct device_attribute *attr, const char *buf, size_t count)	\
 {									\
 	int ret;							\
 	struct scsi_device *sdev;					\
@@ -317,7 +317,7 @@ sdev_rd_attr (model, "%.16s\n");
 sdev_rd_attr (rev, "%.4s\n");
 
 static ssize_t
-sdev_show_timeout (struct device *dev, char *buf)
+sdev_show_timeout (struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct scsi_device *sdev;
 	sdev = to_scsi_device(dev);
@@ -325,7 +325,7 @@ sdev_show_timeout (struct device *dev, c
 }
 
 static ssize_t
-sdev_store_timeout (struct device *dev, const char *buf, size_t count)
+sdev_store_timeout (struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct scsi_device *sdev;
 	int timeout;
@@ -337,14 +337,14 @@ sdev_store_timeout (struct device *dev, 
 static DEVICE_ATTR(timeout, S_IRUGO | S_IWUSR, sdev_show_timeout, sdev_store_timeout);
 
 static ssize_t
-store_rescan_field (struct device *dev, const char *buf, size_t count) 
+store_rescan_field (struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	scsi_rescan_device(dev);
 	return count;
 }
 static DEVICE_ATTR(rescan, S_IWUSR, NULL, store_rescan_field);
 
-static ssize_t sdev_store_delete(struct device *dev, const char *buf,
+static ssize_t sdev_store_delete(struct device *dev, struct device_attribute *attr, const char *buf,
 				 size_t count)
 {
 	scsi_remove_device(to_scsi_device(dev));
@@ -353,7 +353,7 @@ static ssize_t sdev_store_delete(struct 
 static DEVICE_ATTR(delete, S_IWUSR, NULL, sdev_store_delete);
 
 static ssize_t
-store_state_field(struct device *dev, const char *buf, size_t count)
+store_state_field(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	int i;
 	struct scsi_device *sdev = to_scsi_device(dev);
@@ -376,7 +376,7 @@ store_state_field(struct device *dev, co
 }
 
 static ssize_t
-show_state_field(struct device *dev, char *buf)
+show_state_field(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct scsi_device *sdev = to_scsi_device(dev);
 	const char *name = scsi_device_state_name(sdev->sdev_state);
@@ -390,7 +390,7 @@ show_state_field(struct device *dev, cha
 static DEVICE_ATTR(state, S_IRUGO | S_IWUSR, show_state_field, store_state_field);
 
 static ssize_t
-show_queue_type_field(struct device *dev, char *buf)
+show_queue_type_field(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct scsi_device *sdev = to_scsi_device(dev);
 	const char *name = "none";
@@ -406,7 +406,7 @@ show_queue_type_field(struct device *dev
 static DEVICE_ATTR(queue_type, S_IRUGO, show_queue_type_field, NULL);
 
 static ssize_t
-show_iostat_counterbits(struct device *dev, char *buf)
+show_iostat_counterbits(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	return snprintf(buf, 20, "%d\n", (int)sizeof(atomic_t) * 8);
 }
@@ -415,7 +415,7 @@ static DEVICE_ATTR(iocounterbits, S_IRUG
 
 #define show_sdev_iostat(field)						\
 static ssize_t								\
-show_iostat_##field(struct device *dev, char *buf)			\
+show_iostat_##field(struct device *dev, struct device_attribute *attr, char *buf)			\
 {									\
 	struct scsi_device *sdev = to_scsi_device(dev);			\
 	unsigned long long count = atomic_read(&sdev->field);		\
@@ -449,7 +449,7 @@ static struct device_attribute *scsi_sys
 	NULL
 };
 
-static ssize_t sdev_store_queue_depth_rw(struct device *dev, const char *buf,
+static ssize_t sdev_store_queue_depth_rw(struct device *dev, struct device_attribute *attr, const char *buf,
 					 size_t count)
 {
 	int depth, retval;
@@ -475,7 +475,7 @@ static struct device_attribute sdev_attr
 	__ATTR(queue_depth, S_IRUGO | S_IWUSR, sdev_show_queue_depth,
 	       sdev_store_queue_depth_rw);
 
-static ssize_t sdev_store_queue_type_rw(struct device *dev, const char *buf,
+static ssize_t sdev_store_queue_type_rw(struct device *dev, struct device_attribute *attr, const char *buf,
 					size_t count)
 {
 	struct scsi_device *sdev = to_scsi_device(dev);
@@ -669,6 +669,13 @@ void __scsi_remove_target(struct scsi_ta
 	scsi_target_reap(starget);
 }
 
+static int __remove_child (struct device * dev, void * data)
+{
+	if (scsi_is_target_device(dev))
+		__scsi_remove_target(to_scsi_target(dev));
+	return 0;
+}
+
 /**
  * scsi_remove_target - try to remove a target and all its devices
  * @dev: generic starget or parent of generic stargets to be removed
@@ -679,7 +686,7 @@ void __scsi_remove_target(struct scsi_ta
  */
 void scsi_remove_target(struct device *dev)
 {
-	struct device *rdev, *idev, *next;
+	struct device *rdev;
 
 	if (scsi_is_target_device(dev)) {
 		__scsi_remove_target(to_scsi_target(dev));
@@ -687,10 +694,7 @@ void scsi_remove_target(struct device *d
 	}
 
 	rdev = get_device(dev);
-	list_for_each_entry_safe(idev, next, &dev->children, node) {
-		if (scsi_is_target_device(idev))
-			__scsi_remove_target(to_scsi_target(idev));
-	}
+	device_for_each_child(dev, NULL, __remove_child);
 	put_device(rdev);
 }
 EXPORT_SYMBOL(scsi_remove_target);
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
--- a/drivers/scsi/scsi_transport_fc.c
+++ b/drivers/scsi/scsi_transport_fc.c
@@ -1022,6 +1022,23 @@ static int fc_rport_match(struct attribu
 	return &i->rport_attr_cont.ac == cont;
 }
 
+
+/*
+ * Must be called with shost->host_lock held
+ */
+static struct device *fc_target_parent(struct Scsi_Host *shost,
+					int channel, uint id)
+{
+	struct fc_rport *rport;
+
+	list_for_each_entry(rport, &fc_host_rports(shost), peers)
+		if ((rport->channel == channel) &&
+		    (rport->scsi_target_id == id))
+			return &rport->dev;
+
+	return NULL;
+}
+
 struct scsi_transport_template *
 fc_attach_transport(struct fc_function_template *ft)
 {
@@ -1057,6 +1074,8 @@ fc_attach_transport(struct fc_function_t
 
 	/* Transport uses the shost workq for scsi scanning */
 	i->t.create_work_queue = 1;
+
+	i->t.target_parent = fc_target_parent;
 	
 	/*
 	 * Setup SCSI Target Attributes.
diff --git a/drivers/scsi/scsi_transport_spi.c b/drivers/scsi/scsi_transport_spi.c
--- a/drivers/scsi/scsi_transport_spi.c
+++ b/drivers/scsi/scsi_transport_spi.c
@@ -348,17 +348,21 @@ spi_transport_rd_attr(rd_strm, "%d\n");
 spi_transport_rd_attr(rti, "%d\n");
 spi_transport_rd_attr(pcomp_en, "%d\n");
 
+/* we only care about the first child device so we return 1 */
+static int child_iter(struct device *dev, void *data)
+{
+	struct scsi_device *sdev = to_scsi_device(dev);
+
+	spi_dv_device(sdev);
+	return 1;
+}
+
 static ssize_t
 store_spi_revalidate(struct class_device *cdev, const char *buf, size_t count)
 {
 	struct scsi_target *starget = transport_class_to_starget(cdev);
 
-	/* FIXME: we're relying on an awful lot of device internals
-	 * here.  We really need a function to get the first available
-	 * child */
-	struct device *dev = container_of(starget->dev.children.next, struct device, node);
-	struct scsi_device *sdev = to_scsi_device(dev);
-	spi_dv_device(sdev);
+	device_for_each_child(&starget->dev, NULL, child_iter);
 	return count;
 }
 static CLASS_DEVICE_ATTR(revalidate, S_IWUSR, NULL, store_spi_revalidate);
@@ -669,6 +673,7 @@ spi_dv_retrain(struct scsi_request *sreq
 {
 	struct spi_internal *i = to_spi_internal(sreq->sr_host->transportt);
 	struct scsi_device *sdev = sreq->sr_device;
+	struct scsi_target *starget = sdev->sdev_target;
 	int period = 0, prevperiod = 0; 
 	enum spi_compare_returns retval;
 
@@ -682,24 +687,40 @@ spi_dv_retrain(struct scsi_request *sreq
 			break;
 
 		/* OK, retrain, fallback */
+		if (i->f->get_iu)
+			i->f->get_iu(starget);
+		if (i->f->get_qas)
+			i->f->get_qas(starget);
 		if (i->f->get_period)
 			i->f->get_period(sdev->sdev_target);
-		newperiod = spi_period(sdev->sdev_target);
-		period = newperiod > period ? newperiod : period;
-		if (period < 0x0d)
-			period++;
-		else
-			period += period >> 1;
-
-		if (unlikely(period > 0xff || period == prevperiod)) {
-			/* Total failure; set to async and return */
-			SPI_PRINTK(sdev->sdev_target, KERN_ERR, "Domain Validation Failure, dropping back to Asynchronous\n");
-			DV_SET(offset, 0);
-			return SPI_COMPARE_FAILURE;
+
+		/* Here's the fallback sequence; first try turning off
+		 * IU, then QAS (if we can control them), then finally
+		 * fall down the periods */
+		if (i->f->set_iu && spi_iu(starget)) {
+			SPI_PRINTK(starget, KERN_ERR, "Domain Validation Disabing Information Units\n");
+			DV_SET(iu, 0);
+		} else if (i->f->set_qas && spi_qas(starget)) {
+			SPI_PRINTK(starget, KERN_ERR, "Domain Validation Disabing Quick Arbitration and Selection\n");
+			DV_SET(qas, 0);
+		} else {
+			newperiod = spi_period(starget);
+			period = newperiod > period ? newperiod : period;
+			if (period < 0x0d)
+				period++;
+			else
+				period += period >> 1;
+
+			if (unlikely(period > 0xff || period == prevperiod)) {
+				/* Total failure; set to async and return */
+				SPI_PRINTK(starget, KERN_ERR, "Domain Validation Failure, dropping back to Asynchronous\n");
+				DV_SET(offset, 0);
+				return SPI_COMPARE_FAILURE;
+			}
+			SPI_PRINTK(starget, KERN_ERR, "Domain Validation detected failure, dropping back\n");
+			DV_SET(period, period);
+			prevperiod = period;
 		}
-		SPI_PRINTK(sdev->sdev_target, KERN_ERR, "Domain Validation detected failure, dropping back\n");
-		DV_SET(period, period);
-		prevperiod = period;
 	}
 	return retval;
 }
@@ -768,23 +789,22 @@ spi_dv_device_internal(struct scsi_reque
 	
 	if (spi_dv_device_compare_inquiry(sreq, buffer, buffer, DV_LOOPS)
 	    != SPI_COMPARE_SUCCESS) {
-		SPI_PRINTK(sdev->sdev_target, KERN_ERR, "Domain Validation Initial Inquiry Failed\n");
+		SPI_PRINTK(starget, KERN_ERR, "Domain Validation Initial Inquiry Failed\n");
 		/* FIXME: should probably offline the device here? */
 		return;
 	}
 
 	/* test width */
-	if (i->f->set_width && spi_max_width(starget) && sdev->wdtr) {
-		i->f->set_width(sdev->sdev_target, 1);
-
-		printk("WIDTH IS %d\n", spi_max_width(starget));
+	if (i->f->set_width && spi_max_width(starget) &&
+	    scsi_device_wide(sdev)) {
+		i->f->set_width(starget, 1);
 
 		if (spi_dv_device_compare_inquiry(sreq, buffer,
 						   buffer + len,
 						   DV_LOOPS)
 		    != SPI_COMPARE_SUCCESS) {
-			SPI_PRINTK(sdev->sdev_target, KERN_ERR, "Wide Transfers Fail\n");
-			i->f->set_width(sdev->sdev_target, 0);
+			SPI_PRINTK(starget, KERN_ERR, "Wide Transfers Fail\n");
+			i->f->set_width(starget, 0);
 		}
 	}
 
@@ -792,14 +812,14 @@ spi_dv_device_internal(struct scsi_reque
 		return;
 
 	/* device can't handle synchronous */
-	if(!sdev->ppr && !sdev->sdtr)
+	if (!scsi_device_sync(sdev) && !scsi_device_dt(sdev))
 		return;
 
 	/* see if the device has an echo buffer.  If it does we can
 	 * do the SPI pattern write tests */
 
 	len = 0;
-	if (sdev->ppr)
+	if (scsi_device_dt(sdev))
 		len = spi_dv_device_get_echo_buffer(sreq, buffer);
 
  retry:
@@ -807,16 +827,32 @@ spi_dv_device_internal(struct scsi_reque
 	/* now set up to the maximum */
 	DV_SET(offset, spi_max_offset(starget));
 	DV_SET(period, spi_min_period(starget));
+	/* try QAS requests; this should be harmless to set if the
+	 * target supports it */
+	if (scsi_device_qas(sdev))
+		DV_SET(qas, 1);
+	/* Also try IU transfers */
+	if (scsi_device_ius(sdev))
+		DV_SET(iu, 1);
+	if (spi_min_period(starget) < 9) {
+		/* This u320 (or u640). Ignore the coupled parameters
+		 * like DT and IU, but set the optional ones */
+		DV_SET(rd_strm, 1);
+		DV_SET(wr_flow, 1);
+		DV_SET(rti, 1);
+		if (spi_min_period(starget) == 8)
+			DV_SET(pcomp_en, 1);
+	}
 
 	if (len == 0) {
-		SPI_PRINTK(sdev->sdev_target, KERN_INFO, "Domain Validation skipping write tests\n");
+		SPI_PRINTK(starget, KERN_INFO, "Domain Validation skipping write tests\n");
 		spi_dv_retrain(sreq, buffer, buffer + len,
 			       spi_dv_device_compare_inquiry);
 		return;
 	}
 
 	if (len > SPI_MAX_ECHO_BUFFER_SIZE) {
-		SPI_PRINTK(sdev->sdev_target, KERN_WARNING, "Echo buffer size %d is too big, trimming to %d\n", len, SPI_MAX_ECHO_BUFFER_SIZE);
+		SPI_PRINTK(starget, KERN_WARNING, "Echo buffer size %d is too big, trimming to %d\n", len, SPI_MAX_ECHO_BUFFER_SIZE);
 		len = SPI_MAX_ECHO_BUFFER_SIZE;
 	}
 
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -373,9 +373,6 @@ static int sd_init_command(struct scsi_c
 		SCpnt->cmnd[7] = (unsigned char) (this_count >> 8) & 0xff;
 		SCpnt->cmnd[8] = (unsigned char) this_count & 0xff;
 	} else {
-		if (this_count > 0xff)
-			this_count = 0xff;
-
 		SCpnt->cmnd[1] |= (unsigned char) ((block >> 16) & 0x1f);
 		SCpnt->cmnd[2] = (unsigned char) ((block >> 8) & 0xff);
 		SCpnt->cmnd[3] = (unsigned char) block & 0xff;
@@ -1368,17 +1365,26 @@ sd_read_write_protect_flag(struct scsi_d
  */
 static void
 sd_read_cache_type(struct scsi_disk *sdkp, char *diskname,
-		   struct scsi_request *SRpnt, unsigned char *buffer) {
+		   struct scsi_request *SRpnt, unsigned char *buffer)
+{
 	int len = 0, res;
 
-	const int dbd = 0;	   /* DBD */
-	const int modepage = 0x08; /* current values, cache page */
+	int dbd;
+	int modepage;
 	struct scsi_mode_data data;
 	struct scsi_sense_hdr sshdr;
 
 	if (sdkp->device->skip_ms_page_8)
 		goto defaults;
 
+	if (sdkp->device->type == TYPE_RBC) {
+		modepage = 6;
+		dbd = 8;
+	} else {
+		modepage = 8;
+		dbd = 0;
+	}
+
 	/* cautiously ask */
 	res = sd_do_mode_sense(SRpnt, dbd, modepage, buffer, 4, &data);
 
@@ -1409,11 +1415,20 @@ sd_read_cache_type(struct scsi_disk *sdk
 			"write back, no read (daft)"
 		};
 		int ct = 0;
-		int offset = data.header_length +
-			data.block_descriptor_length + 2;
+		int offset = data.header_length + data.block_descriptor_length;
+
+		if ((buffer[offset] & 0x3f) != modepage) {
+			printk(KERN_ERR "%s: got wrong page\n", diskname);
+			goto defaults;
+		}
 
-		sdkp->WCE = ((buffer[offset] & 0x04) != 0);
-		sdkp->RCD = ((buffer[offset] & 0x01) != 0);
+		if (modepage == 8) {
+			sdkp->WCE = ((buffer[offset + 2] & 0x04) != 0);
+			sdkp->RCD = ((buffer[offset + 2] & 0x01) != 0);
+		} else {
+			sdkp->WCE = ((buffer[offset + 2] & 0x01) == 0);
+			sdkp->RCD = 0;
+		}
 
 		ct =  sdkp->RCD + 2*sdkp->WCE;
 
@@ -1533,7 +1548,7 @@ static int sd_probe(struct device *dev)
 	int error;
 
 	error = -ENODEV;
-	if ((sdp->type != TYPE_DISK) && (sdp->type != TYPE_MOD))
+	if (sdp->type != TYPE_DISK && sdp->type != TYPE_MOD && sdp->type != TYPE_RBC)
 		goto out;
 
 	SCSI_LOG_HLQUEUE(3, printk("sd_attach: scsi device: <%d,%d,%d,%d>\n", 
@@ -1570,7 +1585,7 @@ static int sd_probe(struct device *dev)
 	sdkp->openers = 0;
 
 	if (!sdp->timeout) {
-		if (sdp->type == TYPE_DISK)
+		if (sdp->type != TYPE_MOD)
 			sdp->timeout = SD_TIMEOUT;
 		else
 			sdp->timeout = SD_MOD_TIMEOUT;
diff --git a/drivers/scsi/seagate.c b/drivers/scsi/seagate.c
--- a/drivers/scsi/seagate.c
+++ b/drivers/scsi/seagate.c
@@ -97,6 +97,7 @@
 #include <linux/delay.h>
 #include <linux/blkdev.h>
 #include <linux/stat.h>
+#include <linux/delay.h>
 
 #include <asm/io.h>
 #include <asm/system.h>
@@ -1631,7 +1632,7 @@ static int seagate_st0x_bus_reset(Scsi_C
 	/* assert  RESET signal on SCSI bus.  */
 	WRITE_CONTROL (BASE_CMD | CMD_RST);
 
-	udelay (20 * 1000);
+	mdelay (20);
 
 	WRITE_CONTROL (BASE_CMD);
 	st0x_aborted = DID_RESET;
@@ -1640,16 +1641,6 @@ static int seagate_st0x_bus_reset(Scsi_C
 	return SUCCESS;
 }
 
-static int seagate_st0x_host_reset(Scsi_Cmnd *SCpnt)
-{
-	return FAILED;
-}
-
-static int seagate_st0x_device_reset(Scsi_Cmnd *SCpnt)
-{
-	return FAILED;
-}
-
 static int seagate_st0x_release(struct Scsi_Host *shost)
 {
 	if (shost->irq)
@@ -1665,8 +1656,6 @@ static Scsi_Host_Template driver_templat
 	.queuecommand   	= seagate_st0x_queue_command,
 	.eh_abort_handler	= seagate_st0x_abort,
 	.eh_bus_reset_handler	= seagate_st0x_bus_reset,
-	.eh_host_reset_handler	= seagate_st0x_host_reset,
-	.eh_device_reset_handler = seagate_st0x_device_reset,
 	.can_queue      	= 1,
 	.this_id        	= 7,
 	.sg_tablesize   	= SG_ALL,
diff --git a/drivers/scsi/seagate.h b/drivers/scsi/seagate.h
--- a/drivers/scsi/seagate.h
+++ b/drivers/scsi/seagate.h
@@ -15,7 +15,5 @@ static int seagate_st0x_queue_command(Sc
 static int seagate_st0x_abort(Scsi_Cmnd *);
 static const char *seagate_st0x_info(struct Scsi_Host *);
 static int seagate_st0x_bus_reset(Scsi_Cmnd *);
-static int seagate_st0x_device_reset(Scsi_Cmnd *);
-static int seagate_st0x_host_reset(Scsi_Cmnd *);
 
 #endif /* _SEAGATE_H */
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -1430,7 +1430,7 @@ static struct file_operations sg_fops = 
 	.fasync = sg_fasync,
 };
 
-static struct class_simple * sg_sysfs_class;
+static struct class *sg_sysfs_class;
 
 static int sg_sysfs_valid = 0;
 
@@ -1551,13 +1551,13 @@ sg_add(struct class_device *cl_dev)
 	if (sg_sysfs_valid) {
 		struct class_device * sg_class_member;
 
-		sg_class_member = class_simple_device_add(sg_sysfs_class, 
+		sg_class_member = class_device_create(sg_sysfs_class,
 				MKDEV(SCSI_GENERIC_MAJOR, k), 
 				cl_dev->dev, "%s", 
 				disk->disk_name);
 		if (IS_ERR(sg_class_member))
 			printk(KERN_WARNING "sg_add: "
-				"class_simple_device_add failed\n");
+				"class_device_create failed\n");
 		class_set_devdata(sg_class_member, sdp);
 		error = sysfs_create_link(&scsidp->sdev_gendev.kobj, 
 					  &sg_class_member->kobj, "generic");
@@ -1636,7 +1636,7 @@ sg_remove(struct class_device *cl_dev)
 
 	if (sdp) {
 		sysfs_remove_link(&scsidp->sdev_gendev.kobj, "generic");
-		class_simple_device_remove(MKDEV(SCSI_GENERIC_MAJOR, k));
+		class_device_destroy(sg_sysfs_class, MKDEV(SCSI_GENERIC_MAJOR, k));
 		cdev_del(sdp->cdev);
 		sdp->cdev = NULL;
 		devfs_remove("%s/generic", scsidp->devfs_name);
@@ -1677,7 +1677,7 @@ init_sg(void)
 				    SG_MAX_DEVS, "sg");
 	if (rc)
 		return rc;
-        sg_sysfs_class = class_simple_create(THIS_MODULE, "scsi_generic");
+        sg_sysfs_class = class_create(THIS_MODULE, "scsi_generic");
         if ( IS_ERR(sg_sysfs_class) ) {
 		rc = PTR_ERR(sg_sysfs_class);
 		goto err_out;
@@ -1690,7 +1690,7 @@ init_sg(void)
 #endif				/* CONFIG_SCSI_PROC_FS */
 		return 0;
 	}
-	class_simple_destroy(sg_sysfs_class);
+	class_destroy(sg_sysfs_class);
 err_out:
 	unregister_chrdev_region(MKDEV(SCSI_GENERIC_MAJOR, 0), SG_MAX_DEVS);
 	return rc;
@@ -1703,7 +1703,7 @@ exit_sg(void)
 	sg_proc_cleanup();
 #endif				/* CONFIG_SCSI_PROC_FS */
 	scsi_unregister_interface(&sg_interface);
-	class_simple_destroy(sg_sysfs_class);
+	class_destroy(sg_sysfs_class);
 	sg_sysfs_valid = 0;
 	unregister_chrdev_region(MKDEV(SCSI_GENERIC_MAJOR, 0),
 				 SG_MAX_DEVS);
@@ -2472,6 +2472,8 @@ sg_remove_request(Sg_fd * sfp, Sg_reques
 	if ((!sfp) || (!srp) || (!sfp->headrp))
 		return res;
 	write_lock_irqsave(&sfp->rq_list_lock, iflags);
+	if (srp->my_cmdp)
+		srp->my_cmdp->upper_private_data = NULL;
 	prev_rp = sfp->headrp;
 	if (srp == prev_rp) {
 		sfp->headrp = prev_rp->nextrp;
@@ -2969,23 +2971,22 @@ static void * dev_seq_start(struct seq_f
 {
 	struct sg_proc_deviter * it = kmalloc(sizeof(*it), GFP_KERNEL);
 
+	s->private = it;
 	if (! it)
 		return NULL;
+
 	if (NULL == sg_dev_arr)
-		goto err1;
+		return NULL;
 	it->index = *pos;
 	it->max = sg_last_dev();
 	if (it->index >= it->max)
-		goto err1;
+		return NULL;
 	return it;
-err1:
-	kfree(it);
-	return NULL;
 }
 
 static void * dev_seq_next(struct seq_file *s, void *v, loff_t *pos)
 {
-	struct sg_proc_deviter * it = (struct sg_proc_deviter *) v;
+	struct sg_proc_deviter * it = s->private;
 
 	*pos = ++it->index;
 	return (it->index < it->max) ? it : NULL;
@@ -2993,7 +2994,7 @@ static void * dev_seq_next(struct seq_fi
 
 static void dev_seq_stop(struct seq_file *s, void *v)
 {
-	kfree (v);
+	kfree(s->private);
 }
 
 static int sg_proc_open_dev(struct inode *inode, struct file *file)
diff --git a/drivers/scsi/sgiwd93.c b/drivers/scsi/sgiwd93.c
--- a/drivers/scsi/sgiwd93.c
+++ b/drivers/scsi/sgiwd93.c
@@ -310,7 +310,14 @@ int sgiwd93_release(struct Scsi_Host *in
 static int sgiwd93_bus_reset(Scsi_Cmnd *cmd)
 {
 	/* FIXME perform bus-specific reset */
+
+	/* FIXME 2: kill this function, and let midlayer fallback
+	   to the same result, calling wd33c93_host_reset() */
+
+	spin_lock_irq(cmd->device->host->host_lock);
 	wd33c93_host_reset(cmd);
+	spin_unlock_irq(cmd->device->host->host_lock);
+
 	return SUCCESS;
 }
 
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -17,7 +17,7 @@
    Last modified: 18-JAN-1998 Richard Gooch <rgooch@atnf.csiro.au> Devfs support
  */
 
-static char *verstr = "20050312";
+static char *verstr = "20050501";
 
 #include <linux/module.h>
 
@@ -29,6 +29,7 @@ static char *verstr = "20050312";
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/mtio.h>
+#include <linux/cdrom.h>
 #include <linux/ioctl.h>
 #include <linux/fcntl.h>
 #include <linux/spinlock.h>
@@ -50,6 +51,7 @@ static char *verstr = "20050312";
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_ioctl.h>
 #include <scsi/scsi_request.h>
+#include <scsi/sg.h>
 
 
 /* The driver prints some debugging information on the console if DEBUG
@@ -82,7 +84,7 @@ static int try_wdio = 1;
 static int st_dev_max;
 static int st_nr_dev;
 
-static struct class_simple *st_sysfs_class;
+static struct class *st_sysfs_class;
 
 MODULE_AUTHOR("Kai Makisara");
 MODULE_DESCRIPTION("SCSI Tape Driver");
@@ -3463,7 +3465,10 @@ static int st_ioctl(struct inode *inode,
 		case SCSI_IOCTL_GET_BUS_NUMBER:
 			break;
 		default:
-			if (!capable(CAP_SYS_ADMIN))
+			if ((cmd_in == SG_IO ||
+			     cmd_in == SCSI_IOCTL_SEND_COMMAND ||
+			     cmd_in == CDROM_SEND_PACKET) &&
+			    !capable(CAP_SYS_RAWIO))
 				i = -EPERM;
 			else
 				i = scsi_cmd_ioctl(file, STp->disk, cmd_in, p);
@@ -3471,10 +3476,12 @@ static int st_ioctl(struct inode *inode,
 				return i;
 			break;
 	}
-	if (!capable(CAP_SYS_ADMIN) &&
-	    (cmd_in == SCSI_IOCTL_START_UNIT || cmd_in == SCSI_IOCTL_STOP_UNIT))
-		return -EPERM;
-	return scsi_ioctl(STp->device, cmd_in, p);
+	retval = scsi_ioctl(STp->device, cmd_in, p);
+	if (!retval && cmd_in == SCSI_IOCTL_STOP_UNIT) { /* unload */
+		STp->rew_at_close = 0;
+		STp->ready = ST_NO_TAPE;
+	}
+	return retval;
 
  out:
 	up(&STp->lock);
@@ -4017,8 +4024,9 @@ out_free_tape:
 			if (STm->cdevs[j]) {
 				if (cdev == STm->cdevs[j])
 					cdev = NULL;
-				class_simple_device_remove(MKDEV(SCSI_TAPE_MAJOR,
-								 TAPE_MINOR(i, mode, j)));
+				class_device_destroy(st_sysfs_class,
+						     MKDEV(SCSI_TAPE_MAJOR,
+							   TAPE_MINOR(i, mode, j)));
 				cdev_del(STm->cdevs[j]);
 			}
 		}
@@ -4061,8 +4069,9 @@ static int st_remove(struct device *dev)
 				devfs_remove("%s/mt%s", SDp->devfs_name, st_formats[j]);
 				devfs_remove("%s/mt%sn", SDp->devfs_name, st_formats[j]);
 				for (j=0; j < 2; j++) {
-					class_simple_device_remove(MKDEV(SCSI_TAPE_MAJOR,
-									 TAPE_MINOR(i, mode, j)));
+					class_device_destroy(st_sysfs_class,
+							     MKDEV(SCSI_TAPE_MAJOR,
+								   TAPE_MINOR(i, mode, j)));
 					cdev_del(tpnt->modes[mode].cdevs[j]);
 					tpnt->modes[mode].cdevs[j] = NULL;
 				}
@@ -4127,7 +4136,7 @@ static int __init init_st(void)
 		"st: Version %s, fixed bufsize %d, s/g segs %d\n",
 		verstr, st_fixed_buffer_size, st_max_sg_segs);
 
-	st_sysfs_class = class_simple_create(THIS_MODULE, "scsi_tape");
+	st_sysfs_class = class_create(THIS_MODULE, "scsi_tape");
 	if (IS_ERR(st_sysfs_class)) {
 		st_sysfs_class = NULL;
 		printk(KERN_ERR "Unable create sysfs class for SCSI tapes\n");
@@ -4140,12 +4149,10 @@ static int __init init_st(void)
 			do_create_driverfs_files();
 			return 0;
 		}
-		if (st_sysfs_class)
-			class_simple_destroy(st_sysfs_class);		
 		unregister_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
-
 					 ST_MAX_TAPE_ENTRIES);
 	}
+	class_destroy(st_sysfs_class);
 
 	printk(KERN_ERR "Unable to get major %d for SCSI tapes\n", SCSI_TAPE_MAJOR);
 	return 1;
@@ -4153,13 +4160,11 @@ static int __init init_st(void)
 
 static void __exit exit_st(void)
 {
-	if (st_sysfs_class)
-		class_simple_destroy(st_sysfs_class);
-	st_sysfs_class = NULL;
 	do_remove_driverfs_files();
 	scsi_unregister_driver(&st_template.gendrv);
 	unregister_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
 				 ST_MAX_TAPE_ENTRIES);
+	class_destroy(st_sysfs_class);
 	kfree(scsi_tapes);
 	printk(KERN_INFO "st: Unloaded.\n");
 }
@@ -4277,12 +4282,12 @@ static void do_create_class_files(struct
 		snprintf(name, 10, "%s%s%s", rew ? "n" : "",
 			 STp->disk->disk_name, st_formats[i]);
 		st_class_member =
-			class_simple_device_add(st_sysfs_class,
-						MKDEV(SCSI_TAPE_MAJOR,
-						      TAPE_MINOR(dev_num, mode, rew)),
-						&STp->device->sdev_gendev, "%s", name);
+			class_device_create(st_sysfs_class,
+					    MKDEV(SCSI_TAPE_MAJOR,
+						  TAPE_MINOR(dev_num, mode, rew)),
+					    &STp->device->sdev_gendev, "%s", name);
 		if (IS_ERR(st_class_member)) {
-			printk(KERN_WARNING "st%d: class_simple_device_add failed\n",
+			printk(KERN_WARNING "st%d: class_device_create failed\n",
 			       dev_num);
 			goto out;
 		}
diff --git a/drivers/scsi/sun3x_esp.c b/drivers/scsi/sun3x_esp.c
--- a/drivers/scsi/sun3x_esp.c
+++ b/drivers/scsi/sun3x_esp.c
@@ -23,8 +23,6 @@
 #include <asm/dvma.h>
 #include <asm/irq.h>
 
-extern struct NCR_ESP *espchain;
-
 static void dma_barrier(struct NCR_ESP *esp);
 static int  dma_bytes_sent(struct NCR_ESP *esp, int fifo_count);
 static int  dma_can_transfer(struct NCR_ESP *esp, Scsi_Cmnd *sp);
diff --git a/drivers/scsi/sym53c416.c b/drivers/scsi/sym53c416.c
--- a/drivers/scsi/sym53c416.c
+++ b/drivers/scsi/sym53c416.c
@@ -785,26 +785,14 @@ int sym53c416_queuecommand(Scsi_Cmnd *SC
 	return 0;
 }
 
-static int sym53c416_abort(Scsi_Cmnd *SCpnt)
-{
-	return FAILED;
-}
-
-static int sym53c416_bus_reset(Scsi_Cmnd *SCpnt)
-{
-	return FAILED;
-}
-
-static int sym53c416_device_reset(Scsi_Cmnd *SCpnt)
-{
-	return FAILED;
-}
-
 static int sym53c416_host_reset(Scsi_Cmnd *SCpnt)
 {
 	int base;
 	int scsi_id = -1;	
 	int i;
+	unsigned long flags;
+
+	spin_lock_irqsave(&sym53c416_lock, flags);
 
 	/* printk("sym53c416_reset\n"); */
 	base = SCpnt->device->host->io_port;
@@ -816,6 +804,8 @@ static int sym53c416_host_reset(Scsi_Cmn
 	outb(NOOP | PIO_MODE, base + COMMAND_REG);
 	outb(RESET_SCSI_BUS, base + COMMAND_REG);
 	sym53c416_init(base, scsi_id);
+
+	spin_unlock_irqrestore(&sym53c416_lock, flags);
 	return SUCCESS;
 }
 
@@ -865,10 +855,7 @@ static Scsi_Host_Template driver_templat
 	.detect =		sym53c416_detect,
 	.info =			sym53c416_info,	
 	.queuecommand =		sym53c416_queuecommand,
-	.eh_abort_handler =	sym53c416_abort,
 	.eh_host_reset_handler =sym53c416_host_reset,
-	.eh_bus_reset_handler = sym53c416_bus_reset,
-	.eh_device_reset_handler =sym53c416_device_reset,
 	.release = 		sym53c416_release,
 	.bios_param =		sym53c416_bios_param,
 	.can_queue =		1,
diff --git a/drivers/scsi/sym53c416.h b/drivers/scsi/sym53c416.h
--- a/drivers/scsi/sym53c416.h
+++ b/drivers/scsi/sym53c416.h
@@ -26,10 +26,7 @@ static int sym53c416_detect(Scsi_Host_Te
 static const char *sym53c416_info(struct Scsi_Host *);
 static int sym53c416_release(struct Scsi_Host *);
 static int sym53c416_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
-static int sym53c416_abort(Scsi_Cmnd *);
 static int sym53c416_host_reset(Scsi_Cmnd *);
-static int sym53c416_bus_reset(Scsi_Cmnd *);
-static int sym53c416_device_reset(Scsi_Cmnd *);
 static int sym53c416_bios_param(struct scsi_device *, struct block_device *,
 		sector_t, int *);
 static void sym53c416_setup(char *str, int *ints);
diff --git a/drivers/scsi/sym53c8xx_2/sym_defs.h b/drivers/scsi/sym53c8xx_2/sym_defs.h
--- a/drivers/scsi/sym53c8xx_2/sym_defs.h
+++ b/drivers/scsi/sym53c8xx_2/sym_defs.h
@@ -40,7 +40,7 @@
 #ifndef SYM_DEFS_H
 #define SYM_DEFS_H
 
-#define SYM_VERSION "2.2.0"
+#define SYM_VERSION "2.2.1"
 #define SYM_DRIVER_NAME	"sym-" SYM_VERSION
 
 /*
diff --git a/drivers/scsi/sym53c8xx_2/sym_glue.c b/drivers/scsi/sym53c8xx_2/sym_glue.c
--- a/drivers/scsi/sym53c8xx_2/sym_glue.c
+++ b/drivers/scsi/sym53c8xx_2/sym_glue.c
@@ -155,10 +155,11 @@ pci_get_base_address(struct pci_dev *pde
 	base = tmp;
 	if ((tmp & 0x7) == PCI_BASE_ADDRESS_MEM_TYPE_64) {
 		pci_read_config_dword(pdev, PCI_BAR_OFFSET(index++), &tmp);
-		if (tmp > 0)
+		if (tmp > 0) {
 			dev_err(&pdev->dev,
 				"BAR %d is 64-bit, disabling\n", index - 1);
-		base = 0;
+			base = 0;
+		}
 	}
 
 	if ((base & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO) {
@@ -389,13 +390,20 @@ static int sym_scatter_no_sglist(struct 
 {
 	struct sym_tblmove *data = &cp->phys.data[SYM_CONF_MAX_SG-1];
 	int segment;
+	unsigned int len = cmd->request_bufflen;
 
-	cp->data_len = cmd->request_bufflen;
-
-	if (cmd->request_bufflen) {
+	if (len) {
 		dma_addr_t baddr = map_scsi_single_data(np, cmd);
 		if (baddr) {
-			sym_build_sge(np, data, baddr, cmd->request_bufflen);
+			if (len & 1) {
+				struct sym_tcb *tp = &np->target[cp->target];
+				if (tp->head.wval & EWS) {
+					len++;
+					cp->odd_byte_adjustment++;
+				}
+			}
+			cp->data_len = len;
+			sym_build_sge(np, data, baddr, len);
 			segment = 1;
 		} else {
 			segment = -2;
@@ -418,6 +426,7 @@ static int sym_scatter(struct sym_hcb *n
 		segment = sym_scatter_no_sglist(np, cp, cmd);
 	else if ((use_sg = map_scsi_sg_data(np, cmd)) > 0) {
 		struct scatterlist *scatter = (struct scatterlist *)cmd->buffer;
+		struct sym_tcb *tp = &np->target[cp->target];
 		struct sym_tblmove *data;
 
 		if (use_sg > SYM_CONF_MAX_SG) {
@@ -431,6 +440,11 @@ static int sym_scatter(struct sym_hcb *n
 			dma_addr_t baddr = sg_dma_address(&scatter[segment]);
 			unsigned int len = sg_dma_len(&scatter[segment]);
 
+			if ((len & 1) && (tp->head.wval & EWS)) {
+				len++;
+				cp->odd_byte_adjustment++;
+			}
+
 			sym_build_sge(np, &data[segment], baddr, len);
 			cp->data_len += len;
 		}
@@ -456,10 +470,8 @@ static int sym_queue_command(struct sym_
 	 *  Minimal checkings, so that we will not 
 	 *  go outside our tables.
 	 */
-	if (sdev->id == np->myaddr ||
-	    sdev->id >= SYM_CONF_MAX_TARGET ||
-	    sdev->lun >= SYM_CONF_MAX_LUN) {
-		sym_xpt_done2(np, cmd, CAM_DEV_NOT_THERE);
+	if (sdev->id == np->myaddr) {
+		sym_xpt_done2(np, cmd, DID_NO_CONNECT);
 		return 0;
 	}
 
@@ -469,28 +481,6 @@ static int sym_queue_command(struct sym_
 	tp = &np->target[sdev->id];
 
 	/*
-	 *  Complete the 1st INQUIRY command with error 
-	 *  condition if the device is flagged NOSCAN 
-	 *  at BOOT in the NVRAM. This may speed up 
-	 *  the boot and maintain coherency with BIOS 
-	 *  device numbering. Clearing the flag allows 
-	 *  user to rescan skipped devices later.
-	 *  We also return error for devices not flagged 
-	 *  for SCAN LUNS in the NVRAM since some mono-lun 
-	 *  devices behave badly when asked for some non 
-	 *  zero LUN. Btw, this is an absolute hack.:-)
-	 */
-	if (cmd->cmnd[0] == 0x12 || cmd->cmnd[0] == 0x0) {
-		if ((tp->usrflags & SYM_SCAN_BOOT_DISABLED) ||
-		    ((tp->usrflags & SYM_SCAN_LUNS_DISABLED) && 
-		     sdev->lun != 0)) {
-			tp->usrflags &= ~SYM_SCAN_BOOT_DISABLED;
-			sym_xpt_done2(np, cmd, CAM_DEV_NOT_THERE);
-			return 0;
-		}
-	}
-
-	/*
 	 *  Select tagged/untagged.
 	 */
 	lp = sym_lp(tp, sdev->lun);
@@ -511,23 +501,10 @@ static int sym_queue_command(struct sym_
  */
 static inline int sym_setup_cdb(struct sym_hcb *np, struct scsi_cmnd *cmd, struct sym_ccb *cp)
 {
-	u32	cmd_ba;
-	int	cmd_len;
-
-	/*
-	 *  CDB is 16 bytes max.
-	 */
-	if (cmd->cmd_len > sizeof(cp->cdb_buf)) {
-		sym_set_cam_status(cp->cmd, CAM_REQ_INVALID);
-		return -1;
-	}
-
 	memcpy(cp->cdb_buf, cmd->cmnd, cmd->cmd_len);
-	cmd_ba  = CCB_BA (cp, cdb_buf[0]);
-	cmd_len = cmd->cmd_len;
 
-	cp->phys.cmd.addr	= cpu_to_scr(cmd_ba);
-	cp->phys.cmd.size	= cpu_to_scr(cmd_len);
+	cp->phys.cmd.addr = CCB_BA(cp, cdb_buf[0]);
+	cp->phys.cmd.size = cpu_to_scr(cmd->cmd_len);
 
 	return 0;
 }
@@ -554,10 +531,7 @@ int sym_setup_data_and_start(struct sym_
 	if (dir != DMA_NONE) {
 		cp->segments = sym_scatter(np, cp, cmd);
 		if (cp->segments < 0) {
-			if (cp->segments == -2)
-				sym_set_cam_status(cmd, CAM_RESRC_UNAVAIL);
-			else
-				sym_set_cam_status(cmd, CAM_REQ_TOO_BIG);
+			sym_set_cam_status(cmd, DID_ERROR);
 			goto out_abort;
 		}
 	} else {
@@ -855,7 +829,7 @@ prepare:
 	ep->to_do = to_do;
 	/* Complete the command with locks held as required by the driver */
 	if (to_do == SYM_EH_DO_COMPLETE)
-		sym_xpt_done2(np, cmd, CAM_REQ_ABORTED);
+		sym_xpt_done2(np, cmd, DID_ABORT);
 
 	/* Wait for completion with locks released, as required by kernel */
 	if (to_do == SYM_EH_DO_WAIT) {
@@ -882,22 +856,46 @@ prepare:
  */
 static int sym53c8xx_eh_abort_handler(struct scsi_cmnd *cmd)
 {
-	return sym_eh_handler(SYM_EH_ABORT, "ABORT", cmd);
+	int rc;
+
+	spin_lock_irq(cmd->device->host->host_lock);
+	rc = sym_eh_handler(SYM_EH_ABORT, "ABORT", cmd);
+	spin_unlock_irq(cmd->device->host->host_lock);
+
+	return rc;
 }
 
 static int sym53c8xx_eh_device_reset_handler(struct scsi_cmnd *cmd)
 {
-	return sym_eh_handler(SYM_EH_DEVICE_RESET, "DEVICE RESET", cmd);
+	int rc;
+
+	spin_lock_irq(cmd->device->host->host_lock);
+	rc = sym_eh_handler(SYM_EH_DEVICE_RESET, "DEVICE RESET", cmd);
+	spin_unlock_irq(cmd->device->host->host_lock);
+
+	return rc;
 }
 
 static int sym53c8xx_eh_bus_reset_handler(struct scsi_cmnd *cmd)
 {
-	return sym_eh_handler(SYM_EH_BUS_RESET, "BUS RESET", cmd);
+	int rc;
+
+	spin_lock_irq(cmd->device->host->host_lock);
+	rc = sym_eh_handler(SYM_EH_BUS_RESET, "BUS RESET", cmd);
+	spin_unlock_irq(cmd->device->host->host_lock);
+
+	return rc;
 }
 
 static int sym53c8xx_eh_host_reset_handler(struct scsi_cmnd *cmd)
 {
-	return sym_eh_handler(SYM_EH_HOST_RESET, "HOST RESET", cmd);
+	int rc;
+
+	spin_lock_irq(cmd->device->host->host_lock);
+	rc = sym_eh_handler(SYM_EH_HOST_RESET, "HOST RESET", cmd);
+	spin_unlock_irq(cmd->device->host->host_lock);
+
+	return rc;
 }
 
 /*
@@ -921,7 +919,7 @@ static void sym_tune_dev_queuing(struct 
 	lp->s.reqtags     = reqtags;
 
 	if (reqtags != oldtags) {
-		dev_info(&tp->sdev->sdev_target->dev,
+		dev_info(&tp->starget->dev,
 		         "tagged command queuing %s, command queue depth %d.\n",
 		          lp->s.reqtags ? "enabled" : "disabled",
  		          lp->started_limit);
@@ -981,22 +979,34 @@ static int device_queue_depth(struct sym
 	return DEF_DEPTH;
 }
 
-static int sym53c8xx_slave_alloc(struct scsi_device *device)
+static int sym53c8xx_slave_alloc(struct scsi_device *sdev)
 {
-	struct sym_hcb *np = sym_get_hcb(device->host);
-	struct sym_tcb *tp = &np->target[device->id];
-	if (!tp->sdev)
-		tp->sdev = device;
+	struct sym_hcb *np;
+	struct sym_tcb *tp;
 
-	return 0;
-}
+	if (sdev->id >= SYM_CONF_MAX_TARGET || sdev->lun >= SYM_CONF_MAX_LUN)
+		return -ENXIO;
 
-static void sym53c8xx_slave_destroy(struct scsi_device *device)
-{
-	struct sym_hcb *np = sym_get_hcb(device->host);
-	struct sym_tcb *tp = &np->target[device->id];
-	if (tp->sdev == device)
-		tp->sdev = NULL;
+	np = sym_get_hcb(sdev->host);
+	tp = &np->target[sdev->id];
+
+	/*
+	 * Fail the device init if the device is flagged NOSCAN at BOOT in
+	 * the NVRAM.  This may speed up boot and maintain coherency with
+	 * BIOS device numbering.  Clearing the flag allows the user to
+	 * rescan skipped devices later.  We also return an error for
+	 * devices not flagged for SCAN LUNS in the NVRAM since some single
+	 * lun devices behave badly when asked for a non zero LUN.
+	 */
+
+	if ((tp->usrflags & SYM_SCAN_BOOT_DISABLED) ||
+	    ((tp->usrflags & SYM_SCAN_LUNS_DISABLED) && sdev->lun != 0)) {
+		tp->usrflags &= ~SYM_SCAN_BOOT_DISABLED;
+		return -ENXIO;
+	}
+
+	tp->starget = sdev->sdev_target;
+	return 0;
 }
 
 /*
@@ -1897,6 +1907,7 @@ static int sym_detach(struct sym_hcb *np
 	 */
 	printk("%s: resetting chip\n", sym_name(np));
 	OUTB(np, nc_istat, SRST);
+	INB(np, nc_mbox1);
 	udelay(10);
 	OUTB(np, nc_istat, 0);
 
@@ -1915,7 +1926,6 @@ static struct scsi_host_template sym2_te
 	.queuecommand		= sym53c8xx_queue_command,
 	.slave_alloc		= sym53c8xx_slave_alloc,
 	.slave_configure	= sym53c8xx_slave_configure,
-	.slave_destroy		= sym53c8xx_slave_destroy,
 	.eh_abort_handler	= sym53c8xx_eh_abort_handler,
 	.eh_device_reset_handler = sym53c8xx_eh_device_reset_handler,
 	.eh_bus_reset_handler	= sym53c8xx_eh_bus_reset_handler,
diff --git a/drivers/scsi/sym53c8xx_2/sym_glue.h b/drivers/scsi/sym53c8xx_2/sym_glue.h
--- a/drivers/scsi/sym53c8xx_2/sym_glue.h
+++ b/drivers/scsi/sym53c8xx_2/sym_glue.h
@@ -142,33 +142,6 @@
 #define scr_to_cpu(dw)	le32_to_cpu(dw)
 
 /*
- *  Remap some status field values.
- */
-#define CAM_REQ_CMP		DID_OK
-#define CAM_SEL_TIMEOUT		DID_NO_CONNECT
-#define CAM_CMD_TIMEOUT		DID_TIME_OUT
-#define CAM_REQ_ABORTED		DID_ABORT
-#define CAM_UNCOR_PARITY	DID_PARITY
-#define CAM_SCSI_BUS_RESET	DID_RESET	
-#define CAM_REQUEUE_REQ		DID_SOFT_ERROR
-#define	CAM_UNEXP_BUSFREE	DID_ERROR
-#define	CAM_SCSI_BUSY		DID_BUS_BUSY
-
-#define	CAM_DEV_NOT_THERE	DID_NO_CONNECT
-#define	CAM_REQ_INVALID		DID_ERROR
-#define	CAM_REQ_TOO_BIG		DID_ERROR
-
-#define	CAM_RESRC_UNAVAIL	DID_ERROR
-
-/*
- *  Remap data direction values.
- */
-#define CAM_DIR_NONE		DMA_NONE
-#define CAM_DIR_IN		DMA_FROM_DEVICE
-#define CAM_DIR_OUT		DMA_TO_DEVICE
-#define CAM_DIR_UNKNOWN		DMA_BIDIRECTIONAL
-
-/*
  *  These ones are used as return code from 
  *  error recovery handlers under Linux.
  */
diff --git a/drivers/scsi/sym53c8xx_2/sym_hipd.c b/drivers/scsi/sym53c8xx_2/sym_hipd.c
--- a/drivers/scsi/sym53c8xx_2/sym_hipd.c
+++ b/drivers/scsi/sym53c8xx_2/sym_hipd.c
@@ -97,7 +97,7 @@ static void sym_print_msg(struct sym_ccb
 static void sym_print_nego_msg(struct sym_hcb *np, int target, char *label, u_char *msg)
 {
 	struct sym_tcb *tp = &np->target[target];
-	dev_info(&tp->sdev->sdev_target->dev, "%s: ", label);
+	dev_info(&tp->starget->dev, "%s: ", label);
 
 	sym_show_msg(msg);
 	printf(".\n");
@@ -149,8 +149,10 @@ static char *sym_scsi_bus_mode(int mode)
 static void sym_chip_reset (struct sym_hcb *np)
 {
 	OUTB(np, nc_istat, SRST);
+	INB(np, nc_mbox1);
 	udelay(10);
 	OUTB(np, nc_istat, 0);
+	INB(np, nc_mbox1);
 	udelay(2000);	/* For BUS MODE to settle */
 }
 
@@ -216,6 +218,7 @@ int sym_reset_scsi_bus(struct sym_hcb *n
 	OUTB(np, nc_stest3, TE);
 	OUTB(np, nc_dcntl, (np->rv_dcntl & IRQM));
 	OUTB(np, nc_scntl1, CRST);
+	INB(np, nc_mbox1);
 	udelay(200);
 
 	if (!SYM_SETUP_SCSI_BUS_CHECK)
@@ -280,8 +283,10 @@ static void sym_selectclock(struct sym_h
 		if (!i)
 			printf("%s: the chip cannot lock the frequency\n",
 				sym_name(np));
-	} else
-		udelay((50+10));
+	} else {
+		INB(np, nc_mbox1);
+		udelay(50+10);
+	}
 	OUTB(np, nc_stest3, HSC);		/* Halt the scsi clock	*/
 	OUTB(np, nc_scntl3, scntl3);
 	OUTB(np, nc_stest1, (DBLEN|DBLSEL));/* Select clock multiplier	*/
@@ -1445,7 +1450,7 @@ static void sym_check_goals(struct sym_h
 static int sym_prepare_nego(struct sym_hcb *np, struct sym_ccb *cp, u_char *msgptr)
 {
 	struct sym_tcb *tp = &np->target[cp->target];
-	struct scsi_target *starget = tp->sdev->sdev_target;
+	struct scsi_target *starget = tp->starget;
 	struct sym_trans *goal = &tp->tgoal;
 	int msglen = 0;
 	int nego;
@@ -1690,7 +1695,7 @@ static void sym_flush_comp_queue(struct 
 		if (cam_status)
 			sym_set_cam_status(cmd, cam_status);
 #ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING
-		if (sym_get_cam_status(cmd) == CAM_REQUEUE_REQ) {
+		if (sym_get_cam_status(cmd) == DID_SOFT_ERROR) {
 			struct sym_tcb *tp = &np->target[cp->target];
 			struct sym_lcb *lp = sym_lp(tp, cp->lun);
 			if (lp) {
@@ -1791,12 +1796,13 @@ void sym_start_up (struct sym_hcb *np, i
 	/*
 	 *  Wakeup all pending jobs.
 	 */
-	sym_flush_busy_queue(np, CAM_SCSI_BUS_RESET);
+	sym_flush_busy_queue(np, DID_RESET);
 
 	/*
 	 *  Init chip.
 	 */
 	OUTB(np, nc_istat,  0x00);			/*  Remove Reset, abort */
+	INB(np, nc_mbox1);
 	udelay(2000); /* The 895 needs time for the bus mode to settle */
 
 	OUTB(np, nc_scntl0, np->rv_scntl0 | 0xc0);
@@ -1905,6 +1911,7 @@ void sym_start_up (struct sym_hcb *np, i
 	if (np->features & (FE_ULTRA2|FE_ULTRA3)) {
 		OUTONW(np, nc_sien, SBMC);
 		if (reason == 0) {
+			INB(np, nc_mbox1);
 			mdelay(100);
 			INW(np, nc_sist);
 		}
@@ -2074,7 +2081,7 @@ static void sym_settrans(struct sym_hcb 
 static void sym_setwide(struct sym_hcb *np, int target, u_char wide)
 {
 	struct sym_tcb *tp = &np->target[target];
-	struct scsi_target *starget = tp->sdev->sdev_target;
+	struct scsi_target *starget = tp->starget;
 
 	if (spi_width(starget) == wide)
 		return;
@@ -2102,7 +2109,7 @@ sym_setsync(struct sym_hcb *np, int targ
             u_char ofs, u_char per, u_char div, u_char fak)
 {
 	struct sym_tcb *tp = &np->target[target];
-	struct scsi_target *starget = tp->sdev->sdev_target;
+	struct scsi_target *starget = tp->starget;
 	u_char wide = (tp->head.wval & EWS) ? BUS_16_BIT : BUS_8_BIT;
 
 	sym_settrans(np, target, 0, ofs, per, wide, div, fak);
@@ -2129,7 +2136,7 @@ sym_setpprot(struct sym_hcb *np, int tar
              u_char per, u_char wide, u_char div, u_char fak)
 {
 	struct sym_tcb *tp = &np->target[target];
-	struct scsi_target *starget = tp->sdev->sdev_target;
+	struct scsi_target *starget = tp->starget;
 
 	sym_settrans(np, target, opts, ofs, per, wide, div, fak);
 
@@ -2944,7 +2951,7 @@ unknown_int:
  *  Dequeue from the START queue all CCBs that match 
  *  a given target/lun/task condition (-1 means all),
  *  and move them from the BUSY queue to the COMP queue 
- *  with CAM_REQUEUE_REQ status condition.
+ *  with DID_SOFT_ERROR status condition.
  *  This function is used during error handling/recovery.
  *  It is called with SCRIPTS not running.
  */
@@ -2974,7 +2981,7 @@ sym_dequeue_from_squeue(struct sym_hcb *
 		if ((target == -1 || cp->target == target) &&
 		    (lun    == -1 || cp->lun    == lun)    &&
 		    (task   == -1 || cp->tag    == task)) {
-			sym_set_cam_status(cp->cmd, CAM_REQUEUE_REQ);
+			sym_set_cam_status(cp->cmd, DID_SOFT_ERROR);
 			sym_remque(&cp->link_ccbq);
 			sym_insque_tail(&cp->link_ccbq, &np->comp_ccbq);
 		}
@@ -3093,13 +3100,13 @@ static void sym_sir_bad_scsi_status(stru
 		/*
 		 *  Message table indirect structure.
 		 */
-		cp->phys.smsg.addr	= cpu_to_scr(CCB_BA(cp, scsi_smsg2));
+		cp->phys.smsg.addr	= CCB_BA(cp, scsi_smsg2);
 		cp->phys.smsg.size	= cpu_to_scr(msglen);
 
 		/*
 		 *  sense command
 		 */
-		cp->phys.cmd.addr	= cpu_to_scr(CCB_BA(cp, sensecmd));
+		cp->phys.cmd.addr	= CCB_BA(cp, sensecmd);
 		cp->phys.cmd.size	= cpu_to_scr(6);
 
 		/*
@@ -3116,7 +3123,7 @@ static void sym_sir_bad_scsi_status(stru
 		 *  sense data
 		 */
 		memset(cp->sns_bbuf, 0, SYM_SNS_BBUF_LEN);
-		cp->phys.sense.addr	= cpu_to_scr(CCB_BA(cp, sns_bbuf));
+		cp->phys.sense.addr	= CCB_BA(cp, sns_bbuf);
 		cp->phys.sense.size	= cpu_to_scr(SYM_SNS_BBUF_LEN);
 
 		/*
@@ -3198,7 +3205,7 @@ int sym_clear_tasks(struct sym_hcb *np, 
 		sym_insque_tail(&cp->link_ccbq, &np->comp_ccbq);
 
 		/* Preserve the software timeout condition */
-		if (sym_get_cam_status(cmd) != CAM_CMD_TIMEOUT)
+		if (sym_get_cam_status(cmd) != DID_TIME_OUT)
 			sym_set_cam_status(cmd, cam_status);
 		++i;
 #if 0
@@ -3366,7 +3373,7 @@ static void sym_sir_task_recovery(struct
 		 *  Make sure at least our IO to abort has been dequeued.
 		 */
 #ifndef SYM_OPT_HANDLE_DEVICE_QUEUEING
-		assert(i && sym_get_cam_status(cp->cmd) == CAM_REQUEUE_REQ);
+		assert(i && sym_get_cam_status(cp->cmd) == DID_SOFT_ERROR);
 #else
 		sym_remque(&cp->link_ccbq);
 		sym_insque_tail(&cp->link_ccbq, &np->comp_ccbq);
@@ -3375,9 +3382,9 @@ static void sym_sir_task_recovery(struct
 		 *  Keep track in cam status of the reason of the abort.
 		 */
 		if (cp->to_abort == 2)
-			sym_set_cam_status(cp->cmd, CAM_CMD_TIMEOUT);
+			sym_set_cam_status(cp->cmd, DID_TIME_OUT);
 		else
-			sym_set_cam_status(cp->cmd, CAM_REQ_ABORTED);
+			sym_set_cam_status(cp->cmd, DID_ABORT);
 
 		/*
 		 *  Complete with error everything that we have dequeued.
@@ -3491,7 +3498,7 @@ static void sym_sir_task_recovery(struct
 		 *  conditions not due to timeout.
 		 */
 		if (cp->to_abort == 2)
-			sym_set_cam_status(cp->cmd, CAM_CMD_TIMEOUT);
+			sym_set_cam_status(cp->cmd, DID_TIME_OUT);
 		cp->to_abort = 0; /* We donnot expect to fail here */
 		break;
 
@@ -3502,7 +3509,7 @@ static void sym_sir_task_recovery(struct
 	case SIR_ABORT_SENT:
 		target = INB(np, nc_sdid) & 0xf;
 		tp = &np->target[target];
-		starget = tp->sdev->sdev_target;
+		starget = tp->starget;
 		
 		/*
 		**  If we didn't abort anything, leave here.
@@ -3551,7 +3558,7 @@ static void sym_sir_task_recovery(struct
 		 */
 		i = (INL(np, nc_scratcha) - np->squeue_ba) / 4;
 		sym_dequeue_from_squeue(np, i, target, lun, -1);
-		sym_clear_tasks(np, CAM_REQ_ABORTED, target, lun, task);
+		sym_clear_tasks(np, DID_ABORT, target, lun, task);
 		sym_flush_comp_queue(np, 0);
 
  		/*
@@ -3566,7 +3573,7 @@ static void sym_sir_task_recovery(struct
 	 *  Print to the log the message we intend to send.
 	 */
 	if (num == SIR_TARGET_SELECTED) {
-		dev_info(&tp->sdev->sdev_target->dev, "control msgout:");
+		dev_info(&tp->starget->dev, "control msgout:");
 		sym_printl_hex(np->abrt_msg, np->abrt_tbl.size);
 		np->abrt_tbl.size = cpu_to_scr(np->abrt_tbl.size);
 	}
@@ -3877,6 +3884,8 @@ int sym_compute_residual(struct sym_hcb 
 		resid += (tmp & 0xffffff);
 	}
 
+	resid -= cp->odd_byte_adjustment;
+
 	/*
 	 *  Hopefully, the result is not too wrong.
 	 */
@@ -4758,10 +4767,8 @@ struct sym_ccb *sym_get_ccb (struct sym_
 	}
 
 #endif
-	/*
-	 *  Remember all informations needed to free this CCB.
-	 */
 	cp->to_abort = 0;
+	cp->odd_byte_adjustment = 0;
 	cp->tag	   = tag;
 	cp->order  = tag_order;
 	cp->target = tn;
@@ -5104,7 +5111,7 @@ static void sym_alloc_lcb_tags (struct s
 	lp->itlq_tbl = sym_calloc_dma(SYM_CONF_MAX_TASK*4, "ITLQ_TBL");
 	if (!lp->itlq_tbl)
 		goto fail;
-	lp->cb_tags = kcalloc(SYM_CONF_MAX_TASK, 1, GFP_KERNEL);
+	lp->cb_tags = kcalloc(SYM_CONF_MAX_TASK, 1, GFP_ATOMIC);
 	if (!lp->cb_tags) {
 		sym_mfree_dma(lp->itlq_tbl, SYM_CONF_MAX_TASK*4, "ITLQ_TBL");
 		lp->itlq_tbl = NULL;
@@ -5243,7 +5250,7 @@ int sym_queue_scsiio(struct sym_hcb *np,
 	/*
 	 *  message
 	 */
-	cp->phys.smsg.addr	= cpu_to_scr(CCB_BA(cp, scsi_smsg));
+	cp->phys.smsg.addr	= CCB_BA(cp, scsi_smsg);
 	cp->phys.smsg.size	= cpu_to_scr(msglen);
 
 	/*
@@ -5343,7 +5350,7 @@ int sym_abort_scsiio(struct sym_hcb *np,
 }
 
 /*
- *  Complete execution of a SCSI command with extented 
+ *  Complete execution of a SCSI command with extended 
  *  error, SCSI status error, or having been auto-sensed.
  *
  *  The SCRIPTS processor is not running there, so we 
@@ -5441,7 +5448,7 @@ if (resid)
 		/*
 		 *  Let's requeue it to device.
 		 */
-		sym_set_cam_status(cmd, CAM_REQUEUE_REQ);
+		sym_set_cam_status(cmd, DID_SOFT_ERROR);
 		goto finish;
 	}
 weirdness:
diff --git a/drivers/scsi/sym53c8xx_2/sym_hipd.h b/drivers/scsi/sym53c8xx_2/sym_hipd.h
--- a/drivers/scsi/sym53c8xx_2/sym_hipd.h
+++ b/drivers/scsi/sym53c8xx_2/sym_hipd.h
@@ -151,6 +151,16 @@
  */
 #define	SYM_CONF_MIN_ASYNC (40)
 
+
+/*
+ * MEMORY ALLOCATOR.
+ */
+
+#define SYM_MEM_WARN	1	/* Warn on failed operations */
+
+#define SYM_MEM_PAGE_ORDER 0	/* 1 PAGE  maximum */
+#define SYM_MEM_CLUSTER_SHIFT	(PAGE_SHIFT+SYM_MEM_PAGE_ORDER)
+#define SYM_MEM_FREE_UNUSED	/* Free unused pages immediately */
 /*
  *  Shortest memory chunk is (1<<SYM_MEM_SHIFT), currently 16.
  *  Actual allocations happen as SYM_MEM_CLUSTER_SIZE sized.
@@ -444,7 +454,7 @@ struct sym_tcb {
 	 */
 	u_char	usrflags;
 	u_short	usrtags;
-	struct scsi_device *sdev;
+	struct scsi_target *starget;
 };
 
 /*
@@ -754,10 +764,8 @@ struct sym_ccb {
 	int	segments;	/* Number of SG segments	*/
 
 	u8	order;		/* Tag type (if tagged command)	*/
+	unsigned char odd_byte_adjustment;	/* odd-sized req on wide bus */
 
-	/*
-	 *  Miscellaneous status'.
-	 */
 	u_char	nego_status;	/* Negotiation status		*/
 	u_char	xerr_status;	/* Extended error flags		*/
 	u32	extra_bytes;	/* Extraneous bytes transferred	*/
@@ -809,7 +817,7 @@ struct sym_ccb {
 #endif
 };
 
-#define CCB_BA(cp,lbl)	(cp->ccb_ba + offsetof(struct sym_ccb, lbl))
+#define CCB_BA(cp,lbl)	cpu_to_scr(cp->ccb_ba + offsetof(struct sym_ccb, lbl))
 
 #ifdef	SYM_OPT_HANDLE_DIR_UNKNOWN
 #define	sym_goalp(cp) ((cp->host_flags & HF_DATA_IN) ? cp->goalp : cp->wgoalp)
@@ -1138,33 +1146,33 @@ static inline void sym_setup_data_pointe
 	 *  No segments means no data.
 	 */
 	if (!cp->segments)
-		dir = CAM_DIR_NONE;
+		dir = DMA_NONE;
 
 	/*
 	 *  Set the data pointer.
 	 */
 	switch(dir) {
 #ifdef	SYM_OPT_HANDLE_DIR_UNKNOWN
-	case CAM_DIR_UNKNOWN:
+	case DMA_BIDIRECTIONAL:
 #endif
-	case CAM_DIR_OUT:
+	case DMA_TO_DEVICE:
 		goalp = SCRIPTA_BA(np, data_out2) + 8;
 		lastp = goalp - 8 - (cp->segments * (2*4));
 #ifdef	SYM_OPT_HANDLE_DIR_UNKNOWN
 		cp->wgoalp = cpu_to_scr(goalp);
-		if (dir != CAM_DIR_UNKNOWN)
+		if (dir != DMA_BIDIRECTIONAL)
 			break;
 		cp->phys.head.wlastp = cpu_to_scr(lastp);
 		/* fall through */
 #else
 		break;
 #endif
-	case CAM_DIR_IN:
+	case DMA_FROM_DEVICE:
 		cp->host_flags |= HF_DATA_IN;
 		goalp = SCRIPTA_BA(np, data_in2) + 8;
 		lastp = goalp - 8 - (cp->segments * (2*4));
 		break;
-	case CAM_DIR_NONE:
+	case DMA_NONE:
 	default:
 #ifdef	SYM_OPT_HANDLE_DIR_UNKNOWN
 		cp->host_flags |= HF_DATA_IN;
@@ -1185,7 +1193,7 @@ static inline void sym_setup_data_pointe
 	/*
 	 *  If direction is unknown, start at data_io.
 	 */
-	if (dir == CAM_DIR_UNKNOWN)
+	if (dir == DMA_BIDIRECTIONAL)
 		cp->phys.head.savep = cpu_to_scr(SCRIPTB_BA(np, data_io));
 #endif
 }
@@ -1194,12 +1202,6 @@ static inline void sym_setup_data_pointe
  *  MEMORY ALLOCATOR.
  */
 
-#define SYM_MEM_PAGE_ORDER 0	/* 1 PAGE  maximum */
-#define SYM_MEM_CLUSTER_SHIFT	(PAGE_SHIFT+SYM_MEM_PAGE_ORDER)
-#define SYM_MEM_FREE_UNUSED	/* Free unused pages immediately */
-
-#define SYM_MEM_WARN	1	/* Warn on failed operations */
-
 #define sym_get_mem_cluster()	\
 	(void *) __get_free_pages(GFP_ATOMIC, SYM_MEM_PAGE_ORDER)
 #define sym_free_mem_cluster(p)	\
diff --git a/drivers/scsi/sym53c8xx_2/sym_nvram.c b/drivers/scsi/sym53c8xx_2/sym_nvram.c
--- a/drivers/scsi/sym53c8xx_2/sym_nvram.c
+++ b/drivers/scsi/sym53c8xx_2/sym_nvram.c
@@ -270,6 +270,7 @@ static void S24C16_set_bit(struct sym_de
 
 	}
 	OUTB(np, nc_gpreg, *gpreg);
+	INB(np, nc_mbox1);
 	udelay(5);
 }
 
@@ -366,7 +367,7 @@ static void S24C16_read_byte(struct sym_
 	S24C16_write_ack(np, ack_data, gpreg, gpcntl);
 }
 
-#if SYM_CONF_NVRAM_WRITE_SUPPORT
+#ifdef SYM_CONF_NVRAM_WRITE_SUPPORT
 /*
  *  Write 'len' bytes starting at 'offset'.
  */
@@ -547,6 +548,7 @@ static int sym_read_Symbios_nvram(struct
 static void T93C46_Clk(struct sym_device *np, u_char *gpreg)
 {
 	OUTB(np, nc_gpreg, *gpreg | 0x04);
+	INB(np, nc_mbox1);
 	udelay(2);
 	OUTB(np, nc_gpreg, *gpreg);
 }
@@ -574,6 +576,7 @@ static void T93C46_Write_Bit(struct sym_
 	*gpreg |= 0x10;
 		
 	OUTB(np, nc_gpreg, *gpreg);
+	INB(np, nc_mbox1);
 	udelay(2);
 
 	T93C46_Clk(np, gpreg);
@@ -586,6 +589,7 @@ static void T93C46_Stop(struct sym_devic
 {
 	*gpreg &= 0xef;
 	OUTB(np, nc_gpreg, *gpreg);
+	INB(np, nc_mbox1);
 	udelay(2);
 
 	T93C46_Clk(np, gpreg);
@@ -733,7 +737,8 @@ static int sym_read_parisc_pdc(struct sy
 	return SYM_PARISC_PDC;
 }
 #else
-static int sym_read_parisc_pdc(struct sym_device *np, struct pdc_initiator *x)
+static inline int sym_read_parisc_pdc(struct sym_device *np,
+					struct pdc_initiator *x)
 {
 	return 0;
 }
diff --git a/drivers/scsi/t128.c b/drivers/scsi/t128.c
--- a/drivers/scsi/t128.c
+++ b/drivers/scsi/t128.c
@@ -437,8 +437,6 @@ static Scsi_Host_Template driver_templat
 	.queuecommand   = t128_queue_command,
 	.eh_abort_handler = t128_abort,
 	.eh_bus_reset_handler    = t128_bus_reset,
-	.eh_host_reset_handler   = t128_host_reset,
-	.eh_device_reset_handler = t128_device_reset,
 	.bios_param     = t128_biosparam,
 	.can_queue      = CAN_QUEUE,
         .this_id        = 7,
diff --git a/drivers/scsi/t128.h b/drivers/scsi/t128.h
--- a/drivers/scsi/t128.h
+++ b/drivers/scsi/t128.h
@@ -43,6 +43,7 @@
 
 #define T128_PUBLIC_RELEASE 3
 
+#define TDEBUG		0
 #define TDEBUG_INIT	0x1
 #define TDEBUG_TRANSFER 0x2
 
@@ -96,9 +97,7 @@ static int t128_biosparam(struct scsi_de
 			  sector_t, int*);
 static int t128_detect(Scsi_Host_Template *);
 static int t128_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
-static int t128_host_reset(Scsi_Cmnd *);
 static int t128_bus_reset(Scsi_Cmnd *);
-static int t128_device_reset(Scsi_Cmnd *);
 
 #ifndef CMD_PER_LUN
 #define CMD_PER_LUN 2
@@ -140,8 +139,6 @@ static int t128_device_reset(Scsi_Cmnd *
 #define do_NCR5380_intr do_t128_intr
 #define NCR5380_queue_command t128_queue_command
 #define NCR5380_abort t128_abort
-#define NCR5380_host_reset t128_host_reset
-#define NCR5380_device_reset t128_device_reset
 #define NCR5380_bus_reset t128_bus_reset
 #define NCR5380_proc_info t128_proc_info
 
diff --git a/drivers/scsi/tmscsim.c b/drivers/scsi/tmscsim.c
--- a/drivers/scsi/tmscsim.c
+++ b/drivers/scsi/tmscsim.c
@@ -2120,6 +2120,8 @@ static int DC390_bus_reset (struct scsi_
 	struct dc390_acb*    pACB = (struct dc390_acb*) cmd->device->host->hostdata;
 	u8   bval;
 
+	spin_lock_irq(cmd->device->host->host_lock);
+
 	bval = DC390_read8(CtrlReg1) | DIS_INT_ON_SCSI_RST;
 	DC390_write8(CtrlReg1, bval);	/* disable IRQ on bus reset */
 
@@ -2127,7 +2129,7 @@ static int DC390_bus_reset (struct scsi_
 	dc390_ResetSCSIBus(pACB);
 
 	dc390_ResetDevParam(pACB);
-	udelay(1000);
+	mdelay(1);
 	pACB->pScsiHost->last_reset = jiffies + 3*HZ/2 
 		+ HZ * dc390_eepromBuf[pACB->AdapterIndex][EE_DELAY];
     
@@ -2142,6 +2144,8 @@ static int DC390_bus_reset (struct scsi_
 	bval = DC390_read8(CtrlReg1) & ~DIS_INT_ON_SCSI_RST;
 	DC390_write8(CtrlReg1, bval);	/* re-enable interrupt */
 
+	spin_unlock_irq(cmd->device->host->host_lock);
+
 	return SUCCESS;
 }
 
diff --git a/drivers/scsi/u14-34f.c b/drivers/scsi/u14-34f.c
--- a/drivers/scsi/u14-34f.c
+++ b/drivers/scsi/u14-34f.c
@@ -446,8 +446,6 @@ static struct scsi_host_template driver_
                 .release                 = u14_34f_release,
                 .queuecommand            = u14_34f_queuecommand,
                 .eh_abort_handler        = u14_34f_eh_abort,
-                .eh_device_reset_handler = NULL,
-                .eh_bus_reset_handler    = NULL,
                 .eh_host_reset_handler   = u14_34f_eh_host_reset,
                 .bios_param              = u14_34f_bios_param,
                 .slave_configure         = u14_34f_slave_configure,
@@ -1374,15 +1372,6 @@ static int u14_34f_eh_abort(struct scsi_
       if (inb(sh[j]->io_port + REG_SYS_INTR) & IRQ_ASSERTED)
          printk("%s: abort, mbox %d, interrupt pending.\n", BN(j), i);
 
-      if (SCarg->eh_state == SCSI_STATE_TIMEOUT) {
-         unmap_dma(i, j);
-         SCarg->host_scribble = NULL;
-         HD(j)->cp_stat[i] = FREE;
-         printk("%s, abort, mbox %d, eh_state timeout, pid %ld.\n",
-                BN(j), i, SCarg->pid);
-         return SUCCESS;
-         }
-
       return FAILED;
       }
 
@@ -1419,16 +1408,20 @@ static int u14_34f_eh_host_reset(struct 
    printk("%s: reset, enter, target %d.%d:%d, pid %ld.\n",
           BN(j), SCarg->device->channel, SCarg->device->id, SCarg->device->lun, SCarg->pid);
 
+   spin_lock_irq(sh[j]->host_lock);
+
    if (SCarg->host_scribble == NULL)
       printk("%s: reset, pid %ld inactive.\n", BN(j), SCarg->pid);
 
    if (HD(j)->in_reset) {
       printk("%s: reset, exit, already in reset.\n", BN(j));
+      spin_unlock_irq(sh[j]->host_lock);
       return FAILED;
       }
 
    if (wait_on_busy(sh[j]->io_port, MAXLOOP)) {
       printk("%s: reset, exit, timeout error.\n", BN(j));
+      spin_unlock_irq(sh[j]->host_lock);
       return FAILED;
       }
 
@@ -1479,6 +1472,7 @@ static int u14_34f_eh_host_reset(struct 
 
    if (wait_on_busy(sh[j]->io_port, MAXLOOP)) {
       printk("%s: reset, cannot reset, timeout error.\n", BN(j));
+      spin_unlock_irq(sh[j]->host_lock);
       return FAILED;
       }
 
@@ -1540,6 +1534,7 @@ static int u14_34f_eh_host_reset(struct 
    if (arg_done) printk("%s: reset, exit, pid %ld done.\n", BN(j), SCarg->pid);
    else          printk("%s: reset, exit.\n", BN(j));
 
+   spin_unlock_irq(sh[j]->host_lock);
    return SUCCESS;
 }
 
diff --git a/drivers/scsi/ultrastor.c b/drivers/scsi/ultrastor.c
--- a/drivers/scsi/ultrastor.c
+++ b/drivers/scsi/ultrastor.c
@@ -879,7 +879,7 @@ static int ultrastor_abort(Scsi_Cmnd *SC
 	ogm_addr = (unsigned int)isa_bus_to_virt(inl(port0 + 23));
 	icm_status = inb(port0 + 27);
 	icm_addr = (unsigned int)isa_bus_to_virt(inl(port0 + 28));
-	spin_lock_irqsave(host->host_lock, flags);
+	spin_unlock_irqrestore(host->host_lock, flags);
       }
 
     /* First check to see if an interrupt is pending.  I suspect the SiS
@@ -954,9 +954,7 @@ static int ultrastor_abort(Scsi_Cmnd *SC
     SCpnt->result = DID_ABORT << 16;
     
     /* Take the host lock to guard against scsi layer re-entry */
-    spin_lock_irqsave(host->host_lock, flags);
     done(SCpnt);
-    spin_unlock_irqrestore(host->host_lock, flags);
 
     /* Need to set a timeout here in case command never completes.  */
     return SUCCESS;
diff --git a/drivers/scsi/wd7000.c b/drivers/scsi/wd7000.c
--- a/drivers/scsi/wd7000.c
+++ b/drivers/scsi/wd7000.c
@@ -1586,9 +1586,16 @@ static int wd7000_host_reset(struct scsi
 {
 	Adapter *host = (Adapter *) SCpnt->device->host->hostdata;
 
-	if (wd7000_adapter_reset(host) < 0)
+	spin_unlock_irq(SCpnt->device->host->host_lock);
+
+	if (wd7000_adapter_reset(host) < 0) {
+		spin_unlock_irq(SCpnt->device->host->host_lock);
 		return FAILED;
+	}
+
 	wd7000_enable_intr(host);
+
+	spin_unlock_irq(SCpnt->device->host->host_lock);
 	return SUCCESS;
 }
 
diff --git a/drivers/serial/68328serial.c b/drivers/serial/68328serial.c
--- a/drivers/serial/68328serial.c
+++ b/drivers/serial/68328serial.c
@@ -316,7 +316,7 @@ static _INLINE_ void receive_chars(struc
 /*				show_net_buffers(); */
 				return;
 			} else if (ch == 0x12) { /* ^R */
-				machine_restart(NULL);
+				emergency_restart();
 				return;
 #endif /* CONFIG_MAGIC_SYSRQ */
 			}
@@ -992,18 +992,17 @@ static int get_lsr_info(struct m68k_seri
 /*
  * This routine sends a break character out the serial port.
  */
-static void send_break(	struct m68k_serial * info, int duration)
+static void send_break(struct m68k_serial * info, unsigned int duration)
 {
 	m68328_uart *uart = &uart_addr[info->line];
         unsigned long flags;
         if (!info->port)
                 return;
-        set_current_state(TASK_INTERRUPTIBLE);
         save_flags(flags);
         cli();
 #ifdef USE_INTS	
 	uart->utx.w |= UTX_SEND_BREAK;
-        schedule_timeout(duration);
+	msleep_interruptible(duration);
 	uart->utx.w &= ~UTX_SEND_BREAK;
 #endif		
         restore_flags(flags);
@@ -1033,14 +1032,14 @@ static int rs_ioctl(struct tty_struct *t
 				return retval;
 			tty_wait_until_sent(tty, 0);
 			if (!arg)
-				send_break(info, HZ/4);	/* 1/4 second */
+				send_break(info, 250);	/* 1/4 second */
 			return 0;
 		case TCSBRKP:	/* support for POSIX tcsendbreak() */
 			retval = tty_check_change(tty);
 			if (retval)
 				return retval;
 			tty_wait_until_sent(tty, 0);
-			send_break(info, arg ? arg*(HZ/10) : HZ/4);
+			send_break(info, arg ? arg*(100) : 250);
 			return 0;
 		case TIOCGSOFTCAR:
 			error = put_user(C_CLOCAL(tty) ? 1 : 0,
@@ -1498,23 +1497,6 @@ rs68328_init(void)
 	return 0;
 }
 
-
-
-/*
- * register_serial and unregister_serial allows for serial ports to be
- * configured at run-time, to support PCMCIA modems.
- */
-/* SPARC: Unused at this time, just here to make things link. */
-int register_serial(struct serial_struct *req)
-{
-	return -1;
-}
-
-void unregister_serial(int line)
-{
-	return;
-}
-	
 module_init(rs68328_init);
 
 
diff --git a/drivers/serial/68360serial.c b/drivers/serial/68360serial.c
--- a/drivers/serial/68360serial.c
+++ b/drivers/serial/68360serial.c
@@ -1394,14 +1394,13 @@ static void end_break(ser_info_t *info)
 /*
  * This routine sends a break character out the serial port.
  */
-static void send_break(ser_info_t *info, int duration)
+static void send_break(ser_info_t *info, unsigned int duration)
 {
-	set_current_state(TASK_INTERRUPTIBLE);
 #ifdef SERIAL_DEBUG_SEND_BREAK
 	printk("rs_send_break(%d) jiff=%lu...", duration, jiffies);
 #endif
 	begin_break(info);
-	schedule_timeout(duration);
+	msleep_interruptible(duration);
 	end_break(info);
 #ifdef SERIAL_DEBUG_SEND_BREAK
 	printk("done jiffies=%lu\n", jiffies);
@@ -1436,7 +1435,7 @@ static int rs_360_ioctl(struct tty_struc
 			if (signal_pending(current))
 				return -EINTR;
 			if (!arg) {
-				send_break(info, HZ/4);	/* 1/4 second */
+				send_break(info, 250);	/* 1/4 second */
 				if (signal_pending(current))
 					return -EINTR;
 			}
@@ -1448,7 +1447,7 @@ static int rs_360_ioctl(struct tty_struc
 			tty_wait_until_sent(tty, 0);
 			if (signal_pending(current))
 				return -EINTR;
-			send_break(info, arg ? arg*(HZ/10) : HZ/4);
+			send_break(info, arg ? arg*100 : 250);
 			if (signal_pending(current))
 				return -EINTR;
 			return 0;
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -77,23 +77,9 @@ static unsigned int share_irqs = SERIAL8
  */
 #define is_real_interrupt(irq)	((irq) != 0)
 
-/*
- * This converts from our new CONFIG_ symbols to the symbols
- * that asm/serial.h expects.  You _NEED_ to comment out the
- * linux/config.h include contained inside asm/serial.h for
- * this to work.
- */
-#undef CONFIG_SERIAL_MANY_PORTS
-#undef CONFIG_SERIAL_DETECT_IRQ
-#undef CONFIG_SERIAL_MULTIPORT
-#undef CONFIG_HUB6
-
 #ifdef CONFIG_SERIAL_8250_DETECT_IRQ
 #define CONFIG_SERIAL_DETECT_IRQ 1
 #endif
-#ifdef CONFIG_SERIAL_8250_MULTIPORT
-#define CONFIG_SERIAL_MULTIPORT 1
-#endif
 #ifdef CONFIG_SERIAL_8250_MANY_PORTS
 #define CONFIG_SERIAL_MANY_PORTS 1
 #endif
@@ -119,7 +105,7 @@ static struct old_serial_port old_serial
 	SERIAL_PORT_DFNS /* defined in asm/serial.h */
 };
 
-#define UART_NR	(ARRAY_SIZE(old_serial_port) + CONFIG_SERIAL_8250_NR_UARTS)
+#define UART_NR	CONFIG_SERIAL_8250_NR_UARTS
 
 #ifdef CONFIG_SERIAL_8250_RSA
 
@@ -132,9 +118,9 @@ struct uart_8250_port {
 	struct uart_port	port;
 	struct timer_list	timer;		/* "no irq" timer */
 	struct list_head	list;		/* ports on this IRQ */
-	unsigned int		capabilities;	/* port capabilities */
+	unsigned short		capabilities;	/* port capabilities */
+	unsigned short		bugs;		/* port bugs */
 	unsigned int		tx_loadsz;	/* transmit fifo load size */
-	unsigned short		rev;
 	unsigned char		acr;
 	unsigned char		ier;
 	unsigned char		lcr;
@@ -560,7 +546,14 @@ static void autoconfig_has_efr(struct ua
 	if (id1 == 0x16 && id2 == 0xC9 &&
 	    (id3 == 0x50 || id3 == 0x52 || id3 == 0x54)) {
 		up->port.type = PORT_16C950;
-		up->rev = rev | (id3 << 8);
+
+		/*
+		 * Enable work around for the Oxford Semiconductor 952 rev B
+		 * chip which causes it to seriously miscalculate baud rates
+		 * when DLL is 0.
+		 */
+		if (id3 == 0x52 && rev == 0x01)
+			up->bugs |= UART_BUG_QUOT;
 		return;
 	}
 	
@@ -577,8 +570,6 @@ static void autoconfig_has_efr(struct ua
 
 	id2 = id1 >> 8;
 	if (id2 == 0x10 || id2 == 0x12 || id2 == 0x14) {
-		if (id2 == 0x10)
-			up->rev = id1 & 255;
 		up->port.type = PORT_16850;
 		return;
 	}
@@ -809,6 +800,7 @@ static void autoconfig(struct uart_8250_
 //	save_flags(flags); cli();
 
 	up->capabilities = 0;
+	up->bugs = 0;
 
 	if (!(up->port.flags & UPF_BUGGY_UART)) {
 		/*
@@ -1001,26 +993,31 @@ static void autoconfig_irq(struct uart_8
 	up->port.irq = (irq > 0) ? irq : 0;
 }
 
+static inline void __stop_tx(struct uart_8250_port *p)
+{
+	if (p->ier & UART_IER_THRI) {
+		p->ier &= ~UART_IER_THRI;
+		serial_out(p, UART_IER, p->ier);
+	}
+}
+
 static void serial8250_stop_tx(struct uart_port *port, unsigned int tty_stop)
 {
 	struct uart_8250_port *up = (struct uart_8250_port *)port;
 
-	if (up->ier & UART_IER_THRI) {
-		up->ier &= ~UART_IER_THRI;
-		serial_out(up, UART_IER, up->ier);
-	}
+	__stop_tx(up);
 
 	/*
-	 * We only do this from uart_stop - if we run out of
-	 * characters to send, we don't want to prevent the
-	 * FIFO from emptying.
+	 * We really want to stop the transmitter from sending.
 	 */
-	if (up->port.type == PORT_16C950 && tty_stop) {
+	if (up->port.type == PORT_16C950) {
 		up->acr |= UART_ACR_TXDIS;
 		serial_icr_write(up, UART_ACR, up->acr);
 	}
 }
 
+static void transmit_chars(struct uart_8250_port *up);
+
 static void serial8250_start_tx(struct uart_port *port, unsigned int tty_start)
 {
 	struct uart_8250_port *up = (struct uart_8250_port *)port;
@@ -1028,11 +1025,20 @@ static void serial8250_start_tx(struct u
 	if (!(up->ier & UART_IER_THRI)) {
 		up->ier |= UART_IER_THRI;
 		serial_out(up, UART_IER, up->ier);
+
+		if (up->bugs & UART_BUG_TXEN) {
+			unsigned char lsr, iir;
+			lsr = serial_in(up, UART_LSR);
+			iir = serial_in(up, UART_IIR);
+			if (lsr & UART_LSR_TEMT && iir & UART_IIR_NO_INT)
+				transmit_chars(up);
+		}
 	}
+
 	/*
-	 * We only do this from uart_start
+	 * Re-enable the transmitter if we disabled it.
 	 */
-	if (tty_start && up->port.type == PORT_16C950) {
+	if (up->port.type == PORT_16C950 && up->acr & UART_ACR_TXDIS) {
 		up->acr &= ~UART_ACR_TXDIS;
 		serial_icr_write(up, UART_ACR, up->acr);
 	}
@@ -1153,7 +1159,7 @@ static _INLINE_ void transmit_chars(stru
 		return;
 	}
 	if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) {
-		serial8250_stop_tx(&up->port, 0);
+		__stop_tx(up);
 		return;
 	}
 
@@ -1172,7 +1178,7 @@ static _INLINE_ void transmit_chars(stru
 	DEBUG_INTR("THRE...");
 
 	if (uart_circ_empty(xmit))
-		serial8250_stop_tx(&up->port, 0);
+		__stop_tx(up);
 }
 
 static _INLINE_ void check_modem_status(struct uart_8250_port *up)
@@ -1374,13 +1380,10 @@ static unsigned int serial8250_tx_empty(
 static unsigned int serial8250_get_mctrl(struct uart_port *port)
 {
 	struct uart_8250_port *up = (struct uart_8250_port *)port;
-	unsigned long flags;
 	unsigned char status;
 	unsigned int ret;
 
-	spin_lock_irqsave(&up->port.lock, flags);
 	status = serial_in(up, UART_MSR);
-	spin_unlock_irqrestore(&up->port.lock, flags);
 
 	ret = 0;
 	if (status & UART_MSR_DCD)
@@ -1433,6 +1436,7 @@ static int serial8250_startup(struct uar
 {
 	struct uart_8250_port *up = (struct uart_8250_port *)port;
 	unsigned long flags;
+	unsigned char lsr, iir;
 	int retval;
 
 	up->capabilities = uart_config[up->port.type].flags;
@@ -1536,6 +1540,26 @@ static int serial8250_startup(struct uar
 			up->port.mctrl |= TIOCM_OUT2;
 
 	serial8250_set_mctrl(&up->port, up->port.mctrl);
+
+	/*
+	 * Do a quick test to see if we receive an
+	 * interrupt when we enable the TX irq.
+	 */
+	serial_outp(up, UART_IER, UART_IER_THRI);
+	lsr = serial_in(up, UART_LSR);
+	iir = serial_in(up, UART_IIR);
+	serial_outp(up, UART_IER, 0);
+
+	if (lsr & UART_LSR_TEMT && iir & UART_IIR_NO_INT) {
+		if (!(up->bugs & UART_BUG_TXEN)) {
+			up->bugs |= UART_BUG_TXEN;
+			pr_debug("ttyS%d - enabling bad tx status workarounds\n",
+				 port->line);
+		}
+	} else {
+		up->bugs &= ~UART_BUG_TXEN;
+	}
+
 	spin_unlock_irqrestore(&up->port.lock, flags);
 
 	/*
@@ -1645,22 +1669,22 @@ serial8250_set_termios(struct uart_port 
 
 	switch (termios->c_cflag & CSIZE) {
 	case CS5:
-		cval = 0x00;
+		cval = UART_LCR_WLEN5;
 		break;
 	case CS6:
-		cval = 0x01;
+		cval = UART_LCR_WLEN6;
 		break;
 	case CS7:
-		cval = 0x02;
+		cval = UART_LCR_WLEN7;
 		break;
 	default:
 	case CS8:
-		cval = 0x03;
+		cval = UART_LCR_WLEN8;
 		break;
 	}
 
 	if (termios->c_cflag & CSTOPB)
-		cval |= 0x04;
+		cval |= UART_LCR_STOP;
 	if (termios->c_cflag & PARENB)
 		cval |= UART_LCR_PARITY;
 	if (!(termios->c_cflag & PARODD))
@@ -1677,12 +1701,9 @@ serial8250_set_termios(struct uart_port 
 	quot = serial8250_get_divisor(port, baud);
 
 	/*
-	 * Work around a bug in the Oxford Semiconductor 952 rev B
-	 * chip which causes it to seriously miscalculate baud rates
-	 * when DLL is 0.
+	 * Oxford Semi 952 rev B workaround
 	 */
-	if ((quot & 0xff) == 0 && up->port.type == PORT_16C950 &&
-	    up->rev == 0x5201)
+	if (up->bugs & UART_BUG_QUOT && (quot & 0xff) == 0)
 		quot ++;
 
 	if (up->capabilities & UART_CAP_FIFO && up->port.fifosize > 1) {
@@ -2040,7 +2061,8 @@ static void __init serial8250_isa_init_p
 		up->port.ops = &serial8250_pops;
 	}
 
-	for (i = 0, up = serial8250_ports; i < ARRAY_SIZE(old_serial_port);
+	for (i = 0, up = serial8250_ports;
+	     i < ARRAY_SIZE(old_serial_port) && i < UART_NR;
 	     i++, up++) {
 		up->port.iobase   = old_serial_port[i].port;
 		up->port.irq      = irq_canonicalize(old_serial_port[i].irq);
@@ -2289,10 +2311,11 @@ static int __devinit serial8250_probe(st
 {
 	struct plat_serial8250_port *p = dev->platform_data;
 	struct uart_port port;
+	int ret, i;
 
 	memset(&port, 0, sizeof(struct uart_port));
 
-	for (; p && p->flags != 0; p++) {
+	for (i = 0; p && p->flags != 0; p++, i++) {
 		port.iobase	= p->iobase;
 		port.membase	= p->membase;
 		port.irq	= p->irq;
@@ -2301,10 +2324,16 @@ static int __devinit serial8250_probe(st
 		port.iotype	= p->iotype;
 		port.flags	= p->flags;
 		port.mapbase	= p->mapbase;
+		port.hub6	= p->hub6;
 		port.dev	= dev;
 		if (share_irqs)
 			port.flags |= UPF_SHARE_IRQ;
-		serial8250_register_port(&port);
+		ret = serial8250_register_port(&port);
+		if (ret < 0) {
+			dev_err(dev, "unable to register port at index %d "
+				"(IO%lx MEM%lx IRQ%d): %d\n", i,
+				p->iobase, p->mapbase, p->irq, ret);
+		}
 	}
 	return 0;
 }
diff --git a/drivers/serial/8250.h b/drivers/serial/8250.h
--- a/drivers/serial/8250.h
+++ b/drivers/serial/8250.h
@@ -51,6 +51,9 @@ struct serial8250_config {
 #define UART_CAP_AFE	(1 << 11)	/* MCR-based hw flow control */
 #define UART_CAP_UUE	(1 << 12)	/* UART needs IER bit 6 set (Xscale) */
 
+#define UART_BUG_QUOT	(1 << 0)	/* UART has buggy quot LSB */
+#define UART_BUG_TXEN	(1 << 1)	/* UART has buggy TX IIR status */
+
 #if defined(__i386__) && (defined(CONFIG_M386) || defined(CONFIG_M486))
 #define _INLINE_ inline
 #else
diff --git a/drivers/serial/8250_accent.c b/drivers/serial/8250_accent.c
new file mode 100644
--- /dev/null
+++ b/drivers/serial/8250_accent.c
@@ -0,0 +1,47 @@
+/*
+ *  linux/drivers/serial/8250_accent.c
+ *
+ *  Copyright (C) 2005 Russell King.
+ *  Data taken from include/asm-i386/serial.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/serial_8250.h>
+
+#define PORT(_base,_irq)				\
+	{						\
+		.iobase		= _base,		\
+		.irq		= _irq,			\
+		.uartclk	= 1843200,		\
+		.iotype		= UPIO_PORT,		\
+		.flags		= UPF_BOOT_AUTOCONF,	\
+	}
+
+static struct plat_serial8250_port accent_data[] = {
+	PORT(0x330, 4),
+	PORT(0x338, 4),
+	{ },
+};
+
+static struct platform_device accent_device = {
+	.name			= "serial8250",
+	.id			= 2,
+	.dev			= {
+		.platform_data	= accent_data,
+	},
+};
+
+static int __init accent_init(void)
+{
+	return platform_device_register(&accent_device);
+}
+
+module_init(accent_init);
+
+MODULE_AUTHOR("Russell King");
+MODULE_DESCRIPTION("8250 serial probe module for Accent Async cards");
+MODULE_LICENSE("GPL");
diff --git a/drivers/serial/8250_boca.c b/drivers/serial/8250_boca.c
new file mode 100644
--- /dev/null
+++ b/drivers/serial/8250_boca.c
@@ -0,0 +1,61 @@
+/*
+ *  linux/drivers/serial/8250_boca.c
+ *
+ *  Copyright (C) 2005 Russell King.
+ *  Data taken from include/asm-i386/serial.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/serial_8250.h>
+
+#define PORT(_base,_irq)				\
+	{						\
+		.iobase		= _base,		\
+		.irq		= _irq,			\
+		.uartclk	= 1843200,		\
+		.iotype		= UPIO_PORT,		\
+		.flags		= UPF_BOOT_AUTOCONF,	\
+	}
+
+static struct plat_serial8250_port boca_data[] = {
+	PORT(0x100, 12),
+	PORT(0x108, 12),
+	PORT(0x110, 12),
+	PORT(0x118, 12),
+	PORT(0x120, 12),
+	PORT(0x128, 12),
+	PORT(0x130, 12),
+	PORT(0x138, 12),
+	PORT(0x140, 12),
+	PORT(0x148, 12),
+	PORT(0x150, 12),
+	PORT(0x158, 12),
+	PORT(0x160, 12),
+	PORT(0x168, 12),
+	PORT(0x170, 12),
+	PORT(0x178, 12),
+	{ },
+};
+
+static struct platform_device boca_device = {
+	.name			= "serial8250",
+	.id			= 3,
+	.dev			= {
+		.platform_data	= boca_data,
+	},
+};
+
+static int __init boca_init(void)
+{
+	return platform_device_register(&boca_device);
+}
+
+module_init(boca_init);
+
+MODULE_AUTHOR("Russell King");
+MODULE_DESCRIPTION("8250 serial probe module for Boca cards");
+MODULE_LICENSE("GPL");
diff --git a/drivers/serial/8250_fourport.c b/drivers/serial/8250_fourport.c
new file mode 100644
--- /dev/null
+++ b/drivers/serial/8250_fourport.c
@@ -0,0 +1,53 @@
+/*
+ *  linux/drivers/serial/8250_fourport.c
+ *
+ *  Copyright (C) 2005 Russell King.
+ *  Data taken from include/asm-i386/serial.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/serial_8250.h>
+
+#define PORT(_base,_irq)						\
+	{								\
+		.iobase		= _base,				\
+		.irq		= _irq,					\
+		.uartclk	= 1843200,				\
+		.iotype		= UPIO_PORT,				\
+		.flags		= UPF_BOOT_AUTOCONF | UPF_FOURPORT,	\
+	}
+
+static struct plat_serial8250_port fourport_data[] = {
+	PORT(0x1a0, 9),
+	PORT(0x1a8, 9),
+	PORT(0x1b0, 9),
+	PORT(0x1b8, 9),
+	PORT(0x2a0, 5),
+	PORT(0x2a8, 5),
+	PORT(0x2b0, 5),
+	PORT(0x2b8, 5),
+	{ },
+};
+
+static struct platform_device fourport_device = {
+	.name			= "serial8250",
+	.id			= 1,
+	.dev			= {
+		.platform_data	= fourport_data,
+	},
+};
+
+static int __init fourport_init(void)
+{
+	return platform_device_register(&fourport_device);
+}
+
+module_init(fourport_init);
+
+MODULE_AUTHOR("Russell King");
+MODULE_DESCRIPTION("8250 serial probe module for AST Fourport cards");
+MODULE_LICENSE("GPL");
diff --git a/drivers/serial/8250_hub6.c b/drivers/serial/8250_hub6.c
new file mode 100644
--- /dev/null
+++ b/drivers/serial/8250_hub6.c
@@ -0,0 +1,58 @@
+/*
+ *  linux/drivers/serial/8250_hub6.c
+ *
+ *  Copyright (C) 2005 Russell King.
+ *  Data taken from include/asm-i386/serial.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/serial_8250.h>
+
+#define HUB6(card,port)							\
+	{								\
+		.iobase		= 0x302,				\
+		.irq		= 3,					\
+		.uartclk	= 1843200,				\
+		.iotype		= UPIO_HUB6,				\
+		.flags		= UPF_BOOT_AUTOCONF,			\
+		.hub6		= (card) << 6 | (port) << 3 | 1,	\
+	}
+
+static struct plat_serial8250_port hub6_data[] = {
+	HUB6(0,0),
+	HUB6(0,1),
+	HUB6(0,2),
+	HUB6(0,3),
+	HUB6(0,4),
+	HUB6(0,5),
+	HUB6(1,0),
+	HUB6(1,1),
+	HUB6(1,2),
+	HUB6(1,3),
+	HUB6(1,4),
+	HUB6(1,5),
+	{ },
+};
+
+static struct platform_device hub6_device = {
+	.name			= "serial8250",
+	.id			= 4,
+	.dev			= {
+		.platform_data	= hub6_data,
+	},
+};
+
+static int __init hub6_init(void)
+{
+	return platform_device_register(&hub6_device);
+}
+
+module_init(hub6_init);
+
+MODULE_AUTHOR("Russell King");
+MODULE_DESCRIPTION("8250 serial probe module for Hub6 cards");
+MODULE_LICENSE("GPL");
diff --git a/drivers/serial/8250_mca.c b/drivers/serial/8250_mca.c
new file mode 100644
--- /dev/null
+++ b/drivers/serial/8250_mca.c
@@ -0,0 +1,64 @@
+/*
+ *  linux/drivers/serial/8250_mca.c
+ *
+ *  Copyright (C) 2005 Russell King.
+ *  Data taken from include/asm-i386/serial.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/mca.h>
+#include <linux/serial_8250.h>
+
+/*
+ * FIXME: Should we be doing AUTO_IRQ here?
+ */
+#ifdef CONFIG_SERIAL_8250_DETECT_IRQ
+#define MCA_FLAGS	UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_AUTO_IRQ
+#else
+#define MCA_FLAGS	UPF_BOOT_AUTOCONF | UPF_SKIP_TEST
+#endif
+
+#define PORT(_base,_irq)			\
+	{					\
+		.iobase		= _base,	\
+		.irq		= _irq,		\
+		.uartclk	= 1843200,	\
+		.iotype		= UPIO_PORT,	\
+		.flags		= MCA_FLAGS,	\
+	}
+
+static struct plat_serial8250_port mca_data[] = {
+	PORT(0x3220, 3),
+	PORT(0x3228, 3),
+	PORT(0x4220, 3),
+	PORT(0x4228, 3),
+	PORT(0x5220, 3),
+	PORT(0x5228, 3),
+	{ },
+};
+
+static struct platform_device mca_device = {
+	.name			= "serial8250",
+	.id			= 5,
+	.dev			= {
+		.platform_data	= mca_data,
+	},
+};
+
+static int __init mca_init(void)
+{
+	if (!MCA_bus)
+		return -ENODEV;
+	return platform_device_register(&mca_device);
+}
+
+module_init(mca_init);
+
+MODULE_AUTHOR("Russell King");
+MODULE_DESCRIPTION("8250 serial probe module for MCA ports");
+MODULE_LICENSE("GPL");
diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c
--- a/drivers/serial/8250_pci.c
+++ b/drivers/serial/8250_pci.c
@@ -389,6 +389,9 @@ static void __devexit sbs_exit(struct pc
  *     - 10x cards have control registers in IO and/or memory space;
  *     - 20x cards have control registers in standard PCI configuration space.
  *
+ * There are also Quartet Serial cards which use Oxford Semiconductor
+ * 16954 quad UART PCI chip clocked by 18.432 MHz quartz.
+ *
  * Note: some SIIG cards are probed by the parport_serial object.
  */
 
@@ -1026,6 +1029,10 @@ enum pci_board_num_t {
 	pbn_b0_2_921600,
 	pbn_b0_4_921600,
 
+	pbn_b0_2_1130000,
+
+	pbn_b0_4_1152000,
+
 	pbn_b0_bt_1_115200,
 	pbn_b0_bt_2_115200,
 	pbn_b0_bt_8_115200,
@@ -1159,6 +1166,20 @@ static struct pci_board pci_boards[] __d
 		.uart_offset	= 8,
 	},
 
+	[pbn_b0_2_1130000] = {
+		.flags          = FL_BASE0,
+		.num_ports      = 2,
+		.base_baud      = 1130000,
+		.uart_offset    = 8,
+	},
+
+	[pbn_b0_4_1152000] = {
+		.flags		= FL_BASE0,
+		.num_ports	= 4,
+		.base_baud	= 1152000,
+		.uart_offset	= 8,
+	},
+
 	[pbn_b0_bt_1_115200] = {
 		.flags		= FL_BASE0|FL_BASE_BARS,
 		.num_ports	= 1,
@@ -1755,33 +1776,30 @@ pciserial_init_one(struct pci_dev *dev, 
 static void __devexit pciserial_remove_one(struct pci_dev *dev)
 {
 	struct serial_private *priv = pci_get_drvdata(dev);
+	struct pci_serial_quirk *quirk;
+	int i;
 
 	pci_set_drvdata(dev, NULL);
 
-	if (priv) {
-		struct pci_serial_quirk *quirk;
-		int i;
-
-		for (i = 0; i < priv->nr; i++)
-			serial8250_unregister_port(priv->line[i]);
+	for (i = 0; i < priv->nr; i++)
+		serial8250_unregister_port(priv->line[i]);
 
-		for (i = 0; i < PCI_NUM_BAR_RESOURCES; i++) {
-			if (priv->remapped_bar[i])
-				iounmap(priv->remapped_bar[i]);
-			priv->remapped_bar[i] = NULL;
-		}
+	for (i = 0; i < PCI_NUM_BAR_RESOURCES; i++) {
+		if (priv->remapped_bar[i])
+			iounmap(priv->remapped_bar[i]);
+		priv->remapped_bar[i] = NULL;
+	}
 
-		/*
-		 * Find the exit quirks.
-		 */
-		quirk = find_quirk(dev);
-		if (quirk->exit)
-			quirk->exit(dev);
+	/*
+	 * Find the exit quirks.
+	 */
+	quirk = find_quirk(dev);
+	if (quirk->exit)
+		quirk->exit(dev);
 
-		pci_disable_device(dev);
+	pci_disable_device(dev);
 
-		kfree(priv);
-	}
+	kfree(priv);
 }
 
 static int pciserial_suspend_one(struct pci_dev *dev, pm_message_t state)
@@ -1978,6 +1996,19 @@ static struct pci_device_id serial_pci_t
 		PCI_VENDOR_ID_SPECIALIX, PCI_SUBDEVICE_ID_SPECIALIX_SPEED4, 0, 0,
 		pbn_b0_4_921600 },
 	{	PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI954,
+		PCI_SUBVENDOR_ID_SIIG, PCI_SUBDEVICE_ID_SIIG_QUARTET_SERIAL, 0, 0,
+		pbn_b0_4_1152000 },
+
+		/*
+		 * The below card is a little controversial since it is the
+		 * subject of a PCI vendor/device ID clash.  (See
+		 * www.ussg.iu.edu/hypermail/linux/kernel/0303.1/0516.html).
+		 * For now just used the hex ID 0x950a.
+		 */
+	{	PCI_VENDOR_ID_OXSEMI, 0x950a,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_b0_2_1130000 },
+	{	PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI954,
 		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
 		pbn_b0_4_115200 },
 	{	PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI952,
diff --git a/drivers/serial/8250_pnp.c b/drivers/serial/8250_pnp.c
--- a/drivers/serial/8250_pnp.c
+++ b/drivers/serial/8250_pnp.c
@@ -394,7 +394,7 @@ static int __devinit serial_pnp_guess_bo
 }
 
 static int __devinit
-serial_pnp_probe(struct pnp_dev * dev, const struct pnp_device_id *dev_id)
+serial_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)
 {
 	struct uart_port port;
 	int ret, line, flags = dev_id->driver_data;
@@ -406,15 +406,23 @@ serial_pnp_probe(struct pnp_dev * dev, c
 	}
 
 	memset(&port, 0, sizeof(struct uart_port));
-	port.irq = pnp_irq(dev,0);
-	port.iobase = pnp_port_start(dev, 0);
+	port.irq = pnp_irq(dev, 0);
+	if (pnp_port_valid(dev, 0)) {
+		port.iobase = pnp_port_start(dev, 0);
+		port.iotype = UPIO_PORT;
+	} else if (pnp_mem_valid(dev, 0)) {
+		port.mapbase = pnp_mem_start(dev, 0);
+		port.iotype = UPIO_MEM;
+		port.flags = UPF_IOREMAP;
+	} else
+		return -ENODEV;
 
 #ifdef SERIAL_DEBUG_PNP
-	printk("Setup PNP port: port %x, irq %d, type %d\n",
-	       port.iobase, port.irq, port.iotype);
+	printk("Setup PNP port: port %x, mem 0x%lx, irq %d, type %d\n",
+	       port.iobase, port.mapbase, port.irq, port.iotype);
 #endif
 
-	port.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF;
+	port.flags |= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF;
 	port.uartclk = 1843200;
 	port.dev = &dev->dev;
 
@@ -426,7 +434,7 @@ serial_pnp_probe(struct pnp_dev * dev, c
 
 }
 
-static void __devexit serial_pnp_remove(struct pnp_dev * dev)
+static void __devexit serial_pnp_remove(struct pnp_dev *dev)
 {
 	long line = (long)pnp_get_drvdata(dev);
 	if (line)
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -86,14 +86,14 @@ config SERIAL_8250_ACPI
 	  namespace, say Y here.  If unsure, say N.
 
 config SERIAL_8250_NR_UARTS
-	int "Maximum number of non-legacy 8250/16550 serial ports"
+	int "Maximum number of 8250/16550 serial ports"
 	depends on SERIAL_8250
 	default "4"
-	---help---
-	  Set this to the number of non-legacy serial ports you want
-	  the driver to support.  This includes any ports discovered
-	  via ACPI or PCI enumeration and any ports that may be added
-	  at run-time via hot-plug.
+	help
+	  Set this to the number of serial ports you want the driver
+	  to support.  This includes any ports discovered via ACPI or
+	  PCI enumeration and any ports that may be added at run-time
+	  via hot-plug, or any ISA multi-port serial cards.
 
 config SERIAL_8250_EXTENDED
 	bool "Extended 8250/16550 serial driver options"
@@ -141,34 +141,77 @@ config SERIAL_8250_DETECT_IRQ
 
 	  If unsure, say N.
 
-config SERIAL_8250_MULTIPORT
-	bool "Support special multiport boards"
-	depends on SERIAL_8250_EXTENDED
-	help
-	  Some multiport serial ports have special ports which are used to
-	  signal when there are any serial ports on the board which need
-	  servicing. Say Y here to enable the serial driver to take advantage
-	  of those special I/O ports.
-
 config SERIAL_8250_RSA
 	bool "Support RSA serial ports"
 	depends on SERIAL_8250_EXTENDED
 	help
 	  ::: To be written :::
 
-comment "Non-8250 serial port support"
+#
+# Multi-port serial cards
+#
+
+config SERIAL_8250_FOURPORT
+	tristate "Support Fourport cards"
+	depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS
+	help
+	  Say Y here if you have an AST FourPort serial board.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called 8250_fourport.
+
+config SERIAL_8250_ACCENT
+	tristate "Support Accent cards"
+	depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS
+	help
+	  Say Y here if you have an Accent Async serial board.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called 8250_accent.
+
+
+config SERIAL_8250_BOCA
+	tristate "Support Boca cards"
+	depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS
+	help
+	  Say Y here if you have a Boca serial board.  Please read the Boca
+	  mini-HOWTO, avaialble from <http://www.tldp.org/docs.html#howto>
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called 8250_boca.
+
+
+config SERIAL_8250_HUB6
+	tristate "Support Hub6 cards"
+	depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS
+	help
+	  Say Y here if you have a HUB6 serial board.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called 8250_hub6.
+
+config SERIAL_8250_MCA
+	tristate "Support 8250-type ports on MCA buses"
+	depends on SERIAL_8250 != n && MCA
+	help
+	  Say Y here if you have a MCA serial ports.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called 8250_mca.
 
 config SERIAL_8250_ACORN
 	tristate "Acorn expansion card serial port support"
-	depends on ARM && ARCH_ACORN && SERIAL_8250
+	depends on ARCH_ACORN && SERIAL_8250
 	help
 	  If you have an Atomwide Serial card or Serial Port card for an Acorn
 	  system, say Y to this option.  The driver can handle 1, 2, or 3 port
 	  cards.  If unsure, say N.
 
+comment "Non-8250 serial port support"
+
 config SERIAL_AMBA_PL010
 	tristate "ARM AMBA PL010 serial port support"
-	depends on ARM_AMBA
+	depends on ARM_AMBA && (BROKEN || !ARCH_VERSATILE)
 	select SERIAL_CORE
 	help
 	  This selects the ARM(R) AMBA(R) PrimeCell PL010 UART.  If you have
@@ -263,13 +306,6 @@ config SERIAL_S3C2410_CONSOLE
 	  your boot loader about how to pass options to the kernel at
 	  boot time.)
 
-config SERIAL_BAST_SIO
-	bool "Support for BAST SuperIO serial ports"
-	depends on ARCH_BAST && SERIAL_8250=y
-	help
-	  Support for registerin the SuperIO chip on BAST board with
-	  the 8250/16550 uart code.
-
 config SERIAL_DZ
 	bool "DECstation DZ serial driver"
 	depends on MACH_DECSTATION && MIPS32
@@ -753,7 +789,7 @@ config SERIAL_MPC52xx_CONSOLE_BAUD
 
 config SERIAL_ICOM
 	tristate "IBM Multiport Serial Adapter"
-	depends on PPC_ISERIES || PPC_PSERIES
+	depends on PCI && (PPC_ISERIES || PPC_PSERIES)
 	select SERIAL_CORE
 	help
 	  This driver is for a family of multiport serial adapters
@@ -783,7 +819,7 @@ config SERIAL_M32R_SIO_CONSOLE
 
 config SERIAL_M32R_PLDSIO
 	bool "M32R SIO I/F on a PLD"
-	depends on SERIAL_M32R_SIO=y
+	depends on SERIAL_M32R_SIO=y && (PLAT_OPSPUT || PALT_USRV || PLAT_M32700UT)
 	default n
 	help
 	  Say Y here if you want to use the M32R serial controller
@@ -843,4 +879,13 @@ config SERIAL_JSM
           To compile this driver as a module, choose M here: the
           module will be called jsm.
 
+config SERIAL_SGI_IOC4
+	tristate "SGI IOC4 controller serial support"
+	depends on (IA64_GENERIC || IA64_SGI_SN2) && SGI_IOC4
+	select SERIAL_CORE
+	help
+		If you have an SGI Altix with an IOC4 based Base IO card
+		and wish to use the serial ports on this card, say Y.
+		Otherwise, say N.
+
 endmenu
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -17,6 +17,11 @@ obj-$(CONFIG_SERIAL_8250) += 8250.o $(se
 obj-$(CONFIG_SERIAL_8250_CS) += serial_cs.o
 obj-$(CONFIG_SERIAL_8250_ACORN) += 8250_acorn.o
 obj-$(CONFIG_SERIAL_8250_CONSOLE) += 8250_early.o
+obj-$(CONFIG_SERIAL_8250_FOURPORT) += 8250_fourport.o
+obj-$(CONFIG_SERIAL_8250_ACCENT) += 8250_accent.o
+obj-$(CONFIG_SERIAL_8250_BOCA) += 8250_boca.o
+obj-$(CONFIG_SERIAL_8250_HUB6) += 8250_hub6.o
+obj-$(CONFIG_SERIAL_8250_MCA) += 8250_mca.o
 obj-$(CONFIG_SERIAL_AMBA_PL010) += amba-pl010.o
 obj-$(CONFIG_SERIAL_AMBA_PL011) += amba-pl011.o
 obj-$(CONFIG_SERIAL_CLPS711X) += clps711x.o
@@ -39,7 +44,6 @@ obj-$(CONFIG_SERIAL_LH7A40X) += serial_l
 obj-$(CONFIG_SERIAL_AU1X00) += au1x00_uart.o
 obj-$(CONFIG_SERIAL_DZ) += dz.o
 obj-$(CONFIG_SERIAL_SH_SCI) += sh-sci.o
-obj-$(CONFIG_SERIAL_BAST_SIO) += bast_sio.o
 obj-$(CONFIG_SERIAL_SGI_L1_CONSOLE) += sn_console.o
 obj-$(CONFIG_SERIAL_CPM) += cpm_uart/
 obj-$(CONFIG_SERIAL_IMX) += imx.o
@@ -51,4 +55,4 @@ obj-$(CONFIG_ETRAX_SERIAL) += crisv10.o
 obj-$(CONFIG_SERIAL_JSM) += jsm/
 obj-$(CONFIG_SERIAL_TXX9) += serial_txx9.o
 obj-$(CONFIG_SERIAL_VR41XX) += vr41xx_siu.o
-obj-$(CONFIG_BLK_DEV_SGIIOC4) += ioc4_serial.o
+obj-$(CONFIG_SERIAL_SGI_IOC4) += ioc4_serial.o
diff --git a/drivers/serial/au1x00_uart.c b/drivers/serial/au1x00_uart.c
--- a/drivers/serial/au1x00_uart.c
+++ b/drivers/serial/au1x00_uart.c
@@ -556,13 +556,10 @@ static unsigned int serial8250_tx_empty(
 static unsigned int serial8250_get_mctrl(struct uart_port *port)
 {
 	struct uart_8250_port *up = (struct uart_8250_port *)port;
-	unsigned long flags;
 	unsigned char status;
 	unsigned int ret;
 
-	spin_lock_irqsave(&up->port.lock, flags);
 	status = serial_in(up, UART_MSR);
-	spin_unlock_irqrestore(&up->port.lock, flags);
 
 	ret = 0;
 	if (status & UART_MSR_DCD)
@@ -773,22 +770,22 @@ serial8250_set_termios(struct uart_port 
 
 	switch (termios->c_cflag & CSIZE) {
 	case CS5:
-		cval = 0x00;
+		cval = UART_LCR_WLEN5;
 		break;
 	case CS6:
-		cval = 0x01;
+		cval = UART_LCR_WLEN6;
 		break;
 	case CS7:
-		cval = 0x02;
+		cval = UART_LCR_WLEN7;
 		break;
 	default:
 	case CS8:
-		cval = 0x03;
+		cval = UART_LCR_WLEN8;
 		break;
 	}
 
 	if (termios->c_cflag & CSTOPB)
-		cval |= 0x04;
+		cval |= UART_LCR_STOP;
 	if (termios->c_cflag & PARENB)
 		cval |= UART_LCR_PARITY;
 	if (!(termios->c_cflag & PARODD))
diff --git a/drivers/serial/bast_sio.c b/drivers/serial/bast_sio.c
deleted file mode 100644
--- a/drivers/serial/bast_sio.c
+++ /dev/null
@@ -1,80 +0,0 @@
-/* linux/drivers/serial/bast_sio.c
- *
- * Copyright (c) 2004 Simtec Electronics
- *   Ben Dooks <ben@simtec.co.uk>
- *
- * http://www.simtec.co.uk/products/EB2410ITX/
- *
- * 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.
- *
- * Modifications:
- *	23-Sep-2004  BJD  Added copyright header
- *	23-Sep-2004  BJD  Added serial port remove code
-*/
-
-#include <linux/module.h>
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/tty.h>
-#include <linux/serial.h>
-#include <linux/serial_core.h>
-#include <linux/types.h>
-
-#include <asm/io.h>
-#include <asm/serial.h>
-#include <asm/mach-types.h>
-
-#include <asm/arch/map.h>
-#include <asm/arch/irqs.h>
-#include <asm/arch/bast-map.h>
-#include <asm/arch/bast-irq.h>
-
-static int __init serial_bast_register(unsigned long port, unsigned int irq)
-{
-	struct serial_struct serial_req;
-
-	serial_req.flags      = UPF_AUTOPROBE | UPF_SHARE_IRQ;
-	serial_req.baud_base  = BASE_BAUD;
-	serial_req.irq        = irq;
-	serial_req.io_type    = UPIO_MEM;
-	serial_req.iomap_base = port;
-	serial_req.iomem_base = ioremap(port, 0x10);
-	serial_req.iomem_reg_shift = 0;
-
-	return register_serial(&serial_req);
-}
-
-#define SERIAL_BASE (S3C2410_CS2 + BAST_PA_SUPERIO)
-
-static int port[2] = { -1, -1 };
-
-static int __init serial_bast_init(void)
-{
-	if (machine_is_bast()) {
-		port[0] = serial_bast_register(SERIAL_BASE + 0x2f8, IRQ_PCSERIAL1);
-		port[1] = serial_bast_register(SERIAL_BASE + 0x3f8, IRQ_PCSERIAL2);
-	}
-
-	return 0;
-}
-
-static void __exit serial_bast_exit(void)
-{
-	if (port[0] != -1)
-		unregister_serial(port[0]);
-	if (port[1] != -1)
-		unregister_serial(port[1]);
-}
-
-
-module_init(serial_bast_init);
-module_exit(serial_bast_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Ben Dooks, ben@simtec.co.uk");
-MODULE_DESCRIPTION("BAST Onboard Serial setup");
-
-
diff --git a/drivers/serial/cpm_uart/cpm_uart.h b/drivers/serial/cpm_uart/cpm_uart.h
--- a/drivers/serial/cpm_uart/cpm_uart.h
+++ b/drivers/serial/cpm_uart/cpm_uart.h
@@ -40,13 +40,15 @@
 #define TX_NUM_FIFO	4
 #define TX_BUF_SIZE	32
 
+#define SCC_WAIT_CLOSING 100
+
 struct uart_cpm_port {
 	struct uart_port	port;
-	u16			rx_nrfifos;	
+	u16			rx_nrfifos;
 	u16			rx_fifosize;
-	u16			tx_nrfifos;	
+	u16			tx_nrfifos;
 	u16			tx_fifosize;
-	smc_t			*smcp;	
+	smc_t			*smcp;
 	smc_uart_t		*smcup;
 	scc_t			*sccp;
 	scc_uart_t		*sccup;
@@ -67,6 +69,8 @@ struct uart_cpm_port {
 	int			 bits;
 	/* Keep track of 'odd' SMC2 wirings */
 	int			is_portb;
+	/* wait on close if needed */
+	int 			wait_closing;
 };
 
 extern int cpm_uart_port_map[UART_NR];
diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c
--- a/drivers/serial/cpm_uart/cpm_uart_core.c
+++ b/drivers/serial/cpm_uart/cpm_uart_core.c
@@ -9,9 +9,10 @@
  *
  *  Maintainer: Kumar Gala (kumar.gala@freescale.com) (CPM2)
  *              Pantelis Antoniou (panto@intracom.gr) (CPM1)
- * 
+ *
  *  Copyright (C) 2004 Freescale Semiconductor, Inc.
  *            (C) 2004 Intracom, S.A.
+ *            (C) 2005 MontaVista Software, Inc. by Vitaly Bordug <vbordug@ru.mvista.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
@@ -70,8 +71,22 @@ static void cpm_uart_initbd(struct uart_
 
 /**************************************************************/
 
+static inline unsigned long cpu2cpm_addr(void *addr)
+{
+	if ((unsigned long)addr >= CPM_ADDR)
+		return (unsigned long)addr;
+	return virt_to_bus(addr);
+}
+
+static inline void *cpm2cpu_addr(unsigned long addr)
+{
+	if (addr >= CPM_ADDR)
+		return (void *)addr;
+	return bus_to_virt(addr);
+}
+
 /*
- * Check, if transmit buffers are processed		
+ * Check, if transmit buffers are processed
 */
 static unsigned int cpm_uart_tx_empty(struct uart_port *port)
 {
@@ -143,15 +158,18 @@ static void cpm_uart_start_tx(struct uar
 	}
 
 	if (cpm_uart_tx_pump(port) != 0) {
-		if (IS_SMC(pinfo))
+		if (IS_SMC(pinfo)) {
 			smcp->smc_smcm |= SMCM_TX;
-		else
+			smcp->smc_smcmr |= SMCMR_TEN;
+		} else {
 			sccp->scc_sccm |= UART_SCCM_TX;
+			pinfo->sccp->scc_gsmrl |= SCC_GSMRL_ENT;
+		}
 	}
 }
 
 /*
- * Stop receiver 
+ * Stop receiver
  */
 static void cpm_uart_stop_rx(struct uart_port *port)
 {
@@ -176,7 +194,7 @@ static void cpm_uart_enable_ms(struct ua
 }
 
 /*
- * Generate a break. 
+ * Generate a break.
  */
 static void cpm_uart_break_ctl(struct uart_port *port, int break_state)
 {
@@ -231,7 +249,7 @@ static void cpm_uart_int_rx(struct uart_
 		/* get number of characters, and check spce in flip-buffer */
 		i = bdp->cbd_datlen;
 
-		/* If we have not enough room in tty flip buffer, then we try 
+		/* If we have not enough room in tty flip buffer, then we try
 		 * later, which will be the next rx-interrupt or a timeout
 		 */
 		if ((tty->flip.count + i) >= TTY_FLIPBUF_SIZE) {
@@ -243,7 +261,7 @@ static void cpm_uart_int_rx(struct uart_
 		}
 
 		/* get pointer */
-		cp = (unsigned char *)bus_to_virt(bdp->cbd_bufaddr);
+		cp = cpm2cpu_addr(bdp->cbd_bufaddr);
 
 		/* loop through the buffer */
 		while (i-- > 0) {
@@ -265,13 +283,14 @@ static void cpm_uart_int_rx(struct uart_
 		}		/* End while (i--) */
 
 		/* This BD is ready to be used again. Clear status. get next */
-		bdp->cbd_sc &= ~(BD_SC_BR | BD_SC_FR | BD_SC_PR | BD_SC_OV);
+		bdp->cbd_sc &= ~(BD_SC_BR | BD_SC_FR | BD_SC_PR | BD_SC_OV | BD_SC_ID);
 		bdp->cbd_sc |= BD_SC_EMPTY;
 
 		if (bdp->cbd_sc & BD_SC_WRAP)
 			bdp = pinfo->rx_bd_base;
 		else
 			bdp++;
+
 	} /* End for (;;) */
 
 	/* Write back buffer pointer */
@@ -336,22 +355,22 @@ static irqreturn_t cpm_uart_int(int irq,
 
 	if (IS_SMC(pinfo)) {
 		events = smcp->smc_smce;
+		smcp->smc_smce = events;
 		if (events & SMCM_BRKE)
 			uart_handle_break(port);
 		if (events & SMCM_RX)
 			cpm_uart_int_rx(port, regs);
 		if (events & SMCM_TX)
 			cpm_uart_int_tx(port, regs);
-		smcp->smc_smce = events;
 	} else {
 		events = sccp->scc_scce;
+		sccp->scc_scce = events;
 		if (events & UART_SCCM_BRKE)
 			uart_handle_break(port);
 		if (events & UART_SCCM_RX)
 			cpm_uart_int_rx(port, regs);
 		if (events & UART_SCCM_TX)
 			cpm_uart_int_tx(port, regs);
-		sccp->scc_scce = events;
 	}
 	return (events) ? IRQ_HANDLED : IRQ_NONE;
 }
@@ -360,6 +379,7 @@ static int cpm_uart_startup(struct uart_
 {
 	int retval;
 	struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
+	int line = pinfo - cpm_uart_ports;
 
 	pr_debug("CPM uart[%d]:startup\n", port->line);
 
@@ -376,9 +396,19 @@ static int cpm_uart_startup(struct uart_
 		pinfo->sccp->scc_sccm |= UART_SCCM_RX;
 	}
 
+	if (!(pinfo->flags & FLAG_CONSOLE))
+		cpm_line_cr_cmd(line,CPM_CR_INIT_TRX);
 	return 0;
 }
 
+inline void cpm_uart_wait_until_send(struct uart_cpm_port *pinfo)
+{
+	unsigned long target_jiffies = jiffies + pinfo->wait_closing;
+
+	while (!time_after(jiffies, target_jiffies))
+   		schedule();
+}
+
 /*
  * Shutdown the uart
  */
@@ -394,6 +424,12 @@ static void cpm_uart_shutdown(struct uar
 
 	/* If the port is not the console, disable Rx and Tx. */
 	if (!(pinfo->flags & FLAG_CONSOLE)) {
+		/* Wait for all the BDs marked sent */
+		while(!cpm_uart_tx_empty(port))
+			schedule_timeout(2);
+		if(pinfo->wait_closing)
+			cpm_uart_wait_until_send(pinfo);
+
 		/* Stop uarts */
 		if (IS_SMC(pinfo)) {
 			volatile smc_t *smcp = pinfo->smcp;
@@ -502,7 +538,7 @@ static void cpm_uart_set_termios(struct 
 	 */
 	if ((termios->c_cflag & CREAD) == 0)
 		port->read_status_mask &= ~BD_SC_EMPTY;
-	
+
 	spin_lock_irqsave(&port->lock, flags);
 
 	/* Start bit has not been added (so don't, because we would just
@@ -569,7 +605,8 @@ static int cpm_uart_tx_pump(struct uart_
 		/* Pick next descriptor and fill from buffer */
 		bdp = pinfo->tx_cur;
 
-		p = bus_to_virt(bdp->cbd_bufaddr);
+		p = cpm2cpu_addr(bdp->cbd_bufaddr);
+
 		*p++ = xmit->buf[xmit->tail];
 		bdp->cbd_datlen = 1;
 		bdp->cbd_sc |= BD_SC_READY;
@@ -595,7 +632,7 @@ static int cpm_uart_tx_pump(struct uart_
 
 	while (!(bdp->cbd_sc & BD_SC_READY) && (xmit->tail != xmit->head)) {
 		count = 0;
-		p = bus_to_virt(bdp->cbd_bufaddr);
+		p = cpm2cpu_addr(bdp->cbd_bufaddr);
 		while (count < pinfo->tx_fifosize) {
 			*p++ = xmit->buf[xmit->tail];
 			xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
@@ -606,6 +643,7 @@ static int cpm_uart_tx_pump(struct uart_
 		}
 		bdp->cbd_datlen = count;
 		bdp->cbd_sc |= BD_SC_READY;
+		__asm__("eieio");
 		/* Get next BD. */
 		if (bdp->cbd_sc & BD_SC_WRAP)
 			bdp = pinfo->tx_bd_base;
@@ -643,12 +681,12 @@ static void cpm_uart_initbd(struct uart_
 	mem_addr = pinfo->mem_addr;
 	bdp = pinfo->rx_cur = pinfo->rx_bd_base;
 	for (i = 0; i < (pinfo->rx_nrfifos - 1); i++, bdp++) {
-		bdp->cbd_bufaddr = virt_to_bus(mem_addr);
+		bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr);
 		bdp->cbd_sc = BD_SC_EMPTY | BD_SC_INTRPT;
 		mem_addr += pinfo->rx_fifosize;
 	}
-	
-	bdp->cbd_bufaddr = virt_to_bus(mem_addr);
+
+	bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr);
 	bdp->cbd_sc = BD_SC_WRAP | BD_SC_EMPTY | BD_SC_INTRPT;
 
 	/* Set the physical address of the host memory
@@ -658,12 +696,12 @@ static void cpm_uart_initbd(struct uart_
 	mem_addr = pinfo->mem_addr + L1_CACHE_ALIGN(pinfo->rx_nrfifos * pinfo->rx_fifosize);
 	bdp = pinfo->tx_cur = pinfo->tx_bd_base;
 	for (i = 0; i < (pinfo->tx_nrfifos - 1); i++, bdp++) {
-		bdp->cbd_bufaddr = virt_to_bus(mem_addr);
+		bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr);
 		bdp->cbd_sc = BD_SC_INTRPT;
 		mem_addr += pinfo->tx_fifosize;
 	}
-	
-	bdp->cbd_bufaddr = virt_to_bus(mem_addr);
+
+	bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr);
 	bdp->cbd_sc = BD_SC_WRAP | BD_SC_INTRPT;
 }
 
@@ -763,6 +801,8 @@ static void cpm_uart_init_smc(struct uar
 	/* Using idle charater time requires some additional tuning.  */
 	up->smc_mrblr = pinfo->rx_fifosize;
 	up->smc_maxidl = pinfo->rx_fifosize;
+	up->smc_brklen = 0;
+	up->smc_brkec = 0;
 	up->smc_brkcr = 1;
 
 	cpm_line_cr_cmd(line, CPM_CR_INIT_TRX);
@@ -796,7 +836,7 @@ static int cpm_uart_request_port(struct 
 	/*
 	 * Setup any port IO, connect any baud rate generators,
 	 * etc.  This is expected to be handled by board
-	 * dependant code 
+	 * dependant code
 	 */
 	if (pinfo->set_lineif)
 		pinfo->set_lineif(pinfo);
@@ -815,6 +855,10 @@ static int cpm_uart_request_port(struct 
 		return ret;
 
 	cpm_uart_initbd(pinfo);
+	if (IS_SMC(pinfo))
+		cpm_uart_init_smc(pinfo);
+	else
+		cpm_uart_init_scc(pinfo);
 
 	return 0;
 }
@@ -869,7 +913,7 @@ struct uart_cpm_port cpm_uart_ports[UART
 		.flags = FLAG_SMC,
 		.tx_nrfifos = TX_NUM_FIFO,
 		.tx_fifosize = TX_BUF_SIZE,
-		.rx_nrfifos = RX_NUM_FIFO, 
+		.rx_nrfifos = RX_NUM_FIFO,
 		.rx_fifosize = RX_BUF_SIZE,
 		.set_lineif = smc1_lineif,
 	},
@@ -883,7 +927,7 @@ struct uart_cpm_port cpm_uart_ports[UART
 		.flags = FLAG_SMC,
 		.tx_nrfifos = TX_NUM_FIFO,
 		.tx_fifosize = TX_BUF_SIZE,
-		.rx_nrfifos = RX_NUM_FIFO, 
+		.rx_nrfifos = RX_NUM_FIFO,
 		.rx_fifosize = RX_BUF_SIZE,
 		.set_lineif = smc2_lineif,
 #ifdef CONFIG_SERIAL_CPM_ALT_SMC2
@@ -899,9 +943,10 @@ struct uart_cpm_port cpm_uart_ports[UART
 		},
 		.tx_nrfifos = TX_NUM_FIFO,
 		.tx_fifosize = TX_BUF_SIZE,
-		.rx_nrfifos = RX_NUM_FIFO, 
+		.rx_nrfifos = RX_NUM_FIFO,
 		.rx_fifosize = RX_BUF_SIZE,
 		.set_lineif = scc1_lineif,
+		.wait_closing = SCC_WAIT_CLOSING,
 	},
 	[UART_SCC2] = {
 		.port = {
@@ -912,9 +957,10 @@ struct uart_cpm_port cpm_uart_ports[UART
 		},
 		.tx_nrfifos = TX_NUM_FIFO,
 		.tx_fifosize = TX_BUF_SIZE,
-		.rx_nrfifos = RX_NUM_FIFO, 
+		.rx_nrfifos = RX_NUM_FIFO,
 		.rx_fifosize = RX_BUF_SIZE,
 		.set_lineif = scc2_lineif,
+		.wait_closing = SCC_WAIT_CLOSING,
 	},
 	[UART_SCC3] = {
 		.port = {
@@ -925,9 +971,10 @@ struct uart_cpm_port cpm_uart_ports[UART
 		},
 		.tx_nrfifos = TX_NUM_FIFO,
 		.tx_fifosize = TX_BUF_SIZE,
-		.rx_nrfifos = RX_NUM_FIFO, 
+		.rx_nrfifos = RX_NUM_FIFO,
 		.rx_fifosize = RX_BUF_SIZE,
 		.set_lineif = scc3_lineif,
+		.wait_closing = SCC_WAIT_CLOSING,
 	},
 	[UART_SCC4] = {
 		.port = {
@@ -938,9 +985,10 @@ struct uart_cpm_port cpm_uart_ports[UART
 		},
 		.tx_nrfifos = TX_NUM_FIFO,
 		.tx_fifosize = TX_BUF_SIZE,
-		.rx_nrfifos = RX_NUM_FIFO, 
+		.rx_nrfifos = RX_NUM_FIFO,
 		.rx_fifosize = RX_BUF_SIZE,
 		.set_lineif = scc4_lineif,
+		.wait_closing = SCC_WAIT_CLOSING,
 	},
 };
 
@@ -983,11 +1031,8 @@ static void cpm_uart_console_write(struc
 		 * If the buffer address is in the CPM DPRAM, don't
 		 * convert it.
 		 */
-		if ((uint) (bdp->cbd_bufaddr) > (uint) CPM_ADDR)
-			cp = (unsigned char *) (bdp->cbd_bufaddr);
-		else
-			cp = bus_to_virt(bdp->cbd_bufaddr);
-		
+		cp = cpm2cpu_addr(bdp->cbd_bufaddr);
+
 		*cp = *s;
 
 		bdp->cbd_datlen = 1;
@@ -1003,10 +1048,7 @@ static void cpm_uart_console_write(struc
 			while ((bdp->cbd_sc & BD_SC_READY) != 0)
 				;
 
-			if ((uint) (bdp->cbd_bufaddr) > (uint) CPM_ADDR)
-				cp = (unsigned char *) (bdp->cbd_bufaddr);
-			else
-				cp = bus_to_virt(bdp->cbd_bufaddr);
+			cp = cpm2cpu_addr(bdp->cbd_bufaddr);
 
 			*cp = 13;
 			bdp->cbd_datlen = 1;
@@ -1045,7 +1087,7 @@ static int __init cpm_uart_console_setup
 	port =
 	    (struct uart_port *)&cpm_uart_ports[cpm_uart_port_map[co->index]];
 	pinfo = (struct uart_cpm_port *)port;
-	
+
 	pinfo->flags |= FLAG_CONSOLE;
 
 	if (options) {
@@ -1062,7 +1104,7 @@ static int __init cpm_uart_console_setup
 	/*
 	 * Setup any port IO, connect any baud rate generators,
 	 * etc.  This is expected to be handled by board
-	 * dependant code 
+	 * dependant code
 	 */
 	if (pinfo->set_lineif)
 		pinfo->set_lineif(pinfo);
@@ -1092,14 +1134,14 @@ static int __init cpm_uart_console_setup
 	return 0;
 }
 
-extern struct uart_driver cpm_reg;
+static struct uart_driver cpm_reg;
 static struct console cpm_scc_uart_console = {
-	.name		"ttyCPM",
-	.write		cpm_uart_console_write,
-	.device		uart_console_device,
-	.setup		cpm_uart_console_setup,
-	.flags		CON_PRINTBUFFER,
-	.index		-1,
+	.name		= "ttyCPM",
+	.write		= cpm_uart_console_write,
+	.device		= uart_console_device,
+	.setup		= cpm_uart_console_setup,
+	.flags		= CON_PRINTBUFFER,
+	.index		= -1,
 	.data		= &cpm_reg,
 };
 
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm1.c b/drivers/serial/cpm_uart/cpm_uart_cpm1.c
--- a/drivers/serial/cpm_uart/cpm_uart_cpm1.c
+++ b/drivers/serial/cpm_uart/cpm_uart_cpm1.c
@@ -5,7 +5,7 @@
  *
  *  Maintainer: Kumar Gala (kumar.gala@freescale.com) (CPM2)
  *              Pantelis Antoniou (panto@intracom.gr) (CPM1)
- * 
+ *
  *  Copyright (C) 2004 Freescale Semiconductor, Inc.
  *            (C) 2004 Intracom, S.A.
  *
@@ -82,6 +82,17 @@ void cpm_line_cr_cmd(int line, int cmd)
 void smc1_lineif(struct uart_cpm_port *pinfo)
 {
 	volatile cpm8xx_t *cp = cpmp;
+
+	(void)cp;	/* fix warning */
+#if defined (CONFIG_MPC885ADS)
+	/* Enable SMC1 transceivers */
+	{
+		cp->cp_pepar |= 0x000000c0;
+		cp->cp_pedir &= ~0x000000c0;
+		cp->cp_peso &= ~0x00000040;
+		cp->cp_peso |= 0x00000080;
+	}
+#elif defined (CONFIG_MPC86XADS)
 	unsigned int iobits = 0x000000c0;
 
 	if (!pinfo->is_portb) {
@@ -93,13 +104,35 @@ void smc1_lineif(struct uart_cpm_port *p
 		((immap_t *)IMAP_ADDR)->im_ioport.iop_padir &= ~iobits;
 		((immap_t *)IMAP_ADDR)->im_ioport.iop_paodr &= ~iobits;
 	}
-
+#endif
 	pinfo->brg = 1;
 }
 
 void smc2_lineif(struct uart_cpm_port *pinfo)
 {
-	/* XXX SMC2: insert port configuration here */
+	volatile cpm8xx_t *cp = cpmp;
+
+	(void)cp;	/* fix warning */
+#if defined (CONFIG_MPC885ADS)
+	cp->cp_pepar |= 0x00000c00;
+	cp->cp_pedir &= ~0x00000c00;
+	cp->cp_peso &= ~0x00000400;
+	cp->cp_peso |= 0x00000800;
+#elif defined (CONFIG_MPC86XADS)
+	unsigned int iobits = 0x00000c00;
+
+	if (!pinfo->is_portb) {
+		cp->cp_pbpar |= iobits;
+		cp->cp_pbdir &= ~iobits;
+		cp->cp_pbodr &= ~iobits;
+	} else {
+		((immap_t *)IMAP_ADDR)->im_ioport.iop_papar |= iobits;
+		((immap_t *)IMAP_ADDR)->im_ioport.iop_padir &= ~iobits;
+		((immap_t *)IMAP_ADDR)->im_ioport.iop_paodr &= ~iobits;
+	}
+
+#endif
+
 	pinfo->brg = 2;
 }
 
@@ -128,7 +161,7 @@ void scc4_lineif(struct uart_cpm_port *p
 }
 
 /*
- * Allocate DP-Ram and memory buffers. We need to allocate a transmit and 
+ * Allocate DP-Ram and memory buffers. We need to allocate a transmit and
  * receive buffer descriptors from dual port ram, and a character
  * buffer area from host mem. If we are allocating for the console we need
  * to do it from bootmem
@@ -155,7 +188,9 @@ int cpm_uart_allocbuf(struct uart_cpm_po
 	memsz = L1_CACHE_ALIGN(pinfo->rx_nrfifos * pinfo->rx_fifosize) +
 	    L1_CACHE_ALIGN(pinfo->tx_nrfifos * pinfo->tx_fifosize);
 	if (is_con) {
-		mem_addr = (u8 *) m8xx_cpm_hostalloc(memsz);
+		/* was hostalloc but changed cause it blows away the */
+		/* large tlb mapping when pinning the kernel area    */
+		mem_addr = (u8 *) cpm_dpram_addr(cpm_dpalloc(memsz, 8));
 		dma_addr = 0;
 	} else
 		mem_addr = dma_alloc_coherent(NULL, memsz, &dma_addr,
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm2.c b/drivers/serial/cpm_uart/cpm_uart_cpm2.c
--- a/drivers/serial/cpm_uart/cpm_uart_cpm2.c
+++ b/drivers/serial/cpm_uart/cpm_uart_cpm2.c
@@ -134,12 +134,21 @@ void scc1_lineif(struct uart_cpm_port *p
 
 void scc2_lineif(struct uart_cpm_port *pinfo)
 {
+	/*
+	 * STx GP3 uses the SCC2 secondary option pin assignment
+	 * which this driver doesn't account for in the static
+	 * pin assignments. This kind of board specific info
+	 * really has to get out of the driver so boards can
+	 * be supported in a sane fashion.
+	 */
+#ifndef CONFIG_STX_GP3
 	volatile iop_cpm2_t *io = &cpm2_immr->im_ioport;
 	io->iop_pparb |= 0x008b0000;
 	io->iop_pdirb |= 0x00880000;
 	io->iop_psorb |= 0x00880000;
 	io->iop_pdirb &= ~0x00030000;
 	io->iop_psorb &= ~0x00030000;
+#endif
 	cpm2_immr->im_cpmux.cmx_scr &= 0xff00ffff;
 	cpm2_immr->im_cpmux.cmx_scr |= 0x00090000;
 	pinfo->brg = 2;
diff --git a/drivers/serial/crisv10.c b/drivers/serial/crisv10.c
--- a/drivers/serial/crisv10.c
+++ b/drivers/serial/crisv10.c
@@ -426,8 +426,6 @@
 static char *serial_version = "$Revision: 1.25 $";
 
 #include <linux/config.h>
-#include <linux/version.h>
-
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <linux/signal.h>
diff --git a/drivers/serial/icom.c b/drivers/serial/icom.c
--- a/drivers/serial/icom.c
+++ b/drivers/serial/icom.c
@@ -25,7 +25,6 @@
 #define SERIAL_DO_RESTART
 #include <linux/module.h>
 #include <linux/config.h>
-#include <linux/version.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/signal.h>
diff --git a/drivers/serial/icom.h b/drivers/serial/icom.h
--- a/drivers/serial/icom.h
+++ b/drivers/serial/icom.h
@@ -286,5 +286,3 @@ struct lookup_int_table {
 	u32	__iomem *global_int_mask;
 	unsigned long	processor_id;
 };
-
-#define MSECS_TO_JIFFIES(ms) (((ms)*HZ+999)/1000)
diff --git a/drivers/serial/ioc4_serial.c b/drivers/serial/ioc4_serial.c
--- a/drivers/serial/ioc4_serial.c
+++ b/drivers/serial/ioc4_serial.c
@@ -20,7 +20,7 @@
 #include <linux/serial_reg.h>
 #include <linux/module.h>
 #include <linux/pci.h>
-#include <linux/ioc4_common.h>
+#include <linux/ioc4.h>
 #include <linux/serial_core.h>
 
 /*
@@ -130,12 +130,19 @@
 				 IOC4_SIO_IR_S3_TX_EXPLICIT)
 
 /* Bitmasks for IOC4_OTHER_IR, IOC4_OTHER_IEC, and IOC4_OTHER_IES  */
-#define IOC4_OTHER_IR_ATA_INT           0x00000001  /* ATAPI intr pass-thru */
-#define IOC4_OTHER_IR_ATA_MEMERR        0x00000002  /* ATAPI DMA PCI error */
-#define IOC4_OTHER_IR_S0_MEMERR         0x00000004  /* Port 0 PCI error */
-#define IOC4_OTHER_IR_S1_MEMERR         0x00000008  /* Port 1 PCI error */
-#define IOC4_OTHER_IR_S2_MEMERR         0x00000010  /* Port 2 PCI error */
-#define IOC4_OTHER_IR_S3_MEMERR         0x00000020  /* Port 3 PCI error */
+#define IOC4_OTHER_IR_ATA_INT		0x00000001  /* ATAPI intr pass-thru */
+#define IOC4_OTHER_IR_ATA_MEMERR	0x00000002  /* ATAPI DMA PCI error */
+#define IOC4_OTHER_IR_S0_MEMERR		0x00000004  /* Port 0 PCI error */
+#define IOC4_OTHER_IR_S1_MEMERR		0x00000008  /* Port 1 PCI error */
+#define IOC4_OTHER_IR_S2_MEMERR		0x00000010  /* Port 2 PCI error */
+#define IOC4_OTHER_IR_S3_MEMERR		0x00000020  /* Port 3 PCI error */
+#define IOC4_OTHER_IR_KBD_INT		0x00000040  /* Keyboard/mouse */
+#define IOC4_OTHER_IR_RESERVED		0x007fff80  /* Reserved */
+#define IOC4_OTHER_IR_RT_INT		0x00800000  /* INT_OUT section output */
+#define IOC4_OTHER_IR_GEN_INT		0xff000000  /* Generic pins */
+
+#define IOC4_OTHER_IR_SER_MEMERR (IOC4_OTHER_IR_S0_MEMERR | IOC4_OTHER_IR_S1_MEMERR | \
+				  IOC4_OTHER_IR_S2_MEMERR | IOC4_OTHER_IR_S3_MEMERR)
 
 /* Bitmasks for IOC4_SIO_CR */
 #define IOC4_SIO_CR_CMD_PULSE_SHIFT              0  /* byte bus strobe shift */
@@ -274,70 +281,24 @@ struct ioc4_uartregs {
 #define i4u_dlm u2.dlm
 #define i4u_fcr u3.fcr
 
-/* PCI memory space register map addressed using pci_bar0 */
-struct ioc4_memregs {
-	struct ioc4_mem {
-		/* Miscellaneous IOC4  registers */
-		uint32_t pci_err_addr_l;
-		uint32_t pci_err_addr_h;
-		uint32_t sio_ir;
-		uint32_t other_ir;
-
-		/* These registers are read-only for general kernel code.  */
-		uint32_t sio_ies_ro;
-		uint32_t other_ies_ro;
-		uint32_t sio_iec_ro;
-		uint32_t other_iec_ro;
-		uint32_t sio_cr;
-		uint32_t misc_fill1;
-		uint32_t int_out;
-		uint32_t misc_fill2;
-		uint32_t gpcr_s;
-		uint32_t gpcr_c;
-		uint32_t gpdr;
-		uint32_t misc_fill3;
-		uint32_t gppr_0;
-		uint32_t gppr_1;
-		uint32_t gppr_2;
-		uint32_t gppr_3;
-		uint32_t gppr_4;
-		uint32_t gppr_5;
-		uint32_t gppr_6;
-		uint32_t gppr_7;
-	} ioc4_mem;
-
-	char misc_fill4[0x100 - 0x5C - 4];
-
-	/* ATA/ATAP registers */
-	uint32_t ata_notused[9];
-	char ata_fill1[0x140 - 0x120 - 4];
-	uint32_t ata_notused1[8];
-	char ata_fill2[0x200 - 0x15C - 4];
-
-	/* Keyboard and mouse registers */
-	uint32_t km_notused[5];;
-	char km_fill1[0x300 - 0x210 - 4];
-
-	/* Serial port registers used for DMA serial I/O */
-	struct ioc4_serial {
-		uint32_t sbbr01_l;
-		uint32_t sbbr01_h;
-		uint32_t sbbr23_l;
-		uint32_t sbbr23_h;
-
-		struct ioc4_serialregs port_0;
-		struct ioc4_serialregs port_1;
-		struct ioc4_serialregs port_2;
-		struct ioc4_serialregs port_3;
-		struct ioc4_uartregs uart_0;
-		struct ioc4_uartregs uart_1;
-		struct ioc4_uartregs uart_2;
-		struct ioc4_uartregs uart_3;
-	} ioc4_serial;
-};
+/* Serial port registers used for DMA serial I/O */
+struct ioc4_serial {
+	uint32_t sbbr01_l;
+	uint32_t sbbr01_h;
+	uint32_t sbbr23_l;
+	uint32_t sbbr23_h;
+
+	struct ioc4_serialregs port_0;
+	struct ioc4_serialregs port_1;
+	struct ioc4_serialregs port_2;
+	struct ioc4_serialregs port_3;
+	struct ioc4_uartregs uart_0;
+	struct ioc4_uartregs uart_1;
+	struct ioc4_uartregs uart_2;
+	struct ioc4_uartregs uart_3;
+} ioc4_serial;
 
 /* UART clock speed */
-#define IOC4_SER_XIN_CLK        IOC4_SER_XIN_CLK_66
 #define IOC4_SER_XIN_CLK_66     66666667
 #define IOC4_SER_XIN_CLK_33     33333333
 
@@ -412,8 +373,8 @@ enum sio_proto {
 					| UART_LCR_WLEN7 | UART_LCR_WLEN8)
 #define LCR_MASK_STOP_BITS	(UART_LCR_STOP)
 
-#define PENDING(_p)	(readl(&(_p)->ip_mem->sio_ir) & _p->ip_ienb)
-#define READ_SIO_IR(_p) readl(&(_p)->ip_mem->sio_ir)
+#define PENDING(_p)	(readl(&(_p)->ip_mem->sio_ir.raw) & _p->ip_ienb)
+#define READ_SIO_IR(_p) readl(&(_p)->ip_mem->sio_ir.raw)
 
 /* Default to 4k buffers */
 #ifdef IOC4_1K_BUFFERS
@@ -447,7 +408,7 @@ struct ioc4_control {
  */
 #define MAX_IOC4_INTR_ENTS	(8 * sizeof(uint32_t))
 struct ioc4_soft {
-	struct ioc4_mem __iomem *is_ioc4_mem_addr;
+	struct ioc4_misc_regs __iomem *is_ioc4_misc_addr;
 	struct ioc4_serial __iomem *is_ioc4_serial_addr;
 
 	/* Each interrupt type has an entry in the array */
@@ -486,7 +447,7 @@ struct ioc4_port {
 	struct ioc4_soft *ip_ioc4_soft;
 
 	/* pci mem addresses */
-	struct ioc4_mem __iomem *ip_mem;
+	struct ioc4_misc_regs __iomem *ip_mem;
 	struct ioc4_serial __iomem *ip_serial;
 	struct ioc4_serialregs __iomem *ip_serial_regs;
 	struct ioc4_uartregs __iomem *ip_uart_regs;
@@ -553,7 +514,7 @@ struct hooks {
 	uint32_t intr_dma_error;
 	uint32_t intr_clear;
 	uint32_t intr_all;
-	char rs422_select_pin;
+	int rs422_select_pin;
 };
 
 static struct hooks hooks_array[IOC4_NUM_SERIAL_PORTS] = {
@@ -669,7 +630,7 @@ static void handle_intr(void *arg, uint3
 static inline void
 write_ireg(struct ioc4_soft *ioc4_soft, uint32_t val, int which, int type)
 {
-	struct ioc4_mem __iomem *mem = ioc4_soft->is_ioc4_mem_addr;
+	struct ioc4_misc_regs __iomem *mem = ioc4_soft->is_ioc4_misc_addr;
 	unsigned long flags;
 
 	spin_lock_irqsave(&ioc4_soft->is_ir_lock, flags);
@@ -678,11 +639,11 @@ write_ireg(struct ioc4_soft *ioc4_soft, 
 	case IOC4_SIO_INTR_TYPE:
 		switch (which) {
 		case IOC4_W_IES:
-			writel(val, &mem->sio_ies_ro);
+			writel(val, &mem->sio_ies.raw);
 			break;
 
 		case IOC4_W_IEC:
-			writel(val, &mem->sio_iec_ro);
+			writel(val, &mem->sio_iec.raw);
 			break;
 		}
 		break;
@@ -690,11 +651,11 @@ write_ireg(struct ioc4_soft *ioc4_soft, 
 	case IOC4_OTHER_INTR_TYPE:
 		switch (which) {
 		case IOC4_W_IES:
-			writel(val, &mem->other_ies_ro);
+			writel(val, &mem->other_ies.raw);
 			break;
 
 		case IOC4_W_IEC:
-			writel(val, &mem->other_iec_ro);
+			writel(val, &mem->other_iec.raw);
 			break;
 		}
 		break;
@@ -747,7 +708,8 @@ static int set_baud(struct ioc4_port *po
  */
 static struct ioc4_port *get_ioc4_port(struct uart_port *the_port)
 {
-	struct ioc4_control *control = dev_get_drvdata(the_port->dev);
+	struct ioc4_driver_data *idd = dev_get_drvdata(the_port->dev);
+	struct ioc4_control *control = idd->idd_serial_data;
 	int ii;
 
 	if (control) {
@@ -782,7 +744,7 @@ static struct ioc4_port *get_ioc4_port(s
 static inline uint32_t
 pending_intrs(struct ioc4_soft *soft, int type)
 {
-	struct ioc4_mem __iomem *mem = soft->is_ioc4_mem_addr;
+	struct ioc4_misc_regs __iomem *mem = soft->is_ioc4_misc_addr;
 	unsigned long flag;
 	uint32_t intrs = 0;
 
@@ -793,11 +755,11 @@ pending_intrs(struct ioc4_soft *soft, in
 
 	switch (type) {
 	case IOC4_SIO_INTR_TYPE:
-		intrs = readl(&mem->sio_ir) & readl(&mem->sio_ies_ro);
+		intrs = readl(&mem->sio_ir.raw) & readl(&mem->sio_ies.raw);
 		break;
 
 	case IOC4_OTHER_INTR_TYPE:
-		intrs = readl(&mem->other_ir) & readl(&mem->other_ies_ro);
+		intrs = readl(&mem->other_ir.raw) & readl(&mem->other_ies.raw);
 
 		/* Don't process any ATA interrupte */
 		intrs &= ~(IOC4_OTHER_IR_ATA_INT | IOC4_OTHER_IR_ATA_MEMERR);
@@ -826,7 +788,7 @@ static int inline port_init(struct ioc4_
 
 	/* Wait until any pending bus activity for this port has ceased */
 	do
-		sio_cr = readl(&port->ip_mem->sio_cr);
+		sio_cr = readl(&port->ip_mem->sio_cr.raw);
 	while (!(sio_cr & IOC4_SIO_CR_SIO_DIAG_IDLE));
 
 	/* Finish reset sequence */
@@ -899,7 +861,7 @@ static int inline port_init(struct ioc4_
 	write_ireg(port->ip_ioc4_soft, hooks->intr_clear,
 		       IOC4_W_IEC, IOC4_SIO_INTR_TYPE);
 	port->ip_ienb &= ~hooks->intr_clear;
-	writel(hooks->intr_clear, &port->ip_mem->sio_ir);
+	writel(hooks->intr_clear, &port->ip_mem->sio_ir.raw);
 	return 0;
 }
 
@@ -918,23 +880,23 @@ static void handle_dma_error_intr(void *
 	spin_lock_irqsave(&port->ip_lock, flags);
 
 	/* ACK the interrupt */
-	writel(hooks->intr_dma_error, &port->ip_mem->other_ir);
+	writel(hooks->intr_dma_error, &port->ip_mem->other_ir.raw);
 
-	if (readl(&port->ip_mem->pci_err_addr_l) & IOC4_PCI_ERR_ADDR_VLD) {
+	if (readl(&port->ip_mem->pci_err_addr_l.raw) & IOC4_PCI_ERR_ADDR_VLD) {
 		printk(KERN_ERR
 			"PCI error address is 0x%lx, "
 				"master is serial port %c %s\n",
 		     (((uint64_t)readl(&port->ip_mem->pci_err_addr_h)
 							 << 32)
-				| readl(&port->ip_mem->pci_err_addr_l))
+				| readl(&port->ip_mem->pci_err_addr_l.raw))
 					& IOC4_PCI_ERR_ADDR_ADDR_MSK, '1' +
-		     ((char)(readl(&port->ip_mem-> pci_err_addr_l) &
+		     ((char)(readl(&port->ip_mem->pci_err_addr_l.raw) &
 			     IOC4_PCI_ERR_ADDR_MST_NUM_MSK) >> 1),
-		     (readl(&port->ip_mem->pci_err_addr_l)
+		     (readl(&port->ip_mem->pci_err_addr_l.raw)
 				& IOC4_PCI_ERR_ADDR_MST_TYP_MSK)
 				? "RX" : "TX");
 
-		if (readl(&port->ip_mem->pci_err_addr_l)
+		if (readl(&port->ip_mem->pci_err_addr_l.raw)
 						& IOC4_PCI_ERR_ADDR_MUL_ERR) {
 			printk(KERN_ERR
 				"Multiple errors occurred\n");
@@ -1018,26 +980,26 @@ static irqreturn_t ioc4_intr(int irq, vo
 				"other_ies = 0x%x\n",
 			       (intr_type == IOC4_SIO_INTR_TYPE) ? "sio" :
 			       "other", this_ir,
-			       readl(&soft->is_ioc4_mem_addr->sio_ir),
-			       readl(&soft->is_ioc4_mem_addr->sio_ies_ro),
-			       readl(&soft->is_ioc4_mem_addr->other_ir),
-			       readl(&soft->is_ioc4_mem_addr->other_ies_ro));
+			       readl(&soft->is_ioc4_misc_addr->sio_ir.raw),
+			       readl(&soft->is_ioc4_misc_addr->sio_ies.raw),
+			       readl(&soft->is_ioc4_misc_addr->other_ir.raw),
+			       readl(&soft->is_ioc4_misc_addr->other_ies.raw));
 		}
 	}
 #ifdef DEBUG_INTERRUPTS
 	{
-		struct ioc4_mem __iomem *mem = soft->is_ioc4_mem_addr;
+		struct ioc4_misc_regs __iomem *mem = soft->is_ioc4_misc_addr;
 		spinlock_t *lp = &soft->is_ir_lock;
 		unsigned long flag;
 
 		spin_lock_irqsave(&soft->is_ir_lock, flag);
-		printk ("%s : %d : mem 0x%p sio_ir 0x%x sio_ies_ro 0x%x "
-				"other_ir 0x%x other_ies_ro 0x%x mask 0x%x\n",
+		printk ("%s : %d : mem 0x%p sio_ir 0x%x sio_ies 0x%x "
+				"other_ir 0x%x other_ies 0x%x mask 0x%x\n",
 		     __FUNCTION__, __LINE__,
-		     (void *)mem, readl(&mem->sio_ir),
-		     readl(&mem->sio_ies_ro),
-		     readl(&mem->other_ir),
-		     readl(&mem->other_ies_ro),
+		     (void *)mem, readl(&mem->sio_ir.raw),
+		     readl(&mem->sio_ies.raw),
+		     readl(&mem->other_ir.raw),
+		     readl(&mem->other_ies.raw),
 		     IOC4_OTHER_IR_ATA_INT | IOC4_OTHER_IR_ATA_MEMERR);
 		spin_unlock_irqrestore(&soft->is_ir_lock, flag);
 	}
@@ -1049,21 +1011,20 @@ static irqreturn_t ioc4_intr(int irq, vo
  * ioc4_attach_local - Device initialization.
  *			Called at *_attach() time for each
  *			IOC4 with serial ports in the system.
- * @control: ioc4_control ptr
- * @pdev: PCI handle for this device
- * @soft: soft struct for this device
- * @ioc4: ioc4 mem space
- */
-static int inline ioc4_attach_local(struct pci_dev *pdev,
-			struct ioc4_control *control,
-			struct ioc4_soft *soft, void __iomem *ioc4_mem,
-			void __iomem *ioc4_serial)
+ * @idd: Master module data for this IOC4
+ */
+static int inline ioc4_attach_local(struct ioc4_driver_data *idd)
 {
 	struct ioc4_port *port;
 	struct ioc4_port *ports[IOC4_NUM_SERIAL_PORTS];
 	int port_number;
 	uint16_t ioc4_revid_min = 62;
 	uint16_t ioc4_revid;
+	struct pci_dev *pdev = idd->idd_pdev;
+	struct ioc4_control* control = idd->idd_serial_data;
+	struct ioc4_soft *soft = control->ic_soft;
+	void __iomem *ioc4_misc = idd->idd_misc_regs;
+	void __iomem *ioc4_serial = soft->is_ioc4_serial_addr;
 
 	/* IOC4 firmware must be at least rev 62 */
 	pci_read_config_word(pdev, PCI_COMMAND_SPECIAL, &ioc4_revid);
@@ -1076,7 +1037,7 @@ static int inline ioc4_attach_local(stru
 				ioc4_revid, ioc4_revid_min);
 		return -EPERM;
 	}
-	BUG_ON(ioc4_mem == NULL);
+	BUG_ON(ioc4_misc == NULL);
 	BUG_ON(ioc4_serial == NULL);
 
 	/* Create port structures for each port */
@@ -1100,10 +1061,18 @@ static int inline ioc4_attach_local(stru
 		port->ip_ioc4_soft = soft;
 		port->ip_pdev = pdev;
 		port->ip_ienb = 0;
-		port->ip_pci_bus_speed = IOC4_SER_XIN_CLK;
+		/* Use baud rate calculations based on detected PCI
+		 * bus speed.  Simply test whether the PCI clock is
+		 * running closer to 66MHz or 33MHz.
+		 */
+		if (idd->count_period/IOC4_EXTINT_COUNT_DIVISOR < 20) {
+			port->ip_pci_bus_speed = IOC4_SER_XIN_CLK_66;
+		} else {
+			port->ip_pci_bus_speed = IOC4_SER_XIN_CLK_33;
+		}
 		port->ip_baud = 9600;
 		port->ip_control = control;
-		port->ip_mem = ioc4_mem;
+		port->ip_mem = ioc4_misc;
 		port->ip_serial = ioc4_serial;
 
 		/* point to the right hook */
@@ -1604,14 +1573,12 @@ static int ioc4_set_proto(struct ioc4_po
 	switch (proto) {
 	case PROTO_RS232:
 		/* Clear the appropriate GIO pin */
-		writel(0, (&port->ip_mem->gppr_0 +
-				  hooks->rs422_select_pin));
+		writel(0, (&port->ip_mem->gppr[hooks->rs422_select_pin].raw));
 		break;
 
 	case PROTO_RS422:
 		/* Set the appropriate GIO pin */
-		writel(1, (&port->ip_mem->gppr_0 +
-				  hooks->rs422_select_pin));
+		writel(1, (&port->ip_mem->gppr[hooks->rs422_select_pin].raw));
 		break;
 
 	default:
@@ -1885,7 +1852,7 @@ static void handle_intr(void *arg, uint3
 		if (sio_ir & hooks->intr_delta_dcd) {
 			/* ACK the interrupt */
 			writel(hooks->intr_delta_dcd,
-				&port->ip_mem->sio_ir);
+				&port->ip_mem->sio_ir.raw);
 
 			shadow = readl(&port->ip_serial_regs->shadow);
 
@@ -1907,7 +1874,7 @@ static void handle_intr(void *arg, uint3
 		if (sio_ir & hooks->intr_delta_cts) {
 			/* ACK the interrupt */
 			writel(hooks->intr_delta_cts,
-					&port->ip_mem->sio_ir);
+					&port->ip_mem->sio_ir.raw);
 
 			shadow = readl(&port->ip_serial_regs->shadow);
 
@@ -1928,7 +1895,7 @@ static void handle_intr(void *arg, uint3
 		if (sio_ir & hooks->intr_rx_timer) {
 			/* ACK the interrupt */
 			writel(hooks->intr_rx_timer,
-				&port->ip_mem->sio_ir);
+				&port->ip_mem->sio_ir.raw);
 
 			if ((port->ip_notify & N_DATA_READY)
 					&& (port->ip_port)) {
@@ -1974,7 +1941,7 @@ static void handle_intr(void *arg, uint3
 
 			/* ACK the interrupt */
 			writel(hooks->intr_tx_explicit,
-					&port->ip_mem->sio_ir);
+					&port->ip_mem->sio_ir.raw);
 
 			if (port->ip_notify & N_OUTPUT_LOWAT)
 				ioc4_cb_output_lowat(port);
@@ -2634,7 +2601,8 @@ ioc4_serial_core_attach(struct pci_dev *
 {
 	struct ioc4_port *port;
 	struct uart_port *the_port;
-	struct ioc4_control *control = pci_get_drvdata(pdev);
+	struct ioc4_driver_data *idd = pci_get_drvdata(pdev);
+	struct ioc4_control *control = idd->idd_serial_data;
 	int ii;
 
 	DPRINT_CONFIG(("%s: attach pdev 0x%p - control 0x%p\n",
@@ -2680,55 +2648,29 @@ ioc4_serial_core_attach(struct pci_dev *
 
 /**
  * ioc4_serial_attach_one - register attach function
- *		called per card found from ioc4_serial_detect as part
- *		of module_init().
- * @pdev: handle for this card
- * @pci_id: pci id for this card
+ *		called per card found from IOC4 master module.
+ * @idd: Master module data for this IOC4
  */
 int
-ioc4_serial_attach_one(struct pci_dev *pdev, const struct pci_device_id *pci_id)
+ioc4_serial_attach_one(struct ioc4_driver_data *idd)
 {
-	struct ioc4_mem __iomem *mem;
-	unsigned long tmp_addr, tmp_addr1;
+	unsigned long tmp_addr1;
 	struct ioc4_serial __iomem *serial;
 	struct ioc4_soft *soft;
 	struct ioc4_control *control;
-	int tmp, ret = 0;
+	int ret = 0;
 
 
-	DPRINT_CONFIG(("%s (0x%p, 0x%p)\n", __FUNCTION__, pdev, pci_id));
-
-	/* Map in the ioc4 memory */
-	tmp_addr = pci_resource_start(pdev, 0);
-	if (!tmp_addr) {
-		printk(KERN_WARNING
-			 "ioc4 (%p) : unable to get PIO mapping for "
-				"MEM space\n", (void *)pdev);
-		return -ENODEV;
-	}
-	if (!request_region(tmp_addr, sizeof(struct ioc4_mem), "sioc4_mem")) {
-		printk(KERN_ALERT
-			"ioc4 (%p): unable to get request region for "
-			"MEM space\n", (void *)pdev);
-		return -ENODEV;
-	}
-	mem = ioremap(tmp_addr, sizeof(struct ioc4_mem));
-	if (!mem) {
-		printk(KERN_WARNING
-			 "ioc4 (%p) : unable to remap ioc4 memory\n",
-				(void *)pdev);
-		ret = -ENODEV;
-		goto out1;
-	}
+	DPRINT_CONFIG(("%s (0x%p, 0x%p)\n", __FUNCTION__, idd->idd_pdev, idd->idd_pci_id));
 
 	/* request serial registers */
-	tmp_addr1 = pci_resource_start(pdev, 0) + IOC4_SERIAL_OFFSET;
+	tmp_addr1 = idd->idd_bar0 + IOC4_SERIAL_OFFSET;
 
 	if (!request_region(tmp_addr1, sizeof(struct ioc4_serial),
 					"sioc4_uart")) {
 		printk(KERN_WARNING
 			"ioc4 (%p): unable to get request region for "
-				"uart space\n", (void *)pdev);
+				"uart space\n", (void *)idd->idd_pdev);
 		ret = -ENODEV;
 		goto out1;
 	}
@@ -2736,12 +2678,12 @@ ioc4_serial_attach_one(struct pci_dev *p
 	if (!serial) {
 		printk(KERN_WARNING
 			 "ioc4 (%p) : unable to remap ioc4 serial register\n",
-				(void *)pdev);
+				(void *)idd->idd_pdev);
 		ret = -ENODEV;
 		goto out2;
 	}
 	DPRINT_CONFIG(("%s : mem 0x%p, serial 0x%p\n",
-				__FUNCTION__, (void *)mem, (void *)serial));
+				__FUNCTION__, (void *)idd->idd_misc_regs, (void *)serial));
 
 	/* Get memory for the new card */
 	control = kmalloc(sizeof(struct ioc4_control) * IOC4_NUM_SERIAL_PORTS,
@@ -2754,59 +2696,56 @@ ioc4_serial_attach_one(struct pci_dev *p
 		goto out2;
 	}
 	memset(control, 0, sizeof(struct ioc4_control));
-	pci_set_drvdata(pdev, control);
+	idd->idd_serial_data = control;
 
 	/* Allocate the soft structure */
 	soft = kmalloc(sizeof(struct ioc4_soft), GFP_KERNEL);
 	if (!soft) {
 		printk(KERN_WARNING
 		       "ioc4 (%p): unable to get memory for the soft struct\n",
-		       (void *)pdev);
+		       (void *)idd->idd_pdev);
 		ret = -ENOMEM;
 		goto out3;
 	}
 	memset(soft, 0, sizeof(struct ioc4_soft));
 
 	spin_lock_init(&soft->is_ir_lock);
-	soft->is_ioc4_mem_addr = mem;
+	soft->is_ioc4_misc_addr = idd->idd_misc_regs;
 	soft->is_ioc4_serial_addr = serial;
 
 	/* Init the IOC4 */
-	pci_read_config_dword(pdev, PCI_COMMAND, &tmp);
-	pci_write_config_dword(pdev, PCI_COMMAND,
-			       tmp | PCI_COMMAND_PARITY | PCI_COMMAND_SERR);
-
-	writel(0xf << IOC4_SIO_CR_CMD_PULSE_SHIFT, &mem->sio_cr);
+	writel(0xf << IOC4_SIO_CR_CMD_PULSE_SHIFT,
+	       &idd->idd_misc_regs->sio_cr.raw);
 
 	/* Enable serial port mode select generic PIO pins as outputs */
 	writel(IOC4_GPCR_UART0_MODESEL | IOC4_GPCR_UART1_MODESEL
 		| IOC4_GPCR_UART2_MODESEL | IOC4_GPCR_UART3_MODESEL,
-		&mem->gpcr_s);
+		&idd->idd_misc_regs->gpcr_s.raw);
 
-	/* Clear and disable all interrupts */
+	/* Clear and disable all serial interrupts */
 	write_ireg(soft, ~0, IOC4_W_IEC, IOC4_SIO_INTR_TYPE);
-	writel(~0, &mem->sio_ir);
-	write_ireg(soft, ~(IOC4_OTHER_IR_ATA_INT | IOC4_OTHER_IR_ATA_MEMERR),
-			IOC4_W_IEC, IOC4_OTHER_INTR_TYPE);
-	writel(~(IOC4_OTHER_IR_ATA_MEMERR | IOC4_OTHER_IR_ATA_MEMERR),
-					&mem->other_ir);
+	writel(~0, &idd->idd_misc_regs->sio_ir.raw);
+	write_ireg(soft, IOC4_OTHER_IR_SER_MEMERR, IOC4_W_IEC,
+		   IOC4_OTHER_INTR_TYPE);
+	writel(IOC4_OTHER_IR_SER_MEMERR, &idd->idd_misc_regs->other_ir.raw);
 	control->ic_soft = soft;
-	if (!request_irq(pdev->irq, ioc4_intr, SA_SHIRQ,
+
+	/* Hook up interrupt handler */
+	if (!request_irq(idd->idd_pdev->irq, ioc4_intr, SA_SHIRQ,
 				"sgi-ioc4serial", (void *)soft)) {
-		control->ic_irq = pdev->irq;
+		control->ic_irq = idd->idd_pdev->irq;
 	} else {
 		printk(KERN_WARNING
 		    "%s : request_irq fails for IRQ 0x%x\n ",
-			__FUNCTION__, pdev->irq);
+			__FUNCTION__, idd->idd_pdev->irq);
 	}
-	if ((ret = ioc4_attach_local(pdev, control, soft,
-				soft->is_ioc4_mem_addr,
-				soft->is_ioc4_serial_addr)))
+	ret = ioc4_attach_local(idd);
+	if (ret)
 		goto out4;
 
 	/* register port with the serial core */
 
-	if ((ret = ioc4_serial_core_attach(pdev)))
+	if ((ret = ioc4_serial_core_attach(idd->idd_pdev)))
 		goto out4;
 
 	return ret;
@@ -2819,7 +2758,6 @@ out3:
 out2:
 	release_region(tmp_addr1, sizeof(struct ioc4_serial));
 out1:
-	release_region(tmp_addr, sizeof(struct ioc4_mem));
 
 	return ret;
 }
@@ -2828,11 +2766,10 @@ out1:
 /**
  * ioc4_serial_remove_one - detach function
  *
- * @pdev: handle for this card
+ * @idd: IOC4 master module data for this IOC4
  */
 
-#if 0
-void ioc4_serial_remove_one(struct pci_dev *pdev)
+int ioc4_serial_remove_one(struct ioc4_driver_data *idd)
 {
 	int ii;
 	struct ioc4_control *control;
@@ -2840,7 +2777,7 @@ void ioc4_serial_remove_one(struct pci_d
 	struct ioc4_port *port;
 	struct ioc4_soft *soft;
 
-	control = pci_get_drvdata(pdev);
+	control = idd->idd_serial_data;
 
 	for (ii = 0; ii < IOC4_NUM_SERIAL_PORTS; ii++) {
 		the_port = &control->ic_port[ii].icp_uart_port;
@@ -2867,10 +2804,17 @@ void ioc4_serial_remove_one(struct pci_d
 		kfree(soft);
 	}
 	kfree(control);
-	pci_set_drvdata(pdev, NULL);
-	uart_unregister_driver(&ioc4_uart);
+	idd->idd_serial_data = NULL;
+
+	return 0;
 }
-#endif
+
+static struct ioc4_submodule ioc4_serial_submodule = {
+	.is_name = "IOC4_serial",
+	.is_owner = THIS_MODULE,
+	.is_probe = ioc4_serial_attach_one,
+	.is_remove = ioc4_serial_remove_one,
+};
 
 /**
  * ioc4_serial_init - module init
@@ -2886,12 +2830,20 @@ int ioc4_serial_init(void)
 			__FUNCTION__);
 		return ret;
 	}
-	return 0;
+
+	/* register with IOC4 main module */
+	return ioc4_register_submodule(&ioc4_serial_submodule);
+}
+
+static void __devexit ioc4_serial_exit(void)
+{
+	ioc4_unregister_submodule(&ioc4_serial_submodule);
+	uart_unregister_driver(&ioc4_uart);
 }
 
+module_init(ioc4_serial_init);
+module_exit(ioc4_serial_exit);
+
 MODULE_AUTHOR("Pat Gefre - Silicon Graphics Inc. (SGI) <pfg@sgi.com>");
 MODULE_DESCRIPTION("Serial PCI driver module for SGI IOC4 Base-IO Card");
 MODULE_LICENSE("GPL");
-
-EXPORT_SYMBOL(ioc4_serial_init);
-EXPORT_SYMBOL(ioc4_serial_attach_one);
diff --git a/drivers/serial/ip22zilog.c b/drivers/serial/ip22zilog.c
--- a/drivers/serial/ip22zilog.c
+++ b/drivers/serial/ip22zilog.c
@@ -518,27 +518,28 @@ static irqreturn_t ip22zilog_interrupt(i
 static __inline__ unsigned char ip22zilog_read_channel_status(struct uart_port *port)
 {
 	struct zilog_channel *channel;
-	unsigned long flags;
 	unsigned char status;
 
-	spin_lock_irqsave(&port->lock, flags);
-
 	channel = ZILOG_CHANNEL_FROM_PORT(port);
 	status = readb(&channel->control);
 	ZSDELAY();
 
-	spin_unlock_irqrestore(&port->lock, flags);
-
 	return status;
 }
 
 /* The port lock is not held.  */
 static unsigned int ip22zilog_tx_empty(struct uart_port *port)
 {
+	unsigned long flags;
 	unsigned char status;
 	unsigned int ret;
 
+	spin_lock_irqsave(&port->lock, flags);
+
 	status = ip22zilog_read_channel_status(port);
+
+	spin_unlock_irqrestore(&port->lock, flags);
+
 	if (status & Tx_BUF_EMP)
 		ret = TIOCSER_TEMT;
 	else
@@ -547,7 +548,7 @@ static unsigned int ip22zilog_tx_empty(s
 	return ret;
 }
 
-/* The port lock is not held.  */
+/* The port lock is held and interrupts are disabled.  */
 static unsigned int ip22zilog_get_mctrl(struct uart_port *port)
 {
 	unsigned char status;
diff --git a/drivers/serial/jsm/jsm.h b/drivers/serial/jsm/jsm.h
--- a/drivers/serial/jsm/jsm.h
+++ b/drivers/serial/jsm/jsm.h
@@ -28,7 +28,6 @@
 #define __JSM_DRIVER_H
 
 #include <linux/kernel.h>
-#include <linux/version.h>
 #include <linux/types.h>	/* To pick up the varions Linux types */
 #include <linux/tty.h>
 #include <linux/serial_core.h>
@@ -90,7 +89,7 @@ enum {
 #define WRITEBUFLEN	((4096) + 4)
 #define MYFLIPLEN	N_TTY_BUF_SIZE
 
-#define JSM_VERSION	"jsm: 1.1-1-INKERNEL"
+#define JSM_VERSION	"jsm: 1.2-1-INKERNEL"
 #define JSM_PARTNUM	"40002438_A-INKERNEL"
 
 struct jsm_board;
diff --git a/drivers/serial/jsm/jsm_driver.c b/drivers/serial/jsm/jsm_driver.c
--- a/drivers/serial/jsm/jsm_driver.c
+++ b/drivers/serial/jsm/jsm_driver.c
@@ -22,6 +22,7 @@
  * Scott H Kilau <Scott_Kilau@digi.com>
  * Wendy Xiong   <wendyx@us.ltcfwd.linux.ibm.com>
  *
+ *
  ***********************************************************************/
 #include <linux/moduleparam.h>
 #include <linux/pci.h>
@@ -42,7 +43,7 @@ struct uart_driver jsm_uart_driver = {
 	.owner		= THIS_MODULE,
 	.driver_name	= JSM_DRIVER_NAME,
 	.dev_name	= "ttyn",
-	.major		= 253,
+	.major		= 0,
 	.minor		= JSM_MINOR_START,
 	.nr		= NR_PORTS,
 };
diff --git a/drivers/serial/jsm/jsm_neo.c b/drivers/serial/jsm/jsm_neo.c
--- a/drivers/serial/jsm/jsm_neo.c
+++ b/drivers/serial/jsm/jsm_neo.c
@@ -48,8 +48,9 @@ static inline void neo_pci_posting_flush
 
 static void neo_set_cts_flow_control(struct jsm_channel *ch)
 {
-	u8 ier = readb(&ch->ch_neo_uart->ier);
-	u8 efr = readb(&ch->ch_neo_uart->efr);
+	u8 ier, efr;
+	ier = readb(&ch->ch_neo_uart->ier);
+	efr = readb(&ch->ch_neo_uart->efr);
 
 	jsm_printk(PARAM, INFO, &ch->ch_bd->pci_dev, "Setting CTSFLOW\n");
 
@@ -78,8 +79,9 @@ static void neo_set_cts_flow_control(str
 
 static void neo_set_rts_flow_control(struct jsm_channel *ch)
 {
-	u8 ier = readb(&ch->ch_neo_uart->ier);
-	u8 efr = readb(&ch->ch_neo_uart->efr);
+	u8 ier, efr;
+	ier = readb(&ch->ch_neo_uart->ier);
+	efr = readb(&ch->ch_neo_uart->efr);
 
 	jsm_printk(PARAM, INFO, &ch->ch_bd->pci_dev, "Setting RTSFLOW\n");
 
@@ -117,8 +119,9 @@ static void neo_set_rts_flow_control(str
 
 static void neo_set_ixon_flow_control(struct jsm_channel *ch)
 {
-	u8 ier = readb(&ch->ch_neo_uart->ier);
-	u8 efr = readb(&ch->ch_neo_uart->efr);
+	u8 ier, efr;
+	ier = readb(&ch->ch_neo_uart->ier);
+	efr = readb(&ch->ch_neo_uart->efr);
 
 	jsm_printk(PARAM, INFO, &ch->ch_bd->pci_dev, "Setting IXON FLOW\n");
 
@@ -153,8 +156,9 @@ static void neo_set_ixon_flow_control(st
 
 static void neo_set_ixoff_flow_control(struct jsm_channel *ch)
 {
-	u8 ier = readb(&ch->ch_neo_uart->ier);
-	u8 efr = readb(&ch->ch_neo_uart->efr);
+	u8 ier, efr;
+	ier = readb(&ch->ch_neo_uart->ier);
+	efr = readb(&ch->ch_neo_uart->efr);
 
 	jsm_printk(PARAM, INFO, &ch->ch_bd->pci_dev, "Setting IXOFF FLOW\n");
 
@@ -190,8 +194,9 @@ static void neo_set_ixoff_flow_control(s
 
 static void neo_set_no_input_flow_control(struct jsm_channel *ch)
 {
-	u8 ier = readb(&ch->ch_neo_uart->ier);
-	u8 efr = readb(&ch->ch_neo_uart->efr);
+	u8 ier, efr;
+	ier = readb(&ch->ch_neo_uart->ier);
+	efr = readb(&ch->ch_neo_uart->efr);
 
 	jsm_printk(PARAM, INFO, &ch->ch_bd->pci_dev, "Unsetting Input FLOW\n");
 
@@ -228,8 +233,9 @@ static void neo_set_no_input_flow_contro
 
 static void neo_set_no_output_flow_control(struct jsm_channel *ch)
 {
-	u8 ier = readb(&ch->ch_neo_uart->ier);
-	u8 efr = readb(&ch->ch_neo_uart->efr);
+	u8 ier, efr;
+	ier = readb(&ch->ch_neo_uart->ier);
+	efr = readb(&ch->ch_neo_uart->efr);
 
 	jsm_printk(PARAM, INFO, &ch->ch_bd->pci_dev, "Unsetting Output FLOW\n");
 
diff --git a/drivers/serial/m32r_sio.c b/drivers/serial/m32r_sio.c
--- a/drivers/serial/m32r_sio.c
+++ b/drivers/serial/m32r_sio.c
@@ -724,22 +724,22 @@ static void m32r_sio_set_termios(struct 
 
 	switch (termios->c_cflag & CSIZE) {
 	case CS5:
-		cval = 0x00;
+		cval = UART_LCR_WLEN5;
 		break;
 	case CS6:
-		cval = 0x01;
+		cval = UART_LCR_WLEN6;
 		break;
 	case CS7:
-		cval = 0x02;
+		cval = UART_LCR_WLEN7;
 		break;
 	default:
 	case CS8:
-		cval = 0x03;
+		cval = UART_LCR_WLEN8;
 		break;
 	}
 
 	if (termios->c_cflag & CSTOPB)
-		cval |= 0x04;
+		cval |= UART_LCR_STOP;
 	if (termios->c_cflag & PARENB)
 		cval |= UART_LCR_PARITY;
 	if (!(termios->c_cflag & PARODD))
@@ -1123,7 +1123,7 @@ static int __init m32r_sio_console_setup
 	return uart_set_options(port, co, baud, parity, bits, flow);
 }
 
-extern struct uart_driver m32r_sio_reg;
+static struct uart_driver m32r_sio_reg;
 static struct console m32r_sio_console = {
 	.name		= "ttyS",
 	.write		= m32r_sio_console_write,
diff --git a/drivers/serial/mpsc.c b/drivers/serial/mpsc.c
--- a/drivers/serial/mpsc.c
+++ b/drivers/serial/mpsc.c
@@ -67,7 +67,11 @@
 
 static struct mpsc_port_info mpsc_ports[MPSC_NUM_CTLRS];
 static struct mpsc_shared_regs mpsc_shared_regs;
+static struct uart_driver mpsc_reg;
 
+static void mpsc_start_rx(struct mpsc_port_info *pi);
+static void mpsc_free_ring_mem(struct mpsc_port_info *pi);
+static void mpsc_release_port(struct uart_port *port);
 /*
  ******************************************************************************
  *
@@ -546,7 +550,6 @@ static int
 mpsc_alloc_ring_mem(struct mpsc_port_info *pi)
 {
 	int rc = 0;
-	static void mpsc_free_ring_mem(struct mpsc_port_info *pi);
 
 	pr_debug("mpsc_alloc_ring_mem[%d]: Allocating ring mem\n",
 		pi->port.line);
@@ -745,7 +748,6 @@ mpsc_rx_intr(struct mpsc_port_info *pi, 
 	int	rc = 0;
 	u8	*bp;
 	char	flag = TTY_NORMAL;
-	static void mpsc_start_rx(struct mpsc_port_info *pi);
 
 	pr_debug("mpsc_rx_intr[%d]: Handling Rx intr\n", pi->port.line);
 
@@ -1056,12 +1058,9 @@ mpsc_get_mctrl(struct uart_port *port)
 {
 	struct mpsc_port_info *pi = (struct mpsc_port_info *)port;
 	u32 mflags, status;
-	ulong iflags;
 
-	spin_lock_irqsave(&pi->port.lock, iflags);
 	status = (pi->mirror_regs) ? pi->MPSC_CHR_10_m :
 		readl(pi->mpsc_base + MPSC_CHR_10);
-	spin_unlock_irqrestore(&pi->port.lock, iflags);
 
 	mflags = 0;
 	if (status & 0x1)
@@ -1178,7 +1177,6 @@ static void
 mpsc_shutdown(struct uart_port *port)
 {
 	struct mpsc_port_info *pi = (struct mpsc_port_info *)port;
-	static void mpsc_release_port(struct uart_port *port);
 
 	pr_debug("mpsc_shutdown[%d]: Shutting down MPSC\n", port->line);
 
@@ -1448,7 +1446,6 @@ mpsc_console_setup(struct console *co, c
 	return uart_set_options(&pi->port, co, baud, parity, bits, flow);
 }
 
-extern struct uart_driver mpsc_reg;
 static struct console mpsc_console = {
 	.name   = MPSC_DEV_NAME,
 	.write  = mpsc_console_write,
diff --git a/drivers/serial/pmac_zilog.c b/drivers/serial/pmac_zilog.c
--- a/drivers/serial/pmac_zilog.c
+++ b/drivers/serial/pmac_zilog.c
@@ -604,7 +604,7 @@ static void pmz_set_mctrl(struct uart_po
 /* 
  * Get Modem Control bits (only the input ones, the core will
  * or that with a cached value of the control ones)
- * The port lock is not held.
+ * The port lock is held and interrupts are disabled.
  */
 static unsigned int pmz_get_mctrl(struct uart_port *port)
 {
@@ -615,7 +615,7 @@ static unsigned int pmz_get_mctrl(struct
 	if (ZS_IS_ASLEEP(uap) || uap->node == NULL)
 		return 0;
 
-	status = pmz_peek_status(to_pmz(port));
+	status = read_zsreg(uap, R0);
 
 	ret = 0;
 	if (status & DCD)
@@ -1545,7 +1545,7 @@ static void pmz_dispose_port(struct uart
 /*
  * Called upon match with an escc node in the devive-tree.
  */
-static int pmz_attach(struct macio_dev *mdev, const struct of_match *match)
+static int pmz_attach(struct macio_dev *mdev, const struct of_device_id *match)
 {
 	int i;
 	
@@ -1850,20 +1850,17 @@ err_out:
 	return rc;
 }
 
-static struct of_match pmz_match[] = 
+static struct of_device_id pmz_match[] = 
 {
 	{
 	.name 		= "ch-a",
-	.type		= OF_ANY_MATCH,
-	.compatible	= OF_ANY_MATCH
 	},
 	{
 	.name 		= "ch-b",
-	.type		= OF_ANY_MATCH,
-	.compatible	= OF_ANY_MATCH
 	},
 	{},
 };
+MODULE_DEVICE_TABLE (of, pmz_match);
 
 static struct macio_driver pmz_driver = 
 {
diff --git a/drivers/serial/pxa.c b/drivers/serial/pxa.c
--- a/drivers/serial/pxa.c
+++ b/drivers/serial/pxa.c
@@ -274,14 +274,11 @@ static unsigned int serial_pxa_tx_empty(
 static unsigned int serial_pxa_get_mctrl(struct uart_port *port)
 {
 	struct uart_pxa_port *up = (struct uart_pxa_port *)port;
-	unsigned long flags;
 	unsigned char status;
 	unsigned int ret;
 
 return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;
-	spin_lock_irqsave(&up->port.lock, flags);
 	status = serial_in(up, UART_MSR);
-	spin_unlock_irqrestore(&up->port.lock, flags);
 
 	ret = 0;
 	if (status & UART_MSR_DCD)
@@ -455,22 +452,22 @@ serial_pxa_set_termios(struct uart_port 
 
 	switch (termios->c_cflag & CSIZE) {
 	case CS5:
-		cval = 0x00;
+		cval = UART_LCR_WLEN5;
 		break;
 	case CS6:
-		cval = 0x01;
+		cval = UART_LCR_WLEN6;
 		break;
 	case CS7:
-		cval = 0x02;
+		cval = UART_LCR_WLEN7;
 		break;
 	default:
 	case CS8:
-		cval = 0x03;
+		cval = UART_LCR_WLEN8;
 		break;
 	}
 
 	if (termios->c_cflag & CSTOPB)
-		cval |= 0x04;
+		cval |= UART_LCR_STOP;
 	if (termios->c_cflag & PARENB)
 		cval |= UART_LCR_PARITY;
 	if (!(termios->c_cflag & PARODD))
diff --git a/drivers/serial/s3c2410.c b/drivers/serial/s3c2410.c
--- a/drivers/serial/s3c2410.c
+++ b/drivers/serial/s3c2410.c
@@ -198,7 +198,7 @@ static inline struct s3c24xx_uart_port *
 
 /* translate a port to the device name */
 
-static inline char *s3c24xx_serial_portname(struct uart_port *port)
+static inline const char *s3c24xx_serial_portname(struct uart_port *port)
 {
 	return to_platform_device(port->dev)->name;
 }
@@ -522,14 +522,11 @@ static void s3c24xx_serial_shutdown(stru
 static int s3c24xx_serial_startup(struct uart_port *port)
 {
 	struct s3c24xx_uart_port *ourport = to_ourport(port);
-	unsigned long flags;
 	int ret;
 
 	dbg("s3c24xx_serial_startup: port=%p (%08lx,%p)\n",
 	    port->mapbase, port->membase);
 
-	local_irq_save(flags);
-
 	rx_enabled(port) = 1;
 
 	ret = request_irq(RX_IRQ(port),
@@ -563,12 +560,10 @@ static int s3c24xx_serial_startup(struct
 	/* the port reset code should have done the correct
 	 * register setup for the port controls */
 
-	local_irq_restore(flags);
 	return ret;
 
  err:
 	s3c24xx_serial_shutdown(port);
-	local_irq_restore(flags);
 	return ret;
 }
 
@@ -903,7 +898,7 @@ static void s3c24xx_serial_release_port(
 
 static int s3c24xx_serial_request_port(struct uart_port *port)
 {
-	char *name = s3c24xx_serial_portname(port);
+	const char *name = s3c24xx_serial_portname(port);
 	return request_mem_region(port->mapbase, MAP_SIZE, name) ? 0 : -EBUSY;
 }
 
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c
--- a/drivers/serial/serial_core.c
+++ b/drivers/serial/serial_core.c
@@ -182,6 +182,13 @@ static int uart_startup(struct uart_stat
 				uart_set_mctrl(port, TIOCM_RTS | TIOCM_DTR);
 		}
 
+		if (info->flags & UIF_CTS_FLOW) {
+			spin_lock_irq(&port->lock);
+			if (!(port->ops->get_mctrl(port) & TIOCM_CTS))
+				info->tty->hw_stopped = 1;
+			spin_unlock_irq(&port->lock);
+		}
+
 		info->flags |= UIF_INITIALIZED;
 
 		clear_bit(TTY_IO_ERROR, &info->tty->flags);
@@ -828,7 +835,10 @@ static int uart_tiocmget(struct tty_stru
 	if ((!file || !tty_hung_up_p(file)) &&
 	    !(tty->flags & (1 << TTY_IO_ERROR))) {
 		result = port->mctrl;
+
+		spin_lock_irq(&port->lock);
 		result |= port->ops->get_mctrl(port);
+		spin_unlock_irq(&port->lock);
 	}
 	up(&state->sem);
 
@@ -1131,6 +1141,16 @@ static void uart_set_termios(struct tty_
 		spin_unlock_irqrestore(&state->port->lock, flags);
 	}
 
+	/* Handle turning on CRTSCTS */
+	if (!(old_termios->c_cflag & CRTSCTS) && (cflag & CRTSCTS)) {
+		spin_lock_irqsave(&state->port->lock, flags);
+		if (!(state->port->ops->get_mctrl(state->port) & TIOCM_CTS)) {
+			tty->hw_stopped = 1;
+			state->port->ops->stop_tx(state->port, 0);
+		}
+		spin_unlock_irqrestore(&state->port->lock, flags);
+	}
+
 #if 0
 	/*
 	 * No need to wake up processes in open wait, since they
@@ -1369,6 +1389,7 @@ uart_block_til_ready(struct file *filp, 
 	DECLARE_WAITQUEUE(wait, current);
 	struct uart_info *info = state->info;
 	struct uart_port *port = state->port;
+	unsigned int mctrl;
 
 	info->blocked_open++;
 	state->count--;
@@ -1416,7 +1437,10 @@ uart_block_til_ready(struct file *filp, 
 		 * and wait for the carrier to indicate that the
 		 * modem is ready for us.
 		 */
-		if (port->ops->get_mctrl(port) & TIOCM_CAR)
+		spin_lock_irq(&port->lock);
+		mctrl = port->ops->get_mctrl(port);
+		spin_unlock_irq(&port->lock);
+		if (mctrl & TIOCM_CAR)
 			break;
 
 		up(&state->sem);
@@ -1618,7 +1642,9 @@ static int uart_line_info(char *buf, str
 
 	if(capable(CAP_SYS_ADMIN))
 	{
+		spin_lock_irq(&port->lock);
 		status = port->ops->get_mctrl(port);
+		spin_unlock_irq(&port->lock);
 
 		ret += sprintf(buf + ret, " tx:%d rx:%d",
 				port->icount.tx, port->icount.rx);
@@ -1782,6 +1808,12 @@ uart_set_options(struct uart_port *port,
 	struct termios termios;
 	int i;
 
+	/*
+	 * Ensure that the serial console lock is initialised
+	 * early.
+	 */
+	spin_lock_init(&port->lock);
+
 	memset(&termios, 0, sizeof(struct termios));
 
 	termios.c_cflag = CREAD | HUPCL | CLOCAL;
@@ -2170,10 +2202,16 @@ int uart_add_one_port(struct uart_driver
 
 	state->port = port;
 
-	spin_lock_init(&port->lock);
 	port->cons = drv->cons;
 	port->info = state->info;
 
+	/*
+	 * If this port is a console, then the spinlock is already
+	 * initialised.
+	 */
+	if (!uart_console(port))
+		spin_lock_init(&port->lock);
+
 	uart_configure_port(drv, state, port);
 
 	/*
diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c
--- a/drivers/serial/serial_cs.c
+++ b/drivers/serial/serial_cs.c
@@ -45,7 +45,6 @@
 #include <asm/io.h>
 #include <asm/system.h>
 
-#include <pcmcia/version.h>
 #include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
@@ -232,11 +231,6 @@ static dev_link_t *serial_attach(void)
 	link->next = dev_list;
 	dev_list = link;
 	client_reg.dev_info = &dev_info;
-	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 = &serial_event;
 	client_reg.Version = 0x0210;
 	client_reg.event_callback_args.client_data = link;
 	ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -772,13 +766,120 @@ serial_event(event_t event, int priority
 	return 0;
 }
 
+static struct pcmcia_device_id serial_ids[] = {
+	PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0057, 0x0021),
+	PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0089, 0x110a),
+	PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0104, 0x000a),
+	PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0105, 0xea15),
+	PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0109, 0x0501),
+	PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0138, 0x110a),
+	PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0140, 0x000a),
+	PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0143, 0x3341),
+	PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0143, 0xc0ab),
+	PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x016c, 0x0081),
+	PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x021b, 0x0101),
+	PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x08a1, 0xc0ab),
+	PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0105, 0x0d0a),
+	PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0105, 0x0e0a),
+	PCMCIA_PFC_DEVICE_PROD_ID123(1, "MEGAHERTZ", "CC/XJEM3288", "DATA/FAX/CELL ETHERNET MODEM", 0xf510db04, 0x04cd2988, 0x46a52d63),
+	PCMCIA_PFC_DEVICE_PROD_ID123(1, "MEGAHERTZ", "CC/XJEM3336", "DATA/FAX/CELL ETHERNET MODEM", 0xf510db04, 0x0143b773, 0x46a52d63),
+	PCMCIA_PFC_DEVICE_PROD_ID123(1, "MEGAHERTZ", "EM1144T", "PCMCIA MODEM", 0xf510db04, 0x856d66c8, 0xbd6c43ef),
+	PCMCIA_PFC_DEVICE_PROD_ID123(1, "MEGAHERTZ", "XJEM1144/CCEM1144", "PCMCIA MODEM", 0xf510db04, 0x52d21e1e, 0xbd6c43ef),
+	PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "CEM28", 0x2e3ee845, 0x0ea978ea),
+	PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "CEM33", 0x2e3ee845, 0x80609023),
+	PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "CEM56", 0x2e3ee845, 0xa650c32a),
+	PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "REM10", 0x2e3ee845, 0x76df1d29),
+	PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "XEM5600", 0x2e3ee845, 0xf1403719),
+	PCMCIA_PFC_DEVICE_PROD_ID12(1, "AnyCom", "Fast Ethernet + 56K COMBO", 0x578ba6e7, 0xb0ac62c4),
+	PCMCIA_PFC_DEVICE_PROD_ID12(1, "D-Link", "DME336T", 0x1a424a1c, 0xb23897ff),
+	PCMCIA_PFC_DEVICE_PROD_ID12(1, "Gateway 2000", "XJEM3336", 0xdd9989be, 0x662c394c),
+	PCMCIA_PFC_DEVICE_PROD_ID12(1, "Grey Cell", "GCS3000", 0x2a151fac, 0x48b932ae),
+	PCMCIA_PFC_DEVICE_PROD_ID12(1, "Linksys", "EtherFast 10&100 + 56K PC Card (PCMLM56)", 0x0733cc81, 0xb3765033),
+	PCMCIA_PFC_DEVICE_PROD_ID12(1, "LINKSYS", "PCMLM336", 0xf7cb0b07, 0x7a821b58),
+	PCMCIA_PFC_DEVICE_PROD_ID12(1, "MEGAHERTZ", "XJEM1144/CCEM1144", 0xf510db04, 0x52d21e1e),
+	PCMCIA_PFC_DEVICE_PROD_ID12(1, "Ositech", "Trumpcard:Jack of Diamonds Modem+Ethernet", 0xc2f80cd, 0x656947b9),
+	PCMCIA_PFC_DEVICE_PROD_ID12(1, "Ositech", "Trumpcard:Jack of Hearts Modem+Ethernet", 0xc2f80cd, 0xdc9ba5ed),
+	PCMCIA_PFC_DEVICE_PROD_ID12(1, "PCMCIAs", "ComboCard", 0xdcfe12d3, 0xcd8906cc),
+	PCMCIA_PFC_DEVICE_PROD_ID12(1, "PCMCIAs", "LanModem", 0xdcfe12d3, 0xc67c648f),
+	PCMCIA_PFC_DEVICE_PROD_ID12(1, "TDK", "GlobalNetworker 3410/3412", 0x1eae9475, 0xd9a93bed),
+	PCMCIA_PFC_DEVICE_PROD_ID12(1, "Xircom", "CreditCard Ethernet+Modem II", 0x2e3ee845, 0xeca401bf),
+	PCMCIA_MFC_DEVICE_MANF_CARD(0, 0x0104, 0x0070),
+	PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x0101, 0x0562),
+	PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x0104, 0x0070),
+	PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x016c, 0x0020),
+	PCMCIA_MFC_DEVICE_PROD_ID123(1, "APEX DATA", "MULTICARD", "ETHERNET-MODEM", 0x11c2da09, 0x7289dc5d, 0xaad95e1f),
+	PCMCIA_MFC_DEVICE_PROD_ID12(1, "IBM", "Home and Away 28.8 PC Card       ", 0xb569a6e5, 0x5bd4ff2c),
+	PCMCIA_MFC_DEVICE_PROD_ID12(1, "IBM", "Home and Away Credit Card Adapter", 0xb569a6e5, 0x4bdf15c3),
+	PCMCIA_MFC_DEVICE_PROD_ID12(1, "IBM", "w95 Home and Away Credit Card ", 0xb569a6e5, 0xae911c15),
+	PCMCIA_MFC_DEVICE_PROD_ID1(1, "Motorola MARQUIS", 0xf03e4e77),
+	PCMCIA_MFC_DEVICE_PROD_ID2(1, "FAX/Modem/Ethernet Combo Card ", 0x1ed59302),
+	PCMCIA_DEVICE_MANF_CARD(0x0089, 0x0301),
+	PCMCIA_DEVICE_MANF_CARD(0x0101, 0x0039),
+	PCMCIA_DEVICE_MANF_CARD(0x0104, 0x0006),
+	PCMCIA_DEVICE_MANF_CARD(0x0105, 0x410a),
+	PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0d50),
+	PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0d51),
+	PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0d52),
+	PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0d53),
+	PCMCIA_DEVICE_MANF_CARD(0x010b, 0xd180),
+	PCMCIA_DEVICE_MANF_CARD(0x0137, 0x000e),
+	PCMCIA_DEVICE_MANF_CARD(0x0137, 0x001b),
+	PCMCIA_DEVICE_MANF_CARD(0x0137, 0x0025),
+	PCMCIA_DEVICE_MANF_CARD(0x0137, 0x0045),
+	PCMCIA_DEVICE_MANF_CARD(0x0137, 0x0052),
+	PCMCIA_DEVICE_PROD_ID134("ADV", "TECH", "COMpad-32/85", 0x67459937, 0x916d02ba, 0x8fbe92ae),
+	PCMCIA_DEVICE_PROD_ID124("GATEWAY2000", "CC3144", "PCMCIA MODEM", 0x506bccae, 0xcb3685f1, 0xbd6c43ef),
+	PCMCIA_DEVICE_PROD_ID14("MEGAHERTZ", "PCMCIA MODEM", 0xf510db04, 0xbd6c43ef),
+	PCMCIA_DEVICE_PROD_ID124("TOSHIBA", "T144PF", "PCMCIA MODEM", 0xb4585a1a, 0x7271409c, 0xbd6c43ef),
+	PCMCIA_DEVICE_PROD_ID123("FUJITSU", "FC14F ", "MBH10213", 0x6ee5a3d8, 0x30ead12b, 0xb00f05a0),
+	PCMCIA_DEVICE_PROD_ID13("MEGAHERTZ", "V.34 PCMCIA MODEM", 0xf510db04, 0xbb2cce4a),
+	PCMCIA_DEVICE_PROD_ID12("Brain Boxes", "Bluetooth PC Card", 0xee138382, 0xd4ce9b02),
+	PCMCIA_DEVICE_PROD_ID12("CIRRUS LOGIC", "FAX MODEM", 0xe625f451, 0xcecd6dfa),
+	PCMCIA_DEVICE_PROD_ID12("COMPAQ", "PCMCIA 28800 FAX/DATA MODEM", 0xa3a3062c, 0x8cbd7c76),
+	PCMCIA_DEVICE_PROD_ID12("COMPAQ", "PCMCIA 33600 FAX/DATA MODEM", 0xa3a3062c, 0x5a00ce95),
+	PCMCIA_DEVICE_PROD_ID12("Computerboards, Inc.", "PCM-COM422", 0xd0b78f51, 0x7e2d49ed),
+	PCMCIA_DEVICE_PROD_ID12("Dr. Neuhaus", "FURY CARD 14K4", 0x76942813, 0x8b96ce65),
+	PCMCIA_DEVICE_PROD_ID12("Intelligent", "ANGIA FAX/MODEM", 0xb496e65e, 0xf31602a6),
+	PCMCIA_DEVICE_PROD_ID12("Intel", "MODEM 2400+", 0x816cc815, 0x412729fb),
+	PCMCIA_DEVICE_PROD_ID12("IOTech Inc ", "PCMCIA Dual RS-232 Serial Port Card", 0x3bd2d898, 0x92abc92f),
+	PCMCIA_DEVICE_PROD_ID12("MACRONIX", "FAX/MODEM", 0x668388b3, 0x3f9bdf2f),
+	PCMCIA_DEVICE_PROD_ID12("Multi-Tech", "MT1432LT", 0x5f73be51, 0x0b3e2383),
+	PCMCIA_DEVICE_PROD_ID12("Multi-Tech", "MT2834LT", 0x5f73be51, 0x4cd7c09e),
+	PCMCIA_DEVICE_PROD_ID12("OEM      ", "C288MX     ", 0xb572d360, 0xd2385b7a),
+	PCMCIA_DEVICE_PROD_ID12("PCMCIA   ", "C336MX     ", 0x99bcafe9, 0xaa25bcab),
+	PCMCIA_DEVICE_PROD_ID12("Quatech Inc", "PCMCIA Dual RS-232 Serial Port Card", 0xc4420b35, 0x92abc92f),
+	PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "PCMCIA", "EN2218-LAN/MODEM", 0x281f1c5d, 0x570f348e, "PCMLM28.cis"),
+	PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "PCMCIA", "UE2218-LAN/MODEM", 0x281f1c5d, 0x6fdcacee, "PCMLM28.cis"),
+	PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "Psion Dacom", "Gold Card V34 Ethernet", 0xf5f025c2, 0x338e8155, "PCMLM28.cis"),
+	PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "Psion Dacom", "Gold Card V34 Ethernet GSM", 0xf5f025c2, 0x4ae85d35, "PCMLM28.cis"),
+	PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "LINKSYS", "PCMLM28", 0xf7cb0b07, 0x66881874, "PCMLM28.cis"),
+	PCMCIA_MFC_DEVICE_CIS_PROD_ID12(1, "DAYNA COMMUNICATIONS", "LAN AND MODEM MULTIFUNCTION", 0x8fdf8f89, 0xdd5ed9e8, "DP83903.cis"),
+	PCMCIA_MFC_DEVICE_CIS_PROD_ID4(1, "NSC MF LAN/Modem", 0x58fc6056, "DP83903.cis"),
+	PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x0556, "3CCFEM556.cis"),
+	PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0175, 0x0000, "DP83903.cis"),
+	PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x0035, "3CXEM556.cis"),
+	PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x003d, "3CXEM556.cis"),
+	PCMCIA_DEVICE_CIS_PROD_ID12("MultiTech", "PCMCIA 56K DataFax", 0x842047ee, 0xc2efcf03, "MT5634ZLX.cis"),
+	PCMCIA_DEVICE_CIS_PROD_ID12("ADVANTECH", "COMpad-32/85B-4", 0x96913a85, 0xcec8f102, "COMpad4.cis"),
+	PCMCIA_DEVICE_CIS_PROD_ID123("ADVANTECH", "COMpad-32/85", "1.0", 0x96913a85, 0x8fbe92ae, 0x0877b627, "COMpad2.cis"),
+	PCMCIA_DEVICE_CIS_PROD_ID2("RS-COM 2P", 0xad20b156, "RS-COM-2P.cis"),
+	/* too generic */
+	/* PCMCIA_MFC_DEVICE_MANF_CARD(0, 0x0160, 0x0002), */
+	/* PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x0160, 0x0002), */
+	PCMCIA_DEVICE_FUNC_ID(2),
+	PCMCIA_DEVICE_NULL,
+};
+MODULE_DEVICE_TABLE(pcmcia, serial_ids);
+
 static struct pcmcia_driver serial_cs_driver = {
 	.owner		= THIS_MODULE,
 	.drv		= {
 		.name	= "serial_cs",
 	},
 	.attach		= serial_attach,
+	.event		= serial_event,
 	.detach		= serial_detach,
+	.id_table	= serial_ids,
 };
 
 static int __init init_serial_cs(void)
diff --git a/drivers/serial/serial_txx9.c b/drivers/serial/serial_txx9.c
--- a/drivers/serial/serial_txx9.c
+++ b/drivers/serial/serial_txx9.c
@@ -442,13 +442,10 @@ static unsigned int serial_txx9_tx_empty
 static unsigned int serial_txx9_get_mctrl(struct uart_port *port)
 {
 	struct uart_txx9_port *up = (struct uart_txx9_port *)port;
-	unsigned long flags;
 	unsigned int ret;
 
-	spin_lock_irqsave(&up->port.lock, flags);
 	ret =  ((sio_in(up, TXX9_SIFLCR) & TXX9_SIFLCR_RTSSC) ? 0 : TIOCM_RTS)
 		| ((sio_in(up, TXX9_SICISR) & TXX9_SICISR_CTSS) ? 0 : TIOCM_CTS);
-	spin_unlock_irqrestore(&up->port.lock, flags);
 
 	return ret;
 }
diff --git a/drivers/serial/sn_console.c b/drivers/serial/sn_console.c
--- a/drivers/serial/sn_console.c
+++ b/drivers/serial/sn_console.c
@@ -572,6 +572,7 @@ static void sn_transmit_chars(struct sn_
 
 	if (uart_circ_empty(xmit) || uart_tx_stopped(&port->sc_port)) {
 		/* Nothing to do. */
+		ia64_sn_console_intr_disable(SAL_CONSOLE_INTR_XMIT);
 		return;
 	}
 
@@ -1092,6 +1093,7 @@ int __init sn_serial_console_early_setup
 		return -1;
 
 	sal_console_port.sc_ops = &poll_ops;
+	spin_lock_init(&sal_console_port.sc_port.lock);
 	early_sn_setup();	/* Find SAL entry points */
 	register_console(&sal_console_early);
 
diff --git a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c
--- a/drivers/serial/sunsab.c
+++ b/drivers/serial/sunsab.c
@@ -426,18 +426,15 @@ static void sunsab_set_mctrl(struct uart
 		sunsab_tx_idle(up);
 }
 
-/* port->lock is not held.  */
+/* port->lock is held by caller and interrupts are disabled.  */
 static unsigned int sunsab_get_mctrl(struct uart_port *port)
 {
 	struct uart_sunsab_port *up = (struct uart_sunsab_port *) port;
-	unsigned long flags;
 	unsigned char val;
 	unsigned int result;
 
 	result = 0;
 
-	spin_lock_irqsave(&up->port.lock, flags);
-
 	val = readb(&up->regs->r.pvr);
 	result |= (val & up->pvr_dsr_bit) ? 0 : TIOCM_DSR;
 
@@ -447,8 +444,6 @@ static unsigned int sunsab_get_mctrl(str
 	val = readb(&up->regs->r.star);
 	result |= (val & SAB82532_STAR_CTS) ? TIOCM_CTS : 0;
 
-	spin_unlock_irqrestore(&up->port.lock, flags);
-
 	return result;
 }
 
diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c
--- a/drivers/serial/sunsu.c
+++ b/drivers/serial/sunsu.c
@@ -572,13 +572,10 @@ static unsigned int sunsu_tx_empty(struc
 static unsigned int sunsu_get_mctrl(struct uart_port *port)
 {
 	struct uart_sunsu_port *up = (struct uart_sunsu_port *) port;
-	unsigned long flags;
 	unsigned char status;
 	unsigned int ret;
 
-	spin_lock_irqsave(&up->port.lock, flags);
 	status = serial_in(up, UART_MSR);
-	spin_unlock_irqrestore(&up->port.lock, flags);
 
 	ret = 0;
 	if (status & UART_MSR_DCD)
diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c
--- a/drivers/serial/sunzilog.c
+++ b/drivers/serial/sunzilog.c
@@ -610,27 +610,28 @@ static irqreturn_t sunzilog_interrupt(in
 static __inline__ unsigned char sunzilog_read_channel_status(struct uart_port *port)
 {
 	struct zilog_channel __iomem *channel;
-	unsigned long flags;
 	unsigned char status;
 
-	spin_lock_irqsave(&port->lock, flags);
-
 	channel = ZILOG_CHANNEL_FROM_PORT(port);
 	status = sbus_readb(&channel->control);
 	ZSDELAY();
 
-	spin_unlock_irqrestore(&port->lock, flags);
-
 	return status;
 }
 
 /* The port lock is not held.  */
 static unsigned int sunzilog_tx_empty(struct uart_port *port)
 {
+	unsigned long flags;
 	unsigned char status;
 	unsigned int ret;
 
+	spin_lock_irqsave(&port->lock, flags);
+
 	status = sunzilog_read_channel_status(port);
+
+	spin_unlock_irqrestore(&port->lock, flags);
+
 	if (status & Tx_BUF_EMP)
 		ret = TIOCSER_TEMT;
 	else
@@ -639,7 +640,7 @@ static unsigned int sunzilog_tx_empty(st
 	return ret;
 }
 
-/* The port lock is not held.  */
+/* The port lock is held and interrupts are disabled.  */
 static unsigned int sunzilog_get_mctrl(struct uart_port *port)
 {
 	unsigned char status;
@@ -1071,7 +1072,7 @@ static void __init sunzilog_alloc_tables
  */
 static struct zilog_layout __iomem * __init get_zs_sun4u(int chip, int zsnode)
 {
-	unsigned long mapped_addr;
+	void __iomem *mapped_addr;
 	unsigned int sun4u_ino;
 	struct sbus_bus *sbus = NULL;
 	struct sbus_dev *sdev = NULL;
@@ -1111,9 +1112,9 @@ static struct zilog_layout __iomem * __i
 		apply_fhc_ranges(central_bus->child,
 				 &zsregs[0], 1);
 		apply_central_ranges(central_bus, &zsregs[0], 1);
-		mapped_addr =
-			(((u64)zsregs[0].which_io)<<32UL) |
-			((u64)zsregs[0].phys_addr);
+		mapped_addr = (void __iomem *)
+			((((u64)zsregs[0].which_io)<<32UL) |
+			((u64)zsregs[0].phys_addr));
 	}
 
 	if (zilog_irq == -1) {
diff --git a/drivers/sh/superhyway/superhyway-sysfs.c b/drivers/sh/superhyway/superhyway-sysfs.c
--- a/drivers/sh/superhyway/superhyway-sysfs.c
+++ b/drivers/sh/superhyway/superhyway-sysfs.c
@@ -15,7 +15,7 @@
 #include <linux/superhyway.h>
 
 #define superhyway_ro_attr(name, fmt, field)				\
-static ssize_t name##_show(struct device *dev, char *buf)		\
+static ssize_t name##_show(struct device *dev, struct device_attribute *attr, char *buf)		\
 {									\
 	struct superhyway_device *s = to_superhyway_device(dev);	\
 	return sprintf(buf, fmt, s->field);				\
diff --git a/drivers/sn/Kconfig b/drivers/sn/Kconfig
new file mode 100644
--- /dev/null
+++ b/drivers/sn/Kconfig
@@ -0,0 +1,20 @@
+#
+# Miscellaneous SN-specific devices
+#
+
+menu "SN Devices"
+
+config SGI_IOC4
+	tristate "SGI IOC4 Base IO support"
+	depends on (IA64_GENERIC || IA64_SGI_SN2) && MMTIMER
+	default m
+	---help---
+	This option enables basic support for the SGI IOC4-based Base IO
+	controller card.  This option does not enable any specific
+	functions on such a card, but provides necessary infrastructure
+	for other drivers to utilize.
+
+	If you have an SGI Altix with an IOC4-based
+	I/O controller say Y.  Otherwise say N.
+
+endmenu
diff --git a/drivers/sn/Makefile b/drivers/sn/Makefile
--- a/drivers/sn/Makefile
+++ b/drivers/sn/Makefile
@@ -3,4 +3,4 @@
 #
 #
 
-obj-$(CONFIG_BLK_DEV_SGIIOC4) += ioc4.o
+obj-$(CONFIG_SGI_IOC4) += ioc4.o
diff --git a/drivers/sn/ioc4.c b/drivers/sn/ioc4.c
--- a/drivers/sn/ioc4.c
+++ b/drivers/sn/ioc4.c
@@ -6,60 +6,422 @@
  * Copyright (C) 2005 Silicon Graphics, Inc.  All Rights Reserved.
  */
 
-/*
- * This file contains a shim driver for the IOC4 IDE and serial drivers.
+/* This file contains the master driver module for use by SGI IOC4 subdrivers.
+ *
+ * It allocates any resources shared between multiple subdevices, and
+ * provides accessor functions (where needed) and the like for those
+ * resources.  It also provides a mechanism for the subdevice modules
+ * to support loading and unloading.
+ *
+ * Non-shared resources (e.g. external interrupt A_INT_OUT register page
+ * alias, serial port and UART registers) are handled by the subdevice
+ * modules themselves.
+ *
+ * This is all necessary because IOC4 is not implemented as a multi-function
+ * PCI device, but an amalgamation of disparate registers for several
+ * types of device (ATA, serial, external interrupts).  The normal
+ * resource management in the kernel doesn't have quite the right interfaces
+ * to handle this situation (e.g. multiple modules can't claim the same
+ * PCI ID), thus this IOC4 master module.
  */
 
 #include <linux/errno.h>
 #include <linux/module.h>
 #include <linux/pci.h>
-#include <linux/ioc4_common.h>
-#include <linux/ide.h>
+#include <linux/ioc4.h>
+#include <linux/mmtimer.h>
+#include <linux/rtc.h>
+#include <linux/rwsem.h>
+#include <asm/sn/addrs.h>
+#include <asm/sn/clksupport.h>
+#include <asm/sn/shub_mmr.h>
+
+/***************
+ * Definitions *
+ ***************/
+
+/* Tweakable values */
+
+/* PCI bus speed detection/calibration */
+#define IOC4_CALIBRATE_COUNT 63	/* Calibration cycle period */
+#define IOC4_CALIBRATE_CYCLES 256	/* Average over this many cycles */
+#define IOC4_CALIBRATE_DISCARD 2	/* Discard first few cycles */
+#define IOC4_CALIBRATE_LOW_MHZ 25	/* Lower bound on bus speed sanity */
+#define IOC4_CALIBRATE_HIGH_MHZ 75	/* Upper bound on bus speed sanity */
+#define IOC4_CALIBRATE_DEFAULT_MHZ 66	/* Assumed if sanity check fails */
+
+/************************
+ * Submodule management *
+ ************************/
+
+static LIST_HEAD(ioc4_devices);
+static DECLARE_RWSEM(ioc4_devices_rwsem);
+
+static LIST_HEAD(ioc4_submodules);
+static DECLARE_RWSEM(ioc4_submodules_rwsem);
+
+/* Register an IOC4 submodule */
+int
+ioc4_register_submodule(struct ioc4_submodule *is)
+{
+	struct ioc4_driver_data *idd;
 
+	down_write(&ioc4_submodules_rwsem);
+	list_add(&is->is_list, &ioc4_submodules);
+	up_write(&ioc4_submodules_rwsem);
+
+	/* Initialize submodule for each IOC4 */
+	if (!is->is_probe)
+		return 0;
+
+	down_read(&ioc4_devices_rwsem);
+	list_for_each_entry(idd, &ioc4_devices, idd_list) {
+		if (is->is_probe(idd)) {
+			printk(KERN_WARNING
+			       "%s: IOC4 submodule %s probe failed "
+			       "for pci_dev %s",
+			       __FUNCTION__, module_name(is->is_owner),
+			       pci_name(idd->idd_pdev));
+		}
+	}
+	up_read(&ioc4_devices_rwsem);
 
-static int __devinit
-ioc4_probe_one(struct pci_dev *pdev, const struct pci_device_id *pci_id)
+	return 0;
+}
+
+/* Unregister an IOC4 submodule */
+void
+ioc4_unregister_submodule(struct ioc4_submodule *is)
+{
+	struct ioc4_driver_data *idd;
+
+	down_write(&ioc4_submodules_rwsem);
+	list_del(&is->is_list);
+	up_write(&ioc4_submodules_rwsem);
+
+	/* Remove submodule for each IOC4 */
+	if (!is->is_remove)
+		return;
+
+	down_read(&ioc4_devices_rwsem);
+	list_for_each_entry(idd, &ioc4_devices, idd_list) {
+		if (is->is_remove(idd)) {
+			printk(KERN_WARNING
+			       "%s: IOC4 submodule %s remove failed "
+			       "for pci_dev %s.\n",
+			       __FUNCTION__, module_name(is->is_owner),
+			       pci_name(idd->idd_pdev));
+		}
+	}
+	up_read(&ioc4_devices_rwsem);
+}
+
+/*********************
+ * Device management *
+ *********************/
+
+#define IOC4_CALIBRATE_LOW_LIMIT \
+	(1000*IOC4_EXTINT_COUNT_DIVISOR/IOC4_CALIBRATE_LOW_MHZ)
+#define IOC4_CALIBRATE_HIGH_LIMIT \
+	(1000*IOC4_EXTINT_COUNT_DIVISOR/IOC4_CALIBRATE_HIGH_MHZ)
+#define IOC4_CALIBRATE_DEFAULT \
+	(1000*IOC4_EXTINT_COUNT_DIVISOR/IOC4_CALIBRATE_DEFAULT_MHZ)
+
+#define IOC4_CALIBRATE_END \
+	(IOC4_CALIBRATE_CYCLES + IOC4_CALIBRATE_DISCARD)
+
+#define IOC4_INT_OUT_MODE_TOGGLE 0x7	/* Toggle INT_OUT every COUNT+1 ticks */
+
+/* Determines external interrupt output clock period of the PCI bus an
+ * IOC4 is attached to.  This value can be used to determine the PCI
+ * bus speed.
+ *
+ * IOC4 has a design feature that various internal timers are derived from
+ * the PCI bus clock.  This causes IOC4 device drivers to need to take the
+ * bus speed into account when setting various register values (e.g. INT_OUT
+ * register COUNT field, UART divisors, etc).  Since this information is
+ * needed by several subdrivers, it is determined by the main IOC4 driver,
+ * even though the following code utilizes external interrupt registers
+ * to perform the speed calculation.
+ */
+static void
+ioc4_clock_calibrate(struct ioc4_driver_data *idd)
+{
+	extern unsigned long sn_rtc_cycles_per_second;
+	union ioc4_int_out int_out;
+	union ioc4_gpcr gpcr;
+	unsigned int state, last_state = 1;
+	uint64_t start = 0, end, period;
+	unsigned int count = 0;
+
+	/* Enable output */
+	gpcr.raw = 0;
+	gpcr.fields.dir = IOC4_GPCR_DIR_0;
+	gpcr.fields.int_out_en = 1;
+	writel(gpcr.raw, &idd->idd_misc_regs->gpcr_s.raw);
+
+	/* Reset to power-on state */
+	writel(0, &idd->idd_misc_regs->int_out.raw);
+	mmiowb();
+
+	printk(KERN_INFO
+	       "%s: Calibrating PCI bus speed "
+	       "for pci_dev %s ... ", __FUNCTION__, pci_name(idd->idd_pdev));
+	/* Set up square wave */
+	int_out.raw = 0;
+	int_out.fields.count = IOC4_CALIBRATE_COUNT;
+	int_out.fields.mode = IOC4_INT_OUT_MODE_TOGGLE;
+	int_out.fields.diag = 0;
+	writel(int_out.raw, &idd->idd_misc_regs->int_out.raw);
+	mmiowb();
+
+	/* Check square wave period averaged over some number of cycles */
+	do {
+		int_out.raw = readl(&idd->idd_misc_regs->int_out.raw);
+		state = int_out.fields.int_out;
+		if (!last_state && state) {
+			count++;
+			if (count == IOC4_CALIBRATE_END) {
+				end = rtc_time();
+				break;
+			} else if (count == IOC4_CALIBRATE_DISCARD)
+				start = rtc_time();
+		}
+		last_state = state;
+	} while (1);
+
+	/* Calculation rearranged to preserve intermediate precision.
+	 * Logically:
+	 * 1. "end - start" gives us number of RTC cycles over all the
+	 *    square wave cycles measured.
+	 * 2. Divide by number of square wave cycles to get number of
+	 *    RTC cycles per square wave cycle.
+	 * 3. Divide by 2*(int_out.fields.count+1), which is the formula
+	 *    by which the IOC4 generates the square wave, to get the
+	 *    number of RTC cycles per IOC4 INT_OUT count.
+	 * 4. Divide by sn_rtc_cycles_per_second to get seconds per
+	 *    count.
+	 * 5. Multiply by 1E9 to get nanoseconds per count.
+	 */
+	period = ((end - start) * 1000000000) /
+	    (IOC4_CALIBRATE_CYCLES * 2 * (IOC4_CALIBRATE_COUNT + 1)
+	     * sn_rtc_cycles_per_second);
+
+	/* Bounds check the result. */
+	if (period > IOC4_CALIBRATE_LOW_LIMIT ||
+	    period < IOC4_CALIBRATE_HIGH_LIMIT) {
+		printk("failed. Assuming PCI clock ticks are %d ns.\n",
+		       IOC4_CALIBRATE_DEFAULT / IOC4_EXTINT_COUNT_DIVISOR);
+		period = IOC4_CALIBRATE_DEFAULT;
+	} else {
+		printk("succeeded. PCI clock ticks are %ld ns.\n",
+		       period / IOC4_EXTINT_COUNT_DIVISOR);
+	}
+
+	/* Remember results.  We store the extint clock period rather
+	 * than the PCI clock period so that greater precision is
+	 * retained.  Divide by IOC4_EXTINT_COUNT_DIVISOR to get
+	 * PCI clock period.
+	 */
+	idd->count_period = period;
+}
+
+/* Adds a new instance of an IOC4 card */
+static int
+ioc4_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id)
 {
+	struct ioc4_driver_data *idd;
+	struct ioc4_submodule *is;
+	uint32_t pcmd;
 	int ret;
 
+	/* Enable IOC4 and take ownership of it */
 	if ((ret = pci_enable_device(pdev))) {
 		printk(KERN_WARNING
-			 "%s: Failed to enable device with "
-				"pci_dev 0x%p... returning\n",
-				__FUNCTION__, (void *)pdev);
-		return ret;
+		       "%s: Failed to enable IOC4 device for pci_dev %s.\n",
+		       __FUNCTION__, pci_name(pdev));
+		goto out;
 	}
 	pci_set_master(pdev);
 
-	/* attach each sub-device */
-	ret = ioc4_ide_attach_one(pdev, pci_id);
-	if (ret)
-		return ret;
-	return ioc4_serial_attach_one(pdev, pci_id);
+	/* Set up per-IOC4 data */
+	idd = kmalloc(sizeof(struct ioc4_driver_data), GFP_KERNEL);
+	if (!idd) {
+		printk(KERN_WARNING
+		       "%s: Failed to allocate IOC4 data for pci_dev %s.\n",
+		       __FUNCTION__, pci_name(pdev));
+		ret = -ENODEV;
+		goto out_idd;
+	}
+	idd->idd_pdev = pdev;
+	idd->idd_pci_id = pci_id;
+
+	/* Map IOC4 misc registers.  These are shared between subdevices
+	 * so the main IOC4 module manages them.
+	 */
+	idd->idd_bar0 = pci_resource_start(idd->idd_pdev, 0);
+	if (!idd->idd_bar0) {
+		printk(KERN_WARNING
+		       "%s: Unable to find IOC4 misc resource "
+		       "for pci_dev %s.\n",
+		       __FUNCTION__, pci_name(idd->idd_pdev));
+		ret = -ENODEV;
+		goto out_pci;
+	}
+	if (!request_region(idd->idd_bar0, sizeof(struct ioc4_misc_regs),
+			    "ioc4_misc")) {
+		printk(KERN_WARNING
+		       "%s: Unable to request IOC4 misc region "
+		       "for pci_dev %s.\n",
+		       __FUNCTION__, pci_name(idd->idd_pdev));
+		ret = -ENODEV;
+		goto out_pci;
+	}
+	idd->idd_misc_regs = ioremap(idd->idd_bar0,
+				     sizeof(struct ioc4_misc_regs));
+	if (!idd->idd_misc_regs) {
+		printk(KERN_WARNING
+		       "%s: Unable to remap IOC4 misc region "
+		       "for pci_dev %s.\n",
+		       __FUNCTION__, pci_name(idd->idd_pdev));
+		ret = -ENODEV;
+		goto out_misc_region;
+	}
+
+	/* Failsafe portion of per-IOC4 initialization */
+
+	/* Initialize IOC4 */
+	pci_read_config_dword(idd->idd_pdev, PCI_COMMAND, &pcmd);
+	pci_write_config_dword(idd->idd_pdev, PCI_COMMAND,
+			       pcmd | PCI_COMMAND_PARITY | PCI_COMMAND_SERR);
+
+	/* Determine PCI clock */
+	ioc4_clock_calibrate(idd);
+
+	/* Disable/clear all interrupts.  Need to do this here lest
+	 * one submodule request the shared IOC4 IRQ, but interrupt
+	 * is generated by a different subdevice.
+	 */
+	/* Disable */
+	writel(~0, &idd->idd_misc_regs->other_iec.raw);
+	writel(~0, &idd->idd_misc_regs->sio_iec);
+	/* Clear (i.e. acknowledge) */
+	writel(~0, &idd->idd_misc_regs->other_ir.raw);
+	writel(~0, &idd->idd_misc_regs->sio_ir);
+
+	/* Track PCI-device specific data */
+	idd->idd_serial_data = NULL;
+	pci_set_drvdata(idd->idd_pdev, idd);
+	down_write(&ioc4_devices_rwsem);
+	list_add(&idd->idd_list, &ioc4_devices);
+	up_write(&ioc4_devices_rwsem);
+
+	/* Add this IOC4 to all submodules */
+	down_read(&ioc4_submodules_rwsem);
+	list_for_each_entry(is, &ioc4_submodules, is_list) {
+		if (is->is_probe && is->is_probe(idd)) {
+			printk(KERN_WARNING
+			       "%s: IOC4 submodule 0x%s probe failed "
+			       "for pci_dev %s.\n",
+			       __FUNCTION__, module_name(is->is_owner),
+			       pci_name(idd->idd_pdev));
+		}
+	}
+	up_read(&ioc4_submodules_rwsem);
+
+	return 0;
+
+out_misc_region:
+	release_region(idd->idd_bar0, sizeof(struct ioc4_misc_regs));
+out_pci:
+	kfree(idd);
+out_idd:
+	pci_disable_device(pdev);
+out:
+	return ret;
+}
+
+/* Removes a particular instance of an IOC4 card. */
+static void
+ioc4_remove(struct pci_dev *pdev)
+{
+	struct ioc4_submodule *is;
+	struct ioc4_driver_data *idd;
+
+	idd = pci_get_drvdata(pdev);
+
+	/* Remove this IOC4 from all submodules */
+	down_read(&ioc4_submodules_rwsem);
+	list_for_each_entry(is, &ioc4_submodules, is_list) {
+		if (is->is_remove && is->is_remove(idd)) {
+			printk(KERN_WARNING
+			       "%s: IOC4 submodule 0x%s remove failed "
+			       "for pci_dev %s.\n",
+			       __FUNCTION__, module_name(is->is_owner),
+			       pci_name(idd->idd_pdev));
+		}
+	}
+	up_read(&ioc4_submodules_rwsem);
+
+	/* Release resources */
+	iounmap(idd->idd_misc_regs);
+	if (!idd->idd_bar0) {
+		printk(KERN_WARNING
+		       "%s: Unable to get IOC4 misc mapping for pci_dev %s. "
+		       "Device removal may be incomplete.\n",
+		       __FUNCTION__, pci_name(idd->idd_pdev));
+	}
+	release_region(idd->idd_bar0, sizeof(struct ioc4_misc_regs));
+
+	/* Disable IOC4 and relinquish */
+	pci_disable_device(pdev);
+
+	/* Remove and free driver data */
+	down_write(&ioc4_devices_rwsem);
+	list_del(&idd->idd_list);
+	up_write(&ioc4_devices_rwsem);
+	kfree(idd);
 }
 
-/* pci device struct */
-static struct pci_device_id ioc4_s_id_table[] = {
+static struct pci_device_id ioc4_id_table[] = {
 	{PCI_VENDOR_ID_SGI, PCI_DEVICE_ID_SGI_IOC4, PCI_ANY_ID,
 	 PCI_ANY_ID, 0x0b4000, 0xFFFFFF},
 	{0}
 };
-MODULE_DEVICE_TABLE(pci, ioc4_s_id_table);
 
-static struct pci_driver __devinitdata ioc4_s_driver = {
-	.name	= "IOC4",
-	.id_table = ioc4_s_id_table,
-	.probe	= ioc4_probe_one,
+static struct pci_driver __devinitdata ioc4_driver = {
+	.name = "IOC4",
+	.id_table = ioc4_id_table,
+	.probe = ioc4_probe,
+	.remove = ioc4_remove,
 };
 
-static int __devinit ioc4_detect(void)
+MODULE_DEVICE_TABLE(pci, ioc4_id_table);
+
+/*********************
+ * Module management *
+ *********************/
+
+/* Module load */
+static int __devinit
+ioc4_init(void)
 {
-	ioc4_serial_init();
+	return pci_register_driver(&ioc4_driver);
+}
 
-	return pci_register_driver(&ioc4_s_driver);
+/* Module unload */
+static void __devexit
+ioc4_exit(void)
+{
+	pci_unregister_driver(&ioc4_driver);
 }
-module_init(ioc4_detect);
 
-MODULE_AUTHOR("Pat Gefre - Silicon Graphics Inc. (SGI) <pfg@sgi.com>");
-MODULE_DESCRIPTION("PCI driver module for SGI IOC4 Base-IO Card");
+module_init(ioc4_init);
+module_exit(ioc4_exit);
+
+MODULE_AUTHOR("Brent Casavant - Silicon Graphics, Inc. <bcasavan@sgi.com>");
+MODULE_DESCRIPTION("PCI driver master module for SGI IOC4 Base-IO Card");
 MODULE_LICENSE("GPL");
+
+EXPORT_SYMBOL(ioc4_register_submodule);
+EXPORT_SYMBOL(ioc4_unregister_submodule);
diff --git a/drivers/telephony/ixj.c b/drivers/telephony/ixj.c
--- a/drivers/telephony/ixj.c
+++ b/drivers/telephony/ixj.c
@@ -329,10 +329,8 @@ static IXJ *ixj_alloc()
 
 static void ixj_fsk_free(IXJ *j)
 {
-	if(j->fskdata != NULL) {
-		kfree(j->fskdata);
-		j->fskdata = NULL;
-	}
+	kfree(j->fskdata);
+	j->fskdata = NULL;
 }
 
 static void ixj_fsk_alloc(IXJ *j)
@@ -3867,13 +3865,11 @@ static int set_rec_codec(IXJ *j, int rat
 		j->rec_mode = 7;
 		break;
 	default:
+		kfree(j->read_buffer);
 		j->rec_frame_size = 0;
 		j->rec_mode = -1;
-		if (j->read_buffer) {
-			kfree(j->read_buffer);
-			j->read_buffer = NULL;
-			j->read_buffer_size = 0;
-		}
+		j->read_buffer = NULL;
+		j->read_buffer_size = 0;
 		retval = 1;
 		break;
 	}
@@ -3991,14 +3987,12 @@ static int ixj_record_start(IXJ *j)
 
 static void ixj_record_stop(IXJ *j)
 {
-	if(ixjdebug & 0x0002)
+	if (ixjdebug & 0x0002)
 		printk("IXJ %d Stopping Record Codec %d at %ld\n", j->board, j->rec_codec, jiffies);
 
-	if (j->read_buffer) {
-		kfree(j->read_buffer);
-		j->read_buffer = NULL;
-		j->read_buffer_size = 0;
-	}
+	kfree(j->read_buffer);
+	j->read_buffer = NULL;
+	j->read_buffer_size = 0;
 	if (j->rec_mode > -1) {
 		ixj_WriteDSPCommand(0x5120, j);
 		j->rec_mode = -1;
@@ -4449,13 +4443,11 @@ static int set_play_codec(IXJ *j, int ra
 		j->play_mode = 5;
 		break;
 	default:
+		kfree(j->write_buffer);
 		j->play_frame_size = 0;
 		j->play_mode = -1;
-		if (j->write_buffer) {
-			kfree(j->write_buffer);
-			j->write_buffer = NULL;
-			j->write_buffer_size = 0;
-		}
+		j->write_buffer = NULL;
+		j->write_buffer_size = 0;
 		retval = 1;
 		break;
 	}
@@ -4578,14 +4570,12 @@ static int ixj_play_start(IXJ *j)
 
 static void ixj_play_stop(IXJ *j)
 {
-	if(ixjdebug & 0x0002)
+	if (ixjdebug & 0x0002)
 		printk("IXJ %d Stopping Play Codec %d at %ld\n", j->board, j->play_codec, jiffies);
 
-	if (j->write_buffer) {
-		kfree(j->write_buffer);
-		j->write_buffer = NULL;
-		j->write_buffer_size = 0;
-	}
+	kfree(j->write_buffer);
+	j->write_buffer = NULL;
+	j->write_buffer_size = 0;
 	if (j->play_mode > -1) {
 		ixj_WriteDSPCommand(0x5221, j);	/* Stop playback and flush buffers.  8022 reference page 9-40 */
 
@@ -5810,9 +5800,7 @@ static void ixj_cpt_stop(IXJ *j)
 		ixj_play_tone(j, 0);
 		j->tone_state = j->tone_cadence_state = 0;
 		if (j->cadence_t) {
-			if (j->cadence_t->ce) {
-				kfree(j->cadence_t->ce);
-			}
+			kfree(j->cadence_t->ce);
 			kfree(j->cadence_t);
 			j->cadence_t = NULL;
 		}
@@ -7497,10 +7485,8 @@ static void cleanup(void)
 					printk(KERN_INFO "IXJ: Releasing XILINX address for /dev/phone%d\n", cnt);
 				release_region(j->XILINXbase, 4);
 			}
-			if (j->read_buffer)
-				kfree(j->read_buffer);
-			if (j->write_buffer)
-				kfree(j->write_buffer);
+			kfree(j->read_buffer);
+			kfree(j->write_buffer);
 			if (j->dev)
 				pnp_device_detach(j->dev);
 			if (ixjdebug & 0x0002)
diff --git a/drivers/telephony/ixj_pcmcia.c b/drivers/telephony/ixj_pcmcia.c
--- a/drivers/telephony/ixj_pcmcia.c
+++ b/drivers/telephony/ixj_pcmcia.c
@@ -9,7 +9,6 @@
 #include <linux/errno.h>	/* error codes */
 #include <linux/slab.h>
 
-#include <pcmcia/version.h>
 #include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
@@ -69,11 +68,6 @@ static dev_link_t *ixj_attach(void)
 	link->next = dev_list;
 	dev_list = link;
 	client_reg.dev_info = &dev_info;
-	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 = &ixj_event;
 	client_reg.Version = 0x0210;
 	client_reg.event_callback_args.client_data = link;
 	ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -295,13 +289,21 @@ static int ixj_event(event_t event, int 
 	return 0;
 }
 
+static struct pcmcia_device_id ixj_ids[] = {
+	PCMCIA_DEVICE_MANF_CARD(0x0257, 0x0600),
+	PCMCIA_DEVICE_NULL
+};
+MODULE_DEVICE_TABLE(pcmcia, ixj_ids);
+
 static struct pcmcia_driver ixj_driver = {
 	.owner		= THIS_MODULE,
 	.drv		= {
 		.name	= "ixj_cs",
 	},
 	.attach		= ixj_attach,
+	.event		= ixj_event,
 	.detach		= ixj_detach,
+	.id_table	= ixj_ids,
 };
 
 static int __init ixj_pcmcia_init(void)
diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig
--- a/drivers/usb/Kconfig
+++ b/drivers/usb/Kconfig
@@ -20,6 +20,7 @@ config USB_ARCH_HAS_OHCI
 	default y if SA1111
 	default y if ARCH_OMAP
 	default y if ARCH_LH7A404
+	default y if ARCH_S3C2410
 	default y if PXA27x
 	# PPC:
 	default y if STB03xxx
diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile
--- a/drivers/usb/Makefile
+++ b/drivers/usb/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_USB)		+= core/
 obj-$(CONFIG_USB_MON)		+= mon/
 
 obj-$(CONFIG_USB_EHCI_HCD)	+= host/
+obj-$(CONFIG_USB_ISP116X_HCD)	+= host/
 obj-$(CONFIG_USB_OHCI_HCD)	+= host/
 obj-$(CONFIG_USB_UHCI_HCD)	+= host/
 obj-$(CONFIG_USB_SL811_HCD)	+= host/
@@ -31,6 +32,7 @@ obj-$(CONFIG_USB_MOUSE)		+= input/
 obj-$(CONFIG_USB_MTOUCH)	+= input/
 obj-$(CONFIG_USB_POWERMATE)	+= input/
 obj-$(CONFIG_USB_WACOM)		+= input/
+obj-$(CONFIG_USB_ACECAD)	+= input/
 obj-$(CONFIG_USB_XPAD)		+= input/
 
 obj-$(CONFIG_USB_DABUSB)	+= media/
@@ -63,12 +65,14 @@ obj-$(CONFIG_USB_EMI26)		+= misc/
 obj-$(CONFIG_USB_EMI62)		+= misc/
 obj-$(CONFIG_USB_IDMOUSE)	+= misc/
 obj-$(CONFIG_USB_LCD)		+= misc/
+obj-$(CONFIG_USB_LD)		+= misc/
 obj-$(CONFIG_USB_LED)		+= misc/
 obj-$(CONFIG_USB_LEGOTOWER)	+= misc/
 obj-$(CONFIG_USB_RIO500)	+= misc/
 obj-$(CONFIG_USB_TEST)		+= misc/
 obj-$(CONFIG_USB_USS720)	+= misc/
 obj-$(CONFIG_USB_PHIDGETSERVO)	+= misc/
+obj-$(CONFIG_USB_SISUSBVGA)	+= misc/
 
 obj-$(CONFIG_USB_ATM)		+= atm/
 obj-$(CONFIG_USB_SPEEDTOUCH)	+= atm/
diff --git a/drivers/usb/atm/Kconfig b/drivers/usb/atm/Kconfig
--- a/drivers/usb/atm/Kconfig
+++ b/drivers/usb/atm/Kconfig
@@ -1,30 +1,60 @@
 #
-# USB ATM driver configuration
+# USB/ATM DSL configuration
 #
-comment "USB ATM/DSL drivers"
+
+menu "USB DSL modem support"
 	depends on USB
 
 config USB_ATM
-	tristate "Generic USB ATM/DSL core I/O support"
+	tristate "USB DSL modem support"
 	depends on USB && ATM
 	select CRC32
 	default n
 	help
-	  This provides a library which is used for packet I/O by USB DSL
-	  modems, such as the SpeedTouch driver below. 
+	  Say Y here if you want to connect a USB Digital Subscriber Line (DSL)
+	  modem to your computer's USB port.  You will then need to choose your
+	  modem from the list below.
 
 	  To compile this driver as a module, choose M here: the
-	  module will be called usb_atm.
+	  module will be called usbatm.
 
 config USB_SPEEDTOUCH
-	tristate "Alcatel Speedtouch USB support"
-	depends on USB && ATM
-	select USB_ATM
+	tristate "Speedtouch USB support"
+	depends on USB_ATM
+	select FW_LOADER
 	help
-	  Say Y here if you have an Alcatel SpeedTouch USB or SpeedTouch 330
+	  Say Y here if you have an SpeedTouch USB or SpeedTouch 330
 	  modem.  In order to use your modem you will need to install the 
 	  two parts of the firmware, extracted by the user space tools; see
 	  <http://www.linux-usb.org/SpeedTouch/> for details.
 
 	  To compile this driver as a module, choose M here: the
 	  module will be called speedtch.
+
+config USB_CXACRU
+	tristate "Conexant AccessRunner USB support"
+	depends on USB_ATM
+	select FW_LOADER
+	help
+	  Say Y here if you have an ADSL USB modem based on the Conexant
+	  AccessRunner chipset.  In order to use your modem you will need to
+	  install the firmware, extracted by the user space tools; see
+	  <http://accessrunner.sourceforge.net/> for details.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called cxacru.
+
+config USB_XUSBATM
+	tristate "Other USB DSL modem support"
+	depends on USB_ATM
+	help
+	  Say Y here if you have a DSL USB modem not explicitly supported by
+	  another USB DSL drivers.  In order to use your modem you will need to
+	  pass the vendor ID, product ID, and endpoint numbers for transmission
+	  and reception as module parameters.  You may need to initialize the
+	  the modem using a user space utility (a firmware loader for example).
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called xusbatm.
+
+endmenu
diff --git a/drivers/usb/atm/Makefile b/drivers/usb/atm/Makefile
--- a/drivers/usb/atm/Makefile
+++ b/drivers/usb/atm/Makefile
@@ -1,7 +1,8 @@
 #
-# Makefile for the rest of the USB drivers
-# (the ones that don't fit into any other categories)
+# Makefile for USB ATM/xDSL drivers
 #
 
-obj-$(CONFIG_USB_ATM)		+= usb_atm.o
+obj-$(CONFIG_USB_CXACRU)	+= cxacru.o
 obj-$(CONFIG_USB_SPEEDTOUCH)	+= speedtch.o
+obj-$(CONFIG_USB_ATM)		+= usbatm.o
+obj-$(CONFIG_USB_XUSBATM)	+= xusbatm.o
diff --git a/drivers/usb/atm/cxacru.c b/drivers/usb/atm/cxacru.c
new file mode 100644
--- /dev/null
+++ b/drivers/usb/atm/cxacru.c
@@ -0,0 +1,878 @@
+/******************************************************************************
+ *  cxacru.c  -  driver for USB ADSL modems based on
+ *               Conexant AccessRunner chipset
+ *
+ *  Copyright (C) 2004 David Woodhouse, Duncan Sands, Roman Kagan
+ *  Copyright (C) 2005 Duncan Sands, Roman Kagan (rkagan % mail ! ru)
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/*
+ *  Credit is due for Josep Comas, who created the original patch to speedtch.c
+ *  to support the different padding used by the AccessRunner (now generalized
+ *  into usbatm), and the userspace firmware loading utility.
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/kernel.h>
+#include <linux/timer.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/device.h>	/* FIXME: linux/firmware.h should include it itself */
+#include <linux/firmware.h>
+
+#include "usbatm.h"
+
+#define DRIVER_AUTHOR	"Roman Kagan, David Woodhouse, Duncan Sands"
+#define DRIVER_VERSION	"0.2"
+#define DRIVER_DESC	"Conexant AccessRunner ADSL USB modem driver"
+
+static const char cxacru_driver_name[] = "cxacru";
+
+#define CXACRU_EP_CMD		0x01	/* Bulk/interrupt in/out */
+#define CXACRU_EP_DATA		0x02	/* Bulk in/out */
+
+#define CMD_PACKET_SIZE		64	/* Should be maxpacket(ep)? */
+
+/* Addresses */
+#define PLLFCLK_ADDR	0x00350068
+#define PLLBCLK_ADDR	0x0035006c
+#define SDRAMEN_ADDR	0x00350010
+#define FW_ADDR		0x00801000
+#define BR_ADDR		0x00180600
+#define SIG_ADDR	0x00180500
+#define BR_STACK_ADDR	0x00187f10
+
+/* Values */
+#define SDRAM_ENA	0x1
+
+#define CMD_TIMEOUT	2000	/* msecs */
+#define POLL_INTERVAL	5000	/* msecs */
+
+/* commands for interaction with the modem through the control channel before
+ * firmware is loaded  */
+enum cxacru_fw_request {
+	FW_CMD_ERR,
+	FW_GET_VER,
+	FW_READ_MEM,
+	FW_WRITE_MEM,
+	FW_RMW_MEM,
+	FW_CHECKSUM_MEM,
+	FW_GOTO_MEM,
+};
+
+/* commands for interaction with the modem through the control channel once
+ * firmware is loaded  */
+enum cxacru_cm_request {
+	CM_REQUEST_UNDEFINED = 0x80,
+	CM_REQUEST_TEST,
+	CM_REQUEST_CHIP_GET_MAC_ADDRESS,
+	CM_REQUEST_CHIP_GET_DP_VERSIONS,
+	CM_REQUEST_CHIP_ADSL_LINE_START,
+	CM_REQUEST_CHIP_ADSL_LINE_STOP,
+	CM_REQUEST_CHIP_ADSL_LINE_GET_STATUS,
+	CM_REQUEST_CHIP_ADSL_LINE_GET_SPEED,
+	CM_REQUEST_CARD_INFO_GET,
+	CM_REQUEST_CARD_DATA_GET,
+	CM_REQUEST_CARD_DATA_SET,
+	CM_REQUEST_COMMAND_HW_IO,
+	CM_REQUEST_INTERFACE_HW_IO,
+	CM_REQUEST_CARD_SERIAL_DATA_PATH_GET,
+	CM_REQUEST_CARD_SERIAL_DATA_PATH_SET,
+	CM_REQUEST_CARD_CONTROLLER_VERSION_GET,
+	CM_REQUEST_CARD_GET_STATUS,
+	CM_REQUEST_CARD_GET_MAC_ADDRESS,
+	CM_REQUEST_CARD_GET_DATA_LINK_STATUS,
+	CM_REQUEST_MAX,
+};
+
+/* reply codes to the commands above */
+enum cxacru_cm_status {
+	CM_STATUS_UNDEFINED,
+	CM_STATUS_SUCCESS,
+	CM_STATUS_ERROR,
+	CM_STATUS_UNSUPPORTED,
+	CM_STATUS_UNIMPLEMENTED,
+	CM_STATUS_PARAMETER_ERROR,
+	CM_STATUS_DBG_LOOPBACK,
+	CM_STATUS_MAX,
+};
+
+/* indices into CARD_INFO_GET return array */
+enum cxacru_info_idx {
+	CXINF_DOWNSTREAM_RATE,
+	CXINF_UPSTREAM_RATE,
+	CXINF_LINK_STATUS,
+	CXINF_LINE_STATUS,
+	CXINF_MAC_ADDRESS_HIGH,
+	CXINF_MAC_ADDRESS_LOW,
+	CXINF_UPSTREAM_SNR_MARGIN,
+	CXINF_DOWNSTREAM_SNR_MARGIN,
+	CXINF_UPSTREAM_ATTENUATION,
+	CXINF_DOWNSTREAM_ATTENUATION,
+	CXINF_TRANSMITTER_POWER,
+	CXINF_UPSTREAM_BITS_PER_FRAME,
+	CXINF_DOWNSTREAM_BITS_PER_FRAME,
+	CXINF_STARTUP_ATTEMPTS,
+	CXINF_UPSTREAM_CRC_ERRORS,
+	CXINF_DOWNSTREAM_CRC_ERRORS,
+	CXINF_UPSTREAM_FEC_ERRORS,
+	CXINF_DOWNSTREAM_FEC_ERRORS,
+	CXINF_UPSTREAM_HEC_ERRORS,
+	CXINF_DOWNSTREAM_HEC_ERRORS,
+	CXINF_LINE_STARTABLE,
+	CXINF_MODULATION,
+	CXINF_ADSL_HEADEND,
+	CXINF_ADSL_HEADEND_ENVIRONMENT,
+	CXINF_CONTROLLER_VERSION,
+	/* dunno what the missing two mean */
+	CXINF_MAX = 0x1c,
+};
+
+struct cxacru_modem_type {
+	u32 pll_f_clk;
+	u32 pll_b_clk;
+	int boot_rom_patch;
+};
+
+struct cxacru_data {
+	struct usbatm_data *usbatm;
+
+	const struct cxacru_modem_type *modem_type;
+
+	int line_status;
+	struct work_struct poll_work;
+
+	/* contol handles */
+	struct semaphore cm_serialize;
+	u8 *rcv_buf;
+	u8 *snd_buf;
+	struct urb *rcv_urb;
+	struct urb *snd_urb;
+	struct completion rcv_done;
+	struct completion snd_done;
+};
+
+/* the following three functions are stolen from drivers/usb/core/message.c */
+static void cxacru_blocking_completion(struct urb *urb, struct pt_regs *regs)
+{
+	complete((struct completion *)urb->context);
+}
+
+static void cxacru_timeout_kill(unsigned long data)
+{
+	usb_unlink_urb((struct urb *) data);
+}
+
+static int cxacru_start_wait_urb(struct urb *urb, struct completion *done,
+				 int* actual_length)
+{
+	struct timer_list timer;
+	int status;
+
+	init_timer(&timer);
+	timer.expires = jiffies + msecs_to_jiffies(CMD_TIMEOUT);
+	timer.data = (unsigned long) urb;
+	timer.function = cxacru_timeout_kill;
+	add_timer(&timer);
+	wait_for_completion(done);
+	status = urb->status;
+	if (status == -ECONNRESET)
+		status = -ETIMEDOUT;
+	del_timer_sync(&timer);
+
+	if (actual_length)
+		*actual_length = urb->actual_length;
+	return status;
+}
+
+static int cxacru_cm(struct cxacru_data *instance, enum cxacru_cm_request cm,
+		     u8 *wdata, int wsize, u8 *rdata, int rsize)
+{
+	int ret, actlen;
+	int offb, offd;
+	const int stride = CMD_PACKET_SIZE - 4;
+	u8 *wbuf = instance->snd_buf;
+	u8 *rbuf = instance->rcv_buf;
+	int wbuflen = ((wsize - 1) / stride + 1) * CMD_PACKET_SIZE;
+	int rbuflen = ((rsize - 1) / stride + 1) * CMD_PACKET_SIZE;
+
+	if (wbuflen > PAGE_SIZE || rbuflen > PAGE_SIZE) {
+		dbg("too big transfer requested");
+		ret = -ENOMEM;
+		goto fail;
+	}
+
+	down(&instance->cm_serialize);
+
+	/* submit reading urb before the writing one */
+	init_completion(&instance->rcv_done);
+	ret = usb_submit_urb(instance->rcv_urb, GFP_KERNEL);
+	if (ret < 0) {
+		dbg("submitting read urb for cm %#x failed", cm);
+		ret = ret;
+		goto fail;
+	}
+
+	memset(wbuf, 0, wbuflen);
+	/* handle wsize == 0 */
+	wbuf[0] = cm;
+	for (offb = offd = 0; offd < wsize; offd += stride, offb += CMD_PACKET_SIZE) {
+		wbuf[offb] = cm;
+		memcpy(wbuf + offb + 4, wdata + offd, min_t(int, stride, wsize - offd));
+	}
+
+	instance->snd_urb->transfer_buffer_length = wbuflen;
+	init_completion(&instance->snd_done);
+	ret = usb_submit_urb(instance->snd_urb, GFP_KERNEL);
+	if (ret < 0) {
+		dbg("submitting write urb for cm %#x failed", cm);
+		ret = ret;
+		goto fail;
+	}
+
+	ret = cxacru_start_wait_urb(instance->snd_urb, &instance->snd_done, NULL);
+	if (ret < 0) {
+		dbg("sending cm %#x failed", cm);
+		ret = ret;
+		goto fail;
+	}
+
+	ret = cxacru_start_wait_urb(instance->rcv_urb, &instance->rcv_done, &actlen);
+	if (ret < 0) {
+		dbg("receiving cm %#x failed", cm);
+		ret = ret;
+		goto fail;
+	}
+	if (actlen % CMD_PACKET_SIZE || !actlen) {
+		dbg("response is not a positive multiple of %d: %#x",
+				CMD_PACKET_SIZE, actlen);
+		ret = -EIO;
+		goto fail;
+	}
+
+	/* check the return status and copy the data to the output buffer, if needed */
+	for (offb = offd = 0; offd < rsize && offb < actlen; offb += CMD_PACKET_SIZE) {
+		if (rbuf[offb] != cm) {
+			dbg("wrong cm %#x in response", rbuf[offb]);
+			ret = -EIO;
+			goto fail;
+		}
+		if (rbuf[offb + 1] != CM_STATUS_SUCCESS) {
+			dbg("response failed: %#x", rbuf[offb + 1]);
+			ret = -EIO;
+			goto fail;
+		}
+		if (offd >= rsize)
+			break;
+		memcpy(rdata + offd, rbuf + offb + 4, min_t(int, stride, rsize - offd));
+		offd += stride;
+	}
+
+	ret = offd;
+	dbg("cm %#x", cm);
+fail:
+	up(&instance->cm_serialize);
+	return ret;
+}
+
+static int cxacru_cm_get_array(struct cxacru_data *instance, enum cxacru_cm_request cm,
+			       u32 *data, int size)
+{
+	int ret, len;
+	u32 *buf;
+	int offb, offd;
+	const int stride = CMD_PACKET_SIZE / (4 * 2) - 1;
+	int buflen =  ((size - 1) / stride + 1 + size * 2) * 4;
+
+	buf = kmalloc(buflen, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+
+	ret = cxacru_cm(instance, cm, NULL, 0, (u8 *) buf, buflen);
+	if (ret < 0)
+		goto cleanup;
+
+	/* len > 0 && len % 4 == 0 guaranteed by cxacru_cm() */
+	len = ret / 4;
+	for (offb = 0; offb < len; ) {
+		int l = le32_to_cpu(buf[offb++]);
+		if (l > stride || l > (len - offb) / 2) {
+			dbg("wrong data length %#x in response", l);
+			ret = -EIO;
+			goto cleanup;
+		}
+		while (l--) {
+			offd = le32_to_cpu(buf[offb++]);
+			if (offd >= size) {
+				dbg("wrong index %#x in response", offd);
+				ret = -EIO;
+				goto cleanup;
+			}
+			data[offd] = le32_to_cpu(buf[offb++]);
+		}
+	}
+
+	ret = 0;
+
+cleanup:
+	kfree(buf);
+	return ret;
+}
+
+static int cxacru_card_status(struct cxacru_data *instance)
+{
+	int ret = cxacru_cm(instance, CM_REQUEST_CARD_GET_STATUS, NULL, 0, NULL, 0);
+	if (ret < 0) {		/* firmware not loaded */
+		dbg("cxacru_adsl_start: CARD_GET_STATUS returned %d", ret);
+		return ret;
+	}
+	return 0;
+}
+
+static void cxacru_poll_status(struct cxacru_data *instance);
+
+static int cxacru_atm_start(struct usbatm_data *usbatm_instance,
+		struct atm_dev *atm_dev)
+{
+	struct cxacru_data *instance = usbatm_instance->driver_data;
+	struct device *dev = &usbatm_instance->usb_intf->dev;
+	/*
+	struct atm_dev *atm_dev = usbatm_instance->atm_dev;
+	*/
+	int ret;
+
+	dbg("cxacru_atm_start");
+
+	/* Read MAC address */
+	ret = cxacru_cm(instance, CM_REQUEST_CARD_GET_MAC_ADDRESS, NULL, 0,
+			atm_dev->esi, sizeof(atm_dev->esi));
+	if (ret < 0) {
+		dev_err(dev, "cxacru_atm_start: CARD_GET_MAC_ADDRESS returned %d\n", ret);
+		return ret;
+	}
+
+	/* start ADSL */
+	ret = cxacru_cm(instance, CM_REQUEST_CHIP_ADSL_LINE_START, NULL, 0, NULL, 0);
+	if (ret < 0) {
+		dev_err(dev, "cxacru_atm_start: CHIP_ADSL_LINE_START returned %d\n", ret);
+		return ret;
+	}
+
+	/* Start status polling */
+	cxacru_poll_status(instance);
+	return 0;
+}
+
+static void cxacru_poll_status(struct cxacru_data *instance)
+{
+	u32 buf[CXINF_MAX] = {};
+	struct device *dev = &instance->usbatm->usb_intf->dev;
+	struct atm_dev *atm_dev = instance->usbatm->atm_dev;
+	int ret;
+
+	ret = cxacru_cm_get_array(instance, CM_REQUEST_CARD_INFO_GET, buf, CXINF_MAX);
+	if (ret < 0) {
+		dev_warn(dev, "poll status: error %d\n", ret);
+		goto reschedule;
+	}
+
+	if (instance->line_status == buf[CXINF_LINE_STATUS])
+		goto reschedule;
+
+	instance->line_status = buf[CXINF_LINE_STATUS];
+	switch (instance->line_status) {
+	case 0:
+		atm_dev->signal = ATM_PHY_SIG_LOST;
+		dev_info(dev, "ADSL line: down\n");
+		break;
+
+	case 1:
+		atm_dev->signal = ATM_PHY_SIG_LOST;
+		dev_info(dev, "ADSL line: attemtping to activate\n");
+		break;
+
+	case 2:
+		atm_dev->signal = ATM_PHY_SIG_LOST;
+		dev_info(dev, "ADSL line: training\n");
+		break;
+
+	case 3:
+		atm_dev->signal = ATM_PHY_SIG_LOST;
+		dev_info(dev, "ADSL line: channel analysis\n");
+		break;
+
+	case 4:
+		atm_dev->signal = ATM_PHY_SIG_LOST;
+		dev_info(dev, "ADSL line: exchange\n");
+		break;
+
+	case 5:
+		atm_dev->link_rate = buf[CXINF_DOWNSTREAM_RATE] * 1000 / 424;
+		atm_dev->signal = ATM_PHY_SIG_FOUND;
+
+		dev_info(dev, "ADSL line: up (%d kb/s down | %d kb/s up)\n",
+		     buf[CXINF_DOWNSTREAM_RATE], buf[CXINF_UPSTREAM_RATE]);
+		break;
+
+	case 6:
+		atm_dev->signal = ATM_PHY_SIG_LOST;
+		dev_info(dev, "ADSL line: waiting\n");
+		break;
+
+	case 7:
+		atm_dev->signal = ATM_PHY_SIG_LOST;
+		dev_info(dev, "ADSL line: initializing\n");
+		break;
+
+	default:
+		atm_dev->signal = ATM_PHY_SIG_UNKNOWN;
+		dev_info(dev, "Unknown line state %02x\n", instance->line_status);
+		break;
+	}
+reschedule:
+	schedule_delayed_work(&instance->poll_work, msecs_to_jiffies(POLL_INTERVAL));
+}
+
+static int cxacru_fw(struct usb_device *usb_dev, enum cxacru_fw_request fw,
+		     u8 code1, u8 code2, u32 addr, u8 *data, int size)
+{
+	int ret;
+	u8 *buf;
+	int offd, offb;
+	const int stride = CMD_PACKET_SIZE - 8;
+
+	buf = (u8 *) __get_free_page(GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+
+	offb = offd = 0;
+	do {
+		int l = min_t(int, stride, size - offd);
+		buf[offb++] = fw;
+		buf[offb++] = l;
+		buf[offb++] = code1;
+		buf[offb++] = code2;
+		*((u32 *) (buf + offb)) = cpu_to_le32(addr);
+		offb += 4;
+		addr += l;
+		if(l)
+			memcpy(buf + offb, data + offd, l);
+		if (l < stride)
+			memset(buf + offb + l, 0, stride - l);
+		offb += stride;
+		offd += stride;
+		if ((offb >= PAGE_SIZE) || (offd >= size)) {
+			ret = usb_bulk_msg(usb_dev, usb_sndbulkpipe(usb_dev, CXACRU_EP_CMD),
+					   buf, offb, NULL, CMD_TIMEOUT);
+			if (ret < 0) {
+				dbg("sending fw %#x failed", fw);
+				goto cleanup;
+			}
+			offb = 0;
+		}
+	} while(offd < size);
+	dbg("sent fw %#x", fw);
+
+	ret = 0;
+
+cleanup:
+	free_page((unsigned long) buf);
+	return ret;
+}
+
+static void cxacru_upload_firmware(struct cxacru_data *instance,
+				   const struct firmware *fw,
+				   const struct firmware *bp,
+				   const struct firmware *cf)
+{
+	int ret;
+	int off;
+	struct usb_device *usb_dev = instance->usbatm->usb_dev;
+	struct device *dev = &instance->usbatm->usb_intf->dev;
+	u16 signature[] = { usb_dev->descriptor.idVendor, usb_dev->descriptor.idProduct };
+	u32 val;
+
+	dbg("cxacru_upload_firmware");
+
+	/* FirmwarePllFClkValue */
+	val = cpu_to_le32(instance->modem_type->pll_f_clk);
+	ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, PLLFCLK_ADDR, (u8 *) &val, 4);
+	if (ret) {
+		dev_err(dev, "FirmwarePllFClkValue failed: %d\n", ret);
+		return;
+	}
+
+	/* FirmwarePllBClkValue */
+	val = cpu_to_le32(instance->modem_type->pll_b_clk);
+	ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, PLLBCLK_ADDR, (u8 *) &val, 4);
+	if (ret) {
+		dev_err(dev, "FirmwarePllBClkValue failed: %d\n", ret);
+		return;
+	}
+
+	/* Enable SDRAM */
+	val = cpu_to_le32(SDRAM_ENA);
+	ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, SDRAMEN_ADDR, (u8 *) &val, 4);
+	if (ret) {
+		dev_err(dev, "Enable SDRAM failed: %d\n", ret);
+		return;
+	}
+
+	/* Firmware */
+	ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, FW_ADDR, fw->data, fw->size);
+	if (ret) {
+		dev_err(dev, "Firmware upload failed: %d\n", ret);
+		return;
+	}
+
+	/* Boot ROM patch */
+	if (instance->modem_type->boot_rom_patch) {
+		ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, BR_ADDR, bp->data, bp->size);
+		if (ret) {
+			dev_err(dev, "Boot ROM patching failed: %d\n", ret);
+			return;
+		}
+	}
+
+	/* Signature */
+	ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, SIG_ADDR, (u8 *) signature, 4);
+	if (ret) {
+		dev_err(dev, "Signature storing failed: %d\n", ret);
+		return;
+	}
+
+	if (instance->modem_type->boot_rom_patch) {
+		val = cpu_to_le32(BR_ADDR);
+		ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, BR_STACK_ADDR, (u8 *) &val, 4);
+	}
+	else {
+		ret = cxacru_fw(usb_dev, FW_GOTO_MEM, 0x0, 0x0, FW_ADDR, NULL, 0);
+	}
+	if (ret) {
+		dev_err(dev, "Passing control to firmware failed: %d\n", ret);
+		return;
+	}
+
+	/* Delay to allow firmware to start up. */
+	msleep_interruptible(1000);
+
+	usb_clear_halt(usb_dev, usb_sndbulkpipe(usb_dev, CXACRU_EP_CMD));
+	usb_clear_halt(usb_dev, usb_rcvbulkpipe(usb_dev, CXACRU_EP_CMD));
+	usb_clear_halt(usb_dev, usb_sndbulkpipe(usb_dev, CXACRU_EP_DATA));
+	usb_clear_halt(usb_dev, usb_rcvbulkpipe(usb_dev, CXACRU_EP_DATA));
+
+	ret = cxacru_cm(instance, CM_REQUEST_CARD_GET_STATUS, NULL, 0, NULL, 0);
+	if (ret < 0) {
+		dev_err(dev, "modem failed to initialize: %d\n", ret);
+		return;
+	}
+
+	/* Load config data (le32), doing one packet at a time */
+	if (cf)
+		for (off = 0; off < cf->size / 4; ) {
+			u32 buf[CMD_PACKET_SIZE / 4 - 1];
+			int i, len = min_t(int, cf->size / 4 - off, CMD_PACKET_SIZE / 4 / 2 - 1);
+			buf[0] = cpu_to_le32(len);
+			for (i = 0; i < len; i++, off++) {
+				buf[i * 2 + 1] = cpu_to_le32(off);
+				memcpy(buf + i * 2 + 2, cf->data + off * 4, 4);
+			}
+			ret = cxacru_cm(instance, CM_REQUEST_CARD_DATA_SET,
+					(u8 *) buf, len, NULL, 0);
+			if (ret < 0) {
+				dev_err(dev, "load config data failed: %d\n", ret);
+				return;
+			}
+		}
+
+	msleep_interruptible(4000);
+}
+
+static int cxacru_find_firmware(struct cxacru_data *instance,
+				char* phase, const struct firmware **fw_p)
+{
+	struct device *dev = &instance->usbatm->usb_intf->dev;
+	char buf[16];
+
+	sprintf(buf, "cxacru-%s.bin", phase);
+	dbg("cxacru_find_firmware: looking for %s", buf);
+
+	if (request_firmware(fw_p, buf, dev)) {
+		dev_dbg(dev, "no stage %s firmware found\n", phase);
+		return -ENOENT;
+	}
+
+	dev_info(dev, "found firmware %s\n", buf);
+
+	return 0;
+}
+
+static int cxacru_heavy_init(struct usbatm_data *usbatm_instance,
+			     struct usb_interface *usb_intf)
+{
+	struct device *dev = &usbatm_instance->usb_intf->dev;
+	const struct firmware *fw, *bp, *cf;
+	struct cxacru_data *instance = usbatm_instance->driver_data;
+
+	int ret = cxacru_find_firmware(instance, "fw", &fw);
+	if (ret) {
+		dev_warn(dev, "firmware (cxacru-fw.bin) unavailable (hotplug misconfiguration?)\n");
+		return ret;
+	}
+
+	if (instance->modem_type->boot_rom_patch) {
+		ret = cxacru_find_firmware(instance, "bp", &bp);
+		if (ret) {
+			dev_warn(dev, "boot ROM patch (cxacru-bp.bin) unavailable (hotplug misconfiguration?)\n");
+			release_firmware(fw);
+			return ret;
+		}
+	}
+
+	if (cxacru_find_firmware(instance, "cf", &cf))		/* optional */
+		cf = NULL;
+
+	cxacru_upload_firmware(instance, fw, bp, cf);
+
+	if (cf)
+		release_firmware(cf);
+	if (instance->modem_type->boot_rom_patch)
+		release_firmware(bp);
+	release_firmware(fw);
+
+	ret = cxacru_card_status(instance);
+	if (ret)
+		dbg("modem initialisation failed");
+	else
+		dbg("done setting up the modem");
+
+	return ret;
+}
+
+static int cxacru_bind(struct usbatm_data *usbatm_instance,
+		       struct usb_interface *intf, const struct usb_device_id *id,
+		       int *need_heavy_init)
+{
+	struct cxacru_data *instance;
+	struct usb_device *usb_dev = interface_to_usbdev(intf);
+	int ret;
+
+	/* instance init */
+	instance = kmalloc(sizeof(*instance), GFP_KERNEL);
+	if (!instance) {
+		dbg("cxacru_bind: no memory for instance data");
+		return -ENOMEM;
+	}
+
+	memset(instance, 0, sizeof(*instance));
+
+	instance->usbatm = usbatm_instance;
+	instance->modem_type = (struct cxacru_modem_type *) id->driver_info;
+
+	instance->rcv_buf = (u8 *) __get_free_page(GFP_KERNEL);
+	if (!instance->rcv_buf) {
+		dbg("cxacru_bind: no memory for rcv_buf");
+		ret = -ENOMEM;
+		goto fail;
+	}
+	instance->snd_buf = (u8 *) __get_free_page(GFP_KERNEL);
+	if (!instance->snd_buf) {
+		dbg("cxacru_bind: no memory for snd_buf");
+		ret = -ENOMEM;
+		goto fail;
+	}
+	instance->rcv_urb = usb_alloc_urb(0, GFP_KERNEL);
+	if (!instance->rcv_urb) {
+		dbg("cxacru_bind: no memory for rcv_urb");
+		ret = -ENOMEM;
+		goto fail;
+	}
+	instance->snd_urb = usb_alloc_urb(0, GFP_KERNEL);
+	if (!instance->snd_urb) {
+		dbg("cxacru_bind: no memory for snd_urb");
+		ret = -ENOMEM;
+		goto fail;
+	}
+
+	usb_fill_int_urb(instance->rcv_urb,
+			usb_dev, usb_rcvintpipe(usb_dev, CXACRU_EP_CMD),
+			instance->rcv_buf, PAGE_SIZE,
+			cxacru_blocking_completion, &instance->rcv_done, 1);
+	instance->rcv_urb->transfer_flags |= URB_ASYNC_UNLINK;
+
+	usb_fill_int_urb(instance->snd_urb,
+			usb_dev, usb_sndintpipe(usb_dev, CXACRU_EP_CMD),
+			instance->snd_buf, PAGE_SIZE,
+			cxacru_blocking_completion, &instance->snd_done, 4);
+	instance->snd_urb->transfer_flags |= URB_ASYNC_UNLINK;
+
+	init_MUTEX(&instance->cm_serialize);
+
+	INIT_WORK(&instance->poll_work, (void *)cxacru_poll_status, instance);
+
+	usbatm_instance->driver_data = instance;
+
+	*need_heavy_init = cxacru_card_status(instance);
+
+	return 0;
+
+ fail:
+	free_page((unsigned long) instance->snd_buf);
+	free_page((unsigned long) instance->rcv_buf);
+	usb_free_urb(instance->snd_urb);
+	usb_free_urb(instance->rcv_urb);
+	kfree(instance);
+
+	return ret;
+}
+
+static void cxacru_unbind(struct usbatm_data *usbatm_instance,
+		struct usb_interface *intf)
+{
+	struct cxacru_data *instance = usbatm_instance->driver_data;
+
+	dbg("cxacru_unbind entered");
+
+	if (!instance) {
+		dbg("cxacru_unbind: NULL instance!");
+		return;
+	}
+
+	while (!cancel_delayed_work(&instance->poll_work))
+	       flush_scheduled_work();
+
+	usb_kill_urb(instance->snd_urb);
+	usb_kill_urb(instance->rcv_urb);
+	usb_free_urb(instance->snd_urb);
+	usb_free_urb(instance->rcv_urb);
+
+	free_page((unsigned long) instance->snd_buf);
+	free_page((unsigned long) instance->rcv_buf);
+	kfree(instance);
+
+	usbatm_instance->driver_data = NULL;
+}
+
+static const struct cxacru_modem_type cxacru_cafe = {
+	.pll_f_clk = 0x02d874df,
+	.pll_b_clk = 0x0196a51a,
+	.boot_rom_patch = 1,
+};
+
+static const struct cxacru_modem_type cxacru_cb00 = {
+	.pll_f_clk = 0x5,
+	.pll_b_clk = 0x3,
+	.boot_rom_patch = 0,
+};
+
+static const struct usb_device_id cxacru_usb_ids[] = {
+	{ /* V = Conexant			P = ADSL modem (Euphrates project)	*/
+		USB_DEVICE(0x0572, 0xcafe),	.driver_info = (unsigned long) &cxacru_cafe
+	},
+	{ /* V = Conexant			P = ADSL modem (Hasbani project)	*/
+		USB_DEVICE(0x0572, 0xcb00),	.driver_info = (unsigned long) &cxacru_cb00
+	},
+	{ /* V = Conexant			P = ADSL modem				*/
+		USB_DEVICE(0x0572, 0xcb01),	.driver_info = (unsigned long) &cxacru_cb00
+	},
+	{ /* V = Conexant			P = ADSL modem				*/
+		USB_DEVICE(0x0572, 0xcb06),	.driver_info = (unsigned long) &cxacru_cb00
+	},
+	{ /* V = Olitec				P = ADSL modem version 2		*/
+		USB_DEVICE(0x08e3, 0x0100),	.driver_info = (unsigned long) &cxacru_cafe
+	},
+	{ /* V = Olitec				P = ADSL modem version 3		*/
+		USB_DEVICE(0x08e3, 0x0102),	.driver_info = (unsigned long) &cxacru_cb00
+	},
+	{ /* V = Trust/Amigo Technology Co.	P = AMX-CA86U				*/
+		USB_DEVICE(0x0eb0, 0x3457),	.driver_info = (unsigned long) &cxacru_cafe
+	},
+	{ /* V = Zoom				P = 5510				*/
+		USB_DEVICE(0x1803, 0x5510),	.driver_info = (unsigned long) &cxacru_cb00
+	},
+	{ /* V = Draytek			P = Vigor 318				*/
+		USB_DEVICE(0x0675, 0x0200),	.driver_info = (unsigned long) &cxacru_cb00
+	},
+	{ /* V = Zyxel				P = 630-C1 aka OMNI ADSL USB (Annex A)	*/
+		USB_DEVICE(0x0586, 0x330a),	.driver_info = (unsigned long) &cxacru_cb00
+	},
+	{ /* V = Zyxel				P = 630-C3 aka OMNI ADSL USB (Annex B)	*/
+		USB_DEVICE(0x0586, 0x330b),	.driver_info = (unsigned long) &cxacru_cb00
+	},
+	{ /* V = Aethra				P = Starmodem UM1020			*/
+		USB_DEVICE(0x0659, 0x0020),	.driver_info = (unsigned long) &cxacru_cb00
+	},
+	{ /* V = Aztech Systems			P = ? AKA Pirelli AUA-010		*/
+		USB_DEVICE(0x0509, 0x0812),	.driver_info = (unsigned long) &cxacru_cb00
+	},
+	{ /* V = Netopia			P = Cayman 3341(Annex A)/3351(Annex B)	*/
+		USB_DEVICE(0x100d, 0xcb01),	.driver_info = (unsigned long) &cxacru_cb00
+	},
+	{ /* V = Netopia			P = Cayman 3342(Annex A)/3352(Annex B)	*/
+		USB_DEVICE(0x100d, 0x3342),	.driver_info = (unsigned long) &cxacru_cb00
+	},
+	{}
+};
+
+MODULE_DEVICE_TABLE(usb, cxacru_usb_ids);
+
+static struct usbatm_driver cxacru_driver = {
+	.owner		= THIS_MODULE,
+	.driver_name	= cxacru_driver_name,
+	.bind		= cxacru_bind,
+	.heavy_init	= cxacru_heavy_init,
+	.unbind		= cxacru_unbind,
+	.atm_start	= cxacru_atm_start,
+	.in		= CXACRU_EP_DATA,
+	.out		= CXACRU_EP_DATA,
+	.rx_padding	= 3,
+	.tx_padding	= 11,
+};
+
+static int cxacru_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
+{
+	return usbatm_usb_probe(intf, id, &cxacru_driver);
+}
+
+static struct usb_driver cxacru_usb_driver = {
+	.owner		= THIS_MODULE,
+	.name		= cxacru_driver_name,
+	.probe		= cxacru_usb_probe,
+	.disconnect	= usbatm_usb_disconnect,
+	.id_table	= cxacru_usb_ids
+};
+
+static int __init cxacru_init(void)
+{
+	return usb_register(&cxacru_usb_driver);
+}
+
+static void __exit cxacru_cleanup(void)
+{
+	usb_deregister(&cxacru_usb_driver);
+}
+
+module_init(cxacru_init);
+module_exit(cxacru_cleanup);
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRIVER_VERSION);
diff --git a/drivers/usb/atm/speedtch.c b/drivers/usb/atm/speedtch.c
--- a/drivers/usb/atm/speedtch.c
+++ b/drivers/usb/atm/speedtch.c
@@ -5,6 +5,8 @@
  *  Copyright (C) 2003, Duncan Sands
  *  Copyright (C) 2004, David Woodhouse
  *
+ *  Based on "modem_run.c", copyright (C) 2001, Benoit Papillault
+ *
  *  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)
@@ -21,467 +23,191 @@
  *
  ******************************************************************************/
 
-#include <linux/module.h>
-#include <linux/moduleparam.h>
+#include <asm/page.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/firmware.h>
 #include <linux/gfp.h>
+#include <linux/init.h>
 #include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/timer.h>
-#include <linux/errno.h>
-#include <linux/proc_fs.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
 #include <linux/slab.h>
-#include <linux/wait.h>
-#include <linux/list.h>
-#include <asm/processor.h>
-#include <asm/uaccess.h>
-#include <linux/smp_lock.h>
-#include <linux/interrupt.h>
-#include <linux/atm.h>
-#include <linux/atmdev.h>
-#include <linux/crc32.h>
-#include <linux/init.h>
-#include <linux/firmware.h>
-
-#include "usb_atm.h"
+#include <linux/stat.h>
+#include <linux/timer.h>
+#include <linux/workqueue.h>
 
-#if defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE)
-#	define USE_FW_LOADER
-#endif
+#include "usbatm.h"
 
 #define DRIVER_AUTHOR	"Johan Verrept, Duncan Sands <duncan.sands@free.fr>"
-#define DRIVER_VERSION	"1.8"
+#define DRIVER_VERSION	"1.9"
 #define DRIVER_DESC	"Alcatel SpeedTouch USB driver version " DRIVER_VERSION
 
 static const char speedtch_driver_name[] = "speedtch";
 
-#define SPEEDTOUCH_VENDORID		0x06b9
-#define SPEEDTOUCH_PRODUCTID		0x4061
+#define CTRL_TIMEOUT 2000	/* milliseconds */
+#define DATA_TIMEOUT 2000	/* milliseconds */
 
-/* Timeout in jiffies */
-#define CTRL_TIMEOUT 2000
-#define DATA_TIMEOUT 2000
-
-#define OFFSET_7  0		/* size 1 */
-#define OFFSET_b  1		/* size 8 */
-#define OFFSET_d  9		/* size 4 */
-#define OFFSET_e 13		/* size 1 */
-#define OFFSET_f 14		/* size 1 */
-#define TOTAL    15
-
-#define SIZE_7 1
-#define SIZE_b 8
-#define SIZE_d 4
-#define SIZE_e 1
-#define SIZE_f 1
-
-static int dl_512_first = 0;
-static int sw_buffering = 0;
-
-module_param(dl_512_first, bool, 0444);
-MODULE_PARM_DESC(dl_512_first, "Read 512 bytes before sending firmware");
-
-module_param(sw_buffering, uint, 0444);
-MODULE_PARM_DESC(sw_buffering, "Enable software buffering");
-
-#define UDSL_IOCTL_LINE_UP		1
-#define UDSL_IOCTL_LINE_DOWN		2
-
-#define SPEEDTCH_ENDPOINT_INT		0x81
-#define SPEEDTCH_ENDPOINT_DATA		0x07
-#define SPEEDTCH_ENDPOINT_FIRMWARE	0x05
+#define OFFSET_7	0		/* size 1 */
+#define OFFSET_b	1		/* size 8 */
+#define OFFSET_d	9		/* size 4 */
+#define OFFSET_e	13		/* size 1 */
+#define OFFSET_f	14		/* size 1 */
+#define TOTAL		15
+
+#define SIZE_7		1
+#define SIZE_b		8
+#define SIZE_d		4
+#define SIZE_e		1
+#define SIZE_f		1
+
+#define MIN_POLL_DELAY		5000	/* milliseconds */
+#define MAX_POLL_DELAY		60000	/* milliseconds */
+
+#define RESUBMIT_DELAY		1000	/* milliseconds */
+
+#define DEFAULT_ALTSETTING	1
+#define DEFAULT_DL_512_FIRST	0
+#define DEFAULT_SW_BUFFERING	0
+
+static int altsetting = DEFAULT_ALTSETTING;
+static int dl_512_first = DEFAULT_DL_512_FIRST;
+static int sw_buffering = DEFAULT_SW_BUFFERING;
+
+module_param(altsetting, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(altsetting,
+		 "Alternative setting for data interface (default: "
+		 __MODULE_STRING(DEFAULT_ALTSETTING) ")");
+
+module_param(dl_512_first, bool, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(dl_512_first,
+		 "Read 512 bytes before sending firmware (default: "
+		 __MODULE_STRING(DEFAULT_DL_512_FIRST) ")");
+
+module_param(sw_buffering, bool, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(sw_buffering,
+		 "Enable software buffering (default: "
+		 __MODULE_STRING(DEFAULT_SW_BUFFERING) ")");
+
+#define ENDPOINT_INT		0x81
+#define ENDPOINT_DATA		0x07
+#define ENDPOINT_FIRMWARE	0x05
 
 #define hex2int(c) ( (c >= '0') && (c <= '9') ? (c - '0') : ((c & 0xf) + 9) )
 
-static struct usb_device_id speedtch_usb_ids[] = {
-	{USB_DEVICE(SPEEDTOUCH_VENDORID, SPEEDTOUCH_PRODUCTID)},
-	{}
-};
+struct speedtch_instance_data {
+	struct usbatm_data *usbatm;
 
-MODULE_DEVICE_TABLE(usb, speedtch_usb_ids);
+	struct work_struct status_checker;
 
-struct speedtch_instance_data {
-	struct udsl_instance_data u;
+	unsigned char last_status;
+
+	int poll_delay; /* milliseconds */
 
-	/* Status */
+	struct timer_list resubmit_timer;
 	struct urb *int_urb;
 	unsigned char int_data[16];
-	struct work_struct poll_work;
-	struct timer_list poll_timer;
-};
-/* USB */
-
-static int speedtch_usb_probe(struct usb_interface *intf,
-			      const struct usb_device_id *id);
-static void speedtch_usb_disconnect(struct usb_interface *intf);
-static int speedtch_usb_ioctl(struct usb_interface *intf, unsigned int code,
-			      void *user_data);
-static void speedtch_handle_int(struct urb *urb, struct pt_regs *regs);
-static void speedtch_poll_status(struct speedtch_instance_data *instance);
 
-static struct usb_driver speedtch_usb_driver = {
-	.owner		= THIS_MODULE,
-	.name		= speedtch_driver_name,
-	.probe		= speedtch_usb_probe,
-	.disconnect	= speedtch_usb_disconnect,
-	.ioctl		= speedtch_usb_ioctl,
-	.id_table	= speedtch_usb_ids,
+	unsigned char scratch_buffer[TOTAL];
 };
 
 /***************
 **  firmware  **
 ***************/
 
-static void speedtch_got_firmware(struct speedtch_instance_data *instance,
-				  int got_it)
-{
-	int err;
-	struct usb_interface *intf;
-
-	down(&instance->u.serialize);	/* vs self, speedtch_firmware_start */
-	if (instance->u.status == UDSL_LOADED_FIRMWARE)
-		goto out;
-	if (!got_it) {
-		instance->u.status = UDSL_NO_FIRMWARE;
-		goto out;
-	}
-	if ((err = usb_set_interface(instance->u.usb_dev, 1, 1)) < 0) {
-		dbg("speedtch_got_firmware: usb_set_interface returned %d!", err);
-		instance->u.status = UDSL_NO_FIRMWARE;
-		goto out;
-	}
-
-	/* Set up interrupt endpoint */
-	intf = usb_ifnum_to_if(instance->u.usb_dev, 0);
-	if (intf && !usb_driver_claim_interface(&speedtch_usb_driver, intf, NULL)) {
-
-		instance->int_urb = usb_alloc_urb(0, GFP_KERNEL);
-		if (instance->int_urb) {
-
-			usb_fill_int_urb(instance->int_urb, instance->u.usb_dev,
-					 usb_rcvintpipe(instance->u.usb_dev, SPEEDTCH_ENDPOINT_INT),
-					 instance->int_data,
-					 sizeof(instance->int_data),
-					 speedtch_handle_int, instance, 50);
-			err = usb_submit_urb(instance->int_urb, GFP_KERNEL);
-			if (err) {
-				/* Doesn't matter; we'll poll anyway */
-				dbg("speedtch_got_firmware: Submission of interrupt URB failed %d", err);
-				usb_free_urb(instance->int_urb);
-				instance->int_urb = NULL;
-				usb_driver_release_interface(&speedtch_usb_driver, intf);
-			}
-		}
-	}
-	/* Start status polling */
-	mod_timer(&instance->poll_timer, jiffies + (1 * HZ));
-
-	instance->u.status = UDSL_LOADED_FIRMWARE;
-	tasklet_schedule(&instance->u.receive_tasklet);
- out:
-	up(&instance->u.serialize);
-	wake_up_interruptible(&instance->u.firmware_waiters);
-}
-
-static int speedtch_set_swbuff(struct speedtch_instance_data *instance,
-			       int state)
+static void speedtch_set_swbuff(struct speedtch_instance_data *instance, int state)
 {
-	struct usb_device *dev = instance->u.usb_dev;
+	struct usbatm_data *usbatm = instance->usbatm;
+	struct usb_device *usb_dev = usbatm->usb_dev;
 	int ret;
 
-	ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
-			      0x32, 0x40, state ? 0x01 : 0x00,
-			      0x00, NULL, 0, 100);
-	if (ret < 0) {
-		printk("Warning: %sabling SW buffering: usb_control_msg returned %d\n",
-		     state ? "En" : "Dis", ret);
-		return ret;
-	}
-
-	dbg("speedtch_set_swbuff: %sbled SW buffering", state ? "En" : "Dis");
-	return 0;
+	ret = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0),
+			      0x32, 0x40, state ? 0x01 : 0x00, 0x00, NULL, 0, CTRL_TIMEOUT);
+	if (ret < 0)
+		usb_warn(usbatm,
+			 "%sabling SW buffering: usb_control_msg returned %d\n",
+			 state ? "En" : "Dis", ret);
+	else
+		dbg("speedtch_set_swbuff: %sbled SW buffering", state ? "En" : "Dis");
 }
 
 static void speedtch_test_sequence(struct speedtch_instance_data *instance)
 {
-	struct usb_device *dev = instance->u.usb_dev;
-	unsigned char buf[10];
+	struct usbatm_data *usbatm = instance->usbatm;
+	struct usb_device *usb_dev = usbatm->usb_dev;
+	unsigned char *buf = instance->scratch_buffer;
 	int ret;
 
 	/* URB 147 */
 	buf[0] = 0x1c;
 	buf[1] = 0x50;
-	ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
-			      0x01, 0x40, 0x0b, 0x00, buf, 2, 100);
+	ret = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0),
+			      0x01, 0x40, 0x0b, 0x00, buf, 2, CTRL_TIMEOUT);
 	if (ret < 0)
-		printk(KERN_WARNING "%s failed on URB147: %d\n", __func__, ret);
+		usb_warn(usbatm, "%s failed on URB147: %d\n", __func__, ret);
 
 	/* URB 148 */
 	buf[0] = 0x32;
 	buf[1] = 0x00;
-	ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
-			      0x01, 0x40, 0x02, 0x00, buf, 2, 100);
+	ret = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0),
+			      0x01, 0x40, 0x02, 0x00, buf, 2, CTRL_TIMEOUT);
 	if (ret < 0)
-		printk(KERN_WARNING "%s failed on URB148: %d\n", __func__, ret);
+		usb_warn(usbatm, "%s failed on URB148: %d\n", __func__, ret);
 
 	/* URB 149 */
 	buf[0] = 0x01;
 	buf[1] = 0x00;
 	buf[2] = 0x01;
-	ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
-			      0x01, 0x40, 0x03, 0x00, buf, 3, 100);
+	ret = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0),
+			      0x01, 0x40, 0x03, 0x00, buf, 3, CTRL_TIMEOUT);
 	if (ret < 0)
-		printk(KERN_WARNING "%s failed on URB149: %d\n", __func__, ret);
+		usb_warn(usbatm, "%s failed on URB149: %d\n", __func__, ret);
 
 	/* URB 150 */
 	buf[0] = 0x01;
 	buf[1] = 0x00;
 	buf[2] = 0x01;
-	ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
-			      0x01, 0x40, 0x04, 0x00, buf, 3, 100);
+	ret = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0),
+			      0x01, 0x40, 0x04, 0x00, buf, 3, CTRL_TIMEOUT);
 	if (ret < 0)
-		printk(KERN_WARNING "%s failed on URB150: %d\n", __func__, ret);
-}
-
-static int speedtch_start_synchro(struct speedtch_instance_data *instance)
-{
-	struct usb_device *dev = instance->u.usb_dev;
-	unsigned char buf[2];
-	int ret;
-
-	ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
-			      0x12, 0xc0, 0x04, 0x00,
-			      buf, sizeof(buf), CTRL_TIMEOUT);
-	if (ret < 0) {
-		printk(KERN_WARNING "SpeedTouch: Failed to start ADSL synchronisation: %d\n", ret);
-		return ret;
-	}
-
-	dbg("speedtch_start_synchro: modem prodded. %d Bytes returned: %02x %02x", ret, buf[0], buf[1]);
-	return 0;
-}
-
-static void speedtch_handle_int(struct urb *urb, struct pt_regs *regs)
-{
-	struct speedtch_instance_data *instance = urb->context;
-	unsigned int count = urb->actual_length;
-	int ret;
-
-	/* The magic interrupt for "up state" */
-	const static unsigned char up_int[6]   = { 0xa1, 0x00, 0x01, 0x00, 0x00, 0x00 };
-	/* The magic interrupt for "down state" */
-	const static unsigned char down_int[6] = { 0xa1, 0x00, 0x00, 0x00, 0x00, 0x00 };
-
-	switch (urb->status) {
-	case 0:
-		/* success */
-		break;
-	case -ECONNRESET:
-	case -ENOENT:
-	case -ESHUTDOWN:
-		/* this urb is terminated; clean up */
-		dbg("%s - urb shutting down with status: %d", __func__, urb->status);
-		return;
-	default:
-		dbg("%s - nonzero urb status received: %d", __func__, urb->status);
-		goto exit;
-	}
-
-	if (count < 6) {
-		dbg("%s - int packet too short", __func__);
-		goto exit;
-	}
-
-	if (!memcmp(up_int, instance->int_data, 6)) {
-		del_timer(&instance->poll_timer);
-		printk(KERN_NOTICE "DSL line goes up\n");
-	} else if (!memcmp(down_int, instance->int_data, 6)) {
-		printk(KERN_NOTICE "DSL line goes down\n");
-	} else {
-		int i;
-
-		printk(KERN_DEBUG "Unknown interrupt packet of %d bytes:", count);
-		for (i = 0; i < count; i++)
-			printk(" %02x", instance->int_data[i]);
-		printk("\n");
-	}
-	schedule_work(&instance->poll_work);
-
- exit:
-	rmb();
-	if (!instance->int_urb)
-		return;
-
-	ret = usb_submit_urb(urb, GFP_ATOMIC);
-	if (ret)
-		err("%s - usb_submit_urb failed with result %d", __func__, ret);
+		usb_warn(usbatm, "%s failed on URB150: %d\n", __func__, ret);
 }
 
-static int speedtch_get_status(struct speedtch_instance_data *instance,
-			       unsigned char *buf)
-{
-	struct usb_device *dev = instance->u.usb_dev;
-	int ret;
-
-	memset(buf, 0, TOTAL);
-
-	ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
-			      0x12, 0xc0, 0x07, 0x00, buf + OFFSET_7, SIZE_7,
-			      CTRL_TIMEOUT);
-	if (ret < 0) {
-		dbg("MSG 7 failed");
-		return ret;
-	}
-
-	ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
-			      0x12, 0xc0, 0x0b, 0x00, buf + OFFSET_b, SIZE_b,
-			      CTRL_TIMEOUT);
-	if (ret < 0) {
-		dbg("MSG B failed");
-		return ret;
-	}
-
-	ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
-			      0x12, 0xc0, 0x0d, 0x00, buf + OFFSET_d, SIZE_d,
-			      CTRL_TIMEOUT);
-	if (ret < 0) {
-		dbg("MSG D failed");
-		return ret;
-	}
-
-	ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
-			      0x01, 0xc0, 0x0e, 0x00, buf + OFFSET_e, SIZE_e,
-			      CTRL_TIMEOUT);
-	if (ret < 0) {
-		dbg("MSG E failed");
-		return ret;
-	}
-
-	ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
-			      0x01, 0xc0, 0x0f, 0x00, buf + OFFSET_f, SIZE_f,
-			      CTRL_TIMEOUT);
-	if (ret < 0) {
-		dbg("MSG F failed");
-		return ret;
-	}
-
-	return 0;
-}
-
-static void speedtch_poll_status(struct speedtch_instance_data *instance)
-{
-	unsigned char buf[TOTAL];
-	int ret;
-
-	ret = speedtch_get_status(instance, buf);
-	if (ret) {
-		printk(KERN_WARNING
-		       "SpeedTouch: Error %d fetching device status\n", ret);
-		return;
-	}
-
-	dbg("Line state %02x", buf[OFFSET_7]);
-
-	switch (buf[OFFSET_7]) {
-	case 0:
-		if (instance->u.atm_dev->signal != ATM_PHY_SIG_LOST) {
-			instance->u.atm_dev->signal = ATM_PHY_SIG_LOST;
-			printk(KERN_NOTICE "ADSL line is down\n");
-			/* It'll never resync again unless we ask it to... */
-			speedtch_start_synchro(instance);
-		}
-		break;
-
-	case 0x08:
-		if (instance->u.atm_dev->signal != ATM_PHY_SIG_UNKNOWN) {
-			instance->u.atm_dev->signal = ATM_PHY_SIG_UNKNOWN;
-			printk(KERN_NOTICE "ADSL line is blocked?\n");
-		}
-		break;
-
-	case 0x10:
-		if (instance->u.atm_dev->signal != ATM_PHY_SIG_LOST) {
-			instance->u.atm_dev->signal = ATM_PHY_SIG_LOST;
-			printk(KERN_NOTICE "ADSL line is synchronising\n");
-		}
-		break;
-
-	case 0x20:
-		if (instance->u.atm_dev->signal != ATM_PHY_SIG_FOUND) {
-			int down_speed = buf[OFFSET_b] | (buf[OFFSET_b + 1] << 8)
-				| (buf[OFFSET_b + 2] << 16) | (buf[OFFSET_b + 3] << 24);
-			int up_speed = buf[OFFSET_b + 4] | (buf[OFFSET_b + 5] << 8)
-				| (buf[OFFSET_b + 6] << 16) | (buf[OFFSET_b + 7] << 24);
-
-			if (!(down_speed & 0x0000ffff) &&
-			    !(up_speed & 0x0000ffff)) {
-				down_speed >>= 16;
-				up_speed >>= 16;
-			}
-			instance->u.atm_dev->link_rate = down_speed * 1000 / 424;
-			instance->u.atm_dev->signal = ATM_PHY_SIG_FOUND;
-
-			printk(KERN_NOTICE
-			       "ADSL line is up (%d Kib/s down | %d Kib/s up)\n",
-			       down_speed, up_speed);
-		}
-		break;
-
-	default:
-		if (instance->u.atm_dev->signal != ATM_PHY_SIG_UNKNOWN) {
-			instance->u.atm_dev->signal = ATM_PHY_SIG_UNKNOWN;
-			printk(KERN_NOTICE "Unknown line state %02x\n", buf[OFFSET_7]);
-		}
-		break;
-	}
-}
-
-static void speedtch_timer_poll(unsigned long data)
-{
-	struct speedtch_instance_data *instance = (void *)data;
-
-	schedule_work(&instance->poll_work);
-	mod_timer(&instance->poll_timer, jiffies + (5 * HZ));
-}
-
-#ifdef USE_FW_LOADER
-static void speedtch_upload_firmware(struct speedtch_instance_data *instance,
+static int speedtch_upload_firmware(struct speedtch_instance_data *instance,
 				     const struct firmware *fw1,
 				     const struct firmware *fw2)
 {
 	unsigned char *buffer;
-	struct usb_device *usb_dev = instance->u.usb_dev;
+	struct usbatm_data *usbatm = instance->usbatm;
 	struct usb_interface *intf;
-	int actual_length, ret;
+	struct usb_device *usb_dev = usbatm->usb_dev;
+	int actual_length;
+	int ret = 0;
 	int offset;
 
-	dbg("speedtch_upload_firmware");
-
-	if (!(intf = usb_ifnum_to_if(usb_dev, 2))) {
-		dbg("speedtch_upload_firmware: interface not found!");
-		goto fail;
-	}
+	usb_dbg(usbatm, "%s entered\n", __func__);
 
 	if (!(buffer = (unsigned char *)__get_free_page(GFP_KERNEL))) {
-		dbg("speedtch_upload_firmware: no memory for buffer!");
-		goto fail;
+		ret = -ENOMEM;
+		usb_dbg(usbatm, "%s: no memory for buffer!\n", __func__);
+		goto out;
 	}
 
-	/* A user-space firmware loader may already have claimed interface #2 */
-	if ((ret =
-	     usb_driver_claim_interface(&speedtch_usb_driver, intf, NULL)) < 0) {
-		dbg("speedtch_upload_firmware: interface in use (%d)!", ret);
-		goto fail_free;
+	if (!(intf = usb_ifnum_to_if(usb_dev, 2))) {
+		ret = -ENODEV;
+		usb_dbg(usbatm, "%s: interface not found!\n", __func__);
+		goto out_free;
 	}
 
 	/* URB 7 */
 	if (dl_512_first) {	/* some modems need a read before writing the firmware */
-		ret = usb_bulk_msg(usb_dev, usb_rcvbulkpipe(usb_dev, SPEEDTCH_ENDPOINT_FIRMWARE),
+		ret = usb_bulk_msg(usb_dev, usb_rcvbulkpipe(usb_dev, ENDPOINT_FIRMWARE),
 				   buffer, 0x200, &actual_length, 2000);
 
 		if (ret < 0 && ret != -ETIMEDOUT)
-			dbg("speedtch_upload_firmware: read BLOCK0 from modem failed (%d)!", ret);
+			usb_dbg(usbatm, "%s: read BLOCK0 from modem failed (%d)!\n", __func__, ret);
 		else
-			dbg("speedtch_upload_firmware: BLOCK0 downloaded (%d bytes)", ret);
+			usb_dbg(usbatm, "%s: BLOCK0 downloaded (%d bytes)\n", __func__, ret);
 	}
 
 	/* URB 8 : both leds are static green */
@@ -489,60 +215,60 @@ static void speedtch_upload_firmware(str
 		int thislen = min_t(int, PAGE_SIZE, fw1->size - offset);
 		memcpy(buffer, fw1->data + offset, thislen);
 
-		ret = usb_bulk_msg(usb_dev, usb_sndbulkpipe(usb_dev, SPEEDTCH_ENDPOINT_FIRMWARE),
+		ret = usb_bulk_msg(usb_dev, usb_sndbulkpipe(usb_dev, ENDPOINT_FIRMWARE),
 				   buffer, thislen, &actual_length, DATA_TIMEOUT);
 
 		if (ret < 0) {
-			dbg("speedtch_upload_firmware: write BLOCK1 to modem failed (%d)!", ret);
-			goto fail_release;
+			usb_dbg(usbatm, "%s: write BLOCK1 to modem failed (%d)!\n", __func__, ret);
+			goto out_free;
 		}
-		dbg("speedtch_upload_firmware: BLOCK1 uploaded (%zu bytes)", fw1->size);
+		usb_dbg(usbatm, "%s: BLOCK1 uploaded (%zu bytes)\n", __func__, fw1->size);
 	}
 
 	/* USB led blinking green, ADSL led off */
 
 	/* URB 11 */
-	ret = usb_bulk_msg(usb_dev, usb_rcvbulkpipe(usb_dev, SPEEDTCH_ENDPOINT_FIRMWARE),
+	ret = usb_bulk_msg(usb_dev, usb_rcvbulkpipe(usb_dev, ENDPOINT_FIRMWARE),
 			   buffer, 0x200, &actual_length, DATA_TIMEOUT);
 
 	if (ret < 0) {
-		dbg("speedtch_upload_firmware: read BLOCK2 from modem failed (%d)!", ret);
-		goto fail_release;
+		usb_dbg(usbatm, "%s: read BLOCK2 from modem failed (%d)!\n", __func__, ret);
+		goto out_free;
 	}
-	dbg("speedtch_upload_firmware: BLOCK2 downloaded (%d bytes)", actual_length);
+	usb_dbg(usbatm, "%s: BLOCK2 downloaded (%d bytes)\n", __func__, actual_length);
 
 	/* URBs 12 to 139 - USB led blinking green, ADSL led off */
 	for (offset = 0; offset < fw2->size; offset += PAGE_SIZE) {
 		int thislen = min_t(int, PAGE_SIZE, fw2->size - offset);
 		memcpy(buffer, fw2->data + offset, thislen);
 
-		ret = usb_bulk_msg(usb_dev, usb_sndbulkpipe(usb_dev, SPEEDTCH_ENDPOINT_FIRMWARE),
+		ret = usb_bulk_msg(usb_dev, usb_sndbulkpipe(usb_dev, ENDPOINT_FIRMWARE),
 				   buffer, thislen, &actual_length, DATA_TIMEOUT);
 
 		if (ret < 0) {
-			dbg("speedtch_upload_firmware: write BLOCK3 to modem failed (%d)!", ret);
-			goto fail_release;
+			usb_dbg(usbatm, "%s: write BLOCK3 to modem failed (%d)!\n", __func__, ret);
+			goto out_free;
 		}
 	}
-	dbg("speedtch_upload_firmware: BLOCK3 uploaded (%zu bytes)", fw2->size);
+	usb_dbg(usbatm, "%s: BLOCK3 uploaded (%zu bytes)\n", __func__, fw2->size);
 
 	/* USB led static green, ADSL led static red */
 
 	/* URB 142 */
-	ret = usb_bulk_msg(usb_dev, usb_rcvbulkpipe(usb_dev, SPEEDTCH_ENDPOINT_FIRMWARE),
+	ret = usb_bulk_msg(usb_dev, usb_rcvbulkpipe(usb_dev, ENDPOINT_FIRMWARE),
 			   buffer, 0x200, &actual_length, DATA_TIMEOUT);
 
 	if (ret < 0) {
-		dbg("speedtch_upload_firmware: read BLOCK4 from modem failed (%d)!", ret);
-		goto fail_release;
+		usb_dbg(usbatm, "%s: read BLOCK4 from modem failed (%d)!\n", __func__, ret);
+		goto out_free;
 	}
 
 	/* success */
-	dbg("speedtch_upload_firmware: BLOCK4 downloaded (%d bytes)", actual_length);
+	usb_dbg(usbatm, "%s: BLOCK4 downloaded (%d bytes)\n", __func__, actual_length);
 
 	/* Delay to allow firmware to start up. We can do this here
 	   because we're in our own kernel thread anyway. */
-	msleep(1000);
+	msleep_interruptible(1000);
 
 	/* Enable software buffering, if requested */
 	if (sw_buffering)
@@ -551,291 +277,543 @@ static void speedtch_upload_firmware(str
 	/* Magic spell; don't ask us what this does */
 	speedtch_test_sequence(instance);
 
-	/* Start modem synchronisation */
-	if (speedtch_start_synchro(instance))
-		dbg("speedtch_start_synchro: failed");
-
-	speedtch_got_firmware(instance, 1);
-
-	free_page((unsigned long)buffer);
-	return;
+	ret = 0;
 
- fail_release:
-	/* Only release interface #2 if uploading failed; we don't release it
-	   we succeeded.  This prevents the userspace tools from trying to load
-	   the firmware themselves */
-	usb_driver_release_interface(&speedtch_usb_driver, intf);
- fail_free:
+out_free:
 	free_page((unsigned long)buffer);
- fail:
-	speedtch_got_firmware(instance, 0);
+out:
+	return ret;
 }
 
-static int speedtch_find_firmware(struct speedtch_instance_data
-				  *instance, int phase,
+static int speedtch_find_firmware(struct usb_interface *intf, int phase,
 				  const struct firmware **fw_p)
 {
-	char buf[24];
-	const u16 bcdDevice = le16_to_cpu(instance->u.usb_dev->descriptor.bcdDevice);
+	struct device *dev = &intf->dev;
+	const u16 bcdDevice = le16_to_cpu(interface_to_usbdev(intf)->descriptor.bcdDevice);
 	const u8 major_revision = bcdDevice >> 8;
 	const u8 minor_revision = bcdDevice & 0xff;
+	char buf[24];
 
 	sprintf(buf, "speedtch-%d.bin.%x.%02x", phase, major_revision, minor_revision);
-	dbg("speedtch_find_firmware: looking for %s", buf);
+	dev_dbg(dev, "%s: looking for %s\n", __func__, buf);
 
-	if (request_firmware(fw_p, buf, &instance->u.usb_dev->dev)) {
+	if (request_firmware(fw_p, buf, dev)) {
 		sprintf(buf, "speedtch-%d.bin.%x", phase, major_revision);
-		dbg("speedtch_find_firmware: looking for %s", buf);
+		dev_dbg(dev, "%s: looking for %s\n", __func__, buf);
 
-		if (request_firmware(fw_p, buf, &instance->u.usb_dev->dev)) {
+		if (request_firmware(fw_p, buf, dev)) {
 			sprintf(buf, "speedtch-%d.bin", phase);
-			dbg("speedtch_find_firmware: looking for %s", buf);
+			dev_dbg(dev, "%s: looking for %s\n", __func__, buf);
 
-			if (request_firmware(fw_p, buf, &instance->u.usb_dev->dev)) {
-				dev_warn(&instance->u.usb_dev->dev, "no stage %d firmware found!", phase);
+			if (request_firmware(fw_p, buf, dev)) {
+				dev_warn(dev, "no stage %d firmware found!\n", phase);
 				return -ENOENT;
 			}
 		}
 	}
 
-	dev_info(&instance->u.usb_dev->dev, "found stage %d firmware %s\n", phase, buf);
+	dev_info(dev, "found stage %d firmware %s\n", phase, buf);
 
 	return 0;
 }
 
-static int speedtch_load_firmware(void *arg)
+static int speedtch_heavy_init(struct usbatm_data *usbatm, struct usb_interface *intf)
 {
 	const struct firmware *fw1, *fw2;
-	struct speedtch_instance_data *instance = arg;
-
-	BUG_ON(!instance);
+	struct speedtch_instance_data *instance = usbatm->driver_data;
+	int ret;
 
-	daemonize("firmware/speedtch");
+	if ((ret = speedtch_find_firmware(intf, 1, &fw1)) < 0)
+			return ret;
 
-	if (!speedtch_find_firmware(instance, 1, &fw1)) {
-		if (!speedtch_find_firmware(instance, 2, &fw2)) {
-			speedtch_upload_firmware(instance, fw1, fw2);
-			release_firmware(fw2);
-		}
+	if ((ret = speedtch_find_firmware(intf, 2, &fw2)) < 0) {
 		release_firmware(fw1);
+		return ret;
 	}
 
-	/* In case we failed, set state back to NO_FIRMWARE so that
-	   another later attempt may work. Otherwise, we never actually
-	   manage to recover if, for example, the firmware is on /usr and
-	   we look for it too early. */
-	speedtch_got_firmware(instance, 0);
+	ret = speedtch_upload_firmware(instance, fw1, fw2);
 
-	module_put(THIS_MODULE);
-	udsl_put_instance(&instance->u);
-	return 0;
+	release_firmware(fw2);
+	release_firmware(fw1);
+
+	return ret;
 }
-#endif /* USE_FW_LOADER */
 
-static void speedtch_firmware_start(struct speedtch_instance_data *instance)
+
+/**********
+**  ATM  **
+**********/
+
+static int speedtch_read_status(struct speedtch_instance_data *instance)
 {
-#ifdef USE_FW_LOADER
+	struct usbatm_data *usbatm = instance->usbatm;
+	struct usb_device *usb_dev = usbatm->usb_dev;
+	unsigned char *buf = instance->scratch_buffer;
 	int ret;
-#endif
 
-	dbg("speedtch_firmware_start");
+	memset(buf, 0, TOTAL);
 
-	down(&instance->u.serialize);	/* vs self, speedtch_got_firmware */
+	ret = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0),
+			      0x12, 0xc0, 0x07, 0x00, buf + OFFSET_7, SIZE_7,
+			      CTRL_TIMEOUT);
+	if (ret < 0) {
+		atm_dbg(usbatm, "%s: MSG 7 failed\n", __func__);
+		return ret;
+	}
 
-	if (instance->u.status >= UDSL_LOADING_FIRMWARE) {
-		up(&instance->u.serialize);
-		return;
+	ret = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0),
+			      0x12, 0xc0, 0x0b, 0x00, buf + OFFSET_b, SIZE_b,
+			      CTRL_TIMEOUT);
+	if (ret < 0) {
+		atm_dbg(usbatm, "%s: MSG B failed\n", __func__);
+		return ret;
 	}
 
-	instance->u.status = UDSL_LOADING_FIRMWARE;
-	up(&instance->u.serialize);
+	ret = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0),
+			      0x12, 0xc0, 0x0d, 0x00, buf + OFFSET_d, SIZE_d,
+			      CTRL_TIMEOUT);
+	if (ret < 0) {
+		atm_dbg(usbatm, "%s: MSG D failed\n", __func__);
+		return ret;
+	}
 
-#ifdef USE_FW_LOADER
-	udsl_get_instance(&instance->u);
-	try_module_get(THIS_MODULE);
+	ret = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0),
+			      0x01, 0xc0, 0x0e, 0x00, buf + OFFSET_e, SIZE_e,
+			      CTRL_TIMEOUT);
+	if (ret < 0) {
+		atm_dbg(usbatm, "%s: MSG E failed\n", __func__);
+		return ret;
+	}
 
-	ret = kernel_thread(speedtch_load_firmware, instance,
-			    CLONE_FS | CLONE_FILES);
+	ret = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0),
+			      0x01, 0xc0, 0x0f, 0x00, buf + OFFSET_f, SIZE_f,
+			      CTRL_TIMEOUT);
+	if (ret < 0) {
+		atm_dbg(usbatm, "%s: MSG F failed\n", __func__);
+		return ret;
+	}
 
-	if (ret >= 0)
-		return;		/* OK */
+	return 0;
+}
 
-	dbg("speedtch_firmware_start: kernel_thread failed (%d)!", ret);
+static int speedtch_start_synchro(struct speedtch_instance_data *instance)
+{
+	struct usbatm_data *usbatm = instance->usbatm;
+	struct usb_device *usb_dev = usbatm->usb_dev;
+	unsigned char *buf = instance->scratch_buffer;
+	int ret;
 
-	module_put(THIS_MODULE);
-	udsl_put_instance(&instance->u);
-	/* Just pretend it never happened... hope modem_run happens */
-#endif				/* USE_FW_LOADER */
+	atm_dbg(usbatm, "%s entered\n", __func__);
 
-	speedtch_got_firmware(instance, 0);
-}
+	memset(buf, 0, 2);
 
-static int speedtch_firmware_wait(struct udsl_instance_data *instance)
-{
-	speedtch_firmware_start((void *)instance);
+	ret = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0),
+			      0x12, 0xc0, 0x04, 0x00,
+			      buf, 2, CTRL_TIMEOUT);
 
-	if (wait_event_interruptible(instance->firmware_waiters, instance->status != UDSL_LOADING_FIRMWARE) < 0)
-		return -ERESTARTSYS;
+	if (ret < 0)
+		atm_warn(usbatm, "failed to start ADSL synchronisation: %d\n", ret);
+	else
+		atm_dbg(usbatm, "%s: modem prodded. %d bytes returned: %02x %02x\n",
+			__func__, ret, buf[0], buf[1]);
 
-	return (instance->status == UDSL_LOADED_FIRMWARE) ? 0 : -EAGAIN;
+	return ret;
 }
 
-/**********
-**  USB  **
-**********/
-
-static int speedtch_usb_ioctl(struct usb_interface *intf, unsigned int code,
-			      void *user_data)
+static void speedtch_check_status(struct speedtch_instance_data *instance)
 {
-	struct speedtch_instance_data *instance = usb_get_intfdata(intf);
+	struct usbatm_data *usbatm = instance->usbatm;
+	struct atm_dev *atm_dev = usbatm->atm_dev;
+	unsigned char *buf = instance->scratch_buffer;
+	int down_speed, up_speed, ret;
+	unsigned char status;
 
-	dbg("speedtch_usb_ioctl entered");
+	atm_dbg(usbatm, "%s entered\n", __func__);
 
-	if (!instance) {
-		dbg("speedtch_usb_ioctl: NULL instance!");
-		return -ENODEV;
+	ret = speedtch_read_status(instance);
+	if (ret < 0) {
+		atm_warn(usbatm, "error %d fetching device status\n", ret);
+		instance->poll_delay = min(2 * instance->poll_delay, MAX_POLL_DELAY);
+		return;
 	}
 
-	switch (code) {
-	case UDSL_IOCTL_LINE_UP:
-		instance->u.atm_dev->signal = ATM_PHY_SIG_FOUND;
-		speedtch_got_firmware(instance, 1);
-		return (instance->u.status == UDSL_LOADED_FIRMWARE) ? 0 : -EIO;
-	case UDSL_IOCTL_LINE_DOWN:
-		instance->u.atm_dev->signal = ATM_PHY_SIG_LOST;
-		return 0;
-	default:
-		return -ENOTTY;
+	instance->poll_delay = max(instance->poll_delay / 2, MIN_POLL_DELAY);
+
+	status = buf[OFFSET_7];
+
+	atm_dbg(usbatm, "%s: line state %02x\n", __func__, status);
+
+	if ((status != instance->last_status) || !status) {
+		switch (status) {
+		case 0:
+			atm_dev->signal = ATM_PHY_SIG_LOST;
+			if (instance->last_status)
+				atm_info(usbatm, "ADSL line is down\n");
+			/* It may never resync again unless we ask it to... */
+			ret = speedtch_start_synchro(instance);
+			break;
+
+		case 0x08:
+			atm_dev->signal = ATM_PHY_SIG_UNKNOWN;
+			atm_info(usbatm, "ADSL line is blocked?\n");
+			break;
+
+		case 0x10:
+			atm_dev->signal = ATM_PHY_SIG_LOST;
+			atm_info(usbatm, "ADSL line is synchronising\n");
+			break;
+
+		case 0x20:
+			down_speed = buf[OFFSET_b] | (buf[OFFSET_b + 1] << 8)
+				| (buf[OFFSET_b + 2] << 16) | (buf[OFFSET_b + 3] << 24);
+			up_speed = buf[OFFSET_b + 4] | (buf[OFFSET_b + 5] << 8)
+				| (buf[OFFSET_b + 6] << 16) | (buf[OFFSET_b + 7] << 24);
+
+			if (!(down_speed & 0x0000ffff) && !(up_speed & 0x0000ffff)) {
+				down_speed >>= 16;
+				up_speed >>= 16;
+			}
+
+			atm_dev->link_rate = down_speed * 1000 / 424;
+			atm_dev->signal = ATM_PHY_SIG_FOUND;
+
+			atm_info(usbatm,
+				 "ADSL line is up (%d kb/s down | %d kb/s up)\n",
+				 down_speed, up_speed);
+			break;
+
+		default:
+			atm_dev->signal = ATM_PHY_SIG_UNKNOWN;
+			atm_info(usbatm, "Unknown line state %02x\n", status);
+			break;
+		}
+
+		instance->last_status = status;
 	}
 }
 
-static int speedtch_usb_probe(struct usb_interface *intf,
-			      const struct usb_device_id *id)
+static void speedtch_status_poll(unsigned long data)
 {
-	struct usb_device *dev = interface_to_usbdev(intf);
-	int ifnum = intf->altsetting->desc.bInterfaceNumber;
-	struct speedtch_instance_data *instance;
-	unsigned char mac_str[13];
-	int ret, i;
-	char buf7[SIZE_7];
+	struct speedtch_instance_data *instance = (void *)data;
 
-	dbg("speedtch_usb_probe: trying device with vendor=0x%x, product=0x%x, ifnum %d",
-	    le16_to_cpu(dev->descriptor.idVendor),
-	    le16_to_cpu(dev->descriptor.idProduct), ifnum);
+	schedule_work(&instance->status_checker);
 
-	if ((dev->descriptor.bDeviceClass != USB_CLASS_VENDOR_SPEC) || 
-	    (ifnum != 1))
-		return -ENODEV;
+	/* The following check is racy, but the race is harmless */
+	if (instance->poll_delay < MAX_POLL_DELAY)
+		mod_timer(&instance->status_checker.timer, jiffies + msecs_to_jiffies(instance->poll_delay));
+	else
+		atm_warn(instance->usbatm, "Too many failures - disabling line status polling\n");
+}
 
-	dbg("speedtch_usb_probe: device accepted");
+static void speedtch_resubmit_int(unsigned long data)
+{
+	struct speedtch_instance_data *instance = (void *)data;
+	struct urb *int_urb = instance->int_urb;
+	int ret;
 
-	/* instance init */
-	instance = kmalloc(sizeof(*instance), GFP_KERNEL);
-	if (!instance) {
-		dbg("speedtch_usb_probe: no memory for instance data!");
-		return -ENOMEM;
+	atm_dbg(instance->usbatm, "%s entered\n", __func__);
+
+	if (int_urb) {
+		ret = usb_submit_urb(int_urb, GFP_ATOMIC);
+		if (!ret)
+			schedule_work(&instance->status_checker);
+		else {
+			atm_dbg(instance->usbatm, "%s: usb_submit_urb failed with result %d\n", __func__, ret);
+			mod_timer(&instance->resubmit_timer, jiffies + msecs_to_jiffies(RESUBMIT_DELAY));
+		}
 	}
+}
 
-	memset(instance, 0, sizeof(struct speedtch_instance_data));
+static void speedtch_handle_int(struct urb *int_urb, struct pt_regs *regs)
+{
+	struct speedtch_instance_data *instance = int_urb->context;
+	struct usbatm_data *usbatm = instance->usbatm;
+	unsigned int count = int_urb->actual_length;
+	int ret = int_urb->status;
 
-	if ((ret = usb_set_interface(dev, 0, 0)) < 0)
-		goto fail;
+	/* The magic interrupt for "up state" */
+	const static unsigned char up_int[6]   = { 0xa1, 0x00, 0x01, 0x00, 0x00, 0x00 };
+	/* The magic interrupt for "down state" */
+	const static unsigned char down_int[6] = { 0xa1, 0x00, 0x00, 0x00, 0x00, 0x00 };
+
+	atm_dbg(usbatm, "%s entered\n", __func__);
 
-	if ((ret = usb_set_interface(dev, 2, 0)) < 0)
+	if (ret < 0) {
+		atm_dbg(usbatm, "%s: nonzero urb status %d!\n", __func__, ret);
 		goto fail;
+	}
 
-	instance->u.data_endpoint = SPEEDTCH_ENDPOINT_DATA;
-	instance->u.firmware_wait = speedtch_firmware_wait;
-	instance->u.driver_name = speedtch_driver_name;
+	if ((count == 6) && !memcmp(up_int, instance->int_data, 6)) {
+		del_timer(&instance->status_checker.timer);
+		atm_info(usbatm, "DSL line goes up\n");
+	} else if ((count == 6) && !memcmp(down_int, instance->int_data, 6)) {
+		atm_info(usbatm, "DSL line goes down\n");
+	} else {
+		int i;
 
-	ret = udsl_instance_setup(dev, &instance->u);
-	if (ret)
+		atm_dbg(usbatm, "%s: unknown interrupt packet of length %d:", __func__, count);
+		for (i = 0; i < count; i++)
+			printk(" %02x", instance->int_data[i]);
+		printk("\n");
 		goto fail;
+	}
+
+	if ((int_urb = instance->int_urb)) {
+		ret = usb_submit_urb(int_urb, GFP_ATOMIC);
+		schedule_work(&instance->status_checker);
+		if (ret < 0) {
+			atm_dbg(usbatm, "%s: usb_submit_urb failed with result %d\n", __func__, ret);
+			goto fail;
+		}
+	}
 
-	init_timer(&instance->poll_timer);
-	instance->poll_timer.function = speedtch_timer_poll;
-	instance->poll_timer.data = (unsigned long)instance;
-
-	INIT_WORK(&instance->poll_work, (void *)speedtch_poll_status, instance);
-
-	/* set MAC address, it is stored in the serial number */
-	memset(instance->u.atm_dev->esi, 0, sizeof(instance->u.atm_dev->esi));
-	if (usb_string(dev, dev->descriptor.iSerialNumber, mac_str, sizeof(mac_str)) == 12) {
+	return;
+
+fail:
+	if ((int_urb = instance->int_urb))
+		mod_timer(&instance->resubmit_timer, jiffies + msecs_to_jiffies(RESUBMIT_DELAY));
+}
+
+static int speedtch_atm_start(struct usbatm_data *usbatm, struct atm_dev *atm_dev)
+{
+	struct usb_device *usb_dev = usbatm->usb_dev;
+	struct speedtch_instance_data *instance = usbatm->driver_data;
+	int i, ret;
+	unsigned char mac_str[13];
+
+	atm_dbg(usbatm, "%s entered\n", __func__);
+
+	if ((ret = usb_set_interface(usb_dev, 1, altsetting)) < 0) {
+		atm_dbg(usbatm, "%s: usb_set_interface returned %d!\n", __func__, ret);
+		return ret;
+	}
+
+	/* Set MAC address, it is stored in the serial number */
+	memset(atm_dev->esi, 0, sizeof(atm_dev->esi));
+	if (usb_string(usb_dev, usb_dev->descriptor.iSerialNumber, mac_str, sizeof(mac_str)) == 12) {
 		for (i = 0; i < 6; i++)
-			instance->u.atm_dev->esi[i] =
-				(hex2int(mac_str[i * 2]) * 16) + (hex2int(mac_str[i * 2 + 1]));
+			atm_dev->esi[i] = (hex2int(mac_str[i * 2]) * 16) + (hex2int(mac_str[i * 2 + 1]));
 	}
 
-	/* First check whether the modem already seems to be alive */
-	ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
-			      0x12, 0xc0, 0x07, 0x00, buf7, SIZE_7, 500);
-
-	if (ret == SIZE_7) {
-		dbg("firmware appears to be already loaded");
-		speedtch_got_firmware(instance, 1);
-		speedtch_poll_status(instance);
-	} else {
-		speedtch_firmware_start(instance);
+	/* Start modem synchronisation */
+	ret = speedtch_start_synchro(instance);
+
+	/* Set up interrupt endpoint */
+	if (instance->int_urb) {
+		ret = usb_submit_urb(instance->int_urb, GFP_KERNEL);
+		if (ret < 0) {
+			/* Doesn't matter; we'll poll anyway */
+			atm_dbg(usbatm, "%s: submission of interrupt URB failed (%d)!\n", __func__, ret);
+			usb_free_urb(instance->int_urb);
+			instance->int_urb = NULL;
+		}
 	}
 
-	usb_set_intfdata(intf, instance);
+	/* Start status polling */
+	mod_timer(&instance->status_checker.timer, jiffies + msecs_to_jiffies(1000));
 
 	return 0;
+}
 
- fail:
-	kfree(instance);
+static void speedtch_atm_stop(struct usbatm_data *usbatm, struct atm_dev *atm_dev)
+{
+	struct speedtch_instance_data *instance = usbatm->driver_data;
+	struct urb *int_urb = instance->int_urb;
+
+	atm_dbg(usbatm, "%s entered\n", __func__);
 
-	return -ENOMEM;
+	del_timer_sync(&instance->status_checker.timer);
+
+	/*
+	 * Since resubmit_timer and int_urb can schedule themselves and
+	 * each other, shutting them down correctly takes some care
+	 */
+	instance->int_urb = NULL; /* signal shutdown */
+	mb();
+	usb_kill_urb(int_urb);
+	del_timer_sync(&instance->resubmit_timer);
+	/*
+	 * At this point, speedtch_handle_int and speedtch_resubmit_int
+	 * can run or be running, but instance->int_urb == NULL means that
+	 * they will not reschedule
+	 */
+	usb_kill_urb(int_urb);
+	del_timer_sync(&instance->resubmit_timer);
+	usb_free_urb(int_urb);
+
+	flush_scheduled_work();
 }
 
-static void speedtch_usb_disconnect(struct usb_interface *intf)
+
+/**********
+**  USB  **
+**********/
+
+static struct usb_device_id speedtch_usb_ids[] = {
+	{USB_DEVICE(0x06b9, 0x4061)},
+	{}
+};
+
+MODULE_DEVICE_TABLE(usb, speedtch_usb_ids);
+
+static int speedtch_usb_probe(struct usb_interface *, const struct usb_device_id *);
+
+static struct usb_driver speedtch_usb_driver = {
+	.owner		= THIS_MODULE,
+	.name		= speedtch_driver_name,
+	.probe		= speedtch_usb_probe,
+	.disconnect	= usbatm_usb_disconnect,
+	.id_table	= speedtch_usb_ids
+};
+
+static void speedtch_release_interfaces(struct usb_device *usb_dev, int num_interfaces) {
+	struct usb_interface *cur_intf;
+	int i;
+
+	for(i = 0; i < num_interfaces; i++)
+		if ((cur_intf = usb_ifnum_to_if(usb_dev, i))) {
+			usb_set_intfdata(cur_intf, NULL);
+			usb_driver_release_interface(&speedtch_usb_driver, cur_intf);
+		}
+}
+
+static int speedtch_bind(struct usbatm_data *usbatm,
+			 struct usb_interface *intf,
+			 const struct usb_device_id *id,
+			 int *need_heavy_init)
 {
-	struct speedtch_instance_data *instance = usb_get_intfdata(intf);
+	struct usb_device *usb_dev = interface_to_usbdev(intf);
+	struct usb_interface *cur_intf;
+	struct speedtch_instance_data *instance;
+	int ifnum = intf->altsetting->desc.bInterfaceNumber;
+	int num_interfaces = usb_dev->actconfig->desc.bNumInterfaces;
+	int i, ret;
 
-	dbg("speedtch_usb_disconnect entered");
+	usb_dbg(usbatm, "%s entered\n", __func__);
 
-	if (!instance) {
-		dbg("speedtch_usb_disconnect: NULL instance!");
-		return;
+	if (usb_dev->descriptor.bDeviceClass != USB_CLASS_VENDOR_SPEC) {
+		usb_dbg(usbatm, "%s: wrong device class %d\n", __func__, usb_dev->descriptor.bDeviceClass);
+		return -ENODEV;
 	}
 
-/*QQ need to handle disconnects on interface #2 while uploading firmware */
-/*QQ and what about interface #1? */
+	/* claim all interfaces */
 
-	if (instance->int_urb) {
-		struct urb *int_urb = instance->int_urb;
-		instance->int_urb = NULL;
-		wmb();
-		usb_unlink_urb(int_urb);
-		usb_free_urb(int_urb);
+	for (i=0; i < num_interfaces; i++) {
+		cur_intf = usb_ifnum_to_if(usb_dev, i);
+
+		if ((i != ifnum) && cur_intf) {
+			ret = usb_driver_claim_interface(&speedtch_usb_driver, cur_intf, usbatm);
+
+			if (ret < 0) {
+				usb_dbg(usbatm, "%s: failed to claim interface %d (%d)\n", __func__, i, ret);
+				speedtch_release_interfaces(usb_dev, i);
+				return ret;
+			}
+		}
 	}
 
-	instance->int_data[0] = 1;
-	del_timer_sync(&instance->poll_timer);
-	wmb();
-	flush_scheduled_work();
+	instance = kmalloc(sizeof(*instance), GFP_KERNEL);
+
+	if (!instance) {
+		usb_dbg(usbatm, "%s: no memory for instance data!\n", __func__);
+		ret = -ENOMEM;
+		goto fail_release;
+	}
+
+	memset(instance, 0, sizeof(struct speedtch_instance_data));
+
+	instance->usbatm = usbatm;
+
+	INIT_WORK(&instance->status_checker, (void *)speedtch_check_status, instance);
+
+	instance->status_checker.timer.function = speedtch_status_poll;
+	instance->status_checker.timer.data = (unsigned long)instance;
+	instance->last_status = 0xff;
+	instance->poll_delay = MIN_POLL_DELAY;
+
+	init_timer(&instance->resubmit_timer);
+	instance->resubmit_timer.function = speedtch_resubmit_int;
+	instance->resubmit_timer.data = (unsigned long)instance;
 
-	udsl_instance_disconnect(&instance->u);
+	instance->int_urb = usb_alloc_urb(0, GFP_KERNEL);
 
-	/* clean up */
-	usb_set_intfdata(intf, NULL);
-	udsl_put_instance(&instance->u);
+	if (instance->int_urb)
+		usb_fill_int_urb(instance->int_urb, usb_dev,
+				 usb_rcvintpipe(usb_dev, ENDPOINT_INT),
+				 instance->int_data, sizeof(instance->int_data),
+				 speedtch_handle_int, instance, 50);
+	else
+		usb_dbg(usbatm, "%s: no memory for interrupt urb!\n", __func__);
+
+	/* check whether the modem already seems to be alive */
+	ret = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0),
+			      0x12, 0xc0, 0x07, 0x00,
+			      instance->scratch_buffer + OFFSET_7, SIZE_7, 500);
+
+	*need_heavy_init = (ret != SIZE_7);
+
+	usb_dbg(usbatm, "%s: firmware %s loaded\n", __func__, need_heavy_init ? "not" : "already");
+
+	if (*need_heavy_init)
+		if ((ret = usb_reset_device(usb_dev)) < 0)
+			goto fail_free;
+
+        usbatm->driver_data = instance;
+
+	return 0;
+
+fail_free:
+	usb_free_urb(instance->int_urb);
+	kfree(instance);
+fail_release:
+	speedtch_release_interfaces(usb_dev, num_interfaces);
+	return ret;
+}
+
+static void speedtch_unbind(struct usbatm_data *usbatm, struct usb_interface *intf)
+{
+	struct usb_device *usb_dev = interface_to_usbdev(intf);
+	struct speedtch_instance_data *instance = usbatm->driver_data;
+
+	usb_dbg(usbatm, "%s entered\n", __func__);
+
+	speedtch_release_interfaces(usb_dev, usb_dev->actconfig->desc.bNumInterfaces);
+	usb_free_urb(instance->int_urb);
+	kfree(instance);
 }
 
+
 /***********
 **  init  **
 ***********/
 
+static struct usbatm_driver speedtch_usbatm_driver = {
+	.owner		= THIS_MODULE,
+	.driver_name	= speedtch_driver_name,
+	.bind		= speedtch_bind,
+	.heavy_init	= speedtch_heavy_init,
+	.unbind		= speedtch_unbind,
+	.atm_start	= speedtch_atm_start,
+	.atm_stop	= speedtch_atm_stop,
+	.in		= ENDPOINT_DATA,
+	.out		= ENDPOINT_DATA
+};
+
+static int speedtch_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
+{
+	return usbatm_usb_probe(intf, id, &speedtch_usbatm_driver);
+}
+
 static int __init speedtch_usb_init(void)
 {
-	dbg("speedtch_usb_init: driver version " DRIVER_VERSION);
+	dbg("%s: driver version %s", __func__, DRIVER_VERSION);
 
 	return usb_register(&speedtch_usb_driver);
 }
 
 static void __exit speedtch_usb_cleanup(void)
 {
-	dbg("speedtch_usb_cleanup entered");
+	dbg("%s", __func__);
 
 	usb_deregister(&speedtch_usb_driver);
 }
diff --git a/drivers/usb/atm/usb_atm.c b/drivers/usb/atm/usb_atm.c
deleted file mode 100644
--- a/drivers/usb/atm/usb_atm.c
+++ /dev/null
@@ -1,1188 +0,0 @@
-/******************************************************************************
- *  usb_atm.c - Generic USB xDSL driver core
- *
- *  Copyright (C) 2001, Alcatel
- *  Copyright (C) 2003, Duncan Sands, SolNegro, Josep Comas
- *  Copyright (C) 2004, David Woodhouse
- *
- *  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.
- *
- ******************************************************************************/
-
-/*
- *  Written by Johan Verrept, maintained by Duncan Sands (duncan.sands@free.fr)
- *
- *  1.7+:	- See the check-in logs
- *
- *  1.6:	- No longer opens a connection if the firmware is not loaded
- *  		- Added support for the speedtouch 330
- *  		- Removed the limit on the number of devices
- *  		- Module now autoloads on device plugin
- *  		- Merged relevant parts of sarlib
- *  		- Replaced the kernel thread with a tasklet
- *  		- New packet transmission code
- *  		- Changed proc file contents
- *  		- Fixed all known SMP races
- *  		- Many fixes and cleanups
- *  		- Various fixes by Oliver Neukum (oliver@neukum.name)
- *
- *  1.5A:	- Version for inclusion in 2.5 series kernel
- *		- Modifications by Richard Purdie (rpurdie@rpsys.net)
- *		- made compatible with kernel 2.5.6 onwards by changing
- *		udsl_usb_send_data_context->urb to a pointer and adding code
- *		to alloc and free it
- *		- remove_wait_queue() added to udsl_atm_processqueue_thread()
- *
- *  1.5:	- fixed memory leak when atmsar_decode_aal5 returned NULL.
- *		(reported by stephen.robinson@zen.co.uk)
- *
- *  1.4:	- changed the spin_lock() under interrupt to spin_lock_irqsave()
- *		- unlink all active send urbs of a vcc that is being closed.
- *
- *  1.3.1:	- added the version number
- *
- *  1.3:	- Added multiple send urb support
- *		- fixed memory leak and vcc->tx_inuse starvation bug
- *		  when not enough memory left in vcc.
- *
- *  1.2:	- Fixed race condition in udsl_usb_send_data()
- *  1.1:	- Turned off packet debugging
- *
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/timer.h>
-#include <linux/errno.h>
-#include <linux/proc_fs.h>
-#include <linux/slab.h>
-#include <linux/wait.h>
-#include <linux/list.h>
-#include <asm/uaccess.h>
-#include <linux/smp_lock.h>
-#include <linux/interrupt.h>
-#include <linux/atm.h>
-#include <linux/atmdev.h>
-#include <linux/crc32.h>
-#include <linux/init.h>
-#include <linux/firmware.h>
-
-#include "usb_atm.h"
-
-#ifdef VERBOSE_DEBUG
-static int udsl_print_packet(const unsigned char *data, int len);
-#define PACKETDEBUG(arg...)	udsl_print_packet (arg)
-#define vdbg(arg...)		dbg (arg)
-#else
-#define PACKETDEBUG(arg...)
-#define vdbg(arg...)
-#endif
-
-#define DRIVER_AUTHOR	"Johan Verrept, Duncan Sands <duncan.sands@free.fr>"
-#define DRIVER_VERSION	"1.8"
-#define DRIVER_DESC	"Generic USB ATM/DSL I/O, version " DRIVER_VERSION
-
-static unsigned int num_rcv_urbs = UDSL_DEFAULT_RCV_URBS;
-static unsigned int num_snd_urbs = UDSL_DEFAULT_SND_URBS;
-static unsigned int num_rcv_bufs = UDSL_DEFAULT_RCV_BUFS;
-static unsigned int num_snd_bufs = UDSL_DEFAULT_SND_BUFS;
-static unsigned int rcv_buf_size = UDSL_DEFAULT_RCV_BUF_SIZE;
-static unsigned int snd_buf_size = UDSL_DEFAULT_SND_BUF_SIZE;
-
-module_param(num_rcv_urbs, uint, 0444);
-MODULE_PARM_DESC(num_rcv_urbs,
-		 "Number of urbs used for reception (range: 0-"
-		 __MODULE_STRING(UDSL_MAX_RCV_URBS) ", default: "
-		 __MODULE_STRING(UDSL_DEFAULT_RCV_URBS) ")");
-
-module_param(num_snd_urbs, uint, 0444);
-MODULE_PARM_DESC(num_snd_urbs,
-		 "Number of urbs used for transmission (range: 0-"
-		 __MODULE_STRING(UDSL_MAX_SND_URBS) ", default: "
-		 __MODULE_STRING(UDSL_DEFAULT_SND_URBS) ")");
-
-module_param(num_rcv_bufs, uint, 0444);
-MODULE_PARM_DESC(num_rcv_bufs,
-		 "Number of buffers used for reception (range: 0-"
-		 __MODULE_STRING(UDSL_MAX_RCV_BUFS) ", default: "
-		 __MODULE_STRING(UDSL_DEFAULT_RCV_BUFS) ")");
-
-module_param(num_snd_bufs, uint, 0444);
-MODULE_PARM_DESC(num_snd_bufs,
-		 "Number of buffers used for transmission (range: 0-"
-		 __MODULE_STRING(UDSL_MAX_SND_BUFS) ", default: "
-		 __MODULE_STRING(UDSL_DEFAULT_SND_BUFS) ")");
-
-module_param(rcv_buf_size, uint, 0444);
-MODULE_PARM_DESC(rcv_buf_size,
-		 "Size of the buffers used for reception (range: 0-"
-		 __MODULE_STRING(UDSL_MAX_RCV_BUF_SIZE) ", default: "
-		 __MODULE_STRING(UDSL_DEFAULT_RCV_BUF_SIZE) ")");
-
-module_param(snd_buf_size, uint, 0444);
-MODULE_PARM_DESC(snd_buf_size,
-		 "Size of the buffers used for transmission (range: 0-"
-		 __MODULE_STRING(UDSL_MAX_SND_BUF_SIZE) ", default: "
-		 __MODULE_STRING(UDSL_DEFAULT_SND_BUF_SIZE) ")");
-
-/* ATM */
-
-static void udsl_atm_dev_close(struct atm_dev *dev);
-static int udsl_atm_open(struct atm_vcc *vcc);
-static void udsl_atm_close(struct atm_vcc *vcc);
-static int udsl_atm_ioctl(struct atm_dev *dev, unsigned int cmd, void __user * arg);
-static int udsl_atm_send(struct atm_vcc *vcc, struct sk_buff *skb);
-static int udsl_atm_proc_read(struct atm_dev *atm_dev, loff_t * pos, char *page);
-
-static struct atmdev_ops udsl_atm_devops = {
-	.dev_close	= udsl_atm_dev_close,
-	.open		= udsl_atm_open,
-	.close		= udsl_atm_close,
-	.ioctl		= udsl_atm_ioctl,
-	.send		= udsl_atm_send,
-	.proc_read	= udsl_atm_proc_read,
-	.owner		= THIS_MODULE,
-};
-
-/***********
-**  misc  **
-***********/
-
-static inline void udsl_pop(struct atm_vcc *vcc, struct sk_buff *skb)
-{
-	if (vcc->pop)
-		vcc->pop(vcc, skb);
-	else
-		dev_kfree_skb(skb);
-}
-
-/*************
-**  decode  **
-*************/
-
-static inline struct udsl_vcc_data *udsl_find_vcc(struct udsl_instance_data *instance,
-						  short vpi, int vci)
-{
-	struct udsl_vcc_data *vcc;
-
-	list_for_each_entry(vcc, &instance->vcc_list, list)
-		if ((vcc->vci == vci) && (vcc->vpi == vpi))
-			return vcc;
-	return NULL;
-}
-
-static void udsl_extract_cells(struct udsl_instance_data *instance,
-			       unsigned char *source, unsigned int howmany)
-{
-	struct udsl_vcc_data *cached_vcc = NULL;
-	struct atm_vcc *vcc;
-	struct sk_buff *sarb;
-	struct udsl_vcc_data *vcc_data;
-	int cached_vci = 0;
-	unsigned int i;
-	int pti;
-	int vci;
-	short cached_vpi = 0;
-	short vpi;
-
-	for (i = 0; i < howmany;
-	     i++, source += ATM_CELL_SIZE + instance->rcv_padding) {
-		vpi = ((source[0] & 0x0f) << 4) | (source[1] >> 4);
-		vci = ((source[1] & 0x0f) << 12) | (source[2] << 4) | (source[3] >> 4);
-		pti = (source[3] & 0x2) != 0;
-
-		vdbg("udsl_extract_cells: vpi %hd, vci %d, pti %d", vpi, vci, pti);
-
-		if (cached_vcc && (vci == cached_vci) && (vpi == cached_vpi))
-			vcc_data = cached_vcc;
-		else if ((vcc_data = udsl_find_vcc(instance, vpi, vci))) {
-			cached_vcc = vcc_data;
-			cached_vpi = vpi;
-			cached_vci = vci;
-		} else {
-			dbg("udsl_extract_cells: unknown vpi/vci (%hd/%d)!", vpi, vci);
-			continue;
-		}
-
-		vcc = vcc_data->vcc;
-		sarb = vcc_data->sarb;
-
-		if (sarb->tail + ATM_CELL_PAYLOAD > sarb->end) {
-			dbg("udsl_extract_cells: buffer overrun (sarb->len %u, vcc: 0x%p)!", sarb->len, vcc);
-			/* discard cells already received */
-			skb_trim(sarb, 0);
-		}
-
-		memcpy(sarb->tail, source + ATM_CELL_HEADER, ATM_CELL_PAYLOAD);
-		__skb_put(sarb, ATM_CELL_PAYLOAD);
-
-		if (pti) {
-			struct sk_buff *skb;
-			unsigned int length;
-			unsigned int pdu_length;
-
-			length = (source[ATM_CELL_SIZE - 6] << 8) + source[ATM_CELL_SIZE - 5];
-
-			/* guard against overflow */
-			if (length > ATM_MAX_AAL5_PDU) {
-				dbg("udsl_extract_cells: bogus length %u (vcc: 0x%p)!", length, vcc);
-				atomic_inc(&vcc->stats->rx_err);
-				goto out;
-			}
-
-			pdu_length = UDSL_NUM_CELLS(length) * ATM_CELL_PAYLOAD;
-
-			if (sarb->len < pdu_length) {
-				dbg("udsl_extract_cells: bogus pdu_length %u (sarb->len: %u, vcc: 0x%p)!", pdu_length, sarb->len, vcc);
-				atomic_inc(&vcc->stats->rx_err);
-				goto out;
-			}
-
-			if (crc32_be(~0, sarb->tail - pdu_length, pdu_length) != 0xc704dd7b) {
-				dbg("udsl_extract_cells: packet failed crc check (vcc: 0x%p)!", vcc);
-				atomic_inc(&vcc->stats->rx_err);
-				goto out;
-			}
-
-			vdbg("udsl_extract_cells: got packet (length: %u, pdu_length: %u, vcc: 0x%p)", length, pdu_length, vcc);
-
-			if (!(skb = dev_alloc_skb(length))) {
-				dbg("udsl_extract_cells: no memory for skb (length: %u)!", length);
-				atomic_inc(&vcc->stats->rx_drop);
-				goto out;
-			}
-
-			vdbg("udsl_extract_cells: allocated new sk_buff (skb: 0x%p, skb->truesize: %u)", skb, skb->truesize);
-
-			if (!atm_charge(vcc, skb->truesize)) {
-				dbg("udsl_extract_cells: failed atm_charge (skb->truesize: %u)!", skb->truesize);
-				dev_kfree_skb(skb);
-				goto out;	/* atm_charge increments rx_drop */
-			}
-
-			memcpy(skb->data, sarb->tail - pdu_length, length);
-			__skb_put(skb, length);
-
-			vdbg("udsl_extract_cells: sending skb 0x%p, skb->len %u, skb->truesize %u", skb, skb->len, skb->truesize);
-
-			PACKETDEBUG(skb->data, skb->len);
-
-			vcc->push(vcc, skb);
-
-			atomic_inc(&vcc->stats->rx);
-		out:
-			skb_trim(sarb, 0);
-		}
-	}
-}
-
-/*************
-**  encode  **
-*************/
-
-static inline void udsl_fill_cell_header(unsigned char *target, struct atm_vcc *vcc)
-{
-	target[0] = vcc->vpi >> 4;
-	target[1] = (vcc->vpi << 4) | (vcc->vci >> 12);
-	target[2] = vcc->vci >> 4;
-	target[3] = vcc->vci << 4;
-	target[4] = 0xec;
-}
-
-static const unsigned char zeros[ATM_CELL_PAYLOAD];
-
-static void udsl_groom_skb(struct atm_vcc *vcc, struct sk_buff *skb)
-{
-	struct udsl_control *ctrl = UDSL_SKB(skb);
-	unsigned int zero_padding;
-	u32 crc;
-
-	ctrl->atm_data.vcc = vcc;
-
-	ctrl->num_cells = UDSL_NUM_CELLS(skb->len);
-	ctrl->num_entire = skb->len / ATM_CELL_PAYLOAD;
-
-	zero_padding = ctrl->num_cells * ATM_CELL_PAYLOAD - skb->len - ATM_AAL5_TRAILER;
-
-	if (ctrl->num_entire + 1 < ctrl->num_cells)
-		ctrl->pdu_padding = zero_padding - (ATM_CELL_PAYLOAD - ATM_AAL5_TRAILER);
-	else
-		ctrl->pdu_padding = zero_padding;
-
-	ctrl->aal5_trailer[0] = 0;	/* UU = 0 */
-	ctrl->aal5_trailer[1] = 0;	/* CPI = 0 */
-	ctrl->aal5_trailer[2] = skb->len >> 8;
-	ctrl->aal5_trailer[3] = skb->len;
-
-	crc = crc32_be(~0, skb->data, skb->len);
-	crc = crc32_be(crc, zeros, zero_padding);
-	crc = crc32_be(crc, ctrl->aal5_trailer, 4);
-	crc = ~crc;
-
-	ctrl->aal5_trailer[4] = crc >> 24;
-	ctrl->aal5_trailer[5] = crc >> 16;
-	ctrl->aal5_trailer[6] = crc >> 8;
-	ctrl->aal5_trailer[7] = crc;
-}
-
-static unsigned int udsl_write_cells(struct udsl_instance_data *instance,
-				     unsigned int howmany, struct sk_buff *skb,
-				     unsigned char **target_p)
-{
-	struct udsl_control *ctrl = UDSL_SKB(skb);
-	unsigned char *target = *target_p;
-	unsigned int nc, ne, i;
-
-	vdbg("udsl_write_cells: howmany=%u, skb->len=%d, num_cells=%u, num_entire=%u, pdu_padding=%u", howmany, skb->len, ctrl->num_cells, ctrl->num_entire, ctrl->pdu_padding);
-
-	nc = ctrl->num_cells;
-	ne = min(howmany, ctrl->num_entire);
-
-	for (i = 0; i < ne; i++) {
-		udsl_fill_cell_header(target, ctrl->atm_data.vcc);
-		target += ATM_CELL_HEADER;
-		memcpy(target, skb->data, ATM_CELL_PAYLOAD);
-		target += ATM_CELL_PAYLOAD;
-		if (instance->snd_padding) {
-			memset(target, 0, instance->snd_padding);
-			target += instance->snd_padding;
-		}
-		__skb_pull(skb, ATM_CELL_PAYLOAD);
-	}
-
-	ctrl->num_entire -= ne;
-
-	if (!(ctrl->num_cells -= ne) || !(howmany -= ne))
-		goto out;
-
-	udsl_fill_cell_header(target, ctrl->atm_data.vcc);
-	target += ATM_CELL_HEADER;
-	memcpy(target, skb->data, skb->len);
-	target += skb->len;
-	__skb_pull(skb, skb->len);
-	memset(target, 0, ctrl->pdu_padding);
-	target += ctrl->pdu_padding;
-
-	if (--ctrl->num_cells) {
-		if (!--howmany) {
-			ctrl->pdu_padding = ATM_CELL_PAYLOAD - ATM_AAL5_TRAILER;
-			goto out;
-		}
-
-		if (instance->snd_padding) {
-			memset(target, 0, instance->snd_padding);
-			target += instance->snd_padding;
-		}
-		udsl_fill_cell_header(target, ctrl->atm_data.vcc);
-		target += ATM_CELL_HEADER;
-		memset(target, 0, ATM_CELL_PAYLOAD - ATM_AAL5_TRAILER);
-		target += ATM_CELL_PAYLOAD - ATM_AAL5_TRAILER;
-
-		--ctrl->num_cells;
-		UDSL_ASSERT(!ctrl->num_cells);
-	}
-
-	memcpy(target, ctrl->aal5_trailer, ATM_AAL5_TRAILER);
-	target += ATM_AAL5_TRAILER;
-	/* set pti bit in last cell */
-	*(target + 3 - ATM_CELL_SIZE) |= 0x2;
-	if (instance->snd_padding) {
-		memset(target, 0, instance->snd_padding);
-		target += instance->snd_padding;
-	}
- out:
-	*target_p = target;
-	return nc - ctrl->num_cells;
-}
-
-/**************
-**  receive  **
-**************/
-
-static void udsl_complete_receive(struct urb *urb, struct pt_regs *regs)
-{
-	struct udsl_receive_buffer *buf;
-	struct udsl_instance_data *instance;
-	struct udsl_receiver *rcv;
-	unsigned long flags;
-
-	if (!urb || !(rcv = urb->context)) {
-		dbg("udsl_complete_receive: bad urb!");
-		return;
-	}
-
-	instance = rcv->instance;
-	buf = rcv->buffer;
-
-	buf->filled_cells = urb->actual_length / (ATM_CELL_SIZE + instance->rcv_padding);
-
-	vdbg("udsl_complete_receive: urb 0x%p, status %d, actual_length %d, filled_cells %u, rcv 0x%p, buf 0x%p", urb, urb->status, urb->actual_length, buf->filled_cells, rcv, buf);
-
-	UDSL_ASSERT(buf->filled_cells <= rcv_buf_size);
-
-	/* may not be in_interrupt() */
-	spin_lock_irqsave(&instance->receive_lock, flags);
-	list_add(&rcv->list, &instance->spare_receivers);
-	list_add_tail(&buf->list, &instance->filled_receive_buffers);
-	if (likely(!urb->status))
-		tasklet_schedule(&instance->receive_tasklet);
-	spin_unlock_irqrestore(&instance->receive_lock, flags);
-}
-
-static void udsl_process_receive(unsigned long data)
-{
-	struct udsl_receive_buffer *buf;
-	struct udsl_instance_data *instance = (struct udsl_instance_data *)data;
-	struct udsl_receiver *rcv;
-	int err;
-
- made_progress:
-	while (!list_empty(&instance->spare_receive_buffers)) {
-		spin_lock_irq(&instance->receive_lock);
-		if (list_empty(&instance->spare_receivers)) {
-			spin_unlock_irq(&instance->receive_lock);
-			break;
-		}
-		rcv = list_entry(instance->spare_receivers.next,
-				 struct udsl_receiver, list);
-		list_del(&rcv->list);
-		spin_unlock_irq(&instance->receive_lock);
-
-		buf = list_entry(instance->spare_receive_buffers.next,
-				 struct udsl_receive_buffer, list);
-		list_del(&buf->list);
-
-		rcv->buffer = buf;
-
-		usb_fill_bulk_urb(rcv->urb, instance->usb_dev,
-				  usb_rcvbulkpipe(instance->usb_dev, instance->data_endpoint),
-				  buf->base,
-				  rcv_buf_size * (ATM_CELL_SIZE + instance->rcv_padding),
-				  udsl_complete_receive, rcv);
-
-		vdbg("udsl_process_receive: sending urb 0x%p, rcv 0x%p, buf 0x%p",
-		     rcv->urb, rcv, buf);
-
-		if ((err = usb_submit_urb(rcv->urb, GFP_ATOMIC)) < 0) {
-			dbg("udsl_process_receive: urb submission failed (%d)!", err);
-			list_add(&buf->list, &instance->spare_receive_buffers);
-			spin_lock_irq(&instance->receive_lock);
-			list_add(&rcv->list, &instance->spare_receivers);
-			spin_unlock_irq(&instance->receive_lock);
-			break;
-		}
-	}
-
-	spin_lock_irq(&instance->receive_lock);
-	if (list_empty(&instance->filled_receive_buffers)) {
-		spin_unlock_irq(&instance->receive_lock);
-		return;		/* done - no more buffers */
-	}
-	buf = list_entry(instance->filled_receive_buffers.next,
-			 struct udsl_receive_buffer, list);
-	list_del(&buf->list);
-	spin_unlock_irq(&instance->receive_lock);
-
-	vdbg("udsl_process_receive: processing buf 0x%p", buf);
-	udsl_extract_cells(instance, buf->base, buf->filled_cells);
-	list_add(&buf->list, &instance->spare_receive_buffers);
-	goto made_progress;
-}
-
-/***********
-**  send  **
-***********/
-
-static void udsl_complete_send(struct urb *urb, struct pt_regs *regs)
-{
-	struct udsl_instance_data *instance;
-	struct udsl_sender *snd;
-	unsigned long flags;
-
-	if (!urb || !(snd = urb->context) || !(instance = snd->instance)) {
-		dbg("udsl_complete_send: bad urb!");
-		return;
-	}
-
-	vdbg("udsl_complete_send: urb 0x%p, status %d, snd 0x%p, buf 0x%p", urb,
-	     urb->status, snd, snd->buffer);
-
-	/* may not be in_interrupt() */
-	spin_lock_irqsave(&instance->send_lock, flags);
-	list_add(&snd->list, &instance->spare_senders);
-	list_add(&snd->buffer->list, &instance->spare_send_buffers);
-	tasklet_schedule(&instance->send_tasklet);
-	spin_unlock_irqrestore(&instance->send_lock, flags);
-}
-
-static void udsl_process_send(unsigned long data)
-{
-	struct udsl_send_buffer *buf;
-	struct udsl_instance_data *instance = (struct udsl_instance_data *)data;
-	struct sk_buff *skb;
-	struct udsl_sender *snd;
-	int err;
-	unsigned int num_written;
-
- made_progress:
-	spin_lock_irq(&instance->send_lock);
-	while (!list_empty(&instance->spare_senders)) {
-		if (!list_empty(&instance->filled_send_buffers)) {
-			buf = list_entry(instance->filled_send_buffers.next,
-					 struct udsl_send_buffer, list);
-			list_del(&buf->list);
-		} else if ((buf = instance->current_buffer)) {
-			instance->current_buffer = NULL;
-		} else		/* all buffers empty */
-			break;
-
-		snd = list_entry(instance->spare_senders.next,
-				 struct udsl_sender, list);
-		list_del(&snd->list);
-		spin_unlock_irq(&instance->send_lock);
-
-		snd->buffer = buf;
-		usb_fill_bulk_urb(snd->urb, instance->usb_dev,
-				  usb_sndbulkpipe(instance->usb_dev, instance->data_endpoint),
-				  buf->base,
-				  (snd_buf_size - buf->free_cells) * (ATM_CELL_SIZE + instance->snd_padding),
-				  udsl_complete_send, snd);
-
-		vdbg("udsl_process_send: submitting urb 0x%p (%d cells), snd 0x%p, buf 0x%p",
-		     snd->urb, snd_buf_size - buf->free_cells, snd, buf);
-
-		if ((err = usb_submit_urb(snd->urb, GFP_ATOMIC)) < 0) {
-			dbg("udsl_process_send: urb submission failed (%d)!", err);
-			spin_lock_irq(&instance->send_lock);
-			list_add(&snd->list, &instance->spare_senders);
-			spin_unlock_irq(&instance->send_lock);
-			list_add(&buf->list, &instance->filled_send_buffers);
-			return;	/* bail out */
-		}
-
-		spin_lock_irq(&instance->send_lock);
-	}			/* while */
-	spin_unlock_irq(&instance->send_lock);
-
-	if (!instance->current_skb)
-		instance->current_skb = skb_dequeue(&instance->sndqueue);
-	if (!instance->current_skb)
-		return;		/* done - no more skbs */
-
-	skb = instance->current_skb;
-
-	if (!(buf = instance->current_buffer)) {
-		spin_lock_irq(&instance->send_lock);
-		if (list_empty(&instance->spare_send_buffers)) {
-			instance->current_buffer = NULL;
-			spin_unlock_irq(&instance->send_lock);
-			return;	/* done - no more buffers */
-		}
-		buf = list_entry(instance->spare_send_buffers.next,
-			       struct udsl_send_buffer, list);
-		list_del(&buf->list);
-		spin_unlock_irq(&instance->send_lock);
-
-		buf->free_start = buf->base;
-		buf->free_cells = snd_buf_size;
-
-		instance->current_buffer = buf;
-	}
-
-	num_written = udsl_write_cells(instance, buf->free_cells, skb, &buf->free_start);
-
-	vdbg("udsl_process_send: wrote %u cells from skb 0x%p to buffer 0x%p",
-	     num_written, skb, buf);
-
-	if (!(buf->free_cells -= num_written)) {
-		list_add_tail(&buf->list, &instance->filled_send_buffers);
-		instance->current_buffer = NULL;
-	}
-
-	vdbg("udsl_process_send: buffer contains %d cells, %d left",
-	     snd_buf_size - buf->free_cells, buf->free_cells);
-
-	if (!UDSL_SKB(skb)->num_cells) {
-		struct atm_vcc *vcc = UDSL_SKB(skb)->atm_data.vcc;
-
-		udsl_pop(vcc, skb);
-		instance->current_skb = NULL;
-
-		atomic_inc(&vcc->stats->tx);
-	}
-
-	goto made_progress;
-}
-
-static void udsl_cancel_send(struct udsl_instance_data *instance,
-			     struct atm_vcc *vcc)
-{
-	struct sk_buff *skb, *n;
-
-	dbg("udsl_cancel_send entered");
-	spin_lock_irq(&instance->sndqueue.lock);
-	for (skb = instance->sndqueue.next, n = skb->next;
-	     skb != (struct sk_buff *)&instance->sndqueue;
-	     skb = n, n = skb->next)
-		if (UDSL_SKB(skb)->atm_data.vcc == vcc) {
-			dbg("udsl_cancel_send: popping skb 0x%p", skb);
-			__skb_unlink(skb, &instance->sndqueue);
-			udsl_pop(vcc, skb);
-		}
-	spin_unlock_irq(&instance->sndqueue.lock);
-
-	tasklet_disable(&instance->send_tasklet);
-	if ((skb = instance->current_skb) && (UDSL_SKB(skb)->atm_data.vcc == vcc)) {
-		dbg("udsl_cancel_send: popping current skb (0x%p)", skb);
-		instance->current_skb = NULL;
-		udsl_pop(vcc, skb);
-	}
-	tasklet_enable(&instance->send_tasklet);
-	dbg("udsl_cancel_send done");
-}
-
-static int udsl_atm_send(struct atm_vcc *vcc, struct sk_buff *skb)
-{
-	struct udsl_instance_data *instance = vcc->dev->dev_data;
-	int err;
-
-	vdbg("udsl_atm_send called (skb 0x%p, len %u)", skb, skb->len);
-
-	if (!instance) {
-		dbg("udsl_atm_send: NULL data!");
-		err = -ENODEV;
-		goto fail;
-	}
-
-	if (vcc->qos.aal != ATM_AAL5) {
-		dbg("udsl_atm_send: unsupported ATM type %d!", vcc->qos.aal);
-		err = -EINVAL;
-		goto fail;
-	}
-
-	if (skb->len > ATM_MAX_AAL5_PDU) {
-		dbg("udsl_atm_send: packet too long (%d vs %d)!", skb->len,
-		    ATM_MAX_AAL5_PDU);
-		err = -EINVAL;
-		goto fail;
-	}
-
-	PACKETDEBUG(skb->data, skb->len);
-
-	udsl_groom_skb(vcc, skb);
-	skb_queue_tail(&instance->sndqueue, skb);
-	tasklet_schedule(&instance->send_tasklet);
-
-	return 0;
-
- fail:
-	udsl_pop(vcc, skb);
-	return err;
-}
-
-/********************
-**  bean counting  **
-********************/
-
-static void udsl_destroy_instance(struct kref *kref)
-{
-	struct udsl_instance_data *instance =
-	    container_of(kref, struct udsl_instance_data, refcount);
-
-	tasklet_kill(&instance->receive_tasklet);
-	tasklet_kill(&instance->send_tasklet);
-	usb_put_dev(instance->usb_dev);
-	kfree(instance);
-}
-
-void udsl_get_instance(struct udsl_instance_data *instance)
-{
-	kref_get(&instance->refcount);
-}
-
-void udsl_put_instance(struct udsl_instance_data *instance)
-{
-	kref_put(&instance->refcount, udsl_destroy_instance);
-}
-
-/**********
-**  ATM  **
-**********/
-
-static void udsl_atm_dev_close(struct atm_dev *dev)
-{
-	struct udsl_instance_data *instance = dev->dev_data;
-
-	dev->dev_data = NULL;
-	udsl_put_instance(instance);
-}
-
-static int udsl_atm_proc_read(struct atm_dev *atm_dev, loff_t * pos, char *page)
-{
-	struct udsl_instance_data *instance = atm_dev->dev_data;
-	int left = *pos;
-
-	if (!instance) {
-		dbg("udsl_atm_proc_read: NULL instance!");
-		return -ENODEV;
-	}
-
-	if (!left--)
-		return sprintf(page, "%s\n", instance->description);
-
-	if (!left--)
-		return sprintf(page, "MAC: %02x:%02x:%02x:%02x:%02x:%02x\n",
-			       atm_dev->esi[0], atm_dev->esi[1],
-			       atm_dev->esi[2], atm_dev->esi[3],
-			       atm_dev->esi[4], atm_dev->esi[5]);
-
-	if (!left--)
-		return sprintf(page,
-			       "AAL5: tx %d ( %d err ), rx %d ( %d err, %d drop )\n",
-			       atomic_read(&atm_dev->stats.aal5.tx),
-			       atomic_read(&atm_dev->stats.aal5.tx_err),
-			       atomic_read(&atm_dev->stats.aal5.rx),
-			       atomic_read(&atm_dev->stats.aal5.rx_err),
-			       atomic_read(&atm_dev->stats.aal5.rx_drop));
-
-	if (!left--) {
-		switch (atm_dev->signal) {
-		case ATM_PHY_SIG_FOUND:
-			sprintf(page, "Line up");
-			break;
-		case ATM_PHY_SIG_LOST:
-			sprintf(page, "Line down");
-			break;
-		default:
-			sprintf(page, "Line state unknown");
-			break;
-		}
-
-		if (instance->usb_dev->state == USB_STATE_NOTATTACHED)
-			strcat(page, ", disconnected\n");
-		else {
-			if (instance->status == UDSL_LOADED_FIRMWARE)
-				strcat(page, ", firmware loaded\n");
-			else if (instance->status == UDSL_LOADING_FIRMWARE)
-				strcat(page, ", firmware loading\n");
-			else
-				strcat(page, ", no firmware\n");
-		}
-
-		return strlen(page);
-	}
-
-	return 0;
-}
-
-static int udsl_atm_open(struct atm_vcc *vcc)
-{
-	struct udsl_instance_data *instance = vcc->dev->dev_data;
-	struct udsl_vcc_data *new;
-	unsigned int max_pdu;
-	int vci = vcc->vci;
-	short vpi = vcc->vpi;
-	int err;
-
-	dbg("udsl_atm_open: vpi %hd, vci %d", vpi, vci);
-
-	if (!instance) {
-		dbg("udsl_atm_open: NULL data!");
-		return -ENODEV;
-	}
-
-	/* only support AAL5 */
-	if ((vcc->qos.aal != ATM_AAL5) || (vcc->qos.rxtp.max_sdu < 0)
-	    || (vcc->qos.rxtp.max_sdu > ATM_MAX_AAL5_PDU)) {
-		dbg("udsl_atm_open: unsupported ATM type %d!", vcc->qos.aal);
-		return -EINVAL;
-	}
-
-	if (instance->firmware_wait &&
-	    (err = instance->firmware_wait(instance)) < 0) {
-		dbg("udsl_atm_open: firmware not loaded (%d)!", err);
-		return err;
-	}
-
-	down(&instance->serialize);	/* vs self, udsl_atm_close */
-
-	if (udsl_find_vcc(instance, vpi, vci)) {
-		dbg("udsl_atm_open: %hd/%d already in use!", vpi, vci);
-		up(&instance->serialize);
-		return -EADDRINUSE;
-	}
-
-	if (!(new = kmalloc(sizeof(struct udsl_vcc_data), GFP_KERNEL))) {
-		dbg("udsl_atm_open: no memory for vcc_data!");
-		up(&instance->serialize);
-		return -ENOMEM;
-	}
-
-	memset(new, 0, sizeof(struct udsl_vcc_data));
-	new->vcc = vcc;
-	new->vpi = vpi;
-	new->vci = vci;
-
-	/* udsl_extract_cells requires at least one cell */
-	max_pdu = max(1, UDSL_NUM_CELLS(vcc->qos.rxtp.max_sdu)) * ATM_CELL_PAYLOAD;
-	if (!(new->sarb = alloc_skb(max_pdu, GFP_KERNEL))) {
-		dbg("udsl_atm_open: no memory for SAR buffer!");
-		kfree(new);
-		up(&instance->serialize);
-		return -ENOMEM;
-	}
-
-	vcc->dev_data = new;
-
-	tasklet_disable(&instance->receive_tasklet);
-	list_add(&new->list, &instance->vcc_list);
-	tasklet_enable(&instance->receive_tasklet);
-
-	set_bit(ATM_VF_ADDR, &vcc->flags);
-	set_bit(ATM_VF_PARTIAL, &vcc->flags);
-	set_bit(ATM_VF_READY, &vcc->flags);
-
-	up(&instance->serialize);
-
-	tasklet_schedule(&instance->receive_tasklet);
-
-	dbg("udsl_atm_open: allocated vcc data 0x%p (max_pdu: %u)", new, max_pdu);
-
-	return 0;
-}
-
-static void udsl_atm_close(struct atm_vcc *vcc)
-{
-	struct udsl_instance_data *instance = vcc->dev->dev_data;
-	struct udsl_vcc_data *vcc_data = vcc->dev_data;
-
-	dbg("udsl_atm_close called");
-
-	if (!instance || !vcc_data) {
-		dbg("udsl_atm_close: NULL data!");
-		return;
-	}
-
-	dbg("udsl_atm_close: deallocating vcc 0x%p with vpi %d vci %d",
-	    vcc_data, vcc_data->vpi, vcc_data->vci);
-
-	udsl_cancel_send(instance, vcc);
-
-	down(&instance->serialize);	/* vs self, udsl_atm_open */
-
-	tasklet_disable(&instance->receive_tasklet);
-	list_del(&vcc_data->list);
-	tasklet_enable(&instance->receive_tasklet);
-
-	kfree_skb(vcc_data->sarb);
-	vcc_data->sarb = NULL;
-
-	kfree(vcc_data);
-	vcc->dev_data = NULL;
-
-	vcc->vpi = ATM_VPI_UNSPEC;
-	vcc->vci = ATM_VCI_UNSPEC;
-	clear_bit(ATM_VF_READY, &vcc->flags);
-	clear_bit(ATM_VF_PARTIAL, &vcc->flags);
-	clear_bit(ATM_VF_ADDR, &vcc->flags);
-
-	up(&instance->serialize);
-
-	dbg("udsl_atm_close successful");
-}
-
-static int udsl_atm_ioctl(struct atm_dev *dev, unsigned int cmd,
-			  void __user * arg)
-{
-	switch (cmd) {
-	case ATM_QUERYLOOP:
-		return put_user(ATM_LM_NONE, (int __user *)arg) ? -EFAULT : 0;
-	default:
-		return -ENOIOCTLCMD;
-	}
-}
-
-/**********
-**  USB  **
-**********/
-
-int udsl_instance_setup(struct usb_device *dev,
-			struct udsl_instance_data *instance)
-{
-	char *buf;
-	int i, length;
-
-	kref_init(&instance->refcount);	/* one for USB */
-	udsl_get_instance(instance);	/* one for ATM */
-
-	init_MUTEX(&instance->serialize);
-
-	instance->usb_dev = dev;
-
-	INIT_LIST_HEAD(&instance->vcc_list);
-
-	instance->status = UDSL_NO_FIRMWARE;
-	init_waitqueue_head(&instance->firmware_waiters);
-
-	spin_lock_init(&instance->receive_lock);
-	INIT_LIST_HEAD(&instance->spare_receivers);
-	INIT_LIST_HEAD(&instance->filled_receive_buffers);
-
-	tasklet_init(&instance->receive_tasklet, udsl_process_receive, (unsigned long)instance);
-	INIT_LIST_HEAD(&instance->spare_receive_buffers);
-
-	skb_queue_head_init(&instance->sndqueue);
-
-	spin_lock_init(&instance->send_lock);
-	INIT_LIST_HEAD(&instance->spare_senders);
-	INIT_LIST_HEAD(&instance->spare_send_buffers);
-
-	tasklet_init(&instance->send_tasklet, udsl_process_send,
-		     (unsigned long)instance);
-	INIT_LIST_HEAD(&instance->filled_send_buffers);
-
-	/* receive init */
-	for (i = 0; i < num_rcv_urbs; i++) {
-		struct udsl_receiver *rcv = &(instance->receivers[i]);
-
-		if (!(rcv->urb = usb_alloc_urb(0, GFP_KERNEL))) {
-			dbg("udsl_usb_probe: no memory for receive urb %d!", i);
-			goto fail;
-		}
-
-		rcv->instance = instance;
-
-		list_add(&rcv->list, &instance->spare_receivers);
-	}
-
-	for (i = 0; i < num_rcv_bufs; i++) {
-		struct udsl_receive_buffer *buf =
-		    &(instance->receive_buffers[i]);
-
-		buf->base = kmalloc(rcv_buf_size * (ATM_CELL_SIZE + instance->rcv_padding),
-				    GFP_KERNEL);
-		if (!buf->base) {
-			dbg("udsl_usb_probe: no memory for receive buffer %d!", i);
-			goto fail;
-		}
-
-		list_add(&buf->list, &instance->spare_receive_buffers);
-	}
-
-	/* send init */
-	for (i = 0; i < num_snd_urbs; i++) {
-		struct udsl_sender *snd = &(instance->senders[i]);
-
-		if (!(snd->urb = usb_alloc_urb(0, GFP_KERNEL))) {
-			dbg("udsl_usb_probe: no memory for send urb %d!", i);
-			goto fail;
-		}
-
-		snd->instance = instance;
-
-		list_add(&snd->list, &instance->spare_senders);
-	}
-
-	for (i = 0; i < num_snd_bufs; i++) {
-		struct udsl_send_buffer *buf = &(instance->send_buffers[i]);
-
-		buf->base = kmalloc(snd_buf_size * (ATM_CELL_SIZE + instance->snd_padding),
-				    GFP_KERNEL);
-		if (!buf->base) {
-			dbg("udsl_usb_probe: no memory for send buffer %d!", i);
-			goto fail;
-		}
-
-		list_add(&buf->list, &instance->spare_send_buffers);
-	}
-
-	/* ATM init */
-	instance->atm_dev = atm_dev_register(instance->driver_name,
-					     &udsl_atm_devops, -1, NULL);
-	if (!instance->atm_dev) {
-		dbg("udsl_usb_probe: failed to register ATM device!");
-		goto fail;
-	}
-
-	instance->atm_dev->ci_range.vpi_bits = ATM_CI_MAX;
-	instance->atm_dev->ci_range.vci_bits = ATM_CI_MAX;
-	instance->atm_dev->signal = ATM_PHY_SIG_UNKNOWN;
-
-	/* temp init ATM device, set to 128kbit */
-	instance->atm_dev->link_rate = 128 * 1000 / 424;
-
-	/* device description */
-	buf = instance->description;
-	length = sizeof(instance->description);
-
-	if ((i = usb_string(dev, dev->descriptor.iProduct, buf, length)) < 0)
-		goto finish;
-
-	buf += i;
-	length -= i;
-
-	i = scnprintf(buf, length, " (");
-	buf += i;
-	length -= i;
-
-	if (length <= 0 || (i = usb_make_path(dev, buf, length)) < 0)
-		goto finish;
-
-	buf += i;
-	length -= i;
-
-	snprintf(buf, length, ")");
-
- finish:
-	/* ready for ATM callbacks */
-	wmb();
-	instance->atm_dev->dev_data = instance;
-
-	usb_get_dev(dev);
-
-	return 0;
-
- fail:
-	for (i = 0; i < num_snd_bufs; i++)
-		kfree(instance->send_buffers[i].base);
-
-	for (i = 0; i < num_snd_urbs; i++)
-		usb_free_urb(instance->senders[i].urb);
-
-	for (i = 0; i < num_rcv_bufs; i++)
-		kfree(instance->receive_buffers[i].base);
-
-	for (i = 0; i < num_rcv_urbs; i++)
-		usb_free_urb(instance->receivers[i].urb);
-
-	return -ENOMEM;
-}
-
-void udsl_instance_disconnect(struct udsl_instance_data *instance)
-{
-	int i;
-
-	dbg("udsl_instance_disconnect entered");
-
-	if (!instance) {
-		dbg("udsl_instance_disconnect: NULL instance!");
-		return;
-	}
-
-	/* receive finalize */
-	tasklet_disable(&instance->receive_tasklet);
-
-	for (i = 0; i < num_rcv_urbs; i++)
-		usb_kill_urb(instance->receivers[i].urb);
-
-	/* no need to take the spinlock */
-	INIT_LIST_HEAD(&instance->filled_receive_buffers);
-	INIT_LIST_HEAD(&instance->spare_receive_buffers);
-
-	tasklet_enable(&instance->receive_tasklet);
-
-	for (i = 0; i < num_rcv_urbs; i++)
-		usb_free_urb(instance->receivers[i].urb);
-
-	for (i = 0; i < num_rcv_bufs; i++)
-		kfree(instance->receive_buffers[i].base);
-
-	/* send finalize */
-	tasklet_disable(&instance->send_tasklet);
-
-	for (i = 0; i < num_snd_urbs; i++)
-		usb_kill_urb(instance->senders[i].urb);
-
-	/* no need to take the spinlock */
-	INIT_LIST_HEAD(&instance->spare_senders);
-	INIT_LIST_HEAD(&instance->spare_send_buffers);
-	instance->current_buffer = NULL;
-
-	tasklet_enable(&instance->send_tasklet);
-
-	for (i = 0; i < num_snd_urbs; i++)
-		usb_free_urb(instance->senders[i].urb);
-
-	for (i = 0; i < num_snd_bufs; i++)
-		kfree(instance->send_buffers[i].base);
-
-	/* ATM finalize */
-	shutdown_atm_dev(instance->atm_dev);
-}
-
-EXPORT_SYMBOL_GPL(udsl_get_instance);
-EXPORT_SYMBOL_GPL(udsl_put_instance);
-EXPORT_SYMBOL_GPL(udsl_instance_setup);
-EXPORT_SYMBOL_GPL(udsl_instance_disconnect);
-
-/***********
-**  init  **
-***********/
-
-static int __init udsl_usb_init(void)
-{
-	dbg("udsl_usb_init: driver version " DRIVER_VERSION);
-
-	if (sizeof(struct udsl_control) > sizeof(((struct sk_buff *) 0)->cb)) {
-		printk(KERN_ERR __FILE__ ": unusable with this kernel!\n");
-		return -EIO;
-	}
-
-	if ((num_rcv_urbs > UDSL_MAX_RCV_URBS)
-	    || (num_snd_urbs > UDSL_MAX_SND_URBS)
-	    || (num_rcv_bufs > UDSL_MAX_RCV_BUFS)
-	    || (num_snd_bufs > UDSL_MAX_SND_BUFS)
-	    || (rcv_buf_size > UDSL_MAX_RCV_BUF_SIZE)
-	    || (snd_buf_size > UDSL_MAX_SND_BUF_SIZE))
-		return -EINVAL;
-
-	return 0;
-}
-
-static void __exit udsl_usb_exit(void)
-{
-}
-
-module_init(udsl_usb_init);
-module_exit(udsl_usb_exit);
-
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE("GPL");
-MODULE_VERSION(DRIVER_VERSION);
-
-/************
-**  debug  **
-************/
-
-#ifdef VERBOSE_DEBUG
-static int udsl_print_packet(const unsigned char *data, int len)
-{
-	unsigned char buffer[256];
-	int i = 0, j = 0;
-
-	for (i = 0; i < len;) {
-		buffer[0] = '\0';
-		sprintf(buffer, "%.3d :", i);
-		for (j = 0; (j < 16) && (i < len); j++, i++) {
-			sprintf(buffer, "%s %2.2x", buffer, data[i]);
-		}
-		dbg("%s", buffer);
-	}
-	return i;
-}
-#endif
diff --git a/drivers/usb/atm/usb_atm.h b/drivers/usb/atm/usb_atm.h
deleted file mode 100644
--- a/drivers/usb/atm/usb_atm.h
+++ /dev/null
@@ -1,176 +0,0 @@
-/******************************************************************************
- *  usb_atm.h - Generic USB xDSL driver core
- *
- *  Copyright (C) 2001, Alcatel
- *  Copyright (C) 2003, Duncan Sands, SolNegro, Josep Comas
- *  Copyright (C) 2004, David Woodhouse
- *
- *  This program is free software; you can redistribute it and/or modify it
- *  under the terms of the GNU General Public License as published by the Free
- *  Software Foundation; either version 2 of the License, or (at your option)
- *  any later version.
- *
- *  This program is distributed in the hope that it will be useful, but WITHOUT
- *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- *  more details.
- *
- *  You should have received a copy of the GNU General Public License along with
- *  this program; if not, write to the Free Software Foundation, Inc., 59
- *  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- *
- ******************************************************************************/
-
-#include <linux/config.h>
-#include <linux/list.h>
-#include <linux/kref.h>
-#include <linux/atm.h>
-#include <linux/atmdev.h>
-#include <asm/semaphore.h>
-
-/*
-#define DEBUG
-#define VERBOSE_DEBUG
-*/
-
-#if !defined (DEBUG) && defined (CONFIG_USB_DEBUG)
-#	define DEBUG
-#endif
-
-#include <linux/usb.h>
-
-#ifdef DEBUG
-#define UDSL_ASSERT(x)	BUG_ON(!(x))
-#else
-#define UDSL_ASSERT(x)	do { if (!(x)) warn("failed assertion '" #x "' at line %d", __LINE__); } while(0)
-#endif
-
-#define UDSL_MAX_RCV_URBS		4
-#define UDSL_MAX_SND_URBS		4
-#define UDSL_MAX_RCV_BUFS		8
-#define UDSL_MAX_SND_BUFS		8
-#define UDSL_MAX_RCV_BUF_SIZE		1024	/* ATM cells */
-#define UDSL_MAX_SND_BUF_SIZE		1024	/* ATM cells */
-#define UDSL_DEFAULT_RCV_URBS		2
-#define UDSL_DEFAULT_SND_URBS		2
-#define UDSL_DEFAULT_RCV_BUFS		4
-#define UDSL_DEFAULT_SND_BUFS		4
-#define UDSL_DEFAULT_RCV_BUF_SIZE	64	/* ATM cells */
-#define UDSL_DEFAULT_SND_BUF_SIZE	64	/* ATM cells */
-
-#define ATM_CELL_HEADER			(ATM_CELL_SIZE - ATM_CELL_PAYLOAD)
-#define UDSL_NUM_CELLS(x)		(((x) + ATM_AAL5_TRAILER + ATM_CELL_PAYLOAD - 1) / ATM_CELL_PAYLOAD)
-
-/* receive */
-
-struct udsl_receive_buffer {
-	struct list_head list;
-	unsigned char *base;
-	unsigned int filled_cells;
-};
-
-struct udsl_receiver {
-	struct list_head list;
-	struct udsl_receive_buffer *buffer;
-	struct urb *urb;
-	struct udsl_instance_data *instance;
-};
-
-struct udsl_vcc_data {
-	/* vpi/vci lookup */
-	struct list_head list;
-	short vpi;
-	int vci;
-	struct atm_vcc *vcc;
-
-	/* raw cell reassembly */
-	struct sk_buff *sarb;
-};
-
-/* send */
-
-struct udsl_send_buffer {
-	struct list_head list;
-	unsigned char *base;
-	unsigned char *free_start;
-	unsigned int free_cells;
-};
-
-struct udsl_sender {
-	struct list_head list;
-	struct udsl_send_buffer *buffer;
-	struct urb *urb;
-	struct udsl_instance_data *instance;
-};
-
-struct udsl_control {
-	struct atm_skb_data atm_data;
-	unsigned int num_cells;
-	unsigned int num_entire;
-	unsigned int pdu_padding;
-	unsigned char aal5_trailer[ATM_AAL5_TRAILER];
-};
-
-#define UDSL_SKB(x)		((struct udsl_control *)(x)->cb)
-
-/* main driver data */
-
-enum udsl_status {
-	UDSL_NO_FIRMWARE,
-	UDSL_LOADING_FIRMWARE,
-	UDSL_LOADED_FIRMWARE
-};
-
-struct udsl_instance_data {
-	struct kref refcount;
-	struct semaphore serialize;
-
-	/* USB device part */
-	struct usb_device *usb_dev;
-	char description[64];
-	int data_endpoint;
-	int snd_padding;
-	int rcv_padding;
-	const char *driver_name;
-
-	/* ATM device part */
-	struct atm_dev *atm_dev;
-	struct list_head vcc_list;
-
-	/* firmware */
-	int (*firmware_wait) (struct udsl_instance_data *);
-	enum udsl_status status;
-	wait_queue_head_t firmware_waiters;
-
-	/* receive */
-	struct udsl_receiver receivers[UDSL_MAX_RCV_URBS];
-	struct udsl_receive_buffer receive_buffers[UDSL_MAX_RCV_BUFS];
-
-	spinlock_t receive_lock;
-	struct list_head spare_receivers;
-	struct list_head filled_receive_buffers;
-
-	struct tasklet_struct receive_tasklet;
-	struct list_head spare_receive_buffers;
-
-	/* send */
-	struct udsl_sender senders[UDSL_MAX_SND_URBS];
-	struct udsl_send_buffer send_buffers[UDSL_MAX_SND_BUFS];
-
-	struct sk_buff_head sndqueue;
-
-	spinlock_t send_lock;
-	struct list_head spare_senders;
-	struct list_head spare_send_buffers;
-
-	struct tasklet_struct send_tasklet;
-	struct sk_buff *current_skb;			/* being emptied */
-	struct udsl_send_buffer *current_buffer;	/* being filled */
-	struct list_head filled_send_buffers;
-};
-
-extern int udsl_instance_setup(struct usb_device *dev,
-			       struct udsl_instance_data *instance);
-extern void udsl_instance_disconnect(struct udsl_instance_data *instance);
-extern void udsl_get_instance(struct udsl_instance_data *instance);
-extern void udsl_put_instance(struct udsl_instance_data *instance);
diff --git a/drivers/usb/atm/usbatm.c b/drivers/usb/atm/usbatm.c
new file mode 100644
--- /dev/null
+++ b/drivers/usb/atm/usbatm.c
@@ -0,0 +1,1230 @@
+/******************************************************************************
+ *  usbatm.c - Generic USB xDSL driver core
+ *
+ *  Copyright (C) 2001, Alcatel
+ *  Copyright (C) 2003, Duncan Sands, SolNegro, Josep Comas
+ *  Copyright (C) 2004, David Woodhouse, Roman Kagan
+ *
+ *  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.
+ *
+ ******************************************************************************/
+
+/*
+ *  Written by Johan Verrept, Duncan Sands (duncan.sands@free.fr) and David Woodhouse
+ *
+ *  1.7+:	- See the check-in logs
+ *
+ *  1.6:	- No longer opens a connection if the firmware is not loaded
+ *  		- Added support for the speedtouch 330
+ *  		- Removed the limit on the number of devices
+ *  		- Module now autoloads on device plugin
+ *  		- Merged relevant parts of sarlib
+ *  		- Replaced the kernel thread with a tasklet
+ *  		- New packet transmission code
+ *  		- Changed proc file contents
+ *  		- Fixed all known SMP races
+ *  		- Many fixes and cleanups
+ *  		- Various fixes by Oliver Neukum (oliver@neukum.name)
+ *
+ *  1.5A:	- Version for inclusion in 2.5 series kernel
+ *		- Modifications by Richard Purdie (rpurdie@rpsys.net)
+ *		- made compatible with kernel 2.5.6 onwards by changing
+ *		usbatm_usb_send_data_context->urb to a pointer and adding code
+ *		to alloc and free it
+ *		- remove_wait_queue() added to usbatm_atm_processqueue_thread()
+ *
+ *  1.5:	- fixed memory leak when atmsar_decode_aal5 returned NULL.
+ *		(reported by stephen.robinson@zen.co.uk)
+ *
+ *  1.4:	- changed the spin_lock() under interrupt to spin_lock_irqsave()
+ *		- unlink all active send urbs of a vcc that is being closed.
+ *
+ *  1.3.1:	- added the version number
+ *
+ *  1.3:	- Added multiple send urb support
+ *		- fixed memory leak and vcc->tx_inuse starvation bug
+ *		  when not enough memory left in vcc.
+ *
+ *  1.2:	- Fixed race condition in usbatm_usb_send_data()
+ *  1.1:	- Turned off packet debugging
+ *
+ */
+
+#include "usbatm.h"
+
+#include <asm/uaccess.h>
+#include <linux/crc32.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/proc_fs.h>
+#include <linux/sched.h>
+#include <linux/signal.h>
+#include <linux/slab.h>
+#include <linux/smp_lock.h>
+#include <linux/stat.h>
+#include <linux/timer.h>
+#include <linux/wait.h>
+
+#ifdef VERBOSE_DEBUG
+static int usbatm_print_packet(const unsigned char *data, int len);
+#define PACKETDEBUG(arg...)	usbatm_print_packet (arg)
+#define vdbg(arg...)		dbg (arg)
+#else
+#define PACKETDEBUG(arg...)
+#define vdbg(arg...)
+#endif
+
+#define DRIVER_AUTHOR	"Johan Verrept, Duncan Sands <duncan.sands@free.fr>"
+#define DRIVER_VERSION	"1.9"
+#define DRIVER_DESC	"Generic USB ATM/DSL I/O, version " DRIVER_VERSION
+
+static const char usbatm_driver_name[] = "usbatm";
+
+#define UDSL_MAX_RCV_URBS		16
+#define UDSL_MAX_SND_URBS		16
+#define UDSL_MAX_RCV_BUF_SIZE		1024	/* ATM cells */
+#define UDSL_MAX_SND_BUF_SIZE		1024	/* ATM cells */
+#define UDSL_DEFAULT_RCV_URBS		4
+#define UDSL_DEFAULT_SND_URBS		4
+#define UDSL_DEFAULT_RCV_BUF_SIZE	64	/* ATM cells */
+#define UDSL_DEFAULT_SND_BUF_SIZE	64	/* ATM cells */
+
+#define ATM_CELL_HEADER			(ATM_CELL_SIZE - ATM_CELL_PAYLOAD)
+
+#define THROTTLE_MSECS			100	/* delay to recover processing after urb submission fails */
+
+static unsigned int num_rcv_urbs = UDSL_DEFAULT_RCV_URBS;
+static unsigned int num_snd_urbs = UDSL_DEFAULT_SND_URBS;
+static unsigned int rcv_buf_size = UDSL_DEFAULT_RCV_BUF_SIZE;
+static unsigned int snd_buf_size = UDSL_DEFAULT_SND_BUF_SIZE;
+
+module_param(num_rcv_urbs, uint, S_IRUGO);
+MODULE_PARM_DESC(num_rcv_urbs,
+		 "Number of urbs used for reception (range: 0-"
+		 __MODULE_STRING(UDSL_MAX_RCV_URBS) ", default: "
+		 __MODULE_STRING(UDSL_DEFAULT_RCV_URBS) ")");
+
+module_param(num_snd_urbs, uint, S_IRUGO);
+MODULE_PARM_DESC(num_snd_urbs,
+		 "Number of urbs used for transmission (range: 0-"
+		 __MODULE_STRING(UDSL_MAX_SND_URBS) ", default: "
+		 __MODULE_STRING(UDSL_DEFAULT_SND_URBS) ")");
+
+module_param(rcv_buf_size, uint, S_IRUGO);
+MODULE_PARM_DESC(rcv_buf_size,
+		 "Size of the buffers used for reception in ATM cells (range: 1-"
+		 __MODULE_STRING(UDSL_MAX_RCV_BUF_SIZE) ", default: "
+		 __MODULE_STRING(UDSL_DEFAULT_RCV_BUF_SIZE) ")");
+
+module_param(snd_buf_size, uint, S_IRUGO);
+MODULE_PARM_DESC(snd_buf_size,
+		 "Size of the buffers used for transmission in ATM cells (range: 1-"
+		 __MODULE_STRING(UDSL_MAX_SND_BUF_SIZE) ", default: "
+		 __MODULE_STRING(UDSL_DEFAULT_SND_BUF_SIZE) ")");
+
+
+/* receive */
+
+struct usbatm_vcc_data {
+	/* vpi/vci lookup */
+	struct list_head list;
+	short vpi;
+	int vci;
+	struct atm_vcc *vcc;
+
+	/* raw cell reassembly */
+	struct sk_buff *sarb;
+};
+
+
+/* send */
+
+struct usbatm_control {
+	struct atm_skb_data atm;
+	u32 len;
+	u32 crc;
+};
+
+#define UDSL_SKB(x)		((struct usbatm_control *)(x)->cb)
+
+
+/* ATM */
+
+static void usbatm_atm_dev_close(struct atm_dev *dev);
+static int usbatm_atm_open(struct atm_vcc *vcc);
+static void usbatm_atm_close(struct atm_vcc *vcc);
+static int usbatm_atm_ioctl(struct atm_dev *dev, unsigned int cmd, void __user * arg);
+static int usbatm_atm_send(struct atm_vcc *vcc, struct sk_buff *skb);
+static int usbatm_atm_proc_read(struct atm_dev *atm_dev, loff_t * pos, char *page);
+
+static struct atmdev_ops usbatm_atm_devops = {
+	.dev_close	= usbatm_atm_dev_close,
+	.open		= usbatm_atm_open,
+	.close		= usbatm_atm_close,
+	.ioctl		= usbatm_atm_ioctl,
+	.send		= usbatm_atm_send,
+	.proc_read	= usbatm_atm_proc_read,
+	.owner		= THIS_MODULE,
+};
+
+
+/***********
+**  misc  **
+***********/
+
+static inline unsigned int usbatm_pdu_length(unsigned int length)
+{
+	length += ATM_CELL_PAYLOAD - 1 + ATM_AAL5_TRAILER;
+	return length - length % ATM_CELL_PAYLOAD;
+}
+
+static inline void usbatm_pop(struct atm_vcc *vcc, struct sk_buff *skb)
+{
+	if (vcc->pop)
+		vcc->pop(vcc, skb);
+	else
+		dev_kfree_skb(skb);
+}
+
+
+/***********
+**  urbs  **
+************/
+
+static inline struct urb *usbatm_pop_urb(struct usbatm_channel *channel)
+{
+	struct urb *urb;
+
+	spin_lock_irq(&channel->lock);
+	if (list_empty(&channel->list)) {
+		spin_unlock_irq(&channel->lock);
+		return NULL;
+	}
+
+	urb = list_entry(channel->list.next, struct urb, urb_list);
+	list_del(&urb->urb_list);
+	spin_unlock_irq(&channel->lock);
+
+	return urb;
+}
+
+static inline int usbatm_submit_urb(struct urb *urb)
+{
+	struct usbatm_channel *channel = urb->context;
+	int ret;
+
+	vdbg("%s: submitting urb 0x%p, size %u",
+	     __func__, urb, urb->transfer_buffer_length);
+
+	ret = usb_submit_urb(urb, GFP_ATOMIC);
+	if (ret) {
+		atm_dbg(channel->usbatm, "%s: urb 0x%p submission failed (%d)!\n",
+			__func__, urb, ret);
+
+		/* consider all errors transient and return the buffer back to the queue */
+		urb->status = -EAGAIN;
+		spin_lock_irq(&channel->lock);
+
+		/* must add to the front when sending; doesn't matter when receiving */
+		list_add(&urb->urb_list, &channel->list);
+
+		spin_unlock_irq(&channel->lock);
+
+		/* make sure the channel doesn't stall */
+		mod_timer(&channel->delay, jiffies + msecs_to_jiffies(THROTTLE_MSECS));
+	}
+
+	return ret;
+}
+
+static void usbatm_complete(struct urb *urb, struct pt_regs *regs)
+{
+	struct usbatm_channel *channel = urb->context;
+	unsigned long flags;
+
+	vdbg("%s: urb 0x%p, status %d, actual_length %d",
+	     __func__, urb, urb->status, urb->actual_length);
+
+	/* usually in_interrupt(), but not always */
+	spin_lock_irqsave(&channel->lock, flags);
+
+	/* must add to the back when receiving; doesn't matter when sending */
+	list_add_tail(&urb->urb_list, &channel->list);
+
+	spin_unlock_irqrestore(&channel->lock, flags);
+
+	if (unlikely(urb->status))
+		/* throttle processing in case of an error */
+		mod_timer(&channel->delay, jiffies + msecs_to_jiffies(THROTTLE_MSECS));
+	else
+		tasklet_schedule(&channel->tasklet);
+}
+
+
+/*************
+**  decode  **
+*************/
+
+static inline struct usbatm_vcc_data *usbatm_find_vcc(struct usbatm_data *instance,
+						  short vpi, int vci)
+{
+	struct usbatm_vcc_data *vcc;
+
+	list_for_each_entry(vcc, &instance->vcc_list, list)
+		if ((vcc->vci == vci) && (vcc->vpi == vpi))
+			return vcc;
+	return NULL;
+}
+
+static void usbatm_extract_cells(struct usbatm_data *instance,
+			       unsigned char *source, unsigned int avail_data)
+{
+	struct usbatm_vcc_data *cached_vcc = NULL;
+	struct atm_vcc *vcc;
+	struct sk_buff *sarb;
+	unsigned int stride = instance->rx_channel.stride;
+	int vci, cached_vci = 0;
+	short vpi, cached_vpi = 0;
+	u8 pti;
+
+	for (; avail_data >= stride; avail_data -= stride, source += stride) {
+		vpi = ((source[0] & 0x0f) << 4)  | (source[1] >> 4);
+		vci = ((source[1] & 0x0f) << 12) | (source[2] << 4) | (source[3] >> 4);
+		pti = ((source[3] & 0xe) >> 1);
+
+		vdbg("%s: vpi %hd, vci %d, pti %d", __func__, vpi, vci, pti);
+
+		if ((vci != cached_vci) || (vpi != cached_vpi)) {
+			cached_vpi = vpi;
+			cached_vci = vci;
+
+			cached_vcc = usbatm_find_vcc(instance, vpi, vci);
+
+			if (!cached_vcc)
+				atm_dbg(instance, "%s: unknown vpi/vci (%hd/%d)!\n", __func__, vpi, vci);
+		}
+
+		if (!cached_vcc)
+			continue;
+
+		vcc = cached_vcc->vcc;
+
+		/* OAM F5 end-to-end */
+		if (pti == ATM_PTI_E2EF5) {
+			atm_warn(instance, "%s: OAM not supported (vpi %d, vci %d)!\n", __func__, vpi, vci);
+			atomic_inc(&vcc->stats->rx_err);
+			continue;
+		}
+
+		sarb = cached_vcc->sarb;
+
+		if (sarb->tail + ATM_CELL_PAYLOAD > sarb->end) {
+			atm_dbg(instance, "%s: buffer overrun (sarb->len %u, vcc: 0x%p)!\n",
+					__func__, sarb->len, vcc);
+			/* discard cells already received */
+			skb_trim(sarb, 0);
+			UDSL_ASSERT(sarb->tail + ATM_CELL_PAYLOAD <= sarb->end);
+		}
+
+		memcpy(sarb->tail, source + ATM_CELL_HEADER, ATM_CELL_PAYLOAD);
+		__skb_put(sarb, ATM_CELL_PAYLOAD);
+
+		if (pti & 1) {
+			struct sk_buff *skb;
+			unsigned int length;
+			unsigned int pdu_length;
+
+			length = (source[ATM_CELL_SIZE - 6] << 8) + source[ATM_CELL_SIZE - 5];
+
+			/* guard against overflow */
+			if (length > ATM_MAX_AAL5_PDU) {
+				atm_dbg(instance, "%s: bogus length %u (vcc: 0x%p)!\n",
+						__func__, length, vcc);
+				atomic_inc(&vcc->stats->rx_err);
+				goto out;
+			}
+
+			pdu_length = usbatm_pdu_length(length);
+
+			if (sarb->len < pdu_length) {
+				atm_dbg(instance, "%s: bogus pdu_length %u (sarb->len: %u, vcc: 0x%p)!\n",
+						__func__, pdu_length, sarb->len, vcc);
+				atomic_inc(&vcc->stats->rx_err);
+				goto out;
+			}
+
+			if (crc32_be(~0, sarb->tail - pdu_length, pdu_length) != 0xc704dd7b) {
+				atm_dbg(instance, "%s: packet failed crc check (vcc: 0x%p)!\n",
+						__func__, vcc);
+				atomic_inc(&vcc->stats->rx_err);
+				goto out;
+			}
+
+			vdbg("%s: got packet (length: %u, pdu_length: %u, vcc: 0x%p)", __func__, length, pdu_length, vcc);
+
+			if (!(skb = dev_alloc_skb(length))) {
+				atm_dbg(instance, "%s: no memory for skb (length: %u)!\n", __func__, length);
+				atomic_inc(&vcc->stats->rx_drop);
+				goto out;
+			}
+
+			vdbg("%s: allocated new sk_buff (skb: 0x%p, skb->truesize: %u)", __func__, skb, skb->truesize);
+
+			if (!atm_charge(vcc, skb->truesize)) {
+				atm_dbg(instance, "%s: failed atm_charge (skb->truesize: %u)!\n", __func__, skb->truesize);
+				dev_kfree_skb(skb);
+				goto out;	/* atm_charge increments rx_drop */
+			}
+
+			memcpy(skb->data, sarb->tail - pdu_length, length);
+			__skb_put(skb, length);
+
+			vdbg("%s: sending skb 0x%p, skb->len %u, skb->truesize %u",
+			     __func__, skb, skb->len, skb->truesize);
+
+			PACKETDEBUG(skb->data, skb->len);
+
+			vcc->push(vcc, skb);
+
+			atomic_inc(&vcc->stats->rx);
+		out:
+			skb_trim(sarb, 0);
+		}
+	}
+}
+
+
+/*************
+**  encode  **
+*************/
+
+static unsigned int usbatm_write_cells(struct usbatm_data *instance,
+				       struct sk_buff *skb,
+				       u8 *target, unsigned int avail_space)
+{
+	struct usbatm_control *ctrl = UDSL_SKB(skb);
+	struct atm_vcc *vcc = ctrl->atm.vcc;
+	unsigned int num_written;
+	unsigned int stride = instance->tx_channel.stride;
+
+	vdbg("%s: skb->len=%d, avail_space=%u", __func__, skb->len, avail_space);
+	UDSL_ASSERT(!(avail_space % stride));
+
+	for (num_written = 0; num_written < avail_space && ctrl->len;
+	     num_written += stride, target += stride) {
+		unsigned int data_len = min_t(unsigned int, skb->len, ATM_CELL_PAYLOAD);
+		unsigned int left = ATM_CELL_PAYLOAD - data_len;
+		u8 *ptr = target;
+
+		ptr[0] = vcc->vpi >> 4;
+		ptr[1] = (vcc->vpi << 4) | (vcc->vci >> 12);
+		ptr[2] = vcc->vci >> 4;
+		ptr[3] = vcc->vci << 4;
+		ptr[4] = 0xec;
+		ptr += ATM_CELL_HEADER;
+
+		memcpy(ptr, skb->data, data_len);
+		ptr += data_len;
+		__skb_pull(skb, data_len);
+
+		if(!left)
+			continue;
+
+		memset(ptr, 0, left);
+
+		if (left >= ATM_AAL5_TRAILER) {	/* trailer will go in this cell */
+			u8 *trailer = target + ATM_CELL_SIZE - ATM_AAL5_TRAILER;
+			/* trailer[0] = 0;		UU = 0 */
+			/* trailer[1] = 0;		CPI = 0 */
+			trailer[2] = ctrl->len >> 8;
+			trailer[3] = ctrl->len;
+
+			ctrl->crc = ~ crc32_be(ctrl->crc, ptr, left - 4);
+
+			trailer[4] = ctrl->crc >> 24;
+			trailer[5] = ctrl->crc >> 16;
+			trailer[6] = ctrl->crc >> 8;
+			trailer[7] = ctrl->crc;
+
+			target[3] |= 0x2;	/* adjust PTI */
+
+			ctrl->len = 0;		/* tag this skb finished */
+		}
+		else
+			ctrl->crc = crc32_be(ctrl->crc, ptr, left);
+	}
+
+	return num_written;
+}
+
+
+/**************
+**  receive  **
+**************/
+
+static void usbatm_rx_process(unsigned long data)
+{
+	struct usbatm_data *instance = (struct usbatm_data *)data;
+	struct urb *urb;
+
+	while ((urb = usbatm_pop_urb(&instance->rx_channel))) {
+		vdbg("%s: processing urb 0x%p", __func__, urb);
+
+		if (usb_pipeisoc(urb->pipe)) {
+			int i;
+			for (i = 0; i < urb->number_of_packets; i++)
+				if (!urb->iso_frame_desc[i].status)
+					usbatm_extract_cells(instance,
+							     (u8 *)urb->transfer_buffer + urb->iso_frame_desc[i].offset,
+							     urb->iso_frame_desc[i].actual_length);
+		}
+		else
+			if (!urb->status)
+				usbatm_extract_cells(instance, urb->transfer_buffer, urb->actual_length);
+
+		if (usbatm_submit_urb(urb))
+			return;
+	}
+}
+
+
+/***********
+**  send  **
+***********/
+
+static void usbatm_tx_process(unsigned long data)
+{
+	struct usbatm_data *instance = (struct usbatm_data *)data;
+	struct sk_buff *skb = instance->current_skb;
+	struct urb *urb = NULL;
+	const unsigned int buf_size = instance->tx_channel.buf_size;
+	unsigned int num_written = 0;
+	u8 *buffer = NULL;
+
+	if (!skb)
+		skb = skb_dequeue(&instance->sndqueue);
+
+	while (skb) {
+		if (!urb) {
+			urb = usbatm_pop_urb(&instance->tx_channel);
+			if (!urb)
+				break;		/* no more senders */
+			buffer = urb->transfer_buffer;
+			num_written = (urb->status == -EAGAIN) ?
+				urb->transfer_buffer_length : 0;
+		}
+
+		num_written += usbatm_write_cells(instance, skb,
+						  buffer + num_written,
+						  buf_size - num_written);
+
+		vdbg("%s: wrote %u bytes from skb 0x%p to urb 0x%p",
+		     __func__, num_written, skb, urb);
+
+		if (!UDSL_SKB(skb)->len) {
+			struct atm_vcc *vcc = UDSL_SKB(skb)->atm.vcc;
+
+			usbatm_pop(vcc, skb);
+			atomic_inc(&vcc->stats->tx);
+
+			skb = skb_dequeue(&instance->sndqueue);
+		}
+
+		if (num_written == buf_size || (!skb && num_written)) {
+			urb->transfer_buffer_length = num_written;
+
+			if (usbatm_submit_urb(urb))
+				break;
+			urb = NULL;
+		}
+	}
+
+	instance->current_skb = skb;
+}
+
+static void usbatm_cancel_send(struct usbatm_data *instance,
+			       struct atm_vcc *vcc)
+{
+	struct sk_buff *skb, *n;
+
+	atm_dbg(instance, "%s entered\n", __func__);
+	spin_lock_irq(&instance->sndqueue.lock);
+	for (skb = instance->sndqueue.next, n = skb->next;
+	     skb != (struct sk_buff *)&instance->sndqueue;
+	     skb = n, n = skb->next)
+		if (UDSL_SKB(skb)->atm.vcc == vcc) {
+			atm_dbg(instance, "%s: popping skb 0x%p\n", __func__, skb);
+			__skb_unlink(skb, &instance->sndqueue);
+			usbatm_pop(vcc, skb);
+		}
+	spin_unlock_irq(&instance->sndqueue.lock);
+
+	tasklet_disable(&instance->tx_channel.tasklet);
+	if ((skb = instance->current_skb) && (UDSL_SKB(skb)->atm.vcc == vcc)) {
+		atm_dbg(instance, "%s: popping current skb (0x%p)\n", __func__, skb);
+		instance->current_skb = NULL;
+		usbatm_pop(vcc, skb);
+	}
+	tasklet_enable(&instance->tx_channel.tasklet);
+	atm_dbg(instance, "%s done\n", __func__);
+}
+
+static int usbatm_atm_send(struct atm_vcc *vcc, struct sk_buff *skb)
+{
+	struct usbatm_data *instance = vcc->dev->dev_data;
+	struct usbatm_control *ctrl = UDSL_SKB(skb);
+	int err;
+
+	vdbg("%s called (skb 0x%p, len %u)", __func__, skb, skb->len);
+
+	if (!instance) {
+		dbg("%s: NULL data!", __func__);
+		err = -ENODEV;
+		goto fail;
+	}
+
+	if (vcc->qos.aal != ATM_AAL5) {
+		atm_dbg(instance, "%s: unsupported ATM type %d!\n", __func__, vcc->qos.aal);
+		err = -EINVAL;
+		goto fail;
+	}
+
+	if (skb->len > ATM_MAX_AAL5_PDU) {
+		atm_dbg(instance, "%s: packet too long (%d vs %d)!\n",
+				__func__, skb->len, ATM_MAX_AAL5_PDU);
+		err = -EINVAL;
+		goto fail;
+	}
+
+	PACKETDEBUG(skb->data, skb->len);
+
+	/* initialize the control block */
+	ctrl->atm.vcc = vcc;
+	ctrl->len = skb->len;
+	ctrl->crc = crc32_be(~0, skb->data, skb->len);
+
+	skb_queue_tail(&instance->sndqueue, skb);
+	tasklet_schedule(&instance->tx_channel.tasklet);
+
+	return 0;
+
+ fail:
+	usbatm_pop(vcc, skb);
+	return err;
+}
+
+
+/********************
+**  bean counting  **
+********************/
+
+static void usbatm_destroy_instance(struct kref *kref)
+{
+	struct usbatm_data *instance = container_of(kref, struct usbatm_data, refcount);
+
+	dbg("%s", __func__);
+
+	tasklet_kill(&instance->rx_channel.tasklet);
+	tasklet_kill(&instance->tx_channel.tasklet);
+	usb_put_dev(instance->usb_dev);
+	kfree(instance);
+}
+
+void usbatm_get_instance(struct usbatm_data *instance)
+{
+	dbg("%s", __func__);
+
+	kref_get(&instance->refcount);
+}
+
+void usbatm_put_instance(struct usbatm_data *instance)
+{
+	dbg("%s", __func__);
+
+	kref_put(&instance->refcount, usbatm_destroy_instance);
+}
+
+
+/**********
+**  ATM  **
+**********/
+
+static void usbatm_atm_dev_close(struct atm_dev *dev)
+{
+	struct usbatm_data *instance = dev->dev_data;
+
+	dbg("%s", __func__);
+
+	if (!instance)
+		return;
+
+	dev->dev_data = NULL;
+	usbatm_put_instance(instance);	/* taken in usbatm_atm_init */
+}
+
+static int usbatm_atm_proc_read(struct atm_dev *atm_dev, loff_t * pos, char *page)
+{
+	struct usbatm_data *instance = atm_dev->dev_data;
+	int left = *pos;
+
+	if (!instance) {
+		dbg("%s: NULL instance!", __func__);
+		return -ENODEV;
+	}
+
+	if (!left--)
+		return sprintf(page, "%s\n", instance->description);
+
+	if (!left--)
+		return sprintf(page, "MAC: %02x:%02x:%02x:%02x:%02x:%02x\n",
+			       atm_dev->esi[0], atm_dev->esi[1],
+			       atm_dev->esi[2], atm_dev->esi[3],
+			       atm_dev->esi[4], atm_dev->esi[5]);
+
+	if (!left--)
+		return sprintf(page,
+			       "AAL5: tx %d ( %d err ), rx %d ( %d err, %d drop )\n",
+			       atomic_read(&atm_dev->stats.aal5.tx),
+			       atomic_read(&atm_dev->stats.aal5.tx_err),
+			       atomic_read(&atm_dev->stats.aal5.rx),
+			       atomic_read(&atm_dev->stats.aal5.rx_err),
+			       atomic_read(&atm_dev->stats.aal5.rx_drop));
+
+	if (!left--)
+		switch (atm_dev->signal) {
+		case ATM_PHY_SIG_FOUND:
+			return sprintf(page, "Line up\n");
+		case ATM_PHY_SIG_LOST:
+			return sprintf(page, "Line down\n");
+		default:
+			return sprintf(page, "Line state unknown\n");
+		}
+
+	return 0;
+}
+
+static int usbatm_atm_open(struct atm_vcc *vcc)
+{
+	struct usbatm_data *instance = vcc->dev->dev_data;
+	struct usbatm_vcc_data *new = NULL;
+	int ret;
+	int vci = vcc->vci;
+	short vpi = vcc->vpi;
+
+	if (!instance) {
+		dbg("%s: NULL data!", __func__);
+		return -ENODEV;
+	}
+
+	atm_dbg(instance, "%s: vpi %hd, vci %d\n", __func__, vpi, vci);
+
+	/* only support AAL5 */
+	if ((vcc->qos.aal != ATM_AAL5) || (vcc->qos.rxtp.max_sdu < 0)
+	    || (vcc->qos.rxtp.max_sdu > ATM_MAX_AAL5_PDU)) {
+		atm_dbg(instance, "%s: unsupported ATM type %d!\n", __func__, vcc->qos.aal);
+		return -EINVAL;
+	}
+
+	down(&instance->serialize);	/* vs self, usbatm_atm_close */
+
+	if (usbatm_find_vcc(instance, vpi, vci)) {
+		atm_dbg(instance, "%s: %hd/%d already in use!\n", __func__, vpi, vci);
+		ret = -EADDRINUSE;
+		goto fail;
+	}
+
+	if (!(new = kmalloc(sizeof(struct usbatm_vcc_data), GFP_KERNEL))) {
+		atm_dbg(instance, "%s: no memory for vcc_data!\n", __func__);
+		ret = -ENOMEM;
+		goto fail;
+	}
+
+	memset(new, 0, sizeof(struct usbatm_vcc_data));
+	new->vcc = vcc;
+	new->vpi = vpi;
+	new->vci = vci;
+
+	new->sarb = alloc_skb(usbatm_pdu_length(vcc->qos.rxtp.max_sdu), GFP_KERNEL);
+	if (!new->sarb) {
+		atm_dbg(instance, "%s: no memory for SAR buffer!\n", __func__);
+		ret = -ENOMEM;
+		goto fail;
+	}
+
+	vcc->dev_data = new;
+
+	tasklet_disable(&instance->rx_channel.tasklet);
+	list_add(&new->list, &instance->vcc_list);
+	tasklet_enable(&instance->rx_channel.tasklet);
+
+	set_bit(ATM_VF_ADDR, &vcc->flags);
+	set_bit(ATM_VF_PARTIAL, &vcc->flags);
+	set_bit(ATM_VF_READY, &vcc->flags);
+
+	up(&instance->serialize);
+
+	atm_dbg(instance, "%s: allocated vcc data 0x%p\n", __func__, new);
+
+	return 0;
+
+fail:
+	kfree(new);
+	up(&instance->serialize);
+	return ret;
+}
+
+static void usbatm_atm_close(struct atm_vcc *vcc)
+{
+	struct usbatm_data *instance = vcc->dev->dev_data;
+	struct usbatm_vcc_data *vcc_data = vcc->dev_data;
+
+	if (!instance || !vcc_data) {
+		dbg("%s: NULL data!", __func__);
+		return;
+	}
+
+	atm_dbg(instance, "%s entered\n", __func__);
+
+	atm_dbg(instance, "%s: deallocating vcc 0x%p with vpi %d vci %d\n",
+		__func__, vcc_data, vcc_data->vpi, vcc_data->vci);
+
+	usbatm_cancel_send(instance, vcc);
+
+	down(&instance->serialize);	/* vs self, usbatm_atm_open */
+
+	tasklet_disable(&instance->rx_channel.tasklet);
+	list_del(&vcc_data->list);
+	tasklet_enable(&instance->rx_channel.tasklet);
+
+	kfree_skb(vcc_data->sarb);
+	vcc_data->sarb = NULL;
+
+	kfree(vcc_data);
+	vcc->dev_data = NULL;
+
+	vcc->vpi = ATM_VPI_UNSPEC;
+	vcc->vci = ATM_VCI_UNSPEC;
+	clear_bit(ATM_VF_READY, &vcc->flags);
+	clear_bit(ATM_VF_PARTIAL, &vcc->flags);
+	clear_bit(ATM_VF_ADDR, &vcc->flags);
+
+	up(&instance->serialize);
+
+	atm_dbg(instance, "%s successful\n", __func__);
+}
+
+static int usbatm_atm_ioctl(struct atm_dev *dev, unsigned int cmd,
+			  void __user * arg)
+{
+	switch (cmd) {
+	case ATM_QUERYLOOP:
+		return put_user(ATM_LM_NONE, (int __user *)arg) ? -EFAULT : 0;
+	default:
+		return -ENOIOCTLCMD;
+	}
+}
+
+static int usbatm_atm_init(struct usbatm_data *instance)
+{
+	struct atm_dev *atm_dev;
+	int ret, i;
+
+	/* ATM init */
+	atm_dev = atm_dev_register(instance->driver_name, &usbatm_atm_devops, -1, NULL);
+	if (!atm_dev) {
+		usb_dbg(instance, "%s: failed to register ATM device!\n", __func__);
+		return -1;
+	}
+
+	instance->atm_dev = atm_dev;
+
+	atm_dev->ci_range.vpi_bits = ATM_CI_MAX;
+	atm_dev->ci_range.vci_bits = ATM_CI_MAX;
+	atm_dev->signal = ATM_PHY_SIG_UNKNOWN;
+
+	/* temp init ATM device, set to 128kbit */
+	atm_dev->link_rate = 128 * 1000 / 424;
+
+	if (instance->driver->atm_start && ((ret = instance->driver->atm_start(instance, atm_dev)) < 0)) {
+		atm_dbg(instance, "%s: atm_start failed: %d!\n", __func__, ret);
+		goto fail;
+	}
+
+	/* ready for ATM callbacks */
+	usbatm_get_instance(instance);	/* dropped in usbatm_atm_dev_close */
+	mb();
+	atm_dev->dev_data = instance;
+
+	/* submit all rx URBs */
+	for (i = 0; i < num_rcv_urbs; i++)
+		usbatm_submit_urb(instance->urbs[i]);
+
+	return 0;
+
+ fail:
+	instance->atm_dev = NULL;
+	shutdown_atm_dev(atm_dev); /* usbatm_atm_dev_close will eventually be called */
+	return ret;
+}
+
+
+/**********
+**  USB  **
+**********/
+
+static int usbatm_do_heavy_init(void *arg)
+{
+	struct usbatm_data *instance = arg;
+	int ret;
+
+	daemonize(instance->driver->driver_name);
+	allow_signal(SIGTERM);
+
+	complete(&instance->thread_started);
+
+	ret = instance->driver->heavy_init(instance, instance->usb_intf);
+
+	if (!ret)
+		ret = usbatm_atm_init(instance);
+
+	down(&instance->serialize);
+	instance->thread_pid = -1;
+	up(&instance->serialize);
+
+	complete_and_exit(&instance->thread_exited, ret);
+}
+
+static int usbatm_heavy_init(struct usbatm_data *instance)
+{
+	int ret = kernel_thread(usbatm_do_heavy_init, instance, CLONE_KERNEL);
+
+	if (ret < 0) {
+		usb_dbg(instance, "%s: failed to create kernel_thread (%d)!\n", __func__, ret);
+		return ret;
+	}
+
+	down(&instance->serialize);
+	instance->thread_pid = ret;
+	up(&instance->serialize);
+
+	wait_for_completion(&instance->thread_started);
+
+	return 0;
+}
+
+static void usbatm_tasklet_schedule(unsigned long data)
+{
+	tasklet_schedule((struct tasklet_struct *) data);
+}
+
+static inline void usbatm_init_channel(struct usbatm_channel *channel)
+{
+	spin_lock_init(&channel->lock);
+	INIT_LIST_HEAD(&channel->list);
+	channel->delay.function = usbatm_tasklet_schedule;
+	channel->delay.data = (unsigned long) &channel->tasklet;
+	init_timer(&channel->delay);
+}
+
+int usbatm_usb_probe(struct usb_interface *intf, const struct usb_device_id *id,
+		     struct usbatm_driver *driver)
+{
+	struct device *dev = &intf->dev;
+	struct usb_device *usb_dev = interface_to_usbdev(intf);
+	struct usbatm_data *instance;
+	char *buf;
+	int error = -ENOMEM;
+	int i, length;
+	int need_heavy;
+
+	dev_dbg(dev, "%s: trying driver %s with vendor=0x%x, product=0x%x, ifnum %d\n",
+			__func__, driver->driver_name,
+			le16_to_cpu(usb_dev->descriptor.idVendor),
+			le16_to_cpu(usb_dev->descriptor.idProduct),
+			intf->altsetting->desc.bInterfaceNumber);
+
+	/* instance init */
+	instance = kcalloc(1, sizeof(*instance) + sizeof(struct urb *) * (num_rcv_urbs + num_snd_urbs), GFP_KERNEL);
+	if (!instance) {
+		dev_dbg(dev, "%s: no memory for instance data!\n", __func__);
+		return -ENOMEM;
+	}
+
+	/* public fields */
+
+	instance->driver = driver;
+	snprintf(instance->driver_name, sizeof(instance->driver_name), driver->driver_name);
+
+	instance->usb_dev = usb_dev;
+	instance->usb_intf = intf;
+
+	buf = instance->description;
+	length = sizeof(instance->description);
+
+	if ((i = usb_string(usb_dev, usb_dev->descriptor.iProduct, buf, length)) < 0)
+		goto bind;
+
+	buf += i;
+	length -= i;
+
+	i = scnprintf(buf, length, " (");
+	buf += i;
+	length -= i;
+
+	if (length <= 0 || (i = usb_make_path(usb_dev, buf, length)) < 0)
+		goto bind;
+
+	buf += i;
+	length -= i;
+
+	snprintf(buf, length, ")");
+
+ bind:
+	need_heavy = 1;
+	if (driver->bind && (error = driver->bind(instance, intf, id, &need_heavy)) < 0) {
+			dev_dbg(dev, "%s: bind failed: %d!\n", __func__, error);
+			goto fail_free;
+	}
+
+	/* private fields */
+
+	kref_init(&instance->refcount);		/* dropped in usbatm_usb_disconnect */
+	init_MUTEX(&instance->serialize);
+
+	instance->thread_pid = -1;
+	init_completion(&instance->thread_started);
+	init_completion(&instance->thread_exited);
+
+	INIT_LIST_HEAD(&instance->vcc_list);
+
+	usbatm_init_channel(&instance->rx_channel);
+	usbatm_init_channel(&instance->tx_channel);
+	tasklet_init(&instance->rx_channel.tasklet, usbatm_rx_process, (unsigned long)instance);
+	tasklet_init(&instance->tx_channel.tasklet, usbatm_tx_process, (unsigned long)instance);
+	instance->rx_channel.endpoint = usb_rcvbulkpipe(usb_dev, driver->in);
+	instance->tx_channel.endpoint = usb_sndbulkpipe(usb_dev, driver->out);
+	instance->rx_channel.stride = ATM_CELL_SIZE + driver->rx_padding;
+	instance->tx_channel.stride = ATM_CELL_SIZE + driver->tx_padding;
+	instance->rx_channel.buf_size = rcv_buf_size * instance->rx_channel.stride;
+	instance->tx_channel.buf_size = snd_buf_size * instance->tx_channel.stride;
+	instance->rx_channel.usbatm = instance->tx_channel.usbatm = instance;
+
+	skb_queue_head_init(&instance->sndqueue);
+
+	for (i = 0; i < num_rcv_urbs + num_snd_urbs; i++) {
+		struct urb *urb;
+		u8 *buffer;
+		unsigned int iso_packets = 0, iso_size = 0;
+		struct usbatm_channel *channel = i < num_rcv_urbs ?
+			&instance->rx_channel : &instance->tx_channel;
+
+		if (usb_pipeisoc(channel->endpoint)) {
+			/* don't expect iso out endpoints */
+			iso_size = usb_maxpacket(instance->usb_dev, channel->endpoint, 0);
+			iso_size -= iso_size % channel->stride;	/* alignment */
+			BUG_ON(!iso_size);
+			iso_packets = (channel->buf_size - 1) / iso_size + 1;
+		}
+
+		urb = usb_alloc_urb(iso_packets, GFP_KERNEL);
+		if (!urb) {
+			dev_dbg(dev, "%s: no memory for urb %d!\n", __func__, i);
+			goto fail_unbind;
+		}
+
+		instance->urbs[i] = urb;
+
+		buffer = kmalloc(channel->buf_size, GFP_KERNEL);
+		if (!buffer) {
+			dev_dbg(dev, "%s: no memory for buffer %d!\n", __func__, i);
+			goto fail_unbind;
+		}
+		memset(buffer, 0, channel->buf_size);
+
+		usb_fill_bulk_urb(urb, instance->usb_dev, channel->endpoint,
+				  buffer, channel->buf_size, usbatm_complete, channel);
+		if (iso_packets) {
+			int j;
+			urb->interval = 1;
+			urb->transfer_flags = URB_ISO_ASAP;
+			urb->number_of_packets = iso_packets;
+			for (j = 0; j < iso_packets; j++) {
+				urb->iso_frame_desc[j].offset = iso_size * j;
+				urb->iso_frame_desc[j].length = min_t(int, iso_size,
+								      channel->buf_size - urb->iso_frame_desc[j].offset);
+			}
+		}
+
+		/* put all tx URBs on the list of spares */
+		if (i >= num_rcv_urbs)
+			list_add_tail(&urb->urb_list, &channel->list);
+
+		vdbg("%s: alloced buffer 0x%p buf size %u urb 0x%p",
+		     __func__, urb->transfer_buffer, urb->transfer_buffer_length, urb);
+	}
+
+	if (need_heavy && driver->heavy_init) {
+		error = usbatm_heavy_init(instance);
+	} else {
+		complete(&instance->thread_exited);	/* pretend that heavy_init was run */
+		error = usbatm_atm_init(instance);
+	}
+
+	if (error < 0)
+		goto fail_unbind;
+
+	usb_get_dev(usb_dev);
+	usb_set_intfdata(intf, instance);
+
+	return 0;
+
+ fail_unbind:
+	if (instance->driver->unbind)
+		instance->driver->unbind(instance, intf);
+ fail_free:
+	for (i = 0; i < num_rcv_urbs + num_snd_urbs; i++) {
+		if (instance->urbs[i])
+			kfree(instance->urbs[i]->transfer_buffer);
+		usb_free_urb(instance->urbs[i]);
+	}
+
+	kfree (instance);
+
+	return error;
+}
+EXPORT_SYMBOL_GPL(usbatm_usb_probe);
+
+void usbatm_usb_disconnect(struct usb_interface *intf)
+{
+	struct device *dev = &intf->dev;
+	struct usbatm_data *instance = usb_get_intfdata(intf);
+	int i;
+
+	dev_dbg(dev, "%s entered\n", __func__);
+
+	if (!instance) {
+		dev_dbg(dev, "%s: NULL instance!\n", __func__);
+		return;
+	}
+
+	usb_set_intfdata(intf, NULL);
+
+	down(&instance->serialize);
+	if (instance->thread_pid >= 0)
+		kill_proc(instance->thread_pid, SIGTERM, 1);
+	up(&instance->serialize);
+
+	wait_for_completion(&instance->thread_exited);
+
+	tasklet_disable(&instance->rx_channel.tasklet);
+	tasklet_disable(&instance->tx_channel.tasklet);
+
+	for (i = 0; i < num_rcv_urbs + num_snd_urbs; i++)
+		usb_kill_urb(instance->urbs[i]);
+
+	del_timer_sync(&instance->rx_channel.delay);
+	del_timer_sync(&instance->tx_channel.delay);
+
+	if (instance->atm_dev && instance->driver->atm_stop)
+		instance->driver->atm_stop(instance, instance->atm_dev);
+
+	if (instance->driver->unbind)
+		instance->driver->unbind(instance, intf);
+
+	instance->driver_data = NULL;
+
+	/* turn usbatm_[rt]x_process into noop */
+	/* no need to take the spinlock */
+	INIT_LIST_HEAD(&instance->rx_channel.list);
+	INIT_LIST_HEAD(&instance->tx_channel.list);
+
+	tasklet_enable(&instance->rx_channel.tasklet);
+	tasklet_enable(&instance->tx_channel.tasklet);
+
+	for (i = 0; i < num_rcv_urbs + num_snd_urbs; i++) {
+		kfree(instance->urbs[i]->transfer_buffer);
+		usb_free_urb(instance->urbs[i]);
+	}
+
+	/* ATM finalize */
+	if (instance->atm_dev)
+		shutdown_atm_dev(instance->atm_dev);
+
+	usbatm_put_instance(instance);	/* taken in usbatm_usb_probe */
+}
+EXPORT_SYMBOL_GPL(usbatm_usb_disconnect);
+
+
+/***********
+**  init  **
+***********/
+
+static int __init usbatm_usb_init(void)
+{
+	dbg("%s: driver version %s", __func__, DRIVER_VERSION);
+
+	if (sizeof(struct usbatm_control) > sizeof(((struct sk_buff *) 0)->cb)) {
+		printk(KERN_ERR "%s unusable with this kernel!\n", usbatm_driver_name);
+		return -EIO;
+	}
+
+	if ((num_rcv_urbs > UDSL_MAX_RCV_URBS)
+	    || (num_snd_urbs > UDSL_MAX_SND_URBS)
+	    || (rcv_buf_size < 1)
+	    || (rcv_buf_size > UDSL_MAX_RCV_BUF_SIZE)
+	    || (snd_buf_size < 1)
+	    || (snd_buf_size > UDSL_MAX_SND_BUF_SIZE))
+		return -EINVAL;
+
+	return 0;
+}
+module_init(usbatm_usb_init);
+
+static void __exit usbatm_usb_exit(void)
+{
+	dbg("%s", __func__);
+}
+module_exit(usbatm_usb_exit);
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRIVER_VERSION);
+
+/************
+**  debug  **
+************/
+
+#ifdef VERBOSE_DEBUG
+static int usbatm_print_packet(const unsigned char *data, int len)
+{
+	unsigned char buffer[256];
+	int i = 0, j = 0;
+
+	for (i = 0; i < len;) {
+		buffer[0] = '\0';
+		sprintf(buffer, "%.3d :", i);
+		for (j = 0; (j < 16) && (i < len); j++, i++) {
+			sprintf(buffer, "%s %2.2x", buffer, data[i]);
+		}
+		dbg("%s", buffer);
+	}
+	return i;
+}
+#endif
diff --git a/drivers/usb/atm/usbatm.h b/drivers/usb/atm/usbatm.h
new file mode 100644
--- /dev/null
+++ b/drivers/usb/atm/usbatm.h
@@ -0,0 +1,184 @@
+/******************************************************************************
+ *  usbatm.h - Generic USB xDSL driver core
+ *
+ *  Copyright (C) 2001, Alcatel
+ *  Copyright (C) 2003, Duncan Sands, SolNegro, Josep Comas
+ *  Copyright (C) 2004, David Woodhouse
+ *
+ *  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	_USBATM_H_
+#define	_USBATM_H_
+
+#include <linux/config.h>
+
+/*
+#define DEBUG
+#define VERBOSE_DEBUG
+*/
+
+#if !defined (DEBUG) && defined (CONFIG_USB_DEBUG)
+#	define DEBUG
+#endif
+
+#include <asm/semaphore.h>
+#include <linux/atm.h>
+#include <linux/atmdev.h>
+#include <linux/completion.h>
+#include <linux/device.h>
+#include <linux/kref.h>
+#include <linux/list.h>
+#include <linux/stringify.h>
+#include <linux/usb.h>
+
+#ifdef DEBUG
+#define UDSL_ASSERT(x)	BUG_ON(!(x))
+#else
+#define UDSL_ASSERT(x)	do { if (!(x)) warn("failed assertion '%s' at line %d", __stringify(x), __LINE__); } while(0)
+#endif
+
+#define usb_err(instance, format, arg...)	\
+	dev_err(&(instance)->usb_intf->dev , format , ## arg)
+#define usb_info(instance, format, arg...)	\
+	dev_info(&(instance)->usb_intf->dev , format , ## arg)
+#define usb_warn(instance, format, arg...)	\
+	dev_warn(&(instance)->usb_intf->dev , format , ## arg)
+#define usb_dbg(instance, format, arg...)	\
+	dev_dbg(&(instance)->usb_intf->dev , format , ## arg)
+
+/* FIXME: move to dev_* once ATM is driver model aware */
+#define atm_printk(level, instance, format, arg...)	\
+	printk(level "ATM dev %d: " format ,		\
+	(instance)->atm_dev->number , ## arg)
+
+#define atm_err(instance, format, arg...)	\
+	atm_printk(KERN_ERR, instance , format , ## arg)
+#define atm_info(instance, format, arg...)	\
+	atm_printk(KERN_INFO, instance , format , ## arg)
+#define atm_warn(instance, format, arg...)	\
+	atm_printk(KERN_WARNING, instance , format , ## arg)
+#ifdef DEBUG
+#define atm_dbg(instance, format, arg...)	\
+	atm_printk(KERN_DEBUG, instance , format , ## arg)
+#else
+#define atm_dbg(instance, format, arg...)	\
+	do {} while (0)
+#endif
+
+
+/* mini driver */
+
+struct usbatm_data;
+
+/*
+*  Assuming all methods exist and succeed, they are called in this order:
+*
+*  	bind, heavy_init, atm_start, ..., atm_stop, unbind
+*/
+
+struct usbatm_driver {
+	struct module *owner;
+
+	const char *driver_name;
+
+	/*
+	*  init device ... can sleep, or cause probe() failure.  Drivers with a heavy_init
+	*  method can avoid having it called by setting need_heavy_init to zero.
+	*/
+        int (*bind) (struct usbatm_data *, struct usb_interface *,
+		     const struct usb_device_id *id, int *need_heavy_init);
+
+	/* additional device initialization that is too slow to be done in probe() */
+        int (*heavy_init) (struct usbatm_data *, struct usb_interface *);
+
+	/* cleanup device ... can sleep, but can't fail */
+        void (*unbind) (struct usbatm_data *, struct usb_interface *);
+
+	/* init ATM device ... can sleep, or cause ATM initialization failure */
+	int (*atm_start) (struct usbatm_data *, struct atm_dev *);
+
+	/* cleanup ATM device ... can sleep, but can't fail */
+	void (*atm_stop) (struct usbatm_data *, struct atm_dev *);
+
+        int in;		/* rx endpoint */
+        int out;	/* tx endpoint */
+
+	unsigned rx_padding;
+	unsigned tx_padding;
+};
+
+extern int usbatm_usb_probe(struct usb_interface *intf, const struct usb_device_id *id,
+		struct usbatm_driver *driver);
+extern void usbatm_usb_disconnect(struct usb_interface *intf);
+
+
+struct usbatm_channel {
+	int endpoint;			/* usb pipe */
+	unsigned int stride;		/* ATM cell size + padding */
+	unsigned int buf_size;		/* urb buffer size */
+	spinlock_t lock;
+	struct list_head list;
+	struct tasklet_struct tasklet;
+	struct timer_list delay;
+	struct usbatm_data *usbatm;
+};
+
+/* main driver data */
+
+struct usbatm_data {
+	/******************
+	*  public fields  *
+        ******************/
+
+	/* mini driver */
+	struct usbatm_driver *driver;
+	void *driver_data;
+	char driver_name[16];
+
+	/* USB device */
+	struct usb_device *usb_dev;
+	struct usb_interface *usb_intf;
+	char description[64];
+
+	/* ATM device */
+	struct atm_dev *atm_dev;
+
+	/********************************
+	*  private fields - do not use  *
+        ********************************/
+
+	struct kref refcount;
+	struct semaphore serialize;
+
+	/* heavy init */
+	int thread_pid;
+	struct completion thread_started;
+	struct completion thread_exited;
+
+	/* ATM device */
+	struct list_head vcc_list;
+
+	struct usbatm_channel rx_channel;
+	struct usbatm_channel tx_channel;
+
+	struct sk_buff_head sndqueue;
+	struct sk_buff *current_skb;			/* being emptied */
+
+	struct urb *urbs[0];
+};
+
+#endif	/* _USBATM_H_ */
diff --git a/drivers/usb/atm/xusbatm.c b/drivers/usb/atm/xusbatm.c
new file mode 100644
--- /dev/null
+++ b/drivers/usb/atm/xusbatm.c
@@ -0,0 +1,196 @@
+/******************************************************************************
+ *  xusbatm.c -	dumb usbatm-based driver for modems initialized in userspace
+ *
+ *  Copyright (C) 2005 Duncan Sands, Roman Kagan (rkagan % mail ! ru)
+ *
+ *  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/module.h>
+#include <linux/netdevice.h>		/* FIXME: required by linux/etherdevice.h */
+#include <linux/etherdevice.h>		/* for random_ether_addr() */
+
+#include "usbatm.h"
+
+
+#define XUSBATM_DRIVERS_MAX	8
+
+#define XUSBATM_PARM(name, type, parmtype, desc) \
+	static type name[XUSBATM_DRIVERS_MAX]; \
+	static int num_##name; \
+	module_param_array(name, parmtype, &num_##name, 0444); \
+	MODULE_PARM_DESC(name, desc)
+
+XUSBATM_PARM(vendor, unsigned short, ushort, "USB device vendor");
+XUSBATM_PARM(product, unsigned short, ushort, "USB device product");
+
+XUSBATM_PARM(rx_endpoint, unsigned char, byte, "rx endpoint number");
+XUSBATM_PARM(tx_endpoint, unsigned char, byte, "tx endpoint number");
+XUSBATM_PARM(rx_padding, unsigned char, byte, "rx padding (default 0)");
+XUSBATM_PARM(tx_padding, unsigned char, byte, "tx padding (default 0)");
+
+static const char xusbatm_driver_name[] = "xusbatm";
+
+static struct usbatm_driver xusbatm_drivers[XUSBATM_DRIVERS_MAX];
+static struct usb_device_id xusbatm_usb_ids[XUSBATM_DRIVERS_MAX + 1];
+static struct usb_driver xusbatm_usb_driver;
+
+static int usb_intf_has_ep(const struct usb_interface *intf, u8 ep)
+{
+	int i, j;
+
+	for (i = 0; i < intf->num_altsetting; i++) {
+		struct usb_host_interface *alt = intf->altsetting;
+		for (j = 0; j < alt->desc.bNumEndpoints; j++)
+			if ((alt->endpoint[i].desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK) == ep)
+				return 1;
+	}
+	return 0;
+}
+
+static int xusbatm_bind(struct usbatm_data *usbatm_instance,
+			struct usb_interface *intf, const struct usb_device_id *id,
+			int *need_heavy_init)
+{
+	struct usb_device *usb_dev = interface_to_usbdev(intf);
+	int drv_ix = id - xusbatm_usb_ids;
+	int rx_ep_present = usb_intf_has_ep(intf, rx_endpoint[drv_ix]);
+	int tx_ep_present = usb_intf_has_ep(intf, tx_endpoint[drv_ix]);
+	u8 searched_ep = rx_ep_present ? tx_endpoint[drv_ix] : rx_endpoint[drv_ix];
+	int i, ret;
+
+	usb_dbg(usbatm_instance, "%s: binding driver %d: vendor %#x product %#x"
+		" rx: ep %#x padd %d tx: ep %#x padd %d\n",
+		__func__, drv_ix, vendor[drv_ix], product[drv_ix],
+		rx_endpoint[drv_ix], rx_padding[drv_ix],
+		tx_endpoint[drv_ix], tx_padding[drv_ix]);
+
+	if (!rx_ep_present && !tx_ep_present) {
+		usb_dbg(usbatm_instance, "%s: intf #%d has neither rx (%#x) nor tx (%#x) endpoint\n",
+			__func__, intf->altsetting->desc.bInterfaceNumber,
+			rx_endpoint[drv_ix], tx_endpoint[drv_ix]);
+		return -ENODEV;
+	}
+
+	if (rx_ep_present && tx_ep_present)
+		return 0;
+
+	for(i = 0; i < usb_dev->actconfig->desc.bNumInterfaces; i++) {
+		struct usb_interface *cur_if = usb_dev->actconfig->interface[i];
+
+		if (cur_if != intf && usb_intf_has_ep(cur_if, searched_ep)) {
+			ret = usb_driver_claim_interface(&xusbatm_usb_driver,
+							 cur_if, usbatm_instance);
+			if (!ret)
+				usb_err(usbatm_instance, "%s: failed to claim interface #%d (%d)\n",
+					__func__, cur_if->altsetting->desc.bInterfaceNumber, ret);
+			return ret;
+		}
+	}
+
+	usb_err(usbatm_instance, "%s: no interface has endpoint %#x\n",
+		__func__, searched_ep);
+	return -ENODEV;
+}
+
+static void xusbatm_unbind(struct usbatm_data *usbatm_instance,
+			   struct usb_interface *intf)
+{
+	struct usb_device *usb_dev = interface_to_usbdev(intf);
+	int i;
+	usb_dbg(usbatm_instance, "%s entered\n", __func__);
+
+	for(i = 0; i < usb_dev->actconfig->desc.bNumInterfaces; i++) {
+		struct usb_interface *cur_if = usb_dev->actconfig->interface[i];
+		usb_set_intfdata(cur_if, NULL);
+		usb_driver_release_interface(&xusbatm_usb_driver, cur_if);
+	}
+}
+
+static int xusbatm_atm_start(struct usbatm_data *usbatm_instance,
+			     struct atm_dev *atm_dev)
+{
+	atm_dbg(usbatm_instance, "%s entered\n", __func__);
+
+	/* use random MAC as we've no way to get it from the device */
+	random_ether_addr(atm_dev->esi);
+
+	return 0;
+}
+
+
+static int xusbatm_usb_probe(struct usb_interface *intf,
+			     const struct usb_device_id *id)
+{
+	return usbatm_usb_probe(intf, id,
+				xusbatm_drivers + (id - xusbatm_usb_ids));
+}
+
+static struct usb_driver xusbatm_usb_driver = {
+	.owner		= THIS_MODULE,
+	.name		= xusbatm_driver_name,
+	.probe		= xusbatm_usb_probe,
+	.disconnect	= usbatm_usb_disconnect,
+	.id_table	= xusbatm_usb_ids
+};
+
+static int __init xusbatm_init(void)
+{
+	int i;
+
+	dbg("xusbatm_init");
+
+	if (!num_vendor ||
+	    num_vendor != num_product ||
+	    num_vendor != num_rx_endpoint ||
+	    num_vendor != num_tx_endpoint) {
+		warn("malformed module parameters");
+		return -EINVAL;
+	}
+
+	for (i = 0; i < num_vendor; i++) {
+		xusbatm_usb_ids[i].match_flags	= USB_DEVICE_ID_MATCH_DEVICE;
+		xusbatm_usb_ids[i].idVendor	= vendor[i];
+		xusbatm_usb_ids[i].idProduct	= product[i];
+
+
+		xusbatm_drivers[i].owner	= THIS_MODULE;
+		xusbatm_drivers[i].driver_name	= xusbatm_driver_name;
+		xusbatm_drivers[i].bind		= xusbatm_bind;
+		xusbatm_drivers[i].unbind	= xusbatm_unbind;
+		xusbatm_drivers[i].atm_start	= xusbatm_atm_start;
+		xusbatm_drivers[i].in		= rx_endpoint[i];
+		xusbatm_drivers[i].out		= tx_endpoint[i];
+		xusbatm_drivers[i].rx_padding	= rx_padding[i];
+		xusbatm_drivers[i].tx_padding	= tx_padding[i];
+	}
+
+	return usb_register(&xusbatm_usb_driver);
+}
+module_init(xusbatm_init);
+
+static void __exit xusbatm_exit(void)
+{
+	dbg("xusbatm_exit entered");
+
+	usb_deregister(&xusbatm_usb_driver);
+}
+module_exit(xusbatm_exit);
+
+MODULE_AUTHOR("Roman Kagan, Duncan Sands");
+MODULE_DESCRIPTION("Driver for USB ADSL modems initialized in userspace");
+MODULE_LICENSE("GPL");
+MODULE_VERSION("0.1");
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -106,6 +106,111 @@ static int acm_ctrl_msg(struct acm *acm,
 	acm_ctrl_msg(acm, USB_CDC_REQ_SEND_BREAK, ms, NULL, 0)
 
 /*
+ * Write buffer management.
+ * All of these assume proper locks taken by the caller.
+ */
+
+static int acm_wb_alloc(struct acm *acm)
+{
+	int i, wbn;
+	struct acm_wb *wb;
+
+	wbn = acm->write_current;
+	i = 0;
+	for (;;) {
+		wb = &acm->wb[wbn];
+		if (!wb->use) {
+			wb->use = 1;
+			return wbn;
+		}
+		wbn = (wbn + 1) % ACM_NWB;
+		if (++i >= ACM_NWB)
+			return -1;
+	}
+}
+
+static void acm_wb_free(struct acm *acm, int wbn)
+{
+	acm->wb[wbn].use = 0;
+}
+
+static int acm_wb_is_avail(struct acm *acm)
+{
+	int i, n;
+
+	n = 0;
+	for (i = 0; i < ACM_NWB; i++) {
+		if (!acm->wb[i].use)
+			n++;
+	}
+	return n;
+}
+
+static inline int acm_wb_is_used(struct acm *acm, int wbn)
+{
+	return acm->wb[wbn].use;
+}
+
+/*
+ * Finish write.
+ */
+static void acm_write_done(struct acm *acm)
+{
+	unsigned long flags;
+	int wbn;
+
+	spin_lock_irqsave(&acm->write_lock, flags);
+	acm->write_ready = 1;
+	wbn = acm->write_current;
+	acm_wb_free(acm, wbn);
+	acm->write_current = (wbn + 1) % ACM_NWB;
+	spin_unlock_irqrestore(&acm->write_lock, flags);
+}
+
+/*
+ * Poke write.
+ */
+static int acm_write_start(struct acm *acm)
+{
+	unsigned long flags;
+	int wbn;
+	struct acm_wb *wb;
+	int rc;
+
+	spin_lock_irqsave(&acm->write_lock, flags);
+	if (!acm->dev) {
+		spin_unlock_irqrestore(&acm->write_lock, flags);
+		return -ENODEV;
+	}
+
+	if (!acm->write_ready) {
+		spin_unlock_irqrestore(&acm->write_lock, flags);
+		return 0;	/* A white lie */
+	}
+
+	wbn = acm->write_current;
+	if (!acm_wb_is_used(acm, wbn)) {
+		spin_unlock_irqrestore(&acm->write_lock, flags);
+		return 0;
+	}
+	wb = &acm->wb[wbn];
+
+	acm->write_ready = 0;
+	spin_unlock_irqrestore(&acm->write_lock, flags);
+
+	acm->writeurb->transfer_buffer = wb->buf;
+	acm->writeurb->transfer_dma = wb->dmah;
+	acm->writeurb->transfer_buffer_length = wb->len;
+	acm->writeurb->dev = acm->dev;
+
+	if ((rc = usb_submit_urb(acm->writeurb, GFP_ATOMIC)) < 0) {
+		dbg("usb_submit_urb(write bulk) failed: %d", rc);
+		acm_write_done(acm);
+	}
+	return rc;
+}
+
+/*
  * Interrupt handlers for various ACM device responses
  */
 
@@ -237,17 +342,13 @@ static void acm_rx_tasklet(unsigned long
 static void acm_write_bulk(struct urb *urb, struct pt_regs *regs)
 {
 	struct acm *acm = (struct acm *)urb->context;
-	dbg("Entering acm_write_bulk with status %d\n", urb->status);
 
-	if (!ACM_READY(acm))
-		goto out;
-
-	if (urb->status)
-		dbg("nonzero write bulk status received: %d", urb->status);
+	dbg("Entering acm_write_bulk with status %d\n", urb->status);
 
-	schedule_work(&acm->work);
-out:
-	acm->ready_for_write = 1;
+	acm_write_done(acm);
+	acm_write_start(acm);
+	if (ACM_READY(acm))
+		schedule_work(&acm->work);
 }
 
 static void acm_softint(void *private)
@@ -321,6 +422,17 @@ bail_out:
 	return -EIO;
 }
 
+static void acm_tty_unregister(struct acm *acm)
+{
+	tty_unregister_device(acm_tty_driver, acm->minor);
+	usb_put_intf(acm->control);
+	acm_table[acm->minor] = NULL;
+	usb_free_urb(acm->ctrlurb);
+	usb_free_urb(acm->readurb);
+	usb_free_urb(acm->writeurb);
+	kfree(acm);
+}
+
 static void acm_tty_close(struct tty_struct *tty, struct file *filp)
 {
 	struct acm *acm = tty->driver_data;
@@ -335,14 +447,8 @@ static void acm_tty_close(struct tty_str
 			usb_kill_urb(acm->ctrlurb);
 			usb_kill_urb(acm->writeurb);
 			usb_kill_urb(acm->readurb);
-		} else {
-			tty_unregister_device(acm_tty_driver, acm->minor);
-			acm_table[acm->minor] = NULL;
-			usb_free_urb(acm->ctrlurb);
-			usb_free_urb(acm->readurb);
-			usb_free_urb(acm->writeurb);
-			kfree(acm);
-		}
+		} else
+			acm_tty_unregister(acm);
 	}
 	up(&open_sem);
 }
@@ -351,32 +457,33 @@ static int acm_tty_write(struct tty_stru
 {
 	struct acm *acm = tty->driver_data;
 	int stat;
+	unsigned long flags;
+	int wbn;
+	struct acm_wb *wb;
+
 	dbg("Entering acm_tty_write to write %d bytes,\n", count);
 
 	if (!ACM_READY(acm))
 		return -EINVAL;
-	if (!acm->ready_for_write)
-		return 0;
 	if (!count)
 		return 0;
 
-	count = (count > acm->writesize) ? acm->writesize : count;
+	spin_lock_irqsave(&acm->write_lock, flags);
+	if ((wbn = acm_wb_alloc(acm)) < 0) {
+		spin_unlock_irqrestore(&acm->write_lock, flags);
+		acm_write_start(acm);
+		return 0;
+	}
+	wb = &acm->wb[wbn];
 
+	count = (count > acm->writesize) ? acm->writesize : count;
 	dbg("Get %d bytes...", count);
-	memcpy(acm->write_buffer, buf, count);
-	dbg("  Successfully copied.\n");
+	memcpy(wb->buf, buf, count);
+	wb->len = count;
+	spin_unlock_irqrestore(&acm->write_lock, flags);
 
-	acm->writeurb->transfer_buffer_length = count;
-	acm->writeurb->dev = acm->dev;
-
-	acm->ready_for_write = 0;
-	stat = usb_submit_urb(acm->writeurb, GFP_ATOMIC);
-	if (stat < 0) {
-		dbg("usb_submit_urb(write bulk) failed");
-		acm->ready_for_write = 1;
+	if ((stat = acm_write_start(acm)) < 0)
 		return stat;
-	}
-
 	return count;
 }
 
@@ -385,7 +492,11 @@ static int acm_tty_write_room(struct tty
 	struct acm *acm = tty->driver_data;
 	if (!ACM_READY(acm))
 		return -EINVAL;
-	return !acm->ready_for_write ? 0 : acm->writesize;
+	/*
+	 * Do not let the line discipline to know that we have a reserve,
+	 * or it might get too enthusiastic.
+	 */
+	return (acm->write_ready && acm_wb_is_avail(acm)) ? acm->writesize : 0;
 }
 
 static int acm_tty_chars_in_buffer(struct tty_struct *tty)
@@ -393,7 +504,10 @@ static int acm_tty_chars_in_buffer(struc
 	struct acm *acm = tty->driver_data;
 	if (!ACM_READY(acm))
 		return -EINVAL;
-	return !acm->ready_for_write ? acm->writeurb->transfer_buffer_length : 0;
+	/*
+	 * This is inaccurate (overcounts), but it works.
+	 */
+	return (ACM_NWB - acm_wb_is_avail(acm)) * acm->writesize;
 }
 
 static void acm_tty_throttle(struct tty_struct *tty)
@@ -526,6 +640,39 @@ static void acm_tty_set_termios(struct t
  * USB probe and disconnect routines.
  */
 
+/* Little helper: write buffers free */
+static void acm_write_buffers_free(struct acm *acm)
+{
+	int i;
+	struct acm_wb *wb;
+
+	for (wb = &acm->wb[0], i = 0; i < ACM_NWB; i++, wb++) {
+		usb_buffer_free(acm->dev, acm->writesize, wb->buf, wb->dmah);
+	}
+}
+
+/* Little helper: write buffers allocate */
+static int acm_write_buffers_alloc(struct acm *acm)
+{
+	int i;
+	struct acm_wb *wb;
+
+	for (wb = &acm->wb[0], i = 0; i < ACM_NWB; i++, wb++) {
+		wb->buf = usb_buffer_alloc(acm->dev, acm->writesize, GFP_KERNEL,
+		    &wb->dmah);
+		if (!wb->buf) {
+			while (i != 0) {
+				--i;
+				--wb;
+				usb_buffer_free(acm->dev, acm->writesize,
+				    wb->buf, wb->dmah);
+			}
+			return -ENOMEM;
+		}
+	}
+	return 0;
+}
+
 static int acm_probe (struct usb_interface *intf,
 		      const struct usb_device_id *id)
 {
@@ -700,7 +847,8 @@ skip_normal_probe:
 	acm->bh.data = (unsigned long) acm;
 	INIT_WORK(&acm->work, acm_softint, acm);
 	spin_lock_init(&acm->throttle_lock);
-	acm->ready_for_write = 1;
+	spin_lock_init(&acm->write_lock);
+	acm->write_ready = 1;
 
 	buf = usb_buffer_alloc(usb_dev, ctrlsize, GFP_KERNEL, &acm->ctrl_dma);
 	if (!buf) {
@@ -716,12 +864,10 @@ skip_normal_probe:
 	}
 	acm->read_buffer = buf;
 
-	buf = usb_buffer_alloc(usb_dev, acm->writesize, GFP_KERNEL, &acm->write_dma);
-	if (!buf) {
+	if (acm_write_buffers_alloc(acm) < 0) {
 		dev_dbg(&intf->dev, "out of memory (write buffer alloc)\n");
 		goto alloc_fail4;
 	}
-	acm->write_buffer = buf;	
 
 	acm->ctrlurb = usb_alloc_urb(0, GFP_KERNEL);
 	if (!acm->ctrlurb) {
@@ -750,9 +896,9 @@ skip_normal_probe:
 	acm->readurb->transfer_dma = acm->read_dma;
 
 	usb_fill_bulk_urb(acm->writeurb, usb_dev, usb_sndbulkpipe(usb_dev, epwrite->bEndpointAddress),
-			  acm->write_buffer, acm->writesize, acm_write_bulk, acm);
+			  NULL, acm->writesize, acm_write_bulk, acm);
 	acm->writeurb->transfer_flags |= URB_NO_FSBR | URB_NO_TRANSFER_DMA_MAP;
-	acm->writeurb->transfer_dma = acm->write_dma;
+	/* acm->writeurb->transfer_dma = 0; */
 
 	dev_info(&intf->dev, "ttyACM%d: USB ACM device\n", minor);
 
@@ -764,7 +910,8 @@ skip_normal_probe:
 
 	usb_driver_claim_interface(&acm_driver, data_interface, acm);
 
-	tty_register_device(acm_tty_driver, minor, &intf->dev);
+	usb_get_intf(control_interface);
+	tty_register_device(acm_tty_driver, minor, &control_interface->dev);
 
 	acm_table[minor] = acm;
 	usb_set_intfdata (intf, acm);
@@ -775,7 +922,7 @@ alloc_fail7:
 alloc_fail6:
 	usb_free_urb(acm->ctrlurb);
 alloc_fail5:
-	usb_buffer_free(usb_dev, acm->writesize, acm->write_buffer, acm->write_dma);
+	acm_write_buffers_free(acm);
 alloc_fail4:
 	usb_buffer_free(usb_dev, readsize, acm->read_buffer, acm->read_dma);
 alloc_fail3:
@@ -806,19 +953,14 @@ static void acm_disconnect(struct usb_in
 
 	flush_scheduled_work(); /* wait for acm_softint */
 
-	usb_buffer_free(usb_dev, acm->writesize, acm->write_buffer, acm->write_dma);
+	acm_write_buffers_free(acm);
 	usb_buffer_free(usb_dev, acm->readsize, acm->read_buffer, acm->read_dma);
 	usb_buffer_free(usb_dev, acm->ctrlsize, acm->ctrl_buffer, acm->ctrl_dma);
 
 	usb_driver_release_interface(&acm_driver, acm->data);
 
 	if (!acm->used) {
-		tty_unregister_device(acm_tty_driver, acm->minor);
-		acm_table[acm->minor] = NULL;
-		usb_free_urb(acm->ctrlurb);
-		usb_free_urb(acm->readurb);
-		usb_free_urb(acm->writeurb);
-		kfree(acm);
+		acm_tty_unregister(acm);
 		up(&open_sem);
 		return;
 	}
@@ -838,6 +980,9 @@ static struct usb_device_id acm_ids[] = 
 	{ USB_DEVICE(0x0870, 0x0001), /* Metricom GS Modem */
 	.driver_info = NO_UNION_NORMAL, /* has no union descriptor */
 	},
+	{ USB_DEVICE(0x0482, 0x0203), /* KYOCERA AH-K3001V */
+	.driver_info = NO_UNION_NORMAL, /* has no union descriptor */
+	},
 	/* control interfaces with various AT-command sets */
 	{ USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM,
 		USB_CDC_ACM_PROTO_AT_V25TER) },
diff --git a/drivers/usb/class/cdc-acm.h b/drivers/usb/class/cdc-acm.h
--- a/drivers/usb/class/cdc-acm.h
+++ b/drivers/usb/class/cdc-acm.h
@@ -51,14 +51,34 @@
  * Internal driver structures.
  */
 
+/*
+ * The only reason to have several buffers is to accomodate assumptions
+ * in line disciplines. They ask for empty space amount, receive our URB size,
+ * and proceed to issue several 1-character writes, assuming they will fit.
+ * The very first write takes a complete URB. Fortunately, this only happens
+ * when processing onlcr, so we only need 2 buffers.
+ */
+#define ACM_NWB  2
+struct acm_wb {
+	unsigned char *buf;
+	dma_addr_t dmah;
+	int len;
+	int use;
+};
+
 struct acm {
 	struct usb_device *dev;				/* the corresponding usb device */
 	struct usb_interface *control;			/* control interface */
 	struct usb_interface *data;			/* data interface */
 	struct tty_struct *tty;				/* the corresponding tty */
 	struct urb *ctrlurb, *readurb, *writeurb;	/* urbs */
-	u8 *ctrl_buffer, *read_buffer, *write_buffer;	/* buffers of urbs */
-	dma_addr_t ctrl_dma, read_dma, write_dma;	/* dma handles of buffers */
+	u8 *ctrl_buffer, *read_buffer;			/* buffers of urbs */
+	dma_addr_t ctrl_dma, read_dma;			/* dma handles of buffers */
+	struct acm_wb wb[ACM_NWB];
+	int write_current;				/* current write buffer */
+	int write_used;					/* number of non-empty write buffers */
+	int write_ready;				/* write urb is not running */
+	spinlock_t write_lock;
 	struct usb_cdc_line_coding line;		/* bits, stop, parity */
 	struct work_struct work;			/* work queue entry for line discipline waking up */
 	struct tasklet_struct bh;			/* rx processing */
@@ -71,7 +91,6 @@ struct acm {
 	unsigned int minor;				/* acm minor number */
 	unsigned char throttle;				/* throttled by tty layer */
 	unsigned char clocal;				/* termios CLOCAL */
-	unsigned char ready_for_write;			/* write urb can be used */
 	unsigned char resubmit_to_unthrottle;		/* throtteling has disabled the read urb */
 	unsigned int ctrl_caps;				/* control capabilities from the class specific header */
 };
diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c
--- a/drivers/usb/class/usblp.c
+++ b/drivers/usb/class/usblp.c
@@ -379,6 +379,8 @@ static int usblp_open(struct inode *inod
 	usblp->writeurb->transfer_buffer_length = 0;
 	usblp->wcomplete = 1; /* we begin writeable */
 	usblp->rcomplete = 0;
+	usblp->writeurb->status = 0;
+	usblp->readurb->status = 0;
 
 	if (usblp->bidir) {
 		usblp->readcount = 0;
@@ -751,6 +753,7 @@ static ssize_t usblp_read(struct file *f
 				schedule();
 			} else {
 				set_current_state(TASK_RUNNING);
+				down(&usblp->sem);
 				break;
 			}
 			down (&usblp->sem);
diff --git a/drivers/usb/core/buffer.c b/drivers/usb/core/buffer.c
--- a/drivers/usb/core/buffer.c
+++ b/drivers/usb/core/buffer.c
@@ -106,7 +106,7 @@ void hcd_buffer_destroy (struct usb_hcd 
 void *hcd_buffer_alloc (
 	struct usb_bus 		*bus,
 	size_t			size,
-	int			mem_flags,
+	unsigned		mem_flags,
 	dma_addr_t		*dma
 )
 {
diff --git a/drivers/usb/core/devices.c b/drivers/usb/core/devices.c
--- a/drivers/usb/core/devices.c
+++ b/drivers/usb/core/devices.c
@@ -239,7 +239,7 @@ static char *usb_dump_interface_descript
 	int setno)
 {
 	const struct usb_interface_descriptor *desc = &intfc->altsetting[setno].desc;
-	char *driver_name = "";
+	const char *driver_name = "";
 
 	if (start > end)
 		return start;
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -569,8 +569,11 @@ static int proc_control(struct dev_state
 			free_page((unsigned long)tbuf);
 			return -EINVAL;
 		}
-		snoop(&dev->dev, "control read: bRequest=%02x bRrequestType=%02x wValue=%04x wIndex=%04x\n", 
-			ctrl.bRequest, ctrl.bRequestType, ctrl.wValue, ctrl.wIndex);
+		snoop(&dev->dev, "control read: bRequest=%02x "
+				"bRrequestType=%02x wValue=%04x "
+				"wIndex=%04x wLength=%04x\n",
+			ctrl.bRequest, ctrl.bRequestType, ctrl.wValue,
+				ctrl.wIndex, ctrl.wLength);
 
 		usb_unlock_device(dev);
 		i = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), ctrl.bRequest, ctrl.bRequestType,
@@ -579,11 +582,11 @@ static int proc_control(struct dev_state
 		if ((i > 0) && ctrl.wLength) {
 			if (usbfs_snoop) {
 				dev_info(&dev->dev, "control read: data ");
-				for (j = 0; j < ctrl.wLength; ++j)
+				for (j = 0; j < i; ++j)
 					printk ("%02x ", (unsigned char)(tbuf)[j]);
 				printk("\n");
 			}
-			if (copy_to_user(ctrl.data, tbuf, ctrl.wLength)) {
+			if (copy_to_user(ctrl.data, tbuf, i)) {
 				free_page((unsigned long)tbuf);
 				return -EFAULT;
 			}
@@ -595,8 +598,11 @@ static int proc_control(struct dev_state
 				return -EFAULT;
 			}
 		}
-		snoop(&dev->dev, "control write: bRequest=%02x bRrequestType=%02x wValue=%04x wIndex=%04x\n", 
-			ctrl.bRequest, ctrl.bRequestType, ctrl.wValue, ctrl.wIndex);
+		snoop(&dev->dev, "control write: bRequest=%02x "
+				"bRrequestType=%02x wValue=%04x "
+				"wIndex=%04x wLength=%04x\n",
+			ctrl.bRequest, ctrl.bRequestType, ctrl.wValue,
+				ctrl.wIndex, ctrl.wLength);
 		if (usbfs_snoop) {
 			dev_info(&dev->dev, "control write: data: ");
 			for (j = 0; j < ctrl.wLength; ++j)
@@ -784,16 +790,16 @@ static int proc_setconfig(struct dev_sta
  		for (i = 0; i < actconfig->desc.bNumInterfaces; ++i) {
  			if (usb_interface_claimed(actconfig->interface[i])) {
 				dev_warn (&ps->dev->dev,
-					"usbfs: interface %d claimed "
+					"usbfs: interface %d claimed by %s "
 					"while '%s' sets config #%d\n",
 					actconfig->interface[i]
 						->cur_altsetting
 						->desc.bInterfaceNumber,
+					actconfig->interface[i]
+						->dev.driver->name,
 					current->comm, u);
-#if 0	/* FIXME:  enable in 2.6.10 or so */
  				status = -EBUSY;
 				break;
-#endif
 			}
  		}
  	}
diff --git a/drivers/usb/core/file.c b/drivers/usb/core/file.c
--- a/drivers/usb/core/file.c
+++ b/drivers/usb/core/file.c
@@ -68,7 +68,7 @@ static struct file_operations usb_fops =
 	.open =		usb_open,
 };
 
-static struct class_simple *usb_class;
+static struct class *usb_class;
 
 int usb_major_init(void)
 {
@@ -80,9 +80,10 @@ int usb_major_init(void)
 		goto out;
 	}
 
-	usb_class = class_simple_create(THIS_MODULE, "usb");
+	usb_class = class_create(THIS_MODULE, "usb");
 	if (IS_ERR(usb_class)) {
-		err("class_simple_create failed for usb devices");
+		error = PTR_ERR(usb_class);
+		err("class_create failed for usb devices");
 		unregister_chrdev(USB_MAJOR, "usb");
 		goto out;
 	}
@@ -95,7 +96,7 @@ out:
 
 void usb_major_cleanup(void)
 {
-	class_simple_destroy(usb_class);
+	class_destroy(usb_class);
 	devfs_remove("usb");
 	unregister_chrdev(USB_MAJOR, "usb");
 }
@@ -171,7 +172,7 @@ int usb_register_dev(struct usb_interfac
 		++temp;
 	else
 		temp = name;
-	intf->class_dev = class_simple_device_add(usb_class, MKDEV(USB_MAJOR, minor), &intf->dev, "%s", temp);
+	intf->class_dev = class_device_create(usb_class, MKDEV(USB_MAJOR, minor), &intf->dev, "%s", temp);
 	if (IS_ERR(intf->class_dev)) {
 		spin_lock (&minor_lock);
 		usb_minors[intf->minor] = NULL;
@@ -220,7 +221,7 @@ void usb_deregister_dev(struct usb_inter
 
 	snprintf(name, BUS_ID_SIZE, class_driver->name, intf->minor - minor_base);
 	devfs_remove (name);
-	class_simple_device_remove(MKDEV(USB_MAJOR, intf->minor));
+	class_device_destroy(usb_class, MKDEV(USB_MAJOR, intf->minor));
 	intf->class_dev = NULL;
 	intf->minor = -1;
 }
diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c
--- a/drivers/usb/core/hcd-pci.c
+++ b/drivers/usb/core/hcd-pci.c
@@ -380,6 +380,7 @@ int usb_hcd_pci_resume (struct pci_dev *
 		usb_hc_died (hcd);
 	}
 
+	pci_enable_device(dev);
 	return retval;
 }
 EXPORT_SYMBOL (usb_hcd_pci_resume);
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -519,119 +519,120 @@ error:
 /*-------------------------------------------------------------------------*/
 
 /*
- * Root Hub interrupt transfers are synthesized with a timer.
- * Completions are called in_interrupt() but not in_irq().
+ * Root Hub interrupt transfers are polled using a timer if the
+ * driver requests it; otherwise the driver is responsible for
+ * calling usb_hcd_poll_rh_status() when an event occurs.
  *
- * Note: some root hubs (including common UHCI based designs) can't
- * correctly issue port change IRQs.  They're the ones that _need_ a
- * timer; most other root hubs don't.  Some systems could save a
- * lot of battery power by eliminating these root hub timer IRQs.
+ * Completions are called in_interrupt(), but they may or may not
+ * be in_irq().
  */
+void usb_hcd_poll_rh_status(struct usb_hcd *hcd)
+{
+	struct urb	*urb;
+	int		length;
+	unsigned long	flags;
+	char		buffer[4];	/* Any root hubs with > 31 ports? */
 
-static void rh_report_status (unsigned long ptr);
+	if (!hcd->uses_new_polling && !hcd->status_urb)
+		return;
 
-static int rh_status_urb (struct usb_hcd *hcd, struct urb *urb) 
-{
-	int	len = 1 + (urb->dev->maxchild / 8);
+	length = hcd->driver->hub_status_data(hcd, buffer);
+	if (length > 0) {
 
-	/* rh_timer protected by hcd_data_lock */
-	if (hcd->rh_timer.data || urb->transfer_buffer_length < len) {
-		dev_dbg (hcd->self.controller,
-				"not queuing rh status urb, stat %d\n",
-				urb->status);
-		return -EINVAL;
+		/* try to complete the status urb */
+		local_irq_save (flags);
+		spin_lock(&hcd_root_hub_lock);
+		urb = hcd->status_urb;
+		if (urb) {
+			spin_lock(&urb->lock);
+			if (urb->status == -EINPROGRESS) {
+				hcd->poll_pending = 0;
+				hcd->status_urb = NULL;
+				urb->status = 0;
+				urb->hcpriv = NULL;
+				urb->actual_length = length;
+				memcpy(urb->transfer_buffer, buffer, length);
+			} else		/* urb has been unlinked */
+				length = 0;
+			spin_unlock(&urb->lock);
+		} else
+			length = 0;
+		spin_unlock(&hcd_root_hub_lock);
+
+		/* local irqs are always blocked in completions */
+		if (length > 0)
+			usb_hcd_giveback_urb (hcd, urb, NULL);
+		else
+			hcd->poll_pending = 1;
+		local_irq_restore (flags);
 	}
 
-	init_timer (&hcd->rh_timer);
-	hcd->rh_timer.function = rh_report_status;
-	hcd->rh_timer.data = (unsigned long) urb;
-	/* USB 2.0 spec says 256msec; this is close enough */
-	hcd->rh_timer.expires = jiffies + HZ/4;
-	add_timer (&hcd->rh_timer);
-	urb->hcpriv = hcd;	/* nonzero to indicate it's queued */
-	return 0;
+	/* The USB 2.0 spec says 256 ms.  This is close enough and won't
+	 * exceed that limit if HZ is 100. */
+	if (hcd->uses_new_polling ? hcd->poll_rh :
+			(length == 0 && hcd->status_urb != NULL))
+		mod_timer (&hcd->rh_timer, jiffies + msecs_to_jiffies(250));
 }
+EXPORT_SYMBOL_GPL(usb_hcd_poll_rh_status);
 
 /* timer callback */
+static void rh_timer_func (unsigned long _hcd)
+{
+	usb_hcd_poll_rh_status((struct usb_hcd *) _hcd);
+}
+
+/*-------------------------------------------------------------------------*/
 
-static void rh_report_status (unsigned long ptr)
+static int rh_queue_status (struct usb_hcd *hcd, struct urb *urb)
 {
-	struct urb	*urb;
-	struct usb_hcd	*hcd;
-	int		length = 0;
+	int		retval;
 	unsigned long	flags;
+	int		len = 1 + (urb->dev->maxchild / 8);
 
-	urb = (struct urb *) ptr;
-	local_irq_save (flags);
-	spin_lock (&urb->lock);
-
-	/* do nothing if the urb's been unlinked */
-	if (!urb->dev
-			|| urb->status != -EINPROGRESS
-			|| (hcd = urb->dev->bus->hcpriv) == NULL) {
-		spin_unlock (&urb->lock);
-		local_irq_restore (flags);
-		return;
-	}
+	spin_lock_irqsave (&hcd_root_hub_lock, flags);
+	if (urb->status != -EINPROGRESS)	/* already unlinked */
+		retval = urb->status;
+	else if (hcd->status_urb || urb->transfer_buffer_length < len) {
+		dev_dbg (hcd->self.controller, "not queuing rh status urb\n");
+		retval = -EINVAL;
+	} else {
+		hcd->status_urb = urb;
+		urb->hcpriv = hcd;	/* indicate it's queued */
 
-	/* complete the status urb, or retrigger the timer */
-	spin_lock (&hcd_data_lock);
-	if (urb->dev->state == USB_STATE_CONFIGURED) {
-		length = hcd->driver->hub_status_data (
-					hcd, urb->transfer_buffer);
-		if (length > 0) {
-			hcd->rh_timer.data = 0;
-			urb->actual_length = length;
-			urb->status = 0;
-			urb->hcpriv = NULL;
-		} else
-			mod_timer (&hcd->rh_timer, jiffies + HZ/4);
+		if (!hcd->uses_new_polling)
+			mod_timer (&hcd->rh_timer, jiffies +
+					msecs_to_jiffies(250));
+
+		/* If a status change has already occurred, report it ASAP */
+		else if (hcd->poll_pending)
+			mod_timer (&hcd->rh_timer, jiffies);
+		retval = 0;
 	}
-	spin_unlock (&hcd_data_lock);
-	spin_unlock (&urb->lock);
-
-	/* local irqs are always blocked in completions */
-	if (length > 0)
-		usb_hcd_giveback_urb (hcd, urb, NULL);
-	local_irq_restore (flags);
+	spin_unlock_irqrestore (&hcd_root_hub_lock, flags);
+	return retval;
 }
 
-/*-------------------------------------------------------------------------*/
-
 static int rh_urb_enqueue (struct usb_hcd *hcd, struct urb *urb)
 {
-	if (usb_pipeint (urb->pipe)) {
-		int		retval;
-		unsigned long	flags;
-
-		spin_lock_irqsave (&hcd_data_lock, flags);
-		retval = rh_status_urb (hcd, urb);
-		spin_unlock_irqrestore (&hcd_data_lock, flags);
-		return retval;
-	}
+	if (usb_pipeint (urb->pipe))
+		return rh_queue_status (hcd, urb);
 	if (usb_pipecontrol (urb->pipe))
 		return rh_call_control (hcd, urb);
-	else
-		return -EINVAL;
+	return -EINVAL;
 }
 
 /*-------------------------------------------------------------------------*/
 
+/* Asynchronous unlinks of root-hub control URBs are legal, but they
+ * don't do anything.  Status URB unlinks must be made in process context
+ * with interrupts enabled.
+ */
 static int usb_rh_urb_dequeue (struct usb_hcd *hcd, struct urb *urb)
 {
-	unsigned long	flags;
-
-	/* note:  always a synchronous unlink */
-	if ((unsigned long) urb == hcd->rh_timer.data) {
-		del_timer_sync (&hcd->rh_timer);
-		hcd->rh_timer.data = 0;
+	if (usb_pipeendpoint(urb->pipe) == 0) {	/* Control URB */
+		if (in_interrupt())
+			return 0;		/* nothing to do */
 
-		local_irq_save (flags);
-		urb->hcpriv = NULL;
-		usb_hcd_giveback_urb (hcd, urb, NULL);
-		local_irq_restore (flags);
-
-	} else if (usb_pipeendpoint(urb->pipe) == 0) {
 		spin_lock_irq(&urb->lock);	/* from usb_kill_urb */
 		++urb->reject;
 		spin_unlock_irq(&urb->lock);
@@ -642,8 +643,22 @@ static int usb_rh_urb_dequeue (struct us
 		spin_lock_irq(&urb->lock);
 		--urb->reject;
 		spin_unlock_irq(&urb->lock);
-	} else
-		return -EINVAL;
+
+	} else {				/* Status URB */
+		if (!hcd->uses_new_polling)
+			del_timer_sync (&hcd->rh_timer);
+		local_irq_disable ();
+		spin_lock (&hcd_root_hub_lock);
+		if (urb == hcd->status_urb) {
+			hcd->status_urb = NULL;
+			urb->hcpriv = NULL;
+		} else
+			urb = NULL;		/* wasn't fully queued */
+		spin_unlock (&hcd_root_hub_lock);
+		if (urb)
+			usb_hcd_giveback_urb (hcd, urb, NULL);
+		local_irq_enable ();
+	}
 
 	return 0;
 }
@@ -651,50 +666,45 @@ static int usb_rh_urb_dequeue (struct us
 /*-------------------------------------------------------------------------*/
 
 /* exported only within usbcore */
-struct usb_bus *usb_bus_get (struct usb_bus *bus)
+struct usb_bus *usb_bus_get(struct usb_bus *bus)
 {
-	struct class_device *tmp;
+	if (bus)
+		kref_get(&bus->kref);
+	return bus;
+}
 
-	if (!bus)
-		return NULL;
+static void usb_host_release(struct kref *kref)
+{
+	struct usb_bus *bus = container_of(kref, struct usb_bus, kref);
 
-	tmp = class_device_get(&bus->class_dev);
-	if (tmp)        
-		return to_usb_bus(tmp);
-	else
-		return NULL;
+	if (bus->release)
+		bus->release(bus);
 }
 
 /* exported only within usbcore */
-void usb_bus_put (struct usb_bus *bus)
+void usb_bus_put(struct usb_bus *bus)
 {
 	if (bus)
-		class_device_put(&bus->class_dev);
+		kref_put(&bus->kref, usb_host_release);
 }
 
 /*-------------------------------------------------------------------------*/
 
-static void usb_host_release(struct class_device *class_dev)
-{
-	struct usb_bus *bus = to_usb_bus(class_dev);
-
-	if (bus->release)
-		bus->release(bus);
-}
-
-static struct class usb_host_class = {
-	.name		= "usb_host",
-	.release	= &usb_host_release,
-};
+static struct class *usb_host_class;
 
 int usb_host_init(void)
 {
-	return class_register(&usb_host_class);
+	int retval = 0;
+
+	usb_host_class = class_create(THIS_MODULE, "usb_host");
+	if (IS_ERR(usb_host_class))
+		retval = PTR_ERR(usb_host_class);
+	return retval;
 }
 
 void usb_host_cleanup(void)
 {
-	class_unregister(&usb_host_class);
+	class_destroy(usb_host_class);
 }
 
 /**
@@ -719,8 +729,7 @@ static void usb_bus_init (struct usb_bus
 
 	INIT_LIST_HEAD (&bus->bus_list);
 
-	class_device_initialize(&bus->class_dev);
-	bus->class_dev.class = &usb_host_class;
+	kref_init(&bus->kref);
 }
 
 /**
@@ -761,7 +770,6 @@ struct usb_bus *usb_alloc_bus (struct us
 static int usb_register_bus(struct usb_bus *bus)
 {
 	int busnum;
-	int retval;
 
 	down (&usb_bus_list_lock);
 	busnum = find_next_zero_bit (busmap.busmap, USB_MAXBUS, 1);
@@ -774,15 +782,15 @@ static int usb_register_bus(struct usb_b
 		return -E2BIG;
 	}
 
-	snprintf(bus->class_dev.class_id, BUS_ID_SIZE, "usb%d", busnum);
-	bus->class_dev.dev = bus->controller;
-	retval = class_device_add(&bus->class_dev);
-	if (retval) {
+	bus->class_dev = class_device_create(usb_host_class, MKDEV(0,0), bus->controller, "usb%d", busnum);
+	if (IS_ERR(bus->class_dev)) {
 		clear_bit(busnum, busmap.busmap);
 		up(&usb_bus_list_lock);
-		return retval;
+		return PTR_ERR(bus->class_dev);
 	}
 
+	class_set_devdata(bus->class_dev, bus);
+
 	/* Add it to the local list of buses */
 	list_add (&bus->bus_list, &usb_bus_list);
 	up (&usb_bus_list_lock);
@@ -820,34 +828,26 @@ static void usb_deregister_bus (struct u
 
 	clear_bit (bus->busnum, busmap.busmap);
 
-	class_device_del(&bus->class_dev);
+	class_device_unregister(bus->class_dev);
 }
 
 /**
- * usb_hcd_register_root_hub - called by HCD to register its root hub 
+ * register_root_hub - called by usb_add_hcd() to register a root hub
  * @usb_dev: the usb root hub device to be registered.
  * @hcd: host controller for this root hub
  *
- * The USB host controller calls this function to register the root hub
- * properly with the USB subsystem.  It sets up the device properly in
- * the device tree and stores the root_hub pointer in the bus structure,
- * then calls usb_new_device() to register the usb device.  It also
- * assigns the root hub's USB address (always 1).
+ * This function registers the root hub with the USB subsystem.  It sets up
+ * the device properly in the device tree and stores the root_hub pointer
+ * in the bus structure, then calls usb_new_device() to register the usb
+ * device.  It also assigns the root hub's USB address (always 1).
  */
-int usb_hcd_register_root_hub (struct usb_device *usb_dev, struct usb_hcd *hcd)
+static int register_root_hub (struct usb_device *usb_dev,
+		struct usb_hcd *hcd)
 {
 	struct device *parent_dev = hcd->self.controller;
 	const int devnum = 1;
 	int retval;
 
-	/* hcd->driver->start() reported can_wakeup, probably with
-	 * assistance from board's boot firmware.
-	 * NOTE:  normal devices won't enable wakeup by default.
-	 */
-	if (hcd->can_wakeup)
-		dev_dbg (parent_dev, "supports USB remote wakeup\n");
-	hcd->remote_wakeup = hcd->can_wakeup;
-
 	usb_dev->devnum = devnum;
 	usb_dev->bus->devnum_next = devnum + 1;
 	memset (&usb_dev->bus->devmap.devicemap, 0,
@@ -890,7 +890,16 @@ int usb_hcd_register_root_hub (struct us
 
 	return retval;
 }
-EXPORT_SYMBOL_GPL(usb_hcd_register_root_hub);
+
+void usb_enable_root_hub_irq (struct usb_bus *bus)
+{
+	struct usb_hcd *hcd;
+
+	hcd = container_of (bus, struct usb_hcd, self);
+	if (hcd->driver->hub_irq_enable && !hcd->poll_rh &&
+			hcd->state != HC_STATE_HALT)
+		hcd->driver->hub_irq_enable (hcd);
+}
 
 
 /*-------------------------------------------------------------------------*/
@@ -930,9 +939,9 @@ long usb_calc_bus_time (int speed, int i
 	case USB_SPEED_HIGH:	/* ISOC or INTR */
 		// FIXME adjust for input vs output
 		if (isoc)
-			tmp = HS_USECS (bytecount);
+			tmp = HS_NSECS_ISO (bytecount);
 		else
-			tmp = HS_USECS_ISO (bytecount);
+			tmp = HS_NSECS (bytecount);
 		return tmp;
 	default:
 		pr_debug ("%s: bogus device speed!\n", usbcore_name);
@@ -1103,7 +1112,7 @@ static void urb_unlink (struct urb *urb)
  * expects usb_submit_urb() to have sanity checked and conditioned all
  * inputs in the urb
  */
-static int hcd_submit_urb (struct urb *urb, int mem_flags)
+static int hcd_submit_urb (struct urb *urb, unsigned mem_flags)
 {
 	int			status;
 	struct usb_hcd		*hcd = urb->dev->bus->hcpriv;
@@ -1355,7 +1364,8 @@ hcd_endpoint_disable (struct usb_device 
 
 	hcd = udev->bus->hcpriv;
 
-	WARN_ON (!HC_IS_RUNNING (hcd->state) && hcd->state != HC_STATE_HALT);
+	WARN_ON (!HC_IS_RUNNING (hcd->state) && hcd->state != HC_STATE_HALT &&
+			udev->state != USB_STATE_NOTATTACHED);
 
 	local_irq_disable ();
 
@@ -1619,6 +1629,8 @@ void usb_hc_died (struct usb_hcd *hcd)
 
 	spin_lock_irqsave (&hcd_root_hub_lock, flags);
 	if (hcd->rh_registered) {
+		hcd->poll_rh = 0;
+		del_timer(&hcd->rh_timer);
 
 		/* make khubd clean up old urbs and devices */
 		usb_set_device_state (hcd->self.root_hub,
@@ -1672,6 +1684,8 @@ struct usb_hcd *usb_create_hcd (const st
 	hcd->self.bus_name = bus_name;
 
 	init_timer(&hcd->rh_timer);
+	hcd->rh_timer.function = rh_timer_func;
+	hcd->rh_timer.data = (unsigned long) hcd;
 
 	hcd->driver = driver;
 	hcd->product_desc = (driver->product_desc) ? driver->product_desc :
@@ -1701,7 +1715,8 @@ EXPORT_SYMBOL (usb_put_hcd);
 int usb_add_hcd(struct usb_hcd *hcd,
 		unsigned int irqnum, unsigned long irqflags)
 {
-	int	retval;
+	int retval;
+	struct usb_device *rhdev;
 
 	dev_info(hcd->self.controller, "%s\n", hcd->product_desc);
 
@@ -1717,7 +1732,7 @@ int usb_add_hcd(struct usb_hcd *hcd,
 	}
 
 	if ((retval = usb_register_bus(&hcd->self)) < 0)
-		goto err1;
+		goto err_register_bus;
 
 	if (hcd->driver->irq) {
 		char	buf[8], *bufp = buf;
@@ -1734,7 +1749,7 @@ int usb_add_hcd(struct usb_hcd *hcd,
 				hcd->irq_descr, hcd)) != 0) {
 			dev_err(hcd->self.controller,
 					"request interrupt %s failed\n", bufp);
-			goto err2;
+			goto err_request_irq;
 		}
 		hcd->irq = irqnum;
 		dev_info(hcd->self.controller, "irq %s, %s 0x%08llx\n", bufp,
@@ -1750,19 +1765,55 @@ int usb_add_hcd(struct usb_hcd *hcd,
 					(unsigned long long)hcd->rsrc_start);
 	}
 
+	/* Allocate the root hub before calling hcd->driver->start(),
+	 * but don't register it until afterward so that the hardware
+	 * is running.
+	 */
+	if ((rhdev = usb_alloc_dev(NULL, &hcd->self, 0)) == NULL) {
+		dev_err(hcd->self.controller, "unable to allocate root hub\n");
+		retval = -ENOMEM;
+		goto err_allocate_root_hub;
+	}
+	rhdev->speed = (hcd->driver->flags & HCD_USB2) ? USB_SPEED_HIGH :
+			USB_SPEED_FULL;
+
+	/* Although in principle hcd->driver->start() might need to use rhdev,
+	 * none of the current drivers do.
+	 */
 	if ((retval = hcd->driver->start(hcd)) < 0) {
 		dev_err(hcd->self.controller, "startup error %d\n", retval);
-		goto err3;
+		goto err_hcd_driver_start;
 	}
 
+	/* hcd->driver->start() reported can_wakeup, probably with
+	 * assistance from board's boot firmware.
+	 * NOTE:  normal devices won't enable wakeup by default.
+	 */
+	if (hcd->can_wakeup)
+		dev_dbg(hcd->self.controller, "supports USB remote wakeup\n");
+	hcd->remote_wakeup = hcd->can_wakeup;
+
+	if ((retval = register_root_hub(rhdev, hcd)) != 0)
+		goto err_register_root_hub;
+
+	if (hcd->uses_new_polling && hcd->poll_rh)
+		usb_hcd_poll_rh_status(hcd);
 	return retval;
 
- err3:
+ err_register_root_hub:
+	hcd->driver->stop(hcd);
+
+ err_hcd_driver_start:
+	usb_put_dev(rhdev);
+
+ err_allocate_root_hub:
 	if (hcd->irq >= 0)
 		free_irq(irqnum, hcd);
- err2:
+
+ err_request_irq:
 	usb_deregister_bus(&hcd->self);
- err1:
+
+ err_register_bus:
 	hcd_buffer_destroy(hcd);
 	return retval;
 } 
@@ -1789,6 +1840,9 @@ void usb_remove_hcd(struct usb_hcd *hcd)
 	spin_unlock_irq (&hcd_root_hub_lock);
 	usb_disconnect(&hcd->self.root_hub);
 
+	hcd->poll_rh = 0;
+	del_timer_sync(&hcd->rh_timer);
+
 	hcd->driver->stop(hcd);
 	hcd->state = HC_STATE_HALT;
 
@@ -1801,7 +1855,7 @@ EXPORT_SYMBOL (usb_remove_hcd);
 
 /*-------------------------------------------------------------------------*/
 
-#if defined(CONFIG_USB_MON) || defined(CONFIG_USB_MON_MODULE)
+#if defined(CONFIG_USB_MON)
 
 struct usb_mon_operations *mon_ops;
 
diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h
--- a/drivers/usb/core/hcd.h
+++ b/drivers/usb/core/hcd.h
@@ -65,7 +65,8 @@ struct usb_hcd {	/* usb_bus.hcpriv point
 	const char		*product_desc;	/* product/vendor string */
 	char			irq_descr[24];	/* driver + bus # */
 
-	struct timer_list	rh_timer;	/* drives root hub */
+	struct timer_list	rh_timer;	/* drives root-hub polling */
+	struct urb		*status_urb;	/* the current status urb */
 
 	/*
 	 * hardware info/state
@@ -76,10 +77,17 @@ struct usb_hcd {	/* usb_bus.hcpriv point
 	unsigned		remote_wakeup:1;/* sw should use wakeup? */
 	unsigned		rh_registered:1;/* is root hub registered? */
 
+	/* The next flag is a stopgap, to be removed when all the HCDs
+	 * support the new root-hub polling mechanism. */
+	unsigned		uses_new_polling:1;
+	unsigned		poll_rh:1;	/* poll for rh status? */
+	unsigned		poll_pending:1;	/* status has changed? */
+
 	int			irq;		/* irq allocated */
 	void __iomem		*regs;		/* device memory/io */
 	u64			rsrc_start;	/* memory/io resource start */
 	u64			rsrc_len;	/* memory/io resource length */
+	unsigned		power_budget;	/* in mA, 0 = no limit */
 
 #define HCD_BUFFER_POOLS	4
 	struct dma_pool		*pool [HCD_BUFFER_POOLS];
@@ -134,12 +142,12 @@ struct hcd_timeout {	/* timeouts we allo
 
 struct usb_operations {
 	int (*get_frame_number) (struct usb_device *usb_dev);
-	int (*submit_urb) (struct urb *urb, int mem_flags);
+	int (*submit_urb) (struct urb *urb, unsigned mem_flags);
 	int (*unlink_urb) (struct urb *urb, int status);
 
 	/* allocate dma-consistent buffer for URB_DMA_NOMAPPING */
 	void *(*buffer_alloc)(struct usb_bus *bus, size_t size,
-			int mem_flags,
+			unsigned mem_flags,
 			dma_addr_t *dma);
 	void (*buffer_free)(struct usb_bus *bus, size_t size,
 			void *addr, dma_addr_t dma);
@@ -192,7 +200,7 @@ struct hc_driver {
 	int	(*urb_enqueue) (struct usb_hcd *hcd,
 					struct usb_host_endpoint *ep,
 					struct urb *urb,
-					int mem_flags);
+					unsigned mem_flags);
 	int	(*urb_dequeue) (struct usb_hcd *hcd, struct urb *urb);
 
 	/* hw synch, freeing endpoint resources that urb_dequeue can't */
@@ -207,6 +215,8 @@ struct hc_driver {
 	int		(*hub_suspend)(struct usb_hcd *);
 	int		(*hub_resume)(struct usb_hcd *);
 	int		(*start_port_reset)(struct usb_hcd *, unsigned port_num);
+	void		(*hub_irq_enable)(struct usb_hcd *);
+		/* Needed only if port-change IRQs are level-triggered */
 };
 
 extern void usb_hcd_giveback_urb (struct usb_hcd *hcd, struct urb *urb, struct pt_regs *regs);
@@ -237,13 +247,15 @@ int hcd_buffer_create (struct usb_hcd *h
 void hcd_buffer_destroy (struct usb_hcd *hcd);
 
 void *hcd_buffer_alloc (struct usb_bus *bus, size_t size,
-	int mem_flags, dma_addr_t *dma);
+	unsigned mem_flags, dma_addr_t *dma);
 void hcd_buffer_free (struct usb_bus *bus, size_t size,
 	void *addr, dma_addr_t dma);
 
 /* generic bus glue, needed for host controllers that don't use PCI */
 extern irqreturn_t usb_hcd_irq (int irq, void *__hcd, struct pt_regs *r);
+
 extern void usb_hc_died (struct usb_hcd *hcd);
+extern void usb_hcd_poll_rh_status(struct usb_hcd *hcd);
 
 /* -------------------------------------------------------------------------- */
 
@@ -322,17 +334,19 @@ extern void usb_release_bandwidth (struc
 extern int usb_check_bandwidth (struct usb_device *dev, struct urb *urb);
 
 /*
- * Ceiling microseconds (typical) for that many bytes at high speed
+ * Ceiling [nano/micro]seconds (typical) for that many bytes at high speed
  * ISO is a bit less, no ACK ... from USB 2.0 spec, 5.11.3 (and needed
  * to preallocate bandwidth)
  */
 #define USB2_HOST_DELAY	5	/* nsec, guess */
-#define HS_USECS(bytes) NS_TO_US ( ((55 * 8 * 2083)/1000) \
+#define HS_NSECS(bytes) ( ((55 * 8 * 2083)/1000) \
 	+ ((2083UL * (3167 + BitTime (bytes)))/1000) \
 	+ USB2_HOST_DELAY)
-#define HS_USECS_ISO(bytes) NS_TO_US ( ((38 * 8 * 2083)/1000) \
+#define HS_NSECS_ISO(bytes) ( ((38 * 8 * 2083)/1000) \
 	+ ((2083UL * (3167 + BitTime (bytes)))/1000) \
 	+ USB2_HOST_DELAY)
+#define HS_USECS(bytes) NS_TO_US (HS_NSECS(bytes))
+#define HS_USECS_ISO(bytes) NS_TO_US (HS_NSECS_ISO(bytes))
 
 extern long usb_calc_bus_time (int speed, int is_input,
 			int isoc, int bytecount);
@@ -341,9 +355,6 @@ extern long usb_calc_bus_time (int speed
 
 extern struct usb_bus *usb_alloc_bus (struct usb_operations *);
 
-extern int usb_hcd_register_root_hub (struct usb_device *usb_dev,
-		struct usb_hcd *hcd);
-
 extern void usb_hcd_resume_root_hub (struct usb_hcd *hcd);
 
 extern void usb_set_device_state(struct usb_device *udev,
@@ -360,6 +371,8 @@ extern wait_queue_head_t usb_kill_urb_qu
 extern struct usb_bus *usb_bus_get (struct usb_bus *bus);
 extern void usb_bus_put (struct usb_bus *bus);
 
+extern void usb_enable_root_hub_irq (struct usb_bus *bus);
+
 extern int usb_find_interface_driver (struct usb_device *dev,
 	struct usb_interface *interface);
 
@@ -399,7 +412,7 @@ static inline void usbfs_cleanup(void) {
 
 /*-------------------------------------------------------------------------*/
 
-#if defined(CONFIG_USB_MON) || defined(CONFIG_USB_MON_MODULE)
+#if defined(CONFIG_USB_MON)
 
 struct usb_mon_operations {
 	void (*urb_submit)(struct usb_bus *bus, struct urb *urb);
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -26,6 +26,7 @@
 #include <linux/ioctl.h>
 #include <linux/usb.h>
 #include <linux/usbdevice_fs.h>
+#include <linux/kthread.h>
 
 #include <asm/semaphore.h>
 #include <asm/uaccess.h>
@@ -47,8 +48,7 @@ static LIST_HEAD(hub_event_list);	/* Lis
 /* Wakes up khubd */
 static DECLARE_WAIT_QUEUE_HEAD(khubd_wait);
 
-static pid_t khubd_pid = 0;			/* PID of khubd */
-static DECLARE_COMPLETION(khubd_exited);
+static struct task_struct *khubd_task;
 
 /* cycle leds on hubs that aren't blinking for attention */
 static int blinkenlights = 0;
@@ -643,15 +643,21 @@ static int hub_configure(struct usb_hub 
 		message = "can't get hub status";
 		goto fail;
 	}
-	cpu_to_le16s(&hubstatus);
-	if ((hubstatus & (1 << USB_DEVICE_SELF_POWERED)) == 0) {
+	le16_to_cpus(&hubstatus);
+	if (hdev == hdev->bus->root_hub) {
+		struct usb_hcd *hcd =
+				container_of(hdev->bus, struct usb_hcd, self);
+
+		hub->power_budget = min(500u, hcd->power_budget) / 2;
+	} else if ((hubstatus & (1 << USB_DEVICE_SELF_POWERED)) == 0) {
 		dev_dbg(hub_dev, "hub controller current requirement: %dmA\n",
 			hub->descriptor->bHubContrCurrent);
 		hub->power_budget = (501 - hub->descriptor->bHubContrCurrent)
 					/ 2;
+	}
+	if (hub->power_budget)
 		dev_dbg(hub_dev, "%dmA bus power budget for children\n",
 			hub->power_budget * 2);
-	}
 
 
 	ret = hub_hub_status(hub, &hubstatus, &hubchange);
@@ -1727,7 +1733,7 @@ static int finish_port_resume(struct usb
 			struct usb_driver	*driver;
 
 			intf = udev->actconfig->interface[i];
-			if (intf->dev.power.power_state == PMSG_SUSPEND)
+			if (intf->dev.power.power_state == PMSG_ON)
 				continue;
 			if (!intf->dev.driver) {
 				/* FIXME maybe force to alt 0 */
@@ -2787,6 +2793,11 @@ static void hub_events(void)
 
 		hub->activating = 0;
 
+		/* If this is a root hub, tell the HCD it's okay to
+		 * re-enable port-change interrupts now. */
+		if (!hdev->parent)
+			usb_enable_root_hub_irq(hdev->bus);
+
 loop:
 		usb_unlock_device(hdev);
 		usb_put_intf(intf);
@@ -2796,23 +2807,16 @@ loop:
 
 static int hub_thread(void *__unused)
 {
-	/*
-	 * This thread doesn't need any user-level access,
-	 * so get rid of all our resources
-	 */
-
-	daemonize("khubd");
-	allow_signal(SIGKILL);
-
-	/* Send me a signal to get me die (for debugging) */
 	do {
 		hub_events();
-		wait_event_interruptible(khubd_wait, !list_empty(&hub_event_list)); 
-		try_to_freeze(PF_FREEZE);
-	} while (!signal_pending(current));
+		wait_event_interruptible(khubd_wait,
+				!list_empty(&hub_event_list) ||
+				kthread_should_stop());
+		try_to_freeze();
+	} while (!kthread_should_stop() || !list_empty(&hub_event_list));
 
-	pr_debug ("%s: khubd exiting\n", usbcore_name);
-	complete_and_exit(&khubd_exited, 0);
+	pr_debug("%s: khubd exiting\n", usbcore_name);
+	return 0;
 }
 
 static struct usb_device_id hub_id_table [] = {
@@ -2838,20 +2842,15 @@ static struct usb_driver hub_driver = {
 
 int usb_hub_init(void)
 {
-	pid_t pid;
-
 	if (usb_register(&hub_driver) < 0) {
 		printk(KERN_ERR "%s: can't register hub driver\n",
 			usbcore_name);
 		return -1;
 	}
 
-	pid = kernel_thread(hub_thread, NULL, CLONE_KERNEL);
-	if (pid >= 0) {
-		khubd_pid = pid;
-
+	khubd_task = kthread_run(hub_thread, NULL, "khubd");
+	if (!IS_ERR(khubd_task))
 		return 0;
-	}
 
 	/* Fall through if kernel_thread failed */
 	usb_deregister(&hub_driver);
@@ -2862,12 +2861,7 @@ int usb_hub_init(void)
 
 void usb_hub_cleanup(void)
 {
-	int ret;
-
-	/* Kill the thread */
-	ret = kill_proc(khubd_pid, SIGKILL, 1);
-
-	wait_for_completion(&khubd_exited);
+	kthread_stop(khubd_task);
 
 	/*
 	 * Hub resources are freed for us by usb_deregister. It calls
@@ -2879,7 +2873,6 @@ void usb_hub_cleanup(void)
 	usb_deregister(&hub_driver);
 } /* usb_hub_cleanup() */
 
-
 static int config_descriptors_changed(struct usb_device *udev)
 {
 	unsigned			index;
diff --git a/drivers/usb/core/hub.h b/drivers/usb/core/hub.h
--- a/drivers/usb/core/hub.h
+++ b/drivers/usb/core/hub.h
@@ -224,15 +224,4 @@ struct usb_hub {
 	struct work_struct	leds;
 };
 
-/* use this for low-powered root hubs */
-static inline void
-hub_set_power_budget (struct usb_device *hubdev, unsigned mA)
-{
-	struct usb_hub	*hub;
-
-	hub = (struct usb_hub *)
-		usb_get_intfdata (hubdev->actconfig->interface[0]);
-	hub->power_budget = min(mA,(unsigned)500)/2;
-}
-
 #endif /* __LINUX_HUB_H */
diff --git a/drivers/usb/core/inode.c b/drivers/usb/core/inode.c
--- a/drivers/usb/core/inode.c
+++ b/drivers/usb/core/inode.c
@@ -453,17 +453,6 @@ static int usbfs_fill_super(struct super
 	return 0;
 }
 
-static struct dentry * get_dentry(struct dentry *parent, const char *name)
-{               
-	struct qstr qstr;
-
-	qstr.name = name;
-	qstr.len = strlen(name);
-	qstr.hash = full_name_hash(name,qstr.len);
-	return lookup_hash(&qstr,parent);
-}               
-
-
 /*
  * fs_create_by_name - create a file, given a name
  * @name:	name of file
@@ -496,7 +485,7 @@ static int fs_create_by_name (const char
 
 	*dentry = NULL;
 	down(&parent->d_inode->i_sem);
-	*dentry = get_dentry (parent, name);
+	*dentry = lookup_one_len(name, parent, strlen(name));
 	if (!IS_ERR(dentry)) {
 		if ((mode & S_IFMT) == S_IFDIR)
 			error = usbfs_mkdir (parent->d_inode, *dentry, mode);
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -320,7 +320,7 @@ int usb_sg_init (
 	struct scatterlist	*sg,
 	int			nents,
 	size_t			length,
-	int			mem_flags
+	unsigned		mem_flags
 )
 {
 	int			i;
@@ -985,8 +985,10 @@ void usb_disable_device(struct usb_devic
 		for (i = 0; i < dev->actconfig->desc.bNumInterfaces; i++) {
 			struct usb_interface	*interface;
 
-			/* remove this interface */
+			/* remove this interface if it has been registered */
 			interface = dev->actconfig->interface[i];
+			if (!klist_node_attached(&interface->dev.knode_bus))
+				continue;
 			dev_dbg (&dev->dev, "unregistering interface %s\n",
 				interface->dev.bus_id);
 			usb_remove_sysfs_intf_files(interface);
@@ -1439,7 +1441,7 @@ free_interfaces:
 		}
 	}
 
-	return ret;
+	return 0;
 }
 
 // synchronous request completion model
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c
--- a/drivers/usb/core/sysfs.c
+++ b/drivers/usb/core/sysfs.c
@@ -24,7 +24,7 @@
 
 /* Active configuration fields */
 #define usb_actconfig_show(field, multiplier, format_string)		\
-static ssize_t  show_##field (struct device *dev, char *buf)		\
+static ssize_t  show_##field (struct device *dev, struct device_attribute *attr, char *buf)		\
 {									\
 	struct usb_device *udev;					\
 	struct usb_host_config *actconfig;				\
@@ -46,7 +46,7 @@ usb_actconfig_attr (bNumInterfaces, 1, "
 usb_actconfig_attr (bmAttributes, 1, "%2x\n")
 usb_actconfig_attr (bMaxPower, 2, "%3dmA\n")
 
-static ssize_t show_configuration_string(struct device *dev, char *buf)
+static ssize_t show_configuration_string(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct usb_device *udev;
 	struct usb_host_config *actconfig;
@@ -69,7 +69,7 @@ static DEVICE_ATTR(configuration, S_IRUG
 usb_actconfig_show(bConfigurationValue, 1, "%u\n");
 
 static ssize_t
-set_bConfigurationValue (struct device *dev, const char *buf, size_t count)
+set_bConfigurationValue (struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct usb_device	*udev = udev = to_usb_device (dev);
 	int			config, value;
@@ -87,7 +87,7 @@ static DEVICE_ATTR(bConfigurationValue, 
 
 /* String fields */
 #define usb_string_attr(name)						\
-static ssize_t  show_##name(struct device *dev, char *buf)		\
+static ssize_t  show_##name(struct device *dev, struct device_attribute *attr, char *buf)		\
 {									\
 	struct usb_device *udev;					\
 	int len;							\
@@ -107,7 +107,7 @@ usb_string_attr(manufacturer);
 usb_string_attr(serial);
 
 static ssize_t
-show_speed (struct device *dev, char *buf)
+show_speed (struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct usb_device *udev;
 	char *speed;
@@ -133,7 +133,7 @@ show_speed (struct device *dev, char *bu
 static DEVICE_ATTR(speed, S_IRUGO, show_speed, NULL);
 
 static ssize_t
-show_devnum (struct device *dev, char *buf)
+show_devnum (struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct usb_device *udev;
 
@@ -143,7 +143,7 @@ show_devnum (struct device *dev, char *b
 static DEVICE_ATTR(devnum, S_IRUGO, show_devnum, NULL);
 
 static ssize_t
-show_version (struct device *dev, char *buf)
+show_version (struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct usb_device *udev;
 	u16 bcdUSB;
@@ -155,7 +155,7 @@ show_version (struct device *dev, char *
 static DEVICE_ATTR(version, S_IRUGO, show_version, NULL);
 
 static ssize_t
-show_maxchild (struct device *dev, char *buf)
+show_maxchild (struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct usb_device *udev;
 
@@ -167,7 +167,7 @@ static DEVICE_ATTR(maxchild, S_IRUGO, sh
 /* Descriptor fields */
 #define usb_descriptor_attr_le16(field, format_string)			\
 static ssize_t								\
-show_##field (struct device *dev, char *buf)				\
+show_##field (struct device *dev, struct device_attribute *attr, char *buf)				\
 {									\
 	struct usb_device *udev;					\
 									\
@@ -183,7 +183,7 @@ usb_descriptor_attr_le16(bcdDevice, "%04
 
 #define usb_descriptor_attr(field, format_string)			\
 static ssize_t								\
-show_##field (struct device *dev, char *buf)				\
+show_##field (struct device *dev, struct device_attribute *attr, char *buf)				\
 {									\
 	struct usb_device *udev;					\
 									\
@@ -196,6 +196,7 @@ usb_descriptor_attr (bDeviceClass, "%02x
 usb_descriptor_attr (bDeviceSubClass, "%02x\n")
 usb_descriptor_attr (bDeviceProtocol, "%02x\n")
 usb_descriptor_attr (bNumConfigurations, "%d\n")
+usb_descriptor_attr (bMaxPacketSize0, "%d\n")
 
 static struct attribute *dev_attrs[] = {
 	/* current configuration's attributes */
@@ -211,6 +212,7 @@ static struct attribute *dev_attrs[] = {
 	&dev_attr_bDeviceSubClass.attr,
 	&dev_attr_bDeviceProtocol.attr,
 	&dev_attr_bNumConfigurations.attr,
+	&dev_attr_bMaxPacketSize0.attr,
 	&dev_attr_speed.attr,
 	&dev_attr_devnum.attr,
 	&dev_attr_version.attr,
@@ -254,7 +256,7 @@ void usb_remove_sysfs_dev_files (struct 
 /* Interface fields */
 #define usb_intf_attr(field, format_string)				\
 static ssize_t								\
-show_##field (struct device *dev, char *buf)				\
+show_##field (struct device *dev, struct device_attribute *attr, char *buf)				\
 {									\
 	struct usb_interface *intf = to_usb_interface (dev);		\
 									\
@@ -269,7 +271,7 @@ usb_intf_attr (bInterfaceClass, "%02x\n"
 usb_intf_attr (bInterfaceSubClass, "%02x\n")
 usb_intf_attr (bInterfaceProtocol, "%02x\n")
 
-static ssize_t show_interface_string(struct device *dev, char *buf)
+static ssize_t show_interface_string(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct usb_interface *intf;
 	struct usb_device *udev;
@@ -286,7 +288,7 @@ static ssize_t show_interface_string(str
 }
 static DEVICE_ATTR(interface, S_IRUGO, show_interface_string, NULL);
 
-static ssize_t show_modalias(struct device *dev, char *buf)
+static ssize_t show_modalias(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct usb_interface *intf;
 	struct usb_device *udev;
diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c
--- a/drivers/usb/core/urb.c
+++ b/drivers/usb/core/urb.c
@@ -60,7 +60,7 @@ void usb_init_urb(struct urb *urb)
  *
  * The driver must call usb_free_urb() when it is finished with the urb.
  */
-struct urb *usb_alloc_urb(int iso_packets, int mem_flags)
+struct urb *usb_alloc_urb(int iso_packets, unsigned mem_flags)
 {
 	struct urb *urb;
 
@@ -224,7 +224,7 @@ struct urb * usb_get_urb(struct urb *urb
  *      GFP_NOIO, unless b) or c) apply
  *
  */
-int usb_submit_urb(struct urb *urb, int mem_flags)
+int usb_submit_urb(struct urb *urb, unsigned mem_flags)
 {
 	int			pipe, temp, max;
 	struct usb_device	*dev;
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -293,7 +293,7 @@ int usb_driver_claim_interface(struct us
 	/* if interface was already added, bind now; else let
 	 * the future device_add() bind it, bypassing probe()
 	 */
-	if (!list_empty (&dev->bus_list))
+	if (klist_node_attached(&dev->knode_bus))
 		device_bind_driver(dev);
 
 	return 0;
@@ -322,9 +322,15 @@ void usb_driver_release_interface(struct
 	if (!dev->driver || dev->driver != &driver->driver)
 		return;
 
-	/* don't disconnect from disconnect(), or before dev_add() */
-	if (!list_empty (&dev->driver_list) && !list_empty (&dev->bus_list))
+	/* don't release from within disconnect() */
+	if (iface->condition != USB_INTERFACE_BOUND)
+		return;
+
+	/* release only after device_add() */
+	if (klist_node_attached(&dev->knode_bus)) {
+		iface->condition = USB_INTERFACE_UNBINDING;
 		device_release_driver(dev);
+	}
 
 	dev->driver = NULL;
 	usb_set_intfdata(iface, NULL);
@@ -462,6 +468,25 @@ usb_match_id(struct usb_interface *inter
 	return NULL;
 }
 
+
+static int __find_interface(struct device * dev, void * data)
+{
+	struct usb_interface ** ret = (struct usb_interface **)data;
+	struct usb_interface * intf = *ret;
+	int *minor = (int *)data;
+
+	/* can't look at usb devices, only interfaces */
+	if (dev->driver == &usb_generic_driver)
+		return 0;
+
+	intf = to_usb_interface(dev);
+	if (intf->minor != -1 && intf->minor == *minor) {
+		*ret = intf;
+		return 1;
+	}
+	return 0;
+}
+
 /**
  * usb_find_interface - find usb_interface pointer for driver and device
  * @drv: the driver whose current configuration is considered
@@ -473,26 +498,12 @@ usb_match_id(struct usb_interface *inter
  */
 struct usb_interface *usb_find_interface(struct usb_driver *drv, int minor)
 {
-	struct list_head *entry;
-	struct device *dev;
-	struct usb_interface *intf;
+	struct usb_interface *intf = (struct usb_interface *)(long)minor;
+	int ret;
 
-	list_for_each(entry, &drv->driver.devices) {
-		dev = container_of(entry, struct device, driver_list);
+	ret = driver_for_each_device(&drv->driver, NULL, &intf, __find_interface);
 
-		/* can't look at usb devices, only interfaces */
-		if (dev->driver == &usb_generic_driver)
-			continue;
-
-		intf = to_usb_interface(dev);
-		if (intf->minor == -1)
-			continue;
-		if (intf->minor == minor)
-			return intf;
-	}
-
-	/* no device found that matches */
-	return NULL;	
+	return ret ? intf : NULL;
 }
 
 static int usb_device_match (struct device *dev, struct device_driver *drv)
@@ -1118,7 +1129,7 @@ int __usb_get_extra_descriptor(char *buf
 void *usb_buffer_alloc (
 	struct usb_device *dev,
 	size_t size,
-	int mem_flags,
+	unsigned mem_flags,
 	dma_addr_t *dma
 )
 {
@@ -1521,6 +1532,9 @@ EXPORT_SYMBOL(usb_register);
 EXPORT_SYMBOL(usb_deregister);
 EXPORT_SYMBOL(usb_disabled);
 
+EXPORT_SYMBOL_GPL(usb_get_intf);
+EXPORT_SYMBOL_GPL(usb_put_intf);
+
 EXPORT_SYMBOL(usb_alloc_dev);
 EXPORT_SYMBOL(usb_put_dev);
 EXPORT_SYMBOL(usb_get_dev);
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -53,6 +53,9 @@ config USB_GADGET_DEBUG_FILES
 	   driver on a new board.   Enable these files by choosing "Y"
 	   here.  If in doubt, or to conserve kernel memory, say "N".
 
+config	USB_GADGET_SELECTED
+	boolean
+
 #
 # USB Peripheral Controller Support
 #
@@ -85,6 +88,7 @@ config USB_NET2280
 	tristate
 	depends on USB_GADGET_NET2280
 	default USB_GADGET
+	select USB_GADGET_SELECTED
 
 config USB_GADGET_PXA2XX
 	boolean "PXA 25x or IXP 4xx"
@@ -105,6 +109,7 @@ config USB_PXA2XX
 	tristate
 	depends on USB_GADGET_PXA2XX
 	default USB_GADGET
+	select USB_GADGET_SELECTED
 
 # if there's only one gadget driver, using only two bulk endpoints,
 # don't waste memory for the other endpoints
@@ -134,6 +139,7 @@ config USB_GOKU
 	tristate
 	depends on USB_GADGET_GOKU
 	default USB_GADGET
+	select USB_GADGET_SELECTED
 
 
 config USB_GADGET_LH7A40X
@@ -146,6 +152,7 @@ config USB_LH7A40X
 	tristate
 	depends on USB_GADGET_LH7A40X
 	default USB_GADGET
+	select USB_GADGET_SELECTED
 
 
 config USB_GADGET_OMAP
@@ -167,6 +174,7 @@ config USB_OMAP
 	tristate
 	depends on USB_GADGET_OMAP
 	default USB_GADGET
+	select USB_GADGET_SELECTED
 
 config USB_OTG
 	boolean "OTG Support"
@@ -207,6 +215,7 @@ config USB_DUMMY_HCD
 	tristate
 	depends on USB_GADGET_DUMMY_HCD
 	default USB_GADGET
+	select USB_GADGET_SELECTED
 
 # NOTE:  Please keep dummy_hcd LAST so that "real hardware" appears
 # first and will be selected by default.
@@ -226,7 +235,7 @@ config USB_GADGET_DUALSPEED
 #
 choice
 	tristate "USB Gadget Drivers"
-	depends on USB_GADGET
+	depends on USB_GADGET && USB_GADGET_SELECTED
 	default USB_ETH
 	help
 	  A Linux "Gadget Driver" talks to the USB Peripheral Controller
diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c
--- a/drivers/usb/gadget/dummy_hcd.c
+++ b/drivers/usb/gadget/dummy_hcd.c
@@ -65,7 +65,7 @@
 
 
 #define DRIVER_DESC	"USB Host+Gadget Emulator"
-#define DRIVER_VERSION	"17 Dec 2004"
+#define DRIVER_VERSION	"02 May 2005"
 
 static const char	driver_name [] = "dummy_hcd";
 static const char	driver_desc [] = "USB Host+Gadget Emulator";
@@ -141,6 +141,8 @@ static const char *const ep_name [] = {
 };
 #define DUMMY_ENDPOINTS	(sizeof(ep_name)/sizeof(char *))
 
+/*-------------------------------------------------------------------------*/
+
 #define FIFO_SIZE		64
 
 struct urbp {
@@ -148,6 +150,13 @@ struct urbp {
 	struct list_head	urbp_list;
 };
 
+
+enum dummy_rh_state {
+	DUMMY_RH_RESET,
+	DUMMY_RH_SUSPENDED,
+	DUMMY_RH_RUNNING
+};
+
 struct dummy {
 	spinlock_t			lock;
 
@@ -161,12 +170,18 @@ struct dummy {
 	struct dummy_request		fifo_req;
 	u8				fifo_buf [FIFO_SIZE];
 	u16				devstatus;
+	unsigned			udc_suspended:1;
+	unsigned			pullup:1;
+	unsigned			active:1;
+	unsigned			old_active:1;
 
 	/*
 	 * MASTER/HOST side support
 	 */
+	enum dummy_rh_state		rh_state;
 	struct timer_list		timer;
 	u32				port_status;
+	u32				old_status;
 	unsigned			resuming:1;
 	unsigned long			re_timeout;
 
@@ -189,6 +204,11 @@ static inline struct device *dummy_dev (
 	return dummy_to_hcd(dum)->self.controller;
 }
 
+static inline struct device *udc_dev (struct dummy *dum)
+{
+	return dum->gadget.dev.parent;
+}
+
 static inline struct dummy *ep_to_dummy (struct dummy_ep *ep)
 {
 	return container_of (ep->gadget, struct dummy, gadget);
@@ -208,16 +228,98 @@ static struct dummy			*the_controller;
 
 /*-------------------------------------------------------------------------*/
 
-/*
- * This "hardware" may look a bit odd in diagnostics since it's got both
- * host and device sides; and it binds different drivers to each side.
- */
-static struct platform_device		the_pdev;
+/* SLAVE/GADGET SIDE UTILITY ROUTINES */
 
-static struct device_driver dummy_driver = {
-	.name		= (char *) driver_name,
-	.bus		= &platform_bus_type,
-};
+/* called with spinlock held */
+static void nuke (struct dummy *dum, struct dummy_ep *ep)
+{
+	while (!list_empty (&ep->queue)) {
+		struct dummy_request	*req;
+
+		req = list_entry (ep->queue.next, struct dummy_request, queue);
+		list_del_init (&req->queue);
+		req->req.status = -ESHUTDOWN;
+
+		spin_unlock (&dum->lock);
+		req->req.complete (&ep->ep, &req->req);
+		spin_lock (&dum->lock);
+	}
+}
+
+/* caller must hold lock */
+static void
+stop_activity (struct dummy *dum)
+{
+	struct dummy_ep	*ep;
+
+	/* prevent any more requests */
+	dum->address = 0;
+
+	/* The timer is left running so that outstanding URBs can fail */
+
+	/* nuke any pending requests first, so driver i/o is quiesced */
+	list_for_each_entry (ep, &dum->gadget.ep_list, ep.ep_list)
+		nuke (dum, ep);
+
+	/* driver now does any non-usb quiescing necessary */
+}
+
+/* caller must hold lock */
+static void
+set_link_state (struct dummy *dum)
+{
+	dum->active = 0;
+	if ((dum->port_status & USB_PORT_STAT_POWER) == 0)
+		dum->port_status = 0;
+
+	/* UDC suspend must cause a disconnect */
+	else if (!dum->pullup || dum->udc_suspended) {
+		dum->port_status &= ~(USB_PORT_STAT_CONNECTION |
+					USB_PORT_STAT_ENABLE |
+					USB_PORT_STAT_LOW_SPEED |
+					USB_PORT_STAT_HIGH_SPEED |
+					USB_PORT_STAT_SUSPEND);
+		if ((dum->old_status & USB_PORT_STAT_CONNECTION) != 0)
+			dum->port_status |= (USB_PORT_STAT_C_CONNECTION << 16);
+	} else {
+		dum->port_status |= USB_PORT_STAT_CONNECTION;
+		if ((dum->old_status & USB_PORT_STAT_CONNECTION) == 0)
+			dum->port_status |= (USB_PORT_STAT_C_CONNECTION << 16);
+		if ((dum->port_status & USB_PORT_STAT_ENABLE) == 0)
+			dum->port_status &= ~USB_PORT_STAT_SUSPEND;
+		else if ((dum->port_status & USB_PORT_STAT_SUSPEND) == 0 &&
+				dum->rh_state != DUMMY_RH_SUSPENDED)
+			dum->active = 1;
+	}
+
+	if ((dum->port_status & USB_PORT_STAT_ENABLE) == 0 || dum->active)
+		dum->resuming = 0;
+
+	if ((dum->port_status & USB_PORT_STAT_CONNECTION) == 0 ||
+			(dum->port_status & USB_PORT_STAT_RESET) != 0) {
+		if ((dum->old_status & USB_PORT_STAT_CONNECTION) != 0 &&
+				(dum->old_status & USB_PORT_STAT_RESET) == 0 &&
+				dum->driver) {
+			stop_activity (dum);
+			spin_unlock (&dum->lock);
+			dum->driver->disconnect (&dum->gadget);
+			spin_lock (&dum->lock);
+		}
+	} else if (dum->active != dum->old_active) {
+		if (dum->old_active && dum->driver->suspend) {
+			spin_unlock (&dum->lock);
+			dum->driver->suspend (&dum->gadget);
+			spin_lock (&dum->lock);
+		} else if (!dum->old_active && dum->driver->resume) {
+			spin_unlock (&dum->lock);
+			dum->driver->resume (&dum->gadget);
+			spin_lock (&dum->lock);
+		}
+	}
+
+	dum->old_status = dum->port_status;
+	dum->old_active = dum->active;
+}
 
 /*-------------------------------------------------------------------------*/
 
@@ -324,7 +426,7 @@ dummy_enable (struct usb_ep *_ep, const 
 	_ep->maxpacket = max;
 	ep->desc = desc;
 
-	dev_dbg (dummy_dev(dum), "enabled %s (ep%d%s-%s) maxpacket %d\n",
+	dev_dbg (udc_dev(dum), "enabled %s (ep%d%s-%s) maxpacket %d\n",
 		_ep->name,
 		desc->bEndpointAddress & 0x0f,
 		(desc->bEndpointAddress & USB_DIR_IN) ? "in" : "out",
@@ -345,22 +447,6 @@ done:
 	return retval;
 }
 
-/* called with spinlock held */
-static void nuke (struct dummy *dum, struct dummy_ep *ep)
-{
-	while (!list_empty (&ep->queue)) {
-		struct dummy_request	*req;
-
-		req = list_entry (ep->queue.next, struct dummy_request, queue);
-		list_del_init (&req->queue);
-		req->req.status = -ESHUTDOWN;
-
-		spin_unlock (&dum->lock);
-		req->req.complete (&ep->ep, &req->req);
-		spin_lock (&dum->lock);
-	}
-}
-
 static int dummy_disable (struct usb_ep *_ep)
 {
 	struct dummy_ep		*ep;
@@ -379,12 +465,12 @@ static int dummy_disable (struct usb_ep 
 	nuke (dum, ep);
 	spin_unlock_irqrestore (&dum->lock, flags);
 
-	dev_dbg (dummy_dev(dum), "disabled %s\n", _ep->name);
+	dev_dbg (udc_dev(dum), "disabled %s\n", _ep->name);
 	return retval;
 }
 
 static struct usb_request *
-dummy_alloc_request (struct usb_ep *_ep, int mem_flags)
+dummy_alloc_request (struct usb_ep *_ep, unsigned mem_flags)
 {
 	struct dummy_ep		*ep;
 	struct dummy_request	*req;
@@ -421,7 +507,7 @@ dummy_alloc_buffer (
 	struct usb_ep *_ep,
 	unsigned bytes,
 	dma_addr_t *dma,
-	int mem_flags
+	unsigned mem_flags
 ) {
 	char			*retval;
 	struct dummy_ep		*ep;
@@ -454,7 +540,8 @@ fifo_complete (struct usb_ep *ep, struct
 }
 
 static int
-dummy_queue (struct usb_ep *_ep, struct usb_request *_req, int mem_flags)
+dummy_queue (struct usb_ep *_ep, struct usb_request *_req,
+		unsigned mem_flags)
 {
 	struct dummy_ep		*ep;
 	struct dummy_request	*req;
@@ -474,7 +561,7 @@ dummy_queue (struct usb_ep *_ep, struct 
 		return -ESHUTDOWN;
 
 #if 0
-	dev_dbg (dummy_dev(dum), "ep %p queue req %p to %s, len %d buf %p\n",
+	dev_dbg (udc_dev(dum), "ep %p queue req %p to %s, len %d buf %p\n",
 			ep, _req, _ep->name, _req->length, _req->buf);
 #endif
 
@@ -537,7 +624,7 @@ static int dummy_dequeue (struct usb_ep 
 	spin_unlock_irqrestore (&dum->lock, flags);
 
 	if (retval == 0) {
-		dev_dbg (dummy_dev(dum),
+		dev_dbg (udc_dev(dum),
 				"dequeued req %p from %s, len %d buf %p\n",
 				req, _ep->name, _req->length, _req->buf);
 		_req->complete (_ep, _req);
@@ -601,13 +688,21 @@ static int dummy_wakeup (struct usb_gadg
 	struct dummy	*dum;
 
 	dum = gadget_to_dummy (_gadget);
-	if ((dum->devstatus & (1 << USB_DEVICE_REMOTE_WAKEUP)) == 0
-			|| !(dum->port_status & (1 << USB_PORT_FEAT_SUSPEND)))
+	if (!(dum->devstatus &	( (1 << USB_DEVICE_B_HNP_ENABLE)
+				| (1 << USB_DEVICE_REMOTE_WAKEUP))))
 		return -EINVAL;
+	if ((dum->port_status & USB_PORT_STAT_CONNECTION) == 0)
+		return -ENOLINK;
+	if ((dum->port_status & USB_PORT_STAT_SUSPEND) == 0 &&
+			 dum->rh_state != DUMMY_RH_SUSPENDED)
+		return -EIO;
+
+	/* FIXME: What if the root hub is suspended but the port isn't? */
 
 	/* hub notices our request, issues downstream resume, etc */
 	dum->resuming = 1;
-	dum->port_status |= (1 << USB_PORT_FEAT_C_SUSPEND);
+	dum->re_timeout = jiffies + msecs_to_jiffies(20);
+	mod_timer (&dummy_to_hcd (dum)->rh_timer, dum->re_timeout);
 	return 0;
 }
 
@@ -623,17 +718,33 @@ static int dummy_set_selfpowered (struct
 	return 0;
 }
 
+static int dummy_pullup (struct usb_gadget *_gadget, int value)
+{
+	struct dummy	*dum;
+	unsigned long	flags;
+
+	dum = gadget_to_dummy (_gadget);
+	spin_lock_irqsave (&dum->lock, flags);
+	dum->pullup = (value != 0);
+	set_link_state (dum);
+	spin_unlock_irqrestore (&dum->lock, flags);
+
+	usb_hcd_poll_rh_status (dummy_to_hcd (dum));
+	return 0;
+}
+
 static const struct usb_gadget_ops dummy_ops = {
 	.get_frame	= dummy_g_get_frame,
 	.wakeup		= dummy_wakeup,
 	.set_selfpowered = dummy_set_selfpowered,
+	.pullup		= dummy_pullup,
 };
 
 /*-------------------------------------------------------------------------*/
 
 /* "function" sysfs attribute */
 static ssize_t
-show_function (struct device *dev, char *buf)
+show_function (struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct dummy	*dum = gadget_dev_to_dummy (dev);
 
@@ -641,7 +752,7 @@ show_function (struct device *dev, char 
 		return 0;
 	return scnprintf (buf, PAGE_SIZE, "%s\n", dum->driver->function);
 }
-DEVICE_ATTR (function, S_IRUGO, show_function, NULL);
+static DEVICE_ATTR (function, S_IRUGO, show_function, NULL);
 
 /*-------------------------------------------------------------------------*/
 
@@ -659,38 +770,6 @@ DEVICE_ATTR (function, S_IRUGO, show_fun
  * for each driver that registers:  just add to a big root hub.
  */
 
-static void
-dummy_udc_release (struct device *dev)
-{
-}
-
-static void
-dummy_pdev_release (struct device *dev)
-{
-}
-
-static int
-dummy_register_udc (struct dummy *dum)
-{
-	int		rc;
-
-	strcpy (dum->gadget.dev.bus_id, "udc");
-	dum->gadget.dev.parent = dummy_dev(dum);
-	dum->gadget.dev.release = dummy_udc_release;
-
-	rc = device_register (&dum->gadget.dev);
-	if (rc == 0)
-		device_create_file (&dum->gadget.dev, &dev_attr_function);
-	return rc;
-}
-
-static void
-dummy_unregister_udc (struct dummy *dum)
-{
-	device_remove_file (&dum->gadget.dev, &dev_attr_function);
-	device_unregister (&dum->gadget.dev);
-}
-
 int
 usb_gadget_register_driver (struct usb_gadget_driver *driver)
 {
@@ -709,12 +788,8 @@ usb_gadget_register_driver (struct usb_g
 	 * SLAVE side init ... the layer above hardware, which
 	 * can't enumerate without help from the driver we're binding.
 	 */
-	dum->gadget.name = gadget_name;
-	dum->gadget.ops = &dummy_ops;
-	dum->gadget.is_dualspeed = 1;
 
 	dum->devstatus = 0;
-	dum->resuming = 0;
 
 	INIT_LIST_HEAD (&dum->gadget.ep_list);
 	for (i = 0; i < DUMMY_ENDPOINTS; i++) {
@@ -740,7 +815,7 @@ usb_gadget_register_driver (struct usb_g
 
 	dum->driver = driver;
 	dum->gadget.dev.driver = &driver->driver;
-	dev_dbg (dummy_dev(dum), "binding gadget driver '%s'\n",
+	dev_dbg (udc_dev(dum), "binding gadget driver '%s'\n",
 			driver->driver.name);
 	if ((retval = driver->bind (&dum->gadget)) != 0) {
 		dum->driver = NULL;
@@ -748,42 +823,21 @@ usb_gadget_register_driver (struct usb_g
 		return retval;
 	}
 
-	// FIXME: Check these calls for errors and re-order
 	driver->driver.bus = dum->gadget.dev.parent->bus;
 	driver_register (&driver->driver);
-
 	device_bind_driver (&dum->gadget.dev);
 
 	/* khubd will enumerate this in a while */
-	dum->port_status |= USB_PORT_STAT_CONNECTION
-		| (1 << USB_PORT_FEAT_C_CONNECTION);
+	spin_lock_irq (&dum->lock);
+	dum->pullup = 1;
+	set_link_state (dum);
+	spin_unlock_irq (&dum->lock);
+
+	usb_hcd_poll_rh_status (dummy_to_hcd (dum));
 	return 0;
 }
 EXPORT_SYMBOL (usb_gadget_register_driver);
 
-/* caller must hold lock */
-static void
-stop_activity (struct dummy *dum, struct usb_gadget_driver *driver)
-{
-	struct dummy_ep	*ep;
-
-	/* prevent any more requests */
-	dum->address = 0;
-
-	/* The timer is left running so that outstanding URBs can fail */
-
-	/* nuke any pending requests first, so driver i/o is quiesced */
-	list_for_each_entry (ep, &dum->gadget.ep_list, ep.ep_list)
-		nuke (dum, ep);
-
-	/* driver now does any non-usb quiescing necessary */
-	if (driver) {
-		spin_unlock (&dum->lock);
-		driver->disconnect (&dum->gadget);
-		spin_lock (&dum->lock);
-	}
-}
-
 int
 usb_gadget_unregister_driver (struct usb_gadget_driver *driver)
 {
@@ -795,35 +849,138 @@ usb_gadget_unregister_driver (struct usb
 	if (!driver || driver != dum->driver)
 		return -EINVAL;
 
-	dev_dbg (dummy_dev(dum), "unregister gadget driver '%s'\n",
+	dev_dbg (udc_dev(dum), "unregister gadget driver '%s'\n",
 			driver->driver.name);
 
 	spin_lock_irqsave (&dum->lock, flags);
-	stop_activity (dum, driver);
-	dum->port_status &= ~(USB_PORT_STAT_CONNECTION | USB_PORT_STAT_ENABLE |
-			USB_PORT_STAT_LOW_SPEED | USB_PORT_STAT_HIGH_SPEED);
-	dum->port_status |= (1 << USB_PORT_FEAT_C_CONNECTION);
+	dum->pullup = 0;
+	set_link_state (dum);
 	spin_unlock_irqrestore (&dum->lock, flags);
 
 	driver->unbind (&dum->gadget);
 	dum->driver = NULL;
 
 	device_release_driver (&dum->gadget.dev);
-
 	driver_unregister (&driver->driver);
 
+	spin_lock_irqsave (&dum->lock, flags);
+	dum->pullup = 0;
+	set_link_state (dum);
+	spin_unlock_irqrestore (&dum->lock, flags);
+
+	usb_hcd_poll_rh_status (dummy_to_hcd (dum));
 	return 0;
 }
 EXPORT_SYMBOL (usb_gadget_unregister_driver);
 
 #undef is_enabled
 
+/* just declare this in any driver that really need it */
+extern int net2280_set_fifo_mode (struct usb_gadget *gadget, int mode);
+
 int net2280_set_fifo_mode (struct usb_gadget *gadget, int mode)
 {
 	return -ENOSYS;
 }
 EXPORT_SYMBOL (net2280_set_fifo_mode);
 
+
+/* The gadget structure is stored inside the hcd structure and will be
+ * released along with it. */
+static void
+dummy_gadget_release (struct device *dev)
+{
+#if 0		/* usb_bus_put isn't EXPORTed! */
+	struct dummy	*dum = gadget_dev_to_dummy (dev);
+
+	usb_bus_put (&dummy_to_hcd (dum)->self);
+#endif
+}
+
+static int dummy_udc_probe (struct device *dev)
+{
+	struct dummy	*dum = the_controller;
+	int		rc;
+
+	dum->gadget.name = gadget_name;
+	dum->gadget.ops = &dummy_ops;
+	dum->gadget.is_dualspeed = 1;
+
+	/* maybe claim OTG support, though we won't complete HNP */
+	dum->gadget.is_otg = (dummy_to_hcd(dum)->self.otg_port != 0);
+
+	strcpy (dum->gadget.dev.bus_id, "gadget");
+	dum->gadget.dev.parent = dev;
+	dum->gadget.dev.release = dummy_gadget_release;
+	rc = device_register (&dum->gadget.dev);
+	if (rc < 0)
+		return rc;
+
+#if 0		/* usb_bus_get isn't EXPORTed! */
+	usb_bus_get (&dummy_to_hcd (dum)->self);
+#endif
+
+	dev_set_drvdata (dev, dum);
+	device_create_file (&dum->gadget.dev, &dev_attr_function);
+	return rc;
+}
+
+static int dummy_udc_remove (struct device *dev)
+{
+	struct dummy	*dum = dev_get_drvdata (dev);
+
+	dev_set_drvdata (dev, NULL);
+	device_remove_file (&dum->gadget.dev, &dev_attr_function);
+	device_unregister (&dum->gadget.dev);
+	return 0;
+}
+
+static int dummy_udc_suspend (struct device *dev, pm_message_t state,
+		u32 level)
+{
+	struct dummy	*dum = dev_get_drvdata(dev);
+
+	if (level != SUSPEND_DISABLE)
+		return 0;
+
+	dev_dbg (dev, "%s\n", __FUNCTION__);
+	spin_lock_irq (&dum->lock);
+	dum->udc_suspended = 1;
+	set_link_state (dum);
+	spin_unlock_irq (&dum->lock);
+
+	dev->power.power_state = state;
+	usb_hcd_poll_rh_status (dummy_to_hcd (dum));
+	return 0;
+}
+
+static int dummy_udc_resume (struct device *dev, u32 level)
+{
+	struct dummy	*dum = dev_get_drvdata(dev);
+
+	if (level != RESUME_ENABLE)
+		return 0;
+
+	dev_dbg (dev, "%s\n", __FUNCTION__);
+	spin_lock_irq (&dum->lock);
+	dum->udc_suspended = 0;
+	set_link_state (dum);
+	spin_unlock_irq (&dum->lock);
+
+	dev->power.power_state = PMSG_ON;
+	usb_hcd_poll_rh_status (dummy_to_hcd (dum));
+	return 0;
+}
+
+static struct device_driver dummy_udc_driver = {
+	.name		= (char *) gadget_name,
+	.bus		= &platform_bus_type,
+	.probe		= dummy_udc_probe,
+	.remove		= dummy_udc_remove,
+	.suspend	= dummy_udc_suspend,
+	.resume		= dummy_udc_resume,
+};
+
 /*-------------------------------------------------------------------------*/
 
 /* MASTER/HOST SIDE DRIVER
@@ -842,7 +999,7 @@ static int dummy_urb_enqueue (
 	struct usb_hcd			*hcd,
 	struct usb_host_endpoint	*ep,
 	struct urb			*urb,
-	int				mem_flags
+	unsigned			mem_flags
 ) {
 	struct dummy	*dum;
 	struct urbp	*urbp;
@@ -880,7 +1037,16 @@ static int dummy_urb_enqueue (
 
 static int dummy_urb_dequeue (struct usb_hcd *hcd, struct urb *urb)
 {
-	/* giveback happens automatically in timer callback */
+	struct dummy	*dum;
+	unsigned long	flags;
+
+	/* giveback happens automatically in timer callback,
+	 * so make sure the callback happens */
+	dum = hcd_to_dummy (hcd);
+	spin_lock_irqsave (&dum->lock, flags);
+	if (dum->rh_state != DUMMY_RH_RUNNING && !list_empty(&dum->urbp_list))
+		mod_timer (&dum->timer, jiffies);
+	spin_unlock_irqrestore (&dum->lock, flags);
 	return 0;
 }
 
@@ -1025,7 +1191,6 @@ static int periodic_bytes (struct dummy 
 
 		/* high bandwidth mode */
 		tmp = le16_to_cpu(ep->desc->wMaxPacketSize);
-		tmp = le16_to_cpu (tmp);
 		tmp = (tmp >> 11) & 0x03;
 		tmp *= 8 /* applies to entire frame */;
 		limit += limit * tmp;
@@ -1123,7 +1288,8 @@ restart:
 		if (urb->status != -EINPROGRESS) {
 			/* likely it was just unlinked */
 			goto return_urb;
-		}
+		} else if (dum->rh_state != DUMMY_RH_RUNNING)
+			continue;
 		type = usb_pipetype (urb->pipe);
 
 		/* used up this frame's non-periodic bandwidth?
@@ -1168,12 +1334,14 @@ restart:
 			struct usb_ctrlrequest		setup;
 			int				value = 1;
 			struct dummy_ep			*ep2;
+			unsigned			w_index;
+			unsigned			w_value;
 
 			setup = *(struct usb_ctrlrequest*) urb->setup_packet;
-			le16_to_cpus (&setup.wIndex);
-			le16_to_cpus (&setup.wValue);
-			le16_to_cpus (&setup.wLength);
-			if (setup.wLength != urb->transfer_buffer_length) {
+			w_index = le16_to_cpu(setup.wIndex);
+			w_value = le16_to_cpu(setup.wValue);
+			if (le16_to_cpu(setup.wLength) !=
+					urb->transfer_buffer_length) {
 				maybe_set_status (urb, -EOVERFLOW);
 				goto return_urb;
 			}
@@ -1182,7 +1350,7 @@ restart:
 			list_for_each_entry (req, &ep->queue, queue) {
 				list_del_init (&req->queue);
 				req->req.status = -EOVERFLOW;
-				dev_dbg (dummy_dev(dum), "stale req = %p\n",
+				dev_dbg (udc_dev(dum), "stale req = %p\n",
 						req);
 
 				spin_unlock (&dum->lock);
@@ -1203,31 +1371,40 @@ restart:
 			case USB_REQ_SET_ADDRESS:
 				if (setup.bRequestType != Dev_Request)
 					break;
-				dum->address = setup.wValue;
+				dum->address = w_value;
 				maybe_set_status (urb, 0);
-				dev_dbg (dummy_dev(dum), "set_address = %d\n",
-						setup.wValue);
+				dev_dbg (udc_dev(dum), "set_address = %d\n",
+						w_value);
 				value = 0;
 				break;
 			case USB_REQ_SET_FEATURE:
 				if (setup.bRequestType == Dev_Request) {
 					value = 0;
-					switch (setup.wValue) {
+					switch (w_value) {
 					case USB_DEVICE_REMOTE_WAKEUP:
 						break;
+					case USB_DEVICE_B_HNP_ENABLE:
+						dum->gadget.b_hnp_enable = 1;
+						break;
+					case USB_DEVICE_A_HNP_SUPPORT:
+						dum->gadget.a_hnp_support = 1;
+						break;
+					case USB_DEVICE_A_ALT_HNP_SUPPORT:
+						dum->gadget.a_alt_hnp_support
+							= 1;
+						break;
 					default:
 						value = -EOPNOTSUPP;
 					}
 					if (value == 0) {
 						dum->devstatus |=
-							(1 << setup.wValue);
+							(1 << w_value);
 						maybe_set_status (urb, 0);
 					}
 
 				} else if (setup.bRequestType == Ep_Request) {
 					// endpoint halt
-					ep2 = find_endpoint (dum,
-							setup.wIndex);
+					ep2 = find_endpoint (dum, w_index);
 					if (!ep2) {
 						value = -EOPNOTSUPP;
 						break;
@@ -1239,7 +1416,7 @@ restart:
 				break;
 			case USB_REQ_CLEAR_FEATURE:
 				if (setup.bRequestType == Dev_Request) {
-					switch (setup.wValue) {
+					switch (w_value) {
 					case USB_DEVICE_REMOTE_WAKEUP:
 						dum->devstatus &= ~(1 <<
 							USB_DEVICE_REMOTE_WAKEUP);
@@ -1252,8 +1429,7 @@ restart:
 					}
 				} else if (setup.bRequestType == Ep_Request) {
 					// endpoint halt
-					ep2 = find_endpoint (dum,
-							setup.wIndex);
+					ep2 = find_endpoint (dum, w_index);
 					if (!ep2) {
 						value = -EOPNOTSUPP;
 						break;
@@ -1279,7 +1455,7 @@ restart:
 					if (urb->transfer_buffer_length > 0) {
 						if (setup.bRequestType ==
 								Ep_InRequest) {
-	ep2 = find_endpoint (dum, setup.wIndex);
+	ep2 = find_endpoint (dum, w_index);
 	if (!ep2) {
 		value = -EOPNOTSUPP;
 		break;
@@ -1321,7 +1497,7 @@ restart:
 
 			if (value < 0) {
 				if (value != -EOPNOTSUPP)
-					dev_dbg (dummy_dev(dum),
+					dev_dbg (udc_dev(dum),
 						"setup --> %d\n",
 						value);
 				maybe_set_status (urb, -EPIPE);
@@ -1377,12 +1553,12 @@ return_urb:
 		goto restart;
 	}
 
-	/* want a 1 msec delay here */
-	if (!list_empty (&dum->urbp_list))
-		mod_timer (&dum->timer, jiffies + msecs_to_jiffies(1));
-	else {
+	if (list_empty (&dum->urbp_list)) {
 		usb_put_dev (dum->udev);
 		dum->udev = NULL;
+	} else if (dum->rh_state == DUMMY_RH_RUNNING) {
+		/* want a 1 msec delay here */
+		mod_timer (&dum->timer, jiffies + msecs_to_jiffies(1));
 	}
 
 	spin_unlock_irqrestore (&dum->lock, flags);
@@ -1391,29 +1567,39 @@ return_urb:
 /*-------------------------------------------------------------------------*/
 
 #define PORT_C_MASK \
-	 ((1 << USB_PORT_FEAT_C_CONNECTION) \
-	| (1 << USB_PORT_FEAT_C_ENABLE) \
-	| (1 << USB_PORT_FEAT_C_SUSPEND) \
-	| (1 << USB_PORT_FEAT_C_OVER_CURRENT) \
-	| (1 << USB_PORT_FEAT_C_RESET))
+	((USB_PORT_STAT_C_CONNECTION \
+	| USB_PORT_STAT_C_ENABLE \
+	| USB_PORT_STAT_C_SUSPEND \
+	| USB_PORT_STAT_C_OVERCURRENT \
+	| USB_PORT_STAT_C_RESET) << 16)
 
 static int dummy_hub_status (struct usb_hcd *hcd, char *buf)
 {
 	struct dummy		*dum;
 	unsigned long		flags;
-	int			retval;
+	int			retval = 0;
 
 	dum = hcd_to_dummy (hcd);
 
 	spin_lock_irqsave (&dum->lock, flags);
-	if (!(dum->port_status & PORT_C_MASK))
-		retval = 0;
-	else {
+	if (hcd->state != HC_STATE_RUNNING)
+		goto done;
+
+	if (dum->resuming && time_after_eq (jiffies, dum->re_timeout)) {
+		dum->port_status |= (USB_PORT_STAT_C_SUSPEND << 16);
+		dum->port_status &= ~USB_PORT_STAT_SUSPEND;
+		set_link_state (dum);
+	}
+
+	if ((dum->port_status & PORT_C_MASK) != 0) {
 		*buf = (1 << 1);
 		dev_dbg (dummy_dev(dum), "port status 0x%08x has changes\n",
-			dum->port_status);
+				dum->port_status);
 		retval = 1;
+		if (dum->rh_state == DUMMY_RH_SUSPENDED)
+			usb_hcd_resume_root_hub (hcd);
 	}
+done:
 	spin_unlock_irqrestore (&dum->lock, flags);
 	return retval;
 }
@@ -1424,7 +1610,8 @@ hub_descriptor (struct usb_hub_descripto
 	memset (desc, 0, sizeof *desc);
 	desc->bDescriptorType = 0x29;
 	desc->bDescLength = 9;
-	desc->wHubCharacteristics = __constant_cpu_to_le16 (0x0001);
+	desc->wHubCharacteristics = (__force __u16)
+			(__constant_cpu_to_le16 (0x0001));
 	desc->bNbrPorts = 1;
 	desc->bitmap [0] = 0xff;
 	desc->bitmap [1] = 0xff;
@@ -1442,6 +1629,9 @@ static int dummy_hub_control (
 	int		retval = 0;
 	unsigned long	flags;
 
+	if (hcd->state != HC_STATE_RUNNING)
+		return -ETIMEDOUT;
+
 	dum = hcd_to_dummy (hcd);
 	spin_lock_irqsave (&dum->lock, flags);
 	switch (typeReq) {
@@ -1450,27 +1640,27 @@ static int dummy_hub_control (
 	case ClearPortFeature:
 		switch (wValue) {
 		case USB_PORT_FEAT_SUSPEND:
-			if (dum->port_status & (1 << USB_PORT_FEAT_SUSPEND)) {
+			if (dum->port_status & USB_PORT_STAT_SUSPEND) {
 				/* 20msec resume signaling */
 				dum->resuming = 1;
 				dum->re_timeout = jiffies +
-							msecs_to_jiffies(20);
+						msecs_to_jiffies(20);
 			}
 			break;
 		case USB_PORT_FEAT_POWER:
-			dum->port_status = 0;
-			dum->resuming = 0;
-			stop_activity(dum, dum->driver);
-			break;
+			if (dum->port_status & USB_PORT_STAT_POWER)
+				dev_dbg (dummy_dev(dum), "power-off\n");
+			/* FALLS THROUGH */
 		default:
 			dum->port_status &= ~(1 << wValue);
+			set_link_state (dum);
 		}
 		break;
 	case GetHubDescriptor:
 		hub_descriptor ((struct usb_hub_descriptor *) buf);
 		break;
 	case GetHubStatus:
-		*(u32 *) buf = __constant_cpu_to_le32 (0);
+		*(__le32 *) buf = __constant_cpu_to_le32 (0);
 		break;
 	case GetPortStatus:
 		if (wIndex != 1)
@@ -1479,23 +1669,16 @@ static int dummy_hub_control (
 		/* whoever resets or resumes must GetPortStatus to
 		 * complete it!!
 		 */
-		if (dum->resuming && time_after (jiffies, dum->re_timeout)) {
-			dum->port_status |= (1 << USB_PORT_FEAT_C_SUSPEND);
-			dum->port_status &= ~(1 << USB_PORT_FEAT_SUSPEND);
-			dum->resuming = 0;
-			dum->re_timeout = 0;
-			if (dum->driver && dum->driver->resume) {
-				spin_unlock (&dum->lock);
-				dum->driver->resume (&dum->gadget);
-				spin_lock (&dum->lock);
-			}
+		if (dum->resuming &&
+				time_after_eq (jiffies, dum->re_timeout)) {
+			dum->port_status |= (USB_PORT_STAT_C_SUSPEND << 16);
+			dum->port_status &= ~USB_PORT_STAT_SUSPEND;
 		}
-		if ((dum->port_status & (1 << USB_PORT_FEAT_RESET)) != 0
-				&& time_after (jiffies, dum->re_timeout)) {
-			dum->port_status |= (1 << USB_PORT_FEAT_C_RESET);
-			dum->port_status &= ~(1 << USB_PORT_FEAT_RESET);
-			dum->re_timeout = 0;
-			if (dum->driver) {
+		if ((dum->port_status & USB_PORT_STAT_RESET) != 0 &&
+				time_after_eq (jiffies, dum->re_timeout)) {
+			dum->port_status |= (USB_PORT_STAT_C_RESET << 16);
+			dum->port_status &= ~USB_PORT_STAT_RESET;
+			if (dum->pullup) {
 				dum->port_status |= USB_PORT_STAT_ENABLE;
 				/* give it the best speed we agree on */
 				dum->gadget.speed = dum->driver->speed;
@@ -1516,8 +1699,9 @@ static int dummy_hub_control (
 				}
 			}
 		}
-		((u16 *) buf)[0] = cpu_to_le16 (dum->port_status);
-		((u16 *) buf)[1] = cpu_to_le16 (dum->port_status >> 16);
+		set_link_state (dum);
+		((__le16 *) buf)[0] = cpu_to_le16 (dum->port_status);
+		((__le16 *) buf)[1] = cpu_to_le16 (dum->port_status >> 16);
 		break;
 	case SetHubFeature:
 		retval = -EPIPE;
@@ -1525,36 +1709,37 @@ static int dummy_hub_control (
 	case SetPortFeature:
 		switch (wValue) {
 		case USB_PORT_FEAT_SUSPEND:
-			if ((dum->port_status & (1 << USB_PORT_FEAT_SUSPEND))
-					== 0) {
-				dum->port_status |=
-						(1 << USB_PORT_FEAT_SUSPEND);
-				if (dum->driver && dum->driver->suspend) {
-					spin_unlock (&dum->lock);
-					dum->driver->suspend (&dum->gadget);
-					spin_lock (&dum->lock);
-				}
+			if (dum->active) {
+				dum->port_status |= USB_PORT_STAT_SUSPEND;
+
+				/* HNP would happen here; for now we
+				 * assume b_bus_req is always true.
+				 */
+				set_link_state (dum);
+				if (((1 << USB_DEVICE_B_HNP_ENABLE)
+						& dum->devstatus) != 0)
+					dev_dbg (dummy_dev(dum),
+							"no HNP yet!\n");
 			}
 			break;
+		case USB_PORT_FEAT_POWER:
+			dum->port_status |= USB_PORT_STAT_POWER;
+			set_link_state (dum);
+			break;
 		case USB_PORT_FEAT_RESET:
-			/* if it's already running, disconnect first */
-			if (dum->port_status & USB_PORT_STAT_ENABLE) {
-				dum->port_status &= ~(USB_PORT_STAT_ENABLE
-						| USB_PORT_STAT_LOW_SPEED
-						| USB_PORT_STAT_HIGH_SPEED);
-				if (dum->driver) {
-					dev_dbg (dummy_dev(dum),
-							"disconnect\n");
-					stop_activity (dum, dum->driver);
-				}
-
-				/* FIXME test that code path! */
-			}
+			/* if it's already enabled, disable */
+			dum->port_status &= ~(USB_PORT_STAT_ENABLE
+					| USB_PORT_STAT_LOW_SPEED
+					| USB_PORT_STAT_HIGH_SPEED);
+			dum->devstatus = 0;
 			/* 50msec reset signaling */
 			dum->re_timeout = jiffies + msecs_to_jiffies(50);
-			/* FALLTHROUGH */
+			/* FALLS THROUGH */
 		default:
-			dum->port_status |= (1 << wValue);
+			if ((dum->port_status & USB_PORT_STAT_POWER) != 0) {
+				dum->port_status |= (1 << wValue);
+				set_link_state (dum);
+			}
 		}
 		break;
 
@@ -1567,9 +1752,35 @@ static int dummy_hub_control (
 		retval = -EPIPE;
 	}
 	spin_unlock_irqrestore (&dum->lock, flags);
+
+	if ((dum->port_status & PORT_C_MASK) != 0)
+		usb_hcd_poll_rh_status (hcd);
 	return retval;
 }
 
+static int dummy_hub_suspend (struct usb_hcd *hcd)
+{
+	struct dummy *dum = hcd_to_dummy (hcd);
+
+	spin_lock_irq (&dum->lock);
+	dum->rh_state = DUMMY_RH_SUSPENDED;
+	set_link_state (dum);
+	spin_unlock_irq (&dum->lock);
+	return 0;
+}
+
+static int dummy_hub_resume (struct usb_hcd *hcd)
+{
+	struct dummy *dum = hcd_to_dummy (hcd);
+
+	spin_lock_irq (&dum->lock);
+	dum->rh_state = DUMMY_RH_RUNNING;
+	set_link_state (dum);
+	if (!list_empty(&dum->urbp_list))
+		mod_timer (&dum->timer, jiffies);
+	spin_unlock_irq (&dum->lock);
+	return 0;
+}
 
 /*-------------------------------------------------------------------------*/
 
@@ -1600,7 +1811,7 @@ show_urb (char *buf, size_t size, struct
 }
 
 static ssize_t
-show_urbs (struct device *dev, char *buf)
+show_urbs (struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct usb_hcd		*hcd = dev_get_drvdata (dev);
 	struct dummy		*dum = hcd_to_dummy (hcd);
@@ -1625,8 +1836,6 @@ static DEVICE_ATTR (urbs, S_IRUGO, show_
 static int dummy_start (struct usb_hcd *hcd)
 {
 	struct dummy		*dum;
-	struct usb_device	*root;
-	int			retval;
 
 	dum = hcd_to_dummy (hcd);
 
@@ -1639,38 +1848,22 @@ static int dummy_start (struct usb_hcd *
 	init_timer (&dum->timer);
 	dum->timer.function = dummy_timer;
 	dum->timer.data = (unsigned long) dum;
+	dum->rh_state = DUMMY_RH_RUNNING;
 
 	INIT_LIST_HEAD (&dum->urbp_list);
 
-	root = usb_alloc_dev (NULL, &hcd->self, 0);
-	if (!root)
-		return -ENOMEM;
-
-	/* root hub enters addressed state... */
-	hcd->state = HC_STATE_RUNNING;
-	root->speed = USB_SPEED_HIGH;
-
-	/* ...then configured, so khubd sees us. */
-	if ((retval = usb_hcd_register_root_hub (root, hcd)) != 0) {
-		goto err1;
-	}
-
 	/* only show a low-power port: just 8mA */
-	hub_set_power_budget (root, 8);
+	hcd->power_budget = 8;
+	hcd->state = HC_STATE_RUNNING;
+	hcd->uses_new_polling = 1;
 
-	if ((retval = dummy_register_udc (dum)) != 0)
-		goto err2;
+#ifdef CONFIG_USB_OTG
+	hcd->self.otg_port = 1;
+#endif
 
 	/* FIXME 'urbs' should be a per-device thing, maybe in usbcore */
 	device_create_file (dummy_dev(dum), &dev_attr_urbs);
 	return 0;
-
- err2:
-	usb_disconnect (&hcd->self.root_hub);
- err1:
-	usb_put_dev (root);
-	hcd->state = HC_STATE_QUIESCING;
-	return retval;
 }
 
 static void dummy_stop (struct usb_hcd *hcd)
@@ -1680,10 +1873,7 @@ static void dummy_stop (struct usb_hcd *
 	dum = hcd_to_dummy (hcd);
 
 	device_remove_file (dummy_dev(dum), &dev_attr_urbs);
-
 	usb_gadget_unregister_driver (dum->driver);
-	dummy_unregister_udc (dum);
-
 	dev_info (dummy_dev(dum), "stopped\n");
 }
 
@@ -1711,9 +1901,11 @@ static const struct hc_driver dummy_hcd 
 
 	.hub_status_data = 	dummy_hub_status,
 	.hub_control = 		dummy_hub_control,
+	.hub_suspend =		dummy_hub_suspend,
+	.hub_resume =		dummy_hub_resume,
 };
 
-static int dummy_probe (struct device *dev)
+static int dummy_hcd_probe (struct device *dev)
 {
 	struct usb_hcd		*hcd;
 	int			retval;
@@ -1733,7 +1925,7 @@ static int dummy_probe (struct device *d
 	return retval;
 }
 
-static void dummy_remove (struct device *dev)
+static int dummy_hcd_remove (struct device *dev)
 {
 	struct usb_hcd		*hcd;
 
@@ -1741,53 +1933,127 @@ static void dummy_remove (struct device 
 	usb_remove_hcd (hcd);
 	usb_put_hcd (hcd);
 	the_controller = NULL;
+	return 0;
 }
 
-/*-------------------------------------------------------------------------*/
-
-static int dummy_pdev_detect (void)
+static int dummy_hcd_suspend (struct device *dev, pm_message_t state,
+		u32 level)
 {
-	int			retval;
+	struct usb_hcd		*hcd;
 
-	retval = driver_register (&dummy_driver);
-	if (retval < 0)
-		return retval;
+	if (level != SUSPEND_DISABLE)
+		return 0;
 
-	the_pdev.name = "hc";
-	the_pdev.dev.driver = &dummy_driver;
-	the_pdev.dev.release = dummy_pdev_release;
+	dev_dbg (dev, "%s\n", __FUNCTION__);
+	hcd = dev_get_drvdata (dev);
 
-	retval = platform_device_register (&the_pdev);
-	if (retval < 0)
-		driver_unregister (&dummy_driver);
-	return retval;
+#ifndef CONFIG_USB_SUSPEND
+	/* Otherwise this would never happen */
+	usb_lock_device (hcd->self.root_hub);
+	dummy_hub_suspend (hcd);
+	usb_unlock_device (hcd->self.root_hub);
+#endif
+
+	hcd->state = HC_STATE_SUSPENDED;
+	return 0;
 }
 
-static void dummy_pdev_remove (void)
+static int dummy_hcd_resume (struct device *dev, u32 level)
 {
-	platform_device_unregister (&the_pdev);
-	driver_unregister (&dummy_driver);
+	struct usb_hcd		*hcd;
+
+	if (level != RESUME_ENABLE)
+		return 0;
+
+	dev_dbg (dev, "%s\n", __FUNCTION__);
+	hcd = dev_get_drvdata (dev);
+	hcd->state = HC_STATE_RUNNING;
+
+#ifndef CONFIG_USB_SUSPEND
+	/* Otherwise this would never happen */
+	usb_lock_device (hcd->self.root_hub);
+	dummy_hub_resume (hcd);
+	usb_unlock_device (hcd->self.root_hub);
+#endif
+
+	usb_hcd_poll_rh_status (hcd);
+	return 0;
 }
 
+static struct device_driver dummy_hcd_driver = {
+	.name		= (char *) driver_name,
+	.bus		= &platform_bus_type,
+	.probe		= dummy_hcd_probe,
+	.remove		= dummy_hcd_remove,
+	.suspend	= dummy_hcd_suspend,
+	.resume		= dummy_hcd_resume,
+};
+
 /*-------------------------------------------------------------------------*/
 
+/* These don't need to do anything because the pdev structures are
+ * statically allocated. */
+static void
+dummy_udc_release (struct device *dev) {}
+
+static void
+dummy_hcd_release (struct device *dev) {}
+
+static struct platform_device		the_udc_pdev = {
+	.name		= (char *) gadget_name,
+	.id		= -1,
+	.dev		= {
+		.release	= dummy_udc_release,
+	},
+};
+
+static struct platform_device		the_hcd_pdev = {
+	.name		= (char *) driver_name,
+	.id		= -1,
+	.dev		= {
+		.release	= dummy_hcd_release,
+	},
+};
+
 static int __init init (void)
 {
 	int	retval;
 
 	if (usb_disabled ())
 		return -ENODEV;
-	if ((retval = dummy_pdev_detect ()) != 0)
+
+	retval = driver_register (&dummy_hcd_driver);
+	if (retval < 0)
 		return retval;
-	if ((retval = dummy_probe (&the_pdev.dev)) != 0)
-		dummy_pdev_remove ();
+
+	retval = driver_register (&dummy_udc_driver);
+	if (retval < 0)
+		goto err_register_udc_driver;
+
+	retval = platform_device_register (&the_hcd_pdev);
+	if (retval < 0)
+		goto err_register_hcd;
+
+	retval = platform_device_register (&the_udc_pdev);
+	if (retval < 0)
+		goto err_register_udc;
+	return retval;
+
+err_register_udc:
+	platform_device_unregister (&the_hcd_pdev);
+err_register_hcd:
+	driver_unregister (&dummy_udc_driver);
+err_register_udc_driver:
+	driver_unregister (&dummy_hcd_driver);
 	return retval;
 }
 module_init (init);
 
 static void __exit cleanup (void)
 {
-	dummy_remove (&the_pdev.dev);
-	dummy_pdev_remove ();
+	platform_device_unregister (&the_udc_pdev);
+	platform_device_unregister (&the_hcd_pdev);
+	driver_unregister (&dummy_udc_driver);
+	driver_unregister (&dummy_hcd_driver);
 }
 module_exit (cleanup);
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
--- a/drivers/usb/gadget/ether.c
+++ b/drivers/usb/gadget/ether.c
@@ -84,18 +84,19 @@
  */
 
 #define DRIVER_DESC		"Ethernet Gadget"
-#define DRIVER_VERSION		"Equinox 2004"
+#define DRIVER_VERSION		"May Day 2005"
 
 static const char shortname [] = "ether";
 static const char driver_desc [] = DRIVER_DESC;
 
 #define RX_EXTRA	20		/* guard against rx overflows */
 
-#ifdef	CONFIG_USB_ETH_RNDIS
 #include "rndis.h"
-#else
-#define rndis_init() 0
-#define rndis_exit() do{}while(0)
+
+#ifndef	CONFIG_USB_ETH_RNDIS
+#define rndis_uninit(x)		do{}while(0)
+#define rndis_deregister(c)	do{}while(0)
+#define rndis_exit()		do{}while(0)
 #endif
 
 /* CDC and RNDIS support the same host-chosen outgoing packet filters. */
@@ -140,9 +141,6 @@ struct eth_dev {
  * It also ASSUMES a self-powered device, without remote wakeup,
  * although remote wakeup support would make sense.
  */
-static const char *EP_IN_NAME;
-static const char *EP_OUT_NAME;
-static const char *EP_STATUS_NAME;
 
 /*-------------------------------------------------------------------------*/
 
@@ -312,6 +310,7 @@ static inline int rndis_active(struct et
 #define	FS_BPS		(19 *  64 * 1 * 1000 * 8)
 
 #ifdef CONFIG_USB_GADGET_DUALSPEED
+#define	DEVSPEED	USB_SPEED_HIGH
 
 static unsigned qmult = 5;
 module_param (qmult, uint, S_IRUGO|S_IWUSR);
@@ -330,6 +329,8 @@ static inline int BITRATE(struct usb_gad
 }
 
 #else	/* full speed (low speed doesn't do bulk) */
+#define	DEVSPEED	USB_SPEED_FULL
+
 #define qlen(gadget) DEFAULT_QLEN
 
 static inline int BITRATE(struct usb_gadget *g)
@@ -395,7 +396,8 @@ static inline int BITRATE(struct usb_gad
 #define STRING_SUBSET			8
 #define STRING_RNDIS			9
 
-#define USB_BUFSIZ	256		/* holds our biggest descriptor */
+/* holds our biggest descriptor (or RNDIS response) */
+#define USB_BUFSIZ	256
 
 /*
  * This device advertises one configuration, eth_config, unless RNDIS
@@ -538,7 +540,7 @@ static const struct usb_cdc_call_mgmt_de
 	.bDataInterface = 	0x01,
 };
 
-static struct usb_cdc_acm_descriptor acm_descriptor = {
+static const struct usb_cdc_acm_descriptor acm_descriptor = {
 	.bLength =  		sizeof acm_descriptor,
 	.bDescriptorType = 	USB_DT_CS_INTERFACE,
 	.bDescriptorSubType = 	USB_CDC_ACM_TYPE,
@@ -846,7 +848,7 @@ static const struct usb_descriptor_heade
 #else
 
 /* if there's no high speed support, maxpacket doesn't change. */
-#define ep_desc(g,hs,fs) fs
+#define ep_desc(g,hs,fs) (((void)(g)), (fs))
 
 static inline void __init hs_subset_descriptors(void)
 {
@@ -943,13 +945,36 @@ config_buf (enum usb_device_speed speed,
 
 /*-------------------------------------------------------------------------*/
 
-static void eth_start (struct eth_dev *dev, int gfp_flags);
-static int alloc_requests (struct eth_dev *dev, unsigned n, int gfp_flags);
+static void eth_start (struct eth_dev *dev, unsigned gfp_flags);
+static int alloc_requests (struct eth_dev *dev, unsigned n, unsigned gfp_flags);
 
-#ifdef	DEV_CONFIG_CDC
-static inline int ether_alt_ep_setup (struct eth_dev *dev, struct usb_ep *ep)
+static int
+set_ether_config (struct eth_dev *dev, unsigned gfp_flags)
 {
-	const struct usb_endpoint_descriptor	*d;
+	int					result = 0;
+	struct usb_gadget			*gadget = dev->gadget;
+
+#if defined(DEV_CONFIG_CDC) || defined(CONFIG_USB_ETH_RNDIS)
+	/* status endpoint used for RNDIS and (optionally) CDC */
+	if (!subset_active(dev) && dev->status_ep) {
+		dev->status = ep_desc (gadget, &hs_status_desc,
+						&fs_status_desc);
+		dev->status_ep->driver_data = dev;
+
+		result = usb_ep_enable (dev->status_ep, dev->status);
+		if (result != 0) {
+			DEBUG (dev, "enable %s --> %d\n", 
+				dev->status_ep->name, result);
+			goto done;
+		}
+	}
+#endif
+
+	dev->in = ep_desc (dev->gadget, &hs_source_desc, &fs_source_desc);
+	dev->in_ep->driver_data = dev;
+
+	dev->out = ep_desc (dev->gadget, &hs_sink_desc, &fs_sink_desc);
+	dev->out_ep->driver_data = dev;
 
 	/* With CDC,  the host isn't allowed to use these two data
 	 * endpoints in the default altsetting for the interface.
@@ -959,135 +984,33 @@ static inline int ether_alt_ep_setup (st
 	 * a side effect of setting a packet filter.  Deactivation is
 	 * from REMOTE_NDIS_HALT_MSG, reset from REMOTE_NDIS_RESET_MSG.
 	 */
-
-	/* one endpoint writes data back IN to the host */
-	if (strcmp (ep->name, EP_IN_NAME) == 0) {
-		d = ep_desc (dev->gadget, &hs_source_desc, &fs_source_desc);
-		ep->driver_data = dev;
-		dev->in = d;
-
-	/* one endpoint just reads OUT packets */
-	} else if (strcmp (ep->name, EP_OUT_NAME) == 0) {
-		d = ep_desc (dev->gadget, &hs_sink_desc, &fs_sink_desc);
-		ep->driver_data = dev;
-		dev->out = d;
-
-	/* optional status/notification endpoint */
-	} else if (EP_STATUS_NAME &&
-			strcmp (ep->name, EP_STATUS_NAME) == 0) {
-		int			result;
-
-		d = ep_desc (dev->gadget, &hs_status_desc, &fs_status_desc);
-		result = usb_ep_enable (ep, d);
-		if (result < 0)
-			return result;
-
-		ep->driver_data = dev;
-		dev->status = d;
-	}
-	return 0;
-}
-#endif
-
-#if	defined(DEV_CONFIG_SUBSET) || defined(CONFIG_USB_ETH_RNDIS)
-static inline int ether_ep_setup (struct eth_dev *dev, struct usb_ep *ep)
-{
-	int					result;
-	const struct usb_endpoint_descriptor	*d;
-
-	/* CDC subset is simpler:  if the device is there,
-	 * it's live with rx and tx endpoints.
-	 *
-	 * Do this as a shortcut for RNDIS too.
-	 */
-
-	/* one endpoint writes data back IN to the host */
-	if (strcmp (ep->name, EP_IN_NAME) == 0) {
-		d = ep_desc (dev->gadget, &hs_source_desc, &fs_source_desc);
-		result = usb_ep_enable (ep, d);
-		if (result < 0)
-			return result;
-
-		ep->driver_data = dev;
-		dev->in = d;
-
-	/* one endpoint just reads OUT packets */
-	} else if (strcmp (ep->name, EP_OUT_NAME) == 0) {
-		d = ep_desc (dev->gadget, &hs_sink_desc, &fs_sink_desc);
-		result = usb_ep_enable (ep, d);
-		if (result < 0)
-			return result;
-
-		ep->driver_data = dev;
-		dev->out = d;
-	}
-
-	return 0;
-}
-#endif
-
-static int
-set_ether_config (struct eth_dev *dev, int gfp_flags)
-{
-	int			result = 0;
-	struct usb_ep		*ep;
-	struct usb_gadget	*gadget = dev->gadget;
-
-	gadget_for_each_ep (ep, gadget) {
-#ifdef	DEV_CONFIG_CDC
-		if (!dev->rndis && dev->cdc) {
-			result = ether_alt_ep_setup (dev, ep);
-			if (result == 0)
-				continue;
+	if (!cdc_active(dev)) {
+		result = usb_ep_enable (dev->in_ep, dev->in);
+		if (result != 0) {
+			DEBUG(dev, "enable %s --> %d\n", 
+				dev->in_ep->name, result);
+			goto done;
 		}
-#endif
-
-#ifdef	CONFIG_USB_ETH_RNDIS
-		if (dev->rndis && strcmp (ep->name, EP_STATUS_NAME) == 0) {
-			const struct usb_endpoint_descriptor	*d;
-			d = ep_desc (gadget, &hs_status_desc, &fs_status_desc);
-			result = usb_ep_enable (ep, d);
-			if (result == 0) {
-				ep->driver_data = dev;
-				dev->status = d;
-				continue;
-			}
-		} else
-#endif
 
-		{
-#if	defined(DEV_CONFIG_SUBSET) || defined(CONFIG_USB_ETH_RNDIS)
-			result = ether_ep_setup (dev, ep);
-			if (result == 0)
-				continue;
-#endif
+		result = usb_ep_enable (dev->out_ep, dev->out);
+		if (result != 0) {
+			DEBUG (dev, "enable %s --> %d\n", 
+				dev->in_ep->name, result);
+			goto done;
 		}
-
-		/* stop on error */
-		ERROR (dev, "can't enable %s, result %d\n", ep->name, result);
-		break;
 	}
-	if (!result && (!dev->in_ep || !dev->out_ep))
-		result = -ENODEV;
 
+done:
 	if (result == 0)
 		result = alloc_requests (dev, qlen (gadget), gfp_flags);
 
 	/* on error, disable any endpoints  */
 	if (result < 0) {
-#if defined(DEV_CONFIG_CDC) || defined(CONFIG_USB_ETH_RNDIS)
-		if (dev->status)
+		if (!subset_active(dev))
 			(void) usb_ep_disable (dev->status_ep);
-#endif
 		dev->status = NULL;
-#if defined(DEV_CONFIG_SUBSET) || defined(CONFIG_USB_ETH_RNDIS)
-		if (dev->rndis || !dev->cdc) {
-			if (dev->in)
-				(void) usb_ep_disable (dev->in_ep);
-			if (dev->out)
-				(void) usb_ep_disable (dev->out_ep);
-		}
-#endif
+		(void) usb_ep_disable (dev->in_ep);
+		(void) usb_ep_disable (dev->out_ep);
 		dev->in = NULL;
 		dev->out = NULL;
 	} else
@@ -1095,8 +1018,7 @@ set_ether_config (struct eth_dev *dev, i
 	/* activate non-CDC configs right away
 	 * this isn't strictly according to the RNDIS spec
 	 */
-#if defined(DEV_CONFIG_SUBSET) || defined(CONFIG_USB_ETH_RNDIS)
-	if (dev->rndis || !dev->cdc) {
+	if (!cdc_active (dev)) {
 		netif_carrier_on (dev->net);
 		if (netif_running (dev->net)) {
 			spin_unlock (&dev->lock);
@@ -1104,7 +1026,6 @@ set_ether_config (struct eth_dev *dev, i
 			spin_lock (&dev->lock);
 		}
 	}
-#endif
 
 	if (result == 0)
 		DEBUG (dev, "qlen %d\n", qlen (gadget));
@@ -1124,6 +1045,7 @@ static void eth_reset_config (struct eth
 
 	netif_stop_queue (dev->net);
 	netif_carrier_off (dev->net);
+	rndis_uninit(dev->rndis_config);
 
 	/* disable endpoints, forcing (synchronous) completion of
 	 * pending i/o.  then free the requests.
@@ -1150,6 +1072,8 @@ static void eth_reset_config (struct eth
 	if (dev->status) {
 		usb_ep_disable (dev->status_ep);
 	}
+	dev->rndis = 0;
+	dev->cdc_filter = 0;
 	dev->config = 0;
 }
 
@@ -1157,14 +1081,11 @@ static void eth_reset_config (struct eth
  * that returns config descriptors, and altsetting code.
  */
 static int
-eth_set_config (struct eth_dev *dev, unsigned number, int gfp_flags)
+eth_set_config (struct eth_dev *dev, unsigned number, unsigned gfp_flags)
 {
 	int			result = 0;
 	struct usb_gadget	*gadget = dev->gadget;
 
-	if (number == dev->config)
-		return 0;
-
 	if (gadget_is_sa1100 (gadget)
 			&& dev->config
 			&& atomic_read (&dev->tx_qlen) != 0) {
@@ -1174,12 +1095,8 @@ eth_set_config (struct eth_dev *dev, uns
 	}
 	eth_reset_config (dev);
 
-	/* default:  pass all packets, no multicast filtering */
-	dev->cdc_filter = DEFAULT_FILTER;
-
 	switch (number) {
 	case DEV_CONFIG_VALUE:
-		dev->rndis = 0;
 		result = set_ether_config (dev, gfp_flags);
 		break;
 #ifdef	CONFIG_USB_ETH_RNDIS
@@ -1218,9 +1135,9 @@ eth_set_config (struct eth_dev *dev, uns
 		dev->config = number;
 		INFO (dev, "%s speed config #%d: %d mA, %s, using %s\n",
 				speed, number, power, driver_desc,
-				dev->rndis
+				rndis_active(dev)
 					? "RNDIS"
-					: (dev->cdc
+					: (cdc_active(dev)
 						? "CDC Ethernet"
 						: "CDC Ethernet Subset"));
 	}
@@ -1231,6 +1148,13 @@ eth_set_config (struct eth_dev *dev, uns
 
 #ifdef	DEV_CONFIG_CDC
 
+/* The interrupt endpoint is used in CDC networking models (Ethernet, ATM)
+ * only to notify the host about link status changes (which we support) or
+ * report completion of some encapsulated command (as used in RNDIS).  Since
+ * we want this CDC Ethernet code to be vendor-neutral, we don't use that
+ * command mechanism; and only one status request is ever queued.
+ */
+
 static void eth_status_complete (struct usb_ep *ep, struct usb_request *req)
 {
 	struct usb_cdc_notification	*event = req->buf;
@@ -1259,7 +1183,7 @@ static void eth_status_complete (struct 
 	} else if (value != -ECONNRESET)
 		DEBUG (dev, "event %02x --> %d\n",
 			event->bNotificationType, value);
-	event->bmRequestType = 0xff;
+	req->context = NULL;
 }
 
 static void issue_start_status (struct eth_dev *dev)
@@ -1276,6 +1200,8 @@ static void issue_start_status (struct e
 	 * a "cancel the whole queue" primitive since any
 	 * unlink-one primitive has way too many error modes.
 	 * here, we "know" toggle is already clear...
+	 *
+	 * FIXME iff req->context != null just dequeue it
 	 */
 	usb_ep_disable (dev->status_ep);
 	usb_ep_enable (dev->status_ep, dev->status);
@@ -1292,6 +1218,8 @@ static void issue_start_status (struct e
 
 	req->length = sizeof *event;
 	req->complete = eth_status_complete;
+	req->context = dev;
+
 	value = usb_ep_queue (dev->status_ep, req, GFP_ATOMIC);
 	if (value < 0)
 		DEBUG (dev, "status buf queue --> %d\n", value);
@@ -1351,9 +1279,9 @@ eth_setup (struct usb_gadget *gadget, co
 	struct eth_dev		*dev = get_gadget_data (gadget);
 	struct usb_request	*req = dev->req;
 	int			value = -EOPNOTSUPP;
-	u16			wIndex = (__force u16) ctrl->wIndex;
-	u16			wValue = (__force u16) ctrl->wValue;
-	u16			wLength = (__force u16) ctrl->wLength;
+	u16			wIndex = le16_to_cpu(ctrl->wIndex);
+	u16			wValue = le16_to_cpu(ctrl->wValue);
+	u16			wLength = le16_to_cpu(ctrl->wLength);
 
 	/* descriptors just go into the pre-allocated ep0 buffer,
 	 * while config change events may enable network traffic.
@@ -1424,7 +1352,7 @@ eth_setup (struct usb_gadget *gadget, co
 				|| !dev->config
 				|| wIndex > 1)
 			break;
-		if (!dev->cdc && wIndex != 0)
+		if (!cdc_active(dev) && wIndex != 0)
 			break;
 		spin_lock (&dev->lock);
 
@@ -1456,9 +1384,11 @@ eth_setup (struct usb_gadget *gadget, co
 
 			/* CDC requires the data transfers not be done from
 			 * the default interface setting ... also, setting
-			 * the non-default interface clears filters etc.
+			 * the non-default interface resets filters etc.
 			 */
 			if (wValue == 1) {
+				if (!cdc_active (dev))
+					break;
 				usb_ep_enable (dev->in_ep, dev->in);
 				usb_ep_enable (dev->out_ep, dev->out);
 				dev->cdc_filter = DEFAULT_FILTER;
@@ -1492,11 +1422,11 @@ done_set_intf:
 				|| !dev->config
 				|| wIndex > 1)
 			break;
-		if (!(dev->cdc || dev->rndis) && wIndex != 0)
+		if (!(cdc_active(dev) || rndis_active(dev)) && wIndex != 0)
 			break;
 
 		/* for CDC, iff carrier is on, data interface is active. */
-		if (dev->rndis || wIndex != 1)
+		if (rndis_active(dev) || wIndex != 1)
 			*(u8 *)req->buf = 0;
 		else
 			*(u8 *)req->buf = netif_carrier_ok (dev->net) ? 1 : 0;
@@ -1509,8 +1439,7 @@ done_set_intf:
 		 * wValue = packet filter bitmap
 		 */
 		if (ctrl->bRequestType != (USB_TYPE_CLASS|USB_RECIP_INTERFACE)
-				|| !dev->cdc
-				|| dev->rndis
+				|| !cdc_active(dev)
 				|| wLength != 0
 				|| wIndex > 1)
 			break;
@@ -1534,7 +1463,7 @@ done_set_intf:
 	 */
 	case USB_CDC_SEND_ENCAPSULATED_COMMAND:
 		if (ctrl->bRequestType != (USB_TYPE_CLASS|USB_RECIP_INTERFACE)
-				|| !dev->rndis
+				|| !rndis_active(dev)
 				|| wLength > USB_BUFSIZ
 				|| wValue
 				|| rndis_control_intf.bInterfaceNumber
@@ -1549,7 +1478,7 @@ done_set_intf:
 	case USB_CDC_GET_ENCAPSULATED_RESPONSE:
 		if ((USB_DIR_IN|USB_TYPE_CLASS|USB_RECIP_INTERFACE)
 					== ctrl->bRequestType
-				&& dev->rndis
+				&& rndis_active(dev)
 				// && wLength >= 0x0400
 				&& !wValue
 				&& rndis_control_intf.bInterfaceNumber
@@ -1669,7 +1598,7 @@ static void defer_kevent (struct eth_dev
 static void rx_complete (struct usb_ep *ep, struct usb_request *req);
 
 static int
-rx_submit (struct eth_dev *dev, struct usb_request *req, int gfp_flags)
+rx_submit (struct eth_dev *dev, struct usb_request *req, unsigned gfp_flags)
 {
 	struct sk_buff		*skb;
 	int			retval = -ENOMEM;
@@ -1688,10 +1617,8 @@ rx_submit (struct eth_dev *dev, struct u
 	 */
 	size = (sizeof (struct ethhdr) + dev->net->mtu + RX_EXTRA);
 	size += dev->out_ep->maxpacket - 1;
-#ifdef CONFIG_USB_ETH_RNDIS
-	if (dev->rndis)
+	if (rndis_active(dev))
 		size += sizeof (struct rndis_packet_msg_type);
-#endif	
 	size -= size % dev->out_ep->maxpacket;
 
 	if ((skb = alloc_skb (size + NET_IP_ALIGN, gfp_flags)) == 0) {
@@ -1735,11 +1662,9 @@ static void rx_complete (struct usb_ep *
 	/* normal completion */
 	case 0:
 		skb_put (skb, req->actual);
-#ifdef CONFIG_USB_ETH_RNDIS
 		/* we know MaxPacketsPerTransfer == 1 here */
-		if (dev->rndis)
+		if (rndis_active(dev))
 			status = rndis_rm_hdr (skb);
-#endif
 		if (status < 0
 				|| ETH_HLEN > skb->len
 				|| skb->len > ETH_FRAME_LEN) {
@@ -1799,7 +1724,7 @@ clean:
 }
 
 static int prealloc (struct list_head *list, struct usb_ep *ep,
-			unsigned n, int gfp_flags)
+			unsigned n, unsigned gfp_flags)
 {
 	unsigned		i;
 	struct usb_request	*req;
@@ -1838,7 +1763,7 @@ extra:
 	return 0;
 }
 
-static int alloc_requests (struct eth_dev *dev, unsigned n, int gfp_flags)
+static int alloc_requests (struct eth_dev *dev, unsigned n, unsigned gfp_flags)
 {
 	int status;
 
@@ -1854,13 +1779,11 @@ fail:
 	return status;
 }
 
-static void rx_fill (struct eth_dev *dev, int gfp_flags)
+static void rx_fill (struct eth_dev *dev, unsigned gfp_flags)
 {
 	struct usb_request	*req;
 	unsigned long		flags;
 
-	clear_bit (WORK_RX_MEMORY, &dev->todo);
-
 	/* fill unused rxq slots with some skb */
 	spin_lock_irqsave (&dev->lock, flags);
 	while (!list_empty (&dev->rx_reqs)) {
@@ -1883,11 +1806,9 @@ static void eth_work (void *_dev)
 {
 	struct eth_dev		*dev = _dev;
 
-	if (test_bit (WORK_RX_MEMORY, &dev->todo)) {
+	if (test_and_clear_bit (WORK_RX_MEMORY, &dev->todo)) {
 		if (netif_running (dev->net))
 			rx_fill (dev, GFP_KERNEL);
-		else
-			clear_bit (WORK_RX_MEMORY, &dev->todo);
 	}
 
 	if (dev->todo)
@@ -1971,8 +1892,7 @@ static int eth_start_xmit (struct sk_buf
 	 * or the hardware can't use skb buffers.
 	 * or there's not enough space for any RNDIS headers we need
 	 */
-#ifdef CONFIG_USB_ETH_RNDIS
-	if (dev->rndis) {
+	if (rndis_active(dev)) {
 		struct sk_buff	*skb_rndis;
 
 		skb_rndis = skb_realloc_headroom (skb,
@@ -1985,7 +1905,6 @@ static int eth_start_xmit (struct sk_buf
 		rndis_add_hdr (skb);
 		length = skb->len;
 	}
-#endif
 	req->buf = skb->data;
 	req->context = skb;
 	req->complete = tx_complete;
@@ -2018,9 +1937,7 @@ static int eth_start_xmit (struct sk_buf
 	}
 
 	if (retval) {
-#ifdef CONFIG_USB_ETH_RNDIS
 drop:
-#endif
 		dev->stats.tx_dropped++;
 		dev_kfree_skb_any (skb);
 		spin_lock_irqsave (&dev->lock, flags);
@@ -2036,27 +1953,31 @@ drop:
 
 #ifdef CONFIG_USB_ETH_RNDIS
 
-static void rndis_send_media_state (struct eth_dev *dev, int connect)
-{
-	if (!dev)
-		return;
-	
-	if (connect) {
-		if (rndis_signal_connect (dev->rndis_config))
-			return;
-	} else {
-		if (rndis_signal_disconnect (dev->rndis_config))
-			return;
-	}
-}
+/* The interrupt endpoint is used in RNDIS to notify the host when messages
+ * other than data packets are available ... notably the REMOTE_NDIS_*_CMPLT
+ * messages, but also REMOTE_NDIS_INDICATE_STATUS_MSG and potentially even
+ * REMOTE_NDIS_KEEPALIVE_MSG.
+ *
+ * The RNDIS control queue is processed by GET_ENCAPSULATED_RESPONSE, and
+ * normally just one notification will be queued.
+ */
+
+static struct usb_request *eth_req_alloc (struct usb_ep *, unsigned, unsigned);
+static void eth_req_free (struct usb_ep *ep, struct usb_request *req);
 
 static void
 rndis_control_ack_complete (struct usb_ep *ep, struct usb_request *req)
 {
+	struct eth_dev          *dev = ep->driver_data;
+
 	if (req->status || req->actual != req->length)
-		DEBUG ((struct eth_dev *) ep->driver_data,
+		DEBUG (dev,
 			"rndis control ack complete --> %d, %d/%d\n",
 			req->status, req->actual, req->length);
+	req->context = NULL;
+
+	if (req != dev->stat_req)
+		eth_req_free(ep, req);
 }
 
 static int rndis_control_ack (struct net_device *net)
@@ -2071,11 +1992,19 @@ static int rndis_control_ack (struct net
 		return -ENODEV;
 	}
 
+	/* in case queue length > 1 */
+	if (resp->context) {
+		resp = eth_req_alloc (dev->status_ep, 8, GFP_ATOMIC);
+		if (!resp)
+			return -ENOMEM;
+	}
+
 	/* Send RNDIS RESPONSE_AVAILABLE notification;
 	 * USB_CDC_NOTIFY_RESPONSE_AVAILABLE should work too
 	 */
 	resp->length = 8;
 	resp->complete = rndis_control_ack_complete;
+	resp->context = dev;
 	
 	*((__le32 *) resp->buf) = __constant_cpu_to_le32 (1);
 	*((__le32 *) resp->buf + 1) = __constant_cpu_to_le32 (0);
@@ -2089,9 +2018,13 @@ static int rndis_control_ack (struct net
 	return 0;
 }
 
+#else
+
+#define	rndis_control_ack	NULL
+
 #endif	/* RNDIS */
 
-static void eth_start (struct eth_dev *dev, int gfp_flags)
+static void eth_start (struct eth_dev *dev, unsigned gfp_flags)
 {
 	DEBUG (dev, "%s\n", __FUNCTION__);
 
@@ -2101,14 +2034,12 @@ static void eth_start (struct eth_dev *d
 	/* and open the tx floodgates */ 
 	atomic_set (&dev->tx_qlen, 0);
 	netif_wake_queue (dev->net);
-#ifdef CONFIG_USB_ETH_RNDIS
-	if (dev->rndis) {
+	if (rndis_active(dev)) {
 		rndis_set_param_medium (dev->rndis_config,
 					NDIS_MEDIUM_802_3,
 					BITRATE(dev->gadget)/100);
-		rndis_send_media_state (dev, 1);
+		(void) rndis_signal_connect (dev->rndis_config);
 	}
-#endif	
 }
 
 static int eth_open (struct net_device *net)
@@ -2149,28 +2080,27 @@ static int eth_stop (struct net_device *
 		}
 	}
 	
-#ifdef	CONFIG_USB_ETH_RNDIS
-	if (dev->rndis) {
+	if (rndis_active(dev)) {
 		rndis_set_param_medium (dev->rndis_config,
 					NDIS_MEDIUM_802_3, 0);
-		rndis_send_media_state (dev, 0);
+		(void) rndis_signal_disconnect (dev->rndis_config);
 	}
-#endif
 
 	return 0;
 }
 
 /*-------------------------------------------------------------------------*/
 
-static struct usb_request *eth_req_alloc (struct usb_ep *ep, unsigned size)
+static struct usb_request *
+eth_req_alloc (struct usb_ep *ep, unsigned size, unsigned gfp_flags)
 {
 	struct usb_request	*req;
 
-	req = usb_ep_alloc_request (ep, GFP_KERNEL);
+	req = usb_ep_alloc_request (ep, gfp_flags);
 	if (!req)
 		return NULL;
 
-	req->buf = kmalloc (size, GFP_KERNEL);
+	req->buf = kmalloc (size, gfp_flags);
 	if (!req->buf) {
 		usb_ep_free_request (ep, req);
 		req = NULL;
@@ -2192,10 +2122,8 @@ eth_unbind (struct usb_gadget *gadget)
 	struct eth_dev		*dev = get_gadget_data (gadget);
 
 	DEBUG (dev, "unbind\n");
-#ifdef CONFIG_USB_ETH_RNDIS
 	rndis_deregister (dev->rndis_config);
 	rndis_exit ();
-#endif
 
 	/* we've already been disconnected ... no i/o is active */
 	if (dev->req) {
@@ -2368,13 +2296,11 @@ autoconf_fail:
 			gadget->name);
 		return -ENODEV;
 	}
-	EP_IN_NAME = in_ep->name;
 	in_ep->driver_data = in_ep;	/* claim */
 	
 	out_ep = usb_ep_autoconfig (gadget, &fs_sink_desc);
 	if (!out_ep)
 		goto autoconf_fail;
-	EP_OUT_NAME = out_ep->name;
 	out_ep->driver_data = out_ep;	/* claim */
 
 #if defined(DEV_CONFIG_CDC) || defined(CONFIG_USB_ETH_RNDIS)
@@ -2384,7 +2310,6 @@ autoconf_fail:
 	if (cdc || rndis) {
 		status_ep = usb_ep_autoconfig (gadget, &fs_status_desc);
 		if (status_ep) {
-			EP_STATUS_NAME = status_ep->name;
 			status_ep->driver_data = status_ep;	/* claim */
 		} else if (rndis) {
 			dev_err (&gadget->dev,
@@ -2426,7 +2351,7 @@ autoconf_fail:
 	hs_source_desc.bEndpointAddress = fs_source_desc.bEndpointAddress;
 	hs_sink_desc.bEndpointAddress = fs_sink_desc.bEndpointAddress;
 #if defined(DEV_CONFIG_CDC) || defined(CONFIG_USB_ETH_RNDIS)
-	if (EP_STATUS_NAME)
+	if (status_ep)
 		hs_status_desc.bEndpointAddress =
 				fs_status_desc.bEndpointAddress;
 #endif
@@ -2499,20 +2424,23 @@ autoconf_fail:
 	SET_ETHTOOL_OPS(net, &ops);
 
 	/* preallocate control message data and buffer */
-	dev->req = eth_req_alloc (gadget->ep0, USB_BUFSIZ);
+	dev->req = eth_req_alloc (gadget->ep0, USB_BUFSIZ, GFP_KERNEL);
 	if (!dev->req)
 		goto fail;
 	dev->req->complete = eth_setup_complete;
 
 	/* ... and maybe likewise for status transfer */
+#if defined(DEV_CONFIG_CDC) || defined(CONFIG_USB_ETH_RNDIS)
 	if (dev->status_ep) {
 		dev->stat_req = eth_req_alloc (dev->status_ep,
-					STATUS_BYTECOUNT);
+					STATUS_BYTECOUNT, GFP_KERNEL);
 		if (!dev->stat_req) {
 			eth_req_free (gadget->ep0, dev->req);
 			goto fail;
 		}
+		dev->stat_req->context = NULL;
 	}
+#endif
 
 	/* finish hookup to lower layer ... */
 	dev->gadget = gadget;
@@ -2526,16 +2454,16 @@ autoconf_fail:
 	netif_stop_queue (dev->net);
 	netif_carrier_off (dev->net);
 
- 	// SET_NETDEV_DEV (dev->net, &gadget->dev);
+ 	SET_NETDEV_DEV (dev->net, &gadget->dev);
  	status = register_netdev (dev->net);
 	if (status < 0)
 		goto fail1;
 
 	INFO (dev, "%s, version: " DRIVER_VERSION "\n", driver_desc);
 	INFO (dev, "using %s, OUT %s IN %s%s%s\n", gadget->name,
-		EP_OUT_NAME, EP_IN_NAME,
-		EP_STATUS_NAME ? " STATUS " : "",
-		EP_STATUS_NAME ? EP_STATUS_NAME : ""
+		out_ep->name, in_ep->name,
+		status_ep ? " STATUS " : "",
+		status_ep ? status_ep->name : ""
 		);
 	INFO (dev, "MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
 		net->dev_addr [0], net->dev_addr [1],
@@ -2548,7 +2476,6 @@ autoconf_fail:
 			dev->host_mac [2], dev->host_mac [3],
 			dev->host_mac [4], dev->host_mac [5]);
 
-#ifdef	CONFIG_USB_ETH_RNDIS
 	if (rndis) {
 		u32	vendorID = 0;
 
@@ -2565,7 +2492,7 @@ fail0:
 		/* these set up a lot of the OIDs that RNDIS needs */
 		rndis_set_host_mac (dev->rndis_config, dev->host_mac);
 		if (rndis_set_param_dev (dev->rndis_config, dev->net,
-					 &dev->stats))
+					 &dev->stats, &dev->cdc_filter))
 			goto fail0;
 		if (rndis_set_param_vendor (dev->rndis_config, vendorID,
 					    manufacturer))
@@ -2576,7 +2503,6 @@ fail0:
 			goto fail0;
 		INFO (dev, "RNDIS ready\n");
 	}
-#endif	
 
 	return status;
 
@@ -2610,11 +2536,8 @@ eth_resume (struct usb_gadget *gadget)
 /*-------------------------------------------------------------------------*/
 
 static struct usb_gadget_driver eth_driver = {
-#ifdef CONFIG_USB_GADGET_DUALSPEED
-	.speed		= USB_SPEED_HIGH,
-#else
-	.speed		= USB_SPEED_FULL,
-#endif
+	.speed		= DEVSPEED,
+
 	.function	= (char *) driver_desc,
 	.bind		= eth_bind,
 	.unbind		= eth_unbind,
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c
--- a/drivers/usb/gadget/file_storage.c
+++ b/drivers/usb/gadget/file_storage.c
@@ -81,6 +81,10 @@
  *	removable		Default false, boolean for removable media
  *	luns=N			Default N = number of filenames, number of
  *					LUNs to support
+ *	stall			Default determined according to the type of
+ *					USB device controller (usually true),
+ *					boolean to permit the driver to halt
+ *					bulk endpoints
  *	transport=XXX		Default BBB, transport name (CB, CBI, or BBB)
  *	protocol=YYY		Default SCSI, protocol name (RBC, 8020 or
  *					ATAPI, QIC, UFI, 8070, or SCSI;
@@ -91,14 +95,10 @@
  *	buflen=N		Default N=16384, buffer size used (will be
  *					rounded down to a multiple of
  *					PAGE_CACHE_SIZE)
- *	stall			Default determined according to the type of
- *					USB device controller (usually true),
- *					boolean to permit the driver to halt
- *					bulk endpoints
  *
  * If CONFIG_USB_FILE_STORAGE_TEST is not set, only the "file", "ro",
- * "removable", and "luns" options are available; default values are used
- * for everything else.
+ * "removable", "luns", and "stall" options are available; default values
+ * are used for everything else.
  *
  * The pathnames of the backing files and the ro settings are available in
  * the attribute files "file" and "ro" in the lun<n> subdirectory of the
@@ -342,14 +342,15 @@ static struct {
 	int		num_ros;
 	unsigned int	nluns;
 
+	int		removable;
+	int		can_stall;
+
 	char		*transport_parm;
 	char		*protocol_parm;
-	int		removable;
 	unsigned short	vendor;
 	unsigned short	product;
 	unsigned short	release;
 	unsigned int	buflen;
-	int		can_stall;
 
 	int		transport_type;
 	char		*transport_name;
@@ -360,11 +361,11 @@ static struct {
 	.transport_parm		= "BBB",
 	.protocol_parm		= "SCSI",
 	.removable		= 0,
+	.can_stall		= 1,
 	.vendor			= DRIVER_VENDOR_ID,
 	.product		= DRIVER_PRODUCT_ID,
 	.release		= 0xffff,	// Use controller chip type
 	.buflen			= 16384,
-	.can_stall		= 1,
 	};
 
 
@@ -380,6 +381,9 @@ MODULE_PARM_DESC(luns, "number of LUNs")
 module_param_named(removable, mod_data.removable, bool, S_IRUGO);
 MODULE_PARM_DESC(removable, "true to simulate removable media");
 
+module_param_named(stall, mod_data.can_stall, bool, S_IRUGO);
+MODULE_PARM_DESC(stall, "false to prevent bulk stalls");
+
 
 /* In the non-TEST version, only the module parameters listed above
  * are available. */
@@ -404,9 +408,6 @@ MODULE_PARM_DESC(release, "USB release n
 module_param_named(buflen, mod_data.buflen, uint, S_IRUGO);
 MODULE_PARM_DESC(buflen, "I/O buffer size");
 
-module_param_named(stall, mod_data.can_stall, bool, S_IRUGO);
-MODULE_PARM_DESC(stall, "false to prevent bulk stalls");
-
 #endif /* CONFIG_USB_FILE_STORAGE_TEST */
 
 
@@ -818,7 +819,7 @@ static void inline put_be32(u8 *buf, u32
 	buf[0] = val >> 24;
 	buf[1] = val >> 16;
 	buf[2] = val >> 8;
-	buf[3] = val;
+	buf[3] = val & 0xff;
 }
 
 
@@ -1276,8 +1277,8 @@ static int class_setup_req(struct fsg_de
 {
 	struct usb_request	*req = fsg->ep0req;
 	int			value = -EOPNOTSUPP;
-	u16			w_index = ctrl->wIndex;
-	u16			w_length = ctrl->wLength;
+	u16			w_index = le16_to_cpu(ctrl->wIndex);
+	u16			w_length = le16_to_cpu(ctrl->wLength);
 
 	if (!fsg->config)
 		return value;
@@ -1312,7 +1313,7 @@ static int class_setup_req(struct fsg_de
 			}
 			VDBG(fsg, "get max LUN\n");
 			*(u8 *) req->buf = fsg->nluns - 1;
-			value = min(w_length, (u16) 1);
+			value = 1;
 			break;
 		}
 	}
@@ -1344,7 +1345,7 @@ static int class_setup_req(struct fsg_de
 			"unknown class-specific control req "
 			"%02x.%02x v%04x i%04x l%u\n",
 			ctrl->bRequestType, ctrl->bRequest,
-			ctrl->wValue, w_index, w_length);
+			le16_to_cpu(ctrl->wValue), w_index, w_length);
 	return value;
 }
 
@@ -1358,9 +1359,8 @@ static int standard_setup_req(struct fsg
 {
 	struct usb_request	*req = fsg->ep0req;
 	int			value = -EOPNOTSUPP;
-	u16			w_index = ctrl->wIndex;
-	u16			w_value = ctrl->wValue;
-	u16			w_length = ctrl->wLength;
+	u16			w_index = le16_to_cpu(ctrl->wIndex);
+	u16			w_value = le16_to_cpu(ctrl->wValue);
 
 	/* Usually this just stores reply data in the pre-allocated ep0 buffer,
 	 * but config change events will also reconfigure hardware. */
@@ -1374,7 +1374,7 @@ static int standard_setup_req(struct fsg
 
 		case USB_DT_DEVICE:
 			VDBG(fsg, "get device descriptor\n");
-			value = min(w_length, (u16) sizeof device_desc);
+			value = sizeof device_desc;
 			memcpy(req->buf, &device_desc, value);
 			break;
 #ifdef CONFIG_USB_GADGET_DUALSPEED
@@ -1382,7 +1382,7 @@ static int standard_setup_req(struct fsg
 			VDBG(fsg, "get device qualifier\n");
 			if (!fsg->gadget->is_dualspeed)
 				break;
-			value = min(w_length, (u16) sizeof dev_qualifier);
+			value = sizeof dev_qualifier;
 			memcpy(req->buf, &dev_qualifier, value);
 			break;
 
@@ -1401,8 +1401,6 @@ static int standard_setup_req(struct fsg
 					req->buf,
 					w_value >> 8,
 					w_value & 0xff);
-			if (value >= 0)
-				value = min(w_length, (u16) value);
 			break;
 
 		case USB_DT_STRING:
@@ -1411,8 +1409,6 @@ static int standard_setup_req(struct fsg
 			/* wIndex == language code */
 			value = usb_gadget_get_string(&stringtab,
 					w_value & 0xff, req->buf);
-			if (value >= 0)
-				value = min(w_length, (u16) value);
 			break;
 		}
 		break;
@@ -1438,7 +1434,7 @@ static int standard_setup_req(struct fsg
 			break;
 		VDBG(fsg, "get configuration\n");
 		*(u8 *) req->buf = fsg->config;
-		value = min(w_length, (u16) 1);
+		value = 1;
 		break;
 
 	case USB_REQ_SET_INTERFACE:
@@ -1466,14 +1462,14 @@ static int standard_setup_req(struct fsg
 		}
 		VDBG(fsg, "get interface\n");
 		*(u8 *) req->buf = 0;
-		value = min(w_length, (u16) 1);
+		value = 1;
 		break;
 
 	default:
 		VDBG(fsg,
 			"unknown control req %02x.%02x v%04x i%04x l%u\n",
 			ctrl->bRequestType, ctrl->bRequest,
-			w_value, w_index, w_length);
+			w_value, w_index, le16_to_cpu(ctrl->wLength));
 	}
 
 	return value;
@@ -1485,6 +1481,7 @@ static int fsg_setup(struct usb_gadget *
 {
 	struct fsg_dev		*fsg = get_gadget_data(gadget);
 	int			rc;
+	int			w_length = le16_to_cpu(ctrl->wLength);
 
 	++fsg->ep0_req_tag;		// Record arrival of a new request
 	fsg->ep0req->context = NULL;
@@ -1498,9 +1495,9 @@ static int fsg_setup(struct usb_gadget *
 
 	/* Respond with data/status or defer until later? */
 	if (rc >= 0 && rc != DELAYED_STATUS) {
+		rc = min(rc, w_length);
 		fsg->ep0req->length = rc;
-		fsg->ep0req->zero = (rc < ctrl->wLength &&
-				(rc % gadget->ep0->maxpacket) == 0);
+		fsg->ep0req->zero = rc < w_length;
 		fsg->ep0req_name = (ctrl->bRequestType & USB_DIR_IN ?
 				"ep0-in" : "ep0-out");
 		rc = ep0_queue(fsg);
@@ -1554,8 +1551,7 @@ static int sleep_thread(struct fsg_dev *
 	rc = wait_event_interruptible(fsg->thread_wqh,
 			fsg->thread_wakeup_needed);
 	fsg->thread_wakeup_needed = 0;
-	if (current->flags & PF_FREEZE)
-		refrigerator(PF_FREEZE);
+	try_to_freeze();
 	return (rc ? -EINTR : 0);
 }
 
@@ -2661,7 +2657,7 @@ static int check_command(struct fsg_dev 
 		}
 	}
 
-	/* Check that the LUN values are oonsistent */
+	/* Check that the LUN values are consistent */
 	if (transport_is_bbb()) {
 		if (fsg->lun != lun)
 			DBG(fsg, "using LUN %d from CBW, "
@@ -3554,14 +3550,14 @@ static void close_all_backing_files(stru
 }
 
 
-static ssize_t show_ro(struct device *dev, char *buf)
+static ssize_t show_ro(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct lun	*curlun = dev_to_lun(dev);
 
 	return sprintf(buf, "%d\n", curlun->ro);
 }
 
-static ssize_t show_file(struct device *dev, char *buf)
+static ssize_t show_file(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct lun	*curlun = dev_to_lun(dev);
 	struct fsg_dev	*fsg = (struct fsg_dev *) dev_get_drvdata(dev);
@@ -3589,7 +3585,7 @@ static ssize_t show_file(struct device *
 }
 
 
-static ssize_t store_ro(struct device *dev, const char *buf, size_t count)
+static ssize_t store_ro(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	ssize_t		rc = count;
 	struct lun	*curlun = dev_to_lun(dev);
@@ -3613,7 +3609,7 @@ static ssize_t store_ro(struct device *d
 	return rc;
 }
 
-static ssize_t store_file(struct device *dev, const char *buf, size_t count)
+static ssize_t store_file(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct lun	*curlun = dev_to_lun(dev);
 	struct fsg_dev	*fsg = (struct fsg_dev *) dev_get_drvdata(dev);
diff --git a/drivers/usb/gadget/goku_udc.c b/drivers/usb/gadget/goku_udc.c
--- a/drivers/usb/gadget/goku_udc.c
+++ b/drivers/usb/gadget/goku_udc.c
@@ -70,7 +70,7 @@ MODULE_LICENSE("GPL");
  * seem to behave quite as expected.  Used by default.
  *
  * OUT dma documents design problems handling the common "short packet"
- * transfer termination policy; it couldn't enabled by default, even
+ * transfer termination policy; it couldn't be enabled by default, even
  * if the OUT-dma abort problems had a resolution.
  */
 static unsigned use_dma = 1;
@@ -269,7 +269,7 @@ static int goku_ep_disable(struct usb_ep
 /*-------------------------------------------------------------------------*/
 
 static struct usb_request *
-goku_alloc_request(struct usb_ep *_ep, int gfp_flags)
+goku_alloc_request(struct usb_ep *_ep, unsigned gfp_flags)
 {
 	struct goku_request	*req;
 
@@ -313,7 +313,7 @@ goku_free_request(struct usb_ep *_ep, st
 #if	defined(CONFIG_X86)
 #define USE_KMALLOC
 
-#elif	defined(CONFIG_MIPS) && !defined(CONFIG_NONCOHERENT_IO)
+#elif	defined(CONFIG_MIPS) && !defined(CONFIG_DMA_NONCOHERENT)
 #define USE_KMALLOC
 
 #elif	defined(CONFIG_PPC) && !defined(CONFIG_NOT_COHERENT_CACHE)
@@ -327,7 +327,7 @@ goku_free_request(struct usb_ep *_ep, st
  */
 static void *
 goku_alloc_buffer(struct usb_ep *_ep, unsigned bytes,
-			dma_addr_t *dma, int  gfp_flags)
+			dma_addr_t *dma, unsigned gfp_flags)
 {
 	void		*retval;
 	struct goku_ep	*ep;
@@ -789,7 +789,7 @@ finished:
 /*-------------------------------------------------------------------------*/
 
 static int
-goku_queue(struct usb_ep *_ep, struct usb_request *_req, int gfp_flags)
+goku_queue(struct usb_ep *_ep, struct usb_request *_req, unsigned gfp_flags)
 {
 	struct goku_request	*req;
 	struct goku_ep		*ep;
@@ -1524,9 +1524,12 @@ static void ep0_setup(struct goku_udc *d
 	/* read SETUP packet and enter DATA stage */
 	ctrl.bRequestType = readl(&regs->bRequestType);
 	ctrl.bRequest = readl(&regs->bRequest);
-	ctrl.wValue  = (readl(&regs->wValueH)  << 8) | readl(&regs->wValueL);
-	ctrl.wIndex  = (readl(&regs->wIndexH)  << 8) | readl(&regs->wIndexL);
-	ctrl.wLength = (readl(&regs->wLengthH) << 8) | readl(&regs->wLengthL);
+	ctrl.wValue  = cpu_to_le16((readl(&regs->wValueH)  << 8)
+					| readl(&regs->wValueL));
+	ctrl.wIndex  = cpu_to_le16((readl(&regs->wIndexH)  << 8)
+					| readl(&regs->wIndexL));
+	ctrl.wLength = cpu_to_le16((readl(&regs->wLengthH) << 8)
+					| readl(&regs->wLengthL));
 	writel(0, &regs->SetupRecv);
 
 	nuke(&dev->ep[0], 0);
@@ -1548,18 +1551,20 @@ static void ep0_setup(struct goku_udc *d
 		case USB_REQ_CLEAR_FEATURE:
 			switch (ctrl.bRequestType) {
 			case USB_RECIP_ENDPOINT:
-				tmp = ctrl.wIndex & 0x0f;
+				tmp = le16_to_cpu(ctrl.wIndex) & 0x0f;
 				/* active endpoint */
 				if (tmp > 3 || (!dev->ep[tmp].desc && tmp != 0))
 					goto stall;
-				if (ctrl.wIndex & USB_DIR_IN) {
+				if (ctrl.wIndex & __constant_cpu_to_le16(
+						USB_DIR_IN)) {
 					if (!dev->ep[tmp].is_in)
 						goto stall;
 				} else {
 					if (dev->ep[tmp].is_in)
 						goto stall;
 				}
-				if (ctrl.wValue != USB_ENDPOINT_HALT)
+				if (ctrl.wValue != __constant_cpu_to_le16(
+						USB_ENDPOINT_HALT))
 					goto stall;
 				if (tmp)
 					goku_clear_halt(&dev->ep[tmp]);
@@ -1571,7 +1576,7 @@ succeed:
 				return;
 			case USB_RECIP_DEVICE:
 				/* device remote wakeup: always clear */
-				if (ctrl.wValue != 1)
+				if (ctrl.wValue != __constant_cpu_to_le16(1))
 					goto stall;
 				VDBG(dev, "clear dev remote wakeup\n");
 				goto succeed;
@@ -1589,14 +1594,15 @@ succeed:
 #ifdef USB_TRACE
 	VDBG(dev, "SETUP %02x.%02x v%04x i%04x l%04x\n",
 		ctrl.bRequestType, ctrl.bRequest,
-		ctrl.wValue, ctrl.wIndex, ctrl.wLength);
+		le16_to_cpu(ctrl.wValue), le16_to_cpu(ctrl.wIndex),
+		le16_to_cpu(ctrl.wLength));
 #endif
 
 	/* hw wants to know when we're configured (or not) */
 	dev->req_config = (ctrl.bRequest == USB_REQ_SET_CONFIGURATION
 				&& ctrl.bRequestType == USB_RECIP_DEVICE);
 	if (unlikely(dev->req_config))
-		dev->configured = (ctrl.wValue != 0);
+		dev->configured = (ctrl.wValue != __constant_cpu_to_le16(0));
 
 	/* delegate everything to the gadget driver.
 	 * it may respond after this irq handler returns.
diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c
--- a/drivers/usb/gadget/inode.c
+++ b/drivers/usb/gadget/inode.c
@@ -417,8 +417,8 @@ ep_read (struct file *fd, char __user *b
 		goto free1;
 
 	value = ep_io (data, kbuf, len);
-	VDEBUG (data->dev, "%s read %d OUT, status %d\n",
-		data->name, len, value);
+	VDEBUG (data->dev, "%s read %zu OUT, status %d\n",
+		data->name, len, (int) value);
 	if (value >= 0 && copy_to_user (buf, kbuf, value))
 		value = -EFAULT;
 
@@ -465,8 +465,8 @@ ep_write (struct file *fd, const char __
 	}
 
 	value = ep_io (data, kbuf, len);
-	VDEBUG (data->dev, "%s write %d IN, status %d\n",
-		data->name, len, value);
+	VDEBUG (data->dev, "%s write %zu IN, status %d\n",
+		data->name, len, (int) value);
 free1:
 	up (&data->lock);
 	kfree (kbuf);
@@ -1318,8 +1318,8 @@ gadgetfs_setup (struct usb_gadget *gadge
 	struct usb_request		*req = dev->req;
 	int				value = -EOPNOTSUPP;
 	struct usb_gadgetfs_event	*event;
-	u16				w_value = ctrl->wValue;
-	u16				w_length = ctrl->wLength;
+	u16				w_value = le16_to_cpu(ctrl->wValue);
+	u16				w_length = le16_to_cpu(ctrl->wLength);
 
 	spin_lock (&dev->lock);
 	dev->setup_abort = 0;
diff --git a/drivers/usb/gadget/lh7a40x_udc.c b/drivers/usb/gadget/lh7a40x_udc.c
--- a/drivers/usb/gadget/lh7a40x_udc.c
+++ b/drivers/usb/gadget/lh7a40x_udc.c
@@ -1106,7 +1106,7 @@ static int lh7a40x_ep_disable(struct usb
 }
 
 static struct usb_request *lh7a40x_alloc_request(struct usb_ep *ep,
-						 int gfp_flags)
+						 unsigned gfp_flags)
 {
 	struct lh7a40x_request *req;
 
@@ -1134,7 +1134,7 @@ static void lh7a40x_free_request(struct 
 }
 
 static void *lh7a40x_alloc_buffer(struct usb_ep *ep, unsigned bytes,
-				  dma_addr_t * dma, int gfp_flags)
+				  dma_addr_t * dma, unsigned gfp_flags)
 {
 	char *retval;
 
@@ -1158,7 +1158,7 @@ static void lh7a40x_free_buffer(struct u
  *  NOTE: Sets INDEX register
  */
 static int lh7a40x_queue(struct usb_ep *_ep, struct usb_request *_req,
-			 int gfp_flags)
+			 unsigned gfp_flags)
 {
 	struct lh7a40x_request *req;
 	struct lh7a40x_ep *ep;
diff --git a/drivers/usb/gadget/ndis.h b/drivers/usb/gadget/ndis.h
--- a/drivers/usb/gadget/ndis.h
+++ b/drivers/usb/gadget/ndis.h
@@ -47,17 +47,17 @@ struct NDIS_PM_WAKE_UP_CAPABILITIES {
 #define NDIS_DEVICE_WAKE_ON_MAGIC_PACKET_ENABLE   0x00000004
 
 struct NDIS_PNP_CAPABILITIES {
-	u32					Flags;
+	__le32					Flags;
 	struct NDIS_PM_WAKE_UP_CAPABILITIES	WakeUpCapabilities;
 };
 
 struct NDIS_PM_PACKET_PATTERN {
-	u32	Priority;
-	u32	Reserved;
-	u32	MaskSize;
-	u32	PatternOffset;
-	u32	PatternSize;
-	u32	PatternFlags;
+	__le32	Priority;
+	__le32	Reserved;
+	__le32	MaskSize;
+	__le32	PatternOffset;
+	__le32	PatternSize;
+	__le32	PatternFlags;
 };
 
 
diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c
--- a/drivers/usb/gadget/net2280.c
+++ b/drivers/usb/gadget/net2280.c
@@ -376,7 +376,7 @@ static int net2280_disable (struct usb_e
 /*-------------------------------------------------------------------------*/
 
 static struct usb_request *
-net2280_alloc_request (struct usb_ep *_ep, int gfp_flags)
+net2280_alloc_request (struct usb_ep *_ep, unsigned gfp_flags)
 {
 	struct net2280_ep	*ep;
 	struct net2280_request	*req;
@@ -448,7 +448,7 @@ net2280_free_request (struct usb_ep *_ep
 #elif	defined(CONFIG_PPC) && !defined(CONFIG_NOT_COHERENT_CACHE)
 #define USE_KMALLOC
 
-#elif	defined(CONFIG_MIPS) && !defined(CONFIG_NONCOHERENT_IO)
+#elif	defined(CONFIG_MIPS) && !defined(CONFIG_DMA_NONCOHERENT)
 #define USE_KMALLOC
 
 /* FIXME there are other cases, including an x86-64 one ...  */
@@ -463,7 +463,7 @@ net2280_alloc_buffer (
 	struct usb_ep		*_ep,
 	unsigned		bytes,
 	dma_addr_t		*dma,
-	int			gfp_flags
+	unsigned		gfp_flags
 )
 {
 	void			*retval;
@@ -897,7 +897,7 @@ done (struct net2280_ep *ep, struct net2
 /*-------------------------------------------------------------------------*/
 
 static int
-net2280_queue (struct usb_ep *_ep, struct usb_request *_req, int gfp_flags)
+net2280_queue (struct usb_ep *_ep, struct usb_request *_req, unsigned gfp_flags)
 {
 	struct net2280_request	*req;
 	struct net2280_ep	*ep;
@@ -1113,7 +1113,7 @@ static void restart_dma (struct net2280_
 		if (ep->in_fifo_validate)
 			dmactl |= (1 << DMA_FIFO_VALIDATE);
 		list_for_each_entry (entry, &ep->queue, queue) {
-			u32		dmacount;
+			__le32		dmacount;
 
 			if (entry == req)
 				continue;
@@ -1238,7 +1238,7 @@ static int net2280_dequeue (struct usb_e
 				&ep->dma->dmadesc);
 			if (req->td->dmacount & dma_done_ie)
 				writel (readl (&ep->dma->dmacount)
-						| dma_done_ie,
+						| le32_to_cpu(dma_done_ie),
 					&ep->dma->dmacount);
 		} else {
 			struct net2280_request	*prev;
@@ -1469,7 +1469,7 @@ static const struct usb_gadget_ops net22
 
 /* "function" sysfs attribute */
 static ssize_t
-show_function (struct device *_dev, char *buf)
+show_function (struct device *_dev, struct device_attribute *attr, char *buf)
 {
 	struct net2280	*dev = dev_get_drvdata (_dev);
 
@@ -1482,7 +1482,7 @@ show_function (struct device *_dev, char
 static DEVICE_ATTR (function, S_IRUGO, show_function, NULL);
 
 static ssize_t
-show_registers (struct device *_dev, char *buf)
+show_registers (struct device *_dev, struct device_attribute *attr, char *buf)
 {
 	struct net2280		*dev;
 	char			*next;
@@ -1490,7 +1490,7 @@ show_registers (struct device *_dev, cha
 	unsigned long		flags;
 	int			i;
 	u32			t1, t2;
-	char			*s;
+	const char		*s;
 
 	dev = dev_get_drvdata (_dev);
 	next = buf;
@@ -1637,7 +1637,7 @@ show_registers (struct device *_dev, cha
 static DEVICE_ATTR (registers, S_IRUGO, show_registers, NULL);
 
 static ssize_t
-show_queues (struct device *_dev, char *buf)
+show_queues (struct device *_dev, struct device_attribute *attr, char *buf)
 {
 	struct net2280		*dev;
 	char			*next;
@@ -1779,6 +1779,9 @@ static void set_fifo_mode (struct net228
 	list_add_tail (&dev->ep [6].ep.ep_list, &dev->gadget.ep_list);
 }
 
+/* just declare this in any driver that really need it */
+extern int net2280_set_fifo_mode (struct usb_gadget *gadget, int mode);
+
 /**
  * net2280_set_fifo_mode - change allocation of fifo buffers
  * @gadget: access to the net2280 device that will be updated
@@ -2382,9 +2385,9 @@ static void handle_stat0_irqs (struct ne
 		cpu_to_le32s (&u.raw [0]);
 		cpu_to_le32s (&u.raw [1]);
 
-		le16_to_cpus (&u.r.wValue);
-		le16_to_cpus (&u.r.wIndex);
-		le16_to_cpus (&u.r.wLength);
+#define	w_value		le16_to_cpup (&u.r.wValue)
+#define	w_index		le16_to_cpup (&u.r.wIndex)
+#define	w_length	le16_to_cpup (&u.r.wLength)
 
 		/* ack the irq */
 		writel (1 << SETUP_PACKET_INTERRUPT, &dev->regs->irqstat0);
@@ -2413,25 +2416,25 @@ static void handle_stat0_irqs (struct ne
 		switch (u.r.bRequest) {
 		case USB_REQ_GET_STATUS: {
 			struct net2280_ep	*e;
-			u16			status;
+			__le32			status;
 
 			/* hw handles device and interface status */
 			if (u.r.bRequestType != (USB_DIR_IN|USB_RECIP_ENDPOINT))
 				goto delegate;
-			if ((e = get_ep_by_addr (dev, u.r.wIndex)) == 0
-					|| u.r.wLength > 2)
+			if ((e = get_ep_by_addr (dev, w_index)) == 0
+					|| w_length > 2)
 				goto do_stall;
 
 			if (readl (&e->regs->ep_rsp)
 					& (1 << SET_ENDPOINT_HALT))
-				status = __constant_cpu_to_le16 (1);
+				status = __constant_cpu_to_le32 (1);
 			else
-				status = __constant_cpu_to_le16 (0);
+				status = __constant_cpu_to_le32 (0);
 
 			/* don't bother with a request object! */
 			writel (0, &dev->epregs [0].ep_irqenb);
-			set_fifo_bytecount (ep, u.r.wLength);
-			writel (status, &dev->epregs [0].ep_data);
+			set_fifo_bytecount (ep, w_length);
+			writel ((__force u32)status, &dev->epregs [0].ep_data);
 			allow_status (ep);
 			VDEBUG (dev, "%s stat %02x\n", ep->ep.name, status);
 			goto next_endpoints;
@@ -2443,10 +2446,10 @@ static void handle_stat0_irqs (struct ne
 			/* hw handles device features */
 			if (u.r.bRequestType != USB_RECIP_ENDPOINT)
 				goto delegate;
-			if (u.r.wValue != USB_ENDPOINT_HALT
-					|| u.r.wLength != 0)
+			if (w_value != USB_ENDPOINT_HALT
+					|| w_length != 0)
 				goto do_stall;
-			if ((e = get_ep_by_addr (dev, u.r.wIndex)) == 0)
+			if ((e = get_ep_by_addr (dev, w_index)) == 0)
 				goto do_stall;
 			clear_halt (e);
 			allow_status (ep);
@@ -2460,10 +2463,10 @@ static void handle_stat0_irqs (struct ne
 			/* hw handles device features */
 			if (u.r.bRequestType != USB_RECIP_ENDPOINT)
 				goto delegate;
-			if (u.r.wValue != USB_ENDPOINT_HALT
-					|| u.r.wLength != 0)
+			if (w_value != USB_ENDPOINT_HALT
+					|| w_length != 0)
 				goto do_stall;
-			if ((e = get_ep_by_addr (dev, u.r.wIndex)) == 0)
+			if ((e = get_ep_by_addr (dev, w_index)) == 0)
 				goto do_stall;
 			set_halt (e);
 			allow_status (ep);
@@ -2473,10 +2476,10 @@ static void handle_stat0_irqs (struct ne
 			break;
 		default:
 delegate:
-			VDEBUG (dev, "setup %02x.%02x v%04x i%04x "
+			VDEBUG (dev, "setup %02x.%02x v%04x i%04x l%04x"
 				"ep_cfg %08x\n",
 				u.r.bRequestType, u.r.bRequest,
-				u.r.wValue, u.r.wIndex,
+				w_value, w_index, w_length,
 				readl (&ep->regs->ep_cfg));
 			spin_unlock (&dev->lock);
 			tmp = dev->driver->setup (&dev->gadget, &u.r);
@@ -2497,6 +2500,10 @@ do_stall:
 		 */
 	}
 
+#undef	w_value
+#undef	w_index
+#undef	w_length
+
 next_endpoints:
 	/* endpoint data irq ? */
 	scratch = stat & 0x7f;
@@ -2653,7 +2660,7 @@ static void handle_stat1_irqs (struct ne
 				restart_dma (ep);
 			else if (ep->is_in && use_dma_chaining) {
 				struct net2280_request	*req;
-				u32			dmacount;
+				__le32			dmacount;
 
 				/* the descriptor at the head of the chain
 				 * may still have VALID_BIT clear; that's
diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c
--- a/drivers/usb/gadget/omap_udc.c
+++ b/drivers/usb/gadget/omap_udc.c
@@ -52,7 +52,6 @@
 #include <asm/mach-types.h>
 
 #include <asm/arch/dma.h>
-#include <asm/arch/mux.h>
 #include <asm/arch/usb.h>
 
 #include "omap_udc.h"
@@ -167,7 +166,7 @@ static int omap_ep_enable(struct usb_ep 
 	maxp = le16_to_cpu (desc->wMaxPacketSize);
 	if ((desc->bmAttributes == USB_ENDPOINT_XFER_BULK
 				&& maxp != ep->maxpacket)
-			|| desc->wMaxPacketSize > ep->maxpacket
+			|| le16_to_cpu(desc->wMaxPacketSize) > ep->maxpacket
 			|| !desc->wMaxPacketSize) {
 		DBG("%s, bad %s maxpacket\n", __FUNCTION__, _ep->name);
 		return -ERANGE;
@@ -214,7 +213,7 @@ static int omap_ep_enable(struct usb_ep 
 	ep->has_dma = 0;
 	ep->lch = -1;
 	use_ep(ep, UDC_EP_SEL);
-	UDC_CTRL_REG = UDC_RESET_EP;
+	UDC_CTRL_REG = udc->clr_halt;
 	ep->ackwait = 0;
 	deselect_ep();
 
@@ -253,7 +252,7 @@ static int omap_ep_disable(struct usb_ep
 	}
 
 	spin_lock_irqsave(&ep->udc->lock, flags);
-	ep->desc = 0;
+	ep->desc = NULL;
 	nuke (ep, -ESHUTDOWN);
 	ep->ep.maxpacket = ep->maxpacket;
 	ep->has_dma = 0;
@@ -270,7 +269,7 @@ static int omap_ep_disable(struct usb_ep
 /*-------------------------------------------------------------------------*/
 
 static struct usb_request *
-omap_alloc_request(struct usb_ep *ep, int gfp_flags)
+omap_alloc_request(struct usb_ep *ep, unsigned gfp_flags)
 {
 	struct omap_req	*req;
 
@@ -299,7 +298,7 @@ omap_alloc_buffer(
 	struct usb_ep	*_ep,
 	unsigned	bytes,
 	dma_addr_t	*dma,
-	int		gfp_flags
+	unsigned	gfp_flags
 )
 {
 	void		*retval;
@@ -388,8 +387,8 @@ done(struct omap_ep *ep, struct omap_req
 
 /*-------------------------------------------------------------------------*/
 
-#define	FIFO_FULL	(UDC_NON_ISO_FIFO_FULL | UDC_ISO_FIFO_FULL)
-#define	FIFO_UNWRITABLE	(UDC_EP_HALTED | FIFO_FULL)
+#define UDC_FIFO_FULL		(UDC_NON_ISO_FIFO_FULL | UDC_ISO_FIFO_FULL)
+#define UDC_FIFO_UNWRITABLE	(UDC_EP_HALTED | UDC_FIFO_FULL)
 
 #define FIFO_EMPTY	(UDC_NON_ISO_FIFO_EMPTY | UDC_ISO_FIFO_EMPTY)
 #define FIFO_UNREADABLE (UDC_EP_HALTED | FIFO_EMPTY)
@@ -433,7 +432,7 @@ static int write_fifo(struct omap_ep *ep
 
 	/* PIO-IN isn't double buffered except for iso */
 	ep_stat = UDC_STAT_FLG_REG;
-	if (ep_stat & FIFO_UNWRITABLE)
+	if (ep_stat & UDC_FIFO_UNWRITABLE)
 		return 0;
 
 	count = ep->ep.maxpacket;
@@ -504,7 +503,7 @@ static int read_fifo(struct omap_ep *ep,
 		if (ep_stat & UDC_EP_HALTED)
 			break;
 
-		if (ep_stat & FIFO_FULL)
+		if (ep_stat & UDC_FIFO_FULL)
 			avail = ep->ep.maxpacket;
 		else  {
 			avail = UDC_RXFSTAT_REG;
@@ -538,6 +537,32 @@ static int read_fifo(struct omap_ep *ep,
 
 /*-------------------------------------------------------------------------*/
 
+static inline dma_addr_t dma_csac(unsigned lch)
+{
+	dma_addr_t	csac;
+
+	/* omap 3.2/3.3 erratum: sometimes 0 is returned if CSAC/CDAC is
+	 * read before the DMA controller finished disabling the channel.
+	 */
+	csac = omap_readw(OMAP_DMA_CSAC(lch));
+	if (csac == 0)
+		csac = omap_readw(OMAP_DMA_CSAC(lch));
+	return csac;
+}
+
+static inline dma_addr_t dma_cdac(unsigned lch)
+{
+	dma_addr_t	cdac;
+
+	/* omap 3.2/3.3 erratum: sometimes 0 is returned if CSAC/CDAC is
+	 * read before the DMA controller finished disabling the channel.
+	 */
+	cdac = omap_readw(OMAP_DMA_CDAC(lch));
+	if (cdac == 0)
+		cdac = omap_readw(OMAP_DMA_CDAC(lch));
+	return cdac;
+}
+
 static u16 dma_src_len(struct omap_ep *ep, dma_addr_t start)
 {
 	dma_addr_t	end;
@@ -548,7 +573,7 @@ static u16 dma_src_len(struct omap_ep *e
 	if (cpu_is_omap15xx())
 		return 0;
 
-	end = omap_readw(OMAP_DMA_CSAC(ep->lch));
+	end = dma_csac(ep->lch);
 	if (end == ep->dma_counter)
 		return 0;
 
@@ -559,14 +584,14 @@ static u16 dma_src_len(struct omap_ep *e
 }
 
 #define DMA_DEST_LAST(x) (cpu_is_omap15xx() \
-		? OMAP_DMA_CSAC(x) /* really: CPC */ \
-		: OMAP_DMA_CDAC(x))
+		? omap_readw(OMAP_DMA_CSAC(x)) /* really: CPC */ \
+		: dma_cdac(x))
 
 static u16 dma_dest_len(struct omap_ep *ep, dma_addr_t start)
 {
 	dma_addr_t	end;
 
-	end = omap_readw(DMA_DEST_LAST(ep->lch));
+	end = DMA_DEST_LAST(ep->lch);
 	if (end == ep->dma_counter)
 		return 0;
 
@@ -593,7 +618,7 @@ static void next_in_dma(struct omap_ep *
 				: OMAP_DMA_SYNC_ELEMENT;
 
 	/* measure length in either bytes or packets */
-	if ((cpu_is_omap16xx() && length <= (UDC_TXN_TSC + 1))
+	if ((cpu_is_omap16xx() && length <= UDC_TXN_TSC)
 			|| (cpu_is_omap15xx() && length < ep->maxpacket)) {
 		txdma_ctrl = UDC_TXN_EOT | length;
 		omap_set_dma_transfer_params(ep->lch, OMAP_DMA_DATA_TYPE_S8,
@@ -602,15 +627,15 @@ static void next_in_dma(struct omap_ep *
 		length = min(length / ep->maxpacket,
 				(unsigned) UDC_TXN_TSC + 1);
  		txdma_ctrl = length;
-		omap_set_dma_transfer_params(ep->lch, OMAP_DMA_DATA_TYPE_S8,
-				ep->ep.maxpacket, length, sync_mode);
+		omap_set_dma_transfer_params(ep->lch, OMAP_DMA_DATA_TYPE_S16,
+				ep->ep.maxpacket >> 1, length, sync_mode);
 		length *= ep->maxpacket;
 	}
 	omap_set_dma_src_params(ep->lch, OMAP_DMA_PORT_EMIFF,
 		OMAP_DMA_AMODE_POST_INC, req->req.dma + req->req.actual);
 
 	omap_start_dma(ep->lch);
-	ep->dma_counter = omap_readw(OMAP_DMA_CSAC(ep->lch));
+	ep->dma_counter = dma_csac(ep->lch);
 	UDC_DMA_IRQ_EN_REG |= UDC_TX_DONE_IE(ep->dma_channel);
 	UDC_TXDMA_REG(ep->dma_channel) = UDC_TXN_START | txdma_ctrl;
 	req->dma_bytes = length;
@@ -650,12 +675,12 @@ static void next_out_dma(struct omap_ep 
 	packets = (req->req.length - req->req.actual) / ep->ep.maxpacket;
 	packets = min(packets, (unsigned)UDC_RXN_TC + 1);
 	req->dma_bytes = packets * ep->ep.maxpacket;
-	omap_set_dma_transfer_params(ep->lch, OMAP_DMA_DATA_TYPE_S8,
-			ep->ep.maxpacket, packets,
+	omap_set_dma_transfer_params(ep->lch, OMAP_DMA_DATA_TYPE_S16,
+			ep->ep.maxpacket >> 1, packets,
 			OMAP_DMA_SYNC_ELEMENT);
 	omap_set_dma_dest_params(ep->lch, OMAP_DMA_PORT_EMIFF,
 		OMAP_DMA_AMODE_POST_INC, req->req.dma + req->req.actual);
-	ep->dma_counter = omap_readw(DMA_DEST_LAST(ep->lch));
+	ep->dma_counter = DMA_DEST_LAST(ep->lch);
 
 	UDC_RXDMA_REG(ep->dma_channel) = UDC_RXN_STOP | (packets - 1);
 	UDC_DMA_IRQ_EN_REG |= UDC_RX_EOT_IE(ep->dma_channel);
@@ -763,7 +788,7 @@ static void dma_channel_claim(struct oma
 		reg = UDC_TXDMA_CFG_REG;
 	else
 		reg = UDC_RXDMA_CFG_REG;
-	reg |= 1 << 12;		/* "pulse" activated */
+	reg |= UDC_DMA_REQ;		/* "pulse" activated */
 
 	ep->dma_channel = 0;
 	ep->lch = -1;
@@ -787,6 +812,11 @@ static void dma_channel_claim(struct oma
 			ep->ep.name, dma_error, ep, &ep->lch);
 		if (status == 0) {
 			UDC_TXDMA_CFG_REG = reg;
+			/* EMIFF */
+			omap_set_dma_src_burst_mode(ep->lch,
+						OMAP_DMA_DATA_BURST_4);
+			omap_set_dma_src_data_pack(ep->lch, 1);
+			/* TIPB */
 			omap_set_dma_dest_params(ep->lch,
 				OMAP_DMA_PORT_TIPB,
 				OMAP_DMA_AMODE_CONSTANT,
@@ -797,10 +827,15 @@ static void dma_channel_claim(struct oma
 			ep->ep.name, dma_error, ep, &ep->lch);
 		if (status == 0) {
 			UDC_RXDMA_CFG_REG = reg;
+			/* TIPB */
 			omap_set_dma_src_params(ep->lch,
 				OMAP_DMA_PORT_TIPB,
 				OMAP_DMA_AMODE_CONSTANT,
 				(unsigned long) io_v2p((u32)&UDC_DATA_DMA_REG));
+			/* EMIFF */
+			omap_set_dma_dest_burst_mode(ep->lch,
+						OMAP_DMA_DATA_BURST_4);
+			omap_set_dma_dest_data_pack(ep->lch, 1);
 		}
 	}
 	if (status)
@@ -856,7 +891,7 @@ static void dma_channel_release(struct o
 	if (!list_empty(&ep->queue))
 		req = container_of(ep->queue.next, struct omap_req, queue);
 	else
-		req = 0;
+		req = NULL;
 
 	active = ((1 << 7) & omap_readl(OMAP_DMA_CCR(ep->lch))) != 0;
 
@@ -865,9 +900,13 @@ static void dma_channel_release(struct o
 			(ep->bEndpointAddress & USB_DIR_IN) ? 't' : 'r',
 			ep->dma_channel - 1, req);
 
+	/* NOTE: re-setting RX_REQ/TX_REQ because of a chip bug (before
+	 * OMAP 1710 ES2.0) where reading the DMA_CFG can clear them.
+	 */
+
 	/* wait till current packet DMA finishes, and fifo empties */
 	if (ep->bEndpointAddress & USB_DIR_IN) {
-		UDC_TXDMA_CFG_REG &= ~mask;
+		UDC_TXDMA_CFG_REG = (UDC_TXDMA_CFG_REG & ~mask) | UDC_DMA_REQ;
 
 		if (req) {
 			finish_in_dma(ep, req, -ECONNRESET);
@@ -880,7 +919,7 @@ static void dma_channel_release(struct o
 		while (UDC_TXDMA_CFG_REG & mask)
 			udelay(10);
 	} else {
-		UDC_RXDMA_CFG_REG &= ~mask;
+		UDC_RXDMA_CFG_REG = (UDC_RXDMA_CFG_REG & ~mask) | UDC_DMA_REQ;
 
 		/* dma empties the fifo */
 		while (UDC_RXDMA_CFG_REG & mask)
@@ -898,7 +937,7 @@ static void dma_channel_release(struct o
 /*-------------------------------------------------------------------------*/
 
 static int
-omap_ep_queue(struct usb_ep *_ep, struct usb_request *_req, int gfp_flags)
+omap_ep_queue(struct usb_ep *_ep, struct usb_request *_req, unsigned gfp_flags)
 {
 	struct omap_ep	*ep = container_of(_ep, struct omap_ep, ep);
 	struct omap_req	*req = container_of(_req, struct omap_req, req);
@@ -997,18 +1036,19 @@ omap_ep_queue(struct usb_ep *_ep, struct
 					UDC_IRQ_EN_REG = irq_en;
 				}
 
-				/* STATUS is reverse direction */
-				UDC_EP_NUM_REG = is_in
-						? UDC_EP_SEL
-						: (UDC_EP_SEL|UDC_EP_DIR);
+				/* STATUS for zero length DATA stages is
+				 * always an IN ... even for IN transfers,
+				 * a wierd case which seem to stall OMAP.
+				 */
+				UDC_EP_NUM_REG = (UDC_EP_SEL|UDC_EP_DIR);
 				UDC_CTRL_REG = UDC_CLR_EP;
 				UDC_CTRL_REG = UDC_SET_FIFO_EN;
-				UDC_EP_NUM_REG = udc->ep0_in ? 0 : UDC_EP_DIR;
+				UDC_EP_NUM_REG = UDC_EP_DIR;
 
 				/* cleanup */
 				udc->ep0_pending = 0;
 				done(ep, req, 0);
-				req = 0;
+				req = NULL;
 
 			/* non-empty DATA stage */
 			} else if (is_in) {
@@ -1029,7 +1069,7 @@ omap_ep_queue(struct usb_ep *_ep, struct
 			(is_in ? next_in_dma : next_out_dma)(ep, req);
 		else if (req) {
 			if ((is_in ? write_fifo : read_fifo)(ep, req) == 1)
-				req = 0;
+				req = NULL;
 			deselect_ep();
 			if (!is_in) {
 				UDC_CTRL_REG = UDC_SET_FIFO_EN;
@@ -1041,7 +1081,7 @@ omap_ep_queue(struct usb_ep *_ep, struct
 
 irq_wait:
 	/* irq handler advances the queue */
-	if (req != 0)
+	if (req != NULL)
 		list_add_tail(&req->queue, &ep->queue);
 	spin_unlock_irqrestore(&udc->lock, flags);
 
@@ -1140,7 +1180,7 @@ static int omap_ep_set_halt(struct usb_e
 				dma_channel_claim(ep, channel);
 		} else {
 			use_ep(ep, 0);
-			UDC_CTRL_REG = UDC_RESET_EP;
+			UDC_CTRL_REG = ep->udc->clr_halt;
 			ep->ackwait = 0;
 			if (!(ep->bEndpointAddress & USB_DIR_IN)) {
 				UDC_CTRL_REG = UDC_SET_FIFO_EN;
@@ -1238,6 +1278,8 @@ static int can_pullup(struct omap_udc *u
 
 static void pullup_enable(struct omap_udc *udc)
 {
+	udc->gadget.dev.parent->power.power_state = PMSG_ON;
+	udc->gadget.dev.power.power_state = PMSG_ON;
 	UDC_SYSCON1_REG |= UDC_PULLUP_EN;
 #ifndef CONFIG_USB_OTG
 	if (!cpu_is_omap15xx())
@@ -1382,7 +1424,7 @@ static void update_otg(struct omap_udc *
 static void ep0_irq(struct omap_udc *udc, u16 irq_src)
 {
 	struct omap_ep	*ep0 = &udc->ep[0];
-	struct omap_req	*req = 0;
+	struct omap_req	*req = NULL;
 
 	ep0->irqs++;
 
@@ -1438,7 +1480,7 @@ static void ep0_irq(struct omap_udc *udc
 				if (req)
 					done(ep0, req, 0);
 			}
-			req = 0;
+			req = NULL;
 		} else if (stat & UDC_STALL) {
 			UDC_CTRL_REG = UDC_CLR_HALT;
 			UDC_EP_NUM_REG = UDC_EP_DIR;
@@ -1511,9 +1553,10 @@ static void ep0_irq(struct omap_udc *udc
 			u.word[3] = UDC_DATA_REG;
 			UDC_EP_NUM_REG = 0;
 		} while (UDC_IRQ_SRC_REG & UDC_SETUP);
-		le16_to_cpus (&u.r.wValue);
-		le16_to_cpus (&u.r.wIndex);
-		le16_to_cpus (&u.r.wLength);
+
+#define	w_value		le16_to_cpup (&u.r.wValue)
+#define	w_index		le16_to_cpup (&u.r.wIndex)
+#define	w_length	le16_to_cpup (&u.r.wLength)
 
 		/* Delegate almost all control requests to the gadget driver,
 		 * except for a handful of ch9 status/feature requests that
@@ -1529,11 +1572,11 @@ static void ep0_irq(struct omap_udc *udc
 			/* udc needs to know when ep != 0 is valid */
 			if (u.r.bRequestType != USB_RECIP_DEVICE)
 				goto delegate;
-			if (u.r.wLength != 0)
+			if (w_length != 0)
 				goto do_stall;
 			udc->ep0_set_config = 1;
-			udc->ep0_reset_config = (u.r.wValue == 0);
-			VDBG("set config %d\n", u.r.wValue);
+			udc->ep0_reset_config = (w_value == 0);
+			VDBG("set config %d\n", w_value);
 
 			/* update udc NOW since gadget driver may start
 			 * queueing requests immediately; clear config
@@ -1549,23 +1592,28 @@ static void ep0_irq(struct omap_udc *udc
 			/* clear endpoint halt */
 			if (u.r.bRequestType != USB_RECIP_ENDPOINT)
 				goto delegate;
-			if (u.r.wValue != USB_ENDPOINT_HALT
-					|| u.r.wLength != 0)
+			if (w_value != USB_ENDPOINT_HALT
+					|| w_length != 0)
 				goto do_stall;
-			ep = &udc->ep[u.r.wIndex & 0xf];
+			ep = &udc->ep[w_index & 0xf];
 			if (ep != ep0) {
-				if (u.r.wIndex & USB_DIR_IN)
+				if (w_index & USB_DIR_IN)
 					ep += 16;
 				if (ep->bmAttributes == USB_ENDPOINT_XFER_ISOC
 						|| !ep->desc)
 					goto do_stall;
 				use_ep(ep, 0);
-				UDC_CTRL_REG = UDC_RESET_EP;
+				UDC_CTRL_REG = udc->clr_halt;
 				ep->ackwait = 0;
 				if (!(ep->bEndpointAddress & USB_DIR_IN)) {
 					UDC_CTRL_REG = UDC_SET_FIFO_EN;
 					ep->ackwait = 1 + ep->double_buf;
 				}
+				/* NOTE:  assumes the host behaves sanely,
+				 * only clearing real halts.  Else we may
+				 * need to kill pending transfers and then
+				 * restart the queue... very messy for DMA!
+				 */
 			}
 			VDBG("%s halt cleared by host\n", ep->name);
 			goto ep0out_status_stage;
@@ -1573,11 +1621,11 @@ static void ep0_irq(struct omap_udc *udc
 			/* set endpoint halt */
 			if (u.r.bRequestType != USB_RECIP_ENDPOINT)
 				goto delegate;
-			if (u.r.wValue != USB_ENDPOINT_HALT
-					|| u.r.wLength != 0)
+			if (w_value != USB_ENDPOINT_HALT
+					|| w_length != 0)
 				goto do_stall;
-			ep = &udc->ep[u.r.wIndex & 0xf];
-			if (u.r.wIndex & USB_DIR_IN)
+			ep = &udc->ep[w_index & 0xf];
+			if (w_index & USB_DIR_IN)
 				ep += 16;
 			if (ep->bmAttributes == USB_ENDPOINT_XFER_ISOC
 					|| ep == ep0 || !ep->desc)
@@ -1615,13 +1663,13 @@ ep0out_status_stage:
 			UDC_CTRL_REG = UDC_SET_FIFO_EN;
 			UDC_EP_NUM_REG = UDC_EP_DIR;
 			status = 0;
-			VDBG("GET_STATUS, interface %d\n", u.r.wIndex);
+			VDBG("GET_STATUS, interface %d\n", w_index);
 			/* next, status stage */
 			break;
 		default:
 delegate:
 			/* activate the ep0out fifo right away */
-			if (!udc->ep0_in && u.r.wLength) {
+			if (!udc->ep0_in && w_length) {
 				UDC_EP_NUM_REG = 0;
 				UDC_CTRL_REG = UDC_SET_FIFO_EN;
 			}
@@ -1632,7 +1680,11 @@ delegate:
 			 */
 			VDBG("SETUP %02x.%02x v%04x i%04x l%04x\n",
 				u.r.bRequestType, u.r.bRequest,
-				u.r.wValue, u.r.wIndex, u.r.wLength);
+				w_value, w_index, w_length);
+
+#undef	w_value
+#undef	w_index
+#undef	w_length
 
 			/* The gadget driver may return an error here,
 			 * causing an immediate protocol stall.
@@ -2013,7 +2065,7 @@ int usb_gadget_register_driver (struct u
 	udc->softconnect = 1;
 
 	/* hook up the driver */
-	driver->driver.bus = 0;
+	driver->driver.bus = NULL;
 	udc->driver = driver;
 	udc->gadget.dev.driver = &driver->driver;
 	spin_unlock_irqrestore(&udc->lock, flags);
@@ -2021,8 +2073,8 @@ int usb_gadget_register_driver (struct u
 	status = driver->bind (&udc->gadget);
 	if (status) {
 		DBG("bind to %s --> %d\n", driver->driver.name, status);
-		udc->gadget.dev.driver = 0;
-		udc->driver = 0;
+		udc->gadget.dev.driver = NULL;
+		udc->driver = NULL;
 		goto done;
 	}
 	DBG("bound to driver %s\n", driver->driver.name);
@@ -2035,8 +2087,8 @@ int usb_gadget_register_driver (struct u
 		if (status < 0) {
 			ERR("can't bind to transceiver\n");
 			driver->unbind (&udc->gadget);
-			udc->gadget.dev.driver = 0;
-			udc->driver = 0;
+			udc->gadget.dev.driver = NULL;
+			udc->driver = NULL;
 			goto done;
 		}
 	} else {
@@ -2071,7 +2123,7 @@ int usb_gadget_unregister_driver (struct
 		omap_vbus_session(&udc->gadget, 0);
 
 	if (udc->transceiver)
-		(void) otg_set_peripheral(udc->transceiver, 0);
+		(void) otg_set_peripheral(udc->transceiver, NULL);
 	else
 		pullup_disable(udc);
 
@@ -2080,9 +2132,8 @@ int usb_gadget_unregister_driver (struct
 	spin_unlock_irqrestore(&udc->lock, flags);
 
 	driver->unbind(&udc->gadget);
-	udc->gadget.dev.driver = 0;
-	udc->driver = 0;
-
+	udc->gadget.dev.driver = NULL;
+	udc->driver = NULL;
 
 	DBG("unregistered driver '%s'\n", driver->driver.name);
 	return status;
@@ -2178,14 +2229,14 @@ static int proc_otg_show(struct seq_file
 
 	tmp = OTG_REV_REG;
 	trans = USB_TRANSCEIVER_CTRL_REG;
-	seq_printf(s, "OTG rev %d.%d, transceiver_ctrl %03x\n",
+	seq_printf(s, "\nOTG rev %d.%d, transceiver_ctrl %05x\n",
 		tmp >> 4, tmp & 0xf, trans);
 	tmp = OTG_SYSCON_1_REG;
 	seq_printf(s, "otg_syscon1 %08x usb2 %s, usb1 %s, usb0 %s,"
 			FOURBITS "\n", tmp,
 		trx_mode(USB2_TRX_MODE(tmp), trans & CONF_USB2_UNI_R),
 		trx_mode(USB1_TRX_MODE(tmp), trans & CONF_USB1_UNI_R),
-		(USB0_TRX_MODE(tmp) == 0)
+		(USB0_TRX_MODE(tmp) == 0 && !cpu_is_omap1710())
 			? "internal"
 			: trx_mode(USB0_TRX_MODE(tmp), 1),
 		(tmp & OTG_IDLE_EN) ? " !otg" : "",
@@ -2235,6 +2286,7 @@ static int proc_otg_show(struct seq_file
 	seq_printf(s, "otg_outctrl %04x" "\n", tmp);
 	tmp = OTG_TEST_REG;
 	seq_printf(s, "otg_test    %04x" "\n", tmp);
+	return 0;
 }
 
 static int proc_udc_show(struct seq_file *s, void *_)
@@ -2378,7 +2430,7 @@ static int proc_udc_show(struct seq_file
 
 static int proc_udc_open(struct inode *inode, struct file *file)
 {
-	return single_open(file, proc_udc_show, 0);
+	return single_open(file, proc_udc_show, NULL);
 }
 
 static struct file_operations proc_ops = {
@@ -2399,7 +2451,7 @@ static void create_proc_file(void)
 
 static void remove_proc_file(void)
 {
-	remove_proc_entry(proc_filename, 0);
+	remove_proc_entry(proc_filename, NULL);
 }
 
 #else
@@ -2414,6 +2466,10 @@ static inline void remove_proc_file(void
 /* Before this controller can enumerate, we need to pick an endpoint
  * configuration, or "fifo_mode"  That involves allocating 2KB of packet
  * buffer space among the endpoints we'll be operating.
+ *
+ * NOTE: as of OMAP 1710 ES2.0, writing a new endpoint config when
+ * UDC_SYSCON_1_REG.CFG_LOCK is set can now work.  We won't use that
+ * capability yet though.
  */
 static unsigned __init
 omap_ep_setup(char *name, u8 addr, u8 type,
@@ -2505,7 +2561,7 @@ static void omap_udc_release(struct devi
 {
 	complete(udc->done);
 	kfree (udc);
-	udc = 0;
+	udc = NULL;
 }
 
 static int __init
@@ -2577,23 +2633,33 @@ omap_udc_setup(struct platform_device *o
 	case 1:
 		OMAP_BULK_EP("ep1in",  USB_DIR_IN  | 1);
 		OMAP_BULK_EP("ep2out", USB_DIR_OUT | 2);
+		OMAP_INT_EP("ep9in",   USB_DIR_IN  | 9, 16);
+
 		OMAP_BULK_EP("ep3in",  USB_DIR_IN  | 3);
 		OMAP_BULK_EP("ep4out", USB_DIR_OUT | 4);
+		OMAP_INT_EP("ep10in",  USB_DIR_IN  | 10, 16);
 
 		OMAP_BULK_EP("ep5in",  USB_DIR_IN  | 5);
 		OMAP_BULK_EP("ep5out", USB_DIR_OUT | 5);
+		OMAP_INT_EP("ep11in",  USB_DIR_IN  | 11, 16);
+
 		OMAP_BULK_EP("ep6in",  USB_DIR_IN  | 6);
 		OMAP_BULK_EP("ep6out", USB_DIR_OUT | 6);
+		OMAP_INT_EP("ep12in",  USB_DIR_IN  | 12, 16);
 
 		OMAP_BULK_EP("ep7in",  USB_DIR_IN  | 7);
 		OMAP_BULK_EP("ep7out", USB_DIR_OUT | 7);
+		OMAP_INT_EP("ep13in",  USB_DIR_IN  | 13, 16);
+		OMAP_INT_EP("ep13out", USB_DIR_OUT | 13, 16);
+
 		OMAP_BULK_EP("ep8in",  USB_DIR_IN  | 8);
 		OMAP_BULK_EP("ep8out", USB_DIR_OUT | 8);
+		OMAP_INT_EP("ep14in",  USB_DIR_IN  | 14, 16);
+		OMAP_INT_EP("ep14out", USB_DIR_OUT | 14, 16);
+
+		OMAP_BULK_EP("ep15in",  USB_DIR_IN  | 15);
+		OMAP_BULK_EP("ep15out", USB_DIR_OUT | 15);
 
-		OMAP_INT_EP("ep9in",   USB_DIR_IN  | 9, 16);
-		OMAP_INT_EP("ep10out", USB_DIR_IN  | 10, 16);
-		OMAP_INT_EP("ep11in",  USB_DIR_IN  | 9, 16);
-		OMAP_INT_EP("ep12out", USB_DIR_IN  | 10, 16);
 		break;
 
 #ifdef	USE_ISO
@@ -2640,8 +2706,8 @@ static int __init omap_udc_probe(struct 
 	struct platform_device	*odev = to_platform_device(dev);
 	int			status = -ENODEV;
 	int			hmc;
-	struct otg_transceiver	*xceiv = 0;
-	const char		*type = 0;
+	struct otg_transceiver	*xceiv = NULL;
+	const char		*type = NULL;
 	struct omap_usb_config	*config = dev->platform_data;
 
 	/* NOTE:  "knows" the order of the resources! */
@@ -2676,54 +2742,78 @@ static int __init omap_udc_probe(struct 
 			FUNC_MUX_CTRL_0_REG = tmp;
 		}
 	} else {
+		/* The transceiver may package some GPIO logic or handle
+		 * loopback and/or transceiverless setup; if we find one,
+		 * use it.  Except for OTG, we don't _need_ to talk to one;
+		 * but not having one probably means no VBUS detection.
+		 */
+		xceiv = otg_get_transceiver();
+		if (xceiv)
+			type = xceiv->label;
+		else if (config->otg) {
+			DBG("OTG requires external transceiver!\n");
+			goto cleanup0;
+		}
+
 		hmc = HMC_1610;
 		switch (hmc) {
+		case 0:			/* POWERUP DEFAULT == 0 */
+		case 4:
+		case 12:
+		case 20:
+			if (!cpu_is_omap1710()) {
+				type = "integrated";
+				break;
+			}
+			/* FALL THROUGH */
 		case 3:
 		case 11:
 		case 16:
 		case 19:
 		case 25:
-			xceiv = otg_get_transceiver();
 			if (!xceiv) {
 				DBG("external transceiver not registered!\n");
-				if (config->otg)
-					goto cleanup0;
-				type = "(unknown external)";
-			} else
-				type = xceiv->label;
-			break;
-		case 0:			/* POWERUP DEFAULT == 0 */
-		case 4:
-		case 12:
-		case 20:
-			type = "INTEGRATED";
+				type = "unknown";
+			}
 			break;
 		case 21:			/* internal loopback */
-			type = "(loopback)";
+			type = "loopback";
 			break;
 		case 14:			/* transceiverless */
-			type = "(none)";
+			if (cpu_is_omap1710())
+				goto bad_on_1710;
+			/* FALL THROUGH */
+		case 13:
+		case 15:
+			type = "no";
 			break;
 
 		default:
+bad_on_1710:
 			ERR("unrecognized UDC HMC mode %d\n", hmc);
-			return -ENODEV;
+			goto cleanup0;
 		}
 	}
-	INFO("hmc mode %d, transceiver %s\n", hmc, type);
+	INFO("hmc mode %d, %s transceiver\n", hmc, type);
 
 	/* a "gadget" abstracts/virtualizes the controller */
 	status = omap_udc_setup(odev, xceiv);
 	if (status) {
 		goto cleanup0;
 	}
-	xceiv = 0;
+	xceiv = NULL;
 	// "udc" is now valid
 	pullup_disable(udc);
 #if	defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
 	udc->gadget.is_otg = (config->otg != 0);
 #endif
 
+	/* starting with omap1710 es2.0, clear toggle is a separate bit */
+	if (UDC_REV_REG >= 0x61)
+		udc->clr_halt = UDC_RESET_EP | UDC_CLRDATA_TOGGLE;
+	else
+		udc->clr_halt = UDC_RESET_EP;
+
 	/* USB general purpose IRQ:  ep0, state changes, dma, etc */
 	status = request_irq(odev->resource[1].start, omap_udc_irq,
 			SA_SAMPLE_RANDOM, driver_name, udc);
@@ -2765,7 +2855,7 @@ cleanup2:
 
 cleanup1:
 	kfree (udc);
-	udc = 0;
+	udc = NULL;
 
 cleanup0:
 	if (xceiv)
@@ -2788,7 +2878,7 @@ static int __exit omap_udc_remove(struct
 	pullup_disable(udc);
 	if (udc->transceiver) {
 		put_device(udc->transceiver->dev);
-		udc->transceiver = 0;
+		udc->transceiver = NULL;
 	}
 	UDC_SYSCON1_REG = 0;
 
@@ -2809,13 +2899,33 @@ static int __exit omap_udc_remove(struct
 	return 0;
 }
 
-static int omap_udc_suspend(struct device *dev, pm_message_t state, u32 level)
+/* suspend/resume/wakeup from sysfs (echo > power/state) or when the
+ * system is forced into deep sleep
+ *
+ * REVISIT we should probably reject suspend requests when there's a host
+ * session active, rather than disconnecting, at least on boards that can
+ * report VBUS irqs (UDC_DEVSTAT_REG.UDC_ATT).  And in any case, we need to
+ * make host resumes and VBUS detection trigger OMAP wakeup events; that
+ * may involve talking to an external transceiver (e.g. isp1301).
+ */
+
+static int omap_udc_suspend(struct device *dev, pm_message_t message, u32 level)
 {
-	if (level != 0)
+	u32	devstat;
+
+	if (level != SUSPEND_POWER_DOWN)
 		return 0;
+	devstat = UDC_DEVSTAT_REG;
+
+	/* we're requesting 48 MHz clock if the pullup is enabled
+	 * (== we're attached to the host) and we're not suspended,
+	 * which would prevent entry to deep sleep...
+	 */
+	if ((devstat & UDC_ATT) != 0 && (devstat & UDC_SUS) == 0) {
+		WARN("session active; suspend requires disconnect\n");
+		omap_pullup(&udc->gadget, 0);
+	}
 
-	DBG("suspend, state %d\n", state);
-	omap_pullup(&udc->gadget, 0);
 	udc->gadget.dev.power.power_state = PMSG_SUSPEND;
 	udc->gadget.dev.parent->power.power_state = PMSG_SUSPEND;
 	return 0;
@@ -2823,12 +2933,10 @@ static int omap_udc_suspend(struct devic
 
 static int omap_udc_resume(struct device *dev, u32 level)
 {
-	if (level != 0)
+	if (level != RESUME_POWER_ON)
 		return 0;
 
 	DBG("resume + wakeup/SRP\n");
-	udc->gadget.dev.parent->power.power_state = PMSG_ON;
-	udc->gadget.dev.power.power_state = PMSG_ON;
 	omap_pullup(&udc->gadget, 1);
 
 	/* maybe the host would enumerate us if we nudged it */
diff --git a/drivers/usb/gadget/omap_udc.h b/drivers/usb/gadget/omap_udc.h
--- a/drivers/usb/gadget/omap_udc.h
+++ b/drivers/usb/gadget/omap_udc.h
@@ -20,6 +20,7 @@
 #define	UDC_CTRL_REG			UDC_REG(0x0C)	/* Endpoint control */
 #	define	UDC_CLR_HALT		(1 << 7)
 #	define	UDC_SET_HALT		(1 << 6)
+#	define	UDC_CLRDATA_TOGGLE	(1 << 3)
 #	define	UDC_SET_FIFO_EN		(1 << 2)
 #	define	UDC_CLR_EP		(1 << 1)
 #	define	UDC_RESET_EP		(1 << 0)
@@ -99,6 +100,7 @@
 
 /* DMA configuration registers:  up to three channels in each direction.  */
 #define	UDC_RXDMA_CFG_REG		UDC_REG(0x40)	/* 3 eps for RX DMA */
+#	define	UDC_DMA_REQ		(1 << 12)
 #define	UDC_TXDMA_CFG_REG		UDC_REG(0x44)	/* 3 eps for TX DMA */
 #define	UDC_DATA_DMA_REG		UDC_REG(0x48)	/* rx/tx fifo addr */
 
@@ -162,6 +164,7 @@ struct omap_udc {
 	spinlock_t			lock;
 	struct omap_ep			ep[32];
 	u16				devstat;
+	u16				clr_halt;
 	struct otg_transceiver		*transceiver;
 	struct list_head		iso;
 	unsigned			softconnect:1;
@@ -171,7 +174,6 @@ struct omap_udc {
 	unsigned			ep0_set_config:1;
 	unsigned			ep0_reset_config:1;
 	unsigned			ep0_setup:1;
-
 	struct completion		*done;
 };
 
diff --git a/drivers/usb/gadget/pxa2xx_udc.c b/drivers/usb/gadget/pxa2xx_udc.c
--- a/drivers/usb/gadget/pxa2xx_udc.c
+++ b/drivers/usb/gadget/pxa2xx_udc.c
@@ -1,6 +1,6 @@
 /*
  * linux/drivers/usb/gadget/pxa2xx_udc.c
- * Intel PXA2xx and IXP4xx on-chip full speed USB device controllers
+ * Intel PXA25x and IXP4xx on-chip full speed USB device controllers
  *
  * Copyright (C) 2002 Intrinsyc, Inc. (Frank Becker)
  * Copyright (C) 2003 Robert Schwebel, Pengutronix
@@ -63,7 +63,7 @@
 
 
 /*
- * This driver handles the USB Device Controller (UDC) in Intel's PXA 2xx
+ * This driver handles the USB Device Controller (UDC) in Intel's PXA 25x
  * series processors.  The UDC for the IXP 4xx series is very similar.
  * There are fifteen endpoints, in addition to ep0.
  *
@@ -79,8 +79,8 @@
  * pxa250 a0/a1 b0/b1/b2 sure act like they're still there.
  */
 
-#define	DRIVER_VERSION	"14-Dec-2003"
-#define	DRIVER_DESC	"PXA 2xx USB Device Controller driver"
+#define	DRIVER_VERSION	"4-May-2005"
+#define	DRIVER_DESC	"PXA 25x USB Device Controller driver"
 
 
 static const char driver_name [] = "pxa2xx_udc";
@@ -290,6 +290,7 @@ static int pxa2xx_ep_enable (struct usb_
 static int pxa2xx_ep_disable (struct usb_ep *_ep)
 {
 	struct pxa2xx_ep	*ep;
+	unsigned long		flags;
 
 	ep = container_of (_ep, struct pxa2xx_ep, ep);
 	if (!_ep || !ep->desc) {
@@ -297,6 +298,8 @@ static int pxa2xx_ep_disable (struct usb
 			_ep ? ep->ep.name : NULL);
 		return -EINVAL;
 	}
+	local_irq_save(flags);
+
 	nuke (ep, -ESHUTDOWN);
 
 #ifdef	USE_DMA
@@ -313,6 +316,7 @@ static int pxa2xx_ep_disable (struct usb
 	ep->desc = NULL;
 	ep->stopped = 1;
 
+	local_irq_restore(flags);
 	DBG(DBG_VERBOSE, "%s disabled\n", _ep->name);
 	return 0;
 }
@@ -328,7 +332,7 @@ static int pxa2xx_ep_disable (struct usb
  * 	pxa2xx_ep_alloc_request - allocate a request data structure
  */
 static struct usb_request *
-pxa2xx_ep_alloc_request (struct usb_ep *_ep, int gfp_flags)
+pxa2xx_ep_alloc_request (struct usb_ep *_ep, unsigned gfp_flags)
 {
 	struct pxa2xx_request *req;
 
@@ -363,7 +367,7 @@ pxa2xx_ep_free_request (struct usb_ep *_
  */
 static void *
 pxa2xx_ep_alloc_buffer(struct usb_ep *_ep, unsigned bytes,
-	dma_addr_t *dma, int gfp_flags)
+	dma_addr_t *dma, unsigned gfp_flags)
 {
 	char			*retval;
 
@@ -870,7 +874,7 @@ done:
 /*-------------------------------------------------------------------------*/
 
 static int
-pxa2xx_ep_queue(struct usb_ep *_ep, struct usb_request *_req, int gfp_flags)
+pxa2xx_ep_queue(struct usb_ep *_ep, struct usb_request *_req, unsigned gfp_flags)
 {
 	struct pxa2xx_request	*req;
 	struct pxa2xx_ep	*ep;
@@ -971,10 +975,10 @@ pxa2xx_ep_queue(struct usb_ep *_ep, stru
 			kick_dma(ep, req);
 #endif
 		/* can the FIFO can satisfy the request immediately? */
-		} else if ((ep->bEndpointAddress & USB_DIR_IN) != 0
-				&& (*ep->reg_udccs & UDCCS_BI_TFS) != 0
-				&& write_fifo(ep, req)) {
-			req = NULL;
+		} else if ((ep->bEndpointAddress & USB_DIR_IN) != 0) {
+			if ((*ep->reg_udccs & UDCCS_BI_TFS) != 0
+					&& write_fifo(ep, req))
+				req = NULL;
 		} else if ((*ep->reg_udccs & UDCCS_BO_RFS) != 0
 				&& read_fifo(ep, req)) {
 			req = NULL;
@@ -1290,7 +1294,7 @@ udc_proc_read(char *page, char **start, 
 		"%s version: %s\nGadget driver: %s\nHost %s\n\n",
 		driver_name, DRIVER_VERSION SIZE_STR DMASTR,
 		dev->driver ? dev->driver->driver.name : "(none)",
-		is_usb_connected() ? "full speed" : "disconnected");
+		is_vbus_present() ? "full speed" : "disconnected");
 	size -= t;
 	next += t;
 
@@ -1339,7 +1343,7 @@ udc_proc_read(char *page, char **start, 
 		next += t;
 	}
 
-	if (!is_usb_connected() || !dev->driver)
+	if (!is_vbus_present() || !dev->driver)
 		goto done;
 
 	t = scnprintf(next, size, "ep0 IN %lu/%lu, OUT %lu/%lu\nirqs %lu\n\n",
@@ -1429,7 +1433,7 @@ done:
 
 /* "function" sysfs attribute */
 static ssize_t
-show_function (struct device *_dev, char *buf)
+show_function (struct device *_dev, struct device_attribute *attr, char *buf)
 {
 	struct pxa2xx_udc	*dev = dev_get_drvdata (_dev);
 
@@ -1454,7 +1458,7 @@ static void udc_disable(struct pxa2xx_ud
 	UFNRH = UFNRH_SIM;
 
 	/* if hardware supports it, disconnect from usb */
-	make_usb_disappear();
+	pullup_off();
 
 	udc_clear_mask_UDCCR(UDCCR_UDE);
 
@@ -1567,7 +1571,7 @@ static void udc_enable (struct pxa2xx_ud
 	UICR0 &= ~UICR0_IM0;
 
 	/* if hardware supports it, pullup D+ and wait for reset */
-	let_usb_appear();
+	pullup_on();
 }
 
 
@@ -2052,10 +2056,10 @@ pxa2xx_udc_irq(int irq, void *_dev, stru
 		if (unlikely(udccr & UDCCR_SUSIR)) {
 			udc_ack_int_UDCCR(UDCCR_SUSIR);
 			handled = 1;
-			DBG(DBG_VERBOSE, "USB suspend%s\n", is_usb_connected()
+			DBG(DBG_VERBOSE, "USB suspend%s\n", is_vbus_present()
 				? "" : "+disconnect");
 
-			if (!is_usb_connected())
+			if (!is_vbus_present())
 				stop_activity(dev, dev->driver);
 			else if (dev->gadget.speed != USB_SPEED_UNKNOWN
 					&& dev->driver
@@ -2073,7 +2077,7 @@ pxa2xx_udc_irq(int irq, void *_dev, stru
 			if (dev->gadget.speed != USB_SPEED_UNKNOWN
 					&& dev->driver
 					&& dev->driver->resume
-					&& is_usb_connected())
+					&& is_vbus_present())
 				dev->driver->resume(&dev->gadget);
 		}
 
@@ -2509,7 +2513,7 @@ static int __init pxa2xx_udc_probe(struc
 	udc_disable(dev);
 	udc_reinit(dev);
 
-	dev->vbus = is_usb_connected();
+	dev->vbus = is_vbus_present();
 
 	/* irq setup after old hardware state is cleaned up */
 	retval = request_irq(IRQ_USB, pxa2xx_udc_irq,
@@ -2555,6 +2559,12 @@ lubbock_fail0:
 
 	return 0;
 }
+
+static void pxa2xx_udc_shutdown(struct device *_dev)
+{
+	pullup_off();
+}
+
 static int __exit pxa2xx_udc_remove(struct device *_dev)
 {
 	struct pxa2xx_udc *dev = dev_get_drvdata(_dev);
@@ -2624,6 +2634,7 @@ static struct device_driver udc_driver =
 	.name		= "pxa2xx-udc",
 	.bus		= &platform_bus_type,
 	.probe		= pxa2xx_udc_probe,
+	.shutdown	= pxa2xx_udc_shutdown,
 	.remove		= __exit_p(pxa2xx_udc_remove),
 	.suspend	= pxa2xx_udc_suspend,
 	.resume		= pxa2xx_udc_resume,
diff --git a/drivers/usb/gadget/pxa2xx_udc.h b/drivers/usb/gadget/pxa2xx_udc.h
--- a/drivers/usb/gadget/pxa2xx_udc.h
+++ b/drivers/usb/gadget/pxa2xx_udc.h
@@ -177,23 +177,23 @@ struct pxa2xx_udc {
 
 static struct pxa2xx_udc *the_controller;
 
-/* one GPIO should be used to detect host disconnect */
-static inline int is_usb_connected(void)
+/* one GPIO should be used to detect VBUS from the host */
+static inline int is_vbus_present(void)
 {
 	if (!the_controller->mach->udc_is_connected)
 		return 1;
 	return the_controller->mach->udc_is_connected();
 }
 
-/* one GPIO should force the host to see this device (or not) */
-static inline void make_usb_disappear(void)
+/* one GPIO should control a D+ pullup, so host sees this device (or not) */
+static inline void pullup_off(void)
 {
 	if (!the_controller->mach->udc_command)
 		return;
 	the_controller->mach->udc_command(PXA2XX_UDC_CMD_DISCONNECT);
 }
 
-static inline void let_usb_appear(void)
+static inline void pullup_on(void)
 {
 	if (!the_controller->mach->udc_command)
 		return;
diff --git a/drivers/usb/gadget/rndis.c b/drivers/usb/gadget/rndis.c
--- a/drivers/usb/gadget/rndis.c
+++ b/drivers/usb/gadget/rndis.c
@@ -41,6 +41,7 @@
 
 
 #undef	RNDIS_PM
+#undef	RNDIS_WAKEUP
 #undef	VERBOSE
 
 #include "rndis.h"
@@ -60,7 +61,7 @@
 	} while (0)
 static int rndis_debug = 0;
 
-module_param (rndis_debug, bool, 0);
+module_param (rndis_debug, int, 0);
 MODULE_PARM_DESC (rndis_debug, "enable debugging");
 
 #else
@@ -78,22 +79,103 @@ static rndis_params rndis_per_dev_params
 static const __le32 rndis_driver_version = __constant_cpu_to_le32 (1);
 
 /* Function Prototypes */
-static int rndis_init_response (int configNr, rndis_init_msg_type *buf);
-static int rndis_query_response (int configNr, rndis_query_msg_type *buf);
-static int rndis_set_response (int configNr, rndis_set_msg_type *buf);
-static int rndis_reset_response (int configNr, rndis_reset_msg_type *buf);
-static int rndis_keepalive_response (int configNr, 
-				     rndis_keepalive_msg_type *buf);
-
 static rndis_resp_t *rndis_add_response (int configNr, u32 length);
 
 
+/* supported OIDs */
+static const u32 oid_supported_list [] = 
+{
+	/* the general stuff */
+	OID_GEN_SUPPORTED_LIST,
+	OID_GEN_HARDWARE_STATUS,
+	OID_GEN_MEDIA_SUPPORTED,
+	OID_GEN_MEDIA_IN_USE,
+	OID_GEN_MAXIMUM_FRAME_SIZE,
+	OID_GEN_LINK_SPEED,
+	OID_GEN_TRANSMIT_BLOCK_SIZE,
+	OID_GEN_RECEIVE_BLOCK_SIZE,
+	OID_GEN_VENDOR_ID,
+	OID_GEN_VENDOR_DESCRIPTION,
+	OID_GEN_VENDOR_DRIVER_VERSION,
+	OID_GEN_CURRENT_PACKET_FILTER,
+	OID_GEN_MAXIMUM_TOTAL_SIZE,
+	OID_GEN_MEDIA_CONNECT_STATUS,
+	OID_GEN_PHYSICAL_MEDIUM,
+#if 0
+	OID_GEN_RNDIS_CONFIG_PARAMETER,
+#endif
+	
+	/* the statistical stuff */
+	OID_GEN_XMIT_OK,
+	OID_GEN_RCV_OK,
+	OID_GEN_XMIT_ERROR,
+	OID_GEN_RCV_ERROR,
+	OID_GEN_RCV_NO_BUFFER,
+#ifdef	RNDIS_OPTIONAL_STATS
+	OID_GEN_DIRECTED_BYTES_XMIT,
+	OID_GEN_DIRECTED_FRAMES_XMIT,
+	OID_GEN_MULTICAST_BYTES_XMIT,
+	OID_GEN_MULTICAST_FRAMES_XMIT,
+	OID_GEN_BROADCAST_BYTES_XMIT,
+	OID_GEN_BROADCAST_FRAMES_XMIT,
+	OID_GEN_DIRECTED_BYTES_RCV,
+	OID_GEN_DIRECTED_FRAMES_RCV,
+	OID_GEN_MULTICAST_BYTES_RCV,
+	OID_GEN_MULTICAST_FRAMES_RCV,
+	OID_GEN_BROADCAST_BYTES_RCV,
+	OID_GEN_BROADCAST_FRAMES_RCV,
+	OID_GEN_RCV_CRC_ERROR,
+	OID_GEN_TRANSMIT_QUEUE_LENGTH,
+#endif	/* RNDIS_OPTIONAL_STATS */
+
+    	/* mandatory 802.3 */
+	/* the general stuff */
+	OID_802_3_PERMANENT_ADDRESS,
+	OID_802_3_CURRENT_ADDRESS,
+	OID_802_3_MULTICAST_LIST,
+	OID_802_3_MAC_OPTIONS,
+	OID_802_3_MAXIMUM_LIST_SIZE,
+	
+	/* the statistical stuff */
+	OID_802_3_RCV_ERROR_ALIGNMENT,
+	OID_802_3_XMIT_ONE_COLLISION,
+	OID_802_3_XMIT_MORE_COLLISIONS,
+#ifdef	RNDIS_OPTIONAL_STATS
+	OID_802_3_XMIT_DEFERRED,
+	OID_802_3_XMIT_MAX_COLLISIONS,
+	OID_802_3_RCV_OVERRUN,
+	OID_802_3_XMIT_UNDERRUN,
+	OID_802_3_XMIT_HEARTBEAT_FAILURE,
+	OID_802_3_XMIT_TIMES_CRS_LOST,
+	OID_802_3_XMIT_LATE_COLLISIONS,
+#endif	/* RNDIS_OPTIONAL_STATS */
+
+#ifdef	RNDIS_PM
+	/* PM and wakeup are mandatory for USB: */
+
+	/* power management */
+	OID_PNP_CAPABILITIES,
+	OID_PNP_QUERY_POWER,
+	OID_PNP_SET_POWER,
+
+#ifdef	RNDIS_WAKEUP
+	/* wake up host */
+	OID_PNP_ENABLE_WAKE_UP,
+	OID_PNP_ADD_WAKE_UP_PATTERN,
+	OID_PNP_REMOVE_WAKE_UP_PATTERN,
+#endif	/* RNDIS_WAKEUP */
+#endif	/* RNDIS_PM */
+};
+
+
 /* NDIS Functions */
-static int gen_ndis_query_resp (int configNr, u32 OID, rndis_resp_t *r)
+static int
+gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
+		rndis_resp_t *r)
 {
 	int 			retval = -ENOTSUPP;
-	u32 			length = 0;
-	__le32			*tmp;
+	u32 			length = 4;	/* usually */
+	__le32			*outbuf;
 	int			i, count;
 	rndis_query_cmplt_type	*resp;
 
@@ -101,7 +183,22 @@ static int gen_ndis_query_resp (int conf
 	resp = (rndis_query_cmplt_type *) r->buf;
 
 	if (!resp) return -ENOMEM;
-	
+
+	if (buf_len && rndis_debug > 1) {
+		DEBUG("query OID %08x value, len %d:\n", OID, buf_len);
+		for (i = 0; i < buf_len; i += 16) {
+			DEBUG ("%03d: %08x %08x %08x %08x\n", i,
+				le32_to_cpup((__le32 *)&buf[i]),
+				le32_to_cpup((__le32 *)&buf[i + 4]),
+				le32_to_cpup((__le32 *)&buf[i + 8]),
+				le32_to_cpup((__le32 *)&buf[i + 12]));
+		}
+	}
+
+	/* response goes here, right after the header */
+	outbuf = (__le32 *) &resp[1];
+	resp->InformationBufferOffset = __constant_cpu_to_le32 (16);
+
 	switch (OID) {
 
 	/* general oids (table 4-1) */
@@ -111,42 +208,36 @@ static int gen_ndis_query_resp (int conf
 		DEBUG ("%s: OID_GEN_SUPPORTED_LIST\n", __FUNCTION__);
 		length = sizeof (oid_supported_list);
 		count  = length / sizeof (u32);
-		tmp = (__le32 *) ((u8 *)resp + 24);
 		for (i = 0; i < count; i++)
-			tmp[i] = cpu_to_le32 (oid_supported_list[i]);
+			outbuf[i] = cpu_to_le32 (oid_supported_list[i]);
 		retval = 0;
 		break;
 		
 	/* mandatory */
 	case OID_GEN_HARDWARE_STATUS:
 		DEBUG("%s: OID_GEN_HARDWARE_STATUS\n", __FUNCTION__);
-		length = 4;
 		/* Bogus question! 
 		 * Hardware must be ready to receive high level protocols.
 		 * BTW: 
 		 * reddite ergo quae sunt Caesaris Caesari
 		 * et quae sunt Dei Deo!
 		 */
-		*((__le32 *) resp + 6) = __constant_cpu_to_le32 (0);
+		*outbuf = __constant_cpu_to_le32 (0);
 		retval = 0;
 		break;
 		
 	/* mandatory */
 	case OID_GEN_MEDIA_SUPPORTED:
 		DEBUG("%s: OID_GEN_MEDIA_SUPPORTED\n", __FUNCTION__);
-		length = 4;
-		*((__le32 *) resp + 6) = cpu_to_le32 (
-					rndis_per_dev_params [configNr].medium);
+		*outbuf = cpu_to_le32 (rndis_per_dev_params [configNr].medium);
 		retval = 0;
 		break;
 		
 	/* mandatory */
 	case OID_GEN_MEDIA_IN_USE:
 		DEBUG("%s: OID_GEN_MEDIA_IN_USE\n", __FUNCTION__);
-		length = 4;
 		/* one medium, one transport... (maybe you do it better) */
-		*((__le32 *) resp + 6) = cpu_to_le32 (
-					rndis_per_dev_params [configNr].medium);
+		*outbuf = cpu_to_le32 (rndis_per_dev_params [configNr].medium);
 		retval = 0;
 		break;
 		
@@ -154,25 +245,21 @@ static int gen_ndis_query_resp (int conf
 	case OID_GEN_MAXIMUM_FRAME_SIZE:
 		DEBUG("%s: OID_GEN_MAXIMUM_FRAME_SIZE\n", __FUNCTION__);
 		if (rndis_per_dev_params [configNr].dev) {
-			length = 4;
-			*((__le32 *) resp + 6) = cpu_to_le32 (
+			*outbuf = cpu_to_le32 (
 				rndis_per_dev_params [configNr].dev->mtu);
 			retval = 0;
-		} else {
-			*((__le32 *) resp + 6) = __constant_cpu_to_le32 (0);
-			retval = 0;
 		}
 		break;
 		
 	/* mandatory */
 	case OID_GEN_LINK_SPEED:
-//		DEBUG("%s: OID_GEN_LINK_SPEED\n", __FUNCTION__);
-		length = 4;
+		if (rndis_debug > 1)
+			DEBUG("%s: OID_GEN_LINK_SPEED\n", __FUNCTION__);
 		if (rndis_per_dev_params [configNr].media_state
-			== NDIS_MEDIA_STATE_DISCONNECTED)
-		    *((__le32 *) resp + 6) = __constant_cpu_to_le32 (0);
+				== NDIS_MEDIA_STATE_DISCONNECTED)
+			*outbuf = __constant_cpu_to_le32 (0);
 		else
-		    *((__le32 *) resp + 6) = cpu_to_le32 (
+			*outbuf = cpu_to_le32 (
 				rndis_per_dev_params [configNr].speed);
 		retval = 0;
 		break;
@@ -181,8 +268,7 @@ static int gen_ndis_query_resp (int conf
 	case OID_GEN_TRANSMIT_BLOCK_SIZE:
 		DEBUG("%s: OID_GEN_TRANSMIT_BLOCK_SIZE\n", __FUNCTION__);
 		if (rndis_per_dev_params [configNr].dev) {
-			length = 4;
-			*((__le32 *) resp + 6) = cpu_to_le32 (
+			*outbuf = cpu_to_le32 (
 				rndis_per_dev_params [configNr].dev->mtu);
 			retval = 0;
 		}
@@ -192,8 +278,7 @@ static int gen_ndis_query_resp (int conf
 	case OID_GEN_RECEIVE_BLOCK_SIZE:
 		DEBUG("%s: OID_GEN_RECEIVE_BLOCK_SIZE\n", __FUNCTION__);
 		if (rndis_per_dev_params [configNr].dev) {
-			length = 4;
-			*((__le32 *) resp + 6) = cpu_to_le32 (
+			*outbuf = cpu_to_le32 (
 				rndis_per_dev_params [configNr].dev->mtu);
 			retval = 0;
 		}
@@ -202,8 +287,7 @@ static int gen_ndis_query_resp (int conf
 	/* mandatory */
 	case OID_GEN_VENDOR_ID:
 		DEBUG("%s: OID_GEN_VENDOR_ID\n", __FUNCTION__);
-		length = 4;
-		*((__le32 *) resp + 6) = cpu_to_le32 (
+		*outbuf = cpu_to_le32 (
 			rndis_per_dev_params [configNr].vendorID);
 		retval = 0;
 		break;
@@ -212,51 +296,44 @@ static int gen_ndis_query_resp (int conf
 	case OID_GEN_VENDOR_DESCRIPTION:
 		DEBUG("%s: OID_GEN_VENDOR_DESCRIPTION\n", __FUNCTION__);
 		length = strlen (rndis_per_dev_params [configNr].vendorDescr);
-		memcpy ((u8 *) resp + 24, 
+		memcpy (outbuf,
 			rndis_per_dev_params [configNr].vendorDescr, length);
 		retval = 0;
 		break;
 
 	case OID_GEN_VENDOR_DRIVER_VERSION:
 		DEBUG("%s: OID_GEN_VENDOR_DRIVER_VERSION\n", __FUNCTION__);
-		length = 4;
 		/* Created as LE */
-		*((__le32 *) resp + 6) = rndis_driver_version;
+		*outbuf = rndis_driver_version;
 		retval = 0;
 		break;
 
 	/* mandatory */
 	case OID_GEN_CURRENT_PACKET_FILTER:
 		DEBUG("%s: OID_GEN_CURRENT_PACKET_FILTER\n", __FUNCTION__);
-		length = 4;
-		*((__le32 *) resp + 6) = cpu_to_le32 (
-					rndis_per_dev_params[configNr].filter);
+		*outbuf = cpu_to_le32 (*rndis_per_dev_params[configNr].filter);
 		retval = 0;
 		break;
 
 	/* mandatory */
 	case OID_GEN_MAXIMUM_TOTAL_SIZE:
 		DEBUG("%s: OID_GEN_MAXIMUM_TOTAL_SIZE\n", __FUNCTION__);
-		length = 4;
-		*((__le32 *) resp + 6) = __constant_cpu_to_le32(
-					RNDIS_MAX_TOTAL_SIZE);
+		*outbuf = __constant_cpu_to_le32(RNDIS_MAX_TOTAL_SIZE);
 		retval = 0;
 		break;
 
 	/* mandatory */
 	case OID_GEN_MEDIA_CONNECT_STATUS:
-		DEBUG("%s: OID_GEN_MEDIA_CONNECT_STATUS\n", __FUNCTION__);
-		length = 4;
-		*((__le32 *) resp + 6) = cpu_to_le32 (
-					rndis_per_dev_params [configNr]
+		if (rndis_debug > 1)
+			DEBUG("%s: OID_GEN_MEDIA_CONNECT_STATUS\n", __FUNCTION__);
+		*outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
 						.media_state);
 		retval = 0;
 		break;
 
 	case OID_GEN_PHYSICAL_MEDIUM:
 		DEBUG("%s: OID_GEN_PHYSICAL_MEDIUM\n", __FUNCTION__);
-		length = 4;
-		*((__le32 *) resp + 6) = __constant_cpu_to_le32 (0);
+		*outbuf = __constant_cpu_to_le32 (0);
 		retval = 0;
 		break;
 
@@ -266,8 +343,7 @@ static int gen_ndis_query_resp (int conf
 	 */
 	case OID_GEN_MAC_OPTIONS:		/* from WinME */
 		DEBUG("%s: OID_GEN_MAC_OPTIONS\n", __FUNCTION__);
-		length = 4;
-		*((__le32 *) resp + 6) = __constant_cpu_to_le32(
+		*outbuf = __constant_cpu_to_le32(
 			  NDIS_MAC_OPTION_RECEIVE_SERIALIZED
 			| NDIS_MAC_OPTION_FULL_DUPLEX);
 		retval = 0;
@@ -277,62 +353,49 @@ static int gen_ndis_query_resp (int conf
 
 	/* mandatory */
 	case OID_GEN_XMIT_OK:
-		DEBUG("%s: OID_GEN_XMIT_OK\n", __FUNCTION__);
+		if (rndis_debug > 1)
+			DEBUG("%s: OID_GEN_XMIT_OK\n", __FUNCTION__);
 		if (rndis_per_dev_params [configNr].stats) {
-			length = 4;
-			*((__le32 *) resp + 6) = cpu_to_le32 (
+			*outbuf = cpu_to_le32 (
 			    rndis_per_dev_params [configNr].stats->tx_packets - 
 			    rndis_per_dev_params [configNr].stats->tx_errors -
 			    rndis_per_dev_params [configNr].stats->tx_dropped);
 			retval = 0;
-		} else {
-			*((__le32 *) resp + 6) = __constant_cpu_to_le32 (0);
-			retval = 0;
 		}
 		break;
 
 	/* mandatory */
 	case OID_GEN_RCV_OK:
-		DEBUG("%s: OID_GEN_RCV_OK\n", __FUNCTION__);
+		if (rndis_debug > 1)
+			DEBUG("%s: OID_GEN_RCV_OK\n", __FUNCTION__);
 		if (rndis_per_dev_params [configNr].stats) {
-			length = 4;
-			*((__le32 *) resp + 6) = cpu_to_le32 (
+			*outbuf = cpu_to_le32 (
 			    rndis_per_dev_params [configNr].stats->rx_packets - 
 			    rndis_per_dev_params [configNr].stats->rx_errors -
 			    rndis_per_dev_params [configNr].stats->rx_dropped);
 			retval = 0;
-		} else {
-			*((__le32 *) resp + 6) = __constant_cpu_to_le32 (0);
-			retval = 0;
 		}
 		break;
 		
 	/* mandatory */
 	case OID_GEN_XMIT_ERROR:
-		DEBUG("%s: OID_GEN_XMIT_ERROR\n", __FUNCTION__);
+		if (rndis_debug > 1)
+			DEBUG("%s: OID_GEN_XMIT_ERROR\n", __FUNCTION__);
 		if (rndis_per_dev_params [configNr].stats) {
-			length = 4;
-			*((__le32 *) resp + 6) = cpu_to_le32 (
-				rndis_per_dev_params [configNr]
+			*outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
 					.stats->tx_errors);
 			retval = 0;
-		} else {
-			*((__le32 *) resp + 6) = __constant_cpu_to_le32 (0);
-			retval = 0;
 		}
 		break;
 		
 	/* mandatory */
 	case OID_GEN_RCV_ERROR:
-		DEBUG("%s: OID_GEN_RCV_ERROR\n", __FUNCTION__);
+		if (rndis_debug > 1)
+			DEBUG("%s: OID_GEN_RCV_ERROR\n", __FUNCTION__);
 		if (rndis_per_dev_params [configNr].stats) {
-			*((__le32 *) resp + 6) = cpu_to_le32 (
-				rndis_per_dev_params [configNr]
+			*outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
 					.stats->rx_errors);
 			retval = 0;
-		} else {
-			*((__le32 *) resp + 6) = __constant_cpu_to_le32 (0);
-			retval = 0;
 		}
 		break;
 		
@@ -340,13 +403,9 @@ static int gen_ndis_query_resp (int conf
 	case OID_GEN_RCV_NO_BUFFER:
 		DEBUG("%s: OID_GEN_RCV_NO_BUFFER\n", __FUNCTION__);
 		if (rndis_per_dev_params [configNr].stats) {
-			*((__le32 *) resp + 6) = cpu_to_le32 (
-				rndis_per_dev_params [configNr]
+			*outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
 					.stats->rx_dropped);
 			retval = 0;
-		} else {
-			*((__le32 *) resp + 6) = __constant_cpu_to_le32 (0);
-			retval = 0;
 		}
 		break;
 
@@ -359,8 +418,7 @@ static int gen_ndis_query_resp (int conf
 		 * divided by weight of Alpha Centauri
 		 */
 		if (rndis_per_dev_params [configNr].stats) {
-			length = 4;
-			*((__le32 *) resp + 6) = cpu_to_le32 (
+			*outbuf = cpu_to_le32 (
 				(rndis_per_dev_params [configNr]
 					.stats->tx_packets - 
 				 rndis_per_dev_params [configNr]
@@ -369,9 +427,6 @@ static int gen_ndis_query_resp (int conf
 					 .stats->tx_dropped)
 				* 123);
 			retval = 0;
-		} else {
-			*((__le32 *) resp + 6) = __constant_cpu_to_le32 (0);
-			retval = 0;
 		}
 		break;
 		
@@ -379,8 +434,7 @@ static int gen_ndis_query_resp (int conf
 		DEBUG("%s: OID_GEN_DIRECTED_FRAMES_XMIT\n", __FUNCTION__);
 		/* dito */
 		if (rndis_per_dev_params [configNr].stats) {
-			length = 4;
-			*((__le32 *) resp + 6) = cpu_to_le32 (
+			*outbuf = cpu_to_le32 (
 				(rndis_per_dev_params [configNr]
 					.stats->tx_packets - 
 				 rndis_per_dev_params [configNr]
@@ -389,144 +443,105 @@ static int gen_ndis_query_resp (int conf
 					 .stats->tx_dropped)
 				/ 123);
 			retval = 0;
-		} else {
-			*((__le32 *) resp + 6) = __constant_cpu_to_le32 (0);
-			retval = 0;
 		}
 		break;
 		
 	case OID_GEN_MULTICAST_BYTES_XMIT:
 		DEBUG("%s: OID_GEN_MULTICAST_BYTES_XMIT\n", __FUNCTION__);
 		if (rndis_per_dev_params [configNr].stats) {
-			*((__le32 *) resp + 6) = cpu_to_le32 (
-				rndis_per_dev_params [configNr]
+			*outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
 					.stats->multicast*1234);
 			retval = 0;
-		} else {
-			*((__le32 *) resp + 6) = __constant_cpu_to_le32 (0);
-			retval = 0;
 		}
 		break;
 		
 	case OID_GEN_MULTICAST_FRAMES_XMIT:
 		DEBUG("%s: OID_GEN_MULTICAST_FRAMES_XMIT\n", __FUNCTION__);
 		if (rndis_per_dev_params [configNr].stats) {
-			*((__le32 *) resp + 6) = cpu_to_le32 (
-				rndis_per_dev_params [configNr]
+			*outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
 					.stats->multicast);
 			retval = 0;
-		} else {
-			*((__le32 *) resp + 6) = __constant_cpu_to_le32 (0);
-			retval = 0;
 		}
 		break;
 		
 	case OID_GEN_BROADCAST_BYTES_XMIT:
 		DEBUG("%s: OID_GEN_BROADCAST_BYTES_XMIT\n", __FUNCTION__);
 		if (rndis_per_dev_params [configNr].stats) {
-			*((__le32 *) resp + 6) = cpu_to_le32 (
-				rndis_per_dev_params [configNr]
+			*outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
 					.stats->tx_packets/42*255);
 			retval = 0;
-		} else {
-			*((__le32 *) resp + 6) = __constant_cpu_to_le32 (0);
-			retval = 0;
 		}
 		break;
 		
 	case OID_GEN_BROADCAST_FRAMES_XMIT:
 		DEBUG("%s: OID_GEN_BROADCAST_FRAMES_XMIT\n", __FUNCTION__);
 		if (rndis_per_dev_params [configNr].stats) {
-			*((__le32 *) resp + 6) = cpu_to_le32 (
-				rndis_per_dev_params [configNr]
+			*outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
 					.stats->tx_packets/42);
 			retval = 0;
-		} else {
-			*((__le32 *) resp + 6) = __constant_cpu_to_le32 (0);
-			retval = 0;
 		}
 		break;
 		
 	case OID_GEN_DIRECTED_BYTES_RCV:
 		DEBUG("%s: OID_GEN_DIRECTED_BYTES_RCV\n", __FUNCTION__);
-		*((__le32 *) resp + 6) = __constant_cpu_to_le32 (0);
+		*outbuf = __constant_cpu_to_le32 (0);
 		retval = 0;
 		break;
 		
 	case OID_GEN_DIRECTED_FRAMES_RCV:
 		DEBUG("%s: OID_GEN_DIRECTED_FRAMES_RCV\n", __FUNCTION__);
-		*((__le32 *) resp + 6) = __constant_cpu_to_le32 (0);
+		*outbuf = __constant_cpu_to_le32 (0);
 		retval = 0;
 		break;
 		
 	case OID_GEN_MULTICAST_BYTES_RCV:
 		DEBUG("%s: OID_GEN_MULTICAST_BYTES_RCV\n", __FUNCTION__);
 		if (rndis_per_dev_params [configNr].stats) {
-			*((__le32 *) resp + 6) = cpu_to_le32 (
-				rndis_per_dev_params [configNr]
+			*outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
 					.stats->multicast * 1111);
 			retval = 0;
-		} else {
-			*((__le32 *) resp + 6) = __constant_cpu_to_le32 (0);
-			retval = 0;
 		}
 		break;
 		
 	case OID_GEN_MULTICAST_FRAMES_RCV:
 		DEBUG("%s: OID_GEN_MULTICAST_FRAMES_RCV\n", __FUNCTION__);
 		if (rndis_per_dev_params [configNr].stats) {
-			*((__le32 *) resp + 6) = cpu_to_le32 (
-				rndis_per_dev_params [configNr]
+			*outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
 					.stats->multicast);
 			retval = 0;
-		} else {
-			*((__le32 *) resp + 6) = __constant_cpu_to_le32 (0);
-			retval = 0;
 		}
 		break;
 		
 	case OID_GEN_BROADCAST_BYTES_RCV:
 		DEBUG("%s: OID_GEN_BROADCAST_BYTES_RCV\n", __FUNCTION__);
 		if (rndis_per_dev_params [configNr].stats) {
-			*((__le32 *) resp + 6) = cpu_to_le32 (
-				rndis_per_dev_params [configNr]
+			*outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
 					.stats->rx_packets/42*255);
 			retval = 0;
-		} else {
-			*((__le32 *) resp + 6) = __constant_cpu_to_le32 (0);
-			retval = 0;
 		}
 		break;
 		
 	case OID_GEN_BROADCAST_FRAMES_RCV:
 		DEBUG("%s: OID_GEN_BROADCAST_FRAMES_RCV\n", __FUNCTION__);
 		if (rndis_per_dev_params [configNr].stats) {
-			*((__le32 *) resp + 6) = cpu_to_le32 (
-				rndis_per_dev_params [configNr]
+			*outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
 					.stats->rx_packets/42);
 			retval = 0;
-		} else {
-			*((__le32 *) resp + 6) = __constant_cpu_to_le32 (0);
-			retval = 0;
 		}
 		break;
 		
 	case OID_GEN_RCV_CRC_ERROR:
 		DEBUG("%s: OID_GEN_RCV_CRC_ERROR\n", __FUNCTION__);
 		if (rndis_per_dev_params [configNr].stats) {
-			*((__le32 *) resp + 6) = cpu_to_le32 (
-				rndis_per_dev_params [configNr]
+			*outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
 					.stats->rx_crc_errors);
 			retval = 0;
-		} else {
-			*((__le32 *) resp + 6) = __constant_cpu_to_le32 (0);
-			retval = 0;
 		}
 		break;
 		
 	case OID_GEN_TRANSMIT_QUEUE_LENGTH:
 		DEBUG("%s: OID_GEN_TRANSMIT_QUEUE_LENGTH\n", __FUNCTION__);
-		*((__le32 *) resp + 6) = __constant_cpu_to_le32 (0);
+		*outbuf = __constant_cpu_to_le32 (0);
 		retval = 0;
 		break;
 #endif	/* RNDIS_OPTIONAL_STATS */
@@ -538,13 +553,10 @@ static int gen_ndis_query_resp (int conf
 		DEBUG("%s: OID_802_3_PERMANENT_ADDRESS\n", __FUNCTION__);
 		if (rndis_per_dev_params [configNr].dev) {
 			length = ETH_ALEN;
-			memcpy ((u8 *) resp + 24,
+			memcpy (outbuf,
 				rndis_per_dev_params [configNr].host_mac,
 				length);
 			retval = 0;
-		} else {
-			*((__le32 *) resp + 6) = __constant_cpu_to_le32 (0);
-			retval = 0;
 		}
 		break;
 		
@@ -553,7 +565,7 @@ static int gen_ndis_query_resp (int conf
 		DEBUG("%s: OID_802_3_CURRENT_ADDRESS\n", __FUNCTION__);
 		if (rndis_per_dev_params [configNr].dev) {
 			length = ETH_ALEN;
-			memcpy ((u8 *) resp + 24,
+			memcpy (outbuf,
 				rndis_per_dev_params [configNr].host_mac,
 				length);
 			retval = 0;
@@ -563,18 +575,16 @@ static int gen_ndis_query_resp (int conf
 	/* mandatory */
 	case OID_802_3_MULTICAST_LIST:
 		DEBUG("%s: OID_802_3_MULTICAST_LIST\n", __FUNCTION__);
-		length = 4;
 		/* Multicast base address only */
-		*((__le32 *) resp + 6) = __constant_cpu_to_le32 (0xE0000000);
+		*outbuf = __constant_cpu_to_le32 (0xE0000000);
 		retval = 0;
 		break;
 		
 	/* mandatory */
 	case OID_802_3_MAXIMUM_LIST_SIZE:
 		DEBUG("%s: OID_802_3_MAXIMUM_LIST_SIZE\n", __FUNCTION__);
-		 length = 4;
 		/* Multicast base address only */
-		*((__le32 *) resp + 6) = __constant_cpu_to_le32 (1);
+		*outbuf = __constant_cpu_to_le32 (1);
 		retval = 0;
 		break;
 		
@@ -587,11 +597,8 @@ static int gen_ndis_query_resp (int conf
 	/* mandatory */
 	case OID_802_3_RCV_ERROR_ALIGNMENT:
 		DEBUG("%s: OID_802_3_RCV_ERROR_ALIGNMENT\n", __FUNCTION__);
-		if (rndis_per_dev_params [configNr].stats)
-		{
-			length = 4;
-			*((__le32 *) resp + 6) = cpu_to_le32 (
-				rndis_per_dev_params [configNr]
+		if (rndis_per_dev_params [configNr].stats) {
+			*outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
 					.stats->rx_frame_errors);
 			retval = 0;
 		}
@@ -600,16 +607,14 @@ static int gen_ndis_query_resp (int conf
 	/* mandatory */
 	case OID_802_3_XMIT_ONE_COLLISION:
 		DEBUG("%s: OID_802_3_XMIT_ONE_COLLISION\n", __FUNCTION__);
-		length = 4;
-		*((__le32 *) resp + 6) = __constant_cpu_to_le32 (0);
+		*outbuf = __constant_cpu_to_le32 (0);
 		retval = 0;
 		break;
 		
 	/* mandatory */
 	case OID_802_3_XMIT_MORE_COLLISIONS:
 		DEBUG("%s: OID_802_3_XMIT_MORE_COLLISIONS\n", __FUNCTION__);
-		length = 4;
-		*((__le32 *) resp + 6) = __constant_cpu_to_le32 (0);
+		*outbuf = __constant_cpu_to_le32 (0);
 		retval = 0;
 		break;
 		
@@ -655,27 +660,18 @@ static int gen_ndis_query_resp (int conf
 	case OID_PNP_CAPABILITIES:
 		DEBUG("%s: OID_PNP_CAPABILITIES\n", __FUNCTION__);
 
-		/* just PM, and remote wakeup on link status change
-		 * (not magic packet or pattern match)
-		 */
+		/* for now, no wakeup capabilities */
 		length = sizeof (struct NDIS_PNP_CAPABILITIES);
-		memset (resp, 0, length);
-		{
-			struct NDIS_PNP_CAPABILITIES *caps = (void *) resp;
-
-			caps->Flags = NDIS_DEVICE_WAKE_UP_ENABLE;
-			caps->WakeUpCapabilities.MinLinkChangeWakeUp 
-				 = NdisDeviceStateD3;
-
-			/* FIXME then use usb_gadget_wakeup(), and
-			 * set USB_CONFIG_ATT_WAKEUP in config desc
-			 */
-		}
+		memset(outbuf, 0, length);
 		retval = 0;
 		break;
 	case OID_PNP_QUERY_POWER:
-		DEBUG("%s: OID_PNP_QUERY_POWER\n", __FUNCTION__);
-		/* sure, handle any power state that maps to USB suspend */
+		DEBUG("%s: OID_PNP_QUERY_POWER D%d\n", __FUNCTION__,
+				le32_to_cpup((__le32 *) buf) - 1);
+		/* only suspend is a real power state, and
+		 * it can't be entered by OID_PNP_SET_POWER...
+		 */
+		length = 0;
 		retval = 0;
 		break;
 #endif
@@ -684,11 +680,12 @@ static int gen_ndis_query_resp (int conf
 		printk (KERN_WARNING "%s: query unknown OID 0x%08X\n", 
 			 __FUNCTION__, OID);
 	}
+	if (retval < 0)
+		length = 0;
 	
-	resp->InformationBufferOffset = __constant_cpu_to_le32 (16);
 	resp->InformationBufferLength = cpu_to_le32 (length);
-	resp->MessageLength = cpu_to_le32 (24 + length);
-	r->length = 24 + length;
+	r->length = length + sizeof *resp;
+	resp->MessageLength = cpu_to_le32 (r->length);
 	return retval;
 }
 
@@ -705,45 +702,40 @@ static int gen_ndis_set_resp (u8 configN
 	if (!resp)
 		return -ENOMEM;
 
-	DEBUG("set OID %08x value, len %d:\n", OID, buf_len);
-	for (i = 0; i < buf_len; i += 16) {
-		DEBUG ("%03d: "
-			" %02x %02x %02x %02x"
-			" %02x %02x %02x %02x"
-			" %02x %02x %02x %02x"
-			" %02x %02x %02x %02x"
-			"\n",
-			i,
-			buf[i], buf [i+1],
-				buf[i+2], buf[i+3],
-			buf[i+4], buf [i+5],
-				buf[i+6], buf[i+7],
-			buf[i+8], buf [i+9],
-				buf[i+10], buf[i+11],
-			buf[i+12], buf [i+13],
-				buf[i+14], buf[i+15]);
+	if (buf_len && rndis_debug > 1) {
+		DEBUG("set OID %08x value, len %d:\n", OID, buf_len);
+		for (i = 0; i < buf_len; i += 16) {
+			DEBUG ("%03d: %08x %08x %08x %08x\n", i,
+				le32_to_cpup((__le32 *)&buf[i]),
+				le32_to_cpup((__le32 *)&buf[i + 4]),
+				le32_to_cpup((__le32 *)&buf[i + 8]),
+				le32_to_cpup((__le32 *)&buf[i + 12]));
+		}
 	}
 
+	params = &rndis_per_dev_params [configNr];
 	switch (OID) {
 	case OID_GEN_CURRENT_PACKET_FILTER:
-		params = &rndis_per_dev_params [configNr];
-		retval = 0;
 
-		/* FIXME use these NDIS_PACKET_TYPE_* bitflags to
-		 * set the cdc_filter; it's not RNDIS-specific
+		/* these NDIS_PACKET_TYPE_* bitflags are shared with
+		 * cdc_filter; it's not RNDIS-specific
 		 * NDIS_PACKET_TYPE_x == USB_CDC_PACKET_TYPE_x for x in:
 		 *	PROMISCUOUS, DIRECTED,
 		 *	MULTICAST, ALL_MULTICAST, BROADCAST
 		 */
-		params->filter = le32_to_cpup((__le32 *)buf);
+		*params->filter = (u16) le32_to_cpup((__le32 *)buf);
 		DEBUG("%s: OID_GEN_CURRENT_PACKET_FILTER %08x\n",
-			__FUNCTION__, params->filter);
+			__FUNCTION__, *params->filter);
 
 		/* this call has a significant side effect:  it's
 		 * what makes the packet flow start and stop, like
 		 * activating the CDC Ethernet altsetting.
 		 */
-		if (params->filter) {
+#ifdef	RNDIS_PM
+update_linkstate:
+#endif
+		retval = 0;
+		if (*params->filter) {
 			params->state = RNDIS_DATA_INITIALIZED;
 			netif_carrier_on(params->dev);
 			if (netif_running(params->dev))
@@ -776,21 +768,34 @@ static int gen_ndis_set_resp (u8 configN
 
 #ifdef	RNDIS_PM
 	case OID_PNP_SET_POWER:
-		DEBUG ("OID_PNP_SET_POWER\n");
-		/* sure, handle any power state that maps to USB suspend */
-		retval = 0;
-		break;
-
-	case OID_PNP_ENABLE_WAKE_UP:
-		/* always-connected ... */
-		DEBUG ("OID_PNP_ENABLE_WAKE_UP\n");
-		retval = 0;
+		/* The only real power state is USB suspend, and RNDIS requests
+		 * can't enter it; this one isn't really about power.  After
+		 * resuming, Windows forces a reset, and then SET_POWER D0.
+		 * FIXME ... then things go batty; Windows wedges itself.
+		 */
+		i = le32_to_cpup((__force __le32 *)buf);
+		DEBUG("%s: OID_PNP_SET_POWER D%d\n", __FUNCTION__, i - 1);
+		switch (i) {
+		case NdisDeviceStateD0:
+			*params->filter = params->saved_filter;
+			goto update_linkstate;
+		case NdisDeviceStateD3:
+		case NdisDeviceStateD2:
+		case NdisDeviceStateD1:
+			params->saved_filter = *params->filter;
+			retval = 0;
+			break;
+		}
 		break;
 
-	// no PM resume patterns supported (specified where?)
-	// so OID_PNP_{ADD,REMOVE}_WAKE_UP_PATTERN always fails
+#ifdef	RNDIS_WAKEUP
+	// no wakeup support advertised, so wakeup OIDs always fail:
+	//  - OID_PNP_ENABLE_WAKE_UP
+	//  - OID_PNP_{ADD,REMOVE}_WAKE_UP_PATTERN
 #endif
 
+#endif	/* RNDIS_PM */
+
 	default:
 		printk (KERN_WARNING "%s: set unknown OID 0x%08X, size %d\n", 
 			 __FUNCTION__, OID, buf_len);
@@ -811,13 +816,10 @@ static int rndis_init_response (int conf
 	if (!rndis_per_dev_params [configNr].dev) return -ENOTSUPP;
 	
 	r = rndis_add_response (configNr, sizeof (rndis_init_cmplt_type));
-	
-	if (!r) return -ENOMEM;
-	
+	if (!r)
+		return -ENOMEM;
 	resp = (rndis_init_cmplt_type *) r->buf;
 	
-	if (!resp) return -ENOMEM;
-	
 	resp->MessageType = __constant_cpu_to_le32 (
 			REMOTE_NDIS_INITIALIZE_CMPLT);
 	resp->MessageLength = __constant_cpu_to_le32 (52);
@@ -857,20 +859,22 @@ static int rndis_query_response (int con
 	 * oid_supported_list is the largest answer 
 	 */
 	r = rndis_add_response (configNr, sizeof (oid_supported_list));
-	
-	if (!r) return -ENOMEM;
+	if (!r)
+		return -ENOMEM;
 	resp = (rndis_query_cmplt_type *) r->buf;
 	
-	if (!resp) return -ENOMEM;
-	
 	resp->MessageType = __constant_cpu_to_le32 (REMOTE_NDIS_QUERY_CMPLT);
-	resp->MessageLength = __constant_cpu_to_le32 (24);
 	resp->RequestID = buf->RequestID; /* Still LE in msg buffer */
-	
-	if (gen_ndis_query_resp (configNr, le32_to_cpu (buf->OID), r)) {
+  	
+	if (gen_ndis_query_resp (configNr, le32_to_cpu (buf->OID),
+			le32_to_cpu(buf->InformationBufferOffset)
+					+ 8 + (u8 *) buf,
+			le32_to_cpu(buf->InformationBufferLength),
+			r)) {
 		/* OID not supported */
 		resp->Status = __constant_cpu_to_le32 (
 				RNDIS_STATUS_NOT_SUPPORTED);
+		resp->MessageLength = __constant_cpu_to_le32 (sizeof *resp);
 		resp->InformationBufferLength = __constant_cpu_to_le32 (0);
 		resp->InformationBufferOffset = __constant_cpu_to_le32 (0);
 	} else
@@ -889,10 +893,9 @@ static int rndis_set_response (int confi
 	rndis_resp_t		*r;
 	
 	r = rndis_add_response (configNr, sizeof (rndis_set_cmplt_type));
-	
-	if (!r) return -ENOMEM;
+	if (!r)
+		return -ENOMEM;
 	resp = (rndis_set_cmplt_type *) r->buf;
-	if (!resp) return -ENOMEM;
 
 	BufLength = le32_to_cpu (buf->InformationBufferLength);
 	BufOffset = le32_to_cpu (buf->InformationBufferOffset);
@@ -930,10 +933,9 @@ static int rndis_reset_response (int con
 	rndis_resp_t		*r;
 	
 	r = rndis_add_response (configNr, sizeof (rndis_reset_cmplt_type));
-	
-	if (!r) return -ENOMEM;
+	if (!r)
+		return -ENOMEM;
 	resp = (rndis_reset_cmplt_type *) r->buf;
-	if (!resp) return -ENOMEM;
 	
 	resp->MessageType = __constant_cpu_to_le32 (REMOTE_NDIS_RESET_CMPLT);
 	resp->MessageLength = __constant_cpu_to_le32 (16);
@@ -957,8 +959,9 @@ static int rndis_keepalive_response (int
 	/* host "should" check only in RNDIS_DATA_INITIALIZED state */
 
 	r = rndis_add_response (configNr, sizeof (rndis_keepalive_cmplt_type));
+	if (!r)
+		return -ENOMEM;
 	resp = (rndis_keepalive_cmplt_type *) r->buf;
-	if (!resp) return -ENOMEM;
 		
 	resp->MessageType = __constant_cpu_to_le32 (
 			REMOTE_NDIS_KEEPALIVE_CMPLT);
@@ -987,10 +990,9 @@ static int rndis_indicate_status_msg (in
 	
 	r = rndis_add_response (configNr, 
 				sizeof (rndis_indicate_status_msg_type));
-	if (!r) return -ENOMEM;
-	
+	if (!r)
+		return -ENOMEM;
 	resp = (rndis_indicate_status_msg_type *) r->buf;
-	if (!resp) return -ENOMEM;
 	
 	resp->MessageType = __constant_cpu_to_le32 (
 			REMOTE_NDIS_INDICATE_STATUS_MSG);
@@ -1021,6 +1023,21 @@ int rndis_signal_disconnect (int configN
 					  RNDIS_STATUS_MEDIA_DISCONNECT);
 }
 
+void rndis_uninit (int configNr)
+{
+	u8 *buf;
+	u32 length;
+
+	if (configNr >= RNDIS_MAX_CONFIGS)
+		return;
+	rndis_per_dev_params [configNr].used = 0;
+	rndis_per_dev_params [configNr].state = RNDIS_UNINITIALIZED;
+
+	/* drain the response queue */
+	while ((buf = rndis_get_next_response(configNr, &length)))
+		rndis_free_response(configNr, buf);
+}
+
 void rndis_set_host_mac (int configNr, const u8 *addr)
 {
 	rndis_per_dev_params [configNr].host_mac = addr;
@@ -1046,9 +1063,13 @@ int rndis_msg_parser (u8 configNr, u8 *b
 		return -ENOTSUPP;
 	params = &rndis_per_dev_params [configNr];
 	
+	/* NOTE: RNDIS is *EXTREMELY* chatty ... Windows constantly polls for
+	 * rx/tx statistics and link status, in addition to KEEPALIVE traffic
+	 * and normal HC level polling to see if there's any IN traffic.
+	 */
+
 	/* For USB: responses may take up to 10 seconds */
-	switch (MsgType)
-	{
+	switch (MsgType) {
 	case REMOTE_NDIS_INITIALIZE_MSG:
 		DEBUG("%s: REMOTE_NDIS_INITIALIZE_MSG\n", 
 			__FUNCTION__ );
@@ -1082,10 +1103,9 @@ int rndis_msg_parser (u8 configNr, u8 *b
 
 	case REMOTE_NDIS_KEEPALIVE_MSG:
 		/* For USB: host does this every 5 seconds */
-#ifdef	VERBOSE
-		DEBUG("%s: REMOTE_NDIS_KEEPALIVE_MSG\n", 
-			__FUNCTION__ );
-#endif
+		if (rndis_debug > 1)
+			DEBUG("%s: REMOTE_NDIS_KEEPALIVE_MSG\n", 
+				__FUNCTION__ );
 		return rndis_keepalive_response (configNr,
 						 (rndis_keepalive_msg_type *) 
 						 buf);
@@ -1152,7 +1172,8 @@ void rndis_deregister (int configNr)
 }
 
 int rndis_set_param_dev (u8 configNr, struct net_device *dev, 
-			 struct net_device_stats *stats)
+			 struct net_device_stats *stats,
+			 u16 *cdc_filter)
 {
 	DEBUG("%s:\n", __FUNCTION__ );
 	if (!dev || !stats) return -1;
@@ -1160,6 +1181,7 @@ int rndis_set_param_dev (u8 configNr, st
 	
 	rndis_per_dev_params [configNr].dev = dev;
 	rndis_per_dev_params [configNr].stats = stats;
+	rndis_per_dev_params [configNr].filter = cdc_filter;
 	
 	return 0;
 }
@@ -1178,7 +1200,7 @@ int rndis_set_param_vendor (u8 configNr,
 
 int rndis_set_param_medium (u8 configNr, u32 medium, u32 speed)
 {
-	DEBUG("%s:\n", __FUNCTION__ );
+	DEBUG("%s: %u %u\n", __FUNCTION__, medium, speed);
 	if (configNr >= RNDIS_MAX_CONFIGS) return -1;
 	
 	rndis_per_dev_params [configNr].medium = medium;
@@ -1242,6 +1264,7 @@ static rndis_resp_t *rndis_add_response 
 {
 	rndis_resp_t	*r;
 	
+	/* NOTE:  this gets copied into ether.c USB_BUFSIZ bytes ... */
 	r = kmalloc (sizeof (rndis_resp_t) + length, GFP_ATOMIC);
 	if (!r) return NULL;
 	
diff --git a/drivers/usb/gadget/rndis.h b/drivers/usb/gadget/rndis.h
--- a/drivers/usb/gadget/rndis.h
+++ b/drivers/usb/gadget/rndis.h
@@ -69,90 +69,6 @@
 #define OID_PNP_ENABLE_WAKE_UP			0xFD010106
 
 
-/* supported OIDs */
-static const u32 oid_supported_list [] = 
-{
-	/* the general stuff */
-	OID_GEN_SUPPORTED_LIST,
-	OID_GEN_HARDWARE_STATUS,
-	OID_GEN_MEDIA_SUPPORTED,
-	OID_GEN_MEDIA_IN_USE,
-	OID_GEN_MAXIMUM_FRAME_SIZE,
-	OID_GEN_LINK_SPEED,
-	OID_GEN_TRANSMIT_BLOCK_SIZE,
-	OID_GEN_RECEIVE_BLOCK_SIZE,
-	OID_GEN_VENDOR_ID,
-	OID_GEN_VENDOR_DESCRIPTION,
-	OID_GEN_VENDOR_DRIVER_VERSION,
-	OID_GEN_CURRENT_PACKET_FILTER,
-	OID_GEN_MAXIMUM_TOTAL_SIZE,
-	OID_GEN_MEDIA_CONNECT_STATUS,
-	OID_GEN_PHYSICAL_MEDIUM,
-#if 0
-	OID_GEN_RNDIS_CONFIG_PARAMETER,
-#endif
-	
-	/* the statistical stuff */
-	OID_GEN_XMIT_OK,
-	OID_GEN_RCV_OK,
-	OID_GEN_XMIT_ERROR,
-	OID_GEN_RCV_ERROR,
-	OID_GEN_RCV_NO_BUFFER,
-#ifdef	RNDIS_OPTIONAL_STATS
-	OID_GEN_DIRECTED_BYTES_XMIT,
-	OID_GEN_DIRECTED_FRAMES_XMIT,
-	OID_GEN_MULTICAST_BYTES_XMIT,
-	OID_GEN_MULTICAST_FRAMES_XMIT,
-	OID_GEN_BROADCAST_BYTES_XMIT,
-	OID_GEN_BROADCAST_FRAMES_XMIT,
-	OID_GEN_DIRECTED_BYTES_RCV,
-	OID_GEN_DIRECTED_FRAMES_RCV,
-	OID_GEN_MULTICAST_BYTES_RCV,
-	OID_GEN_MULTICAST_FRAMES_RCV,
-	OID_GEN_BROADCAST_BYTES_RCV,
-	OID_GEN_BROADCAST_FRAMES_RCV,
-	OID_GEN_RCV_CRC_ERROR,
-	OID_GEN_TRANSMIT_QUEUE_LENGTH,
-#endif	/* RNDIS_OPTIONAL_STATS */
-
-    	/* mandatory 802.3 */
-	/* the general stuff */
-	OID_802_3_PERMANENT_ADDRESS,
-	OID_802_3_CURRENT_ADDRESS,
-	OID_802_3_MULTICAST_LIST,
-	OID_802_3_MAC_OPTIONS,
-	OID_802_3_MAXIMUM_LIST_SIZE,
-	
-	/* the statistical stuff */
-	OID_802_3_RCV_ERROR_ALIGNMENT,
-	OID_802_3_XMIT_ONE_COLLISION,
-	OID_802_3_XMIT_MORE_COLLISIONS,
-#ifdef	RNDIS_OPTIONAL_STATS
-	OID_802_3_XMIT_DEFERRED,
-	OID_802_3_XMIT_MAX_COLLISIONS,
-	OID_802_3_RCV_OVERRUN,
-	OID_802_3_XMIT_UNDERRUN,
-	OID_802_3_XMIT_HEARTBEAT_FAILURE,
-	OID_802_3_XMIT_TIMES_CRS_LOST,
-	OID_802_3_XMIT_LATE_COLLISIONS,
-#endif	/* RNDIS_OPTIONAL_STATS */
-
-#ifdef	RNDIS_PM
-	/* PM and wakeup are mandatory for USB: */
-
-	/* power management */
-	OID_PNP_CAPABILITIES,
-	OID_PNP_QUERY_POWER,
-	OID_PNP_SET_POWER,
-
-	/* wake up host */
-	OID_PNP_ENABLE_WAKE_UP,
-	OID_PNP_ADD_WAKE_UP_PATTERN,
-	OID_PNP_REMOVE_WAKE_UP_PATTERN,
-#endif
-};
-
-
 typedef struct rndis_init_msg_type 
 {
 	__le32	MessageType;
@@ -309,15 +225,18 @@ typedef struct rndis_resp_t
 typedef struct rndis_params
 {
 	u8			confignr;
-	int			used;
+	u8			used;
+	u16			saved_filter;
 	enum rndis_state	state;
-	u32			filter;
 	u32			medium;
 	u32			speed;
 	u32			media_state;
+
 	const u8		*host_mac;
+	u16			*filter;
 	struct net_device 	*dev;
 	struct net_device_stats *stats;
+
 	u32			vendorID;
 	const char		*vendorDescr;
 	int 			(*ack) (struct net_device *);
@@ -329,7 +248,8 @@ int  rndis_msg_parser (u8 configNr, u8 *
 int  rndis_register (int (*rndis_control_ack) (struct net_device *));
 void rndis_deregister (int configNr);
 int  rndis_set_param_dev (u8 configNr, struct net_device *dev,
-			 struct net_device_stats *stats);
+			 struct net_device_stats *stats,
+			 u16 *cdc_filter);
 int  rndis_set_param_vendor (u8 configNr, u32 vendorID, 
 			    const char *vendorDescr);
 int  rndis_set_param_medium (u8 configNr, u32 medium, u32 speed);
@@ -338,6 +258,7 @@ int rndis_rm_hdr (struct sk_buff *skb);
 u8   *rndis_get_next_response (int configNr, u32 *length);
 void rndis_free_response (int configNr, u8 *buf);
 
+void rndis_uninit (int configNr);
 int  rndis_signal_connect (int configNr);
 int  rndis_signal_disconnect (int configNr);
 int  rndis_state (int configNr);
diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c
--- a/drivers/usb/gadget/serial.c
+++ b/drivers/usb/gadget/serial.c
@@ -300,18 +300,18 @@ static int gs_build_config_buf(u8 *buf, 
 		u8 type, unsigned int index, int is_otg);
 
 static struct usb_request *gs_alloc_req(struct usb_ep *ep, unsigned int len,
-	int kmalloc_flags);
+	unsigned kmalloc_flags);
 static void gs_free_req(struct usb_ep *ep, struct usb_request *req);
 
 static struct gs_req_entry *gs_alloc_req_entry(struct usb_ep *ep, unsigned len,
-	int kmalloc_flags);
+	unsigned kmalloc_flags);
 static void gs_free_req_entry(struct usb_ep *ep, struct gs_req_entry *req);
 
-static int gs_alloc_ports(struct gs_dev *dev, int kmalloc_flags);
+static int gs_alloc_ports(struct gs_dev *dev, unsigned kmalloc_flags);
 static void gs_free_ports(struct gs_dev *dev);
 
 /* circular buffer */
-static struct gs_buf *gs_buf_alloc(unsigned int size, int kmalloc_flags);
+static struct gs_buf *gs_buf_alloc(unsigned int size, unsigned kmalloc_flags);
 static void gs_buf_free(struct gs_buf *gb);
 static void gs_buf_clear(struct gs_buf *gb);
 static unsigned int gs_buf_data_avail(struct gs_buf *gb);
@@ -1607,9 +1607,9 @@ static int gs_setup(struct usb_gadget *g
 	int ret = -EOPNOTSUPP;
 	struct gs_dev *dev = get_gadget_data(gadget);
 	struct usb_request *req = dev->dev_ctrl_req;
-	u16 wIndex = ctrl->wIndex;
-	u16 wValue = ctrl->wValue;
-	u16 wLength = ctrl->wLength;
+	u16 wIndex = le16_to_cpu(ctrl->wIndex);
+	u16 wValue = le16_to_cpu(ctrl->wValue);
+	u16 wLength = le16_to_cpu(ctrl->wLength);
 
 	switch (ctrl->bRequestType & USB_TYPE_MASK) {
 	case USB_TYPE_STANDARD:
@@ -1651,9 +1651,9 @@ static int gs_setup_standard(struct usb_
 	int ret = -EOPNOTSUPP;
 	struct gs_dev *dev = get_gadget_data(gadget);
 	struct usb_request *req = dev->dev_ctrl_req;
-	u16 wIndex = ctrl->wIndex;
-	u16 wValue = ctrl->wValue;
-	u16 wLength = ctrl->wLength;
+	u16 wIndex = le16_to_cpu(ctrl->wIndex);
+	u16 wValue = le16_to_cpu(ctrl->wValue);
+	u16 wLength = le16_to_cpu(ctrl->wLength);
 
 	switch (ctrl->bRequest) {
 	case USB_REQ_GET_DESCRIPTOR:
@@ -1782,9 +1782,9 @@ static int gs_setup_class(struct usb_gad
 	struct gs_dev *dev = get_gadget_data(gadget);
 	struct gs_port *port = dev->dev_port[0];	/* ACM only has one port */
 	struct usb_request *req = dev->dev_ctrl_req;
-	u16 wIndex = ctrl->wIndex;
-	u16 wValue = ctrl->wValue;
-	u16 wLength = ctrl->wLength;
+	u16 wIndex = le16_to_cpu(ctrl->wIndex);
+	u16 wValue = le16_to_cpu(ctrl->wValue);
+	u16 wLength = le16_to_cpu(ctrl->wLength);
 
 	switch (ctrl->bRequest) {
 	case USB_CDC_REQ_SET_LINE_CODING:
@@ -2119,7 +2119,8 @@ static int gs_build_config_buf(u8 *buf, 
  * Allocate a usb_request and its buffer.  Returns a pointer to the
  * usb_request or NULL if there is an error.
  */
-static struct usb_request *gs_alloc_req(struct usb_ep *ep, unsigned int len, int kmalloc_flags)
+static struct usb_request *
+gs_alloc_req(struct usb_ep *ep, unsigned int len, unsigned kmalloc_flags)
 {
 	struct usb_request *req;
 
@@ -2159,7 +2160,8 @@ static void gs_free_req(struct usb_ep *e
  * Allocates a request and its buffer, using the given
  * endpoint, buffer len, and kmalloc flags.
  */
-static struct gs_req_entry *gs_alloc_req_entry(struct usb_ep *ep, unsigned len, int kmalloc_flags)
+static struct gs_req_entry *
+gs_alloc_req_entry(struct usb_ep *ep, unsigned len, unsigned kmalloc_flags)
 {
 	struct gs_req_entry	*req;
 
@@ -2200,7 +2202,7 @@ static void gs_free_req_entry(struct usb
  *
  * The device lock is normally held when calling this function.
  */
-static int gs_alloc_ports(struct gs_dev *dev, int kmalloc_flags)
+static int gs_alloc_ports(struct gs_dev *dev, unsigned kmalloc_flags)
 {
 	int i;
 	struct gs_port *port;
@@ -2282,7 +2284,7 @@ static void gs_free_ports(struct gs_dev 
  *
  * Allocate a circular buffer and all associated memory.
  */
-static struct gs_buf *gs_buf_alloc(unsigned int size, int kmalloc_flags)
+static struct gs_buf *gs_buf_alloc(unsigned int size, unsigned kmalloc_flags)
 {
 	struct gs_buf *gb;
 
diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c
--- a/drivers/usb/gadget/zero.c
+++ b/drivers/usb/gadget/zero.c
@@ -612,7 +612,7 @@ static void source_sink_complete (struct
 }
 
 static struct usb_request *
-source_sink_start_ep (struct usb_ep *ep, int gfp_flags)
+source_sink_start_ep (struct usb_ep *ep, unsigned gfp_flags)
 {
 	struct usb_request	*req;
 	int			status;
@@ -640,7 +640,7 @@ source_sink_start_ep (struct usb_ep *ep,
 }
 
 static int
-set_source_sink_config (struct zero_dev *dev, int gfp_flags)
+set_source_sink_config (struct zero_dev *dev, unsigned gfp_flags)
 {
 	int			result = 0;
 	struct usb_ep		*ep;
@@ -744,7 +744,7 @@ static void loopback_complete (struct us
 }
 
 static int
-set_loopback_config (struct zero_dev *dev, int gfp_flags)
+set_loopback_config (struct zero_dev *dev, unsigned gfp_flags)
 {
 	int			result = 0;
 	struct usb_ep		*ep;
@@ -845,7 +845,7 @@ static void zero_reset_config (struct ze
  * by limiting configuration choices (like the pxa2xx).
  */
 static int
-zero_set_config (struct zero_dev *dev, unsigned number, int gfp_flags)
+zero_set_config (struct zero_dev *dev, unsigned number, unsigned gfp_flags)
 {
 	int			result = 0;
 	struct usb_gadget	*gadget = dev->gadget;
@@ -919,9 +919,9 @@ zero_setup (struct usb_gadget *gadget, c
 	struct zero_dev		*dev = get_gadget_data (gadget);
 	struct usb_request	*req = dev->req;
 	int			value = -EOPNOTSUPP;
-	u16			w_index = ctrl->wIndex;
-	u16			w_value = ctrl->wValue;
-	u16			w_length = ctrl->wLength;
+	u16			w_index = le16_to_cpu(ctrl->wIndex);
+	u16			w_value = le16_to_cpu(ctrl->wValue);
+	u16			w_length = le16_to_cpu(ctrl->wLength);
 
 	/* usually this stores reply data in the pre-allocated ep0 buffer,
 	 * but config change events will reconfigure hardware.
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -49,6 +49,19 @@ config USB_EHCI_ROOT_HUB_TT
 
 	  This supports the EHCI implementation from TransDimension Inc.
 
+config USB_ISP116X_HCD
+	tristate "ISP116X HCD support"
+	depends on USB
+	default N
+	---help---
+	  The ISP1160 and ISP1161 chips are USB host controllers. Enable this
+	  option if your board has this chip. If unsure, say N.
+
+	  This driver does not support isochronous transfers.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called isp116x-hcd.
+
 config USB_OHCI_HCD
 	tristate "OHCI HCD support"
 	depends on USB && USB_ARCH_HAS_OHCI
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -4,6 +4,7 @@
 #
 
 obj-$(CONFIG_USB_EHCI_HCD)	+= ehci-hcd.o
+obj-$(CONFIG_USB_ISP116X_HCD)	+= isp116x-hcd.o
 obj-$(CONFIG_USB_OHCI_HCD)	+= ohci-hcd.o
 obj-$(CONFIG_USB_UHCI_HCD)	+= uhci-hcd.o
 obj-$(CONFIG_USB_SL811_HCD)	+= sl811-hcd.o
diff --git a/drivers/usb/host/ehci-dbg.c b/drivers/usb/host/ehci-dbg.c
--- a/drivers/usb/host/ehci-dbg.c
+++ b/drivers/usb/host/ehci-dbg.c
@@ -254,7 +254,7 @@ dbg_port_buf (char *buf, unsigned len, c
 	}
 
 	return scnprintf (buf, len,
-		"%s%sport %d status %06x%s%s sig=%s %s%s%s%s%s%s%s%s%s",
+		"%s%sport %d status %06x%s%s sig=%s%s%s%s%s%s%s%s%s%s",
 		label, label [0] ? " " : "", port, status,
 		(status & PORT_POWER) ? " POWER" : "",
 		(status & PORT_OWNER) ? " OWNER" : "",
@@ -450,7 +450,7 @@ show_async (struct class_device *class_d
 
 	*buf = 0;
 
-	bus = to_usb_bus(class_dev);
+	bus = class_get_devdata(class_dev);
 	hcd = bus->hcpriv;
 	ehci = hcd_to_ehci (hcd);
 	next = buf;
@@ -496,7 +496,7 @@ show_periodic (struct class_device *clas
 		return 0;
 	seen_count = 0;
 
-	bus = to_usb_bus(class_dev);
+	bus = class_get_devdata(class_dev);
 	hcd = bus->hcpriv;
 	ehci = hcd_to_ehci (hcd);
 	next = buf;
@@ -527,7 +527,7 @@ show_periodic (struct class_device *clas
 						p.qh->period,
 						le32_to_cpup (&p.qh->hw_info2)
 							/* uframe masks */
-							& 0xffff,
+							& (QH_CMASK | QH_SMASK),
 						p.qh);
 				size -= temp;
 				next += temp;
@@ -633,7 +633,7 @@ show_registers (struct class_device *cla
 	static char		fmt [] = "%*s\n";
 	static char		label [] = "";
 
-	bus = to_usb_bus(class_dev);
+	bus = class_get_devdata(class_dev);
 	hcd = bus->hcpriv;
 	ehci = hcd_to_ehci (hcd);
 	next = buf;
@@ -644,9 +644,11 @@ show_registers (struct class_device *cla
 	if (bus->controller->power.power_state) {
 		size = scnprintf (next, size,
 			"bus %s, device %s (driver " DRIVER_VERSION ")\n"
+			"%s\n"
 			"SUSPENDED (no register access)\n",
 			hcd->self.controller->bus->name,
-			hcd->self.controller->bus_id);
+			hcd->self.controller->bus_id,
+			hcd->product_desc);
 		goto done;
 	}
 
@@ -654,13 +656,53 @@ show_registers (struct class_device *cla
 	i = HC_VERSION(readl (&ehci->caps->hc_capbase));
 	temp = scnprintf (next, size,
 		"bus %s, device %s (driver " DRIVER_VERSION ")\n"
+		"%s\n"
 		"EHCI %x.%02x, hcd state %d\n",
 		hcd->self.controller->bus->name,
 		hcd->self.controller->bus_id,
+		hcd->product_desc,
 		i >> 8, i & 0x0ff, hcd->state);
 	size -= temp;
 	next += temp;
 
+#ifdef	CONFIG_PCI
+	/* EHCI 0.96 and later may have "extended capabilities" */
+	if (hcd->self.controller->bus == &pci_bus_type) {
+		struct pci_dev	*pdev;
+		u32		offset, cap, cap2;
+		unsigned	count = 256/4;
+
+		pdev = to_pci_dev(ehci_to_hcd(ehci)->self.controller);
+		offset = HCC_EXT_CAPS (readl (&ehci->caps->hcc_params));
+		while (offset && count--) {
+			pci_read_config_dword (pdev, offset, &cap);
+			switch (cap & 0xff) {
+			case 1:
+				temp = scnprintf (next, size,
+					"ownership %08x%s%s\n", cap,
+					(cap & (1 << 24)) ? " linux" : "",
+					(cap & (1 << 16)) ? " firmware" : "");
+				size -= temp;
+				next += temp;
+
+				offset += 4;
+				pci_read_config_dword (pdev, offset, &cap2);
+				temp = scnprintf (next, size,
+					"SMI sts/enable 0x%08x\n", cap2);
+				size -= temp;
+				next += temp;
+				break;
+			case 0:		/* illegal reserved capability */
+				cap = 0;
+				/* FALLTHROUGH */
+			default:		/* unknown */
+				break;
+			}
+			temp = (cap >> 8) & 0xff;
+		}
+	}
+#endif
+
 	// FIXME interpret both types of params
 	i = readl (&ehci->caps->hcs_params);
 	temp = scnprintf (next, size, "structural params 0x%08x\n", i);
@@ -696,12 +738,19 @@ show_registers (struct class_device *cla
 	size -= temp;
 	next += temp;
 
-	for (i = 0; i < HCS_N_PORTS (ehci->hcs_params); i++) {
-		temp = dbg_port_buf (scratch, sizeof scratch, label, i + 1,
-				readl (&ehci->regs->port_status [i]));
+	for (i = 1; i <= HCS_N_PORTS (ehci->hcs_params); i++) {
+		temp = dbg_port_buf (scratch, sizeof scratch, label, i,
+				readl (&ehci->regs->port_status [i - 1]));
 		temp = scnprintf (next, size, fmt, temp, scratch);
 		size -= temp;
 		next += temp;
+		if (i == HCS_DEBUG_PORT(ehci->hcs_params) && ehci->debug) {
+			temp = scnprintf (next, size,
+					"    debug control %08x\n",
+					readl (&ehci->debug->control));
+			size -= temp;
+			next += temp;
+		}
 	}
 
 	if (ehci->reclaim) {
@@ -735,7 +784,7 @@ static CLASS_DEVICE_ATTR (registers, S_I
 
 static inline void create_debug_files (struct ehci_hcd *ehci)
 {
-	struct class_device *cldev = &ehci_to_hcd(ehci)->self.class_dev;
+	struct class_device *cldev = ehci_to_hcd(ehci)->self.class_dev;
 
 	class_device_create_file(cldev, &class_device_attr_async);
 	class_device_create_file(cldev, &class_device_attr_periodic);
@@ -744,7 +793,7 @@ static inline void create_debug_files (s
 
 static inline void remove_debug_files (struct ehci_hcd *ehci)
 {
-	struct class_device *cldev = &ehci_to_hcd(ehci)->self.class_dev;
+	struct class_device *cldev = ehci_to_hcd(ehci)->self.class_dev;
 
 	class_device_remove_file(cldev, &class_device_attr_async);
 	class_device_remove_file(cldev, &class_device_attr_periodic);
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -304,30 +304,31 @@ static void ehci_watchdog (unsigned long
  */
 static int bios_handoff (struct ehci_hcd *ehci, int where, u32 cap)
 {
+	struct pci_dev *pdev = to_pci_dev(ehci_to_hcd(ehci)->self.controller);
+
+	/* always say Linux will own the hardware */
+	pci_write_config_byte(pdev, where + 3, 1);
+
+	/* maybe wait a while for BIOS to respond */
 	if (cap & (1 << 16)) {
 		int msec = 5000;
-		struct pci_dev *pdev =
-				to_pci_dev(ehci_to_hcd(ehci)->self.controller);
-
-		/* request handoff to OS */
-		cap |= 1 << 24;
-		pci_write_config_dword(pdev, where, cap);
 
-		/* and wait a while for it to happen */
 		do {
 			msleep(10);
 			msec -= 10;
 			pci_read_config_dword(pdev, where, &cap);
 		} while ((cap & (1 << 16)) && msec);
 		if (cap & (1 << 16)) {
-			ehci_err (ehci, "BIOS handoff failed (%d, %04x)\n",
+			ehci_err(ehci, "BIOS handoff failed (%d, %08x)\n",
 				where, cap);
 			// some BIOS versions seem buggy...
 			// return 1;
 			ehci_warn (ehci, "continuing after BIOS bug...\n");
-			return 0;
-		} 
-		ehci_dbg (ehci, "BIOS handoff succeeded\n");
+			/* disable all SMIs, and clear "BIOS owns" flag */
+			pci_write_config_dword(pdev, where + 4, 0);
+			pci_write_config_byte(pdev, where + 2, 0);
+		} else
+			ehci_dbg(ehci, "BIOS handoff succeeded\n");
 	}
 	return 0;
 }
@@ -492,8 +493,6 @@ static int ehci_start (struct usb_hcd *h
 {
 	struct ehci_hcd		*ehci = hcd_to_ehci (hcd);
 	u32			temp;
-	struct usb_device	*udev;
-	struct usb_bus		*bus;
 	int			retval;
 	u32			hcc_params;
 	u8                      sbrn = 0;
@@ -588,8 +587,8 @@ static int ehci_start (struct usb_hcd *h
 		writel (0, &ehci->regs->segment);
 #if 0
 // this is deeply broken on almost all architectures
-		if (!pci_set_dma_mask (to_pci_dev(hcd->self.controller), 0xffffffffffffffffULL))
-			ehci_info (ehci, "enabled 64bit PCI DMA\n");
+		if (!dma_set_mask (hcd->self.controller, DMA_64BIT_MASK))
+			ehci_info (ehci, "enabled 64bit DMA\n");
 #endif
 	}
 
@@ -631,17 +630,6 @@ static int ehci_start (struct usb_hcd *h
 
 	/* set async sleep time = 10 us ... ? */
 
-	/* wire up the root hub */
-	bus = hcd_to_bus (hcd);
-	udev = first ? usb_alloc_dev (NULL, bus, 0) : bus->root_hub;
-	if (!udev) {
-done2:
-		ehci_mem_cleanup (ehci);
-		return -ENOMEM;
-	}
-	udev->speed = USB_SPEED_HIGH;
-	udev->state = first ? USB_STATE_ATTACHED : USB_STATE_CONFIGURED;
-
 	/*
 	 * Start, enabling full USB 2.0 functionality ... usb 1.1 devices
 	 * are explicitly handed to companion controller(s), so no TT is
@@ -664,24 +652,6 @@ done2:
 		first ? "initialized" : "restarted",
 		temp >> 8, temp & 0xff, DRIVER_VERSION);
 
-	/*
-	 * From here on, khubd concurrently accesses the root
-	 * hub; drivers will be talking to enumerated devices.
-	 * (On restart paths, khubd already knows about the root
-	 * hub and could find work as soon as we wrote FLAG_CF.)
-	 *
-	 * Before this point the HC was idle/ready.  After, khubd
-	 * and device drivers may start it running.
-	 */
-	if (first && usb_hcd_register_root_hub (udev, hcd) != 0) {
-		if (hcd->state == HC_STATE_RUNNING)
-			ehci_quiesce (ehci);
-		ehci_reset (ehci);
-		usb_put_dev (udev); 
-		retval = -ENODEV;
-		goto done2;
-	}
-
 	writel (INTR_MASK, &ehci->regs->intr_enable); /* Turn On Interrupts */
 
 	if (first)
@@ -990,7 +960,7 @@ static int ehci_urb_enqueue (
 	struct usb_hcd	*hcd,
 	struct usb_host_endpoint *ep,
 	struct urb	*urb,
-	int		mem_flags
+	unsigned	mem_flags
 ) {
 	struct ehci_hcd		*ehci = hcd_to_ehci (hcd);
 	struct list_head	qtd_list;
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
--- a/drivers/usb/host/ehci-hub.c
+++ b/drivers/usb/host/ehci-hub.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001-2002 by David Brownell
+ * Copyright (C) 2001-2004 by David Brownell
  * 
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c
--- a/drivers/usb/host/ehci-q.c
+++ b/drivers/usb/host/ehci-q.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001-2002 by David Brownell
+ * Copyright (C) 2001-2004 by David Brownell
  * 
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the
@@ -222,7 +222,7 @@ __acquires(ehci->lock)
 		struct ehci_qh	*qh = (struct ehci_qh *) urb->hcpriv;
 
 		/* S-mask in a QH means it's an interrupt urb */
-		if ((qh->hw_info2 & __constant_cpu_to_le32 (0x00ff)) != 0) {
+		if ((qh->hw_info2 & __constant_cpu_to_le32 (QH_SMASK)) != 0) {
 
 			/* ... update hc-wide periodic stats (for usbfs) */
 			ehci_to_hcd(ehci)->self.bandwidth_int_reqs--;
@@ -428,7 +428,8 @@ halt:
 			/* should be rare for periodic transfers,
 			 * except maybe high bandwidth ...
 			 */
-			if (qh->period) {
+			if ((__constant_cpu_to_le32 (QH_SMASK)
+					& qh->hw_info2) != 0) {
 				intr_deschedule (ehci, qh);
 				(void) qh_schedule (ehci, qh);
 			} else
@@ -657,8 +658,8 @@ qh_make (
 	 * For control/bulk requests, the HC or TT handles these.
 	 */
 	if (type == PIPE_INTERRUPT) {
-		qh->usecs = usb_calc_bus_time (USB_SPEED_HIGH, is_input, 0,
-				hb_mult (maxp) * max_packet (maxp));
+		qh->usecs = NS_TO_US (usb_calc_bus_time (USB_SPEED_HIGH, is_input, 0,
+				hb_mult (maxp) * max_packet (maxp)));
 		qh->start = NO_FRAME;
 
 		if (urb->dev->speed == USB_SPEED_HIGH) {
@@ -898,7 +899,7 @@ submit_async (
 	struct usb_host_endpoint *ep,
 	struct urb		*urb,
 	struct list_head	*qtd_list,
-	int			mem_flags
+	unsigned		mem_flags
 ) {
 	struct ehci_qtd		*qtd;
 	int			epnum;
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
--- a/drivers/usb/host/ehci-sched.c
+++ b/drivers/usb/host/ehci-sched.c
@@ -301,7 +301,7 @@ static int qh_link_periodic (struct ehci
 
 	dev_dbg (&qh->dev->dev,
 		"link qh%d-%04x/%p start %d [%d/%d us]\n",
-		period, le32_to_cpup (&qh->hw_info2) & 0xffff,
+		period, le32_to_cpup (&qh->hw_info2) & (QH_CMASK | QH_SMASK),
 		qh, qh->start, qh->usecs, qh->c_usecs);
 
 	/* high bandwidth, or otherwise every microframe */
@@ -385,7 +385,8 @@ static void qh_unlink_periodic (struct e
 
 	dev_dbg (&qh->dev->dev,
 		"unlink qh%d-%04x/%p start %d [%d/%d us]\n",
-		qh->period, le32_to_cpup (&qh->hw_info2) & 0xffff,
+		qh->period,
+		le32_to_cpup (&qh->hw_info2) & (QH_CMASK | QH_SMASK),
 		qh, qh->start, qh->usecs, qh->c_usecs);
 
 	/* qh->qh_next still "live" to HC */
@@ -411,7 +412,7 @@ static void intr_deschedule (struct ehci
 	 * active high speed queues may need bigger delays...
 	 */
 	if (list_empty (&qh->qtd_list)
-			|| (__constant_cpu_to_le32 (0x0ff << 8)
+			|| (__constant_cpu_to_le32 (QH_CMASK)
 					& qh->hw_info2) != 0)
 		wait = 2;
 	else
@@ -533,7 +534,7 @@ static int qh_schedule (struct ehci_hcd 
 
 	/* reuse the previous schedule slots, if we can */
 	if (frame < qh->period) {
-		uframe = ffs (le32_to_cpup (&qh->hw_info2) & 0x00ff);
+		uframe = ffs (le32_to_cpup (&qh->hw_info2) & QH_SMASK);
 		status = check_intr_schedule (ehci, frame, --uframe,
 				qh, &c_mask);
 	} else {
@@ -569,10 +570,10 @@ static int qh_schedule (struct ehci_hcd 
 		qh->start = frame;
 
 		/* reset S-frame and (maybe) C-frame masks */
-		qh->hw_info2 &= __constant_cpu_to_le32 (~0xffff);
+		qh->hw_info2 &= __constant_cpu_to_le32(~(QH_CMASK | QH_SMASK));
 		qh->hw_info2 |= qh->period
 			? cpu_to_le32 (1 << uframe)
-			: __constant_cpu_to_le32 (0xff);
+			: __constant_cpu_to_le32 (QH_SMASK);
 		qh->hw_info2 |= c_mask;
 	} else
 		ehci_dbg (ehci, "reused qh %p schedule\n", qh);
@@ -588,7 +589,7 @@ static int intr_submit (
 	struct usb_host_endpoint *ep,
 	struct urb		*urb,
 	struct list_head	*qtd_list,
-	int			mem_flags
+	unsigned		mem_flags
 ) {
 	unsigned		epnum;
 	unsigned long		flags;
@@ -633,13 +634,12 @@ done:
 /* ehci_iso_stream ops work with both ITD and SITD */
 
 static struct ehci_iso_stream *
-iso_stream_alloc (int mem_flags)
+iso_stream_alloc (unsigned mem_flags)
 {
 	struct ehci_iso_stream *stream;
 
-	stream = kmalloc(sizeof *stream, mem_flags);
+	stream = kcalloc(1, sizeof *stream, mem_flags);
 	if (likely (stream != NULL)) {
-		memset (stream, 0, sizeof(*stream));
 		INIT_LIST_HEAD(&stream->td_list);
 		INIT_LIST_HEAD(&stream->free_list);
 		stream->next_uframe = -1;
@@ -847,7 +847,7 @@ iso_stream_find (struct ehci_hcd *ehci, 
 /* ehci_iso_sched ops can be ITD-only or SITD-only */
 
 static struct ehci_iso_sched *
-iso_sched_alloc (unsigned packets, int mem_flags)
+iso_sched_alloc (unsigned packets, unsigned mem_flags)
 {
 	struct ehci_iso_sched	*iso_sched;
 	int			size = sizeof *iso_sched;
@@ -894,7 +894,7 @@ itd_sched_init (
 		trans |= length << 16;
 		uframe->transaction = cpu_to_le32 (trans);
 
-		/* might need to cross a buffer page within a td */
+		/* might need to cross a buffer page within a uframe */
 		uframe->bufp = (buf & ~(u64)0x0fff);
 		buf += length;
 		if (unlikely ((uframe->bufp != (buf & ~(u64)0x0fff))))
@@ -920,7 +920,7 @@ itd_urb_transaction (
 	struct ehci_iso_stream	*stream,
 	struct ehci_hcd		*ehci,
 	struct urb		*urb,
-	int			mem_flags
+	unsigned		mem_flags
 )
 {
 	struct ehci_itd		*itd;
@@ -1194,6 +1194,7 @@ itd_init (struct ehci_iso_stream *stream
 {
 	int i;
 
+	/* it's been recently zeroed */
 	itd->hw_next = EHCI_LIST_END;
 	itd->hw_bufp [0] = stream->buf0;
 	itd->hw_bufp [1] = stream->buf1;
@@ -1210,8 +1211,7 @@ itd_patch (
 	struct ehci_itd		*itd,
 	struct ehci_iso_sched	*iso_sched,
 	unsigned		index,
-	u16			uframe,
-	int			first
+	u16			uframe
 )
 {
 	struct ehci_iso_packet	*uf = &iso_sched->packet [index];
@@ -1228,7 +1228,7 @@ itd_patch (
 	itd->hw_bufp_hi [pg] |= cpu_to_le32 ((u32)(uf->bufp >> 32));
 
 	/* iso_frame_desc[].offset must be strictly increasing */
-	if (unlikely (!first && uf->cross)) {
+	if (unlikely (uf->cross)) {
 		u64	bufp = uf->bufp + 4096;
 		itd->pg = ++pg;
 		itd->hw_bufp [pg] |= cpu_to_le32 (bufp & ~(u32)0);
@@ -1257,7 +1257,7 @@ itd_link_urb (
 	struct ehci_iso_stream	*stream
 )
 {
-	int			packet, first = 1;
+	int			packet;
 	unsigned		next_uframe, uframe, frame;
 	struct ehci_iso_sched	*iso_sched = urb->hcpriv;
 	struct ehci_itd		*itd;
@@ -1290,7 +1290,6 @@ itd_link_urb (
 			list_move_tail (&itd->itd_list, &stream->td_list);
 			itd->stream = iso_stream_get (stream);
 			itd->urb = usb_get_urb (urb);
-			first = 1;
 			itd_init (stream, itd);
 		}
 
@@ -1298,8 +1297,7 @@ itd_link_urb (
 		frame = next_uframe >> 3;
 
 		itd->usecs [uframe] = stream->usecs;
-		itd_patch (itd, iso_sched, packet, uframe, first);
-		first = 0;
+		itd_patch (itd, iso_sched, packet, uframe);
 
 		next_uframe += stream->interval;
 		stream->depth += stream->interval;
@@ -1415,7 +1413,8 @@ itd_complete (
 
 /*-------------------------------------------------------------------------*/
 
-static int itd_submit (struct ehci_hcd *ehci, struct urb *urb, int mem_flags)
+static int itd_submit (struct ehci_hcd *ehci, struct urb *urb,
+	unsigned mem_flags)
 {
 	int			status = -EINVAL;
 	unsigned long		flags;
@@ -1526,7 +1525,7 @@ sitd_urb_transaction (
 	struct ehci_iso_stream	*stream,
 	struct ehci_hcd		*ehci,
 	struct urb		*urb,
-	int			mem_flags
+	unsigned		mem_flags
 )
 {
 	struct ehci_sitd	*sitd;
@@ -1775,7 +1774,8 @@ sitd_complete (
 }
 
 
-static int sitd_submit (struct ehci_hcd *ehci, struct urb *urb, int mem_flags)
+static int sitd_submit (struct ehci_hcd *ehci, struct urb *urb,
+	unsigned mem_flags)
 {
 	int			status = -EINVAL;
 	unsigned long		flags;
@@ -1825,7 +1825,8 @@ done:
 #else
 
 static inline int
-sitd_submit (struct ehci_hcd *ehci, struct urb *urb, int mem_flags)
+sitd_submit (struct ehci_hcd *ehci, struct urb *urb,
+	unsigned mem_flags)
 {
 	ehci_dbg (ehci, "split iso support is disabled\n");
 	return -ENOSYS;
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -385,6 +385,11 @@ struct ehci_qh {
 	__le32			hw_info1;        /* see EHCI 3.6.2 */
 #define	QH_HEAD		0x00008000
 	__le32			hw_info2;        /* see EHCI 3.6.2 */
+#define	QH_SMASK	0x000000ff
+#define	QH_CMASK	0x0000ff00
+#define	QH_HUBADDR	0x007f0000
+#define	QH_HUBPORT	0x3f800000
+#define	QH_MULT		0xc0000000
 	__le32			hw_current;	 /* qtd list - see EHCI 3.6.4 */
 	
 	/* qtd overlay (hardware parts of a struct ehci_qtd) */
diff --git a/drivers/usb/host/hc_crisv10.c b/drivers/usb/host/hc_crisv10.c
--- a/drivers/usb/host/hc_crisv10.c
+++ b/drivers/usb/host/hc_crisv10.c
@@ -463,7 +463,8 @@ static void etrax_usb_free_epid(int epid
 
 static int etrax_remove_from_sb_list(struct urb *urb);
 
-static void* etrax_usb_buffer_alloc(struct usb_bus* bus, size_t size, int mem_flags, dma_addr_t *dma);
+static void* etrax_usb_buffer_alloc(struct usb_bus* bus, size_t size,
+	unsigned mem_flags, dma_addr_t *dma);
 static void etrax_usb_buffer_free(struct usb_bus *bus, size_t size, void *addr, dma_addr_t dma);
 
 static void etrax_usb_add_to_bulk_sb_list(struct urb *urb, int epid);
@@ -476,7 +477,7 @@ static int etrax_usb_submit_ctrl_urb(str
 static int etrax_usb_submit_intr_urb(struct urb *urb);
 static int etrax_usb_submit_isoc_urb(struct urb *urb);
 
-static int etrax_usb_submit_urb(struct urb *urb, int mem_flags);
+static int etrax_usb_submit_urb(struct urb *urb, unsigned mem_flags);
 static int etrax_usb_unlink_urb(struct urb *urb, int status);
 static int etrax_usb_get_frame_number(struct usb_device *usb_dev);
 
@@ -1262,7 +1263,7 @@ static int etrax_usb_allocate_epid(void)
 	return -1;
 }
 
-static int etrax_usb_submit_urb(struct urb *urb, int mem_flags)
+static int etrax_usb_submit_urb(struct urb *urb, unsigned mem_flags)
 {
 	etrax_hc_t *hc;
 	int ret = -EINVAL;
@@ -4277,7 +4278,8 @@ etrax_usb_bulk_eot_timer_func(unsigned l
 }
 
 static void*
-etrax_usb_buffer_alloc(struct usb_bus* bus, size_t size, int mem_flags, dma_addr_t *dma)
+etrax_usb_buffer_alloc(struct usb_bus* bus, size_t size,
+	unsigned mem_flags, dma_addr_t *dma)
 {
   return kmalloc(size, mem_flags);
 }
diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c
new file mode 100644
--- /dev/null
+++ b/drivers/usb/host/isp116x-hcd.c
@@ -0,0 +1,1873 @@
+/*
+ * ISP116x HCD (Host Controller Driver) for USB.
+ *
+ * Derived from the SL811 HCD, rewritten for ISP116x.
+ * Copyright (C) 2005 Olav Kongas <ok@artecdesign.ee>
+ *
+ * Portions:
+ * Copyright (C) 2004 Psion Teklogix (for NetBook PRO)
+ * Copyright (C) 2004 David Brownell
+ *
+ * Periodic scheduling is based on Roman's OHCI code
+ * Copyright (C) 1999 Roman Weissgaerber
+ *
+ */
+
+/*
+ * The driver basically works. A number of people have used it with a range
+ * of devices.
+ *
+ * The driver passes all usbtests 1-14.
+ *
+ * Suspending/resuming of root hub via sysfs works. Remote wakeup works too.
+ * And suspending/resuming of platform device works too. Suspend/resume
+ * via HCD operations vector is not implemented.
+ *
+ * Iso transfer support is not implemented. Adding this would include
+ * implementing recovery from the failure to service the processed ITL
+ * fifo ram in time, which will involve chip reset.
+ *
+ * TODO:
+ + More testing of suspend/resume.
+*/
+
+/*
+  ISP116x chips require certain delays between accesses to its
+  registers. The following timing options exist.
+
+  1. Configure your memory controller (the best)
+  2. Implement platform-specific delay function possibly
+  combined with configuring the memory controller; see
+  include/linux/usb-isp116x.h for more info. Some broken
+  memory controllers line LH7A400 SMC need this. Also,
+  uncomment for that to work the following
+  USE_PLATFORM_DELAY macro.
+  3. Use ndelay (easiest, poorest). For that, uncomment
+  the following USE_NDELAY macro.
+*/
+#define USE_PLATFORM_DELAY
+//#define USE_NDELAY
+
+//#define DEBUG
+//#define VERBOSE
+/* Transfer descriptors. See dump_ptd() for printout format  */
+//#define PTD_TRACE
+/* enqueuing/finishing log of urbs */
+//#define URB_TRACE
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/ioport.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/smp_lock.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/interrupt.h>
+#include <linux/usb.h>
+#include <linux/usb_isp116x.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/byteorder.h>
+
+#ifndef DEBUG
+#	define	STUB_DEBUG_FILE
+#endif
+
+#include "../core/hcd.h"
+#include "isp116x.h"
+
+#define DRIVER_VERSION	"08 Apr 2005"
+#define DRIVER_DESC	"ISP116x USB Host Controller Driver"
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+
+static const char hcd_name[] = "isp116x-hcd";
+
+/*-----------------------------------------------------------------*/
+
+/*
+  Write len bytes to fifo, pad till 32-bit boundary
+ */
+static void write_ptddata_to_fifo(struct isp116x *isp116x, void *buf, int len)
+{
+	u8 *dp = (u8 *) buf;
+	u16 *dp2 = (u16 *) buf;
+	u16 w;
+	int quot = len % 4;
+
+	if ((unsigned long)dp2 & 1) {
+		/* not aligned */
+		for (; len > 1; len -= 2) {
+			w = *dp++;
+			w |= *dp++ << 8;
+			isp116x_raw_write_data16(isp116x, w);
+		}
+		if (len)
+			isp116x_write_data16(isp116x, (u16) * dp);
+	} else {
+		/* aligned */
+		for (; len > 1; len -= 2)
+			isp116x_raw_write_data16(isp116x, *dp2++);
+		if (len)
+			isp116x_write_data16(isp116x, 0xff & *((u8 *) dp2));
+	}
+	if (quot == 1 || quot == 2)
+		isp116x_raw_write_data16(isp116x, 0);
+}
+
+/*
+  Read len bytes from fifo and then read till 32-bit boundary.
+ */
+static void read_ptddata_from_fifo(struct isp116x *isp116x, void *buf, int len)
+{
+	u8 *dp = (u8 *) buf;
+	u16 *dp2 = (u16 *) buf;
+	u16 w;
+	int quot = len % 4;
+
+	if ((unsigned long)dp2 & 1) {
+		/* not aligned */
+		for (; len > 1; len -= 2) {
+			w = isp116x_raw_read_data16(isp116x);
+			*dp++ = w & 0xff;
+			*dp++ = (w >> 8) & 0xff;
+		}
+		if (len)
+			*dp = 0xff & isp116x_read_data16(isp116x);
+	} else {
+		/* aligned */
+		for (; len > 1; len -= 2)
+			*dp2++ = isp116x_raw_read_data16(isp116x);
+		if (len)
+			*(u8 *) dp2 = 0xff & isp116x_read_data16(isp116x);
+	}
+	if (quot == 1 || quot == 2)
+		isp116x_raw_read_data16(isp116x);
+}
+
+/*
+  Write ptd's and data for scheduled transfers into
+  the fifo ram. Fifo must be empty and ready.
+*/
+static void pack_fifo(struct isp116x *isp116x)
+{
+	struct isp116x_ep *ep;
+	struct ptd *ptd;
+	int buflen = isp116x->atl_last_dir == PTD_DIR_IN
+	    ? isp116x->atl_bufshrt : isp116x->atl_buflen;
+	int ptd_count = 0;
+
+	isp116x_write_reg16(isp116x, HCuPINT, HCuPINT_AIIEOT);
+	isp116x_write_reg16(isp116x, HCXFERCTR, buflen);
+	isp116x_write_addr(isp116x, HCATLPORT | ISP116x_WRITE_OFFSET);
+	for (ep = isp116x->atl_active; ep; ep = ep->active) {
+		++ptd_count;
+		ptd = &ep->ptd;
+		dump_ptd(ptd);
+		dump_ptd_out_data(ptd, ep->data);
+		isp116x_write_data16(isp116x, ptd->count);
+		isp116x_write_data16(isp116x, ptd->mps);
+		isp116x_write_data16(isp116x, ptd->len);
+		isp116x_write_data16(isp116x, ptd->faddr);
+		buflen -= sizeof(struct ptd);
+		/* Skip writing data for last IN PTD */
+		if (ep->active || (isp116x->atl_last_dir != PTD_DIR_IN)) {
+			write_ptddata_to_fifo(isp116x, ep->data, ep->length);
+			buflen -= ALIGN(ep->length, 4);
+		}
+	}
+	BUG_ON(buflen);
+}
+
+/*
+  Read the processed ptd's and data from fifo ram back to
+  URBs' buffers. Fifo must be full and done
+*/
+static void unpack_fifo(struct isp116x *isp116x)
+{
+	struct isp116x_ep *ep;
+	struct ptd *ptd;
+	int buflen = isp116x->atl_last_dir == PTD_DIR_IN
+	    ? isp116x->atl_buflen : isp116x->atl_bufshrt;
+
+	isp116x_write_reg16(isp116x, HCuPINT, HCuPINT_AIIEOT);
+	isp116x_write_reg16(isp116x, HCXFERCTR, buflen);
+	isp116x_write_addr(isp116x, HCATLPORT);
+	for (ep = isp116x->atl_active; ep; ep = ep->active) {
+		ptd = &ep->ptd;
+		ptd->count = isp116x_read_data16(isp116x);
+		ptd->mps = isp116x_read_data16(isp116x);
+		ptd->len = isp116x_read_data16(isp116x);
+		ptd->faddr = isp116x_read_data16(isp116x);
+		buflen -= sizeof(struct ptd);
+		/* Skip reading data for last Setup or Out PTD */
+		if (ep->active || (isp116x->atl_last_dir == PTD_DIR_IN)) {
+			read_ptddata_from_fifo(isp116x, ep->data, ep->length);
+			buflen -= ALIGN(ep->length, 4);
+		}
+		dump_ptd(ptd);
+		dump_ptd_in_data(ptd, ep->data);
+	}
+	BUG_ON(buflen);
+}
+
+/*---------------------------------------------------------------*/
+
+/*
+  Set up PTD's.
+*/
+static void preproc_atl_queue(struct isp116x *isp116x)
+{
+	struct isp116x_ep *ep;
+	struct urb *urb;
+	struct ptd *ptd;
+	u16 len;
+
+	for (ep = isp116x->atl_active; ep; ep = ep->active) {
+		u16 toggle = 0, dir = PTD_DIR_SETUP;
+
+		BUG_ON(list_empty(&ep->hep->urb_list));
+		urb = container_of(ep->hep->urb_list.next,
+				   struct urb, urb_list);
+		ptd = &ep->ptd;
+		len = ep->length;
+		spin_lock(&urb->lock);
+		ep->data = (unsigned char *)urb->transfer_buffer
+		    + urb->actual_length;
+
+		switch (ep->nextpid) {
+		case USB_PID_IN:
+			toggle = usb_gettoggle(urb->dev, ep->epnum, 0);
+			dir = PTD_DIR_IN;
+			break;
+		case USB_PID_OUT:
+			toggle = usb_gettoggle(urb->dev, ep->epnum, 1);
+			dir = PTD_DIR_OUT;
+			break;
+		case USB_PID_SETUP:
+			len = sizeof(struct usb_ctrlrequest);
+			ep->data = urb->setup_packet;
+			break;
+		case USB_PID_ACK:
+			toggle = 1;
+			len = 0;
+			dir = (urb->transfer_buffer_length
+			       && usb_pipein(urb->pipe))
+			    ? PTD_DIR_OUT : PTD_DIR_IN;
+			break;
+		default:
+			ERR("%s %d: ep->nextpid %d\n", __func__, __LINE__,
+			    ep->nextpid);
+			BUG();
+		}
+
+		ptd->count = PTD_CC_MSK | PTD_ACTIVE_MSK | PTD_TOGGLE(toggle);
+		ptd->mps = PTD_MPS(ep->maxpacket)
+		    | PTD_SPD(urb->dev->speed == USB_SPEED_LOW)
+		    | PTD_EP(ep->epnum);
+		ptd->len = PTD_LEN(len) | PTD_DIR(dir);
+		ptd->faddr = PTD_FA(usb_pipedevice(urb->pipe));
+		spin_unlock(&urb->lock);
+		if (!ep->active) {
+			ptd->mps |= PTD_LAST_MSK;
+			isp116x->atl_last_dir = dir;
+		}
+		isp116x->atl_bufshrt = sizeof(struct ptd) + isp116x->atl_buflen;
+		isp116x->atl_buflen = isp116x->atl_bufshrt + ALIGN(len, 4);
+	}
+}
+
+/*
+  Analyze transfer results, handle partial transfers and errors
+*/
+static void postproc_atl_queue(struct isp116x *isp116x)
+{
+	struct isp116x_ep *ep;
+	struct urb *urb;
+	struct usb_device *udev;
+	struct ptd *ptd;
+	int short_not_ok;
+	u8 cc;
+
+	for (ep = isp116x->atl_active; ep; ep = ep->active) {
+		BUG_ON(list_empty(&ep->hep->urb_list));
+		urb =
+		    container_of(ep->hep->urb_list.next, struct urb, urb_list);
+		udev = urb->dev;
+		ptd = &ep->ptd;
+		cc = PTD_GET_CC(ptd);
+
+		spin_lock(&urb->lock);
+		short_not_ok = 1;
+
+		/* Data underrun is special. For allowed underrun
+		   we clear the error and continue as normal. For
+		   forbidden underrun we finish the DATA stage
+		   immediately while for control transfer,
+		   we do a STATUS stage. */
+		if (cc == TD_DATAUNDERRUN) {
+			if (!(urb->transfer_flags & URB_SHORT_NOT_OK)) {
+				DBG("Allowed data underrun\n");
+				cc = TD_CC_NOERROR;
+				short_not_ok = 0;
+			} else {
+				ep->error_count = 1;
+				if (usb_pipecontrol(urb->pipe))
+					ep->nextpid = USB_PID_ACK;
+				else
+					usb_settoggle(udev, ep->epnum,
+						      ep->nextpid ==
+						      USB_PID_OUT,
+						      PTD_GET_TOGGLE(ptd) ^ 1);
+				urb->status = cc_to_error[TD_DATAUNDERRUN];
+				spin_unlock(&urb->lock);
+				continue;
+			}
+		}
+		/* Keep underrun error through the STATUS stage */
+		if (urb->status == cc_to_error[TD_DATAUNDERRUN])
+			cc = TD_DATAUNDERRUN;
+
+		if (cc != TD_CC_NOERROR && cc != TD_NOTACCESSED
+		    && (++ep->error_count >= 3 || cc == TD_CC_STALL
+			|| cc == TD_DATAOVERRUN)) {
+			if (urb->status == -EINPROGRESS)
+				urb->status = cc_to_error[cc];
+			if (ep->nextpid == USB_PID_ACK)
+				ep->nextpid = 0;
+			spin_unlock(&urb->lock);
+			continue;
+		}
+		/* According to usb spec, zero-length Int transfer signals
+		   finishing of the urb. Hey, does this apply only
+		   for IN endpoints? */
+		if (usb_pipeint(urb->pipe) && !PTD_GET_LEN(ptd)) {
+			if (urb->status == -EINPROGRESS)
+				urb->status = 0;
+			spin_unlock(&urb->lock);
+			continue;
+		}
+
+		/* Relax after previously failed, but later succeeded
+		   or correctly NAK'ed retransmission attempt */
+		if (ep->error_count
+		    && (cc == TD_CC_NOERROR || cc == TD_NOTACCESSED))
+			ep->error_count = 0;
+
+		/* Take into account idiosyncracies of the isp116x chip
+		   regarding toggle bit for failed transfers */
+		if (ep->nextpid == USB_PID_OUT)
+			usb_settoggle(udev, ep->epnum, 1, PTD_GET_TOGGLE(ptd)
+				      ^ (ep->error_count > 0));
+		else if (ep->nextpid == USB_PID_IN)
+			usb_settoggle(udev, ep->epnum, 0, PTD_GET_TOGGLE(ptd)
+				      ^ (ep->error_count > 0));
+
+		switch (ep->nextpid) {
+		case USB_PID_IN:
+		case USB_PID_OUT:
+			urb->actual_length += PTD_GET_COUNT(ptd);
+			if (PTD_GET_ACTIVE(ptd)
+			    || (cc != TD_CC_NOERROR && cc < 0x0E))
+				break;
+			if (urb->transfer_buffer_length != urb->actual_length) {
+				if (short_not_ok)
+					break;
+			} else {
+				if (urb->transfer_flags & URB_ZERO_PACKET
+				    && ep->nextpid == USB_PID_OUT
+				    && !(PTD_GET_COUNT(ptd) % ep->maxpacket)) {
+					DBG("Zero packet requested\n");
+					break;
+				}
+			}
+			/* All data for this URB is transferred, let's finish */
+			if (usb_pipecontrol(urb->pipe))
+				ep->nextpid = USB_PID_ACK;
+			else if (urb->status == -EINPROGRESS)
+				urb->status = 0;
+			break;
+		case USB_PID_SETUP:
+			if (PTD_GET_ACTIVE(ptd)
+			    || (cc != TD_CC_NOERROR && cc < 0x0E))
+				break;
+			if (urb->transfer_buffer_length == urb->actual_length)
+				ep->nextpid = USB_PID_ACK;
+			else if (usb_pipeout(urb->pipe)) {
+				usb_settoggle(udev, 0, 1, 1);
+				ep->nextpid = USB_PID_OUT;
+			} else {
+				usb_settoggle(udev, 0, 0, 1);
+				ep->nextpid = USB_PID_IN;
+			}
+			break;
+		case USB_PID_ACK:
+			if (PTD_GET_ACTIVE(ptd)
+			    || (cc != TD_CC_NOERROR && cc < 0x0E))
+				break;
+			if (urb->status == -EINPROGRESS)
+				urb->status = 0;
+			ep->nextpid = 0;
+			break;
+		default:
+			BUG_ON(1);
+		}
+		spin_unlock(&urb->lock);
+	}
+}
+
+/*
+  Take done or failed requests out of schedule. Give back
+  processed urbs.
+*/
+static void finish_request(struct isp116x *isp116x, struct isp116x_ep *ep,
+			   struct urb *urb, struct pt_regs *regs)
+__releases(isp116x->lock) __acquires(isp116x->lock)
+{
+	unsigned i;
+
+	urb->hcpriv = NULL;
+	ep->error_count = 0;
+
+	if (usb_pipecontrol(urb->pipe))
+		ep->nextpid = USB_PID_SETUP;
+
+	urb_dbg(urb, "Finish");
+
+	spin_unlock(&isp116x->lock);
+	usb_hcd_giveback_urb(isp116x_to_hcd(isp116x), urb, regs);
+	spin_lock(&isp116x->lock);
+
+	/* take idle endpoints out of the schedule */
+	if (!list_empty(&ep->hep->urb_list))
+		return;
+
+	/* async deschedule */
+	if (!list_empty(&ep->schedule)) {
+		list_del_init(&ep->schedule);
+		return;
+	}
+
+	/* periodic deschedule */
+	DBG("deschedule qh%d/%p branch %d\n", ep->period, ep, ep->branch);
+	for (i = ep->branch; i < PERIODIC_SIZE; i += ep->period) {
+		struct isp116x_ep *temp;
+		struct isp116x_ep **prev = &isp116x->periodic[i];
+
+		while (*prev && ((temp = *prev) != ep))
+			prev = &temp->next;
+		if (*prev)
+			*prev = ep->next;
+		isp116x->load[i] -= ep->load;
+	}
+	ep->branch = PERIODIC_SIZE;
+	isp116x_to_hcd(isp116x)->self.bandwidth_allocated -=
+	    ep->load / ep->period;
+
+	/* switch irq type? */
+	if (!--isp116x->periodic_count) {
+		isp116x->irqenb &= ~HCuPINT_SOF;
+		isp116x->irqenb |= HCuPINT_ATL;
+	}
+}
+
+/*
+  Scan transfer lists, schedule transfers, send data off
+  to chip.
+ */
+static void start_atl_transfers(struct isp116x *isp116x)
+{
+	struct isp116x_ep *last_ep = NULL, *ep;
+	struct urb *urb;
+	u16 load = 0;
+	int len, index, speed, byte_time;
+
+	if (atomic_read(&isp116x->atl_finishing))
+		return;
+
+	if (!HC_IS_RUNNING(isp116x_to_hcd(isp116x)->state))
+		return;
+
+	/* FIFO not empty? */
+	if (isp116x_read_reg16(isp116x, HCBUFSTAT) & HCBUFSTAT_ATL_FULL)
+		return;
+
+	isp116x->atl_active = NULL;
+	isp116x->atl_buflen = isp116x->atl_bufshrt = 0;
+
+	/* Schedule int transfers */
+	if (isp116x->periodic_count) {
+		isp116x->fmindex = index =
+		    (isp116x->fmindex + 1) & (PERIODIC_SIZE - 1);
+		if ((load = isp116x->load[index])) {
+			/* Bring all int transfers for this frame
+			   into the active queue */
+			isp116x->atl_active = last_ep =
+			    isp116x->periodic[index];
+			while (last_ep->next)
+				last_ep = (last_ep->active = last_ep->next);
+			last_ep->active = NULL;
+		}
+	}
+
+	/* Schedule control/bulk transfers */
+	list_for_each_entry(ep, &isp116x->async, schedule) {
+		urb = container_of(ep->hep->urb_list.next,
+				   struct urb, urb_list);
+		speed = urb->dev->speed;
+		byte_time = speed == USB_SPEED_LOW
+		    ? BYTE_TIME_LOWSPEED : BYTE_TIME_FULLSPEED;
+
+		if (ep->nextpid == USB_PID_SETUP) {
+			len = sizeof(struct usb_ctrlrequest);
+		} else if (ep->nextpid == USB_PID_ACK) {
+			len = 0;
+		} else {
+			/* Find current free length ... */
+			len = (MAX_LOAD_LIMIT - load) / byte_time;
+
+			/* ... then limit it to configured max size ... */
+			len = min(len, speed == USB_SPEED_LOW ?
+				  MAX_TRANSFER_SIZE_LOWSPEED :
+				  MAX_TRANSFER_SIZE_FULLSPEED);
+
+			/* ... and finally cut to the multiple of MaxPacketSize,
+			   or to the real length if there's enough room. */
+			if (len <
+			    (urb->transfer_buffer_length -
+			     urb->actual_length)) {
+				len -= len % ep->maxpacket;
+				if (!len)
+					continue;
+			} else
+				len = urb->transfer_buffer_length -
+				    urb->actual_length;
+			BUG_ON(len < 0);
+		}
+
+		load += len * byte_time;
+		if (load > MAX_LOAD_LIMIT)
+			break;
+
+		ep->active = NULL;
+		ep->length = len;
+		if (last_ep)
+			last_ep->active = ep;
+		else
+			isp116x->atl_active = ep;
+		last_ep = ep;
+	}
+
+	/* Avoid starving of endpoints */
+	if ((&isp116x->async)->next != (&isp116x->async)->prev)
+		list_move(&isp116x->async, (&isp116x->async)->next);
+
+	if (isp116x->atl_active) {
+		preproc_atl_queue(isp116x);
+		pack_fifo(isp116x);
+	}
+}
+
+/*
+  Finish the processed transfers
+*/
+static void finish_atl_transfers(struct isp116x *isp116x, struct pt_regs *regs)
+{
+	struct isp116x_ep *ep;
+	struct urb *urb;
+
+	if (!isp116x->atl_active)
+		return;
+	/* Fifo not ready? */
+	if (!(isp116x_read_reg16(isp116x, HCBUFSTAT) & HCBUFSTAT_ATL_DONE))
+		return;
+
+	atomic_inc(&isp116x->atl_finishing);
+	unpack_fifo(isp116x);
+	postproc_atl_queue(isp116x);
+	for (ep = isp116x->atl_active; ep; ep = ep->active) {
+		urb =
+		    container_of(ep->hep->urb_list.next, struct urb, urb_list);
+		/* USB_PID_ACK check here avoids finishing of
+		   control transfers, for which TD_DATAUNDERRUN
+		   occured, while URB_SHORT_NOT_OK was set */
+		if (urb && urb->status != -EINPROGRESS
+		    && ep->nextpid != USB_PID_ACK)
+			finish_request(isp116x, ep, urb, regs);
+	}
+	atomic_dec(&isp116x->atl_finishing);
+}
+
+static irqreturn_t isp116x_irq(struct usb_hcd *hcd, struct pt_regs *regs)
+{
+	struct isp116x *isp116x = hcd_to_isp116x(hcd);
+	u16 irqstat;
+	irqreturn_t ret = IRQ_NONE;
+
+	spin_lock(&isp116x->lock);
+	isp116x_write_reg16(isp116x, HCuPINTENB, 0);
+	irqstat = isp116x_read_reg16(isp116x, HCuPINT);
+	isp116x_write_reg16(isp116x, HCuPINT, irqstat);
+
+	if (irqstat & (HCuPINT_ATL | HCuPINT_SOF)) {
+		ret = IRQ_HANDLED;
+		finish_atl_transfers(isp116x, regs);
+	}
+
+	if (irqstat & HCuPINT_OPR) {
+		u32 intstat = isp116x_read_reg32(isp116x, HCINTSTAT);
+		isp116x_write_reg32(isp116x, HCINTSTAT, intstat);
+		if (intstat & HCINT_UE) {
+			ERR("Unrecoverable error\n");
+			/* What should we do here? Reset?  */
+		}
+		if (intstat & HCINT_RHSC) {
+			isp116x->rhstatus =
+			    isp116x_read_reg32(isp116x, HCRHSTATUS);
+			isp116x->rhport[0] =
+			    isp116x_read_reg32(isp116x, HCRHPORT1);
+			isp116x->rhport[1] =
+			    isp116x_read_reg32(isp116x, HCRHPORT2);
+		}
+		if (intstat & HCINT_RD) {
+			DBG("---- remote wakeup\n");
+			schedule_work(&isp116x->rh_resume);
+			ret = IRQ_HANDLED;
+		}
+		irqstat &= ~HCuPINT_OPR;
+		ret = IRQ_HANDLED;
+	}
+
+	if (irqstat & (HCuPINT_ATL | HCuPINT_SOF)) {
+		start_atl_transfers(isp116x);
+	}
+
+	isp116x_write_reg16(isp116x, HCuPINTENB, isp116x->irqenb);
+	spin_unlock(&isp116x->lock);
+	return ret;
+}
+
+/*-----------------------------------------------------------------*/
+
+/* usb 1.1 says max 90% of a frame is available for periodic transfers.
+ * this driver doesn't promise that much since it's got to handle an
+ * IRQ per packet; irq handling latencies also use up that time.
+ */
+
+/* out of 1000 us */
+#define	MAX_PERIODIC_LOAD	600
+static int balance(struct isp116x *isp116x, u16 period, u16 load)
+{
+	int i, branch = -ENOSPC;
+
+	/* search for the least loaded schedule branch of that period
+	   which has enough bandwidth left unreserved. */
+	for (i = 0; i < period; i++) {
+		if (branch < 0 || isp116x->load[branch] > isp116x->load[i]) {
+			int j;
+
+			for (j = i; j < PERIODIC_SIZE; j += period) {
+				if ((isp116x->load[j] + load)
+				    > MAX_PERIODIC_LOAD)
+					break;
+			}
+			if (j < PERIODIC_SIZE)
+				continue;
+			branch = i;
+		}
+	}
+	return branch;
+}
+
+/* NB! ALL the code above this point runs with isp116x->lock
+   held, irqs off
+*/
+
+/*-----------------------------------------------------------------*/
+
+static int isp116x_urb_enqueue(struct usb_hcd *hcd,
+			       struct usb_host_endpoint *hep, struct urb *urb,
+			       unsigned mem_flags)
+{
+	struct isp116x *isp116x = hcd_to_isp116x(hcd);
+	struct usb_device *udev = urb->dev;
+	unsigned int pipe = urb->pipe;
+	int is_out = !usb_pipein(pipe);
+	int type = usb_pipetype(pipe);
+	int epnum = usb_pipeendpoint(pipe);
+	struct isp116x_ep *ep = NULL;
+	unsigned long flags;
+	int i;
+	int ret = 0;
+
+	urb_dbg(urb, "Enqueue");
+
+	if (type == PIPE_ISOCHRONOUS) {
+		ERR("Isochronous transfers not supported\n");
+		urb_dbg(urb, "Refused to enqueue");
+		return -ENXIO;
+	}
+	/* avoid all allocations within spinlocks: request or endpoint */
+	if (!hep->hcpriv) {
+		ep = kcalloc(1, sizeof *ep, mem_flags);
+		if (!ep)
+			return -ENOMEM;
+	}
+
+	spin_lock_irqsave(&isp116x->lock, flags);
+	if (!HC_IS_RUNNING(hcd->state)) {
+		ret = -ENODEV;
+		goto fail;
+	}
+
+	if (hep->hcpriv)
+		ep = hep->hcpriv;
+	else {
+		INIT_LIST_HEAD(&ep->schedule);
+		ep->udev = usb_get_dev(udev);
+		ep->epnum = epnum;
+		ep->maxpacket = usb_maxpacket(udev, urb->pipe, is_out);
+		usb_settoggle(udev, epnum, is_out, 0);
+
+		if (type == PIPE_CONTROL) {
+			ep->nextpid = USB_PID_SETUP;
+		} else if (is_out) {
+			ep->nextpid = USB_PID_OUT;
+		} else {
+			ep->nextpid = USB_PID_IN;
+		}
+
+		if (urb->interval) {
+			/*
+			   With INT URBs submitted, the driver works with SOF
+			   interrupt enabled and ATL interrupt disabled. After
+			   the PTDs are written to fifo ram, the chip starts
+			   fifo processing and usb transfers after the next
+			   SOF and continues until the transfers are finished
+			   (succeeded or failed) or the frame ends. Therefore,
+			   the transfers occur only in every second frame,
+			   while fifo reading/writing and data processing
+			   occur in every other second frame. */
+			if (urb->interval < 2)
+				urb->interval = 2;
+			if (urb->interval > 2 * PERIODIC_SIZE)
+				urb->interval = 2 * PERIODIC_SIZE;
+			ep->period = urb->interval >> 1;
+			ep->branch = PERIODIC_SIZE;
+			ep->load = usb_calc_bus_time(udev->speed,
+						     !is_out,
+						     (type == PIPE_ISOCHRONOUS),
+						     usb_maxpacket(udev, pipe,
+								   is_out)) /
+			    1000;
+		}
+		hep->hcpriv = ep;
+		ep->hep = hep;
+	}
+
+	/* maybe put endpoint into schedule */
+	switch (type) {
+	case PIPE_CONTROL:
+	case PIPE_BULK:
+		if (list_empty(&ep->schedule))
+			list_add_tail(&ep->schedule, &isp116x->async);
+		break;
+	case PIPE_INTERRUPT:
+		urb->interval = ep->period;
+		ep->length = min((int)ep->maxpacket,
+				 urb->transfer_buffer_length);
+
+		/* urb submitted for already existing endpoint */
+		if (ep->branch < PERIODIC_SIZE)
+			break;
+
+		ret = ep->branch = balance(isp116x, ep->period, ep->load);
+		if (ret < 0)
+			goto fail;
+		ret = 0;
+
+		urb->start_frame = (isp116x->fmindex & (PERIODIC_SIZE - 1))
+		    + ep->branch;
+
+		/* sort each schedule branch by period (slow before fast)
+		   to share the faster parts of the tree without needing
+		   dummy/placeholder nodes */
+		DBG("schedule qh%d/%p branch %d\n", ep->period, ep, ep->branch);
+		for (i = ep->branch; i < PERIODIC_SIZE; i += ep->period) {
+			struct isp116x_ep **prev = &isp116x->periodic[i];
+			struct isp116x_ep *here = *prev;
+
+			while (here && ep != here) {
+				if (ep->period > here->period)
+					break;
+				prev = &here->next;
+				here = *prev;
+			}
+			if (ep != here) {
+				ep->next = here;
+				*prev = ep;
+			}
+			isp116x->load[i] += ep->load;
+		}
+		hcd->self.bandwidth_allocated += ep->load / ep->period;
+
+		/* switch over to SOFint */
+		if (!isp116x->periodic_count++) {
+			isp116x->irqenb &= ~HCuPINT_ATL;
+			isp116x->irqenb |= HCuPINT_SOF;
+			isp116x_write_reg16(isp116x, HCuPINTENB,
+					    isp116x->irqenb);
+		}
+	}
+
+	/* in case of unlink-during-submit */
+	spin_lock(&urb->lock);
+	if (urb->status != -EINPROGRESS) {
+		spin_unlock(&urb->lock);
+		finish_request(isp116x, ep, urb, NULL);
+		ret = 0;
+		goto fail;
+	}
+	urb->hcpriv = hep;
+	spin_unlock(&urb->lock);
+	start_atl_transfers(isp116x);
+
+      fail:
+	spin_unlock_irqrestore(&isp116x->lock, flags);
+	return ret;
+}
+
+/*
+   Dequeue URBs.
+*/
+static int isp116x_urb_dequeue(struct usb_hcd *hcd, struct urb *urb)
+{
+	struct isp116x *isp116x = hcd_to_isp116x(hcd);
+	struct usb_host_endpoint *hep;
+	struct isp116x_ep *ep, *ep_act;
+	unsigned long flags;
+
+	spin_lock_irqsave(&isp116x->lock, flags);
+	hep = urb->hcpriv;
+	/* URB already unlinked (or never linked)? */
+	if (!hep) {
+		spin_unlock_irqrestore(&isp116x->lock, flags);
+		return 0;
+	}
+	ep = hep->hcpriv;
+	WARN_ON(hep != ep->hep);
+
+	/* In front of queue? */
+	if (ep->hep->urb_list.next == &urb->urb_list)
+		/* active? */
+		for (ep_act = isp116x->atl_active; ep_act;
+		     ep_act = ep_act->active)
+			if (ep_act == ep) {
+				VDBG("dequeue, urb %p active; wait for irq\n",
+				     urb);
+				urb = NULL;
+				break;
+			}
+
+	if (urb)
+		finish_request(isp116x, ep, urb, NULL);
+
+	spin_unlock_irqrestore(&isp116x->lock, flags);
+	return 0;
+}
+
+static void isp116x_endpoint_disable(struct usb_hcd *hcd,
+				     struct usb_host_endpoint *hep)
+{
+	int i;
+	struct isp116x_ep *ep = hep->hcpriv;;
+
+	if (!ep)
+		return;
+
+	/* assume we'd just wait for the irq */
+	for (i = 0; i < 100 && !list_empty(&hep->urb_list); i++)
+		msleep(3);
+	if (!list_empty(&hep->urb_list))
+		WARN("ep %p not empty?\n", ep);
+
+	usb_put_dev(ep->udev);
+	kfree(ep);
+	hep->hcpriv = NULL;
+}
+
+static int isp116x_get_frame(struct usb_hcd *hcd)
+{
+	struct isp116x *isp116x = hcd_to_isp116x(hcd);
+	u32 fmnum;
+	unsigned long flags;
+
+	spin_lock_irqsave(&isp116x->lock, flags);
+	fmnum = isp116x_read_reg32(isp116x, HCFMNUM);
+	spin_unlock_irqrestore(&isp116x->lock, flags);
+	return (int)fmnum;
+}
+
+/*----------------------------------------------------------------*/
+
+/*
+  Adapted from ohci-hub.c. Currently we don't support autosuspend.
+*/
+static int isp116x_hub_status_data(struct usb_hcd *hcd, char *buf)
+{
+	struct isp116x *isp116x = hcd_to_isp116x(hcd);
+	int ports, i, changed = 0;
+
+	if (!HC_IS_RUNNING(hcd->state))
+		return -ESHUTDOWN;
+
+	ports = isp116x->rhdesca & RH_A_NDP;
+
+	/* init status */
+	if (isp116x->rhstatus & (RH_HS_LPSC | RH_HS_OCIC))
+		buf[0] = changed = 1;
+	else
+		buf[0] = 0;
+
+	for (i = 0; i < ports; i++) {
+		u32 status = isp116x->rhport[i];
+
+		if (status & (RH_PS_CSC | RH_PS_PESC | RH_PS_PSSC
+			      | RH_PS_OCIC | RH_PS_PRSC)) {
+			changed = 1;
+			buf[0] |= 1 << (i + 1);
+			continue;
+		}
+	}
+	return changed;
+}
+
+static void isp116x_hub_descriptor(struct isp116x *isp116x,
+				   struct usb_hub_descriptor *desc)
+{
+	u32 reg = isp116x->rhdesca;
+
+	desc->bDescriptorType = 0x29;
+	desc->bDescLength = 9;
+	desc->bHubContrCurrent = 0;
+	desc->bNbrPorts = (u8) (reg & 0x3);
+	/* Power switching, device type, overcurrent. */
+	desc->wHubCharacteristics =
+	    (__force __u16) cpu_to_le16((u16) ((reg >> 8) & 0x1f));
+	desc->bPwrOn2PwrGood = (u8) ((reg >> 24) & 0xff);
+	/* two bitmaps:  ports removable, and legacy PortPwrCtrlMask */
+	desc->bitmap[0] = desc->bNbrPorts == 1 ? 1 << 1 : 3 << 1;
+	desc->bitmap[1] = ~0;
+}
+
+/* Perform reset of a given port.
+   It would be great to just start the reset and let the
+   USB core to clear the reset in due time. However,
+   root hub ports should be reset for at least 50 ms, while
+   our chip stays in reset for about 10 ms. I.e., we must
+   repeatedly reset it ourself here.
+*/
+static inline void root_port_reset(struct isp116x *isp116x, unsigned port)
+{
+	u32 tmp;
+	unsigned long flags, t;
+
+	/* Root hub reset should be 50 ms, but some devices
+	   want it even longer. */
+	t = jiffies + msecs_to_jiffies(100);
+
+	while (time_before(jiffies, t)) {
+		spin_lock_irqsave(&isp116x->lock, flags);
+		/* spin until any current reset finishes */
+		for (;;) {
+			tmp = isp116x_read_reg32(isp116x, port ?
+						 HCRHPORT2 : HCRHPORT1);
+			if (!(tmp & RH_PS_PRS))
+				break;
+			udelay(500);
+		}
+		/* Don't reset a disconnected port */
+		if (!(tmp & RH_PS_CCS)) {
+			spin_unlock_irqrestore(&isp116x->lock, flags);
+			break;
+		}
+		/* Reset lasts 10ms (claims datasheet) */
+		isp116x_write_reg32(isp116x, port ? HCRHPORT2 :
+				    HCRHPORT1, (RH_PS_PRS));
+		spin_unlock_irqrestore(&isp116x->lock, flags);
+		msleep(10);
+	}
+}
+
+/* Adapted from ohci-hub.c */
+static int isp116x_hub_control(struct usb_hcd *hcd,
+			       u16 typeReq,
+			       u16 wValue, u16 wIndex, char *buf, u16 wLength)
+{
+	struct isp116x *isp116x = hcd_to_isp116x(hcd);
+	int ret = 0;
+	unsigned long flags;
+	int ports = isp116x->rhdesca & RH_A_NDP;
+	u32 tmp = 0;
+
+	switch (typeReq) {
+	case ClearHubFeature:
+		DBG("ClearHubFeature: ");
+		switch (wValue) {
+		case C_HUB_OVER_CURRENT:
+			DBG("C_HUB_OVER_CURRENT\n");
+			spin_lock_irqsave(&isp116x->lock, flags);
+			isp116x_write_reg32(isp116x, HCRHSTATUS, RH_HS_OCIC);
+			spin_unlock_irqrestore(&isp116x->lock, flags);
+		case C_HUB_LOCAL_POWER:
+			DBG("C_HUB_LOCAL_POWER\n");
+			break;
+		default:
+			goto error;
+		}
+		break;
+	case SetHubFeature:
+		DBG("SetHubFeature: ");
+		switch (wValue) {
+		case C_HUB_OVER_CURRENT:
+		case C_HUB_LOCAL_POWER:
+			DBG("C_HUB_OVER_CURRENT or C_HUB_LOCAL_POWER\n");
+			break;
+		default:
+			goto error;
+		}
+		break;
+	case GetHubDescriptor:
+		DBG("GetHubDescriptor\n");
+		isp116x_hub_descriptor(isp116x,
+				       (struct usb_hub_descriptor *)buf);
+		break;
+	case GetHubStatus:
+		DBG("GetHubStatus\n");
+		*(__le32 *) buf = 0;
+		break;
+	case GetPortStatus:
+		DBG("GetPortStatus\n");
+		if (!wIndex || wIndex > ports)
+			goto error;
+		tmp = isp116x->rhport[--wIndex];
+		*(__le32 *) buf = cpu_to_le32(tmp);
+		DBG("GetPortStatus: port[%d]  %08x\n", wIndex + 1, tmp);
+		break;
+	case ClearPortFeature:
+		DBG("ClearPortFeature: ");
+		if (!wIndex || wIndex > ports)
+			goto error;
+		wIndex--;
+
+		switch (wValue) {
+		case USB_PORT_FEAT_ENABLE:
+			DBG("USB_PORT_FEAT_ENABLE\n");
+			tmp = RH_PS_CCS;
+			break;
+		case USB_PORT_FEAT_C_ENABLE:
+			DBG("USB_PORT_FEAT_C_ENABLE\n");
+			tmp = RH_PS_PESC;
+			break;
+		case USB_PORT_FEAT_SUSPEND:
+			DBG("USB_PORT_FEAT_SUSPEND\n");
+			tmp = RH_PS_POCI;
+			break;
+		case USB_PORT_FEAT_C_SUSPEND:
+			DBG("USB_PORT_FEAT_C_SUSPEND\n");
+			tmp = RH_PS_PSSC;
+			break;
+		case USB_PORT_FEAT_POWER:
+			DBG("USB_PORT_FEAT_POWER\n");
+			tmp = RH_PS_LSDA;
+			break;
+		case USB_PORT_FEAT_C_CONNECTION:
+			DBG("USB_PORT_FEAT_C_CONNECTION\n");
+			tmp = RH_PS_CSC;
+			break;
+		case USB_PORT_FEAT_C_OVER_CURRENT:
+			DBG("USB_PORT_FEAT_C_OVER_CURRENT\n");
+			tmp = RH_PS_OCIC;
+			break;
+		case USB_PORT_FEAT_C_RESET:
+			DBG("USB_PORT_FEAT_C_RESET\n");
+			tmp = RH_PS_PRSC;
+			break;
+		default:
+			goto error;
+		}
+		spin_lock_irqsave(&isp116x->lock, flags);
+		isp116x_write_reg32(isp116x, wIndex
+				    ? HCRHPORT2 : HCRHPORT1, tmp);
+		isp116x->rhport[wIndex] =
+		    isp116x_read_reg32(isp116x, wIndex ? HCRHPORT2 : HCRHPORT1);
+		spin_unlock_irqrestore(&isp116x->lock, flags);
+		break;
+	case SetPortFeature:
+		DBG("SetPortFeature: ");
+		if (!wIndex || wIndex > ports)
+			goto error;
+		wIndex--;
+		switch (wValue) {
+		case USB_PORT_FEAT_SUSPEND:
+			DBG("USB_PORT_FEAT_SUSPEND\n");
+			spin_lock_irqsave(&isp116x->lock, flags);
+			isp116x_write_reg32(isp116x, wIndex
+					    ? HCRHPORT2 : HCRHPORT1, RH_PS_PSS);
+			break;
+		case USB_PORT_FEAT_POWER:
+			DBG("USB_PORT_FEAT_POWER\n");
+			spin_lock_irqsave(&isp116x->lock, flags);
+			isp116x_write_reg32(isp116x, wIndex
+					    ? HCRHPORT2 : HCRHPORT1, RH_PS_PPS);
+			break;
+		case USB_PORT_FEAT_RESET:
+			DBG("USB_PORT_FEAT_RESET\n");
+			root_port_reset(isp116x, wIndex);
+			spin_lock_irqsave(&isp116x->lock, flags);
+			break;
+		default:
+			goto error;
+		}
+		isp116x->rhport[wIndex] =
+		    isp116x_read_reg32(isp116x, wIndex ? HCRHPORT2 : HCRHPORT1);
+		spin_unlock_irqrestore(&isp116x->lock, flags);
+		break;
+
+	default:
+	      error:
+		/* "protocol stall" on error */
+		DBG("PROTOCOL STALL\n");
+		ret = -EPIPE;
+	}
+	return ret;
+}
+
+#ifdef	CONFIG_PM
+
+static int isp116x_hub_suspend(struct usb_hcd *hcd)
+{
+	struct isp116x *isp116x = hcd_to_isp116x(hcd);
+	unsigned long flags;
+	u32 val;
+	int ret = 0;
+
+	spin_lock_irqsave(&isp116x->lock, flags);
+
+	val = isp116x_read_reg32(isp116x, HCCONTROL);
+	switch (val & HCCONTROL_HCFS) {
+	case HCCONTROL_USB_OPER:
+		hcd->state = HC_STATE_QUIESCING;
+		val &= (~HCCONTROL_HCFS & ~HCCONTROL_RWE);
+		val |= HCCONTROL_USB_SUSPEND;
+		if (hcd->remote_wakeup)
+			val |= HCCONTROL_RWE;
+		/* Wait for usb transfers to finish */
+		mdelay(2);
+		isp116x_write_reg32(isp116x, HCCONTROL, val);
+		hcd->state = HC_STATE_SUSPENDED;
+		/* Wait for devices to suspend */
+		mdelay(5);
+	case HCCONTROL_USB_SUSPEND:
+		break;
+	case HCCONTROL_USB_RESUME:
+		isp116x_write_reg32(isp116x, HCCONTROL,
+				    (val & ~HCCONTROL_HCFS) |
+				    HCCONTROL_USB_RESET);
+	case HCCONTROL_USB_RESET:
+		ret = -EBUSY;
+		break;
+	default:
+		ret = -EINVAL;
+	}
+
+	spin_unlock_irqrestore(&isp116x->lock, flags);
+	return ret;
+}
+
+static int isp116x_hub_resume(struct usb_hcd *hcd)
+{
+	struct isp116x *isp116x = hcd_to_isp116x(hcd);
+	u32 val;
+	int ret = -EINPROGRESS;
+
+	msleep(5);
+	spin_lock_irq(&isp116x->lock);
+
+	val = isp116x_read_reg32(isp116x, HCCONTROL);
+	switch (val & HCCONTROL_HCFS) {
+	case HCCONTROL_USB_SUSPEND:
+		val &= ~HCCONTROL_HCFS;
+		val |= HCCONTROL_USB_RESUME;
+		isp116x_write_reg32(isp116x, HCCONTROL, val);
+	case HCCONTROL_USB_RESUME:
+		break;
+	case HCCONTROL_USB_OPER:
+		/* Without setting power_state here the
+		   SUSPENDED state won't be removed from
+		   sysfs/usbN/power.state as a response to remote
+		   wakeup. Maybe in the future. */
+		hcd->self.root_hub->dev.power.power_state = PMSG_ON;
+		ret = 0;
+		break;
+	default:
+		ret = -EBUSY;
+	}
+
+	if (ret != -EINPROGRESS) {
+		spin_unlock_irq(&isp116x->lock);
+		return ret;
+	}
+
+	val = isp116x->rhdesca & RH_A_NDP;
+	while (val--) {
+		u32 stat =
+		    isp116x_read_reg32(isp116x, val ? HCRHPORT2 : HCRHPORT1);
+		/* force global, not selective, resume */
+		if (!(stat & RH_PS_PSS))
+			continue;
+		DBG("%s: Resuming port %d\n", __func__, val);
+		isp116x_write_reg32(isp116x, RH_PS_POCI, val
+				    ? HCRHPORT2 : HCRHPORT1);
+	}
+	spin_unlock_irq(&isp116x->lock);
+
+	hcd->state = HC_STATE_RESUMING;
+	mdelay(20);
+
+	/* Go operational */
+	spin_lock_irq(&isp116x->lock);
+	val = isp116x_read_reg32(isp116x, HCCONTROL);
+	isp116x_write_reg32(isp116x, HCCONTROL,
+			    (val & ~HCCONTROL_HCFS) | HCCONTROL_USB_OPER);
+	spin_unlock_irq(&isp116x->lock);
+	/* see analogous comment above */
+	hcd->self.root_hub->dev.power.power_state = PMSG_ON;
+	hcd->state = HC_STATE_RUNNING;
+
+	return 0;
+}
+
+static void isp116x_rh_resume(void *_hcd)
+{
+	struct usb_hcd *hcd = _hcd;
+
+	usb_resume_device(hcd->self.root_hub);
+}
+
+#else
+
+#define	isp116x_hub_suspend	NULL
+#define	isp116x_hub_resume	NULL
+
+static void isp116x_rh_resume(void *_hcd)
+{
+}
+
+#endif
+
+/*-----------------------------------------------------------------*/
+
+#ifdef STUB_DEBUG_FILE
+
+static inline void create_debug_file(struct isp116x *isp116x)
+{
+}
+
+static inline void remove_debug_file(struct isp116x *isp116x)
+{
+}
+
+#else
+
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+
+static void dump_irq(struct seq_file *s, char *label, u16 mask)
+{
+	seq_printf(s, "%s %04x%s%s%s%s%s%s\n", label, mask,
+		   mask & HCuPINT_CLKRDY ? " clkrdy" : "",
+		   mask & HCuPINT_SUSP ? " susp" : "",
+		   mask & HCuPINT_OPR ? " opr" : "",
+		   mask & HCuPINT_AIIEOT ? " eot" : "",
+		   mask & HCuPINT_ATL ? " atl" : "",
+		   mask & HCuPINT_SOF ? " sof" : "");
+}
+
+static void dump_int(struct seq_file *s, char *label, u32 mask)
+{
+	seq_printf(s, "%s %08x%s%s%s%s%s%s%s\n", label, mask,
+		   mask & HCINT_MIE ? " MIE" : "",
+		   mask & HCINT_RHSC ? " rhsc" : "",
+		   mask & HCINT_FNO ? " fno" : "",
+		   mask & HCINT_UE ? " ue" : "",
+		   mask & HCINT_RD ? " rd" : "",
+		   mask & HCINT_SF ? " sof" : "", mask & HCINT_SO ? " so" : "");
+}
+
+static int proc_isp116x_show(struct seq_file *s, void *unused)
+{
+	struct isp116x *isp116x = s->private;
+	struct isp116x_ep *ep;
+	struct urb *urb;
+	unsigned i;
+	char *str;
+
+	seq_printf(s, "%s\n%s version %s\n",
+		   isp116x_to_hcd(isp116x)->product_desc, hcd_name,
+		   DRIVER_VERSION);
+
+	if (HC_IS_SUSPENDED(isp116x_to_hcd(isp116x)->state)) {
+		seq_printf(s, "HCD is suspended\n");
+		return 0;
+	}
+	if (!HC_IS_RUNNING(isp116x_to_hcd(isp116x)->state)) {
+		seq_printf(s, "HCD not running\n");
+		return 0;
+	}
+
+	spin_lock_irq(&isp116x->lock);
+
+	dump_irq(s, "hc_irq_enable", isp116x_read_reg16(isp116x, HCuPINTENB));
+	dump_irq(s, "hc_irq_status", isp116x_read_reg16(isp116x, HCuPINT));
+	dump_int(s, "hc_int_enable", isp116x_read_reg32(isp116x, HCINTENB));
+	dump_int(s, "hc_int_status", isp116x_read_reg32(isp116x, HCINTSTAT));
+
+	list_for_each_entry(ep, &isp116x->async, schedule) {
+
+		switch (ep->nextpid) {
+		case USB_PID_IN:
+			str = "in";
+			break;
+		case USB_PID_OUT:
+			str = "out";
+			break;
+		case USB_PID_SETUP:
+			str = "setup";
+			break;
+		case USB_PID_ACK:
+			str = "status";
+			break;
+		default:
+			str = "?";
+			break;
+		};
+		seq_printf(s, "%p, ep%d%s, maxpacket %d:\n", ep,
+			   ep->epnum, str, ep->maxpacket);
+		list_for_each_entry(urb, &ep->hep->urb_list, urb_list) {
+			seq_printf(s, "  urb%p, %d/%d\n", urb,
+				   urb->actual_length,
+				   urb->transfer_buffer_length);
+		}
+	}
+	if (!list_empty(&isp116x->async))
+		seq_printf(s, "\n");
+
+	seq_printf(s, "periodic size= %d\n", PERIODIC_SIZE);
+
+	for (i = 0; i < PERIODIC_SIZE; i++) {
+		ep = isp116x->periodic[i];
+		if (!ep)
+			continue;
+		seq_printf(s, "%2d [%3d]:\n", i, isp116x->load[i]);
+
+		/* DUMB: prints shared entries multiple times */
+		do {
+			seq_printf(s, "   %d/%p (%sdev%d ep%d%s max %d)\n",
+				   ep->period, ep,
+				   (ep->udev->speed ==
+				    USB_SPEED_FULL) ? "" : "ls ",
+				   ep->udev->devnum, ep->epnum,
+				   (ep->epnum ==
+				    0) ? "" : ((ep->nextpid ==
+						USB_PID_IN) ? "in" : "out"),
+				   ep->maxpacket);
+			ep = ep->next;
+		} while (ep);
+	}
+	spin_unlock_irq(&isp116x->lock);
+	seq_printf(s, "\n");
+
+	return 0;
+}
+
+static int proc_isp116x_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, proc_isp116x_show, PDE(inode)->data);
+}
+
+static struct file_operations proc_ops = {
+	.open = proc_isp116x_open,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = single_release,
+};
+
+/* expect just one isp116x per system */
+static const char proc_filename[] = "driver/isp116x";
+
+static void create_debug_file(struct isp116x *isp116x)
+{
+	struct proc_dir_entry *pde;
+
+	pde = create_proc_entry(proc_filename, 0, NULL);
+	if (pde == NULL)
+		return;
+
+	pde->proc_fops = &proc_ops;
+	pde->data = isp116x;
+	isp116x->pde = pde;
+}
+
+static void remove_debug_file(struct isp116x *isp116x)
+{
+	if (isp116x->pde)
+		remove_proc_entry(proc_filename, NULL);
+}
+
+#endif
+
+/*-----------------------------------------------------------------*/
+
+/*
+  Software reset - can be called from any contect.
+*/
+static int isp116x_sw_reset(struct isp116x *isp116x)
+{
+	int retries = 15;
+	unsigned long flags;
+	int ret = 0;
+
+	spin_lock_irqsave(&isp116x->lock, flags);
+	isp116x_write_reg16(isp116x, HCSWRES, HCSWRES_MAGIC);
+	isp116x_write_reg32(isp116x, HCCMDSTAT, HCCMDSTAT_HCR);
+	while (--retries) {
+		/* It usually resets within 1 ms */
+		mdelay(1);
+		if (!(isp116x_read_reg32(isp116x, HCCMDSTAT) & HCCMDSTAT_HCR))
+			break;
+	}
+	if (!retries) {
+		ERR("Software reset timeout\n");
+		ret = -ETIME;
+	}
+	spin_unlock_irqrestore(&isp116x->lock, flags);
+	return ret;
+}
+
+/*
+  Reset. Tries to perform platform-specific hardware
+  reset first; falls back to software reset.
+*/
+static int isp116x_reset(struct usb_hcd *hcd)
+{
+	struct isp116x *isp116x = hcd_to_isp116x(hcd);
+	unsigned long t;
+	u16 clkrdy = 0;
+	int ret = 0, timeout = 15 /* ms */ ;
+
+	if (isp116x->board && isp116x->board->reset) {
+		/* Hardware reset */
+		isp116x->board->reset(hcd->self.controller, 1);
+		msleep(10);
+		if (isp116x->board->clock)
+			isp116x->board->clock(hcd->self.controller, 1);
+		msleep(1);
+		isp116x->board->reset(hcd->self.controller, 0);
+	} else
+		ret = isp116x_sw_reset(isp116x);
+
+	if (ret)
+		return ret;
+
+	t = jiffies + msecs_to_jiffies(timeout);
+	while (time_before_eq(jiffies, t)) {
+		msleep(4);
+		spin_lock_irq(&isp116x->lock);
+		clkrdy = isp116x_read_reg16(isp116x, HCuPINT) & HCuPINT_CLKRDY;
+		spin_unlock_irq(&isp116x->lock);
+		if (clkrdy)
+			break;
+	}
+	if (!clkrdy) {
+		ERR("Clock not ready after 20ms\n");
+		/* After sw_reset the clock won't report to be ready, if
+		   H_WAKEUP pin is high. */
+		if (!isp116x->board || !isp116x->board->reset)
+			ERR("The driver does not support hardware wakeup.\n");
+			ERR("Please make sure that the H_WAKEUP pin "
+				"is pulled low!\n");
+		ret = -ENODEV;
+	}
+	return ret;
+}
+
+static void isp116x_stop(struct usb_hcd *hcd)
+{
+	struct isp116x *isp116x = hcd_to_isp116x(hcd);
+	unsigned long flags;
+	u32 val;
+
+	spin_lock_irqsave(&isp116x->lock, flags);
+	isp116x_write_reg16(isp116x, HCuPINTENB, 0);
+
+	/* Switch off ports' power, some devices don't come up
+	   after next 'insmod' without this */
+	val = isp116x_read_reg32(isp116x, HCRHDESCA);
+	val &= ~(RH_A_NPS | RH_A_PSM);
+	isp116x_write_reg32(isp116x, HCRHDESCA, val);
+	isp116x_write_reg32(isp116x, HCRHSTATUS, RH_HS_LPS);
+	spin_unlock_irqrestore(&isp116x->lock, flags);
+
+	/* Put the chip into reset state */
+	if (isp116x->board && isp116x->board->reset)
+		isp116x->board->reset(hcd->self.controller, 0);
+	else
+		isp116x_sw_reset(isp116x);
+
+	/* Stop the clock */
+	if (isp116x->board && isp116x->board->clock)
+		isp116x->board->clock(hcd->self.controller, 0);
+}
+
+/*
+  Configure the chip. The chip must be successfully reset by now.
+*/
+static int isp116x_start(struct usb_hcd *hcd)
+{
+	struct isp116x *isp116x = hcd_to_isp116x(hcd);
+	struct isp116x_platform_data *board = isp116x->board;
+	u32 val;
+	unsigned long flags;
+
+	spin_lock_irqsave(&isp116x->lock, flags);
+
+	/* clear interrupt status and disable all interrupt sources */
+	isp116x_write_reg16(isp116x, HCuPINT, 0xff);
+	isp116x_write_reg16(isp116x, HCuPINTENB, 0);
+
+	val = isp116x_read_reg16(isp116x, HCCHIPID);
+	if ((val & HCCHIPID_MASK) != HCCHIPID_MAGIC) {
+		ERR("Invalid chip ID %04x\n", val);
+		spin_unlock_irqrestore(&isp116x->lock, flags);
+		return -ENODEV;
+	}
+
+	isp116x_write_reg16(isp116x, HCITLBUFLEN, ISP116x_ITL_BUFSIZE);
+	isp116x_write_reg16(isp116x, HCATLBUFLEN, ISP116x_ATL_BUFSIZE);
+
+	/* ----- HW conf */
+	val = HCHWCFG_INT_ENABLE | HCHWCFG_DBWIDTH(1);
+	if (board->sel15Kres)
+		val |= HCHWCFG_15KRSEL;
+	/* Remote wakeup won't work without working clock */
+	if (board->clknotstop || board->remote_wakeup_enable)
+		val |= HCHWCFG_CLKNOTSTOP;
+	if (board->oc_enable)
+		val |= HCHWCFG_ANALOG_OC;
+	if (board->int_act_high)
+		val |= HCHWCFG_INT_POL;
+	if (board->int_edge_triggered)
+		val |= HCHWCFG_INT_TRIGGER;
+	isp116x_write_reg16(isp116x, HCHWCFG, val);
+
+	/* ----- Root hub conf */
+	val = 0;
+	/* AN10003_1.pdf recommends NPS to be always 1 */
+	if (board->no_power_switching)
+		val |= RH_A_NPS;
+	if (board->power_switching_mode)
+		val |= RH_A_PSM;
+	if (board->potpg)
+		val |= (board->potpg << 24) & RH_A_POTPGT;
+	else
+		val |= (25 << 24) & RH_A_POTPGT;
+	isp116x_write_reg32(isp116x, HCRHDESCA, val);
+	isp116x->rhdesca = isp116x_read_reg32(isp116x, HCRHDESCA);
+
+	val = RH_B_PPCM;
+	isp116x_write_reg32(isp116x, HCRHDESCB, val);
+	isp116x->rhdescb = isp116x_read_reg32(isp116x, HCRHDESCB);
+
+	val = 0;
+	if (board->remote_wakeup_enable) {
+		hcd->can_wakeup = 1;
+		val |= RH_HS_DRWE;
+	}
+	isp116x_write_reg32(isp116x, HCRHSTATUS, val);
+	isp116x->rhstatus = isp116x_read_reg32(isp116x, HCRHSTATUS);
+
+	isp116x_write_reg32(isp116x, HCFMINTVL, 0x27782edf);
+
+	hcd->state = HC_STATE_RUNNING;
+
+	/* Set up interrupts */
+	isp116x->intenb = HCINT_MIE | HCINT_RHSC | HCINT_UE;
+	if (board->remote_wakeup_enable)
+		isp116x->intenb |= HCINT_RD;
+	isp116x->irqenb = HCuPINT_ATL | HCuPINT_OPR;	/* | HCuPINT_SUSP; */
+	isp116x_write_reg32(isp116x, HCINTENB, isp116x->intenb);
+	isp116x_write_reg16(isp116x, HCuPINTENB, isp116x->irqenb);
+
+	/* Go operational */
+	val = HCCONTROL_USB_OPER;
+	/* Remote wakeup connected - NOT SUPPORTED */
+	/*  if (board->remote_wakeup_connected)
+	   val |= HCCONTROL_RWC;  */
+	if (board->remote_wakeup_enable)
+		val |= HCCONTROL_RWE;
+	isp116x_write_reg32(isp116x, HCCONTROL, val);
+
+	/* Disable ports to avoid race in device enumeration */
+	isp116x_write_reg32(isp116x, HCRHPORT1, RH_PS_CCS);
+	isp116x_write_reg32(isp116x, HCRHPORT2, RH_PS_CCS);
+
+	isp116x_show_regs(isp116x);
+	spin_unlock_irqrestore(&isp116x->lock, flags);
+	return 0;
+}
+
+/*-----------------------------------------------------------------*/
+
+static struct hc_driver isp116x_hc_driver = {
+	.description = hcd_name,
+	.product_desc = "ISP116x Host Controller",
+	.hcd_priv_size = sizeof(struct isp116x),
+
+	.irq = isp116x_irq,
+	.flags = HCD_USB11,
+
+	.reset = isp116x_reset,
+	.start = isp116x_start,
+	.stop = isp116x_stop,
+
+	.urb_enqueue = isp116x_urb_enqueue,
+	.urb_dequeue = isp116x_urb_dequeue,
+	.endpoint_disable = isp116x_endpoint_disable,
+
+	.get_frame_number = isp116x_get_frame,
+
+	.hub_status_data = isp116x_hub_status_data,
+	.hub_control = isp116x_hub_control,
+	.hub_suspend = isp116x_hub_suspend,
+	.hub_resume = isp116x_hub_resume,
+};
+
+/*----------------------------------------------------------------*/
+
+static int __init_or_module isp116x_remove(struct device *dev)
+{
+	struct usb_hcd *hcd = dev_get_drvdata(dev);
+	struct isp116x *isp116x;
+	struct platform_device *pdev;
+	struct resource *res;
+
+	if(!hcd)
+		return 0;
+	isp116x = hcd_to_isp116x(hcd);
+	pdev = container_of(dev, struct platform_device, dev);
+	remove_debug_file(isp116x);
+	usb_remove_hcd(hcd);
+
+	iounmap(isp116x->data_reg);
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	release_mem_region(res->start, 2);
+	iounmap(isp116x->addr_reg);
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	release_mem_region(res->start, 2);
+
+	usb_put_hcd(hcd);
+	return 0;
+}
+
+#define resource_len(r) (((r)->end - (r)->start) + 1)
+
+static int __init isp116x_probe(struct device *dev)
+{
+	struct usb_hcd *hcd;
+	struct isp116x *isp116x;
+	struct platform_device *pdev;
+	struct resource *addr, *data;
+	void __iomem *addr_reg;
+	void __iomem *data_reg;
+	int irq;
+	int ret = 0;
+
+	pdev = container_of(dev, struct platform_device, dev);
+	if (pdev->num_resources < 3) {
+		ret = -ENODEV;
+		goto err1;
+	}
+
+	data = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	addr = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	irq = platform_get_irq(pdev, 0);
+	if (!addr || !data || irq < 0) {
+		ret = -ENODEV;
+		goto err1;
+	}
+
+	if (dev->dma_mask) {
+		DBG("DMA not supported\n");
+		ret = -EINVAL;
+		goto err1;
+	}
+
+	if (!request_mem_region(addr->start, 2, hcd_name)) {
+		ret = -EBUSY;
+		goto err1;
+	}
+	addr_reg = ioremap(addr->start, resource_len(addr));
+	if (addr_reg == NULL) {
+		ret = -ENOMEM;
+		goto err2;
+	}
+	if (!request_mem_region(data->start, 2, hcd_name)) {
+		ret = -EBUSY;
+		goto err3;
+	}
+	data_reg = ioremap(data->start, resource_len(data));
+	if (data_reg == NULL) {
+		ret = -ENOMEM;
+		goto err4;
+	}
+
+	/* allocate and initialize hcd */
+	hcd = usb_create_hcd(&isp116x_hc_driver, dev, dev->bus_id);
+	if (!hcd) {
+		ret = -ENOMEM;
+		goto err5;
+	}
+	/* this rsrc_start is bogus */
+	hcd->rsrc_start = addr->start;
+	isp116x = hcd_to_isp116x(hcd);
+	isp116x->data_reg = data_reg;
+	isp116x->addr_reg = addr_reg;
+	spin_lock_init(&isp116x->lock);
+	INIT_LIST_HEAD(&isp116x->async);
+	INIT_WORK(&isp116x->rh_resume, isp116x_rh_resume, hcd);
+	isp116x->board = dev->platform_data;
+
+	if (!isp116x->board) {
+		ERR("Platform data structure not initialized\n");
+		ret = -ENODEV;
+		goto err6;
+	}
+	if (isp116x_check_platform_delay(isp116x)) {
+		ERR("USE_PLATFORM_DELAY defined, but delay function not "
+		    "implemented.\n");
+		ERR("See comments in drivers/usb/host/isp116x-hcd.c\n");
+		ret = -ENODEV;
+		goto err6;
+	}
+
+	ret = usb_add_hcd(hcd, irq, SA_INTERRUPT);
+	if (ret != 0)
+		goto err6;
+
+	create_debug_file(isp116x);
+	return 0;
+
+      err6:
+	usb_put_hcd(hcd);
+      err5:
+	iounmap(data_reg);
+      err4:
+	release_mem_region(data->start, 2);
+      err3:
+	iounmap(addr_reg);
+      err2:
+	release_mem_region(addr->start, 2);
+      err1:
+	ERR("init error, %d\n", ret);
+	return ret;
+}
+
+#ifdef	CONFIG_PM
+/*
+  Suspend of platform device
+*/
+static int isp116x_suspend(struct device *dev, pm_message_t state, u32 phase)
+{
+	int ret = 0;
+	struct usb_hcd *hcd = dev_get_drvdata(dev);
+
+	VDBG("%s: state %x, phase %x\n", __func__, state, phase);
+
+	if (phase != SUSPEND_DISABLE && phase != SUSPEND_POWER_DOWN)
+		return 0;
+
+	ret = usb_suspend_device(hcd->self.root_hub, state);
+	if (!ret) {
+		dev->power.power_state = state;
+		INFO("%s suspended\n", hcd_name);
+	} else
+		ERR("%s suspend failed\n", hcd_name);
+
+	return ret;
+}
+
+/*
+  Resume platform device
+*/
+static int isp116x_resume(struct device *dev, u32 phase)
+{
+	int ret = 0;
+	struct usb_hcd *hcd = dev_get_drvdata(dev);
+
+	VDBG("%s:  state %x, phase %x\n", __func__, dev->power.power_state,
+	     phase);
+	if (phase != RESUME_POWER_ON)
+		return 0;
+
+	ret = usb_resume_device(hcd->self.root_hub);
+	if (!ret) {
+		dev->power.power_state = PMSG_ON;
+		VDBG("%s resumed\n", (char *)hcd_name);
+	}
+	return ret;
+}
+
+#else
+
+#define	isp116x_suspend    NULL
+#define	isp116x_resume     NULL
+
+#endif
+
+static struct device_driver isp116x_driver = {
+	.name = (char *)hcd_name,
+	.bus = &platform_bus_type,
+	.probe = isp116x_probe,
+	.remove = isp116x_remove,
+	.suspend = isp116x_suspend,
+	.resume = isp116x_resume,
+};
+
+/*-----------------------------------------------------------------*/
+
+static int __init isp116x_init(void)
+{
+	if (usb_disabled())
+		return -ENODEV;
+
+	INFO("driver %s, %s\n", hcd_name, DRIVER_VERSION);
+	return driver_register(&isp116x_driver);
+}
+
+module_init(isp116x_init);
+
+static void __exit isp116x_cleanup(void)
+{
+	driver_unregister(&isp116x_driver);
+}
+
+module_exit(isp116x_cleanup);
diff --git a/drivers/usb/host/isp116x.h b/drivers/usb/host/isp116x.h
new file mode 100644
--- /dev/null
+++ b/drivers/usb/host/isp116x.h
@@ -0,0 +1,583 @@
+/*
+ * ISP116x register declarations and HCD data structures
+ *
+ * Copyright (C) 2005 Olav Kongas <ok@artecdesign.ee>
+ * Portions:
+ * Copyright (C) 2004 Lothar Wassmann
+ * Copyright (C) 2004 Psion Teklogix
+ * Copyright (C) 2004 David Brownell
+ */
+
+/* us of 1ms frame */
+#define  MAX_LOAD_LIMIT		850
+
+/* Full speed: max # of bytes to transfer for a single urb
+   at a time must be < 1024 && must be multiple of 64.
+   832 allows transfering 4kiB within 5 frames. */
+#define MAX_TRANSFER_SIZE_FULLSPEED	832
+
+/* Low speed: there is no reason to schedule in very big
+   chunks; often the requested long transfers are for
+   string descriptors containing short strings. */
+#define MAX_TRANSFER_SIZE_LOWSPEED	64
+
+/* Bytetime (us), a rough indication of how much time it
+   would take to transfer a byte of useful data over USB */
+#define BYTE_TIME_FULLSPEED	1
+#define BYTE_TIME_LOWSPEED	20
+
+/* Buffer sizes */
+#define ISP116x_BUF_SIZE	4096
+#define ISP116x_ITL_BUFSIZE	0
+#define ISP116x_ATL_BUFSIZE	((ISP116x_BUF_SIZE) - 2*(ISP116x_ITL_BUFSIZE))
+
+#define ISP116x_WRITE_OFFSET	0x80
+
+/*------------ ISP116x registers/bits ------------*/
+#define	HCREVISION	0x00
+#define	HCCONTROL	0x01
+#define		HCCONTROL_HCFS	(3 << 6)	/* host controller
+						   functional state */
+#define		HCCONTROL_USB_RESET	(0 << 6)
+#define		HCCONTROL_USB_RESUME	(1 << 6)
+#define		HCCONTROL_USB_OPER	(2 << 6)
+#define		HCCONTROL_USB_SUSPEND	(3 << 6)
+#define		HCCONTROL_RWC	(1 << 9)	/* remote wakeup connected */
+#define		HCCONTROL_RWE	(1 << 10)	/* remote wakeup enable */
+#define	HCCMDSTAT	0x02
+#define		HCCMDSTAT_HCR	(1 << 0)	/* host controller reset */
+#define		HCCMDSTAT_SOC	(3 << 16)	/* scheduling overrun count */
+#define	HCINTSTAT	0x03
+#define		HCINT_SO	(1 << 0)	/* scheduling overrun */
+#define		HCINT_WDH	(1 << 1)	/* writeback of done_head */
+#define		HCINT_SF	(1 << 2)	/* start frame */
+#define		HCINT_RD	(1 << 3)	/* resume detect */
+#define		HCINT_UE	(1 << 4)	/* unrecoverable error */
+#define		HCINT_FNO	(1 << 5)	/* frame number overflow */
+#define		HCINT_RHSC	(1 << 6)	/* root hub status change */
+#define		HCINT_OC	(1 << 30)	/* ownership change */
+#define		HCINT_MIE	(1 << 31)	/* master interrupt enable */
+#define	HCINTENB	0x04
+#define	HCINTDIS	0x05
+#define	HCFMINTVL	0x0d
+#define	HCFMREM		0x0e
+#define	HCFMNUM		0x0f
+#define	HCLSTHRESH	0x11
+#define	HCRHDESCA	0x12
+#define		RH_A_NDP	(0x3 << 0)	/* # downstream ports */
+#define		RH_A_PSM	(1 << 8)	/* power switching mode */
+#define		RH_A_NPS	(1 << 9)	/* no power switching */
+#define		RH_A_DT		(1 << 10)	/* device type (mbz) */
+#define		RH_A_OCPM	(1 << 11)	/* overcurrent protection
+						   mode */
+#define		RH_A_NOCP	(1 << 12)	/* no overcurrent protection */
+#define		RH_A_POTPGT	(0xff << 24)	/* power on -> power good
+						   time */
+#define	HCRHDESCB	0x13
+#define		RH_B_DR		(0xffff << 0)	/* device removable flags */
+#define		RH_B_PPCM	(0xffff << 16)	/* port power control mask */
+#define	HCRHSTATUS	0x14
+#define		RH_HS_LPS	(1 << 0)	/* local power status */
+#define		RH_HS_OCI	(1 << 1)	/* over current indicator */
+#define		RH_HS_DRWE	(1 << 15)	/* device remote wakeup
+						   enable */
+#define		RH_HS_LPSC	(1 << 16)	/* local power status change */
+#define		RH_HS_OCIC	(1 << 17)	/* over current indicator
+						   change */
+#define		RH_HS_CRWE	(1 << 31)	/* clear remote wakeup
+						   enable */
+#define	HCRHPORT1	0x15
+#define		RH_PS_CCS	(1 << 0)	/* current connect status */
+#define		RH_PS_PES	(1 << 1)	/* port enable status */
+#define		RH_PS_PSS	(1 << 2)	/* port suspend status */
+#define		RH_PS_POCI	(1 << 3)	/* port over current
+						   indicator */
+#define		RH_PS_PRS	(1 << 4)	/* port reset status */
+#define		RH_PS_PPS	(1 << 8)	/* port power status */
+#define		RH_PS_LSDA	(1 << 9)	/* low speed device attached */
+#define		RH_PS_CSC	(1 << 16)	/* connect status change */
+#define		RH_PS_PESC	(1 << 17)	/* port enable status change */
+#define		RH_PS_PSSC	(1 << 18)	/* port suspend status
+						   change */
+#define		RH_PS_OCIC	(1 << 19)	/* over current indicator
+						   change */
+#define		RH_PS_PRSC	(1 << 20)	/* port reset status change */
+#define		HCRHPORT_CLRMASK	(0x1f << 16)
+#define	HCRHPORT2	0x16
+#define	HCHWCFG		0x20
+#define		HCHWCFG_15KRSEL		(1 << 12)
+#define		HCHWCFG_CLKNOTSTOP	(1 << 11)
+#define		HCHWCFG_ANALOG_OC	(1 << 10)
+#define		HCHWCFG_DACK_MODE	(1 << 8)
+#define		HCHWCFG_EOT_POL		(1 << 7)
+#define		HCHWCFG_DACK_POL	(1 << 6)
+#define		HCHWCFG_DREQ_POL	(1 << 5)
+#define		HCHWCFG_DBWIDTH_MASK	(0x03 << 3)
+#define		HCHWCFG_DBWIDTH(n)	(((n) << 3) & HCHWCFG_DBWIDTH_MASK)
+#define		HCHWCFG_INT_POL		(1 << 2)
+#define		HCHWCFG_INT_TRIGGER	(1 << 1)
+#define		HCHWCFG_INT_ENABLE	(1 << 0)
+#define	HCDMACFG	0x21
+#define		HCDMACFG_BURST_LEN_MASK	(0x03 << 5)
+#define		HCDMACFG_BURST_LEN(n)	(((n) << 5) & HCDMACFG_BURST_LEN_MASK)
+#define		HCDMACFG_BURST_LEN_1	HCDMACFG_BURST_LEN(0)
+#define		HCDMACFG_BURST_LEN_4	HCDMACFG_BURST_LEN(1)
+#define		HCDMACFG_BURST_LEN_8	HCDMACFG_BURST_LEN(2)
+#define		HCDMACFG_DMA_ENABLE	(1 << 4)
+#define		HCDMACFG_BUF_TYPE_MASK	(0x07 << 1)
+#define		HCDMACFG_CTR_SEL	(1 << 2)
+#define		HCDMACFG_ITLATL_SEL	(1 << 1)
+#define		HCDMACFG_DMA_RW_SELECT	(1 << 0)
+#define	HCXFERCTR	0x22
+#define	HCuPINT		0x24
+#define		HCuPINT_SOF		(1 << 0)
+#define		HCuPINT_ATL		(1 << 1)
+#define		HCuPINT_AIIEOT		(1 << 2)
+#define		HCuPINT_OPR		(1 << 4)
+#define		HCuPINT_SUSP		(1 << 5)
+#define		HCuPINT_CLKRDY		(1 << 6)
+#define	HCuPINTENB	0x25
+#define	HCCHIPID	0x27
+#define		HCCHIPID_MASK		0xff00
+#define		HCCHIPID_MAGIC		0x6100
+#define	HCSCRATCH	0x28
+#define	HCSWRES		0x29
+#define		HCSWRES_MAGIC		0x00f6
+#define	HCITLBUFLEN	0x2a
+#define	HCATLBUFLEN	0x2b
+#define	HCBUFSTAT	0x2c
+#define		HCBUFSTAT_ITL0_FULL	(1 << 0)
+#define		HCBUFSTAT_ITL1_FULL	(1 << 1)
+#define		HCBUFSTAT_ATL_FULL	(1 << 2)
+#define		HCBUFSTAT_ITL0_DONE	(1 << 3)
+#define		HCBUFSTAT_ITL1_DONE	(1 << 4)
+#define		HCBUFSTAT_ATL_DONE	(1 << 5)
+#define	HCRDITL0LEN	0x2d
+#define	HCRDITL1LEN	0x2e
+#define	HCITLPORT	0x40
+#define	HCATLPORT	0x41
+
+/* Philips transfer descriptor */
+struct ptd {
+	u16 count;
+#define	PTD_COUNT_MSK	(0x3ff << 0)
+#define	PTD_TOGGLE_MSK	(1 << 10)
+#define	PTD_ACTIVE_MSK	(1 << 11)
+#define	PTD_CC_MSK	(0xf << 12)
+	u16 mps;
+#define	PTD_MPS_MSK	(0x3ff << 0)
+#define	PTD_SPD_MSK	(1 << 10)
+#define	PTD_LAST_MSK	(1 << 11)
+#define	PTD_EP_MSK	(0xf << 12)
+	u16 len;
+#define	PTD_LEN_MSK	(0x3ff << 0)
+#define	PTD_DIR_MSK	(3 << 10)
+#define	PTD_DIR_SETUP	(0)
+#define	PTD_DIR_OUT	(1)
+#define	PTD_DIR_IN	(2)
+#define	PTD_B5_5_MSK	(1 << 13)
+	u16 faddr;
+#define	PTD_FA_MSK	(0x7f << 0)
+#define	PTD_FMT_MSK	(1 << 7)
+} __attribute__ ((packed, aligned(2)));
+
+/* PTD accessor macros. */
+#define PTD_GET_COUNT(p)	(((p)->count & PTD_COUNT_MSK) >> 0)
+#define PTD_COUNT(v)		(((v) << 0) & PTD_COUNT_MSK)
+#define PTD_GET_TOGGLE(p)	(((p)->count & PTD_TOGGLE_MSK) >> 10)
+#define PTD_TOGGLE(v)		(((v) << 10) & PTD_TOGGLE_MSK)
+#define PTD_GET_ACTIVE(p)	(((p)->count & PTD_ACTIVE_MSK) >> 11)
+#define PTD_ACTIVE(v)		(((v) << 11) & PTD_ACTIVE_MSK)
+#define PTD_GET_CC(p)		(((p)->count & PTD_CC_MSK) >> 12)
+#define PTD_CC(v)		(((v) << 12) & PTD_CC_MSK)
+#define PTD_GET_MPS(p)		(((p)->mps & PTD_MPS_MSK) >> 0)
+#define PTD_MPS(v)		(((v) << 0) & PTD_MPS_MSK)
+#define PTD_GET_SPD(p)		(((p)->mps & PTD_SPD_MSK) >> 10)
+#define PTD_SPD(v)		(((v) << 10) & PTD_SPD_MSK)
+#define PTD_GET_LAST(p)		(((p)->mps & PTD_LAST_MSK) >> 11)
+#define PTD_LAST(v)		(((v) << 11) & PTD_LAST_MSK)
+#define PTD_GET_EP(p)		(((p)->mps & PTD_EP_MSK) >> 12)
+#define PTD_EP(v)		(((v) << 12) & PTD_EP_MSK)
+#define PTD_GET_LEN(p)		(((p)->len & PTD_LEN_MSK) >> 0)
+#define PTD_LEN(v)		(((v) << 0) & PTD_LEN_MSK)
+#define PTD_GET_DIR(p)		(((p)->len & PTD_DIR_MSK) >> 10)
+#define PTD_DIR(v)		(((v) << 10) & PTD_DIR_MSK)
+#define PTD_GET_B5_5(p)		(((p)->len & PTD_B5_5_MSK) >> 13)
+#define PTD_B5_5(v)		(((v) << 13) & PTD_B5_5_MSK)
+#define PTD_GET_FA(p)		(((p)->faddr & PTD_FA_MSK) >> 0)
+#define PTD_FA(v)		(((v) << 0) & PTD_FA_MSK)
+#define PTD_GET_FMT(p)		(((p)->faddr & PTD_FMT_MSK) >> 7)
+#define PTD_FMT(v)		(((v) << 7) & PTD_FMT_MSK)
+
+/*  Hardware transfer status codes -- CC from ptd->count */
+#define TD_CC_NOERROR      0x00
+#define TD_CC_CRC          0x01
+#define TD_CC_BITSTUFFING  0x02
+#define TD_CC_DATATOGGLEM  0x03
+#define TD_CC_STALL        0x04
+#define TD_DEVNOTRESP      0x05
+#define TD_PIDCHECKFAIL    0x06
+#define TD_UNEXPECTEDPID   0x07
+#define TD_DATAOVERRUN     0x08
+#define TD_DATAUNDERRUN    0x09
+    /* 0x0A, 0x0B reserved for hardware */
+#define TD_BUFFEROVERRUN   0x0C
+#define TD_BUFFERUNDERRUN  0x0D
+    /* 0x0E, 0x0F reserved for HCD */
+#define TD_NOTACCESSED     0x0F
+
+/* map PTD status codes (CC) to errno values */
+static const int cc_to_error[16] = {
+	/* No  Error  */ 0,
+	/* CRC Error  */ -EILSEQ,
+	/* Bit Stuff  */ -EPROTO,
+	/* Data Togg  */ -EILSEQ,
+	/* Stall      */ -EPIPE,
+	/* DevNotResp */ -ETIMEDOUT,
+	/* PIDCheck   */ -EPROTO,
+	/* UnExpPID   */ -EPROTO,
+	/* DataOver   */ -EOVERFLOW,
+	/* DataUnder  */ -EREMOTEIO,
+	/* (for hw)   */ -EIO,
+	/* (for hw)   */ -EIO,
+	/* BufferOver */ -ECOMM,
+	/* BuffUnder  */ -ENOSR,
+	/* (for HCD)  */ -EALREADY,
+	/* (for HCD)  */ -EALREADY
+};
+
+/*--------------------------------------------------------------*/
+
+#define	LOG2_PERIODIC_SIZE	5	/* arbitrary; this matches OHCI */
+#define	PERIODIC_SIZE		(1 << LOG2_PERIODIC_SIZE)
+
+struct isp116x {
+	spinlock_t lock;
+	struct work_struct rh_resume;
+
+	void __iomem *addr_reg;
+	void __iomem *data_reg;
+
+	struct isp116x_platform_data *board;
+
+	struct proc_dir_entry *pde;
+	unsigned long stat1, stat2, stat4, stat8, stat16;
+
+	/* HC registers */
+	u32 intenb;		/* "OHCI" interrupts */
+	u16 irqenb;		/* uP interrupts */
+
+	/* Root hub registers */
+	u32 rhdesca;
+	u32 rhdescb;
+	u32 rhstatus;
+	u32 rhport[2];
+
+	/* async schedule: control, bulk */
+	struct list_head async;
+
+	/* periodic schedule: int */
+	u16 load[PERIODIC_SIZE];
+	struct isp116x_ep *periodic[PERIODIC_SIZE];
+	unsigned periodic_count;
+	u16 fmindex;
+
+	/* Schedule for the current frame */
+	struct isp116x_ep *atl_active;
+	int atl_buflen;
+	int atl_bufshrt;
+	int atl_last_dir;
+	atomic_t atl_finishing;
+};
+
+static inline struct isp116x *hcd_to_isp116x(struct usb_hcd *hcd)
+{
+	return (struct isp116x *)(hcd->hcd_priv);
+}
+
+static inline struct usb_hcd *isp116x_to_hcd(struct isp116x *isp116x)
+{
+	return container_of((void *)isp116x, struct usb_hcd, hcd_priv);
+}
+
+struct isp116x_ep {
+	struct usb_host_endpoint *hep;
+	struct usb_device *udev;
+	struct ptd ptd;
+
+	u8 maxpacket;
+	u8 epnum;
+	u8 nextpid;
+	u16 error_count;
+	u16 length;		/* of current packet */
+	unsigned char *data;	/* to databuf */
+	/* queue of active EP's (the ones scheduled for the
+	   current frame) */
+	struct isp116x_ep *active;
+
+	/* periodic schedule */
+	u16 period;
+	u16 branch;
+	u16 load;
+	struct isp116x_ep *next;
+
+	/* async schedule */
+	struct list_head schedule;
+};
+
+/*-------------------------------------------------------------------------*/
+
+#ifdef DEBUG
+#define DBG(stuff...)		printk(KERN_DEBUG "116x: " stuff)
+#else
+#define DBG(stuff...)		do{}while(0)
+#endif
+
+#ifdef VERBOSE
+#    define VDBG		DBG
+#else
+#    define VDBG(stuff...)	do{}while(0)
+#endif
+
+#define ERR(stuff...)		printk(KERN_ERR "116x: " stuff)
+#define WARN(stuff...)		printk(KERN_WARNING "116x: " stuff)
+#define INFO(stuff...)		printk(KERN_INFO "116x: " stuff)
+
+/* ------------------------------------------------- */
+
+#if defined(USE_PLATFORM_DELAY)
+#if defined(USE_NDELAY)
+#error USE_PLATFORM_DELAY and USE_NDELAY simultaneously defined.
+#endif
+#define	isp116x_delay(h,d)	(h)->board->delay(	\
+				isp116x_to_hcd(h)->self.controller,d)
+#define isp116x_check_platform_delay(h)	((h)->board->delay == NULL)
+#elif defined(USE_NDELAY)
+#define	isp116x_delay(h,d)	ndelay(d)
+#define isp116x_check_platform_delay(h)	0
+#else
+#define	isp116x_delay(h,d)	do{}while(0)
+#define isp116x_check_platform_delay(h)	0
+#endif
+
+#if defined(DEBUG)
+#define	IRQ_TEST()	BUG_ON(!irqs_disabled())
+#else
+#define	IRQ_TEST()	do{}while(0)
+#endif
+
+static inline void isp116x_write_addr(struct isp116x *isp116x, unsigned reg)
+{
+	IRQ_TEST();
+	writew(reg & 0xff, isp116x->addr_reg);
+	isp116x_delay(isp116x, 300);
+}
+
+static inline void isp116x_write_data16(struct isp116x *isp116x, u16 val)
+{
+	writew(val, isp116x->data_reg);
+	isp116x_delay(isp116x, 150);
+}
+
+static inline void isp116x_raw_write_data16(struct isp116x *isp116x, u16 val)
+{
+	__raw_writew(val, isp116x->data_reg);
+	isp116x_delay(isp116x, 150);
+}
+
+static inline u16 isp116x_read_data16(struct isp116x *isp116x)
+{
+	u16 val;
+
+	val = readw(isp116x->data_reg);
+	isp116x_delay(isp116x, 150);
+	return val;
+}
+
+static inline u16 isp116x_raw_read_data16(struct isp116x *isp116x)
+{
+	u16 val;
+
+	val = __raw_readw(isp116x->data_reg);
+	isp116x_delay(isp116x, 150);
+	return val;
+}
+
+static inline void isp116x_write_data32(struct isp116x *isp116x, u32 val)
+{
+	writew(val & 0xffff, isp116x->data_reg);
+	isp116x_delay(isp116x, 150);
+	writew(val >> 16, isp116x->data_reg);
+	isp116x_delay(isp116x, 150);
+}
+
+static inline u32 isp116x_read_data32(struct isp116x *isp116x)
+{
+	u32 val;
+
+	val = (u32) readw(isp116x->data_reg);
+	isp116x_delay(isp116x, 150);
+	val |= ((u32) readw(isp116x->data_reg)) << 16;
+	isp116x_delay(isp116x, 150);
+	return val;
+}
+
+/* Let's keep register access functions out of line. Hint:
+   we wait at least 150 ns at every access.
+*/
+static u16 isp116x_read_reg16(struct isp116x *isp116x, unsigned reg)
+{
+	isp116x_write_addr(isp116x, reg);
+	return isp116x_read_data16(isp116x);
+}
+
+static u32 isp116x_read_reg32(struct isp116x *isp116x, unsigned reg)
+{
+	isp116x_write_addr(isp116x, reg);
+	return isp116x_read_data32(isp116x);
+}
+
+static void isp116x_write_reg16(struct isp116x *isp116x, unsigned reg,
+				unsigned val)
+{
+	isp116x_write_addr(isp116x, reg | ISP116x_WRITE_OFFSET);
+	isp116x_write_data16(isp116x, (u16) (val & 0xffff));
+}
+
+static void isp116x_write_reg32(struct isp116x *isp116x, unsigned reg,
+				unsigned val)
+{
+	isp116x_write_addr(isp116x, reg | ISP116x_WRITE_OFFSET);
+	isp116x_write_data32(isp116x, (u32) val);
+}
+
+#define isp116x_show_reg(d,r) {					\
+	if ((r) < 0x20) {			                \
+		DBG("%-12s[%02x]: %08x\n", #r,			\
+			r, isp116x_read_reg32(d, r));		\
+	} else {						\
+		DBG("%-12s[%02x]:     %04x\n", #r,		\
+			r, isp116x_read_reg16(d, r));	    	\
+	}							\
+}
+
+static inline void isp116x_show_regs(struct isp116x *isp116x)
+{
+	isp116x_show_reg(isp116x, HCREVISION);
+	isp116x_show_reg(isp116x, HCCONTROL);
+	isp116x_show_reg(isp116x, HCCMDSTAT);
+	isp116x_show_reg(isp116x, HCINTSTAT);
+	isp116x_show_reg(isp116x, HCINTENB);
+	isp116x_show_reg(isp116x, HCFMINTVL);
+	isp116x_show_reg(isp116x, HCFMREM);
+	isp116x_show_reg(isp116x, HCFMNUM);
+	isp116x_show_reg(isp116x, HCLSTHRESH);
+	isp116x_show_reg(isp116x, HCRHDESCA);
+	isp116x_show_reg(isp116x, HCRHDESCB);
+	isp116x_show_reg(isp116x, HCRHSTATUS);
+	isp116x_show_reg(isp116x, HCRHPORT1);
+	isp116x_show_reg(isp116x, HCRHPORT2);
+	isp116x_show_reg(isp116x, HCHWCFG);
+	isp116x_show_reg(isp116x, HCDMACFG);
+	isp116x_show_reg(isp116x, HCXFERCTR);
+	isp116x_show_reg(isp116x, HCuPINT);
+	isp116x_show_reg(isp116x, HCuPINTENB);
+	isp116x_show_reg(isp116x, HCCHIPID);
+	isp116x_show_reg(isp116x, HCSCRATCH);
+	isp116x_show_reg(isp116x, HCITLBUFLEN);
+	isp116x_show_reg(isp116x, HCATLBUFLEN);
+	isp116x_show_reg(isp116x, HCBUFSTAT);
+	isp116x_show_reg(isp116x, HCRDITL0LEN);
+	isp116x_show_reg(isp116x, HCRDITL1LEN);
+}
+
+#if defined(URB_TRACE)
+
+#define PIPETYPE(pipe)  ({ char *__s;			\
+	if (usb_pipecontrol(pipe))	__s = "ctrl";	\
+	else if (usb_pipeint(pipe))	__s = "int";	\
+	else if (usb_pipebulk(pipe))	__s = "bulk";	\
+	else				__s = "iso";	\
+	__s;})
+#define PIPEDIR(pipe)   ({ usb_pipein(pipe) ? "in" : "out"; })
+#define URB_NOTSHORT(urb) ({ (urb)->transfer_flags & URB_SHORT_NOT_OK ? \
+	"short_not_ok" : ""; })
+
+/* print debug info about the URB */
+static void urb_dbg(struct urb *urb, char *msg)
+{
+	unsigned int pipe;
+
+	if (!urb) {
+		DBG("%s: zero urb\n", msg);
+		return;
+	}
+	pipe = urb->pipe;
+	DBG("%s: FA %d ep%d%s %s: len %d/%d %s\n", msg,
+	    usb_pipedevice(pipe), usb_pipeendpoint(pipe),
+	    PIPEDIR(pipe), PIPETYPE(pipe),
+	    urb->transfer_buffer_length, urb->actual_length, URB_NOTSHORT(urb));
+}
+
+#else
+
+#define  urb_dbg(urb,msg)   do{}while(0)
+
+#endif				/* ! defined(URB_TRACE) */
+
+#if defined(PTD_TRACE)
+
+#define PTD_DIR_STR(ptd)  ({char __c;		\
+	switch(PTD_GET_DIR(ptd)){		\
+	case 0:  __c = 's'; break;		\
+	case 1:  __c = 'o'; break;		\
+	default: __c = 'i'; break;		\
+	}; __c;})
+
+/*
+  Dump PTD info. The code documents the format
+  perfectly, right :)
+*/
+static inline void dump_ptd(struct ptd *ptd)
+{
+	printk("td: %x %d%c%d %d,%d,%d  %x %x%x%x\n",
+	       PTD_GET_CC(ptd), PTD_GET_FA(ptd),
+	       PTD_DIR_STR(ptd), PTD_GET_EP(ptd),
+	       PTD_GET_COUNT(ptd), PTD_GET_LEN(ptd), PTD_GET_MPS(ptd),
+	       PTD_GET_TOGGLE(ptd), PTD_GET_ACTIVE(ptd),
+	       PTD_GET_SPD(ptd), PTD_GET_LAST(ptd));
+}
+
+static inline void dump_ptd_out_data(struct ptd *ptd, u8 * buf)
+{
+	int k;
+
+	if (PTD_GET_DIR(ptd) != PTD_DIR_IN && PTD_GET_LEN(ptd)) {
+		printk("-> ");
+		for (k = 0; k < PTD_GET_LEN(ptd); ++k)
+			printk("%02x ", ((u8 *) buf)[k]);
+		printk("\n");
+	}
+}
+
+static inline void dump_ptd_in_data(struct ptd *ptd, u8 * buf)
+{
+	int k;
+
+	if (PTD_GET_DIR(ptd) == PTD_DIR_IN && PTD_GET_COUNT(ptd)) {
+		printk("<- ");
+		for (k = 0; k < PTD_GET_COUNT(ptd); ++k)
+			printk("%02x ", ((u8 *) buf)[k]);
+		printk("\n");
+	}
+	if (PTD_GET_LAST(ptd))
+		printk("-\n");
+}
+
+#else
+
+#define dump_ptd(ptd)               do{}while(0)
+#define dump_ptd_in_data(ptd,buf)   do{}while(0)
+#define dump_ptd_out_data(ptd,buf)  do{}while(0)
+
+#endif				/* ! defined(PTD_TRACE) */
diff --git a/drivers/usb/host/ohci-dbg.c b/drivers/usb/host/ohci-dbg.c
--- a/drivers/usb/host/ohci-dbg.c
+++ b/drivers/usb/host/ohci-dbg.c
@@ -481,7 +481,7 @@ show_async (struct class_device *class_d
 	size_t			temp;
 	unsigned long		flags;
 
-	bus = to_usb_bus(class_dev);
+	bus = class_get_devdata(class_dev);
 	hcd = bus->hcpriv;
 	ohci = hcd_to_ohci(hcd);
 
@@ -514,7 +514,7 @@ show_periodic (struct class_device *clas
 		return 0;
 	seen_count = 0;
 
-	bus = to_usb_bus(class_dev);
+	bus = class_get_devdata(class_dev);
 	hcd = bus->hcpriv;
 	ohci = hcd_to_ohci(hcd);
 	next = buf;
@@ -611,7 +611,7 @@ show_registers (struct class_device *cla
 	char			*next;
 	u32			rdata;
 
-	bus = to_usb_bus(class_dev);
+	bus = class_get_devdata(class_dev);
 	hcd = bus->hcpriv;
 	ohci = hcd_to_ohci(hcd);
 	regs = ohci->regs;
@@ -684,7 +684,7 @@ static CLASS_DEVICE_ATTR (registers, S_I
 
 static inline void create_debug_files (struct ohci_hcd *ohci)
 {
-	struct class_device *cldev = &ohci_to_hcd(ohci)->self.class_dev;
+	struct class_device *cldev = ohci_to_hcd(ohci)->self.class_dev;
 
 	class_device_create_file(cldev, &class_device_attr_async);
 	class_device_create_file(cldev, &class_device_attr_periodic);
@@ -694,7 +694,7 @@ static inline void create_debug_files (s
 
 static inline void remove_debug_files (struct ohci_hcd *ohci)
 {
-	struct class_device *cldev = &ohci_to_hcd(ohci)->self.class_dev;
+	struct class_device *cldev = ohci_to_hcd(ohci)->self.class_dev;
 
 	class_device_remove_file(cldev, &class_device_attr_async);
 	class_device_remove_file(cldev, &class_device_attr_periodic);
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -95,12 +95,11 @@
 #include <linux/init.h>
 #include <linux/timer.h>
 #include <linux/list.h>
-#include <linux/interrupt.h>  /* for in_interrupt () */
 #include <linux/usb.h>
 #include <linux/usb_otg.h>
-#include "../core/hcd.h"
 #include <linux/dma-mapping.h> 
-#include <linux/dmapool.h>    /* needed by ohci-mem.c when no PCI */
+#include <linux/dmapool.h>
+#include <linux/reboot.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
@@ -108,8 +107,9 @@
 #include <asm/unaligned.h>
 #include <asm/byteorder.h>
 
+#include "../core/hcd.h"
 
-#define DRIVER_VERSION "2004 Nov 08"
+#define DRIVER_VERSION "2005 April 22"
 #define DRIVER_AUTHOR "Roman Weissgaerber, David Brownell"
 #define DRIVER_DESC "USB 1.1 'Open' Host Controller (OHCI) Driver"
 
@@ -141,6 +141,7 @@ static const char	hcd_name [] = "ohci_hc
 static void ohci_dump (struct ohci_hcd *ohci, int verbose);
 static int ohci_init (struct ohci_hcd *ohci);
 static void ohci_stop (struct usb_hcd *hcd);
+static int ohci_reboot (struct notifier_block *, unsigned long , void *);
 
 #include "ohci-hub.c"
 #include "ohci-dbg.c"
@@ -179,7 +180,7 @@ static int ohci_urb_enqueue (
 	struct usb_hcd	*hcd,
 	struct usb_host_endpoint *ep,
 	struct urb	*urb,
-	int		mem_flags
+	unsigned	mem_flags
 ) {
 	struct ohci_hcd	*ohci = hcd_to_ohci (hcd);
 	struct ed	*ed;
@@ -420,6 +421,23 @@ static void ohci_usb_reset (struct ohci_
 	ohci_writel (ohci, ohci->hc_control, &ohci->regs->control);
 }
 
+/* reboot notifier forcibly disables IRQs and DMA, helping kexec and
+ * other cases where the next software may expect clean state from the
+ * "firmware".  this is bus-neutral, unlike shutdown() methods.
+ */
+static int
+ohci_reboot (struct notifier_block *block, unsigned long code, void *null)
+{
+	struct ohci_hcd *ohci;
+
+	ohci = container_of (block, struct ohci_hcd, reboot_notifier);
+	ohci_writel (ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable);
+	ohci_usb_reset (ohci);
+	/* flush the writes */
+	(void) ohci_readl (ohci, &ohci->regs->control);
+	return 0;
+}
+
 /*-------------------------------------------------------------------------*
  * HC functions
  *-------------------------------------------------------------------------*/
@@ -487,13 +505,10 @@ static int ohci_init (struct ohci_hcd *o
 /* Start an OHCI controller, set the BUS operational
  * resets USB and controller
  * enable interrupts 
- * connect the virtual root hub
  */
 static int ohci_run (struct ohci_hcd *ohci)
 {
   	u32			mask, temp;
-  	struct usb_device	*udev;
-  	struct usb_bus		*bus;
 	int			first = ohci->fminterval == 0;
 
 	disable (ohci);
@@ -654,37 +669,15 @@ retry:
 
 	// POTPGT delay is bits 24-31, in 2 ms units.
 	mdelay ((temp >> 23) & 0x1fe);
-	bus = &ohci_to_hcd(ohci)->self;
 	ohci_to_hcd(ohci)->state = HC_STATE_RUNNING;
 
 	ohci_dump (ohci, 1);
 
-	udev = bus->root_hub;
-	if (udev) {
-		return 0;
-	}
- 
-	/* connect the virtual root hub */
-	udev = usb_alloc_dev (NULL, bus, 0);
-	if (!udev) {
-		disable (ohci);
-		ohci->hc_control &= ~OHCI_CTRL_HCFS;
-		ohci_writel (ohci, ohci->hc_control, &ohci->regs->control);
-		return -ENOMEM;
+	if (ohci_to_hcd(ohci)->self.root_hub == NULL) {
+		register_reboot_notifier (&ohci->reboot_notifier);
+		create_debug_files (ohci);
 	}
 
-	udev->speed = USB_SPEED_FULL;
-	if (usb_hcd_register_root_hub (udev, ohci_to_hcd(ohci)) != 0) {
-		usb_put_dev (udev);
-		disable (ohci);
-		ohci->hc_control &= ~OHCI_CTRL_HCFS;
-		ohci_writel (ohci, ohci->hc_control, &ohci->regs->control);
-		return -ENODEV;
-	}
-	if (ohci->power_budget)
-		hub_set_power_budget(udev, ohci->power_budget);
-
-	create_debug_files (ohci);
 	return 0;
 }
 
@@ -781,6 +774,7 @@ static void ohci_stop (struct usb_hcd *h
 	ohci_writel (ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable);
 	
 	remove_debug_files (ohci);
+	unregister_reboot_notifier (&ohci->reboot_notifier);
 	ohci_mem_cleanup (ohci);
 	if (ohci->hcca) {
 		dma_free_coherent (hcd->self.controller, 
@@ -893,6 +887,10 @@ MODULE_LICENSE ("GPL");
 #include "ohci-sa1111.c"
 #endif
 
+#ifdef CONFIG_ARCH_S3C2410
+#include "ohci-s3c2410.c"
+#endif
+
 #ifdef CONFIG_ARCH_OMAP
 #include "ohci-omap.c"
 #endif
@@ -915,6 +913,7 @@ MODULE_LICENSE ("GPL");
 
 #if !(defined(CONFIG_PCI) \
       || defined(CONFIG_SA1111) \
+      || defined(CONFIG_ARCH_S3C2410) \
       || defined(CONFIG_ARCH_OMAP) \
       || defined (CONFIG_ARCH_LH7A404) \
       || defined (CONFIG_PXA27x) \
diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c
--- a/drivers/usb/host/ohci-hub.c
+++ b/drivers/usb/host/ohci-hub.c
@@ -419,10 +419,11 @@ ohci_hub_descriptor (
 
 	/* two bitmaps:  ports removable, and usb 1.0 legacy PortPwrCtrlMask */
 	rh = roothub_b (ohci);
+	memset(desc->bitmap, 0xff, sizeof(desc->bitmap));
 	desc->bitmap [0] = rh & RH_B_DR;
 	if (ports > 7) {
 		desc->bitmap [1] = (rh & RH_B_DR) >> 8;
-		desc->bitmap [2] = desc->bitmap [3] = 0xff;
+		desc->bitmap [2] = 0xff;
 	} else
 		desc->bitmap [1] = 0xff;
 }
diff --git a/drivers/usb/host/ohci-mem.c b/drivers/usb/host/ohci-mem.c
--- a/drivers/usb/host/ohci-mem.c
+++ b/drivers/usb/host/ohci-mem.c
@@ -29,6 +29,7 @@ static void ohci_hcd_init (struct ohci_h
 	spin_lock_init (&ohci->lock);
 	INIT_LIST_HEAD (&ohci->pending);
 	INIT_WORK (&ohci->rh_resume, ohci_rh_resume, ohci_to_hcd(ohci));
+	ohci->reboot_notifier.notifier_call = ohci_reboot;
 }
 
 /*-------------------------------------------------------------------------*/
@@ -83,7 +84,7 @@ dma_to_td (struct ohci_hcd *hc, dma_addr
 
 /* TDs ... */
 static struct td *
-td_alloc (struct ohci_hcd *hc, int mem_flags)
+td_alloc (struct ohci_hcd *hc, unsigned mem_flags)
 {
 	dma_addr_t	dma;
 	struct td	*td;
@@ -117,7 +118,7 @@ td_free (struct ohci_hcd *hc, struct td 
 
 /* EDs ... */
 static struct ed *
-ed_alloc (struct ohci_hcd *hc, int mem_flags)
+ed_alloc (struct ohci_hcd *hc, unsigned mem_flags)
 {
 	dma_addr_t	dma;
 	struct ed	*ed;
diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c
--- a/drivers/usb/host/ohci-omap.c
+++ b/drivers/usb/host/ohci-omap.c
@@ -181,7 +181,7 @@ static int omap_start_hc(struct ohci_hcd
 	if (config->otg) {
 		ohci_to_hcd(ohci)->self.otg_port = config->otg;
 		/* default/minimum OTG power budget:  8 mA */
-		ohci->power_budget = 8;
+		ohci_to_hcd(ohci)->power_budget = 8;
 	}
 
 	/* boards can use OTG transceivers in non-OTG modes */
@@ -230,7 +230,7 @@ static int omap_start_hc(struct ohci_hcd
 
 		/* TPS2045 switch for internal transceiver (port 1) */
 		if (machine_is_omap_osk()) {
-			ohci->power_budget = 250;
+			ohci_to_hcd(ohci)->power_budget = 250;
 
 			rh &= ~RH_A_NOCP;
 
@@ -456,34 +456,22 @@ static int ohci_hcd_omap_drv_remove(stru
 
 #ifdef	CONFIG_PM
 
-/* states match PCI usage, always suspending the root hub except that
- * 4 ~= D3cold (ACPI D3) with clock off (resume sees reset).
- *
- * FIXME: above comment is not right, and code is wrong, too :-(.
- */
-
-static int ohci_omap_suspend(struct device *dev, pm_message_t state, u32 level)
+static int ohci_omap_suspend(struct device *dev, pm_message_t message, u32 level)
 {
 	struct ohci_hcd	*ohci = hcd_to_ohci(dev_get_drvdata(dev));
 	int		status = -EINVAL;
 
 	if (level != SUSPEND_POWER_DOWN)
 		return 0;
-	if (state <= dev->power.power_state)
-		return 0;
 
-	dev_dbg(dev, "suspend to %d\n", state);
 	down(&ohci_to_hcd(ohci)->self.root_hub->serialize);
 	status = ohci_hub_suspend(ohci_to_hcd(ohci));
 	if (status == 0) {
-		if (state >= 4) {
-			omap_ohci_clock_power(0);
-			ohci_to_hcd(ohci)->self.root_hub->state =
-					USB_STATE_SUSPENDED;
-			state = 4;
-		}
+		omap_ohci_clock_power(0);
+		ohci_to_hcd(ohci)->self.root_hub->state =
+			USB_STATE_SUSPENDED;
 		ohci_to_hcd(ohci)->state = HC_STATE_SUSPENDED;
-		dev->power.power_state = state;
+		dev->power.power_state = PMSG_SUSPEND;
 	}
 	up(&ohci_to_hcd(ohci)->self.root_hub->serialize);
 	return status;
@@ -497,29 +485,20 @@ static int ohci_omap_resume(struct devic
 	if (level != RESUME_POWER_ON)
 		return 0;
 
-	switch (dev->power.power_state) {
-	case 0:
-		break;
-	case 4:
-		if (time_before(jiffies, ohci->next_statechange))
-			msleep(5);
-		ohci->next_statechange = jiffies;
-		omap_ohci_clock_power(1);
-		/* FALLTHROUGH */
-	default:
-		dev_dbg(dev, "resume from %d\n", dev->power.power_state);
+	if (time_before(jiffies, ohci->next_statechange))
+		msleep(5);
+	ohci->next_statechange = jiffies;
+	omap_ohci_clock_power(1);
 #ifdef	CONFIG_USB_SUSPEND
-		/* get extra cleanup even if remote wakeup isn't in use */
-		status = usb_resume_device(ohci_to_hcd(ohci)->self.root_hub);
+	/* get extra cleanup even if remote wakeup isn't in use */
+	status = usb_resume_device(ohci_to_hcd(ohci)->self.root_hub);
 #else
-		down(&ohci_to_hcd(ohci)->self.root_hub->serialize);
-		status = ohci_hub_resume(ohci_to_hcd(ohci));
-		up(&ohci_to_hcd(ohci)->self.root_hub->serialize);
+	down(&ohci_to_hcd(ohci)->self.root_hub->serialize);
+	status = ohci_hub_resume(ohci_to_hcd(ohci));
+	up(&ohci_to_hcd(ohci)->self.root_hub->serialize);
 #endif
-		if (status == 0)
-			dev->power.power_state = 0;
-		break;
-	}
+	if (status == 0)
+		dev->power.power_state = PMSG_ON;
 	return status;
 }
 
diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c
--- a/drivers/usb/host/ohci-pci.c
+++ b/drivers/usb/host/ohci-pci.c
@@ -14,14 +14,11 @@
  * This file is licenced under the GPL.
  */
  
-#ifdef CONFIG_PMAC_PBOOK
+#ifdef CONFIG_PPC_PMAC
 #include <asm/machdep.h>
 #include <asm/pmac_feature.h>
 #include <asm/pci-bridge.h>
 #include <asm/prom.h>
-#ifndef CONFIG_PM
-#	define CONFIG_PM
-#endif
 #endif
 
 #ifndef CONFIG_PCI
@@ -132,7 +129,7 @@ static int ohci_pci_suspend (struct usb_
 	/* let things settle down a bit */
 	msleep (100);
 	
-#ifdef CONFIG_PMAC_PBOOK
+#ifdef CONFIG_PPC_PMAC
 	if (_machine == _MACH_Pmac) {
 	   	struct device_node	*of_node;
  
@@ -141,7 +138,7 @@ static int ohci_pci_suspend (struct usb_
 		if (of_node)
 			pmac_call_feature(PMAC_FTR_USB_ENABLE, of_node, 0, 0);
 	}
-#endif /* CONFIG_PMAC_PBOOK */
+#endif /* CONFIG_PPC_PMAC */
 	return 0;
 }
 
@@ -151,7 +148,7 @@ static int ohci_pci_resume (struct usb_h
 	struct ohci_hcd		*ohci = hcd_to_ohci (hcd);
 	int			retval = 0;
 
-#ifdef CONFIG_PMAC_PBOOK
+#ifdef CONFIG_PPC_PMAC
 	if (_machine == _MACH_Pmac) {
 		struct device_node *of_node;
 
@@ -160,7 +157,7 @@ static int ohci_pci_resume (struct usb_h
 		if (of_node)
 			pmac_call_feature (PMAC_FTR_USB_ENABLE, of_node, 0, 1);
 	}
-#endif /* CONFIG_PMAC_PBOOK */
+#endif /* CONFIG_PPC_PMAC */
 
 	/* resume root hub */
 	if (time_before (jiffies, ohci->next_statechange))
diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c
new file mode 100644
--- /dev/null
+++ b/drivers/usb/host/ohci-s3c2410.c
@@ -0,0 +1,496 @@
+/*
+ * OHCI HCD (Host Controller Driver) for USB.
+ *
+ * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
+ * (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net>
+ * (C) Copyright 2002 Hewlett-Packard Company
+ *
+ * USB Bus Glue for Samsung S3C2410
+ *
+ * Written by Christopher Hoover <ch@hpl.hp.com>
+ * Based on fragments of previous driver by Rusell King et al.
+ *
+ * Modified for S3C2410 from ohci-sa1111.c, ohci-omap.c and ohci-lh7a40.c
+ *	by Ben Dooks, <ben@simtec.co.uk>
+ *	Copyright (C) 2004 Simtec Electronics
+ *
+ * Thanks to basprog@mail.ru for updates to newer kernels
+ *
+ * This file is licenced under the GPL.
+*/
+
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/hardware/clock.h>
+#include <asm/arch/usb-control.h>
+
+#define valid_port(idx) ((idx) == 1 || (idx) == 2)
+
+/* clock device associated with the hcd */
+
+static struct clk *clk;
+
+/* forward definitions */
+
+static void s3c2410_hcd_oc(struct s3c2410_hcd_info *info, int port_oc);
+
+/* conversion functions */
+
+struct s3c2410_hcd_info *to_s3c2410_info(struct usb_hcd *hcd)
+{
+	return hcd->self.controller->platform_data;
+}
+
+static void s3c2410_start_hc(struct platform_device *dev, struct usb_hcd *hcd)
+{
+	struct s3c2410_hcd_info *info = dev->dev.platform_data;
+
+	dev_dbg(&dev->dev, "s3c2410_start_hc:\n");
+	clk_enable(clk);
+
+	if (info != NULL) {
+		info->hcd	= hcd;
+		info->report_oc = s3c2410_hcd_oc;
+
+		if (info->enable_oc != NULL) {
+			(info->enable_oc)(info, 1);
+		}
+	}
+}
+
+static void s3c2410_stop_hc(struct platform_device *dev)
+{
+	struct s3c2410_hcd_info *info = dev->dev.platform_data;
+
+	dev_dbg(&dev->dev, "s3c2410_stop_hc:\n");
+
+	if (info != NULL) {
+		info->report_oc = NULL;
+		info->hcd	= NULL;
+
+		if (info->enable_oc != NULL) {
+			(info->enable_oc)(info, 0);
+		}
+	}
+
+	clk_disable(clk);
+}
+
+/* ohci_s3c2410_hub_status_data
+ *
+ * update the status data from the hub with anything that
+ * has been detected by our system
+*/
+
+static int
+ohci_s3c2410_hub_status_data (struct usb_hcd *hcd, char *buf)
+{
+	struct s3c2410_hcd_info *info = to_s3c2410_info(hcd);
+	struct s3c2410_hcd_port *port;
+	int orig;
+	int portno;
+
+	orig  = ohci_hub_status_data (hcd, buf);
+
+	if (info == NULL)
+		return orig;
+
+	port = &info->port[0];
+
+	/* mark any changed port as changed */
+
+	for (portno = 0; portno < 2; port++, portno++) {
+		if (port->oc_changed == 1 &&
+		    port->flags & S3C_HCDFLG_USED) {
+			dev_dbg(hcd->self.controller,
+				"oc change on port %d\n", portno);
+
+			if (orig < 1)
+				orig = 1;
+
+			buf[0] |= 1<<(portno+1);
+		}
+	}
+
+	return orig;
+}
+
+/* s3c2410_usb_set_power
+ *
+ * configure the power on a port, by calling the platform device
+ * routine registered with the platform device
+*/
+
+static void s3c2410_usb_set_power(struct s3c2410_hcd_info *info,
+				  int port, int to)
+{
+	if (info == NULL)
+		return;
+
+	if (info->power_control != NULL) {
+		info->port[port-1].power = to;
+		(info->power_control)(port, to);
+	}
+}
+
+/* ohci_s3c2410_hub_control
+ *
+ * look at control requests to the hub, and see if we need
+ * to take any action or over-ride the results from the
+ * request.
+*/
+
+static int ohci_s3c2410_hub_control (
+	struct usb_hcd	*hcd,
+	u16		typeReq,
+	u16		wValue,
+	u16		wIndex,
+	char		*buf,
+	u16		wLength)
+{
+	struct s3c2410_hcd_info *info = to_s3c2410_info(hcd);
+	struct usb_hub_descriptor *desc;
+	int ret = -EINVAL;
+	u32 *data = (u32 *)buf;
+
+	dev_dbg(hcd->self.controller,
+		"s3c2410_hub_control(%p,0x%04x,0x%04x,0x%04x,%p,%04x)\n",
+		hcd, typeReq, wValue, wIndex, buf, wLength);
+
+	/* if we are only an humble host without any special capabilites
+	 * process the request straight away and exit */
+
+	if (info == NULL) {
+		ret = ohci_hub_control(hcd, typeReq, wValue,
+				       wIndex, buf, wLength);
+		goto out;
+	}
+
+	/* check the request to see if it needs handling */
+
+	switch (typeReq) {
+	case SetPortFeature:
+		if (wValue == USB_PORT_FEAT_POWER) {
+			dev_dbg(hcd->self.controller, "SetPortFeat: POWER\n");
+			s3c2410_usb_set_power(info, wIndex, 1);
+			goto out;
+		}
+		break;
+
+	case ClearPortFeature:
+		switch (wValue) {
+		case USB_PORT_FEAT_C_OVER_CURRENT:
+			dev_dbg(hcd->self.controller,
+				"ClearPortFeature: C_OVER_CURRENT\n");
+
+			if (valid_port(wIndex)) {
+				info->port[wIndex-1].oc_changed = 0;
+				info->port[wIndex-1].oc_status = 0;
+			}
+
+			goto out;
+
+		case USB_PORT_FEAT_OVER_CURRENT:
+			dev_dbg(hcd->self.controller,
+				"ClearPortFeature: OVER_CURRENT\n");
+
+			if (valid_port(wIndex)) {
+				info->port[wIndex-1].oc_status = 0;
+			}
+
+			goto out;
+
+		case USB_PORT_FEAT_POWER:
+			dev_dbg(hcd->self.controller,
+				"ClearPortFeature: POWER\n");
+
+			if (valid_port(wIndex)) {
+				s3c2410_usb_set_power(info, wIndex, 0);
+				return 0;
+			}
+		}
+		break;
+	}
+
+	ret = ohci_hub_control(hcd, typeReq, wValue, wIndex, buf, wLength);
+	if (ret)
+		goto out;
+
+	switch (typeReq) {
+	case GetHubDescriptor:
+
+		/* update the hub's descriptor */
+
+		desc = (struct usb_hub_descriptor *)buf;
+
+		if (info->power_control == NULL)
+			return ret;
+
+		dev_dbg(hcd->self.controller, "wHubCharacteristics 0x%04x\n",
+			desc->wHubCharacteristics);
+
+		/* remove the old configurations for power-switching, and
+		 * over-current protection, and insert our new configuration
+		 */
+
+		desc->wHubCharacteristics &= ~cpu_to_le16(HUB_CHAR_LPSM);
+		desc->wHubCharacteristics |= cpu_to_le16(0x0001);
+
+		if (info->enable_oc) {
+			desc->wHubCharacteristics &= ~cpu_to_le16(HUB_CHAR_OCPM);
+			desc->wHubCharacteristics |=  cpu_to_le16(0x0008|0x0001);
+		}
+
+		dev_dbg(hcd->self.controller, "wHubCharacteristics after 0x%04x\n",
+			desc->wHubCharacteristics);
+
+		return ret;
+
+	case GetPortStatus:
+		/* check port status */
+
+		dev_dbg(hcd->self.controller, "GetPortStatus(%d)\n", wIndex);
+
+		if (valid_port(wIndex)) {
+			if (info->port[wIndex-1].oc_changed) {
+				*data |= cpu_to_le32(RH_PS_OCIC);
+			}
+
+			if (info->port[wIndex-1].oc_status) {
+				*data |= cpu_to_le32(RH_PS_POCI);
+			}
+		}
+	}
+
+ out:
+	return ret;
+}
+
+/* s3c2410_hcd_oc
+ *
+ * handle an over-current report
+*/
+
+static void s3c2410_hcd_oc(struct s3c2410_hcd_info *info, int port_oc)
+{
+	struct s3c2410_hcd_port *port;
+	struct usb_hcd *hcd;
+	unsigned long flags;
+	int portno;
+
+	if (info == NULL)
+		return;
+
+	port = &info->port[0];
+	hcd = info->hcd;
+
+	local_irq_save(flags);
+
+	for (portno = 0; portno < 2; port++, portno++) {
+		if (port_oc & (1<<portno) &&
+		    port->flags & S3C_HCDFLG_USED) {
+			port->oc_status = 1;
+			port->oc_changed = 1;
+
+			/* ok, once over-current is detected,
+			   the port needs to be powered down */
+			s3c2410_usb_set_power(info, portno+1, 0);
+		}
+	}
+
+	local_irq_restore(flags);
+}
+
+/* may be called without controller electrically present */
+/* may be called with controller, bus, and devices active */
+
+/*
+ * usb_hcd_s3c2410_remove - shutdown processing for HCD
+ * @dev: USB Host Controller being removed
+ * Context: !in_interrupt()
+ *
+ * Reverses the effect of usb_hcd_3c2410_probe(), first invoking
+ * the HCD's stop() method.  It is always called from a thread
+ * context, normally "rmmod", "apmd", or something similar.
+ *
+*/
+
+void usb_hcd_s3c2410_remove (struct usb_hcd *hcd, struct platform_device *dev)
+{
+	usb_remove_hcd(hcd);
+	s3c2410_stop_hc(dev);
+	iounmap(hcd->regs);
+	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+	usb_put_hcd(hcd);
+}
+
+/**
+ * usb_hcd_s3c2410_probe - initialize S3C2410-based HCDs
+ * Context: !in_interrupt()
+ *
+ * Allocates basic resources for this USB host controller, and
+ * then invokes the start() method for the HCD associated with it
+ * through the hotplug entry's driver_data.
+ *
+ */
+int usb_hcd_s3c2410_probe (const struct hc_driver *driver,
+			   struct platform_device *dev)
+{
+	struct usb_hcd *hcd = NULL;
+	int retval;
+
+	s3c2410_usb_set_power(dev->dev.platform_data, 0, 1);
+	s3c2410_usb_set_power(dev->dev.platform_data, 1, 1);
+
+	hcd = usb_create_hcd(driver, &dev->dev, "s3c24xx");
+	if (hcd == NULL)
+		return -ENOMEM;
+
+	hcd->rsrc_start = dev->resource[0].start;
+	hcd->rsrc_len   = dev->resource[0].end - dev->resource[0].start + 1;
+
+	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
+		dev_err(&dev->dev, "request_mem_region failed");
+		retval = -EBUSY;
+		goto err0;
+	}
+
+	clk = clk_get(NULL, "usb-host");
+	if (IS_ERR(clk)) {
+		dev_err(&dev->dev, "cannot get usb-host clock\n");
+		retval = -ENOENT;
+		goto err1;
+	}
+
+	clk_use(clk);
+	s3c2410_start_hc(dev, hcd);
+
+	hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
+	if (!hcd->regs) {
+		dev_err(&dev->dev, "ioremap failed\n");
+		retval = -ENOMEM;
+		goto err2;
+	}
+
+	ohci_hcd_init(hcd_to_ohci(hcd));
+
+	retval = usb_add_hcd(hcd, dev->resource[1].start, SA_INTERRUPT);
+	if (retval != 0)
+		goto err2;
+
+	return 0;
+
+ err2:
+	s3c2410_stop_hc(dev);
+	iounmap(hcd->regs);
+	clk_unuse(clk);
+	clk_put(clk);
+
+ err1:
+	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+
+ err0:
+	usb_put_hcd(hcd);
+	return retval;
+}
+
+/*-------------------------------------------------------------------------*/
+
+static int
+ohci_s3c2410_start (struct usb_hcd *hcd)
+{
+	struct ohci_hcd	*ohci = hcd_to_ohci (hcd);
+	int ret;
+
+	if ((ret = ohci_init(ohci)) < 0)
+		return ret;
+
+	if ((ret = ohci_run (ohci)) < 0) {
+		err ("can't start %s", hcd->self.bus_name);
+		ohci_stop (hcd);
+		return ret;
+	}
+
+	return 0;
+}
+
+
+static const struct hc_driver ohci_s3c2410_hc_driver = {
+	.description =		hcd_name,
+	.product_desc =		"S3C24XX OHCI",
+	.hcd_priv_size =	sizeof(struct ohci_hcd),
+
+	/*
+	 * generic hardware linkage
+	 */
+	.irq =			ohci_irq,
+	.flags =		HCD_USB11 | HCD_MEMORY,
+
+	/*
+	 * basic lifecycle operations
+	 */
+	.start =		ohci_s3c2410_start,
+	.stop =			ohci_stop,
+
+	/*
+	 * managing i/o requests and associated device resources
+	 */
+	.urb_enqueue =		ohci_urb_enqueue,
+	.urb_dequeue =		ohci_urb_dequeue,
+	.endpoint_disable =	ohci_endpoint_disable,
+
+	/*
+	 * scheduling support
+	 */
+	.get_frame_number =	ohci_get_frame,
+
+	/*
+	 * root hub support
+	 */
+	.hub_status_data =	ohci_s3c2410_hub_status_data,
+	.hub_control =		ohci_s3c2410_hub_control,
+
+#if defined(CONFIG_USB_SUSPEND) && 0
+	.hub_suspend =		ohci_hub_suspend,
+	.hub_resume =		ohci_hub_resume,
+#endif
+};
+
+/* device driver */
+
+static int ohci_hcd_s3c2410_drv_probe(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	return usb_hcd_s3c2410_probe(&ohci_s3c2410_hc_driver, pdev);
+}
+
+static int ohci_hcd_s3c2410_drv_remove(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct usb_hcd *hcd = dev_get_drvdata(dev);
+
+	usb_hcd_s3c2410_remove(hcd, pdev);
+	return 0;
+}
+
+static struct device_driver ohci_hcd_s3c2410_driver = {
+	.name		= "s3c2410-ohci",
+	.bus		= &platform_bus_type,
+	.probe		= ohci_hcd_s3c2410_drv_probe,
+	.remove		= ohci_hcd_s3c2410_drv_remove,
+	/*.suspend	= ohci_hcd_s3c2410_drv_suspend, */
+	/*.resume	= ohci_hcd_s3c2410_drv_resume, */
+};
+
+static int __init ohci_hcd_s3c2410_init (void)
+{
+	return driver_register(&ohci_hcd_s3c2410_driver);
+}
+
+static void __exit ohci_hcd_s3c2410_cleanup (void)
+{
+	driver_unregister(&ohci_hcd_s3c2410_driver);
+}
+
+module_init (ohci_hcd_s3c2410_init);
+module_exit (ohci_hcd_s3c2410_cleanup);
diff --git a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h
--- a/drivers/usb/host/ohci.h
+++ b/drivers/usb/host/ohci.h
@@ -371,7 +371,6 @@ struct ohci_hcd {
 	 * other external transceivers should be software-transparent 
 	 */
 	struct otg_transceiver	*transceiver;
-	unsigned		power_budget;
 
 	/*
 	 * memory management for queue data structures
@@ -390,6 +389,7 @@ struct ohci_hcd {
 	u32			fminterval;		/* saved register */
 
 	struct work_struct	rh_resume;
+	struct notifier_block	reboot_notifier;
 
 	unsigned long		flags;		/* for HC bugs */
 #define	OHCI_QUIRK_AMD756	0x01			/* erratum #4 */
diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c
--- a/drivers/usb/host/sl811-hcd.c
+++ b/drivers/usb/host/sl811-hcd.c
@@ -815,7 +815,7 @@ static int sl811h_urb_enqueue(
 	struct usb_hcd		*hcd,
 	struct usb_host_endpoint *hep,
 	struct urb		*urb,
-	int			mem_flags
+	unsigned		mem_flags
 ) {
 	struct sl811		*sl811 = hcd_to_sl811(hcd);
 	struct usb_device	*udev = urb->dev;
@@ -1563,29 +1563,15 @@ static int
 sl811h_start(struct usb_hcd *hcd)
 {
 	struct sl811		*sl811 = hcd_to_sl811(hcd);
-	struct usb_device	*udev;
 
 	/* chip has been reset, VBUS power is off */
-
-	udev = usb_alloc_dev(NULL, &hcd->self, 0);
-	if (!udev)
-		return -ENOMEM;
-
-	udev->speed = USB_SPEED_FULL;
 	hcd->state = HC_STATE_RUNNING;
 
-	if (sl811->board)
+	if (sl811->board) {
 		hcd->can_wakeup = sl811->board->can_wakeup;
-
-	if (usb_hcd_register_root_hub(udev, hcd) != 0) {
-		usb_put_dev(udev);
-		sl811h_stop(hcd);
-		return -ENODEV;
+		hcd->power_budget = sl811->board->power * 2;
 	}
 
-	if (sl811->board && sl811->board->power)
-		hub_set_power_budget(udev, sl811->board->power * 2);
-
 	/* enable power and interupts */
 	port_power(sl811, 1);
 
diff --git a/drivers/usb/host/sl811_cs.c b/drivers/usb/host/sl811_cs.c
--- a/drivers/usb/host/sl811_cs.c
+++ b/drivers/usb/host/sl811_cs.c
@@ -20,7 +20,6 @@
 #include <linux/timer.h>
 #include <linux/ioport.h>
 
-#include <pcmcia/version.h>
 #include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
@@ -68,13 +67,6 @@ static const char driver_name[DEV_NAME_L
 
 static dev_link_t *dev_list = NULL;
 
-static int irq_list[4] = { -1 };
-static int irq_list_count;
-
-module_param_array(irq_list, int, &irq_list_count, 0444);
-
-INT_MODULE_PARM(irq_mask, 0xdeb8);
-
 typedef struct local_info_t {
 	dev_link_t		link;
 	dev_node_t		node;
@@ -373,7 +365,7 @@ static dev_link_t *sl811_cs_attach(void)
 	local_info_t *local;
 	dev_link_t *link;
 	client_reg_t client_reg;
-	int ret, i;
+	int ret;
 
 	local = kmalloc(sizeof(local_info_t), GFP_KERNEL);
 	if (!local)
@@ -385,11 +377,6 @@ static dev_link_t *sl811_cs_attach(void)
 	/* Initialize */
 	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 < irq_list_count; i++)
-			link->irq.IRQInfo2 |= 1 << irq_list[i];
 	link->irq.Handler = NULL;
 
 	link->conf.Attributes = 0;
@@ -401,11 +388,6 @@ static dev_link_t *sl811_cs_attach(void)
 	dev_list = link;
 	client_reg.dev_info = (dev_info_t *) &driver_name;
 	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 = &sl811_cs_event;
 	client_reg.Version = 0x0210;
 	client_reg.event_callback_args.client_data = link;
 	ret = pcmcia_register_client(&link->handle, &client_reg);
@@ -418,13 +400,21 @@ static dev_link_t *sl811_cs_attach(void)
 	return link;
 }
 
+static struct pcmcia_device_id sl811_ids[] = {
+	PCMCIA_DEVICE_MANF_CARD(0xc015, 0x0001), /* RATOC USB HOST CF+ Card */
+	PCMCIA_DEVICE_NULL,
+};
+MODULE_DEVICE_TABLE(pcmcia, sl811_ids);
+
 static struct pcmcia_driver sl811_cs_driver = {
 	.owner		= THIS_MODULE,
 	.drv		= {
 		.name	= (char *)driver_name,
 	},
 	.attach		= sl811_cs_attach,
+	.event		= sl811_cs_event,
 	.detach		= sl811_cs_detach,
+	.id_table	= sl811_ids,
 };
 
 /*====================================================================*/
diff --git a/drivers/usb/host/uhci-debug.c b/drivers/usb/host/uhci-debug.c
--- a/drivers/usb/host/uhci-debug.c
+++ b/drivers/usb/host/uhci-debug.c
@@ -237,6 +237,37 @@ static int uhci_show_sc(int port, unsign
 	return out - buf;
 }
 
+static int uhci_show_root_hub_state(struct uhci_hcd *uhci, char *buf, int len)
+{
+	char *out = buf;
+	char *rh_state;
+
+	/* Try to make sure there's enough memory */
+	if (len < 60)
+		return 0;
+
+	switch (uhci->rh_state) {
+	    case UHCI_RH_RESET:
+		rh_state = "reset";		break;
+	    case UHCI_RH_SUSPENDED:
+		rh_state = "suspended";		break;
+	    case UHCI_RH_AUTO_STOPPED:
+		rh_state = "auto-stopped";	break;
+	    case UHCI_RH_RESUMING:
+		rh_state = "resuming";		break;
+	    case UHCI_RH_SUSPENDING:
+		rh_state = "suspending";	break;
+	    case UHCI_RH_RUNNING:
+		rh_state = "running";		break;
+	    case UHCI_RH_RUNNING_NODEVS:
+		rh_state = "running, no devs";	break;
+	    default:
+		rh_state = "?";			break;
+	}
+	out += sprintf(out, "Root-hub state: %s\n", rh_state);
+	return out - buf;
+}
+
 static int uhci_show_status(struct uhci_hcd *uhci, char *buf, int len)
 {
 	char *out = buf;
@@ -408,6 +439,7 @@ static int uhci_sprint_schedule(struct u
 
 	spin_lock_irqsave(&uhci->lock, flags);
 
+	out += uhci_show_root_hub_state(uhci, out, len - (out - buf));
 	out += sprintf(out, "HC status\n");
 	out += uhci_show_status(uhci, out, len - (out - buf));
 
diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c
--- a/drivers/usb/host/uhci-hcd.c
+++ b/drivers/usb/host/uhci-hcd.c
@@ -13,18 +13,13 @@
  * (C) Copyright 2000 Yggdrasil Computing, Inc. (port of new PCI interface
  *               support from usb-ohci.c by Adam Richter, adam@yggdrasil.com).
  * (C) Copyright 1999 Gregory P. Smith (from usb-ohci.c)
- * (C) Copyright 2004 Alan Stern, stern@rowland.harvard.edu
+ * (C) Copyright 2004-2005 Alan Stern, stern@rowland.harvard.edu
  *
  * Intel documents this fairly well, and as far as I know there
  * are no royalties or anything like that, but even so there are
  * people who decided that they want to do the same thing in a
  * completely different way.
  *
- * WARNING! The USB documentation is downright evil. Most of it
- * is just crap, written by a committee. You're better off ignoring
- * most of it, the important stuff is:
- *  - the low-level protocol (fairly simple but lots of small details)
- *  - working around the horridness of the rest
  */
 
 #include <linux/config.h>
@@ -64,7 +59,7 @@
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v2.2"
+#define DRIVER_VERSION "v2.3"
 #define DRIVER_AUTHOR "Linus 'Frodo Rabbit' Torvalds, Johannes Erdfelt, \
 Randy Dunlap, Georg Acher, Deti Fliegl, Thomas Sailer, Roman Weissgaerber, \
 Alan Stern"
@@ -89,8 +84,9 @@ static char *errbuf;
 
 static kmem_cache_t *uhci_up_cachep;	/* urb_priv */
 
+static void suspend_rh(struct uhci_hcd *uhci, enum uhci_rh_state new_state);
+static void wakeup_rh(struct uhci_hcd *uhci);
 static void uhci_get_current_frame_number(struct uhci_hcd *uhci);
-static void hc_state_transitions(struct uhci_hcd *uhci);
 
 /* If a transfer is still active after this much time, turn off FSBR */
 #define IDLE_TIMEOUT	msecs_to_jiffies(50)
@@ -101,256 +97,342 @@ static void hc_state_transitions(struct 
 /* to make sure it doesn't hog all of the bandwidth */
 #define DEPTH_INTERVAL 5
 
+static inline void restart_timer(struct uhci_hcd *uhci)
+{
+	mod_timer(&uhci->stall_timer, jiffies + msecs_to_jiffies(100));
+}
+
 #include "uhci-hub.c"
 #include "uhci-debug.c"
 #include "uhci-q.c"
 
-static int init_stall_timer(struct usb_hcd *hcd);
-
-static void stall_callback(unsigned long ptr)
+/*
+ * Make sure the controller is completely inactive, unable to
+ * generate interrupts or do DMA.
+ */
+static void reset_hc(struct uhci_hcd *uhci)
 {
-	struct usb_hcd *hcd = (struct usb_hcd *)ptr;
-	struct uhci_hcd *uhci = hcd_to_uhci(hcd);
-	struct urb_priv *up;
-	unsigned long flags;
+	int port;
 
-	spin_lock_irqsave(&uhci->lock, flags);
-	uhci_scan_schedule(uhci, NULL);
-
-	list_for_each_entry(up, &uhci->urb_list, urb_list) {
-		struct urb *u = up->urb;
-
-		spin_lock(&u->lock);
-
-		/* Check if the FSBR timed out */
-		if (up->fsbr && !up->fsbr_timeout && time_after_eq(jiffies, up->fsbrtime + IDLE_TIMEOUT))
-			uhci_fsbr_timeout(uhci, u);
+	/* Turn off PIRQ enable and SMI enable.  (This also turns off the
+	 * BIOS's USB Legacy Support.)  Turn off all the R/WC bits too.
+	 */
+	pci_write_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP,
+			USBLEGSUP_RWC);
 
-		spin_unlock(&u->lock);
-	}
+	/* Reset the HC - this will force us to get a
+	 * new notification of any already connected
+	 * ports due to the virtual disconnect that it
+	 * implies.
+	 */
+	outw(USBCMD_HCRESET, uhci->io_addr + USBCMD);
+	mb();
+	udelay(5);
+	if (inw(uhci->io_addr + USBCMD) & USBCMD_HCRESET)
+		dev_warn(uhci_dev(uhci), "HCRESET not completed yet!\n");
 
-	/* Really disable FSBR */
-	if (!uhci->fsbr && uhci->fsbrtimeout && time_after_eq(jiffies, uhci->fsbrtimeout)) {
-		uhci->fsbrtimeout = 0;
-		uhci->skel_term_qh->link = UHCI_PTR_TERM;
-	}
+	/* Just to be safe, disable interrupt requests and
+	 * make sure the controller is stopped.
+	 */
+	outw(0, uhci->io_addr + USBINTR);
+	outw(0, uhci->io_addr + USBCMD);
 
-	/* Poll for and perform state transitions */
-	hc_state_transitions(uhci);
-	if (unlikely(uhci->suspended_ports && uhci->state != UHCI_SUSPENDED))
-		uhci_check_ports(uhci);
+	/* HCRESET doesn't affect the Suspend, Reset, and Resume Detect
+	 * bits in the port status and control registers.
+	 * We have to clear them by hand.
+	 */
+	for (port = 0; port < uhci->rh_numports; ++port)
+		outw(0, uhci->io_addr + USBPORTSC1 + (port * 2));
 
-	init_stall_timer(hcd);
-	spin_unlock_irqrestore(&uhci->lock, flags);
+	uhci->port_c_suspend = uhci->suspended_ports =
+			uhci->resuming_ports = 0;
+	uhci->rh_state = UHCI_RH_RESET;
+	uhci->is_stopped = UHCI_IS_STOPPED;
+	uhci_to_hcd(uhci)->state = HC_STATE_HALT;
+	uhci_to_hcd(uhci)->poll_rh = 0;
 }
 
-static int init_stall_timer(struct usb_hcd *hcd)
+/*
+ * Last rites for a defunct/nonfunctional controller
+ * or one we don't want to use any more.
+ */
+static void hc_died(struct uhci_hcd *uhci)
 {
-	struct uhci_hcd *uhci = hcd_to_uhci(hcd);
-
-	init_timer(&uhci->stall_timer);
-	uhci->stall_timer.function = stall_callback;
-	uhci->stall_timer.data = (unsigned long)hcd;
-	uhci->stall_timer.expires = jiffies + msecs_to_jiffies(100);
-	add_timer(&uhci->stall_timer);
-
-	return 0;
+	reset_hc(uhci);
+	uhci->hc_inaccessible = 1;
+	del_timer(&uhci->stall_timer);
 }
 
-static irqreturn_t uhci_irq(struct usb_hcd *hcd, struct pt_regs *regs)
+/*
+ * Initialize a controller that was newly discovered or has just been
+ * resumed.  In either case we can't be sure of its previous state.
+ */
+static void check_and_reset_hc(struct uhci_hcd *uhci)
 {
-	struct uhci_hcd *uhci = hcd_to_uhci(hcd);
-	unsigned long io_addr = uhci->io_addr;
-	unsigned short status;
+	u16 legsup;
+	unsigned int cmd, intr;
 
 	/*
-	 * Read the interrupt status, and write it back to clear the
-	 * interrupt cause.  Contrary to the UHCI specification, the
-	 * "HC Halted" status bit is persistent: it is RO, not R/WC.
+	 * When restarting a suspended controller, we expect all the
+	 * settings to be the same as we left them:
+	 *
+	 *	PIRQ and SMI disabled, no R/W bits set in USBLEGSUP;
+	 *	Controller is stopped and configured with EGSM set;
+	 *	No interrupts enabled except possibly Resume Detect.
+	 *
+	 * If any of these conditions are violated we do a complete reset.
 	 */
-	status = inw(io_addr + USBSTS);
-	if (!(status & ~USBSTS_HCH))	/* shared interrupt, not mine */
-		return IRQ_NONE;
-	outw(status, io_addr + USBSTS);		/* Clear it */
-
-	if (status & ~(USBSTS_USBINT | USBSTS_ERROR | USBSTS_RD)) {
-		if (status & USBSTS_HSE)
-			dev_err(uhci_dev(uhci), "host system error, "
-					"PCI problems?\n");
-		if (status & USBSTS_HCPE)
-			dev_err(uhci_dev(uhci), "host controller process "
-					"error, something bad happened!\n");
-		if ((status & USBSTS_HCH) && uhci->state > 0) {
-			dev_err(uhci_dev(uhci), "host controller halted, "
-					"very bad!\n");
-			/* FIXME: Reset the controller, fix the offending TD */
-		}
+	pci_read_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP, &legsup);
+	if (legsup & ~(USBLEGSUP_RO | USBLEGSUP_RWC)) {
+		dev_dbg(uhci_dev(uhci), "%s: legsup = 0x%04x\n",
+				__FUNCTION__, legsup);
+		goto reset_needed;
+	}
+
+	cmd = inw(uhci->io_addr + USBCMD);
+	if ((cmd & USBCMD_RS) || !(cmd & USBCMD_CF) || !(cmd & USBCMD_EGSM)) {
+		dev_dbg(uhci_dev(uhci), "%s: cmd = 0x%04x\n",
+				__FUNCTION__, cmd);
+		goto reset_needed;
+	}
+
+	intr = inw(uhci->io_addr + USBINTR);
+	if (intr & (~USBINTR_RESUME)) {
+		dev_dbg(uhci_dev(uhci), "%s: intr = 0x%04x\n",
+				__FUNCTION__, intr);
+		goto reset_needed;
 	}
+	return;
 
-	if (status & USBSTS_RD)
-		uhci->resume_detect = 1;
-
-	spin_lock(&uhci->lock);
-	uhci_scan_schedule(uhci, regs);
-	spin_unlock(&uhci->lock);
-
-	return IRQ_HANDLED;
+reset_needed:
+	dev_dbg(uhci_dev(uhci), "Performing full reset\n");
+	reset_hc(uhci);
 }
 
-static void reset_hc(struct uhci_hcd *uhci)
+/*
+ * Store the basic register settings needed by the controller.
+ */
+static void configure_hc(struct uhci_hcd *uhci)
 {
-	unsigned long io_addr = uhci->io_addr;
+	/* Set the frame length to the default: 1 ms exactly */
+	outb(USBSOF_DEFAULT, uhci->io_addr + USBSOF);
 
-	/* Turn off PIRQ, SMI, and all interrupts.  This also turns off
-	 * the BIOS's USB Legacy Support.
-	 */
-	pci_write_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP, 0);
-	outw(0, uhci->io_addr + USBINTR);
+	/* Store the frame list base address */
+	outl(uhci->fl->dma_handle, uhci->io_addr + USBFLBASEADD);
 
-	/* Global reset for 50ms */
-	uhci->state = UHCI_RESET;
-	outw(USBCMD_GRESET, io_addr + USBCMD);
-	msleep(50);
-	outw(0, io_addr + USBCMD);
-
-	/* Another 10ms delay */
-	msleep(10);
-	uhci->resume_detect = 0;
-	uhci->is_stopped = UHCI_IS_STOPPED;
+	/* Set the current frame number */
+	outw(uhci->frame_number, uhci->io_addr + USBFRNUM);
+
+	/* Mark controller as running before we enable interrupts */
+	uhci_to_hcd(uhci)->state = HC_STATE_RUNNING;
+	mb();
+
+	/* Enable PIRQ */
+	pci_write_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP,
+			USBLEGSUP_DEFAULT);
 }
 
-static void suspend_hc(struct uhci_hcd *uhci)
+
+static int resume_detect_interrupts_are_broken(struct uhci_hcd *uhci)
 {
-	unsigned long io_addr = uhci->io_addr;
+	int port;
 
-	dev_dbg(uhci_dev(uhci), "%s\n", __FUNCTION__);
-	uhci->state = UHCI_SUSPENDED;
-	uhci->resume_detect = 0;
-	outw(USBCMD_EGSM, io_addr + USBCMD);
+	switch (to_pci_dev(uhci_dev(uhci))->vendor) {
+	    default:
+		break;
 
-	/* FIXME: Wait for the controller to actually stop */
-	uhci_get_current_frame_number(uhci);
-	uhci->is_stopped = UHCI_IS_STOPPED;
+	    case PCI_VENDOR_ID_GENESYS:
+		/* Genesys Logic's GL880S controllers don't generate
+		 * resume-detect interrupts.
+		 */
+		return 1;
 
-	uhci_scan_schedule(uhci, NULL);
+	    case PCI_VENDOR_ID_INTEL:
+		/* Some of Intel's USB controllers have a bug that causes
+		 * resume-detect interrupts if any port has an over-current
+		 * condition.  To make matters worse, some motherboards
+		 * hardwire unused USB ports' over-current inputs active!
+		 * To prevent problems, we will not enable resume-detect
+		 * interrupts if any ports are OC.
+		 */
+		for (port = 0; port < uhci->rh_numports; ++port) {
+			if (inw(uhci->io_addr + USBPORTSC1 + port * 2) &
+					USBPORTSC_OC)
+				return 1;
+		}
+		break;
+	}
+	return 0;
 }
 
-static void wakeup_hc(struct uhci_hcd *uhci)
-{
-	unsigned long io_addr = uhci->io_addr;
-
-	switch (uhci->state) {
-		case UHCI_SUSPENDED:		/* Start the resume */
-			dev_dbg(uhci_dev(uhci), "%s\n", __FUNCTION__);
-
-			/* Global resume for >= 20ms */
-			outw(USBCMD_FGR | USBCMD_EGSM, io_addr + USBCMD);
-			uhci->state = UHCI_RESUMING_1;
-			uhci->state_end = jiffies + msecs_to_jiffies(20);
-			uhci->is_stopped = 0;
-			break;
+static void suspend_rh(struct uhci_hcd *uhci, enum uhci_rh_state new_state)
+__releases(uhci->lock)
+__acquires(uhci->lock)
+{
+	int auto_stop;
+	int int_enable;
+
+	auto_stop = (new_state == UHCI_RH_AUTO_STOPPED);
+	dev_dbg(uhci_dev(uhci), "%s%s\n", __FUNCTION__,
+			(auto_stop ? " (auto-stop)" : ""));
 
-		case UHCI_RESUMING_1:		/* End global resume */
-			uhci->state = UHCI_RESUMING_2;
-			outw(0, io_addr + USBCMD);
-			/* Falls through */
-
-		case UHCI_RESUMING_2:		/* Wait for EOP to be sent */
-			if (inw(io_addr + USBCMD) & USBCMD_FGR)
-				break;
-
-			/* Run for at least 1 second, and
-			 * mark it configured with a 64-byte max packet */
-			uhci->state = UHCI_RUNNING_GRACE;
-			uhci->state_end = jiffies + HZ;
-			outw(USBCMD_RS | USBCMD_CF | USBCMD_MAXP,
-					io_addr + USBCMD);
-			break;
+	/* If we get a suspend request when we're already auto-stopped
+	 * then there's nothing to do.
+	 */
+	if (uhci->rh_state == UHCI_RH_AUTO_STOPPED) {
+		uhci->rh_state = new_state;
+		return;
+	}
 
-		case UHCI_RUNNING_GRACE:	/* Now allowed to suspend */
-			uhci->state = UHCI_RUNNING;
-			break;
+	/* Enable resume-detect interrupts if they work.
+	 * Then enter Global Suspend mode, still configured.
+	 */
+	int_enable = (resume_detect_interrupts_are_broken(uhci) ?
+			0 : USBINTR_RESUME);
+	outw(int_enable, uhci->io_addr + USBINTR);
+	outw(USBCMD_EGSM | USBCMD_CF, uhci->io_addr + USBCMD);
+	mb();
+	udelay(5);
 
-		default:
-			break;
+	/* If we're auto-stopping then no devices have been attached
+	 * for a while, so there shouldn't be any active URBs and the
+	 * controller should stop after a few microseconds.  Otherwise
+	 * we will give the controller one frame to stop.
+	 */
+	if (!auto_stop && !(inw(uhci->io_addr + USBSTS) & USBSTS_HCH)) {
+		uhci->rh_state = UHCI_RH_SUSPENDING;
+		spin_unlock_irq(&uhci->lock);
+		msleep(1);
+		spin_lock_irq(&uhci->lock);
+		if (uhci->hc_inaccessible)	/* Died */
+			return;
 	}
-}
+	if (!(inw(uhci->io_addr + USBSTS) & USBSTS_HCH))
+		dev_warn(uhci_dev(uhci), "Controller not stopped yet!\n");
 
-static int ports_active(struct uhci_hcd *uhci)
-{
-	unsigned long io_addr = uhci->io_addr;
-	int connection = 0;
-	int i;
+	uhci_get_current_frame_number(uhci);
+	smp_wmb();
 
-	for (i = 0; i < uhci->rh_numports; i++)
-		connection |= (inw(io_addr + USBPORTSC1 + i * 2) & USBPORTSC_CCS);
+	uhci->rh_state = new_state;
+	uhci->is_stopped = UHCI_IS_STOPPED;
+	del_timer(&uhci->stall_timer);
+	uhci_to_hcd(uhci)->poll_rh = !int_enable;
 
-	return connection;
+	uhci_scan_schedule(uhci, NULL);
 }
 
-static int suspend_allowed(struct uhci_hcd *uhci)
+static void start_rh(struct uhci_hcd *uhci)
 {
-	unsigned long io_addr = uhci->io_addr;
-	int i;
-
-	if (to_pci_dev(uhci_dev(uhci))->vendor != PCI_VENDOR_ID_INTEL)
-		return 1;
+	uhci->is_stopped = 0;
+	smp_wmb();
 
-	/* Some of Intel's USB controllers have a bug that causes false
-	 * resume indications if any port has an over current condition.
-	 * To prevent problems, we will not allow a global suspend if
-	 * any ports are OC.
-	 *
-	 * Some motherboards using Intel's chipsets (but not using all
-	 * the USB ports) appear to hardwire the over current inputs active
-	 * to disable the USB ports.
+	/* Mark it configured and running with a 64-byte max packet.
+	 * All interrupts are enabled, even though RESUME won't do anything.
+	 */
+	outw(USBCMD_RS | USBCMD_CF | USBCMD_MAXP, uhci->io_addr + USBCMD);
+	outw(USBINTR_TIMEOUT | USBINTR_RESUME | USBINTR_IOC | USBINTR_SP,
+			uhci->io_addr + USBINTR);
+	mb();
+	uhci->rh_state = UHCI_RH_RUNNING;
+	uhci_to_hcd(uhci)->poll_rh = 1;
+	restart_timer(uhci);
+}
+
+static void wakeup_rh(struct uhci_hcd *uhci)
+__releases(uhci->lock)
+__acquires(uhci->lock)
+{
+	dev_dbg(uhci_dev(uhci), "%s%s\n", __FUNCTION__,
+			uhci->rh_state == UHCI_RH_AUTO_STOPPED ?
+				" (auto-start)" : "");
+
+	/* If we are auto-stopped then no devices are attached so there's
+	 * no need for wakeup signals.  Otherwise we send Global Resume
+	 * for 20 ms.
 	 */
+	if (uhci->rh_state == UHCI_RH_SUSPENDED) {
+		uhci->rh_state = UHCI_RH_RESUMING;
+		outw(USBCMD_FGR | USBCMD_EGSM | USBCMD_CF,
+				uhci->io_addr + USBCMD);
+		spin_unlock_irq(&uhci->lock);
+		msleep(20);
+		spin_lock_irq(&uhci->lock);
+		if (uhci->hc_inaccessible)	/* Died */
+			return;
 
-	/* check for over current condition on any port */
-	for (i = 0; i < uhci->rh_numports; i++) {
-		if (inw(io_addr + USBPORTSC1 + i * 2) & USBPORTSC_OC)
-			return 0;
+		/* End Global Resume and wait for EOP to be sent */
+		outw(USBCMD_CF, uhci->io_addr + USBCMD);
+		mb();
+		udelay(4);
+		if (inw(uhci->io_addr + USBCMD) & USBCMD_FGR)
+			dev_warn(uhci_dev(uhci), "FGR not stopped yet!\n");
 	}
 
-	return 1;
+	start_rh(uhci);
+
+	/* Restart root hub polling */
+	mod_timer(&uhci_to_hcd(uhci)->rh_timer, jiffies);
 }
 
-static void hc_state_transitions(struct uhci_hcd *uhci)
+static void stall_callback(unsigned long _uhci)
 {
-	switch (uhci->state) {
-		case UHCI_RUNNING:
-
-			/* global suspend if nothing connected for 1 second */
-			if (!ports_active(uhci) && suspend_allowed(uhci)) {
-				uhci->state = UHCI_SUSPENDING_GRACE;
-				uhci->state_end = jiffies + HZ;
-			}
-			break;
+	struct uhci_hcd *uhci = (struct uhci_hcd *) _uhci;
+	unsigned long flags;
 
-		case UHCI_SUSPENDING_GRACE:
-			if (ports_active(uhci))
-				uhci->state = UHCI_RUNNING;
-			else if (time_after_eq(jiffies, uhci->state_end))
-				suspend_hc(uhci);
-			break;
+	spin_lock_irqsave(&uhci->lock, flags);
+	uhci_scan_schedule(uhci, NULL);
+	check_fsbr(uhci);
 
-		case UHCI_SUSPENDED:
+	if (!uhci->is_stopped)
+		restart_timer(uhci);
+	spin_unlock_irqrestore(&uhci->lock, flags);
+}
 
-			/* wakeup if requested by a device */
-			if (uhci->resume_detect)
-				wakeup_hc(uhci);
-			break;
+static irqreturn_t uhci_irq(struct usb_hcd *hcd, struct pt_regs *regs)
+{
+	struct uhci_hcd *uhci = hcd_to_uhci(hcd);
+	unsigned short status;
+	unsigned long flags;
 
-		case UHCI_RESUMING_1:
-		case UHCI_RESUMING_2:
-		case UHCI_RUNNING_GRACE:
-			if (time_after_eq(jiffies, uhci->state_end))
-				wakeup_hc(uhci);
-			break;
+	/*
+	 * Read the interrupt status, and write it back to clear the
+	 * interrupt cause.  Contrary to the UHCI specification, the
+	 * "HC Halted" status bit is persistent: it is RO, not R/WC.
+	 */
+	status = inw(uhci->io_addr + USBSTS);
+	if (!(status & ~USBSTS_HCH))	/* shared interrupt, not mine */
+		return IRQ_NONE;
+	outw(status, uhci->io_addr + USBSTS);		/* Clear it */
 
-		default:
-			break;
+	if (status & ~(USBSTS_USBINT | USBSTS_ERROR | USBSTS_RD)) {
+		if (status & USBSTS_HSE)
+			dev_err(uhci_dev(uhci), "host system error, "
+					"PCI problems?\n");
+		if (status & USBSTS_HCPE)
+			dev_err(uhci_dev(uhci), "host controller process "
+					"error, something bad happened!\n");
+		if (status & USBSTS_HCH) {
+			spin_lock_irqsave(&uhci->lock, flags);
+			if (uhci->rh_state >= UHCI_RH_RUNNING) {
+				dev_err(uhci_dev(uhci),
+					"host controller halted, "
+					"very bad!\n");
+				hc_died(uhci);
+				spin_unlock_irqrestore(&uhci->lock, flags);
+				return IRQ_HANDLED;
+			}
+			spin_unlock_irqrestore(&uhci->lock, flags);
+		}
 	}
+
+	if (status & USBSTS_RD)
+		usb_hcd_poll_rh_status(hcd);
+
+	spin_lock_irqsave(&uhci->lock, flags);
+	uhci_scan_schedule(uhci, regs);
+	spin_unlock_irqrestore(&uhci->lock, flags);
+
+	return IRQ_HANDLED;
 }
 
 /*
@@ -363,48 +445,6 @@ static void uhci_get_current_frame_numbe
 		uhci->frame_number = inw(uhci->io_addr + USBFRNUM);
 }
 
-static int start_hc(struct uhci_hcd *uhci)
-{
-	unsigned long io_addr = uhci->io_addr;
-	int timeout = 10;
-
-	/*
-	 * Reset the HC - this will force us to get a
-	 * new notification of any already connected
-	 * ports due to the virtual disconnect that it
-	 * implies.
-	 */
-	outw(USBCMD_HCRESET, io_addr + USBCMD);
-	while (inw(io_addr + USBCMD) & USBCMD_HCRESET) {
-		if (--timeout < 0) {
-			dev_err(uhci_dev(uhci), "USBCMD_HCRESET timed out!\n");
-			return -ETIMEDOUT;
-		}
-		msleep(1);
-	}
-
-	/* Mark controller as running before we enable interrupts */
-	uhci_to_hcd(uhci)->state = HC_STATE_RUNNING;
-
-	/* Turn on PIRQ and all interrupts */
-	pci_write_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP,
-			USBLEGSUP_DEFAULT);
-	outw(USBINTR_TIMEOUT | USBINTR_RESUME | USBINTR_IOC | USBINTR_SP,
-		io_addr + USBINTR);
-
-	/* Start at frame 0 */
-	outw(0, io_addr + USBFRNUM);
-	outl(uhci->fl->dma_handle, io_addr + USBFLBASEADD);
-
-	/* Run and mark it configured with a 64-byte max packet */
-	uhci->state = UHCI_RUNNING_GRACE;
-	uhci->state_end = jiffies + HZ;
-	outw(USBCMD_RS | USBCMD_CF | USBCMD_MAXP, io_addr + USBCMD);
-	uhci->is_stopped = 0;
-
-	return 0;
-}
-
 /*
  * De-allocate all resources
  */
@@ -448,16 +488,58 @@ static void release_uhci(struct uhci_hcd
 static int uhci_reset(struct usb_hcd *hcd)
 {
 	struct uhci_hcd *uhci = hcd_to_uhci(hcd);
+	unsigned io_size = (unsigned) hcd->rsrc_len;
+	int port;
 
 	uhci->io_addr = (unsigned long) hcd->rsrc_start;
 
-	/* Kick BIOS off this hardware and reset, so we won't get
-	 * interrupts from any previous setup.
+	/* The UHCI spec says devices must have 2 ports, and goes on to say
+	 * they may have more but gives no way to determine how many there
+	 * are.  However according to the UHCI spec, Bit 7 of the port
+	 * status and control register is always set to 1.  So we try to
+	 * use this to our advantage.  Another common failure mode when
+	 * a nonexistent register is addressed is to return all ones, so
+	 * we test for that also.
 	 */
-	reset_hc(uhci);
+	for (port = 0; port < (io_size - USBPORTSC1) / 2; port++) {
+		unsigned int portstatus;
+
+		portstatus = inw(uhci->io_addr + USBPORTSC1 + (port * 2));
+		if (!(portstatus & 0x0080) || portstatus == 0xffff)
+			break;
+	}
+	if (debug)
+		dev_info(uhci_dev(uhci), "detected %d ports\n", port);
+
+	/* Anything greater than 7 is weird so we'll ignore it. */
+	if (port > UHCI_RH_MAXCHILD) {
+		dev_info(uhci_dev(uhci), "port count misdetected? "
+				"forcing to 2 ports\n");
+		port = 2;
+	}
+	uhci->rh_numports = port;
+
+	/* Kick BIOS off this hardware and reset if the controller
+	 * isn't already safely quiescent.
+	 */
+	check_and_reset_hc(uhci);
 	return 0;
 }
 
+/* Make sure the controller is quiescent and that we're not using it
+ * any more.  This is mainly for the benefit of programs which, like kexec,
+ * expect the hardware to be idle: not doing DMA or generating IRQs.
+ *
+ * This routine may be called in a damaged or failing kernel.  Hence we
+ * do not acquire the spinlock before shutting down the controller.
+ */
+static void uhci_shutdown(struct pci_dev *pdev)
+{
+	struct usb_hcd *hcd = (struct usb_hcd *) pci_get_drvdata(pdev);
+
+	hc_died(hcd_to_uhci(hcd));
+}
+
 /*
  * Allocate a frame list, and then setup the skeleton
  *
@@ -478,17 +560,20 @@ static int uhci_start(struct usb_hcd *hc
 {
 	struct uhci_hcd *uhci = hcd_to_uhci(hcd);
 	int retval = -EBUSY;
-	int i, port;
-	unsigned io_size;
+	int i;
 	dma_addr_t dma_handle;
-	struct usb_device *udev;
 	struct dentry *dentry;
 
-	io_size = (unsigned) hcd->rsrc_len;
-
-	dentry = debugfs_create_file(hcd->self.bus_name, S_IFREG|S_IRUGO|S_IWUSR, uhci_debugfs_root, uhci, &uhci_debug_operations);
+	hcd->uses_new_polling = 1;
+	if (pci_find_capability(to_pci_dev(uhci_dev(uhci)), PCI_CAP_ID_PM))
+		hcd->can_wakeup = 1;		/* Assume it supports PME# */
+
+	dentry = debugfs_create_file(hcd->self.bus_name,
+			S_IFREG|S_IRUGO|S_IWUSR, uhci_debugfs_root, uhci,
+			&uhci_debug_operations);
 	if (!dentry) {
-		dev_err(uhci_dev(uhci), "couldn't create uhci debugfs entry\n");
+		dev_err(uhci_dev(uhci),
+				"couldn't create uhci debugfs entry\n");
 		retval = -ENOMEM;
 		goto err_create_debug_entry;
 	}
@@ -510,6 +595,10 @@ static int uhci_start(struct usb_hcd *hc
 
 	init_waitqueue_head(&uhci->waitqh);
 
+	init_timer(&uhci->stall_timer);
+	uhci->stall_timer.function = stall_callback;
+	uhci->stall_timer.data = (unsigned long) uhci;
+
 	uhci->fl = dma_alloc_coherent(uhci_dev(uhci), sizeof(*uhci->fl),
 			&dma_handle, 0);
 	if (!uhci->fl) {
@@ -536,46 +625,14 @@ static int uhci_start(struct usb_hcd *hc
 		goto err_create_qh_pool;
 	}
 
-	/* Initialize the root hub */
-
-	/* UHCI specs says devices must have 2 ports, but goes on to say */
-	/*  they may have more but give no way to determine how many they */
-	/*  have. However, according to the UHCI spec, Bit 7 is always set */
-	/*  to 1. So we try to use this to our advantage */
-	for (port = 0; port < (io_size - 0x10) / 2; port++) {
-		unsigned int portstatus;
-
-		portstatus = inw(uhci->io_addr + 0x10 + (port * 2));
-		if (!(portstatus & 0x0080))
-			break;
-	}
-	if (debug)
-		dev_info(uhci_dev(uhci), "detected %d ports\n", port);
-
-	/* This is experimental so anything less than 2 or greater than 8 is */
-	/*  something weird and we'll ignore it */
-	if (port < 2 || port > UHCI_RH_MAXCHILD) {
-		dev_info(uhci_dev(uhci), "port count misdetected? "
-				"forcing to 2 ports\n");
-		port = 2;
-	}
-
-	uhci->rh_numports = port;
-
-	udev = usb_alloc_dev(NULL, &hcd->self, 0);
-	if (!udev) {
-		dev_err(uhci_dev(uhci), "unable to allocate root hub\n");
-		goto err_alloc_root_hub;
-	}
-
-	uhci->term_td = uhci_alloc_td(uhci, udev);
+	uhci->term_td = uhci_alloc_td(uhci);
 	if (!uhci->term_td) {
 		dev_err(uhci_dev(uhci), "unable to allocate terminating TD\n");
 		goto err_alloc_term_td;
 	}
 
 	for (i = 0; i < UHCI_NUM_SKELQH; i++) {
-		uhci->skelqh[i] = uhci_alloc_qh(uhci, udev);
+		uhci->skelqh[i] = uhci_alloc_qh(uhci);
 		if (!uhci->skelqh[i]) {
 			dev_err(uhci_dev(uhci), "unable to allocate QH\n");
 			goto err_alloc_skelqh;
@@ -641,32 +698,17 @@ static int uhci_start(struct usb_hcd *hc
 
 	/*
 	 * Some architectures require a full mb() to enforce completion of
-	 * the memory writes above before the I/O transfers in start_hc().
+	 * the memory writes above before the I/O transfers in configure_hc().
 	 */
 	mb();
-	if ((retval = start_hc(uhci)) != 0)
-		goto err_alloc_skelqh;
-
-	init_stall_timer(hcd);
-
-	udev->speed = USB_SPEED_FULL;
-
-	if (usb_hcd_register_root_hub(udev, hcd) != 0) {
-		dev_err(uhci_dev(uhci), "unable to start root hub\n");
-		retval = -ENOMEM;
-		goto err_start_root_hub;
-	}
 
+	configure_hc(uhci);
+	start_rh(uhci);
 	return 0;
 
 /*
  * error exits:
  */
-err_start_root_hub:
-	reset_hc(uhci);
-
-	del_timer_sync(&uhci->stall_timer);
-
 err_alloc_skelqh:
 	for (i = 0; i < UHCI_NUM_SKELQH; i++)
 		if (uhci->skelqh[i]) {
@@ -678,9 +720,6 @@ err_alloc_skelqh:
 	uhci->term_td = NULL;
 
 err_alloc_term_td:
-	usb_put_dev(udev);
-
-err_alloc_root_hub:
 	dma_pool_destroy(uhci->qh_pool);
 	uhci->qh_pool = NULL;
 
@@ -705,73 +744,114 @@ static void uhci_stop(struct usb_hcd *hc
 {
 	struct uhci_hcd *uhci = hcd_to_uhci(hcd);
 
-	del_timer_sync(&uhci->stall_timer);
-	reset_hc(uhci);
-
 	spin_lock_irq(&uhci->lock);
+	reset_hc(uhci);
 	uhci_scan_schedule(uhci, NULL);
 	spin_unlock_irq(&uhci->lock);
-	
+
+	del_timer_sync(&uhci->stall_timer);
 	release_uhci(uhci);
 }
 
 #ifdef CONFIG_PM
+static int uhci_rh_suspend(struct usb_hcd *hcd)
+{
+	struct uhci_hcd *uhci = hcd_to_uhci(hcd);
+
+	spin_lock_irq(&uhci->lock);
+	if (!uhci->hc_inaccessible)		/* Not dead */
+		suspend_rh(uhci, UHCI_RH_SUSPENDED);
+	spin_unlock_irq(&uhci->lock);
+	return 0;
+}
+
+static int uhci_rh_resume(struct usb_hcd *hcd)
+{
+	struct uhci_hcd *uhci = hcd_to_uhci(hcd);
+	int rc = 0;
+
+	spin_lock_irq(&uhci->lock);
+	if (uhci->hc_inaccessible) {
+		if (uhci->rh_state == UHCI_RH_SUSPENDED) {
+			dev_warn(uhci_dev(uhci), "HC isn't running!\n");
+			rc = -ENODEV;
+		}
+		/* Otherwise the HC is dead */
+	} else
+		wakeup_rh(uhci);
+	spin_unlock_irq(&uhci->lock);
+	return rc;
+}
+
 static int uhci_suspend(struct usb_hcd *hcd, pm_message_t message)
 {
 	struct uhci_hcd *uhci = hcd_to_uhci(hcd);
+	int rc = 0;
+
+	dev_dbg(uhci_dev(uhci), "%s\n", __FUNCTION__);
 
 	spin_lock_irq(&uhci->lock);
+	if (uhci->hc_inaccessible)	/* Dead or already suspended */
+		goto done;
 
-	/* Don't try to suspend broken motherboards, reset instead */
-	if (suspend_allowed(uhci))
-		suspend_hc(uhci);
-	else {
-		spin_unlock_irq(&uhci->lock);
-		reset_hc(uhci);
-		spin_lock_irq(&uhci->lock);
-		uhci_scan_schedule(uhci, NULL);
-	}
+#ifndef CONFIG_USB_SUSPEND
+	/* Otherwise this would never happen */
+	suspend_rh(uhci, UHCI_RH_SUSPENDED);
+#endif
+
+	if (uhci->rh_state > UHCI_RH_SUSPENDED) {
+		dev_warn(uhci_dev(uhci), "Root hub isn't suspended!\n");
+		hcd->state = HC_STATE_RUNNING;
+		rc = -EBUSY;
+		goto done;
+	};
 
+	/* All PCI host controllers are required to disable IRQ generation
+	 * at the source, so we must turn off PIRQ.
+	 */
+	pci_write_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP, 0);
+	uhci->hc_inaccessible = 1;
+
+	/* FIXME: Enable non-PME# remote wakeup? */
+
+done:
 	spin_unlock_irq(&uhci->lock);
-	return 0;
+	if (rc == 0)
+		del_timer_sync(&hcd->rh_timer);
+	return rc;
 }
 
 static int uhci_resume(struct usb_hcd *hcd)
 {
 	struct uhci_hcd *uhci = hcd_to_uhci(hcd);
-	int rc;
 
-	pci_set_master(to_pci_dev(uhci_dev(uhci)));
+	dev_dbg(uhci_dev(uhci), "%s\n", __FUNCTION__);
 
+	if (uhci->rh_state == UHCI_RH_RESET)	/* Dead */
+		return 0;
 	spin_lock_irq(&uhci->lock);
 
-	if (uhci->state == UHCI_SUSPENDED) {
+	/* FIXME: Disable non-PME# remote wakeup? */
 
-		/*
-		 * Some systems don't maintain the UHCI register values
-		 * during a PM suspend/resume cycle, so reinitialize
-		 * the Frame Number, Framelist Base Address, Interrupt
-		 * Enable, and Legacy Support registers.
-		 */
-		pci_write_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP,
-				0);
-		outw(uhci->frame_number, uhci->io_addr + USBFRNUM);
-		outl(uhci->fl->dma_handle, uhci->io_addr + USBFLBASEADD);
-		outw(USBINTR_TIMEOUT | USBINTR_RESUME | USBINTR_IOC |
-				USBINTR_SP, uhci->io_addr + USBINTR);
-		uhci->resume_detect = 1;
-		pci_write_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP,
-				USBLEGSUP_DEFAULT);
-	} else {
-		spin_unlock_irq(&uhci->lock);
-		reset_hc(uhci);
-		if ((rc = start_hc(uhci)) != 0)
-			return rc;
-		spin_lock_irq(&uhci->lock);
-	}
-	hcd->state = HC_STATE_RUNNING;
+	uhci->hc_inaccessible = 0;
+
+	/* The BIOS may have changed the controller settings during a
+	 * system wakeup.  Check it and reconfigure to avoid problems.
+	 */
+	check_and_reset_hc(uhci);
+	configure_hc(uhci);
+
+#ifndef CONFIG_USB_SUSPEND
+	/* Otherwise this would never happen */
+	wakeup_rh(uhci);
+#endif
+	if (uhci->rh_state == UHCI_RH_RESET)
+		suspend_rh(uhci, UHCI_RH_SUSPENDED);
 
 	spin_unlock_irq(&uhci->lock);
+
+	if (hcd->poll_rh)
+		usb_hcd_poll_rh_status(hcd);
 	return 0;
 }
 #endif
@@ -788,13 +868,15 @@ static void uhci_hcd_endpoint_disable(st
 static int uhci_hcd_get_frame_number(struct usb_hcd *hcd)
 {
 	struct uhci_hcd *uhci = hcd_to_uhci(hcd);
-	int frame_number;
 	unsigned long flags;
+	int is_stopped;
+	int frame_number;
 
 	/* Minimize latency by avoiding the spinlock */
 	local_irq_save(flags);
-	rmb();
-	frame_number = (uhci->is_stopped ? uhci->frame_number :
+	is_stopped = uhci->is_stopped;
+	smp_rmb();
+	frame_number = (is_stopped ? uhci->frame_number :
 			inw(uhci->io_addr + USBFRNUM));
 	local_irq_restore(flags);
 	return frame_number;
@@ -817,6 +899,8 @@ static const struct hc_driver uhci_drive
 #ifdef CONFIG_PM
 	.suspend =		uhci_suspend,
 	.resume =		uhci_resume,
+	.hub_suspend =		uhci_rh_suspend,
+	.hub_resume =		uhci_rh_resume,
 #endif
 	.stop =			uhci_stop,
 
@@ -845,6 +929,7 @@ static struct pci_driver uhci_pci_driver
 
 	.probe =	usb_hcd_pci_probe,
 	.remove =	usb_hcd_pci_remove,
+	.shutdown =	uhci_shutdown,
 
 #ifdef	CONFIG_PM
 	.suspend =	usb_hcd_pci_suspend,
diff --git a/drivers/usb/host/uhci-hcd.h b/drivers/usb/host/uhci-hcd.h
--- a/drivers/usb/host/uhci-hcd.h
+++ b/drivers/usb/host/uhci-hcd.h
@@ -41,6 +41,7 @@
 #define USBFRNUM	6
 #define USBFLBASEADD	8
 #define USBSOF		12
+#define   USBSOF_DEFAULT	64	/* Frame length is exactly 1 ms */
 
 /* USB port status and control registers */
 #define USBPORTSC1	16
@@ -66,6 +67,8 @@
 /* Legacy support register */
 #define USBLEGSUP		0xc0
 #define   USBLEGSUP_DEFAULT	0x2000	/* only PIRQ enable set */
+#define   USBLEGSUP_RWC		0x8f00	/* the R/WC bits */
+#define   USBLEGSUP_RO		0x5040	/* R/O and reserved bits */
 
 #define UHCI_NULL_DATA_SIZE	0x7FF	/* for UHCI controller TD */
 
@@ -111,7 +114,6 @@ struct uhci_qh {
 	/* Software fields */
 	dma_addr_t dma_handle;
 
-	struct usb_device *dev;
 	struct urb_priv *urbp;
 
 	struct list_head list;		/* P: uhci->frame_list_lock */
@@ -203,7 +205,6 @@ struct uhci_td {
 	/* Software fields */
 	dma_addr_t dma_handle;
 
-	struct usb_device *dev;
 	struct urb *urb;
 
 	struct list_head list;		/* P: urb->lock */
@@ -314,26 +315,32 @@ static inline int __interval_to_skel(int
 }
 
 /*
- * Device states for the host controller.
+ * States for the root hub.
  *
  * To prevent "bouncing" in the presence of electrical noise,
- * we insist on a 1-second "grace" period, before switching to
- * the RUNNING or SUSPENDED states, during which the state is
- * not allowed to change.
- *
- * The resume process is divided into substates in order to avoid
- * potentially length delays during the timer handler.
- *
- * States in which the host controller is halted must have values <= 0.
- */
-enum uhci_state {
-	UHCI_RESET,
-	UHCI_RUNNING_GRACE,		/* Before RUNNING */
-	UHCI_RUNNING,			/* The normal state */
-	UHCI_SUSPENDING_GRACE,		/* Before SUSPENDED */
-	UHCI_SUSPENDED = -10,		/* When no devices are attached */
-	UHCI_RESUMING_1,
-	UHCI_RESUMING_2
+ * when there are no devices attached we delay for 1 second in the
+ * RUNNING_NODEVS state before switching to the AUTO_STOPPED state.
+ * 
+ * (Note that the AUTO_STOPPED state won't be necessary once the hub
+ * driver learns to autosuspend.)
+ */
+enum uhci_rh_state {
+	/* In the following states the HC must be halted.
+	 * These two must come first */
+	UHCI_RH_RESET,
+	UHCI_RH_SUSPENDED,
+
+	UHCI_RH_AUTO_STOPPED,
+	UHCI_RH_RESUMING,
+
+	/* In this state the HC changes from running to halted,
+	 * so it can legally appear either way. */
+	UHCI_RH_SUSPENDING,
+
+	/* In the following states it's an error if the HC is halted.
+	 * These two must come last */
+	UHCI_RH_RUNNING,		/* The normal state */
+	UHCI_RH_RUNNING_NODEVS,		/* Running with no devices attached */
 };
 
 /*
@@ -363,15 +370,16 @@ struct uhci_hcd {
 	int fsbr;				/* Full-speed bandwidth reclamation */
 	unsigned long fsbrtimeout;		/* FSBR delay */
 
-	enum uhci_state state;			/* FIXME: needs a spinlock */
-	unsigned long state_end;		/* Time of next transition */
+	enum uhci_rh_state rh_state;
+	unsigned long auto_stop_time;		/* When to AUTO_STOP */
+
 	unsigned int frame_number;		/* As of last check */
 	unsigned int is_stopped;
 #define UHCI_IS_STOPPED		9999		/* Larger than a frame # */
 
 	unsigned int scan_in_progress:1;	/* Schedule scan is running */
 	unsigned int need_rescan:1;		/* Redo the schedule scan */
-	unsigned int resume_detect:1;		/* Need a Global Resume */
+	unsigned int hc_inaccessible:1;		/* HC is suspended or dead */
 
 	/* Support for port suspend/resume/reset */
 	unsigned long port_c_suspend;		/* Bit-arrays of ports */
@@ -451,4 +459,11 @@ struct urb_priv {
  * #2 urb->lock
  */
 
+
+/* Some special IDs */
+
+#define PCI_VENDOR_ID_GENESYS		0x17a0
+#define PCI_DEVICE_ID_GL880S_UHCI	0x8083
+#define PCI_DEVICE_ID_GL880S_EHCI	0x8084
+
 #endif
diff --git a/drivers/usb/host/uhci-hub.c b/drivers/usb/host/uhci-hub.c
--- a/drivers/usb/host/uhci-hub.c
+++ b/drivers/usb/host/uhci-hub.c
@@ -33,9 +33,24 @@ static __u8 root_hub_hub_des[] =
 /* status change bits:  nonzero writes will clear */
 #define RWC_BITS	(USBPORTSC_OCC | USBPORTSC_PEC | USBPORTSC_CSC)
 
-static int uhci_hub_status_data(struct usb_hcd *hcd, char *buf)
+/* A port that either is connected or has a changed-bit set will prevent
+ * us from AUTO_STOPPING.
+ */
+static int any_ports_active(struct uhci_hcd *uhci)
+{
+	int port;
+
+	for (port = 0; port < uhci->rh_numports; ++port) {
+		if ((inw(uhci->io_addr + USBPORTSC1 + port * 2) &
+				(USBPORTSC_CCS | RWC_BITS)) ||
+				test_bit(port, &uhci->port_c_suspend))
+			return 1;
+	}
+	return 0;
+}
+
+static inline int get_hub_status_data(struct uhci_hcd *uhci, char *buf)
 {
-	struct uhci_hcd *uhci = hcd_to_uhci(hcd);
 	int port;
 
 	*buf = 0;
@@ -44,8 +59,6 @@ static int uhci_hub_status_data(struct u
 				test_bit(port, &uhci->port_c_suspend))
 			*buf |= (1 << (port + 1));
 	}
-	if (*buf && uhci->state == UHCI_SUSPENDED)
-		uhci->resume_detect = 1;
 	return !!*buf;
 }
 
@@ -115,6 +128,11 @@ static void uhci_check_ports(struct uhci
 				set_bit(port, &uhci->resuming_ports);
 				uhci->ports_timeout = jiffies +
 						msecs_to_jiffies(20);
+
+				/* Make sure we see the port again
+				 * after the resuming period is over. */
+				mod_timer(&uhci_to_hcd(uhci)->rh_timer,
+						uhci->ports_timeout);
 			} else if (time_after_eq(jiffies,
 						uhci->ports_timeout)) {
 				uhci_finish_suspend(uhci, port, port_addr);
@@ -123,6 +141,60 @@ static void uhci_check_ports(struct uhci
 	}
 }
 
+static int uhci_hub_status_data(struct usb_hcd *hcd, char *buf)
+{
+	struct uhci_hcd *uhci = hcd_to_uhci(hcd);
+	unsigned long flags;
+	int status;
+
+	spin_lock_irqsave(&uhci->lock, flags);
+	if (uhci->hc_inaccessible) {
+		status = 0;
+		goto done;
+	}
+
+	uhci_check_ports(uhci);
+	status = get_hub_status_data(uhci, buf);
+
+	switch (uhci->rh_state) {
+	    case UHCI_RH_SUSPENDING:
+	    case UHCI_RH_SUSPENDED:
+		/* if port change, ask to be resumed */
+		if (status)
+			usb_hcd_resume_root_hub(hcd);
+		break;
+
+	    case UHCI_RH_AUTO_STOPPED:
+		/* if port change, auto start */
+		if (status)
+			wakeup_rh(uhci);
+		break;
+
+	    case UHCI_RH_RUNNING:
+		/* are any devices attached? */
+		if (!any_ports_active(uhci)) {
+			uhci->rh_state = UHCI_RH_RUNNING_NODEVS;
+			uhci->auto_stop_time = jiffies + HZ;
+		}
+		break;
+
+	    case UHCI_RH_RUNNING_NODEVS:
+		/* auto-stop if nothing connected for 1 second */
+		if (any_ports_active(uhci))
+			uhci->rh_state = UHCI_RH_RUNNING;
+		else if (time_after_eq(jiffies, uhci->auto_stop_time))
+			suspend_rh(uhci, UHCI_RH_AUTO_STOPPED);
+		break;
+
+	    default:
+		break;
+	}
+
+done:
+	spin_unlock_irqrestore(&uhci->lock, flags);
+	return status;
+}
+
 /* size of returned buffer is part of USB spec */
 static int uhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 			u16 wIndex, char *buf, u16 wLength)
@@ -134,6 +206,9 @@ static int uhci_hub_control(struct usb_h
 	u16 wPortChange, wPortStatus;
 	unsigned long flags;
 
+	if (uhci->hc_inaccessible)
+		return -ETIMEDOUT;
+
 	spin_lock_irqsave(&uhci->lock, flags);
 	switch (typeReq) {
 
diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c
--- a/drivers/usb/host/uhci-q.c
+++ b/drivers/usb/host/uhci-q.c
@@ -32,6 +32,8 @@ static void uhci_free_pending_tds(struct
  */
 static inline void uhci_set_next_interrupt(struct uhci_hcd *uhci)
 {
+	if (uhci->is_stopped)
+		mod_timer(&uhci->stall_timer, jiffies);
 	uhci->term_td->status |= cpu_to_le32(TD_CTRL_IOC); 
 }
 
@@ -46,7 +48,7 @@ static inline void uhci_moveto_complete(
 	list_move_tail(&urbp->urb_list, &uhci->complete_list);
 }
 
-static struct uhci_td *uhci_alloc_td(struct uhci_hcd *uhci, struct usb_device *dev)
+static struct uhci_td *uhci_alloc_td(struct uhci_hcd *uhci)
 {
 	dma_addr_t dma_handle;
 	struct uhci_td *td;
@@ -61,14 +63,11 @@ static struct uhci_td *uhci_alloc_td(str
 	td->buffer = 0;
 
 	td->frame = -1;
-	td->dev = dev;
 
 	INIT_LIST_HEAD(&td->list);
 	INIT_LIST_HEAD(&td->remove_list);
 	INIT_LIST_HEAD(&td->fl_list);
 
-	usb_get_dev(dev);
-
 	return td;
 }
 
@@ -168,13 +167,10 @@ static void uhci_free_td(struct uhci_hcd
 	if (!list_empty(&td->fl_list))
 		dev_warn(uhci_dev(uhci), "td %p still in fl_list!\n", td);
 
-	if (td->dev)
-		usb_put_dev(td->dev);
-
 	dma_pool_free(uhci->td_pool, td, td->dma_handle);
 }
 
-static struct uhci_qh *uhci_alloc_qh(struct uhci_hcd *uhci, struct usb_device *dev)
+static struct uhci_qh *uhci_alloc_qh(struct uhci_hcd *uhci)
 {
 	dma_addr_t dma_handle;
 	struct uhci_qh *qh;
@@ -188,14 +184,11 @@ static struct uhci_qh *uhci_alloc_qh(str
 	qh->element = UHCI_PTR_TERM;
 	qh->link = UHCI_PTR_TERM;
 
-	qh->dev = dev;
 	qh->urbp = NULL;
 
 	INIT_LIST_HEAD(&qh->list);
 	INIT_LIST_HEAD(&qh->remove_list);
 
-	usb_get_dev(dev);
-
 	return qh;
 }
 
@@ -206,9 +199,6 @@ static void uhci_free_qh(struct uhci_hcd
 	if (!list_empty(&qh->remove_list))
 		dev_warn(uhci_dev(uhci), "qh %p still in remove_list!\n", qh);
 
-	if (qh->dev)
-		usb_put_dev(qh->dev);
-
 	dma_pool_free(uhci->qh_pool, qh, qh->dma_handle);
 }
 
@@ -597,7 +587,7 @@ static int uhci_submit_control(struct uh
 	/*
 	 * Build the TD for the control request setup packet
 	 */
-	td = uhci_alloc_td(uhci, urb->dev);
+	td = uhci_alloc_td(uhci);
 	if (!td)
 		return -ENOMEM;
 
@@ -626,7 +616,7 @@ static int uhci_submit_control(struct uh
 		if (pktsze > maxsze)
 			pktsze = maxsze;
 
-		td = uhci_alloc_td(uhci, urb->dev);
+		td = uhci_alloc_td(uhci);
 		if (!td)
 			return -ENOMEM;
 
@@ -644,7 +634,7 @@ static int uhci_submit_control(struct uh
 	/*
 	 * Build the final TD for control status 
 	 */
-	td = uhci_alloc_td(uhci, urb->dev);
+	td = uhci_alloc_td(uhci);
 	if (!td)
 		return -ENOMEM;
 
@@ -666,7 +656,7 @@ static int uhci_submit_control(struct uh
 	uhci_fill_td(td, status | TD_CTRL_IOC,
 		destination | uhci_explen(UHCI_NULL_DATA_SIZE), 0);
 
-	qh = uhci_alloc_qh(uhci, urb->dev);
+	qh = uhci_alloc_qh(uhci);
 	if (!qh)
 		return -ENOMEM;
 
@@ -865,7 +855,7 @@ static int uhci_submit_common(struct uhc
 				status &= ~TD_CTRL_SPD;
 		}
 
-		td = uhci_alloc_td(uhci, urb->dev);
+		td = uhci_alloc_td(uhci);
 		if (!td)
 			return -ENOMEM;
 
@@ -891,7 +881,7 @@ static int uhci_submit_common(struct uhc
 	 */
 	if (usb_pipeout(urb->pipe) && (urb->transfer_flags & URB_ZERO_PACKET) &&
 	    !len && urb->transfer_buffer_length) {
-		td = uhci_alloc_td(uhci, urb->dev);
+		td = uhci_alloc_td(uhci);
 		if (!td)
 			return -ENOMEM;
 
@@ -913,7 +903,7 @@ static int uhci_submit_common(struct uhc
 	 * flag setting. */
 	td->status |= cpu_to_le32(TD_CTRL_IOC);
 
-	qh = uhci_alloc_qh(uhci, urb->dev);
+	qh = uhci_alloc_qh(uhci);
 	if (!qh)
 		return -ENOMEM;
 
@@ -1096,7 +1086,7 @@ static int uhci_submit_isochronous(struc
 		if (!urb->iso_frame_desc[i].length)
 			continue;
 
-		td = uhci_alloc_td(uhci, urb->dev);
+		td = uhci_alloc_td(uhci);
 		if (!td)
 			return -ENOMEM;
 
@@ -1174,7 +1164,7 @@ static struct urb *uhci_find_urb_ep(stru
 
 static int uhci_urb_enqueue(struct usb_hcd *hcd,
 		struct usb_host_endpoint *ep,
-		struct urb *urb, int mem_flags)
+		struct urb *urb, unsigned mem_flags)
 {
 	int ret;
 	struct uhci_hcd *uhci = hcd_to_uhci(hcd);
@@ -1497,6 +1487,7 @@ static void uhci_scan_schedule(struct uh
  rescan:
 	uhci->need_rescan = 0;
 
+	uhci_clear_next_interrupt(uhci);
 	uhci_get_current_frame_number(uhci);
 
 	if (uhci->frame_number + uhci->is_stopped != uhci->qh_remove_age)
@@ -1537,3 +1528,26 @@ static void uhci_scan_schedule(struct uh
 	/* Wake up anyone waiting for an URB to complete */
 	wake_up_all(&uhci->waitqh);
 }
+
+static void check_fsbr(struct uhci_hcd *uhci)
+{
+	struct urb_priv *up;
+
+	list_for_each_entry(up, &uhci->urb_list, urb_list) {
+		struct urb *u = up->urb;
+
+		spin_lock(&u->lock);
+
+		/* Check if the FSBR timed out */
+		if (up->fsbr && !up->fsbr_timeout && time_after_eq(jiffies, up->fsbrtime + IDLE_TIMEOUT))
+			uhci_fsbr_timeout(uhci, u);
+
+		spin_unlock(&u->lock);
+	}
+
+	/* Really disable FSBR */
+	if (!uhci->fsbr && uhci->fsbrtimeout && time_after_eq(jiffies, uhci->fsbrtimeout)) {
+		uhci->fsbrtimeout = 0;
+		uhci->skel_term_qh->link = UHCI_PTR_TERM;
+	}
+}
diff --git a/drivers/usb/image/microtek.c b/drivers/usb/image/microtek.c
--- a/drivers/usb/image/microtek.c
+++ b/drivers/usb/image/microtek.c
@@ -361,8 +361,7 @@ int mts_scsi_queuecommand (Scsi_Cmnd *sr
 static void mts_transfer_cleanup( struct urb *transfer );
 static void mts_do_sg(struct urb * transfer, struct pt_regs *regs);
 
-
-inline static
+static inline
 void mts_int_submit_urb (struct urb* transfer,
 			int pipe,
 			void* data,
diff --git a/drivers/usb/input/Kconfig b/drivers/usb/input/Kconfig
--- a/drivers/usb/input/Kconfig
+++ b/drivers/usb/input/Kconfig
@@ -151,6 +151,18 @@ config USB_WACOM
 	  To compile this driver as a module, choose M here: the
 	  module will be called wacom.
 
+config USB_ACECAD
+	tristate "Acecad Flair tablet support"
+	depends on USB && INPUT
+	help
+	  Say Y here if you want to use the USB version of the Acecad Flair
+	  tablet.  Make sure to say Y to "Mouse support"
+	  (CONFIG_INPUT_MOUSEDEV) and/or "Event interface support"
+	  (CONFIG_INPUT_EVDEV) as well.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called acecad.
+
 config USB_KBTAB
 	tristate "KB Gear JamStudio tablet support"
 	depends on USB && INPUT
@@ -190,6 +202,18 @@ config USB_MTOUCH
 	  To compile this driver as a module, choose M here: the
 	  module will be called mtouchusb.
 
+config USB_ITMTOUCH
+	tristate "ITM Touch USB Touchscreen Driver"
+	depends on USB && INPUT
+	---help---
+	  Say Y here if you want to use a ITM Touch USB
+	  Touchscreen controller.
+
+	  This touchscreen is used in LG 1510SF monitors.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called itmtouch.
+
 config USB_EGALAX
 	tristate "eGalax TouchKit USB Touchscreen Driver"
 	depends on USB && INPUT
@@ -235,3 +259,16 @@ config USB_ATI_REMOTE
 	  To compile this driver as a module, choose M here: the module will be
 	  called ati_remote.
 
+config USB_KEYSPAN_REMOTE
+	tristate "Keyspan DMR USB remote control (EXPERIMENTAL)"
+	depends on USB && INPUT && EXPERIMENTAL
+	---help---
+	  Say Y here if you want to use a Keyspan DMR USB remote control.
+	  Currently only the UIA-11 type of receiver has been tested.  The tag
+	  on the receiver that connects to the USB port should have a P/N that
+	  will tell you what type of DMR you have.  The UIA-10 type is not
+	  supported at this time.  This driver maps all buttons to keypress
+	  events.
+
+	  To compile this driver as a module, choose M here: the module will
+	  be called keyspan_remote.
diff --git a/drivers/usb/input/Makefile b/drivers/usb/input/Makefile
--- a/drivers/usb/input/Makefile
+++ b/drivers/usb/input/Makefile
@@ -31,9 +31,12 @@ obj-$(CONFIG_USB_ATI_REMOTE)	+= ati_remo
 obj-$(CONFIG_USB_HID)		+= usbhid.o
 obj-$(CONFIG_USB_KBD)		+= usbkbd.o
 obj-$(CONFIG_USB_KBTAB)		+= kbtab.o
+obj-$(CONFIG_USB_KEYSPAN_REMOTE)	+= keyspan_remote.o
 obj-$(CONFIG_USB_MOUSE)		+= usbmouse.o
 obj-$(CONFIG_USB_MTOUCH)	+= mtouchusb.o
+obj-$(CONFIG_USB_ITMTOUCH)	+= itmtouch.o
 obj-$(CONFIG_USB_EGALAX)	+= touchkitusb.o
 obj-$(CONFIG_USB_POWERMATE)	+= powermate.o
 obj-$(CONFIG_USB_WACOM)		+= wacom.o
+obj-$(CONFIG_USB_ACECAD)	+= acecad.o
 obj-$(CONFIG_USB_XPAD)		+= xpad.o
diff --git a/drivers/usb/input/acecad.c b/drivers/usb/input/acecad.c
new file mode 100644
--- /dev/null
+++ b/drivers/usb/input/acecad.c
@@ -0,0 +1,283 @@
+/*
+ *  Copyright (c) 2001-2005 Edouard TISSERANT   <edouard.tisserant@wanadoo.fr>
+ *  Copyright (c) 2004-2005 Stephane VOLTZ      <svoltz@numericable.fr>
+ *
+ *  USB Acecad "Acecad Flair" tablet support
+ *
+ *  Changelog:
+ *      v3.2 - Added sysfs support
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/input.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/usb.h>
+#include <linux/usb_input.h>
+
+/*
+ * Version Information
+ */
+#define DRIVER_VERSION "v3.2"
+#define DRIVER_DESC    "USB Acecad Flair tablet driver"
+#define DRIVER_LICENSE "GPL"
+#define DRIVER_AUTHOR  "Edouard TISSERANT <edouard.tisserant@wanadoo.fr>"
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE(DRIVER_LICENSE);
+
+#define USB_VENDOR_ID_ACECAD	0x0460
+#define USB_DEVICE_ID_FLAIR	0x0004
+#define USB_DEVICE_ID_302	0x0008
+
+struct usb_acecad {
+	char name[128];
+	char phys[64];
+	struct usb_device *usbdev;
+	struct input_dev dev;
+	struct urb *irq;
+
+	signed char *data;
+	dma_addr_t data_dma;
+};
+
+static void usb_acecad_irq(struct urb *urb, struct pt_regs *regs)
+{
+	struct usb_acecad *acecad = urb->context;
+	unsigned char *data = acecad->data;
+	struct input_dev *dev = &acecad->dev;
+	int prox, status;
+
+	switch (urb->status) {
+		case 0:
+			/* success */
+			break;
+		case -ECONNRESET:
+		case -ENOENT:
+		case -ESHUTDOWN:
+			/* this urb is terminated, clean up */
+			dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status);
+			return;
+		default:
+			dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status);
+			goto resubmit;
+	}
+
+	prox = (data[0] & 0x04) >> 2;
+	input_report_key(dev, BTN_TOOL_PEN, prox);
+
+	if (prox) {
+		int x = data[1] | (data[2] << 8);
+		int y = data[3] | (data[4] << 8);
+		/* Pressure should compute the same way for flair and 302 */
+		int pressure = data[5] | (data[6] << 8);
+		int touch = data[0] & 0x01;
+		int stylus = (data[0] & 0x10) >> 4;
+		int stylus2 = (data[0] & 0x20) >> 5;
+		input_report_abs(dev, ABS_X, x);
+		input_report_abs(dev, ABS_Y, y);
+		input_report_abs(dev, ABS_PRESSURE, pressure);
+		input_report_key(dev, BTN_TOUCH, touch);
+		input_report_key(dev, BTN_STYLUS, stylus);
+		input_report_key(dev, BTN_STYLUS2, stylus2);
+	}
+
+	/* event termination */
+	input_sync(dev);
+
+resubmit:
+	status = usb_submit_urb(urb, GFP_ATOMIC);
+	if (status)
+		err("can't resubmit intr, %s-%s/input0, status %d",
+			acecad->usbdev->bus->bus_name, acecad->usbdev->devpath, status);
+}
+
+static int usb_acecad_open(struct input_dev *dev)
+{
+	struct usb_acecad *acecad = dev->private;
+
+	acecad->irq->dev = acecad->usbdev;
+	if (usb_submit_urb(acecad->irq, GFP_KERNEL))
+		return -EIO;
+
+	return 0;
+}
+
+static void usb_acecad_close(struct input_dev *dev)
+{
+	struct usb_acecad *acecad = dev->private;
+
+	usb_kill_urb(acecad->irq);
+}
+
+static int usb_acecad_probe(struct usb_interface *intf, const struct usb_device_id *id)
+{
+	struct usb_device *dev = interface_to_usbdev(intf);
+	struct usb_host_interface *interface = intf->cur_altsetting;
+	struct usb_endpoint_descriptor *endpoint;
+	struct usb_acecad *acecad;
+	int pipe, maxp;
+	char path[64];
+
+	if (interface->desc.bNumEndpoints != 1)
+		return -ENODEV;
+
+	endpoint = &interface->endpoint[0].desc;
+
+	if (!(endpoint->bEndpointAddress & 0x80))
+		return -ENODEV;
+
+	if ((endpoint->bmAttributes & 3) != 3)
+		return -ENODEV;
+
+	pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
+	maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
+
+	acecad = kcalloc(1, sizeof(struct usb_acecad), GFP_KERNEL);
+	if (!acecad)
+		return -ENOMEM;
+
+	acecad->data = usb_buffer_alloc(dev, 8, SLAB_KERNEL, &acecad->data_dma);
+	if (!acecad->data)
+		goto fail1;
+
+	acecad->irq = usb_alloc_urb(0, GFP_KERNEL);
+	if (!acecad->irq)
+		goto fail2;
+
+	if (dev->manufacturer)
+		strlcpy(acecad->name, dev->manufacturer, sizeof(acecad->name));
+
+	if (dev->product) {
+		if (dev->manufacturer)
+			strlcat(acecad->name, " ", sizeof(acecad->name));
+		strlcat(acecad->name, dev->product, sizeof(acecad->name));
+	}
+
+	usb_make_path(dev, path, sizeof(path));
+	snprintf(acecad->phys, sizeof(acecad->phys), "%s/input0", path);
+
+	acecad->usbdev = dev;
+
+	acecad->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+	acecad->dev.absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE);
+	acecad->dev.keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
+	acecad->dev.keybit[LONG(BTN_DIGI)] = BIT(BTN_TOOL_PEN) |BIT(BTN_TOUCH) | BIT(BTN_STYLUS) | BIT(BTN_STYLUS2);
+
+	switch (id->driver_info) {
+		case 0:
+			acecad->dev.absmax[ABS_X] = 5000;
+			acecad->dev.absmax[ABS_Y] = 3750;
+			acecad->dev.absmax[ABS_PRESSURE] = 512;
+			if (!strlen(acecad->name))
+				snprintf(acecad->name, sizeof(acecad->name),
+					"USB Acecad Flair Tablet %04x:%04x",
+					dev->descriptor.idVendor, dev->descriptor.idProduct);
+			break;
+		case 1:
+			acecad->dev.absmax[ABS_X] = 3000;
+			acecad->dev.absmax[ABS_Y] = 2250;
+			acecad->dev.absmax[ABS_PRESSURE] = 1024;
+			if (!strlen(acecad->name))
+				snprintf(acecad->name, sizeof(acecad->name),
+					"USB Acecad 302 Tablet %04x:%04x",
+					dev->descriptor.idVendor, dev->descriptor.idProduct);
+			break;
+	}
+
+	acecad->dev.absfuzz[ABS_X] = 4;
+	acecad->dev.absfuzz[ABS_Y] = 4;
+
+	acecad->dev.private = acecad;
+	acecad->dev.open = usb_acecad_open;
+	acecad->dev.close = usb_acecad_close;
+
+	acecad->dev.name = acecad->name;
+	acecad->dev.phys = acecad->phys;
+	usb_to_input_id(dev, &acecad->dev.id);
+	acecad->dev.dev = &intf->dev;
+
+	usb_fill_int_urb(acecad->irq, dev, pipe,
+			acecad->data, maxp > 8 ? 8 : maxp,
+			usb_acecad_irq, acecad, endpoint->bInterval);
+	acecad->irq->transfer_dma = acecad->data_dma;
+	acecad->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+
+	input_register_device(&acecad->dev);
+
+	printk(KERN_INFO "input: %s with packet size %d on %s\n",
+		acecad->name, maxp, path);
+
+	usb_set_intfdata(intf, acecad);
+
+	return 0;
+
+ fail2:	usb_buffer_free(dev, 8, acecad->data, acecad->data_dma);
+ fail1:	kfree(acecad);
+	return -ENOMEM;
+}
+
+static void usb_acecad_disconnect(struct usb_interface *intf)
+{
+	struct usb_acecad *acecad = usb_get_intfdata(intf);
+
+	usb_set_intfdata(intf, NULL);
+	if (acecad) {
+		usb_kill_urb(acecad->irq);
+		input_unregister_device(&acecad->dev);
+		usb_free_urb(acecad->irq);
+		usb_buffer_free(interface_to_usbdev(intf), 10, acecad->data, acecad->data_dma);
+		kfree(acecad);
+	}
+}
+
+static struct usb_device_id usb_acecad_id_table [] = {
+	{ USB_DEVICE(USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_FLAIR), .driver_info = 0 },
+	{ USB_DEVICE(USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_302),	 .driver_info = 1 },
+	{ }
+};
+
+MODULE_DEVICE_TABLE(usb, usb_acecad_id_table);
+
+static struct usb_driver usb_acecad_driver = {
+	.owner =	THIS_MODULE,
+	.name =		"usb_acecad",
+	.probe =	usb_acecad_probe,
+	.disconnect =	usb_acecad_disconnect,
+	.id_table =	usb_acecad_id_table,
+};
+
+static int __init usb_acecad_init(void)
+{
+	int result = usb_register(&usb_acecad_driver);
+	if (result == 0)
+		info(DRIVER_VERSION ":" DRIVER_DESC);
+	return result;
+}
+
+static void __exit usb_acecad_exit(void)
+{
+	usb_deregister(&usb_acecad_driver);
+}
+
+module_init(usb_acecad_init);
+module_exit(usb_acecad_exit);
diff --git a/drivers/usb/input/aiptek.c b/drivers/usb/input/aiptek.c
--- a/drivers/usb/input/aiptek.c
+++ b/drivers/usb/input/aiptek.c
@@ -1,7 +1,7 @@
 /*
  *  Native support for the Aiptek HyperPen USB Tablets
  *  (4000U/5000U/6000U/8000U/12000U)
- *  
+ *
  *  Copyright (c) 2001      Chris Atenasio   <chris@crud.net>
  *  Copyright (c) 2002-2004 Bryan W. Headley <bwheadley@earthlink.net>
  *
@@ -31,7 +31,7 @@
  *           - Added support for the sysfs interface, deprecating the
  *             procfs interface for 2.5.x kernel. Also added support for
  *             Wheel command. Bryan W. Headley July-15-2003.
- *      v1.2 - Reworked jitter timer as a kernel thread. 
+ *      v1.2 - Reworked jitter timer as a kernel thread.
  *             Bryan W. Headley November-28-2003/Jan-10-2004.
  *      v1.3 - Repaired issue of kernel thread going nuts on single-processor
  *             machines, introduced programmableDelay as a command line
@@ -49,10 +49,10 @@
  * NOTE:
  *      This kernel driver is augmented by the "Aiptek" XFree86 input
  *      driver for your X server, as well as the Gaiptek GUI Front-end
- *      "Tablet Manager". 
- *      These three products are highly interactive with one another, 
+ *      "Tablet Manager".
+ *      These three products are highly interactive with one another,
  *      so therefore it's easier to document them all as one subsystem.
- *      Please visit the project's "home page", located at, 
+ *      Please visit the project's "home page", located at,
  *      http://aiptektablet.sourceforge.net.
  *
  * This program is free software; you can redistribute it and/or modify
@@ -77,6 +77,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/usb.h>
+#include <linux/usb_input.h>
 #include <linux/sched.h>
 #include <asm/uaccess.h>
 #include <asm/unaligned.h>
@@ -156,7 +157,7 @@
  * Command/Data    Description     Return Bytes    Return Value
  * 0x10/0x00       SwitchToMouse       0
  * 0x10/0x01       SwitchToTablet      0
- * 0x18/0x04       SetResolution       0 
+ * 0x18/0x04       SetResolution       0
  * 0x12/0xFF       AutoGainOn          0
  * 0x17/0x00       FilterOn            0
  * 0x01/0x00       GetXExtension       2           MaxX
@@ -247,7 +248,7 @@
 #define AIPTEK_DIAGNOSTIC_SENDING_ABSOLUTE_IN_RELATIVE	2
 #define AIPTEK_DIAGNOSTIC_TOOL_DISALLOWED		3
 
-	/* Time to wait (in ms) to help mask hand jittering 
+	/* Time to wait (in ms) to help mask hand jittering
 	 * when pressing the stylus buttons.
 	 */
 #define AIPTEK_JITTER_DELAY_DEFAULT			50
@@ -324,7 +325,6 @@ struct aiptek {
 	struct aiptek_settings curSetting;	/* tablet's current programmable */
 	struct aiptek_settings newSetting;	/* ... and new param settings    */
 	unsigned int ifnum;			/* interface number for IO       */
-	int openCount;				/* module use counter            */
 	int diagnostic;				/* tablet diagnostic codes       */
 	unsigned long eventCount;		/* event count                   */
 	int inDelay;				/* jitter: in jitter delay?      */
@@ -791,7 +791,7 @@ exit:
  * specific Aiptek model numbers, because there has been overlaps,
  * use, and reuse of id's in existing models. Certain models have
  * been known to use more than one ID, indicative perhaps of
- * manufacturing revisions. In any event, we consider these 
+ * manufacturing revisions. In any event, we consider these
  * IDs to not be model-specific nor unique.
  */
 static const struct usb_device_id aiptek_ids[] = {
@@ -814,15 +814,9 @@ static int aiptek_open(struct input_dev 
 {
 	struct aiptek *aiptek = inputdev->private;
 
-	if (aiptek->openCount++ > 0) {
-		return 0;
-	}
-
 	aiptek->urb->dev = aiptek->usbdev;
-	if (usb_submit_urb(aiptek->urb, GFP_KERNEL) != 0) {
-		aiptek->openCount--;
+	if (usb_submit_urb(aiptek->urb, GFP_KERNEL) != 0)
 		return -EIO;
-	}
 
 	return 0;
 }
@@ -834,13 +828,11 @@ static void aiptek_close(struct input_de
 {
 	struct aiptek *aiptek = inputdev->private;
 
-	if (--aiptek->openCount == 0) {
-		usb_kill_urb(aiptek->urb);
-	}
+	usb_kill_urb(aiptek->urb);
 }
 
 /***********************************************************************
- * aiptek_set_report and aiptek_get_report() are borrowed from Linux 2.4.x, 
+ * aiptek_set_report and aiptek_get_report() are borrowed from Linux 2.4.x,
  * where they were known as usb_set_report and usb_get_report.
  */
 static int
@@ -1025,7 +1017,7 @@ static int aiptek_program_tablet(struct 
 /***********************************************************************
  * support the 'size' file -- display support
  */
-static ssize_t show_tabletSize(struct device *dev, char *buf)
+static ssize_t show_tabletSize(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct aiptek *aiptek = dev_get_drvdata(dev);
 
@@ -1048,7 +1040,7 @@ static DEVICE_ATTR(size, S_IRUGO, show_t
 /***********************************************************************
  * support routines for the 'product_id' file
  */
-static ssize_t show_tabletProductId(struct device *dev, char *buf)
+static ssize_t show_tabletProductId(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct aiptek *aiptek = dev_get_drvdata(dev);
 
@@ -1064,7 +1056,7 @@ static DEVICE_ATTR(product_id, S_IRUGO, 
 /***********************************************************************
  * support routines for the 'vendor_id' file
  */
-static ssize_t show_tabletVendorId(struct device *dev, char *buf)
+static ssize_t show_tabletVendorId(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct aiptek *aiptek = dev_get_drvdata(dev);
 
@@ -1079,7 +1071,7 @@ static DEVICE_ATTR(vendor_id, S_IRUGO, s
 /***********************************************************************
  * support routines for the 'vendor' file
  */
-static ssize_t show_tabletManufacturer(struct device *dev, char *buf)
+static ssize_t show_tabletManufacturer(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct aiptek *aiptek = dev_get_drvdata(dev);
 	int retval;
@@ -1096,7 +1088,7 @@ static DEVICE_ATTR(vendor, S_IRUGO, show
 /***********************************************************************
  * support routines for the 'product' file
  */
-static ssize_t show_tabletProduct(struct device *dev, char *buf)
+static ssize_t show_tabletProduct(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct aiptek *aiptek = dev_get_drvdata(dev);
 	int retval;
@@ -1114,7 +1106,7 @@ static DEVICE_ATTR(product, S_IRUGO, sho
  * support routines for the 'pointer_mode' file. Note that this file
  * both displays current setting and allows reprogramming.
  */
-static ssize_t show_tabletPointerMode(struct device *dev, char *buf)
+static ssize_t show_tabletPointerMode(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct aiptek *aiptek = dev_get_drvdata(dev);
 	char *s;
@@ -1143,7 +1135,7 @@ static ssize_t show_tabletPointerMode(st
 }
 
 static ssize_t
-store_tabletPointerMode(struct device *dev, const char *buf, size_t count)
+store_tabletPointerMode(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct aiptek *aiptek = dev_get_drvdata(dev);
 	if (aiptek == NULL)
@@ -1168,7 +1160,7 @@ static DEVICE_ATTR(pointer_mode,
  * support routines for the 'coordinate_mode' file. Note that this file
  * both displays current setting and allows reprogramming.
  */
-static ssize_t show_tabletCoordinateMode(struct device *dev, char *buf)
+static ssize_t show_tabletCoordinateMode(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct aiptek *aiptek = dev_get_drvdata(dev);
 	char *s;
@@ -1193,7 +1185,7 @@ static ssize_t show_tabletCoordinateMode
 }
 
 static ssize_t
-store_tabletCoordinateMode(struct device *dev, const char *buf, size_t count)
+store_tabletCoordinateMode(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct aiptek *aiptek = dev_get_drvdata(dev);
 	if (aiptek == NULL)
@@ -1217,7 +1209,7 @@ static DEVICE_ATTR(coordinate_mode,
  * support routines for the 'tool_mode' file. Note that this file
  * both displays current setting and allows reprogramming.
  */
-static ssize_t show_tabletToolMode(struct device *dev, char *buf)
+static ssize_t show_tabletToolMode(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct aiptek *aiptek = dev_get_drvdata(dev);
 	char *s;
@@ -1262,7 +1254,7 @@ static ssize_t show_tabletToolMode(struc
 }
 
 static ssize_t
-store_tabletToolMode(struct device *dev, const char *buf, size_t count)
+store_tabletToolMode(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct aiptek *aiptek = dev_get_drvdata(dev);
 	if (aiptek == NULL)
@@ -1295,7 +1287,7 @@ static DEVICE_ATTR(tool_mode,
  * support routines for the 'xtilt' file. Note that this file
  * both displays current setting and allows reprogramming.
  */
-static ssize_t show_tabletXtilt(struct device *dev, char *buf)
+static ssize_t show_tabletXtilt(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct aiptek *aiptek = dev_get_drvdata(dev);
 
@@ -1311,7 +1303,7 @@ static ssize_t show_tabletXtilt(struct d
 }
 
 static ssize_t
-store_tabletXtilt(struct device *dev, const char *buf, size_t count)
+store_tabletXtilt(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct aiptek *aiptek = dev_get_drvdata(dev);
 	int x;
@@ -1337,7 +1329,7 @@ static DEVICE_ATTR(xtilt,
  * support routines for the 'ytilt' file. Note that this file
  * both displays current setting and allows reprogramming.
  */
-static ssize_t show_tabletYtilt(struct device *dev, char *buf)
+static ssize_t show_tabletYtilt(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct aiptek *aiptek = dev_get_drvdata(dev);
 
@@ -1353,7 +1345,7 @@ static ssize_t show_tabletYtilt(struct d
 }
 
 static ssize_t
-store_tabletYtilt(struct device *dev, const char *buf, size_t count)
+store_tabletYtilt(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct aiptek *aiptek = dev_get_drvdata(dev);
 	int y;
@@ -1379,7 +1371,7 @@ static DEVICE_ATTR(ytilt,
  * support routines for the 'jitter' file. Note that this file
  * both displays current setting and allows reprogramming.
  */
-static ssize_t show_tabletJitterDelay(struct device *dev, char *buf)
+static ssize_t show_tabletJitterDelay(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct aiptek *aiptek = dev_get_drvdata(dev);
 
@@ -1390,7 +1382,7 @@ static ssize_t show_tabletJitterDelay(st
 }
 
 static ssize_t
-store_tabletJitterDelay(struct device *dev, const char *buf, size_t count)
+store_tabletJitterDelay(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct aiptek *aiptek = dev_get_drvdata(dev);
 
@@ -1409,7 +1401,7 @@ static DEVICE_ATTR(jitter,
  * support routines for the 'delay' file. Note that this file
  * both displays current setting and allows reprogramming.
  */
-static ssize_t show_tabletProgrammableDelay(struct device *dev, char *buf)
+static ssize_t show_tabletProgrammableDelay(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct aiptek *aiptek = dev_get_drvdata(dev);
 
@@ -1421,7 +1413,7 @@ static ssize_t show_tabletProgrammableDe
 }
 
 static ssize_t
-store_tabletProgrammableDelay(struct device *dev, const char *buf, size_t count)
+store_tabletProgrammableDelay(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct aiptek *aiptek = dev_get_drvdata(dev);
 
@@ -1440,7 +1432,7 @@ static DEVICE_ATTR(delay,
  * support routines for the 'input_path' file. Note that this file
  * only displays current setting.
  */
-static ssize_t show_tabletInputDevice(struct device *dev, char *buf)
+static ssize_t show_tabletInputDevice(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct aiptek *aiptek = dev_get_drvdata(dev);
 
@@ -1457,7 +1449,7 @@ static DEVICE_ATTR(input_path, S_IRUGO, 
  * support routines for the 'event_count' file. Note that this file
  * only displays current setting.
  */
-static ssize_t show_tabletEventsReceived(struct device *dev, char *buf)
+static ssize_t show_tabletEventsReceived(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct aiptek *aiptek = dev_get_drvdata(dev);
 
@@ -1473,7 +1465,7 @@ static DEVICE_ATTR(event_count, S_IRUGO,
  * support routines for the 'diagnostic' file. Note that this file
  * only displays current setting.
  */
-static ssize_t show_tabletDiagnosticMessage(struct device *dev, char *buf)
+static ssize_t show_tabletDiagnosticMessage(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct aiptek *aiptek = dev_get_drvdata(dev);
 	char *retMsg;
@@ -1515,7 +1507,7 @@ static DEVICE_ATTR(diagnostic, S_IRUGO, 
  * support routines for the 'stylus_upper' file. Note that this file
  * both displays current setting and allows for setting changing.
  */
-static ssize_t show_tabletStylusUpper(struct device *dev, char *buf)
+static ssize_t show_tabletStylusUpper(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct aiptek *aiptek = dev_get_drvdata(dev);
 	char *s;
@@ -1540,7 +1532,7 @@ static ssize_t show_tabletStylusUpper(st
 }
 
 static ssize_t
-store_tabletStylusUpper(struct device *dev, const char *buf, size_t count)
+store_tabletStylusUpper(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct aiptek *aiptek = dev_get_drvdata(dev);
 
@@ -1565,7 +1557,7 @@ static DEVICE_ATTR(stylus_upper,
  * support routines for the 'stylus_lower' file. Note that this file
  * both displays current setting and allows for setting changing.
  */
-static ssize_t show_tabletStylusLower(struct device *dev, char *buf)
+static ssize_t show_tabletStylusLower(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct aiptek *aiptek = dev_get_drvdata(dev);
 	char *s;
@@ -1590,7 +1582,7 @@ static ssize_t show_tabletStylusLower(st
 }
 
 static ssize_t
-store_tabletStylusLower(struct device *dev, const char *buf, size_t count)
+store_tabletStylusLower(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct aiptek *aiptek = dev_get_drvdata(dev);
 
@@ -1615,7 +1607,7 @@ static DEVICE_ATTR(stylus_lower,
  * support routines for the 'mouse_left' file. Note that this file
  * both displays current setting and allows for setting changing.
  */
-static ssize_t show_tabletMouseLeft(struct device *dev, char *buf)
+static ssize_t show_tabletMouseLeft(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct aiptek *aiptek = dev_get_drvdata(dev);
 	char *s;
@@ -1644,7 +1636,7 @@ static ssize_t show_tabletMouseLeft(stru
 }
 
 static ssize_t
-store_tabletMouseLeft(struct device *dev, const char *buf, size_t count)
+store_tabletMouseLeft(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct aiptek *aiptek = dev_get_drvdata(dev);
 
@@ -1669,7 +1661,7 @@ static DEVICE_ATTR(mouse_left,
  * support routines for the 'mouse_middle' file. Note that this file
  * both displays current setting and allows for setting changing.
  */
-static ssize_t show_tabletMouseMiddle(struct device *dev, char *buf)
+static ssize_t show_tabletMouseMiddle(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct aiptek *aiptek = dev_get_drvdata(dev);
 	char *s;
@@ -1698,7 +1690,7 @@ static ssize_t show_tabletMouseMiddle(st
 }
 
 static ssize_t
-store_tabletMouseMiddle(struct device *dev, const char *buf, size_t count)
+store_tabletMouseMiddle(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct aiptek *aiptek = dev_get_drvdata(dev);
 
@@ -1725,7 +1717,7 @@ static DEVICE_ATTR(mouse_middle,
  * support routines for the 'mouse_right' file. Note that this file
  * both displays current setting and allows for setting changing.
  */
-static ssize_t show_tabletMouseRight(struct device *dev, char *buf)
+static ssize_t show_tabletMouseRight(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct aiptek *aiptek = dev_get_drvdata(dev);
 	char *s;
@@ -1754,7 +1746,7 @@ static ssize_t show_tabletMouseRight(str
 }
 
 static ssize_t
-store_tabletMouseRight(struct device *dev, const char *buf, size_t count)
+store_tabletMouseRight(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct aiptek *aiptek = dev_get_drvdata(dev);
 
@@ -1780,7 +1772,7 @@ static DEVICE_ATTR(mouse_right,
  * support routines for the 'wheel' file. Note that this file
  * both displays current setting and allows for setting changing.
  */
-static ssize_t show_tabletWheel(struct device *dev, char *buf)
+static ssize_t show_tabletWheel(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct aiptek *aiptek = dev_get_drvdata(dev);
 
@@ -1796,7 +1788,7 @@ static ssize_t show_tabletWheel(struct d
 }
 
 static ssize_t
-store_tabletWheel(struct device *dev, const char *buf, size_t count)
+store_tabletWheel(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct aiptek *aiptek = dev_get_drvdata(dev);
 
@@ -1814,7 +1806,7 @@ static DEVICE_ATTR(wheel,
  * support routines for the 'execute' file. Note that this file
  * both displays current setting and allows for setting changing.
  */
-static ssize_t show_tabletExecute(struct device *dev, char *buf)
+static ssize_t show_tabletExecute(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct aiptek *aiptek = dev_get_drvdata(dev);
 
@@ -1829,7 +1821,7 @@ static ssize_t show_tabletExecute(struct
 }
 
 static ssize_t
-store_tabletExecute(struct device *dev, const char *buf, size_t count)
+store_tabletExecute(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct aiptek *aiptek = dev_get_drvdata(dev);
 
@@ -1855,7 +1847,7 @@ static DEVICE_ATTR(execute,
  * support routines for the 'odm_code' file. Note that this file
  * only displays current setting.
  */
-static ssize_t show_tabletODMCode(struct device *dev, char *buf)
+static ssize_t show_tabletODMCode(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct aiptek *aiptek = dev_get_drvdata(dev);
 
@@ -1871,7 +1863,7 @@ static DEVICE_ATTR(odm_code, S_IRUGO, sh
  * support routines for the 'model_code' file. Note that this file
  * only displays current setting.
  */
-static ssize_t show_tabletModelCode(struct device *dev, char *buf)
+static ssize_t show_tabletModelCode(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct aiptek *aiptek = dev_get_drvdata(dev);
 
@@ -1887,7 +1879,7 @@ static DEVICE_ATTR(model_code, S_IRUGO, 
  * support routines for the 'firmware_code' file. Note that this file
  * only displays current setting.
  */
-static ssize_t show_firmwareCode(struct device *dev, char *buf)
+static ssize_t show_firmwareCode(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct aiptek *aiptek = dev_get_drvdata(dev);
 
@@ -2134,10 +2126,7 @@ aiptek_probe(struct usb_interface *intf,
 	aiptek->inputdev.absflat[ABS_WHEEL] = 0;
 	aiptek->inputdev.name = "Aiptek";
 	aiptek->inputdev.phys = aiptek->features.usbPath;
-	aiptek->inputdev.id.bustype = BUS_USB;
-	aiptek->inputdev.id.vendor = le16_to_cpu(usbdev->descriptor.idVendor);
-	aiptek->inputdev.id.product = le16_to_cpu(usbdev->descriptor.idProduct);
-	aiptek->inputdev.id.version = le16_to_cpu(usbdev->descriptor.bcdDevice);
+	usb_to_input_id(usbdev, &aiptek->inputdev.id);
 	aiptek->inputdev.dev = &intf->dev;
 
 	aiptek->usbdev = usbdev;
@@ -2252,7 +2241,6 @@ static void aiptek_disconnect(struct usb
 				AIPTEK_PACKET_LENGTH,
 				aiptek->data, aiptek->data_dma);
 		kfree(aiptek);
-		aiptek = NULL;
 	}
 }
 
diff --git a/drivers/usb/input/ati_remote.c b/drivers/usb/input/ati_remote.c
--- a/drivers/usb/input/ati_remote.c
+++ b/drivers/usb/input/ati_remote.c
@@ -1,15 +1,15 @@
-/* 
+/*
  *  USB ATI Remote support
  *
  *  Version 2.2.0 Copyright (c) 2004 Torrey Hoffman <thoffman@arnor.net>
  *  Version 2.1.1 Copyright (c) 2002 Vladimir Dergachev
  *
  *  This 2.2.0 version is a rewrite / cleanup of the 2.1.1 driver, including
- *  porting to the 2.6 kernel interfaces, along with other modification 
+ *  porting to the 2.6 kernel interfaces, along with other modification
  *  to better match the style of the existing usb/input drivers.  However, the
  *  protocol and hardware handling is essentially unchanged from 2.1.1.
- *  
- *  The 2.1.1 driver was derived from the usbati_remote and usbkbd drivers by 
+ *
+ *  The 2.1.1 driver was derived from the usbati_remote and usbkbd drivers by
  *  Vojtech Pavlik.
  *
  *  Changes:
@@ -23,64 +23,64 @@
  *            Added support for the "Lola" remote contributed by:
  *                Seth Cohn <sethcohn@yahoo.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 
+ * 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
- * 
- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  *
  * Hardware & software notes
  *
- * These remote controls are distributed by ATI as part of their 
- * "All-In-Wonder" video card packages.  The receiver self-identifies as a 
+ * These remote controls are distributed by ATI as part of their
+ * "All-In-Wonder" video card packages.  The receiver self-identifies as a
  * "USB Receiver" with manufacturer "X10 Wireless Technology Inc".
  *
- * The "Lola" remote is available from X10.  See: 
+ * The "Lola" remote is available from X10.  See:
  *    http://www.x10.com/products/lola_sg1.htm
  * The Lola is similar to the ATI remote but has no mouse support, and slightly
  * different keys.
  *
- * It is possible to use multiple receivers and remotes on multiple computers 
+ * It is possible to use multiple receivers and remotes on multiple computers
  * simultaneously by configuring them to use specific channels.
- * 
- * The RF protocol used by the remote supports 16 distinct channels, 1 to 16.  
- * Actually, it may even support more, at least in some revisions of the 
+ *
+ * The RF protocol used by the remote supports 16 distinct channels, 1 to 16.
+ * Actually, it may even support more, at least in some revisions of the
  * hardware.
  *
  * Each remote can be configured to transmit on one channel as follows:
- *   - Press and hold the "hand icon" button.  
- *   - When the red LED starts to blink, let go of the "hand icon" button. 
- *   - When it stops blinking, input the channel code as two digits, from 01 
+ *   - Press and hold the "hand icon" button.
+ *   - When the red LED starts to blink, let go of the "hand icon" button.
+ *   - When it stops blinking, input the channel code as two digits, from 01
  *     to 16, and press the hand icon again.
- * 
+ *
  * The timing can be a little tricky.  Try loading the module with debug=1
  * to have the kernel print out messages about the remote control number
  * and mask.  Note: debugging prints remote numbers as zero-based hexadecimal.
  *
  * The driver has a "channel_mask" parameter. This bitmask specifies which
- * channels will be ignored by the module.  To mask out channels, just add 
+ * channels will be ignored by the module.  To mask out channels, just add
  * all the 2^channel_number values together.
  *
  * For instance, set channel_mask = 2^4 = 16 (binary 10000) to make ati_remote
- * ignore signals coming from remote controls transmitting on channel 4, but 
+ * ignore signals coming from remote controls transmitting on channel 4, but
  * accept all other channels.
  *
- * Or, set channel_mask = 65533, (0xFFFD), and all channels except 1 will be 
+ * Or, set channel_mask = 65533, (0xFFFD), and all channels except 1 will be
  * ignored.
  *
- * The default is 0 (respond to all channels). Bit 0 and bits 17-32 of this 
+ * The default is 0 (respond to all channels). Bit 0 and bits 17-32 of this
  * parameter are unused.
  *
  */
@@ -94,18 +94,19 @@
 #include <linux/moduleparam.h>
 #include <linux/input.h>
 #include <linux/usb.h>
+#include <linux/usb_input.h>
 #include <linux/wait.h>
 
 /*
  * Module and Version Information, Module Parameters
  */
- 
-#define ATI_REMOTE_VENDOR_ID 	0x0bc7
-#define ATI_REMOTE_PRODUCT_ID 	0x004
-#define LOLA_REMOTE_PRODUCT_ID 	0x002
+
+#define ATI_REMOTE_VENDOR_ID	0x0bc7
+#define ATI_REMOTE_PRODUCT_ID	0x004
+#define LOLA_REMOTE_PRODUCT_ID	0x002
 #define MEDION_REMOTE_PRODUCT_ID 0x006
 
-#define DRIVER_VERSION 	        "2.2.1"
+#define DRIVER_VERSION	        "2.2.1"
 #define DRIVER_AUTHOR           "Torrey Hoffman <thoffman@arnor.net>"
 #define DRIVER_DESC             "ATI/X10 RF USB Remote Control"
 
@@ -113,18 +114,18 @@
 #define DATA_BUFSIZE      63    /* size of URB data buffers */
 #define ATI_INPUTNUM      1     /* Which input device to register as */
 
-static unsigned long channel_mask = 0;
+static unsigned long channel_mask;
 module_param(channel_mask, ulong, 0444);
 MODULE_PARM_DESC(channel_mask, "Bitmask of remote control channels to ignore");
 
-static int debug = 0;
+static int debug;
 module_param(debug, int, 0444);
 MODULE_PARM_DESC(debug, "Enable extra debug messages and information");
 
 #define dbginfo(dev, format, arg...) do { if (debug) dev_info(dev , format , ## arg); } while (0)
 #undef err
 #define err(format, arg...) printk(KERN_ERR format , ## arg)
- 
+
 static struct usb_device_id ati_remote_table[] = {
 	{ USB_DEVICE(ATI_REMOTE_VENDOR_ID, ATI_REMOTE_PRODUCT_ID) },
 	{ USB_DEVICE(ATI_REMOTE_VENDOR_ID, LOLA_REMOTE_PRODUCT_ID) },
@@ -148,7 +149,7 @@ static char init2[] = { 0x01, 0x00, 0x20
 /* Acceleration curve for directional control pad */
 static char accel[] = { 1, 2, 4, 6, 9, 13, 20 };
 
-/* Duplicate event filtering time. 
+/* Duplicate event filtering time.
  * Sequential, identical KIND_FILTERED inputs with less than
  * FILTER_TIME jiffies between them are considered as repeat
  * events. The hardware generates 5 events for the first keypress
@@ -161,10 +162,10 @@ static char accel[] = { 1, 2, 4, 6, 9, 1
 static DECLARE_MUTEX(disconnect_sem);
 
 struct ati_remote {
-	struct input_dev idev;		
+	struct input_dev idev;
 	struct usb_device *udev;
 	struct usb_interface *interface;
-		
+
 	struct urb *irq_urb;
 	struct urb *out_urb;
 	struct usb_endpoint_descriptor *endpoint_in;
@@ -174,13 +175,11 @@ struct ati_remote {
 	dma_addr_t inbuf_dma;
 	dma_addr_t outbuf_dma;
 
-	int open;                   /* open counter */
-	
 	unsigned char old_data[2];  /* Detect duplicate events */
 	unsigned long old_jiffies;
 	unsigned long acc_jiffies;  /* handle acceleration */
 	unsigned int repeat_count;
-	
+
 	char name[NAME_BUFSIZE];
 	char phys[NAME_BUFSIZE];
 
@@ -206,14 +205,14 @@ static struct
 	int type;
 	unsigned int code;
 	int value;
-}  ati_remote_tbl[] = 
+}  ati_remote_tbl[] =
 {
 	/* Directional control pad axes */
 	{KIND_ACCEL,   0x35, 0x70, EV_REL, REL_X, -1},	 /* left */
 	{KIND_ACCEL,   0x36, 0x71, EV_REL, REL_X, 1},    /* right */
 	{KIND_ACCEL,   0x37, 0x72, EV_REL, REL_Y, -1},	 /* up */
 	{KIND_ACCEL,   0x38, 0x73, EV_REL, REL_Y, 1},    /* down */
-	/* Directional control pad diagonals */	
+	/* Directional control pad diagonals */
 	{KIND_LU,      0x39, 0x74, EV_REL, 0, 0},        /* left up */
 	{KIND_RU,      0x3a, 0x75, EV_REL, 0, 0},        /* right up */
 	{KIND_LD,      0x3c, 0x77, EV_REL, 0, 0},        /* left down */
@@ -225,7 +224,7 @@ static struct
 	{KIND_LITERAL, 0x41, 0x7c, EV_KEY, BTN_RIGHT, 1},/* right btn down */
 	{KIND_LITERAL, 0x42, 0x7d, EV_KEY, BTN_RIGHT, 0},/* right btn up */
 
-	/* Artificial "doubleclick" events are generated by the hardware. 
+	/* Artificial "doubleclick" events are generated by the hardware.
 	 * They are mapped to the "side" and "extra" mouse buttons here. */
 	{KIND_FILTERED, 0x3f, 0x7a, EV_KEY, BTN_SIDE, 1}, /* left dblclick */
 	{KIND_FILTERED, 0x43, 0x7e, EV_KEY, BTN_EXTRA, 1},/* right dblclick */
@@ -273,15 +272,15 @@ static struct
 	{KIND_FILTERED, 0xea, 0x25, EV_KEY, KEY_PLAY, 1},       /* ( >) */
 	{KIND_FILTERED, 0xe9, 0x24, EV_KEY, KEY_REWIND, 1},     /* (<<) */
 	{KIND_FILTERED, 0xeb, 0x26, EV_KEY, KEY_FORWARD, 1},    /* (>>) */
-	{KIND_FILTERED, 0xed, 0x28, EV_KEY, KEY_STOP, 1},       /* ([]) */ 
+	{KIND_FILTERED, 0xed, 0x28, EV_KEY, KEY_STOP, 1},       /* ([]) */
 	{KIND_FILTERED, 0xee, 0x29, EV_KEY, KEY_PAUSE, 1},      /* ('') */
 	{KIND_FILTERED, 0xf0, 0x2b, EV_KEY, KEY_PREVIOUS, 1},   /* (<-) */
 	{KIND_FILTERED, 0xef, 0x2a, EV_KEY, KEY_NEXT, 1},       /* (>+) */
 	{KIND_FILTERED, 0xf2, 0x2D, EV_KEY, KEY_INFO, 1},       /* PLAYING */
 	{KIND_FILTERED, 0xf3, 0x2E, EV_KEY, KEY_HOME, 1},       /* TOP */
 	{KIND_FILTERED, 0xf4, 0x2F, EV_KEY, KEY_END, 1},        /* END */
-	{KIND_FILTERED, 0xf5, 0x30, EV_KEY, KEY_SELECT, 1},     /* SELECT */	
-	
+	{KIND_FILTERED, 0xf5, 0x30, EV_KEY, KEY_SELECT, 1},     /* SELECT */
+
 	{KIND_END, 0x00, 0x00, EV_MAX + 1, 0, 0}
 };
 
@@ -315,7 +314,7 @@ static void ati_remote_dump(unsigned cha
 	if ((len == 1) && (data[0] != (unsigned char)0xff) && (data[0] != 0x00))
 		warn("Weird byte 0x%02x", data[0]);
 	else if (len == 4)
-		warn("Weird key %02x %02x %02x %02x", 
+		warn("Weird key %02x %02x %02x %02x",
 		     data[0], data[1], data[2], data[3]);
 	else
 		warn("Weird data, len=%d %02x %02x %02x %02x %02x %02x ...",
@@ -328,25 +327,16 @@ static void ati_remote_dump(unsigned cha
 static int ati_remote_open(struct input_dev *inputdev)
 {
 	struct ati_remote *ati_remote = inputdev->private;
-	int retval = 0;
-
-	down(&disconnect_sem);
-
-	if (ati_remote->open++)
-		goto exit;
 
 	/* On first open, submit the read urb which was set up previously. */
 	ati_remote->irq_urb->dev = ati_remote->udev;
 	if (usb_submit_urb(ati_remote->irq_urb, GFP_KERNEL)) {
-		dev_err(&ati_remote->interface->dev, 
+		dev_err(&ati_remote->interface->dev,
 			"%s: usb_submit_urb failed!\n", __FUNCTION__);
-		ati_remote->open--;
-		retval = -EIO;
+		return -EIO;
 	}
 
-exit:
-	up(&disconnect_sem);
-	return retval;
+	return 0;
 }
 
 /*
@@ -355,9 +345,8 @@ exit:
 static void ati_remote_close(struct input_dev *inputdev)
 {
 	struct ati_remote *ati_remote = inputdev->private;
-	
-	if (!--ati_remote->open)
-		usb_kill_urb(ati_remote->irq_urb);
+
+	usb_kill_urb(ati_remote->irq_urb);
 }
 
 /*
@@ -366,13 +355,13 @@ static void ati_remote_close(struct inpu
 static void ati_remote_irq_out(struct urb *urb, struct pt_regs *regs)
 {
 	struct ati_remote *ati_remote = urb->context;
-	
+
 	if (urb->status) {
 		dev_dbg(&ati_remote->interface->dev, "%s: status %d\n",
 			__FUNCTION__, urb->status);
 		return;
 	}
-	
+
 	ati_remote->send_flags |= SEND_FLAG_COMPLETE;
 	wmb();
 	wake_up(&ati_remote->wait);
@@ -380,16 +369,16 @@ static void ati_remote_irq_out(struct ur
 
 /*
  *	ati_remote_sendpacket
- *		
+ *
  *	Used to send device initialization strings
  */
 static int ati_remote_sendpacket(struct ati_remote *ati_remote, u16 cmd, unsigned char *data)
 {
 	int retval = 0;
-	
+
 	/* Set up out_urb */
 	memcpy(ati_remote->out_urb->transfer_buffer + 1, data, LO(cmd));
-	((char *) ati_remote->out_urb->transfer_buffer)[0] = HI(cmd);	
+	((char *) ati_remote->out_urb->transfer_buffer)[0] = HI(cmd);
 
 	ati_remote->out_urb->transfer_buffer_length = LO(cmd) + 1;
 	ati_remote->out_urb->dev = ati_remote->udev;
@@ -397,17 +386,17 @@ static int ati_remote_sendpacket(struct 
 
 	retval = usb_submit_urb(ati_remote->out_urb, GFP_ATOMIC);
 	if (retval) {
-		dev_dbg(&ati_remote->interface->dev, 
+		dev_dbg(&ati_remote->interface->dev,
 			 "sendpacket: usb_submit_urb failed: %d\n", retval);
 		return retval;
 	}
 
 	wait_event_timeout(ati_remote->wait,
 		((ati_remote->out_urb->status != -EINPROGRESS) ||
-		 	(ati_remote->send_flags & SEND_FLAG_COMPLETE)),
+			(ati_remote->send_flags & SEND_FLAG_COMPLETE)),
 		HZ);
 	usb_kill_urb(ati_remote->out_urb);
-	
+
 	return retval;
 }
 
@@ -419,15 +408,15 @@ static int ati_remote_event_lookup(int r
 	int i;
 
 	for (i = 0; ati_remote_tbl[i].kind != KIND_END; i++) {
-		/* 
-		 * Decide if the table entry matches the remote input. 
+		/*
+		 * Decide if the table entry matches the remote input.
 		 */
 		if ((((ati_remote_tbl[i].data1 & 0x0f) == (d1 & 0x0f))) &&
-		    ((((ati_remote_tbl[i].data1 >> 4) - 
-		       (d1 >> 4) + rem) & 0x0f) == 0x0f) && 
+		    ((((ati_remote_tbl[i].data1 >> 4) -
+		       (d1 >> 4) + rem) & 0x0f) == 0x0f) &&
 		    (ati_remote_tbl[i].data2 == d2))
 			return i;
-		
+
 	}
 	return -1;
 }
@@ -435,16 +424,16 @@ static int ati_remote_event_lookup(int r
 /*
  *	ati_remote_report_input
  */
-static void ati_remote_input_report(struct urb *urb, struct pt_regs *regs)	
+static void ati_remote_input_report(struct urb *urb, struct pt_regs *regs)
 {
 	struct ati_remote *ati_remote = urb->context;
 	unsigned char *data= ati_remote->inbuf;
-	struct input_dev *dev = &ati_remote->idev; 
+	struct input_dev *dev = &ati_remote->idev;
 	int index, acc;
 	int remote_num;
-	
+
 	/* Deal with strange looking inputs */
-	if ( (urb->actual_length != 4) || (data[0] != 0x14) || 
+	if ( (urb->actual_length != 4) || (data[0] != 0x14) ||
 		((data[3] & 0x0f) != 0x00) ) {
 		ati_remote_dump(data, urb->actual_length);
 		return;
@@ -453,7 +442,7 @@ static void ati_remote_input_report(stru
 	/* Mask unwanted remote channels.  */
 	/* note: remote_num is 0-based, channel 1 on remote == 0 here */
 	remote_num = (data[3] >> 4) & 0x0f;
-        if (channel_mask & (1 << (remote_num + 1))) { 
+        if (channel_mask & (1 << (remote_num + 1))) {
 		dbginfo(&ati_remote->interface->dev,
 			"Masked input from channel 0x%02x: data %02x,%02x, mask= 0x%02lx\n",
 			remote_num, data[1], data[2], channel_mask);
@@ -463,37 +452,36 @@ static void ati_remote_input_report(stru
 	/* Look up event code index in translation table */
 	index = ati_remote_event_lookup(remote_num, data[1], data[2]);
 	if (index < 0) {
-		dev_warn(&ati_remote->interface->dev, 
-			 "Unknown input from channel 0x%02x: data %02x,%02x\n", 
+		dev_warn(&ati_remote->interface->dev,
+			 "Unknown input from channel 0x%02x: data %02x,%02x\n",
 			 remote_num, data[1], data[2]);
 		return;
-	} 
-	dbginfo(&ati_remote->interface->dev, 
+	}
+	dbginfo(&ati_remote->interface->dev,
 		"channel 0x%02x; data %02x,%02x; index %d; keycode %d\n",
 		remote_num, data[1], data[2], index, ati_remote_tbl[index].code);
-	
+
 	if (ati_remote_tbl[index].kind == KIND_LITERAL) {
 		input_regs(dev, regs);
 		input_event(dev, ati_remote_tbl[index].type,
 			ati_remote_tbl[index].code,
 			ati_remote_tbl[index].value);
 		input_sync(dev);
-		
+
 		ati_remote->old_jiffies = jiffies;
 		return;
 	}
-	
+
 	if (ati_remote_tbl[index].kind == KIND_FILTERED) {
 		/* Filter duplicate events which happen "too close" together. */
-		if ((ati_remote->old_data[0] == data[1]) && 
-	 		(ati_remote->old_data[1] == data[2]) && 
-	 		((ati_remote->old_jiffies + FILTER_TIME) > jiffies)) {
+		if ((ati_remote->old_data[0] == data[1]) &&
+			(ati_remote->old_data[1] == data[2]) &&
+			((ati_remote->old_jiffies + FILTER_TIME) > jiffies)) {
 			ati_remote->repeat_count++;
-		} 
-		else {
+		} else {
 			ati_remote->repeat_count = 0;
 		}
-		
+
 		ati_remote->old_data[0] = data[1];
 		ati_remote->old_data[1] = data[2];
 		ati_remote->old_jiffies = jiffies;
@@ -501,7 +489,7 @@ static void ati_remote_input_report(stru
 		if ((ati_remote->repeat_count > 0)
 		    && (ati_remote->repeat_count < 5))
 			return;
-		
+
 
 		input_regs(dev, regs);
 		input_event(dev, ati_remote_tbl[index].type,
@@ -511,13 +499,13 @@ static void ati_remote_input_report(stru
 		input_sync(dev);
 
 		return;
-	}			
-	
-	/* 
+	}
+
+	/*
 	 * Other event kinds are from the directional control pad, and have an
 	 * acceleration factor applied to them.  Without this acceleration, the
 	 * control pad is mostly unusable.
-	 * 
+	 *
 	 * If elapsed time since last event is > 1/4 second, user "stopped",
 	 * so reset acceleration. Otherwise, user is probably holding the control
 	 * pad down, so we increase acceleration, ramping up over two seconds to
@@ -559,7 +547,7 @@ static void ati_remote_input_report(stru
 		input_report_rel(dev, REL_Y, acc);
 		break;
 	default:
-		dev_dbg(&ati_remote->interface->dev, "ati_remote kind=%d\n", 
+		dev_dbg(&ati_remote->interface->dev, "ati_remote kind=%d\n",
 			ati_remote_tbl[index].kind);
 	}
 	input_sync(dev);
@@ -586,12 +574,12 @@ static void ati_remote_irq_in(struct urb
 	case -ESHUTDOWN:
 		dev_dbg(&ati_remote->interface->dev, "%s: urb error status, unlink? \n",
 			__FUNCTION__);
-		return;	
+		return;
 	default:		/* error */
-		dev_dbg(&ati_remote->interface->dev, "%s: Nonzero urb status %d\n", 
+		dev_dbg(&ati_remote->interface->dev, "%s: Nonzero urb status %d\n",
 			__FUNCTION__, urb->status);
 	}
-	
+
 	retval = usb_submit_urb(urb, SLAB_ATOMIC);
 	if (retval)
 		dev_err(&ati_remote->interface->dev, "%s: usb_submit_urb()=%d\n",
@@ -603,8 +591,6 @@ static void ati_remote_irq_in(struct urb
  */
 static void ati_remote_delete(struct ati_remote *ati_remote)
 {
-	if (!ati_remote) return;
-
 	if (ati_remote->irq_urb)
 		usb_kill_urb(ati_remote->irq_urb);
 
@@ -614,16 +600,16 @@ static void ati_remote_delete(struct ati
 	input_unregister_device(&ati_remote->idev);
 
 	if (ati_remote->inbuf)
-		usb_buffer_free(ati_remote->udev, DATA_BUFSIZE, 
+		usb_buffer_free(ati_remote->udev, DATA_BUFSIZE,
 				ati_remote->inbuf, ati_remote->inbuf_dma);
-		
+
 	if (ati_remote->outbuf)
-		usb_buffer_free(ati_remote->udev, DATA_BUFSIZE, 
+		usb_buffer_free(ati_remote->udev, DATA_BUFSIZE,
 				ati_remote->outbuf, ati_remote->outbuf_dma);
-	
+
 	if (ati_remote->irq_urb)
 		usb_free_urb(ati_remote->irq_urb);
-	
+
 	if (ati_remote->out_urb)
 		usb_free_urb(ati_remote->out_urb);
 
@@ -636,51 +622,49 @@ static void ati_remote_input_init(struct
 	int i;
 
 	idev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
-	idev->keybit[LONG(BTN_MOUSE)] = ( BIT(BTN_LEFT) | BIT(BTN_RIGHT) | 
+	idev->keybit[LONG(BTN_MOUSE)] = ( BIT(BTN_LEFT) | BIT(BTN_RIGHT) |
 					  BIT(BTN_SIDE) | BIT(BTN_EXTRA) );
 	idev->relbit[0] = BIT(REL_X) | BIT(REL_Y);
 	for (i = 0; ati_remote_tbl[i].kind != KIND_END; i++)
 		if (ati_remote_tbl[i].type == EV_KEY)
 			set_bit(ati_remote_tbl[i].code, idev->keybit);
-	
+
 	idev->private = ati_remote;
 	idev->open = ati_remote_open;
 	idev->close = ati_remote_close;
-	
+
 	idev->name = ati_remote->name;
 	idev->phys = ati_remote->phys;
-	
-	idev->id.bustype = BUS_USB;		
-	idev->id.vendor = le16_to_cpu(ati_remote->udev->descriptor.idVendor);
-	idev->id.product = le16_to_cpu(ati_remote->udev->descriptor.idProduct);
-	idev->id.version = le16_to_cpu(ati_remote->udev->descriptor.bcdDevice);
+
+	usb_to_input_id(ati_remote->udev, &idev->id);
+	idev->dev = &ati_remote->udev->dev;
 }
 
 static int ati_remote_initialize(struct ati_remote *ati_remote)
 {
 	struct usb_device *udev = ati_remote->udev;
 	int pipe, maxp;
-		
+
 	init_waitqueue_head(&ati_remote->wait);
 
 	/* Set up irq_urb */
 	pipe = usb_rcvintpipe(udev, ati_remote->endpoint_in->bEndpointAddress);
 	maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe));
 	maxp = (maxp > DATA_BUFSIZE) ? DATA_BUFSIZE : maxp;
-	
-	usb_fill_int_urb(ati_remote->irq_urb, udev, pipe, ati_remote->inbuf, 
-			 maxp, ati_remote_irq_in, ati_remote, 
+
+	usb_fill_int_urb(ati_remote->irq_urb, udev, pipe, ati_remote->inbuf,
+			 maxp, ati_remote_irq_in, ati_remote,
 			 ati_remote->endpoint_in->bInterval);
 	ati_remote->irq_urb->transfer_dma = ati_remote->inbuf_dma;
 	ati_remote->irq_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
-	
+
 	/* Set up out_urb */
 	pipe = usb_sndintpipe(udev, ati_remote->endpoint_out->bEndpointAddress);
 	maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe));
 	maxp = (maxp > DATA_BUFSIZE) ? DATA_BUFSIZE : maxp;
 
-	usb_fill_int_urb(ati_remote->out_urb, udev, pipe, ati_remote->outbuf, 
-			 maxp, ati_remote_irq_out, ati_remote, 
+	usb_fill_int_urb(ati_remote->out_urb, udev, pipe, ati_remote->outbuf,
+			 maxp, ati_remote_irq_out, ati_remote,
 			 ati_remote->endpoint_out->bInterval);
 	ati_remote->out_urb->transfer_dma = ati_remote->outbuf_dma;
 	ati_remote->out_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
@@ -688,11 +672,11 @@ static int ati_remote_initialize(struct 
 	/* send initialization strings */
 	if ((ati_remote_sendpacket(ati_remote, 0x8004, init1)) ||
 	    (ati_remote_sendpacket(ati_remote, 0x8007, init2))) {
-		dev_err(&ati_remote->interface->dev, 
+		dev_err(&ati_remote->interface->dev,
 			 "Initializing ati_remote hardware failed.\n");
 		return 1;
 	}
-	
+
 	return 0;
 }
 
@@ -769,7 +753,7 @@ static int ati_remote_probe(struct usb_i
 
 	if (!strlen(ati_remote->name))
 		sprintf(ati_remote->name, DRIVER_DESC "(%04x,%04x)",
-			le16_to_cpu(ati_remote->udev->descriptor.idVendor), 
+			le16_to_cpu(ati_remote->udev->descriptor.idVendor),
 			le16_to_cpu(ati_remote->udev->descriptor.idProduct));
 
 	/* Device Hardware Initialization - fills in ati_remote->idev from udev. */
@@ -781,11 +765,11 @@ static int ati_remote_probe(struct usb_i
 	ati_remote_input_init(ati_remote);
 	input_register_device(&ati_remote->idev);
 
-	dev_info(&ati_remote->interface->dev, "Input registered: %s on %s\n", 
+	dev_info(&ati_remote->interface->dev, "Input registered: %s on %s\n",
 		 ati_remote->name, path);
 
 	usb_set_intfdata(interface, ati_remote);
-	
+
 error:
 	if (retval)
 		ati_remote_delete(ati_remote);
@@ -800,18 +784,14 @@ static void ati_remote_disconnect(struct
 {
 	struct ati_remote *ati_remote;
 
-	down(&disconnect_sem);
-
 	ati_remote = usb_get_intfdata(interface);
 	usb_set_intfdata(interface, NULL);
 	if (!ati_remote) {
 		warn("%s - null device?\n", __FUNCTION__);
 		return;
 	}
-	
-	ati_remote_delete(ati_remote);
 
-	up(&disconnect_sem);
+	ati_remote_delete(ati_remote);
 }
 
 /*
@@ -820,7 +800,7 @@ static void ati_remote_disconnect(struct
 static int __init ati_remote_init(void)
 {
 	int result;
-	
+
 	result = usb_register(&ati_remote_driver);
 	if (result)
 		err("usb_register error #%d\n", result);
@@ -838,8 +818,8 @@ static void __exit ati_remote_exit(void)
 	usb_deregister(&ati_remote_driver);
 }
 
-/* 
- *	module specification 
+/*
+ *	module specification
  */
 
 module_init(ati_remote_init);
diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c
--- a/drivers/usb/input/hid-core.c
+++ b/drivers/usb/input/hid-core.c
@@ -232,7 +232,7 @@ static int hid_add_field(struct hid_pars
 	report->size += parser->global.report_size * parser->global.report_count;
 
 	if (!parser->local.usage_index) /* Ignore padding fields */
-		return 0; 
+		return 0;
 
 	usages = max_t(int, parser->local.usage_index, parser->global.report_count);
 
@@ -765,7 +765,7 @@ static __inline__ __u32 s32ton(__s32 val
 static __inline__ __u32 extract(__u8 *report, unsigned offset, unsigned n)
 {
 	report += (offset >> 5) << 2; offset &= 31;
-	return (le64_to_cpu(get_unaligned((__le64*)report)) >> offset) & ((1 << n) - 1);
+	return (le64_to_cpu(get_unaligned((__le64*)report)) >> offset) & ((1ULL << n) - 1);
 }
 
 static __inline__ void implement(__u8 *report, unsigned offset, unsigned n, __u32 value)
@@ -789,12 +789,12 @@ static __inline__ int search(__s32 *arra
 	return -1;
 }
 
-static void hid_process_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value, struct pt_regs *regs)
+static void hid_process_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value, int interrupt, struct pt_regs *regs)
 {
 	hid_dump_input(usage, value);
 	if (hid->claimed & HID_CLAIMED_INPUT)
 		hidinput_hid_event(hid, field, usage, value, regs);
-	if (hid->claimed & HID_CLAIMED_HIDDEV)
+	if (hid->claimed & HID_CLAIMED_HIDDEV && interrupt)
 		hiddev_hid_event(hid, field, usage, value, regs);
 }
 
@@ -804,7 +804,7 @@ static void hid_process_event(struct hid
  * reporting to the layer).
  */
 
-static void hid_input_field(struct hid_device *hid, struct hid_field *field, __u8 *data, struct pt_regs *regs)
+static void hid_input_field(struct hid_device *hid, struct hid_field *field, __u8 *data, int interrupt, struct pt_regs *regs)
 {
 	unsigned n;
 	unsigned count = field->report_count;
@@ -831,19 +831,19 @@ static void hid_input_field(struct hid_d
 	for (n = 0; n < count; n++) {
 
 		if (HID_MAIN_ITEM_VARIABLE & field->flags) {
-			hid_process_event(hid, field, &field->usage[n], value[n], regs);
+			hid_process_event(hid, field, &field->usage[n], value[n], interrupt, regs);
 			continue;
 		}
 
 		if (field->value[n] >= min && field->value[n] <= max
 			&& field->usage[field->value[n] - min].hid
 			&& search(value, field->value[n], count))
-				hid_process_event(hid, field, &field->usage[field->value[n] - min], 0, regs);
+				hid_process_event(hid, field, &field->usage[field->value[n] - min], 0, interrupt, regs);
 
 		if (value[n] >= min && value[n] <= max
 			&& field->usage[value[n] - min].hid
 			&& search(field->value, value[n], count))
-				hid_process_event(hid, field, &field->usage[value[n] - min], 1, regs);
+				hid_process_event(hid, field, &field->usage[value[n] - min], 1, interrupt, regs);
 	}
 
 	memcpy(field->value, value, count * sizeof(__s32));
@@ -851,7 +851,7 @@ exit:
 	kfree(value);
 }
 
-static int hid_input_report(int type, struct urb *urb, struct pt_regs *regs)
+static int hid_input_report(int type, struct urb *urb, int interrupt, struct pt_regs *regs)
 {
 	struct hid_device *hid = urb->context;
 	struct hid_report_enum *report_enum = hid->report_enum + type;
@@ -899,7 +899,7 @@ static int hid_input_report(int type, st
 		hiddev_report_event(hid, report);
 
 	for (n = 0; n < report->maxfield; n++)
-		hid_input_field(hid, report->field[n], data, regs);
+		hid_input_field(hid, report->field[n], data, interrupt, regs);
 
 	if (hid->claimed & HID_CLAIMED_INPUT)
 		hidinput_report_event(hid, report);
@@ -918,7 +918,7 @@ static void hid_irq_in(struct urb *urb, 
 
 	switch (urb->status) {
 		case 0:			/* success */
-			hid_input_report(HID_INPUT_REPORT, urb, regs);
+			hid_input_report(HID_INPUT_REPORT, urb, 1, regs);
 			break;
 		case -ECONNRESET:	/* unlink */
 		case -ENOENT:
@@ -1142,7 +1142,7 @@ static void hid_ctrl(struct urb *urb, st
 	switch (urb->status) {
 		case 0:			/* success */
 			if (hid->ctrl[hid->ctrltail].dir == USB_DIR_IN)
-				hid_input_report(hid->ctrl[hid->ctrltail].report->type, urb, regs);
+				hid_input_report(hid->ctrl[hid->ctrltail].report->type, urb, 0, regs);
 		case -ESHUTDOWN:	/* unplug */
 		case -EILSEQ:		/* unplug timectrl on uhci */
 			unplug = 1;
@@ -1233,6 +1233,13 @@ int hid_wait_io(struct hid_device *hid)
 	return 0;
 }
 
+static int hid_set_idle(struct usb_device *dev, int ifnum, int report, int idle)
+{
+	return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+		HID_REQ_SET_IDLE, USB_TYPE_CLASS | USB_RECIP_INTERFACE, (idle << 8) | report,
+		ifnum, NULL, 0, USB_CTRL_SET_TIMEOUT);
+}
+
 static int hid_get_class_descriptor(struct usb_device *dev, int ifnum,
 		unsigned char type, void *buf, int size)
 {
@@ -1301,10 +1308,6 @@ void hid_init_reports(struct hid_device 
 
 	if (err)
 		warn("timeout initializing reports\n");
-
-	usb_control_msg(hid->dev, usb_sndctrlpipe(hid->dev, 0),
-		HID_REQ_SET_IDLE, USB_TYPE_CLASS | USB_RECIP_INTERFACE, 0,
-		hid->ifnum, NULL, 0, USB_CTRL_SET_TIMEOUT);
 }
 
 #define USB_VENDOR_ID_WACOM		0x056a
@@ -1318,6 +1321,10 @@ void hid_init_reports(struct hid_device 
 #define USB_DEVICE_ID_WACOM_INTUOS3	0x00B0
 #define USB_DEVICE_ID_WACOM_CINTIQ	0x003F
 
+#define USB_VENDOR_ID_ACECAD		0x0460
+#define USB_DEVICE_ID_ACECAD_FLAIR	0x0004
+#define USB_DEVICE_ID_ACECAD_302	0x0008
+
 #define USB_VENDOR_ID_KBGEAR		0x084e
 #define USB_DEVICE_ID_KBGEAR_JAMSTUDIO	0x1001
 
@@ -1365,6 +1372,9 @@ void hid_init_reports(struct hid_device 
 #define USB_VENDOR_ID_A4TECH		0x09da
 #define USB_DEVICE_ID_A4TECH_WCP32PU	0x0006
 
+#define USB_VENDOR_ID_AASHIMA		0x06D6
+#define USB_DEVICE_ID_AASHIMA_GAMEPAD	0x0025
+
 #define USB_VENDOR_ID_CYPRESS		0x04b4
 #define USB_DEVICE_ID_CYPRESS_MOUSE	0x0001
 #define USB_DEVICE_ID_CYPRESS_HIDCOM	0x5500
@@ -1421,6 +1431,19 @@ void hid_init_reports(struct hid_device 
 #define USB_DEVICE_ID_VERNIER_SKIP	0x0003
 #define USB_DEVICE_ID_VERNIER_CYCLOPS	0x0004
 
+#define USB_VENDOR_ID_LD		0x0f11
+#define USB_DEVICE_ID_CASSY        	0x1000
+#define USB_DEVICE_ID_POCKETCASSY	0x1010
+#define USB_DEVICE_ID_MOBILECASSY	0x1020
+#define USB_DEVICE_ID_JWM		0x1080
+#define USB_DEVICE_ID_DMMP		0x1081
+#define USB_DEVICE_ID_UMIP		0x1090
+#define USB_DEVICE_ID_VIDEOCOM		0x1200
+#define USB_DEVICE_ID_COM3LAB		0x2000
+#define USB_DEVICE_ID_TELEPORT		0x2010
+#define USB_DEVICE_ID_NETWORKANALYSER	0x2020
+#define USB_DEVICE_ID_POWERCONTROL	0x2030
+
 
 /*
  * Alphabetically sorted blacklist by quirk type.
@@ -1456,6 +1479,17 @@ static struct hid_blacklist {
 	{ USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_POWERMATE, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_SOUNDKNOB, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_KBGEAR, USB_DEVICE_ID_KBGEAR_JAMSTUDIO, HID_QUIRK_IGNORE },
+	{ USB_VENDOR_ID_LD, USB_DEVICE_ID_CASSY, HID_QUIRK_IGNORE },
+	{ USB_VENDOR_ID_LD, USB_DEVICE_ID_POCKETCASSY, HID_QUIRK_IGNORE },
+	{ USB_VENDOR_ID_LD, USB_DEVICE_ID_MOBILECASSY, HID_QUIRK_IGNORE },
+	{ USB_VENDOR_ID_LD, USB_DEVICE_ID_JWM, HID_QUIRK_IGNORE },
+	{ USB_VENDOR_ID_LD, USB_DEVICE_ID_DMMP, HID_QUIRK_IGNORE },
+	{ USB_VENDOR_ID_LD, USB_DEVICE_ID_UMIP, HID_QUIRK_IGNORE },
+	{ USB_VENDOR_ID_LD, USB_DEVICE_ID_VIDEOCOM, HID_QUIRK_IGNORE },
+	{ USB_VENDOR_ID_LD, USB_DEVICE_ID_COM3LAB, HID_QUIRK_IGNORE },
+	{ USB_VENDOR_ID_LD, USB_DEVICE_ID_TELEPORT, HID_QUIRK_IGNORE },
+	{ USB_VENDOR_ID_LD, USB_DEVICE_ID_NETWORKANALYSER, HID_QUIRK_IGNORE },
+	{ USB_VENDOR_ID_LD, USB_DEVICE_ID_POWERCONTROL, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_MCC, USB_DEVICE_ID_MCC_PMD1024LS, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_MCC, USB_DEVICE_ID_MCC_PMD1208LS, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_IGNORE },
@@ -1502,6 +1536,9 @@ static struct hid_blacklist {
 	{ USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_4_PHIDGETSERVO_20, HID_QUIRK_IGNORE },
 	{ USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_1_PHIDGETSERVO_20, HID_QUIRK_IGNORE },
 
+	{ USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_FLAIR, HID_QUIRK_IGNORE },
+	{ USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_302, HID_QUIRK_IGNORE },
+
 	{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_UC100KM, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS124U, HID_QUIRK_NOGET },
 	{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM, HID_QUIRK_NOGET },
@@ -1514,6 +1551,7 @@ static struct hid_blacklist {
 	{ USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU, HID_QUIRK_2WHEEL_MOUSE_HACK_7 },
 	{ USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE, HID_QUIRK_2WHEEL_MOUSE_HACK_5 },
 
+	{ USB_VENDOR_ID_AASHIMA, USB_DEVICE_ID_AASHIMA_GAMEPAD, HID_QUIRK_BADPAD },
 	{ USB_VENDOR_ID_ALPS, USB_DEVICE_ID_IBM_GAMEPAD, HID_QUIRK_BADPAD },
 	{ USB_VENDOR_ID_CHIC, USB_DEVICE_ID_CHIC_GAMEPAD, HID_QUIRK_BADPAD },
 	{ USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_DRIVING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT },
@@ -1590,6 +1628,8 @@ static struct hid_device *usb_hid_config
 		return NULL;
 	}
 
+	hid_set_idle(dev, interface->desc.bInterfaceNumber, 0, 0);
+
 	if ((n = hid_get_class_descriptor(dev, interface->desc.bInterfaceNumber, HID_DT_REPORT, rdesc, rsize)) < 0) {
 		dbg("reading report descriptor failed");
 		kfree(rdesc);
@@ -1635,7 +1675,7 @@ static struct hid_device *usb_hid_config
 		/* Change the polling interval of mice. */
 		if (hid->collection->usage == HID_GD_MOUSE && hid_mousepoll_interval > 0)
 			interval = hid_mousepoll_interval;
-		
+
 		if (endpoint->bEndpointAddress & USB_DIR_IN) {
 			if (hid->urbin)
 				continue;
@@ -1762,7 +1802,7 @@ static int hid_probe(struct usb_interfac
 			intf->altsetting->desc.bInterfaceNumber);
 
 	if (!(hid = usb_hid_configure(intf)))
-		return -EIO;
+		return -ENODEV;
 
 	hid_init_reports(hid);
 	hid_dump_device(hid);
@@ -1777,7 +1817,7 @@ static int hid_probe(struct usb_interfac
 	if (!hid->claimed) {
 		printk ("HID device not claimed by input or hiddev\n");
 		hid_disconnect(intf);
-		return -EIO;
+		return -ENODEV;
 	}
 
 	printk(KERN_INFO);
diff --git a/drivers/usb/input/hid-debug.h b/drivers/usb/input/hid-debug.h
--- a/drivers/usb/input/hid-debug.h
+++ b/drivers/usb/input/hid-debug.h
@@ -67,7 +67,7 @@ static const struct hid_usage_entry hid_
       {0, 0x44, "Vbry"},
       {0, 0x45, "Vbrz"},
       {0, 0x46, "Vno"},
-    {0, 0x80, "SystemControl"}, 
+    {0, 0x80, "SystemControl"},
       {0, 0x81, "SystemPowerDown"},
       {0, 0x82, "SystemSleep"},
       {0, 0x83, "SystemWakeUp"},
@@ -347,7 +347,7 @@ __inline__ static void tab(int n) {
 
 static void hid_dump_field(struct hid_field *field, int n) {
 	int j;
-	
+
 	if (field->physical) {
 		tab(n);
 		printk("Physical(");
@@ -408,7 +408,7 @@ static void hid_dump_field(struct hid_fi
 					printk("%s", units[sys][i]);
 					if(nibble != 1) {
 						/* This is a _signed_ nibble(!) */
-	
+
 						int val = nibble & 0x7;
 						if(nibble & 0x08)
 							val = -((0x7 & ~val) +1);
@@ -443,7 +443,7 @@ static void __attribute__((unused)) hid_
 	struct list_head *list;
 	unsigned i,k;
 	static char *table[] = {"INPUT", "OUTPUT", "FEATURE"};
-	
+
 	for (i = 0; i < HID_REPORT_TYPES; i++) {
 		report_enum = device->report_enum + i;
 		list = report_enum->report_list.next;
@@ -664,8 +664,8 @@ static char *keys[KEY_MAX + 1] = {
 static char *relatives[REL_MAX + 1] = {
 	[REL_X] = "X",			[REL_Y] = "Y",
 	[REL_Z] = "Z",			[REL_HWHEEL] = "HWheel",
-	[REL_DIAL] = "Dial",		[REL_WHEEL] = "Wheel", 
-	[REL_MISC] = "Misc",	
+	[REL_DIAL] = "Dial",		[REL_WHEEL] = "Wheel",
+	[REL_MISC] = "Misc",
 };
 
 static char *absolutes[ABS_MAX + 1] = {
@@ -690,9 +690,9 @@ static char *misc[MSC_MAX + 1] = {
 };
 
 static char *leds[LED_MAX + 1] = {
-	[LED_NUML] = "NumLock",		[LED_CAPSL] = "CapsLock", 
+	[LED_NUML] = "NumLock",		[LED_CAPSL] = "CapsLock",
 	[LED_SCROLLL] = "ScrollLock",	[LED_COMPOSE] = "Compose",
-	[LED_KANA] = "Kana",		[LED_SLEEP] = "Sleep", 
+	[LED_KANA] = "Kana",		[LED_SLEEP] = "Sleep",
 	[LED_SUSPEND] = "Suspend",	[LED_MUTE] = "Mute",
 	[LED_MISC] = "Misc",
 };
diff --git a/drivers/usb/input/hid-input.c b/drivers/usb/input/hid-input.c
--- a/drivers/usb/input/hid-input.c
+++ b/drivers/usb/input/hid-input.c
@@ -31,6 +31,7 @@
 #include <linux/kernel.h>
 #include <linux/input.h>
 #include <linux/usb.h>
+#include <linux/usb_input.h>
 
 #undef DEBUG
 
@@ -164,7 +165,7 @@ static void hidinput_configure_usage(str
 				case HID_GD_X: case HID_GD_Y: case HID_GD_Z:
 				case HID_GD_RX: case HID_GD_RY: case HID_GD_RZ:
 				case HID_GD_SLIDER: case HID_GD_DIAL: case HID_GD_WHEEL:
-					if (field->flags & HID_MAIN_ITEM_RELATIVE) 
+					if (field->flags & HID_MAIN_ITEM_RELATIVE)
 						map_rel(usage->hid & 0xf);
 					else
 						map_abs(usage->hid & 0xf);
@@ -297,7 +298,7 @@ static void hidinput_configure_usage(str
 		case HID_UP_MSVENDOR:
 
 			goto ignore;
-			
+
 		case HID_UP_PID:
 
 			set_bit(EV_FF, input->evbit);
@@ -349,7 +350,7 @@ static void hidinput_configure_usage(str
 		goto ignore;
 
 	if ((device->quirks & (HID_QUIRK_2WHEEL_MOUSE_HACK_7 | HID_QUIRK_2WHEEL_MOUSE_HACK_5)) &&
-		 (usage->type == EV_REL) && (usage->code == REL_WHEEL)) 
+		 (usage->type == EV_REL) && (usage->code == REL_WHEEL))
 			set_bit(REL_HWHEEL, bit);
 
 	if (((device->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_5) && (usage->hid == 0x00090005))
@@ -365,11 +366,11 @@ static void hidinput_configure_usage(str
 			a = field->logical_minimum = 0;
 			b = field->logical_maximum = 255;
 		}
-		
+
 		if (field->application == HID_GD_GAMEPAD || field->application == HID_GD_JOYSTICK)
 			input_set_abs_params(input, usage->code, a, b, (b - a) >> 8, (b - a) >> 4);
 		else	input_set_abs_params(input, usage->code, a, b, 0, 0);
-		
+
 	}
 
 	if (usage->hat_min < usage->hat_max || usage->hat_dir) {
@@ -397,11 +398,12 @@ ignore:
 
 void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value, struct pt_regs *regs)
 {
-	struct input_dev *input = &field->hidinput->input;
+	struct input_dev *input;
 	int *quirks = &hid->quirks;
 
-	if (!input)
+	if (!field->hidinput)
 		return;
+	input = &field->hidinput->input;
 
 	input_regs(input, regs);
 
@@ -420,7 +422,7 @@ void hidinput_hid_event(struct hid_devic
 		return;
 	}
 
-	if (usage->hat_min < usage->hat_max || usage->hat_dir) { 
+	if (usage->hat_min < usage->hat_max || usage->hat_dir) {
 		int hat_dir = usage->hat_dir;
 		if (!hat_dir)
 			hat_dir = (value - usage->hat_min) * 8 / (usage->hat_max - usage->hat_min + 1) + 1;
@@ -551,7 +553,7 @@ int hidinput_connect(struct hid_device *
 	for (i = 0; i < hid->maxcollection; i++)
 		if (hid->collection[i].type == HID_COLLECTION_APPLICATION ||
 		    hid->collection[i].type == HID_COLLECTION_PHYSICAL)
-		    	if (IS_INPUT_APPLICATION(hid->collection[i].usage))
+			if (IS_INPUT_APPLICATION(hid->collection[i].usage))
 				break;
 
 	if (i == hid->maxcollection)
@@ -581,10 +583,7 @@ int hidinput_connect(struct hid_device *
 				hidinput->input.name = hid->name;
 				hidinput->input.phys = hid->phys;
 				hidinput->input.uniq = hid->uniq;
-				hidinput->input.id.bustype = BUS_USB;
-				hidinput->input.id.vendor = le16_to_cpu(dev->descriptor.idVendor);
-				hidinput->input.id.product = le16_to_cpu(dev->descriptor.idProduct);
-				hidinput->input.id.version = le16_to_cpu(dev->descriptor.bcdDevice);
+				usb_to_input_id(dev, &hidinput->input.id);
 				hidinput->input.dev = &hid->intf->dev;
 			}
 
@@ -592,7 +591,7 @@ int hidinput_connect(struct hid_device *
 				for (j = 0; j < report->field[i]->maxusage; j++)
 					hidinput_configure_usage(hidinput, report->field[i],
 								 report->field[i]->usage + j);
-			
+
 			if (hid->quirks & HID_QUIRK_MULTI_INPUT) {
 				/* This will leave hidinput NULL, so that it
 				 * allocates another one if we have more inputs on
diff --git a/drivers/usb/input/hid-lgff.c b/drivers/usb/input/hid-lgff.c
--- a/drivers/usb/input/hid-lgff.c
+++ b/drivers/usb/input/hid-lgff.c
@@ -94,7 +94,7 @@ struct lgff_device {
 					isn't really necessary */
 
 	unsigned long flags[1];      /* Contains various information about the
-				        state of the driver for this device */	
+				        state of the driver for this device */
 
 	struct timer_list timer;
 };
@@ -234,7 +234,7 @@ static struct hid_report* hid_lgff_dupli
 		kfree(ret);
 		return NULL;
 	}
-	memset(ret->field[0]->value, 0, sizeof(s32[8]));	
+	memset(ret->field[0]->value, 0, sizeof(s32[8]));
 
 	return ret;
 }
@@ -295,11 +295,11 @@ static int hid_lgff_event(struct hid_dev
 	unsigned long flags;
 
 	if (type != EV_FF)                     return -EINVAL;
-       	if (!LGFF_CHECK_OWNERSHIP(code, lgff)) return -EACCES;
+	if (!LGFF_CHECK_OWNERSHIP(code, lgff)) return -EACCES;
 	if (value < 0)                         return -EINVAL;
 
 	spin_lock_irqsave(&lgff->lock, flags);
-	
+
 	if (value > 0) {
 		if (test_bit(EFFECT_STARTED, effect->flags)) {
 			spin_unlock_irqrestore(&lgff->lock, flags);
@@ -345,7 +345,7 @@ static int hid_lgff_flush(struct input_d
 		  and perform ioctls on the same fd all at the same time */
 		if ( current->pid == lgff->effects[i].owner
 		     && test_bit(EFFECT_USED, lgff->effects[i].flags)) {
-			
+
 			if (hid_lgff_erase(dev, i))
 				warn("erase effect %d failed", i);
 		}
@@ -378,7 +378,7 @@ static int hid_lgff_upload_effect(struct
 	struct lgff_effect new;
 	int id;
 	unsigned long flags;
-	
+
 	dbg("ioctl rumble");
 
 	if (!test_bit(effect->type, input->ffbit)) return -EINVAL;
@@ -441,7 +441,7 @@ static void hid_lgff_timer(unsigned long
 
 	spin_lock_irqsave(&lgff->lock, flags);
 
- 	for (i=0; i<LGFF_EFFECTS; ++i) {
+	for (i=0; i<LGFF_EFFECTS; ++i) {
 		struct lgff_effect* effect = lgff->effects +i;
 
 		if (test_bit(EFFECT_PLAYING, effect->flags)) {
@@ -491,7 +491,7 @@ static void hid_lgff_timer(unsigned long
 				set_bit(EFFECT_PLAYING, lgff->effects[i].flags);
 			}
 		}
- 	}
+	}
 
 #define CLAMP(x) if (x < 0) x = 0; if (x > 0xff) x = 0xff
 
@@ -524,5 +524,5 @@ static void hid_lgff_timer(unsigned long
 		add_timer(&lgff->timer);
 	}
 
- 	spin_unlock_irqrestore(&lgff->lock, flags);
+	spin_unlock_irqrestore(&lgff->lock, flags);
 }
diff --git a/drivers/usb/input/hid.h b/drivers/usb/input/hid.h
--- a/drivers/usb/input/hid.h
+++ b/drivers/usb/input/hid.h
@@ -118,7 +118,7 @@ struct hid_item {
 #define HID_MAIN_ITEM_CONSTANT		0x001
 #define HID_MAIN_ITEM_VARIABLE		0x002
 #define HID_MAIN_ITEM_RELATIVE		0x004
-#define HID_MAIN_ITEM_WRAP		0x008	
+#define HID_MAIN_ITEM_WRAP		0x008
 #define HID_MAIN_ITEM_NONLINEAR		0x010
 #define HID_MAIN_ITEM_NO_PREFERRED	0x020
 #define HID_MAIN_ITEM_NULL_STATE	0x040
@@ -172,14 +172,14 @@ struct hid_item {
 #define HID_USAGE_PAGE		0xffff0000
 
 #define HID_UP_UNDEFINED	0x00000000
-#define HID_UP_GENDESK 		0x00010000
-#define HID_UP_KEYBOARD 	0x00070000
-#define HID_UP_LED 		0x00080000
-#define HID_UP_BUTTON 		0x00090000
-#define HID_UP_ORDINAL 		0x000a0000
+#define HID_UP_GENDESK		0x00010000
+#define HID_UP_KEYBOARD		0x00070000
+#define HID_UP_LED		0x00080000
+#define HID_UP_BUTTON		0x00090000
+#define HID_UP_ORDINAL		0x000a0000
 #define HID_UP_CONSUMER		0x000c0000
-#define HID_UP_DIGITIZER 	0x000d0000
-#define HID_UP_PID 		0x000f0000
+#define HID_UP_DIGITIZER	0x000d0000
+#define HID_UP_PID		0x000f0000
 #define HID_UP_HPVENDOR         0xff7f0000
 #define HID_UP_MSVENDOR		0xff000000
 
@@ -406,7 +406,7 @@ struct hid_device {							/* device repo
 	dma_addr_t outbuf_dma;						/* Output buffer dma */
 	spinlock_t outlock;						/* Output fifo spinlock */
 
-	unsigned claimed;						/* Claimed by hidinput, hiddev? */	
+	unsigned claimed;						/* Claimed by hidinput, hiddev? */
 	unsigned quirks;						/* Various quirks the device can pull on us */
 
 	struct list_head inputs;					/* The list of inputs */
diff --git a/drivers/usb/input/hiddev.c b/drivers/usb/input/hiddev.c
--- a/drivers/usb/input/hiddev.c
+++ b/drivers/usb/input/hiddev.c
@@ -95,7 +95,7 @@ hiddev_lookup_report(struct hid_device *
 			return NULL;
 		rinfo->report_id = ((struct hid_report *) list)->id;
 		break;
-		
+
 	case HID_REPORT_ID_NEXT:
 		list = (struct list_head *)
 			report_enum->report_id_hash[rinfo->report_id & HID_REPORT_ID_MASK];
@@ -106,7 +106,7 @@ hiddev_lookup_report(struct hid_device *
 			return NULL;
 		rinfo->report_id = ((struct hid_report *) list)->id;
 		break;
-		
+
 	default:
 		return NULL;
 	}
@@ -158,7 +158,7 @@ static void hiddev_send_event(struct hid
 		if (uref->field_index != HID_FIELD_INDEX_NONE ||
 		    (list->flags & HIDDEV_FLAG_REPORT) != 0) {
 			list->buffer[list->head] = *uref;
-			list->head = (list->head + 1) & 
+			list->head = (list->head + 1) &
 				(HIDDEV_BUFFER_SIZE - 1);
 			kill_fasync(&list->fasync, SIGIO, POLL_IN);
 		}
@@ -179,9 +179,9 @@ void hiddev_hid_event(struct hid_device 
 	unsigned type = field->report_type;
 	struct hiddev_usage_ref uref;
 
-	uref.report_type = 
+	uref.report_type =
 	  (type == HID_INPUT_REPORT) ? HID_REPORT_TYPE_INPUT :
-	  ((type == HID_OUTPUT_REPORT) ? HID_REPORT_TYPE_OUTPUT : 
+	  ((type == HID_OUTPUT_REPORT) ? HID_REPORT_TYPE_OUTPUT :
 	   ((type == HID_FEATURE_REPORT) ? HID_REPORT_TYPE_FEATURE:0));
 	uref.report_id = field->report->id;
 	uref.field_index = field->index;
@@ -199,9 +199,9 @@ void hiddev_report_event(struct hid_devi
 	struct hiddev_usage_ref uref;
 
 	memset(&uref, 0, sizeof(uref));
-	uref.report_type = 
+	uref.report_type =
 	  (type == HID_INPUT_REPORT) ? HID_REPORT_TYPE_INPUT :
-	  ((type == HID_OUTPUT_REPORT) ? HID_REPORT_TYPE_OUTPUT : 
+	  ((type == HID_OUTPUT_REPORT) ? HID_REPORT_TYPE_OUTPUT :
 	   ((type == HID_FEATURE_REPORT) ? HID_REPORT_TYPE_FEATURE:0));
 	uref.report_id = report->id;
 	uref.field_index = HID_FIELD_INDEX_NONE;
@@ -236,7 +236,7 @@ static int hiddev_release(struct inode *
 	*listptr = (*listptr)->next;
 
 	if (!--list->hiddev->open) {
-		if (list->hiddev->exist) 
+		if (list->hiddev->exist)
 			hid_close(list->hiddev->hid);
 		else
 			kfree(list->hiddev);
@@ -303,7 +303,7 @@ static ssize_t hiddev_read(struct file *
 		if (list->head == list->tail) {
 			add_wait_queue(&list->hiddev->wait, &wait);
 			set_current_state(TASK_INTERRUPTIBLE);
-			
+
 			while (list->head == list->tail) {
 				if (file->f_flags & O_NONBLOCK) {
 					retval = -EAGAIN;
@@ -317,7 +317,7 @@ static ssize_t hiddev_read(struct file *
 					retval = -EIO;
 					break;
 				}
-				
+
 				schedule();
 			}
 
@@ -329,7 +329,7 @@ static ssize_t hiddev_read(struct file *
 			return retval;
 
 
-		while (list->head != list->tail && 
+		while (list->head != list->tail &&
 		       retval + event_size <= count) {
 			if ((list->flags & HIDDEV_FLAG_UREF) == 0) {
 				if (list->buffer[list->tail].field_index !=
@@ -405,10 +405,10 @@ static int hiddev_ioctl(struct inode *in
 			return -EINVAL;
 
 		for (i = 0; i < hid->maxcollection; i++)
-			if (hid->collection[i].type == 
+			if (hid->collection[i].type ==
 			    HID_COLLECTION_APPLICATION && arg-- == 0)
 				break;
-		
+
 		if (i == hid->maxcollection)
 			return -EINVAL;
 
@@ -562,7 +562,7 @@ static int hiddev_ioctl(struct inode *in
 		if (!uref_multi)
 			return -ENOMEM;
 		uref = &uref_multi->uref;
-		if (copy_from_user(uref, user_arg, sizeof(*uref))) 
+		if (copy_from_user(uref, user_arg, sizeof(*uref)))
 			goto fault;
 
 		rinfo.report_type = uref->report_type;
@@ -595,7 +595,7 @@ static int hiddev_ioctl(struct inode *in
 			return -ENOMEM;
 		uref = &uref_multi->uref;
 		if (cmd == HIDIOCGUSAGES || cmd == HIDIOCSUSAGES) {
-			if (copy_from_user(uref_multi, user_arg, 
+			if (copy_from_user(uref_multi, user_arg,
 					   sizeof(*uref_multi)))
 				goto fault;
 		} else {
@@ -603,7 +603,7 @@ static int hiddev_ioctl(struct inode *in
 				goto fault;
 		}
 
-		if (cmd != HIDIOCGUSAGE && 
+		if (cmd != HIDIOCGUSAGE &&
 		    cmd != HIDIOCGUSAGES &&
 		    uref->report_type == HID_REPORT_TYPE_INPUT)
 			goto inval;
@@ -651,16 +651,16 @@ static int hiddev_ioctl(struct inode *in
 				return field->usage[uref->usage_index].collection_index;
 			case HIDIOCGUSAGES:
 				for (i = 0; i < uref_multi->num_values; i++)
-					uref_multi->values[i] = 
+					uref_multi->values[i] =
 					    field->value[uref->usage_index + i];
-				if (copy_to_user(user_arg, uref_multi, 
+				if (copy_to_user(user_arg, uref_multi,
 						 sizeof(*uref_multi)))
 					goto fault;
 				goto goodreturn;
 			case HIDIOCSUSAGES:
 				for (i = 0; i < uref_multi->num_values; i++)
-					field->value[uref->usage_index + i] = 
-				  	    uref_multi->values[i];
+					field->value[uref->usage_index + i] =
+					    uref_multi->values[i];
 				goto goodreturn;
 		}
 
@@ -670,7 +670,7 @@ goodreturn:
 fault:
 		kfree(uref_multi);
 		return -EFAULT;
-inval:		
+inval:
 		kfree(uref_multi);
 		return -EINVAL;
 
@@ -734,7 +734,7 @@ static struct usb_class_driver hiddev_cl
 	.name =		"usb/hid/hiddev%d",
 	.fops =		&hiddev_fops,
 	.mode =		S_IFCHR | S_IRUGO | S_IWUSR,
-       	.minor_base =	HIDDEV_MINOR_BASE,
+	.minor_base =	HIDDEV_MINOR_BASE,
 };
 
 /*
@@ -747,7 +747,7 @@ int hiddev_connect(struct hid_device *hi
 	int retval;
 
 	for (i = 0; i < hid->maxcollection; i++)
-		if (hid->collection[i].type == 
+		if (hid->collection[i].type ==
 		    HID_COLLECTION_APPLICATION &&
 		    !IS_INPUT_APPLICATION(hid->collection[i].usage))
 			break;
@@ -755,11 +755,11 @@ int hiddev_connect(struct hid_device *hi
 	if (i == hid->maxcollection && (hid->quirks & HID_QUIRK_HIDDEV) == 0)
 		return -1;
 
- 	if (!(hiddev = kmalloc(sizeof(struct hiddev), GFP_KERNEL)))
+	if (!(hiddev = kmalloc(sizeof(struct hiddev), GFP_KERNEL)))
 		return -1;
 	memset(hiddev, 0, sizeof(struct hiddev));
 
- 	retval = usb_register_dev(hid->intf, &hiddev_class);
+	retval = usb_register_dev(hid->intf, &hiddev_class);
 	if (retval) {
 		err("Not able to get a minor for this device.");
 		kfree(hiddev);
@@ -768,12 +768,12 @@ int hiddev_connect(struct hid_device *hi
 
 	init_waitqueue_head(&hiddev->wait);
 
- 	hiddev_table[hid->intf->minor - HIDDEV_MINOR_BASE] = hiddev;
+	hiddev_table[hid->intf->minor - HIDDEV_MINOR_BASE] = hiddev;
 
 	hiddev->hid = hid;
 	hiddev->exist = 1;
 
- 	hid->minor = hid->intf->minor;
+	hid->minor = hid->intf->minor;
 	hid->hiddev = hiddev;
 
 	return 0;
@@ -818,7 +818,7 @@ void hiddev_disconnect(struct hid_device
 /* We never attach in this manner, and rely on HID to connect us.  This
  * is why there is no disconnect routine defined in the usb_driver either.
  */
-static int hiddev_usbd_probe(struct usb_interface *intf, 
+static int hiddev_usbd_probe(struct usb_interface *intf,
 			     const struct usb_device_id *hiddev_info)
 {
 	return -ENODEV;
diff --git a/drivers/usb/input/itmtouch.c b/drivers/usb/input/itmtouch.c
new file mode 100644
--- /dev/null
+++ b/drivers/usb/input/itmtouch.c
@@ -0,0 +1,266 @@
+/******************************************************************************
+ * itmtouch.c  --  Driver for ITM touchscreen panel
+ *
+ * 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.
+ *
+ * Based upon original work by Chris Collins <xfire-itmtouch@xware.cx>.
+ *
+ * Kudos to ITM for providing me with the datasheet for the panel,
+ * even though it was a day later than I had finished writing this
+ * driver.
+ *
+ * It has meant that I've been able to correct my interpretation of the
+ * protocol packets however.
+ *
+ * CC -- 2003/9/29
+ *
+ * History
+ * 1.0 & 1.1  2003 (CC) vojtech@suse.cz
+ *   Original version for 2.4.x kernels
+ *
+ * 1.2  02/03/2005 (HCE) hc@mivu.no
+ *   Complete rewrite to support Linux 2.6.10, thanks to mtouchusb.c for hints.
+ *   Unfortunately no calibration support at this time.
+ *
+ * 1.2.1  09/03/2005 (HCE) hc@mivu.no
+ *   Code cleanup and adjusting syntax to start matching kernel standards
+ *
+ *****************************************************************************/
+
+#include <linux/config.h>
+
+#ifdef CONFIG_USB_DEBUG
+	#define DEBUG
+#else
+	#undef DEBUG
+#endif
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/input.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/usb.h>
+#include <linux/usb_input.h>
+
+/* only an 8 byte buffer necessary for a single packet */
+#define ITM_BUFSIZE			8
+#define PATH_SIZE			64
+
+#define USB_VENDOR_ID_ITMINC		0x0403
+#define USB_PRODUCT_ID_TOUCHPANEL	0xf9e9
+
+#define DRIVER_AUTHOR "Hans-Christian Egtvedt <hc@mivu.no>"
+#define DRIVER_VERSION "v1.2.1"
+#define DRIVER_DESC "USB ITM Inc Touch Panel Driver"
+#define DRIVER_LICENSE "GPL"
+
+MODULE_AUTHOR( DRIVER_AUTHOR );
+MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_LICENSE( DRIVER_LICENSE );
+
+struct itmtouch_dev {
+	struct usb_device	*usbdev; /* usb device */
+	struct input_dev	inputdev; /* input device */
+	struct urb		*readurb; /* urb */
+	char			rbuf[ITM_BUFSIZE]; /* data */
+	int			users;
+	char name[128];
+	char phys[64];
+};
+
+static struct usb_device_id itmtouch_ids [] = {
+	{ USB_DEVICE(USB_VENDOR_ID_ITMINC, USB_PRODUCT_ID_TOUCHPANEL) },
+	{ }
+};
+
+static void itmtouch_irq(struct urb *urb, struct pt_regs *regs)
+{
+	struct itmtouch_dev * itmtouch = urb->context;
+	unsigned char *data = urb->transfer_buffer;
+	struct input_dev *dev = &itmtouch->inputdev;
+	int retval;
+
+	switch (urb->status) {
+	case 0:
+		/* success */
+		break;
+	case -ETIMEDOUT:
+		/* this urb is timing out */
+		dbg("%s - urb timed out - was the device unplugged?",
+		    __FUNCTION__);
+		return;
+	case -ECONNRESET:
+	case -ENOENT:
+	case -ESHUTDOWN:
+		/* this urb is terminated, clean up */
+		dbg("%s - urb shutting down with status: %d",
+		    __FUNCTION__, urb->status);
+		return;
+	default:
+		dbg("%s - nonzero urb status received: %d",
+		    __FUNCTION__, urb->status);
+		goto exit;
+	}
+
+	input_regs(dev, regs);
+
+	/* if pressure has been released, then don't report X/Y */
+	if (data[7] & 0x20) {
+		input_report_abs(dev, ABS_X, (data[0] & 0x1F) << 7 | (data[3] & 0x7F));
+		input_report_abs(dev, ABS_Y, (data[1] & 0x1F) << 7 | (data[4] & 0x7F));
+	}
+
+	input_report_abs(dev, ABS_PRESSURE, (data[2] & 1) << 7 | (data[5] & 0x7F));
+	input_report_key(dev, BTN_TOUCH, ~data[7] & 0x20);
+	input_sync(dev);
+
+exit:
+	retval = usb_submit_urb (urb, GFP_ATOMIC);
+	if (retval)
+		printk(KERN_ERR "%s - usb_submit_urb failed with result: %d",
+				__FUNCTION__, retval);
+}
+
+static int itmtouch_open(struct input_dev *input)
+{
+	struct itmtouch_dev *itmtouch = input->private;
+
+	itmtouch->readurb->dev = itmtouch->usbdev;
+
+	if (usb_submit_urb(itmtouch->readurb, GFP_KERNEL))
+		return -EIO;
+
+	return 0;
+}
+
+static void itmtouch_close(struct input_dev *input)
+{
+	struct itmtouch_dev *itmtouch = input->private;
+
+	usb_kill_urb(itmtouch->readurb);
+}
+
+static int itmtouch_probe(struct usb_interface *intf, const struct usb_device_id *id)
+{
+	struct itmtouch_dev *itmtouch;
+	struct usb_host_interface *interface;
+	struct usb_endpoint_descriptor *endpoint;
+	struct usb_device *udev = interface_to_usbdev(intf);
+	unsigned int pipe;
+	unsigned int maxp;
+	char path[PATH_SIZE];
+
+	interface = intf->cur_altsetting;
+	endpoint = &interface->endpoint[0].desc;
+
+	if (!(itmtouch = kcalloc(1, sizeof(struct itmtouch_dev), GFP_KERNEL))) {
+		err("%s - Out of memory.", __FUNCTION__);
+		return -ENOMEM;
+	}
+
+	itmtouch->usbdev = udev;
+
+	itmtouch->inputdev.private = itmtouch;
+	itmtouch->inputdev.open = itmtouch_open;
+	itmtouch->inputdev.close = itmtouch_close;
+
+	usb_make_path(udev, path, PATH_SIZE);
+
+	itmtouch->inputdev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+	itmtouch->inputdev.absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE);
+	itmtouch->inputdev.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+
+	itmtouch->inputdev.name = itmtouch->name;
+	itmtouch->inputdev.phys = itmtouch->phys;
+	usb_to_input_id(udev, &itmtouch->inputdev.id);
+	itmtouch->inputdev.dev = &intf->dev;
+
+	if (!strlen(itmtouch->name))
+		sprintf(itmtouch->name, "USB ITM touchscreen");
+
+	/* device limits */
+	/* as specified by the ITM datasheet, X and Y are 12bit,
+	 * Z (pressure) is 8 bit. However, the fields are defined up
+	 * to 14 bits for future possible expansion.
+	 */
+	input_set_abs_params(&itmtouch->inputdev, ABS_X, 0, 0x0FFF, 2, 0);
+	input_set_abs_params(&itmtouch->inputdev, ABS_Y, 0, 0x0FFF, 2, 0);
+	input_set_abs_params(&itmtouch->inputdev, ABS_PRESSURE, 0, 0xFF, 2, 0);
+
+	/* initialise the URB so we can read from the transport stream */
+	pipe = usb_rcvintpipe(itmtouch->usbdev, endpoint->bEndpointAddress);
+	maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe));
+
+	if (maxp > ITM_BUFSIZE)
+		maxp = ITM_BUFSIZE;
+
+	itmtouch->readurb = usb_alloc_urb(0, GFP_KERNEL);
+
+	if (!itmtouch->readurb) {
+		dbg("%s - usb_alloc_urb failed: itmtouch->readurb", __FUNCTION__);
+		kfree(itmtouch);
+		return -ENOMEM;
+	}
+
+	usb_fill_int_urb(itmtouch->readurb, itmtouch->usbdev, pipe, itmtouch->rbuf,
+			 maxp, itmtouch_irq, itmtouch, endpoint->bInterval);
+
+	input_register_device(&itmtouch->inputdev);
+
+	printk(KERN_INFO "itmtouch: %s registered on %s\n", itmtouch->name, path);
+	usb_set_intfdata(intf, itmtouch);
+
+	return 0;
+}
+
+static void itmtouch_disconnect(struct usb_interface *intf)
+{
+	struct itmtouch_dev *itmtouch = usb_get_intfdata(intf);
+
+	usb_set_intfdata(intf, NULL);
+
+	if (itmtouch) {
+		input_unregister_device(&itmtouch->inputdev);
+		usb_kill_urb(itmtouch->readurb);
+		usb_free_urb(itmtouch->readurb);
+		kfree(itmtouch);
+	}
+}
+
+MODULE_DEVICE_TABLE(usb, itmtouch_ids);
+
+static struct usb_driver itmtouch_driver = {
+	.owner =        THIS_MODULE,
+	.name =         "itmtouch",
+	.probe =        itmtouch_probe,
+	.disconnect =   itmtouch_disconnect,
+	.id_table =     itmtouch_ids,
+};
+
+static int __init itmtouch_init(void)
+{
+	info(DRIVER_DESC " " DRIVER_VERSION);
+	info(DRIVER_AUTHOR);
+	return usb_register(&itmtouch_driver);
+}
+
+static void __exit itmtouch_exit(void)
+{
+	usb_deregister(&itmtouch_driver);
+}
+
+module_init(itmtouch_init);
+module_exit(itmtouch_exit);
diff --git a/drivers/usb/input/kbtab.c b/drivers/usb/input/kbtab.c
--- a/drivers/usb/input/kbtab.c
+++ b/drivers/usb/input/kbtab.c
@@ -4,6 +4,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/usb.h>
+#include <linux/usb_input.h>
 #include <asm/unaligned.h>
 #include <asm/byteorder.h>
 
@@ -36,7 +37,6 @@ struct kbtab {
 	struct input_dev dev;
 	struct usb_device *usbdev;
 	struct urb *irq;
-	int open;
 	int x, y;
 	int button;
 	int pressure;
@@ -79,12 +79,12 @@ static void kbtab_irq(struct urb *urb, s
 	/*input_report_key(dev, BTN_TOUCH , data[0] & 0x01);*/
 	input_report_key(dev, BTN_RIGHT, data[0] & 0x02);
 
-	if( -1 == kb_pressure_click){ 
+	if (-1 == kb_pressure_click) {
 		input_report_abs(dev, ABS_PRESSURE, kbtab->pressure);
 	} else {
 		input_report_key(dev, BTN_LEFT, (kbtab->pressure > kb_pressure_click) ? 1 : 0);
 	};
-	
+
 	input_sync(dev);
 
  exit:
@@ -105,14 +105,9 @@ static int kbtab_open(struct input_dev *
 {
 	struct kbtab *kbtab = dev->private;
 
-	if (kbtab->open++)
-		return 0;
-
 	kbtab->irq->dev = kbtab->usbdev;
-	if (usb_submit_urb(kbtab->irq, GFP_KERNEL)) {
-		kbtab->open--;
+	if (usb_submit_urb(kbtab->irq, GFP_KERNEL))
 		return -EIO;
-	}
 
 	return 0;
 }
@@ -121,8 +116,7 @@ static void kbtab_close(struct input_dev
 {
 	struct kbtab *kbtab = dev->private;
 
-	if (!--kbtab->open)
-		usb_kill_urb(kbtab->irq);
+	usb_kill_urb(kbtab->irq);
 }
 
 static int kbtab_probe(struct usb_interface *intf, const struct usb_device_id *id)
@@ -161,7 +155,7 @@ static int kbtab_probe(struct usb_interf
 	kbtab->dev.absmax[ABS_X] = 0x2000;
 	kbtab->dev.absmax[ABS_Y] = 0x1750;
 	kbtab->dev.absmax[ABS_PRESSURE] = 0xff;
-	
+
 	kbtab->dev.absfuzz[ABS_X] = 4;
 	kbtab->dev.absfuzz[ABS_Y] = 4;
 
@@ -174,10 +168,7 @@ static int kbtab_probe(struct usb_interf
 
 	kbtab->dev.name = "KB Gear Tablet";
 	kbtab->dev.phys = kbtab->phys;
-	kbtab->dev.id.bustype = BUS_USB;
-	kbtab->dev.id.vendor = le16_to_cpu(dev->descriptor.idVendor);
-	kbtab->dev.id.product = le16_to_cpu(dev->descriptor.idProduct);
-	kbtab->dev.id.version = le16_to_cpu(dev->descriptor.bcdDevice);
+	usb_to_input_id(dev, &kbtab->dev.id);
 	kbtab->dev.dev = &intf->dev;
 	kbtab->usbdev = dev;
 
diff --git a/drivers/usb/input/keyspan_remote.c b/drivers/usb/input/keyspan_remote.c
new file mode 100644
--- /dev/null
+++ b/drivers/usb/input/keyspan_remote.c
@@ -0,0 +1,633 @@
+/*
+ * keyspan_remote: USB driver for the Keyspan DMR
+ *
+ * Copyright (C) 2005 Zymeta Corporation - Michael Downey (downey@zymeta.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, version 2.
+ *
+ * This driver has been put together with the support of Innosys, Inc.
+ * and Keyspan, Inc the manufacturers of the Keyspan USB DMR product.
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/input.h>
+#include <linux/usb.h>
+
+#define DRIVER_VERSION	"v0.1"
+#define DRIVER_AUTHOR	"Michael Downey <downey@zymeta.com>"
+#define DRIVER_DESC	"Driver for the USB Keyspan remote control."
+#define DRIVER_LICENSE	"GPL"
+
+/* Parameters that can be passed to the driver. */
+static int debug;
+module_param(debug, int, 0444);
+MODULE_PARM_DESC(debug, "Enable extra debug messages and information");
+
+/* Vendor and product ids */
+#define USB_KEYSPAN_VENDOR_ID		0x06CD
+#define USB_KEYSPAN_PRODUCT_UIA11	0x0202
+
+/* Defines for converting the data from the remote. */
+#define ZERO		0x18
+#define ZERO_MASK	0x1F	/* 5 bits for a 0 */
+#define ONE		0x3C
+#define ONE_MASK	0x3F	/* 6 bits for a 1 */
+#define SYNC		0x3F80
+#define SYNC_MASK	0x3FFF	/* 14 bits for a SYNC sequence */
+#define STOP		0x00
+#define STOP_MASK	0x1F	/* 5 bits for the STOP sequence */
+#define GAP		0xFF
+
+#define RECV_SIZE	8	/* The UIA-11 type have a 8 byte limit. */
+
+/* table of devices that work with this driver */
+static struct usb_device_id keyspan_table[] = {
+	{ USB_DEVICE(USB_KEYSPAN_VENDOR_ID, USB_KEYSPAN_PRODUCT_UIA11) },
+	{ }					/* Terminating entry */
+};
+
+/* Structure to store all the real stuff that a remote sends to us. */
+struct keyspan_message {
+	u16	system;
+	u8	button;
+	u8	toggle;
+};
+
+/* Structure used for all the bit testing magic needed to be done. */
+struct bit_tester {
+	u32	tester;
+	int	len;
+	int	pos;
+	int	bits_left;
+	u8	buffer[32];
+};
+
+/* Structure to hold all of our driver specific stuff */
+struct usb_keyspan {
+	char				name[128];
+	char				phys[64];
+	struct usb_device*		udev;
+	struct input_dev		input;
+	struct usb_interface*		interface;
+	struct usb_endpoint_descriptor* in_endpoint;
+	struct urb*			irq_urb;
+	int				open;
+	dma_addr_t			in_dma;
+	unsigned char*			in_buffer;
+
+	/* variables used to parse messages from remote. */
+	struct bit_tester		data;
+	int				stage;
+	int				toggle;
+};
+
+/*
+ * Table that maps the 31 possible keycodes to input keys.
+ * Currently there are 15 and 17 button models so RESERVED codes
+ * are blank areas in the mapping.
+ */
+static int keyspan_key_table[] = {
+	KEY_RESERVED,		/* 0 is just a place holder. */
+	KEY_RESERVED,
+	KEY_STOP,
+	KEY_PLAYCD,
+	KEY_RESERVED,
+	KEY_PREVIOUSSONG,
+	KEY_REWIND,
+	KEY_FORWARD,
+	KEY_NEXTSONG,
+	KEY_RESERVED,
+	KEY_RESERVED,
+	KEY_RESERVED,
+	KEY_PAUSE,
+	KEY_VOLUMEUP,
+	KEY_RESERVED,
+	KEY_RESERVED,
+	KEY_RESERVED,
+	KEY_VOLUMEDOWN,
+	KEY_RESERVED,
+	KEY_UP,
+	KEY_RESERVED,
+	KEY_MUTE,
+	KEY_LEFT,
+	KEY_ENTER,
+	KEY_RIGHT,
+	KEY_RESERVED,
+	KEY_RESERVED,
+	KEY_DOWN,
+	KEY_RESERVED,
+	KEY_KPASTERISK,
+	KEY_RESERVED,
+	KEY_MENU
+};
+
+static struct usb_driver keyspan_driver;
+
+/*
+ * Debug routine that prints out what we've received from the remote.
+ */
+static void keyspan_print(struct usb_keyspan* dev) /*unsigned char* data)*/
+{
+	char codes[4*RECV_SIZE];
+	int i;
+
+	for (i = 0; i < RECV_SIZE; i++) {
+		snprintf(codes+i*3, 4, "%02x ", dev->in_buffer[i]);
+	}
+
+	dev_info(&dev->udev->dev, "%s\n", codes);
+}
+
+/*
+ * Routine that manages the bit_tester structure.  It makes sure that there are
+ * at least bits_needed bits loaded into the tester.
+ */
+static int keyspan_load_tester(struct usb_keyspan* dev, int bits_needed)
+{
+	if (dev->data.bits_left >= bits_needed)
+		return(0);
+
+	/*
+	 * Somehow we've missed the last message. The message will be repeated
+	 * though so it's not too big a deal
+	 */
+	if (dev->data.pos >= dev->data.len) {
+		dev_dbg(&dev->udev, "%s - Error ran out of data. pos: %d, len: %d\n",
+			__FUNCTION__, dev->data.pos, dev->data.len);
+		return(-1);
+	}
+
+	/* Load as much as we can into the tester. */
+	while ((dev->data.bits_left + 7 < (sizeof(dev->data.tester) * 8)) &&
+	       (dev->data.pos < dev->data.len)) {
+		dev->data.tester += (dev->data.buffer[dev->data.pos++] << dev->data.bits_left);
+		dev->data.bits_left += 8;
+	}
+
+	return(0);
+}
+
+/*
+ * Routine that handles all the logic needed to parse out the message from the remote.
+ */
+static void keyspan_check_data(struct usb_keyspan *remote, struct pt_regs *regs)
+{
+	int i;
+	int found = 0;
+	struct keyspan_message message;
+
+	switch(remote->stage) {
+	case 0:
+		/*
+		 * In stage 0 we want to find the start of a message.  The remote sends a 0xFF as filler.
+		 * So the first byte that isn't a FF should be the start of a new message.
+		 */
+		for (i = 0; i < RECV_SIZE && remote->in_buffer[i] == GAP; ++i);
+
+		if (i < RECV_SIZE) {
+			memcpy(remote->data.buffer, remote->in_buffer, RECV_SIZE);
+			remote->data.len = RECV_SIZE;
+			remote->data.pos = 0;
+			remote->data.tester = 0;
+			remote->data.bits_left = 0;
+			remote->stage = 1;
+		}
+		break;
+
+	case 1:
+		/*
+		 * Stage 1 we should have 16 bytes and should be able to detect a
+		 * SYNC.  The SYNC is 14 bits, 7 0's and then 7 1's.
+		 */
+		memcpy(remote->data.buffer + remote->data.len, remote->in_buffer, RECV_SIZE);
+		remote->data.len += RECV_SIZE;
+
+		found = 0;
+		while ((remote->data.bits_left >= 14 || remote->data.pos < remote->data.len) && !found) {
+			for (i = 0; i < 8; ++i) {
+				if (keyspan_load_tester(remote, 14) != 0) {
+					remote->stage = 0;
+					return;
+				}
+
+				if ((remote->data.tester & SYNC_MASK) == SYNC) {
+					remote->data.tester = remote->data.tester >> 14;
+					remote->data.bits_left -= 14;
+					found = 1;
+					break;
+				} else {
+					remote->data.tester = remote->data.tester >> 1;
+					--remote->data.bits_left;
+				}
+			}
+		}
+
+		if (!found) {
+			remote->stage = 0;
+			remote->data.len = 0;
+		} else {
+			remote->stage = 2;
+		}
+		break;
+
+	case 2:
+		/*
+		 * Stage 2 we should have 24 bytes which will be enough for a full
+		 * message.  We need to parse out the system code, button code,
+		 * toggle code, and stop.
+		 */
+		memcpy(remote->data.buffer + remote->data.len, remote->in_buffer, RECV_SIZE);
+		remote->data.len += RECV_SIZE;
+
+		message.system = 0;
+		for (i = 0; i < 9; i++) {
+			keyspan_load_tester(remote, 6);
+
+			if ((remote->data.tester & ZERO_MASK) == ZERO) {
+				message.system = message.system << 1;
+				remote->data.tester = remote->data.tester >> 5;
+				remote->data.bits_left -= 5;
+			} else if ((remote->data.tester & ONE_MASK) == ONE) {
+				message.system = (message.system << 1) + 1;
+				remote->data.tester = remote->data.tester >> 6;
+				remote->data.bits_left -= 6;
+			} else {
+				err("%s - Unknown sequence found in system data.\n", __FUNCTION__);
+				remote->stage = 0;
+				return;
+			}
+		}
+
+		message.button = 0;
+		for (i = 0; i < 5; i++) {
+			keyspan_load_tester(remote, 6);
+
+			if ((remote->data.tester & ZERO_MASK) == ZERO) {
+				message.button = message.button << 1;
+				remote->data.tester = remote->data.tester >> 5;
+				remote->data.bits_left -= 5;
+			} else if ((remote->data.tester & ONE_MASK) == ONE) {
+				message.button = (message.button << 1) + 1;
+				remote->data.tester = remote->data.tester >> 6;
+				remote->data.bits_left -= 6;
+			} else {
+				err("%s - Unknown sequence found in button data.\n", __FUNCTION__);
+				remote->stage = 0;
+				return;
+			}
+		}
+
+		keyspan_load_tester(remote, 6);
+		if ((remote->data.tester & ZERO_MASK) == ZERO) {
+			message.toggle = 0;
+			remote->data.tester = remote->data.tester >> 5;
+			remote->data.bits_left -= 5;
+		} else if ((remote->data.tester & ONE_MASK) == ONE) {
+			message.toggle = 1;
+			remote->data.tester = remote->data.tester >> 6;
+			remote->data.bits_left -= 6;
+		} else {
+			err("%s - Error in message, invalid toggle.\n", __FUNCTION__);
+		}
+
+		keyspan_load_tester(remote, 5);
+		if ((remote->data.tester & STOP_MASK) == STOP) {
+			remote->data.tester = remote->data.tester >> 5;
+			remote->data.bits_left -= 5;
+		} else {
+			err("Bad message recieved, no stop bit found.\n");
+		}
+
+		dev_dbg(&remote->udev,
+			"%s found valid message: system: %d, button: %d, toggle: %d\n",
+			__FUNCTION__, message.system, message.button, message.toggle);
+
+		if (message.toggle != remote->toggle) {
+			input_regs(&remote->input, regs);
+			input_report_key(&remote->input, keyspan_key_table[message.button], 1);
+			input_report_key(&remote->input, keyspan_key_table[message.button], 0);
+			input_sync(&remote->input);
+			remote->toggle = message.toggle;
+		}
+
+		remote->stage = 0;
+		break;
+	}
+}
+
+/*
+ * Routine for sending all the initialization messages to the remote.
+ */
+static int keyspan_setup(struct usb_device* dev)
+{
+	int retval = 0;
+
+	retval = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+				 0x11, 0x40, 0x5601, 0x0, NULL, 0, 0);
+	if (retval) {
+		dev_dbg(&dev->dev, "%s - failed to set bit rate due to error: %d\n",
+			__FUNCTION__, retval);
+		return(retval);
+	}
+
+	retval = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+				 0x44, 0x40, 0x0, 0x0, NULL, 0, 0);
+	if (retval) {
+		dev_dbg(&dev->dev, "%s - failed to set resume sensitivity due to error: %d\n",
+			__FUNCTION__, retval);
+		return(retval);
+	}
+
+	retval = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+				 0x22, 0x40, 0x0, 0x0, NULL, 0, 0);
+	if (retval) {
+		dev_dbg(&dev->dev, "%s - failed to turn receive on due to error: %d\n",
+			__FUNCTION__, retval);
+		return(retval);
+	}
+
+	dev_dbg(&dev->dev, "%s - Setup complete.\n", __FUNCTION__);
+	return(retval);
+}
+
+/*
+ * Routine used to handle a new message that has come in.
+ */
+static void keyspan_irq_recv(struct urb *urb, struct pt_regs *regs)
+{
+	struct usb_keyspan *dev = urb->context;
+	int retval;
+
+	/* Check our status in case we need to bail out early. */
+	switch (urb->status) {
+	case 0:
+		break;
+
+	/* Device went away so don't keep trying to read from it. */
+	case -ECONNRESET:
+	case -ENOENT:
+	case -ESHUTDOWN:
+		return;
+
+	default:
+		goto resubmit;
+		break;
+	}
+
+	if (debug)
+		keyspan_print(dev);
+
+	keyspan_check_data(dev, regs);
+
+resubmit:
+	retval = usb_submit_urb(urb, GFP_ATOMIC);
+	if (retval)
+		err ("%s - usb_submit_urb failed with result: %d", __FUNCTION__, retval);
+}
+
+static int keyspan_open(struct input_dev *dev)
+{
+	struct usb_keyspan *remote = dev->private;
+
+	if (remote->open++)
+		return 0;
+
+	remote->irq_urb->dev = remote->udev;
+	if (usb_submit_urb(remote->irq_urb, GFP_KERNEL)) {
+		remote->open--;
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static void keyspan_close(struct input_dev *dev)
+{
+	struct usb_keyspan *remote = dev->private;
+
+	if (!--remote->open)
+		usb_kill_urb(remote->irq_urb);
+}
+
+/*
+ * Routine that sets up the driver to handle a specific USB device detected on the bus.
+ */
+static int keyspan_probe(struct usb_interface *interface, const struct usb_device_id *id)
+{
+	int i;
+	int retval = -ENOMEM;
+	char path[64];
+	char *buf;
+	struct usb_keyspan *remote = NULL;
+	struct usb_host_interface *iface_desc;
+	struct usb_endpoint_descriptor *endpoint;
+	struct usb_device *udev = usb_get_dev(interface_to_usbdev(interface));
+
+	/* See if the offered device matches what we can accept */
+	if ((udev->descriptor.idVendor != USB_KEYSPAN_VENDOR_ID) ||
+	    (udev->descriptor.idProduct != USB_KEYSPAN_PRODUCT_UIA11) )
+		return -ENODEV;
+
+	/* allocate memory for our device state and initialize it */
+	remote = kmalloc(sizeof(*remote), GFP_KERNEL);
+	if (remote == NULL) {
+		err("Out of memory\n");
+		goto error;
+	}
+	memset(remote, 0x00, sizeof(*remote));
+
+	remote->udev = udev;
+	remote->interface = interface;
+	remote->toggle = -1;	/* Set to -1 so we will always not match the toggle from the first remote message. */
+
+	/* set up the endpoint information */
+	/* use only the first in interrupt endpoint */
+	iface_desc = interface->cur_altsetting;
+	for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
+		endpoint = &iface_desc->endpoint[i].desc;
+
+		if (!remote->in_endpoint &&
+		    (endpoint->bEndpointAddress & USB_DIR_IN) &&
+		    ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT)) {
+			/* we found our interrupt in endpoint */
+			remote->in_endpoint = endpoint;
+
+			remote->in_buffer = usb_buffer_alloc(remote->udev, RECV_SIZE, SLAB_ATOMIC, &remote->in_dma);
+			if (!remote->in_buffer) {
+				retval = -ENOMEM;
+				goto error;
+			}
+		}
+	}
+
+	if (!remote->in_endpoint) {
+		err("Could not find interrupt input endpoint.\n");
+		retval = -ENODEV;
+		goto error;
+	}
+
+	remote->irq_urb = usb_alloc_urb(0, GFP_KERNEL);
+	if (!remote->irq_urb) {
+		err("Failed to allocate urb.\n");
+		retval = -ENOMEM;
+		goto error;
+	}
+
+	retval = keyspan_setup(remote->udev);
+	if (retval) {
+		err("Failed to setup device.\n");
+		retval = -ENODEV;
+		goto error;
+	}
+
+	/*
+	 * Setup the input system with the bits we are going to be reporting
+	 */
+	remote->input.evbit[0] = BIT(EV_KEY);		/* We will only report KEY events. */
+	for (i = 0; i < 32; ++i) {
+		if (keyspan_key_table[i] != KEY_RESERVED) {
+			set_bit(keyspan_key_table[i], remote->input.keybit);
+		}
+	}
+
+	remote->input.private = remote;
+	remote->input.open = keyspan_open;
+	remote->input.close = keyspan_close;
+
+	usb_make_path(remote->udev, path, 64);
+	sprintf(remote->phys, "%s/input0", path);
+
+	remote->input.name = remote->name;
+	remote->input.phys = remote->phys;
+	remote->input.id.bustype = BUS_USB;
+	remote->input.id.vendor = le16_to_cpu(remote->udev->descriptor.idVendor);
+	remote->input.id.product = le16_to_cpu(remote->udev->descriptor.idProduct);
+	remote->input.id.version = le16_to_cpu(remote->udev->descriptor.bcdDevice);
+
+	if (!(buf = kmalloc(63, GFP_KERNEL))) {
+		usb_buffer_free(remote->udev, RECV_SIZE, remote->in_buffer, remote->in_dma);
+		kfree(remote);
+		return -ENOMEM;
+	}
+
+	if (remote->udev->descriptor.iManufacturer &&
+	    usb_string(remote->udev, remote->udev->descriptor.iManufacturer, buf, 63) > 0)
+		strcat(remote->name, buf);
+
+	if (remote->udev->descriptor.iProduct &&
+	    usb_string(remote->udev, remote->udev->descriptor.iProduct, buf, 63) > 0)
+		sprintf(remote->name, "%s %s", remote->name, buf);
+
+	if (!strlen(remote->name))
+		sprintf(remote->name, "USB Keyspan Remote %04x:%04x",
+			remote->input.id.vendor, remote->input.id.product);
+
+	kfree(buf);
+
+	/*
+	 * Initialize the URB to access the device. The urb gets sent to the device in keyspan_open()
+	 */
+	usb_fill_int_urb(remote->irq_urb,
+			 remote->udev, usb_rcvintpipe(remote->udev, remote->in_endpoint->bEndpointAddress),
+			 remote->in_buffer, RECV_SIZE, keyspan_irq_recv, remote,
+			 remote->in_endpoint->bInterval);
+	remote->irq_urb->transfer_dma = remote->in_dma;
+	remote->irq_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+
+	/* we can register the device now, as it is ready */
+	input_register_device(&remote->input);
+
+	/* save our data pointer in this interface device */
+	usb_set_intfdata(interface, remote);
+
+	/* let the user know what node this device is now attached to */
+	info("connected: %s on %s", remote->name, path);
+	return 0;
+
+error:
+	/*
+	 * In case of error we need to clean up any allocated buffers
+	 */
+	if (remote->irq_urb)
+		usb_free_urb(remote->irq_urb);
+
+	if (remote->in_buffer)
+		usb_buffer_free(remote->udev, RECV_SIZE, remote->in_buffer, remote->in_dma);
+
+	if (remote)
+		kfree(remote);
+
+	return retval;
+}
+
+/*
+ * Routine called when a device is disconnected from the USB.
+ */
+static void keyspan_disconnect(struct usb_interface *interface)
+{
+	struct usb_keyspan *remote;
+
+	/* prevent keyspan_open() from racing keyspan_disconnect() */
+	lock_kernel();
+
+	remote = usb_get_intfdata(interface);
+	usb_set_intfdata(interface, NULL);
+
+	if (remote) {	/* We have a valid driver structure so clean up everything we allocated. */
+		input_unregister_device(&remote->input);
+		usb_kill_urb(remote->irq_urb);
+		usb_free_urb(remote->irq_urb);
+		usb_buffer_free(interface_to_usbdev(interface), RECV_SIZE, remote->in_buffer, remote->in_dma);
+		kfree(remote);
+	}
+
+	unlock_kernel();
+
+	info("USB Keyspan now disconnected");
+}
+
+/*
+ * Standard driver set up sections
+ */
+static struct usb_driver keyspan_driver =
+{
+	.owner =	THIS_MODULE,
+	.name =		"keyspan_remote",
+	.probe =	keyspan_probe,
+	.disconnect =	keyspan_disconnect,
+	.id_table =	keyspan_table
+};
+
+static int __init usb_keyspan_init(void)
+{
+	int result;
+
+	/* register this driver with the USB subsystem */
+	result = usb_register(&keyspan_driver);
+	if (result)
+		err("usb_register failed. Error number %d\n", result);
+
+	return result;
+}
+
+static void __exit usb_keyspan_exit(void)
+{
+	/* deregister this driver with the USB subsystem */
+	usb_deregister(&keyspan_driver);
+}
+
+module_init(usb_keyspan_init);
+module_exit(usb_keyspan_exit);
+
+MODULE_DEVICE_TABLE(usb, keyspan_table);
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE(DRIVER_LICENSE);
diff --git a/drivers/usb/input/mtouchusb.c b/drivers/usb/input/mtouchusb.c
--- a/drivers/usb/input/mtouchusb.c
+++ b/drivers/usb/input/mtouchusb.c
@@ -42,9 +42,9 @@
 #include <linux/config.h>
 
 #ifdef CONFIG_USB_DEBUG
-        #define DEBUG
+	#define DEBUG
 #else
-        #undef DEBUG
+	#undef DEBUG
 #endif
 
 #include <linux/kernel.h>
@@ -53,6 +53,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/usb.h>
+#include <linux/usb_input.h>
 
 #define MTOUCHUSB_MIN_XC                0x0
 #define MTOUCHUSB_MAX_RAW_XC            0x4000
@@ -93,275 +94,252 @@ module_param(raw_coordinates, bool, S_IR
 MODULE_PARM_DESC(raw_coordinates, "report raw coordinate values (y, default) or hardware-calibrated coordinate values (n)");
 
 struct mtouch_usb {
-        unsigned char *data;
-        dma_addr_t data_dma;
-        struct urb *irq;
-        struct usb_device *udev;
-        struct input_dev input;
-        int open;
-        char name[128];
-        char phys[64];
+	unsigned char *data;
+	dma_addr_t data_dma;
+	struct urb *irq;
+	struct usb_device *udev;
+	struct input_dev input;
+	char name[128];
+	char phys[64];
 };
 
-static struct usb_device_id mtouchusb_devices [] = {
-        { USB_DEVICE(0x0596, 0x0001) },
-        { }
+static struct usb_device_id mtouchusb_devices[] = {
+	{ USB_DEVICE(0x0596, 0x0001) },
+	{ }
 };
 
 static void mtouchusb_irq(struct urb *urb, struct pt_regs *regs)
 {
-        struct mtouch_usb *mtouch = urb->context;
-        int retval;
+	struct mtouch_usb *mtouch = urb->context;
+	int retval;
 
-        switch (urb->status) {
-                case 0:
-                        /* success */
-                        break;
-                case -ETIMEDOUT:
-                        /* this urb is timing out */
-                        dbg("%s - urb timed out - was the device unplugged?",
-                            __FUNCTION__);
-                        return;
-                case -ECONNRESET:
-                case -ENOENT:
-                case -ESHUTDOWN:
-                        /* this urb is terminated, clean up */
-                        dbg("%s - urb shutting down with status: %d",
-                            __FUNCTION__, urb->status);
-                        return;
-                default:
-                        dbg("%s - nonzero urb status received: %d",
-                            __FUNCTION__, urb->status);
-                        goto exit;
-        }
-
-        input_regs(&mtouch->input, regs);
-        input_report_key(&mtouch->input, BTN_TOUCH,
-                         MTOUCHUSB_GET_TOUCHED(mtouch->data));
-        input_report_abs(&mtouch->input, ABS_X,
-                         MTOUCHUSB_GET_XC(mtouch->data));
-        input_report_abs(&mtouch->input, ABS_Y,
+	switch (urb->status) {
+	case 0:
+		/* success */
+		break;
+	case -ETIMEDOUT:
+		/* this urb is timing out */
+		dbg("%s - urb timed out - was the device unplugged?",
+		    __FUNCTION__);
+		return;
+	case -ECONNRESET:
+	case -ENOENT:
+	case -ESHUTDOWN:
+		/* this urb is terminated, clean up */
+		dbg("%s - urb shutting down with status: %d",
+		    __FUNCTION__, urb->status);
+		return;
+	default:
+		dbg("%s - nonzero urb status received: %d",
+		    __FUNCTION__, urb->status);
+		goto exit;
+	}
+
+	input_regs(&mtouch->input, regs);
+	input_report_key(&mtouch->input, BTN_TOUCH,
+			 MTOUCHUSB_GET_TOUCHED(mtouch->data));
+	input_report_abs(&mtouch->input, ABS_X, MTOUCHUSB_GET_XC(mtouch->data));
+	input_report_abs(&mtouch->input, ABS_Y,
 			 (raw_coordinates ? MTOUCHUSB_MAX_RAW_YC : MTOUCHUSB_MAX_CALIB_YC)
-                         - MTOUCHUSB_GET_YC(mtouch->data));
-        input_sync(&mtouch->input);
+			 - MTOUCHUSB_GET_YC(mtouch->data));
+	input_sync(&mtouch->input);
 
 exit:
-        retval = usb_submit_urb (urb, GFP_ATOMIC);
-        if (retval)
-                err ("%s - usb_submit_urb failed with result: %d",
-                     __FUNCTION__, retval);
+	retval = usb_submit_urb(urb, GFP_ATOMIC);
+	if (retval)
+		err("%s - usb_submit_urb failed with result: %d",
+		    __FUNCTION__, retval);
 }
 
-static int mtouchusb_open (struct input_dev *input)
+static int mtouchusb_open(struct input_dev *input)
 {
-        struct mtouch_usb *mtouch = input->private;
+	struct mtouch_usb *mtouch = input->private;
 
-        if (mtouch->open++)
-                return 0;
+	mtouch->irq->dev = mtouch->udev;
 
-        mtouch->irq->dev = mtouch->udev;
+	if (usb_submit_urb(mtouch->irq, GFP_ATOMIC))
+		return -EIO;
 
-        if (usb_submit_urb (mtouch->irq, GFP_ATOMIC)) {
-                mtouch->open--;
-                return -EIO;
-        }
-
-        return 0;
+	return 0;
 }
 
-static void mtouchusb_close (struct input_dev *input)
+static void mtouchusb_close(struct input_dev *input)
 {
-        struct mtouch_usb *mtouch = input->private;
+	struct mtouch_usb *mtouch = input->private;
 
-        if (!--mtouch->open)
-                usb_kill_urb (mtouch->irq);
+	usb_kill_urb(mtouch->irq);
 }
 
 static int mtouchusb_alloc_buffers(struct usb_device *udev, struct mtouch_usb *mtouch)
 {
-        dbg("%s - called", __FUNCTION__);
+	dbg("%s - called", __FUNCTION__);
 
-        mtouch->data = usb_buffer_alloc(udev, MTOUCHUSB_REPORT_DATA_SIZE,
-                                        SLAB_ATOMIC, &mtouch->data_dma);
+	mtouch->data = usb_buffer_alloc(udev, MTOUCHUSB_REPORT_DATA_SIZE,
+					SLAB_ATOMIC, &mtouch->data_dma);
 
-        if (!mtouch->data)
-                return -1;
+	if (!mtouch->data)
+		return -1;
 
-        return 0;
+	return 0;
 }
 
 static void mtouchusb_free_buffers(struct usb_device *udev, struct mtouch_usb *mtouch)
 {
-        dbg("%s - called", __FUNCTION__);
+	dbg("%s - called", __FUNCTION__);
 
-        if (mtouch->data)
-                usb_buffer_free(udev, MTOUCHUSB_REPORT_DATA_SIZE,
-                                mtouch->data, mtouch->data_dma);
+	if (mtouch->data)
+		usb_buffer_free(udev, MTOUCHUSB_REPORT_DATA_SIZE,
+				mtouch->data, mtouch->data_dma);
 }
 
 static int mtouchusb_probe(struct usb_interface *intf, const struct usb_device_id *id)
 {
-        struct mtouch_usb *mtouch;
-        struct usb_host_interface *interface;
-        struct usb_endpoint_descriptor *endpoint;
-        struct usb_device *udev = interface_to_usbdev (intf);
-        char path[64];
-        int nRet;
-
-        dbg("%s - called", __FUNCTION__);
-
-        dbg("%s - setting interface", __FUNCTION__);
-        interface = intf->cur_altsetting;
-
-        dbg("%s - setting endpoint", __FUNCTION__);
-        endpoint = &interface->endpoint[0].desc;
-
-        if (!(mtouch = kmalloc (sizeof (struct mtouch_usb), GFP_KERNEL))) {
-                err("%s - Out of memory.", __FUNCTION__);
-                return -ENOMEM;
-        }
-
-        memset(mtouch, 0, sizeof(struct mtouch_usb));
-        mtouch->udev = udev;
-
-        dbg("%s - allocating buffers", __FUNCTION__);
-        if (mtouchusb_alloc_buffers(udev, mtouch)) {
-                mtouchusb_free_buffers(udev, mtouch);
-                kfree(mtouch);
-                return -ENOMEM;
-        }
-
-        mtouch->input.private = mtouch;
-        mtouch->input.open = mtouchusb_open;
-        mtouch->input.close = mtouchusb_close;
-
-        usb_make_path(udev, path, 64);
-        sprintf(mtouch->phys, "%s/input0", path);
-
-        mtouch->input.name = mtouch->name;
-        mtouch->input.phys = mtouch->phys;
-        mtouch->input.id.bustype = BUS_USB;
-        mtouch->input.id.vendor = le16_to_cpu(udev->descriptor.idVendor);
-        mtouch->input.id.product = le16_to_cpu(udev->descriptor.idProduct);
-        mtouch->input.id.version = le16_to_cpu(udev->descriptor.bcdDevice);
-        mtouch->input.dev = &intf->dev;
-
-        mtouch->input.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
-        mtouch->input.absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
-        mtouch->input.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
-
-        /* Used to Scale Compensated Data and Flip Y */
-        mtouch->input.absmin[ABS_X] =  MTOUCHUSB_MIN_XC;
-        mtouch->input.absmax[ABS_X] =  raw_coordinates ? \
-                                       MTOUCHUSB_MAX_RAW_XC : MTOUCHUSB_MAX_CALIB_XC;
-        mtouch->input.absfuzz[ABS_X] = MTOUCHUSB_XC_FUZZ;
-        mtouch->input.absflat[ABS_X] = MTOUCHUSB_XC_FLAT;
-        mtouch->input.absmin[ABS_Y] =  MTOUCHUSB_MIN_YC;
-        mtouch->input.absmax[ABS_Y] =  raw_coordinates ? \
-                                       MTOUCHUSB_MAX_RAW_YC : MTOUCHUSB_MAX_CALIB_YC;
-        mtouch->input.absfuzz[ABS_Y] = MTOUCHUSB_YC_FUZZ;
-        mtouch->input.absflat[ABS_Y] = MTOUCHUSB_YC_FLAT;
+	struct mtouch_usb *mtouch;
+	struct usb_host_interface *interface;
+	struct usb_endpoint_descriptor *endpoint;
+	struct usb_device *udev = interface_to_usbdev(intf);
+	char path[64];
+	int nRet;
+
+	dbg("%s - called", __FUNCTION__);
+
+	dbg("%s - setting interface", __FUNCTION__);
+	interface = intf->cur_altsetting;
+
+	dbg("%s - setting endpoint", __FUNCTION__);
+	endpoint = &interface->endpoint[0].desc;
+
+	if (!(mtouch = kmalloc(sizeof(struct mtouch_usb), GFP_KERNEL))) {
+		err("%s - Out of memory.", __FUNCTION__);
+		return -ENOMEM;
+	}
+
+	memset(mtouch, 0, sizeof(struct mtouch_usb));
+	mtouch->udev = udev;
+
+	dbg("%s - allocating buffers", __FUNCTION__);
+	if (mtouchusb_alloc_buffers(udev, mtouch)) {
+		mtouchusb_free_buffers(udev, mtouch);
+		kfree(mtouch);
+		return -ENOMEM;
+	}
+
+	mtouch->input.private = mtouch;
+	mtouch->input.open = mtouchusb_open;
+	mtouch->input.close = mtouchusb_close;
+
+	usb_make_path(udev, path, 64);
+	sprintf(mtouch->phys, "%s/input0", path);
+
+	mtouch->input.name = mtouch->name;
+	mtouch->input.phys = mtouch->phys;
+	usb_to_input_id(udev, &mtouch->input.id);
+	mtouch->input.dev = &intf->dev;
+
+	mtouch->input.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+	mtouch->input.absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
+	mtouch->input.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+
+	/* Used to Scale Compensated Data and Flip Y */
+	mtouch->input.absmin[ABS_X] = MTOUCHUSB_MIN_XC;
+	mtouch->input.absmax[ABS_X] = raw_coordinates ?
+					MTOUCHUSB_MAX_RAW_XC : MTOUCHUSB_MAX_CALIB_XC;
+	mtouch->input.absfuzz[ABS_X] = MTOUCHUSB_XC_FUZZ;
+	mtouch->input.absflat[ABS_X] = MTOUCHUSB_XC_FLAT;
+	mtouch->input.absmin[ABS_Y] = MTOUCHUSB_MIN_YC;
+	mtouch->input.absmax[ABS_Y] = raw_coordinates ?
+					MTOUCHUSB_MAX_RAW_YC : MTOUCHUSB_MAX_CALIB_YC;
+	mtouch->input.absfuzz[ABS_Y] = MTOUCHUSB_YC_FUZZ;
+	mtouch->input.absflat[ABS_Y] = MTOUCHUSB_YC_FLAT;
 
 	if (udev->manufacturer)
 		strcat(mtouch->name, udev->manufacturer);
 	if (udev->product)
 		sprintf(mtouch->name, "%s %s", mtouch->name, udev->product);
 
-        if (!strlen(mtouch->name))
-                sprintf(mtouch->name, "USB Touchscreen %04x:%04x",
-                        mtouch->input.id.vendor, mtouch->input.id.product);
-
-        nRet = usb_control_msg(mtouch->udev,
-                               usb_rcvctrlpipe(udev, 0),
-                               MTOUCHUSB_RESET,
-                               USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
-                               1,
-                               0,
-                               NULL,
-                               0,
-                               USB_CTRL_SET_TIMEOUT);
-        dbg("%s - usb_control_msg - MTOUCHUSB_RESET - bytes|err: %d",
-            __FUNCTION__, nRet);
-
-        dbg("%s - usb_alloc_urb: mtouch->irq", __FUNCTION__);
-        mtouch->irq = usb_alloc_urb(0, GFP_KERNEL);
-        if (!mtouch->irq) {
-                dbg("%s - usb_alloc_urb failed: mtouch->irq", __FUNCTION__);
-                mtouchusb_free_buffers(udev, mtouch);
-                kfree(mtouch);
-                return -ENOMEM;
-        }
-
-        dbg("%s - usb_fill_int_urb", __FUNCTION__);
-        usb_fill_int_urb(mtouch->irq,
-                         mtouch->udev,
-                         usb_rcvintpipe(mtouch->udev, 0x81),
-                         mtouch->data,
-                         MTOUCHUSB_REPORT_DATA_SIZE,
-                         mtouchusb_irq,
-                         mtouch,
-                         endpoint->bInterval);
-
-        dbg("%s - input_register_device", __FUNCTION__);
-        input_register_device(&mtouch->input);
-
-        nRet = usb_control_msg(mtouch->udev,
-                               usb_rcvctrlpipe(udev, 0),
-                               MTOUCHUSB_ASYNC_REPORT,
-                               USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
-                               1,
-                               1,
-                               NULL,
-                               0,
-                               USB_CTRL_SET_TIMEOUT);
-        dbg("%s - usb_control_msg - MTOUCHUSB_ASYNC_REPORT - bytes|err: %d",
-            __FUNCTION__, nRet);
+	if (!strlen(mtouch->name))
+		sprintf(mtouch->name, "USB Touchscreen %04x:%04x",
+			mtouch->input.id.vendor, mtouch->input.id.product);
+
+	nRet = usb_control_msg(mtouch->udev, usb_rcvctrlpipe(udev, 0),
+			       MTOUCHUSB_RESET,
+			       USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+			       1, 0, NULL, 0, USB_CTRL_SET_TIMEOUT);
+	dbg("%s - usb_control_msg - MTOUCHUSB_RESET - bytes|err: %d",
+	    __FUNCTION__, nRet);
+
+	dbg("%s - usb_alloc_urb: mtouch->irq", __FUNCTION__);
+	mtouch->irq = usb_alloc_urb(0, GFP_KERNEL);
+	if (!mtouch->irq) {
+		dbg("%s - usb_alloc_urb failed: mtouch->irq", __FUNCTION__);
+		mtouchusb_free_buffers(udev, mtouch);
+		kfree(mtouch);
+		return -ENOMEM;
+	}
+
+	dbg("%s - usb_fill_int_urb", __FUNCTION__);
+	usb_fill_int_urb(mtouch->irq, mtouch->udev,
+			 usb_rcvintpipe(mtouch->udev, 0x81),
+			 mtouch->data, MTOUCHUSB_REPORT_DATA_SIZE,
+			 mtouchusb_irq, mtouch, endpoint->bInterval);
+
+	dbg("%s - input_register_device", __FUNCTION__);
+	input_register_device(&mtouch->input);
+
+	nRet = usb_control_msg(mtouch->udev, usb_rcvctrlpipe(udev, 0),
+			       MTOUCHUSB_ASYNC_REPORT,
+			       USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+			       1, 1, NULL, 0, USB_CTRL_SET_TIMEOUT);
+	dbg("%s - usb_control_msg - MTOUCHUSB_ASYNC_REPORT - bytes|err: %d",
+	    __FUNCTION__, nRet);
 
-        printk(KERN_INFO "input: %s on %s\n", mtouch->name, path);
-        usb_set_intfdata(intf, mtouch);
+	printk(KERN_INFO "input: %s on %s\n", mtouch->name, path);
+	usb_set_intfdata(intf, mtouch);
 
-        return 0;
+	return 0;
 }
 
 static void mtouchusb_disconnect(struct usb_interface *intf)
 {
-        struct mtouch_usb *mtouch = usb_get_intfdata (intf);
+	struct mtouch_usb *mtouch = usb_get_intfdata(intf);
 
-        dbg("%s - called", __FUNCTION__);
-        usb_set_intfdata(intf, NULL);
-        if (mtouch) {
-                dbg("%s - mtouch is initialized, cleaning up", __FUNCTION__);
-                usb_kill_urb(mtouch->irq);
-                input_unregister_device(&mtouch->input);
-                usb_free_urb(mtouch->irq);
-                mtouchusb_free_buffers(interface_to_usbdev(intf), mtouch);
-                kfree(mtouch);
-        }
+	dbg("%s - called", __FUNCTION__);
+	usb_set_intfdata(intf, NULL);
+	if (mtouch) {
+		dbg("%s - mtouch is initialized, cleaning up", __FUNCTION__);
+		usb_kill_urb(mtouch->irq);
+		input_unregister_device(&mtouch->input);
+		usb_free_urb(mtouch->irq);
+		mtouchusb_free_buffers(interface_to_usbdev(intf), mtouch);
+		kfree(mtouch);
+	}
 }
 
-MODULE_DEVICE_TABLE (usb, mtouchusb_devices);
+MODULE_DEVICE_TABLE(usb, mtouchusb_devices);
 
 static struct usb_driver mtouchusb_driver = {
-        .owner =      THIS_MODULE,
-        .name =       "mtouchusb",
-        .probe =      mtouchusb_probe,
-        .disconnect = mtouchusb_disconnect,
-        .id_table =   mtouchusb_devices,
+	.owner		= THIS_MODULE,
+	.name		= "mtouchusb",
+	.probe		= mtouchusb_probe,
+	.disconnect	= mtouchusb_disconnect,
+	.id_table	= mtouchusb_devices,
 };
 
-static int __init mtouchusb_init(void) {
-        dbg("%s - called", __FUNCTION__);
-        return usb_register(&mtouchusb_driver);
+static int __init mtouchusb_init(void)
+{
+	dbg("%s - called", __FUNCTION__);
+	return usb_register(&mtouchusb_driver);
 }
 
-static void __exit mtouchusb_cleanup(void) {
-        dbg("%s - called", __FUNCTION__);
-        usb_deregister(&mtouchusb_driver);
+static void __exit mtouchusb_cleanup(void)
+{
+	dbg("%s - called", __FUNCTION__);
+	usb_deregister(&mtouchusb_driver);
 }
 
 module_init(mtouchusb_init);
 module_exit(mtouchusb_cleanup);
 
-MODULE_AUTHOR( DRIVER_AUTHOR );
-MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
diff --git a/drivers/usb/input/powermate.c b/drivers/usb/input/powermate.c
--- a/drivers/usb/input/powermate.c
+++ b/drivers/usb/input/powermate.c
@@ -10,7 +10,7 @@
  * back to the host when polled by the USB controller.
  *
  * Testing with the knob I have has shown that it measures approximately 94 "clicks"
- * for one full rotation. Testing with my High Speed Rotation Actuator (ok, it was 
+ * for one full rotation. Testing with my High Speed Rotation Actuator (ok, it was
  * a variable speed cordless electric drill) has shown that the device can measure
  * speeds of up to 7 clicks either clockwise or anticlockwise between pollings from
  * the host. If it counts more than 7 clicks before it is polled, it will wrap back
@@ -35,6 +35,7 @@
 #include <linux/init.h>
 #include <linux/spinlock.h>
 #include <linux/usb.h>
+#include <linux/usb_input.h>
 
 #define POWERMATE_VENDOR	0x077d	/* Griffin Technology, Inc. */
 #define POWERMATE_PRODUCT_NEW	0x0410	/* Griffin PowerMate */
@@ -120,9 +121,9 @@ exit:
 /* Decide if we need to issue a control message and do so. Must be called with pm->lock taken */
 static void powermate_sync_state(struct powermate_device *pm)
 {
-	if (pm->requires_update == 0) 
+	if (pm->requires_update == 0)
 		return; /* no updates are required */
-	if (pm->config->status == -EINPROGRESS) 
+	if (pm->config->status == -EINPROGRESS)
 		return; /* an update is already in progress; it'll issue this update when it completes */
 
 	if (pm->requires_update & UPDATE_PULSE_ASLEEP){
@@ -142,7 +143,7 @@ static void powermate_sync_state(struct 
 		   2: multiply the speed
 		   the argument only has an effect for operations 0 and 2, and ranges between
 		   1 (least effect) to 255 (maximum effect).
-       
+
 		   thus, several states are equivalent and are coalesced into one state.
 
 		   we map this onto a range from 0 to 510, with:
@@ -151,7 +152,7 @@ static void powermate_sync_state(struct 
 		   256 -- 510  -- use multiple (510 = fastest).
 
 		   Only values of 'arg' quite close to 255 are particularly useful/spectacular.
-		*/    
+		*/
 		if (pm->pulse_speed < 255){
 			op = 0;                   // divide
 			arg = 255 - pm->pulse_speed;
@@ -199,14 +200,14 @@ static void powermate_config_complete(st
 
 	if (urb->status)
 		printk(KERN_ERR "powermate: config urb returned %d\n", urb->status);
-	
+
 	spin_lock_irqsave(&pm->lock, flags);
 	powermate_sync_state(pm);
 	spin_unlock_irqrestore(&pm->lock, flags);
 }
 
 /* Set the LED up as described and begin the sync with the hardware if required */
-static void powermate_pulse_led(struct powermate_device *pm, int static_brightness, int pulse_speed, 
+static void powermate_pulse_led(struct powermate_device *pm, int static_brightness, int pulse_speed,
 				int pulse_table, int pulse_asleep, int pulse_awake)
 {
 	unsigned long flags;
@@ -229,7 +230,7 @@ static void powermate_pulse_led(struct p
 	/* mark state updates which are required */
 	if (static_brightness != pm->static_brightness){
 		pm->static_brightness = static_brightness;
-		pm->requires_update |= UPDATE_STATIC_BRIGHTNESS;		
+		pm->requires_update |= UPDATE_STATIC_BRIGHTNESS;
 	}
 	if (pulse_asleep != pm->pulse_asleep){
 		pm->pulse_asleep = pulse_asleep;
@@ -246,7 +247,7 @@ static void powermate_pulse_led(struct p
 	}
 
 	powermate_sync_state(pm);
-   
+
 	spin_unlock_irqrestore(&pm->lock, flags);
 }
 
@@ -257,19 +258,19 @@ static int powermate_input_event(struct 
 	struct powermate_device *pm = dev->private;
 
 	if (type == EV_MSC && code == MSC_PULSELED){
-		/*  
+		/*
 		    bits  0- 7: 8 bits: LED brightness
 		    bits  8-16: 9 bits: pulsing speed modifier (0 ... 510); 0-254 = slower, 255 = standard, 256-510 = faster.
 		    bits 17-18: 2 bits: pulse table (0, 1, 2 valid)
 		    bit     19: 1 bit : pulse whilst asleep?
 		    bit     20: 1 bit : pulse constantly?
-		*/  
+		*/
 		int static_brightness = command & 0xFF;   // bits 0-7
 		int pulse_speed = (command >> 8) & 0x1FF; // bits 8-16
 		int pulse_table = (command >> 17) & 0x3;  // bits 17-18
 		int pulse_asleep = (command >> 19) & 0x1; // bit 19
 		int pulse_awake  = (command >> 20) & 0x1; // bit 20
-  
+
 		powermate_pulse_led(pm, static_brightness, pulse_speed, pulse_table, pulse_asleep, pulse_awake);
 	}
 
@@ -378,7 +379,7 @@ static int powermate_probe(struct usb_in
 	switch (le16_to_cpu(udev->descriptor.idProduct)) {
 	case POWERMATE_PRODUCT_NEW: pm->input.name = pm_name_powermate; break;
 	case POWERMATE_PRODUCT_OLD: pm->input.name = pm_name_soundknob; break;
-	default: 
+	default:
 		pm->input.name = pm_name_soundknob;
 		printk(KERN_WARNING "powermate: unknown product id %04x\n",
 		       le16_to_cpu(udev->descriptor.idProduct));
@@ -389,10 +390,7 @@ static int powermate_probe(struct usb_in
 	pm->input.keybit[LONG(BTN_0)] = BIT(BTN_0);
 	pm->input.relbit[LONG(REL_DIAL)] = BIT(REL_DIAL);
 	pm->input.mscbit[LONG(MSC_PULSELED)] = BIT(MSC_PULSELED);
-	pm->input.id.bustype = BUS_USB;
-	pm->input.id.vendor = le16_to_cpu(udev->descriptor.idVendor);
-	pm->input.id.product = le16_to_cpu(udev->descriptor.idProduct);
-	pm->input.id.version = le16_to_cpu(udev->descriptor.bcdDevice);
+	usb_to_input_id(udev, &pm->input.id);
 	pm->input.event = powermate_input_event;
 	pm->input.dev = &intf->dev;
 	pm->input.phys = pm->phys;
@@ -402,11 +400,11 @@ static int powermate_probe(struct usb_in
 	usb_make_path(udev, path, 64);
 	snprintf(pm->phys, 64, "%s/input0", path);
 	printk(KERN_INFO "input: %s on %s\n", pm->input.name, pm->input.phys);
-	
+
 	/* force an update of everything */
 	pm->requires_update = UPDATE_PULSE_ASLEEP | UPDATE_PULSE_AWAKE | UPDATE_PULSE_MODE | UPDATE_STATIC_BRIGHTNESS;
 	powermate_pulse_led(pm, 0x80, 255, 0, 1, 0); // set default pulse parameters
-  
+
 	usb_set_intfdata(intf, pm);
 	return 0;
 }
diff --git a/drivers/usb/input/touchkitusb.c b/drivers/usb/input/touchkitusb.c
--- a/drivers/usb/input/touchkitusb.c
+++ b/drivers/usb/input/touchkitusb.c
@@ -35,7 +35,7 @@
 #define DEBUG
 #endif
 #include <linux/usb.h>
-
+#include <linux/usb_input.h>
 
 #define TOUCHKIT_MIN_XC			0x0
 #define TOUCHKIT_MAX_XC			0x07ff
@@ -69,7 +69,6 @@ struct touchkit_usb {
 	struct urb *irq;
 	struct usb_device *udev;
 	struct input_dev input;
-	int open;
 	char name[128];
 	char phys[64];
 };
@@ -134,15 +133,10 @@ static int touchkit_open(struct input_de
 {
 	struct touchkit_usb *touchkit = input->private;
 
-	if (touchkit->open++)
-		return 0;
-
 	touchkit->irq->dev = touchkit->udev;
 
-	if (usb_submit_urb(touchkit->irq, GFP_ATOMIC)) {
-		touchkit->open--;
+	if (usb_submit_urb(touchkit->irq, GFP_ATOMIC))
 		return -EIO;
-	}
 
 	return 0;
 }
@@ -151,8 +145,7 @@ static void touchkit_close(struct input_
 {
 	struct touchkit_usb *touchkit = input->private;
 
-	if (!--touchkit->open)
-		usb_kill_urb(touchkit->irq);
+	usb_kill_urb(touchkit->irq);
 }
 
 static int touchkit_alloc_buffers(struct usb_device *udev,
@@ -209,10 +202,7 @@ static int touchkit_probe(struct usb_int
 
 	touchkit->input.name = touchkit->name;
 	touchkit->input.phys = touchkit->phys;
-	touchkit->input.id.bustype = BUS_USB;
-	touchkit->input.id.vendor = le16_to_cpu(udev->descriptor.idVendor);
-	touchkit->input.id.product = le16_to_cpu(udev->descriptor.idProduct);
-	touchkit->input.id.version = le16_to_cpu(udev->descriptor.bcdDevice);
+	usb_to_input_id(udev, &touchkit->input.id);
 	touchkit->input.dev = &intf->dev;
 
 	touchkit->input.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
diff --git a/drivers/usb/input/usbkbd.c b/drivers/usb/input/usbkbd.c
--- a/drivers/usb/input/usbkbd.c
+++ b/drivers/usb/input/usbkbd.c
@@ -9,18 +9,18 @@
 /*
  * 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 
+ * 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
- * 
+ *
  * Should you need to contact me, the author, you can do so either by
  * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
  * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
@@ -32,6 +32,7 @@
 #include <linux/input.h>
 #include <linux/init.h>
 #include <linux/usb.h>
+#include <linux/usb_input.h>
 
 /*
  * Version Information
@@ -72,7 +73,6 @@ struct usb_kbd {
 	unsigned char newleds;
 	char name[128];
 	char phys[64];
-	int open;
 
 	unsigned char *new;
 	struct usb_ctrlrequest *cr;
@@ -166,7 +166,7 @@ static void usb_kbd_led(struct urb *urb,
 
 	if (urb->status)
 		warn("led urb status %d received", urb->status);
-	
+
 	if (*(kbd->leds) == kbd->newleds)
 		return;
 
@@ -180,14 +180,9 @@ static int usb_kbd_open(struct input_dev
 {
 	struct usb_kbd *kbd = dev->private;
 
-	if (kbd->open++)
-		return 0;
-
 	kbd->irq->dev = kbd->usbdev;
-	if (usb_submit_urb(kbd->irq, GFP_KERNEL)) {
-		kbd->open--;
+	if (usb_submit_urb(kbd->irq, GFP_KERNEL))
 		return -EIO;
-	}
 
 	return 0;
 }
@@ -196,8 +191,7 @@ static void usb_kbd_close(struct input_d
 {
 	struct usb_kbd *kbd = dev->private;
 
-	if (!--kbd->open)
-		usb_kill_urb(kbd->irq);
+	usb_kill_urb(kbd->irq);
 }
 
 static int usb_kbd_alloc_mem(struct usb_device *dev, struct usb_kbd *kbd)
@@ -230,7 +224,7 @@ static void usb_kbd_free_mem(struct usb_
 		usb_buffer_free(dev, 1, kbd->leds, kbd->leds_dma);
 }
 
-static int usb_kbd_probe(struct usb_interface *iface, 
+static int usb_kbd_probe(struct usb_interface *iface,
 			 const struct usb_device_id *id)
 {
 	struct usb_device * dev = interface_to_usbdev(iface);
@@ -272,7 +266,7 @@ static int usb_kbd_probe(struct usb_inte
 	for (i = 0; i < 255; i++)
 		set_bit(usb_kbd_keycode[i], kbd->dev.keybit);
 	clear_bit(0, kbd->dev.keybit);
-	
+
 	kbd->dev.private = kbd;
 	kbd->dev.event = usb_kbd_event;
 	kbd->dev.open = usb_kbd_open;
@@ -294,11 +288,8 @@ static int usb_kbd_probe(struct usb_inte
 	sprintf(kbd->phys, "%s/input0", path);
 
 	kbd->dev.name = kbd->name;
-	kbd->dev.phys = kbd->phys;	
-	kbd->dev.id.bustype = BUS_USB;
-	kbd->dev.id.vendor = le16_to_cpu(dev->descriptor.idVendor);
-	kbd->dev.id.product = le16_to_cpu(dev->descriptor.idProduct);
-	kbd->dev.id.version = le16_to_cpu(dev->descriptor.bcdDevice);
+	kbd->dev.phys = kbd->phys;
+	usb_to_input_id(dev, &kbd->dev.id);
 	kbd->dev.dev = &iface->dev;
 
 	if (dev->manufacturer)
@@ -329,7 +320,7 @@ static int usb_kbd_probe(struct usb_inte
 static void usb_kbd_disconnect(struct usb_interface *intf)
 {
 	struct usb_kbd *kbd = usb_get_intfdata (intf);
-	
+
 	usb_set_intfdata(intf, NULL);
 	if (kbd) {
 		usb_kill_urb(kbd->irq);
diff --git a/drivers/usb/input/usbmouse.c b/drivers/usb/input/usbmouse.c
--- a/drivers/usb/input/usbmouse.c
+++ b/drivers/usb/input/usbmouse.c
@@ -9,18 +9,18 @@
 /*
  * 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 
+ * 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
- * 
+ *
  * Should you need to contact me, the author, you can do so either by
  * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
  * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
@@ -32,6 +32,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/usb.h>
+#include <linux/usb_input.h>
 
 /*
  * Version Information
@@ -51,7 +52,6 @@ struct usb_mouse {
 	struct usb_device *usbdev;
 	struct input_dev dev;
 	struct urb *irq;
-	int open;
 
 	signed char *data;
 	dma_addr_t data_dma;
@@ -101,14 +101,9 @@ static int usb_mouse_open(struct input_d
 {
 	struct usb_mouse *mouse = dev->private;
 
-	if (mouse->open++)
-		return 0;
-
 	mouse->irq->dev = mouse->usbdev;
-	if (usb_submit_urb(mouse->irq, GFP_KERNEL)) {
-		mouse->open--;
+	if (usb_submit_urb(mouse->irq, GFP_KERNEL))
 		return -EIO;
-	}
 
 	return 0;
 }
@@ -117,8 +112,7 @@ static void usb_mouse_close(struct input
 {
 	struct usb_mouse *mouse = dev->private;
 
-	if (!--mouse->open)
-		usb_kill_urb(mouse->irq);
+	usb_kill_urb(mouse->irq);
 }
 
 static int usb_mouse_probe(struct usb_interface * intf, const struct usb_device_id * id)
@@ -132,19 +126,19 @@ static int usb_mouse_probe(struct usb_in
 
 	interface = intf->cur_altsetting;
 
-	if (interface->desc.bNumEndpoints != 1) 
+	if (interface->desc.bNumEndpoints != 1)
 		return -ENODEV;
 
 	endpoint = &interface->endpoint[0].desc;
-	if (!(endpoint->bEndpointAddress & 0x80)) 
+	if (!(endpoint->bEndpointAddress & 0x80))
 		return -ENODEV;
-	if ((endpoint->bmAttributes & 3) != 3) 
+	if ((endpoint->bmAttributes & 3) != 3)
 		return -ENODEV;
 
 	pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
 	maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
 
-	if (!(mouse = kmalloc(sizeof(struct usb_mouse), GFP_KERNEL))) 
+	if (!(mouse = kmalloc(sizeof(struct usb_mouse), GFP_KERNEL)))
 		return -ENOMEM;
 	memset(mouse, 0, sizeof(struct usb_mouse));
 
@@ -178,10 +172,7 @@ static int usb_mouse_probe(struct usb_in
 
 	mouse->dev.name = mouse->name;
 	mouse->dev.phys = mouse->phys;
-	mouse->dev.id.bustype = BUS_USB;
-	mouse->dev.id.vendor = le16_to_cpu(dev->descriptor.idVendor);
-	mouse->dev.id.product = le16_to_cpu(dev->descriptor.idProduct);
-	mouse->dev.id.version = le16_to_cpu(dev->descriptor.bcdDevice);
+	usb_to_input_id(dev, &mouse->dev.id);
 	mouse->dev.dev = &intf->dev;
 
 	if (dev->manufacturer)
@@ -209,7 +200,7 @@ static int usb_mouse_probe(struct usb_in
 static void usb_mouse_disconnect(struct usb_interface *intf)
 {
 	struct usb_mouse *mouse = usb_get_intfdata (intf);
-	
+
 	usb_set_intfdata(intf, NULL);
 	if (mouse) {
 		usb_kill_urb(mouse->irq);
@@ -238,7 +229,7 @@ static struct usb_driver usb_mouse_drive
 static int __init usb_mouse_init(void)
 {
 	int retval = usb_register(&usb_mouse_driver);
-	if (retval == 0) 
+	if (retval == 0)
 		info(DRIVER_VERSION ":" DRIVER_DESC);
 	return retval;
 }
diff --git a/drivers/usb/input/wacom.c b/drivers/usb/input/wacom.c
--- a/drivers/usb/input/wacom.c
+++ b/drivers/usb/input/wacom.c
@@ -9,7 +9,7 @@
  *  Copyright (c) 2000 Daniel Egger		<egger@suse.de>
  *  Copyright (c) 2001 Frederic Lepied		<flepied@mandrakesoft.com>
  *  Copyright (c) 2004 Panagiotis Issaris	<panagiotis.issaris@mech.kuleuven.ac.be>
- *  Copyright (c) 2002-2004 Ping Cheng		<pingc@wacom.com>
+ *  Copyright (c) 2002-2005 Ping Cheng		<pingc@wacom.com>
  *
  *  ChangeLog:
  *      v0.1 (vp)  - Initial release
@@ -18,7 +18,7 @@
  *	v0.4 (sm)  - Support for more Intuos models, menustrip
  *			relative mode, proximity.
  *	v0.5 (vp)  - Big cleanup, nifty features removed,
- * 			they belong in userspace
+ *			they belong in userspace
  *	v1.8 (vp)  - Submit URB only when operating, moved to CVS,
  *			use input_report_key instead of report_btn and
  *			other cleanups
@@ -51,6 +51,9 @@
  *		   - Cleanups here and there
  *    v1.30.1 (pi) - Added Graphire3 support
  *	v1.40 (pc) - Add support for several new devices, fix eraser reporting, ...
+ *	v1.43 (pc) - Added support for Cintiq 21UX
+		   - Fixed a Graphire bug
+		   - Merged wacom_intuos3_irq into wacom_intuos_irq
  */
 
 /*
@@ -66,13 +69,14 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/usb.h>
+#include <linux/usb_input.h>
 #include <asm/unaligned.h>
 #include <asm/byteorder.h>
 
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v1.40"
+#define DRIVER_VERSION "v1.43"
 #define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>"
 #define DRIVER_DESC "USB Wacom Graphire and Wacom Intuos tablet driver"
 #define DRIVER_LICENSE "GPL"
@@ -83,6 +87,16 @@ MODULE_LICENSE(DRIVER_LICENSE);
 
 #define USB_VENDOR_ID_WACOM	0x056a
 
+enum {
+	PENPARTNER = 0,
+	GRAPHIRE,
+	PL,
+	INTUOS,
+	INTUOS3,
+	CINTIQ,
+	MAX_TYPE
+};
+
 struct wacom_features {
 	char *name;
 	int pktlen;
@@ -102,7 +116,6 @@ struct wacom {
 	struct urb *irq;
 	struct wacom_features *features;
 	int tool[2];
-	int open;
 	__u32 serial[2];
 	char phys[32];
 };
@@ -149,7 +162,7 @@ static void wacom_pl_irq(struct urb *urb
 	prox = data[1] & 0x40;
 
 	input_regs(dev, regs);
-	
+
 	if (prox) {
 
 		pressure = (signed char)((data[7] << 1) | ((data[4] >> 2) & 1));
@@ -166,8 +179,7 @@ static void wacom_pl_irq(struct urb *urb
 		if (!wacom->tool[0]) {
 			/* Going into proximity select tool */
 			wacom->tool[1] = (data[4] & 0x20)? BTN_TOOL_RUBBER : BTN_TOOL_PEN;
-		}
-		else {
+		} else {
 			/* was entered with stylus2 pressed */
 			if (wacom->tool[1] == BTN_TOOL_RUBBER && !(data[4] & 0x20) ) {
 				/* report out proximity for previous tool */
@@ -182,16 +194,15 @@ static void wacom_pl_irq(struct urb *urb
 			wacom->tool[1] = BTN_TOOL_PEN;
 		}
 		input_report_key(dev, wacom->tool[1], prox); /* report in proximity for tool */
-		input_report_abs(dev, ABS_X, data[3] | ((__u32)data[2] << 7) | ((__u32)(data[1] & 0x03) << 14));
-		input_report_abs(dev, ABS_Y, data[6] | ((__u32)data[5] << 7) | ((__u32)(data[4] & 0x03) << 14));
+		input_report_abs(dev, ABS_X, data[3] | (data[2] << 7) | ((data[1] & 0x03) << 14));
+		input_report_abs(dev, ABS_Y, data[6] | (data[5] << 7) | ((data[4] & 0x03) << 14));
 		input_report_abs(dev, ABS_PRESSURE, pressure);
 
 		input_report_key(dev, BTN_TOUCH, data[4] & 0x08);
 		input_report_key(dev, BTN_STYLUS, data[4] & 0x10);
 		/* Only allow the stylus2 button to be reported for the pen tool. */
 		input_report_key(dev, BTN_STYLUS2, (wacom->tool[1] == BTN_TOOL_PEN) && (data[4] & 0x20));
-	}
-	else {
+	} else {
 		/* report proximity-out of a (valid) tool */
 		if (wacom->tool[1] != BTN_TOOL_RUBBER) {
 			/* Unknown tool selected default to pen tool */
@@ -203,7 +214,7 @@ static void wacom_pl_irq(struct urb *urb
 	wacom->tool[0] = prox; /* Save proximity state */
 	input_sync(dev);
 
-exit:
+ exit:
 	retval = usb_submit_urb (urb, GFP_ATOMIC);
 	if (retval)
 		err ("%s - usb_submit_urb failed with result %d",
@@ -232,20 +243,16 @@ static void wacom_ptu_irq(struct urb *ur
 		goto exit;
 	}
 
-	if (data[0] != 2)
-	{
+	if (data[0] != 2) {
 		printk(KERN_INFO "wacom_ptu_irq: received unknown report #%d\n", data[0]);
 		goto exit;
 	}
 
 	input_regs(dev, regs);
-	if (data[1] & 0x04)
-	{
+	if (data[1] & 0x04) {
 		input_report_key(dev, BTN_TOOL_RUBBER, data[1] & 0x20);
 		input_report_key(dev, BTN_TOUCH, data[1] & 0x08);
-	}
-	else
-	{
+	} else {
 		input_report_key(dev, BTN_TOOL_PEN, data[1] & 0x20);
 		input_report_key(dev, BTN_TOUCH, data[1] & 0x01);
 	}
@@ -257,7 +264,7 @@ static void wacom_ptu_irq(struct urb *ur
 
 	input_sync(dev);
 
-exit:
+ exit:
 	retval = usb_submit_urb (urb, GFP_ATOMIC);
 	if (retval)
 		err ("%s - usb_submit_urb failed with result %d",
@@ -300,7 +307,7 @@ static void wacom_penpartner_irq(struct 
 	input_report_key(dev, BTN_STYLUS, (data[5] & 0x40));
 	input_sync(dev);
 
-exit:
+ exit:
 	retval = usb_submit_urb (urb, GFP_ATOMIC);
 	if (retval)
 		err ("%s - usb_submit_urb failed with result %d",
@@ -335,52 +342,51 @@ static void wacom_graphire_irq(struct ur
 		goto exit;
 	}
 
-	x = le16_to_cpu(*(__le16 *) &data[2]);
-	y = le16_to_cpu(*(__le16 *) &data[4]);
-
 	input_regs(dev, regs);
 
-	switch ((data[1] >> 5) & 3) {
+	if (data[1] & 0x10) { /* in prox */
 
-		case 0:	/* Pen */
-			input_report_key(dev, BTN_TOOL_PEN, data[1] & 0x80);
-			break;
+		switch ((data[1] >> 5) & 3) {
 
-		case 1: /* Rubber */
-			input_report_key(dev, BTN_TOOL_RUBBER, data[1] & 0x80);
-			break;
-
-		case 2: /* Mouse with wheel */
-			input_report_key(dev, BTN_MIDDLE, data[1] & 0x04);
-			input_report_rel(dev, REL_WHEEL, (signed char) data[6]);
-			/* fall through */
-
-                case 3: /* Mouse without wheel */
-			input_report_key(dev, BTN_TOOL_MOUSE, data[7] > 24);
-			input_report_key(dev, BTN_LEFT, data[1] & 0x01);
-			input_report_key(dev, BTN_RIGHT, data[1] & 0x02);
-			input_report_abs(dev, ABS_DISTANCE, data[7]);
+			case 0:	/* Pen */
+				wacom->tool[0] = BTN_TOOL_PEN;
+				break;
 
-			input_report_abs(dev, ABS_X, x);
-			input_report_abs(dev, ABS_Y, y);
+			case 1: /* Rubber */
+				wacom->tool[0] = BTN_TOOL_RUBBER;
+				break;
 
-			input_sync(dev);
-			goto exit;
+			case 2: /* Mouse with wheel */
+				input_report_key(dev, BTN_MIDDLE, data[1] & 0x04);
+				input_report_rel(dev, REL_WHEEL, (signed char) data[6]);
+				/* fall through */
+
+			case 3: /* Mouse without wheel */
+				wacom->tool[0] = BTN_TOOL_MOUSE;
+				input_report_key(dev, BTN_LEFT, data[1] & 0x01);
+				input_report_key(dev, BTN_RIGHT, data[1] & 0x02);
+				input_report_abs(dev, ABS_DISTANCE, data[7]);
+				break;
+		}
 	}
 
-	if (data[1] & 0x80) {
+	if (data[1] & 0x90) {
+		x = le16_to_cpu(*(__le16 *) &data[2]);
+		y = le16_to_cpu(*(__le16 *) &data[4]);
 		input_report_abs(dev, ABS_X, x);
 		input_report_abs(dev, ABS_Y, y);
+		if (wacom->tool[0] != BTN_TOOL_MOUSE) {
+			input_report_abs(dev, ABS_PRESSURE, le16_to_cpu(*(__le16 *) &data[6]));
+			input_report_key(dev, BTN_TOUCH, data[1] & 0x01);
+			input_report_key(dev, BTN_STYLUS, data[1] & 0x02);
+			input_report_key(dev, BTN_STYLUS2, data[1] & 0x04);
+		}
 	}
 
-	input_report_abs(dev, ABS_PRESSURE, le16_to_cpu(*(__le16 *) &data[6]));
-	input_report_key(dev, BTN_TOUCH, data[1] & 0x01);
-	input_report_key(dev, BTN_STYLUS, data[1] & 0x02);
-	input_report_key(dev, BTN_STYLUS2, data[1] & 0x04);
-
+	input_report_key(dev, wacom->tool[0], data[1] & 0x10);
 	input_sync(dev);
 
-exit:
+ exit:
 	retval = usb_submit_urb (urb, GFP_ATOMIC);
 	if (retval)
 		err ("%s - usb_submit_urb failed with result %d",
@@ -398,14 +404,13 @@ static int wacom_intuos_inout(struct urb
 	idx = data[1] & 0x01;
 
 	/* Enter report */
-	if ((data[1] & 0xfc) == 0xc0)
-	{
+	if ((data[1] & 0xfc) == 0xc0) {
 		/* serial number of the tool */
-		wacom->serial[idx] = ((__u32)(data[3] & 0x0f) << 28) +
-			((__u32)data[4] << 20) + ((__u32)data[5] << 12) +
-			((__u32)data[6] << 4) + (data[7] >> 4);
+		wacom->serial[idx] = ((data[3] & 0x0f) << 28) +
+			(data[4] << 20) + (data[5] << 12) +
+			(data[6] << 4) + (data[7] >> 4);
 
-		switch (((__u32)data[2] << 4) | (data[3] >> 4)) {
+		switch ((data[2] << 4) | (data[3] >> 4)) {
 			case 0x812: /* Inking pen */
 			case 0x801: /* Intuos3 Inking pen */
 			case 0x012:
@@ -449,7 +454,7 @@ static int wacom_intuos_inout(struct urb
 			case 0x112:
 			case 0x913: /* Intuos3 Airbrush */
 				wacom->tool[idx] = BTN_TOOL_AIRBRUSH;
-				break;	/* Airbrush */
+				break;
 			default: /* Unknown tool */
 				wacom->tool[idx] = BTN_TOOL_PEN;
 		}
@@ -478,9 +483,8 @@ static void wacom_intuos_general(struct 
 	unsigned int t;
 
 	/* general pen packet */
-	if ((data[1] & 0xb8) == 0xa0)
-	{
-		t = ((__u32)data[6] << 2) | ((data[7] >> 6) & 3);
+	if ((data[1] & 0xb8) == 0xa0) {
+		t = (data[6] << 2) | ((data[7] >> 6) & 3);
 		input_report_abs(dev, ABS_PRESSURE, t);
 		input_report_abs(dev, ABS_TILT_X,
 				((data[7] << 1) & 0x7e) | (data[8] >> 7));
@@ -491,10 +495,9 @@ static void wacom_intuos_general(struct 
 	}
 
 	/* airbrush second packet */
-	if ((data[1] & 0xbc) == 0xb4)
-	{
+	if ((data[1] & 0xbc) == 0xb4) {
 		input_report_abs(dev, ABS_WHEEL,
-				((__u32)data[6] << 2) | ((data[7] >> 6) & 3));
+				(data[6] << 2) | ((data[7] >> 6) & 3));
 		input_report_abs(dev, ABS_TILT_X,
 				((data[7] << 1) & 0x7e) | (data[8] >> 7));
 		input_report_abs(dev, ABS_TILT_Y, data[8] & 0x7f);
@@ -526,7 +529,7 @@ static void wacom_intuos_irq(struct urb 
 		goto exit;
 	}
 
-	if (data[0] != 2 && data[0] != 5 && data[0] != 6) {
+	if (data[0] != 2 && data[0] != 5 && data[0] != 6 && data[0] != 12) {
 		dbg("wacom_intuos_irq: received unknown report #%d", data[0]);
 		goto exit;
 	}
@@ -536,107 +539,10 @@ static void wacom_intuos_irq(struct urb 
 	/* tool number */
 	idx = data[1] & 0x01;
 
-	/* process in/out prox events */
-	if (wacom_intuos_inout(urb)) goto exit;
-
-	input_report_abs(dev, ABS_X, be16_to_cpu(*(__be16 *) &data[2]));
-	input_report_abs(dev, ABS_Y, be16_to_cpu(*(__be16 *) &data[4]));
-	input_report_abs(dev, ABS_DISTANCE, data[9]);
-
-	/* process general packets */
-	wacom_intuos_general(urb);
-	
-	if ((data[1] & 0xbc) == 0xa8 || (data[1] & 0xbe) == 0xb0) {		/* 4D mouse or Lens cursor packets */
-
-		if (data[1] & 0x02) {						/* Rotation packet */
-
-			t = ((__u32)data[6] << 3) | ((data[7] >> 5) & 7);
-			input_report_abs(dev, ABS_RZ, (data[7] & 0x20) ? ((t - 1) / 2) : -t / 2);
-
-		} else {
-
-	 		if ((data[1] & 0x10) == 0) {				/* 4D mouse packets */
-
-				input_report_key(dev, BTN_LEFT,   data[8] & 0x01);
-				input_report_key(dev, BTN_MIDDLE, data[8] & 0x02);
-				input_report_key(dev, BTN_RIGHT,  data[8] & 0x04);
-
-				input_report_key(dev, BTN_SIDE,   data[8] & 0x20);
-				input_report_key(dev, BTN_EXTRA,  data[8] & 0x10);
-				t = ((__u32)data[6] << 2) | ((data[7] >> 6) & 3);
-				input_report_abs(dev, ABS_THROTTLE, (data[8] & 0x08) ? -t : t);
-
-			} else {
-				if (wacom->tool[idx] == BTN_TOOL_MOUSE) {	/* 2D mouse packets */	
-					input_report_key(dev, BTN_LEFT,   data[8] & 0x04);
-					input_report_key(dev, BTN_MIDDLE, data[8] & 0x08);
-					input_report_key(dev, BTN_RIGHT,  data[8] & 0x10);
-					input_report_rel(dev, REL_WHEEL, 
-					    (-(__u32)(data[8] & 0x01) + (__u32)((data[8] & 0x02) >> 1)));
-				}
-				else {     /* Lens cursor packets */
-					input_report_key(dev, BTN_LEFT,   data[8] & 0x01);
-					input_report_key(dev, BTN_MIDDLE, data[8] & 0x02);
-					input_report_key(dev, BTN_RIGHT,  data[8] & 0x04);
-					input_report_key(dev, BTN_SIDE,   data[8] & 0x10);
-					input_report_key(dev, BTN_EXTRA,  data[8] & 0x08);
-				}
-			}
-		}
-	}
-	
-	input_report_key(dev, wacom->tool[idx], 1);
-	input_event(dev, EV_MSC, MSC_SERIAL, wacom->serial[idx]);
-	input_sync(dev);
-
-exit:
-	retval = usb_submit_urb (urb, GFP_ATOMIC);
-	if (retval)
-		err ("%s - usb_submit_urb failed with result %d",
-		     __FUNCTION__, retval);
-}
-
-static void wacom_intuos3_irq(struct urb *urb, struct pt_regs *regs)
-{
-	struct wacom *wacom = urb->context;
-	unsigned char *data = wacom->data;
-	struct input_dev *dev = &wacom->dev;
-	unsigned int t;
-	int idx, retval;
-
-	switch (urb->status) {
-	case 0:
-		/* success */
-		break;
-	case -ECONNRESET:
-	case -ENOENT:
-	case -ESHUTDOWN:
-		/* this urb is terminated, clean up */
-		dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status);
-		return;
-	default:
-		dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status);
-		goto exit;
-	}
-
-	/* check for valid report */
-	if (data[0] != 2 && data[0] != 5 && data[0] != 12)
-	{
-		printk(KERN_INFO "wacom_intuos3_irq: received unknown report #%d\n", data[0]);
-		goto exit;
-	}
-
-	input_regs(dev, regs);
-
-	/* tool index is always 0 here since there is no dual input tool */
-	idx = data[1] & 0x01;
-
 	/* pad packets. Works as a second tool and is always in prox */
-	if (data[0] == 12)
-	{
+	if (data[0] == 12) {
 		/* initiate the pad as a device */
-		if (wacom->tool[1] != BTN_TOOL_FINGER)
-		{
+		if (wacom->tool[1] != BTN_TOOL_FINGER) {
 			wacom->tool[1] = BTN_TOOL_FINGER;
 			input_report_key(dev, wacom->tool[1], 1);
 		}
@@ -656,37 +562,78 @@ static void wacom_intuos3_irq(struct urb
 	}
 
 	/* process in/out prox events */
-	if (wacom_intuos_inout(urb)) goto exit;
+	if (wacom_intuos_inout(urb))
+		goto exit;
 
-	input_report_abs(dev, ABS_X, ((__u32)data[2] << 9) | ((__u32)data[3] << 1) | ((data[9] >> 1) & 1));
-	input_report_abs(dev, ABS_Y, ((__u32)data[4] << 9) | ((__u32)data[5] << 1) | (data[9] & 1));
-	input_report_abs(dev, ABS_DISTANCE, ((data[9] >> 2) & 0x3f));
+	/* Cintiq doesn't send data when RDY bit isn't set */
+	if ((wacom->features->type == CINTIQ) && !(data[1] & 0x40))
+		goto exit;
+
+	if (wacom->features->type >= INTUOS3) {
+		input_report_abs(dev, ABS_X, (data[2] << 9) | (data[3] << 1) | ((data[9] >> 1) & 1));
+		input_report_abs(dev, ABS_Y, (data[4] << 9) | (data[5] << 1) | (data[9] & 1));
+		input_report_abs(dev, ABS_DISTANCE, ((data[9] >> 2) & 0x3f));
+	} else {
+		input_report_abs(dev, ABS_X, be16_to_cpu(*(__be16 *) &data[2]));
+		input_report_abs(dev, ABS_Y, be16_to_cpu(*(__be16 *) &data[4]));
+		input_report_abs(dev, ABS_DISTANCE, ((data[9] >> 3) & 0x1f));
+	}
 
 	/* process general packets */
 	wacom_intuos_general(urb);
 
-	if ((data[1] & 0xbc) == 0xa8 || (data[1] & 0xbe) == 0xb0)
-	{
-		/* Marker pen rotation packet. Reported as wheel due to valuator limitation */
-		if (data[1] & 0x02)
-		{
-			t = ((__u32)data[6] << 3) | ((data[7] >> 5) & 7);
-			t = (data[7] & 0x20) ? ((t > 900) ? ((t-1) / 2 - 1350) :
-				((t-1) / 2 + 450)) : (450 - t / 2) ;
-			input_report_abs(dev, ABS_WHEEL, t);
-		}
+	/* 4D mouse, 2D mouse, marker pen rotation, or Lens cursor packets */
+	if ((data[1] & 0xbc) == 0xa8 || (data[1] & 0xbe) == 0xb0) {
+
+		if (data[1] & 0x02) {
+			/* Rotation packet */
+			if (wacom->features->type >= INTUOS3) {
+				/* I3 marker pen rotation reported as wheel
+				 * due to valuator limitation
+				 */
+				t = (data[6] << 3) | ((data[7] >> 5) & 7);
+				t = (data[7] & 0x20) ? ((t > 900) ? ((t-1) / 2 - 1350) :
+					((t-1) / 2 + 450)) : (450 - t / 2) ;
+				input_report_abs(dev, ABS_WHEEL, t);
+			} else {
+				/* 4D mouse rotation packet */
+				t = (data[6] << 3) | ((data[7] >> 5) & 7);
+				input_report_abs(dev, ABS_RZ, (data[7] & 0x20) ?
+					((t - 1) / 2) : -t / 2);
+			}
+
+		} else if (!(data[1] & 0x10) && wacom->features->type < INTUOS3) {
+			/* 4D mouse packet */
+			input_report_key(dev, BTN_LEFT,   data[8] & 0x01);
+			input_report_key(dev, BTN_MIDDLE, data[8] & 0x02);
+			input_report_key(dev, BTN_RIGHT,  data[8] & 0x04);
+
+			input_report_key(dev, BTN_SIDE,   data[8] & 0x20);
+			input_report_key(dev, BTN_EXTRA,  data[8] & 0x10);
+			t = (data[6] << 2) | ((data[7] >> 6) & 3);
+			input_report_abs(dev, ABS_THROTTLE, (data[8] & 0x08) ? -t : t);
 
-		/* 2D mouse packets */
-		if (wacom->tool[idx] == BTN_TOOL_MOUSE)
-		{
+		} else if (wacom->tool[idx] == BTN_TOOL_MOUSE) {
+			/* 2D mouse packet */
 			input_report_key(dev, BTN_LEFT,   data[8] & 0x04);
 			input_report_key(dev, BTN_MIDDLE, data[8] & 0x08);
 			input_report_key(dev, BTN_RIGHT,  data[8] & 0x10);
-			input_report_key(dev, BTN_SIDE,   data[8] & 0x40);
-			input_report_key(dev, BTN_EXTRA,  data[8] & 0x20);
-			/* mouse wheel is positive when rolled backwards */
-			input_report_rel(dev, REL_WHEEL,  ((__u32)((data[8] & 0x02) >> 1)
-					 - (__u32)(data[8] & 0x01)));
+			input_report_rel(dev, REL_WHEEL, ((data[8] & 0x02) >> 1)
+						 - (data[8] & 0x01));
+
+			/* I3 2D mouse side buttons */
+			if (wacom->features->type == INTUOS3) {
+				input_report_key(dev, BTN_SIDE,   data[8] & 0x40);
+				input_report_key(dev, BTN_EXTRA,  data[8] & 0x20);
+			}
+
+		} else if (wacom->features->type < INTUOS3) {
+			/* Lens cursor packets */
+			input_report_key(dev, BTN_LEFT,   data[8] & 0x01);
+			input_report_key(dev, BTN_MIDDLE, data[8] & 0x02);
+			input_report_key(dev, BTN_RIGHT,  data[8] & 0x04);
+			input_report_key(dev, BTN_SIDE,   data[8] & 0x10);
+			input_report_key(dev, BTN_EXTRA,  data[8] & 0x08);
 		}
 	}
 
@@ -702,35 +649,36 @@ exit:
 }
 
 static struct wacom_features wacom_features[] = {
-	{ "Wacom Penpartner",    7,   5040,  3780,  255, 32, 0, wacom_penpartner_irq },
-        { "Wacom Graphire",      8,  10206,  7422,  511, 32, 1, wacom_graphire_irq },
-	{ "Wacom Graphire2 4x5", 8,  10206,  7422,  511, 32, 1, wacom_graphire_irq },
- 	{ "Wacom Graphire2 5x7", 8,  13918, 10206,  511, 32, 1, wacom_graphire_irq },
-	{ "Wacom Graphire3",     8,  10208,  7424,  511, 32, 1, wacom_graphire_irq },
-	{ "Wacom Graphire3 6x8", 8,  16704, 12064,  511, 32, 1, wacom_graphire_irq },
-  	{ "Wacom Intuos 4x5",   10,  12700, 10600, 1023, 15, 2, wacom_intuos_irq },
- 	{ "Wacom Intuos 6x8",   10,  20320, 16240, 1023, 15, 2, wacom_intuos_irq },
- 	{ "Wacom Intuos 9x12",  10,  30480, 24060, 1023, 15, 2, wacom_intuos_irq },
- 	{ "Wacom Intuos 12x12", 10,  30480, 31680, 1023, 15, 2, wacom_intuos_irq },
- 	{ "Wacom Intuos 12x18", 10,  45720, 31680, 1023, 15, 2, wacom_intuos_irq },
- 	{ "Wacom PL400",         8,   5408,  4056,  255, 32, 3, wacom_pl_irq },
- 	{ "Wacom PL500",         8,   6144,  4608,  255, 32, 3, wacom_pl_irq },
- 	{ "Wacom PL600",         8,   6126,  4604,  255, 32, 3, wacom_pl_irq },
- 	{ "Wacom PL600SX",       8,   6260,  5016,  255, 32, 3, wacom_pl_irq },
- 	{ "Wacom PL550",         8,   6144,  4608,  511, 32, 3, wacom_pl_irq },
- 	{ "Wacom PL800",         8,   7220,  5780,  511, 32, 3, wacom_pl_irq },
-	{ "Wacom Intuos2 4x5",   10, 12700, 10600, 1023, 15, 2, wacom_intuos_irq },
-	{ "Wacom Intuos2 6x8",   10, 20320, 16240, 1023, 15, 2, wacom_intuos_irq },
-	{ "Wacom Intuos2 9x12",  10, 30480, 24060, 1023, 15, 2, wacom_intuos_irq },
-	{ "Wacom Intuos2 12x12", 10, 30480, 31680, 1023, 15, 2, wacom_intuos_irq },
-	{ "Wacom Intuos2 12x18", 10, 45720, 31680, 1023, 15, 2, wacom_intuos_irq },
-	{ "Wacom Volito",        8,   5104,  3712,  511, 32, 1, wacom_graphire_irq },
-	{ "Wacom Cintiq Partner",8,  20480, 15360,  511, 32, 3, wacom_ptu_irq },
-	{ "Wacom Intuos3 4x5",   10, 25400, 20320, 1023, 15, 4, wacom_intuos3_irq },
-	{ "Wacom Intuos3 6x8",   10, 40640, 30480, 1023, 15, 4, wacom_intuos3_irq },
-	{ "Wacom Intuos3 9x12",  10, 60960, 45720, 1023, 15, 4, wacom_intuos3_irq },
-	{ "Wacom Intuos2 6x8",   10, 20320, 16240, 1023, 15, 2, wacom_intuos_irq },
- 	{ }
+	{ "Wacom Penpartner",    7,   5040,  3780,  255, 32, PENPARTNER, wacom_penpartner_irq },
+        { "Wacom Graphire",      8,  10206,  7422,  511, 32, GRAPHIRE,   wacom_graphire_irq },
+	{ "Wacom Graphire2 4x5", 8,  10206,  7422,  511, 32, GRAPHIRE,   wacom_graphire_irq },
+	{ "Wacom Graphire2 5x7", 8,  13918, 10206,  511, 32, GRAPHIRE,   wacom_graphire_irq },
+	{ "Wacom Graphire3",     8,  10208,  7424,  511, 32, GRAPHIRE,   wacom_graphire_irq },
+	{ "Wacom Graphire3 6x8", 8,  16704, 12064,  511, 32, GRAPHIRE,   wacom_graphire_irq },
+	{ "Wacom Intuos 4x5",   10,  12700, 10600, 1023, 15, INTUOS,     wacom_intuos_irq },
+	{ "Wacom Intuos 6x8",   10,  20320, 16240, 1023, 15, INTUOS,     wacom_intuos_irq },
+	{ "Wacom Intuos 9x12",  10,  30480, 24060, 1023, 15, INTUOS,     wacom_intuos_irq },
+	{ "Wacom Intuos 12x12", 10,  30480, 31680, 1023, 15, INTUOS,     wacom_intuos_irq },
+	{ "Wacom Intuos 12x18", 10,  45720, 31680, 1023, 15, INTUOS,     wacom_intuos_irq },
+	{ "Wacom PL400",         8,   5408,  4056,  255, 32, PL,         wacom_pl_irq },
+	{ "Wacom PL500",         8,   6144,  4608,  255, 32, PL,         wacom_pl_irq },
+	{ "Wacom PL600",         8,   6126,  4604,  255, 32, PL,         wacom_pl_irq },
+	{ "Wacom PL600SX",       8,   6260,  5016,  255, 32, PL,         wacom_pl_irq },
+	{ "Wacom PL550",         8,   6144,  4608,  511, 32, PL,         wacom_pl_irq },
+	{ "Wacom PL800",         8,   7220,  5780,  511, 32, PL,         wacom_pl_irq },
+	{ "Wacom Intuos2 4x5",   10, 12700, 10600, 1023, 15, INTUOS,     wacom_intuos_irq },
+	{ "Wacom Intuos2 6x8",   10, 20320, 16240, 1023, 15, INTUOS,     wacom_intuos_irq },
+	{ "Wacom Intuos2 9x12",  10, 30480, 24060, 1023, 15, INTUOS,     wacom_intuos_irq },
+	{ "Wacom Intuos2 12x12", 10, 30480, 31680, 1023, 15, INTUOS,     wacom_intuos_irq },
+	{ "Wacom Intuos2 12x18", 10, 45720, 31680, 1023, 15, INTUOS,     wacom_intuos_irq },
+	{ "Wacom Volito",        8,   5104,  3712,  511, 32, GRAPHIRE,   wacom_graphire_irq },
+	{ "Wacom Cintiq Partner",8,  20480, 15360,  511, 32, PL,         wacom_ptu_irq },
+	{ "Wacom Intuos3 4x5",   10, 25400, 20320, 1023, 15, INTUOS3,    wacom_intuos_irq },
+	{ "Wacom Intuos3 6x8",   10, 40640, 30480, 1023, 15, INTUOS3,    wacom_intuos_irq },
+	{ "Wacom Intuos3 9x12",  10, 60960, 45720, 1023, 15, INTUOS3,    wacom_intuos_irq },
+	{ "Wacom Cintiq 21UX",   10, 87200, 65600, 1023, 15, CINTIQ,     wacom_intuos_irq },
+	{ "Wacom Intuos2 6x8",   10, 20320, 16240, 1023, 15, INTUOS,     wacom_intuos_irq },
+	{ }
 };
 
 static struct usb_device_id wacom_ids[] = {
@@ -761,6 +709,7 @@ static struct usb_device_id wacom_ids[] 
 	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB0) },
 	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB1) },
 	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB2) },
+	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x3F) },
 	{ USB_DEVICE(USB_VENDOR_ID_WACOM, 0x47) },
 	{ }
 };
@@ -771,14 +720,9 @@ static int wacom_open(struct input_dev *
 {
 	struct wacom *wacom = dev->private;
 
-	if (wacom->open++)
-		return 0;
-
 	wacom->irq->dev = wacom->usbdev;
-	if (usb_submit_urb(wacom->irq, GFP_KERNEL)) {
-		wacom->open--;
+	if (usb_submit_urb(wacom->irq, GFP_KERNEL))
 		return -EIO;
-	}
 
 	return 0;
 }
@@ -787,8 +731,7 @@ static void wacom_close(struct input_dev
 {
 	struct wacom *wacom = dev->private;
 
-	if (!--wacom->open)
-		usb_kill_urb(wacom->irq);
+	usb_kill_urb(wacom->irq);
 }
 
 static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id)
@@ -823,32 +766,33 @@ static int wacom_probe(struct usb_interf
 	wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_PEN) | BIT(BTN_TOUCH) | BIT(BTN_STYLUS);
 
 	switch (wacom->features->type) {
-		case 1:
+		case GRAPHIRE:
 			wacom->dev.evbit[0] |= BIT(EV_REL);
 			wacom->dev.relbit[0] |= BIT(REL_WHEEL);
 			wacom->dev.absbit[0] |= BIT(ABS_DISTANCE);
 			wacom->dev.keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
- 			wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE) | BIT(BTN_STYLUS2);
+			wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE) | BIT(BTN_STYLUS2);
 			break;
 
-		case 4: /* new functions for Intuos3 */
+		case INTUOS3:
+		case CINTIQ:
 			wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER);
 			wacom->dev.keybit[LONG(BTN_LEFT)] |= BIT(BTN_0) | BIT(BTN_1) | BIT(BTN_2) | BIT(BTN_3) | BIT(BTN_4) | BIT(BTN_5) | BIT(BTN_6) | BIT(BTN_7);
 			wacom->dev.absbit[0] |= BIT(ABS_RX) | BIT(ABS_RY);
 			/* fall through */
 
-		case 2:
+		case INTUOS:
 			wacom->dev.evbit[0] |= BIT(EV_MSC) | BIT(EV_REL);
 			wacom->dev.mscbit[0] |= BIT(MSC_SERIAL);
 			wacom->dev.relbit[0] |= BIT(REL_WHEEL);
 			wacom->dev.keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE) | BIT(BTN_SIDE) | BIT(BTN_EXTRA);
- 			wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE)	| BIT(BTN_TOOL_BRUSH)
+			wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE)	| BIT(BTN_TOOL_BRUSH)
 							  | BIT(BTN_TOOL_PENCIL) | BIT(BTN_TOOL_AIRBRUSH) | BIT(BTN_TOOL_LENS) | BIT(BTN_STYLUS2);
 			wacom->dev.absbit[0] |= BIT(ABS_DISTANCE) | BIT(ABS_WHEEL) | BIT(ABS_TILT_X) | BIT(ABS_TILT_Y) | BIT(ABS_RZ) | BIT(ABS_THROTTLE);
 			break;
 
-		case 3:
- 			wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_STYLUS2) | BIT(BTN_TOOL_RUBBER);
+		case PL:
+			wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_STYLUS2) | BIT(BTN_TOOL_RUBBER);
 			break;
 	}
 
@@ -879,10 +823,7 @@ static int wacom_probe(struct usb_interf
 
 	wacom->dev.name = wacom->features->name;
 	wacom->dev.phys = wacom->phys;
-	wacom->dev.id.bustype = BUS_USB;
-	wacom->dev.id.vendor = le16_to_cpu(dev->descriptor.idVendor);
-	wacom->dev.id.product = le16_to_cpu(dev->descriptor.idProduct);
-	wacom->dev.id.version = le16_to_cpu(dev->descriptor.bcdDevice);
+	usb_to_input_id(dev, &wacom->dev.id);
 	wacom->dev.dev = &intf->dev;
 	wacom->usbdev = dev;
 
diff --git a/drivers/usb/input/xpad.c b/drivers/usb/input/xpad.c
--- a/drivers/usb/input/xpad.c
+++ b/drivers/usb/input/xpad.c
@@ -62,6 +62,7 @@
 #include <linux/module.h>
 #include <linux/smp_lock.h>
 #include <linux/usb.h>
+#include <linux/usb_input.h>
 
 #define DRIVER_VERSION "v0.0.5"
 #define DRIVER_AUTHOR "Marko Friedemann <mfr@bmx-chemnitz.de>"
@@ -104,13 +105,12 @@ MODULE_DEVICE_TABLE (usb, xpad_table);
 struct usb_xpad {
 	struct input_dev dev;			/* input device interface */
 	struct usb_device *udev;		/* usb device */
-	
+
 	struct urb *irq_in;			/* urb for interrupt in report */
 	unsigned char *idata;			/* input data */
 	dma_addr_t idata_dma;
-	
+
 	char phys[65];				/* physical device path */
-	int open_count;				/* reference count */
 };
 
 /*
@@ -128,35 +128,35 @@ static void xpad_process_packet(struct u
 	struct input_dev *dev = &xpad->dev;
 
 	input_regs(dev, regs);
-	
+
 	/* left stick */
 	input_report_abs(dev, ABS_X, (__s16) (((__s16)data[13] << 8) | data[12]));
 	input_report_abs(dev, ABS_Y, (__s16) (((__s16)data[15] << 8) | data[14]));
-	
+
 	/* right stick */
 	input_report_abs(dev, ABS_RX, (__s16) (((__s16)data[17] << 8) | data[16]));
 	input_report_abs(dev, ABS_RY, (__s16) (((__s16)data[19] << 8) | data[18]));
-	
+
 	/* triggers left/right */
 	input_report_abs(dev, ABS_Z, data[10]);
 	input_report_abs(dev, ABS_RZ, data[11]);
-	
+
 	/* digital pad */
 	input_report_abs(dev, ABS_HAT0X, !!(data[2] & 0x08) - !!(data[2] & 0x04));
 	input_report_abs(dev, ABS_HAT0Y, !!(data[2] & 0x02) - !!(data[2] & 0x01));
-	
+
 	/* start/back buttons and stick press left/right */
 	input_report_key(dev, BTN_START, (data[2] & 0x10) >> 4);
 	input_report_key(dev, BTN_BACK, (data[2] & 0x20) >> 5);
 	input_report_key(dev, BTN_THUMBL, (data[2] & 0x40) >> 6);
 	input_report_key(dev, BTN_THUMBR, data[2] >> 7);
-	
+
 	/* "analog" buttons A, B, X, Y */
 	input_report_key(dev, BTN_A, data[4]);
 	input_report_key(dev, BTN_B, data[5]);
 	input_report_key(dev, BTN_X, data[6]);
 	input_report_key(dev, BTN_Y, data[7]);
-	
+
 	/* "analog" buttons black, white */
 	input_report_key(dev, BTN_C, data[8]);
 	input_report_key(dev, BTN_Z, data[9]);
@@ -168,7 +168,7 @@ static void xpad_irq_in(struct urb *urb,
 {
 	struct usb_xpad *xpad = urb->context;
 	int retval;
-	
+
 	switch (urb->status) {
 	case 0:
 		/* success */
@@ -183,7 +183,7 @@ static void xpad_irq_in(struct urb *urb,
 		dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status);
 		goto exit;
 	}
-	
+
 	xpad_process_packet(xpad, 0, xpad->idata, regs);
 
 exit:
@@ -196,25 +196,19 @@ exit:
 static int xpad_open (struct input_dev *dev)
 {
 	struct usb_xpad *xpad = dev->private;
-	
-	if (xpad->open_count++)
-		return 0;
-	
+
 	xpad->irq_in->dev = xpad->udev;
-	if (usb_submit_urb(xpad->irq_in, GFP_KERNEL)) {
-		xpad->open_count--;
+	if (usb_submit_urb(xpad->irq_in, GFP_KERNEL))
 		return -EIO;
-	}
-	
+
 	return 0;
 }
 
 static void xpad_close (struct input_dev *dev)
 {
 	struct usb_xpad *xpad = dev->private;
-	
-	if (!--xpad->open_count)
-		usb_kill_urb(xpad->irq_in);
+
+	usb_kill_urb(xpad->irq_in);
 }
 
 static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id)
@@ -224,19 +218,19 @@ static int xpad_probe(struct usb_interfa
 	struct usb_endpoint_descriptor *ep_irq_in;
 	char path[64];
 	int i;
-	
+
 	for (i = 0; xpad_device[i].idVendor; i++) {
 		if ((le16_to_cpu(udev->descriptor.idVendor) == xpad_device[i].idVendor) &&
 		    (le16_to_cpu(udev->descriptor.idProduct) == xpad_device[i].idProduct))
 			break;
 	}
-	
+
 	if ((xpad = kmalloc (sizeof(struct usb_xpad), GFP_KERNEL)) == NULL) {
 		err("cannot allocate memory for new pad");
 		return -ENOMEM;
 	}
 	memset(xpad, 0, sizeof(struct usb_xpad));
-	
+
 	xpad->idata = usb_buffer_alloc(udev, XPAD_PKT_LEN,
 				       SLAB_ATOMIC, &xpad->idata_dma);
 	if (!xpad->idata) {
@@ -251,43 +245,40 @@ static int xpad_probe(struct usb_interfa
                 kfree(xpad);
 		return -ENOMEM;
         }
-	
+
 	ep_irq_in = &intf->cur_altsetting->endpoint[0].desc;
-	
+
 	usb_fill_int_urb(xpad->irq_in, udev,
 			 usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress),
 			 xpad->idata, XPAD_PKT_LEN, xpad_irq_in,
 			 xpad, ep_irq_in->bInterval);
 	xpad->irq_in->transfer_dma = xpad->idata_dma;
 	xpad->irq_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
-	
+
 	xpad->udev = udev;
-	
-	xpad->dev.id.bustype = BUS_USB;
-	xpad->dev.id.vendor = le16_to_cpu(udev->descriptor.idVendor);
-	xpad->dev.id.product = le16_to_cpu(udev->descriptor.idProduct);
-	xpad->dev.id.version = le16_to_cpu(udev->descriptor.bcdDevice);
+
+	usb_to_input_id(udev, &xpad->dev.id);
 	xpad->dev.dev = &intf->dev;
 	xpad->dev.private = xpad;
 	xpad->dev.name = xpad_device[i].name;
 	xpad->dev.phys = xpad->phys;
 	xpad->dev.open = xpad_open;
 	xpad->dev.close = xpad_close;
-	
+
 	usb_make_path(udev, path, 64);
 	snprintf(xpad->phys, 64,  "%s/input0", path);
-	
+
 	xpad->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
-	
+
 	for (i = 0; xpad_btn[i] >= 0; i++)
 		set_bit(xpad_btn[i], xpad->dev.keybit);
-	
+
 	for (i = 0; xpad_abs[i] >= 0; i++) {
-		
+
 		signed short t = xpad_abs[i];
-		
+
 		set_bit(t, xpad->dev.absbit);
-		
+
 		switch (t) {
 			case ABS_X:
 			case ABS_Y:
@@ -310,11 +301,11 @@ static int xpad_probe(struct usb_interfa
 				break;
 		}
 	}
-	
+
 	input_register_device(&xpad->dev);
-	
+
 	printk(KERN_INFO "input: %s on %s", xpad->dev.name, path);
-	
+
 	usb_set_intfdata(intf, xpad);
 	return 0;
 }
@@ -322,7 +313,7 @@ static int xpad_probe(struct usb_interfa
 static void xpad_disconnect(struct usb_interface *intf)
 {
 	struct usb_xpad *xpad = usb_get_intfdata (intf);
-	
+
 	usb_set_intfdata(intf, NULL);
 	if (xpad) {
 		usb_kill_urb(xpad->irq_in);
diff --git a/drivers/usb/media/Makefile b/drivers/usb/media/Makefile
--- a/drivers/usb/media/Makefile
+++ b/drivers/usb/media/Makefile
@@ -2,7 +2,7 @@
 # Makefile for USB Media drivers
 #
 
-sn9c102-objs	:= sn9c102_core.o sn9c102_hv7131d.o sn9c102_mi0343.o sn9c102_pas106b.o sn9c102_pas202bcb.o sn9c102_tas5110c1b.o sn9c102_tas5130d1b.o
+sn9c102-objs	:= sn9c102_core.o sn9c102_hv7131d.o sn9c102_mi0343.o sn9c102_ov7630.o sn9c102_pas106b.o sn9c102_pas202bcb.o sn9c102_tas5110c1b.o sn9c102_tas5130d1b.o
 
 obj-$(CONFIG_USB_DABUSB)	+= dabusb.o
 obj-$(CONFIG_USB_DSBR)		+= dsbr100.o
diff --git a/drivers/usb/media/konicawc.c b/drivers/usb/media/konicawc.c
--- a/drivers/usb/media/konicawc.c
+++ b/drivers/usb/media/konicawc.c
@@ -16,6 +16,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/input.h>
+#include <linux/usb_input.h>
 
 #include "usbvideo.h"
 
@@ -845,10 +846,7 @@ static int konicawc_probe(struct usb_int
 		cam->input.private = cam;
 		cam->input.evbit[0] = BIT(EV_KEY);
 		cam->input.keybit[LONG(BTN_0)] = BIT(BTN_0);
-		cam->input.id.bustype = BUS_USB;
-		cam->input.id.vendor = le16_to_cpu(dev->descriptor.idVendor);
-		cam->input.id.product = le16_to_cpu(dev->descriptor.idProduct);
-		cam->input.id.version = le16_to_cpu(dev->descriptor.bcdDevice);
+		usb_to_input_id(dev, &cam->input.id);
 		input_register_device(&cam->input);
 		
 		usb_make_path(dev, cam->input_physname, 56);
diff --git a/drivers/usb/media/pwc/pwc-uncompress.c b/drivers/usb/media/pwc/pwc-uncompress.c
--- a/drivers/usb/media/pwc/pwc-uncompress.c
+++ b/drivers/usb/media/pwc/pwc-uncompress.c
@@ -118,9 +118,9 @@ int pwc_decompress(struct pwc_device *pd
 		   return -ENXIO; /* No such device or address: missing decompressor */
 		 }
 
+#if 0
 		switch (pdev->type)
 		 {
-#if 0		 
 		  case 675:
 		  case 680:
 		  case 690:
@@ -128,18 +128,17 @@ int pwc_decompress(struct pwc_device *pd
 		  case 730:
 		  case 740:
 		  case 750:
-		    pwc_dec23_decompress(&pdev->image, &pdev->view, &pdev->offset,
-				yuv, image,
-				flags,
+		    pwc_dec23_decompress(&pdev->image, &pdev->view,
+				&pdev->offset, yuv, image, flags,
 				pdev->decompress_data, pdev->vbandlength);
 		    break;
 		  case 645:
 		  case 646:
 		    /* TODO & FIXME */
-#endif		    
-		    return -ENXIO; /* No such device or address: missing decompressor */
+		    return -ENXIO; /* Missing decompressor */
 		    break;
 		 }
+#endif
 	}
 	return 0;
 }
diff --git a/drivers/usb/media/sn9c102.h b/drivers/usb/media/sn9c102.h
--- a/drivers/usb/media/sn9c102.h
+++ b/drivers/usb/media/sn9c102.h
@@ -56,7 +56,7 @@
 #define SN9C102_MODULE_AUTHOR   "(C) 2004-2005 Luca Risolia"
 #define SN9C102_AUTHOR_EMAIL    "<luca.risolia@studio.unibo.it>"
 #define SN9C102_MODULE_LICENSE  "GPL"
-#define SN9C102_MODULE_VERSION  "1:1.24"
+#define SN9C102_MODULE_VERSION  "1:1.24a"
 #define SN9C102_MODULE_VERSION_CODE  KERNEL_VERSION(1, 0, 24)
 
 enum sn9c102_bridge {
diff --git a/drivers/usb/media/sn9c102_core.c b/drivers/usb/media/sn9c102_core.c
--- a/drivers/usb/media/sn9c102_core.c
+++ b/drivers/usb/media/sn9c102_core.c
@@ -429,7 +429,7 @@ sn9c102_i2c_try_read(struct sn9c102_devi
 }
 
 
-static int 
+int
 sn9c102_i2c_try_write(struct sn9c102_device* cam,
                       struct sn9c102_sensor* sensor, u8 address, u8 value)
 {
diff --git a/drivers/usb/media/sn9c102_ov7630.c b/drivers/usb/media/sn9c102_ov7630.c
new file mode 100644
--- /dev/null
+++ b/drivers/usb/media/sn9c102_ov7630.c
@@ -0,0 +1,394 @@
+/***************************************************************************
+ * Plug-in for OV7630 image sensor connected to the SN9C10x PC Camera      *
+ * Controllers                                                             *
+ *                                                                         *
+ * Copyright (C) 2005 by Luca Risolia <luca.risolia@studio.unibo.it>       *
+ *                                                                         *
+ * 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 "sn9c102_sensor.h"
+
+
+static struct sn9c102_sensor ov7630;
+
+
+static int ov7630_init(struct sn9c102_device* cam)
+{
+	int err = 0;
+
+	err += sn9c102_write_reg(cam, 0x00, 0x14);
+	err += sn9c102_write_reg(cam, 0x60, 0x17);
+	err += sn9c102_write_reg(cam, 0x0f, 0x18);
+	err += sn9c102_write_reg(cam, 0x50, 0x19);
+
+	err += sn9c102_i2c_write(cam, 0x12, 0x8d);
+	err += sn9c102_i2c_write(cam, 0x11, 0x00);
+	err += sn9c102_i2c_write(cam, 0x15, 0x34);
+	err += sn9c102_i2c_write(cam, 0x16, 0x03);
+	err += sn9c102_i2c_write(cam, 0x17, 0x1c);
+	err += sn9c102_i2c_write(cam, 0x18, 0xbd);
+	err += sn9c102_i2c_write(cam, 0x19, 0x06);
+	err += sn9c102_i2c_write(cam, 0x1a, 0xf6);
+	err += sn9c102_i2c_write(cam, 0x1b, 0x04);
+	err += sn9c102_i2c_write(cam, 0x20, 0x44);
+	err += sn9c102_i2c_write(cam, 0x23, 0xee);
+	err += sn9c102_i2c_write(cam, 0x26, 0xa0);
+	err += sn9c102_i2c_write(cam, 0x27, 0x9a);
+	err += sn9c102_i2c_write(cam, 0x28, 0x20);
+	err += sn9c102_i2c_write(cam, 0x29, 0x30);
+	err += sn9c102_i2c_write(cam, 0x2f, 0x3d);
+	err += sn9c102_i2c_write(cam, 0x30, 0x24);
+	err += sn9c102_i2c_write(cam, 0x32, 0x86);
+	err += sn9c102_i2c_write(cam, 0x60, 0xa9);
+	err += sn9c102_i2c_write(cam, 0x61, 0x42);
+	err += sn9c102_i2c_write(cam, 0x65, 0x00);
+	err += sn9c102_i2c_write(cam, 0x69, 0x38);
+	err += sn9c102_i2c_write(cam, 0x6f, 0x88);
+	err += sn9c102_i2c_write(cam, 0x70, 0x0b);
+	err += sn9c102_i2c_write(cam, 0x71, 0x00);
+	err += sn9c102_i2c_write(cam, 0x74, 0x21);
+	err += sn9c102_i2c_write(cam, 0x7d, 0xf7);
+
+	return err;
+}
+
+
+static int ov7630_set_ctrl(struct sn9c102_device* cam,
+                           const struct v4l2_control* ctrl)
+{
+	int err = 0;
+
+	switch (ctrl->id) {
+	case V4L2_CID_EXPOSURE:
+		err += sn9c102_i2c_write(cam, 0x10, ctrl->value >> 2);
+		err += sn9c102_i2c_write(cam, 0x76, ctrl->value & 0x03);
+		break;
+	case V4L2_CID_RED_BALANCE:
+		err += sn9c102_i2c_write(cam, 0x02, ctrl->value);
+		break;
+	case V4L2_CID_BLUE_BALANCE:
+		err += sn9c102_i2c_write(cam, 0x03, ctrl->value);
+		break;
+	case V4L2_CID_GAIN:
+		err += sn9c102_i2c_write(cam, 0x00, ctrl->value);
+		break;
+	case V4L2_CID_CONTRAST:
+		err += ctrl->value ? sn9c102_i2c_write(cam, 0x05,
+		                                       (ctrl->value-1) | 0x20)
+		                   : sn9c102_i2c_write(cam, 0x05, 0x00);
+		break;
+	case V4L2_CID_BRIGHTNESS:
+		err += sn9c102_i2c_write(cam, 0x06, ctrl->value);
+		break;
+	case V4L2_CID_SATURATION:
+		err += sn9c102_i2c_write(cam, 0x03, ctrl->value << 4);
+		break;
+	case V4L2_CID_HUE:
+		err += ctrl->value ? sn9c102_i2c_write(cam, 0x04,
+		                                       (ctrl->value-1) | 0x20)
+		                   : sn9c102_i2c_write(cam, 0x04, 0x00);
+		break;
+	case V4L2_CID_DO_WHITE_BALANCE:
+		err += sn9c102_i2c_write(cam, 0x0c, ctrl->value);
+		break;
+	case V4L2_CID_WHITENESS:
+		err += sn9c102_i2c_write(cam, 0x0d, ctrl->value);
+		break;
+	case V4L2_CID_AUTO_WHITE_BALANCE:
+		err += sn9c102_i2c_write(cam, 0x12, (ctrl->value << 2) | 0x09);
+		break;
+	case V4L2_CID_AUTOGAIN:
+		err += sn9c102_i2c_write(cam, 0x13, ctrl->value);
+		break;
+	case V4L2_CID_VFLIP:
+		err += sn9c102_i2c_write(cam, 0x75, 0x0e | (ctrl->value << 7));
+		break;
+	case V4L2_CID_BLACK_LEVEL:
+		err += sn9c102_i2c_write(cam, 0x25, ctrl->value);
+		break;
+	case SN9C102_V4L2_CID_BRIGHT_LEVEL:
+		err += sn9c102_i2c_write(cam, 0x24, ctrl->value);
+		break;
+	case SN9C102_V4L2_CID_GAMMA:
+		err += sn9c102_i2c_write(cam, 0x14, (ctrl->value << 2) | 0x80);
+		break;
+	case SN9C102_V4L2_CID_BAND_FILTER:
+		err += sn9c102_i2c_write(cam, 0x2d, ctrl->value << 2);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return err ? -EIO : 0;
+}
+
+
+static int ov7630_set_crop(struct sn9c102_device* cam,
+                           const struct v4l2_rect* rect)
+{
+	struct sn9c102_sensor* s = &ov7630;
+	int err = 0;
+	u8 v_start = (u8)(rect->top - s->cropcap.bounds.top) + 1;
+
+	err += sn9c102_write_reg(cam, v_start, 0x13);
+
+	return err;
+}
+
+
+static int ov7630_set_pix_format(struct sn9c102_device* cam,
+                                 const struct v4l2_pix_format* pix)
+{
+	int err = 0;
+
+	if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X)
+		err += sn9c102_write_reg(cam, 0x20, 0x19);
+	else
+		err += sn9c102_write_reg(cam, 0x50, 0x19);
+
+	return err;
+}
+
+
+static struct sn9c102_sensor ov7630 = {
+	.name = "OV7630",
+	.maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>",
+	.sysfs_ops = SN9C102_I2C_WRITE,
+	.frequency = SN9C102_I2C_100KHZ,
+	.interface = SN9C102_I2C_2WIRES,
+	.i2c_slave_id = 0x21,
+	.init = &ov7630_init,
+	.qctrl = {
+		{
+			.id = V4L2_CID_GAIN,
+			.type = V4L2_CTRL_TYPE_INTEGER,
+			.name = "global gain",
+			.minimum = 0x00,
+			.maximum = 0x3f,
+			.step = 0x01,
+			.default_value = 0x14,
+			.flags = 0,
+		},
+		{
+			.id = V4L2_CID_HUE,
+			.type = V4L2_CTRL_TYPE_INTEGER,
+			.name = "hue",
+			.minimum = 0x00,
+			.maximum = 0x1f+1,
+			.step = 0x01,
+			.default_value = 0x00,
+			.flags = 0,
+		},
+		{
+			.id = V4L2_CID_SATURATION,
+			.type = V4L2_CTRL_TYPE_INTEGER,
+			.name = "saturation",
+			.minimum = 0x00,
+			.maximum = 0x0f,
+			.step = 0x01,
+			.default_value = 0x08,
+			.flags = 0,
+		},
+		{
+			.id = V4L2_CID_CONTRAST,
+			.type = V4L2_CTRL_TYPE_INTEGER,
+			.name = "contrast",
+			.minimum = 0x00,
+			.maximum = 0x1f+1,
+			.step = 0x01,
+			.default_value = 0x00,
+			.flags = 0,
+		},
+		{
+			.id = V4L2_CID_EXPOSURE,
+			.type = V4L2_CTRL_TYPE_INTEGER,
+			.name = "exposure",
+			.minimum = 0x000,
+			.maximum = 0x3ff,
+			.step = 0x001,
+			.default_value = 0x83<<2,
+			.flags = 0,
+		},
+		{
+			.id = V4L2_CID_RED_BALANCE,
+			.type = V4L2_CTRL_TYPE_INTEGER,
+			.name = "red balance",
+			.minimum = 0x00,
+			.maximum = 0xff,
+			.step = 0x01,
+			.default_value = 0x3a,
+			.flags = 0,
+		},
+		{
+			.id = V4L2_CID_BLUE_BALANCE,
+			.type = V4L2_CTRL_TYPE_INTEGER,
+			.name = "blue balance",
+			.minimum = 0x00,
+			.maximum = 0xff,
+			.step = 0x01,
+			.default_value = 0x77,
+			.flags = 0,
+		},
+		{
+			.id = V4L2_CID_BRIGHTNESS,
+			.type = V4L2_CTRL_TYPE_INTEGER,
+			.name = "brightness",
+			.minimum = 0x00,
+			.maximum = 0xff,
+			.step = 0x01,
+			.default_value = 0xa0,
+			.flags = 0,
+		},
+		{
+			.id = V4L2_CID_DO_WHITE_BALANCE,
+			.type = V4L2_CTRL_TYPE_INTEGER,
+			.name = "white balance background: blue",
+			.minimum = 0x00,
+			.maximum = 0x3f,
+			.step = 0x01,
+			.default_value = 0x20,
+			.flags = 0,
+		},
+		{
+			.id = V4L2_CID_WHITENESS,
+			.type = V4L2_CTRL_TYPE_INTEGER,
+			.name = "white balance background: red",
+			.minimum = 0x00,
+			.maximum = 0x3f,
+			.step = 0x01,
+			.default_value = 0x20,
+			.flags = 0,
+		},
+		{
+			.id = V4L2_CID_AUTO_WHITE_BALANCE,
+			.type = V4L2_CTRL_TYPE_BOOLEAN,
+			.name = "auto white balance",
+			.minimum = 0x00,
+			.maximum = 0x01,
+			.step = 0x01,
+			.default_value = 0x01,
+			.flags = 0,
+		},
+		{
+			.id = V4L2_CID_AUTOGAIN,
+			.type = V4L2_CTRL_TYPE_INTEGER,
+			.name = "gain & exposure mode",
+			.minimum = 0x00,
+			.maximum = 0x03,
+			.step = 0x01,
+			.default_value = 0x00,
+			.flags = 0,
+		},
+		{
+			.id = V4L2_CID_VFLIP,
+			.type = V4L2_CTRL_TYPE_BOOLEAN,
+			.name = "vertical flip",
+			.minimum = 0x00,
+			.maximum = 0x01,
+			.step = 0x01,
+			.default_value = 0x01,
+			.flags = 0,
+		},
+		{
+			.id = V4L2_CID_BLACK_LEVEL,
+			.type = V4L2_CTRL_TYPE_INTEGER,
+			.name = "black pixel ratio",
+			.minimum = 0x01,
+			.maximum = 0x9a,
+			.step = 0x01,
+			.default_value = 0x8a,
+			.flags = 0,
+		},
+		{
+			.id = SN9C102_V4L2_CID_BRIGHT_LEVEL,
+			.type = V4L2_CTRL_TYPE_INTEGER,
+			.name = "bright pixel ratio",
+			.minimum = 0x01,
+			.maximum = 0x9a,
+			.step = 0x01,
+			.default_value = 0x10,
+			.flags = 0,
+		},
+		{
+			.id = SN9C102_V4L2_CID_BAND_FILTER,
+			.type = V4L2_CTRL_TYPE_BOOLEAN,
+			.name = "band filter",
+			.minimum = 0x00,
+			.maximum = 0x01,
+			.step = 0x01,
+			.default_value = 0x00,
+			.flags = 0,
+		},
+		{
+			.id = SN9C102_V4L2_CID_GAMMA,
+			.type = V4L2_CTRL_TYPE_BOOLEAN,
+			.name = "rgb gamma",
+			.minimum = 0x00,
+			.maximum = 0x01,
+			.step = 0x01,
+			.default_value = 0x00,
+			.flags = 0,
+		},
+	},
+	.set_ctrl = &ov7630_set_ctrl,
+	.cropcap = {
+		.bounds = {
+			.left = 0,
+			.top = 0,
+			.width = 640,
+			.height = 480,
+		},
+		.defrect = {
+			.left = 0,
+			.top = 0,
+			.width = 640,
+			.height = 480,
+		},
+	},
+	.set_crop = &ov7630_set_crop,
+	.pix_format = {
+		.width = 640,
+		.height = 480,
+		.pixelformat = V4L2_PIX_FMT_SBGGR8,
+		.priv = 8,
+	},
+	.set_pix_format = &ov7630_set_pix_format
+};
+
+
+int sn9c102_probe_ov7630(struct sn9c102_device* cam)
+{
+	int err = 0;
+
+	sn9c102_attach_sensor(cam, &ov7630);
+
+	if (le16_to_cpu(ov7630.usbdev->descriptor.idProduct) != 0x608f &&
+	    le16_to_cpu(ov7630.usbdev->descriptor.idProduct) != 0x602c)
+		return -ENODEV;
+
+	err += sn9c102_write_reg(cam, 0x01, 0x01);
+	err += sn9c102_write_reg(cam, 0x00, 0x01);
+	err += sn9c102_write_reg(cam, 0x28, 0x17);
+
+	if (err)
+		return -EIO;
+
+	err += sn9c102_i2c_write(cam, 0x0b, 0);
+	if (err)
+		return -ENODEV;
+
+	return 0;
+}
diff --git a/drivers/usb/media/sn9c102_sensor.h b/drivers/usb/media/sn9c102_sensor.h
--- a/drivers/usb/media/sn9c102_sensor.h
+++ b/drivers/usb/media/sn9c102_sensor.h
@@ -64,6 +64,7 @@ struct sn9c102_sensor;
 */
 extern int sn9c102_probe_hv7131d(struct sn9c102_device* cam);
 extern int sn9c102_probe_mi0343(struct sn9c102_device* cam);
+extern int sn9c102_probe_ov7630(struct sn9c102_device* cam);
 extern int sn9c102_probe_pas106b(struct sn9c102_device* cam);
 extern int sn9c102_probe_pas202bcb(struct sn9c102_device* cam);
 extern int sn9c102_probe_tas5110c1b(struct sn9c102_device* cam);
@@ -80,6 +81,7 @@ static int (*sn9c102_sensor_table[])(str
 	&sn9c102_probe_pas106b, /* strong detection based on SENSOR ids */    \
 	&sn9c102_probe_pas202bcb, /* strong detection based on SENSOR ids */  \
 	&sn9c102_probe_hv7131d, /* strong detection based on SENSOR ids */    \
+	&sn9c102_probe_ov7630, /* detection mostly based on USB pid/vid */    \
 	&sn9c102_probe_tas5110c1b, /* detection based on USB pid/vid */       \
 	&sn9c102_probe_tas5130d1b, /* detection based on USB pid/vid */       \
 	NULL,                                                                 \
@@ -103,7 +105,8 @@ static const struct usb_device_id sn9c10
 	{ USB_DEVICE(0x0c45, 0x6029), }, /* PAS106B */                        \
 	{ USB_DEVICE(0x0c45, 0x602a), }, /* HV7131D */                        \
 	{ USB_DEVICE(0x0c45, 0x602b), }, /* MI-0343 */                        \
-	{ USB_DEVICE(0x0c45, 0x602c), }, /* OV7620 */                         \
+	{ USB_DEVICE(0x0c45, 0x602c), }, /* OV7630 */                         \
+	{ USB_DEVICE(0x0c45, 0x602d), },                                      \
 	{ USB_DEVICE(0x0c45, 0x6030), }, /* MI03x */                          \
 	{ USB_DEVICE(0x0c45, 0x6080), },                                      \
 	{ USB_DEVICE(0x0c45, 0x6082), }, /* MI0343 and MI0360 */              \
@@ -145,6 +148,8 @@ static const struct usb_device_id sn9c10
 */
 
 /* The "try" I2C I/O versions are used when probing the sensor */
+extern int sn9c102_i2c_try_write(struct sn9c102_device*,struct sn9c102_sensor*,
+                                 u8 address, u8 value);
 extern int sn9c102_i2c_try_read(struct sn9c102_device*,struct sn9c102_sensor*,
                                 u8 address);
 
@@ -201,6 +206,8 @@ enum sn9c102_i2c_interface {
 	SN9C102_I2C_3WIRES,
 };
 
+#define SN9C102_MAX_CTRLS V4L2_CID_LASTP1-V4L2_CID_BASE+10
+
 struct sn9c102_sensor {
 	char name[32], /* sensor name */
 	     maintainer[64]; /* name of the mantainer <email> */
@@ -243,7 +250,7 @@ struct sn9c102_sensor {
 	   sensor according to the default configuration structures below.
 	*/
 
-	struct v4l2_queryctrl qctrl[V4L2_CID_LASTP1-V4L2_CID_BASE];
+	struct v4l2_queryctrl qctrl[SN9C102_MAX_CTRLS];
 	/*
 	   Optional list of default controls, defined as indicated in the 
 	   V4L2 API. Menu type controls are not handled by this interface.
@@ -356,7 +363,7 @@ struct sn9c102_sensor {
 	   core module to store successfully updated values of the above
 	   settings, for rollbacks..etc..in case of errors during atomic I/O
 	*/
-	struct v4l2_queryctrl _qctrl[V4L2_CID_LASTP1-V4L2_CID_BASE];
+	struct v4l2_queryctrl _qctrl[SN9C102_MAX_CTRLS];
 	struct v4l2_rect _rect;
 };
 
@@ -367,5 +374,8 @@ struct sn9c102_sensor {
 #define SN9C102_V4L2_CID_GREEN_BALANCE V4L2_CID_PRIVATE_BASE + 1
 #define SN9C102_V4L2_CID_RESET_LEVEL V4L2_CID_PRIVATE_BASE + 2
 #define SN9C102_V4L2_CID_PIXEL_BIAS_VOLTAGE V4L2_CID_PRIVATE_BASE + 3
+#define SN9C102_V4L2_CID_GAMMA V4L2_CID_PRIVATE_BASE + 4
+#define SN9C102_V4L2_CID_BAND_FILTER V4L2_CID_PRIVATE_BASE + 5
+#define SN9C102_V4L2_CID_BRIGHT_LEVEL V4L2_CID_PRIVATE_BASE + 6
 
 #endif /* _SN9C102_SENSOR_H_ */
diff --git a/drivers/usb/media/sn9c102_tas5110c1b.c b/drivers/usb/media/sn9c102_tas5110c1b.c
--- a/drivers/usb/media/sn9c102_tas5110c1b.c
+++ b/drivers/usb/media/sn9c102_tas5110c1b.c
@@ -24,8 +24,6 @@
 
 static struct sn9c102_sensor tas5110c1b;
 
-static struct v4l2_control tas5110c1b_gain;
-
 
 static int tas5110c1b_init(struct sn9c102_device* cam)
 {
@@ -46,21 +44,6 @@ static int tas5110c1b_init(struct sn9c10
 }
 
 
-static int tas5110c1b_get_ctrl(struct sn9c102_device* cam, 
-                               struct v4l2_control* ctrl)
-{
-	switch (ctrl->id) {
-	case V4L2_CID_GAIN:
-		ctrl->value = tas5110c1b_gain.value;
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-
 static int tas5110c1b_set_ctrl(struct sn9c102_device* cam, 
                                const struct v4l2_control* ctrl)
 {
@@ -68,8 +51,7 @@ static int tas5110c1b_set_ctrl(struct sn
 
 	switch (ctrl->id) {
 	case V4L2_CID_GAIN:
-		if (!(err += sn9c102_i2c_write(cam, 0x20, 0xf6 - ctrl->value)))
-			tas5110c1b_gain.value = ctrl->value;
+		err += sn9c102_i2c_write(cam, 0x20, 0xf6 - ctrl->value);
 		break;
 	default:
 		return -EINVAL;
@@ -147,7 +129,6 @@ static struct sn9c102_sensor tas5110c1b 
 			.height = 288,
 		},
 	},
-	.get_ctrl = &tas5110c1b_get_ctrl,
 	.set_crop = &tas5110c1b_set_crop,
 	.pix_format = {
 		.width = 352,
diff --git a/drivers/usb/media/sn9c102_tas5130d1b.c b/drivers/usb/media/sn9c102_tas5130d1b.c
--- a/drivers/usb/media/sn9c102_tas5130d1b.c
+++ b/drivers/usb/media/sn9c102_tas5130d1b.c
@@ -24,8 +24,6 @@
 
 static struct sn9c102_sensor tas5130d1b;
 
-static struct v4l2_control tas5130d1b_gain, tas5130d1b_exposure;
-
 
 static int tas5130d1b_init(struct sn9c102_device* cam)
 {
@@ -44,24 +42,6 @@ static int tas5130d1b_init(struct sn9c10
 }
 
 
-static int tas5130d1b_get_ctrl(struct sn9c102_device* cam, 
-                               struct v4l2_control* ctrl)
-{
-	switch (ctrl->id) {
-	case V4L2_CID_GAIN:
-		ctrl->value = tas5130d1b_gain.value;
-		break;
-	case V4L2_CID_EXPOSURE:
-		ctrl->value = tas5130d1b_exposure.value;
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-
 static int tas5130d1b_set_ctrl(struct sn9c102_device* cam, 
                                const struct v4l2_control* ctrl)
 {
@@ -69,12 +49,10 @@ static int tas5130d1b_set_ctrl(struct sn
 
 	switch (ctrl->id) {
 	case V4L2_CID_GAIN:
-		if (!(err += sn9c102_i2c_write(cam, 0x20, 0xf6 - ctrl->value)))
-			tas5130d1b_gain.value = ctrl->value;
+		err += sn9c102_i2c_write(cam, 0x20, 0xf6 - ctrl->value);
 		break;
 	case V4L2_CID_EXPOSURE:
-		if (!(err += sn9c102_i2c_write(cam, 0x40, 0x47 - ctrl->value)))
-			tas5130d1b_exposure.value = ctrl->value;
+		err += sn9c102_i2c_write(cam, 0x40, 0x47 - ctrl->value);
 		break;
 	default:
 		return -EINVAL;
@@ -147,7 +125,6 @@ static struct sn9c102_sensor tas5130d1b 
 			.flags = 0,
 		},
 	},
-	.get_ctrl = &tas5130d1b_get_ctrl,
 	.set_ctrl = &tas5130d1b_set_ctrl,
 	.cropcap = {
 		.bounds = {
diff --git a/drivers/usb/media/stv680.c b/drivers/usb/media/stv680.c
--- a/drivers/usb/media/stv680.c
+++ b/drivers/usb/media/stv680.c
@@ -1375,9 +1375,13 @@ static int stv680_probe (struct usb_inte
 	    (le16_to_cpu(dev->descriptor.idProduct) == USB_PENCAM_PRODUCT_ID)) {
 		camera_name = "STV0680";
 		PDEBUG (0, "STV(i): STV0680 camera found.");
+	} else if ((le16_to_cpu(dev->descriptor.idVendor) == USB_CREATIVEGOMINI_VENDOR_ID) &&
+		   (le16_to_cpu(dev->descriptor.idProduct) == USB_CREATIVEGOMINI_PRODUCT_ID)) {
+		camera_name = "Creative WebCam Go Mini";
+		PDEBUG (0, "STV(i): Creative WebCam Go Mini found.");
 	} else {
-		PDEBUG (0, "STV(e): Vendor/Product ID do not match STV0680 values.");
-		PDEBUG (0, "STV(e): Check that the STV0680 camera is connected to the computer.");
+		PDEBUG (0, "STV(e): Vendor/Product ID do not match STV0680 or Creative WebCam Go Mini values.");
+		PDEBUG (0, "STV(e): Check that the STV0680 or Creative WebCam Go Mini camera is connected to the computer.");
 		retval = -ENODEV;
 		goto error;
 	}
diff --git a/drivers/usb/media/stv680.h b/drivers/usb/media/stv680.h
--- a/drivers/usb/media/stv680.h
+++ b/drivers/usb/media/stv680.h
@@ -41,12 +41,17 @@
 
 #define USB_PENCAM_VENDOR_ID	0x0553
 #define USB_PENCAM_PRODUCT_ID	0x0202
+
+#define USB_CREATIVEGOMINI_VENDOR_ID	0x041e
+#define USB_CREATIVEGOMINI_PRODUCT_ID	0x4007
+
 #define PENCAM_TIMEOUT          1000
 /* fmt 4 */
 #define STV_VIDEO_PALETTE       VIDEO_PALETTE_RGB24
 
 static struct usb_device_id device_table[] = {
 	{USB_DEVICE (USB_PENCAM_VENDOR_ID, USB_PENCAM_PRODUCT_ID)},
+	{USB_DEVICE (USB_CREATIVEGOMINI_VENDOR_ID, USB_CREATIVEGOMINI_PRODUCT_ID)},
 	{}
 };
 MODULE_DEVICE_TABLE (usb, device_table);
diff --git a/drivers/usb/misc/Kconfig b/drivers/usb/misc/Kconfig
--- a/drivers/usb/misc/Kconfig
+++ b/drivers/usb/misc/Kconfig
@@ -139,6 +139,16 @@ config USB_IDMOUSE
 
 source "drivers/usb/misc/sisusbvga/Kconfig"
 
+config USB_LD
+	tristate "USB LD driver"
+	depends on USB && EXPERIMENTAL
+	help
+	  This driver is for generic USB devices that use interrupt transfers,
+	  like LD Didactic's USB devices.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called ldusb.
+
 config USB_TEST
 	tristate "USB testing driver (DEVELOPMENT)"
 	depends on USB && USB_DEVICEFS && EXPERIMENTAL
diff --git a/drivers/usb/misc/Makefile b/drivers/usb/misc/Makefile
--- a/drivers/usb/misc/Makefile
+++ b/drivers/usb/misc/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_USB_EMI26)		+= emi26.o
 obj-$(CONFIG_USB_EMI62)		+= emi62.o
 obj-$(CONFIG_USB_IDMOUSE)	+= idmouse.o
 obj-$(CONFIG_USB_LCD)		+= usblcd.o
+obj-$(CONFIG_USB_LD)		+= ldusb.o
 obj-$(CONFIG_USB_LED)		+= usbled.o
 obj-$(CONFIG_USB_LEGOTOWER)	+= legousbtower.o
 obj-$(CONFIG_USB_PHIDGETKIT)	+= phidgetkit.o
diff --git a/drivers/usb/misc/cytherm.c b/drivers/usb/misc/cytherm.c
--- a/drivers/usb/misc/cytherm.c
+++ b/drivers/usb/misc/cytherm.c
@@ -85,7 +85,7 @@ static int vendor_command(struct usb_dev
 #define BRIGHTNESS 0x2c     /* RAM location for brightness value */
 #define BRIGHTNESS_SEM 0x2b /* RAM location for brightness semaphore */
 
-static ssize_t show_brightness(struct device *dev, char *buf)
+static ssize_t show_brightness(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct usb_interface *intf = to_usb_interface(dev);    
 	struct usb_cytherm *cytherm = usb_get_intfdata(intf);     
@@ -93,7 +93,7 @@ static ssize_t show_brightness(struct de
 	return sprintf(buf, "%i", cytherm->brightness);
 }
 
-static ssize_t set_brightness(struct device *dev, const char *buf, 
+static ssize_t set_brightness(struct device *dev, struct device_attribute *attr, const char *buf,
 			      size_t count)
 {
 	struct usb_interface *intf = to_usb_interface(dev);
@@ -138,7 +138,7 @@ static DEVICE_ATTR(brightness, S_IRUGO |
 #define TEMP 0x33 /* RAM location for temperature */
 #define SIGN 0x34 /* RAM location for temperature sign */
 
-static ssize_t show_temp(struct device *dev, char *buf)
+static ssize_t show_temp(struct device *dev, struct device_attribute *attr, char *buf)
 {
 
 	struct usb_interface *intf = to_usb_interface(dev);
@@ -174,7 +174,7 @@ static ssize_t show_temp(struct device *
 }
 
 
-static ssize_t set_temp(struct device *dev, const char *buf, size_t count)
+static ssize_t set_temp(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	return count;
 }
@@ -184,7 +184,7 @@ static DEVICE_ATTR(temp, S_IRUGO, show_t
 
 #define BUTTON 0x7a
 
-static ssize_t show_button(struct device *dev, char *buf)
+static ssize_t show_button(struct device *dev, struct device_attribute *attr, char *buf)
 {
 
 	struct usb_interface *intf = to_usb_interface(dev);
@@ -215,7 +215,7 @@ static ssize_t show_button(struct device
 }
 
 
-static ssize_t set_button(struct device *dev, const char *buf, size_t count)
+static ssize_t set_button(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	return count;
 }
@@ -223,7 +223,7 @@ static ssize_t set_button(struct device 
 static DEVICE_ATTR(button, S_IRUGO, show_button, set_button);
 
 
-static ssize_t show_port0(struct device *dev, char *buf)
+static ssize_t show_port0(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct usb_interface *intf = to_usb_interface(dev);
 	struct usb_cytherm *cytherm = usb_get_intfdata(intf);
@@ -249,7 +249,7 @@ static ssize_t show_port0(struct device 
 }
 
 
-static ssize_t set_port0(struct device *dev, const char *buf, size_t count)
+static ssize_t set_port0(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct usb_interface *intf = to_usb_interface(dev);
 	struct usb_cytherm *cytherm = usb_get_intfdata(intf);
@@ -283,7 +283,7 @@ static ssize_t set_port0(struct device *
 
 static DEVICE_ATTR(port0, S_IRUGO | S_IWUSR | S_IWGRP, show_port0, set_port0);
 
-static ssize_t show_port1(struct device *dev, char *buf)
+static ssize_t show_port1(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct usb_interface *intf = to_usb_interface(dev);
 	struct usb_cytherm *cytherm = usb_get_intfdata(intf);
@@ -309,7 +309,7 @@ static ssize_t show_port1(struct device 
 }
 
 
-static ssize_t set_port1(struct device *dev, const char *buf, size_t count)
+static ssize_t set_port1(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct usb_interface *intf = to_usb_interface(dev);
 	struct usb_cytherm *cytherm = usb_get_intfdata(intf);
diff --git a/drivers/usb/misc/idmouse.c b/drivers/usb/misc/idmouse.c
--- a/drivers/usb/misc/idmouse.c
+++ b/drivers/usb/misc/idmouse.c
@@ -1,4 +1,4 @@
-/* Siemens ID Mouse driver v0.5
+/* Siemens ID Mouse driver v0.6
 
   This program is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public License as
@@ -11,6 +11,9 @@
   Derived from the USB Skeleton driver 1.1,
   Copyright (C) 2003 Greg Kroah-Hartman (greg@kroah.com)
 
+  Additional information provided by Martin Reising
+  <Martin.Reising@natural-computing.de>
+
 */
 
 #include <linux/config.h>
@@ -25,29 +28,44 @@
 #include <asm/uaccess.h>
 #include <linux/usb.h>
 
+/* image constants */
 #define WIDTH 225
-#define HEIGHT 288
-#define HEADER "P5 225 288 255 "
+#define HEIGHT 289
+#define HEADER "P5 225 289 255 "
 #define IMGSIZE ((WIDTH * HEIGHT) + sizeof(HEADER)-1)
 
-/* Version Information */
-#define DRIVER_VERSION "0.5"
+/* version information */
+#define DRIVER_VERSION "0.6"
 #define DRIVER_SHORT   "idmouse"
 #define DRIVER_AUTHOR  "Florian 'Floe' Echtler <echtler@fs.tum.de>"
 #define DRIVER_DESC    "Siemens ID Mouse FingerTIP Sensor Driver"
 
-/* Siemens ID Mouse */
-#define USB_IDMOUSE_VENDOR_ID  0x0681
-#define USB_IDMOUSE_PRODUCT_ID 0x0005
-
-/* we still need a minor number */
+/* minor number for misc USB devices */
 #define USB_IDMOUSE_MINOR_BASE 132
 
+/* vendor and device IDs */
+#define ID_SIEMENS 0x0681
+#define ID_IDMOUSE 0x0005
+#define ID_CHERRY  0x0010
+
+/* device ID table */
 static struct usb_device_id idmouse_table[] = {
-	{USB_DEVICE(USB_IDMOUSE_VENDOR_ID, USB_IDMOUSE_PRODUCT_ID)},
-	{} /* null entry at the end */
+	{USB_DEVICE(ID_SIEMENS, ID_IDMOUSE)}, /* Siemens ID Mouse (Professional) */
+	{USB_DEVICE(ID_SIEMENS, ID_CHERRY )}, /* Cherry FingerTIP ID Board       */
+	{}                                    /* terminating null entry          */
 };
 
+/* sensor commands */
+#define FTIP_RESET   0x20
+#define FTIP_ACQUIRE 0x21
+#define FTIP_RELEASE 0x22
+#define FTIP_BLINK   0x23  /* LSB of value = blink pulse width */
+#define FTIP_SCROLL  0x24
+
+#define ftip_command(dev, command, value, index) \
+	usb_control_msg (dev->udev, usb_sndctrlpipe (dev->udev, 0), command, \
+	USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT, value, index, NULL, 0, 1000)
+
 MODULE_DEVICE_TABLE(usb, idmouse_table);
 
 /* structure to hold all of our device specific stuff */
@@ -57,7 +75,8 @@ struct usb_idmouse {
 	struct usb_interface *interface; /* the interface for this device */
 
 	unsigned char *bulk_in_buffer; /* the buffer to receive data */
-	size_t bulk_in_size; /* the size of the receive buffer */
+	size_t bulk_in_size; /* the maximum bulk packet size */
+	size_t orig_bi_size; /* same as above, but reported by the device */
 	__u8 bulk_in_endpointAddr; /* the address of the bulk in endpoint */
 
 	int open; /* if the port is open or not */
@@ -103,7 +122,7 @@ static struct usb_driver idmouse_driver 
 	.id_table = idmouse_table,
 };
 
-// prevent races between open() and disconnect()
+/* prevent races between open() and disconnect() */
 static DECLARE_MUTEX(disconnect_sem);
 
 static int idmouse_create_image(struct usb_idmouse *dev)
@@ -112,42 +131,34 @@ static int idmouse_create_image(struct u
 	int bulk_read = 0;
 	int result = 0;
 
-	if (dev->bulk_in_size < sizeof(HEADER))
-		return -ENOMEM;
-
-	memcpy(dev->bulk_in_buffer,HEADER,sizeof(HEADER)-1);
+	memcpy(dev->bulk_in_buffer, HEADER, sizeof(HEADER)-1);
 	bytes_read += sizeof(HEADER)-1;
 
-	/* Dump the setup packets. Yes, they are uncommented, simply 
-	   because they were sniffed under Windows using SnoopyPro.
-	   I _guess_ that 0x22 is a kind of reset command and 0x21 
-	   means init..
-	*/
-	result = usb_control_msg (dev->udev, usb_sndctrlpipe (dev->udev, 0),
-				0x21, 0x42, 0x0001, 0x0002, NULL, 0, 1000);
+	/* reset the device and set a fast blink rate */
+	result = ftip_command(dev, FTIP_RELEASE, 0, 0);
 	if (result < 0)
-		return result;
-	result = usb_control_msg (dev->udev, usb_sndctrlpipe (dev->udev, 0),
-				0x20, 0x42, 0x0001, 0x0002, NULL, 0, 1000);
-	if (result < 0)
-		return result;
-	result = usb_control_msg (dev->udev, usb_sndctrlpipe (dev->udev, 0),
-				0x22, 0x42, 0x0000, 0x0002, NULL, 0, 1000);
+		goto reset;
+	result = ftip_command(dev, FTIP_BLINK,   1, 0);
 	if (result < 0)
-		return result;
+		goto reset;
 
-	result = usb_control_msg (dev->udev, usb_sndctrlpipe (dev->udev, 0),
-				0x21, 0x42, 0x0001, 0x0002, NULL, 0, 1000);
+	/* initialize the sensor - sending this command twice */
+	/* significantly reduces the rate of failed reads     */
+	result = ftip_command(dev, FTIP_ACQUIRE, 0, 0);
 	if (result < 0)
-		return result;
-	result = usb_control_msg (dev->udev, usb_sndctrlpipe (dev->udev, 0),
-				0x20, 0x42, 0x0001, 0x0002, NULL, 0, 1000);
+		goto reset;
+	result = ftip_command(dev, FTIP_ACQUIRE, 0, 0);
 	if (result < 0)
-		return result;
-	result = usb_control_msg (dev->udev, usb_sndctrlpipe (dev->udev, 0),
-				0x20, 0x42, 0x0000, 0x0002, NULL, 0, 1000);
+		goto reset;
+
+	/* start the readout - sending this command twice */
+	/* presumably enables the high dynamic range mode */
+	result = ftip_command(dev, FTIP_RESET,   0, 0);
 	if (result < 0)
-		return result;
+		goto reset;
+	result = ftip_command(dev, FTIP_RESET,   0, 0);
+	if (result < 0)
+		goto reset;
 
 	/* loop over a blocking bulk read to get data from the device */
 	while (bytes_read < IMGSIZE) {
@@ -155,22 +166,40 @@ static int idmouse_create_image(struct u
 				usb_rcvbulkpipe (dev->udev, dev->bulk_in_endpointAddr),
 				dev->bulk_in_buffer + bytes_read,
 				dev->bulk_in_size, &bulk_read, 5000);
-		if (result < 0)
-			return result;
-		if (signal_pending(current))
-			return -EINTR;
+		if (result < 0) {
+			/* Maybe this error was caused by the increased packet size? */
+			/* Reset to the original value and tell userspace to retry.  */
+			if (dev->bulk_in_size != dev->orig_bi_size) {
+				dev->bulk_in_size = dev->orig_bi_size;
+				result = -EAGAIN;
+			}
+			break;
+		}
+		if (signal_pending(current)) {
+			result = -EINTR;
+			break;
+		}
 		bytes_read += bulk_read;
 	}
 
 	/* reset the device */
-	result = usb_control_msg (dev->udev, usb_sndctrlpipe (dev->udev, 0),
-				0x22, 0x42, 0x0000, 0x0002, NULL, 0, 1000);
-	if (result < 0)
-		return result;
+reset:
+	ftip_command(dev, FTIP_RELEASE, 0, 0);
+
+	/* check for valid image */
+	/* right border should be black (0x00) */
+	for (bytes_read = sizeof(HEADER)-1 + WIDTH-1; bytes_read < IMGSIZE; bytes_read += WIDTH)
+		if (dev->bulk_in_buffer[bytes_read] != 0x00)
+			return -EAGAIN;
+
+	/* lower border should be white (0xFF) */
+	for (bytes_read = IMGSIZE-WIDTH; bytes_read < IMGSIZE-1; bytes_read++)
+		if (dev->bulk_in_buffer[bytes_read] != 0xFF)
+			return -EAGAIN;
 
-	/* should be IMGSIZE == 64815 */
+	/* should be IMGSIZE == 65040 */
 	dbg("read %d bytes fingerprint data", bytes_read);
-	return 0;
+	return result;
 }
 
 static inline void idmouse_delete(struct usb_idmouse *dev)
@@ -282,10 +311,10 @@ static ssize_t idmouse_read(struct file 
 
 	dev = (struct usb_idmouse *) file->private_data;
 
-	// lock this object
+	/* lock this object */
 	down (&dev->sem);
 
-	// verify that the device wasn't unplugged
+	/* verify that the device wasn't unplugged */
 	if (!dev->present) {
 		up (&dev->sem);
 		return -ENODEV;
@@ -296,8 +325,7 @@ static ssize_t idmouse_read(struct file 
 		return 0;
 	}
 
-	if (count > IMGSIZE - *ppos)
-		count = IMGSIZE - *ppos;
+	count = min ((loff_t)count, IMGSIZE - (*ppos));
 
 	if (copy_to_user (buffer, dev->bulk_in_buffer + *ppos, count)) {
 		result = -EFAULT;
@@ -306,7 +334,7 @@ static ssize_t idmouse_read(struct file 
 		*ppos += count;
 	}
 
-	// unlock the device 
+	/* unlock the device */
 	up(&dev->sem);
 	return result;
 }
@@ -318,7 +346,6 @@ static int idmouse_probe(struct usb_inte
 	struct usb_idmouse *dev = NULL;
 	struct usb_host_interface *iface_desc;
 	struct usb_endpoint_descriptor *endpoint;
-	size_t buffer_size;
 	int result;
 
 	/* check if we have gotten the data or the hid interface */
@@ -344,11 +371,11 @@ static int idmouse_probe(struct usb_inte
 		USB_ENDPOINT_XFER_BULK)) {
 
 		/* we found a bulk in endpoint */
-		buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
-		dev->bulk_in_size = buffer_size;
+		dev->orig_bi_size = le16_to_cpu(endpoint->wMaxPacketSize);
+		dev->bulk_in_size = 0x200; /* works _much_ faster */
 		dev->bulk_in_endpointAddr = endpoint->bEndpointAddress;
 		dev->bulk_in_buffer =
-			kmalloc(IMGSIZE + buffer_size, GFP_KERNEL);
+			kmalloc(IMGSIZE + dev->bulk_in_size, GFP_KERNEL);
 
 		if (!dev->bulk_in_buffer) {
 			err("Unable to allocate input buffer.");
diff --git a/drivers/usb/misc/ldusb.c b/drivers/usb/misc/ldusb.c
new file mode 100644
--- /dev/null
+++ b/drivers/usb/misc/ldusb.c
@@ -0,0 +1,799 @@
+/**
+ * Generic USB driver for report based interrupt in/out devices
+ * like LD Didactic's USB devices. LD Didactic's USB devices are
+ * HID devices which do not use HID report definitons (they use
+ * raw interrupt in and our reports only for communication).
+ *
+ * This driver uses a ring buffer for time critical reading of
+ * interrupt in reports and provides read and write methods for
+ * raw interrupt reports (similar to the Windows HID driver).
+ * Devices based on the book USB COMPLETE by Jan Axelson may need
+ * such a compatibility to the Windows HID driver.
+ *
+ * Copyright (C) 2005 Michael Hund <mhund@ld-didactic.de>
+ *
+ *	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.
+ *
+ * Derived from Lego USB Tower driver
+ * Copyright (C) 2003 David Glance <advidgsf@sourceforge.net>
+ *		 2001-2004 Juergen Stuber <starblue@users.sourceforge.net>
+ *
+ * V0.1  (mh) Initial version
+ * V0.11 (mh) Added raw support for HID 1.0 devices (no interrupt out endpoint)
+ * V0.12 (mh) Added kmalloc check for string buffer
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+
+#include <asm/uaccess.h>
+#include <linux/input.h>
+#include <linux/usb.h>
+#include <linux/poll.h>
+
+/* Define these values to match your devices */
+#define USB_VENDOR_ID_LD		0x0f11	/* USB Vendor ID of LD Didactic GmbH */
+#define USB_DEVICE_ID_CASSY		0x1000	/* USB Product ID for all CASSY-S modules */
+#define USB_DEVICE_ID_POCKETCASSY	0x1010	/* USB Product ID for Pocket-CASSY */
+#define USB_DEVICE_ID_MOBILECASSY	0x1020	/* USB Product ID for Mobile-CASSY */
+#define USB_DEVICE_ID_JWM		0x1080	/* USB Product ID for Joule and Wattmeter */
+#define USB_DEVICE_ID_DMMP		0x1081	/* USB Product ID for Digital Multimeter P (reserved) */
+#define USB_DEVICE_ID_UMIP		0x1090	/* USB Product ID for UMI P */
+#define USB_DEVICE_ID_VIDEOCOM		0x1200	/* USB Product ID for VideoCom */
+#define USB_DEVICE_ID_COM3LAB		0x2000	/* USB Product ID for COM3LAB */
+#define USB_DEVICE_ID_TELEPORT		0x2010	/* USB Product ID for Terminal Adapter */
+#define USB_DEVICE_ID_NETWORKANALYSER	0x2020	/* USB Product ID for Network Analyser */
+#define USB_DEVICE_ID_POWERCONTROL	0x2030	/* USB Product ID for Controlling device for Power Electronics */
+
+#define USB_VENDOR_ID_VERNIER		0x08f7
+#define USB_DEVICE_ID_VERNIER_LABPRO	0x0001
+#define USB_DEVICE_ID_VERNIER_GOTEMP	0x0002
+#define USB_DEVICE_ID_VERNIER_SKIP	0x0003
+#define USB_DEVICE_ID_VERNIER_CYCLOPS	0x0004
+
+
+#ifdef CONFIG_USB_DYNAMIC_MINORS
+#define USB_LD_MINOR_BASE	0
+#else
+#define USB_LD_MINOR_BASE	176
+#endif
+
+/* table of devices that work with this driver */
+static struct usb_device_id ld_usb_table [] = {
+	{ USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_CASSY) },
+	{ USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_POCKETCASSY) },
+	{ USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_MOBILECASSY) },
+	{ USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_JWM) },
+	{ USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_DMMP) },
+	{ USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_UMIP) },
+	{ USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_VIDEOCOM) },
+	{ USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_COM3LAB) },
+	{ USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_TELEPORT) },
+	{ USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_NETWORKANALYSER) },
+	{ USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_POWERCONTROL) },
+	{ USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_LABPRO) },
+	{ USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_GOTEMP) },
+	{ USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_SKIP) },
+	{ USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_CYCLOPS) },
+	{ }					/* Terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, ld_usb_table);
+MODULE_VERSION("V0.12");
+MODULE_AUTHOR("Michael Hund <mhund@ld-didactic.de>");
+MODULE_DESCRIPTION("LD USB Driver");
+MODULE_LICENSE("GPL");
+MODULE_SUPPORTED_DEVICE("LD USB Devices");
+
+#ifdef CONFIG_USB_DEBUG
+	static int debug = 1;
+#else
+	static int debug = 0;
+#endif
+
+/* Use our own dbg macro */
+#define dbg_info(dev, format, arg...) do { if (debug) dev_info(dev , format , ## arg); } while (0)
+
+/* Module parameters */
+module_param(debug, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(debug, "Debug enabled or not");
+
+/* All interrupt in transfers are collected in a ring buffer to
+ * avoid racing conditions and get better performance of the driver.
+ */
+static int ring_buffer_size = 128;
+module_param(ring_buffer_size, int, 0);
+MODULE_PARM_DESC(ring_buffer_size, "Read ring buffer size in reports");
+
+/* The write_buffer can contain more than one interrupt out transfer.
+ */
+static int write_buffer_size = 10;
+module_param(write_buffer_size, int, 0);
+MODULE_PARM_DESC(write_buffer_size, "Write buffer size in reports");
+
+/* As of kernel version 2.6.4 ehci-hcd uses an
+ * "only one interrupt transfer per frame" shortcut
+ * to simplify the scheduling of periodic transfers.
+ * This conflicts with our standard 1ms intervals for in and out URBs.
+ * We use default intervals of 2ms for in and 2ms for out transfers,
+ * which should be fast enough.
+ * Increase the interval to allow more devices that do interrupt transfers,
+ * or set to 1 to use the standard interval from the endpoint descriptors.
+ */
+static int min_interrupt_in_interval = 2;
+module_param(min_interrupt_in_interval, int, 0);
+MODULE_PARM_DESC(min_interrupt_in_interval, "Minimum interrupt in interval in ms");
+
+static int min_interrupt_out_interval = 2;
+module_param(min_interrupt_out_interval, int, 0);
+MODULE_PARM_DESC(min_interrupt_out_interval, "Minimum interrupt out interval in ms");
+
+/* Structure to hold all of our device specific stuff */
+struct ld_usb {
+	struct semaphore	sem;		/* locks this structure */
+	struct usb_interface*	intf;		/* save off the usb interface pointer */
+
+	int			open_count;	/* number of times this port has been opened */
+
+	char*			ring_buffer;
+	unsigned int		ring_head;
+	unsigned int		ring_tail;
+
+	wait_queue_head_t	read_wait;
+	wait_queue_head_t	write_wait;
+
+	char*			interrupt_in_buffer;
+	struct usb_endpoint_descriptor* interrupt_in_endpoint;
+	struct urb*		interrupt_in_urb;
+	int			interrupt_in_interval;
+	size_t			interrupt_in_endpoint_size;
+	int			interrupt_in_running;
+	int			interrupt_in_done;
+
+	char*			interrupt_out_buffer;
+	struct usb_endpoint_descriptor* interrupt_out_endpoint;
+	struct urb*		interrupt_out_urb;
+	int			interrupt_out_interval;
+	size_t			interrupt_out_endpoint_size;
+	int			interrupt_out_busy;
+};
+
+/* prevent races between open() and disconnect() */
+static DECLARE_MUTEX(disconnect_sem);
+
+static struct usb_driver ld_usb_driver;
+
+/**
+ *	ld_usb_abort_transfers
+ *      aborts transfers and frees associated data structures
+ */
+static void ld_usb_abort_transfers(struct ld_usb *dev)
+{
+	/* shutdown transfer */
+	if (dev->interrupt_in_running) {
+		dev->interrupt_in_running = 0;
+		if (dev->intf)
+			usb_kill_urb(dev->interrupt_in_urb);
+	}
+	if (dev->interrupt_out_busy)
+		if (dev->intf)
+			usb_kill_urb(dev->interrupt_out_urb);
+}
+
+/**
+ *	ld_usb_delete
+ */
+static void ld_usb_delete(struct ld_usb *dev)
+{
+	ld_usb_abort_transfers(dev);
+
+	/* free data structures */
+	usb_free_urb(dev->interrupt_in_urb);
+	usb_free_urb(dev->interrupt_out_urb);
+	kfree(dev->ring_buffer);
+	kfree(dev->interrupt_in_buffer);
+	kfree(dev->interrupt_out_buffer);
+	kfree(dev);
+}
+
+/**
+ *	ld_usb_interrupt_in_callback
+ */
+static void ld_usb_interrupt_in_callback(struct urb *urb, struct pt_regs *regs)
+{
+	struct ld_usb *dev = urb->context;
+	size_t *actual_buffer;
+	unsigned int next_ring_head;
+	int retval;
+
+	if (urb->status) {
+		if (urb->status == -ENOENT ||
+		    urb->status == -ECONNRESET ||
+		    urb->status == -ESHUTDOWN) {
+			goto exit;
+		} else {
+			dbg_info(&dev->intf->dev, "%s: nonzero status received: %d\n",
+				 __FUNCTION__, urb->status);
+			goto resubmit; /* maybe we can recover */
+		}
+	}
+
+	if (urb->actual_length > 0) {
+		next_ring_head = (dev->ring_head+1) % ring_buffer_size;
+		if (next_ring_head != dev->ring_tail) {
+			actual_buffer = (size_t*)(dev->ring_buffer + dev->ring_head*(sizeof(size_t)+dev->interrupt_in_endpoint_size));
+			/* actual_buffer gets urb->actual_length + interrupt_in_buffer */
+			*actual_buffer = urb->actual_length;
+			memcpy(actual_buffer+1, dev->interrupt_in_buffer, urb->actual_length);
+			dev->ring_head = next_ring_head;
+			dbg_info(&dev->intf->dev, "%s: received %d bytes\n",
+				 __FUNCTION__, urb->actual_length);
+		} else
+			dev_warn(&dev->intf->dev,
+				 "Ring buffer overflow, %d bytes dropped\n",
+				 urb->actual_length);
+	}
+
+resubmit:
+	/* resubmit if we're still running */
+	if (dev->interrupt_in_running && dev->intf) {
+		retval = usb_submit_urb(dev->interrupt_in_urb, GFP_ATOMIC);
+		if (retval)
+			dev_err(&dev->intf->dev,
+				"usb_submit_urb failed (%d)\n", retval);
+	}
+
+exit:
+	dev->interrupt_in_done = 1;
+	wake_up_interruptible(&dev->read_wait);
+}
+
+/**
+ *	ld_usb_interrupt_out_callback
+ */
+static void ld_usb_interrupt_out_callback(struct urb *urb, struct pt_regs *regs)
+{
+	struct ld_usb *dev = urb->context;
+
+	/* sync/async unlink faults aren't errors */
+	if (urb->status && !(urb->status == -ENOENT ||
+			     urb->status == -ECONNRESET ||
+			     urb->status == -ESHUTDOWN))
+		dbg_info(&dev->intf->dev,
+			 "%s - nonzero write interrupt status received: %d\n",
+			 __FUNCTION__, urb->status);
+
+	dev->interrupt_out_busy = 0;
+	wake_up_interruptible(&dev->write_wait);
+}
+
+/**
+ *	ld_usb_open
+ */
+static int ld_usb_open(struct inode *inode, struct file *file)
+{
+	struct ld_usb *dev;
+	int subminor;
+	int retval = 0;
+	struct usb_interface *interface;
+
+	nonseekable_open(inode, file);
+	subminor = iminor(inode);
+
+	down(&disconnect_sem);
+
+	interface = usb_find_interface(&ld_usb_driver, subminor);
+
+	if (!interface) {
+		err("%s - error, can't find device for minor %d\n",
+		     __FUNCTION__, subminor);
+		retval = -ENODEV;
+		goto unlock_disconnect_exit;
+	}
+
+	dev = usb_get_intfdata(interface);
+
+	if (!dev) {
+		retval = -ENODEV;
+		goto unlock_disconnect_exit;
+	}
+
+	/* lock this device */
+	if (down_interruptible(&dev->sem)) {
+		retval = -ERESTARTSYS;
+		goto unlock_disconnect_exit;
+	}
+
+	/* allow opening only once */
+	if (dev->open_count) {
+		retval = -EBUSY;
+		goto unlock_exit;
+	}
+	dev->open_count = 1;
+
+	/* initialize in direction */
+	dev->ring_head = 0;
+	dev->ring_tail = 0;
+	usb_fill_int_urb(dev->interrupt_in_urb,
+			 interface_to_usbdev(interface),
+			 usb_rcvintpipe(interface_to_usbdev(interface),
+					dev->interrupt_in_endpoint->bEndpointAddress),
+			 dev->interrupt_in_buffer,
+			 dev->interrupt_in_endpoint_size,
+			 ld_usb_interrupt_in_callback,
+			 dev,
+			 dev->interrupt_in_interval);
+
+	dev->interrupt_in_running = 1;
+	dev->interrupt_in_done = 0;
+
+	retval = usb_submit_urb(dev->interrupt_in_urb, GFP_KERNEL);
+	if (retval) {
+		dev_err(&interface->dev, "Couldn't submit interrupt_in_urb %d\n", retval);
+		dev->interrupt_in_running = 0;
+		dev->open_count = 0;
+		goto unlock_exit;
+	}
+
+	/* save device in the file's private structure */
+	file->private_data = dev;
+
+unlock_exit:
+	up(&dev->sem);
+
+unlock_disconnect_exit:
+	up(&disconnect_sem);
+
+	return retval;
+}
+
+/**
+ *	ld_usb_release
+ */
+static int ld_usb_release(struct inode *inode, struct file *file)
+{
+	struct ld_usb *dev;
+	int retval = 0;
+
+	dev = file->private_data;
+
+	if (dev == NULL) {
+		retval = -ENODEV;
+		goto exit;
+	}
+
+	if (down_interruptible(&dev->sem)) {
+		retval = -ERESTARTSYS;
+		goto exit;
+	}
+
+	if (dev->open_count != 1) {
+		retval = -ENODEV;
+		goto unlock_exit;
+	}
+	if (dev->intf == NULL) {
+		/* the device was unplugged before the file was released */
+		up(&dev->sem);
+		/* unlock here as ld_usb_delete frees dev */
+		ld_usb_delete(dev);
+		goto exit;
+	}
+
+	/* wait until write transfer is finished */
+	if (dev->interrupt_out_busy)
+		wait_event_interruptible_timeout(dev->write_wait, !dev->interrupt_out_busy, 2 * HZ);
+	ld_usb_abort_transfers(dev);
+	dev->open_count = 0;
+
+unlock_exit:
+	up(&dev->sem);
+
+exit:
+	return retval;
+}
+
+/**
+ *	ld_usb_poll
+ */
+static unsigned int ld_usb_poll(struct file *file, poll_table *wait)
+{
+	struct ld_usb *dev;
+	unsigned int mask = 0;
+
+	dev = file->private_data;
+
+	poll_wait(file, &dev->read_wait, wait);
+	poll_wait(file, &dev->write_wait, wait);
+
+	if (dev->ring_head != dev->ring_tail)
+		mask |= POLLIN | POLLRDNORM;
+	if (!dev->interrupt_out_busy)
+		mask |= POLLOUT | POLLWRNORM;
+
+	return mask;
+}
+
+/**
+ *	ld_usb_read
+ */
+static ssize_t ld_usb_read(struct file *file, char __user *buffer, size_t count,
+			   loff_t *ppos)
+{
+	struct ld_usb *dev;
+	size_t *actual_buffer;
+	size_t bytes_to_read;
+	int retval = 0;
+
+	dev = file->private_data;
+
+	/* verify that we actually have some data to read */
+	if (count == 0)
+		goto exit;
+
+	/* lock this object */
+	if (down_interruptible(&dev->sem)) {
+		retval = -ERESTARTSYS;
+		goto exit;
+	}
+
+	/* verify that the device wasn't unplugged */
+	if (dev->intf == NULL) {
+		retval = -ENODEV;
+		err("No device or device unplugged %d\n", retval);
+		goto unlock_exit;
+	}
+
+	/* wait for data */
+	if (dev->ring_head == dev->ring_tail) {
+		if (file->f_flags & O_NONBLOCK) {
+			retval = -EAGAIN;
+			goto unlock_exit;
+		}
+		retval = wait_event_interruptible(dev->read_wait, dev->interrupt_in_done);
+		if (retval < 0)
+			goto unlock_exit;
+	}
+
+	/* actual_buffer contains actual_length + interrupt_in_buffer */
+	actual_buffer = (size_t*)(dev->ring_buffer + dev->ring_tail*(sizeof(size_t)+dev->interrupt_in_endpoint_size));
+	bytes_to_read = min(count, *actual_buffer);
+	if (bytes_to_read < *actual_buffer)
+		dev_warn(&dev->intf->dev, "Read buffer overflow, %d bytes dropped\n",
+			 *actual_buffer-bytes_to_read);
+
+	/* copy one interrupt_in_buffer from ring_buffer into userspace */
+	if (copy_to_user(buffer, actual_buffer+1, bytes_to_read)) {
+		retval = -EFAULT;
+		goto unlock_exit;
+	}
+	dev->ring_tail = (dev->ring_tail+1) % ring_buffer_size;
+
+	retval = bytes_to_read;
+
+unlock_exit:
+	/* unlock the device */
+	up(&dev->sem);
+
+exit:
+	return retval;
+}
+
+/**
+ *	ld_usb_write
+ */
+static ssize_t ld_usb_write(struct file *file, const char __user *buffer,
+			    size_t count, loff_t *ppos)
+{
+	struct ld_usb *dev;
+	size_t bytes_to_write;
+	int retval = 0;
+
+	dev = file->private_data;
+
+	/* verify that we actually have some data to write */
+	if (count == 0)
+		goto exit;
+
+	/* lock this object */
+	if (down_interruptible(&dev->sem)) {
+		retval = -ERESTARTSYS;
+		goto exit;
+	}
+
+	/* verify that the device wasn't unplugged */
+	if (dev->intf == NULL) {
+		retval = -ENODEV;
+		err("No device or device unplugged %d\n", retval);
+		goto unlock_exit;
+	}
+
+	/* wait until previous transfer is finished */
+	if (dev->interrupt_out_busy) {
+		if (file->f_flags & O_NONBLOCK) {
+			retval = -EAGAIN;
+			goto unlock_exit;
+		}
+		retval = wait_event_interruptible(dev->write_wait, !dev->interrupt_out_busy);
+		if (retval < 0) {
+			goto unlock_exit;
+		}
+	}
+
+	/* write the data into interrupt_out_buffer from userspace */
+	bytes_to_write = min(count, write_buffer_size*dev->interrupt_out_endpoint_size);
+	if (bytes_to_write < count)
+		dev_warn(&dev->intf->dev, "Write buffer overflow, %d bytes dropped\n",count-bytes_to_write);
+	dbg_info(&dev->intf->dev, "%s: count = %d, bytes_to_write = %d\n", __FUNCTION__, count, bytes_to_write);
+
+	if (copy_from_user(dev->interrupt_out_buffer, buffer, bytes_to_write)) {
+		retval = -EFAULT;
+		goto unlock_exit;
+	}
+
+	if (dev->interrupt_out_endpoint == NULL) {
+		/* try HID_REQ_SET_REPORT=9 on control_endpoint instead of interrupt_out_endpoint */
+		retval = usb_control_msg(interface_to_usbdev(dev->intf),
+					 usb_sndctrlpipe(interface_to_usbdev(dev->intf), 0),
+					 9,
+					 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
+					 1 << 8, 0,
+					 dev->interrupt_out_buffer,
+					 bytes_to_write,
+					 USB_CTRL_SET_TIMEOUT * HZ);
+		if (retval < 0)
+			err("Couldn't submit HID_REQ_SET_REPORT %d\n", retval);
+		goto unlock_exit;
+	}
+
+	/* send off the urb */
+	usb_fill_int_urb(dev->interrupt_out_urb,
+			 interface_to_usbdev(dev->intf),
+			 usb_sndintpipe(interface_to_usbdev(dev->intf),
+					dev->interrupt_out_endpoint->bEndpointAddress),
+			 dev->interrupt_out_buffer,
+			 bytes_to_write,
+			 ld_usb_interrupt_out_callback,
+			 dev,
+			 dev->interrupt_out_interval);
+
+	dev->interrupt_out_busy = 1;
+	wmb();
+
+	retval = usb_submit_urb(dev->interrupt_out_urb, GFP_KERNEL);
+	if (retval) {
+		dev->interrupt_out_busy = 0;
+		err("Couldn't submit interrupt_out_urb %d\n", retval);
+		goto unlock_exit;
+	}
+	retval = bytes_to_write;
+
+unlock_exit:
+	/* unlock the device */
+	up(&dev->sem);
+
+exit:
+	return retval;
+}
+
+/* file operations needed when we register this driver */
+static struct file_operations ld_usb_fops = {
+	.owner =	THIS_MODULE,
+	.read  =	ld_usb_read,
+	.write =	ld_usb_write,
+	.open =		ld_usb_open,
+	.release =	ld_usb_release,
+	.poll =		ld_usb_poll,
+};
+
+/*
+ * usb class driver info in order to get a minor number from the usb core,
+ * and to have the device registered with devfs and the driver core
+ */
+static struct usb_class_driver ld_usb_class = {
+	.name =		"ldusb%d",
+	.fops =		&ld_usb_fops,
+	.minor_base =	USB_LD_MINOR_BASE,
+};
+
+/**
+ *	ld_usb_probe
+ *
+ *	Called by the usb core when a new device is connected that it thinks
+ *	this driver might be interested in.
+ */
+static int ld_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
+{
+	struct usb_device *udev = interface_to_usbdev(intf);
+	struct ld_usb *dev = NULL;
+	struct usb_host_interface *iface_desc;
+	struct usb_endpoint_descriptor *endpoint;
+	char *buffer;
+	int i;
+	int retval = -ENOMEM;
+
+	/* allocate memory for our device state and intialize it */
+
+	dev = kmalloc(sizeof(*dev), GFP_KERNEL);
+	if (dev == NULL) {
+		dev_err(&intf->dev, "Out of memory\n");
+		goto exit;
+	}
+	memset(dev, 0x00, sizeof(*dev));
+	init_MUTEX(&dev->sem);
+	dev->intf = intf;
+	init_waitqueue_head(&dev->read_wait);
+	init_waitqueue_head(&dev->write_wait);
+
+	/* workaround for early firmware versions on fast computers */
+	if ((le16_to_cpu(udev->descriptor.idVendor) == USB_VENDOR_ID_LD) &&
+	    ((le16_to_cpu(udev->descriptor.idProduct) == USB_DEVICE_ID_CASSY) ||
+	     (le16_to_cpu(udev->descriptor.idProduct) == USB_DEVICE_ID_COM3LAB)) &&
+	    (le16_to_cpu(udev->descriptor.bcdDevice) <= 0x103)) {
+		buffer = kmalloc(256, GFP_KERNEL);
+		if (buffer == NULL) {
+			dev_err(&intf->dev, "Couldn't allocate string buffer\n");
+			goto error;
+		}
+		/* usb_string makes SETUP+STALL to leave always ControlReadLoop */
+		usb_string(udev, 255, buffer, 256);
+		kfree(buffer);
+	}
+
+	iface_desc = intf->cur_altsetting;
+
+	/* set up the endpoint information */
+	for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
+		endpoint = &iface_desc->endpoint[i].desc;
+
+		if (((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) &&
+		    ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT)) {
+			dev->interrupt_in_endpoint = endpoint;
+		}
+
+		if (((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) &&
+		    ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT)) {
+			dev->interrupt_out_endpoint = endpoint;
+		}
+	}
+	if (dev->interrupt_in_endpoint == NULL) {
+		dev_err(&intf->dev, "Interrupt in endpoint not found\n");
+		goto error;
+	}
+	if (dev->interrupt_out_endpoint == NULL)
+		dev_warn(&intf->dev, "Interrupt out endpoint not found (using control endpoint instead)\n");
+
+	dev->interrupt_in_endpoint_size = le16_to_cpu(dev->interrupt_in_endpoint->wMaxPacketSize);
+	dev->ring_buffer = kmalloc(ring_buffer_size*(sizeof(size_t)+dev->interrupt_in_endpoint_size), GFP_KERNEL);
+	if (!dev->ring_buffer) {
+		dev_err(&intf->dev, "Couldn't allocate ring_buffer\n");
+		goto error;
+	}
+	dev->interrupt_in_buffer = kmalloc(dev->interrupt_in_endpoint_size, GFP_KERNEL);
+	if (!dev->interrupt_in_buffer) {
+		dev_err(&intf->dev, "Couldn't allocate interrupt_in_buffer\n");
+		goto error;
+	}
+	dev->interrupt_in_urb = usb_alloc_urb(0, GFP_KERNEL);
+	if (!dev->interrupt_in_urb) {
+		dev_err(&intf->dev, "Couldn't allocate interrupt_in_urb\n");
+		goto error;
+	}
+	dev->interrupt_out_endpoint_size = dev->interrupt_out_endpoint ? le16_to_cpu(dev->interrupt_out_endpoint->wMaxPacketSize) :
+									 udev->descriptor.bMaxPacketSize0;
+	dev->interrupt_out_buffer = kmalloc(write_buffer_size*dev->interrupt_out_endpoint_size, GFP_KERNEL);
+	if (!dev->interrupt_out_buffer) {
+		dev_err(&intf->dev, "Couldn't allocate interrupt_out_buffer\n");
+		goto error;
+	}
+	dev->interrupt_out_urb = usb_alloc_urb(0, GFP_KERNEL);
+	if (!dev->interrupt_out_urb) {
+		dev_err(&intf->dev, "Couldn't allocate interrupt_out_urb\n");
+		goto error;
+	}
+	dev->interrupt_in_interval = min_interrupt_in_interval > dev->interrupt_in_endpoint->bInterval ? min_interrupt_in_interval : dev->interrupt_in_endpoint->bInterval;
+	if (dev->interrupt_out_endpoint)
+		dev->interrupt_out_interval = min_interrupt_out_interval > dev->interrupt_out_endpoint->bInterval ? min_interrupt_out_interval : dev->interrupt_out_endpoint->bInterval;
+
+	/* we can register the device now, as it is ready */
+	usb_set_intfdata(intf, dev);
+
+	retval = usb_register_dev(intf, &ld_usb_class);
+	if (retval) {
+		/* something prevented us from registering this driver */
+		dev_err(&intf->dev, "Not able to get a minor for this device.\n");
+		usb_set_intfdata(intf, NULL);
+		goto error;
+	}
+
+	/* let the user know what node this device is now attached to */
+	dev_info(&intf->dev, "LD USB Device #%d now attached to major %d minor %d\n",
+		(intf->minor - USB_LD_MINOR_BASE), USB_MAJOR, intf->minor);
+
+exit:
+	return retval;
+
+error:
+	ld_usb_delete(dev);
+
+	return retval;
+}
+
+/**
+ *	ld_usb_disconnect
+ *
+ *	Called by the usb core when the device is removed from the system.
+ */
+static void ld_usb_disconnect(struct usb_interface *intf)
+{
+	struct ld_usb *dev;
+	int minor;
+
+	down(&disconnect_sem);
+
+	dev = usb_get_intfdata(intf);
+	usb_set_intfdata(intf, NULL);
+
+	down(&dev->sem);
+
+	minor = intf->minor;
+
+	/* give back our minor */
+	usb_deregister_dev(intf, &ld_usb_class);
+
+	/* if the device is not opened, then we clean up right now */
+	if (!dev->open_count) {
+		up(&dev->sem);
+		ld_usb_delete(dev);
+	} else {
+		dev->intf = NULL;
+		up(&dev->sem);
+	}
+
+	up(&disconnect_sem);
+
+	dev_info(&intf->dev, "LD USB Device #%d now disconnected\n",
+		 (minor - USB_LD_MINOR_BASE));
+}
+
+/* usb specific object needed to register this driver with the usb subsystem */
+static struct usb_driver ld_usb_driver = {
+	.owner =	THIS_MODULE,
+	.name =		"ldusb",
+	.probe =	ld_usb_probe,
+	.disconnect =	ld_usb_disconnect,
+	.id_table =	ld_usb_table,
+};
+
+/**
+ *	ld_usb_init
+ */
+static int __init ld_usb_init(void)
+{
+	int retval;
+
+	/* register this driver with the USB subsystem */
+	retval = usb_register(&ld_usb_driver);
+	if (retval)
+		err("usb_register failed for the "__FILE__" driver. Error number %d\n", retval);
+
+	return retval;
+}
+
+/**
+ *	ld_usb_exit
+ */
+static void __exit ld_usb_exit(void)
+{
+	/* deregister this driver with the USB subsystem */
+	usb_deregister(&ld_usb_driver);
+}
+
+module_init(ld_usb_init);
+module_exit(ld_usb_exit);
+
diff --git a/drivers/usb/misc/phidgetkit.c b/drivers/usb/misc/phidgetkit.c
--- a/drivers/usb/misc/phidgetkit.c
+++ b/drivers/usb/misc/phidgetkit.c
@@ -173,7 +173,7 @@ exit:
 }
 
 #define set_lcd_line(number)	\
-static ssize_t lcd_line_##number(struct device *dev, const char *buf, size_t count)	\
+static ssize_t lcd_line_##number(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)	\
 {											\
 	struct usb_interface *intf = to_usb_interface(dev);				\
 	struct phidget_interfacekit *kit = usb_get_intfdata(intf);			\
@@ -184,7 +184,7 @@ static DEVICE_ATTR(lcd_line_##number, S_
 set_lcd_line(1);
 set_lcd_line(2);
 
-static ssize_t set_backlight(struct device *dev, const char *buf, size_t count)
+static ssize_t set_backlight(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct usb_interface *intf = to_usb_interface(dev);
 	struct phidget_interfacekit *kit = usb_get_intfdata(intf);
@@ -232,7 +232,7 @@ static void remove_lcd_files(struct phid
 	}
 }
 
-static ssize_t enable_lcd_files(struct device *dev, const char *buf, size_t count)
+static ssize_t enable_lcd_files(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct usb_interface *intf = to_usb_interface(dev);
 	struct phidget_interfacekit *kit = usb_get_intfdata(intf);
@@ -307,7 +307,7 @@ resubmit:
 }
 
 #define show_set_output(value)		\
-static ssize_t set_output##value(struct device *dev, const char *buf, 	\
+static ssize_t set_output##value(struct device *dev, struct device_attribute *attr, const char *buf, 	\
 							size_t count)	\
 {									\
 	struct usb_interface *intf = to_usb_interface(dev);		\
@@ -324,7 +324,7 @@ static ssize_t set_output##value(struct 
 	return retval ? retval : count;					\
 }									\
 									\
-static ssize_t show_output##value(struct device *dev, char *buf)	\
+static ssize_t show_output##value(struct device *dev, struct device_attribute *attr, char *buf)	\
 {									\
 	struct usb_interface *intf = to_usb_interface(dev);		\
 	struct phidget_interfacekit *kit = usb_get_intfdata(intf);	\
@@ -343,7 +343,7 @@ show_set_output(7);
 show_set_output(8);	/* should be MAX_INTERFACES - 1 */
 
 #define show_input(value)	\
-static ssize_t show_input##value(struct device *dev, char *buf)	\
+static ssize_t show_input##value(struct device *dev, struct device_attribute *attr, char *buf)	\
 {									\
 	struct usb_interface *intf = to_usb_interface(dev);		\
 	struct phidget_interfacekit *kit = usb_get_intfdata(intf);	\
@@ -362,7 +362,7 @@ show_input(7);
 show_input(8);		/* should be MAX_INTERFACES - 1 */
 
 #define show_sensor(value)	\
-static ssize_t show_sensor##value(struct device *dev, char *buf)	\
+static ssize_t show_sensor##value(struct device *dev, struct device_attribute *attr, char *buf)	\
 {									\
 	struct usb_interface *intf = to_usb_interface(dev);		\
 	struct phidget_interfacekit *kit = usb_get_intfdata(intf);	\
diff --git a/drivers/usb/misc/phidgetservo.c b/drivers/usb/misc/phidgetservo.c
--- a/drivers/usb/misc/phidgetservo.c
+++ b/drivers/usb/misc/phidgetservo.c
@@ -207,7 +207,7 @@ change_position_v20(struct phidget_servo
 }
 
 #define show_set(value)	\
-static ssize_t set_servo##value (struct device *dev,			\
+static ssize_t set_servo##value (struct device *dev, struct device_attribute *attr,			\
 					const char *buf, size_t count)	\
 {									\
 	int degrees, minutes, retval;					\
@@ -233,7 +233,7 @@ static ssize_t set_servo##value (struct 
 	return retval < 0 ? retval : count;				\
 }									\
 									\
-static ssize_t show_servo##value (struct device *dev, char *buf) 	\
+static ssize_t show_servo##value (struct device *dev, struct device_attribute *attr, char *buf) 	\
 {									\
 	struct usb_interface *intf = to_usb_interface (dev);		\
 	struct phidget_servo *servo = usb_get_intfdata (intf);		\
diff --git a/drivers/usb/misc/usbled.c b/drivers/usb/misc/usbled.c
--- a/drivers/usb/misc/usbled.c
+++ b/drivers/usb/misc/usbled.c
@@ -81,14 +81,14 @@ static void change_color(struct usb_led 
 }
 
 #define show_set(value)	\
-static ssize_t show_##value(struct device *dev, char *buf)		\
+static ssize_t show_##value(struct device *dev, struct device_attribute *attr, char *buf)		\
 {									\
 	struct usb_interface *intf = to_usb_interface(dev);		\
 	struct usb_led *led = usb_get_intfdata(intf);			\
 									\
 	return sprintf(buf, "%d\n", led->value);			\
 }									\
-static ssize_t set_##value(struct device *dev, const char *buf, size_t count)	\
+static ssize_t set_##value(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)	\
 {									\
 	struct usb_interface *intf = to_usb_interface(dev);		\
 	struct usb_led *led = usb_get_intfdata(intf);			\
diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c
--- a/drivers/usb/misc/usbtest.c
+++ b/drivers/usb/misc/usbtest.c
@@ -461,7 +461,7 @@ static int perform_sglist (
 
 static unsigned realworld = 1;
 module_param (realworld, uint, 0);
-MODULE_PARM_DESC (realworld, "clear to demand stricter ch9 compliance");
+MODULE_PARM_DESC (realworld, "clear to demand stricter spec compliance");
 
 static int get_altsetting (struct usbtest_dev *dev)
 {
@@ -604,9 +604,8 @@ static int ch9_postconfig (struct usbtes
 				USB_DIR_IN | USB_RECIP_DEVICE,
 				0, 0, dev->buf, 1, USB_CTRL_GET_TIMEOUT);
 		if (retval != 1 || dev->buf [0] != expected) {
-			dev_dbg (&iface->dev,
-				"get config --> %d (%d)\n", retval,
-				expected);
+			dev_dbg (&iface->dev, "get config --> %d %d (1 %d)\n",
+				retval, dev->buf[0], expected);
 			return (retval < 0) ? retval : -EDOM;
 		}
 	}
@@ -1243,7 +1242,7 @@ static int ctrl_out (struct usbtest_dev 
 	char			*what = "?";
 	struct usb_device	*udev;
 	
-	if (length > 0xffff || vary >= length)
+	if (length < 1 || length > 0xffff || vary >= length)
 		return -EINVAL;
 
 	buf = kmalloc(length, SLAB_KERNEL);
@@ -1266,6 +1265,11 @@ static int ctrl_out (struct usbtest_dev 
 				0, 0, buf, len, USB_CTRL_SET_TIMEOUT);
 		if (retval != len) {
 			what = "write";
+			if (retval >= 0) {
+				INFO(dev, "ctrl_out, wlen %d (expected %d)\n",
+						retval, len);
+				retval = -EBADMSG;
+			}
 			break;
 		}
 
@@ -1275,6 +1279,11 @@ static int ctrl_out (struct usbtest_dev 
 				0, 0, buf, len, USB_CTRL_GET_TIMEOUT);
 		if (retval != len) {
 			what = "read";
+			if (retval >= 0) {
+				INFO(dev, "ctrl_out, rlen %d (expected %d)\n",
+						retval, len);
+				retval = -EBADMSG;
+			}
 			break;
 		}
 
@@ -1293,8 +1302,13 @@ static int ctrl_out (struct usbtest_dev 
 		}
 
 		len += vary;
+
+		/* [real world] the "zero bytes IN" case isn't really used.
+		 * hardware can easily trip up in this wierd case, since its
+		 * status stage is IN, not OUT like other ep0in transfers.
+		 */
 		if (len > length)
-			len = 0;
+			len = realworld ? 1 : 0;
 	}
 
 	if (retval < 0)
@@ -1519,6 +1533,11 @@ usbtest_ioctl (struct usb_interface *int
 	if (down_interruptible (&dev->sem))
 		return -ERESTARTSYS;
 
+	if (intf->dev.power.power_state != PMSG_ON) {
+		up (&dev->sem);
+		return -EHOSTUNREACH;
+	}
+
 	/* some devices, like ez-usb default devices, need a non-default
 	 * altsetting to have any active endpoints.  some tests change
 	 * altsettings; force a default so most tests don't need to check.
@@ -1762,8 +1781,10 @@ usbtest_ioctl (struct usb_interface *int
 	case 14:
 		if (!dev->info->ctrl_out)
 			break;
-		dev_dbg (&intf->dev, "TEST 14:  %d ep0out, 0..%d vary %d\n",
-				param->iterations, param->length, param->vary);
+		dev_dbg (&intf->dev, "TEST 14:  %d ep0out, %d..%d vary %d\n",
+				param->iterations,
+				realworld ? 1 : 0, param->length,
+				param->vary);
 		retval = ctrl_out (dev, param->iterations, 
 				param->length, param->vary);
 		break;
@@ -1927,6 +1948,27 @@ usbtest_probe (struct usb_interface *int
 	return 0;
 }
 
+static int usbtest_suspend (struct usb_interface *intf, pm_message_t message)
+{
+	struct usbtest_dev	*dev = usb_get_intfdata (intf);
+
+	down (&dev->sem);
+	intf->dev.power.power_state = PMSG_SUSPEND;
+	up (&dev->sem);
+	return 0;
+}
+
+static int usbtest_resume (struct usb_interface *intf)
+{
+	struct usbtest_dev	*dev = usb_get_intfdata (intf);
+
+	down (&dev->sem);
+	intf->dev.power.power_state = PMSG_ON;
+	up (&dev->sem);
+	return 0;
+}
+
+
 static void usbtest_disconnect (struct usb_interface *intf)
 {
 	struct usbtest_dev	*dev = usb_get_intfdata (intf);
@@ -2115,6 +2157,8 @@ static struct usb_driver usbtest_driver 
 	.probe =	usbtest_probe,
 	.ioctl =	usbtest_ioctl,
 	.disconnect =	usbtest_disconnect,
+	.suspend =	usbtest_suspend,
+	.resume =	usbtest_resume,
 };
 
 /*-------------------------------------------------------------------------*/
diff --git a/drivers/usb/mon/Kconfig b/drivers/usb/mon/Kconfig
--- a/drivers/usb/mon/Kconfig
+++ b/drivers/usb/mon/Kconfig
@@ -2,21 +2,15 @@
 # USB Monitor configuration
 #
 
-# In normal life, it makes little sense to have usbmon as a module, and in fact
-# it is harmful, because there is no way to autoload the module.
-# The 'm' option is allowed for hackers who debug the usbmon itself,
-# and for those who have usbcore as a module.
 config USB_MON
-	tristate "USB Monitor"
-	depends on USB
+	bool "USB Monitor"
+	depends on USB!=n
 	default y
 	help
 	  If you say Y here, a component which captures the USB traffic
 	  between peripheral-specific drivers and HC drivers will be built.
-	  The USB_MON is similar in spirit and may be compatible with Dave
-	  Harding's USBMon.
+	  For more information, see <file:Documentation/usb/usbmon.txt>.
 
-	  This is somewhat experimental at this time, but it should be safe,
-	  as long as you aren't building this as a module and then removing it.
+	  This is somewhat experimental at this time, but it should be safe.
 
-	  If unsure, say Y. Do not say M.
+	  If unsure, say Y.
diff --git a/drivers/usb/mon/Makefile b/drivers/usb/mon/Makefile
--- a/drivers/usb/mon/Makefile
+++ b/drivers/usb/mon/Makefile
@@ -4,4 +4,5 @@
 
 usbmon-objs	:= mon_main.o mon_stat.o mon_text.o
 
-obj-$(CONFIG_USB_MON)	+= usbmon.o
+# This does not use CONFIG_USB_MON because we want this to use a tristate.
+obj-$(CONFIG_USB)	+= usbmon.o
diff --git a/drivers/usb/mon/mon_main.c b/drivers/usb/mon/mon_main.c
--- a/drivers/usb/mon/mon_main.c
+++ b/drivers/usb/mon/mon_main.c
@@ -2,6 +2,8 @@
  * The USB Monitor, inspired by Dave Harding's USBMon.
  *
  * mon_main.c: Main file, module initiation and exit, registrations, etc.
+ *
+ * Copyright (C) 2005 Pete Zaitcev (zaitcev@redhat.com)
  */
 
 #include <linux/kernel.h>
@@ -311,7 +313,7 @@ static int __init mon_init(void)
 
 	mondir = debugfs_create_dir("usbmon", NULL);
 	if (IS_ERR(mondir)) {
-		printk(KERN_NOTICE TAG ": debugs is not available\n");
+		printk(KERN_NOTICE TAG ": debugfs is not available\n");
 		return -ENODEV;
 	}
 	if (mondir == NULL) {
diff --git a/drivers/usb/mon/mon_text.c b/drivers/usb/mon/mon_text.c
--- a/drivers/usb/mon/mon_text.c
+++ b/drivers/usb/mon/mon_text.c
@@ -19,11 +19,16 @@
 #define DATA_MAX  32
 
 /*
+ * Defined by USB 2.0 clause 9.3, table 9.2.
+ */
+#define SETUP_MAX  8
+
+/*
  * This limit exists to prevent OOMs when the user process stops reading.
  */
 #define EVENT_MAX  25
 
-#define PRINTF_DFL  120
+#define PRINTF_DFL  130
 
 struct mon_event_text {
 	struct list_head e_link;
@@ -33,7 +38,9 @@ struct mon_event_text {
 	unsigned int tstamp;
 	int length;		/* Depends on type: xfer length or act length */
 	int status;
+	char setup_flag;
 	char data_flag;
+	unsigned char setup[SETUP_MAX];
 	unsigned char data[DATA_MAX];
 };
 
@@ -64,6 +71,22 @@ static void mon_text_dtor(void *, kmem_c
  * This is called with the whole mon_bus locked, so no additional lock.
  */
 
+static inline char mon_text_get_setup(struct mon_event_text *ep,
+    struct urb *urb, char ev_type)
+{
+
+	if (!usb_pipecontrol(urb->pipe) || ev_type != 'S')
+		return '-';
+
+	if (urb->transfer_flags & URB_NO_SETUP_DMA_MAP)
+		return 'D';
+	if (urb->setup_packet == NULL)
+		return 'Z';	/* '0' would be not as pretty. */
+
+	memcpy(ep->setup, urb->setup_packet, SETUP_MAX);
+	return 0;
+}
+
 static inline char mon_text_get_data(struct mon_event_text *ep, struct urb *urb,
     int len, char ev_type)
 {
@@ -90,7 +113,6 @@ static inline char mon_text_get_data(str
 
 	/*
 	 * Bulk is easy to shortcut reliably. 
-	 * XXX Control needs setup packet taken.
 	 * XXX Other pipe types need consideration. Currently, we overdo it
 	 * and collect garbage for them: better more than less.
 	 */
@@ -144,6 +166,7 @@ static void mon_text_event(struct mon_re
 	/* Collecting status makes debugging sense for submits, too */
 	ep->status = urb->status;
 
+	ep->setup_flag = mon_text_get_setup(ep, urb, ev_type);
 	ep->data_flag = mon_text_get_data(ep, urb, ep->length, ev_type);
 
 	rp->nevents++;
@@ -299,10 +322,25 @@ static ssize_t mon_text_read(struct file
 	default: /* PIPE_BULK */  utype = 'B';
 	}
 	cnt += snprintf(pbuf + cnt, limit - cnt,
-	    "%lx %u %c %c%c:%03u:%02u %d %d",
+	    "%lx %u %c %c%c:%03u:%02u",
 	    ep->id, ep->tstamp, ep->type,
-	    utype, udir, usb_pipedevice(ep->pipe), usb_pipeendpoint(ep->pipe),
-	    ep->status, ep->length);
+	    utype, udir, usb_pipedevice(ep->pipe), usb_pipeendpoint(ep->pipe));
+
+	if (ep->setup_flag == 0) {   /* Setup packet is present and captured */
+		cnt += snprintf(pbuf + cnt, limit - cnt,
+		    " s %02x %02x %04x %04x %04x",
+		    ep->setup[0],
+		    ep->setup[1],
+		    (ep->setup[3] << 8) | ep->setup[2],
+		    (ep->setup[5] << 8) | ep->setup[4],
+		    (ep->setup[7] << 8) | ep->setup[6]);
+	} else if (ep->setup_flag != '-') { /* Unable to capture setup packet */
+		cnt += snprintf(pbuf + cnt, limit - cnt,
+		    " %c __ __ ____ ____ ____", ep->setup_flag);
+	} else {                     /* No setup for this kind of URB */
+		cnt += snprintf(pbuf + cnt, limit - cnt, " %d", ep->status);
+	}
+	cnt += snprintf(pbuf + cnt, limit - cnt, " %d", ep->length);
 
 	if ((data_len = ep->length) > 0) {
 		if (ep->data_flag == 0) {
diff --git a/drivers/usb/mon/usb_mon.h b/drivers/usb/mon/usb_mon.h
--- a/drivers/usb/mon/usb_mon.h
+++ b/drivers/usb/mon/usb_mon.h
@@ -1,5 +1,7 @@
 /*
  * The USB Monitor, inspired by Dave Harding's USBMon.
+ *
+ * Copyright (C) 2005 Pete Zaitcev (zaitcev@redhat.com)
  */
 
 #ifndef __USB_MON_H
diff --git a/drivers/usb/net/kaweth.c b/drivers/usb/net/kaweth.c
--- a/drivers/usb/net/kaweth.c
+++ b/drivers/usb/net/kaweth.c
@@ -477,7 +477,7 @@ static int kaweth_reset(struct kaweth_de
 }
 
 static void kaweth_usb_receive(struct urb *, struct pt_regs *regs);
-static int kaweth_resubmit_rx_urb(struct kaweth_device *, int);
+static int kaweth_resubmit_rx_urb(struct kaweth_device *, unsigned);
 
 /****************************************************************
 	int_callback
@@ -550,7 +550,7 @@ static void kaweth_resubmit_tl(void *d)
  *     kaweth_resubmit_rx_urb
  ****************************************************************/
 static int kaweth_resubmit_rx_urb(struct kaweth_device *kaweth,
-						int mem_flags)
+						unsigned mem_flags)
 {
 	int result;
 
diff --git a/drivers/usb/net/pegasus.c b/drivers/usb/net/pegasus.c
--- a/drivers/usb/net/pegasus.c
+++ b/drivers/usb/net/pegasus.c
@@ -59,7 +59,6 @@ static const char driver_name[] = "pegas
 
 static int loopback = 0;
 static int mii_mode = 0;
-static int multicast_filter_limit = 32;
 
 static struct usb_eth_dev usb_dev_id[] = {
 #define	PEGASUS_DEV(pn, vid, pid, flags)	\
@@ -1166,7 +1165,7 @@ static void pegasus_set_multicast(struct
 		pegasus->eth_regs[EthCtrl2] |= RX_PROMISCUOUS;
 		if (netif_msg_link(pegasus))
 			pr_info("%s: Promiscuous mode enabled.\n", net->name);
-	} else if ((net->mc_count > multicast_filter_limit) ||
+	} else if (net->mc_count ||
 		   (net->flags & IFF_ALLMULTI)) {
 		pegasus->eth_regs[EthCtrl0] |= RX_MULTICAST;
 		pegasus->eth_regs[EthCtrl2] &= ~RX_PROMISCUOUS;
diff --git a/drivers/usb/net/pegasus.h b/drivers/usb/net/pegasus.h
--- a/drivers/usb/net/pegasus.h
+++ b/drivers/usb/net/pegasus.h
@@ -249,6 +249,8 @@ PEGASUS_DEV( "Kingston KNU101TX Ethernet
 		DEFAULT_GPIO_RESET)
 PEGASUS_DEV( "LANEED USB Ethernet LD-USB/TX", VENDOR_LANEED, 0x4002,
 		DEFAULT_GPIO_RESET )
+PEGASUS_DEV( "LANEED USB Ethernet LD-USBL/TX", VENDOR_LANEED, 0x4005,
+		DEFAULT_GPIO_RESET | PEGASUS_II)
 PEGASUS_DEV( "LANEED USB Ethernet LD-USB/TX", VENDOR_LANEED, 0x400b,
 		DEFAULT_GPIO_RESET | PEGASUS_II )
 PEGASUS_DEV( "LANEED USB Ethernet LD-USB/T", VENDOR_LANEED, 0xabc1,
diff --git a/drivers/usb/net/rtl8150.c b/drivers/usb/net/rtl8150.c
--- a/drivers/usb/net/rtl8150.c
+++ b/drivers/usb/net/rtl8150.c
@@ -167,8 +167,6 @@ struct rtl8150 {
 
 typedef struct rtl8150 rtl8150_t;
 
-static unsigned long multicast_filter_limit = 32;
-
 static void fill_skb_pool(rtl8150_t *);
 static void free_skb_pool(rtl8150_t *);
 static inline struct sk_buff *pull_skb(rtl8150_t *);
@@ -667,7 +665,7 @@ static void rtl8150_set_multicast(struct
 	if (netdev->flags & IFF_PROMISC) {
 		dev->rx_creg |= cpu_to_le16(0x0001);
 		info("%s: promiscuous mode", netdev->name);
-	} else if ((netdev->mc_count > multicast_filter_limit) ||
+	} else if (netdev->mc_count ||
 		   (netdev->flags & IFF_ALLMULTI)) {
 		dev->rx_creg &= cpu_to_le16(0xfffe);
 		dev->rx_creg |= cpu_to_le16(0x0002);
diff --git a/drivers/usb/net/usbnet.c b/drivers/usb/net/usbnet.c
--- a/drivers/usb/net/usbnet.c
+++ b/drivers/usb/net/usbnet.c
@@ -1429,7 +1429,7 @@ static int generic_cdc_bind (struct usbn
 			info->ether = (void *) buf;
 			if (info->ether->bLength != sizeof *info->ether) {
 				dev_dbg (&intf->dev, "CDC ether len %u\n",
-					info->u->bLength);
+					info->ether->bLength);
 				goto bad_desc;
 			}
 			dev->net->mtu = le16_to_cpup (
@@ -1922,7 +1922,7 @@ static int genelink_rx_fixup (struct usb
 
 			// copy the packet data to the new skb
 			memcpy(skb_put(gl_skb, size), packet->packet_data, size);
-			skb_return (dev, skb);
+			skb_return (dev, gl_skb);
 		}
 
 		// advance to the next packet
@@ -3227,9 +3227,9 @@ static int usbnet_stop (struct net_devic
 	temp = unlink_urbs (dev, &dev->txq) + unlink_urbs (dev, &dev->rxq);
 
 	// maybe wait for deletions to finish.
-	while (skb_queue_len (&dev->rxq)
-			&& skb_queue_len (&dev->txq)
-			&& skb_queue_len (&dev->done)) {
+	while (!skb_queue_empty(&dev->rxq) &&
+	       !skb_queue_empty(&dev->txq) &&
+	       !skb_queue_empty(&dev->done)) {
 		msleep(UNLINK_TIMEOUT_MS);
 		if (netif_msg_ifdown (dev))
 			devdbg (dev, "waited for %d urb completions", temp);
diff --git a/drivers/usb/net/zd1201.c b/drivers/usb/net/zd1201.c
--- a/drivers/usb/net/zd1201.c
+++ b/drivers/usb/net/zd1201.c
@@ -29,6 +29,7 @@ static struct usb_device_id zd1201_table
 	{USB_DEVICE(0x0ace, 0x1201)}, /* ZyDAS ZD1201 Wireless USB Adapter */
 	{USB_DEVICE(0x050d, 0x6051)}, /* Belkin F5D6051 usb  adapter */
 	{USB_DEVICE(0x0db0, 0x6823)}, /* MSI UB11B usb  adapter */
+	{USB_DEVICE(0x1044, 0x8005)}, /* GIGABYTE GN-WLBZ201 usb adapter */
 	{}
 };
 
@@ -345,8 +346,7 @@ static void zd1201_usbrx(struct urb *urb
 			if (datalen<14)
 				goto resubmit;
 			if ((seq & IEEE802_11_SCTL_FRAG) == 0) {
-				frag = kmalloc(sizeof(struct zd1201_frag*),
-				    GFP_ATOMIC);
+				frag = kmalloc(sizeof(*frag), GFP_ATOMIC);
 				if (!frag)
 					goto resubmit;
 				skb = dev_alloc_skb(IEEE802_11_DATA_LEN +14+2);
@@ -1884,12 +1884,53 @@ static void zd1201_disconnect(struct usb
 	kfree(zd);
 }
 
+#ifdef CONFIG_PM
+
+static int zd1201_suspend(struct usb_interface *interface,
+			   pm_message_t message)
+{
+	struct zd1201 *zd = usb_get_intfdata(interface);
+
+	netif_device_detach(zd->dev);
+
+	zd->was_enabled = zd->mac_enabled;
+
+	if (zd->was_enabled)
+		return zd1201_disable(zd);
+	else
+		return 0;
+}
+
+static int zd1201_resume(struct usb_interface *interface)
+{
+	struct zd1201 *zd = usb_get_intfdata(interface);
+
+	if (!zd || !zd->dev)
+		return -ENODEV;
+
+	netif_device_attach(zd->dev);
+
+	if (zd->was_enabled)
+		return zd1201_enable(zd);
+	else
+		return 0;
+}
+
+#else
+
+#define zd1201_suspend NULL
+#define zd1201_resume  NULL
+
+#endif
+
 static struct usb_driver zd1201_usb = {
 	.owner = THIS_MODULE,
 	.name = "zd1201",
 	.probe = zd1201_probe,
 	.disconnect = zd1201_disconnect,
 	.id_table = zd1201_table,
+	.suspend = zd1201_suspend,
+	.resume = zd1201_resume,
 };
 
 static int __init zd1201_init(void)
diff --git a/drivers/usb/net/zd1201.h b/drivers/usb/net/zd1201.h
--- a/drivers/usb/net/zd1201.h
+++ b/drivers/usb/net/zd1201.h
@@ -46,6 +46,7 @@ struct zd1201 {
 	char			essid[IW_ESSID_MAX_SIZE+1];
 	int			essidlen;
 	int			mac_enabled;
+	int			was_enabled;
 	int			monitor;
 	int			encode_enabled;
 	int			encode_restricted;
diff --git a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c
--- a/drivers/usb/serial/cyberjack.c
+++ b/drivers/usb/serial/cyberjack.c
@@ -213,10 +213,14 @@ static int cyberjack_write (struct usb_s
 		return (0);
 	}
 
-	if (port->write_urb->status == -EINPROGRESS) {
+	spin_lock(&port->lock);
+	if (port->write_urb_busy) {
+		spin_unlock(&port->lock);
 		dbg("%s - already writing", __FUNCTION__);
-		return (0);
+		return 0;
 	}
+	port->write_urb_busy = 1;
+	spin_unlock(&port->lock);
 
 	spin_lock_irqsave(&priv->lock, flags);
 
@@ -224,6 +228,7 @@ static int cyberjack_write (struct usb_s
 		/* To much data for buffer. Reset buffer. */
 		priv->wrfilled=0;
 		spin_unlock_irqrestore(&priv->lock, flags);
+		port->write_urb_busy = 0;
 		return (0);
 	}
 
@@ -268,6 +273,7 @@ static int cyberjack_write (struct usb_s
 			priv->wrfilled=0;
 			priv->wrsent=0;
 			spin_unlock_irqrestore(&priv->lock, flags);
+			port->write_urb_busy = 0;
 			return 0;
 		}
 
@@ -412,7 +418,8 @@ static void cyberjack_write_bulk_callbac
 	struct cyberjack_private *priv = usb_get_serial_port_data(port);
 
 	dbg("%s - port %d", __FUNCTION__, port->number);
-	
+
+	port->write_urb_busy = 0;
 	if (urb->status) {
 		dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, urb->status);
 		return;
@@ -424,12 +431,6 @@ static void cyberjack_write_bulk_callbac
 	if( priv->wrfilled ) {
 		int length, blksize, result;
 
-		if (port->write_urb->status == -EINPROGRESS) {
-			dbg("%s - already writing", __FUNCTION__);
-			spin_unlock(&priv->lock);
-			return;
-		}
-
 		dbg("%s - transmitting data (frame n)", __FUNCTION__);
 
 		length = ((priv->wrfilled - priv->wrsent) > port->bulk_out_size) ?
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -264,16 +264,26 @@
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v1.4.2"
+#define DRIVER_VERSION "v1.4.3"
 #define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>, Bill Ryder <bryder@sgi.com>, Kuba Ober <kuba@mareimbrium.org>"
 #define DRIVER_DESC "USB FTDI Serial Converters Driver"
 
 static int debug;
 
-static struct usb_device_id id_table_sio [] = {
-	{ USB_DEVICE(FTDI_VID, FTDI_SIO_PID) },
-	{ USB_DEVICE(MOBILITY_VID, MOBILITY_USB_SERIAL_PID) },
-	{ }						/* Terminating entry */
+/* struct ftdi_sio_quirk is used by devices requiring special attention. */
+struct ftdi_sio_quirk {
+	void (*setup)(struct usb_serial *); /* Special settings during startup. */
+};
+
+static void  ftdi_USB_UIRT_setup	(struct usb_serial *serial);
+static void  ftdi_HE_TIRA1_setup	(struct usb_serial *serial);
+
+static struct ftdi_sio_quirk ftdi_USB_UIRT_quirk = {
+	.setup = ftdi_USB_UIRT_setup,
+};
+
+static struct ftdi_sio_quirk ftdi_HE_TIRA1_quirk = {
+	.setup = ftdi_HE_TIRA1_setup,
 };
 
 /*
@@ -288,237 +298,11 @@ static struct usb_device_id id_table_sio
  * the bcdDevice value is used to differentiate FT232BM and FT245BM from
  * the earlier FT8U232AM and FT8U232BM.  For now, include all known VID/PID
  * combinations in both tables.
- * FIXME: perhaps bcdDevice can also identify 12MHz devices, but I don't know
- * if those ever went into mass production. [Ian Abbott]
+ * FIXME: perhaps bcdDevice can also identify 12MHz FT8U232AM devices,
+ * but I don't know if those ever went into mass production. [Ian Abbott]
  */
 
 
-static struct usb_device_id id_table_8U232AM [] = {
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_IRTRANS_PID, 0, 0x3ff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_8U232AM_PID, 0, 0x3ff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_8U232AM_ALT_PID, 0, 0x3ff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_RELAIS_PID, 0, 0x3ff) },
-	{ USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_IOBOARD_PID) },
-	{ USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_MINI_IOBOARD_PID) },
-	{ USB_DEVICE_VER(FTDI_NF_RIC_VID, FTDI_NF_RIC_PID, 0, 0x3ff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_XF_632_PID, 0, 0x3ff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_XF_634_PID, 0, 0x3ff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_XF_547_PID, 0, 0x3ff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_XF_633_PID, 0, 0x3ff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_XF_631_PID, 0, 0x3ff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_XF_635_PID, 0, 0x3ff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_XF_640_PID, 0, 0x3ff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_XF_642_PID, 0, 0x3ff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_VNHCPCUSB_D_PID, 0, 0x3ff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_DSS20_PID, 0, 0x3ff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2101_PID, 0, 0x3ff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2102_PID, 0, 0x3ff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2103_PID, 0, 0x3ff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2104_PID, 0, 0x3ff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2201_1_PID, 0, 0x3ff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2201_2_PID, 0, 0x3ff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2202_1_PID, 0, 0x3ff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2202_2_PID, 0, 0x3ff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2203_1_PID, 0, 0x3ff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2203_2_PID, 0, 0x3ff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2401_1_PID, 0, 0x3ff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2401_2_PID, 0, 0x3ff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2401_3_PID, 0, 0x3ff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2401_4_PID, 0, 0x3ff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2402_1_PID, 0, 0x3ff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2402_2_PID, 0, 0x3ff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2402_3_PID, 0, 0x3ff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2402_4_PID, 0, 0x3ff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2403_1_PID, 0, 0x3ff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2403_2_PID, 0, 0x3ff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2403_3_PID, 0, 0x3ff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2403_4_PID, 0, 0x3ff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2801_1_PID, 0, 0x3ff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2801_2_PID, 0, 0x3ff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2801_3_PID, 0, 0x3ff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2801_4_PID, 0, 0x3ff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2801_5_PID, 0, 0x3ff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2801_6_PID, 0, 0x3ff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2801_7_PID, 0, 0x3ff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2801_8_PID, 0, 0x3ff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2802_1_PID, 0, 0x3ff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2802_2_PID, 0, 0x3ff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2802_3_PID, 0, 0x3ff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2802_4_PID, 0, 0x3ff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2802_5_PID, 0, 0x3ff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2802_6_PID, 0, 0x3ff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2802_7_PID, 0, 0x3ff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2802_8_PID, 0, 0x3ff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2803_1_PID, 0, 0x3ff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2803_2_PID, 0, 0x3ff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2803_3_PID, 0, 0x3ff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2803_4_PID, 0, 0x3ff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2803_5_PID, 0, 0x3ff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2803_6_PID, 0, 0x3ff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2803_7_PID, 0, 0x3ff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2803_8_PID, 0, 0x3ff) },
-	{ USB_DEVICE_VER(IDTECH_VID, IDTECH_IDT1221U_PID, 0, 0x3ff) },
-	{ USB_DEVICE_VER(OCT_VID, OCT_US101_PID, 0, 0x3ff) },
-	{ USB_DEVICE_VER(FTDI_VID, PROTEGO_SPECIAL_1, 0, 0x3ff) },
-	{ USB_DEVICE_VER(FTDI_VID, PROTEGO_R2X0, 0, 0x3ff) },
-	{ USB_DEVICE_VER(FTDI_VID, PROTEGO_SPECIAL_3, 0, 0x3ff) },
-	{ USB_DEVICE_VER(FTDI_VID, PROTEGO_SPECIAL_4, 0, 0x3ff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_ELV_UO100_PID, 0, 0x3ff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_ELV_UM100_PID, 0, 0x3ff) },
-	{ USB_DEVICE_VER(FTDI_VID, INSIDE_ACCESSO, 0, 0x3ff) },
-	{ USB_DEVICE_VER(INTREPID_VID, INTREPID_VALUECAN_PID, 0, 0x3ff) },
-	{ USB_DEVICE_VER(INTREPID_VID, INTREPID_NEOVI_PID, 0, 0x3ff) },
-	{ USB_DEVICE_VER(FALCOM_VID, FALCOM_TWIST_PID, 0, 0x3ff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_SUUNTO_SPORTS_PID, 0, 0x3ff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_RM_CANVIEW_PID, 0, 0x3ff) },
-	{ USB_DEVICE_VER(BANDB_VID, BANDB_USOTL4_PID, 0, 0x3ff) },
-	{ USB_DEVICE_VER(BANDB_VID, BANDB_USTL4_PID, 0, 0x3ff) },
-	{ USB_DEVICE_VER(BANDB_VID, BANDB_USO9ML2_PID, 0, 0x3ff) },
-	{ USB_DEVICE_VER(FTDI_VID, EVER_ECO_PRO_CDS, 0, 0x3ff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_4N_GALAXY_DE_0_PID, 0, 0x3ff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_4N_GALAXY_DE_1_PID, 0, 0x3ff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_4N_GALAXY_DE_2_PID, 0, 0x3ff) },
-	{ }						/* Terminating entry */
-};
-
-
-static struct usb_device_id id_table_FT232BM [] = {
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_IRTRANS_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_8U232AM_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_8U232AM_ALT_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_RELAIS_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(FTDI_NF_RIC_VID, FTDI_NF_RIC_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_XF_632_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_XF_634_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_XF_547_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_XF_633_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_XF_631_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_XF_635_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_XF_640_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_XF_642_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_VNHCPCUSB_D_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_DSS20_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_MTXORB_0_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_MTXORB_1_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_MTXORB_2_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_MTXORB_3_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_MTXORB_4_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_MTXORB_5_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_MTXORB_6_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_PERLE_ULTRAPORT_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_PIEGROUP_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2101_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2102_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2103_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2104_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2201_1_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2201_2_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2202_1_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2202_2_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2203_1_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2203_2_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2401_1_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2401_2_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2401_3_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2401_4_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2402_1_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2402_2_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2402_3_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2402_4_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2403_1_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2403_2_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2403_3_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2403_4_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2801_1_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2801_2_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2801_3_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2801_4_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2801_5_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2801_6_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2801_7_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2801_8_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2802_1_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2802_2_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2802_3_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2802_4_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2802_5_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2802_6_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2802_7_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2802_8_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2803_1_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2803_2_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2803_3_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2803_4_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2803_5_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2803_6_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2803_7_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2803_8_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(IDTECH_VID, IDTECH_IDT1221U_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(OCT_VID, OCT_US101_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(FTDI_VID, PROTEGO_SPECIAL_1, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(FTDI_VID, PROTEGO_R2X0, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(FTDI_VID, PROTEGO_SPECIAL_3, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(FTDI_VID, PROTEGO_SPECIAL_4, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E808_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E809_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E80A_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E80B_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E80C_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E80D_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E80E_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E80F_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E888_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E889_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88A_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88B_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88C_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88D_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88E_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88F_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_ELV_UO100_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_ELV_UM100_PID, 0x400, 0xffff) },
- 	{ USB_DEVICE_VER(FTDI_VID, LINX_SDMUSBQSS_PID, 0x400, 0xffff) },
- 	{ USB_DEVICE_VER(FTDI_VID, LINX_MASTERDEVEL2_PID, 0x400, 0xffff) },
- 	{ USB_DEVICE_VER(FTDI_VID, LINX_FUTURE_0_PID, 0x400, 0xffff) },
- 	{ USB_DEVICE_VER(FTDI_VID, LINX_FUTURE_1_PID, 0x400, 0xffff) },
- 	{ USB_DEVICE_VER(FTDI_VID, LINX_FUTURE_2_PID, 0x400, 0xffff) },
-	{ USB_DEVICE(FTDI_VID, FTDI_CCSICDU20_0_PID) },
-	{ USB_DEVICE(FTDI_VID, FTDI_CCSICDU40_1_PID) },
-	{ USB_DEVICE_VER(FTDI_VID, INSIDE_ACCESSO, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(INTREPID_VID, INTREPID_VALUECAN_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(INTREPID_VID, INTREPID_NEOVI_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(FALCOM_VID, FALCOM_TWIST_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_SUUNTO_SPORTS_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_RM_CANVIEW_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(BANDB_VID, BANDB_USOTL4_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(BANDB_VID, BANDB_USTL4_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(BANDB_VID, BANDB_USO9ML2_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(FTDI_VID, EVER_ECO_PRO_CDS, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_4N_GALAXY_DE_0_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_4N_GALAXY_DE_1_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_4N_GALAXY_DE_2_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_ACTIVE_ROBOTS_PID, 0x400, 0xffff) },
-	{ }						/* Terminating entry */
-};
-
-
-static struct usb_device_id id_table_USB_UIRT [] = {
-	{ USB_DEVICE(FTDI_VID, FTDI_USB_UIRT_PID) },
-	{ }						/* Terminating entry */
-};
-
-
-static struct usb_device_id id_table_HE_TIRA1 [] = {
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_HE_TIRA1_PID, 0x400, 0xffff) },
-	{ }						/* Terminating entry */
-};
-
-
-static struct usb_device_id id_table_FT2232C[] = {
-	{ USB_DEVICE(FTDI_VID, FTDI_8U2232C_PID) },
-	{ }						/* Terminating entry */
-};
-
 
 static struct usb_device_id id_table_combined [] = {
 	{ USB_DEVICE(FTDI_VID, FTDI_IRTRANS_PID) },
@@ -540,14 +324,14 @@ static struct usb_device_id id_table_com
 	{ USB_DEVICE(FTDI_VID, FTDI_DSS20_PID) },
 	{ USB_DEVICE(FTDI_NF_RIC_VID, FTDI_NF_RIC_PID) },
 	{ USB_DEVICE(FTDI_VID, FTDI_VNHCPCUSB_D_PID) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_MTXORB_0_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_MTXORB_1_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_MTXORB_2_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_MTXORB_3_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_MTXORB_4_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_MTXORB_5_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_MTXORB_6_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_PERLE_ULTRAPORT_PID, 0x400, 0xffff) },
+	{ USB_DEVICE(FTDI_VID, FTDI_MTXORB_0_PID) },
+	{ USB_DEVICE(FTDI_VID, FTDI_MTXORB_1_PID) },
+	{ USB_DEVICE(FTDI_VID, FTDI_MTXORB_2_PID) },
+	{ USB_DEVICE(FTDI_VID, FTDI_MTXORB_3_PID) },
+	{ USB_DEVICE(FTDI_VID, FTDI_MTXORB_4_PID) },
+	{ USB_DEVICE(FTDI_VID, FTDI_MTXORB_5_PID) },
+	{ USB_DEVICE(FTDI_VID, FTDI_MTXORB_6_PID) },
+	{ USB_DEVICE(FTDI_VID, FTDI_PERLE_ULTRAPORT_PID) },
 	{ USB_DEVICE(FTDI_VID, FTDI_PIEGROUP_PID) },
 	{ USB_DEVICE(SEALEVEL_VID, SEALEVEL_2101_PID) },
 	{ USB_DEVICE(SEALEVEL_VID, SEALEVEL_2102_PID) },
@@ -597,35 +381,37 @@ static struct usb_device_id id_table_com
 	{ USB_DEVICE(SEALEVEL_VID, SEALEVEL_2803_8_PID) },
 	{ USB_DEVICE(IDTECH_VID, IDTECH_IDT1221U_PID) },
 	{ USB_DEVICE(OCT_VID, OCT_US101_PID) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_HE_TIRA1_PID, 0x400, 0xffff) },
-	{ USB_DEVICE(FTDI_VID, FTDI_USB_UIRT_PID) },
+	{ USB_DEVICE(FTDI_VID, FTDI_HE_TIRA1_PID),
+		.driver_info = (kernel_ulong_t)&ftdi_HE_TIRA1_quirk },
+	{ USB_DEVICE(FTDI_VID, FTDI_USB_UIRT_PID),
+		.driver_info = (kernel_ulong_t)&ftdi_USB_UIRT_quirk },
 	{ USB_DEVICE(FTDI_VID, PROTEGO_SPECIAL_1) },
 	{ USB_DEVICE(FTDI_VID, PROTEGO_R2X0) },
 	{ USB_DEVICE(FTDI_VID, PROTEGO_SPECIAL_3) },
 	{ USB_DEVICE(FTDI_VID, PROTEGO_SPECIAL_4) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E808_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E809_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E80A_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E80B_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E80C_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E80D_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E80E_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E80F_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E888_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E889_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88A_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88B_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88C_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88D_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88E_PID, 0x400, 0xffff) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88F_PID, 0x400, 0xffff) },
+	{ USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E808_PID) },
+	{ USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E809_PID) },
+	{ USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E80A_PID) },
+	{ USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E80B_PID) },
+	{ USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E80C_PID) },
+	{ USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E80D_PID) },
+	{ USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E80E_PID) },
+	{ USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E80F_PID) },
+	{ USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E888_PID) },
+	{ USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E889_PID) },
+	{ USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E88A_PID) },
+	{ USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E88B_PID) },
+	{ USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E88C_PID) },
+	{ USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E88D_PID) },
+	{ USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E88E_PID) },
+	{ USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E88F_PID) },
 	{ USB_DEVICE(FTDI_VID, FTDI_ELV_UO100_PID) },
 	{ USB_DEVICE(FTDI_VID, FTDI_ELV_UM100_PID) },
- 	{ USB_DEVICE_VER(FTDI_VID, LINX_SDMUSBQSS_PID, 0x400, 0xffff) },
- 	{ USB_DEVICE_VER(FTDI_VID, LINX_MASTERDEVEL2_PID, 0x400, 0xffff) },
- 	{ USB_DEVICE_VER(FTDI_VID, LINX_FUTURE_0_PID, 0x400, 0xffff) },
- 	{ USB_DEVICE_VER(FTDI_VID, LINX_FUTURE_1_PID, 0x400, 0xffff) },
- 	{ USB_DEVICE_VER(FTDI_VID, LINX_FUTURE_2_PID, 0x400, 0xffff) },
+ 	{ USB_DEVICE(FTDI_VID, LINX_SDMUSBQSS_PID) },
+ 	{ USB_DEVICE(FTDI_VID, LINX_MASTERDEVEL2_PID) },
+ 	{ USB_DEVICE(FTDI_VID, LINX_FUTURE_0_PID) },
+ 	{ USB_DEVICE(FTDI_VID, LINX_FUTURE_1_PID) },
+ 	{ USB_DEVICE(FTDI_VID, LINX_FUTURE_2_PID) },
  	{ USB_DEVICE(FTDI_VID, FTDI_CCSICDU20_0_PID) },
  	{ USB_DEVICE(FTDI_VID, FTDI_CCSICDU40_1_PID) },
 	{ USB_DEVICE(FTDI_VID, INSIDE_ACCESSO) },
@@ -642,7 +428,10 @@ static struct usb_device_id id_table_com
 	{ USB_DEVICE(FTDI_VID, FTDI_4N_GALAXY_DE_1_PID) },
 	{ USB_DEVICE(FTDI_VID, FTDI_4N_GALAXY_DE_2_PID) },
 	{ USB_DEVICE(MOBILITY_VID, MOBILITY_USB_SERIAL_PID) },
-	{ USB_DEVICE_VER(FTDI_VID, FTDI_ACTIVE_ROBOTS_PID, 0x400, 0xffff) },
+	{ USB_DEVICE(FTDI_VID, FTDI_ACTIVE_ROBOTS_PID) },
+	{ USB_DEVICE(FTDI_VID, FTDI_MHAM_Y6_PID) },
+	{ USB_DEVICE(FTDI_VID, FTDI_MHAM_Y8_PID) },
+	{ USB_DEVICE(EVOLUTION_VID, EVOLUTION_ER1_PID) },
 	{ }						/* Terminating entry */
 };
 
@@ -705,12 +494,8 @@ struct ftdi_private {
  ASYNC_SPD_CUST | ASYNC_SPD_SHI | ASYNC_SPD_WARP )
 
 /* function prototypes for a FTDI serial converter */
-static int  ftdi_SIO_startup		(struct usb_serial *serial);
-static int  ftdi_8U232AM_startup	(struct usb_serial *serial);
-static int  ftdi_FT232BM_startup	(struct usb_serial *serial);
-static int  ftdi_FT2232C_startup	(struct usb_serial *serial);
-static int  ftdi_USB_UIRT_startup	(struct usb_serial *serial);
-static int  ftdi_HE_TIRA1_startup	(struct usb_serial *serial);
+static int  ftdi_sio_probe	(struct usb_serial *serial, const struct usb_device_id *id);
+static int  ftdi_sio_attach		(struct usb_serial *serial);
 static void ftdi_shutdown		(struct usb_serial *serial);
 static int  ftdi_open			(struct usb_serial_port *port, struct file *filp);
 static void ftdi_close			(struct usb_serial_port *port, struct file *filp);
@@ -733,146 +518,16 @@ static unsigned short int ftdi_232am_bau
 static __u32 ftdi_232bm_baud_base_to_divisor (int baud, int base);
 static __u32 ftdi_232bm_baud_to_divisor (int baud);
 
-static struct usb_serial_device_type ftdi_SIO_device = {
-	.owner =		THIS_MODULE,
-	.name =			"FTDI SIO",
-	.id_table =		id_table_sio,
-	.num_interrupt_in =	0,
-	.num_bulk_in =		1,
-	.num_bulk_out =		1,
-	.num_ports =		1,
-	.open =			ftdi_open,
-	.close =		ftdi_close,
-	.throttle =		ftdi_throttle,
-	.unthrottle =		ftdi_unthrottle,
-	.write =		ftdi_write,
-	.write_room =		ftdi_write_room,
-	.chars_in_buffer =	ftdi_chars_in_buffer,
-	.read_bulk_callback =	ftdi_read_bulk_callback,
-	.write_bulk_callback =	ftdi_write_bulk_callback,
-	.tiocmget =             ftdi_tiocmget,
-	.tiocmset =             ftdi_tiocmset,
-	.ioctl =		ftdi_ioctl,
-	.set_termios =		ftdi_set_termios,
-	.break_ctl =		ftdi_break_ctl,
-	.attach =		ftdi_SIO_startup,
-	.shutdown =		ftdi_shutdown,
-};
-
-static struct usb_serial_device_type ftdi_8U232AM_device = {
-	.owner =		THIS_MODULE,
-	.name =			"FTDI 8U232AM Compatible",
-	.id_table =		id_table_8U232AM,
-	.num_interrupt_in =	0,
-	.num_bulk_in =		1,
-	.num_bulk_out =		1,
-	.num_ports =		1,
-	.open =			ftdi_open,
-	.close =		ftdi_close,
-	.throttle =		ftdi_throttle,
-	.unthrottle =		ftdi_unthrottle,
-	.write =		ftdi_write,
-	.write_room =		ftdi_write_room,
-	.chars_in_buffer =	ftdi_chars_in_buffer,
-	.read_bulk_callback =	ftdi_read_bulk_callback,
-	.write_bulk_callback =	ftdi_write_bulk_callback,
-	.tiocmget =             ftdi_tiocmget,
-	.tiocmset =             ftdi_tiocmset,
-	.ioctl =		ftdi_ioctl,
-	.set_termios =		ftdi_set_termios,
-	.break_ctl =		ftdi_break_ctl,
-	.attach =		ftdi_8U232AM_startup,
-	.shutdown =		ftdi_shutdown,
-};
-
-static struct usb_serial_device_type ftdi_FT232BM_device = {
-	.owner =		THIS_MODULE,
-	.name =			"FTDI FT232BM Compatible",
-	.id_table =		id_table_FT232BM,
-	.num_interrupt_in =	0,
-	.num_bulk_in =		1,
-	.num_bulk_out =		1,
-	.num_ports =		1,
-	.open =			ftdi_open,
-	.close =		ftdi_close,
-	.throttle =		ftdi_throttle,
-	.unthrottle =		ftdi_unthrottle,
-	.write =		ftdi_write,
-	.write_room =		ftdi_write_room,
-	.chars_in_buffer =	ftdi_chars_in_buffer,
-	.read_bulk_callback =	ftdi_read_bulk_callback,
-	.write_bulk_callback =	ftdi_write_bulk_callback,
-	.tiocmget =             ftdi_tiocmget,
-	.tiocmset =             ftdi_tiocmset,
-	.ioctl =		ftdi_ioctl,
-	.set_termios =		ftdi_set_termios,
-	.break_ctl =		ftdi_break_ctl,
-	.attach =		ftdi_FT232BM_startup,
-	.shutdown =		ftdi_shutdown,
-};
-
-static struct usb_serial_device_type ftdi_FT2232C_device = {
-	.owner =		THIS_MODULE,
-	.name =			"FTDI FT2232C Compatible",
-	.id_table =		id_table_FT2232C,
-	.num_interrupt_in =	0,
-	.num_bulk_in =		1,
-	.num_bulk_out =		1,
-	.num_ports =		1,
-	.open =			ftdi_open,
-	.close =		ftdi_close,
-	.throttle =		ftdi_throttle,
-	.unthrottle =		ftdi_unthrottle,
-	.write =		ftdi_write,
-	.write_room =		ftdi_write_room,
-	.chars_in_buffer =	ftdi_chars_in_buffer,
-	.read_bulk_callback =	ftdi_read_bulk_callback,
-	.write_bulk_callback =	ftdi_write_bulk_callback,
-	.tiocmget =             ftdi_tiocmget,
-	.tiocmset =             ftdi_tiocmset,
-	.ioctl =		ftdi_ioctl,
-	.set_termios =		ftdi_set_termios,
-	.break_ctl =		ftdi_break_ctl,
-	.attach =		ftdi_FT2232C_startup,
-	.shutdown =		ftdi_shutdown,
-};
-
-static struct usb_serial_device_type ftdi_USB_UIRT_device = {
-	.owner =		THIS_MODULE,
-	.name =			"USB-UIRT Infrared Tranceiver",
-	.id_table =		id_table_USB_UIRT,
-	.num_interrupt_in =	0,
-	.num_bulk_in =		1,
-	.num_bulk_out =		1,
-	.num_ports =		1,
-	.open =			ftdi_open,
-	.close =		ftdi_close,
-	.throttle =		ftdi_throttle,
-	.unthrottle =		ftdi_unthrottle,
-	.write =		ftdi_write,
-	.write_room =		ftdi_write_room,
-	.chars_in_buffer =	ftdi_chars_in_buffer,
-	.read_bulk_callback =	ftdi_read_bulk_callback,
-	.write_bulk_callback =	ftdi_write_bulk_callback,
-	.tiocmget =             ftdi_tiocmget,
-	.tiocmset =             ftdi_tiocmset,
-	.ioctl =		ftdi_ioctl,
-	.set_termios =		ftdi_set_termios,
-	.break_ctl =		ftdi_break_ctl,
-	.attach =		ftdi_USB_UIRT_startup,
-	.shutdown =		ftdi_shutdown,
-};
-
-/* The TIRA1 is based on a  FT232BM which requires a fixed baud rate of 100000
- * and which requires RTS-CTS to be enabled. */
-static struct usb_serial_device_type ftdi_HE_TIRA1_device = {
+static struct usb_serial_device_type ftdi_sio_device = {
 	.owner =		THIS_MODULE,
-	.name =			"Home-Electronics TIRA-1 IR Transceiver",
-	.id_table =		id_table_HE_TIRA1,
+	.name =			"FTDI USB Serial Device",
+	.short_name =		"ftdi_sio",
+	.id_table =		id_table_combined,
 	.num_interrupt_in =	0,
 	.num_bulk_in =		1,
 	.num_bulk_out =		1,
 	.num_ports =		1,
+	.probe =		ftdi_sio_probe,
 	.open =			ftdi_open,
 	.close =		ftdi_close,
 	.throttle =		ftdi_throttle,
@@ -887,13 +542,13 @@ static struct usb_serial_device_type ftd
 	.ioctl =		ftdi_ioctl,
 	.set_termios =		ftdi_set_termios,
 	.break_ctl =		ftdi_break_ctl,
-	.attach =		ftdi_HE_TIRA1_startup,
+	.attach =		ftdi_sio_attach,
 	.shutdown =		ftdi_shutdown,
 };
 
 
-
 #define WDR_TIMEOUT 5000 /* default urb timeout */
+#define WDR_SHORT_TIMEOUT 1000	/* shorter urb timeout */
 
 /* High and low are for DTR, RTS etc etc */
 #define HIGH 1
@@ -942,62 +597,59 @@ static __u32 ftdi_232bm_baud_to_divisor(
 	 return(ftdi_232bm_baud_base_to_divisor(baud, 48000000));
 }
 
-static int set_rts(struct usb_serial_port *port, int high_or_low)
+#define set_mctrl(port, set)		update_mctrl((port), (set), 0)
+#define clear_mctrl(port, clear)	update_mctrl((port), 0, (clear))
+
+static int update_mctrl(struct usb_serial_port *port, unsigned int set, unsigned int clear)
 {
 	struct ftdi_private *priv = usb_get_serial_port_data(port);
 	char *buf;
-	unsigned ftdi_high_or_low;
+	unsigned urb_value;
 	int rv;
-	
-	buf = kmalloc(1, GFP_NOIO);
-	if (!buf)
-		return -ENOMEM;
-	
-	if (high_or_low) {
-		ftdi_high_or_low = FTDI_SIO_SET_RTS_HIGH;
-		priv->last_dtr_rts |= TIOCM_RTS;
-	} else {
-		ftdi_high_or_low = FTDI_SIO_SET_RTS_LOW;
-		priv->last_dtr_rts &= ~TIOCM_RTS;
-	}
-	rv = usb_control_msg(port->serial->dev,
-			       usb_sndctrlpipe(port->serial->dev, 0),
-			       FTDI_SIO_SET_MODEM_CTRL_REQUEST, 
-			       FTDI_SIO_SET_MODEM_CTRL_REQUEST_TYPE,
-			       ftdi_high_or_low, priv->interface, 
-			       buf, 0, WDR_TIMEOUT);
-
-	kfree(buf);
-	return rv;
-}
 
+	if (((set | clear) & (TIOCM_DTR | TIOCM_RTS)) == 0) {
+		dbg("%s - DTR|RTS not being set|cleared", __FUNCTION__);
+		return 0;	/* no change */
+	}
 
-static int set_dtr(struct usb_serial_port *port, int high_or_low)
-{
-	struct ftdi_private *priv = usb_get_serial_port_data(port);
-	char *buf;
-	unsigned ftdi_high_or_low;
-	int rv;
-	
 	buf = kmalloc(1, GFP_NOIO);
-	if (!buf)
+	if (!buf) {
 		return -ENOMEM;
-
-	if (high_or_low) {
-		ftdi_high_or_low = FTDI_SIO_SET_DTR_HIGH;
-		priv->last_dtr_rts |= TIOCM_DTR;
-	} else {
-		ftdi_high_or_low = FTDI_SIO_SET_DTR_LOW;
-		priv->last_dtr_rts &= ~TIOCM_DTR;
 	}
+
+	clear &= ~set;	/* 'set' takes precedence over 'clear' */
+	urb_value = 0;
+	if (clear & TIOCM_DTR)
+		urb_value |= FTDI_SIO_SET_DTR_LOW;
+	if (clear & TIOCM_RTS)
+		urb_value |= FTDI_SIO_SET_RTS_LOW;
+	if (set & TIOCM_DTR)
+		urb_value |= FTDI_SIO_SET_DTR_HIGH;
+	if (set & TIOCM_RTS)
+		urb_value |= FTDI_SIO_SET_RTS_HIGH;
 	rv = usb_control_msg(port->serial->dev,
 			       usb_sndctrlpipe(port->serial->dev, 0),
 			       FTDI_SIO_SET_MODEM_CTRL_REQUEST, 
 			       FTDI_SIO_SET_MODEM_CTRL_REQUEST_TYPE,
-			       ftdi_high_or_low, priv->interface, 
+			       urb_value, priv->interface,
 			       buf, 0, WDR_TIMEOUT);
 
 	kfree(buf);
+	if (rv < 0) {
+		err("%s Error from MODEM_CTRL urb: DTR %s, RTS %s",
+				__FUNCTION__,
+				(set & TIOCM_DTR) ? "HIGH" :
+				(clear & TIOCM_DTR) ? "LOW" : "unchanged",
+				(set & TIOCM_RTS) ? "HIGH" :
+				(clear & TIOCM_RTS) ? "LOW" : "unchanged");
+	} else {
+		dbg("%s - DTR %s, RTS %s", __FUNCTION__,
+				(set & TIOCM_DTR) ? "HIGH" :
+				(clear & TIOCM_DTR) ? "LOW" : "unchanged",
+				(set & TIOCM_RTS) ? "HIGH" :
+				(clear & TIOCM_RTS) ? "LOW" : "unchanged");
+		priv->last_dtr_rts = (priv->last_dtr_rts & ~clear) | set;
+	}
 	return rv;
 }
 
@@ -1030,7 +682,7 @@ static int change_speed(struct usb_seria
 			    FTDI_SIO_SET_BAUDRATE_REQUEST,
 			    FTDI_SIO_SET_BAUDRATE_REQUEST_TYPE,
 			    urb_value, urb_index,
-			    buf, 0, 100);
+			    buf, 0, WDR_SHORT_TIMEOUT);
 
 	kfree(buf);
 	return rv;
@@ -1212,13 +864,66 @@ check_and_exit:
 } /* set_serial_info */
 
 
+/* Determine type of FTDI chip based on USB config and descriptor. */
+static void ftdi_determine_type(struct usb_serial_port *port)
+{
+	struct ftdi_private *priv = usb_get_serial_port_data(port);
+	struct usb_serial *serial = port->serial;
+	struct usb_device *udev = serial->dev;
+	unsigned version;
+	unsigned interfaces;
+
+	/* Assume it is not the original SIO device for now. */
+	priv->baud_base = 48000000 / 16;
+	priv->write_offset = 0;
+
+	version = le16_to_cpu(udev->descriptor.bcdDevice);
+	interfaces = udev->actconfig->desc.bNumInterfaces;
+	dbg("%s: bcdDevice = 0x%x, bNumInterfaces = %u", __FUNCTION__,
+			version, interfaces);
+	if (interfaces > 1) {
+		int inter;
+
+		/* Multiple interfaces.  Assume FT2232C. */
+		priv->chip_type = FT2232C;
+		/* Determine interface code. */
+		inter = serial->interface->altsetting->desc.bInterfaceNumber;
+		if (inter == 0) {
+			priv->interface = PIT_SIOA;
+		} else {
+			priv->interface = PIT_SIOB;
+		}
+		/* BM-type devices have a bug where bcdDevice gets set
+		 * to 0x200 when iSerialNumber is 0.  */
+		if (version < 0x500) {
+			dbg("%s: something fishy - bcdDevice too low for multi-interface device",
+					__FUNCTION__);
+		}
+	} else if (version < 0x200) {
+		/* Old device.  Assume its the original SIO. */
+		priv->chip_type = SIO;
+		priv->baud_base = 12000000 / 16;
+		priv->write_offset = 1;
+	} else if (version < 0x400) {
+		/* Assume its an FT8U232AM (or FT8U245AM) */
+		/* (It might be a BM because of the iSerialNumber bug,
+		 * but it will still work as an AM device.) */
+		priv->chip_type = FT8U232AM;
+	} else {
+		/* Assume its an FT232BM (or FT245BM) */
+		priv->chip_type = FT232BM;
+	}
+	info("Detected %s", ftdi_chip_name[priv->chip_type]);
+}
+
+
 /*
  * ***************************************************************************
  * Sysfs Attribute
  * ***************************************************************************
  */
 
-static ssize_t show_latency_timer(struct device *dev, char *buf)
+static ssize_t show_latency_timer(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct usb_serial_port *port = to_usb_serial_port(dev);
 	struct ftdi_private *priv = usb_get_serial_port_data(port);
@@ -1245,7 +950,7 @@ static ssize_t show_latency_timer(struct
 }
 
 /* Write a new value of the latency timer, in units of milliseconds. */
-static ssize_t store_latency_timer(struct device *dev, const char *valbuf,
+static ssize_t store_latency_timer(struct device *dev, struct device_attribute *attr, const char *valbuf,
 				   size_t count)
 {
 	struct usb_serial_port *port = to_usb_serial_port(dev);
@@ -1276,7 +981,7 @@ static ssize_t store_latency_timer(struc
 
 /* Write an event character directly to the FTDI register.  The ASCII
    value is in the low 8 bits, with the enable bit in the 9th bit. */
-static ssize_t store_event_char(struct device *dev, const char *valbuf,
+static ssize_t store_event_char(struct device *dev, struct device_attribute *attr, const char *valbuf,
 				size_t count)
 {
 	struct usb_serial_port *port = to_usb_serial_port(dev);
@@ -1355,12 +1060,20 @@ static void remove_sysfs_attrs(struct us
  * ***************************************************************************
  */
 
-/* Common startup subroutine */
-/* Called from ftdi_SIO_startup, etc. */
-static int ftdi_common_startup (struct usb_serial *serial)
+/* Probe function to check for special devices */
+static int ftdi_sio_probe (struct usb_serial *serial, const struct usb_device_id *id)
+{
+	usb_set_serial_data(serial, (void *)id->driver_info);
+
+	return (0);
+}
+
+/* attach subroutine */
+static int ftdi_sio_attach (struct usb_serial *serial)
 {
 	struct usb_serial_port *port = serial->port[0];
 	struct ftdi_private *priv;
+	struct ftdi_sio_quirk *quirk;
 	
 	dbg("%s",__FUNCTION__);
 
@@ -1400,150 +1113,49 @@ static int ftdi_common_startup (struct u
 	port->bulk_out_buffer = NULL;
 
 	usb_set_serial_port_data(serial->port[0], priv);
-	
-	return (0);
-}
-
-
-/* Startup for the SIO chip */
-/* Called from usbserial:serial_probe */
-static int ftdi_SIO_startup (struct usb_serial *serial)
-{
-	struct ftdi_private *priv;
-	int err;
-
-	dbg("%s",__FUNCTION__);
 
-	err = ftdi_common_startup(serial);
-	if (err){
-		return (err);
-	}
-
-	priv = usb_get_serial_port_data(serial->port[0]);
-	priv->chip_type = SIO;
-	priv->baud_base = 12000000 / 16;
-	priv->write_offset = 1;
-	
-	return (0);
-}
-
-/* Startup for the 8U232AM chip */
-/* Called from usbserial:serial_probe */
-static int ftdi_8U232AM_startup (struct usb_serial *serial)
-{ /* ftdi_8U232AM_startup */
-	struct ftdi_private *priv;
-	int err;
-
-	dbg("%s",__FUNCTION__);
-	err = ftdi_common_startup(serial);
-	if (err){
-		return (err);
-	}
-
-	priv = usb_get_serial_port_data(serial->port[0]);
-	priv->chip_type = FT8U232AM;
-	priv->baud_base = 48000000 / 2; /* Would be / 16, but FTDI supports 0.125, 0.25 and 0.5 divisor fractions! */
-	
+	ftdi_determine_type (serial->port[0]);
 	create_sysfs_attrs(serial);
-	
-	return (0);
-} /* ftdi_8U232AM_startup */
 
-/* Startup for the FT232BM chip */
-/* Called from usbserial:serial_probe */
-static int ftdi_FT232BM_startup (struct usb_serial *serial)
-{ /* ftdi_FT232BM_startup */
-	struct ftdi_private *priv;
-	int err;
-
-	dbg("%s",__FUNCTION__);
-	err = ftdi_common_startup(serial);
-	if (err){
-		return (err);
+	/* Check for device requiring special set up. */
+	quirk = (struct ftdi_sio_quirk *)usb_get_serial_data(serial);
+	if (quirk && quirk->setup) {
+		quirk->setup(serial);
 	}
-
-	priv = usb_get_serial_port_data(serial->port[0]);
-	priv->chip_type = FT232BM;
-	priv->baud_base = 48000000 / 2; /* Would be / 16, but FT232BM supports multiple of 0.125 divisor fractions! */
 	
-	create_sysfs_attrs(serial);
-
 	return (0);
-} /* ftdi_FT232BM_startup */
-
-/* Startup for the FT2232C chip */
-/* Called from usbserial:serial_probe */
-static int ftdi_FT2232C_startup (struct usb_serial *serial)
-{ /* ftdi_FT2232C_startup */
-	struct ftdi_private *priv;
-	int err;
-	int inter;
-
-	dbg("%s",__FUNCTION__);
-	err = ftdi_common_startup(serial);
-	if (err){
-		return (err);
-	}
-
-	priv = usb_get_serial_port_data(serial->port[0]);
-	priv->chip_type = FT2232C;
-	inter = serial->interface->altsetting->desc.bInterfaceNumber;
-
-	if (inter) {
-		priv->interface = PIT_SIOB;
-	}
-	else  {
-		priv->interface = PIT_SIOA;
-	}
-	priv->baud_base = 48000000 / 2; /* Would be / 16, but FT2232C supports multiple of 0.125 divisor fractions! */
-	
-	create_sysfs_attrs(serial);
+} /* ftdi_sio_attach */
 
-	return (0);
-} /* ftdi_FT2232C_startup */
 
-/* Startup for the USB-UIRT device, which requires hardwired baudrate (38400 gets mapped to 312500) */
+/* Setup for the USB-UIRT device, which requires hardwired
+ * baudrate (38400 gets mapped to 312500) */
 /* Called from usbserial:serial_probe */
-static int ftdi_USB_UIRT_startup (struct usb_serial *serial)
-{ /* ftdi_USB_UIRT_startup */
+static void ftdi_USB_UIRT_setup (struct usb_serial *serial)
+{
 	struct ftdi_private *priv;
-	int err;
 
 	dbg("%s",__FUNCTION__);
-	err = ftdi_8U232AM_startup(serial);
-	if (err){
-		return (err);
-	}
 
 	priv = usb_get_serial_port_data(serial->port[0]);
 	priv->flags |= ASYNC_SPD_CUST;
 	priv->custom_divisor = 77;
 	priv->force_baud = B38400;
-	
-	return (0);
-} /* ftdi_USB_UIRT_startup */
+} /* ftdi_USB_UIRT_setup */
 
-/* Startup for the HE-TIRA1 device, which requires hardwired
- * baudrate (38400 gets mapped to 100000) */
-static int ftdi_HE_TIRA1_startup (struct usb_serial *serial)
-{ /* ftdi_HE_TIRA1_startup */
+/* Setup for the HE-TIRA1 device, which requires hardwired
+ * baudrate (38400 gets mapped to 100000) and RTS-CTS enabled.  */
+static void ftdi_HE_TIRA1_setup (struct usb_serial *serial)
+{
 	struct ftdi_private *priv;
-	int err;
 
 	dbg("%s",__FUNCTION__);
-	err = ftdi_FT232BM_startup(serial);
-	if (err){
-		return (err);
-	}
 
 	priv = usb_get_serial_port_data(serial->port[0]);
 	priv->flags |= ASYNC_SPD_CUST;
 	priv->custom_divisor = 240;
 	priv->force_baud = B38400;
 	priv->force_rtscts = 1;
-	
-	return (0);
-} /* ftdi_HE_TIRA1_startup */
+} /* ftdi_HE_TIRA1_setup */
 
 
 /* ftdi_shutdown is called from usbserial:usb_serial_disconnect 
@@ -1608,12 +1220,7 @@ static int  ftdi_open (struct usb_serial
 	/* FIXME: Flow control might be enabled, so it should be checked -
 	   we have no control of defaults! */
 	/* Turn on RTS and DTR since we are not flow controlling by default */
-	if (set_dtr(port, HIGH) < 0) {
-		err("%s Error from DTR HIGH urb", __FUNCTION__);
-	}
-	if (set_rts(port, HIGH) < 0){
-		err("%s Error from RTS HIGH urb", __FUNCTION__);
-	}
+	set_mctrl(port, TIOCM_DTR | TIOCM_RTS);
 
 	/* Not throttled */
 	spin_lock_irqsave(&priv->rx_lock, flags);
@@ -1663,14 +1270,8 @@ static void ftdi_close (struct usb_seria
 			err("error from flowcontrol urb");
 		}	    
 
-		/* drop DTR */
-		if (set_dtr(port, LOW) < 0){
-			err("Error from DTR LOW urb");
-		}
-		/* drop RTS */
-		if (set_rts(port, LOW) < 0) {
-			err("Error from RTS LOW urb");
-		}
+		/* drop RTS and DTR */
+		clear_mctrl(port, TIOCM_DTR | TIOCM_RTS);
 	} /* Note change no line if hupcl is off */
 
 	/* cancel any scheduled reading */
@@ -2186,7 +1787,7 @@ static void ftdi_set_termios (struct usb
 			    FTDI_SIO_SET_DATA_REQUEST, 
 			    FTDI_SIO_SET_DATA_REQUEST_TYPE,
 			    urb_value , priv->interface,
-			    buf, 0, 100) < 0) {
+			    buf, 0, WDR_SHORT_TIMEOUT) < 0) {
 		err("%s FAILED to set databits/stopbits/parity", __FUNCTION__);
 	}	   
 
@@ -2201,25 +1802,14 @@ static void ftdi_set_termios (struct usb
 			err("%s error from disable flowcontrol urb", __FUNCTION__);
 		}	    
 		/* Drop RTS and DTR */
-		if (set_dtr(port, LOW) < 0){
-			err("%s Error from DTR LOW urb", __FUNCTION__);
-		}
-		if (set_rts(port, LOW) < 0){
-			err("%s Error from RTS LOW urb", __FUNCTION__);
-		}	
-		
+		clear_mctrl(port, TIOCM_DTR | TIOCM_RTS);
 	} else {
 		/* set the baudrate determined before */
 		if (change_speed(port)) {
 			err("%s urb failed to set baurdrate", __FUNCTION__);
 		}
 		/* Ensure  RTS and DTR are raised */
-		else if (set_dtr(port, HIGH) < 0){
-			err("%s Error from DTR HIGH urb", __FUNCTION__);
-		}
-		else if (set_rts(port, HIGH) < 0){
-			err("%s Error from RTS HIGH urb", __FUNCTION__);
-		}	
+		set_mctrl(port, TIOCM_DTR | TIOCM_RTS);
 	}
 
 	/* Set flow control */
@@ -2331,35 +1921,8 @@ static int ftdi_tiocmget (struct usb_ser
 
 static int ftdi_tiocmset(struct usb_serial_port *port, struct file * file, unsigned int set, unsigned int clear)
 {
-	int ret;
-	
 	dbg("%s TIOCMSET", __FUNCTION__);
-	if (set & TIOCM_DTR){
-		if ((ret = set_dtr(port, HIGH)) < 0) {
-			err("Urb to set DTR failed");
-			return(ret);
-		}
-	}
-	if (set & TIOCM_RTS) {
-		if ((ret = set_rts(port, HIGH)) < 0){
-			err("Urb to set RTS failed");
-			return(ret);
-		}
-	}
-	
-	if (clear & TIOCM_DTR){
-		if ((ret = set_dtr(port, LOW)) < 0){
-			err("Urb to unset DTR failed");
-			return(ret);
-		}
-	}	
-	if (clear & TIOCM_RTS) {
-		if ((ret = set_rts(port, LOW)) < 0){
-			err("Urb to unset RTS failed");
-			return(ret);
-		}
-	}
-	return(0);
+	return update_mctrl(port, set, clear);
 }
 
 
@@ -2367,60 +1930,11 @@ static int ftdi_ioctl (struct usb_serial
 {
 	struct ftdi_private *priv = usb_get_serial_port_data(port);
 
-	int  ret, mask;
-	
 	dbg("%s cmd 0x%04x", __FUNCTION__, cmd);
 
 	/* Based on code from acm.c and others */
 	switch (cmd) {
 
-	case TIOCMBIS: /* turns on (Sets) the lines as specified by the mask */
-		dbg("%s TIOCMBIS", __FUNCTION__);
- 	        if (get_user(mask, (unsigned long __user *) arg))
-			return -EFAULT;
-  	        if (mask & TIOCM_DTR){
-			if ((ret = set_dtr(port, HIGH)) < 0) {
-				err("Urb to set DTR failed");
-				return(ret);
-			}
-		}
-		if (mask & TIOCM_RTS) {
-			if ((ret = set_rts(port, HIGH)) < 0){
-				err("Urb to set RTS failed");
-				return(ret);
-			}
-		}
-		return(0);
-		break;
-
-	case TIOCMBIC: /* turns off (Clears) the lines as specified by the mask */
-		dbg("%s TIOCMBIC", __FUNCTION__);
- 	        if (get_user(mask, (unsigned long __user *) arg))
-			return -EFAULT;
-  	        if (mask & TIOCM_DTR){
-			if ((ret = set_dtr(port, LOW)) < 0){
-				err("Urb to unset DTR failed");
-				return(ret);
-			}
-		}	
-		if (mask & TIOCM_RTS) {
-			if ((ret = set_rts(port, LOW)) < 0){
-				err("Urb to unset RTS failed");
-				return(ret);
-			}
-		}
-		return(0);
-		break;
-
-		/*
-		 * I had originally implemented TCSET{A,S}{,F,W} and
-		 * TCGET{A,S} here separately, however when testing I
-		 * found that the higher layers actually do the termios
-		 * conversions themselves and pass the call onto
-		 * ftdi_sio_set_termios. 
-		 *
-		 */
-
 	case TIOCGSERIAL: /* gets serial port data */
 		return get_serial_info(port, (struct serial_struct __user *) arg);
 
@@ -2516,24 +2030,9 @@ static int __init ftdi_init (void)
 	int retval;
 
 	dbg("%s", __FUNCTION__);
-	retval = usb_serial_register(&ftdi_SIO_device);
-	if (retval)
-		goto failed_SIO_register;
-	retval = usb_serial_register(&ftdi_8U232AM_device);
-	if (retval)
-		goto failed_8U232AM_register;
-	retval = usb_serial_register(&ftdi_FT232BM_device);
-	if (retval)
-		goto failed_FT232BM_register;
-	retval = usb_serial_register(&ftdi_FT2232C_device);
-	if (retval)
-		goto failed_FT2232C_register;
-	retval = usb_serial_register(&ftdi_USB_UIRT_device);
-	if (retval)
-		goto failed_USB_UIRT_register;
-	retval = usb_serial_register(&ftdi_HE_TIRA1_device);
+	retval = usb_serial_register(&ftdi_sio_device);
 	if (retval)
-		goto failed_HE_TIRA1_register;
+		goto failed_sio_register;
 	retval = usb_register(&ftdi_driver);
 	if (retval) 
 		goto failed_usb_register;
@@ -2541,18 +2040,8 @@ static int __init ftdi_init (void)
 	info(DRIVER_VERSION ":" DRIVER_DESC);
 	return 0;
 failed_usb_register:
-	usb_serial_deregister(&ftdi_HE_TIRA1_device);
-failed_HE_TIRA1_register:
-	usb_serial_deregister(&ftdi_USB_UIRT_device);
-failed_USB_UIRT_register:
-	usb_serial_deregister(&ftdi_FT2232C_device);
-failed_FT2232C_register:
-	usb_serial_deregister(&ftdi_FT232BM_device);
-failed_FT232BM_register:
-	usb_serial_deregister(&ftdi_8U232AM_device);
-failed_8U232AM_register:
-	usb_serial_deregister(&ftdi_SIO_device);
-failed_SIO_register:
+	usb_serial_deregister(&ftdi_sio_device);
+failed_sio_register:
 	return retval;
 }
 
@@ -2563,12 +2052,7 @@ static void __exit ftdi_exit (void)
 	dbg("%s", __FUNCTION__);
 
 	usb_deregister (&ftdi_driver);
-	usb_serial_deregister (&ftdi_HE_TIRA1_device);
-	usb_serial_deregister (&ftdi_USB_UIRT_device);
-	usb_serial_deregister (&ftdi_FT2232C_device);
-	usb_serial_deregister (&ftdi_FT232BM_device);
-	usb_serial_deregister (&ftdi_8U232AM_device);
-	usb_serial_deregister (&ftdi_SIO_device);
+	usb_serial_deregister (&ftdi_sio_device);
 
 }
 
diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h
--- a/drivers/usb/serial/ftdi_sio.h
+++ b/drivers/usb/serial/ftdi_sio.h
@@ -265,10 +265,24 @@
 #define MOBILITY_USB_SERIAL_PID		0x0202	/* EasiDock USB 200 serial */
 
 /*
+ * microHAM product IDs (http://www.microham.com).
+ * Submitted by Justin Burket (KL1RL) <zorton@jtan.com>.
+ */
+#define FTDI_MHAM_Y6_PID 0xEEEA		/* USB-Y6 interface */
+#define FTDI_MHAM_Y8_PID 0xEEEB		/* USB-Y8 interface */
+
+/*
  * Active Robots product ids.
  */
 #define FTDI_ACTIVE_ROBOTS_PID	0xE548	/* USB comms board */
 
+/*
+ * Evolution Robotics products (http://www.evolution.com/).
+ * Submitted by Shawn M. Lavelle.
+ */
+#define EVOLUTION_VID		0xDEEE	/* Vendor ID */
+#define EVOLUTION_ER1_PID	0x0300	/* ER1 Control Module */
+
 /* Commands */
 #define FTDI_SIO_RESET 		0 /* Reset the port */
 #define FTDI_SIO_MODEM_CTRL 	1 /* Set the modem control register */
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c
--- a/drivers/usb/serial/generic.c
+++ b/drivers/usb/serial/generic.c
@@ -174,10 +174,14 @@ int usb_serial_generic_write(struct usb_
 
 	/* only do something if we have a bulk out endpoint */
 	if (serial->num_bulk_out) {
-		if (port->write_urb->status == -EINPROGRESS) {
+		spin_lock(&port->lock);
+		if (port->write_urb_busy) {
+			spin_unlock(&port->lock);
 			dbg("%s - already writing", __FUNCTION__);
-			return (0);
+			return 0;
 		}
+		port->write_urb_busy = 1;
+		spin_unlock(&port->lock);
 
 		count = (count > port->bulk_out_size) ? port->bulk_out_size : count;
 
@@ -195,17 +199,20 @@ int usb_serial_generic_write(struct usb_
 				     usb_serial_generic_write_bulk_callback), port);
 
 		/* send the data out the bulk port */
+		port->write_urb_busy = 1;
 		result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
-		if (result)
+		if (result) {
 			dev_err(&port->dev, "%s - failed submitting write urb, error %d\n", __FUNCTION__, result);
-		else
+			/* don't have to grab the lock here, as we will retry if != 0 */
+			port->write_urb_busy = 0;
+		} else
 			result = count;
 
 		return result;
 	}
 
 	/* no bulk out, so return 0 bytes written */
-	return (0);
+	return 0;
 }
 
 int usb_serial_generic_write_room (struct usb_serial_port *port)
@@ -214,9 +221,9 @@ int usb_serial_generic_write_room (struc
 	int room = 0;
 
 	dbg("%s - port %d", __FUNCTION__, port->number);
-	
+
 	if (serial->num_bulk_out) {
-		if (port->write_urb->status != -EINPROGRESS)
+		if (port->write_urb_busy)
 			room = port->bulk_out_size;
 	}
 
@@ -232,7 +239,7 @@ int usb_serial_generic_chars_in_buffer (
 	dbg("%s - port %d", __FUNCTION__, port->number);
 
 	if (serial->num_bulk_out) {
-		if (port->write_urb->status == -EINPROGRESS)
+		if (port->write_urb_busy)
 			chars = port->write_urb->transfer_buffer_length;
 	}
 
@@ -291,6 +298,7 @@ void usb_serial_generic_write_bulk_callb
 
 	dbg("%s - port %d", __FUNCTION__, port->number);
 
+	port->write_urb_busy = 0;
 	if (urb->status) {
 		dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, urb->status);
 		return;
diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c
--- a/drivers/usb/serial/ipaq.c
+++ b/drivers/usb/serial/ipaq.c
@@ -818,11 +818,6 @@ static void ipaq_write_gather(struct usb
 	struct ipaq_packet	*pkt, *tmp;
 	struct urb		*urb = port->write_urb;
 
-	if (urb->status == -EINPROGRESS) {
-		/* Should never happen */
-		err("%s - flushing while urb is active !", __FUNCTION__);
-		return;
-	}
 	room = URBDATA_SIZE;
 	list_for_each_entry_safe(pkt, tmp, &priv->queue, list) {
 		count = min(room, (int)(pkt->len - pkt->written));
diff --git a/drivers/usb/serial/ipw.c b/drivers/usb/serial/ipw.c
--- a/drivers/usb/serial/ipw.c
+++ b/drivers/usb/serial/ipw.c
@@ -399,16 +399,21 @@ static int ipw_write(struct usb_serial_p
 		dbg("%s - write request of 0 bytes", __FUNCTION__);
 		return 0;
 	}
-	
-	/* Racy and broken, FIXME properly! */
-	if (port->write_urb->status == -EINPROGRESS)
+
+	spin_lock(&port->lock);
+	if (port->write_urb_busy) {
+		spin_unlock(&port->lock);
+		dbg("%s - already writing", __FUNCTION__);
 		return 0;
+	}
+	port->write_urb_busy = 1;
+	spin_unlock(&port->lock);
 
 	count = min(count, port->bulk_out_size);
 	memcpy(port->bulk_out_buffer, buf, count);
 
 	dbg("%s count now:%d", __FUNCTION__, count);
-	
+
 	usb_fill_bulk_urb(port->write_urb, dev,
 			  usb_sndbulkpipe(dev, port->bulk_out_endpointAddress),
 			  port->write_urb->transfer_buffer,
@@ -418,6 +423,7 @@ static int ipw_write(struct usb_serial_p
 
 	ret = usb_submit_urb(port->write_urb, GFP_ATOMIC);
 	if (ret != 0) {
+		port->write_urb_busy = 0;
 		dbg("%s - usb_submit_urb(write bulk) failed with error = %d", __FUNCTION__, ret);
 		return ret;
 	}
diff --git a/drivers/usb/serial/ir-usb.c b/drivers/usb/serial/ir-usb.c
--- a/drivers/usb/serial/ir-usb.c
+++ b/drivers/usb/serial/ir-usb.c
@@ -341,10 +341,14 @@ static int ir_write (struct usb_serial_p
 	if (count == 0)
 		return 0;
 
-	if (port->write_urb->status == -EINPROGRESS) {
-		dbg ("%s - already writing", __FUNCTION__);
+	spin_lock(&port->lock);
+	if (port->write_urb_busy) {
+		spin_unlock(&port->lock);
+		dbg("%s - already writing", __FUNCTION__);
 		return 0;
 	}
+	port->write_urb_busy = 1;
+	spin_unlock(&port->lock);
 
 	transfer_buffer = port->write_urb->transfer_buffer;
 	transfer_size = min(count, port->bulk_out_size - 1);
@@ -374,9 +378,10 @@ static int ir_write (struct usb_serial_p
 	port->write_urb->transfer_flags = URB_ZERO_PACKET;
 
 	result = usb_submit_urb (port->write_urb, GFP_ATOMIC);
-	if (result)
+	if (result) {
+		port->write_urb_busy = 0;
 		dev_err(&port->dev, "%s - failed submitting write urb, error %d\n", __FUNCTION__, result);
-	else
+	} else
 		result = transfer_size;
 
 	return result;
@@ -387,7 +392,8 @@ static void ir_write_bulk_callback (stru
 	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
 
 	dbg("%s - port %d", __FUNCTION__, port->number);
-	
+
+	port->write_urb_busy = 0;
 	if (urb->status) {
 		dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, urb->status);
 		return;
diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c
--- a/drivers/usb/serial/keyspan_pda.c
+++ b/drivers/usb/serial/keyspan_pda.c
@@ -520,9 +520,13 @@ static int keyspan_pda_write(struct usb_
 	   the TX urb is in-flight (wait until it completes)
 	   the device is full (wait until it says there is room)
 	*/
-	if (port->write_urb->status == -EINPROGRESS || priv->tx_throttled ) {
-		return( 0 );
+	spin_lock(&port->lock);
+	if (port->write_urb_busy || priv->tx_throttled) {
+		spin_unlock(&port->lock);
+		return 0;
 	}
+	port->write_urb_busy = 1;
+	spin_unlock(&port->lock);
 
 	/* At this point the URB is in our control, nobody else can submit it
 	   again (the only sudden transition was the one from EINPROGRESS to
@@ -570,7 +574,7 @@ static int keyspan_pda_write(struct usb_
 		memcpy (port->write_urb->transfer_buffer, buf, count);
 		/* send the data out the bulk port */
 		port->write_urb->transfer_buffer_length = count;
-		
+
 		priv->tx_room -= count;
 
 		port->write_urb->dev = port->serial->dev;
@@ -593,6 +597,8 @@ static int keyspan_pda_write(struct usb_
 
 	rc = count;
 exit:
+	if (rc < 0)
+		port->write_urb_busy = 0;
 	return rc;
 }
 
@@ -602,6 +608,7 @@ static void keyspan_pda_write_bulk_callb
 	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
 	struct keyspan_pda_private *priv;
 
+	port->write_urb_busy = 0;
 	priv = usb_get_serial_port_data(port);
 
 	/* queue up a wakeup at scheduler time */
@@ -626,12 +633,12 @@ static int keyspan_pda_write_room (struc
 static int keyspan_pda_chars_in_buffer (struct usb_serial_port *port)
 {
 	struct keyspan_pda_private *priv;
-	
+
 	priv = usb_get_serial_port_data(port);
-	
+
 	/* when throttled, return at least WAKEUP_CHARS to tell select() (via
 	   n_tty.c:normal_poll() ) that we're not writeable. */
-	if( port->write_urb->status == -EINPROGRESS || priv->tx_throttled )
+	if (port->write_urb_busy || priv->tx_throttled)
 		return 256;
 	return 0;
 }
diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c
--- a/drivers/usb/serial/omninet.c
+++ b/drivers/usb/serial/omninet.c
@@ -254,10 +254,15 @@ static int omninet_write (struct usb_ser
 		dbg("%s - write request of 0 bytes", __FUNCTION__);
 		return (0);
 	}
-	if (wport->write_urb->status == -EINPROGRESS) {
+
+	spin_lock(&port->lock);
+	if (port->write_urb_busy) {
+		spin_unlock(&port->lock);
 		dbg("%s - already writing", __FUNCTION__);
-		return (0);
+		return 0;
 	}
+	port->write_urb_busy = 1;
+	spin_unlock(&port->lock);
 
 	count = (count > OMNINET_BULKOUTSIZE) ? OMNINET_BULKOUTSIZE : count;
 
@@ -275,9 +280,10 @@ static int omninet_write (struct usb_ser
 
 	wport->write_urb->dev = serial->dev;
 	result = usb_submit_urb(wport->write_urb, GFP_ATOMIC);
-	if (result)
+	if (result) {
+		port->write_urb_busy = 0;
 		err("%s - failed submitting write urb, error %d", __FUNCTION__, result);
-	else
+	} else
 		result = count;
 
 	return result;
@@ -291,7 +297,7 @@ static int omninet_write_room (struct us
 
 	int room = 0; // Default: no room
 
-	if (wport->write_urb->status != -EINPROGRESS)
+	if (wport->write_urb_busy)
 		room = wport->bulk_out_size - OMNINET_HEADERLEN;
 
 //	dbg("omninet_write_room returns %d", room);
@@ -306,6 +312,7 @@ static void omninet_write_bulk_callback 
 
 //	dbg("omninet_write_bulk_callback, port %0x\n", port);
 
+	port->write_urb_busy = 0;
 	if (urb->status) {
 		dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, urb->status);
 		return;
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -12,14 +12,25 @@
   History:
 
   2005-05-19  v0.1   Initial version, based on incomplete docs
-                     and analysis of misbehavior of the standard driver
+                     and analysis of misbehavior with the standard driver
   2005-05-20  v0.2   Extended the input buffer to avoid losing
                      random 64-byte chunks of data
   2005-05-21  v0.3   implemented chars_in_buffer()
                      turned on low_latency
                      simplified the code somewhat
+  2005-05-24  v0.4   option_write() sometimes deadlocked under heavy load
+                     removed some dead code
+                     added sponsor notice
+                     coding style clean-up
+  2005-06-20  v0.4.1 add missing braces :-/
+                     killed end-of-line whitespace
+  2005-07-15  v0.4.2 rename WLAN product to FUSION, add FUSION2
+
+  Work sponsored by: Sigos GmbH, Germany <info@sigos.de>
+
 */
-#define DRIVER_VERSION "v0.3"
+
+#define DRIVER_VERSION "v0.4"
 #define DRIVER_AUTHOR "Matthias Urlichs <smurf@smurf.noris.de>"
 #define DRIVER_DESC "Option Card (PC-Card to) USB to Serial Driver"
 
@@ -44,7 +55,6 @@ static int  option_write_room (struct us
 
 static void option_instat_callback(struct urb *urb, struct pt_regs *regs);
 
-
 static int  option_write (struct usb_serial_port *port,
                           const unsigned char *buf, int count);
 
@@ -60,14 +70,17 @@ static int  option_tiocmset (struct usb_
 static int  option_send_setup (struct usb_serial_port *port);
 
 /* Vendor and product IDs */
-#define OPTION_VENDOR_ID		0x0AF0
+#define OPTION_VENDOR_ID			0x0AF0
+
+#define OPTION_PRODUCT_OLD		0x5000
+#define OPTION_PRODUCT_FUSION	0x6000
+#define OPTION_PRODUCT_FUSION2	0x6300
 
-#define	OPTION_PRODUCT_OLD		0x5000
-#define	OPTION_PRODUCT_WLAN		0x6000
 
 static struct usb_device_id option_ids[] = {
 	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_OLD) },
-	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_WLAN) },
+	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION) },
+	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION2) },
 	{ } /* Terminating entry */
 };
 
@@ -85,58 +98,62 @@ static struct usb_driver option_driver =
  * recognizes separately, thus num_port=1.
  */
 static struct usb_serial_device_type option_3port_device = {
-	.owner			= THIS_MODULE,
-	.name			= "Option 3-port card",
-	.short_name		= "option",
-	.id_table		= option_ids,
-	.num_interrupt_in	= NUM_DONT_CARE,
-	.num_bulk_in		= NUM_DONT_CARE,
-	.num_bulk_out		= NUM_DONT_CARE,
-	.num_ports		= 1, /* 3 */
-	.open			= option_open,
-	.close			= option_close,
-	.write			= option_write,
-	.write_room		= option_write_room,
-	.chars_in_buffer	= option_chars_in_buffer,
-	.throttle		= option_rx_throttle,
-	.unthrottle		= option_rx_unthrottle,
-	.ioctl			= option_ioctl,
-	.set_termios		= option_set_termios,
-	.break_ctl		= option_break_ctl,
-	.tiocmget		= option_tiocmget,
-	.tiocmset		= option_tiocmset,
-	.attach			= option_startup,
-	.shutdown		= option_shutdown,
-	.read_int_callback	= option_instat_callback,
+	.owner             = THIS_MODULE,
+	.name              = "Option 3G data card",
+	.short_name        = "option",
+	.id_table          = option_ids,
+	.num_interrupt_in  = NUM_DONT_CARE,
+	.num_bulk_in       = NUM_DONT_CARE,
+	.num_bulk_out      = NUM_DONT_CARE,
+	.num_ports         = 1, /* 3, but the card reports its ports separately */
+	.open              = option_open,
+	.close             = option_close,
+	.write             = option_write,
+	.write_room        = option_write_room,
+	.chars_in_buffer   = option_chars_in_buffer,
+	.throttle          = option_rx_throttle,
+	.unthrottle        = option_rx_unthrottle,
+	.ioctl             = option_ioctl,
+	.set_termios       = option_set_termios,
+	.break_ctl         = option_break_ctl,
+	.tiocmget          = option_tiocmget,
+	.tiocmset          = option_tiocmset,
+	.attach            = option_startup,
+	.shutdown          = option_shutdown,
+	.read_int_callback = option_instat_callback,
 };
 
+#ifdef CONFIG_USB_DEBUG
 static int debug;
+#else
+#define debug 0
+#endif
+
 
 /* per port private data */
 
-#define N_IN_URB	4
-#define N_OUT_URB	1
-#define IN_BUFLEN	1024
-#define OUT_BUFLEN	1024
+#define N_IN_URB 4
+#define N_OUT_URB 1
+#define IN_BUFLEN 1024
+#define OUT_BUFLEN 128
 
 struct option_port_private {
 	/* Input endpoints and buffer for this port */
-	struct urb	*in_urbs[N_IN_URB];
-	char		in_buffer[N_IN_URB][IN_BUFLEN];
+	struct urb *in_urbs[N_IN_URB];
+	char in_buffer[N_IN_URB][IN_BUFLEN];
 	/* Output endpoints and buffer for this port */
-	struct urb	*out_urbs[N_OUT_URB];
-	char		out_buffer[N_OUT_URB][OUT_BUFLEN];
+	struct urb *out_urbs[N_OUT_URB];
+	char out_buffer[N_OUT_URB][OUT_BUFLEN];
 
 	/* Settings for the port */
-	int		rts_state;	/* Handshaking pins (outputs) */
-	int		dtr_state;
-	int		cts_state;	/* Handshaking pins (inputs) */
-	int		dsr_state;
-	int		dcd_state;
-	int		ri_state;
-	// int		break_on;
+	int rts_state;	/* Handshaking pins (outputs) */
+	int dtr_state;
+	int cts_state;	/* Handshaking pins (inputs) */
+	int dsr_state;
+	int dcd_state;
+	int ri_state;
 
-	unsigned long	tx_start_time[N_OUT_URB];
+	unsigned long tx_start_time[N_OUT_URB];
 };
 
 
@@ -190,13 +207,13 @@ static void
 option_break_ctl (struct usb_serial_port *port, int break_state)
 {
 	/* Unfortunately, I don't know how to send a break */
- 	dbg("%s", __FUNCTION__);
+	dbg("%s", __FUNCTION__);
 }
 
 
 static void
 option_set_termios (struct usb_serial_port *port,
-				     struct termios *old_termios)
+                    struct termios *old_termios)
 {
 	dbg("%s", __FUNCTION__);
 
@@ -204,10 +221,10 @@ option_set_termios (struct usb_serial_po
 }
 
 static int
-option_tiocmget(struct usb_serial_port *port, struct file *file)
+option_tiocmget (struct usb_serial_port *port, struct file *file)
 {
-	unsigned int			value;
-	struct option_port_private 	*portdata;
+	unsigned int value;
+	struct option_port_private *portdata;
 
 	portdata = usb_get_serial_port_data(port);
 
@@ -225,7 +242,7 @@ static int
 option_tiocmset (struct usb_serial_port *port, struct file *file,
                  unsigned int set, unsigned int clear)
 {
-	struct option_port_private 	*portdata;
+	struct option_port_private *portdata;
 
 	portdata = usb_get_serial_port_data(port);
 
@@ -250,71 +267,50 @@ option_ioctl (struct usb_serial_port *po
 
 /* Write */
 static int
-option_write(struct usb_serial_port *port,
-			 const unsigned char *buf, int count)
+option_write (struct usb_serial_port *port,
+			  const unsigned char *buf, int count)
 {
-	struct option_port_private 	*portdata;
-	int				i;
-	int 				left, todo;
-	struct urb			*this_urb = NULL; /* spurious */
- 	int 				err;
+	struct option_port_private *portdata;
+	int i;
+	int left, todo;
+	struct urb *this_urb = NULL; /* spurious */
+	int err;
 
 	portdata = usb_get_serial_port_data(port);
 
 	dbg("%s: write (%d chars)", __FUNCTION__, count);
 
-#if 0
-	spin_lock(&port->lock);
-	if (port->write_urb_busy) {
-		spin_unlock(&port->lock);
-		dbg("%s: already writing", __FUNCTION__);
-		return 0;
-	}
-	port->write_urb_busy = 1;
-	spin_unlock(&port->lock);
-#endif
-
 	i = 0;
 	left = count;
-	while (left>0) {
+	for (i=0; left > 0 && i < N_OUT_URB; i++) {
 		todo = left;
 		if (todo > OUT_BUFLEN)
 			todo = OUT_BUFLEN;
 
-		for (;i < N_OUT_URB; i++) {
-			/* Check we have a valid urb/endpoint before we use it... */
-			this_urb = portdata->out_urbs[i];
-			if (this_urb->status != -EINPROGRESS)
-				break;
+		this_urb = portdata->out_urbs[i];
+		if (this_urb->status == -EINPROGRESS) {
 			if (this_urb->transfer_flags & URB_ASYNC_UNLINK)
 				continue;
 			if (time_before(jiffies, portdata->tx_start_time[i] + 10 * HZ))
 				continue;
 			this_urb->transfer_flags |= URB_ASYNC_UNLINK;
 			usb_unlink_urb(this_urb);
+			continue;
 		}
-
-		if (i == N_OUT_URB) {
-			/* no bulk out free! */
-			dbg("%s: no output urb -- left %d", __FUNCTION__,count-left);
-#if 0
-			port->write_urb_busy = 0;
-#endif
-			return count-left;
-		}
+		if (this_urb->status != 0)
+			dbg("usb_write %p failed (err=%d)", this_urb, this_urb->status);
 
 		dbg("%s: endpoint %d buf %d", __FUNCTION__, usb_pipeendpoint(this_urb->pipe), i);
 
+		/* send the data */
 		memcpy (this_urb->transfer_buffer, buf, todo);
-
-		/* send the data out the bulk port */
 		this_urb->transfer_buffer_length = todo;
 
 		this_urb->transfer_flags &= ~URB_ASYNC_UNLINK;
 		this_urb->dev = port->serial->dev;
 		err = usb_submit_urb(this_urb, GFP_ATOMIC);
 		if (err) {
-			dbg("usb_submit_urb %p (write bulk) failed (%d,, has %d)", this_urb, err, this_urb->status);
+			dbg("usb_submit_urb %p (write bulk) failed (%d, has %d)", this_urb, err, this_urb->status);
 			continue;
 		}
 		portdata->tx_start_time[i] = jiffies;
@@ -323,9 +319,6 @@ option_write(struct usb_serial_port *por
 	}
 
 	count -= left;
-#if 0
-	port->write_urb_busy = 0;
-#endif
 	dbg("%s: wrote (did %d)", __FUNCTION__, count);
 	return count;
 }
@@ -333,7 +326,7 @@ option_write(struct usb_serial_port *por
 static void
 option_indat_callback (struct urb *urb, struct pt_regs *regs)
 {
-	int	i, err;
+	int i, err;
 	int endpoint;
 	struct usb_serial_port *port;
 	struct tty_struct *tty;
@@ -444,10 +437,11 @@ option_write_room (struct usb_serial_por
 
 	portdata = usb_get_serial_port_data(port);
 
-	for (i=0; i < N_OUT_URB; i++)
+	for (i=0; i < N_OUT_URB; i++) {
 		this_urb = portdata->out_urbs[i];
 		if (this_urb && this_urb->status != -EINPROGRESS)
 			data_len += OUT_BUFLEN;
+	}
 
 	dbg("%s: %d", __FUNCTION__, data_len);
 	return data_len;
@@ -464,11 +458,11 @@ option_chars_in_buffer (struct usb_seria
 
 	portdata = usb_get_serial_port_data(port);
 
-	for (i=0; i < N_OUT_URB; i++)
+	for (i=0; i < N_OUT_URB; i++) {
 		this_urb = portdata->out_urbs[i];
 		if (this_urb && this_urb->status == -EINPROGRESS)
 			data_len += this_urb->transfer_buffer_length;
-
+	}
 	dbg("%s: %d", __FUNCTION__, data_len);
 	return data_len;
 }
@@ -477,10 +471,10 @@ option_chars_in_buffer (struct usb_seria
 static int
 option_open (struct usb_serial_port *port, struct file *filp)
 {
-	struct option_port_private 	*portdata;
-	struct usb_serial 		*serial = port->serial;
-	int				i, err;
-	struct urb			*urb;
+	struct option_port_private *portdata;
+	struct usb_serial *serial = port->serial;
+	int i, err;
+	struct urb *urb;
 
 	portdata = usb_get_serial_port_data(port);
 
@@ -528,7 +522,7 @@ option_open (struct usb_serial_port *por
 }
 
 static inline void
-stop_urb(struct urb *urb)
+stop_urb (struct urb *urb)
 {
 	if (urb && urb->status == -EINPROGRESS) {
 		urb->transfer_flags &= ~URB_ASYNC_UNLINK;
@@ -537,11 +531,11 @@ stop_urb(struct urb *urb)
 }
 
 static void
-option_close(struct usb_serial_port *port, struct file *filp)
+option_close (struct usb_serial_port *port, struct file *filp)
 {
-	int			i;
-	struct usb_serial	*serial = port->serial;
-	struct option_port_private 	*portdata;
+	int i;
+	struct usb_serial *serial = port->serial;
+	struct option_port_private *portdata;
 
 	dbg("%s", __FUNCTION__);
 	portdata = usb_get_serial_port_data(port);
@@ -589,11 +583,11 @@ option_setup_urb (struct usb_serial *ser
 
 /* Setup urbs */
 static void
-option_setup_urbs(struct usb_serial *serial)
+option_setup_urbs (struct usb_serial *serial)
 {
-	int				j;
-	struct usb_serial_port		*port;
-	struct option_port_private	*portdata;
+	int j;
+	struct usb_serial_port *port;
+	struct option_port_private *portdata;
 
 	dbg("%s", __FUNCTION__);
 
@@ -617,7 +611,7 @@ option_setup_urbs(struct usb_serial *ser
 
 
 static int
-option_send_setup(struct usb_serial_port *port)
+option_send_setup (struct usb_serial_port *port)
 {
 	struct usb_serial *serial = port->serial;
 	struct option_port_private *portdata;
@@ -644,9 +638,9 @@ option_send_setup(struct usb_serial_port
 static int
 option_startup (struct usb_serial *serial)
 {
-	int				i, err;
-	struct usb_serial_port		*port;
-	struct option_port_private	*portdata;
+	int i, err;
+	struct usb_serial_port *port;
+	struct option_port_private *portdata;
 
 	dbg("%s", __FUNCTION__);
 
@@ -677,9 +671,9 @@ option_startup (struct usb_serial *seria
 static void
 option_shutdown (struct usb_serial *serial)
 {
-	int				i, j;
-	struct usb_serial_port		*port;
-	struct option_port_private	*portdata;
+	int i, j;
+	struct usb_serial_port *port;
+	struct option_port_private *portdata;
 
 	dbg("%s", __FUNCTION__);
 
@@ -724,6 +718,8 @@ MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_VERSION(DRIVER_VERSION);
 MODULE_LICENSE("GPL");
 
+#ifdef CONFIG_USB_DEBUG
 module_param(debug, bool, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(debug, "Debug messages");
+#endif
 
diff --git a/drivers/usb/serial/safe_serial.c b/drivers/usb/serial/safe_serial.c
--- a/drivers/usb/serial/safe_serial.c
+++ b/drivers/usb/serial/safe_serial.c
@@ -299,10 +299,14 @@ static int safe_write (struct usb_serial
 		dbg ("%s - write request of 0 bytes", __FUNCTION__);
 		return (0);
 	}
-	if (port->write_urb->status == -EINPROGRESS) {
-		dbg ("%s - already writing", __FUNCTION__);
-		return (0);
+	spin_lock(&port->lock);
+	if (port->write_urb_busy) {
+		spin_unlock(&port->lock);
+		dbg("%s - already writing", __FUNCTION__);
+		return 0;
 	}
+	port->write_urb_busy = 1;
+	spin_unlock(&port->lock);
 
 	packet_length = port->bulk_out_size;	// get max packetsize
 
@@ -354,6 +358,7 @@ static int safe_write (struct usb_serial
 #endif
 	port->write_urb->dev = port->serial->dev;
 	if ((result = usb_submit_urb (port->write_urb, GFP_KERNEL))) {
+		port->write_urb_busy = 0;
 		err ("%s - failed submitting write urb, error %d", __FUNCTION__, result);
 		return 0;
 	}
@@ -368,7 +373,7 @@ static int safe_write_room (struct usb_s
 
 	dbg ("%s", __FUNCTION__);
 
-	if (port->write_urb->status != -EINPROGRESS)
+	if (port->write_urb_busy)
 		room = port->bulk_out_size - (safe ? 2 : 0);
 
 	if (room) {
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -1047,6 +1047,7 @@ int usb_serial_probe(struct usb_interfac
 		memset(port, 0x00, sizeof(struct usb_serial_port));
 		port->number = i + serial->minor;
 		port->serial = serial;
+		spin_lock_init(&port->lock);
 		INIT_WORK(&port->work, usb_serial_port_softint, port);
 		serial->port[i] = port;
 	}
diff --git a/drivers/usb/serial/usb-serial.h b/drivers/usb/serial/usb-serial.h
--- a/drivers/usb/serial/usb-serial.h
+++ b/drivers/usb/serial/usb-serial.h
@@ -69,6 +69,7 @@
  * usb_serial_port: structure for the specific ports of a device.
  * @serial: pointer back to the struct usb_serial owner of this port.
  * @tty: pointer to the corresponding tty for this port.
+ * @lock: spinlock to grab when updating portions of this structure.
  * @number: the number of the port (the minor number).
  * @interrupt_in_buffer: pointer to the interrupt in buffer for this port.
  * @interrupt_in_urb: pointer to the interrupt in struct urb for this port.
@@ -98,6 +99,7 @@
 struct usb_serial_port {
 	struct usb_serial *	serial;
 	struct tty_struct *	tty;
+	spinlock_t		lock;
 	unsigned char		number;
 
 	unsigned char *		interrupt_in_buffer;
@@ -117,6 +119,7 @@ struct usb_serial_port {
 	unsigned char *		bulk_out_buffer;
 	int			bulk_out_size;
 	struct urb *		write_urb;
+	int			write_urb_busy;
 	__u8			bulk_out_endpointAddress;
 
 	wait_queue_head_t	write_wait;
diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c
--- a/drivers/usb/storage/scsiglue.c
+++ b/drivers/usb/storage/scsiglue.c
@@ -155,6 +155,15 @@ static int slave_configure(struct scsi_d
 		 * If this device makes that mistake, tell the sd driver. */
 		if (us->flags & US_FL_FIX_CAPACITY)
 			sdev->fix_capacity = 1;
+
+		/* USB-IDE bridges tend to report SK = 0x04 (Non-recoverable
+		 * Hardware Error) when any low-level error occurs,
+		 * recoverable or not.  Setting this flag tells the SCSI
+		 * midlayer to retry such commands, which frequently will
+		 * succeed and fix the error.  The worst this can lead to
+		 * is an occasional series of retries that will all fail. */
+		sdev->retry_hwerror = 1;
+
 	} else {
 
 		/* Non-disk-type devices don't need to blacklist any pages
@@ -233,13 +242,11 @@ static int command_abort(struct scsi_cmn
 		set_bit(US_FLIDX_ABORTING, &us->flags);
 		usb_stor_stop_transport(us);
 	}
-	scsi_unlock(us_to_host(us));
 
 	/* Wait for the aborted command to finish */
 	wait_for_completion(&us->notify);
 
 	/* Reacquire the lock and allow USB transfers to resume */
-	scsi_lock(us_to_host(us));
 	clear_bit(US_FLIDX_ABORTING, &us->flags);
 	clear_bit(US_FLIDX_TIMED_OUT, &us->flags);
 	return SUCCESS;
@@ -255,62 +262,28 @@ static int device_reset(struct scsi_cmnd
 
 	US_DEBUGP("%s called\n", __FUNCTION__);
 
-	scsi_unlock(us_to_host(us));
-
 	/* lock the device pointers and do the reset */
 	down(&(us->dev_semaphore));
-	if (test_bit(US_FLIDX_DISCONNECTING, &us->flags)) {
-		result = FAILED;
-		US_DEBUGP("No reset during disconnect\n");
-	} else
-		result = us->transport_reset(us);
+	result = us->transport_reset(us);
 	up(&(us->dev_semaphore));
 
-	/* lock the host for the return */
-	scsi_lock(us_to_host(us));
-	return result;
+	return result < 0 ? FAILED : SUCCESS;
 }
 
-/* This resets the device's USB port. */
-/* It refuses to work if there's more than one interface in
- * the device, so that other users are not affected. */
+/* Simulate a SCSI bus reset by resetting the device's USB port. */
 /* This is always called with scsi_lock(host) held */
 static int bus_reset(struct scsi_cmnd *srb)
 {
 	struct us_data *us = host_to_us(srb->device->host);
-	int result, rc;
+	int result;
 
 	US_DEBUGP("%s called\n", __FUNCTION__);
 
-	scsi_unlock(us_to_host(us));
-
-	/* The USB subsystem doesn't handle synchronisation between
-	 * a device's several drivers. Therefore we reset only devices
-	 * with just one interface, which we of course own. */
-
 	down(&(us->dev_semaphore));
-	if (test_bit(US_FLIDX_DISCONNECTING, &us->flags)) {
-		result = -EIO;
-		US_DEBUGP("No reset during disconnect\n");
-	} else if (us->pusb_dev->actconfig->desc.bNumInterfaces != 1) {
-		result = -EBUSY;
-		US_DEBUGP("Refusing to reset a multi-interface device\n");
-	} else {
-		rc = usb_lock_device_for_reset(us->pusb_dev, us->pusb_intf);
-		if (rc < 0) {
-			US_DEBUGP("unable to lock device for reset: %d\n", rc);
-			result = rc;
-		} else {
-			result = usb_reset_device(us->pusb_dev);
-			if (rc)
-				usb_unlock_device(us->pusb_dev);
-			US_DEBUGP("usb_reset_device returns %d\n", result);
-		}
-	}
+	result = usb_stor_port_reset(us);
 	up(&(us->dev_semaphore));
 
 	/* lock the host for the return */
-	scsi_lock(us_to_host(us));
 	return result < 0 ? FAILED : SUCCESS;
 }
 
@@ -329,6 +302,14 @@ void usb_stor_report_device_reset(struct
 	}
 }
 
+/* Report a driver-initiated bus reset to the SCSI layer.
+ * Calling this for a SCSI-initiated reset is unnecessary but harmless.
+ * The caller must own the SCSI host lock. */
+void usb_stor_report_bus_reset(struct us_data *us)
+{
+	scsi_report_bus_reset(us_to_host(us), 0);
+}
+
 /***********************************************************************
  * /proc/scsi/ functions
  ***********************************************************************/
@@ -407,7 +388,7 @@ US_DO_ALL_FLAGS
  ***********************************************************************/
 
 /* Output routine for the sysfs max_sectors file */
-static ssize_t show_max_sectors(struct device *dev, char *buf)
+static ssize_t show_max_sectors(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct scsi_device *sdev = to_scsi_device(dev);
 
@@ -415,7 +396,7 @@ static ssize_t show_max_sectors(struct d
 }
 
 /* Input routine for the sysfs max_sectors file */
-static ssize_t store_max_sectors(struct device *dev, const char *buf,
+static ssize_t store_max_sectors(struct device *dev, struct device_attribute *attr, const char *buf,
 		size_t count)
 {
 	struct scsi_device *sdev = to_scsi_device(dev);
diff --git a/drivers/usb/storage/scsiglue.h b/drivers/usb/storage/scsiglue.h
--- a/drivers/usb/storage/scsiglue.h
+++ b/drivers/usb/storage/scsiglue.h
@@ -42,6 +42,7 @@
 #define _SCSIGLUE_H_
 
 extern void usb_stor_report_device_reset(struct us_data *us);
+extern void usb_stor_report_bus_reset(struct us_data *us);
 
 extern unsigned char usb_stor_sense_invalidCDB[18];
 extern struct scsi_host_template usb_stor_host_template;
diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c
--- a/drivers/usb/storage/transport.c
+++ b/drivers/usb/storage/transport.c
@@ -266,8 +266,9 @@ int usb_stor_clear_halt(struct us_data *
 		NULL, 0, 3*HZ);
 
 	/* reset the endpoint toggle */
-	usb_settoggle(us->pusb_dev, usb_pipeendpoint(pipe),
-		usb_pipeout(pipe), 0);
+	if (result >= 0)
+		usb_settoggle(us->pusb_dev, usb_pipeendpoint(pipe),
+				usb_pipeout(pipe), 0);
 
 	US_DEBUGP("%s: result = %d\n", __FUNCTION__, result);
 	return result;
@@ -540,15 +541,15 @@ void usb_stor_invoke_transport(struct sc
 	 */
 	if (test_bit(US_FLIDX_TIMED_OUT, &us->flags)) {
 		US_DEBUGP("-- command was aborted\n");
-		goto Handle_Abort;
+		srb->result = DID_ABORT << 16;
+		goto Handle_Errors;
 	}
 
 	/* if there is a transport error, reset and don't auto-sense */
 	if (result == USB_STOR_TRANSPORT_ERROR) {
 		US_DEBUGP("-- transport indicates error, resetting\n");
-		us->transport_reset(us);
 		srb->result = DID_ERROR << 16;
-		return;
+		goto Handle_Errors;
 	}
 
 	/* if the transport provided its own sense data, don't auto-sense */
@@ -668,7 +669,8 @@ void usb_stor_invoke_transport(struct sc
 
 		if (test_bit(US_FLIDX_TIMED_OUT, &us->flags)) {
 			US_DEBUGP("-- auto-sense aborted\n");
-			goto Handle_Abort;
+			srb->result = DID_ABORT << 16;
+			goto Handle_Errors;
 		}
 		if (temp_result != USB_STOR_TRANSPORT_GOOD) {
 			US_DEBUGP("-- auto-sense failure\n");
@@ -677,9 +679,9 @@ void usb_stor_invoke_transport(struct sc
 			 * multi-target device, since failure of an
 			 * auto-sense is perfectly valid
 			 */
-			if (!(us->flags & US_FL_SCM_MULT_TARG))
-				us->transport_reset(us);
 			srb->result = DID_ERROR << 16;
+			if (!(us->flags & US_FL_SCM_MULT_TARG))
+				goto Handle_Errors;
 			return;
 		}
 
@@ -720,12 +722,28 @@ void usb_stor_invoke_transport(struct sc
 
 	return;
 
-	/* abort processing: the bulk-only transport requires a reset
-	 * following an abort */
-  Handle_Abort:
-	srb->result = DID_ABORT << 16;
-	if (us->protocol == US_PR_BULK)
+	/* Error and abort processing: try to resynchronize with the device
+	 * by issuing a port reset.  If that fails, try a class-specific
+	 * device reset. */
+  Handle_Errors:
+
+	/* Let the SCSI layer know we are doing a reset, set the
+	 * RESETTING bit, and clear the ABORTING bit so that the reset
+	 * may proceed. */
+	scsi_lock(us_to_host(us));
+	usb_stor_report_bus_reset(us);
+	set_bit(US_FLIDX_RESETTING, &us->flags);
+	clear_bit(US_FLIDX_ABORTING, &us->flags);
+	scsi_unlock(us_to_host(us));
+
+	result = usb_stor_port_reset(us);
+	if (result < 0) {
+		scsi_lock(us_to_host(us));
+		usb_stor_report_device_reset(us);
+		scsi_unlock(us_to_host(us));
 		us->transport_reset(us);
+	}
+	clear_bit(US_FLIDX_RESETTING, &us->flags);
 }
 
 /* Stop the current URB transfer */
@@ -1124,7 +1142,7 @@ int usb_stor_Bulk_transport(struct scsi_
  * It's handy that every transport mechanism uses the control endpoint for
  * resets.
  *
- * Basically, we send a reset with a 20-second timeout, so we don't get
+ * Basically, we send a reset with a 5-second timeout, so we don't get
  * jammed attempting to do the reset.
  */
 static int usb_stor_reset_common(struct us_data *us,
@@ -1133,28 +1151,18 @@ static int usb_stor_reset_common(struct 
 {
 	int result;
 	int result2;
-	int rc = FAILED;
 
-	/* Let the SCSI layer know we are doing a reset, set the
-	 * RESETTING bit, and clear the ABORTING bit so that the reset
-	 * may proceed.
-	 */
-	scsi_lock(us_to_host(us));
-	usb_stor_report_device_reset(us);
-	set_bit(US_FLIDX_RESETTING, &us->flags);
-	clear_bit(US_FLIDX_ABORTING, &us->flags);
-	scsi_unlock(us_to_host(us));
+	if (test_bit(US_FLIDX_DISCONNECTING, &us->flags)) {
+		US_DEBUGP("No reset during disconnect\n");
+		return -EIO;
+	}
 
-	/* A 20-second timeout may seem rather long, but a LaCie
-	 * StudioDrive USB2 device takes 16+ seconds to get going
-	 * following a powerup or USB attach event.
-	 */
 	result = usb_stor_control_msg(us, us->send_ctrl_pipe,
 			request, requesttype, value, index, data, size,
-			20*HZ);
+			5*HZ);
 	if (result < 0) {
 		US_DEBUGP("Soft reset failed: %d\n", result);
-		goto Done;
+		return result;
 	}
 
  	/* Give the device some time to recover from the reset,
@@ -1164,7 +1172,7 @@ static int usb_stor_reset_common(struct 
  			HZ*6);
 	if (test_bit(US_FLIDX_DISCONNECTING, &us->flags)) {
 		US_DEBUGP("Reset interrupted by disconnect\n");
-		goto Done;
+		return -EIO;
 	}
 
 	US_DEBUGP("Soft reset: clearing bulk-in endpoint halt\n");
@@ -1173,17 +1181,14 @@ static int usb_stor_reset_common(struct 
 	US_DEBUGP("Soft reset: clearing bulk-out endpoint halt\n");
 	result2 = usb_stor_clear_halt(us, us->send_bulk_pipe);
 
-	/* return a result code based on the result of the control message */
-	if (result < 0 || result2 < 0) {
+	/* return a result code based on the result of the clear-halts */
+	if (result >= 0)
+		result = result2;
+	if (result < 0)
 		US_DEBUGP("Soft reset failed\n");
-		goto Done;
-	}
-	US_DEBUGP("Soft reset done\n");
-	rc = SUCCESS;
-
-  Done:
-	clear_bit(US_FLIDX_RESETTING, &us->flags);
-	return rc;
+	else
+		US_DEBUGP("Soft reset done\n");
+	return result;
 }
 
 /* This issues a CB[I] Reset to the device in question
@@ -1213,3 +1218,32 @@ int usb_stor_Bulk_reset(struct us_data *
 				 USB_TYPE_CLASS | USB_RECIP_INTERFACE,
 				 0, us->ifnum, NULL, 0);
 }
+
+/* Issue a USB port reset to the device.  But don't do anything if
+ * there's more than one interface in the device, so that other users
+ * are not affected. */
+int usb_stor_port_reset(struct us_data *us)
+{
+	int result, rc;
+
+	if (test_bit(US_FLIDX_DISCONNECTING, &us->flags)) {
+		result = -EIO;
+		US_DEBUGP("No reset during disconnect\n");
+	} else if (us->pusb_dev->actconfig->desc.bNumInterfaces != 1) {
+		result = -EBUSY;
+		US_DEBUGP("Refusing to reset a multi-interface device\n");
+	} else {
+		result = rc =
+			usb_lock_device_for_reset(us->pusb_dev, us->pusb_intf);
+		if (result < 0) {
+			US_DEBUGP("unable to lock device for reset: %d\n",
+					result);
+		} else {
+			result = usb_reset_device(us->pusb_dev);
+			if (rc)
+				usb_unlock_device(us->pusb_dev);
+			US_DEBUGP("usb_reset_device returns %d\n", result);
+		}
+	}
+	return result;
+}
diff --git a/drivers/usb/storage/transport.h b/drivers/usb/storage/transport.h
--- a/drivers/usb/storage/transport.h
+++ b/drivers/usb/storage/transport.h
@@ -171,4 +171,5 @@ extern int usb_stor_bulk_transfer_buf(st
 extern int usb_stor_bulk_transfer_sg(struct us_data *us, unsigned int pipe,
 		void *buf, unsigned int length, int use_sg, int *residual);
 
+extern int usb_stor_port_reset(struct us_data *us);
 #endif
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
--- a/drivers/usb/storage/unusual_devs.h
+++ b/drivers/usb/storage/unusual_devs.h
@@ -697,7 +697,7 @@ UNUSUAL_DEV(  0x07af, 0x0004, 0x0100, 0x
 UNUSUAL_DEV(  0x07af, 0x0005, 0x0100, 0x0100, 
 		"Microtech",
 		"USB-SCSI-HD50",
-		US_SC_SCSI, US_PR_BULK, usb_stor_euscsi_init,
+		US_SC_DEVICE, US_PR_DEVICE, usb_stor_euscsi_init,
 		US_FL_SCM_MULT_TARG ), 
 
 #ifdef CONFIG_USB_STORAGE_DPCM
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c
--- a/drivers/usb/storage/usb.c
+++ b/drivers/usb/storage/usb.c
@@ -847,10 +847,8 @@ retry:
 		wait_event_interruptible_timeout(us->delay_wait,
 				test_bit(US_FLIDX_DISCONNECTING, &us->flags),
 				delay_use * HZ);
-		if (current->flags & PF_FREEZE) {
-			refrigerator(PF_FREEZE);
+		if (try_to_freeze())
 			goto retry;
-		}
 	}
 
 	/* If the device is still connected, perform the scanning */
diff --git a/drivers/usb/usb-skeleton.c b/drivers/usb/usb-skeleton.c
--- a/drivers/usb/usb-skeleton.c
+++ b/drivers/usb/usb-skeleton.c
@@ -257,7 +257,8 @@ static int skel_probe(struct usb_interfa
 		endpoint = &iface_desc->endpoint[i].desc;
 
 		if (!dev->bulk_in_endpointAddr &&
-		    (endpoint->bEndpointAddress & USB_DIR_IN) &&
+		    ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
+					== USB_DIR_IN) &&
 		    ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
 					== USB_ENDPOINT_XFER_BULK)) {
 			/* we found a bulk in endpoint */
@@ -272,7 +273,8 @@ static int skel_probe(struct usb_interfa
 		}
 
 		if (!dev->bulk_out_endpointAddr &&
-		    !(endpoint->bEndpointAddress & USB_DIR_OUT) &&
+		    ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
+					== USB_DIR_OUT) &&
 		    ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
 					== USB_ENDPOINT_XFER_BULK)) {
 			/* we found a bulk out endpoint */
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -322,6 +322,22 @@ config FB_FM2
 	  This is the frame buffer device driver for the Amiga FrameMaster
 	  card from BSC (exhibited 1992 but not shipped as a CBM product).
 
+config FB_ARC
+	tristate "Arc Monochrome LCD board support"
+	depends on FB && X86
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	select FB_SOFT_CURSOR
+	help
+	  This enables support for the Arc Monochrome LCD board. The board
+	  is based on the KS-108 lcd controller and is typically a matrix
+	  of 2*n chips. This driver was tested with a 128x64 panel. This
+	  driver supports it for use with x86 SBCs through a 16 bit GPIO
+	  interface (8 bit data, 8 bit control). If you anticpate using
+	  this driver, say Y or M; otherwise say N. You must specify the
+	  GPIO IO address to be used for setting control and data.
+
 config FB_ATARI
 	bool "Atari native chipset support"
 	depends on (FB = y) && ATARI && BROKEN
@@ -1383,8 +1399,8 @@ config FB_TX3912
 	  Say Y here to enable kernel support for the on-board framebuffer.
 
 config FB_G364
-	bool
-	depends on MIPS_MAGNUM_4000 || OLIVETTI_M700
+	bool "G364 frame buffer support"
+	depends on (FB = y) && (MIPS_MAGNUM_4000 || OLIVETTI_M700)
  	select FB_CFB_FILLRECT
  	select FB_CFB_COPYAREA
  	select FB_CFB_IMAGEBLIT
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -21,6 +21,7 @@ obj-$(CONFIG_FB_MACMODES)      += macmod
 # Hardware specific drivers go first
 obj-$(CONFIG_FB_RETINAZ3)         += retz3fb.o
 obj-$(CONFIG_FB_AMIGA)            += amifb.o c2p.o
+obj-$(CONFIG_FB_ARC)              += arcfb.o
 obj-$(CONFIG_FB_CLPS711X)         += clps711xfb.o
 obj-$(CONFIG_FB_CYBER)            += cyberfb.o
 obj-$(CONFIG_FB_CYBER2000)        += cyber2000fb.o
diff --git a/drivers/video/arcfb.c b/drivers/video/arcfb.c
new file mode 100644
--- /dev/null
+++ b/drivers/video/arcfb.c
@@ -0,0 +1,684 @@
+/*
+ * linux/drivers/video/arcfb.c -- FB driver for Arc monochrome LCD board
+ *
+ * Copyright (C) 2005, Jaya Kumar <jayalk@intworks.biz>
+ * http://www.intworks.biz/arclcd
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive for
+ * more details.
+ *
+ * Layout is based on skeletonfb.c by James Simmons and Geert Uytterhoeven.
+ *
+ * This driver was written to be used with the Arc LCD board. Arc uses a
+ * set of KS108 chips that control individual 64x64 LCD matrices. The board
+ * can be paneled in a variety of setups such as 2x1=128x64, 4x4=256x256 and
+ * so on. The interface between the board and the host is TTL based GPIO. The
+ * GPIO requirements are 8 writable data lines and 4+n lines for control. On a
+ * GPIO-less system, the board can be tested by connecting the respective sigs
+ * up to a parallel port connector. The driver requires the IO addresses for
+ * data and control GPIO at load time. It is unable to probe for the
+ * existence of the LCD so it must be told at load time whether it should
+ * be enabled or not.
+ *
+ * Todo:
+ * - testing with 4x4
+ * - testing with interrupt hw
+ *
+ * General notes:
+ * - User must set tuhold. It's in microseconds. According to the 108 spec,
+ *   the hold time is supposed to be at least 1 microsecond.
+ * - User must set num_cols=x num_rows=y, eg: x=2 means 128
+ * - User must set arcfb_enable=1 to enable it
+ * - User must set dio_addr=0xIOADDR cio_addr=0xIOADDR
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/arcfb.h>
+
+#include <asm/uaccess.h>
+
+#define floor8(a) (a&(~0x07))
+#define floorXres(a,xres) (a&(~(xres - 1)))
+#define iceil8(a) (((int)((a+7)/8))*8)
+#define ceil64(a) (a|0x3F)
+#define ceilXres(a,xres) (a|(xres - 1))
+
+/* ks108 chipset specific defines and code */
+
+#define KS_SET_DPY_START_LINE 	0xC0
+#define KS_SET_PAGE_NUM 	0xB8
+#define KS_SET_X 		0x40
+#define KS_CEHI 		0x01
+#define KS_CELO 		0x00
+#define KS_SEL_CMD 		0x08
+#define KS_SEL_DATA 		0x00
+#define KS_DPY_ON 		0x3F
+#define KS_DPY_OFF 		0x3E
+#define KS_INTACK 		0x40
+#define KS_CLRINT		0x02
+
+struct arcfb_par {
+	unsigned long dio_addr;
+	unsigned long cio_addr;
+	unsigned long c2io_addr;
+	atomic_t ref_count;
+	unsigned char cslut[9];
+	struct fb_info *info;
+	unsigned int irq;
+	spinlock_t lock;
+};
+
+static struct fb_fix_screeninfo arcfb_fix __initdata = {
+	.id =		"arcfb",
+	.type =		FB_TYPE_PACKED_PIXELS,
+	.visual =	FB_VISUAL_MONO01,
+	.xpanstep =	0,
+	.ypanstep =	1,
+	.ywrapstep =	0,
+	.accel =	FB_ACCEL_NONE,
+};
+
+static struct fb_var_screeninfo arcfb_var __initdata = {
+	.xres		= 128,
+	.yres		= 64,
+	.xres_virtual	= 128,
+	.yres_virtual	= 64,
+	.bits_per_pixel	= 1,
+	.nonstd		= 1,
+};
+
+static unsigned long num_cols;
+static unsigned long num_rows;
+static unsigned long dio_addr;
+static unsigned long cio_addr;
+static unsigned long c2io_addr;
+static unsigned long splashval;
+static unsigned long tuhold;
+static unsigned int nosplash;
+static unsigned int arcfb_enable;
+static unsigned int irq;
+
+static DECLARE_WAIT_QUEUE_HEAD(arcfb_waitq);
+
+static void ks108_writeb_ctl(struct arcfb_par *par,
+				unsigned int chipindex, unsigned char value)
+{
+	unsigned char chipselval = par->cslut[chipindex];
+
+	outb(chipselval|KS_CEHI|KS_SEL_CMD, par->cio_addr);
+	outb(value, par->dio_addr);
+	udelay(tuhold);
+	outb(chipselval|KS_CELO|KS_SEL_CMD, par->cio_addr);
+}
+
+static void ks108_writeb_mainctl(struct arcfb_par *par, unsigned char value)
+{
+
+	outb(value, par->cio_addr);
+	udelay(tuhold);
+}
+
+static unsigned char ks108_readb_ctl2(struct arcfb_par *par)
+{
+	return inb(par->c2io_addr);
+}
+
+static void ks108_writeb_data(struct arcfb_par *par,
+				unsigned int chipindex, unsigned char value)
+{
+	unsigned char chipselval = par->cslut[chipindex];
+
+	outb(chipselval|KS_CEHI|KS_SEL_DATA, par->cio_addr);
+	outb(value, par->dio_addr);
+	udelay(tuhold);
+	outb(chipselval|KS_CELO|KS_SEL_DATA, par->cio_addr);
+}
+
+static void ks108_set_start_line(struct arcfb_par *par,
+				unsigned int chipindex, unsigned char y)
+{
+	ks108_writeb_ctl(par, chipindex, KS_SET_DPY_START_LINE|y);
+}
+
+static void ks108_set_yaddr(struct arcfb_par *par,
+				unsigned int chipindex, unsigned char y)
+{
+	ks108_writeb_ctl(par, chipindex, KS_SET_PAGE_NUM|y);
+}
+
+static void ks108_set_xaddr(struct arcfb_par *par,
+				unsigned int chipindex, unsigned char x)
+{
+	ks108_writeb_ctl(par, chipindex, KS_SET_X|x);
+}
+
+static void ks108_clear_lcd(struct arcfb_par *par, unsigned int chipindex)
+{
+	int i,j;
+
+	for (i = 0; i <= 8; i++) {
+		ks108_set_yaddr(par, chipindex, i);
+		ks108_set_xaddr(par, chipindex, 0);
+		for (j = 0; j < 64; j++) {
+			ks108_writeb_data(par, chipindex,
+				(unsigned char) splashval);
+		}
+	}
+}
+
+/* main arcfb functions */
+
+static int arcfb_open(struct fb_info *info, int user)
+{
+	struct arcfb_par *par = info->par;
+
+	atomic_inc(&par->ref_count);
+	return 0;
+}
+
+static int arcfb_release(struct fb_info *info, int user)
+{
+	struct arcfb_par *par = info->par;
+	int count = atomic_read(&par->ref_count);
+
+	if (!count)
+		return -EINVAL;
+	atomic_dec(&par->ref_count);
+	return 0;
+}
+
+static int arcfb_pan_display(struct fb_var_screeninfo *var,
+				struct fb_info *info)
+{
+	int i;
+	struct arcfb_par *par = info->par;
+
+	if ((var->vmode & FB_VMODE_YWRAP) && (var->yoffset < 64)
+		&& (info->var.yres <= 64)) {
+		for (i = 0; i < num_cols; i++) {
+			ks108_set_start_line(par, i, var->yoffset);
+		}
+		info->var.yoffset = var->yoffset;
+		return 0;
+	}
+
+	return -EINVAL;
+}
+
+static irqreturn_t arcfb_interrupt(int vec, void *dev_instance,
+		struct pt_regs *regs)
+{
+	struct fb_info *info = dev_instance;
+	unsigned char ctl2status;
+	struct arcfb_par *par = info->par;
+
+	ctl2status = ks108_readb_ctl2(par);
+
+	if (!(ctl2status & KS_INTACK)) /* not arc generated interrupt */
+		return IRQ_NONE;
+
+	ks108_writeb_mainctl(par, KS_CLRINT);
+
+	spin_lock(&par->lock);
+        if (waitqueue_active(&arcfb_waitq)) {
+                wake_up(&arcfb_waitq);
+        }
+	spin_unlock(&par->lock);
+
+	return IRQ_HANDLED;
+}
+
+/*
+ * here we handle a specific page on the lcd. the complexity comes from
+ * the fact that the fb is laidout in 8xX vertical columns. we extract
+ * each write of 8 vertical pixels. then we shift out as we move along
+ * X. That's what rightshift does. bitmask selects the desired input bit.
+ */
+static void arcfb_lcd_update_page(struct arcfb_par *par, unsigned int upper,
+		unsigned int left, unsigned int right, unsigned int distance)
+{
+	unsigned char *src;
+	unsigned int xindex, yindex, chipindex, linesize;
+	int i, count;
+	unsigned char val;
+	unsigned char bitmask, rightshift;
+
+	xindex = left >> 6;
+	yindex = upper >> 6;
+	chipindex = (xindex + (yindex*num_cols));
+
+	ks108_set_yaddr(par, chipindex, upper/8);
+
+	linesize = par->info->var.xres/8;
+	src = par->info->screen_base + (left/8) + (upper * linesize);
+	ks108_set_xaddr(par, chipindex, left);
+
+	bitmask=1;
+	rightshift=0;
+	while (left <= right) {
+		val = 0;
+		for (i = 0; i < 8; i++) {
+			if ( i > rightshift) {
+				val |= (*(src + (i*linesize)) & bitmask)
+						<< (i - rightshift);
+			} else {
+				val |= (*(src + (i*linesize)) & bitmask)
+						 >> (rightshift - i);
+			}
+		}
+		ks108_writeb_data(par, chipindex, val);
+		left++;
+		count++;
+		if (bitmask == 0x80) {
+			bitmask = 1;
+			src++;
+			rightshift=0;
+		} else {
+			bitmask <<= 1;
+			rightshift++;
+		}
+	}
+}
+
+/*
+ * here we handle the entire vertical page of the update. we write across
+ * lcd chips. update_page uses the upper/left values to decide which
+ * chip to select for the right. upper is needed for setting the page
+ * desired for the write.
+ */
+static void arcfb_lcd_update_vert(struct arcfb_par *par, unsigned int top,
+		unsigned int bottom, unsigned int left, unsigned int right)
+{
+	unsigned int distance, upper, lower;
+
+	distance = (bottom - top) + 1;
+	upper = top;
+	lower = top + 7;
+
+	while (distance > 0) {
+		distance -= 8;
+		arcfb_lcd_update_page(par, upper, left, right, 8);
+		upper = lower + 1;
+		lower = upper + 7;
+	}
+}
+
+/*
+ * here we handle horizontal blocks for the update. update_vert will
+ * handle spaning multiple pages. we break out each horizontal
+ * block in to individual blocks no taller than 64 pixels.
+ */
+static void arcfb_lcd_update_horiz(struct arcfb_par *par, unsigned int left,
+			unsigned int right, unsigned int top, unsigned int h)
+{
+	unsigned int distance, upper, lower;
+
+	distance = h;
+	upper = floor8(top);
+	lower = min(upper + distance - 1, ceil64(upper));
+
+	while (distance > 0) {
+		distance -= ((lower - upper) + 1 );
+		arcfb_lcd_update_vert(par, upper, lower, left, right);
+		upper = lower + 1;
+		lower = min(upper + distance - 1, ceil64(upper));
+	}
+}
+
+/*
+ * here we start the process of spliting out the fb update into
+ * individual blocks of pixels. we end up spliting into 64x64 blocks
+ * and finally down to 64x8 pages.
+ */
+static void arcfb_lcd_update(struct arcfb_par *par, unsigned int dx,
+			unsigned int dy, unsigned int w, unsigned int h)
+{
+	unsigned int left, right, distance, y;
+
+	/* align the request first */
+	y = floor8(dy);
+	h += dy - y;
+	h = iceil8(h);
+
+	distance = w;
+	left = dx;
+	right = min(left + w - 1, ceil64(left));
+
+	while (distance > 0) {
+		arcfb_lcd_update_horiz(par, left, right, y, h);
+		distance -= ((right - left) + 1);
+		left = right + 1;
+		right = min(left + distance - 1, ceil64(left));
+	}
+}
+
+void arcfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
+{
+	struct arcfb_par *par = info->par;
+
+	cfb_fillrect(info, rect);
+
+	/* update the physical lcd */
+	arcfb_lcd_update(par, rect->dx, rect->dy, rect->width, rect->height);
+}
+
+void arcfb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
+{
+	struct arcfb_par *par = info->par;
+
+	cfb_copyarea(info, area);
+
+	/* update the physical lcd */
+	arcfb_lcd_update(par, area->dx, area->dy, area->width, area->height);
+}
+
+void arcfb_imageblit(struct fb_info *info, const struct fb_image *image)
+{
+	struct arcfb_par *par = info->par;
+
+	cfb_imageblit(info, image);
+
+	/* update the physical lcd */
+	arcfb_lcd_update(par, image->dx, image->dy, image->width,
+				image->height);
+}
+
+static int arcfb_ioctl(struct inode *inode, struct file *file,
+			  unsigned int cmd, unsigned long arg,
+			  struct fb_info *info)
+{
+	void __user *argp = (void __user *)arg;
+	struct arcfb_par *par = info->par;
+	unsigned long flags;
+
+	switch (cmd) {
+		case FBIO_WAITEVENT:
+		{
+			DEFINE_WAIT(wait);
+			/* illegal to wait on arc if no irq will occur */
+			if (!par->irq)
+				return -EINVAL;
+
+			/* wait until the Arc has generated an interrupt
+			 * which will wake us up */
+			spin_lock_irqsave(&par->lock, flags);
+			prepare_to_wait(&arcfb_waitq, &wait,
+					TASK_INTERRUPTIBLE);
+			spin_unlock_irqrestore(&par->lock, flags);
+			schedule();
+			finish_wait(&arcfb_waitq, &wait);
+		}
+		case FBIO_GETCONTROL2:
+		{
+			unsigned char ctl2;
+
+			ctl2 = ks108_readb_ctl2(info->par);
+			if (copy_to_user(argp, &ctl2, sizeof(ctl2)))
+				return -EFAULT;
+			return 0;
+		}
+		default:
+			return -EINVAL;
+	}
+}
+
+/*
+ * this is the access path from userspace. they can seek and write to
+ * the fb. it's inefficient for them to do anything less than 64*8
+ * writes since we update the lcd in each write() anyway.
+ */
+static ssize_t arcfb_write(struct file *file, const char *buf, size_t count,
+				loff_t *ppos)
+{
+	/* modded from epson 1355 */
+
+	struct inode *inode;
+	int fbidx;
+	struct fb_info *info;
+	unsigned long p;
+	int err=-EINVAL;
+	unsigned int fbmemlength,x,y,w,h, bitppos, startpos, endpos, bitcount;
+	struct arcfb_par *par;
+	unsigned int xres;
+
+	p = *ppos;
+	inode = file->f_dentry->d_inode;
+	fbidx = iminor(inode);
+	info = registered_fb[fbidx];
+	par = info->par;
+
+	if (!info || !info->screen_base)
+		return -ENODEV;
+
+	xres = info->var.xres;
+	fbmemlength = (xres * info->var.yres)/8;
+
+	if (p > fbmemlength)
+		return -ENOSPC;
+
+	err = 0;
+	if ((count + p) > fbmemlength) {
+		count = fbmemlength - p;
+		err = -ENOSPC;
+	}
+
+	if (count) {
+		char *base_addr;
+
+		base_addr = info->screen_base;
+		count -= copy_from_user(base_addr + p, buf, count);
+		*ppos += count;
+		err = -EFAULT;
+	}
+
+
+	bitppos = p*8;
+	startpos = floorXres(bitppos, xres);
+	endpos = ceilXres((bitppos + (count*8)), xres);
+	bitcount = endpos - startpos;
+
+	x = startpos % xres;
+	y = startpos / xres;
+	w = xres;
+	h = bitcount / xres;
+	arcfb_lcd_update(par, x, y, w, h);
+
+	if (count)
+		return count;
+	return err;
+}
+
+static void arcfb_platform_release(struct device *device)
+{
+}
+
+static struct fb_ops arcfb_ops = {
+	.owner		= THIS_MODULE,
+	.fb_open	= arcfb_open,
+	.fb_write	= arcfb_write,
+	.fb_release	= arcfb_release,
+	.fb_pan_display	= arcfb_pan_display,
+	.fb_fillrect	= arcfb_fillrect,
+	.fb_copyarea	= arcfb_copyarea,
+	.fb_imageblit	= arcfb_imageblit,
+	.fb_cursor	= soft_cursor,
+	.fb_ioctl 	= arcfb_ioctl,
+};
+
+static int __init arcfb_probe(struct device *device)
+{
+	struct platform_device *dev = to_platform_device(device);
+	struct fb_info *info;
+	int retval = -ENOMEM;
+	int videomemorysize;
+	unsigned char *videomemory;
+	struct arcfb_par *par;
+	int i;
+
+	videomemorysize = (((64*64)*num_cols)*num_rows)/8;
+
+	/* We need a flat backing store for the Arc's
+	   less-flat actual paged framebuffer */
+	if (!(videomemory = vmalloc(videomemorysize)))
+		return retval;
+
+	memset(videomemory, 0, videomemorysize);
+
+	info = framebuffer_alloc(sizeof(struct arcfb_par), &dev->dev);
+	if (!info)
+		goto err;
+
+	info->screen_base = (char __iomem *)videomemory;
+	info->fbops = &arcfb_ops;
+
+	info->var = arcfb_var;
+	info->fix = arcfb_fix;
+	par = info->par;
+	par->info = info;
+
+	if (!dio_addr || !cio_addr || !c2io_addr) {
+		printk(KERN_WARNING "no IO addresses supplied\n");
+		goto err1;
+	}
+	par->dio_addr = dio_addr;
+	par->cio_addr = cio_addr;
+	par->c2io_addr = c2io_addr;
+	par->cslut[0] = 0x00;
+	par->cslut[1] = 0x06;
+	info->flags = FBINFO_FLAG_DEFAULT;
+	spin_lock_init(&par->lock);
+	retval = register_framebuffer(info);
+	if (retval < 0)
+		goto err1;
+	dev_set_drvdata(&dev->dev, info);
+	if (irq) {
+		par->irq = irq;
+		if (request_irq(par->irq, &arcfb_interrupt, SA_SHIRQ,
+				"arcfb", info)) {
+			printk(KERN_INFO
+				"arcfb: Failed req IRQ %d\n", par->irq);
+			goto err1;
+		}
+	}
+	printk(KERN_INFO
+	       "fb%d: Arc frame buffer device, using %dK of video memory\n",
+	       info->node, videomemorysize >> 10);
+
+	/* this inits the lcd but doesn't clear dirty pixels */
+	for (i = 0; i < num_cols * num_rows; i++) {
+		ks108_writeb_ctl(par, i, KS_DPY_OFF);
+		ks108_set_start_line(par, i, 0);
+		ks108_set_yaddr(par, i, 0);
+		ks108_set_xaddr(par, i, 0);
+		ks108_writeb_ctl(par, i, KS_DPY_ON);
+	}
+
+	/* if we were told to splash the screen, we just clear it */
+	if (!nosplash) {
+		for (i = 0; i < num_cols * num_rows; i++) {
+			printk(KERN_INFO "fb%d: splashing lcd %d\n",
+				info->node, i);
+			ks108_set_start_line(par, i, 0);
+			ks108_clear_lcd(par, i);
+		}
+	}
+
+	return 0;
+err1:
+	framebuffer_release(info);
+err:
+	vfree(videomemory);
+	return retval;
+}
+
+static int arcfb_remove(struct device *device)
+{
+	struct fb_info *info = dev_get_drvdata(device);
+
+	if (info) {
+		unregister_framebuffer(info);
+		vfree(info->screen_base);
+		framebuffer_release(info);
+	}
+	return 0;
+}
+
+static struct device_driver arcfb_driver = {
+	.name	= "arcfb",
+	.bus	= &platform_bus_type,
+	.probe	= arcfb_probe,
+	.remove = arcfb_remove,
+};
+
+static struct platform_device arcfb_device = {
+	.name	= "arcfb",
+	.id	= 0,
+	.dev	= {
+		.release = arcfb_platform_release,
+	}
+};
+
+static int __init arcfb_init(void)
+{
+	int ret;
+
+	if (!arcfb_enable)
+		return -ENXIO;
+
+	ret = driver_register(&arcfb_driver);
+	if (!ret) {
+		ret = platform_device_register(&arcfb_device);
+		if (ret)
+			driver_unregister(&arcfb_driver);
+	}
+	return ret;
+
+}
+
+static void __exit arcfb_exit(void)
+{
+	platform_device_unregister(&arcfb_device);
+	driver_unregister(&arcfb_driver);
+}
+
+module_param(num_cols, ulong, 0);
+MODULE_PARM_DESC(num_cols, "Num horiz panels, eg: 2 = 128 bit wide");
+module_param(num_rows, ulong, 0);
+MODULE_PARM_DESC(num_rows, "Num vert panels, eg: 1 = 64 bit high");
+module_param(nosplash, uint, 0);
+MODULE_PARM_DESC(nosplash, "Disable doing the splash screen");
+module_param(arcfb_enable, uint, 0);
+MODULE_PARM_DESC(arcfb_enable, "Enable communication with Arc board");
+module_param(dio_addr, ulong, 0);
+MODULE_PARM_DESC(dio_addr, "IO address for data, eg: 0x480");
+module_param(cio_addr, ulong, 0);
+MODULE_PARM_DESC(cio_addr, "IO address for control, eg: 0x400");
+module_param(c2io_addr, ulong, 0);
+MODULE_PARM_DESC(c2io_addr, "IO address for secondary control, eg: 0x408");
+module_param(splashval, ulong, 0);
+MODULE_PARM_DESC(splashval, "Splash pattern: 0xFF is black, 0x00 is green");
+module_param(tuhold, ulong, 0);
+MODULE_PARM_DESC(tuhold, "Time to hold between strobing data to Arc board");
+module_param(irq, uint, 0);
+MODULE_PARM_DESC(irq, "IRQ for the Arc board");
+
+module_init(arcfb_init);
+module_exit(arcfb_exit);
+
+MODULE_DESCRIPTION("fbdev driver for Arc monochrome LCD board");
+MODULE_AUTHOR("Jaya Kumar");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c
--- a/drivers/video/aty/aty128fb.c
+++ b/drivers/video/aty/aty128fb.c
@@ -350,10 +350,8 @@ static int default_vmode __initdata = VM
 static int default_cmode __initdata = CMODE_8;
 #endif
 
-#ifdef CONFIG_PMAC_PBOOK
 static int default_crt_on __initdata = 0;
 static int default_lcd_on __initdata = 1;
-#endif
 
 #ifdef CONFIG_MTRR
 static int mtrr = 1;
@@ -1249,7 +1247,6 @@ static int aty128_crtc_to_var(const stru
 	return 0;
 }
 
-#ifdef CONFIG_PMAC_PBOOK
 static void aty128_set_crt_enable(struct aty128fb_par *par, int on)
 {
 	if (on) {
@@ -1284,7 +1281,6 @@ static void aty128_set_lcd_enable(struct
 		aty_st_le32(LVDS_GEN_CNTL, reg);
 	}
 }
-#endif /* CONFIG_PMAC_PBOOK */
 
 static void aty128_set_pll(struct aty128_pll *pll, const struct aty128fb_par *par)
 {
@@ -1491,12 +1487,10 @@ static int aty128fb_set_par(struct fb_in
 	info->fix.visual = par->crtc.bpp == 8 ? FB_VISUAL_PSEUDOCOLOR
 		: FB_VISUAL_DIRECTCOLOR;
 
-#ifdef CONFIG_PMAC_PBOOK
 	if (par->chip_gen == rage_M3) {
 		aty128_set_crt_enable(par, par->crt_on);
 		aty128_set_lcd_enable(par, par->lcd_on);
 	}
-#endif
 	if (par->accel_flags & FB_ACCELF_TEXT)
 		aty128_init_engine(par);
 
@@ -1652,7 +1646,6 @@ static int __init aty128fb_setup(char *o
 		return 0;
 
 	while ((this_opt = strsep(&options, ",")) != NULL) {
-#ifdef CONFIG_PMAC_PBOOK
 		if (!strncmp(this_opt, "lcd:", 4)) {
 			default_lcd_on = simple_strtoul(this_opt+4, NULL, 0);
 			continue;
@@ -1660,7 +1653,6 @@ static int __init aty128fb_setup(char *o
 			default_crt_on = simple_strtoul(this_opt+4, NULL, 0);
 			continue;
 		}
-#endif
 #ifdef CONFIG_MTRR
 		if(!strncmp(this_opt, "nomtrr", 6)) {
 			mtrr = 0;
@@ -1752,10 +1744,8 @@ static int __init aty128_init(struct pci
 	info->fbops = &aty128fb_ops;
 	info->flags = FBINFO_FLAG_DEFAULT;
 
-#ifdef CONFIG_PMAC_PBOOK
 	par->lcd_on = default_lcd_on;
 	par->crt_on = default_crt_on;
-#endif
 
 	var = default_var;
 #ifdef CONFIG_PPC_PMAC
@@ -2035,12 +2025,10 @@ static int aty128fb_blank(int blank, str
 
 	aty_st_8(CRTC_EXT_CNTL+1, state);
 
-#ifdef CONFIG_PMAC_PBOOK
 	if (par->chip_gen == rage_M3) {
 		aty128_set_crt_enable(par, par->crt_on && !blank);
 		aty128_set_lcd_enable(par, par->lcd_on && !blank);
 	}
-#endif	
 #ifdef CONFIG_PMAC_BACKLIGHT
 	if ((_machine == _MACH_Pmac) && !blank)
 		set_backlight_enable(1);
@@ -2124,7 +2112,6 @@ static int aty128fb_setcolreg(u_int regn
 static int aty128fb_ioctl(struct inode *inode, struct file *file, u_int cmd,
 			  u_long arg, struct fb_info *info)
 {
-#ifdef CONFIG_PMAC_PBOOK
 	struct aty128fb_par *par = info->par;
 	u32 value;
 	int rc;
@@ -2149,7 +2136,6 @@ static int aty128fb_ioctl(struct inode *
 		value = (par->crt_on << 1) | par->lcd_on;
 		return put_user(value, (__u32 __user *)arg);
 	}
-#endif
 	return -EINVAL;
 }
 
diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c
--- a/drivers/video/aty/radeon_base.c
+++ b/drivers/video/aty/radeon_base.c
@@ -2521,6 +2521,11 @@ static void __devexit radeonfb_pci_unreg
  
 	radeonfb_pm_exit(rinfo);
 
+	if (rinfo->mon1_EDID)
+		sysfs_remove_bin_file(&rinfo->pdev->dev.kobj, &edid1_attr);
+	if (rinfo->mon2_EDID)
+		sysfs_remove_bin_file(&rinfo->pdev->dev.kobj, &edid2_attr);
+
 #if 0
 	/* restore original state
 	 * 
diff --git a/drivers/video/au1100fb.c b/drivers/video/au1100fb.c
--- a/drivers/video/au1100fb.c
+++ b/drivers/video/au1100fb.c
@@ -111,15 +111,15 @@ static int au1100fb_ioctl(struct inode *
 void au1100_nocursor(struct display *p, int mode, int xx, int yy){};
 
 static struct fb_ops au1100fb_ops = {
-	owner:		THIS_MODULE,
-	fb_get_fix:	fbgen_get_fix,
-	fb_get_var:	fbgen_get_var,
-	fb_set_var:	fbgen_set_var,
-	fb_get_cmap:	fbgen_get_cmap,
-	fb_set_cmap:	fbgen_set_cmap,
-	fb_pan_display: fbgen_pan_display,
-        fb_ioctl:       au1100fb_ioctl,
-	fb_mmap:        au1100fb_mmap,
+	.owner		= THIS_MODULE,
+	.fb_get_fix	= fbgen_get_fix,
+	.fb_get_var	= fbgen_get_var,
+	.fb_set_var	= fbgen_set_var,
+	.fb_get_cmap	= fbgen_get_cmap,
+	.fb_set_cmap	= fbgen_set_cmap,
+	.fb_pan_display	= fbgen_pan_display,
+        .fb_ioctl	= au1100fb_ioctl,
+	.fb_mmap	= au1100fb_mmap,
 };
 
 static void au1100_detect(void)
diff --git a/drivers/video/chipsfb.c b/drivers/video/chipsfb.c
--- a/drivers/video/chipsfb.c
+++ b/drivers/video/chipsfb.c
@@ -28,22 +28,17 @@
 #include <linux/fb.h>
 #include <linux/init.h>
 #include <linux/pci.h>
+#include <linux/console.h>
 #include <asm/io.h>
 
 #ifdef CONFIG_PMAC_BACKLIGHT
 #include <asm/backlight.h>
 #endif
-#ifdef CONFIG_PMAC_PBOOK
-#include <linux/adb.h>
-#include <linux/pmu.h>
-#endif
 
 /*
  * Since we access the display with inb/outb to fixed port numbers,
  * we can only handle one 6555x chip.  -- paulus
  */
-static struct fb_info chipsfb_info;
-
 #define write_ind(num, val, ap, dp)	do { \
 	outb((num), (ap)); outb((val), (dp)); \
 } while (0)
@@ -74,14 +69,6 @@ static struct fb_info chipsfb_info;
 	inb(0x3da); read_ind(num, var, 0x3c0, 0x3c1); \
 } while (0)
 
-#ifdef CONFIG_PMAC_PBOOK
-static unsigned char *save_framebuffer;
-int chips_sleep_notify(struct pmu_sleep_notifier *self, int when);
-static struct pmu_sleep_notifier chips_sleep_notifier = {
-	chips_sleep_notify, SLEEP_LEVEL_VIDEO,
-};
-#endif
-
 /*
  * Exported functions
  */
@@ -356,6 +343,8 @@ static struct fb_var_screeninfo chipsfb_
 
 static void __init init_chips(struct fb_info *p, unsigned long addr)
 {
+	memset(p->screen_base, 0, 0x100000);
+
 	p->fix = chipsfb_fix;
 	p->fix.smem_start = addr;
 
@@ -366,34 +355,41 @@ static void __init init_chips(struct fb_
 
 	fb_alloc_cmap(&p->cmap, 256, 0);
 
-	if (register_framebuffer(p) < 0) {
-		printk(KERN_ERR "C&T 65550 framebuffer failed to register\n");
-		return;
-	}
-
-	printk(KERN_INFO "fb%d: Chips 65550 frame buffer (%dK RAM detected)\n",
-		p->node, p->fix.smem_len / 1024);
-
 	chips_hw_init();
 }
 
 static int __devinit
 chipsfb_pci_init(struct pci_dev *dp, const struct pci_device_id *ent)
 {
-	struct fb_info *p = &chipsfb_info;
+	struct fb_info *p;
 	unsigned long addr, size;
 	unsigned short cmd;
+	int rc = -ENODEV;
+
+	if (pci_enable_device(dp) < 0) {
+		dev_err(&dp->dev, "Cannot enable PCI device\n");
+		goto err_out;
+	}
 
 	if ((dp->resource[0].flags & IORESOURCE_MEM) == 0)
-		return -ENODEV;
+		goto err_disable;
 	addr = pci_resource_start(dp, 0);
 	size = pci_resource_len(dp, 0);
 	if (addr == 0)
-		return -ENODEV;
-	if (p->screen_base != 0)
-		return -EBUSY;
-	if (!request_mem_region(addr, size, "chipsfb"))
-		return -EBUSY;
+		goto err_disable;
+
+	p = framebuffer_alloc(0, &dp->dev);
+	if (p == NULL) {
+		dev_err(&dp->dev, "Cannot allocate framebuffer structure\n");
+		rc = -ENOMEM;
+		goto err_disable;
+	}
+
+	if (pci_request_region(dp, 0, "chipsfb") != 0) {
+		dev_err(&dp->dev, "Cannot request framebuffer\n");
+		rc = -EBUSY;
+		goto err_release_fb;
+	}
 
 #ifdef __BIG_ENDIAN
 	addr += 0x800000;	// Use big-endian aperture
@@ -411,40 +407,89 @@ chipsfb_pci_init(struct pci_dev *dp, con
 	set_backlight_enable(1);
 #endif /* CONFIG_PMAC_BACKLIGHT */
 
+#ifdef CONFIG_PPC
 	p->screen_base = __ioremap(addr, 0x200000, _PAGE_NO_CACHE);
+#else
+	p->screen_base = ioremap(addr, 0x200000);
+#endif
 	if (p->screen_base == NULL) {
-		release_mem_region(addr, size);
-		return -ENOMEM;
+		dev_err(&dp->dev, "Cannot map framebuffer\n");
+		rc = -ENOMEM;
+		goto err_release_pci;
 	}
+
+	pci_set_drvdata(dp, p);
 	p->device = &dp->dev;
+
 	init_chips(p, addr);
 
-#ifdef CONFIG_PMAC_PBOOK
-	pmu_register_sleep_notifier(&chips_sleep_notifier);
-#endif /* CONFIG_PMAC_PBOOK */
+	if (register_framebuffer(p) < 0) {
+		dev_err(&dp->dev,"C&T 65550 framebuffer failed to register\n");
+		goto err_unmap;
+	}
 
-	/* Clear the entire framebuffer */
-	memset(p->screen_base, 0, 0x100000);
+	dev_info(&dp->dev,"fb%d: Chips 65550 frame buffer"
+		 " (%dK RAM detected)\n",
+		 p->node, p->fix.smem_len / 1024);
 
-	pci_set_drvdata(dp, p);
 	return 0;
+
+ err_unmap:
+	iounmap(p->screen_base);
+ err_release_pci:
+	pci_release_region(dp, 0);
+ err_release_fb:
+	framebuffer_release(p);
+ err_disable:
+ err_out:
+	return rc;
 }
 
 static void __devexit chipsfb_remove(struct pci_dev *dp)
 {
 	struct fb_info *p = pci_get_drvdata(dp);
 
-	if (p != &chipsfb_info || p->screen_base == NULL)
+	if (p->screen_base == NULL)
 		return;
 	unregister_framebuffer(p);
 	iounmap(p->screen_base);
 	p->screen_base = NULL;
-	release_mem_region(pci_resource_start(dp, 0), pci_resource_len(dp, 0));
+	pci_release_region(dp, 0);
+}
+
+#ifdef CONFIG_PM
+static int chipsfb_pci_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+        struct fb_info *p = pci_get_drvdata(pdev);
+
+	if (state == pdev->dev.power.power_state)
+		return 0;
+	if (state != PM_SUSPEND_MEM)
+		goto done;
+
+	acquire_console_sem();
+	chipsfb_blank(1, p);
+	fb_set_suspend(p, 1);
+	release_console_sem();
+ done:
+	pdev->dev.power.power_state = state;
+	return 0;
+}
+
+static int chipsfb_pci_resume(struct pci_dev *pdev)
+{
+        struct fb_info *p = pci_get_drvdata(pdev);
 
-#ifdef CONFIG_PMAC_PBOOK
-	pmu_unregister_sleep_notifier(&chips_sleep_notifier);
-#endif /* CONFIG_PMAC_PBOOK */
+	acquire_console_sem();
+	fb_set_suspend(p, 0);
+	chipsfb_blank(0, p);
+	release_console_sem();
+
+	pdev->dev.power.power_state = PMSG_ON;
+	return 0;
 }
+#endif /* CONFIG_PM */
+
 
 static struct pci_device_id chipsfb_pci_tbl[] = {
 	{ PCI_VENDOR_ID_CT, PCI_DEVICE_ID_CT_65550, PCI_ANY_ID, PCI_ANY_ID },
@@ -458,6 +503,10 @@ static struct pci_driver chipsfb_driver 
 	.id_table =	chipsfb_pci_tbl,
 	.probe =	chipsfb_pci_init,
 	.remove =	__devexit_p(chipsfb_remove),
+#ifdef CONFIG_PM
+	.suspend =	chipsfb_pci_suspend,
+	.resume =	chipsfb_pci_resume,
+#endif
 };
 
 int __init chips_init(void)
@@ -475,48 +524,4 @@ static void __exit chipsfb_exit(void)
 	pci_unregister_driver(&chipsfb_driver);
 }
 
-#ifdef CONFIG_PMAC_PBOOK
-/*
- * Save the contents of the frame buffer when we go to sleep,
- * and restore it when we wake up again.
- */
-int
-chips_sleep_notify(struct pmu_sleep_notifier *self, int when)
-{
-	struct fb_info *p = &chipsfb_info;
-	int nb = p->var.yres * p->fix.line_length;
-
-	if (p->screen_base == NULL)
-		return PBOOK_SLEEP_OK;
-
-	switch (when) {
-	case PBOOK_SLEEP_REQUEST:
-		save_framebuffer = vmalloc(nb);
-		if (save_framebuffer == NULL)
-			return PBOOK_SLEEP_REFUSE;
-		break;
-	case PBOOK_SLEEP_REJECT:
-		if (save_framebuffer) {
-			vfree(save_framebuffer);
-			save_framebuffer = NULL;
-		}
-		break;
-	case PBOOK_SLEEP_NOW:
-		chipsfb_blank(1, p);
-		if (save_framebuffer)
-			memcpy(save_framebuffer, p->screen_base, nb);
-		break;
-	case PBOOK_WAKE:
-		if (save_framebuffer) {
-			memcpy(p->screen_base, save_framebuffer, nb);
-			vfree(save_framebuffer);
-			save_framebuffer = NULL;
-		}
-		chipsfb_blank(0, p);
-		break;
-	}
-	return PBOOK_SLEEP_OK;
-}
-#endif /* CONFIG_PMAC_PBOOK */
-
 MODULE_LICENSE("GPL");
diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig
--- a/drivers/video/console/Kconfig
+++ b/drivers/video/console/Kconfig
@@ -6,7 +6,7 @@ menu "Console display driver support"
 
 config VGA_CONSOLE
 	bool "VGA text console" if EMBEDDED || !X86
-	depends on !ARCH_ACORN && !ARCH_EBSA110 && !4xx && !8xx && !SPARC32 && !SPARC64 && !M68K && !PARISC
+	depends on !ARCH_ACORN && !ARCH_EBSA110 && !4xx && !8xx && !SPARC32 && !SPARC64 && !M68K && !PARISC && !ARCH_VERSATILE
 	default y
 	help
 	  Saying Y here will allow you to use Linux in text mode through a
@@ -153,6 +153,14 @@ config FONT_6x11
 	  Small console font with Macintosh-style high-half glyphs.  Some Mac
 	  framebuffer drivers don't support this one at all.
 
+config FONT_7x14
+	bool "console 7x14 font (not supported by all drivers)" if FONTS
+	depends on FRAMEBUFFER_CONSOLE
+	help
+	  Console font with characters just a bit smaller than the default.
+	  If the standard 8x16 font is a little too big for you, say Y.
+	  Otherwise, say N.
+
 config FONT_PEARL_8x8
 	bool "Pearl (old m68k) console 8x8 font" if FONTS
 	depends on FRAMEBUFFER_CONSOLE
@@ -187,5 +195,13 @@ config FONT_SUN12x22
 	  big letters (like the letters used in the SPARC PROM). If the
 	  standard font is unreadable for you, say Y, otherwise say N.
 
+config FONT_10x18
+	bool "console 10x18 font (not supported by all drivers)" if FONTS
+	depends on FRAMEBUFFER_CONSOLE
+	help
+	  This is a high resolution console font for machines with very
+	  big letters. It fits between the sun 12x22 and the normal 8x16 font.
+	  If other fonts are too big or too small for you, say Y, otherwise say N.
+
 endmenu
 
diff --git a/drivers/video/console/Makefile b/drivers/video/console/Makefile
--- a/drivers/video/console/Makefile
+++ b/drivers/video/console/Makefile
@@ -10,6 +10,8 @@ font-objs-$(CONFIG_FONT_SUN12x22)  += fo
 font-objs-$(CONFIG_FONT_8x8)       += font_8x8.o
 font-objs-$(CONFIG_FONT_8x16)      += font_8x16.o
 font-objs-$(CONFIG_FONT_6x11)      += font_6x11.o
+font-objs-$(CONFIG_FONT_7x14)      += font_7x14.o
+font-objs-$(CONFIG_FONT_10x18)     += font_10x18.o
 font-objs-$(CONFIG_FONT_PEARL_8x8) += font_pearl_8x8.o
 font-objs-$(CONFIG_FONT_ACORN_8x8) += font_acorn_8x8.o
 font-objs-$(CONFIG_FONT_MINI_4x6)  += font_mini_4x6.o
diff --git a/drivers/video/console/bitblit.c b/drivers/video/console/bitblit.c
--- a/drivers/video/console/bitblit.c
+++ b/drivers/video/console/bitblit.c
@@ -107,13 +107,6 @@ static void bit_putcs(struct vc_data *vc
 		      const unsigned short *s, int count, int yy, int xx,
 		      int fg, int bg)
 {
-	void (*move_unaligned)(struct fb_info *info, struct fb_pixmap *buf,
-			       u8 *dst, u32 d_pitch, u8 *src, u32 idx,
-			       u32 height, u32 shift_high, u32 shift_low,
-			       u32 mod);
-	void (*move_aligned)(struct fb_info *info, struct fb_pixmap *buf,
-			     u8 *dst, u32 d_pitch, u8 *src, u32 s_pitch,
-			     u32 height);
 	unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
 	unsigned int width = (vc->vc_font.width + 7) >> 3;
 	unsigned int cellsize = vc->vc_font.height * width;
@@ -141,13 +134,6 @@ static void bit_putcs(struct vc_data *vc
 	image.height = vc->vc_font.height;
 	image.depth = 1;
 
-	if (info->pixmap.outbuf && info->pixmap.inbuf) {
-		move_aligned = fb_iomove_buf_aligned;
-		move_unaligned = fb_iomove_buf_unaligned;
-	} else {
-		move_aligned = fb_sysmove_buf_aligned;
-		move_unaligned = fb_sysmove_buf_unaligned;
-	}
 	while (count) {
 		if (count > maxcnt)
 			cnt = k = maxcnt;
@@ -171,9 +157,9 @@ static void bit_putcs(struct vc_data *vc
 					src = buf;
 				}
 
-				move_unaligned(info, &info->pixmap, dst, pitch,
-					       src, idx, image.height,
-					       shift_high, shift_low, mod);
+				fb_pad_unaligned_buffer(dst, pitch, src, idx,
+						image.height, shift_high,
+						shift_low, mod);
 				shift_low += mod;
 				dst += (shift_low >= 8) ? width : width - 1;
 				shift_low &= 7;
@@ -189,8 +175,7 @@ static void bit_putcs(struct vc_data *vc
 					src = buf;
 				}
 
-				move_aligned(info, &info->pixmap, dst, pitch,
-					     src, idx, image.height);
+				fb_pad_aligned_buffer(dst, pitch, src, idx, image.height);
 				dst += width;
 			}
 		}
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -142,7 +142,6 @@ static int fbcon_set_origin(struct vc_da
 #define CURSOR_DRAW_DELAY		(1)
 
 /* # VBL ints between cursor state changes */
-#define ARM_CURSOR_BLINK_RATE		(10)
 #define ATARI_CURSOR_BLINK_RATE		(42)
 #define MAC_CURSOR_BLINK_RATE		(32)
 #define DEFAULT_CURSOR_BLINK_RATE	(20)
@@ -276,7 +275,8 @@ static void fb_flashcursor(void *private
 
 	if (!vc || !CON_IS_VISIBLE(vc) ||
 	    fbcon_is_inactive(vc, info) ||
- 	    registered_fb[con2fb_map[vc->vc_num]] != info)
+ 	    registered_fb[con2fb_map[vc->vc_num]] != info ||
+	    vc_cons[ops->currcon].d->vc_deccm != 1)
 		return;
 	acquire_console_sem();
 	p = &fb_display[vc->vc_num];
@@ -288,7 +288,7 @@ static void fb_flashcursor(void *private
 	release_console_sem();
 }
 
-#if (defined(__arm__) && defined(IRQ_VSYNCPULSE)) || defined(CONFIG_ATARI) || defined(CONFIG_MAC)
+#if defined(CONFIG_ATARI) || defined(CONFIG_MAC)
 static int cursor_blink_rate;
 static irqreturn_t fb_vbl_handler(int irq, void *dev_id, struct pt_regs *fp)
 {
@@ -878,11 +878,6 @@ static const char *fbcon_startup(void)
 	}
 #endif				/* CONFIG_MAC */
 
-#if defined(__arm__) && defined(IRQ_VSYNCPULSE)
-	cursor_blink_rate = ARM_CURSOR_BLINK_RATE;
-	irqres = request_irq(IRQ_VSYNCPULSE, fb_vbl_handler, SA_SHIRQ,
-			     "framebuffer vbl", info);
-#endif
 	/* Initialize the work queue. If the driver provides its
 	 * own work queue this means it will use something besides 
 	 * default timer to flash the cursor. */
diff --git a/drivers/video/console/font_10x18.c b/drivers/video/console/font_10x18.c
new file mode 100644
--- /dev/null
+++ b/drivers/video/console/font_10x18.c
@@ -0,0 +1,5146 @@
+/********************************
+ * adapted from font_sun12x22.c *
+ * by Jurriaan Kalkman 06-2005  *
+ ********************************/
+
+#include <linux/font.h>
+
+#define FONTDATAMAX 9216
+
+static unsigned char fontdata_10x18[FONTDATAMAX] = {
+
+	/* 0 0x00 '^@' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 1 0x01 '^A' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x3f, 0x80, /* 0011111110 */
+	0x40, 0x40, /* 0100000001 */
+	0x5b, 0x40, /* 0101101101 */
+	0x40, 0x40, /* 0100000001 */
+	0x44, 0x40, /* 0100010001 */
+	0x44, 0x40, /* 0100010001 */
+	0x51, 0x40, /* 0101000101 */
+	0x4e, 0x40, /* 0100111001 */
+	0x40, 0x40, /* 0100000001 */
+	0x3f, 0x80, /* 0011111110 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 2 0x02 '^B' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x3f, 0x80, /* 0011111110 */
+	0x7f, 0xc0, /* 0111111111 */
+	0x64, 0xc0, /* 0110010011 */
+	0x7f, 0xc0, /* 0111111111 */
+	0x7b, 0xc0, /* 0111101111 */
+	0x7b, 0xc0, /* 0111101111 */
+	0x6e, 0xc0, /* 0110111011 */
+	0x71, 0xc0, /* 0111000111 */
+	0x7f, 0xc0, /* 0111111111 */
+	0x3f, 0x80, /* 0011111110 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 3 0x03 '^C' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x11, 0x00, /* 0001000100 */
+	0x3b, 0x80, /* 0011101110 */
+	0x7f, 0xc0, /* 0111111111 */
+	0x3f, 0x80, /* 0011111110 */
+	0x3f, 0x80, /* 0011111110 */
+	0x1f, 0x00, /* 0001111100 */
+	0x1f, 0x00, /* 0001111100 */
+	0x0e, 0x00, /* 0000111000 */
+	0x0e, 0x00, /* 0000111000 */
+	0x04, 0x00, /* 0000010000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 4 0x04 '^D' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x04, 0x00, /* 0000010000 */
+	0x0e, 0x00, /* 0000111000 */
+	0x0e, 0x00, /* 0000111000 */
+	0x1f, 0x00, /* 0001111100 */
+	0x1f, 0x00, /* 0001111100 */
+	0x3f, 0x80, /* 0011111110 */
+	0x1f, 0x00, /* 0001111100 */
+	0x1f, 0x00, /* 0001111100 */
+	0x0e, 0x00, /* 0000111000 */
+	0x0e, 0x00, /* 0000111000 */
+	0x04, 0x00, /* 0000010000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 5 0x05 '^E' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x1e, 0x00, /* 0001111000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x31, 0x80, /* 0011000110 */
+	0x7b, 0xc0, /* 0111101111 */
+	0x35, 0x80, /* 0011010110 */
+	0x04, 0x00, /* 0000010000 */
+	0x0e, 0x00, /* 0000111000 */
+	0x1f, 0x00, /* 0001111100 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 6 0x06 '^F' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x04, 0x00, /* 0000010000 */
+	0x0e, 0x00, /* 0000111000 */
+	0x1f, 0x00, /* 0001111100 */
+	0x1f, 0x00, /* 0001111100 */
+	0x3f, 0x80, /* 0011111110 */
+	0x7f, 0xc0, /* 0111111111 */
+	0x7f, 0xc0, /* 0111111111 */
+	0x35, 0x80, /* 0011010110 */
+	0x04, 0x00, /* 0000010000 */
+	0x0e, 0x00, /* 0000111000 */
+	0x1f, 0x00, /* 0001111100 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 7 0x07 '^G' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x1e, 0x00, /* 0001111000 */
+	0x1e, 0x00, /* 0001111000 */
+	0x3f, 0x00, /* 0011111100 */
+	0x3f, 0x00, /* 0011111100 */
+	0x1e, 0x00, /* 0001111000 */
+	0x1e, 0x00, /* 0001111000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 8 0x08 '^H' */
+	0xff, 0xc0, /* 1111111111 */
+	0xff, 0xc0, /* 1111111111 */
+	0xff, 0xc0, /* 1111111111 */
+	0xff, 0xc0, /* 1111111111 */
+	0xff, 0xc0, /* 1111111111 */
+	0xf3, 0xc0, /* 1111001111 */
+	0xe1, 0xc0, /* 1110000111 */
+	0xe1, 0xc0, /* 1110000111 */
+	0xc0, 0xc0, /* 1100000011 */
+	0xc0, 0xc0, /* 1100000011 */
+	0xe1, 0xc0, /* 1110000111 */
+	0xe1, 0xc0, /* 1110000111 */
+	0xf3, 0xc0, /* 1111001111 */
+	0xff, 0xc0, /* 1111111111 */
+	0xff, 0xc0, /* 1111111111 */
+	0xff, 0xc0, /* 1111111111 */
+	0xff, 0xc0, /* 1111111111 */
+	0xff, 0xc0, /* 1111111111 */
+
+	/* 9 0x09 '^I' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x12, 0x00, /* 0001001000 */
+	0x12, 0x00, /* 0001001000 */
+	0x21, 0x00, /* 0010000100 */
+	0x21, 0x00, /* 0010000100 */
+	0x12, 0x00, /* 0001001000 */
+	0x12, 0x00, /* 0001001000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 10 0x0a '^J' */
+	0xff, 0xc0, /* 1111111111 */
+	0xff, 0xc0, /* 1111111111 */
+	0xff, 0xc0, /* 1111111111 */
+	0xff, 0xc0, /* 1111111111 */
+	0xff, 0xc0, /* 1111111111 */
+	0xf3, 0xc0, /* 1111001111 */
+	0xed, 0xc0, /* 1110110111 */
+	0xed, 0xc0, /* 1110110111 */
+	0xde, 0xc0, /* 1101111011 */
+	0xde, 0xc0, /* 1101111011 */
+	0xed, 0xc0, /* 1110110111 */
+	0xed, 0xc0, /* 1110110111 */
+	0xf3, 0xc0, /* 1111001111 */
+	0xff, 0xc0, /* 1111111111 */
+	0xff, 0xc0, /* 1111111111 */
+	0xff, 0xc0, /* 1111111111 */
+	0xff, 0xc0, /* 1111111111 */
+	0xff, 0xc0, /* 1111111111 */
+
+	/* 11 0x0b '^K' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x0f, 0xc0, /* 0000111111 */
+	0x0f, 0xc0, /* 0000111111 */
+	0x03, 0xc0, /* 0000001111 */
+	0x06, 0xc0, /* 0000011011 */
+	0x0c, 0xc0, /* 0000110011 */
+	0x3c, 0x00, /* 0011110000 */
+	0x66, 0x00, /* 0110011000 */
+	0xc3, 0x00, /* 1100001100 */
+	0xc3, 0x00, /* 1100001100 */
+	0xc3, 0x00, /* 1100001100 */
+	0x66, 0x00, /* 0110011000 */
+	0x3c, 0x00, /* 0011110000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 12 0x0c '^L' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x1e, 0x00, /* 0001111000 */
+	0x33, 0x00, /* 0011001100 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x33, 0x00, /* 0011001100 */
+	0x1e, 0x00, /* 0001111000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x3f, 0x00, /* 0011111100 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 13 0x0d '^M' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x0f, 0x80, /* 0000111110 */
+	0x08, 0x80, /* 0000100010 */
+	0x0f, 0x80, /* 0000111110 */
+	0x08, 0x00, /* 0000100000 */
+	0x08, 0x00, /* 0000100000 */
+	0x08, 0x00, /* 0000100000 */
+	0x08, 0x00, /* 0000100000 */
+	0x08, 0x00, /* 0000100000 */
+	0x08, 0x00, /* 0000100000 */
+	0x38, 0x00, /* 0011100000 */
+	0x78, 0x00, /* 0111100000 */
+	0x30, 0x00, /* 0011000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 14 0x0e '^N' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x1f, 0x80, /* 0001111110 */
+	0x10, 0x80, /* 0001000010 */
+	0x1f, 0x80, /* 0001111110 */
+	0x10, 0x80, /* 0001000010 */
+	0x10, 0x80, /* 0001000010 */
+	0x10, 0x80, /* 0001000010 */
+	0x10, 0x80, /* 0001000010 */
+	0x13, 0x80, /* 0001001110 */
+	0x17, 0x80, /* 0001011110 */
+	0x73, 0x00, /* 0111001100 */
+	0xf0, 0x00, /* 1111000000 */
+	0x60, 0x00, /* 0110000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 15 0x0f '^O' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x04, 0x00, /* 0000010000 */
+	0x24, 0x80, /* 0010010010 */
+	0x15, 0x00, /* 0001010100 */
+	0x55, 0x40, /* 0101010101 */
+	0x3f, 0x80, /* 0011111110 */
+	0x0e, 0x00, /* 0000111000 */
+	0x00, 0x00, /* 0000000000 */
+	0x0e, 0x00, /* 0000111000 */
+	0x3f, 0x80, /* 0011111110 */
+	0x55, 0x40, /* 0101010101 */
+	0x15, 0x00, /* 0001010100 */
+	0x24, 0x80, /* 0010010010 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 16 0x10 '^P' */
+	0x00, 0x80, /* 0000000010 */
+	0x01, 0x80, /* 0000000110 */
+	0x03, 0x80, /* 0000001110 */
+	0x07, 0x80, /* 0000011110 */
+	0x0f, 0x80, /* 0000111110 */
+	0x1f, 0x80, /* 0001111110 */
+	0x3f, 0x80, /* 0011111110 */
+	0x7f, 0x80, /* 0111111110 */
+	0xff, 0x80, /* 1111111110 */
+	0x7f, 0x80, /* 0111111110 */
+	0x3f, 0x80, /* 0011111110 */
+	0x1f, 0x80, /* 0001111110 */
+	0x0f, 0x80, /* 0000111110 */
+	0x07, 0x80, /* 0000011110 */
+	0x03, 0x80, /* 0000001110 */
+	0x01, 0x80, /* 0000000110 */
+	0x00, 0x80, /* 0000000010 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 17 0x11 '^Q' */
+	0x40, 0x00, /* 0100000000 */
+	0x60, 0x00, /* 0110000000 */
+	0x70, 0x00, /* 0111000000 */
+	0x78, 0x00, /* 0111100000 */
+	0x7c, 0x00, /* 0111110000 */
+	0x7e, 0x00, /* 0111111000 */
+	0x7f, 0x00, /* 0111111100 */
+	0x7f, 0x80, /* 0111111110 */
+	0x7f, 0xc0, /* 0111111111 */
+	0x7f, 0x80, /* 0111111110 */
+	0x7f, 0x00, /* 0111111100 */
+	0x7e, 0x00, /* 0111111000 */
+	0x7c, 0x00, /* 0111110000 */
+	0x78, 0x00, /* 0111100000 */
+	0x70, 0x00, /* 0111000000 */
+	0x60, 0x00, /* 0110000000 */
+	0x40, 0x00, /* 0100000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 18 0x12 '^R' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x1e, 0x00, /* 0001111000 */
+	0x3f, 0x00, /* 0011111100 */
+	0x7f, 0x80, /* 0111111110 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x7f, 0x80, /* 0111111110 */
+	0x3f, 0x00, /* 0011111100 */
+	0x1e, 0x00, /* 0001111000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 19 0x13 '^S' */
+	0x00, 0x00, /* 0000000000 */
+	0x33, 0x00, /* 0011001100 */
+	0x33, 0x00, /* 0011001100 */
+	0x33, 0x00, /* 0011001100 */
+	0x33, 0x00, /* 0011001100 */
+	0x33, 0x00, /* 0011001100 */
+	0x33, 0x00, /* 0011001100 */
+	0x33, 0x00, /* 0011001100 */
+	0x33, 0x00, /* 0011001100 */
+	0x33, 0x00, /* 0011001100 */
+	0x33, 0x00, /* 0011001100 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x33, 0x00, /* 0011001100 */
+	0x33, 0x00, /* 0011001100 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 20 0x14 '^T' */
+	0x00, 0x00, /* 0000000000 */
+	0x1f, 0xc0, /* 0001111111 */
+	0x39, 0x80, /* 0011100110 */
+	0x79, 0x80, /* 0111100110 */
+	0x79, 0x80, /* 0111100110 */
+	0x79, 0x80, /* 0111100110 */
+	0x39, 0x80, /* 0011100110 */
+	0x19, 0x80, /* 0001100110 */
+	0x19, 0x80, /* 0001100110 */
+	0x19, 0x80, /* 0001100110 */
+	0x19, 0x80, /* 0001100110 */
+	0x19, 0x80, /* 0001100110 */
+	0x19, 0x80, /* 0001100110 */
+	0x39, 0xc0, /* 0011100111 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 21 0x15 '^U' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x3e, 0x00, /* 0011111000 */
+	0x63, 0x00, /* 0110001100 */
+	0x63, 0x00, /* 0110001100 */
+	0x60, 0x00, /* 0110000000 */
+	0x60, 0x00, /* 0110000000 */
+	0x3e, 0x00, /* 0011111000 */
+	0x63, 0x00, /* 0110001100 */
+	0x63, 0x00, /* 0110001100 */
+	0x3e, 0x00, /* 0011111000 */
+	0x03, 0x00, /* 0000001100 */
+	0x03, 0x00, /* 0000001100 */
+	0x63, 0x00, /* 0110001100 */
+	0x63, 0x00, /* 0110001100 */
+	0x3e, 0x00, /* 0011111000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 22 0x16 '^V' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x7f, 0x80, /* 0111111110 */
+	0x7f, 0x80, /* 0111111110 */
+	0x7f, 0x80, /* 0111111110 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 23 0x17 '^W' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x1e, 0x00, /* 0001111000 */
+	0x3f, 0x00, /* 0011111100 */
+	0x7f, 0x80, /* 0111111110 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x7f, 0x80, /* 0111111110 */
+	0x3f, 0x00, /* 0011111100 */
+	0x1e, 0x00, /* 0001111000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x7f, 0x80, /* 0111111110 */
+	0x7f, 0x80, /* 0111111110 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 24 0x18 '^X' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x1e, 0x00, /* 0001111000 */
+	0x3f, 0x00, /* 0011111100 */
+	0x7f, 0x80, /* 0111111110 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 25 0x19 '^Y' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x7f, 0x80, /* 0111111110 */
+	0x3f, 0x00, /* 0011111100 */
+	0x1e, 0x00, /* 0001111000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 26 0x1a '^Z' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x04, 0x00, /* 0000010000 */
+	0x06, 0x00, /* 0000011000 */
+	0x07, 0x00, /* 0000011100 */
+	0x7f, 0x80, /* 0111111110 */
+	0x7f, 0x80, /* 0111111110 */
+	0x07, 0x00, /* 0000011100 */
+	0x06, 0x00, /* 0000011000 */
+	0x04, 0x00, /* 0000010000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 27 0x1b '^[' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x08, 0x00, /* 0000100000 */
+	0x18, 0x00, /* 0001100000 */
+	0x38, 0x00, /* 0011100000 */
+	0x7f, 0x80, /* 0111111110 */
+	0x7f, 0x80, /* 0111111110 */
+	0x38, 0x00, /* 0011100000 */
+	0x18, 0x00, /* 0001100000 */
+	0x08, 0x00, /* 0000100000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 28 0x1c '^\' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x60, 0x00, /* 0110000000 */
+	0x60, 0x00, /* 0110000000 */
+	0x60, 0x00, /* 0110000000 */
+	0x7f, 0x80, /* 0111111110 */
+	0x7f, 0x80, /* 0111111110 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 29 0x1d '^]' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x12, 0x00, /* 0001001000 */
+	0x33, 0x00, /* 0011001100 */
+	0x73, 0x80, /* 0111001110 */
+	0xff, 0xc0, /* 1111111111 */
+	0xff, 0xc0, /* 1111111111 */
+	0x73, 0x80, /* 0111001110 */
+	0x33, 0x00, /* 0011001100 */
+	0x12, 0x00, /* 0001001000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 30 0x1e '^^' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x04, 0x00, /* 0000010000 */
+	0x04, 0x00, /* 0000010000 */
+	0x0e, 0x00, /* 0000111000 */
+	0x0e, 0x00, /* 0000111000 */
+	0x1f, 0x00, /* 0001111100 */
+	0x1f, 0x00, /* 0001111100 */
+	0x3f, 0x80, /* 0011111110 */
+	0x3f, 0x80, /* 0011111110 */
+	0x7f, 0xc0, /* 0111111111 */
+	0x7f, 0xc0, /* 0111111111 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 31 0x1f '^_' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x7f, 0xc0, /* 0111111111 */
+	0x7f, 0xc0, /* 0111111111 */
+	0x3f, 0x80, /* 0011111110 */
+	0x3f, 0x80, /* 0011111110 */
+	0x1f, 0x00, /* 0001111100 */
+	0x1f, 0x00, /* 0001111100 */
+	0x0e, 0x00, /* 0000111000 */
+	0x0e, 0x00, /* 0000111000 */
+	0x04, 0x00, /* 0000010000 */
+	0x04, 0x00, /* 0000010000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 32 0x20 ' ' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 33 0x21 '!' */
+	0x00, 0x00, /* 0000000000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x00, 0x00, /* 0000000000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 34 0x22 '"' */
+	0x00, 0x00, /* 0000000000 */
+	0x63, 0x00, /* 0110001100 */
+	0xf7, 0x80, /* 1111011110 */
+	0xf7, 0x80, /* 1111011110 */
+	0x31, 0x80, /* 0011000110 */
+	0x31, 0x80, /* 0011000110 */
+	0x63, 0x00, /* 0110001100 */
+	0x42, 0x00, /* 0100001000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 35 0x23 '#' */
+	0x00, 0x00, /* 0000000000 */
+	0x33, 0x00, /* 0011001100 */
+	0x33, 0x00, /* 0011001100 */
+	0x7f, 0x80, /* 0111111110 */
+	0x7f, 0x80, /* 0111111110 */
+	0x33, 0x00, /* 0011001100 */
+	0x33, 0x00, /* 0011001100 */
+	0x33, 0x00, /* 0011001100 */
+	0x33, 0x00, /* 0011001100 */
+	0x7f, 0x80, /* 0111111110 */
+	0x7f, 0x80, /* 0111111110 */
+	0x33, 0x00, /* 0011001100 */
+	0x33, 0x00, /* 0011001100 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 36 0x24 '$' */
+	0x00, 0x00, /* 0000000000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x3e, 0x00, /* 0011111000 */
+	0x3f, 0x00, /* 0011111100 */
+	0x6f, 0x80, /* 0110111110 */
+	0x6d, 0x80, /* 0110110110 */
+	0x6c, 0x80, /* 0110110010 */
+	0x3c, 0x00, /* 0011110000 */
+	0x0f, 0x00, /* 0000111100 */
+	0x0d, 0x80, /* 0000110110 */
+	0x4d, 0x80, /* 0100110110 */
+	0x6d, 0x80, /* 0110110110 */
+	0x7f, 0x00, /* 0111111100 */
+	0x3e, 0x00, /* 0011111000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 37 0x25 '%' */
+	0x00, 0x00, /* 0000000000 */
+	0x31, 0x80, /* 0011000110 */
+	0x7b, 0x00, /* 0111101100 */
+	0x7b, 0x00, /* 0111101100 */
+	0x36, 0x00, /* 0011011000 */
+	0x06, 0x00, /* 0000011000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x18, 0x00, /* 0001100000 */
+	0x1b, 0x00, /* 0001101100 */
+	0x37, 0x80, /* 0011011110 */
+	0x37, 0x80, /* 0011011110 */
+	0x63, 0x00, /* 0110001100 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 38 0x26 '&' */
+	0x00, 0x00, /* 0000000000 */
+	0x07, 0x00, /* 0000011100 */
+	0x0f, 0x80, /* 0000111110 */
+	0x19, 0x80, /* 0001100110 */
+	0x19, 0x80, /* 0001100110 */
+	0x0f, 0x80, /* 0000111110 */
+	0x1e, 0x00, /* 0001111000 */
+	0x3e, 0x00, /* 0011111000 */
+	0x76, 0x00, /* 0111011000 */
+	0x66, 0x40, /* 0110011001 */
+	0x63, 0xc0, /* 0110001111 */
+	0x63, 0x80, /* 0110001110 */
+	0x63, 0x00, /* 0110001100 */
+	0x3f, 0x80, /* 0011111110 */
+	0x1c, 0xc0, /* 0001110011 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 39 0x27 ''' */
+	0x00, 0x00, /* 0000000000 */
+	0x30, 0x00, /* 0011000000 */
+	0x78, 0x00, /* 0111100000 */
+	0x78, 0x00, /* 0111100000 */
+	0x18, 0x00, /* 0001100000 */
+	0x18, 0x00, /* 0001100000 */
+	0x30, 0x00, /* 0011000000 */
+	0x20, 0x00, /* 0010000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 40 0x28 '(' */
+	0x00, 0x00, /* 0000000000 */
+	0x03, 0x00, /* 0000001100 */
+	0x06, 0x00, /* 0000011000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x18, 0x00, /* 0001100000 */
+	0x18, 0x00, /* 0001100000 */
+	0x18, 0x00, /* 0001100000 */
+	0x18, 0x00, /* 0001100000 */
+	0x18, 0x00, /* 0001100000 */
+	0x18, 0x00, /* 0001100000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x06, 0x00, /* 0000011000 */
+	0x03, 0x00, /* 0000001100 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 41 0x29 ')' */
+	0x00, 0x00, /* 0000000000 */
+	0x30, 0x00, /* 0011000000 */
+	0x18, 0x00, /* 0001100000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x06, 0x00, /* 0000011000 */
+	0x06, 0x00, /* 0000011000 */
+	0x06, 0x00, /* 0000011000 */
+	0x06, 0x00, /* 0000011000 */
+	0x06, 0x00, /* 0000011000 */
+	0x06, 0x00, /* 0000011000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x18, 0x00, /* 0001100000 */
+	0x30, 0x00, /* 0011000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 42 0x2a '*' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x4c, 0x80, /* 0100110010 */
+	0x6d, 0x80, /* 0110110110 */
+	0x3f, 0x00, /* 0011111100 */
+	0x7f, 0x80, /* 0111111110 */
+	0x3f, 0x00, /* 0011111100 */
+	0x6d, 0x80, /* 0110110110 */
+	0x4c, 0x80, /* 0100110010 */
+	0x0c, 0x00, /* 0000110000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 43 0x2b '+' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x7f, 0x80, /* 0111111110 */
+	0x7f, 0x80, /* 0111111110 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 44 0x2c ',' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x30, 0x00, /* 0011000000 */
+	0x78, 0x00, /* 0111100000 */
+	0x78, 0x00, /* 0111100000 */
+	0x18, 0x00, /* 0001100000 */
+	0x18, 0x00, /* 0001100000 */
+	0x30, 0x00, /* 0011000000 */
+	0x60, 0x00, /* 0110000000 */
+	0x40, 0x00, /* 0100000000 */
+
+	/* 45 0x2d '-' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x7f, 0x80, /* 0111111110 */
+	0x7f, 0x80, /* 0111111110 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 46 0x2e '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x18, 0x00, /* 0001100000 */
+	0x3c, 0x00, /* 0011110000 */
+	0x3c, 0x00, /* 0011110000 */
+	0x18, 0x00, /* 0001100000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 47 0x2f '/' */
+	0x00, 0x00, /* 0000000000 */
+	0x01, 0x80, /* 0000000110 */
+	0x01, 0x80, /* 0000000110 */
+	0x03, 0x00, /* 0000001100 */
+	0x03, 0x00, /* 0000001100 */
+	0x06, 0x00, /* 0000011000 */
+	0x06, 0x00, /* 0000011000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x18, 0x00, /* 0001100000 */
+	0x18, 0x00, /* 0001100000 */
+	0x30, 0x00, /* 0011000000 */
+	0x30, 0x00, /* 0011000000 */
+	0x60, 0x00, /* 0110000000 */
+	0x60, 0x00, /* 0110000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 48 0x30 '0' */
+	0x00, 0x00, /* 0000000000 */
+	0x0e, 0x00, /* 0000111000 */
+	0x1f, 0x00, /* 0001111100 */
+	0x23, 0x00, /* 0010001100 */
+	0x61, 0x80, /* 0110000110 */
+	0x63, 0x80, /* 0110001110 */
+	0x65, 0x80, /* 0110010110 */
+	0x65, 0x80, /* 0110010110 */
+	0x69, 0x80, /* 0110100110 */
+	0x69, 0x80, /* 0110100110 */
+	0x71, 0x80, /* 0111000110 */
+	0x61, 0x00, /* 0110000100 */
+	0x31, 0x00, /* 0011000100 */
+	0x3e, 0x00, /* 0011111000 */
+	0x1c, 0x00, /* 0001110000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 49 0x31 '1' */
+	0x00, 0x00, /* 0000000000 */
+	0x04, 0x00, /* 0000010000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x1c, 0x00, /* 0001110000 */
+	0x3c, 0x00, /* 0011110000 */
+	0x6c, 0x00, /* 0110110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x7f, 0x80, /* 0111111110 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 50 0x32 '2' */
+	0x00, 0x00, /* 0000000000 */
+	0x1e, 0x00, /* 0001111000 */
+	0x3f, 0x00, /* 0011111100 */
+	0x63, 0x80, /* 0110001110 */
+	0x41, 0x80, /* 0100000110 */
+	0x01, 0x80, /* 0000000110 */
+	0x01, 0x80, /* 0000000110 */
+	0x03, 0x00, /* 0000001100 */
+	0x06, 0x00, /* 0000011000 */
+	0x06, 0x00, /* 0000011000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x18, 0x00, /* 0001100000 */
+	0x30, 0x80, /* 0011000010 */
+	0x7f, 0x80, /* 0111111110 */
+	0x7f, 0x80, /* 0111111110 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 51 0x33 '3' */
+	0x00, 0x00, /* 0000000000 */
+	0x1c, 0x00, /* 0001110000 */
+	0x3e, 0x00, /* 0011111000 */
+	0x47, 0x00, /* 0100011100 */
+	0x03, 0x00, /* 0000001100 */
+	0x07, 0x00, /* 0000011100 */
+	0x06, 0x00, /* 0000011000 */
+	0x0e, 0x00, /* 0000111000 */
+	0x07, 0x00, /* 0000011100 */
+	0x03, 0x00, /* 0000001100 */
+	0x01, 0x80, /* 0000000110 */
+	0x41, 0x80, /* 0100000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x3f, 0x00, /* 0011111100 */
+	0x1e, 0x00, /* 0001111000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 52 0x34 '4' */
+	0x00, 0x00, /* 0000000000 */
+	0x06, 0x00, /* 0000011000 */
+	0x0e, 0x00, /* 0000111000 */
+	0x1e, 0x00, /* 0001111000 */
+	0x36, 0x00, /* 0011011000 */
+	0x36, 0x00, /* 0011011000 */
+	0x66, 0x00, /* 0110011000 */
+	0x66, 0x00, /* 0110011000 */
+	0xc6, 0x00, /* 1100011000 */
+	0xc6, 0x00, /* 1100011000 */
+	0xff, 0x80, /* 1111111110 */
+	0xff, 0x80, /* 1111111110 */
+	0x06, 0x00, /* 0000011000 */
+	0x06, 0x00, /* 0000011000 */
+	0x06, 0x00, /* 0000011000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 53 0x35 '5' */
+	0x00, 0x00, /* 0000000000 */
+	0x1f, 0x00, /* 0001111100 */
+	0x1f, 0x00, /* 0001111100 */
+	0x30, 0x00, /* 0011000000 */
+	0x30, 0x00, /* 0011000000 */
+	0x60, 0x00, /* 0110000000 */
+	0x7e, 0x00, /* 0111111000 */
+	0x67, 0x00, /* 0110011100 */
+	0x03, 0x80, /* 0000001110 */
+	0x01, 0x80, /* 0000000110 */
+	0x01, 0x80, /* 0000000110 */
+	0x01, 0x80, /* 0000000110 */
+	0x41, 0x80, /* 0100000110 */
+	0x63, 0x00, /* 0110001100 */
+	0x3e, 0x00, /* 0011111000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 54 0x36 '6' */
+	0x00, 0x00, /* 0000000000 */
+	0x06, 0x00, /* 0000011000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x18, 0x00, /* 0001100000 */
+	0x30, 0x00, /* 0011000000 */
+	0x30, 0x00, /* 0011000000 */
+	0x60, 0x00, /* 0110000000 */
+	0x6e, 0x00, /* 0110111000 */
+	0x7f, 0x00, /* 0111111100 */
+	0x73, 0x80, /* 0111001110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x71, 0x00, /* 0111000100 */
+	0x3e, 0x00, /* 0011111000 */
+	0x1c, 0x00, /* 0001110000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 55 0x37 '7' */
+	0x00, 0x00, /* 0000000000 */
+	0x1f, 0x80, /* 0001111110 */
+	0x3f, 0x80, /* 0011111110 */
+	0x61, 0x80, /* 0110000110 */
+	0x01, 0x80, /* 0000000110 */
+	0x03, 0x00, /* 0000001100 */
+	0x03, 0x00, /* 0000001100 */
+	0x06, 0x00, /* 0000011000 */
+	0x06, 0x00, /* 0000011000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x18, 0x00, /* 0001100000 */
+	0x18, 0x00, /* 0001100000 */
+	0x30, 0x00, /* 0011000000 */
+	0x30, 0x00, /* 0011000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 56 0x38 '8' */
+	0x00, 0x00, /* 0000000000 */
+	0x1e, 0x00, /* 0001111000 */
+	0x23, 0x00, /* 0010001100 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x31, 0x00, /* 0011000100 */
+	0x1a, 0x00, /* 0001101000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x16, 0x00, /* 0001011000 */
+	0x23, 0x00, /* 0010001100 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x31, 0x00, /* 0011000100 */
+	0x1e, 0x00, /* 0001111000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 57 0x39 '9' */
+	0x00, 0x00, /* 0000000000 */
+	0x0e, 0x00, /* 0000111000 */
+	0x17, 0x00, /* 0001011100 */
+	0x23, 0x80, /* 0010001110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x73, 0x80, /* 0111001110 */
+	0x3d, 0x80, /* 0011110110 */
+	0x19, 0x80, /* 0001100110 */
+	0x01, 0x80, /* 0000000110 */
+	0x03, 0x00, /* 0000001100 */
+	0x03, 0x00, /* 0000001100 */
+	0x06, 0x00, /* 0000011000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x18, 0x00, /* 0001100000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 58 0x3a ':' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x18, 0x00, /* 0001100000 */
+	0x3c, 0x00, /* 0011110000 */
+	0x3c, 0x00, /* 0011110000 */
+	0x18, 0x00, /* 0001100000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x18, 0x00, /* 0001100000 */
+	0x3c, 0x00, /* 0011110000 */
+	0x3c, 0x00, /* 0011110000 */
+	0x18, 0x00, /* 0001100000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 59 0x3b ';' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x18, 0x00, /* 0001100000 */
+	0x3c, 0x00, /* 0011110000 */
+	0x3c, 0x00, /* 0011110000 */
+	0x18, 0x00, /* 0001100000 */
+	0x00, 0x00, /* 0000000000 */
+	0x18, 0x00, /* 0001100000 */
+	0x3c, 0x00, /* 0011110000 */
+	0x3c, 0x00, /* 0011110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x18, 0x00, /* 0001100000 */
+	0x30, 0x00, /* 0011000000 */
+	0x20, 0x00, /* 0010000000 */
+
+	/* 60 0x3c '<' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x03, 0x00, /* 0000001100 */
+	0x06, 0x00, /* 0000011000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x18, 0x00, /* 0001100000 */
+	0x30, 0x00, /* 0011000000 */
+	0x60, 0x00, /* 0110000000 */
+	0x60, 0x00, /* 0110000000 */
+	0x30, 0x00, /* 0011000000 */
+	0x18, 0x00, /* 0001100000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x06, 0x00, /* 0000011000 */
+	0x03, 0x00, /* 0000001100 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 61 0x3d '=' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x7f, 0x80, /* 0111111110 */
+	0x7f, 0x80, /* 0111111110 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x7f, 0x80, /* 0111111110 */
+	0x7f, 0x80, /* 0111111110 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 62 0x3e '>' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x30, 0x00, /* 0011000000 */
+	0x18, 0x00, /* 0001100000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x06, 0x00, /* 0000011000 */
+	0x03, 0x00, /* 0000001100 */
+	0x01, 0x80, /* 0000000110 */
+	0x01, 0x80, /* 0000000110 */
+	0x03, 0x00, /* 0000001100 */
+	0x06, 0x00, /* 0000011000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x18, 0x00, /* 0001100000 */
+	0x30, 0x00, /* 0011000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 63 0x3f '?' */
+	0x00, 0x00, /* 0000000000 */
+	0x0e, 0x00, /* 0000111000 */
+	0x1f, 0x00, /* 0001111100 */
+	0x3b, 0x80, /* 0011101110 */
+	0x21, 0x80, /* 0010000110 */
+	0x01, 0x80, /* 0000000110 */
+	0x03, 0x00, /* 0000001100 */
+	0x06, 0x00, /* 0000011000 */
+	0x06, 0x00, /* 0000011000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 64 0x40 '@' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x0e, 0x00, /* 0000111000 */
+	0x3f, 0x00, /* 0011111100 */
+	0x31, 0x80, /* 0011000110 */
+	0x65, 0x80, /* 0110010110 */
+	0x6d, 0x80, /* 0110110110 */
+	0x6d, 0x80, /* 0110110110 */
+	0x6d, 0x80, /* 0110110110 */
+	0x6d, 0x80, /* 0110110110 */
+	0x6f, 0x80, /* 0110111110 */
+	0x60, 0x00, /* 0110000000 */
+	0x31, 0x80, /* 0011000110 */
+	0x3f, 0x80, /* 0011111110 */
+	0x0f, 0x00, /* 0000111100 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 65 0x41 'A' */
+	0x00, 0x00, /* 0000000000 */
+	0x04, 0x00, /* 0000010000 */
+	0x04, 0x00, /* 0000010000 */
+	0x0e, 0x00, /* 0000111000 */
+	0x0e, 0x00, /* 0000111000 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x19, 0x80, /* 0001100110 */
+	0x31, 0x80, /* 0011000110 */
+	0x3f, 0x80, /* 0011111110 */
+	0x31, 0x80, /* 0011000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x60, 0xc0, /* 0110000011 */
+	0x60, 0xc0, /* 0110000011 */
+	0xf1, 0xc0, /* 1111000111 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 66 0x42 'B' */
+	0x00, 0x00, /* 0000000000 */
+	0xfc, 0x00, /* 1111110000 */
+	0x62, 0x00, /* 0110001000 */
+	0x63, 0x00, /* 0110001100 */
+	0x63, 0x00, /* 0110001100 */
+	0x63, 0x00, /* 0110001100 */
+	0x66, 0x00, /* 0110011000 */
+	0x7e, 0x00, /* 0111111000 */
+	0x63, 0x00, /* 0110001100 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x63, 0x00, /* 0110001100 */
+	0xfe, 0x00, /* 1111111000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 67 0x43 'C' */
+	0x00, 0x00, /* 0000000000 */
+	0x0f, 0x00, /* 0000111100 */
+	0x11, 0x80, /* 0001000110 */
+	0x20, 0x80, /* 0010000010 */
+	0x20, 0x00, /* 0010000000 */
+	0x60, 0x00, /* 0110000000 */
+	0x60, 0x00, /* 0110000000 */
+	0x60, 0x00, /* 0110000000 */
+	0x60, 0x00, /* 0110000000 */
+	0x60, 0x00, /* 0110000000 */
+	0x60, 0x00, /* 0110000000 */
+	0x20, 0x00, /* 0010000000 */
+	0x30, 0x80, /* 0011000010 */
+	0x19, 0x00, /* 0001100100 */
+	0x0e, 0x00, /* 0000111000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 68 0x44 'D' */
+	0x00, 0x00, /* 0000000000 */
+	0xfc, 0x00, /* 1111110000 */
+	0x67, 0x00, /* 0110011100 */
+	0x63, 0x00, /* 0110001100 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x00, /* 0110000100 */
+	0x66, 0x00, /* 0110011000 */
+	0xf8, 0x00, /* 1111100000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 69 0x45 'E' */
+	0x00, 0x00, /* 0000000000 */
+	0x7f, 0x80, /* 0111111110 */
+	0x30, 0x80, /* 0011000010 */
+	0x30, 0x80, /* 0011000010 */
+	0x30, 0x00, /* 0011000000 */
+	0x30, 0x00, /* 0011000000 */
+	0x31, 0x00, /* 0011000100 */
+	0x3f, 0x00, /* 0011111100 */
+	0x31, 0x00, /* 0011000100 */
+	0x30, 0x00, /* 0011000000 */
+	0x30, 0x00, /* 0011000000 */
+	0x30, 0x00, /* 0011000000 */
+	0x30, 0x80, /* 0011000010 */
+	0x30, 0x80, /* 0011000010 */
+	0x7f, 0x80, /* 0111111110 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 70 0x46 'F' */
+	0x00, 0x00, /* 0000000000 */
+	0x7f, 0x80, /* 0111111110 */
+	0x30, 0x80, /* 0011000010 */
+	0x30, 0x80, /* 0011000010 */
+	0x30, 0x00, /* 0011000000 */
+	0x30, 0x00, /* 0011000000 */
+	0x31, 0x00, /* 0011000100 */
+	0x3f, 0x00, /* 0011111100 */
+	0x31, 0x00, /* 0011000100 */
+	0x30, 0x00, /* 0011000000 */
+	0x30, 0x00, /* 0011000000 */
+	0x30, 0x00, /* 0011000000 */
+	0x30, 0x00, /* 0011000000 */
+	0x30, 0x00, /* 0011000000 */
+	0x78, 0x00, /* 0111100000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 71 0x47 'G' */
+	0x00, 0x00, /* 0000000000 */
+	0x0f, 0x00, /* 0000111100 */
+	0x11, 0x80, /* 0001000110 */
+	0x20, 0x80, /* 0010000010 */
+	0x20, 0x00, /* 0010000000 */
+	0x60, 0x00, /* 0110000000 */
+	0x60, 0x00, /* 0110000000 */
+	0x60, 0x00, /* 0110000000 */
+	0x60, 0x00, /* 0110000000 */
+	0x67, 0xc0, /* 0110011111 */
+	0x61, 0x80, /* 0110000110 */
+	0x21, 0x80, /* 0010000110 */
+	0x31, 0x80, /* 0011000110 */
+	0x19, 0x80, /* 0001100110 */
+	0x0e, 0x00, /* 0000111000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 72 0x48 'H' */
+	0x00, 0x00, /* 0000000000 */
+	0xf3, 0xc0, /* 1111001111 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x7f, 0x80, /* 0111111110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0xf3, 0xc0, /* 1111001111 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 73 0x49 'I' */
+	0x00, 0x00, /* 0000000000 */
+	0x3f, 0x00, /* 0011111100 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x3f, 0x00, /* 0011111100 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 74 0x4a 'J' */
+	0x00, 0x00, /* 0000000000 */
+	0x3f, 0x00, /* 0011111100 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x08, 0x00, /* 0000100000 */
+	0x70, 0x00, /* 0111000000 */
+	0x60, 0x00, /* 0110000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 75 0x4b 'K' */
+	0x00, 0x00, /* 0000000000 */
+	0xf1, 0x80, /* 1111000110 */
+	0x63, 0x00, /* 0110001100 */
+	0x66, 0x00, /* 0110011000 */
+	0x6c, 0x00, /* 0110110000 */
+	0x78, 0x00, /* 0111100000 */
+	0x70, 0x00, /* 0111000000 */
+	0x70, 0x00, /* 0111000000 */
+	0x78, 0x00, /* 0111100000 */
+	0x78, 0x00, /* 0111100000 */
+	0x6c, 0x00, /* 0110110000 */
+	0x66, 0x00, /* 0110011000 */
+	0x63, 0x00, /* 0110001100 */
+	0x61, 0x80, /* 0110000110 */
+	0xf0, 0xc0, /* 1111000011 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 76 0x4c 'L' */
+	0x00, 0x00, /* 0000000000 */
+	0x78, 0x00, /* 0111100000 */
+	0x30, 0x00, /* 0011000000 */
+	0x30, 0x00, /* 0011000000 */
+	0x30, 0x00, /* 0011000000 */
+	0x30, 0x00, /* 0011000000 */
+	0x30, 0x00, /* 0011000000 */
+	0x30, 0x00, /* 0011000000 */
+	0x30, 0x00, /* 0011000000 */
+	0x30, 0x00, /* 0011000000 */
+	0x30, 0x00, /* 0011000000 */
+	0x30, 0x00, /* 0011000000 */
+	0x30, 0x80, /* 0011000010 */
+	0x30, 0x80, /* 0011000010 */
+	0x7f, 0x80, /* 0111111110 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 77 0x4d 'M' */
+	0x00, 0x00, /* 0000000000 */
+	0xe0, 0xc0, /* 1110000011 */
+	0x61, 0x80, /* 0110000110 */
+	0x73, 0x80, /* 0111001110 */
+	0x73, 0x80, /* 0111001110 */
+	0x6d, 0x80, /* 0110110110 */
+	0x6d, 0x80, /* 0110110110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0xf3, 0xc0, /* 1111001111 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 78 0x4e 'N' */
+	0x00, 0x00, /* 0000000000 */
+	0xf3, 0xc0, /* 1111001111 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x71, 0x80, /* 0111000110 */
+	0x79, 0x80, /* 0111100110 */
+	0x79, 0x80, /* 0111100110 */
+	0x6d, 0x80, /* 0110110110 */
+	0x6d, 0x80, /* 0110110110 */
+	0x67, 0x80, /* 0110011110 */
+	0x67, 0x80, /* 0110011110 */
+	0x63, 0x80, /* 0110001110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0xf3, 0xc0, /* 1111001111 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 79 0x4f 'O' */
+	0x00, 0x00, /* 0000000000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x17, 0x00, /* 0001011100 */
+	0x23, 0x00, /* 0010001100 */
+	0x21, 0x80, /* 0010000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x21, 0x00, /* 0010000100 */
+	0x31, 0x00, /* 0011000100 */
+	0x1a, 0x00, /* 0001101000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 80 0x50 'P' */
+	0x00, 0x00, /* 0000000000 */
+	0xfe, 0x00, /* 1111111000 */
+	0x63, 0x00, /* 0110001100 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x63, 0x00, /* 0110001100 */
+	0x7e, 0x00, /* 0111111000 */
+	0x60, 0x00, /* 0110000000 */
+	0x60, 0x00, /* 0110000000 */
+	0x60, 0x00, /* 0110000000 */
+	0x60, 0x00, /* 0110000000 */
+	0x60, 0x00, /* 0110000000 */
+	0x60, 0x00, /* 0110000000 */
+	0xf0, 0x00, /* 1111000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 81 0x51 'Q' */
+	0x00, 0x00, /* 0000000000 */
+	0x0e, 0x00, /* 0000111000 */
+	0x13, 0x00, /* 0001001100 */
+	0x23, 0x00, /* 0010001100 */
+	0x21, 0x80, /* 0010000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x31, 0x80, /* 0011000110 */
+	0x3b, 0x00, /* 0011101100 */
+	0x1e, 0x00, /* 0001111000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x1e, 0x00, /* 0001111000 */
+	0x26, 0x00, /* 0010011000 */
+	0x03, 0x80, /* 0000001110 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 82 0x52 'R' */
+	0x00, 0x00, /* 0000000000 */
+	0xfe, 0x00, /* 1111111000 */
+	0x63, 0x00, /* 0110001100 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x00, /* 0110000100 */
+	0x7e, 0x00, /* 0111111000 */
+	0x78, 0x00, /* 0111100000 */
+	0x6c, 0x00, /* 0110110000 */
+	0x6e, 0x00, /* 0110111000 */
+	0x67, 0x00, /* 0110011100 */
+	0x63, 0x80, /* 0110001110 */
+	0x61, 0xc0, /* 0110000111 */
+	0xf0, 0xc0, /* 1111000011 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 83 0x53 'S' */
+	0x00, 0x00, /* 0000000000 */
+	0x1f, 0x00, /* 0001111100 */
+	0x31, 0x80, /* 0011000110 */
+	0x60, 0x80, /* 0110000010 */
+	0x60, 0x00, /* 0110000000 */
+	0x60, 0x00, /* 0110000000 */
+	0x30, 0x00, /* 0011000000 */
+	0x18, 0x00, /* 0001100000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x06, 0x00, /* 0000011000 */
+	0x03, 0x00, /* 0000001100 */
+	0x01, 0x80, /* 0000000110 */
+	0x41, 0x80, /* 0100000110 */
+	0x63, 0x00, /* 0110001100 */
+	0x3e, 0x00, /* 0011111000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 84 0x54 'T' */
+	0x00, 0x00, /* 0000000000 */
+	0x7f, 0x80, /* 0111111110 */
+	0x4c, 0x80, /* 0100110010 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x3f, 0x00, /* 0011111100 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 85 0x55 'U' */
+	0x00, 0x00, /* 0000000000 */
+	0xf3, 0xc0, /* 1111001111 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x73, 0x00, /* 0111001100 */
+	0x3f, 0x00, /* 0011111100 */
+	0x1e, 0x00, /* 0001111000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 86 0x56 'V' */
+	0x00, 0x00, /* 0000000000 */
+	0xe1, 0xc0, /* 1110000111 */
+	0xc0, 0xc0, /* 1100000011 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x33, 0x00, /* 0011001100 */
+	0x33, 0x00, /* 0011001100 */
+	0x33, 0x00, /* 0011001100 */
+	0x12, 0x00, /* 0001001000 */
+	0x1e, 0x00, /* 0001111000 */
+	0x1e, 0x00, /* 0001111000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 87 0x57 'W' */
+	0x00, 0x00, /* 0000000000 */
+	0xe1, 0xc0, /* 1110000111 */
+	0xc0, 0xc0, /* 1100000011 */
+	0xc0, 0xc0, /* 1100000011 */
+	0xc0, 0xc0, /* 1100000011 */
+	0xe0, 0xc0, /* 1110000011 */
+	0x61, 0x80, /* 0110000110 */
+	0x6d, 0x80, /* 0110110110 */
+	0x6d, 0x80, /* 0110110110 */
+	0x7f, 0x80, /* 0111111110 */
+	0x77, 0x00, /* 0111011100 */
+	0x33, 0x00, /* 0011001100 */
+	0x33, 0x00, /* 0011001100 */
+	0x33, 0x00, /* 0011001100 */
+	0x33, 0x00, /* 0011001100 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 88 0x58 'X' */
+	0x00, 0x00, /* 0000000000 */
+	0xf7, 0x80, /* 1111011110 */
+	0x63, 0x00, /* 0110001100 */
+	0x63, 0x00, /* 0110001100 */
+	0x36, 0x00, /* 0011011000 */
+	0x36, 0x00, /* 0011011000 */
+	0x36, 0x00, /* 0011011000 */
+	0x1c, 0x00, /* 0001110000 */
+	0x1c, 0x00, /* 0001110000 */
+	0x36, 0x00, /* 0011011000 */
+	0x36, 0x00, /* 0011011000 */
+	0x36, 0x00, /* 0011011000 */
+	0x63, 0x00, /* 0110001100 */
+	0x63, 0x00, /* 0110001100 */
+	0xf7, 0x80, /* 1111011110 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 89 0x59 'Y' */
+	0x00, 0x00, /* 0000000000 */
+	0xf3, 0xc0, /* 1111001111 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x33, 0x00, /* 0011001100 */
+	0x33, 0x00, /* 0011001100 */
+	0x1e, 0x00, /* 0001111000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x1e, 0x00, /* 0001111000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 90 0x5a 'Z' */
+	0x00, 0x00, /* 0000000000 */
+	0x3f, 0x80, /* 0011111110 */
+	0x21, 0x80, /* 0010000110 */
+	0x01, 0x80, /* 0000000110 */
+	0x03, 0x00, /* 0000001100 */
+	0x03, 0x00, /* 0000001100 */
+	0x06, 0x00, /* 0000011000 */
+	0x06, 0x00, /* 0000011000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x18, 0x00, /* 0001100000 */
+	0x18, 0x00, /* 0001100000 */
+	0x30, 0x00, /* 0011000000 */
+	0x30, 0x80, /* 0011000010 */
+	0x3f, 0x80, /* 0011111110 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 91 0x5b '[' */
+	0x00, 0x00, /* 0000000000 */
+	0x1f, 0x00, /* 0001111100 */
+	0x1f, 0x00, /* 0001111100 */
+	0x18, 0x00, /* 0001100000 */
+	0x18, 0x00, /* 0001100000 */
+	0x18, 0x00, /* 0001100000 */
+	0x18, 0x00, /* 0001100000 */
+	0x18, 0x00, /* 0001100000 */
+	0x18, 0x00, /* 0001100000 */
+	0x18, 0x00, /* 0001100000 */
+	0x18, 0x00, /* 0001100000 */
+	0x18, 0x00, /* 0001100000 */
+	0x18, 0x00, /* 0001100000 */
+	0x18, 0x00, /* 0001100000 */
+	0x1f, 0x00, /* 0001111100 */
+	0x1f, 0x00, /* 0001111100 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 92 0x5c '\' */
+	0x00, 0x00, /* 0000000000 */
+	0xc0, 0x00, /* 1100000000 */
+	0x60, 0x00, /* 0110000000 */
+	0x60, 0x00, /* 0110000000 */
+	0x30, 0x00, /* 0011000000 */
+	0x30, 0x00, /* 0011000000 */
+	0x18, 0x00, /* 0001100000 */
+	0x18, 0x00, /* 0001100000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x06, 0x00, /* 0000011000 */
+	0x06, 0x00, /* 0000011000 */
+	0x03, 0x00, /* 0000001100 */
+	0x03, 0x00, /* 0000001100 */
+	0x01, 0x80, /* 0000000110 */
+	0x01, 0x80, /* 0000000110 */
+	0x00, 0xc0, /* 0000000011 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 93 0x5d ']' */
+	0x00, 0x00, /* 0000000000 */
+	0x3e, 0x00, /* 0011111000 */
+	0x3e, 0x00, /* 0011111000 */
+	0x06, 0x00, /* 0000011000 */
+	0x06, 0x00, /* 0000011000 */
+	0x06, 0x00, /* 0000011000 */
+	0x06, 0x00, /* 0000011000 */
+	0x06, 0x00, /* 0000011000 */
+	0x06, 0x00, /* 0000011000 */
+	0x06, 0x00, /* 0000011000 */
+	0x06, 0x00, /* 0000011000 */
+	0x06, 0x00, /* 0000011000 */
+	0x06, 0x00, /* 0000011000 */
+	0x06, 0x00, /* 0000011000 */
+	0x3e, 0x00, /* 0011111000 */
+	0x3e, 0x00, /* 0011111000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 94 0x5e '^' */
+	0x00, 0x00, /* 0000000000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x1e, 0x00, /* 0001111000 */
+	0x33, 0x00, /* 0011001100 */
+	0x61, 0x80, /* 0110000110 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 95 0x5f '_' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0xff, 0xc0, /* 1111111111 */
+	0xff, 0xc0, /* 1111111111 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 96 0x60 '`' */
+	0x04, 0x00, /* 0000010000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x18, 0x00, /* 0001100000 */
+	0x18, 0x00, /* 0001100000 */
+	0x1e, 0x00, /* 0001111000 */
+	0x1e, 0x00, /* 0001111000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 97 0x61 'a' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x1f, 0x00, /* 0001111100 */
+	0x31, 0x80, /* 0011000110 */
+	0x21, 0x80, /* 0010000110 */
+	0x07, 0x80, /* 0000011110 */
+	0x39, 0x80, /* 0011100110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x73, 0x80, /* 0111001110 */
+	0x3d, 0xc0, /* 0011110111 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 98 0x62 'b' */
+	0x20, 0x00, /* 0010000000 */
+	0x60, 0x00, /* 0110000000 */
+	0xe0, 0x00, /* 1110000000 */
+	0x60, 0x00, /* 0110000000 */
+	0x60, 0x00, /* 0110000000 */
+	0x66, 0x00, /* 0110011000 */
+	0x6f, 0x00, /* 0110111100 */
+	0x73, 0x80, /* 0111001110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x71, 0x80, /* 0111000110 */
+	0x7b, 0x00, /* 0111101100 */
+	0x4e, 0x00, /* 0100111000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 99 0x63 'c' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x1e, 0x00, /* 0001111000 */
+	0x37, 0x00, /* 0011011100 */
+	0x23, 0x00, /* 0010001100 */
+	0x60, 0x00, /* 0110000000 */
+	0x60, 0x00, /* 0110000000 */
+	0x60, 0x00, /* 0110000000 */
+	0x60, 0x00, /* 0110000000 */
+	0x71, 0x00, /* 0111000100 */
+	0x33, 0x00, /* 0011001100 */
+	0x1e, 0x00, /* 0001111000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 100 0x64 'd' */
+	0x01, 0x80, /* 0000000110 */
+	0x03, 0x80, /* 0000001110 */
+	0x01, 0x80, /* 0000000110 */
+	0x01, 0x80, /* 0000000110 */
+	0x01, 0x80, /* 0000000110 */
+	0x0d, 0x80, /* 0000110110 */
+	0x37, 0x80, /* 0011011110 */
+	0x23, 0x80, /* 0010001110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x73, 0x80, /* 0111001110 */
+	0x35, 0x80, /* 0011010110 */
+	0x19, 0xc0, /* 0001100111 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 101 0x65 'e' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x33, 0x00, /* 0011001100 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x7f, 0x80, /* 0111111110 */
+	0x60, 0x00, /* 0110000000 */
+	0x60, 0x00, /* 0110000000 */
+	0x30, 0x00, /* 0011000000 */
+	0x19, 0x80, /* 0001100110 */
+	0x0e, 0x00, /* 0000111000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 102 0x66 'f' */
+	0x07, 0x00, /* 0000011100 */
+	0x09, 0x80, /* 0000100110 */
+	0x09, 0x80, /* 0000100110 */
+	0x18, 0x00, /* 0001100000 */
+	0x18, 0x00, /* 0001100000 */
+	0x18, 0x00, /* 0001100000 */
+	0x18, 0x00, /* 0001100000 */
+	0x7f, 0x00, /* 0111111100 */
+	0x18, 0x00, /* 0001100000 */
+	0x18, 0x00, /* 0001100000 */
+	0x18, 0x00, /* 0001100000 */
+	0x18, 0x00, /* 0001100000 */
+	0x18, 0x00, /* 0001100000 */
+	0x18, 0x00, /* 0001100000 */
+	0x3c, 0x00, /* 0011110000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 103 0x67 'g' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x1c, 0x80, /* 0001110010 */
+	0x37, 0x80, /* 0011011110 */
+	0x63, 0x00, /* 0110001100 */
+	0x63, 0x00, /* 0110001100 */
+	0x36, 0x00, /* 0011011000 */
+	0x3c, 0x00, /* 0011110000 */
+	0x60, 0x00, /* 0110000000 */
+	0x7f, 0x00, /* 0111111100 */
+	0x3f, 0x80, /* 0011111110 */
+	0x21, 0x80, /* 0010000110 */
+	0x40, 0x80, /* 0100000010 */
+	0x7f, 0x00, /* 0111111100 */
+	0x3e, 0x00, /* 0011111000 */
+
+	/* 104 0x68 'h' */
+	0x10, 0x00, /* 0001000000 */
+	0x30, 0x00, /* 0011000000 */
+	0x70, 0x00, /* 0111000000 */
+	0x30, 0x00, /* 0011000000 */
+	0x30, 0x00, /* 0011000000 */
+	0x37, 0x00, /* 0011011100 */
+	0x3b, 0x80, /* 0011101110 */
+	0x31, 0x80, /* 0011000110 */
+	0x31, 0x80, /* 0011000110 */
+	0x31, 0x80, /* 0011000110 */
+	0x31, 0x80, /* 0011000110 */
+	0x31, 0x80, /* 0011000110 */
+	0x31, 0x80, /* 0011000110 */
+	0x31, 0x80, /* 0011000110 */
+	0x7b, 0xc0, /* 0111101111 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 105 0x69 'i' */
+	0x00, 0x00, /* 0000000000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x3c, 0x00, /* 0011110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x3f, 0x00, /* 0011111100 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 106 0x6a 'j' */
+	0x00, 0x00, /* 0000000000 */
+	0x01, 0x80, /* 0000000110 */
+	0x01, 0x80, /* 0000000110 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x07, 0x80, /* 0000011110 */
+	0x01, 0x80, /* 0000000110 */
+	0x01, 0x80, /* 0000000110 */
+	0x01, 0x80, /* 0000000110 */
+	0x01, 0x80, /* 0000000110 */
+	0x01, 0x80, /* 0000000110 */
+	0x01, 0x80, /* 0000000110 */
+	0x01, 0x80, /* 0000000110 */
+	0x41, 0x80, /* 0100000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x71, 0x80, /* 0111000110 */
+	0x3f, 0x00, /* 0011111100 */
+	0x1c, 0x00, /* 0001110000 */
+
+	/* 107 0x6b 'k' */
+	0x60, 0x00, /* 0110000000 */
+	0xe0, 0x00, /* 1110000000 */
+	0x60, 0x00, /* 0110000000 */
+	0x60, 0x00, /* 0110000000 */
+	0x60, 0x00, /* 0110000000 */
+	0x63, 0x80, /* 0110001110 */
+	0x66, 0x00, /* 0110011000 */
+	0x6c, 0x00, /* 0110110000 */
+	0x78, 0x00, /* 0111100000 */
+	0x70, 0x00, /* 0111000000 */
+	0x78, 0x00, /* 0111100000 */
+	0x6c, 0x00, /* 0110110000 */
+	0x6e, 0x00, /* 0110111000 */
+	0x67, 0x00, /* 0110011100 */
+	0xf3, 0x80, /* 1111001110 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 108 0x6c 'l' */
+	0x3c, 0x00, /* 0011110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x3f, 0x00, /* 0011111100 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 109 0x6d 'm' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0xdb, 0x80, /* 1101101110 */
+	0x6d, 0x80, /* 0110110110 */
+	0x6d, 0x80, /* 0110110110 */
+	0x6d, 0x80, /* 0110110110 */
+	0x6d, 0x80, /* 0110110110 */
+	0x6d, 0x80, /* 0110110110 */
+	0x6d, 0x80, /* 0110110110 */
+	0x6d, 0x80, /* 0110110110 */
+	0x6d, 0x80, /* 0110110110 */
+	0xed, 0xc0, /* 1110110111 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 110 0x6e 'n' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x6f, 0x00, /* 0110111100 */
+	0x7b, 0x80, /* 0111101110 */
+	0x31, 0x80, /* 0011000110 */
+	0x31, 0x80, /* 0011000110 */
+	0x31, 0x80, /* 0011000110 */
+	0x31, 0x80, /* 0011000110 */
+	0x31, 0x80, /* 0011000110 */
+	0x31, 0x80, /* 0011000110 */
+	0x31, 0x80, /* 0011000110 */
+	0x7b, 0xc0, /* 0111101111 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 111 0x6f 'o' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x3c, 0x00, /* 0011110000 */
+	0x66, 0x00, /* 0110011000 */
+	0xc3, 0x00, /* 1100001100 */
+	0xc1, 0x80, /* 1100000110 */
+	0xc1, 0x80, /* 1100000110 */
+	0xc1, 0x80, /* 1100000110 */
+	0xc1, 0x80, /* 1100000110 */
+	0xe1, 0x80, /* 1110000110 */
+	0x73, 0x00, /* 0111001100 */
+	0x3c, 0x00, /* 0011110000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 112 0x70 'p' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0xde, 0x00, /* 1101111000 */
+	0x76, 0x00, /* 0111011000 */
+	0x63, 0x00, /* 0110001100 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x71, 0x80, /* 0111000110 */
+	0x7b, 0x00, /* 0111101100 */
+	0x7e, 0x00, /* 0111111000 */
+	0x60, 0x00, /* 0110000000 */
+	0x60, 0x00, /* 0110000000 */
+	0xf0, 0x00, /* 1111000000 */
+
+	/* 113 0x71 'q' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x0e, 0xc0, /* 0000111011 */
+	0x1b, 0x80, /* 0001101110 */
+	0x33, 0x80, /* 0011001110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x71, 0x80, /* 0111000110 */
+	0x3b, 0x80, /* 0011101110 */
+	0x1f, 0x80, /* 0001111110 */
+	0x01, 0x80, /* 0000000110 */
+	0x01, 0x80, /* 0000000110 */
+	0x03, 0xc0, /* 0000001111 */
+
+	/* 114 0x72 'r' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x73, 0x00, /* 0111001100 */
+	0x35, 0x80, /* 0011010110 */
+	0x39, 0x80, /* 0011100110 */
+	0x30, 0x00, /* 0011000000 */
+	0x30, 0x00, /* 0011000000 */
+	0x30, 0x00, /* 0011000000 */
+	0x30, 0x00, /* 0011000000 */
+	0x30, 0x00, /* 0011000000 */
+	0x30, 0x00, /* 0011000000 */
+	0x78, 0x00, /* 0111100000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 115 0x73 's' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x3f, 0x00, /* 0011111100 */
+	0x63, 0x00, /* 0110001100 */
+	0x61, 0x00, /* 0110000100 */
+	0x70, 0x00, /* 0111000000 */
+	0x38, 0x00, /* 0011100000 */
+	0x0e, 0x00, /* 0000111000 */
+	0x07, 0x00, /* 0000011100 */
+	0x43, 0x00, /* 0100001100 */
+	0x63, 0x00, /* 0110001100 */
+	0x7e, 0x00, /* 0111111000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 116 0x74 't' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x08, 0x00, /* 0000100000 */
+	0x08, 0x00, /* 0000100000 */
+	0x18, 0x00, /* 0001100000 */
+	0x7f, 0x80, /* 0111111110 */
+	0x18, 0x00, /* 0001100000 */
+	0x18, 0x00, /* 0001100000 */
+	0x18, 0x00, /* 0001100000 */
+	0x18, 0x00, /* 0001100000 */
+	0x18, 0x00, /* 0001100000 */
+	0x18, 0x00, /* 0001100000 */
+	0x18, 0x00, /* 0001100000 */
+	0x1c, 0x80, /* 0001110010 */
+	0x0f, 0x00, /* 0000111100 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 117 0x75 'u' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0xf7, 0x80, /* 1111011110 */
+	0x63, 0x00, /* 0110001100 */
+	0x63, 0x00, /* 0110001100 */
+	0x63, 0x00, /* 0110001100 */
+	0x63, 0x00, /* 0110001100 */
+	0x63, 0x00, /* 0110001100 */
+	0x63, 0x00, /* 0110001100 */
+	0x63, 0x00, /* 0110001100 */
+	0x77, 0x00, /* 0111011100 */
+	0x3d, 0x80, /* 0011110110 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 118 0x76 'v' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0xf1, 0xc0, /* 1111000111 */
+	0x60, 0xc0, /* 0110000011 */
+	0x31, 0x80, /* 0011000110 */
+	0x31, 0x80, /* 0011000110 */
+	0x19, 0x80, /* 0001100110 */
+	0x1b, 0x00, /* 0001101100 */
+	0x0f, 0x00, /* 0000111100 */
+	0x0f, 0x00, /* 0000111100 */
+	0x06, 0x00, /* 0000011000 */
+	0x06, 0x00, /* 0000011000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 119 0x77 'w' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0xe3, 0xc0, /* 1110001111 */
+	0xc1, 0x80, /* 1100000110 */
+	0xc1, 0x80, /* 1100000110 */
+	0xc1, 0x80, /* 1100000110 */
+	0xc1, 0x80, /* 1100000110 */
+	0x6b, 0x00, /* 0110101100 */
+	0x6b, 0x00, /* 0110101100 */
+	0x7e, 0x00, /* 0111111000 */
+	0x36, 0x00, /* 0011011000 */
+	0x36, 0x00, /* 0011011000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 120 0x78 'x' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0xf7, 0x80, /* 1111011110 */
+	0x63, 0x00, /* 0110001100 */
+	0x36, 0x00, /* 0011011000 */
+	0x36, 0x00, /* 0011011000 */
+	0x1c, 0x00, /* 0001110000 */
+	0x1c, 0x00, /* 0001110000 */
+	0x36, 0x00, /* 0011011000 */
+	0x66, 0x00, /* 0110011000 */
+	0x63, 0x00, /* 0110001100 */
+	0xf7, 0x80, /* 1111011110 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 121 0x79 'y' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0xf3, 0xc0, /* 1111001111 */
+	0x61, 0x80, /* 0110000110 */
+	0x33, 0x00, /* 0011001100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1e, 0x00, /* 0001111000 */
+	0x0e, 0x00, /* 0000111000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x18, 0x00, /* 0001100000 */
+	0x78, 0x00, /* 0111100000 */
+	0x70, 0x00, /* 0111000000 */
+
+	/* 122 0x7a 'z' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x7f, 0x80, /* 0111111110 */
+	0x61, 0x80, /* 0110000110 */
+	0x43, 0x00, /* 0100001100 */
+	0x06, 0x00, /* 0000011000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x18, 0x00, /* 0001100000 */
+	0x30, 0x00, /* 0011000000 */
+	0x60, 0x80, /* 0110000010 */
+	0x61, 0x80, /* 0110000110 */
+	0x7f, 0x80, /* 0111111110 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 123 0x7b '{' */
+	0x07, 0x00, /* 0000011100 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x18, 0x00, /* 0001100000 */
+	0x70, 0x00, /* 0111000000 */
+	0x18, 0x00, /* 0001100000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x07, 0x00, /* 0000011100 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 124 0x7c '|' */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 125 0x7d '}' */
+	0x38, 0x00, /* 0011100000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x06, 0x00, /* 0000011000 */
+	0x03, 0x80, /* 0000001110 */
+	0x06, 0x00, /* 0000011000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x38, 0x00, /* 0011100000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 126 0x7e '~' */
+	0x00, 0x00, /* 0000000000 */
+	0x18, 0x80, /* 0001100010 */
+	0x3d, 0x80, /* 0011110110 */
+	0x6f, 0x00, /* 0110111100 */
+	0x46, 0x00, /* 0100011000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 127 0x7f '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x12, 0x00, /* 0001001000 */
+	0x21, 0x00, /* 0010000100 */
+	0x40, 0x80, /* 0100000010 */
+	0x40, 0x80, /* 0100000010 */
+	0x40, 0x80, /* 0100000010 */
+	0x7f, 0x80, /* 0111111110 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 128 0x80 '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x1f, 0x00, /* 0001111100 */
+	0x21, 0x80, /* 0010000110 */
+	0x40, 0x80, /* 0100000010 */
+	0x40, 0x00, /* 0100000000 */
+	0x40, 0x00, /* 0100000000 */
+	0x40, 0x00, /* 0100000000 */
+	0x40, 0x00, /* 0100000000 */
+	0x40, 0x00, /* 0100000000 */
+	0x40, 0x00, /* 0100000000 */
+	0x60, 0x80, /* 0110000010 */
+	0x31, 0x00, /* 0011000100 */
+	0x1e, 0x00, /* 0001111000 */
+	0x08, 0x00, /* 0000100000 */
+	0x04, 0x00, /* 0000010000 */
+	0x02, 0x00, /* 0000001000 */
+	0x02, 0x00, /* 0000001000 */
+	0x1c, 0x00, /* 0001110000 */
+
+	/* 129 0x81 '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x7b, 0x80, /* 0111101110 */
+	0x31, 0x00, /* 0011000100 */
+	0x31, 0x00, /* 0011000100 */
+	0x31, 0x00, /* 0011000100 */
+	0x31, 0x00, /* 0011000100 */
+	0x31, 0x00, /* 0011000100 */
+	0x31, 0x00, /* 0011000100 */
+	0x31, 0x00, /* 0011000100 */
+	0x3b, 0x00, /* 0011101100 */
+	0x1c, 0x80, /* 0001110010 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 130 0x82 '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x01, 0x00, /* 0000000100 */
+	0x02, 0x00, /* 0000001000 */
+	0x04, 0x00, /* 0000010000 */
+	0x00, 0x00, /* 0000000000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x33, 0x00, /* 0011001100 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x7f, 0x80, /* 0111111110 */
+	0x60, 0x00, /* 0110000000 */
+	0x60, 0x00, /* 0110000000 */
+	0x30, 0x00, /* 0011000000 */
+	0x19, 0x80, /* 0001100110 */
+	0x0e, 0x00, /* 0000111000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 131 0x83 '.' */
+	0x04, 0x00, /* 0000010000 */
+	0x0e, 0x00, /* 0000111000 */
+	0x1b, 0x00, /* 0001101100 */
+	0x31, 0x80, /* 0011000110 */
+	0x00, 0x00, /* 0000000000 */
+	0x1f, 0x00, /* 0001111100 */
+	0x31, 0x80, /* 0011000110 */
+	0x21, 0x80, /* 0010000110 */
+	0x07, 0x80, /* 0000011110 */
+	0x39, 0x80, /* 0011100110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x73, 0x80, /* 0111001110 */
+	0x3d, 0xc0, /* 0011110111 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 132 0x84 '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x1f, 0x00, /* 0001111100 */
+	0x31, 0x80, /* 0011000110 */
+	0x21, 0x80, /* 0010000110 */
+	0x07, 0x80, /* 0000011110 */
+	0x39, 0x80, /* 0011100110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x73, 0x80, /* 0111001110 */
+	0x3d, 0xc0, /* 0011110111 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 133 0x85 '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x18, 0x00, /* 0001100000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x06, 0x00, /* 0000011000 */
+	0x00, 0x00, /* 0000000000 */
+	0x1f, 0x00, /* 0001111100 */
+	0x31, 0x80, /* 0011000110 */
+	0x21, 0x80, /* 0010000110 */
+	0x07, 0x80, /* 0000011110 */
+	0x39, 0x80, /* 0011100110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x73, 0x80, /* 0111001110 */
+	0x3d, 0xc0, /* 0011110111 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 134 0x86 '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x0e, 0x00, /* 0000111000 */
+	0x1b, 0x00, /* 0001101100 */
+	0x0e, 0x00, /* 0000111000 */
+	0x00, 0x00, /* 0000000000 */
+	0x1f, 0x00, /* 0001111100 */
+	0x31, 0x80, /* 0011000110 */
+	0x21, 0x80, /* 0010000110 */
+	0x07, 0x80, /* 0000011110 */
+	0x39, 0x80, /* 0011100110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x73, 0x80, /* 0111001110 */
+	0x3d, 0xc0, /* 0011110111 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 135 0x87 '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x1f, 0x00, /* 0001111100 */
+	0x31, 0x80, /* 0011000110 */
+	0x20, 0x80, /* 0010000010 */
+	0x60, 0x00, /* 0110000000 */
+	0x60, 0x00, /* 0110000000 */
+	0x60, 0x00, /* 0110000000 */
+	0x70, 0x80, /* 0111000010 */
+	0x30, 0x80, /* 0011000010 */
+	0x1f, 0x00, /* 0001111100 */
+	0x04, 0x00, /* 0000010000 */
+	0x02, 0x00, /* 0000001000 */
+	0x01, 0x00, /* 0000000100 */
+	0x0e, 0x00, /* 0000111000 */
+
+	/* 136 0x88 '.' */
+	0x04, 0x00, /* 0000010000 */
+	0x0e, 0x00, /* 0000111000 */
+	0x1b, 0x00, /* 0001101100 */
+	0x31, 0x80, /* 0011000110 */
+	0x00, 0x00, /* 0000000000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x33, 0x00, /* 0011001100 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x7f, 0x80, /* 0111111110 */
+	0x60, 0x00, /* 0110000000 */
+	0x60, 0x00, /* 0110000000 */
+	0x30, 0x00, /* 0011000000 */
+	0x19, 0x80, /* 0001100110 */
+	0x0e, 0x00, /* 0000111000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 137 0x89 '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x36, 0x00, /* 0011011000 */
+	0x36, 0x00, /* 0011011000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x33, 0x00, /* 0011001100 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x7f, 0x80, /* 0111111110 */
+	0x60, 0x00, /* 0110000000 */
+	0x60, 0x00, /* 0110000000 */
+	0x30, 0x00, /* 0011000000 */
+	0x19, 0x80, /* 0001100110 */
+	0x0e, 0x00, /* 0000111000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 138 0x8a '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x30, 0x00, /* 0011000000 */
+	0x18, 0x00, /* 0001100000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x00, 0x00, /* 0000000000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x33, 0x00, /* 0011001100 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x7f, 0x80, /* 0111111110 */
+	0x60, 0x00, /* 0110000000 */
+	0x60, 0x00, /* 0110000000 */
+	0x30, 0x00, /* 0011000000 */
+	0x19, 0x80, /* 0001100110 */
+	0x0e, 0x00, /* 0000111000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 139 0x8b '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x36, 0x00, /* 0011011000 */
+	0x36, 0x00, /* 0011011000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x3c, 0x00, /* 0011110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x3f, 0x00, /* 0011111100 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 140 0x8c '.' */
+	0x08, 0x00, /* 0000100000 */
+	0x1c, 0x00, /* 0001110000 */
+	0x36, 0x00, /* 0011011000 */
+	0x63, 0x00, /* 0110001100 */
+	0x00, 0x00, /* 0000000000 */
+	0x3c, 0x00, /* 0011110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x3f, 0x00, /* 0011111100 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 141 0x8d '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x30, 0x00, /* 0011000000 */
+	0x18, 0x00, /* 0001100000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x00, 0x00, /* 0000000000 */
+	0x3c, 0x00, /* 0011110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x3f, 0x00, /* 0011111100 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 142 0x8e '.' */
+	0x31, 0x80, /* 0011000110 */
+	0x31, 0x80, /* 0011000110 */
+	0x04, 0x00, /* 0000010000 */
+	0x04, 0x00, /* 0000010000 */
+	0x0e, 0x00, /* 0000111000 */
+	0x0e, 0x00, /* 0000111000 */
+	0x0e, 0x00, /* 0000111000 */
+	0x19, 0x00, /* 0001100100 */
+	0x19, 0x00, /* 0001100100 */
+	0x3f, 0x00, /* 0011111100 */
+	0x31, 0x00, /* 0011000100 */
+	0x31, 0x00, /* 0011000100 */
+	0x60, 0x80, /* 0110000010 */
+	0x60, 0x80, /* 0110000010 */
+	0xf3, 0xc0, /* 1111001111 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 143 0x8f '.' */
+	0x04, 0x00, /* 0000010000 */
+	0x0a, 0x00, /* 0000101000 */
+	0x0a, 0x00, /* 0000101000 */
+	0x04, 0x00, /* 0000010000 */
+	0x0e, 0x00, /* 0000111000 */
+	0x0e, 0x00, /* 0000111000 */
+	0x0e, 0x00, /* 0000111000 */
+	0x19, 0x00, /* 0001100100 */
+	0x19, 0x00, /* 0001100100 */
+	0x3f, 0x00, /* 0011111100 */
+	0x31, 0x00, /* 0011000100 */
+	0x31, 0x00, /* 0011000100 */
+	0x60, 0x80, /* 0110000010 */
+	0x60, 0x80, /* 0110000010 */
+	0xf3, 0xc0, /* 1111001111 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 144 0x90 '.' */
+	0x03, 0x00, /* 0000001100 */
+	0x06, 0x00, /* 0000011000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x7f, 0x80, /* 0111111110 */
+	0x30, 0x80, /* 0011000010 */
+	0x30, 0x80, /* 0011000010 */
+	0x30, 0x00, /* 0011000000 */
+	0x31, 0x00, /* 0011000100 */
+	0x3f, 0x00, /* 0011111100 */
+	0x31, 0x00, /* 0011000100 */
+	0x30, 0x00, /* 0011000000 */
+	0x30, 0x00, /* 0011000000 */
+	0x30, 0x80, /* 0011000010 */
+	0x30, 0x80, /* 0011000010 */
+	0x7f, 0x80, /* 0111111110 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 145 0x91 '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x3b, 0x80, /* 0011101110 */
+	0x6c, 0xc0, /* 0110110011 */
+	0x4c, 0xc0, /* 0100110011 */
+	0x0c, 0xc0, /* 0000110011 */
+	0x3f, 0xc0, /* 0011111111 */
+	0x6c, 0x00, /* 0110110000 */
+	0xcc, 0x00, /* 1100110000 */
+	0xcc, 0x00, /* 1100110000 */
+	0xee, 0xc0, /* 1110111011 */
+	0x7b, 0x80, /* 0111101110 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 146 0x92 '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x07, 0xc0, /* 0000011111 */
+	0x0e, 0x40, /* 0000111001 */
+	0x0e, 0x40, /* 0000111001 */
+	0x0e, 0x00, /* 0000111000 */
+	0x16, 0x00, /* 0001011000 */
+	0x16, 0x80, /* 0001011010 */
+	0x17, 0x80, /* 0001011110 */
+	0x16, 0x80, /* 0001011010 */
+	0x3e, 0x00, /* 0011111000 */
+	0x26, 0x00, /* 0010011000 */
+	0x26, 0x00, /* 0010011000 */
+	0x46, 0x40, /* 0100011001 */
+	0x46, 0x40, /* 0100011001 */
+	0xef, 0xc0, /* 1110111111 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 147 0x93 '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x08, 0x00, /* 0000100000 */
+	0x1c, 0x00, /* 0001110000 */
+	0x36, 0x00, /* 0011011000 */
+	0x00, 0x00, /* 0000000000 */
+	0x3c, 0x00, /* 0011110000 */
+	0x66, 0x00, /* 0110011000 */
+	0xc3, 0x00, /* 1100001100 */
+	0xc1, 0x80, /* 1100000110 */
+	0xc1, 0x80, /* 1100000110 */
+	0xc1, 0x80, /* 1100000110 */
+	0xc1, 0x80, /* 1100000110 */
+	0xe1, 0x80, /* 1110000110 */
+	0x73, 0x00, /* 0111001100 */
+	0x3c, 0x00, /* 0011110000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 148 0x94 '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x33, 0x00, /* 0011001100 */
+	0x33, 0x00, /* 0011001100 */
+	0x00, 0x00, /* 0000000000 */
+	0x3c, 0x00, /* 0011110000 */
+	0x66, 0x00, /* 0110011000 */
+	0xc3, 0x00, /* 1100001100 */
+	0xc1, 0x80, /* 1100000110 */
+	0xc1, 0x80, /* 1100000110 */
+	0xc1, 0x80, /* 1100000110 */
+	0xc1, 0x80, /* 1100000110 */
+	0xe1, 0x80, /* 1110000110 */
+	0x73, 0x00, /* 0111001100 */
+	0x3c, 0x00, /* 0011110000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 149 0x95 '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x18, 0x00, /* 0001100000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x06, 0x00, /* 0000011000 */
+	0x00, 0x00, /* 0000000000 */
+	0x3c, 0x00, /* 0011110000 */
+	0x66, 0x00, /* 0110011000 */
+	0xc3, 0x00, /* 1100001100 */
+	0xc1, 0x80, /* 1100000110 */
+	0xc1, 0x80, /* 1100000110 */
+	0xc1, 0x80, /* 1100000110 */
+	0xc1, 0x80, /* 1100000110 */
+	0xe1, 0x80, /* 1110000110 */
+	0x73, 0x00, /* 0111001100 */
+	0x3c, 0x00, /* 0011110000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 150 0x96 '.' */
+	0x08, 0x00, /* 0000100000 */
+	0x1c, 0x00, /* 0001110000 */
+	0x36, 0x00, /* 0011011000 */
+	0x63, 0x00, /* 0110001100 */
+	0x00, 0x00, /* 0000000000 */
+	0xf7, 0x80, /* 1111011110 */
+	0x63, 0x00, /* 0110001100 */
+	0x63, 0x00, /* 0110001100 */
+	0x63, 0x00, /* 0110001100 */
+	0x63, 0x00, /* 0110001100 */
+	0x63, 0x00, /* 0110001100 */
+	0x63, 0x00, /* 0110001100 */
+	0x63, 0x00, /* 0110001100 */
+	0x77, 0x00, /* 0111011100 */
+	0x3d, 0x80, /* 0011110110 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 151 0x97 '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x60, 0x00, /* 0110000000 */
+	0x30, 0x00, /* 0011000000 */
+	0x18, 0x00, /* 0001100000 */
+	0x00, 0x00, /* 0000000000 */
+	0xf7, 0x80, /* 1111011110 */
+	0x63, 0x00, /* 0110001100 */
+	0x63, 0x00, /* 0110001100 */
+	0x63, 0x00, /* 0110001100 */
+	0x63, 0x00, /* 0110001100 */
+	0x63, 0x00, /* 0110001100 */
+	0x63, 0x00, /* 0110001100 */
+	0x63, 0x00, /* 0110001100 */
+	0x77, 0x00, /* 0111011100 */
+	0x3d, 0x80, /* 0011110110 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 152 0x98 '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x33, 0x00, /* 0011001100 */
+	0x33, 0x00, /* 0011001100 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0xf3, 0xc0, /* 1111001111 */
+	0x61, 0x80, /* 0110000110 */
+	0x33, 0x00, /* 0011001100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1e, 0x00, /* 0001111000 */
+	0x0e, 0x00, /* 0000111000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x18, 0x00, /* 0001100000 */
+	0x78, 0x00, /* 0111100000 */
+	0x70, 0x00, /* 0111000000 */
+
+	/* 153 0x99 '.' */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x0c, 0x00, /* 0000110000 */
+	0x17, 0x00, /* 0001011100 */
+	0x23, 0x00, /* 0010001100 */
+	0x21, 0x80, /* 0010000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x21, 0x00, /* 0010000100 */
+	0x31, 0x00, /* 0011000100 */
+	0x1a, 0x00, /* 0001101000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 154 0x9a '.' */
+	0x33, 0x00, /* 0011001100 */
+	0x33, 0x00, /* 0011001100 */
+	0x00, 0x00, /* 0000000000 */
+	0xf1, 0xc0, /* 1111000111 */
+	0x60, 0x80, /* 0110000010 */
+	0x60, 0x80, /* 0110000010 */
+	0x60, 0x80, /* 0110000010 */
+	0x60, 0x80, /* 0110000010 */
+	0x60, 0x80, /* 0110000010 */
+	0x60, 0x80, /* 0110000010 */
+	0x60, 0x80, /* 0110000010 */
+	0x60, 0x80, /* 0110000010 */
+	0x71, 0x00, /* 0111000100 */
+	0x3f, 0x00, /* 0011111100 */
+	0x1e, 0x00, /* 0001111000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 155 0x9b '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x06, 0x00, /* 0000011000 */
+	0x06, 0x00, /* 0000011000 */
+	0x1f, 0x80, /* 0001111110 */
+	0x36, 0x80, /* 0011011010 */
+	0x26, 0x00, /* 0010011000 */
+	0x66, 0x00, /* 0110011000 */
+	0x66, 0x00, /* 0110011000 */
+	0x66, 0x00, /* 0110011000 */
+	0x66, 0x00, /* 0110011000 */
+	0x76, 0x00, /* 0111011000 */
+	0x36, 0x80, /* 0011011010 */
+	0x1f, 0x80, /* 0001111110 */
+	0x06, 0x00, /* 0000011000 */
+	0x06, 0x00, /* 0000011000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 156 0x9c '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x1e, 0x00, /* 0001111000 */
+	0x3b, 0x00, /* 0011101100 */
+	0x33, 0x00, /* 0011001100 */
+	0x30, 0x00, /* 0011000000 */
+	0x30, 0x00, /* 0011000000 */
+	0x30, 0x00, /* 0011000000 */
+	0x7e, 0x00, /* 0111111000 */
+	0x7e, 0x00, /* 0111111000 */
+	0x30, 0x00, /* 0011000000 */
+	0x30, 0x00, /* 0011000000 */
+	0x30, 0x00, /* 0011000000 */
+	0x30, 0x00, /* 0011000000 */
+	0x7c, 0x80, /* 0111110010 */
+	0x7f, 0x80, /* 0111111110 */
+	0x43, 0x00, /* 0100001100 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 157 0x9d '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x40, 0x80, /* 0100000010 */
+	0x40, 0x80, /* 0100000010 */
+	0x21, 0x00, /* 0010000100 */
+	0x33, 0x00, /* 0011001100 */
+	0x33, 0x00, /* 0011001100 */
+	0x1e, 0x00, /* 0001111000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x3f, 0x00, /* 0011111100 */
+	0x0c, 0x00, /* 0000110000 */
+	0x3f, 0x00, /* 0011111100 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 158 0x9e '.' */
+	0x00, 0x00, /* 0000000000 */
+	0xbf, 0x00, /* 1011111100 */
+	0x40, 0x80, /* 0100000010 */
+	0x40, 0x80, /* 0100000010 */
+	0x7f, 0x00, /* 0111111100 */
+	0x40, 0x00, /* 0100000000 */
+	0x48, 0x00, /* 0100100000 */
+	0x48, 0x00, /* 0100100000 */
+	0x5e, 0x00, /* 0101111000 */
+	0x48, 0x00, /* 0100100000 */
+	0x48, 0x00, /* 0100100000 */
+	0x48, 0x00, /* 0100100000 */
+	0x48, 0x80, /* 0100100010 */
+	0x47, 0x00, /* 0100011100 */
+	0xe0, 0x00, /* 1110000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 159 0x9f '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x03, 0x00, /* 0000001100 */
+	0x04, 0x80, /* 0000010010 */
+	0x08, 0x00, /* 0000100000 */
+	0x08, 0x00, /* 0000100000 */
+	0x08, 0x00, /* 0000100000 */
+	0x08, 0x00, /* 0000100000 */
+	0x09, 0x00, /* 0000100100 */
+	0x3e, 0x00, /* 0011111000 */
+	0x48, 0x00, /* 0100100000 */
+	0x08, 0x00, /* 0000100000 */
+	0x08, 0x00, /* 0000100000 */
+	0x08, 0x00, /* 0000100000 */
+	0x08, 0x00, /* 0000100000 */
+	0x08, 0x00, /* 0000100000 */
+	0x90, 0x00, /* 1001000000 */
+	0x60, 0x00, /* 0110000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 160 0xa0 '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x03, 0x00, /* 0000001100 */
+	0x06, 0x00, /* 0000011000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x00, 0x00, /* 0000000000 */
+	0x1f, 0x00, /* 0001111100 */
+	0x31, 0x80, /* 0011000110 */
+	0x21, 0x80, /* 0010000110 */
+	0x07, 0x80, /* 0000011110 */
+	0x39, 0x80, /* 0011100110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x73, 0x80, /* 0111001110 */
+	0x3d, 0xc0, /* 0011110111 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 161 0xa1 '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x03, 0x00, /* 0000001100 */
+	0x06, 0x00, /* 0000011000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x00, 0x00, /* 0000000000 */
+	0x3c, 0x00, /* 0011110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x3f, 0x00, /* 0011111100 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 162 0xa2 '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x06, 0x00, /* 0000011000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x18, 0x00, /* 0001100000 */
+	0x00, 0x00, /* 0000000000 */
+	0x3c, 0x00, /* 0011110000 */
+	0x66, 0x00, /* 0110011000 */
+	0xc3, 0x00, /* 1100001100 */
+	0xc1, 0x80, /* 1100000110 */
+	0xc1, 0x80, /* 1100000110 */
+	0xc1, 0x80, /* 1100000110 */
+	0xc1, 0x80, /* 1100000110 */
+	0xe1, 0x80, /* 1110000110 */
+	0x73, 0x00, /* 0111001100 */
+	0x3c, 0x00, /* 0011110000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 163 0xa3 '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x06, 0x00, /* 0000011000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x18, 0x00, /* 0001100000 */
+	0x00, 0x00, /* 0000000000 */
+	0xf7, 0x80, /* 1111011110 */
+	0x63, 0x00, /* 0110001100 */
+	0x63, 0x00, /* 0110001100 */
+	0x63, 0x00, /* 0110001100 */
+	0x63, 0x00, /* 0110001100 */
+	0x63, 0x00, /* 0110001100 */
+	0x63, 0x00, /* 0110001100 */
+	0x63, 0x00, /* 0110001100 */
+	0x77, 0x00, /* 0111011100 */
+	0x3d, 0x80, /* 0011110110 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 164 0xa4 '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x38, 0x80, /* 0011100010 */
+	0x7f, 0x80, /* 0111111110 */
+	0x47, 0x00, /* 0100011100 */
+	0x00, 0x00, /* 0000000000 */
+	0x6f, 0x00, /* 0110111100 */
+	0x7b, 0x80, /* 0111101110 */
+	0x31, 0x80, /* 0011000110 */
+	0x31, 0x80, /* 0011000110 */
+	0x31, 0x80, /* 0011000110 */
+	0x31, 0x80, /* 0011000110 */
+	0x31, 0x80, /* 0011000110 */
+	0x31, 0x80, /* 0011000110 */
+	0x31, 0x80, /* 0011000110 */
+	0x7b, 0xc0, /* 0111101111 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 165 0xa5 '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x38, 0x80, /* 0011100010 */
+	0x7f, 0x80, /* 0111111110 */
+	0x47, 0x00, /* 0100011100 */
+	0x00, 0x00, /* 0000000000 */
+	0xe3, 0xc0, /* 1110001111 */
+	0x71, 0x80, /* 0111000110 */
+	0x79, 0x80, /* 0111100110 */
+	0x79, 0x80, /* 0111100110 */
+	0x6d, 0x80, /* 0110110110 */
+	0x6d, 0x80, /* 0110110110 */
+	0x67, 0x80, /* 0110011110 */
+	0x63, 0x80, /* 0110001110 */
+	0x61, 0x80, /* 0110000110 */
+	0xf0, 0xc0, /* 1111000011 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 166 0xa6 '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x3e, 0x00, /* 0011111000 */
+	0x63, 0x00, /* 0110001100 */
+	0x03, 0x00, /* 0000001100 */
+	0x0f, 0x00, /* 0000111100 */
+	0x33, 0x00, /* 0011001100 */
+	0x63, 0x00, /* 0110001100 */
+	0x63, 0x00, /* 0110001100 */
+	0x67, 0x00, /* 0110011100 */
+	0x3b, 0x80, /* 0011101110 */
+	0x00, 0x00, /* 0000000000 */
+	0x7f, 0x80, /* 0111111110 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 167 0xa7 '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x0e, 0x00, /* 0000111000 */
+	0x33, 0x00, /* 0011001100 */
+	0x21, 0x80, /* 0010000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x00, /* 0110000100 */
+	0x33, 0x00, /* 0011001100 */
+	0x1c, 0x00, /* 0001110000 */
+	0x00, 0x00, /* 0000000000 */
+	0x7f, 0x80, /* 0111111110 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 168 0xa8 '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x06, 0x00, /* 0000011000 */
+	0x06, 0x00, /* 0000011000 */
+	0x00, 0x00, /* 0000000000 */
+	0x06, 0x00, /* 0000011000 */
+	0x06, 0x00, /* 0000011000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x18, 0x00, /* 0001100000 */
+	0x30, 0x00, /* 0011000000 */
+	0x60, 0x00, /* 0110000000 */
+	0x60, 0x00, /* 0110000000 */
+	0x60, 0x80, /* 0110000010 */
+	0x73, 0x80, /* 0111001110 */
+	0x3f, 0x00, /* 0011111100 */
+	0x1e, 0x00, /* 0001111000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 169 0xa9 '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x7f, 0x80, /* 0111111110 */
+	0x7f, 0x80, /* 0111111110 */
+	0x60, 0x00, /* 0110000000 */
+	0x60, 0x00, /* 0110000000 */
+	0x60, 0x00, /* 0110000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 170 0xaa '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x7f, 0x80, /* 0111111110 */
+	0x7f, 0x80, /* 0111111110 */
+	0x01, 0x80, /* 0000000110 */
+	0x01, 0x80, /* 0000000110 */
+	0x01, 0x80, /* 0000000110 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 171 0xab '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x20, 0x00, /* 0010000000 */
+	0x60, 0x00, /* 0110000000 */
+	0x20, 0x00, /* 0010000000 */
+	0x20, 0x80, /* 0010000010 */
+	0x21, 0x00, /* 0010000100 */
+	0x22, 0x00, /* 0010001000 */
+	0x74, 0x00, /* 0111010000 */
+	0x08, 0x00, /* 0000100000 */
+	0x17, 0x00, /* 0001011100 */
+	0x28, 0x80, /* 0010100010 */
+	0x43, 0x00, /* 0100001100 */
+	0x04, 0x00, /* 0000010000 */
+	0x08, 0x00, /* 0000100000 */
+	0x0f, 0x80, /* 0000111110 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 172 0xac '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x20, 0x00, /* 0010000000 */
+	0x60, 0x00, /* 0110000000 */
+	0x20, 0x00, /* 0010000000 */
+	0x20, 0x80, /* 0010000010 */
+	0x21, 0x00, /* 0010000100 */
+	0x22, 0x00, /* 0010001000 */
+	0x74, 0x00, /* 0111010000 */
+	0x09, 0x00, /* 0000100100 */
+	0x13, 0x00, /* 0001001100 */
+	0x25, 0x00, /* 0010010100 */
+	0x49, 0x00, /* 0100100100 */
+	0x1f, 0x80, /* 0001111110 */
+	0x01, 0x00, /* 0000000100 */
+	0x01, 0x00, /* 0000000100 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 173 0xad '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x00, 0x00, /* 0000000000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 174 0xae '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x0d, 0x80, /* 0000110110 */
+	0x1b, 0x00, /* 0001101100 */
+	0x36, 0x00, /* 0011011000 */
+	0x6c, 0x00, /* 0110110000 */
+	0xd8, 0x00, /* 1101100000 */
+	0x6c, 0x00, /* 0110110000 */
+	0x36, 0x00, /* 0011011000 */
+	0x1b, 0x00, /* 0001101100 */
+	0x0d, 0x80, /* 0000110110 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 175 0xaf '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x6c, 0x00, /* 0110110000 */
+	0x36, 0x00, /* 0011011000 */
+	0x1b, 0x00, /* 0001101100 */
+	0x0d, 0x80, /* 0000110110 */
+	0x06, 0xc0, /* 0000011011 */
+	0x0d, 0x80, /* 0000110110 */
+	0x1b, 0x00, /* 0001101100 */
+	0x36, 0x00, /* 0011011000 */
+	0x6c, 0x00, /* 0110110000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 176 0xb0 '.' */
+	0xc3, 0x00, /* 1100001100 */
+	0x41, 0x00, /* 0100000100 */
+	0x18, 0x40, /* 0001100001 */
+	0x10, 0x40, /* 0001000001 */
+	0xc3, 0x00, /* 1100001100 */
+	0x41, 0x00, /* 0100000100 */
+	0x18, 0x40, /* 0001100001 */
+	0x10, 0x40, /* 0001000001 */
+	0xc3, 0x00, /* 1100001100 */
+	0x41, 0x00, /* 0100000100 */
+	0x18, 0x40, /* 0001100001 */
+	0x10, 0x40, /* 0001000001 */
+	0xc3, 0x00, /* 1100001100 */
+	0x41, 0x00, /* 0100000100 */
+	0x18, 0x40, /* 0001100001 */
+	0x10, 0x40, /* 0001000001 */
+	0xc3, 0x00, /* 1100001100 */
+	0x41, 0x00, /* 0100000100 */
+
+	/* 177 0xb1 '.' */
+	0x11, 0x00, /* 0001000100 */
+	0xbb, 0x80, /* 1011101110 */
+	0x11, 0x00, /* 0001000100 */
+	0x44, 0x40, /* 0100010001 */
+	0xee, 0xc0, /* 1110111011 */
+	0x44, 0x40, /* 0100010001 */
+	0x11, 0x00, /* 0001000100 */
+	0xbb, 0x80, /* 1011101110 */
+	0x11, 0x00, /* 0001000100 */
+	0x44, 0x40, /* 0100010001 */
+	0xee, 0xc0, /* 1110111011 */
+	0x44, 0x40, /* 0100010001 */
+	0x11, 0x00, /* 0001000100 */
+	0xbb, 0x80, /* 1011101110 */
+	0x11, 0x00, /* 0001000100 */
+	0x44, 0x40, /* 0100010001 */
+	0xee, 0xc0, /* 1110111011 */
+	0x44, 0x40, /* 0100010001 */
+
+	/* 178 0xb2 '.' */
+	0x3c, 0xc0, /* 0011110011 */
+	0xbe, 0xc0, /* 1011111011 */
+	0xe7, 0x80, /* 1110011110 */
+	0xef, 0x80, /* 1110111110 */
+	0x3c, 0xc0, /* 0011110011 */
+	0xbe, 0xc0, /* 1011111011 */
+	0xe7, 0x80, /* 1110011110 */
+	0xef, 0x80, /* 1110111110 */
+	0x3c, 0xc0, /* 0011110011 */
+	0xbe, 0xc0, /* 1011111011 */
+	0xe7, 0x80, /* 1110011110 */
+	0xef, 0x80, /* 1110111110 */
+	0x3c, 0xc0, /* 0011110011 */
+	0xbe, 0xc0, /* 1011111011 */
+	0xe7, 0x80, /* 1110011110 */
+	0xef, 0x80, /* 1110111110 */
+	0x3c, 0xc0, /* 0011110011 */
+	0xbe, 0xc0, /* 1011111011 */
+
+	/* 179 0xb3 '.' */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+
+	/* 180 0xb4 '.' */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0xfc, 0x00, /* 1111110000 */
+	0xfc, 0x00, /* 1111110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+
+	/* 181 0xb5 '.' */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0xfc, 0x00, /* 1111110000 */
+	0xfc, 0x00, /* 1111110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0xfc, 0x00, /* 1111110000 */
+	0xfc, 0x00, /* 1111110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+
+	/* 182 0xb6 '.' */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0xfb, 0x00, /* 1111101100 */
+	0xfb, 0x00, /* 1111101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+
+	/* 183 0xb7 '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0xff, 0x00, /* 1111111100 */
+	0xff, 0x00, /* 1111111100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+
+	/* 184 0xb8 '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0xfc, 0x00, /* 1111110000 */
+	0xfc, 0x00, /* 1111110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0xfc, 0x00, /* 1111110000 */
+	0xfc, 0x00, /* 1111110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+
+	/* 185 0xb9 '.' */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0xfb, 0x00, /* 1111101100 */
+	0xfb, 0x00, /* 1111101100 */
+	0x03, 0x00, /* 0000001100 */
+	0xfb, 0x00, /* 1111101100 */
+	0xfb, 0x00, /* 1111101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+
+	/* 186 0xba '.' */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+
+	/* 187 0xbb '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0xff, 0x00, /* 1111111100 */
+	0xff, 0x00, /* 1111111100 */
+	0x03, 0x00, /* 0000001100 */
+	0xfb, 0x00, /* 1111101100 */
+	0xfb, 0x00, /* 1111101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+
+	/* 188 0xbc '.' */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0xfb, 0x00, /* 1111101100 */
+	0xfb, 0x00, /* 1111101100 */
+	0x03, 0x00, /* 0000001100 */
+	0xff, 0x00, /* 1111111100 */
+	0xff, 0x00, /* 1111111100 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 189 0xbd '.' */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0xff, 0x00, /* 1111111100 */
+	0xff, 0x00, /* 1111111100 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 190 0xbe '.' */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0xfc, 0x00, /* 1111110000 */
+	0xfc, 0x00, /* 1111110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0xfc, 0x00, /* 1111110000 */
+	0xfc, 0x00, /* 1111110000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 191 0xbf '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0xfc, 0x00, /* 1111110000 */
+	0xfc, 0x00, /* 1111110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+
+	/* 192 0xc0 '.' */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0f, 0xc0, /* 0000111111 */
+	0x0f, 0xc0, /* 0000111111 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 193 0xc1 '.' */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0xff, 0xc0, /* 1111111111 */
+	0xff, 0xc0, /* 1111111111 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 194 0xc2 '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0xff, 0xc0, /* 1111111111 */
+	0xff, 0xc0, /* 1111111111 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+
+	/* 195 0xc3 '.' */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0f, 0xc0, /* 0000111111 */
+	0x0f, 0xc0, /* 0000111111 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+
+	/* 196 0xc4 '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0xff, 0xc0, /* 1111111111 */
+	0xff, 0xc0, /* 1111111111 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 197 0xc5 '.' */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0xff, 0xc0, /* 1111111111 */
+	0xff, 0xc0, /* 1111111111 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+
+	/* 198 0xc6 '.' */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0f, 0xc0, /* 0000111111 */
+	0x0f, 0xc0, /* 0000111111 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0f, 0xc0, /* 0000111111 */
+	0x0f, 0xc0, /* 0000111111 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+
+	/* 199 0xc7 '.' */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0xc0, /* 0001101111 */
+	0x1b, 0xc0, /* 0001101111 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+
+	/* 200 0xc8 '.' */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0xc0, /* 0001101111 */
+	0x1b, 0xc0, /* 0001101111 */
+	0x18, 0x00, /* 0001100000 */
+	0x1f, 0xc0, /* 0001111111 */
+	0x1f, 0xc0, /* 0001111111 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 201 0xc9 '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x1f, 0xc0, /* 0001111111 */
+	0x1f, 0xc0, /* 0001111111 */
+	0x18, 0x00, /* 0001100000 */
+	0x1b, 0xc0, /* 0001101111 */
+	0x1b, 0xc0, /* 0001101111 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+
+	/* 202 0xca '.' */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0xfb, 0xc0, /* 1111101111 */
+	0xfb, 0xc0, /* 1111101111 */
+	0x00, 0x00, /* 0000000000 */
+	0xff, 0xc0, /* 1111111111 */
+	0xff, 0xc0, /* 1111111111 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 203 0xcb '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0xff, 0xc0, /* 1111111111 */
+	0xff, 0xc0, /* 1111111111 */
+	0x00, 0x00, /* 0000000000 */
+	0xfb, 0xc0, /* 1111101111 */
+	0xfb, 0xc0, /* 1111101111 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+
+	/* 204 0xcc '.' */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0xc0, /* 0001101111 */
+	0x1b, 0xc0, /* 0001101111 */
+	0x18, 0x00, /* 0001100000 */
+	0x1b, 0xc0, /* 0001101111 */
+	0x1b, 0xc0, /* 0001101111 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+
+	/* 205 0xcd '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0xff, 0xc0, /* 1111111111 */
+	0xff, 0xc0, /* 1111111111 */
+	0x00, 0x00, /* 0000000000 */
+	0xff, 0xc0, /* 1111111111 */
+	0xff, 0xc0, /* 1111111111 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 206 0xce '.' */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0xfb, 0xc0, /* 1111101111 */
+	0xfb, 0xc0, /* 1111101111 */
+	0x00, 0x00, /* 0000000000 */
+	0xfb, 0xc0, /* 1111101111 */
+	0xfb, 0xc0, /* 1111101111 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+
+	/* 207 0xcf '.' */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0xff, 0xc0, /* 1111111111 */
+	0xff, 0xc0, /* 1111111111 */
+	0x00, 0x00, /* 0000000000 */
+	0xff, 0xc0, /* 1111111111 */
+	0xff, 0xc0, /* 1111111111 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 208 0xd0 '.' */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0xff, 0xc0, /* 1111111111 */
+	0xff, 0xc0, /* 1111111111 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 209 0xd1 '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0xff, 0xc0, /* 1111111111 */
+	0xff, 0xc0, /* 1111111111 */
+	0x00, 0x00, /* 0000000000 */
+	0xff, 0xc0, /* 1111111111 */
+	0xff, 0xc0, /* 1111111111 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+
+	/* 210 0xd2 '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0xff, 0xc0, /* 1111111111 */
+	0xff, 0xc0, /* 1111111111 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+
+	/* 211 0xd3 '.' */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1f, 0xc0, /* 0001111111 */
+	0x1f, 0xc0, /* 0001111111 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 212 0xd4 '.' */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0f, 0xc0, /* 0000111111 */
+	0x0f, 0xc0, /* 0000111111 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0f, 0xc0, /* 0000111111 */
+	0x0f, 0xc0, /* 0000111111 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 213 0xd5 '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x0f, 0xc0, /* 0000111111 */
+	0x0f, 0xc0, /* 0000111111 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0f, 0xc0, /* 0000111111 */
+	0x0f, 0xc0, /* 0000111111 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+
+	/* 214 0xd6 '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x1f, 0xc0, /* 0001111111 */
+	0x1f, 0xc0, /* 0001111111 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+
+	/* 215 0xd7 '.' */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0xff, 0xc0, /* 1111111111 */
+	0xff, 0xc0, /* 1111111111 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+	0x1b, 0x00, /* 0001101100 */
+
+	/* 216 0xd8 '.' */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0xff, 0xc0, /* 1111111111 */
+	0xff, 0xc0, /* 1111111111 */
+	0x0c, 0x00, /* 0000110000 */
+	0xff, 0xc0, /* 1111111111 */
+	0xff, 0xc0, /* 1111111111 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+
+	/* 217 0xd9 '.' */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0xfc, 0x00, /* 1111110000 */
+	0xfc, 0x00, /* 1111110000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 218 0xda '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x0f, 0xc0, /* 0000111111 */
+	0x0f, 0xc0, /* 0000111111 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+
+	/* 219 0xdb '.' */
+	0xff, 0xc0, /* 1111111111 */
+	0xff, 0xc0, /* 1111111111 */
+	0xff, 0xc0, /* 1111111111 */
+	0xff, 0xc0, /* 1111111111 */
+	0xff, 0xc0, /* 1111111111 */
+	0xff, 0xc0, /* 1111111111 */
+	0xff, 0xc0, /* 1111111111 */
+	0xff, 0xc0, /* 1111111111 */
+	0xff, 0xc0, /* 1111111111 */
+	0xff, 0xc0, /* 1111111111 */
+	0xff, 0xc0, /* 1111111111 */
+	0xff, 0xc0, /* 1111111111 */
+	0xff, 0xc0, /* 1111111111 */
+	0xff, 0xc0, /* 1111111111 */
+	0xff, 0xc0, /* 1111111111 */
+	0xff, 0xc0, /* 1111111111 */
+	0xff, 0xc0, /* 1111111111 */
+	0xff, 0xc0, /* 1111111111 */
+
+	/* 220 0xdc '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0xff, 0xc0, /* 1111111111 */
+	0xff, 0xc0, /* 1111111111 */
+	0xff, 0xc0, /* 1111111111 */
+	0xff, 0xc0, /* 1111111111 */
+	0xff, 0xc0, /* 1111111111 */
+	0xff, 0xc0, /* 1111111111 */
+	0xff, 0xc0, /* 1111111111 */
+	0xff, 0xc0, /* 1111111111 */
+	0xff, 0xc0, /* 1111111111 */
+	0xff, 0xc0, /* 1111111111 */
+
+	/* 221 0xdd '.' */
+	0xf8, 0x00, /* 1111100000 */
+	0xf8, 0x00, /* 1111100000 */
+	0xf8, 0x00, /* 1111100000 */
+	0xf8, 0x00, /* 1111100000 */
+	0xf8, 0x00, /* 1111100000 */
+	0xf8, 0x00, /* 1111100000 */
+	0xf8, 0x00, /* 1111100000 */
+	0xf8, 0x00, /* 1111100000 */
+	0xf8, 0x00, /* 1111100000 */
+	0xf8, 0x00, /* 1111100000 */
+	0xf8, 0x00, /* 1111100000 */
+	0xf8, 0x00, /* 1111100000 */
+	0xf8, 0x00, /* 1111100000 */
+	0xf8, 0x00, /* 1111100000 */
+	0xf8, 0x00, /* 1111100000 */
+	0xf8, 0x00, /* 1111100000 */
+	0xf8, 0x00, /* 1111100000 */
+	0xf8, 0x00, /* 1111100000 */
+
+	/* 222 0xde '.' */
+	0x07, 0xc0, /* 0000011111 */
+	0x07, 0xc0, /* 0000011111 */
+	0x07, 0xc0, /* 0000011111 */
+	0x07, 0xc0, /* 0000011111 */
+	0x07, 0xc0, /* 0000011111 */
+	0x07, 0xc0, /* 0000011111 */
+	0x07, 0xc0, /* 0000011111 */
+	0x07, 0xc0, /* 0000011111 */
+	0x07, 0xc0, /* 0000011111 */
+	0x07, 0xc0, /* 0000011111 */
+	0x07, 0xc0, /* 0000011111 */
+	0x07, 0xc0, /* 0000011111 */
+	0x07, 0xc0, /* 0000011111 */
+	0x07, 0xc0, /* 0000011111 */
+	0x07, 0xc0, /* 0000011111 */
+	0x07, 0xc0, /* 0000011111 */
+	0x07, 0xc0, /* 0000011111 */
+	0x07, 0xc0, /* 0000011111 */
+
+	/* 223 0xdf '.' */
+	0xff, 0xc0, /* 1111111111 */
+	0xff, 0xc0, /* 1111111111 */
+	0xff, 0xc0, /* 1111111111 */
+	0xff, 0xc0, /* 1111111111 */
+	0xff, 0xc0, /* 1111111111 */
+	0xff, 0xc0, /* 1111111111 */
+	0xff, 0xc0, /* 1111111111 */
+	0xff, 0xc0, /* 1111111111 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 224 0xe0 '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x1c, 0x80, /* 0001110010 */
+	0x35, 0x80, /* 0011010110 */
+	0x63, 0x00, /* 0110001100 */
+	0x63, 0x00, /* 0110001100 */
+	0x63, 0x00, /* 0110001100 */
+	0x63, 0x00, /* 0110001100 */
+	0x63, 0x00, /* 0110001100 */
+	0x63, 0x00, /* 0110001100 */
+	0x37, 0x80, /* 0011011110 */
+	0x1c, 0x80, /* 0001110010 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 225 0xe1 '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x1e, 0x00, /* 0001111000 */
+	0x33, 0x00, /* 0011001100 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x63, 0x00, /* 0110001100 */
+	0x6f, 0x00, /* 0110111100 */
+	0x63, 0x00, /* 0110001100 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x63, 0x00, /* 0110001100 */
+	0x6e, 0x00, /* 0110111000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 226 0xe2 '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x7f, 0x80, /* 0111111110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x60, 0x00, /* 0110000000 */
+	0x60, 0x00, /* 0110000000 */
+	0x60, 0x00, /* 0110000000 */
+	0x60, 0x00, /* 0110000000 */
+	0x60, 0x00, /* 0110000000 */
+	0x60, 0x00, /* 0110000000 */
+	0x60, 0x00, /* 0110000000 */
+	0x60, 0x00, /* 0110000000 */
+	0x60, 0x00, /* 0110000000 */
+	0x60, 0x00, /* 0110000000 */
+	0x60, 0x00, /* 0110000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 227 0xe3 '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x7f, 0x80, /* 0111111110 */
+	0x33, 0x00, /* 0011001100 */
+	0x33, 0x00, /* 0011001100 */
+	0x33, 0x00, /* 0011001100 */
+	0x33, 0x00, /* 0011001100 */
+	0x33, 0x00, /* 0011001100 */
+	0x33, 0x00, /* 0011001100 */
+	0x33, 0x00, /* 0011001100 */
+	0x33, 0x00, /* 0011001100 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 228 0xe4 '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0xff, 0x80, /* 1111111110 */
+	0x60, 0x00, /* 0110000000 */
+	0x30, 0x00, /* 0011000000 */
+	0x30, 0x00, /* 0011000000 */
+	0x18, 0x00, /* 0001100000 */
+	0x18, 0x00, /* 0001100000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x18, 0x00, /* 0001100000 */
+	0x30, 0x00, /* 0011000000 */
+	0x30, 0x80, /* 0011000010 */
+	0x61, 0x80, /* 0110000110 */
+	0xff, 0x80, /* 1111111110 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 229 0xe5 '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x1f, 0xc0, /* 0001111111 */
+	0x36, 0x00, /* 0011011000 */
+	0x63, 0x00, /* 0110001100 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x33, 0x00, /* 0011001100 */
+	0x3e, 0x00, /* 0011111000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 230 0xe6 '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x73, 0x80, /* 0111001110 */
+	0x6d, 0x80, /* 0110110110 */
+	0x60, 0x00, /* 0110000000 */
+	0x60, 0x00, /* 0110000000 */
+	0x60, 0x00, /* 0110000000 */
+	0x60, 0x00, /* 0110000000 */
+	0xc0, 0x00, /* 1100000000 */
+
+	/* 231 0xe7 '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x01, 0x80, /* 0000000110 */
+	0x36, 0x40, /* 0011011001 */
+	0x5e, 0x00, /* 0101111000 */
+	0x8c, 0x00, /* 1000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 232 0xe8 '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x7f, 0x80, /* 0111111110 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x1e, 0x00, /* 0001111000 */
+	0x33, 0x00, /* 0011001100 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x33, 0x00, /* 0011001100 */
+	0x1e, 0x00, /* 0001111000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x7f, 0x80, /* 0111111110 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 233 0xe9 '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x0e, 0x00, /* 0000111000 */
+	0x1f, 0x00, /* 0001111100 */
+	0x31, 0x80, /* 0011000110 */
+	0x31, 0x80, /* 0011000110 */
+	0x60, 0xc0, /* 0110000011 */
+	0x7f, 0xc0, /* 0111111111 */
+	0x7f, 0xc0, /* 0111111111 */
+	0x60, 0xc0, /* 0110000011 */
+	0x31, 0x80, /* 0011000110 */
+	0x31, 0x80, /* 0011000110 */
+	0x1f, 0x00, /* 0001111100 */
+	0x0e, 0x00, /* 0000111000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 234 0xea '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x1e, 0x00, /* 0001111000 */
+	0x33, 0x00, /* 0011001100 */
+	0x61, 0x80, /* 0110000110 */
+	0xc0, 0xc0, /* 1100000011 */
+	0xc0, 0xc0, /* 1100000011 */
+	0xc0, 0xc0, /* 1100000011 */
+	0x61, 0x80, /* 0110000110 */
+	0x33, 0x00, /* 0011001100 */
+	0x33, 0x00, /* 0011001100 */
+	0x33, 0x00, /* 0011001100 */
+	0x33, 0x00, /* 0011001100 */
+	0xf3, 0xc0, /* 1111001111 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 235 0xeb '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x07, 0x00, /* 0000011100 */
+	0x1f, 0x80, /* 0001111110 */
+	0x30, 0xc0, /* 0011000011 */
+	0x30, 0x00, /* 0011000000 */
+	0x18, 0x00, /* 0001100000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x3e, 0x00, /* 0011111000 */
+	0x66, 0x00, /* 0110011000 */
+	0xc3, 0x00, /* 1100001100 */
+	0xc3, 0x00, /* 1100001100 */
+	0xc3, 0x00, /* 1100001100 */
+	0x66, 0x00, /* 0110011000 */
+	0x3c, 0x00, /* 0011110000 */
+	0x18, 0x00, /* 0001100000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 236 0xec '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x33, 0x00, /* 0011001100 */
+	0x6d, 0x80, /* 0110110110 */
+	0xcc, 0xc0, /* 1100110011 */
+	0xcc, 0xc0, /* 1100110011 */
+	0xcc, 0xc0, /* 1100110011 */
+	0xcc, 0xc0, /* 1100110011 */
+	0x6d, 0x80, /* 0110110110 */
+	0x33, 0x00, /* 0011001100 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 237 0xed '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x01, 0x80, /* 0000000110 */
+	0x01, 0x80, /* 0000000110 */
+	0x03, 0x00, /* 0000001100 */
+	0x03, 0x00, /* 0000001100 */
+	0x37, 0x00, /* 0011011100 */
+	0x6d, 0x80, /* 0110110110 */
+	0xcc, 0xc0, /* 1100110011 */
+	0xcc, 0xc0, /* 1100110011 */
+	0xcc, 0xc0, /* 1100110011 */
+	0xcc, 0xc0, /* 1100110011 */
+	0x6d, 0x80, /* 0110110110 */
+	0x3b, 0x00, /* 0011101100 */
+	0x30, 0x00, /* 0011000000 */
+	0x30, 0x00, /* 0011000000 */
+	0x60, 0x00, /* 0110000000 */
+	0x60, 0x00, /* 0110000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 238 0xee '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x03, 0x80, /* 0000001110 */
+	0x0e, 0x00, /* 0000111000 */
+	0x18, 0x00, /* 0001100000 */
+	0x18, 0x00, /* 0001100000 */
+	0x30, 0x00, /* 0011000000 */
+	0x30, 0x00, /* 0011000000 */
+	0x3f, 0x80, /* 0011111110 */
+	0x3f, 0x80, /* 0011111110 */
+	0x30, 0x00, /* 0011000000 */
+	0x30, 0x00, /* 0011000000 */
+	0x18, 0x00, /* 0001100000 */
+	0x18, 0x00, /* 0001100000 */
+	0x0e, 0x00, /* 0000111000 */
+	0x03, 0x80, /* 0000001110 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 239 0xef '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x1e, 0x00, /* 0001111000 */
+	0x33, 0x00, /* 0011001100 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x61, 0x80, /* 0110000110 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 240 0xf0 '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x7f, 0x80, /* 0111111110 */
+	0x7f, 0x80, /* 0111111110 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x7f, 0x80, /* 0111111110 */
+	0x7f, 0x80, /* 0111111110 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x7f, 0x80, /* 0111111110 */
+	0x7f, 0x80, /* 0111111110 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 241 0xf1 '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x7f, 0x80, /* 0111111110 */
+	0x7f, 0x80, /* 0111111110 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x00, 0x00, /* 0000000000 */
+	0x7f, 0x80, /* 0111111110 */
+	0x7f, 0x80, /* 0111111110 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 242 0xf2 '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0xe0, 0x00, /* 1110000000 */
+	0x38, 0x00, /* 0011100000 */
+	0x0e, 0x00, /* 0000111000 */
+	0x03, 0x80, /* 0000001110 */
+	0x0e, 0x00, /* 0000111000 */
+	0x38, 0x00, /* 0011100000 */
+	0xe0, 0x00, /* 1110000000 */
+	0x00, 0x00, /* 0000000000 */
+	0xff, 0x00, /* 1111111100 */
+	0xff, 0x00, /* 1111111100 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 243 0xf3 '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x03, 0x80, /* 0000001110 */
+	0x0e, 0x00, /* 0000111000 */
+	0x38, 0x00, /* 0011100000 */
+	0xe0, 0x00, /* 1110000000 */
+	0x38, 0x00, /* 0011100000 */
+	0x0e, 0x00, /* 0000111000 */
+	0x03, 0x80, /* 0000001110 */
+	0x00, 0x00, /* 0000000000 */
+	0xff, 0x80, /* 1111111110 */
+	0xff, 0x80, /* 1111111110 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 244 0xf4 '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x1e, 0x00, /* 0001111000 */
+	0x33, 0x00, /* 0011001100 */
+	0x33, 0x00, /* 0011001100 */
+	0x30, 0x00, /* 0011000000 */
+	0x30, 0x00, /* 0011000000 */
+	0x30, 0x00, /* 0011000000 */
+	0x30, 0x00, /* 0011000000 */
+	0x30, 0x00, /* 0011000000 */
+	0x30, 0x00, /* 0011000000 */
+	0x30, 0x00, /* 0011000000 */
+	0x30, 0x00, /* 0011000000 */
+	0x30, 0x00, /* 0011000000 */
+	0x30, 0x00, /* 0011000000 */
+	0x30, 0x00, /* 0011000000 */
+	0x30, 0x00, /* 0011000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 245 0xf5 '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x1e, 0x00, /* 0001111000 */
+	0x33, 0x00, /* 0011001100 */
+	0x33, 0x00, /* 0011001100 */
+	0x03, 0x00, /* 0000001100 */
+	0x03, 0x00, /* 0000001100 */
+	0x03, 0x00, /* 0000001100 */
+	0x03, 0x00, /* 0000001100 */
+	0x03, 0x00, /* 0000001100 */
+	0x03, 0x00, /* 0000001100 */
+	0x03, 0x00, /* 0000001100 */
+	0x03, 0x00, /* 0000001100 */
+	0x03, 0x00, /* 0000001100 */
+	0x03, 0x00, /* 0000001100 */
+	0x03, 0x00, /* 0000001100 */
+	0x03, 0x00, /* 0000001100 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 246 0xf6 '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x7f, 0x80, /* 0111111110 */
+	0x7f, 0x80, /* 0111111110 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 247 0xf7 '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x38, 0x00, /* 0011100000 */
+	0x6c, 0x00, /* 0110110000 */
+	0x06, 0xc0, /* 0000011011 */
+	0x03, 0x80, /* 0000001110 */
+	0x38, 0x00, /* 0011100000 */
+	0x6c, 0x00, /* 0110110000 */
+	0x06, 0xc0, /* 0000011011 */
+	0x03, 0x80, /* 0000001110 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 248 0xf8 '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x1e, 0x00, /* 0001111000 */
+	0x33, 0x00, /* 0011001100 */
+	0x33, 0x00, /* 0011001100 */
+	0x1e, 0x00, /* 0001111000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 249 0xf9 '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x1e, 0x00, /* 0001111000 */
+	0x1e, 0x00, /* 0001111000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 250 0xfa '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 251 0xfb '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x0f, 0xc0, /* 0000111111 */
+	0x0f, 0xc0, /* 0000111111 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0xcc, 0x00, /* 1100110000 */
+	0x6c, 0x00, /* 0110110000 */
+	0x3c, 0x00, /* 0011110000 */
+	0x1c, 0x00, /* 0001110000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 252 0xfc '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x27, 0x00, /* 0010011100 */
+	0x7b, 0x00, /* 0111101100 */
+	0x31, 0x00, /* 0011000100 */
+	0x31, 0x00, /* 0011000100 */
+	0x31, 0x00, /* 0011000100 */
+	0x7b, 0x80, /* 0111101110 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 253 0xfd '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x1e, 0x00, /* 0001111000 */
+	0x3f, 0x00, /* 0011111100 */
+	0x63, 0x00, /* 0110001100 */
+	0x43, 0x00, /* 0100001100 */
+	0x06, 0x00, /* 0000011000 */
+	0x0c, 0x00, /* 0000110000 */
+	0x18, 0x00, /* 0001100000 */
+	0x30, 0x80, /* 0011000010 */
+	0x7f, 0x80, /* 0111111110 */
+	0x7f, 0x80, /* 0111111110 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 254 0xfe '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x3f, 0x00, /* 0011111100 */
+	0x3f, 0x00, /* 0011111100 */
+	0x3f, 0x00, /* 0011111100 */
+	0x3f, 0x00, /* 0011111100 */
+	0x3f, 0x00, /* 0011111100 */
+	0x3f, 0x00, /* 0011111100 */
+	0x3f, 0x00, /* 0011111100 */
+	0x3f, 0x00, /* 0011111100 */
+	0x3f, 0x00, /* 0011111100 */
+	0x3f, 0x00, /* 0011111100 */
+	0x3f, 0x00, /* 0011111100 */
+	0x3f, 0x00, /* 0011111100 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+	/* 255 0xff '.' */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+	0x00, 0x00, /* 0000000000 */
+
+};
+
+
+struct font_desc font_10x18 = {
+	FONT10x18_IDX,
+	"10x18",
+	10,
+	18,
+	fontdata_10x18,
+#ifdef __sparc__
+	5
+#else
+	-1
+#endif
+};
diff --git a/drivers/video/console/font_7x14.c b/drivers/video/console/font_7x14.c
new file mode 100644
--- /dev/null
+++ b/drivers/video/console/font_7x14.c
@@ -0,0 +1,4118 @@
+/**************************************/
+/* this file adapted from font_8x16.c */
+/* by Jurriaan Kalkman 05-2005        */
+/**************************************/
+
+#include <linux/font.h>
+
+#define FONTDATAMAX 3584
+
+static unsigned char fontdata_7x14[FONTDATAMAX] = {
+
+	/* 0 0x00 '^@' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 1 0x01 '^A' */
+	0x00, /* 0000000 */
+	0x7c, /* 0111110 */
+	0x82, /* 1000001 */
+	0xaa, /* 1010101 */
+	0x82, /* 1000001 */
+	0x82, /* 1000001 */
+	0xba, /* 1011101 */
+	0x92, /* 1001001 */
+	0x82, /* 1000001 */
+	0x7c, /* 0111110 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 2 0x02 '^B' */
+	0x00, /* 0000000 */
+	0x7c, /* 0111110 */
+	0xfe, /* 1111111 */
+	0xd6, /* 1101011 */
+	0xfe, /* 1111111 */
+	0xfe, /* 1111111 */
+	0xc6, /* 1100011 */
+	0xee, /* 1110111 */
+	0xfe, /* 1111111 */
+	0xfe, /* 1111111 */
+	0x7c, /* 0111110 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 3 0x03 '^C' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x6c, /* 0110110 */
+	0x7c, /* 0111110 */
+	0xfe, /* 1111111 */
+	0x7c, /* 0111110 */
+	0x38, /* 0011100 */
+	0x18, /* 0001100 */
+	0x10, /* 0001000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 4 0x04 '^D' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x10, /* 0001000 */
+	0x38, /* 0011100 */
+	0x7c, /* 0111110 */
+	0xfe, /* 1111111 */
+	0x7c, /* 0111110 */
+	0x38, /* 0011100 */
+	0x10, /* 0001000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 5 0x05 '^E' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x38, /* 0011100 */
+	0x38, /* 0011100 */
+	0x38, /* 0011100 */
+	0xee, /* 1110111 */
+	0xee, /* 1110111 */
+	0xee, /* 1110111 */
+	0x10, /* 0001000 */
+	0x10, /* 0001000 */
+	0x38, /* 0011100 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 6 0x06 '^F' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x10, /* 0001000 */
+	0x38, /* 0011100 */
+	0x7c, /* 0111110 */
+	0xfe, /* 1111111 */
+	0xfe, /* 1111111 */
+	0x7c, /* 0111110 */
+	0x10, /* 0001000 */
+	0x10, /* 0001000 */
+	0x38, /* 0011100 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 7 0x07 '^G' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x18, /* 0001100 */
+	0x3c, /* 0011110 */
+	0x3c, /* 0011110 */
+	0x18, /* 0001100 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 8 0x08 '^H' */
+	0xfe, /* 1111111 */
+	0xfe, /* 1111111 */
+	0xfe, /* 1111111 */
+	0xfe, /* 1111111 */
+	0xfe, /* 1111111 */
+	0xe6, /* 1110011 */
+	0xc2, /* 1100001 */
+	0xc2, /* 1100001 */
+	0xe6, /* 1110011 */
+	0xfe, /* 1111111 */
+	0xfe, /* 1111111 */
+	0xfe, /* 1111111 */
+	0xfe, /* 1111111 */
+	0xfe, /* 1111111 */
+
+	/* 9 0x09 '^I' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x38, /* 0011100 */
+	0x6c, /* 0110110 */
+	0x44, /* 0100010 */
+	0x6c, /* 0110110 */
+	0x38, /* 0011100 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 10 0x0a '^J' */
+	0xfe, /* 1111111 */
+	0xfe, /* 1111111 */
+	0xfe, /* 1111111 */
+	0xfe, /* 1111111 */
+	0xfe, /* 1111111 */
+	0xc6, /* 1100011 */
+	0x92, /* 1001001 */
+	0xba, /* 1011101 */
+	0x92, /* 1001001 */
+	0xc6, /* 1100011 */
+	0xfe, /* 1111111 */
+	0xfe, /* 1111111 */
+	0xfe, /* 1111111 */
+	0xfe, /* 1111111 */
+
+	/* 11 0x0b '^K' */
+	0x00, /* 0000000 */
+	0x1e, /* 0001111 */
+	0x0e, /* 0000111 */
+	0x1a, /* 0001101 */
+	0x1a, /* 0001101 */
+	0x78, /* 0111100 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0x78, /* 0111100 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 12 0x0c '^L' */
+	0x00, /* 0000000 */
+	0x3c, /* 0011110 */
+	0x66, /* 0110011 */
+	0x66, /* 0110011 */
+	0x66, /* 0110011 */
+	0x66, /* 0110011 */
+	0x3c, /* 0011110 */
+	0x18, /* 0001100 */
+	0x7e, /* 0111111 */
+	0x18, /* 0001100 */
+	0x18, /* 0001100 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 13 0x0d '^M' */
+	0x00, /* 0000000 */
+	0x3e, /* 0011111 */
+	0x36, /* 0011011 */
+	0x3e, /* 0011111 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x70, /* 0111000 */
+	0xf0, /* 1111000 */
+	0xe0, /* 1110000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 14 0x0e '^N' */
+	0x00, /* 0000000 */
+	0x7e, /* 0111111 */
+	0x66, /* 0110011 */
+	0x7e, /* 0111111 */
+	0x66, /* 0110011 */
+	0x66, /* 0110011 */
+	0x66, /* 0110011 */
+	0x66, /* 0110011 */
+	0x6e, /* 0110111 */
+	0xee, /* 1110111 */
+	0xec, /* 1110110 */
+	0xc0, /* 1100000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 15 0x0f '^O' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x10, /* 0001000 */
+	0x10, /* 0001000 */
+	0xd6, /* 1101011 */
+	0x38, /* 0011100 */
+	0xee, /* 1110111 */
+	0x38, /* 0011100 */
+	0xd6, /* 1101011 */
+	0x10, /* 0001000 */
+	0x10, /* 0001000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 16 0x10 '^P' */
+	0x00, /* 0000000 */
+	0x80, /* 1000000 */
+	0xc0, /* 1100000 */
+	0xe0, /* 1110000 */
+	0xf0, /* 1111000 */
+	0xfc, /* 1111110 */
+	0xf0, /* 1111000 */
+	0xe0, /* 1110000 */
+	0xc0, /* 1100000 */
+	0x80, /* 1000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 17 0x11 '^Q' */
+	0x00, /* 0000000 */
+	0x04, /* 0000010 */
+	0x0c, /* 0000110 */
+	0x1c, /* 0001110 */
+	0x3c, /* 0011110 */
+	0xfc, /* 1111110 */
+	0x3c, /* 0011110 */
+	0x1c, /* 0001110 */
+	0x0c, /* 0000110 */
+	0x04, /* 0000010 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 18 0x12 '^R' */
+	0x00, /* 0000000 */
+	0x18, /* 0001100 */
+	0x3c, /* 0011110 */
+	0x7e, /* 0111111 */
+	0x18, /* 0001100 */
+	0x18, /* 0001100 */
+	0x18, /* 0001100 */
+	0x7e, /* 0111111 */
+	0x3c, /* 0011110 */
+	0x18, /* 0001100 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 19 0x13 '^S' */
+	0x00, /* 0000000 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x00, /* 0000000 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 20 0x14 '^T' */
+	0x00, /* 0000000 */
+	0x7e, /* 0111111 */
+	0xd4, /* 1101010 */
+	0xd4, /* 1101010 */
+	0xd4, /* 1101010 */
+	0x74, /* 0111010 */
+	0x14, /* 0001010 */
+	0x14, /* 0001010 */
+	0x14, /* 0001010 */
+	0x14, /* 0001010 */
+	0x16, /* 0001011 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 21 0x15 '^U' */
+	0x78, /* 0111100 */
+	0xcc, /* 1100110 */
+	0x60, /* 0110000 */
+	0x38, /* 0011100 */
+	0x6c, /* 0110110 */
+	0xc6, /* 1100011 */
+	0xc6, /* 1100011 */
+	0x6c, /* 0110110 */
+	0x38, /* 0011100 */
+	0x18, /* 0001100 */
+	0xcc, /* 1100110 */
+	0x78, /* 0111100 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 22 0x16 '^V' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0xfc, /* 1111110 */
+	0xfc, /* 1111110 */
+	0xfc, /* 1111110 */
+	0xfc, /* 1111110 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 23 0x17 '^W' */
+	0x00, /* 0000000 */
+	0x18, /* 0001100 */
+	0x3c, /* 0011110 */
+	0x7e, /* 0111111 */
+	0x18, /* 0001100 */
+	0x18, /* 0001100 */
+	0x18, /* 0001100 */
+	0x7e, /* 0111111 */
+	0x3c, /* 0011110 */
+	0x18, /* 0001100 */
+	0x7e, /* 0111111 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 24 0x18 '^X' */
+	0x00, /* 0000000 */
+	0x18, /* 0001100 */
+	0x3c, /* 0011110 */
+	0x7e, /* 0111111 */
+	0x18, /* 0001100 */
+	0x18, /* 0001100 */
+	0x18, /* 0001100 */
+	0x18, /* 0001100 */
+	0x18, /* 0001100 */
+	0x18, /* 0001100 */
+	0x18, /* 0001100 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 25 0x19 '^Y' */
+	0x00, /* 0000000 */
+	0x18, /* 0001100 */
+	0x18, /* 0001100 */
+	0x18, /* 0001100 */
+	0x18, /* 0001100 */
+	0x18, /* 0001100 */
+	0x18, /* 0001100 */
+	0x18, /* 0001100 */
+	0x7e, /* 0111111 */
+	0x3c, /* 0011110 */
+	0x18, /* 0001100 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 26 0x1a '^Z' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x30, /* 0011000 */
+	0x18, /* 0001100 */
+	0xfc, /* 1111110 */
+	0x18, /* 0001100 */
+	0x30, /* 0011000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 27 0x1b '^[' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x30, /* 0011000 */
+	0x60, /* 0110000 */
+	0xfc, /* 1111110 */
+	0x60, /* 0110000 */
+	0x30, /* 0011000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 28 0x1c '^\' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0xc0, /* 1100000 */
+	0xc0, /* 1100000 */
+	0xc0, /* 1100000 */
+	0xfc, /* 1111110 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 29 0x1d '^]' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x28, /* 0010100 */
+	0x6c, /* 0110110 */
+	0xfe, /* 1111111 */
+	0x6c, /* 0110110 */
+	0x28, /* 0010100 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 30 0x1e '^^' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x78, /* 0111100 */
+	0x78, /* 0111100 */
+	0xfc, /* 1111110 */
+	0xfc, /* 1111110 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 31 0x1f '^_' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0xfc, /* 1111110 */
+	0xfc, /* 1111110 */
+	0x78, /* 0111100 */
+	0x78, /* 0111100 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 32 0x20 ' ' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 33 0x21 '!' */
+	0x00, /* 0000000 */
+	0x18, /* 0001100 */
+	0x3c, /* 0011110 */
+	0x3c, /* 0011110 */
+	0x3c, /* 0011110 */
+	0x18, /* 0001100 */
+	0x18, /* 0001100 */
+	0x18, /* 0001100 */
+	0x00, /* 0000000 */
+	0x18, /* 0001100 */
+	0x18, /* 0001100 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 34 0x22 '"' */
+	0x00, /* 0000000 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x28, /* 0010100 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 35 0x23 '#' */
+	0x00, /* 0000000 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0xfe, /* 1111111 */
+	0xfe, /* 1111111 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0xfe, /* 1111111 */
+	0xfe, /* 1111111 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 36 0x24 '$' */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x78, /* 0111100 */
+	0xcc, /* 1100110 */
+	0xc4, /* 1100010 */
+	0xc0, /* 1100000 */
+	0x78, /* 0111100 */
+	0x0c, /* 0000110 */
+	0x8c, /* 1000110 */
+	0xcc, /* 1100110 */
+	0x78, /* 0111100 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x00, /* 0000000 */
+
+	/* 37 0x25 '%' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0xc0, /* 1100000 */
+	0xc4, /* 1100010 */
+	0x0c, /* 0000110 */
+	0x18, /* 0001100 */
+	0x30, /* 0011000 */
+	0x60, /* 0110000 */
+	0xcc, /* 1100110 */
+	0x8c, /* 1000110 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 38 0x26 '&' */
+	0x00, /* 0000000 */
+	0x38, /* 0011100 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x38, /* 0011100 */
+	0x78, /* 0111100 */
+	0xde, /* 1101111 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xdc, /* 1101110 */
+	0x76, /* 0111011 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 39 0x27 ''' */
+	0x00, /* 0000000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x60, /* 0110000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 40 0x28 '(' */
+	0x00, /* 0000000 */
+	0x0c, /* 0000110 */
+	0x18, /* 0001100 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x18, /* 0001100 */
+	0x0c, /* 0000110 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 41 0x29 ')' */
+	0x00, /* 0000000 */
+	0x30, /* 0011000 */
+	0x18, /* 0001100 */
+	0x0c, /* 0000110 */
+	0x0c, /* 0000110 */
+	0x0c, /* 0000110 */
+	0x0c, /* 0000110 */
+	0x0c, /* 0000110 */
+	0x0c, /* 0000110 */
+	0x18, /* 0001100 */
+	0x30, /* 0011000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 42 0x2a '*' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x6c, /* 0110110 */
+	0x38, /* 0011100 */
+	0xfe, /* 1111111 */
+	0x38, /* 0011100 */
+	0x6c, /* 0110110 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 43 0x2b '+' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x10, /* 0001000 */
+	0x10, /* 0001000 */
+	0x7c, /* 0111110 */
+	0x10, /* 0001000 */
+	0x10, /* 0001000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 44 0x2c ',' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x18, /* 0001100 */
+	0x18, /* 0001100 */
+	0x18, /* 0001100 */
+	0x30, /* 0011000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 45 0x2d '-' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0xfc, /* 1111110 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 46 0x2e '.' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x18, /* 0001100 */
+	0x18, /* 0001100 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 47 0x2f '/' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x04, /* 0000010 */
+	0x0c, /* 0000110 */
+	0x18, /* 0001100 */
+	0x30, /* 0011000 */
+	0x60, /* 0110000 */
+	0xc0, /* 1100000 */
+	0x80, /* 1000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 48 0x30 '0' */
+	0x00, /* 0000000 */
+	0x30, /* 0011000 */
+	0x78, /* 0111100 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xdc, /* 1101110 */
+	0xec, /* 1110110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0x78, /* 0111100 */
+	0x30, /* 0011000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 49 0x31 '1' */
+	0x00, /* 0000000 */
+	0x18, /* 0001100 */
+	0x38, /* 0011100 */
+	0x78, /* 0111100 */
+	0x18, /* 0001100 */
+	0x18, /* 0001100 */
+	0x18, /* 0001100 */
+	0x18, /* 0001100 */
+	0x18, /* 0001100 */
+	0x18, /* 0001100 */
+	0x7c, /* 0111110 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 50 0x32 '2' */
+	0x00, /* 0000000 */
+	0x78, /* 0111100 */
+	0xcc, /* 1100110 */
+	0x0c, /* 0000110 */
+	0x18, /* 0001100 */
+	0x18, /* 0001100 */
+	0x30, /* 0011000 */
+	0x60, /* 0110000 */
+	0xc0, /* 1100000 */
+	0xcc, /* 1100110 */
+	0xfc, /* 1111110 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 51 0x33 '3' */
+	0x00, /* 0000000 */
+	0x78, /* 0111100 */
+	0xcc, /* 1100110 */
+	0x0c, /* 0000110 */
+	0x0c, /* 0000110 */
+	0x38, /* 0011100 */
+	0x0c, /* 0000110 */
+	0x0c, /* 0000110 */
+	0x0c, /* 0000110 */
+	0xcc, /* 1100110 */
+	0x78, /* 0111100 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 52 0x34 '4' */
+	0x00, /* 0000000 */
+	0x0c, /* 0000110 */
+	0x1c, /* 0001110 */
+	0x3c, /* 0011110 */
+	0x6c, /* 0110110 */
+	0xcc, /* 1100110 */
+	0xfe, /* 1111111 */
+	0x0c, /* 0000110 */
+	0x0c, /* 0000110 */
+	0x0c, /* 0000110 */
+	0x0c, /* 0000110 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 53 0x35 '5' */
+	0x00, /* 0000000 */
+	0xfc, /* 1111110 */
+	0xc0, /* 1100000 */
+	0xc0, /* 1100000 */
+	0xc0, /* 1100000 */
+	0xf8, /* 1111100 */
+	0x0c, /* 0000110 */
+	0x0c, /* 0000110 */
+	0x0c, /* 0000110 */
+	0xcc, /* 1100110 */
+	0x78, /* 0111100 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 54 0x36 '6' */
+	0x00, /* 0000000 */
+	0x30, /* 0011000 */
+	0x60, /* 0110000 */
+	0xc0, /* 1100000 */
+	0xc0, /* 1100000 */
+	0xf8, /* 1111100 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0x78, /* 0111100 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 55 0x37 '7' */
+	0x00, /* 0000000 */
+	0xfc, /* 1111110 */
+	0xcc, /* 1100110 */
+	0x0c, /* 0000110 */
+	0x0c, /* 0000110 */
+	0x18, /* 0001100 */
+	0x18, /* 0001100 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 56 0x38 '8' */
+	0x00, /* 0000000 */
+	0x78, /* 0111100 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0x78, /* 0111100 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0x78, /* 0111100 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 57 0x39 '9' */
+	0x00, /* 0000000 */
+	0x78, /* 0111100 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0x7c, /* 0111110 */
+	0x0c, /* 0000110 */
+	0x0c, /* 0000110 */
+	0x0c, /* 0000110 */
+	0x18, /* 0001100 */
+	0x70, /* 0111000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 58 0x3a ':' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x18, /* 0001100 */
+	0x18, /* 0001100 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x18, /* 0001100 */
+	0x18, /* 0001100 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 59 0x3b ';' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x18, /* 0001100 */
+	0x18, /* 0001100 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x18, /* 0001100 */
+	0x18, /* 0001100 */
+	0x30, /* 0011000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 60 0x3c '<' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x04, /* 0000010 */
+	0x0c, /* 0000110 */
+	0x18, /* 0001100 */
+	0x30, /* 0011000 */
+	0x60, /* 0110000 */
+	0x30, /* 0011000 */
+	0x18, /* 0001100 */
+	0x0c, /* 0000110 */
+	0x04, /* 0000010 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 61 0x3d '=' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x7c, /* 0111110 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x7c, /* 0111110 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 62 0x3e '>' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x40, /* 0100000 */
+	0x60, /* 0110000 */
+	0x30, /* 0011000 */
+	0x18, /* 0001100 */
+	0x0c, /* 0000110 */
+	0x18, /* 0001100 */
+	0x30, /* 0011000 */
+	0x60, /* 0110000 */
+	0x40, /* 0100000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 63 0x3f '?' */
+	0x00, /* 0000000 */
+	0x78, /* 0111100 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0x18, /* 0001100 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x00, /* 0000000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 64 0x40 '@' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x78, /* 0111100 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xdc, /* 1101110 */
+	0xdc, /* 1101110 */
+	0xd8, /* 1101100 */
+	0xc0, /* 1100000 */
+	0x78, /* 0111100 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 65 0x41 'A' */
+	0x00, /* 0000000 */
+	0x30, /* 0011000 */
+	0x78, /* 0111100 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xfc, /* 1111110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 66 0x42 'B' */
+	0x00, /* 0000000 */
+	0xf8, /* 1111100 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x78, /* 0111100 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0xf8, /* 1111100 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 67 0x43 'C' */
+	0x00, /* 0000000 */
+	0x38, /* 0011100 */
+	0x6c, /* 0110110 */
+	0xc4, /* 1100010 */
+	0xc0, /* 1100000 */
+	0xc0, /* 1100000 */
+	0xc0, /* 1100000 */
+	0xc0, /* 1100000 */
+	0xc4, /* 1100010 */
+	0x6c, /* 0110110 */
+	0x38, /* 0011100 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 68 0x44 'D' */
+	0x00, /* 0000000 */
+	0xf0, /* 1111000 */
+	0xd8, /* 1101100 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xd8, /* 1101100 */
+	0xf0, /* 1111000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 69 0x45 'E' */
+	0x00, /* 0000000 */
+	0x7c, /* 0111110 */
+	0x6c, /* 0110110 */
+	0x64, /* 0110010 */
+	0x68, /* 0110100 */
+	0x78, /* 0111100 */
+	0x68, /* 0110100 */
+	0x60, /* 0110000 */
+	0x64, /* 0110010 */
+	0x6c, /* 0110110 */
+	0x7c, /* 0111110 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 70 0x46 'F' */
+	0x00, /* 0000000 */
+	0x7c, /* 0111110 */
+	0x64, /* 0110010 */
+	0x60, /* 0110000 */
+	0x68, /* 0110100 */
+	0x78, /* 0111100 */
+	0x68, /* 0110100 */
+	0x60, /* 0110000 */
+	0x60, /* 0110000 */
+	0x60, /* 0110000 */
+	0x70, /* 0111000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 71 0x47 'G' */
+	0x00, /* 0000000 */
+	0x38, /* 0011100 */
+	0x6c, /* 0110110 */
+	0xc4, /* 1100010 */
+	0xc0, /* 1100000 */
+	0xc0, /* 1100000 */
+	0xdc, /* 1101110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0x6c, /* 0110110 */
+	0x34, /* 0011010 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 72 0x48 'H' */
+	0x00, /* 0000000 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xfc, /* 1111110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 73 0x49 'I' */
+	0x00, /* 0000000 */
+	0x3c, /* 0011110 */
+	0x18, /* 0001100 */
+	0x18, /* 0001100 */
+	0x18, /* 0001100 */
+	0x18, /* 0001100 */
+	0x18, /* 0001100 */
+	0x18, /* 0001100 */
+	0x18, /* 0001100 */
+	0x18, /* 0001100 */
+	0x3c, /* 0011110 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 74 0x4a 'J' */
+	0x00, /* 0000000 */
+	0x1c, /* 0001110 */
+	0x0c, /* 0000110 */
+	0x0c, /* 0000110 */
+	0x0c, /* 0000110 */
+	0x0c, /* 0000110 */
+	0x0c, /* 0000110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0x78, /* 0111100 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 75 0x4b 'K' */
+	0x00, /* 0000000 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xd8, /* 1101100 */
+	0xf0, /* 1111000 */
+	0xf0, /* 1111000 */
+	0xd8, /* 1101100 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 76 0x4c 'L' */
+	0x00, /* 0000000 */
+	0xc0, /* 1100000 */
+	0xc0, /* 1100000 */
+	0xc0, /* 1100000 */
+	0xc0, /* 1100000 */
+	0xc0, /* 1100000 */
+	0xc0, /* 1100000 */
+	0xc0, /* 1100000 */
+	0xc4, /* 1100010 */
+	0xcc, /* 1100110 */
+	0xfc, /* 1111110 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 77 0x4d 'M' */
+	0x00, /* 0000000 */
+	0xc6, /* 1100011 */
+	0xee, /* 1110111 */
+	0xfe, /* 1111111 */
+	0xfe, /* 1111111 */
+	0xd6, /* 1101011 */
+	0xc6, /* 1100011 */
+	0xc6, /* 1100011 */
+	0xc6, /* 1100011 */
+	0xc6, /* 1100011 */
+	0xc6, /* 1100011 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 78 0x4e 'N' */
+	0x00, /* 0000000 */
+	0xcc, /* 1100110 */
+	0xec, /* 1110110 */
+	0xec, /* 1110110 */
+	0xfc, /* 1111110 */
+	0xdc, /* 1101110 */
+	0xdc, /* 1101110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 79 0x4f 'O' */
+	0x00, /* 0000000 */
+	0x78, /* 0111100 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0x78, /* 0111100 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 80 0x50 'P' */
+	0x00, /* 0000000 */
+	0xf8, /* 1111100 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xf8, /* 1111100 */
+	0xc0, /* 1100000 */
+	0xc0, /* 1100000 */
+	0xc0, /* 1100000 */
+	0xc0, /* 1100000 */
+	0xc0, /* 1100000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 81 0x51 'Q' */
+	0x00, /* 0000000 */
+	0x78, /* 0111100 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xdc, /* 1101110 */
+	0x78, /* 0111100 */
+	0x18, /* 0001100 */
+	0x1c, /* 0001110 */
+	0x00, /* 0000000 */
+
+	/* 82 0x52 'R' */
+	0x00, /* 0000000 */
+	0xf8, /* 1111100 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xf8, /* 1111100 */
+	0xd8, /* 1101100 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 83 0x53 'S' */
+	0x00, /* 0000000 */
+	0x7c, /* 0111110 */
+	0xc4, /* 1100010 */
+	0xc0, /* 1100000 */
+	0xc0, /* 1100000 */
+	0x60, /* 0110000 */
+	0x38, /* 0011100 */
+	0x0c, /* 0000110 */
+	0x0c, /* 0000110 */
+	0x8c, /* 1000110 */
+	0xf8, /* 1111100 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 84 0x54 'T' */
+	0x00, /* 0000000 */
+	0xfc, /* 1111110 */
+	0xfc, /* 1111110 */
+	0xb4, /* 1011010 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x78, /* 0111100 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 85 0x55 'U' */
+	0x00, /* 0000000 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0x78, /* 0111100 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 86 0x56 'V' */
+	0x00, /* 0000000 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0x78, /* 0111100 */
+	0x78, /* 0111100 */
+	0x30, /* 0011000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 87 0x57 'W' */
+	0x00, /* 0000000 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xfc, /* 1111110 */
+	0xfc, /* 1111110 */
+	0x48, /* 0100100 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 88 0x58 'X' */
+	0x00, /* 0000000 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0x78, /* 0111100 */
+	0x78, /* 0111100 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x78, /* 0111100 */
+	0x78, /* 0111100 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 89 0x59 'Y' */
+	0x00, /* 0000000 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0x78, /* 0111100 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 90 0x5a 'Z' */
+	0x00, /* 0000000 */
+	0xfc, /* 1111110 */
+	0xcc, /* 1100110 */
+	0x8c, /* 1000110 */
+	0x18, /* 0001100 */
+	0x18, /* 0001100 */
+	0x30, /* 0011000 */
+	0x60, /* 0110000 */
+	0xc4, /* 1100010 */
+	0xcc, /* 1100110 */
+	0xfc, /* 1111110 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 91 0x5b '[' */
+	0x00, /* 0000000 */
+	0x78, /* 0111100 */
+	0x60, /* 0110000 */
+	0x60, /* 0110000 */
+	0x60, /* 0110000 */
+	0x60, /* 0110000 */
+	0x60, /* 0110000 */
+	0x60, /* 0110000 */
+	0x60, /* 0110000 */
+	0x60, /* 0110000 */
+	0x78, /* 0111100 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 92 0x5c '\' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x80, /* 1000000 */
+	0xc0, /* 1100000 */
+	0xe0, /* 1110000 */
+	0x70, /* 0111000 */
+	0x38, /* 0011100 */
+	0x1c, /* 0001110 */
+	0x0c, /* 0000110 */
+	0x04, /* 0000010 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 93 0x5d ']' */
+	0x00, /* 0000000 */
+	0x78, /* 0111100 */
+	0x18, /* 0001100 */
+	0x18, /* 0001100 */
+	0x18, /* 0001100 */
+	0x18, /* 0001100 */
+	0x18, /* 0001100 */
+	0x18, /* 0001100 */
+	0x18, /* 0001100 */
+	0x18, /* 0001100 */
+	0x78, /* 0111100 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 94 0x5e '^' */
+	0x10, /* 0001000 */
+	0x38, /* 0011100 */
+	0x6c, /* 0110110 */
+	0xc6, /* 1100011 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 95 0x5f '_' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0xfe, /* 1111111 */
+	0x00, /* 0000000 */
+
+	/* 96 0x60 '`' */
+	0x00, /* 0000000 */
+	0x60, /* 0110000 */
+	0x30, /* 0011000 */
+	0x18, /* 0001100 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 97 0x61 'a' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x78, /* 0111100 */
+	0x0c, /* 0000110 */
+	0x7c, /* 0111110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0x76, /* 0111011 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 98 0x62 'b' */
+	0x00, /* 0000000 */
+	0xc0, /* 1100000 */
+	0xc0, /* 1100000 */
+	0xc0, /* 1100000 */
+	0xf0, /* 1111000 */
+	0xd8, /* 1101100 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xf8, /* 1111100 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 99 0x63 'c' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x78, /* 0111100 */
+	0xcc, /* 1100110 */
+	0xc0, /* 1100000 */
+	0xc0, /* 1100000 */
+	0xc0, /* 1100000 */
+	0xcc, /* 1100110 */
+	0x78, /* 0111100 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 100 0x64 'd' */
+	0x00, /* 0000000 */
+	0x1c, /* 0001110 */
+	0x0c, /* 0000110 */
+	0x0c, /* 0000110 */
+	0x3c, /* 0011110 */
+	0x6c, /* 0110110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0x76, /* 0111011 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 101 0x65 'e' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x78, /* 0111100 */
+	0xcc, /* 1100110 */
+	0xfc, /* 1111110 */
+	0xc0, /* 1100000 */
+	0xc0, /* 1100000 */
+	0xcc, /* 1100110 */
+	0x78, /* 0111100 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 102 0x66 'f' */
+	0x00, /* 0000000 */
+	0x38, /* 0011100 */
+	0x6c, /* 0110110 */
+	0x64, /* 0110010 */
+	0x60, /* 0110000 */
+	0xf0, /* 1111000 */
+	0x60, /* 0110000 */
+	0x60, /* 0110000 */
+	0x60, /* 0110000 */
+	0x60, /* 0110000 */
+	0xf0, /* 1111000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 103 0x67 'g' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x76, /* 0111011 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0x7c, /* 0111110 */
+	0x0c, /* 0000110 */
+	0xcc, /* 1100110 */
+	0x78, /* 0111100 */
+
+	/* 104 0x68 'h' */
+	0x00, /* 0000000 */
+	0xc0, /* 1100000 */
+	0xc0, /* 1100000 */
+	0xc0, /* 1100000 */
+	0xd8, /* 1101100 */
+	0xec, /* 1110110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 105 0x69 'i' */
+	0x00, /* 0000000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x00, /* 0000000 */
+	0x70, /* 0111000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x78, /* 0111100 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 106 0x6a 'j' */
+	0x00, /* 0000000 */
+	0x0c, /* 0000110 */
+	0x0c, /* 0000110 */
+	0x00, /* 0000000 */
+	0x1c, /* 0001110 */
+	0x0c, /* 0000110 */
+	0x0c, /* 0000110 */
+	0x0c, /* 0000110 */
+	0x0c, /* 0000110 */
+	0x0c, /* 0000110 */
+	0x0c, /* 0000110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0x78, /* 0111100 */
+
+	/* 107 0x6b 'k' */
+	0x00, /* 0000000 */
+	0xc0, /* 1100000 */
+	0xc0, /* 1100000 */
+	0xc0, /* 1100000 */
+	0xcc, /* 1100110 */
+	0xd8, /* 1101100 */
+	0xf0, /* 1111000 */
+	0xf0, /* 1111000 */
+	0xd8, /* 1101100 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 108 0x6c 'l' */
+	0x00, /* 0000000 */
+	0x70, /* 0111000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x78, /* 0111100 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 109 0x6d 'm' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0xec, /* 1110110 */
+	0xfe, /* 1111111 */
+	0xd6, /* 1101011 */
+	0xd6, /* 1101011 */
+	0xd6, /* 1101011 */
+	0xd6, /* 1101011 */
+	0xd6, /* 1101011 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 110 0x6e 'n' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0xb8, /* 1011100 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 111 0x6f 'o' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x78, /* 0111100 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0x78, /* 0111100 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 112 0x70 'p' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0xb8, /* 1011100 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xf8, /* 1111100 */
+	0xc0, /* 1100000 */
+	0xc0, /* 1100000 */
+	0xc0, /* 1100000 */
+
+	/* 113 0x71 'q' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x74, /* 0111010 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0x7c, /* 0111110 */
+	0x0c, /* 0000110 */
+	0x0c, /* 0000110 */
+	0x0c, /* 0000110 */
+
+	/* 114 0x72 'r' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0xb8, /* 1011100 */
+	0xec, /* 1110110 */
+	0xcc, /* 1100110 */
+	0xc0, /* 1100000 */
+	0xc0, /* 1100000 */
+	0xc0, /* 1100000 */
+	0xc0, /* 1100000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 115 0x73 's' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x78, /* 0111100 */
+	0xcc, /* 1100110 */
+	0x60, /* 0110000 */
+	0x30, /* 0011000 */
+	0x18, /* 0001100 */
+	0xcc, /* 1100110 */
+	0x78, /* 0111100 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 116 0x74 't' */
+	0x00, /* 0000000 */
+	0x10, /* 0001000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0xfc, /* 1111110 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x36, /* 0011011 */
+	0x1c, /* 0001110 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 117 0x75 'u' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0x76, /* 0111011 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 118 0x76 'v' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0x78, /* 0111100 */
+	0x30, /* 0011000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 119 0x77 'w' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0xc6, /* 1100011 */
+	0xc6, /* 1100011 */
+	0xd6, /* 1101011 */
+	0xd6, /* 1101011 */
+	0xd6, /* 1101011 */
+	0xfe, /* 1111111 */
+	0x6c, /* 0110110 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 120 0x78 'x' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0x78, /* 0111100 */
+	0x30, /* 0011000 */
+	0x78, /* 0111100 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 121 0x79 'y' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0x7c, /* 0111110 */
+	0x0c, /* 0000110 */
+	0x18, /* 0001100 */
+	0xf0, /* 1111000 */
+
+	/* 122 0x7a 'z' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0xfc, /* 1111110 */
+	0xcc, /* 1100110 */
+	0x18, /* 0001100 */
+	0x30, /* 0011000 */
+	0x60, /* 0110000 */
+	0xcc, /* 1100110 */
+	0xfc, /* 1111110 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 123 0x7b '{' */
+	0x00, /* 0000000 */
+	0x1c, /* 0001110 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0xe0, /* 1110000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x1c, /* 0001110 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 124 0x7c '|' */
+	0x00, /* 0000000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 125 0x7d '}' */
+	0x00, /* 0000000 */
+	0x70, /* 0111000 */
+	0x18, /* 0001100 */
+	0x18, /* 0001100 */
+	0x18, /* 0001100 */
+	0x0e, /* 0000111 */
+	0x18, /* 0001100 */
+	0x18, /* 0001100 */
+	0x18, /* 0001100 */
+	0x18, /* 0001100 */
+	0x70, /* 0111000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 126 0x7e '~' */
+	0x00, /* 0000000 */
+	0xec, /* 1110110 */
+	0xb8, /* 1011100 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 127 0x7f '' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x10, /* 0001000 */
+	0x38, /* 0011100 */
+	0x6c, /* 0110110 */
+	0xc6, /* 1100011 */
+	0xc6, /* 1100011 */
+	0xc6, /* 1100011 */
+	0xfe, /* 1111111 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 128 0x80 '€' */
+	0x00, /* 0000000 */
+	0x38, /* 0011100 */
+	0x6c, /* 0110110 */
+	0xc4, /* 1100010 */
+	0xc0, /* 1100000 */
+	0xc0, /* 1100000 */
+	0xc0, /* 1100000 */
+	0xc0, /* 1100000 */
+	0xc4, /* 1100010 */
+	0x6c, /* 0110110 */
+	0x38, /* 0011100 */
+	0x18, /* 0001100 */
+	0x70, /* 0111000 */
+	0x00, /* 0000000 */
+
+	/* 129 0x81 '�' */
+	0x00, /* 0000000 */
+	0xcc, /* 1100110 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0x76, /* 0111011 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 130 0x82 '‚' */
+	0x0c, /* 0000110 */
+	0x18, /* 0001100 */
+	0x30, /* 0011000 */
+	0x00, /* 0000000 */
+	0x78, /* 0111100 */
+	0xcc, /* 1100110 */
+	0xfc, /* 1111110 */
+	0xc0, /* 1100000 */
+	0xc0, /* 1100000 */
+	0xcc, /* 1100110 */
+	0x78, /* 0111100 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 131 0x83 'ƒ' */
+	0x10, /* 0001000 */
+	0x38, /* 0011100 */
+	0x6c, /* 0110110 */
+	0x00, /* 0000000 */
+	0x78, /* 0111100 */
+	0x0c, /* 0000110 */
+	0x7c, /* 0111110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0x76, /* 0111011 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 132 0x84 '„' */
+	0x00, /* 0000000 */
+	0xcc, /* 1100110 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x78, /* 0111100 */
+	0x0c, /* 0000110 */
+	0x7c, /* 0111110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0x76, /* 0111011 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 133 0x85 '…' */
+	0x60, /* 0110000 */
+	0x30, /* 0011000 */
+	0x18, /* 0001100 */
+	0x00, /* 0000000 */
+	0x78, /* 0111100 */
+	0x0c, /* 0000110 */
+	0x7c, /* 0111110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0x76, /* 0111011 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 134 0x86 '†' */
+	0x38, /* 0011100 */
+	0x6c, /* 0110110 */
+	0x38, /* 0011100 */
+	0x00, /* 0000000 */
+	0x78, /* 0111100 */
+	0x0c, /* 0000110 */
+	0x7c, /* 0111110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0x76, /* 0111011 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 135 0x87 '‡' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x78, /* 0111100 */
+	0xcc, /* 1100110 */
+	0xc0, /* 1100000 */
+	0xc0, /* 1100000 */
+	0xc0, /* 1100000 */
+	0xcc, /* 1100110 */
+	0x78, /* 0111100 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0xe0, /* 1110000 */
+
+	/* 136 0x88 'ˆ' */
+	0x10, /* 0001000 */
+	0x38, /* 0011100 */
+	0x6c, /* 0110110 */
+	0x00, /* 0000000 */
+	0x78, /* 0111100 */
+	0xcc, /* 1100110 */
+	0xfc, /* 1111110 */
+	0xc0, /* 1100000 */
+	0xc0, /* 1100000 */
+	0xcc, /* 1100110 */
+	0x78, /* 0111100 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 137 0x89 '‰' */
+	0x00, /* 0000000 */
+	0xcc, /* 1100110 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x78, /* 0111100 */
+	0xcc, /* 1100110 */
+	0xfc, /* 1111110 */
+	0xc0, /* 1100000 */
+	0xc0, /* 1100000 */
+	0xcc, /* 1100110 */
+	0x78, /* 0111100 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 138 0x8a 'Š' */
+	0xc0, /* 1100000 */
+	0x60, /* 0110000 */
+	0x30, /* 0011000 */
+	0x00, /* 0000000 */
+	0x78, /* 0111100 */
+	0xcc, /* 1100110 */
+	0xfc, /* 1111110 */
+	0xc0, /* 1100000 */
+	0xc0, /* 1100000 */
+	0xcc, /* 1100110 */
+	0x78, /* 0111100 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 139 0x8b '‹' */
+	0x00, /* 0000000 */
+	0x6c, /* 0110110 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x38, /* 0011100 */
+	0x18, /* 0001100 */
+	0x18, /* 0001100 */
+	0x18, /* 0001100 */
+	0x18, /* 0001100 */
+	0x18, /* 0001100 */
+	0x3c, /* 0011110 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 140 0x8c 'Œ' */
+	0x30, /* 0011000 */
+	0x78, /* 0111100 */
+	0xcc, /* 1100110 */
+	0x00, /* 0000000 */
+	0x70, /* 0111000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x78, /* 0111100 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 141 0x8d '�' */
+	0xc0, /* 1100000 */
+	0x60, /* 0110000 */
+	0x30, /* 0011000 */
+	0x00, /* 0000000 */
+	0x70, /* 0111000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x78, /* 0111100 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 142 0x8e 'Ž' */
+	0x00, /* 0000000 */
+	0xcc, /* 1100110 */
+	0x00, /* 0000000 */
+	0x30, /* 0011000 */
+	0x78, /* 0111100 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xfc, /* 1111110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 143 0x8f '�' */
+	0x30, /* 0011000 */
+	0x48, /* 0100100 */
+	0x48, /* 0100100 */
+	0x30, /* 0011000 */
+	0x78, /* 0111100 */
+	0xcc, /* 1100110 */
+	0xfc, /* 1111110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 144 0x90 '�' */
+	0x18, /* 0001100 */
+	0x30, /* 0011000 */
+	0xfc, /* 1111110 */
+	0xcc, /* 1100110 */
+	0xc4, /* 1100010 */
+	0xd0, /* 1101000 */
+	0xf0, /* 1111000 */
+	0xd0, /* 1101000 */
+	0xc4, /* 1100010 */
+	0xcc, /* 1100110 */
+	0xfc, /* 1111110 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 145 0x91 '‘' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0xec, /* 1110110 */
+	0x36, /* 0011011 */
+	0x36, /* 0011011 */
+	0x7e, /* 0111111 */
+	0xd8, /* 1101100 */
+	0xd8, /* 1101100 */
+	0x6e, /* 0110111 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 146 0x92 '’' */
+	0x00, /* 0000000 */
+	0x3e, /* 0011111 */
+	0x6c, /* 0110110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xfe, /* 1111111 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xce, /* 1100111 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 147 0x93 '“' */
+	0x10, /* 0001000 */
+	0x38, /* 0011100 */
+	0x6c, /* 0110110 */
+	0x00, /* 0000000 */
+	0x78, /* 0111100 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0x78, /* 0111100 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 148 0x94 '”' */
+	0x00, /* 0000000 */
+	0xcc, /* 1100110 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x78, /* 0111100 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0x78, /* 0111100 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 149 0x95 '•' */
+	0xc0, /* 1100000 */
+	0x60, /* 0110000 */
+	0x30, /* 0011000 */
+	0x00, /* 0000000 */
+	0x78, /* 0111100 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0x78, /* 0111100 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 150 0x96 '–' */
+	0x30, /* 0011000 */
+	0x78, /* 0111100 */
+	0xcc, /* 1100110 */
+	0x00, /* 0000000 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0x76, /* 0111011 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 151 0x97 '—' */
+	0x60, /* 0110000 */
+	0x30, /* 0011000 */
+	0x18, /* 0001100 */
+	0x00, /* 0000000 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0x76, /* 0111011 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 152 0x98 '˜' */
+	0x00, /* 0000000 */
+	0xcc, /* 1100110 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0x7c, /* 0111110 */
+	0x0c, /* 0000110 */
+	0x18, /* 0001100 */
+	0x70, /* 0111000 */
+
+	/* 153 0x99 '™' */
+	0xcc, /* 1100110 */
+	0x00, /* 0000000 */
+	0x78, /* 0111100 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0x78, /* 0111100 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 154 0x9a 'š' */
+	0xcc, /* 1100110 */
+	0x00, /* 0000000 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0x78, /* 0111100 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 155 0x9b '›' */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x7c, /* 0111110 */
+	0xcc, /* 1100110 */
+	0xc0, /* 1100000 */
+	0xc0, /* 1100000 */
+	0xc0, /* 1100000 */
+	0xcc, /* 1100110 */
+	0x7c, /* 0111110 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 156 0x9c 'œ' */
+	0x38, /* 0011100 */
+	0x6c, /* 0110110 */
+	0x64, /* 0110010 */
+	0x60, /* 0110000 */
+	0xf0, /* 1111000 */
+	0x60, /* 0110000 */
+	0x60, /* 0110000 */
+	0x60, /* 0110000 */
+	0x60, /* 0110000 */
+	0xe6, /* 1110011 */
+	0xfc, /* 1111110 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 157 0x9d '�' */
+	0x00, /* 0000000 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0x78, /* 0111100 */
+	0x30, /* 0011000 */
+	0xfc, /* 1111110 */
+	0x30, /* 0011000 */
+	0xfc, /* 1111110 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 158 0x9e 'ž' */
+	0xf8, /* 1111100 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xf8, /* 1111100 */
+	0xc4, /* 1100010 */
+	0xcc, /* 1100110 */
+	0xde, /* 1101111 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xc6, /* 1100011 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 159 0x9f 'Ÿ' */
+	0x1c, /* 0001110 */
+	0x36, /* 0011011 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0xfc, /* 1111110 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0xb0, /* 1011000 */
+	0xe0, /* 1110000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 160 0xa0 ' ' */
+	0x18, /* 0001100 */
+	0x30, /* 0011000 */
+	0x60, /* 0110000 */
+	0x00, /* 0000000 */
+	0x78, /* 0111100 */
+	0x0c, /* 0000110 */
+	0x7c, /* 0111110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0x76, /* 0111011 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 161 0xa1 '¡' */
+	0x18, /* 0001100 */
+	0x30, /* 0011000 */
+	0x60, /* 0110000 */
+	0x00, /* 0000000 */
+	0x70, /* 0111000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x78, /* 0111100 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 162 0xa2 '¢' */
+	0x18, /* 0001100 */
+	0x30, /* 0011000 */
+	0x60, /* 0110000 */
+	0x00, /* 0000000 */
+	0x78, /* 0111100 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0x78, /* 0111100 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 163 0xa3 '£' */
+	0x18, /* 0001100 */
+	0x30, /* 0011000 */
+	0x60, /* 0110000 */
+	0x00, /* 0000000 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0x76, /* 0111011 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 164 0xa4 '¤' */
+	0x00, /* 0000000 */
+	0x76, /* 0111011 */
+	0xdc, /* 1101110 */
+	0x00, /* 0000000 */
+	0xb8, /* 1011100 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 165 0xa5 '¥' */
+	0x76, /* 0111011 */
+	0xdc, /* 1101110 */
+	0x00, /* 0000000 */
+	0xcc, /* 1100110 */
+	0xec, /* 1110110 */
+	0xec, /* 1110110 */
+	0xfc, /* 1111110 */
+	0xdc, /* 1101110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 166 0xa6 '¦' */
+	0x00, /* 0000000 */
+	0x78, /* 0111100 */
+	0xd8, /* 1101100 */
+	0xd8, /* 1101100 */
+	0x7c, /* 0111110 */
+	0x00, /* 0000000 */
+	0xfc, /* 1111110 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 167 0xa7 '§' */
+	0x00, /* 0000000 */
+	0x70, /* 0111000 */
+	0xd8, /* 1101100 */
+	0xd8, /* 1101100 */
+	0x70, /* 0111000 */
+	0x00, /* 0000000 */
+	0xf8, /* 1111100 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 168 0xa8 '¨' */
+	0x00, /* 0000000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x00, /* 0000000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x60, /* 0110000 */
+	0xc0, /* 1100000 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0x78, /* 0111100 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 169 0xa9 '©' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0xfc, /* 1111110 */
+	0xc0, /* 1100000 */
+	0xc0, /* 1100000 */
+	0xc0, /* 1100000 */
+	0xc0, /* 1100000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 170 0xaa 'ª' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0xfc, /* 1111110 */
+	0x0c, /* 0000110 */
+	0x0c, /* 0000110 */
+	0x0c, /* 0000110 */
+	0x0c, /* 0000110 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 171 0xab '«' */
+	0x60, /* 0110000 */
+	0xe0, /* 1110000 */
+	0x62, /* 0110001 */
+	0x66, /* 0110011 */
+	0x6c, /* 0110110 */
+	0x18, /* 0001100 */
+	0x30, /* 0011000 */
+	0x60, /* 0110000 */
+	0xc0, /* 1100000 */
+	0xb8, /* 1011100 */
+	0x4c, /* 0100110 */
+	0x18, /* 0001100 */
+	0x30, /* 0011000 */
+	0x7c, /* 0111110 */
+
+	/* 172 0xac '¬' */
+	0x60, /* 0110000 */
+	0xe0, /* 1110000 */
+	0x62, /* 0110001 */
+	0x66, /* 0110011 */
+	0x6c, /* 0110110 */
+	0x18, /* 0001100 */
+	0x30, /* 0011000 */
+	0x6c, /* 0110110 */
+	0xdc, /* 1101110 */
+	0xb4, /* 1011010 */
+	0x7e, /* 0111111 */
+	0x0c, /* 0000110 */
+	0x0c, /* 0000110 */
+	0x00, /* 0000000 */
+
+	/* 173 0xad '­' */
+	0x00, /* 0000000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x00, /* 0000000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x78, /* 0111100 */
+	0x78, /* 0111100 */
+	0x78, /* 0111100 */
+	0x30, /* 0011000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 174 0xae '®' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x36, /* 0011011 */
+	0x6c, /* 0110110 */
+	0xd8, /* 1101100 */
+	0x6c, /* 0110110 */
+	0x36, /* 0011011 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 175 0xaf '¯' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0xd8, /* 1101100 */
+	0x6c, /* 0110110 */
+	0x36, /* 0011011 */
+	0x6c, /* 0110110 */
+	0xd8, /* 1101100 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 176 0xb0 '°' */
+	0x88, /* 1000100 */
+	0x22, /* 0010001 */
+	0x88, /* 1000100 */
+	0x22, /* 0010001 */
+	0x88, /* 1000100 */
+	0x22, /* 0010001 */
+	0x88, /* 1000100 */
+	0x22, /* 0010001 */
+	0x88, /* 1000100 */
+	0x22, /* 0010001 */
+	0x88, /* 1000100 */
+	0x22, /* 0010001 */
+	0x88, /* 1000100 */
+	0x22, /* 0010001 */
+
+	/* 177 0xb1 '±' */
+	0x54, /* 0101010 */
+	0xaa, /* 1010101 */
+	0x54, /* 0101010 */
+	0xaa, /* 1010101 */
+	0x54, /* 0101010 */
+	0xaa, /* 1010101 */
+	0x54, /* 0101010 */
+	0xaa, /* 1010101 */
+	0x54, /* 0101010 */
+	0xaa, /* 1010101 */
+	0x54, /* 0101010 */
+	0xaa, /* 1010101 */
+	0x54, /* 0101010 */
+	0xaa, /* 1010101 */
+
+	/* 178 0xb2 '²' */
+	0xee, /* 1110111 */
+	0xba, /* 1011101 */
+	0xee, /* 1110111 */
+	0xba, /* 1011101 */
+	0xee, /* 1110111 */
+	0xba, /* 1011101 */
+	0xee, /* 1110111 */
+	0xba, /* 1011101 */
+	0xee, /* 1110111 */
+	0xba, /* 1011101 */
+	0xee, /* 1110111 */
+	0xba, /* 1011101 */
+	0xee, /* 1110111 */
+	0xba, /* 1011101 */
+
+	/* 179 0xb3 '³' */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+
+	/* 180 0xb4 '´' */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0xf0, /* 1111000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+
+	/* 181 0xb5 'µ' */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0xf0, /* 1111000 */
+	0x30, /* 0011000 */
+	0xf0, /* 1111000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+
+	/* 182 0xb6 '¶' */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0xec, /* 1110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+
+	/* 183 0xb7 '·' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0xfc, /* 1111110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+
+	/* 184 0xb8 '¸' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0xf0, /* 1111000 */
+	0x30, /* 0011000 */
+	0xf0, /* 1111000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+
+	/* 185 0xb9 '¹' */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0xec, /* 1110110 */
+	0x0c, /* 0000110 */
+	0xec, /* 1110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+
+	/* 186 0xba 'º' */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+
+	/* 187 0xbb '»' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0xfc, /* 1111110 */
+	0x0c, /* 0000110 */
+	0xec, /* 1110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+
+	/* 188 0xbc '¼' */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0xec, /* 1110110 */
+	0x0c, /* 0000110 */
+	0xfc, /* 1111110 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 189 0xbd '½' */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0xfc, /* 1111110 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 190 0xbe '¾' */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0xf0, /* 1111000 */
+	0x30, /* 0011000 */
+	0xf0, /* 1111000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 191 0xbf '¿' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0xf0, /* 1111000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+
+	/* 192 0xc0 'À' */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x3e, /* 0011111 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 193 0xc1 'Á' */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0xfe, /* 1111111 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 194 0xc2 'Â' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0xfe, /* 1111111 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+
+	/* 195 0xc3 'Ã' */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x3e, /* 0011111 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+
+	/* 196 0xc4 'Ä' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0xfe, /* 1111111 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 197 0xc5 'Å' */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0xfe, /* 1111111 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+
+	/* 198 0xc6 'Æ' */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x3e, /* 0011111 */
+	0x30, /* 0011000 */
+	0x3e, /* 0011111 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+
+	/* 199 0xc7 'Ç' */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6e, /* 0110111 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+
+	/* 200 0xc8 'È' */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6e, /* 0110111 */
+	0x60, /* 0110000 */
+	0x7e, /* 0111111 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 201 0xc9 'É' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x7e, /* 0111111 */
+	0x60, /* 0110000 */
+	0x6e, /* 0110111 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+
+	/* 202 0xca 'Ê' */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0xee, /* 1110111 */
+	0x00, /* 0000000 */
+	0xfe, /* 1111111 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 203 0xcb 'Ë' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0xfe, /* 1111111 */
+	0x00, /* 0000000 */
+	0xee, /* 1110111 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+
+	/* 204 0xcc 'Ì' */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6e, /* 0110111 */
+	0x60, /* 0110000 */
+	0x6e, /* 0110111 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+
+	/* 205 0xcd 'Í' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0xfe, /* 1111111 */
+	0x00, /* 0000000 */
+	0xfe, /* 1111111 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 206 0xce 'Î' */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0xee, /* 1110111 */
+	0x00, /* 0000000 */
+	0xee, /* 1110111 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+
+	/* 207 0xcf 'Ï' */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0xfe, /* 1111111 */
+	0x00, /* 0000000 */
+	0xfe, /* 1111111 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 208 0xd0 'Ð' */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0xfe, /* 1111111 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 209 0xd1 'Ñ' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0xfe, /* 1111111 */
+	0x00, /* 0000000 */
+	0xfe, /* 1111111 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+
+	/* 210 0xd2 'Ò' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0xfe, /* 1111111 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+
+	/* 211 0xd3 'Ó' */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x7e, /* 0111111 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 212 0xd4 'Ô' */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x3e, /* 0011111 */
+	0x30, /* 0011000 */
+	0x3e, /* 0011111 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 213 0xd5 'Õ' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x3e, /* 0011111 */
+	0x30, /* 0011000 */
+	0x3e, /* 0011111 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+
+	/* 214 0xd6 'Ö' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x7e, /* 0111111 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+
+	/* 215 0xd7 '×' */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0xfe, /* 1111111 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+
+	/* 216 0xd8 'Ø' */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0xfe, /* 1111111 */
+	0x30, /* 0011000 */
+	0xfe, /* 1111111 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+
+	/* 217 0xd9 'Ù' */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0xf0, /* 1111000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 218 0xda 'Ú' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x3e, /* 0011111 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+
+	/* 219 0xdb 'Û' */
+	0xfe, /* 1111111 */
+	0xfe, /* 1111111 */
+	0xfe, /* 1111111 */
+	0xfe, /* 1111111 */
+	0xfe, /* 1111111 */
+	0xfe, /* 1111111 */
+	0xfe, /* 1111111 */
+	0xfe, /* 1111111 */
+	0xfe, /* 1111111 */
+	0xfe, /* 1111111 */
+	0xfe, /* 1111111 */
+	0xfe, /* 1111111 */
+	0xfe, /* 1111111 */
+	0xfe, /* 1111111 */
+
+	/* 220 0xdc 'Ü' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0xfe, /* 1111111 */
+	0xfe, /* 1111111 */
+	0xfe, /* 1111111 */
+	0xfe, /* 1111111 */
+	0xfe, /* 1111111 */
+	0xfe, /* 1111111 */
+	0xfe, /* 1111111 */
+	0xfe, /* 1111111 */
+
+	/* 221 0xdd 'Ý' */
+	0xe0, /* 1110000 */
+	0xe0, /* 1110000 */
+	0xe0, /* 1110000 */
+	0xe0, /* 1110000 */
+	0xe0, /* 1110000 */
+	0xe0, /* 1110000 */
+	0xe0, /* 1110000 */
+	0xe0, /* 1110000 */
+	0xe0, /* 1110000 */
+	0xe0, /* 1110000 */
+	0xe0, /* 1110000 */
+	0xe0, /* 1110000 */
+	0xe0, /* 1110000 */
+	0xe0, /* 1110000 */
+
+	/* 222 0xde 'Þ' */
+	0x1e, /* 0001111 */
+	0x1e, /* 0001111 */
+	0x1e, /* 0001111 */
+	0x1e, /* 0001111 */
+	0x1e, /* 0001111 */
+	0x1e, /* 0001111 */
+	0x1e, /* 0001111 */
+	0x1e, /* 0001111 */
+	0x1e, /* 0001111 */
+	0x1e, /* 0001111 */
+	0x1e, /* 0001111 */
+	0x1e, /* 0001111 */
+	0x1e, /* 0001111 */
+	0x1e, /* 0001111 */
+
+	/* 223 0xdf 'ß' */
+	0xfe, /* 1111111 */
+	0xfe, /* 1111111 */
+	0xfe, /* 1111111 */
+	0xfe, /* 1111111 */
+	0xfe, /* 1111111 */
+	0xfe, /* 1111111 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 224 0xe0 'à' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x76, /* 0111011 */
+	0xdc, /* 1101110 */
+	0xd8, /* 1101100 */
+	0xd8, /* 1101100 */
+	0xd8, /* 1101100 */
+	0xdc, /* 1101110 */
+	0x76, /* 0111011 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 225 0xe1 'á' */
+	0x00, /* 0000000 */
+	0x78, /* 0111100 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xd8, /* 1101100 */
+	0xcc, /* 1100110 */
+	0xc6, /* 1100011 */
+	0xc6, /* 1100011 */
+	0xc6, /* 1100011 */
+	0xcc, /* 1100110 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 226 0xe2 'â' */
+	0x00, /* 0000000 */
+	0xfc, /* 1111110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xc0, /* 1100000 */
+	0xc0, /* 1100000 */
+	0xc0, /* 1100000 */
+	0xc0, /* 1100000 */
+	0xc0, /* 1100000 */
+	0xc0, /* 1100000 */
+	0xc0, /* 1100000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 227 0xe3 'ã' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0xfe, /* 1111111 */
+	0xfe, /* 1111111 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 228 0xe4 'ä' */
+	0x00, /* 0000000 */
+	0xfc, /* 1111110 */
+	0xcc, /* 1100110 */
+	0x60, /* 0110000 */
+	0x30, /* 0011000 */
+	0x18, /* 0001100 */
+	0x18, /* 0001100 */
+	0x30, /* 0011000 */
+	0x60, /* 0110000 */
+	0xcc, /* 1100110 */
+	0xfc, /* 1111110 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 229 0xe5 'å' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x7e, /* 0111111 */
+	0xd8, /* 1101100 */
+	0xd8, /* 1101100 */
+	0xd8, /* 1101100 */
+	0xd8, /* 1101100 */
+	0xd8, /* 1101100 */
+	0x70, /* 0111000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 230 0xe6 'æ' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xf8, /* 1111100 */
+	0xc0, /* 1100000 */
+	0xc0, /* 1100000 */
+	0x80, /* 1000000 */
+
+	/* 231 0xe7 'ç' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x76, /* 0111011 */
+	0xdc, /* 1101110 */
+	0x18, /* 0001100 */
+	0x18, /* 0001100 */
+	0x18, /* 0001100 */
+	0x18, /* 0001100 */
+	0x18, /* 0001100 */
+	0x18, /* 0001100 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 232 0xe8 'è' */
+	0x00, /* 0000000 */
+	0xfc, /* 1111110 */
+	0x30, /* 0011000 */
+	0x78, /* 0111100 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0x78, /* 0111100 */
+	0x30, /* 0011000 */
+	0xfc, /* 1111110 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 233 0xe9 'é' */
+	0x00, /* 0000000 */
+	0x38, /* 0011100 */
+	0x6c, /* 0110110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xfc, /* 1111110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0x6c, /* 0110110 */
+	0x38, /* 0011100 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 234 0xea 'ê' */
+	0x00, /* 0000000 */
+	0x38, /* 0011100 */
+	0x6c, /* 0110110 */
+	0xc6, /* 1100011 */
+	0xc6, /* 1100011 */
+	0xc6, /* 1100011 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0xee, /* 1110111 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 235 0xeb 'ë' */
+	0x00, /* 0000000 */
+	0x3c, /* 0011110 */
+	0x60, /* 0110000 */
+	0x30, /* 0011000 */
+	0x18, /* 0001100 */
+	0x7c, /* 0111110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0x78, /* 0111100 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 236 0xec 'ì' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x7c, /* 0111110 */
+	0xd6, /* 1101011 */
+	0xd6, /* 1101011 */
+	0xd6, /* 1101011 */
+	0x7c, /* 0111110 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 237 0xed 'í' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x06, /* 0000011 */
+	0x0c, /* 0000110 */
+	0x7c, /* 0111110 */
+	0xd6, /* 1101011 */
+	0xd6, /* 1101011 */
+	0xe6, /* 1110011 */
+	0x7c, /* 0111110 */
+	0x60, /* 0110000 */
+	0xc0, /* 1100000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 238 0xee 'î' */
+	0x00, /* 0000000 */
+	0x1c, /* 0001110 */
+	0x30, /* 0011000 */
+	0x60, /* 0110000 */
+	0x60, /* 0110000 */
+	0x7c, /* 0111110 */
+	0x60, /* 0110000 */
+	0x60, /* 0110000 */
+	0x60, /* 0110000 */
+	0x30, /* 0011000 */
+	0x1c, /* 0001110 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 239 0xef 'ï' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x78, /* 0111100 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0xcc, /* 1100110 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 240 0xf0 'ð' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0xfc, /* 1111110 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0xfc, /* 1111110 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0xfc, /* 1111110 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 241 0xf1 'ñ' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0xfc, /* 1111110 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0xfc, /* 1111110 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 242 0xf2 'ò' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x60, /* 0110000 */
+	0x30, /* 0011000 */
+	0x18, /* 0001100 */
+	0x0c, /* 0000110 */
+	0x18, /* 0001100 */
+	0x30, /* 0011000 */
+	0x60, /* 0110000 */
+	0x00, /* 0000000 */
+	0xfc, /* 1111110 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 243 0xf3 'ó' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x18, /* 0001100 */
+	0x30, /* 0011000 */
+	0x60, /* 0110000 */
+	0xc0, /* 1100000 */
+	0x60, /* 0110000 */
+	0x30, /* 0011000 */
+	0x18, /* 0001100 */
+	0x00, /* 0000000 */
+	0xfc, /* 1111110 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 244 0xf4 'ô' */
+	0x00, /* 0000000 */
+	0x1c, /* 0001110 */
+	0x36, /* 0011011 */
+	0x36, /* 0011011 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+
+	/* 245 0xf5 'õ' */
+	0x18, /* 0001100 */
+	0x18, /* 0001100 */
+	0x18, /* 0001100 */
+	0x18, /* 0001100 */
+	0x18, /* 0001100 */
+	0x18, /* 0001100 */
+	0x18, /* 0001100 */
+	0x18, /* 0001100 */
+	0xd8, /* 1101100 */
+	0xd8, /* 1101100 */
+	0xd8, /* 1101100 */
+	0x70, /* 0111000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 246 0xf6 'ö' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x30, /* 0011000 */
+	0x00, /* 0000000 */
+	0xfc, /* 1111110 */
+	0x00, /* 0000000 */
+	0x30, /* 0011000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 247 0xf7 '÷' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x76, /* 0111011 */
+	0xdc, /* 1101110 */
+	0x00, /* 0000000 */
+	0x76, /* 0111011 */
+	0xdc, /* 1101110 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 248 0xf8 'ø' */
+	0x38, /* 0011100 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x38, /* 0011100 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 249 0xf9 'ù' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x30, /* 0011000 */
+	0x30, /* 0011000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 250 0xfa 'ú' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x30, /* 0011000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 251 0xfb 'û' */
+	0x1e, /* 0001111 */
+	0x18, /* 0001100 */
+	0x18, /* 0001100 */
+	0x18, /* 0001100 */
+	0x18, /* 0001100 */
+	0x18, /* 0001100 */
+	0xd8, /* 1101100 */
+	0xd8, /* 1101100 */
+	0xd8, /* 1101100 */
+	0x78, /* 0111100 */
+	0x38, /* 0011100 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 252 0xfc 'ü' */
+	0xd8, /* 1101100 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x6c, /* 0110110 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 253 0xfd 'ý' */
+	0x78, /* 0111100 */
+	0xcc, /* 1100110 */
+	0x18, /* 0001100 */
+	0x30, /* 0011000 */
+	0x64, /* 0110010 */
+	0xfc, /* 1111110 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 254 0xfe 'þ' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x7c, /* 0111110 */
+	0x7c, /* 0111110 */
+	0x7c, /* 0111110 */
+	0x7c, /* 0111110 */
+	0x7c, /* 0111110 */
+	0x7c, /* 0111110 */
+	0x7c, /* 0111110 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+	/* 255 0xff 'ÿ' */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+	0x00, /* 0000000 */
+
+};
+
+
+struct font_desc font_7x14 = {
+	FONT7x14_IDX,
+	"7x14",
+	7,
+	14,
+	fontdata_7x14,
+	0
+};
diff --git a/drivers/video/console/font_sun12x22.c b/drivers/video/console/font_sun12x22.c
--- a/drivers/video/console/font_sun12x22.c
+++ b/drivers/video/console/font_sun12x22.c
@@ -29,24 +29,23 @@ static unsigned char fontdata_sun12x22[F
 	0x00, 0x00, /* 000000000000 */
 
 	/* 1 0x01 '^A' */
-	/* FIXME */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
+	0x1f, 0xc0, /* 000111111100 */
+	0x30, 0x60, /* 001100000110 */
+	0x65, 0x30, /* 011001010011 */
+	0x6d, 0xb0, /* 011011011011 */
+	0x60, 0x30, /* 011000000011 */
+	0x62, 0x30, /* 011000100011 */
+	0x62, 0x30, /* 011000100011 */
+	0x60, 0x30, /* 011000000011 */
+	0x6f, 0xb0, /* 011011111011 */
+	0x67, 0x30, /* 011001110011 */
+	0x30, 0x60, /* 001100000110 */
+	0x1f, 0xc0, /* 000111111100 */
 	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
@@ -54,24 +53,23 @@ static unsigned char fontdata_sun12x22[F
 	0x00, 0x00, /* 000000000000 */
 
 	/* 2 0x02 '^B' */
-	/* FIXME */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
+	0x1f, 0xc0, /* 000111111100 */
+	0x3f, 0xe0, /* 001111111110 */
+	0x7a, 0xf0, /* 011110101111 */
+	0x72, 0x70, /* 011100100111 */
+	0x7f, 0xf0, /* 011111111111 */
+	0x7d, 0xf0, /* 011111011111 */
+	0x7d, 0xf0, /* 011111011111 */
+	0x7f, 0xf0, /* 011111111111 */
+	0x70, 0x70, /* 011100000111 */
+	0x78, 0xf0, /* 011110001111 */
+	0x3f, 0xe0, /* 001111111110 */
+	0x1f, 0xc0, /* 000111111100 */
 	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
@@ -79,24 +77,23 @@ static unsigned char fontdata_sun12x22[F
 	0x00, 0x00, /* 000000000000 */
 
 	/* 3 0x03 '^C' */
-	/* FIXME */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x19, 0x80, /* 000110011000 */
 	0x3f, 0xc0, /* 001111111100 */
+	0x7f, 0xe0, /* 011111111110 */
 	0x3f, 0xc0, /* 001111111100 */
 	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
+	0x1f, 0x80, /* 000111111000 */
+	0x1f, 0x80, /* 000111111000 */
+	0x0f, 0x00, /* 000011110000 */
+	0x0f, 0x00, /* 000011110000 */
+	0x06, 0x00, /* 000001100000 */
+	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
@@ -104,24 +101,23 @@ static unsigned char fontdata_sun12x22[F
 	0x00, 0x00, /* 000000000000 */
 
 	/* 4 0x04 '^D' */
-	/* FIXME */
-	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
+	0x02, 0x00, /* 000000100000 */
+	0x07, 0x00, /* 000001110000 */
+	0x0f, 0x80, /* 000011111000 */
+	0x0f, 0x80, /* 000011111000 */
+	0x1f, 0xc0, /* 000111111100 */
+	0x1f, 0xc0, /* 000111111100 */
+	0x3f, 0xe0, /* 001111111110 */
+	0x1f, 0xc0, /* 000111111100 */
+	0x1f, 0xc0, /* 000111111100 */
+	0x0f, 0x80, /* 000011111000 */
+	0x0f, 0x80, /* 000011111000 */
+	0x07, 0x00, /* 000001110000 */
+	0x02, 0x00, /* 000000100000 */
 	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
@@ -129,24 +125,23 @@ static unsigned char fontdata_sun12x22[F
 	0x00, 0x00, /* 000000000000 */
 
 	/* 5 0x05 '^E' */
-	/* FIXME */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
+	0x02, 0x00, /* 000000100000 */
+	0x07, 0x00, /* 000001110000 */
+	0x07, 0x00, /* 000001110000 */
+	0x02, 0x00, /* 000000100000 */
+	0x18, 0xc0, /* 000110001100 */
+	0x3d, 0xe0, /* 001111011110 */
+	0x3d, 0xe0, /* 001111011110 */
+	0x1a, 0xc0, /* 000110101100 */
+	0x02, 0x00, /* 000000100000 */
+	0x07, 0x00, /* 000001110000 */
+	0x0f, 0x80, /* 000011111000 */
+	0x1f, 0xc0, /* 000111111100 */
 	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
@@ -154,23 +149,22 @@ static unsigned char fontdata_sun12x22[F
 	0x00, 0x00, /* 000000000000 */
 
 	/* 6 0x06 '^F' */
-	/* FIXME */
-	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
+	0x06, 0x00, /* 000001100000 */
+	0x0f, 0x00, /* 000011110000 */
+	0x1f, 0x80, /* 000111111000 */
+	0x1f, 0x80, /* 000111111000 */
 	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
+	0x7f, 0xe0, /* 011111111110 */
+	0x7f, 0xe0, /* 011111111110 */
+	0x36, 0xc0, /* 001101101100 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x0f, 0x00, /* 000011110000 */
+	0x1f, 0x80, /* 000111111000 */
 	0x3f, 0xc0, /* 001111111100 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
@@ -179,24 +173,23 @@ static unsigned char fontdata_sun12x22[F
 	0x00, 0x00, /* 000000000000 */
 
 	/* 7 0x07 '^G' */
-	/* FIXME */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
+	0x06, 0x00, /* 000001100000 */
+	0x0f, 0x00, /* 000011110000 */
+	0x0f, 0x00, /* 000011110000 */
+	0x1f, 0x80, /* 000111111000 */
+	0x1f, 0x80, /* 000111111000 */
 	0x3f, 0xc0, /* 001111111100 */
 	0x3f, 0xc0, /* 001111111100 */
+	0x1f, 0x80, /* 000111111000 */
+	0x1f, 0x80, /* 000111111000 */
+	0x0f, 0x00, /* 000011110000 */
+	0x0f, 0x00, /* 000011110000 */
+	0x06, 0x00, /* 000001100000 */
+	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
@@ -204,49 +197,47 @@ static unsigned char fontdata_sun12x22[F
 	0x00, 0x00, /* 000000000000 */
 
 	/* 8 0x08 '^H' */
-	/* FIXME */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
+	0xff, 0xf0, /* 111111111111 */
+	0xff, 0xf0, /* 111111111111 */
+	0xff, 0xf0, /* 111111111111 */
+	0xff, 0xf0, /* 111111111111 */
+	0xf9, 0xf0, /* 111110011111 */
+	0xf0, 0xf0, /* 111100001111 */
+	0xf0, 0xf0, /* 111100001111 */
+	0xe0, 0x70, /* 111000000111 */
+	0xe0, 0x70, /* 111000000111 */
+	0xc0, 0x30, /* 110000000011 */
+	0xc0, 0x30, /* 110000000011 */
+	0xe0, 0x70, /* 111000000111 */
+	0xe0, 0x70, /* 111000000111 */
+	0xf0, 0xf0, /* 111100001111 */
+	0xf0, 0xf0, /* 111100001111 */
+	0xf9, 0xf0, /* 111110011111 */
+	0xff, 0xf0, /* 111111111111 */
+	0xff, 0xf0, /* 111111111111 */
+	0xff, 0xf0, /* 111111111111 */
+	0xff, 0xf0, /* 111111111111 */
+	0xff, 0xf0, /* 111111111111 */
+	0xff, 0xf0, /* 111111111111 */
 
 	/* 9 0x09 '^I' */
-	/* FIXME */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
+	0x06, 0x00, /* 000001100000 */
+	0x0f, 0x00, /* 000011110000 */
+	0x0f, 0x00, /* 000011110000 */
+	0x19, 0x80, /* 000110011000 */
+	0x19, 0x80, /* 000110011000 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x19, 0x80, /* 000110011000 */
+	0x19, 0x80, /* 000110011000 */
+	0x0f, 0x00, /* 000011110000 */
+	0x0f, 0x00, /* 000011110000 */
+	0x06, 0x00, /* 000001100000 */
 	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
@@ -254,74 +245,71 @@ static unsigned char fontdata_sun12x22[F
 	0x00, 0x00, /* 000000000000 */
 
 	/* 10 0x0a '^J' */
-	/* FIXME */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
+	0xff, 0xf0, /* 111111111111 */
+	0xff, 0xf0, /* 111111111111 */
+	0xff, 0xf0, /* 111111111111 */
+	0xff, 0xf0, /* 111111111111 */
+	0xf9, 0xf0, /* 111110011111 */
+	0xf0, 0xf0, /* 111100001111 */
+	0xf0, 0xf0, /* 111100001111 */
+	0xe6, 0x70, /* 111001100111 */
+	0xe6, 0x70, /* 111001100111 */
+	0xcf, 0x30, /* 110011110011 */
+	0xcf, 0x30, /* 110011110011 */
+	0xe6, 0x70, /* 111001100111 */
+	0xe6, 0x70, /* 111001100111 */
+	0xf0, 0xf0, /* 111100001111 */
+	0xf0, 0xf0, /* 111100001111 */
+	0xf9, 0xf0, /* 111110011111 */
+	0xff, 0xf0, /* 111111111111 */
+	0xff, 0xf0, /* 111111111111 */
+	0xff, 0xf0, /* 111111111111 */
+	0xff, 0xf0, /* 111111111111 */
+	0xff, 0xf0, /* 111111111111 */
+	0xff, 0xf0, /* 111111111111 */
 
 	/* 11 0x0b '^K' */
-	/* FIXME */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
+	0x0f, 0xe0, /* 000011111110 */
+	0x0f, 0xe0, /* 000011111110 */
+	0x01, 0xe0, /* 000000011110 */
+	0x03, 0x60, /* 000000110110 */
+	0x06, 0x60, /* 000001100110 */
+	0x1e, 0x00, /* 000111100000 */
+	0x33, 0x00, /* 001100110000 */
+	0x33, 0x00, /* 001100110000 */
+	0x61, 0x80, /* 011000011000 */
+	0x61, 0x80, /* 011000011000 */
+	0x33, 0x00, /* 001100110000 */
+	0x33, 0x00, /* 001100110000 */
+	0x1e, 0x00, /* 000111100000 */
+	0x0c, 0x00, /* 000011000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 
 	/* 12 0x0c '^L' */
-	/* FIXME */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
+	0x06, 0x00, /* 000001100000 */
+	0x0f, 0x00, /* 000011110000 */
+	0x19, 0x80, /* 000110011000 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x19, 0x80, /* 000110011000 */
+	0x0f, 0x00, /* 000011110000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
 	0x3f, 0xc0, /* 001111111100 */
 	0x3f, 0xc0, /* 001111111100 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
@@ -329,149 +317,143 @@ static unsigned char fontdata_sun12x22[F
 	0x00, 0x00, /* 000000000000 */
 
 	/* 13 0x0d '^M' */
-	/* FIXME */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
+	0x0f, 0xe0, /* 000011111110 */
+	0x0c, 0x60, /* 000011000110 */
+	0x0c, 0x60, /* 000011000110 */
+	0x0f, 0xe0, /* 000011111110 */
+	0x0c, 0x00, /* 000011000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x3c, 0x00, /* 001111000000 */
+	0x7c, 0x00, /* 011111000000 */
+	0x78, 0x00, /* 011110000000 */
+	0x30, 0x00, /* 001100000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 
 	/* 14 0x0e '^N' */
-	/* FIXME */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
+	0x1f, 0xe0, /* 000111111110 */
+	0x18, 0x60, /* 000110000110 */
+	0x18, 0x60, /* 000110000110 */
+	0x1f, 0xe0, /* 000111111110 */
+	0x18, 0x60, /* 000110000110 */
+	0x18, 0x60, /* 000110000110 */
+	0x18, 0x60, /* 000110000110 */
+	0x18, 0x60, /* 000110000110 */
+	0x18, 0x60, /* 000110000110 */
+	0x18, 0x60, /* 000110000110 */
+	0x19, 0xe0, /* 000110011110 */
+	0x1b, 0xe0, /* 000110111110 */
+	0x1b, 0xc0, /* 000110111100 */
+	0x79, 0x80, /* 011110011000 */
+	0xf8, 0x00, /* 111110000000 */
+	0xf0, 0x00, /* 111100000000 */
+	0x60, 0x00, /* 011000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 
 	/* 15 0x0f '^O' */
-	/* FIXME */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
+	0x18, 0xc0, /* 000110001100 */
+	0x0d, 0x80, /* 000011011000 */
+	0x6d, 0xb0, /* 011011011011 */
+	0x3d, 0xe0, /* 001111011110 */
 	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-
-	/* 16 0x10 '^P' */
-	/* FIXME */
-	0x00, 0x00, /* 000000000000 */
+	0x3d, 0xe0, /* 001111011110 */
+	0x6d, 0xb0, /* 011011011011 */
+	0x0d, 0x80, /* 000011011000 */
+	0x18, 0xc0, /* 000110001100 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
+
+	/* 16 0x10 '^P' */
 	0x00, 0x00, /* 000000000000 */
+	0x00, 0x20, /* 000000000010 */
+	0x00, 0x60, /* 000000000110 */
+	0x00, 0xe0, /* 000000001110 */
+	0x01, 0xe0, /* 000000011110 */
+	0x03, 0xe0, /* 000000111110 */
+	0x07, 0xe0, /* 000001111110 */
+	0x0f, 0xe0, /* 000011111110 */
+	0x1f, 0xe0, /* 000111111110 */
+	0x3f, 0xe0, /* 001111111110 */
+	0x7f, 0xe0, /* 011111111110 */
+	0x3f, 0xe0, /* 001111111110 */
+	0x1f, 0xe0, /* 000111111110 */
+	0x0f, 0xe0, /* 000011111110 */
+	0x07, 0xe0, /* 000001111110 */
+	0x03, 0xe0, /* 000000111110 */
+	0x01, 0xe0, /* 000000011110 */
+	0x00, 0xe0, /* 000000001110 */
+	0x00, 0x60, /* 000000000110 */
+	0x00, 0x20, /* 000000000010 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 
 	/* 17 0x11 '^Q' */
-	/* FIXME */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
+	0x40, 0x00, /* 010000000000 */
+	0x60, 0x00, /* 011000000000 */
+	0x70, 0x00, /* 011100000000 */
+	0x78, 0x00, /* 011110000000 */
+	0x7c, 0x00, /* 011111000000 */
+	0x7e, 0x00, /* 011111100000 */
+	0x7f, 0x00, /* 011111110000 */
+	0x7f, 0x80, /* 011111111000 */
+	0x7f, 0xc0, /* 011111111100 */
+	0x7f, 0xe0, /* 011111111110 */
+	0x7f, 0xc0, /* 011111111100 */
+	0x7f, 0x80, /* 011111111000 */
+	0x7f, 0x00, /* 011111110000 */
+	0x7e, 0x00, /* 011111100000 */
+	0x7c, 0x00, /* 011111000000 */
+	0x78, 0x00, /* 011110000000 */
+	0x70, 0x00, /* 011100000000 */
+	0x60, 0x00, /* 011000000000 */
+	0x40, 0x00, /* 010000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 
 	/* 18 0x12 '^R' */
-	/* FIXME */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
+	0x04, 0x00, /* 000001000000 */
+	0x0e, 0x00, /* 000011100000 */
+	0x1f, 0x00, /* 000111110000 */
+	0x3f, 0x80, /* 001111111000 */
+	0x7f, 0xc0, /* 011111111100 */
+	0x0e, 0x00, /* 000011100000 */
+	0x0e, 0x00, /* 000011100000 */
+	0x7f, 0xc0, /* 011111111100 */
+	0x3f, 0x80, /* 001111111000 */
+	0x1f, 0x00, /* 000111110000 */
+	0x0e, 0x00, /* 000011100000 */
+	0x04, 0x00, /* 000001000000 */
 	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
@@ -551,99 +533,95 @@ static unsigned char fontdata_sun12x22[F
 	0x00, 0x00, /* 000000000000 */
 
 	/* 22 0x16 '^V' */
-	/* FIXME */
-	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
-
-	/* 23 0x17 '^W' */
-	/* FIXME */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
+	0x7f, 0xe0, /* 011111111110 */
+	0x7f, 0xe0, /* 011111111110 */
+	0x7f, 0xe0, /* 011111111110 */
 	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 
-	/* 24 0x18 '^X' */
-	/* FIXME */
+	/* 23 0x17 '^W' */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
+	0x04, 0x00, /* 000001000000 */
+	0x0e, 0x00, /* 000011100000 */
+	0x1f, 0x00, /* 000111110000 */
+	0x3f, 0x80, /* 001111111000 */
+	0x7f, 0xc0, /* 011111111100 */
+	0x0e, 0x00, /* 000011100000 */
+	0x0e, 0x00, /* 000011100000 */
+	0x7f, 0xc0, /* 011111111100 */
+	0x3f, 0x80, /* 001111111000 */
+	0x1f, 0x00, /* 000111110000 */
+	0x0e, 0x00, /* 000011100000 */
+	0x04, 0x00, /* 000001000000 */
 	0x00, 0x00, /* 000000000000 */
+	0x7f, 0xe0, /* 011111111110 */
+	0x7f, 0xe0, /* 011111111110 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
+
+	/* 24 0x18 '^X' */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
-
-	/* 25 0x19 '^Y' */
-	/* FIXME */
+	0x04, 0x00, /* 000001000000 */
+	0x0e, 0x00, /* 000011100000 */
+	0x1f, 0x00, /* 000111110000 */
+	0x3f, 0x80, /* 001111111000 */
+	0x7f, 0xc0, /* 011111111100 */
+	0x0e, 0x00, /* 000011100000 */
+	0x0e, 0x00, /* 000011100000 */
+	0x0e, 0x00, /* 000011100000 */
+	0x0e, 0x00, /* 000011100000 */
+	0x0e, 0x00, /* 000011100000 */
+	0x0e, 0x00, /* 000011100000 */
+	0x0e, 0x00, /* 000011100000 */
+	0x0e, 0x00, /* 000011100000 */
+	0x0e, 0x00, /* 000011100000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
+	0x00, 0x00, /* 000000000000 */
+
+	/* 25 0x19 '^Y' */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x0e, 0x00, /* 000011100000 */
+	0x0e, 0x00, /* 000011100000 */
+	0x0e, 0x00, /* 000011100000 */
+	0x0e, 0x00, /* 000011100000 */
+	0x0e, 0x00, /* 000011100000 */
+	0x0e, 0x00, /* 000011100000 */
+	0x0e, 0x00, /* 000011100000 */
+	0x0e, 0x00, /* 000011100000 */
+	0x0e, 0x00, /* 000011100000 */
+	0x0e, 0x00, /* 000011100000 */
+	0x7f, 0xc0, /* 011111111100 */
+	0x3f, 0x80, /* 001111111000 */
+	0x1f, 0x00, /* 000111110000 */
+	0x0e, 0x00, /* 000011100000 */
+	0x04, 0x00, /* 000001000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
@@ -651,24 +629,23 @@ static unsigned char fontdata_sun12x22[F
 	0x00, 0x00, /* 000000000000 */
 
 	/* 26 0x1a '^Z' */
-	/* FIXME */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
+	0x00, 0x00, /* 000000000000 */
+	0x08, 0x00, /* 000010000000 */
+	0x18, 0x00, /* 000110000000 */
+	0x38, 0x00, /* 001110000000 */
+	0x7f, 0xe0, /* 011111111110 */
+	0xff, 0xe0, /* 111111111110 */
+	0x7f, 0xe0, /* 011111111110 */
+	0x38, 0x00, /* 001110000000 */
+	0x18, 0x00, /* 000110000000 */
+	0x08, 0x00, /* 000010000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
@@ -676,24 +653,23 @@ static unsigned char fontdata_sun12x22[F
 	0x00, 0x00, /* 000000000000 */
 
 	/* 27 0x1b '^[' */
-	/* FIXME */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
+	0x00, 0x00, /* 000000000000 */
+	0x01, 0x00, /* 000000010000 */
+	0x01, 0x80, /* 000000011000 */
+	0x01, 0xc0, /* 000000011100 */
+	0x7f, 0xe0, /* 011111111110 */
+	0x7f, 0xf0, /* 011111111111 */
+	0x7f, 0xe0, /* 011111111110 */
+	0x01, 0xc0, /* 000000011100 */
+	0x01, 0x80, /* 000000011000 */
+	0x01, 0x00, /* 000000010000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
@@ -701,24 +677,23 @@ static unsigned char fontdata_sun12x22[F
 	0x00, 0x00, /* 000000000000 */
 
 	/* 28 0x1c '^\' */
-	/* FIXME */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x30, 0x00, /* 001100000000 */
+	0x30, 0x00, /* 001100000000 */
+	0x3f, 0xe0, /* 001111111110 */
+	0x3f, 0xe0, /* 001111111110 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
@@ -726,24 +701,23 @@ static unsigned char fontdata_sun12x22[F
 	0x00, 0x00, /* 000000000000 */
 
 	/* 29 0x1d '^]' */
-	/* FIXME */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
+	0x00, 0x00, /* 000000000000 */
+	0x09, 0x00, /* 000010010000 */
+	0x19, 0x80, /* 000110011000 */
+	0x39, 0xc0, /* 001110011100 */
+	0x7f, 0xe0, /* 011111111110 */
+	0xff, 0xf0, /* 111111111111 */
+	0x7f, 0xe0, /* 011111111110 */
+	0x39, 0xc0, /* 001110011100 */
+	0x19, 0x80, /* 000110011000 */
+	0x09, 0x00, /* 000010010000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
@@ -751,24 +725,23 @@ static unsigned char fontdata_sun12x22[F
 	0x00, 0x00, /* 000000000000 */
 
 	/* 30 0x1e '^^' */
-	/* FIXME */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
+	0x00, 0x00, /* 000000000000 */
+	0x04, 0x00, /* 000001000000 */
+	0x04, 0x00, /* 000001000000 */
+	0x0e, 0x00, /* 000011100000 */
+	0x0e, 0x00, /* 000011100000 */
+	0x1f, 0x00, /* 000111110000 */
+	0x1f, 0x00, /* 000111110000 */
+	0x3f, 0x80, /* 001111111000 */
+	0x3f, 0x80, /* 001111111000 */
+	0x7f, 0xc0, /* 011111111100 */
+	0x7f, 0xc0, /* 011111111100 */
+	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
@@ -776,24 +749,23 @@ static unsigned char fontdata_sun12x22[F
 	0x00, 0x00, /* 000000000000 */
 
 	/* 31 0x1f '^_' */
-	/* FIXME */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
+	0x00, 0x00, /* 000000000000 */
+	0x7f, 0xc0, /* 011111111100 */
+	0x7f, 0xc0, /* 011111111100 */
+	0x3f, 0x80, /* 001111111000 */
+	0x3f, 0x80, /* 001111111000 */
+	0x1f, 0x00, /* 000111110000 */
+	0x1f, 0x00, /* 000111110000 */
+	0x0e, 0x00, /* 000011100000 */
+	0x0e, 0x00, /* 000011100000 */
+	0x04, 0x00, /* 000001000000 */
+	0x04, 0x00, /* 000001000000 */
+	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
@@ -3081,29 +3053,28 @@ static unsigned char fontdata_sun12x22[F
 	0x00, 0x00, /* 000000000000 */
 
 	/* 127 0x7f '.' */
-	/* FIXME */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0xff, 0xf0, /* 111111111111 */
+	0xff, 0xf0, /* 111111111111 */
+	0x00, 0x00, /* 000000000000 */
 
 	/* 128 0x80 '.' */
 	0x00, 0x00, /* 000000000000 */
@@ -3826,24 +3797,23 @@ static unsigned char fontdata_sun12x22[F
 	0x00, 0x00, /* 000000000000 */
 
 	/* 158 0x9e '.' */
-	/* FIXME */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
+	0x7f, 0x80, /* 011111111000 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0x60, /* 001100000110 */
+	0x30, 0x60, /* 001100000110 */
+	0x30, 0x60, /* 001100000110 */
+	0x30, 0xc0, /* 001100001100 */
+	0x37, 0x80, /* 001101111000 */
+	0x30, 0x00, /* 001100000000 */
+	0x33, 0x00, /* 001100110000 */
+	0x37, 0x80, /* 001101111000 */
+	0x33, 0x00, /* 001100110000 */
+	0x33, 0x00, /* 001100110000 */
+	0x33, 0x30, /* 001100110011 */
+	0x31, 0xe0, /* 001100011110 */
+	0x78, 0xc0, /* 011110001100 */
 	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
@@ -3851,28 +3821,27 @@ static unsigned char fontdata_sun12x22[F
 	0x00, 0x00, /* 000000000000 */
 
 	/* 159 0x9f '.' */
-	/* FIXME */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
+	0x00, 0xc0, /* 000000001100 */
+	0x01, 0xe0, /* 000000011110 */
+	0x03, 0x30, /* 000000110011 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x3f, 0xe0, /* 001111111110 */
+	0x7f, 0xc0, /* 011111111100 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0xcc, 0x00, /* 110011000000 */
+	0x78, 0x00, /* 011110000000 */
+	0x30, 0x00, /* 001100000000 */
 	0x00, 0x00, /* 000000000000 */
 
 	/* 160 0xa0 '.' */
@@ -4092,24 +4061,23 @@ static unsigned char fontdata_sun12x22[F
 	0x00, 0x00, /* 000000000000 */
 
 	/* 169 0xa9 '.' */
-	/* FIXME */
-	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x3f, 0xc0, /* 001111111100 */
 	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
+	0x30, 0x00, /* 001100000000 */
+	0x30, 0x00, /* 001100000000 */
+	0x30, 0x00, /* 001100000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
@@ -5413,24 +5381,23 @@ static unsigned char fontdata_sun12x22[F
 	0x00, 0x00, /* 000000000000 */
 
 	/* 224 0xe0 '.' */
-	/* FIXME */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
+	0x00, 0x00, /* 000000000000 */
+	0x0f, 0x60, /* 000011110110 */
+	0x13, 0xe0, /* 000100111110 */
+	0x21, 0xc0, /* 001000011100 */
+	0x60, 0xc0, /* 011000001100 */
+	0x60, 0xc0, /* 011000001100 */
+	0x60, 0xc0, /* 011000001100 */
+	0x60, 0xc0, /* 011000001100 */
+	0x70, 0x80, /* 011100001000 */
+	0x39, 0xc0, /* 001110011100 */
+	0x1f, 0x60, /* 000111110110 */
+	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
@@ -5462,24 +5429,23 @@ static unsigned char fontdata_sun12x22[F
 	0x00, 0x00, /* 000000000000 */
 
 	/* 226 0xe2 '.' */
-	/* FIXME */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
+	0x3f, 0xe0, /* 001111111110 */
+	0x3f, 0xe0, /* 001111111110 */
+	0x30, 0x60, /* 001100000110 */
+	0x30, 0x60, /* 001100000110 */
+	0x30, 0x00, /* 001100000000 */
+	0x30, 0x00, /* 001100000000 */
+	0x30, 0x00, /* 001100000000 */
+	0x30, 0x00, /* 001100000000 */
+	0x30, 0x00, /* 001100000000 */
+	0x30, 0x00, /* 001100000000 */
+	0x30, 0x00, /* 001100000000 */
+	0x30, 0x00, /* 001100000000 */
+	0x30, 0x00, /* 001100000000 */
+	0x30, 0x00, /* 001100000000 */
 	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
@@ -5487,49 +5453,47 @@ static unsigned char fontdata_sun12x22[F
 	0x00, 0x00, /* 000000000000 */
 
 	/* 227 0xe3 '.' */
-	/* FIXME */
-	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
+	0x7f, 0xe0, /* 011111111110 */
+	0x7f, 0xe0, /* 011111111110 */
+	0x19, 0x80, /* 000110011000 */
+	0x19, 0x80, /* 000110011000 */
+	0x19, 0x80, /* 000110011000 */
+	0x19, 0x80, /* 000110011000 */
+	0x19, 0x80, /* 000110011000 */
+	0x19, 0x80, /* 000110011000 */
+	0x19, 0x80, /* 000110011000 */
+	0x19, 0x80, /* 000110011000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
-
-	/* 228 0xe4 '.' */
-	/* FIXME */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
+
+	/* 228 0xe4 '.' */
 	0x00, 0x00, /* 000000000000 */
+	0x7f, 0xe0, /* 011111111110 */
+	0x7f, 0xe0, /* 011111111110 */
+	0x60, 0x60, /* 011000000110 */
+	0x30, 0x60, /* 001100000110 */
+	0x30, 0x00, /* 001100000000 */
+	0x18, 0x00, /* 000110000000 */
+	0x18, 0x00, /* 000110000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x18, 0x00, /* 000110000000 */
+	0x18, 0x00, /* 000110000000 */
+	0x30, 0x00, /* 001100000000 */
+	0x30, 0x60, /* 001100000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x7f, 0xe0, /* 011111111110 */
+	0x7f, 0xe0, /* 011111111110 */
 	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
@@ -5537,24 +5501,23 @@ static unsigned char fontdata_sun12x22[F
 	0x00, 0x00, /* 000000000000 */
 
 	/* 229 0xe5 '.' */
-	/* FIXME */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
+	0x07, 0xe0, /* 000001111110 */
+	0x0f, 0xe0, /* 000011111110 */
+	0x13, 0x80, /* 000100111000 */
+	0x21, 0xc0, /* 001000011100 */
+	0x60, 0xc0, /* 011000001100 */
+	0x60, 0xc0, /* 011000001100 */
+	0x60, 0xc0, /* 011000001100 */
+	0x60, 0xc0, /* 011000001100 */
+	0x70, 0x80, /* 011100001000 */
+	0x39, 0x00, /* 001110010000 */
+	0x1e, 0x00, /* 000111100000 */
+	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
@@ -5586,24 +5549,23 @@ static unsigned char fontdata_sun12x22[F
 	0x00, 0x00, /* 000000000000 */
 
 	/* 231 0xe7 '.' */
-	/* FIXME */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
+	0x19, 0x80, /* 000110011000 */
 	0x3f, 0xc0, /* 001111111100 */
+	0x66, 0x60, /* 011001100110 */
+	0x66, 0x60, /* 011001100110 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
@@ -5611,24 +5573,23 @@ static unsigned char fontdata_sun12x22[F
 	0x00, 0x00, /* 000000000000 */
 
 	/* 232 0xe8 '.' */
-	/* FIXME */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
+	0x7f, 0xe0, /* 011111111110 */
+	0x7f, 0xe0, /* 011111111110 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x0f, 0x00, /* 000011110000 */
+	0x19, 0x80, /* 000110011000 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x19, 0x80, /* 000110011000 */
+	0x0f, 0x00, /* 000011110000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x7f, 0xe0, /* 011111111110 */
+	0x7f, 0xe0, /* 011111111110 */
 	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
@@ -5636,24 +5597,23 @@ static unsigned char fontdata_sun12x22[F
 	0x00, 0x00, /* 000000000000 */
 
 	/* 233 0xe9 '.' */
-	/* FIXME */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
+	0x0f, 0x00, /* 000011110000 */
+	0x1f, 0x80, /* 000111111000 */
+	0x30, 0xc0, /* 001100001100 */
+	0x60, 0x60, /* 011000000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x7f, 0xe0, /* 011111111110 */
+	0x7f, 0xe0, /* 011111111110 */
+	0x60, 0x60, /* 011000000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x30, 0xc0, /* 001100001100 */
+	0x1f, 0x80, /* 000111111000 */
+	0x0f, 0x00, /* 000011110000 */
 	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
@@ -5661,24 +5621,23 @@ static unsigned char fontdata_sun12x22[F
 	0x00, 0x00, /* 000000000000 */
 
 	/* 234 0xea '.' */
-	/* FIXME */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
+	0x1f, 0x00, /* 000111110000 */
+	0x31, 0x80, /* 001100011000 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x60, 0x60, /* 011000000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x19, 0x80, /* 000110011000 */
+	0x19, 0x80, /* 000110011000 */
+	0xd9, 0xb0, /* 110110011011 */
+	0x79, 0xe0, /* 011110011110 */
 	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
@@ -5686,24 +5645,23 @@ static unsigned char fontdata_sun12x22[F
 	0x00, 0x00, /* 000000000000 */
 
 	/* 235 0xeb '.' */
-	/* FIXME */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
+	0x07, 0x80, /* 000001111000 */
+	0x0c, 0xc0, /* 000011001100 */
+	0x18, 0x60, /* 000110000110 */
+	0x18, 0x00, /* 000110000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x06, 0x00, /* 000001100000 */
+	0x03, 0x00, /* 000000110000 */
+	0x0f, 0x80, /* 000011111000 */
+	0x11, 0xc0, /* 000100011100 */
+	0x20, 0xe0, /* 001000001110 */
+	0x60, 0x60, /* 011000000110 */
+	0x60, 0x60, /* 011000000110 */
+	0x70, 0x40, /* 011100000100 */
+	0x38, 0x80, /* 001110001000 */
+	0x1f, 0x00, /* 000111110000 */
 	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
@@ -5711,74 +5669,71 @@ static unsigned char fontdata_sun12x22[F
 	0x00, 0x00, /* 000000000000 */
 
 	/* 236 0xec '.' */
-	/* FIXME */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
+	0x39, 0xc0, /* 001110011100 */
+	0x6f, 0x60, /* 011011110110 */
+	0x66, 0x60, /* 011001100110 */
+	0xc6, 0x30, /* 110001100011 */
+	0xc6, 0x30, /* 110001100011 */
+	0x66, 0x60, /* 011001100110 */
+	0x6f, 0x60, /* 011011110110 */
+	0x39, 0xc0, /* 001110011100 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
-
-	/* 237 0xed '.' */
-	/* FIXME */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
+
+	/* 237 0xed '.' */
 	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
+	0x00, 0xc0, /* 000000001100 */
+	0x00, 0xc0, /* 000000001100 */
+	0x01, 0x80, /* 000000011000 */
+	0x01, 0x80, /* 000000011000 */
+	0x3b, 0xc0, /* 001110111100 */
+	0x6f, 0x60, /* 011011110110 */
+	0x66, 0x60, /* 011001100110 */
+	0xc6, 0x30, /* 110001100011 */
+	0xc6, 0x30, /* 110001100011 */
+	0x66, 0x60, /* 011001100110 */
+	0x6f, 0x60, /* 011011110110 */
+	0x3d, 0xc0, /* 001111011100 */
+	0x18, 0x00, /* 000110000000 */
+	0x18, 0x00, /* 000110000000 */
+	0x30, 0x00, /* 001100000000 */
+	0x30, 0x00, /* 001100000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 
 	/* 238 0xee '.' */
-	/* FIXME */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
+	0x01, 0xc0, /* 000000011100 */
+	0x03, 0x00, /* 000000110000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x18, 0x00, /* 000110000000 */
+	0x1f, 0xc0, /* 000111111100 */
+	0x18, 0x00, /* 000110000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x03, 0x00, /* 000000110000 */
+	0x01, 0xc0, /* 000000011100 */
 	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
@@ -5786,24 +5741,23 @@ static unsigned char fontdata_sun12x22[F
 	0x00, 0x00, /* 000000000000 */
 
 	/* 239 0xef '.' */
-	/* FIXME */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
+	0x0f, 0x00, /* 000011110000 */
+	0x1f, 0x80, /* 000111111000 */
+	0x39, 0xc0, /* 001110011100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
+	0x30, 0xc0, /* 001100001100 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
@@ -5811,24 +5765,23 @@ static unsigned char fontdata_sun12x22[F
 	0x00, 0x00, /* 000000000000 */
 
 	/* 240 0xf0 '.' */
-	/* FIXME */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
+	0x7f, 0xe0, /* 011111111110 */
+	0x7f, 0xe0, /* 011111111110 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x7f, 0xe0, /* 011111111110 */
+	0x7f, 0xe0, /* 011111111110 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x7f, 0xe0, /* 011111111110 */
+	0x7f, 0xe0, /* 011111111110 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
@@ -5860,24 +5813,23 @@ static unsigned char fontdata_sun12x22[F
 	0x00, 0x00, /* 000000000000 */
 
 	/* 242 0xf2 '.' */
-	/* FIXME */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
+	0x60, 0x00, /* 011000000000 */
+	0x38, 0x00, /* 001110000000 */
+	0x0e, 0x00, /* 000011100000 */
+	0x03, 0x80, /* 000000111000 */
+	0x00, 0xe0, /* 000000001110 */
+	0x00, 0xe0, /* 000000001110 */
+	0x03, 0x80, /* 000000111000 */
+	0x0e, 0x00, /* 000011100000 */
+	0x38, 0x00, /* 001110000000 */
+	0x60, 0x00, /* 011000000000 */
 	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
+	0x7f, 0xe0, /* 011111111110 */
+	0x7f, 0xe0, /* 011111111110 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
@@ -5885,24 +5837,23 @@ static unsigned char fontdata_sun12x22[F
 	0x00, 0x00, /* 000000000000 */
 
 	/* 243 0xf3 '.' */
-	/* FIXME */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
+	0x00, 0x60, /* 000000000110 */
+	0x01, 0xc0, /* 000000011100 */
+	0x07, 0x00, /* 000001110000 */
+	0x1c, 0x00, /* 000111000000 */
+	0x70, 0x00, /* 011100000000 */
+	0x70, 0x00, /* 011100000000 */
+	0x1c, 0x00, /* 000111000000 */
+	0x07, 0x00, /* 000001110000 */
+	0x01, 0xc0, /* 000000011100 */
+	0x00, 0x60, /* 000000000110 */
 	0x00, 0x00, /* 000000000000 */
+	0x7f, 0xe0, /* 011111111110 */
+	0x7f, 0xe0, /* 011111111110 */
 	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
@@ -5910,54 +5861,52 @@ static unsigned char fontdata_sun12x22[F
 	0x00, 0x00, /* 000000000000 */
 
 	/* 244 0xf4 '.' */
-	/* FIXME */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
+	0x03, 0x80, /* 000000111000 */
+	0x07, 0xc0, /* 000001111100 */
+	0x0c, 0x60, /* 000011000110 */
+	0x0c, 0x60, /* 000011000110 */
+	0x0c, 0x00, /* 000011000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x0c, 0x00, /* 000011000000 */
+	0x0c, 0x00, /* 000011000000 */
 
 	/* 245 0xf5 '.' */
-	/* FIXME */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
-	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
+	0x1c, 0x00, /* 000111000000 */
+	0x3e, 0x00, /* 001111100000 */
+	0x63, 0x00, /* 011000110000 */
+	0x63, 0x00, /* 011000110000 */
+	0x03, 0x00, /* 000000110000 */
+	0x03, 0x00, /* 000000110000 */
+	0x03, 0x00, /* 000000110000 */
+	0x03, 0x00, /* 000000110000 */
+	0x03, 0x00, /* 000000110000 */
+	0x03, 0x00, /* 000000110000 */
+	0x03, 0x00, /* 000000110000 */
+	0x03, 0x00, /* 000000110000 */
+	0x03, 0x00, /* 000000110000 */
+	0x03, 0x00, /* 000000110000 */
+	0x03, 0x00, /* 000000110000 */
+	0x03, 0x00, /* 000000110000 */
+	0x03, 0x00, /* 000000110000 */
+	0x03, 0x00, /* 000000110000 */
+	0x03, 0x00, /* 000000110000 */
+	0x03, 0x00, /* 000000110000 */
+	0x03, 0x00, /* 000000110000 */
 
 	/* 246 0xf6 '.' */
 	0x00, 0x00, /* 000000000000 */
@@ -5984,24 +5933,23 @@ static unsigned char fontdata_sun12x22[F
 	0x00, 0x00, /* 000000000000 */
 
 	/* 247 0xf7 '.' */
-	/* FIXME */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x38, 0x00, /* 001110000000 */
+	0x6c, 0x00, /* 011011000000 */
+	0x06, 0x30, /* 000001100011 */
+	0x03, 0x60, /* 000000110110 */
+	0x39, 0xc0, /* 001110011100 */
+	0x6c, 0x00, /* 011011000000 */
+	0x06, 0x30, /* 000001100011 */
+	0x03, 0x60, /* 000000110110 */
+	0x01, 0xc0, /* 000000011100 */
+	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
@@ -6033,44 +5981,31 @@ static unsigned char fontdata_sun12x22[F
 	0x00, 0x00, /* 000000000000 */
 
 	/* 249 0xf9 '.' */
-	/* FIXME */
-	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
-
-	/* 250 0xfa '.' */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
+	0x1c, 0x00, /* 000111000000 */
+	0x3e, 0x00, /* 001111100000 */
+	0x3e, 0x00, /* 001111100000 */
+	0x3e, 0x00, /* 001111100000 */
+	0x1c, 0x00, /* 000111000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
+
+	/* 250 0xfa '.' */
 	0x00, 0x00, /* 000000000000 */
-	0x06, 0x00, /* 000001100000 */
-	0x0f, 0x00, /* 000011110000 */
-	0x0f, 0x00, /* 000011110000 */
-	0x06, 0x00, /* 000001100000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
@@ -6080,51 +6015,61 @@ static unsigned char fontdata_sun12x22[F
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
-
-	/* 251 0xfb '.' */
-	/* FIXME */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
+	0x18, 0x00, /* 000110000000 */
+	0x3c, 0x00, /* 001111000000 */
+	0x3c, 0x00, /* 001111000000 */
+	0x18, 0x00, /* 000110000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
+
+	/* 251 0xfb '.' */
 	0x00, 0x00, /* 000000000000 */
+	0x07, 0xe0, /* 000001111110 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x06, 0x00, /* 000001100000 */
+	0xc6, 0x00, /* 110001100000 */
+	0x66, 0x00, /* 011001100000 */
+	0x36, 0x00, /* 001101100000 */
+	0x1e, 0x00, /* 000111100000 */
+	0x0e, 0x00, /* 000011100000 */
+	0x06, 0x00, /* 000001100000 */
+	0x02, 0x00, /* 000000100000 */
 	0x00, 0x00, /* 000000000000 */
 
 	/* 252 0xfc '.' */
-	/* FIXME */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x13, 0x80, /* 000100111000 */
+	0x3d, 0xc0, /* 001111011100 */
+	0x18, 0xc0, /* 000110001100 */
+	0x18, 0xc0, /* 000110001100 */
+	0x18, 0xc0, /* 000110001100 */
+	0x18, 0xc0, /* 000110001100 */
+	0x3d, 0xe0, /* 001111011110 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
+	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
-	0x3f, 0xc0, /* 001111111100 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
 	0x00, 0x00, /* 000000000000 */
diff --git a/drivers/video/console/fonts.c b/drivers/video/console/fonts.c
--- a/drivers/video/console/fonts.c
+++ b/drivers/video/console/fonts.c
@@ -36,6 +36,10 @@ static struct font_desc *fonts[] = {
 #undef NO_FONTS
     &font_vga_6x11,
 #endif
+#ifdef CONFIG_FONT_7x14
+#undef NO_FONTS
+    &font_7x14,
+#endif
 #ifdef CONFIG_FONT_SUN8x16
 #undef NO_FONTS
     &font_sun_8x16,
@@ -44,6 +48,10 @@ static struct font_desc *fonts[] = {
 #undef NO_FONTS
     &font_sun_12x22,
 #endif
+#ifdef CONFIG_FONT_10x18
+#undef NO_FONTS
+    &font_10x18,
+#endif
 #ifdef CONFIG_FONT_ACORN_8x8
 #undef NO_FONTS
     &font_acorn_8x8,
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -95,6 +95,7 @@ static unsigned long vgacon_uni_pagedir[
 /* Description of the hardware situation */
 static unsigned long	vga_vram_base;		/* Base of video memory */
 static unsigned long	vga_vram_end;		/* End of video memory */
+static int		vga_vram_size;		/* Size of video memory */
 static u16		vga_video_port_reg;	/* Video register select port */
 static u16		vga_video_port_val;	/* Video register value port */
 static unsigned int	vga_video_num_columns;	/* Number of text columns */
@@ -288,6 +289,7 @@ static const char __init *vgacon_startup
 
 	vga_vram_base = VGA_MAP_MEM(vga_vram_base);
 	vga_vram_end = VGA_MAP_MEM(vga_vram_end);
+	vga_vram_size = vga_vram_end - vga_vram_base;
 
 	/*
 	 *      Find out if there is a graphics card present.
@@ -504,9 +506,13 @@ static int vgacon_switch(struct vc_data 
 	 */
 	vga_video_num_columns = c->vc_cols;
 	vga_video_num_lines = c->vc_rows;
+
+	/* We can only copy out the size of the video buffer here,
+	 * otherwise we get into VGA BIOS */
+
 	if (!vga_is_gfx)
 		scr_memcpyw((u16 *) c->vc_origin, (u16 *) c->vc_screenbuf,
-			    c->vc_screenbuf_size);
+			    c->vc_screenbuf_size > vga_vram_size ? vga_vram_size : c->vc_screenbuf_size);
 	return 0;		/* Redrawing not needed */
 }
 
@@ -961,7 +967,6 @@ static int vgacon_scrolldelta(struct vc_
 	if (!lines)		/* Turn scrollback off */
 		c->vc_visible_origin = c->vc_origin;
 	else {
-		int vram_size = vga_vram_end - vga_vram_base;
 		int margin = c->vc_size_row * 4;
 		int ul, we, p, st;
 
@@ -971,7 +976,7 @@ static int vgacon_scrolldelta(struct vc_
 			we = vga_rolled_over + c->vc_size_row;
 		} else {
 			ul = 0;
-			we = vram_size;
+			we = vga_vram_size;
 		}
 		p = (c->vc_visible_origin - vga_vram_base - ul + we) % we +
 		    lines * c->vc_size_row;
@@ -1012,9 +1017,13 @@ static void vgacon_save_screen(struct vc
 		c->vc_x = ORIG_X;
 		c->vc_y = ORIG_Y;
 	}
+
+	/* We can't copy in more then the size of the video buffer,
+	 * or we'll be copying in VGA BIOS */
+
 	if (!vga_is_gfx)
 		scr_memcpyw((u16 *) c->vc_screenbuf, (u16 *) c->vc_origin,
-			    c->vc_screenbuf_size);
+			    c->vc_screenbuf_size > vga_vram_size ? vga_vram_size : c->vc_screenbuf_size);
 }
 
 static int vgacon_scroll(struct vc_data *c, int t, int b, int dir,
diff --git a/drivers/video/fbcmap.c b/drivers/video/fbcmap.c
--- a/drivers/video/fbcmap.c
+++ b/drivers/video/fbcmap.c
@@ -212,7 +212,7 @@ int fb_cmap_to_user(struct fb_cmap *from
 
 int fb_set_cmap(struct fb_cmap *cmap, struct fb_info *info)
 {
-	int i, start;
+	int i, start, rc = 0;
 	u16 *red, *green, *blue, *transp;
 	u_int hred, hgreen, hblue, htransp = 0xffff;
 
@@ -225,75 +225,51 @@ int fb_set_cmap(struct fb_cmap *cmap, st
 	if (start < 0 || (!info->fbops->fb_setcolreg &&
 			  !info->fbops->fb_setcmap))
 		return -EINVAL;
-	if (info->fbops->fb_setcmap)
-		return info->fbops->fb_setcmap(cmap, info);
-	for (i = 0; i < cmap->len; i++) {
-		hred = *red++;
-		hgreen = *green++;
-		hblue = *blue++;
-		if (transp)
-			htransp = *transp++;
-		if (info->fbops->fb_setcolreg(start++,
-					      hred, hgreen, hblue, htransp,
-					      info))
-			break;
+	if (info->fbops->fb_setcmap) {
+		rc = info->fbops->fb_setcmap(cmap, info);
+	} else {
+		for (i = 0; i < cmap->len; i++) {
+			hred = *red++;
+			hgreen = *green++;
+			hblue = *blue++;
+			if (transp)
+				htransp = *transp++;
+			if (info->fbops->fb_setcolreg(start++,
+						      hred, hgreen, hblue,
+						      htransp, info))
+				break;
+		}
 	}
-	return 0;
+	if (rc == 0)
+		fb_copy_cmap(cmap, &info->cmap);
+
+	return rc;
 }
 
 int fb_set_user_cmap(struct fb_cmap_user *cmap, struct fb_info *info)
 {
-	int i, start;
-	u16 __user *red, *green, *blue, *transp;
-	u_int hred, hgreen, hblue, htransp = 0xffff;
-
-	red = cmap->red;
-	green = cmap->green;
-	blue = cmap->blue;
-	transp = cmap->transp;
-	start = cmap->start;
+	int rc, size = cmap->len * sizeof(u16);
+	struct fb_cmap umap;
 
-	if (start < 0 || (!info->fbops->fb_setcolreg &&
-			  !info->fbops->fb_setcmap))
+	if (cmap->start < 0 || (!info->fbops->fb_setcolreg &&
+			        !info->fbops->fb_setcmap))
 		return -EINVAL;
 
-	/* If we can batch, do it */
-	if (info->fbops->fb_setcmap && cmap->len > 1) {
-		struct fb_cmap umap;
-		int size = cmap->len * sizeof(u16);
-		int rc;
-
-		memset(&umap, 0, sizeof(struct fb_cmap));
-		rc = fb_alloc_cmap(&umap, cmap->len, transp != NULL);
-		if (rc)
-			return rc;
-		if (copy_from_user(umap.red, red, size) ||
-		    copy_from_user(umap.green, green, size) ||
-		    copy_from_user(umap.blue, blue, size) ||
-		    (transp && copy_from_user(umap.transp, transp, size))) {
-			rc = -EFAULT;
-		}
-		umap.start = start;
-		if (rc == 0)
-			rc = info->fbops->fb_setcmap(&umap, info);
-		fb_dealloc_cmap(&umap);
+	memset(&umap, 0, sizeof(struct fb_cmap));
+	rc = fb_alloc_cmap(&umap, cmap->len, cmap->transp != NULL);
+	if (rc)
 		return rc;
+	if (copy_from_user(umap.red, cmap->red, size) ||
+	    copy_from_user(umap.green, cmap->green, size) ||
+	    copy_from_user(umap.blue, cmap->blue, size) ||
+	    (cmap->transp && copy_from_user(umap.transp, cmap->transp, size))) {
+		fb_dealloc_cmap(&umap);
+		return -EFAULT;
 	}
-
-	for (i = 0; i < cmap->len; i++, red++, blue++, green++) {
-		if (get_user(hred, red) ||
-		    get_user(hgreen, green) ||
-		    get_user(hblue, blue) ||
-		    (transp && get_user(htransp, transp)))
-			return -EFAULT;
-		if (info->fbops->fb_setcolreg(start++,
-					      hred, hgreen, hblue, htransp,
-					      info))
-			return 0;
-		if (transp)
-			transp++;
-	}
-	return 0;
+	umap.start = cmap->start;
+	rc = fb_set_cmap(&umap, info);
+	fb_dealloc_cmap(&umap);
+	return rc;
 }
 
 /**
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -76,70 +76,24 @@ int fb_get_color_depth(struct fb_var_scr
 EXPORT_SYMBOL(fb_get_color_depth);
 
 /*
- * Drawing helpers.
+ * Data padding functions.
  */
-void fb_iomove_buf_aligned(struct fb_info *info, struct fb_pixmap *buf,
-			   u8 *dst, u32 d_pitch, u8 *src, u32 s_pitch,
-			   u32 height)
-{
-	int i;
-
-	for (i = height; i--; ) {
-		buf->outbuf(info, dst, src, s_pitch);
-		src += s_pitch;
-		dst += d_pitch;
-	}
-}
-
-void fb_sysmove_buf_aligned(struct fb_info *info, struct fb_pixmap *buf,
-			    u8 *dst, u32 d_pitch, u8 *src, u32 s_pitch,
-			    u32 height)
+void fb_pad_aligned_buffer(u8 *dst, u32 d_pitch, u8 *src, u32 s_pitch, u32 height)
 {
 	int i, j;
 
 	for (i = height; i--; ) {
+		/* s_pitch is a few bytes at the most, memcpy is suboptimal */
 		for (j = 0; j < s_pitch; j++)
 			dst[j] = src[j];
 		src += s_pitch;
 		dst += d_pitch;
 	}
 }
+EXPORT_SYMBOL(fb_pad_aligned_buffer);
 
-void fb_iomove_buf_unaligned(struct fb_info *info, struct fb_pixmap *buf,
-			     u8 *dst, u32 d_pitch, u8 *src, u32 idx,
-			     u32 height, u32 shift_high, u32 shift_low,
-			     u32 mod)
-{
-	u8 mask = (u8) (0xfff << shift_high), tmp;
-	int i, j;
-
-	for (i = height; i--; ) {
-		for (j = 0; j < idx; j++) {
-			tmp = buf->inbuf(info, dst+j);
-			tmp &= mask;
-			tmp |= *src >> shift_low;
-			buf->outbuf(info, dst+j, &tmp, 1);
-			tmp = *src << shift_high;
-			buf->outbuf(info, dst+j+1, &tmp, 1);
-			src++;
-		}
-		tmp = buf->inbuf(info, dst+idx);
-		tmp &= mask;
-		tmp |= *src >> shift_low;
-		buf->outbuf(info, dst+idx, &tmp, 1);
-		if (shift_high < mod) {
-			tmp = *src << shift_high;
-			buf->outbuf(info, dst+idx+1, &tmp, 1);
-		}	
-		src++;
-		dst += d_pitch;
-	}
-}
-
-void fb_sysmove_buf_unaligned(struct fb_info *info, struct fb_pixmap *buf,
-			      u8 *dst, u32 d_pitch, u8 *src, u32 idx,
-			      u32 height, u32 shift_high, u32 shift_low,
-			      u32 mod)
+void fb_pad_unaligned_buffer(u8 *dst, u32 d_pitch, u8 *src, u32 idx, u32 height,
+				u32 shift_high, u32 shift_low, u32 mod)
 {
 	u8 mask = (u8) (0xfff << shift_high), tmp;
 	int i, j;
@@ -166,6 +120,7 @@ void fb_sysmove_buf_unaligned(struct fb_
 		dst += d_pitch;
 	}
 }
+EXPORT_SYMBOL(fb_pad_unaligned_buffer);
 
 /*
  * we need to lock this section since fb_cursor
@@ -673,7 +628,7 @@ fb_pan_display(struct fb_info *info, str
 int
 fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var)
 {
-	int err;
+	int err, flags = info->flags;
 
 	if (var->activate & FB_ACTIVATE_INV_MODE) {
 		struct fb_videomode mode1, mode2;
@@ -727,7 +682,7 @@ fb_set_var(struct fb_info *info, struct 
 			    !list_empty(&info->modelist))
 				err = fb_add_videomode(&mode, &info->modelist);
 
-			if (!err && info->flags & FBINFO_MISC_USEREVENT) {
+			if (!err && (flags & FBINFO_MISC_USEREVENT)) {
 				struct fb_event event;
 
 				info->flags &= ~FBINFO_MISC_USEREVENT;
@@ -1040,7 +995,7 @@ static struct file_operations fb_fops = 
 #endif
 };
 
-static struct class_simple *fb_class;
+static struct class *fb_class;
 
 /**
  *	register_framebuffer - registers a frame buffer device
@@ -1066,7 +1021,7 @@ register_framebuffer(struct fb_info *fb_
 			break;
 	fb_info->node = i;
 
-	fb_info->class_device = class_simple_device_add(fb_class, MKDEV(FB_MAJOR, i),
+	fb_info->class_device = class_device_create(fb_class, MKDEV(FB_MAJOR, i),
 				    fb_info->device, "fb%d", i);
 	if (IS_ERR(fb_info->class_device)) {
 		/* Not fatal */
@@ -1081,7 +1036,7 @@ register_framebuffer(struct fb_info *fb_
 			fb_info->pixmap.size = FBPIXMAPSIZE;
 			fb_info->pixmap.buf_align = 1;
 			fb_info->pixmap.scan_align = 1;
-			fb_info->pixmap.access_align = 4;
+			fb_info->pixmap.access_align = 32;
 			fb_info->pixmap.flags = FB_PIXMAP_DEFAULT;
 		}
 	}	
@@ -1134,7 +1089,7 @@ unregister_framebuffer(struct fb_info *f
 	registered_fb[i]=NULL;
 	num_registered_fb--;
 	fb_cleanup_class_device(fb_info);
-	class_simple_device_remove(MKDEV(FB_MAJOR, i));
+	class_device_destroy(fb_class, MKDEV(FB_MAJOR, i));
 	return 0;
 }
 
@@ -1197,7 +1152,7 @@ fbmem_init(void)
 	if (register_chrdev(FB_MAJOR,"fb",&fb_fops))
 		printk("unable to get major %d for fb devs\n", FB_MAJOR);
 
-	fb_class = class_simple_create(THIS_MODULE, "graphics");
+	fb_class = class_create(THIS_MODULE, "graphics");
 	if (IS_ERR(fb_class)) {
 		printk(KERN_WARNING "Unable to create fb class; errno = %ld\n", PTR_ERR(fb_class));
 		fb_class = NULL;
@@ -1210,7 +1165,8 @@ module_init(fbmem_init);
 static void __exit
 fbmem_exit(void)
 {
-	class_simple_destroy(fb_class);
+	class_destroy(fb_class);
+	unregister_chrdev(FB_MAJOR, "fb");
 }
 
 module_exit(fbmem_exit);
@@ -1357,10 +1313,6 @@ EXPORT_SYMBOL(fb_set_var);
 EXPORT_SYMBOL(fb_blank);
 EXPORT_SYMBOL(fb_pan_display);
 EXPORT_SYMBOL(fb_get_buffer_offset);
-EXPORT_SYMBOL(fb_iomove_buf_unaligned);
-EXPORT_SYMBOL(fb_iomove_buf_aligned);
-EXPORT_SYMBOL(fb_sysmove_buf_unaligned);
-EXPORT_SYMBOL(fb_sysmove_buf_aligned);
 EXPORT_SYMBOL(fb_set_suspend);
 EXPORT_SYMBOL(fb_register_client);
 EXPORT_SYMBOL(fb_unregister_client);
diff --git a/drivers/video/fbmon.c b/drivers/video/fbmon.c
--- a/drivers/video/fbmon.c
+++ b/drivers/video/fbmon.c
@@ -1241,6 +1241,8 @@ int fb_validate_mode(const struct fb_var
 		vtotal *= 2;
 
 	hfreq = pixclock/htotal;
+	hfreq = (hfreq + 500) / 1000 * 1000;
+
 	vfreq = hfreq/vtotal;
 
 	return (vfreq < vfmin || vfreq > vfmax || 
diff --git a/drivers/video/fbsysfs.c b/drivers/video/fbsysfs.c
--- a/drivers/video/fbsysfs.c
+++ b/drivers/video/fbsysfs.c
@@ -228,8 +228,6 @@ static ssize_t store_virtual(struct clas
 	if (last - buf >= count)
 		return -EINVAL;
 	var.yres_virtual = simple_strtoul(last, &last, 0);
-	printk(KERN_ERR "fb: xres %d yres %d\n", var.xres_virtual,
-	       var.yres_virtual);
 
 	if ((err = activate(fb_info, &var)))
 		return err;
@@ -244,10 +242,68 @@ static ssize_t show_virtual(struct class
 			fb_info->var.yres_virtual);
 }
 
-static ssize_t store_cmap(struct class_device *class_device, const char * buf,
+/* Format for cmap is "%02x%c%4x%4x%4x\n" */
+/* %02x entry %c transp %4x red %4x blue %4x green \n */
+/* 256 rows at 16 chars equals 4096, the normal page size */
+/* the code will automatically adjust for different page sizes */
+static ssize_t store_cmap(struct class_device *class_device, const char *buf,
 			  size_t count)
 {
-//	struct fb_info *fb_info = (struct fb_info *)class_get_devdata(class_device);
+	struct fb_info *fb_info = (struct fb_info *)class_get_devdata(class_device);
+	int rc, i, start, length, transp = 0;
+
+	if ((count > PAGE_SIZE) || ((count % 16) != 0))
+		return -EINVAL;
+
+	if (!fb_info->fbops->fb_setcolreg && !fb_info->fbops->fb_setcmap)
+		return -EINVAL;
+
+	sscanf(buf, "%02x", &start);
+	length = count / 16;
+
+	for (i = 0; i < length; i++)
+		if (buf[i * 16 + 2] != ' ')
+			transp = 1;
+
+	/* If we can batch, do it */
+	if (fb_info->fbops->fb_setcmap && length > 1) {
+		struct fb_cmap umap;
+
+		memset(&umap, 0, sizeof(umap));
+		if ((rc = fb_alloc_cmap(&umap, length, transp)))
+			return rc;
+
+		umap.start = start;
+		for (i = 0; i < length; i++) {
+			sscanf(&buf[i * 16 +  3], "%4hx", &umap.red[i]);
+			sscanf(&buf[i * 16 +  7], "%4hx", &umap.blue[i]);
+			sscanf(&buf[i * 16 + 11], "%4hx", &umap.green[i]);
+			if (transp)
+				umap.transp[i] = (buf[i * 16 +  2] != ' ');
+		}
+		rc = fb_info->fbops->fb_setcmap(&umap, fb_info);
+		fb_copy_cmap(&umap, &fb_info->cmap);
+		fb_dealloc_cmap(&umap);
+
+		return rc;
+	}
+	for (i = 0; i < length; i++) {
+		u16 red, blue, green, tsp;
+
+		sscanf(&buf[i * 16 +  3], "%4hx", &red);
+		sscanf(&buf[i * 16 +  7], "%4hx", &blue);
+		sscanf(&buf[i * 16 + 11], "%4hx", &green);
+		tsp = (buf[i * 16 +  2] != ' ');
+		if ((rc = fb_info->fbops->fb_setcolreg(start++,
+				      red, green, blue, tsp, fb_info)))
+			return rc;
+
+		fb_info->cmap.red[i] = red;
+		fb_info->cmap.blue[i] = blue;
+		fb_info->cmap.green[i] = green;
+		if (transp)
+			fb_info->cmap.transp[i] = tsp;
+	}
 	return 0;
 }
 
@@ -255,20 +311,24 @@ static ssize_t show_cmap(struct class_de
 {
 	struct fb_info *fb_info =
 		(struct fb_info *)class_get_devdata(class_device);
-	unsigned int offset = 0, i;
+	unsigned int i;
 
 	if (!fb_info->cmap.red || !fb_info->cmap.blue ||
-	    fb_info->cmap.green || fb_info->cmap.transp)
+	   !fb_info->cmap.green)
+		return -EINVAL;
+
+	if (fb_info->cmap.len > PAGE_SIZE / 16)
 		return -EINVAL;
 
+	/* don't mess with the format, the buffer is PAGE_SIZE */
+	/* 256 entries at 16 chars per line equals 4096 = PAGE_SIZE */
 	for (i = 0; i < fb_info->cmap.len; i++) {
-		offset += snprintf(buf, PAGE_SIZE - offset,
-				   "%d,%d,%d,%d,%d\n", i + fb_info->cmap.start,
-				   fb_info->cmap.red[i], fb_info->cmap.blue[i],
-				   fb_info->cmap.green[i],
-				   fb_info->cmap.transp[i]);
+		snprintf(&buf[ i * 16], PAGE_SIZE - i * 16, "%02x%c%4x%4x%4x\n", i + fb_info->cmap.start,
+			((fb_info->cmap.transp && fb_info->cmap.transp[i]) ? '*' : ' '),
+			fb_info->cmap.red[i], fb_info->cmap.blue[i],
+			fb_info->cmap.green[i]);
 	}
-	return offset;
+	return 16 * fb_info->cmap.len;
 }
 
 static ssize_t store_blank(struct class_device *class_device, const char * buf,
@@ -354,6 +414,13 @@ static ssize_t show_pan(struct class_dev
 			fb_info->var.xoffset);
 }
 
+static ssize_t show_name(struct class_device *class_device, char *buf)
+{
+	struct fb_info *fb_info = (struct fb_info *)class_get_devdata(class_device);
+
+	return snprintf(buf, PAGE_SIZE, "%s\n", fb_info->fix.id);
+}
+
 static struct class_device_attribute class_device_attrs[] = {
 	__ATTR(bits_per_pixel, S_IRUGO|S_IWUSR, show_bpp, store_bpp),
 	__ATTR(blank, S_IRUGO|S_IWUSR, show_blank, store_blank),
@@ -364,6 +431,7 @@ static struct class_device_attribute cla
 	__ATTR(modes, S_IRUGO|S_IWUSR, show_modes, store_modes),
 	__ATTR(pan, S_IRUGO|S_IWUSR, show_pan, store_pan),
 	__ATTR(virtual_size, S_IRUGO|S_IWUSR, show_virtual, store_virtual),
+	__ATTR(name, S_IRUGO, show_name, NULL),
 };
 
 int fb_init_class_device(struct fb_info *fb_info)
diff --git a/drivers/video/gbefb.c b/drivers/video/gbefb.c
--- a/drivers/video/gbefb.c
+++ b/drivers/video/gbefb.c
@@ -1045,14 +1045,14 @@ static struct fb_ops gbefb_ops = {
  * sysfs
  */
 
-static ssize_t gbefb_show_memsize(struct device *dev, char *buf)
+static ssize_t gbefb_show_memsize(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	return snprintf(buf, PAGE_SIZE, "%d\n", gbe_mem_size);
 }
 
 static DEVICE_ATTR(size, S_IRUGO, gbefb_show_memsize, NULL);
 
-static ssize_t gbefb_show_rev(struct device *device, char *buf)
+static ssize_t gbefb_show_rev(struct device *device, struct device_attribute *attr, char *buf)
 {
 	return snprintf(buf, PAGE_SIZE, "%d\n", gbe_revision);
 }
diff --git a/drivers/video/i810/i810_main.c b/drivers/video/i810/i810_main.c
--- a/drivers/video/i810/i810_main.c
+++ b/drivers/video/i810/i810_main.c
@@ -1885,6 +1885,7 @@ static int __devinit i810fb_init_pci (st
 	memset(info->pixmap.addr, 0, 8*1024);
 	info->pixmap.size = 8*1024;
 	info->pixmap.buf_align = 8;
+	info->pixmap.access_align = 32;
 	info->pixmap.flags = FB_PIXMAP_SYSTEM;
 
 	if ((err = i810_allocate_pci_resource(par, entry))) {
diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c
--- a/drivers/video/imxfb.c
+++ b/drivers/video/imxfb.c
@@ -249,9 +249,6 @@ static void imxfb_enable_controller(stru
 	/* disable hardware cursor */
 	LCDC_CPOS	&= ~(CPOS_CC0 | CPOS_CC1);
 
-	/* fixed burst length (see erratum 11) */
-	LCDC_DMACR = DMACR_BURST | DMACR_HM(8) | DMACR_TM(2);
-
 	LCDC_RMCR = RMCR_LCDC_EN;
 
 	if(fbi->backlight_power)
@@ -359,6 +356,7 @@ static int imxfb_activate_var(struct fb_
 	LCDC_PCR	= fbi->pcr;
 	LCDC_PWMR	= fbi->pwmr;
 	LCDC_LSCR1	= fbi->lscr1;
+	LCDC_DMACR	= fbi->dmacr;
 
 	return 0;
 }
@@ -509,6 +507,7 @@ static int __init imxfb_init_fbinfo(stru
 	fbi->cmap_inverse		= inf->cmap_inverse;
 	fbi->pcr			= inf->pcr;
 	fbi->lscr1			= inf->lscr1;
+	fbi->dmacr			= inf->dmacr;
 	fbi->pwmr			= inf->pwmr;
 	fbi->lcd_power			= inf->lcd_power;
 	fbi->backlight_power		= inf->backlight_power;
@@ -642,12 +641,12 @@ static int imxfb_remove(struct device *d
 {
 	struct platform_device *pdev = to_platform_device(dev);
 	struct fb_info *info = dev_get_drvdata(dev);
+	struct imxfb_info *fbi = info->par;
 	struct resource *res;
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 
-	/* disable LCD controller */
-	LCDC_RMCR &= ~RMCR_LCDC_EN;
+	imxfb_disable_controller(fbi);
 
 	unregister_framebuffer(info);
 
@@ -663,8 +662,9 @@ static int imxfb_remove(struct device *d
 
 void  imxfb_shutdown(struct device * dev)
 {
-	/* disable LCD Controller */
-	LCDC_RMCR &= ~RMCR_LCDC_EN;
+	struct fb_info *info = dev_get_drvdata(dev);
+	struct imxfb_info *fbi = info->par;
+	imxfb_disable_controller(fbi);
 }
 
 static struct device_driver imxfb_driver = {
diff --git a/drivers/video/imxfb.h b/drivers/video/imxfb.h
--- a/drivers/video/imxfb.h
+++ b/drivers/video/imxfb.h
@@ -54,6 +54,7 @@ struct imxfb_info {
 	u_int			pcr;
 	u_int			pwmr;
 	u_int			lscr1;
+	u_int			dmacr;
 	u_int			cmap_inverse:1,
 				cmap_static:1,
 				unused:30;
diff --git a/drivers/video/intelfb/intelfbdrv.c b/drivers/video/intelfb/intelfbdrv.c
--- a/drivers/video/intelfb/intelfbdrv.c
+++ b/drivers/video/intelfb/intelfbdrv.c
@@ -214,7 +214,7 @@ static struct fb_ops intel_fb_ops = {
 
 /* PCI driver module table */
 static struct pci_driver intelfb_driver = {
-	.name =		"Intel(R) " SUPPORTED_CHIPSETS " Framebuffer Driver",
+	.name =		"intelfb",
 	.id_table =	intelfb_pci_table,
 	.probe =	intelfb_pci_register,
 	.remove =	__devexit_p(intelfb_pci_unregister)
@@ -238,12 +238,15 @@ static int noregister   = 0;
 static int probeonly    = 0;
 static int idonly       = 0;
 static int bailearly    = 0;
+static int voffset	= 48;
 static char *mode       = NULL;
 
 module_param(accel, bool, S_IRUGO);
 MODULE_PARM_DESC(accel, "Enable console acceleration");
 module_param(vram, int, S_IRUGO);
 MODULE_PARM_DESC(vram, "System RAM to allocate to framebuffer in MiB");
+module_param(voffset, int, S_IRUGO);
+MODULE_PARM_DESC(voffset, "Offset of framebuffer in MiB");
 module_param(hwcursor, bool, S_IRUGO);
 MODULE_PARM_DESC(hwcursor, "Enable HW cursor");
 module_param(mtrr, bool, S_IRUGO);
@@ -503,6 +506,7 @@ intelfb_pci_register(struct pci_dev *pde
 	struct agp_bridge_data *bridge;
  	int aperture_bar = 0;
  	int mmio_bar = 1;
+	int offset;
 
 	DBG_MSG("intelfb_pci_register\n");
 
@@ -579,23 +583,6 @@ intelfb_pci_register(struct pci_dev *pde
 		return -ENODEV;
 	}
 
-	/* Map the fb and MMIO regions */
-	dinfo->aperture.virtual = (u8 __iomem *)ioremap_nocache
-		(dinfo->aperture.physical, dinfo->aperture.size);
-	if (!dinfo->aperture.virtual) {
-		ERR_MSG("Cannot remap FB region.\n");
-		cleanup(dinfo);
-		return -ENODEV;
-	}
-	dinfo->mmio_base =
-		(u8 __iomem *)ioremap_nocache(dinfo->mmio_base_phys,
-					       INTEL_REG_SIZE);
-	if (!dinfo->mmio_base) {
-		ERR_MSG("Cannot remap MMIO region.\n");
-		cleanup(dinfo);
-		return -ENODEV;
-	}
-
 	/* Get the chipset info. */
 	dinfo->pci_chipset = pdev->device;
 
@@ -626,9 +613,15 @@ intelfb_pci_register(struct pci_dev *pde
 		dinfo->accel = 0;
 	}
 
+	if (MB(voffset) < stolen_size)
+		offset = (stolen_size >> 12);
+	else
+		offset = ROUND_UP_TO_PAGE(MB(voffset))/GTT_PAGE_SIZE;
+
 	/* Framebuffer parameters - Use all the stolen memory if >= vram */
-	if (ROUND_UP_TO_PAGE(stolen_size) >= MB(vram)) {
+	if (ROUND_UP_TO_PAGE(stolen_size) >= ((offset << 12) +  MB(vram))) {
 		dinfo->fb.size = ROUND_UP_TO_PAGE(stolen_size);
+		dinfo->fb.offset = 0;
 		dinfo->fbmem_gart = 0;
 	} else {
 		dinfo->fb.size =  MB(vram);
@@ -661,19 +654,38 @@ intelfb_pci_register(struct pci_dev *pde
 
 	/* set the mem offsets - set them after the already used pages */
 	if (dinfo->accel) {
-		dinfo->ring.offset = (stolen_size >> 12)
-			+ gtt_info.current_memory;
+		dinfo->ring.offset = offset + gtt_info.current_memory;
 	}
 	if (dinfo->hwcursor) {
-		dinfo->cursor.offset = (stolen_size >> 12) +
+		dinfo->cursor.offset = offset +
 			+ gtt_info.current_memory + (dinfo->ring.size >> 12);
 	}
 	if (dinfo->fbmem_gart) {
-		dinfo->fb.offset = (stolen_size >> 12) +
+		dinfo->fb.offset = offset +
 			+ gtt_info.current_memory + (dinfo->ring.size >> 12)
 			+ (dinfo->cursor.size >> 12);
 	}
 
+	/* Map the fb and MMIO regions */
+	/* ioremap only up to the end of used aperture */
+	dinfo->aperture.virtual = (u8 __iomem *)ioremap_nocache
+		(dinfo->aperture.physical, (dinfo->fb.offset << 12)
+		 + dinfo->fb.size);
+	if (!dinfo->aperture.virtual) {
+		ERR_MSG("Cannot remap FB region.\n");
+		cleanup(dinfo);
+		return -ENODEV;
+	}
+
+	dinfo->mmio_base =
+		(u8 __iomem *)ioremap_nocache(dinfo->mmio_base_phys,
+					       INTEL_REG_SIZE);
+	if (!dinfo->mmio_base) {
+		ERR_MSG("Cannot remap MMIO region.\n");
+		cleanup(dinfo);
+		return -ENODEV;
+	}
+
 	/* Allocate memories (which aren't stolen) */
 	if (dinfo->accel) {
 		if (!(dinfo->gtt_ring_mem =
@@ -1083,6 +1095,7 @@ intelfb_set_fbinfo(struct intelfb_info *
 
 	info->pixmap.size = 64*1024;
 	info->pixmap.buf_align = 8;
+	info->pixmap.access_align = 32;
 	info->pixmap.flags = FB_PIXMAP_SYSTEM;
 
 	if (intelfb_init_var(dinfo))
@@ -1293,7 +1306,7 @@ intelfb_set_par(struct fb_info *info)
 
 	intelfb_blank(FB_BLANK_POWERDOWN, info);
 
-	if (dinfo->accel)
+	if (ACCEL(dinfo, info))
 		intelfbhw_2d_stop(dinfo);
 
  	memcpy(hw, &dinfo->save_state, sizeof(*hw));
@@ -1309,7 +1322,7 @@ intelfb_set_par(struct fb_info *info)
 
 	update_dinfo(dinfo, &info->var);
 
-	if (dinfo->accel)
+	if (ACCEL(dinfo, info))
 		intelfbhw_2d_start(dinfo);
 
 	intelfb_pan_display(&info->var, info);
diff --git a/drivers/video/logo/Kconfig b/drivers/video/logo/Kconfig
--- a/drivers/video/logo/Kconfig
+++ b/drivers/video/logo/Kconfig
@@ -63,5 +63,10 @@ config LOGO_SUPERH_CLUT224
 	depends on LOGO && SUPERH
 	default y
 
+config LOGO_M32R_CLUT224
+	bool "224-color M32R Linux logo"
+	depends on LOGO && M32R
+	default y
+
 endmenu
 
diff --git a/drivers/video/logo/Makefile b/drivers/video/logo/Makefile
--- a/drivers/video/logo/Makefile
+++ b/drivers/video/logo/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_LOGO_SUN_CLUT224)		+= logo_
 obj-$(CONFIG_LOGO_SUPERH_MONO)		+= logo_superh_mono.o
 obj-$(CONFIG_LOGO_SUPERH_VGA16)		+= logo_superh_vga16.o
 obj-$(CONFIG_LOGO_SUPERH_CLUT224)	+= logo_superh_clut224.o
+obj-$(CONFIG_LOGO_M32R_CLUT224)		+= logo_m32r_clut224.o
 
 # How to generate logo's
 
diff --git a/drivers/video/logo/logo.c b/drivers/video/logo/logo.c
--- a/drivers/video/logo/logo.c
+++ b/drivers/video/logo/logo.c
@@ -33,6 +33,7 @@ extern const struct linux_logo logo_sun_
 extern const struct linux_logo logo_superh_mono;
 extern const struct linux_logo logo_superh_vga16;
 extern const struct linux_logo logo_superh_clut224;
+extern const struct linux_logo logo_m32r_clut224;
 
 
 const struct linux_logo *fb_find_logo(int depth)
@@ -97,6 +98,10 @@ const struct linux_logo *fb_find_logo(in
 		/* SuperH Linux logo */
 		logo = &logo_superh_clut224;
 #endif
+#ifdef CONFIG_LOGO_M32R_CLUT224
+		/* M32R Linux logo */
+		logo = &logo_m32r_clut224;
+#endif
 	}
 	return logo;
 }
diff --git a/drivers/video/logo/logo_m32r_clut224.ppm b/drivers/video/logo/logo_m32r_clut224.ppm
new file mode 100644
--- /dev/null
+++ b/drivers/video/logo/logo_m32r_clut224.ppm
@@ -0,0 +1,1292 @@
+P3
+# CREATOR: The GIMP's PNM Filter Version 1.0
+#
+# Note: how to convert ppm to pnm(ascii).
+#   $ convert -posterize 224 m32r.ppm - | pnm2asc -f5 >logo_m32r_clut224.ppm
+#
+# convert - imagemagick: /usr/bin/convert
+# pnm2asc - pnm to ascii-pnm format converter
+#   http://www.is.aist.go.jp/etlcdb/util/p2a.htm#English
+
+80 80
+255
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  2 2 3  2 2 3  2 2 3  2 2 3  2 2 3
+  2 2 3  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  2 2 3  2 2 3
+  2 2 3  2 2 3  2 2 3  2 2 3  2 2 3
+  2 2 3  2 2 3  2 2 3  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  2 2 3  2 2 3  2 2 3  2 2 3
+  2 2 3  2 2 3  2 2 3  2 2 3  2 2 3
+  2 2 3  2 2 3  2 2 3  2 2 3  2 2 3
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  2 2 3  2 2 3  2 2 3  2 2 3
+  2 2 3  2 2 3  2 2 3  2 2 3  2 2 3
+  2 2 3  43 43 43  75 75 75  27 27 27  2 2 3
+  2 2 3  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  2 2 3  2 2 3  2 2 3  2 2 3  2 2 3
+  2 2 3  2 2 3  2 2 3  2 2 3  2 2 3
+  2 2 3  59 59 59  123 123 123  67 67 67  27 27 27
+  2 2 3  2 2 3  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  2 2 3  2 2 3  2 2 3  2 2 3  2 2 3
+  2 2 3  2 2 3  2 2 3  2 2 3  2 2 3
+  10 6 3  59 59 59  80 80 80  43 43 43  27 27 27
+  2 2 3  2 2 3  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  2 2 3
+  2 2 3  2 2 3  2 2 3  2 2 3  2 2 3
+  2 2 3  2 2 3  2 2 3  2 2 3  2 2 3
+  2 2 3  19 19 19  2 2 3  2 2 3  2 2 3
+  2 2 3  2 2 3  2 2 3  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  2 2 3
+  2 2 3  2 2 3  2 2 3  2 2 3  2 2 3
+  2 2 3  2 2 3  2 2 3  2 2 3  2 2 3
+  2 2 3  2 2 3  2 2 3  2 2 3  2 2 3
+  2 2 3  2 2 3  2 2 3  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  2 2 3
+  2 2 3  2 2 3  10 6 3  10 6 3  2 2 3
+  2 2 3  2 2 3  2 2 3  2 2 3  2 2 3
+  10 6 3  11 11 11  11 11 11  2 2 3  2 2 3
+  2 2 3  2 2 3  2 2 3  2 2 3  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  2 2 3
+  2 2 3  2 2 3  2 2 3  27 27 27  10 6 3
+  2 2 3  2 2 3  2 2 3  2 2 3  2 2 3
+  19 19 19  2 2 3  2 2 3  51 51 51  2 2 3
+  2 2 3  2 2 3  2 2 3  2 2 3  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  2 2 3
+  2 2 3  123 123 123  196 196 196  115 115 115  2 2 3
+  2 2 3  2 2 3  2 2 3  75 75 75  141 141 140
+  172 172 172  196 196 196  190 189 188  2 2 3  11 11 11
+  2 2 3  2 2 3  2 2 3  2 2 3  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  2 2 3
+  27 27 27  164 164 164  228 228 228  221 221 220  10 6 3
+  2 2 3  2 2 3  2 2 3  172 172 172  245 245 245
+  254 254 252  254 254 252  221 221 220  35 35 35  2 2 3
+  2 2 3  2 2 3  2 2 3  2 2 3  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  2 2 3
+  164 164 164  228 228 228  35 35 35  236 236 236  236 236 236
+  2 2 3  11 11 11  2 2 3  254 254 252  245 245 245
+  2 2 3  75 75 75  245 245 245  245 245 245  2 2 3
+  2 2 3  2 2 3  2 2 3  2 2 3  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  2 2 3
+  212 212 212  2 2 3  51 51 51  11 11 11  245 245 245
+  27 27 27  80 80 80  10 6 3  254 254 252  2 2 3
+  2 2 3  91 91 91  19 19 19  254 254 252  2 2 3
+  2 2 3  2 2 3  2 2 3  2 2 3  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  2 2 3
+  196 196 196  10 6 3  2 2 3  11 11 11  107 107 107
+  49 35 5  57 42 11  31 22 3  236 236 236  2 2 3
+  2 2 3  2 2 3  2 2 3  254 254 252  2 2 3
+  2 2 3  2 2 3  2 2 3  2 2 3  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  2 2 3
+  107 107 107  221 221 220  2 2 3  64 43 7  194 148 10
+  236 188 10  225 180 10  170 126 10  236 188 10  94 86 67
+  2 2 3  2 2 3  204 204 204  236 236 236  2 2 3
+  2 2 3  2 2 3  2 2 3  2 2 3  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  2 2 3
+  2 2 3  228 228 228  182 126 10  218 164 9  236 188 10
+  236 188 10  237 204 14  236 205 40  246 214 48  246 214 48
+  245 189 11  209 156 9  196 196 196  11 11 11  2 2 3
+  2 2 3  2 2 3  2 2 3  2 2 3  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  2 2 3
+  2 2 3  165 114 10  207 148 7  229 172 9  236 180 10
+  236 196 11  237 204 14  242 218 43  246 218 75  246 218 19
+  246 213 13  246 218 19  244 205 11  218 164 9  2 2 3
+  2 2 3  2 2 3  2 2 3  2 2 3  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  2 2 3
+  164 109 5  192 133 7  224 165 9  236 180 10  236 188 10
+  236 196 11  241 212 42  246 218 75  246 218 19  246 218 19
+  246 218 19  236 196 11  150 114 10  229 172 9  2 2 3
+  2 2 3  2 2 3  2 2 3  2 2 3  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  2 2 3
+  165 114 10  201 142 7  229 172 9  242 182 11  236 188 10
+  237 204 14  245 213 67  246 218 19  246 213 13  246 213 13
+  154 119 10  207 148 7  218 164 9  216 156 8  2 2 3
+  2 2 3  2 2 3  2 2 3  2 2 3  2 2 3
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  2 2 3
+  2 2 3  120 78 3  225 180 10  245 189 11  236 205 40
+  241 212 42  241 212 17  237 204 14  148 107 9  182 126 10
+  216 156 8  218 164 9  207 148 7  82 70 43  2 2 3
+  2 2 3  123 123 123  35 35 35  2 2 3  2 2 3
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  2 2 3
+  10 6 3  180 180 180  156 102 5  135 88 5  142 106 7
+  126 98 11  165 114 10  185 132 9  207 148 7  215 150 13
+  199 140 8  188 148 71  196 196 196  190 189 188  2 2 3
+  2 2 3  11 11 11  132 132 132  75 75 75  2 2 3
+  2 2 3  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  2 2 3
+  10 6 3  190 189 188  190 189 188  151 97 5  192 133 7
+  207 148 7  206 142 8  199 140 8  180 121 7  180 132 31
+  190 189 188  190 189 188  212 212 212  212 212 212  107 107 107
+  2 2 3  2 2 3  99 99 99  51 51 51  2 2 3
+  2 2 3  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  2 2 3
+  2 2 3  190 189 188  190 189 188  190 189 188  136 95 7
+  151 97 5  151 97 5  151 97 5  183 156 91  190 189 188
+  190 189 188  228 228 228  254 254 252  254 254 252  221 221 220
+  2 2 3  2 2 3  2 2 3  2 2 3  2 2 3
+  2 2 3  10 6 3  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  2 2 3  2 2 3
+  75 75 75  245 245 245  196 196 196  190 189 188  190 189 188
+  190 189 188  196 196 196  190 189 188  190 189 188  204 204 204
+  236 236 236  254 254 252  254 254 252  254 254 252  254 254 252
+  35 35 35  2 2 3  2 2 3  2 2 3  2 2 3
+  2 2 3  2 2 3  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  2 2 3  27 27 27  2 2 3
+  245 245 245  254 254 252  245 245 245  190 189 188  190 189 188
+  190 189 188  190 189 188  190 189 188  212 212 212  245 245 245
+  254 254 252  254 254 252  254 254 252  254 254 252  254 254 252
+  254 254 252  10 6 3  2 2 3  2 2 3  2 2 3
+  2 2 3  2 2 3  2 2 3  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  2 2 3  2 2 3  132 132 132
+  254 254 252  254 254 252  254 254 252  236 236 236  196 196 196
+  190 189 188  204 204 204  245 245 245  245 245 245  254 254 252
+  254 254 252  254 254 252  254 254 252  254 254 252  254 254 252
+  254 254 252  80 80 80  2 2 3  2 2 3  2 2 3
+  2 2 3  2 2 3  2 2 3  2 2 3  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  2 2 3  2 2 3  2 2 3  254 254 252
+  254 254 252  254 254 252  254 254 252  254 254 252  245 245 245
+  245 245 245  254 254 252  254 254 252  254 254 252  254 254 252
+  254 254 252  254 254 252  254 254 252  254 254 252  254 254 252
+  254 254 252  254 254 252  2 2 3  2 2 3  2 2 3
+  2 2 3  2 2 3  2 2 3  2 2 3  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  2 2 3  2 2 3  2 2 3  212 212 212  245 245 245
+  254 254 252  254 254 252  254 254 252  254 254 252  245 245 245
+  254 254 252  254 254 252  254 254 252  254 254 252  254 254 252
+  254 254 252  254 254 252  254 254 252  254 254 252  254 254 252
+  254 254 252  254 254 252  2 2 3  2 2 3  2 2 3
+  2 2 3  2 2 3  2 2 3  2 2 3  2 2 3
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  2 2 3
+  2 2 3  2 2 3  2 2 3  204 204 204  245 245 245
+  254 254 252  254 254 252  254 254 252  254 254 252  254 254 252
+  245 245 245  254 254 252  254 254 252  254 254 252  254 254 252
+  254 254 252  254 254 252  254 254 252  254 254 252  254 254 252
+  245 245 245  236 236 236  2 2 3  2 2 3  2 2 3
+  2 2 3  2 2 3  2 2 3  2 2 3  2 2 3
+  2 2 3  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  2 2 3  2 2 3
+  2 2 3  2 2 3  11 11 11  164 164 164  212 212 212
+  236 236 236  245 245 245  254 254 252  236 236 236  221 221 220
+  221 221 220  228 228 228  245 245 245  245 245 245  245 245 245
+  236 236 236  221 221 220  212 212 212  204 204 204  204 204 204
+  196 196 196  204 204 204  59 59 59  2 2 3  2 2 3
+  2 2 3  2 2 3  2 2 3  2 2 3  2 2 3
+  2 2 3  2 2 3  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  2 2 3  2 2 3
+  2 2 3  2 2 3  27 27 27  172 172 172  212 212 212
+  236 236 236  254 254 252  254 254 252  254 254 252  228 228 228
+  254 254 252  254 254 252  254 254 252  254 254 252  254 254 252
+  254 254 252  245 245 245  221 221 220  204 204 204  196 196 196
+  196 196 196  196 196 196  228 228 228  19 19 19  2 2 3
+  80 80 80  2 2 3  2 2 3  2 2 3  2 2 3
+  2 2 3  2 2 3  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  2 2 3  2 2 3  2 2 3
+  11 11 11  2 2 3  164 164 164  236 236 236  254 254 252
+  254 254 252  254 254 252  254 254 252  254 254 252  245 245 245
+  254 254 252  254 254 252  254 254 252  254 254 252  254 254 252
+  254 254 252  254 254 252  254 254 252  254 254 252  254 254 252
+  236 236 236  212 212 212  196 196 196  245 245 245  2 2 3
+  2 2 3  11 11 11  51 51 51  2 2 3  2 2 3
+  2 2 3  2 2 3  2 2 3  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  2 2 3  2 2 3  86 86 83
+  2 2 3  27 27 27  236 236 236  254 254 252  254 254 252
+  245 245 245  254 254 252  254 254 252  254 254 252  254 254 252
+  254 254 252  254 254 252  254 254 252  254 254 252  254 254 252
+  254 254 252  254 254 252  254 254 252  254 254 252  254 254 252
+  254 254 252  254 254 252  212 212 212  196 196 196  91 91 91
+  2 2 3  2 2 3  2 2 3  11 11 11  2 2 3
+  2 2 3  2 2 3  2 2 3  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  2 2 3  2 2 3  2 2 3
+  2 2 3  245 245 245  254 254 252  254 254 252  254 254 252
+  254 254 252  254 254 252  254 254 252  254 254 252  245 245 245
+  254 254 252  245 245 245  254 254 252  254 254 252  254 254 252
+  254 254 252  245 245 245  254 254 252  254 254 252  254 254 252
+  254 254 252  254 254 252  254 254 252  221 221 220  245 245 245
+  2 2 3  11 11 11  43 43 43  19 19 19  10 6 3
+  2 2 3  2 2 3  2 2 3  2 2 3  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  2 2 3  80 80 80  2 2 3
+  2 2 3  254 254 252  254 254 252  254 254 252  254 254 252
+  254 254 252  254 254 252  254 254 252  254 254 252  254 254 252
+  245 245 245  254 254 252  254 254 252  254 254 252  254 254 252
+  254 254 252  254 254 252  254 254 252  254 254 252  254 254 252
+  254 254 252  254 254 252  254 254 252  254 254 252  254 254 252
+  43 43 43  27 27 27  80 80 80  19 19 19  80 80 80
+  2 2 3  2 2 3  2 2 3  2 2 3  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  2 2 3  2 2 3  2 2 3  2 2 3
+  245 245 245  254 254 252  254 254 252  17 11 233  254 254 252
+  254 254 252  254 254 252  254 254 252  236 236 236  17 11 233
+  17 11 233  254 254 252  254 254 252  254 254 252  254 254 252
+  254 254 252  254 254 252  254 254 252  254 254 252  245 245 245
+  254 254 252  254 254 252  254 254 252  254 254 252  254 254 252
+  254 254 252  11 11 11  11 11 11  2 2 3  2 2 3
+  2 2 3  2 2 3  2 2 3  2 2 3  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  2 2 3  67 67 67  2 2 3  19 19 19
+  254 254 252  254 254 252  245 245 245  17 11 233  245 245 245
+  254 254 252  254 254 252  17 11 233  228 228 228  17 11 233
+  17 11 233  17 11 233  17 11 233  254 254 252  17 11 233
+  17 11 233  254 254 252  254 254 252  17 11 233  17 11 233
+  17 11 233  254 254 252  254 254 252  254 254 252  254 254 252
+  254 254 252  2 2 3  2 2 3  2 2 3  2 2 3
+  11 11 11  2 2 3  2 2 3  2 2 3  2 2 3
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  2 2 3  10 6 3  11 11 11  2 2 3  228 228 228
+  254 254 252  254 254 252  254 254 252  17 11 233  254 254 252
+  254 254 252  17 11 233  17 11 233  17 11 233  245 245 245
+  254 254 252  254 254 252  17 11 233  17 11 233  17 11 233
+  17 11 233  17 11 233  254 254 252  17 11 233  17 11 233
+  17 11 233  17 11 233  254 254 252  254 254 252  254 254 252
+  254 254 252  2 2 3  2 2 3  2 2 3  2 2 3
+  27 27 27  2 2 3  2 2 3  2 2 3  2 2 3
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  2 2 3  2 2 3  2 2 3  2 2 3  254 254 252
+  254 254 252  254 254 252  254 254 252  17 11 233  17 11 233
+  17 11 233  17 11 233  17 11 233  17 11 233  254 254 252
+  17 11 233  17 11 233  17 11 233  254 254 252  254 254 252
+  17 11 233  17 11 233  254 254 252  17 11 233  17 11 233
+  254 254 252  17 11 233  254 254 252  254 254 252  254 254 252
+  254 254 252  2 2 3  2 2 3  2 2 3  2 2 3
+  11 11 11  2 2 3  2 2 3  2 2 3  2 2 3
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  2 2 3
+  2 2 3  19 19 19  2 2 3  2 2 3  254 254 252
+  254 254 252  254 254 252  17 11 233  245 245 245  17 11 233
+  17 11 233  245 245 245  254 254 252  17 11 233  254 254 252
+  17 11 233  17 11 233  17 11 233  254 254 252  254 254 252
+  17 11 233  17 11 233  254 254 252  17 11 233  17 11 233
+  17 11 233  17 11 233  254 254 252  254 254 252  254 254 252
+  254 254 252  2 2 3  2 2 3  2 2 3  2 2 3
+  2 2 3  2 2 3  2 2 3  2 2 3  2 2 3
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  2 2 3
+  2 2 3  19 19 19  2 2 3  19 19 19  254 254 252
+  254 254 252  245 245 245  17 11 233  254 254 252  17 11 233
+  17 11 233  254 254 252  254 254 252  17 11 233  254 254 252
+  254 254 252  254 254 252  17 11 233  17 11 233  254 254 252
+  17 11 233  17 11 233  254 254 252  17 11 233  17 11 233
+  17 11 233  17 11 233  17 11 233  254 254 252  254 254 252
+  254 254 252  2 2 3  2 2 3  2 2 3  2 2 3
+  2 2 3  2 2 3  2 2 3  2 2 3  2 2 3
+  2 2 3  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  2 2 3  2 2 3
+  2 2 3  43 43 43  2 2 3  43 43 43  254 254 252
+  245 245 245  254 254 252  17 11 233  254 254 252  17 11 233
+  254 254 252  254 254 252  254 254 252  17 11 233  17 11 233
+  17 11 233  17 11 233  17 11 233  254 254 252  17 11 233
+  17 11 233  17 11 233  17 11 233  17 11 233  17 11 233
+  245 245 245  254 254 252  17 11 233  254 254 252  254 254 252
+  245 245 245  2 2 3  2 2 3  2 2 3  11 11 11
+  2 2 3  2 2 3  2 2 3  2 2 3  2 2 3
+  2 2 3  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  2 2 3  2 2 3
+  2 2 3  75 75 75  2 2 3  99 99 99  254 254 252
+  254 254 252  254 254 252  17 11 233  254 254 252  254 254 252
+  254 254 252  254 254 252  245 245 245  228 228 228  254 254 252
+  254 254 252  17 11 233  245 245 245  254 254 252  254 254 252
+  254 254 252  254 254 252  254 254 252  17 11 233  17 11 233
+  254 254 252  254 254 252  254 254 252  254 254 252  254 254 252
+  254 254 252  2 2 3  2 2 3  2 2 3  75 75 75
+  2 2 3  2 2 3  2 2 3  2 2 3  2 2 3
+  2 2 3  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  2 2 3  2 2 3
+  2 2 3  2 2 3  11 11 11  107 107 107  254 254 252
+  254 254 252  254 254 252  254 254 252  254 254 252  254 254 252
+  245 245 245  254 254 252  245 245 245  236 236 236  254 254 252
+  254 254 252  254 254 252  254 254 252  254 254 252  254 254 252
+  254 254 252  254 254 252  254 254 252  254 254 252  245 245 245
+  254 254 252  254 254 252  254 254 252  254 254 252  254 254 252
+  254 254 252  2 2 3  2 2 3  11 11 11  19 19 19
+  11 11 11  2 2 3  2 2 3  2 2 3  2 2 3
+  2 2 3  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  2 2 3  11 11 11
+  140 102 3  11 11 11  10 6 3  67 67 67  254 254 252
+  245 245 245  245 245 245  254 254 252  254 254 252  245 245 245
+  254 254 252  254 254 252  245 245 245  228 228 228  254 254 252
+  254 254 252  254 254 252  254 254 252  254 254 252  254 254 252
+  254 254 252  245 245 245  254 254 252  254 254 252  245 245 245
+  254 254 252  254 254 252  254 254 252  254 254 252  254 254 252
+  254 254 252  2 2 3  43 43 43  2 2 3  2 2 3
+  2 2 3  11 11 11  67 67 67  11 11 11  2 2 3
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  185 132 9  242 182 11
+  245 189 11  245 189 11  49 35 5  2 2 3  228 228 228
+  254 254 252  254 254 252  254 254 252  245 245 245  254 254 252
+  254 254 252  254 254 252  254 254 252  228 228 228  245 245 245
+  254 254 252  254 254 252  254 254 252  254 254 252  254 254 252
+  254 254 252  254 254 252  254 254 252  254 254 252  254 254 252
+  254 254 252  254 254 252  254 254 252  245 238 222  232 189 94
+  226 186 99  43 43 43  2 2 3  2 2 3  2 2 3
+  2 2 3  2 2 3  2 2 3  59 59 59  2 2 3
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  216 156 8  236 180 22
+  245 189 11  245 189 11  245 189 11  49 35 5  11 11 11
+  212 212 212  245 245 245  254 254 252  254 254 252  254 254 252
+  254 254 252  254 254 252  245 245 245  228 228 228  254 254 252
+  245 245 245  254 254 252  254 254 252  254 254 252  254 254 252
+  254 254 252  254 254 252  254 254 252  254 254 252  254 254 252
+  245 245 245  254 254 252  254 254 252  229 172 9  246 218 19
+  246 218 19  41 27 3  2 2 3  2 2 3  2 2 3
+  2 2 3  2 2 3  19 19 19  27 27 27  196 154 14
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  199 140 8  229 172 9  242 182 11
+  245 189 11  245 189 11  245 189 11  244 196 10  2 2 3
+  2 2 3  115 115 115  254 254 252  254 254 252  254 254 252
+  254 254 252  254 254 252  245 245 245  228 228 228  254 254 252
+  254 254 252  245 245 245  254 254 252  254 254 252  254 254 252
+  254 254 252  254 254 252  254 254 252  254 254 252  254 254 252
+  254 254 252  254 254 252  254 254 252  224 165 9  245 189 11
+  236 196 11  19 19 19  2 2 3  2 2 3  2 2 3
+  2 2 3  2 2 3  2 2 3  11 11 11  236 196 11
+  244 205 11  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  182 126 10  209 156 9  215 150 13
+  193 140 10  207 148 24  216 156 8  242 182 11  245 189 11
+  245 189 11  245 189 11  245 189 11  245 189 11  209 156 9
+  2 2 3  2 2 3  43 43 43  254 254 252  254 254 252
+  254 254 252  254 254 252  254 254 252  254 254 252  245 245 245
+  254 254 252  254 254 252  254 254 252  254 254 252  245 245 245
+  254 254 252  254 254 252  254 254 252  254 254 252  254 254 252
+  254 254 252  254 254 252  236 236 236  216 156 8  245 189 11
+  229 172 9  64 43 7  2 2 3  2 2 3  2 2 3
+  2 2 3  2 2 3  2 2 3  207 148 7  236 188 10
+  245 189 11  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  180 121 7  216 156 8  242 182 11  236 180 10
+  229 172 9  242 182 11  242 182 11  245 189 11  245 189 11
+  245 189 11  245 189 11  245 189 11  245 189 11  237 204 14
+  170 126 10  2 2 3  2 2 3  11 11 11  236 236 236
+  254 254 252  254 254 252  254 254 252  254 254 252  254 254 252
+  254 254 252  254 254 252  254 254 252  254 254 252  254 254 252
+  254 254 252  254 254 252  254 254 252  254 254 252  254 254 252
+  254 254 252  204 204 204  196 196 196  216 156 8  236 180 10
+  224 165 9  182 126 10  73 48 6  2 2 3  2 2 3
+  2 2 3  41 27 3  199 140 8  229 172 9  236 180 10
+  245 189 11  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  185 132 9  229 172 9  245 189 11  245 189 11
+  245 189 11  245 189 11  245 189 11  245 189 11  245 189 11
+  245 189 11  245 189 11  245 189 11  245 189 11  245 189 11
+  226 188 11  2 2 3  2 2 3  2 2 3  11 11 11
+  245 245 245  254 254 252  254 254 252  254 254 252  254 254 252
+  254 254 252  245 245 245  254 254 252  254 254 252  254 254 252
+  254 254 252  254 254 252  254 254 252  254 254 252  254 254 252
+  254 254 252  196 196 196  196 196 196  215 150 13  236 180 10
+  229 172 9  201 142 7  185 132 9  180 121 7  173 120 10
+  180 121 7  192 133 7  229 172 9  242 182 11  245 189 11
+  245 189 11  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  180 126 47  224 165 9  245 189 11  245 189 11
+  245 189 11  245 189 11  245 189 11  245 189 11  245 189 11
+  245 189 11  245 189 11  245 189 11  245 189 11  245 189 11
+  236 188 10  193 140 10  2 2 3  2 2 3  2 2 3
+  2 2 3  212 212 212  254 254 252  245 245 245  245 245 245
+  254 254 252  254 254 252  254 254 252  245 245 245  254 254 252
+  254 254 252  254 254 252  254 254 252  254 254 252  254 254 252
+  254 254 252  204 204 204  196 196 196  199 140 8  229 172 9
+  236 180 10  218 164 9  215 150 13  207 148 7  207 148 7
+  216 156 8  229 172 9  245 189 11  245 189 11  245 189 11
+  245 189 11  242 182 11  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  185 132 9  216 156 8  242 182 11  245 189 11
+  245 189 11  245 189 11  245 189 11  245 189 11  245 189 11
+  245 189 11  245 189 11  245 189 11  245 189 11  245 189 11
+  245 189 11  236 196 11  19 19 19  2 2 3  2 2 3
+  2 2 3  11 11 11  254 254 252  254 254 252  254 254 252
+  254 254 252  254 254 252  254 254 252  254 254 252  254 254 252
+  254 254 252  254 254 252  245 245 245  254 254 252  254 254 252
+  245 245 245  221 221 220  196 196 196  185 132 9  229 172 9
+  242 182 11  229 172 9  224 165 9  218 164 9  224 165 9
+  229 172 9  236 180 10  245 189 11  245 189 11  245 189 11
+  245 189 11  236 180 22  242 182 11  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  236 180 22  245 189 11
+  245 189 11  245 189 11  245 189 11  245 189 11  245 189 11
+  245 189 11  245 189 11  245 189 11  245 189 11  245 189 11
+  245 189 11  236 188 10  225 180 10  2 2 3  2 2 3
+  2 2 3  11 11 11  254 254 252  254 254 252  254 254 252
+  254 254 252  254 254 252  254 254 252  254 254 252  254 254 252
+  254 254 252  254 254 252  254 254 252  254 254 252  254 254 252
+  254 254 252  221 221 220  19 19 19  185 132 9  224 165 9
+  245 189 11  245 189 11  242 182 11  236 180 10  236 180 10
+  242 182 11  242 182 11  245 189 11  245 189 11  245 189 11
+  245 189 11  245 189 11  245 189 11  245 189 11  196 154 14
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  207 148 7  236 180 22  245 189 11
+  245 189 11  245 189 11  245 189 11  245 189 11  245 189 11
+  245 189 11  245 189 11  245 189 11  245 189 11  242 182 11
+  245 189 11  245 189 11  237 204 14  135 88 5  2 2 3
+  27 27 27  254 254 252  254 254 252  254 254 252  254 254 252
+  254 254 252  245 245 245  254 254 252  254 254 252  245 245 245
+  254 254 252  254 254 252  254 254 252  254 254 252  254 254 252
+  254 254 252  67 67 67  19 13 3  185 132 9  229 172 9
+  242 182 11  245 189 11  245 189 11  245 189 11  245 189 11
+  245 189 11  245 189 11  245 189 11  245 189 11  245 189 11
+  245 189 11  245 189 11  245 189 11  245 189 11  245 189 11
+  236 180 22  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  245 189 11  242 182 11
+  242 182 11  245 189 11  245 189 11  245 189 11  245 189 11
+  245 189 11  245 189 11  245 189 11  245 189 11  245 189 11
+  245 189 11  245 189 11  236 188 10  226 188 11  104 83 48
+  254 254 252  254 254 252  254 254 252  254 254 252  245 245 245
+  254 254 252  254 254 252  245 245 245  254 254 252  245 245 245
+  254 254 252  245 245 245  254 254 252  254 254 252  254 254 252
+  2 2 3  2 2 3  56 38 5  185 132 9  229 172 9
+  245 189 11  245 189 11  245 189 11  245 189 11  245 189 11
+  245 189 11  245 189 11  245 189 11  245 189 11  245 189 11
+  245 189 11  245 189 11  245 189 11  245 189 11  242 182 11
+  229 172 9  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  182 126 10  215 150 13  242 182 11  245 189 11
+  245 189 11  245 189 11  245 189 11  245 189 11  245 189 11
+  245 189 11  245 189 11  245 189 11  245 189 11  245 189 11
+  245 189 11  242 182 11  245 189 11  236 196 11  216 156 8
+  254 254 252  254 254 252  254 254 252  254 254 252  254 254 252
+  254 254 252  254 254 252  254 254 252  254 254 252  254 254 252
+  254 254 252  254 254 252  254 254 252  245 245 245  2 2 3
+  2 2 3  2 2 3  75 54 3  182 126 10  229 172 9
+  242 182 11  245 189 11  245 189 11  245 189 11  245 189 11
+  245 189 11  245 189 11  245 189 11  245 189 11  245 189 11
+  245 189 11  245 189 11  245 189 11  245 189 11  229 172 9
+  207 148 24  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  192 133 7  229 172 9  242 182 11  245 189 11
+  245 189 11  245 189 11  245 189 11  245 189 11  245 189 11
+  245 189 11  245 189 11  245 189 11  245 189 11  245 189 11
+  245 189 11  245 189 11  242 182 11  225 180 10  224 165 9
+  107 69 5  245 245 245  254 254 252  254 254 252  254 254 252
+  254 254 252  254 254 252  254 254 252  254 254 252  254 254 252
+  254 254 252  236 236 236  2 2 3  2 2 3  2 2 3
+  2 2 3  2 2 3  91 67 9  182 126 10  229 172 9
+  245 189 11  245 189 11  245 189 11  245 189 11  245 189 11
+  245 189 11  245 189 11  245 189 11  245 189 11  245 189 11
+  245 189 11  242 182 11  242 182 11  216 156 8  180 126 47
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  206 142 8  224 165 9  245 189 11  242 182 11
+  245 189 11  245 189 11  245 189 11  245 189 11  245 189 11
+  245 189 11  245 189 11  245 189 11  245 189 11  242 182 11
+  245 189 11  245 189 11  242 182 11  242 182 11  216 156 8
+  156 102 5  19 13 3  43 43 43  196 196 196  254 254 252
+  245 245 245  254 254 252  254 254 252  204 204 204  51 51 51
+  2 2 3  2 2 3  2 2 3  2 2 3  2 2 3
+  2 2 3  2 2 3  95 62 5  185 132 9  229 172 9
+  242 182 11  245 189 11  245 189 11  245 189 11  245 189 11
+  245 189 11  245 189 11  242 182 11  245 189 11  245 189 11
+  236 180 22  216 156 8  206 142 8  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  192 133 7  215 150 13  229 172 9  229 172 9
+  236 180 10  236 180 22  242 182 11  242 182 11  245 189 11
+  245 189 11  245 189 11  245 189 11  245 189 11  245 189 11
+  245 189 11  245 189 11  245 189 11  229 172 9  216 156 8
+  156 102 5  83 54 6  2 2 3  2 2 3  2 2 3
+  2 2 3  2 2 3  2 2 3  2 2 3  2 2 3
+  2 2 3  2 2 3  2 2 3  2 2 3  2 2 3
+  2 2 3  2 2 3  115 73 3  185 132 9  229 172 9
+  242 182 11  245 189 11  245 189 11  245 189 11  245 189 11
+  245 189 11  242 182 11  229 172 9  229 172 9  216 156 8
+  180 121 7  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  180 121 7  182 126 10  192 133 7  199 140 8
+  207 148 7  215 150 13  216 156 8  224 165 9  229 172 9
+  236 180 22  245 189 11  242 182 11  245 189 11  242 182 11
+  245 189 11  245 189 11  242 182 11  229 172 9  199 140 8
+  151 97 5  101 67 7  2 2 3  2 2 3  2 2 3
+  2 2 3  2 2 3  2 2 3  2 2 3  2 2 3
+  2 2 3  2 2 3  2 2 3  2 2 3  2 2 3
+  2 2 3  2 2 3  115 73 3  180 121 7  216 156 8
+  236 180 22  242 182 11  245 189 11  245 189 11  242 182 11
+  236 180 10  224 165 9  215 150 13  206 142 8  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  156 102 5  164 109 5  172 114 5  180 121 7  180 121 7
+  192 133 7  201 142 7  216 156 8  224 165 9  236 180 22
+  245 189 11  242 182 11  229 172 9  201 142 7  172 114 5
+  125 83 5  83 54 6  2 2 3  2 2 3  2 2 3
+  2 2 3  2 2 3  2 2 3  2 2 3  2 2 3
+  2 2 3  2 2 3  2 2 3  2 2 3  2 2 3
+  2 2 3  2 2 3  91 58 5  156 102 5  192 133 7
+  216 156 8  229 172 9  236 180 10  236 180 10  229 172 9
+  215 150 13  199 140 8  164 109 5  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  120 78 3  132 82 3
+  151 97 5  157 106 7  180 121 7  185 132 9  193 140 10
+  207 148 7  207 148 7  192 133 7  172 114 5  132 82 3
+  101 67 7  41 27 3  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  73 48 6  143 90 3  180 121 7
+  192 133 7  207 148 7  207 148 7  201 142 7  185 132 9
+  173 120 10  136 95 7  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  91 58 5  125 83 5  135 88 5
+  144 95 7  151 97 5  132 82 3  115 73 3  95 62 5
+  64 43 7  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  64 43 7  91 58 5  151 97 5
+  157 106 7  172 114 5  172 114 5  164 109 5  151 97 5
+  85 59 6  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  73 48 6
+  91 58 5  95 62 5  95 62 5  91 58 5  56 38 5
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  83 54 6
+  107 69 5  132 82 3  125 83 5  101 67 7  71 47 31
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
+  215 150 13  215 150 13  215 150 13  215 150 13  215 150 13
diff --git a/drivers/video/matrox/matroxfb_maven.c b/drivers/video/matrox/matroxfb_maven.c
--- a/drivers/video/matrox/matroxfb_maven.c
+++ b/drivers/video/matrox/matroxfb_maven.c
@@ -1230,7 +1230,6 @@ static int maven_shutdown_client(struct 
 }
 
 static unsigned short normal_i2c[] = { MAVEN_I2CID, I2C_CLIENT_END };
-static unsigned short normal_i2c_range[] = { MAVEN_I2CID, MAVEN_I2CID, I2C_CLIENT_END };
 I2C_CLIENT_INSMOD;
 
 static struct i2c_driver maven_driver;
diff --git a/drivers/video/matrox/matroxfb_misc.c b/drivers/video/matrox/matroxfb_misc.c
--- a/drivers/video/matrox/matroxfb_misc.c
+++ b/drivers/video/matrox/matroxfb_misc.c
@@ -197,10 +197,7 @@ int matroxfb_vgaHWinit(WPMINFO struct my
 	DBG(__FUNCTION__)
 
 	hw->SEQ[0] = 0x00;
-	if (fwidth == 9)
-		hw->SEQ[1] = 0x00;
-	else
-		hw->SEQ[1] = 0x01;	/* or 0x09 */
+	hw->SEQ[1] = 0x01;	/* or 0x09 */
 	hw->SEQ[2] = 0x0F;	/* bitplanes */
 	hw->SEQ[3] = 0x00;
 	hw->SEQ[4] = 0x0E;
diff --git a/drivers/video/modedb.c b/drivers/video/modedb.c
--- a/drivers/video/modedb.c
+++ b/drivers/video/modedb.c
@@ -246,6 +246,11 @@ static const struct fb_videomode modedb[
 	/* 480x300 @ 72 Hz, 48.0 kHz hsync */
 	NULL, 72, 480, 300, 33386, 40, 24, 11, 19, 80, 3,
 	0, FB_VMODE_DOUBLE
+    }, {
+	/* 1920x1200 @ 60 Hz, 74.5 Khz hsync */
+	NULL, 60, 1920, 1200, 5177, 128, 336, 1, 38, 208, 3,
+	FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+	FB_VMODE_NONINTERLACED
     },
 };
 
diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c
--- a/drivers/video/nvidia/nvidia.c
+++ b/drivers/video/nvidia/nvidia.c
@@ -516,9 +516,9 @@ static struct backlight_controller nvidi
 static void nvidiafb_load_cursor_image(struct nvidia_par *par, u8 * data8,
 				       u16 bg, u16 fg, u32 w, u32 h)
 {
+	u32 *data = (u32 *) data8;
 	int i, j, k = 0;
 	u32 b, tmp;
-	u32 *data = (u32 *) data8;
 
 	w = (w + 1) & ~1;
 
@@ -890,11 +890,11 @@ static int nvidiafb_cursor(struct fb_inf
 {
 	struct nvidia_par *par = info->par;
 	u8 data[MAX_CURS * MAX_CURS / 8];
-	u16 fg, bg;
 	int i, set = cursor->set;
+	u16 fg, bg;
 
 	if (cursor->image.width > MAX_CURS || cursor->image.height > MAX_CURS)
-		return soft_cursor(info, cursor);
+		return -ENXIO;
 
 	NVShowHideCursor(par, 0);
 
@@ -931,21 +931,18 @@ static int nvidiafb_cursor(struct fb_inf
 		if (src) {
 			switch (cursor->rop) {
 			case ROP_XOR:
-				for (i = 0; i < s_pitch * cursor->image.height;
-				     i++)
+				for (i = 0; i < s_pitch * cursor->image.height; i++)
 					src[i] = dat[i] ^ msk[i];
 				break;
 			case ROP_COPY:
 			default:
-				for (i = 0; i < s_pitch * cursor->image.height;
-				     i++)
+				for (i = 0; i < s_pitch * cursor->image.height; i++)
 					src[i] = dat[i] & msk[i];
 				break;
 			}
 
-			fb_sysmove_buf_aligned(info, &info->pixmap, data,
-					       d_pitch, src, s_pitch,
-					       cursor->image.height);
+			fb_pad_aligned_buffer(data, d_pitch, src, s_pitch,
+						cursor->image.height);
 
 			bg = ((info->cmap.red[bg_idx] & 0xf8) << 7) |
 			    ((info->cmap.green[bg_idx] & 0xf8) << 2) |
@@ -1327,6 +1324,13 @@ static int __devinit nvidia_set_fbinfo(s
 
 		fb_videomode_to_var(&nvidiafb_default_var, &modedb);
 		nvidiafb_default_var.bits_per_pixel = 8;
+	} else if (par->fpWidth && par->fpHeight) {
+		char buf[16];
+
+		memset(buf, 0, 16);
+		snprintf(buf, 15, "%dx%d", par->fpWidth, par->fpHeight);
+		fb_find_mode(&nvidiafb_default_var, info, buf, specs->modedb,
+			     specs->modedb_len, &modedb, 8);
 	}
 
 	if (mode_option)
@@ -1348,6 +1352,7 @@ static int __devinit nvidia_set_fbinfo(s
 
 	info->pixmap.scan_align = 4;
 	info->pixmap.buf_align = 4;
+	info->pixmap.access_align = 32;
 	info->pixmap.size = 8 * 1024;
 	info->pixmap.flags = FB_PIXMAP_SYSTEM;
 
diff --git a/drivers/video/platinumfb.c b/drivers/video/platinumfb.c
--- a/drivers/video/platinumfb.c
+++ b/drivers/video/platinumfb.c
@@ -523,7 +523,7 @@ int __init platinumfb_setup(char *option
 #define invalidate_cache(addr)
 #endif
 
-static int __devinit platinumfb_probe(struct of_device* odev, const struct of_match *match)
+static int __devinit platinumfb_probe(struct of_device* odev, const struct of_device_id *match)
 {
 	struct device_node	*dp = odev->node;
 	struct fb_info		*info;
@@ -647,12 +647,10 @@ static int __devexit platinumfb_remove(s
 	return 0;
 }
 
-static struct of_match platinumfb_match[] = 
+static struct of_device_id platinumfb_match[] = 
 {
 	{
 	.name 		= "platinum",
-	.type		= OF_ANY_MATCH,
-	.compatible	= OF_ANY_MATCH,
 	},
 	{},
 };
diff --git a/drivers/video/pm2fb.c b/drivers/video/pm2fb.c
--- a/drivers/video/pm2fb.c
+++ b/drivers/video/pm2fb.c
@@ -138,27 +138,27 @@ static struct fb_var_screeninfo pm2fb_va
  * Utility functions
  */
 
-inline static u32 RD32(unsigned char __iomem *base, s32 off)
+static inline u32 RD32(unsigned char __iomem *base, s32 off)
 {
 	return fb_readl(base + off);
 }
 
-inline static void WR32(unsigned char __iomem *base, s32 off, u32 v)
+static inline void WR32(unsigned char __iomem *base, s32 off, u32 v)
 {
 	fb_writel(v, base + off);
 }
 
-inline static u32 pm2_RD(struct pm2fb_par* p, s32 off)
+static inline u32 pm2_RD(struct pm2fb_par* p, s32 off)
 {
 	return RD32(p->v_regs, off);
 }
 
-inline static void pm2_WR(struct pm2fb_par* p, s32 off, u32 v)
+static inline void pm2_WR(struct pm2fb_par* p, s32 off, u32 v)
 {
 	WR32(p->v_regs, off, v);
 }
 
-inline static u32 pm2_RDAC_RD(struct pm2fb_par* p, s32 idx)
+static inline u32 pm2_RDAC_RD(struct pm2fb_par* p, s32 idx)
 {
 	int index = PM2R_RD_INDEXED_DATA;
 	switch (p->type) {
@@ -174,7 +174,7 @@ inline static u32 pm2_RDAC_RD(struct pm2
 	return pm2_RD(p, index);
 }
 
-inline static void pm2_RDAC_WR(struct pm2fb_par* p, s32 idx, u32 v)
+static inline void pm2_RDAC_WR(struct pm2fb_par* p, s32 idx, u32 v)
 {
 	int index = PM2R_RD_INDEXED_DATA;
 	switch (p->type) {
@@ -190,7 +190,7 @@ inline static void pm2_RDAC_WR(struct pm
 	pm2_WR(p, index, v);
 }
 
-inline static void pm2v_RDAC_WR(struct pm2fb_par* p, s32 idx, u32 v)
+static inline void pm2v_RDAC_WR(struct pm2fb_par* p, s32 idx, u32 v)
 {
 	pm2_WR(p, PM2VR_RD_INDEX_LOW, idx & 0xff);
 	mb();
@@ -200,7 +200,7 @@ inline static void pm2v_RDAC_WR(struct p
 #ifdef CONFIG_FB_PM2_FIFO_DISCONNECT
 #define WAIT_FIFO(p,a)
 #else
-inline static void WAIT_FIFO(struct pm2fb_par* p, u32 a)
+static inline void WAIT_FIFO(struct pm2fb_par* p, u32 a)
 {
 	while( pm2_RD(p, PM2R_IN_FIFO_SPACE) < a );
 	mb();
diff --git a/drivers/video/pm3fb.c b/drivers/video/pm3fb.c
--- a/drivers/video/pm3fb.c
+++ b/drivers/video/pm3fb.c
@@ -5,7 +5,7 @@
  *  Based on code written by:
  *           Sven Luther, <luther@dpt-info.u-strasbg.fr>
  *           Alan Hourihane, <alanh@fairlite.demon.co.uk>
- *           Russel King, <rmk@arm.linux.org.uk>
+ *           Russell King, <rmk@arm.linux.org.uk>
  *  Based on linux/drivers/video/skeletonfb.c:
  *	Copyright (C) 1997 Geert Uytterhoeven
  *  Based on linux/driver/video/pm2fb.c:
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c
--- a/drivers/video/pxafb.c
+++ b/drivers/video/pxafb.c
@@ -43,6 +43,7 @@
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/uaccess.h>
+#include <asm/div64.h>
 #include <asm/arch/pxa-regs.h>
 #include <asm/arch/bitfield.h>
 #include <asm/arch/pxafb.h>
@@ -460,7 +461,7 @@ static inline unsigned int get_pcd(unsig
          * speeds */
 
 	pcd = (unsigned long long)get_lcdclk_frequency_10khz() * pixclock;
-	pcd /= 100000000 * 2;
+	do_div(pcd, 100000000 * 2);
 	/* no need for this, since we should subtract 1 anyway. they cancel */
 	/* pcd += 1; */ /* make up for integer math truncations */
 	return (unsigned int)pcd;
@@ -716,6 +717,9 @@ static void pxafb_enable_controller(stru
 	DPRINTK("reg_lccr2 0x%08x\n", (unsigned int) fbi->reg_lccr2);
 	DPRINTK("reg_lccr3 0x%08x\n", (unsigned int) fbi->reg_lccr3);
 
+	/* enable LCD controller clock */
+	pxa_set_cken(CKEN16_LCD, 1);
+
 	/* Sequence from 11.7.10 */
 	LCCR3 = fbi->reg_lccr3;
 	LCCR2 = fbi->reg_lccr2;
@@ -749,6 +753,9 @@ static void pxafb_disable_controller(str
 
 	schedule_timeout(20 * HZ / 1000);
 	remove_wait_queue(&fbi->ctrlr_wait, &wait);
+
+	/* disable LCD controller clock */
+	pxa_set_cken(CKEN16_LCD, 0);
 }
 
 /*
@@ -1298,8 +1305,6 @@ int __init pxafb_probe(struct device *de
 		ret = -ENOMEM;
 		goto failed;
 	}
-	/* enable LCD controller clock */
-	pxa_set_cken(CKEN16_LCD, 1);
 
 	ret = request_irq(IRQ_LCD, pxafb_handle_irq, SA_INTERRUPT, "LCD", fbi);
 	if (ret) {
diff --git a/drivers/video/radeonfb.c b/drivers/video/radeonfb.c
--- a/drivers/video/radeonfb.c
+++ b/drivers/video/radeonfb.c
@@ -80,7 +80,7 @@
 #include <video/radeon.h>
 #include <linux/radeonfb.h>
 
-#define DEBUG	1
+#define DEBUG  0
 
 #if DEBUG
 #define RTRACE		printk
diff --git a/drivers/video/riva/fbdev.c b/drivers/video/riva/fbdev.c
--- a/drivers/video/riva/fbdev.c
+++ b/drivers/video/riva/fbdev.c
@@ -1582,12 +1582,11 @@ static int rivafb_cursor(struct fb_info 
 {
 	struct riva_par *par = (struct riva_par *) info->par;
 	u8 data[MAX_CURS * MAX_CURS/8];
-	u16 fg, bg;
 	int i, set = cursor->set;
+	u16 fg, bg;
 
-	if (cursor->image.width > MAX_CURS ||
-	    cursor->image.height > MAX_CURS)
-		return soft_cursor(info, cursor);
+	if (cursor->image.width > MAX_CURS || cursor->image.height > MAX_CURS)
+		return -ENXIO;
 
 	par->riva.ShowHideCursor(&par->riva, 0);
 
@@ -1625,21 +1624,18 @@ static int rivafb_cursor(struct fb_info 
 		if (src) {
 			switch (cursor->rop) {
 			case ROP_XOR:
-				for (i = 0; i < s_pitch * cursor->image.height;
-				     i++)
+				for (i = 0; i < s_pitch * cursor->image.height; i++)
 					src[i] = dat[i] ^ msk[i];
 				break;
 			case ROP_COPY:
 			default:
-				for (i = 0; i < s_pitch * cursor->image.height;
-				     i++)
+				for (i = 0; i < s_pitch * cursor->image.height; i++)
 					src[i] = dat[i] & msk[i];
 				break;
 			}
 
-			fb_sysmove_buf_aligned(info, &info->pixmap, data,
-					       d_pitch, src, s_pitch,
-					       cursor->image.height);
+			fb_pad_aligned_buffer(data, d_pitch, src, s_pitch,
+						cursor->image.height);
 
 			bg = ((info->cmap.red[bg_idx] & 0xf8) << 7) |
 				((info->cmap.green[bg_idx] & 0xf8) << 2) |
@@ -1727,6 +1723,7 @@ static int __devinit riva_set_fbinfo(str
 
 	info->pixmap.size = 8 * 1024;
 	info->pixmap.buf_align = 4;
+	info->pixmap.access_align = 32;
 	info->pixmap.flags = FB_PIXMAP_SYSTEM;
 	info->var.yres_virtual = -1;
 	NVTRACE_LEAVE();
@@ -1829,7 +1826,7 @@ static void __devinit riva_get_EDID(stru
 #ifdef CONFIG_PPC_OF
 	if (!riva_get_EDID_OF(info, pdev))
 		printk(PFX "could not retrieve EDID from OF\n");
-#elif CONFIG_FB_RIVA_I2C
+#elif defined(CONFIG_FB_RIVA_I2C)
 	if (!riva_get_EDID_i2c(info))
 		printk(PFX "could not retrieve EDID from DDC/I2C\n");
 #endif
diff --git a/drivers/video/s1d13xxxfb.c b/drivers/video/s1d13xxxfb.c
--- a/drivers/video/s1d13xxxfb.c
+++ b/drivers/video/s1d13xxxfb.c
@@ -67,12 +67,18 @@ static struct fb_fix_screeninfo __devini
 static inline u8
 s1d13xxxfb_readreg(struct s1d13xxxfb_par *par, u16 regno)
 {
+#if defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_OPSPUT) || defined(CONFIG_PLAT_MAPPI3)
+	regno=((regno & 1) ? (regno & ~1L) : (regno + 1));
+#endif
 	return readb(par->regs + regno);
 }
 
 static inline void
 s1d13xxxfb_writereg(struct s1d13xxxfb_par *par, u16 regno, u8 value)
 {
+#if defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_OPSPUT) || defined(CONFIG_PLAT_MAPPI3)
+	regno=((regno & 1) ? (regno & ~1L) : (regno + 1));
+#endif
 	writeb(value, par->regs + regno);
 }
 
@@ -259,7 +265,11 @@ s1d13xxxfb_setcolreg(u_int regno, u_int 
 			dbg("s1d13xxxfb_setcolreg: pseudo %d, val %08x\n",
 				    regno, pseudo_val);
 
+#if defined(CONFIG_PLAT_MAPPI)
+			((u32 *)info->pseudo_palette)[regno] = cpu_to_le16(pseudo_val);
+#else
 			((u32 *)info->pseudo_palette)[regno] = pseudo_val;
+#endif
 
 			break;
 		case FB_VISUAL_PSEUDOCOLOR:
@@ -493,7 +503,7 @@ s1d13xxxfb_fetch_hw_state(struct fb_info
 }
 
 
-static int __devexit
+static int
 s1d13xxxfb_remove(struct device *dev)
 {
 	struct fb_info *info = dev_get_drvdata(dev);
diff --git a/drivers/video/sa1100fb.c b/drivers/video/sa1100fb.c
--- a/drivers/video/sa1100fb.c
+++ b/drivers/video/sa1100fb.c
@@ -598,7 +598,7 @@ sa1100fb_setcolreg(u_int regno, u_int re
  *    requests for the LCD controller.  If we hit this, it means we're
  *    doing nothing but LCD DMA.
  */
-static unsigned int sa1100fb_display_dma_period(struct fb_var_screeninfo *var)
+static inline unsigned int sa1100fb_display_dma_period(struct fb_var_screeninfo *var)
 {
 	/*
 	 * Period = pixclock * bits_per_byte * bytes_per_transfer
diff --git a/drivers/video/savage/savagefb_driver.c b/drivers/video/savage/savagefb_driver.c
--- a/drivers/video/savage/savagefb_driver.c
+++ b/drivers/video/savage/savagefb_driver.c
@@ -1897,7 +1897,7 @@ static int __devinit savage_init_fb_info
 		info->pixmap.size = 8*1024;
 		info->pixmap.scan_align = 4;
 		info->pixmap.buf_align = 4;
-		info->pixmap.access_align = 4;
+		info->pixmap.access_align = 32;
 
 		fb_alloc_cmap (&info->cmap, NR_PALETTE, 0);
 		info->flags |= FBINFO_HWACCEL_COPYAREA |
@@ -2113,7 +2113,7 @@ static int savagefb_suspend (struct pci_
 	printk(KERN_DEBUG "state: %u\n", state);
 
 	acquire_console_sem();
-	fb_set_suspend(info, state);
+	fb_set_suspend(info, pci_choose_state(dev, state));
 	savage_disable_mmio(par);
 	release_console_sem();
 
diff --git a/drivers/video/softcursor.c b/drivers/video/softcursor.c
--- a/drivers/video/softcursor.c
+++ b/drivers/video/softcursor.c
@@ -58,17 +58,10 @@ int soft_cursor(struct fb_info *info, st
 	} else 
 		memcpy(src, image->data, dsize);
 	
-	if (info->pixmap.outbuf)
-		fb_iomove_buf_aligned(info, &info->pixmap, dst, d_pitch, src,
-				  s_pitch, image->height);
-	else
-		fb_sysmove_buf_aligned(info, &info->pixmap, dst, d_pitch, src,
-				   s_pitch, image->height);
-
+	fb_pad_aligned_buffer(dst, d_pitch, src, s_pitch, image->height);
 	image->data = dst;
 	info->fbops->fb_imageblit(info, image);
 	kfree(src);
-
 	return 0;
 }
 
diff --git a/drivers/video/tridentfb.c b/drivers/video/tridentfb.c
--- a/drivers/video/tridentfb.c
+++ b/drivers/video/tridentfb.c
@@ -454,13 +454,16 @@ static struct accel_switch accel_image =
 static void tridentfb_fillrect(struct fb_info * info, const struct fb_fillrect *fr)
 {
 	int bpp = info->var.bits_per_pixel;
-	int col;
+	int col = 0;
 	
 	switch (bpp) {
 		default:
-		case 8: col = fr->color;
+		case 8: col |= fr->color;
+			col |= col << 8;
+			col |= col << 16;
 			break;
 		case 16: col = ((u32 *)(info->pseudo_palette))[fr->color];
+			
 			 break;
 		case 32: col = ((u32 *)(info->pseudo_palette))[fr->color];
 			 break;
@@ -882,8 +885,9 @@ static int tridentfb_set_par(struct fb_i
 
 	write3X4(GraphEngReg, 0x80);	//enable GE for text acceleration
 
-//	if (info->var.accel_flags & FB_ACCELF_TEXT)
-//FIXME		acc->init_accel(info->var.xres,bpp);
+#ifdef CONFIG_FB_TRIDENT_ACCEL	
+	acc->init_accel(info->var.xres,bpp);
+#endif
 	
 	switch (bpp) {
 		case 8:  tmp = 0x00; break;
@@ -900,7 +904,7 @@ static int tridentfb_set_par(struct fb_i
 	write3X4(DRAMControl, tmp);	//both IO,linear enable
 
 	write3X4(InterfaceSel, read3X4(InterfaceSel) | 0x40);
-	write3X4(Performance,0x20);
+	write3X4(Performance,0x92);
 	write3X4(PCIReg,0x07);		//MMIO & PCI read and write burst enable
 
 	/* convert from picoseconds to MHz */
@@ -981,12 +985,14 @@ static int tridentfb_setcolreg(unsigned 
 		t_outb(green>>10,0x3C9);
 		t_outb(blue>>10,0x3C9);
 
-	} else
-	if (bpp == 16) 			/* RGB 565 */
-			((u32*)info->pseudo_palette)[regno] = (red & 0xF800) |
-			((green & 0xFC00) >> 5) | ((blue & 0xF800) >> 11);
-	else
-	if (bpp == 32)		/* ARGB 8888 */
+	} else if (bpp == 16) {	/* RGB 565 */
+		u32 col;
+
+		col = (red & 0xF800) | ((green & 0xFC00) >> 5) |
+			((blue & 0xF800) >> 11);
+		col |= col << 16;	
+		((u32 *)(info->pseudo_palette))[regno] = col;
+	} else if (bpp == 32)		/* ARGB 8888 */
 		((u32*)info->pseudo_palette)[regno] =
 			((transp & 0xFF00) <<16) 	|
 			((red & 0xFF00) << 8) 		|
diff --git a/drivers/video/vesafb.c b/drivers/video/vesafb.c
--- a/drivers/video/vesafb.c
+++ b/drivers/video/vesafb.c
@@ -45,7 +45,7 @@ static struct fb_fix_screeninfo vesafb_f
 };
 
 static int             inverse   = 0;
-static int             mtrr      = 1;
+static int             mtrr      = 3; /* default to write-combining */
 static int	       vram_remap __initdata = 0; /* Set amount of memory to be used */
 static int	       vram_total __initdata = 0; /* Set total amount of memory */
 static int             pmi_setpal = 0;	/* pmi for palette changes ??? */
@@ -204,8 +204,8 @@ static int __init vesafb_setup(char *opt
 			pmi_setpal=0;
 		else if (! strcmp(this_opt, "pmipal"))
 			pmi_setpal=1;
-		else if (! strcmp(this_opt, "mtrr"))
-			mtrr=1;
+		else if (! strncmp(this_opt, "mtrr:", 5))
+			mtrr = simple_strtoul(this_opt+5, NULL, 0);
 		else if (! strcmp(this_opt, "nomtrr"))
 			mtrr=0;
 		else if (! strncmp(this_opt, "vtotal:", 7))
@@ -271,7 +271,7 @@ static int __init vesafb_probe(struct de
 
 	if (!request_mem_region(vesafb_fix.smem_start, size_total, "vesafb")) {
 		printk(KERN_WARNING
-		       "vesafb: abort, cannot reserve video memory at 0x%lx\n",
+		       "vesafb: cannot reserve video memory at 0x%lx\n",
 			vesafb_fix.smem_start);
 		/* We cannot make this fatal. Sometimes this comes from magic
 		   spaces our resource handlers simply don't know about */
@@ -279,13 +279,13 @@ static int __init vesafb_probe(struct de
 
 	info = framebuffer_alloc(sizeof(u32) * 256, &dev->dev);
 	if (!info) {
-		release_mem_region(vesafb_fix.smem_start, vesafb_fix.smem_len);
+		release_mem_region(vesafb_fix.smem_start, size_total);
 		return -ENOMEM;
 	}
 	info->pseudo_palette = info->par;
 	info->par = NULL;
 
-        info->screen_base = ioremap(vesafb_fix.smem_start, vesafb_fix.smem_len);
+	info->screen_base = ioremap(vesafb_fix.smem_start, vesafb_fix.smem_len);
 	if (!info->screen_base) {
 		printk(KERN_ERR
 		       "vesafb: abort, cannot ioremap video memory 0x%x @ 0x%lx\n",
@@ -386,14 +386,40 @@ static int __init vesafb_probe(struct de
 	request_region(0x3c0, 32, "vesafb");
 
 	if (mtrr) {
-		int temp_size = size_total;
-		/* Find the largest power-of-two */
-		while (temp_size & (temp_size - 1))
-                	temp_size &= (temp_size - 1);
-                        
-                /* Try and find a power of two to add */
-		while (temp_size && mtrr_add(vesafb_fix.smem_start, temp_size, MTRR_TYPE_WRCOMB, 1)==-EINVAL) {
-			temp_size >>= 1;
+		unsigned int temp_size = size_total;
+		unsigned int type = 0;
+
+		switch (mtrr) {
+		case 1:
+			type = MTRR_TYPE_UNCACHABLE;
+			break;
+		case 2:
+			type = MTRR_TYPE_WRBACK;
+			break;
+		case 3:
+			type = MTRR_TYPE_WRCOMB;
+			break;
+		case 4:
+			type = MTRR_TYPE_WRTHROUGH;
+			break;
+		default:
+			type = 0;
+			break;
+		}
+
+		if (type) {
+			int rc;
+
+			/* Find the largest power-of-two */
+			while (temp_size & (temp_size - 1))
+				temp_size &= (temp_size - 1);
+
+			/* Try and find a power of two to add */
+			do {
+				rc = mtrr_add(vesafb_fix.smem_start, temp_size,
+					      type, 1);
+				temp_size >>= 1;
+			} while (temp_size >= PAGE_SIZE && rc == -EINVAL);
 		}
 	}
 	
diff --git a/drivers/video/w100fb.c b/drivers/video/w100fb.c
--- a/drivers/video/w100fb.c
+++ b/drivers/video/w100fb.c
@@ -101,7 +101,7 @@ static void(*w100fb_ssp_send)(u8 adrs, u
  * Sysfs functions
  */
 
-static ssize_t rotation_show(struct device *dev, char *buf)
+static ssize_t rotation_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct fb_info *info = dev_get_drvdata(dev);
 	struct w100fb_par *par=info->par;
@@ -109,7 +109,7 @@ static ssize_t rotation_show(struct devi
 	return sprintf(buf, "%d\n",par->rotation_flag);
 }
 
-static ssize_t rotation_store(struct device *dev, const char *buf, size_t count)
+static ssize_t rotation_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	unsigned int rotate;
 	struct fb_info *info = dev_get_drvdata(dev);
@@ -134,7 +134,7 @@ static ssize_t rotation_store(struct dev
 
 static DEVICE_ATTR(rotation, 0644, rotation_show, rotation_store);
 
-static ssize_t w100fb_reg_read(struct device *dev, const char *buf, size_t count)
+static ssize_t w100fb_reg_read(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	unsigned long param;
 	unsigned long regs;
@@ -146,7 +146,7 @@ static ssize_t w100fb_reg_read(struct de
 
 static DEVICE_ATTR(reg_read, 0200, NULL, w100fb_reg_read);
 
-static ssize_t w100fb_reg_write(struct device *dev, const char *buf, size_t count)
+static ssize_t w100fb_reg_write(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	unsigned long regs;
 	unsigned long param;
@@ -163,7 +163,7 @@ static ssize_t w100fb_reg_write(struct d
 static DEVICE_ATTR(reg_write, 0200, NULL, w100fb_reg_write);
 
 
-static ssize_t fastsysclk_show(struct device *dev, char *buf)
+static ssize_t fastsysclk_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct fb_info *info = dev_get_drvdata(dev);
 	struct w100fb_par *par=info->par;
@@ -171,7 +171,7 @@ static ssize_t fastsysclk_show(struct de
 	return sprintf(buf, "%d\n",par->fastsysclk_mode);
 }
 
-static ssize_t fastsysclk_store(struct device *dev, const char *buf, size_t count)
+static ssize_t fastsysclk_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	int param;
 	struct fb_info *info = dev_get_drvdata(dev);
diff --git a/drivers/w1/Kconfig b/drivers/w1/Kconfig
--- a/drivers/w1/Kconfig
+++ b/drivers/w1/Kconfig
@@ -3,9 +3,9 @@ menu "Dallas's 1-wire bus"
 config W1
 	tristate "Dallas's 1-wire support"
 	---help---
-	  Dallas's 1-wire bus is usefull to connect slow 1-pin devices 
+	  Dallas's 1-wire bus is usefull to connect slow 1-pin devices
 	  such as iButtons and thermal sensors.
-	  
+
 	  If you want W1 support, you should say Y here.
 
 	  This W1 support can also be built as a module.  If so, the module
@@ -17,8 +17,8 @@ config W1_MATROX
 	help
 	  Say Y here if you want to communicate with your 1-wire devices
 	  using Matrox's G400 GPIO pins.
-	  
-	  This support is also available as a module.  If so, the module 
+
+	  This support is also available as a module.  If so, the module
 	  will be called matrox_w1.ko.
 
 config W1_DS9490
@@ -27,7 +27,7 @@ config W1_DS9490
 	help
 	  Say Y here if you want to have a driver for DS9490R UWB <-> W1 bridge.
 
-	  This support is also available as a module.  If so, the module 
+	  This support is also available as a module.  If so, the module
 	  will be called ds9490r.ko.
 
 config W1_DS9490_BRIDGE
@@ -37,7 +37,7 @@ config W1_DS9490_BRIDGE
 	  Say Y here if you want to communicate with your 1-wire devices
 	  using DS9490R USB bridge.
 
-	  This support is also available as a module.  If so, the module 
+	  This support is also available as a module.  If so, the module
 	  will be called ds_w1_bridge.ko.
 
 config W1_THERM
@@ -51,7 +51,7 @@ config W1_SMEM
 	tristate "Simple 64bit memory family implementation"
 	depends on W1
 	help
-	  Say Y here if you want to connect 1-wire 
+	  Say Y here if you want to connect 1-wire
 	  simple 64bit memory rom(ds2401/ds2411/ds1990*) to you wire.
 
 endmenu
diff --git a/drivers/w1/ds_w1_bridge.c b/drivers/w1/ds_w1_bridge.c
--- a/drivers/w1/ds_w1_bridge.c
+++ b/drivers/w1/ds_w1_bridge.c
@@ -83,11 +83,11 @@ static u8 ds9490r_read_byte(unsigned lon
 	return byte;
 }
 
-static void ds9490r_write_block(unsigned long data, u8 *buf, int len)
+static void ds9490r_write_block(unsigned long data, const u8 *buf, int len)
 {
 	struct ds_device *dev = (struct ds_device *)data;
 
-	ds_write_block(dev, buf, len);
+	ds_write_block(dev, (u8 *)buf, len);
 }
 
 static u8 ds9490r_read_block(unsigned long data, u8 *buf, int len)
diff --git a/drivers/w1/matrox_w1.c b/drivers/w1/matrox_w1.c
--- a/drivers/w1/matrox_w1.c
+++ b/drivers/w1/matrox_w1.c
@@ -1,8 +1,8 @@
 /*
- * 	matrox_w1.c
+ *	matrox_w1.c
  *
  * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru>
- * 
+ *
  *
  * 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
@@ -59,7 +59,7 @@ static struct pci_driver matrox_w1_pci_d
 	.remove = __devexit_p(matrox_w1_remove),
 };
 
-/* 
+/*
  * Matrox G400 DDC registers.
  */
 
@@ -177,8 +177,8 @@ static int __devinit matrox_w1_probe(str
 
 	dev->bus_master = (struct w1_bus_master *)(dev + 1);
 
-	/* 
-	 * True for G400, for some other we need resource 0, see drivers/video/matrox/matroxfb_base.c 
+	/*
+	 * True for G400, for some other we need resource 0, see drivers/video/matrox/matroxfb_base.c
 	 */
 
 	dev->phys_addr = pci_resource_start(pdev, 1);
diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c
--- a/drivers/w1/w1.c
+++ b/drivers/w1/w1.c
@@ -1,8 +1,8 @@
 /*
- * 	w1.c
+ *	w1.c
  *
  * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru>
- * 
+ *
  *
  * 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
@@ -59,6 +59,19 @@ static pid_t control_thread;
 static int control_needs_exit;
 static DECLARE_COMPLETION(w1_control_complete);
 
+/* stuff for the default family */
+static ssize_t w1_famdefault_read_name(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct w1_slave *sl = container_of(dev, struct w1_slave, dev);
+	return(sprintf(buf, "%s\n", sl->name));
+}
+static struct w1_family_ops w1_default_fops = {
+	.rname = &w1_famdefault_read_name,
+};
+static struct w1_family w1_default_family = {
+	.fops = &w1_default_fops,
+};
+
 static int w1_master_match(struct device *dev, struct device_driver *drv)
 {
 	return 1;
@@ -88,7 +101,7 @@ static void w1_slave_release(struct devi
 	complete(&sl->dev_released);
 }
 
-static ssize_t w1_default_read_name(struct device *dev, char *buf)
+static ssize_t w1_default_read_name(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	return sprintf(buf, "No family registered.\n");
 }
@@ -99,6 +112,20 @@ static ssize_t w1_default_read_bin(struc
 	return sprintf(buf, "No family registered.\n");
 }
 
+static struct device_attribute w1_slave_attribute =
+	__ATTR(name, S_IRUGO, w1_default_read_name, NULL);
+
+static struct bin_attribute w1_slave_bin_attribute = {
+	.attr = {
+		.name = "w1_slave",
+		.mode = S_IRUGO,
+		.owner = THIS_MODULE,
+	},
+	.size = W1_SLAVE_DATA_SIZE,
+	.read = &w1_default_read_bin,
+};
+
+
 static struct bus_type w1_bus_type = {
 	.name = "w1",
 	.match = w1_master_match,
@@ -119,104 +146,118 @@ struct device w1_device = {
 	.release = &w1_master_release
 };
 
-static struct device_attribute w1_slave_attribute = {
-	.attr = {
-			.name = "name",
-			.mode = S_IRUGO,
-			.owner = THIS_MODULE
-	},
-	.show = &w1_default_read_name,
-};
+static ssize_t w1_master_attribute_show_name(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct w1_master *md = container_of(dev, struct w1_master, dev);
+	ssize_t count;
 
-static struct device_attribute w1_slave_attribute_val = {
-	.attr = {
-			.name = "value",
-			.mode = S_IRUGO,
-			.owner = THIS_MODULE
-	},
-	.show = &w1_default_read_name,
-};
+	if (down_interruptible (&md->mutex))
+		return -EBUSY;
 
-static ssize_t w1_master_attribute_show_name(struct device *dev, char *buf)
+	count = sprintf(buf, "%s\n", md->name);
+
+	up(&md->mutex);
+
+	return count;
+}
+
+static ssize_t w1_master_attribute_store_search(struct device * dev,
+						struct device_attribute *attr,
+						const char * buf, size_t count)
 {
-	struct w1_master *md = container_of (dev, struct w1_master, dev);
+	struct w1_master *md = container_of(dev, struct w1_master, dev);
+
+	if (down_interruptible (&md->mutex))
+		return -EBUSY;
+
+	md->search_count = simple_strtol(buf, NULL, 0);
+
+	up(&md->mutex);
+
+	return count;
+}
+
+static ssize_t w1_master_attribute_show_search(struct device *dev,
+					       struct device_attribute *attr,
+					       char *buf)
+{
+	struct w1_master *md = container_of(dev, struct w1_master, dev);
 	ssize_t count;
-	
+
 	if (down_interruptible (&md->mutex))
 		return -EBUSY;
 
-	count = sprintf(buf, "%s\n", md->name);
-	
+	count = sprintf(buf, "%d\n", md->search_count);
+
 	up(&md->mutex);
 
 	return count;
 }
 
-static ssize_t w1_master_attribute_show_pointer(struct device *dev, char *buf)
+static ssize_t w1_master_attribute_show_pointer(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct w1_master *md = container_of(dev, struct w1_master, dev);
 	ssize_t count;
-	
+
 	if (down_interruptible(&md->mutex))
 		return -EBUSY;
 
 	count = sprintf(buf, "0x%p\n", md->bus_master);
-	
+
 	up(&md->mutex);
 	return count;
 }
 
-static ssize_t w1_master_attribute_show_timeout(struct device *dev, char *buf)
+static ssize_t w1_master_attribute_show_timeout(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	ssize_t count;
 	count = sprintf(buf, "%d\n", w1_timeout);
 	return count;
 }
 
-static ssize_t w1_master_attribute_show_max_slave_count(struct device *dev, char *buf)
+static ssize_t w1_master_attribute_show_max_slave_count(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct w1_master *md = container_of(dev, struct w1_master, dev);
 	ssize_t count;
-	
+
 	if (down_interruptible(&md->mutex))
 		return -EBUSY;
 
 	count = sprintf(buf, "%d\n", md->max_slave_count);
-	
+
 	up(&md->mutex);
 	return count;
 }
 
-static ssize_t w1_master_attribute_show_attempts(struct device *dev, char *buf)
+static ssize_t w1_master_attribute_show_attempts(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct w1_master *md = container_of(dev, struct w1_master, dev);
 	ssize_t count;
-	
+
 	if (down_interruptible(&md->mutex))
 		return -EBUSY;
 
 	count = sprintf(buf, "%lu\n", md->attempts);
-	
+
 	up(&md->mutex);
 	return count;
 }
 
-static ssize_t w1_master_attribute_show_slave_count(struct device *dev, char *buf)
+static ssize_t w1_master_attribute_show_slave_count(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct w1_master *md = container_of(dev, struct w1_master, dev);
 	ssize_t count;
-	
+
 	if (down_interruptible(&md->mutex))
 		return -EBUSY;
 
 	count = sprintf(buf, "%d\n", md->slave_count);
-	
+
 	up(&md->mutex);
 	return count;
 }
 
-static ssize_t w1_master_attribute_show_slaves(struct device *dev, char *buf)
-
+static ssize_t w1_master_attribute_show_slaves(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct w1_master *md = container_of(dev, struct w1_master, dev);
 	int c = PAGE_SIZE;
@@ -233,7 +274,7 @@ static ssize_t w1_master_attribute_show_
 		list_for_each_safe(ent, n, &md->slist) {
 			sl = list_entry(ent, struct w1_slave, w1_slave_entry);
 
- 			c -= snprintf(buf + PAGE_SIZE - c, c, "%s\n", sl->name);
+			c -= snprintf(buf + PAGE_SIZE - c, c, "%s\n", sl->name);
 		}
 	}
 
@@ -242,72 +283,51 @@ static ssize_t w1_master_attribute_show_
 	return PAGE_SIZE - c;
 }
 
-static struct device_attribute w1_master_attribute_slaves = {
-	.attr = {
- 			.name = "w1_master_slaves",
-			.mode = S_IRUGO,
-			.owner = THIS_MODULE,
-	},
- 	.show = &w1_master_attribute_show_slaves,
-};
-static struct device_attribute w1_master_attribute_slave_count = {
-	.attr = {
-			.name = "w1_master_slave_count",
-			.mode = S_IRUGO,
-			.owner = THIS_MODULE
-	},
-	.show = &w1_master_attribute_show_slave_count,
-};
-static struct device_attribute w1_master_attribute_attempts = {
-	.attr = {
-			.name = "w1_master_attempts",
-			.mode = S_IRUGO,
-			.owner = THIS_MODULE
-	},
-	.show = &w1_master_attribute_show_attempts,
-};
-static struct device_attribute w1_master_attribute_max_slave_count = {
-	.attr = {
-			.name = "w1_master_max_slave_count",
-			.mode = S_IRUGO,
-			.owner = THIS_MODULE
-	},
-	.show = &w1_master_attribute_show_max_slave_count,
-};
-static struct device_attribute w1_master_attribute_timeout = {
-	.attr = {
-			.name = "w1_master_timeout",
-			.mode = S_IRUGO,
-			.owner = THIS_MODULE
-	},
-	.show = &w1_master_attribute_show_timeout,
-};
-static struct device_attribute w1_master_attribute_pointer = {
-	.attr = {
-			.name = "w1_master_pointer",
-			.mode = S_IRUGO,
-			.owner = THIS_MODULE
-	},
-	.show = &w1_master_attribute_show_pointer,
-};
-static struct device_attribute w1_master_attribute_name = {
-	.attr = {
-			.name = "w1_master_name",
-			.mode = S_IRUGO,
-			.owner = THIS_MODULE
-	},
-	.show = &w1_master_attribute_show_name,
+#define W1_MASTER_ATTR_RO(_name, _mode)				\
+	struct device_attribute w1_master_attribute_##_name =	\
+		__ATTR(w1_master_##_name, _mode,		\
+		       w1_master_attribute_show_##_name, NULL)
+
+#define W1_MASTER_ATTR_RW(_name, _mode)				\
+	struct device_attribute w1_master_attribute_##_name =	\
+		__ATTR(w1_master_##_name, _mode,		\
+		       w1_master_attribute_show_##_name,	\
+		       w1_master_attribute_store_##_name)
+
+static W1_MASTER_ATTR_RO(name, S_IRUGO);
+static W1_MASTER_ATTR_RO(slaves, S_IRUGO);
+static W1_MASTER_ATTR_RO(slave_count, S_IRUGO);
+static W1_MASTER_ATTR_RO(max_slave_count, S_IRUGO);
+static W1_MASTER_ATTR_RO(attempts, S_IRUGO);
+static W1_MASTER_ATTR_RO(timeout, S_IRUGO);
+static W1_MASTER_ATTR_RO(pointer, S_IRUGO);
+static W1_MASTER_ATTR_RW(search, S_IRUGO | S_IWUGO);
+
+static struct attribute *w1_master_default_attrs[] = {
+	&w1_master_attribute_name.attr,
+	&w1_master_attribute_slaves.attr,
+	&w1_master_attribute_slave_count.attr,
+	&w1_master_attribute_max_slave_count.attr,
+	&w1_master_attribute_attempts.attr,
+	&w1_master_attribute_timeout.attr,
+	&w1_master_attribute_pointer.attr,
+	&w1_master_attribute_search.attr,
+	NULL
+};
+
+static struct attribute_group w1_master_defattr_group = {
+	.attrs = w1_master_default_attrs,
 };
 
-static struct bin_attribute w1_slave_bin_attribute = {
-	.attr = {
-		 	.name = "w1_slave",
-		 	.mode = S_IRUGO,
-			.owner = THIS_MODULE,
-	},
-	.size = W1_SLAVE_DATA_SIZE,
-	.read = &w1_default_read_bin,
-};
+int w1_create_master_attributes(struct w1_master *master)
+{
+	return sysfs_create_group(&master->dev.kobj, &w1_master_defattr_group);
+}
+
+void w1_destroy_master_attributes(struct w1_master *master)
+{
+	sysfs_remove_group(&master->dev.kobj, &w1_master_defattr_group);
+}
 
 static int __w1_attach_slave_device(struct w1_slave *sl)
 {
@@ -319,13 +339,13 @@ static int __w1_attach_slave_device(stru
 	sl->dev.release = &w1_slave_release;
 
 	snprintf(&sl->dev.bus_id[0], sizeof(sl->dev.bus_id),
-		  "%02x-%012llx",
-		  (unsigned int) sl->reg_num.family,
-		  (unsigned long long) sl->reg_num.id);
-	snprintf (&sl->name[0], sizeof(sl->name),
-		  "%02x-%012llx",
-		  (unsigned int) sl->reg_num.family,
-		  (unsigned long long) sl->reg_num.id);
+		 "%02x-%012llx",
+		 (unsigned int) sl->reg_num.family,
+		 (unsigned long long) sl->reg_num.id);
+	snprintf(&sl->name[0], sizeof(sl->name),
+		 "%02x-%012llx",
+		 (unsigned int) sl->reg_num.family,
+		 (unsigned long long) sl->reg_num.id);
 
 	dev_dbg(&sl->dev, "%s: registering %s.\n", __func__,
 		&sl->dev.bus_id[0]);
@@ -333,48 +353,36 @@ static int __w1_attach_slave_device(stru
 	err = device_register(&sl->dev);
 	if (err < 0) {
 		dev_err(&sl->dev,
-			 "Device registration [%s] failed. err=%d\n",
-			 sl->dev.bus_id, err);
+			"Device registration [%s] failed. err=%d\n",
+			sl->dev.bus_id, err);
 		return err;
 	}
 
 	memcpy(&sl->attr_bin, &w1_slave_bin_attribute, sizeof(sl->attr_bin));
 	memcpy(&sl->attr_name, &w1_slave_attribute, sizeof(sl->attr_name));
-	memcpy(&sl->attr_val, &w1_slave_attribute_val, sizeof(sl->attr_val));
-	
+
 	sl->attr_bin.read = sl->family->fops->rbin;
 	sl->attr_name.show = sl->family->fops->rname;
-	sl->attr_val.show = sl->family->fops->rval;
-	sl->attr_val.attr.name = sl->family->fops->rvalname;
 
 	err = device_create_file(&sl->dev, &sl->attr_name);
 	if (err < 0) {
 		dev_err(&sl->dev,
-			 "sysfs file creation for [%s] failed. err=%d\n",
-			 sl->dev.bus_id, err);
-		device_unregister(&sl->dev);
-		return err;
-	}
-
-	err = device_create_file(&sl->dev, &sl->attr_val);
-	if (err < 0) {
-		dev_err(&sl->dev,
-			 "sysfs file creation for [%s] failed. err=%d\n",
-			 sl->dev.bus_id, err);
-		device_remove_file(&sl->dev, &sl->attr_name);
+			"sysfs file creation for [%s] failed. err=%d\n",
+			sl->dev.bus_id, err);
 		device_unregister(&sl->dev);
 		return err;
 	}
 
-	err = sysfs_create_bin_file(&sl->dev.kobj, &sl->attr_bin);
-	if (err < 0) {
-		dev_err(&sl->dev,
-			 "sysfs file creation for [%s] failed. err=%d\n",
-			 sl->dev.bus_id, err);
-		device_remove_file(&sl->dev, &sl->attr_name);
-		device_remove_file(&sl->dev, &sl->attr_val);
-		device_unregister(&sl->dev);
-		return err;
+	if ( sl->attr_bin.read ) {
+		err = sysfs_create_bin_file(&sl->dev.kobj, &sl->attr_bin);
+		if (err < 0) {
+			dev_err(&sl->dev,
+				"sysfs file creation for [%s] failed. err=%d\n",
+				sl->dev.bus_id, err);
+			device_remove_file(&sl->dev, &sl->attr_name);
+			device_unregister(&sl->dev);
+			return err;
+		}
 	}
 
 	list_add_tail(&sl->w1_slave_entry, &sl->master->slist);
@@ -410,12 +418,10 @@ static int w1_attach_slave_device(struct
 	spin_lock(&w1_flock);
 	f = w1_family_registered(rn->family);
 	if (!f) {
-		spin_unlock(&w1_flock);
+		f= &w1_default_family;
 		dev_info(&dev->dev, "Family %x for %02x.%012llx.%02x is not registered.\n",
 			  rn->family, rn->family,
 			  (unsigned long long)rn->id, rn->crc);
-		kfree(sl);
-		return -ENODEV;
 	}
 	__w1_family_get(f);
 	spin_unlock(&w1_flock);
@@ -445,7 +451,7 @@ static int w1_attach_slave_device(struct
 static void w1_slave_detach(struct w1_slave *sl)
 {
 	struct w1_netlink_msg msg;
-	
+
 	dev_info(&sl->dev, "%s: detaching %s.\n", __func__, sl->name);
 
 	while (atomic_read(&sl->refcnt)) {
@@ -456,12 +462,15 @@ static void w1_slave_detach(struct w1_sl
 			flush_signals(current);
 	}
 
-	sysfs_remove_bin_file (&sl->dev.kobj, &sl->attr_bin);
+	if ( sl->attr_bin.read ) {
+		sysfs_remove_bin_file (&sl->dev.kobj, &sl->attr_bin);
+	}
 	device_remove_file(&sl->dev, &sl->attr_name);
-	device_remove_file(&sl->dev, &sl->attr_val);
 	device_unregister(&sl->dev);
 	w1_family_put(sl->family);
 
+	sl->master->slave_count--;
+
 	memcpy(&msg.id.id, &sl->reg_num, sizeof(msg.id.id));
 	msg.type = W1_SLAVE_REMOVE;
 	w1_netlink_send(sl->master, &msg);
@@ -471,8 +480,8 @@ static struct w1_master *w1_search_maste
 {
 	struct w1_master *dev;
 	int found = 0;
-	
-	spin_lock_irq(&w1_mlock);
+
+	spin_lock_bh(&w1_mlock);
 	list_for_each_entry(dev, &w1_masters, w1_master_entry) {
 		if (dev->bus_master->data == data) {
 			found = 1;
@@ -480,12 +489,26 @@ static struct w1_master *w1_search_maste
 			break;
 		}
 	}
-	spin_unlock_irq(&w1_mlock);
+	spin_unlock_bh(&w1_mlock);
 
 	return (found)?dev:NULL;
 }
 
-void w1_slave_found(unsigned long data, u64 rn)
+void w1_reconnect_slaves(struct w1_family *f)
+{
+	struct w1_master *dev;
+
+	spin_lock_bh(&w1_mlock);
+	list_for_each_entry(dev, &w1_masters, w1_master_entry) {
+		dev_info(&dev->dev, "Reconnecting slaves in %s into new family %02x.\n",
+				dev->name, f->fid);
+		set_bit(W1_MASTER_NEED_RECONNECT, &dev->flags);
+	}
+	spin_unlock_bh(&w1_mlock);
+}
+
+
+static void w1_slave_found(unsigned long data, u64 rn)
 {
 	int slave_count;
 	struct w1_slave *sl;
@@ -493,6 +516,7 @@ void w1_slave_found(unsigned long data, 
 	struct w1_reg_num *tmp;
 	int family_found = 0;
 	struct w1_master *dev;
+	u64 rn_le = cpu_to_le64(rn);
 
 	dev = w1_search_master(data);
 	if (!dev) {
@@ -500,7 +524,7 @@ void w1_slave_found(unsigned long data, 
 				data);
 		return;
 	}
-	
+
 	tmp = (struct w1_reg_num *) &rn;
 
 	slave_count = 0;
@@ -513,8 +537,7 @@ void w1_slave_found(unsigned long data, 
 		    sl->reg_num.crc == tmp->crc) {
 			set_bit(W1_SLAVE_ACTIVE, (long *)&sl->flags);
 			break;
-		}
-		else if (sl->reg_num.family == tmp->family) {
+		} else if (sl->reg_num.family == tmp->family) {
 			family_found = 1;
 			break;
 		}
@@ -522,36 +545,47 @@ void w1_slave_found(unsigned long data, 
 		slave_count++;
 	}
 
-	rn = cpu_to_le64(rn);
-
 	if (slave_count == dev->slave_count &&
-		rn && ((le64_to_cpu(rn) >> 56) & 0xff) == w1_calc_crc8((u8 *)&rn, 7)) {
+		rn && ((rn >> 56) & 0xff) == w1_calc_crc8((u8 *)&rn_le, 7)) {
 		w1_attach_slave_device(dev, tmp);
 	}
-			
+
 	atomic_dec(&dev->refcnt);
 }
 
-void w1_search(struct w1_master *dev)
+/**
+ * Performs a ROM Search & registers any devices found.
+ * The 1-wire search is a simple binary tree search.
+ * For each bit of the address, we read two bits and write one bit.
+ * The bit written will put to sleep all devies that don't match that bit.
+ * When the two reads differ, the direction choice is obvious.
+ * When both bits are 0, we must choose a path to take.
+ * When we can scan all 64 bits without having to choose a path, we are done.
+ *
+ * See "Application note 187 1-wire search algorithm" at www.maxim-ic.com
+ *
+ * @dev        The master device to search
+ * @cb         Function to call when a device is found
+ */
+void w1_search(struct w1_master *dev, w1_slave_found_callback cb)
 {
-	u64 last, rn, tmp;
-	int i, count = 0;
-	int last_family_desc, last_zero, last_device;
-	int search_bit, id_bit, comp_bit, desc_bit;
-
-	search_bit = id_bit = comp_bit = 0;
-	rn = tmp = last = 0;
-	last_device = last_zero = last_family_desc = 0;
+	u64 last_rn, rn, tmp64;
+	int i, slave_count = 0;
+	int last_zero, last_device;
+	int search_bit, desc_bit;
+	u8  triplet_ret = 0;
+
+	search_bit = 0;
+	rn = last_rn = 0;
+	last_device = 0;
+	last_zero = -1;
 
 	desc_bit = 64;
 
-	while (!(id_bit && comp_bit) && !last_device
-		&& count++ < dev->max_slave_count) {
-		last = rn;
+	while ( !last_device && (slave_count++ < dev->max_slave_count) ) {
+		last_rn = rn;
 		rn = 0;
 
-		last_family_desc = 0;
-
 		/*
 		 * Reset bus and all 1-wire device state machines
 		 * so they can respond to our requests.
@@ -559,98 +593,50 @@ void w1_search(struct w1_master *dev)
 		 * Return 0 - device(s) present, 1 - no devices present.
 		 */
 		if (w1_reset_bus(dev)) {
-			dev_info(&dev->dev, "No devices present on the wire.\n");
+			dev_dbg(&dev->dev, "No devices present on the wire.\n");
 			break;
 		}
 
-#if 1
+		/* Start the search */
 		w1_write_8(dev, W1_SEARCH);
 		for (i = 0; i < 64; ++i) {
-			/*
-			 * Read 2 bits from bus.
-			 * All who don't sleep must send ID bit and COMPLEMENT ID bit.
-			 * They actually are ANDed between all senders.
-			 */
-			id_bit = w1_touch_bit(dev, 1);
-			comp_bit = w1_touch_bit(dev, 1);
-
-			if (id_bit && comp_bit)
-				break;
-
-			if (id_bit == 0 && comp_bit == 0) {
-				if (i == desc_bit)
-					search_bit = 1;
-				else if (i > desc_bit)
-					search_bit = 0;
-				else
-					search_bit = ((last >> i) & 0x1);
-
-				if (search_bit == 0) {
-					last_zero = i;
-					if (last_zero < 9)
-						last_family_desc = last_zero;
-				}
-
-			}
+			/* Determine the direction/search bit */
+			if (i == desc_bit)
+				search_bit = 1;	  /* took the 0 path last time, so take the 1 path */
+			else if (i > desc_bit)
+				search_bit = 0;	  /* take the 0 path on the next branch */
 			else
-				search_bit = id_bit;
+				search_bit = ((last_rn >> i) & 0x1);
 
-			tmp = search_bit;
-			rn |= (tmp << i);
+			/** Read two bits and write one bit */
+			triplet_ret = w1_triplet(dev, search_bit);
 
-			/*
-			 * Write 1 bit to bus
-			 * and make all who don't have "search_bit" in "i"'th position
-			 * in it's registration number sleep.
-			 */
-			if (dev->bus_master->touch_bit)
-				w1_touch_bit(dev, search_bit);
-			else
-				w1_write_bit(dev, search_bit);
+			/* quit if no device responded */
+			if ( (triplet_ret & 0x03) == 0x03 )
+				break;
 
+			/* If both directions were valid, and we took the 0 path... */
+			if (triplet_ret == 0)
+				last_zero = i;
+
+			/* extract the direction taken & update the device number */
+			tmp64 = (triplet_ret >> 2);
+			rn |= (tmp64 << i);
 		}
-#endif
-
-		if (desc_bit == last_zero)
-			last_device = 1;
 
-		desc_bit = last_zero;
-	
-		w1_slave_found(dev->bus_master->data, rn);
+		if ( (triplet_ret & 0x03) != 0x03 ) {
+			if ( (desc_bit == last_zero) || (last_zero < 0))
+				last_device = 1;
+			desc_bit = last_zero;
+			cb(dev->bus_master->data, rn);
+		}
 	}
 }
 
-int w1_create_master_attributes(struct w1_master *dev)
+static int w1_control(void *data)
 {
-	if (	device_create_file(&dev->dev, &w1_master_attribute_slaves) < 0 ||
-		device_create_file(&dev->dev, &w1_master_attribute_slave_count) < 0 ||
-		device_create_file(&dev->dev, &w1_master_attribute_attempts) < 0 ||
-		device_create_file(&dev->dev, &w1_master_attribute_max_slave_count) < 0 ||
-		device_create_file(&dev->dev, &w1_master_attribute_timeout) < 0||
-		device_create_file(&dev->dev, &w1_master_attribute_pointer) < 0||
-		device_create_file(&dev->dev, &w1_master_attribute_name) < 0)
-		return -EINVAL;
-
-	return 0;
-}
-
-void w1_destroy_master_attributes(struct w1_master *dev)
-{
-	device_remove_file(&dev->dev, &w1_master_attribute_slaves);
-	device_remove_file(&dev->dev, &w1_master_attribute_slave_count);
-	device_remove_file(&dev->dev, &w1_master_attribute_attempts);
-	device_remove_file(&dev->dev, &w1_master_attribute_max_slave_count);
-	device_remove_file(&dev->dev, &w1_master_attribute_timeout);
-	device_remove_file(&dev->dev, &w1_master_attribute_pointer);
-	device_remove_file(&dev->dev, &w1_master_attribute_name);
-}
-
-
-int w1_control(void *data)
-{
-	struct w1_slave *sl;
-	struct w1_master *dev;
-	struct list_head *ent, *ment, *n, *mn;
+	struct w1_slave *sl, *sln;
+	struct w1_master *dev, *n;
 	int err, have_to_wait = 0;
 
 	daemonize("w1_control");
@@ -659,16 +645,14 @@ int w1_control(void *data)
 	while (!control_needs_exit || have_to_wait) {
 		have_to_wait = 0;
 
-		try_to_freeze(PF_FREEZE);
+		try_to_freeze();
 		msleep_interruptible(w1_timeout * 1000);
 
 		if (signal_pending(current))
 			flush_signals(current);
 
-		list_for_each_safe(ment, mn, &w1_masters) {
-			dev = list_entry(ment, struct w1_master, w1_master_entry);
-
-			if (!control_needs_exit && !dev->need_exit)
+		list_for_each_entry_safe(dev, n, &w1_masters, w1_master_entry) {
+			if (!control_needs_exit && !dev->flags)
 				continue;
 			/*
 			 * Little race: we can create thread but not set the flag.
@@ -679,12 +663,8 @@ int w1_control(void *data)
 				continue;
 			}
 
-			spin_lock(&w1_mlock);
-			list_del(&dev->w1_master_entry);
-			spin_unlock(&w1_mlock);
-
 			if (control_needs_exit) {
-				dev->need_exit = 1;
+				set_bit(W1_MASTER_NEED_EXIT, &dev->flags);
 
 				err = kill_proc(dev->kpid, SIGTERM, 1);
 				if (err)
@@ -693,24 +673,42 @@ int w1_control(void *data)
 						 dev->kpid);
 			}
 
-			wait_for_completion(&dev->dev_exited);
-
-			list_for_each_safe(ent, n, &dev->slist) {
-				sl = list_entry(ent, struct w1_slave, w1_slave_entry);
+			if (test_bit(W1_MASTER_NEED_EXIT, &dev->flags)) {
+				wait_for_completion(&dev->dev_exited);
+				spin_lock_bh(&w1_mlock);
+				list_del(&dev->w1_master_entry);
+				spin_unlock_bh(&w1_mlock);
 
-				if (!sl)
-					dev_warn(&dev->dev,
-						  "%s: slave entry is NULL.\n",
-						  __func__);
-				else {
+				list_for_each_entry_safe(sl, sln, &dev->slist, w1_slave_entry) {
 					list_del(&sl->w1_slave_entry);
 
 					w1_slave_detach(sl);
 					kfree(sl);
 				}
+				w1_destroy_master_attributes(dev);
+				atomic_dec(&dev->refcnt);
+				continue;
+			}
+
+			if (test_bit(W1_MASTER_NEED_RECONNECT, &dev->flags)) {
+				dev_info(&dev->dev, "Reconnecting slaves in device %s.\n", dev->name);
+				down(&dev->mutex);
+				list_for_each_entry(sl, &dev->slist, w1_slave_entry) {
+					if (sl->family->fid == W1_FAMILY_DEFAULT) {
+						struct w1_reg_num rn;
+						list_del(&sl->w1_slave_entry);
+						w1_slave_detach(sl);
+
+						memcpy(&rn, &sl->reg_num, sizeof(rn));
+
+						kfree(sl);
+
+						w1_attach_slave_device(dev, &rn);
+					}
+				}
+				clear_bit(W1_MASTER_NEED_RECONNECT, &dev->flags);
+				up(&dev->mutex);
 			}
-			w1_destroy_master_attributes(dev);
-			atomic_dec(&dev->refcnt);
 		}
 	}
 
@@ -720,51 +718,50 @@ int w1_control(void *data)
 int w1_process(void *data)
 {
 	struct w1_master *dev = (struct w1_master *) data;
-	struct list_head *ent, *n;
-	struct w1_slave *sl;
+	struct w1_slave *sl, *sln;
 
 	daemonize("%s", dev->name);
 	allow_signal(SIGTERM);
 
-	while (!dev->need_exit) {
-		try_to_freeze(PF_FREEZE);
+	while (!test_bit(W1_MASTER_NEED_EXIT, &dev->flags)) {
+		try_to_freeze();
 		msleep_interruptible(w1_timeout * 1000);
 
 		if (signal_pending(current))
 			flush_signals(current);
 
-		if (dev->need_exit)
+		if (test_bit(W1_MASTER_NEED_EXIT, &dev->flags))
 			break;
 
 		if (!dev->initialized)
 			continue;
 
+		if (dev->search_count == 0)
+			continue;
+
 		if (down_interruptible(&dev->mutex))
 			continue;
 
-		list_for_each_safe(ent, n, &dev->slist) {
-			sl = list_entry(ent, struct w1_slave, w1_slave_entry);
+		list_for_each_entry(sl, &dev->slist, w1_slave_entry)
+			clear_bit(W1_SLAVE_ACTIVE, (long *)&sl->flags);
 
-			if (sl)
-				clear_bit(W1_SLAVE_ACTIVE, (long *)&sl->flags);
-		}
-		
 		w1_search_devices(dev, w1_slave_found);
 
-		list_for_each_safe(ent, n, &dev->slist) {
-			sl = list_entry(ent, struct w1_slave, w1_slave_entry);
-
-			if (sl && !test_bit(W1_SLAVE_ACTIVE, (unsigned long *)&sl->flags) && !--sl->ttl) {
+		list_for_each_entry_safe(sl, sln, &dev->slist, w1_slave_entry) {
+			if (!test_bit(W1_SLAVE_ACTIVE, (unsigned long *)&sl->flags) && !--sl->ttl) {
 				list_del (&sl->w1_slave_entry);
 
 				w1_slave_detach (sl);
 				kfree (sl);
 
 				dev->slave_count--;
-			}
-			else if (test_bit(W1_SLAVE_ACTIVE, (unsigned long *)&sl->flags))
+			} else if (test_bit(W1_SLAVE_ACTIVE, (unsigned long *)&sl->flags))
 				sl->ttl = dev->slave_ttl;
 		}
+
+		if (dev->search_count > 0)
+			dev->search_count--;
+
 		up(&dev->mutex);
 	}
 
@@ -774,7 +771,7 @@ int w1_process(void *data)
 	return 0;
 }
 
-int w1_init(void)
+static int w1_init(void)
 {
 	int retval;
 
@@ -814,18 +811,14 @@ err_out_exit_init:
 	return retval;
 }
 
-void w1_fini(void)
+static void w1_fini(void)
 {
 	struct w1_master *dev;
-	struct list_head *ent, *n;
 
-	list_for_each_safe(ent, n, &w1_masters) {
-		dev = list_entry(ent, struct w1_master, w1_master_entry);
+	list_for_each_entry(dev, &w1_masters, w1_master_entry)
 		__w1_remove_master_device(dev);
-	}
 
 	control_needs_exit = 1;
-
 	wait_for_completion(&w1_control_complete);
 
 	driver_unregister(&w1_driver);
diff --git a/drivers/w1/w1.h b/drivers/w1/w1.h
--- a/drivers/w1/w1.h
+++ b/drivers/w1/w1.h
@@ -1,8 +1,8 @@
 /*
- * 	w1.h
+ *	w1.h
  *
  * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru>
- * 
+ *
  *
  * 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
@@ -74,36 +74,86 @@ struct w1_slave
 	int			ttl;
 
 	struct w1_master	*master;
-	struct w1_family 	*family;
-	struct device 		dev;
-	struct completion 	dev_released;
+	struct w1_family	*family;
+	struct device		dev;
+	struct completion	dev_released;
 
-	struct bin_attribute 	attr_bin;
-	struct device_attribute	attr_name, attr_val;
+	struct bin_attribute	attr_bin;
+	struct device_attribute	attr_name;
 };
 
 typedef void (* w1_slave_found_callback)(unsigned long, u64);
 
+
+/**
+ * Note: read_bit and write_bit are very low level functions and should only
+ * be used with hardware that doesn't really support 1-wire operations,
+ * like a parallel/serial port.
+ * Either define read_bit and write_bit OR define, at minimum, touch_bit and
+ * reset_bus.
+ */
 struct w1_bus_master
 {
-	unsigned long		data;
+	/** the first parameter in all the functions below */
+	unsigned long	data;
 
-	u8			(*read_bit)(unsigned long);
-	void			(*write_bit)(unsigned long, u8);
-  	
-	u8			(*read_byte)(unsigned long);
-  	void			(*write_byte)(unsigned long, u8);
-  	
-	u8			(*read_block)(unsigned long, u8 *, int);
-	void			(*write_block)(unsigned long, u8 *, int);
-	
-  	u8			(*touch_bit)(unsigned long, u8);
-  
-  	u8			(*reset_bus)(unsigned long);
+	/**
+	 * Sample the line level
+	 * @return the level read (0 or 1)
+	 */
+	u8		(*read_bit)(unsigned long);
+
+	/** Sets the line level */
+	void		(*write_bit)(unsigned long, u8);
+
+	/**
+	 * touch_bit is the lowest-level function for devices that really
+	 * support the 1-wire protocol.
+	 * touch_bit(0) = write-0 cycle
+	 * touch_bit(1) = write-1 / read cycle
+	 * @return the bit read (0 or 1)
+	 */
+	u8		(*touch_bit)(unsigned long, u8);
+
+	/**
+	 * Reads a bytes. Same as 8 touch_bit(1) calls.
+	 * @return the byte read
+	 */
+	u8		(*read_byte)(unsigned long);
+
+	/**
+	 * Writes a byte. Same as 8 touch_bit(x) calls.
+	 */
+	void		(*write_byte)(unsigned long, u8);
+
+	/**
+	 * Same as a series of read_byte() calls
+	 * @return the number of bytes read
+	 */
+	u8		(*read_block)(unsigned long, u8 *, int);
+
+	/** Same as a series of write_byte() calls */
+	void		(*write_block)(unsigned long, const u8 *, int);
+
+	/**
+	 * Combines two reads and a smart write for ROM searches
+	 * @return bit0=Id bit1=comp_id bit2=dir_taken
+	 */
+	u8		(*triplet)(unsigned long, u8);
+
+	/**
+	 * long write-0 with a read for the presence pulse detection
+	 * @return -1=Error, 0=Device present, 1=No device present
+	 */
+	u8		(*reset_bus)(unsigned long);
 
-	void			(*search)(unsigned long, w1_slave_found_callback);
+	/** Really nice hardware can handles the ROM searches */
+	void		(*search)(unsigned long, w1_slave_found_callback);
 };
 
+#define W1_MASTER_NEED_EXIT		0
+#define W1_MASTER_NEED_RECONNECT	1
+
 struct w1_master
 {
 	struct list_head	w1_master_entry;
@@ -115,30 +165,31 @@ struct w1_master
 	int			slave_ttl;
 	int			initialized;
 	u32			id;
+	int			search_count;
 
 	atomic_t		refcnt;
 
 	void			*priv;
 	int			priv_size;
 
-	int			need_exit;
+	long			flags;
+
 	pid_t			kpid;
-	struct semaphore 	mutex;
+	struct semaphore	mutex;
 
 	struct device_driver	*driver;
-	struct device 		dev;
-	struct completion 	dev_released;
-	struct completion 	dev_exited;
+	struct device		dev;
+	struct completion	dev_released;
+	struct completion	dev_exited;
 
 	struct w1_bus_master	*bus_master;
 
 	u32			seq, groups;
-	struct sock 		*nls;
+	struct sock		*nls;
 };
 
 int w1_create_master_attributes(struct w1_master *);
-void w1_destroy_master_attributes(struct w1_master *);
-void w1_search(struct w1_master *dev);
+void w1_search(struct w1_master *dev, w1_slave_found_callback cb);
 
 #endif /* __KERNEL__ */
 
diff --git a/drivers/w1/w1_family.c b/drivers/w1/w1_family.c
--- a/drivers/w1/w1_family.c
+++ b/drivers/w1/w1_family.c
@@ -1,8 +1,8 @@
 /*
- * 	w1_family.c
+ *	w1_family.c
  *
  * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru>
- * 
+ *
  *
  * 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
@@ -27,10 +27,11 @@
 
 DEFINE_SPINLOCK(w1_flock);
 static LIST_HEAD(w1_families);
+extern void w1_reconnect_slaves(struct w1_family *f);
 
 static int w1_check_family(struct w1_family *f)
 {
-	if (!f->fops->rname || !f->fops->rbin || !f->fops->rval || !f->fops->rvalname)
+	if (!f->fops->rname || !f->fops->rbin)
 		return -EINVAL;
 
 	return 0;
@@ -60,9 +61,10 @@ int w1_register_family(struct w1_family 
 		newf->need_exit = 0;
 		list_add_tail(&newf->family_entry, &w1_families);
 	}
-
 	spin_unlock(&w1_flock);
 
+	w1_reconnect_slaves(newf);
+
 	return ret;
 }
 
diff --git a/drivers/w1/w1_family.h b/drivers/w1/w1_family.h
--- a/drivers/w1/w1_family.h
+++ b/drivers/w1/w1_family.h
@@ -1,8 +1,8 @@
 /*
- * 	w1_family.h
+ *	w1_family.h
  *
  * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru>
- * 
+ *
  *
  * 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
@@ -27,27 +27,27 @@
 #include <asm/atomic.h>
 
 #define W1_FAMILY_DEFAULT	0
-#define W1_FAMILY_THERM		0x10
-#define W1_FAMILY_SMEM		0x01
+#define W1_FAMILY_SMEM_01	0x01
+#define W1_FAMILY_SMEM_81	0x81
+#define W1_THERM_DS18S20 	0x10
+#define W1_THERM_DS1822  	0x22
+#define W1_THERM_DS18B20 	0x28
 
 #define MAXNAMELEN		32
 
 struct w1_family_ops
 {
-	ssize_t (* rname)(struct device *, char *);
+	ssize_t (* rname)(struct device *, struct device_attribute *, char *);
 	ssize_t (* rbin)(struct kobject *, char *, loff_t, size_t);
-	
-	ssize_t (* rval)(struct device *, char *);
-	unsigned char rvalname[MAXNAMELEN];
 };
 
 struct w1_family
 {
 	struct list_head	family_entry;
 	u8			fid;
-	
+
 	struct w1_family_ops	*fops;
-	
+
 	atomic_t		refcnt;
 	u8			need_exit;
 };
diff --git a/drivers/w1/w1_int.c b/drivers/w1/w1_int.c
--- a/drivers/w1/w1_int.c
+++ b/drivers/w1/w1_int.c
@@ -1,8 +1,8 @@
 /*
- * 	w1_int.c
+ *	w1_int.c
  *
  * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru>
- * 
+ *
  *
  * 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
@@ -39,8 +39,9 @@ extern spinlock_t w1_mlock;
 
 extern int w1_process(void *);
 
-struct w1_master * w1_alloc_dev(u32 id, int slave_count, int slave_ttl,
-	      struct device_driver *driver, struct device *device)
+static struct w1_master * w1_alloc_dev(u32 id, int slave_count, int slave_ttl,
+				       struct device_driver *driver,
+				       struct device *device)
 {
 	struct w1_master *dev;
 	int err;
@@ -60,14 +61,15 @@ struct w1_master * w1_alloc_dev(u32 id, 
 
 	dev->bus_master = (struct w1_bus_master *)(dev + 1);
 
-	dev->owner 		= THIS_MODULE;
-	dev->max_slave_count 	= slave_count;
-	dev->slave_count 	= 0;
-	dev->attempts 		= 0;
-	dev->kpid 		= -1;
-	dev->initialized 	= 0;
-	dev->id 		= id;
+	dev->owner		= THIS_MODULE;
+	dev->max_slave_count	= slave_count;
+	dev->slave_count	= 0;
+	dev->attempts		= 0;
+	dev->kpid		= -1;
+	dev->initialized	= 0;
+	dev->id			= id;
 	dev->slave_ttl		= slave_ttl;
+        dev->search_count	= -1; /* continual scan */
 
 	atomic_set(&dev->refcnt, 2);
 
@@ -86,7 +88,7 @@ struct w1_master * w1_alloc_dev(u32 id, 
 
 	dev->groups = 23;
 	dev->seq = 1;
-	dev->nls = netlink_kernel_create(NETLINK_NFLOG, NULL);
+	dev->nls = netlink_kernel_create(NETLINK_W1, NULL);
 	if (!dev->nls) {
 		printk(KERN_ERR "Failed to create new netlink socket(%u) for w1 master %s.\n",
 			NETLINK_NFLOG, dev->dev.bus_id);
@@ -105,7 +107,7 @@ struct w1_master * w1_alloc_dev(u32 id, 
 	return dev;
 }
 
-void w1_free_dev(struct w1_master *dev)
+static void w1_free_dev(struct w1_master *dev)
 {
 	device_unregister(&dev->dev);
 	if (dev->nls && dev->nls->sk_socket)
@@ -120,6 +122,13 @@ int w1_add_master_device(struct w1_bus_m
 	int retval = 0;
 	struct w1_netlink_msg msg;
 
+        /* validate minimum functionality */
+        if (!(master->touch_bit && master->reset_bus) &&
+            !(master->write_bit && master->read_bit)) {
+		printk(KERN_ERR "w1_add_master_device: invalid function set\n");
+		return(-EINVAL);
+        }
+
 	dev = w1_alloc_dev(w1_ids++, w1_max_slave_count, w1_max_slave_ttl, &w1_driver, &w1_device);
 	if (!dev)
 		return -ENOMEM;
@@ -153,7 +162,7 @@ int w1_add_master_device(struct w1_bus_m
 	return 0;
 
 err_out_kill_thread:
-	dev->need_exit = 1;
+	set_bit(W1_MASTER_NEED_EXIT, &dev->flags);
 	if (kill_proc(dev->kpid, SIGTERM, 1))
 		dev_err(&dev->dev,
 			 "Failed to send signal to w1 kernel thread %d.\n",
@@ -171,7 +180,7 @@ void __w1_remove_master_device(struct w1
 	int err;
 	struct w1_netlink_msg msg;
 
-	dev->need_exit = 1;
+	set_bit(W1_MASTER_NEED_EXIT, &dev->flags);
 	err = kill_proc(dev->kpid, SIGTERM, 1);
 	if (err)
 		dev_err(&dev->dev,
@@ -197,10 +206,8 @@ void __w1_remove_master_device(struct w1
 void w1_remove_master_device(struct w1_bus_master *bm)
 {
 	struct w1_master *dev = NULL;
-	struct list_head *ent, *n;
 
-	list_for_each_safe(ent, n, &w1_masters) {
-		dev = list_entry(ent, struct w1_master, w1_master_entry);
+	list_for_each_entry(dev, &w1_masters, w1_master_entry) {
 		if (!dev->initialized)
 			continue;
 
diff --git a/drivers/w1/w1_int.h b/drivers/w1/w1_int.h
--- a/drivers/w1/w1_int.h
+++ b/drivers/w1/w1_int.h
@@ -1,8 +1,8 @@
 /*
- * 	w1_int.h
+ *	w1_int.h
  *
  * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru>
- * 
+ *
  *
  * 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
@@ -27,8 +27,6 @@
 
 #include "w1.h"
 
-struct w1_master * w1_alloc_dev(u32, int, int, struct device_driver *, struct device *);
-void w1_free_dev(struct w1_master *dev);
 int w1_add_master_device(struct w1_bus_master *);
 void w1_remove_master_device(struct w1_bus_master *);
 void __w1_remove_master_device(struct w1_master *);
diff --git a/drivers/w1/w1_io.c b/drivers/w1/w1_io.c
--- a/drivers/w1/w1_io.c
+++ b/drivers/w1/w1_io.c
@@ -1,8 +1,8 @@
 /*
- * 	w1_io.c
+ *	w1_io.c
  *
  * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru>
- * 
+ *
  *
  * 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
@@ -55,15 +55,29 @@ void w1_delay(unsigned long tm)
 	udelay(tm * w1_delay_parm);
 }
 
+static void w1_write_bit(struct w1_master *dev, int bit);
+static u8 w1_read_bit(struct w1_master *dev);
+
+/**
+ * Generates a write-0 or write-1 cycle and samples the level.
+ */
 u8 w1_touch_bit(struct w1_master *dev, int bit)
 {
 	if (dev->bus_master->touch_bit)
 		return dev->bus_master->touch_bit(dev->bus_master->data, bit);
-	else
+	else if (bit)
 		return w1_read_bit(dev);
+	else {
+		w1_write_bit(dev, 0);
+		return(0);
+	}
 }
 
-void w1_write_bit(struct w1_master *dev, int bit)
+/**
+ * Generates a write-0 or write-1 cycle.
+ * Only call if dev->bus_master->touch_bit is NULL
+ */
+static void w1_write_bit(struct w1_master *dev, int bit)
 {
 	if (bit) {
 		dev->bus_master->write_bit(dev->bus_master->data, 0);
@@ -78,6 +92,12 @@ void w1_write_bit(struct w1_master *dev,
 	}
 }
 
+/**
+ * Writes 8 bits.
+ *
+ * @param dev     the master device
+ * @param byte    the byte to write
+ */
 void w1_write_8(struct w1_master *dev, u8 byte)
 {
 	int i;
@@ -86,10 +106,15 @@ void w1_write_8(struct w1_master *dev, u
 		dev->bus_master->write_byte(dev->bus_master->data, byte);
 	else
 		for (i = 0; i < 8; ++i)
-			w1_write_bit(dev, (byte >> i) & 0x1);
+			w1_touch_bit(dev, (byte >> i) & 0x1);
 }
 
-u8 w1_read_bit(struct w1_master *dev)
+
+/**
+ * Generates a write-1 cycle and samples the level.
+ * Only call if dev->bus_master->touch_bit is NULL
+ */
+static u8 w1_read_bit(struct w1_master *dev)
 {
 	int result;
 
@@ -104,6 +129,53 @@ u8 w1_read_bit(struct w1_master *dev)
 	return result & 0x1;
 }
 
+/**
+ * Does a triplet - used for searching ROM addresses.
+ * Return bits:
+ *  bit 0 = id_bit
+ *  bit 1 = comp_bit
+ *  bit 2 = dir_taken
+ * If both bits 0 & 1 are set, the search should be restarted.
+ *
+ * @param dev     the master device
+ * @param bdir    the bit to write if both id_bit and comp_bit are 0
+ * @return        bit fields - see above
+ */
+u8 w1_triplet(struct w1_master *dev, int bdir)
+{
+	if ( dev->bus_master->triplet )
+		return(dev->bus_master->triplet(dev->bus_master->data, bdir));
+	else {
+		u8 id_bit   = w1_touch_bit(dev, 1);
+		u8 comp_bit = w1_touch_bit(dev, 1);
+		u8 retval;
+
+		if ( id_bit && comp_bit )
+			return(0x03);  /* error */
+
+		if ( !id_bit && !comp_bit ) {
+			/* Both bits are valid, take the direction given */
+			retval = bdir ? 0x04 : 0;
+		} else {
+			/* Only one bit is valid, take that direction */
+			bdir = id_bit;
+			retval = id_bit ? 0x05 : 0x02;
+		}
+
+		if ( dev->bus_master->touch_bit )
+			w1_touch_bit(dev, bdir);
+		else
+			w1_write_bit(dev, bdir);
+		return(retval);
+	}
+}
+
+/**
+ * Reads 8 bits.
+ *
+ * @param dev     the master device
+ * @return        the byte read
+ */
 u8 w1_read_8(struct w1_master * dev)
 {
 	int i;
@@ -113,12 +185,20 @@ u8 w1_read_8(struct w1_master * dev)
 		res = dev->bus_master->read_byte(dev->bus_master->data);
 	else
 		for (i = 0; i < 8; ++i)
-			res |= (w1_read_bit(dev) << i);
+			res |= (w1_touch_bit(dev,1) << i);
 
 	return res;
 }
 
-void w1_write_block(struct w1_master *dev, u8 *buf, int len)
+/**
+ * Writes a series of bytes.
+ *
+ * @param dev     the master device
+ * @param buf     pointer to the data to write
+ * @param len     the number of bytes to write
+ * @return        the byte read
+ */
+void w1_write_block(struct w1_master *dev, const u8 *buf, int len)
 {
 	int i;
 
@@ -129,6 +209,14 @@ void w1_write_block(struct w1_master *de
 			w1_write_8(dev, buf[i]);
 }
 
+/**
+ * Reads a series of bytes.
+ *
+ * @param dev     the master device
+ * @param buf     pointer to the buffer to fill
+ * @param len     the number of bytes to read
+ * @return        the number of bytes read
+ */
 u8 w1_read_block(struct w1_master *dev, u8 *buf, int len)
 {
 	int i;
@@ -145,9 +233,15 @@ u8 w1_read_block(struct w1_master *dev, 
 	return ret;
 }
 
+/**
+ * Issues a reset bus sequence.
+ *
+ * @param  dev The bus master pointer
+ * @return     0=Device present, 1=No device present or error
+ */
 int w1_reset_bus(struct w1_master *dev)
 {
-	int result = 0;
+	int result;
 
 	if (dev->bus_master->reset_bus)
 		result = dev->bus_master->reset_bus(dev->bus_master->data) & 0x1;
@@ -180,12 +274,11 @@ void w1_search_devices(struct w1_master 
 	if (dev->bus_master->search)
 		dev->bus_master->search(dev->bus_master->data, cb);
 	else
-		w1_search(dev);
+		w1_search(dev, cb);
 }
 
-EXPORT_SYMBOL(w1_write_bit);
+EXPORT_SYMBOL(w1_touch_bit);
 EXPORT_SYMBOL(w1_write_8);
-EXPORT_SYMBOL(w1_read_bit);
 EXPORT_SYMBOL(w1_read_8);
 EXPORT_SYMBOL(w1_reset_bus);
 EXPORT_SYMBOL(w1_calc_crc8);
diff --git a/drivers/w1/w1_io.h b/drivers/w1/w1_io.h
--- a/drivers/w1/w1_io.h
+++ b/drivers/w1/w1_io.h
@@ -1,8 +1,8 @@
 /*
- * 	w1_io.h
+ *	w1_io.h
  *
  * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru>
- * 
+ *
  *
  * 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
@@ -26,13 +26,12 @@
 
 void w1_delay(unsigned long);
 u8 w1_touch_bit(struct w1_master *, int);
-void w1_write_bit(struct w1_master *, int);
+u8 w1_triplet(struct w1_master *dev, int bdir);
 void w1_write_8(struct w1_master *, u8);
-u8 w1_read_bit(struct w1_master *);
 u8 w1_read_8(struct w1_master *);
 int w1_reset_bus(struct w1_master *);
 u8 w1_calc_crc8(u8 *, int);
-void w1_write_block(struct w1_master *, u8 *, int);
+void w1_write_block(struct w1_master *, const u8 *, int);
 u8 w1_read_block(struct w1_master *, u8 *, int);
 void w1_search_devices(struct w1_master *dev, w1_slave_found_callback cb);
 
diff --git a/drivers/w1/w1_log.h b/drivers/w1/w1_log.h
--- a/drivers/w1/w1_log.h
+++ b/drivers/w1/w1_log.h
@@ -1,8 +1,8 @@
 /*
- * 	w1_log.h
+ *	w1_log.h
  *
  * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru>
- * 
+ *
  *
  * 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
diff --git a/drivers/w1/w1_netlink.h b/drivers/w1/w1_netlink.h
--- a/drivers/w1/w1_netlink.h
+++ b/drivers/w1/w1_netlink.h
@@ -33,13 +33,13 @@ enum w1_netlink_message_types {
 	W1_MASTER_REMOVE,
 };
 
-struct w1_netlink_msg 
+struct w1_netlink_msg
 {
 	__u8				type;
 	__u8				reserved[3];
 	union
 	{
-		struct w1_reg_num 	id;
+		struct w1_reg_num	id;
 		__u64			w1_id;
 		struct
 		{
diff --git a/drivers/w1/w1_smem.c b/drivers/w1/w1_smem.c
--- a/drivers/w1/w1_smem.c
+++ b/drivers/w1/w1_smem.c
@@ -1,8 +1,8 @@
 /*
- * 	w1_smem.c
+ *	w1_smem.c
  *
  * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru>
- * 
+ *
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the smems of the GNU General Public License as published by
@@ -36,41 +36,25 @@ MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Evgeniy Polyakov <johnpol@2ka.mipt.ru>");
 MODULE_DESCRIPTION("Driver for 1-wire Dallas network protocol, 64bit memory family.");
 
-static ssize_t w1_smem_read_name(struct device *, char *);
-static ssize_t w1_smem_read_val(struct device *, char *);
+static ssize_t w1_smem_read_name(struct device *, struct device_attribute *attr, char *);
 static ssize_t w1_smem_read_bin(struct kobject *, char *, loff_t, size_t);
 
 static struct w1_family_ops w1_smem_fops = {
 	.rname = &w1_smem_read_name,
 	.rbin = &w1_smem_read_bin,
-	.rval = &w1_smem_read_val,
-	.rvalname = "id",
 };
 
-static ssize_t w1_smem_read_name(struct device *dev, char *buf)
+static ssize_t w1_smem_read_name(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct w1_slave *sl = container_of(dev, struct w1_slave, dev);
 
 	return sprintf(buf, "%s\n", sl->name);
 }
 
-static ssize_t w1_smem_read_val(struct device *dev, char *buf)
-{
-	struct w1_slave *sl = container_of(dev, struct w1_slave, dev);
-	int i;
-	ssize_t count = 0;
-	
-	for (i = 0; i < 8; ++i)
-		count += sprintf(buf + count, "%02x ", ((u8 *)&sl->reg_num)[i]);
-	count += sprintf(buf + count, "\n");
-
-	return count;
-}
-
 static ssize_t w1_smem_read_bin(struct kobject *kobj, char *buf, loff_t off, size_t count)
 {
 	struct w1_slave *sl = container_of(container_of(kobj, struct device, kobj),
-			      			struct w1_slave, dev);
+					   struct w1_slave, dev);
 	int i;
 
 	atomic_inc(&sl->refcnt);
@@ -90,7 +74,7 @@ static ssize_t w1_smem_read_bin(struct k
 	for (i = 0; i < 8; ++i)
 		count += sprintf(buf + count, "%02x ", ((u8 *)&sl->reg_num)[i]);
 	count += sprintf(buf + count, "\n");
-	
+
 out:
 	up(&sl->master->mutex);
 out_dec:
@@ -99,19 +83,37 @@ out_dec:
 	return count;
 }
 
-static struct w1_family w1_smem_family = {
-	.fid = W1_FAMILY_SMEM,
+static struct w1_family w1_smem_family_01 = {
+	.fid = W1_FAMILY_SMEM_01,
+	.fops = &w1_smem_fops,
+};
+
+static struct w1_family w1_smem_family_81 = {
+	.fid = W1_FAMILY_SMEM_81,
 	.fops = &w1_smem_fops,
 };
 
 static int __init w1_smem_init(void)
 {
-	return w1_register_family(&w1_smem_family);
+	int err;
+
+	err = w1_register_family(&w1_smem_family_01);
+	if (err)
+		return err;
+	
+	err = w1_register_family(&w1_smem_family_81);
+	if (err) {
+		w1_unregister_family(&w1_smem_family_01);
+		return err;
+	}
+
+	return 0;
 }
 
 static void __exit w1_smem_fini(void)
 {
-	w1_unregister_family(&w1_smem_family);
+	w1_unregister_family(&w1_smem_family_01);
+	w1_unregister_family(&w1_smem_family_81);
 }
 
 module_init(w1_smem_init);
diff --git a/drivers/w1/w1_therm.c b/drivers/w1/w1_therm.c
--- a/drivers/w1/w1_therm.c
+++ b/drivers/w1/w1_therm.c
@@ -1,8 +1,8 @@
 /*
- * 	w1_therm.c
+ *	w1_therm.c
  *
  * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru>
- * 
+ *
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the therms of the GNU General Public License as published by
@@ -38,31 +38,78 @@ MODULE_AUTHOR("Evgeniy Polyakov <johnpol
 MODULE_DESCRIPTION("Driver for 1-wire Dallas network protocol, temperature family.");
 
 static u8 bad_roms[][9] = {
-				{0xaa, 0x00, 0x4b, 0x46, 0xff, 0xff, 0x0c, 0x10, 0x87}, 
+				{0xaa, 0x00, 0x4b, 0x46, 0xff, 0xff, 0x0c, 0x10, 0x87},
 				{}
 			};
 
-static ssize_t w1_therm_read_name(struct device *, char *);
-static ssize_t w1_therm_read_temp(struct device *, char *);
+static ssize_t w1_therm_read_name(struct device *, struct device_attribute *attr, char *);
 static ssize_t w1_therm_read_bin(struct kobject *, char *, loff_t, size_t);
 
 static struct w1_family_ops w1_therm_fops = {
 	.rname = &w1_therm_read_name,
 	.rbin = &w1_therm_read_bin,
-	.rval = &w1_therm_read_temp,
-	.rvalname = "temp1_input",
 };
 
-static ssize_t w1_therm_read_name(struct device *dev, char *buf)
+static struct w1_family w1_therm_family_DS18S20 = {
+	.fid = W1_THERM_DS18S20,
+	.fops = &w1_therm_fops,
+};
+
+static struct w1_family w1_therm_family_DS18B20 = {
+	.fid = W1_THERM_DS18B20,
+	.fops = &w1_therm_fops,
+};
+static struct w1_family w1_therm_family_DS1822 = {
+	.fid = W1_THERM_DS1822,
+	.fops = &w1_therm_fops,
+};
+
+struct w1_therm_family_converter
+{
+	u8			broken;
+	u16			reserved;
+	struct w1_family	*f;
+	int			(*convert)(u8 rom[9]);
+};
+
+static inline int w1_DS18B20_convert_temp(u8 rom[9]);
+static inline int w1_DS18S20_convert_temp(u8 rom[9]);
+
+static struct w1_therm_family_converter w1_therm_families[] = {
+	{
+		.f		= &w1_therm_family_DS18S20,
+		.convert 	= w1_DS18S20_convert_temp
+	},
+	{
+		.f		= &w1_therm_family_DS1822,
+		.convert 	= w1_DS18B20_convert_temp
+	},
+	{
+		.f		= &w1_therm_family_DS18B20,
+		.convert 	= w1_DS18B20_convert_temp
+	},
+};
+
+static ssize_t w1_therm_read_name(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct w1_slave *sl = container_of(dev, struct w1_slave, dev);
 
 	return sprintf(buf, "%s\n", sl->name);
 }
 
-static inline int w1_convert_temp(u8 rom[9])
+static inline int w1_DS18B20_convert_temp(u8 rom[9])
+{
+	int t = (rom[1] << 8) | rom[0];
+	t /= 16;
+	return t;
+}
+
+static inline int w1_DS18S20_convert_temp(u8 rom[9])
 {
 	int t, h;
+
+	if (!rom[7])
+		return 0;
 	
 	if (rom[1] == 0)
 		t = ((s32)rom[0] >> 1)*1000;
@@ -77,11 +124,15 @@ static inline int w1_convert_temp(u8 rom
 	return t;
 }
 
-static ssize_t w1_therm_read_temp(struct device *dev, char *buf)
+static inline int w1_convert_temp(u8 rom[9], u8 fid)
 {
-	struct w1_slave *sl = container_of(dev, struct w1_slave, dev);
+	int i;
+
+	for (i=0; i<sizeof(w1_therm_families)/sizeof(w1_therm_families[0]); ++i)
+		if (w1_therm_families[i].f->fid == fid)
+			return w1_therm_families[i].convert(rom);
 
-	return sprintf(buf, "%d\n", w1_convert_temp(sl->rom));
+	return 0;
 }
 
 static int w1_therm_check_rom(u8 rom[9])
@@ -98,7 +149,7 @@ static int w1_therm_check_rom(u8 rom[9])
 static ssize_t w1_therm_read_bin(struct kobject *kobj, char *buf, loff_t off, size_t count)
 {
 	struct w1_slave *sl = container_of(container_of(kobj, struct device, kobj),
-			      			struct w1_slave, dev);
+					   struct w1_slave, dev);
 	struct w1_master *dev = sl->master;
 	u8 rom[9], crc, verdict;
 	int i, max_trying = 10;
@@ -133,7 +184,7 @@ static ssize_t w1_therm_read_bin(struct 
 			unsigned int tm = 750;
 
 			memcpy(&match[1], (u64 *) & sl->reg_num, 8);
-			
+
 			w1_write_block(dev, match, 9);
 
 			w1_write_8(dev, W1_CONVERT_TEMP);
@@ -146,7 +197,7 @@ static ssize_t w1_therm_read_bin(struct 
 
 			if (!w1_reset_bus (dev)) {
 				w1_write_block(dev, match, 9);
-				
+
 				w1_write_8(dev, W1_READ_SCRATCHPAD);
 				if ((count = w1_read_block(dev, rom, 9)) != 9) {
 					dev_warn(&dev->dev, "w1_read_block() returned %d instead of 9.\n", count);
@@ -176,7 +227,7 @@ static ssize_t w1_therm_read_bin(struct 
 	for (i = 0; i < 9; ++i)
 		count += sprintf(buf + count, "%02x ", sl->rom[i]);
 	
-	count += sprintf(buf + count, "t=%d\n", w1_convert_temp(rom));
+	count += sprintf(buf + count, "t=%d\n", w1_convert_temp(rom, sl->family->fid));
 out:
 	up(&dev->mutex);
 out_dec:
@@ -186,19 +237,26 @@ out_dec:
 	return count;
 }
 
-static struct w1_family w1_therm_family = {
-	.fid = W1_FAMILY_THERM,
-	.fops = &w1_therm_fops,
-};
-
 static int __init w1_therm_init(void)
 {
-	return w1_register_family(&w1_therm_family);
+	int err, i;
+
+	for (i=0; i<sizeof(w1_therm_families)/sizeof(w1_therm_families[0]); ++i) {
+		err = w1_register_family(w1_therm_families[i].f);
+		if (err)
+			w1_therm_families[i].broken = 1;
+	}
+
+	return 0;
 }
 
 static void __exit w1_therm_fini(void)
 {
-	w1_unregister_family(&w1_therm_family);
+	int i;
+
+	for (i=0; i<sizeof(w1_therm_families)/sizeof(w1_therm_families[0]); ++i)
+		if (!w1_therm_families[i].broken)
+			w1_unregister_family(w1_therm_families[i].f);
 }
 
 module_init(w1_therm_init);
diff --git a/drivers/zorro/zorro-sysfs.c b/drivers/zorro/zorro-sysfs.c
--- a/drivers/zorro/zorro-sysfs.c
+++ b/drivers/zorro/zorro-sysfs.c
@@ -21,7 +21,7 @@
 /* show configuration fields */
 #define zorro_config_attr(name, field, format_string)			\
 static ssize_t								\
-show_##name(struct device *dev, char *buf)				\
+show_##name(struct device *dev, struct device_attribute *attr, char *buf)				\
 {									\
 	struct zorro_dev *z;						\
 									\
@@ -36,7 +36,7 @@ zorro_config_attr(serial, rom.er_SerialN
 zorro_config_attr(slotaddr, slotaddr, "0x%04x\n");
 zorro_config_attr(slotsize, slotsize, "0x%04x\n");
 
-static ssize_t zorro_show_resource(struct device *dev, char *buf)
+static ssize_t zorro_show_resource(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct zorro_dev *z = to_zorro_dev(dev);
 
diff --git a/fs/Kconfig b/fs/Kconfig
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -29,6 +29,7 @@ config EXT2_FS_XATTR
 config EXT2_FS_POSIX_ACL
 	bool "Ext2 POSIX Access Control Lists"
 	depends on EXT2_FS_XATTR
+	select FS_POSIX_ACL
 	help
 	  Posix Access Control Lists (ACLs) support permissions for users and
 	  groups beyond the owner/group/world scheme.
@@ -50,6 +51,23 @@ config EXT2_FS_SECURITY
 	  If you are not using a security module that requires using
 	  extended attributes for file security labels, say N.
 
+config EXT2_FS_XIP
+	bool "Ext2 execute in place support"
+	depends on EXT2_FS
+	help
+	  Execute in place can be used on memory-backed block devices. If you
+	  enable this option, you can select to mount block devices which are
+	  capable of this feature without using the page cache.
+
+	  If you do not use a block device that is capable of using this,
+	  or if unsure, say N.
+
+config FS_XIP
+# execute in place
+	bool
+	depends on EXT2_FS_XIP
+	default y
+
 config EXT3_FS
 	tristate "Ext3 journalling file system support"
 	help
@@ -97,6 +115,7 @@ config EXT3_FS_XATTR
 config EXT3_FS_POSIX_ACL
 	bool "Ext3 POSIX Access Control Lists"
 	depends on EXT3_FS_XATTR
+	select FS_POSIX_ACL
 	help
 	  Posix Access Control Lists (ACLs) support permissions for users and
 	  groups beyond the owner/group/world scheme.
@@ -224,6 +243,7 @@ config REISERFS_FS_XATTR
 config REISERFS_FS_POSIX_ACL
 	bool "ReiserFS POSIX Access Control Lists"
 	depends on REISERFS_FS_XATTR
+	select FS_POSIX_ACL
 	help
 	  Posix Access Control Lists (ACLs) support permissions for users and
 	  groups beyond the owner/group/world scheme.
@@ -257,6 +277,7 @@ config JFS_FS
 config JFS_POSIX_ACL
 	bool "JFS POSIX Access Control Lists"
 	depends on JFS_FS
+	select FS_POSIX_ACL
 	help
 	  Posix Access Control Lists (ACLs) support permissions for users and
 	  groups beyond the owner/group/world scheme.
@@ -301,8 +322,7 @@ config FS_POSIX_ACL
 # 	Never use this symbol for ifdefs.
 #
 	bool
-	depends on EXT2_FS_POSIX_ACL || EXT3_FS_POSIX_ACL || JFS_POSIX_ACL || REISERFS_FS_POSIX_ACL || NFSD_V4
-	default y
+	default n
 
 source "fs/xfs/Kconfig"
 
@@ -339,6 +359,22 @@ config ROMFS_FS
 	  If you don't know whether you need it, then you don't need it:
 	  answer N.
 
+config INOTIFY
+	bool "Inotify file change notification support"
+	default y
+	---help---
+	  Say Y here to enable inotify support and the associated system
+	  calls.  Inotify is a file change notification system and a
+	  replacement for dnotify.  Inotify fixes numerous shortcomings in
+	  dnotify and introduces several new features.  It allows monitoring
+	  of both files and directories via a single open fd.  Other features
+	  include multiple file events, one-shot support, and unmount
+	  notification.
+
+	  For more information, see Documentation/filesystems/inotify.txt
+
+	  If unsure, say Y.
+
 config QUOTA
 	bool "Quota support"
 	help
@@ -717,6 +753,12 @@ config PROC_KCORE
 	bool "/proc/kcore support" if !ARM
 	depends on PROC_FS && MMU
 
+config PROC_VMCORE
+        bool "/proc/vmcore support (EXPERIMENTAL)"
+        depends on PROC_FS && EMBEDDED && EXPERIMENTAL && CRASH_DUMP
+        help
+        Exports the dump image of crashed kernel in ELF format.
+
 config SYSFS
 	bool "sysfs file system support" if EMBEDDED
 	default y
@@ -741,56 +783,6 @@ config SYSFS
 
 	Designers of embedded systems may wish to say N here to conserve space.
 
-config DEVFS_FS
-	bool "/dev file system support (OBSOLETE)"
-	depends on EXPERIMENTAL
-	help
-	  This is support for devfs, a virtual file system (like /proc) which
-	  provides the file system interface to device drivers, normally found
-	  in /dev. Devfs does not depend on major and minor number
-	  allocations. Device drivers register entries in /dev which then
-	  appear automatically, which means that the system administrator does
-	  not have to create character and block special device files in the
-	  /dev directory using the mknod command (or MAKEDEV script) anymore.
-
-	  This is work in progress. If you want to use this, you *must* read
-	  the material in <file:Documentation/filesystems/devfs/>, especially
-	  the file README there.
-
-	  Note that devfs no longer manages /dev/pts!  If you are using UNIX98
-	  ptys, you will also need to mount the /dev/pts filesystem (devpts).
-
-	  Note that devfs has been obsoleted by udev,
-	  <http://www.kernel.org/pub/linux/utils/kernel/hotplug/>.
-	  It has been stripped down to a bare minimum and is only provided for
-	  legacy installations that use its naming scheme which is
-	  unfortunately different from the names normal Linux installations
-	  use.
-
-	  If unsure, say N.
-
-config DEVFS_MOUNT
-	bool "Automatically mount at boot"
-	depends on DEVFS_FS
-	help
-	  This option appears if you have CONFIG_DEVFS_FS enabled. Setting
-	  this to 'Y' will make the kernel automatically mount devfs onto /dev
-	  when the system is booted, before the init thread is started.
-	  You can override this with the "devfs=nomount" boot option.
-
-	  If unsure, say N.
-
-config DEVFS_DEBUG
-	bool "Debug devfs"
-	depends on DEVFS_FS
-	help
-	  If you say Y here, then the /dev file system code will generate
-	  debugging messages. See the file
-	  <file:Documentation/filesystems/devfs/boot-options> for more
-	  details.
-
-	  If unsure, say N.
-
 config DEVPTS_FS_XATTR
 	bool "/dev/pts Extended Attributes"
 	depends on UNIX98_PTYS
@@ -1063,26 +1055,18 @@ config JFFS2_FS_DEBUG
 	  If reporting bugs, please try to have available a full dump of the
 	  messages at debug level 1 while the misbehaviour was occurring.
 
-config JFFS2_FS_NAND
-	bool "JFFS2 support for NAND flash"
+config JFFS2_FS_WRITEBUFFER
+	bool "JFFS2 write-buffering support"
 	depends on JFFS2_FS
-	default n
+	default y
 	help
-	  This enables the support for NAND flash in JFFS2. NAND is a newer
-	  type of flash chip design than the traditional NOR flash, with
-	  higher density but a handful of characteristics which make it more
-	  interesting for the file system to use.
-
-	  Say 'N' unless you have NAND flash.
-
-config JFFS2_FS_NOR_ECC
-        bool "JFFS2 support for ECC'd NOR flash (EXPERIMENTAL)"
-        depends on JFFS2_FS && EXPERIMENTAL
-        default n
-        help
-          This enables the experimental support for NOR flash with transparent
-          ECC for JFFS2. This type of flash chip is not common, however it is
-          available from ST Microelectronics.
+	  This enables the write-buffering support in JFFS2.
+
+	  This functionality is required to support JFFS2 on the following
+	  types of flash devices:
+	    - NAND flash
+	    - NOR flash with transparent ECC
+	    - DataFlash
 
 config JFFS2_COMPRESSION_OPTIONS
 	bool "Advanced compression options for JFFS2"
@@ -1318,6 +1302,7 @@ config NFS_FS
 	depends on INET
 	select LOCKD
 	select SUNRPC
+	select NFS_ACL_SUPPORT if NFS_V3_ACL
 	help
 	  If you are connected to some other (usually local) Unix computer
 	  (using SLIP, PLIP, PPP or Ethernet) and want to mount files residing
@@ -1360,6 +1345,16 @@ config NFS_V3
 
 	  If unsure, say Y.
 
+config NFS_V3_ACL
+	bool "Provide client support for the NFSv3 ACL protocol extension"
+	depends on NFS_V3
+	help
+	  Implement the NFSv3 ACL protocol extension for manipulating POSIX
+	  Access Control Lists.  The server should also be compiled with
+	  the NFSv3 ACL protocol extension; see the CONFIG_NFSD_V3_ACL option.
+
+	  If unsure, say N.
+
 config NFS_V4
 	bool "Provide NFSv4 client support (EXPERIMENTAL)"
 	depends on NFS_FS && EXPERIMENTAL
@@ -1403,6 +1398,7 @@ config NFSD
 	select LOCKD
 	select SUNRPC
 	select EXPORTFS
+	select NFS_ACL_SUPPORT if NFSD_V3_ACL || NFSD_V2_ACL
 	help
 	  If you want your Linux box to act as an NFS *server*, so that other
 	  computers on your local network which support NFS can access certain
@@ -1426,6 +1422,10 @@ config NFSD
 	  To compile the NFS server support as a module, choose M here: the
 	  module will be called nfsd.  If unsure, say N.
 
+config NFSD_V2_ACL
+	bool
+	depends on NFSD
+
 config NFSD_V3
 	bool "Provide NFSv3 server support"
 	depends on NFSD
@@ -1433,10 +1433,23 @@ config NFSD_V3
 	  If you would like to include the NFSv3 server as well as the NFSv2
 	  server, say Y here.  If unsure, say Y.
 
+config NFSD_V3_ACL
+	bool "Provide server support for the NFSv3 ACL protocol extension"
+	depends on NFSD_V3
+	select NFSD_V2_ACL
+	help
+	  Implement the NFSv3 ACL protocol extension for manipulating POSIX
+	  Access Control Lists on exported file systems. NFS clients should
+	  be compiled with the NFSv3 ACL protocol extension; see the
+	  CONFIG_NFS_V3_ACL option.  If unsure, say N.
+
 config NFSD_V4
 	bool "Provide NFSv4 server support (EXPERIMENTAL)"
 	depends on NFSD_V3 && EXPERIMENTAL
 	select NFSD_TCP
+	select CRYPTO_MD5
+	select CRYPTO
+	select FS_POSIX_ACL
 	help
 	  If you would like to include the NFSv4 server as well as the NFSv2
 	  and NFSv3 servers, say Y here.  This feature is experimental, and
@@ -1477,6 +1490,15 @@ config LOCKD_V4
 config EXPORTFS
 	tristate
 
+config NFS_ACL_SUPPORT
+	tristate
+	select FS_POSIX_ACL
+
+config NFS_COMMON
+	bool
+	depends on NFSD || NFS_FS
+	default y
+
 config SUNRPC
 	tristate
 
diff --git a/fs/Makefile b/fs/Makefile
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -10,7 +10,9 @@ obj-y :=	open.o read_write.o file_table.
 		ioctl.o readdir.o select.o fifo.o locks.o dcache.o inode.o \
 		attr.o bad_inode.o file.o filesystems.o namespace.o aio.o \
 		seq_file.o xattr.o libfs.o fs-writeback.o mpage.o direct-io.o \
+		ioprio.o
 
+obj-$(CONFIG_INOTIFY)		+= inotify.o
 obj-$(CONFIG_EPOLL)		+= eventpoll.o
 obj-$(CONFIG_COMPAT)		+= compat.o
 
@@ -31,6 +33,7 @@ obj-$(CONFIG_BINFMT_FLAT)	+= binfmt_flat
 
 obj-$(CONFIG_FS_MBCACHE)	+= mbcache.o
 obj-$(CONFIG_FS_POSIX_ACL)	+= posix_acl.o xattr_acl.o
+obj-$(CONFIG_NFS_COMMON)	+= nfs_common/
 
 obj-$(CONFIG_QUOTA)		+= dquot.o
 obj-$(CONFIG_QFMT_V1)		+= quota_v1.o
diff --git a/fs/afs/kafsasyncd.c b/fs/afs/kafsasyncd.c
--- a/fs/afs/kafsasyncd.c
+++ b/fs/afs/kafsasyncd.c
@@ -116,7 +116,7 @@ static int kafsasyncd(void *arg)
 		remove_wait_queue(&kafsasyncd_sleepq, &myself);
 		set_current_state(TASK_RUNNING);
 
-		try_to_freeze(PF_FREEZE);
+		try_to_freeze();
 
 		/* discard pending signals */
 		afs_discard_my_signals();
diff --git a/fs/afs/kafstimod.c b/fs/afs/kafstimod.c
--- a/fs/afs/kafstimod.c
+++ b/fs/afs/kafstimod.c
@@ -91,7 +91,7 @@ static int kafstimod(void *arg)
 			complete_and_exit(&kafstimod_dead, 0);
 		}
 
-		try_to_freeze(PF_FREEZE);
+		try_to_freeze();
 
 		/* discard pending signals */
 		afs_discard_my_signals();
diff --git a/fs/afs/mntpt.c b/fs/afs/mntpt.c
--- a/fs/afs/mntpt.c
+++ b/fs/afs/mntpt.c
@@ -30,7 +30,7 @@ static struct dentry *afs_mntpt_lookup(s
 				       struct dentry *dentry,
 				       struct nameidata *nd);
 static int afs_mntpt_open(struct inode *inode, struct file *file);
-static int afs_mntpt_follow_link(struct dentry *dentry, struct nameidata *nd);
+static void *afs_mntpt_follow_link(struct dentry *dentry, struct nameidata *nd);
 
 struct file_operations afs_mntpt_file_operations = {
 	.open		= afs_mntpt_open,
@@ -233,7 +233,7 @@ static struct vfsmount *afs_mntpt_do_aut
 /*
  * follow a link from a mountpoint directory, thus causing it to be mounted
  */
-static int afs_mntpt_follow_link(struct dentry *dentry, struct nameidata *nd)
+static void *afs_mntpt_follow_link(struct dentry *dentry, struct nameidata *nd)
 {
 	struct vfsmount *newmnt;
 	struct dentry *old_dentry;
@@ -249,7 +249,7 @@ static int afs_mntpt_follow_link(struct 
 	newmnt = afs_mntpt_do_automount(dentry);
 	if (IS_ERR(newmnt)) {
 		path_release(nd);
-		return PTR_ERR(newmnt);
+		return (void *)newmnt;
 	}
 
 	old_dentry = nd->dentry;
@@ -267,7 +267,7 @@ static int afs_mntpt_follow_link(struct 
 	}
 
 	kleave(" = %d", err);
-	return err;
+	return ERR_PTR(err);
 } /* end afs_mntpt_follow_link() */
 
 /*****************************************************************************/
diff --git a/fs/aio.c b/fs/aio.c
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -58,6 +58,7 @@ static DEFINE_SPINLOCK(fput_lock);
 static LIST_HEAD(fput_head);
 
 static void aio_kick_handler(void *);
+static void aio_queue_work(struct kioctx *);
 
 /* aio_setup
  *	Creates the slab caches used by the aio routines, panic on
@@ -747,6 +748,14 @@ out:
 		 * has already been kicked */
 		if (kiocbIsKicked(iocb)) {
 			__queue_kicked_iocb(iocb);
+
+			/*
+			 * __queue_kicked_iocb will always return 1 here, because
+			 * iocb->ki_run_list is empty at this point so it should
+			 * be safe to unconditionally queue the context into the
+			 * work queue.
+			 */
+			aio_queue_work(ctx);
 		}
 	}
 	return ret;
diff --git a/fs/attr.c b/fs/attr.c
--- a/fs/attr.c
+++ b/fs/attr.c
@@ -10,7 +10,7 @@
 #include <linux/mm.h>
 #include <linux/string.h>
 #include <linux/smp_lock.h>
-#include <linux/dnotify.h>
+#include <linux/fsnotify.h>
 #include <linux/fcntl.h>
 #include <linux/quotaops.h>
 #include <linux/security.h>
@@ -107,31 +107,8 @@ int inode_setattr(struct inode * inode, 
 out:
 	return error;
 }
-
 EXPORT_SYMBOL(inode_setattr);
 
-int setattr_mask(unsigned int ia_valid)
-{
-	unsigned long dn_mask = 0;
-
-	if (ia_valid & ATTR_UID)
-		dn_mask |= DN_ATTRIB;
-	if (ia_valid & ATTR_GID)
-		dn_mask |= DN_ATTRIB;
-	if (ia_valid & ATTR_SIZE)
-		dn_mask |= DN_MODIFY;
-	/* both times implies a utime(s) call */
-	if ((ia_valid & (ATTR_ATIME|ATTR_MTIME)) == (ATTR_ATIME|ATTR_MTIME))
-		dn_mask |= DN_ATTRIB;
-	else if (ia_valid & ATTR_ATIME)
-		dn_mask |= DN_ACCESS;
-	else if (ia_valid & ATTR_MTIME)
-		dn_mask |= DN_MODIFY;
-	if (ia_valid & ATTR_MODE)
-		dn_mask |= DN_ATTRIB;
-	return dn_mask;
-}
-
 int notify_change(struct dentry * dentry, struct iattr * attr)
 {
 	struct inode *inode = dentry->d_inode;
@@ -197,11 +174,9 @@ int notify_change(struct dentry * dentry
 	if (ia_valid & ATTR_SIZE)
 		up_write(&dentry->d_inode->i_alloc_sem);
 
-	if (!error) {
-		unsigned long dn_mask = setattr_mask(ia_valid);
-		if (dn_mask)
-			dnotify_parent(dentry, dn_mask);
-	}
+	if (!error)
+		fsnotify_change(dentry, ia_valid);
+
 	return error;
 }
 
diff --git a/fs/autofs/symlink.c b/fs/autofs/symlink.c
--- a/fs/autofs/symlink.c
+++ b/fs/autofs/symlink.c
@@ -12,11 +12,12 @@
 
 #include "autofs_i.h"
 
-static int autofs_follow_link(struct dentry *dentry, struct nameidata *nd)
+/* Nothing to release.. */
+static void *autofs_follow_link(struct dentry *dentry, struct nameidata *nd)
 {
 	char *s=((struct autofs_symlink *)dentry->d_inode->u.generic_ip)->data;
 	nd_set_link(nd, s);
-	return 0;
+	return NULL;
 }
 
 struct inode_operations autofs_symlink_inode_operations = {
diff --git a/fs/autofs4/autofs_i.h b/fs/autofs4/autofs_i.h
--- a/fs/autofs4/autofs_i.h
+++ b/fs/autofs4/autofs_i.h
@@ -92,6 +92,7 @@ struct autofs_wait_queue {
 
 struct autofs_sb_info {
 	u32 magic;
+	struct dentry *root;
 	struct file *pipe;
 	pid_t oz_pgrp;
 	int catatonic;
@@ -185,6 +186,19 @@ int autofs4_wait(struct autofs_sb_info *
 int autofs4_wait_release(struct autofs_sb_info *,autofs_wqt_t,int);
 void autofs4_catatonic_mode(struct autofs_sb_info *);
 
+static inline int autofs4_follow_mount(struct vfsmount **mnt, struct dentry **dentry)
+{
+	int res = 0;
+
+	while (d_mountpoint(*dentry)) {
+		int followed = follow_down(mnt, dentry);
+		if (!followed)
+			break;
+		res = 1;
+	}
+	return res;
+}
+
 static inline int simple_positive(struct dentry *dentry)
 {
 	return dentry->d_inode && !d_unhashed(dentry);
diff --git a/fs/autofs4/expire.c b/fs/autofs4/expire.c
--- a/fs/autofs4/expire.c
+++ b/fs/autofs4/expire.c
@@ -56,12 +56,9 @@ static int autofs4_check_mount(struct vf
 	mntget(mnt);
 	dget(dentry);
 
-	if (!follow_down(&mnt, &dentry))
+	if (!autofs4_follow_mount(&mnt, &dentry))
 		goto done;
 
-	while (d_mountpoint(dentry) && follow_down(&mnt, &dentry))
-		;
-
 	/* This is an autofs submount, we can't expire it */
 	if (is_autofs4_dentry(dentry))
 		goto done;
diff --git a/fs/autofs4/inode.c b/fs/autofs4/inode.c
--- a/fs/autofs4/inode.c
+++ b/fs/autofs4/inode.c
@@ -16,6 +16,7 @@
 #include <linux/pagemap.h>
 #include <linux/parser.h>
 #include <linux/bitops.h>
+#include <linux/smp_lock.h>
 #include "autofs_i.h"
 #include <linux/module.h>
 
@@ -76,6 +77,66 @@ void autofs4_free_ino(struct autofs_info
 	kfree(ino);
 }
 
+/*
+ * Deal with the infamous "Busy inodes after umount ..." message.
+ *
+ * Clean up the dentry tree. This happens with autofs if the user
+ * space program goes away due to a SIGKILL, SIGSEGV etc.
+ */
+static void autofs4_force_release(struct autofs_sb_info *sbi)
+{
+	struct dentry *this_parent = sbi->root;
+	struct list_head *next;
+
+	spin_lock(&dcache_lock);
+repeat:
+	next = this_parent->d_subdirs.next;
+resume:
+	while (next != &this_parent->d_subdirs) {
+		struct dentry *dentry = list_entry(next, struct dentry, d_child);
+
+		/* Negative dentry - don`t care */
+		if (!simple_positive(dentry)) {
+			next = next->next;
+			continue;
+		}
+
+		if (!list_empty(&dentry->d_subdirs)) {
+			this_parent = dentry;
+			goto repeat;
+		}
+
+		next = next->next;
+		spin_unlock(&dcache_lock);
+
+		DPRINTK("dentry %p %.*s",
+			dentry, (int)dentry->d_name.len, dentry->d_name.name);
+
+		dput(dentry);
+		spin_lock(&dcache_lock);
+	}
+
+	if (this_parent != sbi->root) {
+		struct dentry *dentry = this_parent;
+
+		next = this_parent->d_child.next;
+		this_parent = this_parent->d_parent;
+		spin_unlock(&dcache_lock);
+		DPRINTK("parent dentry %p %.*s",
+			dentry, (int)dentry->d_name.len, dentry->d_name.name);
+		dput(dentry);
+		spin_lock(&dcache_lock);
+		goto resume;
+	}
+	spin_unlock(&dcache_lock);
+
+	dput(sbi->root);
+	sbi->root = NULL;
+	shrink_dcache_sb(sbi->sb);
+
+	return;
+}
+
 static void autofs4_put_super(struct super_block *sb)
 {
 	struct autofs_sb_info *sbi = autofs4_sbi(sb);
@@ -85,6 +146,10 @@ static void autofs4_put_super(struct sup
 	if ( !sbi->catatonic )
 		autofs4_catatonic_mode(sbi); /* Free wait queues, close pipe */
 
+	/* Clean up and release dangling references */
+	if (sbi)
+		autofs4_force_release(sbi);
+
 	kfree(sbi);
 
 	DPRINTK("shutting down");
@@ -199,6 +264,7 @@ int autofs4_fill_super(struct super_bloc
 
 	s->s_fs_info = sbi;
 	sbi->magic = AUTOFS_SBI_MAGIC;
+	sbi->root = NULL;
 	sbi->catatonic = 0;
 	sbi->exp_timeout = 0;
 	sbi->oz_pgrp = process_group(current);
@@ -267,6 +333,13 @@ int autofs4_fill_super(struct super_bloc
 	sbi->pipe = pipe;
 
 	/*
+	 * Take a reference to the root dentry so we get a chance to
+	 * clean up the dentry tree on umount.
+	 * See autofs4_force_release.
+	 */
+	sbi->root = dget(root);
+
+	/*
 	 * Success! Install the root dentry now to indicate completion.
 	 */
 	s->s_root = root;
diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c
--- a/fs/autofs4/root.c
+++ b/fs/autofs4/root.c
@@ -205,7 +205,11 @@ static int autofs4_dir_open(struct inode
 		struct vfsmount *fp_mnt = mntget(mnt);
 		struct dentry *fp_dentry = dget(dentry);
 
-		while (follow_down(&fp_mnt, &fp_dentry) && d_mountpoint(fp_dentry));
+		if (!autofs4_follow_mount(&fp_mnt, &fp_dentry)) {
+			dput(fp_dentry);
+			mntput(fp_mnt);
+			return -ENOENT;
+		}
 
 		fp = dentry_open(fp_dentry, fp_mnt, file->f_flags);
 		status = PTR_ERR(fp);
@@ -302,7 +306,14 @@ static int try_to_fill_dentry(struct den
 		
 		DPRINTK("expire done status=%d", status);
 		
-		return 0;
+		/*
+		 * If the directory still exists the mount request must
+		 * continue otherwise it can't be followed at the right
+		 * time during the walk.
+		 */
+		status = d_invalidate(dentry);
+		if (status != -EBUSY)
+			return 0;
 	}
 
 	DPRINTK("dentry=%p %.*s ino=%p",
diff --git a/fs/autofs4/symlink.c b/fs/autofs4/symlink.c
--- a/fs/autofs4/symlink.c
+++ b/fs/autofs4/symlink.c
@@ -12,11 +12,11 @@
 
 #include "autofs_i.h"
 
-static int autofs4_follow_link(struct dentry *dentry, struct nameidata *nd)
+static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd)
 {
 	struct autofs_info *ino = autofs4_dentry_ino(dentry);
 	nd_set_link(nd, (char *)ino->u.symlink);
-	return 0;
+	return NULL;
 }
 
 struct inode_operations autofs4_symlink_inode_operations = {
diff --git a/fs/autofs4/waitq.c b/fs/autofs4/waitq.c
--- a/fs/autofs4/waitq.c
+++ b/fs/autofs4/waitq.c
@@ -191,6 +191,13 @@ int autofs4_wait(struct autofs_sb_info *
 	}
 
 	if ( !wq ) {
+		/* Can't wait for an expire if there's no mount */
+		if (notify == NFY_NONE && !d_mountpoint(dentry)) {
+			kfree(name);
+			up(&sbi->wq_sem);
+			return -ENOENT;
+		}
+
 		/* Create a new wait queue */
 		wq = kmalloc(sizeof(struct autofs_wait_queue),GFP_KERNEL);
 		if ( !wq ) {
@@ -224,8 +231,8 @@ int autofs4_wait(struct autofs_sb_info *
 		int type = (notify == NFY_MOUNT ?
 			autofs_ptype_missing : autofs_ptype_expire_multi);
 
-		DPRINTK(("new wait id = 0x%08lx, name = %.*s, nfy=%d\n",
-			(unsigned long) wq->wait_queue_token, wq->len, wq->name, notify));
+		DPRINTK("new wait id = 0x%08lx, name = %.*s, nfy=%d\n",
+			(unsigned long) wq->wait_queue_token, wq->len, wq->name, notify);
 
 		/* autofs4_notify_daemon() may block */
 		autofs4_notify_daemon(sbi, wq, type);
diff --git a/fs/befs/linuxvfs.c b/fs/befs/linuxvfs.c
--- a/fs/befs/linuxvfs.c
+++ b/fs/befs/linuxvfs.c
@@ -41,8 +41,8 @@ static struct inode *befs_alloc_inode(st
 static void befs_destroy_inode(struct inode *inode);
 static int befs_init_inodecache(void);
 static void befs_destroy_inodecache(void);
-static int befs_follow_link(struct dentry *, struct nameidata *);
-static void befs_put_link(struct dentry *, struct nameidata *);
+static void *befs_follow_link(struct dentry *, struct nameidata *);
+static void befs_put_link(struct dentry *, struct nameidata *, void *);
 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,
@@ -461,7 +461,7 @@ befs_destroy_inodecache(void)
  * The data stream become link name. Unless the LONG_SYMLINK
  * flag is set.
  */
-static int
+static void *
 befs_follow_link(struct dentry *dentry, struct nameidata *nd)
 {
 	befs_inode_info *befs_ino = BEFS_I(dentry->d_inode);
@@ -487,10 +487,10 @@ befs_follow_link(struct dentry *dentry, 
 	}
 
 	nd_set_link(nd, link);
-	return 0;
+	return NULL;
 }
 
-static void befs_put_link(struct dentry *dentry, struct nameidata *nd)
+static void befs_put_link(struct dentry *dentry, struct nameidata *nd, void *p)
 {
 	befs_inode_info *befs_ino = BEFS_I(dentry->d_inode);
 	if (befs_ino->i_flags & BEFS_LONG_SYMLINK) {
diff --git a/fs/binfmt_aout.c b/fs/binfmt_aout.c
--- a/fs/binfmt_aout.c
+++ b/fs/binfmt_aout.c
@@ -316,6 +316,7 @@ static int load_aout_binary(struct linux
 	current->mm->brk = ex.a_bss +
 		(current->mm->start_brk = N_BSSADDR(ex));
 	current->mm->free_area_cache = current->mm->mmap_base;
+	current->mm->cached_hole_size = 0;
 
 	set_mm_counter(current->mm, rss, 0);
 	current->mm->mmap = NULL;
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -775,6 +775,7 @@ static int load_elf_binary(struct linux_
 	   change some of these later */
 	set_mm_counter(current->mm, rss, 0);
 	current->mm->free_area_cache = current->mm->mmap_base;
+	current->mm->cached_hole_size = 0;
 	retval = setup_arg_pages(bprm, randomize_stack_top(STACK_TOP),
 				 executable_stack);
 	if (retval < 0) {
diff --git a/fs/bio.c b/fs/bio.c
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -52,7 +52,7 @@ struct biovec_slab {
  */
 
 #define BV(x) { .nr_vecs = x, .name = "biovec-"__stringify(x) }
-static struct biovec_slab bvec_slabs[BIOVEC_NR_POOLS] = {
+static struct biovec_slab bvec_slabs[BIOVEC_NR_POOLS] __read_mostly = {
 	BV(1), BV(4), BV(16), BV(64), BV(128), BV(BIO_MAX_PAGES),
 };
 #undef BV
@@ -248,19 +248,16 @@ inline void __bio_clone(struct bio *bio,
 {
 	request_queue_t *q = bdev_get_queue(bio_src->bi_bdev);
 
-	memcpy(bio->bi_io_vec, bio_src->bi_io_vec, bio_src->bi_max_vecs * sizeof(struct bio_vec));
+	memcpy(bio->bi_io_vec, bio_src->bi_io_vec,
+		bio_src->bi_max_vecs * sizeof(struct bio_vec));
 
 	bio->bi_sector = bio_src->bi_sector;
 	bio->bi_bdev = bio_src->bi_bdev;
 	bio->bi_flags |= 1 << BIO_CLONED;
 	bio->bi_rw = bio_src->bi_rw;
-
-	/*
-	 * notes -- maybe just leave bi_idx alone. assume identical mapping
-	 * for the clone
-	 */
 	bio->bi_vcnt = bio_src->bi_vcnt;
 	bio->bi_size = bio_src->bi_size;
+	bio->bi_idx = bio_src->bi_idx;
 	bio_phys_segments(q, bio);
 	bio_hw_segments(q, bio);
 }
diff --git a/fs/block_dev.c b/fs/block_dev.c
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -777,8 +777,7 @@ static ssize_t blkdev_file_aio_write(str
 	return generic_file_aio_write_nolock(iocb, &local_iov, 1, &iocb->ki_pos);
 }
 
-static int block_ioctl(struct inode *inode, struct file *file, unsigned cmd,
-			unsigned long arg)
+static long block_ioctl(struct file *file, unsigned cmd, unsigned long arg)
 {
 	return blkdev_ioctl(file->f_mapping->host, file, cmd, arg);
 }
@@ -803,7 +802,7 @@ struct file_operations def_blk_fops = {
   	.aio_write	= blkdev_file_aio_write, 
 	.mmap		= generic_file_mmap,
 	.fsync		= block_fsync,
-	.ioctl		= block_ioctl,
+	.unlocked_ioctl	= block_ioctl,
 #ifdef CONFIG_COMPAT
 	.compat_ioctl	= compat_blkdev_ioctl,
 #endif
diff --git a/fs/buffer.c b/fs/buffer.c
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -278,7 +278,7 @@ EXPORT_SYMBOL(thaw_bdev);
  */
 static void do_sync(unsigned long wait)
 {
-	wakeup_bdflush(0);
+	wakeup_pdflush(0);
 	sync_inodes(0);		/* All mappings, inodes and their blockdevs */
 	DQUOT_SYNC(NULL);
 	sync_supers();		/* Write the superblocks */
@@ -331,7 +331,7 @@ int file_fsync(struct file *filp, struct
 	return ret;
 }
 
-asmlinkage long sys_fsync(unsigned int fd)
+static long do_fsync(unsigned int fd, int datasync)
 {
 	struct file * file;
 	struct address_space *mapping;
@@ -342,14 +342,14 @@ asmlinkage long sys_fsync(unsigned int f
 	if (!file)
 		goto out;
 
-	mapping = file->f_mapping;
-
 	ret = -EINVAL;
 	if (!file->f_op || !file->f_op->fsync) {
 		/* Why?  We can still call filemap_fdatawrite */
 		goto out_putf;
 	}
 
+	mapping = file->f_mapping;
+
 	current->flags |= PF_SYNCWRITE;
 	ret = filemap_fdatawrite(mapping);
 
@@ -358,7 +358,7 @@ asmlinkage long sys_fsync(unsigned int f
 	 * which could cause livelocks in fsync_buffers_list
 	 */
 	down(&mapping->host->i_sem);
-	err = file->f_op->fsync(file, file->f_dentry, 0);
+	err = file->f_op->fsync(file, file->f_dentry, datasync);
 	if (!ret)
 		ret = err;
 	up(&mapping->host->i_sem);
@@ -373,39 +373,14 @@ out:
 	return ret;
 }
 
-asmlinkage long sys_fdatasync(unsigned int fd)
+asmlinkage long sys_fsync(unsigned int fd)
 {
-	struct file * file;
-	struct address_space *mapping;
-	int ret, err;
-
-	ret = -EBADF;
-	file = fget(fd);
-	if (!file)
-		goto out;
-
-	ret = -EINVAL;
-	if (!file->f_op || !file->f_op->fsync)
-		goto out_putf;
-
-	mapping = file->f_mapping;
-
-	current->flags |= PF_SYNCWRITE;
-	ret = filemap_fdatawrite(mapping);
-	down(&mapping->host->i_sem);
-	err = file->f_op->fsync(file, file->f_dentry, 1);
-	if (!ret)
-		ret = err;
-	up(&mapping->host->i_sem);
-	err = filemap_fdatawait(mapping);
-	if (!ret)
-		ret = err;
-	current->flags &= ~PF_SYNCWRITE;
+	return do_fsync(fd, 0);
+}
 
-out_putf:
-	fput(file);
-out:
-	return ret;
+asmlinkage long sys_fdatasync(unsigned int fd)
+{
+	return do_fsync(fd, 1);
 }
 
 /*
@@ -522,13 +497,13 @@ static void free_more_memory(void)
 	struct zone **zones;
 	pg_data_t *pgdat;
 
-	wakeup_bdflush(1024);
+	wakeup_pdflush(1024);
 	yield();
 
 	for_each_pgdat(pgdat) {
 		zones = pgdat->node_zonelists[GFP_NOFS&GFP_ZONEMASK].zones;
 		if (*zones)
-			try_to_free_pages(zones, GFP_NOFS, 0);
+			try_to_free_pages(zones, GFP_NOFS);
 	}
 }
 
@@ -538,8 +513,8 @@ static void free_more_memory(void)
  */
 static void end_buffer_async_read(struct buffer_head *bh, int uptodate)
 {
-	static DEFINE_SPINLOCK(page_uptodate_lock);
 	unsigned long flags;
+	struct buffer_head *first;
 	struct buffer_head *tmp;
 	struct page *page;
 	int page_uptodate = 1;
@@ -561,7 +536,9 @@ static void end_buffer_async_read(struct
 	 * two buffer heads end IO at almost the same time and both
 	 * decide that the page is now completely done.
 	 */
-	spin_lock_irqsave(&page_uptodate_lock, flags);
+	first = page_buffers(page);
+	local_irq_save(flags);
+	bit_spin_lock(BH_Uptodate_Lock, &first->b_state);
 	clear_buffer_async_read(bh);
 	unlock_buffer(bh);
 	tmp = bh;
@@ -574,7 +551,8 @@ static void end_buffer_async_read(struct
 		}
 		tmp = tmp->b_this_page;
 	} while (tmp != bh);
-	spin_unlock_irqrestore(&page_uptodate_lock, flags);
+	bit_spin_unlock(BH_Uptodate_Lock, &first->b_state);
+	local_irq_restore(flags);
 
 	/*
 	 * If none of the buffers had errors and they are all
@@ -586,7 +564,8 @@ static void end_buffer_async_read(struct
 	return;
 
 still_busy:
-	spin_unlock_irqrestore(&page_uptodate_lock, flags);
+	bit_spin_unlock(BH_Uptodate_Lock, &first->b_state);
+	local_irq_restore(flags);
 	return;
 }
 
@@ -597,8 +576,8 @@ still_busy:
 void end_buffer_async_write(struct buffer_head *bh, int uptodate)
 {
 	char b[BDEVNAME_SIZE];
-	static DEFINE_SPINLOCK(page_uptodate_lock);
 	unsigned long flags;
+	struct buffer_head *first;
 	struct buffer_head *tmp;
 	struct page *page;
 
@@ -619,7 +598,10 @@ void end_buffer_async_write(struct buffe
 		SetPageError(page);
 	}
 
-	spin_lock_irqsave(&page_uptodate_lock, flags);
+	first = page_buffers(page);
+	local_irq_save(flags);
+	bit_spin_lock(BH_Uptodate_Lock, &first->b_state);
+
 	clear_buffer_async_write(bh);
 	unlock_buffer(bh);
 	tmp = bh->b_this_page;
@@ -630,12 +612,14 @@ void end_buffer_async_write(struct buffe
 		}
 		tmp = tmp->b_this_page;
 	}
-	spin_unlock_irqrestore(&page_uptodate_lock, flags);
+	bit_spin_unlock(BH_Uptodate_Lock, &first->b_state);
+	local_irq_restore(flags);
 	end_page_writeback(page);
 	return;
 
 still_busy:
-	spin_unlock_irqrestore(&page_uptodate_lock, flags);
+	bit_spin_unlock(BH_Uptodate_Lock, &first->b_state);
+	local_irq_restore(flags);
 	return;
 }
 
@@ -1951,7 +1935,6 @@ static int __block_prepare_write(struct 
 			if (err)
 				break;
 			if (buffer_new(bh)) {
-				clear_buffer_new(bh);
 				unmap_underlying_metadata(bh->b_bdev,
 							bh->b_blocknr);
 				if (PageUptodate(page)) {
@@ -1993,9 +1976,14 @@ static int __block_prepare_write(struct 
 		if (!buffer_uptodate(*wait_bh))
 			err = -EIO;
 	}
-	if (!err)
-		return err;
-
+	if (!err) {
+		bh = head;
+		do {
+			if (buffer_new(bh))
+				clear_buffer_new(bh);
+		} while ((bh = bh->b_this_page) != head);
+		return 0;
+	}
 	/* Error case: */
 	/*
 	 * Zero out any newly allocated blocks to avoid exposing stale
diff --git a/fs/char_dev.c b/fs/char_dev.c
--- a/fs/char_dev.c
+++ b/fs/char_dev.c
@@ -56,10 +56,21 @@ int get_chrdev_list(char *page)
 
 	down(&chrdevs_lock);
 	for (i = 0; i < ARRAY_SIZE(chrdevs) ; i++) {
-		for (cd = chrdevs[i]; cd; cd = cd->next)
+		for (cd = chrdevs[i]; cd; cd = cd->next) {
+			/*
+			 * if the current name, plus the 5 extra characters
+			 * in the device line for this entry
+			 * would run us off the page, we're done
+			 */
+			if ((len+strlen(cd->name) + 5) >= PAGE_SIZE)
+				goto page_full;
+
+
 			len += sprintf(page+len, "%3d %s\n",
 				       cd->major, cd->name);
+		}
 	}
+page_full:
 	up(&chrdevs_lock);
 
 	return len;
@@ -139,7 +150,7 @@ __unregister_chrdev_region(unsigned majo
 	struct char_device_struct *cd = NULL, **cp;
 	int i = major_to_index(major);
 
-	up(&chrdevs_lock);
+	down(&chrdevs_lock);
 	for (cp = &chrdevs[i]; *cp; cp = &(*cp)->next)
 		if ((*cp)->major == major &&
 		    (*cp)->baseminor == baseminor &&
@@ -266,8 +277,9 @@ static struct kobject *cdev_get(struct c
 void cdev_put(struct cdev *p)
 {
 	if (p) {
+		struct module *owner = p->owner;
 		kobject_put(&p->kobj);
-		module_put(p->owner);
+		module_put(owner);
 	}
 }
 
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES
--- a/fs/cifs/CHANGES
+++ b/fs/cifs/CHANGES
@@ -1,3 +1,9 @@
+Version 1.35
+------------
+Add writepage performance improvements.  Fix path name conversions
+for long filenames on mounts which were done with "mapchars" mount option
+specified.
+
 Version 1.34
 ------------
 Fix error mapping of the TOO_MANY_LINKS (hardlinks) case.
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h
--- a/fs/cifs/cifsfs.h
+++ b/fs/cifs/cifsfs.h
@@ -83,8 +83,8 @@ extern int cifs_dir_notify(struct file *
 extern struct dentry_operations cifs_dentry_ops;
 
 /* Functions related to symlinks */
-extern int cifs_follow_link(struct dentry *direntry, struct nameidata *nd);
-extern void cifs_put_link(struct dentry *direntry, struct nameidata *nd);
+extern void *cifs_follow_link(struct dentry *direntry, struct nameidata *nd);
+extern void cifs_put_link(struct dentry *direntry, struct nameidata *nd, void *);
 extern int cifs_readlink(struct dentry *direntry, char __user *buffer, 
 			 int buflen);
 extern int cifs_symlink(struct inode *inode, struct dentry *direntry,
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -2602,6 +2602,9 @@ int CIFSFindNext(const int xid, struct c
 	if(name_len < PATH_MAX) {
 		memcpy(pSMB->ResumeFileName, psrch_inf->presume_name, name_len);
 		byte_count += name_len;
+		/* 14 byte parm len above enough for 2 byte null terminator */
+		pSMB->ResumeFileName[name_len] = 0;
+		pSMB->ResumeFileName[name_len+1] = 0;
 	} else {
 		rc = -EINVAL;
 		goto FNext2_err_exit;
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -643,7 +643,7 @@ int cifs_lock(struct file *file, int cmd
 			 netfid, length,
 			 pfLock->fl_start, numUnlock, numLock, lockType,
 			 wait_flag);
-	if (rc == 0 && (pfLock->fl_flags & FL_POSIX))
+	if (pfLock->fl_flags & FL_POSIX)
 		posix_lock_file_wait(file, pfLock);
 	FreeXid(xid);
 	return rc;
diff --git a/fs/cifs/link.c b/fs/cifs/link.c
--- a/fs/cifs/link.c
+++ b/fs/cifs/link.c
@@ -92,7 +92,7 @@ cifs_hl_exit:
 	return rc;
 }
 
-int
+void *
 cifs_follow_link(struct dentry *direntry, struct nameidata *nd)
 {
 	struct inode *inode = direntry->d_inode;
@@ -148,7 +148,7 @@ out:
 out_no_free:
 	FreeXid(xid);
 	nd_set_link(nd, target_path);
-	return 0;
+	return NULL;	/* No cookie */
 }
 
 int
@@ -330,7 +330,7 @@ cifs_readlink(struct dentry *direntry, c
 	return rc;
 }
 
-void cifs_put_link(struct dentry *direntry, struct nameidata *nd)
+void cifs_put_link(struct dentry *direntry, struct nameidata *nd, void *cookie)
 {
 	char *p = nd_get_link(nd);
 	if (!IS_ERR(p))
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
--- a/fs/cifs/misc.c
+++ b/fs/cifs/misc.c
@@ -611,6 +611,7 @@ cifsConvertToUCS(__le16 * target, const 
 		src_char = source[i];
 		switch (src_char) {
 			case 0:
+				target[j] = 0;
 				goto ctoUCS_out;
 			case ':':
 				target[j] = cpu_to_le16(UNI_COLON);
diff --git a/fs/coda/psdev.c b/fs/coda/psdev.c
--- a/fs/coda/psdev.c
+++ b/fs/coda/psdev.c
@@ -61,7 +61,7 @@ unsigned long coda_timeout = 30; /* .. s
 
 
 struct venus_comm coda_comms[MAX_CODADEVS];
-static struct class_simple *coda_psdev_class;
+static struct class *coda_psdev_class;
 
 /*
  * Device operations
@@ -363,14 +363,14 @@ static int init_coda_psdev(void)
 		     CODA_PSDEV_MAJOR);
               return -EIO;
 	}
-	coda_psdev_class = class_simple_create(THIS_MODULE, "coda");
+	coda_psdev_class = class_create(THIS_MODULE, "coda");
 	if (IS_ERR(coda_psdev_class)) {
 		err = PTR_ERR(coda_psdev_class);
 		goto out_chrdev;
 	}		
 	devfs_mk_dir ("coda");
 	for (i = 0; i < MAX_CODADEVS; i++) {
-		class_simple_device_add(coda_psdev_class, MKDEV(CODA_PSDEV_MAJOR,i), 
+		class_device_create(coda_psdev_class, MKDEV(CODA_PSDEV_MAJOR,i),
 				NULL, "cfs%d", i);
 		err = devfs_mk_cdev(MKDEV(CODA_PSDEV_MAJOR, i),
 				S_IFCHR|S_IRUSR|S_IWUSR, "coda/%d", i);
@@ -382,8 +382,8 @@ static int init_coda_psdev(void)
 
 out_class:
 	for (i = 0; i < MAX_CODADEVS; i++) 
-		class_simple_device_remove(MKDEV(CODA_PSDEV_MAJOR, i));
-	class_simple_destroy(coda_psdev_class);
+		class_device_destroy(coda_psdev_class, MKDEV(CODA_PSDEV_MAJOR, i));
+	class_destroy(coda_psdev_class);
 out_chrdev:
 	unregister_chrdev(CODA_PSDEV_MAJOR, "coda");
 out:
@@ -425,10 +425,10 @@ static int __init init_coda(void)
 	return 0;
 out:
 	for (i = 0; i < MAX_CODADEVS; i++) {
-		class_simple_device_remove(MKDEV(CODA_PSDEV_MAJOR, i));
+		class_device_destroy(coda_psdev_class, MKDEV(CODA_PSDEV_MAJOR, i));
 		devfs_remove("coda/%d", i);
 	}
-	class_simple_destroy(coda_psdev_class);
+	class_destroy(coda_psdev_class);
 	devfs_remove("coda");
 	unregister_chrdev(CODA_PSDEV_MAJOR, "coda");
 	coda_sysctl_clean();
@@ -447,10 +447,10 @@ static void __exit exit_coda(void)
                 printk("coda: failed to unregister filesystem\n");
         }
 	for (i = 0; i < MAX_CODADEVS; i++) {
-		class_simple_device_remove(MKDEV(CODA_PSDEV_MAJOR, i));
+		class_device_destroy(coda_psdev_class, MKDEV(CODA_PSDEV_MAJOR, i));
 		devfs_remove("coda/%d", i);
 	}
-	class_simple_destroy(coda_psdev_class);
+	class_destroy(coda_psdev_class);
 	devfs_remove("coda");
 	unregister_chrdev(CODA_PSDEV_MAJOR, "coda");
 	coda_sysctl_clean();
diff --git a/fs/compat.c b/fs/compat.c
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -37,7 +37,7 @@
 #include <linux/ctype.h>
 #include <linux/module.h>
 #include <linux/dirent.h>
-#include <linux/dnotify.h>
+#include <linux/fsnotify.h>
 #include <linux/highuid.h>
 #include <linux/sunrpc/svc.h>
 #include <linux/nfsd/nfsd.h>
@@ -1307,9 +1307,13 @@ static ssize_t compat_do_readv_writev(in
 out:
 	if (iov != iovstack)
 		kfree(iov);
-	if ((ret + (type == READ)) > 0)
-		dnotify_parent(file->f_dentry,
-				(type == READ) ? DN_ACCESS : DN_MODIFY);
+	if ((ret + (type == READ)) > 0) {
+		struct dentry *dentry = file->f_dentry;
+		if (type == READ)
+			fsnotify_access(dentry);
+		else
+			fsnotify_modify(dentry);
+	}
 	return ret;
 }
 
diff --git a/fs/dcache.c b/fs/dcache.c
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -19,6 +19,7 @@
 #include <linux/string.h>
 #include <linux/mm.h>
 #include <linux/fs.h>
+#include <linux/fsnotify.h>
 #include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/smp_lock.h>
@@ -101,6 +102,7 @@ static inline void dentry_iput(struct de
 		list_del_init(&dentry->d_alias);
 		spin_unlock(&dentry->d_lock);
 		spin_unlock(&dcache_lock);
+		fsnotify_inoderemove(inode);
 		if (dentry->d_op && dentry->d_op->d_iput)
 			dentry->d_op->d_iput(dentry, inode);
 		else
@@ -1165,13 +1167,16 @@ out:
  
 void d_delete(struct dentry * dentry)
 {
+	int isdir = 0;
 	/*
 	 * Are we the only user?
 	 */
 	spin_lock(&dcache_lock);
 	spin_lock(&dentry->d_lock);
+	isdir = S_ISDIR(dentry->d_inode->i_mode);
 	if (atomic_read(&dentry->d_count) == 1) {
 		dentry_iput(dentry);
+		fsnotify_nameremove(dentry, isdir);
 		return;
 	}
 
@@ -1180,6 +1185,8 @@ void d_delete(struct dentry * dentry)
 
 	spin_unlock(&dentry->d_lock);
 	spin_unlock(&dcache_lock);
+
+	fsnotify_nameremove(dentry, isdir);
 }
 
 static void __d_rehash(struct dentry * entry, struct hlist_head *list)
diff --git a/fs/dcookies.c b/fs/dcookies.c
--- a/fs/dcookies.c
+++ b/fs/dcookies.c
@@ -94,12 +94,10 @@ static struct dcookie_struct * alloc_dco
 	if (!dcs)
 		return NULL;
 
-	atomic_inc(&dentry->d_count);
-	atomic_inc(&vfsmnt->mnt_count);
 	dentry->d_cookie = dcs;
 
-	dcs->dentry = dentry;
-	dcs->vfsmnt = vfsmnt;
+	dcs->dentry = dget(dentry);
+	dcs->vfsmnt = mntget(vfsmnt);
 	hash_dcookie(dcs);
 
 	return dcs;
diff --git a/fs/debugfs/file.c b/fs/debugfs/file.c
--- a/fs/debugfs/file.c
+++ b/fs/debugfs/file.c
@@ -45,44 +45,15 @@ struct file_operations debugfs_file_oper
 	.open =		default_open,
 };
 
-#define simple_type(type, format, temptype, strtolfn)				\
-static ssize_t read_file_##type(struct file *file, char __user *user_buf,	\
-				size_t count, loff_t *ppos)			\
-{										\
-	char buf[32];								\
-	type *val = file->private_data;						\
-										\
-	snprintf(buf, sizeof(buf), format "\n", *val);				\
-	return simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf));\
-}										\
-static ssize_t write_file_##type(struct file *file, const char __user *user_buf,\
-				 size_t count, loff_t *ppos)			\
-{										\
-	char *endp;								\
-	char buf[32];								\
-	int buf_size;								\
-	type *val = file->private_data;						\
-	temptype tmp;								\
-										\
-	memset(buf, 0x00, sizeof(buf));						\
-	buf_size = min(count, (sizeof(buf)-1));					\
-	if (copy_from_user(buf, user_buf, buf_size))				\
-		return -EFAULT;							\
-										\
-	tmp = strtolfn(buf, &endp, 0);						\
-	if ((endp == buf) || ((type)tmp != tmp))				\
-		return -EINVAL;							\
-	*val = tmp;								\
-	return count;								\
-}										\
-static struct file_operations fops_##type = {					\
-	.read =		read_file_##type,					\
-	.write =	write_file_##type,					\
-	.open =		default_open,						\
-};
-simple_type(u8, "%c", unsigned long, simple_strtoul);
-simple_type(u16, "%hi", unsigned long, simple_strtoul);
-simple_type(u32, "%i", unsigned long, simple_strtoul);
+static void debugfs_u8_set(void *data, u64 val)
+{
+	*(u8 *)data = val;
+}
+static u64 debugfs_u8_get(void *data)
+{
+	return *(u8 *)data;
+}
+DEFINE_SIMPLE_ATTRIBUTE(fops_u8, debugfs_u8_get, debugfs_u8_set, "%llu\n");
 
 /**
  * debugfs_create_u8 - create a file in the debugfs filesystem that is used to read and write a unsigned 8 bit value.
@@ -116,6 +87,16 @@ struct dentry *debugfs_create_u8(const c
 }
 EXPORT_SYMBOL_GPL(debugfs_create_u8);
 
+static void debugfs_u16_set(void *data, u64 val)
+{
+	*(u16 *)data = val;
+}
+static u64 debugfs_u16_get(void *data)
+{
+	return *(u16 *)data;
+}
+DEFINE_SIMPLE_ATTRIBUTE(fops_u16, debugfs_u16_get, debugfs_u16_set, "%llu\n");
+
 /**
  * debugfs_create_u16 - create a file in the debugfs filesystem that is used to read and write a unsigned 8 bit value.
  *
@@ -148,6 +129,16 @@ struct dentry *debugfs_create_u16(const 
 }
 EXPORT_SYMBOL_GPL(debugfs_create_u16);
 
+static void debugfs_u32_set(void *data, u64 val)
+{
+	*(u32 *)data = val;
+}
+static u64 debugfs_u32_get(void *data)
+{
+	return *(u32 *)data;
+}
+DEFINE_SIMPLE_ATTRIBUTE(fops_u32, debugfs_u32_get, debugfs_u32_set, "%llu\n");
+
 /**
  * debugfs_create_u32 - create a file in the debugfs filesystem that is used to read and write a unsigned 8 bit value.
  *
diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c
--- a/fs/debugfs/inode.c
+++ b/fs/debugfs/inode.c
@@ -110,16 +110,6 @@ static int debug_fill_super(struct super
 	return simple_fill_super(sb, DEBUGFS_MAGIC, debug_files);
 }
 
-static struct dentry * get_dentry(struct dentry *parent, const char *name)
-{               
-	struct qstr qstr;
-
-	qstr.name = name;
-	qstr.len = strlen(name);
-	qstr.hash = full_name_hash(name,qstr.len);
-	return lookup_hash(&qstr,parent);
-}               
-
 static struct super_block *debug_get_sb(struct file_system_type *fs_type,
 				        int flags, const char *dev_name,
 					void *data)
@@ -157,7 +147,7 @@ static int debugfs_create_by_name(const 
 
 	*dentry = NULL;
 	down(&parent->d_inode->i_sem);
-	*dentry = get_dentry (parent, name);
+	*dentry = lookup_one_len(name, parent, strlen(name));
 	if (!IS_ERR(dentry)) {
 		if ((mode & S_IFMT) == S_IFDIR)
 			error = debugfs_mkdir(parent->d_inode, *dentry, mode);
diff --git a/fs/devfs/base.c b/fs/devfs/base.c
--- a/fs/devfs/base.c
+++ b/fs/devfs/base.c
@@ -2491,11 +2491,11 @@ static int devfs_mknod(struct inode *dir
 	return 0;
 }				/*  End Function devfs_mknod  */
 
-static int devfs_follow_link(struct dentry *dentry, struct nameidata *nd)
+static void *devfs_follow_link(struct dentry *dentry, struct nameidata *nd)
 {
 	struct devfs_entry *p = get_devfs_entry_from_vfs_inode(dentry->d_inode);
 	nd_set_link(nd, p ? p->u.symlink.linkname : ERR_PTR(-ENODEV));
-	return 0;
+	return NULL;
 }				/*  End Function devfs_follow_link  */
 
 static struct inode_operations devfs_iops = {
diff --git a/fs/direct-io.c b/fs/direct-io.c
--- a/fs/direct-io.c
+++ b/fs/direct-io.c
@@ -215,7 +215,7 @@ static struct page *dio_get_page(struct 
 static void dio_complete(struct dio *dio, loff_t offset, ssize_t bytes)
 {
 	if (dio->end_io && dio->result)
-		dio->end_io(dio->inode, offset, bytes, dio->map_bh.b_private);
+		dio->end_io(dio->iocb, offset, bytes, dio->map_bh.b_private);
 	if (dio->lock_type == DIO_LOCKING)
 		up_read(&dio->inode->i_alloc_sem);
 }
diff --git a/fs/dquot.c b/fs/dquot.c
--- a/fs/dquot.c
+++ b/fs/dquot.c
@@ -409,13 +409,10 @@ out_dqlock:
  * for this sb+type at all. */
 static void invalidate_dquots(struct super_block *sb, int type)
 {
-	struct dquot *dquot;
-	struct list_head *head;
+	struct dquot *dquot, *tmp;
 
 	spin_lock(&dq_list_lock);
-	for (head = inuse_list.next; head != &inuse_list;) {
-		dquot = list_entry(head, struct dquot, dq_inuse);
-		head = head->next;
+	list_for_each_entry_safe(dquot, tmp, &inuse_list, dq_inuse) {
 		if (dquot->dq_sb != sb)
 			continue;
 		if (dquot->dq_type != type)
@@ -1519,14 +1516,22 @@ out_path:
  * This function is used when filesystem needs to initialize quotas
  * during mount time.
  */
-int vfs_quota_on_mount(int type, int format_id, struct dentry *dentry)
+int vfs_quota_on_mount(struct super_block *sb, char *qf_name,
+		int format_id, int type)
 {
+	struct dentry *dentry;
 	int error;
 
+	dentry = lookup_one_len(qf_name, sb->s_root, strlen(qf_name));
+	if (IS_ERR(dentry))
+		return PTR_ERR(dentry);
+
 	error = security_quota_on(dentry);
-	if (error)
-		return error;
-	return vfs_quota_on_inode(dentry->d_inode, type, format_id);
+	if (!error)
+		error = vfs_quota_on_inode(dentry->d_inode, type, format_id);
+
+	dput(dentry);
+	return error;
 }
 
 /* Generic routine for getting common part of quota structure */
diff --git a/fs/eventpoll.c b/fs/eventpoll.c
--- a/fs/eventpoll.c
+++ b/fs/eventpoll.c
@@ -101,57 +101,6 @@
 /* Maximum number of poll wake up nests we are allowing */
 #define EP_MAX_POLLWAKE_NESTS 4
 
-/* Macro to allocate a "struct epitem" from the slab cache */
-#define EPI_MEM_ALLOC()	(struct epitem *) kmem_cache_alloc(epi_cache, SLAB_KERNEL)
-
-/* Macro to free a "struct epitem" to the slab cache */
-#define EPI_MEM_FREE(p) kmem_cache_free(epi_cache, p)
-
-/* Macro to allocate a "struct eppoll_entry" from the slab cache */
-#define PWQ_MEM_ALLOC()	(struct eppoll_entry *) kmem_cache_alloc(pwq_cache, SLAB_KERNEL)
-
-/* Macro to free a "struct eppoll_entry" to the slab cache */
-#define PWQ_MEM_FREE(p) kmem_cache_free(pwq_cache, p)
-
-/* Fast test to see if the file is an evenpoll file */
-#define IS_FILE_EPOLL(f) ((f)->f_op == &eventpoll_fops)
-
-/* Setup the structure that is used as key for the rb-tree */
-#define EP_SET_FFD(p, f, d) do { (p)->file = (f); (p)->fd = (d); } while (0)
-
-/* Compare rb-tree keys */
-#define EP_CMP_FFD(p1, p2) ((p1)->file > (p2)->file ? +1: \
-			    ((p1)->file < (p2)->file ? -1: (p1)->fd - (p2)->fd))
-
-/* Special initialization for the rb-tree node to detect linkage */
-#define EP_RB_INITNODE(n) (n)->rb_parent = (n)
-
-/* Removes a node from the rb-tree and marks it for a fast is-linked check */
-#define EP_RB_ERASE(n, r) do { rb_erase(n, r); (n)->rb_parent = (n); } while (0)
-
-/* Fast check to verify that the item is linked to the main rb-tree */
-#define EP_RB_LINKED(n) ((n)->rb_parent != (n))
-
-/*
- * Remove the item from the list and perform its initialization.
- * This is useful for us because we can test if the item is linked
- * using "EP_IS_LINKED(p)".
- */
-#define EP_LIST_DEL(p) do { list_del(p); INIT_LIST_HEAD(p); } while (0)
-
-/* Tells us if the item is currently linked */
-#define EP_IS_LINKED(p) (!list_empty(p))
-
-/* Get the "struct epitem" from a wait queue pointer */
-#define EP_ITEM_FROM_WAIT(p) ((struct epitem *) container_of(p, struct eppoll_entry, wait)->base)
-
-/* Get the "struct epitem" from an epoll queue wrapper */
-#define EP_ITEM_FROM_EPQUEUE(p) (container_of(p, struct ep_pqueue, pt)->epi)
-
-/* Tells if the epoll_ctl(2) operation needs an event copy from userspace */
-#define EP_OP_HASH_EVENT(op) ((op) != EPOLL_CTL_DEL)
-
-
 struct epoll_filefd {
 	struct file *file;
 	int fd;
@@ -357,6 +306,82 @@ static struct dentry_operations eventpol
 
 
 
+/* Fast test to see if the file is an evenpoll file */
+static inline int is_file_epoll(struct file *f)
+{
+	return f->f_op == &eventpoll_fops;
+}
+
+/* Setup the structure that is used as key for the rb-tree */
+static inline void ep_set_ffd(struct epoll_filefd *ffd,
+			      struct file *file, int fd)
+{
+	ffd->file = file;
+	ffd->fd = fd;
+}
+
+/* Compare rb-tree keys */
+static inline int ep_cmp_ffd(struct epoll_filefd *p1,
+			     struct epoll_filefd *p2)
+{
+	return (p1->file > p2->file ? +1:
+	        (p1->file < p2->file ? -1 : p1->fd - p2->fd));
+}
+
+/* Special initialization for the rb-tree node to detect linkage */
+static inline void ep_rb_initnode(struct rb_node *n)
+{
+	n->rb_parent = n;
+}
+
+/* Removes a node from the rb-tree and marks it for a fast is-linked check */
+static inline void ep_rb_erase(struct rb_node *n, struct rb_root *r)
+{
+	rb_erase(n, r);
+	n->rb_parent = n;
+}
+
+/* Fast check to verify that the item is linked to the main rb-tree */
+static inline int ep_rb_linked(struct rb_node *n)
+{
+	return n->rb_parent != n;
+}
+
+/*
+ * Remove the item from the list and perform its initialization.
+ * This is useful for us because we can test if the item is linked
+ * using "ep_is_linked(p)".
+ */
+static inline void ep_list_del(struct list_head *p)
+{
+	list_del(p);
+	INIT_LIST_HEAD(p);
+}
+
+/* Tells us if the item is currently linked */
+static inline int ep_is_linked(struct list_head *p)
+{
+	return !list_empty(p);
+}
+
+/* Get the "struct epitem" from a wait queue pointer */
+static inline struct epitem * ep_item_from_wait(wait_queue_t *p)
+{
+	return container_of(p, struct eppoll_entry, wait)->base;
+}
+
+/* Get the "struct epitem" from an epoll queue wrapper */
+static inline struct epitem * ep_item_from_epqueue(poll_table *p)
+{
+	return container_of(p, struct ep_pqueue, pt)->epi;
+}
+
+/* Tells if the epoll_ctl(2) operation needs an event copy from userspace */
+static inline int ep_op_hash_event(int op)
+{
+	return op != EPOLL_CTL_DEL;
+}
+
 /* Initialize the poll safe wake up structure */
 static void ep_poll_safewake_init(struct poll_safewake *psw)
 {
@@ -456,7 +481,7 @@ void eventpoll_release_file(struct file 
 		epi = list_entry(lsthead->next, struct epitem, fllink);
 
 		ep = epi->ep;
-		EP_LIST_DEL(&epi->fllink);
+		ep_list_del(&epi->fllink);
 		down_write(&ep->sem);
 		ep_remove(ep, epi);
 		up_write(&ep->sem);
@@ -534,7 +559,7 @@ sys_epoll_ctl(int epfd, int op, int fd, 
 		     current, epfd, op, fd, event));
 
 	error = -EFAULT;
-	if (EP_OP_HASH_EVENT(op) &&
+	if (ep_op_hash_event(op) &&
 	    copy_from_user(&epds, event, sizeof(struct epoll_event)))
 		goto eexit_1;
 
@@ -560,7 +585,7 @@ sys_epoll_ctl(int epfd, int op, int fd, 
 	 * adding an epoll file descriptor inside itself.
 	 */
 	error = -EINVAL;
-	if (file == tfile || !IS_FILE_EPOLL(file))
+	if (file == tfile || !is_file_epoll(file))
 		goto eexit_3;
 
 	/*
@@ -656,7 +681,7 @@ asmlinkage long sys_epoll_wait(int epfd,
 	 * the user passed to us _is_ an eventpoll file.
 	 */
 	error = -EINVAL;
-	if (!IS_FILE_EPOLL(file))
+	if (!is_file_epoll(file))
 		goto eexit_2;
 
 	/*
@@ -831,11 +856,11 @@ static struct epitem *ep_find(struct eve
 	struct epitem *epi, *epir = NULL;
 	struct epoll_filefd ffd;
 
-	EP_SET_FFD(&ffd, file, fd);
+	ep_set_ffd(&ffd, file, fd);
 	read_lock_irqsave(&ep->lock, flags);
 	for (rbp = ep->rbr.rb_node; rbp; ) {
 		epi = rb_entry(rbp, struct epitem, rbn);
-		kcmp = EP_CMP_FFD(&ffd, &epi->ffd);
+		kcmp = ep_cmp_ffd(&ffd, &epi->ffd);
 		if (kcmp > 0)
 			rbp = rbp->rb_right;
 		else if (kcmp < 0)
@@ -875,7 +900,7 @@ static void ep_release_epitem(struct epi
 {
 
 	if (atomic_dec_and_test(&epi->usecnt))
-		EPI_MEM_FREE(epi);
+		kmem_cache_free(epi_cache, epi);
 }
 
 
@@ -886,10 +911,10 @@ static void ep_release_epitem(struct epi
 static void ep_ptable_queue_proc(struct file *file, wait_queue_head_t *whead,
 				 poll_table *pt)
 {
-	struct epitem *epi = EP_ITEM_FROM_EPQUEUE(pt);
+	struct epitem *epi = ep_item_from_epqueue(pt);
 	struct eppoll_entry *pwq;
 
-	if (epi->nwait >= 0 && (pwq = PWQ_MEM_ALLOC())) {
+	if (epi->nwait >= 0 && (pwq = kmem_cache_alloc(pwq_cache, SLAB_KERNEL))) {
 		init_waitqueue_func_entry(&pwq->wait, ep_poll_callback);
 		pwq->whead = whead;
 		pwq->base = epi;
@@ -912,7 +937,7 @@ static void ep_rbtree_insert(struct even
 	while (*p) {
 		parent = *p;
 		epic = rb_entry(parent, struct epitem, rbn);
-		kcmp = EP_CMP_FFD(&epi->ffd, &epic->ffd);
+		kcmp = ep_cmp_ffd(&epi->ffd, &epic->ffd);
 		if (kcmp > 0)
 			p = &parent->rb_right;
 		else
@@ -932,17 +957,17 @@ static int ep_insert(struct eventpoll *e
 	struct ep_pqueue epq;
 
 	error = -ENOMEM;
-	if (!(epi = EPI_MEM_ALLOC()))
+	if (!(epi = kmem_cache_alloc(epi_cache, SLAB_KERNEL)))
 		goto eexit_1;
 
 	/* Item initialization follow here ... */
-	EP_RB_INITNODE(&epi->rbn);
+	ep_rb_initnode(&epi->rbn);
 	INIT_LIST_HEAD(&epi->rdllink);
 	INIT_LIST_HEAD(&epi->fllink);
 	INIT_LIST_HEAD(&epi->txlink);
 	INIT_LIST_HEAD(&epi->pwqlist);
 	epi->ep = ep;
-	EP_SET_FFD(&epi->ffd, tfile, fd);
+	ep_set_ffd(&epi->ffd, tfile, fd);
 	epi->event = *event;
 	atomic_set(&epi->usecnt, 1);
 	epi->nwait = 0;
@@ -978,7 +1003,7 @@ static int ep_insert(struct eventpoll *e
 	ep_rbtree_insert(ep, epi);
 
 	/* If the file is already "ready" we drop it inside the ready list */
-	if ((revents & event->events) && !EP_IS_LINKED(&epi->rdllink)) {
+	if ((revents & event->events) && !ep_is_linked(&epi->rdllink)) {
 		list_add_tail(&epi->rdllink, &ep->rdllist);
 
 		/* Notify waiting tasks that events are available */
@@ -1007,11 +1032,11 @@ eexit_2:
 	 * allocated wait queue.
 	 */
 	write_lock_irqsave(&ep->lock, flags);
-	if (EP_IS_LINKED(&epi->rdllink))
-		EP_LIST_DEL(&epi->rdllink);
+	if (ep_is_linked(&epi->rdllink))
+		ep_list_del(&epi->rdllink);
 	write_unlock_irqrestore(&ep->lock, flags);
 
-	EPI_MEM_FREE(epi);
+	kmem_cache_free(epi_cache, epi);
 eexit_1:
 	return error;
 }
@@ -1050,14 +1075,14 @@ static int ep_modify(struct eventpoll *e
 	 * If the item is not linked to the hash it means that it's on its
 	 * way toward the removal. Do nothing in this case.
 	 */
-	if (EP_RB_LINKED(&epi->rbn)) {
+	if (ep_rb_linked(&epi->rbn)) {
 		/*
 		 * If the item is "hot" and it is not registered inside the ready
 		 * list, push it inside. If the item is not "hot" and it is currently
 		 * registered inside the ready list, unlink it.
 		 */
 		if (revents & event->events) {
-			if (!EP_IS_LINKED(&epi->rdllink)) {
+			if (!ep_is_linked(&epi->rdllink)) {
 				list_add_tail(&epi->rdllink, &ep->rdllist);
 
 				/* Notify waiting tasks that events are available */
@@ -1097,9 +1122,9 @@ static void ep_unregister_pollwait(struc
 		while (!list_empty(lsthead)) {
 			pwq = list_entry(lsthead->next, struct eppoll_entry, llink);
 
-			EP_LIST_DEL(&pwq->llink);
+			ep_list_del(&pwq->llink);
 			remove_wait_queue(pwq->whead, &pwq->wait);
-			PWQ_MEM_FREE(pwq);
+			kmem_cache_free(pwq_cache, pwq);
 		}
 	}
 }
@@ -1118,7 +1143,7 @@ static int ep_unlink(struct eventpoll *e
 	 * The check protect us from doing a double unlink ( crash ).
 	 */
 	error = -ENOENT;
-	if (!EP_RB_LINKED(&epi->rbn))
+	if (!ep_rb_linked(&epi->rbn))
 		goto eexit_1;
 
 	/*
@@ -1133,14 +1158,14 @@ static int ep_unlink(struct eventpoll *e
 	 * This operation togheter with the above check closes the door to
 	 * double unlinks.
 	 */
-	EP_RB_ERASE(&epi->rbn, &ep->rbr);
+	ep_rb_erase(&epi->rbn, &ep->rbr);
 
 	/*
 	 * If the item we are going to remove is inside the ready file descriptors
 	 * we want to remove it from this list to avoid stale events.
 	 */
-	if (EP_IS_LINKED(&epi->rdllink))
-		EP_LIST_DEL(&epi->rdllink);
+	if (ep_is_linked(&epi->rdllink))
+		ep_list_del(&epi->rdllink);
 
 	error = 0;
 eexit_1:
@@ -1174,8 +1199,8 @@ static int ep_remove(struct eventpoll *e
 
 	/* Remove the current item from the list of epoll hooks */
 	spin_lock(&file->f_ep_lock);
-	if (EP_IS_LINKED(&epi->fllink))
-		EP_LIST_DEL(&epi->fllink);
+	if (ep_is_linked(&epi->fllink))
+		ep_list_del(&epi->fllink);
 	spin_unlock(&file->f_ep_lock);
 
 	/* We need to acquire the write IRQ lock before calling ep_unlink() */
@@ -1210,7 +1235,7 @@ static int ep_poll_callback(wait_queue_t
 {
 	int pwake = 0;
 	unsigned long flags;
-	struct epitem *epi = EP_ITEM_FROM_WAIT(wait);
+	struct epitem *epi = ep_item_from_wait(wait);
 	struct eventpoll *ep = epi->ep;
 
 	DNPRINTK(3, (KERN_INFO "[%p] eventpoll: poll_callback(%p) epi=%p ep=%p\n",
@@ -1228,7 +1253,7 @@ static int ep_poll_callback(wait_queue_t
 		goto is_disabled;
 
 	/* If this file is already in the ready list we exit soon */
-	if (EP_IS_LINKED(&epi->rdllink))
+	if (ep_is_linked(&epi->rdllink))
 		goto is_linked;
 
 	list_add_tail(&epi->rdllink, &ep->rdllist);
@@ -1307,7 +1332,7 @@ static int ep_collect_ready_items(struct
 		lnk = lnk->next;
 
 		/* If this file is already in the ready list we exit soon */
-		if (!EP_IS_LINKED(&epi->txlink)) {
+		if (!ep_is_linked(&epi->txlink)) {
 			/*
 			 * This is initialized in this way so that the default
 			 * behaviour of the reinjecting code will be to push back
@@ -1322,7 +1347,7 @@ static int ep_collect_ready_items(struct
 			/*
 			 * Unlink the item from the ready list.
 			 */
-			EP_LIST_DEL(&epi->rdllink);
+			ep_list_del(&epi->rdllink);
 		}
 	}
 
@@ -1401,7 +1426,7 @@ static void ep_reinject_items(struct eve
 		epi = list_entry(txlist->next, struct epitem, txlink);
 
 		/* Unlink the current item from the transfer list */
-		EP_LIST_DEL(&epi->txlink);
+		ep_list_del(&epi->txlink);
 
 		/*
 		 * If the item is no more linked to the interest set, we don't
@@ -1410,8 +1435,8 @@ static void ep_reinject_items(struct eve
 		 * item is set to have an Edge Triggered behaviour, we don't have
 		 * to push it back either.
 		 */
-		if (EP_RB_LINKED(&epi->rbn) && !(epi->event.events & EPOLLET) &&
-		    (epi->revents & epi->event.events) && !EP_IS_LINKED(&epi->rdllink)) {
+		if (ep_rb_linked(&epi->rbn) && !(epi->event.events & EPOLLET) &&
+		    (epi->revents & epi->event.events) && !ep_is_linked(&epi->rdllink)) {
 			list_add_tail(&epi->rdllink, &ep->rdllist);
 			ricnt++;
 		}
diff --git a/fs/exec.c b/fs/exec.c
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -58,6 +58,9 @@
 
 int core_uses_pid;
 char core_pattern[65] = "core";
+int suid_dumpable = 0;
+
+EXPORT_SYMBOL(suid_dumpable);
 /* The maximal length of core_pattern is also specified in sysctl.c */
 
 static struct linux_binfmt *formats;
@@ -639,6 +642,18 @@ static inline int de_thread(struct task_
 	count = 2;
 	if (thread_group_leader(current))
 		count = 1;
+	else {
+		/*
+		 * The SIGALRM timer survives the exec, but needs to point
+		 * at us as the new group leader now.  We have a race with
+		 * a timer firing now getting the old leader, so we need to
+		 * synchronize with any firing (by calling del_timer_sync)
+		 * before we can safely let the old group leader die.
+		 */
+		sig->real_timer.data = (unsigned long)current;
+		if (del_timer_sync(&sig->real_timer))
+			add_timer(&sig->real_timer);
+	}
 	while (atomic_read(&sig->count) > count) {
 		sig->group_exit_task = current;
 		sig->notify_count = count;
@@ -649,6 +664,7 @@ static inline int de_thread(struct task_
 	}
 	sig->group_exit_task = NULL;
 	sig->notify_count = 0;
+	sig->real_timer.data = (unsigned long)current;
 	spin_unlock_irq(lock);
 
 	/*
@@ -675,10 +691,8 @@ static inline int de_thread(struct task_
 		proc_dentry2 = proc_pid_unhash(leader);
 		write_lock_irq(&tasklist_lock);
 
-		if (leader->tgid != current->tgid)
-			BUG();
-		if (current->pid == current->tgid)
-			BUG();
+		BUG_ON(leader->tgid != current->tgid);
+		BUG_ON(current->pid == current->tgid);
 		/*
 		 * An exec() starts a new thread group with the
 		 * TGID of the previous thread group. Rehash the
@@ -726,8 +740,7 @@ static inline int de_thread(struct task_
 		proc_pid_flush(proc_dentry1);
 		proc_pid_flush(proc_dentry2);
 
-		if (exit_state != EXIT_ZOMBIE)
-			BUG();
+		BUG_ON(exit_state != EXIT_ZOMBIE);
 		release_task(leader);
         }
 
@@ -772,10 +785,8 @@ no_thread_group:
 			kmem_cache_free(sighand_cachep, oldsighand);
 	}
 
-	if (!thread_group_empty(current))
-		BUG();
-	if (!thread_group_leader(current))
-		BUG();
+	BUG_ON(!thread_group_empty(current));
+	BUG_ON(!thread_group_leader(current));
 	return 0;
 }
 	
@@ -868,6 +879,9 @@ int flush_old_exec(struct linux_binprm *
 
 	if (current->euid == current->uid && current->egid == current->gid)
 		current->mm->dumpable = 1;
+	else
+		current->mm->dumpable = suid_dumpable;
+
 	name = bprm->filename;
 
 	/* Copies the binary name from after last slash */
@@ -888,7 +902,7 @@ int flush_old_exec(struct linux_binprm *
 	    permission(bprm->file->f_dentry->d_inode,MAY_READ, NULL) ||
 	    (bprm->interp_flags & BINPRM_FLAGS_ENFORCE_NONDUMP)) {
 		suid_keys(current);
-		current->mm->dumpable = 0;
+		current->mm->dumpable = suid_dumpable;
 	}
 
 	/* An exec changes our domain. We are no longer part of the thread
@@ -1436,6 +1450,8 @@ int do_coredump(long signr, int exit_cod
 	struct inode * inode;
 	struct file * file;
 	int retval = 0;
+	int fsuid = current->fsuid;
+	int flag = 0;
 
 	binfmt = current->binfmt;
 	if (!binfmt || !binfmt->core_dump)
@@ -1445,6 +1461,16 @@ int do_coredump(long signr, int exit_cod
 		up_write(&mm->mmap_sem);
 		goto fail;
 	}
+
+	/*
+	 *	We cannot trust fsuid as being the "true" uid of the
+	 *	process nor do we know its entire history. We only know it
+	 *	was tainted so we dump it as root in mode 2.
+	 */
+	if (mm->dumpable == 2) {	/* Setuid core dump mode */
+		flag = O_EXCL;		/* Stop rewrite attacks */
+		current->fsuid = 0;	/* Dump root private */
+	}
 	mm->dumpable = 0;
 	init_completion(&mm->core_done);
 	spin_lock_irq(&current->sighand->siglock);
@@ -1470,7 +1496,7 @@ int do_coredump(long signr, int exit_cod
  	lock_kernel();
 	format_corename(corename, core_pattern, signr);
 	unlock_kernel();
-	file = filp_open(corename, O_CREAT | 2 | O_NOFOLLOW | O_LARGEFILE, 0600);
+	file = filp_open(corename, O_CREAT | 2 | O_NOFOLLOW | O_LARGEFILE | flag, 0600);
 	if (IS_ERR(file))
 		goto fail_unlock;
 	inode = file->f_dentry->d_inode;
@@ -1495,6 +1521,7 @@ int do_coredump(long signr, int exit_cod
 close_fail:
 	filp_close(file, NULL);
 fail_unlock:
+	current->fsuid = fsuid;
 	complete_all(&mm->core_done);
 fail:
 	return retval;
diff --git a/fs/ext2/Makefile b/fs/ext2/Makefile
--- a/fs/ext2/Makefile
+++ b/fs/ext2/Makefile
@@ -10,3 +10,4 @@ ext2-y := balloc.o bitmap.o dir.o file.o
 ext2-$(CONFIG_EXT2_FS_XATTR)	 += xattr.o xattr_user.o xattr_trusted.o
 ext2-$(CONFIG_EXT2_FS_POSIX_ACL) += acl.o
 ext2-$(CONFIG_EXT2_FS_SECURITY)	 += xattr_security.o
+ext2-$(CONFIG_EXT2_FS_XIP)	 += xip.o
diff --git a/fs/ext2/acl.c b/fs/ext2/acl.c
--- a/fs/ext2/acl.c
+++ b/fs/ext2/acl.c
@@ -396,12 +396,12 @@ static size_t
 ext2_xattr_list_acl_access(struct inode *inode, char *list, size_t list_size,
 			   const char *name, size_t name_len)
 {
-	const size_t size = sizeof(XATTR_NAME_ACL_ACCESS);
+	const size_t size = sizeof(POSIX_ACL_XATTR_ACCESS);
 
 	if (!test_opt(inode->i_sb, POSIX_ACL))
 		return 0;
 	if (list && size <= list_size)
-		memcpy(list, XATTR_NAME_ACL_ACCESS, size);
+		memcpy(list, POSIX_ACL_XATTR_ACCESS, size);
 	return size;
 }
 
@@ -409,12 +409,12 @@ static size_t
 ext2_xattr_list_acl_default(struct inode *inode, char *list, size_t list_size,
 			    const char *name, size_t name_len)
 {
-	const size_t size = sizeof(XATTR_NAME_ACL_DEFAULT);
+	const size_t size = sizeof(POSIX_ACL_XATTR_DEFAULT);
 
 	if (!test_opt(inode->i_sb, POSIX_ACL))
 		return 0;
 	if (list && size <= list_size)
-		memcpy(list, XATTR_NAME_ACL_DEFAULT, size);
+		memcpy(list, POSIX_ACL_XATTR_DEFAULT, size);
 	return size;
 }
 
@@ -506,14 +506,14 @@ ext2_xattr_set_acl_default(struct inode 
 }
 
 struct xattr_handler ext2_xattr_acl_access_handler = {
-	.prefix	= XATTR_NAME_ACL_ACCESS,
+	.prefix	= POSIX_ACL_XATTR_ACCESS,
 	.list	= ext2_xattr_list_acl_access,
 	.get	= ext2_xattr_get_acl_access,
 	.set	= ext2_xattr_set_acl_access,
 };
 
 struct xattr_handler ext2_xattr_acl_default_handler = {
-	.prefix	= XATTR_NAME_ACL_DEFAULT,
+	.prefix	= POSIX_ACL_XATTR_DEFAULT,
 	.list	= ext2_xattr_list_acl_default,
 	.get	= ext2_xattr_get_acl_default,
 	.set	= ext2_xattr_set_acl_default,
diff --git a/fs/ext2/acl.h b/fs/ext2/acl.h
--- a/fs/ext2/acl.h
+++ b/fs/ext2/acl.h
@@ -4,7 +4,7 @@
   (C) 2001 Andreas Gruenbacher, <a.gruenbacher@computer.org>
 */
 
-#include <linux/xattr_acl.h>
+#include <linux/posix_acl_xattr.h>
 
 #define EXT2_ACL_VERSION	0x0001
 
diff --git a/fs/ext2/ext2.h b/fs/ext2/ext2.h
--- a/fs/ext2/ext2.h
+++ b/fs/ext2/ext2.h
@@ -2,6 +2,15 @@
 #include <linux/ext2_fs.h>
 
 /*
+ * ext2 mount options
+ */
+struct ext2_mount_options {
+	unsigned long s_mount_opt;
+	uid_t s_resuid;
+	gid_t s_resgid;
+};
+
+/*
  * second extended file system inode data in memory
  */
 struct ext2_inode_info {
@@ -147,9 +156,11 @@ extern struct file_operations ext2_dir_o
 /* file.c */
 extern struct inode_operations ext2_file_inode_operations;
 extern struct file_operations ext2_file_operations;
+extern struct file_operations ext2_xip_file_operations;
 
 /* inode.c */
 extern struct address_space_operations ext2_aops;
+extern struct address_space_operations ext2_aops_xip;
 extern struct address_space_operations ext2_nobh_aops;
 
 /* namei.c */
diff --git a/fs/ext2/file.c b/fs/ext2/file.c
--- a/fs/ext2/file.c
+++ b/fs/ext2/file.c
@@ -55,6 +55,20 @@ struct file_operations ext2_file_operati
 	.sendfile	= generic_file_sendfile,
 };
 
+#ifdef CONFIG_EXT2_FS_XIP
+struct file_operations ext2_xip_file_operations = {
+	.llseek		= generic_file_llseek,
+	.read		= xip_file_read,
+	.write		= xip_file_write,
+	.ioctl		= ext2_ioctl,
+	.mmap		= xip_file_mmap,
+	.open		= generic_file_open,
+	.release	= ext2_release_file,
+	.fsync		= ext2_sync_file,
+	.sendfile	= xip_file_sendfile,
+};
+#endif
+
 struct inode_operations ext2_file_inode_operations = {
 	.truncate	= ext2_truncate,
 #ifdef CONFIG_EXT2_FS_XATTR
diff --git a/fs/ext2/ialloc.c b/fs/ext2/ialloc.c
--- a/fs/ext2/ialloc.c
+++ b/fs/ext2/ialloc.c
@@ -612,6 +612,7 @@ got:
 	err = ext2_init_acl(inode, dir);
 	if (err) {
 		DQUOT_FREE_INODE(inode);
+		DQUOT_DROP(inode);
 		goto fail2;
 	}
 	mark_inode_dirty(inode);
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c
--- a/fs/ext2/inode.c
+++ b/fs/ext2/inode.c
@@ -33,6 +33,7 @@
 #include <linux/mpage.h>
 #include "ext2.h"
 #include "acl.h"
+#include "xip.h"
 
 MODULE_AUTHOR("Remy Card and others");
 MODULE_DESCRIPTION("Second Extended Filesystem");
@@ -594,6 +595,16 @@ out:
 	if (err)
 		goto cleanup;
 
+	if (ext2_use_xip(inode->i_sb)) {
+		/*
+		 * we need to clear the block
+		 */
+		err = ext2_clear_xip_target (inode,
+			le32_to_cpu(chain[depth-1].key));
+		if (err)
+			goto cleanup;
+	}
+
 	if (ext2_splice_branch(inode, iblock, chain, partial, left) < 0)
 		goto changed;
 
@@ -691,6 +702,11 @@ struct address_space_operations ext2_aop
 	.writepages		= ext2_writepages,
 };
 
+struct address_space_operations ext2_aops_xip = {
+	.bmap			= ext2_bmap,
+	.get_xip_page		= ext2_get_xip_page,
+};
+
 struct address_space_operations ext2_nobh_aops = {
 	.readpage		= ext2_readpage,
 	.readpages		= ext2_readpages,
@@ -910,7 +926,9 @@ void ext2_truncate (struct inode * inode
 	iblock = (inode->i_size + blocksize-1)
 					>> EXT2_BLOCK_SIZE_BITS(inode->i_sb);
 
-	if (test_opt(inode->i_sb, NOBH))
+	if (mapping_is_xip(inode->i_mapping))
+		xip_truncate_page(inode->i_mapping, inode->i_size);
+	else if (test_opt(inode->i_sb, NOBH))
 		nobh_truncate_page(inode->i_mapping, inode->i_size);
 	else
 		block_truncate_page(inode->i_mapping,
@@ -1110,11 +1128,16 @@ void ext2_read_inode (struct inode * ino
 
 	if (S_ISREG(inode->i_mode)) {
 		inode->i_op = &ext2_file_inode_operations;
-		inode->i_fop = &ext2_file_operations;
-		if (test_opt(inode->i_sb, NOBH))
+		if (ext2_use_xip(inode->i_sb)) {
+			inode->i_mapping->a_ops = &ext2_aops_xip;
+			inode->i_fop = &ext2_xip_file_operations;
+		} else if (test_opt(inode->i_sb, NOBH)) {
 			inode->i_mapping->a_ops = &ext2_nobh_aops;
-		else
+			inode->i_fop = &ext2_file_operations;
+		} else {
 			inode->i_mapping->a_ops = &ext2_aops;
+			inode->i_fop = &ext2_file_operations;
+		}
 	} else if (S_ISDIR(inode->i_mode)) {
 		inode->i_op = &ext2_dir_inode_operations;
 		inode->i_fop = &ext2_dir_operations;
diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c
--- a/fs/ext2/namei.c
+++ b/fs/ext2/namei.c
@@ -34,6 +34,7 @@
 #include "ext2.h"
 #include "xattr.h"
 #include "acl.h"
+#include "xip.h"
 
 /*
  * Couple of helper functions - make the code slightly cleaner.
@@ -127,11 +128,16 @@ static int ext2_create (struct inode * d
 	int err = PTR_ERR(inode);
 	if (!IS_ERR(inode)) {
 		inode->i_op = &ext2_file_inode_operations;
-		inode->i_fop = &ext2_file_operations;
-		if (test_opt(inode->i_sb, NOBH))
+		if (ext2_use_xip(inode->i_sb)) {
+			inode->i_mapping->a_ops = &ext2_aops_xip;
+			inode->i_fop = &ext2_xip_file_operations;
+		} else if (test_opt(inode->i_sb, NOBH)) {
 			inode->i_mapping->a_ops = &ext2_nobh_aops;
-		else
+			inode->i_fop = &ext2_file_operations;
+		} else {
 			inode->i_mapping->a_ops = &ext2_aops;
+			inode->i_fop = &ext2_file_operations;
+		}
 		mark_inode_dirty(inode);
 		err = ext2_add_nondir(dentry, inode);
 	}
diff --git a/fs/ext2/super.c b/fs/ext2/super.c
--- a/fs/ext2/super.c
+++ b/fs/ext2/super.c
@@ -31,6 +31,7 @@
 #include "ext2.h"
 #include "xattr.h"
 #include "acl.h"
+#include "xip.h"
 
 static void ext2_sync_super(struct super_block *sb,
 			    struct ext2_super_block *es);
@@ -257,7 +258,7 @@ enum {
 	Opt_bsd_df, Opt_minix_df, Opt_grpid, Opt_nogrpid,
 	Opt_resgid, Opt_resuid, Opt_sb, Opt_err_cont, Opt_err_panic, Opt_err_ro,
 	Opt_nouid32, Opt_check, Opt_nocheck, Opt_debug, Opt_oldalloc, Opt_orlov, Opt_nobh,
-	Opt_user_xattr, Opt_nouser_xattr, Opt_acl, Opt_noacl,
+	Opt_user_xattr, Opt_nouser_xattr, Opt_acl, Opt_noacl, Opt_xip,
 	Opt_ignore, Opt_err,
 };
 
@@ -286,6 +287,7 @@ static match_table_t tokens = {
 	{Opt_nouser_xattr, "nouser_xattr"},
 	{Opt_acl, "acl"},
 	{Opt_noacl, "noacl"},
+	{Opt_xip, "xip"},
 	{Opt_ignore, "grpquota"},
 	{Opt_ignore, "noquota"},
 	{Opt_ignore, "quota"},
@@ -397,6 +399,13 @@ static int parse_options (char * options
 			printk("EXT2 (no)acl options not supported\n");
 			break;
 #endif
+		case Opt_xip:
+#ifdef CONFIG_EXT2_FS_XIP
+			set_opt (sbi->s_mount_opt, XIP);
+#else
+			printk("EXT2 xip option not supported\n");
+#endif
+			break;
 		case Opt_ignore:
 			break;
 		default:
@@ -640,6 +649,9 @@ static int ext2_fill_super(struct super_
 		((EXT2_SB(sb)->s_mount_opt & EXT2_MOUNT_POSIX_ACL) ?
 		 MS_POSIXACL : 0);
 
+	ext2_xip_verify_sb(sb); /* see if bdev supports xip, unset
+				    EXT2_MOUNT_XIP if not */
+
 	if (le32_to_cpu(es->s_rev_level) == EXT2_GOOD_OLD_REV &&
 	    (EXT2_HAS_COMPAT_FEATURE(sb, ~0U) ||
 	     EXT2_HAS_RO_COMPAT_FEATURE(sb, ~0U) ||
@@ -668,6 +680,13 @@ static int ext2_fill_super(struct super_
 
 	blocksize = BLOCK_SIZE << le32_to_cpu(sbi->s_es->s_log_block_size);
 
+	if ((ext2_use_xip(sb)) && ((blocksize != PAGE_SIZE) ||
+				  (sb->s_blocksize != blocksize))) {
+		if (!silent)
+			printk("XIP: Unsupported blocksize\n");
+		goto failed_mount;
+	}
+
 	/* If the blocksize doesn't match, re-read the thing.. */
 	if (sb->s_blocksize != blocksize) {
 		brelse(bh);
@@ -916,17 +935,34 @@ static int ext2_remount (struct super_bl
 {
 	struct ext2_sb_info * sbi = EXT2_SB(sb);
 	struct ext2_super_block * es;
+	unsigned long old_mount_opt = sbi->s_mount_opt;
+	struct ext2_mount_options old_opts;
+	unsigned long old_sb_flags;
+	int err;
+
+	/* Store the old options */
+	old_sb_flags = sb->s_flags;
+	old_opts.s_mount_opt = sbi->s_mount_opt;
+	old_opts.s_resuid = sbi->s_resuid;
+	old_opts.s_resgid = sbi->s_resgid;
 
 	/*
 	 * Allow the "check" option to be passed as a remount option.
 	 */
-	if (!parse_options (data, sbi))
-		return -EINVAL;
+	if (!parse_options (data, sbi)) {
+		err = -EINVAL;
+		goto restore_opts;
+	}
 
 	sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
 		((sbi->s_mount_opt & EXT2_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0);
 
 	es = sbi->s_es;
+	if (((sbi->s_mount_opt & EXT2_MOUNT_XIP) !=
+	    (old_mount_opt & EXT2_MOUNT_XIP)) &&
+	    invalidate_inodes(sb))
+		ext2_warning(sb, __FUNCTION__, "busy inodes while remounting "\
+			     "xip remain in cache (no functional problem)");
 	if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY))
 		return 0;
 	if (*flags & MS_RDONLY) {
@@ -946,7 +982,8 @@ static int ext2_remount (struct super_bl
 			printk("EXT2-fs: %s: couldn't remount RDWR because of "
 			       "unsupported optional features (%x).\n",
 			       sb->s_id, le32_to_cpu(ret));
-			return -EROFS;
+			err = -EROFS;
+			goto restore_opts;
 		}
 		/*
 		 * Mounting a RDONLY partition read-write, so reread and
@@ -959,6 +996,12 @@ static int ext2_remount (struct super_bl
 	}
 	ext2_sync_super(sb, es);
 	return 0;
+restore_opts:
+	sbi->s_mount_opt = old_opts.s_mount_opt;
+	sbi->s_resuid = old_opts.s_resuid;
+	sbi->s_resgid = old_opts.s_resgid;
+	sb->s_flags = old_sb_flags;
+	return err;
 }
 
 static int ext2_statfs (struct super_block * sb, struct kstatfs * buf)
diff --git a/fs/ext2/symlink.c b/fs/ext2/symlink.c
--- a/fs/ext2/symlink.c
+++ b/fs/ext2/symlink.c
@@ -21,11 +21,11 @@
 #include "xattr.h"
 #include <linux/namei.h>
 
-static int ext2_follow_link(struct dentry *dentry, struct nameidata *nd)
+static void *ext2_follow_link(struct dentry *dentry, struct nameidata *nd)
 {
 	struct ext2_inode_info *ei = EXT2_I(dentry->d_inode);
 	nd_set_link(nd, (char *)ei->i_data);
-	return 0;
+	return NULL;
 }
 
 struct inode_operations ext2_symlink_inode_operations = {
diff --git a/fs/ext2/xattr.c b/fs/ext2/xattr.c
--- a/fs/ext2/xattr.c
+++ b/fs/ext2/xattr.c
@@ -823,7 +823,7 @@ cleanup:
 void
 ext2_xattr_put_super(struct super_block *sb)
 {
-	mb_cache_shrink(ext2_xattr_cache, sb->s_bdev);
+	mb_cache_shrink(sb->s_bdev);
 }
 
 
diff --git a/fs/ext2/xip.c b/fs/ext2/xip.c
new file mode 100644
--- /dev/null
+++ b/fs/ext2/xip.c
@@ -0,0 +1,93 @@
+/*
+ *  linux/fs/ext2/xip.c
+ *
+ * Copyright (C) 2005 IBM Corporation
+ * Author: Carsten Otte (cotte@de.ibm.com)
+ */
+
+#include <linux/mm.h>
+#include <linux/fs.h>
+#include <linux/genhd.h>
+#include <linux/buffer_head.h>
+#include <linux/ext2_fs_sb.h>
+#include <linux/ext2_fs.h>
+#include "ext2.h"
+#include "xip.h"
+
+static inline int
+__inode_direct_access(struct inode *inode, sector_t sector,
+		      unsigned long *data)
+{
+	BUG_ON(!inode->i_sb->s_bdev->bd_disk->fops->direct_access);
+	return inode->i_sb->s_bdev->bd_disk->fops
+		->direct_access(inode->i_sb->s_bdev,sector,data);
+}
+
+static inline int
+__ext2_get_sector(struct inode *inode, sector_t offset, int create,
+		   sector_t *result)
+{
+	struct buffer_head tmp;
+	int rc;
+
+	memset(&tmp, 0, sizeof(struct buffer_head));
+	rc = ext2_get_block(inode, offset/ (PAGE_SIZE/512), &tmp,
+			    create);
+	*result = tmp.b_blocknr;
+
+	/* did we get a sparse block (hole in the file)? */
+	if (!tmp.b_blocknr && !rc) {
+		BUG_ON(create);
+		rc = -ENODATA;
+	}
+
+	return rc;
+}
+
+int
+ext2_clear_xip_target(struct inode *inode, int block)
+{
+	sector_t sector = block * (PAGE_SIZE/512);
+	unsigned long data;
+	int rc;
+
+	rc = __inode_direct_access(inode, sector, &data);
+	if (!rc)
+		clear_page((void*)data);
+	return rc;
+}
+
+void ext2_xip_verify_sb(struct super_block *sb)
+{
+	struct ext2_sb_info *sbi = EXT2_SB(sb);
+
+	if ((sbi->s_mount_opt & EXT2_MOUNT_XIP) &&
+	    !sb->s_bdev->bd_disk->fops->direct_access) {
+		sbi->s_mount_opt &= (~EXT2_MOUNT_XIP);
+		ext2_warning(sb, __FUNCTION__,
+			     "ignoring xip option - not supported by bdev");
+	}
+}
+
+struct page *
+ext2_get_xip_page(struct address_space *mapping, sector_t offset,
+		   int create)
+{
+	int rc;
+	unsigned long data;
+	sector_t sector;
+
+	/* first, retrieve the sector number */
+	rc = __ext2_get_sector(mapping->host, offset, create, &sector);
+	if (rc)
+		goto error;
+
+	/* retrieve address of the target data */
+	rc = __inode_direct_access
+		(mapping->host, sector * (PAGE_SIZE/512), &data);
+	if (!rc)
+		return virt_to_page(data);
+
+ error:
+	return ERR_PTR(rc);
+}
diff --git a/fs/ext2/xip.h b/fs/ext2/xip.h
new file mode 100644
--- /dev/null
+++ b/fs/ext2/xip.h
@@ -0,0 +1,25 @@
+/*
+ *  linux/fs/ext2/xip.h
+ *
+ * Copyright (C) 2005 IBM Corporation
+ * Author: Carsten Otte (cotte@de.ibm.com)
+ */
+
+#ifdef CONFIG_EXT2_FS_XIP
+extern void ext2_xip_verify_sb (struct super_block *);
+extern int ext2_clear_xip_target (struct inode *, int);
+
+static inline int ext2_use_xip (struct super_block *sb)
+{
+	struct ext2_sb_info *sbi = EXT2_SB(sb);
+	return (sbi->s_mount_opt & EXT2_MOUNT_XIP);
+}
+struct page* ext2_get_xip_page (struct address_space *, sector_t, int);
+#define mapping_is_xip(map) unlikely(map->a_ops->get_xip_page)
+#else
+#define mapping_is_xip(map)			0
+#define ext2_xip_verify_sb(sb)			do { } while (0)
+#define ext2_use_xip(sb)			0
+#define ext2_clear_xip_target(inode, chain)	0
+#define ext2_get_xip_page			NULL
+#endif
diff --git a/fs/ext3/acl.c b/fs/ext3/acl.c
--- a/fs/ext3/acl.c
+++ b/fs/ext3/acl.c
@@ -393,7 +393,8 @@ ext3_acl_chmod(struct inode *inode)
 		int retries = 0;
 
 	retry:
-		handle = ext3_journal_start(inode, EXT3_DATA_TRANS_BLOCKS);
+		handle = ext3_journal_start(inode,
+				EXT3_DATA_TRANS_BLOCKS(inode->i_sb));
 		if (IS_ERR(handle)) {
 			error = PTR_ERR(handle);
 			ext3_std_error(inode->i_sb, error);
@@ -417,12 +418,12 @@ static size_t
 ext3_xattr_list_acl_access(struct inode *inode, char *list, size_t list_len,
 			   const char *name, size_t name_len)
 {
-	const size_t size = sizeof(XATTR_NAME_ACL_ACCESS);
+	const size_t size = sizeof(POSIX_ACL_XATTR_ACCESS);
 
 	if (!test_opt(inode->i_sb, POSIX_ACL))
 		return 0;
 	if (list && size <= list_len)
-		memcpy(list, XATTR_NAME_ACL_ACCESS, size);
+		memcpy(list, POSIX_ACL_XATTR_ACCESS, size);
 	return size;
 }
 
@@ -430,12 +431,12 @@ static size_t
 ext3_xattr_list_acl_default(struct inode *inode, char *list, size_t list_len,
 			    const char *name, size_t name_len)
 {
-	const size_t size = sizeof(XATTR_NAME_ACL_DEFAULT);
+	const size_t size = sizeof(POSIX_ACL_XATTR_DEFAULT);
 
 	if (!test_opt(inode->i_sb, POSIX_ACL))
 		return 0;
 	if (list && size <= list_len)
-		memcpy(list, XATTR_NAME_ACL_DEFAULT, size);
+		memcpy(list, POSIX_ACL_XATTR_DEFAULT, size);
 	return size;
 }
 
@@ -503,7 +504,7 @@ ext3_xattr_set_acl(struct inode *inode, 
 		acl = NULL;
 
 retry:
-	handle = ext3_journal_start(inode, EXT3_DATA_TRANS_BLOCKS);
+	handle = ext3_journal_start(inode, EXT3_DATA_TRANS_BLOCKS(inode->i_sb));
 	if (IS_ERR(handle))
 		return PTR_ERR(handle);
 	error = ext3_set_acl(handle, inode, type, acl);
@@ -535,14 +536,14 @@ ext3_xattr_set_acl_default(struct inode 
 }
 
 struct xattr_handler ext3_xattr_acl_access_handler = {
-	.prefix	= XATTR_NAME_ACL_ACCESS,
+	.prefix	= POSIX_ACL_XATTR_ACCESS,
 	.list	= ext3_xattr_list_acl_access,
 	.get	= ext3_xattr_get_acl_access,
 	.set	= ext3_xattr_set_acl_access,
 };
 
 struct xattr_handler ext3_xattr_acl_default_handler = {
-	.prefix	= XATTR_NAME_ACL_DEFAULT,
+	.prefix	= POSIX_ACL_XATTR_DEFAULT,
 	.list	= ext3_xattr_list_acl_default,
 	.get	= ext3_xattr_get_acl_default,
 	.set	= ext3_xattr_set_acl_default,
diff --git a/fs/ext3/acl.h b/fs/ext3/acl.h
--- a/fs/ext3/acl.h
+++ b/fs/ext3/acl.h
@@ -4,7 +4,7 @@
   (C) 2001 Andreas Gruenbacher, <a.gruenbacher@computer.org>
 */
 
-#include <linux/xattr_acl.h>
+#include <linux/posix_acl_xattr.h>
 
 #define EXT3_ACL_VERSION	0x0001
 
diff --git a/fs/ext3/balloc.c b/fs/ext3/balloc.c
--- a/fs/ext3/balloc.c
+++ b/fs/ext3/balloc.c
@@ -749,24 +749,24 @@ fail_access:
  * 	to find a free region that is of my size and has not
  * 	been reserved.
  *
- *	on succeed, it returns the reservation window to be appended to.
- *	failed, return NULL.
  */
-static struct ext3_reserve_window_node *find_next_reservable_window(
+static int find_next_reservable_window(
 				struct ext3_reserve_window_node *search_head,
-				unsigned long size, int *start_block,
+				struct ext3_reserve_window_node *my_rsv,
+				struct super_block * sb, int start_block,
 				int last_block)
 {
 	struct rb_node *next;
 	struct ext3_reserve_window_node *rsv, *prev;
 	int cur;
+	int size = my_rsv->rsv_goal_size;
 
 	/* TODO: make the start of the reservation window byte-aligned */
 	/* cur = *start_block & ~7;*/
-	cur = *start_block;
+	cur = start_block;
 	rsv = search_head;
 	if (!rsv)
-		return NULL;
+		return -1;
 
 	while (1) {
 		if (cur <= rsv->rsv_end)
@@ -782,11 +782,11 @@ static struct ext3_reserve_window_node *
 		 * space with expected-size (or more)...
 		 */
 		if (cur > last_block)
-			return NULL;		/* fail */
+			return -1;		/* fail */
 
 		prev = rsv;
 		next = rb_next(&rsv->rsv_node);
-		rsv = list_entry(next, struct ext3_reserve_window_node, rsv_node);
+		rsv = list_entry(next,struct ext3_reserve_window_node,rsv_node);
 
 		/*
 		 * Reached the last reservation, we can just append to the
@@ -813,8 +813,25 @@ static struct ext3_reserve_window_node *
 	 * return the reservation window that we could append to.
 	 * succeed.
 	 */
-	*start_block = cur;
-	return prev;
+
+	if ((prev != my_rsv) && (!rsv_is_empty(&my_rsv->rsv_window)))
+		rsv_window_remove(sb, my_rsv);
+
+	/*
+	 * Let's book the whole avaliable window for now.  We will check the
+	 * disk bitmap later and then, if there are free blocks then we adjust
+	 * the window size if it's larger than requested.
+	 * Otherwise, we will remove this node from the tree next time
+	 * call find_next_reservable_window.
+	 */
+	my_rsv->rsv_start = cur;
+	my_rsv->rsv_end = cur + size - 1;
+	my_rsv->rsv_alloc_hit = 0;
+
+	if (prev != my_rsv)
+		ext3_rsv_window_add(sb, my_rsv);
+
+	return 0;
 }
 
 /**
@@ -852,6 +869,7 @@ static struct ext3_reserve_window_node *
  *	@sb: the super block
  *	@group: the group we are trying to allocate in
  *	@bitmap_bh: the block group block bitmap
+ *
  */
 static int alloc_new_reservation(struct ext3_reserve_window_node *my_rsv,
 		int goal, struct super_block *sb,
@@ -860,10 +878,10 @@ static int alloc_new_reservation(struct 
 	struct ext3_reserve_window_node *search_head;
 	int group_first_block, group_end_block, start_block;
 	int first_free_block;
-	int reservable_space_start;
-	struct ext3_reserve_window_node *prev_rsv;
 	struct rb_root *fs_rsv_root = &EXT3_SB(sb)->s_rsv_window_root;
 	unsigned long size;
+	int ret;
+	spinlock_t *rsv_lock = &EXT3_SB(sb)->s_rsv_window_lock;
 
 	group_first_block = le32_to_cpu(EXT3_SB(sb)->s_es->s_first_data_block) +
 				group * EXT3_BLOCKS_PER_GROUP(sb);
@@ -875,6 +893,7 @@ static int alloc_new_reservation(struct 
 		start_block = goal + group_first_block;
 
 	size = my_rsv->rsv_goal_size;
+
 	if (!rsv_is_empty(&my_rsv->rsv_window)) {
 		/*
 		 * if the old reservation is cross group boundary
@@ -908,6 +927,8 @@ static int alloc_new_reservation(struct 
 			my_rsv->rsv_goal_size= size;
 		}
 	}
+
+	spin_lock(rsv_lock);
 	/*
 	 * shift the search start to the window near the goal block
 	 */
@@ -921,11 +942,16 @@ static int alloc_new_reservation(struct 
 	 * need to check the bitmap after we found a reservable window.
 	 */
 retry:
-	prev_rsv = find_next_reservable_window(search_head, size,
-						&start_block, group_end_block);
-	if (prev_rsv == NULL)
-		goto failed;
-	reservable_space_start = start_block;
+	ret = find_next_reservable_window(search_head, my_rsv, sb,
+						start_block, group_end_block);
+
+	if (ret == -1) {
+		if (!rsv_is_empty(&my_rsv->rsv_window))
+			rsv_window_remove(sb, my_rsv);
+		spin_unlock(rsv_lock);
+		return -1;
+	}
+
 	/*
 	 * On success, find_next_reservable_window() returns the
 	 * reservation window where there is a reservable space after it.
@@ -937,8 +963,9 @@ retry:
 	 * block. Search start from the start block of the reservable space
 	 * we just found.
 	 */
+	spin_unlock(rsv_lock);
 	first_free_block = bitmap_search_next_usable_block(
-			reservable_space_start - group_first_block,
+			my_rsv->rsv_start - group_first_block,
 			bitmap_bh, group_end_block - group_first_block + 1);
 
 	if (first_free_block < 0) {
@@ -946,54 +973,29 @@ retry:
 		 * no free block left on the bitmap, no point
 		 * to reserve the space. return failed.
 		 */
-		goto failed;
+		spin_lock(rsv_lock);
+		if (!rsv_is_empty(&my_rsv->rsv_window))
+			rsv_window_remove(sb, my_rsv);
+		spin_unlock(rsv_lock);
+		return -1;		/* failed */
 	}
+
 	start_block = first_free_block + group_first_block;
 	/*
 	 * check if the first free block is within the
-	 * free space we just found
+	 * free space we just reserved
 	 */
-	if ((start_block >= reservable_space_start) &&
-	  (start_block < reservable_space_start + size))
-		goto found_rsv_window;
+	if (start_block >= my_rsv->rsv_start && start_block < my_rsv->rsv_end)
+		return 0;		/* success */
 	/*
 	 * if the first free bit we found is out of the reservable space
-	 * this means there is no free block on the reservable space
-	 * we should continue search for next reservable space,
+	 * continue search for next reservable space,
 	 * start from where the free block is,
 	 * we also shift the list head to where we stopped last time
 	 */
-	search_head = prev_rsv;
+	search_head = my_rsv;
+	spin_lock(rsv_lock);
 	goto retry;
-
-found_rsv_window:
-	/*
-	 * great! the reservable space contains some free blocks.
-	 * if the search returns that we should add the new
-	 * window just next to where the old window, we don't
- 	 * need to remove the old window first then add it to the
-	 * same place, just update the new start and new end.
-	 */
-	if (my_rsv != prev_rsv)  {
-		if (!rsv_is_empty(&my_rsv->rsv_window))
-			rsv_window_remove(sb, my_rsv);
-	}
-	my_rsv->rsv_start = reservable_space_start;
-	my_rsv->rsv_end = my_rsv->rsv_start + size - 1;
-	my_rsv->rsv_alloc_hit = 0;
-	if (my_rsv != prev_rsv)  {
-		ext3_rsv_window_add(sb, my_rsv);
-	}
-	return 0;		/* succeed */
-failed:
-	/*
-	 * failed to find a new reservation window in the current
-	 * group, remove the current(stale) reservation window
-	 * if there is any
-	 */
-	if (!rsv_is_empty(&my_rsv->rsv_window))
-		rsv_window_remove(sb, my_rsv);
-	return -1;		/* failed */
 }
 
 /*
@@ -1023,7 +1025,6 @@ ext3_try_to_allocate_with_rsv(struct sup
 			int goal, struct ext3_reserve_window_node * my_rsv,
 			int *errp)
 {
-	spinlock_t *rsv_lock;
 	unsigned long group_first_block;
 	int ret = 0;
 	int fatal;
@@ -1052,7 +1053,6 @@ ext3_try_to_allocate_with_rsv(struct sup
 		ret = ext3_try_to_allocate(sb, handle, group, bitmap_bh, goal, NULL);
 		goto out;
 	}
-	rsv_lock = &EXT3_SB(sb)->s_rsv_window_lock;
 	/*
 	 * goal is a group relative block number (if there is a goal)
 	 * 0 < goal < EXT3_BLOCKS_PER_GROUP(sb)
@@ -1078,30 +1078,21 @@ ext3_try_to_allocate_with_rsv(struct sup
 	 * then we could go to allocate from the reservation window directly.
 	 */
 	while (1) {
-		struct ext3_reserve_window rsv_copy;
-
-		rsv_copy._rsv_start = my_rsv->rsv_start;
-		rsv_copy._rsv_end = my_rsv->rsv_end;
-
-		if (rsv_is_empty(&rsv_copy) || (ret < 0) ||
-			!goal_in_my_reservation(&rsv_copy, goal, group, sb)) {
-			spin_lock(rsv_lock);
+		if (rsv_is_empty(&my_rsv->rsv_window) || (ret < 0) ||
+			!goal_in_my_reservation(&my_rsv->rsv_window, goal, group, sb)) {
 			ret = alloc_new_reservation(my_rsv, goal, sb,
 							group, bitmap_bh);
-			rsv_copy._rsv_start = my_rsv->rsv_start;
-			rsv_copy._rsv_end = my_rsv->rsv_end;
-			spin_unlock(rsv_lock);
 			if (ret < 0)
 				break;			/* failed */
 
-			if (!goal_in_my_reservation(&rsv_copy, goal, group, sb))
+			if (!goal_in_my_reservation(&my_rsv->rsv_window, goal, group, sb))
 				goal = -1;
 		}
-		if ((rsv_copy._rsv_start >= group_first_block + EXT3_BLOCKS_PER_GROUP(sb))
-		    || (rsv_copy._rsv_end < group_first_block))
+		if ((my_rsv->rsv_start >= group_first_block + EXT3_BLOCKS_PER_GROUP(sb))
+		    || (my_rsv->rsv_end < group_first_block))
 			BUG();
 		ret = ext3_try_to_allocate(sb, handle, group, bitmap_bh, goal,
-					   &rsv_copy);
+					   &my_rsv->rsv_window);
 		if (ret >= 0) {
 			my_rsv->rsv_alloc_hit++;
 			break;				/* succeed */
diff --git a/fs/ext3/file.c b/fs/ext3/file.c
--- a/fs/ext3/file.c
+++ b/fs/ext3/file.c
@@ -36,7 +36,11 @@ static int ext3_release_file (struct ino
 	/* if we are the last writer on the inode, drop the block reservation */
 	if ((filp->f_mode & FMODE_WRITE) &&
 			(atomic_read(&inode->i_writecount) == 1))
+	{
+		down(&EXT3_I(inode)->truncate_sem);
 		ext3_discard_reservation(inode);
+		up(&EXT3_I(inode)->truncate_sem);
+	}
 	if (is_dx(inode) && filp->private_data)
 		ext3_htree_free_dir_info(filp->private_data);
 
diff --git a/fs/ext3/ialloc.c b/fs/ext3/ialloc.c
--- a/fs/ext3/ialloc.c
+++ b/fs/ext3/ialloc.c
@@ -604,12 +604,14 @@ got:
 	err = ext3_init_acl(handle, inode, dir);
 	if (err) {
 		DQUOT_FREE_INODE(inode);
+		DQUOT_DROP(inode);
 		goto fail2;
   	}
 	err = ext3_mark_inode_dirty(handle, inode);
 	if (err) {
 		ext3_std_error(sb, err);
 		DQUOT_FREE_INODE(inode);
+		DQUOT_DROP(inode);
 		goto fail2;
 	}
 
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c
--- a/fs/ext3/inode.c
+++ b/fs/ext3/inode.c
@@ -128,7 +128,7 @@ static unsigned long blocks_for_truncate
 	if (needed > EXT3_MAX_TRANS_DATA) 
 		needed = EXT3_MAX_TRANS_DATA;
 
-	return EXT3_DATA_TRANS_BLOCKS + needed;
+	return EXT3_DATA_TRANS_BLOCKS(inode->i_sb) + needed;
 }
 
 /* 
@@ -2663,7 +2663,7 @@ static int ext3_do_update_inode(handle_t
 	} else for (block = 0; block < EXT3_N_BLOCKS; block++)
 		raw_inode->i_block[block] = ei->i_data[block];
 
-	if (EXT3_INODE_SIZE(inode->i_sb) > EXT3_GOOD_OLD_INODE_SIZE)
+	if (ei->i_extra_isize)
 		raw_inode->i_extra_isize = cpu_to_le16(ei->i_extra_isize);
 
 	BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata");
@@ -2763,7 +2763,8 @@ int ext3_setattr(struct dentry *dentry, 
 
 		/* (user+group)*(old+new) structure, inode write (sb,
 		 * inode block, ? - but truncate inode update has it) */
-		handle = ext3_journal_start(inode, 4*EXT3_QUOTA_INIT_BLOCKS+3);
+		handle = ext3_journal_start(inode, 2*(EXT3_QUOTA_INIT_BLOCKS(inode->i_sb)+
+					EXT3_QUOTA_DEL_BLOCKS(inode->i_sb))+3);
 		if (IS_ERR(handle)) {
 			error = PTR_ERR(handle);
 			goto err_out;
@@ -2861,7 +2862,7 @@ static int ext3_writepage_trans_blocks(s
 #ifdef CONFIG_QUOTA
 	/* We know that structure was already allocated during DQUOT_INIT so
 	 * we will be updating only the data blocks + inodes */
-	ret += 2*EXT3_QUOTA_TRANS_BLOCKS;
+	ret += 2*EXT3_QUOTA_TRANS_BLOCKS(inode->i_sb);
 #endif
 
 	return ret;
diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c
--- a/fs/ext3/namei.c
+++ b/fs/ext3/namei.c
@@ -932,8 +932,16 @@ static struct buffer_head * ext3_dx_find
 	struct inode *dir = dentry->d_parent->d_inode;
 
 	sb = dir->i_sb;
-	if (!(frame = dx_probe(dentry, NULL, &hinfo, frames, err)))
-		return NULL;
+	/* NFS may look up ".." - look at dx_root directory block */
+	if (namelen > 2 || name[0] != '.'||(name[1] != '.' && name[1] != '\0')){
+		if (!(frame = dx_probe(dentry, NULL, &hinfo, frames, err)))
+			return NULL;
+	} else {
+		frame = frames;
+		frame->bh = NULL;			/* for dx_release() */
+		frame->at = (struct dx_entry *)frames;	/* hack for zero entry*/
+		dx_set_block(frame->at, 0);		/* dx_root block is 0 */
+	}
 	hash = hinfo.hash;
 	do {
 		block = dx_get_block(frame->at);
@@ -1637,9 +1645,9 @@ static int ext3_create (struct inode * d
 	int err, retries = 0;
 
 retry:
-	handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
+	handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS(dir->i_sb) +
 					EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3 +
-					2*EXT3_QUOTA_INIT_BLOCKS);
+					2*EXT3_QUOTA_INIT_BLOCKS(dir->i_sb));
 	if (IS_ERR(handle))
 		return PTR_ERR(handle);
 
@@ -1671,9 +1679,9 @@ static int ext3_mknod (struct inode * di
 		return -EINVAL;
 
 retry:
-	handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
+	handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS(dir->i_sb) +
 			 		EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3 +
-					2*EXT3_QUOTA_INIT_BLOCKS);
+					2*EXT3_QUOTA_INIT_BLOCKS(dir->i_sb));
 	if (IS_ERR(handle))
 		return PTR_ERR(handle);
 
@@ -1707,9 +1715,9 @@ static int ext3_mkdir(struct inode * dir
 		return -EMLINK;
 
 retry:
-	handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
+	handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS(dir->i_sb) +
 					EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3 +
-					2*EXT3_QUOTA_INIT_BLOCKS);
+					2*EXT3_QUOTA_INIT_BLOCKS(dir->i_sb));
 	if (IS_ERR(handle))
 		return PTR_ERR(handle);
 
@@ -1998,7 +2006,7 @@ static int ext3_rmdir (struct inode * di
 	/* Initialize quotas before so that eventual writes go in
 	 * separate transaction */
 	DQUOT_INIT(dentry->d_inode);
-	handle = ext3_journal_start(dir, EXT3_DELETE_TRANS_BLOCKS);
+	handle = ext3_journal_start(dir, EXT3_DELETE_TRANS_BLOCKS(dir->i_sb));
 	if (IS_ERR(handle))
 		return PTR_ERR(handle);
 
@@ -2057,7 +2065,7 @@ static int ext3_unlink(struct inode * di
 	/* Initialize quotas before so that eventual writes go
 	 * in separate transaction */
 	DQUOT_INIT(dentry->d_inode);
-	handle = ext3_journal_start(dir, EXT3_DELETE_TRANS_BLOCKS);
+	handle = ext3_journal_start(dir, EXT3_DELETE_TRANS_BLOCKS(dir->i_sb));
 	if (IS_ERR(handle))
 		return PTR_ERR(handle);
 
@@ -2112,9 +2120,9 @@ static int ext3_symlink (struct inode * 
 		return -ENAMETOOLONG;
 
 retry:
-	handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
+	handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS(dir->i_sb) +
 			 		EXT3_INDEX_EXTRA_TRANS_BLOCKS + 5 +
-					2*EXT3_QUOTA_INIT_BLOCKS);
+					2*EXT3_QUOTA_INIT_BLOCKS(dir->i_sb));
 	if (IS_ERR(handle))
 		return PTR_ERR(handle);
 
@@ -2166,7 +2174,7 @@ static int ext3_link (struct dentry * ol
 		return -EMLINK;
 
 retry:
-	handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
+	handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS(dir->i_sb) +
 					EXT3_INDEX_EXTRA_TRANS_BLOCKS);
 	if (IS_ERR(handle))
 		return PTR_ERR(handle);
@@ -2208,7 +2216,8 @@ static int ext3_rename (struct inode * o
 	 * in separate transaction */
 	if (new_dentry->d_inode)
 		DQUOT_INIT(new_dentry->d_inode);
-	handle = ext3_journal_start(old_dir, 2 * EXT3_DATA_TRANS_BLOCKS +
+	handle = ext3_journal_start(old_dir, 2 *
+					EXT3_DATA_TRANS_BLOCKS(old_dir->i_sb) +
 			 		EXT3_INDEX_EXTRA_TRANS_BLOCKS + 2);
 	if (IS_ERR(handle))
 		return PTR_ERR(handle);
diff --git a/fs/ext3/super.c b/fs/ext3/super.c
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -589,7 +589,7 @@ enum {
 	Opt_commit, Opt_journal_update, Opt_journal_inum,
 	Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback,
 	Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota,
-	Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0,
+	Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota,
 	Opt_ignore, Opt_barrier, Opt_err, Opt_resize,
 };
 
@@ -634,10 +634,10 @@ static match_table_t tokens = {
 	{Opt_grpjquota, "grpjquota=%s"},
 	{Opt_jqfmt_vfsold, "jqfmt=vfsold"},
 	{Opt_jqfmt_vfsv0, "jqfmt=vfsv0"},
-	{Opt_ignore, "grpquota"},
-	{Opt_ignore, "noquota"},
-	{Opt_ignore, "quota"},
-	{Opt_ignore, "usrquota"},
+	{Opt_quota, "grpquota"},
+	{Opt_noquota, "noquota"},
+	{Opt_quota, "quota"},
+	{Opt_quota, "usrquota"},
 	{Opt_barrier, "barrier=%u"},
 	{Opt_err, NULL},
 	{Opt_resize, "resize"},
@@ -876,6 +876,7 @@ set_qf_name:
 				sbi->s_qf_names[qtype] = NULL;
 				return 0;
 			}
+			set_opt(sbi->s_mount_opt, QUOTA);
 			break;
 		case Opt_offusrjquota:
 			qtype = USRQUOTA;
@@ -889,7 +890,10 @@ clear_qf_name:
 					"quota turned on.\n");
 				return 0;
 			}
-			kfree(sbi->s_qf_names[qtype]);
+			/*
+			 * The space will be released later when all options
+			 * are confirmed to be correct
+			 */
 			sbi->s_qf_names[qtype] = NULL;
 			break;
 		case Opt_jqfmt_vfsold:
@@ -898,6 +902,17 @@ clear_qf_name:
 		case Opt_jqfmt_vfsv0:
 			sbi->s_jquota_fmt = QFMT_VFS_V0;
 			break;
+		case Opt_quota:
+			set_opt(sbi->s_mount_opt, QUOTA);
+			break;
+		case Opt_noquota:
+			if (sb_any_quota_enabled(sb)) {
+				printk(KERN_ERR "EXT3-fs: Cannot change quota "
+					"options when quota turned on.\n");
+				return 0;
+			}
+			clear_opt(sbi->s_mount_opt, QUOTA);
+			break;
 #else
 		case Opt_usrjquota:
 		case Opt_grpjquota:
@@ -909,6 +924,9 @@ clear_qf_name:
 				"EXT3-fs: journalled quota options not "
 				"supported.\n");
 			break;
+		case Opt_quota:
+		case Opt_noquota:
+			break;
 #endif
 		case Opt_abort:
 			set_opt(sbi->s_mount_opt, ABORT);
@@ -924,12 +942,13 @@ clear_qf_name:
 		case Opt_ignore:
 			break;
 		case Opt_resize:
-			if (!n_blocks_count) {
+			if (!is_remount) {
 				printk("EXT3-fs: resize option only available "
 					"for remount\n");
 				return 0;
 			}
-			match_int(&args[0], &option);
+			if (match_int(&args[0], &option) != 0)
+				return 0;
 			*n_blocks_count = option;
 			break;
 		case Opt_nobh:
@@ -2093,14 +2112,33 @@ static int ext3_remount (struct super_bl
 {
 	struct ext3_super_block * es;
 	struct ext3_sb_info *sbi = EXT3_SB(sb);
-	unsigned long tmp;
 	unsigned long n_blocks_count = 0;
+	unsigned long old_sb_flags;
+	struct ext3_mount_options old_opts;
+	int err;
+#ifdef CONFIG_QUOTA
+	int i;
+#endif
+
+	/* Store the original options */
+	old_sb_flags = sb->s_flags;
+	old_opts.s_mount_opt = sbi->s_mount_opt;
+	old_opts.s_resuid = sbi->s_resuid;
+	old_opts.s_resgid = sbi->s_resgid;
+	old_opts.s_commit_interval = sbi->s_commit_interval;
+#ifdef CONFIG_QUOTA
+	old_opts.s_jquota_fmt = sbi->s_jquota_fmt;
+	for (i = 0; i < MAXQUOTAS; i++)
+		old_opts.s_qf_names[i] = sbi->s_qf_names[i];
+#endif
 
 	/*
 	 * Allow the "check" option to be passed as a remount option.
 	 */
-	if (!parse_options(data, sb, &tmp, &n_blocks_count, 1))
-		return -EINVAL;
+	if (!parse_options(data, sb, NULL, &n_blocks_count, 1)) {
+		err = -EINVAL;
+		goto restore_opts;
+	}
 
 	if (sbi->s_mount_opt & EXT3_MOUNT_ABORT)
 		ext3_abort(sb, __FUNCTION__, "Abort forced by user");
@@ -2114,8 +2152,10 @@ static int ext3_remount (struct super_bl
 
 	if ((*flags & MS_RDONLY) != (sb->s_flags & MS_RDONLY) ||
 		n_blocks_count > le32_to_cpu(es->s_blocks_count)) {
-		if (sbi->s_mount_opt & EXT3_MOUNT_ABORT)
-			return -EROFS;
+		if (sbi->s_mount_opt & EXT3_MOUNT_ABORT) {
+			err = -EROFS;
+			goto restore_opts;
+		}
 
 		if (*flags & MS_RDONLY) {
 			/*
@@ -2142,7 +2182,8 @@ static int ext3_remount (struct super_bl
 				       "remount RDWR because of unsupported "
 				       "optional features (%x).\n",
 				       sb->s_id, le32_to_cpu(ret));
-				return -EROFS;
+				err = -EROFS;
+				goto restore_opts;
 			}
 			/*
 			 * Mounting a RDONLY partition read-write, so reread
@@ -2152,13 +2193,38 @@ static int ext3_remount (struct super_bl
 			 */
 			ext3_clear_journal_err(sb, es);
 			sbi->s_mount_state = le16_to_cpu(es->s_state);
-			if ((ret = ext3_group_extend(sb, es, n_blocks_count)))
-				return ret;
+			if ((ret = ext3_group_extend(sb, es, n_blocks_count))) {
+				err = ret;
+				goto restore_opts;
+			}
 			if (!ext3_setup_super (sb, es, 0))
 				sb->s_flags &= ~MS_RDONLY;
 		}
 	}
+#ifdef CONFIG_QUOTA
+	/* Release old quota file names */
+	for (i = 0; i < MAXQUOTAS; i++)
+		if (old_opts.s_qf_names[i] &&
+		    old_opts.s_qf_names[i] != sbi->s_qf_names[i])
+			kfree(old_opts.s_qf_names[i]);
+#endif
 	return 0;
+restore_opts:
+	sb->s_flags = old_sb_flags;
+	sbi->s_mount_opt = old_opts.s_mount_opt;
+	sbi->s_resuid = old_opts.s_resuid;
+	sbi->s_resgid = old_opts.s_resgid;
+	sbi->s_commit_interval = old_opts.s_commit_interval;
+#ifdef CONFIG_QUOTA
+	sbi->s_jquota_fmt = old_opts.s_jquota_fmt;
+	for (i = 0; i < MAXQUOTAS; i++) {
+		if (sbi->s_qf_names[i] &&
+		    old_opts.s_qf_names[i] != sbi->s_qf_names[i])
+			kfree(sbi->s_qf_names[i]);
+		sbi->s_qf_names[i] = old_opts.s_qf_names[i];
+	}
+#endif
+	return err;
 }
 
 static int ext3_statfs (struct super_block * sb, struct kstatfs * buf)
@@ -2238,7 +2304,7 @@ static int ext3_dquot_initialize(struct 
 	int ret, err;
 
 	/* We may create quota structure so we need to reserve enough blocks */
-	handle = ext3_journal_start(inode, 2*EXT3_QUOTA_INIT_BLOCKS);
+	handle = ext3_journal_start(inode, 2*EXT3_QUOTA_INIT_BLOCKS(inode->i_sb));
 	if (IS_ERR(handle))
 		return PTR_ERR(handle);
 	ret = dquot_initialize(inode, type);
@@ -2254,7 +2320,7 @@ static int ext3_dquot_drop(struct inode 
 	int ret, err;
 
 	/* We may delete quota structure so we need to reserve enough blocks */
-	handle = ext3_journal_start(inode, 2*EXT3_QUOTA_INIT_BLOCKS);
+	handle = ext3_journal_start(inode, 2*EXT3_QUOTA_DEL_BLOCKS(inode->i_sb));
 	if (IS_ERR(handle))
 		return PTR_ERR(handle);
 	ret = dquot_drop(inode);
@@ -2272,7 +2338,7 @@ static int ext3_write_dquot(struct dquot
 
 	inode = dquot_to_inode(dquot);
 	handle = ext3_journal_start(inode,
-					EXT3_QUOTA_TRANS_BLOCKS);
+					EXT3_QUOTA_TRANS_BLOCKS(dquot->dq_sb));
 	if (IS_ERR(handle))
 		return PTR_ERR(handle);
 	ret = dquot_commit(dquot);
@@ -2288,7 +2354,7 @@ static int ext3_acquire_dquot(struct dqu
 	handle_t *handle;
 
 	handle = ext3_journal_start(dquot_to_inode(dquot),
-					EXT3_QUOTA_INIT_BLOCKS);
+					EXT3_QUOTA_INIT_BLOCKS(dquot->dq_sb));
 	if (IS_ERR(handle))
 		return PTR_ERR(handle);
 	ret = dquot_acquire(dquot);
@@ -2304,7 +2370,7 @@ static int ext3_release_dquot(struct dqu
 	handle_t *handle;
 
 	handle = ext3_journal_start(dquot_to_inode(dquot),
-					EXT3_QUOTA_INIT_BLOCKS);
+					EXT3_QUOTA_DEL_BLOCKS(dquot->dq_sb));
 	if (IS_ERR(handle))
 		return PTR_ERR(handle);
 	ret = dquot_release(dquot);
@@ -2348,22 +2414,8 @@ static int ext3_write_info(struct super_
  */
 static int ext3_quota_on_mount(struct super_block *sb, int type)
 {
-	int err;
-	struct dentry *dentry;
-	struct qstr name = { .name = EXT3_SB(sb)->s_qf_names[type],
-			     .hash = 0,
-			     .len = strlen(EXT3_SB(sb)->s_qf_names[type])};
-
-	dentry = lookup_hash(&name, sb->s_root);
-	if (IS_ERR(dentry))
-		return PTR_ERR(dentry);
-	err = vfs_quota_on_mount(type, EXT3_SB(sb)->s_jquota_fmt, dentry);
-	/* Now invalidate and put the dentry - quota got its own reference
-	 * to inode and dentry has at least wrong hash so we had better
-	 * throw it away */
-	d_invalidate(dentry);
-	dput(dentry);
-	return err;
+	return vfs_quota_on_mount(sb, EXT3_SB(sb)->s_qf_names[type],
+			EXT3_SB(sb)->s_jquota_fmt, type);
 }
 
 /*
@@ -2375,6 +2427,8 @@ static int ext3_quota_on(struct super_bl
 	int err;
 	struct nameidata nd;
 
+	if (!test_opt(sb, QUOTA))
+		return -EINVAL;
 	/* Not journalling quota? */
 	if (!EXT3_SB(sb)->s_qf_names[USRQUOTA] &&
 	    !EXT3_SB(sb)->s_qf_names[GRPQUOTA])
diff --git a/fs/ext3/symlink.c b/fs/ext3/symlink.c
--- a/fs/ext3/symlink.c
+++ b/fs/ext3/symlink.c
@@ -23,11 +23,11 @@
 #include <linux/namei.h>
 #include "xattr.h"
 
-static int ext3_follow_link(struct dentry *dentry, struct nameidata *nd)
+static void * ext3_follow_link(struct dentry *dentry, struct nameidata *nd)
 {
 	struct ext3_inode_info *ei = EXT3_I(dentry->d_inode);
 	nd_set_link(nd, (char*)ei->i_data);
-	return 0;
+	return NULL;
 }
 
 struct inode_operations ext3_symlink_inode_operations = {
diff --git a/fs/ext3/xattr.c b/fs/ext3/xattr.c
--- a/fs/ext3/xattr.c
+++ b/fs/ext3/xattr.c
@@ -1044,7 +1044,7 @@ ext3_xattr_set(struct inode *inode, int 
 	int error, retries = 0;
 
 retry:
-	handle = ext3_journal_start(inode, EXT3_DATA_TRANS_BLOCKS);
+	handle = ext3_journal_start(inode, EXT3_DATA_TRANS_BLOCKS(inode->i_sb));
 	if (IS_ERR(handle)) {
 		error = PTR_ERR(handle);
 	} else {
@@ -1106,7 +1106,7 @@ cleanup:
 void
 ext3_xattr_put_super(struct super_block *sb)
 {
-	mb_cache_shrink(ext3_xattr_cache, sb->s_bdev);
+	mb_cache_shrink(sb->s_bdev);
 }
 
 /*
diff --git a/fs/fat/cache.c b/fs/fat/cache.c
--- a/fs/fat/cache.c
+++ b/fs/fat/cache.c
@@ -56,7 +56,7 @@ int __init fat_cache_init(void)
 	return 0;
 }
 
-void __exit fat_cache_destroy(void)
+void fat_cache_destroy(void)
 {
 	if (kmem_cache_destroy(fat_cache_cachep))
 		printk(KERN_INFO "fat_cache: not all structures were freed\n");
diff --git a/fs/fat/inode.c b/fs/fat/inode.c
--- a/fs/fat/inode.c
+++ b/fs/fat/inode.c
@@ -1327,16 +1327,25 @@ out_fail:
 EXPORT_SYMBOL(fat_fill_super);
 
 int __init fat_cache_init(void);
-void __exit fat_cache_destroy(void);
+void fat_cache_destroy(void);
 
 static int __init init_fat_fs(void)
 {
-	int ret;
+	int err;
 
-	ret = fat_cache_init();
-	if (ret < 0)
-		return ret;
-	return fat_init_inodecache();
+	err = fat_cache_init();
+	if (err)
+		return err;
+
+	err = fat_init_inodecache();
+	if (err)
+		goto failed;
+
+	return 0;
+
+failed:
+	fat_cache_destroy();
+	return err;
 }
 
 static void __exit exit_fat_fs(void)
diff --git a/fs/fcntl.c b/fs/fcntl.c
--- a/fs/fcntl.c
+++ b/fs/fcntl.c
@@ -288,7 +288,7 @@ static long do_fcntl(int fd, unsigned in
 		break;
 	case F_SETLK:
 	case F_SETLKW:
-		err = fcntl_setlk(filp, cmd, (struct flock __user *) arg);
+		err = fcntl_setlk(fd, filp, cmd, (struct flock __user *) arg);
 		break;
 	case F_GETOWN:
 		/*
@@ -376,7 +376,8 @@ asmlinkage long sys_fcntl64(unsigned int
 			break;
 		case F_SETLK64:
 		case F_SETLKW64:
-			err = fcntl_setlk64(filp, cmd, (struct flock64 __user *) arg);
+			err = fcntl_setlk64(fd, filp, cmd,
+					(struct flock64 __user *) arg);
 			break;
 		default:
 			err = do_fcntl(fd, cmd, arg, filp);
diff --git a/fs/file_table.c b/fs/file_table.c
--- a/fs/file_table.c
+++ b/fs/file_table.c
@@ -16,6 +16,7 @@
 #include <linux/eventpoll.h>
 #include <linux/mount.h>
 #include <linux/cdev.h>
+#include <linux/fsnotify.h>
 
 /* sysctl tunables... */
 struct files_stat_struct files_stat = {
@@ -63,42 +64,45 @@ static inline void file_free(struct file
  */
 struct file *get_empty_filp(void)
 {
-static int old_max;
+	static int old_max;
 	struct file * f;
 
 	/*
 	 * Privileged users can go above max_files
 	 */
-	if (files_stat.nr_files < files_stat.max_files ||
-				capable(CAP_SYS_ADMIN)) {
-		f = kmem_cache_alloc(filp_cachep, GFP_KERNEL);
-		if (f) {
-			memset(f, 0, sizeof(*f));
-			if (security_file_alloc(f)) {
-				file_free(f);
-				goto fail;
-			}
-			eventpoll_init_file(f);
-			atomic_set(&f->f_count, 1);
-			f->f_uid = current->fsuid;
-			f->f_gid = current->fsgid;
-			rwlock_init(&f->f_owner.lock);
-			/* f->f_version: 0 */
-			INIT_LIST_HEAD(&f->f_list);
-			f->f_maxcount = INT_MAX;
-			return f;
-		}
-	}
+	if (files_stat.nr_files >= files_stat.max_files &&
+				!capable(CAP_SYS_ADMIN))
+		goto over;
+
+	f = kmem_cache_alloc(filp_cachep, GFP_KERNEL);
+	if (f == NULL)
+		goto fail;
+
+	memset(f, 0, sizeof(*f));
+	if (security_file_alloc(f))
+		goto fail_sec;
+
+	eventpoll_init_file(f);
+	atomic_set(&f->f_count, 1);
+	f->f_uid = current->fsuid;
+	f->f_gid = current->fsgid;
+	rwlock_init(&f->f_owner.lock);
+	/* f->f_version: 0 */
+	INIT_LIST_HEAD(&f->f_list);
+	f->f_maxcount = INT_MAX;
+	return f;
 
+over:
 	/* Ran out of filps - report that */
-	if (files_stat.max_files >= old_max) {
+	if (files_stat.nr_files > old_max) {
 		printk(KERN_INFO "VFS: file-max limit %d reached\n",
 					files_stat.max_files);
-		old_max = files_stat.max_files;
-	} else {
-		/* Big problems... */
-		printk(KERN_WARNING "VFS: filp allocation failed\n");
+		old_max = files_stat.nr_files;
 	}
+	goto fail;
+
+fail_sec:
+	file_free(f);
 fail:
 	return NULL;
 }
@@ -123,6 +127,8 @@ void fastcall __fput(struct file *file)
 	struct inode *inode = dentry->d_inode;
 
 	might_sleep();
+
+	fsnotify_close(file);
 	/*
 	 * The function eventpoll_release() should be the first called
 	 * in the file cleanup chain.
diff --git a/fs/freevxfs/vxfs.h b/fs/freevxfs/vxfs.h
--- a/fs/freevxfs/vxfs.h
+++ b/fs/freevxfs/vxfs.h
@@ -37,7 +37,6 @@
  * superblocks of the Veritas Filesystem.
  */
 #include <linux/types.h>
-#include "vxfs_kcompat.h"
 
 
 /*
diff --git a/fs/freevxfs/vxfs_bmap.c b/fs/freevxfs/vxfs_bmap.c
--- a/fs/freevxfs/vxfs_bmap.c
+++ b/fs/freevxfs/vxfs_bmap.c
@@ -101,7 +101,7 @@ vxfs_bmap_ext4(struct inode *ip, long bn
 	return 0;
 
 fail_size:
-	printk("vxfs: indirect extent to big!\n");
+	printk("vxfs: indirect extent too big!\n");
 fail_buf:
 	return 0;
 }
diff --git a/fs/freevxfs/vxfs_fshead.c b/fs/freevxfs/vxfs_fshead.c
--- a/fs/freevxfs/vxfs_fshead.c
+++ b/fs/freevxfs/vxfs_fshead.c
@@ -78,17 +78,18 @@ vxfs_getfsh(struct inode *ip, int which)
 	struct buffer_head		*bp;
 
 	bp = vxfs_bread(ip, which);
-	if (buffer_mapped(bp)) {
+	if (bp) {
 		struct vxfs_fsh		*fhp;
 
-		if (!(fhp = kmalloc(sizeof(*fhp), SLAB_KERNEL)))
-			return NULL;
+		if (!(fhp = kmalloc(sizeof(*fhp), GFP_KERNEL)))
+			goto out;
 		memcpy(fhp, bp->b_data, sizeof(*fhp));
 
-		brelse(bp);
+		put_bh(bp);
 		return (fhp);
 	}
-
+out:
+	brelse(bp);
 	return NULL;
 }
 
diff --git a/fs/freevxfs/vxfs_immed.c b/fs/freevxfs/vxfs_immed.c
--- a/fs/freevxfs/vxfs_immed.c
+++ b/fs/freevxfs/vxfs_immed.c
@@ -38,7 +38,7 @@
 #include "vxfs_inode.h"
 
 
-static int	vxfs_immed_follow_link(struct dentry *, struct nameidata *);
+static void *	vxfs_immed_follow_link(struct dentry *, struct nameidata *);
 
 static int	vxfs_immed_readpage(struct file *, struct page *);
 
@@ -72,12 +72,12 @@ struct address_space_operations vxfs_imm
  * Returns:
  *   Zero on success, else a negative error code.
  */
-static int
+static void *
 vxfs_immed_follow_link(struct dentry *dp, struct nameidata *np)
 {
 	struct vxfs_inode_info		*vip = VXFS_INO(dp->d_inode);
 	nd_set_link(np, vip->vii_immed.vi_immed);
-	return 0;
+	return NULL;
 }
 
 /**
diff --git a/fs/freevxfs/vxfs_kcompat.h b/fs/freevxfs/vxfs_kcompat.h
deleted file mode 100644
--- a/fs/freevxfs/vxfs_kcompat.h
+++ /dev/null
@@ -1,49 +0,0 @@
-#ifndef _VXFS_KCOMPAT_H
-#define _VXFS_KCOMPAT_H
-
-#include <linux/version.h>
-
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
-
-#include <linux/blkdev.h>
-
-typedef long sector_t;
-
-/* From include/linux/fs.h (Linux 2.5.2-pre3)  */
-static inline struct buffer_head * sb_bread(struct super_block *sb, int block)
-{
-	return bread(sb->s_dev, block, sb->s_blocksize);
-}
-
-/* Dito.  */
-static inline void map_bh(struct buffer_head *bh, struct super_block *sb, int block)
-{
-	bh->b_state |= 1 << BH_Mapped;
-	bh->b_dev = sb->s_dev;
-	bh->b_blocknr = block;
-}
-
-/* From fs/block_dev.c (Linux 2.5.2-pre2)  */
-static inline int sb_set_blocksize(struct super_block *sb, int size)
-{
-	int bits;
-	if (set_blocksize(sb->s_dev, size) < 0)
-		return 0;
-	sb->s_blocksize = size;
-	for (bits = 9, size >>= 9; size >>= 1; bits++)
-		;
-	sb->s_blocksize_bits = bits;
-	return sb->s_blocksize;
-}
-
-/* Dito.  */
-static inline int sb_min_blocksize(struct super_block *sb, int size)
-{
-	int minsize = get_hardsect_size(sb->s_dev);
-	if (size < minsize)
-		size = minsize;
-	return sb_set_blocksize(sb, size);
-}
-
-#endif /* Kernel 2.4 */
-#endif /* _VXFS_KCOMPAT_H */
diff --git a/fs/freevxfs/vxfs_lookup.c b/fs/freevxfs/vxfs_lookup.c
--- a/fs/freevxfs/vxfs_lookup.c
+++ b/fs/freevxfs/vxfs_lookup.c
@@ -61,13 +61,13 @@ struct file_operations vxfs_dir_operatio
 };
 
  
-static __inline__ u_long
+static inline u_long
 dir_pages(struct inode *inode)
 {
 	return (inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
 }
  
-static __inline__ u_long
+static inline u_long
 dir_blocks(struct inode *ip)
 {
 	u_long			bsize = ip->i_sb->s_blocksize;
@@ -79,7 +79,7 @@ dir_blocks(struct inode *ip)
  *
  * len <= VXFS_NAMELEN and de != NULL are guaranteed by caller.
  */
-static __inline__ int
+static inline int
 vxfs_match(int len, const char * const name, struct vxfs_direct *de)
 {
 	if (len != de->d_namelen)
@@ -89,7 +89,7 @@ vxfs_match(int len, const char * const n
 	return !memcmp(name, de->d_name, len);
 }
 
-static __inline__ struct vxfs_direct *
+static inline struct vxfs_direct *
 vxfs_next_entry(struct vxfs_direct *de)
 {
 	return ((struct vxfs_direct *)((char*)de + de->d_reclen));
diff --git a/fs/freevxfs/vxfs_olt.c b/fs/freevxfs/vxfs_olt.c
--- a/fs/freevxfs/vxfs_olt.c
+++ b/fs/freevxfs/vxfs_olt.c
@@ -38,7 +38,7 @@
 #include "vxfs_olt.h"
 
 
-static __inline__ void
+static inline void
 vxfs_get_fshead(struct vxfs_oltfshead *fshp, struct vxfs_sb_info *infp)
 {
 	if (infp->vsi_fshino)
@@ -46,7 +46,7 @@ vxfs_get_fshead(struct vxfs_oltfshead *f
 	infp->vsi_fshino = fshp->olt_fsino[0];
 }
 
-static __inline__ void
+static inline void
 vxfs_get_ilist(struct vxfs_oltilist *ilistp, struct vxfs_sb_info *infp)
 {
 	if (infp->vsi_iext)
@@ -54,7 +54,7 @@ vxfs_get_ilist(struct vxfs_oltilist *ili
 	infp->vsi_iext = ilistp->olt_iext[0]; 
 }
 
-static __inline__ u_long
+static inline u_long
 vxfs_oblock(struct super_block *sbp, daddr_t block, u_long bsize)
 {
 	if (sbp->s_blocksize % bsize)
@@ -104,8 +104,8 @@ vxfs_read_olt(struct super_block *sbp, u
 		goto fail;
 	}
 
-	oaddr = (char *)bp->b_data + op->olt_size;
-	eaddr = (char *)bp->b_data + (infp->vsi_oltsize * sbp->s_blocksize);
+	oaddr = bp->b_data + op->olt_size;
+	eaddr = bp->b_data + (infp->vsi_oltsize * sbp->s_blocksize);
 
 	while (oaddr < eaddr) {
 		struct vxfs_oltcommon	*ocp =
diff --git a/fs/freevxfs/vxfs_subr.c b/fs/freevxfs/vxfs_subr.c
--- a/fs/freevxfs/vxfs_subr.c
+++ b/fs/freevxfs/vxfs_subr.c
@@ -36,7 +36,6 @@
 #include <linux/slab.h>
 #include <linux/pagemap.h>
 
-#include "vxfs_kcompat.h"
 #include "vxfs_extern.h"
 
 
diff --git a/fs/freevxfs/vxfs_super.c b/fs/freevxfs/vxfs_super.c
--- a/fs/freevxfs/vxfs_super.c
+++ b/fs/freevxfs/vxfs_super.c
@@ -155,12 +155,11 @@ static int vxfs_fill_super(struct super_
 
 	sbp->s_flags |= MS_RDONLY;
 
-	infp = kmalloc(sizeof(*infp), GFP_KERNEL);
+	infp = kcalloc(1, sizeof(*infp), GFP_KERNEL);
 	if (!infp) {
 		printk(KERN_WARNING "vxfs: unable to allocate incore superblock\n");
 		return -ENOMEM;
 	}
-	memset(infp, 0, sizeof(*infp));
 
 	bsize = sb_min_blocksize(sbp, BLOCK_SIZE);
 	if (!bsize) {
@@ -196,7 +195,7 @@ static int vxfs_fill_super(struct super_
 #endif
 
 	sbp->s_magic = rsbp->vs_magic;
-	sbp->s_fs_info = (void *)infp;
+	sbp->s_fs_info = infp;
 
 	infp->vsi_raw = rsbp;
 	infp->vsi_bp = bp;
@@ -263,7 +262,7 @@ vxfs_init(void)
 			sizeof(struct vxfs_inode_info), 0, 
 			SLAB_RECLAIM_ACCOUNT, NULL, NULL);
 	if (vxfs_inode_cachep)
-		return (register_filesystem(&vxfs_fs_type));
+		return register_filesystem(&vxfs_fs_type);
 	return -ENOMEM;
 }
 
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -485,32 +485,6 @@ static void set_sb_syncing(int val)
 	spin_unlock(&sb_lock);
 }
 
-/*
- * Find a superblock with inodes that need to be synced
- */
-static struct super_block *get_super_to_sync(void)
-{
-	struct super_block *sb;
-restart:
-	spin_lock(&sb_lock);
-	sb = sb_entry(super_blocks.prev);
-	for (; sb != sb_entry(&super_blocks); sb = sb_entry(sb->s_list.prev)) {
-		if (sb->s_syncing)
-			continue;
-		sb->s_syncing = 1;
-		sb->s_count++;
-		spin_unlock(&sb_lock);
-		down_read(&sb->s_umount);
-		if (!sb->s_root) {
-			drop_super(sb);
-			goto restart;
-		}
-		return sb;
-	}
-	spin_unlock(&sb_lock);
-	return NULL;
-}
-
 /**
  * sync_inodes - writes all inodes to disk
  * @wait: wait for completion
@@ -530,23 +504,39 @@ restart:
  * outstanding dirty inodes, the writeback goes block-at-a-time within the
  * filesystem's write_inode().  This is extremely slow.
  */
-void sync_inodes(int wait)
+static void __sync_inodes(int wait)
 {
 	struct super_block *sb;
 
-	set_sb_syncing(0);
-	while ((sb = get_super_to_sync()) != NULL) {
-		sync_inodes_sb(sb, 0);
-		sync_blockdev(sb->s_bdev);
-		drop_super(sb);
+	spin_lock(&sb_lock);
+restart:
+	list_for_each_entry(sb, &super_blocks, s_list) {
+		if (sb->s_syncing)
+			continue;
+		sb->s_syncing = 1;
+		sb->s_count++;
+		spin_unlock(&sb_lock);
+		down_read(&sb->s_umount);
+		if (sb->s_root) {
+			sync_inodes_sb(sb, wait);
+			sync_blockdev(sb->s_bdev);
+		}
+		up_read(&sb->s_umount);
+		spin_lock(&sb_lock);
+		if (__put_super_and_need_restart(sb))
+			goto restart;
 	}
+	spin_unlock(&sb_lock);
+}
+
+void sync_inodes(int wait)
+{
+	set_sb_syncing(0);
+	__sync_inodes(0);
+
 	if (wait) {
 		set_sb_syncing(0);
-		while ((sb = get_super_to_sync()) != NULL) {
-			sync_inodes_sb(sb, 1);
-			sync_blockdev(sb->s_bdev);
-			drop_super(sb);
-		}
+		__sync_inodes(1);
 	}
 }
 
diff --git a/fs/hfs/bnode.c b/fs/hfs/bnode.c
--- a/fs/hfs/bnode.c
+++ b/fs/hfs/bnode.c
@@ -480,6 +480,8 @@ void hfs_bnode_put(struct hfs_bnode *nod
 			return;
 		}
 		for (i = 0; i < tree->pages_per_bnode; i++) {
+			if (!node->page[i])
+				continue;
 			mark_page_accessed(node->page[i]);
 #if REF_PAGES
 			put_page(node->page[i]);
diff --git a/fs/hfs/extent.c b/fs/hfs/extent.c
--- a/fs/hfs/extent.c
+++ b/fs/hfs/extent.c
@@ -482,7 +482,8 @@ void hfs_file_truncate(struct inode *ino
 		page_cache_release(page);
 		mark_inode_dirty(inode);
 		return;
-	}
+	} else if (inode->i_size == HFS_I(inode)->phys_size)
+		return;
 	size = inode->i_size + HFS_SB(sb)->alloc_blksz - 1;
 	blk_cnt = size / HFS_SB(sb)->alloc_blksz;
 	alloc_cnt = HFS_I(inode)->alloc_blocks;
diff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c
--- a/fs/hfsplus/bnode.c
+++ b/fs/hfsplus/bnode.c
@@ -643,6 +643,8 @@ void hfs_bnode_put(struct hfs_bnode *nod
 			return;
 		}
 		for (i = 0; i < tree->pages_per_bnode; i++) {
+			if (!node->page[i])
+				continue;
 			mark_page_accessed(node->page[i]);
 #if REF_PAGES
 			put_page(node->page[i]);
diff --git a/fs/hfsplus/extents.c b/fs/hfsplus/extents.c
--- a/fs/hfsplus/extents.c
+++ b/fs/hfsplus/extents.c
@@ -461,7 +461,9 @@ void hfsplus_file_truncate(struct inode 
 		page_cache_release(page);
 		mark_inode_dirty(inode);
 		return;
-	}
+	} else if (inode->i_size == HFSPLUS_I(inode).phys_size)
+		return;
+
 	blk_cnt = (inode->i_size + HFSPLUS_SB(sb).alloc_blksz - 1) >> HFSPLUS_SB(sb).alloc_blksz_shift;
 	alloc_cnt = HFSPLUS_I(inode).alloc_blocks;
 	if (blk_cnt == alloc_cnt)
diff --git a/fs/hostfs/hostfs.h b/fs/hostfs/hostfs.h
--- a/fs/hostfs/hostfs.h
+++ b/fs/hostfs/hostfs.h
@@ -69,6 +69,7 @@ extern int read_file(int fd, unsigned lo
 extern int write_file(int fd, unsigned long long *offset, const char *buf,
 		      int len);
 extern int lseek_file(int fd, long long offset, int whence);
+extern int fsync_file(int fd, int datasync);
 extern int file_create(char *name, int ur, int uw, int ux, int gr,
 		       int gw, int gx, int or, int ow, int ox);
 extern int set_attr(const char *file, struct hostfs_iattr *attrs);
diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c
--- a/fs/hostfs/hostfs_kern.c
+++ b/fs/hostfs/hostfs_kern.c
@@ -15,7 +15,6 @@
 #include <linux/pagemap.h>
 #include <linux/blkdev.h>
 #include <linux/list.h>
-#include <linux/root_dev.h>
 #include <linux/statfs.h>
 #include <linux/kdev_t.h>
 #include <asm/uaccess.h>
@@ -160,8 +159,6 @@ static int read_name(struct inode *ino, 
 	ino->i_size = i_size;
 	ino->i_blksize = i_blksize;
 	ino->i_blocks = i_blocks;
-	if((ino->i_sb->s_dev == ROOT_DEV) && (ino->i_uid == getuid()))
-		ino->i_uid = 0;
 	return(0);
 }
 
@@ -385,7 +382,7 @@ int hostfs_file_open(struct inode *ino, 
 
 int hostfs_fsync(struct file *file, struct dentry *dentry, int datasync)
 {
-	return(0);
+	return fsync_file(HOSTFS_I(dentry->d_inode)->fd, datasync);
 }
 
 static struct file_operations hostfs_file_fops = {
@@ -841,16 +838,10 @@ int hostfs_setattr(struct dentry *dentry
 		attrs.ia_mode = attr->ia_mode;
 	}
 	if(attr->ia_valid & ATTR_UID){
-		if((dentry->d_inode->i_sb->s_dev == ROOT_DEV) &&
-		   (attr->ia_uid == 0))
-			attr->ia_uid = getuid();
 		attrs.ia_valid |= HOSTFS_ATTR_UID;
 		attrs.ia_uid = attr->ia_uid;
 	}
 	if(attr->ia_valid & ATTR_GID){
-		if((dentry->d_inode->i_sb->s_dev == ROOT_DEV) &&
-		   (attr->ia_gid == 0))
-			attr->ia_gid = getgid();
 		attrs.ia_valid |= HOSTFS_ATTR_GID;
 		attrs.ia_gid = attr->ia_gid;
 	}
diff --git a/fs/hostfs/hostfs_user.c b/fs/hostfs/hostfs_user.c
--- a/fs/hostfs/hostfs_user.c
+++ b/fs/hostfs/hostfs_user.c
@@ -153,10 +153,24 @@ int lseek_file(int fd, long long offset,
 	int ret;
 
 	ret = lseek64(fd, offset, whence);
-	if(ret < 0) return(-errno);
+	if(ret < 0)
+		return(-errno);
 	return(0);
 }
 
+int fsync_file(int fd, int datasync)
+{
+	int ret;
+	if (datasync)
+		ret = fdatasync(fd);
+	else
+		ret = fsync(fd);
+
+	if (ret < 0)
+		return -errno;
+	return 0;
+}
+
 void close_file(void *stream)
 {
 	close(*((int *) stream));
diff --git a/fs/hppfs/hppfs_kern.c b/fs/hppfs/hppfs_kern.c
--- a/fs/hppfs/hppfs_kern.c
+++ b/fs/hppfs/hppfs_kern.c
@@ -4,6 +4,7 @@
  */
 
 #include <linux/fs.h>
+#include <linux/file.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/slab.h>
@@ -37,7 +38,7 @@ struct hppfs_inode_info {
 
 static inline struct hppfs_inode_info *HPPFS_I(struct inode *inode)
 {
-	return(list_entry(inode, struct hppfs_inode_info, vfs_inode));
+	return container_of(inode, struct hppfs_inode_info, vfs_inode);
 }
 
 #define HPPFS_SUPER_MAGIC 0xb00000ee
@@ -232,7 +233,7 @@ static ssize_t read_proc(struct file *fi
 		set_fs(USER_DS);
 
 	if(ppos) *ppos = file->f_pos;
-	return(n);
+	return n;
 }
 
 static ssize_t hppfs_read_file(int fd, char *buf, ssize_t count)
@@ -253,7 +254,7 @@ static ssize_t hppfs_read_file(int fd, c
 		err = os_read_file(fd, new_buf, cur);
 		if(err < 0){
 			printk("hppfs_read : read failed, errno = %d\n",
-			       count);
+			       err);
 			n = err;
 			goto out_free;
 		}
@@ -270,7 +271,7 @@ static ssize_t hppfs_read_file(int fd, c
  out_free:
 	kfree(new_buf);
  out:
-	return(n);
+	return n;
 }
 
 static ssize_t hppfs_read(struct file *file, char *buf, size_t count,
@@ -491,7 +492,7 @@ static int hppfs_open(struct inode *inod
 		fd = open_host_sock(host_file, &filter);
 		if(fd > 0){
 			data->contents = hppfs_get_data(fd, filter,
-							&data->proc_file,
+							data->proc_file,
 							file, &data->len);
 			if(!IS_ERR(data->contents))
 				data->host_fd = fd;
@@ -543,7 +544,7 @@ static int hppfs_dir_open(struct inode *
 static loff_t hppfs_llseek(struct file *file, loff_t off, int where)
 {
 	struct hppfs_private *data = file->private_data;
-	struct file *proc_file = &data->proc_file;
+	struct file *proc_file = data->proc_file;
 	loff_t (*llseek)(struct file *, loff_t, int);
 	loff_t ret;
 
@@ -586,7 +587,7 @@ static int hppfs_filldir(void *d, const 
 static int hppfs_readdir(struct file *file, void *ent, filldir_t filldir)
 {
 	struct hppfs_private *data = file->private_data;
-	struct file *proc_file = &data->proc_file;
+	struct file *proc_file = data->proc_file;
 	int (*readdir)(struct file *, void *, filldir_t);
 	struct hppfs_dirent dirent = ((struct hppfs_dirent)
 		                      { .vfs_dirent  	= ent,
@@ -661,42 +662,36 @@ static int hppfs_readlink(struct dentry 
 {
 	struct file *proc_file;
 	struct dentry *proc_dentry;
-	int (*readlink)(struct dentry *, char *, int);
-	int err, n;
+	int ret;
 
 	proc_dentry = HPPFS_I(dentry->d_inode)->proc_dentry;
 	proc_file = dentry_open(dget(proc_dentry), NULL, O_RDONLY);
-	err = PTR_ERR(proc_dentry);
-	if(IS_ERR(proc_dentry))
-		return(err);
+	if (IS_ERR(proc_file))
+		return PTR_ERR(proc_file);
 
-	readlink = proc_dentry->d_inode->i_op->readlink;
-	n = (*readlink)(proc_dentry, buffer, buflen);
+	ret = proc_dentry->d_inode->i_op->readlink(proc_dentry, buffer, buflen);
 
 	fput(proc_file);
 
-	return(n);
+	return ret;
 }
 
-static int hppfs_follow_link(struct dentry *dentry, struct nameidata *nd)
+static void* hppfs_follow_link(struct dentry *dentry, struct nameidata *nd)
 {
 	struct file *proc_file;
 	struct dentry *proc_dentry;
-	int (*follow_link)(struct dentry *, struct nameidata *);
-	int err, n;
+	void *ret;
 
 	proc_dentry = HPPFS_I(dentry->d_inode)->proc_dentry;
 	proc_file = dentry_open(dget(proc_dentry), NULL, O_RDONLY);
-	err = PTR_ERR(proc_dentry);
-	if(IS_ERR(proc_dentry))
-		return(err);
+	if (IS_ERR(proc_file))
+		return proc_file;
 
-	follow_link = proc_dentry->d_inode->i_op->follow_link;
-	n = (*follow_link)(proc_dentry, nd);
+	ret = proc_dentry->d_inode->i_op->follow_link(proc_dentry, nd);
 
 	fput(proc_file);
 
-	return(n);
+	return ret;
 }
 
 static struct inode_operations hppfs_dir_iops = {
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -122,6 +122,9 @@ hugetlb_get_unmapped_area(struct file *f
 
 	start_addr = mm->free_area_cache;
 
+	if (len <= mm->cached_hole_size)
+		start_addr = TASK_UNMAPPED_BASE;
+
 full_search:
 	addr = ALIGN(start_addr, HPAGE_SIZE);
 
diff --git a/fs/inode.c b/fs/inode.c
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -21,6 +21,7 @@
 #include <linux/pagemap.h>
 #include <linux/cdev.h>
 #include <linux/bootmem.h>
+#include <linux/inotify.h>
 
 /*
  * This is needed for the following functions:
@@ -202,6 +203,10 @@ void inode_init_once(struct inode *inode
 	INIT_LIST_HEAD(&inode->i_data.i_mmap_nonlinear);
 	spin_lock_init(&inode->i_lock);
 	i_size_ordered_init(inode);
+#ifdef CONFIG_INOTIFY
+	INIT_LIST_HEAD(&inode->inotify_watches);
+	sema_init(&inode->inotify_sem, 1);
+#endif
 }
 
 EXPORT_SYMBOL(inode_init_once);
@@ -282,6 +287,13 @@ static void dispose_list(struct list_hea
 		if (inode->i_data.nrpages)
 			truncate_inode_pages(&inode->i_data, 0);
 		clear_inode(inode);
+
+		spin_lock(&inode_lock);
+		hlist_del_init(&inode->i_hash);
+		list_del_init(&inode->i_sb_list);
+		spin_unlock(&inode_lock);
+
+		wake_up_inode(inode);
 		destroy_inode(inode);
 		nr_disposed++;
 	}
@@ -317,8 +329,6 @@ static int invalidate_list(struct list_h
 		inode = list_entry(tmp, struct inode, i_sb_list);
 		invalidate_inode_buffers(inode);
 		if (!atomic_read(&inode->i_count)) {
-			hlist_del_init(&inode->i_hash);
-			list_del(&inode->i_sb_list);
 			list_move(&inode->i_list, dispose);
 			inode->i_state |= I_FREEING;
 			count++;
@@ -346,6 +356,7 @@ int invalidate_inodes(struct super_block
 
 	down(&iprune_sem);
 	spin_lock(&inode_lock);
+	inotify_unmount_inodes(&sb->s_inodes);
 	busy = invalidate_list(&sb->s_inodes, &throw_away);
 	spin_unlock(&inode_lock);
 
@@ -439,8 +450,6 @@ static void prune_icache(int nr_to_scan)
 			if (!can_unuse(inode))
 				continue;
 		}
-		hlist_del_init(&inode->i_hash);
-		list_del_init(&inode->i_sb_list);
 		list_move(&inode->i_list, &freeable);
 		inode->i_state |= I_FREEING;
 		nr_pruned++;
@@ -500,7 +509,7 @@ repeat:
 			continue;
 		if (!test(inode, data))
 			continue;
-		if (inode->i_state & (I_FREEING|I_CLEAR)) {
+		if (inode->i_state & (I_FREEING|I_CLEAR|I_WILL_FREE)) {
 			__wait_on_freeing_inode(inode);
 			goto repeat;
 		}
@@ -525,7 +534,7 @@ repeat:
 			continue;
 		if (inode->i_sb != sb)
 			continue;
-		if (inode->i_state & (I_FREEING|I_CLEAR)) {
+		if (inode->i_state & (I_FREEING|I_CLEAR|I_WILL_FREE)) {
 			__wait_on_freeing_inode(inode);
 			goto repeat;
 		}
@@ -727,7 +736,7 @@ EXPORT_SYMBOL(iunique);
 struct inode *igrab(struct inode *inode)
 {
 	spin_lock(&inode_lock);
-	if (!(inode->i_state & I_FREEING))
+	if (!(inode->i_state & (I_FREEING|I_WILL_FREE)))
 		__iget(inode);
 	else
 		/*
@@ -748,6 +757,7 @@ EXPORT_SYMBOL(igrab);
  * @head:       the head of the list to search
  * @test:	callback used for comparisons between inodes
  * @data:	opaque data pointer to pass to @test
+ * @wait:	if true wait for the inode to be unlocked, if false do not
  *
  * ifind() searches for the inode specified by @data in the inode
  * cache. This is a generalized version of ifind_fast() for file systems where
@@ -762,7 +772,7 @@ EXPORT_SYMBOL(igrab);
  */
 static inline struct inode *ifind(struct super_block *sb,
 		struct hlist_head *head, int (*test)(struct inode *, void *),
-		void *data)
+		void *data, const int wait)
 {
 	struct inode *inode;
 
@@ -771,7 +781,8 @@ static inline struct inode *ifind(struct
 	if (inode) {
 		__iget(inode);
 		spin_unlock(&inode_lock);
-		wait_on_inode(inode);
+		if (likely(wait))
+			wait_on_inode(inode);
 		return inode;
 	}
 	spin_unlock(&inode_lock);
@@ -811,7 +822,7 @@ static inline struct inode *ifind_fast(s
 }
 
 /**
- * ilookup5 - search for an inode in the inode cache
+ * ilookup5_nowait - search for an inode in the inode cache
  * @sb:		super block of file system to search
  * @hashval:	hash value (usually inode number) to search for
  * @test:	callback used for comparisons between inodes
@@ -823,7 +834,38 @@ static inline struct inode *ifind_fast(s
  * identification of an inode.
  *
  * If the inode is in the cache, the inode is returned with an incremented
- * reference count.
+ * reference count.  Note, the inode lock is not waited upon so you have to be
+ * very careful what you do with the returned inode.  You probably should be
+ * using ilookup5() instead.
+ *
+ * Otherwise NULL is returned.
+ *
+ * Note, @test is called with the inode_lock held, so can't sleep.
+ */
+struct inode *ilookup5_nowait(struct super_block *sb, unsigned long hashval,
+		int (*test)(struct inode *, void *), void *data)
+{
+	struct hlist_head *head = inode_hashtable + hash(sb, hashval);
+
+	return ifind(sb, head, test, data, 0);
+}
+
+EXPORT_SYMBOL(ilookup5_nowait);
+
+/**
+ * ilookup5 - search for an inode in the inode cache
+ * @sb:		super block of file system to search
+ * @hashval:	hash value (usually inode number) to search for
+ * @test:	callback used for comparisons between inodes
+ * @data:	opaque data pointer to pass to @test
+ *
+ * ilookup5() uses ifind() to search for the inode specified by @hashval and
+ * @data in the inode cache. This is a generalized version of ilookup() for
+ * file systems where the inode number is not sufficient for unique
+ * identification of an inode.
+ *
+ * If the inode is in the cache, the inode lock is waited upon and the inode is
+ * returned with an incremented reference count.
  *
  * Otherwise NULL is returned.
  *
@@ -834,7 +876,7 @@ struct inode *ilookup5(struct super_bloc
 {
 	struct hlist_head *head = inode_hashtable + hash(sb, hashval);
 
-	return ifind(sb, head, test, data);
+	return ifind(sb, head, test, data, 1);
 }
 
 EXPORT_SYMBOL(ilookup5);
@@ -891,7 +933,7 @@ struct inode *iget5_locked(struct super_
 	struct hlist_head *head = inode_hashtable + hash(sb, hashval);
 	struct inode *inode;
 
-	inode = ifind(sb, head, test, data);
+	inode = ifind(sb, head, test, data, 1);
 	if (inode)
 		return inode;
 	/*
@@ -1024,17 +1066,21 @@ static void generic_forget_inode(struct 
 		if (!(inode->i_state & (I_DIRTY|I_LOCK)))
 			list_move(&inode->i_list, &inode_unused);
 		inodes_stat.nr_unused++;
-		spin_unlock(&inode_lock);
-		if (!sb || (sb->s_flags & MS_ACTIVE))
+		if (!sb || (sb->s_flags & MS_ACTIVE)) {
+			spin_unlock(&inode_lock);
 			return;
+		}
+		inode->i_state |= I_WILL_FREE;
+		spin_unlock(&inode_lock);
 		write_inode_now(inode, 1);
 		spin_lock(&inode_lock);
+		inode->i_state &= ~I_WILL_FREE;
 		inodes_stat.nr_unused--;
 		hlist_del_init(&inode->i_hash);
 	}
 	list_del_init(&inode->i_list);
 	list_del_init(&inode->i_sb_list);
-	inode->i_state|=I_FREEING;
+	inode->i_state |= I_FREEING;
 	inodes_stat.nr_inodes--;
 	spin_unlock(&inode_lock);
 	if (inode->i_data.nrpages)
@@ -1048,7 +1094,7 @@ static void generic_forget_inode(struct 
  * inode when the usage count drops to zero, and
  * i_nlink is zero.
  */
-static void generic_drop_inode(struct inode *inode)
+void generic_drop_inode(struct inode *inode)
 {
 	if (!inode->i_nlink)
 		generic_delete_inode(inode);
@@ -1056,6 +1102,8 @@ static void generic_drop_inode(struct in
 		generic_forget_inode(inode);
 }
 
+EXPORT_SYMBOL_GPL(generic_drop_inode);
+
 /*
  * Called when we're dropping the last reference
  * to an inode. 
@@ -1238,29 +1286,21 @@ int inode_wait(void *word)
 }
 
 /*
- * If we try to find an inode in the inode hash while it is being deleted, we
- * have to wait until the filesystem completes its deletion before reporting
- * that it isn't found.  This is because iget will immediately call
- * ->read_inode, and we want to be sure that evidence of the deletion is found
- * by ->read_inode.
+ * If we try to find an inode in the inode hash while it is being
+ * deleted, we have to wait until the filesystem completes its
+ * deletion before reporting that it isn't found.  This function waits
+ * until the deletion _might_ have completed.  Callers are responsible
+ * to recheck inode state.
+ *
+ * It doesn't matter if I_LOCK is not set initially, a call to
+ * wake_up_inode() after removing from the hash list will DTRT.
+ *
  * This is called with inode_lock held.
  */
 static void __wait_on_freeing_inode(struct inode *inode)
 {
 	wait_queue_head_t *wq;
 	DEFINE_WAIT_BIT(wait, &inode->i_state, __I_LOCK);
-
-	/*
-	 * I_FREEING and I_CLEAR are cleared in process context under
-	 * inode_lock, so we have to give the tasks who would clear them
-	 * a chance to run and acquire inode_lock.
-	 */
-	if (!(inode->i_state & I_LOCK)) {
-		spin_unlock(&inode_lock);
-		yield();
-		spin_lock(&inode_lock);
-		return;
-	}
 	wq = bit_waitqueue(&inode->i_state, __I_LOCK);
 	prepare_to_wait(wq, &wait.wait, TASK_UNINTERRUPTIBLE);
 	spin_unlock(&inode_lock);
diff --git a/fs/inotify.c b/fs/inotify.c
new file mode 100644
--- /dev/null
+++ b/fs/inotify.c
@@ -0,0 +1,1057 @@
+/*
+ * fs/inotify.c - inode-based file event notifications
+ *
+ * Authors:
+ *	John McCutchan	<ttb@tentacle.dhs.org>
+ *	Robert Love	<rml@novell.com>
+ *
+ * Copyright (C) 2005 John McCutchan
+ *
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/idr.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/file.h>
+#include <linux/mount.h>
+#include <linux/namei.h>
+#include <linux/poll.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/writeback.h>
+#include <linux/inotify.h>
+
+#include <asm/ioctls.h>
+
+static atomic_t inotify_cookie;
+
+static kmem_cache_t *watch_cachep;
+static kmem_cache_t *event_cachep;
+
+static struct vfsmount *inotify_mnt;
+
+/* these are configurable via /proc/sys/fs/inotify/ */
+int inotify_max_user_instances;
+int inotify_max_user_watches;
+int inotify_max_queued_events;
+
+/*
+ * Lock ordering:
+ *
+ * dentry->d_lock (used to keep d_move() away from dentry->d_parent)
+ * iprune_sem (synchronize shrink_icache_memory())
+ * 	inode_lock (protects the super_block->s_inodes list)
+ * 	inode->inotify_sem (protects inode->inotify_watches and watches->i_list)
+ * 		inotify_dev->sem (protects inotify_device and watches->d_list)
+ */
+
+/*
+ * Lifetimes of the three main data structures--inotify_device, inode, and
+ * inotify_watch--are managed by reference count.
+ *
+ * inotify_device: Lifetime is from inotify_init() until release.  Additional
+ * references can bump the count via get_inotify_dev() and drop the count via
+ * put_inotify_dev().
+ *
+ * inotify_watch: Lifetime is from create_watch() to destory_watch().
+ * Additional references can bump the count via get_inotify_watch() and drop
+ * the count via put_inotify_watch().
+ *
+ * inode: Pinned so long as the inode is associated with a watch, from
+ * create_watch() to put_inotify_watch().
+ */
+
+/*
+ * struct inotify_device - represents an inotify instance
+ *
+ * This structure is protected by the semaphore 'sem'.
+ */
+struct inotify_device {
+	wait_queue_head_t 	wq;		/* wait queue for i/o */
+	struct idr		idr;		/* idr mapping wd -> watch */
+	struct semaphore	sem;		/* protects this bad boy */
+	struct list_head 	events;		/* list of queued events */
+	struct list_head	watches;	/* list of watches */
+	atomic_t		count;		/* reference count */
+	struct user_struct	*user;		/* user who opened this dev */
+	unsigned int		queue_size;	/* size of the queue (bytes) */
+	unsigned int		event_count;	/* number of pending events */
+	unsigned int		max_events;	/* maximum number of events */
+	u32			last_wd;	/* the last wd allocated */
+};
+
+/*
+ * struct inotify_kernel_event - An inotify event, originating from a watch and
+ * queued for user-space.  A list of these is attached to each instance of the
+ * device.  In read(), this list is walked and all events that can fit in the
+ * buffer are returned.
+ *
+ * Protected by dev->sem of the device in which we are queued.
+ */
+struct inotify_kernel_event {
+	struct inotify_event	event;	/* the user-space event */
+	struct list_head        list;	/* entry in inotify_device's list */
+	char			*name;	/* filename, if any */
+};
+
+/*
+ * struct inotify_watch - represents a watch request on a specific inode
+ *
+ * d_list is protected by dev->sem of the associated watch->dev.
+ * i_list and mask are protected by inode->inotify_sem of the associated inode.
+ * dev, inode, and wd are never written to once the watch is created.
+ */
+struct inotify_watch {
+	struct list_head	d_list;	/* entry in inotify_device's list */
+	struct list_head	i_list;	/* entry in inode's list */
+	atomic_t		count;	/* reference count */
+	struct inotify_device	*dev;	/* associated device */
+	struct inode		*inode;	/* associated inode */
+	s32 			wd;	/* watch descriptor */
+	u32			mask;	/* event mask for this watch */
+};
+
+#ifdef CONFIG_SYSCTL
+
+#include <linux/sysctl.h>
+
+static int zero;
+
+ctl_table inotify_table[] = {
+	{
+		.ctl_name	= INOTIFY_MAX_USER_INSTANCES,
+		.procname	= "max_user_instances",
+		.data		= &inotify_max_user_instances,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec_minmax,
+		.strategy	= &sysctl_intvec,
+		.extra1		= &zero,
+	},
+	{
+		.ctl_name	= INOTIFY_MAX_USER_WATCHES,
+		.procname	= "max_user_watches",
+		.data		= &inotify_max_user_watches,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec_minmax,
+		.strategy	= &sysctl_intvec,
+		.extra1		= &zero, 
+	},
+	{
+		.ctl_name	= INOTIFY_MAX_QUEUED_EVENTS,
+		.procname	= "max_queued_events",
+		.data		= &inotify_max_queued_events,
+		.maxlen		= sizeof(int),
+		.mode		= 0644, 
+		.proc_handler	= &proc_dointvec_minmax,
+		.strategy	= &sysctl_intvec, 
+		.extra1		= &zero
+	},
+	{ .ctl_name = 0 }
+};
+#endif /* CONFIG_SYSCTL */
+
+static inline void get_inotify_dev(struct inotify_device *dev)
+{
+	atomic_inc(&dev->count);
+}
+
+static inline void put_inotify_dev(struct inotify_device *dev)
+{
+	if (atomic_dec_and_test(&dev->count)) {
+		atomic_dec(&dev->user->inotify_devs);
+		free_uid(dev->user);
+		kfree(dev);
+	}
+}
+
+static inline void get_inotify_watch(struct inotify_watch *watch)
+{
+	atomic_inc(&watch->count);
+}
+
+/*
+ * put_inotify_watch - decrements the ref count on a given watch.  cleans up
+ * the watch and its references if the count reaches zero.
+ */
+static inline void put_inotify_watch(struct inotify_watch *watch)
+{
+	if (atomic_dec_and_test(&watch->count)) {
+		put_inotify_dev(watch->dev);
+		iput(watch->inode);
+		kmem_cache_free(watch_cachep, watch);
+	}
+}
+
+/*
+ * kernel_event - create a new kernel event with the given parameters
+ *
+ * This function can sleep.
+ */
+static struct inotify_kernel_event * kernel_event(s32 wd, u32 mask, u32 cookie,
+						  const char *name)
+{
+	struct inotify_kernel_event *kevent;
+
+	kevent = kmem_cache_alloc(event_cachep, GFP_KERNEL);
+	if (unlikely(!kevent))
+		return NULL;
+
+	/* we hand this out to user-space, so zero it just in case */
+	memset(&kevent->event, 0, sizeof(struct inotify_event));
+
+	kevent->event.wd = wd;
+	kevent->event.mask = mask;
+	kevent->event.cookie = cookie;
+
+	INIT_LIST_HEAD(&kevent->list);
+
+	if (name) {
+		size_t len, rem, event_size = sizeof(struct inotify_event);
+
+		/*
+		 * We need to pad the filename so as to properly align an
+		 * array of inotify_event structures.  Because the structure is
+		 * small and the common case is a small filename, we just round
+		 * up to the next multiple of the structure's sizeof.  This is
+		 * simple and safe for all architectures.
+		 */
+		len = strlen(name) + 1;
+		rem = event_size - len;
+		if (len > event_size) {
+			rem = event_size - (len % event_size);
+			if (len % event_size == 0)
+				rem = 0;
+		}
+
+		kevent->name = kmalloc(len + rem, GFP_KERNEL);
+		if (unlikely(!kevent->name)) {
+			kmem_cache_free(event_cachep, kevent);
+			return NULL;
+		}
+		memcpy(kevent->name, name, len);
+		if (rem)
+			memset(kevent->name + len, 0, rem);		
+		kevent->event.len = len + rem;
+	} else {
+		kevent->event.len = 0;
+		kevent->name = NULL;
+	}
+
+	return kevent;
+}
+
+/*
+ * inotify_dev_get_event - return the next event in the given dev's queue
+ *
+ * Caller must hold dev->sem.
+ */
+static inline struct inotify_kernel_event *
+inotify_dev_get_event(struct inotify_device *dev)
+{
+	return list_entry(dev->events.next, struct inotify_kernel_event, list);
+}
+
+/*
+ * inotify_dev_queue_event - add a new event to the given device
+ *
+ * Caller must hold dev->sem.  Can sleep (calls kernel_event()).
+ */
+static void inotify_dev_queue_event(struct inotify_device *dev,
+				    struct inotify_watch *watch, u32 mask,
+				    u32 cookie, const char *name)
+{
+	struct inotify_kernel_event *kevent, *last;
+
+	/* coalescing: drop this event if it is a dupe of the previous */
+	last = inotify_dev_get_event(dev);
+	if (last && last->event.mask == mask && last->event.wd == watch->wd &&
+			last->event.cookie == cookie) {
+		const char *lastname = last->name;
+
+		if (!name && !lastname)
+			return;
+		if (name && lastname && !strcmp(lastname, name))
+			return;
+	}
+
+	/* the queue overflowed and we already sent the Q_OVERFLOW event */
+	if (unlikely(dev->event_count > dev->max_events))
+		return;
+
+	/* if the queue overflows, we need to notify user space */
+	if (unlikely(dev->event_count == dev->max_events))
+		kevent = kernel_event(-1, IN_Q_OVERFLOW, cookie, NULL);
+	else
+		kevent = kernel_event(watch->wd, mask, cookie, name);
+
+	if (unlikely(!kevent))
+		return;
+
+	/* queue the event and wake up anyone waiting */
+	dev->event_count++;
+	dev->queue_size += sizeof(struct inotify_event) + kevent->event.len;
+	list_add_tail(&kevent->list, &dev->events);
+	wake_up_interruptible(&dev->wq);
+}
+
+/*
+ * remove_kevent - cleans up and ultimately frees the given kevent
+ *
+ * Caller must hold dev->sem.
+ */
+static void remove_kevent(struct inotify_device *dev,
+			  struct inotify_kernel_event *kevent)
+{
+	list_del(&kevent->list);
+
+	dev->event_count--;
+	dev->queue_size -= sizeof(struct inotify_event) + kevent->event.len;
+
+	kfree(kevent->name);
+	kmem_cache_free(event_cachep, kevent);
+}
+
+/*
+ * inotify_dev_event_dequeue - destroy an event on the given device
+ *
+ * Caller must hold dev->sem.
+ */
+static void inotify_dev_event_dequeue(struct inotify_device *dev)
+{
+	if (!list_empty(&dev->events)) {
+		struct inotify_kernel_event *kevent;
+		kevent = inotify_dev_get_event(dev);
+		remove_kevent(dev, kevent);
+	}
+}
+
+/*
+ * inotify_dev_get_wd - returns the next WD for use by the given dev
+ *
+ * Callers must hold dev->sem.  This function can sleep.
+ */
+static int inotify_dev_get_wd(struct inotify_device *dev,
+			      struct inotify_watch *watch)
+{
+	int ret;
+
+	do {
+		if (unlikely(!idr_pre_get(&dev->idr, GFP_KERNEL)))
+			return -ENOSPC;
+		ret = idr_get_new_above(&dev->idr, watch, dev->last_wd+1, &watch->wd);
+	} while (ret == -EAGAIN);
+
+	return ret;
+}
+
+/*
+ * find_inode - resolve a user-given path to a specific inode and return a nd
+ */
+static int find_inode(const char __user *dirname, struct nameidata *nd)
+{
+	int error;
+
+	error = __user_walk(dirname, LOOKUP_FOLLOW, nd);
+	if (error)
+		return error;
+	/* you can only watch an inode if you have read permissions on it */
+	error = permission(nd->dentry->d_inode, MAY_READ, NULL);
+	if (error) 
+		path_release(nd);
+	return error;
+}
+
+/*
+ * create_watch - creates a watch on the given device.
+ *
+ * Callers must hold dev->sem.  Calls inotify_dev_get_wd() so may sleep.
+ * Both 'dev' and 'inode' (by way of nameidata) need to be pinned.
+ */
+static struct inotify_watch *create_watch(struct inotify_device *dev,
+					  u32 mask, struct inode *inode)
+{
+	struct inotify_watch *watch;
+	int ret;
+
+	if (atomic_read(&dev->user->inotify_watches) >=
+			inotify_max_user_watches)
+		return ERR_PTR(-ENOSPC);
+
+	watch = kmem_cache_alloc(watch_cachep, GFP_KERNEL);
+	if (unlikely(!watch))
+		return ERR_PTR(-ENOMEM);
+
+	ret = inotify_dev_get_wd(dev, watch);
+	if (unlikely(ret)) {
+		kmem_cache_free(watch_cachep, watch);
+		return ERR_PTR(ret);
+	}
+
+	dev->last_wd = watch->wd;
+	watch->mask = mask;
+	atomic_set(&watch->count, 0);
+	INIT_LIST_HEAD(&watch->d_list);
+	INIT_LIST_HEAD(&watch->i_list);
+
+	/* save a reference to device and bump the count to make it official */
+	get_inotify_dev(dev);
+	watch->dev = dev;
+
+	/*
+	 * Save a reference to the inode and bump the ref count to make it
+	 * official.  We hold a reference to nameidata, which makes this safe.
+	 */
+	watch->inode = igrab(inode);
+
+	/* bump our own count, corresponding to our entry in dev->watches */
+	get_inotify_watch(watch);
+
+	atomic_inc(&dev->user->inotify_watches);
+
+	return watch;
+}
+
+/*
+ * inotify_find_dev - find the watch associated with the given inode and dev
+ *
+ * Callers must hold inode->inotify_sem.
+ */
+static struct inotify_watch *inode_find_dev(struct inode *inode,
+					    struct inotify_device *dev)
+{
+	struct inotify_watch *watch;
+
+	list_for_each_entry(watch, &inode->inotify_watches, i_list) {
+		if (watch->dev == dev)
+			return watch;
+	}
+
+	return NULL;
+}
+
+/*
+ * remove_watch_no_event - remove_watch() without the IN_IGNORED event.
+ */
+static void remove_watch_no_event(struct inotify_watch *watch,
+				  struct inotify_device *dev)
+{
+	list_del(&watch->i_list);
+	list_del(&watch->d_list);
+
+	atomic_dec(&dev->user->inotify_watches);
+	idr_remove(&dev->idr, watch->wd);
+	put_inotify_watch(watch);
+}
+
+/*
+ * remove_watch - Remove a watch from both the device and the inode.  Sends
+ * the IN_IGNORED event to the given device signifying that the inode is no
+ * longer watched.
+ *
+ * Callers must hold both inode->inotify_sem and dev->sem.  We drop a
+ * reference to the inode before returning.
+ *
+ * The inode is not iput() so as to remain atomic.  If the inode needs to be
+ * iput(), the call returns one.  Otherwise, it returns zero.
+ */
+static void remove_watch(struct inotify_watch *watch,struct inotify_device *dev)
+{
+	inotify_dev_queue_event(dev, watch, IN_IGNORED, 0, NULL);
+	remove_watch_no_event(watch, dev);
+}
+
+/*
+ * inotify_inode_watched - returns nonzero if there are watches on this inode
+ * and zero otherwise.  We call this lockless, we do not care if we race.
+ */
+static inline int inotify_inode_watched(struct inode *inode)
+{
+	return !list_empty(&inode->inotify_watches);
+}
+
+/* Kernel API */
+
+/**
+ * inotify_inode_queue_event - queue an event to all watches on this inode
+ * @inode: inode event is originating from
+ * @mask: event mask describing this event
+ * @cookie: cookie for synchronization, or zero
+ * @name: filename, if any
+ */
+void inotify_inode_queue_event(struct inode *inode, u32 mask, u32 cookie,
+			       const char *name)
+{
+	struct inotify_watch *watch, *next;
+
+	if (!inotify_inode_watched(inode))
+		return;
+
+	down(&inode->inotify_sem);
+	list_for_each_entry_safe(watch, next, &inode->inotify_watches, i_list) {
+		u32 watch_mask = watch->mask;
+		if (watch_mask & mask) {
+			struct inotify_device *dev = watch->dev;
+			get_inotify_watch(watch);
+			down(&dev->sem);
+			inotify_dev_queue_event(dev, watch, mask, cookie, name);
+			if (watch_mask & IN_ONESHOT)
+				remove_watch_no_event(watch, dev);
+			up(&dev->sem);
+			put_inotify_watch(watch);
+		}
+	}
+	up(&inode->inotify_sem);
+}
+EXPORT_SYMBOL_GPL(inotify_inode_queue_event);
+
+/**
+ * inotify_dentry_parent_queue_event - queue an event to a dentry's parent
+ * @dentry: the dentry in question, we queue against this dentry's parent
+ * @mask: event mask describing this event
+ * @cookie: cookie for synchronization, or zero
+ * @name: filename, if any
+ */
+void inotify_dentry_parent_queue_event(struct dentry *dentry, u32 mask,
+				       u32 cookie, const char *name)
+{
+	struct dentry *parent;
+	struct inode *inode;
+
+	spin_lock(&dentry->d_lock);
+	parent = dentry->d_parent;
+	inode = parent->d_inode;
+
+	if (inotify_inode_watched(inode)) {
+		dget(parent);
+		spin_unlock(&dentry->d_lock);
+		inotify_inode_queue_event(inode, mask, cookie, name);
+		dput(parent);
+	} else
+		spin_unlock(&dentry->d_lock);
+}
+EXPORT_SYMBOL_GPL(inotify_dentry_parent_queue_event);
+
+/**
+ * inotify_get_cookie - return a unique cookie for use in synchronizing events.
+ */
+u32 inotify_get_cookie(void)
+{
+	return atomic_inc_return(&inotify_cookie);
+}
+EXPORT_SYMBOL_GPL(inotify_get_cookie);
+
+/**
+ * inotify_unmount_inodes - an sb is unmounting.  handle any watched inodes.
+ * @list: list of inodes being unmounted (sb->s_inodes)
+ *
+ * Called with inode_lock held, protecting the unmounting super block's list
+ * of inodes, and with iprune_sem held, keeping shrink_icache_memory() at bay.
+ * We temporarily drop inode_lock, however, and CAN block.
+ */
+void inotify_unmount_inodes(struct list_head *list)
+{
+	struct inode *inode, *next_i, *need_iput = NULL;
+
+	list_for_each_entry_safe(inode, next_i, list, i_sb_list) {
+		struct inotify_watch *watch, *next_w;
+		struct inode *need_iput_tmp;
+		struct list_head *watches;
+
+		/*
+		 * If i_count is zero, the inode cannot have any watches and
+		 * doing an __iget/iput with MS_ACTIVE clear would actually
+		 * evict all inodes with zero i_count from icache which is
+		 * unnecessarily violent and may in fact be illegal to do.
+		 */
+		if (!atomic_read(&inode->i_count))
+			continue;
+
+		/*
+		 * We cannot __iget() an inode in state I_CLEAR, I_FREEING, or
+		 * I_WILL_FREE which is fine because by that point the inode
+		 * cannot have any associated watches.
+		 */
+		if (inode->i_state & (I_CLEAR | I_FREEING | I_WILL_FREE))
+			continue;
+
+		need_iput_tmp = need_iput;
+		need_iput = NULL;
+		/* In case the remove_watch() drops a reference. */
+		if (inode != need_iput_tmp)
+			__iget(inode);
+		else
+			need_iput_tmp = NULL;
+		/* In case the dropping of a reference would nuke next_i. */
+		if ((&next_i->i_sb_list != list) &&
+				atomic_read(&next_i->i_count) &&
+				!(next_i->i_state & (I_CLEAR | I_FREEING |
+					I_WILL_FREE))) {
+			__iget(next_i);
+			need_iput = next_i;
+		}
+
+		/*
+		 * We can safely drop inode_lock here because we hold
+		 * references on both inode and next_i.  Also no new inodes
+		 * will be added since the umount has begun.  Finally,
+		 * iprune_sem keeps shrink_icache_memory() away.
+		 */
+		spin_unlock(&inode_lock);
+
+		if (need_iput_tmp)
+			iput(need_iput_tmp);
+
+		/* for each watch, send IN_UNMOUNT and then remove it */
+		down(&inode->inotify_sem);
+		watches = &inode->inotify_watches;
+		list_for_each_entry_safe(watch, next_w, watches, i_list) {
+			struct inotify_device *dev = watch->dev;
+			down(&dev->sem);
+			inotify_dev_queue_event(dev, watch, IN_UNMOUNT,0,NULL);
+			remove_watch(watch, dev);
+			up(&dev->sem);
+		}
+		up(&inode->inotify_sem);
+		iput(inode);		
+
+		spin_lock(&inode_lock);
+	}
+}
+EXPORT_SYMBOL_GPL(inotify_unmount_inodes);
+
+/**
+ * inotify_inode_is_dead - an inode has been deleted, cleanup any watches
+ * @inode: inode that is about to be removed
+ */
+void inotify_inode_is_dead(struct inode *inode)
+{
+	struct inotify_watch *watch, *next;
+
+	down(&inode->inotify_sem);
+	list_for_each_entry_safe(watch, next, &inode->inotify_watches, i_list) {
+		struct inotify_device *dev = watch->dev;
+		down(&dev->sem);
+		remove_watch(watch, dev);
+		up(&dev->sem);
+	}
+	up(&inode->inotify_sem);
+}
+EXPORT_SYMBOL_GPL(inotify_inode_is_dead);
+
+/* Device Interface */
+
+static unsigned int inotify_poll(struct file *file, poll_table *wait)
+{
+	struct inotify_device *dev = file->private_data;
+	int ret = 0;
+
+	poll_wait(file, &dev->wq, wait);
+	down(&dev->sem);
+	if (!list_empty(&dev->events))
+		ret = POLLIN | POLLRDNORM;
+	up(&dev->sem);
+
+	return ret;
+}
+
+static ssize_t inotify_read(struct file *file, char __user *buf,
+			    size_t count, loff_t *pos)
+{
+	size_t event_size = sizeof (struct inotify_event);
+	struct inotify_device *dev;
+	char __user *start;
+	int ret;
+	DEFINE_WAIT(wait);
+
+	start = buf;
+	dev = file->private_data;
+
+	while (1) {
+		int events;
+
+		prepare_to_wait(&dev->wq, &wait, TASK_INTERRUPTIBLE);
+
+		down(&dev->sem);
+		events = !list_empty(&dev->events);
+		up(&dev->sem);
+		if (events) {
+			ret = 0;
+			break;
+		}
+
+		if (file->f_flags & O_NONBLOCK) {
+			ret = -EAGAIN;
+			break;
+		}
+
+		if (signal_pending(current)) {
+			ret = -EINTR;
+			break;
+		}
+
+		schedule();
+	}
+
+	finish_wait(&dev->wq, &wait);
+	if (ret)
+		return ret;
+
+	down(&dev->sem);
+	while (1) {
+		struct inotify_kernel_event *kevent;
+
+		ret = buf - start;
+		if (list_empty(&dev->events))
+			break;
+
+		kevent = inotify_dev_get_event(dev);
+		if (event_size + kevent->event.len > count)
+			break;
+
+		if (copy_to_user(buf, &kevent->event, event_size)) {
+			ret = -EFAULT;
+			break;
+		}
+		buf += event_size;
+		count -= event_size;
+
+		if (kevent->name) {
+			if (copy_to_user(buf, kevent->name, kevent->event.len)){
+				ret = -EFAULT;
+				break;
+			}
+			buf += kevent->event.len;
+			count -= kevent->event.len;
+		}
+
+		remove_kevent(dev, kevent);
+	}
+	up(&dev->sem);
+
+	return ret;
+}
+
+static int inotify_release(struct inode *ignored, struct file *file)
+{
+	struct inotify_device *dev = file->private_data;
+
+	/*
+	 * Destroy all of the watches on this device.  Unfortunately, not very
+	 * pretty.  We cannot do a simple iteration over the list, because we
+	 * do not know the inode until we iterate to the watch.  But we need to
+	 * hold inode->inotify_sem before dev->sem.  The following works.
+	 */
+	while (1) {
+		struct inotify_watch *watch;
+		struct list_head *watches;
+		struct inode *inode;
+
+		down(&dev->sem);
+		watches = &dev->watches;
+		if (list_empty(watches)) {
+			up(&dev->sem);
+			break;
+		}
+		watch = list_entry(watches->next, struct inotify_watch, d_list);
+		get_inotify_watch(watch);
+		up(&dev->sem);
+
+		inode = watch->inode;
+		down(&inode->inotify_sem);
+		down(&dev->sem);
+		remove_watch_no_event(watch, dev);
+		up(&dev->sem);
+		up(&inode->inotify_sem);
+		put_inotify_watch(watch);
+	}
+
+	/* destroy all of the events on this device */
+	down(&dev->sem);
+	while (!list_empty(&dev->events))
+		inotify_dev_event_dequeue(dev);
+	up(&dev->sem);
+
+	/* free this device: the put matching the get in inotify_init() */
+	put_inotify_dev(dev);
+
+	return 0;
+}
+
+/*
+ * inotify_ignore - remove a given wd from this inotify instance.
+ *
+ * Can sleep.
+ */
+static int inotify_ignore(struct inotify_device *dev, s32 wd)
+{
+	struct inotify_watch *watch;
+	struct inode *inode;
+
+	down(&dev->sem);
+	watch = idr_find(&dev->idr, wd);
+	if (unlikely(!watch)) {
+		up(&dev->sem);
+		return -EINVAL;
+	}
+	get_inotify_watch(watch);
+	inode = watch->inode;
+	up(&dev->sem);
+
+	down(&inode->inotify_sem);
+	down(&dev->sem);
+
+	/* make sure that we did not race */
+	watch = idr_find(&dev->idr, wd);
+	if (likely(watch))
+		remove_watch(watch, dev);
+
+	up(&dev->sem);
+	up(&inode->inotify_sem);
+	put_inotify_watch(watch);
+
+	return 0;
+}
+
+static long inotify_ioctl(struct file *file, unsigned int cmd,
+			  unsigned long arg)
+{
+	struct inotify_device *dev;
+	void __user *p;
+	int ret = -ENOTTY;
+
+	dev = file->private_data;
+	p = (void __user *) arg;
+
+	switch (cmd) {
+	case FIONREAD:
+		ret = put_user(dev->queue_size, (int __user *) p);
+		break;
+	}
+
+	return ret;
+}
+
+static struct file_operations inotify_fops = {
+	.poll           = inotify_poll,
+	.read           = inotify_read,
+	.release        = inotify_release,
+	.unlocked_ioctl = inotify_ioctl,
+	.compat_ioctl	= inotify_ioctl,
+};
+
+asmlinkage long sys_inotify_init(void)
+{
+	struct inotify_device *dev;
+	struct user_struct *user;
+	struct file *filp;	
+	int fd, ret;
+
+	fd = get_unused_fd();
+	if (fd < 0)
+		return fd;
+
+	filp = get_empty_filp();
+	if (!filp) {
+		ret = -ENFILE;
+		goto out_put_fd;
+	}
+
+	user = get_uid(current->user);
+	if (unlikely(atomic_read(&user->inotify_devs) >=
+			inotify_max_user_instances)) {
+		ret = -EMFILE;
+		goto out_free_uid;
+	}
+
+	dev = kmalloc(sizeof(struct inotify_device), GFP_KERNEL);
+	if (unlikely(!dev)) {
+		ret = -ENOMEM;
+		goto out_free_uid;
+	}
+
+	filp->f_op = &inotify_fops;
+	filp->f_vfsmnt = mntget(inotify_mnt);
+	filp->f_dentry = dget(inotify_mnt->mnt_root);
+	filp->f_mapping = filp->f_dentry->d_inode->i_mapping;
+	filp->f_mode = FMODE_READ;
+	filp->f_flags = O_RDONLY;
+	filp->private_data = dev;
+
+	idr_init(&dev->idr);
+	INIT_LIST_HEAD(&dev->events);
+	INIT_LIST_HEAD(&dev->watches);
+	init_waitqueue_head(&dev->wq);
+	sema_init(&dev->sem, 1);
+	dev->event_count = 0;
+	dev->queue_size = 0;
+	dev->max_events = inotify_max_queued_events;
+	dev->user = user;
+	dev->last_wd = 0;
+	atomic_set(&dev->count, 0);
+
+	get_inotify_dev(dev);
+	atomic_inc(&user->inotify_devs);
+	fd_install(fd, filp);
+
+	return fd;
+out_free_uid:
+	free_uid(user);
+	put_filp(filp);
+out_put_fd:
+	put_unused_fd(fd);
+	return ret;
+}
+
+asmlinkage long sys_inotify_add_watch(int fd, const char __user *path, u32 mask)
+{
+	struct inotify_watch *watch, *old;
+	struct inode *inode;
+	struct inotify_device *dev;
+	struct nameidata nd;
+	struct file *filp;
+	int ret, fput_needed;
+
+	filp = fget_light(fd, &fput_needed);
+	if (unlikely(!filp))
+		return -EBADF;
+
+	/* verify that this is indeed an inotify instance */
+	if (unlikely(filp->f_op != &inotify_fops)) {
+		ret = -EINVAL;
+		goto fput_and_out;
+	}
+
+	ret = find_inode(path, &nd);
+	if (unlikely(ret))
+		goto fput_and_out;
+
+	/* inode held in place by reference to nd; dev by fget on fd */
+	inode = nd.dentry->d_inode;
+	dev = filp->private_data;
+
+	down(&inode->inotify_sem);
+	down(&dev->sem);
+
+	/* don't let user-space set invalid bits: we don't want flags set */
+	mask &= IN_ALL_EVENTS;
+	if (unlikely(!mask)) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	/*
+	 * Handle the case of re-adding a watch on an (inode,dev) pair that we
+	 * are already watching.  We just update the mask and return its wd.
+	 */
+	old = inode_find_dev(inode, dev);
+	if (unlikely(old)) {
+		old->mask = mask;
+		ret = old->wd;
+		goto out;
+	}
+
+	watch = create_watch(dev, mask, inode);
+	if (unlikely(IS_ERR(watch))) {
+		ret = PTR_ERR(watch);
+		goto out;
+	}
+
+	/* Add the watch to the device's and the inode's list */
+	list_add(&watch->d_list, &dev->watches);
+	list_add(&watch->i_list, &inode->inotify_watches);
+	ret = watch->wd;
+out:
+	up(&dev->sem);
+	up(&inode->inotify_sem);
+	path_release(&nd);
+fput_and_out:
+	fput_light(filp, fput_needed);
+	return ret;
+}
+
+asmlinkage long sys_inotify_rm_watch(int fd, u32 wd)
+{
+	struct file *filp;
+	struct inotify_device *dev;
+	int ret, fput_needed;
+
+	filp = fget_light(fd, &fput_needed);
+	if (unlikely(!filp))
+		return -EBADF;
+
+	/* verify that this is indeed an inotify instance */
+	if (unlikely(filp->f_op != &inotify_fops)) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	dev = filp->private_data;
+	ret = inotify_ignore(dev, wd);
+
+out:
+	fput_light(filp, fput_needed);
+	return ret;
+}
+
+static struct super_block *
+inotify_get_sb(struct file_system_type *fs_type, int flags,
+	       const char *dev_name, void *data)
+{
+    return get_sb_pseudo(fs_type, "inotify", NULL, 0xBAD1DEA);
+}
+
+static struct file_system_type inotify_fs_type = {
+    .name           = "inotifyfs",
+    .get_sb         = inotify_get_sb,
+    .kill_sb        = kill_anon_super,
+};
+
+/*
+ * inotify_setup - Our initialization function.  Note that we cannnot return
+ * error because we have compiled-in VFS hooks.  So an (unlikely) failure here
+ * must result in panic().
+ */
+static int __init inotify_setup(void)
+{
+	int ret;
+
+	ret = register_filesystem(&inotify_fs_type);
+	if (unlikely(ret))
+		panic("inotify: register_filesystem returned %d!\n", ret);
+
+	inotify_mnt = kern_mount(&inotify_fs_type);
+	if (IS_ERR(inotify_mnt))
+		panic("inotify: kern_mount ret %ld!\n", PTR_ERR(inotify_mnt));
+
+	inotify_max_queued_events = 16384;
+	inotify_max_user_instances = 128;
+	inotify_max_user_watches = 8192;
+
+	atomic_set(&inotify_cookie, 0);
+
+	watch_cachep = kmem_cache_create("inotify_watch_cache",
+					 sizeof(struct inotify_watch),
+					 0, SLAB_PANIC, NULL, NULL);
+	event_cachep = kmem_cache_create("inotify_event_cache",
+					 sizeof(struct inotify_kernel_event),
+					 0, SLAB_PANIC, NULL, NULL);
+
+	return 0;
+}
+
+module_init(inotify_setup);
diff --git a/fs/ioprio.c b/fs/ioprio.c
new file mode 100644
--- /dev/null
+++ b/fs/ioprio.c
@@ -0,0 +1,174 @@
+/*
+ * fs/ioprio.c
+ *
+ * Copyright (C) 2004 Jens Axboe <axboe@suse.de>
+ *
+ * Helper functions for setting/querying io priorities of processes. The
+ * system calls closely mimmick getpriority/setpriority, see the man page for
+ * those. The prio argument is a composite of prio class and prio data, where
+ * the data argument has meaning within that class. The standard scheduling
+ * classes have 8 distinct prio levels, with 0 being the highest prio and 7
+ * being the lowest.
+ *
+ * IOW, setting BE scheduling class with prio 2 is done ala:
+ *
+ * unsigned int prio = (IOPRIO_CLASS_BE << IOPRIO_CLASS_SHIFT) | 2;
+ *
+ * ioprio_set(PRIO_PROCESS, pid, prio);
+ *
+ * See also Documentation/block/ioprio.txt
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/ioprio.h>
+#include <linux/blkdev.h>
+
+static int set_task_ioprio(struct task_struct *task, int ioprio)
+{
+	struct io_context *ioc;
+
+	if (task->uid != current->euid &&
+	    task->uid != current->uid && !capable(CAP_SYS_NICE))
+		return -EPERM;
+
+	task_lock(task);
+
+	task->ioprio = ioprio;
+
+	ioc = task->io_context;
+	if (ioc && ioc->set_ioprio)
+		ioc->set_ioprio(ioc, ioprio);
+
+	task_unlock(task);
+	return 0;
+}
+
+asmlinkage long sys_ioprio_set(int which, int who, int ioprio)
+{
+	int class = IOPRIO_PRIO_CLASS(ioprio);
+	int data = IOPRIO_PRIO_DATA(ioprio);
+	struct task_struct *p, *g;
+	struct user_struct *user;
+	int ret;
+
+	switch (class) {
+		case IOPRIO_CLASS_RT:
+			if (!capable(CAP_SYS_ADMIN))
+				return -EPERM;
+			/* fall through, rt has prio field too */
+		case IOPRIO_CLASS_BE:
+			if (data >= IOPRIO_BE_NR || data < 0)
+				return -EINVAL;
+
+			break;
+		case IOPRIO_CLASS_IDLE:
+			if (!capable(CAP_SYS_ADMIN))
+				return -EPERM;
+			break;
+		default:
+			return -EINVAL;
+	}
+
+	ret = -ESRCH;
+	read_lock_irq(&tasklist_lock);
+	switch (which) {
+		case IOPRIO_WHO_PROCESS:
+			if (!who)
+				p = current;
+			else
+				p = find_task_by_pid(who);
+			if (p)
+				ret = set_task_ioprio(p, ioprio);
+			break;
+		case IOPRIO_WHO_PGRP:
+			if (!who)
+				who = process_group(current);
+			do_each_task_pid(who, PIDTYPE_PGID, p) {
+				ret = set_task_ioprio(p, ioprio);
+				if (ret)
+					break;
+			} while_each_task_pid(who, PIDTYPE_PGID, p);
+			break;
+		case IOPRIO_WHO_USER:
+			if (!who)
+				user = current->user;
+			else
+				user = find_user(who);
+
+			if (!user)
+				break;
+
+			do_each_thread(g, p) {
+				if (p->uid != who)
+					continue;
+				ret = set_task_ioprio(p, ioprio);
+				if (ret)
+					break;
+			} while_each_thread(g, p);
+
+			if (who)
+				free_uid(user);
+			break;
+		default:
+			ret = -EINVAL;
+	}
+
+	read_unlock_irq(&tasklist_lock);
+	return ret;
+}
+
+asmlinkage long sys_ioprio_get(int which, int who)
+{
+	struct task_struct *g, *p;
+	struct user_struct *user;
+	int ret = -ESRCH;
+
+	read_lock_irq(&tasklist_lock);
+	switch (which) {
+		case IOPRIO_WHO_PROCESS:
+			if (!who)
+				p = current;
+			else
+				p = find_task_by_pid(who);
+			if (p)
+				ret = p->ioprio;
+			break;
+		case IOPRIO_WHO_PGRP:
+			if (!who)
+				who = process_group(current);
+			do_each_task_pid(who, PIDTYPE_PGID, p) {
+				if (ret == -ESRCH)
+					ret = p->ioprio;
+				else
+					ret = ioprio_best(ret, p->ioprio);
+			} while_each_task_pid(who, PIDTYPE_PGID, p);
+			break;
+		case IOPRIO_WHO_USER:
+			if (!who)
+				user = current->user;
+			else
+				user = find_user(who);
+
+			if (!user)
+				break;
+
+			do_each_thread(g, p) {
+				if (p->uid != user->uid)
+					continue;
+				if (ret == -ESRCH)
+					ret = p->ioprio;
+				else
+					ret = ioprio_best(ret, p->ioprio);
+			} while_each_thread(g, p);
+
+			if (who)
+				free_uid(user);
+			break;
+		default:
+			ret = -EINVAL;
+	}
+
+	read_unlock_irq(&tasklist_lock);
+	return ret;
+}
+
diff --git a/fs/isofs/compress.c b/fs/isofs/compress.c
--- a/fs/isofs/compress.c
+++ b/fs/isofs/compress.c
@@ -129,8 +129,14 @@ static int zisofs_readpage(struct file *
 	cend = le32_to_cpu(*(__le32 *)(bh->b_data + (blockendptr & bufmask)));
 	brelse(bh);
 
+	if (cstart > cend)
+		goto eio;
+		
 	csize = cend-cstart;
 
+	if (csize > deflateBound(1UL << zisofs_block_shift))
+		goto eio;
+
 	/* Now page[] contains an array of pages, any of which can be NULL,
 	   and the locks on which we hold.  We should now read the data and
 	   release the pages.  If the pages are NULL the decompressed data
diff --git a/fs/isofs/dir.c b/fs/isofs/dir.c
--- a/fs/isofs/dir.c
+++ b/fs/isofs/dir.c
@@ -193,12 +193,17 @@ static int do_isofs_readdir(struct inode
 
 		/* Handle everything else.  Do name translation if there
 		   is no Rock Ridge NM field. */
-		if (sbi->s_unhide == 'n') {
-			/* Do not report hidden or associated files */
-			if (de->flags[-sbi->s_high_sierra] & 5) {
-				filp->f_pos += de_len;
-				continue;
-			}
+
+		/*
+		 * Do not report hidden files if so instructed, or associated
+		 * files unless instructed to do so
+		 */
+		if ((sbi->s_hide == 'y' &&
+				(de->flags[-sbi->s_high_sierra] & 1)) ||
+		      (sbi->s_showassoc =='n' &&
+				(de->flags[-sbi->s_high_sierra] & 4))) {
+			filp->f_pos += de_len;
+			continue;
 		}
 
 		map = 1;
diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c
--- a/fs/isofs/inode.c
+++ b/fs/isofs/inode.c
@@ -28,11 +28,6 @@
 
 #define BEQUIET
 
-#ifdef LEAK_CHECK
-static int check_malloc;
-static int check_bread;
-#endif
-
 static int isofs_hashi(struct dentry *parent, struct qstr *qstr);
 static int isofs_hash(struct dentry *parent, struct qstr *qstr);
 static int isofs_dentry_cmpi(struct dentry *dentry, struct qstr *a, struct qstr *b);
@@ -55,11 +50,6 @@ static void isofs_put_super(struct super
 	}
 #endif
 
-#ifdef LEAK_CHECK
-	printk("Outstanding mallocs:%d, outstanding buffers: %d\n",
-	       check_malloc, check_bread);
-#endif
-
 	kfree(sbi);
 	sb->s_fs_info = NULL;
 	return;
@@ -73,7 +63,7 @@ static kmem_cache_t *isofs_inode_cachep;
 static struct inode *isofs_alloc_inode(struct super_block *sb)
 {
 	struct iso_inode_info *ei;
-	ei = (struct iso_inode_info *)kmem_cache_alloc(isofs_inode_cachep, SLAB_KERNEL);
+	ei = kmem_cache_alloc(isofs_inode_cachep, SLAB_KERNEL);
 	if (!ei)
 		return NULL;
 	return &ei->vfs_inode;
@@ -84,9 +74,9 @@ static void isofs_destroy_inode(struct i
 	kmem_cache_free(isofs_inode_cachep, ISOFS_I(inode));
 }
 
-static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags)
+static void init_once(void *foo, kmem_cache_t * cachep, unsigned long flags)
 {
-	struct iso_inode_info *ei = (struct iso_inode_info *) foo;
+	struct iso_inode_info *ei = foo;
 
 	if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
 	    SLAB_CTOR_CONSTRUCTOR)
@@ -107,7 +97,8 @@ static int init_inodecache(void)
 static void destroy_inodecache(void)
 {
 	if (kmem_cache_destroy(isofs_inode_cachep))
-		printk(KERN_INFO "iso_inode_cache: not all structures were freed\n");
+		printk(KERN_INFO "iso_inode_cache: not all structures were "
+					"freed\n");
 }
 
 static int isofs_remount(struct super_block *sb, int *flags, char *data)
@@ -144,7 +135,7 @@ static struct dentry_operations isofs_de
 	{
 		.d_hash		= isofs_hashi_ms,
 		.d_compare	= isofs_dentry_cmpi_ms,
-	}
+	},
 #endif
 };
 
@@ -153,7 +144,8 @@ struct iso9660_options{
 	char rock;
 	char joliet;
 	char cruft;
-	char unhide;
+	char hide;
+	char showassoc;
 	char nocompress;
 	unsigned char check;
 	unsigned int blocksize;
@@ -219,8 +211,8 @@ isofs_hashi_common(struct dentry *dentry
 /*
  * Case insensitive compare of two isofs names.
  */
-static int
-isofs_dentry_cmpi_common(struct dentry *dentry,struct qstr *a,struct qstr *b,int ms)
+static int isofs_dentry_cmpi_common(struct dentry *dentry, struct qstr *a,
+				struct qstr *b, int ms)
 {
 	int alen, blen;
 
@@ -243,8 +235,8 @@ isofs_dentry_cmpi_common(struct dentry *
 /*
  * Case sensitive compare of two isofs names.
  */
-static int
-isofs_dentry_cmp_common(struct dentry *dentry,struct qstr *a,struct qstr *b,int ms)
+static int isofs_dentry_cmp_common(struct dentry *dentry, struct qstr *a,
+					struct qstr *b, int ms)
 {
 	int alen, blen;
 
@@ -318,13 +310,15 @@ enum {
 	Opt_block, Opt_check_r, Opt_check_s, Opt_cruft, Opt_gid, Opt_ignore,
 	Opt_iocharset, Opt_map_a, Opt_map_n, Opt_map_o, Opt_mode, Opt_nojoliet,
 	Opt_norock, Opt_sb, Opt_session, Opt_uid, Opt_unhide, Opt_utf8, Opt_err,
-	Opt_nocompress,
+	Opt_nocompress, Opt_hide, Opt_showassoc,
 };
 
 static match_table_t tokens = {
 	{Opt_norock, "norock"},
 	{Opt_nojoliet, "nojoliet"},
 	{Opt_unhide, "unhide"},
+	{Opt_hide, "hide"},
+	{Opt_showassoc, "showassoc"},
 	{Opt_cruft, "cruft"},
 	{Opt_utf8, "utf8"},
 	{Opt_iocharset, "iocharset=%s"},
@@ -356,7 +350,7 @@ static match_table_t tokens = {
 	{Opt_err, NULL}
 };
 
-static int parse_options(char *options, struct iso9660_options * popt)
+static int parse_options(char *options, struct iso9660_options *popt)
 {
 	char *p;
 	int option;
@@ -365,7 +359,8 @@ static int parse_options(char *options, 
 	popt->rock = 'y';
 	popt->joliet = 'y';
 	popt->cruft = 'n';
-	popt->unhide = 'n';
+	popt->hide = 'n';
+	popt->showassoc = 'n';
 	popt->check = 'u';		/* unset */
 	popt->nocompress = 0;
 	popt->blocksize = 1024;
@@ -398,8 +393,12 @@ static int parse_options(char *options, 
 		case Opt_nojoliet:
 			popt->joliet = 'n';
 			break;
+		case Opt_hide:
+			popt->hide = 'y';
+			break;
 		case Opt_unhide:
-			popt->unhide = 'y';
+		case Opt_showassoc:
+			popt->showassoc = 'y';
 			break;
 		case Opt_cruft:
 			popt->cruft = 'y';
@@ -493,7 +492,7 @@ static int parse_options(char *options, 
  */
 #define WE_OBEY_THE_WRITTEN_STANDARDS 1
 
-static unsigned int isofs_get_last_session(struct super_block *sb,s32 session )
+static unsigned int isofs_get_last_session(struct super_block *sb, s32 session)
 {
 	struct cdrom_multisession ms_info;
 	unsigned int vol_desc_start;
@@ -518,7 +517,8 @@ static unsigned int isofs_get_last_sessi
 		printk(KERN_ERR "Invalid session number or type of track\n");
 	}
 	i = ioctl_by_bdev(bdev, CDROMMULTISESSION, (unsigned long) &ms_info);
-	if(session > 0) printk(KERN_ERR "Invalid session number\n");
+	if (session > 0)
+		printk(KERN_ERR "Invalid session number\n");
 #if 0
 	printk("isofs.inode: CDROMMULTISESSION: rc=%d\n",i);
 	if (i==0) {
@@ -557,13 +557,13 @@ static int isofs_fill_super(struct super
 	struct iso9660_options		opt;
 	struct isofs_sb_info	      * sbi;
 
-	sbi = kmalloc(sizeof(struct isofs_sb_info), GFP_KERNEL);
+	sbi = kmalloc(sizeof(*sbi), GFP_KERNEL);
 	if (!sbi)
 		return -ENOMEM;
 	s->s_fs_info = sbi;
-	memset(sbi, 0, sizeof(struct isofs_sb_info));
+	memset(sbi, 0, sizeof(*sbi));
 
-	if (!parse_options((char *) data, &opt))
+	if (!parse_options((char *)data, &opt))
 		goto out_freesbi;
 
 	/*
@@ -792,7 +792,8 @@ root_found:
 	sbi->s_rock = (opt.rock == 'y' ? 2 : 0);
 	sbi->s_rock_offset = -1; /* initial offset, will guess until SP is found*/
 	sbi->s_cruft = opt.cruft;
-	sbi->s_unhide = opt.unhide;
+	sbi->s_hide = opt.hide;
+	sbi->s_showassoc = opt.showassoc;
 	sbi->s_uid = opt.uid;
 	sbi->s_gid = opt.gid;
 	sbi->s_utf8 = opt.utf8;
@@ -1002,7 +1003,6 @@ int isofs_get_blocks(struct inode *inode
 		rv++;
 	}
 
-
 abort:
 	unlock_kernel();
 	return rv;
@@ -1014,7 +1014,7 @@ abort:
 static int isofs_get_block(struct inode *inode, sector_t iblock,
 		    struct buffer_head *bh_result, int create)
 {
-	if ( create ) {
+	if (create) {
 		printk("isofs_get_block: Kernel tries to allocate a block\n");
 		return -EROFS;
 	}
@@ -1061,19 +1061,17 @@ static struct address_space_operations i
 
 static inline void test_and_set_uid(uid_t *p, uid_t value)
 {
-	if(value) {
+	if (value)
 		*p = value;
-	}
 }
 
 static inline void test_and_set_gid(gid_t *p, gid_t value)
 {
-        if(value) {
+        if (value)
                 *p = value;
-        }
 }
 
-static int isofs_read_level3_size(struct inode * inode)
+static int isofs_read_level3_size(struct inode *inode)
 {
 	unsigned long bufsize = ISOFS_BUFFER_SIZE(inode);
 	int high_sierra = ISOFS_SB(inode->i_sb)->s_high_sierra;
@@ -1136,7 +1134,7 @@ static int isofs_read_level3_size(struct
 				bh = sb_bread(inode->i_sb, block);
 				if (!bh)
 					goto out_noread;
-				memcpy((void *) tmpde + slop, bh->b_data, offset);
+				memcpy((void *)tmpde+slop, bh->b_data, offset);
 			}
 			de = tmpde;
 		}
@@ -1150,12 +1148,11 @@ static int isofs_read_level3_size(struct
 		more_entries = de->flags[-high_sierra] & 0x80;
 
 		i++;
-		if(i > 100)
+		if (i > 100)
 			goto out_toomany;
-	} while(more_entries);
+	} while (more_entries);
 out:
-	if (tmpde)
-		kfree(tmpde);
+	kfree(tmpde);
 	if (bh)
 		brelse(bh);
 	return 0;
@@ -1179,7 +1176,7 @@ out_toomany:
 	goto out;
 }
 
-static void isofs_read_inode(struct inode * inode)
+static void isofs_read_inode(struct inode *inode)
 {
 	struct super_block *sb = inode->i_sb;
 	struct isofs_sb_info *sbi = ISOFS_SB(sb);
@@ -1249,7 +1246,7 @@ static void isofs_read_inode(struct inod
 	ei->i_format_parm[2] = 0;
 
 	ei->i_section_size = isonum_733 (de->size);
-	if(de->flags[-high_sierra] & 0x80) {
+	if (de->flags[-high_sierra] & 0x80) {
 		if(isofs_read_level3_size(inode)) goto fail;
 	} else {
 		ei->i_next_section_block = 0;
@@ -1336,16 +1333,16 @@ static void isofs_read_inode(struct inod
 		/* XXX - parse_rock_ridge_inode() had already set i_rdev. */
 		init_special_inode(inode, inode->i_mode, inode->i_rdev);
 
- out:
+out:
 	if (tmpde)
 		kfree(tmpde);
 	if (bh)
 		brelse(bh);
 	return;
 
- out_badread:
+out_badread:
 	printk(KERN_WARNING "ISOFS: unable to read i-node block\n");
- fail:
+fail:
 	make_bad_inode(inode);
 	goto out;
 }
@@ -1394,11 +1391,8 @@ struct inode *isofs_iget(struct super_bl
 
 	hashval = (block << sb->s_blocksize_bits) | offset;
 
-	inode = iget5_locked(sb,
-			     hashval,
-			     &isofs_iget5_test,
-			     &isofs_iget5_set,
-			     &data);
+	inode = iget5_locked(sb, hashval, &isofs_iget5_test,
+			     &isofs_iget5_set, &data);
 
 	if (inode && (inode->i_state & I_NEW)) {
 		sb->s_op->read_inode(inode);
@@ -1408,36 +1402,6 @@ struct inode *isofs_iget(struct super_bl
 	return inode;
 }
 
-#ifdef LEAK_CHECK
-#undef malloc
-#undef free_s
-#undef sb_bread
-#undef brelse
-
-void * leak_check_malloc(unsigned int size){
-  void * tmp;
-  check_malloc++;
-  tmp = kmalloc(size, GFP_KERNEL);
-  return tmp;
-}
-
-void leak_check_free_s(void * obj, int size){
-  check_malloc--;
-  return kfree(obj);
-}
-
-struct buffer_head * leak_check_bread(struct super_block *sb, int block){
-  check_bread++;
-  return sb_bread(sb, block);
-}
-
-void leak_check_brelse(struct buffer_head * bh){
-  check_bread--;
-  return brelse(bh);
-}
-
-#endif
-
 static struct super_block *isofs_get_sb(struct file_system_type *fs_type,
 	int flags, const char *dev_name, void *data)
 {
diff --git a/fs/isofs/isofs.h b/fs/isofs/isofs.h
--- a/fs/isofs/isofs.h
+++ b/fs/isofs/isofs.h
@@ -47,6 +47,8 @@ struct isofs_sb_info {
 	unsigned char s_nosuid;
 	unsigned char s_nodev;
 	unsigned char s_nocompress;
+	unsigned char s_hide;
+	unsigned char s_showassoc;
 
 	mode_t s_mode;
 	gid_t s_gid;
diff --git a/fs/isofs/namei.c b/fs/isofs/namei.c
--- a/fs/isofs/namei.c
+++ b/fs/isofs/namei.c
@@ -131,14 +131,16 @@ isofs_find_entry(struct inode *dir, stru
 		}
 
 		/*
-		 * Skip hidden or associated files unless unhide is set 
+		 * Skip hidden or associated files unless hide or showassoc,
+		 * respectively, is set
 		 */
 		match = 0;
 		if (dlen > 0 &&
-		    (!(de->flags[-sbi->s_high_sierra] & 5)
-		     || sbi->s_unhide == 'y'))
-		{
-			match = (isofs_cmp(dentry,dpnt,dlen) == 0);
+			(sbi->s_hide =='n' ||
+				(!(de->flags[-sbi->s_high_sierra] & 1))) &&
+			(sbi->s_showassoc =='y' ||
+				(!(de->flags[-sbi->s_high_sierra] & 4)))) {
+			match = (isofs_cmp(dentry, dpnt, dlen) == 0);
 		}
 		if (match) {
 			isofs_normalize_block_and_offset(de,
@@ -146,11 +148,11 @@ isofs_find_entry(struct inode *dir, stru
 							 &offset_saved);
                         *block_rv = block_saved;
                         *offset_rv = offset_saved;
-			if (bh) brelse(bh);
+			brelse(bh);
 			return 1;
 		}
 	}
-	if (bh) brelse(bh);
+	brelse(bh);
 	return 0;
 }
 
diff --git a/fs/isofs/rock.c b/fs/isofs/rock.c
--- a/fs/isofs/rock.c
+++ b/fs/isofs/rock.c
@@ -13,352 +13,542 @@
 #include "isofs.h"
 #include "rock.h"
 
-/* These functions are designed to read the system areas of a directory record
+/*
+ * These functions are designed to read the system areas of a directory record
  * and extract relevant information.  There are different functions provided
  * depending upon what information we need at the time.  One function fills
  * out an inode structure, a second one extracts a filename, a third one
  * returns a symbolic link name, and a fourth one returns the extent number
- * for the file. */
+ * for the file.
+ */
 
-#define SIG(A,B) ((A) | ((B) << 8)) /* isonum_721() */
+#define SIG(A,B) ((A) | ((B) << 8))	/* isonum_721() */
 
+struct rock_state {
+	void *buffer;
+	unsigned char *chr;
+	int len;
+	int cont_size;
+	int cont_extent;
+	int cont_offset;
+	struct inode *inode;
+};
+
+/*
+ * This is a way of ensuring that we have something in the system
+ * use fields that is compatible with Rock Ridge.  Return zero on success.
+ */
 
-/* This is a way of ensuring that we have something in the system
-   use fields that is compatible with Rock Ridge */
-#define CHECK_SP(FAIL)	       			\
-      if(rr->u.SP.magic[0] != 0xbe) FAIL;	\
-      if(rr->u.SP.magic[1] != 0xef) FAIL;       \
-      ISOFS_SB(inode->i_sb)->s_rock_offset=rr->u.SP.skip;
-/* We define a series of macros because each function must do exactly the
-   same thing in certain places.  We use the macros to ensure that everything
-   is done correctly */
-
-#define CONTINUE_DECLS \
-  int cont_extent = 0, cont_offset = 0, cont_size = 0;   \
-  void *buffer = NULL
-
-#define CHECK_CE	       			\
-      {cont_extent = isonum_733(rr->u.CE.extent); \
-      cont_offset = isonum_733(rr->u.CE.offset); \
-      cont_size = isonum_733(rr->u.CE.size);}
-
-#define SETUP_ROCK_RIDGE(DE,CHR,LEN)	      		      	\
-  {LEN= sizeof(struct iso_directory_record) + DE->name_len[0];	\
-  if(LEN & 1) LEN++;						\
-  CHR = ((unsigned char *) DE) + LEN;				\
-  LEN = *((unsigned char *) DE) - LEN;                          \
-  if (LEN<0) LEN=0;                                             \
-  if (ISOFS_SB(inode->i_sb)->s_rock_offset!=-1)                \
-  {                                                             \
-     LEN-=ISOFS_SB(inode->i_sb)->s_rock_offset;                \
-     CHR+=ISOFS_SB(inode->i_sb)->s_rock_offset;                \
-     if (LEN<0) LEN=0;                                          \
-  }                                                             \
-}                                     
-
-#define MAYBE_CONTINUE(LABEL,DEV) \
-  {if (buffer) { kfree(buffer); buffer = NULL; } \
-  if (cont_extent){ \
-    int block, offset, offset1; \
-    struct buffer_head * pbh; \
-    buffer = kmalloc(cont_size,GFP_KERNEL); \
-    if (!buffer) goto out; \
-    block = cont_extent; \
-    offset = cont_offset; \
-    offset1 = 0; \
-    pbh = sb_bread(DEV->i_sb, block); \
-    if(pbh){       \
-      if (offset > pbh->b_size || offset + cont_size > pbh->b_size){	\
-	brelse(pbh); \
-	goto out; \
-      } \
-      memcpy(buffer + offset1, pbh->b_data + offset, cont_size - offset1); \
-      brelse(pbh); \
-      chr = (unsigned char *) buffer; \
-      len = cont_size; \
-      cont_extent = 0; \
-      cont_size = 0; \
-      cont_offset = 0; \
-      goto LABEL; \
-    }    \
-    printk("Unable to read rock-ridge attributes\n");    \
-  }}
-
-/* return length of name field; 0: not found, -1: to be ignored */
-int get_rock_ridge_filename(struct iso_directory_record * de,
-			    char * retname, struct inode * inode)
+static int check_sp(struct rock_ridge *rr, struct inode *inode)
 {
-  int len;
-  unsigned char * chr;
-  CONTINUE_DECLS;
-  int retnamlen = 0, truncate=0;
- 
-  if (!ISOFS_SB(inode->i_sb)->s_rock) return 0;
-  *retname = 0;
-
-  SETUP_ROCK_RIDGE(de, chr, len);
- repeat:
-  {
-    struct rock_ridge * rr;
-    int sig;
-    
-    while (len > 2){ /* There may be one byte for padding somewhere */
-      rr = (struct rock_ridge *) chr;
-      if (rr->len < 3) goto out; /* Something got screwed up here */
-      sig = isonum_721(chr);
-      chr += rr->len; 
-      len -= rr->len;
-      if (len < 0) goto out;	/* corrupted isofs */
-
-      switch(sig){
-      case SIG('R','R'):
-	if((rr->u.RR.flags[0] & RR_NM) == 0) goto out;
-	break;
-      case SIG('S','P'):
-	CHECK_SP(goto out);
-	break;
-      case SIG('C','E'):
-	CHECK_CE;
-	break;
-      case SIG('N','M'):
-	if (truncate) break;
-	if (rr->len < 5) break;
-        /*
-	 * If the flags are 2 or 4, this indicates '.' or '..'.
-	 * We don't want to do anything with this, because it
-	 * screws up the code that calls us.  We don't really
-	 * care anyways, since we can just use the non-RR
-	 * name.
-	 */
-	if (rr->u.NM.flags & 6) {
-	  break;
+	if (rr->u.SP.magic[0] != 0xbe)
+		return -1;
+	if (rr->u.SP.magic[1] != 0xef)
+		return -1;
+	ISOFS_SB(inode->i_sb)->s_rock_offset = rr->u.SP.skip;
+	return 0;
+}
+
+static void setup_rock_ridge(struct iso_directory_record *de,
+			struct inode *inode, struct rock_state *rs)
+{
+	rs->len = sizeof(struct iso_directory_record) + de->name_len[0];
+	if (rs->len & 1)
+		(rs->len)++;
+	rs->chr = (unsigned char *)de + rs->len;
+	rs->len = *((unsigned char *)de) - rs->len;
+	if (rs->len < 0)
+		rs->len = 0;
+
+	if (ISOFS_SB(inode->i_sb)->s_rock_offset != -1) {
+		rs->len -= ISOFS_SB(inode->i_sb)->s_rock_offset;
+		rs->chr += ISOFS_SB(inode->i_sb)->s_rock_offset;
+		if (rs->len < 0)
+			rs->len = 0;
+	}
+}
+
+static void init_rock_state(struct rock_state *rs, struct inode *inode)
+{
+	memset(rs, 0, sizeof(*rs));
+	rs->inode = inode;
+}
+
+/*
+ * Returns 0 if the caller should continue scanning, 1 if the scan must end
+ * and -ve on error.
+ */
+static int rock_continue(struct rock_state *rs)
+{
+	int ret = 1;
+	int blocksize = 1 << rs->inode->i_blkbits;
+	const int min_de_size = offsetof(struct rock_ridge, u);
+
+	kfree(rs->buffer);
+	rs->buffer = NULL;
+
+	if ((unsigned)rs->cont_offset > blocksize - min_de_size ||
+	    (unsigned)rs->cont_size > blocksize ||
+	    (unsigned)(rs->cont_offset + rs->cont_size) > blocksize) {
+		printk(KERN_NOTICE "rock: corrupted directory entry. "
+			"extent=%d, offset=%d, size=%d\n",
+			rs->cont_extent, rs->cont_offset, rs->cont_size);
+		ret = -EIO;
+		goto out;
+	}
+
+	if (rs->cont_extent) {
+		struct buffer_head *bh;
+
+		rs->buffer = kmalloc(rs->cont_size, GFP_KERNEL);
+		if (!rs->buffer) {
+			ret = -ENOMEM;
+			goto out;
+		}
+		ret = -EIO;
+		bh = sb_bread(rs->inode->i_sb, rs->cont_extent);
+		if (bh) {
+			memcpy(rs->buffer, bh->b_data + rs->cont_offset,
+					rs->cont_size);
+			put_bh(bh);
+			rs->chr = rs->buffer;
+			rs->len = rs->cont_size;
+			rs->cont_extent = 0;
+			rs->cont_size = 0;
+			rs->cont_offset = 0;
+			return 0;
+		}
+		printk("Unable to read rock-ridge attributes\n");
 	}
+out:
+	kfree(rs->buffer);
+	rs->buffer = NULL;
+	return ret;
+}
+
+/*
+ * We think there's a record of type `sig' at rs->chr.  Parse the signature
+ * and make sure that there's really room for a record of that type.
+ */
+static int rock_check_overflow(struct rock_state *rs, int sig)
+{
+	int len;
+
+	switch (sig) {
+	case SIG('S', 'P'):
+		len = sizeof(struct SU_SP_s);
+		break;
+	case SIG('C', 'E'):
+		len = sizeof(struct SU_CE_s);
+		break;
+	case SIG('E', 'R'):
+		len = sizeof(struct SU_ER_s);
+		break;
+	case SIG('R', 'R'):
+		len = sizeof(struct RR_RR_s);
+		break;
+	case SIG('P', 'X'):
+		len = sizeof(struct RR_PX_s);
+		break;
+	case SIG('P', 'N'):
+		len = sizeof(struct RR_PN_s);
+		break;
+	case SIG('S', 'L'):
+		len = sizeof(struct RR_SL_s);
+		break;
+	case SIG('N', 'M'):
+		len = sizeof(struct RR_NM_s);
+		break;
+	case SIG('C', 'L'):
+		len = sizeof(struct RR_CL_s);
+		break;
+	case SIG('P', 'L'):
+		len = sizeof(struct RR_PL_s);
+		break;
+	case SIG('T', 'F'):
+		len = sizeof(struct RR_TF_s);
+		break;
+	case SIG('Z', 'F'):
+		len = sizeof(struct RR_ZF_s);
+		break;
+	default:
+		len = 0;
+		break;
+	}
+	len += offsetof(struct rock_ridge, u);
+	if (len > rs->len) {
+		printk(KERN_NOTICE "rock: directory entry would overflow "
+				"storage\n");
+		printk(KERN_NOTICE "rock: sig=0x%02x, size=%d, remaining=%d\n",
+				sig, len, rs->len);
+		return -EIO;
+	}
+	return 0;
+}
 
-	if (rr->u.NM.flags & ~1) {
-	  printk("Unsupported NM flag settings (%d)\n",rr->u.NM.flags);
-	  break;
-	}
-	if((strlen(retname) + rr->len - 5) >= 254) {
-	  truncate = 1;
-	  break;
-	}
-	strncat(retname, rr->u.NM.name, rr->len - 5);
-	retnamlen += rr->len - 5;
-	break;
-      case SIG('R','E'):
-	if (buffer) kfree(buffer);
-	return -1;
-      default:
-	break;
-      }
-    }
-  }
-  MAYBE_CONTINUE(repeat,inode);
-  if (buffer) kfree(buffer);
-  return retnamlen; /* If 0, this file did not have a NM field */
- out:
-  if(buffer) kfree(buffer);
-  return 0;
+/*
+ * return length of name field; 0: not found, -1: to be ignored
+ */
+int get_rock_ridge_filename(struct iso_directory_record *de,
+			    char *retname, struct inode *inode)
+{
+	struct rock_state rs;
+	struct rock_ridge *rr;
+	int sig;
+	int retnamlen = 0;
+	int truncate = 0;
+	int ret = 0;
+
+	if (!ISOFS_SB(inode->i_sb)->s_rock)
+		return 0;
+	*retname = 0;
+
+	init_rock_state(&rs, inode);
+	setup_rock_ridge(de, inode, &rs);
+repeat:
+
+	while (rs.len > 2) { /* There may be one byte for padding somewhere */
+		rr = (struct rock_ridge *)rs.chr;
+		if (rr->len < 3)
+			goto out;	/* Something got screwed up here */
+		sig = isonum_721(rs.chr);
+		if (rock_check_overflow(&rs, sig))
+			goto eio;
+		rs.chr += rr->len;
+		rs.len -= rr->len;
+		if (rs.len < 0)
+			goto eio;	/* corrupted isofs */
+
+		switch (sig) {
+		case SIG('R', 'R'):
+			if ((rr->u.RR.flags[0] & RR_NM) == 0)
+				goto out;
+			break;
+		case SIG('S', 'P'):
+			if (check_sp(rr, inode))
+				goto out;
+			break;
+		case SIG('C', 'E'):
+			rs.cont_extent = isonum_733(rr->u.CE.extent);
+			rs.cont_offset = isonum_733(rr->u.CE.offset);
+			rs.cont_size = isonum_733(rr->u.CE.size);
+			break;
+		case SIG('N', 'M'):
+			if (truncate)
+				break;
+			if (rr->len < 5)
+				break;
+			/*
+			 * If the flags are 2 or 4, this indicates '.' or '..'.
+			 * We don't want to do anything with this, because it
+			 * screws up the code that calls us.  We don't really
+			 * care anyways, since we can just use the non-RR
+			 * name.
+			 */
+			if (rr->u.NM.flags & 6)
+				break;
+
+			if (rr->u.NM.flags & ~1) {
+				printk("Unsupported NM flag settings (%d)\n",
+					rr->u.NM.flags);
+				break;
+			}
+			if ((strlen(retname) + rr->len - 5) >= 254) {
+				truncate = 1;
+				break;
+			}
+			strncat(retname, rr->u.NM.name, rr->len - 5);
+			retnamlen += rr->len - 5;
+			break;
+		case SIG('R', 'E'):
+			kfree(rs.buffer);
+			return -1;
+		default:
+			break;
+		}
+	}
+	ret = rock_continue(&rs);
+	if (ret == 0)
+		goto repeat;
+	if (ret == 1)
+		return retnamlen; /* If 0, this file did not have a NM field */
+out:
+	kfree(rs.buffer);
+	return ret;
+eio:
+	ret = -EIO;
+	goto out;
 }
 
 static int
 parse_rock_ridge_inode_internal(struct iso_directory_record *de,
 				struct inode *inode, int regard_xa)
 {
-  int len;
-  unsigned char * chr;
-  int symlink_len = 0;
-  CONTINUE_DECLS;
-
-  if (!ISOFS_SB(inode->i_sb)->s_rock) return 0;
-
-  SETUP_ROCK_RIDGE(de, chr, len);
-  if (regard_xa)
-   {
-     chr+=14;
-     len-=14;
-     if (len<0) len=0;
-   }
-   
- repeat:
-  {
-    int cnt, sig;
-    struct inode * reloc;
-    struct rock_ridge * rr;
-    int rootflag;
-    
-    while (len > 2){ /* There may be one byte for padding somewhere */
-      rr = (struct rock_ridge *) chr;
-      if (rr->len < 3) goto out; /* Something got screwed up here */
-      sig = isonum_721(chr);
-      chr += rr->len; 
-      len -= rr->len;
-      if (len < 0) goto out;	/* corrupted isofs */
-      
-      switch(sig){
+	int symlink_len = 0;
+	int cnt, sig;
+	struct inode *reloc;
+	struct rock_ridge *rr;
+	int rootflag;
+	struct rock_state rs;
+	int ret = 0;
+
+	if (!ISOFS_SB(inode->i_sb)->s_rock)
+		return 0;
+
+	init_rock_state(&rs, inode);
+	setup_rock_ridge(de, inode, &rs);
+	if (regard_xa) {
+		rs.chr += 14;
+		rs.len -= 14;
+		if (rs.len < 0)
+			rs.len = 0;
+	}
+
+repeat:
+	while (rs.len > 2) { /* There may be one byte for padding somewhere */
+		rr = (struct rock_ridge *)rs.chr;
+		if (rr->len < 3)
+			goto out;	/* Something got screwed up here */
+		sig = isonum_721(rs.chr);
+		if (rock_check_overflow(&rs, sig))
+			goto eio;
+		rs.chr += rr->len;
+		rs.len -= rr->len;
+		if (rs.len < 0)
+			goto eio;	/* corrupted isofs */
+
+		switch (sig) {
 #ifndef CONFIG_ZISOFS		/* No flag for SF or ZF */
-      case SIG('R','R'):
-	if((rr->u.RR.flags[0] & 
- 	    (RR_PX | RR_TF | RR_SL | RR_CL)) == 0) goto out;
-	break;
+		case SIG('R', 'R'):
+			if ((rr->u.RR.flags[0] &
+			     (RR_PX | RR_TF | RR_SL | RR_CL)) == 0)
+				goto out;
+			break;
 #endif
-      case SIG('S','P'):
-	CHECK_SP(goto out);
-	break;
-      case SIG('C','E'):
-	CHECK_CE;
-	break;
-      case SIG('E','R'):
-	ISOFS_SB(inode->i_sb)->s_rock = 1;
-	printk(KERN_DEBUG "ISO 9660 Extensions: ");
-	{ int p;
-	  for(p=0;p<rr->u.ER.len_id;p++) printk("%c",rr->u.ER.data[p]);
-	}
-	  printk("\n");
-	break;
-      case SIG('P','X'):
-	inode->i_mode  = isonum_733(rr->u.PX.mode);
-	inode->i_nlink = isonum_733(rr->u.PX.n_links);
-	inode->i_uid   = isonum_733(rr->u.PX.uid);
-	inode->i_gid   = isonum_733(rr->u.PX.gid);
-	break;
-      case SIG('P','N'):
-	{ int high, low;
-	  high = isonum_733(rr->u.PN.dev_high);
-	  low = isonum_733(rr->u.PN.dev_low);
-	  /*
-	   * The Rock Ridge standard specifies that if sizeof(dev_t) <= 4,
-	   * then the high field is unused, and the device number is completely
-	   * stored in the low field.  Some writers may ignore this subtlety,
-	   * and as a result we test to see if the entire device number is
-	   * stored in the low field, and use that.
-	   */
-	  if((low & ~0xff) && high == 0) {
-	    inode->i_rdev = MKDEV(low >> 8, low & 0xff);
-	  } else {
-	    inode->i_rdev = MKDEV(high, low);
-	  }
-	}
-	break;
-      case SIG('T','F'):
-	/* Some RRIP writers incorrectly place ctime in the TF_CREATE field.
-	   Try to handle this correctly for either case. */
-	cnt = 0; /* Rock ridge never appears on a High Sierra disk */
-	if(rr->u.TF.flags & TF_CREATE) { 
-	  inode->i_ctime.tv_sec = iso_date(rr->u.TF.times[cnt++].time, 0);
-	  inode->i_ctime.tv_nsec = 0;
-	}
-	if(rr->u.TF.flags & TF_MODIFY) {
-	  inode->i_mtime.tv_sec = iso_date(rr->u.TF.times[cnt++].time, 0);
-	  inode->i_mtime.tv_nsec = 0;
-	}
-	if(rr->u.TF.flags & TF_ACCESS) {
-	  inode->i_atime.tv_sec = iso_date(rr->u.TF.times[cnt++].time, 0);
-	  inode->i_atime.tv_nsec = 0;
-	}
-	if(rr->u.TF.flags & TF_ATTRIBUTES) { 
-	  inode->i_ctime.tv_sec = iso_date(rr->u.TF.times[cnt++].time, 0);
-	  inode->i_ctime.tv_nsec = 0;
-	} 
-	break;
-      case SIG('S','L'):
-	{int slen;
-	 struct SL_component * slp;
-	 struct SL_component * oldslp;
-	 slen = rr->len - 5;
-	 slp = &rr->u.SL.link;
-	 inode->i_size = symlink_len;
-	 while (slen > 1){
-	   rootflag = 0;
-	   switch(slp->flags &~1){
-	   case 0:
-	     inode->i_size += slp->len;
-	     break;
-	   case 2:
-	     inode->i_size += 1;
-	     break;
-	   case 4:
-	     inode->i_size += 2;
-	     break;
-	   case 8:
-	     rootflag = 1;
-	     inode->i_size += 1;
-	     break;
-	   default:
-	     printk("Symlink component flag not implemented\n");
-	   }
-	   slen -= slp->len + 2;
-	   oldslp = slp;
-	   slp = (struct SL_component *) (((char *) slp) + slp->len + 2);
-
-	   if(slen < 2) {
-	     if(    ((rr->u.SL.flags & 1) != 0) 
-		    && ((oldslp->flags & 1) == 0) ) inode->i_size += 1;
-	     break;
-	   }
-
-	   /*
-	    * If this component record isn't continued, then append a '/'.
-	    */
-	   if (!rootflag && (oldslp->flags & 1) == 0)
-		   inode->i_size += 1;
-	 }
-	}
-	symlink_len = inode->i_size;
-	break;
-      case SIG('R','E'):
-	printk(KERN_WARNING "Attempt to read inode for relocated directory\n");
-	goto out;
-      case SIG('C','L'):
-	ISOFS_I(inode)->i_first_extent = isonum_733(rr->u.CL.location);
-	reloc = isofs_iget(inode->i_sb, ISOFS_I(inode)->i_first_extent, 0);
-	if (!reloc)
-		goto out;
-	inode->i_mode = reloc->i_mode;
-	inode->i_nlink = reloc->i_nlink;
-	inode->i_uid = reloc->i_uid;
-	inode->i_gid = reloc->i_gid;
-	inode->i_rdev = reloc->i_rdev;
-	inode->i_size = reloc->i_size;
-	inode->i_blocks = reloc->i_blocks;
-	inode->i_atime = reloc->i_atime;
-	inode->i_ctime = reloc->i_ctime;
-	inode->i_mtime = reloc->i_mtime;
-	iput(reloc);
-	break;
+		case SIG('S', 'P'):
+			if (check_sp(rr, inode))
+				goto out;
+			break;
+		case SIG('C', 'E'):
+			rs.cont_extent = isonum_733(rr->u.CE.extent);
+			rs.cont_offset = isonum_733(rr->u.CE.offset);
+			rs.cont_size = isonum_733(rr->u.CE.size);
+			break;
+		case SIG('E', 'R'):
+			ISOFS_SB(inode->i_sb)->s_rock = 1;
+			printk(KERN_DEBUG "ISO 9660 Extensions: ");
+			{
+				int p;
+				for (p = 0; p < rr->u.ER.len_id; p++)
+					printk("%c", rr->u.ER.data[p]);
+			}
+			printk("\n");
+			break;
+		case SIG('P', 'X'):
+			inode->i_mode = isonum_733(rr->u.PX.mode);
+			inode->i_nlink = isonum_733(rr->u.PX.n_links);
+			inode->i_uid = isonum_733(rr->u.PX.uid);
+			inode->i_gid = isonum_733(rr->u.PX.gid);
+			break;
+		case SIG('P', 'N'):
+			{
+				int high, low;
+				high = isonum_733(rr->u.PN.dev_high);
+				low = isonum_733(rr->u.PN.dev_low);
+				/*
+				 * The Rock Ridge standard specifies that if
+				 * sizeof(dev_t) <= 4, then the high field is
+				 * unused, and the device number is completely
+				 * stored in the low field.  Some writers may
+				 * ignore this subtlety,
+				 * and as a result we test to see if the entire
+				 * device number is
+				 * stored in the low field, and use that.
+				 */
+				if ((low & ~0xff) && high == 0) {
+					inode->i_rdev =
+					    MKDEV(low >> 8, low & 0xff);
+				} else {
+					inode->i_rdev =
+					    MKDEV(high, low);
+				}
+			}
+			break;
+		case SIG('T', 'F'):
+			/*
+			 * Some RRIP writers incorrectly place ctime in the
+			 * TF_CREATE field. Try to handle this correctly for
+			 * either case.
+			 */
+			/* Rock ridge never appears on a High Sierra disk */
+			cnt = 0;
+			if (rr->u.TF.flags & TF_CREATE) {
+				inode->i_ctime.tv_sec =
+				    iso_date(rr->u.TF.times[cnt++].time,
+					     0);
+				inode->i_ctime.tv_nsec = 0;
+			}
+			if (rr->u.TF.flags & TF_MODIFY) {
+				inode->i_mtime.tv_sec =
+				    iso_date(rr->u.TF.times[cnt++].time,
+					     0);
+				inode->i_mtime.tv_nsec = 0;
+			}
+			if (rr->u.TF.flags & TF_ACCESS) {
+				inode->i_atime.tv_sec =
+				    iso_date(rr->u.TF.times[cnt++].time,
+					     0);
+				inode->i_atime.tv_nsec = 0;
+			}
+			if (rr->u.TF.flags & TF_ATTRIBUTES) {
+				inode->i_ctime.tv_sec =
+				    iso_date(rr->u.TF.times[cnt++].time,
+					     0);
+				inode->i_ctime.tv_nsec = 0;
+			}
+			break;
+		case SIG('S', 'L'):
+			{
+				int slen;
+				struct SL_component *slp;
+				struct SL_component *oldslp;
+				slen = rr->len - 5;
+				slp = &rr->u.SL.link;
+				inode->i_size = symlink_len;
+				while (slen > 1) {
+					rootflag = 0;
+					switch (slp->flags & ~1) {
+					case 0:
+						inode->i_size +=
+						    slp->len;
+						break;
+					case 2:
+						inode->i_size += 1;
+						break;
+					case 4:
+						inode->i_size += 2;
+						break;
+					case 8:
+						rootflag = 1;
+						inode->i_size += 1;
+						break;
+					default:
+						printk("Symlink component flag "
+							"not implemented\n");
+					}
+					slen -= slp->len + 2;
+					oldslp = slp;
+					slp = (struct SL_component *)
+						(((char *)slp) + slp->len + 2);
+
+					if (slen < 2) {
+						if (((rr->u.SL.
+						      flags & 1) != 0)
+						    &&
+						    ((oldslp->
+						      flags & 1) == 0))
+							inode->i_size +=
+							    1;
+						break;
+					}
+
+					/*
+					 * If this component record isn't
+					 * continued, then append a '/'.
+					 */
+					if (!rootflag
+					    && (oldslp->flags & 1) == 0)
+						inode->i_size += 1;
+				}
+			}
+			symlink_len = inode->i_size;
+			break;
+		case SIG('R', 'E'):
+			printk(KERN_WARNING "Attempt to read inode for "
+					"relocated directory\n");
+			goto out;
+		case SIG('C', 'L'):
+			ISOFS_I(inode)->i_first_extent =
+			    isonum_733(rr->u.CL.location);
+			reloc =
+			    isofs_iget(inode->i_sb,
+				       ISOFS_I(inode)->i_first_extent,
+				       0);
+			if (!reloc)
+				goto out;
+			inode->i_mode = reloc->i_mode;
+			inode->i_nlink = reloc->i_nlink;
+			inode->i_uid = reloc->i_uid;
+			inode->i_gid = reloc->i_gid;
+			inode->i_rdev = reloc->i_rdev;
+			inode->i_size = reloc->i_size;
+			inode->i_blocks = reloc->i_blocks;
+			inode->i_atime = reloc->i_atime;
+			inode->i_ctime = reloc->i_ctime;
+			inode->i_mtime = reloc->i_mtime;
+			iput(reloc);
+			break;
 #ifdef CONFIG_ZISOFS
-      case SIG('Z','F'):
-	      if ( !ISOFS_SB(inode->i_sb)->s_nocompress ) {
-		      int algo;
-		      algo = isonum_721(rr->u.ZF.algorithm);
-		      if ( algo == SIG('p','z') ) {
-			      int block_shift = isonum_711(&rr->u.ZF.parms[1]);
-			      if ( block_shift < PAGE_CACHE_SHIFT || block_shift > 17 ) {
-				      printk(KERN_WARNING "isofs: Can't handle ZF block size of 2^%d\n", block_shift);
-			      } else {
-				/* Note: we don't change i_blocks here */
-				      ISOFS_I(inode)->i_file_format = isofs_file_compressed;
-				/* Parameters to compression algorithm (header size, block size) */
-				      ISOFS_I(inode)->i_format_parm[0] = isonum_711(&rr->u.ZF.parms[0]);
-				      ISOFS_I(inode)->i_format_parm[1] = isonum_711(&rr->u.ZF.parms[1]);
-				      inode->i_size = isonum_733(rr->u.ZF.real_size);
-			      }
-		      } else {
-			      printk(KERN_WARNING "isofs: Unknown ZF compression algorithm: %c%c\n",
-				     rr->u.ZF.algorithm[0], rr->u.ZF.algorithm[1]);
-		      }
-	      }
-	      break;
+		case SIG('Z', 'F'): {
+			int algo;
+
+			if (ISOFS_SB(inode->i_sb)->s_nocompress)
+				break;
+			algo = isonum_721(rr->u.ZF.algorithm);
+			if (algo == SIG('p', 'z')) {
+				int block_shift =
+					isonum_711(&rr->u.ZF.parms[1]);
+				if (block_shift < PAGE_CACHE_SHIFT
+						|| block_shift > 17) {
+					printk(KERN_WARNING "isofs: "
+						"Can't handle ZF block "
+						"size of 2^%d\n",
+						block_shift);
+				} else {
+					/*
+					 * Note: we don't change
+					 * i_blocks here
+					 */
+					ISOFS_I(inode)->i_file_format =
+						isofs_file_compressed;
+					/*
+					 * Parameters to compression
+					 * algorithm (header size,
+					 * block size)
+					 */
+					ISOFS_I(inode)->i_format_parm[0] =
+						isonum_711(&rr->u.ZF.parms[0]);
+					ISOFS_I(inode)->i_format_parm[1] =
+						isonum_711(&rr->u.ZF.parms[1]);
+					inode->i_size =
+					    isonum_733(rr->u.ZF.
+						       real_size);
+				}
+			} else {
+				printk(KERN_WARNING
+				       "isofs: Unknown ZF compression "
+						"algorithm: %c%c\n",
+				       rr->u.ZF.algorithm[0],
+				       rr->u.ZF.algorithm[1]);
+			}
+			break;
+		}
 #endif
-      default:
-	break;
-      }
-    }
-  }
-  MAYBE_CONTINUE(repeat,inode);
- out:
-  if(buffer) kfree(buffer);
-  return 0;
+		default:
+			break;
+		}
+	}
+	ret = rock_continue(&rs);
+	if (ret == 0)
+		goto repeat;
+	if (ret == 1)
+		ret = 0;
+out:
+	kfree(rs.buffer);
+	return ret;
+eio:
+	ret = -EIO;
+	goto out;
 }
 
 static char *get_symlink_chunk(char *rpnt, struct rock_ridge *rr, char *plimit)
@@ -376,32 +566,32 @@ static char *get_symlink_chunk(char *rpn
 			if (slp->len > plimit - rpnt)
 				return NULL;
 			memcpy(rpnt, slp->text, slp->len);
-			rpnt+=slp->len;
+			rpnt += slp->len;
 			break;
 		case 2:
 			if (rpnt >= plimit)
 				return NULL;
-			*rpnt++='.';
+			*rpnt++ = '.';
 			break;
 		case 4:
 			if (2 > plimit - rpnt)
 				return NULL;
-			*rpnt++='.';
-			*rpnt++='.';
+			*rpnt++ = '.';
+			*rpnt++ = '.';
 			break;
 		case 8:
 			if (rpnt >= plimit)
 				return NULL;
 			rootflag = 1;
-			*rpnt++='/';
+			*rpnt++ = '/';
 			break;
 		default:
 			printk("Symlink component flag not implemented (%d)\n",
-			     slp->flags);
+			       slp->flags);
 		}
 		slen -= slp->len + 2;
 		oldslp = slp;
-		slp = (struct SL_component *) ((char *) slp + slp->len + 2);
+		slp = (struct SL_component *)((char *)slp + slp->len + 2);
 
 		if (slen < 2) {
 			/*
@@ -412,7 +602,7 @@ static char *get_symlink_chunk(char *rpn
 			    !(oldslp->flags & 1)) {
 				if (rpnt >= plimit)
 					return NULL;
-				*rpnt++='/';
+				*rpnt++ = '/';
 			}
 			break;
 		}
@@ -423,59 +613,61 @@ static char *get_symlink_chunk(char *rpn
 		if (!rootflag && !(oldslp->flags & 1)) {
 			if (rpnt >= plimit)
 				return NULL;
-			*rpnt++='/';
+			*rpnt++ = '/';
 		}
 	}
 	return rpnt;
 }
 
-int parse_rock_ridge_inode(struct iso_directory_record * de,
-			   struct inode * inode)
+int parse_rock_ridge_inode(struct iso_directory_record *de, struct inode *inode)
 {
-   int result=parse_rock_ridge_inode_internal(de,inode,0);
-   /* if rockridge flag was reset and we didn't look for attributes
-    * behind eventual XA attributes, have a look there */
-   if ((ISOFS_SB(inode->i_sb)->s_rock_offset==-1)
-       &&(ISOFS_SB(inode->i_sb)->s_rock==2))
-     {
-	result=parse_rock_ridge_inode_internal(de,inode,14);
-     }
-   return result;
-}
+	int result = parse_rock_ridge_inode_internal(de, inode, 0);
 
-/* readpage() for symlinks: reads symlink contents into the page and either
-   makes it uptodate and returns 0 or returns error (-EIO) */
+	/*
+	 * if rockridge flag was reset and we didn't look for attributes
+	 * behind eventual XA attributes, have a look there
+	 */
+	if ((ISOFS_SB(inode->i_sb)->s_rock_offset == -1)
+	    && (ISOFS_SB(inode->i_sb)->s_rock == 2)) {
+		result = parse_rock_ridge_inode_internal(de, inode, 14);
+	}
+	return result;
+}
 
+/*
+ * readpage() for symlinks: reads symlink contents into the page and either
+ * makes it uptodate and returns 0 or returns error (-EIO)
+ */
 static int rock_ridge_symlink_readpage(struct file *file, struct page *page)
 {
 	struct inode *inode = page->mapping->host;
-        struct iso_inode_info *ei = ISOFS_I(inode);
+	struct iso_inode_info *ei = ISOFS_I(inode);
 	char *link = kmap(page);
 	unsigned long bufsize = ISOFS_BUFFER_SIZE(inode);
 	struct buffer_head *bh;
 	char *rpnt = link;
 	unsigned char *pnt;
-	struct iso_directory_record *raw_inode;
-	CONTINUE_DECLS;
+	struct iso_directory_record *raw_de;
 	unsigned long block, offset;
 	int sig;
-	int len;
-	unsigned char *chr;
 	struct rock_ridge *rr;
+	struct rock_state rs;
+	int ret;
 
 	if (!ISOFS_SB(inode->i_sb)->s_rock)
 		goto error;
 
+	init_rock_state(&rs, inode);
 	block = ei->i_iget5_block;
 	lock_kernel();
 	bh = sb_bread(inode->i_sb, block);
 	if (!bh)
 		goto out_noread;
 
-        offset = ei->i_iget5_offset;
-	pnt = (unsigned char *) bh->b_data + offset;
+	offset = ei->i_iget5_offset;
+	pnt = (unsigned char *)bh->b_data + offset;
 
-	raw_inode = (struct iso_directory_record *) pnt;
+	raw_de = (struct iso_directory_record *)pnt;
 
 	/*
 	 * If we go past the end of the buffer, there is some sort of error.
@@ -483,20 +675,24 @@ static int rock_ridge_symlink_readpage(s
 	if (offset + *pnt > bufsize)
 		goto out_bad_span;
 
-	/* Now test for possible Rock Ridge extensions which will override
-	   some of these numbers in the inode structure. */
+	/*
+	 * Now test for possible Rock Ridge extensions which will override
+	 * some of these numbers in the inode structure.
+	 */
 
-	SETUP_ROCK_RIDGE(raw_inode, chr, len);
+	setup_rock_ridge(raw_de, inode, &rs);
 
-      repeat:
-	while (len > 2) { /* There may be one byte for padding somewhere */
-		rr = (struct rock_ridge *) chr;
+repeat:
+	while (rs.len > 2) { /* There may be one byte for padding somewhere */
+		rr = (struct rock_ridge *)rs.chr;
 		if (rr->len < 3)
 			goto out;	/* Something got screwed up here */
-		sig = isonum_721(chr);
-		chr += rr->len;
-		len -= rr->len;
-		if (len < 0)
+		sig = isonum_721(rs.chr);
+		if (rock_check_overflow(&rs, sig))
+			goto out;
+		rs.chr += rr->len;
+		rs.len -= rr->len;
+		if (rs.len < 0)
 			goto out;	/* corrupted isofs */
 
 		switch (sig) {
@@ -505,7 +701,8 @@ static int rock_ridge_symlink_readpage(s
 				goto out;
 			break;
 		case SIG('S', 'P'):
-			CHECK_SP(goto out);
+			if (check_sp(rr, inode))
+				goto out;
 			break;
 		case SIG('S', 'L'):
 			rpnt = get_symlink_chunk(rpnt, rr,
@@ -515,14 +712,18 @@ static int rock_ridge_symlink_readpage(s
 			break;
 		case SIG('C', 'E'):
 			/* This tells is if there is a continuation record */
-			CHECK_CE;
+			rs.cont_extent = isonum_733(rr->u.CE.extent);
+			rs.cont_offset = isonum_733(rr->u.CE.offset);
+			rs.cont_size = isonum_733(rr->u.CE.size);
 		default:
 			break;
 		}
 	}
-	MAYBE_CONTINUE(repeat, inode);
-	if (buffer)
-		kfree(buffer);
+	ret = rock_continue(&rs);
+	if (ret == 0)
+		goto repeat;
+	if (ret < 0)
+		goto fail;
 
 	if (rpnt == link)
 		goto fail;
@@ -535,19 +736,18 @@ static int rock_ridge_symlink_readpage(s
 	return 0;
 
 	/* error exit from macro */
-      out:
-	if (buffer)
-		kfree(buffer);
+out:
+	kfree(rs.buffer);
 	goto fail;
-      out_noread:
+out_noread:
 	printk("unable to read i-node block");
 	goto fail;
-      out_bad_span:
+out_bad_span:
 	printk("symlink spans iso9660 blocks\n");
-      fail:
+fail:
 	brelse(bh);
 	unlock_kernel();
-      error:
+error:
 	SetPageError(page);
 	kunmap(page);
 	unlock_page(page);
@@ -555,5 +755,5 @@ static int rock_ridge_symlink_readpage(s
 }
 
 struct address_space_operations isofs_symlink_aops = {
-	.readpage	= rock_ridge_symlink_readpage
+	.readpage = rock_ridge_symlink_readpage
 };
diff --git a/fs/isofs/rock.h b/fs/isofs/rock.h
--- a/fs/isofs/rock.h
+++ b/fs/isofs/rock.h
@@ -1,85 +1,88 @@
-/* These structs are used by the system-use-sharing protocol, in which the
-   Rock Ridge extensions are embedded.  It is quite possible that other
-   extensions are present on the disk, and this is fine as long as they
-   all use SUSP */
-
-struct SU_SP{
-  unsigned char magic[2];
-  unsigned char skip;
-} __attribute__((packed));
-
-struct SU_CE{
-  char extent[8];
-  char offset[8];
-  char size[8];
-};
-
-struct SU_ER{
-  unsigned char len_id;
-  unsigned char len_des;
-  unsigned char len_src;
-  unsigned char ext_ver;
-  char data[0];
-} __attribute__((packed));
-
-struct RR_RR{
-  char flags[1];
-} __attribute__((packed));
-
-struct RR_PX{
-  char mode[8];
-  char n_links[8];
-  char uid[8];
-  char gid[8];
-};
-
-struct RR_PN{
-  char dev_high[8];
-  char dev_low[8];
-};
-
-
-struct SL_component{
-  unsigned char flags;
-  unsigned char len;
-  char text[0];
-} __attribute__((packed));
-
-struct RR_SL{
-  unsigned char flags;
-  struct SL_component link;
-} __attribute__((packed));
-
-struct RR_NM{
-  unsigned char flags;
-  char name[0];
-} __attribute__((packed));
-
-struct RR_CL{
-  char location[8];
-};
-
-struct RR_PL{
-  char location[8];
-};
-
-struct stamp{
-  char time[7];
-} __attribute__((packed));
-
-struct RR_TF{
-  char flags;
-  struct stamp times[0];  /* Variable number of these beasts */
-} __attribute__((packed));
+/*
+ * These structs are used by the system-use-sharing protocol, in which the
+ * Rock Ridge extensions are embedded.  It is quite possible that other
+ * extensions are present on the disk, and this is fine as long as they
+ * all use SUSP
+ */
+
+struct SU_SP_s {
+	unsigned char magic[2];
+	unsigned char skip;
+} __attribute__ ((packed));
+
+struct SU_CE_s {
+	char extent[8];
+	char offset[8];
+	char size[8];
+};
+
+struct SU_ER_s {
+	unsigned char len_id;
+	unsigned char len_des;
+	unsigned char len_src;
+	unsigned char ext_ver;
+	char data[0];
+} __attribute__ ((packed));
+
+struct RR_RR_s {
+	char flags[1];
+} __attribute__ ((packed));
+
+struct RR_PX_s {
+	char mode[8];
+	char n_links[8];
+	char uid[8];
+	char gid[8];
+};
+
+struct RR_PN_s {
+	char dev_high[8];
+	char dev_low[8];
+};
+
+struct SL_component {
+	unsigned char flags;
+	unsigned char len;
+	char text[0];
+} __attribute__ ((packed));
+
+struct RR_SL_s {
+	unsigned char flags;
+	struct SL_component link;
+} __attribute__ ((packed));
+
+struct RR_NM_s {
+	unsigned char flags;
+	char name[0];
+} __attribute__ ((packed));
+
+struct RR_CL_s {
+	char location[8];
+};
+
+struct RR_PL_s {
+	char location[8];
+};
+
+struct stamp {
+	char time[7];
+} __attribute__ ((packed));
+
+struct RR_TF_s {
+	char flags;
+	struct stamp times[0];	/* Variable number of these beasts */
+} __attribute__ ((packed));
 
 /* Linux-specific extension for transparent decompression */
-struct RR_ZF{
-  char algorithm[2];
-  char parms[2];
-  char real_size[8];
+struct RR_ZF_s {
+	char algorithm[2];
+	char parms[2];
+	char real_size[8];
 };
 
-/* These are the bits and their meanings for flags in the TF structure. */
+/*
+ * These are the bits and their meanings for flags in the TF structure.
+ */
 #define TF_CREATE 1
 #define TF_MODIFY 2
 #define TF_ACCESS 4
@@ -89,31 +92,31 @@ struct RR_ZF{
 #define TF_EFFECTIVE 64
 #define TF_LONG_FORM 128
 
-struct rock_ridge{
-  char signature[2];
-  unsigned char len;
-  unsigned char version;
-  union{
-    struct SU_SP SP;
-    struct SU_CE CE;
-    struct SU_ER ER;
-    struct RR_RR RR;
-    struct RR_PX PX;
-    struct RR_PN PN;
-    struct RR_SL SL;
-    struct RR_NM NM;
-    struct RR_CL CL;
-    struct RR_PL PL;
-    struct RR_TF TF;
-    struct RR_ZF ZF;
-  } u;
-};
-
-#define RR_PX 1   /* POSIX attributes */
-#define RR_PN 2   /* POSIX devices */
-#define RR_SL 4   /* Symbolic link */
-#define RR_NM 8   /* Alternate Name */
-#define RR_CL 16  /* Child link */
-#define RR_PL 32  /* Parent link */
-#define RR_RE 64  /* Relocation directory */
-#define RR_TF 128 /* Timestamps */
+struct rock_ridge {
+	char signature[2];
+	unsigned char len;
+	unsigned char version;
+	union {
+		struct SU_SP_s SP;
+		struct SU_CE_s CE;
+		struct SU_ER_s ER;
+		struct RR_RR_s RR;
+		struct RR_PX_s PX;
+		struct RR_PN_s PN;
+		struct RR_SL_s SL;
+		struct RR_NM_s NM;
+		struct RR_CL_s CL;
+		struct RR_PL_s PL;
+		struct RR_TF_s TF;
+		struct RR_ZF_s ZF;
+	} u;
+};
+
+#define RR_PX 1			/* POSIX attributes */
+#define RR_PN 2			/* POSIX devices */
+#define RR_SL 4			/* Symbolic link */
+#define RR_NM 8			/* Alternate Name */
+#define RR_CL 16		/* Child link */
+#define RR_PL 32		/* Parent link */
+#define RR_RE 64		/* Relocation directory */
+#define RR_TF 128		/* Timestamps */
diff --git a/fs/jbd/journal.c b/fs/jbd/journal.c
--- a/fs/jbd/journal.c
+++ b/fs/jbd/journal.c
@@ -167,7 +167,7 @@ loop:
 	}
 
 	wake_up(&journal->j_wait_done_commit);
-	if (current->flags & PF_FREEZE) {
+	if (freezing(current)) {
 		/*
 		 * The simpler the better. Flushing journal isn't a
 		 * good idea, because that depends on threads that may
@@ -175,7 +175,7 @@ loop:
 		 */
 		jbd_debug(1, "Now suspending kjournald\n");
 		spin_unlock(&journal->j_state_lock);
-		refrigerator(PF_FREEZE);
+		refrigerator();
 		spin_lock(&journal->j_state_lock);
 	} else {
 		/*
diff --git a/fs/jffs/intrep.c b/fs/jffs/intrep.c
--- a/fs/jffs/intrep.c
+++ b/fs/jffs/intrep.c
@@ -175,8 +175,64 @@ jffs_hexdump(struct mtd_info *mtd, loff_
 	}
 }
 
+/* Print the contents of a node.  */
+static void
+jffs_print_node(struct jffs_node *n)
+{
+	D(printk("jffs_node: 0x%p\n", n));
+	D(printk("{\n"));
+	D(printk("        0x%08x, /* version  */\n", n->version));
+	D(printk("        0x%08x, /* data_offset  */\n", n->data_offset));
+	D(printk("        0x%08x, /* data_size  */\n", n->data_size));
+	D(printk("        0x%08x, /* removed_size  */\n", n->removed_size));
+	D(printk("        0x%08x, /* fm_offset  */\n", n->fm_offset));
+	D(printk("        0x%02x,       /* name_size  */\n", n->name_size));
+	D(printk("        0x%p, /* fm,  fm->offset: %u  */\n",
+		 n->fm, (n->fm ? n->fm->offset : 0)));
+	D(printk("        0x%p, /* version_prev  */\n", n->version_prev));
+	D(printk("        0x%p, /* version_next  */\n", n->version_next));
+	D(printk("        0x%p, /* range_prev  */\n", n->range_prev));
+	D(printk("        0x%p, /* range_next  */\n", n->range_next));
+	D(printk("}\n"));
+}
+
 #endif
 
+/* Print the contents of a raw inode.  */
+static void
+jffs_print_raw_inode(struct jffs_raw_inode *raw_inode)
+{
+	D(printk("jffs_raw_inode: inode number: %u\n", raw_inode->ino));
+	D(printk("{\n"));
+	D(printk("        0x%08x, /* magic  */\n", raw_inode->magic));
+	D(printk("        0x%08x, /* ino  */\n", raw_inode->ino));
+	D(printk("        0x%08x, /* pino  */\n", raw_inode->pino));
+	D(printk("        0x%08x, /* version  */\n", raw_inode->version));
+	D(printk("        0x%08x, /* mode  */\n", raw_inode->mode));
+	D(printk("        0x%04x,     /* uid  */\n", raw_inode->uid));
+	D(printk("        0x%04x,     /* gid  */\n", raw_inode->gid));
+	D(printk("        0x%08x, /* atime  */\n", raw_inode->atime));
+	D(printk("        0x%08x, /* mtime  */\n", raw_inode->mtime));
+	D(printk("        0x%08x, /* ctime  */\n", raw_inode->ctime));
+	D(printk("        0x%08x, /* offset  */\n", raw_inode->offset));
+	D(printk("        0x%08x, /* dsize  */\n", raw_inode->dsize));
+	D(printk("        0x%08x, /* rsize  */\n", raw_inode->rsize));
+	D(printk("        0x%02x,       /* nsize  */\n", raw_inode->nsize));
+	D(printk("        0x%02x,       /* nlink  */\n", raw_inode->nlink));
+	D(printk("        0x%02x,       /* spare  */\n",
+		 raw_inode->spare));
+	D(printk("        %u,          /* rename  */\n",
+		 raw_inode->rename));
+	D(printk("        %u,          /* deleted  */\n",
+		 raw_inode->deleted));
+	D(printk("        0x%02x,       /* accurate  */\n",
+		 raw_inode->accurate));
+	D(printk("        0x%08x, /* dchksum  */\n", raw_inode->dchksum));
+	D(printk("        0x%04x,     /* nchksum  */\n", raw_inode->nchksum));
+	D(printk("        0x%04x,     /* chksum  */\n", raw_inode->chksum));
+	D(printk("}\n"));
+}
+
 #define flash_safe_acquire(arg)
 #define flash_safe_release(arg)
 
@@ -2507,64 +2563,6 @@ jffs_update_file(struct jffs_file *f, st
 	return 0;
 }
 
-/* Print the contents of a node.  */
-void
-jffs_print_node(struct jffs_node *n)
-{
-	D(printk("jffs_node: 0x%p\n", n));
-	D(printk("{\n"));
-	D(printk("        0x%08x, /* version  */\n", n->version));
-	D(printk("        0x%08x, /* data_offset  */\n", n->data_offset));
-	D(printk("        0x%08x, /* data_size  */\n", n->data_size));
-	D(printk("        0x%08x, /* removed_size  */\n", n->removed_size));
-	D(printk("        0x%08x, /* fm_offset  */\n", n->fm_offset));
-	D(printk("        0x%02x,       /* name_size  */\n", n->name_size));
-	D(printk("        0x%p, /* fm,  fm->offset: %u  */\n",
-		 n->fm, (n->fm ? n->fm->offset : 0)));
-	D(printk("        0x%p, /* version_prev  */\n", n->version_prev));
-	D(printk("        0x%p, /* version_next  */\n", n->version_next));
-	D(printk("        0x%p, /* range_prev  */\n", n->range_prev));
-	D(printk("        0x%p, /* range_next  */\n", n->range_next));
-	D(printk("}\n"));
-}
-
-
-/* Print the contents of a raw inode.  */
-void
-jffs_print_raw_inode(struct jffs_raw_inode *raw_inode)
-{
-	D(printk("jffs_raw_inode: inode number: %u\n", raw_inode->ino));
-	D(printk("{\n"));
-	D(printk("        0x%08x, /* magic  */\n", raw_inode->magic));
-	D(printk("        0x%08x, /* ino  */\n", raw_inode->ino));
-	D(printk("        0x%08x, /* pino  */\n", raw_inode->pino));
-	D(printk("        0x%08x, /* version  */\n", raw_inode->version));
-	D(printk("        0x%08x, /* mode  */\n", raw_inode->mode));
-	D(printk("        0x%04x,     /* uid  */\n", raw_inode->uid));
-	D(printk("        0x%04x,     /* gid  */\n", raw_inode->gid));
-	D(printk("        0x%08x, /* atime  */\n", raw_inode->atime));
-	D(printk("        0x%08x, /* mtime  */\n", raw_inode->mtime));
-	D(printk("        0x%08x, /* ctime  */\n", raw_inode->ctime));
-	D(printk("        0x%08x, /* offset  */\n", raw_inode->offset));
-	D(printk("        0x%08x, /* dsize  */\n", raw_inode->dsize));
-	D(printk("        0x%08x, /* rsize  */\n", raw_inode->rsize));
-	D(printk("        0x%02x,       /* nsize  */\n", raw_inode->nsize));
-	D(printk("        0x%02x,       /* nlink  */\n", raw_inode->nlink));
-	D(printk("        0x%02x,       /* spare  */\n",
-		 raw_inode->spare));
-	D(printk("        %u,          /* rename  */\n",
-		 raw_inode->rename));
-	D(printk("        %u,          /* deleted  */\n",
-		 raw_inode->deleted));
-	D(printk("        0x%02x,       /* accurate  */\n",
-		 raw_inode->accurate));
-	D(printk("        0x%08x, /* dchksum  */\n", raw_inode->dchksum));
-	D(printk("        0x%04x,     /* nchksum  */\n", raw_inode->nchksum));
-	D(printk("        0x%04x,     /* chksum  */\n", raw_inode->chksum));
-	D(printk("}\n"));
-}
-
-
 /* Print the contents of a file.  */
 #if 0
 int
@@ -3399,6 +3397,9 @@ jffs_garbage_collect_thread(void *ptr)
 			siginfo_t info;
 			unsigned long signr = 0;
 
+			if (try_to_freeze())
+				continue;
+
 			spin_lock_irq(&current->sighand->siglock);
 			signr = dequeue_signal(current, &current->blocked, &info);
 			spin_unlock_irq(&current->sighand->siglock);
diff --git a/fs/jffs/intrep.h b/fs/jffs/intrep.h
--- a/fs/jffs/intrep.h
+++ b/fs/jffs/intrep.h
@@ -49,8 +49,6 @@ int jffs_garbage_collect_thread(void *c)
 void jffs_garbage_collect_trigger(struct jffs_control *c);
 
 /* For debugging purposes.  */
-void jffs_print_node(struct jffs_node *n);
-void jffs_print_raw_inode(struct jffs_raw_inode *raw_inode);
 #if 0
 int jffs_print_file(struct jffs_file *f);
 #endif  /*  0  */
diff --git a/fs/jffs/jffs_fm.c b/fs/jffs/jffs_fm.c
--- a/fs/jffs/jffs_fm.c
+++ b/fs/jffs/jffs_fm.c
@@ -31,6 +31,60 @@ static void jffs_free_fm(struct jffs_fm 
 extern kmem_cache_t     *fm_cache;
 extern kmem_cache_t     *node_cache;
 
+#if CONFIG_JFFS_FS_VERBOSE > 0
+void
+jffs_print_fmcontrol(struct jffs_fmcontrol *fmc)
+{
+	D(printk("struct jffs_fmcontrol: 0x%p\n", fmc));
+	D(printk("{\n"));
+	D(printk("        %u, /* flash_size  */\n", fmc->flash_size));
+	D(printk("        %u, /* used_size  */\n", fmc->used_size));
+	D(printk("        %u, /* dirty_size  */\n", fmc->dirty_size));
+	D(printk("        %u, /* free_size  */\n", fmc->free_size));
+	D(printk("        %u, /* sector_size  */\n", fmc->sector_size));
+	D(printk("        %u, /* min_free_size  */\n", fmc->min_free_size));
+	D(printk("        %u, /* max_chunk_size  */\n", fmc->max_chunk_size));
+	D(printk("        0x%p, /* mtd  */\n", fmc->mtd));
+	D(printk("        0x%p, /* head  */    "
+		 "(head->offset = 0x%08x)\n",
+		 fmc->head, (fmc->head ? fmc->head->offset : 0)));
+	D(printk("        0x%p, /* tail  */    "
+		 "(tail->offset + tail->size = 0x%08x)\n",
+		 fmc->tail,
+		 (fmc->tail ? fmc->tail->offset + fmc->tail->size : 0)));
+	D(printk("        0x%p, /* head_extra  */\n", fmc->head_extra));
+	D(printk("        0x%p, /* tail_extra  */\n", fmc->tail_extra));
+	D(printk("}\n"));
+}
+#endif  /*  CONFIG_JFFS_FS_VERBOSE > 0  */
+
+#if CONFIG_JFFS_FS_VERBOSE > 2
+static void
+jffs_print_fm(struct jffs_fm *fm)
+{
+	D(printk("struct jffs_fm: 0x%p\n", fm));
+	D(printk("{\n"));
+	D(printk("       0x%08x, /* offset  */\n", fm->offset));
+	D(printk("       %u, /* size  */\n", fm->size));
+	D(printk("       0x%p, /* prev  */\n", fm->prev));
+	D(printk("       0x%p, /* next  */\n", fm->next));
+	D(printk("       0x%p, /* nodes  */\n", fm->nodes));
+	D(printk("}\n"));
+}
+#endif  /*  CONFIG_JFFS_FS_VERBOSE > 2  */
+
+#if 0
+void
+jffs_print_node_ref(struct jffs_node_ref *ref)
+{
+	D(printk("struct jffs_node_ref: 0x%p\n", ref));
+	D(printk("{\n"));
+	D(printk("       0x%p, /* node  */\n", ref->node));
+	D(printk("       0x%p, /* next  */\n", ref->next));
+	D(printk("}\n"));
+}
+#endif  /*  0  */
+
 /* This function creates a new shiny flash memory control structure.  */
 struct jffs_fmcontrol *
 jffs_build_begin(struct jffs_control *c, int unit)
@@ -742,54 +796,3 @@ int jffs_get_node_inuse(void)
 {
 	return no_jffs_node;
 }
-
-void
-jffs_print_fmcontrol(struct jffs_fmcontrol *fmc)
-{
-	D(printk("struct jffs_fmcontrol: 0x%p\n", fmc));
-	D(printk("{\n"));
-	D(printk("        %u, /* flash_size  */\n", fmc->flash_size));
-	D(printk("        %u, /* used_size  */\n", fmc->used_size));
-	D(printk("        %u, /* dirty_size  */\n", fmc->dirty_size));
-	D(printk("        %u, /* free_size  */\n", fmc->free_size));
-	D(printk("        %u, /* sector_size  */\n", fmc->sector_size));
-	D(printk("        %u, /* min_free_size  */\n", fmc->min_free_size));
-	D(printk("        %u, /* max_chunk_size  */\n", fmc->max_chunk_size));
-	D(printk("        0x%p, /* mtd  */\n", fmc->mtd));
-	D(printk("        0x%p, /* head  */    "
-		 "(head->offset = 0x%08x)\n",
-		 fmc->head, (fmc->head ? fmc->head->offset : 0)));
-	D(printk("        0x%p, /* tail  */    "
-		 "(tail->offset + tail->size = 0x%08x)\n",
-		 fmc->tail,
-		 (fmc->tail ? fmc->tail->offset + fmc->tail->size : 0)));
-	D(printk("        0x%p, /* head_extra  */\n", fmc->head_extra));
-	D(printk("        0x%p, /* tail_extra  */\n", fmc->tail_extra));
-	D(printk("}\n"));
-}
-
-void
-jffs_print_fm(struct jffs_fm *fm)
-{
-	D(printk("struct jffs_fm: 0x%p\n", fm));
-	D(printk("{\n"));
-	D(printk("       0x%08x, /* offset  */\n", fm->offset));
-	D(printk("       %u, /* size  */\n", fm->size));
-	D(printk("       0x%p, /* prev  */\n", fm->prev));
-	D(printk("       0x%p, /* next  */\n", fm->next));
-	D(printk("       0x%p, /* nodes  */\n", fm->nodes));
-	D(printk("}\n"));
-}
-
-#if 0
-void
-jffs_print_node_ref(struct jffs_node_ref *ref)
-{
-	D(printk("struct jffs_node_ref: 0x%p\n", ref));
-	D(printk("{\n"));
-	D(printk("       0x%p, /* node  */\n", ref->node));
-	D(printk("       0x%p, /* next  */\n", ref->next));
-	D(printk("}\n"));
-}
-#endif  /*  0  */
-
diff --git a/fs/jffs/jffs_fm.h b/fs/jffs/jffs_fm.h
--- a/fs/jffs/jffs_fm.h
+++ b/fs/jffs/jffs_fm.h
@@ -139,8 +139,9 @@ int jffs_add_node(struct jffs_node *node
 void jffs_fmfree_partly(struct jffs_fmcontrol *fmc, struct jffs_fm *fm,
 			__u32 size);
 
+#if CONFIG_JFFS_FS_VERBOSE > 0
 void jffs_print_fmcontrol(struct jffs_fmcontrol *fmc);
-void jffs_print_fm(struct jffs_fm *fm);
+#endif
 #if 0
 void jffs_print_node_ref(struct jffs_node_ref *ref);
 #endif  /*  0  */
diff --git a/fs/jffs2/Makefile b/fs/jffs2/Makefile
--- a/fs/jffs2/Makefile
+++ b/fs/jffs2/Makefile
@@ -1,7 +1,7 @@
 #
 # Makefile for the Linux Journalling Flash File System v2 (JFFS2)
 #
-# $Id: Makefile.common,v 1.7 2004/11/03 12:57:38 jwboyer Exp $
+# $Id: Makefile.common,v 1.9 2005/02/09 09:23:53 pavlov Exp $
 #
 
 obj-$(CONFIG_JFFS2_FS) += jffs2.o
@@ -11,8 +11,7 @@ jffs2-y	+= read.o nodemgmt.o readinode.o
 jffs2-y	+= symlink.o build.o erase.o background.o fs.o writev.o
 jffs2-y	+= super.o
 
-jffs2-$(CONFIG_JFFS2_FS_NAND)	+= wbuf.o
-jffs2-$(CONFIG_JFFS2_FS_NOR_ECC) += wbuf.o
+jffs2-$(CONFIG_JFFS2_FS_WRITEBUFFER)	+= wbuf.o
 jffs2-$(CONFIG_JFFS2_RUBIN)	+= compr_rubin.o
 jffs2-$(CONFIG_JFFS2_RTIME)	+= compr_rtime.o
 jffs2-$(CONFIG_JFFS2_ZLIB)	+= compr_zlib.o
diff --git a/fs/jffs2/README.Locking b/fs/jffs2/README.Locking
--- a/fs/jffs2/README.Locking
+++ b/fs/jffs2/README.Locking
@@ -1,4 +1,4 @@
-	$Id: README.Locking,v 1.9 2004/11/20 10:35:40 dwmw2 Exp $
+	$Id: README.Locking,v 1.12 2005/04/13 13:22:35 dwmw2 Exp $
 
 	JFFS2 LOCKING DOCUMENTATION
 	---------------------------
@@ -108,6 +108,10 @@ in-core jffs2_inode_cache objects (each 
 correspondent jffs2_inode_cache object). So, the inocache_lock
 has to be locked while walking the c->inocache_list hash buckets.
 
+This spinlock also covers allocation of new inode numbers, which is
+currently just '++->highest_ino++', but might one day get more complicated
+if we need to deal with wrapping after 4 milliard inode numbers are used.
+
 Note, the f->sem guarantees that the correspondent jffs2_inode_cache
 will not be removed. So, it is allowed to access it without locking
 the inocache_lock spinlock. 
diff --git a/fs/jffs2/background.c b/fs/jffs2/background.c
--- a/fs/jffs2/background.c
+++ b/fs/jffs2/background.c
@@ -7,7 +7,7 @@
  *
  * For licensing information, see the file 'LICENCE' in this directory.
  *
- * $Id: background.c,v 1.50 2004/11/16 20:36:10 dwmw2 Exp $
+ * $Id: background.c,v 1.54 2005/05/20 21:37:12 gleixner Exp $
  *
  */
 
@@ -37,7 +37,7 @@ int jffs2_start_garbage_collect_thread(s
 	if (c->gc_task)
 		BUG();
 
-	init_MUTEX_LOCKED(&c->gc_thread_start);
+	init_completion(&c->gc_thread_start);
 	init_completion(&c->gc_thread_exit);
 
 	pid = kernel_thread(jffs2_garbage_collect_thread, c, CLONE_FS|CLONE_FILES);
@@ -48,7 +48,7 @@ int jffs2_start_garbage_collect_thread(s
 	} else {
 		/* Wait for it... */
 		D1(printk(KERN_DEBUG "JFFS2: Garbage collect thread is pid %d\n", pid));
-		down(&c->gc_thread_start);
+		wait_for_completion(&c->gc_thread_start);
 	}
  
 	return ret;
@@ -56,13 +56,16 @@ int jffs2_start_garbage_collect_thread(s
 
 void jffs2_stop_garbage_collect_thread(struct jffs2_sb_info *c)
 {
+	int wait = 0;
 	spin_lock(&c->erase_completion_lock);
 	if (c->gc_task) {
 		D1(printk(KERN_DEBUG "jffs2: Killing GC task %d\n", c->gc_task->pid));
 		send_sig(SIGKILL, c->gc_task, 1);
+		wait = 1;
 	}
 	spin_unlock(&c->erase_completion_lock);
-	wait_for_completion(&c->gc_thread_exit);
+	if (wait)
+		wait_for_completion(&c->gc_thread_exit);
 }
 
 static int jffs2_garbage_collect_thread(void *_c)
@@ -75,7 +78,7 @@ static int jffs2_garbage_collect_thread(
 	allow_signal(SIGCONT);
 
 	c->gc_task = current;
-	up(&c->gc_thread_start);
+	complete(&c->gc_thread_start);
 
 	set_user_nice(current, 10);
 
@@ -92,7 +95,7 @@ static int jffs2_garbage_collect_thread(
 			schedule();
 		}
 
-		if (try_to_freeze(0))
+		if (try_to_freeze())
 			continue;
 
 		cond_resched();
diff --git a/fs/jffs2/build.c b/fs/jffs2/build.c
--- a/fs/jffs2/build.c
+++ b/fs/jffs2/build.c
@@ -7,7 +7,7 @@
  *
  * For licensing information, see the file 'LICENCE' in this directory.
  *
- * $Id: build.c,v 1.69 2004/12/16 20:22:18 dmarlin Exp $
+ * $Id: build.c,v 1.71 2005/07/12 16:37:08 dedekind Exp $
  *
  */
 
@@ -97,14 +97,16 @@ static int jffs2_build_filesystem(struct
 	/* First, scan the medium and build all the inode caches with
 	   lists of physical nodes */
 
-	c->flags |= JFFS2_SB_FLAG_MOUNTING;
+	c->flags |= JFFS2_SB_FLAG_SCANNING;
 	ret = jffs2_scan_medium(c);
+	c->flags &= ~JFFS2_SB_FLAG_SCANNING;
 	if (ret)
 		goto exit;
 
 	D1(printk(KERN_DEBUG "Scanned flash completely\n"));
 	D2(jffs2_dump_block_lists(c));
 
+	c->flags |= JFFS2_SB_FLAG_BUILDING;
 	/* Now scan the directory tree, increasing nlink according to every dirent found. */
 	for_each_inode(i, c, ic) {
 		D1(printk(KERN_DEBUG "Pass 1: ino #%u\n", ic->ino));
@@ -116,7 +118,6 @@ static int jffs2_build_filesystem(struct
 			cond_resched();
 		}
 	}
-	c->flags &= ~JFFS2_SB_FLAG_MOUNTING;
 
 	D1(printk(KERN_DEBUG "Pass 1 complete\n"));
 
@@ -164,6 +165,8 @@ static int jffs2_build_filesystem(struct
 		ic->scan_dents = NULL;
 		cond_resched();
 	}
+	c->flags &= ~JFFS2_SB_FLAG_BUILDING;
+	
 	D1(printk(KERN_DEBUG "Pass 3 complete\n"));
 	D2(jffs2_dump_block_lists(c));
 
@@ -333,13 +336,6 @@ int jffs2_do_mount_fs(struct jffs2_sb_in
 		c->blocks[i].bad_count = 0;
 	}
 
-	init_MUTEX(&c->alloc_sem);
-	init_MUTEX(&c->erase_free_sem);
-	init_waitqueue_head(&c->erase_wait);
-	init_waitqueue_head(&c->inocache_wq);
-	spin_lock_init(&c->erase_completion_lock);
-	spin_lock_init(&c->inocache_lock);
-
 	INIT_LIST_HEAD(&c->clean_list);
 	INIT_LIST_HEAD(&c->very_dirty_list);
 	INIT_LIST_HEAD(&c->dirty_list);
diff --git a/fs/jffs2/compr_zlib.c b/fs/jffs2/compr_zlib.c
--- a/fs/jffs2/compr_zlib.c
+++ b/fs/jffs2/compr_zlib.c
@@ -7,7 +7,7 @@
  *
  * For licensing information, see the file 'LICENCE' in this directory.
  *
- * $Id: compr_zlib.c,v 1.29 2004/11/16 20:36:11 dwmw2 Exp $
+ * $Id: compr_zlib.c,v 1.31 2005/05/20 19:30:06 gleixner Exp $
  *
  */
 
@@ -17,10 +17,10 @@
 
 #include <linux/config.h>
 #include <linux/kernel.h>
+#include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/zlib.h>
 #include <linux/zutil.h>
-#include <asm/semaphore.h>
 #include "nodelist.h"
 #include "compr.h"
 
diff --git a/fs/jffs2/dir.c b/fs/jffs2/dir.c
--- a/fs/jffs2/dir.c
+++ b/fs/jffs2/dir.c
@@ -7,7 +7,7 @@
  *
  * For licensing information, see the file 'LICENCE' in this directory.
  *
- * $Id: dir.c,v 1.84 2004/11/16 20:36:11 dwmw2 Exp $
+ * $Id: dir.c,v 1.86 2005/07/06 12:13:09 dwmw2 Exp $
  *
  */
 
@@ -22,16 +22,6 @@
 #include <linux/time.h>
 #include "nodelist.h"
 
-/* Urgh. Please tell me there's a nicer way of doing these. */
-#include <linux/version.h>
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,48)
-typedef int mknod_arg_t;
-#define NAMEI_COMPAT(x) ((void *)x)
-#else
-typedef dev_t mknod_arg_t;
-#define NAMEI_COMPAT(x) (x)
-#endif
-
 static int jffs2_readdir (struct file *, void *, filldir_t);
 
 static int jffs2_create (struct inode *,struct dentry *,int,
@@ -43,7 +33,7 @@ static int jffs2_unlink (struct inode *,
 static int jffs2_symlink (struct inode *,struct dentry *,const char *);
 static int jffs2_mkdir (struct inode *,struct dentry *,int);
 static int jffs2_rmdir (struct inode *,struct dentry *);
-static int jffs2_mknod (struct inode *,struct dentry *,int,mknod_arg_t);
+static int jffs2_mknod (struct inode *,struct dentry *,int,dev_t);
 static int jffs2_rename (struct inode *, struct dentry *,
                         struct inode *, struct dentry *);
 
@@ -58,8 +48,8 @@ struct file_operations jffs2_dir_operati
 
 struct inode_operations jffs2_dir_inode_operations =
 {
-	.create =	NAMEI_COMPAT(jffs2_create),
-	.lookup =	NAMEI_COMPAT(jffs2_lookup),
+	.create =	jffs2_create,
+	.lookup =	jffs2_lookup,
 	.link =		jffs2_link,
 	.unlink =	jffs2_unlink,
 	.symlink =	jffs2_symlink,
@@ -296,11 +286,11 @@ static int jffs2_symlink (struct inode *
 	struct jffs2_full_dirent *fd;
 	int namelen;
 	uint32_t alloclen, phys_ofs;
-	int ret;
+	int ret, targetlen = strlen(target);
 
 	/* FIXME: If you care. We'd need to use frags for the target
 	   if it grows much more than this */
-	if (strlen(target) > 254)
+	if (targetlen > 254)
 		return -EINVAL;
 
 	ri = jffs2_alloc_raw_inode();
@@ -314,7 +304,7 @@ static int jffs2_symlink (struct inode *
 	 * Just the node will do for now, though 
 	 */
 	namelen = dentry->d_name.len;
-	ret = jffs2_reserve_space(c, sizeof(*ri) + strlen(target), &phys_ofs, &alloclen, ALLOC_NORMAL);
+	ret = jffs2_reserve_space(c, sizeof(*ri) + targetlen, &phys_ofs, &alloclen, ALLOC_NORMAL);
 
 	if (ret) {
 		jffs2_free_raw_inode(ri);
@@ -333,16 +323,16 @@ static int jffs2_symlink (struct inode *
 
 	f = JFFS2_INODE_INFO(inode);
 
-	inode->i_size = strlen(target);
+	inode->i_size = targetlen;
 	ri->isize = ri->dsize = ri->csize = cpu_to_je32(inode->i_size);
 	ri->totlen = cpu_to_je32(sizeof(*ri) + inode->i_size);
 	ri->hdr_crc = cpu_to_je32(crc32(0, ri, sizeof(struct jffs2_unknown_node)-4));
 
 	ri->compr = JFFS2_COMPR_NONE;
-	ri->data_crc = cpu_to_je32(crc32(0, target, strlen(target)));
+	ri->data_crc = cpu_to_je32(crc32(0, target, targetlen));
 	ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));
 	
-	fn = jffs2_write_dnode(c, f, ri, target, strlen(target), phys_ofs, ALLOC_NORMAL);
+	fn = jffs2_write_dnode(c, f, ri, target, targetlen, phys_ofs, ALLOC_NORMAL);
 
 	jffs2_free_raw_inode(ri);
 
@@ -353,6 +343,20 @@ static int jffs2_symlink (struct inode *
 		jffs2_clear_inode(inode);
 		return PTR_ERR(fn);
 	}
+
+	/* We use f->dents field to store the target path. */
+	f->dents = kmalloc(targetlen + 1, GFP_KERNEL);
+	if (!f->dents) {
+		printk(KERN_WARNING "Can't allocate %d bytes of memory\n", targetlen + 1);
+		up(&f->sem);
+		jffs2_complete_reservation(c);
+		jffs2_clear_inode(inode);
+		return -ENOMEM;
+	}
+
+	memcpy(f->dents, target, targetlen + 1);
+	D1(printk(KERN_DEBUG "jffs2_symlink: symlink's target '%s' cached\n", (char *)f->dents));
+
 	/* No data here. Only a metadata node, which will be 
 	   obsoleted by the first data write
 	*/
@@ -564,7 +568,7 @@ static int jffs2_rmdir (struct inode *di
 	return ret;
 }
 
-static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, mknod_arg_t rdev)
+static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, dev_t rdev)
 {
 	struct jffs2_inode_info *f, *dir_f;
 	struct jffs2_sb_info *c;
diff --git a/fs/jffs2/erase.c b/fs/jffs2/erase.c
--- a/fs/jffs2/erase.c
+++ b/fs/jffs2/erase.c
@@ -7,7 +7,7 @@
  *
  * For licensing information, see the file 'LICENCE' in this directory.
  *
- * $Id: erase.c,v 1.66 2004/11/16 20:36:11 dwmw2 Exp $
+ * $Id: erase.c,v 1.80 2005/07/14 19:46:24 joern Exp $
  *
  */
 
@@ -48,6 +48,7 @@ static void jffs2_erase_block(struct jff
 #else /* Linux */
 	struct erase_info *instr;
 
+	D1(printk(KERN_DEBUG "jffs2_erase_block(): erase block %#x (range %#x-%#x)\n", jeb->offset, jeb->offset, jeb->offset + c->sector_size));
 	instr = kmalloc(sizeof(struct erase_info) + sizeof(struct erase_priv_struct), GFP_KERNEL);
 	if (!instr) {
 		printk(KERN_WARNING "kmalloc for struct erase_info in jffs2_erase_block failed. Refiling block for later\n");
@@ -233,7 +234,7 @@ static inline void jffs2_remove_node_ref
 			continue;
 		} 
 
-		if (((*prev)->flash_offset & ~(c->sector_size -1)) == jeb->offset) {
+		if (SECTOR_ADDR((*prev)->flash_offset) == jeb->offset) {
 			/* It's in the block we're erasing */
 			struct jffs2_raw_node_ref *this;
 
@@ -277,11 +278,8 @@ static inline void jffs2_remove_node_ref
 		printk("\n");
 	});
 
-	if (ic->nodes == (void *)ic) {
-		D1(printk(KERN_DEBUG "inocache for ino #%u is all gone now. Freeing\n", ic->ino));
+	if (ic->nodes == (void *)ic && ic->nlink == 0)
 		jffs2_del_ino_cache(c, ic);
-		jffs2_free_inode_cache(ic);
-	}
 }
 
 static void jffs2_free_all_node_refs(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb)
@@ -302,92 +300,86 @@ static void jffs2_free_all_node_refs(str
 	jeb->last_node = NULL;
 }
 
-static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb)
+static int jffs2_block_check_erase(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, uint32_t *bad_offset)
 {
-	struct jffs2_raw_node_ref *marker_ref = NULL;
-	unsigned char *ebuf;
+	void *ebuf;
+	uint32_t ofs;
 	size_t retlen;
-	int ret;
-	uint32_t bad_offset;
-
-	if (!jffs2_cleanmarker_oob(c)) {
-		marker_ref = jffs2_alloc_raw_node_ref();
-		if (!marker_ref) {
-			printk(KERN_WARNING "Failed to allocate raw node ref for clean marker\n");
-			/* Stick it back on the list from whence it came and come back later */
-			jffs2_erase_pending_trigger(c);
-			spin_lock(&c->erase_completion_lock);
-			list_add(&jeb->list, &c->erase_complete_list);
-			spin_unlock(&c->erase_completion_lock);
-			return;
-		}
-	}
+	int ret = -EIO;
+	
 	ebuf = kmalloc(PAGE_SIZE, GFP_KERNEL);
 	if (!ebuf) {
-		printk(KERN_WARNING "Failed to allocate page buffer for verifying erase at 0x%08x. Assuming it worked\n", jeb->offset);
-	} else {
-		uint32_t ofs = jeb->offset;
+		printk(KERN_WARNING "Failed to allocate page buffer for verifying erase at 0x%08x. Refiling\n", jeb->offset);
+		return -EAGAIN;
+	}
 
-		D1(printk(KERN_DEBUG "Verifying erase at 0x%08x\n", jeb->offset));
-		while(ofs < jeb->offset + c->sector_size) {
-			uint32_t readlen = min((uint32_t)PAGE_SIZE, jeb->offset + c->sector_size - ofs);
-			int i;
-
-			bad_offset = ofs;
-
-			ret = jffs2_flash_read(c, ofs, readlen, &retlen, ebuf);
-			if (ret) {
-				printk(KERN_WARNING "Read of newly-erased block at 0x%08x failed: %d. Putting on bad_list\n", ofs, ret);
-				goto bad;
-			}
-			if (retlen != readlen) {
-				printk(KERN_WARNING "Short read from newly-erased block at 0x%08x. Wanted %d, got %zd\n", ofs, readlen, retlen);
-				goto bad;
-			}
-			for (i=0; i<readlen; i += sizeof(unsigned long)) {
-				/* It's OK. We know it's properly aligned */
-				unsigned long datum = *(unsigned long *)(&ebuf[i]);
-				if (datum + 1) {
-					bad_offset += i;
-					printk(KERN_WARNING "Newly-erased block contained word 0x%lx at offset 0x%08x\n", datum, bad_offset);
-				bad: 
-					if (!jffs2_cleanmarker_oob(c))
-						jffs2_free_raw_node_ref(marker_ref);
-					kfree(ebuf);
-				bad2:
-					spin_lock(&c->erase_completion_lock);
-					/* Stick it on a list (any list) so
-					   erase_failed can take it right off
-					   again.  Silly, but shouldn't happen
-					   often. */
-					list_add(&jeb->list, &c->erasing_list);
-					spin_unlock(&c->erase_completion_lock);
-					jffs2_erase_failed(c, jeb, bad_offset);
-					return;
-				}
+	D1(printk(KERN_DEBUG "Verifying erase at 0x%08x\n", jeb->offset));
+
+	for (ofs = jeb->offset; ofs < jeb->offset + c->sector_size; ) {
+		uint32_t readlen = min((uint32_t)PAGE_SIZE, jeb->offset + c->sector_size - ofs);
+		int i;
+
+		*bad_offset = ofs;
+
+		ret = jffs2_flash_read(c, ofs, readlen, &retlen, ebuf);
+		if (ret) {
+			printk(KERN_WARNING "Read of newly-erased block at 0x%08x failed: %d. Putting on bad_list\n", ofs, ret);
+			goto fail;
+		}
+		if (retlen != readlen) {
+			printk(KERN_WARNING "Short read from newly-erased block at 0x%08x. Wanted %d, got %zd\n", ofs, readlen, retlen);
+			goto fail;
+		}
+		for (i=0; i<readlen; i += sizeof(unsigned long)) {
+			/* It's OK. We know it's properly aligned */
+			unsigned long *datum = ebuf + i;
+			if (*datum + 1) {
+				*bad_offset += i;
+				printk(KERN_WARNING "Newly-erased block contained word 0x%lx at offset 0x%08x\n", *datum, *bad_offset);
+				goto fail;
 			}
-			ofs += readlen;
-			cond_resched();
 		}
-		kfree(ebuf);
+		ofs += readlen;
+		cond_resched();
 	}
+	ret = 0;
+fail:
+	kfree(ebuf);
+	return ret;
+}
 
-	bad_offset = jeb->offset;
+static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb)
+{
+	struct jffs2_raw_node_ref *marker_ref = NULL;
+	size_t retlen;
+	int ret;
+	uint32_t bad_offset;
+
+	switch (jffs2_block_check_erase(c, jeb, &bad_offset)) {
+	case -EAGAIN:	goto refile;
+	case -EIO:	goto filebad;
+	}
 
 	/* Write the erase complete marker */	
 	D1(printk(KERN_DEBUG "Writing erased marker to block at 0x%08x\n", jeb->offset));
-	if (jffs2_cleanmarker_oob(c)) {
+	bad_offset = jeb->offset;
 
-		if (jffs2_write_nand_cleanmarker(c, jeb))
-			goto bad2;
-			
-		jeb->first_node = jeb->last_node = NULL;
+	/* Cleanmarker in oob area or no cleanmarker at all ? */
+	if (jffs2_cleanmarker_oob(c) || c->cleanmarker_size == 0) {
 
+		if (jffs2_cleanmarker_oob(c)) {
+			if (jffs2_write_nand_cleanmarker(c, jeb))
+				goto filebad;
+		}
+
+		jeb->first_node = jeb->last_node = NULL;
 		jeb->free_size = c->sector_size;
 		jeb->used_size = 0;
 		jeb->dirty_size = 0;
 		jeb->wasted_size = 0;
+
 	} else {
+
 		struct kvec vecs[1];
 		struct jffs2_unknown_node marker = {
 			.magic =	cpu_to_je16(JFFS2_MAGIC_BITMASK),
@@ -395,21 +387,28 @@ static void jffs2_mark_erased_block(stru
 			.totlen =	cpu_to_je32(c->cleanmarker_size)
 		};
 
+		marker_ref = jffs2_alloc_raw_node_ref();
+		if (!marker_ref) {
+			printk(KERN_WARNING "Failed to allocate raw node ref for clean marker. Refiling\n");
+			goto refile;
+		}
+
 		marker.hdr_crc = cpu_to_je32(crc32(0, &marker, sizeof(struct jffs2_unknown_node)-4));
 
 		vecs[0].iov_base = (unsigned char *) &marker;
 		vecs[0].iov_len = sizeof(marker);
 		ret = jffs2_flash_direct_writev(c, vecs, 1, jeb->offset, &retlen);
 		
-		if (ret) {
-			printk(KERN_WARNING "Write clean marker to block at 0x%08x failed: %d\n",
-			       jeb->offset, ret);
-			goto bad2;
-		}
-		if (retlen != sizeof(marker)) {
-			printk(KERN_WARNING "Short write to newly-erased block at 0x%08x: Wanted %zd, got %zd\n",
-			       jeb->offset, sizeof(marker), retlen);
-			goto bad2;
+		if (ret || retlen != sizeof(marker)) {
+			if (ret)
+				printk(KERN_WARNING "Write clean marker to block at 0x%08x failed: %d\n",
+				       jeb->offset, ret);
+			else
+				printk(KERN_WARNING "Short write to newly-erased block at 0x%08x: Wanted %zd, got %zd\n",
+				       jeb->offset, sizeof(marker), retlen);
+
+			jffs2_free_raw_node_ref(marker_ref);
+			goto filebad;
 		}
 
 		marker_ref->next_in_ino = NULL;
@@ -438,5 +437,22 @@ static void jffs2_mark_erased_block(stru
 	c->nr_free_blocks++;
 	spin_unlock(&c->erase_completion_lock);
 	wake_up(&c->erase_wait);
-}
+	return;
+
+filebad:
+	spin_lock(&c->erase_completion_lock);
+	/* Stick it on a list (any list) so erase_failed can take it
+	   right off again.  Silly, but shouldn't happen often. */
+	list_add(&jeb->list, &c->erasing_list);
+	spin_unlock(&c->erase_completion_lock);
+	jffs2_erase_failed(c, jeb, bad_offset);
+	return;
 
+refile:
+	/* Stick it back on the list from whence it came and come back later */
+	jffs2_erase_pending_trigger(c);
+	spin_lock(&c->erase_completion_lock);
+	list_add(&jeb->list, &c->erase_complete_list);
+	spin_unlock(&c->erase_completion_lock);
+	return;
+}
diff --git a/fs/jffs2/file.c b/fs/jffs2/file.c
--- a/fs/jffs2/file.c
+++ b/fs/jffs2/file.c
@@ -7,11 +7,10 @@
  *
  * For licensing information, see the file 'LICENCE' in this directory.
  *
- * $Id: file.c,v 1.99 2004/11/16 20:36:11 dwmw2 Exp $
+ * $Id: file.c,v 1.102 2005/07/06 12:13:09 dwmw2 Exp $
  *
  */
 
-#include <linux/version.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/fs.h>
@@ -51,9 +50,7 @@ struct file_operations jffs2_file_operat
 	.ioctl =	jffs2_ioctl,
 	.mmap =		generic_file_readonly_mmap,
 	.fsync =	jffs2_fsync,
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,29)
 	.sendfile =	generic_file_sendfile
-#endif
 };
 
 /* jffs2_file_inode_operations */
diff --git a/fs/jffs2/fs.c b/fs/jffs2/fs.c
--- a/fs/jffs2/fs.c
+++ b/fs/jffs2/fs.c
@@ -7,11 +7,10 @@
  *
  * For licensing information, see the file 'LICENCE' in this directory.
  *
- * $Id: fs.c,v 1.51 2004/11/28 12:19:37 dedekind Exp $
+ * $Id: fs.c,v 1.56 2005/07/06 12:13:09 dwmw2 Exp $
  *
  */
 
-#include <linux/version.h>
 #include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
@@ -450,11 +449,15 @@ int jffs2_do_fill_super(struct super_blo
 
 	c = JFFS2_SB_INFO(sb);
 
-#ifndef CONFIG_JFFS2_FS_NAND
+#ifndef CONFIG_JFFS2_FS_WRITEBUFFER
 	if (c->mtd->type == MTD_NANDFLASH) {
 		printk(KERN_ERR "jffs2: Cannot operate on NAND flash unless jffs2 NAND support is compiled in.\n");
 		return -EINVAL;
 	}
+	if (c->mtd->type == MTD_DATAFLASH) {
+		printk(KERN_ERR "jffs2: Cannot operate on DataFlash unless jffs2 DataFlash support is compiled in.\n");
+		return -EINVAL;
+	}
 #endif
 
 	c->flash_size = c->mtd->size;
@@ -522,9 +525,7 @@ int jffs2_do_fill_super(struct super_blo
 	if (!sb->s_root)
 		goto out_root_i;
 
-#if LINUX_VERSION_CODE >= 0x20403
 	sb->s_maxbytes = 0xFFFFFFFF;
-#endif
 	sb->s_blocksize = PAGE_CACHE_SIZE;
 	sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
 	sb->s_magic = JFFS2_SUPER_MAGIC;
@@ -661,6 +662,14 @@ static int jffs2_flash_setup(struct jffs
 		if (ret)
 			return ret;
 	}
+	
+	/* and Dataflash */
+	if (jffs2_dataflash(c)) {
+		ret = jffs2_dataflash_setup(c);
+		if (ret)
+			return ret;
+	}
+	
 	return ret;
 }
 
@@ -674,4 +683,9 @@ void jffs2_flash_cleanup(struct jffs2_sb
 	if (jffs2_nor_ecc(c)) {
 		jffs2_nor_ecc_flash_cleanup(c);
 	}
+	
+	/* and DataFlash */
+	if (jffs2_dataflash(c)) {
+		jffs2_dataflash_cleanup(c);
+	}
 }
diff --git a/fs/jffs2/gc.c b/fs/jffs2/gc.c
--- a/fs/jffs2/gc.c
+++ b/fs/jffs2/gc.c
@@ -7,7 +7,7 @@
  *
  * For licensing information, see the file 'LICENCE' in this directory.
  *
- * $Id: gc.c,v 1.144 2004/12/21 11:18:50 dwmw2 Exp $
+ * $Id: gc.c,v 1.148 2005/04/09 10:47:00 dedekind Exp $
  *
  */
 
@@ -50,6 +50,7 @@ static struct jffs2_eraseblock *jffs2_fi
 	   put the clever wear-levelling algorithms. Eventually.  */
 	/* We possibly want to favour the dirtier blocks more when the
 	   number of free blocks is low. */
+again:
 	if (!list_empty(&c->bad_used_list) && c->nr_free_blocks > c->resv_blocks_gcbad) {
 		D1(printk(KERN_DEBUG "Picking block from bad_used_list to GC next\n"));
 		nextlist = &c->bad_used_list;
@@ -79,6 +80,13 @@ static struct jffs2_eraseblock *jffs2_fi
 		D1(printk(KERN_DEBUG "Picking block from erasable_list to GC next (clean_list and {very_,}dirty_list were empty)\n"));
 
 		nextlist = &c->erasable_list;
+	} else if (!list_empty(&c->erasable_pending_wbuf_list)) {
+		/* There are blocks are wating for the wbuf sync */
+		D1(printk(KERN_DEBUG "Synching wbuf in order to reuse erasable_pending_wbuf_list blocks\n"));
+		spin_unlock(&c->erase_completion_lock);
+		jffs2_flush_wbuf_pad(c);
+		spin_lock(&c->erase_completion_lock);
+		goto again;
 	} else {
 		/* Eep. All were empty */
 		D1(printk(KERN_NOTICE "jffs2: No clean, dirty _or_ erasable blocks to GC from! Where are they all?\n"));
@@ -661,9 +669,10 @@ static int jffs2_garbage_collect_metadat
 {
 	struct jffs2_full_dnode *new_fn;
 	struct jffs2_raw_inode ri;
+	struct jffs2_node_frag *last_frag;
 	jint16_t dev;
 	char *mdata = NULL, mdatalen = 0;
-	uint32_t alloclen, phys_ofs;
+	uint32_t alloclen, phys_ofs, ilen;
 	int ret;
 
 	if (S_ISBLK(JFFS2_F_I_MODE(f)) ||
@@ -699,6 +708,14 @@ static int jffs2_garbage_collect_metadat
 		goto out;
 	}
 	
+	last_frag = frag_last(&f->fragtree);
+	if (last_frag)
+		/* Fetch the inode length from the fragtree rather then
+		 * from i_size since i_size may have not been updated yet */
+		ilen = last_frag->ofs + last_frag->size;
+	else
+		ilen = JFFS2_F_I_SIZE(f);
+	
 	memset(&ri, 0, sizeof(ri));
 	ri.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
 	ri.nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE);
@@ -710,7 +727,7 @@ static int jffs2_garbage_collect_metadat
 	ri.mode = cpu_to_jemode(JFFS2_F_I_MODE(f));
 	ri.uid = cpu_to_je16(JFFS2_F_I_UID(f));
 	ri.gid = cpu_to_je16(JFFS2_F_I_GID(f));
-	ri.isize = cpu_to_je32(JFFS2_F_I_SIZE(f));
+	ri.isize = cpu_to_je32(ilen);
 	ri.atime = cpu_to_je32(JFFS2_F_I_ATIME(f));
 	ri.ctime = cpu_to_je32(JFFS2_F_I_CTIME(f));
 	ri.mtime = cpu_to_je32(JFFS2_F_I_MTIME(f));
@@ -816,8 +833,7 @@ static int jffs2_garbage_collect_deletio
 
 			/* Doesn't matter if there's one in the same erase block. We're going to 
 			   delete it too at the same time. */
-			if ((raw->flash_offset & ~(c->sector_size-1)) ==
-			    (fd->raw->flash_offset & ~(c->sector_size-1)))
+			if (SECTOR_ADDR(raw->flash_offset) == SECTOR_ADDR(fd->raw->flash_offset))
 				continue;
 
 			D1(printk(KERN_DEBUG "Check potential deletion dirent at %08x\n", ref_offset(raw)));
@@ -891,7 +907,7 @@ static int jffs2_garbage_collect_hole(st
 	struct jffs2_raw_inode ri;
 	struct jffs2_node_frag *frag;
 	struct jffs2_full_dnode *new_fn;
-	uint32_t alloclen, phys_ofs;
+	uint32_t alloclen, phys_ofs, ilen;
 	int ret;
 
 	D1(printk(KERN_DEBUG "Writing replacement hole node for ino #%u from offset 0x%x to 0x%x\n",
@@ -951,10 +967,19 @@ static int jffs2_garbage_collect_hole(st
 		ri.csize = cpu_to_je32(0);
 		ri.compr = JFFS2_COMPR_ZERO;
 	}
+	
+	frag = frag_last(&f->fragtree);
+	if (frag)
+		/* Fetch the inode length from the fragtree rather then
+		 * from i_size since i_size may have not been updated yet */
+		ilen = frag->ofs + frag->size;
+	else
+		ilen = JFFS2_F_I_SIZE(f);
+
 	ri.mode = cpu_to_jemode(JFFS2_F_I_MODE(f));
 	ri.uid = cpu_to_je16(JFFS2_F_I_UID(f));
 	ri.gid = cpu_to_je16(JFFS2_F_I_GID(f));
-	ri.isize = cpu_to_je32(JFFS2_F_I_SIZE(f));
+	ri.isize = cpu_to_je32(ilen);
 	ri.atime = cpu_to_je32(JFFS2_F_I_ATIME(f));
 	ri.ctime = cpu_to_je32(JFFS2_F_I_CTIME(f));
 	ri.mtime = cpu_to_je32(JFFS2_F_I_MTIME(f));
@@ -1161,7 +1186,7 @@ static int jffs2_garbage_collect_dnode(s
 		D1(printk(KERN_DEBUG "Expanded dnode to write from (0x%x-0x%x) to (0x%x-0x%x)\n", 
 			  orig_start, orig_end, start, end));
 
-		BUG_ON(end > JFFS2_F_I_SIZE(f));
+		D1(BUG_ON(end > frag_last(&f->fragtree)->ofs + frag_last(&f->fragtree)->size));
 		BUG_ON(end < orig_end);
 		BUG_ON(start > orig_start);
 	}
diff --git a/fs/jffs2/nodelist.c b/fs/jffs2/nodelist.c
--- a/fs/jffs2/nodelist.c
+++ b/fs/jffs2/nodelist.c
@@ -7,7 +7,7 @@
  *
  * For licensing information, see the file 'LICENCE' in this directory.
  *
- * $Id: nodelist.c,v 1.90 2004/12/08 17:59:20 dwmw2 Exp $
+ * $Id: nodelist.c,v 1.98 2005/07/10 15:15:32 dedekind Exp $
  *
  */
 
@@ -55,30 +55,63 @@ void jffs2_add_fd_to_list(struct jffs2_s
 	});
 }
 
-/* Put a new tmp_dnode_info into the list, keeping the list in 
-   order of increasing version
-*/
-static void jffs2_add_tn_to_list(struct jffs2_tmp_dnode_info *tn, struct jffs2_tmp_dnode_info **list)
+/* 
+ * Put a new tmp_dnode_info into the temporaty RB-tree, keeping the list in 
+ * order of increasing version.
+ */
+static void jffs2_add_tn_to_tree(struct jffs2_tmp_dnode_info *tn, struct rb_root *list)
 {
-	struct jffs2_tmp_dnode_info **prev = list;
-	
-	while ((*prev) && (*prev)->version < tn->version) {
-		prev = &((*prev)->next);
-	}
-	tn->next = (*prev);
-        *prev = tn;
-}
+	struct rb_node **p = &list->rb_node;
+	struct rb_node * parent = NULL;
+	struct jffs2_tmp_dnode_info *this;
+
+	while (*p) {
+		parent = *p;
+		this = rb_entry(parent, struct jffs2_tmp_dnode_info, rb);
+
+		/* There may actually be a collision here, but it doesn't
+		   actually matter. As long as the two nodes with the same
+		   version are together, it's all fine. */
+		if (tn->version < this->version)
+			p = &(*p)->rb_left;
+		else
+			p = &(*p)->rb_right;
+        }
+
+	rb_link_node(&tn->rb, parent, p);
+	rb_insert_color(&tn->rb, list);
+}
+
+static void jffs2_free_tmp_dnode_info_list(struct rb_root *list)
+{
+	struct rb_node *this;
+	struct jffs2_tmp_dnode_info *tn;
+
+	this = list->rb_node;
+
+	/* Now at bottom of tree */
+	while (this) {
+		if (this->rb_left)
+			this = this->rb_left;
+		else if (this->rb_right)
+			this = this->rb_right;
+		else {
+			tn = rb_entry(this, struct jffs2_tmp_dnode_info, rb);
+			jffs2_free_full_dnode(tn->fn);
+			jffs2_free_tmp_dnode_info(tn);
 
-static void jffs2_free_tmp_dnode_info_list(struct jffs2_tmp_dnode_info *tn)
-{
-	struct jffs2_tmp_dnode_info *next;
+			this = this->rb_parent;
+			if (!this)
+				break;
 
-	while (tn) {
-		next = tn;
-		tn = tn->next;
-		jffs2_free_full_dnode(next->fn);
-		jffs2_free_tmp_dnode_info(next);
+			if (this->rb_left == &tn->rb)
+				this->rb_left = NULL;
+			else if (this->rb_right == &tn->rb)
+				this->rb_right = NULL;
+			else BUG();
+		}
 	}
+	list->rb_node = NULL;
 }
 
 static void jffs2_free_full_dirent_list(struct jffs2_full_dirent *fd)
@@ -108,12 +141,13 @@ static struct jffs2_raw_node_ref *jffs2_
    with this ino, returning the former in order of version */
 
 int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
-			  struct jffs2_tmp_dnode_info **tnp, struct jffs2_full_dirent **fdp,
+			  struct rb_root *tnp, struct jffs2_full_dirent **fdp,
 			  uint32_t *highest_version, uint32_t *latest_mctime,
 			  uint32_t *mctime_ver)
 {
 	struct jffs2_raw_node_ref *ref, *valid_ref;
-	struct jffs2_tmp_dnode_info *tn, *ret_tn = NULL;
+	struct jffs2_tmp_dnode_info *tn;
+	struct rb_root ret_tn = RB_ROOT;
 	struct jffs2_full_dirent *fd, *ret_fd = NULL;
 	union jffs2_node_union node;
 	size_t retlen;
@@ -127,7 +161,7 @@ int jffs2_get_inode_nodes(struct jffs2_s
 
 	valid_ref = jffs2_first_valid_node(f->inocache->nodes);
 
-	if (!valid_ref)
+	if (!valid_ref && (f->inocache->ino != 1))
 		printk(KERN_WARNING "Eep. No valid nodes for ino #%u\n", f->inocache->ino);
 
 	while (valid_ref) {
@@ -386,7 +420,7 @@ int jffs2_get_inode_nodes(struct jffs2_s
 			D1(printk(KERN_DEBUG "dnode @%08x: ver %u, offset %04x, dsize %04x\n",
 				  ref_offset(ref), je32_to_cpu(node.i.version),
 				  je32_to_cpu(node.i.offset), je32_to_cpu(node.i.dsize)));
-			jffs2_add_tn_to_list(tn, &ret_tn);
+			jffs2_add_tn_to_tree(tn, &ret_tn);
 			break;
 
 		default:
@@ -450,7 +484,7 @@ int jffs2_get_inode_nodes(struct jffs2_s
 	return 0;
 
  free_out:
-	jffs2_free_tmp_dnode_info_list(ret_tn);
+	jffs2_free_tmp_dnode_info_list(&ret_tn);
 	jffs2_free_full_dirent_list(ret_fd);
 	return err;
 }
@@ -489,9 +523,13 @@ struct jffs2_inode_cache *jffs2_get_ino_
 void jffs2_add_ino_cache (struct jffs2_sb_info *c, struct jffs2_inode_cache *new)
 {
 	struct jffs2_inode_cache **prev;
-	D2(printk(KERN_DEBUG "jffs2_add_ino_cache: Add %p (ino #%u)\n", new, new->ino));
+
 	spin_lock(&c->inocache_lock);
-	
+	if (!new->ino)
+		new->ino = ++c->highest_ino;
+
+	D2(printk(KERN_DEBUG "jffs2_add_ino_cache: Add %p (ino #%u)\n", new, new->ino));
+
 	prev = &c->inocache_list[new->ino % INOCACHE_HASHSIZE];
 
 	while ((*prev) && (*prev)->ino < new->ino) {
@@ -506,7 +544,7 @@ void jffs2_add_ino_cache (struct jffs2_s
 void jffs2_del_ino_cache(struct jffs2_sb_info *c, struct jffs2_inode_cache *old)
 {
 	struct jffs2_inode_cache **prev;
-	D2(printk(KERN_DEBUG "jffs2_del_ino_cache: Del %p (ino #%u)\n", old, old->ino));
+	D1(printk(KERN_DEBUG "jffs2_del_ino_cache: Del %p (ino #%u)\n", old, old->ino));
 	spin_lock(&c->inocache_lock);
 	
 	prev = &c->inocache_list[old->ino % INOCACHE_HASHSIZE];
@@ -518,6 +556,14 @@ void jffs2_del_ino_cache(struct jffs2_sb
 		*prev = old->next;
 	}
 
+	/* Free it now unless it's in READING or CLEARING state, which
+	   are the transitions upon read_inode() and clear_inode(). The
+	   rest of the time we know nobody else is looking at it, and 
+	   if it's held by read_inode() or clear_inode() they'll free it
+	   for themselves. */
+	if (old->state != INO_STATE_READING && old->state != INO_STATE_CLEARING)
+		jffs2_free_inode_cache(old);
+
 	spin_unlock(&c->inocache_lock);
 }
 
@@ -530,7 +576,6 @@ void jffs2_free_ino_caches(struct jffs2_
 		this = c->inocache_list[i];
 		while (this) {
 			next = this->next;
-			D2(printk(KERN_DEBUG "jffs2_free_ino_caches: Freeing ino #%u at %p\n", this->ino, this));
 			jffs2_free_inode_cache(this);
 			this = next;
 		}
diff --git a/fs/jffs2/nodelist.h b/fs/jffs2/nodelist.h
--- a/fs/jffs2/nodelist.h
+++ b/fs/jffs2/nodelist.h
@@ -7,7 +7,7 @@
  *
  * For licensing information, see the file 'LICENCE' in this directory.
  *
- * $Id: nodelist.h,v 1.126 2004/11/19 15:06:29 dedekind Exp $
+ * $Id: nodelist.h,v 1.131 2005/07/05 21:03:07 dwmw2 Exp $
  *
  */
 
@@ -135,6 +135,7 @@ struct jffs2_inode_cache {
 #define INO_STATE_CHECKEDABSENT	3	/* Checked, cleared again */
 #define INO_STATE_GC		4	/* GCing a 'pristine' node */
 #define INO_STATE_READING	5	/* In read_inode() */
+#define INO_STATE_CLEARING	6	/* In clear_inode() */
 
 #define INOCACHE_HASHSIZE 128
 
@@ -160,7 +161,7 @@ struct jffs2_full_dnode
 */
 struct jffs2_tmp_dnode_info
 {
-	struct jffs2_tmp_dnode_info *next;
+	struct rb_node rb;
 	struct jffs2_full_dnode *fn;
 	uint32_t version;
 };       
@@ -362,6 +363,18 @@ static inline struct jffs2_node_frag *fr
 		node = node->rb_left;
 	return rb_entry(node, struct jffs2_node_frag, rb);
 }
+
+static inline struct jffs2_node_frag *frag_last(struct rb_root *root)
+{
+	struct rb_node *node = root->rb_node;
+
+	if (!node)
+		return NULL;
+	while(node->rb_right)
+		node = node->rb_right;
+	return rb_entry(node, struct jffs2_node_frag, rb);
+}
+
 #define rb_parent(rb) ((rb)->rb_parent)
 #define frag_next(frag) rb_entry(rb_next(&(frag)->rb), struct jffs2_node_frag, rb)
 #define frag_prev(frag) rb_entry(rb_prev(&(frag)->rb), struct jffs2_node_frag, rb)
@@ -374,7 +387,7 @@ static inline struct jffs2_node_frag *fr
 D2(void jffs2_print_frag_list(struct jffs2_inode_info *f));
 void jffs2_add_fd_to_list(struct jffs2_sb_info *c, struct jffs2_full_dirent *new, struct jffs2_full_dirent **list);
 int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
-			  struct jffs2_tmp_dnode_info **tnp, struct jffs2_full_dirent **fdp,
+			  struct rb_root *tnp, struct jffs2_full_dirent **fdp,
 			  uint32_t *highest_version, uint32_t *latest_mctime,
 			  uint32_t *mctime_ver);
 void jffs2_set_inocache_state(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic, int state);
@@ -462,7 +475,7 @@ int jffs2_do_mount_fs(struct jffs2_sb_in
 /* erase.c */
 void jffs2_erase_pending_blocks(struct jffs2_sb_info *c, int count);
 
-#ifdef CONFIG_JFFS2_FS_NAND
+#ifdef CONFIG_JFFS2_FS_WRITEBUFFER
 /* wbuf.c */
 int jffs2_flush_wbuf_gc(struct jffs2_sb_info *c, uint32_t ino);
 int jffs2_flush_wbuf_pad(struct jffs2_sb_info *c);
diff --git a/fs/jffs2/nodemgmt.c b/fs/jffs2/nodemgmt.c
--- a/fs/jffs2/nodemgmt.c
+++ b/fs/jffs2/nodemgmt.c
@@ -7,7 +7,7 @@
  *
  * For licensing information, see the file 'LICENCE' in this directory.
  *
- * $Id: nodemgmt.c,v 1.115 2004/11/22 11:07:21 dwmw2 Exp $
+ * $Id: nodemgmt.c,v 1.122 2005/05/06 09:30:27 dedekind Exp $
  *
  */
 
@@ -75,7 +75,7 @@ int jffs2_reserve_space(struct jffs2_sb_
 			dirty = c->dirty_size + c->erasing_size - c->nr_erasing_blocks * c->sector_size + c->unchecked_size;
 			if (dirty < c->nospc_dirty_size) {
 				if (prio == ALLOC_DELETION && c->nr_free_blocks + c->nr_erasing_blocks >= c->resv_blocks_deletion) {
-					printk(KERN_NOTICE "jffs2_reserve_space(): Low on dirty space to GC, but it's a deletion. Allowing...\n");
+					D1(printk(KERN_NOTICE "jffs2_reserve_space(): Low on dirty space to GC, but it's a deletion. Allowing...\n"));
 					break;
 				}
 				D1(printk(KERN_DEBUG "dirty size 0x%08x + unchecked_size 0x%08x < nospc_dirty_size 0x%08x, returning -ENOSPC\n",
@@ -98,7 +98,7 @@ int jffs2_reserve_space(struct jffs2_sb_
 			avail = c->free_size + c->dirty_size + c->erasing_size + c->unchecked_size;
 			if ( (avail / c->sector_size) <= blocksneeded) {
 				if (prio == ALLOC_DELETION && c->nr_free_blocks + c->nr_erasing_blocks >= c->resv_blocks_deletion) {
-					printk(KERN_NOTICE "jffs2_reserve_space(): Low on possibly available space, but it's a deletion. Allowing...\n");
+					D1(printk(KERN_NOTICE "jffs2_reserve_space(): Low on possibly available space, but it's a deletion. Allowing...\n"));
 					break;
 				}
 
@@ -308,7 +308,10 @@ int jffs2_add_physical_node_ref(struct j
 
 	D1(printk(KERN_DEBUG "jffs2_add_physical_node_ref(): Node at 0x%x(%d), size 0x%x\n", ref_offset(new), ref_flags(new), len));
 #if 1
-	if (jeb != c->nextblock || (ref_offset(new)) != jeb->offset + (c->sector_size - jeb->free_size)) {
+	/* we could get some obsolete nodes after nextblock was refiled
+	   in wbuf.c */
+	if ((c->nextblock || !ref_obsolete(new))
+	    &&(jeb != c->nextblock || ref_offset(new) != jeb->offset + (c->sector_size - jeb->free_size))) {
 		printk(KERN_WARNING "argh. node added in wrong place\n");
 		jffs2_free_raw_node_ref(new);
 		return -EINVAL;
@@ -332,7 +335,7 @@ int jffs2_add_physical_node_ref(struct j
 		c->used_size += len;
 	}
 
-	if (!jeb->free_size && !jeb->dirty_size) {
+	if (!jeb->free_size && !jeb->dirty_size && !ISDIRTY(jeb->wasted_size)) {
 		/* If it lives on the dirty_list, jffs2_reserve_space will put it there */
 		D1(printk(KERN_DEBUG "Adding full erase block at 0x%08x to clean_list (free 0x%08x, dirty 0x%08x, used 0x%08x\n",
 			  jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size));
@@ -400,7 +403,7 @@ void jffs2_mark_node_obsolete(struct jff
 	jeb = &c->blocks[blocknr];
 
 	if (jffs2_can_mark_obsolete(c) && !jffs2_is_readonly(c) &&
-	    !(c->flags & JFFS2_SB_FLAG_MOUNTING)) {
+	    !(c->flags & (JFFS2_SB_FLAG_SCANNING | JFFS2_SB_FLAG_BUILDING))) {
 		/* Hm. This may confuse static lock analysis. If any of the above 
 		   three conditions is false, we're going to return from this 
 		   function without actually obliterating any nodes or freeing
@@ -434,7 +437,7 @@ void jffs2_mark_node_obsolete(struct jff
 
 	// Take care, that wasted size is taken into concern
 	if ((jeb->dirty_size || ISDIRTY(jeb->wasted_size + ref_totlen(c, jeb, ref))) && jeb != c->nextblock) {
-		D1(printk("Dirtying\n"));
+		D1(printk(KERN_DEBUG "Dirtying\n"));
 		addedsize = ref_totlen(c, jeb, ref);
 		jeb->dirty_size += ref_totlen(c, jeb, ref);
 		c->dirty_size += ref_totlen(c, jeb, ref);
@@ -456,7 +459,7 @@ void jffs2_mark_node_obsolete(struct jff
 			}
 		}
 	} else {
-		D1(printk("Wasting\n"));
+		D1(printk(KERN_DEBUG "Wasting\n"));
 		addedsize = 0;
 		jeb->wasted_size += ref_totlen(c, jeb, ref);
 		c->wasted_size += ref_totlen(c, jeb, ref);	
@@ -467,8 +470,8 @@ void jffs2_mark_node_obsolete(struct jff
 
 	D1(ACCT_PARANOIA_CHECK(jeb));
 
-	if (c->flags & JFFS2_SB_FLAG_MOUNTING) {
-		/* Mount in progress. Don't muck about with the block
+	if (c->flags & JFFS2_SB_FLAG_SCANNING) {
+		/* Flash scanning is in progress. Don't muck about with the block
 		   lists because they're not ready yet, and don't actually
 		   obliterate nodes that look obsolete. If they weren't 
 		   marked obsolete on the flash at the time they _became_
@@ -527,7 +530,8 @@ void jffs2_mark_node_obsolete(struct jff
 
 	spin_unlock(&c->erase_completion_lock);
 
-	if (!jffs2_can_mark_obsolete(c) || jffs2_is_readonly(c)) {
+	if (!jffs2_can_mark_obsolete(c) || jffs2_is_readonly(c) ||
+		(c->flags & JFFS2_SB_FLAG_BUILDING)) {
 		/* We didn't lock the erase_free_sem */
 		return;
 	}
@@ -590,11 +594,8 @@ void jffs2_mark_node_obsolete(struct jff
 		*p = ref->next_in_ino;
 		ref->next_in_ino = NULL;
 
-		if (ic->nodes == (void *)ic) {
-			D1(printk(KERN_DEBUG "inocache for ino #%u is all gone now. Freeing\n", ic->ino));
+		if (ic->nodes == (void *)ic && ic->nlink == 0)
 			jffs2_del_ino_cache(c, ic);
-			jffs2_free_inode_cache(ic);
-		}
 
 		spin_unlock(&c->erase_completion_lock);
 	}
diff --git a/fs/jffs2/os-linux.h b/fs/jffs2/os-linux.h
--- a/fs/jffs2/os-linux.h
+++ b/fs/jffs2/os-linux.h
@@ -7,41 +7,24 @@
  *
  * For licensing information, see the file 'LICENCE' in this directory.
  *
- * $Id: os-linux.h,v 1.51 2004/11/16 20:36:11 dwmw2 Exp $
+ * $Id: os-linux.h,v 1.58 2005/07/12 02:34:35 tpoynor Exp $
  *
  */
 
 #ifndef __JFFS2_OS_LINUX_H__
 #define __JFFS2_OS_LINUX_H__
-#include <linux/version.h>
 
 /* JFFS2 uses Linux mode bits natively -- no need for conversion */
 #define os_to_jffs2_mode(x) (x)
 #define jffs2_to_os_mode(x) (x)
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,73)
-#define kstatfs statfs
-#endif
-
 struct kstatfs;
 struct kvec;
 
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,2)
 #define JFFS2_INODE_INFO(i) (list_entry(i, struct jffs2_inode_info, vfs_inode))
 #define OFNI_EDONI_2SFFJ(f)  (&(f)->vfs_inode)
 #define JFFS2_SB_INFO(sb) (sb->s_fs_info)
 #define OFNI_BS_2SFFJ(c)  ((struct super_block *)c->os_priv)
-#elif defined(JFFS2_OUT_OF_KERNEL)
-#define JFFS2_INODE_INFO(i) ((struct jffs2_inode_info *) &(i)->u)
-#define OFNI_EDONI_2SFFJ(f)  ((struct inode *) ( ((char *)f) - ((char *)(&((struct inode *)NULL)->u)) ) )
-#define JFFS2_SB_INFO(sb) ((struct jffs2_sb_info *) &(sb)->u)
-#define OFNI_BS_2SFFJ(c)  ((struct super_block *) ( ((char *)c) - ((char *)(&((struct super_block *)NULL)->u)) ) )
-#else
-#define JFFS2_INODE_INFO(i) (&i->u.jffs2_i)
-#define OFNI_EDONI_2SFFJ(f)  ((struct inode *) ( ((char *)f) - ((char *)(&((struct inode *)NULL)->u)) ) )
-#define JFFS2_SB_INFO(sb) (&sb->u.jffs2_sb)
-#define OFNI_BS_2SFFJ(c)  ((struct super_block *) ( ((char *)c) - ((char *)(&((struct super_block *)NULL)->u)) ) )
-#endif
 
 
 #define JFFS2_F_I_SIZE(f) (OFNI_EDONI_2SFFJ(f)->i_size)
@@ -49,28 +32,14 @@ struct kvec;
 #define JFFS2_F_I_UID(f) (OFNI_EDONI_2SFFJ(f)->i_uid)
 #define JFFS2_F_I_GID(f) (OFNI_EDONI_2SFFJ(f)->i_gid)
 
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,1)
 #define JFFS2_F_I_RDEV_MIN(f) (iminor(OFNI_EDONI_2SFFJ(f)))
 #define JFFS2_F_I_RDEV_MAJ(f) (imajor(OFNI_EDONI_2SFFJ(f)))
-#else
-#define JFFS2_F_I_RDEV_MIN(f) (MINOR(to_kdev_t(OFNI_EDONI_2SFFJ(f)->i_rdev)))
-#define JFFS2_F_I_RDEV_MAJ(f) (MAJOR(to_kdev_t(OFNI_EDONI_2SFFJ(f)->i_rdev)))
-#endif
 
-/* Urgh. The things we do to keep the 2.4 build working */
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,47)
 #define ITIME(sec) ((struct timespec){sec, 0})
 #define I_SEC(tv) ((tv).tv_sec)
 #define JFFS2_F_I_CTIME(f) (OFNI_EDONI_2SFFJ(f)->i_ctime.tv_sec)
 #define JFFS2_F_I_MTIME(f) (OFNI_EDONI_2SFFJ(f)->i_mtime.tv_sec)
 #define JFFS2_F_I_ATIME(f) (OFNI_EDONI_2SFFJ(f)->i_atime.tv_sec)
-#else
-#define ITIME(x) (x)
-#define I_SEC(x) (x)
-#define JFFS2_F_I_CTIME(f) (OFNI_EDONI_2SFFJ(f)->i_ctime)
-#define JFFS2_F_I_MTIME(f) (OFNI_EDONI_2SFFJ(f)->i_mtime)
-#define JFFS2_F_I_ATIME(f) (OFNI_EDONI_2SFFJ(f)->i_atime)
-#endif
 
 #define sleep_on_spinunlock(wq, s)				\
 	do {							\
@@ -84,23 +53,21 @@ struct kvec;
 
 static inline void jffs2_init_inode_info(struct jffs2_inode_info *f)
 {
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,2)
 	f->highest_version = 0;
 	f->fragtree = RB_ROOT;
 	f->metadata = NULL;
 	f->dents = NULL;
 	f->flags = 0;
 	f->usercompr = 0;
-#else
-	memset(f, 0, sizeof(*f));
-	init_MUTEX_LOCKED(&f->sem);
-#endif
 }
 
+
 #define jffs2_is_readonly(c) (OFNI_BS_2SFFJ(c)->s_flags & MS_RDONLY)
 
-#if (!defined CONFIG_JFFS2_FS_NAND && !defined CONFIG_JFFS2_FS_NOR_ECC)
+#ifndef CONFIG_JFFS2_FS_WRITEBUFFER
+#define SECTOR_ADDR(x) ( ((unsigned long)(x) & ~(c->sector_size-1)) )
 #define jffs2_can_mark_obsolete(c) (1)
+#define jffs2_is_writebuffered(c) (0)
 #define jffs2_cleanmarker_oob(c) (0)
 #define jffs2_write_nand_cleanmarker(c,jeb) (-EIO)
 
@@ -116,11 +83,16 @@ static inline void jffs2_init_inode_info
 #define jffs2_wbuf_timeout NULL
 #define jffs2_wbuf_process NULL
 #define jffs2_nor_ecc(c) (0)
+#define jffs2_dataflash(c) (0)
 #define jffs2_nor_ecc_flash_setup(c) (0)
 #define jffs2_nor_ecc_flash_cleanup(c) do {} while (0)
+#define jffs2_dataflash_setup(c) (0)
+#define jffs2_dataflash_cleanup(c) do {} while (0)
 
 #else /* NAND and/or ECC'd NOR support present */
 
+#define jffs2_is_writebuffered(c) (c->wbuf != NULL)
+#define SECTOR_ADDR(x) ( ((unsigned long)(x) / (unsigned long)(c->sector_size)) * c->sector_size )
 #define jffs2_can_mark_obsolete(c) ((c->mtd->type == MTD_NORFLASH && !(c->mtd->flags & MTD_ECC)) || c->mtd->type == MTD_RAM)
 #define jffs2_cleanmarker_oob(c) (c->mtd->type == MTD_NANDFLASH)
 
@@ -142,16 +114,16 @@ int jffs2_flush_wbuf_gc(struct jffs2_sb_
 int jffs2_flush_wbuf_pad(struct jffs2_sb_info *c);
 int jffs2_nand_flash_setup(struct jffs2_sb_info *c);
 void jffs2_nand_flash_cleanup(struct jffs2_sb_info *c);
-#ifdef CONFIG_JFFS2_FS_NOR_ECC
+
 #define jffs2_nor_ecc(c) (c->mtd->type == MTD_NORFLASH && (c->mtd->flags & MTD_ECC))
 int jffs2_nor_ecc_flash_setup(struct jffs2_sb_info *c);
 void jffs2_nor_ecc_flash_cleanup(struct jffs2_sb_info *c);
-#else
-#define jffs2_nor_ecc(c) (0)
-#define jffs2_nor_ecc_flash_setup(c) (0)
-#define jffs2_nor_ecc_flash_cleanup(c) do {} while (0)
-#endif /* NOR ECC */
-#endif /* NAND */
+
+#define jffs2_dataflash(c) (c->mtd->type == MTD_DATAFLASH)
+int jffs2_dataflash_setup(struct jffs2_sb_info *c);
+void jffs2_dataflash_cleanup(struct jffs2_sb_info *c);
+
+#endif /* WRITEBUFFER */
 
 /* erase.c */
 static inline void jffs2_erase_pending_trigger(struct jffs2_sb_info *c)
diff --git a/fs/jffs2/read.c b/fs/jffs2/read.c
--- a/fs/jffs2/read.c
+++ b/fs/jffs2/read.c
@@ -7,7 +7,7 @@
  *
  * For licensing information, see the file 'LICENCE' in this directory.
  *
- * $Id: read.c,v 1.38 2004/11/16 20:36:12 dwmw2 Exp $
+ * $Id: read.c,v 1.39 2005/03/01 10:34:03 dedekind Exp $
  *
  */
 
@@ -214,33 +214,3 @@ int jffs2_read_inode_range(struct jffs2_
 	return 0;
 }
 
-/* Core function to read symlink target. */
-char *jffs2_getlink(struct jffs2_sb_info *c, struct jffs2_inode_info *f)
-{
-	char *buf;
-	int ret;
-
-	down(&f->sem);
-
-	if (!f->metadata) {
-		printk(KERN_NOTICE "No metadata for symlink inode #%u\n", f->inocache->ino);
-		up(&f->sem);
-		return ERR_PTR(-EINVAL);
-	}
-	buf = kmalloc(f->metadata->size+1, GFP_USER);
-	if (!buf) {
-		up(&f->sem);
-		return ERR_PTR(-ENOMEM);
-	}
-	buf[f->metadata->size]=0;
-
-	ret = jffs2_read_dnode(c, f, f->metadata, buf, 0, f->metadata->size);
-
-	up(&f->sem);
-
-	if (ret) {
-		kfree(buf);
-		return ERR_PTR(ret);
-	}
-	return buf;
-}
diff --git a/fs/jffs2/readinode.c b/fs/jffs2/readinode.c
--- a/fs/jffs2/readinode.c
+++ b/fs/jffs2/readinode.c
@@ -7,7 +7,7 @@
  *
  * For licensing information, see the file 'LICENCE' in this directory.
  *
- * $Id: readinode.c,v 1.117 2004/11/20 18:06:54 dwmw2 Exp $
+ * $Id: readinode.c,v 1.125 2005/07/10 13:13:55 dedekind Exp $
  *
  */
 
@@ -151,6 +151,9 @@ int jffs2_add_full_dnode_to_inode(struct
 
 	D1(printk(KERN_DEBUG "jffs2_add_full_dnode_to_inode(ino #%u, f %p, fn %p)\n", f->inocache->ino, f, fn));
 
+	if (unlikely(!fn->size))
+		return 0;
+
 	newfrag = jffs2_alloc_node_frag();
 	if (unlikely(!newfrag))
 		return -ENOMEM;
@@ -158,11 +161,6 @@ int jffs2_add_full_dnode_to_inode(struct
 	D2(printk(KERN_DEBUG "adding node %04x-%04x @0x%08x on flash, newfrag *%p\n",
 		  fn->ofs, fn->ofs+fn->size, ref_offset(fn->raw), newfrag));
 	
-	if (unlikely(!fn->size)) {
-		jffs2_free_node_frag(newfrag);
-		return 0;
-	}
-
 	newfrag->ofs = fn->ofs;
 	newfrag->size = fn->size;
 	newfrag->node = fn;
@@ -500,7 +498,9 @@ static int jffs2_do_read_inode_internal(
 					struct jffs2_inode_info *f,
 					struct jffs2_raw_inode *latest_node)
 {
-	struct jffs2_tmp_dnode_info *tn_list, *tn;
+	struct jffs2_tmp_dnode_info *tn = NULL;
+	struct rb_root tn_list;
+	struct rb_node *rb, *repl_rb;
 	struct jffs2_full_dirent *fd_list;
 	struct jffs2_full_dnode *fn = NULL;
 	uint32_t crc;
@@ -522,9 +522,10 @@ static int jffs2_do_read_inode_internal(
 	}
 	f->dents = fd_list;
 
-	while (tn_list) {
-		tn = tn_list;
+	rb = rb_first(&tn_list);
 
+	while (rb) {
+		tn = rb_entry(rb, struct jffs2_tmp_dnode_info, rb);
 		fn = tn->fn;
 
 		if (f->metadata) {
@@ -556,7 +557,29 @@ static int jffs2_do_read_inode_internal(
 			mdata_ver = tn->version;
 		}
 	next_tn:
-		tn_list = tn->next;
+		BUG_ON(rb->rb_left);
+		if (rb->rb_parent && rb->rb_parent->rb_left == rb) {
+			/* We were then left-hand child of our parent. We need
+			   to move our own right-hand child into our place. */
+			repl_rb = rb->rb_right;
+			if (repl_rb)
+				repl_rb->rb_parent = rb->rb_parent;
+		} else
+			repl_rb = NULL;
+
+		rb = rb_next(rb);
+
+		/* Remove the spent tn from the tree; don't bother rebalancing
+		   but put our right-hand child in our own place. */
+		if (tn->rb.rb_parent) {
+			if (tn->rb.rb_parent->rb_left == &tn->rb)
+				tn->rb.rb_parent->rb_left = repl_rb;
+			else if (tn->rb.rb_parent->rb_right == &tn->rb)
+				tn->rb.rb_parent->rb_right = repl_rb;
+			else BUG();
+		} else if (tn->rb.rb_right)
+			tn->rb.rb_right->rb_parent = NULL;
+
 		jffs2_free_tmp_dnode_info(tn);
 	}
 	D1(jffs2_sanitycheck_fragtree(f));
@@ -623,6 +646,40 @@ static int jffs2_do_read_inode_internal(
 		   case. */
 		if (!je32_to_cpu(latest_node->isize))
 			latest_node->isize = latest_node->dsize;
+
+		if (f->inocache->state != INO_STATE_CHECKING) {
+			/* Symlink's inode data is the target path. Read it and
+			 * keep in RAM to facilitate quick follow symlink operation.
+			 * We use f->dents field to store the target path, which
+			 * is somewhat ugly. */
+			f->dents = kmalloc(je32_to_cpu(latest_node->csize) + 1, GFP_KERNEL);
+			if (!f->dents) {
+				printk(KERN_WARNING "Can't allocate %d bytes of memory "
+						"for the symlink target path cache\n",
+						je32_to_cpu(latest_node->csize));
+				up(&f->sem);
+				jffs2_do_clear_inode(c, f);
+				return -ENOMEM;
+			}
+			
+			ret = jffs2_flash_read(c, ref_offset(fn->raw) + sizeof(*latest_node),
+						je32_to_cpu(latest_node->csize), &retlen, (char *)f->dents);
+			
+			if (ret  || retlen != je32_to_cpu(latest_node->csize)) {
+				if (retlen != je32_to_cpu(latest_node->csize))
+					ret = -EIO;
+				kfree(f->dents);
+				f->dents = NULL;
+				up(&f->sem);
+				jffs2_do_clear_inode(c, f);
+				return -ret;
+			}
+
+			((char *)f->dents)[je32_to_cpu(latest_node->csize)] = '\0';
+			D1(printk(KERN_DEBUG "jffs2_do_read_inode(): symlink's target '%s' cached\n",
+						(char *)f->dents));
+		}
+		
 		/* fall through... */
 
 	case S_IFBLK:
@@ -672,6 +729,9 @@ void jffs2_do_clear_inode(struct jffs2_s
 	down(&f->sem);
 	deleted = f->inocache && !f->inocache->nlink;
 
+	if (f->inocache && f->inocache->state != INO_STATE_CHECKING)
+		jffs2_set_inocache_state(c, f->inocache, INO_STATE_CLEARING);
+
 	if (f->metadata) {
 		if (deleted)
 			jffs2_mark_node_obsolete(c, f->metadata->raw);
@@ -680,16 +740,27 @@ void jffs2_do_clear_inode(struct jffs2_s
 
 	jffs2_kill_fragtree(&f->fragtree, deleted?c:NULL);
 
-	fds = f->dents;
+	/* For symlink inodes we us f->dents to store the target path name */
+	if (S_ISLNK(OFNI_EDONI_2SFFJ(f)->i_mode)) {
+		if (f->dents) {
+			kfree(f->dents);
+			f->dents = NULL;
+		}
+	} else {
+		fds = f->dents;
 
-	while(fds) {
-		fd = fds;
-		fds = fd->next;
-		jffs2_free_full_dirent(fd);
+		while(fds) {
+			fd = fds;
+			fds = fd->next;
+			jffs2_free_full_dirent(fd);
+		}
 	}
 
-	if (f->inocache && f->inocache->state != INO_STATE_CHECKING)
+	if (f->inocache && f->inocache->state != INO_STATE_CHECKING) {
 		jffs2_set_inocache_state(c, f->inocache, INO_STATE_CHECKEDABSENT);
+		if (f->inocache->nodes == (void *)f->inocache)
+			jffs2_del_ino_cache(c, f->inocache);
+	}
 
 	up(&f->sem);
 }
diff --git a/fs/jffs2/scan.c b/fs/jffs2/scan.c
--- a/fs/jffs2/scan.c
+++ b/fs/jffs2/scan.c
@@ -7,7 +7,7 @@
  *
  * For licensing information, see the file 'LICENCE' in this directory.
  *
- * $Id: scan.c,v 1.115 2004/11/17 12:59:08 dedekind Exp $
+ * $Id: scan.c,v 1.119 2005/02/17 17:51:13 dedekind Exp $
  *
  */
 #include <linux/kernel.h>
@@ -19,7 +19,7 @@
 #include <linux/compiler.h>
 #include "nodelist.h"
 
-#define EMPTY_SCAN_SIZE 1024
+#define DEFAULT_EMPTY_SCAN_SIZE 1024
 
 #define DIRTY_SPACE(x) do { typeof(x) _x = (x); \
 		c->free_size -= _x; c->dirty_size += _x; \
@@ -68,13 +68,21 @@ static int jffs2_scan_dirent_node(struct
 static inline int min_free(struct jffs2_sb_info *c)
 {
 	uint32_t min = 2 * sizeof(struct jffs2_raw_inode);
-#if defined CONFIG_JFFS2_FS_NAND || defined CONFIG_JFFS2_FS_NOR_ECC
+#ifdef CONFIG_JFFS2_FS_WRITEBUFFER
 	if (!jffs2_can_mark_obsolete(c) && min < c->wbuf_pagesize)
 		return c->wbuf_pagesize;
 #endif
 	return min;
 
 }
+
+static inline uint32_t EMPTY_SCAN_SIZE(uint32_t sector_size) {
+	if (sector_size < DEFAULT_EMPTY_SCAN_SIZE)
+		return sector_size;
+	else
+		return DEFAULT_EMPTY_SCAN_SIZE;
+}
+
 int jffs2_scan_medium(struct jffs2_sb_info *c)
 {
 	int i, ret;
@@ -220,7 +228,7 @@ int jffs2_scan_medium(struct jffs2_sb_in
 		c->dirty_size -= c->nextblock->dirty_size;
 		c->nextblock->dirty_size = 0;
 	}
-#if defined CONFIG_JFFS2_FS_NAND || defined CONFIG_JFFS2_FS_NOR_ECC
+#ifdef CONFIG_JFFS2_FS_WRITEBUFFER
 	if (!jffs2_can_mark_obsolete(c) && c->nextblock && (c->nextblock->free_size & (c->wbuf_pagesize-1))) {
 		/* If we're going to start writing into a block which already 
 		   contains data, and the end of the data isn't page-aligned,
@@ -286,7 +294,7 @@ static int jffs2_scan_eraseblock (struct
 	uint32_t hdr_crc, buf_ofs, buf_len;
 	int err;
 	int noise = 0;
-#ifdef CONFIG_JFFS2_FS_NAND
+#ifdef CONFIG_JFFS2_FS_WRITEBUFFER
 	int cleanmarkerfound = 0;
 #endif
 
@@ -295,7 +303,7 @@ static int jffs2_scan_eraseblock (struct
 
 	D1(printk(KERN_DEBUG "jffs2_scan_eraseblock(): Scanning block at 0x%x\n", ofs));
 
-#ifdef CONFIG_JFFS2_FS_NAND
+#ifdef CONFIG_JFFS2_FS_WRITEBUFFER
 	if (jffs2_cleanmarker_oob(c)) {
 		int ret = jffs2_check_nand_cleanmarker(c, jeb);
 		D2(printk(KERN_NOTICE "jffs_check_nand_cleanmarker returned %d\n",ret));
@@ -316,7 +324,7 @@ static int jffs2_scan_eraseblock (struct
 	if (!buf_size) {
 		buf_len = c->sector_size;
 	} else {
-		buf_len = EMPTY_SCAN_SIZE;
+		buf_len = EMPTY_SCAN_SIZE(c->sector_size);
 		err = jffs2_fill_scan_buf(c, buf, buf_ofs, buf_len);
 		if (err)
 			return err;
@@ -326,11 +334,11 @@ static int jffs2_scan_eraseblock (struct
 	ofs = 0;
 
 	/* Scan only 4KiB of 0xFF before declaring it's empty */
-	while(ofs < EMPTY_SCAN_SIZE && *(uint32_t *)(&buf[ofs]) == 0xFFFFFFFF)
+	while(ofs < EMPTY_SCAN_SIZE(c->sector_size) && *(uint32_t *)(&buf[ofs]) == 0xFFFFFFFF)
 		ofs += 4;
 
-	if (ofs == EMPTY_SCAN_SIZE) {
-#ifdef CONFIG_JFFS2_FS_NAND
+	if (ofs == EMPTY_SCAN_SIZE(c->sector_size)) {
+#ifdef CONFIG_JFFS2_FS_WRITEBUFFER
 		if (jffs2_cleanmarker_oob(c)) {
 			/* scan oob, take care of cleanmarker */
 			int ret = jffs2_check_oob_empty(c, jeb, cleanmarkerfound);
@@ -343,7 +351,10 @@ static int jffs2_scan_eraseblock (struct
 		}
 #endif
 		D1(printk(KERN_DEBUG "Block at 0x%08x is empty (erased)\n", jeb->offset));
-		return BLK_STATE_ALLFF;	/* OK to erase if all blocks are like this */
+		if (c->cleanmarker_size == 0)
+			return BLK_STATE_CLEANMARKER;	/* don't bother with re-erase */
+		else
+			return BLK_STATE_ALLFF;	/* OK to erase if all blocks are like this */
 	}
 	if (ofs) {
 		D1(printk(KERN_DEBUG "Free space at %08x ends at %08x\n", jeb->offset,
@@ -422,8 +433,8 @@ scan_more:	
 			/* If we're only checking the beginning of a block with a cleanmarker,
 			   bail now */
 			if (buf_ofs == jeb->offset && jeb->used_size == PAD(c->cleanmarker_size) && 
-			    c->cleanmarker_size && !jeb->dirty_size && !jeb->first_node->next_in_ino) {
-				D1(printk(KERN_DEBUG "%d bytes at start of block seems clean... assuming all clean\n", EMPTY_SCAN_SIZE));
+			    c->cleanmarker_size && !jeb->dirty_size && !jeb->first_node->next_phys) {
+				D1(printk(KERN_DEBUG "%d bytes at start of block seems clean... assuming all clean\n", EMPTY_SCAN_SIZE(c->sector_size)));
 				return BLK_STATE_CLEANMARKER;
 			}
 
@@ -618,7 +629,7 @@ scan_more:	
 	}
 
 	if ((jeb->used_size + jeb->unchecked_size) == PAD(c->cleanmarker_size) && !jeb->dirty_size 
-		&& (!jeb->first_node || !jeb->first_node->next_in_ino) )
+		&& (!jeb->first_node || !jeb->first_node->next_phys) )
 		return BLK_STATE_CLEANMARKER;
 		
 	/* move blocks with max 4 byte dirty space to cleanlist */	
diff --git a/fs/jffs2/super.c b/fs/jffs2/super.c
--- a/fs/jffs2/super.c
+++ b/fs/jffs2/super.c
@@ -7,7 +7,7 @@
  *
  * For licensing information, see the file 'LICENCE' in this directory.
  *
- * $Id: super.c,v 1.104 2004/11/23 15:37:31 gleixner Exp $
+ * $Id: super.c,v 1.107 2005/07/12 16:37:08 dedekind Exp $
  *
  */
 
@@ -140,6 +140,15 @@ static struct super_block *jffs2_get_sb_
 	D1(printk(KERN_DEBUG "jffs2_get_sb_mtd(): New superblock for device %d (\"%s\")\n",
 		  mtd->index, mtd->name));
 
+	/* Initialize JFFS2 superblock locks, the further initialization will be
+	 * done later */
+	init_MUTEX(&c->alloc_sem);
+	init_MUTEX(&c->erase_free_sem);
+	init_waitqueue_head(&c->erase_wait);
+	init_waitqueue_head(&c->inocache_wq);
+	spin_lock_init(&c->erase_completion_lock);
+	spin_lock_init(&c->inocache_lock);
+
 	sb->s_op = &jffs2_super_operations;
 	sb->s_flags = flags | MS_NOATIME;
 
@@ -270,8 +279,6 @@ static void jffs2_put_super (struct supe
 
 	D2(printk(KERN_DEBUG "jffs2: jffs2_put_super()\n"));
 
-	if (!(sb->s_flags & MS_RDONLY))
-		jffs2_stop_garbage_collect_thread(c);
 	down(&c->alloc_sem);
 	jffs2_flush_wbuf_pad(c);
 	up(&c->alloc_sem);
@@ -292,6 +299,8 @@ static void jffs2_put_super (struct supe
 static void jffs2_kill_sb(struct super_block *sb)
 {
 	struct jffs2_sb_info *c = JFFS2_SB_INFO(sb);
+	if (!(sb->s_flags & MS_RDONLY))
+		jffs2_stop_garbage_collect_thread(c);
 	generic_shutdown_super(sb);
 	put_mtd_device(c->mtd);
 	kfree(c);
@@ -309,7 +318,7 @@ static int __init init_jffs2_fs(void)
 	int ret;
 
 	printk(KERN_INFO "JFFS2 version 2.2."
-#ifdef CONFIG_JFFS2_FS_NAND
+#ifdef CONFIG_JFFS2_FS_WRITEBUFFER
 	       " (NAND)"
 #endif
 	       " (C) 2001-2003 Red Hat, Inc.\n");
diff --git a/fs/jffs2/symlink.c b/fs/jffs2/symlink.c
--- a/fs/jffs2/symlink.c
+++ b/fs/jffs2/symlink.c
@@ -7,7 +7,7 @@
  *
  * For licensing information, see the file 'LICENCE' in this directory.
  *
- * $Id: symlink.c,v 1.14 2004/11/16 20:36:12 dwmw2 Exp $
+ * $Id: symlink.c,v 1.16 2005/03/01 10:50:48 dedekind Exp $
  *
  */
 
@@ -18,28 +18,48 @@
 #include <linux/namei.h>
 #include "nodelist.h"
 
-static int jffs2_follow_link(struct dentry *dentry, struct nameidata *nd);
-static void jffs2_put_link(struct dentry *dentry, struct nameidata *nd);
+static void *jffs2_follow_link(struct dentry *dentry, struct nameidata *nd);
 
 struct inode_operations jffs2_symlink_inode_operations =
 {	
 	.readlink =	generic_readlink,
 	.follow_link =	jffs2_follow_link,
-	.put_link =	jffs2_put_link,
 	.setattr =	jffs2_setattr
 };
 
-static int jffs2_follow_link(struct dentry *dentry, struct nameidata *nd)
+static void *jffs2_follow_link(struct dentry *dentry, struct nameidata *nd)
 {
-	unsigned char *buf;
-	buf = jffs2_getlink(JFFS2_SB_INFO(dentry->d_inode->i_sb), JFFS2_INODE_INFO(dentry->d_inode));
-	nd_set_link(nd, buf);
-	return 0;
+	struct jffs2_inode_info *f = JFFS2_INODE_INFO(dentry->d_inode);
+	char *p = (char *)f->dents;
+	
+	/*
+	 * We don't acquire the f->sem mutex here since the only data we
+	 * use is f->dents which in case of the symlink inode points to the
+	 * symlink's target path.
+	 *
+	 * 1. If we are here the inode has already built and f->dents has
+	 * to point to the target path.
+	 * 2. Nobody uses f->dents (if the inode is symlink's inode). The
+	 * exception is inode freeing function which frees f->dents. But
+	 * it can't be called while we are here and before VFS has
+	 * stopped using our f->dents string which we provide by means of
+	 * nd_set_link() call.
+	 */
+	
+	if (!p) {
+		printk(KERN_ERR "jffs2_follow_link(): can't find symlink taerget\n");
+		p = ERR_PTR(-EIO);
+	} else {
+		D1(printk(KERN_DEBUG "jffs2_follow_link(): target path is '%s'\n", (char *) f->dents));
+	}
+
+	nd_set_link(nd, p);
+	
+	/*
+	 * We unlock the f->sem mutex but VFS will use the f->dents string. This is safe
+	 * since the only way that may cause f->dents to be changed is iput() operation.
+	 * But VFS will not use f->dents after iput() has been called.
+	 */
+	return NULL;
 }
 
-static void jffs2_put_link(struct dentry *dentry, struct nameidata *nd)
-{
-	char *s = nd_get_link(nd);
-	if (!IS_ERR(s))
-		kfree(s);
-}
diff --git a/fs/jffs2/wbuf.c b/fs/jffs2/wbuf.c
--- a/fs/jffs2/wbuf.c
+++ b/fs/jffs2/wbuf.c
@@ -9,7 +9,7 @@
  *
  * For licensing information, see the file 'LICENCE' in this directory.
  *
- * $Id: wbuf.c,v 1.82 2004/11/20 22:08:31 dwmw2 Exp $
+ * $Id: wbuf.c,v 1.92 2005/04/05 12:51:54 dedekind Exp $
  *
  */
 
@@ -83,7 +83,7 @@ static void jffs2_wbuf_dirties_inode(str
 	struct jffs2_inodirty *new;
 
 	/* Mark the superblock dirty so that kupdated will flush... */
-	OFNI_BS_2SFFJ(c)->s_dirt = 1;
+	jffs2_erase_pending_trigger(c);
 
 	if (jffs2_wbuf_pending_for_ino(c, ino))
 		return;
@@ -130,7 +130,10 @@ static inline void jffs2_refile_wbuf_blo
 	}
 }
 
-static void jffs2_block_refile(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb)
+#define REFILE_NOTEMPTY 0
+#define REFILE_ANYWAY   1
+
+static void jffs2_block_refile(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, int allow_empty)
 {
 	D1(printk("About to refile bad block at %08x\n", jeb->offset));
 
@@ -144,7 +147,7 @@ static void jffs2_block_refile(struct jf
 		D1(printk("Refiling block at %08x to bad_used_list\n", jeb->offset));
 		list_add(&jeb->list, &c->bad_used_list);
 	} else {
-		BUG();
+		BUG_ON(allow_empty == REFILE_NOTEMPTY);
 		/* It has to have had some nodes or we couldn't be here */
 		D1(printk("Refiling block at %08x to erase_pending_list\n", jeb->offset));
 		list_add(&jeb->list, &c->erase_pending_list);
@@ -179,7 +182,7 @@ static void jffs2_wbuf_recover(struct jf
 
 	jeb = &c->blocks[c->wbuf_ofs / c->sector_size];
 
-	jffs2_block_refile(c, jeb);
+	jffs2_block_refile(c, jeb, REFILE_NOTEMPTY);
 
 	/* Find the first node to be recovered, by skipping over every
 	   node which ends before the wbuf starts, or which is obsolete. */
@@ -264,17 +267,16 @@ static void jffs2_wbuf_recover(struct jf
 	ret = jffs2_reserve_space_gc(c, end-start, &ofs, &len);
 	if (ret) {
 		printk(KERN_WARNING "Failed to allocate space for wbuf recovery. Data loss ensues.\n");
-		if (buf)
-			kfree(buf);
+		kfree(buf);
 		return;
 	}
 	if (end-start >= c->wbuf_pagesize) {
-		/* Need to do another write immediately. This, btw,
-		 means that we'll be writing from 'buf' and not from
-		 the wbuf. Since if we're writing from the wbuf there
-		 won't be more than a wbuf full of data, now will
-		 there? :) */
-
+		/* Need to do another write immediately, but it's possible
+		   that this is just because the wbuf itself is completely
+		   full, and there's nothing earlier read back from the 
+		   flash. Hence 'buf' isn't necessarily what we're writing 
+		   from. */
+		unsigned char *rewrite_buf = buf?:c->wbuf;
 		uint32_t towrite = (end-start) - ((end-start)%c->wbuf_pagesize);
 
 		D1(printk(KERN_DEBUG "Write 0x%x bytes at 0x%08x in wbuf recover\n",
@@ -292,9 +294,9 @@ static void jffs2_wbuf_recover(struct jf
 #endif
 		if (jffs2_cleanmarker_oob(c))
 			ret = c->mtd->write_ecc(c->mtd, ofs, towrite, &retlen,
-						buf, NULL, c->oobinfo);
+						rewrite_buf, NULL, c->oobinfo);
 		else
-			ret = c->mtd->write(c->mtd, ofs, towrite, &retlen, buf);
+			ret = c->mtd->write(c->mtd, ofs, towrite, &retlen, rewrite_buf);
 
 		if (ret || retlen != towrite) {
 			/* Argh. We tried. Really we did. */
@@ -321,10 +323,10 @@ static void jffs2_wbuf_recover(struct jf
 
 		c->wbuf_len = (end - start) - towrite;
 		c->wbuf_ofs = ofs + towrite;
-		memcpy(c->wbuf, buf + towrite, c->wbuf_len);
+		memmove(c->wbuf, rewrite_buf + towrite, c->wbuf_len);
 		/* Don't muck about with c->wbuf_inodes. False positives are harmless. */
-
-		kfree(buf);
+		if (buf)
+			kfree(buf);
 	} else {
 		/* OK, now we're left with the dregs in whichever buffer we're using */
 		if (buf) {
@@ -413,9 +415,9 @@ static int __jffs2_flush_wbuf(struct jff
 	int ret;
 	size_t retlen;
 
-	/* Nothing to do if not NAND flash. In particular, we shouldn't
+	/* Nothing to do if not write-buffering the flash. In particular, we shouldn't
 	   del_timer() the timer we never initialised. */
-	if (jffs2_can_mark_obsolete(c))
+	if (!jffs2_is_writebuffered(c))
 		return 0;
 
 	if (!down_trylock(&c->alloc_sem)) {
@@ -424,7 +426,7 @@ static int __jffs2_flush_wbuf(struct jff
 		BUG();
 	}
 
-	if(!c->wbuf || !c->wbuf_len)
+	if (!c->wbuf_len)	/* already checked c->wbuf above */
 		return 0;
 
 	/* claim remaining space on the page
@@ -433,7 +435,7 @@ static int __jffs2_flush_wbuf(struct jff
 	   if we have a switch to next page, we will not have
 	   enough remaining space for this. 
 	*/
-	if (pad) {
+	if (pad && !jffs2_dataflash(c)) {
 		c->wbuf_len = PAD(c->wbuf_len);
 
 		/* Pad with JFFS2_DIRTY_BITMASK initially.  this helps out ECC'd NOR
@@ -484,7 +486,7 @@ static int __jffs2_flush_wbuf(struct jff
 	spin_lock(&c->erase_completion_lock);
 
 	/* Adjust free size of the block if we padded. */
-	if (pad) {
+	if (pad && !jffs2_dataflash(c)) {
 		struct jffs2_eraseblock *jeb;
 
 		jeb = &c->blocks[c->wbuf_ofs / c->sector_size];
@@ -532,6 +534,9 @@ int jffs2_flush_wbuf_gc(struct jffs2_sb_
 
 	D1(printk(KERN_DEBUG "jffs2_flush_wbuf_gc() called for ino #%u...\n", ino));
 
+	if (!c->wbuf)
+		return 0;
+
 	down(&c->alloc_sem);
 	if (!jffs2_wbuf_pending_for_ino(c, ino)) {
 		D1(printk(KERN_DEBUG "Ino #%d not pending in wbuf. Returning\n", ino));
@@ -547,6 +552,10 @@ int jffs2_flush_wbuf_gc(struct jffs2_sb_
 		D1(printk(KERN_DEBUG "jffs2_flush_wbuf_gc() padding. Not finished checking\n"));
 		down_write(&c->wbuf_sem);
 		ret = __jffs2_flush_wbuf(c, PAD_ACCOUNTING);
+		/* retry flushing wbuf in case jffs2_wbuf_recover
+		   left some data in the wbuf */
+		if (ret)
+			ret = __jffs2_flush_wbuf(c, PAD_ACCOUNTING);
 		up_write(&c->wbuf_sem);
 	} else while (old_wbuf_len &&
 		      old_wbuf_ofs == c->wbuf_ofs) {
@@ -561,6 +570,10 @@ int jffs2_flush_wbuf_gc(struct jffs2_sb_
 			down(&c->alloc_sem);
 			down_write(&c->wbuf_sem);
 			ret = __jffs2_flush_wbuf(c, PAD_ACCOUNTING);
+			/* retry flushing wbuf in case jffs2_wbuf_recover
+			   left some data in the wbuf */
+			if (ret)
+				ret = __jffs2_flush_wbuf(c, PAD_ACCOUNTING);
 			up_write(&c->wbuf_sem);
 			break;
 		}
@@ -578,15 +591,27 @@ int jffs2_flush_wbuf_pad(struct jffs2_sb
 {
 	int ret;
 
+	if (!c->wbuf)
+		return 0;
+
 	down_write(&c->wbuf_sem);
 	ret = __jffs2_flush_wbuf(c, PAD_NOACCOUNT);
+	/* retry - maybe wbuf recover left some data in wbuf. */
+	if (ret)
+		ret = __jffs2_flush_wbuf(c, PAD_NOACCOUNT);
 	up_write(&c->wbuf_sem);
 
 	return ret;
 }
 
+#ifdef CONFIG_JFFS2_FS_WRITEBUFFER
+#define PAGE_DIV(x) ( ((unsigned long)(x) / (unsigned long)(c->wbuf_pagesize)) * (unsigned long)(c->wbuf_pagesize) )
+#define PAGE_MOD(x) ( (unsigned long)(x) % (unsigned long)(c->wbuf_pagesize) )
+#else
 #define PAGE_DIV(x) ( (x) & (~(c->wbuf_pagesize - 1)) )
 #define PAGE_MOD(x) ( (x) & (c->wbuf_pagesize - 1) )
+#endif
+
 int jffs2_flash_writev(struct jffs2_sb_info *c, const struct kvec *invecs, unsigned long count, loff_t to, size_t *retlen, uint32_t ino)
 {
 	struct kvec outvecs[3];
@@ -601,7 +626,7 @@ int jffs2_flash_writev(struct jffs2_sb_i
 	uint32_t outvec_to = to;
 
 	/* If not NAND flash, don't bother */
-	if (!c->wbuf)
+	if (!jffs2_is_writebuffered(c))
 		return jffs2_flash_direct_writev(c, invecs, count, to, retlen);
 	
 	down_write(&c->wbuf_sem);
@@ -630,7 +655,7 @@ int jffs2_flash_writev(struct jffs2_sb_i
 	   erase block. Anything else, and you die.
 	   New block starts at xxx000c (0-b = block header)
 	*/
-	if ( (to & ~(c->sector_size-1)) != (c->wbuf_ofs & ~(c->sector_size-1)) ) {
+	if (SECTOR_ADDR(to) != SECTOR_ADDR(c->wbuf_ofs)) {
 		/* It's a write to a new block */
 		if (c->wbuf_len) {
 			D1(printk(KERN_DEBUG "jffs2_flash_writev() to 0x%lx causes flush of wbuf at 0x%08x\n", (unsigned long)to, c->wbuf_ofs));
@@ -762,9 +787,18 @@ int jffs2_flash_writev(struct jffs2_sb_i
 		
 		if (ret < 0 || wbuf_retlen != PAGE_DIV(totlen)) {
 			/* At this point we have no problem,
-			   c->wbuf is empty. 
+			   c->wbuf is empty. However refile nextblock to avoid
+			   writing again to same address.
 			*/
-			*retlen = donelen;
+			struct jffs2_eraseblock *jeb;
+
+			spin_lock(&c->erase_completion_lock);
+
+			jeb = &c->blocks[outvec_to / c->sector_size];
+			jffs2_block_refile(c, jeb, REFILE_ANYWAY);
+
+			*retlen = 0;
+			spin_unlock(&c->erase_completion_lock);
 			goto exit;
 		}
 		
@@ -819,7 +853,7 @@ int jffs2_flash_write(struct jffs2_sb_in
 {
 	struct kvec vecs[1];
 
-	if (jffs2_can_mark_obsolete(c))
+	if (!jffs2_is_writebuffered(c))
 		return c->mtd->write(c->mtd, ofs, len, retlen, buf);
 
 	vecs[0].iov_base = (unsigned char *) buf;
@@ -835,39 +869,38 @@ int jffs2_flash_read(struct jffs2_sb_inf
 	loff_t	orbf = 0, owbf = 0, lwbf = 0;
 	int	ret;
 
-	/* Read flash */
-	if (!jffs2_can_mark_obsolete(c)) {
-		down_read(&c->wbuf_sem);
+	if (!jffs2_is_writebuffered(c))
+		return c->mtd->read(c->mtd, ofs, len, retlen, buf);
 
-		if (jffs2_cleanmarker_oob(c))
-			ret = c->mtd->read_ecc(c->mtd, ofs, len, retlen, buf, NULL, c->oobinfo);
-		else
-			ret = c->mtd->read(c->mtd, ofs, len, retlen, buf);
+	/* Read flash */
+	down_read(&c->wbuf_sem);
+	if (jffs2_cleanmarker_oob(c))
+		ret = c->mtd->read_ecc(c->mtd, ofs, len, retlen, buf, NULL, c->oobinfo);
+	else
+		ret = c->mtd->read(c->mtd, ofs, len, retlen, buf);
 
-		if ( (ret == -EBADMSG) && (*retlen == len) ) {
-			printk(KERN_WARNING "mtd->read(0x%zx bytes from 0x%llx) returned ECC error\n",
-			       len, ofs);
-			/* 
-			 * We have the raw data without ECC correction in the buffer, maybe 
-			 * we are lucky and all data or parts are correct. We check the node.
-			 * If data are corrupted node check will sort it out.
-			 * We keep this block, it will fail on write or erase and the we
-			 * mark it bad. Or should we do that now? But we should give him a chance.
-			 * Maybe we had a system crash or power loss before the ecc write or  
-			 * a erase was completed.
-			 * So we return success. :)
-			 */
-		 	ret = 0;
-		 }	
-	} else
-		return c->mtd->read(c->mtd, ofs, len, retlen, buf);
+	if ( (ret == -EBADMSG) && (*retlen == len) ) {
+		printk(KERN_WARNING "mtd->read(0x%zx bytes from 0x%llx) returned ECC error\n",
+		       len, ofs);
+		/* 
+		 * We have the raw data without ECC correction in the buffer, maybe 
+		 * we are lucky and all data or parts are correct. We check the node.
+		 * If data are corrupted node check will sort it out.
+		 * We keep this block, it will fail on write or erase and the we
+		 * mark it bad. Or should we do that now? But we should give him a chance.
+		 * Maybe we had a system crash or power loss before the ecc write or  
+		 * a erase was completed.
+		 * So we return success. :)
+		 */
+	 	ret = 0;
+	}	
 
 	/* if no writebuffer available or write buffer empty, return */
 	if (!c->wbuf_pagesize || !c->wbuf_len)
 		goto exit;
 
 	/* if we read in a different block, return */
-	if ( (ofs & ~(c->sector_size-1)) != (c->wbuf_ofs & ~(c->sector_size-1)) ) 
+	if (SECTOR_ADDR(ofs) != SECTOR_ADDR(c->wbuf_ofs))
 		goto exit;
 
 	if (ofs >= c->wbuf_ofs) {
@@ -1161,7 +1194,27 @@ void jffs2_nand_flash_cleanup(struct jff
 	kfree(c->wbuf);
 }
 
-#ifdef CONFIG_JFFS2_FS_NOR_ECC
+int jffs2_dataflash_setup(struct jffs2_sb_info *c) {
+	c->cleanmarker_size = 0;		/* No cleanmarkers needed */
+	
+	/* Initialize write buffer */
+	init_rwsem(&c->wbuf_sem);
+	c->wbuf_pagesize = c->sector_size;
+	c->wbuf_ofs = 0xFFFFFFFF;
+
+	c->wbuf = kmalloc(c->wbuf_pagesize, GFP_KERNEL);
+	if (!c->wbuf)
+		return -ENOMEM;
+
+	printk(KERN_INFO "JFFS2 write-buffering enabled (%i)\n", c->wbuf_pagesize);
+
+	return 0;
+}
+
+void jffs2_dataflash_cleanup(struct jffs2_sb_info *c) {
+	kfree(c->wbuf);
+}
+
 int jffs2_nor_ecc_flash_setup(struct jffs2_sb_info *c) {
 	/* Cleanmarker is actually larger on the flashes */
 	c->cleanmarker_size = 16;
@@ -1181,4 +1234,3 @@ int jffs2_nor_ecc_flash_setup(struct jff
 void jffs2_nor_ecc_flash_cleanup(struct jffs2_sb_info *c) {
 	kfree(c->wbuf);
 }
-#endif
diff --git a/fs/jffs2/write.c b/fs/jffs2/write.c
--- a/fs/jffs2/write.c
+++ b/fs/jffs2/write.c
@@ -7,7 +7,7 @@
  *
  * For licensing information, see the file 'LICENCE' in this directory.
  *
- * $Id: write.c,v 1.87 2004/11/16 20:36:12 dwmw2 Exp $
+ * $Id: write.c,v 1.92 2005/04/13 13:22:35 dwmw2 Exp $
  *
  */
 
@@ -35,13 +35,12 @@ int jffs2_do_new_inode(struct jffs2_sb_i
 	f->inocache = ic;
 	f->inocache->nlink = 1;
 	f->inocache->nodes = (struct jffs2_raw_node_ref *)f->inocache;
-	f->inocache->ino = ++c->highest_ino;
 	f->inocache->state = INO_STATE_PRESENT;
 
-	ri->ino = cpu_to_je32(f->inocache->ino);
 
-	D1(printk(KERN_DEBUG "jffs2_do_new_inode(): Assigned ino# %d\n", f->inocache->ino));
 	jffs2_add_ino_cache(c, f->inocache);
+	D1(printk(KERN_DEBUG "jffs2_do_new_inode(): Assigned ino# %d\n", f->inocache->ino));
+	ri->ino = cpu_to_je32(f->inocache->ino);
 
 	ri->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
 	ri->nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE);
@@ -136,6 +135,15 @@ struct jffs2_full_dnode *jffs2_write_dno
 	raw->__totlen = PAD(sizeof(*ri)+datalen);
 	raw->next_phys = NULL;
 
+	if ((alloc_mode!=ALLOC_GC) && (je32_to_cpu(ri->version) < f->highest_version)) {
+		BUG_ON(!retried);
+		D1(printk(KERN_DEBUG "jffs2_write_dnode : dnode_version %d, "
+				"highest version %d -> updating dnode\n", 
+				je32_to_cpu(ri->version), f->highest_version));
+		ri->version = cpu_to_je32(++f->highest_version);
+		ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));
+	}
+
 	ret = jffs2_flash_writev(c, vecs, cnt, flash_ofs, &retlen,
 				 (alloc_mode==ALLOC_GC)?0:f->inocache->ino);
 
@@ -280,6 +288,16 @@ struct jffs2_full_dirent *jffs2_write_di
 	raw->__totlen = PAD(sizeof(*rd)+namelen);
 	raw->next_phys = NULL;
 
+	if ((alloc_mode!=ALLOC_GC) && (je32_to_cpu(rd->version) < f->highest_version)) {
+		BUG_ON(!retried);
+		D1(printk(KERN_DEBUG "jffs2_write_dirent : dirent_version %d, "
+				     "highest version %d -> updating dirent\n",
+				     je32_to_cpu(rd->version), f->highest_version));
+		rd->version = cpu_to_je32(++f->highest_version);
+		fd->version = je32_to_cpu(rd->version);
+		rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8));
+	}
+
 	ret = jffs2_flash_writev(c, vecs, 2, flash_ofs, &retlen,
 				 (alloc_mode==ALLOC_GC)?0:je32_to_cpu(rd->pino));
 	if (ret || (retlen != sizeof(*rd) + namelen)) {
@@ -625,20 +643,23 @@ int jffs2_do_unlink(struct jffs2_sb_info
 
 		down(&dead_f->sem);
 
-		while (dead_f->dents) {
-			/* There can be only deleted ones */
-			fd = dead_f->dents;
-			
-			dead_f->dents = fd->next;
-			
-			if (fd->ino) {
-				printk(KERN_WARNING "Deleting inode #%u with active dentry \"%s\"->ino #%u\n",
-				       dead_f->inocache->ino, fd->name, fd->ino);
-			} else {
-				D1(printk(KERN_DEBUG "Removing deletion dirent for \"%s\" from dir ino #%u\n", fd->name, dead_f->inocache->ino));
+		if (S_ISDIR(OFNI_EDONI_2SFFJ(dead_f)->i_mode)) {
+			while (dead_f->dents) {
+				/* There can be only deleted ones */
+				fd = dead_f->dents;
+				
+				dead_f->dents = fd->next;
+				
+				if (fd->ino) {
+					printk(KERN_WARNING "Deleting inode #%u with active dentry \"%s\"->ino #%u\n",
+					       dead_f->inocache->ino, fd->name, fd->ino);
+				} else {
+					D1(printk(KERN_DEBUG "Removing deletion dirent for \"%s\" from dir ino #%u\n",
+						fd->name, dead_f->inocache->ino));
+				}
+				jffs2_mark_node_obsolete(c, fd->raw);
+				jffs2_free_full_dirent(fd);
 			}
-			jffs2_mark_node_obsolete(c, fd->raw);
-			jffs2_free_full_dirent(fd);
 		}
 
 		dead_f->inocache->nlink--;
diff --git a/fs/jfs/acl.c b/fs/jfs/acl.c
--- a/fs/jfs/acl.c
+++ b/fs/jfs/acl.c
@@ -21,6 +21,7 @@
 #include <linux/sched.h>
 #include <linux/fs.h>
 #include <linux/quotaops.h>
+#include <linux/posix_acl_xattr.h>
 #include "jfs_incore.h"
 #include "jfs_xattr.h"
 #include "jfs_acl.h"
@@ -36,11 +37,11 @@ static struct posix_acl *jfs_get_acl(str
 
 	switch(type) {
 		case ACL_TYPE_ACCESS:
-			ea_name = XATTR_NAME_ACL_ACCESS;
+			ea_name = POSIX_ACL_XATTR_ACCESS;
 			p_acl = &ji->i_acl;
 			break;
 		case ACL_TYPE_DEFAULT:
-			ea_name = XATTR_NAME_ACL_DEFAULT;
+			ea_name = POSIX_ACL_XATTR_DEFAULT;
 			p_acl = &ji->i_default_acl;
 			break;
 		default:
@@ -70,8 +71,7 @@ static struct posix_acl *jfs_get_acl(str
 		if (!IS_ERR(acl))
 			*p_acl = posix_acl_dup(acl);
 	}
-	if (value)
-		kfree(value);
+	kfree(value);
 	return acl;
 }
 
@@ -89,11 +89,11 @@ static int jfs_set_acl(struct inode *ino
 
 	switch(type) {
 		case ACL_TYPE_ACCESS:
-			ea_name = XATTR_NAME_ACL_ACCESS;
+			ea_name = POSIX_ACL_XATTR_ACCESS;
 			p_acl = &ji->i_acl;
 			break;
 		case ACL_TYPE_DEFAULT:
-			ea_name = XATTR_NAME_ACL_DEFAULT;
+			ea_name = POSIX_ACL_XATTR_DEFAULT;
 			p_acl = &ji->i_default_acl;
 			if (!S_ISDIR(inode->i_mode))
 				return acl ? -EACCES : 0;
@@ -102,7 +102,7 @@ static int jfs_set_acl(struct inode *ino
 			return -EINVAL;
 	}
 	if (acl) {
-		size = xattr_acl_size(acl->a_count);
+		size = posix_acl_xattr_size(acl->a_count);
 		value = kmalloc(size, GFP_KERNEL);
 		if (!value)
 			return -ENOMEM;
@@ -112,8 +112,7 @@ static int jfs_set_acl(struct inode *ino
 	}
 	rc = __jfs_setxattr(inode, ea_name, value, size, 0);
 out:
-	if (value)
-		kfree(value);
+	kfree(value);
 
 	if (!rc) {
 		if (*p_acl && (*p_acl != JFS_ACL_NOT_CACHED))
diff --git a/fs/jfs/file.c b/fs/jfs/file.c
--- a/fs/jfs/file.c
+++ b/fs/jfs/file.c
@@ -1,6 +1,6 @@
 /*
- *   Copyright (c) International Business Machines Corp., 2000-2002
- *   Portions Copyright (c) Christoph Hellwig, 2001-2002
+ *   Copyright (C) International Business Machines Corp., 2000-2002
+ *   Portions Copyright (C) Christoph Hellwig, 2001-2002
  *
  *   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
@@ -19,16 +19,13 @@
 
 #include <linux/fs.h>
 #include "jfs_incore.h"
+#include "jfs_inode.h"
 #include "jfs_dmap.h"
 #include "jfs_txnmgr.h"
 #include "jfs_xattr.h"
 #include "jfs_acl.h"
 #include "jfs_debug.h"
 
-
-extern int jfs_commit_inode(struct inode *, int);
-extern void jfs_truncate(struct inode *);
-
 int jfs_fsync(struct file *file, struct dentry *dentry, int datasync)
 {
 	struct inode *inode = dentry->d_inode;
diff --git a/fs/jfs/inode.c b/fs/jfs/inode.c
--- a/fs/jfs/inode.c
+++ b/fs/jfs/inode.c
@@ -23,6 +23,7 @@
 #include <linux/pagemap.h>
 #include <linux/quotaops.h>
 #include "jfs_incore.h"
+#include "jfs_inode.h"
 #include "jfs_filsys.h"
 #include "jfs_imap.h"
 #include "jfs_extent.h"
@@ -30,14 +31,6 @@
 #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_read_inode(struct inode *inode)
 {
 	if (diRead(inode)) { 
@@ -135,8 +128,12 @@ void jfs_delete_inode(struct inode *inod
 {
 	jfs_info("In jfs_delete_inode, inode = 0x%p", inode);
 
+	if (is_bad_inode(inode) ||
+	    (JFS_IP(inode)->fileset != cpu_to_le32(FILESYSTEM_I)))
+			return;
+
 	if (test_cflag(COMMIT_Freewmap, inode))
-		freeZeroLink(inode);
+		jfs_free_zero_link(inode);
 
 	diFree(inode);
 
diff --git a/fs/jfs/jfs_acl.h b/fs/jfs/jfs_acl.h
--- a/fs/jfs/jfs_acl.h
+++ b/fs/jfs/jfs_acl.h
@@ -20,8 +20,6 @@
 
 #ifdef CONFIG_JFS_POSIX_ACL
 
-#include <linux/xattr_acl.h>
-
 int jfs_permission(struct inode *, int, struct nameidata *);
 int jfs_init_acl(struct inode *, struct inode *);
 int jfs_setattr(struct dentry *, struct iattr *);
diff --git a/fs/jfs/jfs_debug.c b/fs/jfs/jfs_debug.c
--- a/fs/jfs/jfs_debug.c
+++ b/fs/jfs/jfs_debug.c
@@ -58,8 +58,6 @@ void dump_mem(char *label, void *data, i
 
 static struct proc_dir_entry *base;
 #ifdef CONFIG_JFS_DEBUG
-extern read_proc_t jfs_txanchor_read;
-
 static int loglevel_read(char *page, char **start, off_t off,
 			 int count, int *eof, void *data)
 {
@@ -97,14 +95,6 @@ static int loglevel_write(struct file *f
 }
 #endif
 
-
-#ifdef CONFIG_JFS_STATISTICS
-extern read_proc_t jfs_lmstats_read;
-extern read_proc_t jfs_txstats_read;
-extern read_proc_t jfs_xtstat_read;
-extern read_proc_t jfs_mpstat_read;
-#endif
-
 static struct {
 	const char	*name;
 	read_proc_t	*read_fn;
diff --git a/fs/jfs/jfs_debug.h b/fs/jfs/jfs_debug.h
--- a/fs/jfs/jfs_debug.h
+++ b/fs/jfs/jfs_debug.h
@@ -1,6 +1,6 @@
 /*
- *   Copyright (c) International Business Machines Corp., 2000-2002
- *   Portions Copyright (c) Christoph Hellwig, 2001-2002
+ *   Copyright (C) International Business Machines Corp., 2000-2002
+ *   Portions Copyright (C) Christoph Hellwig, 2001-2002
  *
  *   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
@@ -31,7 +31,9 @@
  * CONFIG_JFS_DEBUG or CONFIG_JFS_STATISTICS is defined
  */
 #if defined(CONFIG_PROC_FS) && (defined(CONFIG_JFS_DEBUG) || defined(CONFIG_JFS_STATISTICS))
-	#define PROC_FS_JFS
+#define PROC_FS_JFS
+extern void jfs_proc_init(void);
+extern void jfs_proc_clean(void);
 #endif
 
 /*
@@ -65,8 +67,8 @@
 
 extern int jfsloglevel;
 
-/* dump memory contents */
 extern void dump_mem(char *label, void *data, int length);
+extern int jfs_txanchor_read(char *, char **, off_t, int, int *, void *);
 
 /* information message: e.g., configuration, major event */
 #define jfs_info(fmt, arg...) do {			\
@@ -110,6 +112,11 @@ extern void dump_mem(char *label, void *
  *	----------
  */
 #ifdef	CONFIG_JFS_STATISTICS
+extern int jfs_lmstats_read(char *, char **, off_t, int, int *, void *);
+extern int jfs_txstats_read(char *, char **, off_t, int, int *, void *);
+extern int jfs_mpstat_read(char *, char **, off_t, int, int *, void *);
+extern int jfs_xtstat_read(char *, char **, off_t, int, int *, void *);
+
 #define	INCREMENT(x)		((x)++)
 #define	DECREMENT(x)		((x)--)
 #define	HIGHWATERMARK(x,y)	((x) = max((x), (y)))
diff --git a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c
--- a/fs/jfs/jfs_dmap.c
+++ b/fs/jfs/jfs_dmap.c
@@ -26,36 +26,6 @@
 #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
@@ -105,7 +75,7 @@ static void dbAllocBits(struct bmap * bm
 			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 int dbJoin(dmtree_t * tp, int leafno, int newval);
 static void dbAdjTree(dmtree_t * tp, int leafno, int newval);
 static int dbAdjCtl(struct bmap * bmp, s64 blkno, int newval, int alloc,
 		    int level);
@@ -128,8 +98,8 @@ static int dbExtend(struct inode *ip, s6
 static int dbFindBits(u32 word, int l2nb);
 static int dbFindCtl(struct bmap * bmp, int l2nb, int level, s64 * blkno);
 static int dbFindLeaf(dmtree_t * tp, int l2nb, int *leafidx);
-static void dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno,
-		       int nblocks);
+static int dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno,
+		      int nblocks);
 static int dbFreeDmap(struct bmap * bmp, struct dmap * dp, s64 blkno,
 		      int nblocks);
 static int dbMaxBud(u8 * cp);
@@ -242,7 +212,6 @@ int dbMount(struct inode *ipbmap)
 	JFS_SBI(ipbmap->i_sb)->bmap = bmp;
 
 	memset(bmp->db_active, 0, sizeof(bmp->db_active));
-	DBINITMAP(bmp->db_mapsize, ipbmap, &bmp->db_DBmap);
 
 	/*
 	 * allocate/initialize the bmap lock
@@ -272,7 +241,6 @@ int dbMount(struct inode *ipbmap)
 int dbUnmount(struct inode *ipbmap, int mounterror)
 {
 	struct bmap *bmp = JFS_SBI(ipbmap->i_sb)->bmap;
-	int i;
 
 	if (!(mounterror || isReadOnly(ipbmap)))
 		dbSync(ipbmap);
@@ -282,14 +250,6 @@ int dbUnmount(struct inode *ipbmap, int 
 	 */
 	truncate_inode_pages(ipbmap->i_mapping, 0);
 
-	/*
-	 * Sanity Check
-	 */
-	for (i = 0; i < bmp->db_numag; i++)
-		if (atomic_read(&bmp->db_active[i]))
-			printk(KERN_ERR "dbUnmount: db_active[%d] = %d\n",
-			       i, atomic_read(&bmp->db_active[i]));
-
 	/* free the memory for the in-memory bmap. */
 	kfree(bmp);
 
@@ -416,16 +376,13 @@ int dbFree(struct inode *ip, s64 blkno, 
 		 */
 		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))) {
+			jfs_error(ip->i_sb, "dbFree: error in block map\n");
 			release_metapage(mp);
 			IREAD_UNLOCK(ipbmap);
 			return (rc);
 		}
-
-		DBFREE(bmp->db_DBmap, bmp->db_mapsize, blkno, nb);
 	}
 
 	/* write the last buffer. */
@@ -784,10 +741,6 @@ int dbAlloc(struct inode *ip, s64 hint, 
 		IWRITE_LOCK(ipbmap);
 
 		rc = dbAllocAny(bmp, nblocks, l2nb, results);
-		if (rc == 0) {
-			DBALLOC(bmp->db_DBmap, bmp->db_mapsize, *results,
-				nblocks);
-		}
 
 		goto write_unlock;
 	}
@@ -845,8 +798,6 @@ int dbAlloc(struct inode *ip, s64 hint, 
 		    != -ENOSPC) {
 			if (rc == 0) {
 				*results = blkno;
-				DBALLOC(bmp->db_DBmap, bmp->db_mapsize,
-					*results, nblocks);
 				mark_metapage_dirty(mp);
 			}
 
@@ -872,11 +823,8 @@ int dbAlloc(struct inode *ip, s64 hint, 
 		if ((rc =
 		     dbAllocNear(bmp, dp, blkno, (int) nblocks, l2nb, results))
 		    != -ENOSPC) {
-			if (rc == 0) {
-				DBALLOC(bmp->db_DBmap, bmp->db_mapsize,
-					*results, nblocks);
+			if (rc == 0)
 				mark_metapage_dirty(mp);
-			}
 
 			release_metapage(mp);
 			goto read_unlock;
@@ -887,11 +835,8 @@ int dbAlloc(struct inode *ip, s64 hint, 
 		 */
 		if ((rc = dbAllocDmapLev(bmp, dp, (int) nblocks, l2nb, results))
 		    != -ENOSPC) {
-			if (rc == 0) {
-				DBALLOC(bmp->db_DBmap, bmp->db_mapsize,
-					*results, nblocks);
+			if (rc == 0)
 				mark_metapage_dirty(mp);
-			}
 
 			release_metapage(mp);
 			goto read_unlock;
@@ -905,13 +850,9 @@ int dbAlloc(struct inode *ip, s64 hint, 
 	 * the same allocation group as the hint.
 	 */
 	IWRITE_LOCK(ipbmap);
-	if ((rc = dbAllocAG(bmp, agno, nblocks, l2nb, results))
-	    != -ENOSPC) {
-		if (rc == 0)
-			DBALLOC(bmp->db_DBmap, bmp->db_mapsize,
-				*results, nblocks);
+	if ((rc = dbAllocAG(bmp, agno, nblocks, l2nb, results)) != -ENOSPC)
 		goto write_unlock;
-	}
+
 	IWRITE_UNLOCK(ipbmap);
 
 
@@ -927,9 +868,6 @@ int dbAlloc(struct inode *ip, s64 hint, 
 	 */
 	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);
-	}
 
       write_unlock:
 	IWRITE_UNLOCK(ipbmap);
@@ -1001,10 +939,9 @@ int dbAllocExact(struct inode *ip, s64 b
 
 	IREAD_UNLOCK(ipbmap);
 
-	if (rc == 0) {
-		DBALLOC(bmp->db_DBmap, bmp->db_mapsize, blkno, nblocks);
+	if (rc == 0)
 		mark_metapage_dirty(mp);
-	}
+
 	release_metapage(mp);
 
 	return (rc);
@@ -1153,7 +1090,6 @@ static int dbExtend(struct inode *ip, s6
 		return -EIO;
 	}
 
-	DBALLOCCK(bmp->db_DBmap, bmp->db_mapsize, blkno, nblocks);
 	dp = (struct dmap *) mp->data;
 
 	/* try to allocate the blocks immediately following the
@@ -1164,11 +1100,9 @@ static int dbExtend(struct inode *ip, s6
 	IREAD_UNLOCK(ipbmap);
 
 	/* were we successful ? */
-	if (rc == 0) {
-		DBALLOC(bmp->db_DBmap, bmp->db_mapsize, extblkno,
-			addnblocks);
+	if (rc == 0)
 		write_metapage(mp);
-	} else
+	else
 		/* we were not successful */
 		release_metapage(mp);
 
@@ -2087,7 +2021,7 @@ static int dbFreeDmap(struct bmap * bmp,
 		      int nblocks)
 {
 	s8 oldroot;
-	int rc, word;
+	int rc = 0, word;
 
 	/* save the current value of the root (i.e. maximum free string)
 	 * of the dmap tree.
@@ -2095,11 +2029,11 @@ static int dbFreeDmap(struct bmap * bmp,
 	oldroot = dp->tree.stree[ROOT];
 
 	/* free the specified (blocks) bits */
-	dbFreeBits(bmp, dp, blkno, nblocks);
+	rc = dbFreeBits(bmp, dp, blkno, nblocks);
 
-	/* if the root has not changed, done. */
-	if (dp->tree.stree[ROOT] == oldroot)
-		return (0);
+	/* if error or the root has not changed, done. */
+	if (rc || (dp->tree.stree[ROOT] == oldroot))
+		return (rc);
 
 	/* root changed. bubble the change up to the dmap control pages.
 	 * if the adjustment of the upper level control pages fails,
@@ -2288,15 +2222,16 @@ static void dbAllocBits(struct bmap * bm
  *      blkno	-  starting block number of the bits to be freed.
  *      nblocks	-  number of bits to be freed.
  *
- * RETURN VALUES: none
+ * RETURN VALUES: 0 for success
  *
  * serialization: IREAD_LOCK(ipbmap) or IWRITE_LOCK(ipbmap) held on entry/exit;
  */
-static void dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno,
+static int dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno,
 		       int nblocks)
 {
 	int dbitno, word, rembits, nb, nwords, wbitno, nw, agno;
 	dmtree_t *tp = (dmtree_t *) & dp->tree;
+	int rc = 0;
 	int size;
 
 	/* determine the bit number and word within the dmap of the
@@ -2345,8 +2280,10 @@ static void dbFreeBits(struct bmap * bmp
 
 			/* update the leaf for this dmap word.
 			 */
-			dbJoin(tp, word,
-			       dbMaxBud((u8 *) & dp->wmap[word]));
+			rc = dbJoin(tp, word,
+				    dbMaxBud((u8 *) & dp->wmap[word]));
+			if (rc)
+				return rc;
 
 			word += 1;
 		} else {
@@ -2377,7 +2314,9 @@ static void dbFreeBits(struct bmap * bmp
 
 				/* update the leaf.
 				 */
-				dbJoin(tp, word, size);
+				rc = dbJoin(tp, word, size);
+				if (rc)
+					return rc;
 
 				/* get the number of dmap words handled.
 				 */
@@ -2424,6 +2363,8 @@ static void dbFreeBits(struct bmap * bmp
 	}
 
 	BMAP_UNLOCK(bmp);
+
+	return 0;
 }
 
 
@@ -2531,7 +2472,9 @@ dbAdjCtl(struct bmap * bmp, s64 blkno, i
 		}
 		dbSplit((dmtree_t *) dcp, leafno, dcp->budmin, newval);
 	} else {
-		dbJoin((dmtree_t *) dcp, leafno, newval);
+		rc = dbJoin((dmtree_t *) dcp, leafno, newval);
+		if (rc)
+			return rc;
 	}
 
 	/* check if the root of the current dmap control page changed due
@@ -2756,7 +2699,7 @@ static void dbBackSplit(dmtree_t * tp, i
  *
  * RETURN VALUES: none
  */
-static void dbJoin(dmtree_t * tp, int leafno, int newval)
+static int dbJoin(dmtree_t * tp, int leafno, int newval)
 {
 	int budsz, buddy;
 	s8 *leaf;
@@ -2796,7 +2739,9 @@ static void dbJoin(dmtree_t * tp, int le
 			if (newval > leaf[buddy])
 				break;
 
-			assert(newval == leaf[buddy]);
+			/* It shouldn't be less */
+			if (newval < leaf[buddy])
+				return -EIO;
 
 			/* check which (leafno or buddy) is the left buddy.
 			 * the left buddy gets to claim the blocks resulting
@@ -2828,6 +2773,8 @@ static void dbJoin(dmtree_t * tp, int le
 	/* update the leaf value.
 	 */
 	dbAdjTree(tp, leafno, newval);
+
+	return 0;
 }
 
 
@@ -3194,16 +3141,12 @@ int dbAllocBottomUp(struct inode *ip, s6
 		 */
 		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. */
@@ -4050,223 +3993,3 @@ s64 dbMapFileSizeToMapSize(struct inode 
 
 	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;
-	struct dmap *dp;
-	struct metapage *mp;
-
-	npages = size / 32768;
-	npages += (size % 32768) ? 1 : 0;
-
-	dbmap = (u32 *) xmalloc(npages * 4096, L2PSIZE, kernel_heap);
-	if (dbmap == NULL)
-		BUG();	/* Not robust since this is only unused debug code */
-
-	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) {
-			jfs_error(ipbmap->i_sb,
-				  "DBinitmap: could not read disk map page");
-			continue;
-		}
-		dp = (struct dmap *) 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(struct bmap * 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(struct dmapctl * 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 --git a/fs/jfs/jfs_dtree.c b/fs/jfs/jfs_dtree.c
--- a/fs/jfs/jfs_dtree.c
+++ b/fs/jfs/jfs_dtree.c
@@ -381,9 +381,12 @@ static u32 add_index(tid_t tid, struct i
 		 * It's time to move the inline table to an external
 		 * page and begin to build the xtree
 		 */
-		if (DQUOT_ALLOC_BLOCK(ip, sbi->nbperpage) ||
-		    dbAlloc(ip, 0, sbi->nbperpage, &xaddr))
-			goto clean_up;	/* No space */
+		if (DQUOT_ALLOC_BLOCK(ip, sbi->nbperpage))
+			goto clean_up;
+		if (dbAlloc(ip, 0, sbi->nbperpage, &xaddr)) {
+			DQUOT_FREE_BLOCK(ip, sbi->nbperpage);
+			goto clean_up;
+		}
 
 		/*
 		 * Save the table, we're going to overwrite it with the
@@ -397,13 +400,15 @@ static u32 add_index(tid_t tid, struct i
 		xtInitRoot(tid, ip);
 
 		/*
-		 * Allocate the first block & add it to the xtree
+		 * Add the first block to the xtree
 		 */
 		if (xtInsert(tid, ip, 0, 0, sbi->nbperpage, &xaddr, 0)) {
 			/* This really shouldn't fail */
 			jfs_warn("add_index: xtInsert failed!");
 			memcpy(&jfs_ip->i_dirtable, temp_table,
 			       sizeof (temp_table));
+			dbFree(ip, xaddr, sbi->nbperpage);
+			DQUOT_FREE_BLOCK(ip, sbi->nbperpage);
 			goto clean_up;
 		}
 		ip->i_size = PSIZE;
@@ -2931,6 +2936,9 @@ static void add_missing_indices(struct i
 	ASSERT(p->header.flag & BT_LEAF);
 
 	tlck = txLock(tid, inode, mp, tlckDTREE | tlckENTRY);
+	if (BT_IS_ROOT(mp))
+		tlck->type |= tlckBTROOT;
+
 	dtlck = (struct dt_lock *) &tlck->lock;
 
 	stbl = DT_GETSTBL(p);
@@ -4551,202 +4559,3 @@ int dtModify(tid_t tid, struct inode *ip
 
 	return 0;
 }
-
-#ifdef _JFS_DEBUG_DTREE
-/*
- *	dtDisplayTree()
- *
- * function: traverse forward
- */
-int dtDisplayTree(struct inode *ip)
-{
-	int rc;
-	struct metapage *mp;
-	dtpage_t *p;
-	s64 bn, pbn;
-	int index, lastindex, v, h;
-	pxd_t *xd;
-	struct btstack btstack;
-	struct btframe *btsp;
-	struct btframe *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;
-	struct metapage *mp;
-	struct ldtentry *lh;
-	struct idtentry *ih;
-	pxd_t *xd;
-	int i, j;
-	u8 *stbl;
-	wchar_t name[JFS_NAME_MAX + 1];
-	struct component_name 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 = (struct ldtentry *) & p->slot[stbl[i]];
-			printf("\t[%d] %s:%d", i, key.name,
-			       le32_to_cpu(lh->inumber));
-		} else {
-			ih = (struct idtentry *) & 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 --git a/fs/jfs/jfs_dtree.h b/fs/jfs/jfs_dtree.h
--- a/fs/jfs/jfs_dtree.h
+++ b/fs/jfs/jfs_dtree.h
@@ -269,11 +269,4 @@ extern int dtModify(tid_t tid, struct in
 		    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 --git a/fs/jfs/jfs_extent.c b/fs/jfs/jfs_extent.c
--- a/fs/jfs/jfs_extent.c
+++ b/fs/jfs/jfs_extent.c
@@ -19,6 +19,7 @@
 #include <linux/fs.h>
 #include <linux/quotaops.h>
 #include "jfs_incore.h"
+#include "jfs_inode.h"
 #include "jfs_superblock.h"
 #include "jfs_dmap.h"
 #include "jfs_extent.h"
@@ -33,12 +34,6 @@ static int extBrealloc(struct inode *, s
 #endif
 static s64 extRoundDown(s64 nb);
 
-/*
- * external references
- */
-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)					\
diff --git a/fs/jfs/jfs_imap.c b/fs/jfs/jfs_imap.c
--- a/fs/jfs/jfs_imap.c
+++ b/fs/jfs/jfs_imap.c
@@ -47,6 +47,7 @@
 #include <linux/quotaops.h>
 
 #include "jfs_incore.h"
+#include "jfs_inode.h"
 #include "jfs_filsys.h"
 #include "jfs_dinode.h"
 #include "jfs_dmap.h"
@@ -69,11 +70,6 @@
 #define AG_UNLOCK(imap,agno)		up(&imap->im_aglock[agno])
 
 /*
- * external references
- */
-extern struct address_space_operations jfs_aops;
-
-/*
  * forward references
  */
 static int diAllocAG(struct inomap *, int, boolean_t, struct inode *);
@@ -91,25 +87,6 @@ static int copy_from_dinode(struct dinod
 static void copy_to_dinode(struct dinode *, 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(struct inomap * imap);
-static void DBGdiAlloc(struct inomap * imap, ino_t ino);
-static void DBGdiFree(struct inomap * 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
@@ -192,8 +169,6 @@ int diMount(struct inode *ipimap)
 	imap->im_ipimap = ipimap;
 	JFS_IP(ipimap)->i_imap = imap;
 
-//      DBG_DIINIT(imap);
-
 	return (0);
 }
 
@@ -1047,7 +1022,6 @@ int diFree(struct inode *ip)
 		/* 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.
@@ -1235,7 +1209,6 @@ int diFree(struct inode *ip)
 		jfs_error(ip->i_sb, "diFree: the pmap does not show inode free");
 	}
 	iagp->wmap[extno] = 0;
-	DBG_DIFREE(imap, inum);
 	PXDlength(&iagp->inoext[extno], 0);
 	PXDaddress(&iagp->inoext[extno], 0);
 
@@ -1354,7 +1327,6 @@ diInitInode(struct inode *ip, int iagno,
 	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);
 	jfs_ip->active_ag = -1;
@@ -3189,84 +3161,3 @@ static void copy_to_dinode(struct dinode
 	if (S_ISCHR(ip->i_mode) || S_ISBLK(ip->i_mode))
 		dip->di_rdev = cpu_to_le32(jfs_ip->dev);
 }
-
-#ifdef	_JFS_DEBUG_IMAP
-/*
- *	DBGdiInit()
- */
-static void *DBGdiInit(struct inomap * 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(struct inomap * 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(struct inomap * 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(struct inomap * 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(struct iag * 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 --git a/fs/jfs/jfs_inode.c b/fs/jfs/jfs_inode.c
--- a/fs/jfs/jfs_inode.c
+++ b/fs/jfs/jfs_inode.c
@@ -19,6 +19,7 @@
 #include <linux/fs.h>
 #include <linux/quotaops.h>
 #include "jfs_incore.h"
+#include "jfs_inode.h"
 #include "jfs_filsys.h"
 #include "jfs_imap.h"
 #include "jfs_dinode.h"
diff --git a/fs/jfs/jfs_inode.h b/fs/jfs/jfs_inode.h
--- a/fs/jfs/jfs_inode.h
+++ b/fs/jfs/jfs_inode.h
@@ -1,5 +1,5 @@
 /*
- *   Copyright (c) International Business Machines Corp., 2000-2001
+ *   Copyright (C) International Business Machines Corp., 2000-2001
  *
  *   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
@@ -19,5 +19,22 @@
 #define _H_JFS_INODE
 
 extern struct inode *ialloc(struct inode *, umode_t);
+extern int jfs_fsync(struct file *, struct dentry *, int);
+extern void jfs_read_inode(struct inode *);
+extern int jfs_commit_inode(struct inode *, int);
+extern int jfs_write_inode(struct inode*, int);
+extern void jfs_delete_inode(struct inode *);
+extern void jfs_dirty_inode(struct inode *);
+extern void jfs_truncate(struct inode *);
+extern void jfs_truncate_nolock(struct inode *, loff_t);
+extern void jfs_free_zero_link(struct inode *);
+extern struct dentry *jfs_get_parent(struct dentry *dentry);
 
+extern struct address_space_operations jfs_aops;
+extern struct inode_operations jfs_dir_inode_operations;
+extern struct file_operations jfs_dir_operations;
+extern struct inode_operations jfs_file_inode_operations;
+extern struct file_operations jfs_file_operations;
+extern struct inode_operations jfs_symlink_inode_operations;
+extern struct dentry_operations jfs_ci_dentry_operations;
 #endif				/* _H_JFS_INODE */
diff --git a/fs/jfs/jfs_logmgr.c b/fs/jfs/jfs_logmgr.c
--- a/fs/jfs/jfs_logmgr.c
+++ b/fs/jfs/jfs_logmgr.c
@@ -71,6 +71,7 @@
 #include "jfs_incore.h"
 #include "jfs_filsys.h"
 #include "jfs_metapage.h"
+#include "jfs_superblock.h"
 #include "jfs_txnmgr.h"
 #include "jfs_debug.h"
 
@@ -167,14 +168,6 @@ static struct jfs_log *dummy_log = NULL;
 static DECLARE_MUTEX(jfs_log_sem);
 
 /*
- * external references
- */
-extern void txLazyUnlock(struct tblock * tblk);
-extern int jfs_stop_threads;
-extern struct completion jfsIOwait;
-extern int jfs_tlocks_low;
-
-/*
  * forward references
  */
 static int lmWriteRecord(struct jfs_log * log, struct tblock * tblk,
@@ -198,7 +191,7 @@ static int lbmIOWait(struct lbuf * bp, i
 static bio_end_io_t lbmIODone;
 static void lbmStartIO(struct lbuf * bp);
 static void lmGCwrite(struct jfs_log * log, int cant_block);
-static int lmLogSync(struct jfs_log * log, int nosyncwait);
+static int lmLogSync(struct jfs_log * log, int hard_sync);
 
 
 
@@ -922,19 +915,17 @@ static void lmPostGC(struct lbuf * bp)
  *	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.
  *
  * PARAMETERS:	log	- log structure
- * 		nosyncwait - 1 if called asynchronously
+ * 		hard_sync - 1 to force all metadata to be written
  *
  * RETURN:	0
  *			
  * serialization: LOG_LOCK() held on entry/exit
  */
-static int lmLogSync(struct jfs_log * log, int nosyncwait)
+static int lmLogSync(struct jfs_log * log, int hard_sync)
 {
 	int logsize;
 	int written;		/* written since last syncpt */
@@ -948,11 +939,18 @@ static int lmLogSync(struct jfs_log * lo
 	unsigned long flags;
 
 	/* push dirty metapages out to disk */
-	list_for_each_entry(sbi, &log->sb_list, log_list) {
-		filemap_flush(sbi->ipbmap->i_mapping);
-		filemap_flush(sbi->ipimap->i_mapping);
-		filemap_flush(sbi->direct_inode->i_mapping);
-	}
+	if (hard_sync)
+		list_for_each_entry(sbi, &log->sb_list, log_list) {
+			filemap_fdatawrite(sbi->ipbmap->i_mapping);
+			filemap_fdatawrite(sbi->ipimap->i_mapping);
+			filemap_fdatawrite(sbi->direct_inode->i_mapping);
+		}
+	else
+		list_for_each_entry(sbi, &log->sb_list, log_list) {
+			filemap_flush(sbi->ipbmap->i_mapping);
+			filemap_flush(sbi->ipimap->i_mapping);
+			filemap_flush(sbi->direct_inode->i_mapping);
+		}
 
 	/*
 	 *      forward syncpt
@@ -1028,16 +1026,13 @@ static int lmLogSync(struct jfs_log * lo
 		/* 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) {
+	if (!test_bit(log_SYNCBARRIER, &log->flag) &&
+	    (written > LOGSYNC_BARRIER(logsize)) && log->active) {
 		set_bit(log_SYNCBARRIER, &log->flag);
 		jfs_info("log barrier on: lsn=0x%x syncpt=0x%x", lsn,
 			 log->syncpt);
@@ -1055,11 +1050,12 @@ static int lmLogSync(struct jfs_log * lo
  *
  * FUNCTION:	write log SYNCPT record for specified log
  *
- * PARAMETERS:	log	- log structure
+ * PARAMETERS:	log	  - log structure
+ * 		hard_sync - set to 1 to force metadata to be written
  */
-void jfs_syncpt(struct jfs_log *log)
+void jfs_syncpt(struct jfs_log *log, int hard_sync)
 {	LOG_LOCK(log);
-	lmLogSync(log, 1);
+	lmLogSync(log, hard_sync);
 	LOG_UNLOCK(log);
 }
 
@@ -1624,6 +1620,8 @@ void jfs_flush_journal(struct jfs_log *l
 		}
 	}
 	assert(list_empty(&log->cqueue));
+
+#ifdef CONFIG_JFS_DEBUG
 	if (!list_empty(&log->synclist)) {
 		struct logsyncblk *lp;
 
@@ -1638,9 +1636,8 @@ void jfs_flush_journal(struct jfs_log *l
 				dump_mem("orphan tblock", lp,
 					 sizeof(struct tblock));
 		}
-//		current->state = TASK_INTERRUPTIBLE;
-//		schedule();
 	}
+#endif
 	//assert(list_empty(&log->synclist));
 	clear_bit(log_FLUSH, &log->flag);
 }
@@ -2365,9 +2362,9 @@ int jfsIOWait(void *arg)
 			lbmStartIO(bp);
 			spin_lock_irq(&log_redrive_lock);
 		}
-		if (current->flags & PF_FREEZE) {
+		if (freezing(current)) {
 			spin_unlock_irq(&log_redrive_lock);
-			refrigerator(PF_FREEZE);
+			refrigerator();
 		} else {
 			add_wait_queue(&jfs_IO_thread_wait, &wq);
 			set_current_state(TASK_INTERRUPTIBLE);
diff --git a/fs/jfs/jfs_logmgr.h b/fs/jfs/jfs_logmgr.h
--- a/fs/jfs/jfs_logmgr.h
+++ b/fs/jfs/jfs_logmgr.h
@@ -507,7 +507,9 @@ extern int lmLogClose(struct super_block
 extern int lmLogShutdown(struct jfs_log * log);
 extern int lmLogInit(struct jfs_log * log);
 extern int lmLogFormat(struct jfs_log *log, s64 logAddress, int logSize);
+extern int lmGroupCommit(struct jfs_log *, struct tblock *);
+extern int jfsIOWait(void *);
 extern void jfs_flush_journal(struct jfs_log * log, int wait);
-extern void jfs_syncpt(struct jfs_log *log);
+extern void jfs_syncpt(struct jfs_log *log, int hard_sync);
 
 #endif				/* _H_JFS_LOGMGR */
diff --git a/fs/jfs/jfs_metapage.c b/fs/jfs/jfs_metapage.c
--- a/fs/jfs/jfs_metapage.c
+++ b/fs/jfs/jfs_metapage.c
@@ -198,7 +198,7 @@ static void init_once(void *foo, kmem_ca
 	}
 }
 
-static inline struct metapage *alloc_metapage(int gfp_mask)
+static inline struct metapage *alloc_metapage(unsigned int gfp_mask)
 {
 	return mempool_alloc(metapage_mempool, gfp_mask);
 }
@@ -561,7 +561,6 @@ static int metapage_releasepage(struct p
 			dump_mem("page", page, sizeof(struct page));
 			dump_stack();
 		}
-		WARN_ON(mp->lsn);
 		if (mp->lsn)
 			remove_from_logsync(mp);
 		remove_metapage(page, mp);
@@ -641,7 +640,7 @@ struct metapage *__get_metapage(struct i
 	} else {
 		page = read_cache_page(mapping, page_index,
 			    (filler_t *)mapping->a_ops->readpage, NULL);
-		if (IS_ERR(page)) {
+		if (IS_ERR(page) || !PageUptodate(page)) {
 			jfs_err("read_cache_page failed!");
 			return NULL;
 		}
@@ -726,12 +725,12 @@ void force_metapage(struct metapage *mp)
 	page_cache_release(page);
 }
 
-extern void hold_metapage(struct metapage *mp)
+void hold_metapage(struct metapage *mp)
 {
 	lock_page(mp->page);
 }
 
-extern void put_metapage(struct metapage *mp)
+void put_metapage(struct metapage *mp)
 {
 	if (mp->count || mp->nohomeok) {
 		/* Someone else will release this */
@@ -783,14 +782,6 @@ void release_metapage(struct metapage * 
 	if (test_bit(META_discard, &mp->flag) && !mp->count) {
 		clear_page_dirty(page);
 		ClearPageUptodate(page);
-#ifdef _NOT_YET
-		if (page->mapping) {
-		/* Remove from page cache and page cache reference */
-			remove_from_page_cache(page);
-			page_cache_release(page);
-			metapage_releasepage(page, 0);
-		}
-#endif
 	}
 #else
 	/* Try to keep metapages from using up too much memory */
diff --git a/fs/jfs/jfs_metapage.h b/fs/jfs/jfs_metapage.h
--- a/fs/jfs/jfs_metapage.h
+++ b/fs/jfs/jfs_metapage.h
@@ -1,6 +1,6 @@
 /*
- *   Copyright (c) International Business Machines Corp., 2000-2002
- *   Portions Copyright (c) Christoph Hellwig, 2001-2002
+ *   Copyright (C) International Business Machines Corp., 2000-2002
+ *   Portions Copyright (C) Christoph Hellwig, 2001-2002
  *
  *   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
@@ -58,6 +58,8 @@ struct metapage {
 #define mark_metapage_dirty(mp) set_bit(META_dirty, &(mp)->flag)
 
 /* function prototypes */
+extern int metapage_init(void);
+extern void metapage_exit(void);
 extern struct metapage *__get_metapage(struct inode *inode,
 				  unsigned long lblock, unsigned int size,
 				  int absolute, unsigned long new);
diff --git a/fs/jfs/jfs_superblock.h b/fs/jfs/jfs_superblock.h
--- a/fs/jfs/jfs_superblock.h
+++ b/fs/jfs/jfs_superblock.h
@@ -109,5 +109,16 @@ struct jfs_superblock {
 extern int readSuper(struct super_block *, struct buffer_head **);
 extern int updateSuper(struct super_block *, uint);
 extern void jfs_error(struct super_block *, const char *, ...);
+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 jfs_stop_threads;
+extern struct completion jfsIOwait;
+extern wait_queue_head_t jfs_IO_thread_wait;
+extern wait_queue_head_t jfs_commit_thread_wait;
+extern wait_queue_head_t jfs_sync_thread_wait;
+extern int jfs_extendfs(struct super_block *, s64, int);
 
 #endif /*_H_JFS_SUPERBLOCK */
diff --git a/fs/jfs/jfs_txnmgr.c b/fs/jfs/jfs_txnmgr.c
--- a/fs/jfs/jfs_txnmgr.c
+++ b/fs/jfs/jfs_txnmgr.c
@@ -42,7 +42,6 @@
  * hold on to mp+lock thru update of maps
  */
 
-
 #include <linux/fs.h>
 #include <linux/vmalloc.h>
 #include <linux/smp_lock.h>
@@ -51,6 +50,7 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include "jfs_incore.h"
+#include "jfs_inode.h"
 #include "jfs_filsys.h"
 #include "jfs_metapage.h"
 #include "jfs_dinode.h"
@@ -109,7 +109,6 @@ static int TxLockHWM;		/* High water mar
 static int TxLockVHWM;		/* Very High water mark */
 struct tlock *TxLock;           /* transaction lock table */
 
-
 /*
  *      transaction management lock
  */
@@ -149,7 +148,6 @@ static inline void TXN_SLEEP_DROP_LOCK(w
 
 #define TXN_WAKEUP(event) wake_up_all(event)
 
-
 /*
  *      statistics
  */
@@ -161,16 +159,6 @@ static struct {
 	int waitlock;		/* 4: # of tlock wait */
 } stattx;
 
-
-/*
- * external references
- */
-extern int lmGroupCommit(struct jfs_log *, struct tblock *);
-extern int jfs_commit_inode(struct inode *, int);
-extern int jfs_stop_threads;
-
-extern struct completion jfsIOwait;
-
 /*
  * forward references
  */
@@ -358,7 +346,6 @@ void txExit(void)
 	TxBlock = NULL;
 }
 
-
 /*
  * NAME:        txBegin()
  *
@@ -460,7 +447,6 @@ tid_t txBegin(struct super_block *sb, in
 	return t;
 }
 
-
 /*
  * NAME:        txBeginAnon()
  *
@@ -503,7 +489,6 @@ void txBeginAnon(struct super_block *sb)
 	TXN_UNLOCK();
 }
 
-
 /*
  *      txEnd()
  *
@@ -567,6 +552,11 @@ void txEnd(tid_t tid)
 		 * synchronize with logsync barrier
 		 */
 		if (test_bit(log_SYNCBARRIER, &log->flag)) {
+			TXN_UNLOCK();
+
+			/* write dirty metadata & forward log syncpt */
+			jfs_syncpt(log, 1);
+
 			jfs_info("log barrier off: 0x%x", log->lsn);
 
 			/* enable new transactions start */
@@ -575,11 +565,6 @@ void txEnd(tid_t tid)
 			/* wakeup all waitors for logsync barrier */
 			TXN_WAKEUP(&log->syncwait);
 
-			TXN_UNLOCK();
-
-			/* forward log syncpt */
-			jfs_syncpt(log);
-
 			goto wakeup;
 		}
 	}
@@ -592,7 +577,6 @@ wakeup:
 	TXN_WAKEUP(&TxAnchor.freewait);
 }
 
-
 /*
  *      txLock()
  *
@@ -673,7 +657,9 @@ struct tlock *txLock(tid_t tid, struct i
 				/* only anonymous txn.
 				 * Remove from anon_list
 				 */
+				TXN_LOCK();
 				list_del_init(&jfs_ip->anon_inode_list);
+				TXN_UNLOCK();
 			}
 			jfs_ip->atlhead = tlck->next;
 		} else {
@@ -868,7 +854,6 @@ struct tlock *txLock(tid_t tid, struct i
 	return NULL;
 }
 
-
 /*
  * NAME:        txRelease()
  *
@@ -908,7 +893,6 @@ static void txRelease(struct tblock * tb
 	TXN_UNLOCK();
 }
 
-
 /*
  * NAME:        txUnlock()
  *
@@ -996,7 +980,6 @@ static void txUnlock(struct tblock * tbl
 	}
 }
 
-
 /*
  *      txMaplock()
  *
@@ -1069,7 +1052,6 @@ struct tlock *txMaplock(tid_t tid, struc
 	return tlck;
 }
 
-
 /*
  *      txLinelock()
  *
@@ -1103,8 +1085,6 @@ struct linelock *txLinelock(struct linel
 	return linelock;
 }
 
-
-
 /*
  *              transaction commit management
  *              -----------------------------
@@ -1373,7 +1353,6 @@ int txCommit(tid_t tid,		/* transaction 
 	return rc;
 }
 
-
 /*
  * NAME:        txLog()
  *
@@ -1437,7 +1416,6 @@ static int txLog(struct jfs_log * log, s
 	return rc;
 }
 
-
 /*
  *      diLog()
  *
@@ -1465,7 +1443,6 @@ static int diLog(struct jfs_log * log, s
 	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);
@@ -1552,7 +1529,6 @@ static int diLog(struct jfs_log * log, s
 	return rc;
 }
 
-
 /*
  *      dataLog()
  *
@@ -1599,7 +1575,6 @@ static int dataLog(struct jfs_log * log,
 	return 0;
 }
 
-
 /*
  *      dtLog()
  *
@@ -1639,7 +1614,6 @@ static void dtLog(struct jfs_log * log, 
 			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);
@@ -1704,7 +1678,6 @@ static void dtLog(struct jfs_log * log, 
 	return;
 }
 
-
 /*
  *      xtLog()
  *
@@ -1760,7 +1733,6 @@ static void xtLog(struct jfs_log * log, 
 		 * applying the after-image to the meta-data page.
 		 */
 		lrd->type = cpu_to_le16(LOG_REDOPAGE);
-//              *page_pxd = mp->cm_pxd;
 		PXDaddress(page_pxd, mp->index);
 		PXDlength(page_pxd,
 			  mp->logical_size >> tblk->sb->s_blocksize_bits);
@@ -2093,7 +2065,6 @@ static void xtLog(struct jfs_log * log, 
 	return;
 }
 
-
 /*
  *      mapLog()
  *
@@ -2180,7 +2151,6 @@ void mapLog(struct jfs_log * log, struct
 	}
 }
 
-
 /*
  *      txEA()
  *
@@ -2233,7 +2203,6 @@ void txEA(tid_t tid, struct inode *ip, d
 	}
 }
 
-
 /*
  *      txForce()
  *
@@ -2300,7 +2269,6 @@ void txForce(struct tblock * tblk)
 	}
 }
 
-
 /*
  *      txUpdateMap()
  *
@@ -2437,7 +2405,6 @@ static void txUpdateMap(struct tblock * 
 	}
 }
 
-
 /*
  *      txAllocPMap()
  *
@@ -2509,7 +2476,6 @@ static void txAllocPMap(struct inode *ip
 	}
 }
 
-
 /*
  *      txFreeMap()
  *
@@ -2611,7 +2577,6 @@ void txFreeMap(struct inode *ip,
 	}
 }
 
-
 /*
  *      txFreelock()
  *
@@ -2652,7 +2617,6 @@ void txFreelock(struct inode *ip)
 	TXN_UNLOCK();
 }
 
-
 /*
  *      txAbort()
  *
@@ -2826,9 +2790,9 @@ int jfs_lazycommit(void *arg)
 		/* In case a wakeup came while all threads were active */
 		jfs_commit_thread_waking = 0;
 
-		if (current->flags & PF_FREEZE) {
+		if (freezing(current)) {
 			LAZY_UNLOCK(flags);
-			refrigerator(PF_FREEZE);
+			refrigerator();
 		} else {
 			DECLARE_WAITQUEUE(wq, current);
 
@@ -3025,9 +2989,9 @@ int jfs_sync(void *arg)
 		/* Add anon_list2 back to anon_list */
 		list_splice_init(&TxAnchor.anon_list2, &TxAnchor.anon_list);
 
-		if (current->flags & PF_FREEZE) {
+		if (freezing(current)) {
 			TXN_UNLOCK();
-			refrigerator(PF_FREEZE);
+			refrigerator();
 		} else {
 			DECLARE_WAITQUEUE(wq, current);
 
diff --git a/fs/jfs/jfs_txnmgr.h b/fs/jfs/jfs_txnmgr.h
--- a/fs/jfs/jfs_txnmgr.h
+++ b/fs/jfs/jfs_txnmgr.h
@@ -285,34 +285,26 @@ struct commit {
 /*
  * external declarations
  */
-extern struct tlock *txLock(tid_t tid, struct inode *ip, struct metapage *mp,
-			    int flag);
+extern int jfs_tlocks_low;
 
-extern struct tlock *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 struct linelock *txLinelock(struct linelock * tlock);
-
-extern void txFreeMap(struct inode *ip, struct maplock * maplock,
-		      struct tblock * 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(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
-		 struct tlock * tlck);
-
-extern void txQuiesce(struct super_block *sb);
-
-extern void txResume(struct super_block *sb);
+extern int txInit(void);
+extern void txExit(void);
+extern struct tlock *txLock(tid_t, struct inode *, struct metapage *, int);
+extern struct tlock *txMaplock(tid_t, struct inode *, int);
+extern int txCommit(tid_t, int, struct inode **, int);
+extern tid_t txBegin(struct super_block *, int);
+extern void txBeginAnon(struct super_block *);
+extern void txEnd(tid_t);
+extern void txAbort(tid_t, int);
+extern struct linelock *txLinelock(struct linelock *);
+extern void txFreeMap(struct inode *, struct maplock *, struct tblock *, int);
+extern void txEA(tid_t, struct inode *, dxd_t *, dxd_t *);
+extern void txFreelock(struct inode *);
+extern int lmLog(struct jfs_log *, struct tblock *, struct lrd *,
+		 struct tlock *);
+extern void txQuiesce(struct super_block *);
+extern void txResume(struct super_block *);
+extern void txLazyUnlock(struct tblock *);
+extern int jfs_lazycommit(void *);
+extern int jfs_sync(void *);
 #endif				/* _H_JFS_TXNMGR */
diff --git a/fs/jfs/jfs_unicode.c b/fs/jfs/jfs_unicode.c
--- a/fs/jfs/jfs_unicode.c
+++ b/fs/jfs/jfs_unicode.c
@@ -51,8 +51,9 @@ int jfs_strfromUCS_le(char *to, const __
 		}
 	} else {
 		for (i = 0; (i < len) && from[i]; i++) {
-			if (le16_to_cpu(from[i]) & 0xff00) {
-				if (warn) {
+			if (unlikely(le16_to_cpu(from[i]) & 0xff00)) {
+				to[i] = '?';
+				if (unlikely(warn)) {
 					warn--;
 					warn_again--;
 					printk(KERN_ERR
@@ -61,7 +62,7 @@ int jfs_strfromUCS_le(char *to, const __
 					printk(KERN_ERR
 				"mount with iocharset=utf8 to access\n");
 				}
-				to[i] = '?';
+
 			}
 			else
 				to[i] = (char) (le16_to_cpu(from[i]));
diff --git a/fs/jfs/jfs_xtree.c b/fs/jfs/jfs_xtree.c
--- a/fs/jfs/jfs_xtree.c
+++ b/fs/jfs/jfs_xtree.c
@@ -135,14 +135,6 @@ static int xtSearchNode(struct inode *ip
 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()
  *
@@ -4140,338 +4132,6 @@ s64 xtTruncate_pmap(tid_t tid, struct in
 	return 0;
 }
 
-
-#ifdef _JFS_DEBUG_XTREE
-/*
- *      xtDisplayTree()
- *
- * function: traverse forward
- */
-int xtDisplayTree(struct inode *ip)
-{
-	int rc = 0;
-	struct metapage *mp;
-	xtpage_t *p;
-	s64 bn, pbn;
-	int index, lastindex, v, h;
-	xad_t *xad;
-	struct btstack btstack;
-	struct btframe *btsp;
-	struct btframe *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;
-	xad_t *xad;
-	s64 xaddr, xoff;
-	int xlen, i, j;
-
-	/* 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(btree_t *t)
-{
-	int rc = 0;
-	xtpage_t *p;
-	u64 bn;
-	int index;
-	btentry_t *e;
-	struct btstack 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)
diff --git a/fs/jfs/jfs_xtree.h b/fs/jfs/jfs_xtree.h
--- a/fs/jfs/jfs_xtree.h
+++ b/fs/jfs/jfs_xtree.h
@@ -131,10 +131,4 @@ extern int xtRelocate(tid_t tid, struct 
 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 --git a/fs/jfs/namei.c b/fs/jfs/namei.c
--- a/fs/jfs/namei.c
+++ b/fs/jfs/namei.c
@@ -31,20 +31,9 @@
 #include "jfs_acl.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);
-extern int jfs_init_acl(struct inode *, struct inode *);
-
 /*
  * forward references
  */
-struct inode_operations jfs_dir_inode_operations;
-struct file_operations jfs_dir_operations;
 struct dentry_operations jfs_ci_dentry_operations;
 
 static s64 commitZeroLink(tid_t, struct inode *);
@@ -655,7 +644,7 @@ static s64 commitZeroLink(tid_t tid, str
 
 
 /*
- * NAME:	freeZeroLink()
+ * NAME:	jfs_free_zero_link()
  *
  * FUNCTION:    for non-directory, called by iClose(),
  *		free resources of a file from cache and WORKING map 
@@ -663,15 +652,12 @@ static s64 commitZeroLink(tid_t tid, str
  *		while associated with a pager object,
  *
  * PARAMETER:	ip	- pointer to inode of file.
- *
- * RETURN:	0 -ok
  */
-int freeZeroLink(struct inode *ip)
+void jfs_free_zero_link(struct inode *ip)
 {
-	int rc = 0;
 	int type;
 
-	jfs_info("freeZeroLink: ip = 0x%p", ip);
+	jfs_info("jfs_free_zero_link: ip = 0x%p", ip);
 
 	/* return if not reg or symbolic link or if size is
 	 * already ok.
@@ -684,10 +670,10 @@ int freeZeroLink(struct inode *ip)
 	case S_IFLNK:
 		/* if its contained in inode nothing to do */
 		if (ip->i_size < IDATASIZE)
-			return 0;
+			return;
 		break;
 	default:
-		return 0;
+		return;
 	}
 
 	/*
@@ -737,9 +723,7 @@ int freeZeroLink(struct inode *ip)
 	 * free xtree/data blocks from working block map;
 	 */
 	if (ip->i_size)
-		rc = xtTruncate(0, ip, 0, COMMIT_WMAP);
-
-	return rc;
+		xtTruncate(0, ip, 0, COMMIT_WMAP);
 }
 
 /*
diff --git a/fs/jfs/super.c b/fs/jfs/super.c
--- a/fs/jfs/super.c
+++ b/fs/jfs/super.c
@@ -24,10 +24,12 @@
 #include <linux/completion.h>
 #include <linux/vfs.h>
 #include <linux/moduleparam.h>
+#include <linux/posix_acl.h>
 #include <asm/uaccess.h>
 
 #include "jfs_incore.h"
 #include "jfs_filsys.h"
+#include "jfs_inode.h"
 #include "jfs_metapage.h"
 #include "jfs_superblock.h"
 #include "jfs_dmap.h"
@@ -62,37 +64,6 @@ module_param(jfsloglevel, int, 0644);
 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_read_inode(struct inode *inode);
-extern void jfs_dirty_inode(struct inode *inode);
-extern void jfs_delete_inode(struct inode *inode);
-extern int jfs_write_inode(struct inode *inode, int wait);
-
-extern struct dentry *jfs_get_parent(struct dentry *dentry);
-extern int jfs_extendfs(struct super_block *, s64, int);
-
-extern struct dentry_operations jfs_ci_dentry_operations;
-
-#ifdef PROC_FS_JFS		/* see jfs_debug.h */
-extern void jfs_proc_init(void);
-extern void jfs_proc_clean(void);
-#endif
-
-extern wait_queue_head_t jfs_IO_thread_wait;
-extern wait_queue_head_t jfs_commit_thread_wait;
-extern wait_queue_head_t jfs_sync_thread_wait;
-
 static void jfs_handle_error(struct super_block *sb)
 {
 	struct jfs_sb_info *sbi = JFS_SBI(sb);
@@ -143,6 +114,8 @@ static void jfs_destroy_inode(struct ino
 {
 	struct jfs_inode_info *ji = JFS_IP(inode);
 
+	BUG_ON(!list_empty(&ji->anon_inode_list));
+
 	spin_lock_irq(&ji->ag_lock);
 	if (ji->active_ag != -1) {
 		struct bmap *bmap = JFS_SBI(inode->i_sb)->bmap;
@@ -560,7 +533,7 @@ static int jfs_sync_fs(struct super_bloc
 	/* log == NULL indicates read-only mount */
 	if (log) {
 		jfs_flush_journal(log, wait);
-		jfs_syncpt(log);
+		jfs_syncpt(log, 0);
 	}
 
 	return 0;
@@ -593,11 +566,6 @@ static struct file_system_type jfs_fs_ty
 	.fs_flags	= FS_REQUIRES_DEV,
 };
 
-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;
diff --git a/fs/jfs/symlink.c b/fs/jfs/symlink.c
--- a/fs/jfs/symlink.c
+++ b/fs/jfs/symlink.c
@@ -1,5 +1,5 @@
 /*
- *   Copyright (c) Christoph Hellwig, 2001-2002
+ *   Copyright (C) Christoph Hellwig, 2001-2002
  *
  *   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
@@ -19,13 +19,14 @@
 #include <linux/fs.h>
 #include <linux/namei.h>
 #include "jfs_incore.h"
+#include "jfs_inode.h"
 #include "jfs_xattr.h"
 
-static int jfs_follow_link(struct dentry *dentry, struct nameidata *nd)
+static void *jfs_follow_link(struct dentry *dentry, struct nameidata *nd)
 {
 	char *s = JFS_IP(dentry->d_inode)->i_inline;
 	nd_set_link(nd, s);
-	return 0;
+	return NULL;
 }
 
 struct inode_operations jfs_symlink_inode_operations = {
diff --git a/fs/jfs/xattr.c b/fs/jfs/xattr.c
--- a/fs/jfs/xattr.c
+++ b/fs/jfs/xattr.c
@@ -19,6 +19,7 @@
 
 #include <linux/fs.h>
 #include <linux/xattr.h>
+#include <linux/posix_acl_xattr.h>
 #include <linux/quotaops.h>
 #include "jfs_incore.h"
 #include "jfs_superblock.h"
@@ -718,9 +719,9 @@ static int can_set_system_xattr(struct i
 		return -EPERM;
 
 	/*
-	 * XATTR_NAME_ACL_ACCESS is tied to i_mode
+	 * POSIX_ACL_XATTR_ACCESS is tied to i_mode
 	 */
-	if (strcmp(name, XATTR_NAME_ACL_ACCESS) == 0) {
+	if (strcmp(name, POSIX_ACL_XATTR_ACCESS) == 0) {
 		acl = posix_acl_from_xattr(value, value_len);
 		if (IS_ERR(acl)) {
 			rc = PTR_ERR(acl);
@@ -750,7 +751,7 @@ static int can_set_system_xattr(struct i
 		JFS_IP(inode)->i_acl = JFS_ACL_NOT_CACHED;
 
 		return 0;
-	} else if (strcmp(name, XATTR_NAME_ACL_DEFAULT) == 0) {
+	} else if (strcmp(name, POSIX_ACL_XATTR_DEFAULT) == 0) {
 		acl = posix_acl_from_xattr(value, value_len);
 		if (IS_ERR(acl)) {
 			rc = PTR_ERR(acl);
@@ -780,7 +781,7 @@ static int can_set_xattr(struct inode *i
 	if (IS_RDONLY(inode))
 		return -EROFS;
 
-	if (IS_IMMUTABLE(inode) || IS_APPEND(inode) || S_ISLNK(inode->i_mode))
+	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
 		return -EPERM;
 
 	if(strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN) == 0)
@@ -789,12 +790,12 @@ static int can_set_xattr(struct inode *i
 		 */
 		return can_set_system_xattr(inode, name, value, value_len);
 
-	if(strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN) != 0)
+	if(strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN) == 0)
 		return (capable(CAP_SYS_ADMIN) ? 0 : -EPERM);
 
 #ifdef CONFIG_JFS_SECURITY
 	if (strncmp(name, XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN)
-	    != 0)
+	    == 0)
 		return 0;	/* Leave it to the security module */
 #endif
 		
@@ -946,8 +947,7 @@ int __jfs_setxattr(struct inode *inode, 
       out:
 	up_write(&JFS_IP(inode)->xattr_sem);
 
-	if (os2name)
-		kfree(os2name);
+	kfree(os2name);
 
 	return rc;
 }
@@ -1042,8 +1042,7 @@ ssize_t __jfs_getxattr(struct inode *ino
       out:
 	up_read(&JFS_IP(inode)->xattr_sem);
 
-	if (os2name)
-		kfree(os2name);
+	kfree(os2name);
 
 	return size;
 }
diff --git a/fs/libfs.c b/fs/libfs.c
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -183,6 +183,7 @@ struct file_operations simple_dir_operat
 	.llseek		= dcache_dir_lseek,
 	.read		= generic_read_dir,
 	.readdir	= dcache_readdir,
+	.fsync		= simple_sync_file,
 };
 
 struct inode_operations simple_dir_inode_operations = {
@@ -519,6 +520,102 @@ int simple_transaction_release(struct in
 	return 0;
 }
 
+/* Simple attribute files */
+
+struct simple_attr {
+	u64 (*get)(void *);
+	void (*set)(void *, u64);
+	char get_buf[24];	/* enough to store a u64 and "\n\0" */
+	char set_buf[24];
+	void *data;
+	const char *fmt;	/* format for read operation */
+	struct semaphore sem;	/* protects access to these buffers */
+};
+
+/* simple_attr_open is called by an actual attribute open file operation
+ * to set the attribute specific access operations. */
+int simple_attr_open(struct inode *inode, struct file *file,
+		     u64 (*get)(void *), void (*set)(void *, u64),
+		     const char *fmt)
+{
+	struct simple_attr *attr;
+
+	attr = kmalloc(sizeof(*attr), GFP_KERNEL);
+	if (!attr)
+		return -ENOMEM;
+
+	attr->get = get;
+	attr->set = set;
+	attr->data = inode->u.generic_ip;
+	attr->fmt = fmt;
+	init_MUTEX(&attr->sem);
+
+	file->private_data = attr;
+
+	return nonseekable_open(inode, file);
+}
+
+int simple_attr_close(struct inode *inode, struct file *file)
+{
+	kfree(file->private_data);
+	return 0;
+}
+
+/* read from the buffer that is filled with the get function */
+ssize_t simple_attr_read(struct file *file, char __user *buf,
+			 size_t len, loff_t *ppos)
+{
+	struct simple_attr *attr;
+	size_t size;
+	ssize_t ret;
+
+	attr = file->private_data;
+
+	if (!attr->get)
+		return -EACCES;
+
+	down(&attr->sem);
+	if (*ppos) /* continued read */
+		size = strlen(attr->get_buf);
+	else	  /* first read */
+		size = scnprintf(attr->get_buf, sizeof(attr->get_buf),
+				 attr->fmt,
+				 (unsigned long long)attr->get(attr->data));
+
+	ret = simple_read_from_buffer(buf, len, ppos, attr->get_buf, size);
+	up(&attr->sem);
+	return ret;
+}
+
+/* interpret the buffer as a number to call the set function with */
+ssize_t simple_attr_write(struct file *file, const char __user *buf,
+			  size_t len, loff_t *ppos)
+{
+	struct simple_attr *attr;
+	u64 val;
+	size_t size;
+	ssize_t ret;
+
+	attr = file->private_data;
+
+	if (!attr->set)
+		return -EACCES;
+
+	down(&attr->sem);
+	ret = -EFAULT;
+	size = min(sizeof(attr->set_buf) - 1, len);
+	if (copy_from_user(attr->set_buf, buf, size))
+		goto out;
+
+	ret = len; /* claim we got the whole input */
+	attr->set_buf[size] = '\0';
+	val = simple_strtol(attr->set_buf, NULL, 0);
+	attr->set(attr->data, val);
+out:
+	up(&attr->sem);
+	return ret;
+}
+
 EXPORT_SYMBOL(dcache_dir_close);
 EXPORT_SYMBOL(dcache_dir_lseek);
 EXPORT_SYMBOL(dcache_dir_open);
@@ -547,3 +644,7 @@ EXPORT_SYMBOL(simple_read_from_buffer);
 EXPORT_SYMBOL(simple_transaction_get);
 EXPORT_SYMBOL(simple_transaction_read);
 EXPORT_SYMBOL(simple_transaction_release);
+EXPORT_SYMBOL_GPL(simple_attr_open);
+EXPORT_SYMBOL_GPL(simple_attr_close);
+EXPORT_SYMBOL_GPL(simple_attr_read);
+EXPORT_SYMBOL_GPL(simple_attr_write);
diff --git a/fs/lockd/clntlock.c b/fs/lockd/clntlock.c
--- a/fs/lockd/clntlock.c
+++ b/fs/lockd/clntlock.c
@@ -31,7 +31,7 @@ static int			reclaimer(void *ptr);
  * This is the representation of a blocked client lock.
  */
 struct nlm_wait {
-	struct nlm_wait *	b_next;		/* linked list */
+	struct list_head	b_list;		/* linked list */
 	wait_queue_head_t	b_wait;		/* where to wait on */
 	struct nlm_host *	b_host;
 	struct file_lock *	b_lock;		/* local file lock */
@@ -39,27 +39,54 @@ struct nlm_wait {
 	u32			b_status;	/* grant callback status */
 };
 
-static struct nlm_wait *	nlm_blocked;
+static LIST_HEAD(nlm_blocked);
+
+/*
+ * Queue up a lock for blocking so that the GRANTED request can see it
+ */
+int nlmclnt_prepare_block(struct nlm_rqst *req, struct nlm_host *host, struct file_lock *fl)
+{
+	struct nlm_wait *block;
+
+	BUG_ON(req->a_block != NULL);
+	block = kmalloc(sizeof(*block), GFP_KERNEL);
+	if (block == NULL)
+		return -ENOMEM;
+	block->b_host = host;
+	block->b_lock = fl;
+	init_waitqueue_head(&block->b_wait);
+	block->b_status = NLM_LCK_BLOCKED;
+
+	list_add(&block->b_list, &nlm_blocked);
+	req->a_block = block;
+
+	return 0;
+}
+
+void nlmclnt_finish_block(struct nlm_rqst *req)
+{
+	struct nlm_wait *block = req->a_block;
+
+	if (block == NULL)
+		return;
+	req->a_block = NULL;
+	list_del(&block->b_list);
+	kfree(block);
+}
 
 /*
  * Block on a lock
  */
-int
-nlmclnt_block(struct nlm_host *host, struct file_lock *fl, u32 *statp)
+long nlmclnt_block(struct nlm_rqst *req, long timeout)
 {
-	struct nlm_wait	block, **head;
-	int		err;
-	u32		pstate;
-
-	block.b_host   = host;
-	block.b_lock   = fl;
-	init_waitqueue_head(&block.b_wait);
-	block.b_status = NLM_LCK_BLOCKED;
-	block.b_next   = nlm_blocked;
-	nlm_blocked    = &block;
+	struct nlm_wait	*block = req->a_block;
+	long ret;
 
-	/* Remember pseudo nsm state */
-	pstate = host->h_state;
+	/* A borken server might ask us to block even if we didn't
+	 * request it. Just say no!
+	 */
+	if (!req->a_args.block)
+		return -EAGAIN;
 
 	/* Go to sleep waiting for GRANT callback. Some servers seem
 	 * to lose callbacks, however, so we're going to poll from
@@ -69,28 +96,16 @@ nlmclnt_block(struct nlm_host *host, str
 	 * a 1 minute timeout would do. See the comment before
 	 * nlmclnt_lock for an explanation.
 	 */
-	sleep_on_timeout(&block.b_wait, 30*HZ);
+	ret = wait_event_interruptible_timeout(block->b_wait,
+			block->b_status != NLM_LCK_BLOCKED,
+			timeout);
 
-	for (head = &nlm_blocked; *head; head = &(*head)->b_next) {
-		if (*head == &block) {
-			*head = block.b_next;
-			break;
-		}
-	}
-
-	if (!signalled()) {
-		*statp = block.b_status;
-		return 0;
+	if (block->b_status != NLM_LCK_BLOCKED) {
+		req->a_res.status = block->b_status;
+		block->b_status = NLM_LCK_BLOCKED;
 	}
 
-	/* Okay, we were interrupted. Cancel the pending request
-	 * unless the server has rebooted.
-	 */
-	if (pstate == host->h_state && (err = nlmclnt_cancel(host, fl)) < 0)
-		printk(KERN_NOTICE
-			"lockd: CANCEL call failed (errno %d)\n", -err);
-
-	return -ERESTARTSYS;
+	return ret;
 }
 
 /*
@@ -100,27 +115,23 @@ u32
 nlmclnt_grant(struct nlm_lock *lock)
 {
 	struct nlm_wait	*block;
+	u32 res = nlm_lck_denied;
 
 	/*
 	 * Look up blocked request based on arguments. 
 	 * Warning: must not use cookie to match it!
 	 */
-	for (block = nlm_blocked; block; block = block->b_next) {
-		if (nlm_compare_locks(block->b_lock, &lock->fl))
-			break;
+	list_for_each_entry(block, &nlm_blocked, b_list) {
+		if (nlm_compare_locks(block->b_lock, &lock->fl)) {
+			/* Alright, we found a lock. Set the return status
+			 * and wake up the caller
+			 */
+			block->b_status = NLM_LCK_GRANTED;
+			wake_up(&block->b_wait);
+			res = nlm_granted;
+		}
 	}
-
-	/* Ooops, no blocked request found. */
-	if (block == NULL)
-		return nlm_lck_denied;
-
-	/* Alright, we found the lock. Set the return status and
-	 * wake up the caller.
-	 */
-	block->b_status = NLM_LCK_GRANTED;
-	wake_up(&block->b_wait);
-
-	return nlm_granted;
+	return res;
 }
 
 /*
@@ -230,7 +241,7 @@ restart:
 	host->h_reclaiming = 0;
 
 	/* Now, wake up all processes that sleep on a blocked lock */
-	for (block = nlm_blocked; block; block = block->b_next) {
+	list_for_each_entry(block, &nlm_blocked, b_list) {
 		if (block->b_host == host) {
 			block->b_status = NLM_LCK_DENIED_GRACE_PERIOD;
 			wake_up(&block->b_wait);
diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c
--- a/fs/lockd/clntproc.c
+++ b/fs/lockd/clntproc.c
@@ -21,6 +21,7 @@
 
 #define NLMDBG_FACILITY		NLMDBG_CLIENT
 #define NLMCLNT_GRACE_WAIT	(5*HZ)
+#define NLMCLNT_POLL_TIMEOUT	(30*HZ)
 
 static int	nlmclnt_test(struct nlm_rqst *, struct file_lock *);
 static int	nlmclnt_lock(struct nlm_rqst *, struct file_lock *);
@@ -312,7 +313,7 @@ static int nlm_wait_on_grace(wait_queue_
 	prepare_to_wait(queue, &wait, TASK_INTERRUPTIBLE);
 	if (!signalled ()) {
 		schedule_timeout(NLMCLNT_GRACE_WAIT);
-		try_to_freeze(PF_FREEZE);
+		try_to_freeze();
 		if (!signalled ())
 			status = 0;
 	}
@@ -553,7 +554,8 @@ nlmclnt_lock(struct nlm_rqst *req, struc
 {
 	struct nlm_host	*host = req->a_host;
 	struct nlm_res	*resp = &req->a_res;
-	int		status;
+	long timeout;
+	int status;
 
 	if (!host->h_monitored && nsm_monitor(host) < 0) {
 		printk(KERN_NOTICE "lockd: failed to monitor %s\n",
@@ -562,15 +564,32 @@ nlmclnt_lock(struct nlm_rqst *req, struc
 		goto out;
 	}
 
-	do {
-		if ((status = nlmclnt_call(req, NLMPROC_LOCK)) >= 0) {
-			if (resp->status != NLM_LCK_BLOCKED)
-				break;
-			status = nlmclnt_block(host, fl, &resp->status);
-		}
+	if (req->a_args.block) {
+		status = nlmclnt_prepare_block(req, host, fl);
 		if (status < 0)
 			goto out;
-	} while (resp->status == NLM_LCK_BLOCKED && req->a_args.block);
+	}
+	for(;;) {
+		status = nlmclnt_call(req, NLMPROC_LOCK);
+		if (status < 0)
+			goto out_unblock;
+		if (resp->status != NLM_LCK_BLOCKED)
+			break;
+		/* Wait on an NLM blocking lock */
+		timeout = nlmclnt_block(req, NLMCLNT_POLL_TIMEOUT);
+		/* Did a reclaimer thread notify us of a server reboot? */
+		if (resp->status ==  NLM_LCK_DENIED_GRACE_PERIOD)
+			continue;
+		if (resp->status != NLM_LCK_BLOCKED)
+			break;
+		if (timeout >= 0)
+			continue;
+		/* We were interrupted. Send a CANCEL request to the server
+		 * and exit
+		 */
+		status = (int)timeout;
+		goto out_unblock;
+	}
 
 	if (resp->status == NLM_LCK_GRANTED) {
 		fl->fl_u.nfs_fl.state = host->h_state;
@@ -579,6 +598,11 @@ nlmclnt_lock(struct nlm_rqst *req, struc
 		do_vfs_lock(fl);
 	}
 	status = nlm_stat_to_errno(resp->status);
+out_unblock:
+	nlmclnt_finish_block(req);
+	/* Cancel the blocked request if it is still pending */
+	if (resp->status == NLM_LCK_BLOCKED)
+		nlmclnt_cancel(host, fl);
 out:
 	nlmclnt_release_lockargs(req);
 	return status;
diff --git a/fs/lockd/host.c b/fs/lockd/host.c
--- a/fs/lockd/host.c
+++ b/fs/lockd/host.c
@@ -189,17 +189,15 @@ nlm_bind_host(struct nlm_host *host)
 			goto forgetit;
 
 		xprt_set_timeout(&xprt->timeout, 5, nlmsvc_timeout);
+		xprt->nocong = 1;	/* No congestion control for NLM */
+		xprt->resvport = 1;	/* NLM requires a reserved port */
 
 		/* Existing NLM servers accept AUTH_UNIX only */
 		clnt = rpc_create_client(xprt, host->h_name, &nlm_program,
 					host->h_version, RPC_AUTH_UNIX);
-		if (IS_ERR(clnt)) {
-			xprt_destroy(xprt);
+		if (IS_ERR(clnt))
 			goto forgetit;
-		}
 		clnt->cl_autobind = 1;	/* turn on pmap queries */
-		xprt->nocong = 1;	/* No congestion control for NLM */
-		xprt->resvport = 1;	/* NLM requires a reserved port */
 
 		host->h_rpcclnt = clnt;
 	}
diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c
--- a/fs/lockd/mon.c
+++ b/fs/lockd/mon.c
@@ -115,20 +115,19 @@ nsm_create(void)
 	xprt = xprt_create_proto(IPPROTO_UDP, &sin, NULL);
 	if (IS_ERR(xprt))
 		return (struct rpc_clnt *)xprt;
+	xprt->resvport = 1;	/* NSM requires a reserved port */
 
 	clnt = rpc_create_client(xprt, "localhost",
 				&nsm_program, SM_VERSION,
 				RPC_AUTH_NULL);
 	if (IS_ERR(clnt))
-		goto out_destroy;
+		goto out_err;
 	clnt->cl_softrtry = 1;
 	clnt->cl_chatty   = 1;
 	clnt->cl_oneshot  = 1;
-	xprt->resvport = 1;	/* NSM requires a reserved port */
 	return clnt;
 
-out_destroy:
-	xprt_destroy(xprt);
+out_err:
 	return clnt;
 }
 
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c
--- a/fs/lockd/svc.c
+++ b/fs/lockd/svc.c
@@ -191,7 +191,9 @@ lockd(struct svc_rqst *rqstp)
 		printk(KERN_DEBUG
 			"lockd: new process, skipping host shutdown\n");
 	wake_up(&lockd_exit);
-		
+
+	flush_signals(current);
+
 	/* Exit the RPC thread */
 	svc_exit_thread(rqstp);
 
@@ -329,7 +331,7 @@ static ctl_table nlm_sysctls[] = {
 		.ctl_name	= CTL_UNNUMBERED,
 		.procname	= "nlm_grace_period",
 		.data		= &nlm_grace_period,
-		.maxlen		= sizeof(int),
+		.maxlen		= sizeof(unsigned long),
 		.mode		= 0644,
 		.proc_handler	= &proc_doulongvec_minmax,
 		.extra1		= (unsigned long *) &nlm_grace_period_min,
@@ -339,7 +341,7 @@ static ctl_table nlm_sysctls[] = {
 		.ctl_name	= CTL_UNNUMBERED,
 		.procname	= "nlm_timeout",
 		.data		= &nlm_timeout,
-		.maxlen		= sizeof(int),
+		.maxlen		= sizeof(unsigned long),
 		.mode		= 0644,
 		.proc_handler	= &proc_doulongvec_minmax,
 		.extra1		= (unsigned long *) &nlm_timeout_min,
diff --git a/fs/locks.c b/fs/locks.c
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -1276,7 +1276,7 @@ int fcntl_getlease(struct file *filp)
  */
 static int __setlease(struct file *filp, long arg, struct file_lock **flp)
 {
-	struct file_lock *fl, **before, **my_before = NULL, *lease = *flp;
+	struct file_lock *fl, **before, **my_before = NULL, *lease;
 	struct dentry *dentry = filp->f_dentry;
 	struct inode *inode = dentry->d_inode;
 	int error, rdlease_count = 0, wrlease_count = 0;
@@ -1287,6 +1287,8 @@ static int __setlease(struct file *filp,
 	if (!flp || !(*flp) || !(*flp)->fl_lmops || !(*flp)->fl_lmops->fl_break)
 		goto out;
 
+	lease = *flp;
+
 	error = -EAGAIN;
 	if ((arg == F_RDLCK) && (atomic_read(&inode->i_writecount) > 0))
 		goto out;
@@ -1548,6 +1550,8 @@ int fcntl_getlk(struct file *filp, struc
 
 	if (filp->f_op && filp->f_op->lock) {
 		error = filp->f_op->lock(filp, F_GETLK, &file_lock);
+		if (file_lock.fl_ops && file_lock.fl_ops->fl_release_private)
+			file_lock.fl_ops->fl_release_private(&file_lock);
 		if (error < 0)
 			goto out;
 		else
@@ -1587,7 +1591,8 @@ out:
 /* Apply the lock described by l to an open file descriptor.
  * This implements both the F_SETLK and F_SETLKW commands of fcntl().
  */
-int fcntl_setlk(struct file *filp, unsigned int cmd, struct flock __user *l)
+int fcntl_setlk(unsigned int fd, struct file *filp, unsigned int cmd,
+		struct flock __user *l)
 {
 	struct file_lock *file_lock = locks_alloc_lock();
 	struct flock flock;
@@ -1616,6 +1621,7 @@ int fcntl_setlk(struct file *filp, unsig
 		goto out;
 	}
 
+again:
 	error = flock_to_posix_lock(filp, file_lock, &flock);
 	if (error)
 		goto out;
@@ -1644,25 +1650,33 @@ int fcntl_setlk(struct file *filp, unsig
 	if (error)
 		goto out;
 
-	if (filp->f_op && filp->f_op->lock != NULL) {
+	if (filp->f_op && filp->f_op->lock != NULL)
 		error = filp->f_op->lock(filp, cmd, file_lock);
-		goto out;
-	}
+	else {
+		for (;;) {
+			error = __posix_lock_file(inode, file_lock);
+			if ((error != -EAGAIN) || (cmd == F_SETLK))
+				break;
+			error = wait_event_interruptible(file_lock->fl_wait,
+					!file_lock->fl_next);
+			if (!error)
+				continue;
 
-	for (;;) {
-		error = __posix_lock_file(inode, file_lock);
-		if ((error != -EAGAIN) || (cmd == F_SETLK))
+			locks_delete_block(file_lock);
 			break;
-		error = wait_event_interruptible(file_lock->fl_wait,
-				!file_lock->fl_next);
-		if (!error)
-			continue;
+		}
+	}
 
-		locks_delete_block(file_lock);
-		break;
+	/*
+	 * Attempt to detect a close/fcntl race and recover by
+	 * releasing the lock that was just acquired.
+	 */
+	if (!error && fcheck(fd) != filp && flock.l_type != F_UNLCK) {
+		flock.l_type = F_UNLCK;
+		goto again;
 	}
 
- out:
+out:
 	locks_free_lock(file_lock);
 	return error;
 }
@@ -1690,6 +1704,8 @@ int fcntl_getlk64(struct file *filp, str
 
 	if (filp->f_op && filp->f_op->lock) {
 		error = filp->f_op->lock(filp, F_GETLK, &file_lock);
+		if (file_lock.fl_ops && file_lock.fl_ops->fl_release_private)
+			file_lock.fl_ops->fl_release_private(&file_lock);
 		if (error < 0)
 			goto out;
 		else
@@ -1718,7 +1734,8 @@ out:
 /* Apply the lock described by l to an open file descriptor.
  * This implements both the F_SETLK and F_SETLKW commands of fcntl().
  */
-int fcntl_setlk64(struct file *filp, unsigned int cmd, struct flock64 __user *l)
+int fcntl_setlk64(unsigned int fd, struct file *filp, unsigned int cmd,
+		struct flock64 __user *l)
 {
 	struct file_lock *file_lock = locks_alloc_lock();
 	struct flock64 flock;
@@ -1747,6 +1764,7 @@ int fcntl_setlk64(struct file *filp, uns
 		goto out;
 	}
 
+again:
 	error = flock64_to_posix_lock(filp, file_lock, &flock);
 	if (error)
 		goto out;
@@ -1775,22 +1793,30 @@ int fcntl_setlk64(struct file *filp, uns
 	if (error)
 		goto out;
 
-	if (filp->f_op && filp->f_op->lock != NULL) {
+	if (filp->f_op && filp->f_op->lock != NULL)
 		error = filp->f_op->lock(filp, cmd, file_lock);
-		goto out;
-	}
+	else {
+		for (;;) {
+			error = __posix_lock_file(inode, file_lock);
+			if ((error != -EAGAIN) || (cmd == F_SETLK64))
+				break;
+			error = wait_event_interruptible(file_lock->fl_wait,
+					!file_lock->fl_next);
+			if (!error)
+				continue;
 
-	for (;;) {
-		error = __posix_lock_file(inode, file_lock);
-		if ((error != -EAGAIN) || (cmd == F_SETLK64))
+			locks_delete_block(file_lock);
 			break;
-		error = wait_event_interruptible(file_lock->fl_wait,
-				!file_lock->fl_next);
-		if (!error)
-			continue;
+		}
+	}
 
-		locks_delete_block(file_lock);
-		break;
+	/*
+	 * Attempt to detect a close/fcntl race and recover by
+	 * releasing the lock that was just acquired.
+	 */
+	if (!error && fcheck(fd) != filp && flock.l_type != F_UNLCK) {
+		flock.l_type = F_UNLCK;
+		goto again;
 	}
 
 out:
@@ -1873,6 +1899,8 @@ void locks_remove_flock(struct file *fil
 			.fl_end = OFFSET_MAX,
 		};
 		filp->f_op->flock(filp, F_SETLKW, &fl);
+		if (fl.fl_ops && fl.fl_ops->fl_release_private)
+			fl.fl_ops->fl_release_private(&fl);
 	}
 
 	lock_kernel();
@@ -1880,12 +1908,7 @@ void locks_remove_flock(struct file *fil
 
 	while ((fl = *before) != NULL) {
 		if (fl->fl_file == filp) {
-			/*
-			 * We might have a POSIX lock that was created at the same time
-			 * the filp was closed for the last time. Just remove that too,
-			 * regardless of ownership, since nobody can own it.
-			 */
-			if (IS_FLOCK(fl) || IS_POSIX(fl)) {
+			if (IS_FLOCK(fl)) {
 				locks_delete_lock(before);
 				continue;
 			}
diff --git a/fs/mbcache.c b/fs/mbcache.c
--- a/fs/mbcache.c
+++ b/fs/mbcache.c
@@ -316,11 +316,10 @@ fail:
  * currently in use cannot be freed, and thus remain in the cache. All others
  * are freed.
  *
- * @cache: which cache to shrink
  * @bdev: which device's cache entries to shrink
  */
 void
-mb_cache_shrink(struct mb_cache *cache, struct block_device *bdev)
+mb_cache_shrink(struct block_device *bdev)
 {
 	LIST_HEAD(free_list);
 	struct list_head *l, *ltmp;
diff --git a/fs/namei.c b/fs/namei.c
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -21,7 +21,7 @@
 #include <linux/namei.h>
 #include <linux/quotaops.h>
 #include <linux/pagemap.h>
-#include <linux/dnotify.h>
+#include <linux/fsnotify.h>
 #include <linux/smp_lock.h>
 #include <linux/personality.h>
 #include <linux/security.h>
@@ -314,7 +314,7 @@ void path_release(struct nameidata *nd)
 void path_release_on_umount(struct nameidata *nd)
 {
 	dput(nd->dentry);
-	_mntput(nd->mnt);
+	mntput_no_expire(nd->mnt);
 }
 
 /*
@@ -501,6 +501,7 @@ struct path {
 static inline int __do_follow_link(struct path *path, struct nameidata *nd)
 {
 	int error;
+	void *cookie;
 	struct dentry *dentry = path->dentry;
 
 	touch_atime(path->mnt, dentry);
@@ -508,13 +509,15 @@ static inline int __do_follow_link(struc
 
 	if (path->mnt == nd->mnt)
 		mntget(path->mnt);
-	error = dentry->d_inode->i_op->follow_link(dentry, nd);
-	if (!error) {
+	cookie = dentry->d_inode->i_op->follow_link(dentry, nd);
+	error = PTR_ERR(cookie);
+	if (!IS_ERR(cookie)) {
 		char *s = nd_get_link(nd);
+		error = 0;
 		if (s)
 			error = __vfs_follow_link(nd, s);
 		if (dentry->d_inode->i_op->put_link)
-			dentry->d_inode->i_op->put_link(dentry, nd);
+			dentry->d_inode->i_op->put_link(dentry, nd, cookie);
 	}
 	dput(dentry);
 	mntput(path->mnt);
@@ -1312,7 +1315,7 @@ int vfs_create(struct inode *dir, struct
 	DQUOT_INIT(dir);
 	error = dir->i_op->create(dir, dentry, mode, nd);
 	if (!error) {
-		inode_dir_notify(dir, DN_CREATE);
+		fsnotify_create(dir, dentry->d_name.name);
 		security_inode_post_create(dir, dentry, mode);
 	}
 	return error;
@@ -1577,19 +1580,35 @@ do_link:
  *
  * Simple function to lookup and return a dentry and create it
  * if it doesn't exist.  Is SMP-safe.
+ *
+ * Returns with nd->dentry->d_inode->i_sem locked.
  */
 struct dentry *lookup_create(struct nameidata *nd, int is_dir)
 {
-	struct dentry *dentry;
+	struct dentry *dentry = ERR_PTR(-EEXIST);
 
 	down(&nd->dentry->d_inode->i_sem);
-	dentry = ERR_PTR(-EEXIST);
+	/*
+	 * Yucky last component or no last component at all?
+	 * (foo/., foo/.., /////)
+	 */
 	if (nd->last_type != LAST_NORM)
 		goto fail;
 	nd->flags &= ~LOOKUP_PARENT;
+
+	/*
+	 * Do the final lookup.
+	 */
 	dentry = lookup_hash(&nd->last, nd->dentry);
 	if (IS_ERR(dentry))
 		goto fail;
+
+	/*
+	 * Special case - lookup gave negative, but... we had foo/bar/
+	 * From the vfs_mknod() POV we just have a negative dentry -
+	 * all is fine. Let's be bastards - you had / on the end, you've
+	 * been asking for (non-existent) directory. -ENOENT for you.
+	 */
 	if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode)
 		goto enoent;
 	return dentry;
@@ -1621,7 +1640,7 @@ int vfs_mknod(struct inode *dir, struct 
 	DQUOT_INIT(dir);
 	error = dir->i_op->mknod(dir, dentry, mode, dev);
 	if (!error) {
-		inode_dir_notify(dir, DN_CREATE);
+		fsnotify_create(dir, dentry->d_name.name);
 		security_inode_post_mknod(dir, dentry, mode, dev);
 	}
 	return error;
@@ -1694,7 +1713,7 @@ int vfs_mkdir(struct inode *dir, struct 
 	DQUOT_INIT(dir);
 	error = dir->i_op->mkdir(dir, dentry, mode);
 	if (!error) {
-		inode_dir_notify(dir, DN_CREATE);
+		fsnotify_mkdir(dir, dentry->d_name.name);
 		security_inode_post_mkdir(dir,dentry, mode);
 	}
 	return error;
@@ -1785,7 +1804,6 @@ int vfs_rmdir(struct inode *dir, struct 
 	}
 	up(&dentry->d_inode->i_sem);
 	if (!error) {
-		inode_dir_notify(dir, DN_DELETE);
 		d_delete(dentry);
 	}
 	dput(dentry);
@@ -1859,8 +1877,8 @@ int vfs_unlink(struct inode *dir, struct
 	/* We don't d_delete() NFS sillyrenamed files--they still exist. */
 	if (!error && !(dentry->d_flags & DCACHE_NFSFS_RENAMED)) {
 		d_delete(dentry);
-		inode_dir_notify(dir, DN_DELETE);
 	}
+
 	return error;
 }
 
@@ -1934,7 +1952,7 @@ int vfs_symlink(struct inode *dir, struc
 	DQUOT_INIT(dir);
 	error = dir->i_op->symlink(dir, dentry, oldname);
 	if (!error) {
-		inode_dir_notify(dir, DN_CREATE);
+		fsnotify_create(dir, dentry->d_name.name);
 		security_inode_post_symlink(dir, dentry, oldname);
 	}
 	return error;
@@ -2007,7 +2025,7 @@ int vfs_link(struct dentry *old_dentry, 
 	error = dir->i_op->link(old_dentry, dir, new_dentry);
 	up(&old_dentry->d_inode->i_sem);
 	if (!error) {
-		inode_dir_notify(dir, DN_CREATE);
+		fsnotify_create(dir, new_dentry->d_name.name);
 		security_inode_post_link(old_dentry, dir, new_dentry);
 	}
 	return error;
@@ -2171,6 +2189,7 @@ int vfs_rename(struct inode *old_dir, st
 {
 	int error;
 	int is_dir = S_ISDIR(old_dentry->d_inode->i_mode);
+	const char *old_name;
 
 	if (old_dentry->d_inode == new_dentry->d_inode)
  		return 0;
@@ -2192,18 +2211,19 @@ int vfs_rename(struct inode *old_dir, st
 	DQUOT_INIT(old_dir);
 	DQUOT_INIT(new_dir);
 
+	old_name = fsnotify_oldname_init(old_dentry->d_name.name);
+
 	if (is_dir)
 		error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry);
 	else
 		error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry);
 	if (!error) {
-		if (old_dir == new_dir)
-			inode_dir_notify(old_dir, DN_RENAME);
-		else {
-			inode_dir_notify(old_dir, DN_DELETE);
-			inode_dir_notify(new_dir, DN_CREATE);
-		}
+		const char *new_name = old_dentry->d_name.name;
+		fsnotify_move(old_dir, new_dir, old_name, new_name, is_dir,
+			      new_dentry->d_inode, old_dentry->d_inode);
 	}
+	fsnotify_oldname_free(old_name);
+
 	return error;
 }
 
@@ -2327,15 +2347,17 @@ out:
 int generic_readlink(struct dentry *dentry, char __user *buffer, int buflen)
 {
 	struct nameidata nd;
-	int res;
+	void *cookie;
+
 	nd.depth = 0;
-	res = dentry->d_inode->i_op->follow_link(dentry, &nd);
-	if (!res) {
-		res = vfs_readlink(dentry, buffer, buflen, nd_get_link(&nd));
+	cookie = dentry->d_inode->i_op->follow_link(dentry, &nd);
+	if (!IS_ERR(cookie)) {
+		int res = vfs_readlink(dentry, buffer, buflen, nd_get_link(&nd));
 		if (dentry->d_inode->i_op->put_link)
-			dentry->d_inode->i_op->put_link(dentry, &nd);
+			dentry->d_inode->i_op->put_link(dentry, &nd, cookie);
+		cookie = ERR_PTR(res);
 	}
-	return res;
+	return PTR_ERR(cookie);
 }
 
 int vfs_follow_link(struct nameidata *nd, const char *link)
@@ -2378,23 +2400,20 @@ int page_readlink(struct dentry *dentry,
 	return res;
 }
 
-int page_follow_link_light(struct dentry *dentry, struct nameidata *nd)
+void *page_follow_link_light(struct dentry *dentry, struct nameidata *nd)
 {
-	struct page *page;
+	struct page *page = NULL;
 	nd_set_link(nd, page_getlink(dentry, &page));
-	return 0;
+	return page;
 }
 
-void page_put_link(struct dentry *dentry, struct nameidata *nd)
+void page_put_link(struct dentry *dentry, struct nameidata *nd, void *cookie)
 {
-	if (!IS_ERR(nd_get_link(nd))) {
-		struct page *page;
-		page = find_get_page(dentry->d_inode->i_mapping, 0);
-		if (!page)
-			BUG();
+	struct page *page = cookie;
+
+	if (page) {
 		kunmap(page);
 		page_cache_release(page);
-		page_cache_release(page);
 	}
 }
 
diff --git a/fs/namespace.c b/fs/namespace.c
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -61,7 +61,7 @@ struct vfsmount *alloc_vfsmnt(const char
 		INIT_LIST_HEAD(&mnt->mnt_child);
 		INIT_LIST_HEAD(&mnt->mnt_mounts);
 		INIT_LIST_HEAD(&mnt->mnt_list);
-		INIT_LIST_HEAD(&mnt->mnt_fslink);
+		INIT_LIST_HEAD(&mnt->mnt_expire);
 		if (name) {
 			int size = strlen(name)+1;
 			char *newname = kmalloc(size, GFP_KERNEL);
@@ -160,13 +160,13 @@ clone_mnt(struct vfsmount *old, struct d
 		mnt->mnt_root = dget(root);
 		mnt->mnt_mountpoint = mnt->mnt_root;
 		mnt->mnt_parent = mnt;
-		mnt->mnt_namespace = old->mnt_namespace;
+		mnt->mnt_namespace = current->namespace;
 
 		/* stick the duplicate mount on the same expiry list
 		 * as the original if that was on one */
 		spin_lock(&vfsmount_lock);
-		if (!list_empty(&old->mnt_fslink))
-			list_add(&mnt->mnt_fslink, &old->mnt_fslink);
+		if (!list_empty(&old->mnt_expire))
+			list_add(&mnt->mnt_expire, &old->mnt_expire);
 		spin_unlock(&vfsmount_lock);
 	}
 	return mnt;
@@ -337,7 +337,7 @@ int may_umount(struct vfsmount *mnt)
 
 EXPORT_SYMBOL(may_umount);
 
-void umount_tree(struct vfsmount *mnt)
+static void umount_tree(struct vfsmount *mnt)
 {
 	struct vfsmount *p;
 	LIST_HEAD(kill);
@@ -345,12 +345,13 @@ void umount_tree(struct vfsmount *mnt)
 	for (p = mnt; p; p = next_mnt(p, mnt)) {
 		list_del(&p->mnt_list);
 		list_add(&p->mnt_list, &kill);
+		p->mnt_namespace = NULL;
 	}
 
 	while (!list_empty(&kill)) {
 		mnt = list_entry(kill.next, struct vfsmount, mnt_list);
 		list_del_init(&mnt->mnt_list);
-		list_del_init(&mnt->mnt_fslink);
+		list_del_init(&mnt->mnt_expire);
 		if (mnt->mnt_parent == mnt) {
 			spin_unlock(&vfsmount_lock);
 		} else {
@@ -644,7 +645,7 @@ static int do_loopback(struct nameidata 
 	if (mnt) {
 		/* stop bind mounts from expiring */
 		spin_lock(&vfsmount_lock);
-		list_del_init(&mnt->mnt_fslink);
+		list_del_init(&mnt->mnt_expire);
 		spin_unlock(&vfsmount_lock);
 
 		err = graft_tree(mnt, nd);
@@ -743,7 +744,7 @@ static int do_move_mount(struct nameidat
 
 	/* if the mount is moved, it should no longer be expire
 	 * automatically */
-	list_del_init(&old_nd.mnt->mnt_fslink);
+	list_del_init(&old_nd.mnt->mnt_expire);
 out2:
 	spin_unlock(&vfsmount_lock);
 out1:
@@ -807,12 +808,13 @@ int do_add_mount(struct vfsmount *newmnt
 		goto unlock;
 
 	newmnt->mnt_flags = mnt_flags;
+	newmnt->mnt_namespace = current->namespace;
 	err = graft_tree(newmnt, nd);
 
 	if (err == 0 && fslist) {
 		/* add to the specified expiration list */
 		spin_lock(&vfsmount_lock);
-		list_add_tail(&newmnt->mnt_fslink, fslist);
+		list_add_tail(&newmnt->mnt_expire, fslist);
 		spin_unlock(&vfsmount_lock);
 	}
 
@@ -824,6 +826,54 @@ unlock:
 
 EXPORT_SYMBOL_GPL(do_add_mount);
 
+static void expire_mount(struct vfsmount *mnt, struct list_head *mounts)
+{
+	spin_lock(&vfsmount_lock);
+
+	/*
+	 * Check if mount is still attached, if not, let whoever holds it deal
+	 * with the sucker
+	 */
+	if (mnt->mnt_parent == mnt) {
+		spin_unlock(&vfsmount_lock);
+		return;
+	}
+
+	/*
+	 * Check that it is still dead: the count should now be 2 - as
+	 * contributed by the vfsmount parent and the mntget above
+	 */
+	if (atomic_read(&mnt->mnt_count) == 2) {
+		struct nameidata old_nd;
+
+		/* delete from the namespace */
+		list_del_init(&mnt->mnt_list);
+		mnt->mnt_namespace = NULL;
+		detach_mnt(mnt, &old_nd);
+		spin_unlock(&vfsmount_lock);
+		path_release(&old_nd);
+
+		/*
+		 * Now lay it to rest if this was the last ref on the superblock
+		 */
+		if (atomic_read(&mnt->mnt_sb->s_active) == 1) {
+			/* last instance - try to be smart */
+			lock_kernel();
+			DQUOT_OFF(mnt->mnt_sb);
+			acct_auto_close(mnt->mnt_sb);
+			unlock_kernel();
+		}
+		mntput(mnt);
+	} else {
+		/*
+		 * Someone brought it back to life whilst we didn't have any
+		 * locks held so return it to the expiration list
+		 */
+		list_add_tail(&mnt->mnt_expire, mounts);
+		spin_unlock(&vfsmount_lock);
+	}
+}
+
 /*
  * process a list of expirable mountpoints with the intent of discarding any
  * mountpoints that aren't in use and haven't been touched since last we came
@@ -846,13 +896,13 @@ void mark_mounts_for_expiry(struct list_
 	 * - still marked for expiry (marked on the last call here; marks are
 	 *   cleared by mntput())
 	 */
-	list_for_each_entry_safe(mnt, next, mounts, mnt_fslink) {
+	list_for_each_entry_safe(mnt, next, mounts, mnt_expire) {
 		if (!xchg(&mnt->mnt_expiry_mark, 1) ||
 		    atomic_read(&mnt->mnt_count) != 1)
 			continue;
 
 		mntget(mnt);
-		list_move(&mnt->mnt_fslink, &graveyard);
+		list_move(&mnt->mnt_expire, &graveyard);
 	}
 
 	/*
@@ -862,61 +912,19 @@ void mark_mounts_for_expiry(struct list_
 	 * - dispose of the corpse
 	 */
 	while (!list_empty(&graveyard)) {
-		mnt = list_entry(graveyard.next, struct vfsmount, mnt_fslink);
-		list_del_init(&mnt->mnt_fslink);
+		mnt = list_entry(graveyard.next, struct vfsmount, mnt_expire);
+		list_del_init(&mnt->mnt_expire);
 
 		/* don't do anything if the namespace is dead - all the
 		 * vfsmounts from it are going away anyway */
 		namespace = mnt->mnt_namespace;
-		if (!namespace || atomic_read(&namespace->count) <= 0)
+		if (!namespace || !namespace->root)
 			continue;
 		get_namespace(namespace);
 
 		spin_unlock(&vfsmount_lock);
 		down_write(&namespace->sem);
-		spin_lock(&vfsmount_lock);
-
-		/* check that it is still dead: the count should now be 2 - as
-		 * contributed by the vfsmount parent and the mntget above */
-		if (atomic_read(&mnt->mnt_count) == 2) {
-			struct vfsmount *xdmnt;
-			struct dentry *xdentry;
-
-			/* delete from the namespace */
-			list_del_init(&mnt->mnt_list);
-			list_del_init(&mnt->mnt_child);
-			list_del_init(&mnt->mnt_hash);
-			mnt->mnt_mountpoint->d_mounted--;
-
-			xdentry = mnt->mnt_mountpoint;
-			mnt->mnt_mountpoint = mnt->mnt_root;
-			xdmnt = mnt->mnt_parent;
-			mnt->mnt_parent = mnt;
-
-			spin_unlock(&vfsmount_lock);
-
-			mntput(xdmnt);
-			dput(xdentry);
-
-			/* now lay it to rest if this was the last ref on the
-			 * superblock */
-			if (atomic_read(&mnt->mnt_sb->s_active) == 1) {
-				/* last instance - try to be smart */
-				lock_kernel();
-				DQUOT_OFF(mnt->mnt_sb);
-				acct_auto_close(mnt->mnt_sb);
-				unlock_kernel();
-			}
-
-			mntput(mnt);
-		} else {
-			/* someone brought it back to life whilst we didn't
-			 * have any locks held so return it to the expiration
-			 * list */
-			list_add_tail(&mnt->mnt_fslink, mounts);
-			spin_unlock(&vfsmount_lock);
-		}
-
+		expire_mount(mnt, mounts);
 		up_write(&namespace->sem);
 
 		mntput(mnt);
@@ -1449,16 +1457,12 @@ void __init mnt_init(unsigned long mempa
 
 void __put_namespace(struct namespace *namespace)
 {
-	struct vfsmount *mnt;
-
+	struct vfsmount *root = namespace->root;
+	namespace->root = NULL;
+	spin_unlock(&vfsmount_lock);
 	down_write(&namespace->sem);
 	spin_lock(&vfsmount_lock);
-
-	list_for_each_entry(mnt, &namespace->list, mnt_list) {
-		mnt->mnt_namespace = NULL;
-	}
-
-	umount_tree(namespace->root);
+	umount_tree(root);
 	spin_unlock(&vfsmount_lock);
 	up_write(&namespace->sem);
 	kfree(namespace);
diff --git a/fs/ncpfs/dir.c b/fs/ncpfs/dir.c
--- a/fs/ncpfs/dir.c
+++ b/fs/ncpfs/dir.c
@@ -705,18 +705,6 @@ ncp_do_readdir(struct file *filp, void *
 		DPRINTK("ncp_do_readdir: init failed, err=%d\n", err);
 		return;
 	}
-#ifdef USE_OLD_SLOW_DIRECTORY_LISTING
-	for (;;) {
-		err = ncp_search_for_file_or_subdir(server, &seq, &entry.i);
-		if (err) {
-			DPRINTK("ncp_do_readdir: search failed, err=%d\n", err);
-			break;
-		}
-		entry.volume = entry.i.volNumber;
-		if (!ncp_fill_cache(filp, dirent, filldir, ctl, &entry))
-			break;
-	}
-#else
 	/* We MUST NOT use server->buffer_size handshaked with server if we are
 	   using UDP, as for UDP server uses max. buffer size determined by
 	   MTU, and for TCP server uses hardwired value 65KB (== 66560 bytes). 
@@ -754,7 +742,6 @@ ncp_do_readdir(struct file *filp, void *
 		}
 	} while (more);
 	vfree(buf);
-#endif
 	return;
 }
 
diff --git a/fs/ncpfs/ncplib_kernel.c b/fs/ncpfs/ncplib_kernel.c
--- a/fs/ncpfs/ncplib_kernel.c
+++ b/fs/ncpfs/ncplib_kernel.c
@@ -845,46 +845,6 @@ out:
 	return result;
 }
 
-/* Search for everything */
-int ncp_search_for_file_or_subdir(struct ncp_server *server,
-				  struct nw_search_sequence *seq,
-				  struct nw_info_struct *target)
-{
-	int result;
-
-	ncp_init_request(server);
-	ncp_add_byte(server, 3);	/* subfunction */
-	ncp_add_byte(server, server->name_space[seq->volNumber]);
-	ncp_add_byte(server, 0);	/* data stream (???) */
-	ncp_add_word(server, cpu_to_le16(0x8006));	/* Search attribs */
-	ncp_add_dword(server, RIM_ALL);		/* return info mask */
-	ncp_add_mem(server, seq, 9);
-#ifdef CONFIG_NCPFS_NFS_NS
-	if (server->name_space[seq->volNumber] == NW_NS_NFS) {
-		ncp_add_byte(server, 0);	/* 0 byte pattern */
-	} else 
-#endif
-	{
-		ncp_add_byte(server, 2);	/* 2 byte pattern */
-		ncp_add_byte(server, 0xff);	/* following is a wildcard */
-		ncp_add_byte(server, '*');
-	}
-	
-	if ((result = ncp_request(server, 87)) != 0)
-		goto out;
-	memcpy(seq, ncp_reply_data(server, 0), sizeof(*seq));
-	ncp_extract_file_info(ncp_reply_data(server, 10), target);
-
-	ncp_unlock_server(server);
-	
-	result = ncp_obtain_nfs_info(server, target);
-	return result;
-
-out:
-	ncp_unlock_server(server);
-	return result;
-}
-
 int ncp_search_for_fileset(struct ncp_server *server,
 			   struct nw_search_sequence *seq,
 			   int* more,
diff --git a/fs/ncpfs/ncplib_kernel.h b/fs/ncpfs/ncplib_kernel.h
--- a/fs/ncpfs/ncplib_kernel.h
+++ b/fs/ncpfs/ncplib_kernel.h
@@ -87,9 +87,6 @@ int ncp_open_create_file_or_subdir(struc
 
 int ncp_initialize_search(struct ncp_server *, struct inode *,
 		      struct nw_search_sequence *target);
-int ncp_search_for_file_or_subdir(struct ncp_server *server,
-			      struct nw_search_sequence *seq,
-			      struct nw_info_struct *target);
 int ncp_search_for_fileset(struct ncp_server *server,
 			   struct nw_search_sequence *seq,
 			   int* more, int* cnt,
diff --git a/fs/nfs/Makefile b/fs/nfs/Makefile
--- a/fs/nfs/Makefile
+++ b/fs/nfs/Makefile
@@ -8,6 +8,7 @@ nfs-y 			:= dir.o file.o inode.o nfs2xdr
 			   proc.o read.o symlink.o unlink.o write.o
 nfs-$(CONFIG_ROOT_NFS)	+= nfsroot.o mount_clnt.o      
 nfs-$(CONFIG_NFS_V3)	+= nfs3proc.o nfs3xdr.o
+nfs-$(CONFIG_NFS_V3_ACL)	+= nfs3acl.o
 nfs-$(CONFIG_NFS_V4)	+= nfs4proc.o nfs4xdr.o nfs4state.o nfs4renewd.o \
 			   delegation.o idmap.o \
 			   callback.o callback_xdr.o callback_proc.o
diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c
--- a/fs/nfs/callback.c
+++ b/fs/nfs/callback.c
@@ -14,6 +14,7 @@
 #include <linux/sunrpc/svc.h>
 #include <linux/sunrpc/svcsock.h>
 #include <linux/nfs_fs.h>
+#include "nfs4_fs.h"
 #include "callback.h"
 
 #define NFSDBG_FACILITY NFSDBG_CALLBACK
diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c
--- a/fs/nfs/callback_proc.c
+++ b/fs/nfs/callback_proc.c
@@ -8,6 +8,7 @@
 #include <linux/config.h>
 #include <linux/nfs4.h>
 #include <linux/nfs_fs.h>
+#include "nfs4_fs.h"
 #include "callback.h"
 #include "delegation.h"
 
diff --git a/fs/nfs/callback_xdr.c b/fs/nfs/callback_xdr.c
--- a/fs/nfs/callback_xdr.c
+++ b/fs/nfs/callback_xdr.c
@@ -10,6 +10,7 @@
 #include <linux/sunrpc/svc.h>
 #include <linux/nfs4.h>
 #include <linux/nfs_fs.h>
+#include "nfs4_fs.h"
 #include "callback.h"
 
 #define CB_OP_TAGLEN_MAXSZ	(512)
@@ -410,7 +411,6 @@ static int nfs4_callback_compound(struct
 	xdr_init_decode(&xdr_in, &rqstp->rq_arg, rqstp->rq_arg.head[0].iov_base);
 
 	p = (uint32_t*)((char *)rqstp->rq_res.head[0].iov_base + rqstp->rq_res.head[0].iov_len);
-	rqstp->rq_res.head[0].iov_len = PAGE_SIZE;
 	xdr_init_encode(&xdr_out, &rqstp->rq_res, p);
 
 	decode_compound_hdr_arg(&xdr_in, &hdr_arg);
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c
--- a/fs/nfs/delegation.c
+++ b/fs/nfs/delegation.c
@@ -16,6 +16,7 @@
 #include <linux/nfs_fs.h>
 #include <linux/nfs_xdr.h>
 
+#include "nfs4_fs.h"
 #include "delegation.h"
 
 static struct nfs_delegation *nfs_alloc_delegation(void)
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -32,6 +32,7 @@
 #include <linux/smp_lock.h>
 #include <linux/namei.h>
 
+#include "nfs4_fs.h"
 #include "delegation.h"
 
 #define NFS_PARANOIA 1
@@ -50,8 +51,10 @@ static int nfs_mknod(struct inode *, str
 static int nfs_rename(struct inode *, struct dentry *,
 		      struct inode *, struct dentry *);
 static int nfs_fsync_dir(struct file *, struct dentry *, int);
+static loff_t nfs_llseek_dir(struct file *, loff_t, int);
 
 struct file_operations nfs_dir_operations = {
+	.llseek		= nfs_llseek_dir,
 	.read		= generic_read_dir,
 	.readdir	= nfs_readdir,
 	.open		= nfs_opendir,
@@ -74,6 +77,27 @@ struct inode_operations nfs_dir_inode_op
 	.setattr	= nfs_setattr,
 };
 
+#ifdef CONFIG_NFS_V3
+struct inode_operations nfs3_dir_inode_operations = {
+	.create		= nfs_create,
+	.lookup		= nfs_lookup,
+	.link		= nfs_link,
+	.unlink		= nfs_unlink,
+	.symlink	= nfs_symlink,
+	.mkdir		= nfs_mkdir,
+	.rmdir		= nfs_rmdir,
+	.mknod		= nfs_mknod,
+	.rename		= nfs_rename,
+	.permission	= nfs_permission,
+	.getattr	= nfs_getattr,
+	.setattr	= nfs_setattr,
+	.listxattr	= nfs3_listxattr,
+	.getxattr	= nfs3_getxattr,
+	.setxattr	= nfs3_setxattr,
+	.removexattr	= nfs3_removexattr,
+};
+#endif  /* CONFIG_NFS_V3 */
+
 #ifdef CONFIG_NFS_V4
 
 static struct dentry *nfs_atomic_lookup(struct inode *, struct dentry *, struct nameidata *);
@@ -90,6 +114,9 @@ struct inode_operations nfs4_dir_inode_o
 	.permission	= nfs_permission,
 	.getattr	= nfs_getattr,
 	.setattr	= nfs_setattr,
+	.getxattr       = nfs4_getxattr,
+	.setxattr       = nfs4_setxattr,
+	.listxattr      = nfs4_listxattr,
 };
 
 #endif /* CONFIG_NFS_V4 */
@@ -116,7 +143,8 @@ typedef struct {
 	struct page	*page;
 	unsigned long	page_index;
 	u32		*ptr;
-	u64		target;
+	u64		*dir_cookie;
+	loff_t		current_index;
 	struct nfs_entry *entry;
 	decode_dirent_t	decode;
 	int		plus;
@@ -154,22 +182,22 @@ int nfs_readdir_filler(nfs_readdir_descr
 		/* We requested READDIRPLUS, but the server doesn't grok it */
 		if (error == -ENOTSUPP && desc->plus) {
 			NFS_SERVER(inode)->caps &= ~NFS_CAP_READDIRPLUS;
-			NFS_FLAGS(inode) &= ~NFS_INO_ADVISE_RDPLUS;
+			clear_bit(NFS_INO_ADVISE_RDPLUS, &NFS_FLAGS(inode));
 			desc->plus = 0;
 			goto again;
 		}
 		goto error;
 	}
 	SetPageUptodate(page);
-	NFS_FLAGS(inode) |= NFS_INO_INVALID_ATIME;
+	spin_lock(&inode->i_lock);
+	NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ATIME;
+	spin_unlock(&inode->i_lock);
 	/* Ensure consistent page alignment of the data.
 	 * Note: assumes we have exclusive access to this mapping either
-	 *	 throught inode->i_sem or some other mechanism.
+	 *	 through inode->i_sem or some other mechanism.
 	 */
-	if (page->index == 0) {
-		invalidate_inode_pages(inode->i_mapping);
-		NFS_I(inode)->readdir_timestamp = timestamp;
-	}
+	if (page->index == 0)
+		invalidate_inode_pages2_range(inode->i_mapping, PAGE_CACHE_SIZE, -1);
 	unlock_page(page);
 	return 0;
  error:
@@ -202,22 +230,22 @@ void dir_page_release(nfs_readdir_descri
 
 /*
  * Given a pointer to a buffer that has already been filled by a call
- * to readdir, find the next entry.
+ * to readdir, find the next entry with cookie '*desc->dir_cookie'.
  *
  * If the end of the buffer has been reached, return -EAGAIN, if not,
  * return the offset within the buffer of the next entry to be
  * read.
  */
 static inline
-int find_dirent(nfs_readdir_descriptor_t *desc, struct page *page)
+int find_dirent(nfs_readdir_descriptor_t *desc)
 {
 	struct nfs_entry *entry = desc->entry;
 	int		loop_count = 0,
 			status;
 
 	while((status = dir_decode(desc)) == 0) {
-		dfprintk(VFS, "NFS: found cookie %Lu\n", (long long)entry->cookie);
-		if (entry->prev_cookie == desc->target)
+		dfprintk(VFS, "NFS: found cookie %Lu\n", (unsigned long long)entry->cookie);
+		if (entry->prev_cookie == *desc->dir_cookie)
 			break;
 		if (loop_count++ > 200) {
 			loop_count = 0;
@@ -229,8 +257,44 @@ int find_dirent(nfs_readdir_descriptor_t
 }
 
 /*
- * Find the given page, and call find_dirent() in order to try to
- * return the next entry.
+ * Given a pointer to a buffer that has already been filled by a call
+ * to readdir, find the entry at offset 'desc->file->f_pos'.
+ *
+ * If the end of the buffer has been reached, return -EAGAIN, if not,
+ * return the offset within the buffer of the next entry to be
+ * read.
+ */
+static inline
+int find_dirent_index(nfs_readdir_descriptor_t *desc)
+{
+	struct nfs_entry *entry = desc->entry;
+	int		loop_count = 0,
+			status;
+
+	for(;;) {
+		status = dir_decode(desc);
+		if (status)
+			break;
+
+		dfprintk(VFS, "NFS: found cookie %Lu at index %Ld\n", (unsigned long long)entry->cookie, desc->current_index);
+
+		if (desc->file->f_pos == desc->current_index) {
+			*desc->dir_cookie = entry->cookie;
+			break;
+		}
+		desc->current_index++;
+		if (loop_count++ > 200) {
+			loop_count = 0;
+			schedule();
+		}
+	}
+	dfprintk(VFS, "NFS: find_dirent_index() returns %d\n", status);
+	return status;
+}
+
+/*
+ * Find the given page, and call find_dirent() or find_dirent_index in
+ * order to try to return the next entry.
  */
 static inline
 int find_dirent_page(nfs_readdir_descriptor_t *desc)
@@ -253,7 +317,10 @@ int find_dirent_page(nfs_readdir_descrip
 	/* NOTE: Someone else may have changed the READDIRPLUS flag */
 	desc->page = page;
 	desc->ptr = kmap(page);		/* matching kunmap in nfs_do_filldir */
-	status = find_dirent(desc, page);
+	if (*desc->dir_cookie != 0)
+		status = find_dirent(desc);
+	else
+		status = find_dirent_index(desc);
 	if (status < 0)
 		dir_page_release(desc);
  out:
@@ -268,7 +335,8 @@ int find_dirent_page(nfs_readdir_descrip
  * Recurse through the page cache pages, and return a
  * filled nfs_entry structure of the next directory entry if possible.
  *
- * The target for the search is 'desc->target'.
+ * The target for the search is '*desc->dir_cookie' if non-0,
+ * 'desc->file->f_pos' otherwise
  */
 static inline
 int readdir_search_pagecache(nfs_readdir_descriptor_t *desc)
@@ -276,7 +344,16 @@ int readdir_search_pagecache(nfs_readdir
 	int		loop_count = 0;
 	int		res;
 
-	dfprintk(VFS, "NFS: readdir_search_pagecache() searching for cookie %Lu\n", (long long)desc->target);
+	/* Always search-by-index from the beginning of the cache */
+	if (*desc->dir_cookie == 0) {
+		dfprintk(VFS, "NFS: readdir_search_pagecache() searching for offset %Ld\n", (long long)desc->file->f_pos);
+		desc->page_index = 0;
+		desc->entry->cookie = desc->entry->prev_cookie = 0;
+		desc->entry->eof = 0;
+		desc->current_index = 0;
+	} else
+		dfprintk(VFS, "NFS: readdir_search_pagecache() searching for cookie %Lu\n", (unsigned long long)*desc->dir_cookie);
+
 	for (;;) {
 		res = find_dirent_page(desc);
 		if (res != -EAGAIN)
@@ -313,7 +390,7 @@ int nfs_do_filldir(nfs_readdir_descripto
 	int		loop_count = 0,
 			res;
 
-	dfprintk(VFS, "NFS: nfs_do_filldir() filling starting @ cookie %Lu\n", (long long)desc->target);
+	dfprintk(VFS, "NFS: nfs_do_filldir() filling starting @ cookie %Lu\n", (long long)entry->cookie);
 
 	for(;;) {
 		unsigned d_type = DT_UNKNOWN;
@@ -333,10 +410,11 @@ int nfs_do_filldir(nfs_readdir_descripto
 		}
 
 		res = filldir(dirent, entry->name, entry->len, 
-			      entry->prev_cookie, fileid, d_type);
+			      file->f_pos, fileid, d_type);
 		if (res < 0)
 			break;
-		file->f_pos = desc->target = entry->cookie;
+		file->f_pos++;
+		*desc->dir_cookie = entry->cookie;
 		if (dir_decode(desc) != 0) {
 			desc->page_index ++;
 			break;
@@ -349,7 +427,7 @@ int nfs_do_filldir(nfs_readdir_descripto
 	dir_page_release(desc);
 	if (dentry != NULL)
 		dput(dentry);
-	dfprintk(VFS, "NFS: nfs_do_filldir() filling ended @ cookie %Lu; returning = %d\n", (long long)desc->target, res);
+	dfprintk(VFS, "NFS: nfs_do_filldir() filling ended @ cookie %Lu; returning = %d\n", (unsigned long long)*desc->dir_cookie, res);
 	return res;
 }
 
@@ -375,23 +453,25 @@ int uncached_readdir(nfs_readdir_descrip
 	struct page	*page = NULL;
 	int		status;
 
-	dfprintk(VFS, "NFS: uncached_readdir() searching for cookie %Lu\n", (long long)desc->target);
+	dfprintk(VFS, "NFS: uncached_readdir() searching for cookie %Lu\n", (unsigned long long)*desc->dir_cookie);
 
 	page = alloc_page(GFP_HIGHUSER);
 	if (!page) {
 		status = -ENOMEM;
 		goto out;
 	}
-	desc->error = NFS_PROTO(inode)->readdir(file->f_dentry, cred, desc->target,
+	desc->error = NFS_PROTO(inode)->readdir(file->f_dentry, cred, *desc->dir_cookie,
 						page,
 						NFS_SERVER(inode)->dtsize,
 						desc->plus);
-	NFS_FLAGS(inode) |= NFS_INO_INVALID_ATIME;
+	spin_lock(&inode->i_lock);
+	NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ATIME;
+	spin_unlock(&inode->i_lock);
 	desc->page = page;
 	desc->ptr = kmap(page);		/* matching kunmap in nfs_do_filldir */
 	if (desc->error >= 0) {
 		if ((status = dir_decode(desc)) == 0)
-			desc->entry->prev_cookie = desc->target;
+			desc->entry->prev_cookie = *desc->dir_cookie;
 	} else
 		status = -EIO;
 	if (status < 0)
@@ -412,8 +492,9 @@ int uncached_readdir(nfs_readdir_descrip
 	goto out;
 }
 
-/* The file offset position is now represented as a true offset into the
- * page cache as is the case in most of the other filesystems.
+/* The file offset position represents the dirent entry number.  A
+   last cookie cache takes care of the common case of reading the
+   whole directory.
  */
 static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
 {
@@ -435,15 +516,15 @@ static int nfs_readdir(struct file *filp
 	}
 
 	/*
-	 * filp->f_pos points to the file offset in the page cache.
-	 * but if the cache has meanwhile been zapped, we need to
-	 * read from the last dirent to revalidate f_pos
-	 * itself.
+	 * filp->f_pos points to the dirent entry number.
+	 * *desc->dir_cookie has the cookie for the next entry. We have
+	 * to either find the entry with the appropriate number or
+	 * revalidate the cookie.
 	 */
 	memset(desc, 0, sizeof(*desc));
 
 	desc->file = filp;
-	desc->target = filp->f_pos;
+	desc->dir_cookie = &((struct nfs_open_context *)filp->private_data)->dir_cookie;
 	desc->decode = NFS_PROTO(inode)->decode_dirent;
 	desc->plus = NFS_USE_READDIRPLUS(inode);
 
@@ -455,9 +536,10 @@ static int nfs_readdir(struct file *filp
 
 	while(!desc->entry->eof) {
 		res = readdir_search_pagecache(desc);
+
 		if (res == -EBADCOOKIE) {
 			/* This means either end of directory */
-			if (desc->entry->cookie != desc->target) {
+			if (*desc->dir_cookie && desc->entry->cookie != *desc->dir_cookie) {
 				/* Or that the server has 'lost' a cookie */
 				res = uncached_readdir(desc, dirent, filldir);
 				if (res >= 0)
@@ -467,7 +549,7 @@ static int nfs_readdir(struct file *filp
 			break;
 		}
 		if (res == -ETOOSMALL && desc->plus) {
-			NFS_FLAGS(inode) &= ~NFS_INO_ADVISE_RDPLUS;
+			clear_bit(NFS_INO_ADVISE_RDPLUS, &NFS_FLAGS(inode));
 			nfs_zap_caches(inode);
 			desc->plus = 0;
 			desc->entry->eof = 0;
@@ -490,6 +572,28 @@ static int nfs_readdir(struct file *filp
 	return 0;
 }
 
+loff_t nfs_llseek_dir(struct file *filp, loff_t offset, int origin)
+{
+	down(&filp->f_dentry->d_inode->i_sem);
+	switch (origin) {
+		case 1:
+			offset += filp->f_pos;
+		case 0:
+			if (offset >= 0)
+				break;
+		default:
+			offset = -EINVAL;
+			goto out;
+	}
+	if (offset != filp->f_pos) {
+		filp->f_pos = offset;
+		((struct nfs_open_context *)filp->private_data)->dir_cookie = 0;
+	}
+out:
+	up(&filp->f_dentry->d_inode->i_sem);
+	return offset;
+}
+
 /*
  * All directory operations under NFS are synchronous, so fsync()
  * is a dummy operation.
@@ -508,7 +612,7 @@ static inline int nfs_check_verifier(str
 {
 	if (IS_ROOT(dentry))
 		return 1;
-	if ((NFS_FLAGS(dir) & NFS_INO_INVALID_ATTR) != 0
+	if ((NFS_I(dir)->cache_validity & NFS_INO_INVALID_ATTR) != 0
 			|| nfs_attribute_timeout(dir))
 		return 0;
 	return nfs_verify_change_attribute(dir, (unsigned long)dentry->d_fsdata);
@@ -835,6 +939,7 @@ static struct dentry *nfs_atomic_lookup(
 	error = nfs_revalidate_inode(NFS_SERVER(dir), dir);
 	if (error < 0) {
 		res = ERR_PTR(error);
+		unlock_kernel();
 		goto out;
 	}
 
@@ -1475,11 +1580,12 @@ out:
 
 int nfs_access_get_cached(struct inode *inode, struct rpc_cred *cred, struct nfs_access_entry *res)
 {
-	struct nfs_access_entry *cache = &NFS_I(inode)->cache_access;
+	struct nfs_inode *nfsi = NFS_I(inode);
+	struct nfs_access_entry *cache = &nfsi->cache_access;
 
 	if (cache->cred != cred
 			|| time_after(jiffies, cache->jiffies + NFS_ATTRTIMEO(inode))
-			|| (NFS_FLAGS(inode) & NFS_INO_INVALID_ACCESS))
+			|| (nfsi->cache_validity & NFS_INO_INVALID_ACCESS))
 		return -ENOENT;
 	memcpy(res, cache, sizeof(*res));
 	return 0;
@@ -1487,14 +1593,18 @@ int nfs_access_get_cached(struct inode *
 
 void nfs_access_add_cache(struct inode *inode, struct nfs_access_entry *set)
 {
-	struct nfs_access_entry *cache = &NFS_I(inode)->cache_access;
+	struct nfs_inode *nfsi = NFS_I(inode);
+	struct nfs_access_entry *cache = &nfsi->cache_access;
 
 	if (cache->cred != set->cred) {
 		if (cache->cred)
 			put_rpccred(cache->cred);
 		cache->cred = get_rpccred(set->cred);
 	}
-	NFS_FLAGS(inode) &= ~NFS_INO_INVALID_ACCESS;
+	/* FIXME: replace current access_cache BKL reliance with inode->i_lock */
+	spin_lock(&inode->i_lock);
+	nfsi->cache_validity &= ~NFS_INO_INVALID_ACCESS;
+	spin_unlock(&inode->i_lock);
 	cache->jiffies = set->jiffies;
 	cache->mask = set->mask;
 }
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
--- a/fs/nfs/direct.c
+++ b/fs/nfs/direct.c
@@ -517,7 +517,7 @@ retry:
 	result = tot_bytes;
 
 out:
-	nfs_end_data_update_defer(inode);
+	nfs_end_data_update(inode);
 	nfs_writedata_free(wdata);
 	return result;
 
@@ -751,11 +751,6 @@ nfs_file_direct_write(struct kiocb *iocb
 	retval = -EFAULT;
 	if (!access_ok(VERIFY_READ, iov.iov_base, iov.iov_len))
 		goto out;
-        if (file->f_error) {
-                retval = file->f_error;
-                file->f_error = 0;
-                goto out;
-        }
 	retval = -EFBIG;
 	if (limit != RLIM_INFINITY) {
 		if (pos >= limit) {
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -71,6 +71,18 @@ struct inode_operations nfs_file_inode_o
 	.setattr	= nfs_setattr,
 };
 
+#ifdef CONFIG_NFS_V3
+struct inode_operations nfs3_file_inode_operations = {
+	.permission	= nfs_permission,
+	.getattr	= nfs_getattr,
+	.setattr	= nfs_setattr,
+	.listxattr	= nfs3_listxattr,
+	.getxattr	= nfs3_getxattr,
+	.setxattr	= nfs3_setxattr,
+	.removexattr	= nfs3_removexattr,
+};
+#endif  /* CONFIG_NFS_v3 */
+
 /* Hack for future NFS swap support */
 #ifndef IS_SWAPFILE
 # define IS_SWAPFILE(inode)	(0)
@@ -116,6 +128,22 @@ nfs_file_release(struct inode *inode, st
 }
 
 /**
+ * nfs_revalidate_file - Revalidate the page cache & related metadata
+ * @inode - pointer to inode struct
+ * @file - pointer to file
+ */
+static int nfs_revalidate_file(struct inode *inode, struct file *filp)
+{
+	struct nfs_inode *nfsi = NFS_I(inode);
+	int retval = 0;
+
+	if ((nfsi->cache_validity & NFS_INO_REVAL_PAGECACHE) || nfs_attribute_timeout(inode))
+		retval = __nfs_revalidate_inode(NFS_SERVER(inode), inode);
+	nfs_revalidate_mapping(inode, filp->f_mapping);
+	return 0;
+}
+
+/**
  * nfs_revalidate_size - Revalidate the file size
  * @inode - pointer to inode struct
  * @file - pointer to struct file
@@ -137,7 +165,8 @@ static int nfs_revalidate_file_size(stru
 		goto force_reval;
 	if (nfsi->npages != 0)
 		return 0;
-	return nfs_revalidate_inode(server, inode);
+	if (!(nfsi->cache_validity & NFS_INO_REVAL_PAGECACHE) && !nfs_attribute_timeout(inode))
+		return 0;
 force_reval:
 	return __nfs_revalidate_inode(server, inode);
 }
@@ -198,7 +227,7 @@ nfs_file_read(struct kiocb *iocb, char _
 		dentry->d_parent->d_name.name, dentry->d_name.name,
 		(unsigned long) count, (unsigned long) pos);
 
-	result = nfs_revalidate_inode(NFS_SERVER(inode), inode);
+	result = nfs_revalidate_file(inode, iocb->ki_filp);
 	if (!result)
 		result = generic_file_aio_read(iocb, buf, count, pos);
 	return result;
@@ -216,7 +245,7 @@ nfs_file_sendfile(struct file *filp, lof
 		dentry->d_parent->d_name.name, dentry->d_name.name,
 		(unsigned long) count, (unsigned long long) *ppos);
 
-	res = nfs_revalidate_inode(NFS_SERVER(inode), inode);
+	res = nfs_revalidate_file(inode, filp);
 	if (!res)
 		res = generic_file_sendfile(filp, ppos, count, actor, target);
 	return res;
@@ -232,7 +261,7 @@ nfs_file_mmap(struct file * file, struct
 	dfprintk(VFS, "nfs: mmap(%s/%s)\n",
 		dentry->d_parent->d_name.name, dentry->d_name.name);
 
-	status = nfs_revalidate_inode(NFS_SERVER(inode), inode);
+	status = nfs_revalidate_file(inode, file);
 	if (!status)
 		status = generic_file_mmap(file, vma);
 	return status;
@@ -321,9 +350,15 @@ nfs_file_write(struct kiocb *iocb, const
 	result = -EBUSY;
 	if (IS_SWAPFILE(inode))
 		goto out_swapfile;
-	result = nfs_revalidate_inode(NFS_SERVER(inode), inode);
-	if (result)
-		goto out;
+	/*
+	 * O_APPEND implies that we must revalidate the file length.
+	 */
+	if (iocb->ki_filp->f_flags & O_APPEND) {
+		result = nfs_revalidate_file_size(inode, iocb->ki_filp);
+		if (result)
+			goto out;
+	}
+	nfs_revalidate_mapping(inode, iocb->ki_filp->f_mapping);
 
 	result = count;
 	if (!count)
diff --git a/fs/nfs/idmap.c b/fs/nfs/idmap.c
--- a/fs/nfs/idmap.c
+++ b/fs/nfs/idmap.c
@@ -50,6 +50,7 @@
 #include <linux/nfs_fs.h>
 
 #include <linux/nfs_idmap.h>
+#include "nfs4_fs.h"
 
 #define IDMAP_HASH_SZ          128
 
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -39,6 +39,7 @@
 #include <asm/system.h>
 #include <asm/uaccess.h>
 
+#include "nfs4_fs.h"
 #include "delegation.h"
 
 #define NFSDBG_FACILITY		NFSDBG_VFS
@@ -63,6 +64,7 @@ static void nfs_clear_inode(struct inode
 static void nfs_umount_begin(struct super_block *);
 static int  nfs_statfs(struct super_block *, struct kstatfs *);
 static int  nfs_show_options(struct seq_file *, struct vfsmount *);
+static void nfs_zap_acl_cache(struct inode *);
 
 static struct rpc_program	nfs_program;
 
@@ -106,6 +108,21 @@ static struct rpc_program	nfs_program = 
 	.pipe_dir_name		= "/nfs",
 };
 
+#ifdef CONFIG_NFS_V3_ACL
+static struct rpc_stat		nfsacl_rpcstat = { &nfsacl_program };
+static struct rpc_version *	nfsacl_version[] = {
+	[3]			= &nfsacl_version3,
+};
+
+struct rpc_program		nfsacl_program = {
+	.name =			"nfsacl",
+	.number =		NFS_ACL_PROGRAM,
+	.nrvers =		sizeof(nfsacl_version) / sizeof(nfsacl_version[0]),
+	.version =		nfsacl_version,
+	.stats =		&nfsacl_rpcstat,
+};
+#endif  /* CONFIG_NFS_V3_ACL */
+
 static inline unsigned long
 nfs_fattr_to_ino_t(struct nfs_fattr *fattr)
 {
@@ -118,7 +135,7 @@ nfs_write_inode(struct inode *inode, int
 	int flags = sync ? FLUSH_WAIT : 0;
 	int ret;
 
-	ret = nfs_commit_inode(inode, 0, 0, flags);
+	ret = nfs_commit_inode(inode, flags);
 	if (ret < 0)
 		return ret;
 	return 0;
@@ -140,10 +157,6 @@ nfs_delete_inode(struct inode * inode)
 	clear_inode(inode);
 }
 
-/*
- * For the moment, the only task for the NFS clear_inode method is to
- * release the mmap credential
- */
 static void
 nfs_clear_inode(struct inode *inode)
 {
@@ -152,6 +165,7 @@ nfs_clear_inode(struct inode *inode)
 
 	nfs_wb_all(inode);
 	BUG_ON (!list_empty(&nfsi->open_files));
+	nfs_zap_acl_cache(inode);
 	cred = nfsi->cache_access.cred;
 	if (cred)
 		put_rpccred(cred);
@@ -161,11 +175,13 @@ nfs_clear_inode(struct inode *inode)
 void
 nfs_umount_begin(struct super_block *sb)
 {
-	struct nfs_server *server = NFS_SB(sb);
-	struct rpc_clnt	*rpc;
+	struct rpc_clnt	*rpc = NFS_SB(sb)->client;
 
 	/* -EIO all pending I/O */
-	if ((rpc = server->client) != NULL)
+	if (!IS_ERR(rpc))
+		rpc_killall_tasks(rpc);
+	rpc = NFS_SB(sb)->client_acl;
+	if (!IS_ERR(rpc))
 		rpc_killall_tasks(rpc);
 }
 
@@ -366,13 +382,15 @@ nfs_create_client(struct nfs_server *ser
 	xprt = xprt_create_proto(tcp ? IPPROTO_TCP : IPPROTO_UDP,
 				 &server->addr, &timeparms);
 	if (IS_ERR(xprt)) {
-		printk(KERN_WARNING "NFS: cannot create RPC transport.\n");
+		dprintk("%s: cannot create RPC transport. Error = %ld\n",
+				__FUNCTION__, PTR_ERR(xprt));
 		return (struct rpc_clnt *)xprt;
 	}
 	clnt = rpc_create_client(xprt, server->hostname, &nfs_program,
 				 server->rpc_ops->version, data->pseudoflavor);
 	if (IS_ERR(clnt)) {
-		printk(KERN_WARNING "NFS: cannot create RPC client.\n");
+		dprintk("%s: cannot create RPC client. Error = %ld\n",
+				__FUNCTION__, PTR_ERR(xprt));
 		goto out_fail;
 	}
 
@@ -383,7 +401,6 @@ nfs_create_client(struct nfs_server *ser
 	return clnt;
 
 out_fail:
-	xprt_destroy(xprt);
 	return clnt;
 }
 
@@ -427,21 +444,16 @@ nfs_fill_super(struct super_block *sb, s
 
 	/* Check NFS protocol revision and initialize RPC op vector
 	 * and file handle pool. */
-	if (server->flags & NFS_MOUNT_VER3) {
 #ifdef CONFIG_NFS_V3
+	if (server->flags & NFS_MOUNT_VER3) {
 		server->rpc_ops = &nfs_v3_clientops;
 		server->caps |= NFS_CAP_READDIRPLUS;
-		if (data->version < 4) {
-			printk(KERN_NOTICE "NFS: NFSv3 not supported by mount program.\n");
-			return -EIO;
-		}
-#else
-		printk(KERN_NOTICE "NFS: NFSv3 not supported.\n");
-		return -EIO;
-#endif
 	} else {
 		server->rpc_ops = &nfs_v2_clientops;
 	}
+#else
+	server->rpc_ops = &nfs_v2_clientops;
+#endif
 
 	/* Fill in pseudoflavor for mount version < 5 */
 	if (!(data->flags & NFS_MOUNT_SECFLAVOUR))
@@ -455,17 +467,34 @@ nfs_fill_super(struct super_block *sb, s
 		return PTR_ERR(server->client);
 	/* RFC 2623, sec 2.3.2 */
 	if (authflavor != RPC_AUTH_UNIX) {
+		struct rpc_auth *auth;
+
 		server->client_sys = rpc_clone_client(server->client);
 		if (IS_ERR(server->client_sys))
 			return PTR_ERR(server->client_sys);
-		if (!rpcauth_create(RPC_AUTH_UNIX, server->client_sys))
-			return -ENOMEM;
+		auth = rpcauth_create(RPC_AUTH_UNIX, server->client_sys);
+		if (IS_ERR(auth))
+			return PTR_ERR(auth);
 	} else {
 		atomic_inc(&server->client->cl_count);
 		server->client_sys = server->client;
 	}
-
 	if (server->flags & NFS_MOUNT_VER3) {
+#ifdef CONFIG_NFS_V3_ACL
+		if (!(server->flags & NFS_MOUNT_NOACL)) {
+			server->client_acl = rpc_bind_new_program(server->client, &nfsacl_program, 3);
+			/* No errors! Assume that Sun nfsacls are supported */
+			if (!IS_ERR(server->client_acl))
+				server->caps |= NFS_CAP_ACLS;
+		}
+#else
+		server->flags &= ~NFS_MOUNT_NOACL;
+#endif /* CONFIG_NFS_V3_ACL */
+		/*
+		 * The VFS shouldn't apply the umask to mode bits. We will
+		 * do so ourselves when necessary.
+		 */
+		sb->s_flags |= MS_POSIXACL;
 		if (server->namelen == 0 || server->namelen > NFS3_MAXNAMLEN)
 			server->namelen = NFS3_MAXNAMLEN;
 		sb->s_time_gran = 1;
@@ -549,6 +578,7 @@ static int nfs_show_options(struct seq_f
 		{ NFS_MOUNT_NOCTO, ",nocto", "" },
 		{ NFS_MOUNT_NOAC, ",noac", "" },
 		{ NFS_MOUNT_NONLM, ",nolock", ",lock" },
+		{ NFS_MOUNT_NOACL, ",noacl", "" },
 		{ 0, NULL, NULL }
 	};
 	struct proc_nfs_info *nfs_infop;
@@ -585,14 +615,30 @@ nfs_zap_caches(struct inode *inode)
 	struct nfs_inode *nfsi = NFS_I(inode);
 	int mode = inode->i_mode;
 
+	spin_lock(&inode->i_lock);
+
 	NFS_ATTRTIMEO(inode) = NFS_MINATTRTIMEO(inode);
 	NFS_ATTRTIMEO_UPDATE(inode) = jiffies;
 
 	memset(NFS_COOKIEVERF(inode), 0, sizeof(NFS_COOKIEVERF(inode)));
 	if (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode))
-		nfsi->flags |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS;
+		nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL|NFS_INO_REVAL_PAGECACHE;
 	else
-		nfsi->flags |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS;
+		nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL|NFS_INO_REVAL_PAGECACHE;
+
+	spin_unlock(&inode->i_lock);
+}
+
+static void nfs_zap_acl_cache(struct inode *inode)
+{
+	void (*clear_acl_cache)(struct inode *);
+
+	clear_acl_cache = NFS_PROTO(inode)->clear_acl_cache;
+	if (clear_acl_cache != NULL)
+		clear_acl_cache(inode);
+	spin_lock(&inode->i_lock);
+	NFS_I(inode)->cache_validity &= ~NFS_INO_INVALID_ACL;
+	spin_unlock(&inode->i_lock);
 }
 
 /*
@@ -689,7 +735,7 @@ nfs_fhget(struct super_block *sb, struct
 		/* Why so? Because we want revalidate for devices/FIFOs, and
 		 * that's precisely what we have in nfs_file_inode_operations.
 		 */
-		inode->i_op = &nfs_file_inode_operations;
+		inode->i_op = NFS_SB(sb)->rpc_ops->file_inode_ops;
 		if (S_ISREG(inode->i_mode)) {
 			inode->i_fop = &nfs_file_operations;
 			inode->i_data.a_ops = &nfs_file_aops;
@@ -699,7 +745,7 @@ nfs_fhget(struct super_block *sb, struct
 			inode->i_fop = &nfs_dir_operations;
 			if (nfs_server_capable(inode, NFS_CAP_READDIRPLUS)
 			    && fattr->size <= NFS_LIMIT_READDIRPLUS)
-				NFS_FLAGS(inode) |= NFS_INO_ADVISE_RDPLUS;
+				set_bit(NFS_INO_ADVISE_RDPLUS, &NFS_FLAGS(inode));
 		} else if (S_ISLNK(inode->i_mode))
 			inode->i_op = &nfs_symlink_inode_operations;
 		else
@@ -774,55 +820,84 @@ nfs_setattr(struct dentry *dentry, struc
 		nfs_wb_all(inode);
 	}
 	error = NFS_PROTO(inode)->setattr(dentry, &fattr, attr);
-	if (error == 0) {
+	if (error == 0)
 		nfs_refresh_inode(inode, &fattr);
+	nfs_end_data_update(inode);
+	unlock_kernel();
+	return error;
+}
+
+/**
+ * nfs_setattr_update_inode - Update inode metadata after a setattr call.
+ * @inode: pointer to struct inode
+ * @attr: pointer to struct iattr
+ *
+ * Note: we do this in the *proc.c in order to ensure that
+ *       it works for things like exclusive creates too.
+ */
+void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr)
+{
+	if ((attr->ia_valid & (ATTR_MODE|ATTR_UID|ATTR_GID)) != 0) {
 		if ((attr->ia_valid & ATTR_MODE) != 0) {
-			int mode;
-			mode = inode->i_mode & ~S_IALLUGO;
-			mode |= attr->ia_mode & S_IALLUGO;
+			int mode = attr->ia_mode & S_IALLUGO;
+			mode |= inode->i_mode & ~S_IALLUGO;
 			inode->i_mode = mode;
 		}
 		if ((attr->ia_valid & ATTR_UID) != 0)
 			inode->i_uid = attr->ia_uid;
 		if ((attr->ia_valid & ATTR_GID) != 0)
 			inode->i_gid = attr->ia_gid;
-		if ((attr->ia_valid & ATTR_SIZE) != 0) {
-			inode->i_size = attr->ia_size;
-			vmtruncate(inode, attr->ia_size);
-		}
+		spin_lock(&inode->i_lock);
+		NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
+		spin_unlock(&inode->i_lock);
+	}
+	if ((attr->ia_valid & ATTR_SIZE) != 0) {
+		inode->i_size = attr->ia_size;
+		vmtruncate(inode, attr->ia_size);
 	}
-	if ((attr->ia_valid & (ATTR_MODE|ATTR_UID|ATTR_GID)) != 0)
-		NFS_FLAGS(inode) |= NFS_INO_INVALID_ACCESS;
-	nfs_end_data_update(inode);
-	unlock_kernel();
-	return error;
+}
+
+static int nfs_wait_schedule(void *word)
+{
+	if (signal_pending(current))
+		return -ERESTARTSYS;
+	schedule();
+	return 0;
 }
 
 /*
  * Wait for the inode to get unlocked.
- * (Used for NFS_INO_LOCKED and NFS_INO_REVALIDATING).
  */
-static int
-nfs_wait_on_inode(struct inode *inode, int flag)
+static int nfs_wait_on_inode(struct inode *inode)
 {
 	struct rpc_clnt	*clnt = NFS_CLIENT(inode);
 	struct nfs_inode *nfsi = NFS_I(inode);
-
+	sigset_t oldmask;
 	int error;
-	if (!(NFS_FLAGS(inode) & flag))
-		return 0;
+
 	atomic_inc(&inode->i_count);
-	error = nfs_wait_event(clnt, nfsi->nfs_i_wait,
-				!(NFS_FLAGS(inode) & flag));
+	rpc_clnt_sigmask(clnt, &oldmask);
+	error = wait_on_bit_lock(&nfsi->flags, NFS_INO_REVALIDATING,
+					nfs_wait_schedule, TASK_INTERRUPTIBLE);
+	rpc_clnt_sigunmask(clnt, &oldmask);
 	iput(inode);
+
 	return error;
 }
 
+static void nfs_wake_up_inode(struct inode *inode)
+{
+	struct nfs_inode *nfsi = NFS_I(inode);
+
+	clear_bit(NFS_INO_REVALIDATING, &nfsi->flags);
+	smp_mb__after_clear_bit();
+	wake_up_bit(&nfsi->flags, NFS_INO_REVALIDATING);
+}
+
 int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
 {
 	struct inode *inode = dentry->d_inode;
-	struct nfs_inode *nfsi = NFS_I(inode);
-	int need_atime = nfsi->flags & NFS_INO_INVALID_ATIME;
+	int need_atime = NFS_I(inode)->cache_validity & NFS_INO_INVALID_ATIME;
 	int err;
 
 	if (__IS_FLG(inode, MS_NOATIME))
@@ -851,7 +926,7 @@ struct nfs_open_context *alloc_nfs_open_
 		ctx->state = NULL;
 		ctx->lockowner = current->files;
 		ctx->error = 0;
-		init_waitqueue_head(&ctx->waitq);
+		ctx->dir_cookie = 0;
 	}
 	return ctx;
 }
@@ -968,7 +1043,7 @@ __nfs_revalidate_inode(struct nfs_server
 	struct nfs_fattr fattr;
 	struct nfs_inode *nfsi = NFS_I(inode);
 	unsigned long verifier;
-	unsigned int flags;
+	unsigned long cache_validity;
 
 	dfprintk(PAGECACHE, "NFS: revalidating (%s/%Ld)\n",
 		inode->i_sb->s_id, (long long)NFS_FILEID(inode));
@@ -979,18 +1054,19 @@ __nfs_revalidate_inode(struct nfs_server
 	if (NFS_STALE(inode))
  		goto out_nowait;
 
-	while (NFS_REVALIDATING(inode)) {
-		status = nfs_wait_on_inode(inode, NFS_INO_REVALIDATING);
-		if (status < 0)
-			goto out_nowait;
-		if (NFS_ATTRTIMEO(inode) == 0)
-			continue;
-		if (NFS_FLAGS(inode) & (NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ATIME))
-			continue;
-		status = NFS_STALE(inode) ? -ESTALE : 0;
-		goto out_nowait;
+	status = nfs_wait_on_inode(inode);
+	if (status < 0)
+		goto out;
+	if (NFS_STALE(inode)) {
+		status = -ESTALE;
+		/* Do we trust the cached ESTALE? */
+		if (NFS_ATTRTIMEO(inode) != 0) {
+			if (nfsi->cache_validity & (NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ATIME)) {
+				/* no */
+			} else
+				goto out;
+		}
 	}
-	NFS_FLAGS(inode) |= NFS_INO_REVALIDATING;
 
 	/* Protect against RPC races by saving the change attribute */
 	verifier = nfs_save_change_attribute(inode);
@@ -1002,7 +1078,7 @@ __nfs_revalidate_inode(struct nfs_server
 		if (status == -ESTALE) {
 			nfs_zap_caches(inode);
 			if (!S_ISDIR(inode->i_mode))
-				NFS_FLAGS(inode) |= NFS_INO_STALE;
+				set_bit(NFS_INO_STALE, &NFS_FLAGS(inode));
 		}
 		goto out;
 	}
@@ -1014,36 +1090,30 @@ __nfs_revalidate_inode(struct nfs_server
 			 (long long)NFS_FILEID(inode), status);
 		goto out;
 	}
-	flags = nfsi->flags;
+	spin_lock(&inode->i_lock);
+	cache_validity = nfsi->cache_validity;
+	nfsi->cache_validity &= ~NFS_INO_REVAL_PAGECACHE;
+
 	/*
 	 * We may need to keep the attributes marked as invalid if
 	 * we raced with nfs_end_attr_update().
 	 */
 	if (verifier == nfsi->cache_change_attribute)
-		nfsi->flags &= ~(NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ATIME);
-	/* Do the page cache invalidation */
-	if (flags & NFS_INO_INVALID_DATA) {
-		if (S_ISREG(inode->i_mode)) {
-			if (filemap_fdatawrite(inode->i_mapping) == 0)
-				filemap_fdatawait(inode->i_mapping);
-			nfs_wb_all(inode);
-		}
-		nfsi->flags &= ~NFS_INO_INVALID_DATA;
-		invalidate_inode_pages2(inode->i_mapping);
-		memset(NFS_COOKIEVERF(inode), 0, sizeof(NFS_COOKIEVERF(inode)));
-		dfprintk(PAGECACHE, "NFS: (%s/%Ld) data cache invalidated\n",
-				inode->i_sb->s_id,
-				(long long)NFS_FILEID(inode));
-		/* This ensures we revalidate dentries */
-		nfsi->cache_change_attribute++;
-	}
+		nfsi->cache_validity &= ~(NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ATIME);
+	spin_unlock(&inode->i_lock);
+
+	nfs_revalidate_mapping(inode, inode->i_mapping);
+
+	if (cache_validity & NFS_INO_INVALID_ACL)
+		nfs_zap_acl_cache(inode);
+
 	dfprintk(PAGECACHE, "NFS: (%s/%Ld) revalidation complete\n",
 		inode->i_sb->s_id,
 		(long long)NFS_FILEID(inode));
 
-out:
-	NFS_FLAGS(inode) &= ~NFS_INO_REVALIDATING;
-	wake_up(&nfsi->nfs_i_wait);
+ out:
+	nfs_wake_up_inode(inode);
+
  out_nowait:
 	unlock_kernel();
 	return status;
@@ -1067,13 +1137,45 @@ int nfs_attribute_timeout(struct inode *
  */
 int nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
 {
-	if (!(NFS_FLAGS(inode) & (NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA))
+	if (!(NFS_I(inode)->cache_validity & (NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA))
 			&& !nfs_attribute_timeout(inode))
 		return NFS_STALE(inode) ? -ESTALE : 0;
 	return __nfs_revalidate_inode(server, inode);
 }
 
 /**
+ * nfs_revalidate_mapping - Revalidate the pagecache
+ * @inode - pointer to host inode
+ * @mapping - pointer to mapping
+ */
+void nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping)
+{
+	struct nfs_inode *nfsi = NFS_I(inode);
+
+	if (nfsi->cache_validity & NFS_INO_INVALID_DATA) {
+		if (S_ISREG(inode->i_mode)) {
+			if (filemap_fdatawrite(mapping) == 0)
+				filemap_fdatawait(mapping);
+			nfs_wb_all(inode);
+		}
+		invalidate_inode_pages2(mapping);
+
+		spin_lock(&inode->i_lock);
+		nfsi->cache_validity &= ~NFS_INO_INVALID_DATA;
+		if (S_ISDIR(inode->i_mode)) {
+			memset(nfsi->cookieverf, 0, sizeof(nfsi->cookieverf));
+			/* This ensures we revalidate child dentries */
+			nfsi->cache_change_attribute++;
+		}
+		spin_unlock(&inode->i_lock);
+
+		dfprintk(PAGECACHE, "NFS: (%s/%Ld) data cache invalidated\n",
+				inode->i_sb->s_id,
+				(long long)NFS_FILEID(inode));
+	}
+}
+
+/**
  * nfs_begin_data_update
  * @inode - pointer to inode
  * Declare that a set of operations will update file data on the server
@@ -1096,37 +1198,18 @@ void nfs_end_data_update(struct inode *i
 
 	if (!nfs_have_delegation(inode, FMODE_READ)) {
 		/* Mark the attribute cache for revalidation */
-		nfsi->flags |= NFS_INO_INVALID_ATTR;
+		spin_lock(&inode->i_lock);
+		nfsi->cache_validity |= NFS_INO_INVALID_ATTR;
 		/* Directories and symlinks: invalidate page cache too */
 		if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode))
-			nfsi->flags |= NFS_INO_INVALID_DATA;
+			nfsi->cache_validity |= NFS_INO_INVALID_DATA;
+		spin_unlock(&inode->i_lock);
 	}
 	nfsi->cache_change_attribute ++;
 	atomic_dec(&nfsi->data_updates);
 }
 
 /**
- * nfs_end_data_update_defer
- * @inode - pointer to inode
- * Declare end of the operations that will update file data
- * This will defer marking the inode as needing revalidation
- * unless there are no other pending updates.
- */
-void nfs_end_data_update_defer(struct inode *inode)
-{
-	struct nfs_inode *nfsi = NFS_I(inode);
-
-	if (atomic_dec_and_test(&nfsi->data_updates)) {
-		/* Mark the attribute cache for revalidation */
-		nfsi->flags |= NFS_INO_INVALID_ATTR;
-		/* Directories and symlinks: invalidate page cache too */
-		if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode))
-			nfsi->flags |= NFS_INO_INVALID_DATA;
-		nfsi->cache_change_attribute ++;
-	}
-}
-
-/**
  * nfs_refresh_inode - verify consistency of the inode attribute cache
  * @inode - pointer to inode
  * @fattr - updated attributes
@@ -1145,6 +1228,8 @@ int nfs_refresh_inode(struct inode *inod
 	if (nfs_have_delegation(inode, FMODE_READ))
 		return 0;
 
+	spin_lock(&inode->i_lock);
+
 	/* Are we in the process of updating data on the server? */
 	data_unstable = nfs_caches_unstable(inode);
 
@@ -1152,17 +1237,24 @@ int nfs_refresh_inode(struct inode *inod
 		if ((fattr->valid & NFS_ATTR_PRE_CHANGE) != 0
 				&& nfsi->change_attr == fattr->pre_change_attr)
 			nfsi->change_attr = fattr->change_attr;
-		if (!data_unstable && nfsi->change_attr != fattr->change_attr)
-			nfsi->flags |= NFS_INO_INVALID_ATTR;
+		if (nfsi->change_attr != fattr->change_attr) {
+			nfsi->cache_validity |= NFS_INO_INVALID_ATTR;
+			if (!data_unstable)
+				nfsi->cache_validity |= NFS_INO_REVAL_PAGECACHE;
+		}
 	}
 
-	if ((fattr->valid & NFS_ATTR_FATTR) == 0)
+	if ((fattr->valid & NFS_ATTR_FATTR) == 0) {
+		spin_unlock(&inode->i_lock);
 		return 0;
+	}
 
 	/* Has the inode gone and changed behind our back? */
 	if (nfsi->fileid != fattr->fileid
-			|| (inode->i_mode & S_IFMT) != (fattr->mode & S_IFMT))
+			|| (inode->i_mode & S_IFMT) != (fattr->mode & S_IFMT)) {
+		spin_unlock(&inode->i_lock);
 		return -EIO;
+	}
 
 	cur_size = i_size_read(inode);
  	new_isize = nfs_size_to_loff_t(fattr->size);
@@ -1176,27 +1268,32 @@ int nfs_refresh_inode(struct inode *inod
 	}
 
 	/* Verify a few of the more important attributes */
-	if (!data_unstable) {
-		if (!timespec_equal(&inode->i_mtime, &fattr->mtime)
-				|| cur_size != new_isize)
-			nfsi->flags |= NFS_INO_INVALID_ATTR;
-	} else if (S_ISREG(inode->i_mode) && new_isize > cur_size)
-			nfsi->flags |= NFS_INO_INVALID_ATTR;
+	if (!timespec_equal(&inode->i_mtime, &fattr->mtime)) {
+		nfsi->cache_validity |= NFS_INO_INVALID_ATTR;
+		if (!data_unstable)
+			nfsi->cache_validity |= NFS_INO_REVAL_PAGECACHE;
+	}
+	if (cur_size != new_isize) {
+		nfsi->cache_validity |= NFS_INO_INVALID_ATTR;
+		if (nfsi->npages == 0)
+			nfsi->cache_validity |= NFS_INO_REVAL_PAGECACHE;
+	}
 
 	/* Have any file permissions changed? */
 	if ((inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO)
 			|| inode->i_uid != fattr->uid
 			|| inode->i_gid != fattr->gid)
-		nfsi->flags |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS;
+		nfsi->cache_validity |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS | NFS_INO_INVALID_ACL;
 
 	/* Has the link count changed? */
 	if (inode->i_nlink != fattr->nlink)
-		nfsi->flags |= NFS_INO_INVALID_ATTR;
+		nfsi->cache_validity |= NFS_INO_INVALID_ATTR;
 
 	if (!timespec_equal(&inode->i_atime, &fattr->atime))
-		nfsi->flags |= NFS_INO_INVALID_ATIME;
+		nfsi->cache_validity |= NFS_INO_INVALID_ATIME;
 
 	nfsi->read_cache_jiffies = fattr->timestamp;
+	spin_unlock(&inode->i_lock);
 	return 0;
 }
 
@@ -1215,10 +1312,8 @@ int nfs_refresh_inode(struct inode *inod
 static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr, unsigned long verifier)
 {
 	struct nfs_inode *nfsi = NFS_I(inode);
-	__u64		new_size;
-	loff_t		new_isize;
+	loff_t cur_isize, new_isize;
 	unsigned int	invalid = 0;
-	loff_t		cur_isize;
 	int data_unstable;
 
 	dfprintk(VFS, "NFS: %s(%s/%ld ct=%d info=0x%x)\n",
@@ -1237,11 +1332,15 @@ static int nfs_update_inode(struct inode
 		goto out_err;
 	}
 
+	spin_lock(&inode->i_lock);
+
 	/*
 	 * Make sure the inode's type hasn't changed.
 	 */
-	if ((inode->i_mode & S_IFMT) != (fattr->mode & S_IFMT))
+	if ((inode->i_mode & S_IFMT) != (fattr->mode & S_IFMT)) {
+		spin_unlock(&inode->i_lock);
 		goto out_changed;
+	}
 
 	/*
 	 * Update the read time so we don't revalidate too often.
@@ -1251,61 +1350,56 @@ static int nfs_update_inode(struct inode
 	/* Are we racing with known updates of the metadata on the server? */
 	data_unstable = ! nfs_verify_change_attribute(inode, verifier);
 
-	/* Check if the file size agrees */
-	new_size = fattr->size;
+	/* Check if our cached file size is stale */
  	new_isize = nfs_size_to_loff_t(fattr->size);
 	cur_isize = i_size_read(inode);
-	if (cur_isize != new_size) {
-#ifdef NFS_DEBUG_VERBOSE
-		printk(KERN_DEBUG "NFS: isize change on %s/%ld\n", inode->i_sb->s_id, inode->i_ino);
-#endif
-		/*
-		 * If we have pending writebacks, things can get
-		 * messy.
-		 */
-		if (S_ISREG(inode->i_mode) && data_unstable) {
-			if (new_isize > cur_isize) {
+	if (new_isize != cur_isize) {
+		/* Do we perhaps have any outstanding writes? */
+		if (nfsi->npages == 0) {
+			/* No, but did we race with nfs_end_data_update()? */
+			if (verifier  ==  nfsi->cache_change_attribute) {
 				inode->i_size = new_isize;
-				invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA;
+				invalid |= NFS_INO_INVALID_DATA;
 			}
-		} else {
+			invalid |= NFS_INO_INVALID_ATTR;
+		} else if (new_isize > cur_isize) {
 			inode->i_size = new_isize;
 			invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA;
 		}
+		dprintk("NFS: isize change on server for file %s/%ld\n",
+				inode->i_sb->s_id, inode->i_ino);
 	}
 
-	/*
-	 * Note: we don't check inode->i_mtime since pipes etc.
-	 *       can change this value in VFS without requiring a
-	 *	 cache revalidation.
-	 */
+	/* Check if the mtime agrees */
 	if (!timespec_equal(&inode->i_mtime, &fattr->mtime)) {
 		memcpy(&inode->i_mtime, &fattr->mtime, sizeof(inode->i_mtime));
-#ifdef NFS_DEBUG_VERBOSE
-		printk(KERN_DEBUG "NFS: mtime change on %s/%ld\n", inode->i_sb->s_id, inode->i_ino);
-#endif
+		dprintk("NFS: mtime change on server for file %s/%ld\n",
+				inode->i_sb->s_id, inode->i_ino);
 		if (!data_unstable)
 			invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA;
 	}
 
 	if ((fattr->valid & NFS_ATTR_FATTR_V4)
 	    && nfsi->change_attr != fattr->change_attr) {
-#ifdef NFS_DEBUG_VERBOSE
-		printk(KERN_DEBUG "NFS: change_attr change on %s/%ld\n",
+		dprintk("NFS: change_attr change on server for file %s/%ld\n",
 		       inode->i_sb->s_id, inode->i_ino);
-#endif
 		nfsi->change_attr = fattr->change_attr;
 		if (!data_unstable)
-			invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS;
+			invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
 	}
 
-	memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime));
+	/* If ctime has changed we should definitely clear access+acl caches */
+	if (!timespec_equal(&inode->i_ctime, &fattr->ctime)) {
+		if (!data_unstable)
+			invalid |= NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
+		memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime));
+	}
 	memcpy(&inode->i_atime, &fattr->atime, sizeof(inode->i_atime));
 
 	if ((inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO) ||
 	    inode->i_uid != fattr->uid ||
 	    inode->i_gid != fattr->gid)
-		invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS;
+		invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
 
 	inode->i_mode = fattr->mode;
 	inode->i_nlink = fattr->nlink;
@@ -1337,8 +1431,9 @@ static int nfs_update_inode(struct inode
 				|| S_ISLNK(inode->i_mode)))
 		invalid &= ~NFS_INO_INVALID_DATA;
 	if (!nfs_have_delegation(inode, FMODE_READ))
-		nfsi->flags |= invalid;
+		nfsi->cache_validity |= invalid;
 
+	spin_unlock(&inode->i_lock);
 	return 0;
  out_changed:
 	/*
@@ -1355,7 +1450,7 @@ static int nfs_update_inode(struct inode
 	 */
 	nfs_invalidate_inode(inode);
  out_err:
-	NFS_FLAGS(inode) |= NFS_INO_STALE;
+	set_bit(NFS_INO_STALE, &NFS_FLAGS(inode));
 	return -ESTALE;
 }
 
@@ -1385,74 +1480,95 @@ static struct super_block *nfs_get_sb(st
 	int flags, const char *dev_name, void *raw_data)
 {
 	int error;
-	struct nfs_server *server;
+	struct nfs_server *server = NULL;
 	struct super_block *s;
 	struct nfs_fh *root;
 	struct nfs_mount_data *data = raw_data;
 
-	if (!data) {
-		printk("nfs_read_super: missing data argument\n");
-		return ERR_PTR(-EINVAL);
+	s = ERR_PTR(-EINVAL);
+	if (data == NULL) {
+		dprintk("%s: missing data argument\n", __FUNCTION__);
+		goto out_err;
+	}
+	if (data->version <= 0 || data->version > NFS_MOUNT_VERSION) {
+		dprintk("%s: bad mount version\n", __FUNCTION__);
+		goto out_err;
+	}
+	switch (data->version) {
+		case 1:
+			data->namlen = 0;
+		case 2:
+			data->bsize  = 0;
+		case 3:
+			if (data->flags & NFS_MOUNT_VER3) {
+				dprintk("%s: mount structure version %d does not support NFSv3\n",
+						__FUNCTION__,
+						data->version);
+				goto out_err;
+			}
+			data->root.size = NFS2_FHSIZE;
+			memcpy(data->root.data, data->old_root.data, NFS2_FHSIZE);
+		case 4:
+			if (data->flags & NFS_MOUNT_SECFLAVOUR) {
+				dprintk("%s: mount structure version %d does not support strong security\n",
+						__FUNCTION__,
+						data->version);
+				goto out_err;
+			}
+		case 5:
+			memset(data->context, 0, sizeof(data->context));
 	}
+#ifndef CONFIG_NFS_V3
+	/* If NFSv3 is not compiled in, return -EPROTONOSUPPORT */
+	s = ERR_PTR(-EPROTONOSUPPORT);
+	if (data->flags & NFS_MOUNT_VER3) {
+		dprintk("%s: NFSv3 not compiled into kernel\n", __FUNCTION__);
+		goto out_err;
+	}
+#endif /* CONFIG_NFS_V3 */
 
+	s = ERR_PTR(-ENOMEM);
 	server = kmalloc(sizeof(struct nfs_server), GFP_KERNEL);
 	if (!server)
-		return ERR_PTR(-ENOMEM);
+		goto out_err;
 	memset(server, 0, sizeof(struct nfs_server));
 	/* Zero out the NFS state stuff */
 	init_nfsv4_state(server);
-
-	if (data->version != NFS_MOUNT_VERSION) {
-		printk("nfs warning: mount version %s than kernel\n",
-			data->version < NFS_MOUNT_VERSION ? "older" : "newer");
-		if (data->version < 2)
-			data->namlen = 0;
-		if (data->version < 3)
-			data->bsize  = 0;
-		if (data->version < 4) {
-			data->flags &= ~NFS_MOUNT_VER3;
-			data->root.size = NFS2_FHSIZE;
-			memcpy(data->root.data, data->old_root.data, NFS2_FHSIZE);
-		}
-		if (data->version < 5)
-			data->flags &= ~NFS_MOUNT_SECFLAVOUR;
-	}
+	server->client = server->client_sys = server->client_acl = ERR_PTR(-EINVAL);
 
 	root = &server->fh;
 	if (data->flags & NFS_MOUNT_VER3)
 		root->size = data->root.size;
 	else
 		root->size = NFS2_FHSIZE;
+	s = ERR_PTR(-EINVAL);
 	if (root->size > sizeof(root->data)) {
-		printk("nfs_get_sb: invalid root filehandle\n");
-		kfree(server);
-		return ERR_PTR(-EINVAL);
+		dprintk("%s: invalid root filehandle\n", __FUNCTION__);
+		goto out_err;
 	}
 	memcpy(root->data, data->root.data, root->size);
 
 	/* We now require that the mount process passes the remote address */
 	memcpy(&server->addr, &data->addr, sizeof(server->addr));
 	if (server->addr.sin_addr.s_addr == INADDR_ANY) {
-		printk("NFS: mount program didn't pass remote address!\n");
-		kfree(server);
-		return ERR_PTR(-EINVAL);
+		dprintk("%s: mount program didn't pass remote address!\n",
+				__FUNCTION__);
+		goto out_err;
 	}
 
-	s = sget(fs_type, nfs_compare_super, nfs_set_super, server);
-
-	if (IS_ERR(s) || s->s_root) {
-		kfree(server);
-		return s;
+	/* Fire up rpciod if not yet running */
+	s = ERR_PTR(rpciod_up());
+	if (IS_ERR(s)) {
+		dprintk("%s: couldn't start rpciod! Error = %ld\n",
+				__FUNCTION__, PTR_ERR(s));
+		goto out_err;
 	}
 
-	s->s_flags = flags;
+	s = sget(fs_type, nfs_compare_super, nfs_set_super, server);
+	if (IS_ERR(s) || s->s_root)
+		goto out_rpciod_down;
 
-	/* Fire up rpciod if not yet running */
-	if (rpciod_up() != 0) {
-		printk(KERN_WARNING "NFS: couldn't start rpciod!\n");
-		kfree(server);
-		return ERR_PTR(-EIO);
-	}
+	s->s_flags = flags;
 
 	error = nfs_fill_super(s, data, flags & MS_VERBOSE ? 1 : 0);
 	if (error) {
@@ -1462,6 +1578,11 @@ static struct super_block *nfs_get_sb(st
 	}
 	s->s_flags |= MS_ACTIVE;
 	return s;
+out_rpciod_down:
+	rpciod_down();
+out_err:
+	kfree(server);
+	return s;
 }
 
 static void nfs_kill_super(struct super_block *s)
@@ -1470,10 +1591,12 @@ static void nfs_kill_super(struct super_
 
 	kill_anon_super(s);
 
-	if (server->client != NULL && !IS_ERR(server->client))
+	if (!IS_ERR(server->client))
 		rpc_shutdown_client(server->client);
-	if (server->client_sys != NULL && !IS_ERR(server->client_sys))
+	if (!IS_ERR(server->client_sys))
 		rpc_shutdown_client(server->client_sys);
+	if (!IS_ERR(server->client_acl))
+		rpc_shutdown_client(server->client_acl);
 
 	if (!(server->flags & NFS_MOUNT_NONLM))
 		lockd_down();	/* release rpc.lockd */
@@ -1594,15 +1717,19 @@ static int nfs4_fill_super(struct super_
 
 	clp = nfs4_get_client(&server->addr.sin_addr);
 	if (!clp) {
-		printk(KERN_WARNING "NFS: failed to create NFS4 client.\n");
+		dprintk("%s: failed to create NFS4 client.\n", __FUNCTION__);
 		return -EIO;
 	}
 
 	/* Now create transport and client */
 	authflavour = RPC_AUTH_UNIX;
 	if (data->auth_flavourlen != 0) {
-		if (data->auth_flavourlen > 1)
-			printk(KERN_INFO "NFS: cannot yet deal with multiple auth flavours.\n");
+		if (data->auth_flavourlen != 1) {
+			dprintk("%s: Invalid number of RPC auth flavours %d.\n",
+					__FUNCTION__, data->auth_flavourlen);
+			err = -EINVAL;
+			goto out_fail;
+		}
 		if (copy_from_user(&authflavour, data->auth_flavours, sizeof(authflavour))) {
 			err = -EFAULT;
 			goto out_fail;
@@ -1610,21 +1737,22 @@ static int nfs4_fill_super(struct super_
 	}
 
 	down_write(&clp->cl_sem);
-	if (clp->cl_rpcclient == NULL) {
+	if (IS_ERR(clp->cl_rpcclient)) {
 		xprt = xprt_create_proto(proto, &server->addr, &timeparms);
 		if (IS_ERR(xprt)) {
 			up_write(&clp->cl_sem);
-			printk(KERN_WARNING "NFS: cannot create RPC transport.\n");
 			err = PTR_ERR(xprt);
+			dprintk("%s: cannot create RPC transport. Error = %d\n",
+					__FUNCTION__, err);
 			goto out_fail;
 		}
 		clnt = rpc_create_client(xprt, server->hostname, &nfs_program,
 				server->rpc_ops->version, authflavour);
 		if (IS_ERR(clnt)) {
 			up_write(&clp->cl_sem);
-			printk(KERN_WARNING "NFS: cannot create RPC client.\n");
-			xprt_destroy(xprt);
 			err = PTR_ERR(clnt);
+			dprintk("%s: cannot create RPC client. Error = %d\n",
+					__FUNCTION__, err);
 			goto out_fail;
 		}
 		clnt->cl_intr     = 1;
@@ -1656,21 +1784,26 @@ static int nfs4_fill_super(struct super_
 	clp = NULL;
 
 	if (IS_ERR(clnt)) {
-		printk(KERN_WARNING "NFS: cannot create RPC client.\n");
-		return PTR_ERR(clnt);
+		err = PTR_ERR(clnt);
+		dprintk("%s: cannot create RPC client. Error = %d\n",
+				__FUNCTION__, err);
+		return err;
 	}
 
 	server->client    = clnt;
 
 	if (server->nfs4_state->cl_idmap == NULL) {
-		printk(KERN_WARNING "NFS: failed to create idmapper.\n");
+		dprintk("%s: failed to create idmapper.\n", __FUNCTION__);
 		return -ENOMEM;
 	}
 
 	if (clnt->cl_auth->au_flavor != authflavour) {
-		if (rpcauth_create(authflavour, clnt) == NULL) {
-			printk(KERN_WARNING "NFS: couldn't create credcache!\n");
-			return -ENOMEM;
+		struct rpc_auth *auth;
+
+		auth = rpcauth_create(authflavour, clnt);
+		if (IS_ERR(auth)) {
+			dprintk("%s: couldn't create credcache!\n", __FUNCTION__);
+			return PTR_ERR(auth);
 		}
 	}
 
@@ -1730,8 +1863,12 @@ static struct super_block *nfs4_get_sb(s
 	struct nfs4_mount_data *data = raw_data;
 	void *p;
 
-	if (!data) {
-		printk("nfs_read_super: missing data argument\n");
+	if (data == NULL) {
+		dprintk("%s: missing data argument\n", __FUNCTION__);
+		return ERR_PTR(-EINVAL);
+	}
+	if (data->version <= 0 || data->version > NFS4_MOUNT_VERSION) {
+		dprintk("%s: bad mount version\n", __FUNCTION__);
 		return ERR_PTR(-EINVAL);
 	}
 
@@ -1741,11 +1878,7 @@ static struct super_block *nfs4_get_sb(s
 	memset(server, 0, sizeof(struct nfs_server));
 	/* Zero out the NFS state stuff */
 	init_nfsv4_state(server);
-
-	if (data->version != NFS4_MOUNT_VERSION) {
-		printk("nfs warning: mount version %s than kernel\n",
-			data->version < NFS4_MOUNT_VERSION ? "older" : "newer");
-	}
+	server->client = server->client_sys = server->client_acl = ERR_PTR(-EINVAL);
 
 	p = nfs_copy_user_string(NULL, &data->hostname, 256);
 	if (IS_ERR(p))
@@ -1773,11 +1906,20 @@ static struct super_block *nfs4_get_sb(s
 	}
 	if (server->addr.sin_family != AF_INET ||
 	    server->addr.sin_addr.s_addr == INADDR_ANY) {
-		printk("NFS: mount program didn't pass remote IP address!\n");
+		dprintk("%s: mount program didn't pass remote IP address!\n",
+				__FUNCTION__);
 		s = ERR_PTR(-EINVAL);
 		goto out_free;
 	}
 
+	/* Fire up rpciod if not yet running */
+	s = ERR_PTR(rpciod_up());
+	if (IS_ERR(s)) {
+		dprintk("%s: couldn't start rpciod! Error = %ld\n",
+				__FUNCTION__, PTR_ERR(s));
+		goto out_free;
+	}
+
 	s = sget(fs_type, nfs4_compare_super, nfs_set_super, server);
 
 	if (IS_ERR(s) || s->s_root)
@@ -1785,13 +1927,6 @@ static struct super_block *nfs4_get_sb(s
 
 	s->s_flags = flags;
 
-	/* Fire up rpciod if not yet running */
-	if (rpciod_up() != 0) {
-		printk(KERN_WARNING "NFS: couldn't start rpciod!\n");
-		s = ERR_PTR(-EIO);
-		goto out_free;
-	}
-
 	error = nfs4_fill_super(s, data, flags & MS_VERBOSE ? 1 : 0);
 	if (error) {
 		up_write(&s->s_umount);
@@ -1874,7 +2009,15 @@ static struct inode *nfs_alloc_inode(str
 	nfsi = (struct nfs_inode *)kmem_cache_alloc(nfs_inode_cachep, SLAB_KERNEL);
 	if (!nfsi)
 		return NULL;
-	nfsi->flags = 0;
+	nfsi->flags = 0UL;
+	nfsi->cache_validity = 0UL;
+#ifdef CONFIG_NFS_V3_ACL
+	nfsi->acl_access = ERR_PTR(-EAGAIN);
+	nfsi->acl_default = ERR_PTR(-EAGAIN);
+#endif
+#ifdef CONFIG_NFS_V4
+	nfsi->nfs4_acl = NULL;
+#endif /* CONFIG_NFS_V4 */
 	return &nfsi->vfs_inode;
 }
 
@@ -1899,7 +2042,6 @@ static void init_once(void * foo, kmem_c
 		nfsi->ndirty = 0;
 		nfsi->ncommit = 0;
 		nfsi->npages = 0;
-		init_waitqueue_head(&nfsi->nfs_i_wait);
 		nfs4_init_once(nfsi);
 	}
 }
diff --git a/fs/nfs/mount_clnt.c b/fs/nfs/mount_clnt.c
--- a/fs/nfs/mount_clnt.c
+++ b/fs/nfs/mount_clnt.c
@@ -80,9 +80,7 @@ mnt_create(char *hostname, struct sockad
 	clnt = rpc_create_client(xprt, hostname,
 				&mnt_program, version,
 				RPC_AUTH_UNIX);
-	if (IS_ERR(clnt)) {
-		xprt_destroy(xprt);
-	} else {
+	if (!IS_ERR(clnt)) {
 		clnt->cl_softrtry = 1;
 		clnt->cl_chatty   = 1;
 		clnt->cl_oneshot  = 1;
diff --git a/fs/nfs/nfs3acl.c b/fs/nfs/nfs3acl.c
new file mode 100644
--- /dev/null
+++ b/fs/nfs/nfs3acl.c
@@ -0,0 +1,405 @@
+#include <linux/fs.h>
+#include <linux/nfs.h>
+#include <linux/nfs3.h>
+#include <linux/nfs_fs.h>
+#include <linux/posix_acl_xattr.h>
+#include <linux/nfsacl.h>
+
+#define NFSDBG_FACILITY	NFSDBG_PROC
+
+ssize_t nfs3_listxattr(struct dentry *dentry, char *buffer, size_t size)
+{
+	struct inode *inode = dentry->d_inode;
+	struct posix_acl *acl;
+	int pos=0, len=0;
+
+#	define output(s) do {						\
+			if (pos + sizeof(s) <= size) {			\
+				memcpy(buffer + pos, s, sizeof(s));	\
+				pos += sizeof(s);			\
+			}						\
+			len += sizeof(s);				\
+		} while(0)
+
+	acl = nfs3_proc_getacl(inode, ACL_TYPE_ACCESS);
+	if (IS_ERR(acl))
+		return PTR_ERR(acl);
+	if (acl) {
+		output("system.posix_acl_access");
+		posix_acl_release(acl);
+	}
+
+	if (S_ISDIR(inode->i_mode)) {
+		acl = nfs3_proc_getacl(inode, ACL_TYPE_DEFAULT);
+		if (IS_ERR(acl))
+			return PTR_ERR(acl);
+		if (acl) {
+			output("system.posix_acl_default");
+			posix_acl_release(acl);
+		}
+	}
+
+#	undef output
+
+	if (!buffer || len <= size)
+		return len;
+	return -ERANGE;
+}
+
+ssize_t nfs3_getxattr(struct dentry *dentry, const char *name,
+		void *buffer, size_t size)
+{
+	struct inode *inode = dentry->d_inode;
+	struct posix_acl *acl;
+	int type, error = 0;
+
+	if (strcmp(name, POSIX_ACL_XATTR_ACCESS) == 0)
+		type = ACL_TYPE_ACCESS;
+	else if (strcmp(name, POSIX_ACL_XATTR_DEFAULT) == 0)
+		type = ACL_TYPE_DEFAULT;
+	else
+		return -EOPNOTSUPP;
+
+	acl = nfs3_proc_getacl(inode, type);
+	if (IS_ERR(acl))
+		return PTR_ERR(acl);
+	else if (acl) {
+		if (type == ACL_TYPE_ACCESS && acl->a_count == 0)
+			error = -ENODATA;
+		else
+			error = posix_acl_to_xattr(acl, buffer, size);
+		posix_acl_release(acl);
+	} else
+		error = -ENODATA;
+
+	return error;
+}
+
+int nfs3_setxattr(struct dentry *dentry, const char *name,
+	     const void *value, size_t size, int flags)
+{
+	struct inode *inode = dentry->d_inode;
+	struct posix_acl *acl;
+	int type, error;
+
+	if (strcmp(name, POSIX_ACL_XATTR_ACCESS) == 0)
+		type = ACL_TYPE_ACCESS;
+	else if (strcmp(name, POSIX_ACL_XATTR_DEFAULT) == 0)
+		type = ACL_TYPE_DEFAULT;
+	else
+		return -EOPNOTSUPP;
+
+	acl = posix_acl_from_xattr(value, size);
+	if (IS_ERR(acl))
+		return PTR_ERR(acl);
+	error = nfs3_proc_setacl(inode, type, acl);
+	posix_acl_release(acl);
+
+	return error;
+}
+
+int nfs3_removexattr(struct dentry *dentry, const char *name)
+{
+	struct inode *inode = dentry->d_inode;
+	int type;
+
+	if (strcmp(name, POSIX_ACL_XATTR_ACCESS) == 0)
+		type = ACL_TYPE_ACCESS;
+	else if (strcmp(name, POSIX_ACL_XATTR_DEFAULT) == 0)
+		type = ACL_TYPE_DEFAULT;
+	else
+		return -EOPNOTSUPP;
+
+	return nfs3_proc_setacl(inode, type, NULL);
+}
+
+static void __nfs3_forget_cached_acls(struct nfs_inode *nfsi)
+{
+	if (!IS_ERR(nfsi->acl_access)) {
+		posix_acl_release(nfsi->acl_access);
+		nfsi->acl_access = ERR_PTR(-EAGAIN);
+	}
+	if (!IS_ERR(nfsi->acl_default)) {
+		posix_acl_release(nfsi->acl_default);
+		nfsi->acl_default = ERR_PTR(-EAGAIN);
+	}
+}
+
+void nfs3_forget_cached_acls(struct inode *inode)
+{
+	dprintk("NFS: nfs3_forget_cached_acls(%s/%ld)\n", inode->i_sb->s_id,
+		inode->i_ino);
+	spin_lock(&inode->i_lock);
+	__nfs3_forget_cached_acls(NFS_I(inode));
+	spin_unlock(&inode->i_lock);
+}
+
+static struct posix_acl *nfs3_get_cached_acl(struct inode *inode, int type)
+{
+	struct nfs_inode *nfsi = NFS_I(inode);
+	struct posix_acl *acl = ERR_PTR(-EINVAL);
+
+	spin_lock(&inode->i_lock);
+	switch(type) {
+		case ACL_TYPE_ACCESS:
+			acl = nfsi->acl_access;
+			break;
+
+		case ACL_TYPE_DEFAULT:
+			acl = nfsi->acl_default;
+			break;
+
+		default:
+			goto out;
+	}
+	if (IS_ERR(acl))
+		acl = ERR_PTR(-EAGAIN);
+	else
+		acl = posix_acl_dup(acl);
+out:
+	spin_unlock(&inode->i_lock);
+	dprintk("NFS: nfs3_get_cached_acl(%s/%ld, %d) = %p\n", inode->i_sb->s_id,
+		inode->i_ino, type, acl);
+	return acl;
+}
+
+static void nfs3_cache_acls(struct inode *inode, struct posix_acl *acl,
+		    struct posix_acl *dfacl)
+{
+	struct nfs_inode *nfsi = NFS_I(inode);
+
+	dprintk("nfs3_cache_acls(%s/%ld, %p, %p)\n", inode->i_sb->s_id,
+		inode->i_ino, acl, dfacl);
+	spin_lock(&inode->i_lock);
+	__nfs3_forget_cached_acls(NFS_I(inode));
+	nfsi->acl_access = posix_acl_dup(acl);
+	nfsi->acl_default = posix_acl_dup(dfacl);
+	spin_unlock(&inode->i_lock);
+}
+
+struct posix_acl *nfs3_proc_getacl(struct inode *inode, int type)
+{
+	struct nfs_server *server = NFS_SERVER(inode);
+	struct nfs_fattr fattr;
+	struct page *pages[NFSACL_MAXPAGES] = { };
+	struct nfs3_getaclargs args = {
+		.fh = NFS_FH(inode),
+		/* The xdr layer may allocate pages here. */
+		.pages = pages,
+	};
+	struct nfs3_getaclres res = {
+		.fattr =	&fattr,
+	};
+	struct posix_acl *acl;
+	int status, count;
+
+	if (!nfs_server_capable(inode, NFS_CAP_ACLS))
+		return ERR_PTR(-EOPNOTSUPP);
+
+	status = nfs_revalidate_inode(server, inode);
+	if (status < 0)
+		return ERR_PTR(status);
+	acl = nfs3_get_cached_acl(inode, type);
+	if (acl != ERR_PTR(-EAGAIN))
+		return acl;
+	acl = NULL;
+
+	/*
+	 * Only get the access acl when explicitly requested: We don't
+	 * need it for access decisions, and only some applications use
+	 * it. Applications which request the access acl first are not
+	 * penalized from this optimization.
+	 */
+	if (type == ACL_TYPE_ACCESS)
+		args.mask |= NFS_ACLCNT|NFS_ACL;
+	if (S_ISDIR(inode->i_mode))
+		args.mask |= NFS_DFACLCNT|NFS_DFACL;
+	if (args.mask == 0)
+		return NULL;
+
+	dprintk("NFS call getacl\n");
+	status = rpc_call(server->client_acl, ACLPROC3_GETACL,
+			  &args, &res, 0);
+	dprintk("NFS reply getacl: %d\n", status);
+
+	/* pages may have been allocated at the xdr layer. */
+	for (count = 0; count < NFSACL_MAXPAGES && args.pages[count]; count++)
+		__free_page(args.pages[count]);
+
+	switch (status) {
+		case 0:
+			status = nfs_refresh_inode(inode, &fattr);
+			break;
+		case -EPFNOSUPPORT:
+		case -EPROTONOSUPPORT:
+			dprintk("NFS_V3_ACL extension not supported; disabling\n");
+			server->caps &= ~NFS_CAP_ACLS;
+		case -ENOTSUPP:
+			status = -EOPNOTSUPP;
+		default:
+			goto getout;
+	}
+	if ((args.mask & res.mask) != args.mask) {
+		status = -EIO;
+		goto getout;
+	}
+
+	if (res.acl_access != NULL) {
+		if (posix_acl_equiv_mode(res.acl_access, NULL) == 0) {
+			posix_acl_release(res.acl_access);
+			res.acl_access = NULL;
+		}
+	}
+	nfs3_cache_acls(inode, res.acl_access, res.acl_default);
+
+	switch(type) {
+		case ACL_TYPE_ACCESS:
+			acl = res.acl_access;
+			res.acl_access = NULL;
+			break;
+
+		case ACL_TYPE_DEFAULT:
+			acl = res.acl_default;
+			res.acl_default = NULL;
+	}
+
+getout:
+	posix_acl_release(res.acl_access);
+	posix_acl_release(res.acl_default);
+
+	if (status != 0) {
+		posix_acl_release(acl);
+		acl = ERR_PTR(status);
+	}
+	return acl;
+}
+
+static int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl,
+		  struct posix_acl *dfacl)
+{
+	struct nfs_server *server = NFS_SERVER(inode);
+	struct nfs_fattr fattr;
+	struct page *pages[NFSACL_MAXPAGES] = { };
+	struct nfs3_setaclargs args = {
+		.inode = inode,
+		.mask = NFS_ACL,
+		.acl_access = acl,
+		.pages = pages,
+	};
+	int status, count;
+
+	status = -EOPNOTSUPP;
+	if (!nfs_server_capable(inode, NFS_CAP_ACLS))
+		goto out;
+
+	/* We are doing this here, because XDR marshalling can only
+	   return -ENOMEM. */
+	status = -ENOSPC;
+	if (acl != NULL && acl->a_count > NFS_ACL_MAX_ENTRIES)
+		goto out;
+	if (dfacl != NULL && dfacl->a_count > NFS_ACL_MAX_ENTRIES)
+		goto out;
+	if (S_ISDIR(inode->i_mode)) {
+		args.mask |= NFS_DFACL;
+		args.acl_default = dfacl;
+	}
+
+	dprintk("NFS call setacl\n");
+	nfs_begin_data_update(inode);
+	status = rpc_call(server->client_acl, ACLPROC3_SETACL,
+			  &args, &fattr, 0);
+	spin_lock(&inode->i_lock);
+	NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ACCESS;
+	spin_unlock(&inode->i_lock);
+	nfs_end_data_update(inode);
+	dprintk("NFS reply setacl: %d\n", status);
+
+	/* pages may have been allocated at the xdr layer. */
+	for (count = 0; count < NFSACL_MAXPAGES && args.pages[count]; count++)
+		__free_page(args.pages[count]);
+
+	switch (status) {
+		case 0:
+			status = nfs_refresh_inode(inode, &fattr);
+			break;
+		case -EPFNOSUPPORT:
+		case -EPROTONOSUPPORT:
+			dprintk("NFS_V3_ACL SETACL RPC not supported"
+					"(will not retry)\n");
+			server->caps &= ~NFS_CAP_ACLS;
+		case -ENOTSUPP:
+			status = -EOPNOTSUPP;
+	}
+out:
+	return status;
+}
+
+int nfs3_proc_setacl(struct inode *inode, int type, struct posix_acl *acl)
+{
+	struct posix_acl *alloc = NULL, *dfacl = NULL;
+	int status;
+
+	if (S_ISDIR(inode->i_mode)) {
+		switch(type) {
+			case ACL_TYPE_ACCESS:
+				alloc = dfacl = nfs3_proc_getacl(inode,
+						ACL_TYPE_DEFAULT);
+				if (IS_ERR(alloc))
+					goto fail;
+				break;
+
+			case ACL_TYPE_DEFAULT:
+				dfacl = acl;
+				alloc = acl = nfs3_proc_getacl(inode,
+						ACL_TYPE_ACCESS);
+				if (IS_ERR(alloc))
+					goto fail;
+				break;
+
+			default:
+				return -EINVAL;
+		}
+	} else if (type != ACL_TYPE_ACCESS)
+			return -EINVAL;
+
+	if (acl == NULL) {
+		alloc = acl = posix_acl_from_mode(inode->i_mode, GFP_KERNEL);
+		if (IS_ERR(alloc))
+			goto fail;
+	}
+	status = nfs3_proc_setacls(inode, acl, dfacl);
+	posix_acl_release(alloc);
+	return status;
+
+fail:
+	return PTR_ERR(alloc);
+}
+
+int nfs3_proc_set_default_acl(struct inode *dir, struct inode *inode,
+		mode_t mode)
+{
+	struct posix_acl *dfacl, *acl;
+	int error = 0;
+
+	dfacl = nfs3_proc_getacl(dir, ACL_TYPE_DEFAULT);
+	if (IS_ERR(dfacl)) {
+		error = PTR_ERR(dfacl);
+		return (error == -EOPNOTSUPP) ? 0 : error;
+	}
+	if (!dfacl)
+		return 0;
+	acl = posix_acl_clone(dfacl, GFP_KERNEL);
+	error = -ENOMEM;
+	if (!acl)
+		goto out_release_dfacl;
+	error = posix_acl_create_masq(acl, &mode);
+	if (error < 0)
+		goto out_release_acl;
+	error = nfs3_proc_setacls(inode, acl, S_ISDIR(inode->i_mode) ?
+						      dfacl : NULL);
+out_release_acl:
+	posix_acl_release(acl);
+out_release_dfacl:
+	posix_acl_release(dfacl);
+	return error;
+}
diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c
--- a/fs/nfs/nfs3proc.c
+++ b/fs/nfs/nfs3proc.c
@@ -17,6 +17,7 @@
 #include <linux/nfs_page.h>
 #include <linux/lockd/bind.h>
 #include <linux/smp_lock.h>
+#include <linux/nfs_mount.h>
 
 #define NFSDBG_FACILITY		NFSDBG_PROC
 
@@ -45,7 +46,7 @@ static inline int
 nfs3_rpc_call_wrapper(struct rpc_clnt *clnt, u32 proc, void *argp, void *resp, int flags)
 {
 	struct rpc_message msg = {
-		.rpc_proc	= &nfs3_procedures[proc],
+		.rpc_proc	= &clnt->cl_procinfo[proc],
 		.rpc_argp	= argp,
 		.rpc_resp	= resp,
 	};
@@ -119,6 +120,8 @@ nfs3_proc_setattr(struct dentry *dentry,
 	dprintk("NFS call  setattr\n");
 	fattr->valid = 0;
 	status = rpc_call(NFS_CLIENT(inode), NFS3PROC_SETATTR, &arg, fattr, 0);
+	if (status == 0)
+		nfs_setattr_update_inode(inode, sattr);
 	dprintk("NFS reply setattr: %d\n", status);
 	return status;
 }
@@ -313,7 +316,8 @@ nfs3_proc_create(struct inode *dir, stru
 		.fh		= &fhandle,
 		.fattr		= &fattr
 	};
-	int			status;
+	mode_t mode = sattr->ia_mode;
+	int status;
 
 	dprintk("NFS call  create %s\n", dentry->d_name.name);
 	arg.createmode = NFS3_CREATE_UNCHECKED;
@@ -323,6 +327,8 @@ nfs3_proc_create(struct inode *dir, stru
 		arg.verifier[1] = current->pid;
 	}
 
+	sattr->ia_mode &= ~current->fs->umask;
+
 again:
 	dir_attr.valid = 0;
 	fattr.valid = 0;
@@ -366,9 +372,14 @@ again:
 		 * not sure this buys us anything (and I'd have
 		 * to revamp the NFSv3 XDR code) */
 		status = nfs3_proc_setattr(dentry, &fattr, sattr);
+		if (status == 0)
+			nfs_setattr_update_inode(dentry->d_inode, sattr);
 		nfs_refresh_inode(dentry->d_inode, &fattr);
 		dprintk("NFS reply setattr (post-create): %d\n", status);
 	}
+	if (status != 0)
+		goto out;
+	status = nfs3_proc_set_default_acl(dir, dentry->d_inode, mode);
 out:
 	dprintk("NFS reply create: %d\n", status);
 	return status;
@@ -538,15 +549,24 @@ nfs3_proc_mkdir(struct inode *dir, struc
 		.fh		= &fhandle,
 		.fattr		= &fattr
 	};
-	int			status;
+	int mode = sattr->ia_mode;
+	int status;
 
 	dprintk("NFS call  mkdir %s\n", dentry->d_name.name);
 	dir_attr.valid = 0;
 	fattr.valid = 0;
+
+	sattr->ia_mode &= ~current->fs->umask;
+
 	status = rpc_call(NFS_CLIENT(dir), NFS3PROC_MKDIR, &arg, &res, 0);
 	nfs_refresh_inode(dir, &dir_attr);
-	if (status == 0)
-		status = nfs_instantiate(dentry, &fhandle, &fattr);
+	if (status != 0)
+		goto out;
+	status = nfs_instantiate(dentry, &fhandle, &fattr);
+	if (status != 0)
+		goto out;
+	status = nfs3_proc_set_default_acl(dir, dentry->d_inode, mode);
+out:
 	dprintk("NFS reply mkdir: %d\n", status);
 	return status;
 }
@@ -641,6 +661,7 @@ nfs3_proc_mknod(struct inode *dir, struc
 		.fh		= &fh,
 		.fattr		= &fattr
 	};
+	mode_t mode = sattr->ia_mode;
 	int status;
 
 	switch (sattr->ia_mode & S_IFMT) {
@@ -653,12 +674,20 @@ nfs3_proc_mknod(struct inode *dir, struc
 
 	dprintk("NFS call  mknod %s %u:%u\n", dentry->d_name.name,
 			MAJOR(rdev), MINOR(rdev));
+
+	sattr->ia_mode &= ~current->fs->umask;
+
 	dir_attr.valid = 0;
 	fattr.valid = 0;
 	status = rpc_call(NFS_CLIENT(dir), NFS3PROC_MKNOD, &arg, &res, 0);
 	nfs_refresh_inode(dir, &dir_attr);
-	if (status == 0)
-		status = nfs_instantiate(dentry, &fh, &fattr);
+	if (status != 0)
+		goto out;
+	status = nfs_instantiate(dentry, &fh, &fattr);
+	if (status != 0)
+		goto out;
+	status = nfs3_proc_set_default_acl(dir, dentry->d_inode, mode);
+out:
 	dprintk("NFS reply mknod: %d\n", status);
 	return status;
 }
@@ -825,7 +854,8 @@ nfs3_proc_lock(struct file *filp, int cm
 struct nfs_rpc_ops	nfs_v3_clientops = {
 	.version	= 3,			/* protocol version */
 	.dentry_ops	= &nfs_dentry_operations,
-	.dir_inode_ops	= &nfs_dir_inode_operations,
+	.dir_inode_ops	= &nfs3_dir_inode_operations,
+	.file_inode_ops	= &nfs3_file_inode_operations,
 	.getroot	= nfs3_proc_get_root,
 	.getattr	= nfs3_proc_getattr,
 	.setattr	= nfs3_proc_setattr,
@@ -856,4 +886,5 @@ struct nfs_rpc_ops	nfs_v3_clientops = {
 	.file_open	= nfs_open,
 	.file_release	= nfs_release,
 	.lock		= nfs3_proc_lock,
+	.clear_acl_cache = nfs3_forget_cached_acls,
 };
diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c
--- a/fs/nfs/nfs3xdr.c
+++ b/fs/nfs/nfs3xdr.c
@@ -21,6 +21,7 @@
 #include <linux/nfs.h>
 #include <linux/nfs3.h>
 #include <linux/nfs_fs.h>
+#include <linux/nfsacl.h>
 
 #define NFSDBG_FACILITY		NFSDBG_XDR
 
@@ -79,6 +80,11 @@ extern int			nfs_stat_to_errno(int);
 #define NFS3_pathconfres_sz	(1+NFS3_post_op_attr_sz+6)
 #define NFS3_commitres_sz	(1+NFS3_wcc_data_sz+2)
 
+#define ACL3_getaclargs_sz	(NFS3_fh_sz+1)
+#define ACL3_setaclargs_sz	(NFS3_fh_sz+1+2*(2+5*3))
+#define ACL3_getaclres_sz	(1+NFS3_post_op_attr_sz+1+2*(2+5*3))
+#define ACL3_setaclres_sz	(1+NFS3_post_op_attr_sz)
+
 /*
  * Map file type to S_IFMT bits
  */
@@ -627,6 +633,74 @@ nfs3_xdr_commitargs(struct rpc_rqst *req
 	return 0;
 }
 
+#ifdef CONFIG_NFS_V3_ACL
+/*
+ * Encode GETACL arguments
+ */
+static int
+nfs3_xdr_getaclargs(struct rpc_rqst *req, u32 *p,
+		    struct nfs3_getaclargs *args)
+{
+	struct rpc_auth *auth = req->rq_task->tk_auth;
+	unsigned int replen;
+
+	p = xdr_encode_fhandle(p, args->fh);
+	*p++ = htonl(args->mask);
+	req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
+
+	if (args->mask & (NFS_ACL | NFS_DFACL)) {
+		/* Inline the page array */
+		replen = (RPC_REPHDRSIZE + auth->au_rslack +
+			  ACL3_getaclres_sz) << 2;
+		xdr_inline_pages(&req->rq_rcv_buf, replen, args->pages, 0,
+				 NFSACL_MAXPAGES << PAGE_SHIFT);
+	}
+	return 0;
+}
+
+/*
+ * Encode SETACL arguments
+ */
+static int
+nfs3_xdr_setaclargs(struct rpc_rqst *req, u32 *p,
+                   struct nfs3_setaclargs *args)
+{
+	struct xdr_buf *buf = &req->rq_snd_buf;
+	unsigned int base, len_in_head, len = nfsacl_size(
+		(args->mask & NFS_ACL)   ? args->acl_access  : NULL,
+		(args->mask & NFS_DFACL) ? args->acl_default : NULL);
+	int count, err;
+
+	p = xdr_encode_fhandle(p, NFS_FH(args->inode));
+	*p++ = htonl(args->mask);
+	base = (char *)p - (char *)buf->head->iov_base;
+	/* put as much of the acls into head as possible. */
+	len_in_head = min_t(unsigned int, buf->head->iov_len - base, len);
+	len -= len_in_head;
+	req->rq_slen = xdr_adjust_iovec(req->rq_svec, p + (len_in_head >> 2));
+
+	for (count = 0; (count << PAGE_SHIFT) < len; count++) {
+		args->pages[count] = alloc_page(GFP_KERNEL);
+		if (!args->pages[count]) {
+			while (count)
+				__free_page(args->pages[--count]);
+			return -ENOMEM;
+		}
+	}
+	xdr_encode_pages(buf, args->pages, 0, len);
+
+	err = nfsacl_encode(buf, base, args->inode,
+			    (args->mask & NFS_ACL) ?
+			    args->acl_access : NULL, 1, 0);
+	if (err > 0)
+		err = nfsacl_encode(buf, base + err, args->inode,
+				    (args->mask & NFS_DFACL) ?
+				    args->acl_default : NULL, 1,
+				    NFS_ACL_DEFAULT);
+	return (err > 0) ? 0 : err;
+}
+#endif  /* CONFIG_NFS_V3_ACL */
+
 /*
  * NFS XDR decode functions
  */
@@ -978,6 +1052,54 @@ nfs3_xdr_commitres(struct rpc_rqst *req,
 	return 0;
 }
 
+#ifdef CONFIG_NFS_V3_ACL
+/*
+ * Decode GETACL reply
+ */
+static int
+nfs3_xdr_getaclres(struct rpc_rqst *req, u32 *p,
+		   struct nfs3_getaclres *res)
+{
+	struct xdr_buf *buf = &req->rq_rcv_buf;
+	int status = ntohl(*p++);
+	struct posix_acl **acl;
+	unsigned int *aclcnt;
+	int err, base;
+
+	if (status != 0)
+		return -nfs_stat_to_errno(status);
+	p = xdr_decode_post_op_attr(p, res->fattr);
+	res->mask = ntohl(*p++);
+	if (res->mask & ~(NFS_ACL|NFS_ACLCNT|NFS_DFACL|NFS_DFACLCNT))
+		return -EINVAL;
+	base = (char *)p - (char *)req->rq_rcv_buf.head->iov_base;
+
+	acl = (res->mask & NFS_ACL) ? &res->acl_access : NULL;
+	aclcnt = (res->mask & NFS_ACLCNT) ? &res->acl_access_count : NULL;
+	err = nfsacl_decode(buf, base, aclcnt, acl);
+
+	acl = (res->mask & NFS_DFACL) ? &res->acl_default : NULL;
+	aclcnt = (res->mask & NFS_DFACLCNT) ? &res->acl_default_count : NULL;
+	if (err > 0)
+		err = nfsacl_decode(buf, base + err, aclcnt, acl);
+	return (err > 0) ? 0 : err;
+}
+
+/*
+ * Decode setacl reply.
+ */
+static int
+nfs3_xdr_setaclres(struct rpc_rqst *req, u32 *p, struct nfs_fattr *fattr)
+{
+	int status = ntohl(*p++);
+
+	if (status)
+		return -nfs_stat_to_errno(status);
+	xdr_decode_post_op_attr(p, fattr);
+	return 0;
+}
+#endif  /* CONFIG_NFS_V3_ACL */
+
 #ifndef MAX
 # define MAX(a, b)	(((a) > (b))? (a) : (b))
 #endif
@@ -1021,3 +1143,28 @@ struct rpc_version		nfs_version3 = {
 	.procs			= nfs3_procedures
 };
 
+#ifdef CONFIG_NFS_V3_ACL
+static struct rpc_procinfo	nfs3_acl_procedures[] = {
+	[ACLPROC3_GETACL] = {
+		.p_proc = ACLPROC3_GETACL,
+		.p_encode = (kxdrproc_t) nfs3_xdr_getaclargs,
+		.p_decode = (kxdrproc_t) nfs3_xdr_getaclres,
+		.p_bufsiz = MAX(ACL3_getaclargs_sz, ACL3_getaclres_sz) << 2,
+		.p_timer = 1,
+	},
+	[ACLPROC3_SETACL] = {
+		.p_proc = ACLPROC3_SETACL,
+		.p_encode = (kxdrproc_t) nfs3_xdr_setaclargs,
+		.p_decode = (kxdrproc_t) nfs3_xdr_setaclres,
+		.p_bufsiz = MAX(ACL3_setaclargs_sz, ACL3_setaclres_sz) << 2,
+		.p_timer = 0,
+	},
+};
+
+struct rpc_version		nfsacl_version3 = {
+	.number			= 3,
+	.nrprocs		= sizeof(nfs3_acl_procedures)/
+				  sizeof(nfs3_acl_procedures[0]),
+	.procs			= nfs3_acl_procedures,
+};
+#endif  /* CONFIG_NFS_V3_ACL */
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
new file mode 100644
--- /dev/null
+++ b/fs/nfs/nfs4_fs.h
@@ -0,0 +1,253 @@
+/*
+ * linux/fs/nfs/nfs4_fs.h
+ *
+ * Copyright (C) 2005 Trond Myklebust
+ *
+ * NFSv4-specific filesystem definitions and declarations
+ */
+
+#ifndef __LINUX_FS_NFS_NFS4_FS_H
+#define __LINUX_FS_NFS_NFS4_FS_H
+
+#ifdef CONFIG_NFS_V4
+
+struct idmap;
+
+/*
+ * In a seqid-mutating op, this macro controls which error return
+ * values trigger incrementation of the seqid.
+ *
+ * from rfc 3010:
+ * The client MUST monotonically increment the sequence number for the
+ * CLOSE, LOCK, LOCKU, OPEN, OPEN_CONFIRM, and OPEN_DOWNGRADE
+ * operations.  This is true even in the event that the previous
+ * operation that used the sequence number received an error.  The only
+ * exception to this rule is if the previous operation received one of
+ * the following errors: NFSERR_STALE_CLIENTID, NFSERR_STALE_STATEID,
+ * NFSERR_BAD_STATEID, NFSERR_BAD_SEQID, NFSERR_BADXDR,
+ * NFSERR_RESOURCE, NFSERR_NOFILEHANDLE.
+ *
+ */
+#define seqid_mutating_err(err)       \
+(((err) != NFSERR_STALE_CLIENTID) &&  \
+ ((err) != NFSERR_STALE_STATEID)  &&  \
+ ((err) != NFSERR_BAD_STATEID)    &&  \
+ ((err) != NFSERR_BAD_SEQID)      &&  \
+ ((err) != NFSERR_BAD_XDR)        &&  \
+ ((err) != NFSERR_RESOURCE)       &&  \
+ ((err) != NFSERR_NOFILEHANDLE))
+
+enum nfs4_client_state {
+	NFS4CLNT_OK  = 0,
+};
+
+/*
+ * The nfs4_client identifies our client state to the server.
+ */
+struct nfs4_client {
+	struct list_head	cl_servers;	/* Global list of servers */
+	struct in_addr		cl_addr;	/* Server identifier */
+	u64			cl_clientid;	/* constant */
+	nfs4_verifier		cl_confirm;
+	unsigned long		cl_state;
+
+	u32			cl_lockowner_id;
+
+	/*
+	 * The following rwsem ensures exclusive access to the server
+	 * while we recover the state following a lease expiration.
+	 */
+	struct rw_semaphore	cl_sem;
+
+	struct list_head	cl_delegations;
+	struct list_head	cl_state_owners;
+	struct list_head	cl_unused;
+	int			cl_nunused;
+	spinlock_t		cl_lock;
+	atomic_t		cl_count;
+
+	struct rpc_clnt *	cl_rpcclient;
+	struct rpc_cred *	cl_cred;
+
+	struct list_head	cl_superblocks;	/* List of nfs_server structs */
+
+	unsigned long		cl_lease_time;
+	unsigned long		cl_last_renewal;
+	struct work_struct	cl_renewd;
+	struct work_struct	cl_recoverd;
+
+	wait_queue_head_t	cl_waitq;
+	struct rpc_wait_queue	cl_rpcwaitq;
+
+	/* used for the setclientid verifier */
+	struct timespec		cl_boot_time;
+
+	/* idmapper */
+	struct idmap *		cl_idmap;
+
+	/* Our own IP address, as a null-terminated string.
+	 * This is used to generate the clientid, and the callback address.
+	 */
+	char			cl_ipaddr[16];
+	unsigned char		cl_id_uniquifier;
+};
+
+/*
+ * NFS4 state_owners and lock_owners are simply labels for ordered
+ * sequences of RPC calls. Their sole purpose is to provide once-only
+ * semantics by allowing the server to identify replayed requests.
+ *
+ * The ->so_sema is held during all state_owner seqid-mutating operations:
+ * OPEN, OPEN_DOWNGRADE, and CLOSE. Its purpose is to properly serialize
+ * so_seqid.
+ */
+struct nfs4_state_owner {
+	struct list_head     so_list;	 /* per-clientid list of state_owners */
+	struct nfs4_client   *so_client;
+	u32                  so_id;      /* 32-bit identifier, unique */
+	struct semaphore     so_sema;
+	u32                  so_seqid;   /* protected by so_sema */
+	atomic_t	     so_count;
+
+	struct rpc_cred	     *so_cred;	 /* Associated cred */
+	struct list_head     so_states;
+	struct list_head     so_delegations;
+};
+
+/*
+ * struct nfs4_state maintains the client-side state for a given
+ * (state_owner,inode) tuple (OPEN) or state_owner (LOCK).
+ *
+ * OPEN:
+ * In order to know when to OPEN_DOWNGRADE or CLOSE the state on the server,
+ * we need to know how many files are open for reading or writing on a
+ * given inode. This information too is stored here.
+ *
+ * LOCK: one nfs4_state (LOCK) to hold the lock stateid nfs4_state(OPEN)
+ */
+
+struct nfs4_lock_state {
+	struct list_head	ls_locks;	/* Other lock stateids */
+	struct nfs4_state *	ls_state;	/* Pointer to open state */
+	fl_owner_t		ls_owner;	/* POSIX lock owner */
+#define NFS_LOCK_INITIALIZED 1
+	int			ls_flags;
+	u32			ls_seqid;
+	u32			ls_id;
+	nfs4_stateid		ls_stateid;
+	atomic_t		ls_count;
+};
+
+/* bits for nfs4_state->flags */
+enum {
+	LK_STATE_IN_USE,
+	NFS_DELEGATED_STATE,
+};
+
+struct nfs4_state {
+	struct list_head open_states;	/* List of states for the same state_owner */
+	struct list_head inode_states;	/* List of states for the same inode */
+	struct list_head lock_states;	/* List of subservient lock stateids */
+
+	struct nfs4_state_owner *owner;	/* Pointer to the open owner */
+	struct inode *inode;		/* Pointer to the inode */
+
+	unsigned long flags;		/* Do we hold any locks? */
+	struct semaphore lock_sema;	/* Serializes file locking operations */
+	spinlock_t state_lock;		/* Protects the lock_states list */
+
+	nfs4_stateid stateid;
+
+	unsigned int nreaders;
+	unsigned int nwriters;
+	int state;			/* State on the server (R,W, or RW) */
+	atomic_t count;
+};
+
+
+struct nfs4_exception {
+	long timeout;
+	int retry;
+};
+
+struct nfs4_state_recovery_ops {
+	int (*recover_open)(struct nfs4_state_owner *, struct nfs4_state *);
+	int (*recover_lock)(struct nfs4_state *, struct file_lock *);
+};
+
+extern struct dentry_operations nfs4_dentry_operations;
+extern struct inode_operations nfs4_dir_inode_operations;
+
+/* inode.c */
+extern ssize_t nfs4_getxattr(struct dentry *, const char *, void *, size_t);
+extern int nfs4_setxattr(struct dentry *, const char *, const void *, size_t, int);
+extern ssize_t nfs4_listxattr(struct dentry *, char *, size_t);
+
+
+/* nfs4proc.c */
+extern int nfs4_map_errors(int err);
+extern int nfs4_proc_setclientid(struct nfs4_client *, u32, unsigned short);
+extern int nfs4_proc_setclientid_confirm(struct nfs4_client *);
+extern int nfs4_proc_async_renew(struct nfs4_client *);
+extern int nfs4_proc_renew(struct nfs4_client *);
+extern int nfs4_do_close(struct inode *inode, struct nfs4_state *state, mode_t mode);
+extern struct inode *nfs4_atomic_open(struct inode *, struct dentry *, struct nameidata *);
+extern int nfs4_open_revalidate(struct inode *, struct dentry *, int);
+
+extern struct nfs4_state_recovery_ops nfs4_reboot_recovery_ops;
+extern struct nfs4_state_recovery_ops nfs4_network_partition_recovery_ops;
+
+extern const u32 nfs4_fattr_bitmap[2];
+extern const u32 nfs4_statfs_bitmap[2];
+extern const u32 nfs4_pathconf_bitmap[2];
+extern const u32 nfs4_fsinfo_bitmap[2];
+
+/* nfs4renewd.c */
+extern void nfs4_schedule_state_renewal(struct nfs4_client *);
+extern void nfs4_renewd_prepare_shutdown(struct nfs_server *);
+extern void nfs4_kill_renewd(struct nfs4_client *);
+extern void nfs4_renew_state(void *);
+
+/* nfs4state.c */
+extern void init_nfsv4_state(struct nfs_server *);
+extern void destroy_nfsv4_state(struct nfs_server *);
+extern struct nfs4_client *nfs4_get_client(struct in_addr *);
+extern void nfs4_put_client(struct nfs4_client *clp);
+extern int nfs4_init_client(struct nfs4_client *clp);
+extern struct nfs4_client *nfs4_find_client(struct in_addr *);
+extern u32 nfs4_alloc_lockowner_id(struct nfs4_client *);
+
+extern struct nfs4_state_owner * nfs4_get_state_owner(struct nfs_server *, struct rpc_cred *);
+extern void nfs4_put_state_owner(struct nfs4_state_owner *);
+extern void nfs4_drop_state_owner(struct nfs4_state_owner *);
+extern struct nfs4_state * nfs4_get_open_state(struct inode *, struct nfs4_state_owner *);
+extern void nfs4_put_open_state(struct nfs4_state *);
+extern void nfs4_close_state(struct nfs4_state *, mode_t);
+extern struct nfs4_state *nfs4_find_state(struct inode *, struct rpc_cred *, mode_t mode);
+extern void nfs4_increment_seqid(int status, struct nfs4_state_owner *sp);
+extern void nfs4_schedule_state_recovery(struct nfs4_client *);
+extern int nfs4_set_lock_state(struct nfs4_state *state, struct file_lock *fl);
+extern void nfs4_increment_lock_seqid(int status, struct nfs4_lock_state *ls);
+extern void nfs4_copy_stateid(nfs4_stateid *, struct nfs4_state *, fl_owner_t);
+
+extern const nfs4_stateid zero_stateid;
+
+/* nfs4xdr.c */
+extern uint32_t *nfs4_decode_dirent(uint32_t *p, struct nfs_entry *entry, int plus);
+extern struct rpc_procinfo nfs4_procedures[];
+
+struct nfs4_mount_data;
+
+/* callback_xdr.c */
+extern struct svc_version nfs4_callback_version1;
+
+#else
+
+#define init_nfsv4_state(server)  do { } while (0)
+#define destroy_nfsv4_state(server)       do { } while (0)
+#define nfs4_put_state_owner(inode, owner) do { } while (0)
+#define nfs4_put_open_state(state) do { } while (0)
+#define nfs4_close_state(a, b) do { } while (0)
+
+#endif /* CONFIG_NFS_V4 */
+#endif /* __LINUX_FS_NFS_NFS4_FS.H */
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -48,6 +48,7 @@
 #include <linux/smp_lock.h>
 #include <linux/namei.h>
 
+#include "nfs4_fs.h"
 #include "delegation.h"
 
 #define NFSDBG_FACILITY		NFSDBG_PROC
@@ -62,8 +63,6 @@ static int nfs4_handle_exception(struct 
 extern u32 *nfs4_decode_dirent(u32 *p, struct nfs_entry *entry, int plus);
 extern struct rpc_procinfo nfs4_procedures[];
 
-extern nfs4_stateid zero_stateid;
-
 /* Prevent leaks of NFSv4 errors into userland */
 int nfs4_map_errors(int err)
 {
@@ -104,7 +103,7 @@ const u32 nfs4_statfs_bitmap[2] = {
 	| FATTR4_WORD1_SPACE_TOTAL
 };
 
-u32 nfs4_pathconf_bitmap[2] = {
+const u32 nfs4_pathconf_bitmap[2] = {
 	FATTR4_WORD0_MAXLINK
 	| FATTR4_WORD0_MAXNAME,
 	0
@@ -124,7 +123,7 @@ static void nfs4_setup_readdir(u64 cooki
 
 	BUG_ON(readdir->count < 80);
 	if (cookie > 2) {
-		readdir->cookie = (cookie > 2) ? cookie : 0;
+		readdir->cookie = cookie;
 		memcpy(&readdir->verifier, verifier, sizeof(readdir->verifier));
 		return;
 	}
@@ -270,14 +269,9 @@ static int nfs4_open_reclaim(struct nfs4
 	int err;
 	do {
 		err = _nfs4_open_reclaim(sp, state);
-		switch (err) {
-			case 0:
-			case -NFS4ERR_STALE_CLIENTID:
-			case -NFS4ERR_STALE_STATEID:
-			case -NFS4ERR_EXPIRED:
-				return err;
-		}
-		err = nfs4_handle_exception(server, err, &exception);
+		if (err != -NFS4ERR_DELAY)
+			break;
+		nfs4_handle_exception(server, err, &exception);
 	} while (exception.retry);
 	return err;
 }
@@ -509,6 +503,20 @@ out_stale:
 	goto out_nodeleg;
 }
 
+static inline int nfs4_do_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *state, struct dentry *dentry)
+{
+	struct nfs_server *server = NFS_SERVER(dentry->d_inode);
+	struct nfs4_exception exception = { };
+	int err;
+
+	do {
+		err = _nfs4_open_expired(sp, state, dentry);
+		if (err == -NFS4ERR_DELAY)
+			nfs4_handle_exception(server, err, &exception);
+	} while (exception.retry);
+	return err;
+}
+
 static int nfs4_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *state)
 {
 	struct nfs_inode *nfsi = NFS_I(state->inode);
@@ -521,7 +529,7 @@ static int nfs4_open_expired(struct nfs4
 			continue;
 		get_nfs_open_context(ctx);
 		spin_unlock(&state->inode->i_lock);
-		status = _nfs4_open_expired(sp, state, ctx->dentry);
+		status = nfs4_do_open_expired(sp, state, ctx->dentry);
 		put_nfs_open_context(ctx);
 		return status;
 	}
@@ -745,17 +753,18 @@ static int _nfs4_do_setattr(struct nfs_s
                 .rpc_argp       = &arg,
                 .rpc_resp       = &res,
         };
+	int status;
 
         fattr->valid = 0;
 
-	if (state != NULL)
+	if (state != NULL) {
 		msg.rpc_cred = state->owner->so_cred;
-	if (sattr->ia_valid & ATTR_SIZE)
-		nfs4_copy_stateid(&arg.stateid, state, NULL);
-	else
+		nfs4_copy_stateid(&arg.stateid, state, current->files);
+	} else
 		memcpy(&arg.stateid, &zero_stateid, sizeof(arg.stateid));
 
-	return rpc_call_sync(server->client, &msg, 0);
+	status = rpc_call_sync(server->client, &msg, 0);
+	return status;
 }
 
 static int nfs4_do_setattr(struct nfs_server *server, struct nfs_fattr *fattr,
@@ -1116,47 +1125,33 @@ static int
 nfs4_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,
 		  struct iattr *sattr)
 {
-	struct inode *		inode = dentry->d_inode;
-	int			size_change = sattr->ia_valid & ATTR_SIZE;
-	struct nfs4_state	*state = NULL;
-	int need_iput = 0;
+	struct rpc_cred *cred;
+	struct inode *inode = dentry->d_inode;
+	struct nfs4_state *state;
 	int status;
 
 	fattr->valid = 0;
 	
-	if (size_change) {
-		struct rpc_cred *cred = rpcauth_lookupcred(NFS_SERVER(inode)->client->cl_auth, 0);
-		if (IS_ERR(cred))
-			return PTR_ERR(cred);
+	cred = rpcauth_lookupcred(NFS_SERVER(inode)->client->cl_auth, 0);
+	if (IS_ERR(cred))
+		return PTR_ERR(cred);
+	/* Search for an existing WRITE delegation first */
+	state = nfs4_open_delegated(inode, FMODE_WRITE, cred);
+	if (!IS_ERR(state)) {
+		/* NB: nfs4_open_delegated() bumps the inode->i_count */
+		iput(inode);
+	} else {
+		/* Search for an existing open(O_WRITE) stateid */
 		state = nfs4_find_state(inode, cred, FMODE_WRITE);
-		if (state == NULL) {
-			state = nfs4_open_delegated(dentry->d_inode,
-					FMODE_WRITE, cred);
-			if (IS_ERR(state))
-				state = nfs4_do_open(dentry->d_parent->d_inode,
-						dentry, FMODE_WRITE,
-						NULL, cred);
-			need_iput = 1;
-		}
-		put_rpccred(cred);
-		if (IS_ERR(state))
-			return PTR_ERR(state);
-
-		if (state->inode != inode) {
-			printk(KERN_WARNING "nfs: raced in setattr (%p != %p), returning -EIO\n", inode, state->inode);
-			status = -EIO;
-			goto out;
-		}
 	}
+
 	status = nfs4_do_setattr(NFS_SERVER(inode), fattr,
 			NFS_FH(inode), sattr, state);
-out:
-	if (state) {
-		inode = state->inode;
+	if (status == 0)
+		nfs_setattr_update_inode(inode, sattr);
+	if (state != NULL)
 		nfs4_close_state(state, FMODE_WRITE);
-		if (need_iput)
-			iput(inode);
-	}
+	put_rpccred(cred);
 	return status;
 }
 
@@ -1458,8 +1453,10 @@ nfs4_proc_create(struct inode *dir, stru
 		struct nfs_fattr fattr;
 		status = nfs4_do_setattr(NFS_SERVER(dir), &fattr,
 		                     NFS_FH(state->inode), sattr, state);
-		if (status == 0)
+		if (status == 0) {
+			nfs_setattr_update_inode(state->inode, sattr);
 			goto out;
+		}
 	} else if (flags != 0)
 		goto out;
 	nfs4_close_state(state, flags);
@@ -1731,6 +1728,10 @@ static int _nfs4_proc_readdir(struct den
 	};
 	int			status;
 
+	dprintk("%s: dentry = %s/%s, cookie = %Lu\n", __FUNCTION__,
+			dentry->d_parent->d_name.name,
+			dentry->d_name.name,
+			(unsigned long long)cookie);
 	lock_kernel();
 	nfs4_setup_readdir(cookie, NFS_COOKIEVERF(dir), dentry, &args);
 	res.pgbase = args.pgbase;
@@ -1738,6 +1739,7 @@ static int _nfs4_proc_readdir(struct den
 	if (status == 0)
 		memcpy(NFS_COOKIEVERF(dir), res.verifier.data, NFS4_VERIFIER_SIZE);
 	unlock_kernel();
+	dprintk("%s: returns %d\n", __FUNCTION__, status);
 	return status;
 }
 
@@ -2163,6 +2165,193 @@ nfs4_proc_file_release(struct inode *ino
 	return 0;
 }
 
+static inline int nfs4_server_supports_acls(struct nfs_server *server)
+{
+	return (server->caps & NFS_CAP_ACLS)
+		&& (server->acl_bitmask & ACL4_SUPPORT_ALLOW_ACL)
+		&& (server->acl_bitmask & ACL4_SUPPORT_DENY_ACL);
+}
+
+/* Assuming that XATTR_SIZE_MAX is a multiple of PAGE_CACHE_SIZE, and that
+ * it's OK to put sizeof(void) * (XATTR_SIZE_MAX/PAGE_CACHE_SIZE) bytes on
+ * the stack.
+ */
+#define NFS4ACL_MAXPAGES (XATTR_SIZE_MAX >> PAGE_CACHE_SHIFT)
+
+static void buf_to_pages(const void *buf, size_t buflen,
+		struct page **pages, unsigned int *pgbase)
+{
+	const void *p = buf;
+
+	*pgbase = offset_in_page(buf);
+	p -= *pgbase;
+	while (p < buf + buflen) {
+		*(pages++) = virt_to_page(p);
+		p += PAGE_CACHE_SIZE;
+	}
+}
+
+struct nfs4_cached_acl {
+	int cached;
+	size_t len;
+	char data[0];
+};
+
+static void nfs4_set_cached_acl(struct inode *inode, struct nfs4_cached_acl *acl)
+{
+	struct nfs_inode *nfsi = NFS_I(inode);
+
+	spin_lock(&inode->i_lock);
+	kfree(nfsi->nfs4_acl);
+	nfsi->nfs4_acl = acl;
+	spin_unlock(&inode->i_lock);
+}
+
+static void nfs4_zap_acl_attr(struct inode *inode)
+{
+	nfs4_set_cached_acl(inode, NULL);
+}
+
+static inline ssize_t nfs4_read_cached_acl(struct inode *inode, char *buf, size_t buflen)
+{
+	struct nfs_inode *nfsi = NFS_I(inode);
+	struct nfs4_cached_acl *acl;
+	int ret = -ENOENT;
+
+	spin_lock(&inode->i_lock);
+	acl = nfsi->nfs4_acl;
+	if (acl == NULL)
+		goto out;
+	if (buf == NULL) /* user is just asking for length */
+		goto out_len;
+	if (acl->cached == 0)
+		goto out;
+	ret = -ERANGE; /* see getxattr(2) man page */
+	if (acl->len > buflen)
+		goto out;
+	memcpy(buf, acl->data, acl->len);
+out_len:
+	ret = acl->len;
+out:
+	spin_unlock(&inode->i_lock);
+	return ret;
+}
+
+static void nfs4_write_cached_acl(struct inode *inode, const char *buf, size_t acl_len)
+{
+	struct nfs4_cached_acl *acl;
+
+	if (buf && acl_len <= PAGE_SIZE) {
+		acl = kmalloc(sizeof(*acl) + acl_len, GFP_KERNEL);
+		if (acl == NULL)
+			goto out;
+		acl->cached = 1;
+		memcpy(acl->data, buf, acl_len);
+	} else {
+		acl = kmalloc(sizeof(*acl), GFP_KERNEL);
+		if (acl == NULL)
+			goto out;
+		acl->cached = 0;
+	}
+	acl->len = acl_len;
+out:
+	nfs4_set_cached_acl(inode, acl);
+}
+
+static inline ssize_t nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t buflen)
+{
+	struct page *pages[NFS4ACL_MAXPAGES];
+	struct nfs_getaclargs args = {
+		.fh = NFS_FH(inode),
+		.acl_pages = pages,
+		.acl_len = buflen,
+	};
+	size_t resp_len = buflen;
+	void *resp_buf;
+	struct rpc_message msg = {
+		.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_GETACL],
+		.rpc_argp = &args,
+		.rpc_resp = &resp_len,
+	};
+	struct page *localpage = NULL;
+	int ret;
+
+	if (buflen < PAGE_SIZE) {
+		/* As long as we're doing a round trip to the server anyway,
+		 * let's be prepared for a page of acl data. */
+		localpage = alloc_page(GFP_KERNEL);
+		resp_buf = page_address(localpage);
+		if (localpage == NULL)
+			return -ENOMEM;
+		args.acl_pages[0] = localpage;
+		args.acl_pgbase = 0;
+		args.acl_len = PAGE_SIZE;
+	} else {
+		resp_buf = buf;
+		buf_to_pages(buf, buflen, args.acl_pages, &args.acl_pgbase);
+	}
+	ret = rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
+	if (ret)
+		goto out_free;
+	if (resp_len > args.acl_len)
+		nfs4_write_cached_acl(inode, NULL, resp_len);
+	else
+		nfs4_write_cached_acl(inode, resp_buf, resp_len);
+	if (buf) {
+		ret = -ERANGE;
+		if (resp_len > buflen)
+			goto out_free;
+		if (localpage)
+			memcpy(buf, resp_buf, resp_len);
+	}
+	ret = resp_len;
+out_free:
+	if (localpage)
+		__free_page(localpage);
+	return ret;
+}
+
+static ssize_t nfs4_proc_get_acl(struct inode *inode, void *buf, size_t buflen)
+{
+	struct nfs_server *server = NFS_SERVER(inode);
+	int ret;
+
+	if (!nfs4_server_supports_acls(server))
+		return -EOPNOTSUPP;
+	ret = nfs_revalidate_inode(server, inode);
+	if (ret < 0)
+		return ret;
+	ret = nfs4_read_cached_acl(inode, buf, buflen);
+	if (ret != -ENOENT)
+		return ret;
+	return nfs4_get_acl_uncached(inode, buf, buflen);
+}
+
+static int nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t buflen)
+{
+	struct nfs_server *server = NFS_SERVER(inode);
+	struct page *pages[NFS4ACL_MAXPAGES];
+	struct nfs_setaclargs arg = {
+		.fh		= NFS_FH(inode),
+		.acl_pages	= pages,
+		.acl_len	= buflen,
+	};
+	struct rpc_message msg = {
+		.rpc_proc	= &nfs4_procedures[NFSPROC4_CLNT_SETACL],
+		.rpc_argp	= &arg,
+		.rpc_resp	= NULL,
+	};
+	int ret;
+
+	if (!nfs4_server_supports_acls(server))
+		return -EOPNOTSUPP;
+	buf_to_pages(buf, buflen, arg.acl_pages, &arg.acl_pgbase);
+	ret = rpc_call_sync(NFS_SERVER(inode)->client, &msg, 0);
+	if (ret == 0)
+		nfs4_write_cached_acl(inode, buf, buflen);
+	return ret;
+}
+
 static int
 nfs4_async_handle_error(struct rpc_task *task, struct nfs_server *server)
 {
@@ -2448,14 +2637,11 @@ static int _nfs4_proc_getlk(struct nfs4_
 	down_read(&clp->cl_sem);
 	nlo.clientid = clp->cl_clientid;
 	down(&state->lock_sema);
-	lsp = nfs4_find_lock_state(state, request->fl_owner);
-	if (lsp)
-		nlo.id = lsp->ls_id; 
-	else {
-		spin_lock(&clp->cl_lock);
-		nlo.id = nfs4_alloc_lockowner_id(clp);
-		spin_unlock(&clp->cl_lock);
-	}
+	status = nfs4_set_lock_state(state, request);
+	if (status != 0)
+		goto out;
+	lsp = request->fl_u.nfs4_fl.owner;
+	nlo.id = lsp->ls_id; 
 	arg.u.lockt = &nlo;
 	status = rpc_call_sync(server->client, &msg, 0);
 	if (!status) {
@@ -2476,8 +2662,7 @@ static int _nfs4_proc_getlk(struct nfs4_
 		request->fl_pid = 0;
 		status = 0;
 	}
-	if (lsp)
-		nfs4_put_lock_state(lsp);
+out:
 	up(&state->lock_sema);
 	up_read(&clp->cl_sem);
 	return status;
@@ -2537,28 +2722,26 @@ static int _nfs4_proc_unlck(struct nfs4_
 	};
 	struct nfs4_lock_state *lsp;
 	struct nfs_locku_opargs luargs;
-	int status = 0;
+	int status;
 			
 	down_read(&clp->cl_sem);
 	down(&state->lock_sema);
-	lsp = nfs4_find_lock_state(state, request->fl_owner);
-	if (!lsp)
+	status = nfs4_set_lock_state(state, request);
+	if (status != 0)
 		goto out;
+	lsp = request->fl_u.nfs4_fl.owner;
 	/* We might have lost the locks! */
-	if ((lsp->ls_flags & NFS_LOCK_INITIALIZED) != 0) {
-		luargs.seqid = lsp->ls_seqid;
-		memcpy(&luargs.stateid, &lsp->ls_stateid, sizeof(luargs.stateid));
-		arg.u.locku = &luargs;
-		status = rpc_call_sync(server->client, &msg, RPC_TASK_NOINTR);
-		nfs4_increment_lock_seqid(status, lsp);
-	}
+	if ((lsp->ls_flags & NFS_LOCK_INITIALIZED) == 0)
+		goto out;
+	luargs.seqid = lsp->ls_seqid;
+	memcpy(&luargs.stateid, &lsp->ls_stateid, sizeof(luargs.stateid));
+	arg.u.locku = &luargs;
+	status = rpc_call_sync(server->client, &msg, RPC_TASK_NOINTR);
+	nfs4_increment_lock_seqid(status, lsp);
 
-	if (status == 0) {
+	if (status == 0)
 		memcpy(&lsp->ls_stateid,  &res.u.stateid, 
 				sizeof(lsp->ls_stateid));
-		nfs4_notify_unlck(state, request, lsp);
-	}
-	nfs4_put_lock_state(lsp);
 out:
 	up(&state->lock_sema);
 	if (status == 0)
@@ -2584,7 +2767,7 @@ static int _nfs4_do_setlk(struct nfs4_st
 {
 	struct inode *inode = state->inode;
 	struct nfs_server *server = NFS_SERVER(inode);
-	struct nfs4_lock_state *lsp;
+	struct nfs4_lock_state *lsp = request->fl_u.nfs4_fl.owner;
 	struct nfs_lockargs arg = {
 		.fh = NFS_FH(inode),
 		.type = nfs4_lck_type(cmd, request),
@@ -2606,9 +2789,6 @@ static int _nfs4_do_setlk(struct nfs4_st
 	};
 	int status;
 
-	lsp = nfs4_get_lock_state(state, request->fl_owner);
-	if (lsp == NULL)
-		return -ENOMEM;
 	if (!(lsp->ls_flags & NFS_LOCK_INITIALIZED)) {
 		struct nfs4_state_owner *owner = state->owner;
 		struct nfs_open_to_lock otl = {
@@ -2630,38 +2810,57 @@ static int _nfs4_do_setlk(struct nfs4_st
 		* seqid mutating errors */
 		nfs4_increment_seqid(status, owner);
 		up(&owner->so_sema);
+		if (status == 0) {
+			lsp->ls_flags |= NFS_LOCK_INITIALIZED;
+			lsp->ls_seqid++;
+		}
 	} else {
 		struct nfs_exist_lock el = {
 			.seqid = lsp->ls_seqid,
 		};
 		memcpy(&el.stateid, &lsp->ls_stateid, sizeof(el.stateid));
 		largs.u.exist_lock = &el;
-		largs.new_lock_owner = 0;
 		arg.u.lock = &largs;
 		status = rpc_call_sync(server->client, &msg, RPC_TASK_NOINTR);
+		/* increment seqid on success, and * seqid mutating errors*/
+		nfs4_increment_lock_seqid(status, lsp);
 	}
-	/* increment seqid on success, and * seqid mutating errors*/
-	nfs4_increment_lock_seqid(status, lsp);
 	/* save the returned stateid. */
-	if (status == 0) {
+	if (status == 0)
 		memcpy(&lsp->ls_stateid, &res.u.stateid, sizeof(nfs4_stateid));
-		lsp->ls_flags |= NFS_LOCK_INITIALIZED;
-		if (!reclaim)
-			nfs4_notify_setlk(state, request, lsp);
-	} else if (status == -NFS4ERR_DENIED)
+	else if (status == -NFS4ERR_DENIED)
 		status = -EAGAIN;
-	nfs4_put_lock_state(lsp);
 	return status;
 }
 
 static int nfs4_lock_reclaim(struct nfs4_state *state, struct file_lock *request)
 {
-	return _nfs4_do_setlk(state, F_SETLK, request, 1);
+	struct nfs_server *server = NFS_SERVER(state->inode);
+	struct nfs4_exception exception = { };
+	int err;
+
+	do {
+		err = _nfs4_do_setlk(state, F_SETLK, request, 1);
+		if (err != -NFS4ERR_DELAY)
+			break;
+		nfs4_handle_exception(server, err, &exception);
+	} while (exception.retry);
+	return err;
 }
 
 static int nfs4_lock_expired(struct nfs4_state *state, struct file_lock *request)
 {
-	return _nfs4_do_setlk(state, F_SETLK, request, 0);
+	struct nfs_server *server = NFS_SERVER(state->inode);
+	struct nfs4_exception exception = { };
+	int err;
+
+	do {
+		err = _nfs4_do_setlk(state, F_SETLK, request, 0);
+		if (err != -NFS4ERR_DELAY)
+			break;
+		nfs4_handle_exception(server, err, &exception);
+	} while (exception.retry);
+	return err;
 }
 
 static int _nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock *request)
@@ -2671,7 +2870,9 @@ static int _nfs4_proc_setlk(struct nfs4_
 
 	down_read(&clp->cl_sem);
 	down(&state->lock_sema);
-	status = _nfs4_do_setlk(state, cmd, request, 0);
+	status = nfs4_set_lock_state(state, request);
+	if (status == 0)
+		status = _nfs4_do_setlk(state, cmd, request, 0);
 	up(&state->lock_sema);
 	if (status == 0) {
 		/* Note: we always want to sleep here! */
@@ -2729,10 +2930,53 @@ nfs4_proc_lock(struct file *filp, int cm
 		if (signalled())
 			break;
 	} while(status < 0);
-
 	return status;
 }
 
+
+#define XATTR_NAME_NFSV4_ACL "system.nfs4_acl"
+
+int nfs4_setxattr(struct dentry *dentry, const char *key, const void *buf,
+		size_t buflen, int flags)
+{
+	struct inode *inode = dentry->d_inode;
+
+	if (strcmp(key, XATTR_NAME_NFSV4_ACL) != 0)
+		return -EOPNOTSUPP;
+
+	if (!S_ISREG(inode->i_mode) &&
+	    (!S_ISDIR(inode->i_mode) || inode->i_mode & S_ISVTX))
+		return -EPERM;
+
+	return nfs4_proc_set_acl(inode, buf, buflen);
+}
+
+/* The getxattr man page suggests returning -ENODATA for unknown attributes,
+ * and that's what we'll do for e.g. user attributes that haven't been set.
+ * But we'll follow ext2/ext3's lead by returning -EOPNOTSUPP for unsupported
+ * attributes in kernel-managed attribute namespaces. */
+ssize_t nfs4_getxattr(struct dentry *dentry, const char *key, void *buf,
+		size_t buflen)
+{
+	struct inode *inode = dentry->d_inode;
+
+	if (strcmp(key, XATTR_NAME_NFSV4_ACL) != 0)
+		return -EOPNOTSUPP;
+
+	return nfs4_proc_get_acl(inode, buf, buflen);
+}
+
+ssize_t nfs4_listxattr(struct dentry *dentry, char *buf, size_t buflen)
+{
+	size_t len = strlen(XATTR_NAME_NFSV4_ACL) + 1;
+
+	if (buf && buflen < len)
+		return -ERANGE;
+	if (buf)
+		memcpy(buf, XATTR_NAME_NFSV4_ACL, len);
+	return len;
+}
+
 struct nfs4_state_recovery_ops nfs4_reboot_recovery_ops = {
 	.recover_open	= nfs4_open_reclaim,
 	.recover_lock	= nfs4_lock_reclaim,
@@ -2743,10 +2987,20 @@ struct nfs4_state_recovery_ops nfs4_netw
 	.recover_lock	= nfs4_lock_expired,
 };
 
+static struct inode_operations nfs4_file_inode_operations = {
+	.permission	= nfs_permission,
+	.getattr	= nfs_getattr,
+	.setattr	= nfs_setattr,
+	.getxattr	= nfs4_getxattr,
+	.setxattr	= nfs4_setxattr,
+	.listxattr	= nfs4_listxattr,
+};
+
 struct nfs_rpc_ops	nfs_v4_clientops = {
 	.version	= 4,			/* protocol version */
 	.dentry_ops	= &nfs4_dentry_operations,
 	.dir_inode_ops	= &nfs4_dir_inode_operations,
+	.file_inode_ops	= &nfs4_file_inode_operations,
 	.getroot	= nfs4_proc_get_root,
 	.getattr	= nfs4_proc_getattr,
 	.setattr	= nfs4_proc_setattr,
@@ -2777,6 +3031,7 @@ struct nfs_rpc_ops	nfs_v4_clientops = {
 	.file_open      = nfs4_proc_file_open,
 	.file_release   = nfs4_proc_file_release,
 	.lock		= nfs4_proc_lock,
+	.clear_acl_cache = nfs4_zap_acl_attr,
 };
 
 /*
diff --git a/fs/nfs/nfs4renewd.c b/fs/nfs/nfs4renewd.c
--- a/fs/nfs/nfs4renewd.c
+++ b/fs/nfs/nfs4renewd.c
@@ -53,6 +53,7 @@
 #include <linux/nfs.h>
 #include <linux/nfs4.h>
 #include <linux/nfs_fs.h>
+#include "nfs4_fs.h"
 
 #define NFSDBG_FACILITY	NFSDBG_PROC
 
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -46,24 +46,18 @@
 #include <linux/workqueue.h>
 #include <linux/bitops.h>
 
+#include "nfs4_fs.h"
 #include "callback.h"
 #include "delegation.h"
 
 #define OPENOWNER_POOL_SIZE	8
 
-static DEFINE_SPINLOCK(state_spinlock);
-
-nfs4_stateid zero_stateid;
-
-#if 0
-nfs4_stateid one_stateid =
-	{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
-#endif
+const nfs4_stateid zero_stateid;
 
+static DEFINE_SPINLOCK(state_spinlock);
 static LIST_HEAD(nfs4_clientid_list);
 
 static void nfs4_recover_state(void *);
-extern void nfs4_renew_state(void *);
 
 void
 init_nfsv4_state(struct nfs_server *server)
@@ -116,6 +110,7 @@ nfs4_alloc_client(struct in_addr *addr)
 	INIT_LIST_HEAD(&clp->cl_superblocks);
 	init_waitqueue_head(&clp->cl_waitq);
 	rpc_init_wait_queue(&clp->cl_rpcwaitq, "NFS4 client");
+	clp->cl_rpcclient = ERR_PTR(-EINVAL);
 	clp->cl_boot_time = CURRENT_TIME;
 	clp->cl_state = 1 << NFS4CLNT_OK;
 	return clp;
@@ -137,7 +132,7 @@ nfs4_free_client(struct nfs4_client *clp
 	if (clp->cl_cred)
 		put_rpccred(clp->cl_cred);
 	nfs_idmap_delete(clp);
-	if (clp->cl_rpcclient)
+	if (!IS_ERR(clp->cl_rpcclient))
 		rpc_shutdown_client(clp->cl_rpcclient);
 	kfree(clp);
 	nfs_callback_down();
@@ -365,7 +360,7 @@ nfs4_alloc_open_state(void)
 	atomic_set(&state->count, 1);
 	INIT_LIST_HEAD(&state->lock_states);
 	init_MUTEX(&state->lock_sema);
-	rwlock_init(&state->state_lock);
+	spin_lock_init(&state->state_lock);
 	return state;
 }
 
@@ -547,16 +542,6 @@ __nfs4_find_lock_state(struct nfs4_state
 	return NULL;
 }
 
-struct nfs4_lock_state *
-nfs4_find_lock_state(struct nfs4_state *state, fl_owner_t fl_owner)
-{
-	struct nfs4_lock_state *lsp;
-	read_lock(&state->state_lock);
-	lsp = __nfs4_find_lock_state(state, fl_owner);
-	read_unlock(&state->state_lock);
-	return lsp;
-}
-
 /*
  * Return a compatible lock_state. If no initialized lock_state structure
  * exists, return an uninitialized one.
@@ -573,14 +558,13 @@ static struct nfs4_lock_state *nfs4_allo
 		return NULL;
 	lsp->ls_flags = 0;
 	lsp->ls_seqid = 0;	/* arbitrary */
-	lsp->ls_id = -1; 
 	memset(lsp->ls_stateid.data, 0, sizeof(lsp->ls_stateid.data));
 	atomic_set(&lsp->ls_count, 1);
 	lsp->ls_owner = fl_owner;
-	INIT_LIST_HEAD(&lsp->ls_locks);
 	spin_lock(&clp->cl_lock);
 	lsp->ls_id = nfs4_alloc_lockowner_id(clp);
 	spin_unlock(&clp->cl_lock);
+	INIT_LIST_HEAD(&lsp->ls_locks);
 	return lsp;
 }
 
@@ -590,121 +574,112 @@ static struct nfs4_lock_state *nfs4_allo
  *
  * The caller must be holding state->lock_sema and clp->cl_sem
  */
-struct nfs4_lock_state *nfs4_get_lock_state(struct nfs4_state *state, fl_owner_t owner)
+static struct nfs4_lock_state *nfs4_get_lock_state(struct nfs4_state *state, fl_owner_t owner)
 {
-	struct nfs4_lock_state * lsp;
+	struct nfs4_lock_state *lsp, *new = NULL;
 	
-	lsp = nfs4_find_lock_state(state, owner);
-	if (lsp == NULL)
-		lsp = nfs4_alloc_lock_state(state, owner);
+	for(;;) {
+		spin_lock(&state->state_lock);
+		lsp = __nfs4_find_lock_state(state, owner);
+		if (lsp != NULL)
+			break;
+		if (new != NULL) {
+			new->ls_state = state;
+			list_add(&new->ls_locks, &state->lock_states);
+			set_bit(LK_STATE_IN_USE, &state->flags);
+			lsp = new;
+			new = NULL;
+			break;
+		}
+		spin_unlock(&state->state_lock);
+		new = nfs4_alloc_lock_state(state, owner);
+		if (new == NULL)
+			return NULL;
+	}
+	spin_unlock(&state->state_lock);
+	kfree(new);
 	return lsp;
 }
 
 /*
- * Byte-range lock aware utility to initialize the stateid of read/write
- * requests.
+ * Release reference to lock_state, and free it if we see that
+ * it is no longer in use
  */
-void
-nfs4_copy_stateid(nfs4_stateid *dst, struct nfs4_state *state, fl_owner_t fl_owner)
+static void nfs4_put_lock_state(struct nfs4_lock_state *lsp)
 {
-	if (test_bit(LK_STATE_IN_USE, &state->flags)) {
-		struct nfs4_lock_state *lsp;
+	struct nfs4_state *state;
 
-		lsp = nfs4_find_lock_state(state, fl_owner);
-		if (lsp) {
-			memcpy(dst, &lsp->ls_stateid, sizeof(*dst));
-			nfs4_put_lock_state(lsp);
-			return;
-		}
-	}
-	memcpy(dst, &state->stateid, sizeof(*dst));
+	if (lsp == NULL)
+		return;
+	state = lsp->ls_state;
+	if (!atomic_dec_and_lock(&lsp->ls_count, &state->state_lock))
+		return;
+	list_del(&lsp->ls_locks);
+	if (list_empty(&state->lock_states))
+		clear_bit(LK_STATE_IN_USE, &state->flags);
+	spin_unlock(&state->state_lock);
+	kfree(lsp);
 }
 
-/*
-* Called with state->lock_sema and clp->cl_sem held.
-*/
-void nfs4_increment_lock_seqid(int status, struct nfs4_lock_state *lsp)
+static void nfs4_fl_copy_lock(struct file_lock *dst, struct file_lock *src)
 {
-	if (status == NFS_OK || seqid_mutating_err(-status))
-		lsp->ls_seqid++;
-}
+	struct nfs4_lock_state *lsp = src->fl_u.nfs4_fl.owner;
 
-/* 
-* Check to see if the request lock (type FL_UNLK) effects the fl lock.
-*
-* fl and request must have the same posix owner
-*
-* return: 
-* 0 -> fl not effected by request
-* 1 -> fl consumed by request
-*/
+	dst->fl_u.nfs4_fl.owner = lsp;
+	atomic_inc(&lsp->ls_count);
+}
 
-static int
-nfs4_check_unlock(struct file_lock *fl, struct file_lock *request)
+static void nfs4_fl_release_lock(struct file_lock *fl)
 {
-	if (fl->fl_start >= request->fl_start && fl->fl_end <= request->fl_end)
-		return 1;
-	return 0;
+	nfs4_put_lock_state(fl->fl_u.nfs4_fl.owner);
 }
 
-/*
- * Post an initialized lock_state on the state->lock_states list.
- */
-void nfs4_notify_setlk(struct nfs4_state *state, struct file_lock *request, struct nfs4_lock_state *lsp)
+static struct file_lock_operations nfs4_fl_lock_ops = {
+	.fl_copy_lock = nfs4_fl_copy_lock,
+	.fl_release_private = nfs4_fl_release_lock,
+};
+
+int nfs4_set_lock_state(struct nfs4_state *state, struct file_lock *fl)
 {
-	if (!list_empty(&lsp->ls_locks))
-		return;
-	atomic_inc(&lsp->ls_count);
-	write_lock(&state->state_lock);
-	list_add(&lsp->ls_locks, &state->lock_states);
-	set_bit(LK_STATE_IN_USE, &state->flags);
-	write_unlock(&state->state_lock);
+	struct nfs4_lock_state *lsp;
+
+	if (fl->fl_ops != NULL)
+		return 0;
+	lsp = nfs4_get_lock_state(state, fl->fl_owner);
+	if (lsp == NULL)
+		return -ENOMEM;
+	fl->fl_u.nfs4_fl.owner = lsp;
+	fl->fl_ops = &nfs4_fl_lock_ops;
+	return 0;
 }
 
-/* 
- * to decide to 'reap' lock state:
- * 1) search i_flock for file_locks with fl.lock_state = to ls.
- * 2) determine if unlock will consume found lock. 
- * 	if so, reap
- *
- * 	else, don't reap.
- *
+/*
+ * Byte-range lock aware utility to initialize the stateid of read/write
+ * requests.
  */
-void
-nfs4_notify_unlck(struct nfs4_state *state, struct file_lock *request, struct nfs4_lock_state *lsp)
+void nfs4_copy_stateid(nfs4_stateid *dst, struct nfs4_state *state, fl_owner_t fl_owner)
 {
-	struct inode *inode = state->inode;
-	struct file_lock *fl;
+	struct nfs4_lock_state *lsp;
 
-	for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) {
-		if (!(fl->fl_flags & FL_POSIX))
-			continue;
-		if (fl->fl_owner != lsp->ls_owner)
-			continue;
-		/* Exit if we find at least one lock which is not consumed */
-		if (nfs4_check_unlock(fl,request) == 0)
-			return;
-	}
+	memcpy(dst, &state->stateid, sizeof(*dst));
+	if (test_bit(LK_STATE_IN_USE, &state->flags) == 0)
+		return;
 
-	write_lock(&state->state_lock);
-	list_del_init(&lsp->ls_locks);
-	if (list_empty(&state->lock_states))
-		clear_bit(LK_STATE_IN_USE, &state->flags);
-	write_unlock(&state->state_lock);
+	spin_lock(&state->state_lock);
+	lsp = __nfs4_find_lock_state(state, fl_owner);
+	if (lsp != NULL && (lsp->ls_flags & NFS_LOCK_INITIALIZED) != 0)
+		memcpy(dst, &lsp->ls_stateid, sizeof(*dst));
+	spin_unlock(&state->state_lock);
 	nfs4_put_lock_state(lsp);
 }
 
 /*
- * Release reference to lock_state, and free it if we see that
- * it is no longer in use
- */
-void
-nfs4_put_lock_state(struct nfs4_lock_state *lsp)
+* Called with state->lock_sema and clp->cl_sem held.
+*/
+void nfs4_increment_lock_seqid(int status, struct nfs4_lock_state *lsp)
 {
-	if (!atomic_dec_and_test(&lsp->ls_count))
-		return;
-	BUG_ON (!list_empty(&lsp->ls_locks));
-	kfree(lsp);
+	if (status == NFS_OK || seqid_mutating_err(-status))
+		lsp->ls_seqid++;
 }
 
 /*
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -51,6 +51,7 @@
 #include <linux/nfs4.h>
 #include <linux/nfs_fs.h>
 #include <linux/nfs_idmap.h>
+#include "nfs4_fs.h"
 
 #define NFSDBG_FACILITY		NFSDBG_XDR
 
@@ -82,12 +83,16 @@ static int nfs_stat_to_errno(int);
 #define encode_getfh_maxsz      (op_encode_hdr_maxsz)
 #define decode_getfh_maxsz      (op_decode_hdr_maxsz + 1 + \
 				((3+NFS4_FHSIZE) >> 2))
-#define encode_getattr_maxsz    (op_encode_hdr_maxsz + 3)
+#define nfs4_fattr_bitmap_maxsz 3
+#define encode_getattr_maxsz    (op_encode_hdr_maxsz + nfs4_fattr_bitmap_maxsz)
 #define nfs4_name_maxsz		(1 + ((3 + NFS4_MAXNAMLEN) >> 2))
 #define nfs4_path_maxsz		(1 + ((3 + NFS4_MAXPATHLEN) >> 2))
-#define nfs4_fattr_bitmap_maxsz (36 + 2 * nfs4_name_maxsz)
-#define decode_getattr_maxsz    (op_decode_hdr_maxsz + 3 + \
-                                nfs4_fattr_bitmap_maxsz)
+/* This is based on getfattr, which uses the most attributes: */
+#define nfs4_fattr_value_maxsz	(1 + (1 + 2 + 2 + 4 + 2 + 1 + 1 + 2 + 2 + \
+				3 + 3 + 3 + 2 * nfs4_name_maxsz))
+#define nfs4_fattr_maxsz	(nfs4_fattr_bitmap_maxsz + \
+				nfs4_fattr_value_maxsz)
+#define decode_getattr_maxsz    (op_decode_hdr_maxsz + nfs4_fattr_maxsz)
 #define encode_savefh_maxsz     (op_encode_hdr_maxsz)
 #define decode_savefh_maxsz     (op_decode_hdr_maxsz)
 #define encode_fsinfo_maxsz	(op_encode_hdr_maxsz + 2)
@@ -122,11 +127,11 @@ static int nfs_stat_to_errno(int);
 #define encode_symlink_maxsz	(op_encode_hdr_maxsz + \
 				1 + nfs4_name_maxsz + \
 				nfs4_path_maxsz + \
-				nfs4_fattr_bitmap_maxsz)
+				nfs4_fattr_maxsz)
 #define decode_symlink_maxsz	(op_decode_hdr_maxsz + 8)
 #define encode_create_maxsz	(op_encode_hdr_maxsz + \
 				2 + nfs4_name_maxsz + \
-				nfs4_fattr_bitmap_maxsz)
+				nfs4_fattr_maxsz)
 #define decode_create_maxsz	(op_decode_hdr_maxsz + 8)
 #define encode_delegreturn_maxsz (op_encode_hdr_maxsz + 4)
 #define decode_delegreturn_maxsz (op_decode_hdr_maxsz)
@@ -205,7 +210,7 @@ static int nfs_stat_to_errno(int);
 #define NFS4_enc_setattr_sz     (compound_encode_hdr_maxsz + \
                                 encode_putfh_maxsz + \
                                 op_encode_hdr_maxsz + 4 + \
-                                nfs4_fattr_bitmap_maxsz + \
+                                nfs4_fattr_maxsz + \
                                 encode_getattr_maxsz)
 #define NFS4_dec_setattr_sz     (compound_decode_hdr_maxsz + \
                                 decode_putfh_maxsz + \
@@ -360,6 +365,20 @@ static int nfs_stat_to_errno(int);
 				encode_delegreturn_maxsz)
 #define NFS4_dec_delegreturn_sz (compound_decode_hdr_maxsz + \
 				decode_delegreturn_maxsz)
+#define NFS4_enc_getacl_sz	(compound_encode_hdr_maxsz + \
+				encode_putfh_maxsz + \
+				encode_getattr_maxsz)
+#define NFS4_dec_getacl_sz	(compound_decode_hdr_maxsz + \
+				decode_putfh_maxsz + \
+				op_decode_hdr_maxsz + \
+				nfs4_fattr_bitmap_maxsz + 1)
+#define NFS4_enc_setacl_sz	(compound_encode_hdr_maxsz + \
+				encode_putfh_maxsz + \
+				op_encode_hdr_maxsz + 4 + \
+				nfs4_fattr_bitmap_maxsz + 1)
+#define NFS4_dec_setacl_sz	(compound_decode_hdr_maxsz + \
+				decode_putfh_maxsz + \
+				op_decode_hdr_maxsz + nfs4_fattr_bitmap_maxsz)
 
 static struct {
 	unsigned int	mode;
@@ -459,7 +478,7 @@ static int encode_attrs(struct xdr_strea
 	 * In the worst-case, this would be
 	 *   12(bitmap) + 4(attrlen) + 8(size) + 4(mode) + 4(atime) + 4(mtime)
 	 *          = 36 bytes, plus any contribution from variable-length fields
-	 *            such as owner/group/acl's.
+	 *            such as owner/group.
 	 */
 	len = 16;
 
@@ -660,8 +679,6 @@ static int encode_getattr_two(struct xdr
 
 static int encode_getfattr(struct xdr_stream *xdr, const u32* bitmask)
 {
-	extern u32 nfs4_fattr_bitmap[];
-
 	return encode_getattr_two(xdr,
 			bitmask[0] & nfs4_fattr_bitmap[0],
 			bitmask[1] & nfs4_fattr_bitmap[1]);
@@ -669,8 +686,6 @@ static int encode_getfattr(struct xdr_st
 
 static int encode_fsinfo(struct xdr_stream *xdr, const u32* bitmask)
 {
-	extern u32 nfs4_fsinfo_bitmap[];
-
 	return encode_getattr_two(xdr, bitmask[0] & nfs4_fsinfo_bitmap[0],
 			bitmask[1] & nfs4_fsinfo_bitmap[1]);
 }
@@ -969,7 +984,6 @@ static int encode_putrootfh(struct xdr_s
 
 static void encode_stateid(struct xdr_stream *xdr, const struct nfs_open_context *ctx)
 {
-	extern nfs4_stateid zero_stateid;
 	nfs4_stateid stateid;
 	uint32_t *p;
 
@@ -1000,6 +1014,10 @@ static int encode_read(struct xdr_stream
 static int encode_readdir(struct xdr_stream *xdr, const struct nfs4_readdir_arg *readdir, struct rpc_rqst *req)
 {
 	struct rpc_auth *auth = req->rq_task->tk_auth;
+	uint32_t attrs[2] = {
+		FATTR4_WORD0_RDATTR_ERROR|FATTR4_WORD0_FILEID,
+		FATTR4_WORD1_MOUNTED_ON_FILEID,
+	};
 	int replen;
 	uint32_t *p;
 
@@ -1010,13 +1028,20 @@ static int encode_readdir(struct xdr_str
 	WRITE32(readdir->count >> 1);  /* We're not doing readdirplus */
 	WRITE32(readdir->count);
 	WRITE32(2);
-	if (readdir->bitmask[1] & FATTR4_WORD1_MOUNTED_ON_FILEID) {
-		WRITE32(0);
-		WRITE32(FATTR4_WORD1_MOUNTED_ON_FILEID);
-	} else {
-		WRITE32(FATTR4_WORD0_FILEID);
-		WRITE32(0);
-	}
+	/* Switch to mounted_on_fileid if the server supports it */
+	if (readdir->bitmask[1] & FATTR4_WORD1_MOUNTED_ON_FILEID)
+		attrs[0] &= ~FATTR4_WORD0_FILEID;
+	else
+		attrs[1] &= ~FATTR4_WORD1_MOUNTED_ON_FILEID;
+	WRITE32(attrs[0] & readdir->bitmask[0]);
+	WRITE32(attrs[1] & readdir->bitmask[1]);
+	dprintk("%s: cookie = %Lu, verifier = 0x%x%x, bitmap = 0x%x%x\n",
+			__FUNCTION__,
+			(unsigned long long)readdir->cookie,
+			((u32 *)readdir->verifier.data)[0],
+			((u32 *)readdir->verifier.data)[1],
+			attrs[0] & readdir->bitmask[0],
+			attrs[1] & readdir->bitmask[1]);
 
 	/* set up reply kvec
 	 *    toplevel_status + taglen + rescount + OP_PUTFH + status
@@ -1025,6 +1050,9 @@ static int encode_readdir(struct xdr_str
 	replen = (RPC_REPHDRSIZE + auth->au_rslack + 9) << 2;
 	xdr_inline_pages(&req->rq_rcv_buf, replen, readdir->pages,
 			 readdir->pgbase, readdir->count);
+	dprintk("%s: inlined page args = (%u, %p, %u, %u)\n",
+			__FUNCTION__, replen, readdir->pages,
+			readdir->pgbase, readdir->count);
 
 	return 0;
 }
@@ -1089,6 +1117,25 @@ static int encode_renew(struct xdr_strea
 }
 
 static int
+encode_setacl(struct xdr_stream *xdr, struct nfs_setaclargs *arg)
+{
+	uint32_t *p;
+
+	RESERVE_SPACE(4+sizeof(zero_stateid.data));
+	WRITE32(OP_SETATTR);
+	WRITEMEM(zero_stateid.data, sizeof(zero_stateid.data));
+	RESERVE_SPACE(2*4);
+	WRITE32(1);
+	WRITE32(FATTR4_WORD0_ACL);
+	if (arg->acl_len % 4)
+		return -EINVAL;
+	RESERVE_SPACE(4);
+	WRITE32(arg->acl_len);
+	xdr_write_pages(xdr, arg->acl_pages, arg->acl_pgbase, arg->acl_len);
+	return 0;
+}
+
+static int
 encode_savefh(struct xdr_stream *xdr)
 {
 	uint32_t *p;
@@ -1632,6 +1679,34 @@ out:
 }
 
 /*
+ * Encode a GETACL request
+ */
+static int
+nfs4_xdr_enc_getacl(struct rpc_rqst *req, uint32_t *p,
+		struct nfs_getaclargs *args)
+{
+	struct xdr_stream xdr;
+	struct rpc_auth *auth = req->rq_task->tk_auth;
+	struct compound_hdr hdr = {
+		.nops   = 2,
+	};
+	int replen, status;
+
+	xdr_init_encode(&xdr, &req->rq_snd_buf, p);
+	encode_compound_hdr(&xdr, &hdr);
+	status = encode_putfh(&xdr, args->fh);
+	if (status)
+		goto out;
+	status = encode_getattr_two(&xdr, FATTR4_WORD0_ACL, 0);
+	/* set up reply buffer: */
+	replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS4_dec_getacl_sz) << 2;
+	xdr_inline_pages(&req->rq_rcv_buf, replen,
+		args->acl_pages, args->acl_pgbase, args->acl_len);
+out:
+	return status;
+}
+
+/*
  * Encode a WRITE request
  */
 static int nfs4_xdr_enc_write(struct rpc_rqst *req, uint32_t *p, struct nfs_writeargs *args)
@@ -1697,7 +1772,6 @@ static int nfs4_xdr_enc_fsinfo(struct rp
  */
 static int nfs4_xdr_enc_pathconf(struct rpc_rqst *req, uint32_t *p, const struct nfs4_pathconf_arg *args)
 {
-	extern u32 nfs4_pathconf_bitmap[2];
 	struct xdr_stream xdr;
 	struct compound_hdr hdr = {
 		.nops = 2,
@@ -1718,7 +1792,6 @@ static int nfs4_xdr_enc_pathconf(struct 
  */
 static int nfs4_xdr_enc_statfs(struct rpc_rqst *req, uint32_t *p, const struct nfs4_statfs_arg *args)
 {
-	extern u32 nfs4_statfs_bitmap[];
 	struct xdr_stream xdr;
 	struct compound_hdr hdr = {
 		.nops = 2,
@@ -3003,6 +3076,11 @@ static int decode_readdir(struct xdr_str
 		return status;
 	READ_BUF(8);
 	COPYMEM(readdir->verifier.data, 8);
+	dprintk("%s: verifier = 0x%x%x\n",
+			__FUNCTION__,
+			((u32 *)readdir->verifier.data)[0],
+			((u32 *)readdir->verifier.data)[1]);
+
 
 	hdrlen = (char *) p - (char *) iov->iov_base;
 	recvd = rcvbuf->len - hdrlen;
@@ -3017,12 +3095,14 @@ static int decode_readdir(struct xdr_str
 	for (nr = 0; *p++; nr++) {
 		if (p + 3 > end)
 			goto short_pkt;
+		dprintk("cookie = %Lu, ", *((unsigned long long *)p));
 		p += 2;			/* cookie */
 		len = ntohl(*p++);	/* filename length */
 		if (len > NFS4_MAXNAMLEN) {
 			printk(KERN_WARNING "NFS: giant filename in readdir (len 0x%x)\n", len);
 			goto err_unmap;
 		}
+		dprintk("filename = %*s\n", len, (char *)p);
 		p += XDR_QUADLEN(len);
 		if (p + 1 > end)
 			goto short_pkt;
@@ -3042,6 +3122,7 @@ out:	
 	kunmap_atomic(kaddr, KM_USER0);
 	return 0;
 short_pkt:
+	dprintk("%s: short packet at entry %d\n", __FUNCTION__, nr);
 	entry[0] = entry[1] = 0;
 	/* truncate listing ? */
 	if (!nr) {
@@ -3127,6 +3208,47 @@ static int decode_renew(struct xdr_strea
 	return decode_op_hdr(xdr, OP_RENEW);
 }
 
+static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req,
+		size_t *acl_len)
+{
+	uint32_t *savep;
+	uint32_t attrlen,
+		 bitmap[2] = {0};
+	struct kvec *iov = req->rq_rcv_buf.head;
+	int status;
+
+	*acl_len = 0;
+	if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0)
+		goto out;
+	if ((status = decode_attr_bitmap(xdr, bitmap)) != 0)
+		goto out;
+	if ((status = decode_attr_length(xdr, &attrlen, &savep)) != 0)
+		goto out;
+
+	if (unlikely(bitmap[0] & (FATTR4_WORD0_ACL - 1U)))
+		return -EIO;
+	if (likely(bitmap[0] & FATTR4_WORD0_ACL)) {
+		int hdrlen, recvd;
+
+		/* We ignore &savep and don't do consistency checks on
+		 * the attr length.  Let userspace figure it out.... */
+		hdrlen = (u8 *)xdr->p - (u8 *)iov->iov_base;
+		recvd = req->rq_rcv_buf.len - hdrlen;
+		if (attrlen > recvd) {
+			printk(KERN_WARNING "NFS: server cheating in getattr"
+					" acl reply: attrlen %u > recvd %u\n",
+					attrlen, recvd);
+			return -EINVAL;
+		}
+		if (attrlen <= *acl_len)
+			xdr_read_pages(xdr, attrlen);
+		*acl_len = attrlen;
+	}
+
+out:
+	return status;
+}
+
 static int
 decode_savefh(struct xdr_stream *xdr)
 {
@@ -3418,6 +3540,71 @@ out:
 
 }
 
+/*
+ * Encode an SETACL request
+ */
+static int
+nfs4_xdr_enc_setacl(struct rpc_rqst *req, uint32_t *p, struct nfs_setaclargs *args)
+{
+        struct xdr_stream xdr;
+        struct compound_hdr hdr = {
+                .nops   = 2,
+        };
+        int status;
+
+        xdr_init_encode(&xdr, &req->rq_snd_buf, p);
+        encode_compound_hdr(&xdr, &hdr);
+        status = encode_putfh(&xdr, args->fh);
+        if (status)
+                goto out;
+        status = encode_setacl(&xdr, args);
+out:
+        return status;
+}
+/*
+ * Decode SETACL response
+ */
+static int
+nfs4_xdr_dec_setacl(struct rpc_rqst *rqstp, uint32_t *p, void *res)
+{
+	struct xdr_stream xdr;
+	struct compound_hdr hdr;
+	int status;
+
+	xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
+	status = decode_compound_hdr(&xdr, &hdr);
+	if (status)
+		goto out;
+	status = decode_putfh(&xdr);
+	if (status)
+		goto out;
+	status = decode_setattr(&xdr, res);
+out:
+	return status;
+}
+
+/*
+ * Decode GETACL response
+ */
+static int
+nfs4_xdr_dec_getacl(struct rpc_rqst *rqstp, uint32_t *p, size_t *acl_len)
+{
+	struct xdr_stream xdr;
+	struct compound_hdr hdr;
+	int status;
+
+	xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
+	status = decode_compound_hdr(&xdr, &hdr);
+	if (status)
+		goto out;
+	status = decode_putfh(&xdr);
+	if (status)
+		goto out;
+	status = decode_getacl(&xdr, rqstp, acl_len);
+
+out:
+	return status;
+}
 
 /*
  * Decode CLOSE response
@@ -3895,6 +4082,12 @@ uint32_t *nfs4_decode_dirent(uint32_t *p
 	}
 	len = XDR_QUADLEN(ntohl(*p++));	/* attribute buffer length */
 	if (len > 0) {
+		if (bitmap[0] & FATTR4_WORD0_RDATTR_ERROR) {
+			bitmap[0] &= ~FATTR4_WORD0_RDATTR_ERROR;
+			/* Ignore the return value of rdattr_error for now */
+			p++;
+			len--;
+		}
 		if (bitmap[0] == 0 && bitmap[1] == FATTR4_WORD1_MOUNTED_ON_FILEID)
 			xdr_decode_hyper(p, &entry->ino);
 		else if (bitmap[0] == FATTR4_WORD0_FILEID)
@@ -3934,6 +4127,8 @@ static struct {
 	{ NFS4ERR_DQUOT,	EDQUOT		},
 	{ NFS4ERR_STALE,	ESTALE		},
 	{ NFS4ERR_BADHANDLE,	EBADHANDLE	},
+	{ NFS4ERR_BADOWNER,	EINVAL		},
+	{ NFS4ERR_BADNAME,	EINVAL		},
 	{ NFS4ERR_BAD_COOKIE,	EBADCOOKIE	},
 	{ NFS4ERR_NOTSUPP,	ENOTSUPP	},
 	{ NFS4ERR_TOOSMALL,	ETOOSMALL	},
@@ -4019,6 +4214,8 @@ struct rpc_procinfo	nfs4_procedures[] = 
   PROC(READDIR,		enc_readdir,	dec_readdir),
   PROC(SERVER_CAPS,	enc_server_caps, dec_server_caps),
   PROC(DELEGRETURN,	enc_delegreturn, dec_delegreturn),
+  PROC(GETACL,		enc_getacl,	dec_getacl),
+  PROC(SETACL,		enc_setacl,	dec_setacl),
 };
 
 struct rpc_version		nfs_version4 = {
diff --git a/fs/nfs/nfsroot.c b/fs/nfs/nfsroot.c
--- a/fs/nfs/nfsroot.c
+++ b/fs/nfs/nfsroot.c
@@ -124,6 +124,7 @@ enum {
 	Opt_soft, Opt_hard, Opt_intr,
 	Opt_nointr, Opt_posix, Opt_noposix, Opt_cto, Opt_nocto, Opt_ac, 
 	Opt_noac, Opt_lock, Opt_nolock, Opt_v2, Opt_v3, Opt_udp, Opt_tcp,
+	Opt_acl, Opt_noacl,
 	/* Error token */
 	Opt_err
 };
@@ -158,6 +159,8 @@ static match_table_t __initdata tokens =
 	{Opt_udp, "udp"},
 	{Opt_tcp, "proto=tcp"},
 	{Opt_tcp, "tcp"},
+	{Opt_acl, "acl"},
+	{Opt_noacl, "noacl"},
 	{Opt_err, NULL}
 	
 };
@@ -266,6 +269,12 @@ static int __init root_nfs_parse(char *n
 			case Opt_tcp:
 				nfs_data.flags |= NFS_MOUNT_TCP;
 				break;
+			case Opt_acl:
+				nfs_data.flags &= ~NFS_MOUNT_NOACL;
+				break;
+			case Opt_noacl:
+				nfs_data.flags |= NFS_MOUNT_NOACL;
+				break;
 			default : 
 				return 0;
 		}
diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c
--- a/fs/nfs/pagelist.c
+++ b/fs/nfs/pagelist.c
@@ -107,11 +107,38 @@ void nfs_unlock_request(struct nfs_page 
 	smp_mb__before_clear_bit();
 	clear_bit(PG_BUSY, &req->wb_flags);
 	smp_mb__after_clear_bit();
-	wake_up_all(&req->wb_context->waitq);
+	wake_up_bit(&req->wb_flags, PG_BUSY);
 	nfs_release_request(req);
 }
 
 /**
+ * nfs_set_page_writeback_locked - Lock a request for writeback
+ * @req:
+ */
+int nfs_set_page_writeback_locked(struct nfs_page *req)
+{
+	struct nfs_inode *nfsi = NFS_I(req->wb_context->dentry->d_inode);
+
+	if (!nfs_lock_request(req))
+		return 0;
+	radix_tree_tag_set(&nfsi->nfs_page_tree, req->wb_index, NFS_PAGE_TAG_WRITEBACK);
+	return 1;
+}
+
+/**
+ * nfs_clear_page_writeback - Unlock request and wake up sleepers
+ */
+void nfs_clear_page_writeback(struct nfs_page *req)
+{
+	struct nfs_inode *nfsi = NFS_I(req->wb_context->dentry->d_inode);
+
+	spin_lock(&nfsi->req_lock);
+	radix_tree_tag_clear(&nfsi->nfs_page_tree, req->wb_index, NFS_PAGE_TAG_WRITEBACK);
+	spin_unlock(&nfsi->req_lock);
+	nfs_unlock_request(req);
+}
+
+/**
  * nfs_clear_request - Free up all resources allocated to the request
  * @req:
  *
@@ -150,34 +177,15 @@ nfs_release_request(struct nfs_page *req
 	nfs_page_free(req);
 }
 
-/**
- * nfs_list_add_request - Insert a request into a sorted list
- * @req: request
- * @head: head of list into which to insert the request.
- *
- * Note that the wb_list is sorted by page index in order to facilitate
- * coalescing of requests.
- * We use an insertion sort that is optimized for the case of appended
- * writes.
- */
-void
-nfs_list_add_request(struct nfs_page *req, struct list_head *head)
+static int nfs_wait_bit_interruptible(void *word)
 {
-	struct list_head *pos;
+	int ret = 0;
 
-#ifdef NFS_PARANOIA
-	if (!list_empty(&req->wb_list)) {
-		printk(KERN_ERR "NFS: Add to list failed!\n");
-		BUG();
-	}
-#endif
-	list_for_each_prev(pos, head) {
-		struct nfs_page	*p = nfs_list_entry(pos);
-		if (p->wb_index < req->wb_index)
-			break;
-	}
-	list_add(&req->wb_list, pos);
-	req->wb_list_head = head;
+	if (signal_pending(current))
+		ret = -ERESTARTSYS;
+	else
+		schedule();
+	return ret;
 }
 
 /**
@@ -190,12 +198,22 @@ nfs_list_add_request(struct nfs_page *re
 int
 nfs_wait_on_request(struct nfs_page *req)
 {
-	struct inode	*inode = req->wb_context->dentry->d_inode;
-        struct rpc_clnt	*clnt = NFS_CLIENT(inode);
-
-	if (!NFS_WBACK_BUSY(req))
-		return 0;
-	return nfs_wait_event(clnt, req->wb_context->waitq, !NFS_WBACK_BUSY(req));
+        struct rpc_clnt	*clnt = NFS_CLIENT(req->wb_context->dentry->d_inode);
+	sigset_t oldmask;
+	int ret = 0;
+
+	if (!test_bit(PG_BUSY, &req->wb_flags))
+		goto out;
+	/*
+	 * Note: the call to rpc_clnt_sigmask() suffices to ensure that we
+	 *	 are not interrupted if intr flag is not set
+	 */
+	rpc_clnt_sigmask(clnt, &oldmask);
+	ret = out_of_line_wait_on_bit(&req->wb_flags, PG_BUSY,
+			nfs_wait_bit_interruptible, TASK_INTERRUPTIBLE);
+	rpc_clnt_sigunmask(clnt, &oldmask);
+out:
+	return ret;
 }
 
 /**
@@ -243,6 +261,62 @@ nfs_coalesce_requests(struct list_head *
 	return npages;
 }
 
+#define NFS_SCAN_MAXENTRIES 16
+/**
+ * nfs_scan_lock_dirty - Scan the radix tree for dirty requests
+ * @nfsi: NFS inode
+ * @dst: Destination list
+ * @idx_start: lower bound of page->index to scan
+ * @npages: idx_start + npages sets the upper bound to scan.
+ *
+ * Moves elements from one of the inode request lists.
+ * If the number of requests is set to 0, the entire address_space
+ * starting at index idx_start, is scanned.
+ * The requests are *not* checked to ensure that they form a contiguous set.
+ * You must be holding the inode's req_lock when calling this function
+ */
+int
+nfs_scan_lock_dirty(struct nfs_inode *nfsi, struct list_head *dst,
+	      unsigned long idx_start, unsigned int npages)
+{
+	struct nfs_page *pgvec[NFS_SCAN_MAXENTRIES];
+	struct nfs_page *req;
+	unsigned long idx_end;
+	int found, i;
+	int res;
+
+	res = 0;
+	if (npages == 0)
+		idx_end = ~0;
+	else
+		idx_end = idx_start + npages - 1;
+
+	for (;;) {
+		found = radix_tree_gang_lookup_tag(&nfsi->nfs_page_tree,
+				(void **)&pgvec[0], idx_start, NFS_SCAN_MAXENTRIES,
+				NFS_PAGE_TAG_DIRTY);
+		if (found <= 0)
+			break;
+		for (i = 0; i < found; i++) {
+			req = pgvec[i];
+			if (req->wb_index > idx_end)
+				goto out;
+
+			idx_start = req->wb_index + 1;
+
+			if (nfs_set_page_writeback_locked(req)) {
+				radix_tree_tag_clear(&nfsi->nfs_page_tree,
+						req->wb_index, NFS_PAGE_TAG_DIRTY);
+				nfs_list_remove_request(req);
+				nfs_list_add_request(req, dst);
+				res++;
+			}
+		}
+	}
+out:
+	return res;
+}
+
 /**
  * nfs_scan_list - Scan a list for matching requests
  * @head: One of the NFS inode request lists
@@ -280,7 +354,7 @@ nfs_scan_list(struct list_head *head, st
 		if (req->wb_index > idx_end)
 			break;
 
-		if (!nfs_lock_request(req))
+		if (!nfs_set_page_writeback_locked(req))
 			continue;
 		nfs_list_remove_request(req);
 		nfs_list_add_request(req, dst);
diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c
--- a/fs/nfs/proc.c
+++ b/fs/nfs/proc.c
@@ -114,6 +114,8 @@ nfs_proc_setattr(struct dentry *dentry, 
 	dprintk("NFS call  setattr\n");
 	fattr->valid = 0;
 	status = rpc_call(NFS_CLIENT(inode), NFSPROC_SETATTR, &arg, fattr, 0);
+	if (status == 0)
+		nfs_setattr_update_inode(inode, sattr);
 	dprintk("NFS reply setattr: %d\n", status);
 	return status;
 }
@@ -622,6 +624,7 @@ struct nfs_rpc_ops	nfs_v2_clientops = {
 	.version	= 2,		       /* protocol version */
 	.dentry_ops	= &nfs_dentry_operations,
 	.dir_inode_ops	= &nfs_dir_inode_operations,
+	.file_inode_ops	= &nfs_file_inode_operations,
 	.getroot	= nfs_proc_get_root,
 	.getattr	= nfs_proc_getattr,
 	.setattr	= nfs_proc_setattr,
diff --git a/fs/nfs/read.c b/fs/nfs/read.c
--- a/fs/nfs/read.c
+++ b/fs/nfs/read.c
@@ -140,7 +140,9 @@ static int nfs_readpage_sync(struct nfs_
 		if (rdata->res.eof != 0 || result == 0)
 			break;
 	} while (count);
-	NFS_FLAGS(inode) |= NFS_INO_INVALID_ATIME;
+	spin_lock(&inode->i_lock);
+	NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ATIME;
+	spin_unlock(&inode->i_lock);
 
 	if (count)
 		memclear_highpage_flush(page, rdata->args.pgbase, count);
@@ -173,7 +175,6 @@ static int nfs_readpage_async(struct nfs
 	if (len < PAGE_CACHE_SIZE)
 		memclear_highpage_flush(page, len, PAGE_CACHE_SIZE - len);
 
-	nfs_lock_request(new);
 	nfs_list_add_request(new, &one_request);
 	nfs_pagein_one(&one_request, inode);
 	return 0;
@@ -185,7 +186,6 @@ static void nfs_readpage_release(struct 
 
 	nfs_clear_request(req);
 	nfs_release_request(req);
-	nfs_unlock_request(req);
 
 	dprintk("NFS: read done (%s/%Ld %d@%Ld)\n",
 			req->wb_context->dentry->d_inode->i_sb->s_id,
@@ -475,7 +475,9 @@ void nfs_readpage_result(struct rpc_task
 		}
 		task->tk_status = -EIO;
 	}
-	NFS_FLAGS(data->inode) |= NFS_INO_INVALID_ATIME;
+	spin_lock(&data->inode->i_lock);
+	NFS_I(data->inode)->cache_validity |= NFS_INO_INVALID_ATIME;
+	spin_unlock(&data->inode->i_lock);
 	data->complete(data, status);
 }
 
@@ -553,7 +555,6 @@ readpage_async_filler(void *data, struct
 	}
 	if (len < PAGE_CACHE_SIZE)
 		memclear_highpage_flush(page, len, PAGE_CACHE_SIZE - len);
-	nfs_lock_request(new);
 	nfs_list_add_request(new, desc->head);
 	return 0;
 }
diff --git a/fs/nfs/symlink.c b/fs/nfs/symlink.c
--- a/fs/nfs/symlink.c
+++ b/fs/nfs/symlink.c
@@ -27,26 +27,14 @@
 
 /* Symlink caching in the page cache is even more simplistic
  * and straight-forward than readdir caching.
- *
- * At the beginning of the page we store pointer to struct page in question,
- * simplifying nfs_put_link() (if inode got invalidated we can't find the page
- * to be freed via pagecache lookup).
- * The NUL-terminated string follows immediately thereafter.
  */
 
-struct nfs_symlink {
-	struct page *page;
-	char body[0];
-};
-
 static int nfs_symlink_filler(struct inode *inode, struct page *page)
 {
-	const unsigned int pgbase = offsetof(struct nfs_symlink, body);
-	const unsigned int pglen = PAGE_SIZE - pgbase;
 	int error;
 
 	lock_kernel();
-	error = NFS_PROTO(inode)->readlink(inode, page, pgbase, pglen);
+	error = NFS_PROTO(inode)->readlink(inode, page, 0, PAGE_SIZE);
 	unlock_kernel();
 	if (error < 0)
 		goto error;
@@ -60,11 +48,10 @@ error:
 	return -EIO;
 }
 
-static int nfs_follow_link(struct dentry *dentry, struct nameidata *nd)
+static void *nfs_follow_link(struct dentry *dentry, struct nameidata *nd)
 {
 	struct inode *inode = dentry->d_inode;
 	struct page *page;
-	struct nfs_symlink *p;
 	void *err = ERR_PTR(nfs_revalidate_inode(NFS_SERVER(inode), inode));
 	if (err)
 		goto read_failed;
@@ -78,28 +65,20 @@ static int nfs_follow_link(struct dentry
 		err = ERR_PTR(-EIO);
 		goto getlink_read_error;
 	}
-	p = kmap(page);
-	p->page = page;
-	nd_set_link(nd, p->body);
-	return 0;
+	nd_set_link(nd, kmap(page));
+	return page;
 
 getlink_read_error:
 	page_cache_release(page);
 read_failed:
 	nd_set_link(nd, err);
-	return 0;
+	return NULL;
 }
 
-static void nfs_put_link(struct dentry *dentry, struct nameidata *nd)
+static void nfs_put_link(struct dentry *dentry, struct nameidata *nd, void *cookie)
 {
-	char *s = nd_get_link(nd);
-	if (!IS_ERR(s)) {
-		struct nfs_symlink *p;
-		struct page *page;
-
-		p = container_of(s, struct nfs_symlink, body[0]);
-		page = p->page;
-
+	if (cookie) {
+		struct page *page = cookie;
 		kunmap(page);
 		page_cache_release(page);
 	}
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -220,7 +220,7 @@ static int nfs_writepage_sync(struct nfs
 		ClearPageError(page);
 
 io_error:
-	nfs_end_data_update_defer(inode);
+	nfs_end_data_update(inode);
 	nfs_writedata_free(wdata);
 	return written ? written : result;
 }
@@ -352,7 +352,7 @@ int nfs_writepages(struct address_space 
 		if (err < 0)
 			goto out;
 	}
-	err = nfs_commit_inode(inode, 0, 0, wb_priority(wbc));
+	err = nfs_commit_inode(inode, wb_priority(wbc));
 	if (err > 0) {
 		wbc->nr_to_write -= err;
 		err = 0;
@@ -401,7 +401,7 @@ static void nfs_inode_remove_request(str
 	nfsi->npages--;
 	if (!nfsi->npages) {
 		spin_unlock(&nfsi->req_lock);
-		nfs_end_data_update_defer(inode);
+		nfs_end_data_update(inode);
 		iput(inode);
 	} else
 		spin_unlock(&nfsi->req_lock);
@@ -446,6 +446,8 @@ nfs_mark_request_dirty(struct nfs_page *
 	struct nfs_inode *nfsi = NFS_I(inode);
 
 	spin_lock(&nfsi->req_lock);
+	radix_tree_tag_set(&nfsi->nfs_page_tree,
+			req->wb_index, NFS_PAGE_TAG_DIRTY);
 	nfs_list_add_request(req, &nfsi->dirty);
 	nfsi->ndirty++;
 	spin_unlock(&nfsi->req_lock);
@@ -503,13 +505,12 @@ nfs_wait_on_requests(struct inode *inode
 
 	spin_lock(&nfsi->req_lock);
 	next = idx_start;
-	while (radix_tree_gang_lookup(&nfsi->nfs_page_tree, (void **)&req, next, 1)) {
+	while (radix_tree_gang_lookup_tag(&nfsi->nfs_page_tree, (void **)&req, next, 1, NFS_PAGE_TAG_WRITEBACK)) {
 		if (req->wb_index > idx_end)
 			break;
 
 		next = req->wb_index + 1;
-		if (!NFS_WBACK_BUSY(req))
-			continue;
+		BUG_ON(!NFS_WBACK_BUSY(req));
 
 		atomic_inc(&req->wb_count);
 		spin_unlock(&nfsi->req_lock);
@@ -538,12 +539,15 @@ static int
 nfs_scan_dirty(struct inode *inode, struct list_head *dst, unsigned long idx_start, unsigned int npages)
 {
 	struct nfs_inode *nfsi = NFS_I(inode);
-	int	res;
-	res = nfs_scan_list(&nfsi->dirty, dst, idx_start, npages);
-	nfsi->ndirty -= res;
-	sub_page_state(nr_dirty,res);
-	if ((nfsi->ndirty == 0) != list_empty(&nfsi->dirty))
-		printk(KERN_ERR "NFS: desynchronized value of nfs_i.ndirty.\n");
+	int res = 0;
+
+	if (nfsi->ndirty != 0) {
+		res = nfs_scan_lock_dirty(nfsi, dst, idx_start, npages);
+		nfsi->ndirty -= res;
+		sub_page_state(nr_dirty,res);
+		if ((nfsi->ndirty == 0) != list_empty(&nfsi->dirty))
+			printk(KERN_ERR "NFS: desynchronized value of nfs_i.ndirty.\n");
+	}
 	return res;
 }
 
@@ -562,11 +566,14 @@ static int
 nfs_scan_commit(struct inode *inode, struct list_head *dst, unsigned long idx_start, unsigned int npages)
 {
 	struct nfs_inode *nfsi = NFS_I(inode);
-	int	res;
-	res = nfs_scan_list(&nfsi->commit, dst, idx_start, npages);
-	nfsi->ncommit -= res;
-	if ((nfsi->ncommit == 0) != list_empty(&nfsi->commit))
-		printk(KERN_ERR "NFS: desynchronized value of nfs_i.ncommit.\n");
+	int res = 0;
+
+	if (nfsi->ncommit != 0) {
+		res = nfs_scan_list(&nfsi->commit, dst, idx_start, npages);
+		nfsi->ncommit -= res;
+		if ((nfsi->ncommit == 0) != list_empty(&nfsi->commit))
+			printk(KERN_ERR "NFS: desynchronized value of nfs_i.ncommit.\n");
+	}
 	return res;
 }
 #endif
@@ -750,7 +757,7 @@ int nfs_updatepage(struct file *file, st
 	 * is entirely in cache, it may be more efficient to avoid
 	 * fragmenting write requests.
 	 */
-	if (PageUptodate(page) && inode->i_flock == NULL) {
+	if (PageUptodate(page) && inode->i_flock == NULL && !(file->f_mode & O_SYNC)) {
 		loff_t end_offs = i_size_read(inode) - 1;
 		unsigned long end_index = end_offs >> PAGE_CACHE_SHIFT;
 
@@ -821,7 +828,7 @@ out:
 #else
 	nfs_inode_remove_request(req);
 #endif
-	nfs_unlock_request(req);
+	nfs_clear_page_writeback(req);
 }
 
 static inline int flush_task_priority(int how)
@@ -952,7 +959,7 @@ out_bad:
 		nfs_writedata_free(data);
 	}
 	nfs_mark_request_dirty(req);
-	nfs_unlock_request(req);
+	nfs_clear_page_writeback(req);
 	return -ENOMEM;
 }
 
@@ -1002,7 +1009,7 @@ static int nfs_flush_one(struct list_hea
 		struct nfs_page *req = nfs_list_entry(head->next);
 		nfs_list_remove_request(req);
 		nfs_mark_request_dirty(req);
-		nfs_unlock_request(req);
+		nfs_clear_page_writeback(req);
 	}
 	return -ENOMEM;
 }
@@ -1029,7 +1036,7 @@ nfs_flush_list(struct list_head *head, i
 		req = nfs_list_entry(head->next);
 		nfs_list_remove_request(req);
 		nfs_mark_request_dirty(req);
-		nfs_unlock_request(req);
+		nfs_clear_page_writeback(req);
 	}
 	return error;
 }
@@ -1121,7 +1128,7 @@ static void nfs_writeback_done_full(stru
 		nfs_inode_remove_request(req);
 #endif
 	next:
-		nfs_unlock_request(req);
+		nfs_clear_page_writeback(req);
 	}
 }
 
@@ -1210,36 +1217,24 @@ static void nfs_commit_rpcsetup(struct l
 		struct nfs_write_data *data, int how)
 {
 	struct rpc_task		*task = &data->task;
-	struct nfs_page		*first, *last;
+	struct nfs_page		*first;
 	struct inode		*inode;
-	loff_t			start, end, len;
 
 	/* Set up the RPC argument and reply structs
 	 * NB: take care not to mess about with data->commit et al. */
 
 	list_splice_init(head, &data->pages);
 	first = nfs_list_entry(data->pages.next);
-	last = nfs_list_entry(data->pages.prev);
 	inode = first->wb_context->dentry->d_inode;
 
-	/*
-	 * Determine the offset range of requests in the COMMIT call.
-	 * We rely on the fact that data->pages is an ordered list...
-	 */
-	start = req_offset(first);
-	end = req_offset(last) + last->wb_bytes;
-	len = end - start;
-	/* If 'len' is not a 32-bit quantity, pass '0' in the COMMIT call */
-	if (end >= i_size_read(inode) || len < 0 || len > (~((u32)0) >> 1))
-		len = 0;
-
 	data->inode	  = inode;
 	data->cred	  = first->wb_context->cred;
 
 	data->args.fh     = NFS_FH(data->inode);
-	data->args.offset = start;
-	data->args.count  = len;
-	data->res.count   = len;
+	/* Note: we always request a commit of the entire inode */
+	data->args.offset = 0;
+	data->args.count  = 0;
+	data->res.count   = 0;
 	data->res.fattr   = &data->fattr;
 	data->res.verf    = &data->verf;
 	
@@ -1278,7 +1273,7 @@ nfs_commit_list(struct list_head *head, 
 		req = nfs_list_entry(head->next);
 		nfs_list_remove_request(req);
 		nfs_mark_request_commit(req);
-		nfs_unlock_request(req);
+		nfs_clear_page_writeback(req);
 	}
 	return -ENOMEM;
 }
@@ -1324,7 +1319,7 @@ nfs_commit_done(struct rpc_task *task)
 		dprintk(" mismatch\n");
 		nfs_mark_request_dirty(req);
 	next:
-		nfs_unlock_request(req);
+		nfs_clear_page_writeback(req);
 		res++;
 	}
 	sub_page_state(nr_unstable,res);
@@ -1342,16 +1337,23 @@ static int nfs_flush_inode(struct inode 
 	spin_lock(&nfsi->req_lock);
 	res = nfs_scan_dirty(inode, &head, idx_start, npages);
 	spin_unlock(&nfsi->req_lock);
-	if (res)
-		error = nfs_flush_list(&head, NFS_SERVER(inode)->wpages, how);
+	if (res) {
+		struct nfs_server *server = NFS_SERVER(inode);
+
+		/* For single writes, FLUSH_STABLE is more efficient */
+		if (res == nfsi->npages && nfsi->npages <= server->wpages) {
+			if (res > 1 || nfs_list_entry(head.next)->wb_bytes <= server->wsize)
+				how |= FLUSH_STABLE;
+		}
+		error = nfs_flush_list(&head, server->wpages, how);
+	}
 	if (error < 0)
 		return error;
 	return res;
 }
 
 #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
-int nfs_commit_inode(struct inode *inode, unsigned long idx_start,
-		    unsigned int npages, int how)
+int nfs_commit_inode(struct inode *inode, int how)
 {
 	struct nfs_inode *nfsi = NFS_I(inode);
 	LIST_HEAD(head);
@@ -1359,15 +1361,13 @@ int nfs_commit_inode(struct inode *inode
 				error = 0;
 
 	spin_lock(&nfsi->req_lock);
-	res = nfs_scan_commit(inode, &head, idx_start, npages);
+	res = nfs_scan_commit(inode, &head, 0, 0);
+	spin_unlock(&nfsi->req_lock);
 	if (res) {
-		res += nfs_scan_commit(inode, &head, 0, 0);
-		spin_unlock(&nfsi->req_lock);
 		error = nfs_commit_list(&head, how);
-	} else
-		spin_unlock(&nfsi->req_lock);
-	if (error < 0)
-		return error;
+		if (error < 0)
+			return error;
+	}
 	return res;
 }
 #endif
@@ -1389,7 +1389,7 @@ int nfs_sync_inode(struct inode *inode, 
 			error = nfs_flush_inode(inode, idx_start, npages, how);
 #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
 		if (error == 0)
-			error = nfs_commit_inode(inode, idx_start, npages, how);
+			error = nfs_commit_inode(inode, how);
 #endif
 	} while (error > 0);
 	return error;
diff --git a/fs/nfs_common/Makefile b/fs/nfs_common/Makefile
new file mode 100644
--- /dev/null
+++ b/fs/nfs_common/Makefile
@@ -0,0 +1,7 @@
+#
+# Makefile for Linux filesystem routines that are shared by client and server.
+#
+
+obj-$(CONFIG_NFS_ACL_SUPPORT) += nfs_acl.o
+
+nfs_acl-objs := nfsacl.o
diff --git a/fs/nfs_common/nfsacl.c b/fs/nfs_common/nfsacl.c
new file mode 100644
--- /dev/null
+++ b/fs/nfs_common/nfsacl.c
@@ -0,0 +1,258 @@
+/*
+ * fs/nfs_common/nfsacl.c
+ *
+ *  Copyright (C) 2002-2003 Andreas Gruenbacher <agruen@suse.de>
+ */
+
+/*
+ * The Solaris nfsacl protocol represents some ACLs slightly differently
+ * than POSIX 1003.1e draft 17 does (and we do):
+ *
+ *  - Minimal ACLs always have an ACL_MASK entry, so they have
+ *    four instead of three entries.
+ *  - The ACL_MASK entry in such minimal ACLs always has the same
+ *    permissions as the ACL_GROUP_OBJ entry. (In extended ACLs
+ *    the ACL_MASK and ACL_GROUP_OBJ entries may differ.)
+ *  - The identifier fields of the ACL_USER_OBJ and ACL_GROUP_OBJ
+ *    entries contain the identifiers of the owner and owning group.
+ *    (In POSIX ACLs we always set them to ACL_UNDEFINED_ID).
+ *  - ACL entries in the kernel are kept sorted in ascending order
+ *    of (e_tag, e_id). Solaris ACLs are unsorted.
+ */
+
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/sunrpc/xdr.h>
+#include <linux/nfsacl.h>
+#include <linux/nfs3.h>
+#include <linux/sort.h>
+
+MODULE_LICENSE("GPL");
+
+EXPORT_SYMBOL(nfsacl_encode);
+EXPORT_SYMBOL(nfsacl_decode);
+
+struct nfsacl_encode_desc {
+	struct xdr_array2_desc desc;
+	unsigned int count;
+	struct posix_acl *acl;
+	int typeflag;
+	uid_t uid;
+	gid_t gid;
+};
+
+static int
+xdr_nfsace_encode(struct xdr_array2_desc *desc, void *elem)
+{
+	struct nfsacl_encode_desc *nfsacl_desc =
+		(struct nfsacl_encode_desc *) desc;
+	u32 *p = (u32 *) elem;
+
+	if (nfsacl_desc->count < nfsacl_desc->acl->a_count) {
+		struct posix_acl_entry *entry =
+			&nfsacl_desc->acl->a_entries[nfsacl_desc->count++];
+
+		*p++ = htonl(entry->e_tag | nfsacl_desc->typeflag);
+		switch(entry->e_tag) {
+			case ACL_USER_OBJ:
+				*p++ = htonl(nfsacl_desc->uid);
+				break;
+			case ACL_GROUP_OBJ:
+				*p++ = htonl(nfsacl_desc->gid);
+				break;
+			case ACL_USER:
+			case ACL_GROUP:
+				*p++ = htonl(entry->e_id);
+				break;
+			default:  /* Solaris depends on that! */
+				*p++ = 0;
+				break;
+		}
+		*p++ = htonl(entry->e_perm & S_IRWXO);
+	} else {
+		const struct posix_acl_entry *pa, *pe;
+		int group_obj_perm = ACL_READ|ACL_WRITE|ACL_EXECUTE;
+
+		FOREACH_ACL_ENTRY(pa, nfsacl_desc->acl, pe) {
+			if (pa->e_tag == ACL_GROUP_OBJ) {
+				group_obj_perm = pa->e_perm & S_IRWXO;
+				break;
+			}
+		}
+		/* fake up ACL_MASK entry */
+		*p++ = htonl(ACL_MASK | nfsacl_desc->typeflag);
+		*p++ = htonl(0);
+		*p++ = htonl(group_obj_perm);
+	}
+
+	return 0;
+}
+
+unsigned int
+nfsacl_encode(struct xdr_buf *buf, unsigned int base, struct inode *inode,
+	      struct posix_acl *acl, int encode_entries, int typeflag)
+{
+	int entries = (acl && acl->a_count) ? max_t(int, acl->a_count, 4) : 0;
+	struct nfsacl_encode_desc nfsacl_desc = {
+		.desc = {
+			.elem_size = 12,
+			.array_len = encode_entries ? entries : 0,
+			.xcode = xdr_nfsace_encode,
+		},
+		.acl = acl,
+		.typeflag = typeflag,
+		.uid = inode->i_uid,
+		.gid = inode->i_gid,
+	};
+	int err;
+
+	if (entries > NFS_ACL_MAX_ENTRIES ||
+	    xdr_encode_word(buf, base, entries))
+		return -EINVAL;
+	err = xdr_encode_array2(buf, base + 4, &nfsacl_desc.desc);
+	if (!err)
+		err = 8 + nfsacl_desc.desc.elem_size *
+			  nfsacl_desc.desc.array_len;
+	return err;
+}
+
+struct nfsacl_decode_desc {
+	struct xdr_array2_desc desc;
+	unsigned int count;
+	struct posix_acl *acl;
+};
+
+static int
+xdr_nfsace_decode(struct xdr_array2_desc *desc, void *elem)
+{
+	struct nfsacl_decode_desc *nfsacl_desc =
+		(struct nfsacl_decode_desc *) desc;
+	u32 *p = (u32 *) elem;
+	struct posix_acl_entry *entry;
+
+	if (!nfsacl_desc->acl) {
+		if (desc->array_len > NFS_ACL_MAX_ENTRIES)
+			return -EINVAL;
+		nfsacl_desc->acl = posix_acl_alloc(desc->array_len, GFP_KERNEL);
+		if (!nfsacl_desc->acl)
+			return -ENOMEM;
+		nfsacl_desc->count = 0;
+	}
+
+	entry = &nfsacl_desc->acl->a_entries[nfsacl_desc->count++];
+	entry->e_tag = ntohl(*p++) & ~NFS_ACL_DEFAULT;
+	entry->e_id = ntohl(*p++);
+	entry->e_perm = ntohl(*p++);
+
+	switch(entry->e_tag) {
+		case ACL_USER_OBJ:
+		case ACL_USER:
+		case ACL_GROUP_OBJ:
+		case ACL_GROUP:
+		case ACL_OTHER:
+			if (entry->e_perm & ~S_IRWXO)
+				return -EINVAL;
+			break;
+		case ACL_MASK:
+			/* Solaris sometimes sets additonal bits in the mask */
+			entry->e_perm &= S_IRWXO;
+			break;
+		default:
+			return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int
+cmp_acl_entry(const void *x, const void *y)
+{
+	const struct posix_acl_entry *a = x, *b = y;
+
+	if (a->e_tag != b->e_tag)
+		return a->e_tag - b->e_tag;
+	else if (a->e_id > b->e_id)
+		return 1;
+	else if (a->e_id < b->e_id)
+		return -1;
+	else
+		return 0;
+}
+
+/*
+ * Convert from a Solaris ACL to a POSIX 1003.1e draft 17 ACL.
+ */
+static int
+posix_acl_from_nfsacl(struct posix_acl *acl)
+{
+	struct posix_acl_entry *pa, *pe,
+	       *group_obj = NULL, *mask = NULL;
+
+	if (!acl)
+		return 0;
+
+	sort(acl->a_entries, acl->a_count, sizeof(struct posix_acl_entry),
+	     cmp_acl_entry, NULL);
+
+	/* Clear undefined identifier fields and find the ACL_GROUP_OBJ
+	   and ACL_MASK entries. */
+	FOREACH_ACL_ENTRY(pa, acl, pe) {
+		switch(pa->e_tag) {
+			case ACL_USER_OBJ:
+				pa->e_id = ACL_UNDEFINED_ID;
+				break;
+			case ACL_GROUP_OBJ:
+				pa->e_id = ACL_UNDEFINED_ID;
+				group_obj = pa;
+				break;
+			case ACL_MASK:
+				mask = pa;
+				/* fall through */
+			case ACL_OTHER:
+				pa->e_id = ACL_UNDEFINED_ID;
+				break;
+		}
+	}
+	if (acl->a_count == 4 && group_obj && mask &&
+	    mask->e_perm == group_obj->e_perm) {
+		/* remove bogus ACL_MASK entry */
+		memmove(mask, mask+1, (3 - (mask - acl->a_entries)) *
+				      sizeof(struct posix_acl_entry));
+		acl->a_count = 3;
+	}
+	return 0;
+}
+
+unsigned int
+nfsacl_decode(struct xdr_buf *buf, unsigned int base, unsigned int *aclcnt,
+	      struct posix_acl **pacl)
+{
+	struct nfsacl_decode_desc nfsacl_desc = {
+		.desc = {
+			.elem_size = 12,
+			.xcode = pacl ? xdr_nfsace_decode : NULL,
+		},
+	};
+	u32 entries;
+	int err;
+
+	if (xdr_decode_word(buf, base, &entries) ||
+	    entries > NFS_ACL_MAX_ENTRIES)
+		return -EINVAL;
+	nfsacl_desc.desc.array_maxlen = entries;
+	err = xdr_decode_array2(buf, base + 4, &nfsacl_desc.desc);
+	if (err)
+		return err;
+	if (pacl) {
+		if (entries != nfsacl_desc.desc.array_len ||
+		    posix_acl_from_nfsacl(nfsacl_desc.acl) != 0) {
+			posix_acl_release(nfsacl_desc.acl);
+			return -EINVAL;
+		}
+		*pacl = nfsacl_desc.acl;
+	}
+	if (aclcnt)
+		*aclcnt = entries;
+	return 8 + nfsacl_desc.desc.elem_size *
+		   nfsacl_desc.desc.array_len;
+}
diff --git a/fs/nfsd/Makefile b/fs/nfsd/Makefile
--- a/fs/nfsd/Makefile
+++ b/fs/nfsd/Makefile
@@ -6,7 +6,9 @@ obj-$(CONFIG_NFSD)	+= nfsd.o
 
 nfsd-y 			:= nfssvc.o nfsctl.o nfsproc.o nfsfh.o vfs.o \
 			   export.o auth.o lockd.o nfscache.o nfsxdr.o stats.o
+nfsd-$(CONFIG_NFSD_V2_ACL) += nfs2acl.o
 nfsd-$(CONFIG_NFSD_V3)	+= nfs3proc.o nfs3xdr.o
+nfsd-$(CONFIG_NFSD_V3_ACL) += nfs3acl.o
 nfsd-$(CONFIG_NFSD_V4)	+= nfs4proc.o nfs4xdr.o nfs4state.o nfs4idmap.o \
-			   nfs4acl.o nfs4callback.o
+			   nfs4acl.o nfs4callback.o nfs4recover.o
 nfsd-objs		:= $(nfsd-y)
diff --git a/fs/nfsd/nfs2acl.c b/fs/nfsd/nfs2acl.c
new file mode 100644
--- /dev/null
+++ b/fs/nfsd/nfs2acl.c
@@ -0,0 +1,336 @@
+/*
+ * linux/fs/nfsd/nfsacl.c
+ *
+ * Process version 2 NFSACL requests.
+ *
+ * Copyright (C) 2002-2003 Andreas Gruenbacher <agruen@suse.de>
+ */
+
+#include <linux/sunrpc/svc.h>
+#include <linux/nfs.h>
+#include <linux/nfsd/nfsd.h>
+#include <linux/nfsd/cache.h>
+#include <linux/nfsd/xdr.h>
+#include <linux/nfsd/xdr3.h>
+#include <linux/posix_acl.h>
+#include <linux/nfsacl.h>
+
+#define NFSDDBG_FACILITY		NFSDDBG_PROC
+#define RETURN_STATUS(st)	{ resp->status = (st); return (st); }
+
+/*
+ * NULL call.
+ */
+static int
+nfsacld_proc_null(struct svc_rqst *rqstp, void *argp, void *resp)
+{
+	return nfs_ok;
+}
+
+/*
+ * Get the Access and/or Default ACL of a file.
+ */
+static int nfsacld_proc_getacl(struct svc_rqst * rqstp,
+		struct nfsd3_getaclargs *argp, struct nfsd3_getaclres *resp)
+{
+	svc_fh *fh;
+	struct posix_acl *acl;
+	int nfserr = 0;
+
+	dprintk("nfsd: GETACL(2acl)   %s\n", SVCFH_fmt(&argp->fh));
+
+	fh = fh_copy(&resp->fh, &argp->fh);
+	if ((nfserr = fh_verify(rqstp, &resp->fh, 0, MAY_NOP)))
+		RETURN_STATUS(nfserr_inval);
+
+	if (argp->mask & ~(NFS_ACL|NFS_ACLCNT|NFS_DFACL|NFS_DFACLCNT))
+		RETURN_STATUS(nfserr_inval);
+	resp->mask = argp->mask;
+
+	if (resp->mask & (NFS_ACL|NFS_ACLCNT)) {
+		acl = nfsd_get_posix_acl(fh, ACL_TYPE_ACCESS);
+		if (IS_ERR(acl)) {
+			int err = PTR_ERR(acl);
+
+			if (err == -ENODATA || err == -EOPNOTSUPP)
+				acl = NULL;
+			else {
+				nfserr = nfserrno(err);
+				goto fail;
+			}
+		}
+		if (acl == NULL) {
+			/* Solaris returns the inode's minimum ACL. */
+
+			struct inode *inode = fh->fh_dentry->d_inode;
+			acl = posix_acl_from_mode(inode->i_mode, GFP_KERNEL);
+		}
+		resp->acl_access = acl;
+	}
+	if (resp->mask & (NFS_DFACL|NFS_DFACLCNT)) {
+		/* Check how Solaris handles requests for the Default ACL
+		   of a non-directory! */
+
+		acl = nfsd_get_posix_acl(fh, ACL_TYPE_DEFAULT);
+		if (IS_ERR(acl)) {
+			int err = PTR_ERR(acl);
+
+			if (err == -ENODATA || err == -EOPNOTSUPP)
+				acl = NULL;
+			else {
+				nfserr = nfserrno(err);
+				goto fail;
+			}
+		}
+		resp->acl_default = acl;
+	}
+
+	/* resp->acl_{access,default} are released in nfssvc_release_getacl. */
+	RETURN_STATUS(0);
+
+fail:
+	posix_acl_release(resp->acl_access);
+	posix_acl_release(resp->acl_default);
+	RETURN_STATUS(nfserr);
+}
+
+/*
+ * Set the Access and/or Default ACL of a file.
+ */
+static int nfsacld_proc_setacl(struct svc_rqst * rqstp,
+		struct nfsd3_setaclargs *argp,
+		struct nfsd_attrstat *resp)
+{
+	svc_fh *fh;
+	int nfserr = 0;
+
+	dprintk("nfsd: SETACL(2acl)   %s\n", SVCFH_fmt(&argp->fh));
+
+	fh = fh_copy(&resp->fh, &argp->fh);
+	nfserr = fh_verify(rqstp, &resp->fh, 0, MAY_NOP);
+
+	if (!nfserr) {
+		nfserr = nfserrno( nfsd_set_posix_acl(
+			fh, ACL_TYPE_ACCESS, argp->acl_access) );
+	}
+	if (!nfserr) {
+		nfserr = nfserrno( nfsd_set_posix_acl(
+			fh, ACL_TYPE_DEFAULT, argp->acl_default) );
+	}
+
+	/* argp->acl_{access,default} may have been allocated in
+	   nfssvc_decode_setaclargs. */
+	posix_acl_release(argp->acl_access);
+	posix_acl_release(argp->acl_default);
+	return nfserr;
+}
+
+/*
+ * Check file attributes
+ */
+static int nfsacld_proc_getattr(struct svc_rqst * rqstp,
+		struct nfsd_fhandle *argp, struct nfsd_attrstat *resp)
+{
+	dprintk("nfsd: GETATTR  %s\n", SVCFH_fmt(&argp->fh));
+
+	fh_copy(&resp->fh, &argp->fh);
+	return fh_verify(rqstp, &resp->fh, 0, MAY_NOP);
+}
+
+/*
+ * Check file access
+ */
+static int nfsacld_proc_access(struct svc_rqst *rqstp, struct nfsd3_accessargs *argp,
+		struct nfsd3_accessres *resp)
+{
+	int nfserr;
+
+	dprintk("nfsd: ACCESS(2acl)   %s 0x%x\n",
+			SVCFH_fmt(&argp->fh),
+			argp->access);
+
+	fh_copy(&resp->fh, &argp->fh);
+	resp->access = argp->access;
+	nfserr = nfsd_access(rqstp, &resp->fh, &resp->access, NULL);
+	return nfserr;
+}
+
+/*
+ * XDR decode functions
+ */
+static int nfsaclsvc_decode_getaclargs(struct svc_rqst *rqstp, u32 *p,
+		struct nfsd3_getaclargs *argp)
+{
+	if (!(p = nfs2svc_decode_fh(p, &argp->fh)))
+		return 0;
+	argp->mask = ntohl(*p); p++;
+
+	return xdr_argsize_check(rqstp, p);
+}
+
+
+static int nfsaclsvc_decode_setaclargs(struct svc_rqst *rqstp, u32 *p,
+		struct nfsd3_setaclargs *argp)
+{
+	struct kvec *head = rqstp->rq_arg.head;
+	unsigned int base;
+	int n;
+
+	if (!(p = nfs2svc_decode_fh(p, &argp->fh)))
+		return 0;
+	argp->mask = ntohl(*p++);
+	if (argp->mask & ~(NFS_ACL|NFS_ACLCNT|NFS_DFACL|NFS_DFACLCNT) ||
+	    !xdr_argsize_check(rqstp, p))
+		return 0;
+
+	base = (char *)p - (char *)head->iov_base;
+	n = nfsacl_decode(&rqstp->rq_arg, base, NULL,
+			  (argp->mask & NFS_ACL) ?
+			  &argp->acl_access : NULL);
+	if (n > 0)
+		n = nfsacl_decode(&rqstp->rq_arg, base + n, NULL,
+				  (argp->mask & NFS_DFACL) ?
+				  &argp->acl_default : NULL);
+	return (n > 0);
+}
+
+static int nfsaclsvc_decode_fhandleargs(struct svc_rqst *rqstp, u32 *p,
+		struct nfsd_fhandle *argp)
+{
+	if (!(p = nfs2svc_decode_fh(p, &argp->fh)))
+		return 0;
+	return xdr_argsize_check(rqstp, p);
+}
+
+static int nfsaclsvc_decode_accessargs(struct svc_rqst *rqstp, u32 *p,
+		struct nfsd3_accessargs *argp)
+{
+	if (!(p = nfs2svc_decode_fh(p, &argp->fh)))
+		return 0;
+	argp->access = ntohl(*p++);
+
+	return xdr_argsize_check(rqstp, p);
+}
+
+/*
+ * XDR encode functions
+ */
+
+/* GETACL */
+static int nfsaclsvc_encode_getaclres(struct svc_rqst *rqstp, u32 *p,
+		struct nfsd3_getaclres *resp)
+{
+	struct dentry *dentry = resp->fh.fh_dentry;
+	struct inode *inode = dentry->d_inode;
+	int w = nfsacl_size(
+		(resp->mask & NFS_ACL)   ? resp->acl_access  : NULL,
+		(resp->mask & NFS_DFACL) ? resp->acl_default : NULL);
+	struct kvec *head = rqstp->rq_res.head;
+	unsigned int base;
+	int n;
+
+	if (dentry == NULL || dentry->d_inode == NULL)
+		return 0;
+	inode = dentry->d_inode;
+
+	p = nfs2svc_encode_fattr(rqstp, p, &resp->fh);
+	*p++ = htonl(resp->mask);
+	if (!xdr_ressize_check(rqstp, p))
+		return 0;
+	base = (char *)p - (char *)head->iov_base;
+
+	rqstp->rq_res.page_len = w;
+	while (w > 0) {
+		if (!svc_take_res_page(rqstp))
+			return 0;
+		w -= PAGE_SIZE;
+	}
+
+	n = nfsacl_encode(&rqstp->rq_res, base, inode,
+			  resp->acl_access,
+			  resp->mask & NFS_ACL, 0);
+	if (n > 0)
+		n = nfsacl_encode(&rqstp->rq_res, base + n, inode,
+				  resp->acl_default,
+				  resp->mask & NFS_DFACL,
+				  NFS_ACL_DEFAULT);
+	if (n <= 0)
+		return 0;
+	return 1;
+}
+
+static int nfsaclsvc_encode_attrstatres(struct svc_rqst *rqstp, u32 *p,
+		struct nfsd_attrstat *resp)
+{
+	p = nfs2svc_encode_fattr(rqstp, p, &resp->fh);
+	return xdr_ressize_check(rqstp, p);
+}
+
+/* ACCESS */
+static int nfsaclsvc_encode_accessres(struct svc_rqst *rqstp, u32 *p,
+		struct nfsd3_accessres *resp)
+{
+	p = nfs2svc_encode_fattr(rqstp, p, &resp->fh);
+	*p++ = htonl(resp->access);
+	return xdr_ressize_check(rqstp, p);
+}
+
+/*
+ * XDR release functions
+ */
+static int nfsaclsvc_release_getacl(struct svc_rqst *rqstp, u32 *p,
+		struct nfsd3_getaclres *resp)
+{
+	fh_put(&resp->fh);
+	posix_acl_release(resp->acl_access);
+	posix_acl_release(resp->acl_default);
+	return 1;
+}
+
+static int nfsaclsvc_release_fhandle(struct svc_rqst *rqstp, u32 *p,
+		struct nfsd_fhandle *resp)
+{
+	fh_put(&resp->fh);
+	return 1;
+}
+
+#define nfsaclsvc_decode_voidargs	NULL
+#define nfsaclsvc_encode_voidres	NULL
+#define nfsaclsvc_release_void		NULL
+#define nfsd3_fhandleargs	nfsd_fhandle
+#define nfsd3_attrstatres	nfsd_attrstat
+#define nfsd3_voidres		nfsd3_voidargs
+struct nfsd3_voidargs { int dummy; };
+
+#define PROC(name, argt, rest, relt, cache, respsize)	\
+ { (svc_procfunc) nfsacld_proc_##name,		\
+   (kxdrproc_t) nfsaclsvc_decode_##argt##args,	\
+   (kxdrproc_t) nfsaclsvc_encode_##rest##res,	\
+   (kxdrproc_t) nfsaclsvc_release_##relt,		\
+   sizeof(struct nfsd3_##argt##args),		\
+   sizeof(struct nfsd3_##rest##res),		\
+   0,						\
+   cache,					\
+   respsize,					\
+ }
+
+#define ST 1		/* status*/
+#define AT 21		/* attributes */
+#define pAT (1+AT)	/* post attributes - conditional */
+#define ACL (1+NFS_ACL_MAX_ENTRIES*3)  /* Access Control List */
+
+static struct svc_procedure		nfsd_acl_procedures2[] = {
+  PROC(null,	void,		void,		void,	  RC_NOCACHE, ST),
+  PROC(getacl,	getacl,		getacl,		getacl,	  RC_NOCACHE, ST+1+2*(1+ACL)),
+  PROC(setacl,	setacl,		attrstat,	fhandle,  RC_NOCACHE, ST+AT),
+  PROC(getattr, fhandle,	attrstat,	fhandle,  RC_NOCACHE, ST+AT),
+  PROC(access,	access,		access,		fhandle,  RC_NOCACHE, ST+AT+1),
+};
+
+struct svc_version	nfsd_acl_version2 = {
+		.vs_vers	= 2,
+		.vs_nproc	= 5,
+		.vs_proc	= nfsd_acl_procedures2,
+		.vs_dispatch	= nfsd_dispatch,
+		.vs_xdrsize	= NFS3_SVC_XDRSIZE,
+};
diff --git a/fs/nfsd/nfs3acl.c b/fs/nfsd/nfs3acl.c
new file mode 100644
--- /dev/null
+++ b/fs/nfsd/nfs3acl.c
@@ -0,0 +1,267 @@
+/*
+ * linux/fs/nfsd/nfs3acl.c
+ *
+ * Process version 3 NFSACL requests.
+ *
+ * Copyright (C) 2002-2003 Andreas Gruenbacher <agruen@suse.de>
+ */
+
+#include <linux/sunrpc/svc.h>
+#include <linux/nfs3.h>
+#include <linux/nfsd/nfsd.h>
+#include <linux/nfsd/cache.h>
+#include <linux/nfsd/xdr3.h>
+#include <linux/posix_acl.h>
+#include <linux/nfsacl.h>
+
+#define RETURN_STATUS(st)	{ resp->status = (st); return (st); }
+
+/*
+ * NULL call.
+ */
+static int
+nfsd3_proc_null(struct svc_rqst *rqstp, void *argp, void *resp)
+{
+	return nfs_ok;
+}
+
+/*
+ * Get the Access and/or Default ACL of a file.
+ */
+static int nfsd3_proc_getacl(struct svc_rqst * rqstp,
+		struct nfsd3_getaclargs *argp, struct nfsd3_getaclres *resp)
+{
+	svc_fh *fh;
+	struct posix_acl *acl;
+	int nfserr = 0;
+
+	fh = fh_copy(&resp->fh, &argp->fh);
+	if ((nfserr = fh_verify(rqstp, &resp->fh, 0, MAY_NOP)))
+		RETURN_STATUS(nfserr_inval);
+
+	if (argp->mask & ~(NFS_ACL|NFS_ACLCNT|NFS_DFACL|NFS_DFACLCNT))
+		RETURN_STATUS(nfserr_inval);
+	resp->mask = argp->mask;
+
+	if (resp->mask & (NFS_ACL|NFS_ACLCNT)) {
+		acl = nfsd_get_posix_acl(fh, ACL_TYPE_ACCESS);
+		if (IS_ERR(acl)) {
+			int err = PTR_ERR(acl);
+
+			if (err == -ENODATA || err == -EOPNOTSUPP)
+				acl = NULL;
+			else {
+				nfserr = nfserrno(err);
+				goto fail;
+			}
+		}
+		if (acl == NULL) {
+			/* Solaris returns the inode's minimum ACL. */
+
+			struct inode *inode = fh->fh_dentry->d_inode;
+			acl = posix_acl_from_mode(inode->i_mode, GFP_KERNEL);
+		}
+		resp->acl_access = acl;
+	}
+	if (resp->mask & (NFS_DFACL|NFS_DFACLCNT)) {
+		/* Check how Solaris handles requests for the Default ACL
+		   of a non-directory! */
+
+		acl = nfsd_get_posix_acl(fh, ACL_TYPE_DEFAULT);
+		if (IS_ERR(acl)) {
+			int err = PTR_ERR(acl);
+
+			if (err == -ENODATA || err == -EOPNOTSUPP)
+				acl = NULL;
+			else {
+				nfserr = nfserrno(err);
+				goto fail;
+			}
+		}
+		resp->acl_default = acl;
+	}
+
+	/* resp->acl_{access,default} are released in nfs3svc_release_getacl. */
+	RETURN_STATUS(0);
+
+fail:
+	posix_acl_release(resp->acl_access);
+	posix_acl_release(resp->acl_default);
+	RETURN_STATUS(nfserr);
+}
+
+/*
+ * Set the Access and/or Default ACL of a file.
+ */
+static int nfsd3_proc_setacl(struct svc_rqst * rqstp,
+		struct nfsd3_setaclargs *argp,
+		struct nfsd3_attrstat *resp)
+{
+	svc_fh *fh;
+	int nfserr = 0;
+
+	fh = fh_copy(&resp->fh, &argp->fh);
+	nfserr = fh_verify(rqstp, &resp->fh, 0, MAY_NOP);
+
+	if (!nfserr) {
+		nfserr = nfserrno( nfsd_set_posix_acl(
+			fh, ACL_TYPE_ACCESS, argp->acl_access) );
+	}
+	if (!nfserr) {
+		nfserr = nfserrno( nfsd_set_posix_acl(
+			fh, ACL_TYPE_DEFAULT, argp->acl_default) );
+	}
+
+	/* argp->acl_{access,default} may have been allocated in
+	   nfs3svc_decode_setaclargs. */
+	posix_acl_release(argp->acl_access);
+	posix_acl_release(argp->acl_default);
+	RETURN_STATUS(nfserr);
+}
+
+/*
+ * XDR decode functions
+ */
+static int nfs3svc_decode_getaclargs(struct svc_rqst *rqstp, u32 *p,
+		struct nfsd3_getaclargs *args)
+{
+	if (!(p = nfs3svc_decode_fh(p, &args->fh)))
+		return 0;
+	args->mask = ntohl(*p); p++;
+
+	return xdr_argsize_check(rqstp, p);
+}
+
+
+static int nfs3svc_decode_setaclargs(struct svc_rqst *rqstp, u32 *p,
+		struct nfsd3_setaclargs *args)
+{
+	struct kvec *head = rqstp->rq_arg.head;
+	unsigned int base;
+	int n;
+
+	if (!(p = nfs3svc_decode_fh(p, &args->fh)))
+		return 0;
+	args->mask = ntohl(*p++);
+	if (args->mask & ~(NFS_ACL|NFS_ACLCNT|NFS_DFACL|NFS_DFACLCNT) ||
+	    !xdr_argsize_check(rqstp, p))
+		return 0;
+
+	base = (char *)p - (char *)head->iov_base;
+	n = nfsacl_decode(&rqstp->rq_arg, base, NULL,
+			  (args->mask & NFS_ACL) ?
+			  &args->acl_access : NULL);
+	if (n > 0)
+		n = nfsacl_decode(&rqstp->rq_arg, base + n, NULL,
+				  (args->mask & NFS_DFACL) ?
+				  &args->acl_default : NULL);
+	return (n > 0);
+}
+
+/*
+ * XDR encode functions
+ */
+
+/* GETACL */
+static int nfs3svc_encode_getaclres(struct svc_rqst *rqstp, u32 *p,
+		struct nfsd3_getaclres *resp)
+{
+	struct dentry *dentry = resp->fh.fh_dentry;
+
+	p = nfs3svc_encode_post_op_attr(rqstp, p, &resp->fh);
+	if (resp->status == 0 && dentry && dentry->d_inode) {
+		struct inode *inode = dentry->d_inode;
+		int w = nfsacl_size(
+			(resp->mask & NFS_ACL)   ? resp->acl_access  : NULL,
+			(resp->mask & NFS_DFACL) ? resp->acl_default : NULL);
+		struct kvec *head = rqstp->rq_res.head;
+		unsigned int base;
+		int n;
+
+		*p++ = htonl(resp->mask);
+		if (!xdr_ressize_check(rqstp, p))
+			return 0;
+		base = (char *)p - (char *)head->iov_base;
+
+		rqstp->rq_res.page_len = w;
+		while (w > 0) {
+			if (!svc_take_res_page(rqstp))
+				return 0;
+			w -= PAGE_SIZE;
+		}
+
+		n = nfsacl_encode(&rqstp->rq_res, base, inode,
+				  resp->acl_access,
+				  resp->mask & NFS_ACL, 0);
+		if (n > 0)
+			n = nfsacl_encode(&rqstp->rq_res, base + n, inode,
+					  resp->acl_default,
+					  resp->mask & NFS_DFACL,
+					  NFS_ACL_DEFAULT);
+		if (n <= 0)
+			return 0;
+	} else
+		if (!xdr_ressize_check(rqstp, p))
+			return 0;
+
+	return 1;
+}
+
+/* SETACL */
+static int nfs3svc_encode_setaclres(struct svc_rqst *rqstp, u32 *p,
+		struct nfsd3_attrstat *resp)
+{
+	p = nfs3svc_encode_post_op_attr(rqstp, p, &resp->fh);
+
+	return xdr_ressize_check(rqstp, p);
+}
+
+/*
+ * XDR release functions
+ */
+static int nfs3svc_release_getacl(struct svc_rqst *rqstp, u32 *p,
+		struct nfsd3_getaclres *resp)
+{
+	fh_put(&resp->fh);
+	posix_acl_release(resp->acl_access);
+	posix_acl_release(resp->acl_default);
+	return 1;
+}
+
+#define nfs3svc_decode_voidargs		NULL
+#define nfs3svc_release_void		NULL
+#define nfsd3_setaclres			nfsd3_attrstat
+#define nfsd3_voidres			nfsd3_voidargs
+struct nfsd3_voidargs { int dummy; };
+
+#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,	\
+   (kxdrproc_t) nfs3svc_release_##relt,		\
+   sizeof(struct nfsd3_##argt##args),		\
+   sizeof(struct nfsd3_##rest##res),		\
+   0,						\
+   cache,					\
+   respsize,					\
+ }
+
+#define ST 1		/* status*/
+#define AT 21		/* attributes */
+#define pAT (1+AT)	/* post attributes - conditional */
+#define ACL (1+NFS_ACL_MAX_ENTRIES*3)  /* Access Control List */
+
+static struct svc_procedure		nfsd_acl_procedures3[] = {
+  PROC(null,	void,		void,		void,	  RC_NOCACHE, ST),
+  PROC(getacl,	getacl,		getacl,		getacl,	  RC_NOCACHE, ST+1+2*(1+ACL)),
+  PROC(setacl,	setacl,		setacl,		fhandle,  RC_NOCACHE, ST+pAT),
+};
+
+struct svc_version	nfsd_acl_version3 = {
+		.vs_vers	= 3,
+		.vs_nproc	= 3,
+		.vs_proc	= nfsd_acl_procedures3,
+		.vs_dispatch	= nfsd_dispatch,
+		.vs_xdrsize	= NFS3_SVC_XDRSIZE,
+};
+
diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c
--- a/fs/nfsd/nfs3xdr.c
+++ b/fs/nfsd/nfs3xdr.c
@@ -71,6 +71,12 @@ decode_fh(u32 *p, struct svc_fh *fhp)
 	return p + XDR_QUADLEN(size);
 }
 
+/* Helper function for NFSv3 ACL code */
+u32 *nfs3svc_decode_fh(u32 *p, struct svc_fh *fhp)
+{
+	return decode_fh(p, fhp);
+}
+
 static inline u32 *
 encode_fh(u32 *p, struct svc_fh *fhp)
 {
@@ -233,6 +239,13 @@ encode_post_op_attr(struct svc_rqst *rqs
 	return p;
 }
 
+/* Helper for NFSv3 ACLs */
+u32 *
+nfs3svc_encode_post_op_attr(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp)
+{
+	return encode_post_op_attr(rqstp, p, fhp);
+}
+
 /*
  * Enocde weak cache consistency data
  */
diff --git a/fs/nfsd/nfs4acl.c b/fs/nfsd/nfs4acl.c
--- a/fs/nfsd/nfs4acl.c
+++ b/fs/nfsd/nfs4acl.c
@@ -125,7 +125,7 @@ static short ace2type(struct nfs4_ace *)
 static int _posix_to_nfsv4_one(struct posix_acl *, struct nfs4_acl *, unsigned int);
 static struct posix_acl *_nfsv4_to_posix_one(struct nfs4_acl *, unsigned int);
 int nfs4_acl_add_ace(struct nfs4_acl *, u32, u32, u32, int, uid_t);
-int nfs4_acl_split(struct nfs4_acl *, struct nfs4_acl *);
+static int nfs4_acl_split(struct nfs4_acl *, struct nfs4_acl *);
 
 struct nfs4_acl *
 nfs4_acl_posix_to_nfsv4(struct posix_acl *pacl, struct posix_acl *dpacl,
@@ -775,7 +775,7 @@ out_err:
 	return pacl;
 }
 
-int
+static int
 nfs4_acl_split(struct nfs4_acl *acl, struct nfs4_acl *dacl)
 {
 	struct list_head *h, *n;
diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c
--- a/fs/nfsd/nfs4callback.c
+++ b/fs/nfsd/nfs4callback.c
@@ -54,7 +54,6 @@
 
 /* declarations */
 static void nfs4_cb_null(struct rpc_task *task);
-extern spinlock_t recall_lock;
 
 /* Index of predefined Linux callback client operations */
 
@@ -329,12 +328,12 @@ out:
         .p_bufsiz = MAX(NFS4_##argtype##_sz,NFS4_##restype##_sz) << 2,  \
 }
 
-struct rpc_procinfo     nfs4_cb_procedures[] = {
+static struct rpc_procinfo     nfs4_cb_procedures[] = {
     PROC(CB_NULL,      NULL,     enc_cb_null,     dec_cb_null),
     PROC(CB_RECALL,    COMPOUND,   enc_cb_recall,      dec_cb_recall),
 };
 
-struct rpc_version              nfs_cb_version4 = {
+static struct rpc_version       nfs_cb_version4 = {
         .number                 = 1,
         .nrprocs                = sizeof(nfs4_cb_procedures)/sizeof(nfs4_cb_procedures[0]),
         .procs                  = nfs4_cb_procedures
@@ -348,7 +347,7 @@ static struct rpc_version *	nfs_cb_versi
 /*
  * Use the SETCLIENTID credential
  */
-struct rpc_cred *
+static struct rpc_cred *
 nfsd4_lookupcred(struct nfs4_client *clp, int taskflags)
 {
         struct auth_cred acred;
@@ -387,9 +386,7 @@ nfsd4_probe_callback(struct nfs4_client 
 	char                    hostname[32];
 	int status;
 
-	dprintk("NFSD: probe_callback. cb_parsed %d cb_set %d\n",
-			cb->cb_parsed, atomic_read(&cb->cb_set));
-	if (!cb->cb_parsed || atomic_read(&cb->cb_set))
+	if (atomic_read(&cb->cb_set))
 		return;
 
 	/* Initialize address */
@@ -427,10 +424,10 @@ nfsd4_probe_callback(struct nfs4_client 
 	 * XXX AUTH_UNIX only - need AUTH_GSS....
 	 */
 	sprintf(hostname, "%u.%u.%u.%u", NIPQUAD(addr.sin_addr.s_addr));
-	clnt = rpc_create_client(xprt, hostname, program, 1, RPC_AUTH_UNIX);
+	clnt = rpc_new_client(xprt, hostname, program, 1, RPC_AUTH_UNIX);
 	if (IS_ERR(clnt)) {
 		dprintk("NFSD: couldn't create callback client\n");
-		goto out_xprt;
+		goto out_err;
 	}
 	clnt->cl_intr = 0;
 	clnt->cl_softrtry = 1;
@@ -465,8 +462,6 @@ out_rpciod:
 out_clnt:
 	rpc_shutdown_client(clnt);
 	goto out_err;
-out_xprt:
-	xprt_destroy(xprt);
 out_err:
 	dprintk("NFSD: warning: no callback path to client %.*s\n",
 		(int)clp->cl_name.len, clp->cl_name.data);
diff --git a/fs/nfsd/nfs4idmap.c b/fs/nfsd/nfs4idmap.c
--- a/fs/nfsd/nfs4idmap.c
+++ b/fs/nfsd/nfs4idmap.c
@@ -104,7 +104,7 @@ ent_update(struct ent *new, struct ent *
 	ent_init(new, itm);
 }
 
-void
+static void
 ent_put(struct cache_head *ch, struct cache_detail *cd)
 {
 	if (cache_put(ch, cd)) {
@@ -186,7 +186,7 @@ warn_no_idmapd(struct cache_detail *deta
 static int         idtoname_parse(struct cache_detail *, char *, int);
 static struct ent *idtoname_lookup(struct ent *, int);
 
-struct cache_detail idtoname_cache = {
+static struct cache_detail idtoname_cache = {
 	.hash_size	= ENT_HASHMAX,
 	.hash_table	= idtoname_table,
 	.name		= "nfs4.idtoname",
@@ -277,7 +277,7 @@ nametoid_hash(struct ent *ent)
 	return hash_str(ent->name, ENT_HASHBITS);
 }
 
-void
+static void
 nametoid_request(struct cache_detail *cd, struct cache_head *ch, char **bpp,
     int *blen)
 {
@@ -317,9 +317,9 @@ nametoid_show(struct seq_file *m, struct
 }
 
 static struct ent *nametoid_lookup(struct ent *, int);
-int                nametoid_parse(struct cache_detail *, char *, int);
+static int         nametoid_parse(struct cache_detail *, char *, int);
 
-struct cache_detail nametoid_cache = {
+static struct cache_detail nametoid_cache = {
 	.hash_size	= ENT_HASHMAX,
 	.hash_table	= nametoid_table,
 	.name		= "nfs4.nametoid",
@@ -330,7 +330,7 @@ struct cache_detail nametoid_cache = {
 	.warn_no_listener = warn_no_idmapd,
 };
 
-int
+static int
 nametoid_parse(struct cache_detail *cd, char *buf, int buflen)
 {
 	struct ent ent, *res;
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -45,6 +45,7 @@
 #include <linux/param.h>
 #include <linux/major.h>
 #include <linux/slab.h>
+#include <linux/file.h>
 
 #include <linux/sunrpc/svc.h>
 #include <linux/nfsd/nfsd.h>
@@ -168,12 +169,6 @@ nfsd4_open(struct svc_rqst *rqstp, struc
 		(int)open->op_fname.len, open->op_fname.data,
 		open->op_stateowner);
 
-	if (nfs4_in_grace() && open->op_claim_type != NFS4_OPEN_CLAIM_PREVIOUS)
-		return nfserr_grace;
-
-	if (!nfs4_in_grace() && open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS)
-		return nfserr_no_grace;
-
 	/* This check required by spec. */
 	if (open->op_create && open->op_claim_type != NFS4_OPEN_CLAIM_NULL)
 		return nfserr_inval;
@@ -198,6 +193,11 @@ nfsd4_open(struct svc_rqst *rqstp, struc
 	if (status)
 		goto out;
 	switch (open->op_claim_type) {
+		case NFS4_OPEN_CLAIM_DELEGATE_CUR:
+			status = nfserr_inval;
+			if (open->op_create)
+				goto out;
+			/* fall through */
 		case NFS4_OPEN_CLAIM_NULL:
 			/*
 			 * (1) set CURRENT_FH to the file being opened,
@@ -220,7 +220,6 @@ nfsd4_open(struct svc_rqst *rqstp, struc
 			if (status)
 				goto out;
 			break;
-		case NFS4_OPEN_CLAIM_DELEGATE_CUR:
              	case NFS4_OPEN_CLAIM_DELEGATE_PREV:
 			printk("NFSD: unsupported OPEN claim type %d\n",
 				open->op_claim_type);
@@ -473,26 +472,27 @@ static inline int
 nfsd4_read(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_read *read)
 {
 	int status;
-	struct file *filp = NULL;
 
 	/* no need to check permission - this will be done in nfsd_read() */
 
+	read->rd_filp = NULL;
 	if (read->rd_offset >= OFFSET_MAX)
 		return nfserr_inval;
 
 	nfs4_lock_state();
 	/* check stateid */
 	if ((status = nfs4_preprocess_stateid_op(current_fh, &read->rd_stateid,
-					CHECK_FH | RD_STATE, &filp))) {
+				CHECK_FH | RD_STATE, &read->rd_filp))) {
 		dprintk("NFSD: nfsd4_read: couldn't process stateid!\n");
 		goto out;
 	}
+	if (read->rd_filp)
+		get_file(read->rd_filp);
 	status = nfs_ok;
 out:
 	nfs4_unlock_state();
 	read->rd_rqstp = rqstp;
 	read->rd_fhp = current_fh;
-	read->rd_filp = filp;
 	return status;
 }
 
@@ -532,6 +532,8 @@ nfsd4_remove(struct svc_rqst *rqstp, str
 {
 	int status;
 
+	if (nfs4_in_grace())
+		return nfserr_grace;
 	status = nfsd_unlink(rqstp, current_fh, 0, remove->rm_name, remove->rm_namelen);
 	if (status == nfserr_symlink)
 		return nfserr_notdir;
@@ -550,6 +552,9 @@ nfsd4_rename(struct svc_rqst *rqstp, str
 
 	if (!save_fh->fh_dentry)
 		return status;
+	if (nfs4_in_grace() && !(save_fh->fh_export->ex_flags
+					& NFSEXP_NOSUBTREECHECK))
+		return nfserr_grace;
 	status = nfsd_rename(rqstp, save_fh, rename->rn_sname,
 			     rename->rn_snamelen, current_fh,
 			     rename->rn_tname, rename->rn_tnamelen);
@@ -624,6 +629,8 @@ nfsd4_write(struct svc_rqst *rqstp, stru
 		dprintk("NFSD: nfsd4_write: couldn't process stateid!\n");
 		goto out;
 	}
+	if (filp)
+		get_file(filp);
 	nfs4_unlock_state();
 
 	write->wr_bytes_written = write->wr_buflen;
@@ -635,6 +642,8 @@ nfsd4_write(struct svc_rqst *rqstp, stru
 	status =  nfsd_write(rqstp, current_fh, filp, write->wr_offset,
 			write->wr_vec, write->wr_vlen, write->wr_buflen,
 			&write->wr_how_written);
+	if (filp)
+		fput(filp);
 
 	if (status == nfserr_symlink)
 		status = nfserr_inval;
@@ -923,6 +932,9 @@ encode_op:
 			nfs4_put_stateowner(replay_owner);
 			replay_owner = NULL;
 		}
+		/* XXX Ugh, we need to get rid of this kind of special case: */
+		if (op->opnum == OP_READ && op->u.read.rd_filp)
+			fput(op->u.read.rd_filp);
 	}
 
 out:
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c
new file mode 100644
--- /dev/null
+++ b/fs/nfsd/nfs4recover.c
@@ -0,0 +1,421 @@
+/*
+*  linux/fs/nfsd/nfs4recover.c
+*
+*  Copyright (c) 2004 The Regents of the University of Michigan.
+*  All rights reserved.
+*
+*  Andy Adamson <andros@citi.umich.edu>
+*
+*  Redistribution and use in source and binary forms, with or without
+*  modification, are permitted provided that the following conditions
+*  are met:
+*
+*  1. Redistributions of source code must retain the above copyright
+*     notice, this list of conditions and the following disclaimer.
+*  2. Redistributions in binary form must reproduce the above copyright
+*     notice, this list of conditions and the following disclaimer in the
+*     documentation and/or other materials provided with the distribution.
+*  3. Neither the name of the University nor the names of its
+*     contributors may be used to endorse or promote products derived
+*     from this software without specific prior written permission.
+*
+*  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+*  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+*  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+*  DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+*  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+*  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+*  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+*  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+*  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+*  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+*  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*/
+
+
+#include <linux/sunrpc/svc.h>
+#include <linux/nfsd/nfsd.h>
+#include <linux/nfs4.h>
+#include <linux/nfsd/state.h>
+#include <linux/nfsd/xdr4.h>
+#include <linux/param.h>
+#include <linux/file.h>
+#include <linux/namei.h>
+#include <asm/uaccess.h>
+#include <asm/scatterlist.h>
+#include <linux/crypto.h>
+
+
+#define NFSDDBG_FACILITY                NFSDDBG_PROC
+
+/* Globals */
+static struct nameidata rec_dir;
+static int rec_dir_init = 0;
+
+static void
+nfs4_save_user(uid_t *saveuid, gid_t *savegid)
+{
+	*saveuid = current->fsuid;
+	*savegid = current->fsgid;
+	current->fsuid = 0;
+	current->fsgid = 0;
+}
+
+static void
+nfs4_reset_user(uid_t saveuid, gid_t savegid)
+{
+	current->fsuid = saveuid;
+	current->fsgid = savegid;
+}
+
+static void
+md5_to_hex(char *out, char *md5)
+{
+	int i;
+
+	for (i=0; i<16; i++) {
+		unsigned char c = md5[i];
+
+		*out++ = '0' + ((c&0xf0)>>4) + (c>=0xa0)*('a'-'9'-1);
+		*out++ = '0' + (c&0x0f) + ((c&0x0f)>=0x0a)*('a'-'9'-1);
+	}
+	*out = '\0';
+}
+
+int
+nfs4_make_rec_clidname(char *dname, struct xdr_netobj *clname)
+{
+	struct xdr_netobj cksum;
+	struct crypto_tfm *tfm;
+	struct scatterlist sg[1];
+	int status = nfserr_resource;
+
+	dprintk("NFSD: nfs4_make_rec_clidname for %.*s\n",
+			clname->len, clname->data);
+	tfm = crypto_alloc_tfm("md5", 0);
+	if (tfm == NULL)
+		goto out;
+	cksum.len = crypto_tfm_alg_digestsize(tfm);
+	cksum.data = kmalloc(cksum.len, GFP_KERNEL);
+	if (cksum.data == NULL)
+ 		goto out;
+	crypto_digest_init(tfm);
+
+	sg[0].page = virt_to_page(clname->data);
+	sg[0].offset = offset_in_page(clname->data);
+	sg[0].length = clname->len;
+
+	crypto_digest_update(tfm, sg, 1);
+	crypto_digest_final(tfm, cksum.data);
+
+	md5_to_hex(dname, cksum.data);
+
+	kfree(cksum.data);
+	status = nfs_ok;
+out:
+	if (tfm)
+		crypto_free_tfm(tfm);
+	return status;
+}
+
+static void
+nfsd4_sync_rec_dir(void)
+{
+	down(&rec_dir.dentry->d_inode->i_sem);
+	nfsd_sync_dir(rec_dir.dentry);
+	up(&rec_dir.dentry->d_inode->i_sem);
+}
+
+int
+nfsd4_create_clid_dir(struct nfs4_client *clp)
+{
+	char *dname = clp->cl_recdir;
+	struct dentry *dentry;
+	uid_t uid;
+	gid_t gid;
+	int status;
+
+	dprintk("NFSD: nfsd4_create_clid_dir for \"%s\"\n", dname);
+
+	if (!rec_dir_init || clp->cl_firststate)
+		return 0;
+
+	nfs4_save_user(&uid, &gid);
+
+	/* lock the parent */
+	down(&rec_dir.dentry->d_inode->i_sem);
+
+	dentry = lookup_one_len(dname, rec_dir.dentry, HEXDIR_LEN-1);
+	if (IS_ERR(dentry)) {
+		status = PTR_ERR(dentry);
+		goto out_unlock;
+	}
+	status = -EEXIST;
+	if (dentry->d_inode) {
+		dprintk("NFSD: nfsd4_create_clid_dir: DIRECTORY EXISTS\n");
+		goto out_put;
+	}
+	status = vfs_mkdir(rec_dir.dentry->d_inode, dentry, S_IRWXU);
+out_put:
+	dput(dentry);
+out_unlock:
+	up(&rec_dir.dentry->d_inode->i_sem);
+	if (status == 0) {
+		clp->cl_firststate = 1;
+		nfsd4_sync_rec_dir();
+	}
+	nfs4_reset_user(uid, gid);
+	dprintk("NFSD: nfsd4_create_clid_dir returns %d\n", status);
+	return status;
+}
+
+typedef int (recdir_func)(struct dentry *, struct dentry *);
+
+struct dentry_list {
+	struct dentry *dentry;
+	struct list_head list;
+};
+
+struct dentry_list_arg {
+	struct list_head dentries;
+	struct dentry *parent;
+};
+
+static int
+nfsd4_build_dentrylist(void *arg, const char *name, int namlen,
+		loff_t offset, ino_t ino, unsigned int d_type)
+{
+	struct dentry_list_arg *dla = arg;
+	struct list_head *dentries = &dla->dentries;
+	struct dentry *parent = dla->parent;
+	struct dentry *dentry;
+	struct dentry_list *child;
+
+	if (name && isdotent(name, namlen))
+		return nfs_ok;
+	dentry = lookup_one_len(name, parent, namlen);
+	if (IS_ERR(dentry))
+		return PTR_ERR(dentry);
+	child = kmalloc(sizeof(*child), GFP_KERNEL);
+	if (child == NULL)
+		return -ENOMEM;
+	child->dentry = dentry;
+	list_add(&child->list, dentries);
+	return 0;
+}
+
+static int
+nfsd4_list_rec_dir(struct dentry *dir, recdir_func *f)
+{
+	struct file *filp;
+	struct dentry_list_arg dla = {
+		.parent = dir,
+	};
+	struct list_head *dentries = &dla.dentries;
+	struct dentry_list *child;
+	uid_t uid;
+	gid_t gid;
+	int status;
+
+	if (!rec_dir_init)
+		return 0;
+
+	nfs4_save_user(&uid, &gid);
+
+	filp = dentry_open(dget(dir), mntget(rec_dir.mnt),
+			O_RDWR);
+	status = PTR_ERR(filp);
+	if (IS_ERR(filp))
+		goto out;
+	INIT_LIST_HEAD(dentries);
+	status = vfs_readdir(filp, nfsd4_build_dentrylist, &dla);
+	fput(filp);
+	while (!list_empty(dentries)) {
+		child = list_entry(dentries->next, struct dentry_list, list);
+		status = f(dir, child->dentry);
+		if (status)
+			goto out;
+		list_del(&child->list);
+		dput(child->dentry);
+		kfree(child);
+	}
+out:
+	while (!list_empty(dentries)) {
+		child = list_entry(dentries->next, struct dentry_list, list);
+		list_del(&child->list);
+		dput(child->dentry);
+		kfree(child);
+	}
+	nfs4_reset_user(uid, gid);
+	return status;
+}
+
+static int
+nfsd4_remove_clid_file(struct dentry *dir, struct dentry *dentry)
+{
+	int status;
+
+	if (!S_ISREG(dir->d_inode->i_mode)) {
+		printk("nfsd4: non-file found in client recovery directory\n");
+		return -EINVAL;
+	}
+	down(&dir->d_inode->i_sem);
+	status = vfs_unlink(dir->d_inode, dentry);
+	up(&dir->d_inode->i_sem);
+	return status;
+}
+
+static int
+nfsd4_clear_clid_dir(struct dentry *dir, struct dentry *dentry)
+{
+	int status;
+
+	/* For now this directory should already be empty, but we empty it of
+	 * any regular files anyway, just in case the directory was created by
+	 * a kernel from the future.... */
+	nfsd4_list_rec_dir(dentry, nfsd4_remove_clid_file);
+	down(&dir->d_inode->i_sem);
+	status = vfs_rmdir(dir->d_inode, dentry);
+	up(&dir->d_inode->i_sem);
+	return status;
+}
+
+static int
+nfsd4_unlink_clid_dir(char *name, int namlen)
+{
+	struct dentry *dentry;
+	int status;
+
+	dprintk("NFSD: nfsd4_unlink_clid_dir. name %.*s\n", namlen, name);
+
+	down(&rec_dir.dentry->d_inode->i_sem);
+	dentry = lookup_one_len(name, rec_dir.dentry, namlen);
+	up(&rec_dir.dentry->d_inode->i_sem);
+	if (IS_ERR(dentry)) {
+		status = PTR_ERR(dentry);
+		return status;
+	}
+	status = -ENOENT;
+	if (!dentry->d_inode)
+		goto out;
+
+	status = nfsd4_clear_clid_dir(rec_dir.dentry, dentry);
+out:
+	dput(dentry);
+	return status;
+}
+
+void
+nfsd4_remove_clid_dir(struct nfs4_client *clp)
+{
+	uid_t uid;
+	gid_t gid;
+	int status;
+
+	if (!rec_dir_init || !clp->cl_firststate)
+		return;
+
+	clp->cl_firststate = 0;
+	nfs4_save_user(&uid, &gid);
+	status = nfsd4_unlink_clid_dir(clp->cl_recdir, HEXDIR_LEN-1);
+	nfs4_reset_user(uid, gid);
+	if (status == 0)
+		nfsd4_sync_rec_dir();
+	if (status)
+		printk("NFSD: Failed to remove expired client state directory"
+				" %.*s\n", HEXDIR_LEN, clp->cl_recdir);
+	return;
+}
+
+static int
+purge_old(struct dentry *parent, struct dentry *child)
+{
+	int status;
+
+	if (nfs4_has_reclaimed_state(child->d_name.name))
+		return nfs_ok;
+
+	status = nfsd4_clear_clid_dir(parent, child);
+	if (status)
+		printk("failed to remove client recovery directory %s\n",
+				child->d_name.name);
+	/* Keep trying, success or failure: */
+	return nfs_ok;
+}
+
+void
+nfsd4_recdir_purge_old(void) {
+	int status;
+
+	if (!rec_dir_init)
+		return;
+	status = nfsd4_list_rec_dir(rec_dir.dentry, purge_old);
+	if (status == 0)
+		nfsd4_sync_rec_dir();
+	if (status)
+		printk("nfsd4: failed to purge old clients from recovery"
+			" directory %s\n", rec_dir.dentry->d_name.name);
+	return;
+}
+
+static int
+load_recdir(struct dentry *parent, struct dentry *child)
+{
+	if (child->d_name.len != HEXDIR_LEN - 1) {
+		printk("nfsd4: illegal name %s in recovery directory\n",
+				child->d_name.name);
+		/* Keep trying; maybe the others are OK: */
+		return nfs_ok;
+	}
+	nfs4_client_to_reclaim(child->d_name.name);
+	return nfs_ok;
+}
+
+int
+nfsd4_recdir_load(void) {
+	int status;
+
+	status = nfsd4_list_rec_dir(rec_dir.dentry, load_recdir);
+	if (status)
+		printk("nfsd4: failed loading clients from recovery"
+			" directory %s\n", rec_dir.dentry->d_name.name);
+	return status;
+}
+
+/*
+ * Hold reference to the recovery directory.
+ */
+
+void
+nfsd4_init_recdir(char *rec_dirname)
+{
+	uid_t			uid = 0;
+	gid_t			gid = 0;
+	int 			status;
+
+	printk("NFSD: Using %s as the NFSv4 state recovery directory\n",
+			rec_dirname);
+
+	BUG_ON(rec_dir_init);
+
+	nfs4_save_user(&uid, &gid);
+
+	status = path_lookup(rec_dirname, LOOKUP_FOLLOW, &rec_dir);
+	if (status == -ENOENT)
+		printk("NFSD: recovery directory %s doesn't exist\n",
+				rec_dirname);
+
+	if (!status)
+		rec_dir_init = 1;
+	nfs4_reset_user(uid, gid);
+}
+
+void
+nfsd4_shutdown_recdir(void)
+{
+	if (!rec_dir_init)
+		return;
+	rec_dir_init = 0;
+	path_release(&rec_dir);
+}
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -48,39 +48,32 @@
 #include <linux/nfs4.h>
 #include <linux/nfsd/state.h>
 #include <linux/nfsd/xdr4.h>
+#include <linux/namei.h>
 
 #define NFSDDBG_FACILITY                NFSDDBG_PROC
 
 /* Globals */
 static time_t lease_time = 90;     /* default lease time */
-static time_t old_lease_time = 90; /* past incarnation lease time */
-static u32 nfs4_reclaim_init = 0;
-time_t boot_time;
-static time_t grace_end = 0;
+static time_t user_lease_time = 90;
+static time_t boot_time;
+static int in_grace = 1;
 static u32 current_clientid = 1;
 static u32 current_ownerid = 1;
 static u32 current_fileid = 1;
 static u32 current_delegid = 1;
 static u32 nfs4_init;
-stateid_t zerostateid;             /* bits all 0 */
-stateid_t onestateid;              /* bits all 1 */
+static stateid_t zerostateid;             /* bits all 0 */
+static stateid_t onestateid;              /* bits all 1 */
 
-/* debug counters */
-u32 list_add_perfile = 0; 
-u32 list_del_perfile = 0;
-u32 add_perclient = 0;
-u32 del_perclient = 0;
-u32 alloc_file = 0;
-u32 free_file = 0;
-u32 vfsopen = 0;
-u32 vfsclose = 0;
-u32 alloc_delegation= 0;
-u32 free_delegation= 0;
+#define ZERO_STATEID(stateid) (!memcmp((stateid), &zerostateid, sizeof(stateid_t)))
+#define ONE_STATEID(stateid)  (!memcmp((stateid), &onestateid, sizeof(stateid_t)))
 
 /* forward declarations */
-struct nfs4_stateid * find_stateid(stateid_t *stid, int flags);
+static struct nfs4_stateid * find_stateid(stateid_t *stid, int flags);
 static struct nfs4_delegation * find_delegation_stateid(struct inode *ino, stateid_t *stid);
 static void release_stateid_lockowners(struct nfs4_stateid *open_stp);
+static char user_recovery_dirname[PATH_MAX] = "/var/lib/nfs/v4recovery";
+static void nfs4_set_recdir(char *recdir);
 
 /* Locking:
  *
@@ -90,6 +83,11 @@ static void release_stateid_lockowners(s
  */
 static DECLARE_MUTEX(client_sema);
 
+static kmem_cache_t *stateowner_slab = NULL;
+static kmem_cache_t *file_slab = NULL;
+static kmem_cache_t *stateid_slab = NULL;
+static kmem_cache_t *deleg_slab = NULL;
+
 void
 nfs4_lock_state(void)
 {
@@ -118,16 +116,36 @@ opaque_hashval(const void *ptr, int nbyt
 /* forward declarations */
 static void release_stateowner(struct nfs4_stateowner *sop);
 static void release_stateid(struct nfs4_stateid *stp, int flags);
-static void release_file(struct nfs4_file *fp);
 
 /*
  * Delegation state
  */
 
 /* recall_lock protects the del_recall_lru */
-spinlock_t recall_lock;
+static spinlock_t recall_lock = SPIN_LOCK_UNLOCKED;
 static struct list_head del_recall_lru;
 
+static void
+free_nfs4_file(struct kref *kref)
+{
+	struct nfs4_file *fp = container_of(kref, struct nfs4_file, fi_ref);
+	list_del(&fp->fi_hash);
+	iput(fp->fi_inode);
+	kmem_cache_free(file_slab, fp);
+}
+
+static inline void
+put_nfs4_file(struct nfs4_file *fi)
+{
+	kref_put(&fi->fi_ref, free_nfs4_file);
+}
+
+static inline void
+get_nfs4_file(struct nfs4_file *fi)
+{
+	kref_get(&fi->fi_ref);
+}
+
 static struct nfs4_delegation *
 alloc_init_deleg(struct nfs4_client *clp, struct nfs4_stateid *stp, struct svc_fh *current_fh, u32 type)
 {
@@ -136,13 +154,14 @@ alloc_init_deleg(struct nfs4_client *clp
 	struct nfs4_callback *cb = &stp->st_stateowner->so_client->cl_callback;
 
 	dprintk("NFSD alloc_init_deleg\n");
-	if ((dp = kmalloc(sizeof(struct nfs4_delegation),
-		GFP_KERNEL)) == NULL)
+	dp = kmem_cache_alloc(deleg_slab, GFP_KERNEL);
+	if (dp == NULL)
 		return dp;
-	INIT_LIST_HEAD(&dp->dl_del_perfile);
-	INIT_LIST_HEAD(&dp->dl_del_perclnt);
+	INIT_LIST_HEAD(&dp->dl_perfile);
+	INIT_LIST_HEAD(&dp->dl_perclnt);
 	INIT_LIST_HEAD(&dp->dl_recall_lru);
 	dp->dl_client = clp;
+	get_nfs4_file(fp);
 	dp->dl_file = fp;
 	dp->dl_flock = NULL;
 	get_file(stp->st_vfs_file);
@@ -160,9 +179,8 @@ alloc_init_deleg(struct nfs4_client *clp
 		        current_fh->fh_handle.fh_size);
 	dp->dl_time = 0;
 	atomic_set(&dp->dl_count, 1);
-	list_add(&dp->dl_del_perfile, &fp->fi_del_perfile);
-	list_add(&dp->dl_del_perclnt, &clp->cl_del_perclnt);
-	alloc_delegation++;
+	list_add(&dp->dl_perfile, &fp->fi_delegations);
+	list_add(&dp->dl_perclnt, &clp->cl_delegations);
 	return dp;
 }
 
@@ -171,8 +189,8 @@ nfs4_put_delegation(struct nfs4_delegati
 {
 	if (atomic_dec_and_test(&dp->dl_count)) {
 		dprintk("NFSD: freeing dp %p\n",dp);
-		kfree(dp);
-		free_delegation++;
+		put_nfs4_file(dp->dl_file);
+		kmem_cache_free(deleg_slab, dp);
 	}
 }
 
@@ -193,15 +211,14 @@ nfs4_close_delegation(struct nfs4_delega
 	if (dp->dl_flock)
 		setlease(filp, F_UNLCK, &dp->dl_flock);
 	nfsd_close(filp);
-	vfsclose++;
 }
 
 /* Called under the state lock. */
 static void
 unhash_delegation(struct nfs4_delegation *dp)
 {
-	list_del_init(&dp->dl_del_perfile);
-	list_del_init(&dp->dl_del_perclnt);
+	list_del_init(&dp->dl_perfile);
+	list_del_init(&dp->dl_perclnt);
 	spin_lock(&recall_lock);
 	list_del_init(&dp->dl_recall_lru);
 	spin_unlock(&recall_lock);
@@ -220,8 +237,8 @@ unhash_delegation(struct nfs4_delegation
 
 #define clientid_hashval(id) \
 	((id) & CLIENT_HASH_MASK)
-#define clientstr_hashval(name, namelen) \
-	(opaque_hashval((name), (namelen)) & CLIENT_HASH_MASK)
+#define clientstr_hashval(name) \
+	(opaque_hashval((name), 8) & CLIENT_HASH_MASK)
 /*
  * reclaim_str_hashtbl[] holds known client info from previous reset/reboot
  * used in reboot/reset lease grace period processing
@@ -331,11 +348,11 @@ expire_client(struct nfs4_client *clp)
 
 	INIT_LIST_HEAD(&reaplist);
 	spin_lock(&recall_lock);
-	while (!list_empty(&clp->cl_del_perclnt)) {
-		dp = list_entry(clp->cl_del_perclnt.next, struct nfs4_delegation, dl_del_perclnt);
+	while (!list_empty(&clp->cl_delegations)) {
+		dp = list_entry(clp->cl_delegations.next, struct nfs4_delegation, dl_perclnt);
 		dprintk("NFSD: expire client. dp %p, fp %p\n", dp,
 				dp->dl_flock);
-		list_del_init(&dp->dl_del_perclnt);
+		list_del_init(&dp->dl_perclnt);
 		list_move(&dp->dl_recall_lru, &reaplist);
 	}
 	spin_unlock(&recall_lock);
@@ -347,26 +364,26 @@ expire_client(struct nfs4_client *clp)
 	list_del(&clp->cl_idhash);
 	list_del(&clp->cl_strhash);
 	list_del(&clp->cl_lru);
-	while (!list_empty(&clp->cl_perclient)) {
-		sop = list_entry(clp->cl_perclient.next, struct nfs4_stateowner, so_perclient);
+	while (!list_empty(&clp->cl_openowners)) {
+		sop = list_entry(clp->cl_openowners.next, struct nfs4_stateowner, so_perclient);
 		release_stateowner(sop);
 	}
 	put_nfs4_client(clp);
 }
 
 static struct nfs4_client *
-create_client(struct xdr_netobj name) {
+create_client(struct xdr_netobj name, char *recdir) {
 	struct nfs4_client *clp;
 
 	if (!(clp = alloc_client(name)))
 		goto out;
+	memcpy(clp->cl_recdir, recdir, HEXDIR_LEN);
 	atomic_set(&clp->cl_count, 1);
 	atomic_set(&clp->cl_callback.cb_set, 0);
-	clp->cl_callback.cb_parsed = 0;
 	INIT_LIST_HEAD(&clp->cl_idhash);
 	INIT_LIST_HEAD(&clp->cl_strhash);
-	INIT_LIST_HEAD(&clp->cl_perclient);
-	INIT_LIST_HEAD(&clp->cl_del_perclnt);
+	INIT_LIST_HEAD(&clp->cl_openowners);
+	INIT_LIST_HEAD(&clp->cl_delegations);
 	INIT_LIST_HEAD(&clp->cl_lru);
 out:
 	return clp;
@@ -392,11 +409,9 @@ copy_cred(struct svc_cred *target, struc
 	get_group_info(target->cr_group_info);
 }
 
-static int
-cmp_name(struct xdr_netobj *n1, struct xdr_netobj *n2) {
-	if (!n1 || !n2)
-		return 0;
-	return((n1->len == n2->len) && !memcmp(n1->data, n2->data, n2->len));
+static inline int
+same_name(const char *n1, const char *n2) {
+	return 0 == memcmp(n1, n2, HEXDIR_LEN);
 }
 
 static int
@@ -446,7 +461,7 @@ check_name(struct xdr_netobj name) {
 	return 1;
 }
 
-void
+static void
 add_to_unconfirmed(struct nfs4_client *clp, unsigned int strhashval)
 {
 	unsigned int idhashval;
@@ -458,7 +473,7 @@ add_to_unconfirmed(struct nfs4_client *c
 	clp->cl_time = get_seconds();
 }
 
-void
+static void
 move_to_confirmed(struct nfs4_client *clp)
 {
 	unsigned int idhashval = clientid_hashval(clp->cl_clientid.cl_id);
@@ -468,8 +483,7 @@ move_to_confirmed(struct nfs4_client *cl
 	list_del_init(&clp->cl_strhash);
 	list_del_init(&clp->cl_idhash);
 	list_add(&clp->cl_idhash, &conf_id_hashtbl[idhashval]);
-	strhashval = clientstr_hashval(clp->cl_name.data, 
-			clp->cl_name.len);
+	strhashval = clientstr_hashval(clp->cl_recdir);
 	list_add(&clp->cl_strhash, &conf_str_hashtbl[strhashval]);
 	renew_client(clp);
 }
@@ -500,6 +514,30 @@ find_unconfirmed_client(clientid_t *clid
 	return NULL;
 }
 
+static struct nfs4_client *
+find_confirmed_client_by_str(const char *dname, unsigned int hashval)
+{
+	struct nfs4_client *clp;
+
+	list_for_each_entry(clp, &conf_str_hashtbl[hashval], cl_strhash) {
+		if (same_name(clp->cl_recdir, dname))
+			return clp;
+	}
+	return NULL;
+}
+
+static struct nfs4_client *
+find_unconfirmed_client_by_str(const char *dname, unsigned int hashval)
+{
+	struct nfs4_client *clp;
+
+	list_for_each_entry(clp, &unconf_str_hashtbl[hashval], cl_strhash) {
+		if (same_name(clp->cl_recdir, dname))
+			return clp;
+	}
+	return NULL;
+}
+
 /* a helper function for parse_callback */
 static int
 parse_octet(unsigned int *lenp, char **addrp)
@@ -534,7 +572,7 @@ parse_octet(unsigned int *lenp, char **a
 }
 
 /* parse and set the setclientid ipv4 callback address */
-int
+static int
 parse_ipv4(unsigned int addr_len, char *addr_val, unsigned int *cbaddrp, unsigned short *cbportp)
 {
 	int temp = 0;
@@ -570,7 +608,7 @@ parse_ipv4(unsigned int addr_len, char *
 	return 1;
 }
 
-void
+static void
 gen_callback(struct nfs4_client *clp, struct nfsd4_setclientid *se)
 {
 	struct nfs4_callback *cb = &clp->cl_callback;
@@ -584,14 +622,12 @@ gen_callback(struct nfs4_client *clp, st
 		goto out_err;
 	cb->cb_prog = se->se_callback_prog;
 	cb->cb_ident = se->se_callback_ident;
-	cb->cb_parsed = 1;
 	return;
 out_err:
 	printk(KERN_INFO "NFSD: this client (clientid %08x/%08x) "
 		"will not receive delegations\n",
 		clp->cl_clientid.cl_boot, clp->cl_clientid.cl_id);
 
-	cb->cb_parsed = 0;
 	return;
 }
 
@@ -638,59 +674,43 @@ nfsd4_setclientid(struct svc_rqst *rqstp
 	};
 	nfs4_verifier		clverifier = setclid->se_verf;
 	unsigned int 		strhashval;
-	struct nfs4_client *	conf, * unconf, * new, * clp;
+	struct nfs4_client	*conf, *unconf, *new;
 	int 			status;
+	char                    dname[HEXDIR_LEN];
 	
 	status = nfserr_inval;
 	if (!check_name(clname))
 		goto out;
 
+	status = nfs4_make_rec_clidname(dname, &clname);
+	if (status)
+		goto out;
+
 	/* 
 	 * XXX The Duplicate Request Cache (DRC) has been checked (??)
 	 * We get here on a DRC miss.
 	 */
 
-	strhashval = clientstr_hashval(clname.data, clname.len);
+	strhashval = clientstr_hashval(dname);
 
-	conf = NULL;
 	nfs4_lock_state();
-	list_for_each_entry(clp, &conf_str_hashtbl[strhashval], cl_strhash) {
-		if (!cmp_name(&clp->cl_name, &clname))
-			continue;
+	conf = find_confirmed_client_by_str(dname, strhashval);
+	if (conf) {
 		/* 
 		 * CASE 0:
 		 * clname match, confirmed, different principal
 		 * or different ip_address
 		 */
 		status = nfserr_clid_inuse;
-		if (!cmp_creds(&clp->cl_cred,&rqstp->rq_cred)) {
+		if (!cmp_creds(&conf->cl_cred, &rqstp->rq_cred)
+				|| conf->cl_addr != ip_addr) {
 			printk("NFSD: setclientid: string in use by client"
 			"(clientid %08x/%08x)\n",
-			clp->cl_clientid.cl_boot, clp->cl_clientid.cl_id);
+			conf->cl_clientid.cl_boot, conf->cl_clientid.cl_id);
 			goto out;
 		}
-		if (clp->cl_addr != ip_addr) { 
-			printk("NFSD: setclientid: string in use by client"
-			"(clientid %08x/%08x)\n",
-			clp->cl_clientid.cl_boot, clp->cl_clientid.cl_id);
-			goto out;
-		}
-
-		/* 
-	 	 * cl_name match from a previous SETCLIENTID operation
-	 	 * XXX check for additional matches?
-		 */
-		conf = clp;
-		break;
-	}
-	unconf = NULL;
-	list_for_each_entry(clp, &unconf_str_hashtbl[strhashval], cl_strhash) {
-		if (!cmp_name(&clp->cl_name, &clname))
-			continue;
-		/* cl_name match from a previous SETCLIENTID operation */
-		unconf = clp;
-		break;
 	}
+	unconf = find_unconfirmed_client_by_str(dname, strhashval);
 	status = nfserr_resource;
 	if (!conf) {
 		/* 
@@ -699,7 +719,8 @@ nfsd4_setclientid(struct svc_rqst *rqstp
 		 */
 		if (unconf)
 			expire_client(unconf);
-		if (!(new = create_client(clname)))
+		new = create_client(clname, dname);
+		if (new == NULL)
 			goto out;
 		copy_verf(new, &clverifier);
 		new->cl_addr = ip_addr;
@@ -722,12 +743,16 @@ nfsd4_setclientid(struct svc_rqst *rqstp
 		 * nfs4_client,  but with the new callback info and a 
 		 * new cl_confirm
 		 */
-		if ((unconf) && 
-		    cmp_verf(&unconf->cl_verifier, &conf->cl_verifier) &&
-		     cmp_clid(&unconf->cl_clientid, &conf->cl_clientid)) {
-				expire_client(unconf);
+		if (unconf) {
+			/* Note this is removing unconfirmed {*x***},
+			 * which is stronger than RFC recommended {vxc**}.
+			 * This has the advantage that there is at most
+			 * one {*x***} in either list at any time.
+			 */
+			expire_client(unconf);
 		}
-		if (!(new = create_client(clname)))
+		new = create_client(clname, dname);
+		if (new == NULL)
 			goto out;
 		copy_verf(new,&conf->cl_verifier);
 		new->cl_addr = ip_addr;
@@ -745,7 +770,8 @@ nfsd4_setclientid(struct svc_rqst *rqstp
 		 * using input clverifier, clname, and callback info
 		 * and generate a new cl_clientid and cl_confirm.
 		 */
-		if (!(new = create_client(clname)))
+		new = create_client(clname, dname);
+		if (new == NULL)
 			goto out;
 		copy_verf(new,&clverifier);
 		new->cl_addr = ip_addr;
@@ -771,7 +797,8 @@ nfsd4_setclientid(struct svc_rqst *rqstp
 		 * new cl_verifier and a new cl_confirm
 		 */
 		expire_client(unconf);
-		if (!(new = create_client(clname)))
+		new = create_client(clname, dname);
+		if (new == NULL)
 			goto out;
 		copy_verf(new,&clverifier);
 		new->cl_addr = ip_addr;
@@ -807,7 +834,7 @@ int
 nfsd4_setclientid_confirm(struct svc_rqst *rqstp, struct nfsd4_setclientid_confirm *setclientid_confirm)
 {
 	u32 ip_addr = rqstp->rq_addr.sin_addr.s_addr;
-	struct nfs4_client *clp, *conf = NULL, *unconf = NULL;
+	struct nfs4_client *conf, *unconf;
 	nfs4_verifier confirm = setclientid_confirm->sc_confirm; 
 	clientid_t * clid = &setclientid_confirm->sc_clientid;
 	int status;
@@ -820,102 +847,91 @@ nfsd4_setclientid_confirm(struct svc_rqs
 	 */
 
 	nfs4_lock_state();
-	clp = find_confirmed_client(clid);
-	if (clp) {
-		status = nfserr_inval;
-		/* 
-		 * Found a record for this clientid. If the IP addresses
-		 * don't match, return ERR_INVAL just as if the record had
-		 * not been found.
-		 */
-		if (clp->cl_addr != ip_addr) { 
-			printk("NFSD: setclientid: string in use by client"
-			"(clientid %08x/%08x)\n",
-			clp->cl_clientid.cl_boot, clp->cl_clientid.cl_id);
-			goto out;
-		}
-		conf = clp;
-	}
-	clp = find_unconfirmed_client(clid);
-	if (clp) {
-		status = nfserr_inval;
-		if (clp->cl_addr != ip_addr) { 
-			printk("NFSD: setclientid: string in use by client"
-			"(clientid %08x/%08x)\n",
-			clp->cl_clientid.cl_boot, clp->cl_clientid.cl_id);
-			goto out;
-		}
-		unconf = clp;
-	}
-	/* CASE 1: 
-	* unconf record that matches input clientid and input confirm.
-	* conf record that matches input clientid.
-	* conf  and unconf records match names, verifiers 
-	*/
+
+	conf = find_confirmed_client(clid);
+	unconf = find_unconfirmed_client(clid);
+
+	status = nfserr_clid_inuse;
+	if (conf && conf->cl_addr != ip_addr)
+		goto out;
+	if (unconf && unconf->cl_addr != ip_addr)
+		goto out;
+
 	if ((conf && unconf) && 
 	    (cmp_verf(&unconf->cl_confirm, &confirm)) &&
 	    (cmp_verf(&conf->cl_verifier, &unconf->cl_verifier)) &&
-	    (cmp_name(&conf->cl_name,&unconf->cl_name))  &&
+	    (same_name(conf->cl_recdir,unconf->cl_recdir))  &&
 	    (!cmp_verf(&conf->cl_confirm, &unconf->cl_confirm))) {
+		/* CASE 1:
+		* unconf record that matches input clientid and input confirm.
+		* conf record that matches input clientid.
+		* conf and unconf records match names, verifiers
+		*/
 		if (!cmp_creds(&conf->cl_cred, &unconf->cl_cred)) 
 			status = nfserr_clid_inuse;
 		else {
-			expire_client(conf);
-			clp = unconf;
-			move_to_confirmed(unconf);
+			/* XXX: We just turn off callbacks until we can handle
+			  * change request correctly. */
+			atomic_set(&conf->cl_callback.cb_set, 0);
+			gen_confirm(conf);
+			nfsd4_remove_clid_dir(unconf);
+			expire_client(unconf);
 			status = nfs_ok;
+
 		}
-		goto out;
-	} 
-	/* CASE 2:
-	 * conf record that matches input clientid.
-	 * if unconf record that matches input clientid, then unconf->cl_name
-	 * or unconf->cl_verifier don't match the conf record.
-	 */
-	if ((conf && !unconf) || 
+	} else if ((conf && !unconf) ||
 	    ((conf && unconf) && 
 	     (!cmp_verf(&conf->cl_verifier, &unconf->cl_verifier) ||
-	      !cmp_name(&conf->cl_name, &unconf->cl_name)))) {
-		if (!cmp_creds(&conf->cl_cred,&rqstp->rq_cred)) {
+	      !same_name(conf->cl_recdir, unconf->cl_recdir)))) {
+		/* CASE 2:
+		 * conf record that matches input clientid.
+		 * if unconf record matches input clientid, then
+		 * unconf->cl_name or unconf->cl_verifier don't match the
+		 * conf record.
+		 */
+		if (!cmp_creds(&conf->cl_cred,&rqstp->rq_cred))
 			status = nfserr_clid_inuse;
-		} else {
-			clp = conf;
+		else
 			status = nfs_ok;
-		}
-		goto out;
-	}
-	/* CASE 3:
-	 * conf record not found.
-	 * unconf record found. 
-	 * unconf->cl_confirm matches input confirm
-	 */ 
-	if (!conf && unconf && cmp_verf(&unconf->cl_confirm, &confirm)) {
+	} else if (!conf && unconf
+			&& cmp_verf(&unconf->cl_confirm, &confirm)) {
+		/* CASE 3:
+		 * conf record not found.
+		 * unconf record found.
+		 * unconf->cl_confirm matches input confirm
+		 */
 		if (!cmp_creds(&unconf->cl_cred, &rqstp->rq_cred)) {
 			status = nfserr_clid_inuse;
 		} else {
-			status = nfs_ok;
-			clp = unconf;
+			unsigned int hash =
+				clientstr_hashval(unconf->cl_recdir);
+			conf = find_confirmed_client_by_str(unconf->cl_recdir,
+									hash);
+			if (conf) {
+				nfsd4_remove_clid_dir(conf);
+				expire_client(conf);
+			}
 			move_to_confirmed(unconf);
+			conf = unconf;
+			status = nfs_ok;
 		}
-		goto out;
-	}
-	/* CASE 4:
-	 * conf record not found, or if conf, then conf->cl_confirm does not
-	 * match input confirm.
-	 * unconf record not found, or if unconf, then unconf->cl_confirm 
-	 * does not match input confirm.
-	 */
-	if ((!conf || (conf && !cmp_verf(&conf->cl_confirm, &confirm))) &&
-	    (!unconf || (unconf && !cmp_verf(&unconf->cl_confirm, &confirm)))) {
+	} else if ((!conf || (conf && !cmp_verf(&conf->cl_confirm, &confirm)))
+	    && (!unconf || (unconf && !cmp_verf(&unconf->cl_confirm,
+				    				&confirm)))) {
+		/* CASE 4:
+		 * conf record not found, or if conf, conf->cl_confirm does not
+		 * match input confirm.
+		 * unconf record not found, or if unconf, unconf->cl_confirm
+		 * does not match input confirm.
+		 */
 		status = nfserr_stale_clientid;
-		goto out;
+	} else {
+		/* check that we have hit one of the cases...*/
+		status = nfserr_clid_inuse;
 	}
-	/* check that we have hit one of the cases...*/
-	status = nfserr_inval;
-	goto out;
 out:
 	if (!status)
-		nfsd4_probe_callback(clp);
+		nfsd4_probe_callback(conf);
 	nfs4_unlock_state();
 	return status;
 }
@@ -961,60 +977,65 @@ alloc_init_file(struct inode *ino)
 	struct nfs4_file *fp;
 	unsigned int hashval = file_hashval(ino);
 
-	if ((fp = kmalloc(sizeof(struct nfs4_file),GFP_KERNEL))) {
+	fp = kmem_cache_alloc(file_slab, GFP_KERNEL);
+	if (fp) {
+		kref_init(&fp->fi_ref);
 		INIT_LIST_HEAD(&fp->fi_hash);
-		INIT_LIST_HEAD(&fp->fi_perfile);
-		INIT_LIST_HEAD(&fp->fi_del_perfile);
+		INIT_LIST_HEAD(&fp->fi_stateids);
+		INIT_LIST_HEAD(&fp->fi_delegations);
 		list_add(&fp->fi_hash, &file_hashtbl[hashval]);
 		fp->fi_inode = igrab(ino);
 		fp->fi_id = current_fileid++;
-		alloc_file++;
 		return fp;
 	}
 	return NULL;
 }
 
 static void
-release_all_files(void)
+nfsd4_free_slab(kmem_cache_t **slab)
 {
-	int i;
-	struct nfs4_file *fp;
+	int status;
 
-	for (i=0;i<FILE_HASH_SIZE;i++) {
-		while (!list_empty(&file_hashtbl[i])) {
-			fp = list_entry(file_hashtbl[i].next, struct nfs4_file, fi_hash);
-			/* this should never be more than once... */
-			if (!list_empty(&fp->fi_perfile) || !list_empty(&fp->fi_del_perfile)) {
-				printk("ERROR: release_all_files: file %p is open, creating dangling state !!!\n",fp);
-			}
-			release_file(fp);
-		}
-	}
+	if (*slab == NULL)
+		return;
+	status = kmem_cache_destroy(*slab);
+	*slab = NULL;
+	WARN_ON(status);
 }
 
-kmem_cache_t *stateowner_slab = NULL;
+static void
+nfsd4_free_slabs(void)
+{
+	nfsd4_free_slab(&stateowner_slab);
+	nfsd4_free_slab(&file_slab);
+	nfsd4_free_slab(&stateid_slab);
+	nfsd4_free_slab(&deleg_slab);
+}
 
 static int
 nfsd4_init_slabs(void)
 {
 	stateowner_slab = kmem_cache_create("nfsd4_stateowners",
 			sizeof(struct nfs4_stateowner), 0, 0, NULL, NULL);
-	if (stateowner_slab == NULL) {
-		dprintk("nfsd4: out of memory while initializing nfsv4\n");
-		return -ENOMEM;
-	}
+	if (stateowner_slab == NULL)
+		goto out_nomem;
+	file_slab = kmem_cache_create("nfsd4_files",
+			sizeof(struct nfs4_file), 0, 0, NULL, NULL);
+	if (file_slab == NULL)
+		goto out_nomem;
+	stateid_slab = kmem_cache_create("nfsd4_stateids",
+			sizeof(struct nfs4_stateid), 0, 0, NULL, NULL);
+	if (stateid_slab == NULL)
+		goto out_nomem;
+	deleg_slab = kmem_cache_create("nfsd4_delegations",
+			sizeof(struct nfs4_delegation), 0, 0, NULL, NULL);
+	if (deleg_slab == NULL)
+		goto out_nomem;
 	return 0;
-}
-
-static void
-nfsd4_free_slabs(void)
-{
-	int status = 0;
-
-	if (stateowner_slab)
-		status = kmem_cache_destroy(stateowner_slab);
-	stateowner_slab = NULL;
-	BUG_ON(status);
+out_nomem:
+	nfsd4_free_slabs();
+	dprintk("nfsd4: out of memory while initializing nfsv4\n");
+	return -ENOMEM;
 }
 
 void
@@ -1055,14 +1076,13 @@ alloc_init_open_stateowner(unsigned int 
 	INIT_LIST_HEAD(&sop->so_idhash);
 	INIT_LIST_HEAD(&sop->so_strhash);
 	INIT_LIST_HEAD(&sop->so_perclient);
-	INIT_LIST_HEAD(&sop->so_perfilestate);
-	INIT_LIST_HEAD(&sop->so_perlockowner);  /* not used */
+	INIT_LIST_HEAD(&sop->so_stateids);
+	INIT_LIST_HEAD(&sop->so_perstateid);  /* not used */
 	INIT_LIST_HEAD(&sop->so_close_lru);
 	sop->so_time = 0;
 	list_add(&sop->so_idhash, &ownerid_hashtbl[idhashval]);
 	list_add(&sop->so_strhash, &ownerstr_hashtbl[strhashval]);
-	list_add(&sop->so_perclient, &clp->cl_perclient);
-	add_perclient++;
+	list_add(&sop->so_perclient, &clp->cl_openowners);
 	sop->so_is_open_owner = 1;
 	sop->so_id = current_ownerid++;
 	sop->so_client = clp;
@@ -1080,10 +1100,10 @@ release_stateid_lockowners(struct nfs4_s
 {
 	struct nfs4_stateowner *lock_sop;
 
-	while (!list_empty(&open_stp->st_perlockowner)) {
-		lock_sop = list_entry(open_stp->st_perlockowner.next,
-				struct nfs4_stateowner, so_perlockowner);
-		/* list_del(&open_stp->st_perlockowner);  */
+	while (!list_empty(&open_stp->st_lockowners)) {
+		lock_sop = list_entry(open_stp->st_lockowners.next,
+				struct nfs4_stateowner, so_perstateid);
+		/* list_del(&open_stp->st_lockowners);  */
 		BUG_ON(lock_sop->so_is_open_owner);
 		release_stateowner(lock_sop);
 	}
@@ -1096,14 +1116,12 @@ unhash_stateowner(struct nfs4_stateowner
 
 	list_del(&sop->so_idhash);
 	list_del(&sop->so_strhash);
-	if (sop->so_is_open_owner) {
+	if (sop->so_is_open_owner)
 		list_del(&sop->so_perclient);
-		del_perclient++;
-	}
-	list_del(&sop->so_perlockowner);
-	while (!list_empty(&sop->so_perfilestate)) {
-		stp = list_entry(sop->so_perfilestate.next, 
-			struct nfs4_stateid, st_perfilestate);
+	list_del(&sop->so_perstateid);
+	while (!list_empty(&sop->so_stateids)) {
+		stp = list_entry(sop->so_stateids.next,
+			struct nfs4_stateid, st_perstateowner);
 		if (sop->so_is_open_owner)
 			release_stateid(stp, OPEN_STATE);
 		else
@@ -1125,14 +1143,14 @@ init_stateid(struct nfs4_stateid *stp, s
 	unsigned int hashval = stateid_hashval(sop->so_id, fp->fi_id);
 
 	INIT_LIST_HEAD(&stp->st_hash);
-	INIT_LIST_HEAD(&stp->st_perfilestate);
-	INIT_LIST_HEAD(&stp->st_perlockowner);
+	INIT_LIST_HEAD(&stp->st_perstateowner);
+	INIT_LIST_HEAD(&stp->st_lockowners);
 	INIT_LIST_HEAD(&stp->st_perfile);
 	list_add(&stp->st_hash, &stateid_hashtbl[hashval]);
-	list_add(&stp->st_perfilestate, &sop->so_perfilestate);
-	list_add_perfile++;
-	list_add(&stp->st_perfile, &fp->fi_perfile);
+	list_add(&stp->st_perstateowner, &sop->so_stateids);
+	list_add(&stp->st_perfile, &fp->fi_stateids);
 	stp->st_stateowner = sop;
+	get_nfs4_file(fp);
 	stp->st_file = fp;
 	stp->st_stateid.si_boot = boot_time;
 	stp->st_stateid.si_stateownerid = sop->so_id;
@@ -1142,6 +1160,7 @@ init_stateid(struct nfs4_stateid *stp, s
 	stp->st_deny_bmap = 0;
 	__set_bit(open->op_share_access, &stp->st_access_bmap);
 	__set_bit(open->op_share_deny, &stp->st_deny_bmap);
+	stp->st_openstp = NULL;
 }
 
 static void
@@ -1150,30 +1169,20 @@ release_stateid(struct nfs4_stateid *stp
 	struct file *filp = stp->st_vfs_file;
 
 	list_del(&stp->st_hash);
-	list_del_perfile++;
 	list_del(&stp->st_perfile);
-	list_del(&stp->st_perfilestate);
+	list_del(&stp->st_perstateowner);
 	if (flags & OPEN_STATE) {
 		release_stateid_lockowners(stp);
 		stp->st_vfs_file = NULL;
 		nfsd_close(filp);
-		vfsclose++;
 	} else if (flags & LOCK_STATE)
 		locks_remove_posix(filp, (fl_owner_t) stp->st_stateowner);
-	kfree(stp);
+	put_nfs4_file(stp->st_file);
+	kmem_cache_free(stateid_slab, stp);
 	stp = NULL;
 }
 
 static void
-release_file(struct nfs4_file *fp)
-{
-	free_file++;
-	list_del(&fp->fi_hash);
-	iput(fp->fi_inode);
-	kfree(fp);
-}	
-
-void
 move_to_close_lru(struct nfs4_stateowner *sop)
 {
 	dprintk("NFSD: move_to_close_lru nfs4_stateowner %p\n", sop);
@@ -1183,11 +1192,10 @@ move_to_close_lru(struct nfs4_stateowner
 	sop->so_time = get_seconds();
 }
 
-void
+static void
 release_state_owner(struct nfs4_stateid *stp, int flag)
 {
 	struct nfs4_stateowner *sop = stp->st_stateowner;
-	struct nfs4_file *fp = stp->st_file;
 
 	dprintk("NFSD: release_state_owner\n");
 	release_stateid(stp, flag);
@@ -1196,12 +1204,8 @@ release_state_owner(struct nfs4_stateid 
 	 * released by the laundromat service after the lease period
 	 * to enable us to handle CLOSE replay
 	 */
-	if (sop->so_confirmed && list_empty(&sop->so_perfilestate))
+	if (sop->so_confirmed && list_empty(&sop->so_stateids))
 		move_to_close_lru(sop);
-	/* unused nfs4_file's are releseed. XXX slab cache? */
-	if (list_empty(&fp->fi_perfile) && list_empty(&fp->fi_del_perfile)) {
-		release_file(fp);
-	}
 }
 
 static int
@@ -1231,8 +1235,10 @@ find_file(struct inode *ino)
 	struct nfs4_file *fp;
 
 	list_for_each_entry(fp, &file_hashtbl[hashval], fi_hash) {
-		if (fp->fi_inode == ino)
+		if (fp->fi_inode == ino) {
+			get_nfs4_file(fp);
 			return fp;
+		}
 	}
 	return NULL;
 }
@@ -1240,7 +1246,7 @@ find_file(struct inode *ino)
 #define TEST_ACCESS(x) ((x > 0 || x < 4)?1:0)
 #define TEST_DENY(x) ((x >= 0 || x < 5)?1:0)
 
-void
+static void
 set_access(unsigned int *access, unsigned long bmap) {
 	int i;
 
@@ -1251,7 +1257,7 @@ set_access(unsigned int *access, unsigne
 	}
 }
 
-void
+static void
 set_deny(unsigned int *deny, unsigned long bmap) {
 	int i;
 
@@ -1277,25 +1283,30 @@ test_share(struct nfs4_stateid *stp, str
  * Called to check deny when READ with all zero stateid or
  * WRITE with all zero or all one stateid
  */
-int
+static int
 nfs4_share_conflict(struct svc_fh *current_fh, unsigned int deny_type)
 {
 	struct inode *ino = current_fh->fh_dentry->d_inode;
 	struct nfs4_file *fp;
 	struct nfs4_stateid *stp;
+	int ret;
 
 	dprintk("NFSD: nfs4_share_conflict\n");
 
 	fp = find_file(ino);
-	if (fp) {
+	if (!fp)
+		return nfs_ok;
+	ret = nfserr_locked;
 	/* Search for conflicting share reservations */
-		list_for_each_entry(stp, &fp->fi_perfile, st_perfile) {
-			if (test_bit(deny_type, &stp->st_deny_bmap) ||
-			    test_bit(NFS4_SHARE_DENY_BOTH, &stp->st_deny_bmap))
-				return nfserr_share_denied;
-		}
+	list_for_each_entry(stp, &fp->fi_stateids, st_perfile) {
+		if (test_bit(deny_type, &stp->st_deny_bmap) ||
+		    test_bit(NFS4_SHARE_DENY_BOTH, &stp->st_deny_bmap))
+			goto out;
 	}
-	return nfs_ok;
+	ret = nfs_ok;
+out:
+	put_nfs4_file(fp);
+	return ret;
 }
 
 static inline void
@@ -1427,7 +1438,7 @@ int nfsd_change_deleg_cb(struct file_loc
 		return -EAGAIN;
 }
 
-struct lock_manager_operations nfsd_lease_mng_ops = {
+static struct lock_manager_operations nfsd_lease_mng_ops = {
 	.fl_break = nfsd_break_deleg_cb,
 	.fl_release_private = nfsd_release_deleg_cb,
 	.fl_copy_lock = nfsd_copy_lock_deleg_cb,
@@ -1473,7 +1484,7 @@ nfsd4_process_open1(struct nfsd4_open *o
 	if (sop) {
 		open->op_stateowner = sop;
 		/* check for replay */
-		if (open->op_seqid == sop->so_seqid){
+		if (open->op_seqid == sop->so_seqid - 1){
 			if (sop->so_replay.rp_buflen)
 				return NFSERR_REPLAY_ME;
 			else {
@@ -1488,7 +1499,7 @@ nfsd4_process_open1(struct nfsd4_open *o
 				goto renew;
 			}
 		} else if (sop->so_confirmed) {
-			if (open->op_seqid == sop->so_seqid + 1)
+			if (open->op_seqid == sop->so_seqid)
 				goto renew;
 			status = nfserr_bad_seqid;
 			goto out;
@@ -1521,11 +1532,54 @@ renew:
 	status = nfs_ok;
 	renew_client(sop->so_client);
 out:
-	if (status && open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS)
-		status = nfserr_reclaim_bad;
 	return status;
 }
 
+static inline int
+nfs4_check_delegmode(struct nfs4_delegation *dp, int flags)
+{
+	if ((flags & WR_STATE) && (dp->dl_type == NFS4_OPEN_DELEGATE_READ))
+		return nfserr_openmode;
+	else
+		return nfs_ok;
+}
+
+static struct nfs4_delegation *
+find_delegation_file(struct nfs4_file *fp, stateid_t *stid)
+{
+	struct nfs4_delegation *dp;
+
+	list_for_each_entry(dp, &fp->fi_delegations, dl_perfile) {
+		if (dp->dl_stateid.si_stateownerid == stid->si_stateownerid)
+			return dp;
+	}
+	return NULL;
+}
+
+static int
+nfs4_check_deleg(struct nfs4_file *fp, struct nfsd4_open *open,
+		struct nfs4_delegation **dp)
+{
+	int flags;
+	int status = nfserr_bad_stateid;
+
+	*dp = find_delegation_file(fp, &open->op_delegate_stateid);
+	if (*dp == NULL)
+		goto out;
+	flags = open->op_share_access == NFS4_SHARE_ACCESS_READ ?
+						RD_STATE : WR_STATE;
+	status = nfs4_check_delegmode(*dp, flags);
+	if (status)
+		*dp = NULL;
+out:
+	if (open->op_claim_type != NFS4_OPEN_CLAIM_DELEGATE_CUR)
+		return nfs_ok;
+	if (status)
+		return status;
+	open->op_stateowner->so_confirmed = 1;
+	return nfs_ok;
+}
+
 static int
 nfs4_check_open(struct nfs4_file *fp, struct nfsd4_open *open, struct nfs4_stateid **stpp)
 {
@@ -1533,7 +1587,7 @@ nfs4_check_open(struct nfs4_file *fp, st
 	int status = nfserr_share_denied;
 	struct nfs4_stateowner *sop = open->op_stateowner;
 
-	list_for_each_entry(local, &fp->fi_perfile, st_perfile) {
+	list_for_each_entry(local, &fp->fi_stateids, st_perfile) {
 		/* ignore lock owners */
 		if (local->st_stateowner->so_is_open_owner == 0)
 			continue;
@@ -1549,25 +1603,37 @@ out:
 	return status;
 }
 
+static inline struct nfs4_stateid *
+nfs4_alloc_stateid(void)
+{
+	return kmem_cache_alloc(stateid_slab, GFP_KERNEL);
+}
+
 static int
 nfs4_new_open(struct svc_rqst *rqstp, struct nfs4_stateid **stpp,
+		struct nfs4_delegation *dp,
 		struct svc_fh *cur_fh, int flags)
 {
 	struct nfs4_stateid *stp;
-	int status;
 
-	stp = kmalloc(sizeof(struct nfs4_stateid), GFP_KERNEL);
+	stp = nfs4_alloc_stateid();
 	if (stp == NULL)
 		return nfserr_resource;
 
-	status = nfsd_open(rqstp, cur_fh, S_IFREG, flags, &stp->st_vfs_file);
-	if (status) {
-		if (status == nfserr_dropit)
-			status = nfserr_jukebox;
-		kfree(stp);
-		return status;
+	if (dp) {
+		get_file(dp->dl_vfs_file);
+		stp->st_vfs_file = dp->dl_vfs_file;
+	} else {
+		int status;
+		status = nfsd_open(rqstp, cur_fh, S_IFREG, flags,
+				&stp->st_vfs_file);
+		if (status) {
+			if (status == nfserr_dropit)
+				status = nfserr_jukebox;
+			kmem_cache_free(stateid_slab, stp);
+			return status;
+		}
 	}
-	vfsopen++;
 	*stpp = stp;
 	return 0;
 }
@@ -1619,18 +1685,11 @@ nfs4_upgrade_open(struct svc_rqst *rqstp
 }
 
 
-/* decrement seqid on successful reclaim, it will be bumped in encode_open */
 static void
-nfs4_set_claim_prev(struct nfsd4_open *open, int *status)
+nfs4_set_claim_prev(struct nfsd4_open *open)
 {
-	if (open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS) {
-		if (*status)
-			*status = nfserr_reclaim_bad;
-		else {
-			open->op_stateowner->so_confirmed = 1;
-			open->op_stateowner->so_seqid--;
-		}
-	}
+	open->op_stateowner->so_confirmed = 1;
+	open->op_stateowner->so_client->cl_firststate = 1;
 }
 
 /*
@@ -1646,14 +1705,30 @@ nfs4_open_delegation(struct svc_fh *fh, 
 	int status, flag = 0;
 
 	flag = NFS4_OPEN_DELEGATE_NONE;
-	if (open->op_claim_type != NFS4_OPEN_CLAIM_NULL
-	     || !atomic_read(&cb->cb_set) || !sop->so_confirmed)
-		goto out;
-
-	if (open->op_share_access & NFS4_SHARE_ACCESS_WRITE)
-		flag = NFS4_OPEN_DELEGATE_WRITE;
-	else
-		flag = NFS4_OPEN_DELEGATE_READ;
+	open->op_recall = 0;
+	switch (open->op_claim_type) {
+		case NFS4_OPEN_CLAIM_PREVIOUS:
+			if (!atomic_read(&cb->cb_set))
+				open->op_recall = 1;
+			flag = open->op_delegate_type;
+			if (flag == NFS4_OPEN_DELEGATE_NONE)
+				goto out;
+			break;
+		case NFS4_OPEN_CLAIM_NULL:
+			/* Let's not give out any delegations till everyone's
+			 * had the chance to reclaim theirs.... */
+			if (nfs4_in_grace())
+				goto out;
+			if (!atomic_read(&cb->cb_set) || !sop->so_confirmed)
+				goto out;
+			if (open->op_share_access & NFS4_SHARE_ACCESS_WRITE)
+				flag = NFS4_OPEN_DELEGATE_WRITE;
+			else
+				flag = NFS4_OPEN_DELEGATE_READ;
+			break;
+		default:
+			goto out;
+	}
 
 	dp = alloc_init_deleg(sop->so_client, stp, fh, flag);
 	if (dp == NULL) {
@@ -1687,6 +1762,10 @@ nfs4_open_delegation(struct svc_fh *fh, 
 	             dp->dl_stateid.si_fileid,
 	             dp->dl_stateid.si_generation);
 out:
+	if (open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS
+			&& flag == NFS4_OPEN_DELEGATE_NONE
+			&& open->op_delegate_type != NFS4_OPEN_DELEGATE_NONE)
+		printk("NFSD: WARNING: refusing delegation reclaim\n");
 	open->op_delegate_type = flag;
 }
 
@@ -1699,8 +1778,15 @@ nfsd4_process_open2(struct svc_rqst *rqs
 	struct nfs4_file *fp = NULL;
 	struct inode *ino = current_fh->fh_dentry->d_inode;
 	struct nfs4_stateid *stp = NULL;
+	struct nfs4_delegation *dp = NULL;
 	int status;
 
+	if (nfs4_in_grace() && open->op_claim_type != NFS4_OPEN_CLAIM_PREVIOUS)
+		return nfserr_grace;
+
+	if (!nfs4_in_grace() && open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS)
+		return nfserr_no_grace;
+
 	status = nfserr_inval;
 	if (!TEST_ACCESS(open->op_share_access) || !TEST_DENY(open->op_share_deny))
 		goto out;
@@ -1713,7 +1799,13 @@ nfsd4_process_open2(struct svc_rqst *rqs
 	if (fp) {
 		if ((status = nfs4_check_open(fp, open, &stp)))
 			goto out;
+		status = nfs4_check_deleg(fp, open, &dp);
+		if (status)
+			goto out;
 	} else {
+		status = nfserr_bad_stateid;
+		if (open->op_claim_type == NFS4_OPEN_CLAIM_DELEGATE_CUR)
+			goto out;
 		status = nfserr_resource;
 		fp = alloc_init_file(ino);
 		if (fp == NULL)
@@ -1729,6 +1821,7 @@ nfsd4_process_open2(struct svc_rqst *rqs
 		status = nfs4_upgrade_open(rqstp, current_fh, stp, open);
 		if (status)
 			goto out;
+		update_stateid(&stp->st_stateid);
 	} else {
 		/* Stateid was not found, this is a new OPEN */
 		int flags = 0;
@@ -1736,7 +1829,8 @@ nfsd4_process_open2(struct svc_rqst *rqs
 			flags = MAY_WRITE;
 		else
 			flags = MAY_READ;
-		if ((status = nfs4_new_open(rqstp, &stp, current_fh, flags)))
+		status = nfs4_new_open(rqstp, &stp, dp, current_fh, flags);
+		if (status)
 			goto out;
 		init_stateid(stp, fp, open);
 		status = nfsd4_truncate(rqstp, current_fh, open);
@@ -1759,12 +1853,10 @@ nfsd4_process_open2(struct svc_rqst *rqs
 	            stp->st_stateid.si_boot, stp->st_stateid.si_stateownerid,
 	            stp->st_stateid.si_fileid, stp->st_stateid.si_generation);
 out:
-	/* take the opportunity to clean up unused state */
-	if (fp && list_empty(&fp->fi_perfile) && list_empty(&fp->fi_del_perfile))
-		release_file(fp);
-
-	/* CLAIM_PREVIOUS has different error returns */
-	nfs4_set_claim_prev(open, &status);
+	if (fp)
+		put_nfs4_file(fp);
+	if (status == 0 && open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS)
+		nfs4_set_claim_prev(open);
 	/*
 	* To finish the open response, we just need to set the rflags.
 	*/
@@ -1775,6 +1867,7 @@ out:
 	return status;
 }
 
+static struct workqueue_struct *laundry_wq;
 static struct work_struct laundromat_work;
 static void laundromat_main(void *);
 static DECLARE_WORK(laundromat_work, laundromat_main, NULL);
@@ -1800,7 +1893,7 @@ nfsd4_renew(clientid_t *clid)
 	}
 	renew_client(clp);
 	status = nfserr_cb_path_down;
-	if (!list_empty(&clp->cl_del_perclnt)
+	if (!list_empty(&clp->cl_delegations)
 			&& !atomic_read(&clp->cl_callback.cb_set))
 		goto out;
 	status = nfs_ok;
@@ -1809,7 +1902,15 @@ out:
 	return status;
 }
 
-time_t
+static void
+end_grace(void)
+{
+	dprintk("NFSD: end of grace period\n");
+	nfsd4_recdir_purge_old();
+	in_grace = 0;
+}
+
+static time_t
 nfs4_laundromat(void)
 {
 	struct nfs4_client *clp;
@@ -1823,6 +1924,8 @@ nfs4_laundromat(void)
 	nfs4_lock_state();
 
 	dprintk("NFSD: laundromat service - starting\n");
+	if (in_grace)
+		end_grace();
 	list_for_each_safe(pos, next, &client_lru) {
 		clp = list_entry(pos, struct nfs4_client, cl_lru);
 		if (time_after((unsigned long)clp->cl_time, (unsigned long)cutoff)) {
@@ -1833,6 +1936,7 @@ nfs4_laundromat(void)
 		}
 		dprintk("NFSD: purging unused client (clientid %08x)\n",
 			clp->cl_clientid.cl_id);
+		nfsd4_remove_clid_dir(clp);
 		expire_client(clp);
 	}
 	INIT_LIST_HEAD(&reaplist);
@@ -1882,17 +1986,14 @@ laundromat_main(void *not_used)
 
 	t = nfs4_laundromat();
 	dprintk("NFSD: laundromat_main - sleeping for %ld seconds\n", t);
-	schedule_delayed_work(&laundromat_work, t*HZ);
+	queue_delayed_work(laundry_wq, &laundromat_work, t*HZ);
 }
 
-/* search ownerid_hashtbl[] and close_lru for stateid owner
- * (stateid->si_stateownerid)
- */
-struct nfs4_stateowner *
-find_openstateowner_id(u32 st_id, int flags) {
+static struct nfs4_stateowner *
+search_close_lru(u32 st_id, int flags)
+{
 	struct nfs4_stateowner *local = NULL;
 
-	dprintk("NFSD: find_openstateowner_id %d\n", st_id);
 	if (flags & CLOSE_STATE) {
 		list_for_each_entry(local, &close_lru, so_close_lru) {
 			if (local->so_id == st_id)
@@ -1949,15 +2050,6 @@ out:
 }
 
 static inline int
-nfs4_check_delegmode(struct nfs4_delegation *dp, int flags)
-{
-	if ((flags & WR_STATE) && (dp->dl_type == NFS4_OPEN_DELEGATE_READ))
-		return nfserr_openmode;
-	else
-		return nfs_ok;
-}
-
-static inline int
 check_special_stateids(svc_fh *current_fh, stateid_t *stateid, int flags)
 {
 	/* Trying to call delegreturn with a special stateid? Yuch: */
@@ -2067,14 +2159,19 @@ out:
 	return status;
 }
 
+static inline int
+setlkflg (int type)
+{
+	return (type == NFS4_READW_LT || type == NFS4_READ_LT) ?
+		RD_STATE : WR_STATE;
+}
 
 /* 
  * Checks for sequence id mutating operations. 
  */
-int
-nfs4_preprocess_seqid_op(struct svc_fh *current_fh, u32 seqid, stateid_t *stateid, int flags, struct nfs4_stateowner **sopp, struct nfs4_stateid **stpp, clientid_t *lockclid)
+static int
+nfs4_preprocess_seqid_op(struct svc_fh *current_fh, u32 seqid, stateid_t *stateid, int flags, struct nfs4_stateowner **sopp, struct nfs4_stateid **stpp, struct nfsd4_lock *lock)
 {
-	int status;
 	struct nfs4_stateid *stp;
 	struct nfs4_stateowner *sop;
 
@@ -2082,53 +2179,65 @@ nfs4_preprocess_seqid_op(struct svc_fh *
 			"stateid = (%08x/%08x/%08x/%08x)\n", seqid,
 		stateid->si_boot, stateid->si_stateownerid, stateid->si_fileid,
 		stateid->si_generation);
-			        
+
 	*stpp = NULL;
 	*sopp = NULL;
 
-	status = nfserr_bad_stateid;
 	if (ZERO_STATEID(stateid) || ONE_STATEID(stateid)) {
 		printk("NFSD: preprocess_seqid_op: magic stateid!\n");
-		goto out;
+		return nfserr_bad_stateid;
 	}
 
-	status = nfserr_stale_stateid;
 	if (STALE_STATEID(stateid))
-		goto out;
+		return nfserr_stale_stateid;
 	/*
 	* We return BAD_STATEID if filehandle doesn't match stateid, 
 	* the confirmed flag is incorrecly set, or the generation 
 	* number is incorrect.  
-	* If there is no entry in the openfile table for this id, 
-	* we can't always return BAD_STATEID;
-	* this might be a retransmitted CLOSE which has arrived after 
-	* the openfile has been released.
 	*/
-	if (!(stp = find_stateid(stateid, flags)))
-		goto no_nfs4_stateid;
-
-	status = nfserr_bad_stateid;
+	stp = find_stateid(stateid, flags);
+	if (stp == NULL) {
+		/*
+		 * Also, we should make sure this isn't just the result of
+		 * a replayed close:
+		 */
+		sop = search_close_lru(stateid->si_stateownerid, flags);
+		if (sop == NULL)
+			return nfserr_bad_stateid;
+		*sopp = sop;
+		goto check_replay;
+	}
 
-	/* for new lock stateowners:
-	 * check that the lock->v.new.open_stateid
-	 * refers to an open stateowner
-	 *
-	 * check that the lockclid (nfs4_lock->v.new.clientid) is the same
-	 * as the open_stateid->st_stateowner->so_client->clientid
-	 */
-	if (lockclid) {
+	if (lock) {
 		struct nfs4_stateowner *sop = stp->st_stateowner;
+		clientid_t *lockclid = &lock->v.new.clientid;
 		struct nfs4_client *clp = sop->so_client;
+		int lkflg = 0;
+		int status;
+
+		lkflg = setlkflg(lock->lk_type);
+
+		if (lock->lk_is_new) {
+                       if (!sop->so_is_open_owner)
+			       return nfserr_bad_stateid;
+                       if (!cmp_clid(&clp->cl_clientid, lockclid))
+			       return nfserr_bad_stateid;
+                       /* stp is the open stateid */
+                       status = nfs4_check_openmode(stp, lkflg);
+                       if (status)
+			       return status;
+               } else {
+                       /* stp is the lock stateid */
+                       status = nfs4_check_openmode(stp->st_openstp, lkflg);
+                       if (status)
+			       return status;
+               }
 
-		if (!sop->so_is_open_owner)
-			goto out;
-		if (!cmp_clid(&clp->cl_clientid, lockclid))
-			goto out;
 	}
 
 	if ((flags & CHECK_FH) && nfs4_check_fh(current_fh, stp)) {
 		printk("NFSD: preprocess_seqid_op: fh-stateid mismatch!\n");
-		goto out;
+		return nfserr_bad_stateid;
 	}
 
 	*stpp = stp;
@@ -2139,63 +2248,41 @@ nfs4_preprocess_seqid_op(struct svc_fh *
 	*  For the moment, we ignore the possibility of 
 	*  generation number wraparound.
 	*/
-	if (seqid != sop->so_seqid + 1)
+	if (seqid != sop->so_seqid)
 		goto check_replay;
 
-	if (sop->so_confirmed) {
-		if (flags & CONFIRM) {
-			printk("NFSD: preprocess_seqid_op: expected unconfirmed stateowner!\n");
-			goto out;
-		}
+	if (sop->so_confirmed && flags & CONFIRM) {
+		printk("NFSD: preprocess_seqid_op: expected"
+				" unconfirmed stateowner!\n");
+		return nfserr_bad_stateid;
 	}
-	else {
-		if (!(flags & CONFIRM)) {
-			printk("NFSD: preprocess_seqid_op: stateowner not confirmed yet!\n");
-			goto out;
-		}
+	if (!sop->so_confirmed && !(flags & CONFIRM)) {
+		printk("NFSD: preprocess_seqid_op: stateowner not"
+				" confirmed yet!\n");
+		return nfserr_bad_stateid;
 	}
 	if (stateid->si_generation > stp->st_stateid.si_generation) {
 		printk("NFSD: preprocess_seqid_op: future stateid?!\n");
-		goto out;
+		return nfserr_bad_stateid;
 	}
 
-	status = nfserr_old_stateid;
 	if (stateid->si_generation < stp->st_stateid.si_generation) {
 		printk("NFSD: preprocess_seqid_op: old stateid!\n");
-		goto out;
-	}
-	/* XXX renew the client lease here */
-	status = nfs_ok;
-
-out:
-	return status;
-
-no_nfs4_stateid:
-
-	/*
-	* We determine whether this is a bad stateid or a replay, 
-	* starting by trying to look up the stateowner.
-	* If stateowner is not found - stateid is bad.
-	*/
-	if (!(sop = find_openstateowner_id(stateid->si_stateownerid, flags))) {
-		printk("NFSD: preprocess_seqid_op: no stateowner or nfs4_stateid!\n");
-		status = nfserr_bad_stateid;
-		goto out;
+		return nfserr_old_stateid;
 	}
-	*sopp = sop;
+	renew_client(sop->so_client);
+	return nfs_ok;
 
 check_replay:
-	if (seqid == sop->so_seqid) {
+	if (seqid == sop->so_seqid - 1) {
 		printk("NFSD: preprocess_seqid_op: retransmission?\n");
 		/* indicate replay to calling function */
-		status = NFSERR_REPLAY_ME;
-	} else  {
-		printk("NFSD: preprocess_seqid_op: bad seqid (expected %d, got %d\n", sop->so_seqid +1, seqid);
-
-		*sopp = NULL;
-		status = nfserr_bad_seqid;
+		return NFSERR_REPLAY_ME;
 	}
-	goto out;
+	printk("NFSD: preprocess_seqid_op: bad seqid (expected %d, got %d)\n",
+			sop->so_seqid, seqid);
+	*sopp = NULL;
+	return nfserr_bad_seqid;
 }
 
 int
@@ -2230,6 +2317,8 @@ nfsd4_open_confirm(struct svc_rqst *rqst
 		         stp->st_stateid.si_stateownerid,
 		         stp->st_stateid.si_fileid,
 		         stp->st_stateid.si_generation);
+
+	nfsd4_create_clid_dir(sop->so_client);
 out:
 	if (oc->oc_stateowner)
 		nfs4_get_stateowner(oc->oc_stateowner);
@@ -2387,7 +2476,7 @@ static struct list_head lock_ownerid_has
 static struct list_head	lock_ownerstr_hashtbl[LOCK_HASH_SIZE];
 static struct list_head lockstateid_hashtbl[STATEID_HASH_SIZE];
 
-struct nfs4_stateid *
+static struct nfs4_stateid *
 find_stateid(stateid_t *stid, int flags)
 {
 	struct nfs4_stateid *local = NULL;
@@ -2419,25 +2508,19 @@ find_stateid(stateid_t *stid, int flags)
 static struct nfs4_delegation *
 find_delegation_stateid(struct inode *ino, stateid_t *stid)
 {
-	struct nfs4_delegation *dp = NULL;
-	struct nfs4_file *fp = NULL;
-	u32 st_id;
+	struct nfs4_file *fp;
+	struct nfs4_delegation *dl;
 
 	dprintk("NFSD:find_delegation_stateid stateid=(%08x/%08x/%08x/%08x)\n",
                     stid->si_boot, stid->si_stateownerid,
                     stid->si_fileid, stid->si_generation);
 
-	st_id = stid->si_stateownerid;
 	fp = find_file(ino);
-	if (fp) {
-		list_for_each_entry(dp, &fp->fi_del_perfile, dl_del_perfile) {
-			if(dp->dl_stateid.si_stateownerid == st_id) {
-				dprintk("NFSD: find_delegation dp %p\n",dp);
-				return dp;
-			}
-		}
-	}
-	return NULL;
+	if (!fp)
+		return NULL;
+	dl = find_delegation_file(fp, stid);
+	put_nfs4_file(fp);
+	return dl;
 }
 
 /*
@@ -2457,7 +2540,7 @@ nfs4_transform_lock_offset(struct file_l
 		lock->fl_end = OFFSET_MAX;
 }
 
-int
+static int
 nfs4_verify_lock_stateowner(struct nfs4_stateowner *sop, unsigned int hashval)
 {
 	struct nfs4_stateowner *local = NULL;
@@ -2498,22 +2581,6 @@ nfs4_set_lock_denied(struct file_lock *f
 }
 
 static struct nfs4_stateowner *
-find_lockstateowner(struct xdr_netobj *owner, clientid_t *clid)
-{
-	struct nfs4_stateowner *local = NULL;
-	int i;
-
-	for (i = 0; i < LOCK_HASH_SIZE; i++) {
-		list_for_each_entry(local, &lock_ownerid_hashtbl[i], so_idhash) {
-			if (!cmp_owner_str(local, owner, clid))
-				continue;
-			return local;
-		}
-	}
-	return NULL;
-}
-
-static struct nfs4_stateowner *
 find_lockstateowner_str(struct inode *inode, clientid_t *clid,
 		struct xdr_netobj *owner)
 {
@@ -2533,7 +2600,6 @@ find_lockstateowner_str(struct inode *in
  * occured. 
  *
  * strhashval = lock_ownerstr_hashval 
- * so_seqid = lock->lk_new_lock_seqid - 1: it gets bumped in encode 
  */
 
 static struct nfs4_stateowner *
@@ -2548,17 +2614,17 @@ alloc_init_lock_stateowner(unsigned int 
 	INIT_LIST_HEAD(&sop->so_idhash);
 	INIT_LIST_HEAD(&sop->so_strhash);
 	INIT_LIST_HEAD(&sop->so_perclient);
-	INIT_LIST_HEAD(&sop->so_perfilestate);
-	INIT_LIST_HEAD(&sop->so_perlockowner);
+	INIT_LIST_HEAD(&sop->so_stateids);
+	INIT_LIST_HEAD(&sop->so_perstateid);
 	INIT_LIST_HEAD(&sop->so_close_lru); /* not used */
 	sop->so_time = 0;
 	list_add(&sop->so_idhash, &lock_ownerid_hashtbl[idhashval]);
 	list_add(&sop->so_strhash, &lock_ownerstr_hashtbl[strhashval]);
-	list_add(&sop->so_perlockowner, &open_stp->st_perlockowner);
+	list_add(&sop->so_perstateid, &open_stp->st_lockowners);
 	sop->so_is_open_owner = 0;
 	sop->so_id = current_ownerid++;
 	sop->so_client = clp;
-	sop->so_seqid = lock->lk_new_lock_seqid - 1;
+	sop->so_seqid = lock->lk_new_lock_seqid;
 	sop->so_confirmed = 1;
 	rp = &sop->so_replay;
 	rp->rp_status = NFSERR_SERVERFAULT;
@@ -2567,24 +2633,24 @@ alloc_init_lock_stateowner(unsigned int 
 	return sop;
 }
 
-struct nfs4_stateid *
+static struct nfs4_stateid *
 alloc_init_lock_stateid(struct nfs4_stateowner *sop, struct nfs4_file *fp, struct nfs4_stateid *open_stp)
 {
 	struct nfs4_stateid *stp;
 	unsigned int hashval = stateid_hashval(sop->so_id, fp->fi_id);
 
-	if ((stp = kmalloc(sizeof(struct nfs4_stateid), 
-					GFP_KERNEL)) == NULL)
+	stp = nfs4_alloc_stateid();
+	if (stp == NULL)
 		goto out;
 	INIT_LIST_HEAD(&stp->st_hash);
 	INIT_LIST_HEAD(&stp->st_perfile);
-	INIT_LIST_HEAD(&stp->st_perfilestate);
-	INIT_LIST_HEAD(&stp->st_perlockowner); /* not used */
+	INIT_LIST_HEAD(&stp->st_perstateowner);
+	INIT_LIST_HEAD(&stp->st_lockowners); /* not used */
 	list_add(&stp->st_hash, &lockstateid_hashtbl[hashval]);
-	list_add(&stp->st_perfile, &fp->fi_perfile);
-	list_add_perfile++;
-	list_add(&stp->st_perfilestate, &sop->so_perfilestate);
+	list_add(&stp->st_perfile, &fp->fi_stateids);
+	list_add(&stp->st_perstateowner, &sop->so_stateids);
 	stp->st_stateowner = sop;
+	get_nfs4_file(fp);
 	stp->st_file = fp;
 	stp->st_stateid.si_boot = boot_time;
 	stp->st_stateid.si_stateownerid = sop->so_id;
@@ -2593,12 +2659,13 @@ alloc_init_lock_stateid(struct nfs4_stat
 	stp->st_vfs_file = open_stp->st_vfs_file; /* FIXME refcount?? */
 	stp->st_access_bmap = open_stp->st_access_bmap;
 	stp->st_deny_bmap = open_stp->st_deny_bmap;
+	stp->st_openstp = open_stp;
 
 out:
 	return stp;
 }
 
-int
+static int
 check_lock_length(u64 offset, u64 length)
 {
 	return ((length == 0)  || ((length != ~(u64)0) &&
@@ -2611,7 +2678,7 @@ check_lock_length(u64 offset, u64 length
 int
 nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock *lock)
 {
-	struct nfs4_stateowner *lock_sop = NULL, *open_sop = NULL;
+	struct nfs4_stateowner *open_sop = NULL;
 	struct nfs4_stateid *lock_stp;
 	struct file *filp;
 	struct file_lock file_lock;
@@ -2623,22 +2690,17 @@ nfsd4_lock(struct svc_rqst *rqstp, struc
 		(long long) lock->lk_offset,
 		(long long) lock->lk_length);
 
-	if (nfs4_in_grace() && !lock->lk_reclaim)
-		return nfserr_grace;
-	if (!nfs4_in_grace() && lock->lk_reclaim)
-		return nfserr_no_grace;
-
 	if (check_lock_length(lock->lk_offset, lock->lk_length))
 		 return nfserr_inval;
 
 	nfs4_lock_state();
 
 	if (lock->lk_is_new) {
-	/*
-	 * Client indicates that this is a new lockowner.
-	 * Use open owner and open stateid to create lock owner and lock 
-	 * stateid.
-	 */
+		/*
+		 * Client indicates that this is a new lockowner.
+		 * Use open owner and open stateid to create lock owner and
+		 * lock stateid.
+		 */
 		struct nfs4_stateid *open_stp = NULL;
 		struct nfs4_file *fp;
 		
@@ -2648,38 +2710,22 @@ nfsd4_lock(struct svc_rqst *rqstp, struc
 			goto out;
 		}
 
-		/* is the new lock seqid presented by the client zero? */
-		status = nfserr_bad_seqid;
-		if (lock->v.new.lock_seqid != 0)
-			goto out;
-
 		/* validate and update open stateid and open seqid */
 		status = nfs4_preprocess_seqid_op(current_fh, 
 				        lock->lk_new_open_seqid,
 		                        &lock->lk_new_open_stateid,
 		                        CHECK_FH | OPEN_STATE,
-		                        &open_sop, &open_stp,
-					&lock->v.new.clientid);
-		if (status) {
-			if (lock->lk_reclaim)
-				status = nfserr_reclaim_bad;
+		                        &open_sop, &open_stp, lock);
+		if (status)
 			goto out;
-		}
 		/* create lockowner and lock stateid */
 		fp = open_stp->st_file;
 		strhashval = lock_ownerstr_hashval(fp->fi_inode, 
 				open_sop->so_client->cl_clientid.cl_id, 
 				&lock->v.new.owner);
-		/* 
-		 * If we already have this lock owner, the client is in 
-		 * error (or our bookeeping is wrong!) 
-		 * for asking for a 'new lock'.
-		 */
-		status = nfserr_bad_stateid;
-		lock_sop = find_lockstateowner(&lock->v.new.owner,
-						&lock->v.new.clientid);
-		if (lock_sop)
-			goto out;
+		/* XXX: Do we need to check for duplicate stateowners on
+		 * the same file, or should they just be allowed (and
+		 * create new stateids)? */
 		status = nfserr_resource;
 		if (!(lock->lk_stateowner = alloc_init_lock_stateowner(strhashval, open_sop->so_client, open_stp, lock)))
 			goto out;
@@ -2697,7 +2743,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struc
 				       lock->lk_old_lock_seqid, 
 				       &lock->lk_old_lock_stateid, 
 				       CHECK_FH | LOCK_STATE, 
-				       &lock->lk_stateowner, &lock_stp, NULL);
+				       &lock->lk_stateowner, &lock_stp, lock);
 		if (status)
 			goto out;
 	}
@@ -2709,6 +2755,13 @@ nfsd4_lock(struct svc_rqst *rqstp, struc
 		goto out;
 	}
 
+	status = nfserr_grace;
+	if (nfs4_in_grace() && !lock->lk_reclaim)
+		goto out;
+	status = nfserr_no_grace;
+	if (!nfs4_in_grace() && lock->lk_reclaim)
+		goto out;
+
 	locks_init_lock(&file_lock);
 	switch (lock->lk_type) {
 		case NFS4_READ_LT:
@@ -2775,10 +2828,10 @@ conflicting_lock:
 out_destroy_new_stateid:
 	if (lock->lk_is_new) {
 		dprintk("NFSD: nfsd4_lock: destroy new stateid!\n");
-	/*
-	* An error encountered after instantiation of the new
-	* stateid has forced us to destroy it.
-	*/
+		/*
+		 * An error encountered after instantiation of the new
+		 * stateid has forced us to destroy it.
+		 */
 		if (!seqid_mutating_err(status))
 			open_sop->so_seqid--;
 
@@ -2970,8 +3023,11 @@ int
 nfsd4_release_lockowner(struct svc_rqst *rqstp, struct nfsd4_release_lockowner *rlockowner)
 {
 	clientid_t *clid = &rlockowner->rl_clientid;
-	struct nfs4_stateowner *local = NULL;
+	struct nfs4_stateowner *sop;
+	struct nfs4_stateid *stp;
 	struct xdr_netobj *owner = &rlockowner->rl_owner;
+	struct list_head matches;
+	int i;
 	int status;
 
 	dprintk("nfsd4_release_lockowner clientid: (%08x/%08x):\n",
@@ -2987,22 +3043,37 @@ nfsd4_release_lockowner(struct svc_rqst 
 
 	nfs4_lock_state();
 
-	status = nfs_ok;
-	local = find_lockstateowner(owner, clid);
-	if (local) {
-		struct nfs4_stateid *stp;
-
-		/* check for any locks held by any stateid
-		 * associated with the (lock) stateowner */
-		status = nfserr_locks_held;
-		list_for_each_entry(stp, &local->so_perfilestate,
-				st_perfilestate) {
-			if (check_for_locks(stp->st_vfs_file, local))
-				goto out;
+	status = nfserr_locks_held;
+	/* XXX: we're doing a linear search through all the lockowners.
+	 * Yipes!  For now we'll just hope clients aren't really using
+	 * release_lockowner much, but eventually we have to fix these
+	 * data structures. */
+	INIT_LIST_HEAD(&matches);
+	for (i = 0; i < LOCK_HASH_SIZE; i++) {
+		list_for_each_entry(sop, &lock_ownerid_hashtbl[i], so_idhash) {
+			if (!cmp_owner_str(sop, owner, clid))
+				continue;
+			list_for_each_entry(stp, &sop->so_stateids,
+					st_perstateowner) {
+				if (check_for_locks(stp->st_vfs_file, sop))
+					goto out;
+				/* Note: so_perclient unused for lockowners,
+				 * so it's OK to fool with here. */
+				list_add(&sop->so_perclient, &matches);
+			}
 		}
-		/* no locks held by (lock) stateowner */
-		status = nfs_ok;
-		release_stateowner(local);
+	}
+	/* Clients probably won't expect us to return with some (but not all)
+	 * of the lockowner state released; so don't release any until all
+	 * have been checked. */
+	status = nfs_ok;
+	while (!list_empty(&matches)) {
+		sop = list_entry(matches.next, struct nfs4_stateowner,
+								so_perclient);
+		/* unhash_stateowner deletes so_perclient only
+		 * for openowners. */
+		list_del(&sop->so_perclient);
+		release_stateowner(sop);
 	}
 out:
 	nfs4_unlock_state();
@@ -3010,39 +3081,38 @@ out:
 }
 
 static inline struct nfs4_client_reclaim *
-alloc_reclaim(int namelen)
+alloc_reclaim(void)
 {
-	struct nfs4_client_reclaim *crp = NULL;
+	return kmalloc(sizeof(struct nfs4_client_reclaim), GFP_KERNEL);
+}
 
-	crp = kmalloc(sizeof(struct nfs4_client_reclaim), GFP_KERNEL);
-	if (!crp)
-		return NULL;
-	crp->cr_name.data = kmalloc(namelen, GFP_KERNEL);
-	if (!crp->cr_name.data) {
-		kfree(crp);
-		return NULL;
-	}
-	return crp;
+int
+nfs4_has_reclaimed_state(const char *name)
+{
+	unsigned int strhashval = clientstr_hashval(name);
+	struct nfs4_client *clp;
+
+	clp = find_confirmed_client_by_str(name, strhashval);
+	return clp ? 1 : 0;
 }
 
 /*
  * failure => all reset bets are off, nfserr_no_grace...
  */
-static int
-nfs4_client_to_reclaim(char *name, int namlen)
+int
+nfs4_client_to_reclaim(const char *name)
 {
 	unsigned int strhashval;
 	struct nfs4_client_reclaim *crp = NULL;
 
-	dprintk("NFSD nfs4_client_to_reclaim NAME: %.*s\n", namlen, name);
-	crp = alloc_reclaim(namlen);
+	dprintk("NFSD nfs4_client_to_reclaim NAME: %.*s\n", HEXDIR_LEN, name);
+	crp = alloc_reclaim();
 	if (!crp)
 		return 0;
-	strhashval = clientstr_hashval(name, namlen);
+	strhashval = clientstr_hashval(name);
 	INIT_LIST_HEAD(&crp->cr_strhash);
 	list_add(&crp->cr_strhash, &reclaim_str_hashtbl[strhashval]);
-	memcpy(crp->cr_name.data, name, namlen);
-	crp->cr_name.len = namlen;
+	memcpy(crp->cr_recdir, name, HEXDIR_LEN);
 	reclaim_str_hashtbl_size++;
 	return 1;
 }
@@ -3053,13 +3123,11 @@ nfs4_release_reclaim(void)
 	struct nfs4_client_reclaim *crp = NULL;
 	int i;
 
-	BUG_ON(!nfs4_reclaim_init);
 	for (i = 0; i < CLIENT_HASH_SIZE; i++) {
 		while (!list_empty(&reclaim_str_hashtbl[i])) {
 			crp = list_entry(reclaim_str_hashtbl[i].next,
 			                struct nfs4_client_reclaim, cr_strhash);
 			list_del(&crp->cr_strhash);
-			kfree(crp->cr_name.data);
 			kfree(crp);
 			reclaim_str_hashtbl_size--;
 		}
@@ -3069,7 +3137,7 @@ nfs4_release_reclaim(void)
 
 /*
  * called from OPEN, CLAIM_PREVIOUS with a new clientid. */
-struct nfs4_client_reclaim *
+static struct nfs4_client_reclaim *
 nfs4_find_reclaim_client(clientid_t *clid)
 {
 	unsigned int strhashval;
@@ -3082,13 +3150,14 @@ nfs4_find_reclaim_client(clientid_t *cli
 	if (clp == NULL)
 		return NULL;
 
-	dprintk("NFSD: nfs4_find_reclaim_client for %.*s\n",
-		            clp->cl_name.len, clp->cl_name.data);
+	dprintk("NFSD: nfs4_find_reclaim_client for %.*s with recdir %s\n",
+		            clp->cl_name.len, clp->cl_name.data,
+			    clp->cl_recdir);
 
 	/* find clp->cl_name in reclaim_str_hashtbl */
-	strhashval = clientstr_hashval(clp->cl_name.data, clp->cl_name.len);
+	strhashval = clientstr_hashval(clp->cl_recdir);
 	list_for_each_entry(crp, &reclaim_str_hashtbl[strhashval], cr_strhash) {
-		if (cmp_name(&crp->cr_name, &clp->cl_name)) {
+		if (same_name(crp->cr_recdir, clp->cl_recdir)) {
 			return crp;
 		}
 	}
@@ -3101,30 +3170,16 @@ nfs4_find_reclaim_client(clientid_t *cli
 int
 nfs4_check_open_reclaim(clientid_t *clid)
 {
-	struct nfs4_client_reclaim *crp;
-
-	if ((crp = nfs4_find_reclaim_client(clid)) == NULL)
-		return nfserr_reclaim_bad;
-	return nfs_ok;
+	return nfs4_find_reclaim_client(clid) ? nfs_ok : nfserr_reclaim_bad;
 }
 
+/* initialization to perform at module load time: */
 
-/* 
- * Start and stop routines
- */
-
-static void
-__nfs4_state_init(void)
+void
+nfs4_state_init(void)
 {
 	int i;
-	time_t grace_time;
 
-	if (!nfs4_reclaim_init) {
-		for (i = 0; i < CLIENT_HASH_SIZE; i++)
-			INIT_LIST_HEAD(&reclaim_str_hashtbl[i]);
-		reclaim_str_hashtbl_size = 0;
-		nfs4_reclaim_init = 1;
-	}
 	for (i = 0; i < CLIENT_HASH_SIZE; i++) {
 		INIT_LIST_HEAD(&conf_id_hashtbl[i]);
 		INIT_LIST_HEAD(&conf_str_hashtbl[i]);
@@ -3146,26 +3201,46 @@ __nfs4_state_init(void)
 		INIT_LIST_HEAD(&lock_ownerid_hashtbl[i]);
 		INIT_LIST_HEAD(&lock_ownerstr_hashtbl[i]);
 	}
-	memset(&zerostateid, 0, sizeof(stateid_t));
 	memset(&onestateid, ~0, sizeof(stateid_t));
-
 	INIT_LIST_HEAD(&close_lru);
 	INIT_LIST_HEAD(&client_lru);
 	INIT_LIST_HEAD(&del_recall_lru);
-	spin_lock_init(&recall_lock);
+	for (i = 0; i < CLIENT_HASH_SIZE; i++)
+		INIT_LIST_HEAD(&reclaim_str_hashtbl[i]);
+	reclaim_str_hashtbl_size = 0;
+}
+
+static void
+nfsd4_load_reboot_recovery_data(void)
+{
+	int status;
+
+	nfs4_lock_state();
+	nfsd4_init_recdir(user_recovery_dirname);
+	status = nfsd4_recdir_load();
+	nfs4_unlock_state();
+	if (status)
+		printk("NFSD: Failure reading reboot recovery data\n");
+}
+
+/* initialization to perform when the nfsd service is started: */
+
+static void
+__nfs4_state_start(void)
+{
+	time_t grace_time;
+
 	boot_time = get_seconds();
-	grace_time = max(old_lease_time, lease_time);
-	if (reclaim_str_hashtbl_size == 0)
-		grace_time = 0;
-	if (grace_time)
-		printk("NFSD: starting %ld-second grace period\n", grace_time);
-	grace_end = boot_time + grace_time;
-	INIT_WORK(&laundromat_work,laundromat_main, NULL);
-	schedule_delayed_work(&laundromat_work, NFSD_LEASE_TIME*HZ);
+	grace_time = max(user_lease_time, lease_time);
+	lease_time = user_lease_time;
+	in_grace = 1;
+	printk("NFSD: starting %ld-second grace period\n", grace_time);
+	laundry_wq = create_singlethread_workqueue("nfsd4");
+	queue_delayed_work(laundry_wq, &laundromat_work, grace_time*HZ);
 }
 
 int
-nfs4_state_init(void)
+nfs4_state_start(void)
 {
 	int status;
 
@@ -3174,7 +3249,8 @@ nfs4_state_init(void)
 	status = nfsd4_init_slabs();
 	if (status)
 		return status;
-	__nfs4_state_init();
+	nfsd4_load_reboot_recovery_data();
+	__nfs4_state_start();
 	nfs4_init = 1;
 	return 0;
 }
@@ -3182,14 +3258,7 @@ nfs4_state_init(void)
 int
 nfs4_in_grace(void)
 {
-	return get_seconds() < grace_end;
-}
-
-void
-set_no_grace(void)
-{
-	printk("NFSD: ERROR in reboot recovery.  State reclaims will fail.\n");
-	grace_end = get_seconds();
+	return in_grace;
 }
 
 time_t
@@ -3236,21 +3305,11 @@ __nfs4_state_shutdown(void)
 		unhash_delegation(dp);
 	}
 
-	release_all_files();
 	cancel_delayed_work(&laundromat_work);
-	flush_scheduled_work();
+	flush_workqueue(laundry_wq);
+	destroy_workqueue(laundry_wq);
+	nfsd4_shutdown_recdir();
 	nfs4_init = 0;
-	dprintk("NFSD: list_add_perfile %d list_del_perfile %d\n",
-			list_add_perfile, list_del_perfile);
-	dprintk("NFSD: add_perclient %d del_perclient %d\n",
-			add_perclient, del_perclient);
-	dprintk("NFSD: alloc_file %d free_file %d\n",
-			alloc_file, free_file);
-	dprintk("NFSD: vfsopen %d vfsclose %d\n",
-			vfsopen, vfsclose);
-	dprintk("NFSD: alloc_delegation %d free_delegation %d\n",
-			alloc_delegation, free_delegation);
-
 }
 
 void
@@ -3263,56 +3322,48 @@ nfs4_state_shutdown(void)
 	nfs4_unlock_state();
 }
 
+static void
+nfs4_set_recdir(char *recdir)
+{
+	nfs4_lock_state();
+	strcpy(user_recovery_dirname, recdir);
+	nfs4_unlock_state();
+}
+
+/*
+ * Change the NFSv4 recovery directory to recdir.
+ */
+int
+nfs4_reset_recoverydir(char *recdir)
+{
+	int status;
+	struct nameidata nd;
+
+	status = path_lookup(recdir, LOOKUP_FOLLOW, &nd);
+	if (status)
+		return status;
+	status = -ENOTDIR;
+	if (S_ISDIR(nd.dentry->d_inode->i_mode)) {
+		nfs4_set_recdir(recdir);
+		status = 0;
+	}
+	path_release(&nd);
+	return status;
+}
+
 /*
  * Called when leasetime is changed.
  *
- * if nfsd is not started, simply set the global lease.
- *
- * if nfsd(s) are running, lease change requires nfsv4 state to be reset.
- * e.g: boot_time is reset, existing nfs4_client structs are
- * used to fill reclaim_str_hashtbl, then all state (except for the
- * reclaim_str_hashtbl) is re-initialized.
- *
- * if the old lease time is greater than the new lease time, the grace
- * period needs to be set to the old lease time to allow clients to reclaim
- * their state. XXX - we may want to set the grace period == lease time
- * after an initial grace period == old lease time
- *
- * if an error occurs in this process, the new lease is set, but the server
- * will not honor OPEN or LOCK reclaims, and will return nfserr_no_grace
- * which means OPEN/LOCK/READ/WRITE will fail during grace period.
- *
- * clients will attempt to reset all state with SETCLIENTID/CONFIRM, and
- * OPEN and LOCK reclaims.
+ * The only way the protocol gives us to handle on-the-fly lease changes is to
+ * simulate a reboot.  Instead of doing that, we just wait till the next time
+ * we start to register any changes in lease time.  If the administrator
+ * really wants to change the lease time *now*, they can go ahead and bring
+ * nfsd down and then back up again after changing the lease time.
  */
 void
 nfs4_reset_lease(time_t leasetime)
 {
-	struct nfs4_client *clp;
-	int i;
-
-	printk("NFSD: New leasetime %ld\n",leasetime);
-	if (!nfs4_init)
-		return;
-	nfs4_lock_state();
-	old_lease_time = lease_time;
-	lease_time = leasetime;
-
-	nfs4_release_reclaim();
-
-	/* populate reclaim_str_hashtbl with current confirmed nfs4_clientid */
-	for (i = 0; i < CLIENT_HASH_SIZE; i++) {
-		list_for_each_entry(clp, &conf_id_hashtbl[i], cl_idhash) {
-			if (!nfs4_client_to_reclaim(clp->cl_name.data,
-						clp->cl_name.len)) {
-				nfs4_release_reclaim();
-				goto init_state;
-			}
-		}
-	}
-init_state:
-	__nfs4_state_shutdown();
-	__nfs4_state_init();
-	nfs4_unlock_state();
+	lock_kernel();
+	user_lease_time = leasetime;
+	unlock_kernel();
 }
-
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -136,7 +136,7 @@ xdr_error:					\
 	}					\
 } while (0)
 
-u32 *read_buf(struct nfsd4_compoundargs *argp, int nbytes)
+static u32 *read_buf(struct nfsd4_compoundargs *argp, int nbytes)
 {
 	/* We want more bytes than seem to be available.
 	 * Maybe we need a new page, maybe we have just run out
@@ -190,7 +190,7 @@ defer_free(struct nfsd4_compoundargs *ar
 	return 0;
 }
 
-char *savemem(struct nfsd4_compoundargs *argp, u32 *p, int nbytes)
+static char *savemem(struct nfsd4_compoundargs *argp, u32 *p, int nbytes)
 {
 	void *new = NULL;
 	if (p == argp->tmp) {
@@ -1210,16 +1210,15 @@ nfsd4_decode_compound(struct nfsd4_compo
 	save = resp->p;
 
 /*
- * Routine for encoding the result of a
- * "seqid-mutating" NFSv4 operation.  This is
- * where seqids are incremented, and the
- * replay cache is filled.
+ * Routine for encoding the result of a "seqid-mutating" NFSv4 operation.  This
+ * is where sequence id's are incremented, and the replay cache is filled.
+ * Note that we increment sequence id's here, at the last moment, so we're sure
+ * we know whether the error to be returned is a sequence id mutating error.
  */
 
 #define ENCODE_SEQID_OP_TAIL(stateowner) do {			\
 	if (seqid_mutating_err(nfserr) && stateowner) { 	\
-		if (stateowner->so_confirmed)			\
-			stateowner->so_seqid++;			\
+		stateowner->so_seqid++;				\
 		stateowner->so_replay.rp_status = nfserr;   	\
 		stateowner->so_replay.rp_buflen = 		\
 			  (((char *)(resp)->p - (char *)save)); \
@@ -1366,7 +1365,10 @@ nfsd4_encode_fattr(struct svc_fh *fhp, s
 	if (bmval0 & FATTR4_WORD0_FH_EXPIRE_TYPE) {
 		if ((buflen -= 4) < 0)
 			goto out_resource;
-		WRITE32( NFS4_FH_NOEXPIRE_WITH_OPEN | NFS4_FH_VOL_RENAME );
+		if (exp->ex_flags & NFSEXP_NOSUBTREECHECK)
+			WRITE32(NFS4_FH_PERSISTENT);
+		else
+			WRITE32(NFS4_FH_PERSISTENT|NFS4_FH_VOL_RENAME);
 	}
 	if (bmval0 & FATTR4_WORD0_CHANGE) {
 		/*
@@ -1969,7 +1971,7 @@ nfsd4_encode_open(struct nfsd4_compoundr
 	case NFS4_OPEN_DELEGATE_READ:
 		RESERVE_SPACE(20 + sizeof(stateid_t));
 		WRITEMEM(&open->op_delegate_stateid, sizeof(stateid_t));
-		WRITE32(0);
+		WRITE32(open->op_recall);
 
 		/*
 		 * TODO: ACE's in delegations
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -51,6 +51,7 @@ enum {
 	NFSD_Fh,
 	NFSD_Threads,
 	NFSD_Leasetime,
+	NFSD_RecoveryDir,
 };
 
 /*
@@ -66,6 +67,7 @@ static ssize_t write_getfs(struct file *
 static ssize_t write_filehandle(struct file *file, char *buf, size_t size);
 static ssize_t write_threads(struct file *file, char *buf, size_t size);
 static ssize_t write_leasetime(struct file *file, char *buf, size_t size);
+static ssize_t write_recoverydir(struct file *file, char *buf, size_t size);
 
 static ssize_t (*write_op[])(struct file *, char *, size_t) = {
 	[NFSD_Svc] = write_svc,
@@ -78,6 +80,7 @@ static ssize_t (*write_op[])(struct file
 	[NFSD_Fh] = write_filehandle,
 	[NFSD_Threads] = write_threads,
 	[NFSD_Leasetime] = write_leasetime,
+	[NFSD_RecoveryDir] = write_recoverydir,
 };
 
 static ssize_t nfsctl_transaction_write(struct file *file, const char __user *buf, size_t size, loff_t *pos)
@@ -349,6 +352,25 @@ static ssize_t write_leasetime(struct fi
 	return strlen(buf);
 }
 
+static ssize_t write_recoverydir(struct file *file, char *buf, size_t size)
+{
+	char *mesg = buf;
+	char *recdir;
+	int len, status;
+
+	if (size > PATH_MAX || buf[size-1] != '\n')
+		return -EINVAL;
+	buf[size-1] = 0;
+
+	recdir = mesg;
+	len = qword_get(&mesg, recdir, size);
+	if (len <= 0)
+		return -EINVAL;
+
+	status = nfs4_reset_recoverydir(recdir);
+	return strlen(buf);
+}
+
 /*----------------------------------------------------------------------------*/
 /*
  *	populating the filesystem.
@@ -369,6 +391,7 @@ static int nfsd_fill_super(struct super_
 		[NFSD_Threads] = {"threads", &transaction_ops, S_IWUSR|S_IRUSR},
 #ifdef CONFIG_NFSD_V4
 		[NFSD_Leasetime] = {"nfsv4leasetime", &transaction_ops, S_IWUSR|S_IRUSR},
+		[NFSD_RecoveryDir] = {"nfsv4recoverydir", &transaction_ops, S_IWUSR|S_IRUSR},
 #endif
 		/* last one */ {""}
 	};
@@ -397,9 +420,8 @@ static int __init init_nfsd(void)
 	nfsd_cache_init();	/* RPC reply cache */
 	nfsd_export_init();	/* Exports table */
 	nfsd_lockd_init();	/* lockd->nfsd callbacks */
-#ifdef CONFIG_NFSD_V4
+	nfs4_state_init();	/* NFSv4 locking state */
 	nfsd_idmap_init();      /* Name to ID mapping */
-#endif /* CONFIG_NFSD_V4 */
 	if (proc_mkdir("fs/nfs", NULL)) {
 		struct proc_dir_entry *entry;
 		entry = create_proc_entry("fs/nfs/exports", 0, NULL);
@@ -426,9 +448,7 @@ static void __exit exit_nfsd(void)
 	remove_proc_entry("fs/nfs", NULL);
 	nfsd_stat_shutdown();
 	nfsd_lockd_shutdown();
-#ifdef CONFIG_NFSD_V4
 	nfsd_idmap_shutdown();
-#endif /* CONFIG_NFSD_V4 */
 	unregister_filesystem(&nfsd_fs_type);
 }
 
diff --git a/fs/nfsd/nfsproc.c b/fs/nfsd/nfsproc.c
--- a/fs/nfsd/nfsproc.c
+++ b/fs/nfsd/nfsproc.c
@@ -591,6 +591,7 @@ nfserrno (int errno)
 		{ nfserr_dropit, -ENOMEM },
 		{ nfserr_badname, -ESRCH },
 		{ nfserr_io, -ETXTBSY },
+		{ nfserr_notsupp, -EOPNOTSUPP },
 		{ -1, -EIO }
 	};
 	int	i;
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
--- a/fs/nfsd/nfssvc.c
+++ b/fs/nfsd/nfssvc.c
@@ -31,6 +31,7 @@
 #include <linux/nfsd/stats.h>
 #include <linux/nfsd/cache.h>
 #include <linux/lockd/bind.h>
+#include <linux/nfsacl.h>
 
 #define NFSDDBG_FACILITY	NFSDDBG_SVC
 
@@ -94,7 +95,7 @@ nfsd_svc(unsigned short port, int nrserv
 	error =	nfsd_racache_init(2*nrservs);
 	if (error<0)
 		goto out;
-	error = nfs4_state_init();
+	error = nfs4_state_start();
 	if (error<0)
 		goto out;
 	if (!nfsd_serv) {
@@ -286,6 +287,7 @@ out:
 	svc_exit_thread(rqstp);
 
 	/* Release module */
+	unlock_kernel();
 	module_put_and_exit(0);
 }
 
@@ -362,6 +364,32 @@ nfsd_dispatch(struct svc_rqst *rqstp, u3
 	return 1;
 }
 
+#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
+static struct svc_stat	nfsd_acl_svcstats;
+static struct svc_version *	nfsd_acl_version[] = {
+	[2] = &nfsd_acl_version2,
+	[3] = &nfsd_acl_version3,
+};
+
+#define NFSD_ACL_NRVERS		(sizeof(nfsd_acl_version)/sizeof(nfsd_acl_version[0]))
+static struct svc_program	nfsd_acl_program = {
+	.pg_prog		= NFS_ACL_PROGRAM,
+	.pg_nvers		= NFSD_ACL_NRVERS,
+	.pg_vers		= nfsd_acl_version,
+	.pg_name		= "nfsd",
+	.pg_class		= "nfsd",
+	.pg_stats		= &nfsd_acl_svcstats,
+};
+
+static struct svc_stat	nfsd_acl_svcstats = {
+	.program	= &nfsd_acl_program,
+};
+
+#define nfsd_acl_program_p	&nfsd_acl_program
+#else
+#define nfsd_acl_program_p	NULL
+#endif /* defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) */
+
 extern struct svc_version nfsd_version2, nfsd_version3, nfsd_version4;
 
 static struct svc_version *	nfsd_version[] = {
@@ -376,6 +404,7 @@ static struct svc_version *	nfsd_version
 
 #define NFSD_NRVERS		(sizeof(nfsd_version)/sizeof(nfsd_version[0]))
 struct svc_program		nfsd_program = {
+	.pg_next		= nfsd_acl_program_p,
 	.pg_prog		= NFS_PROGRAM,		/* program number */
 	.pg_nvers		= NFSD_NRVERS,		/* nr of entries in nfsd_version */
 	.pg_vers		= nfsd_version,		/* version table */
diff --git a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c
--- a/fs/nfsd/nfsxdr.c
+++ b/fs/nfsd/nfsxdr.c
@@ -49,6 +49,12 @@ decode_fh(u32 *p, struct svc_fh *fhp)
 	return p + (NFS_FHSIZE >> 2);
 }
 
+/* Helper function for NFSv2 ACL code */
+u32 *nfs2svc_decode_fh(u32 *p, struct svc_fh *fhp)
+{
+	return decode_fh(p, fhp);
+}
+
 static inline u32 *
 encode_fh(u32 *p, struct svc_fh *fhp)
 {
@@ -190,6 +196,11 @@ encode_fattr(struct svc_rqst *rqstp, u32
 	return p;
 }
 
+/* Helper function for NFSv2 ACL code */
+u32 *nfs2svc_encode_fattr(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp)
+{
+	return encode_fattr(rqstp, p, fhp);
+}
 
 /*
  * XDR decode functions
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -45,11 +45,10 @@
 #endif /* CONFIG_NFSD_V3 */
 #include <linux/nfsd/nfsfh.h>
 #include <linux/quotaops.h>
-#include <linux/dnotify.h>
-#ifdef CONFIG_NFSD_V4
+#include <linux/fsnotify.h>
 #include <linux/posix_acl.h>
 #include <linux/posix_acl_xattr.h>
-#include <linux/xattr_acl.h>
+#ifdef CONFIG_NFSD_V4
 #include <linux/xattr.h>
 #include <linux/nfs4.h>
 #include <linux/nfs4_acl.h>
@@ -424,13 +423,13 @@ nfsd4_set_nfs4_acl(struct svc_rqst *rqst
 		goto out_nfserr;
 
 	if (pacl) {
-		error = set_nfsv4_acl_one(dentry, pacl, XATTR_NAME_ACL_ACCESS);
+		error = set_nfsv4_acl_one(dentry, pacl, POSIX_ACL_XATTR_ACCESS);
 		if (error < 0)
 			goto out_nfserr;
 	}
 
 	if (dpacl) {
-		error = set_nfsv4_acl_one(dentry, dpacl, XATTR_NAME_ACL_DEFAULT);
+		error = set_nfsv4_acl_one(dentry, dpacl, POSIX_ACL_XATTR_DEFAULT);
 		if (error < 0)
 			goto out_nfserr;
 	}
@@ -497,7 +496,7 @@ nfsd4_get_nfs4_acl(struct svc_rqst *rqst
 	struct posix_acl *pacl = NULL, *dpacl = NULL;
 	unsigned int flags = 0;
 
-	pacl = _get_posix_acl(dentry, XATTR_NAME_ACL_ACCESS);
+	pacl = _get_posix_acl(dentry, POSIX_ACL_XATTR_ACCESS);
 	if (IS_ERR(pacl) && PTR_ERR(pacl) == -ENODATA)
 		pacl = posix_acl_from_mode(inode->i_mode, GFP_KERNEL);
 	if (IS_ERR(pacl)) {
@@ -507,7 +506,7 @@ nfsd4_get_nfs4_acl(struct svc_rqst *rqst
 	}
 
 	if (S_ISDIR(inode->i_mode)) {
-		dpacl = _get_posix_acl(dentry, XATTR_NAME_ACL_DEFAULT);
+		dpacl = _get_posix_acl(dentry, POSIX_ACL_XATTR_DEFAULT);
 		if (IS_ERR(dpacl) && PTR_ERR(dpacl) == -ENODATA)
 			dpacl = NULL;
 		else if (IS_ERR(dpacl)) {
@@ -734,7 +733,7 @@ nfsd_sync(struct file *filp)
 	up(&inode->i_sem);
 }
 
-static void
+void
 nfsd_sync_dir(struct dentry *dp)
 {
 	nfsd_dosync(NULL, dp, dp->d_inode->i_fop);
@@ -861,7 +860,7 @@ nfsd_vfs_read(struct svc_rqst *rqstp, st
 		nfsdstats.io_read += err;
 		*count = err;
 		err = 0;
-		dnotify_parent(file->f_dentry, DN_ACCESS);
+		fsnotify_access(file->f_dentry);
 	} else 
 		err = nfserrno(err);
 out:
@@ -917,7 +916,7 @@ nfsd_vfs_write(struct svc_rqst *rqstp, s
 	set_fs(oldfs);
 	if (err >= 0) {
 		nfsdstats.io_write += cnt;
-		dnotify_parent(file->f_dentry, DN_MODIFY);
+		fsnotify_modify(file->f_dentry);
 	}
 
 	/* clear setuid/setgid flag after write */
@@ -1857,3 +1856,107 @@ nfsd_racache_init(int cache_size)
 	nfsdstats.ra_size = cache_size;
 	return 0;
 }
+
+#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
+struct posix_acl *
+nfsd_get_posix_acl(struct svc_fh *fhp, int type)
+{
+	struct inode *inode = fhp->fh_dentry->d_inode;
+	char *name;
+	void *value = NULL;
+	ssize_t size;
+	struct posix_acl *acl;
+
+	if (!IS_POSIXACL(inode) || !inode->i_op || !inode->i_op->getxattr)
+		return ERR_PTR(-EOPNOTSUPP);
+	switch(type) {
+		case ACL_TYPE_ACCESS:
+			name = POSIX_ACL_XATTR_ACCESS;
+			break;
+		case ACL_TYPE_DEFAULT:
+			name = POSIX_ACL_XATTR_DEFAULT;
+			break;
+		default:
+			return ERR_PTR(-EOPNOTSUPP);
+	}
+
+	size = inode->i_op->getxattr(fhp->fh_dentry, name, NULL, 0);
+
+	if (size < 0) {
+		acl = ERR_PTR(size);
+		goto getout;
+	} else if (size > 0) {
+		value = kmalloc(size, GFP_KERNEL);
+		if (!value) {
+			acl = ERR_PTR(-ENOMEM);
+			goto getout;
+		}
+		size = inode->i_op->getxattr(fhp->fh_dentry, name, value, size);
+		if (size < 0) {
+			acl = ERR_PTR(size);
+			goto getout;
+		}
+	}
+	acl = posix_acl_from_xattr(value, size);
+
+getout:
+	kfree(value);
+	return acl;
+}
+
+int
+nfsd_set_posix_acl(struct svc_fh *fhp, int type, struct posix_acl *acl)
+{
+	struct inode *inode = fhp->fh_dentry->d_inode;
+	char *name;
+	void *value = NULL;
+	size_t size;
+	int error;
+
+	if (!IS_POSIXACL(inode) || !inode->i_op ||
+	    !inode->i_op->setxattr || !inode->i_op->removexattr)
+		return -EOPNOTSUPP;
+	switch(type) {
+		case ACL_TYPE_ACCESS:
+			name = POSIX_ACL_XATTR_ACCESS;
+			break;
+		case ACL_TYPE_DEFAULT:
+			name = POSIX_ACL_XATTR_DEFAULT;
+			break;
+		default:
+			return -EOPNOTSUPP;
+	}
+
+	if (acl && acl->a_count) {
+		size = posix_acl_xattr_size(acl->a_count);
+		value = kmalloc(size, GFP_KERNEL);
+		if (!value)
+			return -ENOMEM;
+		size = posix_acl_to_xattr(acl, value, size);
+		if (size < 0) {
+			error = size;
+			goto getout;
+		}
+	} else
+		size = 0;
+
+	if (!fhp->fh_locked)
+		fh_lock(fhp);  /* unlocking is done automatically */
+	if (size)
+		error = inode->i_op->setxattr(fhp->fh_dentry, name,
+					      value, size, 0);
+	else {
+		if (!S_ISDIR(inode->i_mode) && type == ACL_TYPE_DEFAULT)
+			error = 0;
+		else {
+			error = inode->i_op->removexattr(fhp->fh_dentry, name);
+			if (error == -ENODATA)
+				error = 0;
+		}
+	}
+
+getout:
+	kfree(value);
+	return error;
+}
+#endif  /* defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) */
diff --git a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog
--- a/fs/ntfs/ChangeLog
+++ b/fs/ntfs/ChangeLog
@@ -1,21 +1,18 @@
 ToDo/Notes:
 	- Find and fix bugs.
-	- Checkpoint or disable the user space journal ($UsnJrnl).
 	- In between ntfs_prepare/commit_write, need exclusion between
-	  simultaneous file extensions. Need perhaps an NInoResizeUnderway()
-	  flag which we can set in ntfs_prepare_write() and clear again in
-	  ntfs_commit_write(). Just have to be careful in readpage/writepage,
-	  as well as in truncate, that we play nice... We might need to have
-	  a data_size field in the ntfs_inode to store the real attribute
-	  length. Also need to be careful with initialized_size extention in
+	  simultaneous file extensions.  This is given to us by holding i_sem
+	  on the inode.  The only places in the kernel when a file is resized
+	  are prepare/commit write and truncate for both of which i_sem is
+	  held.  Just have to be careful in readpage/writepage and all other
+	  helpers not running under i_sem that we play nice...
+	  Also need to be careful with initialized_size extention in
 	  ntfs_prepare_write. Basically, just be _very_ careful in this code...
-	  OTOH, perhaps i_sem, which is held accross generic_file_write is
-	  sufficient for synchronisation here. We then just need to make sure
-	  ntfs_readpage/writepage/truncate interoperate properly with us.
-	  UPDATE: The above is all ok as it is due to i_sem held.  The only
-	  thing that needs to be checked is ntfs_writepage() which does not
-	  hold i_sem.  It cannot change i_size but it needs to cope with a
-	  concurrent i_size change.
+	  UPDATE: The only things that need to be checked are read/writepage
+	  which do not hold i_sem.  Note writepage cannot change i_size but it
+	  needs to cope with a concurrent i_size change, just like readpage.
+	  Also both need to cope with concurrent changes to the other sizes,
+	  i.e. initialized/allocated/compressed size, as well.
 	- Implement mft.c::sync_mft_mirror_umount().  We currently will just
 	  leave the volume dirty on umount if the final iput(vol->mft_ino)
 	  causes a write of any mirrored mft records due to the mft mirror
@@ -25,12 +22,161 @@ ToDo/Notes:
 	- Enable the code for setting the NT4 compatibility flag when we start
 	  making NTFS 1.2 specific modifications.
 
-2.1.23-WIP
+2.1.23 - Implement extension of resident files and make writing safe as well as
+	 many bug fixes, cleanups, and enhancements...
 
 	- Add printk rate limiting for ntfs_warning() and ntfs_error() when
 	  compiled without debug.  This avoids a possible denial of service
 	  attack.  Thanks to Carl-Daniel Hailfinger from SuSE for pointing this
 	  out.
+	- Fix compilation warnings on ia64.  (Randy Dunlap)
+	- Use i_size_{read,write}() instead of reading i_size by hand and cache
+	  the value where apropriate.
+	- Add size_lock to the ntfs_inode structure.  This is an rw spinlock
+	  and it locks against access to the inode sizes.  Note, ->size_lock
+	  is also accessed from irq context so you must use the _irqsave and
+	  _irqrestore lock and unlock functions, respectively.  Protect all
+	  accesses to allocated_size, initialized_size, and compressed_size.
+	- Minor optimization to fs/ntfs/super.c::ntfs_statfs() and its helpers.
+	- Implement extension of resident files in the regular file write code
+	  paths (fs/ntfs/aops.c::ntfs_{prepare,commit}_write()).  At present
+	  this only works until the data attribute becomes too big for the mft
+	  record after which we abort the write returning -EOPNOTSUPP from
+	  ntfs_prepare_write().
+	- Add disable_sparse mount option together with a per volume sparse
+	  enable bit which is set appropriately and a per inode sparse disable
+	  bit which is preset on some system file inodes as appropriate.
+	- Enforce that sparse support is disabled on NTFS volumes pre 3.0.
+	- Fix a bug in fs/ntfs/runlist.c::ntfs_mapping_pairs_decompress() in
+	  the creation of the unmapped runlist element for the base attribute
+	  extent.
+	- Split ntfs_map_runlist() into ntfs_map_runlist() and a non-locking
+	  helper ntfs_map_runlist_nolock() which is used by ntfs_map_runlist().
+	  This allows us to map runlist fragments with the runlist lock already
+	  held without having to drop and reacquire it around the call.  Adapt
+	  all callers.
+	- Change ntfs_find_vcn() to ntfs_find_vcn_nolock() which takes a locked
+	  runlist.  This allows us to find runlist elements with the runlist
+	  lock already held without having to drop and reacquire it around the
+	  call.  Adapt all callers.
+	- Change time to u64 in time.h::ntfs2utc() as it otherwise generates a
+	  warning in the do_div() call on sparc32.  Thanks to Meelis Roos for
+	  the report and analysis of the warning.
+	- Fix a nasty runlist merge bug when merging two holes.
+	- Set the ntfs_inode->allocated_size to the real allocated size in the
+	  mft record for resident attributes (fs/ntfs/inode.c).
+	- Small readability cleanup to use "a" instead of "ctx->attr"
+	  everywhere (fs/ntfs/inode.c).
+	- Make fs/ntfs/namei.c::ntfs_get_{parent,dentry} static and move the
+	  definition of ntfs_export_ops from fs/ntfs/super.c to namei.c.  Also,
+	  declare ntfs_export_ops in fs/ntfs/ntfs.h.
+	- Correct sparse file handling.  The compressed values need to be
+	  checked and set in the ntfs inode as done for compressed files and
+	  the compressed size needs to be used for vfs inode->i_blocks instead
+	  of the allocated size, again, as done for compressed files.
+	- Add AT_EA in addition to AT_DATA to whitelist for being allowed to be
+	  non-resident in fs/ntfs/attrib.c::ntfs_attr_can_be_non_resident().
+	- Add fs/ntfs/attrib.c::ntfs_attr_vcn_to_lcn_nolock() used by the new
+	  write code.
+	- Fix bug in fs/ntfs/attrib.c::ntfs_find_vcn_nolock() where after
+	  dropping the read lock and taking the write lock we were not checking
+	  whether someone else did not already do the work we wanted to do.
+	- Rename fs/ntfs/attrib.c::ntfs_find_vcn_nolock() to
+	  ntfs_attr_find_vcn_nolock() and update all callers.
+	- Add fs/ntfs/attrib.[hc]::ntfs_attr_make_non_resident().
+	- Fix sign of various error return values to be negative in
+	  fs/ntfs/lcnalloc.c.
+	- Modify ->readpage and ->writepage (fs/ntfs/aops.c) so they detect and
+	  handle the case where an attribute is converted from resident to
+	  non-resident by a concurrent file write.
+	- Remove checks for NULL before calling kfree() since kfree() does the
+	  checking itself.  (Jesper Juhl)
+	- Some utilities modify the boot sector but do not update the checksum.
+	  Thus, relax the checking in fs/ntfs/super.c::is_boot_sector_ntfs() to
+	  only emit a warning when the checksum is incorrect rather than
+	  refusing the mount.  Thanks to Bernd Casimir for pointing this
+	  problem out.
+	- Update attribute definition handling.
+	- Add NTFS_MAX_CLUSTER_SIZE and NTFS_MAX_PAGES_PER_CLUSTER constants.
+	- Use NTFS_MAX_CLUSTER_SIZE in super.c instead of hard coding 0x10000.
+	- Use MAX_BUF_PER_PAGE instead of variable sized array allocation for
+	  better code generation and one less sparse warning in fs/ntfs/aops.c.
+	- Remove spurious void pointer casts from fs/ntfs/.  (Pekka Enberg)
+	- Use C99 style structure initialization after memory allocation where
+	  possible (fs/ntfs/{attrib.c,index.c,super.c}).  Thanks to Al Viro and
+	  Pekka Enberg.
+	- Stamp the transaction log ($UsnJrnl), aka user space journal, if it
+	  is active on the volume and we are mounting read-write or remounting
+	  from read-only to read-write.
+	- Fix a bug in address space operations error recovery code paths where
+	  if the runlist was not mapped at all and a mapping error occured we
+	  would leave the runlist locked on exit to the function so that the
+	  next access to the same file would try to take the lock and deadlock.
+	- Detect the case when Windows has been suspended to disk on the volume
+	  to be mounted and if this is the case do not allow (re)mounting
+	  read-write.  This is done by parsing hiberfil.sys if present.
+	- Fix several occurences of a bug where we would perform 'var & ~const'
+	  with a 64-bit variable and a int, i.e. 32-bit, constant.  This causes
+	  the higher order 32-bits of the 64-bit variable to be zeroed.  To fix
+	  this cast the 'const' to the same 64-bit type as 'var'.
+	- Change the runlist terminator of the newly allocated cluster(s) to
+	  LCN_ENOENT in ntfs_attr_make_non_resident().  Otherwise the runlist
+	  code gets confused.
+	- Add an extra parameter @last_vcn to ntfs_get_size_for_mapping_pairs()
+	  and ntfs_mapping_pairs_build() to allow the runlist encoding to be
+	  partial which is desirable when filling holes in sparse attributes.
+	  Update all callers.
+	- Change ntfs_map_runlist_nolock() to only decompress the mapping pairs
+	  if the requested vcn is inside it.  Otherwise we get into problems
+	  when we try to map an out of bounds vcn because we then try to map
+	  the already mapped runlist fragment which causes
+	  ntfs_mapping_pairs_decompress() to fail and return error.  Update
+	  ntfs_attr_find_vcn_nolock() accordingly.
+	- Fix a nasty deadlock that appeared in recent kernels.
+	  The situation: VFS inode X on a mounted ntfs volume is dirty.  For
+	  same inode X, the ntfs_inode is dirty and thus corresponding on-disk
+	  inode, i.e. mft record, which is in a dirty PAGE_CACHE_PAGE belonging
+	  to the table of inodes, i.e. $MFT, inode 0.
+	  What happens:
+	  Process 1: sys_sync()/umount()/whatever...  calls
+	  __sync_single_inode() for $MFT -> do_writepages() -> write_page for
+	  the dirty page containing the on-disk inode X, the page is now locked
+	  -> ntfs_write_mst_block() which clears PageUptodate() on the page to
+	  prevent anyone else getting hold of it whilst it does the write out.
+	  This is necessary as the on-disk inode needs "fixups" applied before
+	  the write to disk which are removed again after the write and
+	  PageUptodate is then set again.  It then analyses the page looking
+	  for dirty on-disk inodes and when it finds one it calls
+	  ntfs_may_write_mft_record() to see if it is safe to write this
+	  on-disk inode.  This then calls ilookup5() to check if the
+	  corresponding VFS inode is in icache().  This in turn calls ifind()
+	  which waits on the inode lock via wait_on_inode whilst holding the
+	  global inode_lock.
+	  Process 2: pdflush results in a call to __sync_single_inode for the
+	  same VFS inode X on the ntfs volume.  This locks the inode (I_LOCK)
+	  then calls write-inode -> ntfs_write_inode -> map_mft_record() ->
+	  read_cache_page() for the page (in page cache of table of inodes
+	  $MFT, inode 0) containing the on-disk inode.  This page has
+	  PageUptodate() clear because of Process 1 (see above) so
+	  read_cache_page() blocks when it tries to take the page lock for the
+	  page so it can call ntfs_read_page().
+	  Thus Process 1 is holding the page lock on the page containing the
+	  on-disk inode X and it is waiting on the inode X to be unlocked in
+	  ifind() so it can write the page out and then unlock the page.
+	  And Process 2 is holding the inode lock on inode X and is waiting for
+	  the page to be unlocked so it can call ntfs_readpage() or discover
+	  that Process 1 set PageUptodate() again and use the page.
+	  Thus we have a deadlock due to ifind() waiting on the inode lock.
+	  The solution: The fix is to use the newly introduced
+	  ilookup5_nowait() which does not wait on the inode's lock and hence
+	  avoids the deadlock.  This is safe as we do not care about the VFS
+	  inode and only use the fact that it is in the VFS inode cache and the
+	  fact that the vfs and ntfs inodes are one struct in memory to find
+	  the ntfs inode in memory if present.  Also, the ntfs inode has its
+	  own locking so it does not matter if the vfs inode is locked.
+	- Fix bug in mft record writing where we forgot to set the device in
+	  the buffers when mapping them after the VM had discarded them.
+	  Thanks to Martin MOKREJÅ  for the bug report.
 
 2.1.22 - Many bug and race fixes and error handling improvements.
 
@@ -1037,7 +1183,7 @@ tng-0.0.8 - 08/03/2002 - Now using BitKe
 	- Further runlist merging work. (Richard Russon)
 	- Backwards compatibility for gcc-2.95. (Richard Russon)
 	- Update to kernel 2.5.5-pre1 and rediff the now tiny patch.
-	- Convert to new file system declaration using ->ntfs_get_sb() and
+	- Convert to new filesystem declaration using ->ntfs_get_sb() and
 	  replacing ntfs_read_super() with ntfs_fill_super().
 	- Set s_maxbytes to MAX_LFS_FILESIZE to avoid page cache page index
 	  overflow on 32-bit architectures.
@@ -1333,7 +1479,7 @@ tng-0.0.1 - The first useful version.
 	The driver is now actually useful! Yey. (-: It undoubtedly has got bugs
 	though and it doesn't implement accesssing compressed files yet. Also,
 	accessing files with attribute list attributes is not implemented yet
-	either. But for small or simple file systems it should work and allow
+	either. But for small or simple filesystems it should work and allow
 	you to list directories, use stat on directory entries and the file
 	system, open, read, mmap and llseek around in files. A big mile stone
 	has been reached!
@@ -1341,7 +1487,7 @@ tng-0.0.1 - The first useful version.
 tng-0.0.0 - Initial version tag.
 
 	Initial driver implementation. The driver can mount and umount simple
-	NTFS file systems (i.e. ones without attribute lists in the system
+	NTFS filesystems (i.e. ones without attribute lists in the system
 	files). If the mount fails there might be problems in the error handling
 	code paths, so be warned. Otherwise it seems to be loading the system
 	files nicely and the mft record read mapping/unmapping seems to be
diff --git a/fs/ntfs/Makefile b/fs/ntfs/Makefile
--- a/fs/ntfs/Makefile
+++ b/fs/ntfs/Makefile
@@ -6,7 +6,7 @@ ntfs-objs := aops.o attrib.o collate.o c
 	     index.o inode.o mft.o mst.o namei.o runlist.o super.o sysctl.o \
 	     unistr.o upcase.o
 
-EXTRA_CFLAGS = -DNTFS_VERSION=\"2.1.22\"
+EXTRA_CFLAGS = -DNTFS_VERSION=\"2.1.23\"
 
 ifeq ($(CONFIG_NTFS_DEBUG),y)
 EXTRA_CFLAGS += -DDEBUG
@@ -15,5 +15,5 @@ endif
 ifeq ($(CONFIG_NTFS_RW),y)
 EXTRA_CFLAGS += -DNTFS_RW
 
-ntfs-objs += bitmap.o lcnalloc.o logfile.o quota.o
+ntfs-objs += bitmap.o lcnalloc.o logfile.o quota.o usnjrnl.o
 endif
diff --git a/fs/ntfs/aops.c b/fs/ntfs/aops.c
--- a/fs/ntfs/aops.c
+++ b/fs/ntfs/aops.c
@@ -2,7 +2,7 @@
  * aops.c - NTFS kernel address space operations and page cache handling.
  *	    Part of the Linux-NTFS project.
  *
- * Copyright (c) 2001-2004 Anton Altaparmakov
+ * Copyright (c) 2001-2005 Anton Altaparmakov
  * Copyright (c) 2002 Richard Russon
  *
  * This program/include file is free software; you can redistribute it and/or
@@ -66,19 +66,22 @@ static void ntfs_end_buffer_async_read(s
 	ni = NTFS_I(page->mapping->host);
 
 	if (likely(uptodate)) {
-		s64 file_ofs;
+		s64 file_ofs, initialized_size;
 
 		set_buffer_uptodate(bh);
 
 		file_ofs = ((s64)page->index << PAGE_CACHE_SHIFT) +
 				bh_offset(bh);
+		read_lock_irqsave(&ni->size_lock, flags);
+		initialized_size = ni->initialized_size;
+		read_unlock_irqrestore(&ni->size_lock, flags);
 		/* Check for the current buffer head overflowing. */
-		if (file_ofs + bh->b_size > ni->initialized_size) {
+		if (file_ofs + bh->b_size > initialized_size) {
 			char *addr;
 			int ofs = 0;
 
-			if (file_ofs < ni->initialized_size)
-				ofs = ni->initialized_size - file_ofs;
+			if (file_ofs < initialized_size)
+				ofs = initialized_size - file_ofs;
 			addr = kmap_atomic(page, KM_BIO_SRC_IRQ);
 			memset(addr + bh_offset(bh) + ofs, 0, bh->b_size - ofs);
 			flush_dcache_page(page);
@@ -132,7 +135,7 @@ static void ntfs_end_buffer_async_read(s
 					i * rec_size), rec_size);
 		flush_dcache_page(page);
 		kunmap_atomic(addr, KM_BIO_SRC_IRQ);
-		if (likely(!PageError(page) && page_uptodate))
+		if (likely(page_uptodate && !PageError(page)))
 			SetPageUptodate(page);
 	}
 	unlock_page(page);
@@ -168,6 +171,7 @@ static int ntfs_read_block(struct page *
 	runlist_element *rl;
 	struct buffer_head *bh, *head, *arr[MAX_BUF_PER_PAGE];
 	sector_t iblock, lblock, zblock;
+	unsigned long flags;
 	unsigned int blocksize, vcn_ofs;
 	int i, nr;
 	unsigned char blocksize_bits;
@@ -190,8 +194,10 @@ static int ntfs_read_block(struct page *
 	}
 
 	iblock = (s64)page->index << (PAGE_CACHE_SHIFT - blocksize_bits);
+	read_lock_irqsave(&ni->size_lock, flags);
 	lblock = (ni->allocated_size + blocksize - 1) >> blocksize_bits;
 	zblock = (ni->initialized_size + blocksize - 1) >> blocksize_bits;
+	read_unlock_irqrestore(&ni->size_lock, flags);
 
 	/* Loop through all the buffers in the page. */
 	rl = NULL;
@@ -258,7 +264,8 @@ lock_retry_remap:
 					goto lock_retry_remap;
 				rl = NULL;
 				lcn = err;
-			}
+			} else if (!rl)
+				up_read(&ni->runlist.lock);
 			/* Hard error, zero out region. */
 			bh->b_blocknr = -1;
 			SetPageError(page);
@@ -341,14 +348,15 @@ handle_zblock:
  */
 static int ntfs_readpage(struct file *file, struct page *page)
 {
-	loff_t i_size;
 	ntfs_inode *ni, *base_ni;
 	u8 *kaddr;
 	ntfs_attr_search_ctx *ctx;
 	MFT_RECORD *mrec;
+	unsigned long flags;
 	u32 attr_len;
 	int err = 0;
 
+retry_readpage:
 	BUG_ON(!PageLocked(page));
 	/*
 	 * This can potentially happen because we clear PageUptodate() during
@@ -383,9 +391,9 @@ static int ntfs_readpage(struct file *fi
 	 * Attribute is resident, implying it is not compressed or encrypted.
 	 * This also means the attribute is smaller than an mft record and
 	 * hence smaller than a page, so can simply zero out any pages with
-	 * index above 0.  We can also do this if the file size is 0.
+	 * index above 0.
 	 */
-	if (unlikely(page->index > 0 || !i_size_read(VFS_I(ni)))) {
+	if (unlikely(page->index > 0)) {
 		kaddr = kmap_atomic(page, KM_USER0);
 		memset(kaddr, 0, PAGE_CACHE_SIZE);
 		flush_dcache_page(page);
@@ -402,6 +410,14 @@ static int ntfs_readpage(struct file *fi
 		err = PTR_ERR(mrec);
 		goto err_out;
 	}
+	/*
+	 * If a parallel write made the attribute non-resident, drop the mft
+	 * record and retry the readpage.
+	 */
+	if (unlikely(NInoNonResident(ni))) {
+		unmap_mft_record(base_ni);
+		goto retry_readpage;
+	}
 	ctx = ntfs_attr_get_search_ctx(base_ni, mrec);
 	if (unlikely(!ctx)) {
 		err = -ENOMEM;
@@ -412,9 +428,10 @@ static int ntfs_readpage(struct file *fi
 	if (unlikely(err))
 		goto put_unm_err_out;
 	attr_len = le32_to_cpu(ctx->attr->data.resident.value_length);
-	i_size = i_size_read(VFS_I(ni));
-	if (unlikely(attr_len > i_size))
-		attr_len = i_size;
+	read_lock_irqsave(&ni->size_lock, flags);
+	if (unlikely(attr_len > ni->initialized_size))
+		attr_len = ni->initialized_size;
+	read_unlock_irqrestore(&ni->size_lock, flags);
 	kaddr = kmap_atomic(page, KM_USER0);
 	/* Copy the data to the page. */
 	memcpy(kaddr, (u8*)ctx->attr +
@@ -463,12 +480,15 @@ static int ntfs_write_block(struct page 
 {
 	VCN vcn;
 	LCN lcn;
+	s64 initialized_size;
+	loff_t i_size;
 	sector_t block, dblock, iblock;
 	struct inode *vi;
 	ntfs_inode *ni;
 	ntfs_volume *vol;
 	runlist_element *rl;
 	struct buffer_head *bh, *head;
+	unsigned long flags;
 	unsigned int blocksize, vcn_ofs;
 	int err;
 	BOOL need_end_writeback;
@@ -510,11 +530,16 @@ static int ntfs_write_block(struct page 
 	/* The first block in the page. */
 	block = (s64)page->index << (PAGE_CACHE_SHIFT - blocksize_bits);
 
+	read_lock_irqsave(&ni->size_lock, flags);
+	i_size = i_size_read(vi);
+	initialized_size = ni->initialized_size;
+	read_unlock_irqrestore(&ni->size_lock, flags);
+
 	/* The first out of bounds block for the data size. */
-	dblock = (vi->i_size + blocksize - 1) >> blocksize_bits;
+	dblock = (i_size + blocksize - 1) >> blocksize_bits;
 
 	/* The last (fully or partially) initialized block. */
-	iblock = ni->initialized_size >> blocksize_bits;
+	iblock = initialized_size >> blocksize_bits;
 
 	/*
 	 * Be very careful.  We have no exclusion from __set_page_dirty_buffers
@@ -559,7 +584,7 @@ static int ntfs_write_block(struct page 
 
 		/* Make sure we have enough initialized size. */
 		if (unlikely((block >= iblock) &&
-				(ni->initialized_size < vi->i_size))) {
+				(initialized_size < i_size))) {
 			/*
 			 * If this page is fully outside initialized size, zero
 			 * out all pages between the current initialized size
@@ -666,7 +691,8 @@ lock_retry_remap:
 				goto lock_retry_remap;
 			rl = NULL;
 			lcn = err;
-		}
+		} else if (!rl)
+			up_read(&ni->runlist.lock);
 		/* Failed to map the buffer, even after retrying. */
 		bh->b_blocknr = -1;
 		ntfs_error(vol->sb, "Failed to write to inode 0x%lx, "
@@ -801,17 +827,15 @@ static int ntfs_write_mst_block(struct p
 	ntfs_inode *ni = NTFS_I(vi);
 	ntfs_volume *vol = ni->vol;
 	u8 *kaddr;
-	unsigned char bh_size_bits = vi->i_blkbits;
-	unsigned int bh_size = 1 << bh_size_bits;
 	unsigned int rec_size = ni->itype.index.block_size;
 	ntfs_inode *locked_nis[PAGE_CACHE_SIZE / rec_size];
 	struct buffer_head *bh, *head, *tbh, *rec_start_bh;
-	int max_bhs = PAGE_CACHE_SIZE / bh_size;
-	struct buffer_head *bhs[max_bhs];
+	struct buffer_head *bhs[MAX_BUF_PER_PAGE];
 	runlist_element *rl;
-	int i, nr_locked_nis, nr_recs, nr_bhs, bhs_per_rec, err, err2;
-	unsigned rec_size_bits;
+	int i, nr_locked_nis, nr_recs, nr_bhs, max_bhs, bhs_per_rec, err, err2;
+	unsigned bh_size, rec_size_bits;
 	BOOL sync, is_mft, page_is_dirty, rec_is_dirty;
+	unsigned char bh_size_bits;
 
 	ntfs_debug("Entering for inode 0x%lx, attribute type 0x%x, page index "
 			"0x%lx.", vi->i_ino, ni->type, page->index);
@@ -826,7 +850,11 @@ static int ntfs_write_mst_block(struct p
 	 */
 	BUG_ON(!(is_mft || S_ISDIR(vi->i_mode) ||
 			(NInoAttr(ni) && ni->type == AT_INDEX_ALLOCATION)));
+	bh_size_bits = vi->i_blkbits;
+	bh_size = 1 << bh_size_bits;
+	max_bhs = PAGE_CACHE_SIZE / bh_size;
 	BUG_ON(!max_bhs);
+	BUG_ON(max_bhs > MAX_BUF_PER_PAGE);
 
 	/* Were we called for sync purposes? */
 	sync = (wbc->sync_mode == WB_SYNC_ALL);
@@ -846,7 +874,7 @@ static int ntfs_write_mst_block(struct p
 			(PAGE_CACHE_SHIFT - bh_size_bits);
 
 	/* The first out of bounds block for the data size. */
-	dblock = (vi->i_size + bh_size - 1) >> bh_size_bits;
+	dblock = (i_size_read(vi) + bh_size - 1) >> bh_size_bits;
 
 	rl = NULL;
 	err = err2 = nr_bhs = nr_recs = nr_locked_nis = 0;
@@ -858,6 +886,7 @@ static int ntfs_write_mst_block(struct p
 		if (likely(block < rec_block)) {
 			if (unlikely(block >= dblock)) {
 				clear_buffer_dirty(bh);
+				set_buffer_uptodate(bh);
 				continue;
 			}
 			/*
@@ -895,6 +924,7 @@ static int ntfs_write_mst_block(struct p
 			LCN lcn;
 			unsigned int vcn_ofs;
 
+			bh->b_bdev = vol->sb->s_bdev;
 			/* Obtain the vcn and offset of the current block. */
 			vcn = (VCN)block << bh_size_bits;
 			vcn_ofs = vcn & vol->cluster_size_mask;
@@ -938,8 +968,11 @@ lock_retry_remap:
 					if (err2 == -ENOMEM)
 						page_is_dirty = TRUE;
 					lcn = err2;
-				} else
+				} else {
 					err2 = -EIO;
+					if (!rl)
+						up_read(&ni->runlist.lock);
+				}
 				/* Hard error.  Abort writing this record. */
 				if (!err || err == -ENOMEM)
 					err = err2;
@@ -949,7 +982,8 @@ lock_retry_remap:
 						"attribute type 0x%x) because "
 						"its location on disk could "
 						"not be determined (error "
-						"code %lli).", (s64)block <<
+						"code %lli).",
+						(long long)block <<
 						bh_size_bits >>
 						vol->mft_record_size_bits,
 						ni->mft_no, ni->type,
@@ -1223,19 +1257,17 @@ done:
 static int ntfs_writepage(struct page *page, struct writeback_control *wbc)
 {
 	loff_t i_size;
-	struct inode *vi;
-	ntfs_inode *ni, *base_ni;
+	struct inode *vi = page->mapping->host;
+	ntfs_inode *base_ni = NULL, *ni = NTFS_I(vi);
 	char *kaddr;
-	ntfs_attr_search_ctx *ctx;
-	MFT_RECORD *m;
+	ntfs_attr_search_ctx *ctx = NULL;
+	MFT_RECORD *m = NULL;
 	u32 attr_len;
 	int err;
 
+retry_writepage:
 	BUG_ON(!PageLocked(page));
-
-	vi = page->mapping->host;
 	i_size = i_size_read(vi);
-
 	/* Is the page fully outside i_size? (truncate in progress) */
 	if (unlikely(page->index >= (i_size + PAGE_CACHE_SIZE - 1) >>
 			PAGE_CACHE_SHIFT)) {
@@ -1248,8 +1280,6 @@ static int ntfs_writepage(struct page *p
 		ntfs_debug("Write outside i_size - truncated?");
 		return 0;
 	}
-	ni = NTFS_I(vi);
-
 	/* NInoNonResident() == NInoIndexAllocPresent() */
 	if (NInoNonResident(ni)) {
 		/*
@@ -1326,6 +1356,14 @@ static int ntfs_writepage(struct page *p
 		ctx = NULL;
 		goto err_out;
 	}
+	/*
+	 * If a parallel write made the attribute non-resident, drop the mft
+	 * record and retry the writepage.
+	 */
+	if (unlikely(NInoNonResident(ni))) {
+		unmap_mft_record(base_ni);
+		goto retry_writepage;
+	}
 	ctx = ntfs_attr_get_search_ctx(base_ni, m);
 	if (unlikely(!ctx)) {
 		err = -ENOMEM;
@@ -1367,15 +1405,12 @@ static int ntfs_writepage(struct page *p
 	 */
 
 	attr_len = le32_to_cpu(ctx->attr->data.resident.value_length);
-	i_size = i_size_read(VFS_I(ni));
-	kaddr = kmap_atomic(page, KM_USER0);
+	i_size = i_size_read(vi);
 	if (unlikely(attr_len > i_size)) {
-		/* Zero out of bounds area in the mft record. */
-		memset((u8*)ctx->attr + le16_to_cpu(
-				ctx->attr->data.resident.value_offset) +
-				i_size, 0, attr_len - i_size);
 		attr_len = i_size;
+		ctx->attr->data.resident.value_length = cpu_to_le32(attr_len);
 	}
+	kaddr = kmap_atomic(page, KM_USER0);
 	/* Copy the data from the page to the mft record. */
 	memcpy((u8*)ctx->attr +
 			le16_to_cpu(ctx->attr->data.resident.value_offset),
@@ -1405,8 +1440,10 @@ err_out:
 		err = 0;
 	} else {
 		ntfs_error(vi->i_sb, "Resident attribute write failed with "
-				"error %i.  Setting page error flag.", err);
+				"error %i.", err);
 		SetPageError(page);
+		NVolSetErrors(ni->vol);
+		make_bad_inode(vi);
 	}
 	unlock_page(page);
 	if (ctx)
@@ -1425,12 +1462,15 @@ static int ntfs_prepare_nonresident_writ
 {
 	VCN vcn;
 	LCN lcn;
+	s64 initialized_size;
+	loff_t i_size;
 	sector_t block, ablock, iblock;
 	struct inode *vi;
 	ntfs_inode *ni;
 	ntfs_volume *vol;
 	runlist_element *rl;
 	struct buffer_head *bh, *head, *wait[2], **wait_bh = wait;
+	unsigned long flags;
 	unsigned int vcn_ofs, block_start, block_end, blocksize;
 	int err;
 	BOOL is_retry;
@@ -1462,16 +1502,20 @@ static int ntfs_prepare_nonresident_writ
 	/* The first block in the page. */
 	block = (s64)page->index << (PAGE_CACHE_SHIFT - blocksize_bits);
 
+	read_lock_irqsave(&ni->size_lock, flags);
 	/*
-	 * The first out of bounds block for the allocated size. No need to
+	 * The first out of bounds block for the allocated size.  No need to
 	 * round up as allocated_size is in multiples of cluster size and the
 	 * minimum cluster size is 512 bytes, which is equal to the smallest
 	 * blocksize.
 	 */
 	ablock = ni->allocated_size >> blocksize_bits;
+	i_size = i_size_read(vi);
+	initialized_size = ni->initialized_size;
+	read_unlock_irqrestore(&ni->size_lock, flags);
 
 	/* The last (fully or partially) initialized block. */
-	iblock = ni->initialized_size >> blocksize_bits;
+	iblock = initialized_size >> blocksize_bits;
 
 	/* Loop through all the buffers in the page. */
 	block_start = 0;
@@ -1518,7 +1562,7 @@ static int ntfs_prepare_nonresident_writ
 		 * request, i.e. block < ablock is true.
 		 */
 		if (unlikely((block >= iblock) &&
-				(ni->initialized_size < vi->i_size))) {
+				(initialized_size < i_size))) {
 			/*
 			 * If this page is fully outside initialized size, zero
 			 * out all pages between the current initialized size
@@ -1622,6 +1666,8 @@ lock_retry_remap:
 							"not supported yet. "
 							"Sorry.");
 					err = -EOPNOTSUPP;
+					if (!rl)
+						up_read(&ni->runlist.lock);
 					goto err_out;
 				} else if (!is_retry &&
 						lcn == LCN_RL_NOT_MAPPED) {
@@ -1636,7 +1682,8 @@ lock_retry_remap:
 						goto lock_retry_remap;
 					rl = NULL;
 					lcn = err;
-				}
+				} else if (!rl)
+					up_read(&ni->runlist.lock);
 				/*
 				 * Failed to map the buffer, even after
 				 * retrying.
@@ -1797,6 +1844,7 @@ static int ntfs_prepare_write(struct fil
 		unsigned from, unsigned to)
 {
 	s64 new_size;
+	loff_t i_size;
 	struct inode *vi = page->mapping->host;
 	ntfs_inode *base_ni = NULL, *ni = NTFS_I(vi);
 	ntfs_volume *vol = ni->vol;
@@ -1868,14 +1916,8 @@ static int ntfs_prepare_write(struct fil
 	BUG_ON(page_has_buffers(page));
 	new_size = ((s64)page->index << PAGE_CACHE_SHIFT) + to;
 	/* If we do not need to resize the attribute allocation we are done. */
-	if (new_size <= vi->i_size)
+	if (new_size <= i_size_read(vi))
 		goto done;
-
-	// FIXME: We abort for now as this code is not safe.
-	ntfs_error(vi->i_sb, "Changing the file size is not supported yet.  "
-			"Sorry.");
-	return -EOPNOTSUPP;
-
 	/* Map, pin, and lock the (base) mft record. */
 	if (!NInoAttr(ni))
 		base_ni = ni;
@@ -1904,7 +1946,15 @@ static int ntfs_prepare_write(struct fil
 	a = ctx->attr;
 	/* The total length of the attribute value. */
 	attr_len = le32_to_cpu(a->data.resident.value_length);
-	BUG_ON(vi->i_size != attr_len);
+	/* Fix an eventual previous failure of ntfs_commit_write(). */
+	i_size = i_size_read(vi);
+	if (unlikely(attr_len > i_size)) {
+		attr_len = i_size;
+		a->data.resident.value_length = cpu_to_le32(attr_len);
+	}
+	/* If we do not need to resize the attribute allocation we are done. */
+	if (new_size <= attr_len)
+		goto done_unm;
 	/* Check if new size is allowed in $AttrDef. */
 	err = ntfs_attr_size_bounds_check(vol, ni->type, new_size);
 	if (unlikely(err)) {
@@ -1962,6 +2012,7 @@ static int ntfs_prepare_write(struct fil
 	}
 	flush_dcache_mft_record_page(ctx->ntfs_ino);
 	mark_mft_record_dirty(ctx->ntfs_ino);
+done_unm:
 	ntfs_attr_put_search_ctx(ctx);
 	unmap_mft_record(base_ni);
 	/*
@@ -2047,7 +2098,7 @@ static int ntfs_commit_nonresident_write
 	 * now we know ntfs_prepare_write() would have failed in the write
 	 * exceeds i_size case, so this will never trigger which is fine.
 	 */
-	if (pos > vi->i_size) {
+	if (pos > i_size_read(vi)) {
 		ntfs_error(vi->i_sb, "Writing beyond the existing file size is "
 				"not supported yet.  Sorry.");
 		return -EOPNOTSUPP;
@@ -2183,9 +2234,13 @@ static int ntfs_commit_write(struct file
 	}
 	kunmap_atomic(kaddr, KM_USER0);
 	/* Update i_size if necessary. */
-	if (vi->i_size < attr_len) {
+	if (i_size_read(vi) < attr_len) {
+		unsigned long flags;
+
+		write_lock_irqsave(&ni->size_lock, flags);
 		ni->allocated_size = ni->initialized_size = attr_len;
 		i_size_write(vi, attr_len);
+		write_unlock_irqrestore(&ni->size_lock, flags);
 	}
 	/* Mark the mft record dirty, so it gets written back. */
 	flush_dcache_mft_record_page(ctx->ntfs_ino);
diff --git a/fs/ntfs/attrib.c b/fs/ntfs/attrib.c
--- a/fs/ntfs/attrib.c
+++ b/fs/ntfs/attrib.c
@@ -1,7 +1,7 @@
 /**
  * attrib.c - NTFS attribute operations.  Part of the Linux-NTFS project.
  *
- * Copyright (c) 2001-2004 Anton Altaparmakov
+ * Copyright (c) 2001-2005 Anton Altaparmakov
  * Copyright (c) 2002 Richard Russon
  *
  * This program/include file is free software; you can redistribute it and/or
@@ -21,88 +21,217 @@
  */
 
 #include <linux/buffer_head.h>
+#include <linux/swap.h>
 
 #include "attrib.h"
 #include "debug.h"
 #include "layout.h"
+#include "lcnalloc.h"
+#include "malloc.h"
 #include "mft.h"
 #include "ntfs.h"
 #include "types.h"
 
 /**
- * ntfs_map_runlist - map (a part of) a runlist of an ntfs inode
+ * ntfs_map_runlist_nolock - map (a part of) a runlist of an ntfs inode
  * @ni:		ntfs inode for which to map (part of) a runlist
  * @vcn:	map runlist part containing this vcn
  *
  * Map the part of a runlist containing the @vcn of the ntfs inode @ni.
  *
- * Return 0 on success and -errno on error.
+ * Return 0 on success and -errno on error.  There is one special error code
+ * which is not an error as such.  This is -ENOENT.  It means that @vcn is out
+ * of bounds of the runlist.
  *
- * Locking: - The runlist must be unlocked on entry and is unlocked on return.
- *	    - This function takes the lock for writing and modifies the runlist.
+ * Locking: - The runlist must be locked for writing.
+ *	    - This function modifies the runlist.
  */
-int ntfs_map_runlist(ntfs_inode *ni, VCN vcn)
+int ntfs_map_runlist_nolock(ntfs_inode *ni, VCN vcn)
 {
+	VCN end_vcn;
 	ntfs_inode *base_ni;
+	MFT_RECORD *m;
+	ATTR_RECORD *a;
 	ntfs_attr_search_ctx *ctx;
-	MFT_RECORD *mrec;
+	runlist_element *rl;
 	int err = 0;
 
 	ntfs_debug("Mapping runlist part containing vcn 0x%llx.",
 			(unsigned long long)vcn);
-
 	if (!NInoAttr(ni))
 		base_ni = ni;
 	else
 		base_ni = ni->ext.base_ntfs_ino;
-
-	mrec = map_mft_record(base_ni);
-	if (IS_ERR(mrec))
-		return PTR_ERR(mrec);
-	ctx = ntfs_attr_get_search_ctx(base_ni, mrec);
+	m = map_mft_record(base_ni);
+	if (IS_ERR(m))
+		return PTR_ERR(m);
+	ctx = ntfs_attr_get_search_ctx(base_ni, m);
 	if (unlikely(!ctx)) {
 		err = -ENOMEM;
 		goto err_out;
 	}
 	err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len,
 			CASE_SENSITIVE, vcn, NULL, 0, ctx);
-	if (unlikely(err))
-		goto put_err_out;
+	if (unlikely(err)) {
+		if (err == -ENOENT)
+			err = -EIO;
+		goto err_out;
+	}
+	a = ctx->attr;
+	/*
+	 * Only decompress the mapping pairs if @vcn is inside it.  Otherwise
+	 * we get into problems when we try to map an out of bounds vcn because
+	 * we then try to map the already mapped runlist fragment and
+	 * ntfs_mapping_pairs_decompress() fails.
+	 */
+	end_vcn = sle64_to_cpu(a->data.non_resident.highest_vcn) + 1;
+	if (unlikely(!a->data.non_resident.lowest_vcn && end_vcn <= 1))
+		end_vcn = ni->allocated_size >> ni->vol->cluster_size_bits;
+	if (unlikely(vcn >= end_vcn)) {
+		err = -ENOENT;
+		goto err_out;
+	}
+	rl = ntfs_mapping_pairs_decompress(ni->vol, a, ni->runlist.rl);
+	if (IS_ERR(rl))
+		err = PTR_ERR(rl);
+	else
+		ni->runlist.rl = rl;
+err_out:
+	if (likely(ctx))
+		ntfs_attr_put_search_ctx(ctx);
+	unmap_mft_record(base_ni);
+	return err;
+}
+
+/**
+ * ntfs_map_runlist - map (a part of) a runlist of an ntfs inode
+ * @ni:		ntfs inode for which to map (part of) a runlist
+ * @vcn:	map runlist part containing this vcn
+ *
+ * Map the part of a runlist containing the @vcn of the ntfs inode @ni.
+ *
+ * Return 0 on success and -errno on error.  There is one special error code
+ * which is not an error as such.  This is -ENOENT.  It means that @vcn is out
+ * of bounds of the runlist.
+ *
+ * Locking: - The runlist must be unlocked on entry and is unlocked on return.
+ *	    - This function takes the runlist lock for writing and modifies the
+ *	      runlist.
+ */
+int ntfs_map_runlist(ntfs_inode *ni, VCN vcn)
+{
+	int err = 0;
 
 	down_write(&ni->runlist.lock);
 	/* Make sure someone else didn't do the work while we were sleeping. */
 	if (likely(ntfs_rl_vcn_to_lcn(ni->runlist.rl, vcn) <=
-			LCN_RL_NOT_MAPPED)) {
-		runlist_element *rl;
+			LCN_RL_NOT_MAPPED))
+		err = ntfs_map_runlist_nolock(ni, vcn);
+	up_write(&ni->runlist.lock);
+	return err;
+}
 
-		rl = ntfs_mapping_pairs_decompress(ni->vol, ctx->attr,
-				ni->runlist.rl);
-		if (IS_ERR(rl))
-			err = PTR_ERR(rl);
+/**
+ * ntfs_attr_vcn_to_lcn_nolock - convert a vcn into a lcn given an ntfs inode
+ * @ni:			ntfs inode of the attribute whose runlist to search
+ * @vcn:		vcn to convert
+ * @write_locked:	true if the runlist is locked for writing
+ *
+ * Find the virtual cluster number @vcn in the runlist of the ntfs attribute
+ * described by the ntfs inode @ni and return the corresponding logical cluster
+ * number (lcn).
+ *
+ * If the @vcn is not mapped yet, the attempt is made to map the attribute
+ * extent containing the @vcn and the vcn to lcn conversion is retried.
+ *
+ * If @write_locked is true the caller has locked the runlist for writing and
+ * if false for reading.
+ *
+ * Since lcns must be >= 0, we use negative return codes with special meaning:
+ *
+ * Return code	Meaning / Description
+ * ==========================================
+ *  LCN_HOLE	Hole / not allocated on disk.
+ *  LCN_ENOENT	There is no such vcn in the runlist, i.e. @vcn is out of bounds.
+ *  LCN_ENOMEM	Not enough memory to map runlist.
+ *  LCN_EIO	Critical error (runlist/file is corrupt, i/o error, etc).
+ *
+ * Locking: - The runlist must be locked on entry and is left locked on return.
+ *	    - If @write_locked is FALSE, i.e. the runlist is locked for reading,
+ *	      the lock may be dropped inside the function so you cannot rely on
+ *	      the runlist still being the same when this function returns.
+ */
+LCN ntfs_attr_vcn_to_lcn_nolock(ntfs_inode *ni, const VCN vcn,
+		const BOOL write_locked)
+{
+	LCN lcn;
+	BOOL is_retry = FALSE;
+
+	ntfs_debug("Entering for i_ino 0x%lx, vcn 0x%llx, %s_locked.",
+			ni->mft_no, (unsigned long long)vcn,
+			write_locked ? "write" : "read");
+	BUG_ON(!ni);
+	BUG_ON(!NInoNonResident(ni));
+	BUG_ON(vcn < 0);
+retry_remap:
+	/* Convert vcn to lcn.  If that fails map the runlist and retry once. */
+	lcn = ntfs_rl_vcn_to_lcn(ni->runlist.rl, vcn);
+	if (likely(lcn >= LCN_HOLE)) {
+		ntfs_debug("Done, lcn 0x%llx.", (long long)lcn);
+		return lcn;
+	}
+	if (lcn != LCN_RL_NOT_MAPPED) {
+		if (lcn != LCN_ENOENT)
+			lcn = LCN_EIO;
+	} else if (!is_retry) {
+		int err;
+
+		if (!write_locked) {
+			up_read(&ni->runlist.lock);
+			down_write(&ni->runlist.lock);
+			if (unlikely(ntfs_rl_vcn_to_lcn(ni->runlist.rl, vcn) !=
+					LCN_RL_NOT_MAPPED)) {
+				up_write(&ni->runlist.lock);
+				down_read(&ni->runlist.lock);
+				goto retry_remap;
+			}
+		}
+		err = ntfs_map_runlist_nolock(ni, vcn);
+		if (!write_locked) {
+			up_write(&ni->runlist.lock);
+			down_read(&ni->runlist.lock);
+		}
+		if (likely(!err)) {
+			is_retry = TRUE;
+			goto retry_remap;
+		}
+		if (err == -ENOENT)
+			lcn = LCN_ENOENT;
+		else if (err == -ENOMEM)
+			lcn = LCN_ENOMEM;
 		else
-			ni->runlist.rl = rl;
+			lcn = LCN_EIO;
 	}
-	up_write(&ni->runlist.lock);
-
-put_err_out:
-	ntfs_attr_put_search_ctx(ctx);
-err_out:
-	unmap_mft_record(base_ni);
-	return err;
+	if (lcn != LCN_ENOENT)
+		ntfs_error(ni->vol->sb, "Failed with error code %lli.",
+				(long long)lcn);
+	return lcn;
 }
 
 /**
- * ntfs_find_vcn - find a vcn in the runlist described by an ntfs inode
- * @ni:		ntfs inode describing the runlist to search
- * @vcn:	vcn to find
- * @need_write:	if false, lock for reading and if true, lock for writing
+ * ntfs_attr_find_vcn_nolock - find a vcn in the runlist of an ntfs inode
+ * @ni:			ntfs inode describing the runlist to search
+ * @vcn:		vcn to find
+ * @write_locked:	true if the runlist is locked for writing
  *
  * Find the virtual cluster number @vcn in the runlist described by the ntfs
  * inode @ni and return the address of the runlist element containing the @vcn.
- * The runlist is left locked and the caller has to unlock it.  If @need_write
- * is true, the runlist is locked for writing and if @need_write is false, the
- * runlist is locked for reading.  In the error case, the runlist is not left
- * locked.
+ *
+ * If the @vcn is not mapped yet, the attempt is made to map the attribute
+ * extent containing the @vcn and the vcn to lcn conversion is retried.
+ *
+ * If @write_locked is true the caller has locked the runlist for writing and
+ * if false for reading.
  *
  * Note you need to distinguish between the lcn of the returned runlist element
  * being >= 0 and LCN_HOLE.  In the later case you have to return zeroes on
@@ -118,34 +247,29 @@ err_out:
  *	-ENOMEM - Not enough memory to map runlist.
  *	-EIO	- Critical error (runlist/file is corrupt, i/o error, etc).
  *
- * Locking: - The runlist must be unlocked on entry.
- *	    - On failing return, the runlist is unlocked.
- *	    - On successful return, the runlist is locked.  If @need_write us
- *	      true, it is locked for writing.  Otherwise is is locked for
- *	      reading.
+ * Locking: - The runlist must be locked on entry and is left locked on return.
+ *	    - If @write_locked is FALSE, i.e. the runlist is locked for reading,
+ *	      the lock may be dropped inside the function so you cannot rely on
+ *	      the runlist still being the same when this function returns.
  */
-runlist_element *ntfs_find_vcn(ntfs_inode *ni, const VCN vcn,
-		const BOOL need_write)
+runlist_element *ntfs_attr_find_vcn_nolock(ntfs_inode *ni, const VCN vcn,
+		const BOOL write_locked)
 {
 	runlist_element *rl;
 	int err = 0;
 	BOOL is_retry = FALSE;
 
-	ntfs_debug("Entering for i_ino 0x%lx, vcn 0x%llx, lock for %sing.",
+	ntfs_debug("Entering for i_ino 0x%lx, vcn 0x%llx, %s_locked.",
 			ni->mft_no, (unsigned long long)vcn,
-			!need_write ? "read" : "writ");
+			write_locked ? "write" : "read");
 	BUG_ON(!ni);
 	BUG_ON(!NInoNonResident(ni));
 	BUG_ON(vcn < 0);
-lock_retry_remap:
-	if (!need_write)
-		down_read(&ni->runlist.lock);
-	else
-		down_write(&ni->runlist.lock);
+retry_remap:
 	rl = ni->runlist.rl;
 	if (likely(rl && vcn >= rl[0].vcn)) {
 		while (likely(rl->length)) {
-			if (likely(vcn < rl[1].vcn)) {
+			if (unlikely(vcn < rl[1].vcn)) {
 				if (likely(rl->lcn >= LCN_HOLE)) {
 					ntfs_debug("Done.");
 					return rl;
@@ -161,30 +285,41 @@ lock_retry_remap:
 				err = -EIO;
 		}
 	}
-	if (!need_write)
-		up_read(&ni->runlist.lock);
-	else
-		up_write(&ni->runlist.lock);
 	if (!err && !is_retry) {
 		/*
 		 * The @vcn is in an unmapped region, map the runlist and
 		 * retry.
 		 */
-		err = ntfs_map_runlist(ni, vcn);
+		if (!write_locked) {
+			up_read(&ni->runlist.lock);
+			down_write(&ni->runlist.lock);
+			if (unlikely(ntfs_rl_vcn_to_lcn(ni->runlist.rl, vcn) !=
+					LCN_RL_NOT_MAPPED)) {
+				up_write(&ni->runlist.lock);
+				down_read(&ni->runlist.lock);
+				goto retry_remap;
+			}
+		}
+		err = ntfs_map_runlist_nolock(ni, vcn);
+		if (!write_locked) {
+			up_write(&ni->runlist.lock);
+			down_read(&ni->runlist.lock);
+		}
 		if (likely(!err)) {
 			is_retry = TRUE;
-			goto lock_retry_remap;
+			goto retry_remap;
 		}
 		/*
-		 * -EINVAL and -ENOENT coming from a failed mapping attempt are
-		 * equivalent to i/o errors for us as they should not happen in
-		 * our code paths.
+		 * -EINVAL coming from a failed mapping attempt is equivalent
+		 * to i/o error for us as it should not happen in our code
+		 * paths.
 		 */
-		if (err == -EINVAL || err == -ENOENT)
+		if (err == -EINVAL)
 			err = -EIO;
 	} else if (!err)
 		err = -EIO;
-	ntfs_error(ni->vol->sb, "Failed with error code %i.", err);
+	if (err != -ENOENT)
+		ntfs_error(ni->vol->sb, "Failed with error code %i.", err);
 	return ERR_PTR(err);
 }
 
@@ -870,15 +1005,14 @@ int ntfs_attr_lookup(const ATTR_TYPE typ
 static inline void ntfs_attr_init_search_ctx(ntfs_attr_search_ctx *ctx,
 		ntfs_inode *ni, MFT_RECORD *mrec)
 {
-	ctx->mrec = mrec;
-	/* Sanity checks are performed elsewhere. */
-	ctx->attr = (ATTR_RECORD*)((u8*)mrec + le16_to_cpu(mrec->attrs_offset));
-	ctx->is_first = TRUE;
-	ctx->ntfs_ino = ni;
-	ctx->al_entry = NULL;
-	ctx->base_ntfs_ino = NULL;
-	ctx->base_mrec = NULL;
-	ctx->base_attr = NULL;
+	*ctx = (ntfs_attr_search_ctx) {
+		.mrec = mrec,
+		/* Sanity checks are performed elsewhere. */
+		.attr = (ATTR_RECORD*)((u8*)mrec +
+				le16_to_cpu(mrec->attrs_offset)),
+		.is_first = TRUE,
+		.ntfs_ino = ni,
+	};
 }
 
 /**
@@ -945,6 +1079,8 @@ void ntfs_attr_put_search_ctx(ntfs_attr_
 	return;
 }
 
+#ifdef NTFS_RW
+
 /**
  * ntfs_attr_find_in_attrdef - find an attribute in the $AttrDef system file
  * @vol:	ntfs volume to which the attribute belongs
@@ -1024,27 +1160,21 @@ int ntfs_attr_size_bounds_check(const nt
  * Check whether the attribute of @type on the ntfs volume @vol is allowed to
  * be non-resident.  This information is obtained from $AttrDef system file.
  *
- * Return 0 if the attribute is allowed to be non-resident, -EPERM if not, or
+ * Return 0 if the attribute is allowed to be non-resident, -EPERM if not, and
  * -ENOENT if the attribute is not listed in $AttrDef.
  */
 int ntfs_attr_can_be_non_resident(const ntfs_volume *vol, const ATTR_TYPE type)
 {
 	ATTR_DEF *ad;
 
-	/*
-	 * $DATA is always allowed to be non-resident even if $AttrDef does not
-	 * specify this in the flags of the $DATA attribute definition record.
-	 */
-	if (type == AT_DATA)
-		return 0;
 	/* Find the attribute definition record in $AttrDef. */
 	ad = ntfs_attr_find_in_attrdef(vol, type);
 	if (unlikely(!ad))
 		return -ENOENT;
 	/* Check the flags and return the result. */
-	if (ad->flags & CAN_BE_NON_RESIDENT)
-		return 0;
-	return -EPERM;
+	if (ad->flags & ATTR_DEF_RESIDENT)
+		return -EPERM;
+	return 0;
 }
 
 /**
@@ -1067,9 +1197,9 @@ int ntfs_attr_can_be_non_resident(const 
  */
 int ntfs_attr_can_be_resident(const ntfs_volume *vol, const ATTR_TYPE type)
 {
-	if (type != AT_INDEX_ALLOCATION && type != AT_EA)
-		return 0;
-	return -EPERM;
+	if (type == AT_INDEX_ALLOCATION || type == AT_EA)
+		return -EPERM;
+	return 0;
 }
 
 /**
@@ -1117,6 +1247,328 @@ int ntfs_attr_record_resize(MFT_RECORD *
 }
 
 /**
+ * ntfs_attr_make_non_resident - convert a resident to a non-resident attribute
+ * @ni:		ntfs inode describing the attribute to convert
+ *
+ * Convert the resident ntfs attribute described by the ntfs inode @ni to a
+ * non-resident one.
+ *
+ * Return 0 on success and -errno on error.  The following error return codes
+ * are defined:
+ *	-EPERM	- The attribute is not allowed to be non-resident.
+ *	-ENOMEM	- Not enough memory.
+ *	-ENOSPC	- Not enough disk space.
+ *	-EINVAL	- Attribute not defined on the volume.
+ *	-EIO	- I/o error or other error.
+ * Note that -ENOSPC is also returned in the case that there is not enough
+ * space in the mft record to do the conversion.  This can happen when the mft
+ * record is already very full.  The caller is responsible for trying to make
+ * space in the mft record and trying again.  FIXME: Do we need a separate
+ * error return code for this kind of -ENOSPC or is it always worth trying
+ * again in case the attribute may then fit in a resident state so no need to
+ * make it non-resident at all?  Ho-hum...  (AIA)
+ *
+ * NOTE to self: No changes in the attribute list are required to move from
+ *		 a resident to a non-resident attribute.
+ *
+ * Locking: - The caller must hold i_sem on the inode.
+ */
+int ntfs_attr_make_non_resident(ntfs_inode *ni)
+{
+	s64 new_size;
+	struct inode *vi = VFS_I(ni);
+	ntfs_volume *vol = ni->vol;
+	ntfs_inode *base_ni;
+	MFT_RECORD *m;
+	ATTR_RECORD *a;
+	ntfs_attr_search_ctx *ctx;
+	struct page *page;
+	runlist_element *rl;
+	u8 *kaddr;
+	unsigned long flags;
+	int mp_size, mp_ofs, name_ofs, arec_size, err, err2;
+	u32 attr_size;
+	u8 old_res_attr_flags;
+
+	/* Check that the attribute is allowed to be non-resident. */
+	err = ntfs_attr_can_be_non_resident(vol, ni->type);
+	if (unlikely(err)) {
+		if (err == -EPERM)
+			ntfs_debug("Attribute is not allowed to be "
+					"non-resident.");
+		else
+			ntfs_debug("Attribute not defined on the NTFS "
+					"volume!");
+		return err;
+	}
+	/*
+	 * The size needs to be aligned to a cluster boundary for allocation
+	 * purposes.
+	 */
+	new_size = (i_size_read(vi) + vol->cluster_size - 1) &
+			~(vol->cluster_size - 1);
+	if (new_size > 0) {
+		runlist_element *rl2;
+
+		/*
+		 * Will need the page later and since the page lock nests
+		 * outside all ntfs locks, we need to get the page now.
+		 */
+		page = find_or_create_page(vi->i_mapping, 0,
+				mapping_gfp_mask(vi->i_mapping));
+		if (unlikely(!page))
+			return -ENOMEM;
+		/* Start by allocating clusters to hold the attribute value. */
+		rl = ntfs_cluster_alloc(vol, 0, new_size >>
+				vol->cluster_size_bits, -1, DATA_ZONE);
+		if (IS_ERR(rl)) {
+			err = PTR_ERR(rl);
+			ntfs_debug("Failed to allocate cluster%s, error code "
+					"%i.", (new_size >>
+					vol->cluster_size_bits) > 1 ? "s" : "",
+					err);
+			goto page_err_out;
+		}
+		/* Change the runlist terminator to LCN_ENOENT. */
+		rl2 = rl;
+		while (rl2->length)
+			rl2++;
+		BUG_ON(rl2->lcn != LCN_RL_NOT_MAPPED);
+		rl2->lcn = LCN_ENOENT;
+	} else {
+		rl = NULL;
+		page = NULL;
+	}
+	/* Determine the size of the mapping pairs array. */
+	mp_size = ntfs_get_size_for_mapping_pairs(vol, rl, 0, -1);
+	if (unlikely(mp_size < 0)) {
+		err = mp_size;
+		ntfs_debug("Failed to get size for mapping pairs array, error "
+				"code %i.", err);
+		goto rl_err_out;
+	}
+	down_write(&ni->runlist.lock);
+	if (!NInoAttr(ni))
+		base_ni = ni;
+	else
+		base_ni = ni->ext.base_ntfs_ino;
+	m = map_mft_record(base_ni);
+	if (IS_ERR(m)) {
+		err = PTR_ERR(m);
+		m = NULL;
+		ctx = NULL;
+		goto err_out;
+	}
+	ctx = ntfs_attr_get_search_ctx(base_ni, m);
+	if (unlikely(!ctx)) {
+		err = -ENOMEM;
+		goto err_out;
+	}
+	err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len,
+			CASE_SENSITIVE, 0, NULL, 0, ctx);
+	if (unlikely(err)) {
+		if (err == -ENOENT)
+			err = -EIO;
+		goto err_out;
+	}
+	m = ctx->mrec;
+	a = ctx->attr;
+	BUG_ON(NInoNonResident(ni));
+	BUG_ON(a->non_resident);
+	/*
+	 * Calculate new offsets for the name and the mapping pairs array.
+	 * We assume the attribute is not compressed or sparse.
+	 */
+	name_ofs = (offsetof(ATTR_REC,
+			data.non_resident.compressed_size) + 7) & ~7;
+	mp_ofs = (name_ofs + a->name_length * sizeof(ntfschar) + 7) & ~7;
+	/*
+	 * Determine the size of the resident part of the now non-resident
+	 * attribute record.
+	 */
+	arec_size = (mp_ofs + mp_size + 7) & ~7;
+	/*
+	 * If the page is not uptodate bring it uptodate by copying from the
+	 * attribute value.
+	 */
+	attr_size = le32_to_cpu(a->data.resident.value_length);
+	BUG_ON(attr_size != i_size_read(vi));
+	if (page && !PageUptodate(page)) {
+		kaddr = kmap_atomic(page, KM_USER0);
+		memcpy(kaddr, (u8*)a +
+				le16_to_cpu(a->data.resident.value_offset),
+				attr_size);
+		memset(kaddr + attr_size, 0, PAGE_CACHE_SIZE - attr_size);
+		kunmap_atomic(kaddr, KM_USER0);
+		flush_dcache_page(page);
+		SetPageUptodate(page);
+	}
+	/* Backup the attribute flag. */
+	old_res_attr_flags = a->data.resident.flags;
+	/* Resize the resident part of the attribute record. */
+	err = ntfs_attr_record_resize(m, a, arec_size);
+	if (unlikely(err))
+		goto err_out;
+	/*
+	 * Convert the resident part of the attribute record to describe a
+	 * non-resident attribute.
+	 */
+	a->non_resident = 1;
+	/* Move the attribute name if it exists and update the offset. */
+	if (a->name_length)
+		memmove((u8*)a + name_ofs, (u8*)a + le16_to_cpu(a->name_offset),
+				a->name_length * sizeof(ntfschar));
+	a->name_offset = cpu_to_le16(name_ofs);
+	/*
+	 * FIXME: For now just clear all of these as we do not support them
+	 * when writing.
+	 */
+	a->flags &= cpu_to_le16(0xffff & ~le16_to_cpu(ATTR_IS_SPARSE |
+			ATTR_IS_ENCRYPTED | ATTR_COMPRESSION_MASK));
+	/* Setup the fields specific to non-resident attributes. */
+	a->data.non_resident.lowest_vcn = 0;
+	a->data.non_resident.highest_vcn = cpu_to_sle64((new_size - 1) >>
+			vol->cluster_size_bits);
+	a->data.non_resident.mapping_pairs_offset = cpu_to_le16(mp_ofs);
+	a->data.non_resident.compression_unit = 0;
+	memset(&a->data.non_resident.reserved, 0,
+			sizeof(a->data.non_resident.reserved));
+	a->data.non_resident.allocated_size = cpu_to_sle64(new_size);
+	a->data.non_resident.data_size =
+			a->data.non_resident.initialized_size =
+			cpu_to_sle64(attr_size);
+	/* Generate the mapping pairs array into the attribute record. */
+	err = ntfs_mapping_pairs_build(vol, (u8*)a + mp_ofs,
+			arec_size - mp_ofs, rl, 0, -1, NULL);
+	if (unlikely(err)) {
+		ntfs_debug("Failed to build mapping pairs, error code %i.",
+				err);
+		goto undo_err_out;
+	}
+	/* Setup the in-memory attribute structure to be non-resident. */
+	/*
+	 * FIXME: For now just clear all of these as we do not support them
+	 * when writing.
+	 */
+	NInoClearSparse(ni);
+	NInoClearEncrypted(ni);
+	NInoClearCompressed(ni);
+	ni->runlist.rl = rl;
+	write_lock_irqsave(&ni->size_lock, flags);
+	ni->allocated_size = new_size;
+	write_unlock_irqrestore(&ni->size_lock, flags);
+	/*
+	 * This needs to be last since the address space operations ->readpage
+	 * and ->writepage can run concurrently with us as they are not
+	 * serialized on i_sem.  Note, we are not allowed to fail once we flip
+	 * this switch, which is another reason to do this last.
+	 */
+	NInoSetNonResident(ni);
+	/* Mark the mft record dirty, so it gets written back. */
+	flush_dcache_mft_record_page(ctx->ntfs_ino);
+	mark_mft_record_dirty(ctx->ntfs_ino);
+	ntfs_attr_put_search_ctx(ctx);
+	unmap_mft_record(base_ni);
+	up_write(&ni->runlist.lock);
+	if (page) {
+		set_page_dirty(page);
+		unlock_page(page);
+		mark_page_accessed(page);
+		page_cache_release(page);
+	}
+	ntfs_debug("Done.");
+	return 0;
+undo_err_out:
+	/* Convert the attribute back into a resident attribute. */
+	a->non_resident = 0;
+	/* Move the attribute name if it exists and update the offset. */
+	name_ofs = (offsetof(ATTR_RECORD, data.resident.reserved) +
+			sizeof(a->data.resident.reserved) + 7) & ~7;
+	if (a->name_length)
+		memmove((u8*)a + name_ofs, (u8*)a + le16_to_cpu(a->name_offset),
+				a->name_length * sizeof(ntfschar));
+	mp_ofs = (name_ofs + a->name_length * sizeof(ntfschar) + 7) & ~7;
+	a->name_offset = cpu_to_le16(name_ofs);
+	arec_size = (mp_ofs + attr_size + 7) & ~7;
+	/* Resize the resident part of the attribute record. */
+	err2 = ntfs_attr_record_resize(m, a, arec_size);
+	if (unlikely(err2)) {
+		/*
+		 * This cannot happen (well if memory corruption is at work it
+		 * could happen in theory), but deal with it as well as we can.
+		 * If the old size is too small, truncate the attribute,
+		 * otherwise simply give it a larger allocated size.
+		 * FIXME: Should check whether chkdsk complains when the
+		 * allocated size is much bigger than the resident value size.
+		 */
+		arec_size = le32_to_cpu(a->length);
+		if ((mp_ofs + attr_size) > arec_size) {
+			err2 = attr_size;
+			attr_size = arec_size - mp_ofs;
+			ntfs_error(vol->sb, "Failed to undo partial resident "
+					"to non-resident attribute "
+					"conversion.  Truncating inode 0x%lx, "
+					"attribute type 0x%x from %i bytes to "
+					"%i bytes to maintain metadata "
+					"consistency.  THIS MEANS YOU ARE "
+					"LOSING %i BYTES DATA FROM THIS %s.",
+					vi->i_ino,
+					(unsigned)le32_to_cpu(ni->type),
+					err2, attr_size, err2 - attr_size,
+					((ni->type == AT_DATA) &&
+					!ni->name_len) ? "FILE": "ATTRIBUTE");
+			write_lock_irqsave(&ni->size_lock, flags);
+			ni->initialized_size = attr_size;
+			i_size_write(vi, attr_size);
+			write_unlock_irqrestore(&ni->size_lock, flags);
+		}
+	}
+	/* Setup the fields specific to resident attributes. */
+	a->data.resident.value_length = cpu_to_le32(attr_size);
+	a->data.resident.value_offset = cpu_to_le16(mp_ofs);
+	a->data.resident.flags = old_res_attr_flags;
+	memset(&a->data.resident.reserved, 0,
+			sizeof(a->data.resident.reserved));
+	/* Copy the data from the page back to the attribute value. */
+	if (page) {
+		kaddr = kmap_atomic(page, KM_USER0);
+		memcpy((u8*)a + mp_ofs, kaddr, attr_size);
+		kunmap_atomic(kaddr, KM_USER0);
+	}
+	/* Setup the allocated size in the ntfs inode in case it changed. */
+	write_lock_irqsave(&ni->size_lock, flags);
+	ni->allocated_size = arec_size - mp_ofs;
+	write_unlock_irqrestore(&ni->size_lock, flags);
+	/* Mark the mft record dirty, so it gets written back. */
+	flush_dcache_mft_record_page(ctx->ntfs_ino);
+	mark_mft_record_dirty(ctx->ntfs_ino);
+err_out:
+	if (ctx)
+		ntfs_attr_put_search_ctx(ctx);
+	if (m)
+		unmap_mft_record(base_ni);
+	ni->runlist.rl = NULL;
+	up_write(&ni->runlist.lock);
+rl_err_out:
+	if (rl) {
+		if (ntfs_cluster_free_from_rl(vol, rl) < 0) {
+			ntfs_error(vol->sb, "Failed to release allocated "
+					"cluster(s) in error code path.  Run "
+					"chkdsk to recover the lost "
+					"cluster(s).");
+			NVolSetErrors(vol);
+		}
+		ntfs_free(rl);
+page_err_out:
+		unlock_page(page);
+		page_cache_release(page);
+	}
+	if (err == -EINVAL)
+		err = -EIO;
+	return err;
+}
+
+/**
  * ntfs_attr_set - fill (a part of) an attribute with a byte
  * @ni:		ntfs inode describing the attribute to fill
  * @ofs:	offset inside the attribute at which to start to fill
@@ -1127,6 +1579,10 @@ int ntfs_attr_record_resize(MFT_RECORD *
  * byte offset @ofs inside the attribute with the constant byte @val.
  *
  * This function is effectively like memset() applied to an ntfs attribute.
+ * Note thie function actually only operates on the page cache pages belonging
+ * to the ntfs attribute and it marks them dirty after doing the memset().
+ * Thus it relies on the vm dirty page write code paths to cause the modified
+ * pages to be written to the mft record/disk.
  *
  * Return 0 on success and -errno on error.  An error code of -ESPIPE means
  * that @ofs + @cnt were outside the end of the attribute and no write was
@@ -1155,7 +1611,7 @@ int ntfs_attr_set(ntfs_inode *ni, const 
 	end = ofs + cnt;
 	end_ofs = end & ~PAGE_CACHE_MASK;
 	/* If the end is outside the inode size return -ESPIPE. */
-	if (unlikely(end > VFS_I(ni)->i_size)) {
+	if (unlikely(end > i_size_read(VFS_I(ni)))) {
 		ntfs_error(vol->sb, "Request exceeds end of attribute.");
 		return -ESPIPE;
 	}
@@ -1256,3 +1712,5 @@ done:
 	ntfs_debug("Done.");
 	return 0;
 }
+
+#endif /* NTFS_RW */
diff --git a/fs/ntfs/attrib.h b/fs/ntfs/attrib.h
--- a/fs/ntfs/attrib.h
+++ b/fs/ntfs/attrib.h
@@ -2,7 +2,7 @@
  * attrib.h - Defines for attribute handling in NTFS Linux kernel driver.
  *	      Part of the Linux-NTFS project.
  *
- * Copyright (c) 2001-2004 Anton Altaparmakov
+ * Copyright (c) 2001-2005 Anton Altaparmakov
  * Copyright (c) 2002 Richard Russon
  *
  * This program/include file is free software; you can redistribute it and/or
@@ -60,10 +60,14 @@ typedef struct {
 	ATTR_RECORD *base_attr;
 } ntfs_attr_search_ctx;
 
+extern int ntfs_map_runlist_nolock(ntfs_inode *ni, VCN vcn);
 extern int ntfs_map_runlist(ntfs_inode *ni, VCN vcn);
 
-extern runlist_element *ntfs_find_vcn(ntfs_inode *ni, const VCN vcn,
-		const BOOL need_write);
+extern LCN ntfs_attr_vcn_to_lcn_nolock(ntfs_inode *ni, const VCN vcn,
+		const BOOL write_locked);
+
+extern runlist_element *ntfs_attr_find_vcn_nolock(ntfs_inode *ni,
+		const VCN vcn, const BOOL write_locked);
 
 int ntfs_attr_lookup(const ATTR_TYPE type, const ntfschar *name,
 		const u32 name_len, const IGNORE_CASE_BOOL ic,
@@ -85,6 +89,8 @@ extern ntfs_attr_search_ctx *ntfs_attr_g
 		MFT_RECORD *mrec);
 extern void ntfs_attr_put_search_ctx(ntfs_attr_search_ctx *ctx);
 
+#ifdef NTFS_RW
+
 extern int ntfs_attr_size_bounds_check(const ntfs_volume *vol,
 		const ATTR_TYPE type, const s64 size);
 extern int ntfs_attr_can_be_non_resident(const ntfs_volume *vol,
@@ -94,7 +100,11 @@ extern int ntfs_attr_can_be_resident(con
 
 extern int ntfs_attr_record_resize(MFT_RECORD *m, ATTR_RECORD *a, u32 new_size);
 
+extern int ntfs_attr_make_non_resident(ntfs_inode *ni);
+
 extern int ntfs_attr_set(ntfs_inode *ni, const s64 ofs, const s64 cnt,
 		const u8 val);
 
+#endif /* NTFS_RW */
+
 #endif /* _LINUX_NTFS_ATTRIB_H */
diff --git a/fs/ntfs/compress.c b/fs/ntfs/compress.c
--- a/fs/ntfs/compress.c
+++ b/fs/ntfs/compress.c
@@ -96,13 +96,14 @@ void free_compression_buffers(void)
 /**
  * zero_partial_compressed_page - zero out of bounds compressed page region
  */
-static void zero_partial_compressed_page(ntfs_inode *ni, struct page *page)
+static void zero_partial_compressed_page(struct page *page,
+		const s64 initialized_size)
 {
 	u8 *kp = page_address(page);
 	unsigned int kp_ofs;
 
 	ntfs_debug("Zeroing page region outside initialized size.");
-	if (((s64)page->index << PAGE_CACHE_SHIFT) >= ni->initialized_size) {
+	if (((s64)page->index << PAGE_CACHE_SHIFT) >= initialized_size) {
 		/*
 		 * FIXME: Using clear_page() will become wrong when we get
 		 * PAGE_CACHE_SIZE != PAGE_SIZE but for now there is no problem.
@@ -110,7 +111,7 @@ static void zero_partial_compressed_page
 		clear_page(kp);
 		return;
 	}
-	kp_ofs = ni->initialized_size & ~PAGE_CACHE_MASK;
+	kp_ofs = initialized_size & ~PAGE_CACHE_MASK;
 	memset(kp + kp_ofs, 0, PAGE_CACHE_SIZE - kp_ofs);
 	return;
 }
@@ -118,12 +119,12 @@ static void zero_partial_compressed_page
 /**
  * handle_bounds_compressed_page - test for&handle out of bounds compressed page
  */
-static inline void handle_bounds_compressed_page(ntfs_inode *ni,
-		struct page *page)
+static inline void handle_bounds_compressed_page(struct page *page,
+		const loff_t i_size, const s64 initialized_size)
 {
-	if ((page->index >= (ni->initialized_size >> PAGE_CACHE_SHIFT)) &&
-			(ni->initialized_size < VFS_I(ni)->i_size))
-		zero_partial_compressed_page(ni, page);
+	if ((page->index >= (initialized_size >> PAGE_CACHE_SHIFT)) &&
+			(initialized_size < i_size))
+		zero_partial_compressed_page(page, initialized_size);
 	return;
 }
 
@@ -138,6 +139,8 @@ static inline void handle_bounds_compres
  * @xpage_done:		set to 1 if xpage was completed successfully (IN/OUT)
  * @cb_start:		compression block to decompress (IN)
  * @cb_size:		size of compression block @cb_start in bytes (IN)
+ * @i_size:		file size when we started the read (IN)
+ * @initialized_size:	initialized file size when we started the read (IN)
  *
  * The caller must have disabled preemption. ntfs_decompress() reenables it when
  * the critical section is finished.
@@ -165,7 +168,8 @@ static inline void handle_bounds_compres
 static int ntfs_decompress(struct page *dest_pages[], int *dest_index,
 		int *dest_ofs, const int dest_max_index, const int dest_max_ofs,
 		const int xpage, char *xpage_done, u8 *const cb_start,
-		const u32 cb_size)
+		const u32 cb_size, const loff_t i_size,
+		const s64 initialized_size)
 {
 	/*
 	 * Pointers into the compressed data, i.e. the compression block (cb),
@@ -219,9 +223,6 @@ return_error:
 		spin_unlock(&ntfs_cb_lock);
 		/* Second stage: finalize completed pages. */
 		if (nr_completed_pages > 0) {
-			struct page *page = dest_pages[completed_pages[0]];
-			ntfs_inode *ni = NTFS_I(page->mapping->host);
-
 			for (i = 0; i < nr_completed_pages; i++) {
 				int di = completed_pages[i];
 
@@ -230,7 +231,8 @@ return_error:
 				 * If we are outside the initialized size, zero
 				 * the out of bounds page range.
 				 */
-				handle_bounds_compressed_page(ni, dp);
+				handle_bounds_compressed_page(dp, i_size,
+						initialized_size);
 				flush_dcache_page(dp);
 				kunmap(dp);
 				SetPageUptodate(dp);
@@ -478,12 +480,14 @@ return_overflow:
  */
 int ntfs_read_compressed_block(struct page *page)
 {
+	loff_t i_size;
+	s64 initialized_size;
 	struct address_space *mapping = page->mapping;
 	ntfs_inode *ni = NTFS_I(mapping->host);
 	ntfs_volume *vol = ni->vol;
 	struct super_block *sb = vol->sb;
 	runlist_element *rl;
-	unsigned long block_size = sb->s_blocksize;
+	unsigned long flags, block_size = sb->s_blocksize;
 	unsigned char block_size_bits = sb->s_blocksize_bits;
 	u8 *cb, *cb_pos, *cb_end;
 	struct buffer_head **bhs;
@@ -552,8 +556,12 @@ int ntfs_read_compressed_block(struct pa
 	 * The remaining pages need to be allocated and inserted into the page
 	 * cache, alignment guarantees keep all the below much simpler. (-8
 	 */
-	max_page = ((VFS_I(ni)->i_size + PAGE_CACHE_SIZE - 1) >>
-			PAGE_CACHE_SHIFT) - offset;
+	read_lock_irqsave(&ni->size_lock, flags);
+	i_size = i_size_read(VFS_I(ni));
+	initialized_size = ni->initialized_size;
+	read_unlock_irqrestore(&ni->size_lock, flags);
+	max_page = ((i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT) -
+			offset;
 	if (nr_pages < max_page)
 		max_page = nr_pages;
 	for (i = 0; i < max_page; i++, offset++) {
@@ -824,7 +832,8 @@ lock_retry_remap:
 				 * If we are outside the initialized size, zero
 				 * the out of bounds page range.
 				 */
-				handle_bounds_compressed_page(ni, page);
+				handle_bounds_compressed_page(page, i_size,
+						initialized_size);
 				flush_dcache_page(page);
 				kunmap(page);
 				SetPageUptodate(page);
@@ -847,7 +856,8 @@ lock_retry_remap:
 		ntfs_debug("Found compressed compression block.");
 		err = ntfs_decompress(pages, &cur_page, &cur_ofs,
 				cb_max_page, cb_max_ofs, xpage, &xpage_done,
-				cb_pos,	cb_size - (cb_pos - cb));
+				cb_pos,	cb_size - (cb_pos - cb), i_size,
+				initialized_size);
 		/*
 		 * We can sleep from now on, lock already dropped by
 		 * ntfs_decompress().
diff --git a/fs/ntfs/debug.c b/fs/ntfs/debug.c
--- a/fs/ntfs/debug.c
+++ b/fs/ntfs/debug.c
@@ -164,14 +164,17 @@ void ntfs_debug_dump_runlist(const runli
 			if (index > -LCN_ENOENT - 1)
 				index = 3;
 			printk(KERN_DEBUG "%-16Lx %s %-16Lx%s\n",
-					(rl + i)->vcn, lcn_str[index],
-					(rl + i)->length, (rl + i)->length ?
-					"" : " (runlist end)");
+					(long long)(rl + i)->vcn, lcn_str[index],
+					(long long)(rl + i)->length,
+					(rl + i)->length ? "" :
+						" (runlist end)");
 		} else
 			printk(KERN_DEBUG "%-16Lx %-16Lx  %-16Lx%s\n",
-					(rl + i)->vcn, (rl + i)->lcn,
-					(rl + i)->length, (rl + i)->length ?
-					"" : " (runlist end)");
+					(long long)(rl + i)->vcn,
+					(long long)(rl + i)->lcn,
+					(long long)(rl + i)->length,
+					(rl + i)->length ? "" :
+						" (runlist end)");
 		if (!(rl + i)->length)
 			break;
 	}
diff --git a/fs/ntfs/dir.c b/fs/ntfs/dir.c
--- a/fs/ntfs/dir.c
+++ b/fs/ntfs/dir.c
@@ -1,7 +1,7 @@
 /**
  * dir.c - NTFS kernel directory operations. Part of the Linux-NTFS project.
  *
- * Copyright (c) 2001-2004 Anton Altaparmakov
+ * Copyright (c) 2001-2005 Anton Altaparmakov
  * Copyright (c) 2002 Richard Russon
  *
  * This program/include file is free software; you can redistribute it and/or
@@ -183,8 +183,7 @@ found_it:
 				name->len = 0;
 				*res = name;
 			} else {
-				if (name)
-					kfree(name);
+				kfree(name);
 				*res = NULL;
 			}
 			mref = le64_to_cpu(ie->data.dir.indexed_file);
@@ -444,8 +443,7 @@ found_it2:
 				name->len = 0;
 				*res = name;
 			} else {
-				if (name)
-					kfree(name);
+				kfree(name);
 				*res = NULL;
 			}
 			mref = le64_to_cpu(ie->data.dir.indexed_file);
@@ -610,7 +608,7 @@ dir_err_out:
 // TODO: (AIA)
 // The algorithm embedded in this code will be required for the time when we
 // want to support adding of entries to directories, where we require correct
-// collation of file names in order not to cause corruption of the file system.
+// collation of file names in order not to cause corruption of the filesystem.
 
 /**
  * ntfs_lookup_inode_by_name - find an inode in a directory given its name
@@ -1101,7 +1099,7 @@ static inline int ntfs_filldir(ntfs_volu
 static int ntfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
 {
 	s64 ia_pos, ia_start, prev_ia_pos, bmp_pos;
-	loff_t fpos;
+	loff_t fpos, i_size;
 	struct inode *bmp_vi, *vdir = filp->f_dentry->d_inode;
 	struct super_block *sb = vdir->i_sb;
 	ntfs_inode *ndir = NTFS_I(vdir);
@@ -1122,7 +1120,8 @@ static int ntfs_readdir(struct file *fil
 			vdir->i_ino, fpos);
 	rc = err = 0;
 	/* Are we at end of dir yet? */
-	if (fpos >= vdir->i_size + vol->mft_record_size)
+	i_size = i_size_read(vdir);
+	if (fpos >= i_size + vol->mft_record_size)
 		goto done;
 	/* Emulate . and .. for all directories. */
 	if (!fpos) {
@@ -1264,7 +1263,7 @@ skip_index_root:
 	bmp_mapping = bmp_vi->i_mapping;
 	/* Get the starting bitmap bit position and sanity check it. */
 	bmp_pos = ia_pos >> ndir->itype.index.block_size_bits;
-	if (unlikely(bmp_pos >> 3 >= bmp_vi->i_size)) {
+	if (unlikely(bmp_pos >> 3 >= i_size_read(bmp_vi))) {
 		ntfs_error(sb, "Current index allocation position exceeds "
 				"index bitmap size.");
 		goto err_out;
@@ -1301,7 +1300,7 @@ find_next_index_buffer:
 			goto get_next_bmp_page;
 		}
 		/* If we have reached the end of the bitmap, we are done. */
-		if (unlikely(((bmp_pos + cur_bmp_pos) >> 3) >= vdir->i_size))
+		if (unlikely(((bmp_pos + cur_bmp_pos) >> 3) >= i_size))
 			goto unm_EOD;
 		ia_pos = (bmp_pos + cur_bmp_pos) <<
 				ndir->itype.index.block_size_bits;
@@ -1309,7 +1308,8 @@ find_next_index_buffer:
 	ntfs_debug("Handling index buffer 0x%llx.",
 			(unsigned long long)bmp_pos + cur_bmp_pos);
 	/* If the current index buffer is in the same page we reuse the page. */
-	if ((prev_ia_pos & PAGE_CACHE_MASK) != (ia_pos & PAGE_CACHE_MASK)) {
+	if ((prev_ia_pos & (s64)PAGE_CACHE_MASK) !=
+			(ia_pos & (s64)PAGE_CACHE_MASK)) {
 		prev_ia_pos = ia_pos;
 		if (likely(ia_page != NULL)) {
 			unlock_page(ia_page);
@@ -1441,7 +1441,7 @@ unm_EOD:
 	ntfs_unmap_page(bmp_page);
 EOD:
 	/* We are finished, set fpos to EOD. */
-	fpos = vdir->i_size + vol->mft_record_size;
+	fpos = i_size + vol->mft_record_size;
 abort:
 	kfree(name);
 done:
@@ -1461,10 +1461,8 @@ err_out:
 		unlock_page(ia_page);
 		ntfs_unmap_page(ia_page);
 	}
-	if (ir)
-		kfree(ir);
-	if (name)
-		kfree(name);
+	kfree(ir);
+	kfree(name);
 	if (ctx)
 		ntfs_attr_put_search_ctx(ctx);
 	if (m)
@@ -1495,7 +1493,7 @@ err_out:
 static int ntfs_dir_open(struct inode *vi, struct file *filp)
 {
 	if (sizeof(unsigned long) < 8) {
-		if (vi->i_size > MAX_LFS_FILESIZE)
+		if (i_size_read(vi) > MAX_LFS_FILESIZE)
 			return -EFBIG;
 	}
 	return 0;
diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c
--- a/fs/ntfs/file.c
+++ b/fs/ntfs/file.c
@@ -47,7 +47,7 @@
 static int ntfs_file_open(struct inode *vi, struct file *filp)
 {
 	if (sizeof(unsigned long) < 8) {
-		if (vi->i_size > MAX_LFS_FILESIZE)
+		if (i_size_read(vi) > MAX_LFS_FILESIZE)
 			return -EFBIG;
 	}
 	return generic_file_open(vi, filp);
diff --git a/fs/ntfs/index.c b/fs/ntfs/index.c
--- a/fs/ntfs/index.c
+++ b/fs/ntfs/index.c
@@ -1,7 +1,7 @@
 /*
  * index.c - NTFS kernel index handling.  Part of the Linux-NTFS project.
  *
- * Copyright (c) 2004 Anton Altaparmakov
+ * Copyright (c) 2004-2005 Anton Altaparmakov
  *
  * This program/include file is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as published
@@ -39,18 +39,8 @@ ntfs_index_context *ntfs_index_ctx_get(n
 	ntfs_index_context *ictx;
 
 	ictx = kmem_cache_alloc(ntfs_index_ctx_cache, SLAB_NOFS);
-	if (ictx) {
-		ictx->idx_ni = idx_ni;
-		ictx->entry = NULL;
-		ictx->data = NULL;
-		ictx->data_len = 0;
-		ictx->is_in_root = 0;
-		ictx->ir = NULL;
-		ictx->actx = NULL;
-		ictx->base_ni = NULL;
-		ictx->ia = NULL;
-		ictx->page = NULL;
-	}
+	if (ictx)
+		*ictx = (ntfs_index_context){ .idx_ni = idx_ni };
 	return ictx;
 }
 
diff --git a/fs/ntfs/inode.c b/fs/ntfs/inode.c
--- a/fs/ntfs/inode.c
+++ b/fs/ntfs/inode.c
@@ -1,7 +1,7 @@
 /**
  * inode.c - NTFS kernel inode handling. Part of the Linux-NTFS project.
  *
- * Copyright (c) 2001-2004 Anton Altaparmakov
+ * Copyright (c) 2001-2005 Anton Altaparmakov
  *
  * This program/include file is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as published
@@ -174,7 +174,7 @@ struct inode *ntfs_iget(struct super_blo
 
 	vi = iget5_locked(sb, mft_no, (test_t)ntfs_test_inode,
 			(set_t)ntfs_init_locked_inode, &na);
-	if (!vi)
+	if (unlikely(!vi))
 		return ERR_PTR(-ENOMEM);
 
 	err = 0;
@@ -188,7 +188,7 @@ struct inode *ntfs_iget(struct super_blo
 	 * There is no point in keeping bad inodes around if the failure was
 	 * due to ENOMEM. We want to be able to retry again later.
 	 */
-	if (err == -ENOMEM) {
+	if (unlikely(err == -ENOMEM)) {
 		iput(vi);
 		vi = ERR_PTR(err);
 	}
@@ -235,7 +235,7 @@ struct inode *ntfs_attr_iget(struct inod
 
 	vi = iget5_locked(base_vi->i_sb, na.mft_no, (test_t)ntfs_test_inode,
 			(set_t)ntfs_init_locked_inode, &na);
-	if (!vi)
+	if (unlikely(!vi))
 		return ERR_PTR(-ENOMEM);
 
 	err = 0;
@@ -250,7 +250,7 @@ struct inode *ntfs_attr_iget(struct inod
 	 * simplifies things in that we never need to check for bad attribute
 	 * inodes elsewhere.
 	 */
-	if (err) {
+	if (unlikely(err)) {
 		iput(vi);
 		vi = ERR_PTR(err);
 	}
@@ -290,7 +290,7 @@ struct inode *ntfs_index_iget(struct ino
 
 	vi = iget5_locked(base_vi->i_sb, na.mft_no, (test_t)ntfs_test_inode,
 			(set_t)ntfs_init_locked_inode, &na);
-	if (!vi)
+	if (unlikely(!vi))
 		return ERR_PTR(-ENOMEM);
 
 	err = 0;
@@ -305,7 +305,7 @@ struct inode *ntfs_index_iget(struct ino
 	 * simplifies things in that we never need to check for bad index
 	 * inodes elsewhere.
 	 */
-	if (err) {
+	if (unlikely(err)) {
 		iput(vi);
 		vi = ERR_PTR(err);
 	}
@@ -317,8 +317,7 @@ struct inode *ntfs_alloc_big_inode(struc
 	ntfs_inode *ni;
 
 	ntfs_debug("Entering.");
-	ni = (ntfs_inode *)kmem_cache_alloc(ntfs_big_inode_cache,
-			SLAB_NOFS);
+	ni = kmem_cache_alloc(ntfs_big_inode_cache, SLAB_NOFS);
 	if (likely(ni != NULL)) {
 		ni->state = 0;
 		return VFS_I(ni);
@@ -343,7 +342,7 @@ static inline ntfs_inode *ntfs_alloc_ext
 	ntfs_inode *ni;
 
 	ntfs_debug("Entering.");
-	ni = (ntfs_inode *)kmem_cache_alloc(ntfs_inode_cache, SLAB_NOFS);
+	ni = kmem_cache_alloc(ntfs_inode_cache, SLAB_NOFS);
 	if (likely(ni != NULL)) {
 		ni->state = 0;
 		return ni;
@@ -376,6 +375,7 @@ static void ntfs_destroy_extent_inode(nt
 void __ntfs_init_inode(struct super_block *sb, ntfs_inode *ni)
 {
 	ntfs_debug("Entering.");
+	rwlock_init(&ni->size_lock);
 	ni->initialized_size = ni->allocated_size = 0;
 	ni->seq_no = 0;
 	atomic_set(&ni->count, 1);
@@ -524,6 +524,7 @@ static int ntfs_read_locked_inode(struct
 	ntfs_volume *vol = NTFS_SB(vi->i_sb);
 	ntfs_inode *ni;
 	MFT_RECORD *m;
+	ATTR_RECORD *a;
 	STANDARD_INFORMATION *si;
 	ntfs_attr_search_ctx *ctx;
 	int err = 0;
@@ -632,9 +633,10 @@ static int ntfs_read_locked_inode(struct
 		}
 		goto unm_err_out;
 	}
+	a = ctx->attr;
 	/* Get the standard information attribute value. */
-	si = (STANDARD_INFORMATION*)((char*)ctx->attr +
-			le16_to_cpu(ctx->attr->data.resident.value_offset));
+	si = (STANDARD_INFORMATION*)((u8*)a +
+			le16_to_cpu(a->data.resident.value_offset));
 
 	/* Transfer information from the standard information into vi. */
 	/*
@@ -673,15 +675,16 @@ static int ntfs_read_locked_inode(struct
 			goto skip_attr_list_load;
 		ntfs_debug("Attribute list found in inode 0x%lx.", vi->i_ino);
 		NInoSetAttrList(ni);
-		if (ctx->attr->flags & ATTR_IS_ENCRYPTED ||
-				ctx->attr->flags & ATTR_COMPRESSION_MASK ||
-				ctx->attr->flags & ATTR_IS_SPARSE) {
+		a = ctx->attr;
+		if (a->flags & ATTR_IS_ENCRYPTED ||
+				a->flags & ATTR_COMPRESSION_MASK ||
+				a->flags & ATTR_IS_SPARSE) {
 			ntfs_error(vi->i_sb, "Attribute list attribute is "
 					"compressed/encrypted/sparse.");
 			goto unm_err_out;
 		}
 		/* Now allocate memory for the attribute list. */
-		ni->attr_list_size = (u32)ntfs_attr_size(ctx->attr);
+		ni->attr_list_size = (u32)ntfs_attr_size(a);
 		ni->attr_list = ntfs_malloc_nofs(ni->attr_list_size);
 		if (!ni->attr_list) {
 			ntfs_error(vi->i_sb, "Not enough memory to allocate "
@@ -689,9 +692,9 @@ static int ntfs_read_locked_inode(struct
 			err = -ENOMEM;
 			goto unm_err_out;
 		}
-		if (ctx->attr->non_resident) {
+		if (a->non_resident) {
 			NInoSetAttrListNonResident(ni);
-			if (ctx->attr->data.non_resident.lowest_vcn) {
+			if (a->data.non_resident.lowest_vcn) {
 				ntfs_error(vi->i_sb, "Attribute list has non "
 						"zero lowest_vcn.");
 				goto unm_err_out;
@@ -701,7 +704,7 @@ static int ntfs_read_locked_inode(struct
 			 * exclusive access to the inode at this time.
 			 */
 			ni->attr_list_rl.rl = ntfs_mapping_pairs_decompress(vol,
-					ctx->attr, NULL);
+					a, NULL);
 			if (IS_ERR(ni->attr_list_rl.rl)) {
 				err = PTR_ERR(ni->attr_list_rl.rl);
 				ni->attr_list_rl.rl = NULL;
@@ -712,27 +715,26 @@ static int ntfs_read_locked_inode(struct
 			/* Now load the attribute list. */
 			if ((err = load_attribute_list(vol, &ni->attr_list_rl,
 					ni->attr_list, ni->attr_list_size,
-					sle64_to_cpu(ctx->attr->data.
-					non_resident.initialized_size)))) {
+					sle64_to_cpu(a->data.non_resident.
+					initialized_size)))) {
 				ntfs_error(vi->i_sb, "Failed to load "
 						"attribute list attribute.");
 				goto unm_err_out;
 			}
-		} else /* if (!ctx.attr->non_resident) */ {
-			if ((u8*)ctx->attr + le16_to_cpu(
-					ctx->attr->data.resident.value_offset) +
-					le32_to_cpu(
-					ctx->attr->data.resident.value_length) >
+		} else /* if (!a->non_resident) */ {
+			if ((u8*)a + le16_to_cpu(a->data.resident.value_offset)
+					+ le32_to_cpu(
+					a->data.resident.value_length) >
 					(u8*)ctx->mrec + vol->mft_record_size) {
 				ntfs_error(vi->i_sb, "Corrupt attribute list "
 						"in inode.");
 				goto unm_err_out;
 			}
 			/* Now copy the attribute list. */
-			memcpy(ni->attr_list, (u8*)ctx->attr + le16_to_cpu(
-					ctx->attr->data.resident.value_offset),
+			memcpy(ni->attr_list, (u8*)a + le16_to_cpu(
+					a->data.resident.value_offset),
 					le32_to_cpu(
-					ctx->attr->data.resident.value_length));
+					a->data.resident.value_length));
 		}
 	}
 skip_attr_list_load:
@@ -741,10 +743,11 @@ skip_attr_list_load:
 	 * in ntfs_ino->attr_list and it is ntfs_ino->attr_list_size bytes.
 	 */
 	if (S_ISDIR(vi->i_mode)) {
+		loff_t bvi_size;
 		struct inode *bvi;
 		ntfs_inode *bni;
 		INDEX_ROOT *ir;
-		char *ir_end, *index_end;
+		u8 *ir_end, *index_end;
 
 		/* It is a directory, find index root attribute. */
 		ntfs_attr_reinit_search_ctx(ctx);
@@ -760,17 +763,16 @@ skip_attr_list_load:
 			}
 			goto unm_err_out;
 		}
+		a = ctx->attr;
 		/* Set up the state. */
-		if (unlikely(ctx->attr->non_resident)) {
+		if (unlikely(a->non_resident)) {
 			ntfs_error(vol->sb, "$INDEX_ROOT attribute is not "
 					"resident.");
 			goto unm_err_out;
 		}
 		/* Ensure the attribute name is placed before the value. */
-		if (unlikely(ctx->attr->name_length &&
-				(le16_to_cpu(ctx->attr->name_offset) >=
-				le16_to_cpu(ctx->attr->data.resident.
-				value_offset)))) {
+		if (unlikely(a->name_length && (le16_to_cpu(a->name_offset) >=
+				le16_to_cpu(a->data.resident.value_offset)))) {
 			ntfs_error(vol->sb, "$INDEX_ROOT attribute name is "
 					"placed after the attribute value.");
 			goto unm_err_out;
@@ -781,28 +783,27 @@ skip_attr_list_load:
 		 * encrypted. However index root cannot be both compressed and
 		 * encrypted.
 		 */
-		if (ctx->attr->flags & ATTR_COMPRESSION_MASK)
+		if (a->flags & ATTR_COMPRESSION_MASK)
 			NInoSetCompressed(ni);
-		if (ctx->attr->flags & ATTR_IS_ENCRYPTED) {
-			if (ctx->attr->flags & ATTR_COMPRESSION_MASK) {
+		if (a->flags & ATTR_IS_ENCRYPTED) {
+			if (a->flags & ATTR_COMPRESSION_MASK) {
 				ntfs_error(vi->i_sb, "Found encrypted and "
 						"compressed attribute.");
 				goto unm_err_out;
 			}
 			NInoSetEncrypted(ni);
 		}
-		if (ctx->attr->flags & ATTR_IS_SPARSE)
+		if (a->flags & ATTR_IS_SPARSE)
 			NInoSetSparse(ni);
-		ir = (INDEX_ROOT*)((char*)ctx->attr + le16_to_cpu(
-				ctx->attr->data.resident.value_offset));
-		ir_end = (char*)ir + le32_to_cpu(
-				ctx->attr->data.resident.value_length);
-		if (ir_end > (char*)ctx->mrec + vol->mft_record_size) {
+		ir = (INDEX_ROOT*)((u8*)a +
+				le16_to_cpu(a->data.resident.value_offset));
+		ir_end = (u8*)ir + le32_to_cpu(a->data.resident.value_length);
+		if (ir_end > (u8*)ctx->mrec + vol->mft_record_size) {
 			ntfs_error(vi->i_sb, "$INDEX_ROOT attribute is "
 					"corrupt.");
 			goto unm_err_out;
 		}
-		index_end = (char*)&ir->index +
+		index_end = (u8*)&ir->index +
 				le32_to_cpu(ir->index.index_length);
 		if (index_end > ir_end) {
 			ntfs_error(vi->i_sb, "Directory index is corrupt.");
@@ -889,7 +890,8 @@ skip_attr_list_load:
 						"attribute.");
 			goto unm_err_out;
 		}
-		if (!ctx->attr->non_resident) {
+		a = ctx->attr;
+		if (!a->non_resident) {
 			ntfs_error(vi->i_sb, "$INDEX_ALLOCATION attribute "
 					"is resident.");
 			goto unm_err_out;
@@ -898,42 +900,40 @@ skip_attr_list_load:
 		 * Ensure the attribute name is placed before the mapping pairs
 		 * array.
 		 */
-		if (unlikely(ctx->attr->name_length &&
-				(le16_to_cpu(ctx->attr->name_offset) >=
-				le16_to_cpu(ctx->attr->data.non_resident.
-				mapping_pairs_offset)))) {
+		if (unlikely(a->name_length && (le16_to_cpu(a->name_offset) >=
+				le16_to_cpu(
+				a->data.non_resident.mapping_pairs_offset)))) {
 			ntfs_error(vol->sb, "$INDEX_ALLOCATION attribute name "
 					"is placed after the mapping pairs "
 					"array.");
 			goto unm_err_out;
 		}
-		if (ctx->attr->flags & ATTR_IS_ENCRYPTED) {
+		if (a->flags & ATTR_IS_ENCRYPTED) {
 			ntfs_error(vi->i_sb, "$INDEX_ALLOCATION attribute "
 					"is encrypted.");
 			goto unm_err_out;
 		}
-		if (ctx->attr->flags & ATTR_IS_SPARSE) {
+		if (a->flags & ATTR_IS_SPARSE) {
 			ntfs_error(vi->i_sb, "$INDEX_ALLOCATION attribute "
 					"is sparse.");
 			goto unm_err_out;
 		}
-		if (ctx->attr->flags & ATTR_COMPRESSION_MASK) {
+		if (a->flags & ATTR_COMPRESSION_MASK) {
 			ntfs_error(vi->i_sb, "$INDEX_ALLOCATION attribute "
 					"is compressed.");
 			goto unm_err_out;
 		}
-		if (ctx->attr->data.non_resident.lowest_vcn) {
+		if (a->data.non_resident.lowest_vcn) {
 			ntfs_error(vi->i_sb, "First extent of "
 					"$INDEX_ALLOCATION attribute has non "
 					"zero lowest_vcn.");
 			goto unm_err_out;
 		}
-		vi->i_size = sle64_to_cpu(
-				ctx->attr->data.non_resident.data_size);
+		vi->i_size = sle64_to_cpu(a->data.non_resident.data_size);
 		ni->initialized_size = sle64_to_cpu(
-				ctx->attr->data.non_resident.initialized_size);
+				a->data.non_resident.initialized_size);
 		ni->allocated_size = sle64_to_cpu(
-				ctx->attr->data.non_resident.allocated_size);
+				a->data.non_resident.allocated_size);
 		/*
 		 * We are done with the mft record, so we release it. Otherwise
 		 * we would deadlock in ntfs_attr_iget().
@@ -958,11 +958,12 @@ skip_attr_list_load:
 			goto unm_err_out;
 		}
 		/* Consistency check bitmap size vs. index allocation size. */
-		if ((bvi->i_size << 3) < (vi->i_size >>
+		bvi_size = i_size_read(bvi);
+		if ((bvi_size << 3) < (vi->i_size >>
 				ni->itype.index.block_size_bits)) {
 			ntfs_error(vi->i_sb, "Index bitmap too small (0x%llx) "
 					"for index allocation (0x%llx).",
-					bvi->i_size << 3, vi->i_size);
+					bvi_size << 3, vi->i_size);
 			goto unm_err_out;
 		}
 skip_large_dir_stuff:
@@ -1010,87 +1011,92 @@ skip_large_dir_stuff:
 			ntfs_error(vi->i_sb, "$DATA attribute is missing.");
 			goto unm_err_out;
 		}
+		a = ctx->attr;
 		/* Setup the state. */
-		if (ctx->attr->non_resident) {
+		if (a->non_resident) {
 			NInoSetNonResident(ni);
-			if (ctx->attr->flags & ATTR_COMPRESSION_MASK) {
-				NInoSetCompressed(ni);
-				if (vol->cluster_size > 4096) {
-					ntfs_error(vi->i_sb, "Found "
-						"compressed data but "
-						"compression is disabled due "
-						"to cluster size (%i) > 4kiB.",
-						vol->cluster_size);
-					goto unm_err_out;
-				}
-				if ((ctx->attr->flags & ATTR_COMPRESSION_MASK)
-						!= ATTR_IS_COMPRESSED) {
-					ntfs_error(vi->i_sb, "Found "
-						"unknown compression method or "
-						"corrupt file.");
-					goto unm_err_out;
+			if (a->flags & (ATTR_COMPRESSION_MASK |
+					ATTR_IS_SPARSE)) {
+				if (a->flags & ATTR_COMPRESSION_MASK) {
+					NInoSetCompressed(ni);
+					if (vol->cluster_size > 4096) {
+						ntfs_error(vi->i_sb, "Found "
+							"compressed data but "
+							"compression is "
+							"disabled due to "
+							"cluster size (%i) > "
+							"4kiB.",
+							vol->cluster_size);
+						goto unm_err_out;
+					}
+					if ((a->flags & ATTR_COMPRESSION_MASK)
+							!= ATTR_IS_COMPRESSED) {
+						ntfs_error(vi->i_sb, "Found "
+							"unknown compression "
+							"method or corrupt "
+							"file.");
+						goto unm_err_out;
+					}
 				}
-				ni->itype.compressed.block_clusters = 1U <<
-						ctx->attr->data.non_resident.
-						compression_unit;
-				if (ctx->attr->data.non_resident.
-						compression_unit != 4) {
+				if (a->flags & ATTR_IS_SPARSE)
+					NInoSetSparse(ni);
+				if (a->data.non_resident.compression_unit !=
+						4) {
 					ntfs_error(vi->i_sb, "Found "
 						"nonstandard compression unit "
 						"(%u instead of 4).  Cannot "
 						"handle this.",
-						ctx->attr->data.non_resident.
+						a->data.non_resident.
 						compression_unit);
 					err = -EOPNOTSUPP;
 					goto unm_err_out;
 				}
+				ni->itype.compressed.block_clusters = 1U <<
+						a->data.non_resident.
+						compression_unit;
 				ni->itype.compressed.block_size = 1U << (
-						ctx->attr->data.non_resident.
+						a->data.non_resident.
 						compression_unit +
 						vol->cluster_size_bits);
 				ni->itype.compressed.block_size_bits = ffs(
-					ni->itype.compressed.block_size) - 1;
+						ni->itype.compressed.
+						block_size) - 1;
+				ni->itype.compressed.size = sle64_to_cpu(
+						a->data.non_resident.
+						compressed_size);
 			}
-			if (ctx->attr->flags & ATTR_IS_ENCRYPTED) {
-				if (ctx->attr->flags & ATTR_COMPRESSION_MASK) {
+			if (a->flags & ATTR_IS_ENCRYPTED) {
+				if (a->flags & ATTR_COMPRESSION_MASK) {
 					ntfs_error(vi->i_sb, "Found encrypted "
 							"and compressed data.");
 					goto unm_err_out;
 				}
 				NInoSetEncrypted(ni);
 			}
-			if (ctx->attr->flags & ATTR_IS_SPARSE)
-				NInoSetSparse(ni);
-			if (ctx->attr->data.non_resident.lowest_vcn) {
+			if (a->data.non_resident.lowest_vcn) {
 				ntfs_error(vi->i_sb, "First extent of $DATA "
 						"attribute has non zero "
 						"lowest_vcn.");
 				goto unm_err_out;
 			}
-			/* Setup all the sizes. */
 			vi->i_size = sle64_to_cpu(
-					ctx->attr->data.non_resident.data_size);
+					a->data.non_resident.data_size);
 			ni->initialized_size = sle64_to_cpu(
-					ctx->attr->data.non_resident.
-					initialized_size);
+					a->data.non_resident.initialized_size);
 			ni->allocated_size = sle64_to_cpu(
-					ctx->attr->data.non_resident.
-					allocated_size);
-			if (NInoCompressed(ni)) {
-				ni->itype.compressed.size = sle64_to_cpu(
-						ctx->attr->data.non_resident.
-						compressed_size);
-			}
+					a->data.non_resident.allocated_size);
 		} else { /* Resident attribute. */
-			/*
-			 * Make all sizes equal for simplicity in read code
-			 * paths. FIXME: Need to keep this in mind when
-			 * converting to non-resident attribute in write code
-			 * path. (Probably only affects truncate().)
-			 */
-			vi->i_size = ni->initialized_size = ni->allocated_size =
-					le32_to_cpu(
-					ctx->attr->data.resident.value_length);
+			vi->i_size = ni->initialized_size = le32_to_cpu(
+					a->data.resident.value_length);
+			ni->allocated_size = le32_to_cpu(a->length) -
+					le16_to_cpu(
+					a->data.resident.value_offset);
+			if (vi->i_size > ni->allocated_size) {
+				ntfs_error(vi->i_sb, "Resident data attribute "
+						"is corrupt (size exceeds "
+						"allocation).");
+				goto unm_err_out;
+			}
 		}
 no_data_attr_special_case:
 		/* We are done with the mft record, so we release it. */
@@ -1117,11 +1123,10 @@ no_data_attr_special_case:
 	 * sizes of all non-resident attributes present to give us the Linux
 	 * correct size that should go into i_blocks (after division by 512).
 	 */
-	if (S_ISDIR(vi->i_mode) || !NInoCompressed(ni))
-		vi->i_blocks = ni->allocated_size >> 9;
-	else
+	if (S_ISREG(vi->i_mode) && (NInoCompressed(ni) || NInoSparse(ni)))
 		vi->i_blocks = ni->itype.compressed.size >> 9;
-
+	else
+		vi->i_blocks = ni->allocated_size >> 9;
 	ntfs_debug("Done.");
 	return 0;
 
@@ -1166,6 +1171,7 @@ static int ntfs_read_locked_attr_inode(s
 	ntfs_volume *vol = NTFS_SB(vi->i_sb);
 	ntfs_inode *ni, *base_ni;
 	MFT_RECORD *m;
+	ATTR_RECORD *a;
 	ntfs_attr_search_ctx *ctx;
 	int err = 0;
 
@@ -1200,24 +1206,21 @@ static int ntfs_read_locked_attr_inode(s
 		err = -ENOMEM;
 		goto unm_err_out;
 	}
-
 	/* Find the attribute. */
 	err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len,
 			CASE_SENSITIVE, 0, NULL, 0, ctx);
 	if (unlikely(err))
 		goto unm_err_out;
-
-	if (!ctx->attr->non_resident) {
+	a = ctx->attr;
+	if (!a->non_resident) {
 		/* Ensure the attribute name is placed before the value. */
-		if (unlikely(ctx->attr->name_length &&
-				(le16_to_cpu(ctx->attr->name_offset) >=
-				le16_to_cpu(ctx->attr->data.resident.
-				value_offset)))) {
+		if (unlikely(a->name_length && (le16_to_cpu(a->name_offset) >=
+				le16_to_cpu(a->data.resident.value_offset)))) {
 			ntfs_error(vol->sb, "Attribute name is placed after "
 					"the attribute value.");
 			goto unm_err_out;
 		}
-		if (NInoMstProtected(ni) || ctx->attr->flags) {
+		if (NInoMstProtected(ni) || a->flags) {
 			ntfs_error(vi->i_sb, "Found mst protected attribute "
 					"or attribute with non-zero flags but "
 					"the attribute is resident.  Please "
@@ -1225,85 +1228,95 @@ static int ntfs_read_locked_attr_inode(s
 					"linux-ntfs-dev@lists.sourceforge.net");
 			goto unm_err_out;
 		}
-		/*
-		 * Resident attribute. Make all sizes equal for simplicity in
-		 * read code paths.
-		 */
-		vi->i_size = ni->initialized_size = ni->allocated_size =
-			le32_to_cpu(ctx->attr->data.resident.value_length);
+		vi->i_size = ni->initialized_size = le32_to_cpu(
+				a->data.resident.value_length);
+		ni->allocated_size = le32_to_cpu(a->length) -
+				le16_to_cpu(a->data.resident.value_offset);
+		if (vi->i_size > ni->allocated_size) {
+			ntfs_error(vi->i_sb, "Resident attribute is corrupt "
+					"(size exceeds allocation).");
+			goto unm_err_out;
+		}
 	} else {
 		NInoSetNonResident(ni);
 		/*
 		 * Ensure the attribute name is placed before the mapping pairs
 		 * array.
 		 */
-		if (unlikely(ctx->attr->name_length &&
-				(le16_to_cpu(ctx->attr->name_offset) >=
-				le16_to_cpu(ctx->attr->data.non_resident.
-				mapping_pairs_offset)))) {
+		if (unlikely(a->name_length && (le16_to_cpu(a->name_offset) >=
+				le16_to_cpu(
+				a->data.non_resident.mapping_pairs_offset)))) {
 			ntfs_error(vol->sb, "Attribute name is placed after "
 					"the mapping pairs array.");
 			goto unm_err_out;
 		}
-		if (ctx->attr->flags & ATTR_COMPRESSION_MASK) {
+		if (a->flags & (ATTR_COMPRESSION_MASK | ATTR_IS_SPARSE)) {
+			if (a->flags & ATTR_COMPRESSION_MASK) {
+				NInoSetCompressed(ni);
+				if ((ni->type != AT_DATA) || (ni->type ==
+						AT_DATA && ni->name_len)) {
+					ntfs_error(vi->i_sb, "Found compressed "
+							"non-data or named "
+							"data attribute.  "
+							"Please report you "
+							"saw this message to "
+							"linux-ntfs-dev@lists."
+							"sourceforge.net");
+					goto unm_err_out;
+				}
+				if (vol->cluster_size > 4096) {
+					ntfs_error(vi->i_sb, "Found compressed "
+							"attribute but "
+							"compression is "
+							"disabled due to "
+							"cluster size (%i) > "
+							"4kiB.",
+							vol->cluster_size);
+					goto unm_err_out;
+				}
+				if ((a->flags & ATTR_COMPRESSION_MASK) !=
+						ATTR_IS_COMPRESSED) {
+					ntfs_error(vi->i_sb, "Found unknown "
+							"compression method.");
+					goto unm_err_out;
+				}
+			}
 			if (NInoMstProtected(ni)) {
 				ntfs_error(vi->i_sb, "Found mst protected "
 						"attribute but the attribute "
-						"is compressed.  Please report "
-						"you saw this message to "
-						"linux-ntfs-dev@lists."
-						"sourceforge.net");
-				goto unm_err_out;
-			}
-			NInoSetCompressed(ni);
-			if ((ni->type != AT_DATA) || (ni->type == AT_DATA &&
-					ni->name_len)) {
-				ntfs_error(vi->i_sb, "Found compressed "
-						"non-data or named data "
-						"attribute.  Please report "
-						"you saw this message to "
+						"is %s.  Please report you "
+						"saw this message to "
 						"linux-ntfs-dev@lists."
-						"sourceforge.net");
-				goto unm_err_out;
-			}
-			if (vol->cluster_size > 4096) {
-				ntfs_error(vi->i_sb, "Found compressed "
-						"attribute but compression is "
-						"disabled due to cluster size "
-						"(%i) > 4kiB.",
-						vol->cluster_size);
+						"sourceforge.net",
+						NInoCompressed(ni) ?
+						"compressed" : "sparse");
 				goto unm_err_out;
 			}
-			if ((ctx->attr->flags & ATTR_COMPRESSION_MASK)
-					!= ATTR_IS_COMPRESSED) {
-				ntfs_error(vi->i_sb, "Found unknown "
-						"compression method.");
-				goto unm_err_out;
-			}
-			ni->itype.compressed.block_clusters = 1U <<
-					ctx->attr->data.non_resident.
-					compression_unit;
-			if (ctx->attr->data.non_resident.compression_unit !=
-					4) {
+			if (a->flags & ATTR_IS_SPARSE)
+				NInoSetSparse(ni);
+			if (a->data.non_resident.compression_unit != 4) {
 				ntfs_error(vi->i_sb, "Found nonstandard "
 						"compression unit (%u instead "
 						"of 4).  Cannot handle this.",
-						ctx->attr->data.non_resident.
+						a->data.non_resident.
 						compression_unit);
 				err = -EOPNOTSUPP;
 				goto unm_err_out;
 			}
+			ni->itype.compressed.block_clusters = 1U <<
+					a->data.non_resident.compression_unit;
 			ni->itype.compressed.block_size = 1U << (
-					ctx->attr->data.non_resident.
-					compression_unit +
+					a->data.non_resident.compression_unit +
 					vol->cluster_size_bits);
 			ni->itype.compressed.block_size_bits = ffs(
-				ni->itype.compressed.block_size) - 1;
+					ni->itype.compressed.block_size) - 1;
+			ni->itype.compressed.size = sle64_to_cpu(
+					a->data.non_resident.compressed_size);
 		}
-		if (ctx->attr->flags & ATTR_IS_ENCRYPTED) {
-			if (ctx->attr->flags & ATTR_COMPRESSION_MASK) {
-				ntfs_error(vi->i_sb, "Found encrypted "
-						"and compressed data.");
+		if (a->flags & ATTR_IS_ENCRYPTED) {
+			if (a->flags & ATTR_COMPRESSION_MASK) {
+				ntfs_error(vi->i_sb, "Found encrypted and "
+						"compressed data.");
 				goto unm_err_out;
 			}
 			if (NInoMstProtected(ni)) {
@@ -1317,37 +1330,17 @@ static int ntfs_read_locked_attr_inode(s
 			}
 			NInoSetEncrypted(ni);
 		}
-		if (ctx->attr->flags & ATTR_IS_SPARSE) {
-			if (NInoMstProtected(ni)) {
-				ntfs_error(vi->i_sb, "Found mst protected "
-						"attribute but the attribute "
-						"is sparse.  Please report "
-						"you saw this message to "
-						"linux-ntfs-dev@lists."
-						"sourceforge.net");
-				goto unm_err_out;
-			}
-			NInoSetSparse(ni);
-		}
-		if (ctx->attr->data.non_resident.lowest_vcn) {
+		if (a->data.non_resident.lowest_vcn) {
 			ntfs_error(vi->i_sb, "First extent of attribute has "
 					"non-zero lowest_vcn.");
 			goto unm_err_out;
 		}
-		/* Setup all the sizes. */
-		vi->i_size = sle64_to_cpu(
-				ctx->attr->data.non_resident.data_size);
+		vi->i_size = sle64_to_cpu(a->data.non_resident.data_size);
 		ni->initialized_size = sle64_to_cpu(
-				ctx->attr->data.non_resident.initialized_size);
+				a->data.non_resident.initialized_size);
 		ni->allocated_size = sle64_to_cpu(
-				ctx->attr->data.non_resident.allocated_size);
-		if (NInoCompressed(ni)) {
-			ni->itype.compressed.size = sle64_to_cpu(
-					ctx->attr->data.non_resident.
-					compressed_size);
-		}
+				a->data.non_resident.allocated_size);
 	}
-
 	/* Setup the operations for this attribute inode. */
 	vi->i_op = NULL;
 	vi->i_fop = NULL;
@@ -1355,12 +1348,10 @@ static int ntfs_read_locked_attr_inode(s
 		vi->i_mapping->a_ops = &ntfs_mst_aops;
 	else
 		vi->i_mapping->a_ops = &ntfs_aops;
-
-	if (!NInoCompressed(ni))
-		vi->i_blocks = ni->allocated_size >> 9;
-	else
+	if (NInoCompressed(ni) || NInoSparse(ni))
 		vi->i_blocks = ni->itype.compressed.size >> 9;
-
+	else
+		vi->i_blocks = ni->allocated_size >> 9;
 	/*
 	 * Make sure the base inode doesn't go away and attach it to the
 	 * attribute inode.
@@ -1429,10 +1420,12 @@ err_out:
  */
 static int ntfs_read_locked_index_inode(struct inode *base_vi, struct inode *vi)
 {
+	loff_t bvi_size;
 	ntfs_volume *vol = NTFS_SB(vi->i_sb);
 	ntfs_inode *ni, *base_ni, *bni;
 	struct inode *bvi;
 	MFT_RECORD *m;
+	ATTR_RECORD *a;
 	ntfs_attr_search_ctx *ctx;
 	INDEX_ROOT *ir;
 	u8 *ir_end, *index_end;
@@ -1474,30 +1467,28 @@ static int ntfs_read_locked_index_inode(
 					"missing.");
 		goto unm_err_out;
 	}
+	a = ctx->attr;
 	/* Set up the state. */
-	if (unlikely(ctx->attr->non_resident)) {
+	if (unlikely(a->non_resident)) {
 		ntfs_error(vol->sb, "$INDEX_ROOT attribute is not resident.");
 		goto unm_err_out;
 	}
 	/* Ensure the attribute name is placed before the value. */
-	if (unlikely(ctx->attr->name_length &&
-			(le16_to_cpu(ctx->attr->name_offset) >=
-			le16_to_cpu(ctx->attr->data.resident.
-			value_offset)))) {
+	if (unlikely(a->name_length && (le16_to_cpu(a->name_offset) >=
+			le16_to_cpu(a->data.resident.value_offset)))) {
 		ntfs_error(vol->sb, "$INDEX_ROOT attribute name is placed "
 				"after the attribute value.");
 		goto unm_err_out;
 	}
 	/* Compressed/encrypted/sparse index root is not allowed. */
-	if (ctx->attr->flags & (ATTR_COMPRESSION_MASK | ATTR_IS_ENCRYPTED |
+	if (a->flags & (ATTR_COMPRESSION_MASK | ATTR_IS_ENCRYPTED |
 			ATTR_IS_SPARSE)) {
 		ntfs_error(vi->i_sb, "Found compressed/encrypted/sparse index "
 				"root attribute.");
 		goto unm_err_out;
 	}
-	ir = (INDEX_ROOT*)((u8*)ctx->attr +
-			le16_to_cpu(ctx->attr->data.resident.value_offset));
-	ir_end = (u8*)ir + le32_to_cpu(ctx->attr->data.resident.value_length);
+	ir = (INDEX_ROOT*)((u8*)a + le16_to_cpu(a->data.resident.value_offset));
+	ir_end = (u8*)ir + le32_to_cpu(a->data.resident.value_length);
 	if (ir_end > (u8*)ctx->mrec + vol->mft_record_size) {
 		ntfs_error(vi->i_sb, "$INDEX_ROOT attribute is corrupt.");
 		goto unm_err_out;
@@ -1570,7 +1561,7 @@ static int ntfs_read_locked_index_inode(
 					"$INDEX_ALLOCATION attribute.");
 		goto unm_err_out;
 	}
-	if (!ctx->attr->non_resident) {
+	if (!a->non_resident) {
 		ntfs_error(vi->i_sb, "$INDEX_ALLOCATION attribute is "
 				"resident.");
 		goto unm_err_out;
@@ -1578,37 +1569,36 @@ static int ntfs_read_locked_index_inode(
 	/*
 	 * Ensure the attribute name is placed before the mapping pairs array.
 	 */
-	if (unlikely(ctx->attr->name_length && (le16_to_cpu(
-			ctx->attr->name_offset) >= le16_to_cpu(
-			ctx->attr->data.non_resident.mapping_pairs_offset)))) {
+	if (unlikely(a->name_length && (le16_to_cpu(a->name_offset) >=
+			le16_to_cpu(
+			a->data.non_resident.mapping_pairs_offset)))) {
 		ntfs_error(vol->sb, "$INDEX_ALLOCATION attribute name is "
 				"placed after the mapping pairs array.");
 		goto unm_err_out;
 	}
-	if (ctx->attr->flags & ATTR_IS_ENCRYPTED) {
+	if (a->flags & ATTR_IS_ENCRYPTED) {
 		ntfs_error(vi->i_sb, "$INDEX_ALLOCATION attribute is "
 				"encrypted.");
 		goto unm_err_out;
 	}
-	if (ctx->attr->flags & ATTR_IS_SPARSE) {
+	if (a->flags & ATTR_IS_SPARSE) {
 		ntfs_error(vi->i_sb, "$INDEX_ALLOCATION attribute is sparse.");
 		goto unm_err_out;
 	}
-	if (ctx->attr->flags & ATTR_COMPRESSION_MASK) {
+	if (a->flags & ATTR_COMPRESSION_MASK) {
 		ntfs_error(vi->i_sb, "$INDEX_ALLOCATION attribute is "
 				"compressed.");
 		goto unm_err_out;
 	}
-	if (ctx->attr->data.non_resident.lowest_vcn) {
+	if (a->data.non_resident.lowest_vcn) {
 		ntfs_error(vi->i_sb, "First extent of $INDEX_ALLOCATION "
 				"attribute has non zero lowest_vcn.");
 		goto unm_err_out;
 	}
-	vi->i_size = sle64_to_cpu(ctx->attr->data.non_resident.data_size);
+	vi->i_size = sle64_to_cpu(a->data.non_resident.data_size);
 	ni->initialized_size = sle64_to_cpu(
-			ctx->attr->data.non_resident.initialized_size);
-	ni->allocated_size = sle64_to_cpu(
-			ctx->attr->data.non_resident.allocated_size);
+			a->data.non_resident.initialized_size);
+	ni->allocated_size = sle64_to_cpu(a->data.non_resident.allocated_size);
 	/*
 	 * We are done with the mft record, so we release it.  Otherwise
 	 * we would deadlock in ntfs_attr_iget().
@@ -1632,10 +1622,10 @@ static int ntfs_read_locked_index_inode(
 		goto iput_unm_err_out;
 	}
 	/* Consistency check bitmap size vs. index allocation size. */
-	if ((bvi->i_size << 3) < (vi->i_size >>
-			ni->itype.index.block_size_bits)) {
+	bvi_size = i_size_read(bvi);
+	if ((bvi_size << 3) < (vi->i_size >> ni->itype.index.block_size_bits)) {
 		ntfs_error(vi->i_sb, "Index bitmap too small (0x%llx) for "
-				"index allocation (0x%llx).", bvi->i_size << 3,
+				"index allocation (0x%llx).", bvi_size << 3,
 				vi->i_size);
 		goto iput_unm_err_out;
 	}
@@ -1646,7 +1636,6 @@ skip_large_index_stuff:
 	vi->i_fop = NULL;
 	vi->i_mapping->a_ops = &ntfs_mst_aops;
 	vi->i_blocks = ni->allocated_size >> 9;
-
 	/*
 	 * Make sure the base inode doesn't go away and attach it to the
 	 * index inode.
@@ -1712,7 +1701,7 @@ int ntfs_read_inode_mount(struct inode *
 	struct buffer_head *bh;
 	ntfs_inode *ni;
 	MFT_RECORD *m = NULL;
-	ATTR_RECORD *attr;
+	ATTR_RECORD *a;
 	ntfs_attr_search_ctx *ctx;
 	unsigned int i, nr_blocks;
 	int err;
@@ -1727,10 +1716,10 @@ int ntfs_read_inode_mount(struct inode *
 	/* Setup the data attribute. It is special as it is mst protected. */
 	NInoSetNonResident(ni);
 	NInoSetMstProtected(ni);
+	NInoSetSparseDisabled(ni);
 	ni->type = AT_DATA;
 	ni->name = NULL;
 	ni->name_len = 0;
-
 	/*
 	 * This sets up our little cheat allowing us to reuse the async read io
 	 * completion handler for directories.
@@ -1808,9 +1797,10 @@ int ntfs_read_inode_mount(struct inode *
 
 		ntfs_debug("Attribute list attribute found in $MFT.");
 		NInoSetAttrList(ni);
-		if (ctx->attr->flags & ATTR_IS_ENCRYPTED ||
-				ctx->attr->flags & ATTR_COMPRESSION_MASK ||
-				ctx->attr->flags & ATTR_IS_SPARSE) {
+		a = ctx->attr;
+		if (a->flags & ATTR_IS_ENCRYPTED ||
+				a->flags & ATTR_COMPRESSION_MASK ||
+				a->flags & ATTR_IS_SPARSE) {
 			ntfs_error(sb, "Attribute list attribute is "
 					"compressed/encrypted/sparse. Not "
 					"allowed. $MFT is corrupt. You should "
@@ -1818,16 +1808,16 @@ int ntfs_read_inode_mount(struct inode *
 			goto put_err_out;
 		}
 		/* Now allocate memory for the attribute list. */
-		ni->attr_list_size = (u32)ntfs_attr_size(ctx->attr);
+		ni->attr_list_size = (u32)ntfs_attr_size(a);
 		ni->attr_list = ntfs_malloc_nofs(ni->attr_list_size);
 		if (!ni->attr_list) {
 			ntfs_error(sb, "Not enough memory to allocate buffer "
 					"for attribute list.");
 			goto put_err_out;
 		}
-		if (ctx->attr->non_resident) {
+		if (a->non_resident) {
 			NInoSetAttrListNonResident(ni);
-			if (ctx->attr->data.non_resident.lowest_vcn) {
+			if (a->data.non_resident.lowest_vcn) {
 				ntfs_error(sb, "Attribute list has non zero "
 						"lowest_vcn. $MFT is corrupt. "
 						"You should run chkdsk.");
@@ -1835,7 +1825,7 @@ int ntfs_read_inode_mount(struct inode *
 			}
 			/* Setup the runlist. */
 			ni->attr_list_rl.rl = ntfs_mapping_pairs_decompress(vol,
-					ctx->attr, NULL);
+					a, NULL);
 			if (IS_ERR(ni->attr_list_rl.rl)) {
 				err = PTR_ERR(ni->attr_list_rl.rl);
 				ni->attr_list_rl.rl = NULL;
@@ -1847,7 +1837,7 @@ int ntfs_read_inode_mount(struct inode *
 			/* Now load the attribute list. */
 			if ((err = load_attribute_list(vol, &ni->attr_list_rl,
 					ni->attr_list, ni->attr_list_size,
-					sle64_to_cpu(ctx->attr->data.
+					sle64_to_cpu(a->data.
 					non_resident.initialized_size)))) {
 				ntfs_error(sb, "Failed to load attribute list "
 						"attribute with error code %i.",
@@ -1855,20 +1845,20 @@ int ntfs_read_inode_mount(struct inode *
 				goto put_err_out;
 			}
 		} else /* if (!ctx.attr->non_resident) */ {
-			if ((u8*)ctx->attr + le16_to_cpu(
-					ctx->attr->data.resident.value_offset) +
+			if ((u8*)a + le16_to_cpu(
+					a->data.resident.value_offset) +
 					le32_to_cpu(
-					ctx->attr->data.resident.value_length) >
+					a->data.resident.value_length) >
 					(u8*)ctx->mrec + vol->mft_record_size) {
 				ntfs_error(sb, "Corrupt attribute list "
 						"attribute.");
 				goto put_err_out;
 			}
 			/* Now copy the attribute list. */
-			memcpy(ni->attr_list, (u8*)ctx->attr + le16_to_cpu(
-					ctx->attr->data.resident.value_offset),
+			memcpy(ni->attr_list, (u8*)a + le16_to_cpu(
+					a->data.resident.value_offset),
 					le32_to_cpu(
-					ctx->attr->data.resident.value_length));
+					a->data.resident.value_length));
 		}
 		/* The attribute list is now setup in memory. */
 		/*
@@ -1934,25 +1924,25 @@ int ntfs_read_inode_mount(struct inode *
 	ntfs_attr_reinit_search_ctx(ctx);
 
 	/* Now load all attribute extents. */
-	attr = NULL;
+	a = NULL;
 	next_vcn = last_vcn = highest_vcn = 0;
 	while (!(err = ntfs_attr_lookup(AT_DATA, NULL, 0, 0, next_vcn, NULL, 0,
 			ctx))) {
 		runlist_element *nrl;
 
 		/* Cache the current attribute. */
-		attr = ctx->attr;
+		a = ctx->attr;
 		/* $MFT must be non-resident. */
-		if (!attr->non_resident) {
+		if (!a->non_resident) {
 			ntfs_error(sb, "$MFT must be non-resident but a "
 					"resident extent was found. $MFT is "
 					"corrupt. Run chkdsk.");
 			goto put_err_out;
 		}
 		/* $MFT must be uncompressed and unencrypted. */
-		if (attr->flags & ATTR_COMPRESSION_MASK ||
-				attr->flags & ATTR_IS_ENCRYPTED ||
-				attr->flags & ATTR_IS_SPARSE) {
+		if (a->flags & ATTR_COMPRESSION_MASK ||
+				a->flags & ATTR_IS_ENCRYPTED ||
+				a->flags & ATTR_IS_SPARSE) {
 			ntfs_error(sb, "$MFT must be uncompressed, "
 					"non-sparse, and unencrypted but a "
 					"compressed/sparse/encrypted extent "
@@ -1966,7 +1956,7 @@ int ntfs_read_inode_mount(struct inode *
 		 * as we have exclusive access to the inode at this time and we
 		 * are a mount in progress task, too.
 		 */
-		nrl = ntfs_mapping_pairs_decompress(vol, attr, ni->runlist.rl);
+		nrl = ntfs_mapping_pairs_decompress(vol, a, ni->runlist.rl);
 		if (IS_ERR(nrl)) {
 			ntfs_error(sb, "ntfs_mapping_pairs_decompress() "
 					"failed with error code %ld.  $MFT is "
@@ -1977,7 +1967,7 @@ int ntfs_read_inode_mount(struct inode *
 
 		/* Are we in the first extent? */
 		if (!next_vcn) {
-			if (attr->data.non_resident.lowest_vcn) {
+			if (a->data.non_resident.lowest_vcn) {
 				ntfs_error(sb, "First extent of $DATA "
 						"attribute has non zero "
 						"lowest_vcn. $MFT is corrupt. "
@@ -1986,15 +1976,15 @@ int ntfs_read_inode_mount(struct inode *
 			}
 			/* Get the last vcn in the $DATA attribute. */
 			last_vcn = sle64_to_cpu(
-					attr->data.non_resident.allocated_size)
+					a->data.non_resident.allocated_size)
 					>> vol->cluster_size_bits;
 			/* Fill in the inode size. */
 			vi->i_size = sle64_to_cpu(
-					attr->data.non_resident.data_size);
-			ni->initialized_size = sle64_to_cpu(attr->data.
-					non_resident.initialized_size);
+					a->data.non_resident.data_size);
+			ni->initialized_size = sle64_to_cpu(
+					a->data.non_resident.initialized_size);
 			ni->allocated_size = sle64_to_cpu(
-					attr->data.non_resident.allocated_size);
+					a->data.non_resident.allocated_size);
 			/*
 			 * Verify the number of mft records does not exceed
 			 * 2^32 - 1.
@@ -2051,7 +2041,7 @@ int ntfs_read_inode_mount(struct inode *
 		}
 
 		/* Get the lowest vcn for the next extent. */
-		highest_vcn = sle64_to_cpu(attr->data.non_resident.highest_vcn);
+		highest_vcn = sle64_to_cpu(a->data.non_resident.highest_vcn);
 		next_vcn = highest_vcn + 1;
 
 		/* Only one extent or error, which we catch below. */
@@ -2060,7 +2050,7 @@ int ntfs_read_inode_mount(struct inode *
 
 		/* Avoid endless loops due to corruption. */
 		if (next_vcn < sle64_to_cpu(
-				attr->data.non_resident.lowest_vcn)) {
+				a->data.non_resident.lowest_vcn)) {
 			ntfs_error(sb, "$MFT has corrupt attribute list "
 					"attribute. Run chkdsk.");
 			goto put_err_out;
@@ -2071,7 +2061,7 @@ int ntfs_read_inode_mount(struct inode *
 				"$MFT is corrupt. Run chkdsk.");
 		goto put_err_out;
 	}
-	if (!attr) {
+	if (!a) {
 		ntfs_error(sb, "$MFT/$DATA attribute not found. $MFT is "
 				"corrupt. Run chkdsk.");
 		goto put_err_out;
@@ -2275,6 +2265,8 @@ int ntfs_show_options(struct seq_file *s
 		seq_printf(sf, ",case_sensitive");
 	if (NVolShowSystemFiles(vol))
 		seq_printf(sf, ",show_sys_files");
+	if (!NVolSparseEnabled(vol))
+		seq_printf(sf, ",disable_sparse");
 	for (i = 0; on_errors_arr[i].val; i++) {
 		if (on_errors_arr[i].val & vol->on_errors)
 			seq_printf(sf, ",errors=%s", on_errors_arr[i].str);
@@ -2311,6 +2303,7 @@ int ntfs_truncate(struct inode *vi)
 	ntfs_volume *vol = ni->vol;
 	ntfs_attr_search_ctx *ctx;
 	MFT_RECORD *m;
+	ATTR_RECORD *a;
 	const char *te = "  Leaving file length out of sync with i_size.";
 	int err;
 
@@ -2347,14 +2340,15 @@ int ntfs_truncate(struct inode *vi)
 					vi->i_ino, err);
 		goto err_out;
 	}
+	a = ctx->attr;
 	/* If the size has not changed there is nothing to do. */
-	if (ntfs_attr_size(ctx->attr) == i_size_read(vi))
+	if (ntfs_attr_size(a) == i_size_read(vi))
 		goto done;
 	// TODO: Implement the truncate...
 	ntfs_error(vi->i_sb, "Inode size has changed but this is not "
 			"implemented yet.  Resetting inode size to old value. "
 			" This is most likely a bug in the ntfs driver!");
-	i_size_write(vi, ntfs_attr_size(ctx->attr)); 
+	i_size_write(vi, ntfs_attr_size(a)); 
 done:
 	ntfs_attr_put_search_ctx(ctx);
 	unmap_mft_record(ni);
@@ -2515,18 +2509,18 @@ int ntfs_write_inode(struct inode *vi, i
 	nt = utc2ntfs(vi->i_mtime);
 	if (si->last_data_change_time != nt) {
 		ntfs_debug("Updating mtime for inode 0x%lx: old = 0x%llx, "
-				"new = 0x%llx", vi->i_ino,
+				"new = 0x%llx", vi->i_ino, (long long)
 				sle64_to_cpu(si->last_data_change_time),
-				sle64_to_cpu(nt));
+				(long long)sle64_to_cpu(nt));
 		si->last_data_change_time = nt;
 		modified = TRUE;
 	}
 	nt = utc2ntfs(vi->i_ctime);
 	if (si->last_mft_change_time != nt) {
 		ntfs_debug("Updating ctime for inode 0x%lx: old = 0x%llx, "
-				"new = 0x%llx", vi->i_ino,
+				"new = 0x%llx", vi->i_ino, (long long)
 				sle64_to_cpu(si->last_mft_change_time),
-				sle64_to_cpu(nt));
+				(long long)sle64_to_cpu(nt));
 		si->last_mft_change_time = nt;
 		modified = TRUE;
 	}
@@ -2534,8 +2528,8 @@ int ntfs_write_inode(struct inode *vi, i
 	if (si->last_access_time != nt) {
 		ntfs_debug("Updating atime for inode 0x%lx: old = 0x%llx, "
 				"new = 0x%llx", vi->i_ino,
-				sle64_to_cpu(si->last_access_time),
-				sle64_to_cpu(nt));
+				(long long)sle64_to_cpu(si->last_access_time),
+				(long long)sle64_to_cpu(nt));
 		si->last_access_time = nt;
 		modified = TRUE;
 	}
diff --git a/fs/ntfs/inode.h b/fs/ntfs/inode.h
--- a/fs/ntfs/inode.h
+++ b/fs/ntfs/inode.h
@@ -2,7 +2,7 @@
  * inode.h - Defines for inode structures NTFS Linux kernel driver. Part of
  *	     the Linux-NTFS project.
  *
- * Copyright (c) 2001-2004 Anton Altaparmakov
+ * Copyright (c) 2001-2005 Anton Altaparmakov
  * Copyright (c) 2002 Richard Russon
  *
  * This program/include file is free software; you can redistribute it and/or
@@ -44,6 +44,7 @@ typedef struct _ntfs_inode ntfs_inode;
  * fields already provided in the VFS inode.
  */
 struct _ntfs_inode {
+	rwlock_t size_lock;	/* Lock serializing access to inode sizes. */
 	s64 initialized_size;	/* Copy from the attribute record. */
 	s64 allocated_size;	/* Copy from the attribute record. */
 	unsigned long state;	/* NTFS specific flags describing this inode.
@@ -109,7 +110,7 @@ struct _ntfs_inode {
 			u8 block_size_bits; 	/* Log2 of the above. */
 			u8 vcn_size_bits;	/* Log2 of the above. */
 		} index;
-		struct { /* It is a compressed file or an attribute inode. */
+		struct { /* It is a compressed/sparse file/attribute inode. */
 			s64 size;		/* Copy of compressed_size from
 						   $DATA. */
 			u32 block_size;		/* Size of a compression block
@@ -165,6 +166,7 @@ typedef enum {
 	NI_Sparse,		/* 1: Unnamed data attr is sparse (f).
 				   1: Create sparse files by default (d).
 				   1: Attribute is sparse (a). */
+	NI_SparseDisabled,	/* 1: May not create sparse regions. */
 	NI_TruncateFailed,	/* 1: Last ntfs_truncate() call failed. */
 } ntfs_inode_state_bits;
 
@@ -217,6 +219,7 @@ NINO_FNS(IndexAllocPresent)
 NINO_FNS(Compressed)
 NINO_FNS(Encrypted)
 NINO_FNS(Sparse)
+NINO_FNS(SparseDisabled)
 NINO_FNS(TruncateFailed)
 
 /*
diff --git a/fs/ntfs/layout.h b/fs/ntfs/layout.h
--- a/fs/ntfs/layout.h
+++ b/fs/ntfs/layout.h
@@ -2,7 +2,7 @@
  * layout.h - All NTFS associated on-disk structures. Part of the Linux-NTFS
  *	      project.
  *
- * Copyright (c) 2001-2004 Anton Altaparmakov
+ * Copyright (c) 2001-2005 Anton Altaparmakov
  * Copyright (c) 2002 Richard Russon
  *
  * This program/include file is free software; you can redistribute it and/or
@@ -547,26 +547,44 @@ enum {
 	COLLATION_NTOFS_ULONG		= const_cpu_to_le32(0x10),
 	COLLATION_NTOFS_SID		= const_cpu_to_le32(0x11),
 	COLLATION_NTOFS_SECURITY_HASH	= const_cpu_to_le32(0x12),
-	COLLATION_NTOFS_ULONGS		= const_cpu_to_le32(0x13)
+	COLLATION_NTOFS_ULONGS		= const_cpu_to_le32(0x13),
 };
 
 typedef le32 COLLATION_RULE;
 
 /*
  * The flags (32-bit) describing attribute properties in the attribute
- * definition structure.  FIXME: This information is from Regis's information
- * and, according to him, it is not certain and probably incomplete.
- * The INDEXABLE flag is fairly certainly correct as only the file name
- * attribute has this flag set and this is the only attribute indexed in NT4.
- */
-enum {
-	INDEXABLE	    = const_cpu_to_le32(0x02), /* Attribute can be
-							  indexed. */
-	NEED_TO_REGENERATE  = const_cpu_to_le32(0x40), /* Need to regenerate
-							  during regeneration
-							  phase. */
-	CAN_BE_NON_RESIDENT = const_cpu_to_le32(0x80), /* Attribute can be
-							  non-resident. */
+ * definition structure.  FIXME: This information is based on Regis's
+ * information and, according to him, it is not certain and probably
+ * incomplete.  The INDEXABLE flag is fairly certainly correct as only the file
+ * name attribute has this flag set and this is the only attribute indexed in
+ * NT4.
+ */
+enum {
+	ATTR_DEF_INDEXABLE	= const_cpu_to_le32(0x02), /* Attribute can be
+					indexed. */
+	ATTR_DEF_MULTIPLE	= const_cpu_to_le32(0x04), /* Attribute type
+					can be present multiple times in the
+					mft records of an inode. */
+	ATTR_DEF_NOT_ZERO	= const_cpu_to_le32(0x08), /* Attribute value
+					must contain at least one non-zero
+					byte. */
+	ATTR_DEF_INDEXED_UNIQUE	= const_cpu_to_le32(0x10), /* Attribute must be
+					indexed and the attribute value must be
+					unique for the attribute type in all of
+					the mft records of an inode. */
+	ATTR_DEF_NAMED_UNIQUE	= const_cpu_to_le32(0x20), /* Attribute must be
+					named and the name must be unique for
+					the attribute type in all of the mft
+					records of an inode. */
+	ATTR_DEF_RESIDENT	= const_cpu_to_le32(0x40), /* Attribute must be
+					resident. */
+	ATTR_DEF_ALWAYS_LOG	= const_cpu_to_le32(0x80), /* Always log
+					modifications to this attribute,
+					regardless of whether it is resident or
+					non-resident.  Without this, only log
+					modifications if the attribute is
+					resident. */
 };
 
 typedef le32 ATTR_DEF_FLAGS;
@@ -749,10 +767,11 @@ typedef struct {
 				record header aligned to 8-byte boundary. */
 /* 34*/			u8 compression_unit; /* The compression unit expressed
 				as the log to the base 2 of the number of
-				clusters in a compression unit. 0 means not
-				compressed. (This effectively limits the
+				clusters in a compression unit.  0 means not
+				compressed.  (This effectively limits the
 				compression unit size to be a power of two
-				clusters.) WinNT4 only uses a value of 4. */
+				clusters.)  WinNT4 only uses a value of 4.
+				Sparse files also have this set to 4. */
 /* 35*/			u8 reserved[5];		/* Align to 8-byte boundary. */
 /* The sizes below are only used when lowest_vcn is zero, as otherwise it would
    be difficult to keep them up-to-date.*/
@@ -772,10 +791,10 @@ typedef struct {
 				data_size. */
 /* sizeof(uncompressed attr) = 64*/
 /* 64*/			sle64 compressed_size;	/* Byte size of the attribute
-				value after compression. Only present when
-				compressed. Always is a multiple of the
-				cluster size. Represents the actual amount of
-				disk space being used on the disk. */
+				value after compression.  Only present when
+				compressed or sparse.  Always is a multiple of
+				the cluster size.  Represents the actual amount
+				of disk space being used on the disk. */
 /* sizeof(compressed attr) = 72*/
 		} __attribute__ ((__packed__)) non_resident;
 	} __attribute__ ((__packed__)) data;
@@ -834,7 +853,7 @@ enum {
 	/* Note, this is a copy of the corresponding bit from the mft record,
 	   telling us whether this file has a view index present (eg. object id
 	   index, quota index, one of the security indexes or the encrypting
-	   file system related indexes). */
+	   filesystem related indexes). */
 };
 
 typedef le32 FILE_ATTR_FLAGS;
@@ -917,20 +936,12 @@ typedef struct {
 		/* 56*/	le64 quota_charged;	/* Byte size of the charge to
 				the quota for all streams of the file. Note: Is
 				zero if quotas are disabled. */
-		/* 64*/	le64 usn;		/* Last update sequence number
-				of the file. This is a direct index into the
-				change (aka usn) journal file. It is zero if
-				the usn journal is disabled.
-				NOTE: To disable the journal need to delete
-				the journal file itself and to then walk the
-				whole mft and set all Usn entries in all mft
-				records to zero! (This can take a while!)
-				The journal is FILE_Extend/$UsnJrnl. Win2k
-				will recreate the journal and initiate
-				logging if necessary when mounting the
-				partition. This, in contrast to disabling the
-				journal is a very fast process, so the user
-				won't even notice it. */
+		/* 64*/	leUSN usn;		/* Last update sequence number
+				of the file.  This is a direct index into the
+				transaction log file ($UsnJrnl).  It is zero if
+				the usn journal is disabled or this file has
+				not been subject to logging yet.  See usnjrnl.h
+				for details. */
 		} __attribute__ ((__packed__)) v3;
 	/* sizeof() = 72 bytes (NTFS 3.x) */
 	} __attribute__ ((__packed__)) ver;
@@ -1893,7 +1904,7 @@ enum {
 	VOLUME_FLAGS_MASK		= const_cpu_to_le16(0x803f),
 
 	/* To make our life easier when checking if we must mount read-only. */
-	VOLUME_MUST_MOUNT_RO_MASK	= const_cpu_to_le16(0x8037),
+	VOLUME_MUST_MOUNT_RO_MASK	= const_cpu_to_le16(0x8027),
 } __attribute__ ((__packed__));
 
 typedef le16 VOLUME_FLAGS;
diff --git a/fs/ntfs/lcnalloc.c b/fs/ntfs/lcnalloc.c
--- a/fs/ntfs/lcnalloc.c
+++ b/fs/ntfs/lcnalloc.c
@@ -1,7 +1,7 @@
 /*
  * lcnalloc.c - Cluster (de)allocation code.  Part of the Linux-NTFS project.
  *
- * Copyright (c) 2004 Anton Altaparmakov
+ * Copyright (c) 2004-2005 Anton Altaparmakov
  *
  * This program/include file is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as published
@@ -60,7 +60,7 @@ int ntfs_cluster_free_from_rl_nolock(ntf
 		if (rl->lcn < 0)
 			continue;
 		err = ntfs_bitmap_clear_run(lcnbmp_vi, rl->lcn, rl->length);
-		if (unlikely(err && (!ret || ret == ENOMEM) && ret != err))
+		if (unlikely(err && (!ret || ret == -ENOMEM) && ret != err))
 			ret = err;
 	}
 	ntfs_debug("Done.");
@@ -140,6 +140,7 @@ runlist_element *ntfs_cluster_alloc(ntfs
 	LCN zone_start, zone_end, bmp_pos, bmp_initial_pos, last_read_pos, lcn;
 	LCN prev_lcn = 0, prev_run_len = 0, mft_zone_size;
 	s64 clusters;
+	loff_t i_size;
 	struct inode *lcnbmp_vi;
 	runlist_element *rl = NULL;
 	struct address_space *mapping;
@@ -249,6 +250,7 @@ runlist_element *ntfs_cluster_alloc(ntfs
 	clusters = count;
 	rlpos = rlsize = 0;
 	mapping = lcnbmp_vi->i_mapping;
+	i_size = i_size_read(lcnbmp_vi);
 	while (1) {
 		ntfs_debug("Start of outer while loop: done_zones 0x%x, "
 				"search_zone %i, pass %i, zone_start 0x%llx, "
@@ -263,7 +265,7 @@ runlist_element *ntfs_cluster_alloc(ntfs
 		last_read_pos = bmp_pos >> 3;
 		ntfs_debug("last_read_pos 0x%llx.",
 				(unsigned long long)last_read_pos);
-		if (last_read_pos > lcnbmp_vi->i_size) {
+		if (last_read_pos > i_size) {
 			ntfs_debug("End of attribute reached.  "
 					"Skipping to zone_pass_done.");
 			goto zone_pass_done;
@@ -287,11 +289,11 @@ runlist_element *ntfs_cluster_alloc(ntfs
 		buf_size = last_read_pos & ~PAGE_CACHE_MASK;
 		buf = page_address(page) + buf_size;
 		buf_size = PAGE_CACHE_SIZE - buf_size;
-		if (unlikely(last_read_pos + buf_size > lcnbmp_vi->i_size))
-			buf_size = lcnbmp_vi->i_size - last_read_pos;
+		if (unlikely(last_read_pos + buf_size > i_size))
+			buf_size = i_size - last_read_pos;
 		buf_size <<= 3;
 		lcn = bmp_pos & 7;
-		bmp_pos &= ~7;
+		bmp_pos &= ~(LCN)7;
 		ntfs_debug("Before inner while loop: buf_size %i, lcn 0x%llx, "
 				"bmp_pos 0x%llx, need_writeback %i.", buf_size,
 				(unsigned long long)lcn,
@@ -309,7 +311,7 @@ runlist_element *ntfs_cluster_alloc(ntfs
 					(unsigned int)*byte);
 			/* Skip full bytes. */
 			if (*byte == 0xff) {
-				lcn = (lcn + 8) & ~7;
+				lcn = (lcn + 8) & ~(LCN)7;
 				ntfs_debug("Continuing while loop 1.");
 				continue;
 			}
@@ -691,7 +693,7 @@ switch_to_data1_zone:		search_zone = 2;
 		if (zone == MFT_ZONE || mft_zone_size <= 0) {
 			ntfs_debug("No free clusters left, going to out.");
 			/* Really no more space left on device. */
-			err = ENOSPC;
+			err = -ENOSPC;
 			goto out;
 		} /* zone == DATA_ZONE && mft_zone_size > 0 */
 		ntfs_debug("Shrinking mft zone.");
@@ -755,13 +757,13 @@ out:
 	if (rl) {
 		int err2;
 
-		if (err == ENOSPC)
+		if (err == -ENOSPC)
 			ntfs_debug("Not enough space to complete allocation, "
-					"err ENOSPC, first free lcn 0x%llx, "
+					"err -ENOSPC, first free lcn 0x%llx, "
 					"could allocate up to 0x%llx "
 					"clusters.",
 					(unsigned long long)rl[0].lcn,
-					(unsigned long long)count - clusters);
+					(unsigned long long)(count - clusters));
 		/* Deallocate all allocated clusters. */
 		ntfs_debug("Attempting rollback...");
 		err2 = ntfs_cluster_free_from_rl_nolock(vol, rl);
@@ -773,10 +775,10 @@ out:
 		}
 		/* Free the runlist. */
 		ntfs_free(rl);
-	} else if (err == ENOSPC)
-		ntfs_debug("No space left at all, err = ENOSPC, "
-				"first free lcn = 0x%llx.",
-				(unsigned long long)vol->data1_zone_pos);
+	} else if (err == -ENOSPC)
+		ntfs_debug("No space left at all, err = -ENOSPC, first free "
+				"lcn = 0x%llx.",
+				(long long)vol->data1_zone_pos);
 	up_write(&vol->lcnbmp_lock);
 	return ERR_PTR(err);
 }
@@ -846,8 +848,8 @@ s64 __ntfs_cluster_free(struct inode *vi
 
 	total_freed = real_freed = 0;
 
-	/* This returns with ni->runlist locked for reading on success. */
-	rl = ntfs_find_vcn(ni, start_vcn, FALSE);
+	down_read(&ni->runlist.lock);
+	rl = ntfs_attr_find_vcn_nolock(ni, start_vcn, FALSE);
 	if (IS_ERR(rl)) {
 		if (!is_rollback)
 			ntfs_error(vol->sb, "Failed to find first runlist "
@@ -861,7 +863,7 @@ s64 __ntfs_cluster_free(struct inode *vi
 			ntfs_error(vol->sb, "First runlist element has "
 					"invalid lcn, aborting.");
 		err = -EIO;
-		goto unl_err_out;
+		goto err_out;
 	}
 	/* Find the starting cluster inside the run that needs freeing. */
 	delta = start_vcn - rl->vcn;
@@ -879,7 +881,7 @@ s64 __ntfs_cluster_free(struct inode *vi
 			if (!is_rollback)
 				ntfs_error(vol->sb, "Failed to clear first run "
 						"(error %i), aborting.", err);
-			goto unl_err_out;
+			goto err_out;
 		}
 		/* We have freed @to_free real clusters. */
 		real_freed = to_free;
@@ -899,30 +901,15 @@ s64 __ntfs_cluster_free(struct inode *vi
 		if (unlikely(rl->lcn < LCN_HOLE)) {
 			VCN vcn;
 
-			/*
-			 * Attempt to map runlist, dropping runlist lock for
-			 * the duration.
-			 */
+			/* Attempt to map runlist. */
 			vcn = rl->vcn;
-			up_read(&ni->runlist.lock);
-			err = ntfs_map_runlist(ni, vcn);
-			if (err) {
-				if (!is_rollback)
-					ntfs_error(vol->sb, "Failed to map "
-							"runlist fragment.");
-				if (err == -EINVAL || err == -ENOENT)
-					err = -EIO;
-				goto err_out;
-			}
-			/*
-			 * This returns with ni->runlist locked for reading on
-			 * success.
-			 */
-			rl = ntfs_find_vcn(ni, vcn, FALSE);
+			rl = ntfs_attr_find_vcn_nolock(ni, vcn, FALSE);
 			if (IS_ERR(rl)) {
 				err = PTR_ERR(rl);
 				if (!is_rollback)
-					ntfs_error(vol->sb, "Failed to find "
+					ntfs_error(vol->sb, "Failed to map "
+							"runlist fragment or "
+							"failed to find "
 							"subsequent runlist "
 							"element.");
 				goto err_out;
@@ -935,7 +922,7 @@ s64 __ntfs_cluster_free(struct inode *vi
 							(unsigned long long)
 							rl->lcn);
 				err = -EIO;
-				goto unl_err_out;
+				goto err_out;
 			}
 		}
 		/* The number of clusters in this run that need freeing. */
@@ -951,7 +938,7 @@ s64 __ntfs_cluster_free(struct inode *vi
 				if (!is_rollback)
 					ntfs_error(vol->sb, "Failed to clear "
 							"subsequent run.");
-				goto unl_err_out;
+				goto err_out;
 			}
 			/* We have freed @to_free real clusters. */
 			real_freed += to_free;
@@ -972,9 +959,8 @@ s64 __ntfs_cluster_free(struct inode *vi
 	/* We are done.  Return the number of actually freed clusters. */
 	ntfs_debug("Done.");
 	return real_freed;
-unl_err_out:
-	up_read(&ni->runlist.lock);
 err_out:
+	up_read(&ni->runlist.lock);
 	if (is_rollback)
 		return err;
 	/* If no real clusters were freed, no need to rollback. */
diff --git a/fs/ntfs/logfile.c b/fs/ntfs/logfile.c
--- a/fs/ntfs/logfile.c
+++ b/fs/ntfs/logfile.c
@@ -1,7 +1,7 @@
 /*
  * logfile.c - NTFS kernel journal handling. Part of the Linux-NTFS project.
  *
- * Copyright (c) 2002-2004 Anton Altaparmakov
+ * Copyright (c) 2002-2005 Anton Altaparmakov
  *
  * This program/include file is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as published
@@ -410,7 +410,7 @@ err_out:
 }
 
 /**
- * ntfs_ckeck_logfile - check in the journal if the volume is consistent
+ * ntfs_check_logfile - check the journal for consistency
  * @log_vi:	struct inode of loaded journal $LogFile to check
  *
  * Check the $LogFile journal for consistency and return TRUE if it is
@@ -443,7 +443,7 @@ BOOL ntfs_check_logfile(struct inode *lo
 	/* An empty $LogFile must have been clean before it got emptied. */
 	if (NVolLogFileEmpty(vol))
 		goto is_empty;
-	size = log_vi->i_size;
+	size = i_size_read(log_vi);
 	/* Make sure the file doesn't exceed the maximum allowed size. */
 	if (size > MaxLogFileSize)
 		size = MaxLogFileSize;
@@ -464,7 +464,7 @@ BOOL ntfs_check_logfile(struct inode *lo
 	 * optimize log_page_size and log_page_bits into constants.
 	 */
 	log_page_bits = generic_ffs(log_page_size) - 1;
-	size &= ~(log_page_size - 1);
+	size &= ~(s64)(log_page_size - 1);
 	/*
 	 * Ensure the log file is big enough to store at least the two restart
 	 * pages and the minimum number of log record pages.
@@ -689,7 +689,8 @@ BOOL ntfs_empty_logfile(struct inode *lo
 	if (!NVolLogFileEmpty(vol)) {
 		int err;
 		
-		err = ntfs_attr_set(NTFS_I(log_vi), 0, log_vi->i_size, 0xff);
+		err = ntfs_attr_set(NTFS_I(log_vi), 0, i_size_read(log_vi),
+				0xff);
 		if (unlikely(err)) {
 			ntfs_error(vol->sb, "Failed to fill $LogFile with "
 					"0xff bytes (error code %i).", err);
diff --git a/fs/ntfs/mft.c b/fs/ntfs/mft.c
--- a/fs/ntfs/mft.c
+++ b/fs/ntfs/mft.c
@@ -1,7 +1,7 @@
 /**
  * mft.c - NTFS kernel mft record operations. Part of the Linux-NTFS project.
  *
- * Copyright (c) 2001-2004 Anton Altaparmakov
+ * Copyright (c) 2001-2005 Anton Altaparmakov
  * Copyright (c) 2002 Richard Russon
  *
  * This program/include file is free software; you can redistribute it and/or
@@ -45,6 +45,7 @@
  */
 static inline MFT_RECORD *map_mft_record_page(ntfs_inode *ni)
 {
+	loff_t i_size;
 	ntfs_volume *vol = ni->vol;
 	struct inode *mft_vi = vol->mft_ino;
 	struct page *page;
@@ -60,13 +61,14 @@ static inline MFT_RECORD *map_mft_record
 	index = ni->mft_no << vol->mft_record_size_bits >> PAGE_CACHE_SHIFT;
 	ofs = (ni->mft_no << vol->mft_record_size_bits) & ~PAGE_CACHE_MASK;
 
+	i_size = i_size_read(mft_vi);
 	/* The maximum valid index into the page cache for $MFT's data. */
-	end_index = mft_vi->i_size >> PAGE_CACHE_SHIFT;
+	end_index = i_size >> PAGE_CACHE_SHIFT;
 
 	/* If the wanted index is out of bounds the mft record doesn't exist. */
 	if (unlikely(index >= end_index)) {
-		if (index > end_index || (mft_vi->i_size & ~PAGE_CACHE_MASK) <
-				ofs + vol->mft_record_size) {
+		if (index > end_index || (i_size & ~PAGE_CACHE_MASK) < ofs +
+				vol->mft_record_size) {
 			page = ERR_PTR(-ENOENT);
 			ntfs_error(vol->sb, "Attemt to read mft record 0x%lx, "
 					"which is beyond the end of the mft.  "
@@ -285,7 +287,7 @@ MFT_RECORD *map_extent_mft_record(ntfs_i
 			}
 			unmap_mft_record(ni);
 			ntfs_error(base_ni->vol->sb, "Found stale extent mft "
-					"reference! Corrupt file system. "
+					"reference! Corrupt filesystem. "
 					"Run chkdsk.");
 			return ERR_PTR(-EIO);
 		}
@@ -316,7 +318,7 @@ map_err_out:
 	/* Verify the sequence number if it is present. */
 	if (seq_no && (le16_to_cpu(m->sequence_number) != seq_no)) {
 		ntfs_error(base_ni->vol->sb, "Found stale extent mft "
-				"reference! Corrupt file system. Run chkdsk.");
+				"reference! Corrupt filesystem. Run chkdsk.");
 		destroy_ni = TRUE;
 		m = ERR_PTR(-EIO);
 		goto unm_err_out;
@@ -531,6 +533,7 @@ int ntfs_sync_mft_mirror(ntfs_volume *vo
 			LCN lcn;
 			unsigned int vcn_ofs;
 
+			bh->b_bdev = vol->sb->s_bdev;
 			/* Obtain the vcn and offset of the current block. */
 			vcn = ((VCN)mft_no << vol->mft_record_size_bits) +
 					(block_start - m_start);
@@ -723,6 +726,7 @@ int write_mft_record_nolock(ntfs_inode *
 			LCN lcn;
 			unsigned int vcn_ofs;
 
+			bh->b_bdev = vol->sb->s_bdev;
 			/* Obtain the vcn and offset of the current block. */
 			vcn = ((VCN)ni->mft_no << vol->mft_record_size_bits) +
 					(block_start - m_start);
@@ -946,20 +950,23 @@ BOOL ntfs_may_write_mft_record(ntfs_volu
 	na.name_len = 0;
 	na.type = AT_UNUSED;
 	/*
-	 * For inode 0, i.e. $MFT itself, we cannot use ilookup5() from here or
-	 * we deadlock because the inode is already locked by the kernel
-	 * (fs/fs-writeback.c::__sync_single_inode()) and ilookup5() waits
-	 * until the inode is unlocked before returning it and it never gets
-	 * unlocked because ntfs_should_write_mft_record() never returns.  )-:
-	 * Fortunately, we have inode 0 pinned in icache for the duration of
-	 * the mount so we can access it directly.
+	 * Optimize inode 0, i.e. $MFT itself, since we have it in memory and
+	 * we get here for it rather often.
 	 */
 	if (!mft_no) {
 		/* Balance the below iput(). */
 		vi = igrab(mft_vi);
 		BUG_ON(vi != mft_vi);
-	} else
-		vi = ilookup5(sb, mft_no, (test_t)ntfs_test_inode, &na);
+	} else {
+		/*
+		 * Have to use ilookup5_nowait() since ilookup5() waits for the
+		 * inode lock which causes ntfs to deadlock when a concurrent
+		 * inode write via the inode dirty code paths and the page
+		 * dirty code path of the inode dirty code path when writing
+		 * $MFT occurs.
+		 */
+		vi = ilookup5_nowait(sb, mft_no, (test_t)ntfs_test_inode, &na);
+	}
 	if (vi) {
 		ntfs_debug("Base inode 0x%lx is in icache.", mft_no);
 		/* The inode is in icache. */
@@ -1014,7 +1021,13 @@ BOOL ntfs_may_write_mft_record(ntfs_volu
 	na.mft_no = MREF_LE(m->base_mft_record);
 	ntfs_debug("Mft record 0x%lx is an extent record.  Looking for base "
 			"inode 0x%lx in icache.", mft_no, na.mft_no);
-	vi = ilookup5(sb, na.mft_no, (test_t)ntfs_test_inode, &na);
+	if (!na.mft_no) {
+		/* Balance the below iput(). */
+		vi = igrab(mft_vi);
+		BUG_ON(vi != mft_vi);
+	} else
+		vi = ilookup5_nowait(sb, na.mft_no, (test_t)ntfs_test_inode,
+				&na);
 	if (!vi) {
 		/*
 		 * The base inode is not in icache, write this extent mft
@@ -1121,6 +1134,7 @@ static int ntfs_mft_bitmap_find_and_allo
 		ntfs_inode *base_ni)
 {
 	s64 pass_end, ll, data_pos, pass_start, ofs, bit;
+	unsigned long flags;
 	struct address_space *mftbmp_mapping;
 	u8 *buf, *byte;
 	struct page *page;
@@ -1134,9 +1148,13 @@ static int ntfs_mft_bitmap_find_and_allo
 	 * Set the end of the pass making sure we do not overflow the mft
 	 * bitmap.
 	 */
+	read_lock_irqsave(&NTFS_I(vol->mft_ino)->size_lock, flags);
 	pass_end = NTFS_I(vol->mft_ino)->allocated_size >>
 			vol->mft_record_size_bits;
+	read_unlock_irqrestore(&NTFS_I(vol->mft_ino)->size_lock, flags);
+	read_lock_irqsave(&NTFS_I(vol->mftbmp_ino)->size_lock, flags);
 	ll = NTFS_I(vol->mftbmp_ino)->initialized_size << 3;
+	read_unlock_irqrestore(&NTFS_I(vol->mftbmp_ino)->size_lock, flags);
 	if (pass_end > ll)
 		pass_end = ll;
 	pass = 1;
@@ -1263,6 +1281,7 @@ static int ntfs_mft_bitmap_extend_alloca
 {
 	LCN lcn;
 	s64 ll;
+	unsigned long flags;
 	struct page *page;
 	ntfs_inode *mft_ni, *mftbmp_ni;
 	runlist_element *rl, *rl2 = NULL;
@@ -1284,17 +1303,20 @@ static int ntfs_mft_bitmap_extend_alloca
 	/*
 	 * Determine the last lcn of the mft bitmap.  The allocated size of the
 	 * mft bitmap cannot be zero so we are ok to do this.
-	 * ntfs_find_vcn() returns the runlist locked on success.
 	 */
-	rl = ntfs_find_vcn(mftbmp_ni, (mftbmp_ni->allocated_size - 1) >>
-			vol->cluster_size_bits, TRUE);
+	down_write(&mftbmp_ni->runlist.lock);
+	read_lock_irqsave(&mftbmp_ni->size_lock, flags);
+	ll = mftbmp_ni->allocated_size;
+	read_unlock_irqrestore(&mftbmp_ni->size_lock, flags);
+	rl = ntfs_attr_find_vcn_nolock(mftbmp_ni,
+			(ll - 1) >> vol->cluster_size_bits, TRUE);
 	if (unlikely(IS_ERR(rl) || !rl->length || rl->lcn < 0)) {
+		up_write(&mftbmp_ni->runlist.lock);
 		ntfs_error(vol->sb, "Failed to determine last allocated "
 				"cluster of mft bitmap attribute.");
-		if (!IS_ERR(rl)) {
-			up_write(&mftbmp_ni->runlist.lock);
+		if (!IS_ERR(rl))
 			ret = -EIO;
-		} else
+		else
 			ret = PTR_ERR(rl);
 		return ret;
 	}
@@ -1396,7 +1418,7 @@ static int ntfs_mft_bitmap_extend_alloca
 	BUG_ON(ll < rl2->vcn);
 	BUG_ON(ll >= rl2->vcn + rl2->length);
 	/* Get the size for the new mapping pairs array for this extent. */
-	mp_size = ntfs_get_size_for_mapping_pairs(vol, rl2, ll);
+	mp_size = ntfs_get_size_for_mapping_pairs(vol, rl2, ll, -1);
 	if (unlikely(mp_size <= 0)) {
 		ntfs_error(vol->sb, "Get size for mapping pairs failed for "
 				"mft bitmap attribute extent.");
@@ -1418,6 +1440,8 @@ static int ntfs_mft_bitmap_extend_alloca
 		// TODO: Deal with this by moving this extent to a new mft
 		// record or by starting a new extent in a new mft record or by
 		// moving other attributes out of this mft record.
+		// Note: It will need to be a special mft record and if none of
+		// those are available it gets rather complicated...
 		ntfs_error(vol->sb, "Not enough space in this mft record to "
 				"accomodate extended mft bitmap attribute "
 				"extent.  Cannot handle this yet.");
@@ -1428,7 +1452,7 @@ static int ntfs_mft_bitmap_extend_alloca
 	/* Generate the mapping pairs array directly into the attr record. */
 	ret = ntfs_mapping_pairs_build(vol, (u8*)a +
 			le16_to_cpu(a->data.non_resident.mapping_pairs_offset),
-			mp_size, rl2, ll, NULL);
+			mp_size, rl2, ll, -1, NULL);
 	if (unlikely(ret)) {
 		ntfs_error(vol->sb, "Failed to build mapping pairs array for "
 				"mft bitmap attribute.");
@@ -1458,9 +1482,11 @@ static int ntfs_mft_bitmap_extend_alloca
 		}
 		a = ctx->attr;
 	}
+	write_lock_irqsave(&mftbmp_ni->size_lock, flags);
 	mftbmp_ni->allocated_size += vol->cluster_size;
 	a->data.non_resident.allocated_size =
 			cpu_to_sle64(mftbmp_ni->allocated_size);
+	write_unlock_irqrestore(&mftbmp_ni->size_lock, flags);
 	/* Ensure the changes make it to disk. */
 	flush_dcache_mft_record_page(ctx->ntfs_ino);
 	mark_mft_record_dirty(ctx->ntfs_ino);
@@ -1476,7 +1502,9 @@ restore_undo_alloc:
 			0, ctx)) {
 		ntfs_error(vol->sb, "Failed to find last attribute extent of "
 				"mft bitmap attribute.%s", es);
+		write_lock_irqsave(&mftbmp_ni->size_lock, flags);
 		mftbmp_ni->allocated_size += vol->cluster_size;
+		write_unlock_irqrestore(&mftbmp_ni->size_lock, flags);
 		ntfs_attr_put_search_ctx(ctx);
 		unmap_mft_record(mft_ni);
 		up_write(&mftbmp_ni->runlist.lock);
@@ -1512,7 +1540,7 @@ undo_alloc:
 				a->data.non_resident.mapping_pairs_offset),
 				old_alen - le16_to_cpu(
 				a->data.non_resident.mapping_pairs_offset),
-				rl2, ll, NULL)) {
+				rl2, ll, -1, NULL)) {
 			ntfs_error(vol->sb, "Failed to restore mapping pairs "
 					"array.%s", es);
 			NVolSetErrors(vol);
@@ -1550,6 +1578,7 @@ undo_alloc:
 static int ntfs_mft_bitmap_extend_initialized_nolock(ntfs_volume *vol)
 {
 	s64 old_data_size, old_initialized_size;
+	unsigned long flags;
 	struct inode *mftbmp_vi;
 	ntfs_inode *mft_ni, *mftbmp_ni;
 	ntfs_attr_search_ctx *ctx;
@@ -1583,7 +1612,8 @@ static int ntfs_mft_bitmap_extend_initia
 		goto put_err_out;
 	}
 	a = ctx->attr;
-	old_data_size = mftbmp_vi->i_size;
+	write_lock_irqsave(&mftbmp_ni->size_lock, flags);
+	old_data_size = i_size_read(mftbmp_vi);
 	old_initialized_size = mftbmp_ni->initialized_size;
 	/*
 	 * We can simply update the initialized_size before filling the space
@@ -1593,11 +1623,12 @@ static int ntfs_mft_bitmap_extend_initia
 	mftbmp_ni->initialized_size += 8;
 	a->data.non_resident.initialized_size =
 			cpu_to_sle64(mftbmp_ni->initialized_size);
-	if (mftbmp_ni->initialized_size > mftbmp_vi->i_size) {
-		mftbmp_vi->i_size = mftbmp_ni->initialized_size;
+	if (mftbmp_ni->initialized_size > old_data_size) {
+		i_size_write(mftbmp_vi, mftbmp_ni->initialized_size);
 		a->data.non_resident.data_size =
-				cpu_to_sle64(mftbmp_vi->i_size);
+				cpu_to_sle64(mftbmp_ni->initialized_size);
 	}
+	write_unlock_irqrestore(&mftbmp_ni->size_lock, flags);
 	/* Ensure the changes make it to disk. */
 	flush_dcache_mft_record_page(ctx->ntfs_ino);
 	mark_mft_record_dirty(ctx->ntfs_ino);
@@ -1636,22 +1667,28 @@ unm_err_out:
 		goto err_out;
 	}
 	a = ctx->attr;
+	write_lock_irqsave(&mftbmp_ni->size_lock, flags);
 	mftbmp_ni->initialized_size = old_initialized_size;
 	a->data.non_resident.initialized_size =
 			cpu_to_sle64(old_initialized_size);
-	if (mftbmp_vi->i_size != old_data_size) {
-		mftbmp_vi->i_size = old_data_size;
+	if (i_size_read(mftbmp_vi) != old_data_size) {
+		i_size_write(mftbmp_vi, old_data_size);
 		a->data.non_resident.data_size = cpu_to_sle64(old_data_size);
 	}
+	write_unlock_irqrestore(&mftbmp_ni->size_lock, flags);
 	flush_dcache_mft_record_page(ctx->ntfs_ino);
 	mark_mft_record_dirty(ctx->ntfs_ino);
 	ntfs_attr_put_search_ctx(ctx);
 	unmap_mft_record(mft_ni);
+#ifdef DEBUG
+	read_lock_irqsave(&mftbmp_ni->size_lock, flags);
 	ntfs_debug("Restored status of mftbmp: allocated_size 0x%llx, "
 			"data_size 0x%llx, initialized_size 0x%llx.",
 			(long long)mftbmp_ni->allocated_size,
-			(long long)mftbmp_vi->i_size,
+			(long long)i_size_read(mftbmp_vi),
 			(long long)mftbmp_ni->initialized_size);
+	read_unlock_irqrestore(&mftbmp_ni->size_lock, flags);
+#endif /* DEBUG */
 err_out:
 	return ret;
 }
@@ -1679,7 +1716,8 @@ static int ntfs_mft_data_extend_allocati
 {
 	LCN lcn;
 	VCN old_last_vcn;
-	s64 min_nr, nr, ll = 0;
+	s64 min_nr, nr, ll;
+	unsigned long flags;
 	ntfs_inode *mft_ni;
 	runlist_element *rl, *rl2;
 	ntfs_attr_search_ctx *ctx = NULL;
@@ -1695,23 +1733,25 @@ static int ntfs_mft_data_extend_allocati
 	 * Determine the preferred allocation location, i.e. the last lcn of
 	 * the mft data attribute.  The allocated size of the mft data
 	 * attribute cannot be zero so we are ok to do this.
-	 * ntfs_find_vcn() returns the runlist locked on success.
 	 */
-	rl = ntfs_find_vcn(mft_ni, (mft_ni->allocated_size - 1) >>
-			vol->cluster_size_bits, TRUE);
+	down_write(&mft_ni->runlist.lock);
+	read_lock_irqsave(&mft_ni->size_lock, flags);
+	ll = mft_ni->allocated_size;
+	read_unlock_irqrestore(&mft_ni->size_lock, flags);
+	rl = ntfs_attr_find_vcn_nolock(mft_ni,
+			(ll - 1) >> vol->cluster_size_bits, TRUE);
 	if (unlikely(IS_ERR(rl) || !rl->length || rl->lcn < 0)) {
+		up_write(&mft_ni->runlist.lock);
 		ntfs_error(vol->sb, "Failed to determine last allocated "
 				"cluster of mft data attribute.");
-		if (!IS_ERR(rl)) {
-			up_write(&mft_ni->runlist.lock);
+		if (!IS_ERR(rl))
 			ret = -EIO;
-		} else
+		else
 			ret = PTR_ERR(rl);
 		return ret;
 	}
 	lcn = rl->lcn + rl->length;
-	ntfs_debug("Last lcn of mft data attribute is 0x%llx.",
-			(long long)lcn);
+	ntfs_debug("Last lcn of mft data attribute is 0x%llx.", (long long)lcn);
 	/* Minimum allocation is one mft record worth of clusters. */
 	min_nr = vol->mft_record_size >> vol->cluster_size_bits;
 	if (!min_nr)
@@ -1721,12 +1761,13 @@ static int ntfs_mft_data_extend_allocati
 	if (!nr)
 		nr = min_nr;
 	/* Ensure we do not go above 2^32-1 mft records. */
-	if (unlikely((mft_ni->allocated_size +
-			(nr << vol->cluster_size_bits)) >>
+	read_lock_irqsave(&mft_ni->size_lock, flags);
+	ll = mft_ni->allocated_size;
+	read_unlock_irqrestore(&mft_ni->size_lock, flags);
+	if (unlikely((ll + (nr << vol->cluster_size_bits)) >>
 			vol->mft_record_size_bits >= (1ll << 32))) {
 		nr = min_nr;
-		if (unlikely((mft_ni->allocated_size +
-				(nr << vol->cluster_size_bits)) >>
+		if (unlikely((ll + (nr << vol->cluster_size_bits)) >>
 				vol->mft_record_size_bits >= (1ll << 32))) {
 			ntfs_warning(vol->sb, "Cannot allocate mft record "
 					"because the maximum number of inodes "
@@ -1772,7 +1813,7 @@ static int ntfs_mft_data_extend_allocati
 		return PTR_ERR(rl);
 	}
 	mft_ni->runlist.rl = rl;
-	ntfs_debug("Allocated %lli clusters.", nr);
+	ntfs_debug("Allocated %lli clusters.", (long long)nr);
 	/* Find the last run in the new runlist. */
 	for (; rl[1].length; rl++)
 		;
@@ -1808,7 +1849,7 @@ static int ntfs_mft_data_extend_allocati
 	BUG_ON(ll < rl2->vcn);
 	BUG_ON(ll >= rl2->vcn + rl2->length);
 	/* Get the size for the new mapping pairs array for this extent. */
-	mp_size = ntfs_get_size_for_mapping_pairs(vol, rl2, ll);
+	mp_size = ntfs_get_size_for_mapping_pairs(vol, rl2, ll, -1);
 	if (unlikely(mp_size <= 0)) {
 		ntfs_error(vol->sb, "Get size for mapping pairs failed for "
 				"mft data attribute extent.");
@@ -1832,7 +1873,11 @@ static int ntfs_mft_data_extend_allocati
 		// moving other attributes out of this mft record.
 		// Note: Use the special reserved mft records and ensure that
 		// this extent is not required to find the mft record in
-		// question.
+		// question.  If no free special records left we would need to
+		// move an existing record away, insert ours in its place, and
+		// then place the moved record into the newly allocated space
+		// and we would then need to update all references to this mft
+		// record appropriately.  This is rather complicated...
 		ntfs_error(vol->sb, "Not enough space in this mft record to "
 				"accomodate extended mft data attribute "
 				"extent.  Cannot handle this yet.");
@@ -1843,7 +1888,7 @@ static int ntfs_mft_data_extend_allocati
 	/* Generate the mapping pairs array directly into the attr record. */
 	ret = ntfs_mapping_pairs_build(vol, (u8*)a +
 			le16_to_cpu(a->data.non_resident.mapping_pairs_offset),
-			mp_size, rl2, ll, NULL);
+			mp_size, rl2, ll, -1, NULL);
 	if (unlikely(ret)) {
 		ntfs_error(vol->sb, "Failed to build mapping pairs array of "
 				"mft data attribute.");
@@ -1875,9 +1920,11 @@ static int ntfs_mft_data_extend_allocati
 		}
 		a = ctx->attr;
 	}
+	write_lock_irqsave(&mft_ni->size_lock, flags);
 	mft_ni->allocated_size += nr << vol->cluster_size_bits;
 	a->data.non_resident.allocated_size =
 			cpu_to_sle64(mft_ni->allocated_size);
+	write_unlock_irqrestore(&mft_ni->size_lock, flags);
 	/* Ensure the changes make it to disk. */
 	flush_dcache_mft_record_page(ctx->ntfs_ino);
 	mark_mft_record_dirty(ctx->ntfs_ino);
@@ -1892,7 +1939,9 @@ restore_undo_alloc:
 			CASE_SENSITIVE, rl[1].vcn, NULL, 0, ctx)) {
 		ntfs_error(vol->sb, "Failed to find last attribute extent of "
 				"mft data attribute.%s", es);
+		write_lock_irqsave(&mft_ni->size_lock, flags);
 		mft_ni->allocated_size += nr << vol->cluster_size_bits;
+		write_unlock_irqrestore(&mft_ni->size_lock, flags);
 		ntfs_attr_put_search_ctx(ctx);
 		unmap_mft_record(mft_ni);
 		up_write(&mft_ni->runlist.lock);
@@ -1921,7 +1970,7 @@ undo_alloc:
 				a->data.non_resident.mapping_pairs_offset),
 				old_alen - le16_to_cpu(
 				a->data.non_resident.mapping_pairs_offset),
-				rl2, ll, NULL)) {
+				rl2, ll, -1, NULL)) {
 			ntfs_error(vol->sb, "Failed to restore mapping pairs "
 					"array.%s", es);
 			NVolSetErrors(vol);
@@ -1991,7 +2040,7 @@ static int ntfs_mft_record_layout(const 
 				"reports this as corruption, please email "
 				"linux-ntfs-dev@lists.sourceforge.net stating "
 				"that you saw this message and that the "
-				"modified file system created was corrupt.  "
+				"modified filesystem created was corrupt.  "
 				"Thank you.");
 	}
 	/* Set the update sequence number to 1. */
@@ -2036,6 +2085,7 @@ static int ntfs_mft_record_layout(const 
  */
 static int ntfs_mft_record_format(const ntfs_volume *vol, const s64 mft_no)
 {
+	loff_t i_size;
 	struct inode *mft_vi = vol->mft_ino;
 	struct page *page;
 	MFT_RECORD *m;
@@ -2051,10 +2101,11 @@ static int ntfs_mft_record_format(const 
 	index = mft_no << vol->mft_record_size_bits >> PAGE_CACHE_SHIFT;
 	ofs = (mft_no << vol->mft_record_size_bits) & ~PAGE_CACHE_MASK;
 	/* The maximum valid index into the page cache for $MFT's data. */
-	end_index = mft_vi->i_size >> PAGE_CACHE_SHIFT;
+	i_size = i_size_read(mft_vi);
+	end_index = i_size >> PAGE_CACHE_SHIFT;
 	if (unlikely(index >= end_index)) {
 		if (unlikely(index > end_index || ofs + vol->mft_record_size >=
-				(mft_vi->i_size & ~PAGE_CACHE_MASK))) {
+				(i_size & ~PAGE_CACHE_MASK))) {
 			ntfs_error(vol->sb, "Tried to format non-existing mft "
 					"record 0x%llx.", (long long)mft_no);
 			return -ENOENT;
@@ -2188,6 +2239,7 @@ ntfs_inode *ntfs_mft_record_alloc(ntfs_v
 		ntfs_inode *base_ni, MFT_RECORD **mrec)
 {
 	s64 ll, bit, old_data_initialized, old_data_size;
+	unsigned long flags;
 	struct inode *vi;
 	struct page *page;
 	ntfs_inode *mft_ni, *mftbmp_ni, *ni;
@@ -2237,9 +2289,13 @@ ntfs_inode *ntfs_mft_record_alloc(ntfs_v
 	 * the first 24 mft records as they are special and whilst they may not
 	 * be in use, we do not allocate from them.
 	 */
+	read_lock_irqsave(&mft_ni->size_lock, flags);
 	ll = mft_ni->initialized_size >> vol->mft_record_size_bits;
-	if (mftbmp_ni->initialized_size << 3 > ll &&
-			mftbmp_ni->initialized_size > 3) {
+	read_unlock_irqrestore(&mft_ni->size_lock, flags);
+	read_lock_irqsave(&mftbmp_ni->size_lock, flags);
+	old_data_initialized = mftbmp_ni->initialized_size;
+	read_unlock_irqrestore(&mftbmp_ni->size_lock, flags);
+	if (old_data_initialized << 3 > ll && old_data_initialized > 3) {
 		bit = ll;
 		if (bit < 24)
 			bit = 24;
@@ -2254,15 +2310,18 @@ ntfs_inode *ntfs_mft_record_alloc(ntfs_v
 	 * mft record that we can allocate.
 	 * Note: The smallest mft record we allocate is mft record 24.
 	 */
-	bit = mftbmp_ni->initialized_size << 3;
+	bit = old_data_initialized << 3;
 	if (unlikely(bit >= (1ll << 32)))
 		goto max_err_out;
+	read_lock_irqsave(&mftbmp_ni->size_lock, flags);
+	old_data_size = mftbmp_ni->allocated_size;
 	ntfs_debug("Status of mftbmp before extension: allocated_size 0x%llx, "
 			"data_size 0x%llx, initialized_size 0x%llx.",
-			(long long)mftbmp_ni->allocated_size,
-			(long long)vol->mftbmp_ino->i_size,
-			(long long)mftbmp_ni->initialized_size);
-	if (mftbmp_ni->initialized_size + 8 > mftbmp_ni->allocated_size) {
+			(long long)old_data_size,
+			(long long)i_size_read(vol->mftbmp_ino),
+			(long long)old_data_initialized);
+	read_unlock_irqrestore(&mftbmp_ni->size_lock, flags);
+	if (old_data_initialized + 8 > old_data_size) {
 		/* Need to extend bitmap by one more cluster. */
 		ntfs_debug("mftbmp: initialized_size + 8 > allocated_size.");
 		err = ntfs_mft_bitmap_extend_allocation_nolock(vol);
@@ -2270,12 +2329,16 @@ ntfs_inode *ntfs_mft_record_alloc(ntfs_v
 			up_write(&vol->mftbmp_lock);
 			goto err_out;
 		}
+#ifdef DEBUG
+		read_lock_irqsave(&mftbmp_ni->size_lock, flags);
 		ntfs_debug("Status of mftbmp after allocation extension: "
 				"allocated_size 0x%llx, data_size 0x%llx, "
 				"initialized_size 0x%llx.",
 				(long long)mftbmp_ni->allocated_size,
-				(long long)vol->mftbmp_ino->i_size,
+				(long long)i_size_read(vol->mftbmp_ino),
 				(long long)mftbmp_ni->initialized_size);
+		read_unlock_irqrestore(&mftbmp_ni->size_lock, flags);
+#endif /* DEBUG */
 	}
 	/*
 	 * We now have sufficient allocated space, extend the initialized_size
@@ -2287,12 +2350,16 @@ ntfs_inode *ntfs_mft_record_alloc(ntfs_v
 		up_write(&vol->mftbmp_lock);
 		goto err_out;
 	}
+#ifdef DEBUG
+	read_lock_irqsave(&mftbmp_ni->size_lock, flags);
 	ntfs_debug("Status of mftbmp after initialized extention: "
 			"allocated_size 0x%llx, data_size 0x%llx, "
 			"initialized_size 0x%llx.",
 			(long long)mftbmp_ni->allocated_size,
-			(long long)vol->mftbmp_ino->i_size,
+			(long long)i_size_read(vol->mftbmp_ino),
 			(long long)mftbmp_ni->initialized_size);
+	read_unlock_irqrestore(&mftbmp_ni->size_lock, flags);
+#endif /* DEBUG */
 	ntfs_debug("Found free record (#3), bit 0x%llx.", (long long)bit);
 found_free_rec:
 	/* @bit is the found free mft record, allocate it in the mft bitmap. */
@@ -2314,7 +2381,10 @@ have_alloc_rec:
 	 * parallel allocation could allocate the same mft record as this one.
 	 */
 	ll = (bit + 1) << vol->mft_record_size_bits;
-	if (ll <= mft_ni->initialized_size) {
+	read_lock_irqsave(&mft_ni->size_lock, flags);
+	old_data_initialized = mft_ni->initialized_size;
+	read_unlock_irqrestore(&mft_ni->size_lock, flags);
+	if (ll <= old_data_initialized) {
 		ntfs_debug("Allocated mft record already initialized.");
 		goto mft_rec_already_initialized;
 	}
@@ -2325,26 +2395,30 @@ have_alloc_rec:
 	 * actually traversed more than once when a freshly formatted volume is
 	 * first written to so it optimizes away nicely in the common case.
 	 */
+	read_lock_irqsave(&mft_ni->size_lock, flags);
 	ntfs_debug("Status of mft data before extension: "
 			"allocated_size 0x%llx, data_size 0x%llx, "
 			"initialized_size 0x%llx.",
 			(long long)mft_ni->allocated_size,
-			(long long)vol->mft_ino->i_size,
+			(long long)i_size_read(vol->mft_ino),
 			(long long)mft_ni->initialized_size);
 	while (ll > mft_ni->allocated_size) {
+		read_unlock_irqrestore(&mft_ni->size_lock, flags);
 		err = ntfs_mft_data_extend_allocation_nolock(vol);
 		if (unlikely(err)) {
 			ntfs_error(vol->sb, "Failed to extend mft data "
 					"allocation.");
 			goto undo_mftbmp_alloc_nolock;
 		}
+		read_lock_irqsave(&mft_ni->size_lock, flags);
 		ntfs_debug("Status of mft data after allocation extension: "
 				"allocated_size 0x%llx, data_size 0x%llx, "
 				"initialized_size 0x%llx.",
 				(long long)mft_ni->allocated_size,
-				(long long)vol->mft_ino->i_size,
+				(long long)i_size_read(vol->mft_ino),
 				(long long)mft_ni->initialized_size);
 	}
+	read_unlock_irqrestore(&mft_ni->size_lock, flags);
 	/*
 	 * Extend mft data initialized size (and data size of course) to reach
 	 * the allocated mft record, formatting the mft records allong the way.
@@ -2352,6 +2426,7 @@ have_alloc_rec:
 	 * needed by ntfs_mft_record_format().  We will update the attribute
 	 * record itself in one fell swoop later on.
 	 */
+	write_lock_irqsave(&mft_ni->size_lock, flags);
 	old_data_initialized = mft_ni->initialized_size;
 	old_data_size = vol->mft_ino->i_size;
 	while (ll > mft_ni->initialized_size) {
@@ -2360,8 +2435,9 @@ have_alloc_rec:
 		new_initialized_size = mft_ni->initialized_size +
 				vol->mft_record_size;
 		mft_no = mft_ni->initialized_size >> vol->mft_record_size_bits;
-		if (new_initialized_size > vol->mft_ino->i_size)
-			vol->mft_ino->i_size = new_initialized_size;
+		if (new_initialized_size > i_size_read(vol->mft_ino))
+			i_size_write(vol->mft_ino, new_initialized_size);
+		write_unlock_irqrestore(&mft_ni->size_lock, flags);
 		ntfs_debug("Initializing mft record 0x%llx.",
 				(long long)mft_no);
 		err = ntfs_mft_record_format(vol, mft_no);
@@ -2369,8 +2445,10 @@ have_alloc_rec:
 			ntfs_error(vol->sb, "Failed to format mft record.");
 			goto undo_data_init;
 		}
+		write_lock_irqsave(&mft_ni->size_lock, flags);
 		mft_ni->initialized_size = new_initialized_size;
 	}
+	write_unlock_irqrestore(&mft_ni->size_lock, flags);
 	record_formatted = TRUE;
 	/* Update the mft data attribute record to reflect the new sizes. */
 	m = map_mft_record(mft_ni);
@@ -2396,22 +2474,27 @@ have_alloc_rec:
 		goto undo_data_init;
 	}
 	a = ctx->attr;
+	read_lock_irqsave(&mft_ni->size_lock, flags);
 	a->data.non_resident.initialized_size =
 			cpu_to_sle64(mft_ni->initialized_size);
-	a->data.non_resident.data_size = cpu_to_sle64(vol->mft_ino->i_size);
+	a->data.non_resident.data_size =
+			cpu_to_sle64(i_size_read(vol->mft_ino));
+	read_unlock_irqrestore(&mft_ni->size_lock, flags);
 	/* Ensure the changes make it to disk. */
 	flush_dcache_mft_record_page(ctx->ntfs_ino);
 	mark_mft_record_dirty(ctx->ntfs_ino);
 	ntfs_attr_put_search_ctx(ctx);
 	unmap_mft_record(mft_ni);
+	read_lock_irqsave(&mft_ni->size_lock, flags);
 	ntfs_debug("Status of mft data after mft record initialization: "
 			"allocated_size 0x%llx, data_size 0x%llx, "
 			"initialized_size 0x%llx.",
 			(long long)mft_ni->allocated_size,
-			(long long)vol->mft_ino->i_size,
+			(long long)i_size_read(vol->mft_ino),
 			(long long)mft_ni->initialized_size);
-	BUG_ON(vol->mft_ino->i_size > mft_ni->allocated_size);
-	BUG_ON(mft_ni->initialized_size > vol->mft_ino->i_size);
+	BUG_ON(i_size_read(vol->mft_ino) > mft_ni->allocated_size);
+	BUG_ON(mft_ni->initialized_size > i_size_read(vol->mft_ino));
+	read_unlock_irqrestore(&mft_ni->size_lock, flags);
 mft_rec_already_initialized:
 	/*
 	 * We can finally drop the mft bitmap lock as the mft data attribute
@@ -2652,8 +2735,10 @@ mft_rec_already_initialized:
 	*mrec = m;
 	return ni;
 undo_data_init:
+	write_lock_irqsave(&mft_ni->size_lock, flags);
 	mft_ni->initialized_size = old_data_initialized;
-	vol->mft_ino->i_size = old_data_size;
+	i_size_write(vol->mft_ino, old_data_size);
+	write_unlock_irqrestore(&mft_ni->size_lock, flags);
 	goto undo_mftbmp_alloc_nolock;
 undo_mftbmp_alloc:
 	down_write(&vol->mftbmp_lock);
diff --git a/fs/ntfs/namei.c b/fs/ntfs/namei.c
--- a/fs/ntfs/namei.c
+++ b/fs/ntfs/namei.c
@@ -153,8 +153,7 @@ static struct dentry *ntfs_lookup(struct
 			ntfs_error(vol->sb, "ntfs_iget(0x%lx) failed with "
 					"error code %li.", dent_ino,
 					PTR_ERR(dent_inode));
-		if (name)
-			kfree(name);
+		kfree(name);
 		/* Return the error code. */
 		return (struct dentry *)dent_inode;
 	}
@@ -380,7 +379,7 @@ struct inode_operations ntfs_dir_inode_o
  * Return the dentry of the parent directory on success or the error code on
  * error (IS_ERR() is true).
  */
-struct dentry *ntfs_get_parent(struct dentry *child_dent)
+static struct dentry *ntfs_get_parent(struct dentry *child_dent)
 {
 	struct inode *vi = child_dent->d_inode;
 	ntfs_inode *ni = NTFS_I(vi);
@@ -465,7 +464,7 @@ try_next:
  *
  * Return the dentry on success or the error code on error (IS_ERR() is true).
  */
-struct dentry *ntfs_get_dentry(struct super_block *sb, void *fh)
+static struct dentry *ntfs_get_dentry(struct super_block *sb, void *fh)
 {
 	struct inode *vi;
 	struct dentry *dent;
@@ -496,3 +495,30 @@ struct dentry *ntfs_get_dentry(struct su
 	ntfs_debug("Done for inode 0x%lx, generation 0x%x.", ino, gen);
 	return dent;
 }
+
+/**
+ * Export operations allowing NFS exporting of mounted NTFS partitions.
+ *
+ * We use the default ->decode_fh() and ->encode_fh() for now.  Note that they
+ * use 32 bits to store the inode number which is an unsigned long so on 64-bit
+ * architectures is usually 64 bits so it would all fail horribly on huge
+ * volumes.  I guess we need to define our own encode and decode fh functions
+ * that store 64-bit inode numbers at some point but for now we will ignore the
+ * problem...
+ *
+ * We also use the default ->get_name() helper (used by ->decode_fh() via
+ * fs/exportfs/expfs.c::find_exported_dentry()) as that is completely fs
+ * independent.
+ *
+ * The default ->get_parent() just returns -EACCES so we have to provide our
+ * own and the default ->get_dentry() is incompatible with NTFS due to not
+ * allowing the inode number 0 which is used in NTFS for the system file $MFT
+ * and due to using iget() whereas NTFS needs ntfs_iget().
+ */
+struct export_operations ntfs_export_ops = {
+	.get_parent	= ntfs_get_parent,	/* Find the parent of a given
+						   directory. */
+	.get_dentry	= ntfs_get_dentry,	/* Find a dentry for the inode
+						   given a file handle
+						   sub-fragment. */
+};
diff --git a/fs/ntfs/ntfs.h b/fs/ntfs/ntfs.h
--- a/fs/ntfs/ntfs.h
+++ b/fs/ntfs/ntfs.h
@@ -2,7 +2,7 @@
  * ntfs.h - Defines for NTFS Linux kernel driver. Part of the Linux-NTFS
  *	    project.
  *
- * Copyright (c) 2001-2004 Anton Altaparmakov
+ * Copyright (c) 2001-2005 Anton Altaparmakov
  * Copyright (C) 2002 Richard Russon
  *
  * This program/include file is free software; you can redistribute it and/or
@@ -31,6 +31,7 @@
 #include <linux/fs.h>
 #include <linux/nls.h>
 #include <linux/smp.h>
+#include <linux/pagemap.h>
 
 #include "types.h"
 #include "volume.h"
@@ -41,6 +42,9 @@ typedef enum {
 	NTFS_BLOCK_SIZE_BITS	= 9,
 	NTFS_SB_MAGIC		= 0x5346544e,	/* 'NTFS' */
 	NTFS_MAX_NAME_LEN	= 255,
+	NTFS_MAX_ATTR_NAME_LEN	= 255,
+	NTFS_MAX_CLUSTER_SIZE	= 64 * 1024,	/* 64kiB */
+	NTFS_MAX_PAGES_PER_CLUSTER = NTFS_MAX_CLUSTER_SIZE / PAGE_CACHE_SIZE,
 } NTFS_CONSTANTS;
 
 /* Global variables. */
@@ -65,6 +69,8 @@ extern struct inode_operations ntfs_dir_
 extern struct  file_operations ntfs_empty_file_ops;
 extern struct inode_operations ntfs_empty_inode_ops;
 
+extern struct export_operations ntfs_export_ops;
+
 /**
  * NTFS_SB - return the ntfs volume given a vfs super block
  * @sb:		VFS super block
diff --git a/fs/ntfs/runlist.c b/fs/ntfs/runlist.c
--- a/fs/ntfs/runlist.c
+++ b/fs/ntfs/runlist.c
@@ -1,7 +1,7 @@
 /**
  * runlist.c - NTFS runlist handling code.  Part of the Linux-NTFS project.
  *
- * Copyright (c) 2001-2004 Anton Altaparmakov
+ * Copyright (c) 2001-2005 Anton Altaparmakov
  * Copyright (c) 2002 Richard Russon
  *
  * This program/include file is free software; you can redistribute it and/or
@@ -59,7 +59,7 @@ static inline void ntfs_rl_mc(runlist_el
  *
  * As the runlists grow, more memory will be required.  To prevent the
  * kernel having to allocate and reallocate large numbers of small bits of
- * memory, this function returns and entire page of memory.
+ * memory, this function returns an entire page of memory.
  *
  * It is up to the caller to serialize access to the runlist @rl.
  *
@@ -113,8 +113,11 @@ static inline BOOL ntfs_are_rl_mergeable
 	BUG_ON(!dst);
 	BUG_ON(!src);
 
-	if ((dst->lcn < 0) || (src->lcn < 0))     /* Are we merging holes? */
+	if ((dst->lcn < 0) || (src->lcn < 0)) {   /* Are we merging holes? */
+		if (dst->lcn == LCN_HOLE && src->lcn == LCN_HOLE)
+			return TRUE;
 		return FALSE;
+	}
 	if ((dst->lcn + dst->length) != src->lcn) /* Are the runs contiguous? */
 		return FALSE;
 	if ((dst->vcn + dst->length) != src->vcn) /* Are the runs misaligned? */
@@ -855,30 +858,42 @@ mpa_err:
 	if (!attr->data.non_resident.lowest_vcn) {
 		VCN max_cluster;
 
-		max_cluster = (sle64_to_cpu(
+		max_cluster = ((sle64_to_cpu(
 				attr->data.non_resident.allocated_size) +
 				vol->cluster_size - 1) >>
-				vol->cluster_size_bits;
+				vol->cluster_size_bits) - 1;
 		/*
-		 * If there is a difference between the highest_vcn and the
-		 * highest cluster, the runlist is either corrupt or, more
-		 * likely, there are more extents following this one.
+		 * A highest_vcn of zero means this is a single extent
+		 * attribute so simply terminate the runlist with LCN_ENOENT).
 		 */
-		if (deltaxcn < --max_cluster) {
-			ntfs_debug("More extents to follow; deltaxcn = 0x%llx, "
-					"max_cluster = 0x%llx",
-					(unsigned long long)deltaxcn,
-					(unsigned long long)max_cluster);
-			rl[rlpos].vcn = vcn;
-			vcn += rl[rlpos].length = max_cluster - deltaxcn;
-			rl[rlpos].lcn = LCN_RL_NOT_MAPPED;
-			rlpos++;
-		} else if (unlikely(deltaxcn > max_cluster)) {
-			ntfs_error(vol->sb, "Corrupt attribute. deltaxcn = "
-					"0x%llx, max_cluster = 0x%llx",
-					(unsigned long long)deltaxcn,
-					(unsigned long long)max_cluster);
-			goto mpa_err;
+		if (deltaxcn) {
+			/*
+			 * If there is a difference between the highest_vcn and
+			 * the highest cluster, the runlist is either corrupt
+			 * or, more likely, there are more extents following
+			 * this one.
+			 */
+			if (deltaxcn < max_cluster) {
+				ntfs_debug("More extents to follow; deltaxcn "
+						"= 0x%llx, max_cluster = "
+						"0x%llx",
+						(unsigned long long)deltaxcn,
+						(unsigned long long)
+						max_cluster);
+				rl[rlpos].vcn = vcn;
+				vcn += rl[rlpos].length = max_cluster -
+						deltaxcn;
+				rl[rlpos].lcn = LCN_RL_NOT_MAPPED;
+				rlpos++;
+			} else if (unlikely(deltaxcn > max_cluster)) {
+				ntfs_error(vol->sb, "Corrupt attribute.  "
+						"deltaxcn = 0x%llx, "
+						"max_cluster = 0x%llx",
+						(unsigned long long)deltaxcn,
+						(unsigned long long)
+						max_cluster);
+				goto mpa_err;
+			}
 		}
 		rl[rlpos].lcn = LCN_ENOENT;
 	} else /* Not the base extent. There may be more extents to follow. */
@@ -918,17 +933,18 @@ err_out:
  *
  * It is up to the caller to serialize access to the runlist @rl.
  *
- * Since lcns must be >= 0, we use negative return values with special meaning:
+ * Since lcns must be >= 0, we use negative return codes with special meaning:
  *
- * Return value			Meaning / Description
+ * Return code		Meaning / Description
  * ==================================================
- *  -1 = LCN_HOLE		Hole / not allocated on disk.
- *  -2 = LCN_RL_NOT_MAPPED	This is part of the runlist which has not been
- *				inserted into the runlist yet.
- *  -3 = LCN_ENOENT		There is no such vcn in the attribute.
+ *  LCN_HOLE		Hole / not allocated on disk.
+ *  LCN_RL_NOT_MAPPED	This is part of the runlist which has not been
+ *			inserted into the runlist yet.
+ *  LCN_ENOENT		There is no such vcn in the attribute.
  *
  * Locking: - The caller must have locked the runlist (for reading or writing).
- *	    - This function does not touch the lock.
+ *	    - This function does not touch the lock, nor does it modify the
+ *	      runlist.
  */
 LCN ntfs_rl_vcn_to_lcn(const runlist_element *rl, const VCN vcn)
 {
@@ -964,6 +980,39 @@ LCN ntfs_rl_vcn_to_lcn(const runlist_ele
 	return LCN_ENOENT;
 }
 
+#ifdef NTFS_RW
+
+/**
+ * ntfs_rl_find_vcn_nolock - find a vcn in a runlist
+ * @rl:		runlist to search
+ * @vcn:	vcn to find
+ *
+ * Find the virtual cluster number @vcn in the runlist @rl and return the
+ * address of the runlist element containing the @vcn on success.
+ *
+ * Return NULL if @rl is NULL or @vcn is in an unmapped part/out of bounds of
+ * the runlist.
+ *
+ * Locking: The runlist must be locked on entry.
+ */
+runlist_element *ntfs_rl_find_vcn_nolock(runlist_element *rl, const VCN vcn)
+{
+	BUG_ON(vcn < 0);
+	if (unlikely(!rl || vcn < rl[0].vcn))
+		return NULL;
+	while (likely(rl->length)) {
+		if (unlikely(vcn < rl[1].vcn)) {
+			if (likely(rl->lcn >= LCN_HOLE))
+				return rl;
+			return NULL;
+		}
+		rl++;
+	}
+	if (likely(rl->lcn == LCN_ENOENT))
+		return rl;
+	return NULL;
+}
+
 /**
  * ntfs_get_nr_significant_bytes - get number of bytes needed to store a number
  * @n:		number for which to get the number of bytes for
@@ -999,10 +1048,17 @@ static inline int ntfs_get_nr_significan
  * ntfs_get_size_for_mapping_pairs - get bytes needed for mapping pairs array
  * @vol:	ntfs volume (needed for the ntfs version)
  * @rl:		locked runlist to determine the size of the mapping pairs of
- * @start_vcn:	vcn at which to start the mapping pairs array
+ * @first_vcn:	first vcn which to include in the mapping pairs array
+ * @last_vcn:	last vcn which to include in the mapping pairs array
  *
  * Walk the locked runlist @rl and calculate the size in bytes of the mapping
- * pairs array corresponding to the runlist @rl, starting at vcn @start_vcn.
+ * pairs array corresponding to the runlist @rl, starting at vcn @first_vcn and
+ * finishing with vcn @last_vcn.
+ *
+ * A @last_vcn of -1 means end of runlist and in that case the size of the
+ * mapping pairs array corresponding to the runlist starting at vcn @first_vcn
+ * and finishing at the end of the runlist is determined.
+ *
  * This for example allows us to allocate a buffer of the right size when
  * building the mapping pairs array.
  *
@@ -1018,34 +1074,50 @@ static inline int ntfs_get_nr_significan
  *	    remains locked throughout, and is left locked upon return.
  */
 int ntfs_get_size_for_mapping_pairs(const ntfs_volume *vol,
-		const runlist_element *rl, const VCN start_vcn)
+		const runlist_element *rl, const VCN first_vcn,
+		const VCN last_vcn)
 {
 	LCN prev_lcn;
 	int rls;
+	BOOL the_end = FALSE;
 
-	BUG_ON(start_vcn < 0);
+	BUG_ON(first_vcn < 0);
+	BUG_ON(last_vcn < -1);
+	BUG_ON(last_vcn >= 0 && first_vcn > last_vcn);
 	if (!rl) {
-		BUG_ON(start_vcn);
+		BUG_ON(first_vcn);
+		BUG_ON(last_vcn > 0);
 		return 1;
 	}
-	/* Skip to runlist element containing @start_vcn. */
-	while (rl->length && start_vcn >= rl[1].vcn)
+	/* Skip to runlist element containing @first_vcn. */
+	while (rl->length && first_vcn >= rl[1].vcn)
 		rl++;
-	if ((!rl->length && start_vcn > rl->vcn) || start_vcn < rl->vcn)
+	if (unlikely((!rl->length && first_vcn > rl->vcn) ||
+			first_vcn < rl->vcn))
 		return -EINVAL;
 	prev_lcn = 0;
 	/* Always need the termining zero byte. */
 	rls = 1;
 	/* Do the first partial run if present. */
-	if (start_vcn > rl->vcn) {
-		s64 delta;
+	if (first_vcn > rl->vcn) {
+		s64 delta, length = rl->length;
 
 		/* We know rl->length != 0 already. */
-		if (rl->length < 0 || rl->lcn < LCN_HOLE)
+		if (unlikely(length < 0 || rl->lcn < LCN_HOLE))
 			goto err_out;
-		delta = start_vcn - rl->vcn;
+		/*
+		 * If @stop_vcn is given and finishes inside this run, cap the
+		 * run length.
+		 */
+		if (unlikely(last_vcn >= 0 && rl[1].vcn > last_vcn)) {
+			s64 s1 = last_vcn + 1;
+			if (unlikely(rl[1].vcn > s1))
+				length = s1 - rl->vcn;
+			the_end = TRUE;
+		}
+		delta = first_vcn - rl->vcn;
 		/* Header byte + length. */
-		rls += 1 + ntfs_get_nr_significant_bytes(rl->length - delta);
+		rls += 1 + ntfs_get_nr_significant_bytes(length - delta);
 		/*
 		 * If the logical cluster number (lcn) denotes a hole and we
 		 * are on NTFS 3.0+, we don't store it at all, i.e. we need
@@ -1053,9 +1125,9 @@ int ntfs_get_size_for_mapping_pairs(cons
 		 * Note: this assumes that on NTFS 1.2-, holes are stored with
 		 * an lcn of -1 and not a delta_lcn of -1 (unless both are -1).
 		 */
-		if (rl->lcn >= 0 || vol->major_ver < 3) {
+		if (likely(rl->lcn >= 0 || vol->major_ver < 3)) {
 			prev_lcn = rl->lcn;
-			if (rl->lcn >= 0)
+			if (likely(rl->lcn >= 0))
 				prev_lcn += delta;
 			/* Change in lcn. */
 			rls += ntfs_get_nr_significant_bytes(prev_lcn);
@@ -1064,11 +1136,23 @@ int ntfs_get_size_for_mapping_pairs(cons
 		rl++;
 	}
 	/* Do the full runs. */
-	for (; rl->length; rl++) {
-		if (rl->length < 0 || rl->lcn < LCN_HOLE)
+	for (; rl->length && !the_end; rl++) {
+		s64 length = rl->length;
+
+		if (unlikely(length < 0 || rl->lcn < LCN_HOLE))
 			goto err_out;
+		/*
+		 * If @stop_vcn is given and finishes inside this run, cap the
+		 * run length.
+		 */
+		if (unlikely(last_vcn >= 0 && rl[1].vcn > last_vcn)) {
+			s64 s1 = last_vcn + 1;
+			if (unlikely(rl[1].vcn > s1))
+				length = s1 - rl->vcn;
+			the_end = TRUE;
+		}
 		/* Header byte + length. */
-		rls += 1 + ntfs_get_nr_significant_bytes(rl->length);
+		rls += 1 + ntfs_get_nr_significant_bytes(length);
 		/*
 		 * If the logical cluster number (lcn) denotes a hole and we
 		 * are on NTFS 3.0+, we don't store it at all, i.e. we need
@@ -1076,7 +1160,7 @@ int ntfs_get_size_for_mapping_pairs(cons
 		 * Note: this assumes that on NTFS 1.2-, holes are stored with
 		 * an lcn of -1 and not a delta_lcn of -1 (unless both are -1).
 		 */
-		if (rl->lcn >= 0 || vol->major_ver < 3) {
+		if (likely(rl->lcn >= 0 || vol->major_ver < 3)) {
 			/* Change in lcn. */
 			rls += ntfs_get_nr_significant_bytes(rl->lcn -
 					prev_lcn);
@@ -1119,7 +1203,7 @@ static inline int ntfs_write_significant
 
 	i = 0;
 	do {
-		if (dst > dst_max)
+		if (unlikely(dst > dst_max))
 			goto err_out;
 		*dst++ = l & 0xffll;
 		l >>= 8;
@@ -1128,12 +1212,12 @@ static inline int ntfs_write_significant
 	j = (n >> 8 * (i - 1)) & 0xff;
 	/* If the sign bit is wrong, we need an extra byte. */
 	if (n < 0 && j >= 0) {
-		if (dst > dst_max)
+		if (unlikely(dst > dst_max))
 			goto err_out;
 		i++;
 		*dst = (s8)-1;
 	} else if (n > 0 && j < 0) {
-		if (dst > dst_max)
+		if (unlikely(dst > dst_max))
 			goto err_out;
 		i++;
 		*dst = (s8)0;
@@ -1149,13 +1233,18 @@ err_out:
  * @dst:	destination buffer to which to write the mapping pairs array
  * @dst_len:	size of destination buffer @dst in bytes
  * @rl:		locked runlist for which to build the mapping pairs array
- * @start_vcn:	vcn at which to start the mapping pairs array
+ * @first_vcn:	first vcn which to include in the mapping pairs array
+ * @last_vcn:	last vcn which to include in the mapping pairs array
  * @stop_vcn:	first vcn outside destination buffer on success or -ENOSPC
  *
  * Create the mapping pairs array from the locked runlist @rl, starting at vcn
- * @start_vcn and save the array in @dst.  @dst_len is the size of @dst in
- * bytes and it should be at least equal to the value obtained by calling
- * ntfs_get_size_for_mapping_pairs().
+ * @first_vcn and finishing with vcn @last_vcn and save the array in @dst.
+ * @dst_len is the size of @dst in bytes and it should be at least equal to the
+ * value obtained by calling ntfs_get_size_for_mapping_pairs().
+ *
+ * A @last_vcn of -1 means end of runlist and in that case the mapping pairs
+ * array corresponding to the runlist starting at vcn @first_vcn and finishing
+ * at the end of the runlist is created.
  *
  * If @rl is NULL, just write a single terminator byte to @dst.
  *
@@ -1164,7 +1253,7 @@ err_out:
  * been filled with all the mapping pairs that will fit, thus it can be treated
  * as partial success, in that a new attribute extent needs to be created or
  * the next extent has to be used and the mapping pairs build has to be
- * continued with @start_vcn set to *@stop_vcn.
+ * continued with @first_vcn set to *@stop_vcn.
  *
  * Return 0 on success and -errno on error.  The following error codes are
  * defined:
@@ -1178,27 +1267,32 @@ err_out:
  */
 int ntfs_mapping_pairs_build(const ntfs_volume *vol, s8 *dst,
 		const int dst_len, const runlist_element *rl,
-		const VCN start_vcn, VCN *const stop_vcn)
+		const VCN first_vcn, const VCN last_vcn, VCN *const stop_vcn)
 {
 	LCN prev_lcn;
 	s8 *dst_max, *dst_next;
 	int err = -ENOSPC;
+	BOOL the_end = FALSE;
 	s8 len_len, lcn_len;
 
-	BUG_ON(start_vcn < 0);
+	BUG_ON(first_vcn < 0);
+	BUG_ON(last_vcn < -1);
+	BUG_ON(last_vcn >= 0 && first_vcn > last_vcn);
 	BUG_ON(dst_len < 1);
 	if (!rl) {
-		BUG_ON(start_vcn);
+		BUG_ON(first_vcn);
+		BUG_ON(last_vcn > 0);
 		if (stop_vcn)
 			*stop_vcn = 0;
 		/* Terminator byte. */
 		*dst = 0;
 		return 0;
 	}
-	/* Skip to runlist element containing @start_vcn. */
-	while (rl->length && start_vcn >= rl[1].vcn)
+	/* Skip to runlist element containing @first_vcn. */
+	while (rl->length && first_vcn >= rl[1].vcn)
 		rl++;
-	if ((!rl->length && start_vcn > rl->vcn) || start_vcn < rl->vcn)
+	if (unlikely((!rl->length && first_vcn > rl->vcn) ||
+			first_vcn < rl->vcn))
 		return -EINVAL;
 	/*
 	 * @dst_max is used for bounds checking in
@@ -1207,17 +1301,27 @@ int ntfs_mapping_pairs_build(const ntfs_
 	dst_max = dst + dst_len - 1;
 	prev_lcn = 0;
 	/* Do the first partial run if present. */
-	if (start_vcn > rl->vcn) {
-		s64 delta;
+	if (first_vcn > rl->vcn) {
+		s64 delta, length = rl->length;
 
 		/* We know rl->length != 0 already. */
-		if (rl->length < 0 || rl->lcn < LCN_HOLE)
+		if (unlikely(length < 0 || rl->lcn < LCN_HOLE))
 			goto err_out;
-		delta = start_vcn - rl->vcn;
+		/*
+		 * If @stop_vcn is given and finishes inside this run, cap the
+		 * run length.
+		 */
+		if (unlikely(last_vcn >= 0 && rl[1].vcn > last_vcn)) {
+			s64 s1 = last_vcn + 1;
+			if (unlikely(rl[1].vcn > s1))
+				length = s1 - rl->vcn;
+			the_end = TRUE;
+		}
+		delta = first_vcn - rl->vcn;
 		/* Write length. */
 		len_len = ntfs_write_significant_bytes(dst + 1, dst_max,
-				rl->length - delta);
-		if (len_len < 0)
+				length - delta);
+		if (unlikely(len_len < 0))
 			goto size_err;
 		/*
 		 * If the logical cluster number (lcn) denotes a hole and we
@@ -1228,19 +1332,19 @@ int ntfs_mapping_pairs_build(const ntfs_
 		 * case on NT4. - We assume that we just need to write the lcn
 		 * change until someone tells us otherwise... (AIA)
 		 */
-		if (rl->lcn >= 0 || vol->major_ver < 3) {
+		if (likely(rl->lcn >= 0 || vol->major_ver < 3)) {
 			prev_lcn = rl->lcn;
-			if (rl->lcn >= 0)
+			if (likely(rl->lcn >= 0))
 				prev_lcn += delta;
 			/* Write change in lcn. */
 			lcn_len = ntfs_write_significant_bytes(dst + 1 +
 					len_len, dst_max, prev_lcn);
-			if (lcn_len < 0)
+			if (unlikely(lcn_len < 0))
 				goto size_err;
 		} else
 			lcn_len = 0;
 		dst_next = dst + len_len + lcn_len + 1;
-		if (dst_next > dst_max)
+		if (unlikely(dst_next > dst_max))
 			goto size_err;
 		/* Update header byte. */
 		*dst = lcn_len << 4 | len_len;
@@ -1250,13 +1354,25 @@ int ntfs_mapping_pairs_build(const ntfs_
 		rl++;
 	}
 	/* Do the full runs. */
-	for (; rl->length; rl++) {
-		if (rl->length < 0 || rl->lcn < LCN_HOLE)
+	for (; rl->length && !the_end; rl++) {
+		s64 length = rl->length;
+
+		if (unlikely(length < 0 || rl->lcn < LCN_HOLE))
 			goto err_out;
+		/*
+		 * If @stop_vcn is given and finishes inside this run, cap the
+		 * run length.
+		 */
+		if (unlikely(last_vcn >= 0 && rl[1].vcn > last_vcn)) {
+			s64 s1 = last_vcn + 1;
+			if (unlikely(rl[1].vcn > s1))
+				length = s1 - rl->vcn;
+			the_end = TRUE;
+		}
 		/* Write length. */
 		len_len = ntfs_write_significant_bytes(dst + 1, dst_max,
-				rl->length);
-		if (len_len < 0)
+				length);
+		if (unlikely(len_len < 0))
 			goto size_err;
 		/*
 		 * If the logical cluster number (lcn) denotes a hole and we
@@ -1267,17 +1383,17 @@ int ntfs_mapping_pairs_build(const ntfs_
 		 * case on NT4. - We assume that we just need to write the lcn
 		 * change until someone tells us otherwise... (AIA)
 		 */
-		if (rl->lcn >= 0 || vol->major_ver < 3) {
+		if (likely(rl->lcn >= 0 || vol->major_ver < 3)) {
 			/* Write change in lcn. */
 			lcn_len = ntfs_write_significant_bytes(dst + 1 +
 					len_len, dst_max, rl->lcn - prev_lcn);
-			if (lcn_len < 0)
+			if (unlikely(lcn_len < 0))
 				goto size_err;
 			prev_lcn = rl->lcn;
 		} else
 			lcn_len = 0;
 		dst_next = dst + len_len + lcn_len + 1;
-		if (dst_next > dst_max)
+		if (unlikely(dst_next > dst_max))
 			goto size_err;
 		/* Update header byte. */
 		*dst = lcn_len << 4 | len_len;
@@ -1436,3 +1552,5 @@ int ntfs_rl_truncate_nolock(const ntfs_v
 	ntfs_debug("Done.");
 	return 0;
 }
+
+#endif /* NTFS_RW */
diff --git a/fs/ntfs/runlist.h b/fs/ntfs/runlist.h
--- a/fs/ntfs/runlist.h
+++ b/fs/ntfs/runlist.h
@@ -2,7 +2,7 @@
  * runlist.h - Defines for runlist handling in NTFS Linux kernel driver.
  *	       Part of the Linux-NTFS project.
  *
- * Copyright (c) 2001-2004 Anton Altaparmakov
+ * Copyright (c) 2001-2005 Anton Altaparmakov
  * Copyright (c) 2002 Richard Russon
  *
  * This program/include file is free software; you can redistribute it and/or
@@ -66,6 +66,8 @@ typedef enum {
 	LCN_HOLE		= -1,	/* Keep this as highest value or die! */
 	LCN_RL_NOT_MAPPED	= -2,
 	LCN_ENOENT		= -3,
+	LCN_ENOMEM		= -4,
+	LCN_EIO			= -5,
 } LCN_SPECIAL_VALUES;
 
 extern runlist_element *ntfs_runlists_merge(runlist_element *drl,
@@ -76,14 +78,22 @@ extern runlist_element *ntfs_mapping_pai
 
 extern LCN ntfs_rl_vcn_to_lcn(const runlist_element *rl, const VCN vcn);
 
+#ifdef NTFS_RW
+
+extern runlist_element *ntfs_rl_find_vcn_nolock(runlist_element *rl,
+		const VCN vcn);
+
 extern int ntfs_get_size_for_mapping_pairs(const ntfs_volume *vol,
-		const runlist_element *rl, const VCN start_vcn);
+		const runlist_element *rl, const VCN first_vcn,
+		const VCN last_vcn);
 
 extern int ntfs_mapping_pairs_build(const ntfs_volume *vol, s8 *dst,
 		const int dst_len, const runlist_element *rl,
-		const VCN start_vcn, VCN *const stop_vcn);
+		const VCN first_vcn, const VCN last_vcn, VCN *const stop_vcn);
 
 extern int ntfs_rl_truncate_nolock(const ntfs_volume *vol,
 		runlist *const runlist, const s64 new_length);
 
+#endif /* NTFS_RW */
+
 #endif /* _LINUX_NTFS_RUNLIST_H */
diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c
--- a/fs/ntfs/super.c
+++ b/fs/ntfs/super.c
@@ -1,7 +1,7 @@
 /*
  * super.c - NTFS kernel super block handling. Part of the Linux-NTFS project.
  *
- * Copyright (c) 2001-2004 Anton Altaparmakov
+ * Copyright (c) 2001-2005 Anton Altaparmakov
  * Copyright (c) 2001,2002 Richard Russon
  *
  * This program/include file is free software; you can redistribute it and/or
@@ -34,14 +34,16 @@
 #include "sysctl.h"
 #include "logfile.h"
 #include "quota.h"
+#include "usnjrnl.h"
 #include "dir.h"
 #include "debug.h"
 #include "index.h"
 #include "aops.h"
+#include "layout.h"
 #include "malloc.h"
 #include "ntfs.h"
 
-/* Number of mounted file systems which have compression enabled. */
+/* Number of mounted filesystems which have compression enabled. */
 static unsigned long ntfs_nr_compression_users;
 
 /* A global default upcase table and a corresponding reference count. */
@@ -102,7 +104,7 @@ static BOOL parse_options(ntfs_volume *v
 	gid_t gid = (gid_t)-1;
 	mode_t fmask = (mode_t)-1, dmask = (mode_t)-1;
 	int mft_zone_multiplier = -1, on_errors = -1;
-	int show_sys_files = -1, case_sensitive = -1;
+	int show_sys_files = -1, case_sensitive = -1, disable_sparse = -1;
 	struct nls_table *nls_map = NULL, *old_nls;
 
 	/* I am lazy... (-8 */
@@ -162,6 +164,7 @@ static BOOL parse_options(ntfs_volume *v
 		else NTFS_GETOPT_WITH_DEFAULT("sloppy", sloppy, TRUE)
 		else NTFS_GETOPT_BOOL("show_sys_files", show_sys_files)
 		else NTFS_GETOPT_BOOL("case_sensitive", case_sensitive)
+		else NTFS_GETOPT_BOOL("disable_sparse", disable_sparse)
 		else NTFS_GETOPT_OPTIONS_ARRAY("errors", on_errors,
 				on_errors_arr)
 		else if (!strcmp(p, "posix") || !strcmp(p, "show_inodes"))
@@ -291,6 +294,21 @@ no_mount_options:
 		else
 			NVolClearCaseSensitive(vol);
 	}
+	if (disable_sparse != -1) {
+		if (disable_sparse)
+			NVolClearSparseEnabled(vol);
+		else {
+			if (!NVolSparseEnabled(vol) &&
+					vol->major_ver && vol->major_ver < 3)
+				ntfs_warning(vol->sb, "Not enabling sparse "
+						"support due to NTFS volume "
+						"version %i.%i (need at least "
+						"version 3.0).", vol->major_ver,
+						vol->minor_ver);
+			else
+				NVolSetSparseEnabled(vol);
+		}
+	}
 	return TRUE;
 needs_arg:
 	ntfs_error(vol->sb, "The %s option requires an argument.", p);
@@ -480,6 +498,12 @@ static int ntfs_remount(struct super_blo
 			NVolSetErrors(vol);
 			return -EROFS;
 		}
+		if (!ntfs_stamp_usnjrnl(vol)) {
+			ntfs_error(sb, "Failed to stamp transation log "
+					"($UsnJrnl)%s", es);
+			NVolSetErrors(vol);
+			return -EROFS;
+		}
 	} else if (!(sb->s_flags & MS_RDONLY) && (*flags & MS_RDONLY)) {
 		/* Remounting read-only. */
 		if (!NVolErrors(vol)) {
@@ -516,16 +540,19 @@ static BOOL is_boot_sector_ntfs(const st
 {
 	/*
 	 * Check that checksum == sum of u32 values from b to the checksum
-	 * field. If checksum is zero, no checking is done.
+	 * field.  If checksum is zero, no checking is done.  We will work when
+	 * the checksum test fails, since some utilities update the boot sector
+	 * ignoring the checksum which leaves the checksum out-of-date.  We
+	 * report a warning if this is the case.
 	 */
-	if ((void*)b < (void*)&b->checksum && b->checksum) {
+	if ((void*)b < (void*)&b->checksum && b->checksum && !silent) {
 		le32 *u;
 		u32 i;
 
 		for (i = 0, u = (le32*)b; u < (le32*)(&b->checksum); ++u)
 			i += le32_to_cpup(u);
 		if (le32_to_cpu(b->checksum) != i)
-			goto not_ntfs;
+			ntfs_warning(sb, "Invalid boot sector checksum.");
 	}
 	/* Check OEMidentifier is "NTFS    " */
 	if (b->oem_id != magicNTFS)
@@ -541,9 +568,9 @@ static BOOL is_boot_sector_ntfs(const st
 	default:
 		goto not_ntfs;
 	}
-	/* Check the cluster size is not above 65536 bytes. */
+	/* Check the cluster size is not above the maximum (64kiB). */
 	if ((u32)le16_to_cpu(b->bpb.bytes_per_sector) *
-			b->bpb.sectors_per_cluster > 0x10000)
+			b->bpb.sectors_per_cluster > NTFS_MAX_CLUSTER_SIZE)
 		goto not_ntfs;
 	/* Check reserved/unused fields are really zero. */
 	if (le16_to_cpu(b->bpb.reserved_sectors) ||
@@ -575,7 +602,7 @@ static BOOL is_boot_sector_ntfs(const st
 	 * many BIOSes will refuse to boot from a bootsector if the magic is
 	 * incorrect, so we emit a warning.
 	 */
-	if (!silent && b->end_of_sector_marker != cpu_to_le16(0xaa55))
+	if (!silent && b->end_of_sector_marker != const_cpu_to_le16(0xaa55))
 		ntfs_warning(sb, "Invalid end of sector marker.");
 	return TRUE;
 not_ntfs:
@@ -967,6 +994,7 @@ static BOOL load_and_init_mft_mirror(ntf
 	tmp_ni = NTFS_I(tmp_ino);
 	/* The $MFTMirr, like the $MFT is multi sector transfer protected. */
 	NInoSetMstProtected(tmp_ni);
+	NInoSetSparseDisabled(tmp_ni);
 	/*
 	 * Set up our little cheat allowing us to reuse the async read io
 	 * completion handler for directories.
@@ -990,12 +1018,12 @@ static BOOL load_and_init_mft_mirror(ntf
  */
 static BOOL check_mft_mirror(ntfs_volume *vol)
 {
-	unsigned long index;
 	struct super_block *sb = vol->sb;
 	ntfs_inode *mirr_ni;
 	struct page *mft_page, *mirr_page;
 	u8 *kmft, *kmirr;
 	runlist_element *rl, rl2[2];
+	pgoff_t index;
 	int mrecs_per_page, i;
 
 	ntfs_debug("Entering.");
@@ -1122,11 +1150,130 @@ static BOOL load_and_check_logfile(ntfs_
 		/* ntfs_check_logfile() will have displayed error output. */
 		return FALSE;
 	}
+	NInoSetSparseDisabled(NTFS_I(tmp_ino));
 	vol->logfile_ino = tmp_ino;
 	ntfs_debug("Done.");
 	return TRUE;
 }
 
+#define NTFS_HIBERFIL_HEADER_SIZE	4096
+
+/**
+ * check_windows_hibernation_status - check if Windows is suspended on a volume
+ * @vol:	ntfs super block of device to check
+ *
+ * Check if Windows is hibernated on the ntfs volume @vol.  This is done by
+ * looking for the file hiberfil.sys in the root directory of the volume.  If
+ * the file is not present Windows is definitely not suspended.
+ *
+ * If hiberfil.sys exists and is less than 4kiB in size it means Windows is
+ * definitely suspended (this volume is not the system volume).  Caveat:  on a
+ * system with many volumes it is possible that the < 4kiB check is bogus but
+ * for now this should do fine.
+ *
+ * If hiberfil.sys exists and is larger than 4kiB in size, we need to read the
+ * hiberfil header (which is the first 4kiB).  If this begins with "hibr",
+ * Windows is definitely suspended.  If it is completely full of zeroes,
+ * Windows is definitely not hibernated.  Any other case is treated as if
+ * Windows is suspended.  This caters for the above mentioned caveat of a
+ * system with many volumes where no "hibr" magic would be present and there is
+ * no zero header.
+ *
+ * Return 0 if Windows is not hibernated on the volume, >0 if Windows is
+ * hibernated on the volume, and -errno on error.
+ */
+static int check_windows_hibernation_status(ntfs_volume *vol)
+{
+	MFT_REF mref;
+	struct inode *vi;
+	ntfs_inode *ni;
+	struct page *page;
+	u32 *kaddr, *kend;
+	ntfs_name *name = NULL;
+	int ret = 1;
+	static const ntfschar hiberfil[13] = { const_cpu_to_le16('h'),
+			const_cpu_to_le16('i'), const_cpu_to_le16('b'),
+			const_cpu_to_le16('e'), const_cpu_to_le16('r'),
+			const_cpu_to_le16('f'), const_cpu_to_le16('i'),
+			const_cpu_to_le16('l'), const_cpu_to_le16('.'),
+			const_cpu_to_le16('s'), const_cpu_to_le16('y'),
+			const_cpu_to_le16('s'), 0 };
+
+	ntfs_debug("Entering.");
+	/*
+	 * Find the inode number for the hibernation file by looking up the
+	 * filename hiberfil.sys in the root directory.
+	 */
+	down(&vol->root_ino->i_sem);
+	mref = ntfs_lookup_inode_by_name(NTFS_I(vol->root_ino), hiberfil, 12,
+			&name);
+	up(&vol->root_ino->i_sem);
+	if (IS_ERR_MREF(mref)) {
+		ret = MREF_ERR(mref);
+		/* If the file does not exist, Windows is not hibernated. */
+		if (ret == -ENOENT) {
+			ntfs_debug("hiberfil.sys not present.  Windows is not "
+					"hibernated on the volume.");
+			return 0;
+		}
+		/* A real error occured. */
+		ntfs_error(vol->sb, "Failed to find inode number for "
+				"hiberfil.sys.");
+		return ret;
+	}
+	/* We do not care for the type of match that was found. */
+	kfree(name);
+	/* Get the inode. */
+	vi = ntfs_iget(vol->sb, MREF(mref));
+	if (IS_ERR(vi) || is_bad_inode(vi)) {
+		if (!IS_ERR(vi))
+			iput(vi);
+		ntfs_error(vol->sb, "Failed to load hiberfil.sys.");
+		return IS_ERR(vi) ? PTR_ERR(vi) : -EIO;
+	}
+	if (unlikely(i_size_read(vi) < NTFS_HIBERFIL_HEADER_SIZE)) {
+		ntfs_debug("hiberfil.sys is smaller than 4kiB (0x%llx).  "
+				"Windows is hibernated on the volume.  This "
+				"is not the system volume.", i_size_read(vi));
+		goto iput_out;
+	}
+	ni = NTFS_I(vi);
+	page = ntfs_map_page(vi->i_mapping, 0);
+	if (IS_ERR(page)) {
+		ntfs_error(vol->sb, "Failed to read from hiberfil.sys.");
+		ret = PTR_ERR(page);
+		goto iput_out;
+	}
+	kaddr = (u32*)page_address(page);
+	if (*(le32*)kaddr == const_cpu_to_le32(0x72626968)/*'hibr'*/) {
+		ntfs_debug("Magic \"hibr\" found in hiberfil.sys.  Windows is "
+				"hibernated on the volume.  This is the "
+				"system volume.");
+		goto unm_iput_out;
+	}
+	kend = kaddr + NTFS_HIBERFIL_HEADER_SIZE/sizeof(*kaddr);
+	do {
+		if (unlikely(*kaddr)) {
+			ntfs_debug("hiberfil.sys is larger than 4kiB "
+					"(0x%llx), does not contain the "
+					"\"hibr\" magic, and does not have a "
+					"zero header.  Windows is hibernated "
+					"on the volume.  This is not the "
+					"system volume.", i_size_read(vi));
+			goto unm_iput_out;
+		}
+	} while (++kaddr < kend);
+	ntfs_debug("hiberfil.sys contains a zero header.  Windows is not "
+			"hibernated on the volume.  This is the system "
+			"volume.");
+	ret = 0;
+unm_iput_out:
+	ntfs_unmap_page(page);
+iput_out:
+	iput(vi);
+	return ret;
+}
+
 /**
  * load_and_init_quota - load and setup the quota file for a volume if present
  * @vol:	ntfs super block describing device whose quota file to load
@@ -1175,8 +1322,7 @@ static BOOL load_and_init_quota(ntfs_vol
 		return FALSE;
 	}
 	/* We do not care for the type of match that was found. */
-	if (name)
-		kfree(name);
+	kfree(name);
 	/* Get the inode. */
 	tmp_ino = ntfs_iget(vol->sb, MREF(mref));
 	if (IS_ERR(tmp_ino) || is_bad_inode(tmp_ino)) {
@@ -1198,6 +1344,167 @@ static BOOL load_and_init_quota(ntfs_vol
 }
 
 /**
+ * load_and_init_usnjrnl - load and setup the transaction log if present
+ * @vol:	ntfs super block describing device whose usnjrnl file to load
+ *
+ * Return TRUE on success or FALSE on error.
+ *
+ * If $UsnJrnl is not present or in the process of being disabled, we set
+ * NVolUsnJrnlStamped() and return success.
+ *
+ * If the $UsnJrnl $DATA/$J attribute has a size equal to the lowest valid usn,
+ * i.e. transaction logging has only just been enabled or the journal has been
+ * stamped and nothing has been logged since, we also set NVolUsnJrnlStamped()
+ * and return success.
+ */
+static BOOL load_and_init_usnjrnl(ntfs_volume *vol)
+{
+	MFT_REF mref;
+	struct inode *tmp_ino;
+	ntfs_inode *tmp_ni;
+	struct page *page;
+	ntfs_name *name = NULL;
+	USN_HEADER *uh;
+	static const ntfschar UsnJrnl[9] = { const_cpu_to_le16('$'),
+			const_cpu_to_le16('U'), const_cpu_to_le16('s'),
+			const_cpu_to_le16('n'), const_cpu_to_le16('J'),
+			const_cpu_to_le16('r'), const_cpu_to_le16('n'),
+			const_cpu_to_le16('l'), 0 };
+	static ntfschar Max[5] = { const_cpu_to_le16('$'),
+			const_cpu_to_le16('M'), const_cpu_to_le16('a'),
+			const_cpu_to_le16('x'), 0 };
+	static ntfschar J[3] = { const_cpu_to_le16('$'),
+			const_cpu_to_le16('J'), 0 };
+
+	ntfs_debug("Entering.");
+	/*
+	 * Find the inode number for the transaction log file by looking up the
+	 * filename $UsnJrnl in the extended system files directory $Extend.
+	 */
+	down(&vol->extend_ino->i_sem);
+	mref = ntfs_lookup_inode_by_name(NTFS_I(vol->extend_ino), UsnJrnl, 8,
+			&name);
+	up(&vol->extend_ino->i_sem);
+	if (IS_ERR_MREF(mref)) {
+		/*
+		 * If the file does not exist, transaction logging is disabled,
+		 * just return success.
+		 */
+		if (MREF_ERR(mref) == -ENOENT) {
+			ntfs_debug("$UsnJrnl not present.  Volume does not "
+					"have transaction logging enabled.");
+not_enabled:
+			/*
+			 * No need to try to stamp the transaction log if
+			 * transaction logging is not enabled.
+			 */
+			NVolSetUsnJrnlStamped(vol);
+			return TRUE;
+		}
+		/* A real error occured. */
+		ntfs_error(vol->sb, "Failed to find inode number for "
+				"$UsnJrnl.");
+		return FALSE;
+	}
+	/* We do not care for the type of match that was found. */
+	kfree(name);
+	/* Get the inode. */
+	tmp_ino = ntfs_iget(vol->sb, MREF(mref));
+	if (unlikely(IS_ERR(tmp_ino) || is_bad_inode(tmp_ino))) {
+		if (!IS_ERR(tmp_ino))
+			iput(tmp_ino);
+		ntfs_error(vol->sb, "Failed to load $UsnJrnl.");
+		return FALSE;
+	}
+	vol->usnjrnl_ino = tmp_ino;
+	/*
+	 * If the transaction log is in the process of being deleted, we can
+	 * ignore it.
+	 */
+	if (unlikely(vol->vol_flags & VOLUME_DELETE_USN_UNDERWAY)) {
+		ntfs_debug("$UsnJrnl in the process of being disabled.  "
+				"Volume does not have transaction logging "
+				"enabled.");
+		goto not_enabled;
+	}
+	/* Get the $DATA/$Max attribute. */
+	tmp_ino = ntfs_attr_iget(vol->usnjrnl_ino, AT_DATA, Max, 4);
+	if (IS_ERR(tmp_ino)) {
+		ntfs_error(vol->sb, "Failed to load $UsnJrnl/$DATA/$Max "
+				"attribute.");
+		return FALSE;
+	}
+	vol->usnjrnl_max_ino = tmp_ino;
+	if (unlikely(i_size_read(tmp_ino) < sizeof(USN_HEADER))) {
+		ntfs_error(vol->sb, "Found corrupt $UsnJrnl/$DATA/$Max "
+				"attribute (size is 0x%llx but should be at "
+				"least 0x%x bytes).", i_size_read(tmp_ino),
+				sizeof(USN_HEADER));
+		return FALSE;
+	}
+	/* Get the $DATA/$J attribute. */
+	tmp_ino = ntfs_attr_iget(vol->usnjrnl_ino, AT_DATA, J, 2);
+	if (IS_ERR(tmp_ino)) {
+		ntfs_error(vol->sb, "Failed to load $UsnJrnl/$DATA/$J "
+				"attribute.");
+		return FALSE;
+	}
+	vol->usnjrnl_j_ino = tmp_ino;
+	/* Verify $J is non-resident and sparse. */
+	tmp_ni = NTFS_I(vol->usnjrnl_j_ino);
+	if (unlikely(!NInoNonResident(tmp_ni) || !NInoSparse(tmp_ni))) {
+		ntfs_error(vol->sb, "$UsnJrnl/$DATA/$J attribute is resident "
+				"and/or not sparse.");
+		return FALSE;
+	}
+	/* Read the USN_HEADER from $DATA/$Max. */
+	page = ntfs_map_page(vol->usnjrnl_max_ino->i_mapping, 0);
+	if (IS_ERR(page)) {
+		ntfs_error(vol->sb, "Failed to read from $UsnJrnl/$DATA/$Max "
+				"attribute.");
+		return FALSE;
+	}
+	uh = (USN_HEADER*)page_address(page);
+	/* Sanity check the $Max. */
+	if (unlikely(sle64_to_cpu(uh->allocation_delta) >
+			sle64_to_cpu(uh->maximum_size))) {
+		ntfs_error(vol->sb, "Allocation delta (0x%llx) exceeds "
+				"maximum size (0x%llx).  $UsnJrnl is corrupt.",
+				(long long)sle64_to_cpu(uh->allocation_delta),
+				(long long)sle64_to_cpu(uh->maximum_size));
+		ntfs_unmap_page(page);
+		return FALSE;
+	}
+	/*
+	 * If the transaction log has been stamped and nothing has been written
+	 * to it since, we do not need to stamp it.
+	 */
+	if (unlikely(sle64_to_cpu(uh->lowest_valid_usn) >=
+			i_size_read(vol->usnjrnl_j_ino))) {
+		if (likely(sle64_to_cpu(uh->lowest_valid_usn) ==
+				i_size_read(vol->usnjrnl_j_ino))) {
+			ntfs_unmap_page(page);
+			ntfs_debug("$UsnJrnl is enabled but nothing has been "
+					"logged since it was last stamped.  "
+					"Treating this as if the volume does "
+					"not have transaction logging "
+					"enabled.");
+			goto not_enabled;
+		}
+		ntfs_error(vol->sb, "$UsnJrnl has lowest valid usn (0x%llx) "
+				"which is out of bounds (0x%llx).  $UsnJrnl "
+				"is corrupt.",
+				(long long)sle64_to_cpu(uh->lowest_valid_usn),
+				i_size_read(vol->usnjrnl_j_ino));
+		ntfs_unmap_page(page);
+		return FALSE;
+	}
+	ntfs_unmap_page(page);
+	ntfs_debug("Done.");
+	return TRUE;
+}
+
+/**
  * load_and_init_attrdef - load the attribute definitions table for a volume
  * @vol:	ntfs super block describing device whose attrdef to load
  *
@@ -1205,10 +1512,11 @@ static BOOL load_and_init_quota(ntfs_vol
  */
 static BOOL load_and_init_attrdef(ntfs_volume *vol)
 {
+	loff_t i_size;
 	struct super_block *sb = vol->sb;
 	struct inode *ino;
 	struct page *page;
-	unsigned long index, max_index;
+	pgoff_t index, max_index;
 	unsigned int size;
 
 	ntfs_debug("Entering.");
@@ -1219,14 +1527,16 @@ static BOOL load_and_init_attrdef(ntfs_v
 			iput(ino);
 		goto failed;
 	}
+	NInoSetSparseDisabled(NTFS_I(ino));
 	/* The size of FILE_AttrDef must be above 0 and fit inside 31 bits. */
-	if (!ino->i_size || ino->i_size > 0x7fffffff)
+	i_size = i_size_read(ino);
+	if (i_size <= 0 || i_size > 0x7fffffff)
 		goto iput_failed;
-	vol->attrdef = (ATTR_DEF*)ntfs_malloc_nofs(ino->i_size);
+	vol->attrdef = (ATTR_DEF*)ntfs_malloc_nofs(i_size);
 	if (!vol->attrdef)
 		goto iput_failed;
 	index = 0;
-	max_index = ino->i_size >> PAGE_CACHE_SHIFT;
+	max_index = i_size >> PAGE_CACHE_SHIFT;
 	size = PAGE_CACHE_SIZE;
 	while (index < max_index) {
 		/* Read the attrdef table and copy it into the linear buffer. */
@@ -1239,12 +1549,12 @@ read_partial_attrdef_page:
 		ntfs_unmap_page(page);
 	};
 	if (size == PAGE_CACHE_SIZE) {
-		size = ino->i_size & ~PAGE_CACHE_MASK;
+		size = i_size & ~PAGE_CACHE_MASK;
 		if (size)
 			goto read_partial_attrdef_page;
 	}
-	vol->attrdef_size = ino->i_size;
-	ntfs_debug("Read %llu bytes from $AttrDef.", ino->i_size);
+	vol->attrdef_size = i_size;
+	ntfs_debug("Read %llu bytes from $AttrDef.", i_size);
 	iput(ino);
 	return TRUE;
 free_iput_failed:
@@ -1267,10 +1577,11 @@ failed:
  */
 static BOOL load_and_init_upcase(ntfs_volume *vol)
 {
+	loff_t i_size;
 	struct super_block *sb = vol->sb;
 	struct inode *ino;
 	struct page *page;
-	unsigned long index, max_index;
+	pgoff_t index, max_index;
 	unsigned int size;
 	int i, max;
 
@@ -1286,14 +1597,15 @@ static BOOL load_and_init_upcase(ntfs_vo
 	 * The upcase size must not be above 64k Unicode characters, must not
 	 * be zero and must be a multiple of sizeof(ntfschar).
 	 */
-	if (!ino->i_size || ino->i_size & (sizeof(ntfschar) - 1) ||
-			ino->i_size > 64ULL * 1024 * sizeof(ntfschar))
+	i_size = i_size_read(ino);
+	if (!i_size || i_size & (sizeof(ntfschar) - 1) ||
+			i_size > 64ULL * 1024 * sizeof(ntfschar))
 		goto iput_upcase_failed;
-	vol->upcase = (ntfschar*)ntfs_malloc_nofs(ino->i_size);
+	vol->upcase = (ntfschar*)ntfs_malloc_nofs(i_size);
 	if (!vol->upcase)
 		goto iput_upcase_failed;
 	index = 0;
-	max_index = ino->i_size >> PAGE_CACHE_SHIFT;
+	max_index = i_size >> PAGE_CACHE_SHIFT;
 	size = PAGE_CACHE_SIZE;
 	while (index < max_index) {
 		/* Read the upcase table and copy it into the linear buffer. */
@@ -1306,13 +1618,13 @@ read_partial_upcase_page:
 		ntfs_unmap_page(page);
 	};
 	if (size == PAGE_CACHE_SIZE) {
-		size = ino->i_size & ~PAGE_CACHE_MASK;
+		size = i_size & ~PAGE_CACHE_MASK;
 		if (size)
 			goto read_partial_upcase_page;
 	}
-	vol->upcase_len = ino->i_size >> UCHAR_T_SIZE_BITS;
+	vol->upcase_len = i_size >> UCHAR_T_SIZE_BITS;
 	ntfs_debug("Read %llu bytes from $UpCase (expected %zu bytes).",
-			ino->i_size, 64 * 1024 * sizeof(ntfschar));
+			i_size, 64 * 1024 * sizeof(ntfschar));
 	iput(ino);
 	down(&ntfs_lock);
 	if (!default_upcase) {
@@ -1376,6 +1688,9 @@ static BOOL load_system_files(ntfs_volum
 	MFT_RECORD *m;
 	VOLUME_INFORMATION *vi;
 	ntfs_attr_search_ctx *ctx;
+#ifdef NTFS_RW
+	int err;
+#endif /* NTFS_RW */
 
 	ntfs_debug("Entering.");
 #ifdef NTFS_RW
@@ -1435,7 +1750,8 @@ static BOOL load_system_files(ntfs_volum
 			iput(vol->lcnbmp_ino);
 		goto bitmap_failed;
 	}
-	if ((vol->nr_clusters + 7) >> 3 > vol->lcnbmp_ino->i_size) {
+	NInoSetSparseDisabled(NTFS_I(vol->lcnbmp_ino));
+	if ((vol->nr_clusters + 7) >> 3 > i_size_read(vol->lcnbmp_ino)) {
 		iput(vol->lcnbmp_ino);
 bitmap_failed:
 		ntfs_error(sb, "Failed to load $Bitmap.");
@@ -1486,6 +1802,12 @@ get_ctx_vol_failed:
 	unmap_mft_record(NTFS_I(vol->vol_ino));
 	printk(KERN_INFO "NTFS volume version %i.%i.\n", vol->major_ver,
 			vol->minor_ver);
+	if (vol->major_ver < 3 && NVolSparseEnabled(vol)) {
+		ntfs_warning(vol->sb, "Disabling sparse support due to NTFS "
+				"volume version %i.%i (need at least version "
+				"3.0).", vol->major_ver, vol->minor_ver);
+		NVolClearSparseEnabled(vol);
+	}
 #ifdef NTFS_RW
 	/* Make sure that no unsupported volume flags are set. */
 	if (vol->vol_flags & VOLUME_MUST_MOUNT_RO_MASK) {
@@ -1545,6 +1867,50 @@ get_ctx_vol_failed:
 		/* This will prevent a read-write remount. */
 		NVolSetErrors(vol);
 	}
+#endif /* NTFS_RW */
+	/* Get the root directory inode so we can do path lookups. */
+	vol->root_ino = ntfs_iget(sb, FILE_root);
+	if (IS_ERR(vol->root_ino) || is_bad_inode(vol->root_ino)) {
+		if (!IS_ERR(vol->root_ino))
+			iput(vol->root_ino);
+		ntfs_error(sb, "Failed to load root directory.");
+		goto iput_logfile_err_out;
+	}
+#ifdef NTFS_RW
+	/*
+	 * Check if Windows is suspended to disk on the target volume.  If it
+	 * is hibernated, we must not write *anything* to the disk so set
+	 * NVolErrors() without setting the dirty volume flag and mount
+	 * read-only.  This will prevent read-write remounting and it will also
+	 * prevent all writes.
+	 */
+	err = check_windows_hibernation_status(vol);
+	if (unlikely(err)) {
+		static const char *es1a = "Failed to determine if Windows is "
+				"hibernated";
+		static const char *es1b = "Windows is hibernated";
+		static const char *es2 = ".  Run chkdsk.";
+		const char *es1;
+
+		es1 = err < 0 ? es1a : es1b;
+		/* If a read-write mount, convert it to a read-only mount. */
+		if (!(sb->s_flags & MS_RDONLY)) {
+			if (!(vol->on_errors & (ON_ERRORS_REMOUNT_RO |
+					ON_ERRORS_CONTINUE))) {
+				ntfs_error(sb, "%s and neither on_errors="
+						"continue nor on_errors="
+						"remount-ro was specified%s",
+						es1, es2);
+				goto iput_root_err_out;
+			}
+			sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME;
+			ntfs_error(sb, "%s.  Mounting read-only%s", es1, es2);
+		} else
+			ntfs_warning(sb, "%s.  Will not be able to remount "
+					"read-write%s", es1, es2);
+		/* This will prevent a read-write remount. */
+		NVolSetErrors(vol);
+	}
 	/* If (still) a read-write mount, mark the volume dirty. */
 	if (!(sb->s_flags & MS_RDONLY) &&
 			ntfs_set_volume_flags(vol, VOLUME_IS_DIRTY)) {
@@ -1558,7 +1924,7 @@ get_ctx_vol_failed:
 			ntfs_error(sb, "%s and neither on_errors=continue nor "
 					"on_errors=remount-ro was specified%s",
 					es1, es2);
-			goto iput_logfile_err_out;
+			goto iput_root_err_out;
 		}
 		ntfs_error(sb, "%s.  Mounting read-only%s", es1, es2);
 		sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME;
@@ -1585,7 +1951,7 @@ get_ctx_vol_failed:
 			ntfs_error(sb, "%s and neither on_errors=continue nor "
 					"on_errors=remount-ro was specified%s",
 					es1, es2);
-			goto iput_logfile_err_out;
+			goto iput_root_err_out;
 		}
 		ntfs_error(sb, "%s.  Mounting read-only%s", es1, es2);
 		sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME;
@@ -1604,23 +1970,15 @@ get_ctx_vol_failed:
 			ntfs_error(sb, "%s and neither on_errors=continue nor "
 					"on_errors=remount-ro was specified%s",
 					es1, es2);
-			goto iput_logfile_err_out;
+			goto iput_root_err_out;
 		}
 		ntfs_error(sb, "%s.  Mounting read-only%s", es1, es2);
 		sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME;
 		NVolSetErrors(vol);
 	}
 #endif /* NTFS_RW */
-	/* Get the root directory inode. */
-	vol->root_ino = ntfs_iget(sb, FILE_root);
-	if (IS_ERR(vol->root_ino) || is_bad_inode(vol->root_ino)) {
-		if (!IS_ERR(vol->root_ino))
-			iput(vol->root_ino);
-		ntfs_error(sb, "Failed to load root directory.");
-		goto iput_logfile_err_out;
-	}
 	/* If on NTFS versions before 3.0, we are done. */
-	if (vol->major_ver < 3)
+	if (unlikely(vol->major_ver < 3))
 		return TRUE;
 	/* NTFS 3.0+ specific initialization. */
 	/* Get the security descriptors inode. */
@@ -1631,7 +1989,7 @@ get_ctx_vol_failed:
 		ntfs_error(sb, "Failed to load $Secure.");
 		goto iput_root_err_out;
 	}
-	// FIXME: Initialize security.
+	// TODO: Initialize security.
 	/* Get the extended system files' directory inode. */
 	vol->extend_ino = ntfs_iget(sb, FILE_Extend);
 	if (IS_ERR(vol->extend_ino) || is_bad_inode(vol->extend_ino)) {
@@ -1682,10 +2040,60 @@ get_ctx_vol_failed:
 		sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME;
 		NVolSetErrors(vol);
 	}
-	// TODO: Delete or checkpoint the $UsnJrnl if it exists.
+	/*
+	 * Find the transaction log file ($UsnJrnl), load it if present, check
+	 * it, and set it up.
+	 */
+	if (!load_and_init_usnjrnl(vol)) {
+		static const char *es1 = "Failed to load $UsnJrnl";
+		static const char *es2 = ".  Run chkdsk.";
+
+		/* If a read-write mount, convert it to a read-only mount. */
+		if (!(sb->s_flags & MS_RDONLY)) {
+			if (!(vol->on_errors & (ON_ERRORS_REMOUNT_RO |
+					ON_ERRORS_CONTINUE))) {
+				ntfs_error(sb, "%s and neither on_errors="
+						"continue nor on_errors="
+						"remount-ro was specified%s",
+						es1, es2);
+				goto iput_usnjrnl_err_out;
+			}
+			sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME;
+			ntfs_error(sb, "%s.  Mounting read-only%s", es1, es2);
+		} else
+			ntfs_warning(sb, "%s.  Will not be able to remount "
+					"read-write%s", es1, es2);
+		/* This will prevent a read-write remount. */
+		NVolSetErrors(vol);
+	}
+	/* If (still) a read-write mount, stamp the transaction log. */
+	if (!(sb->s_flags & MS_RDONLY) && !ntfs_stamp_usnjrnl(vol)) {
+		static const char *es1 = "Failed to stamp transaction log "
+				"($UsnJrnl)";
+		static const char *es2 = ".  Run chkdsk.";
+
+		/* Convert to a read-only mount. */
+		if (!(vol->on_errors & (ON_ERRORS_REMOUNT_RO |
+				ON_ERRORS_CONTINUE))) {
+			ntfs_error(sb, "%s and neither on_errors=continue nor "
+					"on_errors=remount-ro was specified%s",
+					es1, es2);
+			goto iput_usnjrnl_err_out;
+		}
+		ntfs_error(sb, "%s.  Mounting read-only%s", es1, es2);
+		sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME;
+		NVolSetErrors(vol);
+	}
 #endif /* NTFS_RW */
 	return TRUE;
 #ifdef NTFS_RW
+iput_usnjrnl_err_out:
+	if (vol->usnjrnl_j_ino)
+		iput(vol->usnjrnl_j_ino);
+	if (vol->usnjrnl_max_ino)
+		iput(vol->usnjrnl_max_ino);
+	if (vol->usnjrnl_ino)
+		iput(vol->usnjrnl_ino);
 iput_quota_err_out:
 	if (vol->quota_q_ino)
 		iput(vol->quota_q_ino);
@@ -1759,6 +2167,12 @@ static void ntfs_put_super(struct super_
 
 	/* NTFS 3.0+ specific. */
 	if (vol->major_ver >= 3) {
+		if (vol->usnjrnl_j_ino)
+			ntfs_commit_inode(vol->usnjrnl_j_ino);
+		if (vol->usnjrnl_max_ino)
+			ntfs_commit_inode(vol->usnjrnl_max_ino);
+		if (vol->usnjrnl_ino)
+			ntfs_commit_inode(vol->usnjrnl_ino);
 		if (vol->quota_q_ino)
 			ntfs_commit_inode(vol->quota_q_ino);
 		if (vol->quota_ino)
@@ -1814,6 +2228,18 @@ static void ntfs_put_super(struct super_
 	/* NTFS 3.0+ specific clean up. */
 	if (vol->major_ver >= 3) {
 #ifdef NTFS_RW
+		if (vol->usnjrnl_j_ino) {
+			iput(vol->usnjrnl_j_ino);
+			vol->usnjrnl_j_ino = NULL;
+		}
+		if (vol->usnjrnl_max_ino) {
+			iput(vol->usnjrnl_max_ino);
+			vol->usnjrnl_max_ino = NULL;
+		}
+		if (vol->usnjrnl_ino) {
+			iput(vol->usnjrnl_ino);
+			vol->usnjrnl_ino = NULL;
+		}
 		if (vol->quota_q_ino) {
 			iput(vol->quota_q_ino);
 			vol->quota_q_ino = NULL;
@@ -1959,8 +2385,7 @@ static s64 get_nr_free_clusters(ntfs_vol
 	struct address_space *mapping = vol->lcnbmp_ino->i_mapping;
 	filler_t *readpage = (filler_t*)mapping->a_ops->readpage;
 	struct page *page;
-	unsigned long index, max_index;
-	unsigned int max_size;
+	pgoff_t index, max_index;
 
 	ntfs_debug("Entering.");
 	/* Serialize accesses to the cluster bitmap. */
@@ -1972,11 +2397,10 @@ static s64 get_nr_free_clusters(ntfs_vol
 	 */
 	max_index = (((vol->nr_clusters + 7) >> 3) + PAGE_CACHE_SIZE - 1) >>
 			PAGE_CACHE_SHIFT;
-	/* Use multiples of 4 bytes. */
-	max_size = PAGE_CACHE_SIZE >> 2;
-	ntfs_debug("Reading $Bitmap, max_index = 0x%lx, max_size = 0x%x.",
-			max_index, max_size);
-	for (index = 0UL; index < max_index; index++) {
+	/* Use multiples of 4 bytes, thus max_size is PAGE_CACHE_SIZE / 4. */
+	ntfs_debug("Reading $Bitmap, max_index = 0x%lx, max_size = 0x%lx.",
+			max_index, PAGE_CACHE_SIZE / 4);
+	for (index = 0; index < max_index; index++) {
 		unsigned int i;
 		/*
 		 * Read the page from page cache, getting it from backing store
@@ -2008,7 +2432,7 @@ static s64 get_nr_free_clusters(ntfs_vol
 		 * the result as all out of range bytes are set to zero by
 		 * ntfs_readpage().
 		 */
-	  	for (i = 0; i < max_size; i++)
+	  	for (i = 0; i < PAGE_CACHE_SIZE / 4; i++)
 			nr_free -= (s64)hweight32(kaddr[i]);
 		kunmap_atomic(kaddr, KM_USER0);
 		page_cache_release(page);
@@ -2031,6 +2455,8 @@ static s64 get_nr_free_clusters(ntfs_vol
 /**
  * __get_nr_free_mft_records - return the number of free inodes on a volume
  * @vol:	ntfs volume for which to obtain free inode count
+ * @nr_free:	number of mft records in filesystem
+ * @max_index:	maximum number of pages containing set bits
  *
  * Calculate the number of free mft records (inodes) on the mounted NTFS
  * volume @vol. We actually calculate the number of mft records in use instead
@@ -2043,32 +2469,20 @@ static s64 get_nr_free_clusters(ntfs_vol
  *
  * NOTE: Caller must hold mftbmp_lock rw_semaphore for reading or writing.
  */
-static unsigned long __get_nr_free_mft_records(ntfs_volume *vol)
+static unsigned long __get_nr_free_mft_records(ntfs_volume *vol,
+		s64 nr_free, const pgoff_t max_index)
 {
-	s64 nr_free;
 	u32 *kaddr;
 	struct address_space *mapping = vol->mftbmp_ino->i_mapping;
 	filler_t *readpage = (filler_t*)mapping->a_ops->readpage;
 	struct page *page;
-	unsigned long index, max_index;
-	unsigned int max_size;
+	pgoff_t index;
 
 	ntfs_debug("Entering.");
-	/* Number of mft records in file system (at this point in time). */
-	nr_free = vol->mft_ino->i_size >> vol->mft_record_size_bits;
-	/*
-	 * Convert the maximum number of set bits into bytes rounded up, then
-	 * convert into multiples of PAGE_CACHE_SIZE, rounding up so that if we
-	 * have one full and one partial page max_index = 2.
-	 */
-	max_index = ((((NTFS_I(vol->mft_ino)->initialized_size >>
-			vol->mft_record_size_bits) + 7) >> 3) +
-			PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
-	/* Use multiples of 4 bytes. */
-	max_size = PAGE_CACHE_SIZE >> 2;
+	/* Use multiples of 4 bytes, thus max_size is PAGE_CACHE_SIZE / 4. */
 	ntfs_debug("Reading $MFT/$BITMAP, max_index = 0x%lx, max_size = "
-			"0x%x.", max_index, max_size);
-	for (index = 0UL; index < max_index; index++) {
+			"0x%lx.", max_index, PAGE_CACHE_SIZE / 4);
+	for (index = 0; index < max_index; index++) {
 		unsigned int i;
 		/*
 		 * Read the page from page cache, getting it from backing store
@@ -2100,7 +2514,7 @@ static unsigned long __get_nr_free_mft_r
 		 * the result as all out of range bytes are set to zero by
 		 * ntfs_readpage().
 		 */
-	  	for (i = 0; i < max_size; i++)
+	  	for (i = 0; i < PAGE_CACHE_SIZE / 4; i++)
 			nr_free -= (s64)hweight32(kaddr[i]);
 		kunmap_atomic(kaddr, KM_USER0);
 		page_cache_release(page);
@@ -2134,8 +2548,11 @@ static unsigned long __get_nr_free_mft_r
  */
 static int ntfs_statfs(struct super_block *sb, struct kstatfs *sfs)
 {
-	ntfs_volume *vol = NTFS_SB(sb);
 	s64 size;
+	ntfs_volume *vol = NTFS_SB(sb);
+	ntfs_inode *mft_ni = NTFS_I(vol->mft_ino);
+	pgoff_t max_index;
+	unsigned long flags;
 
 	ntfs_debug("Entering.");
 	/* Type of filesystem. */
@@ -2143,13 +2560,13 @@ static int ntfs_statfs(struct super_bloc
 	/* Optimal transfer block size. */
 	sfs->f_bsize  = PAGE_CACHE_SIZE;
 	/*
-	 * Total data blocks in file system in units of f_bsize and since
+	 * Total data blocks in filesystem in units of f_bsize and since
 	 * inodes are also stored in data blocs ($MFT is a file) this is just
 	 * the total clusters.
 	 */
 	sfs->f_blocks = vol->nr_clusters << vol->cluster_size_bits >>
 				PAGE_CACHE_SHIFT;
-	/* Free data blocks in file system in units of f_bsize. */
+	/* Free data blocks in filesystem in units of f_bsize. */
 	size	      = get_nr_free_clusters(vol) << vol->cluster_size_bits >>
 				PAGE_CACHE_SHIFT;
 	if (size < 0LL)
@@ -2158,17 +2575,27 @@ static int ntfs_statfs(struct super_bloc
 	sfs->f_bavail = sfs->f_bfree = size;
 	/* Serialize accesses to the inode bitmap. */
 	down_read(&vol->mftbmp_lock);
-	/* Number of inodes in file system (at this point in time). */
-	sfs->f_files = vol->mft_ino->i_size >> vol->mft_record_size_bits;
+	read_lock_irqsave(&mft_ni->size_lock, flags);
+	size = i_size_read(vol->mft_ino) >> vol->mft_record_size_bits;
+	/*
+	 * Convert the maximum number of set bits into bytes rounded up, then
+	 * convert into multiples of PAGE_CACHE_SIZE, rounding up so that if we
+	 * have one full and one partial page max_index = 2.
+	 */
+	max_index = ((((mft_ni->initialized_size >> vol->mft_record_size_bits)
+			+ 7) >> 3) + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
+	read_unlock_irqrestore(&mft_ni->size_lock, flags);
+	/* Number of inodes in filesystem (at this point in time). */
+	sfs->f_files = size;
 	/* Free inodes in fs (based on current total count). */
-	sfs->f_ffree = __get_nr_free_mft_records(vol);
+	sfs->f_ffree = __get_nr_free_mft_records(vol, size, max_index);
 	up_read(&vol->mftbmp_lock);
 	/*
 	 * File system id. This is extremely *nix flavour dependent and even
 	 * within Linux itself all fs do their own thing. I interpret this to
 	 * mean a unique id associated with the mounted fs and not the id
-	 * associated with the file system driver, the latter is already given
-	 * by the file system type in sfs->f_type. Thus we use the 64-bit
+	 * associated with the filesystem driver, the latter is already given
+	 * by the filesystem type in sfs->f_type. Thus we use the 64-bit
 	 * volume serial number splitting it into two 32-bit parts. We enter
 	 * the least significant 32-bits in f_fsid[0] and the most significant
 	 * 32-bits in f_fsid[1].
@@ -2219,53 +2646,19 @@ static struct super_operations ntfs_sops
 						   proc. */
 };
 
-
 /**
- * Declarations for NTFS specific export operations (fs/ntfs/namei.c).
- */
-extern struct dentry *ntfs_get_parent(struct dentry *child_dent);
-extern struct dentry *ntfs_get_dentry(struct super_block *sb, void *fh);
-
-/**
- * Export operations allowing NFS exporting of mounted NTFS partitions.
- *
- * We use the default ->decode_fh() and ->encode_fh() for now.  Note that they
- * use 32 bits to store the inode number which is an unsigned long so on 64-bit
- * architectures is usually 64 bits so it would all fail horribly on huge
- * volumes.  I guess we need to define our own encode and decode fh functions
- * that store 64-bit inode numbers at some point but for now we will ignore the
- * problem...
- *
- * We also use the default ->get_name() helper (used by ->decode_fh() via
- * fs/exportfs/expfs.c::find_exported_dentry()) as that is completely fs
- * independent.
- *
- * The default ->get_parent() just returns -EACCES so we have to provide our
- * own and the default ->get_dentry() is incompatible with NTFS due to not
- * allowing the inode number 0 which is used in NTFS for the system file $MFT
- * and due to using iget() whereas NTFS needs ntfs_iget().
- */
-static struct export_operations ntfs_export_ops = {
-	.get_parent	= ntfs_get_parent,	/* Find the parent of a given
-						   directory. */
-	.get_dentry	= ntfs_get_dentry,	/* Find a dentry for the inode
-						   given a file handle
-						   sub-fragment. */
-};
-
-/**
- * ntfs_fill_super - mount an ntfs files system
- * @sb:		super block of ntfs file system to mount
+ * ntfs_fill_super - mount an ntfs filesystem
+ * @sb:		super block of ntfs filesystem to mount
  * @opt:	string containing the mount options
  * @silent:	silence error output
  *
  * ntfs_fill_super() is called by the VFS to mount the device described by @sb
- * with the mount otions in @data with the NTFS file system.
+ * with the mount otions in @data with the NTFS filesystem.
  *
  * If @silent is true, remain silent even if errors are detected. This is used
- * during bootup, when the kernel tries to mount the root file system with all
- * registered file systems one after the other until one succeeds. This implies
- * that all file systems except the correct one will quite correctly and
+ * during bootup, when the kernel tries to mount the root filesystem with all
+ * registered filesystems one after the other until one succeeds. This implies
+ * that all filesystems except the correct one will quite correctly and
  * expectedly return an error, but nobody wants to see error messages when in
  * fact this is what is supposed to happen.
  *
@@ -2292,39 +2685,25 @@ static int ntfs_fill_super(struct super_
 		return -ENOMEM;
 	}
 	/* Initialize ntfs_volume structure. */
-	memset(vol, 0, sizeof(ntfs_volume));
-	vol->sb = sb;
-	vol->upcase = NULL;
-	vol->attrdef = NULL;
-	vol->mft_ino = NULL;
-	vol->mftbmp_ino = NULL;
+	*vol = (ntfs_volume) {
+		.sb = sb,
+		/*
+		 * Default is group and other don't have any access to files or
+		 * directories while owner has full access. Further, files by
+		 * default are not executable but directories are of course
+		 * browseable.
+		 */
+		.fmask = 0177,
+		.dmask = 0077,
+	};
 	init_rwsem(&vol->mftbmp_lock);
-#ifdef NTFS_RW
-	vol->mftmirr_ino = NULL;
-	vol->logfile_ino = NULL;
-#endif /* NTFS_RW */
-	vol->lcnbmp_ino = NULL;
 	init_rwsem(&vol->lcnbmp_lock);
-	vol->vol_ino = NULL;
-	vol->root_ino = NULL;
-	vol->secure_ino = NULL;
-	vol->extend_ino = NULL;
-#ifdef NTFS_RW
-	vol->quota_ino = NULL;
-	vol->quota_q_ino = NULL;
-#endif /* NTFS_RW */
-	vol->nls_map = NULL;
-
-	/*
-	 * Default is group and other don't have any access to files or
-	 * directories while owner has full access. Further, files by default
-	 * are not executable but directories are of course browseable.
-	 */
-	vol->fmask = 0177;
-	vol->dmask = 0077;
 
 	unlock_kernel();
 
+	/* By default, enable sparse support. */
+	NVolSetSparseEnabled(vol);
+
 	/* Important to get the mount options dealt with now. */
 	if (!parse_options(vol, (char*)opt))
 		goto err_out_now;
@@ -2347,7 +2726,8 @@ static int ntfs_fill_super(struct super_
 	}
 
 	/* Get the size of the device in units of NTFS_BLOCK_SIZE bytes. */
-	vol->nr_blocks = sb->s_bdev->bd_inode->i_size >> NTFS_BLOCK_SIZE_BITS;
+	vol->nr_blocks = i_size_read(sb->s_bdev->bd_inode) >>
+			NTFS_BLOCK_SIZE_BITS;
 
 	/* Read the boot sector and return unlocked buffer head to it. */
 	if (!(bh = read_ntfs_boot_sector(sb, silent))) {
@@ -2476,6 +2856,18 @@ static int ntfs_fill_super(struct super_
 	/* NTFS 3.0+ specific clean up. */
 	if (vol->major_ver >= 3) {
 #ifdef NTFS_RW
+		if (vol->usnjrnl_j_ino) {
+			iput(vol->usnjrnl_j_ino);
+			vol->usnjrnl_j_ino = NULL;
+		}
+		if (vol->usnjrnl_max_ino) {
+			iput(vol->usnjrnl_max_ino);
+			vol->usnjrnl_max_ino = NULL;
+		}
+		if (vol->usnjrnl_ino) {
+			iput(vol->usnjrnl_ino);
+			vol->usnjrnl_ino = NULL;
+		}
 		if (vol->quota_q_ino) {
 			iput(vol->quota_q_ino);
 			vol->quota_q_ino = NULL;
@@ -2581,7 +2973,7 @@ err_out_now:
  */
 kmem_cache_t *ntfs_name_cache;
 
-/* Slab caches for efficient allocation/deallocation of of inodes. */
+/* Slab caches for efficient allocation/deallocation of inodes. */
 kmem_cache_t *ntfs_inode_cache;
 kmem_cache_t *ntfs_big_inode_cache;
 
@@ -2705,7 +3097,7 @@ static int __init init_ntfs_fs(void)
 		ntfs_debug("NTFS driver registered successfully.");
 		return 0; /* Success! */
 	}
-	printk(KERN_CRIT "NTFS: Failed to register NTFS file system driver!\n");
+	printk(KERN_CRIT "NTFS: Failed to register NTFS filesystem driver!\n");
 
 sysctl_err_out:
 	kmem_cache_destroy(ntfs_big_inode_cache);
@@ -2719,7 +3111,7 @@ actx_err_out:
 	kmem_cache_destroy(ntfs_index_ctx_cache);
 ictx_err_out:
 	if (!err) {
-		printk(KERN_CRIT "NTFS: Aborting NTFS file system driver "
+		printk(KERN_CRIT "NTFS: Aborting NTFS filesystem driver "
 				"registration...\n");
 		err = -ENOMEM;
 	}
@@ -2759,7 +3151,7 @@ static void __exit exit_ntfs_fs(void)
 }
 
 MODULE_AUTHOR("Anton Altaparmakov <aia21@cantab.net>");
-MODULE_DESCRIPTION("NTFS 1.2/3.x driver - Copyright (c) 2001-2004 Anton Altaparmakov");
+MODULE_DESCRIPTION("NTFS 1.2/3.x driver - Copyright (c) 2001-2005 Anton Altaparmakov");
 MODULE_VERSION(NTFS_VERSION);
 MODULE_LICENSE("GPL");
 #ifdef DEBUG
diff --git a/fs/ntfs/sysctl.c b/fs/ntfs/sysctl.c
--- a/fs/ntfs/sysctl.c
+++ b/fs/ntfs/sysctl.c
@@ -3,7 +3,7 @@
  *	      the Linux-NTFS project. Adapted from the old NTFS driver,
  *	      Copyright (C) 1997 Martin von Löwis, Régis Duchesne
  *
- * Copyright (c) 2002-2004 Anton Altaparmakov
+ * Copyright (c) 2002-2005 Anton Altaparmakov
  *
  * This program/include file is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as published
@@ -67,7 +67,7 @@ int ntfs_sysctl(int add)
 			return -ENOMEM;
 #ifdef CONFIG_PROC_FS
 		/*
-		 * If the proc file system is in use and we are a module, need
+		 * If the proc filesystem is in use and we are a module, need
 		 * to set the owner of our proc entry to our module. In the
 		 * non-modular case, THIS_MODULE is NULL, so this is ok.
 		 */
diff --git a/fs/ntfs/sysctl.h b/fs/ntfs/sysctl.h
--- a/fs/ntfs/sysctl.h
+++ b/fs/ntfs/sysctl.h
@@ -26,7 +26,7 @@
 
 #include <linux/config.h>
 
-#if (DEBUG && CONFIG_SYSCTL)
+#if defined(DEBUG) && defined(CONFIG_SYSCTL)
 
 extern int ntfs_sysctl(int add);
 
diff --git a/fs/ntfs/time.h b/fs/ntfs/time.h
--- a/fs/ntfs/time.h
+++ b/fs/ntfs/time.h
@@ -1,7 +1,7 @@
 /*
  * time.h - NTFS time conversion functions.  Part of the Linux-NTFS project.
  *
- * Copyright (c) 2001-2004 Anton Altaparmakov
+ * Copyright (c) 2001-2005 Anton Altaparmakov
  *
  * This program/include file is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as published
@@ -87,7 +87,7 @@ static inline struct timespec ntfs2utc(c
 	struct timespec ts;
 
 	/* Subtract the NTFS time offset. */
-	s64 t = sle64_to_cpu(time) - NTFS_TIME_OFFSET;
+	u64 t = (u64)(sle64_to_cpu(time) - NTFS_TIME_OFFSET);
 	/*
 	 * Convert the time to 1-second intervals and the remainder to
 	 * 1-nano-second intervals.
diff --git a/fs/ntfs/types.h b/fs/ntfs/types.h
--- a/fs/ntfs/types.h
+++ b/fs/ntfs/types.h
@@ -2,7 +2,7 @@
  * types.h - Defines for NTFS Linux kernel driver specific types.
  *	     Part of the Linux-NTFS project.
  *
- * Copyright (c) 2001-2004 Anton Altaparmakov
+ * Copyright (c) 2001-2005 Anton Altaparmakov
  *
  * This program/include file is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as published
@@ -53,6 +53,14 @@ typedef sle64 leLCN;
 typedef s64 LSN;
 typedef sle64 leLSN;
 
+/*
+ * The NTFS transaction log $UsnJrnl uses usn which are signed 64-bit values.
+ * We define our own type USN, to allow for type checking and better code
+ * readability.
+ */
+typedef s64 USN;
+typedef sle64 leUSN;
+
 typedef enum {
 	FALSE = 0,
 	TRUE = 1
diff --git a/fs/ntfs/unistr.c b/fs/ntfs/unistr.c
--- a/fs/ntfs/unistr.c
+++ b/fs/ntfs/unistr.c
@@ -264,7 +264,7 @@ int ntfs_nlstoucs(const ntfs_volume *vol
 
 	/* We don't trust outside sources. */
 	if (ins) {
-		ucs = (ntfschar*)kmem_cache_alloc(ntfs_name_cache, SLAB_NOFS);
+		ucs = kmem_cache_alloc(ntfs_name_cache, SLAB_NOFS);
 		if (ucs) {
 			for (i = o = 0; i < ins_len; i += wc_len) {
 				wc_len = nls->char2uni(ins + i, ins_len - i,
diff --git a/fs/ntfs/usnjrnl.c b/fs/ntfs/usnjrnl.c
new file mode 100644
--- /dev/null
+++ b/fs/ntfs/usnjrnl.c
@@ -0,0 +1,84 @@
+/*
+ * usnjrnl.h - NTFS kernel transaction log ($UsnJrnl) handling.  Part of the
+ *	       Linux-NTFS project.
+ *
+ * Copyright (c) 2005 Anton Altaparmakov
+ *
+ * This program/include file 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/include file 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 (in the main directory of the Linux-NTFS
+ * distribution in the file COPYING); if not, write to the Free Software
+ * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifdef NTFS_RW
+
+#include <linux/fs.h>
+#include <linux/highmem.h>
+#include <linux/mm.h>
+
+#include "aops.h"
+#include "debug.h"
+#include "endian.h"
+#include "time.h"
+#include "types.h"
+#include "usnjrnl.h"
+#include "volume.h"
+
+/**
+ * ntfs_stamp_usnjrnl - stamp the transaction log ($UsnJrnl) on an ntfs volume
+ * @vol:	ntfs volume on which to stamp the transaction log
+ *
+ * Stamp the transaction log ($UsnJrnl) on the ntfs volume @vol and return
+ * TRUE on success and FALSE on error.
+ *
+ * This function assumes that the transaction log has already been loaded and
+ * consistency checked by a call to fs/ntfs/super.c::load_and_init_usnjrnl().
+ */
+BOOL ntfs_stamp_usnjrnl(ntfs_volume *vol)
+{
+	ntfs_debug("Entering.");
+	if (likely(!NVolUsnJrnlStamped(vol))) {
+		sle64 stamp;
+		struct page *page;
+		USN_HEADER *uh;
+
+		page = ntfs_map_page(vol->usnjrnl_max_ino->i_mapping, 0);
+		if (IS_ERR(page)) {
+			ntfs_error(vol->sb, "Failed to read from "
+					"$UsnJrnl/$DATA/$Max attribute.");
+			return FALSE;
+		}
+		uh = (USN_HEADER*)page_address(page);
+		stamp = get_current_ntfs_time();
+		ntfs_debug("Stamping transaction log ($UsnJrnl): old "
+				"journal_id 0x%llx, old lowest_valid_usn "
+				"0x%llx, new journal_id 0x%llx, new "
+				"lowest_valid_usn 0x%llx.",
+				(long long)sle64_to_cpu(uh->journal_id),
+				(long long)sle64_to_cpu(uh->lowest_valid_usn),
+				(long long)sle64_to_cpu(stamp),
+				i_size_read(vol->usnjrnl_j_ino));
+		uh->lowest_valid_usn =
+				cpu_to_sle64(i_size_read(vol->usnjrnl_j_ino));
+		uh->journal_id = stamp;
+		flush_dcache_page(page);
+		set_page_dirty(page);
+		ntfs_unmap_page(page);
+		/* Set the flag so we do not have to do it again on remount. */
+		NVolSetUsnJrnlStamped(vol);
+	}
+	ntfs_debug("Done.");
+	return TRUE;
+}
+
+#endif /* NTFS_RW */
diff --git a/fs/ntfs/usnjrnl.h b/fs/ntfs/usnjrnl.h
new file mode 100644
--- /dev/null
+++ b/fs/ntfs/usnjrnl.h
@@ -0,0 +1,205 @@
+/*
+ * usnjrnl.h - Defines for NTFS kernel transaction log ($UsnJrnl) handling.
+ *	       Part of the Linux-NTFS project.
+ *
+ * Copyright (c) 2005 Anton Altaparmakov
+ *
+ * This program/include file 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/include file 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 (in the main directory of the Linux-NTFS
+ * distribution in the file COPYING); if not, write to the Free Software
+ * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef _LINUX_NTFS_USNJRNL_H
+#define _LINUX_NTFS_USNJRNL_H
+
+#ifdef NTFS_RW
+
+#include "types.h"
+#include "endian.h"
+#include "layout.h"
+#include "volume.h"
+
+/*
+ * Transaction log ($UsnJrnl) organization:
+ *
+ * The transaction log records whenever a file is modified in any way.  So for
+ * example it will record that file "blah" was written to at a particular time
+ * but not what was written.  If will record that a file was deleted or
+ * created, that a file was truncated, etc.  See below for all the reason
+ * codes used.
+ *
+ * The transaction log is in the $Extend directory which is in the root
+ * directory of each volume.  If it is not present it means transaction
+ * logging is disabled.  If it is present it means transaction logging is
+ * either enabled or in the process of being disabled in which case we can
+ * ignore it as it will go away as soon as Windows gets its hands on it.
+ *
+ * To determine whether the transaction logging is enabled or in the process
+ * of being disabled, need to check the volume flags in the
+ * $VOLUME_INFORMATION attribute in the $Volume system file (which is present
+ * in the root directory and has a fixed mft record number, see layout.h).
+ * If the flag VOLUME_DELETE_USN_UNDERWAY is set it means the transaction log
+ * is in the process of being disabled and if this flag is clear it means the
+ * transaction log is enabled.
+ *
+ * The transaction log consists of two parts; the $DATA/$Max attribute as well
+ * as the $DATA/$J attribute.  $Max is a header describing the transaction
+ * log whilst $J is the transaction log data itself as a sequence of variable
+ * sized USN_RECORDs (see below for all the structures).
+ *
+ * We do not care about transaction logging at this point in time but we still
+ * need to let windows know that the transaction log is out of date.  To do
+ * this we need to stamp the transaction log.  This involves setting the
+ * lowest_valid_usn field in the $DATA/$Max attribute to the usn to be used
+ * for the next added USN_RECORD to the $DATA/$J attribute as well as
+ * generating a new journal_id in $DATA/$Max.
+ *
+ * The journal_id is as of the current version (2.0) of the transaction log
+ * simply the 64-bit timestamp of when the journal was either created or last
+ * stamped.
+ *
+ * To determine the next usn there are two ways.  The first is to parse
+ * $DATA/$J and to find the last USN_RECORD in it and to add its record_length
+ * to its usn (which is the byte offset in the $DATA/$J attribute).  The
+ * second is simply to take the data size of the attribute.  Since the usns
+ * are simply byte offsets into $DATA/$J, this is exactly the next usn.  For
+ * obvious reasons we use the second method as it is much simpler and faster.
+ *
+ * As an aside, note that to actually disable the transaction log, one would
+ * need to set the VOLUME_DELETE_USN_UNDERWAY flag (see above), then go
+ * through all the mft records on the volume and set the usn field in their
+ * $STANDARD_INFORMATION attribute to zero.  Once that is done, one would need
+ * to delete the transaction log file, i.e. \$Extent\$UsnJrnl, and finally,
+ * one would need to clear the VOLUME_DELETE_USN_UNDERWAY flag.
+ *
+ * Note that if a volume is unmounted whilst the transaction log is being
+ * disabled, the process will continue the next time the volume is mounted.
+ * This is why we can safely mount read-write when we see a transaction log
+ * in the process of being deleted.
+ */
+
+/* Some $UsnJrnl related constants. */
+#define UsnJrnlMajorVer		2
+#define UsnJrnlMinorVer		0
+
+/*
+ * $DATA/$Max attribute.  This is (always?) resident and has a fixed size of
+ * 32 bytes.  It contains the header describing the transaction log.
+ */
+typedef struct {
+/*Ofs*/
+/*   0*/sle64 maximum_size;	/* The maximum on-disk size of the $DATA/$J
+				   attribute. */
+/*   8*/sle64 allocation_delta;	/* Number of bytes by which to increase the
+				   size of the $DATA/$J attribute. */
+/*0x10*/sle64 journal_id;	/* Current id of the transaction log. */
+/*0x18*/leUSN lowest_valid_usn;	/* Lowest valid usn in $DATA/$J for the
+				   current journal_id. */
+/* sizeof() = 32 (0x20) bytes */
+} __attribute__ ((__packed__)) USN_HEADER;
+
+/*
+ * Reason flags (32-bit).  Cumulative flags describing the change(s) to the
+ * file since it was last opened.  I think the names speak for themselves but
+ * if you disagree check out the descriptions in the Linux NTFS project NTFS
+ * documentation: http://linux-ntfs.sourceforge.net/ntfs/files/usnjrnl.html
+ */
+enum {
+	USN_REASON_DATA_OVERWRITE	= const_cpu_to_le32(0x00000001),
+	USN_REASON_DATA_EXTEND		= const_cpu_to_le32(0x00000002),
+	USN_REASON_DATA_TRUNCATION	= const_cpu_to_le32(0x00000004),
+	USN_REASON_NAMED_DATA_OVERWRITE	= const_cpu_to_le32(0x00000010),
+	USN_REASON_NAMED_DATA_EXTEND	= const_cpu_to_le32(0x00000020),
+	USN_REASON_NAMED_DATA_TRUNCATION= const_cpu_to_le32(0x00000040),
+	USN_REASON_FILE_CREATE		= const_cpu_to_le32(0x00000100),
+	USN_REASON_FILE_DELETE		= const_cpu_to_le32(0x00000200),
+	USN_REASON_EA_CHANGE		= const_cpu_to_le32(0x00000400),
+	USN_REASON_SECURITY_CHANGE	= const_cpu_to_le32(0x00000800),
+	USN_REASON_RENAME_OLD_NAME	= const_cpu_to_le32(0x00001000),
+	USN_REASON_RENAME_NEW_NAME	= const_cpu_to_le32(0x00002000),
+	USN_REASON_INDEXABLE_CHANGE	= const_cpu_to_le32(0x00004000),
+	USN_REASON_BASIC_INFO_CHANGE	= const_cpu_to_le32(0x00008000),
+	USN_REASON_HARD_LINK_CHANGE	= const_cpu_to_le32(0x00010000),
+	USN_REASON_COMPRESSION_CHANGE	= const_cpu_to_le32(0x00020000),
+	USN_REASON_ENCRYPTION_CHANGE	= const_cpu_to_le32(0x00040000),
+	USN_REASON_OBJECT_ID_CHANGE	= const_cpu_to_le32(0x00080000),
+	USN_REASON_REPARSE_POINT_CHANGE	= const_cpu_to_le32(0x00100000),
+	USN_REASON_STREAM_CHANGE	= const_cpu_to_le32(0x00200000),
+	USN_REASON_CLOSE		= const_cpu_to_le32(0x80000000),
+};
+
+typedef le32 USN_REASON_FLAGS;
+
+/*
+ * Source info flags (32-bit).  Information about the source of the change(s)
+ * to the file.  For detailed descriptions of what these mean, see the Linux
+ * NTFS project NTFS documentation:
+ *	http://linux-ntfs.sourceforge.net/ntfs/files/usnjrnl.html
+ */
+enum {
+	USN_SOURCE_DATA_MANAGEMENT	  = const_cpu_to_le32(0x00000001),
+	USN_SOURCE_AUXILIARY_DATA	  = const_cpu_to_le32(0x00000002),
+	USN_SOURCE_REPLICATION_MANAGEMENT = const_cpu_to_le32(0x00000004),
+};
+
+typedef le32 USN_SOURCE_INFO_FLAGS;
+
+/*
+ * $DATA/$J attribute.  This is always non-resident, is marked as sparse, and
+ * is of variabled size.  It consists of a sequence of variable size
+ * USN_RECORDS.  The minimum allocated_size is allocation_delta as
+ * specified in $DATA/$Max.  When the maximum_size specified in $DATA/$Max is
+ * exceeded by more than allocation_delta bytes, allocation_delta bytes are
+ * allocated and appended to the $DATA/$J attribute and an equal number of
+ * bytes at the beginning of the attribute are freed and made sparse.  Note the
+ * making sparse only happens at volume checkpoints and hence the actual
+ * $DATA/$J size can exceed maximum_size + allocation_delta temporarily.
+ */
+typedef struct {
+/*Ofs*/
+/*   0*/le32 length;		/* Byte size of this record (8-byte
+				   aligned). */
+/*   4*/le16 major_ver;		/* Major version of the transaction log used
+				   for this record. */
+/*   6*/le16 minor_ver;		/* Minor version of the transaction log used
+				   for this record. */
+/*   8*/leMFT_REF mft_reference;/* The mft reference of the file (or
+				   directory) described by this record. */
+/*0x10*/leMFT_REF parent_directory;/* The mft reference of the parent
+				   directory of the file described by this
+				   record. */
+/*0x18*/leUSN usn;		/* The usn of this record.  Equals the offset
+				   within the $DATA/$J attribute. */
+/*0x20*/sle64 time;		/* Time when this record was created. */
+/*0x28*/USN_REASON_FLAGS reason;/* Reason flags (see above). */
+/*0x2c*/USN_SOURCE_INFO_FLAGS source_info;/* Source info flags (see above). */
+/*0x30*/le32 security_id;	/* File security_id copied from
+				   $STANDARD_INFORMATION. */
+/*0x34*/FILE_ATTR_FLAGS file_attributes;	/* File attributes copied from
+				   $STANDARD_INFORMATION or $FILE_NAME (not
+				   sure which). */
+/*0x38*/le16 file_name_size;	/* Size of the file name in bytes. */
+/*0x3a*/le16 file_name_offset;	/* Offset to the file name in bytes from the
+				   start of this record. */
+/*0x3c*/ntfschar file_name[0];	/* Use when creating only.  When reading use
+				   file_name_offset to determine the location
+				   of the name. */
+/* sizeof() = 60 (0x3c) bytes */
+} __attribute__ ((__packed__)) USN_RECORD;
+
+extern BOOL ntfs_stamp_usnjrnl(ntfs_volume *vol);
+
+#endif /* NTFS_RW */
+
+#endif /* _LINUX_NTFS_USNJRNL_H */
diff --git a/fs/ntfs/volume.h b/fs/ntfs/volume.h
--- a/fs/ntfs/volume.h
+++ b/fs/ntfs/volume.h
@@ -2,7 +2,7 @@
  * volume.h - Defines for volume structures in NTFS Linux kernel driver. Part
  *	      of the Linux-NTFS project.
  *
- * Copyright (c) 2001-2004 Anton Altaparmakov
+ * Copyright (c) 2001-2005 Anton Altaparmakov
  * Copyright (c) 2002 Richard Russon
  *
  * This program/include file is free software; you can redistribute it and/or
@@ -54,7 +54,7 @@ typedef struct {
 	mode_t dmask;			/* The mask for directory
 					   permissions. */
 	u8 mft_zone_multiplier;		/* Initial mft zone multiplier. */
-	u8 on_errors;			/* What to do on file system errors. */
+	u8 on_errors;			/* What to do on filesystem errors. */
 	/* NTFS bootsector provided information. */
 	u16 sector_size;		/* in bytes */
 	u8 sector_size_bits;		/* log2(sector_size) */
@@ -125,6 +125,10 @@ typedef struct {
 	/* $Quota stuff is NTFS3.0+ specific.  Unused/NULL otherwise. */
 	struct inode *quota_ino;	/* The VFS inode of $Quota. */
 	struct inode *quota_q_ino;	/* Attribute inode for $Quota/$Q. */
+	/* $UsnJrnl stuff is NTFS3.0+ specific.  Unused/NULL otherwise. */
+	struct inode *usnjrnl_ino;	/* The VFS inode of $UsnJrnl. */
+	struct inode *usnjrnl_max_ino;	/* Attribute inode for $UsnJrnl/$Max. */
+	struct inode *usnjrnl_j_ino;	/* Attribute inode for $UsnJrnl/$J. */
 #endif /* NTFS_RW */
 	struct nls_table *nls_map;
 } ntfs_volume;
@@ -141,6 +145,8 @@ typedef enum {
 				      file names in WIN32 namespace. */
 	NV_LogFileEmpty,	/* 1: $LogFile journal is empty. */
 	NV_QuotaOutOfDate,	/* 1: $Quota is out of date. */
+	NV_UsnJrnlStamped,	/* 1: $UsnJrnl has been stamped. */
+	NV_SparseEnabled,	/* 1: May create sparse files. */
 } ntfs_volume_flags;
 
 /*
@@ -167,5 +173,7 @@ NVOL_FNS(ShowSystemFiles)
 NVOL_FNS(CaseSensitive)
 NVOL_FNS(LogFileEmpty)
 NVOL_FNS(QuotaOutOfDate)
+NVOL_FNS(UsnJrnlStamped)
+NVOL_FNS(SparseEnabled)
 
 #endif /* _LINUX_NTFS_VOLUME_H */
diff --git a/fs/open.c b/fs/open.c
--- a/fs/open.c
+++ b/fs/open.c
@@ -10,7 +10,7 @@
 #include <linux/file.h>
 #include <linux/smp_lock.h>
 #include <linux/quotaops.h>
-#include <linux/dnotify.h>
+#include <linux/fsnotify.h>
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/tty.h>
@@ -21,6 +21,7 @@
 #include <linux/vfs.h>
 #include <asm/uaccess.h>
 #include <linux/fs.h>
+#include <linux/personality.h>
 #include <linux/pagemap.h>
 #include <linux/syscalls.h>
 
@@ -807,7 +808,9 @@ struct file *dentry_open(struct dentry *
 
 	/* NB: we're sure to have correct a_ops only after f_op->open */
 	if (f->f_flags & O_DIRECT) {
-		if (!f->f_mapping->a_ops || !f->f_mapping->a_ops->direct_IO) {
+		if (!f->f_mapping->a_ops ||
+		    ((!f->f_mapping->a_ops->direct_IO) &&
+		    (!f->f_mapping->a_ops->get_xip_page))) {
 			fput(f);
 			f = ERR_PTR(-EINVAL);
 		}
@@ -933,31 +936,28 @@ EXPORT_SYMBOL(fd_install);
 asmlinkage long sys_open(const char __user * filename, int flags, int mode)
 {
 	char * tmp;
-	int fd, error;
+	int fd;
+
+	if (force_o_largefile())
+		flags |= O_LARGEFILE;
 
-#if BITS_PER_LONG != 32
-	flags |= O_LARGEFILE;
-#endif
 	tmp = getname(filename);
 	fd = PTR_ERR(tmp);
 	if (!IS_ERR(tmp)) {
 		fd = get_unused_fd();
 		if (fd >= 0) {
 			struct file *f = filp_open(tmp, flags, mode);
-			error = PTR_ERR(f);
-			if (IS_ERR(f))
-				goto out_error;
-			fd_install(fd, f);
+			if (IS_ERR(f)) {
+				put_unused_fd(fd);
+				fd = PTR_ERR(f);
+			} else {
+				fsnotify_open(f->f_dentry);
+				fd_install(fd, f);
+			}
 		}
-out:
 		putname(tmp);
 	}
 	return fd;
-
-out_error:
-	put_unused_fd(fd);
-	fd = error;
-	goto out;
 }
 EXPORT_SYMBOL_GPL(sys_open);
 
@@ -980,23 +980,15 @@ asmlinkage long sys_creat(const char __u
  */
 int filp_close(struct file *filp, fl_owner_t id)
 {
-	int retval;
-
-	/* Report and clear outstanding errors */
-	retval = filp->f_error;
-	if (retval)
-		filp->f_error = 0;
+	int retval = 0;
 
 	if (!file_count(filp)) {
 		printk(KERN_ERR "VFS: Close: file count is 0\n");
-		return retval;
+		return 0;
 	}
 
-	if (filp->f_op && filp->f_op->flush) {
-		int err = filp->f_op->flush(filp);
-		if (!retval)
-			retval = err;
-	}
+	if (filp->f_op && filp->f_op->flush)
+		retval = filp->f_op->flush(filp);
 
 	dnotify_flush(filp, id);
 	locks_remove_posix(filp, id);
diff --git a/fs/partitions/Makefile b/fs/partitions/Makefile
--- a/fs/partitions/Makefile
+++ b/fs/partitions/Makefile
@@ -17,4 +17,3 @@ obj-$(CONFIG_SUN_PARTITION) += sun.o
 obj-$(CONFIG_ULTRIX_PARTITION) += ultrix.o
 obj-$(CONFIG_IBM_PARTITION) += ibm.o
 obj-$(CONFIG_EFI_PARTITION) += efi.o
-obj-$(CONFIG_NEC98_PARTITION) += nec98.o msdos.o
diff --git a/fs/partitions/check.c b/fs/partitions/check.c
--- a/fs/partitions/check.c
+++ b/fs/partitions/check.c
@@ -79,9 +79,6 @@ static int (*check_part[])(struct parsed
 #ifdef CONFIG_LDM_PARTITION
 	ldm_partition,		/* this must come before msdos */
 #endif
-#ifdef CONFIG_NEC98_PARTITION
-	nec98_partition,	/* must be come before `msdos_partition' */
-#endif
 #ifdef CONFIG_MSDOS_PARTITION
 	msdos_partition,
 #endif
diff --git a/fs/partitions/check.h b/fs/partitions/check.h
--- a/fs/partitions/check.h
+++ b/fs/partitions/check.h
@@ -30,7 +30,3 @@ put_partition(struct parsed_partitions *
 
 extern int warn_no_part;
 
-extern void parse_bsd(struct parsed_partitions *state,
-			struct block_device *bdev, u32 offset, u32 size,
-			int origin, char *flavour, int max_partitions);
-
diff --git a/fs/partitions/msdos.c b/fs/partitions/msdos.c
--- a/fs/partitions/msdos.c
+++ b/fs/partitions/msdos.c
@@ -202,12 +202,12 @@ parse_solaris_x86(struct parsed_partitio
 #endif
 }
 
-#if defined(CONFIG_BSD_DISKLABEL) || defined(CONFIG_NEC98_PARTITION)
+#if defined(CONFIG_BSD_DISKLABEL)
 /* 
  * Create devices for BSD partitions listed in a disklabel, under a
  * dos-like partition. See parse_extended() for more information.
  */
-void
+static void
 parse_bsd(struct parsed_partitions *state, struct block_device *bdev,
 		u32 offset, u32 size, int origin, char *flavour,
 		int max_partitions)
diff --git a/fs/proc/Makefile b/fs/proc/Makefile
--- a/fs/proc/Makefile
+++ b/fs/proc/Makefile
@@ -11,4 +11,5 @@ proc-y       += inode.o root.o base.o ge
 		kmsg.o proc_tty.o proc_misc.o
 
 proc-$(CONFIG_PROC_KCORE)	+= kcore.o
+proc-$(CONFIG_PROC_VMCORE)	+= vmcore.o
 proc-$(CONFIG_PROC_DEVICETREE)	+= proc_devtree.o
diff --git a/fs/proc/base.c b/fs/proc/base.c
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -314,7 +314,7 @@ static int may_ptrace_attach(struct task
 	     (current->gid != task->gid)) && !capable(CAP_SYS_PTRACE))
 		goto out;
 	rmb();
-	if (!task->mm->dumpable && !capable(CAP_SYS_PTRACE))
+	if (task->mm->dumpable != 1 && !capable(CAP_SYS_PTRACE))
 		goto out;
 	if (security_ptrace(current, task))
 		goto out;
@@ -890,7 +890,7 @@ static struct file_operations proc_secco
 };
 #endif /* CONFIG_SECCOMP */
 
-static int proc_pid_follow_link(struct dentry *dentry, struct nameidata *nd)
+static void *proc_pid_follow_link(struct dentry *dentry, struct nameidata *nd)
 {
 	struct inode *inode = dentry->d_inode;
 	int error = -EACCES;
@@ -907,7 +907,7 @@ static int proc_pid_follow_link(struct d
 	error = PROC_I(inode)->op.proc_get_link(inode, &nd->dentry, &nd->mnt);
 	nd->last_type = LAST_BIND;
 out:
-	return error;
+	return ERR_PTR(error);
 }
 
 static int do_proc_readlink(struct dentry *dentry, struct vfsmount *mnt,
@@ -1113,7 +1113,9 @@ static int task_dumpable(struct task_str
 	if (mm)
 		dumpable = mm->dumpable;
 	task_unlock(task);
-	return dumpable;
+	if(dumpable == 1)
+		return 1;
+	return 0;
 }
 
 
@@ -1690,11 +1692,11 @@ static int proc_self_readlink(struct den
 	return vfs_readlink(dentry,buffer,buflen,tmp);
 }
 
-static int proc_self_follow_link(struct dentry *dentry, struct nameidata *nd)
+static void *proc_self_follow_link(struct dentry *dentry, struct nameidata *nd)
 {
 	char tmp[30];
 	sprintf(tmp, "%d", current->tgid);
-	return vfs_follow_link(nd,tmp);
+	return ERR_PTR(vfs_follow_link(nd,tmp));
 }	
 
 static struct inode_operations proc_self_inode_operations = {
diff --git a/fs/proc/generic.c b/fs/proc/generic.c
--- a/fs/proc/generic.c
+++ b/fs/proc/generic.c
@@ -329,10 +329,10 @@ static void release_inode_number(unsigne
 	spin_unlock(&proc_inum_lock);
 }
 
-static int proc_follow_link(struct dentry *dentry, struct nameidata *nd)
+static void *proc_follow_link(struct dentry *dentry, struct nameidata *nd)
 {
 	nd_set_link(nd, PDE(dentry->d_inode)->data);
-	return 0;
+	return NULL;
 }
 
 static struct inode_operations proc_link_inode_operations = {
diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c
--- a/fs/proc/proc_misc.c
+++ b/fs/proc/proc_misc.c
@@ -44,6 +44,7 @@
 #include <linux/jiffies.h>
 #include <linux/sysrq.h>
 #include <linux/vmalloc.h>
+#include <linux/crash_dump.h>
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
 #include <asm/io.h>
@@ -219,6 +220,19 @@ static struct file_operations fragmentat
 	.release	= seq_release,
 };
 
+extern struct seq_operations zoneinfo_op;
+static int zoneinfo_open(struct inode *inode, struct file *file)
+{
+	return seq_open(file, &zoneinfo_op);
+}
+
+static struct file_operations proc_zoneinfo_file_operations = {
+	.open		= zoneinfo_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= seq_release,
+};
+
 static int version_read_proc(char *page, char **start, off_t off,
 				 int count, int *eof, void *data)
 {
@@ -438,7 +452,7 @@ static int devices_read_proc(char *page,
 				 int count, int *eof, void *data)
 {
 	int len = get_chrdev_list(page);
-	len += get_blkdev_list(page+len);
+	len += get_blkdev_list(page+len, len);
 	return proc_calc_metrics(page, start, off, count, eof, len);
 }
 
@@ -589,6 +603,7 @@ void __init proc_misc_init(void)
 	create_seq_entry("slabinfo",S_IWUSR|S_IRUGO,&proc_slabinfo_operations);
 	create_seq_entry("buddyinfo",S_IRUGO, &fragmentation_file_operations);
 	create_seq_entry("vmstat",S_IRUGO, &proc_vmstat_file_operations);
+	create_seq_entry("zoneinfo",S_IRUGO, &proc_zoneinfo_file_operations);
 	create_seq_entry("diskstats", 0, &proc_diskstats_operations);
 #ifdef CONFIG_MODULES
 	create_seq_entry("modules", 0, &proc_modules_operations);
@@ -604,6 +619,11 @@ void __init proc_misc_init(void)
 				(size_t)high_memory - PAGE_OFFSET + PAGE_SIZE;
 	}
 #endif
+#ifdef CONFIG_PROC_VMCORE
+	proc_vmcore = create_proc_entry("vmcore", S_IRUSR, NULL);
+	if (proc_vmcore)
+		proc_vmcore->proc_fops = &proc_vmcore_operations;
+#endif
 #ifdef CONFIG_MAGIC_SYSRQ
 	entry = create_proc_entry("sysrq-trigger", S_IWUSR, NULL);
 	if (entry)
diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c
new file mode 100644
--- /dev/null
+++ b/fs/proc/vmcore.c
@@ -0,0 +1,669 @@
+/*
+ *	fs/proc/vmcore.c Interface for accessing the crash
+ * 				 dump from the system's previous life.
+ * 	Heavily borrowed from fs/proc/kcore.c
+ *	Created by: Hariprasad Nellitheertha (hari@in.ibm.com)
+ *	Copyright (C) IBM Corporation, 2004. All rights reserved
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/mm.h>
+#include <linux/proc_fs.h>
+#include <linux/user.h>
+#include <linux/a.out.h>
+#include <linux/elf.h>
+#include <linux/elfcore.h>
+#include <linux/proc_fs.h>
+#include <linux/highmem.h>
+#include <linux/bootmem.h>
+#include <linux/init.h>
+#include <linux/crash_dump.h>
+#include <linux/list.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+
+/* List representing chunks of contiguous memory areas and their offsets in
+ * vmcore file.
+ */
+static LIST_HEAD(vmcore_list);
+
+/* Stores the pointer to the buffer containing kernel elf core headers. */
+static char *elfcorebuf;
+static size_t elfcorebuf_sz;
+
+/* Total size of vmcore file. */
+static u64 vmcore_size;
+
+struct proc_dir_entry *proc_vmcore = NULL;
+
+/* Reads a page from the oldmem device from given offset. */
+static ssize_t read_from_oldmem(char *buf, size_t count,
+			     loff_t *ppos, int userbuf)
+{
+	unsigned long pfn, offset;
+	size_t nr_bytes;
+	ssize_t read = 0, tmp;
+
+	if (!count)
+		return 0;
+
+	offset = (unsigned long)(*ppos % PAGE_SIZE);
+	pfn = (unsigned long)(*ppos / PAGE_SIZE);
+	if (pfn > saved_max_pfn)
+		return -EINVAL;
+
+	do {
+		if (count > (PAGE_SIZE - offset))
+			nr_bytes = PAGE_SIZE - offset;
+		else
+			nr_bytes = count;
+
+		tmp = copy_oldmem_page(pfn, buf, nr_bytes, offset, userbuf);
+		if (tmp < 0)
+			return tmp;
+		*ppos += nr_bytes;
+		count -= nr_bytes;
+		buf += nr_bytes;
+		read += nr_bytes;
+		++pfn;
+		offset = 0;
+	} while (count);
+
+	return read;
+}
+
+/* Maps vmcore file offset to respective physical address in memroy. */
+static u64 map_offset_to_paddr(loff_t offset, struct list_head *vc_list,
+					struct vmcore **m_ptr)
+{
+	struct vmcore *m;
+	u64 paddr;
+
+	list_for_each_entry(m, vc_list, list) {
+		u64 start, end;
+		start = m->offset;
+		end = m->offset + m->size - 1;
+		if (offset >= start && offset <= end) {
+			paddr = m->paddr + offset - start;
+			*m_ptr = m;
+			return paddr;
+		}
+	}
+	*m_ptr = NULL;
+	return 0;
+}
+
+/* Read from the ELF header and then the crash dump. On error, negative value is
+ * returned otherwise number of bytes read are returned.
+ */
+static ssize_t read_vmcore(struct file *file, char __user *buffer,
+				size_t buflen, loff_t *fpos)
+{
+	ssize_t acc = 0, tmp;
+	size_t tsz, nr_bytes;
+	u64 start;
+	struct vmcore *curr_m = NULL;
+
+	if (buflen == 0 || *fpos >= vmcore_size)
+		return 0;
+
+	/* trim buflen to not go beyond EOF */
+	if (buflen > vmcore_size - *fpos)
+		buflen = vmcore_size - *fpos;
+
+	/* Read ELF core header */
+	if (*fpos < elfcorebuf_sz) {
+		tsz = elfcorebuf_sz - *fpos;
+		if (buflen < tsz)
+			tsz = buflen;
+		if (copy_to_user(buffer, elfcorebuf + *fpos, tsz))
+			return -EFAULT;
+		buflen -= tsz;
+		*fpos += tsz;
+		buffer += tsz;
+		acc += tsz;
+
+		/* leave now if filled buffer already */
+		if (buflen == 0)
+			return acc;
+	}
+
+	start = map_offset_to_paddr(*fpos, &vmcore_list, &curr_m);
+	if (!curr_m)
+        	return -EINVAL;
+	if ((tsz = (PAGE_SIZE - (start & ~PAGE_MASK))) > buflen)
+		tsz = buflen;
+
+	/* Calculate left bytes in current memory segment. */
+	nr_bytes = (curr_m->size - (start - curr_m->paddr));
+	if (tsz > nr_bytes)
+		tsz = nr_bytes;
+
+	while (buflen) {
+		tmp = read_from_oldmem(buffer, tsz, &start, 1);
+		if (tmp < 0)
+			return tmp;
+		buflen -= tsz;
+		*fpos += tsz;
+		buffer += tsz;
+		acc += tsz;
+		if (start >= (curr_m->paddr + curr_m->size)) {
+			if (curr_m->list.next == &vmcore_list)
+				return acc;	/*EOF*/
+			curr_m = list_entry(curr_m->list.next,
+						struct vmcore, list);
+			start = curr_m->paddr;
+		}
+		if ((tsz = (PAGE_SIZE - (start & ~PAGE_MASK))) > buflen)
+			tsz = buflen;
+		/* Calculate left bytes in current memory segment. */
+		nr_bytes = (curr_m->size - (start - curr_m->paddr));
+		if (tsz > nr_bytes)
+			tsz = nr_bytes;
+	}
+	return acc;
+}
+
+static int open_vmcore(struct inode *inode, struct file *filp)
+{
+	return 0;
+}
+
+struct file_operations proc_vmcore_operations = {
+	.read		= read_vmcore,
+	.open		= open_vmcore,
+};
+
+static struct vmcore* __init get_new_element(void)
+{
+	struct vmcore *p;
+
+	p = kmalloc(sizeof(*p), GFP_KERNEL);
+	if (p)
+		memset(p, 0, sizeof(*p));
+	return p;
+}
+
+static u64 __init get_vmcore_size_elf64(char *elfptr)
+{
+	int i;
+	u64 size;
+	Elf64_Ehdr *ehdr_ptr;
+	Elf64_Phdr *phdr_ptr;
+
+	ehdr_ptr = (Elf64_Ehdr *)elfptr;
+	phdr_ptr = (Elf64_Phdr*)(elfptr + sizeof(Elf64_Ehdr));
+	size = sizeof(Elf64_Ehdr) + ((ehdr_ptr->e_phnum) * sizeof(Elf64_Phdr));
+	for (i = 0; i < ehdr_ptr->e_phnum; i++) {
+		size += phdr_ptr->p_memsz;
+		phdr_ptr++;
+	}
+	return size;
+}
+
+static u64 __init get_vmcore_size_elf32(char *elfptr)
+{
+	int i;
+	u64 size;
+	Elf32_Ehdr *ehdr_ptr;
+	Elf32_Phdr *phdr_ptr;
+
+	ehdr_ptr = (Elf32_Ehdr *)elfptr;
+	phdr_ptr = (Elf32_Phdr*)(elfptr + sizeof(Elf32_Ehdr));
+	size = sizeof(Elf32_Ehdr) + ((ehdr_ptr->e_phnum) * sizeof(Elf32_Phdr));
+	for (i = 0; i < ehdr_ptr->e_phnum; i++) {
+		size += phdr_ptr->p_memsz;
+		phdr_ptr++;
+	}
+	return size;
+}
+
+/* Merges all the PT_NOTE headers into one. */
+static int __init merge_note_headers_elf64(char *elfptr, size_t *elfsz,
+						struct list_head *vc_list)
+{
+	int i, nr_ptnote=0, rc=0;
+	char *tmp;
+	Elf64_Ehdr *ehdr_ptr;
+	Elf64_Phdr phdr, *phdr_ptr;
+	Elf64_Nhdr *nhdr_ptr;
+	u64 phdr_sz = 0, note_off;
+
+	ehdr_ptr = (Elf64_Ehdr *)elfptr;
+	phdr_ptr = (Elf64_Phdr*)(elfptr + sizeof(Elf64_Ehdr));
+	for (i = 0; i < ehdr_ptr->e_phnum; i++, phdr_ptr++) {
+		int j;
+		void *notes_section;
+		struct vmcore *new;
+		u64 offset, max_sz, sz, real_sz = 0;
+		if (phdr_ptr->p_type != PT_NOTE)
+			continue;
+		nr_ptnote++;
+		max_sz = phdr_ptr->p_memsz;
+		offset = phdr_ptr->p_offset;
+		notes_section = kmalloc(max_sz, GFP_KERNEL);
+		if (!notes_section)
+			return -ENOMEM;
+		rc = read_from_oldmem(notes_section, max_sz, &offset, 0);
+		if (rc < 0) {
+			kfree(notes_section);
+			return rc;
+		}
+		nhdr_ptr = notes_section;
+		for (j = 0; j < max_sz; j += sz) {
+			if (nhdr_ptr->n_namesz == 0)
+				break;
+			sz = sizeof(Elf64_Nhdr) +
+				((nhdr_ptr->n_namesz + 3) & ~3) +
+				((nhdr_ptr->n_descsz + 3) & ~3);
+			real_sz += sz;
+			nhdr_ptr = (Elf64_Nhdr*)((char*)nhdr_ptr + sz);
+		}
+
+		/* Add this contiguous chunk of notes section to vmcore list.*/
+		new = get_new_element();
+		if (!new) {
+			kfree(notes_section);
+			return -ENOMEM;
+		}
+		new->paddr = phdr_ptr->p_offset;
+		new->size = real_sz;
+		list_add_tail(&new->list, vc_list);
+		phdr_sz += real_sz;
+		kfree(notes_section);
+	}
+
+	/* Prepare merged PT_NOTE program header. */
+	phdr.p_type    = PT_NOTE;
+	phdr.p_flags   = 0;
+	note_off = sizeof(Elf64_Ehdr) +
+			(ehdr_ptr->e_phnum - nr_ptnote +1) * sizeof(Elf64_Phdr);
+	phdr.p_offset  = note_off;
+	phdr.p_vaddr   = phdr.p_paddr = 0;
+	phdr.p_filesz  = phdr.p_memsz = phdr_sz;
+	phdr.p_align   = 0;
+
+	/* Add merged PT_NOTE program header*/
+	tmp = elfptr + sizeof(Elf64_Ehdr);
+	memcpy(tmp, &phdr, sizeof(phdr));
+	tmp += sizeof(phdr);
+
+	/* Remove unwanted PT_NOTE program headers. */
+	i = (nr_ptnote - 1) * sizeof(Elf64_Phdr);
+	*elfsz = *elfsz - i;
+	memmove(tmp, tmp+i, ((*elfsz)-sizeof(Elf64_Ehdr)-sizeof(Elf64_Phdr)));
+
+	/* Modify e_phnum to reflect merged headers. */
+	ehdr_ptr->e_phnum = ehdr_ptr->e_phnum - nr_ptnote + 1;
+
+	return 0;
+}
+
+/* Merges all the PT_NOTE headers into one. */
+static int __init merge_note_headers_elf32(char *elfptr, size_t *elfsz,
+						struct list_head *vc_list)
+{
+	int i, nr_ptnote=0, rc=0;
+	char *tmp;
+	Elf32_Ehdr *ehdr_ptr;
+	Elf32_Phdr phdr, *phdr_ptr;
+	Elf32_Nhdr *nhdr_ptr;
+	u64 phdr_sz = 0, note_off;
+
+	ehdr_ptr = (Elf32_Ehdr *)elfptr;
+	phdr_ptr = (Elf32_Phdr*)(elfptr + sizeof(Elf32_Ehdr));
+	for (i = 0; i < ehdr_ptr->e_phnum; i++, phdr_ptr++) {
+		int j;
+		void *notes_section;
+		struct vmcore *new;
+		u64 offset, max_sz, sz, real_sz = 0;
+		if (phdr_ptr->p_type != PT_NOTE)
+			continue;
+		nr_ptnote++;
+		max_sz = phdr_ptr->p_memsz;
+		offset = phdr_ptr->p_offset;
+		notes_section = kmalloc(max_sz, GFP_KERNEL);
+		if (!notes_section)
+			return -ENOMEM;
+		rc = read_from_oldmem(notes_section, max_sz, &offset, 0);
+		if (rc < 0) {
+			kfree(notes_section);
+			return rc;
+		}
+		nhdr_ptr = notes_section;
+		for (j = 0; j < max_sz; j += sz) {
+			if (nhdr_ptr->n_namesz == 0)
+				break;
+			sz = sizeof(Elf32_Nhdr) +
+				((nhdr_ptr->n_namesz + 3) & ~3) +
+				((nhdr_ptr->n_descsz + 3) & ~3);
+			real_sz += sz;
+			nhdr_ptr = (Elf32_Nhdr*)((char*)nhdr_ptr + sz);
+		}
+
+		/* Add this contiguous chunk of notes section to vmcore list.*/
+		new = get_new_element();
+		if (!new) {
+			kfree(notes_section);
+			return -ENOMEM;
+		}
+		new->paddr = phdr_ptr->p_offset;
+		new->size = real_sz;
+		list_add_tail(&new->list, vc_list);
+		phdr_sz += real_sz;
+		kfree(notes_section);
+	}
+
+	/* Prepare merged PT_NOTE program header. */
+	phdr.p_type    = PT_NOTE;
+	phdr.p_flags   = 0;
+	note_off = sizeof(Elf32_Ehdr) +
+			(ehdr_ptr->e_phnum - nr_ptnote +1) * sizeof(Elf32_Phdr);
+	phdr.p_offset  = note_off;
+	phdr.p_vaddr   = phdr.p_paddr = 0;
+	phdr.p_filesz  = phdr.p_memsz = phdr_sz;
+	phdr.p_align   = 0;
+
+	/* Add merged PT_NOTE program header*/
+	tmp = elfptr + sizeof(Elf32_Ehdr);
+	memcpy(tmp, &phdr, sizeof(phdr));
+	tmp += sizeof(phdr);
+
+	/* Remove unwanted PT_NOTE program headers. */
+	i = (nr_ptnote - 1) * sizeof(Elf32_Phdr);
+	*elfsz = *elfsz - i;
+	memmove(tmp, tmp+i, ((*elfsz)-sizeof(Elf32_Ehdr)-sizeof(Elf32_Phdr)));
+
+	/* Modify e_phnum to reflect merged headers. */
+	ehdr_ptr->e_phnum = ehdr_ptr->e_phnum - nr_ptnote + 1;
+
+	return 0;
+}
+
+/* Add memory chunks represented by program headers to vmcore list. Also update
+ * the new offset fields of exported program headers. */
+static int __init process_ptload_program_headers_elf64(char *elfptr,
+						size_t elfsz,
+						struct list_head *vc_list)
+{
+	int i;
+	Elf64_Ehdr *ehdr_ptr;
+	Elf64_Phdr *phdr_ptr;
+	loff_t vmcore_off;
+	struct vmcore *new;
+
+	ehdr_ptr = (Elf64_Ehdr *)elfptr;
+	phdr_ptr = (Elf64_Phdr*)(elfptr + sizeof(Elf64_Ehdr)); /* PT_NOTE hdr */
+
+	/* First program header is PT_NOTE header. */
+	vmcore_off = sizeof(Elf64_Ehdr) +
+			(ehdr_ptr->e_phnum) * sizeof(Elf64_Phdr) +
+			phdr_ptr->p_memsz; /* Note sections */
+
+	for (i = 0; i < ehdr_ptr->e_phnum; i++, phdr_ptr++) {
+		if (phdr_ptr->p_type != PT_LOAD)
+			continue;
+
+		/* Add this contiguous chunk of memory to vmcore list.*/
+		new = get_new_element();
+		if (!new)
+			return -ENOMEM;
+		new->paddr = phdr_ptr->p_offset;
+		new->size = phdr_ptr->p_memsz;
+		list_add_tail(&new->list, vc_list);
+
+		/* Update the program header offset. */
+		phdr_ptr->p_offset = vmcore_off;
+		vmcore_off = vmcore_off + phdr_ptr->p_memsz;
+	}
+	return 0;
+}
+
+static int __init process_ptload_program_headers_elf32(char *elfptr,
+						size_t elfsz,
+						struct list_head *vc_list)
+{
+	int i;
+	Elf32_Ehdr *ehdr_ptr;
+	Elf32_Phdr *phdr_ptr;
+	loff_t vmcore_off;
+	struct vmcore *new;
+
+	ehdr_ptr = (Elf32_Ehdr *)elfptr;
+	phdr_ptr = (Elf32_Phdr*)(elfptr + sizeof(Elf32_Ehdr)); /* PT_NOTE hdr */
+
+	/* First program header is PT_NOTE header. */
+	vmcore_off = sizeof(Elf32_Ehdr) +
+			(ehdr_ptr->e_phnum) * sizeof(Elf32_Phdr) +
+			phdr_ptr->p_memsz; /* Note sections */
+
+	for (i = 0; i < ehdr_ptr->e_phnum; i++, phdr_ptr++) {
+		if (phdr_ptr->p_type != PT_LOAD)
+			continue;
+
+		/* Add this contiguous chunk of memory to vmcore list.*/
+		new = get_new_element();
+		if (!new)
+			return -ENOMEM;
+		new->paddr = phdr_ptr->p_offset;
+		new->size = phdr_ptr->p_memsz;
+		list_add_tail(&new->list, vc_list);
+
+		/* Update the program header offset */
+		phdr_ptr->p_offset = vmcore_off;
+		vmcore_off = vmcore_off + phdr_ptr->p_memsz;
+	}
+	return 0;
+}
+
+/* Sets offset fields of vmcore elements. */
+static void __init set_vmcore_list_offsets_elf64(char *elfptr,
+						struct list_head *vc_list)
+{
+	loff_t vmcore_off;
+	Elf64_Ehdr *ehdr_ptr;
+	struct vmcore *m;
+
+	ehdr_ptr = (Elf64_Ehdr *)elfptr;
+
+	/* Skip Elf header and program headers. */
+	vmcore_off = sizeof(Elf64_Ehdr) +
+			(ehdr_ptr->e_phnum) * sizeof(Elf64_Phdr);
+
+	list_for_each_entry(m, vc_list, list) {
+		m->offset = vmcore_off;
+		vmcore_off += m->size;
+	}
+}
+
+/* Sets offset fields of vmcore elements. */
+static void __init set_vmcore_list_offsets_elf32(char *elfptr,
+						struct list_head *vc_list)
+{
+	loff_t vmcore_off;
+	Elf32_Ehdr *ehdr_ptr;
+	struct vmcore *m;
+
+	ehdr_ptr = (Elf32_Ehdr *)elfptr;
+
+	/* Skip Elf header and program headers. */
+	vmcore_off = sizeof(Elf32_Ehdr) +
+			(ehdr_ptr->e_phnum) * sizeof(Elf32_Phdr);
+
+	list_for_each_entry(m, vc_list, list) {
+		m->offset = vmcore_off;
+		vmcore_off += m->size;
+	}
+}
+
+static int __init parse_crash_elf64_headers(void)
+{
+	int rc=0;
+	Elf64_Ehdr ehdr;
+	u64 addr;
+
+	addr = elfcorehdr_addr;
+
+	/* Read Elf header */
+	rc = read_from_oldmem((char*)&ehdr, sizeof(Elf64_Ehdr), &addr, 0);
+	if (rc < 0)
+		return rc;
+
+	/* Do some basic Verification. */
+	if (memcmp(ehdr.e_ident, ELFMAG, SELFMAG) != 0 ||
+		(ehdr.e_type != ET_CORE) ||
+		!elf_check_arch(&ehdr) ||
+		ehdr.e_ident[EI_CLASS] != ELFCLASS64 ||
+		ehdr.e_ident[EI_VERSION] != EV_CURRENT ||
+		ehdr.e_version != EV_CURRENT ||
+		ehdr.e_ehsize != sizeof(Elf64_Ehdr) ||
+		ehdr.e_phentsize != sizeof(Elf64_Phdr) ||
+		ehdr.e_phnum == 0) {
+		printk(KERN_WARNING "Warning: Core image elf header is not"
+					"sane\n");
+		return -EINVAL;
+	}
+
+	/* Read in all elf headers. */
+	elfcorebuf_sz = sizeof(Elf64_Ehdr) + ehdr.e_phnum * sizeof(Elf64_Phdr);
+	elfcorebuf = kmalloc(elfcorebuf_sz, GFP_KERNEL);
+	if (!elfcorebuf)
+		return -ENOMEM;
+	addr = elfcorehdr_addr;
+	rc = read_from_oldmem(elfcorebuf, elfcorebuf_sz, &addr, 0);
+	if (rc < 0) {
+		kfree(elfcorebuf);
+		return rc;
+	}
+
+	/* Merge all PT_NOTE headers into one. */
+	rc = merge_note_headers_elf64(elfcorebuf, &elfcorebuf_sz, &vmcore_list);
+	if (rc) {
+		kfree(elfcorebuf);
+		return rc;
+	}
+	rc = process_ptload_program_headers_elf64(elfcorebuf, elfcorebuf_sz,
+							&vmcore_list);
+	if (rc) {
+		kfree(elfcorebuf);
+		return rc;
+	}
+	set_vmcore_list_offsets_elf64(elfcorebuf, &vmcore_list);
+	return 0;
+}
+
+static int __init parse_crash_elf32_headers(void)
+{
+	int rc=0;
+	Elf32_Ehdr ehdr;
+	u64 addr;
+
+	addr = elfcorehdr_addr;
+
+	/* Read Elf header */
+	rc = read_from_oldmem((char*)&ehdr, sizeof(Elf32_Ehdr), &addr, 0);
+	if (rc < 0)
+		return rc;
+
+	/* Do some basic Verification. */
+	if (memcmp(ehdr.e_ident, ELFMAG, SELFMAG) != 0 ||
+		(ehdr.e_type != ET_CORE) ||
+		!elf_check_arch(&ehdr) ||
+		ehdr.e_ident[EI_CLASS] != ELFCLASS32||
+		ehdr.e_ident[EI_VERSION] != EV_CURRENT ||
+		ehdr.e_version != EV_CURRENT ||
+		ehdr.e_ehsize != sizeof(Elf32_Ehdr) ||
+		ehdr.e_phentsize != sizeof(Elf32_Phdr) ||
+		ehdr.e_phnum == 0) {
+		printk(KERN_WARNING "Warning: Core image elf header is not"
+					"sane\n");
+		return -EINVAL;
+	}
+
+	/* Read in all elf headers. */
+	elfcorebuf_sz = sizeof(Elf32_Ehdr) + ehdr.e_phnum * sizeof(Elf32_Phdr);
+	elfcorebuf = kmalloc(elfcorebuf_sz, GFP_KERNEL);
+	if (!elfcorebuf)
+		return -ENOMEM;
+	addr = elfcorehdr_addr;
+	rc = read_from_oldmem(elfcorebuf, elfcorebuf_sz, &addr, 0);
+	if (rc < 0) {
+		kfree(elfcorebuf);
+		return rc;
+	}
+
+	/* Merge all PT_NOTE headers into one. */
+	rc = merge_note_headers_elf32(elfcorebuf, &elfcorebuf_sz, &vmcore_list);
+	if (rc) {
+		kfree(elfcorebuf);
+		return rc;
+	}
+	rc = process_ptload_program_headers_elf32(elfcorebuf, elfcorebuf_sz,
+								&vmcore_list);
+	if (rc) {
+		kfree(elfcorebuf);
+		return rc;
+	}
+	set_vmcore_list_offsets_elf32(elfcorebuf, &vmcore_list);
+	return 0;
+}
+
+static int __init parse_crash_elf_headers(void)
+{
+	unsigned char e_ident[EI_NIDENT];
+	u64 addr;
+	int rc=0;
+
+	addr = elfcorehdr_addr;
+	rc = read_from_oldmem(e_ident, EI_NIDENT, &addr, 0);
+	if (rc < 0)
+		return rc;
+	if (memcmp(e_ident, ELFMAG, SELFMAG) != 0) {
+		printk(KERN_WARNING "Warning: Core image elf header"
+					" not found\n");
+		return -EINVAL;
+	}
+
+	if (e_ident[EI_CLASS] == ELFCLASS64) {
+		rc = parse_crash_elf64_headers();
+		if (rc)
+			return rc;
+
+		/* Determine vmcore size. */
+		vmcore_size = get_vmcore_size_elf64(elfcorebuf);
+	} else if (e_ident[EI_CLASS] == ELFCLASS32) {
+		rc = parse_crash_elf32_headers();
+		if (rc)
+			return rc;
+
+		/* Determine vmcore size. */
+		vmcore_size = get_vmcore_size_elf32(elfcorebuf);
+	} else {
+		printk(KERN_WARNING "Warning: Core image elf header is not"
+					" sane\n");
+		return -EINVAL;
+	}
+	return 0;
+}
+
+/* Init function for vmcore module. */
+static int __init vmcore_init(void)
+{
+	int rc = 0;
+
+	/* If elfcorehdr= has been passed in cmdline, then capture the dump.*/
+	if (!(elfcorehdr_addr < ELFCORE_ADDR_MAX))
+		return rc;
+	rc = parse_crash_elf_headers();
+	if (rc) {
+		printk(KERN_WARNING "Kdump: vmcore not initialized\n");
+		return rc;
+	}
+
+	/* Initialize /proc/vmcore size if proc is already up. */
+	if (proc_vmcore)
+		proc_vmcore->size = vmcore_size;
+	return 0;
+}
+module_init(vmcore_init)
diff --git a/fs/qnx4/dir.c b/fs/qnx4/dir.c
--- a/fs/qnx4/dir.c
+++ b/fs/qnx4/dir.c
@@ -61,7 +61,7 @@ static int qnx4_readdir(struct file *fil
 						ino = blknum * QNX4_INODES_PER_BLOCK + ix - 1;
 					else {
 						le  = (struct qnx4_link_info*)de;
-						ino = ( le->dl_inode_blk - 1 ) *
+						ino = ( le32_to_cpu(le->dl_inode_blk) - 1 ) *
 							QNX4_INODES_PER_BLOCK +
 							le->dl_inode_ndx;
 					}
diff --git a/fs/qnx4/inode.c b/fs/qnx4/inode.c
--- a/fs/qnx4/inode.c
+++ b/fs/qnx4/inode.c
@@ -236,7 +236,7 @@ unsigned long qnx4_block_map( struct ino
 	struct buffer_head *bh = NULL;
 	struct qnx4_xblk *xblk = NULL;
 	struct qnx4_inode_entry *qnx4_inode = qnx4_raw_inode(inode);
-	qnx4_nxtnt_t nxtnt = le16_to_cpu(qnx4_inode->di_num_xtnts);
+	u16 nxtnt = le16_to_cpu(qnx4_inode->di_num_xtnts);
 
 	if ( iblock < le32_to_cpu(qnx4_inode->di_first_xtnt.xtnt_size) ) {
 		// iblock is in the first extent. This is easy.
@@ -372,7 +372,7 @@ static int qnx4_fill_super(struct super_
 		printk("qnx4: unable to read the superblock\n");
 		goto outnobh;
 	}
-	if ( le32_to_cpu( *(__u32*)bh->b_data ) != QNX4_SUPER_MAGIC ) {
+	if ( le32_to_cpup((__le32*) bh->b_data) != QNX4_SUPER_MAGIC ) {
 		if (!silent)
 			printk("qnx4: wrong fsid in superblock.\n");
 		goto out;
diff --git a/fs/quota.c b/fs/quota.c
--- a/fs/quota.c
+++ b/fs/quota.c
@@ -149,36 +149,6 @@ static int check_quotactl_valid(struct s
 	return error;
 }
 
-static struct super_block *get_super_to_sync(int type)
-{
-	struct list_head *head;
-	int cnt, dirty;
-
-restart:
-	spin_lock(&sb_lock);
-	list_for_each(head, &super_blocks) {
-		struct super_block *sb = list_entry(head, struct super_block, s_list);
-
-		/* This test just improves performance so it needn't be reliable... */
-		for (cnt = 0, dirty = 0; cnt < MAXQUOTAS; cnt++)
-			if ((type == cnt || type == -1) && sb_has_quota_enabled(sb, cnt)
-			    && info_any_dirty(&sb_dqopt(sb)->info[cnt]))
-				dirty = 1;
-		if (!dirty)
-			continue;
-		sb->s_count++;
-		spin_unlock(&sb_lock);
-		down_read(&sb->s_umount);
-		if (!sb->s_root) {
-			drop_super(sb);
-			goto restart;
-		}
-		return sb;
-	}
-	spin_unlock(&sb_lock);
-	return NULL;
-}
-
 static void quota_sync_sb(struct super_block *sb, int type)
 {
 	int cnt;
@@ -219,17 +189,35 @@ static void quota_sync_sb(struct super_b
 
 void sync_dquots(struct super_block *sb, int type)
 {
+	int cnt, dirty;
+
 	if (sb) {
 		if (sb->s_qcop->quota_sync)
 			quota_sync_sb(sb, type);
+		return;
 	}
-	else {
-		while ((sb = get_super_to_sync(type)) != NULL) {
-			if (sb->s_qcop->quota_sync)
-				quota_sync_sb(sb, type);
-			drop_super(sb);
-		}
+
+	spin_lock(&sb_lock);
+restart:
+	list_for_each_entry(sb, &super_blocks, s_list) {
+		/* This test just improves performance so it needn't be reliable... */
+		for (cnt = 0, dirty = 0; cnt < MAXQUOTAS; cnt++)
+			if ((type == cnt || type == -1) && sb_has_quota_enabled(sb, cnt)
+			    && info_any_dirty(&sb_dqopt(sb)->info[cnt]))
+				dirty = 1;
+		if (!dirty)
+			continue;
+		sb->s_count++;
+		spin_unlock(&sb_lock);
+		down_read(&sb->s_umount);
+		if (sb->s_root && sb->s_qcop->quota_sync)
+			quota_sync_sb(sb, type);
+		up_read(&sb->s_umount);
+		spin_lock(&sb_lock);
+		if (__put_super_and_need_restart(sb))
+			goto restart;
 	}
+	spin_unlock(&sb_lock);
 }
 
 /* Copy parameters and call proper function */
diff --git a/fs/read_write.c b/fs/read_write.c
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -10,7 +10,7 @@
 #include <linux/file.h>
 #include <linux/uio.h>
 #include <linux/smp_lock.h>
-#include <linux/dnotify.h>
+#include <linux/fsnotify.h>
 #include <linux/security.h>
 #include <linux/module.h>
 #include <linux/syscalls.h>
@@ -203,6 +203,16 @@ Einval:
 	return -EINVAL;
 }
 
+static void wait_on_retry_sync_kiocb(struct kiocb *iocb)
+{
+	set_current_state(TASK_UNINTERRUPTIBLE);
+	if (!kiocbIsKicked(iocb))
+		schedule();
+	else
+		kiocbClearKicked(iocb);
+	__set_current_state(TASK_RUNNING);
+}
+
 ssize_t do_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos)
 {
 	struct kiocb kiocb;
@@ -210,7 +220,10 @@ ssize_t do_sync_read(struct file *filp, 
 
 	init_sync_kiocb(&kiocb, filp);
 	kiocb.ki_pos = *ppos;
-	ret = filp->f_op->aio_read(&kiocb, buf, len, kiocb.ki_pos);
+	while (-EIOCBRETRY ==
+		(ret = filp->f_op->aio_read(&kiocb, buf, len, kiocb.ki_pos)))
+		wait_on_retry_sync_kiocb(&kiocb);
+
 	if (-EIOCBQUEUED == ret)
 		ret = wait_on_sync_kiocb(&kiocb);
 	*ppos = kiocb.ki_pos;
@@ -239,7 +252,7 @@ ssize_t vfs_read(struct file *file, char
 			else
 				ret = do_sync_read(file, buf, count, pos);
 			if (ret > 0) {
-				dnotify_parent(file->f_dentry, DN_ACCESS);
+				fsnotify_access(file->f_dentry);
 				current->rchar += ret;
 			}
 			current->syscr++;
@@ -258,7 +271,10 @@ ssize_t do_sync_write(struct file *filp,
 
 	init_sync_kiocb(&kiocb, filp);
 	kiocb.ki_pos = *ppos;
-	ret = filp->f_op->aio_write(&kiocb, buf, len, kiocb.ki_pos);
+	while (-EIOCBRETRY ==
+	       (ret = filp->f_op->aio_write(&kiocb, buf, len, kiocb.ki_pos)))
+		wait_on_retry_sync_kiocb(&kiocb);
+
 	if (-EIOCBQUEUED == ret)
 		ret = wait_on_sync_kiocb(&kiocb);
 	*ppos = kiocb.ki_pos;
@@ -287,7 +303,7 @@ ssize_t vfs_write(struct file *file, con
 			else
 				ret = do_sync_write(file, buf, count, pos);
 			if (ret > 0) {
-				dnotify_parent(file->f_dentry, DN_MODIFY);
+				fsnotify_modify(file->f_dentry);
 				current->wchar += ret;
 			}
 			current->syscw++;
@@ -523,9 +539,12 @@ static ssize_t do_readv_writev(int type,
 out:
 	if (iov != iovstack)
 		kfree(iov);
-	if ((ret + (type == READ)) > 0)
-		dnotify_parent(file->f_dentry,
-				(type == READ) ? DN_ACCESS : DN_MODIFY);
+	if ((ret + (type == READ)) > 0) {
+		if (type == READ)
+			fsnotify_access(file->f_dentry);
+		else
+			fsnotify_modify(file->f_dentry);
+	}
 	return ret;
 Efault:
 	ret = -EFAULT;
diff --git a/fs/reiserfs/bitmap.c b/fs/reiserfs/bitmap.c
--- a/fs/reiserfs/bitmap.c
+++ b/fs/reiserfs/bitmap.c
@@ -46,1125 +46,1221 @@
 #define TEST_OPTION(optname, s) \
     test_bit(_ALLOC_ ## optname , &SB_ALLOC_OPTS(s))
 
-static inline void get_bit_address (struct super_block * s,
-				    b_blocknr_t block, int * bmap_nr, int * offset)
+static inline void get_bit_address(struct super_block *s,
+				   b_blocknr_t block, int *bmap_nr, int *offset)
 {
-    /* It is in the bitmap block number equal to the block
-     * number divided by the number of bits in a block. */
-    *bmap_nr = block / (s->s_blocksize << 3);
-    /* Within that bitmap block it is located at bit offset *offset. */
-    *offset = block & ((s->s_blocksize << 3) - 1 );
-    return;
+	/* It is in the bitmap block number equal to the block
+	 * number divided by the number of bits in a block. */
+	*bmap_nr = block / (s->s_blocksize << 3);
+	/* Within that bitmap block it is located at bit offset *offset. */
+	*offset = block & ((s->s_blocksize << 3) - 1);
+	return;
 }
 
 #ifdef CONFIG_REISERFS_CHECK
-int is_reusable (struct super_block * s, b_blocknr_t block, int bit_value)
+int is_reusable(struct super_block *s, b_blocknr_t block, int bit_value)
 {
-    int i, j;
-
-    if (block == 0 || block >= SB_BLOCK_COUNT (s)) {
-	reiserfs_warning (s, "vs-4010: is_reusable: block number is out of range %lu (%u)",
-			  block, SB_BLOCK_COUNT (s));
-	return 0;
-    }
+	int i, j;
 
-    /* it can't be one of the bitmap blocks */
-    for (i = 0; i < SB_BMAP_NR (s); i ++)
-	if (block == SB_AP_BITMAP (s)[i].bh->b_blocknr) {
-	    reiserfs_warning (s, "vs: 4020: is_reusable: "
-			      "bitmap block %lu(%u) can't be freed or reused",
-			      block, SB_BMAP_NR (s));
-	    return 0;
-	}
-  
-    get_bit_address (s, block, &i, &j);
-
-    if (i >= SB_BMAP_NR (s)) {
-	reiserfs_warning (s, "vs-4030: is_reusable: there is no so many bitmap blocks: "
-			  "block=%lu, bitmap_nr=%d", block, i);
-	return 0;
-    }
-
-    if ((bit_value == 0 && 
-         reiserfs_test_le_bit(j, SB_AP_BITMAP(s)[i].bh->b_data)) ||
-	(bit_value == 1 && 
-	 reiserfs_test_le_bit(j, SB_AP_BITMAP (s)[i].bh->b_data) == 0)) {
-	reiserfs_warning (s, "vs-4040: is_reusable: corresponding bit of block %lu does not "
-			  "match required value (i==%d, j==%d) test_bit==%d",
-		block, i, j, reiserfs_test_le_bit (j, SB_AP_BITMAP (s)[i].bh->b_data));
+	if (block == 0 || block >= SB_BLOCK_COUNT(s)) {
+		reiserfs_warning(s,
+				 "vs-4010: is_reusable: block number is out of range %lu (%u)",
+				 block, SB_BLOCK_COUNT(s));
+		return 0;
+	}
+
+	/* it can't be one of the bitmap blocks */
+	for (i = 0; i < SB_BMAP_NR(s); i++)
+		if (block == SB_AP_BITMAP(s)[i].bh->b_blocknr) {
+			reiserfs_warning(s, "vs: 4020: is_reusable: "
+					 "bitmap block %lu(%u) can't be freed or reused",
+					 block, SB_BMAP_NR(s));
+			return 0;
+		}
 
-	return 0;
-    }
+	get_bit_address(s, block, &i, &j);
 
-    if (bit_value == 0 && block == SB_ROOT_BLOCK (s)) {
-	reiserfs_warning (s, "vs-4050: is_reusable: this is root block (%u), "
-			  "it must be busy", SB_ROOT_BLOCK (s));
-	return 0;
-    }
+	if (i >= SB_BMAP_NR(s)) {
+		reiserfs_warning(s,
+				 "vs-4030: is_reusable: there is no so many bitmap blocks: "
+				 "block=%lu, bitmap_nr=%d", block, i);
+		return 0;
+	}
+
+	if ((bit_value == 0 &&
+	     reiserfs_test_le_bit(j, SB_AP_BITMAP(s)[i].bh->b_data)) ||
+	    (bit_value == 1 &&
+	     reiserfs_test_le_bit(j, SB_AP_BITMAP(s)[i].bh->b_data) == 0)) {
+		reiserfs_warning(s,
+				 "vs-4040: is_reusable: corresponding bit of block %lu does not "
+				 "match required value (i==%d, j==%d) test_bit==%d",
+				 block, i, j, reiserfs_test_le_bit(j,
+								   SB_AP_BITMAP
+								   (s)[i].bh->
+								   b_data));
+
+		return 0;
+	}
+
+	if (bit_value == 0 && block == SB_ROOT_BLOCK(s)) {
+		reiserfs_warning(s,
+				 "vs-4050: is_reusable: this is root block (%u), "
+				 "it must be busy", SB_ROOT_BLOCK(s));
+		return 0;
+	}
 
-    return 1;
+	return 1;
 }
-#endif /* CONFIG_REISERFS_CHECK */
+#endif				/* CONFIG_REISERFS_CHECK */
 
 /* searches in journal structures for a given block number (bmap, off). If block
    is found in reiserfs journal it suggests next free block candidate to test. */
-static inline  int is_block_in_journal (struct super_block * s, int bmap, int
-off, int *next)
+static inline int is_block_in_journal(struct super_block *s, int bmap, int
+				      off, int *next)
 {
-    b_blocknr_t tmp;
+	b_blocknr_t tmp;
 
-    if (reiserfs_in_journal (s, bmap, off, 1, &tmp)) {
-	if (tmp) {              /* hint supplied */
-	    *next = tmp;
-	    PROC_INFO_INC( s, scan_bitmap.in_journal_hint );
-	} else {
-	    (*next) = off + 1;          /* inc offset to avoid looping. */
-	    PROC_INFO_INC( s, scan_bitmap.in_journal_nohint );
+	if (reiserfs_in_journal(s, bmap, off, 1, &tmp)) {
+		if (tmp) {	/* hint supplied */
+			*next = tmp;
+			PROC_INFO_INC(s, scan_bitmap.in_journal_hint);
+		} else {
+			(*next) = off + 1;	/* inc offset to avoid looping. */
+			PROC_INFO_INC(s, scan_bitmap.in_journal_nohint);
+		}
+		PROC_INFO_INC(s, scan_bitmap.retry);
+		return 1;
 	}
-	PROC_INFO_INC( s, scan_bitmap.retry );
-	return 1;
-    }
-    return 0;
+	return 0;
 }
 
 /* it searches for a window of zero bits with given minimum and maximum lengths in one bitmap
  * block; */
-static int scan_bitmap_block (struct reiserfs_transaction_handle *th,
-			      int bmap_n, int *beg, int boundary, int min, int max, int unfm)
-{
-    struct super_block *s = th->t_super;
-    struct reiserfs_bitmap_info *bi=&SB_AP_BITMAP(s)[bmap_n];
-    int end, next;
-    int org = *beg;
-
-    BUG_ON (!th->t_trans_id);
-
-    RFALSE(bmap_n >= SB_BMAP_NR (s), "Bitmap %d is out of range (0..%d)",bmap_n, SB_BMAP_NR (s) - 1);
-    PROC_INFO_INC( s, scan_bitmap.bmap );
+static int scan_bitmap_block(struct reiserfs_transaction_handle *th,
+			     int bmap_n, int *beg, int boundary, int min,
+			     int max, int unfm)
+{
+	struct super_block *s = th->t_super;
+	struct reiserfs_bitmap_info *bi = &SB_AP_BITMAP(s)[bmap_n];
+	int end, next;
+	int org = *beg;
+
+	BUG_ON(!th->t_trans_id);
+
+	RFALSE(bmap_n >= SB_BMAP_NR(s), "Bitmap %d is out of range (0..%d)",
+	       bmap_n, SB_BMAP_NR(s) - 1);
+	PROC_INFO_INC(s, scan_bitmap.bmap);
 /* this is unclear and lacks comments, explain how journal bitmaps
    work here for the reader.  Convey a sense of the design here. What
    is a window? */
 /* - I mean `a window of zero bits' as in description of this function - Zam. */
-  
-    if ( !bi ) {
-	reiserfs_warning (s, "NULL bitmap info pointer for bitmap %d", bmap_n);
-	return 0;
-    }
-    if (buffer_locked (bi->bh)) {
-       PROC_INFO_INC( s, scan_bitmap.wait );
-       __wait_on_buffer (bi->bh);
-    }
-
-    while (1) {
-	cont:
-	if (bi->free_count < min)
-		return 0; // No free blocks in this bitmap
-
-	/* search for a first zero bit -- beggining of a window */
-	*beg = reiserfs_find_next_zero_le_bit
-	        ((unsigned long*)(bi->bh->b_data), boundary, *beg);
-  
-	if (*beg + min > boundary) { /* search for a zero bit fails or the rest of bitmap block
-				      * cannot contain a zero window of minimum size */
-	    return 0;
-	}
-
-	if (unfm && is_block_in_journal(s,bmap_n, *beg, beg))
-	    continue;
-	/* first zero bit found; we check next bits */
-	for (end = *beg + 1;; end ++) {
-	    if (end >= *beg + max || end >= boundary || reiserfs_test_le_bit (end, bi->bh->b_data)) {
-		next = end;
-		break;
-	    }
-	    /* finding the other end of zero bit window requires looking into journal structures (in
-	     * case of searching for free blocks for unformatted nodes) */
-	    if (unfm && is_block_in_journal(s, bmap_n, end, &next))
-		break;
-	}
-
-	/* now (*beg) points to beginning of zero bits window,
-	 * (end) points to one bit after the window end */
-	if (end - *beg >= min) { /* it seems we have found window of proper size */
-	    int i;
-	    reiserfs_prepare_for_journal (s, bi->bh, 1);
-	    /* try to set all blocks used checking are they still free */
-	    for (i = *beg; i < end; i++) {
-		/* It seems that we should not check in journal again. */
-		if (reiserfs_test_and_set_le_bit (i, bi->bh->b_data)) {
-		    /* bit was set by another process
-		     * while we slept in prepare_for_journal() */
-		    PROC_INFO_INC( s, scan_bitmap.stolen );
-		    if (i >= *beg + min)	{ /* we can continue with smaller set of allocated blocks,
-					   * if length of this set is more or equal to `min' */
-			end = i;
-			break;
-		    }
-		    /* otherwise we clear all bit were set ... */
-		    while (--i >= *beg)
-			reiserfs_test_and_clear_le_bit (i, bi->bh->b_data);
-		    reiserfs_restore_prepared_buffer (s, bi->bh);
-		    *beg = org;
-		    /* ... and search again in current block from beginning */
-		    goto cont;	
-		}
-	    }
-	    bi->free_count -= (end - *beg);
-	    journal_mark_dirty (th, s, bi->bh);
-
-	    /* free block count calculation */
-	    reiserfs_prepare_for_journal (s, SB_BUFFER_WITH_SB(s), 1);
-	    PUT_SB_FREE_BLOCKS(s, SB_FREE_BLOCKS(s) - (end - *beg));
-	    journal_mark_dirty (th, s, SB_BUFFER_WITH_SB(s));
 
-	    return end - (*beg);
-	} else {
-	    *beg = next;
+	if (!bi) {
+		reiserfs_warning(s, "NULL bitmap info pointer for bitmap %d",
+				 bmap_n);
+		return 0;
+	}
+	if (buffer_locked(bi->bh)) {
+		PROC_INFO_INC(s, scan_bitmap.wait);
+		__wait_on_buffer(bi->bh);
+	}
+
+	while (1) {
+	      cont:
+		if (bi->free_count < min)
+			return 0;	// No free blocks in this bitmap
+
+		/* search for a first zero bit -- beggining of a window */
+		*beg = reiserfs_find_next_zero_le_bit
+		    ((unsigned long *)(bi->bh->b_data), boundary, *beg);
+
+		if (*beg + min > boundary) {	/* search for a zero bit fails or the rest of bitmap block
+						 * cannot contain a zero window of minimum size */
+			return 0;
+		}
+
+		if (unfm && is_block_in_journal(s, bmap_n, *beg, beg))
+			continue;
+		/* first zero bit found; we check next bits */
+		for (end = *beg + 1;; end++) {
+			if (end >= *beg + max || end >= boundary
+			    || reiserfs_test_le_bit(end, bi->bh->b_data)) {
+				next = end;
+				break;
+			}
+			/* finding the other end of zero bit window requires looking into journal structures (in
+			 * case of searching for free blocks for unformatted nodes) */
+			if (unfm && is_block_in_journal(s, bmap_n, end, &next))
+				break;
+		}
+
+		/* now (*beg) points to beginning of zero bits window,
+		 * (end) points to one bit after the window end */
+		if (end - *beg >= min) {	/* it seems we have found window of proper size */
+			int i;
+			reiserfs_prepare_for_journal(s, bi->bh, 1);
+			/* try to set all blocks used checking are they still free */
+			for (i = *beg; i < end; i++) {
+				/* It seems that we should not check in journal again. */
+				if (reiserfs_test_and_set_le_bit
+				    (i, bi->bh->b_data)) {
+					/* bit was set by another process
+					 * while we slept in prepare_for_journal() */
+					PROC_INFO_INC(s, scan_bitmap.stolen);
+					if (i >= *beg + min) {	/* we can continue with smaller set of allocated blocks,
+								 * if length of this set is more or equal to `min' */
+						end = i;
+						break;
+					}
+					/* otherwise we clear all bit were set ... */
+					while (--i >= *beg)
+						reiserfs_test_and_clear_le_bit
+						    (i, bi->bh->b_data);
+					reiserfs_restore_prepared_buffer(s,
+									 bi->
+									 bh);
+					*beg = org;
+					/* ... and search again in current block from beginning */
+					goto cont;
+				}
+			}
+			bi->free_count -= (end - *beg);
+			journal_mark_dirty(th, s, bi->bh);
+
+			/* free block count calculation */
+			reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s),
+						     1);
+			PUT_SB_FREE_BLOCKS(s, SB_FREE_BLOCKS(s) - (end - *beg));
+			journal_mark_dirty(th, s, SB_BUFFER_WITH_SB(s));
+
+			return end - (*beg);
+		} else {
+			*beg = next;
+		}
 	}
-    }
 }
 
-static int bmap_hash_id(struct super_block *s, u32 id) {
-    char * hash_in = NULL;
-    unsigned long hash;
-    unsigned bm;
-
-    if (id <= 2) {
-	bm = 1;
-    } else {
-        hash_in = (char *)(&id);
-        hash = keyed_hash(hash_in, 4);
-	bm = hash % SB_BMAP_NR(s);
-	if (!bm)
-	    bm = 1;
-    }
-    /* this can only be true when SB_BMAP_NR = 1 */
-    if (bm >= SB_BMAP_NR(s))
-    	bm = 0;
-    return bm;
+static int bmap_hash_id(struct super_block *s, u32 id)
+{
+	char *hash_in = NULL;
+	unsigned long hash;
+	unsigned bm;
+
+	if (id <= 2) {
+		bm = 1;
+	} else {
+		hash_in = (char *)(&id);
+		hash = keyed_hash(hash_in, 4);
+		bm = hash % SB_BMAP_NR(s);
+		if (!bm)
+			bm = 1;
+	}
+	/* this can only be true when SB_BMAP_NR = 1 */
+	if (bm >= SB_BMAP_NR(s))
+		bm = 0;
+	return bm;
 }
 
 /*
  * hashes the id and then returns > 0 if the block group for the
  * corresponding hash is full
  */
-static inline int block_group_used(struct super_block *s, u32 id) {
-    int bm;
-    bm = bmap_hash_id(s, id);
-    if (SB_AP_BITMAP(s)[bm].free_count > ((s->s_blocksize << 3) * 60 / 100) ) {
-        return 0;
-    }
-    return 1;
+static inline int block_group_used(struct super_block *s, u32 id)
+{
+	int bm;
+	bm = bmap_hash_id(s, id);
+	if (SB_AP_BITMAP(s)[bm].free_count > ((s->s_blocksize << 3) * 60 / 100)) {
+		return 0;
+	}
+	return 1;
 }
 
 /*
  * the packing is returned in disk byte order
  */
-__le32 reiserfs_choose_packing(struct inode *dir)
+__le32 reiserfs_choose_packing(struct inode * dir)
 {
-    __le32 packing;
-    if (TEST_OPTION(packing_groups, dir->i_sb)) {
-	u32 parent_dir = le32_to_cpu(INODE_PKEY(dir)->k_dir_id);
-	/*
-	 * some versions of reiserfsck expect packing locality 1 to be
-	 * special
-	 */
-	if (parent_dir == 1 || block_group_used(dir->i_sb,parent_dir))
-            packing = INODE_PKEY(dir)->k_objectid;
-        else
-            packing = INODE_PKEY(dir)->k_dir_id;
-    } else
-        packing = INODE_PKEY(dir)->k_objectid;
-    return packing;
+	__le32 packing;
+	if (TEST_OPTION(packing_groups, dir->i_sb)) {
+		u32 parent_dir = le32_to_cpu(INODE_PKEY(dir)->k_dir_id);
+		/*
+		 * some versions of reiserfsck expect packing locality 1 to be
+		 * special
+		 */
+		if (parent_dir == 1 || block_group_used(dir->i_sb, parent_dir))
+			packing = INODE_PKEY(dir)->k_objectid;
+		else
+			packing = INODE_PKEY(dir)->k_dir_id;
+	} else
+		packing = INODE_PKEY(dir)->k_objectid;
+	return packing;
 }
-  
+
 /* Tries to find contiguous zero bit window (given size) in given region of
  * bitmap and place new blocks there. Returns number of allocated blocks. */
-static int scan_bitmap (struct reiserfs_transaction_handle *th,
-			b_blocknr_t *start, b_blocknr_t finish,
-			int min, int max, int unfm, unsigned long file_block)
-{
-    int nr_allocated=0;
-    struct super_block * s = th->t_super;
-    /* find every bm and bmap and bmap_nr in this file, and change them all to bitmap_blocknr
-     * - Hans, it is not a block number - Zam. */
-
-    int bm, off;
-    int end_bm, end_off;
-    int off_max = s->s_blocksize << 3;
-
-    BUG_ON (!th->t_trans_id);
-
-    PROC_INFO_INC( s, scan_bitmap.call ); 
-    if ( SB_FREE_BLOCKS(s) <= 0)
-	return 0; // No point in looking for more free blocks
-
-    get_bit_address (s, *start, &bm, &off);
-    get_bit_address (s, finish, &end_bm, &end_off);
-    if (bm > SB_BMAP_NR(s))
-        return 0;
-    if (end_bm > SB_BMAP_NR(s))
-        end_bm = SB_BMAP_NR(s);
-
-    /* When the bitmap is more than 10% free, anyone can allocate.
-     * When it's less than 10% free, only files that already use the
-     * bitmap are allowed. Once we pass 80% full, this restriction
-     * is lifted.
-     *
-     * We do this so that files that grow later still have space close to
-     * their original allocation. This improves locality, and presumably
-     * performance as a result.
-     *
-     * This is only an allocation policy and does not make up for getting a
-     * bad hint. Decent hinting must be implemented for this to work well.
-     */
-    if ( TEST_OPTION(skip_busy, s) && SB_FREE_BLOCKS(s) > SB_BLOCK_COUNT(s)/20 ) {
-	for (;bm < end_bm; bm++, off = 0) {
-	    if ( ( off && (!unfm || (file_block != 0))) || SB_AP_BITMAP(s)[bm].free_count > (s->s_blocksize << 3) / 10 )
-		nr_allocated = scan_bitmap_block(th, bm, &off, off_max, min, max, unfm);
-	    if (nr_allocated)
-		goto ret;
-        }
-	/* we know from above that start is a reasonable number */
-	get_bit_address (s, *start, &bm, &off);
-    }
-
-    for (;bm < end_bm; bm++, off = 0) {
-	nr_allocated = scan_bitmap_block(th, bm, &off, off_max, min, max, unfm);
-	if (nr_allocated)
-	    goto ret;
-    }
-
-    nr_allocated = scan_bitmap_block(th, bm, &off, end_off + 1, min, max, unfm);
-  
- ret:
-    *start = bm * off_max + off;
-    return nr_allocated;
-
-}
-
-static void _reiserfs_free_block (struct reiserfs_transaction_handle *th,
-				  struct inode *inode, b_blocknr_t block,
-				  int for_unformatted)
-{
-    struct super_block * s = th->t_super;
-    struct reiserfs_super_block * rs;
-    struct buffer_head * sbh;
-    struct reiserfs_bitmap_info *apbi;
-    int nr, offset;
-
-    BUG_ON (!th->t_trans_id);
-
-    PROC_INFO_INC( s, free_block );
-
-    rs = SB_DISK_SUPER_BLOCK (s);
-    sbh = SB_BUFFER_WITH_SB (s);
-    apbi = SB_AP_BITMAP(s);
-
-    get_bit_address (s, block, &nr, &offset);
-
-    if (nr >= sb_bmap_nr (rs)) {
-	reiserfs_warning (s, "vs-4075: reiserfs_free_block: "
-			  "block %lu is out of range on %s",
-			  block, reiserfs_bdevname (s));
-	return;
-    }
+static int scan_bitmap(struct reiserfs_transaction_handle *th,
+		       b_blocknr_t * start, b_blocknr_t finish,
+		       int min, int max, int unfm, unsigned long file_block)
+{
+	int nr_allocated = 0;
+	struct super_block *s = th->t_super;
+	/* find every bm and bmap and bmap_nr in this file, and change them all to bitmap_blocknr
+	 * - Hans, it is not a block number - Zam. */
+
+	int bm, off;
+	int end_bm, end_off;
+	int off_max = s->s_blocksize << 3;
+
+	BUG_ON(!th->t_trans_id);
+
+	PROC_INFO_INC(s, scan_bitmap.call);
+	if (SB_FREE_BLOCKS(s) <= 0)
+		return 0;	// No point in looking for more free blocks
+
+	get_bit_address(s, *start, &bm, &off);
+	get_bit_address(s, finish, &end_bm, &end_off);
+	if (bm > SB_BMAP_NR(s))
+		return 0;
+	if (end_bm > SB_BMAP_NR(s))
+		end_bm = SB_BMAP_NR(s);
+
+	/* When the bitmap is more than 10% free, anyone can allocate.
+	 * When it's less than 10% free, only files that already use the
+	 * bitmap are allowed. Once we pass 80% full, this restriction
+	 * is lifted.
+	 *
+	 * We do this so that files that grow later still have space close to
+	 * their original allocation. This improves locality, and presumably
+	 * performance as a result.
+	 *
+	 * This is only an allocation policy and does not make up for getting a
+	 * bad hint. Decent hinting must be implemented for this to work well.
+	 */
+	if (TEST_OPTION(skip_busy, s)
+	    && SB_FREE_BLOCKS(s) > SB_BLOCK_COUNT(s) / 20) {
+		for (; bm < end_bm; bm++, off = 0) {
+			if ((off && (!unfm || (file_block != 0)))
+			    || SB_AP_BITMAP(s)[bm].free_count >
+			    (s->s_blocksize << 3) / 10)
+				nr_allocated =
+				    scan_bitmap_block(th, bm, &off, off_max,
+						      min, max, unfm);
+			if (nr_allocated)
+				goto ret;
+		}
+		/* we know from above that start is a reasonable number */
+		get_bit_address(s, *start, &bm, &off);
+	}
 
-    reiserfs_prepare_for_journal(s, apbi[nr].bh, 1 ) ;
+	for (; bm < end_bm; bm++, off = 0) {
+		nr_allocated =
+		    scan_bitmap_block(th, bm, &off, off_max, min, max, unfm);
+		if (nr_allocated)
+			goto ret;
+	}
 
-    /* clear bit for the given block in bit map */
-    if (!reiserfs_test_and_clear_le_bit (offset, apbi[nr].bh->b_data)) {
-	reiserfs_warning (s, "vs-4080: reiserfs_free_block: "
-			  "free_block (%s:%lu)[dev:blocknr]: bit already cleared",
-			  reiserfs_bdevname (s), block);
-    }
-    apbi[nr].free_count ++;
-    journal_mark_dirty (th, s, apbi[nr].bh);
+	nr_allocated =
+	    scan_bitmap_block(th, bm, &off, end_off + 1, min, max, unfm);
 
-    reiserfs_prepare_for_journal(s, sbh, 1) ;
-    /* update super block */
-    set_sb_free_blocks( rs, sb_free_blocks(rs) + 1 );
+      ret:
+	*start = bm * off_max + off;
+	return nr_allocated;
 
-    journal_mark_dirty (th, s, sbh);
-    if (for_unformatted)
-        DQUOT_FREE_BLOCK_NODIRTY(inode, 1);
 }
 
-void reiserfs_free_block (struct reiserfs_transaction_handle *th, 
-			  struct inode *inode, b_blocknr_t block,
-			  int for_unformatted)
+static void _reiserfs_free_block(struct reiserfs_transaction_handle *th,
+				 struct inode *inode, b_blocknr_t block,
+				 int for_unformatted)
 {
-    struct super_block * s = th->t_super;
+	struct super_block *s = th->t_super;
+	struct reiserfs_super_block *rs;
+	struct buffer_head *sbh;
+	struct reiserfs_bitmap_info *apbi;
+	int nr, offset;
 
-    BUG_ON (!th->t_trans_id);
+	BUG_ON(!th->t_trans_id);
+
+	PROC_INFO_INC(s, free_block);
+
+	rs = SB_DISK_SUPER_BLOCK(s);
+	sbh = SB_BUFFER_WITH_SB(s);
+	apbi = SB_AP_BITMAP(s);
+
+	get_bit_address(s, block, &nr, &offset);
+
+	if (nr >= sb_bmap_nr(rs)) {
+		reiserfs_warning(s, "vs-4075: reiserfs_free_block: "
+				 "block %lu is out of range on %s",
+				 block, reiserfs_bdevname(s));
+		return;
+	}
 
-    RFALSE(!s, "vs-4061: trying to free block on nonexistent device");
-    RFALSE(is_reusable (s, block, 1) == 0, "vs-4071: can not free such block");
-    /* mark it before we clear it, just in case */
-    journal_mark_freed(th, s, block) ;
-    _reiserfs_free_block(th, inode, block, for_unformatted) ;
+	reiserfs_prepare_for_journal(s, apbi[nr].bh, 1);
+
+	/* clear bit for the given block in bit map */
+	if (!reiserfs_test_and_clear_le_bit(offset, apbi[nr].bh->b_data)) {
+		reiserfs_warning(s, "vs-4080: reiserfs_free_block: "
+				 "free_block (%s:%lu)[dev:blocknr]: bit already cleared",
+				 reiserfs_bdevname(s), block);
+	}
+	apbi[nr].free_count++;
+	journal_mark_dirty(th, s, apbi[nr].bh);
+
+	reiserfs_prepare_for_journal(s, sbh, 1);
+	/* update super block */
+	set_sb_free_blocks(rs, sb_free_blocks(rs) + 1);
+
+	journal_mark_dirty(th, s, sbh);
+	if (for_unformatted)
+		DQUOT_FREE_BLOCK_NODIRTY(inode, 1);
 }
 
-/* preallocated blocks don't need to be run through journal_mark_freed */
-static void reiserfs_free_prealloc_block (struct reiserfs_transaction_handle *th,
-			  struct inode *inode, b_blocknr_t block) {
-    RFALSE(!th->t_super, "vs-4060: trying to free block on nonexistent device");
-    RFALSE(is_reusable (th->t_super, block, 1) == 0, "vs-4070: can not free such block");
-    BUG_ON (!th->t_trans_id);
-    _reiserfs_free_block(th, inode, block, 1) ;
+void reiserfs_free_block(struct reiserfs_transaction_handle *th,
+			 struct inode *inode, b_blocknr_t block,
+			 int for_unformatted)
+{
+	struct super_block *s = th->t_super;
+
+	BUG_ON(!th->t_trans_id);
+
+	RFALSE(!s, "vs-4061: trying to free block on nonexistent device");
+	RFALSE(is_reusable(s, block, 1) == 0,
+	       "vs-4071: can not free such block");
+	/* mark it before we clear it, just in case */
+	journal_mark_freed(th, s, block);
+	_reiserfs_free_block(th, inode, block, for_unformatted);
 }
 
-static void __discard_prealloc (struct reiserfs_transaction_handle * th,
-				struct reiserfs_inode_info *ei)
-{
-    unsigned long save = ei->i_prealloc_block ;
-    int dirty = 0;
-    struct inode *inode = &ei->vfs_inode;
-    BUG_ON (!th->t_trans_id);
+/* preallocated blocks don't need to be run through journal_mark_freed */
+static void reiserfs_free_prealloc_block(struct reiserfs_transaction_handle *th,
+					 struct inode *inode, b_blocknr_t block)
+{
+	RFALSE(!th->t_super,
+	       "vs-4060: trying to free block on nonexistent device");
+	RFALSE(is_reusable(th->t_super, block, 1) == 0,
+	       "vs-4070: can not free such block");
+	BUG_ON(!th->t_trans_id);
+	_reiserfs_free_block(th, inode, block, 1);
+}
+
+static void __discard_prealloc(struct reiserfs_transaction_handle *th,
+			       struct reiserfs_inode_info *ei)
+{
+	unsigned long save = ei->i_prealloc_block;
+	int dirty = 0;
+	struct inode *inode = &ei->vfs_inode;
+	BUG_ON(!th->t_trans_id);
 #ifdef CONFIG_REISERFS_CHECK
-    if (ei->i_prealloc_count < 0)
-	reiserfs_warning (th->t_super, "zam-4001:%s: inode has negative prealloc blocks count.", __FUNCTION__ );
+	if (ei->i_prealloc_count < 0)
+		reiserfs_warning(th->t_super,
+				 "zam-4001:%s: inode has negative prealloc blocks count.",
+				 __FUNCTION__);
 #endif
-    while (ei->i_prealloc_count > 0) {
-	reiserfs_free_prealloc_block(th, inode, ei->i_prealloc_block);
-	ei->i_prealloc_block++;
-	ei->i_prealloc_count --;
-	dirty = 1;
-    }
-    if (dirty)
-    	reiserfs_update_sd(th, inode);
-    ei->i_prealloc_block = save;
-    list_del_init(&(ei->i_prealloc_list));
+	while (ei->i_prealloc_count > 0) {
+		reiserfs_free_prealloc_block(th, inode, ei->i_prealloc_block);
+		ei->i_prealloc_block++;
+		ei->i_prealloc_count--;
+		dirty = 1;
+	}
+	if (dirty)
+		reiserfs_update_sd(th, inode);
+	ei->i_prealloc_block = save;
+	list_del_init(&(ei->i_prealloc_list));
 }
 
 /* FIXME: It should be inline function */
-void reiserfs_discard_prealloc (struct reiserfs_transaction_handle *th, 
-				struct inode *inode)
+void reiserfs_discard_prealloc(struct reiserfs_transaction_handle *th,
+			       struct inode *inode)
 {
-    struct reiserfs_inode_info *ei = REISERFS_I(inode);
-    BUG_ON (!th->t_trans_id);
-    if (ei->i_prealloc_count)
-	__discard_prealloc(th, ei);
+	struct reiserfs_inode_info *ei = REISERFS_I(inode);
+	BUG_ON(!th->t_trans_id);
+	if (ei->i_prealloc_count)
+		__discard_prealloc(th, ei);
 }
 
-void reiserfs_discard_all_prealloc (struct reiserfs_transaction_handle *th)
+void reiserfs_discard_all_prealloc(struct reiserfs_transaction_handle *th)
 {
-    struct list_head * plist = &SB_JOURNAL(th->t_super)->j_prealloc_list;
+	struct list_head *plist = &SB_JOURNAL(th->t_super)->j_prealloc_list;
 
-    BUG_ON (!th->t_trans_id);
+	BUG_ON(!th->t_trans_id);
 
-    while (!list_empty(plist)) {
-	struct reiserfs_inode_info *ei;
-	ei = list_entry(plist->next, struct reiserfs_inode_info, i_prealloc_list);
+	while (!list_empty(plist)) {
+		struct reiserfs_inode_info *ei;
+		ei = list_entry(plist->next, struct reiserfs_inode_info,
+				i_prealloc_list);
 #ifdef CONFIG_REISERFS_CHECK
-	if (!ei->i_prealloc_count) {
-	    reiserfs_warning (th->t_super, "zam-4001:%s: inode is in prealloc list but has no preallocated blocks.", __FUNCTION__);
-	}
+		if (!ei->i_prealloc_count) {
+			reiserfs_warning(th->t_super,
+					 "zam-4001:%s: inode is in prealloc list but has no preallocated blocks.",
+					 __FUNCTION__);
+		}
 #endif
-	__discard_prealloc(th, ei);
-    }
+		__discard_prealloc(th, ei);
+	}
 }
 
-void reiserfs_init_alloc_options (struct super_block *s)
+void reiserfs_init_alloc_options(struct super_block *s)
 {
-    set_bit (_ALLOC_skip_busy, &SB_ALLOC_OPTS(s));
-    set_bit (_ALLOC_dirid_groups, &SB_ALLOC_OPTS(s));
-    set_bit (_ALLOC_packing_groups, &SB_ALLOC_OPTS(s));
+	set_bit(_ALLOC_skip_busy, &SB_ALLOC_OPTS(s));
+	set_bit(_ALLOC_dirid_groups, &SB_ALLOC_OPTS(s));
+	set_bit(_ALLOC_packing_groups, &SB_ALLOC_OPTS(s));
 }
 
 /* block allocator related options are parsed here */
-int reiserfs_parse_alloc_options(struct super_block * s, char * options)
+int reiserfs_parse_alloc_options(struct super_block *s, char *options)
 {
-    char * this_char, * value;
+	char *this_char, *value;
 
-    REISERFS_SB(s)->s_alloc_options.bits = 0; /* clear default settings */
+	REISERFS_SB(s)->s_alloc_options.bits = 0;	/* clear default settings */
 
-    while ( (this_char = strsep (&options, ":")) != NULL ) {
-	if ((value = strchr (this_char, '=')) != NULL)
-	    *value++ = 0;
+	while ((this_char = strsep(&options, ":")) != NULL) {
+		if ((value = strchr(this_char, '=')) != NULL)
+			*value++ = 0;
+
+		if (!strcmp(this_char, "concentrating_formatted_nodes")) {
+			int temp;
+			SET_OPTION(concentrating_formatted_nodes);
+			temp = (value
+				&& *value) ? simple_strtoul(value, &value,
+							    0) : 10;
+			if (temp <= 0 || temp > 100) {
+				REISERFS_SB(s)->s_alloc_options.border = 10;
+			} else {
+				REISERFS_SB(s)->s_alloc_options.border =
+				    100 / temp;
+			}
+			continue;
+		}
+		if (!strcmp(this_char, "displacing_large_files")) {
+			SET_OPTION(displacing_large_files);
+			REISERFS_SB(s)->s_alloc_options.large_file_size =
+			    (value
+			     && *value) ? simple_strtoul(value, &value, 0) : 16;
+			continue;
+		}
+		if (!strcmp(this_char, "displacing_new_packing_localities")) {
+			SET_OPTION(displacing_new_packing_localities);
+			continue;
+		};
+
+		if (!strcmp(this_char, "old_hashed_relocation")) {
+			SET_OPTION(old_hashed_relocation);
+			continue;
+		}
 
-	if (!strcmp(this_char, "concentrating_formatted_nodes")) {
-	    int temp;
-	    SET_OPTION(concentrating_formatted_nodes);
-	    temp = (value && *value) ? simple_strtoul (value, &value, 0) : 10;
-	    if (temp <= 0 || temp > 100) {
-		REISERFS_SB(s)->s_alloc_options.border = 10;
-	    } else {
-		REISERFS_SB(s)->s_alloc_options.border = 100 / temp;
-	   }
-	    continue;
-	}
-	if (!strcmp(this_char, "displacing_large_files")) {
-	    SET_OPTION(displacing_large_files);
-	    REISERFS_SB(s)->s_alloc_options.large_file_size =
-		(value && *value) ? simple_strtoul (value, &value, 0) : 16;
-	    continue;
-	}
-	if (!strcmp(this_char, "displacing_new_packing_localities")) {
-	    SET_OPTION(displacing_new_packing_localities);
-	    continue;
-	};
+		if (!strcmp(this_char, "new_hashed_relocation")) {
+			SET_OPTION(new_hashed_relocation);
+			continue;
+		}
 
-	if (!strcmp(this_char, "old_hashed_relocation")) {
-	    SET_OPTION(old_hashed_relocation);
-	    continue;
-	}
+		if (!strcmp(this_char, "dirid_groups")) {
+			SET_OPTION(dirid_groups);
+			continue;
+		}
+		if (!strcmp(this_char, "oid_groups")) {
+			SET_OPTION(oid_groups);
+			continue;
+		}
+		if (!strcmp(this_char, "packing_groups")) {
+			SET_OPTION(packing_groups);
+			continue;
+		}
+		if (!strcmp(this_char, "hashed_formatted_nodes")) {
+			SET_OPTION(hashed_formatted_nodes);
+			continue;
+		}
 
-	if (!strcmp(this_char, "new_hashed_relocation")) {
-	    SET_OPTION(new_hashed_relocation);
-	    continue;
-	}
+		if (!strcmp(this_char, "skip_busy")) {
+			SET_OPTION(skip_busy);
+			continue;
+		}
 
-        if (!strcmp(this_char, "dirid_groups")) {
-	    SET_OPTION(dirid_groups);
-	    continue;
-        }
-        if (!strcmp(this_char, "oid_groups")) {
-	    SET_OPTION(oid_groups);
-	    continue;
-        }
-        if (!strcmp(this_char, "packing_groups")) {
-	    SET_OPTION(packing_groups);
-	    continue;
-        }
-	if (!strcmp(this_char, "hashed_formatted_nodes")) {
-	    SET_OPTION(hashed_formatted_nodes);
-	    continue;
-	}
+		if (!strcmp(this_char, "hundredth_slices")) {
+			SET_OPTION(hundredth_slices);
+			continue;
+		}
 
-	if (!strcmp(this_char, "skip_busy")) {
-	    SET_OPTION(skip_busy);
-	    continue;
-	}
+		if (!strcmp(this_char, "old_way")) {
+			SET_OPTION(old_way);
+			continue;
+		}
 
-	if (!strcmp(this_char, "hundredth_slices")) {
-	    SET_OPTION(hundredth_slices);
-	    continue;
-	}
+		if (!strcmp(this_char, "displace_based_on_dirid")) {
+			SET_OPTION(displace_based_on_dirid);
+			continue;
+		}
 
-	if (!strcmp(this_char, "old_way")) {
-	    SET_OPTION(old_way);
-	    continue;
-	}
+		if (!strcmp(this_char, "preallocmin")) {
+			REISERFS_SB(s)->s_alloc_options.preallocmin =
+			    (value
+			     && *value) ? simple_strtoul(value, &value, 0) : 4;
+			continue;
+		}
 
-	if (!strcmp(this_char, "displace_based_on_dirid")) {
-	    SET_OPTION(displace_based_on_dirid);
-	    continue;
-	}
+		if (!strcmp(this_char, "preallocsize")) {
+			REISERFS_SB(s)->s_alloc_options.preallocsize =
+			    (value
+			     && *value) ? simple_strtoul(value, &value,
+							 0) :
+			    PREALLOCATION_SIZE;
+			continue;
+		}
 
-	if (!strcmp(this_char, "preallocmin")) {
-	    REISERFS_SB(s)->s_alloc_options.preallocmin =
-		(value && *value) ? simple_strtoul (value, &value, 0) : 4;
-	    continue;
+		reiserfs_warning(s, "zam-4001: %s : unknown option - %s",
+				 __FUNCTION__, this_char);
+		return 1;
 	}
 
-	if (!strcmp(this_char, "preallocsize")) {
-	    REISERFS_SB(s)->s_alloc_options.preallocsize =
-		(value && *value) ? simple_strtoul (value, &value, 0) : PREALLOCATION_SIZE;
-	    continue;
-	}
+	reiserfs_warning(s, "allocator options = [%08x]\n", SB_ALLOC_OPTS(s));
+	return 0;
+}
 
-	reiserfs_warning (s, "zam-4001: %s : unknown option - %s",
-			  __FUNCTION__ , this_char);
-	return 1;
-      }
-  
-    reiserfs_warning (s, "allocator options = [%08x]\n", SB_ALLOC_OPTS(s));
-    return 0;
-}
-  
-static inline void new_hashed_relocation (reiserfs_blocknr_hint_t * hint)
-{
-    char * hash_in;
-    if (hint->formatted_node) {
-	    hash_in = (char*)&hint->key.k_dir_id;
-    } else {
-	if (!hint->inode) {
-	    //hint->search_start = hint->beg;
-	    hash_in = (char*)&hint->key.k_dir_id;
-	} else 
-	    if ( TEST_OPTION(displace_based_on_dirid, hint->th->t_super))
-		hash_in = (char *)(&INODE_PKEY(hint->inode)->k_dir_id);
-	    else
-		hash_in = (char *)(&INODE_PKEY(hint->inode)->k_objectid);
-      }
+static inline void new_hashed_relocation(reiserfs_blocknr_hint_t * hint)
+{
+	char *hash_in;
+	if (hint->formatted_node) {
+		hash_in = (char *)&hint->key.k_dir_id;
+	} else {
+		if (!hint->inode) {
+			//hint->search_start = hint->beg;
+			hash_in = (char *)&hint->key.k_dir_id;
+		} else
+		    if (TEST_OPTION(displace_based_on_dirid, hint->th->t_super))
+			hash_in = (char *)(&INODE_PKEY(hint->inode)->k_dir_id);
+		else
+			hash_in =
+			    (char *)(&INODE_PKEY(hint->inode)->k_objectid);
+	}
 
-    hint->search_start = hint->beg + keyed_hash(hash_in, 4) % (hint->end - hint->beg);
+	hint->search_start =
+	    hint->beg + keyed_hash(hash_in, 4) % (hint->end - hint->beg);
 }
 
 /*
  * Relocation based on dirid, hashing them into a given bitmap block
  * files. Formatted nodes are unaffected, a seperate policy covers them
  */
-static void
-dirid_groups (reiserfs_blocknr_hint_t *hint)
+static void dirid_groups(reiserfs_blocknr_hint_t * hint)
 {
-    unsigned long hash;
-    __u32 dirid = 0;
-    int bm = 0;
-    struct super_block *sb = hint->th->t_super;
-    if (hint->inode)
-	dirid = le32_to_cpu(INODE_PKEY(hint->inode)->k_dir_id);
-    else if (hint->formatted_node)
-        dirid = hint->key.k_dir_id;
-
-    if (dirid) {
-	bm = bmap_hash_id(sb, dirid);
-	hash = bm * (sb->s_blocksize << 3);
-	/* give a portion of the block group to metadata */
+	unsigned long hash;
+	__u32 dirid = 0;
+	int bm = 0;
+	struct super_block *sb = hint->th->t_super;
 	if (hint->inode)
-	    hash += sb->s_blocksize/2;
-	hint->search_start = hash;
-    }
+		dirid = le32_to_cpu(INODE_PKEY(hint->inode)->k_dir_id);
+	else if (hint->formatted_node)
+		dirid = hint->key.k_dir_id;
+
+	if (dirid) {
+		bm = bmap_hash_id(sb, dirid);
+		hash = bm * (sb->s_blocksize << 3);
+		/* give a portion of the block group to metadata */
+		if (hint->inode)
+			hash += sb->s_blocksize / 2;
+		hint->search_start = hash;
+	}
 }
 
 /*
  * Relocation based on oid, hashing them into a given bitmap block
  * files. Formatted nodes are unaffected, a seperate policy covers them
  */
-static void
-oid_groups (reiserfs_blocknr_hint_t *hint)
+static void oid_groups(reiserfs_blocknr_hint_t * hint)
 {
-    if (hint->inode) {
-	unsigned long hash;
-	__u32 oid;
-	__u32 dirid;
-	int bm;
-
-	dirid = le32_to_cpu(INODE_PKEY(hint->inode)->k_dir_id);
-
-	/* keep the root dir and it's first set of subdirs close to
-	 * the start of the disk
-	 */
-	if (dirid <= 2)
-	    hash = (hint->inode->i_sb->s_blocksize << 3);
-	else {
-	    oid = le32_to_cpu(INODE_PKEY(hint->inode)->k_objectid);
-	    bm = bmap_hash_id(hint->inode->i_sb, oid);
-	    hash = bm * (hint->inode->i_sb->s_blocksize << 3);
+	if (hint->inode) {
+		unsigned long hash;
+		__u32 oid;
+		__u32 dirid;
+		int bm;
+
+		dirid = le32_to_cpu(INODE_PKEY(hint->inode)->k_dir_id);
+
+		/* keep the root dir and it's first set of subdirs close to
+		 * the start of the disk
+		 */
+		if (dirid <= 2)
+			hash = (hint->inode->i_sb->s_blocksize << 3);
+		else {
+			oid = le32_to_cpu(INODE_PKEY(hint->inode)->k_objectid);
+			bm = bmap_hash_id(hint->inode->i_sb, oid);
+			hash = bm * (hint->inode->i_sb->s_blocksize << 3);
+		}
+		hint->search_start = hash;
 	}
-	hint->search_start = hash;
-    }
 }
 
 /* returns 1 if it finds an indirect item and gets valid hint info
  * from it, otherwise 0
  */
-static int get_left_neighbor(reiserfs_blocknr_hint_t *hint)
+static int get_left_neighbor(reiserfs_blocknr_hint_t * hint)
 {
-    struct path * path;
-    struct buffer_head * bh;
-    struct item_head * ih;
-    int pos_in_item;
-    __le32 * item;
-    int ret = 0;
+	struct path *path;
+	struct buffer_head *bh;
+	struct item_head *ih;
+	int pos_in_item;
+	__le32 *item;
+	int ret = 0;
 
-    if (!hint->path)		/* reiserfs code can call this function w/o pointer to path
+	if (!hint->path)	/* reiserfs code can call this function w/o pointer to path
 				 * structure supplied; then we rely on supplied search_start */
-	return 0;
+		return 0;
 
-    path = hint->path;
-    bh = get_last_bh(path);
-    RFALSE( !bh, "green-4002: Illegal path specified to get_left_neighbor");
-    ih = get_ih(path);
-    pos_in_item = path->pos_in_item;
-    item = get_item (path);
-
-    hint->search_start = bh->b_blocknr;
-
-    if (!hint->formatted_node && is_indirect_le_ih (ih)) {
-	/* for indirect item: go to left and look for the first non-hole entry
-	   in the indirect item */
-	if (pos_in_item == I_UNFM_NUM (ih))
-	    pos_in_item--;
-//	    pos_in_item = I_UNFM_NUM (ih) - 1;
-	while (pos_in_item >= 0) {
-	    int t=get_block_num(item,pos_in_item);
-	    if (t) {
-		hint->search_start = t;
-		ret = 1;
-		break;
-	    }
-	    pos_in_item --;
+	path = hint->path;
+	bh = get_last_bh(path);
+	RFALSE(!bh, "green-4002: Illegal path specified to get_left_neighbor");
+	ih = get_ih(path);
+	pos_in_item = path->pos_in_item;
+	item = get_item(path);
+
+	hint->search_start = bh->b_blocknr;
+
+	if (!hint->formatted_node && is_indirect_le_ih(ih)) {
+		/* for indirect item: go to left and look for the first non-hole entry
+		   in the indirect item */
+		if (pos_in_item == I_UNFM_NUM(ih))
+			pos_in_item--;
+//          pos_in_item = I_UNFM_NUM (ih) - 1;
+		while (pos_in_item >= 0) {
+			int t = get_block_num(item, pos_in_item);
+			if (t) {
+				hint->search_start = t;
+				ret = 1;
+				break;
+			}
+			pos_in_item--;
+		}
 	}
-    }
 
-    /* does result value fit into specified region? */
-    return ret;
+	/* does result value fit into specified region? */
+	return ret;
 }
 
 /* should be, if formatted node, then try to put on first part of the device
    specified as number of percent with mount option device, else try to put
    on last of device.  This is not to say it is good code to do so,
    but the effect should be measured.  */
-static inline void set_border_in_hint(struct super_block *s, reiserfs_blocknr_hint_t *hint)
+static inline void set_border_in_hint(struct super_block *s,
+				      reiserfs_blocknr_hint_t * hint)
 {
-    b_blocknr_t border = SB_BLOCK_COUNT(s) / REISERFS_SB(s)->s_alloc_options.border;
+	b_blocknr_t border =
+	    SB_BLOCK_COUNT(s) / REISERFS_SB(s)->s_alloc_options.border;
 
-    if (hint->formatted_node)
-	hint->end = border - 1;
-    else
-	hint->beg = border;
+	if (hint->formatted_node)
+		hint->end = border - 1;
+	else
+		hint->beg = border;
 }
 
-static inline void displace_large_file(reiserfs_blocknr_hint_t *hint)
+static inline void displace_large_file(reiserfs_blocknr_hint_t * hint)
 {
-    if ( TEST_OPTION(displace_based_on_dirid, hint->th->t_super))
-	hint->search_start = hint->beg + keyed_hash((char *)(&INODE_PKEY(hint->inode)->k_dir_id), 4) % (hint->end - hint->beg);
-    else
-	hint->search_start = hint->beg + keyed_hash((char *)(&INODE_PKEY(hint->inode)->k_objectid), 4) % (hint->end - hint->beg);
+	if (TEST_OPTION(displace_based_on_dirid, hint->th->t_super))
+		hint->search_start =
+		    hint->beg +
+		    keyed_hash((char *)(&INODE_PKEY(hint->inode)->k_dir_id),
+			       4) % (hint->end - hint->beg);
+	else
+		hint->search_start =
+		    hint->beg +
+		    keyed_hash((char *)(&INODE_PKEY(hint->inode)->k_objectid),
+			       4) % (hint->end - hint->beg);
 }
 
-static inline void hash_formatted_node(reiserfs_blocknr_hint_t *hint)
+static inline void hash_formatted_node(reiserfs_blocknr_hint_t * hint)
 {
-   char * hash_in;
+	char *hash_in;
 
-   if (!hint->inode)
-	hash_in = (char*)&hint->key.k_dir_id;
-    else if ( TEST_OPTION(displace_based_on_dirid, hint->th->t_super))
-	hash_in = (char *)(&INODE_PKEY(hint->inode)->k_dir_id);
-    else
-	hash_in = (char *)(&INODE_PKEY(hint->inode)->k_objectid);
+	if (!hint->inode)
+		hash_in = (char *)&hint->key.k_dir_id;
+	else if (TEST_OPTION(displace_based_on_dirid, hint->th->t_super))
+		hash_in = (char *)(&INODE_PKEY(hint->inode)->k_dir_id);
+	else
+		hash_in = (char *)(&INODE_PKEY(hint->inode)->k_objectid);
 
-	hint->search_start = hint->beg + keyed_hash(hash_in, 4) % (hint->end - hint->beg);
+	hint->search_start =
+	    hint->beg + keyed_hash(hash_in, 4) % (hint->end - hint->beg);
 }
 
-static inline int this_blocknr_allocation_would_make_it_a_large_file(reiserfs_blocknr_hint_t *hint)
+static inline int
+this_blocknr_allocation_would_make_it_a_large_file(reiserfs_blocknr_hint_t *
+						   hint)
 {
-    return hint->block == REISERFS_SB(hint->th->t_super)->s_alloc_options.large_file_size;
+	return hint->block ==
+	    REISERFS_SB(hint->th->t_super)->s_alloc_options.large_file_size;
 }
 
 #ifdef DISPLACE_NEW_PACKING_LOCALITIES
-static inline void displace_new_packing_locality (reiserfs_blocknr_hint_t *hint)
+static inline void displace_new_packing_locality(reiserfs_blocknr_hint_t * hint)
 {
-    struct in_core_key * key = &hint->key;
+	struct in_core_key *key = &hint->key;
 
-    hint->th->displace_new_blocks = 0;
-    hint->search_start = hint->beg + keyed_hash((char*)(&key->k_objectid),4) % (hint->end - hint->beg);
+	hint->th->displace_new_blocks = 0;
+	hint->search_start =
+	    hint->beg + keyed_hash((char *)(&key->k_objectid),
+				   4) % (hint->end - hint->beg);
 }
-  #endif
+#endif
 
-static inline int old_hashed_relocation (reiserfs_blocknr_hint_t * hint)
+static inline int old_hashed_relocation(reiserfs_blocknr_hint_t * hint)
 {
-    b_blocknr_t border;
-    u32 hash_in;
-    
-    if (hint->formatted_node || hint->inode == NULL) {
-	return 0;
-      }
+	b_blocknr_t border;
+	u32 hash_in;
 
-    hash_in = le32_to_cpu((INODE_PKEY(hint->inode))->k_dir_id);
-    border = hint->beg + (u32) keyed_hash(((char *) (&hash_in)), 4) % (hint->end - hint->beg - 1);
-    if (border > hint->search_start)
-	hint->search_start = border;
-
-    return 1;
-  }
-  
-static inline int old_way (reiserfs_blocknr_hint_t * hint)
-{
-    b_blocknr_t border;
-    
-    if (hint->formatted_node || hint->inode == NULL) {
-	return 0;
-    }
-  
-      border = hint->beg + le32_to_cpu(INODE_PKEY(hint->inode)->k_dir_id) % (hint->end  - hint->beg);
-    if (border > hint->search_start)
-	hint->search_start = border;
+	if (hint->formatted_node || hint->inode == NULL) {
+		return 0;
+	}
 
-    return 1;
+	hash_in = le32_to_cpu((INODE_PKEY(hint->inode))->k_dir_id);
+	border =
+	    hint->beg + (u32) keyed_hash(((char *)(&hash_in)),
+					 4) % (hint->end - hint->beg - 1);
+	if (border > hint->search_start)
+		hint->search_start = border;
+
+	return 1;
 }
 
-static inline void hundredth_slices (reiserfs_blocknr_hint_t * hint)
+static inline int old_way(reiserfs_blocknr_hint_t * hint)
 {
-    struct in_core_key * key = &hint->key;
-    b_blocknr_t slice_start;
+	b_blocknr_t border;
 
-    slice_start = (keyed_hash((char*)(&key->k_dir_id),4) % 100) * (hint->end / 100);
-    if ( slice_start > hint->search_start || slice_start + (hint->end / 100) <= hint->search_start) {
-	hint->search_start = slice_start;
-    }
-}
-  
-static void determine_search_start(reiserfs_blocknr_hint_t *hint,
-					  int amount_needed)
-{
-    struct super_block *s = hint->th->t_super;
-    int unfm_hint;
+	if (hint->formatted_node || hint->inode == NULL) {
+		return 0;
+	}
 
-    hint->beg = 0;
-    hint->end = SB_BLOCK_COUNT(s) - 1;
+	border =
+	    hint->beg +
+	    le32_to_cpu(INODE_PKEY(hint->inode)->k_dir_id) % (hint->end -
+							      hint->beg);
+	if (border > hint->search_start)
+		hint->search_start = border;
 
-    /* This is former border algorithm. Now with tunable border offset */
-    if (concentrating_formatted_nodes(s))
-	set_border_in_hint(s, hint);
+	return 1;
+}
 
-#ifdef DISPLACE_NEW_PACKING_LOCALITIES
-    /* whenever we create a new directory, we displace it.  At first we will
-       hash for location, later we might look for a moderately empty place for
-       it */
-    if (displacing_new_packing_localities(s)
-	&& hint->th->displace_new_blocks) {
-	displace_new_packing_locality(hint);
+static inline void hundredth_slices(reiserfs_blocknr_hint_t * hint)
+{
+	struct in_core_key *key = &hint->key;
+	b_blocknr_t slice_start;
 
-	/* we do not continue determine_search_start,
-	 * if new packing locality is being displaced */
-	return;
-    }				      
-#endif
-  
-    /* all persons should feel encouraged to add more special cases here and
-     * test them */
-
-    if (displacing_large_files(s) && !hint->formatted_node
-	&& this_blocknr_allocation_would_make_it_a_large_file(hint)) {
-	displace_large_file(hint);
-	return;
-    }
+	slice_start =
+	    (keyed_hash((char *)(&key->k_dir_id), 4) % 100) * (hint->end / 100);
+	if (slice_start > hint->search_start
+	    || slice_start + (hint->end / 100) <= hint->search_start) {
+		hint->search_start = slice_start;
+	}
+}
 
-    /* if none of our special cases is relevant, use the left neighbor in the
-       tree order of the new node we are allocating for */
-    if (hint->formatted_node && TEST_OPTION(hashed_formatted_nodes,s)) {
-        hash_formatted_node(hint);
-	return;
-    }
+static void determine_search_start(reiserfs_blocknr_hint_t * hint,
+				   int amount_needed)
+{
+	struct super_block *s = hint->th->t_super;
+	int unfm_hint;
 
-    unfm_hint = get_left_neighbor(hint);
+	hint->beg = 0;
+	hint->end = SB_BLOCK_COUNT(s) - 1;
 
-    /* Mimic old block allocator behaviour, that is if VFS allowed for preallocation,
-       new blocks are displaced based on directory ID. Also, if suggested search_start
-       is less than last preallocated block, we start searching from it, assuming that
-       HDD dataflow is faster in forward direction */
-    if ( TEST_OPTION(old_way, s)) {
-	if (!hint->formatted_node) {
-	    if ( !reiserfs_hashed_relocation(s))
-		old_way(hint);
-	    else if (!reiserfs_no_unhashed_relocation(s))
-		old_hashed_relocation(hint);
+	/* This is former border algorithm. Now with tunable border offset */
+	if (concentrating_formatted_nodes(s))
+		set_border_in_hint(s, hint);
 
-	    if ( hint->inode && hint->search_start < REISERFS_I(hint->inode)->i_prealloc_block)
-		hint->search_start = REISERFS_I(hint->inode)->i_prealloc_block;
+#ifdef DISPLACE_NEW_PACKING_LOCALITIES
+	/* whenever we create a new directory, we displace it.  At first we will
+	   hash for location, later we might look for a moderately empty place for
+	   it */
+	if (displacing_new_packing_localities(s)
+	    && hint->th->displace_new_blocks) {
+		displace_new_packing_locality(hint);
+
+		/* we do not continue determine_search_start,
+		 * if new packing locality is being displaced */
+		return;
 	}
-	return;
-    }
+#endif
 
-    /* This is an approach proposed by Hans */
-    if ( TEST_OPTION(hundredth_slices, s) && ! (displacing_large_files(s) && !hint->formatted_node)) {
-	hundredth_slices(hint);
-	return;
-    }
+	/* all persons should feel encouraged to add more special cases here and
+	 * test them */
 
-    /* old_hashed_relocation only works on unformatted */
-    if (!unfm_hint && !hint->formatted_node &&
-        TEST_OPTION(old_hashed_relocation, s))
-    {
-	old_hashed_relocation(hint);
-    }
-    /* new_hashed_relocation works with both formatted/unformatted nodes */
-    if ((!unfm_hint || hint->formatted_node) &&
-        TEST_OPTION(new_hashed_relocation, s))
-    {
-	new_hashed_relocation(hint);
-    }
-    /* dirid grouping works only on unformatted nodes */
-    if (!unfm_hint && !hint->formatted_node && TEST_OPTION(dirid_groups,s))
-    {
-        dirid_groups(hint);
-    }
+	if (displacing_large_files(s) && !hint->formatted_node
+	    && this_blocknr_allocation_would_make_it_a_large_file(hint)) {
+		displace_large_file(hint);
+		return;
+	}
+
+	/* if none of our special cases is relevant, use the left neighbor in the
+	   tree order of the new node we are allocating for */
+	if (hint->formatted_node && TEST_OPTION(hashed_formatted_nodes, s)) {
+		hash_formatted_node(hint);
+		return;
+	}
+
+	unfm_hint = get_left_neighbor(hint);
+
+	/* Mimic old block allocator behaviour, that is if VFS allowed for preallocation,
+	   new blocks are displaced based on directory ID. Also, if suggested search_start
+	   is less than last preallocated block, we start searching from it, assuming that
+	   HDD dataflow is faster in forward direction */
+	if (TEST_OPTION(old_way, s)) {
+		if (!hint->formatted_node) {
+			if (!reiserfs_hashed_relocation(s))
+				old_way(hint);
+			else if (!reiserfs_no_unhashed_relocation(s))
+				old_hashed_relocation(hint);
+
+			if (hint->inode
+			    && hint->search_start <
+			    REISERFS_I(hint->inode)->i_prealloc_block)
+				hint->search_start =
+				    REISERFS_I(hint->inode)->i_prealloc_block;
+		}
+		return;
+	}
 
+	/* This is an approach proposed by Hans */
+	if (TEST_OPTION(hundredth_slices, s)
+	    && !(displacing_large_files(s) && !hint->formatted_node)) {
+		hundredth_slices(hint);
+		return;
+	}
+
+	/* old_hashed_relocation only works on unformatted */
+	if (!unfm_hint && !hint->formatted_node &&
+	    TEST_OPTION(old_hashed_relocation, s)) {
+		old_hashed_relocation(hint);
+	}
+	/* new_hashed_relocation works with both formatted/unformatted nodes */
+	if ((!unfm_hint || hint->formatted_node) &&
+	    TEST_OPTION(new_hashed_relocation, s)) {
+		new_hashed_relocation(hint);
+	}
+	/* dirid grouping works only on unformatted nodes */
+	if (!unfm_hint && !hint->formatted_node && TEST_OPTION(dirid_groups, s)) {
+		dirid_groups(hint);
+	}
 #ifdef DISPLACE_NEW_PACKING_LOCALITIES
-    if (hint->formatted_node && TEST_OPTION(dirid_groups,s))
-    {
-        dirid_groups(hint);
-    }
+	if (hint->formatted_node && TEST_OPTION(dirid_groups, s)) {
+		dirid_groups(hint);
+	}
 #endif
 
-    /* oid grouping works only on unformatted nodes */
-    if (!unfm_hint && !hint->formatted_node && TEST_OPTION(oid_groups,s))
-    {
-        oid_groups(hint);
-    }
-    return;
+	/* oid grouping works only on unformatted nodes */
+	if (!unfm_hint && !hint->formatted_node && TEST_OPTION(oid_groups, s)) {
+		oid_groups(hint);
+	}
+	return;
 }
 
 static int determine_prealloc_size(reiserfs_blocknr_hint_t * hint)
 {
-    /* make minimum size a mount option and benchmark both ways */
-    /* we preallocate blocks only for regular files, specific size */
-    /* benchmark preallocating always and see what happens */
-
-    hint->prealloc_size = 0;
-
-    if (!hint->formatted_node && hint->preallocate) {
-	if (S_ISREG(hint->inode->i_mode)
-	    && hint->inode->i_size >= REISERFS_SB(hint->th->t_super)->s_alloc_options.preallocmin * hint->inode->i_sb->s_blocksize)
-	    hint->prealloc_size = REISERFS_SB(hint->th->t_super)->s_alloc_options.preallocsize - 1;
-    }
-    return CARRY_ON;
+	/* make minimum size a mount option and benchmark both ways */
+	/* we preallocate blocks only for regular files, specific size */
+	/* benchmark preallocating always and see what happens */
+
+	hint->prealloc_size = 0;
+
+	if (!hint->formatted_node && hint->preallocate) {
+		if (S_ISREG(hint->inode->i_mode)
+		    && hint->inode->i_size >=
+		    REISERFS_SB(hint->th->t_super)->s_alloc_options.
+		    preallocmin * hint->inode->i_sb->s_blocksize)
+			hint->prealloc_size =
+			    REISERFS_SB(hint->th->t_super)->s_alloc_options.
+			    preallocsize - 1;
+	}
+	return CARRY_ON;
 }
 
 /* XXX I know it could be merged with upper-level function;
    but may be result function would be too complex. */
-static inline int allocate_without_wrapping_disk (reiserfs_blocknr_hint_t * hint,
-					 b_blocknr_t * new_blocknrs,
-					 b_blocknr_t start, b_blocknr_t finish,
-					 int min,
-					 int amount_needed, int prealloc_size)
-{
-    int rest = amount_needed;
-    int nr_allocated;
-  
-    while (rest > 0 && start <= finish) {
-	nr_allocated = scan_bitmap (hint->th, &start, finish, min,
-				    rest + prealloc_size, !hint->formatted_node,
-				    hint->block);
-
-	if (nr_allocated == 0)	/* no new blocks allocated, return */
-	    break;
-	
-	/* fill free_blocknrs array first */
-	while (rest > 0 && nr_allocated > 0) {
-	    * new_blocknrs ++ = start ++;
-	    rest --; nr_allocated --;
-	}
-
-	/* do we have something to fill prealloc. array also ? */
-	if (nr_allocated > 0) {
-	    /* it means prealloc_size was greater that 0 and we do preallocation */
-	    list_add(&REISERFS_I(hint->inode)->i_prealloc_list,
-		     &SB_JOURNAL(hint->th->t_super)->j_prealloc_list);
-	    REISERFS_I(hint->inode)->i_prealloc_block = start;
-	    REISERFS_I(hint->inode)->i_prealloc_count = nr_allocated;
-	    break;
+static inline int allocate_without_wrapping_disk(reiserfs_blocknr_hint_t * hint,
+						 b_blocknr_t * new_blocknrs,
+						 b_blocknr_t start,
+						 b_blocknr_t finish, int min,
+						 int amount_needed,
+						 int prealloc_size)
+{
+	int rest = amount_needed;
+	int nr_allocated;
+
+	while (rest > 0 && start <= finish) {
+		nr_allocated = scan_bitmap(hint->th, &start, finish, min,
+					   rest + prealloc_size,
+					   !hint->formatted_node, hint->block);
+
+		if (nr_allocated == 0)	/* no new blocks allocated, return */
+			break;
+
+		/* fill free_blocknrs array first */
+		while (rest > 0 && nr_allocated > 0) {
+			*new_blocknrs++ = start++;
+			rest--;
+			nr_allocated--;
+		}
+
+		/* do we have something to fill prealloc. array also ? */
+		if (nr_allocated > 0) {
+			/* it means prealloc_size was greater that 0 and we do preallocation */
+			list_add(&REISERFS_I(hint->inode)->i_prealloc_list,
+				 &SB_JOURNAL(hint->th->t_super)->
+				 j_prealloc_list);
+			REISERFS_I(hint->inode)->i_prealloc_block = start;
+			REISERFS_I(hint->inode)->i_prealloc_count =
+			    nr_allocated;
+			break;
+		}
 	}
-    }
 
-    return (amount_needed - rest);
+	return (amount_needed - rest);
 }
 
 static inline int blocknrs_and_prealloc_arrays_from_search_start
-    (reiserfs_blocknr_hint_t *hint, b_blocknr_t *new_blocknrs, int amount_needed)
-{
-    struct super_block *s = hint->th->t_super;
-    b_blocknr_t start = hint->search_start;
-    b_blocknr_t finish = SB_BLOCK_COUNT(s) - 1;
-    int passno = 0;
-    int nr_allocated = 0;
-    int bigalloc = 0;
-
-    determine_prealloc_size(hint);
-    if (!hint->formatted_node) {
-        int quota_ret;
+    (reiserfs_blocknr_hint_t * hint, b_blocknr_t * new_blocknrs,
+     int amount_needed) {
+	struct super_block *s = hint->th->t_super;
+	b_blocknr_t start = hint->search_start;
+	b_blocknr_t finish = SB_BLOCK_COUNT(s) - 1;
+	int passno = 0;
+	int nr_allocated = 0;
+	int bigalloc = 0;
+
+	determine_prealloc_size(hint);
+	if (!hint->formatted_node) {
+		int quota_ret;
 #ifdef REISERQUOTA_DEBUG
-	reiserfs_debug (s, REISERFS_DEBUG_CODE, "reiserquota: allocating %d blocks id=%u", amount_needed, hint->inode->i_uid);
+		reiserfs_debug(s, REISERFS_DEBUG_CODE,
+			       "reiserquota: allocating %d blocks id=%u",
+			       amount_needed, hint->inode->i_uid);
 #endif
-	quota_ret = DQUOT_ALLOC_BLOCK_NODIRTY(hint->inode, amount_needed);
-	if (quota_ret)    /* Quota exceeded? */
-	    return QUOTA_EXCEEDED;
-	if (hint->preallocate && hint->prealloc_size ) {
+		quota_ret =
+		    DQUOT_ALLOC_BLOCK_NODIRTY(hint->inode, amount_needed);
+		if (quota_ret)	/* Quota exceeded? */
+			return QUOTA_EXCEEDED;
+		if (hint->preallocate && hint->prealloc_size) {
 #ifdef REISERQUOTA_DEBUG
-	    reiserfs_debug (s, REISERFS_DEBUG_CODE, "reiserquota: allocating (prealloc) %d blocks id=%u", hint->prealloc_size, hint->inode->i_uid);
+			reiserfs_debug(s, REISERFS_DEBUG_CODE,
+				       "reiserquota: allocating (prealloc) %d blocks id=%u",
+				       hint->prealloc_size, hint->inode->i_uid);
 #endif
-	    quota_ret = DQUOT_PREALLOC_BLOCK_NODIRTY(hint->inode, hint->prealloc_size);
-	    if (quota_ret)
-		hint->preallocate=hint->prealloc_size=0;
-	}
-	/* for unformatted nodes, force large allocations */
-	bigalloc = amount_needed;
-    }
-
-    do {
-	/* in bigalloc mode, nr_allocated should stay zero until
-	 * the entire allocation is filled
-	 */
-	if (unlikely(bigalloc && nr_allocated)) {
-	    reiserfs_warning(s, "bigalloc is %d, nr_allocated %d\n",
-	    bigalloc, nr_allocated);
-	    /* reset things to a sane value */
-	    bigalloc = amount_needed - nr_allocated;
-	}
-	/*
-	 * try pass 0 and pass 1 looking for a nice big
-	 * contiguous allocation.  Then reset and look
-	 * for anything you can find.
-	 */
-	if (passno == 2 && bigalloc) {
-	    passno = 0;
-	    bigalloc = 0;
-	}
-	switch (passno++) {
-        case 0: /* Search from hint->search_start to end of disk */
-	    start = hint->search_start;
-	    finish = SB_BLOCK_COUNT(s) - 1;
-	    break;
-        case 1: /* Search from hint->beg to hint->search_start */
-	    start = hint->beg;
-	    finish = hint->search_start;
-	    break;
-	case 2: /* Last chance: Search from 0 to hint->beg */
-	    start = 0;
-	    finish = hint->beg;
-	    break;
-	default: /* We've tried searching everywhere, not enough space */
-	    /* Free the blocks */
-	    if (!hint->formatted_node) {
+			quota_ret =
+			    DQUOT_PREALLOC_BLOCK_NODIRTY(hint->inode,
+							 hint->prealloc_size);
+			if (quota_ret)
+				hint->preallocate = hint->prealloc_size = 0;
+		}
+		/* for unformatted nodes, force large allocations */
+		bigalloc = amount_needed;
+	}
+
+	do {
+		/* in bigalloc mode, nr_allocated should stay zero until
+		 * the entire allocation is filled
+		 */
+		if (unlikely(bigalloc && nr_allocated)) {
+			reiserfs_warning(s, "bigalloc is %d, nr_allocated %d\n",
+					 bigalloc, nr_allocated);
+			/* reset things to a sane value */
+			bigalloc = amount_needed - nr_allocated;
+		}
+		/*
+		 * try pass 0 and pass 1 looking for a nice big
+		 * contiguous allocation.  Then reset and look
+		 * for anything you can find.
+		 */
+		if (passno == 2 && bigalloc) {
+			passno = 0;
+			bigalloc = 0;
+		}
+		switch (passno++) {
+		case 0:	/* Search from hint->search_start to end of disk */
+			start = hint->search_start;
+			finish = SB_BLOCK_COUNT(s) - 1;
+			break;
+		case 1:	/* Search from hint->beg to hint->search_start */
+			start = hint->beg;
+			finish = hint->search_start;
+			break;
+		case 2:	/* Last chance: Search from 0 to hint->beg */
+			start = 0;
+			finish = hint->beg;
+			break;
+		default:	/* We've tried searching everywhere, not enough space */
+			/* Free the blocks */
+			if (!hint->formatted_node) {
 #ifdef REISERQUOTA_DEBUG
-		reiserfs_debug (s, REISERFS_DEBUG_CODE, "reiserquota: freeing (nospace) %d blocks id=%u", amount_needed + hint->prealloc_size - nr_allocated, hint->inode->i_uid);
+				reiserfs_debug(s, REISERFS_DEBUG_CODE,
+					       "reiserquota: freeing (nospace) %d blocks id=%u",
+					       amount_needed +
+					       hint->prealloc_size -
+					       nr_allocated,
+					       hint->inode->i_uid);
 #endif
-		DQUOT_FREE_BLOCK_NODIRTY(hint->inode, amount_needed + hint->prealloc_size - nr_allocated);     /* Free not allocated blocks */
-	    }
-  	    while (nr_allocated --)
-		reiserfs_free_block(hint->th, hint->inode, new_blocknrs[nr_allocated], !hint->formatted_node);
-
-	    return NO_DISK_SPACE;
-	}
-    } while ((nr_allocated += allocate_without_wrapping_disk (hint,
-			    new_blocknrs + nr_allocated, start, finish,
-			    bigalloc ? bigalloc : 1,
-			    amount_needed - nr_allocated,
-			    hint->prealloc_size))
-			< amount_needed);
-    if ( !hint->formatted_node &&
-         amount_needed + hint->prealloc_size >
-	 nr_allocated + REISERFS_I(hint->inode)->i_prealloc_count) {
-    /* Some of preallocation blocks were not allocated */
+				DQUOT_FREE_BLOCK_NODIRTY(hint->inode, amount_needed + hint->prealloc_size - nr_allocated);	/* Free not allocated blocks */
+			}
+			while (nr_allocated--)
+				reiserfs_free_block(hint->th, hint->inode,
+						    new_blocknrs[nr_allocated],
+						    !hint->formatted_node);
+
+			return NO_DISK_SPACE;
+		}
+	} while ((nr_allocated += allocate_without_wrapping_disk(hint,
+								 new_blocknrs +
+								 nr_allocated,
+								 start, finish,
+								 bigalloc ?
+								 bigalloc : 1,
+								 amount_needed -
+								 nr_allocated,
+								 hint->
+								 prealloc_size))
+		 < amount_needed);
+	if (!hint->formatted_node &&
+	    amount_needed + hint->prealloc_size >
+	    nr_allocated + REISERFS_I(hint->inode)->i_prealloc_count) {
+		/* Some of preallocation blocks were not allocated */
 #ifdef REISERQUOTA_DEBUG
-	reiserfs_debug (s, REISERFS_DEBUG_CODE, "reiserquota: freeing (failed prealloc) %d blocks id=%u", amount_needed + hint->prealloc_size - nr_allocated - REISERFS_I(hint->inode)->i_prealloc_count, hint->inode->i_uid);
+		reiserfs_debug(s, REISERFS_DEBUG_CODE,
+			       "reiserquota: freeing (failed prealloc) %d blocks id=%u",
+			       amount_needed + hint->prealloc_size -
+			       nr_allocated -
+			       REISERFS_I(hint->inode)->i_prealloc_count,
+			       hint->inode->i_uid);
 #endif
-	DQUOT_FREE_BLOCK_NODIRTY(hint->inode, amount_needed +
-	                         hint->prealloc_size - nr_allocated -
-				 REISERFS_I(hint->inode)->i_prealloc_count);
-    }
+		DQUOT_FREE_BLOCK_NODIRTY(hint->inode, amount_needed +
+					 hint->prealloc_size - nr_allocated -
+					 REISERFS_I(hint->inode)->
+					 i_prealloc_count);
+	}
 
-    return CARRY_ON;
+	return CARRY_ON;
 }
 
 /* grab new blocknrs from preallocated list */
 /* return amount still needed after using them */
-static int use_preallocated_list_if_available (reiserfs_blocknr_hint_t *hint,
-					       b_blocknr_t *new_blocknrs, int amount_needed)
+static int use_preallocated_list_if_available(reiserfs_blocknr_hint_t * hint,
+					      b_blocknr_t * new_blocknrs,
+					      int amount_needed)
 {
-    struct inode * inode = hint->inode;
+	struct inode *inode = hint->inode;
+
+	if (REISERFS_I(inode)->i_prealloc_count > 0) {
+		while (amount_needed) {
+
+			*new_blocknrs++ = REISERFS_I(inode)->i_prealloc_block++;
+			REISERFS_I(inode)->i_prealloc_count--;
 
-    if (REISERFS_I(inode)->i_prealloc_count > 0) {
-	while (amount_needed) {
+			amount_needed--;
+
+			if (REISERFS_I(inode)->i_prealloc_count <= 0) {
+				list_del(&REISERFS_I(inode)->i_prealloc_list);
+				break;
+			}
+		}
+	}
+	/* return amount still needed after using preallocated blocks */
+	return amount_needed;
+}
 
-	    *new_blocknrs ++ = REISERFS_I(inode)->i_prealloc_block ++;
-	    REISERFS_I(inode)->i_prealloc_count --;
-
-	    amount_needed --;
-
-	    if (REISERFS_I(inode)->i_prealloc_count <= 0) {
-		list_del(&REISERFS_I(inode)->i_prealloc_list);  
-		break;
-	    }
-	}
-      }
-    /* return amount still needed after using preallocated blocks */
-    return amount_needed;
-}
-
-int reiserfs_allocate_blocknrs(reiserfs_blocknr_hint_t *hint,
-			       b_blocknr_t * new_blocknrs, int amount_needed,
-			       int reserved_by_us /* Amount of blocks we have
-						      already reserved */)
-{
-    int initial_amount_needed = amount_needed;
-    int ret;
-    struct super_block *s = hint->th->t_super;
-
-    /* Check if there is enough space, taking into account reserved space */
-    if ( SB_FREE_BLOCKS(s) - REISERFS_SB(s)->reserved_blocks <
-	 amount_needed - reserved_by_us)
-        return NO_DISK_SPACE;
-    /* should this be if !hint->inode &&  hint->preallocate? */
-    /* do you mean hint->formatted_node can be removed ? - Zam */
-    /* hint->formatted_node cannot be removed because we try to access
-       inode information here, and there is often no inode assotiated with
-       metadata allocations - green */
+int reiserfs_allocate_blocknrs(reiserfs_blocknr_hint_t * hint, b_blocknr_t * new_blocknrs, int amount_needed, int reserved_by_us	/* Amount of blocks we have
+																	   already reserved */ )
+{
+	int initial_amount_needed = amount_needed;
+	int ret;
+	struct super_block *s = hint->th->t_super;
+
+	/* Check if there is enough space, taking into account reserved space */
+	if (SB_FREE_BLOCKS(s) - REISERFS_SB(s)->reserved_blocks <
+	    amount_needed - reserved_by_us)
+		return NO_DISK_SPACE;
+	/* should this be if !hint->inode &&  hint->preallocate? */
+	/* do you mean hint->formatted_node can be removed ? - Zam */
+	/* hint->formatted_node cannot be removed because we try to access
+	   inode information here, and there is often no inode assotiated with
+	   metadata allocations - green */
+
+	if (!hint->formatted_node && hint->preallocate) {
+		amount_needed = use_preallocated_list_if_available
+		    (hint, new_blocknrs, amount_needed);
+		if (amount_needed == 0)	/* all blocknrs we need we got from
+					   prealloc. list */
+			return CARRY_ON;
+		new_blocknrs += (initial_amount_needed - amount_needed);
+	}
+
+	/* find search start and save it in hint structure */
+	determine_search_start(hint, amount_needed);
+	if (hint->search_start >= SB_BLOCK_COUNT(s))
+		hint->search_start = SB_BLOCK_COUNT(s) - 1;
 
-    if (!hint->formatted_node && hint->preallocate) {
-	amount_needed = use_preallocated_list_if_available
+	/* allocation itself; fill new_blocknrs and preallocation arrays */
+	ret = blocknrs_and_prealloc_arrays_from_search_start
 	    (hint, new_blocknrs, amount_needed);
-	if (amount_needed == 0)	/* all blocknrs we need we got from
-                                   prealloc. list */
-	    return CARRY_ON;
-	new_blocknrs += (initial_amount_needed - amount_needed);
-    }
-
-    /* find search start and save it in hint structure */
-    determine_search_start(hint, amount_needed);
-    if (hint->search_start >= SB_BLOCK_COUNT(s))
-        hint->search_start = SB_BLOCK_COUNT(s) - 1;
-
-    /* allocation itself; fill new_blocknrs and preallocation arrays */
-    ret = blocknrs_and_prealloc_arrays_from_search_start
-	(hint, new_blocknrs, amount_needed);
-
-    /* we used prealloc. list to fill (partially) new_blocknrs array. If final allocation fails we
-     * need to return blocks back to prealloc. list or just free them. -- Zam (I chose second
-     * variant) */
-
-    if (ret != CARRY_ON) {
-	while (amount_needed ++ < initial_amount_needed) {
-	    reiserfs_free_block(hint->th, hint->inode, *(--new_blocknrs), 1);
+
+	/* we used prealloc. list to fill (partially) new_blocknrs array. If final allocation fails we
+	 * need to return blocks back to prealloc. list or just free them. -- Zam (I chose second
+	 * variant) */
+
+	if (ret != CARRY_ON) {
+		while (amount_needed++ < initial_amount_needed) {
+			reiserfs_free_block(hint->th, hint->inode,
+					    *(--new_blocknrs), 1);
+		}
 	}
-    }
-    return ret;
+	return ret;
 }
 
 /* These 2 functions are here to provide blocks reservation to the rest of kernel */
 /* Reserve @blocks amount of blocks in fs pointed by @sb. Caller must make sure
    there are actually this much blocks on the FS available */
-void reiserfs_claim_blocks_to_be_allocated( 
-				      struct super_block *sb, /* super block of
-							        filesystem where
-								blocks should be
-								reserved */
-				      int blocks /* How much to reserve */
-					  )
+void reiserfs_claim_blocks_to_be_allocated(struct super_block *sb,	/* super block of
+									   filesystem where
+									   blocks should be
+									   reserved */
+					   int blocks	/* How much to reserve */
+    )
 {
 
-    /* Fast case, if reservation is zero - exit immediately. */
-    if ( !blocks )
-	return;
+	/* Fast case, if reservation is zero - exit immediately. */
+	if (!blocks)
+		return;
 
-    spin_lock(&REISERFS_SB(sb)->bitmap_lock);
-    REISERFS_SB(sb)->reserved_blocks += blocks;
-    spin_unlock(&REISERFS_SB(sb)->bitmap_lock);
+	spin_lock(&REISERFS_SB(sb)->bitmap_lock);
+	REISERFS_SB(sb)->reserved_blocks += blocks;
+	spin_unlock(&REISERFS_SB(sb)->bitmap_lock);
 }
 
 /* Unreserve @blocks amount of blocks in fs pointed by @sb */
-void reiserfs_release_claimed_blocks( 
-				struct super_block *sb, /* super block of
-							  filesystem where
-							  blocks should be
-							  reserved */
-				int blocks /* How much to unreserve */
-					  )
+void reiserfs_release_claimed_blocks(struct super_block *sb,	/* super block of
+								   filesystem where
+								   blocks should be
+								   reserved */
+				     int blocks	/* How much to unreserve */
+    )
 {
 
-    /* Fast case, if unreservation is zero - exit immediately. */
-    if ( !blocks )
-	return;
+	/* Fast case, if unreservation is zero - exit immediately. */
+	if (!blocks)
+		return;
 
-    spin_lock(&REISERFS_SB(sb)->bitmap_lock);
-    REISERFS_SB(sb)->reserved_blocks -= blocks;
-    spin_unlock(&REISERFS_SB(sb)->bitmap_lock);
-    RFALSE( REISERFS_SB(sb)->reserved_blocks < 0, "amount of blocks reserved became zero?");
+	spin_lock(&REISERFS_SB(sb)->bitmap_lock);
+	REISERFS_SB(sb)->reserved_blocks -= blocks;
+	spin_unlock(&REISERFS_SB(sb)->bitmap_lock);
+	RFALSE(REISERFS_SB(sb)->reserved_blocks < 0,
+	       "amount of blocks reserved became zero?");
 }
 
 /* This function estimates how much pages we will be able to write to FS
    used for reiserfs_file_write() purposes for now. */
-int reiserfs_can_fit_pages ( struct super_block *sb /* superblock of filesystem
-						       to estimate space */ )
+int reiserfs_can_fit_pages(struct super_block *sb	/* superblock of filesystem
+							   to estimate space */ )
 {
 	int space;
 
 	spin_lock(&REISERFS_SB(sb)->bitmap_lock);
-	space = (SB_FREE_BLOCKS(sb) - REISERFS_SB(sb)->reserved_blocks) >> ( PAGE_CACHE_SHIFT - sb->s_blocksize_bits);
+	space =
+	    (SB_FREE_BLOCKS(sb) -
+	     REISERFS_SB(sb)->reserved_blocks) >> (PAGE_CACHE_SHIFT -
+						   sb->s_blocksize_bits);
 	spin_unlock(&REISERFS_SB(sb)->bitmap_lock);
 
-	return space>0?space:0;
+	return space > 0 ? space : 0;
 }
diff --git a/fs/reiserfs/dir.c b/fs/reiserfs/dir.c
--- a/fs/reiserfs/dir.c
+++ b/fs/reiserfs/dir.c
@@ -12,264 +12,286 @@
 #include <linux/buffer_head.h>
 #include <asm/uaccess.h>
 
-extern struct reiserfs_key  MIN_KEY;
+extern struct reiserfs_key MIN_KEY;
 
-static int reiserfs_readdir (struct file *, void *, filldir_t);
-static int reiserfs_dir_fsync(struct file *filp, struct dentry *dentry, int datasync) ;
+static int reiserfs_readdir(struct file *, void *, filldir_t);
+static int reiserfs_dir_fsync(struct file *filp, struct dentry *dentry,
+			      int datasync);
 
 struct file_operations reiserfs_dir_operations = {
-    .read	= generic_read_dir,
-    .readdir	= reiserfs_readdir,
-    .fsync	= reiserfs_dir_fsync,
-    .ioctl	= reiserfs_ioctl,
+	.read = generic_read_dir,
+	.readdir = reiserfs_readdir,
+	.fsync = reiserfs_dir_fsync,
+	.ioctl = reiserfs_ioctl,
 };
 
-static int reiserfs_dir_fsync(struct file *filp, struct dentry *dentry, int datasync) {
-  struct inode *inode = dentry->d_inode;
-  int err;
-  reiserfs_write_lock(inode->i_sb);
-  err = reiserfs_commit_for_inode(inode) ;
-  reiserfs_write_unlock(inode->i_sb) ;
-  if (err < 0)
-      return err;
-  return 0;
+static int reiserfs_dir_fsync(struct file *filp, struct dentry *dentry,
+			      int datasync)
+{
+	struct inode *inode = dentry->d_inode;
+	int err;
+	reiserfs_write_lock(inode->i_sb);
+	err = reiserfs_commit_for_inode(inode);
+	reiserfs_write_unlock(inode->i_sb);
+	if (err < 0)
+		return err;
+	return 0;
 }
 
-
 #define store_ih(where,what) copy_item_head (where, what)
 
 //
-static int reiserfs_readdir (struct file * filp, void * dirent, filldir_t filldir)
+static int reiserfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
 {
-    struct inode *inode = filp->f_dentry->d_inode;
-    struct cpu_key pos_key;	/* key of current position in the directory (key of directory entry) */
-    INITIALIZE_PATH (path_to_entry);
-    struct buffer_head * bh;
-    int item_num, entry_num;
-    const struct reiserfs_key * rkey;
-    struct item_head * ih, tmp_ih;
-    int search_res;
-    char * local_buf;
-    loff_t next_pos;
-    char small_buf[32] ; /* avoid kmalloc if we can */
-    struct reiserfs_dir_entry de;
-    int ret = 0;
-
-    reiserfs_write_lock(inode->i_sb);
-
-    reiserfs_check_lock_depth(inode->i_sb, "readdir") ;
-
-    /* form key for search the next directory entry using f_pos field of
-       file structure */
-    make_cpu_key (&pos_key, inode, (filp->f_pos) ? (filp->f_pos) : DOT_OFFSET,
-		  TYPE_DIRENTRY, 3);
-    next_pos = cpu_key_k_offset (&pos_key);
-
-    /*  reiserfs_warning (inode->i_sb, "reiserfs_readdir 1: f_pos = %Ld", filp->f_pos);*/
-
-    path_to_entry.reada = PATH_READA;
-    while (1) {
-    research:
-	/* search the directory item, containing entry with specified key */
-	search_res = search_by_entry_key (inode->i_sb, &pos_key, &path_to_entry, &de);
-	if (search_res == IO_ERROR) {
-	    // FIXME: we could just skip part of directory which could
-	    // not be read
-	    ret = -EIO;
-	    goto out;
-	}
-	entry_num = de.de_entry_num;
-	bh = de.de_bh;
-	item_num = de.de_item_num;
-	ih = de.de_ih;
-	store_ih (&tmp_ih, ih);
-		
-	/* we must have found item, that is item of this directory, */
-	RFALSE( COMP_SHORT_KEYS (&(ih->ih_key), &pos_key),
-		"vs-9000: found item %h does not match to dir we readdir %K",
-		ih, &pos_key);
-	RFALSE( item_num > B_NR_ITEMS (bh) - 1,
-		"vs-9005 item_num == %d, item amount == %d", 
-		item_num, B_NR_ITEMS (bh));
-      
-	/* and entry must be not more than number of entries in the item */
-	RFALSE( I_ENTRY_COUNT (ih) < entry_num,
-		"vs-9010: entry number is too big %d (%d)", 
-		entry_num, I_ENTRY_COUNT (ih));
-
-	if (search_res == POSITION_FOUND || entry_num < I_ENTRY_COUNT (ih)) {
-	    /* go through all entries in the directory item beginning from the entry, that has been found */
-	    struct reiserfs_de_head * deh = B_I_DEH (bh, ih) + entry_num;
-
-	    for (; entry_num < I_ENTRY_COUNT (ih); entry_num ++, deh ++) {
-		int d_reclen;
-		char * d_name;
-		off_t d_off;
-		ino_t d_ino;
-
-		if (!de_visible (deh))
-		    /* it is hidden entry */
-		    continue;
-		d_reclen = entry_length (bh, ih, entry_num);
-		d_name = B_I_DEH_ENTRY_FILE_NAME (bh, ih, deh);
-		if (!d_name[d_reclen - 1])
-		    d_reclen = strlen (d_name);
-	
-		if (d_reclen > REISERFS_MAX_NAME(inode->i_sb->s_blocksize)){
-		    /* too big to send back to VFS */
-		    continue ;
-		}
-
-                /* Ignore the .reiserfs_priv entry */
-                if (reiserfs_xattrs (inode->i_sb) &&
-                    !old_format_only(inode->i_sb) &&
-                    filp->f_dentry == inode->i_sb->s_root &&
-                    REISERFS_SB(inode->i_sb)->priv_root &&
-                    REISERFS_SB(inode->i_sb)->priv_root->d_inode &&
-                    deh_objectid(deh) == le32_to_cpu (INODE_PKEY(REISERFS_SB(inode->i_sb)->priv_root->d_inode)->k_objectid)) {
-                  continue;
-                }
-
-		d_off = deh_offset (deh);
-		filp->f_pos = d_off ;
-		d_ino = deh_objectid (deh);
-		if (d_reclen <= 32) {
-		  local_buf = small_buf ;
-		} else {
-		    local_buf = reiserfs_kmalloc(d_reclen, GFP_NOFS, inode->i_sb) ;
-		    if (!local_buf) {
-			pathrelse (&path_to_entry);
-			ret = -ENOMEM ;
+	struct inode *inode = filp->f_dentry->d_inode;
+	struct cpu_key pos_key;	/* key of current position in the directory (key of directory entry) */
+	INITIALIZE_PATH(path_to_entry);
+	struct buffer_head *bh;
+	int item_num, entry_num;
+	const struct reiserfs_key *rkey;
+	struct item_head *ih, tmp_ih;
+	int search_res;
+	char *local_buf;
+	loff_t next_pos;
+	char small_buf[32];	/* avoid kmalloc if we can */
+	struct reiserfs_dir_entry de;
+	int ret = 0;
+
+	reiserfs_write_lock(inode->i_sb);
+
+	reiserfs_check_lock_depth(inode->i_sb, "readdir");
+
+	/* form key for search the next directory entry using f_pos field of
+	   file structure */
+	make_cpu_key(&pos_key, inode,
+		     (filp->f_pos) ? (filp->f_pos) : DOT_OFFSET, TYPE_DIRENTRY,
+		     3);
+	next_pos = cpu_key_k_offset(&pos_key);
+
+	/*  reiserfs_warning (inode->i_sb, "reiserfs_readdir 1: f_pos = %Ld", filp->f_pos); */
+
+	path_to_entry.reada = PATH_READA;
+	while (1) {
+	      research:
+		/* search the directory item, containing entry with specified key */
+		search_res =
+		    search_by_entry_key(inode->i_sb, &pos_key, &path_to_entry,
+					&de);
+		if (search_res == IO_ERROR) {
+			// FIXME: we could just skip part of directory which could
+			// not be read
+			ret = -EIO;
 			goto out;
-		    }
-		    if (item_moved (&tmp_ih, &path_to_entry)) {
-			reiserfs_kfree(local_buf, d_reclen, inode->i_sb) ;
-			goto research;
-		    }
 		}
-		// Note, that we copy name to user space via temporary
-		// buffer (local_buf) because filldir will block if
-		// user space buffer is swapped out. At that time
-		// entry can move to somewhere else
-		memcpy (local_buf, d_name, d_reclen);
-		if (filldir (dirent, local_buf, d_reclen, d_off, d_ino, 
-		             DT_UNKNOWN) < 0) {
-		    if (local_buf != small_buf) {
-			reiserfs_kfree(local_buf, d_reclen, inode->i_sb) ;
-		    }
-		    goto end;
-		}
-		if (local_buf != small_buf) {
-		    reiserfs_kfree(local_buf, d_reclen, inode->i_sb) ;
+		entry_num = de.de_entry_num;
+		bh = de.de_bh;
+		item_num = de.de_item_num;
+		ih = de.de_ih;
+		store_ih(&tmp_ih, ih);
+
+		/* we must have found item, that is item of this directory, */
+		RFALSE(COMP_SHORT_KEYS(&(ih->ih_key), &pos_key),
+		       "vs-9000: found item %h does not match to dir we readdir %K",
+		       ih, &pos_key);
+		RFALSE(item_num > B_NR_ITEMS(bh) - 1,
+		       "vs-9005 item_num == %d, item amount == %d",
+		       item_num, B_NR_ITEMS(bh));
+
+		/* and entry must be not more than number of entries in the item */
+		RFALSE(I_ENTRY_COUNT(ih) < entry_num,
+		       "vs-9010: entry number is too big %d (%d)",
+		       entry_num, I_ENTRY_COUNT(ih));
+
+		if (search_res == POSITION_FOUND
+		    || entry_num < I_ENTRY_COUNT(ih)) {
+			/* go through all entries in the directory item beginning from the entry, that has been found */
+			struct reiserfs_de_head *deh =
+			    B_I_DEH(bh, ih) + entry_num;
+
+			for (; entry_num < I_ENTRY_COUNT(ih);
+			     entry_num++, deh++) {
+				int d_reclen;
+				char *d_name;
+				off_t d_off;
+				ino_t d_ino;
+
+				if (!de_visible(deh))
+					/* it is hidden entry */
+					continue;
+				d_reclen = entry_length(bh, ih, entry_num);
+				d_name = B_I_DEH_ENTRY_FILE_NAME(bh, ih, deh);
+				if (!d_name[d_reclen - 1])
+					d_reclen = strlen(d_name);
+
+				if (d_reclen >
+				    REISERFS_MAX_NAME(inode->i_sb->
+						      s_blocksize)) {
+					/* too big to send back to VFS */
+					continue;
+				}
+
+				/* Ignore the .reiserfs_priv entry */
+				if (reiserfs_xattrs(inode->i_sb) &&
+				    !old_format_only(inode->i_sb) &&
+				    filp->f_dentry == inode->i_sb->s_root &&
+				    REISERFS_SB(inode->i_sb)->priv_root &&
+				    REISERFS_SB(inode->i_sb)->priv_root->d_inode
+				    && deh_objectid(deh) ==
+				    le32_to_cpu(INODE_PKEY
+						(REISERFS_SB(inode->i_sb)->
+						 priv_root->d_inode)->
+						k_objectid)) {
+					continue;
+				}
+
+				d_off = deh_offset(deh);
+				filp->f_pos = d_off;
+				d_ino = deh_objectid(deh);
+				if (d_reclen <= 32) {
+					local_buf = small_buf;
+				} else {
+					local_buf =
+					    reiserfs_kmalloc(d_reclen, GFP_NOFS,
+							     inode->i_sb);
+					if (!local_buf) {
+						pathrelse(&path_to_entry);
+						ret = -ENOMEM;
+						goto out;
+					}
+					if (item_moved(&tmp_ih, &path_to_entry)) {
+						reiserfs_kfree(local_buf,
+							       d_reclen,
+							       inode->i_sb);
+						goto research;
+					}
+				}
+				// Note, that we copy name to user space via temporary
+				// buffer (local_buf) because filldir will block if
+				// user space buffer is swapped out. At that time
+				// entry can move to somewhere else
+				memcpy(local_buf, d_name, d_reclen);
+				if (filldir
+				    (dirent, local_buf, d_reclen, d_off, d_ino,
+				     DT_UNKNOWN) < 0) {
+					if (local_buf != small_buf) {
+						reiserfs_kfree(local_buf,
+							       d_reclen,
+							       inode->i_sb);
+					}
+					goto end;
+				}
+				if (local_buf != small_buf) {
+					reiserfs_kfree(local_buf, d_reclen,
+						       inode->i_sb);
+				}
+				// next entry should be looked for with such offset
+				next_pos = deh_offset(deh) + 1;
+
+				if (item_moved(&tmp_ih, &path_to_entry)) {
+					goto research;
+				}
+			}	/* for */
 		}
 
-		// next entry should be looked for with such offset
-		next_pos = deh_offset (deh) + 1;
+		if (item_num != B_NR_ITEMS(bh) - 1)
+			// end of directory has been reached
+			goto end;
+
+		/* item we went through is last item of node. Using right
+		   delimiting key check is it directory end */
+		rkey = get_rkey(&path_to_entry, inode->i_sb);
+		if (!comp_le_keys(rkey, &MIN_KEY)) {
+			/* set pos_key to key, that is the smallest and greater
+			   that key of the last entry in the item */
+			set_cpu_key_k_offset(&pos_key, next_pos);
+			continue;
+		}
 
-		if (item_moved (&tmp_ih, &path_to_entry)) {
-		    goto research;
+		if (COMP_SHORT_KEYS(rkey, &pos_key)) {
+			// end of directory has been reached
+			goto end;
 		}
-	    } /* for */
-	}
 
-	if (item_num != B_NR_ITEMS (bh) - 1)
-	    // end of directory has been reached
-	    goto end;
-
-	/* item we went through is last item of node. Using right
-	   delimiting key check is it directory end */
-	rkey = get_rkey (&path_to_entry, inode->i_sb);
-	if (! comp_le_keys (rkey, &MIN_KEY)) {
-	    /* set pos_key to key, that is the smallest and greater
-	       that key of the last entry in the item */
-	    set_cpu_key_k_offset (&pos_key, next_pos);
-	    continue;
-	}
-
-	if ( COMP_SHORT_KEYS (rkey, &pos_key)) {
-	    // end of directory has been reached
-	    goto end;
-	}
-	
-	/* directory continues in the right neighboring block */
-	set_cpu_key_k_offset (&pos_key, le_key_k_offset (KEY_FORMAT_3_5, rkey));
-
-    } /* while */
-
-
- end:
-    filp->f_pos = next_pos;
-    pathrelse (&path_to_entry);
-    reiserfs_check_path(&path_to_entry) ;
- out:
-    reiserfs_write_unlock(inode->i_sb);
-    return ret;
+		/* directory continues in the right neighboring block */
+		set_cpu_key_k_offset(&pos_key,
+				     le_key_k_offset(KEY_FORMAT_3_5, rkey));
+
+	}			/* while */
+
+      end:
+	filp->f_pos = next_pos;
+	pathrelse(&path_to_entry);
+	reiserfs_check_path(&path_to_entry);
+      out:
+	reiserfs_write_unlock(inode->i_sb);
+	return ret;
 }
 
 /* compose directory item containing "." and ".." entries (entries are
    not aligned to 4 byte boundary) */
 /* the last four params are LE */
-void make_empty_dir_item_v1 (char * body, __le32 dirid, __le32 objid,
-			     __le32 par_dirid, __le32 par_objid)
+void make_empty_dir_item_v1(char *body, __le32 dirid, __le32 objid,
+			    __le32 par_dirid, __le32 par_objid)
 {
-    struct reiserfs_de_head * deh;
+	struct reiserfs_de_head *deh;
 
-    memset (body, 0, EMPTY_DIR_SIZE_V1);
-    deh = (struct reiserfs_de_head *)body;
-    
-    /* direntry header of "." */
-    put_deh_offset( &(deh[0]), DOT_OFFSET );
-    /* these two are from make_le_item_head, and are are LE */
-    deh[0].deh_dir_id = dirid;
-    deh[0].deh_objectid = objid;
-    deh[0].deh_state = 0; /* Endian safe if 0 */
-    put_deh_location( &(deh[0]), EMPTY_DIR_SIZE_V1 - strlen( "." ));
-    mark_de_visible(&(deh[0]));
-  
-    /* direntry header of ".." */
-    put_deh_offset( &(deh[1]), DOT_DOT_OFFSET);
-    /* key of ".." for the root directory */
-    /* these two are from the inode, and are are LE */
-    deh[1].deh_dir_id = par_dirid;
-    deh[1].deh_objectid = par_objid;
-    deh[1].deh_state = 0; /* Endian safe if 0 */
-    put_deh_location( &(deh[1]), deh_location( &(deh[0]) ) - strlen( ".." ) );
-    mark_de_visible(&(deh[1]));
-
-    /* copy ".." and "." */
-    memcpy (body + deh_location( &(deh[0]) ), ".", 1);
-    memcpy (body + deh_location( &(deh[1]) ), "..", 2);
+	memset(body, 0, EMPTY_DIR_SIZE_V1);
+	deh = (struct reiserfs_de_head *)body;
+
+	/* direntry header of "." */
+	put_deh_offset(&(deh[0]), DOT_OFFSET);
+	/* these two are from make_le_item_head, and are are LE */
+	deh[0].deh_dir_id = dirid;
+	deh[0].deh_objectid = objid;
+	deh[0].deh_state = 0;	/* Endian safe if 0 */
+	put_deh_location(&(deh[0]), EMPTY_DIR_SIZE_V1 - strlen("."));
+	mark_de_visible(&(deh[0]));
+
+	/* direntry header of ".." */
+	put_deh_offset(&(deh[1]), DOT_DOT_OFFSET);
+	/* key of ".." for the root directory */
+	/* these two are from the inode, and are are LE */
+	deh[1].deh_dir_id = par_dirid;
+	deh[1].deh_objectid = par_objid;
+	deh[1].deh_state = 0;	/* Endian safe if 0 */
+	put_deh_location(&(deh[1]), deh_location(&(deh[0])) - strlen(".."));
+	mark_de_visible(&(deh[1]));
+
+	/* copy ".." and "." */
+	memcpy(body + deh_location(&(deh[0])), ".", 1);
+	memcpy(body + deh_location(&(deh[1])), "..", 2);
 }
 
 /* compose directory item containing "." and ".." entries */
-void make_empty_dir_item (char * body, __le32 dirid, __le32 objid,
-			  __le32 par_dirid, __le32 par_objid)
+void make_empty_dir_item(char *body, __le32 dirid, __le32 objid,
+			 __le32 par_dirid, __le32 par_objid)
 {
-    struct reiserfs_de_head * deh;
+	struct reiserfs_de_head *deh;
+
+	memset(body, 0, EMPTY_DIR_SIZE);
+	deh = (struct reiserfs_de_head *)body;
 
-    memset (body, 0, EMPTY_DIR_SIZE);
-    deh = (struct reiserfs_de_head *)body;
-    
-    /* direntry header of "." */
-    put_deh_offset( &(deh[0]), DOT_OFFSET );
-    /* these two are from make_le_item_head, and are are LE */
-    deh[0].deh_dir_id = dirid;
-    deh[0].deh_objectid = objid;
-    deh[0].deh_state = 0; /* Endian safe if 0 */
-    put_deh_location( &(deh[0]), EMPTY_DIR_SIZE - ROUND_UP( strlen( "." ) ) );
-    mark_de_visible(&(deh[0]));
-  
-    /* direntry header of ".." */
-    put_deh_offset( &(deh[1]), DOT_DOT_OFFSET );
-    /* key of ".." for the root directory */
-    /* these two are from the inode, and are are LE */
-    deh[1].deh_dir_id = par_dirid;
-    deh[1].deh_objectid = par_objid;
-    deh[1].deh_state = 0; /* Endian safe if 0 */
-    put_deh_location( &(deh[1]), deh_location( &(deh[0])) - ROUND_UP( strlen( ".." ) ) );
-    mark_de_visible(&(deh[1]));
-
-    /* copy ".." and "." */
-    memcpy (body + deh_location( &(deh[0]) ), ".", 1);
-    memcpy (body + deh_location( &(deh[1]) ), "..", 2);
+	/* direntry header of "." */
+	put_deh_offset(&(deh[0]), DOT_OFFSET);
+	/* these two are from make_le_item_head, and are are LE */
+	deh[0].deh_dir_id = dirid;
+	deh[0].deh_objectid = objid;
+	deh[0].deh_state = 0;	/* Endian safe if 0 */
+	put_deh_location(&(deh[0]), EMPTY_DIR_SIZE - ROUND_UP(strlen(".")));
+	mark_de_visible(&(deh[0]));
+
+	/* direntry header of ".." */
+	put_deh_offset(&(deh[1]), DOT_DOT_OFFSET);
+	/* key of ".." for the root directory */
+	/* these two are from the inode, and are are LE */
+	deh[1].deh_dir_id = par_dirid;
+	deh[1].deh_objectid = par_objid;
+	deh[1].deh_state = 0;	/* Endian safe if 0 */
+	put_deh_location(&(deh[1]),
+			 deh_location(&(deh[0])) - ROUND_UP(strlen("..")));
+	mark_de_visible(&(deh[1]));
+
+	/* copy ".." and "." */
+	memcpy(body + deh_location(&(deh[0])), ".", 1);
+	memcpy(body + deh_location(&(deh[1])), "..", 2);
 }
diff --git a/fs/reiserfs/do_balan.c b/fs/reiserfs/do_balan.c
--- a/fs/reiserfs/do_balan.c
+++ b/fs/reiserfs/do_balan.c
@@ -8,7 +8,6 @@
 /* balance the tree according to the analysis made before,		*/
 /* and using buffers obtained after all above.				*/
 
-
 /**
  ** balance_leaf_when_delete
  ** balance_leaf
@@ -24,23 +23,22 @@
 
 #ifdef CONFIG_REISERFS_CHECK
 
-struct tree_balance * cur_tb = NULL; /* detects whether more than one
-                                        copy of tb exists as a means
-                                        of checking whether schedule
-                                        is interrupting do_balance */
+struct tree_balance *cur_tb = NULL;	/* detects whether more than one
+					   copy of tb exists as a means
+					   of checking whether schedule
+					   is interrupting do_balance */
 #endif
 
-inline void do_balance_mark_leaf_dirty (struct tree_balance * tb, 
-					struct buffer_head * bh, int flag)
+inline void do_balance_mark_leaf_dirty(struct tree_balance *tb,
+				       struct buffer_head *bh, int flag)
 {
-    journal_mark_dirty(tb->transaction_handle,
-                       tb->transaction_handle->t_super, bh) ;
+	journal_mark_dirty(tb->transaction_handle,
+			   tb->transaction_handle->t_super, bh);
 }
 
 #define do_balance_mark_internal_dirty do_balance_mark_leaf_dirty
 #define do_balance_mark_sb_dirty do_balance_mark_leaf_dirty
 
-
 /* summary: 
  if deleting something ( tb->insert_size[0] < 0 )
    return(balance_leaf_when_delete()); (flag d handled here)
@@ -64,8 +62,6 @@ be performed by do_balance.
 
 -Hans */
 
-
-
 /* Balance leaf node in case of delete or cut: insert_size[0] < 0
  *
  * lnum, rnum can have values >= -1
@@ -73,1384 +69,1933 @@ be performed by do_balance.
  *	 0 means that nothing should be done with the neighbor
  *	>0 means to shift entirely or partly the specified number of items to the neighbor
  */
-static int balance_leaf_when_delete (struct tree_balance * tb, int flag)
+static int balance_leaf_when_delete(struct tree_balance *tb, int flag)
 {
-    struct buffer_head * tbS0 = PATH_PLAST_BUFFER (tb->tb_path);
-    int item_pos = PATH_LAST_POSITION (tb->tb_path);
-    int pos_in_item = tb->tb_path->pos_in_item;
-    struct buffer_info bi;
-    int n;
-    struct item_head * ih;
-
-    RFALSE( tb->FR[0] && B_LEVEL (tb->FR[0]) != DISK_LEAF_NODE_LEVEL + 1,
-	    "vs- 12000: level: wrong FR %z", tb->FR[0]);
-    RFALSE( tb->blknum[0] > 1,
-	    "PAP-12005: tb->blknum == %d, can not be > 1", tb->blknum[0]);
-    RFALSE( ! tb->blknum[0] && ! PATH_H_PPARENT(tb->tb_path, 0),
-	    "PAP-12010: tree can not be empty");
-
-    ih = B_N_PITEM_HEAD (tbS0, item_pos);
-
-    /* Delete or truncate the item */
-
-    switch (flag) {
-    case M_DELETE:   /* delete item in S[0] */
-
-	RFALSE( ih_item_len(ih) + IH_SIZE != -tb->insert_size[0],
-	        "vs-12013: mode Delete, insert size %d, ih to be deleted %h",
- 		 -tb->insert_size [0], ih);
-
-	bi.tb = tb;
-	bi.bi_bh = tbS0;
-	bi.bi_parent = PATH_H_PPARENT (tb->tb_path, 0);
-	bi.bi_position = PATH_H_POSITION (tb->tb_path, 1);
-	leaf_delete_items (&bi, 0, item_pos, 1, -1);
-
-	if ( ! item_pos && tb->CFL[0] ) {
-	    if ( B_NR_ITEMS(tbS0) ) {
-		replace_key(tb, tb->CFL[0],tb->lkey[0],tbS0,0);
-	    }
-	    else {
-		if ( ! PATH_H_POSITION (tb->tb_path, 1) )
-		    replace_key(tb, tb->CFL[0],tb->lkey[0],PATH_H_PPARENT(tb->tb_path, 0),0);
-	    }
-	} 
-
-	RFALSE( ! item_pos && !tb->CFL[0],
-		"PAP-12020: tb->CFL[0]==%p, tb->L[0]==%p", tb->CFL[0], tb->L[0]);
-    
-	break;
+	struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path);
+	int item_pos = PATH_LAST_POSITION(tb->tb_path);
+	int pos_in_item = tb->tb_path->pos_in_item;
+	struct buffer_info bi;
+	int n;
+	struct item_head *ih;
+
+	RFALSE(tb->FR[0] && B_LEVEL(tb->FR[0]) != DISK_LEAF_NODE_LEVEL + 1,
+	       "vs- 12000: level: wrong FR %z", tb->FR[0]);
+	RFALSE(tb->blknum[0] > 1,
+	       "PAP-12005: tb->blknum == %d, can not be > 1", tb->blknum[0]);
+	RFALSE(!tb->blknum[0] && !PATH_H_PPARENT(tb->tb_path, 0),
+	       "PAP-12010: tree can not be empty");
 
-    case M_CUT: {  /* cut item in S[0] */
-	bi.tb = tb;
-	bi.bi_bh = tbS0;
-	bi.bi_parent = PATH_H_PPARENT (tb->tb_path, 0);
-	bi.bi_position = PATH_H_POSITION (tb->tb_path, 1);
-	if (is_direntry_le_ih (ih)) {
-
-	    /* UFS unlink semantics are such that you can only delete one directory entry at a time. */
-	    /* when we cut a directory tb->insert_size[0] means number of entries to be cut (always 1) */
-	    tb->insert_size[0] = -1;
-	    leaf_cut_from_buffer (&bi, item_pos, pos_in_item, -tb->insert_size[0]);
-
-	    RFALSE( ! item_pos && ! pos_in_item && ! tb->CFL[0],
-		    "PAP-12030: can not change delimiting key. CFL[0]=%p", 
-		    tb->CFL[0]);
-
-	    if ( ! item_pos && ! pos_in_item && tb->CFL[0] ) {
-		replace_key(tb, tb->CFL[0],tb->lkey[0],tbS0,0);
-	    }
-	} else {
-	    leaf_cut_from_buffer (&bi, item_pos, pos_in_item, -tb->insert_size[0]);
-
-	    RFALSE( ! ih_item_len(ih),
-		"PAP-12035: cut must leave non-zero dynamic length of item");
-	}
-	break;
-    }
-
-    default:
-	print_cur_tb ("12040");
-	reiserfs_panic (tb->tb_sb, "PAP-12040: balance_leaf_when_delete: unexpectable mode: %s(%d)",
-			(flag == M_PASTE) ? "PASTE" : ((flag == M_INSERT) ? "INSERT" : "UNKNOWN"), flag);
-    }
-
-    /* the rule is that no shifting occurs unless by shifting a node can be freed */
-    n = B_NR_ITEMS(tbS0);
-    if ( tb->lnum[0] )     /* L[0] takes part in balancing */
-    {
-	if ( tb->lnum[0] == -1 )    /* L[0] must be joined with S[0] */
-	{
-	    if ( tb->rnum[0] == -1 )    /* R[0] must be also joined with S[0] */
-	    {			
-		if ( tb->FR[0] == PATH_H_PPARENT(tb->tb_path, 0) )
-		{
-		    /* all contents of all the 3 buffers will be in L[0] */
-		    if ( PATH_H_POSITION (tb->tb_path, 1) == 0 && 1 < B_NR_ITEMS(tb->FR[0]) )
-			replace_key(tb, tb->CFL[0],tb->lkey[0],tb->FR[0],1);
+	ih = B_N_PITEM_HEAD(tbS0, item_pos);
 
-		    leaf_move_items (LEAF_FROM_S_TO_L, tb, n, -1, NULL);
-		    leaf_move_items (LEAF_FROM_R_TO_L, tb, B_NR_ITEMS(tb->R[0]), -1, NULL);
+	/* Delete or truncate the item */
 
-		    reiserfs_invalidate_buffer (tb, tbS0);
-		    reiserfs_invalidate_buffer (tb, tb->R[0]);
+	switch (flag) {
+	case M_DELETE:		/* delete item in S[0] */
 
-		    return 0;
+		RFALSE(ih_item_len(ih) + IH_SIZE != -tb->insert_size[0],
+		       "vs-12013: mode Delete, insert size %d, ih to be deleted %h",
+		       -tb->insert_size[0], ih);
+
+		bi.tb = tb;
+		bi.bi_bh = tbS0;
+		bi.bi_parent = PATH_H_PPARENT(tb->tb_path, 0);
+		bi.bi_position = PATH_H_POSITION(tb->tb_path, 1);
+		leaf_delete_items(&bi, 0, item_pos, 1, -1);
+
+		if (!item_pos && tb->CFL[0]) {
+			if (B_NR_ITEMS(tbS0)) {
+				replace_key(tb, tb->CFL[0], tb->lkey[0], tbS0,
+					    0);
+			} else {
+				if (!PATH_H_POSITION(tb->tb_path, 1))
+					replace_key(tb, tb->CFL[0], tb->lkey[0],
+						    PATH_H_PPARENT(tb->tb_path,
+								   0), 0);
+			}
 		}
-		/* all contents of all the 3 buffers will be in R[0] */
-		leaf_move_items (LEAF_FROM_S_TO_R, tb, n, -1, NULL);
-		leaf_move_items (LEAF_FROM_L_TO_R, tb, B_NR_ITEMS(tb->L[0]), -1, NULL);
-
-		/* right_delimiting_key is correct in R[0] */
-		replace_key(tb, tb->CFR[0],tb->rkey[0],tb->R[0],0);
-
-		reiserfs_invalidate_buffer (tb, tbS0);
-		reiserfs_invalidate_buffer (tb, tb->L[0]);
-
-		return -1;
-	    }
-
-	    RFALSE( tb->rnum[0] != 0, 
-		    "PAP-12045: rnum must be 0 (%d)", tb->rnum[0]);
-	    /* all contents of L[0] and S[0] will be in L[0] */
-	    leaf_shift_left(tb, n, -1);
-
-	    reiserfs_invalidate_buffer (tb, tbS0);
-
-	    return 0;
-	}
-	/* a part of contents of S[0] will be in L[0] and the rest part of S[0] will be in R[0] */
-
-	RFALSE( ( tb->lnum[0] + tb->rnum[0] < n ) || 
-		( tb->lnum[0] + tb->rnum[0] > n+1 ),
-		"PAP-12050: rnum(%d) and lnum(%d) and item number(%d) in S[0] are not consistent",
-		tb->rnum[0], tb->lnum[0], n);
-	RFALSE( ( tb->lnum[0] + tb->rnum[0] == n ) && 
-		(tb->lbytes != -1 || tb->rbytes != -1),
-		"PAP-12055: bad rbytes (%d)/lbytes (%d) parameters when items are not split", 
-		tb->rbytes, tb->lbytes);
-	RFALSE( ( tb->lnum[0] + tb->rnum[0] == n + 1 ) && 
-		(tb->lbytes < 1 || tb->rbytes != -1),
-		"PAP-12060: bad rbytes (%d)/lbytes (%d) parameters when items are split", 
-		tb->rbytes, tb->lbytes);
 
-	leaf_shift_left (tb, tb->lnum[0], tb->lbytes);
-	leaf_shift_right(tb, tb->rnum[0], tb->rbytes);
+		RFALSE(!item_pos && !tb->CFL[0],
+		       "PAP-12020: tb->CFL[0]==%p, tb->L[0]==%p", tb->CFL[0],
+		       tb->L[0]);
 
-	reiserfs_invalidate_buffer (tb, tbS0);
+		break;
 
-	return 0;
-    }
+	case M_CUT:{		/* cut item in S[0] */
+			bi.tb = tb;
+			bi.bi_bh = tbS0;
+			bi.bi_parent = PATH_H_PPARENT(tb->tb_path, 0);
+			bi.bi_position = PATH_H_POSITION(tb->tb_path, 1);
+			if (is_direntry_le_ih(ih)) {
+
+				/* UFS unlink semantics are such that you can only delete one directory entry at a time. */
+				/* when we cut a directory tb->insert_size[0] means number of entries to be cut (always 1) */
+				tb->insert_size[0] = -1;
+				leaf_cut_from_buffer(&bi, item_pos, pos_in_item,
+						     -tb->insert_size[0]);
+
+				RFALSE(!item_pos && !pos_in_item && !tb->CFL[0],
+				       "PAP-12030: can not change delimiting key. CFL[0]=%p",
+				       tb->CFL[0]);
+
+				if (!item_pos && !pos_in_item && tb->CFL[0]) {
+					replace_key(tb, tb->CFL[0], tb->lkey[0],
+						    tbS0, 0);
+				}
+			} else {
+				leaf_cut_from_buffer(&bi, item_pos, pos_in_item,
+						     -tb->insert_size[0]);
 
-    if ( tb->rnum[0] == -1 ) {
-	/* all contents of R[0] and S[0] will be in R[0] */
-	leaf_shift_right(tb, n, -1);
-	reiserfs_invalidate_buffer (tb, tbS0);
-	return 0;
-    }
+				RFALSE(!ih_item_len(ih),
+				       "PAP-12035: cut must leave non-zero dynamic length of item");
+			}
+			break;
+		}
 
-    RFALSE( tb->rnum[0], 
-	    "PAP-12065: bad rnum parameter must be 0 (%d)", tb->rnum[0]);
-    return 0;
-}
+	default:
+		print_cur_tb("12040");
+		reiserfs_panic(tb->tb_sb,
+			       "PAP-12040: balance_leaf_when_delete: unexpectable mode: %s(%d)",
+			       (flag ==
+				M_PASTE) ? "PASTE" : ((flag ==
+						       M_INSERT) ? "INSERT" :
+						      "UNKNOWN"), flag);
+	}
 
+	/* the rule is that no shifting occurs unless by shifting a node can be freed */
+	n = B_NR_ITEMS(tbS0);
+	if (tb->lnum[0]) {	/* L[0] takes part in balancing */
+		if (tb->lnum[0] == -1) {	/* L[0] must be joined with S[0] */
+			if (tb->rnum[0] == -1) {	/* R[0] must be also joined with S[0] */
+				if (tb->FR[0] == PATH_H_PPARENT(tb->tb_path, 0)) {
+					/* all contents of all the 3 buffers will be in L[0] */
+					if (PATH_H_POSITION(tb->tb_path, 1) == 0
+					    && 1 < B_NR_ITEMS(tb->FR[0]))
+						replace_key(tb, tb->CFL[0],
+							    tb->lkey[0],
+							    tb->FR[0], 1);
+
+					leaf_move_items(LEAF_FROM_S_TO_L, tb, n,
+							-1, NULL);
+					leaf_move_items(LEAF_FROM_R_TO_L, tb,
+							B_NR_ITEMS(tb->R[0]),
+							-1, NULL);
+
+					reiserfs_invalidate_buffer(tb, tbS0);
+					reiserfs_invalidate_buffer(tb,
+								   tb->R[0]);
 
-static int balance_leaf (struct tree_balance * tb,
-			 struct item_head * ih,		/* item header of inserted item (this is on little endian) */
-			 const char * body,		/* body  of inserted item or bytes to paste */
-			 int flag,			/* i - insert, d - delete, c - cut, p - paste
-							   (see comment to do_balance) */
-			 struct item_head * insert_key,  /* in our processing of one level we sometimes determine what
-							    must be inserted into the next higher level.  This insertion
-							    consists of a key or two keys and their corresponding
-							    pointers */
-			 struct buffer_head ** insert_ptr /* inserted node-ptrs for the next level */
-    )
-{
-    struct buffer_head * tbS0 = PATH_PLAST_BUFFER (tb->tb_path);
-    int item_pos = PATH_LAST_POSITION (tb->tb_path);	/*  index into the array of item headers in S[0] 
-							    of the affected item */
-    struct buffer_info bi;
-    struct buffer_head *S_new[2];  /* new nodes allocated to hold what could not fit into S */
-    int snum[2];	    /* number of items that will be placed
-                               into S_new (includes partially shifted
-                               items) */
-    int sbytes[2];          /* if an item is partially shifted into S_new then 
-			       if it is a directory item 
-			       it is the number of entries from the item that are shifted into S_new
-			       else
-			       it is the number of bytes from the item that are shifted into S_new
-			    */
-    int n, i;
-    int ret_val;
-    int pos_in_item;
-    int zeros_num;
-
-    PROC_INFO_INC( tb -> tb_sb, balance_at[ 0 ] );
-
-    /* Make balance in case insert_size[0] < 0 */
-    if ( tb->insert_size[0] < 0 )
-	return balance_leaf_when_delete (tb, flag);
-  
-    zeros_num = 0;
-    if (flag == M_INSERT && body == 0)
-	zeros_num = ih_item_len( ih );
-
-    pos_in_item = tb->tb_path->pos_in_item;
-    /* for indirect item pos_in_item is measured in unformatted node
-       pointers. Recalculate to bytes */
-    if (flag != M_INSERT && is_indirect_le_ih (B_N_PITEM_HEAD (tbS0, item_pos)))
-	pos_in_item *= UNFM_P_SIZE;
-
-    if ( tb->lnum[0] > 0 ) {
-	/* Shift lnum[0] items from S[0] to the left neighbor L[0] */
-	if ( item_pos < tb->lnum[0] ) {
-	    /* new item or it part falls to L[0], shift it too */
-	    n = B_NR_ITEMS(tb->L[0]);
-
-	    switch (flag) {
-	    case M_INSERT:   /* insert item into L[0] */
-
-		if ( item_pos == tb->lnum[0] - 1 && tb->lbytes != -1 ) {
-		    /* part of new item falls into L[0] */
-		    int new_item_len;
-		    int version;
-
-		    ret_val = leaf_shift_left (tb, tb->lnum[0]-1, -1);
-
-		    /* Calculate item length to insert to S[0] */
-		    new_item_len = ih_item_len(ih) - tb->lbytes;
-		    /* Calculate and check item length to insert to L[0] */
-		    put_ih_item_len(ih, ih_item_len(ih) - new_item_len );
-
-		    RFALSE( ih_item_len(ih) <= 0,
-			    "PAP-12080: there is nothing to insert into L[0]: ih_item_len=%d",
-                            ih_item_len(ih));
-
-		    /* Insert new item into L[0] */
-		    bi.tb = tb;
-		    bi.bi_bh = tb->L[0];
-		    bi.bi_parent = tb->FL[0];
-		    bi.bi_position = get_left_neighbor_position (tb, 0);
-		    leaf_insert_into_buf (&bi, n + item_pos - ret_val, ih, body,
-					  zeros_num > ih_item_len(ih) ? ih_item_len(ih) : zeros_num);
-
-		    version = ih_version (ih);
-
-		    /* Calculate key component, item length and body to insert into S[0] */
-                    set_le_ih_k_offset( ih, le_ih_k_offset( ih ) + (tb->lbytes << (is_indirect_le_ih(ih)?tb->tb_sb->s_blocksize_bits - UNFM_P_SHIFT:0)) );
-
-		    put_ih_item_len( ih, new_item_len );
-		    if ( tb->lbytes >  zeros_num ) {
-			body += (tb->lbytes - zeros_num);
-			zeros_num = 0;
-		    }
-		    else
-			zeros_num -= tb->lbytes;
-
-		    RFALSE( ih_item_len(ih) <= 0,
-			"PAP-12085: there is nothing to insert into S[0]: ih_item_len=%d",
-			ih_item_len(ih));
-		} else {
-		    /* new item in whole falls into L[0] */
-		    /* Shift lnum[0]-1 items to L[0] */
-		    ret_val = leaf_shift_left(tb, tb->lnum[0]-1, tb->lbytes);
-		    /* Insert new item into L[0] */
-		    bi.tb = tb;
-		    bi.bi_bh = tb->L[0];
-		    bi.bi_parent = tb->FL[0];
-		    bi.bi_position = get_left_neighbor_position (tb, 0);
-		    leaf_insert_into_buf (&bi, n + item_pos - ret_val, ih, body, zeros_num);
-		    tb->insert_size[0] = 0;
-		    zeros_num = 0;
-		}
-		break;
+					return 0;
+				}
+				/* all contents of all the 3 buffers will be in R[0] */
+				leaf_move_items(LEAF_FROM_S_TO_R, tb, n, -1,
+						NULL);
+				leaf_move_items(LEAF_FROM_L_TO_R, tb,
+						B_NR_ITEMS(tb->L[0]), -1, NULL);
+
+				/* right_delimiting_key is correct in R[0] */
+				replace_key(tb, tb->CFR[0], tb->rkey[0],
+					    tb->R[0], 0);
 
-	    case M_PASTE:   /* append item in L[0] */
+				reiserfs_invalidate_buffer(tb, tbS0);
+				reiserfs_invalidate_buffer(tb, tb->L[0]);
 
-		if ( item_pos == tb->lnum[0] - 1 && tb->lbytes != -1 ) {
-		    /* we must shift the part of the appended item */
-		    if ( is_direntry_le_ih (B_N_PITEM_HEAD (tbS0, item_pos))) {
-
-			RFALSE( zeros_num,
-				"PAP-12090: invalid parameter in case of a directory");
-			/* directory item */
-			if ( tb->lbytes > pos_in_item ) {
-			    /* new directory entry falls into L[0] */
-			    struct item_head * pasted;
-			    int l_pos_in_item = pos_in_item;
-							  
-			    /* Shift lnum[0] - 1 items in whole. Shift lbytes - 1 entries from given directory item */
-			    ret_val = leaf_shift_left(tb, tb->lnum[0], tb->lbytes - 1);
-			    if ( ret_val && ! item_pos ) {
-				pasted =  B_N_PITEM_HEAD(tb->L[0],B_NR_ITEMS(tb->L[0])-1);
-				l_pos_in_item += I_ENTRY_COUNT(pasted) - (tb->lbytes-1);
-			    }
-
-			    /* Append given directory entry to directory item */
-			    bi.tb = tb;
-			    bi.bi_bh = tb->L[0];
-			    bi.bi_parent = tb->FL[0];
-			    bi.bi_position = get_left_neighbor_position (tb, 0);
-			    leaf_paste_in_buffer (&bi, n + item_pos - ret_val, l_pos_in_item,
-						  tb->insert_size[0], body, zeros_num);
-
-			    /* previous string prepared space for pasting new entry, following string pastes this entry */
-
-			    /* when we have merge directory item, pos_in_item has been changed too */
-
-			    /* paste new directory entry. 1 is entry number */
-			    leaf_paste_entries (bi.bi_bh, n + item_pos - ret_val, l_pos_in_item, 1,
-						(struct reiserfs_de_head *)body, 
-						body + DEH_SIZE, tb->insert_size[0]
-				);
-			    tb->insert_size[0] = 0;
-			} else {
-			    /* new directory item doesn't fall into L[0] */
-			    /* Shift lnum[0]-1 items in whole. Shift lbytes directory entries from directory item number lnum[0] */
-			    leaf_shift_left (tb, tb->lnum[0], tb->lbytes);
+				return -1;
 			}
-			/* Calculate new position to append in item body */
-			pos_in_item -= tb->lbytes;
-		    }
-		    else {
-			/* regular object */
-			RFALSE( tb->lbytes <= 0,
-			        "PAP-12095: there is nothing to shift to L[0]. lbytes=%d",
-				tb->lbytes);
-			RFALSE( pos_in_item != ih_item_len(B_N_PITEM_HEAD(tbS0, item_pos)),
-                                "PAP-12100: incorrect position to paste: item_len=%d, pos_in_item=%d",
-				ih_item_len(B_N_PITEM_HEAD(tbS0,item_pos)), pos_in_item);
-
-			if ( tb->lbytes >= pos_in_item ) {
-			    /* appended item will be in L[0] in whole */
-			    int l_n;
-
-			    /* this bytes number must be appended to the last item of L[h] */
-			    l_n = tb->lbytes - pos_in_item;
-
-			    /* Calculate new insert_size[0] */
-			    tb->insert_size[0] -= l_n;
-
-			    RFALSE( tb->insert_size[0] <= 0,
-				    "PAP-12105: there is nothing to paste into L[0]. insert_size=%d",
-				    tb->insert_size[0]);
-			    ret_val =  leaf_shift_left(tb,tb->lnum[0], 
-						       ih_item_len(B_N_PITEM_HEAD(tbS0,item_pos)));
-			    /* Append to body of item in L[0] */
-			    bi.tb = tb;
-			    bi.bi_bh = tb->L[0];
-			    bi.bi_parent = tb->FL[0];
-			    bi.bi_position = get_left_neighbor_position (tb, 0);
-			    leaf_paste_in_buffer(
-				&bi,n + item_pos - ret_val,
-				ih_item_len( B_N_PITEM_HEAD(tb->L[0],n+item_pos-ret_val)),
-				l_n,body, zeros_num > l_n ? l_n : zeros_num
-				);
-			    /* 0-th item in S0 can be only of DIRECT type when l_n != 0*/
-			    {
-				int version;
-				int temp_l = l_n;
-				
-				RFALSE (ih_item_len (B_N_PITEM_HEAD (tbS0, 0)),
-					"PAP-12106: item length must be 0");
-				RFALSE (comp_short_le_keys (B_N_PKEY (tbS0, 0),
-							    B_N_PKEY (tb->L[0],
-									    n + item_pos - ret_val)),
-					"PAP-12107: items must be of the same file");
-				if (is_indirect_le_ih(B_N_PITEM_HEAD (tb->L[0],
-								      n + item_pos - ret_val)))	{
-				    temp_l = l_n << (tb->tb_sb->s_blocksize_bits - UNFM_P_SHIFT);
-				}
-				/* update key of first item in S0 */
-				version = ih_version (B_N_PITEM_HEAD (tbS0, 0));
-				set_le_key_k_offset (version, B_N_PKEY (tbS0, 0), 
-						     le_key_k_offset (version, B_N_PKEY (tbS0, 0)) + temp_l);
-				/* update left delimiting key */
-				set_le_key_k_offset (version, B_N_PDELIM_KEY(tb->CFL[0],tb->lkey[0]),
-						     le_key_k_offset (version, B_N_PDELIM_KEY(tb->CFL[0],tb->lkey[0])) + temp_l);
-			    }
-
-			    /* Calculate new body, position in item and insert_size[0] */
-			    if ( l_n > zeros_num ) {
-				body += (l_n - zeros_num);
-				zeros_num = 0;
-			    }
-			    else
-				zeros_num -= l_n;
-			    pos_in_item = 0;	
-
-			    RFALSE( comp_short_le_keys 
-				    (B_N_PKEY(tbS0,0),
-				     B_N_PKEY(tb->L[0],B_NR_ITEMS(tb->L[0])-1)) ||
-				
-				    !op_is_left_mergeable 
-				    (B_N_PKEY (tbS0, 0), tbS0->b_size) ||
-				    !op_is_left_mergeable
-				    (B_N_PDELIM_KEY(tb->CFL[0],tb->lkey[0]), 
-				     tbS0->b_size),
-				    "PAP-12120: item must be merge-able with left neighboring item");
-			}
-			else /* only part of the appended item will be in L[0] */
-			{
-			    /* Calculate position in item for append in S[0] */
-			    pos_in_item -= tb->lbytes;
 
-			    RFALSE( pos_in_item <= 0,
-				    "PAP-12125: no place for paste. pos_in_item=%d", pos_in_item);
+			RFALSE(tb->rnum[0] != 0,
+			       "PAP-12045: rnum must be 0 (%d)", tb->rnum[0]);
+			/* all contents of L[0] and S[0] will be in L[0] */
+			leaf_shift_left(tb, n, -1);
 
-			    /* Shift lnum[0] - 1 items in whole. Shift lbytes - 1 byte from item number lnum[0] */
-			    leaf_shift_left(tb,tb->lnum[0],tb->lbytes);
-			}
-		    }
-		}
-		else /* appended item will be in L[0] in whole */
-		{
-		    struct item_head * pasted;
-
-			if ( ! item_pos  && op_is_left_mergeable (B_N_PKEY (tbS0, 0), tbS0->b_size) )
-			{ /* if we paste into first item of S[0] and it is left mergable */
-			    /* then increment pos_in_item by the size of the last item in L[0] */
-			    pasted = B_N_PITEM_HEAD(tb->L[0],n-1);
-			    if ( is_direntry_le_ih (pasted) )
-				pos_in_item += ih_entry_count(pasted);
-			    else
-				pos_in_item += ih_item_len(pasted);
-			}
+			reiserfs_invalidate_buffer(tb, tbS0);
 
-		    /* Shift lnum[0] - 1 items in whole. Shift lbytes - 1 byte from item number lnum[0] */
-		    ret_val = leaf_shift_left(tb,tb->lnum[0],tb->lbytes);
-		    /* Append to body of item in L[0] */
-		    bi.tb = tb;
-		    bi.bi_bh = tb->L[0];
-		    bi.bi_parent = tb->FL[0];
-		    bi.bi_position = get_left_neighbor_position (tb, 0);
-		    leaf_paste_in_buffer (&bi, n + item_pos - ret_val, pos_in_item, tb->insert_size[0],
-					  body, zeros_num);
-
-		    /* if appended item is directory, paste entry */
-		    pasted = B_N_PITEM_HEAD (tb->L[0], n + item_pos - ret_val);
-		    if (is_direntry_le_ih (pasted))
-			leaf_paste_entries (
-			    bi.bi_bh, n + item_pos - ret_val, pos_in_item, 1, 
-			    (struct reiserfs_de_head *)body, body + DEH_SIZE, tb->insert_size[0]
-			    );
-		    /* if appended item is indirect item, put unformatted node into un list */
-		    if (is_indirect_le_ih (pasted))
-			set_ih_free_space (pasted, 0);
-		    tb->insert_size[0] = 0;
-		    zeros_num = 0;
+			return 0;
 		}
-		break;
-	    default:    /* cases d and t */
-		reiserfs_panic (tb->tb_sb, "PAP-12130: balance_leaf: lnum > 0: unexpectable mode: %s(%d)",
-				(flag == M_DELETE) ? "DELETE" : ((flag == M_CUT) ? "CUT" : "UNKNOWN"), flag);
-	    }
-	} else { 
-	    /* new item doesn't fall into L[0] */
-	    leaf_shift_left(tb,tb->lnum[0],tb->lbytes);
+		/* a part of contents of S[0] will be in L[0] and the rest part of S[0] will be in R[0] */
+
+		RFALSE((tb->lnum[0] + tb->rnum[0] < n) ||
+		       (tb->lnum[0] + tb->rnum[0] > n + 1),
+		       "PAP-12050: rnum(%d) and lnum(%d) and item number(%d) in S[0] are not consistent",
+		       tb->rnum[0], tb->lnum[0], n);
+		RFALSE((tb->lnum[0] + tb->rnum[0] == n) &&
+		       (tb->lbytes != -1 || tb->rbytes != -1),
+		       "PAP-12055: bad rbytes (%d)/lbytes (%d) parameters when items are not split",
+		       tb->rbytes, tb->lbytes);
+		RFALSE((tb->lnum[0] + tb->rnum[0] == n + 1) &&
+		       (tb->lbytes < 1 || tb->rbytes != -1),
+		       "PAP-12060: bad rbytes (%d)/lbytes (%d) parameters when items are split",
+		       tb->rbytes, tb->lbytes);
+
+		leaf_shift_left(tb, tb->lnum[0], tb->lbytes);
+		leaf_shift_right(tb, tb->rnum[0], tb->rbytes);
+
+		reiserfs_invalidate_buffer(tb, tbS0);
+
+		return 0;
 	}
-    }	/* tb->lnum[0] > 0 */
 
-    /* Calculate new item position */
-    item_pos -= ( tb->lnum[0] - (( tb->lbytes != -1 ) ? 1 : 0));
+	if (tb->rnum[0] == -1) {
+		/* all contents of R[0] and S[0] will be in R[0] */
+		leaf_shift_right(tb, n, -1);
+		reiserfs_invalidate_buffer(tb, tbS0);
+		return 0;
+	}
 
-    if ( tb->rnum[0] > 0 ) {
-	/* shift rnum[0] items from S[0] to the right neighbor R[0] */
-	n = B_NR_ITEMS(tbS0);
-	switch ( flag ) {
+	RFALSE(tb->rnum[0],
+	       "PAP-12065: bad rnum parameter must be 0 (%d)", tb->rnum[0]);
+	return 0;
+}
 
-	case M_INSERT:   /* insert item */
-	    if ( n - tb->rnum[0] < item_pos )
-	    { /* new item or its part falls to R[0] */
-		if ( item_pos == n - tb->rnum[0] + 1 && tb->rbytes != -1 )
-		{ /* part of new item falls into R[0] */
-		    loff_t old_key_comp, old_len, r_zeros_number;
-		    const char * r_body;
-		    int version;
-		    loff_t offset;
-
-		    leaf_shift_right(tb,tb->rnum[0]-1,-1);
-
-		    version = ih_version(ih);
-		    /* Remember key component and item length */
-                    old_key_comp = le_ih_k_offset( ih );
-		    old_len = ih_item_len(ih);
-
-		    /* Calculate key component and item length to insert into R[0] */
-                    offset = le_ih_k_offset( ih ) + ((old_len - tb->rbytes )<<(is_indirect_le_ih(ih)?tb->tb_sb->s_blocksize_bits - UNFM_P_SHIFT:0));
-                    set_le_ih_k_offset( ih, offset );
-		    put_ih_item_len( ih, tb->rbytes);
-		    /* Insert part of the item into R[0] */
-		    bi.tb = tb;
-		    bi.bi_bh = tb->R[0];
-		    bi.bi_parent = tb->FR[0];
-		    bi.bi_position = get_right_neighbor_position (tb, 0);
-		    if ( (old_len - tb->rbytes) > zeros_num ) {
-			r_zeros_number = 0;
-			r_body = body + (old_len - tb->rbytes) - zeros_num;
-		    }
-		    else {
-			r_body = body;
-			r_zeros_number = zeros_num - (old_len - tb->rbytes);
-			zeros_num -= r_zeros_number;
-		    }
-
-		    leaf_insert_into_buf (&bi, 0, ih, r_body, r_zeros_number);
-
-		    /* Replace right delimiting key by first key in R[0] */
-		    replace_key(tb, tb->CFR[0],tb->rkey[0],tb->R[0],0);
-
-		    /* Calculate key component and item length to insert into S[0] */
-                    set_le_ih_k_offset( ih, old_key_comp );
-		    put_ih_item_len( ih, old_len - tb->rbytes );
+static int balance_leaf(struct tree_balance *tb, struct item_head *ih,	/* item header of inserted item (this is on little endian) */
+			const char *body,	/* body  of inserted item or bytes to paste */
+			int flag,	/* i - insert, d - delete, c - cut, p - paste
+					   (see comment to do_balance) */
+			struct item_head *insert_key,	/* in our processing of one level we sometimes determine what
+							   must be inserted into the next higher level.  This insertion
+							   consists of a key or two keys and their corresponding
+							   pointers */
+			struct buffer_head **insert_ptr	/* inserted node-ptrs for the next level */
+    )
+{
+	struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path);
+	int item_pos = PATH_LAST_POSITION(tb->tb_path);	/*  index into the array of item headers in S[0] 
+							   of the affected item */
+	struct buffer_info bi;
+	struct buffer_head *S_new[2];	/* new nodes allocated to hold what could not fit into S */
+	int snum[2];		/* number of items that will be placed
+				   into S_new (includes partially shifted
+				   items) */
+	int sbytes[2];		/* if an item is partially shifted into S_new then 
+				   if it is a directory item 
+				   it is the number of entries from the item that are shifted into S_new
+				   else
+				   it is the number of bytes from the item that are shifted into S_new
+				 */
+	int n, i;
+	int ret_val;
+	int pos_in_item;
+	int zeros_num;
+
+	PROC_INFO_INC(tb->tb_sb, balance_at[0]);
+
+	/* Make balance in case insert_size[0] < 0 */
+	if (tb->insert_size[0] < 0)
+		return balance_leaf_when_delete(tb, flag);
+
+	zeros_num = 0;
+	if (flag == M_INSERT && body == 0)
+		zeros_num = ih_item_len(ih);
+
+	pos_in_item = tb->tb_path->pos_in_item;
+	/* for indirect item pos_in_item is measured in unformatted node
+	   pointers. Recalculate to bytes */
+	if (flag != M_INSERT
+	    && is_indirect_le_ih(B_N_PITEM_HEAD(tbS0, item_pos)))
+		pos_in_item *= UNFM_P_SIZE;
+
+	if (tb->lnum[0] > 0) {
+		/* Shift lnum[0] items from S[0] to the left neighbor L[0] */
+		if (item_pos < tb->lnum[0]) {
+			/* new item or it part falls to L[0], shift it too */
+			n = B_NR_ITEMS(tb->L[0]);
+
+			switch (flag) {
+			case M_INSERT:	/* insert item into L[0] */
+
+				if (item_pos == tb->lnum[0] - 1
+				    && tb->lbytes != -1) {
+					/* part of new item falls into L[0] */
+					int new_item_len;
+					int version;
+
+					ret_val =
+					    leaf_shift_left(tb, tb->lnum[0] - 1,
+							    -1);
+
+					/* Calculate item length to insert to S[0] */
+					new_item_len =
+					    ih_item_len(ih) - tb->lbytes;
+					/* Calculate and check item length to insert to L[0] */
+					put_ih_item_len(ih,
+							ih_item_len(ih) -
+							new_item_len);
+
+					RFALSE(ih_item_len(ih) <= 0,
+					       "PAP-12080: there is nothing to insert into L[0]: ih_item_len=%d",
+					       ih_item_len(ih));
+
+					/* Insert new item into L[0] */
+					bi.tb = tb;
+					bi.bi_bh = tb->L[0];
+					bi.bi_parent = tb->FL[0];
+					bi.bi_position =
+					    get_left_neighbor_position(tb, 0);
+					leaf_insert_into_buf(&bi,
+							     n + item_pos -
+							     ret_val, ih, body,
+							     zeros_num >
+							     ih_item_len(ih) ?
+							     ih_item_len(ih) :
+							     zeros_num);
+
+					version = ih_version(ih);
+
+					/* Calculate key component, item length and body to insert into S[0] */
+					set_le_ih_k_offset(ih,
+							   le_ih_k_offset(ih) +
+							   (tb->
+							    lbytes <<
+							    (is_indirect_le_ih
+							     (ih) ? tb->tb_sb->
+							     s_blocksize_bits -
+							     UNFM_P_SHIFT :
+							     0)));
+
+					put_ih_item_len(ih, new_item_len);
+					if (tb->lbytes > zeros_num) {
+						body +=
+						    (tb->lbytes - zeros_num);
+						zeros_num = 0;
+					} else
+						zeros_num -= tb->lbytes;
+
+					RFALSE(ih_item_len(ih) <= 0,
+					       "PAP-12085: there is nothing to insert into S[0]: ih_item_len=%d",
+					       ih_item_len(ih));
+				} else {
+					/* new item in whole falls into L[0] */
+					/* Shift lnum[0]-1 items to L[0] */
+					ret_val =
+					    leaf_shift_left(tb, tb->lnum[0] - 1,
+							    tb->lbytes);
+					/* Insert new item into L[0] */
+					bi.tb = tb;
+					bi.bi_bh = tb->L[0];
+					bi.bi_parent = tb->FL[0];
+					bi.bi_position =
+					    get_left_neighbor_position(tb, 0);
+					leaf_insert_into_buf(&bi,
+							     n + item_pos -
+							     ret_val, ih, body,
+							     zeros_num);
+					tb->insert_size[0] = 0;
+					zeros_num = 0;
+				}
+				break;
 
-		    tb->insert_size[0] -= tb->rbytes;
+			case M_PASTE:	/* append item in L[0] */
 
+				if (item_pos == tb->lnum[0] - 1
+				    && tb->lbytes != -1) {
+					/* we must shift the part of the appended item */
+					if (is_direntry_le_ih
+					    (B_N_PITEM_HEAD(tbS0, item_pos))) {
+
+						RFALSE(zeros_num,
+						       "PAP-12090: invalid parameter in case of a directory");
+						/* directory item */
+						if (tb->lbytes > pos_in_item) {
+							/* new directory entry falls into L[0] */
+							struct item_head
+							    *pasted;
+							int l_pos_in_item =
+							    pos_in_item;
+
+							/* Shift lnum[0] - 1 items in whole. Shift lbytes - 1 entries from given directory item */
+							ret_val =
+							    leaf_shift_left(tb,
+									    tb->
+									    lnum
+									    [0],
+									    tb->
+									    lbytes
+									    -
+									    1);
+							if (ret_val
+							    && !item_pos) {
+								pasted =
+								    B_N_PITEM_HEAD
+								    (tb->L[0],
+								     B_NR_ITEMS
+								     (tb->
+								      L[0]) -
+								     1);
+								l_pos_in_item +=
+								    I_ENTRY_COUNT
+								    (pasted) -
+								    (tb->
+								     lbytes -
+								     1);
+							}
+
+							/* Append given directory entry to directory item */
+							bi.tb = tb;
+							bi.bi_bh = tb->L[0];
+							bi.bi_parent =
+							    tb->FL[0];
+							bi.bi_position =
+							    get_left_neighbor_position
+							    (tb, 0);
+							leaf_paste_in_buffer
+							    (&bi,
+							     n + item_pos -
+							     ret_val,
+							     l_pos_in_item,
+							     tb->insert_size[0],
+							     body, zeros_num);
+
+							/* previous string prepared space for pasting new entry, following string pastes this entry */
+
+							/* when we have merge directory item, pos_in_item has been changed too */
+
+							/* paste new directory entry. 1 is entry number */
+							leaf_paste_entries(bi.
+									   bi_bh,
+									   n +
+									   item_pos
+									   -
+									   ret_val,
+									   l_pos_in_item,
+									   1,
+									   (struct
+									    reiserfs_de_head
+									    *)
+									   body,
+									   body
+									   +
+									   DEH_SIZE,
+									   tb->
+									   insert_size
+									   [0]
+							    );
+							tb->insert_size[0] = 0;
+						} else {
+							/* new directory item doesn't fall into L[0] */
+							/* Shift lnum[0]-1 items in whole. Shift lbytes directory entries from directory item number lnum[0] */
+							leaf_shift_left(tb,
+									tb->
+									lnum[0],
+									tb->
+									lbytes);
+						}
+						/* Calculate new position to append in item body */
+						pos_in_item -= tb->lbytes;
+					} else {
+						/* regular object */
+						RFALSE(tb->lbytes <= 0,
+						       "PAP-12095: there is nothing to shift to L[0]. lbytes=%d",
+						       tb->lbytes);
+						RFALSE(pos_in_item !=
+						       ih_item_len
+						       (B_N_PITEM_HEAD
+							(tbS0, item_pos)),
+						       "PAP-12100: incorrect position to paste: item_len=%d, pos_in_item=%d",
+						       ih_item_len
+						       (B_N_PITEM_HEAD
+							(tbS0, item_pos)),
+						       pos_in_item);
+
+						if (tb->lbytes >= pos_in_item) {
+							/* appended item will be in L[0] in whole */
+							int l_n;
+
+							/* this bytes number must be appended to the last item of L[h] */
+							l_n =
+							    tb->lbytes -
+							    pos_in_item;
+
+							/* Calculate new insert_size[0] */
+							tb->insert_size[0] -=
+							    l_n;
+
+							RFALSE(tb->
+							       insert_size[0] <=
+							       0,
+							       "PAP-12105: there is nothing to paste into L[0]. insert_size=%d",
+							       tb->
+							       insert_size[0]);
+							ret_val =
+							    leaf_shift_left(tb,
+									    tb->
+									    lnum
+									    [0],
+									    ih_item_len
+									    (B_N_PITEM_HEAD
+									     (tbS0,
+									      item_pos)));
+							/* Append to body of item in L[0] */
+							bi.tb = tb;
+							bi.bi_bh = tb->L[0];
+							bi.bi_parent =
+							    tb->FL[0];
+							bi.bi_position =
+							    get_left_neighbor_position
+							    (tb, 0);
+							leaf_paste_in_buffer
+							    (&bi,
+							     n + item_pos -
+							     ret_val,
+							     ih_item_len
+							     (B_N_PITEM_HEAD
+							      (tb->L[0],
+							       n + item_pos -
+							       ret_val)), l_n,
+							     body,
+							     zeros_num >
+							     l_n ? l_n :
+							     zeros_num);
+							/* 0-th item in S0 can be only of DIRECT type when l_n != 0 */
+							{
+								int version;
+								int temp_l =
+								    l_n;
+
+								RFALSE
+								    (ih_item_len
+								     (B_N_PITEM_HEAD
+								      (tbS0,
+								       0)),
+								     "PAP-12106: item length must be 0");
+								RFALSE
+								    (comp_short_le_keys
+								     (B_N_PKEY
+								      (tbS0, 0),
+								      B_N_PKEY
+								      (tb->L[0],
+								       n +
+								       item_pos
+								       -
+								       ret_val)),
+								     "PAP-12107: items must be of the same file");
+								if (is_indirect_le_ih(B_N_PITEM_HEAD(tb->L[0], n + item_pos - ret_val))) {
+									temp_l =
+									    l_n
+									    <<
+									    (tb->
+									     tb_sb->
+									     s_blocksize_bits
+									     -
+									     UNFM_P_SHIFT);
+								}
+								/* update key of first item in S0 */
+								version =
+								    ih_version
+								    (B_N_PITEM_HEAD
+								     (tbS0, 0));
+								set_le_key_k_offset
+								    (version,
+								     B_N_PKEY
+								     (tbS0, 0),
+								     le_key_k_offset
+								     (version,
+								      B_N_PKEY
+								      (tbS0,
+								       0)) +
+								     temp_l);
+								/* update left delimiting key */
+								set_le_key_k_offset
+								    (version,
+								     B_N_PDELIM_KEY
+								     (tb->
+								      CFL[0],
+								      tb->
+								      lkey[0]),
+								     le_key_k_offset
+								     (version,
+								      B_N_PDELIM_KEY
+								      (tb->
+								       CFL[0],
+								       tb->
+								       lkey[0]))
+								     + temp_l);
+							}
+
+							/* Calculate new body, position in item and insert_size[0] */
+							if (l_n > zeros_num) {
+								body +=
+								    (l_n -
+								     zeros_num);
+								zeros_num = 0;
+							} else
+								zeros_num -=
+								    l_n;
+							pos_in_item = 0;
+
+							RFALSE
+							    (comp_short_le_keys
+							     (B_N_PKEY(tbS0, 0),
+							      B_N_PKEY(tb->L[0],
+								       B_NR_ITEMS
+								       (tb->
+									L[0]) -
+								       1))
+							     ||
+							     !op_is_left_mergeable
+							     (B_N_PKEY(tbS0, 0),
+							      tbS0->b_size)
+							     ||
+							     !op_is_left_mergeable
+							     (B_N_PDELIM_KEY
+							      (tb->CFL[0],
+							       tb->lkey[0]),
+							      tbS0->b_size),
+							     "PAP-12120: item must be merge-able with left neighboring item");
+						} else {	/* only part of the appended item will be in L[0] */
+
+							/* Calculate position in item for append in S[0] */
+							pos_in_item -=
+							    tb->lbytes;
+
+							RFALSE(pos_in_item <= 0,
+							       "PAP-12125: no place for paste. pos_in_item=%d",
+							       pos_in_item);
+
+							/* Shift lnum[0] - 1 items in whole. Shift lbytes - 1 byte from item number lnum[0] */
+							leaf_shift_left(tb,
+									tb->
+									lnum[0],
+									tb->
+									lbytes);
+						}
+					}
+				} else {	/* appended item will be in L[0] in whole */
+
+					struct item_head *pasted;
+
+					if (!item_pos && op_is_left_mergeable(B_N_PKEY(tbS0, 0), tbS0->b_size)) {	/* if we paste into first item of S[0] and it is left mergable */
+						/* then increment pos_in_item by the size of the last item in L[0] */
+						pasted =
+						    B_N_PITEM_HEAD(tb->L[0],
+								   n - 1);
+						if (is_direntry_le_ih(pasted))
+							pos_in_item +=
+							    ih_entry_count
+							    (pasted);
+						else
+							pos_in_item +=
+							    ih_item_len(pasted);
+					}
+
+					/* Shift lnum[0] - 1 items in whole. Shift lbytes - 1 byte from item number lnum[0] */
+					ret_val =
+					    leaf_shift_left(tb, tb->lnum[0],
+							    tb->lbytes);
+					/* Append to body of item in L[0] */
+					bi.tb = tb;
+					bi.bi_bh = tb->L[0];
+					bi.bi_parent = tb->FL[0];
+					bi.bi_position =
+					    get_left_neighbor_position(tb, 0);
+					leaf_paste_in_buffer(&bi,
+							     n + item_pos -
+							     ret_val,
+							     pos_in_item,
+							     tb->insert_size[0],
+							     body, zeros_num);
+
+					/* if appended item is directory, paste entry */
+					pasted =
+					    B_N_PITEM_HEAD(tb->L[0],
+							   n + item_pos -
+							   ret_val);
+					if (is_direntry_le_ih(pasted))
+						leaf_paste_entries(bi.bi_bh,
+								   n +
+								   item_pos -
+								   ret_val,
+								   pos_in_item,
+								   1,
+								   (struct
+								    reiserfs_de_head
+								    *)body,
+								   body +
+								   DEH_SIZE,
+								   tb->
+								   insert_size
+								   [0]
+						    );
+					/* if appended item is indirect item, put unformatted node into un list */
+					if (is_indirect_le_ih(pasted))
+						set_ih_free_space(pasted, 0);
+					tb->insert_size[0] = 0;
+					zeros_num = 0;
+				}
+				break;
+			default:	/* cases d and t */
+				reiserfs_panic(tb->tb_sb,
+					       "PAP-12130: balance_leaf: lnum > 0: unexpectable mode: %s(%d)",
+					       (flag ==
+						M_DELETE) ? "DELETE" : ((flag ==
+									 M_CUT)
+									? "CUT"
+									:
+									"UNKNOWN"),
+					       flag);
+			}
+		} else {
+			/* new item doesn't fall into L[0] */
+			leaf_shift_left(tb, tb->lnum[0], tb->lbytes);
 		}
-		else /* whole new item falls into R[0] */
-		{					  
-		    /* Shift rnum[0]-1 items to R[0] */
-		    ret_val = leaf_shift_right(tb,tb->rnum[0]-1,tb->rbytes);
-		    /* Insert new item into R[0] */
-		    bi.tb = tb;
-		    bi.bi_bh = tb->R[0];
-		    bi.bi_parent = tb->FR[0];
-		    bi.bi_position = get_right_neighbor_position (tb, 0);
-		    leaf_insert_into_buf (&bi, item_pos - n + tb->rnum[0] - 1, ih, body, zeros_num);
+	}
 
-		    if ( item_pos - n + tb->rnum[0] - 1 == 0 ) {
-			replace_key(tb, tb->CFR[0],tb->rkey[0],tb->R[0],0);
+	/* tb->lnum[0] > 0 */
+	/* Calculate new item position */
+	item_pos -= (tb->lnum[0] - ((tb->lbytes != -1) ? 1 : 0));
+
+	if (tb->rnum[0] > 0) {
+		/* shift rnum[0] items from S[0] to the right neighbor R[0] */
+		n = B_NR_ITEMS(tbS0);
+		switch (flag) {
+
+		case M_INSERT:	/* insert item */
+			if (n - tb->rnum[0] < item_pos) {	/* new item or its part falls to R[0] */
+				if (item_pos == n - tb->rnum[0] + 1 && tb->rbytes != -1) {	/* part of new item falls into R[0] */
+					loff_t old_key_comp, old_len,
+					    r_zeros_number;
+					const char *r_body;
+					int version;
+					loff_t offset;
+
+					leaf_shift_right(tb, tb->rnum[0] - 1,
+							 -1);
+
+					version = ih_version(ih);
+					/* Remember key component and item length */
+					old_key_comp = le_ih_k_offset(ih);
+					old_len = ih_item_len(ih);
+
+					/* Calculate key component and item length to insert into R[0] */
+					offset =
+					    le_ih_k_offset(ih) +
+					    ((old_len -
+					      tb->
+					      rbytes) << (is_indirect_le_ih(ih)
+							  ? tb->tb_sb->
+							  s_blocksize_bits -
+							  UNFM_P_SHIFT : 0));
+					set_le_ih_k_offset(ih, offset);
+					put_ih_item_len(ih, tb->rbytes);
+					/* Insert part of the item into R[0] */
+					bi.tb = tb;
+					bi.bi_bh = tb->R[0];
+					bi.bi_parent = tb->FR[0];
+					bi.bi_position =
+					    get_right_neighbor_position(tb, 0);
+					if ((old_len - tb->rbytes) > zeros_num) {
+						r_zeros_number = 0;
+						r_body =
+						    body + (old_len -
+							    tb->rbytes) -
+						    zeros_num;
+					} else {
+						r_body = body;
+						r_zeros_number =
+						    zeros_num - (old_len -
+								 tb->rbytes);
+						zeros_num -= r_zeros_number;
+					}
+
+					leaf_insert_into_buf(&bi, 0, ih, r_body,
+							     r_zeros_number);
+
+					/* Replace right delimiting key by first key in R[0] */
+					replace_key(tb, tb->CFR[0], tb->rkey[0],
+						    tb->R[0], 0);
+
+					/* Calculate key component and item length to insert into S[0] */
+					set_le_ih_k_offset(ih, old_key_comp);
+					put_ih_item_len(ih,
+							old_len - tb->rbytes);
+
+					tb->insert_size[0] -= tb->rbytes;
+
+				} else {	/* whole new item falls into R[0] */
+
+					/* Shift rnum[0]-1 items to R[0] */
+					ret_val =
+					    leaf_shift_right(tb,
+							     tb->rnum[0] - 1,
+							     tb->rbytes);
+					/* Insert new item into R[0] */
+					bi.tb = tb;
+					bi.bi_bh = tb->R[0];
+					bi.bi_parent = tb->FR[0];
+					bi.bi_position =
+					    get_right_neighbor_position(tb, 0);
+					leaf_insert_into_buf(&bi,
+							     item_pos - n +
+							     tb->rnum[0] - 1,
+							     ih, body,
+							     zeros_num);
+
+					if (item_pos - n + tb->rnum[0] - 1 == 0) {
+						replace_key(tb, tb->CFR[0],
+							    tb->rkey[0],
+							    tb->R[0], 0);
 
-		    }
-		    zeros_num = tb->insert_size[0] = 0;
-		}
-	    }
-	    else /* new item or part of it doesn't fall into R[0] */
-	    {
-		leaf_shift_right(tb,tb->rnum[0],tb->rbytes);
-	    }
-	    break;
-
-	case M_PASTE:   /* append item */
-
-	    if ( n - tb->rnum[0] <= item_pos )  /* pasted item or part of it falls to R[0] */
-	    {
-		if ( item_pos == n - tb->rnum[0] && tb->rbytes != -1 )
-		{ /* we must shift the part of the appended item */
-		    if ( is_direntry_le_ih (B_N_PITEM_HEAD(tbS0, item_pos)))
-		    { /* we append to directory item */
-			int entry_count;
-
-			RFALSE( zeros_num,
-				"PAP-12145: invalid parameter in case of a directory");
-			entry_count = I_ENTRY_COUNT(B_N_PITEM_HEAD(tbS0, item_pos));
-			if ( entry_count - tb->rbytes < pos_in_item )
-			    /* new directory entry falls into R[0] */
-			{
-			    int paste_entry_position;
-
-			    RFALSE( tb->rbytes - 1 >= entry_count || 
-				    ! tb->insert_size[0],
-				    "PAP-12150: no enough of entries to shift to R[0]: rbytes=%d, entry_count=%d",
-				    tb->rbytes, entry_count);
-			    /* Shift rnum[0]-1 items in whole. Shift rbytes-1 directory entries from directory item number rnum[0] */
-			    leaf_shift_right(tb,tb->rnum[0],tb->rbytes - 1);
-			    /* Paste given directory entry to directory item */
-			    paste_entry_position = pos_in_item - entry_count + tb->rbytes - 1;
-			    bi.tb = tb;
-			    bi.bi_bh = tb->R[0];
-			    bi.bi_parent = tb->FR[0];
-			    bi.bi_position = get_right_neighbor_position (tb, 0);
-			    leaf_paste_in_buffer (&bi, 0, paste_entry_position,
-						  tb->insert_size[0],body,zeros_num);
-			    /* paste entry */
-			    leaf_paste_entries (
-				bi.bi_bh, 0, paste_entry_position, 1, (struct reiserfs_de_head *)body, 
-				body + DEH_SIZE, tb->insert_size[0]
-				);								
-						
-			    if ( paste_entry_position == 0 ) {
-				/* change delimiting keys */
-				replace_key(tb, tb->CFR[0],tb->rkey[0],tb->R[0],0);
-			    }
+					}
+					zeros_num = tb->insert_size[0] = 0;
+				}
+			} else {	/* new item or part of it doesn't fall into R[0] */
 
-			    tb->insert_size[0] = 0;
-			    pos_in_item++;
-			}
-			else /* new directory entry doesn't fall into R[0] */
-			{
-			    leaf_shift_right(tb,tb->rnum[0],tb->rbytes);
-			}
-		    }
-		    else /* regular object */
-		    {
-			int n_shift, n_rem, r_zeros_number;
-			const char * r_body;
-
-			/* Calculate number of bytes which must be shifted from appended item */
-			if ( (n_shift = tb->rbytes - tb->insert_size[0]) < 0 )
-			    n_shift = 0;
-
-			RFALSE(pos_in_item != ih_item_len(B_N_PITEM_HEAD (tbS0, item_pos)),
-			       "PAP-12155: invalid position to paste. ih_item_len=%d, pos_in_item=%d",
-                               pos_in_item, ih_item_len( B_N_PITEM_HEAD(tbS0,item_pos)));
-
-			leaf_shift_right(tb,tb->rnum[0],n_shift);
-			/* Calculate number of bytes which must remain in body after appending to R[0] */
-			if ( (n_rem = tb->insert_size[0] - tb->rbytes) < 0 )
-			    n_rem = 0;
-			
-			{
-			  int version;
-			  unsigned long temp_rem = n_rem;
-			  
-			  version = ih_version (B_N_PITEM_HEAD (tb->R[0],0));
-			  if (is_indirect_le_key(version,B_N_PKEY(tb->R[0],0))){
-			      temp_rem = n_rem << (tb->tb_sb->s_blocksize_bits -
-					 UNFM_P_SHIFT);
-			  }
-			  set_le_key_k_offset (version, B_N_PKEY(tb->R[0],0), 
-					       le_key_k_offset (version, B_N_PKEY(tb->R[0],0)) + temp_rem);
-			  set_le_key_k_offset (version, B_N_PDELIM_KEY(tb->CFR[0],tb->rkey[0]), 
-					       le_key_k_offset (version, B_N_PDELIM_KEY(tb->CFR[0],tb->rkey[0])) + temp_rem);
+				leaf_shift_right(tb, tb->rnum[0], tb->rbytes);
 			}
-/*		  k_offset (B_N_PKEY(tb->R[0],0)) += n_rem;
-		  k_offset (B_N_PDELIM_KEY(tb->CFR[0],tb->rkey[0])) += n_rem;*/
-			do_balance_mark_internal_dirty (tb, tb->CFR[0], 0);
+			break;
 
-			/* Append part of body into R[0] */
-			bi.tb = tb;
-			bi.bi_bh = tb->R[0];
-			bi.bi_parent = tb->FR[0];
-			bi.bi_position = get_right_neighbor_position (tb, 0);
-			if ( n_rem > zeros_num ) {
-			    r_zeros_number = 0;
-			    r_body = body + n_rem - zeros_num;
-			}
-			else {
-			    r_body = body;
-			    r_zeros_number = zeros_num - n_rem;
-			    zeros_num -= r_zeros_number;
-			}
+		case M_PASTE:	/* append item */
 
-			leaf_paste_in_buffer(&bi, 0, n_shift, tb->insert_size[0] - n_rem, r_body, r_zeros_number);
+			if (n - tb->rnum[0] <= item_pos) {	/* pasted item or part of it falls to R[0] */
+				if (item_pos == n - tb->rnum[0] && tb->rbytes != -1) {	/* we must shift the part of the appended item */
+					if (is_direntry_le_ih(B_N_PITEM_HEAD(tbS0, item_pos))) {	/* we append to directory item */
+						int entry_count;
+
+						RFALSE(zeros_num,
+						       "PAP-12145: invalid parameter in case of a directory");
+						entry_count =
+						    I_ENTRY_COUNT(B_N_PITEM_HEAD
+								  (tbS0,
+								   item_pos));
+						if (entry_count - tb->rbytes <
+						    pos_in_item)
+							/* new directory entry falls into R[0] */
+						{
+							int paste_entry_position;
+
+							RFALSE(tb->rbytes - 1 >=
+							       entry_count
+							       || !tb->
+							       insert_size[0],
+							       "PAP-12150: no enough of entries to shift to R[0]: rbytes=%d, entry_count=%d",
+							       tb->rbytes,
+							       entry_count);
+							/* Shift rnum[0]-1 items in whole. Shift rbytes-1 directory entries from directory item number rnum[0] */
+							leaf_shift_right(tb,
+									 tb->
+									 rnum
+									 [0],
+									 tb->
+									 rbytes
+									 - 1);
+							/* Paste given directory entry to directory item */
+							paste_entry_position =
+							    pos_in_item -
+							    entry_count +
+							    tb->rbytes - 1;
+							bi.tb = tb;
+							bi.bi_bh = tb->R[0];
+							bi.bi_parent =
+							    tb->FR[0];
+							bi.bi_position =
+							    get_right_neighbor_position
+							    (tb, 0);
+							leaf_paste_in_buffer
+							    (&bi, 0,
+							     paste_entry_position,
+							     tb->insert_size[0],
+							     body, zeros_num);
+							/* paste entry */
+							leaf_paste_entries(bi.
+									   bi_bh,
+									   0,
+									   paste_entry_position,
+									   1,
+									   (struct
+									    reiserfs_de_head
+									    *)
+									   body,
+									   body
+									   +
+									   DEH_SIZE,
+									   tb->
+									   insert_size
+									   [0]
+							    );
+
+							if (paste_entry_position
+							    == 0) {
+								/* change delimiting keys */
+								replace_key(tb,
+									    tb->
+									    CFR
+									    [0],
+									    tb->
+									    rkey
+									    [0],
+									    tb->
+									    R
+									    [0],
+									    0);
+							}
+
+							tb->insert_size[0] = 0;
+							pos_in_item++;
+						} else {	/* new directory entry doesn't fall into R[0] */
+
+							leaf_shift_right(tb,
+									 tb->
+									 rnum
+									 [0],
+									 tb->
+									 rbytes);
+						}
+					} else {	/* regular object */
+
+						int n_shift, n_rem,
+						    r_zeros_number;
+						const char *r_body;
+
+						/* Calculate number of bytes which must be shifted from appended item */
+						if ((n_shift =
+						     tb->rbytes -
+						     tb->insert_size[0]) < 0)
+							n_shift = 0;
+
+						RFALSE(pos_in_item !=
+						       ih_item_len
+						       (B_N_PITEM_HEAD
+							(tbS0, item_pos)),
+						       "PAP-12155: invalid position to paste. ih_item_len=%d, pos_in_item=%d",
+						       pos_in_item,
+						       ih_item_len
+						       (B_N_PITEM_HEAD
+							(tbS0, item_pos)));
+
+						leaf_shift_right(tb,
+								 tb->rnum[0],
+								 n_shift);
+						/* Calculate number of bytes which must remain in body after appending to R[0] */
+						if ((n_rem =
+						     tb->insert_size[0] -
+						     tb->rbytes) < 0)
+							n_rem = 0;
+
+						{
+							int version;
+							unsigned long temp_rem =
+							    n_rem;
+
+							version =
+							    ih_version
+							    (B_N_PITEM_HEAD
+							     (tb->R[0], 0));
+							if (is_indirect_le_key
+							    (version,
+							     B_N_PKEY(tb->R[0],
+								      0))) {
+								temp_rem =
+								    n_rem <<
+								    (tb->tb_sb->
+								     s_blocksize_bits
+								     -
+								     UNFM_P_SHIFT);
+							}
+							set_le_key_k_offset
+							    (version,
+							     B_N_PKEY(tb->R[0],
+								      0),
+							     le_key_k_offset
+							     (version,
+							      B_N_PKEY(tb->R[0],
+								       0)) +
+							     temp_rem);
+							set_le_key_k_offset
+							    (version,
+							     B_N_PDELIM_KEY(tb->
+									    CFR
+									    [0],
+									    tb->
+									    rkey
+									    [0]),
+							     le_key_k_offset
+							     (version,
+							      B_N_PDELIM_KEY
+							      (tb->CFR[0],
+							       tb->rkey[0])) +
+							     temp_rem);
+						}
+/*		  k_offset (B_N_PKEY(tb->R[0],0)) += n_rem;
+		  k_offset (B_N_PDELIM_KEY(tb->CFR[0],tb->rkey[0])) += n_rem;*/
+						do_balance_mark_internal_dirty
+						    (tb, tb->CFR[0], 0);
 
-			if (is_indirect_le_ih (B_N_PITEM_HEAD(tb->R[0],0))) {
+						/* Append part of body into R[0] */
+						bi.tb = tb;
+						bi.bi_bh = tb->R[0];
+						bi.bi_parent = tb->FR[0];
+						bi.bi_position =
+						    get_right_neighbor_position
+						    (tb, 0);
+						if (n_rem > zeros_num) {
+							r_zeros_number = 0;
+							r_body =
+							    body + n_rem -
+							    zeros_num;
+						} else {
+							r_body = body;
+							r_zeros_number =
+							    zeros_num - n_rem;
+							zeros_num -=
+							    r_zeros_number;
+						}
+
+						leaf_paste_in_buffer(&bi, 0,
+								     n_shift,
+								     tb->
+								     insert_size
+								     [0] -
+								     n_rem,
+								     r_body,
+								     r_zeros_number);
+
+						if (is_indirect_le_ih
+						    (B_N_PITEM_HEAD
+						     (tb->R[0], 0))) {
 #if 0
-			    RFALSE( n_rem,
-				    "PAP-12160: paste more than one unformatted node pointer");
+							RFALSE(n_rem,
+							       "PAP-12160: paste more than one unformatted node pointer");
 #endif
-			    set_ih_free_space (B_N_PITEM_HEAD(tb->R[0],0), 0);
-			}
-			tb->insert_size[0] = n_rem;
-			if ( ! n_rem )
-			    pos_in_item ++;
-		    }
-		}
-		else /* pasted item in whole falls into R[0] */
-		{
-		    struct item_head * pasted;
-
-		    ret_val = leaf_shift_right(tb,tb->rnum[0],tb->rbytes);
-		    /* append item in R[0] */
-		    if ( pos_in_item >= 0 ) {
-			bi.tb = tb;
-			bi.bi_bh = tb->R[0];
-			bi.bi_parent = tb->FR[0];
-			bi.bi_position = get_right_neighbor_position (tb, 0);
-			leaf_paste_in_buffer(&bi,item_pos - n + tb->rnum[0], pos_in_item,
-					     tb->insert_size[0],body, zeros_num);
-		    }
-
-		    /* paste new entry, if item is directory item */
-		    pasted = B_N_PITEM_HEAD(tb->R[0], item_pos - n + tb->rnum[0]);
-		    if (is_direntry_le_ih (pasted) && pos_in_item >= 0 ) {
-			leaf_paste_entries (
-			    bi.bi_bh, item_pos - n + tb->rnum[0], pos_in_item, 1, 
-			    (struct reiserfs_de_head *)body, body + DEH_SIZE, tb->insert_size[0]
-			    );
-			if ( ! pos_in_item ) {
-
-			    RFALSE( item_pos - n + tb->rnum[0],
-				    "PAP-12165: directory item must be first item of node when pasting is in 0th position");
+							set_ih_free_space
+							    (B_N_PITEM_HEAD
+							     (tb->R[0], 0), 0);
+						}
+						tb->insert_size[0] = n_rem;
+						if (!n_rem)
+							pos_in_item++;
+					}
+				} else {	/* pasted item in whole falls into R[0] */
+
+					struct item_head *pasted;
+
+					ret_val =
+					    leaf_shift_right(tb, tb->rnum[0],
+							     tb->rbytes);
+					/* append item in R[0] */
+					if (pos_in_item >= 0) {
+						bi.tb = tb;
+						bi.bi_bh = tb->R[0];
+						bi.bi_parent = tb->FR[0];
+						bi.bi_position =
+						    get_right_neighbor_position
+						    (tb, 0);
+						leaf_paste_in_buffer(&bi,
+								     item_pos -
+								     n +
+								     tb->
+								     rnum[0],
+								     pos_in_item,
+								     tb->
+								     insert_size
+								     [0], body,
+								     zeros_num);
+					}
+
+					/* paste new entry, if item is directory item */
+					pasted =
+					    B_N_PITEM_HEAD(tb->R[0],
+							   item_pos - n +
+							   tb->rnum[0]);
+					if (is_direntry_le_ih(pasted)
+					    && pos_in_item >= 0) {
+						leaf_paste_entries(bi.bi_bh,
+								   item_pos -
+								   n +
+								   tb->rnum[0],
+								   pos_in_item,
+								   1,
+								   (struct
+								    reiserfs_de_head
+								    *)body,
+								   body +
+								   DEH_SIZE,
+								   tb->
+								   insert_size
+								   [0]
+						    );
+						if (!pos_in_item) {
+
+							RFALSE(item_pos - n +
+							       tb->rnum[0],
+							       "PAP-12165: directory item must be first item of node when pasting is in 0th position");
+
+							/* update delimiting keys */
+							replace_key(tb,
+								    tb->CFR[0],
+								    tb->rkey[0],
+								    tb->R[0],
+								    0);
+						}
+					}
+
+					if (is_indirect_le_ih(pasted))
+						set_ih_free_space(pasted, 0);
+					zeros_num = tb->insert_size[0] = 0;
+				}
+			} else {	/* new item doesn't fall into R[0] */
 
-			    /* update delimiting keys */
-			    replace_key(tb, tb->CFR[0],tb->rkey[0],tb->R[0],0);
+				leaf_shift_right(tb, tb->rnum[0], tb->rbytes);
 			}
-		    }
-
-		    if (is_indirect_le_ih (pasted))
-			set_ih_free_space (pasted, 0);
-		    zeros_num = tb->insert_size[0] = 0;
+			break;
+		default:	/* cases d and t */
+			reiserfs_panic(tb->tb_sb,
+				       "PAP-12175: balance_leaf: rnum > 0: unexpectable mode: %s(%d)",
+				       (flag ==
+					M_DELETE) ? "DELETE" : ((flag ==
+								 M_CUT) ? "CUT"
+								: "UNKNOWN"),
+				       flag);
 		}
-	    }
-	    else /* new item doesn't fall into R[0] */
-	    {
-		leaf_shift_right(tb,tb->rnum[0],tb->rbytes);
-	    }
-	    break;
-	default:    /* cases d and t */
-	    reiserfs_panic (tb->tb_sb, "PAP-12175: balance_leaf: rnum > 0: unexpectable mode: %s(%d)",
-			    (flag == M_DELETE) ? "DELETE" : ((flag == M_CUT) ? "CUT" : "UNKNOWN"), flag);
-	}
-    
-    }	/* tb->rnum[0] > 0 */
-
-
-    RFALSE( tb->blknum[0] > 3,
-	    "PAP-12180: blknum can not be %d. It must be <= 3",  tb->blknum[0]);
-    RFALSE( tb->blknum[0] < 0,
-	    "PAP-12185: blknum can not be %d. It must be >= 0",  tb->blknum[0]);
-
-    /* if while adding to a node we discover that it is possible to split
-       it in two, and merge the left part into the left neighbor and the
-       right part into the right neighbor, eliminating the node */
-    if ( tb->blknum[0] == 0 ) { /* node S[0] is empty now */
-
-	RFALSE( ! tb->lnum[0] || ! tb->rnum[0],
-	        "PAP-12190: lnum and rnum must not be zero");
-	/* if insertion was done before 0-th position in R[0], right
-	   delimiting key of the tb->L[0]'s and left delimiting key are
-	   not set correctly */
-	if (tb->CFL[0]) {
-	    if (!tb->CFR[0])
-		reiserfs_panic (tb->tb_sb, "vs-12195: balance_leaf: CFR not initialized");
-	    copy_key (B_N_PDELIM_KEY (tb->CFL[0], tb->lkey[0]), B_N_PDELIM_KEY (tb->CFR[0], tb->rkey[0]));
-	    do_balance_mark_internal_dirty (tb, tb->CFL[0], 0);
-	}
-
-	reiserfs_invalidate_buffer(tb,tbS0);									
-	return 0;
-    }
 
+	}
 
-    /* Fill new nodes that appear in place of S[0] */
+	/* tb->rnum[0] > 0 */
+	RFALSE(tb->blknum[0] > 3,
+	       "PAP-12180: blknum can not be %d. It must be <= 3",
+	       tb->blknum[0]);
+	RFALSE(tb->blknum[0] < 0,
+	       "PAP-12185: blknum can not be %d. It must be >= 0",
+	       tb->blknum[0]);
+
+	/* if while adding to a node we discover that it is possible to split
+	   it in two, and merge the left part into the left neighbor and the
+	   right part into the right neighbor, eliminating the node */
+	if (tb->blknum[0] == 0) {	/* node S[0] is empty now */
+
+		RFALSE(!tb->lnum[0] || !tb->rnum[0],
+		       "PAP-12190: lnum and rnum must not be zero");
+		/* if insertion was done before 0-th position in R[0], right
+		   delimiting key of the tb->L[0]'s and left delimiting key are
+		   not set correctly */
+		if (tb->CFL[0]) {
+			if (!tb->CFR[0])
+				reiserfs_panic(tb->tb_sb,
+					       "vs-12195: balance_leaf: CFR not initialized");
+			copy_key(B_N_PDELIM_KEY(tb->CFL[0], tb->lkey[0]),
+				 B_N_PDELIM_KEY(tb->CFR[0], tb->rkey[0]));
+			do_balance_mark_internal_dirty(tb, tb->CFL[0], 0);
+		}
 
-    /* I am told that this copying is because we need an array to enable
-       the looping code. -Hans */
-    snum[0] = tb->s1num,
-	snum[1] = tb->s2num;
-    sbytes[0] = tb->s1bytes;
-    sbytes[1] = tb->s2bytes;
-    for( i = tb->blknum[0] - 2; i >= 0; i-- ) {
+		reiserfs_invalidate_buffer(tb, tbS0);
+		return 0;
+	}
 
-	RFALSE( !snum[i], "PAP-12200: snum[%d] == %d. Must be > 0", i, snum[i]);
+	/* Fill new nodes that appear in place of S[0] */
 
-	/* here we shift from S to S_new nodes */
+	/* I am told that this copying is because we need an array to enable
+	   the looping code. -Hans */
+	snum[0] = tb->s1num, snum[1] = tb->s2num;
+	sbytes[0] = tb->s1bytes;
+	sbytes[1] = tb->s2bytes;
+	for (i = tb->blknum[0] - 2; i >= 0; i--) {
+
+		RFALSE(!snum[i], "PAP-12200: snum[%d] == %d. Must be > 0", i,
+		       snum[i]);
+
+		/* here we shift from S to S_new nodes */
+
+		S_new[i] = get_FEB(tb);
+
+		/* initialized block type and tree level */
+		set_blkh_level(B_BLK_HEAD(S_new[i]), DISK_LEAF_NODE_LEVEL);
+
+		n = B_NR_ITEMS(tbS0);
+
+		switch (flag) {
+		case M_INSERT:	/* insert item */
+
+			if (n - snum[i] < item_pos) {	/* new item or it's part falls to first new node S_new[i] */
+				if (item_pos == n - snum[i] + 1 && sbytes[i] != -1) {	/* part of new item falls into S_new[i] */
+					int old_key_comp, old_len,
+					    r_zeros_number;
+					const char *r_body;
+					int version;
+
+					/* Move snum[i]-1 items from S[0] to S_new[i] */
+					leaf_move_items(LEAF_FROM_S_TO_SNEW, tb,
+							snum[i] - 1, -1,
+							S_new[i]);
+					/* Remember key component and item length */
+					version = ih_version(ih);
+					old_key_comp = le_ih_k_offset(ih);
+					old_len = ih_item_len(ih);
+
+					/* Calculate key component and item length to insert into S_new[i] */
+					set_le_ih_k_offset(ih,
+							   le_ih_k_offset(ih) +
+							   ((old_len -
+							     sbytes[i]) <<
+							    (is_indirect_le_ih
+							     (ih) ? tb->tb_sb->
+							     s_blocksize_bits -
+							     UNFM_P_SHIFT :
+							     0)));
+
+					put_ih_item_len(ih, sbytes[i]);
+
+					/* Insert part of the item into S_new[i] before 0-th item */
+					bi.tb = tb;
+					bi.bi_bh = S_new[i];
+					bi.bi_parent = NULL;
+					bi.bi_position = 0;
+
+					if ((old_len - sbytes[i]) > zeros_num) {
+						r_zeros_number = 0;
+						r_body =
+						    body + (old_len -
+							    sbytes[i]) -
+						    zeros_num;
+					} else {
+						r_body = body;
+						r_zeros_number =
+						    zeros_num - (old_len -
+								 sbytes[i]);
+						zeros_num -= r_zeros_number;
+					}
+
+					leaf_insert_into_buf(&bi, 0, ih, r_body,
+							     r_zeros_number);
+
+					/* Calculate key component and item length to insert into S[i] */
+					set_le_ih_k_offset(ih, old_key_comp);
+					put_ih_item_len(ih,
+							old_len - sbytes[i]);
+					tb->insert_size[0] -= sbytes[i];
+				} else {	/* whole new item falls into S_new[i] */
+
+					/* Shift snum[0] - 1 items to S_new[i] (sbytes[i] of split item) */
+					leaf_move_items(LEAF_FROM_S_TO_SNEW, tb,
+							snum[i] - 1, sbytes[i],
+							S_new[i]);
+
+					/* Insert new item into S_new[i] */
+					bi.tb = tb;
+					bi.bi_bh = S_new[i];
+					bi.bi_parent = NULL;
+					bi.bi_position = 0;
+					leaf_insert_into_buf(&bi,
+							     item_pos - n +
+							     snum[i] - 1, ih,
+							     body, zeros_num);
 
-	S_new[i] = get_FEB(tb);
+					zeros_num = tb->insert_size[0] = 0;
+				}
+			}
 
-	/* initialized block type and tree level */
-        set_blkh_level( B_BLK_HEAD(S_new[i]), DISK_LEAF_NODE_LEVEL );
+			else {	/* new item or it part don't falls into S_new[i] */
 
+				leaf_move_items(LEAF_FROM_S_TO_SNEW, tb,
+						snum[i], sbytes[i], S_new[i]);
+			}
+			break;
 
-	n = B_NR_ITEMS(tbS0);
-	
-	switch (flag) {
-	case M_INSERT:   /* insert item */
+		case M_PASTE:	/* append item */
 
-	    if ( n - snum[i] < item_pos )
-	    { /* new item or it's part falls to first new node S_new[i]*/
-		if ( item_pos == n - snum[i] + 1 && sbytes[i] != -1 )
-		{ /* part of new item falls into S_new[i] */
-		    int old_key_comp, old_len, r_zeros_number;
-		    const char * r_body;
-		    int version;
-
-		    /* Move snum[i]-1 items from S[0] to S_new[i] */
-		    leaf_move_items (LEAF_FROM_S_TO_SNEW, tb, snum[i] - 1, -1, S_new[i]);
-		    /* Remember key component and item length */
-		    version = ih_version (ih);
-                    old_key_comp = le_ih_k_offset( ih );
-		    old_len = ih_item_len(ih);
-
-		    /* Calculate key component and item length to insert into S_new[i] */
-                    set_le_ih_k_offset( ih,
-                                le_ih_k_offset(ih) + ((old_len - sbytes[i] )<<(is_indirect_le_ih(ih)?tb->tb_sb->s_blocksize_bits - UNFM_P_SHIFT:0)) );
-
-		    put_ih_item_len( ih, sbytes[i] );
-
-		    /* Insert part of the item into S_new[i] before 0-th item */
-		    bi.tb = tb;
-		    bi.bi_bh = S_new[i];
-		    bi.bi_parent = NULL;
-		    bi.bi_position = 0;
-
-		    if ( (old_len - sbytes[i]) > zeros_num ) {
-			r_zeros_number = 0;
-			r_body = body + (old_len - sbytes[i]) - zeros_num;
-		    }
-		    else {
-			r_body = body;
-			r_zeros_number = zeros_num - (old_len - sbytes[i]);
-			zeros_num -= r_zeros_number;
-		    }
-
-		    leaf_insert_into_buf (&bi, 0, ih, r_body, r_zeros_number);
-
-		    /* Calculate key component and item length to insert into S[i] */
-                    set_le_ih_k_offset( ih, old_key_comp );
-		    put_ih_item_len( ih, old_len - sbytes[i] );
-		    tb->insert_size[0] -= sbytes[i];
-		}
-		else /* whole new item falls into S_new[i] */
-		{
-		    /* Shift snum[0] - 1 items to S_new[i] (sbytes[i] of split item) */
-		    leaf_move_items (LEAF_FROM_S_TO_SNEW, tb, snum[i] - 1, sbytes[i], S_new[i]);
-
-		    /* Insert new item into S_new[i] */
-		    bi.tb = tb;
-		    bi.bi_bh = S_new[i];
-		    bi.bi_parent = NULL;
-		    bi.bi_position = 0;
-		    leaf_insert_into_buf (&bi, item_pos - n + snum[i] - 1, ih, body, zeros_num);
+			if (n - snum[i] <= item_pos) {	/* pasted item or part if it falls to S_new[i] */
+				if (item_pos == n - snum[i] && sbytes[i] != -1) {	/* we must shift part of the appended item */
+					struct item_head *aux_ih;
+
+					RFALSE(ih, "PAP-12210: ih must be 0");
+
+					if (is_direntry_le_ih
+					    (aux_ih =
+					     B_N_PITEM_HEAD(tbS0, item_pos))) {
+						/* we append to directory item */
+
+						int entry_count;
+
+						entry_count =
+						    ih_entry_count(aux_ih);
+
+						if (entry_count - sbytes[i] <
+						    pos_in_item
+						    && pos_in_item <=
+						    entry_count) {
+							/* new directory entry falls into S_new[i] */
+
+							RFALSE(!tb->
+							       insert_size[0],
+							       "PAP-12215: insert_size is already 0");
+							RFALSE(sbytes[i] - 1 >=
+							       entry_count,
+							       "PAP-12220: there are no so much entries (%d), only %d",
+							       sbytes[i] - 1,
+							       entry_count);
+
+							/* Shift snum[i]-1 items in whole. Shift sbytes[i] directory entries from directory item number snum[i] */
+							leaf_move_items
+							    (LEAF_FROM_S_TO_SNEW,
+							     tb, snum[i],
+							     sbytes[i] - 1,
+							     S_new[i]);
+							/* Paste given directory entry to directory item */
+							bi.tb = tb;
+							bi.bi_bh = S_new[i];
+							bi.bi_parent = NULL;
+							bi.bi_position = 0;
+							leaf_paste_in_buffer
+							    (&bi, 0,
+							     pos_in_item -
+							     entry_count +
+							     sbytes[i] - 1,
+							     tb->insert_size[0],
+							     body, zeros_num);
+							/* paste new directory entry */
+							leaf_paste_entries(bi.
+									   bi_bh,
+									   0,
+									   pos_in_item
+									   -
+									   entry_count
+									   +
+									   sbytes
+									   [i] -
+									   1, 1,
+									   (struct
+									    reiserfs_de_head
+									    *)
+									   body,
+									   body
+									   +
+									   DEH_SIZE,
+									   tb->
+									   insert_size
+									   [0]
+							    );
+							tb->insert_size[0] = 0;
+							pos_in_item++;
+						} else {	/* new directory entry doesn't fall into S_new[i] */
+							leaf_move_items
+							    (LEAF_FROM_S_TO_SNEW,
+							     tb, snum[i],
+							     sbytes[i],
+							     S_new[i]);
+						}
+					} else {	/* regular object */
+
+						int n_shift, n_rem,
+						    r_zeros_number;
+						const char *r_body;
+
+						RFALSE(pos_in_item !=
+						       ih_item_len
+						       (B_N_PITEM_HEAD
+							(tbS0, item_pos))
+						       || tb->insert_size[0] <=
+						       0,
+						       "PAP-12225: item too short or insert_size <= 0");
+
+						/* Calculate number of bytes which must be shifted from appended item */
+						n_shift =
+						    sbytes[i] -
+						    tb->insert_size[0];
+						if (n_shift < 0)
+							n_shift = 0;
+						leaf_move_items
+						    (LEAF_FROM_S_TO_SNEW, tb,
+						     snum[i], n_shift,
+						     S_new[i]);
+
+						/* Calculate number of bytes which must remain in body after append to S_new[i] */
+						n_rem =
+						    tb->insert_size[0] -
+						    sbytes[i];
+						if (n_rem < 0)
+							n_rem = 0;
+						/* Append part of body into S_new[0] */
+						bi.tb = tb;
+						bi.bi_bh = S_new[i];
+						bi.bi_parent = NULL;
+						bi.bi_position = 0;
+
+						if (n_rem > zeros_num) {
+							r_zeros_number = 0;
+							r_body =
+							    body + n_rem -
+							    zeros_num;
+						} else {
+							r_body = body;
+							r_zeros_number =
+							    zeros_num - n_rem;
+							zeros_num -=
+							    r_zeros_number;
+						}
+
+						leaf_paste_in_buffer(&bi, 0,
+								     n_shift,
+								     tb->
+								     insert_size
+								     [0] -
+								     n_rem,
+								     r_body,
+								     r_zeros_number);
+						{
+							struct item_head *tmp;
+
+							tmp =
+							    B_N_PITEM_HEAD(S_new
+									   [i],
+									   0);
+							if (is_indirect_le_ih
+							    (tmp)) {
+								set_ih_free_space
+								    (tmp, 0);
+								set_le_ih_k_offset
+								    (tmp,
+								     le_ih_k_offset
+								     (tmp) +
+								     (n_rem <<
+								      (tb->
+								       tb_sb->
+								       s_blocksize_bits
+								       -
+								       UNFM_P_SHIFT)));
+							} else {
+								set_le_ih_k_offset
+								    (tmp,
+								     le_ih_k_offset
+								     (tmp) +
+								     n_rem);
+							}
+						}
+
+						tb->insert_size[0] = n_rem;
+						if (!n_rem)
+							pos_in_item++;
+					}
+				} else
+					/* item falls wholly into S_new[i] */
+				{
+					int ret_val;
+					struct item_head *pasted;
 
-		    zeros_num = tb->insert_size[0] = 0;
-		}
-	    }
+#ifdef CONFIG_REISERFS_CHECK
+					struct item_head *ih =
+					    B_N_PITEM_HEAD(tbS0, item_pos);
 
-	    else /* new item or it part don't falls into S_new[i] */
-	    {
-		leaf_move_items (LEAF_FROM_S_TO_SNEW, tb, snum[i], sbytes[i], S_new[i]);
-	    }
-	    break;
-
-	case M_PASTE:   /* append item */
-
-	    if ( n - snum[i] <= item_pos )  /* pasted item or part if it falls to S_new[i] */
-	    {
-		if ( item_pos == n - snum[i] && sbytes[i] != -1 )
-		{ /* we must shift part of the appended item */
-		    struct item_head * aux_ih;
-
-		    RFALSE( ih, "PAP-12210: ih must be 0");
-
-		    if ( is_direntry_le_ih (aux_ih = B_N_PITEM_HEAD(tbS0,item_pos))) {
-			/* we append to directory item */
-
-			int entry_count;
-		
-			entry_count = ih_entry_count(aux_ih);
-
-			if ( entry_count - sbytes[i] < pos_in_item  && pos_in_item <= entry_count ) {
-			    /* new directory entry falls into S_new[i] */
-		  
-			    RFALSE( ! tb->insert_size[0],
-				    "PAP-12215: insert_size is already 0");
-			    RFALSE( sbytes[i] - 1 >= entry_count,
-				    "PAP-12220: there are no so much entries (%d), only %d",
-				    sbytes[i] - 1, entry_count);
-
-			    /* Shift snum[i]-1 items in whole. Shift sbytes[i] directory entries from directory item number snum[i] */
-			    leaf_move_items (LEAF_FROM_S_TO_SNEW, tb, snum[i], sbytes[i]-1, S_new[i]);
-			    /* Paste given directory entry to directory item */
-			    bi.tb = tb;
-			    bi.bi_bh = S_new[i];
-			    bi.bi_parent = NULL;
-			    bi.bi_position = 0;
-			    leaf_paste_in_buffer (&bi, 0, pos_in_item - entry_count + sbytes[i] - 1,
-						  tb->insert_size[0], body,zeros_num);
-			    /* paste new directory entry */
-			    leaf_paste_entries (
-				bi.bi_bh, 0, pos_in_item - entry_count + sbytes[i] - 1,
-				1, (struct reiserfs_de_head *)body, body + DEH_SIZE,
-				tb->insert_size[0]
-				);
-			    tb->insert_size[0] = 0;
-			    pos_in_item++;
-			} else { /* new directory entry doesn't fall into S_new[i] */
-			    leaf_move_items (LEAF_FROM_S_TO_SNEW, tb, snum[i], sbytes[i], S_new[i]);
-			}
-		    }
-		    else /* regular object */
-		    {
-			int n_shift, n_rem, r_zeros_number;
-			const char * r_body;
-
-			RFALSE( pos_in_item != ih_item_len(B_N_PITEM_HEAD(tbS0,item_pos)) ||
-			        tb->insert_size[0] <= 0,
-			        "PAP-12225: item too short or insert_size <= 0");
-
-			/* Calculate number of bytes which must be shifted from appended item */
-			n_shift = sbytes[i] - tb->insert_size[0];
-			if ( n_shift < 0 )
-			    n_shift = 0;
-			leaf_move_items (LEAF_FROM_S_TO_SNEW, tb, snum[i], n_shift, S_new[i]);
-
-			/* Calculate number of bytes which must remain in body after append to S_new[i] */
-			n_rem = tb->insert_size[0] - sbytes[i];
-			if ( n_rem < 0 )
-			    n_rem = 0;
-			/* Append part of body into S_new[0] */
-			bi.tb = tb;
-			bi.bi_bh = S_new[i];
-			bi.bi_parent = NULL;
-			bi.bi_position = 0;
-
-			if ( n_rem > zeros_num ) {
-			    r_zeros_number = 0;
-			    r_body = body + n_rem - zeros_num;
-			}
-			else {
-			    r_body = body;
-			    r_zeros_number = zeros_num - n_rem;
-			    zeros_num -= r_zeros_number;
+					if (!is_direntry_le_ih(ih)
+					    && (pos_in_item != ih_item_len(ih)
+						|| tb->insert_size[0] <= 0))
+						reiserfs_panic(tb->tb_sb,
+							       "PAP-12235: balance_leaf: pos_in_item must be equal to ih_item_len");
+#endif				/* CONFIG_REISERFS_CHECK */
+
+					ret_val =
+					    leaf_move_items(LEAF_FROM_S_TO_SNEW,
+							    tb, snum[i],
+							    sbytes[i],
+							    S_new[i]);
+
+					RFALSE(ret_val,
+					       "PAP-12240: unexpected value returned by leaf_move_items (%d)",
+					       ret_val);
+
+					/* paste into item */
+					bi.tb = tb;
+					bi.bi_bh = S_new[i];
+					bi.bi_parent = NULL;
+					bi.bi_position = 0;
+					leaf_paste_in_buffer(&bi,
+							     item_pos - n +
+							     snum[i],
+							     pos_in_item,
+							     tb->insert_size[0],
+							     body, zeros_num);
+
+					pasted =
+					    B_N_PITEM_HEAD(S_new[i],
+							   item_pos - n +
+							   snum[i]);
+					if (is_direntry_le_ih(pasted)) {
+						leaf_paste_entries(bi.bi_bh,
+								   item_pos -
+								   n + snum[i],
+								   pos_in_item,
+								   1,
+								   (struct
+								    reiserfs_de_head
+								    *)body,
+								   body +
+								   DEH_SIZE,
+								   tb->
+								   insert_size
+								   [0]
+						    );
+					}
+
+					/* if we paste to indirect item update ih_free_space */
+					if (is_indirect_le_ih(pasted))
+						set_ih_free_space(pasted, 0);
+					zeros_num = tb->insert_size[0] = 0;
+				}
 			}
 
-			leaf_paste_in_buffer(&bi, 0, n_shift, tb->insert_size[0]-n_rem, r_body,r_zeros_number);
-			{
-			    struct item_head * tmp;
-
-			    tmp = B_N_PITEM_HEAD(S_new[i],0);
-			    if (is_indirect_le_ih (tmp)) {
-				set_ih_free_space (tmp, 0);
-				set_le_ih_k_offset( tmp, le_ih_k_offset(tmp) + 
-					            (n_rem << (tb->tb_sb->s_blocksize_bits - UNFM_P_SHIFT)));
-			    } else {
-				set_le_ih_k_offset( tmp, le_ih_k_offset(tmp) + 
-				                    n_rem );
-			    }
-			}
+			else {	/* pasted item doesn't fall into S_new[i] */
 
-			tb->insert_size[0] = n_rem;
-			if ( ! n_rem )
-			    pos_in_item++;
-		    }
+				leaf_move_items(LEAF_FROM_S_TO_SNEW, tb,
+						snum[i], sbytes[i], S_new[i]);
+			}
+			break;
+		default:	/* cases d and t */
+			reiserfs_panic(tb->tb_sb,
+				       "PAP-12245: balance_leaf: blknum > 2: unexpectable mode: %s(%d)",
+				       (flag ==
+					M_DELETE) ? "DELETE" : ((flag ==
+								 M_CUT) ? "CUT"
+								: "UNKNOWN"),
+				       flag);
 		}
-		else
-		    /* item falls wholly into S_new[i] */
-		{
-		    int ret_val;
-		    struct item_head * pasted;
 
-#ifdef CONFIG_REISERFS_CHECK
-		    struct item_head * ih = B_N_PITEM_HEAD(tbS0,item_pos);
+		memcpy(insert_key + i, B_N_PKEY(S_new[i], 0), KEY_SIZE);
+		insert_ptr[i] = S_new[i];
 
-		    if ( ! is_direntry_le_ih(ih) && (pos_in_item != ih_item_len(ih) ||
-						     tb->insert_size[0] <= 0) )
-			reiserfs_panic (tb->tb_sb, "PAP-12235: balance_leaf: pos_in_item must be equal to ih_item_len");
-#endif /* CONFIG_REISERFS_CHECK */
-
-		    ret_val = leaf_move_items (LEAF_FROM_S_TO_SNEW, tb, snum[i], sbytes[i], S_new[i]);
-
-		    RFALSE( ret_val,
-			    "PAP-12240: unexpected value returned by leaf_move_items (%d)",
-			    ret_val);
-
-		    /* paste into item */
-		    bi.tb = tb;
-		    bi.bi_bh = S_new[i];
-		    bi.bi_parent = NULL;
-		    bi.bi_position = 0;
-		    leaf_paste_in_buffer(&bi, item_pos - n + snum[i], pos_in_item, tb->insert_size[0], body, zeros_num);
-
-		    pasted = B_N_PITEM_HEAD(S_new[i], item_pos - n + snum[i]);
-		    if (is_direntry_le_ih (pasted))
-		    {
-			leaf_paste_entries (
-			    bi.bi_bh, item_pos - n + snum[i], pos_in_item, 1, 
-			    (struct reiserfs_de_head *)body, body + DEH_SIZE, tb->insert_size[0]
-			    );
-		    }
-
-		    /* if we paste to indirect item update ih_free_space */
-		    if (is_indirect_le_ih (pasted))
-			set_ih_free_space (pasted, 0);
-		    zeros_num = tb->insert_size[0] = 0;
-		}
-	    }
+		RFALSE(!buffer_journaled(S_new[i])
+		       || buffer_journal_dirty(S_new[i])
+		       || buffer_dirty(S_new[i]), "PAP-12247: S_new[%d] : (%b)",
+		       i, S_new[i]);
+	}
 
-	    else /* pasted item doesn't fall into S_new[i] */
-	    {
-		leaf_move_items (LEAF_FROM_S_TO_SNEW, tb, snum[i], sbytes[i], S_new[i]);
-	    }
-	    break;
-	default:    /* cases d and t */
-	    reiserfs_panic (tb->tb_sb, "PAP-12245: balance_leaf: blknum > 2: unexpectable mode: %s(%d)",
-			    (flag == M_DELETE) ? "DELETE" : ((flag == M_CUT) ? "CUT" : "UNKNOWN"), flag);
-	}
-
-	memcpy (insert_key + i,B_N_PKEY(S_new[i],0),KEY_SIZE);
-	insert_ptr[i] = S_new[i];
-
-	RFALSE (!buffer_journaled (S_new [i]) || buffer_journal_dirty (S_new [i]) ||
-		buffer_dirty (S_new [i]),
-		"PAP-12247: S_new[%d] : (%b)", i, S_new[i]);
-    }
-
-    /* if the affected item was not wholly shifted then we perform all necessary operations on that part or whole of the
-       affected item which remains in S */
-    if ( 0 <= item_pos && item_pos < tb->s0num )
-    { /* if we must insert or append into buffer S[0] */
-
-	switch (flag)
-	{
-	case M_INSERT:   /* insert item into S[0] */
-	    bi.tb = tb;
-	    bi.bi_bh = tbS0;
-	    bi.bi_parent = PATH_H_PPARENT (tb->tb_path, 0);
-	    bi.bi_position = PATH_H_POSITION (tb->tb_path, 1);
-	    leaf_insert_into_buf (&bi, item_pos, ih, body, zeros_num);
-
-	    /* If we insert the first key change the delimiting key */
-	    if( item_pos == 0 ) {
-		if (tb->CFL[0]) /* can be 0 in reiserfsck */
-		    replace_key(tb, tb->CFL[0], tb->lkey[0],tbS0,0);
-
-	    }
-	    break;
-
-	case M_PASTE: {  /* append item in S[0] */
-	    struct item_head * pasted;
-
-	    pasted = B_N_PITEM_HEAD (tbS0, item_pos);
-	    /* when directory, may be new entry already pasted */
-	    if (is_direntry_le_ih (pasted)) {
-		if ( pos_in_item >= 0 &&
-		    pos_in_item <= ih_entry_count(pasted) ) {
-
-		    RFALSE( ! tb->insert_size[0], 
-			    "PAP-12260: insert_size is 0 already");
-
-		    /* prepare space */
-		    bi.tb = tb;
-		    bi.bi_bh = tbS0;
-		    bi.bi_parent = PATH_H_PPARENT (tb->tb_path, 0);
-		    bi.bi_position = PATH_H_POSITION (tb->tb_path, 1);
-		    leaf_paste_in_buffer(&bi, item_pos, pos_in_item, tb->insert_size[0], body, zeros_num);
-
-		    /* paste entry */
-		    leaf_paste_entries (
-			bi.bi_bh, item_pos, pos_in_item, 1, (struct reiserfs_de_head *)body,
-			body + DEH_SIZE, tb->insert_size[0]
-			);
-		    if ( ! item_pos && ! pos_in_item ) {
-			RFALSE( !tb->CFL[0] || !tb->L[0], 
-				"PAP-12270: CFL[0]/L[0] must be specified");
-			if (tb->CFL[0]) {
-			    replace_key(tb, tb->CFL[0], tb->lkey[0],tbS0,0);
+	/* if the affected item was not wholly shifted then we perform all necessary operations on that part or whole of the
+	   affected item which remains in S */
+	if (0 <= item_pos && item_pos < tb->s0num) {	/* if we must insert or append into buffer S[0] */
+
+		switch (flag) {
+		case M_INSERT:	/* insert item into S[0] */
+			bi.tb = tb;
+			bi.bi_bh = tbS0;
+			bi.bi_parent = PATH_H_PPARENT(tb->tb_path, 0);
+			bi.bi_position = PATH_H_POSITION(tb->tb_path, 1);
+			leaf_insert_into_buf(&bi, item_pos, ih, body,
+					     zeros_num);
+
+			/* If we insert the first key change the delimiting key */
+			if (item_pos == 0) {
+				if (tb->CFL[0])	/* can be 0 in reiserfsck */
+					replace_key(tb, tb->CFL[0], tb->lkey[0],
+						    tbS0, 0);
 
 			}
-		    }
-		    tb->insert_size[0] = 0;
-		}
-	    } else { /* regular object */
-		if ( pos_in_item == ih_item_len(pasted) ) {
+			break;
 
-		    RFALSE( tb->insert_size[0] <= 0,
-			    "PAP-12275: insert size must not be %d",
-                            tb->insert_size[0]);
-		    bi.tb = tb;
-		    bi.bi_bh = tbS0;
-		    bi.bi_parent = PATH_H_PPARENT (tb->tb_path, 0);
-		    bi.bi_position = PATH_H_POSITION (tb->tb_path, 1);
-		    leaf_paste_in_buffer (&bi, item_pos, pos_in_item, tb->insert_size[0], body, zeros_num);
+		case M_PASTE:{	/* append item in S[0] */
+				struct item_head *pasted;
 
-		    if (is_indirect_le_ih (pasted)) {
+				pasted = B_N_PITEM_HEAD(tbS0, item_pos);
+				/* when directory, may be new entry already pasted */
+				if (is_direntry_le_ih(pasted)) {
+					if (pos_in_item >= 0 &&
+					    pos_in_item <=
+					    ih_entry_count(pasted)) {
+
+						RFALSE(!tb->insert_size[0],
+						       "PAP-12260: insert_size is 0 already");
+
+						/* prepare space */
+						bi.tb = tb;
+						bi.bi_bh = tbS0;
+						bi.bi_parent =
+						    PATH_H_PPARENT(tb->tb_path,
+								   0);
+						bi.bi_position =
+						    PATH_H_POSITION(tb->tb_path,
+								    1);
+						leaf_paste_in_buffer(&bi,
+								     item_pos,
+								     pos_in_item,
+								     tb->
+								     insert_size
+								     [0], body,
+								     zeros_num);
+
+						/* paste entry */
+						leaf_paste_entries(bi.bi_bh,
+								   item_pos,
+								   pos_in_item,
+								   1,
+								   (struct
+								    reiserfs_de_head
+								    *)body,
+								   body +
+								   DEH_SIZE,
+								   tb->
+								   insert_size
+								   [0]
+						    );
+						if (!item_pos && !pos_in_item) {
+							RFALSE(!tb->CFL[0]
+							       || !tb->L[0],
+							       "PAP-12270: CFL[0]/L[0] must be specified");
+							if (tb->CFL[0]) {
+								replace_key(tb,
+									    tb->
+									    CFL
+									    [0],
+									    tb->
+									    lkey
+									    [0],
+									    tbS0,
+									    0);
+
+							}
+						}
+						tb->insert_size[0] = 0;
+					}
+				} else {	/* regular object */
+					if (pos_in_item == ih_item_len(pasted)) {
+
+						RFALSE(tb->insert_size[0] <= 0,
+						       "PAP-12275: insert size must not be %d",
+						       tb->insert_size[0]);
+						bi.tb = tb;
+						bi.bi_bh = tbS0;
+						bi.bi_parent =
+						    PATH_H_PPARENT(tb->tb_path,
+								   0);
+						bi.bi_position =
+						    PATH_H_POSITION(tb->tb_path,
+								    1);
+						leaf_paste_in_buffer(&bi,
+								     item_pos,
+								     pos_in_item,
+								     tb->
+								     insert_size
+								     [0], body,
+								     zeros_num);
+
+						if (is_indirect_le_ih(pasted)) {
 #if 0
-			RFALSE( tb->insert_size[0] != UNFM_P_SIZE,
-				"PAP-12280: insert_size for indirect item must be %d, not %d",
-				UNFM_P_SIZE, tb->insert_size[0]);
+							RFALSE(tb->
+							       insert_size[0] !=
+							       UNFM_P_SIZE,
+							       "PAP-12280: insert_size for indirect item must be %d, not %d",
+							       UNFM_P_SIZE,
+							       tb->
+							       insert_size[0]);
 #endif
-			set_ih_free_space (pasted, 0);
-		    }
-		    tb->insert_size[0] = 0;
-		}
-
+							set_ih_free_space
+							    (pasted, 0);
+						}
+						tb->insert_size[0] = 0;
+					}
 #ifdef CONFIG_REISERFS_CHECK
-		else {
-		    if ( tb->insert_size[0] ) {
-			print_cur_tb ("12285");
-			reiserfs_panic (tb->tb_sb, "PAP-12285: balance_leaf: insert_size must be 0 (%d)", tb->insert_size[0]);
-		    }
+					else {
+						if (tb->insert_size[0]) {
+							print_cur_tb("12285");
+							reiserfs_panic(tb->
+								       tb_sb,
+								       "PAP-12285: balance_leaf: insert_size must be 0 (%d)",
+								       tb->
+								       insert_size
+								       [0]);
+						}
+					}
+#endif				/* CONFIG_REISERFS_CHECK */
+
+				}
+			}	/* case M_PASTE: */
 		}
-#endif /* CONFIG_REISERFS_CHECK */
-	    
-	    }
-	} /* case M_PASTE: */
 	}
-    }
-
 #ifdef CONFIG_REISERFS_CHECK
-    if ( flag == M_PASTE && tb->insert_size[0] ) {
-	print_cur_tb ("12290");
-	reiserfs_panic (tb->tb_sb, "PAP-12290: balance_leaf: insert_size is still not 0 (%d)", tb->insert_size[0]);
-    }
-#endif /* CONFIG_REISERFS_CHECK */
-
-    return 0;
-} /* Leaf level of the tree is balanced (end of balance_leaf) */
-
+	if (flag == M_PASTE && tb->insert_size[0]) {
+		print_cur_tb("12290");
+		reiserfs_panic(tb->tb_sb,
+			       "PAP-12290: balance_leaf: insert_size is still not 0 (%d)",
+			       tb->insert_size[0]);
+	}
+#endif				/* CONFIG_REISERFS_CHECK */
 
+	return 0;
+}				/* Leaf level of the tree is balanced (end of balance_leaf) */
 
 /* Make empty node */
-void make_empty_node (struct buffer_info * bi)
+void make_empty_node(struct buffer_info *bi)
 {
-    struct block_head * blkh;
+	struct block_head *blkh;
 
-    RFALSE( bi->bi_bh == NULL, "PAP-12295: pointer to the buffer is NULL");
+	RFALSE(bi->bi_bh == NULL, "PAP-12295: pointer to the buffer is NULL");
 
-    blkh = B_BLK_HEAD(bi->bi_bh);
-    set_blkh_nr_item( blkh, 0 );
-    set_blkh_free_space( blkh, MAX_CHILD_SIZE(bi->bi_bh) );
+	blkh = B_BLK_HEAD(bi->bi_bh);
+	set_blkh_nr_item(blkh, 0);
+	set_blkh_free_space(blkh, MAX_CHILD_SIZE(bi->bi_bh));
 
-    if (bi->bi_parent)
-	B_N_CHILD (bi->bi_parent, bi->bi_position)->dc_size = 0; /* Endian safe if 0 */
+	if (bi->bi_parent)
+		B_N_CHILD(bi->bi_parent, bi->bi_position)->dc_size = 0;	/* Endian safe if 0 */
 }
 
-
 /* Get first empty buffer */
-struct buffer_head * get_FEB (struct tree_balance * tb)
+struct buffer_head *get_FEB(struct tree_balance *tb)
 {
-    int i;
-    struct buffer_head * first_b;
-    struct buffer_info bi;
-
-    for (i = 0; i < MAX_FEB_SIZE; i ++)
-	if (tb->FEB[i] != 0)
-	    break;
-
-    if (i == MAX_FEB_SIZE)
-	reiserfs_panic(tb->tb_sb, "vs-12300: get_FEB: FEB list is empty");
-
-    bi.tb = tb;
-    bi.bi_bh = first_b = tb->FEB[i];
-    bi.bi_parent = NULL;
-    bi.bi_position = 0;
-    make_empty_node (&bi);
-    set_buffer_uptodate(first_b);
-    tb->FEB[i] = NULL;
-    tb->used[i] = first_b;
+	int i;
+	struct buffer_head *first_b;
+	struct buffer_info bi;
+
+	for (i = 0; i < MAX_FEB_SIZE; i++)
+		if (tb->FEB[i] != 0)
+			break;
+
+	if (i == MAX_FEB_SIZE)
+		reiserfs_panic(tb->tb_sb,
+			       "vs-12300: get_FEB: FEB list is empty");
 
-    return(first_b);
-}
+	bi.tb = tb;
+	bi.bi_bh = first_b = tb->FEB[i];
+	bi.bi_parent = NULL;
+	bi.bi_position = 0;
+	make_empty_node(&bi);
+	set_buffer_uptodate(first_b);
+	tb->FEB[i] = NULL;
+	tb->used[i] = first_b;
 
+	return (first_b);
+}
 
 /* This is now used because reiserfs_free_block has to be able to
 ** schedule.
 */
-static void store_thrown (struct tree_balance * tb, struct buffer_head * bh)
+static void store_thrown(struct tree_balance *tb, struct buffer_head *bh)
 {
-    int i;
+	int i;
 
-    if (buffer_dirty (bh))
-      reiserfs_warning (tb->tb_sb, "store_thrown deals with dirty buffer");
-    for (i = 0; i < sizeof (tb->thrown)/sizeof (tb->thrown[0]); i ++)
-	if (!tb->thrown[i]) {
-	    tb->thrown[i] = bh;
-	    get_bh(bh) ; /* free_thrown puts this */
-	    return;
-	}
-    reiserfs_warning (tb->tb_sb, "store_thrown: too many thrown buffers");
+	if (buffer_dirty(bh))
+		reiserfs_warning(tb->tb_sb,
+				 "store_thrown deals with dirty buffer");
+	for (i = 0; i < sizeof(tb->thrown) / sizeof(tb->thrown[0]); i++)
+		if (!tb->thrown[i]) {
+			tb->thrown[i] = bh;
+			get_bh(bh);	/* free_thrown puts this */
+			return;
+		}
+	reiserfs_warning(tb->tb_sb, "store_thrown: too many thrown buffers");
 }
 
-static void free_thrown(struct tree_balance *tb) {
-    int i ;
-    b_blocknr_t blocknr ;
-    for (i = 0; i < sizeof (tb->thrown)/sizeof (tb->thrown[0]); i++) {
-	if (tb->thrown[i]) {
-	    blocknr = tb->thrown[i]->b_blocknr ;
-	    if (buffer_dirty (tb->thrown[i]))
-	      reiserfs_warning (tb->tb_sb,
-				"free_thrown deals with dirty buffer %d",
-				blocknr);
-	    brelse(tb->thrown[i]) ; /* incremented in store_thrown */
-	    reiserfs_free_block (tb->transaction_handle, NULL, blocknr, 0);
+static void free_thrown(struct tree_balance *tb)
+{
+	int i;
+	b_blocknr_t blocknr;
+	for (i = 0; i < sizeof(tb->thrown) / sizeof(tb->thrown[0]); i++) {
+		if (tb->thrown[i]) {
+			blocknr = tb->thrown[i]->b_blocknr;
+			if (buffer_dirty(tb->thrown[i]))
+				reiserfs_warning(tb->tb_sb,
+						 "free_thrown deals with dirty buffer %d",
+						 blocknr);
+			brelse(tb->thrown[i]);	/* incremented in store_thrown */
+			reiserfs_free_block(tb->transaction_handle, NULL,
+					    blocknr, 0);
+		}
 	}
-    }
 }
 
-void reiserfs_invalidate_buffer (struct tree_balance * tb, struct buffer_head * bh)
+void reiserfs_invalidate_buffer(struct tree_balance *tb, struct buffer_head *bh)
 {
-    struct block_head *blkh;
-    blkh = B_BLK_HEAD(bh);
-    set_blkh_level( blkh, FREE_LEVEL );
-    set_blkh_nr_item( blkh, 0 );
-    
-    clear_buffer_dirty(bh);
-    store_thrown (tb, bh);
+	struct block_head *blkh;
+	blkh = B_BLK_HEAD(bh);
+	set_blkh_level(blkh, FREE_LEVEL);
+	set_blkh_nr_item(blkh, 0);
+
+	clear_buffer_dirty(bh);
+	store_thrown(tb, bh);
 }
 
 /* Replace n_dest'th key in buffer dest by n_src'th key of buffer src.*/
-void replace_key (struct tree_balance * tb, struct buffer_head * dest, int n_dest,
-		  struct buffer_head * src, int n_src)
+void replace_key(struct tree_balance *tb, struct buffer_head *dest, int n_dest,
+		 struct buffer_head *src, int n_src)
 {
 
-    RFALSE( dest == NULL || src == NULL,
-	    "vs-12305: source or destination buffer is 0 (src=%p, dest=%p)",
-	    src, dest);
-    RFALSE( ! B_IS_KEYS_LEVEL (dest),
-	    "vs-12310: invalid level (%z) for destination buffer. dest must be leaf",
-	    dest);
-    RFALSE( n_dest < 0 || n_src < 0,
-	    "vs-12315: src(%d) or dest(%d) key number < 0", n_src, n_dest);
-    RFALSE( n_dest >= B_NR_ITEMS(dest) || n_src >= B_NR_ITEMS(src),
-	    "vs-12320: src(%d(%d)) or dest(%d(%d)) key number is too big",
-	    n_src, B_NR_ITEMS(src), n_dest, B_NR_ITEMS(dest));
-   
-    if (B_IS_ITEMS_LEVEL (src))
-	/* source buffer contains leaf node */
-	memcpy (B_N_PDELIM_KEY(dest,n_dest), B_N_PITEM_HEAD(src,n_src), KEY_SIZE);
-    else
-	memcpy (B_N_PDELIM_KEY(dest,n_dest), B_N_PDELIM_KEY(src,n_src), KEY_SIZE);
+	RFALSE(dest == NULL || src == NULL,
+	       "vs-12305: source or destination buffer is 0 (src=%p, dest=%p)",
+	       src, dest);
+	RFALSE(!B_IS_KEYS_LEVEL(dest),
+	       "vs-12310: invalid level (%z) for destination buffer. dest must be leaf",
+	       dest);
+	RFALSE(n_dest < 0 || n_src < 0,
+	       "vs-12315: src(%d) or dest(%d) key number < 0", n_src, n_dest);
+	RFALSE(n_dest >= B_NR_ITEMS(dest) || n_src >= B_NR_ITEMS(src),
+	       "vs-12320: src(%d(%d)) or dest(%d(%d)) key number is too big",
+	       n_src, B_NR_ITEMS(src), n_dest, B_NR_ITEMS(dest));
+
+	if (B_IS_ITEMS_LEVEL(src))
+		/* source buffer contains leaf node */
+		memcpy(B_N_PDELIM_KEY(dest, n_dest), B_N_PITEM_HEAD(src, n_src),
+		       KEY_SIZE);
+	else
+		memcpy(B_N_PDELIM_KEY(dest, n_dest), B_N_PDELIM_KEY(src, n_src),
+		       KEY_SIZE);
 
-    do_balance_mark_internal_dirty (tb, dest, 0);
+	do_balance_mark_internal_dirty(tb, dest, 0);
 }
 
-
-int get_left_neighbor_position (
-				struct tree_balance * tb, 
-				int h
-				)
+int get_left_neighbor_position(struct tree_balance *tb, int h)
 {
-  int Sh_position = PATH_H_POSITION (tb->tb_path, h + 1);
+	int Sh_position = PATH_H_POSITION(tb->tb_path, h + 1);
 
-  RFALSE( PATH_H_PPARENT (tb->tb_path, h) == 0 || tb->FL[h] == 0,
-	  "vs-12325: FL[%d](%p) or F[%d](%p) does not exist", 
-	  h, tb->FL[h], h, PATH_H_PPARENT (tb->tb_path, h));
-
-  if (Sh_position == 0)
-    return B_NR_ITEMS (tb->FL[h]);
-  else
-    return Sh_position - 1;
+	RFALSE(PATH_H_PPARENT(tb->tb_path, h) == 0 || tb->FL[h] == 0,
+	       "vs-12325: FL[%d](%p) or F[%d](%p) does not exist",
+	       h, tb->FL[h], h, PATH_H_PPARENT(tb->tb_path, h));
+
+	if (Sh_position == 0)
+		return B_NR_ITEMS(tb->FL[h]);
+	else
+		return Sh_position - 1;
 }
 
-
-int get_right_neighbor_position (struct tree_balance * tb, int h)
+int get_right_neighbor_position(struct tree_balance *tb, int h)
 {
-  int Sh_position = PATH_H_POSITION (tb->tb_path, h + 1);
+	int Sh_position = PATH_H_POSITION(tb->tb_path, h + 1);
 
-  RFALSE( PATH_H_PPARENT (tb->tb_path, h) == 0 || tb->FR[h] == 0,
-	  "vs-12330: F[%d](%p) or FR[%d](%p) does not exist", 
-	  h, PATH_H_PPARENT (tb->tb_path, h), h, tb->FR[h]);
-
-  if (Sh_position == B_NR_ITEMS (PATH_H_PPARENT (tb->tb_path, h)))
-    return 0;
-  else
-    return Sh_position + 1;
+	RFALSE(PATH_H_PPARENT(tb->tb_path, h) == 0 || tb->FR[h] == 0,
+	       "vs-12330: F[%d](%p) or FR[%d](%p) does not exist",
+	       h, PATH_H_PPARENT(tb->tb_path, h), h, tb->FR[h]);
+
+	if (Sh_position == B_NR_ITEMS(PATH_H_PPARENT(tb->tb_path, h)))
+		return 0;
+	else
+		return Sh_position + 1;
 }
 
-
 #ifdef CONFIG_REISERFS_CHECK
 
-int is_reusable (struct super_block * s, b_blocknr_t block, int bit_value);
-static void check_internal_node (struct super_block * s, struct buffer_head * bh, char * mes)
+int is_reusable(struct super_block *s, b_blocknr_t block, int bit_value);
+static void check_internal_node(struct super_block *s, struct buffer_head *bh,
+				char *mes)
 {
-  struct disk_child * dc;
-  int i;
+	struct disk_child *dc;
+	int i;
 
-  RFALSE( !bh, "PAP-12336: bh == 0");
+	RFALSE(!bh, "PAP-12336: bh == 0");
 
-  if (!bh || !B_IS_IN_TREE (bh))
-    return;
- 
-  RFALSE( !buffer_dirty (bh) && 
-	  !(buffer_journaled(bh) || buffer_journal_dirty(bh)),
-	  "PAP-12337: buffer (%b) must be dirty", bh);
-  dc = B_N_CHILD (bh, 0);
-
-  for (i = 0; i <= B_NR_ITEMS (bh); i ++, dc ++) {
-    if (!is_reusable (s, dc_block_number(dc), 1) ) {
-      print_cur_tb (mes);
-      reiserfs_panic (s, "PAP-12338: check_internal_node: invalid child pointer %y in %b", dc, bh);
-    }
-  }
-}
+	if (!bh || !B_IS_IN_TREE(bh))
+		return;
 
+	RFALSE(!buffer_dirty(bh) &&
+	       !(buffer_journaled(bh) || buffer_journal_dirty(bh)),
+	       "PAP-12337: buffer (%b) must be dirty", bh);
+	dc = B_N_CHILD(bh, 0);
+
+	for (i = 0; i <= B_NR_ITEMS(bh); i++, dc++) {
+		if (!is_reusable(s, dc_block_number(dc), 1)) {
+			print_cur_tb(mes);
+			reiserfs_panic(s,
+				       "PAP-12338: check_internal_node: invalid child pointer %y in %b",
+				       dc, bh);
+		}
+	}
+}
 
-static int locked_or_not_in_tree (struct buffer_head * bh, char * which)
+static int locked_or_not_in_tree(struct buffer_head *bh, char *which)
 {
-  if ( (!buffer_journal_prepared (bh) && buffer_locked (bh)) ||
-        !B_IS_IN_TREE (bh) ) {
-    reiserfs_warning (NULL, "vs-12339: locked_or_not_in_tree: %s (%b)",
-                      which, bh);
-    return 1;
-  } 
-  return 0;
+	if ((!buffer_journal_prepared(bh) && buffer_locked(bh)) ||
+	    !B_IS_IN_TREE(bh)) {
+		reiserfs_warning(NULL,
+				 "vs-12339: locked_or_not_in_tree: %s (%b)",
+				 which, bh);
+		return 1;
+	}
+	return 0;
 }
 
-
-static int check_before_balancing (struct tree_balance * tb)
+static int check_before_balancing(struct tree_balance *tb)
 {
-  int retval = 0;	
+	int retval = 0;
 
-  if ( cur_tb ) {
-    reiserfs_panic (tb->tb_sb, "vs-12335: check_before_balancing: "
-		    "suspect that schedule occurred based on cur_tb not being null at this point in code. "
-		    "do_balance cannot properly handle schedule occurring while it runs.");
-  }
-  
-  /* double check that buffers that we will modify are unlocked. (fix_nodes should already have
-     prepped all of these for us). */
-  if ( tb->lnum[0] ) {
-    retval |= locked_or_not_in_tree (tb->L[0], "L[0]");
-    retval |= locked_or_not_in_tree (tb->FL[0], "FL[0]");
-    retval |= locked_or_not_in_tree (tb->CFL[0], "CFL[0]");
-    check_leaf (tb->L[0]);
-  }
-  if ( tb->rnum[0] ) {
-    retval |= locked_or_not_in_tree (tb->R[0], "R[0]");
-    retval |= locked_or_not_in_tree (tb->FR[0], "FR[0]");
-    retval |= locked_or_not_in_tree (tb->CFR[0], "CFR[0]");
-    check_leaf (tb->R[0]);
-  }
-  retval |= locked_or_not_in_tree (PATH_PLAST_BUFFER (tb->tb_path), "S[0]");
-  check_leaf (PATH_PLAST_BUFFER (tb->tb_path));
+	if (cur_tb) {
+		reiserfs_panic(tb->tb_sb, "vs-12335: check_before_balancing: "
+			       "suspect that schedule occurred based on cur_tb not being null at this point in code. "
+			       "do_balance cannot properly handle schedule occurring while it runs.");
+	}
 
-  return retval;
-}
+	/* double check that buffers that we will modify are unlocked. (fix_nodes should already have
+	   prepped all of these for us). */
+	if (tb->lnum[0]) {
+		retval |= locked_or_not_in_tree(tb->L[0], "L[0]");
+		retval |= locked_or_not_in_tree(tb->FL[0], "FL[0]");
+		retval |= locked_or_not_in_tree(tb->CFL[0], "CFL[0]");
+		check_leaf(tb->L[0]);
+	}
+	if (tb->rnum[0]) {
+		retval |= locked_or_not_in_tree(tb->R[0], "R[0]");
+		retval |= locked_or_not_in_tree(tb->FR[0], "FR[0]");
+		retval |= locked_or_not_in_tree(tb->CFR[0], "CFR[0]");
+		check_leaf(tb->R[0]);
+	}
+	retval |= locked_or_not_in_tree(PATH_PLAST_BUFFER(tb->tb_path), "S[0]");
+	check_leaf(PATH_PLAST_BUFFER(tb->tb_path));
 
+	return retval;
+}
 
-static void check_after_balance_leaf (struct tree_balance * tb)
+static void check_after_balance_leaf(struct tree_balance *tb)
 {
-    if (tb->lnum[0]) {
-	if (B_FREE_SPACE (tb->L[0]) != 
-	    MAX_CHILD_SIZE (tb->L[0]) - dc_size(B_N_CHILD (tb->FL[0], get_left_neighbor_position (tb, 0)))) {
-	    print_cur_tb ("12221");
-	    reiserfs_panic (tb->tb_sb, "PAP-12355: check_after_balance_leaf: shift to left was incorrect");
-	}
-    }
-    if (tb->rnum[0]) {
-	if (B_FREE_SPACE (tb->R[0]) != 
-	    MAX_CHILD_SIZE (tb->R[0]) - dc_size(B_N_CHILD (tb->FR[0], get_right_neighbor_position (tb, 0)))) {
-	    print_cur_tb ("12222");
-	    reiserfs_panic (tb->tb_sb, "PAP-12360: check_after_balance_leaf: shift to right was incorrect");
-	}
-    }
-    if (PATH_H_PBUFFER(tb->tb_path,1) &&
-	(B_FREE_SPACE (PATH_H_PBUFFER(tb->tb_path,0)) != 
-		    (MAX_CHILD_SIZE (PATH_H_PBUFFER(tb->tb_path,0)) -
-		    dc_size(B_N_CHILD (PATH_H_PBUFFER(tb->tb_path,1),
-		    PATH_H_POSITION (tb->tb_path, 1)))) )) {
-	int left = B_FREE_SPACE (PATH_H_PBUFFER(tb->tb_path,0));
-	int right = (MAX_CHILD_SIZE (PATH_H_PBUFFER(tb->tb_path,0)) -
-		    dc_size(B_N_CHILD (PATH_H_PBUFFER(tb->tb_path,1),
-			PATH_H_POSITION (tb->tb_path, 1))));
-	print_cur_tb ("12223");
-	reiserfs_warning (tb->tb_sb,
-	    "B_FREE_SPACE (PATH_H_PBUFFER(tb->tb_path,0)) = %d; "
-    	    "MAX_CHILD_SIZE (%d) - dc_size( %y, %d ) [%d] = %d",
-	    left,
-	    MAX_CHILD_SIZE (PATH_H_PBUFFER(tb->tb_path,0)),
-	    PATH_H_PBUFFER(tb->tb_path,1),
-	    PATH_H_POSITION (tb->tb_path, 1),
-	    dc_size(B_N_CHILD (PATH_H_PBUFFER(tb->tb_path,1), PATH_H_POSITION (tb->tb_path, 1 )) ),
-	    right );
-	reiserfs_panic (tb->tb_sb, "PAP-12365: check_after_balance_leaf: S is incorrect");
-    }
+	if (tb->lnum[0]) {
+		if (B_FREE_SPACE(tb->L[0]) !=
+		    MAX_CHILD_SIZE(tb->L[0]) -
+		    dc_size(B_N_CHILD
+			    (tb->FL[0], get_left_neighbor_position(tb, 0)))) {
+			print_cur_tb("12221");
+			reiserfs_panic(tb->tb_sb,
+				       "PAP-12355: check_after_balance_leaf: shift to left was incorrect");
+		}
+	}
+	if (tb->rnum[0]) {
+		if (B_FREE_SPACE(tb->R[0]) !=
+		    MAX_CHILD_SIZE(tb->R[0]) -
+		    dc_size(B_N_CHILD
+			    (tb->FR[0], get_right_neighbor_position(tb, 0)))) {
+			print_cur_tb("12222");
+			reiserfs_panic(tb->tb_sb,
+				       "PAP-12360: check_after_balance_leaf: shift to right was incorrect");
+		}
+	}
+	if (PATH_H_PBUFFER(tb->tb_path, 1) &&
+	    (B_FREE_SPACE(PATH_H_PBUFFER(tb->tb_path, 0)) !=
+	     (MAX_CHILD_SIZE(PATH_H_PBUFFER(tb->tb_path, 0)) -
+	      dc_size(B_N_CHILD(PATH_H_PBUFFER(tb->tb_path, 1),
+				PATH_H_POSITION(tb->tb_path, 1)))))) {
+		int left = B_FREE_SPACE(PATH_H_PBUFFER(tb->tb_path, 0));
+		int right = (MAX_CHILD_SIZE(PATH_H_PBUFFER(tb->tb_path, 0)) -
+			     dc_size(B_N_CHILD(PATH_H_PBUFFER(tb->tb_path, 1),
+					       PATH_H_POSITION(tb->tb_path,
+							       1))));
+		print_cur_tb("12223");
+		reiserfs_warning(tb->tb_sb,
+				 "B_FREE_SPACE (PATH_H_PBUFFER(tb->tb_path,0)) = %d; "
+				 "MAX_CHILD_SIZE (%d) - dc_size( %y, %d ) [%d] = %d",
+				 left,
+				 MAX_CHILD_SIZE(PATH_H_PBUFFER(tb->tb_path, 0)),
+				 PATH_H_PBUFFER(tb->tb_path, 1),
+				 PATH_H_POSITION(tb->tb_path, 1),
+				 dc_size(B_N_CHILD
+					 (PATH_H_PBUFFER(tb->tb_path, 1),
+					  PATH_H_POSITION(tb->tb_path, 1))),
+				 right);
+		reiserfs_panic(tb->tb_sb,
+			       "PAP-12365: check_after_balance_leaf: S is incorrect");
+	}
 }
 
-
-static void check_leaf_level (struct tree_balance * tb)
+static void check_leaf_level(struct tree_balance *tb)
 {
-  check_leaf (tb->L[0]);
-  check_leaf (tb->R[0]);
-  check_leaf (PATH_PLAST_BUFFER (tb->tb_path));
+	check_leaf(tb->L[0]);
+	check_leaf(tb->R[0]);
+	check_leaf(PATH_PLAST_BUFFER(tb->tb_path));
 }
 
-static void check_internal_levels (struct tree_balance * tb)
+static void check_internal_levels(struct tree_balance *tb)
 {
-  int h;
+	int h;
 
-  /* check all internal nodes */
-  for (h = 1; tb->insert_size[h]; h ++) {
-    check_internal_node (tb->tb_sb, PATH_H_PBUFFER (tb->tb_path, h), "BAD BUFFER ON PATH");
-    if (tb->lnum[h])
-      check_internal_node (tb->tb_sb, tb->L[h], "BAD L");
-    if (tb->rnum[h])
-      check_internal_node (tb->tb_sb, tb->R[h], "BAD R");
-  }
+	/* check all internal nodes */
+	for (h = 1; tb->insert_size[h]; h++) {
+		check_internal_node(tb->tb_sb, PATH_H_PBUFFER(tb->tb_path, h),
+				    "BAD BUFFER ON PATH");
+		if (tb->lnum[h])
+			check_internal_node(tb->tb_sb, tb->L[h], "BAD L");
+		if (tb->rnum[h])
+			check_internal_node(tb->tb_sb, tb->R[h], "BAD R");
+	}
 
 }
 
 #endif
 
-
-
-
-
-
 /* Now we have all of the buffers that must be used in balancing of
    the tree.  We rely on the assumption that schedule() will not occur
    while do_balance works. ( Only interrupt handlers are acceptable.)
@@ -1484,114 +2029,109 @@ static void check_internal_levels (struc
 
 */
 
-static inline void do_balance_starts (struct tree_balance *tb)
+static inline void do_balance_starts(struct tree_balance *tb)
 {
-    /* use print_cur_tb() to see initial state of struct
-       tree_balance */
+	/* use print_cur_tb() to see initial state of struct
+	   tree_balance */
 
-    /* store_print_tb (tb); */
+	/* store_print_tb (tb); */
 
-    /* do not delete, just comment it out */
+	/* do not delete, just comment it out */
 /*    print_tb(flag, PATH_LAST_POSITION(tb->tb_path), tb->tb_path->pos_in_item, tb, 
 	     "check");*/
-    RFALSE( check_before_balancing (tb), "PAP-12340: locked buffers in TB");
+	RFALSE(check_before_balancing(tb), "PAP-12340: locked buffers in TB");
 #ifdef CONFIG_REISERFS_CHECK
-    cur_tb = tb;
+	cur_tb = tb;
 #endif
 }
 
-
-static inline void do_balance_completed (struct tree_balance * tb)
+static inline void do_balance_completed(struct tree_balance *tb)
 {
-    
+
 #ifdef CONFIG_REISERFS_CHECK
-    check_leaf_level (tb);
-    check_internal_levels (tb);
-    cur_tb = NULL;
+	check_leaf_level(tb);
+	check_internal_levels(tb);
+	cur_tb = NULL;
 #endif
 
-    /* reiserfs_free_block is no longer schedule safe.  So, we need to
-    ** put the buffers we want freed on the thrown list during do_balance,
-    ** and then free them now
-    */
-
-    REISERFS_SB(tb->tb_sb)->s_do_balance ++;
+	/* reiserfs_free_block is no longer schedule safe.  So, we need to
+	 ** put the buffers we want freed on the thrown list during do_balance,
+	 ** and then free them now
+	 */
 
+	REISERFS_SB(tb->tb_sb)->s_do_balance++;
 
-    /* release all nodes hold to perform the balancing */
-    unfix_nodes(tb);
+	/* release all nodes hold to perform the balancing */
+	unfix_nodes(tb);
 
-    free_thrown(tb) ;
+	free_thrown(tb);
 }
 
+void do_balance(struct tree_balance *tb,	/* tree_balance structure */
+		struct item_head *ih,	/* item header of inserted item */
+		const char *body,	/* body  of inserted item or bytes to paste */
+		int flag)
+{				/* i - insert, d - delete
+				   c - cut, p - paste
+
+				   Cut means delete part of an item
+				   (includes removing an entry from a
+				   directory).
+
+				   Delete means delete whole item.
+
+				   Insert means add a new item into the
+				   tree.
+
+				   Paste means to append to the end of an
+				   existing file or to insert a directory
+				   entry.  */
+	int child_pos,		/* position of a child node in its parent */
+	 h;			/* level of the tree being processed */
+	struct item_head insert_key[2];	/* in our processing of one level
+					   we sometimes determine what
+					   must be inserted into the next
+					   higher level.  This insertion
+					   consists of a key or two keys
+					   and their corresponding
+					   pointers */
+	struct buffer_head *insert_ptr[2];	/* inserted node-ptrs for the next
+						   level */
+
+	tb->tb_mode = flag;
+	tb->need_balance_dirty = 0;
+
+	if (FILESYSTEM_CHANGED_TB(tb)) {
+		reiserfs_panic(tb->tb_sb,
+			       "clm-6000: do_balance, fs generation has changed\n");
+	}
+	/* if we have no real work to do  */
+	if (!tb->insert_size[0]) {
+		reiserfs_warning(tb->tb_sb,
+				 "PAP-12350: do_balance: insert_size == 0, mode == %c",
+				 flag);
+		unfix_nodes(tb);
+		return;
+	}
 
+	atomic_inc(&(fs_generation(tb->tb_sb)));
+	do_balance_starts(tb);
 
-
-
-void do_balance (struct tree_balance * tb, /* tree_balance structure */
-		 struct item_head * ih,	   /* item header of inserted item */
-		 const char * body,  /* body  of inserted item or bytes to paste */
-		 int flag)  /* i - insert, d - delete
-			       c - cut, p - paste
-						      
-			       Cut means delete part of an item
-			       (includes removing an entry from a
-			       directory).
-						      
-			       Delete means delete whole item.
-						      
-			       Insert means add a new item into the
-			       tree.
-						      						      
-			       Paste means to append to the end of an
-			       existing file or to insert a directory
-			       entry.  */
-{
-    int child_pos, /* position of a child node in its parent */
-	h;	   /* level of the tree being processed */
-    struct item_head insert_key[2]; /* in our processing of one level
-				       we sometimes determine what
-				       must be inserted into the next
-				       higher level.  This insertion
-				       consists of a key or two keys
-				       and their corresponding
-				       pointers */
-    struct buffer_head *insert_ptr[2]; /* inserted node-ptrs for the next
-					  level */
-
-    tb->tb_mode = flag;
-    tb->need_balance_dirty = 0;
-
-    if (FILESYSTEM_CHANGED_TB(tb)) {
-        reiserfs_panic(tb->tb_sb, "clm-6000: do_balance, fs generation has changed\n") ;
-    }
-    /* if we have no real work to do  */
-    if ( ! tb->insert_size[0] ) {
-	reiserfs_warning (tb->tb_sb,
-			  "PAP-12350: do_balance: insert_size == 0, mode == %c",
-			  flag);
-	unfix_nodes(tb);
-	return;
-    }
-
-    atomic_inc (&(fs_generation (tb->tb_sb)));
-    do_balance_starts (tb);
-    
 	/* balance leaf returns 0 except if combining L R and S into
 	   one node.  see balance_internal() for explanation of this
-	   line of code.*/
-	child_pos = PATH_H_B_ITEM_ORDER (tb->tb_path, 0) +
-	  balance_leaf (tb, ih, body, flag, insert_key, insert_ptr);
+	   line of code. */
+	child_pos = PATH_H_B_ITEM_ORDER(tb->tb_path, 0) +
+	    balance_leaf(tb, ih, body, flag, insert_key, insert_ptr);
 
 #ifdef CONFIG_REISERFS_CHECK
-    check_after_balance_leaf (tb);
+	check_after_balance_leaf(tb);
 #endif
 
-    /* Balance internal level of the tree. */
-    for ( h = 1; h < MAX_HEIGHT && tb->insert_size[h]; h++ )
-	child_pos = balance_internal (tb, h, child_pos, insert_key, insert_ptr);
-
+	/* Balance internal level of the tree. */
+	for (h = 1; h < MAX_HEIGHT && tb->insert_size[h]; h++)
+		child_pos =
+		    balance_internal(tb, h, child_pos, insert_key, insert_ptr);
 
-    do_balance_completed (tb);
+	do_balance_completed(tb);
 
 }
diff --git a/fs/reiserfs/file.c b/fs/reiserfs/file.c
--- a/fs/reiserfs/file.c
+++ b/fs/reiserfs/file.c
@@ -2,7 +2,6 @@
  * Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README
  */
 
-
 #include <linux/time.h>
 #include <linux/reiserfs_fs.h>
 #include <linux/reiserfs_acl.h>
@@ -31,82 +30,84 @@
 ** We use reiserfs_truncate_file to pack the tail, since it already has
 ** all the conditions coded.  
 */
-static int reiserfs_file_release (struct inode * inode, struct file * filp)
+static int reiserfs_file_release(struct inode *inode, struct file *filp)
 {
 
-    struct reiserfs_transaction_handle th ;
-    int err;
-    int jbegin_failure = 0;
-
-    if (!S_ISREG (inode->i_mode))
-	BUG ();
-
-    /* fast out for when nothing needs to be done */
-    if ((atomic_read(&inode->i_count) > 1 ||
-	!(REISERFS_I(inode)->i_flags & i_pack_on_close_mask) || 
-         !tail_has_to_be_packed(inode))       && 
-	REISERFS_I(inode)->i_prealloc_count <= 0) {
-	return 0;
-    }    
-    
-    reiserfs_write_lock(inode->i_sb);
-    down (&inode->i_sem); 
-    /* freeing preallocation only involves relogging blocks that
-     * are already in the current transaction.  preallocation gets
-     * freed at the end of each transaction, so it is impossible for
-     * us to log any additional blocks (including quota blocks)
-     */
-    err = journal_begin(&th, inode->i_sb, 1);
-    if (err) {
-	/* uh oh, we can't allow the inode to go away while there
-	 * is still preallocation blocks pending.  Try to join the
-	 * aborted transaction
-	 */
-	jbegin_failure = err;
-	err = journal_join_abort(&th, inode->i_sb, 1);
+	struct reiserfs_transaction_handle th;
+	int err;
+	int jbegin_failure = 0;
+
+	if (!S_ISREG(inode->i_mode))
+		BUG();
+
+	/* fast out for when nothing needs to be done */
+	if ((atomic_read(&inode->i_count) > 1 ||
+	     !(REISERFS_I(inode)->i_flags & i_pack_on_close_mask) ||
+	     !tail_has_to_be_packed(inode)) &&
+	    REISERFS_I(inode)->i_prealloc_count <= 0) {
+		return 0;
+	}
 
+	reiserfs_write_lock(inode->i_sb);
+	down(&inode->i_sem);
+	/* freeing preallocation only involves relogging blocks that
+	 * are already in the current transaction.  preallocation gets
+	 * freed at the end of each transaction, so it is impossible for
+	 * us to log any additional blocks (including quota blocks)
+	 */
+	err = journal_begin(&th, inode->i_sb, 1);
 	if (err) {
-	    /* hmpf, our choices here aren't good.  We can pin the inode
-	     * which will disallow unmount from every happening, we can
-	     * do nothing, which will corrupt random memory on unmount,
-	     * or we can forcibly remove the file from the preallocation
-	     * list, which will leak blocks on disk.  Lets pin the inode
-	     * and let the admin know what is going on.
-	     */
-	    igrab(inode);
-	    reiserfs_warning(inode->i_sb, "pinning inode %lu because the "
-	                     "preallocation can't be freed");
-	    goto out;
+		/* uh oh, we can't allow the inode to go away while there
+		 * is still preallocation blocks pending.  Try to join the
+		 * aborted transaction
+		 */
+		jbegin_failure = err;
+		err = journal_join_abort(&th, inode->i_sb, 1);
+
+		if (err) {
+			/* hmpf, our choices here aren't good.  We can pin the inode
+			 * which will disallow unmount from every happening, we can
+			 * do nothing, which will corrupt random memory on unmount,
+			 * or we can forcibly remove the file from the preallocation
+			 * list, which will leak blocks on disk.  Lets pin the inode
+			 * and let the admin know what is going on.
+			 */
+			igrab(inode);
+			reiserfs_warning(inode->i_sb,
+					 "pinning inode %lu because the "
+					 "preallocation can't be freed");
+			goto out;
+		}
 	}
-    }
-    reiserfs_update_inode_transaction(inode) ;
+	reiserfs_update_inode_transaction(inode);
 
 #ifdef REISERFS_PREALLOCATE
-    reiserfs_discard_prealloc (&th, inode);
+	reiserfs_discard_prealloc(&th, inode);
 #endif
-    err = journal_end(&th, inode->i_sb, 1);
+	err = journal_end(&th, inode->i_sb, 1);
 
-    /* copy back the error code from journal_begin */
-    if (!err)
-        err = jbegin_failure;
-
-    if (!err && atomic_read(&inode->i_count) <= 1 &&
-	(REISERFS_I(inode)->i_flags & i_pack_on_close_mask) &&
-        tail_has_to_be_packed (inode)) {
-	/* if regular file is released by last holder and it has been
-	   appended (we append by unformatted node only) or its direct
-	   item(s) had to be converted, then it may have to be
-	   indirect2direct converted */
-	err = reiserfs_truncate_file(inode, 0) ;
-    }
-out:
-    up (&inode->i_sem); 
-    reiserfs_write_unlock(inode->i_sb);
-    return err;
+	/* copy back the error code from journal_begin */
+	if (!err)
+		err = jbegin_failure;
+
+	if (!err && atomic_read(&inode->i_count) <= 1 &&
+	    (REISERFS_I(inode)->i_flags & i_pack_on_close_mask) &&
+	    tail_has_to_be_packed(inode)) {
+		/* if regular file is released by last holder and it has been
+		   appended (we append by unformatted node only) or its direct
+		   item(s) had to be converted, then it may have to be
+		   indirect2direct converted */
+		err = reiserfs_truncate_file(inode, 0);
+	}
+      out:
+	up(&inode->i_sem);
+	reiserfs_write_unlock(inode->i_sb);
+	return err;
 }
 
-static void reiserfs_vfs_truncate_file(struct inode *inode) {
-    reiserfs_truncate_file(inode, 1) ;
+static void reiserfs_vfs_truncate_file(struct inode *inode)
+{
+	reiserfs_truncate_file(inode, 1);
 }
 
 /* Sync a reiserfs file. */
@@ -116,26 +117,24 @@ static void reiserfs_vfs_truncate_file(s
  * be removed...
  */
 
-static int reiserfs_sync_file(
-			      struct file   * p_s_filp,
-			      struct dentry * p_s_dentry,
-			      int datasync
-			      ) {
-  struct inode * p_s_inode = p_s_dentry->d_inode;
-  int n_err;
-  int barrier_done;
-
-  if (!S_ISREG(p_s_inode->i_mode))
-      BUG ();
-  n_err = sync_mapping_buffers(p_s_inode->i_mapping) ;
-  reiserfs_write_lock(p_s_inode->i_sb);
-  barrier_done = reiserfs_commit_for_inode(p_s_inode);
-  reiserfs_write_unlock(p_s_inode->i_sb);
-  if (barrier_done != 1)
-      blkdev_issue_flush(p_s_inode->i_sb->s_bdev, NULL);
-  if (barrier_done < 0)
-    return barrier_done;
-  return ( n_err < 0 ) ? -EIO : 0;
+static int reiserfs_sync_file(struct file *p_s_filp,
+			      struct dentry *p_s_dentry, int datasync)
+{
+	struct inode *p_s_inode = p_s_dentry->d_inode;
+	int n_err;
+	int barrier_done;
+
+	if (!S_ISREG(p_s_inode->i_mode))
+		BUG();
+	n_err = sync_mapping_buffers(p_s_inode->i_mapping);
+	reiserfs_write_lock(p_s_inode->i_sb);
+	barrier_done = reiserfs_commit_for_inode(p_s_inode);
+	reiserfs_write_unlock(p_s_inode->i_sb);
+	if (barrier_done != 1)
+		blkdev_issue_flush(p_s_inode->i_sb->s_bdev, NULL);
+	if (barrier_done < 0)
+		return barrier_done;
+	return (n_err < 0) ? -EIO : 0;
 }
 
 /* I really do not want to play with memory shortage right now, so
@@ -147,700 +146,797 @@ static int reiserfs_sync_file(
 /* Allocates blocks for a file to fulfil write request.
    Maps all unmapped but prepared pages from the list.
    Updates metadata with newly allocated blocknumbers as needed */
-static int reiserfs_allocate_blocks_for_region(
-				struct reiserfs_transaction_handle *th,
-				struct inode *inode, /* Inode we work with */
-				loff_t pos, /* Writing position */
-				int num_pages, /* number of pages write going
-						  to touch */
-				int write_bytes, /* amount of bytes to write */
-				struct page **prepared_pages, /* array of
-							         prepared pages
-							       */
-				int blocks_to_allocate /* Amount of blocks we
-							  need to allocate to
-							  fit the data into file
-							 */
-				)
+static int reiserfs_allocate_blocks_for_region(struct reiserfs_transaction_handle *th, struct inode *inode,	/* Inode we work with */
+					       loff_t pos,	/* Writing position */
+					       int num_pages,	/* number of pages write going
+								   to touch */
+					       int write_bytes,	/* amount of bytes to write */
+					       struct page **prepared_pages,	/* array of
+										   prepared pages
+										 */
+					       int blocks_to_allocate	/* Amount of blocks we
+									   need to allocate to
+									   fit the data into file
+									 */
+    )
 {
-    struct cpu_key key; // cpu key of item that we are going to deal with
-    struct item_head *ih; // pointer to item head that we are going to deal with
-    struct buffer_head *bh; // Buffer head that contains items that we are going to deal with
-    __le32 * item; // pointer to item we are going to deal with
-    INITIALIZE_PATH(path); // path to item, that we are going to deal with.
-    b_blocknr_t *allocated_blocks; // Pointer to a place where allocated blocknumbers would be stored.
-    reiserfs_blocknr_hint_t hint; // hint structure for block allocator.
-    size_t res; // return value of various functions that we call.
-    int curr_block; // current block used to keep track of unmapped blocks.
-    int i; // loop counter
-    int itempos; // position in item
-    unsigned int from = (pos & (PAGE_CACHE_SIZE - 1)); // writing position in
-						       // first page
-    unsigned int to = ((pos + write_bytes - 1) & (PAGE_CACHE_SIZE - 1)) + 1; /* last modified byte offset in last page */
-    __u64 hole_size ; // amount of blocks for a file hole, if it needed to be created.
-    int modifying_this_item = 0; // Flag for items traversal code to keep track
-				 // of the fact that we already prepared
-				 // current block for journal
-    int will_prealloc = 0;
-    RFALSE(!blocks_to_allocate, "green-9004: tried to allocate zero blocks?");
-
-    /* only preallocate if this is a small write */
-    if (REISERFS_I(inode)->i_prealloc_count ||
-       (!(write_bytes & (inode->i_sb->s_blocksize -1)) &&
-        blocks_to_allocate <
-        REISERFS_SB(inode->i_sb)->s_alloc_options.preallocsize))
-        will_prealloc = REISERFS_SB(inode->i_sb)->s_alloc_options.preallocsize;
-
-    allocated_blocks = kmalloc((blocks_to_allocate + will_prealloc) *
-    					sizeof(b_blocknr_t), GFP_NOFS);
-
-    /* First we compose a key to point at the writing position, we want to do
-       that outside of any locking region. */
-    make_cpu_key (&key, inode, pos+1, TYPE_ANY, 3/*key length*/);
-
-    /* If we came here, it means we absolutely need to open a transaction,
-       since we need to allocate some blocks */
-    reiserfs_write_lock(inode->i_sb); // Journaling stuff and we need that.
-    res = journal_begin(th, inode->i_sb, JOURNAL_PER_BALANCE_CNT * 3 + 1 + 2 * REISERFS_QUOTA_TRANS_BLOCKS); // Wish I know if this number enough
-    if (res)
-        goto error_exit;
-    reiserfs_update_inode_transaction(inode) ;
-
-    /* Look for the in-tree position of our write, need path for block allocator */
-    res = search_for_position_by_key(inode->i_sb, &key, &path);
-    if ( res == IO_ERROR ) {
-	res = -EIO;
-	goto error_exit;
-    }
-   
-    /* Allocate blocks */
-    /* First fill in "hint" structure for block allocator */
-    hint.th = th; // transaction handle.
-    hint.path = &path; // Path, so that block allocator can determine packing locality or whatever it needs to determine.
-    hint.inode = inode; // Inode is needed by block allocator too.
-    hint.search_start = 0; // We have no hint on where to search free blocks for block allocator.
-    hint.key = key.on_disk_key; // on disk key of file.
-    hint.block = inode->i_blocks>>(inode->i_sb->s_blocksize_bits-9); // Number of disk blocks this file occupies already.
-    hint.formatted_node = 0; // We are allocating blocks for unformatted node.
-    hint.preallocate = will_prealloc;
-
-    /* Call block allocator to allocate blocks */
-    res = reiserfs_allocate_blocknrs(&hint, allocated_blocks, blocks_to_allocate, blocks_to_allocate);
-    if ( res != CARRY_ON ) {
-	if ( res == NO_DISK_SPACE ) {
-	    /* We flush the transaction in case of no space. This way some
-	       blocks might become free */
-	    SB_JOURNAL(inode->i_sb)->j_must_wait = 1;
-	    res = restart_transaction(th, inode, &path);
-            if (res)
-                goto error_exit;
-
-	    /* We might have scheduled, so search again */
-	    res = search_for_position_by_key(inode->i_sb, &key, &path);
-	    if ( res == IO_ERROR ) {
-		res = -EIO;
+	struct cpu_key key;	// cpu key of item that we are going to deal with
+	struct item_head *ih;	// pointer to item head that we are going to deal with
+	struct buffer_head *bh;	// Buffer head that contains items that we are going to deal with
+	__le32 *item;		// pointer to item we are going to deal with
+	INITIALIZE_PATH(path);	// path to item, that we are going to deal with.
+	b_blocknr_t *allocated_blocks;	// Pointer to a place where allocated blocknumbers would be stored.
+	reiserfs_blocknr_hint_t hint;	// hint structure for block allocator.
+	size_t res;		// return value of various functions that we call.
+	int curr_block;		// current block used to keep track of unmapped blocks.
+	int i;			// loop counter
+	int itempos;		// position in item
+	unsigned int from = (pos & (PAGE_CACHE_SIZE - 1));	// writing position in
+	// first page
+	unsigned int to = ((pos + write_bytes - 1) & (PAGE_CACHE_SIZE - 1)) + 1;	/* last modified byte offset in last page */
+	__u64 hole_size;	// amount of blocks for a file hole, if it needed to be created.
+	int modifying_this_item = 0;	// Flag for items traversal code to keep track
+	// of the fact that we already prepared
+	// current block for journal
+	int will_prealloc = 0;
+	RFALSE(!blocks_to_allocate,
+	       "green-9004: tried to allocate zero blocks?");
+
+	/* only preallocate if this is a small write */
+	if (REISERFS_I(inode)->i_prealloc_count ||
+	    (!(write_bytes & (inode->i_sb->s_blocksize - 1)) &&
+	     blocks_to_allocate <
+	     REISERFS_SB(inode->i_sb)->s_alloc_options.preallocsize))
+		will_prealloc =
+		    REISERFS_SB(inode->i_sb)->s_alloc_options.preallocsize;
+
+	allocated_blocks = kmalloc((blocks_to_allocate + will_prealloc) *
+				   sizeof(b_blocknr_t), GFP_NOFS);
+
+	/* First we compose a key to point at the writing position, we want to do
+	   that outside of any locking region. */
+	make_cpu_key(&key, inode, pos + 1, TYPE_ANY, 3 /*key length */ );
+
+	/* If we came here, it means we absolutely need to open a transaction,
+	   since we need to allocate some blocks */
+	reiserfs_write_lock(inode->i_sb);	// Journaling stuff and we need that.
+	res = journal_begin(th, inode->i_sb, JOURNAL_PER_BALANCE_CNT * 3 + 1 + 2 * REISERFS_QUOTA_TRANS_BLOCKS(inode->i_sb));	// Wish I know if this number enough
+	if (res)
 		goto error_exit;
-	    }
+	reiserfs_update_inode_transaction(inode);
 
-	    /* update changed info for hint structure. */
-	    res = reiserfs_allocate_blocknrs(&hint, allocated_blocks, blocks_to_allocate, blocks_to_allocate);
-	    if ( res != CARRY_ON ) {
-		res = -ENOSPC; 
-		pathrelse(&path);
+	/* Look for the in-tree position of our write, need path for block allocator */
+	res = search_for_position_by_key(inode->i_sb, &key, &path);
+	if (res == IO_ERROR) {
+		res = -EIO;
 		goto error_exit;
-	    }
-	} else {
-	    res = -ENOSPC;
-	    pathrelse(&path);
-	    goto error_exit;
 	}
-    }
 
+	/* Allocate blocks */
+	/* First fill in "hint" structure for block allocator */
+	hint.th = th;		// transaction handle.
+	hint.path = &path;	// Path, so that block allocator can determine packing locality or whatever it needs to determine.
+	hint.inode = inode;	// Inode is needed by block allocator too.
+	hint.search_start = 0;	// We have no hint on where to search free blocks for block allocator.
+	hint.key = key.on_disk_key;	// on disk key of file.
+	hint.block = inode->i_blocks >> (inode->i_sb->s_blocksize_bits - 9);	// Number of disk blocks this file occupies already.
+	hint.formatted_node = 0;	// We are allocating blocks for unformatted node.
+	hint.preallocate = will_prealloc;
+
+	/* Call block allocator to allocate blocks */
+	res =
+	    reiserfs_allocate_blocknrs(&hint, allocated_blocks,
+				       blocks_to_allocate, blocks_to_allocate);
+	if (res != CARRY_ON) {
+		if (res == NO_DISK_SPACE) {
+			/* We flush the transaction in case of no space. This way some
+			   blocks might become free */
+			SB_JOURNAL(inode->i_sb)->j_must_wait = 1;
+			res = restart_transaction(th, inode, &path);
+			if (res)
+				goto error_exit;
+
+			/* We might have scheduled, so search again */
+			res =
+			    search_for_position_by_key(inode->i_sb, &key,
+						       &path);
+			if (res == IO_ERROR) {
+				res = -EIO;
+				goto error_exit;
+			}
+
+			/* update changed info for hint structure. */
+			res =
+			    reiserfs_allocate_blocknrs(&hint, allocated_blocks,
+						       blocks_to_allocate,
+						       blocks_to_allocate);
+			if (res != CARRY_ON) {
+				res = -ENOSPC;
+				pathrelse(&path);
+				goto error_exit;
+			}
+		} else {
+			res = -ENOSPC;
+			pathrelse(&path);
+			goto error_exit;
+		}
+	}
 #ifdef __BIG_ENDIAN
-        // Too bad, I have not found any way to convert a given region from
-        // cpu format to little endian format
-    {
-        int i;
-        for ( i = 0; i < blocks_to_allocate ; i++)
-            allocated_blocks[i]=cpu_to_le32(allocated_blocks[i]);
-    }
+	// Too bad, I have not found any way to convert a given region from
+	// cpu format to little endian format
+	{
+		int i;
+		for (i = 0; i < blocks_to_allocate; i++)
+			allocated_blocks[i] = cpu_to_le32(allocated_blocks[i]);
+	}
 #endif
 
-    /* Blocks allocating well might have scheduled and tree might have changed,
-       let's search the tree again */
-    /* find where in the tree our write should go */
-    res = search_for_position_by_key(inode->i_sb, &key, &path);
-    if ( res == IO_ERROR ) {
-	res = -EIO;
-	goto error_exit_free_blocks;
-    }
-
-    bh = get_last_bh( &path ); // Get a bufferhead for last element in path.
-    ih = get_ih( &path );      // Get a pointer to last item head in path.
-    item = get_item( &path );  // Get a pointer to last item in path
-
-    /* Let's see what we have found */
-    if ( res != POSITION_FOUND ) { /* position not found, this means that we
-				      might need to append file with holes
-				      first */
-	// Since we are writing past the file's end, we need to find out if
-	// there is a hole that needs to be inserted before our writing
-	// position, and how many blocks it is going to cover (we need to
-	//  populate pointers to file blocks representing the hole with zeros)
-
-	{
-	    int item_offset = 1;
-	    /*
-	     * if ih is stat data, its offset is 0 and we don't want to
-	     * add 1 to pos in the hole_size calculation
-	     */
-	    if (is_statdata_le_ih(ih))
-	        item_offset = 0;
-	    hole_size = (pos + item_offset -
-	            (le_key_k_offset( get_inode_item_key_version(inode),
-		    &(ih->ih_key)) +
-		    op_bytes_number(ih, inode->i_sb->s_blocksize))) >>
-		    inode->i_sb->s_blocksize_bits;
-	}
-
-	if ( hole_size > 0 ) {
-	    int to_paste = min_t(__u64, hole_size, MAX_ITEM_LEN(inode->i_sb->s_blocksize)/UNFM_P_SIZE ); // How much data to insert first time.
-	    /* area filled with zeroes, to supply as list of zero blocknumbers
-	       We allocate it outside of loop just in case loop would spin for
-	       several iterations. */
-	    char *zeros = kmalloc(to_paste*UNFM_P_SIZE, GFP_ATOMIC); // We cannot insert more than MAX_ITEM_LEN bytes anyway.
-	    if ( !zeros ) {
-		res = -ENOMEM;
+	/* Blocks allocating well might have scheduled and tree might have changed,
+	   let's search the tree again */
+	/* find where in the tree our write should go */
+	res = search_for_position_by_key(inode->i_sb, &key, &path);
+	if (res == IO_ERROR) {
+		res = -EIO;
 		goto error_exit_free_blocks;
-	    }
-	    memset ( zeros, 0, to_paste*UNFM_P_SIZE);
-	    do {
-		to_paste = min_t(__u64, hole_size, MAX_ITEM_LEN(inode->i_sb->s_blocksize)/UNFM_P_SIZE );
-		if ( is_indirect_le_ih(ih) ) {
-		    /* Ok, there is existing indirect item already. Need to append it */
-		    /* Calculate position past inserted item */
-		    make_cpu_key( &key, inode, le_key_k_offset( get_inode_item_key_version(inode), &(ih->ih_key)) + op_bytes_number(ih, inode->i_sb->s_blocksize), TYPE_INDIRECT, 3);
-		    res = reiserfs_paste_into_item( th, &path, &key, inode, (char *)zeros, UNFM_P_SIZE*to_paste);
-		    if ( res ) {
+	}
+
+	bh = get_last_bh(&path);	// Get a bufferhead for last element in path.
+	ih = get_ih(&path);	// Get a pointer to last item head in path.
+	item = get_item(&path);	// Get a pointer to last item in path
+
+	/* Let's see what we have found */
+	if (res != POSITION_FOUND) {	/* position not found, this means that we
+					   might need to append file with holes
+					   first */
+		// Since we are writing past the file's end, we need to find out if
+		// there is a hole that needs to be inserted before our writing
+		// position, and how many blocks it is going to cover (we need to
+		//  populate pointers to file blocks representing the hole with zeros)
+
+		{
+			int item_offset = 1;
+			/*
+			 * if ih is stat data, its offset is 0 and we don't want to
+			 * add 1 to pos in the hole_size calculation
+			 */
+			if (is_statdata_le_ih(ih))
+				item_offset = 0;
+			hole_size = (pos + item_offset -
+				     (le_key_k_offset
+				      (get_inode_item_key_version(inode),
+				       &(ih->ih_key)) + op_bytes_number(ih,
+									inode->
+									i_sb->
+									s_blocksize)))
+			    >> inode->i_sb->s_blocksize_bits;
+		}
+
+		if (hole_size > 0) {
+			int to_paste = min_t(__u64, hole_size, MAX_ITEM_LEN(inode->i_sb->s_blocksize) / UNFM_P_SIZE);	// How much data to insert first time.
+			/* area filled with zeroes, to supply as list of zero blocknumbers
+			   We allocate it outside of loop just in case loop would spin for
+			   several iterations. */
+			char *zeros = kmalloc(to_paste * UNFM_P_SIZE, GFP_ATOMIC);	// We cannot insert more than MAX_ITEM_LEN bytes anyway.
+			if (!zeros) {
+				res = -ENOMEM;
+				goto error_exit_free_blocks;
+			}
+			memset(zeros, 0, to_paste * UNFM_P_SIZE);
+			do {
+				to_paste =
+				    min_t(__u64, hole_size,
+					  MAX_ITEM_LEN(inode->i_sb->
+						       s_blocksize) /
+					  UNFM_P_SIZE);
+				if (is_indirect_le_ih(ih)) {
+					/* Ok, there is existing indirect item already. Need to append it */
+					/* Calculate position past inserted item */
+					make_cpu_key(&key, inode,
+						     le_key_k_offset
+						     (get_inode_item_key_version
+						      (inode),
+						      &(ih->ih_key)) +
+						     op_bytes_number(ih,
+								     inode->
+								     i_sb->
+								     s_blocksize),
+						     TYPE_INDIRECT, 3);
+					res =
+					    reiserfs_paste_into_item(th, &path,
+								     &key,
+								     inode,
+								     (char *)
+								     zeros,
+								     UNFM_P_SIZE
+								     *
+								     to_paste);
+					if (res) {
+						kfree(zeros);
+						goto error_exit_free_blocks;
+					}
+				} else if (is_statdata_le_ih(ih)) {
+					/* No existing item, create it */
+					/* item head for new item */
+					struct item_head ins_ih;
+
+					/* create a key for our new item */
+					make_cpu_key(&key, inode, 1,
+						     TYPE_INDIRECT, 3);
+
+					/* Create new item head for our new item */
+					make_le_item_head(&ins_ih, &key,
+							  key.version, 1,
+							  TYPE_INDIRECT,
+							  to_paste *
+							  UNFM_P_SIZE,
+							  0 /* free space */ );
+
+					/* Find where such item should live in the tree */
+					res =
+					    search_item(inode->i_sb, &key,
+							&path);
+					if (res != ITEM_NOT_FOUND) {
+						/* item should not exist, otherwise we have error */
+						if (res != -ENOSPC) {
+							reiserfs_warning(inode->
+									 i_sb,
+									 "green-9008: search_by_key (%K) returned %d",
+									 &key,
+									 res);
+						}
+						res = -EIO;
+						kfree(zeros);
+						goto error_exit_free_blocks;
+					}
+					res =
+					    reiserfs_insert_item(th, &path,
+								 &key, &ins_ih,
+								 inode,
+								 (char *)zeros);
+				} else {
+					reiserfs_panic(inode->i_sb,
+						       "green-9011: Unexpected key type %K\n",
+						       &key);
+				}
+				if (res) {
+					kfree(zeros);
+					goto error_exit_free_blocks;
+				}
+				/* Now we want to check if transaction is too full, and if it is
+				   we restart it. This will also free the path. */
+				if (journal_transaction_should_end
+				    (th, th->t_blocks_allocated)) {
+					res =
+					    restart_transaction(th, inode,
+								&path);
+					if (res) {
+						pathrelse(&path);
+						kfree(zeros);
+						goto error_exit;
+					}
+				}
+
+				/* Well, need to recalculate path and stuff */
+				set_cpu_key_k_offset(&key,
+						     cpu_key_k_offset(&key) +
+						     (to_paste << inode->
+						      i_blkbits));
+				res =
+				    search_for_position_by_key(inode->i_sb,
+							       &key, &path);
+				if (res == IO_ERROR) {
+					res = -EIO;
+					kfree(zeros);
+					goto error_exit_free_blocks;
+				}
+				bh = get_last_bh(&path);
+				ih = get_ih(&path);
+				item = get_item(&path);
+				hole_size -= to_paste;
+			} while (hole_size);
 			kfree(zeros);
-			goto error_exit_free_blocks;
-		    }
-		} else if ( is_statdata_le_ih(ih) ) {
-		    /* No existing item, create it */
-		    /* item head for new item */
-		    struct item_head ins_ih;
-
-		    /* create a key for our new item */
-		    make_cpu_key( &key, inode, 1, TYPE_INDIRECT, 3);
-
-		    /* Create new item head for our new item */
-		    make_le_item_head (&ins_ih, &key, key.version, 1,
-				       TYPE_INDIRECT, to_paste*UNFM_P_SIZE,
-				       0 /* free space */);
-
-		    /* Find where such item should live in the tree */
-		    res = search_item (inode->i_sb, &key, &path);
-		    if ( res != ITEM_NOT_FOUND ) {
-			/* item should not exist, otherwise we have error */
-			if ( res != -ENOSPC ) {
-			    reiserfs_warning (inode->i_sb,
-				"green-9008: search_by_key (%K) returned %d",
-					      &key, res);
+		}
+	}
+	// Go through existing indirect items first
+	// replace all zeroes with blocknumbers from list
+	// Note that if no corresponding item was found, by previous search,
+	// it means there are no existing in-tree representation for file area
+	// we are going to overwrite, so there is nothing to scan through for holes.
+	for (curr_block = 0, itempos = path.pos_in_item;
+	     curr_block < blocks_to_allocate && res == POSITION_FOUND;) {
+	      retry:
+
+		if (itempos >= ih_item_len(ih) / UNFM_P_SIZE) {
+			/* We run out of data in this indirect item, let's look for another
+			   one. */
+			/* First if we are already modifying current item, log it */
+			if (modifying_this_item) {
+				journal_mark_dirty(th, inode->i_sb, bh);
+				modifying_this_item = 0;
 			}
-			res = -EIO;
-		        kfree(zeros);
-			goto error_exit_free_blocks;
-		    }
-		    res = reiserfs_insert_item( th, &path, &key, &ins_ih, inode, (char *)zeros);
+			/* Then set the key to look for a new indirect item (offset of old
+			   item is added to old item length */
+			set_cpu_key_k_offset(&key,
+					     le_key_k_offset
+					     (get_inode_item_key_version(inode),
+					      &(ih->ih_key)) +
+					     op_bytes_number(ih,
+							     inode->i_sb->
+							     s_blocksize));
+			/* Search ofor position of new key in the tree. */
+			res =
+			    search_for_position_by_key(inode->i_sb, &key,
+						       &path);
+			if (res == IO_ERROR) {
+				res = -EIO;
+				goto error_exit_free_blocks;
+			}
+			bh = get_last_bh(&path);
+			ih = get_ih(&path);
+			item = get_item(&path);
+			itempos = path.pos_in_item;
+			continue;	// loop to check all kinds of conditions and so on.
+		}
+		/* Ok, we have correct position in item now, so let's see if it is
+		   representing file hole (blocknumber is zero) and fill it if needed */
+		if (!item[itempos]) {
+			/* Ok, a hole. Now we need to check if we already prepared this
+			   block to be journaled */
+			while (!modifying_this_item) {	// loop until succeed
+				/* Well, this item is not journaled yet, so we must prepare
+				   it for journal first, before we can change it */
+				struct item_head tmp_ih;	// We copy item head of found item,
+				// here to detect if fs changed under
+				// us while we were preparing for
+				// journal.
+				int fs_gen;	// We store fs generation here to find if someone
+				// changes fs under our feet
+
+				copy_item_head(&tmp_ih, ih);	// Remember itemhead
+				fs_gen = get_generation(inode->i_sb);	// remember fs generation
+				reiserfs_prepare_for_journal(inode->i_sb, bh, 1);	// Prepare a buffer within which indirect item is stored for changing.
+				if (fs_changed(fs_gen, inode->i_sb)
+				    && item_moved(&tmp_ih, &path)) {
+					// Sigh, fs was changed under us, we need to look for new
+					// location of item we are working with
+
+					/* unmark prepaerd area as journaled and search for it's
+					   new position */
+					reiserfs_restore_prepared_buffer(inode->
+									 i_sb,
+									 bh);
+					res =
+					    search_for_position_by_key(inode->
+								       i_sb,
+								       &key,
+								       &path);
+					if (res == IO_ERROR) {
+						res = -EIO;
+						goto error_exit_free_blocks;
+					}
+					bh = get_last_bh(&path);
+					ih = get_ih(&path);
+					item = get_item(&path);
+					itempos = path.pos_in_item;
+					goto retry;
+				}
+				modifying_this_item = 1;
+			}
+			item[itempos] = allocated_blocks[curr_block];	// Assign new block
+			curr_block++;
+		}
+		itempos++;
+	}
+
+	if (modifying_this_item) {	// We need to log last-accessed block, if it
+		// was modified, but not logged yet.
+		journal_mark_dirty(th, inode->i_sb, bh);
+	}
+
+	if (curr_block < blocks_to_allocate) {
+		// Oh, well need to append to indirect item, or to create indirect item
+		// if there weren't any
+		if (is_indirect_le_ih(ih)) {
+			// Existing indirect item - append. First calculate key for append
+			// position. We do not need to recalculate path as it should
+			// already point to correct place.
+			make_cpu_key(&key, inode,
+				     le_key_k_offset(get_inode_item_key_version
+						     (inode),
+						     &(ih->ih_key)) +
+				     op_bytes_number(ih,
+						     inode->i_sb->s_blocksize),
+				     TYPE_INDIRECT, 3);
+			res =
+			    reiserfs_paste_into_item(th, &path, &key, inode,
+						     (char *)(allocated_blocks +
+							      curr_block),
+						     UNFM_P_SIZE *
+						     (blocks_to_allocate -
+						      curr_block));
+			if (res) {
+				goto error_exit_free_blocks;
+			}
+		} else if (is_statdata_le_ih(ih)) {
+			// Last found item was statdata. That means we need to create indirect item.
+			struct item_head ins_ih;	/* itemhead for new item */
+
+			/* create a key for our new item */
+			make_cpu_key(&key, inode, 1, TYPE_INDIRECT, 3);	// Position one,
+			// because that's
+			// where first
+			// indirect item
+			// begins
+			/* Create new item head for our new item */
+			make_le_item_head(&ins_ih, &key, key.version, 1,
+					  TYPE_INDIRECT,
+					  (blocks_to_allocate -
+					   curr_block) * UNFM_P_SIZE,
+					  0 /* free space */ );
+			/* Find where such item should live in the tree */
+			res = search_item(inode->i_sb, &key, &path);
+			if (res != ITEM_NOT_FOUND) {
+				/* Well, if we have found such item already, or some error
+				   occured, we need to warn user and return error */
+				if (res != -ENOSPC) {
+					reiserfs_warning(inode->i_sb,
+							 "green-9009: search_by_key (%K) "
+							 "returned %d", &key,
+							 res);
+				}
+				res = -EIO;
+				goto error_exit_free_blocks;
+			}
+			/* Insert item into the tree with the data as its body */
+			res =
+			    reiserfs_insert_item(th, &path, &key, &ins_ih,
+						 inode,
+						 (char *)(allocated_blocks +
+							  curr_block));
 		} else {
-		    reiserfs_panic(inode->i_sb, "green-9011: Unexpected key type %K\n", &key);
+			reiserfs_panic(inode->i_sb,
+				       "green-9010: unexpected item type for key %K\n",
+				       &key);
 		}
-		if ( res ) {
-		    kfree(zeros);
-		    goto error_exit_free_blocks;
-		}
-		/* Now we want to check if transaction is too full, and if it is
-		   we restart it. This will also free the path. */
-		if (journal_transaction_should_end(th, th->t_blocks_allocated)) {
-		    res = restart_transaction(th, inode, &path);
-                    if (res) {
-                        pathrelse (&path);
-                        kfree(zeros);
-                        goto error_exit;
-                    }
-                }
-
-		/* Well, need to recalculate path and stuff */
-		set_cpu_key_k_offset( &key, cpu_key_k_offset(&key) + (to_paste << inode->i_blkbits));
-		res = search_for_position_by_key(inode->i_sb, &key, &path);
-		if ( res == IO_ERROR ) {
-		    res = -EIO;
-		    kfree(zeros);
-		    goto error_exit_free_blocks;
-		}
-		bh=get_last_bh(&path);
-		ih=get_ih(&path);
-		item = get_item(&path);
-		hole_size -= to_paste;
-	    } while ( hole_size );
-	    kfree(zeros);
-	}
-    }
-
-    // Go through existing indirect items first
-    // replace all zeroes with blocknumbers from list
-    // Note that if no corresponding item was found, by previous search,
-    // it means there are no existing in-tree representation for file area
-    // we are going to overwrite, so there is nothing to scan through for holes.
-    for ( curr_block = 0, itempos = path.pos_in_item ; curr_block < blocks_to_allocate && res == POSITION_FOUND ; ) {
-retry:
-
-	if ( itempos >= ih_item_len(ih)/UNFM_P_SIZE ) {
-	    /* We run out of data in this indirect item, let's look for another
-	       one. */
-	    /* First if we are already modifying current item, log it */
-	    if ( modifying_this_item ) {
-		journal_mark_dirty (th, inode->i_sb, bh);
-		modifying_this_item = 0;
-	    }
-	    /* Then set the key to look for a new indirect item (offset of old
-	       item is added to old item length */
-	    set_cpu_key_k_offset( &key, le_key_k_offset( get_inode_item_key_version(inode), &(ih->ih_key)) + op_bytes_number(ih, inode->i_sb->s_blocksize));
-	    /* Search ofor position of new key in the tree. */
-	    res = search_for_position_by_key(inode->i_sb, &key, &path);
-	    if ( res == IO_ERROR) {
-		res = -EIO;
-		goto error_exit_free_blocks;
-	    }
-	    bh=get_last_bh(&path);
-	    ih=get_ih(&path);
-	    item = get_item(&path);
-	    itempos = path.pos_in_item;
-	    continue; // loop to check all kinds of conditions and so on.
-	}
-	/* Ok, we have correct position in item now, so let's see if it is
-	   representing file hole (blocknumber is zero) and fill it if needed */
-	if ( !item[itempos] ) {
-	    /* Ok, a hole. Now we need to check if we already prepared this
-	       block to be journaled */
-	    while ( !modifying_this_item ) { // loop until succeed
-		/* Well, this item is not journaled yet, so we must prepare
-		   it for journal first, before we can change it */
-		struct item_head tmp_ih; // We copy item head of found item,
-					 // here to detect if fs changed under
-					 // us while we were preparing for
-					 // journal.
-		int fs_gen; // We store fs generation here to find if someone
-			    // changes fs under our feet
-
-		copy_item_head (&tmp_ih, ih); // Remember itemhead
-		fs_gen = get_generation (inode->i_sb); // remember fs generation
-		reiserfs_prepare_for_journal(inode->i_sb, bh, 1); // Prepare a buffer within which indirect item is stored for changing.
-		if (fs_changed (fs_gen, inode->i_sb) && item_moved (&tmp_ih, &path)) {
-		    // Sigh, fs was changed under us, we need to look for new
-		    // location of item we are working with
-
-		    /* unmark prepaerd area as journaled and search for it's
-		       new position */
-		    reiserfs_restore_prepared_buffer(inode->i_sb, bh);
-		    res = search_for_position_by_key(inode->i_sb, &key, &path);
-		    if ( res == IO_ERROR) {
-			res = -EIO;
-			goto error_exit_free_blocks;
-		    }
-		    bh=get_last_bh(&path);
-		    ih=get_ih(&path);
-		    item = get_item(&path);
-		    itempos = path.pos_in_item;
-		    goto retry;
-		}
-		modifying_this_item = 1;
-	    }
-	    item[itempos] = allocated_blocks[curr_block]; // Assign new block
-	    curr_block++;
-	}
-	itempos++;
-    }
-
-    if ( modifying_this_item ) { // We need to log last-accessed block, if it
-				 // was modified, but not logged yet.
-	journal_mark_dirty (th, inode->i_sb, bh);
-    }
-
-    if ( curr_block < blocks_to_allocate ) {
-	// Oh, well need to append to indirect item, or to create indirect item
-	// if there weren't any
-	if ( is_indirect_le_ih(ih) ) {
-	    // Existing indirect item - append. First calculate key for append
-	    // position. We do not need to recalculate path as it should
-	    // already point to correct place.
-	    make_cpu_key( &key, inode, le_key_k_offset( get_inode_item_key_version(inode), &(ih->ih_key)) + op_bytes_number(ih, inode->i_sb->s_blocksize), TYPE_INDIRECT, 3);
-	    res = reiserfs_paste_into_item( th, &path, &key, inode, (char *)(allocated_blocks+curr_block), UNFM_P_SIZE*(blocks_to_allocate-curr_block));
-	    if ( res ) {
-		goto error_exit_free_blocks;
-	    }
-	} else if (is_statdata_le_ih(ih) ) {
-	    // Last found item was statdata. That means we need to create indirect item.
-	    struct item_head ins_ih; /* itemhead for new item */
-
-	    /* create a key for our new item */
-	    make_cpu_key( &key, inode, 1, TYPE_INDIRECT, 3); // Position one,
-							    // because that's
-							    // where first
-							    // indirect item
-							    // begins
-	    /* Create new item head for our new item */
-	    make_le_item_head (&ins_ih, &key, key.version, 1, TYPE_INDIRECT,
-			       (blocks_to_allocate-curr_block)*UNFM_P_SIZE,
-			       0 /* free space */);
-	    /* Find where such item should live in the tree */
-	    res = search_item (inode->i_sb, &key, &path);
-	    if ( res != ITEM_NOT_FOUND ) {
-		/* Well, if we have found such item already, or some error
-		   occured, we need to warn user and return error */
-		if ( res != -ENOSPC ) {
-		    reiserfs_warning (inode->i_sb,
-				      "green-9009: search_by_key (%K) "
-				      "returned %d", &key, res);
+	}
+	// the caller is responsible for closing the transaction
+	// unless we return an error, they are also responsible for logging
+	// the inode.
+	//
+	pathrelse(&path);
+	/*
+	 * cleanup prellocation from previous writes
+	 * if this is a partial block write
+	 */
+	if (write_bytes & (inode->i_sb->s_blocksize - 1))
+		reiserfs_discard_prealloc(th, inode);
+	reiserfs_write_unlock(inode->i_sb);
+
+	// go through all the pages/buffers and map the buffers to newly allocated
+	// blocks (so that system knows where to write these pages later).
+	curr_block = 0;
+	for (i = 0; i < num_pages; i++) {
+		struct page *page = prepared_pages[i];	//current page
+		struct buffer_head *head = page_buffers(page);	// first buffer for a page
+		int block_start, block_end;	// in-page offsets for buffers.
+
+		if (!page_buffers(page))
+			reiserfs_panic(inode->i_sb,
+				       "green-9005: No buffers for prepared page???");
+
+		/* For each buffer in page */
+		for (bh = head, block_start = 0; bh != head || !block_start;
+		     block_start = block_end, bh = bh->b_this_page) {
+			if (!bh)
+				reiserfs_panic(inode->i_sb,
+					       "green-9006: Allocated but absent buffer for a page?");
+			block_end = block_start + inode->i_sb->s_blocksize;
+			if (i == 0 && block_end <= from)
+				/* if this buffer is before requested data to map, skip it */
+				continue;
+			if (i == num_pages - 1 && block_start >= to)
+				/* If this buffer is after requested data to map, abort
+				   processing of current page */
+				break;
+
+			if (!buffer_mapped(bh)) {	// Ok, unmapped buffer, need to map it
+				map_bh(bh, inode->i_sb,
+				       le32_to_cpu(allocated_blocks
+						   [curr_block]));
+				curr_block++;
+				set_buffer_new(bh);
+			}
 		}
-		res = -EIO;
-		goto error_exit_free_blocks;
-	    }
-	    /* Insert item into the tree with the data as its body */
-	    res = reiserfs_insert_item( th, &path, &key, &ins_ih, inode, (char *)(allocated_blocks+curr_block));
-	} else {
-	    reiserfs_panic(inode->i_sb, "green-9010: unexpected item type for key %K\n",&key);
-	}
-    }
-
-    // the caller is responsible for closing the transaction
-    // unless we return an error, they are also responsible for logging
-    // the inode.
-    //
-    pathrelse(&path);
-    /*
-     * cleanup prellocation from previous writes
-     * if this is a partial block write
-     */
-    if (write_bytes & (inode->i_sb->s_blocksize -1))
-        reiserfs_discard_prealloc(th, inode);
-    reiserfs_write_unlock(inode->i_sb);
-
-    // go through all the pages/buffers and map the buffers to newly allocated
-    // blocks (so that system knows where to write these pages later).
-    curr_block = 0;
-    for ( i = 0; i < num_pages ; i++ ) {
-	struct page *page=prepared_pages[i]; //current page
-	struct buffer_head *head = page_buffers(page);// first buffer for a page
-	int block_start, block_end; // in-page offsets for buffers.
-
-	if (!page_buffers(page))
-	    reiserfs_panic(inode->i_sb, "green-9005: No buffers for prepared page???");
-
-	/* For each buffer in page */
-	for(bh = head, block_start = 0; bh != head || !block_start;
-	    block_start=block_end, bh = bh->b_this_page) {
-	    if (!bh)
-		reiserfs_panic(inode->i_sb, "green-9006: Allocated but absent buffer for a page?");
-	    block_end = block_start+inode->i_sb->s_blocksize;
-	    if (i == 0 && block_end <= from )
-		/* if this buffer is before requested data to map, skip it */
-		continue;
-	    if (i == num_pages - 1 && block_start >= to)
-		/* If this buffer is after requested data to map, abort
-		   processing of current page */
-		break;
-
-	    if ( !buffer_mapped(bh) ) { // Ok, unmapped buffer, need to map it
-		map_bh( bh, inode->i_sb, le32_to_cpu(allocated_blocks[curr_block]));
-		curr_block++;
-		set_buffer_new(bh);
-	    }
 	}
-    }
 
-    RFALSE( curr_block > blocks_to_allocate, "green-9007: Used too many blocks? weird");
+	RFALSE(curr_block > blocks_to_allocate,
+	       "green-9007: Used too many blocks? weird");
 
-    kfree(allocated_blocks);
-    return 0;
+	kfree(allocated_blocks);
+	return 0;
 
 // Need to deal with transaction here.
-error_exit_free_blocks:
-    pathrelse(&path);
-    // free blocks
-    for( i = 0; i < blocks_to_allocate; i++ )
-	reiserfs_free_block(th, inode, le32_to_cpu(allocated_blocks[i]), 1);
-
-error_exit:
-    if (th->t_trans_id) {
-        int err;
-        // update any changes we made to blk count
-        reiserfs_update_sd(th, inode);
-        err = journal_end(th, inode->i_sb, JOURNAL_PER_BALANCE_CNT * 3 + 1 + 2 * REISERFS_QUOTA_TRANS_BLOCKS);
-        if (err)
-            res = err;
-    }
-    reiserfs_write_unlock(inode->i_sb);
-    kfree(allocated_blocks);
+      error_exit_free_blocks:
+	pathrelse(&path);
+	// free blocks
+	for (i = 0; i < blocks_to_allocate; i++)
+		reiserfs_free_block(th, inode, le32_to_cpu(allocated_blocks[i]),
+				    1);
+
+      error_exit:
+	if (th->t_trans_id) {
+		int err;
+		// update any changes we made to blk count
+		reiserfs_update_sd(th, inode);
+		err =
+		    journal_end(th, inode->i_sb,
+				JOURNAL_PER_BALANCE_CNT * 3 + 1 +
+				2 * REISERFS_QUOTA_TRANS_BLOCKS(inode->i_sb));
+		if (err)
+			res = err;
+	}
+	reiserfs_write_unlock(inode->i_sb);
+	kfree(allocated_blocks);
 
-    return res;
+	return res;
 }
 
 /* Unlock pages prepared by reiserfs_prepare_file_region_for_write */
-static void reiserfs_unprepare_pages(struct page **prepared_pages, /* list of locked pages */
-			      size_t num_pages /* amount of pages */) {
-    int i; // loop counter
-
-    for (i=0; i < num_pages ; i++) {
-	struct page *page = prepared_pages[i];
-
-	try_to_free_buffers(page);
-	unlock_page(page);
-	page_cache_release(page);
-    }
+static void reiserfs_unprepare_pages(struct page **prepared_pages,	/* list of locked pages */
+				     size_t num_pages /* amount of pages */ )
+{
+	int i;			// loop counter
+
+	for (i = 0; i < num_pages; i++) {
+		struct page *page = prepared_pages[i];
+
+		try_to_free_buffers(page);
+		unlock_page(page);
+		page_cache_release(page);
+	}
 }
 
 /* This function will copy data from userspace to specified pages within
    supplied byte range */
-static int reiserfs_copy_from_user_to_file_region(
-				loff_t pos, /* In-file position */
-				int num_pages, /* Number of pages affected */
-				int write_bytes, /* Amount of bytes to write */
-				struct page **prepared_pages, /* pointer to 
-								 array to
-								 prepared pages
-								*/
-				const char __user *buf /* Pointer to user-supplied
-						   data*/
-				)
+static int reiserfs_copy_from_user_to_file_region(loff_t pos,	/* In-file position */
+						  int num_pages,	/* Number of pages affected */
+						  int write_bytes,	/* Amount of bytes to write */
+						  struct page **prepared_pages,	/* pointer to 
+										   array to
+										   prepared pages
+										 */
+						  const char __user * buf	/* Pointer to user-supplied
+										   data */
+    )
 {
-    long page_fault=0; // status of copy_from_user.
-    int i; // loop counter.
-    int offset; // offset in page
-
-    for ( i = 0, offset = (pos & (PAGE_CACHE_SIZE-1)); i < num_pages ; i++,offset=0) {
-	size_t count = min_t(size_t,PAGE_CACHE_SIZE-offset,write_bytes); // How much of bytes to write to this page
-	struct page *page=prepared_pages[i]; // Current page we process.
-
-	fault_in_pages_readable( buf, count);
-
-	/* Copy data from userspace to the current page */
-	kmap(page);
-	page_fault = __copy_from_user(page_address(page)+offset, buf, count); // Copy the data.
-	/* Flush processor's dcache for this page */
-	flush_dcache_page(page);
-	kunmap(page);
-	buf+=count;
-	write_bytes-=count;
-
-	if (page_fault)
-	    break; // Was there a fault? abort.
-    }
+	long page_fault = 0;	// status of copy_from_user.
+	int i;			// loop counter.
+	int offset;		// offset in page
+
+	for (i = 0, offset = (pos & (PAGE_CACHE_SIZE - 1)); i < num_pages;
+	     i++, offset = 0) {
+		size_t count = min_t(size_t, PAGE_CACHE_SIZE - offset, write_bytes);	// How much of bytes to write to this page
+		struct page *page = prepared_pages[i];	// Current page we process.
+
+		fault_in_pages_readable(buf, count);
+
+		/* Copy data from userspace to the current page */
+		kmap(page);
+		page_fault = __copy_from_user(page_address(page) + offset, buf, count);	// Copy the data.
+		/* Flush processor's dcache for this page */
+		flush_dcache_page(page);
+		kunmap(page);
+		buf += count;
+		write_bytes -= count;
 
-    return page_fault?-EFAULT:0;
+		if (page_fault)
+			break;	// Was there a fault? abort.
+	}
+
+	return page_fault ? -EFAULT : 0;
 }
 
 /* taken fs/buffer.c:__block_commit_write */
 int reiserfs_commit_page(struct inode *inode, struct page *page,
-		unsigned from, unsigned to)
+			 unsigned from, unsigned to)
 {
-    unsigned block_start, block_end;
-    int partial = 0;
-    unsigned blocksize;
-    struct buffer_head *bh, *head;
-    unsigned long i_size_index = inode->i_size >> PAGE_CACHE_SHIFT;
-    int new;
-    int logit = reiserfs_file_data_log(inode);
-    struct super_block *s = inode->i_sb;
-    int bh_per_page = PAGE_CACHE_SIZE / s->s_blocksize;
-    struct reiserfs_transaction_handle th;
-    int ret = 0;
-
-    th.t_trans_id = 0;
-    blocksize = 1 << inode->i_blkbits;
-
-    if (logit) {
-	reiserfs_write_lock(s);
-	ret = journal_begin(&th, s, bh_per_page + 1);
-	if (ret)
-	    goto drop_write_lock;
-	reiserfs_update_inode_transaction(inode);
-    }
-    for(bh = head = page_buffers(page), block_start = 0;
-        bh != head || !block_start;
-	block_start=block_end, bh = bh->b_this_page)
-    {
-
-	new = buffer_new(bh);
-	clear_buffer_new(bh);
-	block_end = block_start + blocksize;
-	if (block_end <= from || block_start >= to) {
-	    if (!buffer_uptodate(bh))
-		    partial = 1;
-	} else {
-	    set_buffer_uptodate(bh);
-	    if (logit) {
-		reiserfs_prepare_for_journal(s, bh, 1);
-		journal_mark_dirty(&th, s, bh);
-	    } else if (!buffer_dirty(bh)) {
-		mark_buffer_dirty(bh);
-		/* do data=ordered on any page past the end
-		 * of file and any buffer marked BH_New.
-		 */
-		if (reiserfs_data_ordered(inode->i_sb) &&
-		    (new || page->index >= i_size_index)) {
-		    reiserfs_add_ordered_list(inode, bh);
-	        }
-	    }
-	}
-    }
-    if (logit) {
-	ret = journal_end(&th, s, bh_per_page + 1);
-drop_write_lock:
-	reiserfs_write_unlock(s);
-    }
-    /*
-     * If this is a partial write which happened to make all buffers
-     * uptodate then we can optimize away a bogus readpage() for
-     * the next read(). Here we 'discover' whether the page went
-     * uptodate as a result of this (potentially partial) write.
-     */
-    if (!partial)
-	SetPageUptodate(page);
-    return ret;
+	unsigned block_start, block_end;
+	int partial = 0;
+	unsigned blocksize;
+	struct buffer_head *bh, *head;
+	unsigned long i_size_index = inode->i_size >> PAGE_CACHE_SHIFT;
+	int new;
+	int logit = reiserfs_file_data_log(inode);
+	struct super_block *s = inode->i_sb;
+	int bh_per_page = PAGE_CACHE_SIZE / s->s_blocksize;
+	struct reiserfs_transaction_handle th;
+	int ret = 0;
+
+	th.t_trans_id = 0;
+	blocksize = 1 << inode->i_blkbits;
+
+	if (logit) {
+		reiserfs_write_lock(s);
+		ret = journal_begin(&th, s, bh_per_page + 1);
+		if (ret)
+			goto drop_write_lock;
+		reiserfs_update_inode_transaction(inode);
+	}
+	for (bh = head = page_buffers(page), block_start = 0;
+	     bh != head || !block_start;
+	     block_start = block_end, bh = bh->b_this_page) {
+
+		new = buffer_new(bh);
+		clear_buffer_new(bh);
+		block_end = block_start + blocksize;
+		if (block_end <= from || block_start >= to) {
+			if (!buffer_uptodate(bh))
+				partial = 1;
+		} else {
+			set_buffer_uptodate(bh);
+			if (logit) {
+				reiserfs_prepare_for_journal(s, bh, 1);
+				journal_mark_dirty(&th, s, bh);
+			} else if (!buffer_dirty(bh)) {
+				mark_buffer_dirty(bh);
+				/* do data=ordered on any page past the end
+				 * of file and any buffer marked BH_New.
+				 */
+				if (reiserfs_data_ordered(inode->i_sb) &&
+				    (new || page->index >= i_size_index)) {
+					reiserfs_add_ordered_list(inode, bh);
+				}
+			}
+		}
+	}
+	if (logit) {
+		ret = journal_end(&th, s, bh_per_page + 1);
+	      drop_write_lock:
+		reiserfs_write_unlock(s);
+	}
+	/*
+	 * If this is a partial write which happened to make all buffers
+	 * uptodate then we can optimize away a bogus readpage() for
+	 * the next read(). Here we 'discover' whether the page went
+	 * uptodate as a result of this (potentially partial) write.
+	 */
+	if (!partial)
+		SetPageUptodate(page);
+	return ret;
 }
 
-
 /* Submit pages for write. This was separated from actual file copying
    because we might want to allocate block numbers in-between.
    This function assumes that caller will adjust file size to correct value. */
-static int reiserfs_submit_file_region_for_write(
-				struct reiserfs_transaction_handle *th,
-				struct inode *inode,
-				loff_t pos, /* Writing position offset */
-				size_t num_pages, /* Number of pages to write */
-				size_t write_bytes, /* number of bytes to write */
-				struct page **prepared_pages /* list of pages */
-				)
+static int reiserfs_submit_file_region_for_write(struct reiserfs_transaction_handle *th, struct inode *inode, loff_t pos,	/* Writing position offset */
+						 size_t num_pages,	/* Number of pages to write */
+						 size_t write_bytes,	/* number of bytes to write */
+						 struct page **prepared_pages	/* list of pages */
+    )
 {
-    int status; // return status of block_commit_write.
-    int retval = 0; // Return value we are going to return.
-    int i; // loop counter
-    int offset; // Writing offset in page.
-    int orig_write_bytes = write_bytes;
-    int sd_update = 0;
-
-    for ( i = 0, offset = (pos & (PAGE_CACHE_SIZE-1)); i < num_pages ; i++,offset=0) {
-	int count = min_t(int,PAGE_CACHE_SIZE-offset,write_bytes); // How much of bytes to write to this page
-	struct page *page=prepared_pages[i]; // Current page we process.
-
-	status = reiserfs_commit_page(inode, page, offset, offset+count);
-	if ( status )
-	    retval = status; // To not overcomplicate matters We are going to
-			     // submit all the pages even if there was error.
-			     // we only remember error status to report it on
-			     // exit.
-	write_bytes-=count;
-    }
-    /* now that we've gotten all the ordered buffers marked dirty,
-     * we can safely update i_size and close any running transaction
-     */
-    if ( pos + orig_write_bytes > inode->i_size) {
-	inode->i_size = pos + orig_write_bytes; // Set new size
-	/* If the file have grown so much that tail packing is no
-	 * longer possible, reset "need to pack" flag */
-	if ( (have_large_tails (inode->i_sb) &&
-	      inode->i_size > i_block_size (inode)*4) ||
-	     (have_small_tails (inode->i_sb) &&
-	     inode->i_size > i_block_size(inode)) )
-	    REISERFS_I(inode)->i_flags &= ~i_pack_on_close_mask ;
-        else if ( (have_large_tails (inode->i_sb) &&
-	          inode->i_size < i_block_size (inode)*4) ||
-	          (have_small_tails (inode->i_sb) &&
-		  inode->i_size < i_block_size(inode)) )
-	    REISERFS_I(inode)->i_flags |= i_pack_on_close_mask ;
+	int status;		// return status of block_commit_write.
+	int retval = 0;		// Return value we are going to return.
+	int i;			// loop counter
+	int offset;		// Writing offset in page.
+	int orig_write_bytes = write_bytes;
+	int sd_update = 0;
+
+	for (i = 0, offset = (pos & (PAGE_CACHE_SIZE - 1)); i < num_pages;
+	     i++, offset = 0) {
+		int count = min_t(int, PAGE_CACHE_SIZE - offset, write_bytes);	// How much of bytes to write to this page
+		struct page *page = prepared_pages[i];	// Current page we process.
+
+		status =
+		    reiserfs_commit_page(inode, page, offset, offset + count);
+		if (status)
+			retval = status;	// To not overcomplicate matters We are going to
+		// submit all the pages even if there was error.
+		// we only remember error status to report it on
+		// exit.
+		write_bytes -= count;
+	}
+	/* now that we've gotten all the ordered buffers marked dirty,
+	 * we can safely update i_size and close any running transaction
+	 */
+	if (pos + orig_write_bytes > inode->i_size) {
+		inode->i_size = pos + orig_write_bytes;	// Set new size
+		/* If the file have grown so much that tail packing is no
+		 * longer possible, reset "need to pack" flag */
+		if ((have_large_tails(inode->i_sb) &&
+		     inode->i_size > i_block_size(inode) * 4) ||
+		    (have_small_tails(inode->i_sb) &&
+		     inode->i_size > i_block_size(inode)))
+			REISERFS_I(inode)->i_flags &= ~i_pack_on_close_mask;
+		else if ((have_large_tails(inode->i_sb) &&
+			  inode->i_size < i_block_size(inode) * 4) ||
+			 (have_small_tails(inode->i_sb) &&
+			  inode->i_size < i_block_size(inode)))
+			REISERFS_I(inode)->i_flags |= i_pack_on_close_mask;
+
+		if (th->t_trans_id) {
+			reiserfs_write_lock(inode->i_sb);
+			reiserfs_update_sd(th, inode);	// And update on-disk metadata
+			reiserfs_write_unlock(inode->i_sb);
+		} else
+			inode->i_sb->s_op->dirty_inode(inode);
 
+		sd_update = 1;
+	}
 	if (th->t_trans_id) {
-	    reiserfs_write_lock(inode->i_sb);
-	    reiserfs_update_sd(th, inode); // And update on-disk metadata
-	    reiserfs_write_unlock(inode->i_sb);
-	} else
-	    inode->i_sb->s_op->dirty_inode(inode);
-
-        sd_update = 1;
-    }
-    if (th->t_trans_id) {
-	reiserfs_write_lock(inode->i_sb);
-	if (!sd_update)
-	    reiserfs_update_sd(th, inode);
-	status = journal_end(th, th->t_super, th->t_blocks_allocated);
-        if (status)
-            retval = status;
-	reiserfs_write_unlock(inode->i_sb);
-    }
-    th->t_trans_id = 0;
-
-    /* 
-     * we have to unlock the pages after updating i_size, otherwise
-     * we race with writepage
-     */
-    for ( i = 0; i < num_pages ; i++) {
-	struct page *page=prepared_pages[i];
-	unlock_page(page); 
-	mark_page_accessed(page);
-	page_cache_release(page);
-    }
-    return retval;
+		reiserfs_write_lock(inode->i_sb);
+		if (!sd_update)
+			reiserfs_update_sd(th, inode);
+		status = journal_end(th, th->t_super, th->t_blocks_allocated);
+		if (status)
+			retval = status;
+		reiserfs_write_unlock(inode->i_sb);
+	}
+	th->t_trans_id = 0;
+
+	/* 
+	 * we have to unlock the pages after updating i_size, otherwise
+	 * we race with writepage
+	 */
+	for (i = 0; i < num_pages; i++) {
+		struct page *page = prepared_pages[i];
+		unlock_page(page);
+		mark_page_accessed(page);
+		page_cache_release(page);
+	}
+	return retval;
 }
 
 /* Look if passed writing region is going to touch file's tail
    (if it is present). And if it is, convert the tail to unformatted node */
-static int reiserfs_check_for_tail_and_convert( struct inode *inode, /* inode to deal with */
-					 loff_t pos, /* Writing position */
-					 int write_bytes /* amount of bytes to write */
-				        )
+static int reiserfs_check_for_tail_and_convert(struct inode *inode,	/* inode to deal with */
+					       loff_t pos,	/* Writing position */
+					       int write_bytes	/* amount of bytes to write */
+    )
 {
-    INITIALIZE_PATH(path); // needed for search_for_position
-    struct cpu_key key; // Key that would represent last touched writing byte.
-    struct item_head *ih; // item header of found block;
-    int res; // Return value of various functions we call.
-    int cont_expand_offset; // We will put offset for generic_cont_expand here
-			    // This can be int just because tails are created
-			    // only for small files.
- 
+	INITIALIZE_PATH(path);	// needed for search_for_position
+	struct cpu_key key;	// Key that would represent last touched writing byte.
+	struct item_head *ih;	// item header of found block;
+	int res;		// Return value of various functions we call.
+	int cont_expand_offset;	// We will put offset for generic_cont_expand here
+	// This can be int just because tails are created
+	// only for small files.
+
 /* this embodies a dependency on a particular tail policy */
-    if ( inode->i_size >= inode->i_sb->s_blocksize*4 ) {
-	/* such a big files do not have tails, so we won't bother ourselves
-	   to look for tails, simply return */
-	return 0;
-    }
+	if (inode->i_size >= inode->i_sb->s_blocksize * 4) {
+		/* such a big files do not have tails, so we won't bother ourselves
+		   to look for tails, simply return */
+		return 0;
+	}
 
-    reiserfs_write_lock(inode->i_sb);
-    /* find the item containing the last byte to be written, or if
-     * writing past the end of the file then the last item of the
-     * file (and then we check its type). */
-    make_cpu_key (&key, inode, pos+write_bytes+1, TYPE_ANY, 3/*key length*/);
-    res = search_for_position_by_key(inode->i_sb, &key, &path);
-    if ( res == IO_ERROR ) {
-        reiserfs_write_unlock(inode->i_sb);
-	return -EIO;
-    }
-    ih = get_ih(&path);
-    res = 0;
-    if ( is_direct_le_ih(ih) ) {
-	/* Ok, closest item is file tail (tails are stored in "direct"
-	 * items), so we need to unpack it. */
-	/* To not overcomplicate matters, we just call generic_cont_expand
-	   which will in turn call other stuff and finally will boil down to
-	    reiserfs_get_block() that would do necessary conversion. */
-	cont_expand_offset = le_key_k_offset(get_inode_item_key_version(inode), &(ih->ih_key));
-	pathrelse(&path);
-	res = generic_cont_expand( inode, cont_expand_offset);
-    } else
-	pathrelse(&path);
+	reiserfs_write_lock(inode->i_sb);
+	/* find the item containing the last byte to be written, or if
+	 * writing past the end of the file then the last item of the
+	 * file (and then we check its type). */
+	make_cpu_key(&key, inode, pos + write_bytes + 1, TYPE_ANY,
+		     3 /*key length */ );
+	res = search_for_position_by_key(inode->i_sb, &key, &path);
+	if (res == IO_ERROR) {
+		reiserfs_write_unlock(inode->i_sb);
+		return -EIO;
+	}
+	ih = get_ih(&path);
+	res = 0;
+	if (is_direct_le_ih(ih)) {
+		/* Ok, closest item is file tail (tails are stored in "direct"
+		 * items), so we need to unpack it. */
+		/* To not overcomplicate matters, we just call generic_cont_expand
+		   which will in turn call other stuff and finally will boil down to
+		   reiserfs_get_block() that would do necessary conversion. */
+		cont_expand_offset =
+		    le_key_k_offset(get_inode_item_key_version(inode),
+				    &(ih->ih_key));
+		pathrelse(&path);
+		res = generic_cont_expand(inode, cont_expand_offset);
+	} else
+		pathrelse(&path);
 
-    reiserfs_write_unlock(inode->i_sb);
-    return res;
+	reiserfs_write_unlock(inode->i_sb);
+	return res;
 }
 
 /* This function locks pages starting from @pos for @inode.
@@ -851,275 +947,296 @@ static int reiserfs_check_for_tail_and_c
    append), it is zeroed, then. 
    Returns number of unallocated blocks that should be allocated to cover
    new file data.*/
-static int reiserfs_prepare_file_region_for_write(
-				struct inode *inode /* Inode of the file */,
-				loff_t pos, /* position in the file */
-				size_t num_pages, /* number of pages to
-					          prepare */
-				size_t write_bytes, /* Amount of bytes to be
-						    overwritten from
-						    @pos */
-				struct page **prepared_pages /* pointer to array
-							       where to store
-							       prepared pages */
-					   )
+static int reiserfs_prepare_file_region_for_write(struct inode *inode
+						  /* Inode of the file */ ,
+						  loff_t pos,	/* position in the file */
+						  size_t num_pages,	/* number of pages to
+									   prepare */
+						  size_t write_bytes,	/* Amount of bytes to be
+									   overwritten from
+									   @pos */
+						  struct page **prepared_pages	/* pointer to array
+										   where to store
+										   prepared pages */
+    )
 {
-    int res=0; // Return values of different functions we call.
-    unsigned long index = pos >> PAGE_CACHE_SHIFT; // Offset in file in pages.
-    int from = (pos & (PAGE_CACHE_SIZE - 1)); // Writing offset in first page
-    int to = ((pos + write_bytes - 1) & (PAGE_CACHE_SIZE - 1)) + 1;
-					 /* offset of last modified byte in last
-				            page */
-    struct address_space *mapping = inode->i_mapping; // Pages are mapped here.
-    int i; // Simple counter
-    int blocks = 0; /* Return value (blocks that should be allocated) */
-    struct buffer_head *bh, *head; // Current bufferhead and first bufferhead
-				   // of a page.
-    unsigned block_start, block_end; // Starting and ending offsets of current
-				     // buffer in the page.
-    struct buffer_head *wait[2], **wait_bh=wait; // Buffers for page, if
-						 // Page appeared to be not up
-						 // to date. Note how we have
-						 // at most 2 buffers, this is
-						 // because we at most may
-						 // partially overwrite two
-						 // buffers for one page. One at                                                 // the beginning of write area
-						 // and one at the end.
-						 // Everything inthe middle gets                                                 // overwritten totally.
-
-    struct cpu_key key; // cpu key of item that we are going to deal with
-    struct item_head *ih = NULL; // pointer to item head that we are going to deal with
-    struct buffer_head *itembuf=NULL; // Buffer head that contains items that we are going to deal with
-    INITIALIZE_PATH(path); // path to item, that we are going to deal with.
-    __le32 * item=NULL; // pointer to item we are going to deal with
-    int item_pos=-1; /* Position in indirect item */
-
-
-    if ( num_pages < 1 ) {
-	reiserfs_warning (inode->i_sb,
-			  "green-9001: reiserfs_prepare_file_region_for_write "
-			  "called with zero number of pages to process");
-	return -EFAULT;
-    }
-
-    /* We have 2 loops for pages. In first loop we grab and lock the pages, so
-       that nobody would touch these until we release the pages. Then
-       we'd start to deal with mapping buffers to blocks. */
-    for ( i = 0; i < num_pages; i++) {
-	prepared_pages[i] = grab_cache_page(mapping, index + i); // locks the page
-	if ( !prepared_pages[i]) {
-	    res = -ENOMEM;
-	    goto failed_page_grabbing;
-	}
-	if (!page_has_buffers(prepared_pages[i]))
-	    create_empty_buffers(prepared_pages[i], inode->i_sb->s_blocksize, 0);
-    }
-
-    /* Let's count amount of blocks for a case where all the blocks
-       overwritten are new (we will substract already allocated blocks later)*/
-    if ( num_pages > 2 )
-	/* These are full-overwritten pages so we count all the blocks in
-	   these pages are counted as needed to be allocated */
-	blocks = (num_pages - 2) << (PAGE_CACHE_SHIFT - inode->i_blkbits);
-
-    /* count blocks needed for first page (possibly partially written) */
-    blocks += ((PAGE_CACHE_SIZE - from) >> inode->i_blkbits) +
-	   !!(from & (inode->i_sb->s_blocksize-1)); /* roundup */
-
-    /* Now we account for last page. If last page == first page (we
-       overwrite only one page), we substract all the blocks past the
-       last writing position in a page out of already calculated number
-       of blocks */
-    blocks += ((num_pages > 1) << (PAGE_CACHE_SHIFT-inode->i_blkbits)) -
-	   ((PAGE_CACHE_SIZE - to) >> inode->i_blkbits);
-	   /* Note how we do not roundup here since partial blocks still
-		   should be allocated */
-
-    /* Now if all the write area lies past the file end, no point in
-       maping blocks, since there is none, so we just zero out remaining
-       parts of first and last pages in write area (if needed) */
-    if ( (pos & ~((loff_t)PAGE_CACHE_SIZE - 1)) > inode->i_size ) {
-	if ( from != 0 ) {/* First page needs to be partially zeroed */
-	    char *kaddr = kmap_atomic(prepared_pages[0], KM_USER0);
-	    memset(kaddr, 0, from);
-	    kunmap_atomic( kaddr, KM_USER0);
-	}
-	if ( to != PAGE_CACHE_SIZE ) { /* Last page needs to be partially zeroed */
-	    char *kaddr = kmap_atomic(prepared_pages[num_pages-1], KM_USER0);
-	    memset(kaddr+to, 0, PAGE_CACHE_SIZE - to);
-	    kunmap_atomic( kaddr, KM_USER0);
+	int res = 0;		// Return values of different functions we call.
+	unsigned long index = pos >> PAGE_CACHE_SHIFT;	// Offset in file in pages.
+	int from = (pos & (PAGE_CACHE_SIZE - 1));	// Writing offset in first page
+	int to = ((pos + write_bytes - 1) & (PAGE_CACHE_SIZE - 1)) + 1;
+	/* offset of last modified byte in last
+	   page */
+	struct address_space *mapping = inode->i_mapping;	// Pages are mapped here.
+	int i;			// Simple counter
+	int blocks = 0;		/* Return value (blocks that should be allocated) */
+	struct buffer_head *bh, *head;	// Current bufferhead and first bufferhead
+	// of a page.
+	unsigned block_start, block_end;	// Starting and ending offsets of current
+	// buffer in the page.
+	struct buffer_head *wait[2], **wait_bh = wait;	// Buffers for page, if
+	// Page appeared to be not up
+	// to date. Note how we have
+	// at most 2 buffers, this is
+	// because we at most may
+	// partially overwrite two
+	// buffers for one page. One at                                                 // the beginning of write area
+	// and one at the end.
+	// Everything inthe middle gets                                                 // overwritten totally.
+
+	struct cpu_key key;	// cpu key of item that we are going to deal with
+	struct item_head *ih = NULL;	// pointer to item head that we are going to deal with
+	struct buffer_head *itembuf = NULL;	// Buffer head that contains items that we are going to deal with
+	INITIALIZE_PATH(path);	// path to item, that we are going to deal with.
+	__le32 *item = NULL;	// pointer to item we are going to deal with
+	int item_pos = -1;	/* Position in indirect item */
+
+	if (num_pages < 1) {
+		reiserfs_warning(inode->i_sb,
+				 "green-9001: reiserfs_prepare_file_region_for_write "
+				 "called with zero number of pages to process");
+		return -EFAULT;
+	}
+
+	/* We have 2 loops for pages. In first loop we grab and lock the pages, so
+	   that nobody would touch these until we release the pages. Then
+	   we'd start to deal with mapping buffers to blocks. */
+	for (i = 0; i < num_pages; i++) {
+		prepared_pages[i] = grab_cache_page(mapping, index + i);	// locks the page
+		if (!prepared_pages[i]) {
+			res = -ENOMEM;
+			goto failed_page_grabbing;
+		}
+		if (!page_has_buffers(prepared_pages[i]))
+			create_empty_buffers(prepared_pages[i],
+					     inode->i_sb->s_blocksize, 0);
+	}
+
+	/* Let's count amount of blocks for a case where all the blocks
+	   overwritten are new (we will substract already allocated blocks later) */
+	if (num_pages > 2)
+		/* These are full-overwritten pages so we count all the blocks in
+		   these pages are counted as needed to be allocated */
+		blocks =
+		    (num_pages - 2) << (PAGE_CACHE_SHIFT - inode->i_blkbits);
+
+	/* count blocks needed for first page (possibly partially written) */
+	blocks += ((PAGE_CACHE_SIZE - from) >> inode->i_blkbits) + !!(from & (inode->i_sb->s_blocksize - 1));	/* roundup */
+
+	/* Now we account for last page. If last page == first page (we
+	   overwrite only one page), we substract all the blocks past the
+	   last writing position in a page out of already calculated number
+	   of blocks */
+	blocks += ((num_pages > 1) << (PAGE_CACHE_SHIFT - inode->i_blkbits)) -
+	    ((PAGE_CACHE_SIZE - to) >> inode->i_blkbits);
+	/* Note how we do not roundup here since partial blocks still
+	   should be allocated */
+
+	/* Now if all the write area lies past the file end, no point in
+	   maping blocks, since there is none, so we just zero out remaining
+	   parts of first and last pages in write area (if needed) */
+	if ((pos & ~((loff_t) PAGE_CACHE_SIZE - 1)) > inode->i_size) {
+		if (from != 0) {	/* First page needs to be partially zeroed */
+			char *kaddr = kmap_atomic(prepared_pages[0], KM_USER0);
+			memset(kaddr, 0, from);
+			kunmap_atomic(kaddr, KM_USER0);
+		}
+		if (to != PAGE_CACHE_SIZE) {	/* Last page needs to be partially zeroed */
+			char *kaddr =
+			    kmap_atomic(prepared_pages[num_pages - 1],
+					KM_USER0);
+			memset(kaddr + to, 0, PAGE_CACHE_SIZE - to);
+			kunmap_atomic(kaddr, KM_USER0);
+		}
+
+		/* Since all blocks are new - use already calculated value */
+		return blocks;
 	}
 
-	/* Since all blocks are new - use already calculated value */
-	return blocks;
-    }
+	/* Well, since we write somewhere into the middle of a file, there is
+	   possibility we are writing over some already allocated blocks, so
+	   let's map these blocks and substract number of such blocks out of blocks
+	   we need to allocate (calculated above) */
+	/* Mask write position to start on blocksize, we do it out of the
+	   loop for performance reasons */
+	pos &= ~((loff_t) inode->i_sb->s_blocksize - 1);
+	/* Set cpu key to the starting position in a file (on left block boundary) */
+	make_cpu_key(&key, inode,
+		     1 + ((pos) & ~((loff_t) inode->i_sb->s_blocksize - 1)),
+		     TYPE_ANY, 3 /*key length */ );
+
+	reiserfs_write_lock(inode->i_sb);	// We need that for at least search_by_key()
+	for (i = 0; i < num_pages; i++) {
+
+		head = page_buffers(prepared_pages[i]);
+		/* For each buffer in the page */
+		for (bh = head, block_start = 0; bh != head || !block_start;
+		     block_start = block_end, bh = bh->b_this_page) {
+			if (!bh)
+				reiserfs_panic(inode->i_sb,
+					       "green-9002: Allocated but absent buffer for a page?");
+			/* Find where this buffer ends */
+			block_end = block_start + inode->i_sb->s_blocksize;
+			if (i == 0 && block_end <= from)
+				/* if this buffer is before requested data to map, skip it */
+				continue;
+
+			if (i == num_pages - 1 && block_start >= to) {
+				/* If this buffer is after requested data to map, abort
+				   processing of current page */
+				break;
+			}
 
-    /* Well, since we write somewhere into the middle of a file, there is
-       possibility we are writing over some already allocated blocks, so
-       let's map these blocks and substract number of such blocks out of blocks
-       we need to allocate (calculated above) */
-    /* Mask write position to start on blocksize, we do it out of the
-       loop for performance reasons */
-    pos &= ~((loff_t) inode->i_sb->s_blocksize - 1);
-    /* Set cpu key to the starting position in a file (on left block boundary)*/
-    make_cpu_key (&key, inode, 1 + ((pos) & ~((loff_t) inode->i_sb->s_blocksize - 1)), TYPE_ANY, 3/*key length*/);
-
-    reiserfs_write_lock(inode->i_sb); // We need that for at least search_by_key()
-    for ( i = 0; i < num_pages ; i++ ) { 
-
-	head = page_buffers(prepared_pages[i]);
-	/* For each buffer in the page */
-	for(bh = head, block_start = 0; bh != head || !block_start;
-	    block_start=block_end, bh = bh->b_this_page) {
-		if (!bh)
-		    reiserfs_panic(inode->i_sb, "green-9002: Allocated but absent buffer for a page?");
-		/* Find where this buffer ends */
-		block_end = block_start+inode->i_sb->s_blocksize;
-		if (i == 0 && block_end <= from )
-		    /* if this buffer is before requested data to map, skip it*/
-		    continue;
-
-		if (i == num_pages - 1 && block_start >= to) {
-		    /* If this buffer is after requested data to map, abort
-		       processing of current page */
-		    break;
-		}
-
-		if ( buffer_mapped(bh) && bh->b_blocknr !=0 ) {
-		    /* This is optimisation for a case where buffer is mapped
-		       and have blocknumber assigned. In case significant amount
-		       of such buffers are present, we may avoid some amount
-		       of search_by_key calls.
-		       Probably it would be possible to move parts of this code
-		       out of BKL, but I afraid that would overcomplicate code
-		       without any noticeable benefit.
-		    */
-		    item_pos++;
-		    /* Update the key */
-		    set_cpu_key_k_offset( &key, cpu_key_k_offset(&key) + inode->i_sb->s_blocksize);
-		    blocks--; // Decrease the amount of blocks that need to be
-			      // allocated
-		    continue; // Go to the next buffer
-		}
-
-		if ( !itembuf || /* if first iteration */
-		     item_pos >= ih_item_len(ih)/UNFM_P_SIZE)
-					     { /* or if we progressed past the
-						  current unformatted_item */
-			/* Try to find next item */
-			res = search_for_position_by_key(inode->i_sb, &key, &path);
-			/* Abort if no more items */
-			if ( res != POSITION_FOUND ) {
-			    /* make sure later loops don't use this item */
-			    itembuf = NULL;
-			    item = NULL;
-			    break;
+			if (buffer_mapped(bh) && bh->b_blocknr != 0) {
+				/* This is optimisation for a case where buffer is mapped
+				   and have blocknumber assigned. In case significant amount
+				   of such buffers are present, we may avoid some amount
+				   of search_by_key calls.
+				   Probably it would be possible to move parts of this code
+				   out of BKL, but I afraid that would overcomplicate code
+				   without any noticeable benefit.
+				 */
+				item_pos++;
+				/* Update the key */
+				set_cpu_key_k_offset(&key,
+						     cpu_key_k_offset(&key) +
+						     inode->i_sb->s_blocksize);
+				blocks--;	// Decrease the amount of blocks that need to be
+				// allocated
+				continue;	// Go to the next buffer
 			}
 
-			/* Update information about current indirect item */
-			itembuf = get_last_bh( &path );
-			ih = get_ih( &path );
-			item = get_item( &path );
-			item_pos = path.pos_in_item;
-
-			RFALSE( !is_indirect_le_ih (ih), "green-9003: indirect item expected");
-		}
-
-		/* See if there is some block associated with the file
-		   at that position, map the buffer to this block */
-		if ( get_block_num(item,item_pos) ) {
-		    map_bh(bh, inode->i_sb, get_block_num(item,item_pos));
-		    blocks--; // Decrease the amount of blocks that need to be
-			      // allocated
-		}
-		item_pos++;
-		/* Update the key */
-		set_cpu_key_k_offset( &key, cpu_key_k_offset(&key) + inode->i_sb->s_blocksize);
-	}
-    }
-    pathrelse(&path); // Free the path
-    reiserfs_write_unlock(inode->i_sb);
+			if (!itembuf ||	/* if first iteration */
+			    item_pos >= ih_item_len(ih) / UNFM_P_SIZE) {	/* or if we progressed past the
+										   current unformatted_item */
+				/* Try to find next item */
+				res =
+				    search_for_position_by_key(inode->i_sb,
+							       &key, &path);
+				/* Abort if no more items */
+				if (res != POSITION_FOUND) {
+					/* make sure later loops don't use this item */
+					itembuf = NULL;
+					item = NULL;
+					break;
+				}
+
+				/* Update information about current indirect item */
+				itembuf = get_last_bh(&path);
+				ih = get_ih(&path);
+				item = get_item(&path);
+				item_pos = path.pos_in_item;
+
+				RFALSE(!is_indirect_le_ih(ih),
+				       "green-9003: indirect item expected");
+			}
+
+			/* See if there is some block associated with the file
+			   at that position, map the buffer to this block */
+			if (get_block_num(item, item_pos)) {
+				map_bh(bh, inode->i_sb,
+				       get_block_num(item, item_pos));
+				blocks--;	// Decrease the amount of blocks that need to be
+				// allocated
+			}
+			item_pos++;
+			/* Update the key */
+			set_cpu_key_k_offset(&key,
+					     cpu_key_k_offset(&key) +
+					     inode->i_sb->s_blocksize);
+		}
+	}
+	pathrelse(&path);	// Free the path
+	reiserfs_write_unlock(inode->i_sb);
 
 	/* Now zero out unmappend buffers for the first and last pages of
 	   write area or issue read requests if page is mapped. */
 	/* First page, see if it is not uptodate */
-	if ( !PageUptodate(prepared_pages[0]) ) {
-	    head = page_buffers(prepared_pages[0]);
+	if (!PageUptodate(prepared_pages[0])) {
+		head = page_buffers(prepared_pages[0]);
 
-	    /* For each buffer in page */
-	    for(bh = head, block_start = 0; bh != head || !block_start;
-		block_start=block_end, bh = bh->b_this_page) {
-
-		if (!bh)
-		    reiserfs_panic(inode->i_sb, "green-9002: Allocated but absent buffer for a page?");
-		/* Find where this buffer ends */
-		block_end = block_start+inode->i_sb->s_blocksize;
-		if ( block_end <= from )
-		    /* if this buffer is before requested data to map, skip it*/
-		    continue;
-		if ( block_start < from ) { /* Aha, our partial buffer */
-		    if ( buffer_mapped(bh) ) { /* If it is mapped, we need to
-						  issue READ request for it to
-						  not loose data */
-			ll_rw_block(READ, 1, &bh);
-			*wait_bh++=bh;
-		    } else { /* Not mapped, zero it */
-			char *kaddr = kmap_atomic(prepared_pages[0], KM_USER0);
-			memset(kaddr+block_start, 0, from-block_start);
-			kunmap_atomic( kaddr, KM_USER0);
-			set_buffer_uptodate(bh);
-		    }
+		/* For each buffer in page */
+		for (bh = head, block_start = 0; bh != head || !block_start;
+		     block_start = block_end, bh = bh->b_this_page) {
+
+			if (!bh)
+				reiserfs_panic(inode->i_sb,
+					       "green-9002: Allocated but absent buffer for a page?");
+			/* Find where this buffer ends */
+			block_end = block_start + inode->i_sb->s_blocksize;
+			if (block_end <= from)
+				/* if this buffer is before requested data to map, skip it */
+				continue;
+			if (block_start < from) {	/* Aha, our partial buffer */
+				if (buffer_mapped(bh)) {	/* If it is mapped, we need to
+								   issue READ request for it to
+								   not loose data */
+					ll_rw_block(READ, 1, &bh);
+					*wait_bh++ = bh;
+				} else {	/* Not mapped, zero it */
+					char *kaddr =
+					    kmap_atomic(prepared_pages[0],
+							KM_USER0);
+					memset(kaddr + block_start, 0,
+					       from - block_start);
+					kunmap_atomic(kaddr, KM_USER0);
+					set_buffer_uptodate(bh);
+				}
+			}
 		}
-	    }
 	}
 
 	/* Last page, see if it is not uptodate, or if the last page is past the end of the file. */
-	if ( !PageUptodate(prepared_pages[num_pages-1]) || 
-	    ((pos+write_bytes)>>PAGE_CACHE_SHIFT) > (inode->i_size>>PAGE_CACHE_SHIFT) ) {
-	    head = page_buffers(prepared_pages[num_pages-1]);
-
-	    /* for each buffer in page */
-	    for(bh = head, block_start = 0; bh != head || !block_start;
-		block_start=block_end, bh = bh->b_this_page) {
-
-		if (!bh)
-		    reiserfs_panic(inode->i_sb, "green-9002: Allocated but absent buffer for a page?");
-		/* Find where this buffer ends */
-		block_end = block_start+inode->i_sb->s_blocksize;
-		if ( block_start >= to )
-		    /* if this buffer is after requested data to map, skip it*/
-		    break;
-		if ( block_end > to ) { /* Aha, our partial buffer */
-		    if ( buffer_mapped(bh) ) { /* If it is mapped, we need to
-						  issue READ request for it to
-						  not loose data */
-			ll_rw_block(READ, 1, &bh);
-			*wait_bh++=bh;
-		    } else { /* Not mapped, zero it */
-			char *kaddr = kmap_atomic(prepared_pages[num_pages-1], KM_USER0);
-			memset(kaddr+to, 0, block_end-to);
-			kunmap_atomic( kaddr, KM_USER0);
-			set_buffer_uptodate(bh);
-		    }
+	if (!PageUptodate(prepared_pages[num_pages - 1]) ||
+	    ((pos + write_bytes) >> PAGE_CACHE_SHIFT) >
+	    (inode->i_size >> PAGE_CACHE_SHIFT)) {
+		head = page_buffers(prepared_pages[num_pages - 1]);
+
+		/* for each buffer in page */
+		for (bh = head, block_start = 0; bh != head || !block_start;
+		     block_start = block_end, bh = bh->b_this_page) {
+
+			if (!bh)
+				reiserfs_panic(inode->i_sb,
+					       "green-9002: Allocated but absent buffer for a page?");
+			/* Find where this buffer ends */
+			block_end = block_start + inode->i_sb->s_blocksize;
+			if (block_start >= to)
+				/* if this buffer is after requested data to map, skip it */
+				break;
+			if (block_end > to) {	/* Aha, our partial buffer */
+				if (buffer_mapped(bh)) {	/* If it is mapped, we need to
+								   issue READ request for it to
+								   not loose data */
+					ll_rw_block(READ, 1, &bh);
+					*wait_bh++ = bh;
+				} else {	/* Not mapped, zero it */
+					char *kaddr =
+					    kmap_atomic(prepared_pages
+							[num_pages - 1],
+							KM_USER0);
+					memset(kaddr + to, 0, block_end - to);
+					kunmap_atomic(kaddr, KM_USER0);
+					set_buffer_uptodate(bh);
+				}
+			}
+		}
+	}
+
+	/* Wait for read requests we made to happen, if necessary */
+	while (wait_bh > wait) {
+		wait_on_buffer(*--wait_bh);
+		if (!buffer_uptodate(*wait_bh)) {
+			res = -EIO;
+			goto failed_read;
 		}
-	    }
 	}
 
-    /* Wait for read requests we made to happen, if necessary */
-    while(wait_bh > wait) {
-	wait_on_buffer(*--wait_bh);
-	if (!buffer_uptodate(*wait_bh)) {
-	    res = -EIO;
-	    goto failed_read;
-	}
-    }
-
-    return blocks;
-failed_page_grabbing:
-    num_pages = i;
-failed_read:
-    reiserfs_unprepare_pages(prepared_pages, num_pages);
-    return res;
+	return blocks;
+      failed_page_grabbing:
+	num_pages = i;
+      failed_read:
+	reiserfs_unprepare_pages(prepared_pages, num_pages);
+	return res;
 }
 
 /* Write @count bytes at position @ppos in a file indicated by @file
@@ -1148,262 +1265,305 @@ failed_read:
    Future Features: providing search_by_key with hints.
 
 */
-static ssize_t reiserfs_file_write( struct file *file, /* the file we are going to write into */
-                             const char __user *buf, /*  pointer to user supplied data
-(in userspace) */
-                             size_t count, /* amount of bytes to write */
-                             loff_t *ppos /* pointer to position in file that we start writing at. Should be updated to
-                                           * new current position before returning. */ )
+static ssize_t reiserfs_file_write(struct file *file,	/* the file we are going to write into */
+				   const char __user * buf,	/*  pointer to user supplied data
+								   (in userspace) */
+				   size_t count,	/* amount of bytes to write */
+				   loff_t * ppos	/* pointer to position in file that we start writing at. Should be updated to
+							 * new current position before returning. */
+				   )
 {
-    size_t already_written = 0; // Number of bytes already written to the file.
-    loff_t pos; // Current position in the file.
-    ssize_t res; // return value of various functions that we call.
-    int err = 0;
-    struct inode *inode = file->f_dentry->d_inode; // Inode of the file that we are writing to.
-				/* To simplify coding at this time, we store
-				   locked pages in array for now */
-    struct page * prepared_pages[REISERFS_WRITE_PAGES_AT_A_TIME];
-    struct reiserfs_transaction_handle th;
-    th.t_trans_id = 0;
-
-    if ( file->f_flags & O_DIRECT) { // Direct IO needs treatment
-	ssize_t result, after_file_end = 0;
-	if ( (*ppos + count >= inode->i_size) || (file->f_flags & O_APPEND) ) {
-	    /* If we are appending a file, we need to put this savelink in here.
-	       If we will crash while doing direct io, finish_unfinished will
-	       cut the garbage from the file end. */
-	    reiserfs_write_lock(inode->i_sb);
-	    err = journal_begin(&th, inode->i_sb,  JOURNAL_PER_BALANCE_CNT );
-            if (err) {
-		reiserfs_write_unlock (inode->i_sb);
-		return err;
-	    }
-	    reiserfs_update_inode_transaction(inode);
-	    add_save_link (&th, inode, 1 /* Truncate */);
-	    after_file_end = 1;
-	    err = journal_end(&th, inode->i_sb, JOURNAL_PER_BALANCE_CNT );
-            reiserfs_write_unlock(inode->i_sb);
-	    if (err)
-		return err;
-	}
-	result = generic_file_write(file, buf, count, ppos);
-
-	if ( after_file_end ) { /* Now update i_size and remove the savelink */
-	    struct reiserfs_transaction_handle th;
-	    reiserfs_write_lock(inode->i_sb);
-	    err = journal_begin(&th, inode->i_sb, 1);
-            if (err) {
-                reiserfs_write_unlock (inode->i_sb);
-                return err;
-            }
-	    reiserfs_update_inode_transaction(inode);
-	    reiserfs_update_sd(&th, inode);
-	    err = journal_end(&th, inode->i_sb, 1);
-            if (err) {
-                reiserfs_write_unlock (inode->i_sb);
-                return err;
-            }
-	    err = remove_save_link (inode, 1/* truncate */);
-	    reiserfs_write_unlock(inode->i_sb);
-            if (err)
-                return err;
-	}
-
-	return result;
-    }
-
-    if ( unlikely((ssize_t) count < 0 ))
-        return -EINVAL;
-
-    if (unlikely(!access_ok(VERIFY_READ, buf, count)))
-        return -EFAULT;
-
-    down(&inode->i_sem); // locks the entire file for just us
-
-    pos = *ppos;
-
-    /* Check if we can write to specified region of file, file
-       is not overly big and this kind of stuff. Adjust pos and
-       count, if needed */
-    res = generic_write_checks(file, &pos, &count, 0);
-    if (res)
-	goto out;
-
-    if ( count == 0 )
-	goto out;
-
-    res = remove_suid(file->f_dentry);
-    if (res)
-	goto out;
-
-    inode_update_time(inode, 1); /* Both mtime and ctime */
-
-    // Ok, we are done with all the checks.
-
-    // Now we should start real work
-
-    /* If we are going to write past the file's packed tail or if we are going
-       to overwrite part of the tail, we need that tail to be converted into
-       unformatted node */
-    res = reiserfs_check_for_tail_and_convert( inode, pos, count);
-    if (res)
-	goto out;
-
-    while ( count > 0) {
-	/* This is the main loop in which we running until some error occures
-	   or until we write all of the data. */
-	size_t num_pages;/* amount of pages we are going to write this iteration */
-	size_t write_bytes; /* amount of bytes to write during this iteration */
-	size_t blocks_to_allocate; /* how much blocks we need to allocate for this iteration */
-        
-        /*  (pos & (PAGE_CACHE_SIZE-1)) is an idiom for offset into a page of pos*/
-	num_pages = !!((pos+count) & (PAGE_CACHE_SIZE - 1)) + /* round up partial
-							  pages */
-		    ((count + (pos & (PAGE_CACHE_SIZE-1))) >> PAGE_CACHE_SHIFT); 
-						/* convert size to amount of
-						   pages */
-	reiserfs_write_lock(inode->i_sb);
-	if ( num_pages > REISERFS_WRITE_PAGES_AT_A_TIME 
-		|| num_pages > reiserfs_can_fit_pages(inode->i_sb) ) {
-	    /* If we were asked to write more data than we want to or if there
-	       is not that much space, then we shorten amount of data to write
-	       for this iteration. */
-	    num_pages = min_t(size_t, REISERFS_WRITE_PAGES_AT_A_TIME, reiserfs_can_fit_pages(inode->i_sb));
-	    /* Also we should not forget to set size in bytes accordingly */
-	    write_bytes = (num_pages << PAGE_CACHE_SHIFT) - 
-			    (pos & (PAGE_CACHE_SIZE-1));
-					 /* If position is not on the
-					    start of the page, we need
-					    to substract the offset
-					    within page */
-	} else
-	    write_bytes = count;
+	size_t already_written = 0;	// Number of bytes already written to the file.
+	loff_t pos;		// Current position in the file.
+	ssize_t res;		// return value of various functions that we call.
+	int err = 0;
+	struct inode *inode = file->f_dentry->d_inode;	// Inode of the file that we are writing to.
+	/* To simplify coding at this time, we store
+	   locked pages in array for now */
+	struct page *prepared_pages[REISERFS_WRITE_PAGES_AT_A_TIME];
+	struct reiserfs_transaction_handle th;
+	th.t_trans_id = 0;
+
+	if (file->f_flags & O_DIRECT) {	// Direct IO needs treatment
+		ssize_t result, after_file_end = 0;
+		if ((*ppos + count >= inode->i_size)
+		    || (file->f_flags & O_APPEND)) {
+			/* If we are appending a file, we need to put this savelink in here.
+			   If we will crash while doing direct io, finish_unfinished will
+			   cut the garbage from the file end. */
+			reiserfs_write_lock(inode->i_sb);
+			err =
+			    journal_begin(&th, inode->i_sb,
+					  JOURNAL_PER_BALANCE_CNT);
+			if (err) {
+				reiserfs_write_unlock(inode->i_sb);
+				return err;
+			}
+			reiserfs_update_inode_transaction(inode);
+			add_save_link(&th, inode, 1 /* Truncate */ );
+			after_file_end = 1;
+			err =
+			    journal_end(&th, inode->i_sb,
+					JOURNAL_PER_BALANCE_CNT);
+			reiserfs_write_unlock(inode->i_sb);
+			if (err)
+				return err;
+		}
+		result = generic_file_write(file, buf, count, ppos);
 
-	/* reserve the blocks to be allocated later, so that later on
-	   we still have the space to write the blocks to */
-	reiserfs_claim_blocks_to_be_allocated(inode->i_sb, num_pages << (PAGE_CACHE_SHIFT - inode->i_blkbits));
-	reiserfs_write_unlock(inode->i_sb);
+		if (after_file_end) {	/* Now update i_size and remove the savelink */
+			struct reiserfs_transaction_handle th;
+			reiserfs_write_lock(inode->i_sb);
+			err = journal_begin(&th, inode->i_sb, 1);
+			if (err) {
+				reiserfs_write_unlock(inode->i_sb);
+				return err;
+			}
+			reiserfs_update_inode_transaction(inode);
+			reiserfs_update_sd(&th, inode);
+			err = journal_end(&th, inode->i_sb, 1);
+			if (err) {
+				reiserfs_write_unlock(inode->i_sb);
+				return err;
+			}
+			err = remove_save_link(inode, 1 /* truncate */ );
+			reiserfs_write_unlock(inode->i_sb);
+			if (err)
+				return err;
+		}
 
-	if ( !num_pages ) { /* If we do not have enough space even for a single page... */
-	    if ( pos > inode->i_size+inode->i_sb->s_blocksize-(pos & (inode->i_sb->s_blocksize-1))) {
-		res = -ENOSPC;
-		break; // In case we are writing past the end of the last file block, break.
-	    }
-	    // Otherwise we are possibly overwriting the file, so
-	    // let's set write size to be equal or less than blocksize.
-	    // This way we get it correctly for file holes.
-	    // But overwriting files on absolutelly full volumes would not
-	    // be very efficient. Well, people are not supposed to fill
-	    // 100% of disk space anyway.
-	    write_bytes = min_t(size_t, count, inode->i_sb->s_blocksize - (pos & (inode->i_sb->s_blocksize - 1)));
-	    num_pages = 1;
-	    // No blocks were claimed before, so do it now.
-	    reiserfs_claim_blocks_to_be_allocated(inode->i_sb, 1 << (PAGE_CACHE_SHIFT - inode->i_blkbits));
-	}
-
-	/* Prepare for writing into the region, read in all the
-	   partially overwritten pages, if needed. And lock the pages,
-	   so that nobody else can access these until we are done.
-	   We get number of actual blocks needed as a result.*/
-	blocks_to_allocate = reiserfs_prepare_file_region_for_write(inode, pos, num_pages, write_bytes, prepared_pages);
-	if ( blocks_to_allocate < 0 ) {
-	    res = blocks_to_allocate;
-	    reiserfs_release_claimed_blocks(inode->i_sb, num_pages << (PAGE_CACHE_SHIFT - inode->i_blkbits));
-	    break;
-	}
-
-	/* First we correct our estimate of how many blocks we need */
-	reiserfs_release_claimed_blocks(inode->i_sb, (num_pages << (PAGE_CACHE_SHIFT - inode->i_sb->s_blocksize_bits)) - blocks_to_allocate );
-
-	if ( blocks_to_allocate > 0) {/*We only allocate blocks if we need to*/
-	    /* Fill in all the possible holes and append the file if needed */
-	    res = reiserfs_allocate_blocks_for_region(&th, inode, pos, num_pages, write_bytes, prepared_pages, blocks_to_allocate);
-	}
-
-	/* well, we have allocated the blocks, so it is time to free
-	   the reservation we made earlier. */
-	reiserfs_release_claimed_blocks(inode->i_sb, blocks_to_allocate);
-	if ( res ) {
-	    reiserfs_unprepare_pages(prepared_pages, num_pages);
-	    break;
+		return result;
 	}
 
+	if (unlikely((ssize_t) count < 0))
+		return -EINVAL;
+
+	if (unlikely(!access_ok(VERIFY_READ, buf, count)))
+		return -EFAULT;
+
+	down(&inode->i_sem);	// locks the entire file for just us
+
+	pos = *ppos;
+
+	/* Check if we can write to specified region of file, file
+	   is not overly big and this kind of stuff. Adjust pos and
+	   count, if needed */
+	res = generic_write_checks(file, &pos, &count, 0);
+	if (res)
+		goto out;
+
+	if (count == 0)
+		goto out;
+
+	res = remove_suid(file->f_dentry);
+	if (res)
+		goto out;
+
+	inode_update_time(inode, 1);	/* Both mtime and ctime */
+
+	// Ok, we are done with all the checks.
+
+	// Now we should start real work
+
+	/* If we are going to write past the file's packed tail or if we are going
+	   to overwrite part of the tail, we need that tail to be converted into
+	   unformatted node */
+	res = reiserfs_check_for_tail_and_convert(inode, pos, count);
+	if (res)
+		goto out;
+
+	while (count > 0) {
+		/* This is the main loop in which we running until some error occures
+		   or until we write all of the data. */
+		size_t num_pages;	/* amount of pages we are going to write this iteration */
+		size_t write_bytes;	/* amount of bytes to write during this iteration */
+		size_t blocks_to_allocate;	/* how much blocks we need to allocate for this iteration */
+
+		/*  (pos & (PAGE_CACHE_SIZE-1)) is an idiom for offset into a page of pos */
+		num_pages = !!((pos + count) & (PAGE_CACHE_SIZE - 1)) +	/* round up partial
+									   pages */
+		    ((count +
+		      (pos & (PAGE_CACHE_SIZE - 1))) >> PAGE_CACHE_SHIFT);
+		/* convert size to amount of
+		   pages */
+		reiserfs_write_lock(inode->i_sb);
+		if (num_pages > REISERFS_WRITE_PAGES_AT_A_TIME
+		    || num_pages > reiserfs_can_fit_pages(inode->i_sb)) {
+			/* If we were asked to write more data than we want to or if there
+			   is not that much space, then we shorten amount of data to write
+			   for this iteration. */
+			num_pages =
+			    min_t(size_t, REISERFS_WRITE_PAGES_AT_A_TIME,
+				  reiserfs_can_fit_pages(inode->i_sb));
+			/* Also we should not forget to set size in bytes accordingly */
+			write_bytes = (num_pages << PAGE_CACHE_SHIFT) -
+			    (pos & (PAGE_CACHE_SIZE - 1));
+			/* If position is not on the
+			   start of the page, we need
+			   to substract the offset
+			   within page */
+		} else
+			write_bytes = count;
+
+		/* reserve the blocks to be allocated later, so that later on
+		   we still have the space to write the blocks to */
+		reiserfs_claim_blocks_to_be_allocated(inode->i_sb,
+						      num_pages <<
+						      (PAGE_CACHE_SHIFT -
+						       inode->i_blkbits));
+		reiserfs_write_unlock(inode->i_sb);
+
+		if (!num_pages) {	/* If we do not have enough space even for a single page... */
+			if (pos >
+			    inode->i_size + inode->i_sb->s_blocksize -
+			    (pos & (inode->i_sb->s_blocksize - 1))) {
+				res = -ENOSPC;
+				break;	// In case we are writing past the end of the last file block, break.
+			}
+			// Otherwise we are possibly overwriting the file, so
+			// let's set write size to be equal or less than blocksize.
+			// This way we get it correctly for file holes.
+			// But overwriting files on absolutelly full volumes would not
+			// be very efficient. Well, people are not supposed to fill
+			// 100% of disk space anyway.
+			write_bytes =
+			    min_t(size_t, count,
+				  inode->i_sb->s_blocksize -
+				  (pos & (inode->i_sb->s_blocksize - 1)));
+			num_pages = 1;
+			// No blocks were claimed before, so do it now.
+			reiserfs_claim_blocks_to_be_allocated(inode->i_sb,
+							      1 <<
+							      (PAGE_CACHE_SHIFT
+							       -
+							       inode->
+							       i_blkbits));
+		}
+
+		/* Prepare for writing into the region, read in all the
+		   partially overwritten pages, if needed. And lock the pages,
+		   so that nobody else can access these until we are done.
+		   We get number of actual blocks needed as a result. */
+		blocks_to_allocate =
+		    reiserfs_prepare_file_region_for_write(inode, pos,
+							   num_pages,
+							   write_bytes,
+							   prepared_pages);
+		if (blocks_to_allocate < 0) {
+			res = blocks_to_allocate;
+			reiserfs_release_claimed_blocks(inode->i_sb,
+							num_pages <<
+							(PAGE_CACHE_SHIFT -
+							 inode->i_blkbits));
+			break;
+		}
+
+		/* First we correct our estimate of how many blocks we need */
+		reiserfs_release_claimed_blocks(inode->i_sb,
+						(num_pages <<
+						 (PAGE_CACHE_SHIFT -
+						  inode->i_sb->
+						  s_blocksize_bits)) -
+						blocks_to_allocate);
+
+		if (blocks_to_allocate > 0) {	/*We only allocate blocks if we need to */
+			/* Fill in all the possible holes and append the file if needed */
+			res =
+			    reiserfs_allocate_blocks_for_region(&th, inode, pos,
+								num_pages,
+								write_bytes,
+								prepared_pages,
+								blocks_to_allocate);
+		}
+
+		/* well, we have allocated the blocks, so it is time to free
+		   the reservation we made earlier. */
+		reiserfs_release_claimed_blocks(inode->i_sb,
+						blocks_to_allocate);
+		if (res) {
+			reiserfs_unprepare_pages(prepared_pages, num_pages);
+			break;
+		}
+
 /* NOTE that allocating blocks and filling blocks can be done in reverse order
    and probably we would do that just to get rid of garbage in files after a
    crash */
 
-	/* Copy data from user-supplied buffer to file's pages */
-	res = reiserfs_copy_from_user_to_file_region(pos, num_pages, write_bytes, prepared_pages, buf);
-	if ( res ) {
-	    reiserfs_unprepare_pages(prepared_pages, num_pages);
-	    break;
-	}
-
-	/* Send the pages to disk and unlock them. */
-	res = reiserfs_submit_file_region_for_write(&th, inode, pos, num_pages,
-	                                            write_bytes,prepared_pages);
-	if ( res )
-	    break;
-
-	already_written += write_bytes;
-	buf += write_bytes;
-	*ppos = pos += write_bytes;
-	count -= write_bytes;
-	balance_dirty_pages_ratelimited(inode->i_mapping);
-    }
-
-    /* this is only true on error */
-    if (th.t_trans_id) {
-        reiserfs_write_lock(inode->i_sb);
-        err = journal_end(&th, th.t_super, th.t_blocks_allocated);
-        reiserfs_write_unlock(inode->i_sb);
-        if (err) {
-            res = err;
-            goto out;
-        }
-    }
-
-    if ((file->f_flags & O_SYNC) || IS_SYNC(inode))
-	res = generic_osync_inode(inode, file->f_mapping, OSYNC_METADATA|OSYNC_DATA);
-
-    up(&inode->i_sem);
-    reiserfs_async_progress_wait(inode->i_sb);
-    return (already_written != 0)?already_written:res;
-
-out:
-    up(&inode->i_sem); // unlock the file on exit.
-    return res;
+		/* Copy data from user-supplied buffer to file's pages */
+		res =
+		    reiserfs_copy_from_user_to_file_region(pos, num_pages,
+							   write_bytes,
+							   prepared_pages, buf);
+		if (res) {
+			reiserfs_unprepare_pages(prepared_pages, num_pages);
+			break;
+		}
+
+		/* Send the pages to disk and unlock them. */
+		res =
+		    reiserfs_submit_file_region_for_write(&th, inode, pos,
+							  num_pages,
+							  write_bytes,
+							  prepared_pages);
+		if (res)
+			break;
+
+		already_written += write_bytes;
+		buf += write_bytes;
+		*ppos = pos += write_bytes;
+		count -= write_bytes;
+		balance_dirty_pages_ratelimited(inode->i_mapping);
+	}
+
+	/* this is only true on error */
+	if (th.t_trans_id) {
+		reiserfs_write_lock(inode->i_sb);
+		err = journal_end(&th, th.t_super, th.t_blocks_allocated);
+		reiserfs_write_unlock(inode->i_sb);
+		if (err) {
+			res = err;
+			goto out;
+		}
+	}
+
+	if ((file->f_flags & O_SYNC) || IS_SYNC(inode))
+		res =
+		    generic_osync_inode(inode, file->f_mapping,
+					OSYNC_METADATA | OSYNC_DATA);
+
+	up(&inode->i_sem);
+	reiserfs_async_progress_wait(inode->i_sb);
+	return (already_written != 0) ? already_written : res;
+
+      out:
+	up(&inode->i_sem);	// unlock the file on exit.
+	return res;
 }
 
-static ssize_t reiserfs_aio_write(struct kiocb *iocb, const char __user *buf,
-			       size_t count, loff_t pos)
+static ssize_t reiserfs_aio_write(struct kiocb *iocb, const char __user * buf,
+				  size_t count, loff_t pos)
 {
-    return generic_file_aio_write(iocb, buf, count, pos);
+	return generic_file_aio_write(iocb, buf, count, pos);
 }
 
-
-
 struct file_operations reiserfs_file_operations = {
-    .read	= generic_file_read,
-    .write	= reiserfs_file_write,
-    .ioctl	= reiserfs_ioctl,
-    .mmap	= generic_file_mmap,
-    .release	= reiserfs_file_release,
-    .fsync	= reiserfs_sync_file,
-    .sendfile	= generic_file_sendfile,
-    .aio_read   = generic_file_aio_read,
-    .aio_write  = reiserfs_aio_write,
+	.read = generic_file_read,
+	.write = reiserfs_file_write,
+	.ioctl = reiserfs_ioctl,
+	.mmap = generic_file_mmap,
+	.release = reiserfs_file_release,
+	.fsync = reiserfs_sync_file,
+	.sendfile = generic_file_sendfile,
+	.aio_read = generic_file_aio_read,
+	.aio_write = reiserfs_aio_write,
 };
 
-
-struct  inode_operations reiserfs_file_inode_operations = {
-    .truncate	= reiserfs_vfs_truncate_file,
-    .setattr    = reiserfs_setattr,
-    .setxattr   = reiserfs_setxattr,
-    .getxattr   = reiserfs_getxattr,
-    .listxattr  = reiserfs_listxattr,
-    .removexattr = reiserfs_removexattr,
-    .permission = reiserfs_permission,
+struct inode_operations reiserfs_file_inode_operations = {
+	.truncate = reiserfs_vfs_truncate_file,
+	.setattr = reiserfs_setattr,
+	.setxattr = reiserfs_setxattr,
+	.getxattr = reiserfs_getxattr,
+	.listxattr = reiserfs_listxattr,
+	.removexattr = reiserfs_removexattr,
+	.permission = reiserfs_permission,
 };
-
-
diff --git a/fs/reiserfs/fix_node.c b/fs/reiserfs/fix_node.c
--- a/fs/reiserfs/fix_node.c
+++ b/fs/reiserfs/fix_node.c
@@ -34,14 +34,12 @@
  ** 
  **/
 
-
 #include <linux/config.h>
 #include <linux/time.h>
 #include <linux/string.h>
 #include <linux/reiserfs_fs.h>
 #include <linux/buffer_head.h>
 
-
 /* To make any changes in the tree we find a node, that contains item
    to be changed/deleted or position in the node we insert a new item
    to. We call this node S. To do balancing we need to decide what we
@@ -56,490 +54,522 @@
    have to have if we do not any shiftings, if we shift to left/right
    neighbor or to both. */
 
-
 /* taking item number in virtual node, returns number of item, that it has in source buffer */
-static inline int old_item_num (int new_num, int affected_item_num, int mode)
+static inline int old_item_num(int new_num, int affected_item_num, int mode)
 {
-  if (mode == M_PASTE || mode == M_CUT || new_num < affected_item_num)
-    return new_num;
+	if (mode == M_PASTE || mode == M_CUT || new_num < affected_item_num)
+		return new_num;
 
-  if (mode == M_INSERT) {
+	if (mode == M_INSERT) {
 
-    RFALSE( new_num == 0, 
-	    "vs-8005: for INSERT mode and item number of inserted item");
+		RFALSE(new_num == 0,
+		       "vs-8005: for INSERT mode and item number of inserted item");
 
-    return new_num - 1;
-  }
+		return new_num - 1;
+	}
 
-  RFALSE( mode != M_DELETE,
-	  "vs-8010: old_item_num: mode must be M_DELETE (mode = \'%c\'", mode);
-  /* delete mode */
-  return new_num + 1;
+	RFALSE(mode != M_DELETE,
+	       "vs-8010: old_item_num: mode must be M_DELETE (mode = \'%c\'",
+	       mode);
+	/* delete mode */
+	return new_num + 1;
 }
 
-static void create_virtual_node (struct tree_balance * tb, int h)
+static void create_virtual_node(struct tree_balance *tb, int h)
 {
-    struct item_head * ih;
-    struct virtual_node * vn = tb->tb_vn;
-    int new_num;
-    struct buffer_head * Sh;	/* this comes from tb->S[h] */
+	struct item_head *ih;
+	struct virtual_node *vn = tb->tb_vn;
+	int new_num;
+	struct buffer_head *Sh;	/* this comes from tb->S[h] */
 
-    Sh = PATH_H_PBUFFER (tb->tb_path, h);
+	Sh = PATH_H_PBUFFER(tb->tb_path, h);
 
-    /* size of changed node */
-    vn->vn_size = MAX_CHILD_SIZE (Sh) - B_FREE_SPACE (Sh) + tb->insert_size[h];
+	/* size of changed node */
+	vn->vn_size =
+	    MAX_CHILD_SIZE(Sh) - B_FREE_SPACE(Sh) + tb->insert_size[h];
 
-    /* for internal nodes array if virtual items is not created */
-    if (h) {
-	vn->vn_nr_item = (vn->vn_size - DC_SIZE) / (DC_SIZE + KEY_SIZE);
-	return;
-    }
+	/* for internal nodes array if virtual items is not created */
+	if (h) {
+		vn->vn_nr_item = (vn->vn_size - DC_SIZE) / (DC_SIZE + KEY_SIZE);
+		return;
+	}
 
-    /* number of items in virtual node  */
-    vn->vn_nr_item = B_NR_ITEMS (Sh) + ((vn->vn_mode == M_INSERT)? 1 : 0) - ((vn->vn_mode == M_DELETE)? 1 : 0);
+	/* number of items in virtual node  */
+	vn->vn_nr_item =
+	    B_NR_ITEMS(Sh) + ((vn->vn_mode == M_INSERT) ? 1 : 0) -
+	    ((vn->vn_mode == M_DELETE) ? 1 : 0);
 
-    /* first virtual item */
-    vn->vn_vi = (struct virtual_item *)(tb->tb_vn + 1);
-    memset (vn->vn_vi, 0, vn->vn_nr_item * sizeof (struct virtual_item));
-    vn->vn_free_ptr += vn->vn_nr_item * sizeof (struct virtual_item);
-
-
-    /* first item in the node */
-    ih = B_N_PITEM_HEAD (Sh, 0);
-
-    /* define the mergeability for 0-th item (if it is not being deleted) */
-    if (op_is_left_mergeable (&(ih->ih_key), Sh->b_size) && (vn->vn_mode != M_DELETE || vn->vn_affected_item_num))
-	    vn->vn_vi[0].vi_type |= VI_TYPE_LEFT_MERGEABLE;
-
-    /* go through all items those remain in the virtual node (except for the new (inserted) one) */
-    for (new_num = 0; new_num < vn->vn_nr_item; new_num ++) {
-	int j;
-	struct virtual_item * vi = vn->vn_vi + new_num;
-	int is_affected = ((new_num != vn->vn_affected_item_num) ? 0 : 1);
-    
-
-	if (is_affected && vn->vn_mode == M_INSERT)
-	    continue;
-    
-	/* get item number in source node */
-	j = old_item_num (new_num, vn->vn_affected_item_num, vn->vn_mode);
-    
-	vi->vi_item_len += ih_item_len(ih + j) + IH_SIZE;
-	vi->vi_ih = ih + j;
-	vi->vi_item = B_I_PITEM (Sh, ih + j);
-	vi->vi_uarea = vn->vn_free_ptr;
-
-	// FIXME: there is no check, that item operation did not
-	// consume too much memory
-	vn->vn_free_ptr += op_create_vi (vn, vi, is_affected, tb->insert_size [0]);
-	if (tb->vn_buf + tb->vn_buf_size < vn->vn_free_ptr)
-	    reiserfs_panic (tb->tb_sb, "vs-8030: create_virtual_node: "
-			    "virtual node space consumed");
-
-	if (!is_affected)
-	    /* this is not being changed */
-	    continue;
-    
-	if (vn->vn_mode == M_PASTE || vn->vn_mode == M_CUT) {
-	    vn->vn_vi[new_num].vi_item_len += tb->insert_size[0];
-	    vi->vi_new_data = vn->vn_data; // pointer to data which is going to be pasted
-	}
-    }
-
-  
-    /* virtual inserted item is not defined yet */
-    if (vn->vn_mode == M_INSERT) {
-	struct virtual_item * vi = vn->vn_vi + vn->vn_affected_item_num;
-      
-	RFALSE( vn->vn_ins_ih == 0,
-		"vs-8040: item header of inserted item is not specified");
-	vi->vi_item_len = tb->insert_size[0];
-	vi->vi_ih = vn->vn_ins_ih;
-	vi->vi_item = vn->vn_data;
-	vi->vi_uarea = vn->vn_free_ptr;
-	
-	op_create_vi (vn, vi, 0/*not pasted or cut*/, tb->insert_size [0]);
-    }
-  
-    /* set right merge flag we take right delimiting key and check whether it is a mergeable item */
-    if (tb->CFR[0]) {
-	struct reiserfs_key * key;
-
-	key = B_N_PDELIM_KEY (tb->CFR[0], tb->rkey[0]);
-	if (op_is_left_mergeable (key, Sh->b_size) && (vn->vn_mode != M_DELETE ||
-						       vn->vn_affected_item_num != B_NR_ITEMS (Sh) - 1))
-		vn->vn_vi[vn->vn_nr_item-1].vi_type |= VI_TYPE_RIGHT_MERGEABLE;
+	/* first virtual item */
+	vn->vn_vi = (struct virtual_item *)(tb->tb_vn + 1);
+	memset(vn->vn_vi, 0, vn->vn_nr_item * sizeof(struct virtual_item));
+	vn->vn_free_ptr += vn->vn_nr_item * sizeof(struct virtual_item);
 
-#ifdef CONFIG_REISERFS_CHECK
-	if (op_is_left_mergeable (key, Sh->b_size) &&
-	    !(vn->vn_mode != M_DELETE || vn->vn_affected_item_num != B_NR_ITEMS (Sh) - 1) ) {
-	    /* we delete last item and it could be merged with right neighbor's first item */
-	    if (!(B_NR_ITEMS (Sh) == 1 && is_direntry_le_ih (B_N_PITEM_HEAD (Sh, 0)) &&
-		  I_ENTRY_COUNT (B_N_PITEM_HEAD (Sh, 0)) == 1)) {
-		/* node contains more than 1 item, or item is not directory item, or this item contains more than 1 entry */
-		print_block (Sh, 0, -1, -1);
-		reiserfs_panic (tb->tb_sb, "vs-8045: create_virtual_node: rdkey %k, affected item==%d (mode==%c) Must be %c", 
-				key, vn->vn_affected_item_num, vn->vn_mode, M_DELETE);
-	    } else
-		/* we can delete directory item, that has only one directory entry in it */
-		;
+	/* first item in the node */
+	ih = B_N_PITEM_HEAD(Sh, 0);
+
+	/* define the mergeability for 0-th item (if it is not being deleted) */
+	if (op_is_left_mergeable(&(ih->ih_key), Sh->b_size)
+	    && (vn->vn_mode != M_DELETE || vn->vn_affected_item_num))
+		vn->vn_vi[0].vi_type |= VI_TYPE_LEFT_MERGEABLE;
+
+	/* go through all items those remain in the virtual node (except for the new (inserted) one) */
+	for (new_num = 0; new_num < vn->vn_nr_item; new_num++) {
+		int j;
+		struct virtual_item *vi = vn->vn_vi + new_num;
+		int is_affected =
+		    ((new_num != vn->vn_affected_item_num) ? 0 : 1);
+
+		if (is_affected && vn->vn_mode == M_INSERT)
+			continue;
+
+		/* get item number in source node */
+		j = old_item_num(new_num, vn->vn_affected_item_num,
+				 vn->vn_mode);
+
+		vi->vi_item_len += ih_item_len(ih + j) + IH_SIZE;
+		vi->vi_ih = ih + j;
+		vi->vi_item = B_I_PITEM(Sh, ih + j);
+		vi->vi_uarea = vn->vn_free_ptr;
+
+		// FIXME: there is no check, that item operation did not
+		// consume too much memory
+		vn->vn_free_ptr +=
+		    op_create_vi(vn, vi, is_affected, tb->insert_size[0]);
+		if (tb->vn_buf + tb->vn_buf_size < vn->vn_free_ptr)
+			reiserfs_panic(tb->tb_sb,
+				       "vs-8030: create_virtual_node: "
+				       "virtual node space consumed");
+
+		if (!is_affected)
+			/* this is not being changed */
+			continue;
+
+		if (vn->vn_mode == M_PASTE || vn->vn_mode == M_CUT) {
+			vn->vn_vi[new_num].vi_item_len += tb->insert_size[0];
+			vi->vi_new_data = vn->vn_data;	// pointer to data which is going to be pasted
+		}
 	}
+
+	/* virtual inserted item is not defined yet */
+	if (vn->vn_mode == M_INSERT) {
+		struct virtual_item *vi = vn->vn_vi + vn->vn_affected_item_num;
+
+		RFALSE(vn->vn_ins_ih == 0,
+		       "vs-8040: item header of inserted item is not specified");
+		vi->vi_item_len = tb->insert_size[0];
+		vi->vi_ih = vn->vn_ins_ih;
+		vi->vi_item = vn->vn_data;
+		vi->vi_uarea = vn->vn_free_ptr;
+
+		op_create_vi(vn, vi, 0 /*not pasted or cut */ ,
+			     tb->insert_size[0]);
+	}
+
+	/* set right merge flag we take right delimiting key and check whether it is a mergeable item */
+	if (tb->CFR[0]) {
+		struct reiserfs_key *key;
+
+		key = B_N_PDELIM_KEY(tb->CFR[0], tb->rkey[0]);
+		if (op_is_left_mergeable(key, Sh->b_size)
+		    && (vn->vn_mode != M_DELETE
+			|| vn->vn_affected_item_num != B_NR_ITEMS(Sh) - 1))
+			vn->vn_vi[vn->vn_nr_item - 1].vi_type |=
+			    VI_TYPE_RIGHT_MERGEABLE;
+
+#ifdef CONFIG_REISERFS_CHECK
+		if (op_is_left_mergeable(key, Sh->b_size) &&
+		    !(vn->vn_mode != M_DELETE
+		      || vn->vn_affected_item_num != B_NR_ITEMS(Sh) - 1)) {
+			/* we delete last item and it could be merged with right neighbor's first item */
+			if (!
+			    (B_NR_ITEMS(Sh) == 1
+			     && is_direntry_le_ih(B_N_PITEM_HEAD(Sh, 0))
+			     && I_ENTRY_COUNT(B_N_PITEM_HEAD(Sh, 0)) == 1)) {
+				/* node contains more than 1 item, or item is not directory item, or this item contains more than 1 entry */
+				print_block(Sh, 0, -1, -1);
+				reiserfs_panic(tb->tb_sb,
+					       "vs-8045: create_virtual_node: rdkey %k, affected item==%d (mode==%c) Must be %c",
+					       key, vn->vn_affected_item_num,
+					       vn->vn_mode, M_DELETE);
+			} else
+				/* we can delete directory item, that has only one directory entry in it */
+				;
+		}
 #endif
-    
-    }
-}
 
+	}
+}
 
 /* using virtual node check, how many items can be shifted to left
    neighbor */
-static void check_left (struct tree_balance * tb, int h, int cur_free)
+static void check_left(struct tree_balance *tb, int h, int cur_free)
 {
-    int i;
-    struct virtual_node * vn = tb->tb_vn;
-    struct virtual_item * vi;
-    int d_size, ih_size;
-
-    RFALSE( cur_free < 0, "vs-8050: cur_free (%d) < 0", cur_free);
-
-    /* internal level */
-    if (h > 0) {	
-	tb->lnum[h] = cur_free / (DC_SIZE + KEY_SIZE);
-	return;
-    }
+	int i;
+	struct virtual_node *vn = tb->tb_vn;
+	struct virtual_item *vi;
+	int d_size, ih_size;
 
-    /* leaf level */
+	RFALSE(cur_free < 0, "vs-8050: cur_free (%d) < 0", cur_free);
 
-    if (!cur_free || !vn->vn_nr_item) {
-	/* no free space or nothing to move */
-	tb->lnum[h] = 0;
-	tb->lbytes = -1;
-	return;
-    }
+	/* internal level */
+	if (h > 0) {
+		tb->lnum[h] = cur_free / (DC_SIZE + KEY_SIZE);
+		return;
+	}
 
-    RFALSE( !PATH_H_PPARENT (tb->tb_path, 0),
-	    "vs-8055: parent does not exist or invalid");
+	/* leaf level */
 
-    vi = vn->vn_vi;
-    if ((unsigned int)cur_free >= (vn->vn_size - ((vi->vi_type & VI_TYPE_LEFT_MERGEABLE) ? IH_SIZE : 0))) {
-	/* all contents of S[0] fits into L[0] */
+	if (!cur_free || !vn->vn_nr_item) {
+		/* no free space or nothing to move */
+		tb->lnum[h] = 0;
+		tb->lbytes = -1;
+		return;
+	}
 
-	RFALSE( vn->vn_mode == M_INSERT || vn->vn_mode == M_PASTE,
-		"vs-8055: invalid mode or balance condition failed");
+	RFALSE(!PATH_H_PPARENT(tb->tb_path, 0),
+	       "vs-8055: parent does not exist or invalid");
 
-	tb->lnum[0] = vn->vn_nr_item;
-	tb->lbytes = -1;
-	return;
-    }
-  
+	vi = vn->vn_vi;
+	if ((unsigned int)cur_free >=
+	    (vn->vn_size -
+	     ((vi->vi_type & VI_TYPE_LEFT_MERGEABLE) ? IH_SIZE : 0))) {
+		/* all contents of S[0] fits into L[0] */
 
-    d_size = 0, ih_size = IH_SIZE;
+		RFALSE(vn->vn_mode == M_INSERT || vn->vn_mode == M_PASTE,
+		       "vs-8055: invalid mode or balance condition failed");
 
-    /* first item may be merge with last item in left neighbor */
-    if (vi->vi_type & VI_TYPE_LEFT_MERGEABLE)
-	d_size = -((int)IH_SIZE), ih_size = 0;
-
-    tb->lnum[0] = 0;
-    for (i = 0; i < vn->vn_nr_item; i ++, ih_size = IH_SIZE, d_size = 0, vi ++) {
-	d_size += vi->vi_item_len;
-	if (cur_free >= d_size) {	
-	    /* the item can be shifted entirely */
-	    cur_free -= d_size;
-	    tb->lnum[0] ++;
-	    continue;
-	}
-      
-	/* the item cannot be shifted entirely, try to split it */
-	/* check whether L[0] can hold ih and at least one byte of the item body */
-	if (cur_free <= ih_size) {
-	    /* cannot shift even a part of the current item */
-	    tb->lbytes = -1;
-	    return;
-	}
-	cur_free -= ih_size;
-    
-	tb->lbytes = op_check_left (vi, cur_free, 0, 0);
-	if (tb->lbytes != -1)
-	    /* count partially shifted item */
-	    tb->lnum[0] ++;
-    
-	break;
-    }
-  
-    return;
-}
+		tb->lnum[0] = vn->vn_nr_item;
+		tb->lbytes = -1;
+		return;
+	}
+
+	d_size = 0, ih_size = IH_SIZE;
 
+	/* first item may be merge with last item in left neighbor */
+	if (vi->vi_type & VI_TYPE_LEFT_MERGEABLE)
+		d_size = -((int)IH_SIZE), ih_size = 0;
+
+	tb->lnum[0] = 0;
+	for (i = 0; i < vn->vn_nr_item;
+	     i++, ih_size = IH_SIZE, d_size = 0, vi++) {
+		d_size += vi->vi_item_len;
+		if (cur_free >= d_size) {
+			/* the item can be shifted entirely */
+			cur_free -= d_size;
+			tb->lnum[0]++;
+			continue;
+		}
+
+		/* the item cannot be shifted entirely, try to split it */
+		/* check whether L[0] can hold ih and at least one byte of the item body */
+		if (cur_free <= ih_size) {
+			/* cannot shift even a part of the current item */
+			tb->lbytes = -1;
+			return;
+		}
+		cur_free -= ih_size;
+
+		tb->lbytes = op_check_left(vi, cur_free, 0, 0);
+		if (tb->lbytes != -1)
+			/* count partially shifted item */
+			tb->lnum[0]++;
+
+		break;
+	}
+
+	return;
+}
 
 /* using virtual node check, how many items can be shifted to right
    neighbor */
-static void check_right (struct tree_balance * tb, int h, int cur_free)
+static void check_right(struct tree_balance *tb, int h, int cur_free)
 {
-    int i;
-    struct virtual_node * vn = tb->tb_vn;
-    struct virtual_item * vi;
-    int d_size, ih_size;
-
-    RFALSE( cur_free < 0, "vs-8070: cur_free < 0");
-    
-    /* internal level */
-    if (h > 0) {
-	tb->rnum[h] = cur_free / (DC_SIZE + KEY_SIZE);
-	return;
-    }
-    
-    /* leaf level */
-    
-    if (!cur_free || !vn->vn_nr_item) {
-	/* no free space  */
-	tb->rnum[h] = 0;
-	tb->rbytes = -1;
-	return;
-    }
-  
-    RFALSE( !PATH_H_PPARENT (tb->tb_path, 0),
-	    "vs-8075: parent does not exist or invalid");
-  
-    vi = vn->vn_vi + vn->vn_nr_item - 1;
-    if ((unsigned int)cur_free >= (vn->vn_size - ((vi->vi_type & VI_TYPE_RIGHT_MERGEABLE) ? IH_SIZE : 0))) {
-	/* all contents of S[0] fits into R[0] */
-	
-	RFALSE( vn->vn_mode == M_INSERT || vn->vn_mode == M_PASTE,
-		"vs-8080: invalid mode or balance condition failed");
+	int i;
+	struct virtual_node *vn = tb->tb_vn;
+	struct virtual_item *vi;
+	int d_size, ih_size;
+
+	RFALSE(cur_free < 0, "vs-8070: cur_free < 0");
+
+	/* internal level */
+	if (h > 0) {
+		tb->rnum[h] = cur_free / (DC_SIZE + KEY_SIZE);
+		return;
+	}
+
+	/* leaf level */
+
+	if (!cur_free || !vn->vn_nr_item) {
+		/* no free space  */
+		tb->rnum[h] = 0;
+		tb->rbytes = -1;
+		return;
+	}
+
+	RFALSE(!PATH_H_PPARENT(tb->tb_path, 0),
+	       "vs-8075: parent does not exist or invalid");
+
+	vi = vn->vn_vi + vn->vn_nr_item - 1;
+	if ((unsigned int)cur_free >=
+	    (vn->vn_size -
+	     ((vi->vi_type & VI_TYPE_RIGHT_MERGEABLE) ? IH_SIZE : 0))) {
+		/* all contents of S[0] fits into R[0] */
+
+		RFALSE(vn->vn_mode == M_INSERT || vn->vn_mode == M_PASTE,
+		       "vs-8080: invalid mode or balance condition failed");
+
+		tb->rnum[h] = vn->vn_nr_item;
+		tb->rbytes = -1;
+		return;
+	}
+
+	d_size = 0, ih_size = IH_SIZE;
+
+	/* last item may be merge with first item in right neighbor */
+	if (vi->vi_type & VI_TYPE_RIGHT_MERGEABLE)
+		d_size = -(int)IH_SIZE, ih_size = 0;
+
+	tb->rnum[0] = 0;
+	for (i = vn->vn_nr_item - 1; i >= 0;
+	     i--, d_size = 0, ih_size = IH_SIZE, vi--) {
+		d_size += vi->vi_item_len;
+		if (cur_free >= d_size) {
+			/* the item can be shifted entirely */
+			cur_free -= d_size;
+			tb->rnum[0]++;
+			continue;
+		}
+
+		/* check whether R[0] can hold ih and at least one byte of the item body */
+		if (cur_free <= ih_size) {	/* cannot shift even a part of the current item */
+			tb->rbytes = -1;
+			return;
+		}
+
+		/* R[0] can hold the header of the item and at least one byte of its body */
+		cur_free -= ih_size;	/* cur_free is still > 0 */
+
+		tb->rbytes = op_check_right(vi, cur_free);
+		if (tb->rbytes != -1)
+			/* count partially shifted item */
+			tb->rnum[0]++;
+
+		break;
+	}
 
-	tb->rnum[h] = vn->vn_nr_item;
-	tb->rbytes = -1;
 	return;
-    }
-    
-    d_size = 0, ih_size = IH_SIZE;
-    
-    /* last item may be merge with first item in right neighbor */
-    if (vi->vi_type & VI_TYPE_RIGHT_MERGEABLE)
-	d_size = -(int)IH_SIZE, ih_size = 0;
-
-    tb->rnum[0] = 0;
-    for (i = vn->vn_nr_item - 1; i >= 0; i --, d_size = 0, ih_size = IH_SIZE, vi --) {
-	d_size += vi->vi_item_len;
-	if (cur_free >= d_size) {	
-	    /* the item can be shifted entirely */
-	    cur_free -= d_size;
-	    tb->rnum[0] ++;
-	    continue;
-	}
-	
-	/* check whether R[0] can hold ih and at least one byte of the item body */
-	if ( cur_free <= ih_size ) {    /* cannot shift even a part of the current item */
-	    tb->rbytes = -1;
-	    return;
-	}
-	
-	/* R[0] can hold the header of the item and at least one byte of its body */
-	cur_free -= ih_size;	/* cur_free is still > 0 */
-
-	tb->rbytes = op_check_right (vi, cur_free);
-	if (tb->rbytes != -1)
-	    /* count partially shifted item */
-	    tb->rnum[0] ++;
-    
-	break;
-    }
-	
-  return;
 }
 
-
 /*
  * from - number of items, which are shifted to left neighbor entirely
  * to - number of item, which are shifted to right neighbor entirely
  * from_bytes - number of bytes of boundary item (or directory entries) which are shifted to left neighbor
  * to_bytes - number of bytes of boundary item (or directory entries) which are shifted to right neighbor */
-static int get_num_ver (int mode, struct tree_balance * tb, int h,
-			int from, int from_bytes,
-			int to,   int to_bytes,
-			short * snum012, int flow
-    )
+static int get_num_ver(int mode, struct tree_balance *tb, int h,
+		       int from, int from_bytes,
+		       int to, int to_bytes, short *snum012, int flow)
 {
-    int i;
-    int cur_free;
-    //    int bytes;
-    int units;
-    struct virtual_node * vn = tb->tb_vn;
-    //    struct virtual_item * vi;
-
-    int total_node_size, max_node_size, current_item_size;
-    int needed_nodes;
-    int start_item, 	/* position of item we start filling node from */
-	end_item,	/* position of item we finish filling node by */
-	start_bytes,/* number of first bytes (entries for directory) of start_item-th item 
-		       we do not include into node that is being filled */
-	end_bytes;	/* number of last bytes (entries for directory) of end_item-th item 
-			   we do node include into node that is being filled */
-    int split_item_positions[2]; /* these are positions in virtual item of
-				    items, that are split between S[0] and
-				    S1new and S1new and S2new */
-
-    split_item_positions[0] = -1;
-    split_item_positions[1] = -1;
-
-    /* We only create additional nodes if we are in insert or paste mode
-       or we are in replace mode at the internal level. If h is 0 and
-       the mode is M_REPLACE then in fix_nodes we change the mode to
-       paste or insert before we get here in the code.  */
-    RFALSE( tb->insert_size[h] < 0  || (mode != M_INSERT && mode != M_PASTE),
-	    "vs-8100: insert_size < 0 in overflow");
-
-    max_node_size = MAX_CHILD_SIZE (PATH_H_PBUFFER (tb->tb_path, h));
-
-    /* snum012 [0-2] - number of items, that lay
-       to S[0], first new node and second new node */
-    snum012[3] = -1;	/* s1bytes */
-    snum012[4] = -1;	/* s2bytes */
-
-    /* internal level */
-    if (h > 0) {
-	i = ((to - from) * (KEY_SIZE + DC_SIZE) + DC_SIZE);
-	if (i == max_node_size)
-	    return 1;
-	return (i / max_node_size + 1);
-    }
-
-    /* leaf level */
-    needed_nodes = 1;
-    total_node_size = 0;
-    cur_free = max_node_size;
-
-    // start from 'from'-th item
-    start_item = from;
-    // skip its first 'start_bytes' units
-    start_bytes = ((from_bytes != -1) ? from_bytes : 0);
-
-    // last included item is the 'end_item'-th one
-    end_item = vn->vn_nr_item - to - 1;
-    // do not count last 'end_bytes' units of 'end_item'-th item
-    end_bytes = (to_bytes != -1) ? to_bytes : 0;
-
-    /* go through all item beginning from the start_item-th item and ending by
-       the end_item-th item. Do not count first 'start_bytes' units of
-       'start_item'-th item and last 'end_bytes' of 'end_item'-th item */
-    
-    for (i = start_item; i <= end_item; i ++) {
-	struct virtual_item * vi = vn->vn_vi + i;
-	int skip_from_end = ((i == end_item) ? end_bytes : 0);
-
-	RFALSE( needed_nodes > 3, "vs-8105: too many nodes are needed");
-
-	/* get size of current item */
-	current_item_size = vi->vi_item_len;
-
-	/* do not take in calculation head part (from_bytes) of from-th item */
-	current_item_size -= op_part_size (vi, 0/*from start*/, start_bytes);
-
-	/* do not take in calculation tail part of last item */
-	current_item_size -= op_part_size (vi, 1/*from end*/, skip_from_end);
-
-	/* if item fits into current node entierly */
-	if (total_node_size + current_item_size <= max_node_size) {
-	    snum012[needed_nodes - 1] ++;
-	    total_node_size += current_item_size;
-	    start_bytes = 0;
-	    continue;
-	}
-
-	if (current_item_size > max_node_size) {
-	    /* virtual item length is longer, than max size of item in
-               a node. It is impossible for direct item */
-	    RFALSE( is_direct_le_ih (vi->vi_ih),
-		    "vs-8110: "
-		    "direct item length is %d. It can not be longer than %d",
-		    current_item_size, max_node_size);
-	    /* we will try to split it */
-	    flow = 1;
-	}
-
-	if (!flow) {
-	    /* as we do not split items, take new node and continue */
-	    needed_nodes ++; i --; total_node_size = 0;
-	    continue;
+	int i;
+	int cur_free;
+	//    int bytes;
+	int units;
+	struct virtual_node *vn = tb->tb_vn;
+	//    struct virtual_item * vi;
+
+	int total_node_size, max_node_size, current_item_size;
+	int needed_nodes;
+	int start_item,		/* position of item we start filling node from */
+	 end_item,		/* position of item we finish filling node by */
+	 start_bytes,		/* number of first bytes (entries for directory) of start_item-th item 
+				   we do not include into node that is being filled */
+	 end_bytes;		/* number of last bytes (entries for directory) of end_item-th item 
+				   we do node include into node that is being filled */
+	int split_item_positions[2];	/* these are positions in virtual item of
+					   items, that are split between S[0] and
+					   S1new and S1new and S2new */
+
+	split_item_positions[0] = -1;
+	split_item_positions[1] = -1;
+
+	/* We only create additional nodes if we are in insert or paste mode
+	   or we are in replace mode at the internal level. If h is 0 and
+	   the mode is M_REPLACE then in fix_nodes we change the mode to
+	   paste or insert before we get here in the code.  */
+	RFALSE(tb->insert_size[h] < 0 || (mode != M_INSERT && mode != M_PASTE),
+	       "vs-8100: insert_size < 0 in overflow");
+
+	max_node_size = MAX_CHILD_SIZE(PATH_H_PBUFFER(tb->tb_path, h));
+
+	/* snum012 [0-2] - number of items, that lay
+	   to S[0], first new node and second new node */
+	snum012[3] = -1;	/* s1bytes */
+	snum012[4] = -1;	/* s2bytes */
+
+	/* internal level */
+	if (h > 0) {
+		i = ((to - from) * (KEY_SIZE + DC_SIZE) + DC_SIZE);
+		if (i == max_node_size)
+			return 1;
+		return (i / max_node_size + 1);
 	}
 
-	// calculate number of item units which fit into node being
-	// filled
-	{
-	    int free_space;
-
-	    free_space = max_node_size - total_node_size - IH_SIZE;
-	    units = op_check_left (vi, free_space, start_bytes, skip_from_end);
-	    if (units == -1) {
-		/* nothing fits into current node, take new node and continue */
-		needed_nodes ++, i--, total_node_size = 0;
-		continue;
-	    }
-	}
-
-	/* something fits into the current node */
-	//if (snum012[3] != -1 || needed_nodes != 1)
-	//  reiserfs_panic (tb->tb_sb, "vs-8115: get_num_ver: too many nodes required");
-	//snum012[needed_nodes - 1 + 3] = op_unit_num (vi) - start_bytes - units;
-	start_bytes += units;
-	snum012[needed_nodes - 1 + 3] = units;
-
-	if (needed_nodes > 2)
-	    reiserfs_warning (tb->tb_sb, "vs-8111: get_num_ver: "
-			      "split_item_position is out of boundary");
-	snum012[needed_nodes - 1] ++;
-	split_item_positions[needed_nodes - 1] = i;
-	needed_nodes ++;
-	/* continue from the same item with start_bytes != -1 */
-	start_item = i;
-	i --;
+	/* leaf level */
+	needed_nodes = 1;
 	total_node_size = 0;
-    }
+	cur_free = max_node_size;
 
-    // sum012[4] (if it is not -1) contains number of units of which
-    // are to be in S1new, snum012[3] - to be in S0. They are supposed
-    // to be S1bytes and S2bytes correspondingly, so recalculate
-    if (snum012[4] > 0) {
-	int split_item_num;
-	int bytes_to_r, bytes_to_l;
-	int bytes_to_S1new;
-    
-	split_item_num = split_item_positions[1];
-	bytes_to_l = ((from == split_item_num && from_bytes != -1) ? from_bytes : 0);
-	bytes_to_r = ((end_item == split_item_num && end_bytes != -1) ? end_bytes : 0);
-	bytes_to_S1new = ((split_item_positions[0] == split_item_positions[1]) ? snum012[3] : 0);
-
-	// s2bytes
-	snum012[4] = op_unit_num (&vn->vn_vi[split_item_num]) - snum012[4] - bytes_to_r - bytes_to_l - bytes_to_S1new;
-
-	if (vn->vn_vi[split_item_num].vi_index != TYPE_DIRENTRY &&
-	    vn->vn_vi[split_item_num].vi_index != TYPE_INDIRECT)
-	    reiserfs_warning (tb->tb_sb, "vs-8115: get_num_ver: not "
-			      "directory or indirect item");
-    }
-
-    /* now we know S2bytes, calculate S1bytes */
-    if (snum012[3] > 0) {
-	int split_item_num;
-	int bytes_to_r, bytes_to_l;
-	int bytes_to_S2new;
-    
-	split_item_num = split_item_positions[0];
-	bytes_to_l = ((from == split_item_num && from_bytes != -1) ? from_bytes : 0);
-	bytes_to_r = ((end_item == split_item_num && end_bytes != -1) ? end_bytes : 0);
-	bytes_to_S2new = ((split_item_positions[0] == split_item_positions[1] && snum012[4] != -1) ? snum012[4] : 0);
-
-	// s1bytes
-	snum012[3] = op_unit_num (&vn->vn_vi[split_item_num]) - snum012[3] - bytes_to_r - bytes_to_l - bytes_to_S2new;
-    }
-    
-    return needed_nodes;
-}
+	// start from 'from'-th item
+	start_item = from;
+	// skip its first 'start_bytes' units
+	start_bytes = ((from_bytes != -1) ? from_bytes : 0);
+
+	// last included item is the 'end_item'-th one
+	end_item = vn->vn_nr_item - to - 1;
+	// do not count last 'end_bytes' units of 'end_item'-th item
+	end_bytes = (to_bytes != -1) ? to_bytes : 0;
+
+	/* go through all item beginning from the start_item-th item and ending by
+	   the end_item-th item. Do not count first 'start_bytes' units of
+	   'start_item'-th item and last 'end_bytes' of 'end_item'-th item */
+
+	for (i = start_item; i <= end_item; i++) {
+		struct virtual_item *vi = vn->vn_vi + i;
+		int skip_from_end = ((i == end_item) ? end_bytes : 0);
+
+		RFALSE(needed_nodes > 3, "vs-8105: too many nodes are needed");
+
+		/* get size of current item */
+		current_item_size = vi->vi_item_len;
+
+		/* do not take in calculation head part (from_bytes) of from-th item */
+		current_item_size -=
+		    op_part_size(vi, 0 /*from start */ , start_bytes);
+
+		/* do not take in calculation tail part of last item */
+		current_item_size -=
+		    op_part_size(vi, 1 /*from end */ , skip_from_end);
+
+		/* if item fits into current node entierly */
+		if (total_node_size + current_item_size <= max_node_size) {
+			snum012[needed_nodes - 1]++;
+			total_node_size += current_item_size;
+			start_bytes = 0;
+			continue;
+		}
 
+		if (current_item_size > max_node_size) {
+			/* virtual item length is longer, than max size of item in
+			   a node. It is impossible for direct item */
+			RFALSE(is_direct_le_ih(vi->vi_ih),
+			       "vs-8110: "
+			       "direct item length is %d. It can not be longer than %d",
+			       current_item_size, max_node_size);
+			/* we will try to split it */
+			flow = 1;
+		}
+
+		if (!flow) {
+			/* as we do not split items, take new node and continue */
+			needed_nodes++;
+			i--;
+			total_node_size = 0;
+			continue;
+		}
+		// calculate number of item units which fit into node being
+		// filled
+		{
+			int free_space;
+
+			free_space = max_node_size - total_node_size - IH_SIZE;
+			units =
+			    op_check_left(vi, free_space, start_bytes,
+					  skip_from_end);
+			if (units == -1) {
+				/* nothing fits into current node, take new node and continue */
+				needed_nodes++, i--, total_node_size = 0;
+				continue;
+			}
+		}
+
+		/* something fits into the current node */
+		//if (snum012[3] != -1 || needed_nodes != 1)
+		//  reiserfs_panic (tb->tb_sb, "vs-8115: get_num_ver: too many nodes required");
+		//snum012[needed_nodes - 1 + 3] = op_unit_num (vi) - start_bytes - units;
+		start_bytes += units;
+		snum012[needed_nodes - 1 + 3] = units;
+
+		if (needed_nodes > 2)
+			reiserfs_warning(tb->tb_sb, "vs-8111: get_num_ver: "
+					 "split_item_position is out of boundary");
+		snum012[needed_nodes - 1]++;
+		split_item_positions[needed_nodes - 1] = i;
+		needed_nodes++;
+		/* continue from the same item with start_bytes != -1 */
+		start_item = i;
+		i--;
+		total_node_size = 0;
+	}
+
+	// sum012[4] (if it is not -1) contains number of units of which
+	// are to be in S1new, snum012[3] - to be in S0. They are supposed
+	// to be S1bytes and S2bytes correspondingly, so recalculate
+	if (snum012[4] > 0) {
+		int split_item_num;
+		int bytes_to_r, bytes_to_l;
+		int bytes_to_S1new;
+
+		split_item_num = split_item_positions[1];
+		bytes_to_l =
+		    ((from == split_item_num
+		      && from_bytes != -1) ? from_bytes : 0);
+		bytes_to_r =
+		    ((end_item == split_item_num
+		      && end_bytes != -1) ? end_bytes : 0);
+		bytes_to_S1new =
+		    ((split_item_positions[0] ==
+		      split_item_positions[1]) ? snum012[3] : 0);
+
+		// s2bytes
+		snum012[4] =
+		    op_unit_num(&vn->vn_vi[split_item_num]) - snum012[4] -
+		    bytes_to_r - bytes_to_l - bytes_to_S1new;
+
+		if (vn->vn_vi[split_item_num].vi_index != TYPE_DIRENTRY &&
+		    vn->vn_vi[split_item_num].vi_index != TYPE_INDIRECT)
+			reiserfs_warning(tb->tb_sb, "vs-8115: get_num_ver: not "
+					 "directory or indirect item");
+	}
+
+	/* now we know S2bytes, calculate S1bytes */
+	if (snum012[3] > 0) {
+		int split_item_num;
+		int bytes_to_r, bytes_to_l;
+		int bytes_to_S2new;
+
+		split_item_num = split_item_positions[0];
+		bytes_to_l =
+		    ((from == split_item_num
+		      && from_bytes != -1) ? from_bytes : 0);
+		bytes_to_r =
+		    ((end_item == split_item_num
+		      && end_bytes != -1) ? end_bytes : 0);
+		bytes_to_S2new =
+		    ((split_item_positions[0] == split_item_positions[1]
+		      && snum012[4] != -1) ? snum012[4] : 0);
+
+		// s1bytes
+		snum012[3] =
+		    op_unit_num(&vn->vn_vi[split_item_num]) - snum012[3] -
+		    bytes_to_r - bytes_to_l - bytes_to_S2new;
+	}
+
+	return needed_nodes;
+}
 
 #ifdef CONFIG_REISERFS_CHECK
-extern struct tree_balance * cur_tb;
+extern struct tree_balance *cur_tb;
 #endif
 
-
 /* Set parameters for balancing.
  * Performs write of results of analysis of balancing into structure tb,
  * where it will later be used by the functions that actually do the balancing. 
@@ -557,131 +587,130 @@ extern struct tree_balance * cur_tb;
  *	s1bytes	number of bytes which flow to the first  new node when S[0] splits (this number is contained in s012 array)
  */
 
-static void set_parameters (struct tree_balance * tb, int h, int lnum,
-			    int rnum, int blk_num, short * s012, int lb, int rb)
+static void set_parameters(struct tree_balance *tb, int h, int lnum,
+			   int rnum, int blk_num, short *s012, int lb, int rb)
 {
 
-  tb->lnum[h] = lnum;
-  tb->rnum[h] = rnum;
-  tb->blknum[h] = blk_num;
-
-  if (h == 0)
-    {  /* only for leaf level */
-      if (s012 != NULL)
-	{
-	  tb->s0num = * s012 ++,
-	  tb->s1num = * s012 ++,
-	  tb->s2num = * s012 ++;
-	  tb->s1bytes = * s012 ++;
-	  tb->s2bytes = * s012;
-	}
-      tb->lbytes = lb;
-      tb->rbytes = rb;
-    }
-  PROC_INFO_ADD( tb -> tb_sb, lnum[ h ], lnum );
-  PROC_INFO_ADD( tb -> tb_sb, rnum[ h ], rnum );
+	tb->lnum[h] = lnum;
+	tb->rnum[h] = rnum;
+	tb->blknum[h] = blk_num;
+
+	if (h == 0) {		/* only for leaf level */
+		if (s012 != NULL) {
+			tb->s0num = *s012++,
+			    tb->s1num = *s012++, tb->s2num = *s012++;
+			tb->s1bytes = *s012++;
+			tb->s2bytes = *s012;
+		}
+		tb->lbytes = lb;
+		tb->rbytes = rb;
+	}
+	PROC_INFO_ADD(tb->tb_sb, lnum[h], lnum);
+	PROC_INFO_ADD(tb->tb_sb, rnum[h], rnum);
 
-  PROC_INFO_ADD( tb -> tb_sb, lbytes[ h ], lb );
-  PROC_INFO_ADD( tb -> tb_sb, rbytes[ h ], rb );
+	PROC_INFO_ADD(tb->tb_sb, lbytes[h], lb);
+	PROC_INFO_ADD(tb->tb_sb, rbytes[h], rb);
 }
 
-
-
 /* check, does node disappear if we shift tb->lnum[0] items to left
    neighbor and tb->rnum[0] to the right one. */
-static int is_leaf_removable (struct tree_balance * tb)
+static int is_leaf_removable(struct tree_balance *tb)
 {
-  struct virtual_node * vn = tb->tb_vn;
-  int to_left, to_right;
-  int size;
-  int remain_items;
-
-  /* number of items, that will be shifted to left (right) neighbor
-     entirely */
-  to_left = tb->lnum[0] - ((tb->lbytes != -1) ? 1 : 0);
-  to_right = tb->rnum[0] - ((tb->rbytes != -1) ? 1 : 0);
-  remain_items = vn->vn_nr_item;
-
-  /* how many items remain in S[0] after shiftings to neighbors */
-  remain_items -= (to_left + to_right);
-
-  if (remain_items < 1) {
-    /* all content of node can be shifted to neighbors */
-    set_parameters (tb, 0, to_left, vn->vn_nr_item - to_left, 0, NULL, -1, -1);    
-    return 1;
-  }
-  
-  if (remain_items > 1 || tb->lbytes == -1 || tb->rbytes == -1)
-    /* S[0] is not removable */
-    return 0;
-
-  /* check, whether we can divide 1 remaining item between neighbors */
-
-  /* get size of remaining item (in item units) */
-  size = op_unit_num (&(vn->vn_vi[to_left]));
-
-  if (tb->lbytes + tb->rbytes >= size) {
-    set_parameters (tb, 0, to_left + 1, to_right + 1, 0, NULL, tb->lbytes, -1);
-    return 1;
-  }
+	struct virtual_node *vn = tb->tb_vn;
+	int to_left, to_right;
+	int size;
+	int remain_items;
+
+	/* number of items, that will be shifted to left (right) neighbor
+	   entirely */
+	to_left = tb->lnum[0] - ((tb->lbytes != -1) ? 1 : 0);
+	to_right = tb->rnum[0] - ((tb->rbytes != -1) ? 1 : 0);
+	remain_items = vn->vn_nr_item;
+
+	/* how many items remain in S[0] after shiftings to neighbors */
+	remain_items -= (to_left + to_right);
+
+	if (remain_items < 1) {
+		/* all content of node can be shifted to neighbors */
+		set_parameters(tb, 0, to_left, vn->vn_nr_item - to_left, 0,
+			       NULL, -1, -1);
+		return 1;
+	}
+
+	if (remain_items > 1 || tb->lbytes == -1 || tb->rbytes == -1)
+		/* S[0] is not removable */
+		return 0;
+
+	/* check, whether we can divide 1 remaining item between neighbors */
+
+	/* get size of remaining item (in item units) */
+	size = op_unit_num(&(vn->vn_vi[to_left]));
+
+	if (tb->lbytes + tb->rbytes >= size) {
+		set_parameters(tb, 0, to_left + 1, to_right + 1, 0, NULL,
+			       tb->lbytes, -1);
+		return 1;
+	}
 
-  return 0;
+	return 0;
 }
 
-
 /* check whether L, S, R can be joined in one node */
-static int are_leaves_removable (struct tree_balance * tb, int lfree, int rfree)
+static int are_leaves_removable(struct tree_balance *tb, int lfree, int rfree)
 {
-  struct virtual_node * vn = tb->tb_vn;
-  int ih_size;
-  struct buffer_head *S0;
-
-  S0 = PATH_H_PBUFFER (tb->tb_path, 0);
-
-  ih_size = 0;
-  if (vn->vn_nr_item) {
-    if (vn->vn_vi[0].vi_type & VI_TYPE_LEFT_MERGEABLE)
-      ih_size += IH_SIZE;
-    
-	if (vn->vn_vi[vn->vn_nr_item-1].vi_type & VI_TYPE_RIGHT_MERGEABLE)
-	    ih_size += IH_SIZE;
-    } else {
-	/* there was only one item and it will be deleted */
-	struct item_head * ih;
-    
-    RFALSE( B_NR_ITEMS (S0) != 1,
-	    "vs-8125: item number must be 1: it is %d", B_NR_ITEMS(S0));
-
-    ih = B_N_PITEM_HEAD (S0, 0);
-    if (tb->CFR[0] && !comp_short_le_keys (&(ih->ih_key), B_N_PDELIM_KEY (tb->CFR[0], tb->rkey[0])))
-	if (is_direntry_le_ih (ih)) {
-	    /* Directory must be in correct state here: that is
-	       somewhere at the left side should exist first directory
-	       item. But the item being deleted can not be that first
-	       one because its right neighbor is item of the same
-	       directory. (But first item always gets deleted in last
-	       turn). So, neighbors of deleted item can be merged, so
-	       we can save ih_size */
-	    ih_size = IH_SIZE;
-	    
-	    /* we might check that left neighbor exists and is of the
-	       same directory */
-	    RFALSE(le_ih_k_offset (ih) == DOT_OFFSET,
-		"vs-8130: first directory item can not be removed until directory is not empty");
-      }
-    
-  }
-
-  if (MAX_CHILD_SIZE (S0) + vn->vn_size <= rfree + lfree + ih_size) {
-    set_parameters (tb, 0, -1, -1, -1, NULL, -1, -1);
-    PROC_INFO_INC( tb -> tb_sb, leaves_removable );
-    return 1;  
-  }
-  return 0;
-  
-}
+	struct virtual_node *vn = tb->tb_vn;
+	int ih_size;
+	struct buffer_head *S0;
+
+	S0 = PATH_H_PBUFFER(tb->tb_path, 0);
+
+	ih_size = 0;
+	if (vn->vn_nr_item) {
+		if (vn->vn_vi[0].vi_type & VI_TYPE_LEFT_MERGEABLE)
+			ih_size += IH_SIZE;
+
+		if (vn->vn_vi[vn->vn_nr_item - 1].
+		    vi_type & VI_TYPE_RIGHT_MERGEABLE)
+			ih_size += IH_SIZE;
+	} else {
+		/* there was only one item and it will be deleted */
+		struct item_head *ih;
+
+		RFALSE(B_NR_ITEMS(S0) != 1,
+		       "vs-8125: item number must be 1: it is %d",
+		       B_NR_ITEMS(S0));
+
+		ih = B_N_PITEM_HEAD(S0, 0);
+		if (tb->CFR[0]
+		    && !comp_short_le_keys(&(ih->ih_key),
+					   B_N_PDELIM_KEY(tb->CFR[0],
+							  tb->rkey[0])))
+			if (is_direntry_le_ih(ih)) {
+				/* Directory must be in correct state here: that is
+				   somewhere at the left side should exist first directory
+				   item. But the item being deleted can not be that first
+				   one because its right neighbor is item of the same
+				   directory. (But first item always gets deleted in last
+				   turn). So, neighbors of deleted item can be merged, so
+				   we can save ih_size */
+				ih_size = IH_SIZE;
+
+				/* we might check that left neighbor exists and is of the
+				   same directory */
+				RFALSE(le_ih_k_offset(ih) == DOT_OFFSET,
+				       "vs-8130: first directory item can not be removed until directory is not empty");
+			}
 
+	}
+
+	if (MAX_CHILD_SIZE(S0) + vn->vn_size <= rfree + lfree + ih_size) {
+		set_parameters(tb, 0, -1, -1, -1, NULL, -1, -1);
+		PROC_INFO_INC(tb->tb_sb, leaves_removable);
+		return 1;
+	}
+	return 0;
 
+}
 
 /* when we do not split item, lnum and rnum are numbers of entire items */
 #define SET_PAR_SHIFT_LEFT \
@@ -704,7 +733,6 @@ else \
 		     -1, -1);\
 }
 
-
 #define SET_PAR_SHIFT_RIGHT \
 if (h)\
 {\
@@ -724,30 +752,27 @@ else \
 		  -1, -1);\
 }
 
+static void free_buffers_in_tb(struct tree_balance *p_s_tb)
+{
+	int n_counter;
 
-static void free_buffers_in_tb (
-		       struct tree_balance * p_s_tb
-		       ) {
-  int n_counter;
-
-  decrement_counters_in_path(p_s_tb->tb_path);
-  
-  for ( n_counter = 0; n_counter < MAX_HEIGHT; n_counter++ ) {
-    decrement_bcount(p_s_tb->L[n_counter]);
-    p_s_tb->L[n_counter] = NULL;
-    decrement_bcount(p_s_tb->R[n_counter]);
-    p_s_tb->R[n_counter] = NULL;
-    decrement_bcount(p_s_tb->FL[n_counter]);
-    p_s_tb->FL[n_counter] = NULL;
-    decrement_bcount(p_s_tb->FR[n_counter]);
-    p_s_tb->FR[n_counter] = NULL;
-    decrement_bcount(p_s_tb->CFL[n_counter]);
-    p_s_tb->CFL[n_counter] = NULL;
-    decrement_bcount(p_s_tb->CFR[n_counter]);
-    p_s_tb->CFR[n_counter] = NULL;
-  }
-}
+	decrement_counters_in_path(p_s_tb->tb_path);
 
+	for (n_counter = 0; n_counter < MAX_HEIGHT; n_counter++) {
+		decrement_bcount(p_s_tb->L[n_counter]);
+		p_s_tb->L[n_counter] = NULL;
+		decrement_bcount(p_s_tb->R[n_counter]);
+		p_s_tb->R[n_counter] = NULL;
+		decrement_bcount(p_s_tb->FL[n_counter]);
+		p_s_tb->FL[n_counter] = NULL;
+		decrement_bcount(p_s_tb->FR[n_counter]);
+		p_s_tb->FR[n_counter] = NULL;
+		decrement_bcount(p_s_tb->CFL[n_counter]);
+		p_s_tb->CFL[n_counter] = NULL;
+		decrement_bcount(p_s_tb->CFR[n_counter]);
+		p_s_tb->CFR[n_counter] = NULL;
+	}
+}
 
 /* Get new buffers for storing new nodes that are created while balancing.
  * Returns:	SCHEDULE_OCCURRED - schedule occurred while the function worked;
@@ -755,183 +780,171 @@ static void free_buffers_in_tb (
  *	        NO_DISK_SPACE - no disk space.
  */
 /* The function is NOT SCHEDULE-SAFE! */
-static int  get_empty_nodes(
-              struct tree_balance * p_s_tb,
-              int n_h
-            ) {
-  struct buffer_head  * p_s_new_bh,
-    		      *	p_s_Sh = PATH_H_PBUFFER (p_s_tb->tb_path, n_h);
-  b_blocknr_t	      *	p_n_blocknr,
-    			a_n_blocknrs[MAX_AMOUNT_NEEDED] = {0, };
-  int       		n_counter,
-   			n_number_of_freeblk,
-                	n_amount_needed,/* number of needed empty blocks */
-			n_retval = CARRY_ON;
-  struct super_block *	p_s_sb = p_s_tb->tb_sb;
-
-
-  /* number_of_freeblk is the number of empty blocks which have been
-     acquired for use by the balancing algorithm minus the number of
-     empty blocks used in the previous levels of the analysis,
-     number_of_freeblk = tb->cur_blknum can be non-zero if a schedule occurs
-     after empty blocks are acquired, and the balancing analysis is
-     then restarted, amount_needed is the number needed by this level
-     (n_h) of the balancing analysis.
-			    
-     Note that for systems with many processes writing, it would be
-     more layout optimal to calculate the total number needed by all
-     levels and then to run reiserfs_new_blocks to get all of them at once.  */
-
-  /* Initiate number_of_freeblk to the amount acquired prior to the restart of
-     the analysis or 0 if not restarted, then subtract the amount needed
-     by all of the levels of the tree below n_h. */
-  /* blknum includes S[n_h], so we subtract 1 in this calculation */
-  for ( n_counter = 0, n_number_of_freeblk = p_s_tb->cur_blknum; n_counter < n_h; n_counter++ )
-    n_number_of_freeblk -= ( p_s_tb->blknum[n_counter] ) ? (p_s_tb->blknum[n_counter] - 1) : 0;
-
-  /* Allocate missing empty blocks. */
-  /* if p_s_Sh == 0  then we are getting a new root */
-  n_amount_needed = ( p_s_Sh ) ? (p_s_tb->blknum[n_h] - 1) : 1;
-  /*  Amount_needed = the amount that we need more than the amount that we have. */
-  if ( n_amount_needed > n_number_of_freeblk )
-    n_amount_needed -= n_number_of_freeblk;
-  else /* If we have enough already then there is nothing to do. */
-    return CARRY_ON;
-
-  /* No need to check quota - is not allocated for blocks used for formatted nodes */
-  if (reiserfs_new_form_blocknrs (p_s_tb, a_n_blocknrs,
-                                   n_amount_needed) == NO_DISK_SPACE)
-    return NO_DISK_SPACE;
-
-  /* for each blocknumber we just got, get a buffer and stick it on FEB */
-  for ( p_n_blocknr = a_n_blocknrs, n_counter = 0; n_counter < n_amount_needed;
-	p_n_blocknr++, n_counter++ ) { 
-
-    RFALSE( ! *p_n_blocknr,
-	    "PAP-8135: reiserfs_new_blocknrs failed when got new blocks");
-
-    p_s_new_bh = sb_getblk(p_s_sb, *p_n_blocknr);
-    RFALSE (buffer_dirty (p_s_new_bh) ||
-	    buffer_journaled (p_s_new_bh) ||
-	    buffer_journal_dirty (p_s_new_bh),
-	    "PAP-8140: journlaled or dirty buffer %b for the new block", 
-	    p_s_new_bh);
-    
-    /* Put empty buffers into the array. */
-    RFALSE (p_s_tb->FEB[p_s_tb->cur_blknum],
-	    "PAP-8141: busy slot for new buffer");
-
-    set_buffer_journal_new (p_s_new_bh);
-    p_s_tb->FEB[p_s_tb->cur_blknum++] = p_s_new_bh;
-  }
+static int get_empty_nodes(struct tree_balance *p_s_tb, int n_h)
+{
+	struct buffer_head *p_s_new_bh,
+	    *p_s_Sh = PATH_H_PBUFFER(p_s_tb->tb_path, n_h);
+	b_blocknr_t *p_n_blocknr, a_n_blocknrs[MAX_AMOUNT_NEEDED] = { 0, };
+	int n_counter, n_number_of_freeblk, n_amount_needed,	/* number of needed empty blocks */
+	 n_retval = CARRY_ON;
+	struct super_block *p_s_sb = p_s_tb->tb_sb;
+
+	/* number_of_freeblk is the number of empty blocks which have been
+	   acquired for use by the balancing algorithm minus the number of
+	   empty blocks used in the previous levels of the analysis,
+	   number_of_freeblk = tb->cur_blknum can be non-zero if a schedule occurs
+	   after empty blocks are acquired, and the balancing analysis is
+	   then restarted, amount_needed is the number needed by this level
+	   (n_h) of the balancing analysis.
+
+	   Note that for systems with many processes writing, it would be
+	   more layout optimal to calculate the total number needed by all
+	   levels and then to run reiserfs_new_blocks to get all of them at once.  */
+
+	/* Initiate number_of_freeblk to the amount acquired prior to the restart of
+	   the analysis or 0 if not restarted, then subtract the amount needed
+	   by all of the levels of the tree below n_h. */
+	/* blknum includes S[n_h], so we subtract 1 in this calculation */
+	for (n_counter = 0, n_number_of_freeblk = p_s_tb->cur_blknum;
+	     n_counter < n_h; n_counter++)
+		n_number_of_freeblk -=
+		    (p_s_tb->blknum[n_counter]) ? (p_s_tb->blknum[n_counter] -
+						   1) : 0;
+
+	/* Allocate missing empty blocks. */
+	/* if p_s_Sh == 0  then we are getting a new root */
+	n_amount_needed = (p_s_Sh) ? (p_s_tb->blknum[n_h] - 1) : 1;
+	/*  Amount_needed = the amount that we need more than the amount that we have. */
+	if (n_amount_needed > n_number_of_freeblk)
+		n_amount_needed -= n_number_of_freeblk;
+	else			/* If we have enough already then there is nothing to do. */
+		return CARRY_ON;
+
+	/* No need to check quota - is not allocated for blocks used for formatted nodes */
+	if (reiserfs_new_form_blocknrs(p_s_tb, a_n_blocknrs,
+				       n_amount_needed) == NO_DISK_SPACE)
+		return NO_DISK_SPACE;
+
+	/* for each blocknumber we just got, get a buffer and stick it on FEB */
+	for (p_n_blocknr = a_n_blocknrs, n_counter = 0;
+	     n_counter < n_amount_needed; p_n_blocknr++, n_counter++) {
+
+		RFALSE(!*p_n_blocknr,
+		       "PAP-8135: reiserfs_new_blocknrs failed when got new blocks");
+
+		p_s_new_bh = sb_getblk(p_s_sb, *p_n_blocknr);
+		RFALSE(buffer_dirty(p_s_new_bh) ||
+		       buffer_journaled(p_s_new_bh) ||
+		       buffer_journal_dirty(p_s_new_bh),
+		       "PAP-8140: journlaled or dirty buffer %b for the new block",
+		       p_s_new_bh);
+
+		/* Put empty buffers into the array. */
+		RFALSE(p_s_tb->FEB[p_s_tb->cur_blknum],
+		       "PAP-8141: busy slot for new buffer");
 
-  if ( n_retval == CARRY_ON && FILESYSTEM_CHANGED_TB (p_s_tb) )
-    n_retval = REPEAT_SEARCH ;
+		set_buffer_journal_new(p_s_new_bh);
+		p_s_tb->FEB[p_s_tb->cur_blknum++] = p_s_new_bh;
+	}
 
-  return n_retval;
-}
+	if (n_retval == CARRY_ON && FILESYSTEM_CHANGED_TB(p_s_tb))
+		n_retval = REPEAT_SEARCH;
 
+	return n_retval;
+}
 
 /* Get free space of the left neighbor, which is stored in the parent
  * node of the left neighbor.  */
-static int get_lfree (struct tree_balance * tb, int h)
+static int get_lfree(struct tree_balance *tb, int h)
 {
-    struct buffer_head * l, * f;
-    int order;
+	struct buffer_head *l, *f;
+	int order;
 
-    if ((f = PATH_H_PPARENT (tb->tb_path, h)) == 0 || (l = tb->FL[h]) == 0)
-	return 0;
+	if ((f = PATH_H_PPARENT(tb->tb_path, h)) == 0 || (l = tb->FL[h]) == 0)
+		return 0;
 
-    if (f == l)
-	order = PATH_H_B_ITEM_ORDER (tb->tb_path, h) - 1;
-    else {
-	order = B_NR_ITEMS (l);
-	f = l;
-    }
+	if (f == l)
+		order = PATH_H_B_ITEM_ORDER(tb->tb_path, h) - 1;
+	else {
+		order = B_NR_ITEMS(l);
+		f = l;
+	}
 
-    return (MAX_CHILD_SIZE(f) - dc_size(B_N_CHILD(f,order)));
+	return (MAX_CHILD_SIZE(f) - dc_size(B_N_CHILD(f, order)));
 }
 
-
 /* Get free space of the right neighbor,
  * which is stored in the parent node of the right neighbor.
  */
-static int get_rfree (struct tree_balance * tb, int h)
+static int get_rfree(struct tree_balance *tb, int h)
 {
-  struct buffer_head * r, * f;
-  int order;
+	struct buffer_head *r, *f;
+	int order;
 
-  if ((f = PATH_H_PPARENT (tb->tb_path, h)) == 0 || (r = tb->FR[h]) == 0)
-    return 0;
+	if ((f = PATH_H_PPARENT(tb->tb_path, h)) == 0 || (r = tb->FR[h]) == 0)
+		return 0;
 
-  if (f == r)
-      order = PATH_H_B_ITEM_ORDER (tb->tb_path, h) + 1;
-  else {
-      order = 0;
-      f = r;
-  }
+	if (f == r)
+		order = PATH_H_B_ITEM_ORDER(tb->tb_path, h) + 1;
+	else {
+		order = 0;
+		f = r;
+	}
 
-  return (MAX_CHILD_SIZE(f) - dc_size( B_N_CHILD(f,order)));
+	return (MAX_CHILD_SIZE(f) - dc_size(B_N_CHILD(f, order)));
 
 }
 
-
 /* Check whether left neighbor is in memory. */
-static int  is_left_neighbor_in_cache(
-              struct tree_balance * p_s_tb,
-              int                   n_h
-            ) {
-  struct buffer_head  * p_s_father, * left;
-  struct super_block  * p_s_sb = p_s_tb->tb_sb;
-  b_blocknr_t		n_left_neighbor_blocknr;
-  int                   n_left_neighbor_position;
-
-  if ( ! p_s_tb->FL[n_h] ) /* Father of the left neighbor does not exist. */
-    return 0;
-
-  /* Calculate father of the node to be balanced. */
-  p_s_father = PATH_H_PBUFFER(p_s_tb->tb_path, n_h + 1);
-
-  RFALSE( ! p_s_father || 
-	  ! B_IS_IN_TREE (p_s_father) || 
-	  ! B_IS_IN_TREE (p_s_tb->FL[n_h]) ||
-	  ! buffer_uptodate (p_s_father) || 
-	  ! buffer_uptodate (p_s_tb->FL[n_h]),
-	  "vs-8165: F[h] (%b) or FL[h] (%b) is invalid", 
-	  p_s_father, p_s_tb->FL[n_h]);
-
-
-  /* Get position of the pointer to the left neighbor into the left father. */
-  n_left_neighbor_position = ( p_s_father == p_s_tb->FL[n_h] ) ?
-                      p_s_tb->lkey[n_h] : B_NR_ITEMS (p_s_tb->FL[n_h]);
-  /* Get left neighbor block number. */
-  n_left_neighbor_blocknr = B_N_CHILD_NUM(p_s_tb->FL[n_h], n_left_neighbor_position);
-  /* Look for the left neighbor in the cache. */
-  if ( (left = sb_find_get_block(p_s_sb, n_left_neighbor_blocknr)) ) {
-
-    RFALSE( buffer_uptodate (left) && ! B_IS_IN_TREE(left),
-	    "vs-8170: left neighbor (%b %z) is not in the tree", left, left);
-    put_bh(left) ;
-    return 1;
-  }
+static int is_left_neighbor_in_cache(struct tree_balance *p_s_tb, int n_h)
+{
+	struct buffer_head *p_s_father, *left;
+	struct super_block *p_s_sb = p_s_tb->tb_sb;
+	b_blocknr_t n_left_neighbor_blocknr;
+	int n_left_neighbor_position;
+
+	if (!p_s_tb->FL[n_h])	/* Father of the left neighbor does not exist. */
+		return 0;
+
+	/* Calculate father of the node to be balanced. */
+	p_s_father = PATH_H_PBUFFER(p_s_tb->tb_path, n_h + 1);
+
+	RFALSE(!p_s_father ||
+	       !B_IS_IN_TREE(p_s_father) ||
+	       !B_IS_IN_TREE(p_s_tb->FL[n_h]) ||
+	       !buffer_uptodate(p_s_father) ||
+	       !buffer_uptodate(p_s_tb->FL[n_h]),
+	       "vs-8165: F[h] (%b) or FL[h] (%b) is invalid",
+	       p_s_father, p_s_tb->FL[n_h]);
+
+	/* Get position of the pointer to the left neighbor into the left father. */
+	n_left_neighbor_position = (p_s_father == p_s_tb->FL[n_h]) ?
+	    p_s_tb->lkey[n_h] : B_NR_ITEMS(p_s_tb->FL[n_h]);
+	/* Get left neighbor block number. */
+	n_left_neighbor_blocknr =
+	    B_N_CHILD_NUM(p_s_tb->FL[n_h], n_left_neighbor_position);
+	/* Look for the left neighbor in the cache. */
+	if ((left = sb_find_get_block(p_s_sb, n_left_neighbor_blocknr))) {
+
+		RFALSE(buffer_uptodate(left) && !B_IS_IN_TREE(left),
+		       "vs-8170: left neighbor (%b %z) is not in the tree",
+		       left, left);
+		put_bh(left);
+		return 1;
+	}
 
-  return 0;
+	return 0;
 }
 
-
 #define LEFT_PARENTS  'l'
 #define RIGHT_PARENTS 'r'
 
-
-static void decrement_key (struct cpu_key * p_s_key)
+static void decrement_key(struct cpu_key *p_s_key)
 {
-    // call item specific function for this key
-    item_ops[cpu_key_k_type (p_s_key)]->decrement_key (p_s_key);
+	// call item specific function for this key
+	item_ops[cpu_key_k_type(p_s_key)]->decrement_key(p_s_key);
 }
 
-
-
-
 /* Calculate far left/right parent of the left/right neighbor of the current node, that
  * is calculate the left/right (FL[h]/FR[h]) neighbor of the parent F[h].
  * Calculate left/right common parent of the current node and L[h]/R[h].
@@ -940,111 +953,121 @@ static void decrement_key (struct cpu_ke
  		SCHEDULE_OCCURRED - schedule occurred while the function worked;
  *	        CARRY_ON         - schedule didn't occur while the function worked;
  */
-static int  get_far_parent (struct tree_balance *   p_s_tb,
-			    int                     n_h,
-			    struct buffer_head  **  pp_s_father,
-			    struct buffer_head  **  pp_s_com_father,
-			    char                    c_lr_par) 
-{
-    struct buffer_head  * p_s_parent;
-    INITIALIZE_PATH (s_path_to_neighbor_father);
-    struct path * p_s_path = p_s_tb->tb_path;
-    struct cpu_key	s_lr_father_key;
-    int                   n_counter,
-	n_position = INT_MAX,
-	n_first_last_position = 0,
-	n_path_offset = PATH_H_PATH_OFFSET(p_s_path, n_h);
-
-    /* Starting from F[n_h] go upwards in the tree, and look for the common
-      ancestor of F[n_h], and its neighbor l/r, that should be obtained. */
-
-    n_counter = n_path_offset;
-
-    RFALSE( n_counter < FIRST_PATH_ELEMENT_OFFSET,
-	    "PAP-8180: invalid path length");
-
-  
-    for ( ; n_counter > FIRST_PATH_ELEMENT_OFFSET; n_counter--  )  {
-	/* Check whether parent of the current buffer in the path is really parent in the tree. */
-	if ( ! B_IS_IN_TREE(p_s_parent = PATH_OFFSET_PBUFFER(p_s_path, n_counter - 1)) )
-	    return REPEAT_SEARCH;
-	/* Check whether position in the parent is correct. */
-	if ( (n_position = PATH_OFFSET_POSITION(p_s_path, n_counter - 1)) > B_NR_ITEMS(p_s_parent) )
-	    return REPEAT_SEARCH;
-	/* Check whether parent at the path really points to the child. */
-	if ( B_N_CHILD_NUM(p_s_parent, n_position) !=
-	     PATH_OFFSET_PBUFFER(p_s_path, n_counter)->b_blocknr )
-	    return REPEAT_SEARCH;
-	/* Return delimiting key if position in the parent is not equal to first/last one. */
-	if ( c_lr_par == RIGHT_PARENTS )
-	    n_first_last_position = B_NR_ITEMS (p_s_parent);
-	if ( n_position != n_first_last_position ) {
-	    *pp_s_com_father = p_s_parent;
-	    get_bh(*pp_s_com_father) ;
-	    /*(*pp_s_com_father = p_s_parent)->b_count++;*/
-	    break;
-	}
-    }
-
-    /* if we are in the root of the tree, then there is no common father */
-    if ( n_counter == FIRST_PATH_ELEMENT_OFFSET ) {
-	/* Check whether first buffer in the path is the root of the tree. */
-	if ( PATH_OFFSET_PBUFFER(p_s_tb->tb_path, FIRST_PATH_ELEMENT_OFFSET)->b_blocknr ==
-	     SB_ROOT_BLOCK (p_s_tb->tb_sb) ) {
-	    *pp_s_father = *pp_s_com_father = NULL;
-	    return CARRY_ON;
-	}
-	return REPEAT_SEARCH;
-    }
-
-    RFALSE( B_LEVEL (*pp_s_com_father) <= DISK_LEAF_NODE_LEVEL,
-	    "PAP-8185: (%b %z) level too small", 
-	    *pp_s_com_father, *pp_s_com_father);
-
-    /* Check whether the common parent is locked. */
-
-    if ( buffer_locked (*pp_s_com_father) ) {
-	__wait_on_buffer(*pp_s_com_father);
-	if ( FILESYSTEM_CHANGED_TB (p_s_tb) ) {
-	    decrement_bcount(*pp_s_com_father);
-	    return REPEAT_SEARCH;
-	}
-    }
-
-    /* So, we got common parent of the current node and its left/right neighbor.
-     Now we are geting the parent of the left/right neighbor. */
-
-    /* Form key to get parent of the left/right neighbor. */
-    le_key2cpu_key (&s_lr_father_key, B_N_PDELIM_KEY(*pp_s_com_father, ( c_lr_par == LEFT_PARENTS ) ?
-						     (p_s_tb->lkey[n_h - 1] = n_position - 1) : (p_s_tb->rkey[n_h - 1] = n_position)));
-
-
-    if ( c_lr_par == LEFT_PARENTS )
-	decrement_key(&s_lr_father_key);
-
-    if (search_by_key(p_s_tb->tb_sb, &s_lr_father_key, &s_path_to_neighbor_father, n_h + 1) == IO_ERROR)
-	// path is released
-	return IO_ERROR;
+static int get_far_parent(struct tree_balance *p_s_tb,
+			  int n_h,
+			  struct buffer_head **pp_s_father,
+			  struct buffer_head **pp_s_com_father, char c_lr_par)
+{
+	struct buffer_head *p_s_parent;
+	INITIALIZE_PATH(s_path_to_neighbor_father);
+	struct path *p_s_path = p_s_tb->tb_path;
+	struct cpu_key s_lr_father_key;
+	int n_counter,
+	    n_position = INT_MAX,
+	    n_first_last_position = 0,
+	    n_path_offset = PATH_H_PATH_OFFSET(p_s_path, n_h);
+
+	/* Starting from F[n_h] go upwards in the tree, and look for the common
+	   ancestor of F[n_h], and its neighbor l/r, that should be obtained. */
+
+	n_counter = n_path_offset;
+
+	RFALSE(n_counter < FIRST_PATH_ELEMENT_OFFSET,
+	       "PAP-8180: invalid path length");
+
+	for (; n_counter > FIRST_PATH_ELEMENT_OFFSET; n_counter--) {
+		/* Check whether parent of the current buffer in the path is really parent in the tree. */
+		if (!B_IS_IN_TREE
+		    (p_s_parent = PATH_OFFSET_PBUFFER(p_s_path, n_counter - 1)))
+			return REPEAT_SEARCH;
+		/* Check whether position in the parent is correct. */
+		if ((n_position =
+		     PATH_OFFSET_POSITION(p_s_path,
+					  n_counter - 1)) >
+		    B_NR_ITEMS(p_s_parent))
+			return REPEAT_SEARCH;
+		/* Check whether parent at the path really points to the child. */
+		if (B_N_CHILD_NUM(p_s_parent, n_position) !=
+		    PATH_OFFSET_PBUFFER(p_s_path, n_counter)->b_blocknr)
+			return REPEAT_SEARCH;
+		/* Return delimiting key if position in the parent is not equal to first/last one. */
+		if (c_lr_par == RIGHT_PARENTS)
+			n_first_last_position = B_NR_ITEMS(p_s_parent);
+		if (n_position != n_first_last_position) {
+			*pp_s_com_father = p_s_parent;
+			get_bh(*pp_s_com_father);
+			/*(*pp_s_com_father = p_s_parent)->b_count++; */
+			break;
+		}
+	}
+
+	/* if we are in the root of the tree, then there is no common father */
+	if (n_counter == FIRST_PATH_ELEMENT_OFFSET) {
+		/* Check whether first buffer in the path is the root of the tree. */
+		if (PATH_OFFSET_PBUFFER
+		    (p_s_tb->tb_path,
+		     FIRST_PATH_ELEMENT_OFFSET)->b_blocknr ==
+		    SB_ROOT_BLOCK(p_s_tb->tb_sb)) {
+			*pp_s_father = *pp_s_com_father = NULL;
+			return CARRY_ON;
+		}
+		return REPEAT_SEARCH;
+	}
+
+	RFALSE(B_LEVEL(*pp_s_com_father) <= DISK_LEAF_NODE_LEVEL,
+	       "PAP-8185: (%b %z) level too small",
+	       *pp_s_com_father, *pp_s_com_father);
+
+	/* Check whether the common parent is locked. */
+
+	if (buffer_locked(*pp_s_com_father)) {
+		__wait_on_buffer(*pp_s_com_father);
+		if (FILESYSTEM_CHANGED_TB(p_s_tb)) {
+			decrement_bcount(*pp_s_com_father);
+			return REPEAT_SEARCH;
+		}
+	}
+
+	/* So, we got common parent of the current node and its left/right neighbor.
+	   Now we are geting the parent of the left/right neighbor. */
+
+	/* Form key to get parent of the left/right neighbor. */
+	le_key2cpu_key(&s_lr_father_key,
+		       B_N_PDELIM_KEY(*pp_s_com_father,
+				      (c_lr_par ==
+				       LEFT_PARENTS) ? (p_s_tb->lkey[n_h - 1] =
+							n_position -
+							1) : (p_s_tb->rkey[n_h -
+									   1] =
+							      n_position)));
+
+	if (c_lr_par == LEFT_PARENTS)
+		decrement_key(&s_lr_father_key);
+
+	if (search_by_key
+	    (p_s_tb->tb_sb, &s_lr_father_key, &s_path_to_neighbor_father,
+	     n_h + 1) == IO_ERROR)
+		// path is released
+		return IO_ERROR;
+
+	if (FILESYSTEM_CHANGED_TB(p_s_tb)) {
+		decrement_counters_in_path(&s_path_to_neighbor_father);
+		decrement_bcount(*pp_s_com_father);
+		return REPEAT_SEARCH;
+	}
+
+	*pp_s_father = PATH_PLAST_BUFFER(&s_path_to_neighbor_father);
 
-    if ( FILESYSTEM_CHANGED_TB (p_s_tb) ) {
+	RFALSE(B_LEVEL(*pp_s_father) != n_h + 1,
+	       "PAP-8190: (%b %z) level too small", *pp_s_father, *pp_s_father);
+	RFALSE(s_path_to_neighbor_father.path_length <
+	       FIRST_PATH_ELEMENT_OFFSET, "PAP-8192: path length is too small");
+
+	s_path_to_neighbor_father.path_length--;
 	decrement_counters_in_path(&s_path_to_neighbor_father);
-	decrement_bcount(*pp_s_com_father);
-	return REPEAT_SEARCH;
-    }
-
-    *pp_s_father = PATH_PLAST_BUFFER(&s_path_to_neighbor_father);
-
-    RFALSE( B_LEVEL (*pp_s_father) != n_h + 1,
-	    "PAP-8190: (%b %z) level too small", *pp_s_father, *pp_s_father);
-    RFALSE( s_path_to_neighbor_father.path_length < FIRST_PATH_ELEMENT_OFFSET,
-	    "PAP-8192: path length is too small");
-
-    s_path_to_neighbor_father.path_length--;
-    decrement_counters_in_path(&s_path_to_neighbor_father);
-    return CARRY_ON;
+	return CARRY_ON;
 }
 
-
 /* Get parents of neighbors of node in the path(S[n_path_offset]) and common parents of
  * S[n_path_offset] and L[n_path_offset]/R[n_path_offset]: F[n_path_offset], FL[n_path_offset],
  * FR[n_path_offset], CFL[n_path_offset], CFR[n_path_offset].
@@ -1052,122 +1075,127 @@ static int  get_far_parent (struct tree_
  * Returns:	SCHEDULE_OCCURRED - schedule occurred while the function worked;
  *	        CARRY_ON - schedule didn't occur while the function worked;
  */
-static int  get_parents (struct tree_balance * p_s_tb, int n_h)
+static int get_parents(struct tree_balance *p_s_tb, int n_h)
 {
-    struct path         * p_s_path = p_s_tb->tb_path;
-    int                   n_position,
-	n_ret_value,
-	n_path_offset = PATH_H_PATH_OFFSET(p_s_tb->tb_path, n_h);
-    struct buffer_head  * p_s_curf,
-	* p_s_curcf;
-
-    /* Current node is the root of the tree or will be root of the tree */
-    if ( n_path_offset <= FIRST_PATH_ELEMENT_OFFSET ) {
-	/* The root can not have parents.
-	   Release nodes which previously were obtained as parents of the current node neighbors. */
+	struct path *p_s_path = p_s_tb->tb_path;
+	int n_position,
+	    n_ret_value,
+	    n_path_offset = PATH_H_PATH_OFFSET(p_s_tb->tb_path, n_h);
+	struct buffer_head *p_s_curf, *p_s_curcf;
+
+	/* Current node is the root of the tree or will be root of the tree */
+	if (n_path_offset <= FIRST_PATH_ELEMENT_OFFSET) {
+		/* The root can not have parents.
+		   Release nodes which previously were obtained as parents of the current node neighbors. */
+		decrement_bcount(p_s_tb->FL[n_h]);
+		decrement_bcount(p_s_tb->CFL[n_h]);
+		decrement_bcount(p_s_tb->FR[n_h]);
+		decrement_bcount(p_s_tb->CFR[n_h]);
+		p_s_tb->FL[n_h] = p_s_tb->CFL[n_h] = p_s_tb->FR[n_h] =
+		    p_s_tb->CFR[n_h] = NULL;
+		return CARRY_ON;
+	}
+
+	/* Get parent FL[n_path_offset] of L[n_path_offset]. */
+	if ((n_position = PATH_OFFSET_POSITION(p_s_path, n_path_offset - 1))) {
+		/* Current node is not the first child of its parent. */
+		/*(p_s_curf = p_s_curcf = PATH_OFFSET_PBUFFER(p_s_path, n_path_offset - 1))->b_count += 2; */
+		p_s_curf = p_s_curcf =
+		    PATH_OFFSET_PBUFFER(p_s_path, n_path_offset - 1);
+		get_bh(p_s_curf);
+		get_bh(p_s_curf);
+		p_s_tb->lkey[n_h] = n_position - 1;
+	} else {
+		/* Calculate current parent of L[n_path_offset], which is the left neighbor of the current node.
+		   Calculate current common parent of L[n_path_offset] and the current node. Note that
+		   CFL[n_path_offset] not equal FL[n_path_offset] and CFL[n_path_offset] not equal F[n_path_offset].
+		   Calculate lkey[n_path_offset]. */
+		if ((n_ret_value = get_far_parent(p_s_tb, n_h + 1, &p_s_curf,
+						  &p_s_curcf,
+						  LEFT_PARENTS)) != CARRY_ON)
+			return n_ret_value;
+	}
+
 	decrement_bcount(p_s_tb->FL[n_h]);
+	p_s_tb->FL[n_h] = p_s_curf;	/* New initialization of FL[n_h]. */
 	decrement_bcount(p_s_tb->CFL[n_h]);
-	decrement_bcount(p_s_tb->FR[n_h]);
-	decrement_bcount(p_s_tb->CFR[n_h]);
-	p_s_tb->FL[n_h] = p_s_tb->CFL[n_h] = p_s_tb->FR[n_h] = p_s_tb->CFR[n_h] = NULL;
-	return CARRY_ON;
-    }
-  
-    /* Get parent FL[n_path_offset] of L[n_path_offset]. */
-    if ( (n_position = PATH_OFFSET_POSITION(p_s_path, n_path_offset - 1)) )  {
-	/* Current node is not the first child of its parent. */
-	/*(p_s_curf = p_s_curcf = PATH_OFFSET_PBUFFER(p_s_path, n_path_offset - 1))->b_count += 2;*/
-	p_s_curf = p_s_curcf = PATH_OFFSET_PBUFFER(p_s_path, n_path_offset - 1);
-	get_bh(p_s_curf) ;
-	get_bh(p_s_curf) ;
-	p_s_tb->lkey[n_h] = n_position - 1;
-    }
-    else  {
-	/* Calculate current parent of L[n_path_offset], which is the left neighbor of the current node.
-	   Calculate current common parent of L[n_path_offset] and the current node. Note that
-	   CFL[n_path_offset] not equal FL[n_path_offset] and CFL[n_path_offset] not equal F[n_path_offset].
-	   Calculate lkey[n_path_offset]. */
-	if ( (n_ret_value = get_far_parent(p_s_tb, n_h + 1, &p_s_curf,
-					   &p_s_curcf, LEFT_PARENTS)) != CARRY_ON )
-	    return n_ret_value;
-    }
-
-    decrement_bcount(p_s_tb->FL[n_h]);
-    p_s_tb->FL[n_h] = p_s_curf; /* New initialization of FL[n_h]. */
-    decrement_bcount(p_s_tb->CFL[n_h]);
-    p_s_tb->CFL[n_h] = p_s_curcf; /* New initialization of CFL[n_h]. */
-
-    RFALSE( (p_s_curf && !B_IS_IN_TREE (p_s_curf)) || 
-	    (p_s_curcf && !B_IS_IN_TREE (p_s_curcf)),
-	    "PAP-8195: FL (%b) or CFL (%b) is invalid", p_s_curf, p_s_curcf);
+	p_s_tb->CFL[n_h] = p_s_curcf;	/* New initialization of CFL[n_h]. */
+
+	RFALSE((p_s_curf && !B_IS_IN_TREE(p_s_curf)) ||
+	       (p_s_curcf && !B_IS_IN_TREE(p_s_curcf)),
+	       "PAP-8195: FL (%b) or CFL (%b) is invalid", p_s_curf, p_s_curcf);
 
 /* Get parent FR[n_h] of R[n_h]. */
 
 /* Current node is the last child of F[n_h]. FR[n_h] != F[n_h]. */
-    if ( n_position == B_NR_ITEMS (PATH_H_PBUFFER(p_s_path, n_h + 1)) ) {
+	if (n_position == B_NR_ITEMS(PATH_H_PBUFFER(p_s_path, n_h + 1))) {
 /* Calculate current parent of R[n_h], which is the right neighbor of F[n_h].
    Calculate current common parent of R[n_h] and current node. Note that CFR[n_h]
    not equal FR[n_path_offset] and CFR[n_h] not equal F[n_h]. */
-	if ( (n_ret_value = get_far_parent(p_s_tb, n_h + 1, &p_s_curf,  &p_s_curcf, RIGHT_PARENTS)) != CARRY_ON )
-	    return n_ret_value;
-    }
-    else {
+		if ((n_ret_value =
+		     get_far_parent(p_s_tb, n_h + 1, &p_s_curf, &p_s_curcf,
+				    RIGHT_PARENTS)) != CARRY_ON)
+			return n_ret_value;
+	} else {
 /* Current node is not the last child of its parent F[n_h]. */
-	/*(p_s_curf = p_s_curcf = PATH_OFFSET_PBUFFER(p_s_path, n_path_offset - 1))->b_count += 2;*/
-	p_s_curf = p_s_curcf = PATH_OFFSET_PBUFFER(p_s_path, n_path_offset - 1);
-	get_bh(p_s_curf) ;
-	get_bh(p_s_curf) ;
-	p_s_tb->rkey[n_h] = n_position;
-    }	
-
-    decrement_bcount(p_s_tb->FR[n_h]);
-    p_s_tb->FR[n_h] = p_s_curf; /* New initialization of FR[n_path_offset]. */
-    
-    decrement_bcount(p_s_tb->CFR[n_h]);
-    p_s_tb->CFR[n_h] = p_s_curcf; /* New initialization of CFR[n_path_offset]. */
-
-    RFALSE( (p_s_curf && !B_IS_IN_TREE (p_s_curf)) ||
-            (p_s_curcf && !B_IS_IN_TREE (p_s_curcf)),
-	    "PAP-8205: FR (%b) or CFR (%b) is invalid", p_s_curf, p_s_curcf);
+		/*(p_s_curf = p_s_curcf = PATH_OFFSET_PBUFFER(p_s_path, n_path_offset - 1))->b_count += 2; */
+		p_s_curf = p_s_curcf =
+		    PATH_OFFSET_PBUFFER(p_s_path, n_path_offset - 1);
+		get_bh(p_s_curf);
+		get_bh(p_s_curf);
+		p_s_tb->rkey[n_h] = n_position;
+	}
 
-    return CARRY_ON;
-}
+	decrement_bcount(p_s_tb->FR[n_h]);
+	p_s_tb->FR[n_h] = p_s_curf;	/* New initialization of FR[n_path_offset]. */
 
+	decrement_bcount(p_s_tb->CFR[n_h]);
+	p_s_tb->CFR[n_h] = p_s_curcf;	/* New initialization of CFR[n_path_offset]. */
+
+	RFALSE((p_s_curf && !B_IS_IN_TREE(p_s_curf)) ||
+	       (p_s_curcf && !B_IS_IN_TREE(p_s_curcf)),
+	       "PAP-8205: FR (%b) or CFR (%b) is invalid", p_s_curf, p_s_curcf);
+
+	return CARRY_ON;
+}
 
 /* it is possible to remove node as result of shiftings to
    neighbors even when we insert or paste item. */
-static inline int can_node_be_removed (int mode, int lfree, int sfree, int rfree, struct tree_balance * tb, int h)
+static inline int can_node_be_removed(int mode, int lfree, int sfree, int rfree,
+				      struct tree_balance *tb, int h)
 {
-    struct buffer_head * Sh = PATH_H_PBUFFER (tb->tb_path, h);
-    int levbytes = tb->insert_size[h];
-    struct item_head * ih;
-    struct reiserfs_key * r_key = NULL;
-
-    ih = B_N_PITEM_HEAD (Sh, 0);
-    if ( tb->CFR[h] )
-	r_key = B_N_PDELIM_KEY(tb->CFR[h],tb->rkey[h]);
-  
-    if (
-	lfree + rfree + sfree < MAX_CHILD_SIZE(Sh) + levbytes
-	/* shifting may merge items which might save space */
-	- (( ! h && op_is_left_mergeable (&(ih->ih_key), Sh->b_size) ) ? IH_SIZE : 0)
-	- (( ! h && r_key && op_is_left_mergeable (r_key, Sh->b_size) ) ? IH_SIZE : 0)
-	+ (( h ) ? KEY_SIZE : 0))
-    {
-	/* node can not be removed */
-	if (sfree >= levbytes ) { /* new item fits into node S[h] without any shifting */
-	    if ( ! h )
-		tb->s0num = B_NR_ITEMS(Sh) + ((mode == M_INSERT ) ? 1 : 0);
-	    set_parameters (tb, h, 0, 0, 1, NULL, -1, -1);
-	    return NO_BALANCING_NEEDED;
-	}
-    }
-    PROC_INFO_INC( tb -> tb_sb, can_node_be_removed[ h ] );
-    return !NO_BALANCING_NEEDED;
+	struct buffer_head *Sh = PATH_H_PBUFFER(tb->tb_path, h);
+	int levbytes = tb->insert_size[h];
+	struct item_head *ih;
+	struct reiserfs_key *r_key = NULL;
+
+	ih = B_N_PITEM_HEAD(Sh, 0);
+	if (tb->CFR[h])
+		r_key = B_N_PDELIM_KEY(tb->CFR[h], tb->rkey[h]);
+
+	if (lfree + rfree + sfree < MAX_CHILD_SIZE(Sh) + levbytes
+	    /* shifting may merge items which might save space */
+	    -
+	    ((!h
+	      && op_is_left_mergeable(&(ih->ih_key), Sh->b_size)) ? IH_SIZE : 0)
+	    -
+	    ((!h && r_key
+	      && op_is_left_mergeable(r_key, Sh->b_size)) ? IH_SIZE : 0)
+	    + ((h) ? KEY_SIZE : 0)) {
+		/* node can not be removed */
+		if (sfree >= levbytes) {	/* new item fits into node S[h] without any shifting */
+			if (!h)
+				tb->s0num =
+				    B_NR_ITEMS(Sh) +
+				    ((mode == M_INSERT) ? 1 : 0);
+			set_parameters(tb, h, 0, 0, 1, NULL, -1, -1);
+			return NO_BALANCING_NEEDED;
+		}
+	}
+	PROC_INFO_INC(tb->tb_sb, can_node_be_removed[h]);
+	return !NO_BALANCING_NEEDED;
 }
 
-
-
 /* Check whether current node S[h] is balanced when increasing its size by
  * Inserting or Pasting.
  * Calculate parameters for balancing for current level h.
@@ -1182,154 +1210,157 @@ static inline int can_node_be_removed (i
  *	       -2 - no disk space.
  */
 /* ip means Inserting or Pasting */
-static int ip_check_balance (struct tree_balance * tb, int h)
+static int ip_check_balance(struct tree_balance *tb, int h)
 {
-    struct virtual_node * vn = tb->tb_vn;
-    int levbytes,  /* Number of bytes that must be inserted into (value
-		      is negative if bytes are deleted) buffer which
-		      contains node being balanced.  The mnemonic is
-		      that the attempted change in node space used level
-		      is levbytes bytes. */
-	n_ret_value;
-
-    int lfree, sfree, rfree /* free space in L, S and R */;
-
-    /* nver is short for number of vertixes, and lnver is the number if
-       we shift to the left, rnver is the number if we shift to the
-       right, and lrnver is the number if we shift in both directions.
-       The goal is to minimize first the number of vertixes, and second,
-       the number of vertixes whose contents are changed by shifting,
-       and third the number of uncached vertixes whose contents are
-       changed by shifting and must be read from disk.  */
-    int nver, lnver, rnver, lrnver;
-
-    /* used at leaf level only, S0 = S[0] is the node being balanced,
-       sInum [ I = 0,1,2 ] is the number of items that will
-       remain in node SI after balancing.  S1 and S2 are new
-       nodes that might be created. */
-  
-    /* we perform 8 calls to get_num_ver().  For each call we calculate five parameters.
-       where 4th parameter is s1bytes and 5th - s2bytes
-    */
-    short snum012[40] = {0,};	/* s0num, s1num, s2num for 8 cases 
-				   0,1 - do not shift and do not shift but bottle
-				   2 - shift only whole item to left
-				   3 - shift to left and bottle as much as possible
-				   4,5 - shift to right	(whole items and as much as possible
-				   6,7 - shift to both directions (whole items and as much as possible)
-				*/
-
-    /* Sh is the node whose balance is currently being checked */
-    struct buffer_head * Sh;
-  
-    Sh = PATH_H_PBUFFER (tb->tb_path, h);
-    levbytes = tb->insert_size[h];
-  
-    /* Calculate balance parameters for creating new root. */
-    if ( ! Sh )  {
-	if ( ! h )
-	    reiserfs_panic (tb->tb_sb, "vs-8210: ip_check_balance: S[0] can not be 0");
-	switch ( n_ret_value = get_empty_nodes (tb, h) )  {
-	case CARRY_ON:
-	    set_parameters (tb, h, 0, 0, 1, NULL, -1, -1);
-	    return NO_BALANCING_NEEDED; /* no balancing for higher levels needed */
-
-	case NO_DISK_SPACE:
-	case REPEAT_SEARCH:
-	    return n_ret_value;
-	default:   
-	    reiserfs_panic(tb->tb_sb, "vs-8215: ip_check_balance: incorrect return value of get_empty_nodes");
-	}
-    }
-  
-    if ( (n_ret_value = get_parents (tb, h)) != CARRY_ON ) /* get parents of S[h] neighbors. */
-	return n_ret_value;
-  
-    sfree = B_FREE_SPACE (Sh);
-
-    /* get free space of neighbors */
-    rfree = get_rfree (tb, h);
-    lfree = get_lfree (tb, h);
-
-    if (can_node_be_removed (vn->vn_mode, lfree, sfree, rfree, tb, h) == NO_BALANCING_NEEDED)
-	/* and new item fits into node S[h] without any shifting */
-	return NO_BALANCING_NEEDED;
-     
-    create_virtual_node (tb, h);
-
-    /*	
-	determine maximal number of items we can shift to the left neighbor (in tb structure)
-	and the maximal number of bytes that can flow to the left neighbor
-	from the left most liquid item that cannot be shifted from S[0] entirely (returned value)
-    */
-    check_left (tb, h, lfree);
-
-    /*
-      determine maximal number of items we can shift to the right neighbor (in tb structure)
-      and the maximal number of bytes that can flow to the right neighbor
-      from the right most liquid item that cannot be shifted from S[0] entirely (returned value)
-    */
-    check_right (tb, h, rfree);
-
-
-    /* all contents of internal node S[h] can be moved into its
-       neighbors, S[h] will be removed after balancing */
-    if (h && (tb->rnum[h] + tb->lnum[h] >= vn->vn_nr_item + 1)) {
-	int to_r; 
-       
-	/* Since we are working on internal nodes, and our internal
-	   nodes have fixed size entries, then we can balance by the
-	   number of items rather than the space they consume.  In this
-	   routine we set the left node equal to the right node,
-	   allowing a difference of less than or equal to 1 child
-	   pointer. */
-	to_r = ((MAX_NR_KEY(Sh)<<1)+2-tb->lnum[h]-tb->rnum[h]+vn->vn_nr_item+1)/2 - 
-	    (MAX_NR_KEY(Sh) + 1 - tb->rnum[h]);
-	set_parameters (tb, h, vn->vn_nr_item + 1 - to_r, to_r, 0, NULL, -1, -1);
-	return CARRY_ON;
-    }
+	struct virtual_node *vn = tb->tb_vn;
+	int levbytes,		/* Number of bytes that must be inserted into (value
+				   is negative if bytes are deleted) buffer which
+				   contains node being balanced.  The mnemonic is
+				   that the attempted change in node space used level
+				   is levbytes bytes. */
+	 n_ret_value;
+
+	int lfree, sfree, rfree /* free space in L, S and R */ ;
+
+	/* nver is short for number of vertixes, and lnver is the number if
+	   we shift to the left, rnver is the number if we shift to the
+	   right, and lrnver is the number if we shift in both directions.
+	   The goal is to minimize first the number of vertixes, and second,
+	   the number of vertixes whose contents are changed by shifting,
+	   and third the number of uncached vertixes whose contents are
+	   changed by shifting and must be read from disk.  */
+	int nver, lnver, rnver, lrnver;
+
+	/* used at leaf level only, S0 = S[0] is the node being balanced,
+	   sInum [ I = 0,1,2 ] is the number of items that will
+	   remain in node SI after balancing.  S1 and S2 are new
+	   nodes that might be created. */
 
-    /* this checks balance condition, that any two neighboring nodes can not fit in one node */
-    RFALSE( h && 
-	    ( tb->lnum[h] >= vn->vn_nr_item + 1 || 
-	      tb->rnum[h] >= vn->vn_nr_item + 1),
-	    "vs-8220: tree is not balanced on internal level");
-    RFALSE( ! h && ((tb->lnum[h] >= vn->vn_nr_item && (tb->lbytes == -1)) ||
-		    (tb->rnum[h] >= vn->vn_nr_item && (tb->rbytes == -1)) ),
-	    "vs-8225: tree is not balanced on leaf level");
-
-    /* all contents of S[0] can be moved into its neighbors
-       S[0] will be removed after balancing. */
-    if (!h && is_leaf_removable (tb))
-	return CARRY_ON;
+	/* we perform 8 calls to get_num_ver().  For each call we calculate five parameters.
+	   where 4th parameter is s1bytes and 5th - s2bytes
+	 */
+	short snum012[40] = { 0, };	/* s0num, s1num, s2num for 8 cases 
+					   0,1 - do not shift and do not shift but bottle
+					   2 - shift only whole item to left
+					   3 - shift to left and bottle as much as possible
+					   4,5 - shift to right (whole items and as much as possible
+					   6,7 - shift to both directions (whole items and as much as possible)
+					 */
+
+	/* Sh is the node whose balance is currently being checked */
+	struct buffer_head *Sh;
+
+	Sh = PATH_H_PBUFFER(tb->tb_path, h);
+	levbytes = tb->insert_size[h];
+
+	/* Calculate balance parameters for creating new root. */
+	if (!Sh) {
+		if (!h)
+			reiserfs_panic(tb->tb_sb,
+				       "vs-8210: ip_check_balance: S[0] can not be 0");
+		switch (n_ret_value = get_empty_nodes(tb, h)) {
+		case CARRY_ON:
+			set_parameters(tb, h, 0, 0, 1, NULL, -1, -1);
+			return NO_BALANCING_NEEDED;	/* no balancing for higher levels needed */
+
+		case NO_DISK_SPACE:
+		case REPEAT_SEARCH:
+			return n_ret_value;
+		default:
+			reiserfs_panic(tb->tb_sb,
+				       "vs-8215: ip_check_balance: incorrect return value of get_empty_nodes");
+		}
+	}
 
+	if ((n_ret_value = get_parents(tb, h)) != CARRY_ON)	/* get parents of S[h] neighbors. */
+		return n_ret_value;
 
-    /* why do we perform this check here rather than earlier??
-       Answer: we can win 1 node in some cases above. Moreover we
-       checked it above, when we checked, that S[0] is not removable
-       in principle */
-    if (sfree >= levbytes) { /* new item fits into node S[h] without any shifting */
-	if ( ! h )
-	    tb->s0num = vn->vn_nr_item;
-	set_parameters (tb, h, 0, 0, 1, NULL, -1, -1);
-	return NO_BALANCING_NEEDED;
-    }
+	sfree = B_FREE_SPACE(Sh);
 
+	/* get free space of neighbors */
+	rfree = get_rfree(tb, h);
+	lfree = get_lfree(tb, h);
+
+	if (can_node_be_removed(vn->vn_mode, lfree, sfree, rfree, tb, h) ==
+	    NO_BALANCING_NEEDED)
+		/* and new item fits into node S[h] without any shifting */
+		return NO_BALANCING_NEEDED;
+
+	create_virtual_node(tb, h);
+
+	/*  
+	   determine maximal number of items we can shift to the left neighbor (in tb structure)
+	   and the maximal number of bytes that can flow to the left neighbor
+	   from the left most liquid item that cannot be shifted from S[0] entirely (returned value)
+	 */
+	check_left(tb, h, lfree);
 
-    {
-	int lpar, rpar, nset, lset, rset, lrset;
-	/* 
-	 * regular overflowing of the node
+	/*
+	   determine maximal number of items we can shift to the right neighbor (in tb structure)
+	   and the maximal number of bytes that can flow to the right neighbor
+	   from the right most liquid item that cannot be shifted from S[0] entirely (returned value)
 	 */
+	check_right(tb, h, rfree);
+
+	/* all contents of internal node S[h] can be moved into its
+	   neighbors, S[h] will be removed after balancing */
+	if (h && (tb->rnum[h] + tb->lnum[h] >= vn->vn_nr_item + 1)) {
+		int to_r;
+
+		/* Since we are working on internal nodes, and our internal
+		   nodes have fixed size entries, then we can balance by the
+		   number of items rather than the space they consume.  In this
+		   routine we set the left node equal to the right node,
+		   allowing a difference of less than or equal to 1 child
+		   pointer. */
+		to_r =
+		    ((MAX_NR_KEY(Sh) << 1) + 2 - tb->lnum[h] - tb->rnum[h] +
+		     vn->vn_nr_item + 1) / 2 - (MAX_NR_KEY(Sh) + 1 -
+						tb->rnum[h]);
+		set_parameters(tb, h, vn->vn_nr_item + 1 - to_r, to_r, 0, NULL,
+			       -1, -1);
+		return CARRY_ON;
+	}
+
+	/* this checks balance condition, that any two neighboring nodes can not fit in one node */
+	RFALSE(h &&
+	       (tb->lnum[h] >= vn->vn_nr_item + 1 ||
+		tb->rnum[h] >= vn->vn_nr_item + 1),
+	       "vs-8220: tree is not balanced on internal level");
+	RFALSE(!h && ((tb->lnum[h] >= vn->vn_nr_item && (tb->lbytes == -1)) ||
+		      (tb->rnum[h] >= vn->vn_nr_item && (tb->rbytes == -1))),
+	       "vs-8225: tree is not balanced on leaf level");
+
+	/* all contents of S[0] can be moved into its neighbors
+	   S[0] will be removed after balancing. */
+	if (!h && is_leaf_removable(tb))
+		return CARRY_ON;
+
+	/* why do we perform this check here rather than earlier??
+	   Answer: we can win 1 node in some cases above. Moreover we
+	   checked it above, when we checked, that S[0] is not removable
+	   in principle */
+	if (sfree >= levbytes) {	/* new item fits into node S[h] without any shifting */
+		if (!h)
+			tb->s0num = vn->vn_nr_item;
+		set_parameters(tb, h, 0, 0, 1, NULL, -1, -1);
+		return NO_BALANCING_NEEDED;
+	}
 
-	/* get_num_ver works in 2 modes (FLOW & NO_FLOW) 
-	   lpar, rpar - number of items we can shift to left/right neighbor (including splitting item)
-	   nset, lset, rset, lrset - shows, whether flowing items give better packing 
-	*/
+	{
+		int lpar, rpar, nset, lset, rset, lrset;
+		/* 
+		 * regular overflowing of the node
+		 */
+
+		/* get_num_ver works in 2 modes (FLOW & NO_FLOW) 
+		   lpar, rpar - number of items we can shift to left/right neighbor (including splitting item)
+		   nset, lset, rset, lrset - shows, whether flowing items give better packing 
+		 */
 #define FLOW 1
-#define NO_FLOW 0	/* do not any splitting */
+#define NO_FLOW 0		/* do not any splitting */
 
-	/* we choose one the following */
+		/* we choose one the following */
 #define NOTHING_SHIFT_NO_FLOW	0
 #define NOTHING_SHIFT_FLOW	5
 #define LEFT_SHIFT_NO_FLOW	10
@@ -1339,164 +1370,173 @@ static int ip_check_balance (struct tree
 #define LR_SHIFT_NO_FLOW	30
 #define LR_SHIFT_FLOW		35
 
+		lpar = tb->lnum[h];
+		rpar = tb->rnum[h];
 
-	lpar = tb->lnum[h];
-	rpar = tb->rnum[h];
-
-
-	/* calculate number of blocks S[h] must be split into when
-	   nothing is shifted to the neighbors,
-	   as well as number of items in each part of the split node (s012 numbers),
-	   and number of bytes (s1bytes) of the shared drop which flow to S1 if any */
-	nset = NOTHING_SHIFT_NO_FLOW;
-	nver = get_num_ver (vn->vn_mode, tb, h,
-			    0, -1, h?vn->vn_nr_item:0, -1, 
-			    snum012, NO_FLOW);
-
-	if (!h)
-	{
-	    int nver1;
-
-	    /* note, that in this case we try to bottle between S[0] and S1 (S1 - the first new node) */
-	    nver1 = get_num_ver (vn->vn_mode, tb, h, 
-				 0, -1, 0, -1, 
-				 snum012 + NOTHING_SHIFT_FLOW, FLOW);
-	    if (nver > nver1)
-		nset = NOTHING_SHIFT_FLOW, nver = nver1;
-	}
-       
- 
-	/* calculate number of blocks S[h] must be split into when
-	   l_shift_num first items and l_shift_bytes of the right most
-	   liquid item to be shifted are shifted to the left neighbor,
-	   as well as number of items in each part of the splitted node (s012 numbers),
-	   and number of bytes (s1bytes) of the shared drop which flow to S1 if any
-	*/
-	lset = LEFT_SHIFT_NO_FLOW;
-	lnver = get_num_ver (vn->vn_mode, tb, h, 
-			     lpar - (( h || tb->lbytes == -1 ) ? 0 : 1), -1, h ? vn->vn_nr_item:0, -1,
-			     snum012 + LEFT_SHIFT_NO_FLOW, NO_FLOW);
-	if (!h)
-	{
-	    int lnver1;
-
-	    lnver1 = get_num_ver (vn->vn_mode, tb, h, 
-				  lpar - ((tb->lbytes != -1) ? 1 : 0), tb->lbytes, 0, -1,
-				  snum012 + LEFT_SHIFT_FLOW, FLOW);
-	    if (lnver > lnver1)
-		lset = LEFT_SHIFT_FLOW, lnver = lnver1;
-	}
-
-
-	/* calculate number of blocks S[h] must be split into when
-	   r_shift_num first items and r_shift_bytes of the left most
-	   liquid item to be shifted are shifted to the right neighbor,
-	   as well as number of items in each part of the splitted node (s012 numbers),
-	   and number of bytes (s1bytes) of the shared drop which flow to S1 if any
-	*/
-	rset = RIGHT_SHIFT_NO_FLOW;
-	rnver = get_num_ver (vn->vn_mode, tb, h, 
-			     0, -1, h ? (vn->vn_nr_item-rpar) : (rpar - (( tb->rbytes != -1 ) ? 1 : 0)), -1, 
-			     snum012 + RIGHT_SHIFT_NO_FLOW, NO_FLOW);
-	if (!h)
-	{
-	    int rnver1;
-
-	    rnver1 = get_num_ver (vn->vn_mode, tb, h, 
-				  0, -1, (rpar - ((tb->rbytes != -1) ? 1 : 0)), tb->rbytes, 
-				  snum012 + RIGHT_SHIFT_FLOW, FLOW);
-
-	    if (rnver > rnver1)
-		rset = RIGHT_SHIFT_FLOW, rnver = rnver1;
-	}
-
-
-	/* calculate number of blocks S[h] must be split into when
-	   items are shifted in both directions,
-	   as well as number of items in each part of the splitted node (s012 numbers),
-	   and number of bytes (s1bytes) of the shared drop which flow to S1 if any
-	*/
-	lrset = LR_SHIFT_NO_FLOW;
-	lrnver = get_num_ver (vn->vn_mode, tb, h, 
-			      lpar - ((h || tb->lbytes == -1) ? 0 : 1), -1, h ? (vn->vn_nr_item-rpar):(rpar - ((tb->rbytes != -1) ? 1 : 0)), -1,
-			      snum012 + LR_SHIFT_NO_FLOW, NO_FLOW);
-	if (!h)
-	{
-	    int lrnver1;
-
-	    lrnver1 = get_num_ver (vn->vn_mode, tb, h, 
-				   lpar - ((tb->lbytes != -1) ? 1 : 0), tb->lbytes, (rpar - ((tb->rbytes != -1) ? 1 : 0)), tb->rbytes,
-				   snum012 + LR_SHIFT_FLOW, FLOW);
-	    if (lrnver > lrnver1)
-		lrset = LR_SHIFT_FLOW, lrnver = lrnver1;
-	}
+		/* calculate number of blocks S[h] must be split into when
+		   nothing is shifted to the neighbors,
+		   as well as number of items in each part of the split node (s012 numbers),
+		   and number of bytes (s1bytes) of the shared drop which flow to S1 if any */
+		nset = NOTHING_SHIFT_NO_FLOW;
+		nver = get_num_ver(vn->vn_mode, tb, h,
+				   0, -1, h ? vn->vn_nr_item : 0, -1,
+				   snum012, NO_FLOW);
+
+		if (!h) {
+			int nver1;
+
+			/* note, that in this case we try to bottle between S[0] and S1 (S1 - the first new node) */
+			nver1 = get_num_ver(vn->vn_mode, tb, h,
+					    0, -1, 0, -1,
+					    snum012 + NOTHING_SHIFT_FLOW, FLOW);
+			if (nver > nver1)
+				nset = NOTHING_SHIFT_FLOW, nver = nver1;
+		}
 
+		/* calculate number of blocks S[h] must be split into when
+		   l_shift_num first items and l_shift_bytes of the right most
+		   liquid item to be shifted are shifted to the left neighbor,
+		   as well as number of items in each part of the splitted node (s012 numbers),
+		   and number of bytes (s1bytes) of the shared drop which flow to S1 if any
+		 */
+		lset = LEFT_SHIFT_NO_FLOW;
+		lnver = get_num_ver(vn->vn_mode, tb, h,
+				    lpar - ((h || tb->lbytes == -1) ? 0 : 1),
+				    -1, h ? vn->vn_nr_item : 0, -1,
+				    snum012 + LEFT_SHIFT_NO_FLOW, NO_FLOW);
+		if (!h) {
+			int lnver1;
+
+			lnver1 = get_num_ver(vn->vn_mode, tb, h,
+					     lpar -
+					     ((tb->lbytes != -1) ? 1 : 0),
+					     tb->lbytes, 0, -1,
+					     snum012 + LEFT_SHIFT_FLOW, FLOW);
+			if (lnver > lnver1)
+				lset = LEFT_SHIFT_FLOW, lnver = lnver1;
+		}
 
+		/* calculate number of blocks S[h] must be split into when
+		   r_shift_num first items and r_shift_bytes of the left most
+		   liquid item to be shifted are shifted to the right neighbor,
+		   as well as number of items in each part of the splitted node (s012 numbers),
+		   and number of bytes (s1bytes) of the shared drop which flow to S1 if any
+		 */
+		rset = RIGHT_SHIFT_NO_FLOW;
+		rnver = get_num_ver(vn->vn_mode, tb, h,
+				    0, -1,
+				    h ? (vn->vn_nr_item - rpar) : (rpar -
+								   ((tb->
+								     rbytes !=
+								     -1) ? 1 :
+								    0)), -1,
+				    snum012 + RIGHT_SHIFT_NO_FLOW, NO_FLOW);
+		if (!h) {
+			int rnver1;
+
+			rnver1 = get_num_ver(vn->vn_mode, tb, h,
+					     0, -1,
+					     (rpar -
+					      ((tb->rbytes != -1) ? 1 : 0)),
+					     tb->rbytes,
+					     snum012 + RIGHT_SHIFT_FLOW, FLOW);
 
-	/* Our general shifting strategy is:
-	   1) to minimized number of new nodes;
-	   2) to minimized number of neighbors involved in shifting;
-	   3) to minimized number of disk reads; */
+			if (rnver > rnver1)
+				rset = RIGHT_SHIFT_FLOW, rnver = rnver1;
+		}
 
-	/* we can win TWO or ONE nodes by shifting in both directions */
-	if (lrnver < lnver && lrnver < rnver)
-	{
-	    RFALSE( h && 
-		    (tb->lnum[h] != 1 || 
-		     tb->rnum[h] != 1 || 
-		     lrnver != 1 || rnver != 2 || lnver != 2 || h != 1),
-		    "vs-8230: bad h");
-	    if (lrset == LR_SHIFT_FLOW)
-		set_parameters (tb, h, tb->lnum[h], tb->rnum[h], lrnver, snum012 + lrset,
-				tb->lbytes, tb->rbytes);
-	    else
-		set_parameters (tb, h, tb->lnum[h] - ((tb->lbytes == -1) ? 0 : 1), 
-				tb->rnum[h] - ((tb->rbytes == -1) ? 0 : 1), lrnver, snum012 + lrset, -1, -1);
+		/* calculate number of blocks S[h] must be split into when
+		   items are shifted in both directions,
+		   as well as number of items in each part of the splitted node (s012 numbers),
+		   and number of bytes (s1bytes) of the shared drop which flow to S1 if any
+		 */
+		lrset = LR_SHIFT_NO_FLOW;
+		lrnver = get_num_ver(vn->vn_mode, tb, h,
+				     lpar - ((h || tb->lbytes == -1) ? 0 : 1),
+				     -1,
+				     h ? (vn->vn_nr_item - rpar) : (rpar -
+								    ((tb->
+								      rbytes !=
+								      -1) ? 1 :
+								     0)), -1,
+				     snum012 + LR_SHIFT_NO_FLOW, NO_FLOW);
+		if (!h) {
+			int lrnver1;
+
+			lrnver1 = get_num_ver(vn->vn_mode, tb, h,
+					      lpar -
+					      ((tb->lbytes != -1) ? 1 : 0),
+					      tb->lbytes,
+					      (rpar -
+					       ((tb->rbytes != -1) ? 1 : 0)),
+					      tb->rbytes,
+					      snum012 + LR_SHIFT_FLOW, FLOW);
+			if (lrnver > lrnver1)
+				lrset = LR_SHIFT_FLOW, lrnver = lrnver1;
+		}
 
-	    return CARRY_ON;
-	}
+		/* Our general shifting strategy is:
+		   1) to minimized number of new nodes;
+		   2) to minimized number of neighbors involved in shifting;
+		   3) to minimized number of disk reads; */
+
+		/* we can win TWO or ONE nodes by shifting in both directions */
+		if (lrnver < lnver && lrnver < rnver) {
+			RFALSE(h &&
+			       (tb->lnum[h] != 1 ||
+				tb->rnum[h] != 1 ||
+				lrnver != 1 || rnver != 2 || lnver != 2
+				|| h != 1), "vs-8230: bad h");
+			if (lrset == LR_SHIFT_FLOW)
+				set_parameters(tb, h, tb->lnum[h], tb->rnum[h],
+					       lrnver, snum012 + lrset,
+					       tb->lbytes, tb->rbytes);
+			else
+				set_parameters(tb, h,
+					       tb->lnum[h] -
+					       ((tb->lbytes == -1) ? 0 : 1),
+					       tb->rnum[h] -
+					       ((tb->rbytes == -1) ? 0 : 1),
+					       lrnver, snum012 + lrset, -1, -1);
 
-	/* if shifting doesn't lead to better packing then don't shift */
-	if (nver == lrnver)
-	{
-	    set_parameters (tb, h, 0, 0, nver, snum012 + nset, -1, -1);
-	    return CARRY_ON;
-	}
+			return CARRY_ON;
+		}
 
+		/* if shifting doesn't lead to better packing then don't shift */
+		if (nver == lrnver) {
+			set_parameters(tb, h, 0, 0, nver, snum012 + nset, -1,
+				       -1);
+			return CARRY_ON;
+		}
 
-	/* now we know that for better packing shifting in only one
-	   direction either to the left or to the right is required */
+		/* now we know that for better packing shifting in only one
+		   direction either to the left or to the right is required */
 
-	/*  if shifting to the left is better than shifting to the right */
-	if (lnver < rnver)
-	{
-	    SET_PAR_SHIFT_LEFT;
-	    return CARRY_ON;
-	}
+		/*  if shifting to the left is better than shifting to the right */
+		if (lnver < rnver) {
+			SET_PAR_SHIFT_LEFT;
+			return CARRY_ON;
+		}
 
-	/* if shifting to the right is better than shifting to the left */
-	if (lnver > rnver)
-	{
-	    SET_PAR_SHIFT_RIGHT;
-	    return CARRY_ON;
-	}
+		/* if shifting to the right is better than shifting to the left */
+		if (lnver > rnver) {
+			SET_PAR_SHIFT_RIGHT;
+			return CARRY_ON;
+		}
 
+		/* now shifting in either direction gives the same number
+		   of nodes and we can make use of the cached neighbors */
+		if (is_left_neighbor_in_cache(tb, h)) {
+			SET_PAR_SHIFT_LEFT;
+			return CARRY_ON;
+		}
 
-	/* now shifting in either direction gives the same number
-	   of nodes and we can make use of the cached neighbors */
-	if (is_left_neighbor_in_cache (tb,h))
-	{
-	    SET_PAR_SHIFT_LEFT;
-	    return CARRY_ON;
+		/* shift to the right independently on whether the right neighbor in cache or not */
+		SET_PAR_SHIFT_RIGHT;
+		return CARRY_ON;
 	}
-
-	/* shift to the right independently on whether the right neighbor in cache or not */
-	SET_PAR_SHIFT_RIGHT;
-	return CARRY_ON;
-    }
 }
 
-
 /* Check whether current node S[h] is balanced when Decreasing its size by
  * Deleting or Cutting for INTERNAL node of S+tree.
  * Calculate parameters for balancing for current level h.
@@ -1513,157 +1553,173 @@ static int ip_check_balance (struct tree
  * Note: Items of internal nodes have fixed size, so the balance condition for
  * the internal part of S+tree is as for the B-trees.
  */
-static int dc_check_balance_internal (struct tree_balance * tb, int h)
+static int dc_check_balance_internal(struct tree_balance *tb, int h)
 {
-  struct virtual_node * vn = tb->tb_vn;
+	struct virtual_node *vn = tb->tb_vn;
 
-  /* Sh is the node whose balance is currently being checked,
-     and Fh is its father.  */
-  struct buffer_head * Sh, * Fh;
-  int maxsize,
-      n_ret_value;
-  int lfree, rfree /* free space in L and R */;
+	/* Sh is the node whose balance is currently being checked,
+	   and Fh is its father.  */
+	struct buffer_head *Sh, *Fh;
+	int maxsize, n_ret_value;
+	int lfree, rfree /* free space in L and R */ ;
 
-  Sh = PATH_H_PBUFFER (tb->tb_path, h); 
-  Fh = PATH_H_PPARENT (tb->tb_path, h); 
+	Sh = PATH_H_PBUFFER(tb->tb_path, h);
+	Fh = PATH_H_PPARENT(tb->tb_path, h);
 
-  maxsize = MAX_CHILD_SIZE(Sh); 
+	maxsize = MAX_CHILD_SIZE(Sh);
 
 /*   using tb->insert_size[h], which is negative in this case, create_virtual_node calculates: */
 /*   new_nr_item = number of items node would have if operation is */
 /* 	performed without balancing (new_nr_item); */
-  create_virtual_node (tb, h);
+	create_virtual_node(tb, h);
 
-  if ( ! Fh )
-    {   /* S[h] is the root. */
-      if ( vn->vn_nr_item > 0 )
-	{
-	  set_parameters (tb, h, 0, 0, 1, NULL, -1, -1);
-	  return NO_BALANCING_NEEDED; /* no balancing for higher levels needed */
-	}
-      /* new_nr_item == 0.
-       * Current root will be deleted resulting in
-       * decrementing the tree height. */
-      set_parameters (tb, h, 0, 0, 0, NULL, -1, -1);
-      return CARRY_ON;
-    }
-
-  if ( (n_ret_value = get_parents(tb,h)) != CARRY_ON )
-    return n_ret_value;
-
-
-  /* get free space of neighbors */
-  rfree = get_rfree (tb, h);
-  lfree = get_lfree (tb, h);
-		
-  /* determine maximal number of items we can fit into neighbors */
-  check_left (tb, h, lfree);
-  check_right (tb, h, rfree);
-
-
-  if ( vn->vn_nr_item >= MIN_NR_KEY(Sh) )
-    { /* Balance condition for the internal node is valid.
-       * In this case we balance only if it leads to better packing. */ 
-      if ( vn->vn_nr_item == MIN_NR_KEY(Sh) )
-	{ /* Here we join S[h] with one of its neighbors,
-	   * which is impossible with greater values of new_nr_item. */
-	  if ( tb->lnum[h] >= vn->vn_nr_item + 1 )
-	    {
-	      /* All contents of S[h] can be moved to L[h]. */
-	      int n;
-	      int order_L;
-	      
-	      order_L = ((n=PATH_H_B_ITEM_ORDER(tb->tb_path, h))==0) ? B_NR_ITEMS(tb->FL[h]) : n - 1;
-	      n = dc_size(B_N_CHILD(tb->FL[h],order_L)) / (DC_SIZE + KEY_SIZE);
-	      set_parameters (tb, h, -n-1, 0, 0, NULL, -1, -1);
-	      return CARRY_ON;
-	    }
-
-	  if ( tb->rnum[h] >= vn->vn_nr_item + 1 )
-	    {
-	      /* All contents of S[h] can be moved to R[h]. */
-	      int n;
-	      int order_R;
-	    
-	      order_R = ((n=PATH_H_B_ITEM_ORDER(tb->tb_path, h))==B_NR_ITEMS(Fh)) ? 0 : n + 1;
-	      n = dc_size(B_N_CHILD(tb->FR[h],order_R)) / (DC_SIZE + KEY_SIZE);
-	      set_parameters (tb, h, 0, -n-1, 0, NULL, -1, -1);
-	      return CARRY_ON;   
-	    }
-	}
+	if (!Fh) {		/* S[h] is the root. */
+		if (vn->vn_nr_item > 0) {
+			set_parameters(tb, h, 0, 0, 1, NULL, -1, -1);
+			return NO_BALANCING_NEEDED;	/* no balancing for higher levels needed */
+		}
+		/* new_nr_item == 0.
+		 * Current root will be deleted resulting in
+		 * decrementing the tree height. */
+		set_parameters(tb, h, 0, 0, 0, NULL, -1, -1);
+		return CARRY_ON;
+	}
+
+	if ((n_ret_value = get_parents(tb, h)) != CARRY_ON)
+		return n_ret_value;
+
+	/* get free space of neighbors */
+	rfree = get_rfree(tb, h);
+	lfree = get_lfree(tb, h);
+
+	/* determine maximal number of items we can fit into neighbors */
+	check_left(tb, h, lfree);
+	check_right(tb, h, rfree);
+
+	if (vn->vn_nr_item >= MIN_NR_KEY(Sh)) {	/* Balance condition for the internal node is valid.
+						 * In this case we balance only if it leads to better packing. */
+		if (vn->vn_nr_item == MIN_NR_KEY(Sh)) {	/* Here we join S[h] with one of its neighbors,
+							 * which is impossible with greater values of new_nr_item. */
+			if (tb->lnum[h] >= vn->vn_nr_item + 1) {
+				/* All contents of S[h] can be moved to L[h]. */
+				int n;
+				int order_L;
+
+				order_L =
+				    ((n =
+				      PATH_H_B_ITEM_ORDER(tb->tb_path,
+							  h)) ==
+				     0) ? B_NR_ITEMS(tb->FL[h]) : n - 1;
+				n = dc_size(B_N_CHILD(tb->FL[h], order_L)) /
+				    (DC_SIZE + KEY_SIZE);
+				set_parameters(tb, h, -n - 1, 0, 0, NULL, -1,
+					       -1);
+				return CARRY_ON;
+			}
+
+			if (tb->rnum[h] >= vn->vn_nr_item + 1) {
+				/* All contents of S[h] can be moved to R[h]. */
+				int n;
+				int order_R;
+
+				order_R =
+				    ((n =
+				      PATH_H_B_ITEM_ORDER(tb->tb_path,
+							  h)) ==
+				     B_NR_ITEMS(Fh)) ? 0 : n + 1;
+				n = dc_size(B_N_CHILD(tb->FR[h], order_R)) /
+				    (DC_SIZE + KEY_SIZE);
+				set_parameters(tb, h, 0, -n - 1, 0, NULL, -1,
+					       -1);
+				return CARRY_ON;
+			}
+		}
 
-      if (tb->rnum[h] + tb->lnum[h] >= vn->vn_nr_item + 1)
-	{
-	  /* All contents of S[h] can be moved to the neighbors (L[h] & R[h]). */
-	  int to_r;
+		if (tb->rnum[h] + tb->lnum[h] >= vn->vn_nr_item + 1) {
+			/* All contents of S[h] can be moved to the neighbors (L[h] & R[h]). */
+			int to_r;
+
+			to_r =
+			    ((MAX_NR_KEY(Sh) << 1) + 2 - tb->lnum[h] -
+			     tb->rnum[h] + vn->vn_nr_item + 1) / 2 -
+			    (MAX_NR_KEY(Sh) + 1 - tb->rnum[h]);
+			set_parameters(tb, h, vn->vn_nr_item + 1 - to_r, to_r,
+				       0, NULL, -1, -1);
+			return CARRY_ON;
+		}
 
-	  to_r = ((MAX_NR_KEY(Sh)<<1)+2-tb->lnum[h]-tb->rnum[h]+vn->vn_nr_item+1)/2 - 
-	    (MAX_NR_KEY(Sh) + 1 - tb->rnum[h]);
-	  set_parameters (tb, h, vn->vn_nr_item + 1 - to_r, to_r, 0, NULL, -1, -1);
-	  return CARRY_ON;
-	}
-
-      /* Balancing does not lead to better packing. */
-      set_parameters (tb, h, 0, 0, 1, NULL, -1, -1);
-      return NO_BALANCING_NEEDED;
-    }
-
-  /* Current node contain insufficient number of items. Balancing is required. */	
-  /* Check whether we can merge S[h] with left neighbor. */
-  if (tb->lnum[h] >= vn->vn_nr_item + 1)
-    if (is_left_neighbor_in_cache (tb,h) || tb->rnum[h] < vn->vn_nr_item + 1 || !tb->FR[h])
-      {
-	int n;
-	int order_L;
-	      
-	order_L = ((n=PATH_H_B_ITEM_ORDER(tb->tb_path, h))==0) ? B_NR_ITEMS(tb->FL[h]) : n - 1;
-	n = dc_size(B_N_CHILD(tb->FL[h],order_L)) / (DC_SIZE + KEY_SIZE);
-	set_parameters (tb, h, -n-1, 0, 0, NULL, -1, -1);
-	return CARRY_ON;
-      }
+		/* Balancing does not lead to better packing. */
+		set_parameters(tb, h, 0, 0, 1, NULL, -1, -1);
+		return NO_BALANCING_NEEDED;
+	}
+
+	/* Current node contain insufficient number of items. Balancing is required. */
+	/* Check whether we can merge S[h] with left neighbor. */
+	if (tb->lnum[h] >= vn->vn_nr_item + 1)
+		if (is_left_neighbor_in_cache(tb, h)
+		    || tb->rnum[h] < vn->vn_nr_item + 1 || !tb->FR[h]) {
+			int n;
+			int order_L;
+
+			order_L =
+			    ((n =
+			      PATH_H_B_ITEM_ORDER(tb->tb_path,
+						  h)) ==
+			     0) ? B_NR_ITEMS(tb->FL[h]) : n - 1;
+			n = dc_size(B_N_CHILD(tb->FL[h], order_L)) / (DC_SIZE +
+								      KEY_SIZE);
+			set_parameters(tb, h, -n - 1, 0, 0, NULL, -1, -1);
+			return CARRY_ON;
+		}
 
-  /* Check whether we can merge S[h] with right neighbor. */
-  if (tb->rnum[h] >= vn->vn_nr_item + 1)
-    {
-      int n;
-      int order_R;
-	    
-      order_R = ((n=PATH_H_B_ITEM_ORDER(tb->tb_path, h))==B_NR_ITEMS(Fh)) ? 0 : (n + 1);
-      n = dc_size(B_N_CHILD(tb->FR[h],order_R)) / (DC_SIZE + KEY_SIZE);
-      set_parameters (tb, h, 0, -n-1, 0, NULL, -1, -1);
-      return CARRY_ON;   
-    }
-
-  /* All contents of S[h] can be moved to the neighbors (L[h] & R[h]). */
-  if (tb->rnum[h] + tb->lnum[h] >= vn->vn_nr_item + 1)
-    {
-      int to_r;
-	    
-      to_r = ((MAX_NR_KEY(Sh)<<1)+2-tb->lnum[h]-tb->rnum[h]+vn->vn_nr_item+1)/2 - 
-	(MAX_NR_KEY(Sh) + 1 - tb->rnum[h]);
-      set_parameters (tb, h, vn->vn_nr_item + 1 - to_r, to_r, 0, NULL, -1, -1);
-      return CARRY_ON;
-    }
-
-  /* For internal nodes try to borrow item from a neighbor */
-  RFALSE( !tb->FL[h] && !tb->FR[h], "vs-8235: trying to borrow for root");
-
-  /* Borrow one or two items from caching neighbor */
-  if (is_left_neighbor_in_cache (tb,h) || !tb->FR[h])
-    {
-      int from_l;
-		
-      from_l = (MAX_NR_KEY(Sh) + 1 - tb->lnum[h] + vn->vn_nr_item + 1) / 2 -  (vn->vn_nr_item + 1);
-      set_parameters (tb, h, -from_l, 0, 1, NULL, -1, -1);
-      return CARRY_ON;
-    }
-
-  set_parameters (tb, h, 0, -((MAX_NR_KEY(Sh)+1-tb->rnum[h]+vn->vn_nr_item+1)/2-(vn->vn_nr_item+1)), 1, 
-		  NULL, -1, -1);
-  return CARRY_ON;
+	/* Check whether we can merge S[h] with right neighbor. */
+	if (tb->rnum[h] >= vn->vn_nr_item + 1) {
+		int n;
+		int order_R;
+
+		order_R =
+		    ((n =
+		      PATH_H_B_ITEM_ORDER(tb->tb_path,
+					  h)) == B_NR_ITEMS(Fh)) ? 0 : (n + 1);
+		n = dc_size(B_N_CHILD(tb->FR[h], order_R)) / (DC_SIZE +
+							      KEY_SIZE);
+		set_parameters(tb, h, 0, -n - 1, 0, NULL, -1, -1);
+		return CARRY_ON;
+	}
+
+	/* All contents of S[h] can be moved to the neighbors (L[h] & R[h]). */
+	if (tb->rnum[h] + tb->lnum[h] >= vn->vn_nr_item + 1) {
+		int to_r;
+
+		to_r =
+		    ((MAX_NR_KEY(Sh) << 1) + 2 - tb->lnum[h] - tb->rnum[h] +
+		     vn->vn_nr_item + 1) / 2 - (MAX_NR_KEY(Sh) + 1 -
+						tb->rnum[h]);
+		set_parameters(tb, h, vn->vn_nr_item + 1 - to_r, to_r, 0, NULL,
+			       -1, -1);
+		return CARRY_ON;
+	}
+
+	/* For internal nodes try to borrow item from a neighbor */
+	RFALSE(!tb->FL[h] && !tb->FR[h], "vs-8235: trying to borrow for root");
+
+	/* Borrow one or two items from caching neighbor */
+	if (is_left_neighbor_in_cache(tb, h) || !tb->FR[h]) {
+		int from_l;
+
+		from_l =
+		    (MAX_NR_KEY(Sh) + 1 - tb->lnum[h] + vn->vn_nr_item +
+		     1) / 2 - (vn->vn_nr_item + 1);
+		set_parameters(tb, h, -from_l, 0, 1, NULL, -1, -1);
+		return CARRY_ON;
+	}
+
+	set_parameters(tb, h, 0,
+		       -((MAX_NR_KEY(Sh) + 1 - tb->rnum[h] + vn->vn_nr_item +
+			  1) / 2 - (vn->vn_nr_item + 1)), 1, NULL, -1, -1);
+	return CARRY_ON;
 }
 
-
 /* Check whether current node S[h] is balanced when Decreasing its size by
  * Deleting or Truncating for LEAF node of S+tree.
  * Calculate parameters for balancing for current level h.
@@ -1677,90 +1733,86 @@ static int dc_check_balance_internal (st
  *	       -1 - no balancing for higher levels needed;
  *	       -2 - no disk space.
  */
-static int dc_check_balance_leaf (struct tree_balance * tb, int h)
+static int dc_check_balance_leaf(struct tree_balance *tb, int h)
 {
-  struct virtual_node * vn = tb->tb_vn;
+	struct virtual_node *vn = tb->tb_vn;
 
-  /* Number of bytes that must be deleted from
-     (value is negative if bytes are deleted) buffer which
-     contains node being balanced.  The mnemonic is that the
-     attempted change in node space used level is levbytes bytes. */
-  int levbytes;
-  /* the maximal item size */
-  int maxsize,
-      n_ret_value;
-  /* S0 is the node whose balance is currently being checked,
-     and F0 is its father.  */
-  struct buffer_head * S0, * F0;
-  int lfree, rfree /* free space in L and R */;
-
-  S0 = PATH_H_PBUFFER (tb->tb_path, 0);
-  F0 = PATH_H_PPARENT (tb->tb_path, 0);
-
-  levbytes = tb->insert_size[h];
-
-  maxsize = MAX_CHILD_SIZE(S0); 	/* maximal possible size of an item */
-
-  if ( ! F0 )
-    {  /* S[0] is the root now. */
-
-      RFALSE( -levbytes >= maxsize - B_FREE_SPACE (S0),
-	      "vs-8240: attempt to create empty buffer tree");
-
-      set_parameters (tb, h, 0, 0, 1, NULL, -1, -1);
-      return NO_BALANCING_NEEDED;
-    }
-
-  if ( (n_ret_value = get_parents(tb,h)) != CARRY_ON )
-    return n_ret_value;
-
-  /* get free space of neighbors */
-  rfree = get_rfree (tb, h);
-  lfree = get_lfree (tb, h);		
-
-  create_virtual_node (tb, h);
-
-  /* if 3 leaves can be merge to one, set parameters and return */
-  if (are_leaves_removable (tb, lfree, rfree))
-    return CARRY_ON;
-
-  /* determine maximal number of items we can shift to the left/right  neighbor
-     and the maximal number of bytes that can flow to the left/right neighbor
-     from the left/right most liquid item that cannot be shifted from S[0] entirely
-     */
-  check_left (tb, h, lfree);
-  check_right (tb, h, rfree);   
-
-  /* check whether we can merge S with left neighbor. */
-  if (tb->lnum[0] >= vn->vn_nr_item && tb->lbytes == -1)
-    if (is_left_neighbor_in_cache (tb,h) ||
-	((tb->rnum[0] - ((tb->rbytes == -1) ? 0 : 1)) < vn->vn_nr_item) || /* S can not be merged with R */
-	!tb->FR[h]) {
-      
-      RFALSE( !tb->FL[h], "vs-8245: dc_check_balance_leaf: FL[h] must exist");
-
-      /* set parameter to merge S[0] with its left neighbor */
-      set_parameters (tb, h, -1, 0, 0, NULL, -1, -1);
-      return CARRY_ON;
-    }
-
-  /* check whether we can merge S[0] with right neighbor. */
-  if (tb->rnum[0] >= vn->vn_nr_item && tb->rbytes == -1) {
-    set_parameters (tb, h, 0, -1, 0, NULL, -1, -1);
-    return CARRY_ON;
-  }
-  
-  /* All contents of S[0] can be moved to the neighbors (L[0] & R[0]). Set parameters and return */
-  if (is_leaf_removable (tb))
-    return CARRY_ON;
-  
-  /* Balancing is not required. */
-  tb->s0num = vn->vn_nr_item;
-  set_parameters (tb, h, 0, 0, 1, NULL, -1, -1);
-  return NO_BALANCING_NEEDED;
-}
+	/* Number of bytes that must be deleted from
+	   (value is negative if bytes are deleted) buffer which
+	   contains node being balanced.  The mnemonic is that the
+	   attempted change in node space used level is levbytes bytes. */
+	int levbytes;
+	/* the maximal item size */
+	int maxsize, n_ret_value;
+	/* S0 is the node whose balance is currently being checked,
+	   and F0 is its father.  */
+	struct buffer_head *S0, *F0;
+	int lfree, rfree /* free space in L and R */ ;
+
+	S0 = PATH_H_PBUFFER(tb->tb_path, 0);
+	F0 = PATH_H_PPARENT(tb->tb_path, 0);
+
+	levbytes = tb->insert_size[h];
 
+	maxsize = MAX_CHILD_SIZE(S0);	/* maximal possible size of an item */
 
+	if (!F0) {		/* S[0] is the root now. */
+
+		RFALSE(-levbytes >= maxsize - B_FREE_SPACE(S0),
+		       "vs-8240: attempt to create empty buffer tree");
+
+		set_parameters(tb, h, 0, 0, 1, NULL, -1, -1);
+		return NO_BALANCING_NEEDED;
+	}
+
+	if ((n_ret_value = get_parents(tb, h)) != CARRY_ON)
+		return n_ret_value;
+
+	/* get free space of neighbors */
+	rfree = get_rfree(tb, h);
+	lfree = get_lfree(tb, h);
+
+	create_virtual_node(tb, h);
+
+	/* if 3 leaves can be merge to one, set parameters and return */
+	if (are_leaves_removable(tb, lfree, rfree))
+		return CARRY_ON;
+
+	/* determine maximal number of items we can shift to the left/right  neighbor
+	   and the maximal number of bytes that can flow to the left/right neighbor
+	   from the left/right most liquid item that cannot be shifted from S[0] entirely
+	 */
+	check_left(tb, h, lfree);
+	check_right(tb, h, rfree);
+
+	/* check whether we can merge S with left neighbor. */
+	if (tb->lnum[0] >= vn->vn_nr_item && tb->lbytes == -1)
+		if (is_left_neighbor_in_cache(tb, h) || ((tb->rnum[0] - ((tb->rbytes == -1) ? 0 : 1)) < vn->vn_nr_item) ||	/* S can not be merged with R */
+		    !tb->FR[h]) {
+
+			RFALSE(!tb->FL[h],
+			       "vs-8245: dc_check_balance_leaf: FL[h] must exist");
+
+			/* set parameter to merge S[0] with its left neighbor */
+			set_parameters(tb, h, -1, 0, 0, NULL, -1, -1);
+			return CARRY_ON;
+		}
+
+	/* check whether we can merge S[0] with right neighbor. */
+	if (tb->rnum[0] >= vn->vn_nr_item && tb->rbytes == -1) {
+		set_parameters(tb, h, 0, -1, 0, NULL, -1, -1);
+		return CARRY_ON;
+	}
+
+	/* All contents of S[0] can be moved to the neighbors (L[0] & R[0]). Set parameters and return */
+	if (is_leaf_removable(tb))
+		return CARRY_ON;
+
+	/* Balancing is not required. */
+	tb->s0num = vn->vn_nr_item;
+	set_parameters(tb, h, 0, 0, 1, NULL, -1, -1);
+	return NO_BALANCING_NEEDED;
+}
 
 /* Check whether current node S[h] is balanced when Decreasing its size by
  * Deleting or Cutting.
@@ -1775,18 +1827,17 @@ static int dc_check_balance_leaf (struct
  *	       -1 - no balancing for higher levels needed;
  *	       -2 - no disk space.
  */
-static int dc_check_balance (struct tree_balance * tb, int h)
+static int dc_check_balance(struct tree_balance *tb, int h)
 {
- RFALSE( ! (PATH_H_PBUFFER (tb->tb_path, h)), "vs-8250: S is not initialized");
+	RFALSE(!(PATH_H_PBUFFER(tb->tb_path, h)),
+	       "vs-8250: S is not initialized");
 
- if ( h )
-   return dc_check_balance_internal (tb, h);
- else
-   return dc_check_balance_leaf (tb, h);
+	if (h)
+		return dc_check_balance_internal(tb, h);
+	else
+		return dc_check_balance_leaf(tb, h);
 }
 
-
-
 /* Check whether current node S[h] is balanced.
  * Calculate parameters for balancing for current level h.
  * Parameters:
@@ -1805,83 +1856,80 @@ static int dc_check_balance (struct tree
  *	       -1 - no balancing for higher levels needed;
  *	       -2 - no disk space.
  */
-static int check_balance (int mode, 
-			  struct tree_balance * tb,
-			  int h, 
-			  int inum,
-			  int pos_in_item,
-			  struct item_head * ins_ih,
-			  const void * data
-			  )
-{
-  struct virtual_node * vn;
-
-  vn = tb->tb_vn = (struct virtual_node *)(tb->vn_buf);
-  vn->vn_free_ptr = (char *)(tb->tb_vn + 1);
-  vn->vn_mode = mode;
-  vn->vn_affected_item_num = inum;
-  vn->vn_pos_in_item = pos_in_item;
-  vn->vn_ins_ih = ins_ih;
-  vn->vn_data = data;
-
-  RFALSE( mode == M_INSERT && !vn->vn_ins_ih,
-	  "vs-8255: ins_ih can not be 0 in insert mode");
-
- if ( tb->insert_size[h] > 0 )
-   /* Calculate balance parameters when size of node is increasing. */
-   return ip_check_balance (tb, h);
+static int check_balance(int mode,
+			 struct tree_balance *tb,
+			 int h,
+			 int inum,
+			 int pos_in_item,
+			 struct item_head *ins_ih, const void *data)
+{
+	struct virtual_node *vn;
+
+	vn = tb->tb_vn = (struct virtual_node *)(tb->vn_buf);
+	vn->vn_free_ptr = (char *)(tb->tb_vn + 1);
+	vn->vn_mode = mode;
+	vn->vn_affected_item_num = inum;
+	vn->vn_pos_in_item = pos_in_item;
+	vn->vn_ins_ih = ins_ih;
+	vn->vn_data = data;
+
+	RFALSE(mode == M_INSERT && !vn->vn_ins_ih,
+	       "vs-8255: ins_ih can not be 0 in insert mode");
+
+	if (tb->insert_size[h] > 0)
+		/* Calculate balance parameters when size of node is increasing. */
+		return ip_check_balance(tb, h);
 
- /* Calculate balance parameters when  size of node is decreasing. */
- return dc_check_balance (tb, h);
+	/* Calculate balance parameters when  size of node is decreasing. */
+	return dc_check_balance(tb, h);
 }
 
+/* Check whether parent at the path is the really parent of the current node.*/
+static int get_direct_parent(struct tree_balance *p_s_tb, int n_h)
+{
+	struct buffer_head *p_s_bh;
+	struct path *p_s_path = p_s_tb->tb_path;
+	int n_position,
+	    n_path_offset = PATH_H_PATH_OFFSET(p_s_tb->tb_path, n_h);
+
+	/* We are in the root or in the new root. */
+	if (n_path_offset <= FIRST_PATH_ELEMENT_OFFSET) {
+
+		RFALSE(n_path_offset < FIRST_PATH_ELEMENT_OFFSET - 1,
+		       "PAP-8260: invalid offset in the path");
+
+		if (PATH_OFFSET_PBUFFER(p_s_path, FIRST_PATH_ELEMENT_OFFSET)->
+		    b_blocknr == SB_ROOT_BLOCK(p_s_tb->tb_sb)) {
+			/* Root is not changed. */
+			PATH_OFFSET_PBUFFER(p_s_path, n_path_offset - 1) = NULL;
+			PATH_OFFSET_POSITION(p_s_path, n_path_offset - 1) = 0;
+			return CARRY_ON;
+		}
+		return REPEAT_SEARCH;	/* Root is changed and we must recalculate the path. */
+	}
+
+	if (!B_IS_IN_TREE
+	    (p_s_bh = PATH_OFFSET_PBUFFER(p_s_path, n_path_offset - 1)))
+		return REPEAT_SEARCH;	/* Parent in the path is not in the tree. */
 
+	if ((n_position =
+	     PATH_OFFSET_POSITION(p_s_path,
+				  n_path_offset - 1)) > B_NR_ITEMS(p_s_bh))
+		return REPEAT_SEARCH;
 
-/* Check whether parent at the path is the really parent of the current node.*/
-static int  get_direct_parent(
-              struct tree_balance * p_s_tb,
-              int                   n_h
-            ) {
-    struct buffer_head  * p_s_bh;
-    struct path         * p_s_path      = p_s_tb->tb_path;
-    int                   n_position,
-	n_path_offset = PATH_H_PATH_OFFSET(p_s_tb->tb_path, n_h);
-    
-    /* We are in the root or in the new root. */
-    if ( n_path_offset <= FIRST_PATH_ELEMENT_OFFSET ) {
-	
-	RFALSE( n_path_offset < FIRST_PATH_ELEMENT_OFFSET - 1,
-		"PAP-8260: invalid offset in the path");
-
-	if ( PATH_OFFSET_PBUFFER(p_s_path, FIRST_PATH_ELEMENT_OFFSET)->b_blocknr ==
-	     SB_ROOT_BLOCK (p_s_tb->tb_sb) ) {
-	    /* Root is not changed. */
-	    PATH_OFFSET_PBUFFER(p_s_path, n_path_offset - 1) = NULL;
-	    PATH_OFFSET_POSITION(p_s_path, n_path_offset - 1) = 0;
-	    return CARRY_ON;
-	}
-	return REPEAT_SEARCH; /* Root is changed and we must recalculate the path. */
-    }
-
-    if ( ! B_IS_IN_TREE(p_s_bh = PATH_OFFSET_PBUFFER(p_s_path, n_path_offset - 1)) )
-	return REPEAT_SEARCH; /* Parent in the path is not in the tree. */
-
-    if ( (n_position = PATH_OFFSET_POSITION(p_s_path, n_path_offset - 1)) > B_NR_ITEMS(p_s_bh) )
-	return REPEAT_SEARCH;
-    
-    if ( B_N_CHILD_NUM(p_s_bh, n_position) != PATH_OFFSET_PBUFFER(p_s_path, n_path_offset)->b_blocknr )
-	/* Parent in the path is not parent of the current node in the tree. */
-	return REPEAT_SEARCH;
-
-    if ( buffer_locked(p_s_bh) ) {
-	__wait_on_buffer(p_s_bh);
-	if ( FILESYSTEM_CHANGED_TB (p_s_tb) )
-	    return REPEAT_SEARCH;
-    }
+	if (B_N_CHILD_NUM(p_s_bh, n_position) !=
+	    PATH_OFFSET_PBUFFER(p_s_path, n_path_offset)->b_blocknr)
+		/* Parent in the path is not parent of the current node in the tree. */
+		return REPEAT_SEARCH;
 
-    return CARRY_ON; /* Parent in the path is unlocked and really parent of the current node.  */
-}
+	if (buffer_locked(p_s_bh)) {
+		__wait_on_buffer(p_s_bh);
+		if (FILESYSTEM_CHANGED_TB(p_s_tb))
+			return REPEAT_SEARCH;
+	}
 
+	return CARRY_ON;	/* Parent in the path is unlocked and really parent of the current node.  */
+}
 
 /* Using lnum[n_h] and rnum[n_h] we should determine what neighbors
  * of S[n_h] we
@@ -1889,356 +1937,401 @@ static int  get_direct_parent(
  * Returns:	SCHEDULE_OCCURRED - schedule occurred while the function worked;
  *	        CARRY_ON - schedule didn't occur while the function worked;
  */
-static int  get_neighbors(
-	            struct tree_balance * p_s_tb,
-	            int 		  n_h
-	          ) {
-    int		 	n_child_position,
-	n_path_offset = PATH_H_PATH_OFFSET(p_s_tb->tb_path, n_h + 1);
-    unsigned long		n_son_number;
-    struct super_block  *	p_s_sb = p_s_tb->tb_sb;
-    struct buffer_head  * p_s_bh;
-
-
-    PROC_INFO_INC( p_s_sb, get_neighbors[ n_h ] );
-
-    if ( p_s_tb->lnum[n_h] ) {
-	/* We need left neighbor to balance S[n_h]. */
-	PROC_INFO_INC( p_s_sb, need_l_neighbor[ n_h ] );
-	p_s_bh = PATH_OFFSET_PBUFFER(p_s_tb->tb_path, n_path_offset);
-	
-	RFALSE( p_s_bh == p_s_tb->FL[n_h] && 
-		! PATH_OFFSET_POSITION(p_s_tb->tb_path, n_path_offset),
-		"PAP-8270: invalid position in the parent");
-
-	n_child_position = ( p_s_bh == p_s_tb->FL[n_h] ) ? p_s_tb->lkey[n_h] : B_NR_ITEMS (p_s_tb->FL[n_h]);
-	n_son_number = B_N_CHILD_NUM(p_s_tb->FL[n_h], n_child_position);
-	p_s_bh = sb_bread(p_s_sb, n_son_number);
-	if (!p_s_bh)
-	    return IO_ERROR;
-	if ( FILESYSTEM_CHANGED_TB (p_s_tb) ) {
-	    decrement_bcount(p_s_bh);
-	    PROC_INFO_INC( p_s_sb, get_neighbors_restart[ n_h ] );
-	    return REPEAT_SEARCH;
-	}
-	
-	RFALSE( ! B_IS_IN_TREE(p_s_tb->FL[n_h]) ||
-                n_child_position > B_NR_ITEMS(p_s_tb->FL[n_h]) ||
-	        B_N_CHILD_NUM(p_s_tb->FL[n_h], n_child_position) !=
-                p_s_bh->b_blocknr, "PAP-8275: invalid parent");
-	RFALSE( ! B_IS_IN_TREE(p_s_bh), "PAP-8280: invalid child");
-	RFALSE( ! n_h &&
-                B_FREE_SPACE (p_s_bh) != MAX_CHILD_SIZE (p_s_bh) - dc_size(B_N_CHILD (p_s_tb->FL[0],n_child_position)),
-                "PAP-8290: invalid child size of left neighbor");
-
-	decrement_bcount(p_s_tb->L[n_h]);
-	p_s_tb->L[n_h] = p_s_bh;
-    }
-
-
-    if ( p_s_tb->rnum[n_h] ) { /* We need right neighbor to balance S[n_path_offset]. */
-	PROC_INFO_INC( p_s_sb, need_r_neighbor[ n_h ] );
-	p_s_bh = PATH_OFFSET_PBUFFER(p_s_tb->tb_path, n_path_offset);
-	
-	RFALSE( p_s_bh == p_s_tb->FR[n_h] && 
-		PATH_OFFSET_POSITION(p_s_tb->tb_path, n_path_offset) >= B_NR_ITEMS(p_s_bh),
-		"PAP-8295: invalid position in the parent");
-
-	n_child_position = ( p_s_bh == p_s_tb->FR[n_h] ) ? p_s_tb->rkey[n_h] + 1 : 0;
-	n_son_number = B_N_CHILD_NUM(p_s_tb->FR[n_h], n_child_position);
-	p_s_bh = sb_bread(p_s_sb, n_son_number);
-	if (!p_s_bh)
-	    return IO_ERROR;
-	if ( FILESYSTEM_CHANGED_TB (p_s_tb) ) {
-	    decrement_bcount(p_s_bh);
-	    PROC_INFO_INC( p_s_sb, get_neighbors_restart[ n_h ] );
-	    return REPEAT_SEARCH;
-	}
-	decrement_bcount(p_s_tb->R[n_h]);
-	p_s_tb->R[n_h] = p_s_bh;
-
-	RFALSE( ! n_h && B_FREE_SPACE (p_s_bh) != MAX_CHILD_SIZE (p_s_bh) - dc_size(B_N_CHILD (p_s_tb->FR[0],n_child_position)),
-                "PAP-8300: invalid child size of right neighbor (%d != %d - %d)",
-                B_FREE_SPACE (p_s_bh), MAX_CHILD_SIZE (p_s_bh),
-                dc_size(B_N_CHILD (p_s_tb->FR[0],n_child_position)));
-	
-    }
-    return CARRY_ON;
+static int get_neighbors(struct tree_balance *p_s_tb, int n_h)
+{
+	int n_child_position,
+	    n_path_offset = PATH_H_PATH_OFFSET(p_s_tb->tb_path, n_h + 1);
+	unsigned long n_son_number;
+	struct super_block *p_s_sb = p_s_tb->tb_sb;
+	struct buffer_head *p_s_bh;
+
+	PROC_INFO_INC(p_s_sb, get_neighbors[n_h]);
+
+	if (p_s_tb->lnum[n_h]) {
+		/* We need left neighbor to balance S[n_h]. */
+		PROC_INFO_INC(p_s_sb, need_l_neighbor[n_h]);
+		p_s_bh = PATH_OFFSET_PBUFFER(p_s_tb->tb_path, n_path_offset);
+
+		RFALSE(p_s_bh == p_s_tb->FL[n_h] &&
+		       !PATH_OFFSET_POSITION(p_s_tb->tb_path, n_path_offset),
+		       "PAP-8270: invalid position in the parent");
+
+		n_child_position =
+		    (p_s_bh ==
+		     p_s_tb->FL[n_h]) ? p_s_tb->lkey[n_h] : B_NR_ITEMS(p_s_tb->
+								       FL[n_h]);
+		n_son_number = B_N_CHILD_NUM(p_s_tb->FL[n_h], n_child_position);
+		p_s_bh = sb_bread(p_s_sb, n_son_number);
+		if (!p_s_bh)
+			return IO_ERROR;
+		if (FILESYSTEM_CHANGED_TB(p_s_tb)) {
+			decrement_bcount(p_s_bh);
+			PROC_INFO_INC(p_s_sb, get_neighbors_restart[n_h]);
+			return REPEAT_SEARCH;
+		}
+
+		RFALSE(!B_IS_IN_TREE(p_s_tb->FL[n_h]) ||
+		       n_child_position > B_NR_ITEMS(p_s_tb->FL[n_h]) ||
+		       B_N_CHILD_NUM(p_s_tb->FL[n_h], n_child_position) !=
+		       p_s_bh->b_blocknr, "PAP-8275: invalid parent");
+		RFALSE(!B_IS_IN_TREE(p_s_bh), "PAP-8280: invalid child");
+		RFALSE(!n_h &&
+		       B_FREE_SPACE(p_s_bh) !=
+		       MAX_CHILD_SIZE(p_s_bh) -
+		       dc_size(B_N_CHILD(p_s_tb->FL[0], n_child_position)),
+		       "PAP-8290: invalid child size of left neighbor");
+
+		decrement_bcount(p_s_tb->L[n_h]);
+		p_s_tb->L[n_h] = p_s_bh;
+	}
+
+	if (p_s_tb->rnum[n_h]) {	/* We need right neighbor to balance S[n_path_offset]. */
+		PROC_INFO_INC(p_s_sb, need_r_neighbor[n_h]);
+		p_s_bh = PATH_OFFSET_PBUFFER(p_s_tb->tb_path, n_path_offset);
+
+		RFALSE(p_s_bh == p_s_tb->FR[n_h] &&
+		       PATH_OFFSET_POSITION(p_s_tb->tb_path,
+					    n_path_offset) >=
+		       B_NR_ITEMS(p_s_bh),
+		       "PAP-8295: invalid position in the parent");
+
+		n_child_position =
+		    (p_s_bh == p_s_tb->FR[n_h]) ? p_s_tb->rkey[n_h] + 1 : 0;
+		n_son_number = B_N_CHILD_NUM(p_s_tb->FR[n_h], n_child_position);
+		p_s_bh = sb_bread(p_s_sb, n_son_number);
+		if (!p_s_bh)
+			return IO_ERROR;
+		if (FILESYSTEM_CHANGED_TB(p_s_tb)) {
+			decrement_bcount(p_s_bh);
+			PROC_INFO_INC(p_s_sb, get_neighbors_restart[n_h]);
+			return REPEAT_SEARCH;
+		}
+		decrement_bcount(p_s_tb->R[n_h]);
+		p_s_tb->R[n_h] = p_s_bh;
+
+		RFALSE(!n_h
+		       && B_FREE_SPACE(p_s_bh) !=
+		       MAX_CHILD_SIZE(p_s_bh) -
+		       dc_size(B_N_CHILD(p_s_tb->FR[0], n_child_position)),
+		       "PAP-8300: invalid child size of right neighbor (%d != %d - %d)",
+		       B_FREE_SPACE(p_s_bh), MAX_CHILD_SIZE(p_s_bh),
+		       dc_size(B_N_CHILD(p_s_tb->FR[0], n_child_position)));
+
+	}
+	return CARRY_ON;
 }
 
 #ifdef CONFIG_REISERFS_CHECK
-void * reiserfs_kmalloc (size_t size, int flags, struct super_block * s)
+void *reiserfs_kmalloc(size_t size, int flags, struct super_block *s)
 {
-    void * vp;
-    static size_t malloced;
+	void *vp;
+	static size_t malloced;
 
-
-    vp = kmalloc (size, flags);
-    if (vp) {
-	REISERFS_SB(s)->s_kmallocs += size;
-	if (REISERFS_SB(s)->s_kmallocs > malloced + 200000) {
-	    reiserfs_warning (s,
-			      "vs-8301: reiserfs_kmalloc: allocated memory %d",
-			      REISERFS_SB(s)->s_kmallocs);
-	    malloced = REISERFS_SB(s)->s_kmallocs;
+	vp = kmalloc(size, flags);
+	if (vp) {
+		REISERFS_SB(s)->s_kmallocs += size;
+		if (REISERFS_SB(s)->s_kmallocs > malloced + 200000) {
+			reiserfs_warning(s,
+					 "vs-8301: reiserfs_kmalloc: allocated memory %d",
+					 REISERFS_SB(s)->s_kmallocs);
+			malloced = REISERFS_SB(s)->s_kmallocs;
+		}
 	}
-    }
-    return vp;
+	return vp;
 }
 
-void reiserfs_kfree (const void * vp, size_t size, struct super_block * s)
+void reiserfs_kfree(const void *vp, size_t size, struct super_block *s)
 {
-    kfree (vp);
-  
-    REISERFS_SB(s)->s_kmallocs -= size;
-    if (REISERFS_SB(s)->s_kmallocs < 0)
-	reiserfs_warning (s, "vs-8302: reiserfs_kfree: allocated memory %d",
-			  REISERFS_SB(s)->s_kmallocs);
+	kfree(vp);
+
+	REISERFS_SB(s)->s_kmallocs -= size;
+	if (REISERFS_SB(s)->s_kmallocs < 0)
+		reiserfs_warning(s,
+				 "vs-8302: reiserfs_kfree: allocated memory %d",
+				 REISERFS_SB(s)->s_kmallocs);
 
 }
 #endif
 
-
-static int get_virtual_node_size (struct super_block * sb, struct buffer_head * bh)
+static int get_virtual_node_size(struct super_block *sb, struct buffer_head *bh)
 {
-    int max_num_of_items;
-    int max_num_of_entries;
-    unsigned long blocksize = sb->s_blocksize;
+	int max_num_of_items;
+	int max_num_of_entries;
+	unsigned long blocksize = sb->s_blocksize;
 
 #define MIN_NAME_LEN 1
 
-    max_num_of_items = (blocksize - BLKH_SIZE) / (IH_SIZE + MIN_ITEM_LEN);
-    max_num_of_entries = (blocksize - BLKH_SIZE - IH_SIZE) / 
-                         (DEH_SIZE + MIN_NAME_LEN);
-
-    return sizeof(struct virtual_node) + 
-           max(max_num_of_items * sizeof (struct virtual_item),
-	       sizeof (struct virtual_item) + sizeof(struct direntry_uarea) + 
-               (max_num_of_entries - 1) * sizeof (__u16));
+	max_num_of_items = (blocksize - BLKH_SIZE) / (IH_SIZE + MIN_ITEM_LEN);
+	max_num_of_entries = (blocksize - BLKH_SIZE - IH_SIZE) /
+	    (DEH_SIZE + MIN_NAME_LEN);
+
+	return sizeof(struct virtual_node) +
+	    max(max_num_of_items * sizeof(struct virtual_item),
+		sizeof(struct virtual_item) + sizeof(struct direntry_uarea) +
+		(max_num_of_entries - 1) * sizeof(__u16));
 }
 
-
-
 /* maybe we should fail balancing we are going to perform when kmalloc
    fails several times. But now it will loop until kmalloc gets
    required memory */
-static int get_mem_for_virtual_node (struct tree_balance * tb)
+static int get_mem_for_virtual_node(struct tree_balance *tb)
 {
-    int check_fs = 0;
-    int size;
-    char * buf;
-
-    size = get_virtual_node_size (tb->tb_sb, PATH_PLAST_BUFFER (tb->tb_path));
-
-    if (size > tb->vn_buf_size) {
-	/* we have to allocate more memory for virtual node */
-	if (tb->vn_buf) {
-	    /* free memory allocated before */
-	    reiserfs_kfree (tb->vn_buf, tb->vn_buf_size, tb->tb_sb);
-	    /* this is not needed if kfree is atomic */
-            check_fs = 1;
-	}
-
-	/* virtual node requires now more memory */
-	tb->vn_buf_size = size;
-
-	/* get memory for virtual item */
-	buf = reiserfs_kmalloc(size, GFP_ATOMIC | __GFP_NOWARN, tb->tb_sb);
-	if ( ! buf ) {
-	    /* getting memory with GFP_KERNEL priority may involve
-               balancing now (due to indirect_to_direct conversion on
-               dcache shrinking). So, release path and collected
-               resources here */
-	    free_buffers_in_tb (tb);
-	    buf = reiserfs_kmalloc(size, GFP_NOFS, tb->tb_sb);
-	    if ( !buf ) {
+	int check_fs = 0;
+	int size;
+	char *buf;
+
+	size = get_virtual_node_size(tb->tb_sb, PATH_PLAST_BUFFER(tb->tb_path));
+
+	if (size > tb->vn_buf_size) {
+		/* we have to allocate more memory for virtual node */
+		if (tb->vn_buf) {
+			/* free memory allocated before */
+			reiserfs_kfree(tb->vn_buf, tb->vn_buf_size, tb->tb_sb);
+			/* this is not needed if kfree is atomic */
+			check_fs = 1;
+		}
+
+		/* virtual node requires now more memory */
+		tb->vn_buf_size = size;
+
+		/* get memory for virtual item */
+		buf =
+		    reiserfs_kmalloc(size, GFP_ATOMIC | __GFP_NOWARN,
+				     tb->tb_sb);
+		if (!buf) {
+			/* getting memory with GFP_KERNEL priority may involve
+			   balancing now (due to indirect_to_direct conversion on
+			   dcache shrinking). So, release path and collected
+			   resources here */
+			free_buffers_in_tb(tb);
+			buf = reiserfs_kmalloc(size, GFP_NOFS, tb->tb_sb);
+			if (!buf) {
 #ifdef CONFIG_REISERFS_CHECK
-		reiserfs_warning (tb->tb_sb,
-				  "vs-8345: get_mem_for_virtual_node: "
-				  "kmalloc failed. reiserfs kmalloced %d bytes",
-				  REISERFS_SB(tb->tb_sb)->s_kmallocs);
+				reiserfs_warning(tb->tb_sb,
+						 "vs-8345: get_mem_for_virtual_node: "
+						 "kmalloc failed. reiserfs kmalloced %d bytes",
+						 REISERFS_SB(tb->tb_sb)->
+						 s_kmallocs);
 #endif
-		tb->vn_buf_size = 0;
-	    }
-	    tb->vn_buf = buf;
-	    schedule() ;
-	    return REPEAT_SEARCH;
-	}
+				tb->vn_buf_size = 0;
+			}
+			tb->vn_buf = buf;
+			schedule();
+			return REPEAT_SEARCH;
+		}
 
-	tb->vn_buf = buf;
-    }
+		tb->vn_buf = buf;
+	}
 
-    if ( check_fs && FILESYSTEM_CHANGED_TB (tb) )
-        return REPEAT_SEARCH;
+	if (check_fs && FILESYSTEM_CHANGED_TB(tb))
+		return REPEAT_SEARCH;
 
-    return CARRY_ON;
+	return CARRY_ON;
 }
 
-
 #ifdef CONFIG_REISERFS_CHECK
-static void tb_buffer_sanity_check (struct super_block * p_s_sb,
-				    struct buffer_head * p_s_bh, 
-				    const char *descr, int level) {
-  if (p_s_bh) {
-    if (atomic_read (&(p_s_bh->b_count)) <= 0) {
-
-      reiserfs_panic (p_s_sb, "jmacd-1: tb_buffer_sanity_check(): negative or zero reference counter for buffer %s[%d] (%b)\n", descr, level, p_s_bh);
-    }
-
-    if ( ! buffer_uptodate (p_s_bh) ) {
-      reiserfs_panic (p_s_sb, "jmacd-2: tb_buffer_sanity_check(): buffer is not up to date %s[%d] (%b)\n", descr, level, p_s_bh);
-    }
-
-    if ( ! B_IS_IN_TREE (p_s_bh) ) {
-      reiserfs_panic (p_s_sb, "jmacd-3: tb_buffer_sanity_check(): buffer is not in tree %s[%d] (%b)\n", descr, level, p_s_bh);
-    }
-
-    if (p_s_bh->b_bdev != p_s_sb->s_bdev) {
-	reiserfs_panic (p_s_sb, "jmacd-4: tb_buffer_sanity_check(): buffer has wrong device %s[%d] (%b)\n", descr, level, p_s_bh);
-    }
-
-    if (p_s_bh->b_size != p_s_sb->s_blocksize) {
-	reiserfs_panic (p_s_sb, "jmacd-5: tb_buffer_sanity_check(): buffer has wrong blocksize %s[%d] (%b)\n", descr, level, p_s_bh);
-    }
-
-    if (p_s_bh->b_blocknr > SB_BLOCK_COUNT(p_s_sb)) {
-	reiserfs_panic (p_s_sb, "jmacd-6: tb_buffer_sanity_check(): buffer block number too high %s[%d] (%b)\n", descr, level, p_s_bh);
-    }
-  }
+static void tb_buffer_sanity_check(struct super_block *p_s_sb,
+				   struct buffer_head *p_s_bh,
+				   const char *descr, int level)
+{
+	if (p_s_bh) {
+		if (atomic_read(&(p_s_bh->b_count)) <= 0) {
+
+			reiserfs_panic(p_s_sb,
+				       "jmacd-1: tb_buffer_sanity_check(): negative or zero reference counter for buffer %s[%d] (%b)\n",
+				       descr, level, p_s_bh);
+		}
+
+		if (!buffer_uptodate(p_s_bh)) {
+			reiserfs_panic(p_s_sb,
+				       "jmacd-2: tb_buffer_sanity_check(): buffer is not up to date %s[%d] (%b)\n",
+				       descr, level, p_s_bh);
+		}
+
+		if (!B_IS_IN_TREE(p_s_bh)) {
+			reiserfs_panic(p_s_sb,
+				       "jmacd-3: tb_buffer_sanity_check(): buffer is not in tree %s[%d] (%b)\n",
+				       descr, level, p_s_bh);
+		}
+
+		if (p_s_bh->b_bdev != p_s_sb->s_bdev) {
+			reiserfs_panic(p_s_sb,
+				       "jmacd-4: tb_buffer_sanity_check(): buffer has wrong device %s[%d] (%b)\n",
+				       descr, level, p_s_bh);
+		}
+
+		if (p_s_bh->b_size != p_s_sb->s_blocksize) {
+			reiserfs_panic(p_s_sb,
+				       "jmacd-5: tb_buffer_sanity_check(): buffer has wrong blocksize %s[%d] (%b)\n",
+				       descr, level, p_s_bh);
+		}
+
+		if (p_s_bh->b_blocknr > SB_BLOCK_COUNT(p_s_sb)) {
+			reiserfs_panic(p_s_sb,
+				       "jmacd-6: tb_buffer_sanity_check(): buffer block number too high %s[%d] (%b)\n",
+				       descr, level, p_s_bh);
+		}
+	}
 }
 #else
-static void tb_buffer_sanity_check (struct super_block * p_s_sb,
-				    struct buffer_head * p_s_bh, 
-				    const char *descr, int level)
-{;}
+static void tb_buffer_sanity_check(struct super_block *p_s_sb,
+				   struct buffer_head *p_s_bh,
+				   const char *descr, int level)
+{;
+}
 #endif
 
-static int clear_all_dirty_bits(struct super_block *s,
-                                 struct buffer_head *bh) {
-  return reiserfs_prepare_for_journal(s, bh, 0) ;
+static int clear_all_dirty_bits(struct super_block *s, struct buffer_head *bh)
+{
+	return reiserfs_prepare_for_journal(s, bh, 0);
 }
 
-static int wait_tb_buffers_until_unlocked (struct tree_balance * p_s_tb)
+static int wait_tb_buffers_until_unlocked(struct tree_balance *p_s_tb)
 {
-    struct buffer_head * locked;
+	struct buffer_head *locked;
 #ifdef CONFIG_REISERFS_CHECK
-    int repeat_counter = 0;
+	int repeat_counter = 0;
 #endif
-    int i;
+	int i;
 
-    do {
+	do {
 
-	locked = NULL;
+		locked = NULL;
 
-	for ( i = p_s_tb->tb_path->path_length; !locked && i > ILLEGAL_PATH_ELEMENT_OFFSET; i-- ) {
-	    if ( PATH_OFFSET_PBUFFER (p_s_tb->tb_path, i) ) {
-		/* if I understand correctly, we can only be sure the last buffer
-		** in the path is in the tree --clm
-		*/
+		for (i = p_s_tb->tb_path->path_length;
+		     !locked && i > ILLEGAL_PATH_ELEMENT_OFFSET; i--) {
+			if (PATH_OFFSET_PBUFFER(p_s_tb->tb_path, i)) {
+				/* if I understand correctly, we can only be sure the last buffer
+				 ** in the path is in the tree --clm
+				 */
 #ifdef CONFIG_REISERFS_CHECK
-		if (PATH_PLAST_BUFFER(p_s_tb->tb_path) ==
-		    PATH_OFFSET_PBUFFER(p_s_tb->tb_path, i)) {
-		    tb_buffer_sanity_check (p_s_tb->tb_sb, 
-					    PATH_OFFSET_PBUFFER (p_s_tb->tb_path, i), 
-					    "S", 
-					    p_s_tb->tb_path->path_length - i);
-		}
+				if (PATH_PLAST_BUFFER(p_s_tb->tb_path) ==
+				    PATH_OFFSET_PBUFFER(p_s_tb->tb_path, i)) {
+					tb_buffer_sanity_check(p_s_tb->tb_sb,
+							       PATH_OFFSET_PBUFFER
+							       (p_s_tb->tb_path,
+								i), "S",
+							       p_s_tb->tb_path->
+							       path_length - i);
+				}
 #endif
-		if (!clear_all_dirty_bits(p_s_tb->tb_sb,
-				     PATH_OFFSET_PBUFFER (p_s_tb->tb_path, i)))
-		{
-		    locked = PATH_OFFSET_PBUFFER (p_s_tb->tb_path, i);
-		}
-	    }
-	}
-
-	for ( i = 0; !locked && i < MAX_HEIGHT && p_s_tb->insert_size[i]; i++ ) { 
-
-	    if (p_s_tb->lnum[i] ) {
-
-		if ( p_s_tb->L[i] ) {
-		    tb_buffer_sanity_check (p_s_tb->tb_sb, p_s_tb->L[i], "L", i);
-		    if (!clear_all_dirty_bits(p_s_tb->tb_sb, p_s_tb->L[i]))
-			locked = p_s_tb->L[i];
+				if (!clear_all_dirty_bits(p_s_tb->tb_sb,
+							  PATH_OFFSET_PBUFFER
+							  (p_s_tb->tb_path,
+							   i))) {
+					locked =
+					    PATH_OFFSET_PBUFFER(p_s_tb->tb_path,
+								i);
+				}
+			}
 		}
 
-		if ( !locked && p_s_tb->FL[i] ) {
-		    tb_buffer_sanity_check (p_s_tb->tb_sb, p_s_tb->FL[i], "FL", i);
-		    if (!clear_all_dirty_bits(p_s_tb->tb_sb, p_s_tb->FL[i]))
-			locked = p_s_tb->FL[i];
-		}
-
-		if ( !locked && p_s_tb->CFL[i] ) {
-		    tb_buffer_sanity_check (p_s_tb->tb_sb, p_s_tb->CFL[i], "CFL", i);
-		    if (!clear_all_dirty_bits(p_s_tb->tb_sb, p_s_tb->CFL[i]))
-			locked = p_s_tb->CFL[i];
-		}
+		for (i = 0; !locked && i < MAX_HEIGHT && p_s_tb->insert_size[i];
+		     i++) {
 
-	    }
+			if (p_s_tb->lnum[i]) {
 
-	    if ( !locked && (p_s_tb->rnum[i]) ) {
-
-		if ( p_s_tb->R[i] ) {
-		    tb_buffer_sanity_check (p_s_tb->tb_sb, p_s_tb->R[i], "R", i);
-		    if (!clear_all_dirty_bits(p_s_tb->tb_sb, p_s_tb->R[i]))
-			locked = p_s_tb->R[i];
+				if (p_s_tb->L[i]) {
+					tb_buffer_sanity_check(p_s_tb->tb_sb,
+							       p_s_tb->L[i],
+							       "L", i);
+					if (!clear_all_dirty_bits
+					    (p_s_tb->tb_sb, p_s_tb->L[i]))
+						locked = p_s_tb->L[i];
+				}
+
+				if (!locked && p_s_tb->FL[i]) {
+					tb_buffer_sanity_check(p_s_tb->tb_sb,
+							       p_s_tb->FL[i],
+							       "FL", i);
+					if (!clear_all_dirty_bits
+					    (p_s_tb->tb_sb, p_s_tb->FL[i]))
+						locked = p_s_tb->FL[i];
+				}
+
+				if (!locked && p_s_tb->CFL[i]) {
+					tb_buffer_sanity_check(p_s_tb->tb_sb,
+							       p_s_tb->CFL[i],
+							       "CFL", i);
+					if (!clear_all_dirty_bits
+					    (p_s_tb->tb_sb, p_s_tb->CFL[i]))
+						locked = p_s_tb->CFL[i];
+				}
+
+			}
+
+			if (!locked && (p_s_tb->rnum[i])) {
+
+				if (p_s_tb->R[i]) {
+					tb_buffer_sanity_check(p_s_tb->tb_sb,
+							       p_s_tb->R[i],
+							       "R", i);
+					if (!clear_all_dirty_bits
+					    (p_s_tb->tb_sb, p_s_tb->R[i]))
+						locked = p_s_tb->R[i];
+				}
+
+				if (!locked && p_s_tb->FR[i]) {
+					tb_buffer_sanity_check(p_s_tb->tb_sb,
+							       p_s_tb->FR[i],
+							       "FR", i);
+					if (!clear_all_dirty_bits
+					    (p_s_tb->tb_sb, p_s_tb->FR[i]))
+						locked = p_s_tb->FR[i];
+				}
+
+				if (!locked && p_s_tb->CFR[i]) {
+					tb_buffer_sanity_check(p_s_tb->tb_sb,
+							       p_s_tb->CFR[i],
+							       "CFR", i);
+					if (!clear_all_dirty_bits
+					    (p_s_tb->tb_sb, p_s_tb->CFR[i]))
+						locked = p_s_tb->CFR[i];
+				}
+			}
 		}
-
-       
-		if ( !locked && p_s_tb->FR[i] ) {
-		    tb_buffer_sanity_check (p_s_tb->tb_sb, p_s_tb->FR[i], "FR", i);
-		    if (!clear_all_dirty_bits(p_s_tb->tb_sb, p_s_tb->FR[i]))
-			locked = p_s_tb->FR[i];
+		/* as far as I can tell, this is not required.  The FEB list seems
+		 ** to be full of newly allocated nodes, which will never be locked,
+		 ** dirty, or anything else.
+		 ** To be safe, I'm putting in the checks and waits in.  For the moment,
+		 ** they are needed to keep the code in journal.c from complaining
+		 ** about the buffer.  That code is inside CONFIG_REISERFS_CHECK as well.
+		 ** --clm
+		 */
+		for (i = 0; !locked && i < MAX_FEB_SIZE; i++) {
+			if (p_s_tb->FEB[i]) {
+				if (!clear_all_dirty_bits
+				    (p_s_tb->tb_sb, p_s_tb->FEB[i]))
+					locked = p_s_tb->FEB[i];
+			}
 		}
 
-		if ( !locked && p_s_tb->CFR[i] ) {
-		    tb_buffer_sanity_check (p_s_tb->tb_sb, p_s_tb->CFR[i], "CFR", i);
-		    if (!clear_all_dirty_bits(p_s_tb->tb_sb, p_s_tb->CFR[i]))
-			locked = p_s_tb->CFR[i];
-		}
-	    }
-	}
-	/* as far as I can tell, this is not required.  The FEB list seems
-	** to be full of newly allocated nodes, which will never be locked,
-	** dirty, or anything else.
-	** To be safe, I'm putting in the checks and waits in.  For the moment,
-	** they are needed to keep the code in journal.c from complaining
-	** about the buffer.  That code is inside CONFIG_REISERFS_CHECK as well.
-	** --clm
-	*/
-	for ( i = 0; !locked && i < MAX_FEB_SIZE; i++ ) { 
-	    if ( p_s_tb->FEB[i] ) {
-		if (!clear_all_dirty_bits(p_s_tb->tb_sb, p_s_tb->FEB[i]))
-		    locked = p_s_tb->FEB[i] ;
-	    }
-	}
-
-	if (locked) {
+		if (locked) {
 #ifdef CONFIG_REISERFS_CHECK
-	    repeat_counter++;
-	    if ( (repeat_counter % 10000) == 0) {
-		reiserfs_warning (p_s_tb->tb_sb,
-				  "wait_tb_buffers_until_released(): too many "
-				  "iterations waiting for buffer to unlock "
-				  "(%b)", locked);
-
-		/* Don't loop forever.  Try to recover from possible error. */
-
-		return ( FILESYSTEM_CHANGED_TB (p_s_tb) ) ? REPEAT_SEARCH : CARRY_ON;
-	    }
+			repeat_counter++;
+			if ((repeat_counter % 10000) == 0) {
+				reiserfs_warning(p_s_tb->tb_sb,
+						 "wait_tb_buffers_until_released(): too many "
+						 "iterations waiting for buffer to unlock "
+						 "(%b)", locked);
+
+				/* Don't loop forever.  Try to recover from possible error. */
+
+				return (FILESYSTEM_CHANGED_TB(p_s_tb)) ?
+				    REPEAT_SEARCH : CARRY_ON;
+			}
 #endif
-	    __wait_on_buffer (locked);
-	    if ( FILESYSTEM_CHANGED_TB (p_s_tb) ) {
-		return REPEAT_SEARCH;
-	    }
-	}
+			__wait_on_buffer(locked);
+			if (FILESYSTEM_CHANGED_TB(p_s_tb)) {
+				return REPEAT_SEARCH;
+			}
+		}
 
-    } while (locked);
+	} while (locked);
 
-    return CARRY_ON;
+	return CARRY_ON;
 }
 
-
 /* Prepare for balancing, that is
  *	get all necessary parents, and neighbors;
  *	analyze what and where should be moved;
@@ -2267,252 +2360,266 @@ static int wait_tb_buffers_until_unlocke
  *             -1 - if no_disk_space 
  */
 
+int fix_nodes(int n_op_mode, struct tree_balance *p_s_tb, struct item_head *p_s_ins_ih,	// item head of item being inserted
+	      const void *data	// inserted item or data to be pasted
+    )
+{
+	int n_ret_value, n_h, n_item_num = PATH_LAST_POSITION(p_s_tb->tb_path);
+	int n_pos_in_item;
 
-int fix_nodes (int n_op_mode,
-	       struct tree_balance * 	p_s_tb,
-	       struct item_head * p_s_ins_ih, // item head of item being inserted
-	       const void * data // inserted item or data to be pasted
-    ) {
-    int	n_ret_value,
-    	n_h,
-    	n_item_num = PATH_LAST_POSITION(p_s_tb->tb_path);
-    int n_pos_in_item;
-
-    /* we set wait_tb_buffers_run when we have to restore any dirty bits cleared
-    ** during wait_tb_buffers_run
-    */
-    int wait_tb_buffers_run = 0 ; 
-    struct buffer_head  * p_s_tbS0 = PATH_PLAST_BUFFER(p_s_tb->tb_path);
-
-    ++ REISERFS_SB(p_s_tb -> tb_sb) -> s_fix_nodes;
-
-    n_pos_in_item = p_s_tb->tb_path->pos_in_item;
-
-
-    p_s_tb->fs_gen = get_generation (p_s_tb->tb_sb);
-
-    /* we prepare and log the super here so it will already be in the
-    ** transaction when do_balance needs to change it.
-    ** This way do_balance won't have to schedule when trying to prepare
-    ** the super for logging
-    */
-    reiserfs_prepare_for_journal(p_s_tb->tb_sb, 
-                                 SB_BUFFER_WITH_SB(p_s_tb->tb_sb), 1) ;
-    journal_mark_dirty(p_s_tb->transaction_handle, p_s_tb->tb_sb, 
-                       SB_BUFFER_WITH_SB(p_s_tb->tb_sb)) ;
-    if ( FILESYSTEM_CHANGED_TB (p_s_tb) )
-	return REPEAT_SEARCH;
-
-    /* if it possible in indirect_to_direct conversion */
-    if (buffer_locked (p_s_tbS0)) {
-        __wait_on_buffer (p_s_tbS0);
-        if ( FILESYSTEM_CHANGED_TB (p_s_tb) )
-            return REPEAT_SEARCH;
-    }
+	/* we set wait_tb_buffers_run when we have to restore any dirty bits cleared
+	 ** during wait_tb_buffers_run
+	 */
+	int wait_tb_buffers_run = 0;
+	struct buffer_head *p_s_tbS0 = PATH_PLAST_BUFFER(p_s_tb->tb_path);
 
-#ifdef CONFIG_REISERFS_CHECK
-    if ( cur_tb ) {
-	print_cur_tb ("fix_nodes");
-	reiserfs_panic(p_s_tb->tb_sb,"PAP-8305: fix_nodes:  there is pending do_balance");
-    }
-
-    if (!buffer_uptodate (p_s_tbS0) || !B_IS_IN_TREE (p_s_tbS0)) {
-	reiserfs_panic (p_s_tb->tb_sb, "PAP-8320: fix_nodes: S[0] (%b %z) is not uptodate "
-			"at the beginning of fix_nodes or not in tree (mode %c)", p_s_tbS0, p_s_tbS0, n_op_mode);
-    }
-
-    /* Check parameters. */
-    switch (n_op_mode) {
-    case M_INSERT:
-	if ( n_item_num <= 0 || n_item_num > B_NR_ITEMS(p_s_tbS0) )
-	    reiserfs_panic(p_s_tb->tb_sb,"PAP-8330: fix_nodes: Incorrect item number %d (in S0 - %d) in case of insert",
-			   n_item_num, B_NR_ITEMS(p_s_tbS0));
-	break;
-    case M_PASTE:
-    case M_DELETE:
-    case M_CUT:
-	if ( n_item_num < 0 || n_item_num >= B_NR_ITEMS(p_s_tbS0) ) {
-	    print_block (p_s_tbS0, 0, -1, -1);
-	    reiserfs_panic(p_s_tb->tb_sb,"PAP-8335: fix_nodes: Incorrect item number(%d); mode = %c insert_size = %d\n", n_item_num, n_op_mode, p_s_tb->insert_size[0]);
-	}
-	break;
-    default:
-	reiserfs_panic(p_s_tb->tb_sb,"PAP-8340: fix_nodes: Incorrect mode of operation");
-    }
-#endif
+	++REISERFS_SB(p_s_tb->tb_sb)->s_fix_nodes;
+
+	n_pos_in_item = p_s_tb->tb_path->pos_in_item;
+
+	p_s_tb->fs_gen = get_generation(p_s_tb->tb_sb);
 
-    if (get_mem_for_virtual_node (p_s_tb) == REPEAT_SEARCH)
-	// FIXME: maybe -ENOMEM when tb->vn_buf == 0? Now just repeat
-	return REPEAT_SEARCH;
-
-
-    /* Starting from the leaf level; for all levels n_h of the tree. */
-    for ( n_h = 0; n_h < MAX_HEIGHT && p_s_tb->insert_size[n_h]; n_h++ ) { 
-	if ( (n_ret_value = get_direct_parent(p_s_tb, n_h)) != CARRY_ON ) {
-	    goto repeat;
-	}
-
-	if ( (n_ret_value = check_balance (n_op_mode, p_s_tb, n_h, n_item_num,
-					   n_pos_in_item, p_s_ins_ih, data)) != CARRY_ON ) {
-	    if ( n_ret_value == NO_BALANCING_NEEDED ) {
-		/* No balancing for higher levels needed. */
-		if ( (n_ret_value = get_neighbors(p_s_tb, n_h)) != CARRY_ON ) {
-		    goto repeat;
-		}
-		if ( n_h != MAX_HEIGHT - 1 )  
-		    p_s_tb->insert_size[n_h + 1] = 0;
-		/* ok, analysis and resource gathering are complete */
+	/* we prepare and log the super here so it will already be in the
+	 ** transaction when do_balance needs to change it.
+	 ** This way do_balance won't have to schedule when trying to prepare
+	 ** the super for logging
+	 */
+	reiserfs_prepare_for_journal(p_s_tb->tb_sb,
+				     SB_BUFFER_WITH_SB(p_s_tb->tb_sb), 1);
+	journal_mark_dirty(p_s_tb->transaction_handle, p_s_tb->tb_sb,
+			   SB_BUFFER_WITH_SB(p_s_tb->tb_sb));
+	if (FILESYSTEM_CHANGED_TB(p_s_tb))
+		return REPEAT_SEARCH;
+
+	/* if it possible in indirect_to_direct conversion */
+	if (buffer_locked(p_s_tbS0)) {
+		__wait_on_buffer(p_s_tbS0);
+		if (FILESYSTEM_CHANGED_TB(p_s_tb))
+			return REPEAT_SEARCH;
+	}
+#ifdef CONFIG_REISERFS_CHECK
+	if (cur_tb) {
+		print_cur_tb("fix_nodes");
+		reiserfs_panic(p_s_tb->tb_sb,
+			       "PAP-8305: fix_nodes:  there is pending do_balance");
+	}
+
+	if (!buffer_uptodate(p_s_tbS0) || !B_IS_IN_TREE(p_s_tbS0)) {
+		reiserfs_panic(p_s_tb->tb_sb,
+			       "PAP-8320: fix_nodes: S[0] (%b %z) is not uptodate "
+			       "at the beginning of fix_nodes or not in tree (mode %c)",
+			       p_s_tbS0, p_s_tbS0, n_op_mode);
+	}
+
+	/* Check parameters. */
+	switch (n_op_mode) {
+	case M_INSERT:
+		if (n_item_num <= 0 || n_item_num > B_NR_ITEMS(p_s_tbS0))
+			reiserfs_panic(p_s_tb->tb_sb,
+				       "PAP-8330: fix_nodes: Incorrect item number %d (in S0 - %d) in case of insert",
+				       n_item_num, B_NR_ITEMS(p_s_tbS0));
 		break;
-	    }
-	    goto repeat;
+	case M_PASTE:
+	case M_DELETE:
+	case M_CUT:
+		if (n_item_num < 0 || n_item_num >= B_NR_ITEMS(p_s_tbS0)) {
+			print_block(p_s_tbS0, 0, -1, -1);
+			reiserfs_panic(p_s_tb->tb_sb,
+				       "PAP-8335: fix_nodes: Incorrect item number(%d); mode = %c insert_size = %d\n",
+				       n_item_num, n_op_mode,
+				       p_s_tb->insert_size[0]);
+		}
+		break;
+	default:
+		reiserfs_panic(p_s_tb->tb_sb,
+			       "PAP-8340: fix_nodes: Incorrect mode of operation");
 	}
+#endif
 
-	if ( (n_ret_value = get_neighbors(p_s_tb, n_h)) != CARRY_ON ) {
-	    goto repeat;
-	}
+	if (get_mem_for_virtual_node(p_s_tb) == REPEAT_SEARCH)
+		// FIXME: maybe -ENOMEM when tb->vn_buf == 0? Now just repeat
+		return REPEAT_SEARCH;
 
-	if ( (n_ret_value = get_empty_nodes(p_s_tb, n_h)) != CARRY_ON ) {
-	    goto repeat;        /* No disk space, or schedule occurred and
-				   analysis may be invalid and needs to be redone. */
-	}
-    
-	if ( ! PATH_H_PBUFFER(p_s_tb->tb_path, n_h) ) {
-	    /* We have a positive insert size but no nodes exist on this
-	       level, this means that we are creating a new root. */
+	/* Starting from the leaf level; for all levels n_h of the tree. */
+	for (n_h = 0; n_h < MAX_HEIGHT && p_s_tb->insert_size[n_h]; n_h++) {
+		if ((n_ret_value = get_direct_parent(p_s_tb, n_h)) != CARRY_ON) {
+			goto repeat;
+		}
 
-	    RFALSE( p_s_tb->blknum[n_h] != 1,
-		    "PAP-8350: creating new empty root");
+		if ((n_ret_value =
+		     check_balance(n_op_mode, p_s_tb, n_h, n_item_num,
+				   n_pos_in_item, p_s_ins_ih,
+				   data)) != CARRY_ON) {
+			if (n_ret_value == NO_BALANCING_NEEDED) {
+				/* No balancing for higher levels needed. */
+				if ((n_ret_value =
+				     get_neighbors(p_s_tb, n_h)) != CARRY_ON) {
+					goto repeat;
+				}
+				if (n_h != MAX_HEIGHT - 1)
+					p_s_tb->insert_size[n_h + 1] = 0;
+				/* ok, analysis and resource gathering are complete */
+				break;
+			}
+			goto repeat;
+		}
 
-	    if ( n_h < MAX_HEIGHT - 1 )
-		p_s_tb->insert_size[n_h + 1] = 0;
-	}
-	else
-	    if ( ! PATH_H_PBUFFER(p_s_tb->tb_path, n_h + 1) ) {
-		if ( p_s_tb->blknum[n_h] > 1 ) {
-		    /* The tree needs to be grown, so this node S[n_h]
-		       which is the root node is split into two nodes,
-		       and a new node (S[n_h+1]) will be created to
-		       become the root node.  */
-	  
-		    RFALSE( n_h == MAX_HEIGHT - 1,
-			    "PAP-8355: attempt to create too high of a tree");
-
-		    p_s_tb->insert_size[n_h + 1] = (DC_SIZE + KEY_SIZE) * (p_s_tb->blknum[n_h] - 1) + DC_SIZE;
-		}
-		else
-		    if ( n_h < MAX_HEIGHT - 1 )
-			p_s_tb->insert_size[n_h + 1] = 0;
-	    }
-	    else
-		p_s_tb->insert_size[n_h + 1] = (DC_SIZE + KEY_SIZE) * (p_s_tb->blknum[n_h] - 1);
-    }
+		if ((n_ret_value = get_neighbors(p_s_tb, n_h)) != CARRY_ON) {
+			goto repeat;
+		}
 
-    if ((n_ret_value = wait_tb_buffers_until_unlocked (p_s_tb)) == CARRY_ON) {
-	if (FILESYSTEM_CHANGED_TB(p_s_tb)) {
-	    wait_tb_buffers_run = 1 ;
-	    n_ret_value = REPEAT_SEARCH ;
-	    goto repeat; 
+		if ((n_ret_value = get_empty_nodes(p_s_tb, n_h)) != CARRY_ON) {
+			goto repeat;	/* No disk space, or schedule occurred and
+					   analysis may be invalid and needs to be redone. */
+		}
+
+		if (!PATH_H_PBUFFER(p_s_tb->tb_path, n_h)) {
+			/* We have a positive insert size but no nodes exist on this
+			   level, this means that we are creating a new root. */
+
+			RFALSE(p_s_tb->blknum[n_h] != 1,
+			       "PAP-8350: creating new empty root");
+
+			if (n_h < MAX_HEIGHT - 1)
+				p_s_tb->insert_size[n_h + 1] = 0;
+		} else if (!PATH_H_PBUFFER(p_s_tb->tb_path, n_h + 1)) {
+			if (p_s_tb->blknum[n_h] > 1) {
+				/* The tree needs to be grown, so this node S[n_h]
+				   which is the root node is split into two nodes,
+				   and a new node (S[n_h+1]) will be created to
+				   become the root node.  */
+
+				RFALSE(n_h == MAX_HEIGHT - 1,
+				       "PAP-8355: attempt to create too high of a tree");
+
+				p_s_tb->insert_size[n_h + 1] =
+				    (DC_SIZE +
+				     KEY_SIZE) * (p_s_tb->blknum[n_h] - 1) +
+				    DC_SIZE;
+			} else if (n_h < MAX_HEIGHT - 1)
+				p_s_tb->insert_size[n_h + 1] = 0;
+		} else
+			p_s_tb->insert_size[n_h + 1] =
+			    (DC_SIZE + KEY_SIZE) * (p_s_tb->blknum[n_h] - 1);
+	}
+
+	if ((n_ret_value = wait_tb_buffers_until_unlocked(p_s_tb)) == CARRY_ON) {
+		if (FILESYSTEM_CHANGED_TB(p_s_tb)) {
+			wait_tb_buffers_run = 1;
+			n_ret_value = REPEAT_SEARCH;
+			goto repeat;
+		} else {
+			return CARRY_ON;
+		}
 	} else {
-	    return CARRY_ON;
+		wait_tb_buffers_run = 1;
+		goto repeat;
 	}
-    } else {
-	wait_tb_buffers_run = 1 ;
-	goto repeat; 
-    }
-
- repeat:
-    // fix_nodes was unable to perform its calculation due to
-    // filesystem got changed under us, lack of free disk space or i/o
-    // failure. If the first is the case - the search will be
-    // repeated. For now - free all resources acquired so far except
-    // for the new allocated nodes
-    {
-	int i;
 
-	/* Release path buffers. */
-	if (wait_tb_buffers_run) {
-	    pathrelse_and_restore(p_s_tb->tb_sb, p_s_tb->tb_path) ;
-	} else {
-	    pathrelse (p_s_tb->tb_path);
-        }	
-	/* brelse all resources collected for balancing */
-	for ( i = 0; i < MAX_HEIGHT; i++ ) {
-	    if (wait_tb_buffers_run) {
-		reiserfs_restore_prepared_buffer(p_s_tb->tb_sb, p_s_tb->L[i]);
-		reiserfs_restore_prepared_buffer(p_s_tb->tb_sb, p_s_tb->R[i]);
-		reiserfs_restore_prepared_buffer(p_s_tb->tb_sb, p_s_tb->FL[i]);
-		reiserfs_restore_prepared_buffer(p_s_tb->tb_sb, p_s_tb->FR[i]);
-		reiserfs_restore_prepared_buffer(p_s_tb->tb_sb, p_s_tb->CFL[i]);
-		reiserfs_restore_prepared_buffer(p_s_tb->tb_sb, p_s_tb->CFR[i]);
-	    }
-
-	    brelse (p_s_tb->L[i]);p_s_tb->L[i] = NULL;
-	    brelse (p_s_tb->R[i]);p_s_tb->R[i] = NULL;
-	    brelse (p_s_tb->FL[i]);p_s_tb->FL[i] = NULL;
-	    brelse (p_s_tb->FR[i]);p_s_tb->FR[i] = NULL;
-	    brelse (p_s_tb->CFL[i]);p_s_tb->CFL[i] = NULL;
-	    brelse (p_s_tb->CFR[i]);p_s_tb->CFR[i] = NULL;
-	}
-
-	if (wait_tb_buffers_run) {
-	    for ( i = 0; i < MAX_FEB_SIZE; i++ ) { 
-		if ( p_s_tb->FEB[i] ) {
-		    reiserfs_restore_prepared_buffer(p_s_tb->tb_sb, 
-						     p_s_tb->FEB[i]) ;
+      repeat:
+	// fix_nodes was unable to perform its calculation due to
+	// filesystem got changed under us, lack of free disk space or i/o
+	// failure. If the first is the case - the search will be
+	// repeated. For now - free all resources acquired so far except
+	// for the new allocated nodes
+	{
+		int i;
+
+		/* Release path buffers. */
+		if (wait_tb_buffers_run) {
+			pathrelse_and_restore(p_s_tb->tb_sb, p_s_tb->tb_path);
+		} else {
+			pathrelse(p_s_tb->tb_path);
+		}
+		/* brelse all resources collected for balancing */
+		for (i = 0; i < MAX_HEIGHT; i++) {
+			if (wait_tb_buffers_run) {
+				reiserfs_restore_prepared_buffer(p_s_tb->tb_sb,
+								 p_s_tb->L[i]);
+				reiserfs_restore_prepared_buffer(p_s_tb->tb_sb,
+								 p_s_tb->R[i]);
+				reiserfs_restore_prepared_buffer(p_s_tb->tb_sb,
+								 p_s_tb->FL[i]);
+				reiserfs_restore_prepared_buffer(p_s_tb->tb_sb,
+								 p_s_tb->FR[i]);
+				reiserfs_restore_prepared_buffer(p_s_tb->tb_sb,
+								 p_s_tb->
+								 CFL[i]);
+				reiserfs_restore_prepared_buffer(p_s_tb->tb_sb,
+								 p_s_tb->
+								 CFR[i]);
+			}
+
+			brelse(p_s_tb->L[i]);
+			p_s_tb->L[i] = NULL;
+			brelse(p_s_tb->R[i]);
+			p_s_tb->R[i] = NULL;
+			brelse(p_s_tb->FL[i]);
+			p_s_tb->FL[i] = NULL;
+			brelse(p_s_tb->FR[i]);
+			p_s_tb->FR[i] = NULL;
+			brelse(p_s_tb->CFL[i]);
+			p_s_tb->CFL[i] = NULL;
+			brelse(p_s_tb->CFR[i]);
+			p_s_tb->CFR[i] = NULL;
+		}
+
+		if (wait_tb_buffers_run) {
+			for (i = 0; i < MAX_FEB_SIZE; i++) {
+				if (p_s_tb->FEB[i]) {
+					reiserfs_restore_prepared_buffer
+					    (p_s_tb->tb_sb, p_s_tb->FEB[i]);
+				}
+			}
 		}
-	    }
+		return n_ret_value;
 	}
-	return n_ret_value;
-    }
 
 }
 
-
 /* Anatoly will probably forgive me renaming p_s_tb to tb. I just
    wanted to make lines shorter */
-void unfix_nodes (struct tree_balance * tb)
+void unfix_nodes(struct tree_balance *tb)
 {
-    int	i;
+	int i;
 
-    /* Release path buffers. */
-    pathrelse_and_restore (tb->tb_sb, tb->tb_path);
+	/* Release path buffers. */
+	pathrelse_and_restore(tb->tb_sb, tb->tb_path);
 
-    /* brelse all resources collected for balancing */
-    for ( i = 0; i < MAX_HEIGHT; i++ ) {
-	reiserfs_restore_prepared_buffer (tb->tb_sb, tb->L[i]);
-	reiserfs_restore_prepared_buffer (tb->tb_sb, tb->R[i]);
-	reiserfs_restore_prepared_buffer (tb->tb_sb, tb->FL[i]);
-	reiserfs_restore_prepared_buffer (tb->tb_sb, tb->FR[i]);
-	reiserfs_restore_prepared_buffer (tb->tb_sb, tb->CFL[i]);
-	reiserfs_restore_prepared_buffer (tb->tb_sb, tb->CFR[i]);
-
-	brelse (tb->L[i]);
-	brelse (tb->R[i]);
-	brelse (tb->FL[i]);
-	brelse (tb->FR[i]);
-	brelse (tb->CFL[i]);
-	brelse (tb->CFR[i]);
-    }
-
-    /* deal with list of allocated (used and unused) nodes */
-    for ( i = 0; i < MAX_FEB_SIZE; i++ ) {
-	if ( tb->FEB[i] ) {
-	    b_blocknr_t blocknr  = tb->FEB[i]->b_blocknr ;
-	    /* de-allocated block which was not used by balancing and
-               bforget about buffer for it */
-	    brelse (tb->FEB[i]);
-	    reiserfs_free_block (tb->transaction_handle, NULL, blocknr, 0);
-	}
-	if (tb->used[i]) {
-	    /* release used as new nodes including a new root */
-	    brelse (tb->used[i]);
+	/* brelse all resources collected for balancing */
+	for (i = 0; i < MAX_HEIGHT; i++) {
+		reiserfs_restore_prepared_buffer(tb->tb_sb, tb->L[i]);
+		reiserfs_restore_prepared_buffer(tb->tb_sb, tb->R[i]);
+		reiserfs_restore_prepared_buffer(tb->tb_sb, tb->FL[i]);
+		reiserfs_restore_prepared_buffer(tb->tb_sb, tb->FR[i]);
+		reiserfs_restore_prepared_buffer(tb->tb_sb, tb->CFL[i]);
+		reiserfs_restore_prepared_buffer(tb->tb_sb, tb->CFR[i]);
+
+		brelse(tb->L[i]);
+		brelse(tb->R[i]);
+		brelse(tb->FL[i]);
+		brelse(tb->FR[i]);
+		brelse(tb->CFL[i]);
+		brelse(tb->CFR[i]);
+	}
+
+	/* deal with list of allocated (used and unused) nodes */
+	for (i = 0; i < MAX_FEB_SIZE; i++) {
+		if (tb->FEB[i]) {
+			b_blocknr_t blocknr = tb->FEB[i]->b_blocknr;
+			/* de-allocated block which was not used by balancing and
+			   bforget about buffer for it */
+			brelse(tb->FEB[i]);
+			reiserfs_free_block(tb->transaction_handle, NULL,
+					    blocknr, 0);
+		}
+		if (tb->used[i]) {
+			/* release used as new nodes including a new root */
+			brelse(tb->used[i]);
+		}
 	}
-    }
-
-    if (tb->vn_buf) 
-    reiserfs_kfree (tb->vn_buf, tb->vn_buf_size, tb->tb_sb);
-
-} 
-
 
+	if (tb->vn_buf)
+		reiserfs_kfree(tb->vn_buf, tb->vn_buf_size, tb->tb_sb);
 
+}
diff --git a/fs/reiserfs/hashes.c b/fs/reiserfs/hashes.c
--- a/fs/reiserfs/hashes.c
+++ b/fs/reiserfs/hashes.c
@@ -22,7 +22,6 @@
 #include <asm/types.h>
 #include <asm/bug.h>
 
-
 #define DELTA 0x9E3779B9
 #define FULLROUNDS 10		/* 32 is overkill, 16 is strong crypto */
 #define PARTROUNDS 6		/* 6 gets complete mixing */
@@ -48,105 +47,75 @@
 		h1 += b1;						\
 	} while(0)
 
-
 u32 keyed_hash(const signed char *msg, int len)
 {
-	u32 k[] = { 0x9464a485, 0x542e1a94, 0x3e846bff, 0xb75bcfc3}; 
+	u32 k[] = { 0x9464a485, 0x542e1a94, 0x3e846bff, 0xb75bcfc3 };
 
 	u32 h0 = k[0], h1 = k[1];
 	u32 a, b, c, d;
 	u32 pad;
 	int i;
- 
-	//	assert(len >= 0 && len < 256);
 
-	pad = (u32)len | ((u32)len << 8);
+	//      assert(len >= 0 && len < 256);
+
+	pad = (u32) len | ((u32) len << 8);
 	pad |= pad << 16;
 
-	while(len >= 16)
-	{
-		a = (u32)msg[ 0]      |
-		    (u32)msg[ 1] << 8 |
-		    (u32)msg[ 2] << 16|
-		    (u32)msg[ 3] << 24;
-		b = (u32)msg[ 4]      |
-		    (u32)msg[ 5] << 8 |
-		    (u32)msg[ 6] << 16|
-		    (u32)msg[ 7] << 24;
-		c = (u32)msg[ 8]      |
-		    (u32)msg[ 9] << 8 |
-		    (u32)msg[10] << 16|
-		    (u32)msg[11] << 24;
-		d = (u32)msg[12]      |
-		    (u32)msg[13] << 8 |
-		    (u32)msg[14] << 16|
-		    (u32)msg[15] << 24;
-		
+	while (len >= 16) {
+		a = (u32) msg[0] |
+		    (u32) msg[1] << 8 | (u32) msg[2] << 16 | (u32) msg[3] << 24;
+		b = (u32) msg[4] |
+		    (u32) msg[5] << 8 | (u32) msg[6] << 16 | (u32) msg[7] << 24;
+		c = (u32) msg[8] |
+		    (u32) msg[9] << 8 |
+		    (u32) msg[10] << 16 | (u32) msg[11] << 24;
+		d = (u32) msg[12] |
+		    (u32) msg[13] << 8 |
+		    (u32) msg[14] << 16 | (u32) msg[15] << 24;
+
 		TEACORE(PARTROUNDS);
 
 		len -= 16;
 		msg += 16;
 	}
 
-	if (len >= 12)
-	{
-		a = (u32)msg[ 0]      |
-		    (u32)msg[ 1] << 8 |
-		    (u32)msg[ 2] << 16|
-		    (u32)msg[ 3] << 24;
-		b = (u32)msg[ 4]      |
-		    (u32)msg[ 5] << 8 |
-		    (u32)msg[ 6] << 16|
-		    (u32)msg[ 7] << 24;
-		c = (u32)msg[ 8]      |
-		    (u32)msg[ 9] << 8 |
-		    (u32)msg[10] << 16|
-		    (u32)msg[11] << 24;
+	if (len >= 12) {
+		a = (u32) msg[0] |
+		    (u32) msg[1] << 8 | (u32) msg[2] << 16 | (u32) msg[3] << 24;
+		b = (u32) msg[4] |
+		    (u32) msg[5] << 8 | (u32) msg[6] << 16 | (u32) msg[7] << 24;
+		c = (u32) msg[8] |
+		    (u32) msg[9] << 8 |
+		    (u32) msg[10] << 16 | (u32) msg[11] << 24;
 
 		d = pad;
-		for(i = 12; i < len; i++)
-		{
+		for (i = 12; i < len; i++) {
 			d <<= 8;
 			d |= msg[i];
 		}
-	}
-	else if (len >= 8)
-	{
-		a = (u32)msg[ 0]      |
-		    (u32)msg[ 1] << 8 |
-		    (u32)msg[ 2] << 16|
-		    (u32)msg[ 3] << 24;
-		b = (u32)msg[ 4]      |
-		    (u32)msg[ 5] << 8 |
-		    (u32)msg[ 6] << 16|
-		    (u32)msg[ 7] << 24;
+	} else if (len >= 8) {
+		a = (u32) msg[0] |
+		    (u32) msg[1] << 8 | (u32) msg[2] << 16 | (u32) msg[3] << 24;
+		b = (u32) msg[4] |
+		    (u32) msg[5] << 8 | (u32) msg[6] << 16 | (u32) msg[7] << 24;
 
 		c = d = pad;
-		for(i = 8; i < len; i++)
-		{
+		for (i = 8; i < len; i++) {
 			c <<= 8;
 			c |= msg[i];
 		}
-	}
-	else if (len >= 4)
-	{
-		a = (u32)msg[ 0]      |
-		    (u32)msg[ 1] << 8 |
-		    (u32)msg[ 2] << 16|
-		    (u32)msg[ 3] << 24;
+	} else if (len >= 4) {
+		a = (u32) msg[0] |
+		    (u32) msg[1] << 8 | (u32) msg[2] << 16 | (u32) msg[3] << 24;
 
 		b = c = d = pad;
-		for(i = 4; i < len; i++)
-		{
+		for (i = 4; i < len; i++) {
 			b <<= 8;
 			b |= msg[i];
 		}
-	}
-	else
-	{
+	} else {
 		a = b = c = d = pad;
-		for(i = 0; i < len; i++)
-		{
+		for (i = 0; i < len; i++) {
 			a <<= 8;
 			a |= msg[i];
 		}
@@ -155,55 +124,59 @@ u32 keyed_hash(const signed char *msg, i
 	TEACORE(FULLROUNDS);
 
 /*	return 0;*/
-	return h0^h1;
+	return h0 ^ h1;
 }
 
 /* What follows in this file is copyright 2000 by Hans Reiser, and the
  * licensing of what follows is governed by reiserfs/README */
 
-u32 yura_hash (const signed char *msg, int len)
+u32 yura_hash(const signed char *msg, int len)
 {
-    int j, pow;
-    u32 a, c;
-    int i;
-    
-    for (pow=1,i=1; i < len; i++) pow = pow * 10; 
-    
-    if (len == 1) 
-	a = msg[0]-48;
-    else
-	a = (msg[0] - 48) * pow;
-    
-    for (i=1; i < len; i++) {
-	c = msg[i] - 48; 
-	for (pow=1,j=i; j < len-1; j++) pow = pow * 10; 
-	a = a + c * pow;
-    }
-    
-    for (; i < 40; i++) {
-	c = '0' - 48; 
-	for (pow=1,j=i; j < len-1; j++) pow = pow * 10; 
-	a = a + c * pow;
-    }
-    
-    for (; i < 256; i++) {
-	c = i; 
-	for (pow=1,j=i; j < len-1; j++) pow = pow * 10; 
-	a = a + c * pow;
-    }
-    
-    a = a << 7;
-    return a;
+	int j, pow;
+	u32 a, c;
+	int i;
+
+	for (pow = 1, i = 1; i < len; i++)
+		pow = pow * 10;
+
+	if (len == 1)
+		a = msg[0] - 48;
+	else
+		a = (msg[0] - 48) * pow;
+
+	for (i = 1; i < len; i++) {
+		c = msg[i] - 48;
+		for (pow = 1, j = i; j < len - 1; j++)
+			pow = pow * 10;
+		a = a + c * pow;
+	}
+
+	for (; i < 40; i++) {
+		c = '0' - 48;
+		for (pow = 1, j = i; j < len - 1; j++)
+			pow = pow * 10;
+		a = a + c * pow;
+	}
+
+	for (; i < 256; i++) {
+		c = i;
+		for (pow = 1, j = i; j < len - 1; j++)
+			pow = pow * 10;
+		a = a + c * pow;
+	}
+
+	a = a << 7;
+	return a;
 }
 
-u32 r5_hash (const signed char *msg, int len)
+u32 r5_hash(const signed char *msg, int len)
 {
-  u32 a=0;
-  while(*msg) { 
-    a += *msg << 4;
-    a += *msg >> 4;
-    a *= 11;
-    msg++;
-   } 
-  return a;
+	u32 a = 0;
+	while (*msg) {
+		a += *msg << 4;
+		a += *msg >> 4;
+		a *= 11;
+		msg++;
+	}
+	return a;
 }
diff --git a/fs/reiserfs/ibalance.c b/fs/reiserfs/ibalance.c
--- a/fs/reiserfs/ibalance.c
+++ b/fs/reiserfs/ibalance.c
@@ -10,13 +10,8 @@
 #include <linux/buffer_head.h>
 
 /* this is one and only function that is used outside (do_balance.c) */
-int	balance_internal (
-			  struct tree_balance * ,
-			  int,
-			  int,
-			  struct item_head * ,
-			  struct buffer_head ** 
-			  );
+int balance_internal(struct tree_balance *,
+		     int, int, struct item_head *, struct buffer_head **);
 
 /* modes of internal_shift_left, internal_shift_right and internal_insert_childs */
 #define INTERNAL_SHIFT_FROM_S_TO_L 0
@@ -27,464 +22,474 @@ int	balance_internal (
 #define INTERNAL_INSERT_TO_L 5
 #define INTERNAL_INSERT_TO_R 6
 
-static void	internal_define_dest_src_infos (
-						int shift_mode,
-						struct tree_balance * tb,
-						int h,
-						struct buffer_info * dest_bi,
-						struct buffer_info * src_bi,
-						int * d_key,
-						struct buffer_head ** cf
-						)
+static void internal_define_dest_src_infos(int shift_mode,
+					   struct tree_balance *tb,
+					   int h,
+					   struct buffer_info *dest_bi,
+					   struct buffer_info *src_bi,
+					   int *d_key, struct buffer_head **cf)
 {
-    memset (dest_bi, 0, sizeof (struct buffer_info));
-    memset (src_bi, 0, sizeof (struct buffer_info));
-    /* define dest, src, dest parent, dest position */
-    switch (shift_mode) {
-    case INTERNAL_SHIFT_FROM_S_TO_L:	/* used in internal_shift_left */
-	src_bi->tb = tb;
-	src_bi->bi_bh = PATH_H_PBUFFER (tb->tb_path, h);
-	src_bi->bi_parent = PATH_H_PPARENT (tb->tb_path, h);
-	src_bi->bi_position = PATH_H_POSITION (tb->tb_path, h + 1);
-	dest_bi->tb = tb;
-	dest_bi->bi_bh = tb->L[h];
-	dest_bi->bi_parent = tb->FL[h];
-	dest_bi->bi_position = get_left_neighbor_position (tb, h);
-	*d_key = tb->lkey[h];
-	*cf = tb->CFL[h];
-	break;
-    case INTERNAL_SHIFT_FROM_L_TO_S:
-	src_bi->tb = tb;
-	src_bi->bi_bh = tb->L[h];
-	src_bi->bi_parent = tb->FL[h];
-	src_bi->bi_position = get_left_neighbor_position (tb, h);
-	dest_bi->tb = tb;
-	dest_bi->bi_bh = PATH_H_PBUFFER (tb->tb_path, h);
-	dest_bi->bi_parent = PATH_H_PPARENT (tb->tb_path, h);
-	dest_bi->bi_position = PATH_H_POSITION (tb->tb_path, h + 1); /* dest position is analog of dest->b_item_order */
-	*d_key = tb->lkey[h];
-	*cf = tb->CFL[h];
-	break;
-      
-    case INTERNAL_SHIFT_FROM_R_TO_S:	/* used in internal_shift_left */
-	src_bi->tb = tb;
-	src_bi->bi_bh = tb->R[h];
-	src_bi->bi_parent = tb->FR[h];
-	src_bi->bi_position = get_right_neighbor_position (tb, h);
-	dest_bi->tb = tb;
-	dest_bi->bi_bh = PATH_H_PBUFFER (tb->tb_path, h);
-	dest_bi->bi_parent = PATH_H_PPARENT (tb->tb_path, h);
-	dest_bi->bi_position = PATH_H_POSITION (tb->tb_path, h + 1);
-	*d_key = tb->rkey[h];
-	*cf = tb->CFR[h];
-	break;
-
-    case INTERNAL_SHIFT_FROM_S_TO_R:
-	src_bi->tb = tb;
-	src_bi->bi_bh = PATH_H_PBUFFER (tb->tb_path, h);
-	src_bi->bi_parent = PATH_H_PPARENT (tb->tb_path, h);
-	src_bi->bi_position = PATH_H_POSITION (tb->tb_path, h + 1);
-	dest_bi->tb = tb;
-	dest_bi->bi_bh = tb->R[h];
-	dest_bi->bi_parent = tb->FR[h];
-	dest_bi->bi_position = get_right_neighbor_position (tb, h);
-	*d_key = tb->rkey[h];
-	*cf = tb->CFR[h];
-	break;
-
-    case INTERNAL_INSERT_TO_L:
-	dest_bi->tb = tb;
-	dest_bi->bi_bh = tb->L[h];
-	dest_bi->bi_parent = tb->FL[h];
-	dest_bi->bi_position = get_left_neighbor_position (tb, h);
-	break;
-	
-    case INTERNAL_INSERT_TO_S:
-	dest_bi->tb = tb;
-	dest_bi->bi_bh = PATH_H_PBUFFER (tb->tb_path, h);
-	dest_bi->bi_parent = PATH_H_PPARENT (tb->tb_path, h);
-	dest_bi->bi_position = PATH_H_POSITION (tb->tb_path, h + 1);
-	break;
-
-    case INTERNAL_INSERT_TO_R:
-	dest_bi->tb = tb;
-	dest_bi->bi_bh = tb->R[h];
-	dest_bi->bi_parent = tb->FR[h];
-	dest_bi->bi_position = get_right_neighbor_position (tb, h);
-	break;
-
-    default:
-	reiserfs_panic (tb->tb_sb, "internal_define_dest_src_infos: shift type is unknown (%d)", shift_mode);
-    }
+	memset(dest_bi, 0, sizeof(struct buffer_info));
+	memset(src_bi, 0, sizeof(struct buffer_info));
+	/* define dest, src, dest parent, dest position */
+	switch (shift_mode) {
+	case INTERNAL_SHIFT_FROM_S_TO_L:	/* used in internal_shift_left */
+		src_bi->tb = tb;
+		src_bi->bi_bh = PATH_H_PBUFFER(tb->tb_path, h);
+		src_bi->bi_parent = PATH_H_PPARENT(tb->tb_path, h);
+		src_bi->bi_position = PATH_H_POSITION(tb->tb_path, h + 1);
+		dest_bi->tb = tb;
+		dest_bi->bi_bh = tb->L[h];
+		dest_bi->bi_parent = tb->FL[h];
+		dest_bi->bi_position = get_left_neighbor_position(tb, h);
+		*d_key = tb->lkey[h];
+		*cf = tb->CFL[h];
+		break;
+	case INTERNAL_SHIFT_FROM_L_TO_S:
+		src_bi->tb = tb;
+		src_bi->bi_bh = tb->L[h];
+		src_bi->bi_parent = tb->FL[h];
+		src_bi->bi_position = get_left_neighbor_position(tb, h);
+		dest_bi->tb = tb;
+		dest_bi->bi_bh = PATH_H_PBUFFER(tb->tb_path, h);
+		dest_bi->bi_parent = PATH_H_PPARENT(tb->tb_path, h);
+		dest_bi->bi_position = PATH_H_POSITION(tb->tb_path, h + 1);	/* dest position is analog of dest->b_item_order */
+		*d_key = tb->lkey[h];
+		*cf = tb->CFL[h];
+		break;
+
+	case INTERNAL_SHIFT_FROM_R_TO_S:	/* used in internal_shift_left */
+		src_bi->tb = tb;
+		src_bi->bi_bh = tb->R[h];
+		src_bi->bi_parent = tb->FR[h];
+		src_bi->bi_position = get_right_neighbor_position(tb, h);
+		dest_bi->tb = tb;
+		dest_bi->bi_bh = PATH_H_PBUFFER(tb->tb_path, h);
+		dest_bi->bi_parent = PATH_H_PPARENT(tb->tb_path, h);
+		dest_bi->bi_position = PATH_H_POSITION(tb->tb_path, h + 1);
+		*d_key = tb->rkey[h];
+		*cf = tb->CFR[h];
+		break;
+
+	case INTERNAL_SHIFT_FROM_S_TO_R:
+		src_bi->tb = tb;
+		src_bi->bi_bh = PATH_H_PBUFFER(tb->tb_path, h);
+		src_bi->bi_parent = PATH_H_PPARENT(tb->tb_path, h);
+		src_bi->bi_position = PATH_H_POSITION(tb->tb_path, h + 1);
+		dest_bi->tb = tb;
+		dest_bi->bi_bh = tb->R[h];
+		dest_bi->bi_parent = tb->FR[h];
+		dest_bi->bi_position = get_right_neighbor_position(tb, h);
+		*d_key = tb->rkey[h];
+		*cf = tb->CFR[h];
+		break;
+
+	case INTERNAL_INSERT_TO_L:
+		dest_bi->tb = tb;
+		dest_bi->bi_bh = tb->L[h];
+		dest_bi->bi_parent = tb->FL[h];
+		dest_bi->bi_position = get_left_neighbor_position(tb, h);
+		break;
+
+	case INTERNAL_INSERT_TO_S:
+		dest_bi->tb = tb;
+		dest_bi->bi_bh = PATH_H_PBUFFER(tb->tb_path, h);
+		dest_bi->bi_parent = PATH_H_PPARENT(tb->tb_path, h);
+		dest_bi->bi_position = PATH_H_POSITION(tb->tb_path, h + 1);
+		break;
+
+	case INTERNAL_INSERT_TO_R:
+		dest_bi->tb = tb;
+		dest_bi->bi_bh = tb->R[h];
+		dest_bi->bi_parent = tb->FR[h];
+		dest_bi->bi_position = get_right_neighbor_position(tb, h);
+		break;
+
+	default:
+		reiserfs_panic(tb->tb_sb,
+			       "internal_define_dest_src_infos: shift type is unknown (%d)",
+			       shift_mode);
+	}
 }
 
-
-
 /* Insert count node pointers into buffer cur before position to + 1.
  * Insert count items into buffer cur before position to.
  * Items and node pointers are specified by inserted and bh respectively.
- */ 
-static void internal_insert_childs (struct buffer_info * cur_bi,
-				    int to, int count,
-				    struct item_head * inserted,
-				    struct buffer_head ** bh
-    )
+ */
+static void internal_insert_childs(struct buffer_info *cur_bi,
+				   int to, int count,
+				   struct item_head *inserted,
+				   struct buffer_head **bh)
 {
-    struct buffer_head * cur = cur_bi->bi_bh;
-    struct block_head * blkh;
-    int nr;
-    struct reiserfs_key * ih;
-    struct disk_child new_dc[2];
-    struct disk_child * dc;
-    int i;
-
-    if (count <= 0)
-	return;
-
-    blkh = B_BLK_HEAD(cur);
-    nr = blkh_nr_item(blkh);
-
-    RFALSE( count > 2,
-	    "too many children (%d) are to be inserted", count);
-    RFALSE( B_FREE_SPACE (cur) < count * (KEY_SIZE + DC_SIZE),
-	    "no enough free space (%d), needed %d bytes", 
-	    B_FREE_SPACE (cur), count * (KEY_SIZE + DC_SIZE));
-
-    /* prepare space for count disk_child */
-    dc = B_N_CHILD(cur,to+1);
-
-    memmove (dc + count, dc, (nr+1-(to+1)) * DC_SIZE);
-
-    /* copy to_be_insert disk children */
-    for (i = 0; i < count; i ++) {
-	put_dc_size( &(new_dc[i]), MAX_CHILD_SIZE(bh[i]) - B_FREE_SPACE(bh[i]));
-	put_dc_block_number( &(new_dc[i]), bh[i]->b_blocknr );
-    }
-    memcpy (dc, new_dc, DC_SIZE * count);
-
-  
-    /* prepare space for count items  */
-    ih = B_N_PDELIM_KEY (cur, ((to == -1) ? 0 : to));
-
-    memmove (ih + count, ih, (nr - to) * KEY_SIZE + (nr + 1 + count) * DC_SIZE);
-
-    /* copy item headers (keys) */
-    memcpy (ih, inserted, KEY_SIZE);
-    if ( count > 1 )
-	memcpy (ih + 1, inserted + 1, KEY_SIZE);
-
-    /* sizes, item number */
-    set_blkh_nr_item( blkh, blkh_nr_item(blkh) + count );
-    set_blkh_free_space( blkh,
-                        blkh_free_space(blkh) - count * (DC_SIZE + KEY_SIZE ) );
-
-    do_balance_mark_internal_dirty (cur_bi->tb, cur,0);
-
-    /*&&&&&&&&&&&&&&&&&&&&&&&&*/
-    check_internal (cur);
-    /*&&&&&&&&&&&&&&&&&&&&&&&&*/
-
-    if (cur_bi->bi_parent) {
-	struct disk_child *t_dc = B_N_CHILD (cur_bi->bi_parent,cur_bi->bi_position);
-	put_dc_size( t_dc, dc_size(t_dc) + (count * (DC_SIZE + KEY_SIZE)));
-	do_balance_mark_internal_dirty(cur_bi->tb, cur_bi->bi_parent, 0);
-
-	/*&&&&&&&&&&&&&&&&&&&&&&&&*/
-	check_internal (cur_bi->bi_parent);
-	/*&&&&&&&&&&&&&&&&&&&&&&&&*/   
-    }
+	struct buffer_head *cur = cur_bi->bi_bh;
+	struct block_head *blkh;
+	int nr;
+	struct reiserfs_key *ih;
+	struct disk_child new_dc[2];
+	struct disk_child *dc;
+	int i;
+
+	if (count <= 0)
+		return;
+
+	blkh = B_BLK_HEAD(cur);
+	nr = blkh_nr_item(blkh);
+
+	RFALSE(count > 2, "too many children (%d) are to be inserted", count);
+	RFALSE(B_FREE_SPACE(cur) < count * (KEY_SIZE + DC_SIZE),
+	       "no enough free space (%d), needed %d bytes",
+	       B_FREE_SPACE(cur), count * (KEY_SIZE + DC_SIZE));
+
+	/* prepare space for count disk_child */
+	dc = B_N_CHILD(cur, to + 1);
+
+	memmove(dc + count, dc, (nr + 1 - (to + 1)) * DC_SIZE);
+
+	/* copy to_be_insert disk children */
+	for (i = 0; i < count; i++) {
+		put_dc_size(&(new_dc[i]),
+			    MAX_CHILD_SIZE(bh[i]) - B_FREE_SPACE(bh[i]));
+		put_dc_block_number(&(new_dc[i]), bh[i]->b_blocknr);
+	}
+	memcpy(dc, new_dc, DC_SIZE * count);
 
-}
+	/* prepare space for count items  */
+	ih = B_N_PDELIM_KEY(cur, ((to == -1) ? 0 : to));
+
+	memmove(ih + count, ih,
+		(nr - to) * KEY_SIZE + (nr + 1 + count) * DC_SIZE);
 
+	/* copy item headers (keys) */
+	memcpy(ih, inserted, KEY_SIZE);
+	if (count > 1)
+		memcpy(ih + 1, inserted + 1, KEY_SIZE);
+
+	/* sizes, item number */
+	set_blkh_nr_item(blkh, blkh_nr_item(blkh) + count);
+	set_blkh_free_space(blkh,
+			    blkh_free_space(blkh) - count * (DC_SIZE +
+							     KEY_SIZE));
+
+	do_balance_mark_internal_dirty(cur_bi->tb, cur, 0);
+
+	/*&&&&&&&&&&&&&&&&&&&&&&&& */
+	check_internal(cur);
+	/*&&&&&&&&&&&&&&&&&&&&&&&& */
+
+	if (cur_bi->bi_parent) {
+		struct disk_child *t_dc =
+		    B_N_CHILD(cur_bi->bi_parent, cur_bi->bi_position);
+		put_dc_size(t_dc,
+			    dc_size(t_dc) + (count * (DC_SIZE + KEY_SIZE)));
+		do_balance_mark_internal_dirty(cur_bi->tb, cur_bi->bi_parent,
+					       0);
+
+		/*&&&&&&&&&&&&&&&&&&&&&&&& */
+		check_internal(cur_bi->bi_parent);
+		/*&&&&&&&&&&&&&&&&&&&&&&&& */
+	}
+
+}
 
 /* Delete del_num items and node pointers from buffer cur starting from *
  * the first_i'th item and first_p'th pointers respectively.		*/
-static void	internal_delete_pointers_items (
-						struct buffer_info * cur_bi,
-						int first_p, 
-						int first_i, 
-						int del_num
-						)
+static void internal_delete_pointers_items(struct buffer_info *cur_bi,
+					   int first_p,
+					   int first_i, int del_num)
 {
-  struct buffer_head * cur = cur_bi->bi_bh;
-  int nr;
-  struct block_head * blkh;
-  struct reiserfs_key * key;
-  struct disk_child * dc;
-
-  RFALSE( cur == NULL, "buffer is 0");
-  RFALSE( del_num < 0,
-          "negative number of items (%d) can not be deleted", del_num);
-  RFALSE( first_p < 0 || first_p + del_num > B_NR_ITEMS (cur) + 1 || first_i < 0,
-          "first pointer order (%d) < 0 or "
-          "no so many pointers (%d), only (%d) or "
-          "first key order %d < 0", first_p, 
-          first_p + del_num, B_NR_ITEMS (cur) + 1, first_i);
-  if ( del_num == 0 )
-    return;
-
-  blkh = B_BLK_HEAD(cur);
-  nr = blkh_nr_item(blkh);
-
-  if ( first_p == 0 && del_num == nr + 1 ) {
-    RFALSE( first_i != 0, "1st deleted key must have order 0, not %d", first_i);
-    make_empty_node (cur_bi);
-    return;
-  }
-
-  RFALSE( first_i + del_num > B_NR_ITEMS (cur),
-          "first_i = %d del_num = %d "
-          "no so many keys (%d) in the node (%b)(%z)",
-          first_i, del_num, first_i + del_num, cur, cur);
-
-
-  /* deleting */
-  dc = B_N_CHILD (cur, first_p);
-
-  memmove (dc, dc + del_num, (nr + 1 - first_p - del_num) * DC_SIZE);
-  key = B_N_PDELIM_KEY (cur, first_i);
-  memmove (key, key + del_num, (nr - first_i - del_num) * KEY_SIZE + (nr + 1 - del_num) * DC_SIZE);
-
-
-  /* sizes, item number */
-  set_blkh_nr_item( blkh, blkh_nr_item(blkh) - del_num );
-  set_blkh_free_space( blkh,
-                    blkh_free_space(blkh) + (del_num * (KEY_SIZE + DC_SIZE) ) );
-
-  do_balance_mark_internal_dirty (cur_bi->tb, cur, 0);
-  /*&&&&&&&&&&&&&&&&&&&&&&&*/
-  check_internal (cur);
-  /*&&&&&&&&&&&&&&&&&&&&&&&*/
- 
-  if (cur_bi->bi_parent) {
-    struct disk_child *t_dc;
-    t_dc = B_N_CHILD (cur_bi->bi_parent, cur_bi->bi_position);
-    put_dc_size( t_dc, dc_size(t_dc) - (del_num * (KEY_SIZE + DC_SIZE) ) );
-
-    do_balance_mark_internal_dirty (cur_bi->tb, cur_bi->bi_parent,0);
-    /*&&&&&&&&&&&&&&&&&&&&&&&&*/
-    check_internal (cur_bi->bi_parent);
-    /*&&&&&&&&&&&&&&&&&&&&&&&&*/   
-  }
-}
+	struct buffer_head *cur = cur_bi->bi_bh;
+	int nr;
+	struct block_head *blkh;
+	struct reiserfs_key *key;
+	struct disk_child *dc;
+
+	RFALSE(cur == NULL, "buffer is 0");
+	RFALSE(del_num < 0,
+	       "negative number of items (%d) can not be deleted", del_num);
+	RFALSE(first_p < 0 || first_p + del_num > B_NR_ITEMS(cur) + 1
+	       || first_i < 0,
+	       "first pointer order (%d) < 0 or "
+	       "no so many pointers (%d), only (%d) or "
+	       "first key order %d < 0", first_p, first_p + del_num,
+	       B_NR_ITEMS(cur) + 1, first_i);
+	if (del_num == 0)
+		return;
+
+	blkh = B_BLK_HEAD(cur);
+	nr = blkh_nr_item(blkh);
+
+	if (first_p == 0 && del_num == nr + 1) {
+		RFALSE(first_i != 0,
+		       "1st deleted key must have order 0, not %d", first_i);
+		make_empty_node(cur_bi);
+		return;
+	}
 
+	RFALSE(first_i + del_num > B_NR_ITEMS(cur),
+	       "first_i = %d del_num = %d "
+	       "no so many keys (%d) in the node (%b)(%z)",
+	       first_i, del_num, first_i + del_num, cur, cur);
+
+	/* deleting */
+	dc = B_N_CHILD(cur, first_p);
+
+	memmove(dc, dc + del_num, (nr + 1 - first_p - del_num) * DC_SIZE);
+	key = B_N_PDELIM_KEY(cur, first_i);
+	memmove(key, key + del_num,
+		(nr - first_i - del_num) * KEY_SIZE + (nr + 1 -
+						       del_num) * DC_SIZE);
+
+	/* sizes, item number */
+	set_blkh_nr_item(blkh, blkh_nr_item(blkh) - del_num);
+	set_blkh_free_space(blkh,
+			    blkh_free_space(blkh) +
+			    (del_num * (KEY_SIZE + DC_SIZE)));
+
+	do_balance_mark_internal_dirty(cur_bi->tb, cur, 0);
+	/*&&&&&&&&&&&&&&&&&&&&&&& */
+	check_internal(cur);
+	/*&&&&&&&&&&&&&&&&&&&&&&& */
+
+	if (cur_bi->bi_parent) {
+		struct disk_child *t_dc;
+		t_dc = B_N_CHILD(cur_bi->bi_parent, cur_bi->bi_position);
+		put_dc_size(t_dc,
+			    dc_size(t_dc) - (del_num * (KEY_SIZE + DC_SIZE)));
+
+		do_balance_mark_internal_dirty(cur_bi->tb, cur_bi->bi_parent,
+					       0);
+		/*&&&&&&&&&&&&&&&&&&&&&&&& */
+		check_internal(cur_bi->bi_parent);
+		/*&&&&&&&&&&&&&&&&&&&&&&&& */
+	}
+}
 
 /* delete n node pointers and items starting from given position */
-static void  internal_delete_childs (struct buffer_info * cur_bi, 
-				     int from, int n)
+static void internal_delete_childs(struct buffer_info *cur_bi, int from, int n)
 {
-  int i_from;
+	int i_from;
 
-  i_from = (from == 0) ? from : from - 1;
+	i_from = (from == 0) ? from : from - 1;
 
-  /* delete n pointers starting from `from' position in CUR;
-     delete n keys starting from 'i_from' position in CUR;
-     */
-  internal_delete_pointers_items (cur_bi, from, i_from, n);
+	/* delete n pointers starting from `from' position in CUR;
+	   delete n keys starting from 'i_from' position in CUR;
+	 */
+	internal_delete_pointers_items(cur_bi, from, i_from, n);
 }
 
-
 /* copy cpy_num node pointers and cpy_num - 1 items from buffer src to buffer dest
 * last_first == FIRST_TO_LAST means, that we copy first items from src to tail of dest
  * last_first == LAST_TO_FIRST means, that we copy last items from src to head of dest 
  */
-static void internal_copy_pointers_items (
-					  struct buffer_info * dest_bi,
-					  struct buffer_head * src,
-					  int last_first, int cpy_num
-					  )
+static void internal_copy_pointers_items(struct buffer_info *dest_bi,
+					 struct buffer_head *src,
+					 int last_first, int cpy_num)
 {
-  /* ATTENTION! Number of node pointers in DEST is equal to number of items in DEST *
-   * as delimiting key have already inserted to buffer dest.*/
-  struct buffer_head * dest = dest_bi->bi_bh;
-  int nr_dest, nr_src;
-  int dest_order, src_order;
-  struct block_head * blkh;
-  struct reiserfs_key * key;
-  struct disk_child * dc;
-
-  nr_src = B_NR_ITEMS (src);
-
-  RFALSE( dest == NULL || src == NULL, 
-	  "src (%p) or dest (%p) buffer is 0", src, dest);
-  RFALSE( last_first != FIRST_TO_LAST && last_first != LAST_TO_FIRST,
-	  "invalid last_first parameter (%d)", last_first);
-  RFALSE( nr_src < cpy_num - 1, 
-	  "no so many items (%d) in src (%d)", cpy_num, nr_src);
-  RFALSE( cpy_num < 0, "cpy_num less than 0 (%d)", cpy_num);
-  RFALSE( cpy_num - 1 + B_NR_ITEMS(dest) > (int)MAX_NR_KEY(dest),
-	  "cpy_num (%d) + item number in dest (%d) can not be > MAX_NR_KEY(%d)",
-	  cpy_num, B_NR_ITEMS(dest), MAX_NR_KEY(dest));
+	/* ATTENTION! Number of node pointers in DEST is equal to number of items in DEST *
+	 * as delimiting key have already inserted to buffer dest.*/
+	struct buffer_head *dest = dest_bi->bi_bh;
+	int nr_dest, nr_src;
+	int dest_order, src_order;
+	struct block_head *blkh;
+	struct reiserfs_key *key;
+	struct disk_child *dc;
+
+	nr_src = B_NR_ITEMS(src);
+
+	RFALSE(dest == NULL || src == NULL,
+	       "src (%p) or dest (%p) buffer is 0", src, dest);
+	RFALSE(last_first != FIRST_TO_LAST && last_first != LAST_TO_FIRST,
+	       "invalid last_first parameter (%d)", last_first);
+	RFALSE(nr_src < cpy_num - 1,
+	       "no so many items (%d) in src (%d)", cpy_num, nr_src);
+	RFALSE(cpy_num < 0, "cpy_num less than 0 (%d)", cpy_num);
+	RFALSE(cpy_num - 1 + B_NR_ITEMS(dest) > (int)MAX_NR_KEY(dest),
+	       "cpy_num (%d) + item number in dest (%d) can not be > MAX_NR_KEY(%d)",
+	       cpy_num, B_NR_ITEMS(dest), MAX_NR_KEY(dest));
 
-  if ( cpy_num == 0 )
-    return;
+	if (cpy_num == 0)
+		return;
 
 	/* coping */
-  blkh = B_BLK_HEAD(dest);
-  nr_dest = blkh_nr_item(blkh);
+	blkh = B_BLK_HEAD(dest);
+	nr_dest = blkh_nr_item(blkh);
 
-  /*dest_order = (last_first == LAST_TO_FIRST) ? 0 : nr_dest;*/
-  /*src_order = (last_first == LAST_TO_FIRST) ? (nr_src - cpy_num + 1) : 0;*/
-  (last_first == LAST_TO_FIRST) ?	(dest_order = 0, src_order = nr_src - cpy_num + 1) :
-    (dest_order = nr_dest, src_order = 0);
+	/*dest_order = (last_first == LAST_TO_FIRST) ? 0 : nr_dest; */
+	/*src_order = (last_first == LAST_TO_FIRST) ? (nr_src - cpy_num + 1) : 0; */
+	(last_first == LAST_TO_FIRST) ? (dest_order = 0, src_order =
+					 nr_src - cpy_num + 1) : (dest_order =
+								  nr_dest,
+								  src_order =
+								  0);
 
-  /* prepare space for cpy_num pointers */
-  dc = B_N_CHILD (dest, dest_order);
+	/* prepare space for cpy_num pointers */
+	dc = B_N_CHILD(dest, dest_order);
 
-  memmove (dc + cpy_num, dc, (nr_dest - dest_order) * DC_SIZE);
+	memmove(dc + cpy_num, dc, (nr_dest - dest_order) * DC_SIZE);
 
 	/* insert pointers */
-  memcpy (dc, B_N_CHILD (src, src_order), DC_SIZE * cpy_num);
-
-
-  /* prepare space for cpy_num - 1 item headers */
-  key = B_N_PDELIM_KEY(dest, dest_order);
-  memmove (key + cpy_num - 1, key,
-	   KEY_SIZE * (nr_dest - dest_order) + DC_SIZE * (nr_dest + cpy_num));
-
-
-  /* insert headers */
-  memcpy (key, B_N_PDELIM_KEY (src, src_order), KEY_SIZE * (cpy_num - 1));
-
-  /* sizes, item number */
-  set_blkh_nr_item( blkh, blkh_nr_item(blkh) + (cpy_num - 1 ) );
-  set_blkh_free_space( blkh,
-      blkh_free_space(blkh) - (KEY_SIZE * (cpy_num - 1) + DC_SIZE * cpy_num ) );
+	memcpy(dc, B_N_CHILD(src, src_order), DC_SIZE * cpy_num);
 
-  do_balance_mark_internal_dirty (dest_bi->tb, dest, 0);
-
-  /*&&&&&&&&&&&&&&&&&&&&&&&&*/
-  check_internal (dest);
-  /*&&&&&&&&&&&&&&&&&&&&&&&&*/
-
-  if (dest_bi->bi_parent) {
-    struct disk_child *t_dc;
-    t_dc = B_N_CHILD(dest_bi->bi_parent,dest_bi->bi_position);
-    put_dc_size( t_dc, dc_size(t_dc) + (KEY_SIZE * (cpy_num - 1) + DC_SIZE * cpy_num) );
-
-    do_balance_mark_internal_dirty (dest_bi->tb, dest_bi->bi_parent,0);
-    /*&&&&&&&&&&&&&&&&&&&&&&&&*/
-    check_internal (dest_bi->bi_parent);
-    /*&&&&&&&&&&&&&&&&&&&&&&&&*/   
-  }
+	/* prepare space for cpy_num - 1 item headers */
+	key = B_N_PDELIM_KEY(dest, dest_order);
+	memmove(key + cpy_num - 1, key,
+		KEY_SIZE * (nr_dest - dest_order) + DC_SIZE * (nr_dest +
+							       cpy_num));
+
+	/* insert headers */
+	memcpy(key, B_N_PDELIM_KEY(src, src_order), KEY_SIZE * (cpy_num - 1));
+
+	/* sizes, item number */
+	set_blkh_nr_item(blkh, blkh_nr_item(blkh) + (cpy_num - 1));
+	set_blkh_free_space(blkh,
+			    blkh_free_space(blkh) - (KEY_SIZE * (cpy_num - 1) +
+						     DC_SIZE * cpy_num));
+
+	do_balance_mark_internal_dirty(dest_bi->tb, dest, 0);
+
+	/*&&&&&&&&&&&&&&&&&&&&&&&& */
+	check_internal(dest);
+	/*&&&&&&&&&&&&&&&&&&&&&&&& */
+
+	if (dest_bi->bi_parent) {
+		struct disk_child *t_dc;
+		t_dc = B_N_CHILD(dest_bi->bi_parent, dest_bi->bi_position);
+		put_dc_size(t_dc,
+			    dc_size(t_dc) + (KEY_SIZE * (cpy_num - 1) +
+					     DC_SIZE * cpy_num));
+
+		do_balance_mark_internal_dirty(dest_bi->tb, dest_bi->bi_parent,
+					       0);
+		/*&&&&&&&&&&&&&&&&&&&&&&&& */
+		check_internal(dest_bi->bi_parent);
+		/*&&&&&&&&&&&&&&&&&&&&&&&& */
+	}
 
 }
 
-
 /* Copy cpy_num node pointers and cpy_num - 1 items from buffer src to buffer dest.
  * Delete cpy_num - del_par items and node pointers from buffer src.
  * last_first == FIRST_TO_LAST means, that we copy/delete first items from src.
  * last_first == LAST_TO_FIRST means, that we copy/delete last items from src.
  */
-static void internal_move_pointers_items (struct buffer_info * dest_bi, 
-					  struct buffer_info * src_bi, 
-					  int last_first, int cpy_num, int del_par)
+static void internal_move_pointers_items(struct buffer_info *dest_bi,
+					 struct buffer_info *src_bi,
+					 int last_first, int cpy_num,
+					 int del_par)
 {
-    int first_pointer;
-    int first_item;
-    
-    internal_copy_pointers_items (dest_bi, src_bi->bi_bh, last_first, cpy_num);
-
-    if (last_first == FIRST_TO_LAST) {	/* shift_left occurs */
-	first_pointer = 0;
-	first_item = 0;
-	/* delete cpy_num - del_par pointers and keys starting for pointers with first_pointer, 
-	   for key - with first_item */
-	internal_delete_pointers_items (src_bi, first_pointer, first_item, cpy_num - del_par);
-    } else {			/* shift_right occurs */
-	int i, j;
+	int first_pointer;
+	int first_item;
 
-	i = ( cpy_num - del_par == ( j = B_NR_ITEMS(src_bi->bi_bh)) + 1 ) ? 0 : j - cpy_num + del_par;
+	internal_copy_pointers_items(dest_bi, src_bi->bi_bh, last_first,
+				     cpy_num);
 
-	internal_delete_pointers_items (src_bi, j + 1 - cpy_num + del_par, i, cpy_num - del_par);
-    }
+	if (last_first == FIRST_TO_LAST) {	/* shift_left occurs */
+		first_pointer = 0;
+		first_item = 0;
+		/* delete cpy_num - del_par pointers and keys starting for pointers with first_pointer, 
+		   for key - with first_item */
+		internal_delete_pointers_items(src_bi, first_pointer,
+					       first_item, cpy_num - del_par);
+	} else {		/* shift_right occurs */
+		int i, j;
+
+		i = (cpy_num - del_par ==
+		     (j =
+		      B_NR_ITEMS(src_bi->bi_bh)) + 1) ? 0 : j - cpy_num +
+		    del_par;
+
+		internal_delete_pointers_items(src_bi,
+					       j + 1 - cpy_num + del_par, i,
+					       cpy_num - del_par);
+	}
 }
 
 /* Insert n_src'th key of buffer src before n_dest'th key of buffer dest. */
-static void internal_insert_key (struct buffer_info * dest_bi, 
-				 int dest_position_before,                 /* insert key before key with n_dest number */
-				 struct buffer_head * src, 
-				 int src_position)
+static void internal_insert_key(struct buffer_info *dest_bi, int dest_position_before,	/* insert key before key with n_dest number */
+				struct buffer_head *src, int src_position)
 {
-    struct buffer_head * dest = dest_bi->bi_bh;
-    int nr;
-    struct block_head * blkh;
-    struct reiserfs_key * key;
-
-    RFALSE( dest == NULL || src == NULL,
-	    "source(%p) or dest(%p) buffer is 0", src, dest);
-    RFALSE( dest_position_before < 0 || src_position < 0,
-	    "source(%d) or dest(%d) key number less than 0", 
-	    src_position, dest_position_before);
-    RFALSE( dest_position_before > B_NR_ITEMS (dest) || 
-	    src_position >= B_NR_ITEMS(src),
-	    "invalid position in dest (%d (key number %d)) or in src (%d (key number %d))",
-	    dest_position_before, B_NR_ITEMS (dest), 
-	    src_position, B_NR_ITEMS(src));
-    RFALSE( B_FREE_SPACE (dest) < KEY_SIZE,
-	    "no enough free space (%d) in dest buffer", B_FREE_SPACE (dest));
-
-    blkh = B_BLK_HEAD(dest);
-    nr = blkh_nr_item(blkh);
-
-    /* prepare space for inserting key */
-    key = B_N_PDELIM_KEY (dest, dest_position_before);
-    memmove (key + 1, key, (nr - dest_position_before) * KEY_SIZE + (nr + 1) * DC_SIZE);
-
-    /* insert key */
-    memcpy (key, B_N_PDELIM_KEY(src, src_position), KEY_SIZE);
-
-    /* Change dirt, free space, item number fields. */
-
-    set_blkh_nr_item( blkh, blkh_nr_item(blkh) + 1 );
-    set_blkh_free_space( blkh, blkh_free_space(blkh) - KEY_SIZE );
-
-    do_balance_mark_internal_dirty (dest_bi->tb, dest, 0);
-
-    if (dest_bi->bi_parent) {
-	struct disk_child *t_dc;
-	t_dc = B_N_CHILD(dest_bi->bi_parent,dest_bi->bi_position);
-	put_dc_size( t_dc, dc_size(t_dc) + KEY_SIZE );
+	struct buffer_head *dest = dest_bi->bi_bh;
+	int nr;
+	struct block_head *blkh;
+	struct reiserfs_key *key;
+
+	RFALSE(dest == NULL || src == NULL,
+	       "source(%p) or dest(%p) buffer is 0", src, dest);
+	RFALSE(dest_position_before < 0 || src_position < 0,
+	       "source(%d) or dest(%d) key number less than 0",
+	       src_position, dest_position_before);
+	RFALSE(dest_position_before > B_NR_ITEMS(dest) ||
+	       src_position >= B_NR_ITEMS(src),
+	       "invalid position in dest (%d (key number %d)) or in src (%d (key number %d))",
+	       dest_position_before, B_NR_ITEMS(dest),
+	       src_position, B_NR_ITEMS(src));
+	RFALSE(B_FREE_SPACE(dest) < KEY_SIZE,
+	       "no enough free space (%d) in dest buffer", B_FREE_SPACE(dest));
+
+	blkh = B_BLK_HEAD(dest);
+	nr = blkh_nr_item(blkh);
+
+	/* prepare space for inserting key */
+	key = B_N_PDELIM_KEY(dest, dest_position_before);
+	memmove(key + 1, key,
+		(nr - dest_position_before) * KEY_SIZE + (nr + 1) * DC_SIZE);
+
+	/* insert key */
+	memcpy(key, B_N_PDELIM_KEY(src, src_position), KEY_SIZE);
+
+	/* Change dirt, free space, item number fields. */
+
+	set_blkh_nr_item(blkh, blkh_nr_item(blkh) + 1);
+	set_blkh_free_space(blkh, blkh_free_space(blkh) - KEY_SIZE);
+
+	do_balance_mark_internal_dirty(dest_bi->tb, dest, 0);
+
+	if (dest_bi->bi_parent) {
+		struct disk_child *t_dc;
+		t_dc = B_N_CHILD(dest_bi->bi_parent, dest_bi->bi_position);
+		put_dc_size(t_dc, dc_size(t_dc) + KEY_SIZE);
 
-	do_balance_mark_internal_dirty (dest_bi->tb, dest_bi->bi_parent,0);
-    }
+		do_balance_mark_internal_dirty(dest_bi->tb, dest_bi->bi_parent,
+					       0);
+	}
 }
 
-
-
 /* Insert d_key'th (delimiting) key from buffer cfl to tail of dest. 
  * Copy pointer_amount node pointers and pointer_amount - 1 items from buffer src to buffer dest.
  * Replace  d_key'th key in buffer cfl.
  * Delete pointer_amount items and node pointers from buffer src.
  */
 /* this can be invoked both to shift from S to L and from R to S */
-static void	internal_shift_left (
-				     int mode,	/* INTERNAL_FROM_S_TO_L | INTERNAL_FROM_R_TO_S */
-				     struct tree_balance * tb,
-				     int h,
-				     int pointer_amount
-				     )
+static void internal_shift_left(int mode,	/* INTERNAL_FROM_S_TO_L | INTERNAL_FROM_R_TO_S */
+				struct tree_balance *tb,
+				int h, int pointer_amount)
 {
-  struct buffer_info dest_bi, src_bi;
-  struct buffer_head * cf;
-  int d_key_position;
-
-  internal_define_dest_src_infos (mode, tb, h, &dest_bi, &src_bi, &d_key_position, &cf);
-
-  /*printk("pointer_amount = %d\n",pointer_amount);*/
-
-  if (pointer_amount) {
-    /* insert delimiting key from common father of dest and src to node dest into position B_NR_ITEM(dest) */
-    internal_insert_key (&dest_bi, B_NR_ITEMS(dest_bi.bi_bh), cf, d_key_position);
-
-    if (B_NR_ITEMS(src_bi.bi_bh) == pointer_amount - 1) {
-      if (src_bi.bi_position/*src->b_item_order*/ == 0)
-	replace_key (tb, cf, d_key_position, src_bi.bi_parent/*src->b_parent*/, 0);
-    } else
-      replace_key (tb, cf, d_key_position, src_bi.bi_bh, pointer_amount - 1);
-  }
-  /* last parameter is del_parameter */
-  internal_move_pointers_items (&dest_bi, &src_bi, FIRST_TO_LAST, pointer_amount, 0);
+	struct buffer_info dest_bi, src_bi;
+	struct buffer_head *cf;
+	int d_key_position;
+
+	internal_define_dest_src_infos(mode, tb, h, &dest_bi, &src_bi,
+				       &d_key_position, &cf);
+
+	/*printk("pointer_amount = %d\n",pointer_amount); */
+
+	if (pointer_amount) {
+		/* insert delimiting key from common father of dest and src to node dest into position B_NR_ITEM(dest) */
+		internal_insert_key(&dest_bi, B_NR_ITEMS(dest_bi.bi_bh), cf,
+				    d_key_position);
+
+		if (B_NR_ITEMS(src_bi.bi_bh) == pointer_amount - 1) {
+			if (src_bi.bi_position /*src->b_item_order */  == 0)
+				replace_key(tb, cf, d_key_position,
+					    src_bi.
+					    bi_parent /*src->b_parent */ , 0);
+		} else
+			replace_key(tb, cf, d_key_position, src_bi.bi_bh,
+				    pointer_amount - 1);
+	}
+	/* last parameter is del_parameter */
+	internal_move_pointers_items(&dest_bi, &src_bi, FIRST_TO_LAST,
+				     pointer_amount, 0);
 
 }
 
@@ -493,67 +498,66 @@ static void	internal_shift_left (
  * Delete n - 1 items and node pointers from buffer S[h].
  */
 /* it always shifts from S[h] to L[h] */
-static void	internal_shift1_left (
-				      struct tree_balance * tb, 
-				      int h, 
-				      int pointer_amount
-				      )
+static void internal_shift1_left(struct tree_balance *tb,
+				 int h, int pointer_amount)
 {
-  struct buffer_info dest_bi, src_bi;
-  struct buffer_head * cf;
-  int d_key_position;
-
-  internal_define_dest_src_infos (INTERNAL_SHIFT_FROM_S_TO_L, tb, h, &dest_bi, &src_bi, &d_key_position, &cf);
-
-  if ( pointer_amount > 0 ) /* insert lkey[h]-th key  from CFL[h] to left neighbor L[h] */
-    internal_insert_key (&dest_bi, B_NR_ITEMS(dest_bi.bi_bh), cf, d_key_position);
-  /*		internal_insert_key (tb->L[h], B_NR_ITEM(tb->L[h]), tb->CFL[h], tb->lkey[h]);*/
-
-  /* last parameter is del_parameter */
-  internal_move_pointers_items (&dest_bi, &src_bi, FIRST_TO_LAST, pointer_amount, 1);
-  /*	internal_move_pointers_items (tb->L[h], tb->S[h], FIRST_TO_LAST, pointer_amount, 1);*/
-}
+	struct buffer_info dest_bi, src_bi;
+	struct buffer_head *cf;
+	int d_key_position;
 
+	internal_define_dest_src_infos(INTERNAL_SHIFT_FROM_S_TO_L, tb, h,
+				       &dest_bi, &src_bi, &d_key_position, &cf);
+
+	if (pointer_amount > 0)	/* insert lkey[h]-th key  from CFL[h] to left neighbor L[h] */
+		internal_insert_key(&dest_bi, B_NR_ITEMS(dest_bi.bi_bh), cf,
+				    d_key_position);
+	/*            internal_insert_key (tb->L[h], B_NR_ITEM(tb->L[h]), tb->CFL[h], tb->lkey[h]); */
+
+	/* last parameter is del_parameter */
+	internal_move_pointers_items(&dest_bi, &src_bi, FIRST_TO_LAST,
+				     pointer_amount, 1);
+	/*    internal_move_pointers_items (tb->L[h], tb->S[h], FIRST_TO_LAST, pointer_amount, 1); */
+}
 
 /* Insert d_key'th (delimiting) key from buffer cfr to head of dest. 
  * Copy n node pointers and n - 1 items from buffer src to buffer dest.
  * Replace  d_key'th key in buffer cfr.
  * Delete n items and node pointers from buffer src.
  */
-static void internal_shift_right (
-				  int mode,	/* INTERNAL_FROM_S_TO_R | INTERNAL_FROM_L_TO_S */
-				  struct tree_balance * tb,
-				  int h,
-				  int pointer_amount
-				  )
+static void internal_shift_right(int mode,	/* INTERNAL_FROM_S_TO_R | INTERNAL_FROM_L_TO_S */
+				 struct tree_balance *tb,
+				 int h, int pointer_amount)
 {
-  struct buffer_info dest_bi, src_bi;
-  struct buffer_head * cf;
-  int d_key_position;
-  int nr;
-
-
-  internal_define_dest_src_infos (mode, tb, h, &dest_bi, &src_bi, &d_key_position, &cf);
-
-  nr = B_NR_ITEMS (src_bi.bi_bh);
-
-  if (pointer_amount > 0) {
-    /* insert delimiting key from common father of dest and src to dest node into position 0 */
-    internal_insert_key (&dest_bi, 0, cf, d_key_position);
-    if (nr == pointer_amount - 1) {
-	 RFALSE( src_bi.bi_bh != PATH_H_PBUFFER (tb->tb_path, h)/*tb->S[h]*/ || 
-		 dest_bi.bi_bh != tb->R[h],
-		 "src (%p) must be == tb->S[h](%p) when it disappears",
-		 src_bi.bi_bh, PATH_H_PBUFFER (tb->tb_path, h));
-      /* when S[h] disappers replace left delemiting key as well */
-      if (tb->CFL[h])
-	replace_key (tb, cf, d_key_position, tb->CFL[h], tb->lkey[h]);
-    } else
-      replace_key (tb, cf, d_key_position, src_bi.bi_bh, nr - pointer_amount);
-  }      
+	struct buffer_info dest_bi, src_bi;
+	struct buffer_head *cf;
+	int d_key_position;
+	int nr;
+
+	internal_define_dest_src_infos(mode, tb, h, &dest_bi, &src_bi,
+				       &d_key_position, &cf);
+
+	nr = B_NR_ITEMS(src_bi.bi_bh);
+
+	if (pointer_amount > 0) {
+		/* insert delimiting key from common father of dest and src to dest node into position 0 */
+		internal_insert_key(&dest_bi, 0, cf, d_key_position);
+		if (nr == pointer_amount - 1) {
+			RFALSE(src_bi.bi_bh != PATH_H_PBUFFER(tb->tb_path, h) /*tb->S[h] */ ||
+			       dest_bi.bi_bh != tb->R[h],
+			       "src (%p) must be == tb->S[h](%p) when it disappears",
+			       src_bi.bi_bh, PATH_H_PBUFFER(tb->tb_path, h));
+			/* when S[h] disappers replace left delemiting key as well */
+			if (tb->CFL[h])
+				replace_key(tb, cf, d_key_position, tb->CFL[h],
+					    tb->lkey[h]);
+		} else
+			replace_key(tb, cf, d_key_position, src_bi.bi_bh,
+				    nr - pointer_amount);
+	}
 
-  /* last parameter is del_parameter */
-  internal_move_pointers_items (&dest_bi, &src_bi, LAST_TO_FIRST, pointer_amount, 0);
+	/* last parameter is del_parameter */
+	internal_move_pointers_items(&dest_bi, &src_bi, LAST_TO_FIRST,
+				     pointer_amount, 0);
 }
 
 /* Insert delimiting key to R[h].
@@ -561,498 +565,526 @@ static void internal_shift_right (
  * Delete n - 1 items and node pointers from buffer S[h].
  */
 /* it always shift from S[h] to R[h] */
-static void	internal_shift1_right (
-				       struct tree_balance * tb, 
-				       int h, 
-				       int pointer_amount
-				       )
+static void internal_shift1_right(struct tree_balance *tb,
+				  int h, int pointer_amount)
 {
-  struct buffer_info dest_bi, src_bi;
-  struct buffer_head * cf;
-  int d_key_position;
-
-  internal_define_dest_src_infos (INTERNAL_SHIFT_FROM_S_TO_R, tb, h, &dest_bi, &src_bi, &d_key_position, &cf);
-
-  if (pointer_amount > 0) /* insert rkey from CFR[h] to right neighbor R[h] */
-    internal_insert_key (&dest_bi, 0, cf, d_key_position);
-  /*		internal_insert_key (tb->R[h], 0, tb->CFR[h], tb->rkey[h]);*/
-	
-  /* last parameter is del_parameter */
-  internal_move_pointers_items (&dest_bi, &src_bi, LAST_TO_FIRST, pointer_amount, 1);
-  /*	internal_move_pointers_items (tb->R[h], tb->S[h], LAST_TO_FIRST, pointer_amount, 1);*/
-}
+	struct buffer_info dest_bi, src_bi;
+	struct buffer_head *cf;
+	int d_key_position;
+
+	internal_define_dest_src_infos(INTERNAL_SHIFT_FROM_S_TO_R, tb, h,
+				       &dest_bi, &src_bi, &d_key_position, &cf);
 
+	if (pointer_amount > 0)	/* insert rkey from CFR[h] to right neighbor R[h] */
+		internal_insert_key(&dest_bi, 0, cf, d_key_position);
+	/*            internal_insert_key (tb->R[h], 0, tb->CFR[h], tb->rkey[h]); */
+
+	/* last parameter is del_parameter */
+	internal_move_pointers_items(&dest_bi, &src_bi, LAST_TO_FIRST,
+				     pointer_amount, 1);
+	/*    internal_move_pointers_items (tb->R[h], tb->S[h], LAST_TO_FIRST, pointer_amount, 1); */
+}
 
 /* Delete insert_num node pointers together with their left items
  * and balance current node.*/
-static void balance_internal_when_delete (struct tree_balance * tb, 
-					  int h, int child_pos)
+static void balance_internal_when_delete(struct tree_balance *tb,
+					 int h, int child_pos)
 {
-    int insert_num;
-    int n;
-    struct buffer_head * tbSh = PATH_H_PBUFFER (tb->tb_path, h);
-    struct buffer_info bi;
-
-    insert_num = tb->insert_size[h] / ((int)(DC_SIZE + KEY_SIZE));
-  
-    /* delete child-node-pointer(s) together with their left item(s) */
-    bi.tb = tb;
-    bi.bi_bh = tbSh;
-    bi.bi_parent = PATH_H_PPARENT (tb->tb_path, h);
-    bi.bi_position = PATH_H_POSITION (tb->tb_path, h + 1);
-
-    internal_delete_childs (&bi, child_pos, -insert_num);
-
-    RFALSE( tb->blknum[h] > 1,
-	    "tb->blknum[%d]=%d when insert_size < 0", h, tb->blknum[h]);
-
-    n = B_NR_ITEMS(tbSh);
-
-    if ( tb->lnum[h] == 0 && tb->rnum[h] == 0 ) {
-	if ( tb->blknum[h] == 0 ) {
-	    /* node S[h] (root of the tree) is empty now */
-	    struct buffer_head *new_root;
-
-	    RFALSE( n || B_FREE_SPACE (tbSh) != MAX_CHILD_SIZE(tbSh) - DC_SIZE,
-		    "buffer must have only 0 keys (%d)", n);
-	    RFALSE( bi.bi_parent, "root has parent (%p)", bi.bi_parent);
-		
-	    /* choose a new root */
-	    if ( ! tb->L[h-1] || ! B_NR_ITEMS(tb->L[h-1]) )
-		new_root = tb->R[h-1];
-	    else
-		new_root = tb->L[h-1];
-	    /* switch super block's tree root block number to the new value */
-            PUT_SB_ROOT_BLOCK( tb->tb_sb, new_root->b_blocknr );
-	    //REISERFS_SB(tb->tb_sb)->s_rs->s_tree_height --;
-            PUT_SB_TREE_HEIGHT( tb->tb_sb, SB_TREE_HEIGHT(tb->tb_sb) - 1 );
-
-	    do_balance_mark_sb_dirty (tb, REISERFS_SB(tb->tb_sb)->s_sbh, 1);
-	    /*&&&&&&&&&&&&&&&&&&&&&&*/
-	    if (h > 1)
-		/* use check_internal if new root is an internal node */
-		check_internal (new_root);
-	    /*&&&&&&&&&&&&&&&&&&&&&&*/
-
-	    /* do what is needed for buffer thrown from tree */
-	    reiserfs_invalidate_buffer(tb, tbSh);
-	    return;
-	}
-	return;
-    }
-
-    if ( tb->L[h] && tb->lnum[h] == -B_NR_ITEMS(tb->L[h]) - 1 ) { /* join S[h] with L[h] */
-
-	RFALSE( tb->rnum[h] != 0,
-		"invalid tb->rnum[%d]==%d when joining S[h] with L[h]",
-		h, tb->rnum[h]);
-
-	internal_shift_left (INTERNAL_SHIFT_FROM_S_TO_L, tb, h, n + 1);
-	reiserfs_invalidate_buffer(tb, tbSh);
-
-	return;
-    }
-
-    if ( tb->R[h] &&  tb->rnum[h] == -B_NR_ITEMS(tb->R[h]) - 1 ) { /* join S[h] with R[h] */
-	RFALSE( tb->lnum[h] != 0,
-		"invalid tb->lnum[%d]==%d when joining S[h] with R[h]",
-		h, tb->lnum[h]);
-
-	internal_shift_right (INTERNAL_SHIFT_FROM_S_TO_R, tb, h, n + 1);
-
-	reiserfs_invalidate_buffer(tb,tbSh);
-	return;
-    }
-
-    if ( tb->lnum[h] < 0 ) { /* borrow from left neighbor L[h] */
-	RFALSE( tb->rnum[h] != 0,
-		"wrong tb->rnum[%d]==%d when borrow from L[h]", h, tb->rnum[h]);
-	/*internal_shift_right (tb, h, tb->L[h], tb->CFL[h], tb->lkey[h], tb->S[h], -tb->lnum[h]);*/
-	internal_shift_right (INTERNAL_SHIFT_FROM_L_TO_S, tb, h, -tb->lnum[h]);
-	return;
-    }
-
-    if ( tb->rnum[h] < 0 ) { /* borrow from right neighbor R[h] */
-	 RFALSE( tb->lnum[h] != 0,
-		 "invalid tb->lnum[%d]==%d when borrow from R[h]", 
-		 h, tb->lnum[h]);
-	internal_shift_left (INTERNAL_SHIFT_FROM_R_TO_S, tb, h, -tb->rnum[h]);/*tb->S[h], tb->CFR[h], tb->rkey[h], tb->R[h], -tb->rnum[h]);*/
-	return;
-    }
-
-    if ( tb->lnum[h] > 0 ) { /* split S[h] into two parts and put them into neighbors */
-	RFALSE( tb->rnum[h] == 0 || tb->lnum[h] + tb->rnum[h] != n + 1,
-		"invalid tb->lnum[%d]==%d or tb->rnum[%d]==%d when S[h](item number == %d) is split between them",
-		h, tb->lnum[h], h, tb->rnum[h], n);
-
-	internal_shift_left (INTERNAL_SHIFT_FROM_S_TO_L, tb, h, tb->lnum[h]);/*tb->L[h], tb->CFL[h], tb->lkey[h], tb->S[h], tb->lnum[h]);*/
-	internal_shift_right (INTERNAL_SHIFT_FROM_S_TO_R, tb, h, tb->rnum[h]);
-
-	reiserfs_invalidate_buffer (tb, tbSh);
-
-	return;
-    }
-    reiserfs_panic (tb->tb_sb, "balance_internal_when_delete: unexpected tb->lnum[%d]==%d or tb->rnum[%d]==%d",
-		    h, tb->lnum[h], h, tb->rnum[h]);
-}
+	int insert_num;
+	int n;
+	struct buffer_head *tbSh = PATH_H_PBUFFER(tb->tb_path, h);
+	struct buffer_info bi;
+
+	insert_num = tb->insert_size[h] / ((int)(DC_SIZE + KEY_SIZE));
+
+	/* delete child-node-pointer(s) together with their left item(s) */
+	bi.tb = tb;
+	bi.bi_bh = tbSh;
+	bi.bi_parent = PATH_H_PPARENT(tb->tb_path, h);
+	bi.bi_position = PATH_H_POSITION(tb->tb_path, h + 1);
+
+	internal_delete_childs(&bi, child_pos, -insert_num);
+
+	RFALSE(tb->blknum[h] > 1,
+	       "tb->blknum[%d]=%d when insert_size < 0", h, tb->blknum[h]);
+
+	n = B_NR_ITEMS(tbSh);
+
+	if (tb->lnum[h] == 0 && tb->rnum[h] == 0) {
+		if (tb->blknum[h] == 0) {
+			/* node S[h] (root of the tree) is empty now */
+			struct buffer_head *new_root;
+
+			RFALSE(n
+			       || B_FREE_SPACE(tbSh) !=
+			       MAX_CHILD_SIZE(tbSh) - DC_SIZE,
+			       "buffer must have only 0 keys (%d)", n);
+			RFALSE(bi.bi_parent, "root has parent (%p)",
+			       bi.bi_parent);
+
+			/* choose a new root */
+			if (!tb->L[h - 1] || !B_NR_ITEMS(tb->L[h - 1]))
+				new_root = tb->R[h - 1];
+			else
+				new_root = tb->L[h - 1];
+			/* switch super block's tree root block number to the new value */
+			PUT_SB_ROOT_BLOCK(tb->tb_sb, new_root->b_blocknr);
+			//REISERFS_SB(tb->tb_sb)->s_rs->s_tree_height --;
+			PUT_SB_TREE_HEIGHT(tb->tb_sb,
+					   SB_TREE_HEIGHT(tb->tb_sb) - 1);
+
+			do_balance_mark_sb_dirty(tb,
+						 REISERFS_SB(tb->tb_sb)->s_sbh,
+						 1);
+			/*&&&&&&&&&&&&&&&&&&&&&& */
+			if (h > 1)
+				/* use check_internal if new root is an internal node */
+				check_internal(new_root);
+			/*&&&&&&&&&&&&&&&&&&&&&& */
+
+			/* do what is needed for buffer thrown from tree */
+			reiserfs_invalidate_buffer(tb, tbSh);
+			return;
+		}
+		return;
+	}
+
+	if (tb->L[h] && tb->lnum[h] == -B_NR_ITEMS(tb->L[h]) - 1) {	/* join S[h] with L[h] */
+
+		RFALSE(tb->rnum[h] != 0,
+		       "invalid tb->rnum[%d]==%d when joining S[h] with L[h]",
+		       h, tb->rnum[h]);
+
+		internal_shift_left(INTERNAL_SHIFT_FROM_S_TO_L, tb, h, n + 1);
+		reiserfs_invalidate_buffer(tb, tbSh);
+
+		return;
+	}
+
+	if (tb->R[h] && tb->rnum[h] == -B_NR_ITEMS(tb->R[h]) - 1) {	/* join S[h] with R[h] */
+		RFALSE(tb->lnum[h] != 0,
+		       "invalid tb->lnum[%d]==%d when joining S[h] with R[h]",
+		       h, tb->lnum[h]);
 
+		internal_shift_right(INTERNAL_SHIFT_FROM_S_TO_R, tb, h, n + 1);
+
+		reiserfs_invalidate_buffer(tb, tbSh);
+		return;
+	}
+
+	if (tb->lnum[h] < 0) {	/* borrow from left neighbor L[h] */
+		RFALSE(tb->rnum[h] != 0,
+		       "wrong tb->rnum[%d]==%d when borrow from L[h]", h,
+		       tb->rnum[h]);
+		/*internal_shift_right (tb, h, tb->L[h], tb->CFL[h], tb->lkey[h], tb->S[h], -tb->lnum[h]); */
+		internal_shift_right(INTERNAL_SHIFT_FROM_L_TO_S, tb, h,
+				     -tb->lnum[h]);
+		return;
+	}
+
+	if (tb->rnum[h] < 0) {	/* borrow from right neighbor R[h] */
+		RFALSE(tb->lnum[h] != 0,
+		       "invalid tb->lnum[%d]==%d when borrow from R[h]",
+		       h, tb->lnum[h]);
+		internal_shift_left(INTERNAL_SHIFT_FROM_R_TO_S, tb, h, -tb->rnum[h]);	/*tb->S[h], tb->CFR[h], tb->rkey[h], tb->R[h], -tb->rnum[h]); */
+		return;
+	}
+
+	if (tb->lnum[h] > 0) {	/* split S[h] into two parts and put them into neighbors */
+		RFALSE(tb->rnum[h] == 0 || tb->lnum[h] + tb->rnum[h] != n + 1,
+		       "invalid tb->lnum[%d]==%d or tb->rnum[%d]==%d when S[h](item number == %d) is split between them",
+		       h, tb->lnum[h], h, tb->rnum[h], n);
+
+		internal_shift_left(INTERNAL_SHIFT_FROM_S_TO_L, tb, h, tb->lnum[h]);	/*tb->L[h], tb->CFL[h], tb->lkey[h], tb->S[h], tb->lnum[h]); */
+		internal_shift_right(INTERNAL_SHIFT_FROM_S_TO_R, tb, h,
+				     tb->rnum[h]);
+
+		reiserfs_invalidate_buffer(tb, tbSh);
+
+		return;
+	}
+	reiserfs_panic(tb->tb_sb,
+		       "balance_internal_when_delete: unexpected tb->lnum[%d]==%d or tb->rnum[%d]==%d",
+		       h, tb->lnum[h], h, tb->rnum[h]);
+}
 
 /* Replace delimiting key of buffers L[h] and S[h] by the given key.*/
-static void replace_lkey (
-		      struct tree_balance * tb,
-		      int h,
-		      struct item_head * key
-		      )
+static void replace_lkey(struct tree_balance *tb, int h, struct item_head *key)
 {
-   RFALSE( tb->L[h] == NULL || tb->CFL[h] == NULL,
-	   "L[h](%p) and CFL[h](%p) must exist in replace_lkey", 
-	   tb->L[h], tb->CFL[h]);
+	RFALSE(tb->L[h] == NULL || tb->CFL[h] == NULL,
+	       "L[h](%p) and CFL[h](%p) must exist in replace_lkey",
+	       tb->L[h], tb->CFL[h]);
 
-  if (B_NR_ITEMS(PATH_H_PBUFFER(tb->tb_path, h)) == 0)
-    return;
+	if (B_NR_ITEMS(PATH_H_PBUFFER(tb->tb_path, h)) == 0)
+		return;
 
-  memcpy (B_N_PDELIM_KEY(tb->CFL[h],tb->lkey[h]), key, KEY_SIZE);
+	memcpy(B_N_PDELIM_KEY(tb->CFL[h], tb->lkey[h]), key, KEY_SIZE);
 
-  do_balance_mark_internal_dirty (tb, tb->CFL[h],0);
+	do_balance_mark_internal_dirty(tb, tb->CFL[h], 0);
 }
 
-
 /* Replace delimiting key of buffers S[h] and R[h] by the given key.*/
-static void replace_rkey (
-		      struct tree_balance * tb,
-		      int h,
-		      struct item_head * key
-		      )
+static void replace_rkey(struct tree_balance *tb, int h, struct item_head *key)
 {
-  RFALSE( tb->R[h] == NULL || tb->CFR[h] == NULL,
-	  "R[h](%p) and CFR[h](%p) must exist in replace_rkey", 
-	  tb->R[h], tb->CFR[h]);
-  RFALSE( B_NR_ITEMS(tb->R[h]) == 0,
-	  "R[h] can not be empty if it exists (item number=%d)", 
-	  B_NR_ITEMS(tb->R[h]));
+	RFALSE(tb->R[h] == NULL || tb->CFR[h] == NULL,
+	       "R[h](%p) and CFR[h](%p) must exist in replace_rkey",
+	       tb->R[h], tb->CFR[h]);
+	RFALSE(B_NR_ITEMS(tb->R[h]) == 0,
+	       "R[h] can not be empty if it exists (item number=%d)",
+	       B_NR_ITEMS(tb->R[h]));
 
-  memcpy (B_N_PDELIM_KEY(tb->CFR[h],tb->rkey[h]), key, KEY_SIZE);
+	memcpy(B_N_PDELIM_KEY(tb->CFR[h], tb->rkey[h]), key, KEY_SIZE);
 
-  do_balance_mark_internal_dirty (tb, tb->CFR[h], 0);
+	do_balance_mark_internal_dirty(tb, tb->CFR[h], 0);
 }
 
-
-int balance_internal (struct tree_balance * tb,			/* tree_balance structure 		*/
-		      int h,					/* level of the tree 			*/
-		      int child_pos,
-		      struct item_head * insert_key,		/* key for insertion on higher level   	*/
-		      struct buffer_head ** insert_ptr	/* node for insertion on higher level*/
+int balance_internal(struct tree_balance *tb,	/* tree_balance structure               */
+		     int h,	/* level of the tree                    */
+		     int child_pos, struct item_head *insert_key,	/* key for insertion on higher level    */
+		     struct buffer_head **insert_ptr	/* node for insertion on higher level */
     )
     /* if inserting/pasting
        {
-       child_pos is the position of the node-pointer in S[h] that	 *
-       pointed to S[h-1] before balancing of the h-1 level;		 *
+       child_pos is the position of the node-pointer in S[h] that        *
+       pointed to S[h-1] before balancing of the h-1 level;              *
        this means that new pointers and items must be inserted AFTER *
        child_pos
        }
        else 
        {
-   it is the position of the leftmost pointer that must be deleted (together with
-   its corresponding key to the left of the pointer)
-   as a result of the previous level's balancing.
-   }
-*/
+       it is the position of the leftmost pointer that must be deleted (together with
+       its corresponding key to the left of the pointer)
+       as a result of the previous level's balancing.
+       }
+     */
 {
-    struct buffer_head * tbSh = PATH_H_PBUFFER (tb->tb_path, h);
-    struct buffer_info bi;
-    int order;		/* we return this: it is 0 if there is no S[h], else it is tb->S[h]->b_item_order */
-    int insert_num, n, k;
-    struct buffer_head * S_new;
-    struct item_head new_insert_key;
-    struct buffer_head * new_insert_ptr = NULL;
-    struct item_head * new_insert_key_addr = insert_key;
-
-    RFALSE( h < 1, "h (%d) can not be < 1 on internal level", h);
-
-    PROC_INFO_INC( tb -> tb_sb, balance_at[ h ] );
-
-    order = ( tbSh ) ? PATH_H_POSITION (tb->tb_path, h + 1)/*tb->S[h]->b_item_order*/ : 0;
-
-  /* Using insert_size[h] calculate the number insert_num of items
-     that must be inserted to or deleted from S[h]. */
-    insert_num = tb->insert_size[h]/((int)(KEY_SIZE + DC_SIZE));
-
-    /* Check whether insert_num is proper **/
-    RFALSE( insert_num < -2  ||  insert_num > 2,
-	    "incorrect number of items inserted to the internal node (%d)", 
-	    insert_num);
-    RFALSE( h > 1  && (insert_num > 1 || insert_num < -1),
-	    "incorrect number of items (%d) inserted to the internal node on a level (h=%d) higher than last internal level", 
-	    insert_num, h);
-
-    /* Make balance in case insert_num < 0 */
-    if ( insert_num < 0 ) {
-	balance_internal_when_delete (tb, h, child_pos);
-	return order;
-    }
- 
-    k = 0;
-    if ( tb->lnum[h] > 0 ) {
-	/* shift lnum[h] items from S[h] to the left neighbor L[h].
-	   check how many of new items fall into L[h] or CFL[h] after
-	   shifting */
-	n = B_NR_ITEMS (tb->L[h]); /* number of items in L[h] */
-	if ( tb->lnum[h] <= child_pos ) {
-	    /* new items don't fall into L[h] or CFL[h] */
-	    internal_shift_left (INTERNAL_SHIFT_FROM_S_TO_L, tb, h, tb->lnum[h]);
-	    /*internal_shift_left (tb->L[h],tb->CFL[h],tb->lkey[h],tbSh,tb->lnum[h]);*/
-	    child_pos -= tb->lnum[h];
-	} else if ( tb->lnum[h] > child_pos + insert_num ) {
-	    /* all new items fall into L[h] */
-	    internal_shift_left (INTERNAL_SHIFT_FROM_S_TO_L, tb, h, tb->lnum[h] - insert_num);
-	    /*			internal_shift_left(tb->L[h],tb->CFL[h],tb->lkey[h],tbSh,
-				tb->lnum[h]-insert_num);
-	    */
-	    /* insert insert_num keys and node-pointers into L[h] */
-	    bi.tb = tb;
-	    bi.bi_bh = tb->L[h];
-	    bi.bi_parent = tb->FL[h];
-	    bi.bi_position = get_left_neighbor_position (tb, h);
-	    internal_insert_childs (&bi,/*tb->L[h], tb->S[h-1]->b_next*/ n + child_pos + 1,
-				    insert_num,insert_key,insert_ptr);
-
-	    insert_num = 0; 
-	} else {
-	    struct disk_child * dc;
-
-	    /* some items fall into L[h] or CFL[h], but some don't fall */
-	    internal_shift1_left(tb,h,child_pos+1);
-	    /* calculate number of new items that fall into L[h] */
-	    k = tb->lnum[h] - child_pos - 1;
-	    bi.tb = tb;
-	    bi.bi_bh = tb->L[h];
-	    bi.bi_parent = tb->FL[h];
-	    bi.bi_position = get_left_neighbor_position (tb, h);
-	    internal_insert_childs (&bi,/*tb->L[h], tb->S[h-1]->b_next,*/ n + child_pos + 1,k,
-				    insert_key,insert_ptr);
-
-	    replace_lkey(tb,h,insert_key + k);
-
-	    /* replace the first node-ptr in S[h] by node-ptr to insert_ptr[k] */
-	    dc = B_N_CHILD(tbSh, 0);
-	    put_dc_size( dc, MAX_CHILD_SIZE(insert_ptr[k]) - B_FREE_SPACE (insert_ptr[k]));
-	    put_dc_block_number( dc, insert_ptr[k]->b_blocknr );
-
-	    do_balance_mark_internal_dirty (tb, tbSh, 0);
-
-	    k++;
-	    insert_key += k;
-	    insert_ptr += k;
-	    insert_num -= k;
-	    child_pos = 0;
-	}
-    }	/* tb->lnum[h] > 0 */
-
-    if ( tb->rnum[h] > 0 ) {
-	/*shift rnum[h] items from S[h] to the right neighbor R[h]*/
-	/* check how many of new items fall into R or CFR after shifting */
-	n = B_NR_ITEMS (tbSh); /* number of items in S[h] */
-	if ( n - tb->rnum[h] >= child_pos )
-	    /* new items fall into S[h] */
-	    /*internal_shift_right(tb,h,tbSh,tb->CFR[h],tb->rkey[h],tb->R[h],tb->rnum[h]);*/
-	    internal_shift_right (INTERNAL_SHIFT_FROM_S_TO_R, tb, h, tb->rnum[h]);
-	else
-	    if ( n + insert_num - tb->rnum[h] < child_pos )
-	    {
-		/* all new items fall into R[h] */
-		/*internal_shift_right(tb,h,tbSh,tb->CFR[h],tb->rkey[h],tb->R[h],
-	    tb->rnum[h] - insert_num);*/
-		internal_shift_right (INTERNAL_SHIFT_FROM_S_TO_R, tb, h, tb->rnum[h] - insert_num);
+	struct buffer_head *tbSh = PATH_H_PBUFFER(tb->tb_path, h);
+	struct buffer_info bi;
+	int order;		/* we return this: it is 0 if there is no S[h], else it is tb->S[h]->b_item_order */
+	int insert_num, n, k;
+	struct buffer_head *S_new;
+	struct item_head new_insert_key;
+	struct buffer_head *new_insert_ptr = NULL;
+	struct item_head *new_insert_key_addr = insert_key;
+
+	RFALSE(h < 1, "h (%d) can not be < 1 on internal level", h);
+
+	PROC_INFO_INC(tb->tb_sb, balance_at[h]);
+
+	order =
+	    (tbSh) ? PATH_H_POSITION(tb->tb_path,
+				     h + 1) /*tb->S[h]->b_item_order */ : 0;
+
+	/* Using insert_size[h] calculate the number insert_num of items
+	   that must be inserted to or deleted from S[h]. */
+	insert_num = tb->insert_size[h] / ((int)(KEY_SIZE + DC_SIZE));
+
+	/* Check whether insert_num is proper * */
+	RFALSE(insert_num < -2 || insert_num > 2,
+	       "incorrect number of items inserted to the internal node (%d)",
+	       insert_num);
+	RFALSE(h > 1 && (insert_num > 1 || insert_num < -1),
+	       "incorrect number of items (%d) inserted to the internal node on a level (h=%d) higher than last internal level",
+	       insert_num, h);
+
+	/* Make balance in case insert_num < 0 */
+	if (insert_num < 0) {
+		balance_internal_when_delete(tb, h, child_pos);
+		return order;
+	}
 
-		/* insert insert_num keys and node-pointers into R[h] */
-		bi.tb = tb;
-		bi.bi_bh = tb->R[h];
-		bi.bi_parent = tb->FR[h];
-		bi.bi_position = get_right_neighbor_position (tb, h);
-		internal_insert_childs (&bi, /*tb->R[h],tb->S[h-1]->b_next*/ child_pos - n - insert_num + tb->rnum[h] - 1,
-					insert_num,insert_key,insert_ptr);
-		insert_num = 0;
-	    }
-	    else
-	    {
-		struct disk_child * dc;
-
-		/* one of the items falls into CFR[h] */
-		internal_shift1_right(tb,h,n - child_pos + 1);
-		/* calculate number of new items that fall into R[h] */
-		k = tb->rnum[h] - n + child_pos - 1;
-		bi.tb = tb;
-		bi.bi_bh = tb->R[h];
-		bi.bi_parent = tb->FR[h];
-		bi.bi_position = get_right_neighbor_position (tb, h);
-		internal_insert_childs (&bi, /*tb->R[h], tb->R[h]->b_child,*/ 0, k, insert_key + 1, insert_ptr + 1);
-
-		replace_rkey(tb,h,insert_key + insert_num - k - 1);
-
-		/* replace the first node-ptr in R[h] by node-ptr insert_ptr[insert_num-k-1]*/
-		dc = B_N_CHILD(tb->R[h], 0);
-		put_dc_size( dc, MAX_CHILD_SIZE(insert_ptr[insert_num-k-1]) -
-    				    B_FREE_SPACE (insert_ptr[insert_num-k-1]));
-		put_dc_block_number( dc, insert_ptr[insert_num-k-1]->b_blocknr );
-
-		do_balance_mark_internal_dirty (tb, tb->R[h],0);
-
-		insert_num -= (k + 1);
-	    }
-    }
+	k = 0;
+	if (tb->lnum[h] > 0) {
+		/* shift lnum[h] items from S[h] to the left neighbor L[h].
+		   check how many of new items fall into L[h] or CFL[h] after
+		   shifting */
+		n = B_NR_ITEMS(tb->L[h]);	/* number of items in L[h] */
+		if (tb->lnum[h] <= child_pos) {
+			/* new items don't fall into L[h] or CFL[h] */
+			internal_shift_left(INTERNAL_SHIFT_FROM_S_TO_L, tb, h,
+					    tb->lnum[h]);
+			/*internal_shift_left (tb->L[h],tb->CFL[h],tb->lkey[h],tbSh,tb->lnum[h]); */
+			child_pos -= tb->lnum[h];
+		} else if (tb->lnum[h] > child_pos + insert_num) {
+			/* all new items fall into L[h] */
+			internal_shift_left(INTERNAL_SHIFT_FROM_S_TO_L, tb, h,
+					    tb->lnum[h] - insert_num);
+			/*                  internal_shift_left(tb->L[h],tb->CFL[h],tb->lkey[h],tbSh,
+			   tb->lnum[h]-insert_num);
+			 */
+			/* insert insert_num keys and node-pointers into L[h] */
+			bi.tb = tb;
+			bi.bi_bh = tb->L[h];
+			bi.bi_parent = tb->FL[h];
+			bi.bi_position = get_left_neighbor_position(tb, h);
+			internal_insert_childs(&bi,
+					       /*tb->L[h], tb->S[h-1]->b_next */
+					       n + child_pos + 1,
+					       insert_num, insert_key,
+					       insert_ptr);
+
+			insert_num = 0;
+		} else {
+			struct disk_child *dc;
+
+			/* some items fall into L[h] or CFL[h], but some don't fall */
+			internal_shift1_left(tb, h, child_pos + 1);
+			/* calculate number of new items that fall into L[h] */
+			k = tb->lnum[h] - child_pos - 1;
+			bi.tb = tb;
+			bi.bi_bh = tb->L[h];
+			bi.bi_parent = tb->FL[h];
+			bi.bi_position = get_left_neighbor_position(tb, h);
+			internal_insert_childs(&bi,
+					       /*tb->L[h], tb->S[h-1]->b_next, */
+					       n + child_pos + 1, k,
+					       insert_key, insert_ptr);
+
+			replace_lkey(tb, h, insert_key + k);
+
+			/* replace the first node-ptr in S[h] by node-ptr to insert_ptr[k] */
+			dc = B_N_CHILD(tbSh, 0);
+			put_dc_size(dc,
+				    MAX_CHILD_SIZE(insert_ptr[k]) -
+				    B_FREE_SPACE(insert_ptr[k]));
+			put_dc_block_number(dc, insert_ptr[k]->b_blocknr);
+
+			do_balance_mark_internal_dirty(tb, tbSh, 0);
+
+			k++;
+			insert_key += k;
+			insert_ptr += k;
+			insert_num -= k;
+			child_pos = 0;
+		}
+	}
+	/* tb->lnum[h] > 0 */
+	if (tb->rnum[h] > 0) {
+		/*shift rnum[h] items from S[h] to the right neighbor R[h] */
+		/* check how many of new items fall into R or CFR after shifting */
+		n = B_NR_ITEMS(tbSh);	/* number of items in S[h] */
+		if (n - tb->rnum[h] >= child_pos)
+			/* new items fall into S[h] */
+			/*internal_shift_right(tb,h,tbSh,tb->CFR[h],tb->rkey[h],tb->R[h],tb->rnum[h]); */
+			internal_shift_right(INTERNAL_SHIFT_FROM_S_TO_R, tb, h,
+					     tb->rnum[h]);
+		else if (n + insert_num - tb->rnum[h] < child_pos) {
+			/* all new items fall into R[h] */
+			/*internal_shift_right(tb,h,tbSh,tb->CFR[h],tb->rkey[h],tb->R[h],
+			   tb->rnum[h] - insert_num); */
+			internal_shift_right(INTERNAL_SHIFT_FROM_S_TO_R, tb, h,
+					     tb->rnum[h] - insert_num);
+
+			/* insert insert_num keys and node-pointers into R[h] */
+			bi.tb = tb;
+			bi.bi_bh = tb->R[h];
+			bi.bi_parent = tb->FR[h];
+			bi.bi_position = get_right_neighbor_position(tb, h);
+			internal_insert_childs(&bi,
+					       /*tb->R[h],tb->S[h-1]->b_next */
+					       child_pos - n - insert_num +
+					       tb->rnum[h] - 1,
+					       insert_num, insert_key,
+					       insert_ptr);
+			insert_num = 0;
+		} else {
+			struct disk_child *dc;
+
+			/* one of the items falls into CFR[h] */
+			internal_shift1_right(tb, h, n - child_pos + 1);
+			/* calculate number of new items that fall into R[h] */
+			k = tb->rnum[h] - n + child_pos - 1;
+			bi.tb = tb;
+			bi.bi_bh = tb->R[h];
+			bi.bi_parent = tb->FR[h];
+			bi.bi_position = get_right_neighbor_position(tb, h);
+			internal_insert_childs(&bi,
+					       /*tb->R[h], tb->R[h]->b_child, */
+					       0, k, insert_key + 1,
+					       insert_ptr + 1);
+
+			replace_rkey(tb, h, insert_key + insert_num - k - 1);
+
+			/* replace the first node-ptr in R[h] by node-ptr insert_ptr[insert_num-k-1] */
+			dc = B_N_CHILD(tb->R[h], 0);
+			put_dc_size(dc,
+				    MAX_CHILD_SIZE(insert_ptr
+						   [insert_num - k - 1]) -
+				    B_FREE_SPACE(insert_ptr
+						 [insert_num - k - 1]));
+			put_dc_block_number(dc,
+					    insert_ptr[insert_num - k -
+						       1]->b_blocknr);
 
-    /** Fill new node that appears instead of S[h] **/
-    RFALSE( tb->blknum[h] > 2, "blknum can not be > 2 for internal level");
-    RFALSE( tb->blknum[h] < 0, "blknum can not be < 0");
+			do_balance_mark_internal_dirty(tb, tb->R[h], 0);
 
-    if ( ! tb->blknum[h] )
-    { /* node S[h] is empty now */
-	RFALSE( ! tbSh, "S[h] is equal NULL");
+			insert_num -= (k + 1);
+		}
+	}
 
-	/* do what is needed for buffer thrown from tree */
-	reiserfs_invalidate_buffer(tb,tbSh);
-	return order;
-    }
+    /** Fill new node that appears instead of S[h] **/
+	RFALSE(tb->blknum[h] > 2, "blknum can not be > 2 for internal level");
+	RFALSE(tb->blknum[h] < 0, "blknum can not be < 0");
 
-    if ( ! tbSh ) {
-	/* create new root */
-	struct disk_child  * dc;
-	struct buffer_head * tbSh_1 = PATH_H_PBUFFER (tb->tb_path, h - 1);
-        struct block_head *  blkh;
-
-
-	if ( tb->blknum[h] != 1 )
-	    reiserfs_panic(NULL, "balance_internal: One new node required for creating the new root");
-	/* S[h] = empty buffer from the list FEB. */
-	tbSh = get_FEB (tb);
-        blkh = B_BLK_HEAD(tbSh);
-        set_blkh_level( blkh, h + 1 );
-
-	/* Put the unique node-pointer to S[h] that points to S[h-1]. */
-
-	dc = B_N_CHILD(tbSh, 0);
-	put_dc_block_number( dc, tbSh_1->b_blocknr );
-	put_dc_size( dc, (MAX_CHILD_SIZE (tbSh_1) - B_FREE_SPACE (tbSh_1)));
-
-	tb->insert_size[h] -= DC_SIZE;
-        set_blkh_free_space( blkh, blkh_free_space(blkh) - DC_SIZE );
-
-	do_balance_mark_internal_dirty (tb, tbSh, 0);
-
-	/*&&&&&&&&&&&&&&&&&&&&&&&&*/
-	check_internal (tbSh);
-	/*&&&&&&&&&&&&&&&&&&&&&&&&*/
-    
-    /* put new root into path structure */
-	PATH_OFFSET_PBUFFER(tb->tb_path, ILLEGAL_PATH_ELEMENT_OFFSET) = tbSh;
-
-	/* Change root in structure super block. */
-        PUT_SB_ROOT_BLOCK( tb->tb_sb, tbSh->b_blocknr );
-        PUT_SB_TREE_HEIGHT( tb->tb_sb, SB_TREE_HEIGHT(tb->tb_sb) + 1 );
-	do_balance_mark_sb_dirty (tb, REISERFS_SB(tb->tb_sb)->s_sbh, 1);
-    }
-	
-    if ( tb->blknum[h] == 2 ) {
-	int snum;
-	struct buffer_info dest_bi, src_bi;
+	if (!tb->blknum[h]) {	/* node S[h] is empty now */
+		RFALSE(!tbSh, "S[h] is equal NULL");
 
+		/* do what is needed for buffer thrown from tree */
+		reiserfs_invalidate_buffer(tb, tbSh);
+		return order;
+	}
 
-	/* S_new = free buffer from list FEB */
-	S_new = get_FEB(tb);
+	if (!tbSh) {
+		/* create new root */
+		struct disk_child *dc;
+		struct buffer_head *tbSh_1 = PATH_H_PBUFFER(tb->tb_path, h - 1);
+		struct block_head *blkh;
+
+		if (tb->blknum[h] != 1)
+			reiserfs_panic(NULL,
+				       "balance_internal: One new node required for creating the new root");
+		/* S[h] = empty buffer from the list FEB. */
+		tbSh = get_FEB(tb);
+		blkh = B_BLK_HEAD(tbSh);
+		set_blkh_level(blkh, h + 1);
+
+		/* Put the unique node-pointer to S[h] that points to S[h-1]. */
+
+		dc = B_N_CHILD(tbSh, 0);
+		put_dc_block_number(dc, tbSh_1->b_blocknr);
+		put_dc_size(dc,
+			    (MAX_CHILD_SIZE(tbSh_1) - B_FREE_SPACE(tbSh_1)));
+
+		tb->insert_size[h] -= DC_SIZE;
+		set_blkh_free_space(blkh, blkh_free_space(blkh) - DC_SIZE);
+
+		do_balance_mark_internal_dirty(tb, tbSh, 0);
+
+		/*&&&&&&&&&&&&&&&&&&&&&&&& */
+		check_internal(tbSh);
+		/*&&&&&&&&&&&&&&&&&&&&&&&& */
+
+		/* put new root into path structure */
+		PATH_OFFSET_PBUFFER(tb->tb_path, ILLEGAL_PATH_ELEMENT_OFFSET) =
+		    tbSh;
+
+		/* Change root in structure super block. */
+		PUT_SB_ROOT_BLOCK(tb->tb_sb, tbSh->b_blocknr);
+		PUT_SB_TREE_HEIGHT(tb->tb_sb, SB_TREE_HEIGHT(tb->tb_sb) + 1);
+		do_balance_mark_sb_dirty(tb, REISERFS_SB(tb->tb_sb)->s_sbh, 1);
+	}
 
-        set_blkh_level( B_BLK_HEAD(S_new), h + 1 );
+	if (tb->blknum[h] == 2) {
+		int snum;
+		struct buffer_info dest_bi, src_bi;
+
+		/* S_new = free buffer from list FEB */
+		S_new = get_FEB(tb);
+
+		set_blkh_level(B_BLK_HEAD(S_new), h + 1);
+
+		dest_bi.tb = tb;
+		dest_bi.bi_bh = S_new;
+		dest_bi.bi_parent = NULL;
+		dest_bi.bi_position = 0;
+		src_bi.tb = tb;
+		src_bi.bi_bh = tbSh;
+		src_bi.bi_parent = PATH_H_PPARENT(tb->tb_path, h);
+		src_bi.bi_position = PATH_H_POSITION(tb->tb_path, h + 1);
+
+		n = B_NR_ITEMS(tbSh);	/* number of items in S[h] */
+		snum = (insert_num + n + 1) / 2;
+		if (n - snum >= child_pos) {
+			/* new items don't fall into S_new */
+			/*  store the delimiting key for the next level */
+			/* new_insert_key = (n - snum)'th key in S[h] */
+			memcpy(&new_insert_key, B_N_PDELIM_KEY(tbSh, n - snum),
+			       KEY_SIZE);
+			/* last parameter is del_par */
+			internal_move_pointers_items(&dest_bi, &src_bi,
+						     LAST_TO_FIRST, snum, 0);
+			/*            internal_move_pointers_items(S_new, tbSh, LAST_TO_FIRST, snum, 0); */
+		} else if (n + insert_num - snum < child_pos) {
+			/* all new items fall into S_new */
+			/*  store the delimiting key for the next level */
+			/* new_insert_key = (n + insert_item - snum)'th key in S[h] */
+			memcpy(&new_insert_key,
+			       B_N_PDELIM_KEY(tbSh, n + insert_num - snum),
+			       KEY_SIZE);
+			/* last parameter is del_par */
+			internal_move_pointers_items(&dest_bi, &src_bi,
+						     LAST_TO_FIRST,
+						     snum - insert_num, 0);
+			/*                  internal_move_pointers_items(S_new,tbSh,1,snum - insert_num,0); */
+
+			/* insert insert_num keys and node-pointers into S_new */
+			internal_insert_childs(&dest_bi,
+					       /*S_new,tb->S[h-1]->b_next, */
+					       child_pos - n - insert_num +
+					       snum - 1,
+					       insert_num, insert_key,
+					       insert_ptr);
+
+			insert_num = 0;
+		} else {
+			struct disk_child *dc;
+
+			/* some items fall into S_new, but some don't fall */
+			/* last parameter is del_par */
+			internal_move_pointers_items(&dest_bi, &src_bi,
+						     LAST_TO_FIRST,
+						     n - child_pos + 1, 1);
+			/*                  internal_move_pointers_items(S_new,tbSh,1,n - child_pos + 1,1); */
+			/* calculate number of new items that fall into S_new */
+			k = snum - n + child_pos - 1;
+
+			internal_insert_childs(&dest_bi, /*S_new, */ 0, k,
+					       insert_key + 1, insert_ptr + 1);
+
+			/* new_insert_key = insert_key[insert_num - k - 1] */
+			memcpy(&new_insert_key, insert_key + insert_num - k - 1,
+			       KEY_SIZE);
+			/* replace first node-ptr in S_new by node-ptr to insert_ptr[insert_num-k-1] */
+
+			dc = B_N_CHILD(S_new, 0);
+			put_dc_size(dc,
+				    (MAX_CHILD_SIZE
+				     (insert_ptr[insert_num - k - 1]) -
+				     B_FREE_SPACE(insert_ptr
+						  [insert_num - k - 1])));
+			put_dc_block_number(dc,
+					    insert_ptr[insert_num - k -
+						       1]->b_blocknr);
+
+			do_balance_mark_internal_dirty(tb, S_new, 0);
+
+			insert_num -= (k + 1);
+		}
+		/* new_insert_ptr = node_pointer to S_new */
+		new_insert_ptr = S_new;
+
+		RFALSE(!buffer_journaled(S_new) || buffer_journal_dirty(S_new)
+		       || buffer_dirty(S_new), "cm-00001: bad S_new (%b)",
+		       S_new);
 
-	dest_bi.tb = tb;
-	dest_bi.bi_bh = S_new;
-	dest_bi.bi_parent = NULL;
-	dest_bi.bi_position = 0;
-	src_bi.tb = tb;
-	src_bi.bi_bh = tbSh;
-	src_bi.bi_parent = PATH_H_PPARENT (tb->tb_path, h);
-	src_bi.bi_position = PATH_H_POSITION (tb->tb_path, h + 1);
-		
-	n = B_NR_ITEMS (tbSh); /* number of items in S[h] */
-	snum = (insert_num + n + 1)/2;
-	if ( n - snum >= child_pos ) {
-	    /* new items don't fall into S_new */
-	    /*	store the delimiting key for the next level */
-	    /* new_insert_key = (n - snum)'th key in S[h] */
-	    memcpy (&new_insert_key,B_N_PDELIM_KEY(tbSh,n - snum),
-		    KEY_SIZE);
-	    /* last parameter is del_par */
-	    internal_move_pointers_items (&dest_bi, &src_bi, LAST_TO_FIRST, snum, 0);
-	    /*            internal_move_pointers_items(S_new, tbSh, LAST_TO_FIRST, snum, 0);*/
-	} else if ( n + insert_num - snum < child_pos ) {
-	    /* all new items fall into S_new */
-	    /*	store the delimiting key for the next level */
-	    /* new_insert_key = (n + insert_item - snum)'th key in S[h] */
-	    memcpy(&new_insert_key,B_N_PDELIM_KEY(tbSh,n + insert_num - snum),
-		   KEY_SIZE);
-	    /* last parameter is del_par */
-	    internal_move_pointers_items (&dest_bi, &src_bi, LAST_TO_FIRST, snum - insert_num, 0);
-	    /*			internal_move_pointers_items(S_new,tbSh,1,snum - insert_num,0);*/
-
-	    /* insert insert_num keys and node-pointers into S_new */
-	    internal_insert_childs (&dest_bi, /*S_new,tb->S[h-1]->b_next,*/child_pos - n - insert_num + snum - 1,
-				    insert_num,insert_key,insert_ptr);
-
-	    insert_num = 0;
-	} else {
-	    struct disk_child * dc;
-
-	    /* some items fall into S_new, but some don't fall */
-	    /* last parameter is del_par */
-	    internal_move_pointers_items (&dest_bi, &src_bi, LAST_TO_FIRST, n - child_pos + 1, 1);
-	    /*			internal_move_pointers_items(S_new,tbSh,1,n - child_pos + 1,1);*/
-	    /* calculate number of new items that fall into S_new */
-	    k = snum - n + child_pos - 1;
-
-	    internal_insert_childs (&dest_bi, /*S_new,*/ 0, k, insert_key + 1, insert_ptr+1);
-
-	    /* new_insert_key = insert_key[insert_num - k - 1] */
-	    memcpy(&new_insert_key,insert_key + insert_num - k - 1,
-		   KEY_SIZE);
-	    /* replace first node-ptr in S_new by node-ptr to insert_ptr[insert_num-k-1] */
-
-	    dc = B_N_CHILD(S_new,0);
-	    put_dc_size( dc, (MAX_CHILD_SIZE(insert_ptr[insert_num-k-1]) -
-				B_FREE_SPACE(insert_ptr[insert_num-k-1])) );
-	    put_dc_block_number( dc, insert_ptr[insert_num-k-1]->b_blocknr );
-
-	    do_balance_mark_internal_dirty (tb, S_new,0);
-			
-	    insert_num -= (k + 1);
-	}
-	/* new_insert_ptr = node_pointer to S_new */
-	new_insert_ptr = S_new;
-
-	RFALSE (!buffer_journaled(S_new) || buffer_journal_dirty(S_new) ||
-		buffer_dirty (S_new),
-		"cm-00001: bad S_new (%b)", S_new);
-
-	// S_new is released in unfix_nodes
-    }
-
-    n = B_NR_ITEMS (tbSh); /*number of items in S[h] */
-
-	if ( 0 <= child_pos && child_pos <= n && insert_num > 0 ) {
-	    bi.tb = tb;
-	    bi.bi_bh = tbSh;
-	    bi.bi_parent = PATH_H_PPARENT (tb->tb_path, h);
-	    bi.bi_position = PATH_H_POSITION (tb->tb_path, h + 1);
-		internal_insert_childs (
-		    &bi,/*tbSh,*/
-		    /*		( tb->S[h-1]->b_parent == tb->S[h] ) ? tb->S[h-1]->b_next :  tb->S[h]->b_child->b_next,*/
-		    child_pos,insert_num,insert_key,insert_ptr
-		    );
+		// S_new is released in unfix_nodes
 	}
 
+	n = B_NR_ITEMS(tbSh);	/*number of items in S[h] */
 
-	memcpy (new_insert_key_addr,&new_insert_key,KEY_SIZE);
+	if (0 <= child_pos && child_pos <= n && insert_num > 0) {
+		bi.tb = tb;
+		bi.bi_bh = tbSh;
+		bi.bi_parent = PATH_H_PPARENT(tb->tb_path, h);
+		bi.bi_position = PATH_H_POSITION(tb->tb_path, h + 1);
+		internal_insert_childs(&bi,	/*tbSh, */
+				       /*          ( tb->S[h-1]->b_parent == tb->S[h] ) ? tb->S[h-1]->b_next :  tb->S[h]->b_child->b_next, */
+				       child_pos, insert_num, insert_key,
+				       insert_ptr);
+	}
+
+	memcpy(new_insert_key_addr, &new_insert_key, KEY_SIZE);
 	insert_ptr[0] = new_insert_ptr;
 
 	return order;
-    }
-
-  
-    
+}
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
--- a/fs/reiserfs/inode.c
+++ b/fs/reiserfs/inode.c
@@ -18,107 +18,109 @@
 #include <linux/writeback.h>
 #include <linux/quotaops.h>
 
-extern int reiserfs_default_io_size; /* default io size devuned in super.c */
+extern int reiserfs_default_io_size;	/* default io size devuned in super.c */
 
 static int reiserfs_commit_write(struct file *f, struct page *page,
-                                 unsigned from, unsigned to);
+				 unsigned from, unsigned to);
 static int reiserfs_prepare_write(struct file *f, struct page *page,
 				  unsigned from, unsigned to);
 
-void reiserfs_delete_inode (struct inode * inode)
+void reiserfs_delete_inode(struct inode *inode)
 {
-    /* We need blocks for transaction + (user+group) quota update (possibly delete) */
-    int jbegin_count = JOURNAL_PER_BALANCE_CNT * 2 + 2 * REISERFS_QUOTA_INIT_BLOCKS;
-    struct reiserfs_transaction_handle th ;
-  
-    reiserfs_write_lock(inode->i_sb);
+	/* We need blocks for transaction + (user+group) quota update (possibly delete) */
+	int jbegin_count =
+	    JOURNAL_PER_BALANCE_CNT * 2 +
+	    2 * REISERFS_QUOTA_INIT_BLOCKS(inode->i_sb);
+	struct reiserfs_transaction_handle th;
 
-    /* The = 0 happens when we abort creating a new inode for some reason like lack of space.. */
-    if (!(inode->i_state & I_NEW) && INODE_PKEY(inode)->k_objectid != 0) { /* also handles bad_inode case */
-	down (&inode->i_sem); 
+	reiserfs_write_lock(inode->i_sb);
 
-	reiserfs_delete_xattrs (inode);
+	/* The = 0 happens when we abort creating a new inode for some reason like lack of space.. */
+	if (!(inode->i_state & I_NEW) && INODE_PKEY(inode)->k_objectid != 0) {	/* also handles bad_inode case */
+		down(&inode->i_sem);
 
-	if (journal_begin(&th, inode->i_sb, jbegin_count)) {
-	    up (&inode->i_sem);
-	    goto out;
-	}
-	reiserfs_update_inode_transaction(inode) ;
+		reiserfs_delete_xattrs(inode);
 
-	if (reiserfs_delete_object (&th, inode)) {
-	    up (&inode->i_sem);
-	    goto out;
-	}
+		if (journal_begin(&th, inode->i_sb, jbegin_count)) {
+			up(&inode->i_sem);
+			goto out;
+		}
+		reiserfs_update_inode_transaction(inode);
 
-	/* Do quota update inside a transaction for journaled quotas. We must do that
-	 * after delete_object so that quota updates go into the same transaction as
-	 * stat data deletion */
-	DQUOT_FREE_INODE(inode);
+		if (reiserfs_delete_object(&th, inode)) {
+			up(&inode->i_sem);
+			goto out;
+		}
+
+		/* Do quota update inside a transaction for journaled quotas. We must do that
+		 * after delete_object so that quota updates go into the same transaction as
+		 * stat data deletion */
+		DQUOT_FREE_INODE(inode);
 
-	if (journal_end(&th, inode->i_sb, jbegin_count)) {
-	    up (&inode->i_sem);
-	    goto out;
-	}
-
-        up (&inode->i_sem);
-
-        /* all items of file are deleted, so we can remove "save" link */
-	remove_save_link (inode, 0/* not truncate */); /* we can't do anything
-                                                        * about an error here */
-    } else {
-	/* no object items are in the tree */
-	;
-    }
-out:
-    clear_inode (inode); /* note this must go after the journal_end to prevent deadlock */
-    inode->i_blocks = 0;
-    reiserfs_write_unlock(inode->i_sb);
-}
-
-static void _make_cpu_key (struct cpu_key * key, int version, __u32 dirid, __u32 objectid, 
-	       loff_t offset, int type, int length )
-{
-    key->version = version;
-
-    key->on_disk_key.k_dir_id = dirid;
-    key->on_disk_key.k_objectid = objectid;
-    set_cpu_key_k_offset (key, offset);
-    set_cpu_key_k_type (key, type);  
-    key->key_length = length;
+		if (journal_end(&th, inode->i_sb, jbegin_count)) {
+			up(&inode->i_sem);
+			goto out;
+		}
+
+		up(&inode->i_sem);
+
+		/* all items of file are deleted, so we can remove "save" link */
+		remove_save_link(inode, 0 /* not truncate */ );	/* we can't do anything
+								 * about an error here */
+	} else {
+		/* no object items are in the tree */
+		;
+	}
+      out:
+	clear_inode(inode);	/* note this must go after the journal_end to prevent deadlock */
+	inode->i_blocks = 0;
+	reiserfs_write_unlock(inode->i_sb);
 }
 
+static void _make_cpu_key(struct cpu_key *key, int version, __u32 dirid,
+			  __u32 objectid, loff_t offset, int type, int length)
+{
+	key->version = version;
+
+	key->on_disk_key.k_dir_id = dirid;
+	key->on_disk_key.k_objectid = objectid;
+	set_cpu_key_k_offset(key, offset);
+	set_cpu_key_k_type(key, type);
+	key->key_length = length;
+}
 
 /* take base of inode_key (it comes from inode always) (dirid, objectid) and version from an inode, set
    offset and type of key */
-void make_cpu_key (struct cpu_key * key, struct inode * inode, loff_t offset,
-	      int type, int length )
+void make_cpu_key(struct cpu_key *key, struct inode *inode, loff_t offset,
+		  int type, int length)
 {
-  _make_cpu_key (key, get_inode_item_key_version (inode), le32_to_cpu (INODE_PKEY (inode)->k_dir_id),
-		 le32_to_cpu (INODE_PKEY (inode)->k_objectid), 
-		 offset, type, length);
+	_make_cpu_key(key, get_inode_item_key_version(inode),
+		      le32_to_cpu(INODE_PKEY(inode)->k_dir_id),
+		      le32_to_cpu(INODE_PKEY(inode)->k_objectid), offset, type,
+		      length);
 }
 
-
 //
 // when key is 0, do not set version and short key
 //
-inline void make_le_item_head (struct item_head * ih, const struct cpu_key * key,
-			       int version,
-			       loff_t offset, int type, int length, 
-			       int entry_count/*or ih_free_space*/)
-{
-    if (key) {
-	ih->ih_key.k_dir_id = cpu_to_le32 (key->on_disk_key.k_dir_id);
-	ih->ih_key.k_objectid = cpu_to_le32 (key->on_disk_key.k_objectid);
-    }
-    put_ih_version( ih, version );
-    set_le_ih_k_offset (ih, offset);
-    set_le_ih_k_type (ih, type);
-    put_ih_item_len( ih, length );
-    /*    set_ih_free_space (ih, 0);*/
-    // for directory items it is entry count, for directs and stat
-    // datas - 0xffff, for indirects - 0
-    put_ih_entry_count( ih, entry_count );
+inline void make_le_item_head(struct item_head *ih, const struct cpu_key *key,
+			      int version,
+			      loff_t offset, int type, int length,
+			      int entry_count /*or ih_free_space */ )
+{
+	if (key) {
+		ih->ih_key.k_dir_id = cpu_to_le32(key->on_disk_key.k_dir_id);
+		ih->ih_key.k_objectid =
+		    cpu_to_le32(key->on_disk_key.k_objectid);
+	}
+	put_ih_version(ih, version);
+	set_le_ih_k_offset(ih, offset);
+	set_le_ih_k_type(ih, type);
+	put_ih_item_len(ih, length);
+	/*    set_ih_free_space (ih, 0); */
+	// for directory items it is entry count, for directs and stat
+	// datas - 0xffff, for indirects - 0
+	put_ih_entry_count(ih, entry_count);
 }
 
 //
@@ -153,84 +155,84 @@ inline void make_le_item_head (struct it
 ** to be unmapped, so that block_prepare_write will correctly call
 ** reiserfs_get_block to convert the tail into an unformatted node
 */
-static inline void fix_tail_page_for_writing(struct page *page) {
-    struct buffer_head *head, *next, *bh ;
+static inline void fix_tail_page_for_writing(struct page *page)
+{
+	struct buffer_head *head, *next, *bh;
 
-    if (page && page_has_buffers(page)) {
-	head = page_buffers(page) ;
-	bh = head ;
-	do {
-	    next = bh->b_this_page ;
-	    if (buffer_mapped(bh) && bh->b_blocknr == 0) {
-	        reiserfs_unmap_buffer(bh) ;
-	    }
-	    bh = next ;
-	} while (bh != head) ;
-    }
+	if (page && page_has_buffers(page)) {
+		head = page_buffers(page);
+		bh = head;
+		do {
+			next = bh->b_this_page;
+			if (buffer_mapped(bh) && bh->b_blocknr == 0) {
+				reiserfs_unmap_buffer(bh);
+			}
+			bh = next;
+		} while (bh != head);
+	}
 }
 
 /* reiserfs_get_block does not need to allocate a block only if it has been
    done already or non-hole position has been found in the indirect item */
-static inline int allocation_needed (int retval, b_blocknr_t allocated, 
-				     struct item_head * ih,
-				     __le32 * item, int pos_in_item)
-{
-  if (allocated)
-	 return 0;
-  if (retval == POSITION_FOUND && is_indirect_le_ih (ih) && 
-      get_block_num(item, pos_in_item))
-	 return 0;
-  return 1;
+static inline int allocation_needed(int retval, b_blocknr_t allocated,
+				    struct item_head *ih,
+				    __le32 * item, int pos_in_item)
+{
+	if (allocated)
+		return 0;
+	if (retval == POSITION_FOUND && is_indirect_le_ih(ih) &&
+	    get_block_num(item, pos_in_item))
+		return 0;
+	return 1;
 }
 
-static inline int indirect_item_found (int retval, struct item_head * ih)
+static inline int indirect_item_found(int retval, struct item_head *ih)
 {
-  return (retval == POSITION_FOUND) && is_indirect_le_ih (ih);
+	return (retval == POSITION_FOUND) && is_indirect_le_ih(ih);
 }
 
-
-static inline void set_block_dev_mapped (struct buffer_head * bh, 
-					 b_blocknr_t block, struct inode * inode)
+static inline void set_block_dev_mapped(struct buffer_head *bh,
+					b_blocknr_t block, struct inode *inode)
 {
 	map_bh(bh, inode->i_sb, block);
 }
 
-
 //
 // files which were created in the earlier version can not be longer,
 // than 2 gb
 //
-static int file_capable (struct inode * inode, long block)
+static int file_capable(struct inode *inode, long block)
 {
-    if (get_inode_item_key_version (inode) != KEY_FORMAT_3_5 || // it is new file.
-	block < (1 << (31 - inode->i_sb->s_blocksize_bits))) // old file, but 'block' is inside of 2gb
-	return 1;
+	if (get_inode_item_key_version(inode) != KEY_FORMAT_3_5 ||	// it is new file.
+	    block < (1 << (31 - inode->i_sb->s_blocksize_bits)))	// old file, but 'block' is inside of 2gb
+		return 1;
 
-    return 0;
+	return 0;
 }
 
 /*static*/ int restart_transaction(struct reiserfs_transaction_handle *th,
-				struct inode *inode, struct path *path) {
-  struct super_block *s = th->t_super ;
-  int len = th->t_blocks_allocated ;
-  int err;
-
-  BUG_ON (!th->t_trans_id);
-  BUG_ON (!th->t_refcount);
-
-  /* we cannot restart while nested */
-  if (th->t_refcount > 1) {
-      return 0  ;
-  }
-  pathrelse(path) ;
-  reiserfs_update_sd(th, inode) ;
-  err = journal_end(th, s, len) ;
-  if (!err) {
-      err = journal_begin(th, s, JOURNAL_PER_BALANCE_CNT * 6) ;
-      if (!err)
-        reiserfs_update_inode_transaction(inode) ;
-  }
-  return err;
+				   struct inode *inode, struct path *path)
+{
+	struct super_block *s = th->t_super;
+	int len = th->t_blocks_allocated;
+	int err;
+
+	BUG_ON(!th->t_trans_id);
+	BUG_ON(!th->t_refcount);
+
+	/* we cannot restart while nested */
+	if (th->t_refcount > 1) {
+		return 0;
+	}
+	pathrelse(path);
+	reiserfs_update_sd(th, inode);
+	err = journal_end(th, s, len);
+	if (!err) {
+		err = journal_begin(th, s, JOURNAL_PER_BALANCE_CNT * 6);
+		if (!err)
+			reiserfs_update_inode_transaction(inode);
+	}
+	return err;
 }
 
 // it is called by get_block when create == 0. Returns block number
@@ -241,181 +243,192 @@ static int file_capable (struct inode * 
 // Please improve the english/clarity in the comment above, as it is
 // hard to understand.
 
-static int _get_block_create_0 (struct inode * inode, long block,
-				 struct buffer_head * bh_result,
-				 int args)
-{
-    INITIALIZE_PATH (path);
-    struct cpu_key key;
-    struct buffer_head * bh;
-    struct item_head * ih, tmp_ih;
-    int fs_gen ;
-    int blocknr;
-    char * p = NULL;
-    int chars;
-    int ret ;
-    int done = 0 ;
-    unsigned long offset ;
-
-    // prepare the key to look for the 'block'-th block of file
-    make_cpu_key (&key, inode,
-		  (loff_t)block * inode->i_sb->s_blocksize + 1, TYPE_ANY, 3);
-
-research:
-    if (search_for_position_by_key (inode->i_sb, &key, &path) != POSITION_FOUND) {
-	pathrelse (&path);
-        if (p)
-            kunmap(bh_result->b_page) ;
-	// We do not return -ENOENT if there is a hole but page is uptodate, because it means
-	// That there is some MMAPED data associated with it that is yet to be written to disk.
-	if ((args & GET_BLOCK_NO_HOLE) && !PageUptodate(bh_result->b_page) ) {
-	    return -ENOENT ;
-	}
-        return 0 ;
-    }
-    
-    //
-    bh = get_last_bh (&path);
-    ih = get_ih (&path);
-    if (is_indirect_le_ih (ih)) {
-	__le32 * ind_item = (__le32 *)B_I_PITEM (bh, ih);
-	
-	/* FIXME: here we could cache indirect item or part of it in
-	   the inode to avoid search_by_key in case of subsequent
-	   access to file */
-	blocknr = get_block_num(ind_item, path.pos_in_item) ;
-	ret = 0 ;
-	if (blocknr) {
-	    map_bh(bh_result, inode->i_sb, blocknr);
-	    if (path.pos_in_item == ((ih_item_len(ih) / UNFM_P_SIZE) - 1)) {
-		set_buffer_boundary(bh_result);
-	    }
-	} else 
-	    // We do not return -ENOENT if there is a hole but page is uptodate, because it means
-	    // That there is some MMAPED data associated with it that is yet to  be written to disk.
-	    if ((args & GET_BLOCK_NO_HOLE) && !PageUptodate(bh_result->b_page) ) {
-	    ret = -ENOENT ;
-	    }
-
-	pathrelse (&path);
-        if (p)
-            kunmap(bh_result->b_page) ;
-	return ret ;
-    }
-
-    // requested data are in direct item(s)
-    if (!(args & GET_BLOCK_READ_DIRECT)) {
-	// we are called by bmap. FIXME: we can not map block of file
-	// when it is stored in direct item(s)
-	pathrelse (&path);	
-        if (p)
-            kunmap(bh_result->b_page) ;
-	return -ENOENT;
-    }
-
-    /* if we've got a direct item, and the buffer or page was uptodate,
-    ** we don't want to pull data off disk again.  skip to the
-    ** end, where we map the buffer and return
-    */
-    if (buffer_uptodate(bh_result)) {
-        goto finished ;
-    } else 
-	/*
-	** grab_tail_page can trigger calls to reiserfs_get_block on up to date
-	** pages without any buffers.  If the page is up to date, we don't want
-	** read old data off disk.  Set the up to date bit on the buffer instead
-	** and jump to the end
-	*/
-	    if (!bh_result->b_page || PageUptodate(bh_result->b_page)) {
-		set_buffer_uptodate(bh_result);
-		goto finished ;
-    }
+static int _get_block_create_0(struct inode *inode, long block,
+			       struct buffer_head *bh_result, int args)
+{
+	INITIALIZE_PATH(path);
+	struct cpu_key key;
+	struct buffer_head *bh;
+	struct item_head *ih, tmp_ih;
+	int fs_gen;
+	int blocknr;
+	char *p = NULL;
+	int chars;
+	int ret;
+	int result;
+	int done = 0;
+	unsigned long offset;
+
+	// prepare the key to look for the 'block'-th block of file
+	make_cpu_key(&key, inode,
+		     (loff_t) block * inode->i_sb->s_blocksize + 1, TYPE_ANY,
+		     3);
+
+      research:
+	result = search_for_position_by_key(inode->i_sb, &key, &path);
+	if (result != POSITION_FOUND) {
+		pathrelse(&path);
+		if (p)
+			kunmap(bh_result->b_page);
+		if (result == IO_ERROR)
+			return -EIO;
+		// We do not return -ENOENT if there is a hole but page is uptodate, because it means
+		// That there is some MMAPED data associated with it that is yet to be written to disk.
+		if ((args & GET_BLOCK_NO_HOLE)
+		    && !PageUptodate(bh_result->b_page)) {
+			return -ENOENT;
+		}
+		return 0;
+	}
+	//
+	bh = get_last_bh(&path);
+	ih = get_ih(&path);
+	if (is_indirect_le_ih(ih)) {
+		__le32 *ind_item = (__le32 *) B_I_PITEM(bh, ih);
+
+		/* FIXME: here we could cache indirect item or part of it in
+		   the inode to avoid search_by_key in case of subsequent
+		   access to file */
+		blocknr = get_block_num(ind_item, path.pos_in_item);
+		ret = 0;
+		if (blocknr) {
+			map_bh(bh_result, inode->i_sb, blocknr);
+			if (path.pos_in_item ==
+			    ((ih_item_len(ih) / UNFM_P_SIZE) - 1)) {
+				set_buffer_boundary(bh_result);
+			}
+		} else
+			// We do not return -ENOENT if there is a hole but page is uptodate, because it means
+			// That there is some MMAPED data associated with it that is yet to  be written to disk.
+		if ((args & GET_BLOCK_NO_HOLE)
+			    && !PageUptodate(bh_result->b_page)) {
+			ret = -ENOENT;
+		}
 
-    // read file tail into part of page
-    offset = (cpu_key_k_offset(&key) - 1) & (PAGE_CACHE_SIZE - 1) ;
-    fs_gen = get_generation(inode->i_sb) ;
-    copy_item_head (&tmp_ih, ih);
-
-    /* we only want to kmap if we are reading the tail into the page.
-    ** this is not the common case, so we don't kmap until we are
-    ** sure we need to.  But, this means the item might move if
-    ** kmap schedules
-    */
-    if (!p) {
-	p = (char *)kmap(bh_result->b_page) ;
-	if (fs_changed (fs_gen, inode->i_sb) && item_moved (&tmp_ih, &path)) {
-	    goto research;
-	}
-    }
-    p += offset ;
-    memset (p, 0, inode->i_sb->s_blocksize);
-    do {
-	if (!is_direct_le_ih (ih)) {
-	    BUG ();
-        }
-	/* make sure we don't read more bytes than actually exist in
-	** the file.  This can happen in odd cases where i_size isn't
-	** correct, and when direct item padding results in a few 
-	** extra bytes at the end of the direct item
-	*/
-        if ((le_ih_k_offset(ih) + path.pos_in_item) > inode->i_size)
-	    break ;
-	if ((le_ih_k_offset(ih) - 1 + ih_item_len(ih)) > inode->i_size) {
-	    chars = inode->i_size - (le_ih_k_offset(ih) - 1) - path.pos_in_item;
-	    done = 1 ;
-	} else {
-	    chars = ih_item_len(ih) - path.pos_in_item;
+		pathrelse(&path);
+		if (p)
+			kunmap(bh_result->b_page);
+		return ret;
+	}
+	// requested data are in direct item(s)
+	if (!(args & GET_BLOCK_READ_DIRECT)) {
+		// we are called by bmap. FIXME: we can not map block of file
+		// when it is stored in direct item(s)
+		pathrelse(&path);
+		if (p)
+			kunmap(bh_result->b_page);
+		return -ENOENT;
+	}
+
+	/* if we've got a direct item, and the buffer or page was uptodate,
+	 ** we don't want to pull data off disk again.  skip to the
+	 ** end, where we map the buffer and return
+	 */
+	if (buffer_uptodate(bh_result)) {
+		goto finished;
+	} else
+		/*
+		 ** grab_tail_page can trigger calls to reiserfs_get_block on up to date
+		 ** pages without any buffers.  If the page is up to date, we don't want
+		 ** read old data off disk.  Set the up to date bit on the buffer instead
+		 ** and jump to the end
+		 */
+	if (!bh_result->b_page || PageUptodate(bh_result->b_page)) {
+		set_buffer_uptodate(bh_result);
+		goto finished;
+	}
+	// read file tail into part of page
+	offset = (cpu_key_k_offset(&key) - 1) & (PAGE_CACHE_SIZE - 1);
+	fs_gen = get_generation(inode->i_sb);
+	copy_item_head(&tmp_ih, ih);
+
+	/* we only want to kmap if we are reading the tail into the page.
+	 ** this is not the common case, so we don't kmap until we are
+	 ** sure we need to.  But, this means the item might move if
+	 ** kmap schedules
+	 */
+	if (!p) {
+		p = (char *)kmap(bh_result->b_page);
+		if (fs_changed(fs_gen, inode->i_sb)
+		    && item_moved(&tmp_ih, &path)) {
+			goto research;
+		}
 	}
-	memcpy (p, B_I_PITEM (bh, ih) + path.pos_in_item, chars);
+	p += offset;
+	memset(p, 0, inode->i_sb->s_blocksize);
+	do {
+		if (!is_direct_le_ih(ih)) {
+			BUG();
+		}
+		/* make sure we don't read more bytes than actually exist in
+		 ** the file.  This can happen in odd cases where i_size isn't
+		 ** correct, and when direct item padding results in a few 
+		 ** extra bytes at the end of the direct item
+		 */
+		if ((le_ih_k_offset(ih) + path.pos_in_item) > inode->i_size)
+			break;
+		if ((le_ih_k_offset(ih) - 1 + ih_item_len(ih)) > inode->i_size) {
+			chars =
+			    inode->i_size - (le_ih_k_offset(ih) - 1) -
+			    path.pos_in_item;
+			done = 1;
+		} else {
+			chars = ih_item_len(ih) - path.pos_in_item;
+		}
+		memcpy(p, B_I_PITEM(bh, ih) + path.pos_in_item, chars);
 
-	if (done) 
-	    break ;
+		if (done)
+			break;
 
-	p += chars;
+		p += chars;
 
-	if (PATH_LAST_POSITION (&path) != (B_NR_ITEMS (bh) - 1))
-	    // we done, if read direct item is not the last item of
-	    // node FIXME: we could try to check right delimiting key
-	    // to see whether direct item continues in the right
-	    // neighbor or rely on i_size
-	    break;
-
-	// update key to look for the next piece
-	set_cpu_key_k_offset (&key, cpu_key_k_offset (&key) + chars);
-	if (search_for_position_by_key (inode->i_sb, &key, &path) != POSITION_FOUND)
-	    // we read something from tail, even if now we got IO_ERROR
-	    break;
-	bh = get_last_bh (&path);
-	ih = get_ih (&path);
-    } while (1);
-
-    flush_dcache_page(bh_result->b_page) ;
-    kunmap(bh_result->b_page) ;
-
-finished:
-    pathrelse (&path);
-    /* this buffer has valid data, but isn't valid for io.  mapping it to
-     * block #0 tells the rest of reiserfs it just has a tail in it
-     */
-    map_bh(bh_result, inode->i_sb, 0);
-    set_buffer_uptodate (bh_result);
-    return 0;
-}
+		if (PATH_LAST_POSITION(&path) != (B_NR_ITEMS(bh) - 1))
+			// we done, if read direct item is not the last item of
+			// node FIXME: we could try to check right delimiting key
+			// to see whether direct item continues in the right
+			// neighbor or rely on i_size
+			break;
+
+		// update key to look for the next piece
+		set_cpu_key_k_offset(&key, cpu_key_k_offset(&key) + chars);
+		result = search_for_position_by_key(inode->i_sb, &key, &path);
+		if (result != POSITION_FOUND)
+			// i/o error most likely
+			break;
+		bh = get_last_bh(&path);
+		ih = get_ih(&path);
+	} while (1);
+
+	flush_dcache_page(bh_result->b_page);
+	kunmap(bh_result->b_page);
 
+      finished:
+	pathrelse(&path);
+
+	if (result == IO_ERROR)
+		return -EIO;
+
+	/* this buffer has valid data, but isn't valid for io.  mapping it to
+	 * block #0 tells the rest of reiserfs it just has a tail in it
+	 */
+	map_bh(bh_result, inode->i_sb, 0);
+	set_buffer_uptodate(bh_result);
+	return 0;
+}
 
 // this is called to create file map. So, _get_block_create_0 will not
 // read direct item
-static int reiserfs_bmap (struct inode * inode, sector_t block,
-			  struct buffer_head * bh_result, int create)
+static int reiserfs_bmap(struct inode *inode, sector_t block,
+			 struct buffer_head *bh_result, int create)
 {
-    if (!file_capable (inode, block))
-	return -EFBIG;
+	if (!file_capable(inode, block))
+		return -EFBIG;
 
-    reiserfs_write_lock(inode->i_sb);
-    /* do not read the direct item */
-    _get_block_create_0 (inode, block, bh_result, 0) ;
-    reiserfs_write_unlock(inode->i_sb);
-    return 0;
+	reiserfs_write_lock(inode->i_sb);
+	/* do not read the direct item */
+	_get_block_create_0(inode, block, bh_result, 0);
+	reiserfs_write_unlock(inode->i_sb);
+	return 0;
 }
 
 /* special version of get_block that is only used by grab_tail_page right
@@ -435,9 +448,11 @@ static int reiserfs_bmap (struct inode *
 ** don't want to send create == GET_BLOCK_NO_HOLE to reiserfs_get_block, 
 ** don't use this function.
 */
-static int reiserfs_get_block_create_0 (struct inode * inode, sector_t block,
-			struct buffer_head * bh_result, int create) {
-    return reiserfs_get_block(inode, block, bh_result, GET_BLOCK_NO_HOLE) ;
+static int reiserfs_get_block_create_0(struct inode *inode, sector_t block,
+				       struct buffer_head *bh_result,
+				       int create)
+{
+	return reiserfs_get_block(inode, block, bh_result, GET_BLOCK_NO_HOLE);
 }
 
 /* This is special helper for reiserfs_get_block in case we are executing
@@ -448,43 +463,42 @@ static int reiserfs_get_blocks_direct_io
 					 struct buffer_head *bh_result,
 					 int create)
 {
-    int ret ;
+	int ret;
 
-    bh_result->b_page = NULL;
+	bh_result->b_page = NULL;
 
-    /* We set the b_size before reiserfs_get_block call since it is
-       referenced in convert_tail_for_hole() that may be called from
-       reiserfs_get_block() */
-    bh_result->b_size = (1 << inode->i_blkbits);
-
-    ret = reiserfs_get_block(inode, iblock, bh_result,
-                             create | GET_BLOCK_NO_DANGLE) ;
-    if (ret)
-        goto out;
-
-    /* don't allow direct io onto tail pages */
-    if (buffer_mapped(bh_result) && bh_result->b_blocknr == 0) {
-        /* make sure future calls to the direct io funcs for this offset
-        ** in the file fail by unmapping the buffer
-        */
-        clear_buffer_mapped(bh_result);
-        ret = -EINVAL ;
-    }
-    /* Possible unpacked tail. Flush the data before pages have
-       disappeared */
-    if (REISERFS_I(inode)->i_flags & i_pack_on_close_mask) {
-        int err;
-        lock_kernel();
-        err = reiserfs_commit_for_inode(inode);
-        REISERFS_I(inode)->i_flags &= ~i_pack_on_close_mask;
-        unlock_kernel();
-        if (err < 0)
-            ret = err;
-    }
-out:
-    return ret ;
-}
+	/* We set the b_size before reiserfs_get_block call since it is
+	   referenced in convert_tail_for_hole() that may be called from
+	   reiserfs_get_block() */
+	bh_result->b_size = (1 << inode->i_blkbits);
 
+	ret = reiserfs_get_block(inode, iblock, bh_result,
+				 create | GET_BLOCK_NO_DANGLE);
+	if (ret)
+		goto out;
+
+	/* don't allow direct io onto tail pages */
+	if (buffer_mapped(bh_result) && bh_result->b_blocknr == 0) {
+		/* make sure future calls to the direct io funcs for this offset
+		 ** in the file fail by unmapping the buffer
+		 */
+		clear_buffer_mapped(bh_result);
+		ret = -EINVAL;
+	}
+	/* Possible unpacked tail. Flush the data before pages have
+	   disappeared */
+	if (REISERFS_I(inode)->i_flags & i_pack_on_close_mask) {
+		int err;
+		lock_kernel();
+		err = reiserfs_commit_for_inode(inode);
+		REISERFS_I(inode)->i_flags &= ~i_pack_on_close_mask;
+		unlock_kernel();
+		if (err < 0)
+			ret = err;
+	}
+      out:
+	return ret;
+}
 
 /*
 ** helper function for when reiserfs_get_block is called for a hole
@@ -496,490 +510,547 @@ out:
 ** you should not be in a transaction, or have any paths held when you
 ** call this.
 */
-static int convert_tail_for_hole(struct inode *inode, 
-                                 struct buffer_head *bh_result,
-				 loff_t tail_offset) {
-    unsigned long index ;
-    unsigned long tail_end ; 
-    unsigned long tail_start ;
-    struct page * tail_page ;
-    struct page * hole_page = bh_result->b_page ;
-    int retval = 0 ;
-
-    if ((tail_offset & (bh_result->b_size - 1)) != 1) 
-        return -EIO ;
-
-    /* always try to read until the end of the block */
-    tail_start = tail_offset & (PAGE_CACHE_SIZE - 1) ;
-    tail_end = (tail_start | (bh_result->b_size - 1)) + 1 ;
-
-    index = tail_offset >> PAGE_CACHE_SHIFT ;
-    /* hole_page can be zero in case of direct_io, we are sure
-       that we cannot get here if we write with O_DIRECT into
-       tail page */
-    if (!hole_page || index != hole_page->index) {
-	tail_page = grab_cache_page(inode->i_mapping, index) ;
-	retval = -ENOMEM;
-	if (!tail_page) {
-	    goto out ;
-	}
-    } else {
-        tail_page = hole_page ;
-    }
-
-    /* we don't have to make sure the conversion did not happen while
-    ** we were locking the page because anyone that could convert
-    ** must first take i_sem.
-    **
-    ** We must fix the tail page for writing because it might have buffers
-    ** that are mapped, but have a block number of 0.  This indicates tail
-    ** data that has been read directly into the page, and block_prepare_write
-    ** won't trigger a get_block in this case.
-    */
-    fix_tail_page_for_writing(tail_page) ;
-    retval = reiserfs_prepare_write(NULL, tail_page, tail_start, tail_end);
-    if (retval)
-        goto unlock ;
-
-    /* tail conversion might change the data in the page */
-    flush_dcache_page(tail_page) ;
-
-    retval = reiserfs_commit_write(NULL, tail_page, tail_start, tail_end) ;
-
-unlock:
-    if (tail_page != hole_page) {
-        unlock_page(tail_page) ;
-	page_cache_release(tail_page) ;
-    }
-out:
-    return retval ;
+static int convert_tail_for_hole(struct inode *inode,
+				 struct buffer_head *bh_result,
+				 loff_t tail_offset)
+{
+	unsigned long index;
+	unsigned long tail_end;
+	unsigned long tail_start;
+	struct page *tail_page;
+	struct page *hole_page = bh_result->b_page;
+	int retval = 0;
+
+	if ((tail_offset & (bh_result->b_size - 1)) != 1)
+		return -EIO;
+
+	/* always try to read until the end of the block */
+	tail_start = tail_offset & (PAGE_CACHE_SIZE - 1);
+	tail_end = (tail_start | (bh_result->b_size - 1)) + 1;
+
+	index = tail_offset >> PAGE_CACHE_SHIFT;
+	/* hole_page can be zero in case of direct_io, we are sure
+	   that we cannot get here if we write with O_DIRECT into
+	   tail page */
+	if (!hole_page || index != hole_page->index) {
+		tail_page = grab_cache_page(inode->i_mapping, index);
+		retval = -ENOMEM;
+		if (!tail_page) {
+			goto out;
+		}
+	} else {
+		tail_page = hole_page;
+	}
+
+	/* we don't have to make sure the conversion did not happen while
+	 ** we were locking the page because anyone that could convert
+	 ** must first take i_sem.
+	 **
+	 ** We must fix the tail page for writing because it might have buffers
+	 ** that are mapped, but have a block number of 0.  This indicates tail
+	 ** data that has been read directly into the page, and block_prepare_write
+	 ** won't trigger a get_block in this case.
+	 */
+	fix_tail_page_for_writing(tail_page);
+	retval = reiserfs_prepare_write(NULL, tail_page, tail_start, tail_end);
+	if (retval)
+		goto unlock;
+
+	/* tail conversion might change the data in the page */
+	flush_dcache_page(tail_page);
+
+	retval = reiserfs_commit_write(NULL, tail_page, tail_start, tail_end);
+
+      unlock:
+	if (tail_page != hole_page) {
+		unlock_page(tail_page);
+		page_cache_release(tail_page);
+	}
+      out:
+	return retval;
 }
 
 static inline int _allocate_block(struct reiserfs_transaction_handle *th,
-			   long block,
-                           struct inode *inode, 
-			   b_blocknr_t *allocated_block_nr, 
-			   struct path * path,
-			   int flags) {
-    BUG_ON (!th->t_trans_id);
-  
+				  long block,
+				  struct inode *inode,
+				  b_blocknr_t * allocated_block_nr,
+				  struct path *path, int flags)
+{
+	BUG_ON(!th->t_trans_id);
+
 #ifdef REISERFS_PREALLOCATE
-    if (!(flags & GET_BLOCK_NO_ISEM)) {
-	return reiserfs_new_unf_blocknrs2(th, inode, allocated_block_nr, path, block);
-    }
+	if (!(flags & GET_BLOCK_NO_ISEM)) {
+		return reiserfs_new_unf_blocknrs2(th, inode, allocated_block_nr,
+						  path, block);
+	}
 #endif
-    return reiserfs_new_unf_blocknrs (th, inode, allocated_block_nr, path, block);
+	return reiserfs_new_unf_blocknrs(th, inode, allocated_block_nr, path,
+					 block);
 }
 
-int reiserfs_get_block (struct inode * inode, sector_t block,
-			struct buffer_head * bh_result, int create)
+int reiserfs_get_block(struct inode *inode, sector_t block,
+		       struct buffer_head *bh_result, int create)
 {
-    int repeat, retval = 0;
-    b_blocknr_t allocated_block_nr = 0;// b_blocknr_t is (unsigned) 32 bit int
-    INITIALIZE_PATH(path);
-    int pos_in_item;
-    struct cpu_key key;
-    struct buffer_head * bh, * unbh = NULL;
-    struct item_head * ih, tmp_ih;
-    __le32 * item;
-    int done;
-    int fs_gen;
-    struct reiserfs_transaction_handle *th = NULL;
-    /* space reserved in transaction batch: 
-        . 3 balancings in direct->indirect conversion
-        . 1 block involved into reiserfs_update_sd()
-       XXX in practically impossible worst case direct2indirect()
-       can incur (much) more than 3 balancings.
-       quota update for user, group */
-    int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3 + 1 + 2 * REISERFS_QUOTA_TRANS_BLOCKS;
-    int version;
-    int dangle = 1;
-    loff_t new_offset = (((loff_t)block) << inode->i_sb->s_blocksize_bits) + 1 ;
-
-				/* bad.... */
-    reiserfs_write_lock(inode->i_sb);
-    version = get_inode_item_key_version (inode);
+	int repeat, retval = 0;
+	b_blocknr_t allocated_block_nr = 0;	// b_blocknr_t is (unsigned) 32 bit int
+	INITIALIZE_PATH(path);
+	int pos_in_item;
+	struct cpu_key key;
+	struct buffer_head *bh, *unbh = NULL;
+	struct item_head *ih, tmp_ih;
+	__le32 *item;
+	int done;
+	int fs_gen;
+	struct reiserfs_transaction_handle *th = NULL;
+	/* space reserved in transaction batch: 
+	   . 3 balancings in direct->indirect conversion
+	   . 1 block involved into reiserfs_update_sd()
+	   XXX in practically impossible worst case direct2indirect()
+	   can incur (much) more than 3 balancings.
+	   quota update for user, group */
+	int jbegin_count =
+	    JOURNAL_PER_BALANCE_CNT * 3 + 1 +
+	    2 * REISERFS_QUOTA_TRANS_BLOCKS(inode->i_sb);
+	int version;
+	int dangle = 1;
+	loff_t new_offset =
+	    (((loff_t) block) << inode->i_sb->s_blocksize_bits) + 1;
 
-    if (block < 0) {
-	reiserfs_write_unlock(inode->i_sb);
-	return -EIO;
-    }
+	/* bad.... */
+	reiserfs_write_lock(inode->i_sb);
+	version = get_inode_item_key_version(inode);
 
-    if (!file_capable (inode, block)) {
-	reiserfs_write_unlock(inode->i_sb);
-	return -EFBIG;
-    }
+	if (block < 0) {
+		reiserfs_write_unlock(inode->i_sb);
+		return -EIO;
+	}
 
-    /* if !create, we aren't changing the FS, so we don't need to
-    ** log anything, so we don't need to start a transaction
-    */
-    if (!(create & GET_BLOCK_CREATE)) {
-	int ret ;
-	/* find number of block-th logical block of the file */
-	ret = _get_block_create_0 (inode, block, bh_result, 
-	                           create | GET_BLOCK_READ_DIRECT) ;
-	reiserfs_write_unlock(inode->i_sb);
-	return ret;
-    }
-    /*
-     * if we're already in a transaction, make sure to close
-     * any new transactions we start in this func
-     */
-    if ((create & GET_BLOCK_NO_DANGLE) ||
-        reiserfs_transaction_running(inode->i_sb))
-        dangle = 0;
-
-    /* If file is of such a size, that it might have a tail and tails are enabled
-    ** we should mark it as possibly needing tail packing on close
-    */
-    if ( (have_large_tails (inode->i_sb) && inode->i_size < i_block_size (inode)*4) ||
-	 (have_small_tails (inode->i_sb) && inode->i_size < i_block_size(inode)) )
-	REISERFS_I(inode)->i_flags |= i_pack_on_close_mask ;
-
-    /* set the key of the first byte in the 'block'-th block of file */
-    make_cpu_key (&key, inode, new_offset,
-		  TYPE_ANY, 3/*key length*/);
-    if ((new_offset + inode->i_sb->s_blocksize - 1) > inode->i_size) {
-start_trans:
-	th = reiserfs_persistent_transaction(inode->i_sb, jbegin_count);
-	if (!th) {
-	    retval = -ENOMEM;
-	    goto failure;
+	if (!file_capable(inode, block)) {
+		reiserfs_write_unlock(inode->i_sb);
+		return -EFBIG;
 	}
-	reiserfs_update_inode_transaction(inode) ;
-    }
- research:
-
-    retval = search_for_position_by_key (inode->i_sb, &key, &path);
-    if (retval == IO_ERROR) {
-	retval = -EIO;
-	goto failure;
-    }
-	
-    bh = get_last_bh (&path);
-    ih = get_ih (&path);
-    item = get_item (&path);
-    pos_in_item = path.pos_in_item;
 
-    fs_gen = get_generation (inode->i_sb);
-    copy_item_head (&tmp_ih, ih);
+	/* if !create, we aren't changing the FS, so we don't need to
+	 ** log anything, so we don't need to start a transaction
+	 */
+	if (!(create & GET_BLOCK_CREATE)) {
+		int ret;
+		/* find number of block-th logical block of the file */
+		ret = _get_block_create_0(inode, block, bh_result,
+					  create | GET_BLOCK_READ_DIRECT);
+		reiserfs_write_unlock(inode->i_sb);
+		return ret;
+	}
+	/*
+	 * if we're already in a transaction, make sure to close
+	 * any new transactions we start in this func
+	 */
+	if ((create & GET_BLOCK_NO_DANGLE) ||
+	    reiserfs_transaction_running(inode->i_sb))
+		dangle = 0;
 
-    if (allocation_needed (retval, allocated_block_nr, ih, item, pos_in_item)) {
-	/* we have to allocate block for the unformatted node */
-	if (!th) {
-	    pathrelse(&path) ;
-	    goto start_trans;
+	/* If file is of such a size, that it might have a tail and tails are enabled
+	 ** we should mark it as possibly needing tail packing on close
+	 */
+	if ((have_large_tails(inode->i_sb)
+	     && inode->i_size < i_block_size(inode) * 4)
+	    || (have_small_tails(inode->i_sb)
+		&& inode->i_size < i_block_size(inode)))
+		REISERFS_I(inode)->i_flags |= i_pack_on_close_mask;
+
+	/* set the key of the first byte in the 'block'-th block of file */
+	make_cpu_key(&key, inode, new_offset, TYPE_ANY, 3 /*key length */ );
+	if ((new_offset + inode->i_sb->s_blocksize - 1) > inode->i_size) {
+	      start_trans:
+		th = reiserfs_persistent_transaction(inode->i_sb, jbegin_count);
+		if (!th) {
+			retval = -ENOMEM;
+			goto failure;
+		}
+		reiserfs_update_inode_transaction(inode);
 	}
+      research:
 
-	repeat = _allocate_block(th, block, inode, &allocated_block_nr, &path, create);
+	retval = search_for_position_by_key(inode->i_sb, &key, &path);
+	if (retval == IO_ERROR) {
+		retval = -EIO;
+		goto failure;
+	}
 
-	if (repeat == NO_DISK_SPACE || repeat == QUOTA_EXCEEDED) {
-	    /* restart the transaction to give the journal a chance to free
-	    ** some blocks.  releases the path, so we have to go back to
-	    ** research if we succeed on the second try
-	    */
-	    SB_JOURNAL(inode->i_sb)->j_next_async_flush = 1;
-	    retval = restart_transaction(th, inode, &path) ;
-            if (retval)
-                goto failure;
-	    repeat = _allocate_block(th, block, inode, &allocated_block_nr, NULL, create);
-
-	    if (repeat != NO_DISK_SPACE && repeat != QUOTA_EXCEEDED) {
-		goto research ;
-	    }
-	    if (repeat == QUOTA_EXCEEDED)
-		retval = -EDQUOT;
-	    else
-		retval = -ENOSPC;
-	    goto failure;
-	}
-
-	if (fs_changed (fs_gen, inode->i_sb) && item_moved (&tmp_ih, &path)) {
-	    goto research;
-	}
-    }
-
-    if (indirect_item_found (retval, ih)) {
-        b_blocknr_t unfm_ptr;
-	/* 'block'-th block is in the file already (there is
-	   corresponding cell in some indirect item). But it may be
-	   zero unformatted node pointer (hole) */
-        unfm_ptr = get_block_num (item, pos_in_item);
-	if (unfm_ptr == 0) {
-	    /* use allocated block to plug the hole */
-	    reiserfs_prepare_for_journal(inode->i_sb, bh, 1) ;
-	    if (fs_changed (fs_gen, inode->i_sb) && item_moved (&tmp_ih, &path)) {
-		reiserfs_restore_prepared_buffer(inode->i_sb, bh) ;
-		goto research;
-	    }
-	    set_buffer_new(bh_result);
-	    if (buffer_dirty(bh_result) && reiserfs_data_ordered(inode->i_sb))
-	    	reiserfs_add_ordered_list(inode, bh_result);
-	    put_block_num(item, pos_in_item, allocated_block_nr) ;
-            unfm_ptr = allocated_block_nr;
-	    journal_mark_dirty (th, inode->i_sb, bh);
-	    reiserfs_update_sd(th, inode) ;
-	}
-	set_block_dev_mapped(bh_result, unfm_ptr, inode);
-	pathrelse (&path);
-        retval = 0;
-	if (!dangle && th)
-	    retval = reiserfs_end_persistent_transaction(th);
+	bh = get_last_bh(&path);
+	ih = get_ih(&path);
+	item = get_item(&path);
+	pos_in_item = path.pos_in_item;
 
-	reiserfs_write_unlock(inode->i_sb);
-	 
-	/* the item was found, so new blocks were not added to the file
-	** there is no need to make sure the inode is updated with this 
-	** transaction
-	*/
-	return retval;
-    }
+	fs_gen = get_generation(inode->i_sb);
+	copy_item_head(&tmp_ih, ih);
 
-    if (!th) {
-	pathrelse(&path) ;
-	goto start_trans;
-    }
-
-    /* desired position is not found or is in the direct item. We have
-       to append file with holes up to 'block'-th block converting
-       direct items to indirect one if necessary */
-    done = 0;
-    do {
-	if (is_statdata_le_ih (ih)) {
-	    __le32 unp = 0;
-	    struct cpu_key tmp_key;
-
-	    /* indirect item has to be inserted */
-	    make_le_item_head (&tmp_ih, &key, version, 1, TYPE_INDIRECT, 
-			       UNFM_P_SIZE, 0/* free_space */);
-
-	    if (cpu_key_k_offset (&key) == 1) {
-		/* we are going to add 'block'-th block to the file. Use
-		   allocated block for that */
-		unp = cpu_to_le32 (allocated_block_nr);
-		set_block_dev_mapped (bh_result, allocated_block_nr, inode);
-		set_buffer_new(bh_result);
-		done = 1;
-	    }
-	    tmp_key = key; // ;)
-	    set_cpu_key_k_offset (&tmp_key, 1);
-	    PATH_LAST_POSITION(&path) ++;
-
-	    retval = reiserfs_insert_item (th, &path, &tmp_key, &tmp_ih, inode, (char *)&unp);
-	    if (retval) {
-		reiserfs_free_block (th, inode, allocated_block_nr, 1);
-		goto failure; // retval == -ENOSPC, -EDQUOT or -EIO or -EEXIST
-	    }
-	    //mark_tail_converted (inode);
-	} else if (is_direct_le_ih (ih)) {
-	    /* direct item has to be converted */
-	    loff_t tail_offset;
-
-	    tail_offset = ((le_ih_k_offset (ih) - 1) & ~(inode->i_sb->s_blocksize - 1)) + 1;
-	    if (tail_offset == cpu_key_k_offset (&key)) {
-		/* direct item we just found fits into block we have
-                   to map. Convert it into unformatted node: use
-                   bh_result for the conversion */
-		set_block_dev_mapped (bh_result, allocated_block_nr, inode);
-		unbh = bh_result;
-		done = 1;
-	    } else {
-		/* we have to padd file tail stored in direct item(s)
-		   up to block size and convert it to unformatted
-		   node. FIXME: this should also get into page cache */
+	if (allocation_needed
+	    (retval, allocated_block_nr, ih, item, pos_in_item)) {
+		/* we have to allocate block for the unformatted node */
+		if (!th) {
+			pathrelse(&path);
+			goto start_trans;
+		}
 
-		pathrelse(&path) ;
-		/*
-		 * ugly, but we can only end the transaction if
-		 * we aren't nested
-		 */
-		BUG_ON (!th->t_refcount);
-		if (th->t_refcount == 1) {
-		    retval = reiserfs_end_persistent_transaction(th);
-		    th = NULL;
-		    if (retval)
+		repeat =
+		    _allocate_block(th, block, inode, &allocated_block_nr,
+				    &path, create);
+
+		if (repeat == NO_DISK_SPACE || repeat == QUOTA_EXCEEDED) {
+			/* restart the transaction to give the journal a chance to free
+			 ** some blocks.  releases the path, so we have to go back to
+			 ** research if we succeed on the second try
+			 */
+			SB_JOURNAL(inode->i_sb)->j_next_async_flush = 1;
+			retval = restart_transaction(th, inode, &path);
+			if (retval)
+				goto failure;
+			repeat =
+			    _allocate_block(th, block, inode,
+					    &allocated_block_nr, NULL, create);
+
+			if (repeat != NO_DISK_SPACE && repeat != QUOTA_EXCEEDED) {
+				goto research;
+			}
+			if (repeat == QUOTA_EXCEEDED)
+				retval = -EDQUOT;
+			else
+				retval = -ENOSPC;
 			goto failure;
 		}
 
-		retval = convert_tail_for_hole(inode, bh_result, tail_offset) ;
-		if (retval) {
-		    if ( retval != -ENOSPC )
-			reiserfs_warning (inode->i_sb, "clm-6004: convert tail failed inode %lu, error %d", inode->i_ino, retval) ;
-		    if (allocated_block_nr) {
-			/* the bitmap, the super, and the stat data == 3 */
-			if (!th)
-			    th = reiserfs_persistent_transaction(inode->i_sb,3);
-			if (th)
-			    reiserfs_free_block (th,inode,allocated_block_nr,1);
-		    }
-		    goto failure ;
-		}
-		goto research ;
-	    }
-	    retval = direct2indirect (th, inode, &path, unbh, tail_offset);
-	    if (retval) {
-		reiserfs_unmap_buffer(unbh);
-		reiserfs_free_block (th, inode, allocated_block_nr, 1);
-		goto failure;
-	    }
-	    /* it is important the set_buffer_uptodate is done after
-	    ** the direct2indirect.  The buffer might contain valid
-	    ** data newer than the data on disk (read by readpage, changed,
-	    ** and then sent here by writepage).  direct2indirect needs
-	    ** to know if unbh was already up to date, so it can decide
-	    ** if the data in unbh needs to be replaced with data from
-	    ** the disk
-	    */
-	    set_buffer_uptodate (unbh);
-
-	    /* unbh->b_page == NULL in case of DIRECT_IO request, this means
-	       buffer will disappear shortly, so it should not be added to
-	     */
-	    if ( unbh->b_page ) {
-		/* we've converted the tail, so we must
-		** flush unbh before the transaction commits
-		*/
-		reiserfs_add_tail_list(inode, unbh) ;
-
-		/* mark it dirty now to prevent commit_write from adding
-		** this buffer to the inode's dirty buffer list
-		*/
-		/*
-		 * AKPM: changed __mark_buffer_dirty to mark_buffer_dirty().
-		 * It's still atomic, but it sets the page dirty too,
-		 * which makes it eligible for writeback at any time by the
-		 * VM (which was also the case with __mark_buffer_dirty())
-		 */
-		mark_buffer_dirty(unbh) ;
-	    }
-	} else {
-	    /* append indirect item with holes if needed, when appending
-	       pointer to 'block'-th block use block, which is already
-	       allocated */
-	    struct cpu_key tmp_key;
-	    unp_t unf_single=0; // We use this in case we need to allocate only
-				// one block which is a fastpath
-	    unp_t *un;
-	    __u64 max_to_insert=MAX_ITEM_LEN(inode->i_sb->s_blocksize)/UNFM_P_SIZE;
-	    __u64 blocks_needed;
-
-	    RFALSE( pos_in_item != ih_item_len(ih) / UNFM_P_SIZE,
-		    "vs-804: invalid position for append");
-	    /* indirect item has to be appended, set up key of that position */
-	    make_cpu_key (&tmp_key, inode,
-			  le_key_k_offset (version, &(ih->ih_key)) + op_bytes_number (ih, inode->i_sb->s_blocksize),
-			  //pos_in_item * inode->i_sb->s_blocksize,
-			  TYPE_INDIRECT, 3);// key type is unimportant
-
-	    blocks_needed = 1 + ((cpu_key_k_offset (&key) - cpu_key_k_offset (&tmp_key)) >> inode->i_sb->s_blocksize_bits);
-	    RFALSE( blocks_needed < 0, "green-805: invalid offset");
-
-	    if ( blocks_needed == 1 ) {
-		un = &unf_single;
-	    } else {
-		un=kmalloc( min(blocks_needed,max_to_insert)*UNFM_P_SIZE,
-			    GFP_ATOMIC); // We need to avoid scheduling.
-		if ( !un) {
-		    un = &unf_single;
-		    blocks_needed = 1;
-		    max_to_insert = 0;
-		} else
-		    memset(un, 0, UNFM_P_SIZE * min(blocks_needed,max_to_insert));
-	    }
-	    if ( blocks_needed <= max_to_insert) {
-		/* we are going to add target block to the file. Use allocated
-		   block for that */
-		un[blocks_needed-1] = cpu_to_le32 (allocated_block_nr);
-		set_block_dev_mapped (bh_result, allocated_block_nr, inode);
-		set_buffer_new(bh_result);
-		done = 1;
-	    } else {
-		/* paste hole to the indirect item */
-		/* If kmalloc failed, max_to_insert becomes zero and it means we
-		   only have space for one block */
-		blocks_needed=max_to_insert?max_to_insert:1;
-	    }
-	    retval = reiserfs_paste_into_item (th, &path, &tmp_key, inode, (char *)un, UNFM_P_SIZE * blocks_needed);
+		if (fs_changed(fs_gen, inode->i_sb)
+		    && item_moved(&tmp_ih, &path)) {
+			goto research;
+		}
+	}
 
-	    if (blocks_needed != 1)
-		kfree(un);
+	if (indirect_item_found(retval, ih)) {
+		b_blocknr_t unfm_ptr;
+		/* 'block'-th block is in the file already (there is
+		   corresponding cell in some indirect item). But it may be
+		   zero unformatted node pointer (hole) */
+		unfm_ptr = get_block_num(item, pos_in_item);
+		if (unfm_ptr == 0) {
+			/* use allocated block to plug the hole */
+			reiserfs_prepare_for_journal(inode->i_sb, bh, 1);
+			if (fs_changed(fs_gen, inode->i_sb)
+			    && item_moved(&tmp_ih, &path)) {
+				reiserfs_restore_prepared_buffer(inode->i_sb,
+								 bh);
+				goto research;
+			}
+			set_buffer_new(bh_result);
+			if (buffer_dirty(bh_result)
+			    && reiserfs_data_ordered(inode->i_sb))
+				reiserfs_add_ordered_list(inode, bh_result);
+			put_block_num(item, pos_in_item, allocated_block_nr);
+			unfm_ptr = allocated_block_nr;
+			journal_mark_dirty(th, inode->i_sb, bh);
+			reiserfs_update_sd(th, inode);
+		}
+		set_block_dev_mapped(bh_result, unfm_ptr, inode);
+		pathrelse(&path);
+		retval = 0;
+		if (!dangle && th)
+			retval = reiserfs_end_persistent_transaction(th);
 
-	    if (retval) {
-		reiserfs_free_block (th, inode, allocated_block_nr, 1);
-		goto failure;
-	    }
-	    if (!done) {
-		/* We need to mark new file size in case this function will be
-		   interrupted/aborted later on. And we may do this only for
-		   holes. */
-		inode->i_size += inode->i_sb->s_blocksize * blocks_needed;
-	    }
-	}
-
-	if (done == 1)
-	    break;
-
-	/* this loop could log more blocks than we had originally asked
-	** for.  So, we have to allow the transaction to end if it is
-	** too big or too full.  Update the inode so things are 
-	** consistent if we crash before the function returns
-	**
-	** release the path so that anybody waiting on the path before
-	** ending their transaction will be able to continue.
-	*/
-	if (journal_transaction_should_end(th, th->t_blocks_allocated)) {
-	  retval = restart_transaction(th, inode, &path) ;
-	  if (retval)
-	    goto failure;
-	}
-	/* inserting indirect pointers for a hole can take a 
-	** long time.  reschedule if needed
-	*/
-	cond_resched();
+		reiserfs_write_unlock(inode->i_sb);
 
-	retval = search_for_position_by_key (inode->i_sb, &key, &path);
-	if (retval == IO_ERROR) {
-	    retval = -EIO;
-	    goto failure;
+		/* the item was found, so new blocks were not added to the file
+		 ** there is no need to make sure the inode is updated with this 
+		 ** transaction
+		 */
+		return retval;
 	}
-	if (retval == POSITION_FOUND) {
-	    reiserfs_warning (inode->i_sb, "vs-825: reiserfs_get_block: "
-			      "%K should not be found", &key);
-	    retval = -EEXIST;
-	    if (allocated_block_nr)
-	        reiserfs_free_block (th, inode, allocated_block_nr, 1);
-	    pathrelse(&path) ;
-	    goto failure;
-	}
-	bh = get_last_bh (&path);
-	ih = get_ih (&path);
-	item = get_item (&path);
-	pos_in_item = path.pos_in_item;
-    } while (1);
 
+	if (!th) {
+		pathrelse(&path);
+		goto start_trans;
+	}
+
+	/* desired position is not found or is in the direct item. We have
+	   to append file with holes up to 'block'-th block converting
+	   direct items to indirect one if necessary */
+	done = 0;
+	do {
+		if (is_statdata_le_ih(ih)) {
+			__le32 unp = 0;
+			struct cpu_key tmp_key;
+
+			/* indirect item has to be inserted */
+			make_le_item_head(&tmp_ih, &key, version, 1,
+					  TYPE_INDIRECT, UNFM_P_SIZE,
+					  0 /* free_space */ );
+
+			if (cpu_key_k_offset(&key) == 1) {
+				/* we are going to add 'block'-th block to the file. Use
+				   allocated block for that */
+				unp = cpu_to_le32(allocated_block_nr);
+				set_block_dev_mapped(bh_result,
+						     allocated_block_nr, inode);
+				set_buffer_new(bh_result);
+				done = 1;
+			}
+			tmp_key = key;	// ;)
+			set_cpu_key_k_offset(&tmp_key, 1);
+			PATH_LAST_POSITION(&path)++;
+
+			retval =
+			    reiserfs_insert_item(th, &path, &tmp_key, &tmp_ih,
+						 inode, (char *)&unp);
+			if (retval) {
+				reiserfs_free_block(th, inode,
+						    allocated_block_nr, 1);
+				goto failure;	// retval == -ENOSPC, -EDQUOT or -EIO or -EEXIST
+			}
+			//mark_tail_converted (inode);
+		} else if (is_direct_le_ih(ih)) {
+			/* direct item has to be converted */
+			loff_t tail_offset;
+
+			tail_offset =
+			    ((le_ih_k_offset(ih) -
+			      1) & ~(inode->i_sb->s_blocksize - 1)) + 1;
+			if (tail_offset == cpu_key_k_offset(&key)) {
+				/* direct item we just found fits into block we have
+				   to map. Convert it into unformatted node: use
+				   bh_result for the conversion */
+				set_block_dev_mapped(bh_result,
+						     allocated_block_nr, inode);
+				unbh = bh_result;
+				done = 1;
+			} else {
+				/* we have to padd file tail stored in direct item(s)
+				   up to block size and convert it to unformatted
+				   node. FIXME: this should also get into page cache */
+
+				pathrelse(&path);
+				/*
+				 * ugly, but we can only end the transaction if
+				 * we aren't nested
+				 */
+				BUG_ON(!th->t_refcount);
+				if (th->t_refcount == 1) {
+					retval =
+					    reiserfs_end_persistent_transaction
+					    (th);
+					th = NULL;
+					if (retval)
+						goto failure;
+				}
+
+				retval =
+				    convert_tail_for_hole(inode, bh_result,
+							  tail_offset);
+				if (retval) {
+					if (retval != -ENOSPC)
+						reiserfs_warning(inode->i_sb,
+								 "clm-6004: convert tail failed inode %lu, error %d",
+								 inode->i_ino,
+								 retval);
+					if (allocated_block_nr) {
+						/* the bitmap, the super, and the stat data == 3 */
+						if (!th)
+							th = reiserfs_persistent_transaction(inode->i_sb, 3);
+						if (th)
+							reiserfs_free_block(th,
+									    inode,
+									    allocated_block_nr,
+									    1);
+					}
+					goto failure;
+				}
+				goto research;
+			}
+			retval =
+			    direct2indirect(th, inode, &path, unbh,
+					    tail_offset);
+			if (retval) {
+				reiserfs_unmap_buffer(unbh);
+				reiserfs_free_block(th, inode,
+						    allocated_block_nr, 1);
+				goto failure;
+			}
+			/* it is important the set_buffer_uptodate is done after
+			 ** the direct2indirect.  The buffer might contain valid
+			 ** data newer than the data on disk (read by readpage, changed,
+			 ** and then sent here by writepage).  direct2indirect needs
+			 ** to know if unbh was already up to date, so it can decide
+			 ** if the data in unbh needs to be replaced with data from
+			 ** the disk
+			 */
+			set_buffer_uptodate(unbh);
+
+			/* unbh->b_page == NULL in case of DIRECT_IO request, this means
+			   buffer will disappear shortly, so it should not be added to
+			 */
+			if (unbh->b_page) {
+				/* we've converted the tail, so we must
+				 ** flush unbh before the transaction commits
+				 */
+				reiserfs_add_tail_list(inode, unbh);
+
+				/* mark it dirty now to prevent commit_write from adding
+				 ** this buffer to the inode's dirty buffer list
+				 */
+				/*
+				 * AKPM: changed __mark_buffer_dirty to mark_buffer_dirty().
+				 * It's still atomic, but it sets the page dirty too,
+				 * which makes it eligible for writeback at any time by the
+				 * VM (which was also the case with __mark_buffer_dirty())
+				 */
+				mark_buffer_dirty(unbh);
+			}
+		} else {
+			/* append indirect item with holes if needed, when appending
+			   pointer to 'block'-th block use block, which is already
+			   allocated */
+			struct cpu_key tmp_key;
+			unp_t unf_single = 0;	// We use this in case we need to allocate only
+			// one block which is a fastpath
+			unp_t *un;
+			__u64 max_to_insert =
+			    MAX_ITEM_LEN(inode->i_sb->s_blocksize) /
+			    UNFM_P_SIZE;
+			__u64 blocks_needed;
+
+			RFALSE(pos_in_item != ih_item_len(ih) / UNFM_P_SIZE,
+			       "vs-804: invalid position for append");
+			/* indirect item has to be appended, set up key of that position */
+			make_cpu_key(&tmp_key, inode,
+				     le_key_k_offset(version,
+						     &(ih->ih_key)) +
+				     op_bytes_number(ih,
+						     inode->i_sb->s_blocksize),
+				     //pos_in_item * inode->i_sb->s_blocksize,
+				     TYPE_INDIRECT, 3);	// key type is unimportant
+
+			blocks_needed =
+			    1 +
+			    ((cpu_key_k_offset(&key) -
+			      cpu_key_k_offset(&tmp_key)) >> inode->i_sb->
+			     s_blocksize_bits);
+			RFALSE(blocks_needed < 0, "green-805: invalid offset");
+
+			if (blocks_needed == 1) {
+				un = &unf_single;
+			} else {
+				un = kmalloc(min(blocks_needed, max_to_insert) * UNFM_P_SIZE, GFP_ATOMIC);	// We need to avoid scheduling.
+				if (!un) {
+					un = &unf_single;
+					blocks_needed = 1;
+					max_to_insert = 0;
+				} else
+					memset(un, 0,
+					       UNFM_P_SIZE * min(blocks_needed,
+								 max_to_insert));
+			}
+			if (blocks_needed <= max_to_insert) {
+				/* we are going to add target block to the file. Use allocated
+				   block for that */
+				un[blocks_needed - 1] =
+				    cpu_to_le32(allocated_block_nr);
+				set_block_dev_mapped(bh_result,
+						     allocated_block_nr, inode);
+				set_buffer_new(bh_result);
+				done = 1;
+			} else {
+				/* paste hole to the indirect item */
+				/* If kmalloc failed, max_to_insert becomes zero and it means we
+				   only have space for one block */
+				blocks_needed =
+				    max_to_insert ? max_to_insert : 1;
+			}
+			retval =
+			    reiserfs_paste_into_item(th, &path, &tmp_key, inode,
+						     (char *)un,
+						     UNFM_P_SIZE *
+						     blocks_needed);
+
+			if (blocks_needed != 1)
+				kfree(un);
+
+			if (retval) {
+				reiserfs_free_block(th, inode,
+						    allocated_block_nr, 1);
+				goto failure;
+			}
+			if (!done) {
+				/* We need to mark new file size in case this function will be
+				   interrupted/aborted later on. And we may do this only for
+				   holes. */
+				inode->i_size +=
+				    inode->i_sb->s_blocksize * blocks_needed;
+			}
+		}
+
+		if (done == 1)
+			break;
 
-    retval = 0;
+		/* this loop could log more blocks than we had originally asked
+		 ** for.  So, we have to allow the transaction to end if it is
+		 ** too big or too full.  Update the inode so things are 
+		 ** consistent if we crash before the function returns
+		 **
+		 ** release the path so that anybody waiting on the path before
+		 ** ending their transaction will be able to continue.
+		 */
+		if (journal_transaction_should_end(th, th->t_blocks_allocated)) {
+			retval = restart_transaction(th, inode, &path);
+			if (retval)
+				goto failure;
+		}
+		/* inserting indirect pointers for a hole can take a 
+		 ** long time.  reschedule if needed
+		 */
+		cond_resched();
+
+		retval = search_for_position_by_key(inode->i_sb, &key, &path);
+		if (retval == IO_ERROR) {
+			retval = -EIO;
+			goto failure;
+		}
+		if (retval == POSITION_FOUND) {
+			reiserfs_warning(inode->i_sb,
+					 "vs-825: reiserfs_get_block: "
+					 "%K should not be found", &key);
+			retval = -EEXIST;
+			if (allocated_block_nr)
+				reiserfs_free_block(th, inode,
+						    allocated_block_nr, 1);
+			pathrelse(&path);
+			goto failure;
+		}
+		bh = get_last_bh(&path);
+		ih = get_ih(&path);
+		item = get_item(&path);
+		pos_in_item = path.pos_in_item;
+	} while (1);
+
+	retval = 0;
+
+      failure:
+	if (th && (!dangle || (retval && !th->t_trans_id))) {
+		int err;
+		if (th->t_trans_id)
+			reiserfs_update_sd(th, inode);
+		err = reiserfs_end_persistent_transaction(th);
+		if (err)
+			retval = err;
+	}
 
- failure:
-    if (th && (!dangle || (retval && !th->t_trans_id))) {
-        int err;
-        if (th->t_trans_id)
-            reiserfs_update_sd(th, inode);
-        err = reiserfs_end_persistent_transaction(th);
-        if (err)
-            retval = err;
-    }
-
-    reiserfs_write_unlock(inode->i_sb);
-    reiserfs_check_path(&path) ;
-    return retval;
+	reiserfs_write_unlock(inode->i_sb);
+	reiserfs_check_path(&path);
+	return retval;
 }
 
 static int
 reiserfs_readpages(struct file *file, struct address_space *mapping,
-		struct list_head *pages, unsigned nr_pages)
+		   struct list_head *pages, unsigned nr_pages)
 {
-    return mpage_readpages(mapping, pages, nr_pages, reiserfs_get_block);
+	return mpage_readpages(mapping, pages, nr_pages, reiserfs_get_block);
 }
 
 /* Compute real number of used bytes by file
@@ -987,51 +1058,56 @@ reiserfs_readpages(struct file *file, st
  */
 static int real_space_diff(struct inode *inode, int sd_size)
 {
-    int bytes;
-    loff_t blocksize = inode->i_sb->s_blocksize ;
+	int bytes;
+	loff_t blocksize = inode->i_sb->s_blocksize;
 
-    if (S_ISLNK(inode->i_mode) || S_ISDIR(inode->i_mode))
-        return sd_size ;
+	if (S_ISLNK(inode->i_mode) || S_ISDIR(inode->i_mode))
+		return sd_size;
 
-    /* End of file is also in full block with indirect reference, so round
-    ** up to the next block.
-    **
-    ** there is just no way to know if the tail is actually packed
-    ** on the file, so we have to assume it isn't.  When we pack the
-    ** tail, we add 4 bytes to pretend there really is an unformatted
-    ** node pointer
-    */
-    bytes = ((inode->i_size + (blocksize-1)) >> inode->i_sb->s_blocksize_bits) * UNFM_P_SIZE + sd_size;
-    return bytes ;
+	/* End of file is also in full block with indirect reference, so round
+	 ** up to the next block.
+	 **
+	 ** there is just no way to know if the tail is actually packed
+	 ** on the file, so we have to assume it isn't.  When we pack the
+	 ** tail, we add 4 bytes to pretend there really is an unformatted
+	 ** node pointer
+	 */
+	bytes =
+	    ((inode->i_size +
+	      (blocksize - 1)) >> inode->i_sb->s_blocksize_bits) * UNFM_P_SIZE +
+	    sd_size;
+	return bytes;
 }
 
 static inline loff_t to_real_used_space(struct inode *inode, ulong blocks,
-                                        int sd_size)
+					int sd_size)
 {
-    if (S_ISLNK(inode->i_mode) || S_ISDIR(inode->i_mode)) {
-        return inode->i_size + (loff_t)(real_space_diff(inode, sd_size)) ;
-    }
-    return ((loff_t)real_space_diff(inode, sd_size)) + (((loff_t)blocks) << 9);
+	if (S_ISLNK(inode->i_mode) || S_ISDIR(inode->i_mode)) {
+		return inode->i_size +
+		    (loff_t) (real_space_diff(inode, sd_size));
+	}
+	return ((loff_t) real_space_diff(inode, sd_size)) +
+	    (((loff_t) blocks) << 9);
 }
 
 /* Compute number of blocks used by file in ReiserFS counting */
 static inline ulong to_fake_used_blocks(struct inode *inode, int sd_size)
 {
-    loff_t bytes = inode_get_bytes(inode) ;
-    loff_t real_space = real_space_diff(inode, sd_size) ;
+	loff_t bytes = inode_get_bytes(inode);
+	loff_t real_space = real_space_diff(inode, sd_size);
 
-    /* keeps fsck and non-quota versions of reiserfs happy */
-    if (S_ISLNK(inode->i_mode) || S_ISDIR(inode->i_mode)) {
-        bytes += (loff_t)511 ;
-    }
-
-    /* files from before the quota patch might i_blocks such that
-    ** bytes < real_space.  Deal with that here to prevent it from
-    ** going negative.
-    */
-    if (bytes < real_space)
-        return 0 ;
-    return (bytes - real_space) >> 9;
+	/* keeps fsck and non-quota versions of reiserfs happy */
+	if (S_ISLNK(inode->i_mode) || S_ISDIR(inode->i_mode)) {
+		bytes += (loff_t) 511;
+	}
+
+	/* files from before the quota patch might i_blocks such that
+	 ** bytes < real_space.  Deal with that here to prevent it from
+	 ** going negative.
+	 */
+	if (bytes < real_space)
+		return 0;
+	return (bytes - real_space) >> 9;
 }
 
 //
@@ -1042,263 +1118,269 @@ static inline ulong to_fake_used_blocks(
 //
 
 // called by read_locked_inode
-static void init_inode (struct inode * inode, struct path * path)
+static void init_inode(struct inode *inode, struct path *path)
 {
-    struct buffer_head * bh;
-    struct item_head * ih;
-    __u32 rdev;
-    //int version = ITEM_VERSION_1;
-
-    bh = PATH_PLAST_BUFFER (path);
-    ih = PATH_PITEM_HEAD (path);
-
-
-    copy_key (INODE_PKEY (inode), &(ih->ih_key));
-    inode->i_blksize = reiserfs_default_io_size;
-
-    INIT_LIST_HEAD(&(REISERFS_I(inode)->i_prealloc_list ));
-    REISERFS_I(inode)->i_flags = 0;
-    REISERFS_I(inode)->i_prealloc_block = 0;
-    REISERFS_I(inode)->i_prealloc_count = 0;
-    REISERFS_I(inode)->i_trans_id = 0;
-    REISERFS_I(inode)->i_jl = NULL;
-    REISERFS_I(inode)->i_acl_access = NULL;
-    REISERFS_I(inode)->i_acl_default = NULL;
-    init_rwsem (&REISERFS_I(inode)->xattr_sem);
-
-    if (stat_data_v1 (ih)) {
-	struct stat_data_v1 * sd = (struct stat_data_v1 *)B_I_PITEM (bh, ih);
-	unsigned long blocks;
-
-	set_inode_item_key_version (inode, KEY_FORMAT_3_5);
-        set_inode_sd_version (inode, STAT_DATA_V1);
-	inode->i_mode  = sd_v1_mode(sd);
-	inode->i_nlink = sd_v1_nlink(sd);
-	inode->i_uid   = sd_v1_uid(sd);
-	inode->i_gid   = sd_v1_gid(sd);
-	inode->i_size  = sd_v1_size(sd);
-	inode->i_atime.tv_sec = sd_v1_atime(sd);
-	inode->i_mtime.tv_sec = sd_v1_mtime(sd);
-	inode->i_ctime.tv_sec = sd_v1_ctime(sd);
-	inode->i_atime.tv_nsec = 0;
-	inode->i_ctime.tv_nsec = 0;
-	inode->i_mtime.tv_nsec = 0;
-
-	inode->i_blocks = sd_v1_blocks(sd);
-	inode->i_generation = le32_to_cpu (INODE_PKEY (inode)->k_dir_id);
-	blocks = (inode->i_size + 511) >> 9;
-	blocks = _ROUND_UP (blocks, inode->i_sb->s_blocksize >> 9);
-	if (inode->i_blocks > blocks) {
-	    // there was a bug in <=3.5.23 when i_blocks could take negative
-	    // values. Starting from 3.5.17 this value could even be stored in
-	    // stat data. For such files we set i_blocks based on file
-	    // size. Just 2 notes: this can be wrong for sparce files. On-disk value will be
-	    // only updated if file's inode will ever change
-	    inode->i_blocks = blocks;
-	}
-
-        rdev = sd_v1_rdev(sd);
-	REISERFS_I(inode)->i_first_direct_byte = sd_v1_first_direct_byte(sd);
-	/* an early bug in the quota code can give us an odd number for the
-	** block count.  This is incorrect, fix it here.
-	*/
-	if (inode->i_blocks & 1) {
-	    inode->i_blocks++ ;
-	}
-	inode_set_bytes(inode, to_real_used_space(inode, inode->i_blocks,
-	                                          SD_V1_SIZE));
-	/* nopack is initially zero for v1 objects. For v2 objects,
-	   nopack is initialised from sd_attrs */
-	REISERFS_I(inode)->i_flags &= ~i_nopack_mask;
-    } else {
-	// new stat data found, but object may have old items
-	// (directories and symlinks)
-	struct stat_data * sd = (struct stat_data *)B_I_PITEM (bh, ih);
-
-	inode->i_mode   = sd_v2_mode(sd);
-	inode->i_nlink  = sd_v2_nlink(sd);
-	inode->i_uid    = sd_v2_uid(sd);
-	inode->i_size   = sd_v2_size(sd);
-	inode->i_gid    = sd_v2_gid(sd);
-	inode->i_mtime.tv_sec  = sd_v2_mtime(sd);
-	inode->i_atime.tv_sec = sd_v2_atime(sd);
-	inode->i_ctime.tv_sec  = sd_v2_ctime(sd);
-	inode->i_ctime.tv_nsec = 0;
-	inode->i_mtime.tv_nsec = 0;
-	inode->i_atime.tv_nsec = 0;
-	inode->i_blocks = sd_v2_blocks(sd);
-        rdev            = sd_v2_rdev(sd);
-	if( S_ISCHR( inode -> i_mode ) || S_ISBLK( inode -> i_mode ) )
-	    inode->i_generation = le32_to_cpu (INODE_PKEY (inode)->k_dir_id);
-	else
-            inode->i_generation = sd_v2_generation(sd);
+	struct buffer_head *bh;
+	struct item_head *ih;
+	__u32 rdev;
+	//int version = ITEM_VERSION_1;
+
+	bh = PATH_PLAST_BUFFER(path);
+	ih = PATH_PITEM_HEAD(path);
+
+	copy_key(INODE_PKEY(inode), &(ih->ih_key));
+	inode->i_blksize = reiserfs_default_io_size;
+
+	INIT_LIST_HEAD(&(REISERFS_I(inode)->i_prealloc_list));
+	REISERFS_I(inode)->i_flags = 0;
+	REISERFS_I(inode)->i_prealloc_block = 0;
+	REISERFS_I(inode)->i_prealloc_count = 0;
+	REISERFS_I(inode)->i_trans_id = 0;
+	REISERFS_I(inode)->i_jl = NULL;
+	REISERFS_I(inode)->i_acl_access = NULL;
+	REISERFS_I(inode)->i_acl_default = NULL;
+	init_rwsem(&REISERFS_I(inode)->xattr_sem);
+
+	if (stat_data_v1(ih)) {
+		struct stat_data_v1 *sd =
+		    (struct stat_data_v1 *)B_I_PITEM(bh, ih);
+		unsigned long blocks;
+
+		set_inode_item_key_version(inode, KEY_FORMAT_3_5);
+		set_inode_sd_version(inode, STAT_DATA_V1);
+		inode->i_mode = sd_v1_mode(sd);
+		inode->i_nlink = sd_v1_nlink(sd);
+		inode->i_uid = sd_v1_uid(sd);
+		inode->i_gid = sd_v1_gid(sd);
+		inode->i_size = sd_v1_size(sd);
+		inode->i_atime.tv_sec = sd_v1_atime(sd);
+		inode->i_mtime.tv_sec = sd_v1_mtime(sd);
+		inode->i_ctime.tv_sec = sd_v1_ctime(sd);
+		inode->i_atime.tv_nsec = 0;
+		inode->i_ctime.tv_nsec = 0;
+		inode->i_mtime.tv_nsec = 0;
+
+		inode->i_blocks = sd_v1_blocks(sd);
+		inode->i_generation = le32_to_cpu(INODE_PKEY(inode)->k_dir_id);
+		blocks = (inode->i_size + 511) >> 9;
+		blocks = _ROUND_UP(blocks, inode->i_sb->s_blocksize >> 9);
+		if (inode->i_blocks > blocks) {
+			// there was a bug in <=3.5.23 when i_blocks could take negative
+			// values. Starting from 3.5.17 this value could even be stored in
+			// stat data. For such files we set i_blocks based on file
+			// size. Just 2 notes: this can be wrong for sparce files. On-disk value will be
+			// only updated if file's inode will ever change
+			inode->i_blocks = blocks;
+		}
 
-	if (S_ISDIR (inode->i_mode) || S_ISLNK (inode->i_mode))
-	    set_inode_item_key_version (inode, KEY_FORMAT_3_5);
-	else
-	    set_inode_item_key_version (inode, KEY_FORMAT_3_6);
-	REISERFS_I(inode)->i_first_direct_byte = 0;
-	set_inode_sd_version (inode, STAT_DATA_V2);
-	inode_set_bytes(inode, to_real_used_space(inode, inode->i_blocks,
-	                                          SD_V2_SIZE));
-	/* read persistent inode attributes from sd and initalise
-	   generic inode flags from them */
-	REISERFS_I(inode)->i_attrs = sd_v2_attrs( sd );
-	sd_attrs_to_i_attrs( sd_v2_attrs( sd ), inode );
-    }
-
-    pathrelse (path);
-    if (S_ISREG (inode->i_mode)) {
-	inode->i_op = &reiserfs_file_inode_operations;
-	inode->i_fop = &reiserfs_file_operations;
-	inode->i_mapping->a_ops = &reiserfs_address_space_operations ;
-    } else if (S_ISDIR (inode->i_mode)) {
-	inode->i_op = &reiserfs_dir_inode_operations;
-	inode->i_fop = &reiserfs_dir_operations;
-    } else if (S_ISLNK (inode->i_mode)) {
-	inode->i_op = &reiserfs_symlink_inode_operations;
-	inode->i_mapping->a_ops = &reiserfs_address_space_operations;
-    } else {
-	inode->i_blocks = 0;
-	inode->i_op = &reiserfs_special_inode_operations;
-	init_special_inode(inode, inode->i_mode, new_decode_dev(rdev));
-    }
-}
+		rdev = sd_v1_rdev(sd);
+		REISERFS_I(inode)->i_first_direct_byte =
+		    sd_v1_first_direct_byte(sd);
+		/* an early bug in the quota code can give us an odd number for the
+		 ** block count.  This is incorrect, fix it here.
+		 */
+		if (inode->i_blocks & 1) {
+			inode->i_blocks++;
+		}
+		inode_set_bytes(inode,
+				to_real_used_space(inode, inode->i_blocks,
+						   SD_V1_SIZE));
+		/* nopack is initially zero for v1 objects. For v2 objects,
+		   nopack is initialised from sd_attrs */
+		REISERFS_I(inode)->i_flags &= ~i_nopack_mask;
+	} else {
+		// new stat data found, but object may have old items
+		// (directories and symlinks)
+		struct stat_data *sd = (struct stat_data *)B_I_PITEM(bh, ih);
+
+		inode->i_mode = sd_v2_mode(sd);
+		inode->i_nlink = sd_v2_nlink(sd);
+		inode->i_uid = sd_v2_uid(sd);
+		inode->i_size = sd_v2_size(sd);
+		inode->i_gid = sd_v2_gid(sd);
+		inode->i_mtime.tv_sec = sd_v2_mtime(sd);
+		inode->i_atime.tv_sec = sd_v2_atime(sd);
+		inode->i_ctime.tv_sec = sd_v2_ctime(sd);
+		inode->i_ctime.tv_nsec = 0;
+		inode->i_mtime.tv_nsec = 0;
+		inode->i_atime.tv_nsec = 0;
+		inode->i_blocks = sd_v2_blocks(sd);
+		rdev = sd_v2_rdev(sd);
+		if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
+			inode->i_generation =
+			    le32_to_cpu(INODE_PKEY(inode)->k_dir_id);
+		else
+			inode->i_generation = sd_v2_generation(sd);
 
+		if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode))
+			set_inode_item_key_version(inode, KEY_FORMAT_3_5);
+		else
+			set_inode_item_key_version(inode, KEY_FORMAT_3_6);
+		REISERFS_I(inode)->i_first_direct_byte = 0;
+		set_inode_sd_version(inode, STAT_DATA_V2);
+		inode_set_bytes(inode,
+				to_real_used_space(inode, inode->i_blocks,
+						   SD_V2_SIZE));
+		/* read persistent inode attributes from sd and initalise
+		   generic inode flags from them */
+		REISERFS_I(inode)->i_attrs = sd_v2_attrs(sd);
+		sd_attrs_to_i_attrs(sd_v2_attrs(sd), inode);
+	}
+
+	pathrelse(path);
+	if (S_ISREG(inode->i_mode)) {
+		inode->i_op = &reiserfs_file_inode_operations;
+		inode->i_fop = &reiserfs_file_operations;
+		inode->i_mapping->a_ops = &reiserfs_address_space_operations;
+	} else if (S_ISDIR(inode->i_mode)) {
+		inode->i_op = &reiserfs_dir_inode_operations;
+		inode->i_fop = &reiserfs_dir_operations;
+	} else if (S_ISLNK(inode->i_mode)) {
+		inode->i_op = &reiserfs_symlink_inode_operations;
+		inode->i_mapping->a_ops = &reiserfs_address_space_operations;
+	} else {
+		inode->i_blocks = 0;
+		inode->i_op = &reiserfs_special_inode_operations;
+		init_special_inode(inode, inode->i_mode, new_decode_dev(rdev));
+	}
+}
 
 // update new stat data with inode fields
-static void inode2sd (void * sd, struct inode * inode, loff_t size)
+static void inode2sd(void *sd, struct inode *inode, loff_t size)
 {
-    struct stat_data * sd_v2 = (struct stat_data *)sd;
-    __u16 flags;
+	struct stat_data *sd_v2 = (struct stat_data *)sd;
+	__u16 flags;
 
-    set_sd_v2_mode(sd_v2, inode->i_mode );
-    set_sd_v2_nlink(sd_v2, inode->i_nlink );
-    set_sd_v2_uid(sd_v2, inode->i_uid );
-    set_sd_v2_size(sd_v2, size );
-    set_sd_v2_gid(sd_v2, inode->i_gid );
-    set_sd_v2_mtime(sd_v2, inode->i_mtime.tv_sec );
-    set_sd_v2_atime(sd_v2, inode->i_atime.tv_sec );
-    set_sd_v2_ctime(sd_v2, inode->i_ctime.tv_sec );
-    set_sd_v2_blocks(sd_v2, to_fake_used_blocks(inode, SD_V2_SIZE));
-    if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
-	set_sd_v2_rdev(sd_v2, new_encode_dev(inode->i_rdev));
-    else
-	set_sd_v2_generation(sd_v2, inode->i_generation);
-    flags = REISERFS_I(inode)->i_attrs;
-    i_attrs_to_sd_attrs( inode, &flags );
-    set_sd_v2_attrs( sd_v2, flags );
+	set_sd_v2_mode(sd_v2, inode->i_mode);
+	set_sd_v2_nlink(sd_v2, inode->i_nlink);
+	set_sd_v2_uid(sd_v2, inode->i_uid);
+	set_sd_v2_size(sd_v2, size);
+	set_sd_v2_gid(sd_v2, inode->i_gid);
+	set_sd_v2_mtime(sd_v2, inode->i_mtime.tv_sec);
+	set_sd_v2_atime(sd_v2, inode->i_atime.tv_sec);
+	set_sd_v2_ctime(sd_v2, inode->i_ctime.tv_sec);
+	set_sd_v2_blocks(sd_v2, to_fake_used_blocks(inode, SD_V2_SIZE));
+	if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
+		set_sd_v2_rdev(sd_v2, new_encode_dev(inode->i_rdev));
+	else
+		set_sd_v2_generation(sd_v2, inode->i_generation);
+	flags = REISERFS_I(inode)->i_attrs;
+	i_attrs_to_sd_attrs(inode, &flags);
+	set_sd_v2_attrs(sd_v2, flags);
 }
 
-
 // used to copy inode's fields to old stat data
-static void inode2sd_v1 (void * sd, struct inode * inode, loff_t size)
+static void inode2sd_v1(void *sd, struct inode *inode, loff_t size)
 {
-    struct stat_data_v1 * sd_v1 = (struct stat_data_v1 *)sd;
+	struct stat_data_v1 *sd_v1 = (struct stat_data_v1 *)sd;
 
-    set_sd_v1_mode(sd_v1, inode->i_mode );
-    set_sd_v1_uid(sd_v1, inode->i_uid );
-    set_sd_v1_gid(sd_v1, inode->i_gid );
-    set_sd_v1_nlink(sd_v1, inode->i_nlink );
-    set_sd_v1_size(sd_v1, size );
-    set_sd_v1_atime(sd_v1, inode->i_atime.tv_sec );
-    set_sd_v1_ctime(sd_v1, inode->i_ctime.tv_sec );
-    set_sd_v1_mtime(sd_v1, inode->i_mtime.tv_sec );
-
-    if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
-        set_sd_v1_rdev(sd_v1, new_encode_dev(inode->i_rdev));
-    else
-        set_sd_v1_blocks(sd_v1, to_fake_used_blocks(inode, SD_V1_SIZE));
+	set_sd_v1_mode(sd_v1, inode->i_mode);
+	set_sd_v1_uid(sd_v1, inode->i_uid);
+	set_sd_v1_gid(sd_v1, inode->i_gid);
+	set_sd_v1_nlink(sd_v1, inode->i_nlink);
+	set_sd_v1_size(sd_v1, size);
+	set_sd_v1_atime(sd_v1, inode->i_atime.tv_sec);
+	set_sd_v1_ctime(sd_v1, inode->i_ctime.tv_sec);
+	set_sd_v1_mtime(sd_v1, inode->i_mtime.tv_sec);
 
-    // Sigh. i_first_direct_byte is back
-    set_sd_v1_first_direct_byte(sd_v1, REISERFS_I(inode)->i_first_direct_byte);
-}
+	if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
+		set_sd_v1_rdev(sd_v1, new_encode_dev(inode->i_rdev));
+	else
+		set_sd_v1_blocks(sd_v1, to_fake_used_blocks(inode, SD_V1_SIZE));
 
+	// Sigh. i_first_direct_byte is back
+	set_sd_v1_first_direct_byte(sd_v1,
+				    REISERFS_I(inode)->i_first_direct_byte);
+}
 
 /* NOTE, you must prepare the buffer head before sending it here,
 ** and then log it after the call
 */
-static void update_stat_data (struct path * path, struct inode * inode,
-                              loff_t size)
+static void update_stat_data(struct path *path, struct inode *inode,
+			     loff_t size)
 {
-    struct buffer_head * bh;
-    struct item_head * ih;
-  
-    bh = PATH_PLAST_BUFFER (path);
-    ih = PATH_PITEM_HEAD (path);
-
-    if (!is_statdata_le_ih (ih))
-	reiserfs_panic (inode->i_sb, "vs-13065: update_stat_data: key %k, found item %h",
-			INODE_PKEY (inode), ih);
-  
-    if (stat_data_v1 (ih)) {
-	// path points to old stat data
-	inode2sd_v1 (B_I_PITEM (bh, ih), inode, size);
-    } else {
-	inode2sd (B_I_PITEM (bh, ih), inode, size);
-    }
-
-    return;
+	struct buffer_head *bh;
+	struct item_head *ih;
+
+	bh = PATH_PLAST_BUFFER(path);
+	ih = PATH_PITEM_HEAD(path);
+
+	if (!is_statdata_le_ih(ih))
+		reiserfs_panic(inode->i_sb,
+			       "vs-13065: update_stat_data: key %k, found item %h",
+			       INODE_PKEY(inode), ih);
+
+	if (stat_data_v1(ih)) {
+		// path points to old stat data
+		inode2sd_v1(B_I_PITEM(bh, ih), inode, size);
+	} else {
+		inode2sd(B_I_PITEM(bh, ih), inode, size);
+	}
+
+	return;
 }
 
+void reiserfs_update_sd_size(struct reiserfs_transaction_handle *th,
+			     struct inode *inode, loff_t size)
+{
+	struct cpu_key key;
+	INITIALIZE_PATH(path);
+	struct buffer_head *bh;
+	int fs_gen;
+	struct item_head *ih, tmp_ih;
+	int retval;
+
+	BUG_ON(!th->t_trans_id);
+
+	make_cpu_key(&key, inode, SD_OFFSET, TYPE_STAT_DATA, 3);	//key type is unimportant
+
+	for (;;) {
+		int pos;
+		/* look for the object's stat data */
+		retval = search_item(inode->i_sb, &key, &path);
+		if (retval == IO_ERROR) {
+			reiserfs_warning(inode->i_sb,
+					 "vs-13050: reiserfs_update_sd: "
+					 "i/o failure occurred trying to update %K stat data",
+					 &key);
+			return;
+		}
+		if (retval == ITEM_NOT_FOUND) {
+			pos = PATH_LAST_POSITION(&path);
+			pathrelse(&path);
+			if (inode->i_nlink == 0) {
+				/*reiserfs_warning (inode->i_sb, "vs-13050: reiserfs_update_sd: i_nlink == 0, stat data not found"); */
+				return;
+			}
+			reiserfs_warning(inode->i_sb,
+					 "vs-13060: reiserfs_update_sd: "
+					 "stat data of object %k (nlink == %d) not found (pos %d)",
+					 INODE_PKEY(inode), inode->i_nlink,
+					 pos);
+			reiserfs_check_path(&path);
+			return;
+		}
 
-void reiserfs_update_sd_size (struct reiserfs_transaction_handle *th,
-			      struct inode * inode, loff_t size)
-{
-    struct cpu_key key;
-    INITIALIZE_PATH(path);
-    struct buffer_head *bh ;
-    int fs_gen ;
-    struct item_head *ih, tmp_ih ;
-    int retval;
-
-    BUG_ON (!th->t_trans_id);
-
-    make_cpu_key (&key, inode, SD_OFFSET, TYPE_STAT_DATA, 3);//key type is unimportant
-    
-    for(;;) {
-	int pos;
-	/* look for the object's stat data */
-	retval = search_item (inode->i_sb, &key, &path);
-	if (retval == IO_ERROR) {
-	    reiserfs_warning (inode->i_sb, "vs-13050: reiserfs_update_sd: "
-			      "i/o failure occurred trying to update %K stat data",
-			      &key);
-	    return;
-	}
-	if (retval == ITEM_NOT_FOUND) {
-	    pos = PATH_LAST_POSITION (&path);
-	    pathrelse(&path) ;
-	    if (inode->i_nlink == 0) {
-		/*reiserfs_warning (inode->i_sb, "vs-13050: reiserfs_update_sd: i_nlink == 0, stat data not found");*/
-		return;
-	    }
-	    reiserfs_warning (inode->i_sb, "vs-13060: reiserfs_update_sd: "
-			      "stat data of object %k (nlink == %d) not found (pos %d)",
-			      INODE_PKEY (inode), inode->i_nlink, pos);
-	    reiserfs_check_path(&path) ;
-	    return;
-	}
-	
-	/* sigh, prepare_for_journal might schedule.  When it schedules the
-	** FS might change.  We have to detect that, and loop back to the
-	** search if the stat data item has moved
-	*/
-	bh = get_last_bh(&path) ;
-	ih = get_ih(&path) ;
-	copy_item_head (&tmp_ih, ih);
-	fs_gen = get_generation (inode->i_sb);
-	reiserfs_prepare_for_journal(inode->i_sb, bh, 1) ;
-	if (fs_changed (fs_gen, inode->i_sb) && item_moved(&tmp_ih, &path)) {
-	    reiserfs_restore_prepared_buffer(inode->i_sb, bh) ;
-	    continue ;	/* Stat_data item has been moved after scheduling. */
-	}
-	break;
-    }
-    update_stat_data (&path, inode, size);
-    journal_mark_dirty(th, th->t_super, bh) ; 
-    pathrelse (&path);
-    return;
+		/* sigh, prepare_for_journal might schedule.  When it schedules the
+		 ** FS might change.  We have to detect that, and loop back to the
+		 ** search if the stat data item has moved
+		 */
+		bh = get_last_bh(&path);
+		ih = get_ih(&path);
+		copy_item_head(&tmp_ih, ih);
+		fs_gen = get_generation(inode->i_sb);
+		reiserfs_prepare_for_journal(inode->i_sb, bh, 1);
+		if (fs_changed(fs_gen, inode->i_sb)
+		    && item_moved(&tmp_ih, &path)) {
+			reiserfs_restore_prepared_buffer(inode->i_sb, bh);
+			continue;	/* Stat_data item has been moved after scheduling. */
+		}
+		break;
+	}
+	update_stat_data(&path, inode, size);
+	journal_mark_dirty(th, th->t_super, bh);
+	pathrelse(&path);
+	return;
 }
 
 /* reiserfs_read_locked_inode is called to read the inode off disk, and it
@@ -1307,9 +1389,10 @@ void reiserfs_update_sd_size (struct rei
 ** corresponding iput might try to delete whatever object the inode last
 ** represented.
 */
-static void reiserfs_make_bad_inode(struct inode *inode) {
-    memset(INODE_PKEY(inode), 0, KEY_SIZE);
-    make_bad_inode(inode);
+static void reiserfs_make_bad_inode(struct inode *inode)
+{
+	memset(INODE_PKEY(inode), 0, KEY_SIZE);
+	make_bad_inode(inode);
 }
 
 //
@@ -1317,77 +1400,79 @@ static void reiserfs_make_bad_inode(stru
 // evolved as the prototype did
 //
 
-int reiserfs_init_locked_inode (struct inode * inode, void *p)
+int reiserfs_init_locked_inode(struct inode *inode, void *p)
 {
-    struct reiserfs_iget_args *args = (struct reiserfs_iget_args *)p ;
-    inode->i_ino = args->objectid;
-    INODE_PKEY(inode)->k_dir_id = cpu_to_le32(args->dirid);
-    return 0;
+	struct reiserfs_iget_args *args = (struct reiserfs_iget_args *)p;
+	inode->i_ino = args->objectid;
+	INODE_PKEY(inode)->k_dir_id = cpu_to_le32(args->dirid);
+	return 0;
 }
 
 /* looks for stat data in the tree, and fills up the fields of in-core
    inode stat data fields */
-void reiserfs_read_locked_inode (struct inode * inode, struct reiserfs_iget_args *args)
+void reiserfs_read_locked_inode(struct inode *inode,
+				struct reiserfs_iget_args *args)
 {
-    INITIALIZE_PATH (path_to_sd);
-    struct cpu_key key;
-    unsigned long dirino;
-    int retval;
-
-    dirino = args->dirid ;
-
-    /* set version 1, version 2 could be used too, because stat data
-       key is the same in both versions */
-    key.version = KEY_FORMAT_3_5;
-    key.on_disk_key.k_dir_id = dirino;
-    key.on_disk_key.k_objectid = inode->i_ino;
-    key.on_disk_key.k_offset = 0;
-    key.on_disk_key.k_type = 0;
-
-    /* look for the object's stat data */
-    retval = search_item (inode->i_sb, &key, &path_to_sd);
-    if (retval == IO_ERROR) {
-	reiserfs_warning (inode->i_sb, "vs-13070: reiserfs_read_locked_inode: "
-			  "i/o failure occurred trying to find stat data of %K",
-			  &key);
-	reiserfs_make_bad_inode(inode) ;
-	return;
-    }
-    if (retval != ITEM_FOUND) {
-	/* a stale NFS handle can trigger this without it being an error */
-	pathrelse (&path_to_sd);
-	reiserfs_make_bad_inode(inode) ;
-	inode->i_nlink = 0;
-	return;
-    }
+	INITIALIZE_PATH(path_to_sd);
+	struct cpu_key key;
+	unsigned long dirino;
+	int retval;
+
+	dirino = args->dirid;
+
+	/* set version 1, version 2 could be used too, because stat data
+	   key is the same in both versions */
+	key.version = KEY_FORMAT_3_5;
+	key.on_disk_key.k_dir_id = dirino;
+	key.on_disk_key.k_objectid = inode->i_ino;
+	key.on_disk_key.k_offset = 0;
+	key.on_disk_key.k_type = 0;
+
+	/* look for the object's stat data */
+	retval = search_item(inode->i_sb, &key, &path_to_sd);
+	if (retval == IO_ERROR) {
+		reiserfs_warning(inode->i_sb,
+				 "vs-13070: reiserfs_read_locked_inode: "
+				 "i/o failure occurred trying to find stat data of %K",
+				 &key);
+		reiserfs_make_bad_inode(inode);
+		return;
+	}
+	if (retval != ITEM_FOUND) {
+		/* a stale NFS handle can trigger this without it being an error */
+		pathrelse(&path_to_sd);
+		reiserfs_make_bad_inode(inode);
+		inode->i_nlink = 0;
+		return;
+	}
+
+	init_inode(inode, &path_to_sd);
 
-    init_inode (inode, &path_to_sd);
-   
-    /* It is possible that knfsd is trying to access inode of a file
-       that is being removed from the disk by some other thread. As we
-       update sd on unlink all that is required is to check for nlink
-       here. This bug was first found by Sizif when debugging
-       SquidNG/Butterfly, forgotten, and found again after Philippe
-       Gramoulle <philippe.gramoulle@mmania.com> reproduced it. 
-
-       More logical fix would require changes in fs/inode.c:iput() to
-       remove inode from hash-table _after_ fs cleaned disk stuff up and
-       in iget() to return NULL if I_FREEING inode is found in
-       hash-table. */
-    /* Currently there is one place where it's ok to meet inode with
-       nlink==0: processing of open-unlinked and half-truncated files
-       during mount (fs/reiserfs/super.c:finish_unfinished()). */
-    if( ( inode -> i_nlink == 0 ) && 
-	! REISERFS_SB(inode -> i_sb) -> s_is_unlinked_ok ) {
-	    reiserfs_warning (inode->i_sb,
-			      "vs-13075: reiserfs_read_locked_inode: "
-			      "dead inode read from disk %K. "
-			      "This is likely to be race with knfsd. Ignore",
-			      &key );
-	    reiserfs_make_bad_inode( inode );
-    }
+	/* It is possible that knfsd is trying to access inode of a file
+	   that is being removed from the disk by some other thread. As we
+	   update sd on unlink all that is required is to check for nlink
+	   here. This bug was first found by Sizif when debugging
+	   SquidNG/Butterfly, forgotten, and found again after Philippe
+	   Gramoulle <philippe.gramoulle@mmania.com> reproduced it. 
+
+	   More logical fix would require changes in fs/inode.c:iput() to
+	   remove inode from hash-table _after_ fs cleaned disk stuff up and
+	   in iget() to return NULL if I_FREEING inode is found in
+	   hash-table. */
+	/* Currently there is one place where it's ok to meet inode with
+	   nlink==0: processing of open-unlinked and half-truncated files
+	   during mount (fs/reiserfs/super.c:finish_unfinished()). */
+	if ((inode->i_nlink == 0) &&
+	    !REISERFS_SB(inode->i_sb)->s_is_unlinked_ok) {
+		reiserfs_warning(inode->i_sb,
+				 "vs-13075: reiserfs_read_locked_inode: "
+				 "dead inode read from disk %K. "
+				 "This is likely to be race with knfsd. Ignore",
+				 &key);
+		reiserfs_make_bad_inode(inode);
+	}
 
-    reiserfs_check_path(&path_to_sd) ; /* init inode should be relsing */
+	reiserfs_check_path(&path_to_sd);	/* init inode should be relsing */
 
 }
 
@@ -1403,140 +1488,148 @@ void reiserfs_read_locked_inode (struct 
  * inode numbers (objectids) are distinguished by parent directory ids.
  *
  */
-int reiserfs_find_actor( struct inode *inode, void *opaque )
+int reiserfs_find_actor(struct inode *inode, void *opaque)
 {
-    struct reiserfs_iget_args *args;
+	struct reiserfs_iget_args *args;
 
-    args = opaque;
-    /* args is already in CPU order */
-    return (inode->i_ino == args->objectid) &&
-	(le32_to_cpu(INODE_PKEY(inode)->k_dir_id) == args->dirid);
-}
-
-struct inode * reiserfs_iget (struct super_block * s, const struct cpu_key * key)
-{
-    struct inode * inode;
-    struct reiserfs_iget_args args ;
-
-    args.objectid = key->on_disk_key.k_objectid ;
-    args.dirid = key->on_disk_key.k_dir_id ;
-    inode = iget5_locked (s, key->on_disk_key.k_objectid, 
-		   reiserfs_find_actor, reiserfs_init_locked_inode, (void *)(&args));
-    if (!inode) 
-	return ERR_PTR(-ENOMEM) ;
-
-    if (inode->i_state & I_NEW) {
-	reiserfs_read_locked_inode(inode, &args);
-	unlock_new_inode(inode);
-    }
-
-    if (comp_short_keys (INODE_PKEY (inode), key) || is_bad_inode (inode)) {
-	/* either due to i/o error or a stale NFS handle */
-	iput (inode);
-	inode = NULL;
-    }
-    return inode;
+	args = opaque;
+	/* args is already in CPU order */
+	return (inode->i_ino == args->objectid) &&
+	    (le32_to_cpu(INODE_PKEY(inode)->k_dir_id) == args->dirid);
 }
 
-struct dentry *reiserfs_get_dentry(struct super_block *sb, void *vobjp)
+struct inode *reiserfs_iget(struct super_block *s, const struct cpu_key *key)
 {
-    __u32 *data = vobjp;
-    struct cpu_key key ;
-    struct dentry *result;
-    struct inode *inode;
-    
-    key.on_disk_key.k_objectid = data[0] ;
-    key.on_disk_key.k_dir_id = data[1] ;
-    reiserfs_write_lock(sb);
-    inode = reiserfs_iget(sb, &key) ;
-    if (inode && !IS_ERR(inode) && data[2] != 0 &&
-	data[2] != inode->i_generation) {
-	    iput(inode) ;
-	    inode = NULL ;
-    }
-    reiserfs_write_unlock(sb);
-    if (!inode)
-	    inode = ERR_PTR(-ESTALE);
-    if (IS_ERR(inode))
-	    return ERR_PTR(PTR_ERR(inode));
-    result = d_alloc_anon(inode);
-    if (!result) {
-	    iput(inode);
-	    return ERR_PTR(-ENOMEM);
-    }
-    return result;
-}
-
-struct dentry *reiserfs_decode_fh(struct super_block *sb, __u32 *data,
-                                     int len, int fhtype,
-				  int (*acceptable)(void *contect, struct dentry *de),
-				  void *context) {
-    __u32 obj[3], parent[3];
-
-    /* fhtype happens to reflect the number of u32s encoded.
-     * due to a bug in earlier code, fhtype might indicate there
-     * are more u32s then actually fitted.
-     * so if fhtype seems to be more than len, reduce fhtype.
-     * Valid types are:
-     *   2 - objectid + dir_id - legacy support
-     *   3 - objectid + dir_id + generation
-     *   4 - objectid + dir_id + objectid and dirid of parent - legacy
-     *   5 - objectid + dir_id + generation + objectid and dirid of parent
-     *   6 - as above plus generation of directory
-     * 6 does not fit in NFSv2 handles
-     */
-    if (fhtype > len) {
-	    if (fhtype != 6 || len != 5)
-		    reiserfs_warning (sb, "nfsd/reiserfs, fhtype=%d, len=%d - odd",
-			   fhtype, len);
-	    fhtype = 5;
-    }
-
-    obj[0] = data[0];
-    obj[1] = data[1];
-    if (fhtype == 3 || fhtype >= 5)
-	    obj[2] = data[2];
-    else    obj[2] = 0; /* generation number */
-
-    if (fhtype >= 4) {
-	    parent[0] = data[fhtype>=5?3:2] ;
-	    parent[1] = data[fhtype>=5?4:3] ;
-	    if (fhtype == 6)
-		    parent[2] = data[5];
-	    else    parent[2] = 0;
-    }
-    return sb->s_export_op->find_exported_dentry(sb, obj, fhtype < 4 ? NULL : parent,
-			       acceptable, context);
-}
-
-int reiserfs_encode_fh(struct dentry *dentry, __u32 *data, int *lenp, int need_parent) {
-    struct inode *inode = dentry->d_inode ;
-    int maxlen = *lenp;
-    
-    if (maxlen < 3)
-        return 255 ;
-
-    data[0] = inode->i_ino ;
-    data[1] = le32_to_cpu(INODE_PKEY (inode)->k_dir_id) ;
-    data[2] = inode->i_generation ;
-    *lenp = 3 ;
-    /* no room for directory info? return what we've stored so far */
-    if (maxlen < 5 || ! need_parent)
-        return 3 ;
-
-    spin_lock(&dentry->d_lock);
-    inode = dentry->d_parent->d_inode ;
-    data[3] = inode->i_ino ;
-    data[4] = le32_to_cpu(INODE_PKEY (inode)->k_dir_id) ;
-    *lenp = 5 ;
-    if (maxlen >= 6) {
-	    data[5] = inode->i_generation ;
-	    *lenp = 6 ;
-    }
-    spin_unlock(&dentry->d_lock);
-    return *lenp ;
+	struct inode *inode;
+	struct reiserfs_iget_args args;
+
+	args.objectid = key->on_disk_key.k_objectid;
+	args.dirid = key->on_disk_key.k_dir_id;
+	inode = iget5_locked(s, key->on_disk_key.k_objectid,
+			     reiserfs_find_actor, reiserfs_init_locked_inode,
+			     (void *)(&args));
+	if (!inode)
+		return ERR_PTR(-ENOMEM);
+
+	if (inode->i_state & I_NEW) {
+		reiserfs_read_locked_inode(inode, &args);
+		unlock_new_inode(inode);
+	}
+
+	if (comp_short_keys(INODE_PKEY(inode), key) || is_bad_inode(inode)) {
+		/* either due to i/o error or a stale NFS handle */
+		iput(inode);
+		inode = NULL;
+	}
+	return inode;
 }
 
+struct dentry *reiserfs_get_dentry(struct super_block *sb, void *vobjp)
+{
+	__u32 *data = vobjp;
+	struct cpu_key key;
+	struct dentry *result;
+	struct inode *inode;
+
+	key.on_disk_key.k_objectid = data[0];
+	key.on_disk_key.k_dir_id = data[1];
+	reiserfs_write_lock(sb);
+	inode = reiserfs_iget(sb, &key);
+	if (inode && !IS_ERR(inode) && data[2] != 0 &&
+	    data[2] != inode->i_generation) {
+		iput(inode);
+		inode = NULL;
+	}
+	reiserfs_write_unlock(sb);
+	if (!inode)
+		inode = ERR_PTR(-ESTALE);
+	if (IS_ERR(inode))
+		return ERR_PTR(PTR_ERR(inode));
+	result = d_alloc_anon(inode);
+	if (!result) {
+		iput(inode);
+		return ERR_PTR(-ENOMEM);
+	}
+	return result;
+}
+
+struct dentry *reiserfs_decode_fh(struct super_block *sb, __u32 * data,
+				  int len, int fhtype,
+				  int (*acceptable) (void *contect,
+						     struct dentry * de),
+				  void *context)
+{
+	__u32 obj[3], parent[3];
+
+	/* fhtype happens to reflect the number of u32s encoded.
+	 * due to a bug in earlier code, fhtype might indicate there
+	 * are more u32s then actually fitted.
+	 * so if fhtype seems to be more than len, reduce fhtype.
+	 * Valid types are:
+	 *   2 - objectid + dir_id - legacy support
+	 *   3 - objectid + dir_id + generation
+	 *   4 - objectid + dir_id + objectid and dirid of parent - legacy
+	 *   5 - objectid + dir_id + generation + objectid and dirid of parent
+	 *   6 - as above plus generation of directory
+	 * 6 does not fit in NFSv2 handles
+	 */
+	if (fhtype > len) {
+		if (fhtype != 6 || len != 5)
+			reiserfs_warning(sb,
+					 "nfsd/reiserfs, fhtype=%d, len=%d - odd",
+					 fhtype, len);
+		fhtype = 5;
+	}
+
+	obj[0] = data[0];
+	obj[1] = data[1];
+	if (fhtype == 3 || fhtype >= 5)
+		obj[2] = data[2];
+	else
+		obj[2] = 0;	/* generation number */
+
+	if (fhtype >= 4) {
+		parent[0] = data[fhtype >= 5 ? 3 : 2];
+		parent[1] = data[fhtype >= 5 ? 4 : 3];
+		if (fhtype == 6)
+			parent[2] = data[5];
+		else
+			parent[2] = 0;
+	}
+	return sb->s_export_op->find_exported_dentry(sb, obj,
+						     fhtype < 4 ? NULL : parent,
+						     acceptable, context);
+}
+
+int reiserfs_encode_fh(struct dentry *dentry, __u32 * data, int *lenp,
+		       int need_parent)
+{
+	struct inode *inode = dentry->d_inode;
+	int maxlen = *lenp;
+
+	if (maxlen < 3)
+		return 255;
+
+	data[0] = inode->i_ino;
+	data[1] = le32_to_cpu(INODE_PKEY(inode)->k_dir_id);
+	data[2] = inode->i_generation;
+	*lenp = 3;
+	/* no room for directory info? return what we've stored so far */
+	if (maxlen < 5 || !need_parent)
+		return 3;
+
+	spin_lock(&dentry->d_lock);
+	inode = dentry->d_parent->d_inode;
+	data[3] = inode->i_ino;
+	data[4] = le32_to_cpu(INODE_PKEY(inode)->k_dir_id);
+	*lenp = 5;
+	if (maxlen >= 6) {
+		data[5] = inode->i_generation;
+		*lenp = 6;
+	}
+	spin_unlock(&dentry->d_lock);
+	return *lenp;
+}
 
 /* looks for stat data, then copies fields to it, marks the buffer
    containing stat data as dirty */
@@ -1545,120 +1638,127 @@ int reiserfs_encode_fh(struct dentry *de
 ** to properly mark inodes for datasync and such, but only actually
 ** does something when called for a synchronous update.
 */
-int reiserfs_write_inode (struct inode * inode, int do_sync) {
-    struct reiserfs_transaction_handle th ;
-    int jbegin_count = 1 ;
-
-    if (inode->i_sb->s_flags & MS_RDONLY)
-        return -EROFS;
-    /* memory pressure can sometimes initiate write_inode calls with sync == 1,
-    ** these cases are just when the system needs ram, not when the 
-    ** inode needs to reach disk for safety, and they can safely be
-    ** ignored because the altered inode has already been logged.
-    */
-    if (do_sync && !(current->flags & PF_MEMALLOC)) {
-	reiserfs_write_lock(inode->i_sb);
-	if (!journal_begin(&th, inode->i_sb, jbegin_count)) {
-            reiserfs_update_sd (&th, inode);
-            journal_end_sync(&th, inode->i_sb, jbegin_count) ;
-        }
-	reiserfs_write_unlock(inode->i_sb);
-    }
-    return 0;
+int reiserfs_write_inode(struct inode *inode, int do_sync)
+{
+	struct reiserfs_transaction_handle th;
+	int jbegin_count = 1;
+
+	if (inode->i_sb->s_flags & MS_RDONLY)
+		return -EROFS;
+	/* memory pressure can sometimes initiate write_inode calls with sync == 1,
+	 ** these cases are just when the system needs ram, not when the 
+	 ** inode needs to reach disk for safety, and they can safely be
+	 ** ignored because the altered inode has already been logged.
+	 */
+	if (do_sync && !(current->flags & PF_MEMALLOC)) {
+		reiserfs_write_lock(inode->i_sb);
+		if (!journal_begin(&th, inode->i_sb, jbegin_count)) {
+			reiserfs_update_sd(&th, inode);
+			journal_end_sync(&th, inode->i_sb, jbegin_count);
+		}
+		reiserfs_write_unlock(inode->i_sb);
+	}
+	return 0;
 }
 
 /* stat data of new object is inserted already, this inserts the item
    containing "." and ".." entries */
-static int reiserfs_new_directory (struct reiserfs_transaction_handle *th, 
-				   struct inode *inode,
-				   struct item_head * ih, struct path * path,
-				   struct inode * dir)
-{
-    struct super_block * sb = th->t_super;
-    char empty_dir [EMPTY_DIR_SIZE];
-    char * body = empty_dir;
-    struct cpu_key key;
-    int retval;
-
-    BUG_ON (!th->t_trans_id);
-    
-    _make_cpu_key (&key, KEY_FORMAT_3_5, le32_to_cpu (ih->ih_key.k_dir_id),
-		   le32_to_cpu (ih->ih_key.k_objectid), DOT_OFFSET, TYPE_DIRENTRY, 3/*key length*/);
-    
-    /* compose item head for new item. Directories consist of items of
-       old type (ITEM_VERSION_1). Do not set key (second arg is 0), it
-       is done by reiserfs_new_inode */
-    if (old_format_only (sb)) {
-	make_le_item_head (ih, NULL, KEY_FORMAT_3_5, DOT_OFFSET, TYPE_DIRENTRY, EMPTY_DIR_SIZE_V1, 2);
-	
-	make_empty_dir_item_v1 (body, ih->ih_key.k_dir_id, ih->ih_key.k_objectid,
-				INODE_PKEY (dir)->k_dir_id, 
-				INODE_PKEY (dir)->k_objectid );
-    } else {
-	make_le_item_head (ih, NULL, KEY_FORMAT_3_5, DOT_OFFSET, TYPE_DIRENTRY, EMPTY_DIR_SIZE, 2);
-	
-	make_empty_dir_item (body, ih->ih_key.k_dir_id, ih->ih_key.k_objectid,
-		   		INODE_PKEY (dir)->k_dir_id, 
-		   		INODE_PKEY (dir)->k_objectid );
-    }
-    
-    /* look for place in the tree for new item */
-    retval = search_item (sb, &key, path);
-    if (retval == IO_ERROR) {
-	reiserfs_warning (sb, "vs-13080: reiserfs_new_directory: "
-			  "i/o failure occurred creating new directory");
-	return -EIO;
-    }
-    if (retval == ITEM_FOUND) {
-	pathrelse (path);
-	reiserfs_warning (sb, "vs-13070: reiserfs_new_directory: "
-			  "object with this key exists (%k)", &(ih->ih_key));
-	return -EEXIST;
-    }
+static int reiserfs_new_directory(struct reiserfs_transaction_handle *th,
+				  struct inode *inode,
+				  struct item_head *ih, struct path *path,
+				  struct inode *dir)
+{
+	struct super_block *sb = th->t_super;
+	char empty_dir[EMPTY_DIR_SIZE];
+	char *body = empty_dir;
+	struct cpu_key key;
+	int retval;
+
+	BUG_ON(!th->t_trans_id);
+
+	_make_cpu_key(&key, KEY_FORMAT_3_5, le32_to_cpu(ih->ih_key.k_dir_id),
+		      le32_to_cpu(ih->ih_key.k_objectid), DOT_OFFSET,
+		      TYPE_DIRENTRY, 3 /*key length */ );
+
+	/* compose item head for new item. Directories consist of items of
+	   old type (ITEM_VERSION_1). Do not set key (second arg is 0), it
+	   is done by reiserfs_new_inode */
+	if (old_format_only(sb)) {
+		make_le_item_head(ih, NULL, KEY_FORMAT_3_5, DOT_OFFSET,
+				  TYPE_DIRENTRY, EMPTY_DIR_SIZE_V1, 2);
+
+		make_empty_dir_item_v1(body, ih->ih_key.k_dir_id,
+				       ih->ih_key.k_objectid,
+				       INODE_PKEY(dir)->k_dir_id,
+				       INODE_PKEY(dir)->k_objectid);
+	} else {
+		make_le_item_head(ih, NULL, KEY_FORMAT_3_5, DOT_OFFSET,
+				  TYPE_DIRENTRY, EMPTY_DIR_SIZE, 2);
 
-    /* insert item, that is empty directory item */
-    return reiserfs_insert_item (th, path, &key, ih, inode, body);
-}
+		make_empty_dir_item(body, ih->ih_key.k_dir_id,
+				    ih->ih_key.k_objectid,
+				    INODE_PKEY(dir)->k_dir_id,
+				    INODE_PKEY(dir)->k_objectid);
+	}
 
+	/* look for place in the tree for new item */
+	retval = search_item(sb, &key, path);
+	if (retval == IO_ERROR) {
+		reiserfs_warning(sb, "vs-13080: reiserfs_new_directory: "
+				 "i/o failure occurred creating new directory");
+		return -EIO;
+	}
+	if (retval == ITEM_FOUND) {
+		pathrelse(path);
+		reiserfs_warning(sb, "vs-13070: reiserfs_new_directory: "
+				 "object with this key exists (%k)",
+				 &(ih->ih_key));
+		return -EEXIST;
+	}
+
+	/* insert item, that is empty directory item */
+	return reiserfs_insert_item(th, path, &key, ih, inode, body);
+}
 
 /* stat data of object has been inserted, this inserts the item
    containing the body of symlink */
-static int reiserfs_new_symlink (struct reiserfs_transaction_handle *th, 
-				 struct inode *inode,	/* Inode of symlink */
-				 struct item_head * ih,
-				 struct path * path, const char * symname, int item_len)
-{
-    struct super_block * sb = th->t_super;
-    struct cpu_key key;
-    int retval;
-
-    BUG_ON (!th->t_trans_id);
-
-    _make_cpu_key (&key, KEY_FORMAT_3_5, 
-		   le32_to_cpu (ih->ih_key.k_dir_id), 
-		   le32_to_cpu (ih->ih_key.k_objectid),
-		   1, TYPE_DIRECT, 3/*key length*/);
-
-    make_le_item_head (ih, NULL, KEY_FORMAT_3_5, 1, TYPE_DIRECT, item_len, 0/*free_space*/);
-
-    /* look for place in the tree for new item */
-    retval = search_item (sb, &key, path);
-    if (retval == IO_ERROR) {
-	reiserfs_warning (sb, "vs-13080: reiserfs_new_symlinik: "
-			  "i/o failure occurred creating new symlink");
-	return -EIO;
-    }
-    if (retval == ITEM_FOUND) {
-	pathrelse (path);
-	reiserfs_warning (sb, "vs-13080: reiserfs_new_symlink: "
-			  "object with this key exists (%k)", &(ih->ih_key));
-	return -EEXIST;
-    }
+static int reiserfs_new_symlink(struct reiserfs_transaction_handle *th, struct inode *inode,	/* Inode of symlink */
+				struct item_head *ih,
+				struct path *path, const char *symname,
+				int item_len)
+{
+	struct super_block *sb = th->t_super;
+	struct cpu_key key;
+	int retval;
+
+	BUG_ON(!th->t_trans_id);
+
+	_make_cpu_key(&key, KEY_FORMAT_3_5,
+		      le32_to_cpu(ih->ih_key.k_dir_id),
+		      le32_to_cpu(ih->ih_key.k_objectid),
+		      1, TYPE_DIRECT, 3 /*key length */ );
 
-    /* insert item, that is body of symlink */
-    return reiserfs_insert_item (th, path, &key, ih, inode, symname);
-}
+	make_le_item_head(ih, NULL, KEY_FORMAT_3_5, 1, TYPE_DIRECT, item_len,
+			  0 /*free_space */ );
 
+	/* look for place in the tree for new item */
+	retval = search_item(sb, &key, path);
+	if (retval == IO_ERROR) {
+		reiserfs_warning(sb, "vs-13080: reiserfs_new_symlinik: "
+				 "i/o failure occurred creating new symlink");
+		return -EIO;
+	}
+	if (retval == ITEM_FOUND) {
+		pathrelse(path);
+		reiserfs_warning(sb, "vs-13080: reiserfs_new_symlink: "
+				 "object with this key exists (%k)",
+				 &(ih->ih_key));
+		return -EEXIST;
+	}
+
+	/* insert item, that is body of symlink */
+	return reiserfs_insert_item(th, path, &key, ih, inode, symname);
+}
 
 /* inserts the stat data into the tree, and then calls
    reiserfs_new_directory (to insert ".", ".." item if new object is
@@ -1669,213 +1769,229 @@ static int reiserfs_new_symlink (struct 
    non-zero due to an error, we have to drop the quota previously allocated
    for the fresh inode.  This can only be done outside a transaction, so
    if we return non-zero, we also end the transaction.  */
-int reiserfs_new_inode (struct reiserfs_transaction_handle *th,
-			struct inode * dir, int mode, 
-			const char * symname, 
-                        /* 0 for regular, EMTRY_DIR_SIZE for dirs, 
-			   strlen (symname) for symlinks)*/
-		         loff_t i_size, struct dentry *dentry, 
-			 struct inode *inode)
-{
-    struct super_block * sb;
-    INITIALIZE_PATH (path_to_key);
-    struct cpu_key key;
-    struct item_head ih;
-    struct stat_data sd;
-    int retval;
-    int err;
-
-    BUG_ON (!th->t_trans_id);
-  
-    if (DQUOT_ALLOC_INODE(inode)) {
-	err = -EDQUOT;
-	goto out_end_trans;
-    }
-    if (!dir || !dir->i_nlink) {
-	err = -EPERM;
-	goto out_bad_inode;
-    }
-
-    sb = dir->i_sb;
-
-    /* item head of new item */
-    ih.ih_key.k_dir_id = reiserfs_choose_packing(dir);
-    ih.ih_key.k_objectid = cpu_to_le32 (reiserfs_get_unused_objectid (th));
-    if (!ih.ih_key.k_objectid) {
-	err = -ENOMEM;
-	goto out_bad_inode ;
-    }
-    if (old_format_only (sb))
-	/* not a perfect generation count, as object ids can be reused, but 
-	** this is as good as reiserfs can do right now.
-	** note that the private part of inode isn't filled in yet, we have
-	** to use the directory.
-	*/
-	inode->i_generation = le32_to_cpu (INODE_PKEY (dir)->k_objectid);
-    else
+int reiserfs_new_inode(struct reiserfs_transaction_handle *th,
+		       struct inode *dir, int mode, const char *symname,
+		       /* 0 for regular, EMTRY_DIR_SIZE for dirs, 
+		          strlen (symname) for symlinks) */
+		       loff_t i_size, struct dentry *dentry,
+		       struct inode *inode)
+{
+	struct super_block *sb;
+	INITIALIZE_PATH(path_to_key);
+	struct cpu_key key;
+	struct item_head ih;
+	struct stat_data sd;
+	int retval;
+	int err;
+
+	BUG_ON(!th->t_trans_id);
+
+	if (DQUOT_ALLOC_INODE(inode)) {
+		err = -EDQUOT;
+		goto out_end_trans;
+	}
+	if (!dir || !dir->i_nlink) {
+		err = -EPERM;
+		goto out_bad_inode;
+	}
+
+	sb = dir->i_sb;
+
+	/* item head of new item */
+	ih.ih_key.k_dir_id = reiserfs_choose_packing(dir);
+	ih.ih_key.k_objectid = cpu_to_le32(reiserfs_get_unused_objectid(th));
+	if (!ih.ih_key.k_objectid) {
+		err = -ENOMEM;
+		goto out_bad_inode;
+	}
+	if (old_format_only(sb))
+		/* not a perfect generation count, as object ids can be reused, but 
+		 ** this is as good as reiserfs can do right now.
+		 ** note that the private part of inode isn't filled in yet, we have
+		 ** to use the directory.
+		 */
+		inode->i_generation = le32_to_cpu(INODE_PKEY(dir)->k_objectid);
+	else
 #if defined( USE_INODE_GENERATION_COUNTER )
-	inode->i_generation = le32_to_cpu(REISERFS_SB(sb)->s_rs->s_inode_generation);
+		inode->i_generation =
+		    le32_to_cpu(REISERFS_SB(sb)->s_rs->s_inode_generation);
 #else
-	inode->i_generation = ++event;
+		inode->i_generation = ++event;
 #endif
 
-    /* fill stat data */
-    inode->i_nlink = (S_ISDIR (mode) ? 2 : 1);
+	/* fill stat data */
+	inode->i_nlink = (S_ISDIR(mode) ? 2 : 1);
+
+	/* uid and gid must already be set by the caller for quota init */
 
-    /* uid and gid must already be set by the caller for quota init */
+	/* symlink cannot be immutable or append only, right? */
+	if (S_ISLNK(inode->i_mode))
+		inode->i_flags &= ~(S_IMMUTABLE | S_APPEND);
 
-    /* symlink cannot be immutable or append only, right? */
-    if( S_ISLNK( inode -> i_mode ) )
-	    inode -> i_flags &= ~ ( S_IMMUTABLE | S_APPEND );
-
-    inode->i_mtime = inode->i_atime = inode->i_ctime =
-	    CURRENT_TIME_SEC;
-    inode->i_size = i_size;
-    inode->i_blocks = 0;
-    inode->i_bytes = 0;
-    REISERFS_I(inode)->i_first_direct_byte = S_ISLNK(mode) ? 1 : 
-      U32_MAX/*NO_BYTES_IN_DIRECT_ITEM*/;
-
-    INIT_LIST_HEAD(&(REISERFS_I(inode)->i_prealloc_list ));
-    REISERFS_I(inode)->i_flags = 0;
-    REISERFS_I(inode)->i_prealloc_block = 0;
-    REISERFS_I(inode)->i_prealloc_count = 0;
-    REISERFS_I(inode)->i_trans_id = 0;
-    REISERFS_I(inode)->i_jl = NULL;
-    REISERFS_I(inode)->i_attrs =
-	REISERFS_I(dir)->i_attrs & REISERFS_INHERIT_MASK;
-    sd_attrs_to_i_attrs( REISERFS_I(inode) -> i_attrs, inode );
-    REISERFS_I(inode)->i_acl_access = NULL;
-    REISERFS_I(inode)->i_acl_default = NULL;
-    init_rwsem (&REISERFS_I(inode)->xattr_sem);
-
-    if (old_format_only (sb))
-	make_le_item_head (&ih, NULL, KEY_FORMAT_3_5, SD_OFFSET, TYPE_STAT_DATA, SD_V1_SIZE, MAX_US_INT);
-    else
-	make_le_item_head (&ih, NULL, KEY_FORMAT_3_6, SD_OFFSET, TYPE_STAT_DATA, SD_SIZE, MAX_US_INT);
-
-    /* key to search for correct place for new stat data */
-    _make_cpu_key (&key, KEY_FORMAT_3_6, le32_to_cpu (ih.ih_key.k_dir_id),
-		   le32_to_cpu (ih.ih_key.k_objectid), SD_OFFSET, TYPE_STAT_DATA, 3/*key length*/);
-
-    /* find proper place for inserting of stat data */
-    retval = search_item (sb, &key, &path_to_key);
-    if (retval == IO_ERROR) {
-	err = -EIO;
-	goto out_bad_inode;
-    }
-    if (retval == ITEM_FOUND) {
-	pathrelse (&path_to_key);
-	err = -EEXIST;
-	goto out_bad_inode;
-    }
-    if (old_format_only (sb)) {
-	if (inode->i_uid & ~0xffff || inode->i_gid & ~0xffff) {
-	    pathrelse (&path_to_key);
-	    /* i_uid or i_gid is too big to be stored in stat data v3.5 */
-	    err = -EINVAL;
-	    goto out_bad_inode;
-	}
-	inode2sd_v1 (&sd, inode, inode->i_size);
-    } else {
-	inode2sd (&sd, inode, inode->i_size);
-    }
-    // these do not go to on-disk stat data
-    inode->i_ino = le32_to_cpu (ih.ih_key.k_objectid);
-    inode->i_blksize = reiserfs_default_io_size;
-  
-    // store in in-core inode the key of stat data and version all
-    // object items will have (directory items will have old offset
-    // format, other new objects will consist of new items)
-    memcpy (INODE_PKEY (inode), &(ih.ih_key), KEY_SIZE);
-    if (old_format_only (sb) || S_ISDIR(mode) || S_ISLNK(mode))
-        set_inode_item_key_version (inode, KEY_FORMAT_3_5);
-    else
-        set_inode_item_key_version (inode, KEY_FORMAT_3_6);
-    if (old_format_only (sb))
-	set_inode_sd_version (inode, STAT_DATA_V1);
-    else
-	set_inode_sd_version (inode, STAT_DATA_V2);
-    
-    /* insert the stat data into the tree */
+	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC;
+	inode->i_size = i_size;
+	inode->i_blocks = 0;
+	inode->i_bytes = 0;
+	REISERFS_I(inode)->i_first_direct_byte = S_ISLNK(mode) ? 1 :
+	    U32_MAX /*NO_BYTES_IN_DIRECT_ITEM */ ;
+
+	INIT_LIST_HEAD(&(REISERFS_I(inode)->i_prealloc_list));
+	REISERFS_I(inode)->i_flags = 0;
+	REISERFS_I(inode)->i_prealloc_block = 0;
+	REISERFS_I(inode)->i_prealloc_count = 0;
+	REISERFS_I(inode)->i_trans_id = 0;
+	REISERFS_I(inode)->i_jl = NULL;
+	REISERFS_I(inode)->i_attrs =
+	    REISERFS_I(dir)->i_attrs & REISERFS_INHERIT_MASK;
+	sd_attrs_to_i_attrs(REISERFS_I(inode)->i_attrs, inode);
+	REISERFS_I(inode)->i_acl_access = NULL;
+	REISERFS_I(inode)->i_acl_default = NULL;
+	init_rwsem(&REISERFS_I(inode)->xattr_sem);
+
+	if (old_format_only(sb))
+		make_le_item_head(&ih, NULL, KEY_FORMAT_3_5, SD_OFFSET,
+				  TYPE_STAT_DATA, SD_V1_SIZE, MAX_US_INT);
+	else
+		make_le_item_head(&ih, NULL, KEY_FORMAT_3_6, SD_OFFSET,
+				  TYPE_STAT_DATA, SD_SIZE, MAX_US_INT);
+
+	/* key to search for correct place for new stat data */
+	_make_cpu_key(&key, KEY_FORMAT_3_6, le32_to_cpu(ih.ih_key.k_dir_id),
+		      le32_to_cpu(ih.ih_key.k_objectid), SD_OFFSET,
+		      TYPE_STAT_DATA, 3 /*key length */ );
+
+	/* find proper place for inserting of stat data */
+	retval = search_item(sb, &key, &path_to_key);
+	if (retval == IO_ERROR) {
+		err = -EIO;
+		goto out_bad_inode;
+	}
+	if (retval == ITEM_FOUND) {
+		pathrelse(&path_to_key);
+		err = -EEXIST;
+		goto out_bad_inode;
+	}
+	if (old_format_only(sb)) {
+		if (inode->i_uid & ~0xffff || inode->i_gid & ~0xffff) {
+			pathrelse(&path_to_key);
+			/* i_uid or i_gid is too big to be stored in stat data v3.5 */
+			err = -EINVAL;
+			goto out_bad_inode;
+		}
+		inode2sd_v1(&sd, inode, inode->i_size);
+	} else {
+		inode2sd(&sd, inode, inode->i_size);
+	}
+	// these do not go to on-disk stat data
+	inode->i_ino = le32_to_cpu(ih.ih_key.k_objectid);
+	inode->i_blksize = reiserfs_default_io_size;
+
+	// store in in-core inode the key of stat data and version all
+	// object items will have (directory items will have old offset
+	// format, other new objects will consist of new items)
+	memcpy(INODE_PKEY(inode), &(ih.ih_key), KEY_SIZE);
+	if (old_format_only(sb) || S_ISDIR(mode) || S_ISLNK(mode))
+		set_inode_item_key_version(inode, KEY_FORMAT_3_5);
+	else
+		set_inode_item_key_version(inode, KEY_FORMAT_3_6);
+	if (old_format_only(sb))
+		set_inode_sd_version(inode, STAT_DATA_V1);
+	else
+		set_inode_sd_version(inode, STAT_DATA_V2);
+
+	/* insert the stat data into the tree */
 #ifdef DISPLACE_NEW_PACKING_LOCALITIES
-    if (REISERFS_I(dir)->new_packing_locality)
-	th->displace_new_blocks = 1;
+	if (REISERFS_I(dir)->new_packing_locality)
+		th->displace_new_blocks = 1;
 #endif
-    retval = reiserfs_insert_item (th, &path_to_key, &key, &ih, inode, (char *)(&sd));
-    if (retval) {
-	err = retval;
-	reiserfs_check_path(&path_to_key) ;
-	goto out_bad_inode;
-    }
-
+	retval =
+	    reiserfs_insert_item(th, &path_to_key, &key, &ih, inode,
+				 (char *)(&sd));
+	if (retval) {
+		err = retval;
+		reiserfs_check_path(&path_to_key);
+		goto out_bad_inode;
+	}
 #ifdef DISPLACE_NEW_PACKING_LOCALITIES
-    if (!th->displace_new_blocks)
-	REISERFS_I(dir)->new_packing_locality = 0;
+	if (!th->displace_new_blocks)
+		REISERFS_I(dir)->new_packing_locality = 0;
 #endif
-    if (S_ISDIR(mode)) {
-	/* insert item with "." and ".." */
-	retval = reiserfs_new_directory (th, inode, &ih, &path_to_key, dir);
-    }
-
-    if (S_ISLNK(mode)) {
-	/* insert body of symlink */
-	if (!old_format_only (sb))
-	    i_size = ROUND_UP(i_size);
-	retval = reiserfs_new_symlink (th, inode, &ih, &path_to_key, symname, i_size);
-    }
-    if (retval) {
-	err = retval;
-	reiserfs_check_path(&path_to_key) ;
-	journal_end(th, th->t_super, th->t_blocks_allocated);
-	goto out_inserted_sd;
-    }
+	if (S_ISDIR(mode)) {
+		/* insert item with "." and ".." */
+		retval =
+		    reiserfs_new_directory(th, inode, &ih, &path_to_key, dir);
+	}
+
+	if (S_ISLNK(mode)) {
+		/* insert body of symlink */
+		if (!old_format_only(sb))
+			i_size = ROUND_UP(i_size);
+		retval =
+		    reiserfs_new_symlink(th, inode, &ih, &path_to_key, symname,
+					 i_size);
+	}
+	if (retval) {
+		err = retval;
+		reiserfs_check_path(&path_to_key);
+		journal_end(th, th->t_super, th->t_blocks_allocated);
+		goto out_inserted_sd;
+	}
+
+	/* XXX CHECK THIS */
+	if (reiserfs_posixacl(inode->i_sb)) {
+		retval = reiserfs_inherit_default_acl(dir, dentry, inode);
+		if (retval) {
+			err = retval;
+			reiserfs_check_path(&path_to_key);
+			journal_end(th, th->t_super, th->t_blocks_allocated);
+			goto out_inserted_sd;
+		}
+	} else if (inode->i_sb->s_flags & MS_POSIXACL) {
+		reiserfs_warning(inode->i_sb, "ACLs aren't enabled in the fs, "
+				 "but vfs thinks they are!");
+	} else if (is_reiserfs_priv_object(dir)) {
+		reiserfs_mark_inode_private(inode);
+	}
 
-    /* XXX CHECK THIS */
-    if (reiserfs_posixacl (inode->i_sb)) {
-        retval = reiserfs_inherit_default_acl (dir, dentry, inode);
-        if (retval) {
-            err = retval;
-            reiserfs_check_path(&path_to_key) ;
-            journal_end(th, th->t_super, th->t_blocks_allocated);
-            goto out_inserted_sd;
-        }
-    } else if (inode->i_sb->s_flags & MS_POSIXACL) {
-	reiserfs_warning (inode->i_sb, "ACLs aren't enabled in the fs, "
-			  "but vfs thinks they are!");
-    } else if (is_reiserfs_priv_object (dir)) {
-	reiserfs_mark_inode_private (inode);
-    }
-
-    insert_inode_hash (inode);
-    reiserfs_update_sd(th, inode);
-    reiserfs_check_path(&path_to_key) ;
+	insert_inode_hash(inode);
+	reiserfs_update_sd(th, inode);
+	reiserfs_check_path(&path_to_key);
 
-    return 0;
+	return 0;
 
 /* it looks like you can easily compress these two goto targets into
  * one.  Keeping it like this doesn't actually hurt anything, and they
  * are place holders for what the quota code actually needs.
  */
-out_bad_inode:
-    /* Invalidate the object, nothing was inserted yet */
-    INODE_PKEY(inode)->k_objectid = 0;
-
-    /* Quota change must be inside a transaction for journaling */
-    DQUOT_FREE_INODE(inode);
-
-out_end_trans:
-    journal_end(th, th->t_super, th->t_blocks_allocated) ;
-    /* Drop can be outside and it needs more credits so it's better to have it outside */
-    DQUOT_DROP(inode);
-    inode->i_flags |= S_NOQUOTA;
-    make_bad_inode(inode);
-
-out_inserted_sd:
-    inode->i_nlink = 0;
-    th->t_trans_id = 0; /* so the caller can't use this handle later */
-    iput(inode);
-    return err;
+      out_bad_inode:
+	/* Invalidate the object, nothing was inserted yet */
+	INODE_PKEY(inode)->k_objectid = 0;
+
+	/* Quota change must be inside a transaction for journaling */
+	DQUOT_FREE_INODE(inode);
+
+      out_end_trans:
+	journal_end(th, th->t_super, th->t_blocks_allocated);
+	/* Drop can be outside and it needs more credits so it's better to have it outside */
+	DQUOT_DROP(inode);
+	inode->i_flags |= S_NOQUOTA;
+	make_bad_inode(inode);
+
+      out_inserted_sd:
+	inode->i_nlink = 0;
+	th->t_trans_id = 0;	/* so the caller can't use this handle later */
+
+	/* If we were inheriting an ACL, we need to release the lock so that
+	 * iput doesn't deadlock in reiserfs_delete_xattrs. The locking
+	 * code really needs to be reworked, but this will take care of it
+	 * for now. -jeffm */
+	if (REISERFS_I(dir)->i_acl_default && !IS_ERR(REISERFS_I(dir)->i_acl_default)) {
+		reiserfs_write_unlock_xattrs(dir->i_sb);
+		iput(inode);
+		reiserfs_write_lock_xattrs(dir->i_sb);
+	} else
+		iput(inode);
+	return err;
 }
 
 /*
@@ -1891,77 +2007,78 @@ out_inserted_sd:
 **
 ** on failure, nonzero is returned, page_result and bh_result are untouched.
 */
-static int grab_tail_page(struct inode *p_s_inode, 
-			  struct page **page_result, 
-			  struct buffer_head **bh_result) {
-
-    /* we want the page with the last byte in the file,
-    ** not the page that will hold the next byte for appending
-    */
-    unsigned long index = (p_s_inode->i_size-1) >> PAGE_CACHE_SHIFT ;
-    unsigned long pos = 0 ;
-    unsigned long start = 0 ;
-    unsigned long blocksize = p_s_inode->i_sb->s_blocksize ;
-    unsigned long offset = (p_s_inode->i_size) & (PAGE_CACHE_SIZE - 1) ;
-    struct buffer_head *bh ;
-    struct buffer_head *head ;
-    struct page * page ;
-    int error ;
-    
-    /* we know that we are only called with inode->i_size > 0.
-    ** we also know that a file tail can never be as big as a block
-    ** If i_size % blocksize == 0, our file is currently block aligned
-    ** and it won't need converting or zeroing after a truncate.
-    */
-    if ((offset & (blocksize - 1)) == 0) {
-        return -ENOENT ;
-    }
-    page = grab_cache_page(p_s_inode->i_mapping, index) ;
-    error = -ENOMEM ;
-    if (!page) {
-        goto out ;
-    }
-    /* start within the page of the last block in the file */
-    start = (offset / blocksize) * blocksize ;
-
-    error = block_prepare_write(page, start, offset, 
-				reiserfs_get_block_create_0) ;
-    if (error)
-	goto unlock ;
-
-    head = page_buffers(page) ;      
-    bh = head;
-    do {
-	if (pos >= start) {
-	    break ;
-	}
-	bh = bh->b_this_page ;
-	pos += blocksize ;
-    } while(bh != head) ;
-
-    if (!buffer_uptodate(bh)) {
-	/* note, this should never happen, prepare_write should
-	** be taking care of this for us.  If the buffer isn't up to date,
-	** I've screwed up the code to find the buffer, or the code to
-	** call prepare_write
-	*/
-	reiserfs_warning (p_s_inode->i_sb,
-			  "clm-6000: error reading block %lu on dev %s",
-			  bh->b_blocknr,
-			  reiserfs_bdevname (p_s_inode->i_sb)) ;
-	error = -EIO ;
-	goto unlock ;
-    }
-    *bh_result = bh ;
-    *page_result = page ;
-
-out:
-    return error ;
-
-unlock:
-    unlock_page(page) ;
-    page_cache_release(page) ;
-    return error ;
+static int grab_tail_page(struct inode *p_s_inode,
+			  struct page **page_result,
+			  struct buffer_head **bh_result)
+{
+
+	/* we want the page with the last byte in the file,
+	 ** not the page that will hold the next byte for appending
+	 */
+	unsigned long index = (p_s_inode->i_size - 1) >> PAGE_CACHE_SHIFT;
+	unsigned long pos = 0;
+	unsigned long start = 0;
+	unsigned long blocksize = p_s_inode->i_sb->s_blocksize;
+	unsigned long offset = (p_s_inode->i_size) & (PAGE_CACHE_SIZE - 1);
+	struct buffer_head *bh;
+	struct buffer_head *head;
+	struct page *page;
+	int error;
+
+	/* we know that we are only called with inode->i_size > 0.
+	 ** we also know that a file tail can never be as big as a block
+	 ** If i_size % blocksize == 0, our file is currently block aligned
+	 ** and it won't need converting or zeroing after a truncate.
+	 */
+	if ((offset & (blocksize - 1)) == 0) {
+		return -ENOENT;
+	}
+	page = grab_cache_page(p_s_inode->i_mapping, index);
+	error = -ENOMEM;
+	if (!page) {
+		goto out;
+	}
+	/* start within the page of the last block in the file */
+	start = (offset / blocksize) * blocksize;
+
+	error = block_prepare_write(page, start, offset,
+				    reiserfs_get_block_create_0);
+	if (error)
+		goto unlock;
+
+	head = page_buffers(page);
+	bh = head;
+	do {
+		if (pos >= start) {
+			break;
+		}
+		bh = bh->b_this_page;
+		pos += blocksize;
+	} while (bh != head);
+
+	if (!buffer_uptodate(bh)) {
+		/* note, this should never happen, prepare_write should
+		 ** be taking care of this for us.  If the buffer isn't up to date,
+		 ** I've screwed up the code to find the buffer, or the code to
+		 ** call prepare_write
+		 */
+		reiserfs_warning(p_s_inode->i_sb,
+				 "clm-6000: error reading block %lu on dev %s",
+				 bh->b_blocknr,
+				 reiserfs_bdevname(p_s_inode->i_sb));
+		error = -EIO;
+		goto unlock;
+	}
+	*bh_result = bh;
+	*page_result = page;
+
+      out:
+	return error;
+
+      unlock:
+	unlock_page(page);
+	page_cache_release(page);
+	return error;
 }
 
 /*
@@ -1970,235 +2087,247 @@ unlock:
 **
 ** some code taken from block_truncate_page
 */
-int reiserfs_truncate_file(struct inode *p_s_inode, int update_timestamps) {
-    struct reiserfs_transaction_handle th ;
-    /* we want the offset for the first byte after the end of the file */
-    unsigned long offset = p_s_inode->i_size & (PAGE_CACHE_SIZE - 1) ;
-    unsigned blocksize = p_s_inode->i_sb->s_blocksize ;
-    unsigned length ;
-    struct page *page = NULL ;
-    int error ;
-    struct buffer_head *bh = NULL ;
-
-    reiserfs_write_lock(p_s_inode->i_sb);
-
-    if (p_s_inode->i_size > 0) {
-        if ((error = grab_tail_page(p_s_inode, &page, &bh))) {
-	    // -ENOENT means we truncated past the end of the file, 
-	    // and get_block_create_0 could not find a block to read in,
-	    // which is ok.
-	    if (error != -ENOENT)
-	        reiserfs_warning (p_s_inode->i_sb,
-				  "clm-6001: grab_tail_page failed %d",
-				  error);
-	    page = NULL ;
-	    bh = NULL ;
-	}
-    }
-
-    /* so, if page != NULL, we have a buffer head for the offset at 
-    ** the end of the file. if the bh is mapped, and bh->b_blocknr != 0, 
-    ** then we have an unformatted node.  Otherwise, we have a direct item, 
-    ** and no zeroing is required on disk.  We zero after the truncate, 
-    ** because the truncate might pack the item anyway 
-    ** (it will unmap bh if it packs).
-    */
-    /* it is enough to reserve space in transaction for 2 balancings:
-       one for "save" link adding and another for the first
-       cut_from_item. 1 is for update_sd */
-    error = journal_begin (&th, p_s_inode->i_sb,
-                           JOURNAL_PER_BALANCE_CNT * 2 + 1);
-    if (error)
-        goto out;
-    reiserfs_update_inode_transaction(p_s_inode) ;
-    if (update_timestamps)
-	    /* we are doing real truncate: if the system crashes before the last
-	       transaction of truncating gets committed - on reboot the file
-	       either appears truncated properly or not truncated at all */
-	add_save_link (&th, p_s_inode, 1);
-    error = reiserfs_do_truncate (&th, p_s_inode, page, update_timestamps) ;
-    if (error)
-        goto out;
-    error = journal_end (&th, p_s_inode->i_sb, JOURNAL_PER_BALANCE_CNT * 2 + 1);
-    if (error)
-        goto out;
-
-    if (update_timestamps) {
-	error = remove_save_link (p_s_inode, 1/* truncate */);
-        if (error)
-            goto out;
-    }
-
-    if (page) {
-        length = offset & (blocksize - 1) ;
-	/* if we are not on a block boundary */
-	if (length) {
-	    char *kaddr;
-
-	    length = blocksize - length ;
-	    kaddr = kmap_atomic(page, KM_USER0) ;
-	    memset(kaddr + offset, 0, length) ;   
-	    flush_dcache_page(page) ;
-	    kunmap_atomic(kaddr, KM_USER0) ;
-	    if (buffer_mapped(bh) && bh->b_blocknr != 0) {
-	        mark_buffer_dirty(bh) ;
-	    }
-	}
-	unlock_page(page) ;
-	page_cache_release(page) ;
-    }
-
-    reiserfs_write_unlock(p_s_inode->i_sb);
-    return 0;
-out:
-    if (page) {
-        unlock_page (page);
-        page_cache_release (page);
-    }
-    reiserfs_write_unlock(p_s_inode->i_sb);
-    return error;
-}
-
-static int map_block_for_writepage(struct inode *inode, 
-			       struct buffer_head *bh_result, 
-                               unsigned long block) {
-    struct reiserfs_transaction_handle th ;
-    int fs_gen ;
-    struct item_head tmp_ih ;
-    struct item_head *ih ;
-    struct buffer_head *bh ;
-    __le32 *item ;
-    struct cpu_key key ;
-    INITIALIZE_PATH(path) ;
-    int pos_in_item ;
-    int jbegin_count = JOURNAL_PER_BALANCE_CNT ;
-    loff_t byte_offset = (block << inode->i_sb->s_blocksize_bits) + 1 ;
-    int retval ;
-    int use_get_block = 0 ;
-    int bytes_copied = 0 ;
-    int copy_size ;
-    int trans_running = 0;
-
-    /* catch places below that try to log something without starting a trans */
-    th.t_trans_id = 0;
-
-    if (!buffer_uptodate(bh_result)) {
-	return -EIO;
-    }
-
-    kmap(bh_result->b_page) ;
-start_over:
-    reiserfs_write_lock(inode->i_sb);
-    make_cpu_key(&key, inode, byte_offset, TYPE_ANY, 3) ;
-
-research:
-    retval = search_for_position_by_key(inode->i_sb, &key, &path) ;
-    if (retval != POSITION_FOUND) {
-        use_get_block = 1;
-	goto out ;
-    } 
-
-    bh = get_last_bh(&path) ;
-    ih = get_ih(&path) ;
-    item = get_item(&path) ;
-    pos_in_item = path.pos_in_item ;
-
-    /* we've found an unformatted node */
-    if (indirect_item_found(retval, ih)) {
-	if (bytes_copied > 0) {
-	    reiserfs_warning (inode->i_sb, "clm-6002: bytes_copied %d",
-			      bytes_copied) ;
-	}
-        if (!get_block_num(item, pos_in_item)) {
-	    /* crap, we are writing to a hole */
-	    use_get_block = 1;
-	    goto out ;
-	}
-	set_block_dev_mapped(bh_result, get_block_num(item,pos_in_item),inode);
-    } else if (is_direct_le_ih(ih)) {
-        char *p ; 
-        p = page_address(bh_result->b_page) ;
-        p += (byte_offset -1) & (PAGE_CACHE_SIZE - 1) ;
-        copy_size = ih_item_len(ih) - pos_in_item;
-
-	fs_gen = get_generation(inode->i_sb) ;
-	copy_item_head(&tmp_ih, ih) ;
-
-	if (!trans_running) {
-	    /* vs-3050 is gone, no need to drop the path */
-	    retval = journal_begin(&th, inode->i_sb, jbegin_count) ;
-            if (retval)
-                goto out;
-	    reiserfs_update_inode_transaction(inode) ;
-	    trans_running = 1;
-	    if (fs_changed(fs_gen, inode->i_sb) && item_moved(&tmp_ih, &path)) {
-		reiserfs_restore_prepared_buffer(inode->i_sb, bh) ;
-		goto research;
-	    }
-	}
-
-	reiserfs_prepare_for_journal(inode->i_sb, bh, 1) ;
-
-	if (fs_changed (fs_gen, inode->i_sb) && item_moved (&tmp_ih, &path)) {
-	    reiserfs_restore_prepared_buffer(inode->i_sb, bh) ;
-	    goto research;
-	}
-
-	memcpy( B_I_PITEM(bh, ih) + pos_in_item, p + bytes_copied, copy_size) ;
-
-	journal_mark_dirty(&th, inode->i_sb, bh) ;
-	bytes_copied += copy_size ;
-	set_block_dev_mapped(bh_result, 0, inode);
-
-	/* are there still bytes left? */
-        if (bytes_copied < bh_result->b_size && 
-	    (byte_offset + bytes_copied) < inode->i_size) {
-	    set_cpu_key_k_offset(&key, cpu_key_k_offset(&key) + copy_size) ;
-	    goto research ;
-	}
-    } else {
-        reiserfs_warning (inode->i_sb,
-			  "clm-6003: bad item inode %lu, device %s",
-			  inode->i_ino, reiserfs_bdevname (inode->i_sb)) ;
-        retval = -EIO ;
-	goto out ;
-    }
-    retval = 0 ;
-    
-out:
-    pathrelse(&path) ;
-    if (trans_running) {
-        int err = journal_end(&th, inode->i_sb, jbegin_count) ;
-        if (err)
-            retval = err;
-	trans_running = 0;
-    }
-    reiserfs_write_unlock(inode->i_sb);
-
-    /* this is where we fill in holes in the file. */
-    if (use_get_block) {
-	retval = reiserfs_get_block(inode, block, bh_result, 
-	                            GET_BLOCK_CREATE | GET_BLOCK_NO_ISEM |
-				    GET_BLOCK_NO_DANGLE);
-	if (!retval) {
-	    if (!buffer_mapped(bh_result) || bh_result->b_blocknr == 0) {
-	        /* get_block failed to find a mapped unformatted node. */
-		use_get_block = 0 ;
-		goto start_over ;
-	    }
-	}
-    }
-    kunmap(bh_result->b_page) ;
-
-    if (!retval && buffer_mapped(bh_result) && bh_result->b_blocknr == 0) {
-	/* we've copied data from the page into the direct item, so the
-	 * buffer in the page is now clean, mark it to reflect that.
-	 */
-        lock_buffer(bh_result);
-	clear_buffer_dirty(bh_result);
-	unlock_buffer(bh_result);
-    }
-    return retval ;
+int reiserfs_truncate_file(struct inode *p_s_inode, int update_timestamps)
+{
+	struct reiserfs_transaction_handle th;
+	/* we want the offset for the first byte after the end of the file */
+	unsigned long offset = p_s_inode->i_size & (PAGE_CACHE_SIZE - 1);
+	unsigned blocksize = p_s_inode->i_sb->s_blocksize;
+	unsigned length;
+	struct page *page = NULL;
+	int error;
+	struct buffer_head *bh = NULL;
+
+	reiserfs_write_lock(p_s_inode->i_sb);
+
+	if (p_s_inode->i_size > 0) {
+		if ((error = grab_tail_page(p_s_inode, &page, &bh))) {
+			// -ENOENT means we truncated past the end of the file, 
+			// and get_block_create_0 could not find a block to read in,
+			// which is ok.
+			if (error != -ENOENT)
+				reiserfs_warning(p_s_inode->i_sb,
+						 "clm-6001: grab_tail_page failed %d",
+						 error);
+			page = NULL;
+			bh = NULL;
+		}
+	}
+
+	/* so, if page != NULL, we have a buffer head for the offset at 
+	 ** the end of the file. if the bh is mapped, and bh->b_blocknr != 0, 
+	 ** then we have an unformatted node.  Otherwise, we have a direct item, 
+	 ** and no zeroing is required on disk.  We zero after the truncate, 
+	 ** because the truncate might pack the item anyway 
+	 ** (it will unmap bh if it packs).
+	 */
+	/* it is enough to reserve space in transaction for 2 balancings:
+	   one for "save" link adding and another for the first
+	   cut_from_item. 1 is for update_sd */
+	error = journal_begin(&th, p_s_inode->i_sb,
+			      JOURNAL_PER_BALANCE_CNT * 2 + 1);
+	if (error)
+		goto out;
+	reiserfs_update_inode_transaction(p_s_inode);
+	if (update_timestamps)
+		/* we are doing real truncate: if the system crashes before the last
+		   transaction of truncating gets committed - on reboot the file
+		   either appears truncated properly or not truncated at all */
+		add_save_link(&th, p_s_inode, 1);
+	error = reiserfs_do_truncate(&th, p_s_inode, page, update_timestamps);
+	if (error)
+		goto out;
+	error =
+	    journal_end(&th, p_s_inode->i_sb, JOURNAL_PER_BALANCE_CNT * 2 + 1);
+	if (error)
+		goto out;
+
+	if (update_timestamps) {
+		error = remove_save_link(p_s_inode, 1 /* truncate */ );
+		if (error)
+			goto out;
+	}
+
+	if (page) {
+		length = offset & (blocksize - 1);
+		/* if we are not on a block boundary */
+		if (length) {
+			char *kaddr;
+
+			length = blocksize - length;
+			kaddr = kmap_atomic(page, KM_USER0);
+			memset(kaddr + offset, 0, length);
+			flush_dcache_page(page);
+			kunmap_atomic(kaddr, KM_USER0);
+			if (buffer_mapped(bh) && bh->b_blocknr != 0) {
+				mark_buffer_dirty(bh);
+			}
+		}
+		unlock_page(page);
+		page_cache_release(page);
+	}
+
+	reiserfs_write_unlock(p_s_inode->i_sb);
+	return 0;
+      out:
+	if (page) {
+		unlock_page(page);
+		page_cache_release(page);
+	}
+	reiserfs_write_unlock(p_s_inode->i_sb);
+	return error;
+}
+
+static int map_block_for_writepage(struct inode *inode,
+				   struct buffer_head *bh_result,
+				   unsigned long block)
+{
+	struct reiserfs_transaction_handle th;
+	int fs_gen;
+	struct item_head tmp_ih;
+	struct item_head *ih;
+	struct buffer_head *bh;
+	__le32 *item;
+	struct cpu_key key;
+	INITIALIZE_PATH(path);
+	int pos_in_item;
+	int jbegin_count = JOURNAL_PER_BALANCE_CNT;
+	loff_t byte_offset = (block << inode->i_sb->s_blocksize_bits) + 1;
+	int retval;
+	int use_get_block = 0;
+	int bytes_copied = 0;
+	int copy_size;
+	int trans_running = 0;
+
+	/* catch places below that try to log something without starting a trans */
+	th.t_trans_id = 0;
+
+	if (!buffer_uptodate(bh_result)) {
+		return -EIO;
+	}
+
+	kmap(bh_result->b_page);
+      start_over:
+	reiserfs_write_lock(inode->i_sb);
+	make_cpu_key(&key, inode, byte_offset, TYPE_ANY, 3);
+
+      research:
+	retval = search_for_position_by_key(inode->i_sb, &key, &path);
+	if (retval != POSITION_FOUND) {
+		use_get_block = 1;
+		goto out;
+	}
+
+	bh = get_last_bh(&path);
+	ih = get_ih(&path);
+	item = get_item(&path);
+	pos_in_item = path.pos_in_item;
+
+	/* we've found an unformatted node */
+	if (indirect_item_found(retval, ih)) {
+		if (bytes_copied > 0) {
+			reiserfs_warning(inode->i_sb,
+					 "clm-6002: bytes_copied %d",
+					 bytes_copied);
+		}
+		if (!get_block_num(item, pos_in_item)) {
+			/* crap, we are writing to a hole */
+			use_get_block = 1;
+			goto out;
+		}
+		set_block_dev_mapped(bh_result,
+				     get_block_num(item, pos_in_item), inode);
+	} else if (is_direct_le_ih(ih)) {
+		char *p;
+		p = page_address(bh_result->b_page);
+		p += (byte_offset - 1) & (PAGE_CACHE_SIZE - 1);
+		copy_size = ih_item_len(ih) - pos_in_item;
+
+		fs_gen = get_generation(inode->i_sb);
+		copy_item_head(&tmp_ih, ih);
+
+		if (!trans_running) {
+			/* vs-3050 is gone, no need to drop the path */
+			retval = journal_begin(&th, inode->i_sb, jbegin_count);
+			if (retval)
+				goto out;
+			reiserfs_update_inode_transaction(inode);
+			trans_running = 1;
+			if (fs_changed(fs_gen, inode->i_sb)
+			    && item_moved(&tmp_ih, &path)) {
+				reiserfs_restore_prepared_buffer(inode->i_sb,
+								 bh);
+				goto research;
+			}
+		}
+
+		reiserfs_prepare_for_journal(inode->i_sb, bh, 1);
+
+		if (fs_changed(fs_gen, inode->i_sb)
+		    && item_moved(&tmp_ih, &path)) {
+			reiserfs_restore_prepared_buffer(inode->i_sb, bh);
+			goto research;
+		}
+
+		memcpy(B_I_PITEM(bh, ih) + pos_in_item, p + bytes_copied,
+		       copy_size);
+
+		journal_mark_dirty(&th, inode->i_sb, bh);
+		bytes_copied += copy_size;
+		set_block_dev_mapped(bh_result, 0, inode);
+
+		/* are there still bytes left? */
+		if (bytes_copied < bh_result->b_size &&
+		    (byte_offset + bytes_copied) < inode->i_size) {
+			set_cpu_key_k_offset(&key,
+					     cpu_key_k_offset(&key) +
+					     copy_size);
+			goto research;
+		}
+	} else {
+		reiserfs_warning(inode->i_sb,
+				 "clm-6003: bad item inode %lu, device %s",
+				 inode->i_ino, reiserfs_bdevname(inode->i_sb));
+		retval = -EIO;
+		goto out;
+	}
+	retval = 0;
+
+      out:
+	pathrelse(&path);
+	if (trans_running) {
+		int err = journal_end(&th, inode->i_sb, jbegin_count);
+		if (err)
+			retval = err;
+		trans_running = 0;
+	}
+	reiserfs_write_unlock(inode->i_sb);
+
+	/* this is where we fill in holes in the file. */
+	if (use_get_block) {
+		retval = reiserfs_get_block(inode, block, bh_result,
+					    GET_BLOCK_CREATE | GET_BLOCK_NO_ISEM
+					    | GET_BLOCK_NO_DANGLE);
+		if (!retval) {
+			if (!buffer_mapped(bh_result)
+			    || bh_result->b_blocknr == 0) {
+				/* get_block failed to find a mapped unformatted node. */
+				use_get_block = 0;
+				goto start_over;
+			}
+		}
+	}
+	kunmap(bh_result->b_page);
+
+	if (!retval && buffer_mapped(bh_result) && bh_result->b_blocknr == 0) {
+		/* we've copied data from the page into the direct item, so the
+		 * buffer in the page is now clean, mark it to reflect that.
+		 */
+		lock_buffer(bh_result);
+		clear_buffer_dirty(bh_result);
+		unlock_buffer(bh_result);
+	}
+	return retval;
 }
 
 /* 
@@ -2206,383 +2335,390 @@ out:
  * start/recovery path as __block_write_full_page, along with special
  * code to handle reiserfs tails.
  */
-static int reiserfs_write_full_page(struct page *page, struct writeback_control *wbc) {
-    struct inode *inode = page->mapping->host ;
-    unsigned long end_index = inode->i_size >> PAGE_CACHE_SHIFT ;
-    int error = 0;
-    unsigned long block ;
-    struct buffer_head *head, *bh;
-    int partial = 0 ;
-    int nr = 0;
-    int checked = PageChecked(page);
-    struct reiserfs_transaction_handle th;
-    struct super_block *s = inode->i_sb;
-    int bh_per_page = PAGE_CACHE_SIZE / s->s_blocksize;
-    th.t_trans_id = 0;
-
-    /* The page dirty bit is cleared before writepage is called, which
-     * means we have to tell create_empty_buffers to make dirty buffers
-     * The page really should be up to date at this point, so tossing
-     * in the BH_Uptodate is just a sanity check.
-     */
-    if (!page_has_buffers(page)) {
-	create_empty_buffers(page, s->s_blocksize,
-	                    (1 << BH_Dirty) | (1 << BH_Uptodate));
-    }
-    head = page_buffers(page) ;
-
-    /* last page in the file, zero out any contents past the
-    ** last byte in the file
-    */
-    if (page->index >= end_index) {
-	char *kaddr;
-	unsigned last_offset;
-
-        last_offset = inode->i_size & (PAGE_CACHE_SIZE - 1) ;
-	/* no file contents in this page */
-	if (page->index >= end_index + 1 || !last_offset) {
-    	    unlock_page(page);
-	    return 0;
-	}
-	kaddr = kmap_atomic(page, KM_USER0);
-	memset(kaddr + last_offset, 0, PAGE_CACHE_SIZE-last_offset) ;
-	flush_dcache_page(page) ;
-	kunmap_atomic(kaddr, KM_USER0) ;
-    }
-    bh = head ;
-    block = page->index << (PAGE_CACHE_SHIFT - s->s_blocksize_bits) ;
-    /* first map all the buffers, logging any direct items we find */
-    do {
-	if ((checked || buffer_dirty(bh)) && (!buffer_mapped(bh) ||
-	   (buffer_mapped(bh) && bh->b_blocknr == 0))) {
-	    /* not mapped yet, or it points to a direct item, search
-	     * the btree for the mapping info, and log any direct
-	     * items found
-	     */
-	    if ((error = map_block_for_writepage(inode, bh, block))) {
-		goto fail ;
-	    }
-	}
-        bh = bh->b_this_page;
-	block++;
-    } while(bh != head) ;
-
-    /*
-     * we start the transaction after map_block_for_writepage,
-     * because it can create holes in the file (an unbounded operation).
-     * starting it here, we can make a reliable estimate for how many
-     * blocks we're going to log
-     */
-    if (checked) {
-	ClearPageChecked(page);
-	reiserfs_write_lock(s);
-	error = journal_begin(&th, s, bh_per_page + 1);
-	if (error) {
-	    reiserfs_write_unlock(s);
-	    goto fail;
-	}
-	reiserfs_update_inode_transaction(inode);
-    }
-    /* now go through and lock any dirty buffers on the page */
-    do {
-	get_bh(bh);
-	if (!buffer_mapped(bh))
-	    continue;
-	if (buffer_mapped(bh) && bh->b_blocknr == 0)
-	    continue;
-
-	if (checked) {
-	    reiserfs_prepare_for_journal(s, bh, 1);
-	    journal_mark_dirty(&th, s, bh);
-	    continue;
-	}
-	/* from this point on, we know the buffer is mapped to a
-	 * real block and not a direct item
+static int reiserfs_write_full_page(struct page *page,
+				    struct writeback_control *wbc)
+{
+	struct inode *inode = page->mapping->host;
+	unsigned long end_index = inode->i_size >> PAGE_CACHE_SHIFT;
+	int error = 0;
+	unsigned long block;
+	struct buffer_head *head, *bh;
+	int partial = 0;
+	int nr = 0;
+	int checked = PageChecked(page);
+	struct reiserfs_transaction_handle th;
+	struct super_block *s = inode->i_sb;
+	int bh_per_page = PAGE_CACHE_SIZE / s->s_blocksize;
+	th.t_trans_id = 0;
+
+	/* The page dirty bit is cleared before writepage is called, which
+	 * means we have to tell create_empty_buffers to make dirty buffers
+	 * The page really should be up to date at this point, so tossing
+	 * in the BH_Uptodate is just a sanity check.
 	 */
-	if (wbc->sync_mode != WB_SYNC_NONE || !wbc->nonblocking) {
-	    lock_buffer(bh);
-	} else {
-	    if (test_set_buffer_locked(bh)) {
-		redirty_page_for_writepage(wbc, page);
-		continue;
-	    }
+	if (!page_has_buffers(page)) {
+		create_empty_buffers(page, s->s_blocksize,
+				     (1 << BH_Dirty) | (1 << BH_Uptodate));
 	}
-	if (test_clear_buffer_dirty(bh)) {
-	    mark_buffer_async_write(bh);
-	} else {
-	    unlock_buffer(bh);
-	}
-    } while((bh = bh->b_this_page) != head);
+	head = page_buffers(page);
 
-    if (checked) {
-	error = journal_end(&th, s, bh_per_page + 1);
-	reiserfs_write_unlock(s);
-	if (error)
-	    goto fail;
-    }
-    BUG_ON(PageWriteback(page));
-    set_page_writeback(page);
-    unlock_page(page);
-
-    /*
-     * since any buffer might be the only dirty buffer on the page, 
-     * the first submit_bh can bring the page out of writeback.
-     * be careful with the buffers.
-     */
-    do {
-        struct buffer_head *next = bh->b_this_page;
-	if (buffer_async_write(bh)) {
-	    submit_bh(WRITE, bh);
-	    nr++;
-	}
-	put_bh(bh);
-	bh = next;
-    } while(bh != head);
-
-    error = 0;
-done:
-    if (nr == 0) {
-        /*
-         * if this page only had a direct item, it is very possible for
-         * no io to be required without there being an error.  Or, 
-	 * someone else could have locked them and sent them down the 
-	 * pipe without locking the page
+	/* last page in the file, zero out any contents past the
+	 ** last byte in the file
 	 */
-	bh = head ;
+	if (page->index >= end_index) {
+		char *kaddr;
+		unsigned last_offset;
+
+		last_offset = inode->i_size & (PAGE_CACHE_SIZE - 1);
+		/* no file contents in this page */
+		if (page->index >= end_index + 1 || !last_offset) {
+			unlock_page(page);
+			return 0;
+		}
+		kaddr = kmap_atomic(page, KM_USER0);
+		memset(kaddr + last_offset, 0, PAGE_CACHE_SIZE - last_offset);
+		flush_dcache_page(page);
+		kunmap_atomic(kaddr, KM_USER0);
+	}
+	bh = head;
+	block = page->index << (PAGE_CACHE_SHIFT - s->s_blocksize_bits);
+	/* first map all the buffers, logging any direct items we find */
 	do {
-	    if (!buffer_uptodate(bh)) {
-	        partial = 1;
-		break;
-	    }
-	    bh = bh->b_this_page;
-	} while(bh != head);
-	if (!partial)
-	    SetPageUptodate(page);
-	end_page_writeback(page);
-    }
-    return error;
-
-fail:
-    /* catches various errors, we need to make sure any valid dirty blocks
-     * get to the media.  The page is currently locked and not marked for 
-     * writeback
-     */
-    ClearPageUptodate(page);
-    bh = head;
-    do {
-	get_bh(bh);
-	if (buffer_mapped(bh) && buffer_dirty(bh) && bh->b_blocknr) {
-	    lock_buffer(bh);
-	    mark_buffer_async_write(bh);
-	} else {
-	    /*
-	     * clear any dirty bits that might have come from getting
-	     * attached to a dirty page
-	     */
-	     clear_buffer_dirty(bh);
-	}
-        bh = bh->b_this_page;
-    } while(bh != head);
-    SetPageError(page);
-    BUG_ON(PageWriteback(page));
-    set_page_writeback(page);
-    unlock_page(page);
-    do {
-        struct buffer_head *next = bh->b_this_page;
-	if (buffer_async_write(bh)) {
-	    clear_buffer_dirty(bh);
-	    submit_bh(WRITE, bh);
-	    nr++;
+		if ((checked || buffer_dirty(bh)) && (!buffer_mapped(bh) ||
+						      (buffer_mapped(bh)
+						       && bh->b_blocknr ==
+						       0))) {
+			/* not mapped yet, or it points to a direct item, search
+			 * the btree for the mapping info, and log any direct
+			 * items found
+			 */
+			if ((error = map_block_for_writepage(inode, bh, block))) {
+				goto fail;
+			}
+		}
+		bh = bh->b_this_page;
+		block++;
+	} while (bh != head);
+
+	/*
+	 * we start the transaction after map_block_for_writepage,
+	 * because it can create holes in the file (an unbounded operation).
+	 * starting it here, we can make a reliable estimate for how many
+	 * blocks we're going to log
+	 */
+	if (checked) {
+		ClearPageChecked(page);
+		reiserfs_write_lock(s);
+		error = journal_begin(&th, s, bh_per_page + 1);
+		if (error) {
+			reiserfs_write_unlock(s);
+			goto fail;
+		}
+		reiserfs_update_inode_transaction(inode);
 	}
-	put_bh(bh);
-	bh = next;
-    } while(bh != head);
-    goto done;
-}
+	/* now go through and lock any dirty buffers on the page */
+	do {
+		get_bh(bh);
+		if (!buffer_mapped(bh))
+			continue;
+		if (buffer_mapped(bh) && bh->b_blocknr == 0)
+			continue;
+
+		if (checked) {
+			reiserfs_prepare_for_journal(s, bh, 1);
+			journal_mark_dirty(&th, s, bh);
+			continue;
+		}
+		/* from this point on, we know the buffer is mapped to a
+		 * real block and not a direct item
+		 */
+		if (wbc->sync_mode != WB_SYNC_NONE || !wbc->nonblocking) {
+			lock_buffer(bh);
+		} else {
+			if (test_set_buffer_locked(bh)) {
+				redirty_page_for_writepage(wbc, page);
+				continue;
+			}
+		}
+		if (test_clear_buffer_dirty(bh)) {
+			mark_buffer_async_write(bh);
+		} else {
+			unlock_buffer(bh);
+		}
+	} while ((bh = bh->b_this_page) != head);
 
+	if (checked) {
+		error = journal_end(&th, s, bh_per_page + 1);
+		reiserfs_write_unlock(s);
+		if (error)
+			goto fail;
+	}
+	BUG_ON(PageWriteback(page));
+	set_page_writeback(page);
+	unlock_page(page);
 
-static int reiserfs_readpage (struct file *f, struct page * page)
-{
-    return block_read_full_page (page, reiserfs_get_block);
+	/*
+	 * since any buffer might be the only dirty buffer on the page, 
+	 * the first submit_bh can bring the page out of writeback.
+	 * be careful with the buffers.
+	 */
+	do {
+		struct buffer_head *next = bh->b_this_page;
+		if (buffer_async_write(bh)) {
+			submit_bh(WRITE, bh);
+			nr++;
+		}
+		put_bh(bh);
+		bh = next;
+	} while (bh != head);
+
+	error = 0;
+      done:
+	if (nr == 0) {
+		/*
+		 * if this page only had a direct item, it is very possible for
+		 * no io to be required without there being an error.  Or, 
+		 * someone else could have locked them and sent them down the 
+		 * pipe without locking the page
+		 */
+		bh = head;
+		do {
+			if (!buffer_uptodate(bh)) {
+				partial = 1;
+				break;
+			}
+			bh = bh->b_this_page;
+		} while (bh != head);
+		if (!partial)
+			SetPageUptodate(page);
+		end_page_writeback(page);
+	}
+	return error;
+
+      fail:
+	/* catches various errors, we need to make sure any valid dirty blocks
+	 * get to the media.  The page is currently locked and not marked for 
+	 * writeback
+	 */
+	ClearPageUptodate(page);
+	bh = head;
+	do {
+		get_bh(bh);
+		if (buffer_mapped(bh) && buffer_dirty(bh) && bh->b_blocknr) {
+			lock_buffer(bh);
+			mark_buffer_async_write(bh);
+		} else {
+			/*
+			 * clear any dirty bits that might have come from getting
+			 * attached to a dirty page
+			 */
+			clear_buffer_dirty(bh);
+		}
+		bh = bh->b_this_page;
+	} while (bh != head);
+	SetPageError(page);
+	BUG_ON(PageWriteback(page));
+	set_page_writeback(page);
+	unlock_page(page);
+	do {
+		struct buffer_head *next = bh->b_this_page;
+		if (buffer_async_write(bh)) {
+			clear_buffer_dirty(bh);
+			submit_bh(WRITE, bh);
+			nr++;
+		}
+		put_bh(bh);
+		bh = next;
+	} while (bh != head);
+	goto done;
 }
 
+static int reiserfs_readpage(struct file *f, struct page *page)
+{
+	return block_read_full_page(page, reiserfs_get_block);
+}
 
-static int reiserfs_writepage (struct page * page, struct writeback_control *wbc)
+static int reiserfs_writepage(struct page *page, struct writeback_control *wbc)
 {
-    struct inode *inode = page->mapping->host ;
-    reiserfs_wait_on_write_block(inode->i_sb) ;
-    return reiserfs_write_full_page(page, wbc) ;
+	struct inode *inode = page->mapping->host;
+	reiserfs_wait_on_write_block(inode->i_sb);
+	return reiserfs_write_full_page(page, wbc);
 }
 
 static int reiserfs_prepare_write(struct file *f, struct page *page,
-			   unsigned from, unsigned to) {
-    struct inode *inode = page->mapping->host ;
-    int ret;
-    int old_ref = 0;
-
-    reiserfs_wait_on_write_block(inode->i_sb) ;
-    fix_tail_page_for_writing(page) ;
-    if (reiserfs_transaction_running(inode->i_sb)) {
-	struct reiserfs_transaction_handle *th;
-	th = (struct reiserfs_transaction_handle *)current->journal_info;
-        BUG_ON (!th->t_refcount);
-        BUG_ON (!th->t_trans_id);
-	old_ref = th->t_refcount;
-	th->t_refcount++;
-    }
-
-    ret = block_prepare_write(page, from, to, reiserfs_get_block) ;
-    if (ret && reiserfs_transaction_running(inode->i_sb)) {
-    	struct reiserfs_transaction_handle *th = current->journal_info;
-	/* this gets a little ugly.  If reiserfs_get_block returned an
-	 * error and left a transacstion running, we've got to close it,
-	 * and we've got to free handle if it was a persistent transaction.
-	 *
-	 * But, if we had nested into an existing transaction, we need
-	 * to just drop the ref count on the handle.
-	 *
-	 * If old_ref == 0, the transaction is from reiserfs_get_block,
-	 * and it was a persistent trans.  Otherwise, it was nested above.
-	 */
-	if (th->t_refcount > old_ref) {
-	    if (old_ref)
-	    	th->t_refcount--;
-	    else {
-                int err;
-		reiserfs_write_lock(inode->i_sb);
-		err = reiserfs_end_persistent_transaction(th);
-		reiserfs_write_unlock(inode->i_sb);
-                if (err)
-                    ret = err;
-	    }
-	}
-    }
-    return ret;
+				  unsigned from, unsigned to)
+{
+	struct inode *inode = page->mapping->host;
+	int ret;
+	int old_ref = 0;
+
+	reiserfs_wait_on_write_block(inode->i_sb);
+	fix_tail_page_for_writing(page);
+	if (reiserfs_transaction_running(inode->i_sb)) {
+		struct reiserfs_transaction_handle *th;
+		th = (struct reiserfs_transaction_handle *)current->
+		    journal_info;
+		BUG_ON(!th->t_refcount);
+		BUG_ON(!th->t_trans_id);
+		old_ref = th->t_refcount;
+		th->t_refcount++;
+	}
+
+	ret = block_prepare_write(page, from, to, reiserfs_get_block);
+	if (ret && reiserfs_transaction_running(inode->i_sb)) {
+		struct reiserfs_transaction_handle *th = current->journal_info;
+		/* this gets a little ugly.  If reiserfs_get_block returned an
+		 * error and left a transacstion running, we've got to close it,
+		 * and we've got to free handle if it was a persistent transaction.
+		 *
+		 * But, if we had nested into an existing transaction, we need
+		 * to just drop the ref count on the handle.
+		 *
+		 * If old_ref == 0, the transaction is from reiserfs_get_block,
+		 * and it was a persistent trans.  Otherwise, it was nested above.
+		 */
+		if (th->t_refcount > old_ref) {
+			if (old_ref)
+				th->t_refcount--;
+			else {
+				int err;
+				reiserfs_write_lock(inode->i_sb);
+				err = reiserfs_end_persistent_transaction(th);
+				reiserfs_write_unlock(inode->i_sb);
+				if (err)
+					ret = err;
+			}
+		}
+	}
+	return ret;
 
 }
 
+static sector_t reiserfs_aop_bmap(struct address_space *as, sector_t block)
+{
+	return generic_block_bmap(as, block, reiserfs_bmap);
+}
 
-static sector_t reiserfs_aop_bmap(struct address_space *as, sector_t block) {
-  return generic_block_bmap(as, block, reiserfs_bmap) ;
-}
-
-static int reiserfs_commit_write(struct file *f, struct page *page, 
-                                 unsigned from, unsigned to) {
-    struct inode *inode = page->mapping->host ;
-    loff_t pos = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to;
-    int ret = 0;
-    int update_sd = 0;
-    struct reiserfs_transaction_handle *th = NULL;
-    
-    reiserfs_wait_on_write_block(inode->i_sb) ;
-    if (reiserfs_transaction_running(inode->i_sb)) {
-        th = current->journal_info;
-    }
-    reiserfs_commit_page(inode, page, from, to);
- 
-    /* generic_commit_write does this for us, but does not update the
-    ** transaction tracking stuff when the size changes.  So, we have
-    ** to do the i_size updates here.
-    */
-    if (pos > inode->i_size) {
-	struct reiserfs_transaction_handle myth ;
-	reiserfs_write_lock(inode->i_sb);
-	/* If the file have grown beyond the border where it
-	   can have a tail, unmark it as needing a tail
-	   packing */
-	if ( (have_large_tails (inode->i_sb) && inode->i_size > i_block_size (inode)*4) ||
-	     (have_small_tails (inode->i_sb) && inode->i_size > i_block_size(inode)) )
-	    REISERFS_I(inode)->i_flags &= ~i_pack_on_close_mask ;
-
-	ret = journal_begin(&myth, inode->i_sb, 1) ;
-	if (ret) {
-	    reiserfs_write_unlock(inode->i_sb);
-	    goto journal_error;
-	}
-	reiserfs_update_inode_transaction(inode) ;
-	inode->i_size = pos ;
-	reiserfs_update_sd(&myth, inode) ;
-	update_sd = 1;
-	ret = journal_end(&myth, inode->i_sb, 1) ;
-	reiserfs_write_unlock(inode->i_sb);
-	if (ret)
-	    goto journal_error;
-    }
-    if (th) {
-	reiserfs_write_lock(inode->i_sb);
-	if (!update_sd)
-	    reiserfs_update_sd(th, inode) ;
-	ret = reiserfs_end_persistent_transaction(th);
-	reiserfs_write_unlock(inode->i_sb);
-	if (ret)
-	    goto out;
-    }
- 
-    /* we test for O_SYNC here so we can commit the transaction
-    ** for any packed tails the file might have had
-    */
-    if (f && (f->f_flags & O_SYNC)) {
-	reiserfs_write_lock(inode->i_sb);
- 	ret = reiserfs_commit_for_inode(inode) ;
-	reiserfs_write_unlock(inode->i_sb);
-    }
-out:
-    return ret ;
+static int reiserfs_commit_write(struct file *f, struct page *page,
+				 unsigned from, unsigned to)
+{
+	struct inode *inode = page->mapping->host;
+	loff_t pos = ((loff_t) page->index << PAGE_CACHE_SHIFT) + to;
+	int ret = 0;
+	int update_sd = 0;
+	struct reiserfs_transaction_handle *th = NULL;
+
+	reiserfs_wait_on_write_block(inode->i_sb);
+	if (reiserfs_transaction_running(inode->i_sb)) {
+		th = current->journal_info;
+	}
+	reiserfs_commit_page(inode, page, from, to);
+
+	/* generic_commit_write does this for us, but does not update the
+	 ** transaction tracking stuff when the size changes.  So, we have
+	 ** to do the i_size updates here.
+	 */
+	if (pos > inode->i_size) {
+		struct reiserfs_transaction_handle myth;
+		reiserfs_write_lock(inode->i_sb);
+		/* If the file have grown beyond the border where it
+		   can have a tail, unmark it as needing a tail
+		   packing */
+		if ((have_large_tails(inode->i_sb)
+		     && inode->i_size > i_block_size(inode) * 4)
+		    || (have_small_tails(inode->i_sb)
+			&& inode->i_size > i_block_size(inode)))
+			REISERFS_I(inode)->i_flags &= ~i_pack_on_close_mask;
+
+		ret = journal_begin(&myth, inode->i_sb, 1);
+		if (ret) {
+			reiserfs_write_unlock(inode->i_sb);
+			goto journal_error;
+		}
+		reiserfs_update_inode_transaction(inode);
+		inode->i_size = pos;
+		reiserfs_update_sd(&myth, inode);
+		update_sd = 1;
+		ret = journal_end(&myth, inode->i_sb, 1);
+		reiserfs_write_unlock(inode->i_sb);
+		if (ret)
+			goto journal_error;
+	}
+	if (th) {
+		reiserfs_write_lock(inode->i_sb);
+		if (!update_sd)
+			reiserfs_update_sd(th, inode);
+		ret = reiserfs_end_persistent_transaction(th);
+		reiserfs_write_unlock(inode->i_sb);
+		if (ret)
+			goto out;
+	}
 
-journal_error:
-    if (th) {
-	reiserfs_write_lock(inode->i_sb);
-	if (!update_sd)
-	    reiserfs_update_sd(th, inode) ;
-        ret = reiserfs_end_persistent_transaction(th);
-	reiserfs_write_unlock(inode->i_sb);
-    }
+	/* we test for O_SYNC here so we can commit the transaction
+	 ** for any packed tails the file might have had
+	 */
+	if (f && (f->f_flags & O_SYNC)) {
+		reiserfs_write_lock(inode->i_sb);
+		ret = reiserfs_commit_for_inode(inode);
+		reiserfs_write_unlock(inode->i_sb);
+	}
+      out:
+	return ret;
+
+      journal_error:
+	if (th) {
+		reiserfs_write_lock(inode->i_sb);
+		if (!update_sd)
+			reiserfs_update_sd(th, inode);
+		ret = reiserfs_end_persistent_transaction(th);
+		reiserfs_write_unlock(inode->i_sb);
+	}
 
-    return ret;
+	return ret;
 }
 
-void sd_attrs_to_i_attrs( __u16 sd_attrs, struct inode *inode )
+void sd_attrs_to_i_attrs(__u16 sd_attrs, struct inode *inode)
 {
-	if( reiserfs_attrs( inode -> i_sb ) ) {
-		if( sd_attrs & REISERFS_SYNC_FL )
-			inode -> i_flags |= S_SYNC;
+	if (reiserfs_attrs(inode->i_sb)) {
+		if (sd_attrs & REISERFS_SYNC_FL)
+			inode->i_flags |= S_SYNC;
 		else
-			inode -> i_flags &= ~S_SYNC;
-		if( sd_attrs & REISERFS_IMMUTABLE_FL )
-			inode -> i_flags |= S_IMMUTABLE;
+			inode->i_flags &= ~S_SYNC;
+		if (sd_attrs & REISERFS_IMMUTABLE_FL)
+			inode->i_flags |= S_IMMUTABLE;
 		else
-			inode -> i_flags &= ~S_IMMUTABLE;
-		if( sd_attrs & REISERFS_APPEND_FL )
-			inode -> i_flags |= S_APPEND;
+			inode->i_flags &= ~S_IMMUTABLE;
+		if (sd_attrs & REISERFS_APPEND_FL)
+			inode->i_flags |= S_APPEND;
 		else
-			inode -> i_flags &= ~S_APPEND;
-		if( sd_attrs & REISERFS_NOATIME_FL )
-			inode -> i_flags |= S_NOATIME;
+			inode->i_flags &= ~S_APPEND;
+		if (sd_attrs & REISERFS_NOATIME_FL)
+			inode->i_flags |= S_NOATIME;
 		else
-			inode -> i_flags &= ~S_NOATIME;
-		if( sd_attrs & REISERFS_NOTAIL_FL )
+			inode->i_flags &= ~S_NOATIME;
+		if (sd_attrs & REISERFS_NOTAIL_FL)
 			REISERFS_I(inode)->i_flags |= i_nopack_mask;
 		else
 			REISERFS_I(inode)->i_flags &= ~i_nopack_mask;
 	}
 }
 
-void i_attrs_to_sd_attrs( struct inode *inode, __u16 *sd_attrs )
+void i_attrs_to_sd_attrs(struct inode *inode, __u16 * sd_attrs)
 {
-	if( reiserfs_attrs( inode -> i_sb ) ) {
-		if( inode -> i_flags & S_IMMUTABLE )
+	if (reiserfs_attrs(inode->i_sb)) {
+		if (inode->i_flags & S_IMMUTABLE)
 			*sd_attrs |= REISERFS_IMMUTABLE_FL;
 		else
 			*sd_attrs &= ~REISERFS_IMMUTABLE_FL;
-		if( inode -> i_flags & S_SYNC )
+		if (inode->i_flags & S_SYNC)
 			*sd_attrs |= REISERFS_SYNC_FL;
 		else
 			*sd_attrs &= ~REISERFS_SYNC_FL;
-		if( inode -> i_flags & S_NOATIME )
+		if (inode->i_flags & S_NOATIME)
 			*sd_attrs |= REISERFS_NOATIME_FL;
 		else
 			*sd_attrs &= ~REISERFS_NOATIME_FL;
-		if( REISERFS_I(inode)->i_flags & i_nopack_mask )
+		if (REISERFS_I(inode)->i_flags & i_nopack_mask)
 			*sd_attrs |= REISERFS_NOTAIL_FL;
 		else
 			*sd_attrs &= ~REISERFS_NOTAIL_FL;
@@ -2594,106 +2730,107 @@ void i_attrs_to_sd_attrs( struct inode *
 */
 static int invalidatepage_can_drop(struct inode *inode, struct buffer_head *bh)
 {
-    int ret = 1 ;
-    struct reiserfs_journal *j = SB_JOURNAL(inode->i_sb) ;
+	int ret = 1;
+	struct reiserfs_journal *j = SB_JOURNAL(inode->i_sb);
 
-    spin_lock(&j->j_dirty_buffers_lock) ;
-    if (!buffer_mapped(bh)) {
-        goto free_jh;
-    }
-    /* the page is locked, and the only places that log a data buffer
-     * also lock the page.
-     */
-    if (reiserfs_file_data_log(inode)) {
-	/*
-	 * very conservative, leave the buffer pinned if
-	 * anyone might need it.
+	spin_lock(&j->j_dirty_buffers_lock);
+	if (!buffer_mapped(bh)) {
+		goto free_jh;
+	}
+	/* the page is locked, and the only places that log a data buffer
+	 * also lock the page.
 	 */
-        if (buffer_journaled(bh) || buffer_journal_dirty(bh)) {
-	    ret = 0 ;
+	if (reiserfs_file_data_log(inode)) {
+		/*
+		 * very conservative, leave the buffer pinned if
+		 * anyone might need it.
+		 */
+		if (buffer_journaled(bh) || buffer_journal_dirty(bh)) {
+			ret = 0;
+		}
+	} else if (buffer_dirty(bh) || buffer_locked(bh)) {
+		struct reiserfs_journal_list *jl;
+		struct reiserfs_jh *jh = bh->b_private;
+
+		/* why is this safe?
+		 * reiserfs_setattr updates i_size in the on disk
+		 * stat data before allowing vmtruncate to be called.
+		 *
+		 * If buffer was put onto the ordered list for this
+		 * transaction, we know for sure either this transaction
+		 * or an older one already has updated i_size on disk,
+		 * and this ordered data won't be referenced in the file
+		 * if we crash.
+		 *
+		 * if the buffer was put onto the ordered list for an older
+		 * transaction, we need to leave it around
+		 */
+		if (jh && (jl = jh->jl)
+		    && jl != SB_JOURNAL(inode->i_sb)->j_current_jl)
+			ret = 0;
 	}
-    } else
-    if (buffer_dirty(bh) || buffer_locked(bh)) {
-	struct reiserfs_journal_list *jl;
-	struct reiserfs_jh *jh = bh->b_private;
-
-	/* why is this safe?
-	 * reiserfs_setattr updates i_size in the on disk
-	 * stat data before allowing vmtruncate to be called.
-	 *
-	 * If buffer was put onto the ordered list for this
-	 * transaction, we know for sure either this transaction
-	 * or an older one already has updated i_size on disk,
-	 * and this ordered data won't be referenced in the file
-	 * if we crash.
-	 *
-	 * if the buffer was put onto the ordered list for an older
-	 * transaction, we need to leave it around
-	 */
-	if (jh && (jl = jh->jl) && jl != SB_JOURNAL(inode->i_sb)->j_current_jl)
-	    ret = 0;
-    }
-free_jh:
-    if (ret && bh->b_private) {
-        reiserfs_free_jh(bh);
-    }
-    spin_unlock(&j->j_dirty_buffers_lock) ;
-    return ret ;
+      free_jh:
+	if (ret && bh->b_private) {
+		reiserfs_free_jh(bh);
+	}
+	spin_unlock(&j->j_dirty_buffers_lock);
+	return ret;
 }
 
 /* clm -- taken from fs/buffer.c:block_invalidate_page */
 static int reiserfs_invalidatepage(struct page *page, unsigned long offset)
 {
-    struct buffer_head *head, *bh, *next;
-    struct inode *inode = page->mapping->host;
-    unsigned int curr_off = 0;
-    int ret = 1;
-
-    BUG_ON(!PageLocked(page));
-
-    if (offset == 0)
-	ClearPageChecked(page);
-
-    if (!page_has_buffers(page))
-	goto out;
-
-    head = page_buffers(page);
-    bh = head;
-    do {
-	unsigned int next_off = curr_off + bh->b_size;
-	next = bh->b_this_page;
+	struct buffer_head *head, *bh, *next;
+	struct inode *inode = page->mapping->host;
+	unsigned int curr_off = 0;
+	int ret = 1;
+
+	BUG_ON(!PageLocked(page));
+
+	if (offset == 0)
+		ClearPageChecked(page);
+
+	if (!page_has_buffers(page))
+		goto out;
+
+	head = page_buffers(page);
+	bh = head;
+	do {
+		unsigned int next_off = curr_off + bh->b_size;
+		next = bh->b_this_page;
+
+		/*
+		 * is this block fully invalidated?
+		 */
+		if (offset <= curr_off) {
+			if (invalidatepage_can_drop(inode, bh))
+				reiserfs_unmap_buffer(bh);
+			else
+				ret = 0;
+		}
+		curr_off = next_off;
+		bh = next;
+	} while (bh != head);
 
 	/*
-	 * is this block fully invalidated?
+	 * We release buffers only if the entire page is being invalidated.
+	 * The get_block cached value has been unconditionally invalidated,
+	 * so real IO is not possible anymore.
 	 */
-	if (offset <= curr_off) {
-	    if (invalidatepage_can_drop(inode, bh))
-		reiserfs_unmap_buffer(bh);
-	    else
-	        ret = 0;
-	}
-	curr_off = next_off;
-	bh = next;
-    } while (bh != head);
-
-    /*
-     * We release buffers only if the entire page is being invalidated.
-     * The get_block cached value has been unconditionally invalidated,
-     * so real IO is not possible anymore.
-     */
-    if (!offset && ret)
-	ret = try_to_release_page(page, 0);
-out:
-    return ret;
-}
-
-static int reiserfs_set_page_dirty(struct page *page) {
-    struct inode *inode = page->mapping->host;
-    if (reiserfs_file_data_log(inode)) {
-	SetPageChecked(page);
-	return __set_page_dirty_nobuffers(page);
-    }
-    return __set_page_dirty_buffers(page);
+	if (!offset && ret)
+		ret = try_to_release_page(page, 0);
+      out:
+	return ret;
+}
+
+static int reiserfs_set_page_dirty(struct page *page)
+{
+	struct inode *inode = page->mapping->host;
+	if (reiserfs_file_data_log(inode)) {
+		SetPageChecked(page);
+		return __set_page_dirty_nobuffers(page);
+	}
+	return __set_page_dirty_buffers(page);
 }
 
 /*
@@ -2707,140 +2844,152 @@ static int reiserfs_set_page_dirty(struc
  */
 static int reiserfs_releasepage(struct page *page, int unused_gfp_flags)
 {
-    struct inode *inode = page->mapping->host ;
-    struct reiserfs_journal *j = SB_JOURNAL(inode->i_sb) ;
-    struct buffer_head *head ;
-    struct buffer_head *bh ;
-    int ret = 1 ;
-
-    WARN_ON(PageChecked(page));
-    spin_lock(&j->j_dirty_buffers_lock) ;
-    head = page_buffers(page) ;
-    bh = head ;
-    do {
-	if (bh->b_private) {
-	    if (!buffer_dirty(bh) && !buffer_locked(bh)) {
-		reiserfs_free_jh(bh);
-	    } else {
-		ret = 0 ;
-		break ;
-	    }
-	}
-	bh = bh->b_this_page ;
-    } while (bh != head) ;
-    if (ret)
-	ret = try_to_free_buffers(page) ;
-    spin_unlock(&j->j_dirty_buffers_lock) ;
-    return ret ;
+	struct inode *inode = page->mapping->host;
+	struct reiserfs_journal *j = SB_JOURNAL(inode->i_sb);
+	struct buffer_head *head;
+	struct buffer_head *bh;
+	int ret = 1;
+
+	WARN_ON(PageChecked(page));
+	spin_lock(&j->j_dirty_buffers_lock);
+	head = page_buffers(page);
+	bh = head;
+	do {
+		if (bh->b_private) {
+			if (!buffer_dirty(bh) && !buffer_locked(bh)) {
+				reiserfs_free_jh(bh);
+			} else {
+				ret = 0;
+				break;
+			}
+		}
+		bh = bh->b_this_page;
+	} while (bh != head);
+	if (ret)
+		ret = try_to_free_buffers(page);
+	spin_unlock(&j->j_dirty_buffers_lock);
+	return ret;
 }
 
 /* We thank Mingming Cao for helping us understand in great detail what
    to do in this section of the code. */
 static ssize_t reiserfs_direct_IO(int rw, struct kiocb *iocb,
-		const struct iovec *iov, loff_t offset, unsigned long nr_segs)
+				  const struct iovec *iov, loff_t offset,
+				  unsigned long nr_segs)
 {
-    struct file *file = iocb->ki_filp;
-    struct inode *inode = file->f_mapping->host;
+	struct file *file = iocb->ki_filp;
+	struct inode *inode = file->f_mapping->host;
 
-    return blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov,
-			offset, nr_segs, reiserfs_get_blocks_direct_io, NULL);
+	return blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov,
+				  offset, nr_segs,
+				  reiserfs_get_blocks_direct_io, NULL);
 }
 
-int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) {
-    struct inode *inode = dentry->d_inode ;
-    int error ;
-    unsigned int ia_valid = attr->ia_valid;
-    reiserfs_write_lock(inode->i_sb);
-    if (attr->ia_valid & ATTR_SIZE) {
-	/* version 2 items will be caught by the s_maxbytes check
-	** done for us in vmtruncate
-	*/
-	if (get_inode_item_key_version(inode) == KEY_FORMAT_3_5 &&
-	    attr->ia_size > MAX_NON_LFS) {
-	    error = -EFBIG ;
-	    goto out;
-	}
-	/* fill in hole pointers in the expanding truncate case. */
-        if (attr->ia_size > inode->i_size) {
-	    error = generic_cont_expand(inode, attr->ia_size) ;
-	    if (REISERFS_I(inode)->i_prealloc_count > 0) {
-		int err;
-		struct reiserfs_transaction_handle th ;
-		/* we're changing at most 2 bitmaps, inode + super */
-		err = journal_begin(&th, inode->i_sb, 4) ;
-		if (!err) {
-		    reiserfs_discard_prealloc (&th, inode);
-		    err = journal_end(&th, inode->i_sb, 4) ;
+int reiserfs_setattr(struct dentry *dentry, struct iattr *attr)
+{
+	struct inode *inode = dentry->d_inode;
+	int error;
+	unsigned int ia_valid = attr->ia_valid;
+	reiserfs_write_lock(inode->i_sb);
+	if (attr->ia_valid & ATTR_SIZE) {
+		/* version 2 items will be caught by the s_maxbytes check
+		 ** done for us in vmtruncate
+		 */
+		if (get_inode_item_key_version(inode) == KEY_FORMAT_3_5 &&
+		    attr->ia_size > MAX_NON_LFS) {
+			error = -EFBIG;
+			goto out;
 		}
-		if (err)
-		    error = err;
-	    }
-	    if (error)
-	        goto out;
-	}
-    }
-
-    if ((((attr->ia_valid & ATTR_UID) && (attr->ia_uid & ~0xffff)) ||
-	 ((attr->ia_valid & ATTR_GID) && (attr->ia_gid & ~0xffff))) &&
-	(get_inode_sd_version (inode) == STAT_DATA_V1)) {
+		/* fill in hole pointers in the expanding truncate case. */
+		if (attr->ia_size > inode->i_size) {
+			error = generic_cont_expand(inode, attr->ia_size);
+			if (REISERFS_I(inode)->i_prealloc_count > 0) {
+				int err;
+				struct reiserfs_transaction_handle th;
+				/* we're changing at most 2 bitmaps, inode + super */
+				err = journal_begin(&th, inode->i_sb, 4);
+				if (!err) {
+					reiserfs_discard_prealloc(&th, inode);
+					err = journal_end(&th, inode->i_sb, 4);
+				}
+				if (err)
+					error = err;
+			}
+			if (error)
+				goto out;
+		}
+	}
+
+	if ((((attr->ia_valid & ATTR_UID) && (attr->ia_uid & ~0xffff)) ||
+	     ((attr->ia_valid & ATTR_GID) && (attr->ia_gid & ~0xffff))) &&
+	    (get_inode_sd_version(inode) == STAT_DATA_V1)) {
 		/* stat data of format v3.5 has 16 bit uid and gid */
-	    error = -EINVAL;
-	    goto out;
+		error = -EINVAL;
+		goto out;
 	}
 
-    error = inode_change_ok(inode, attr) ;
-    if (!error) {
-	if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) ||
-	    (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) {
-                error = reiserfs_chown_xattrs (inode, attr);
-
-                if (!error) {
-		    struct reiserfs_transaction_handle th;
-
-		    /* (user+group)*(old+new) structure - we count quota info and , inode write (sb, inode) */
-		    journal_begin(&th, inode->i_sb, 4*REISERFS_QUOTA_INIT_BLOCKS+2);
-                    error = DQUOT_TRANSFER(inode, attr) ? -EDQUOT : 0;
-		    if (error) {
-			journal_end(&th, inode->i_sb, 4*REISERFS_QUOTA_INIT_BLOCKS+2);
-			goto out;
-		    }
-		    /* Update corresponding info in inode so that everything is in
-		     * one transaction */
-		    if (attr->ia_valid & ATTR_UID)
-			inode->i_uid = attr->ia_uid;
-		    if (attr->ia_valid & ATTR_GID)
-			inode->i_gid = attr->ia_gid;
-		    mark_inode_dirty(inode);
-		    journal_end(&th, inode->i_sb, 4*REISERFS_QUOTA_INIT_BLOCKS+2);
-		}
-        }
-        if (!error)
-            error = inode_setattr(inode, attr) ;
-    }
-
-
-    if (!error && reiserfs_posixacl (inode->i_sb)) {
-        if (attr->ia_valid & ATTR_MODE)
-            error = reiserfs_acl_chmod (inode);
-    }
-
-out:
-    reiserfs_write_unlock(inode->i_sb);
-    return error ;
-}
+	error = inode_change_ok(inode, attr);
+	if (!error) {
+		if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) ||
+		    (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) {
+			error = reiserfs_chown_xattrs(inode, attr);
+
+			if (!error) {
+				struct reiserfs_transaction_handle th;
+				int jbegin_count =
+				    2 *
+				    (REISERFS_QUOTA_INIT_BLOCKS(inode->i_sb) +
+				     REISERFS_QUOTA_DEL_BLOCKS(inode->i_sb)) +
+				    2;
+
+				/* (user+group)*(old+new) structure - we count quota info and , inode write (sb, inode) */
+				error =
+				    journal_begin(&th, inode->i_sb,
+						  jbegin_count);
+				if (error)
+					goto out;
+				error =
+				    DQUOT_TRANSFER(inode, attr) ? -EDQUOT : 0;
+				if (error) {
+					journal_end(&th, inode->i_sb,
+						    jbegin_count);
+					goto out;
+				}
+				/* Update corresponding info in inode so that everything is in
+				 * one transaction */
+				if (attr->ia_valid & ATTR_UID)
+					inode->i_uid = attr->ia_uid;
+				if (attr->ia_valid & ATTR_GID)
+					inode->i_gid = attr->ia_gid;
+				mark_inode_dirty(inode);
+				error =
+				    journal_end(&th, inode->i_sb, jbegin_count);
+			}
+		}
+		if (!error)
+			error = inode_setattr(inode, attr);
+	}
 
+	if (!error && reiserfs_posixacl(inode->i_sb)) {
+		if (attr->ia_valid & ATTR_MODE)
+			error = reiserfs_acl_chmod(inode);
+	}
 
+      out:
+	reiserfs_write_unlock(inode->i_sb);
+	return error;
+}
 
 struct address_space_operations reiserfs_address_space_operations = {
-    .writepage = reiserfs_writepage,
-    .readpage = reiserfs_readpage, 
-    .readpages = reiserfs_readpages, 
-    .releasepage = reiserfs_releasepage,
-    .invalidatepage = reiserfs_invalidatepage,
-    .sync_page = block_sync_page,
-    .prepare_write = reiserfs_prepare_write,
-    .commit_write = reiserfs_commit_write,
-    .bmap = reiserfs_aop_bmap,
-    .direct_IO = reiserfs_direct_IO,
-    .set_page_dirty = reiserfs_set_page_dirty,
-} ;
+	.writepage = reiserfs_writepage,
+	.readpage = reiserfs_readpage,
+	.readpages = reiserfs_readpages,
+	.releasepage = reiserfs_releasepage,
+	.invalidatepage = reiserfs_invalidatepage,
+	.sync_page = block_sync_page,
+	.prepare_write = reiserfs_prepare_write,
+	.commit_write = reiserfs_commit_write,
+	.bmap = reiserfs_aop_bmap,
+	.direct_IO = reiserfs_direct_IO,
+	.set_page_dirty = reiserfs_set_page_dirty,
+};
diff --git a/fs/reiserfs/ioctl.c b/fs/reiserfs/ioctl.c
--- a/fs/reiserfs/ioctl.c
+++ b/fs/reiserfs/ioctl.c
@@ -9,7 +9,7 @@
 #include <linux/pagemap.h>
 #include <linux/smp_lock.h>
 
-static int reiserfs_unpack (struct inode * inode, struct file * filp);
+static int reiserfs_unpack(struct inode *inode, struct file *filp);
 
 /*
 ** reiserfs_ioctl - handler for ioctl for inode
@@ -19,63 +19,72 @@ static int reiserfs_unpack (struct inode
 **  2) REISERFS_IOC_[GS]ETFLAGS, REISERFS_IOC_[GS]ETVERSION
 **  3) That's all for a while ...
 */
-int reiserfs_ioctl (struct inode * inode, struct file * filp, unsigned int cmd,
-		unsigned long arg)
+int reiserfs_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
+		   unsigned long arg)
 {
 	unsigned int flags;
 
 	switch (cmd) {
-	    case REISERFS_IOC_UNPACK:
-		if( S_ISREG( inode -> i_mode ) ) {
-		if (arg)
-		    return reiserfs_unpack (inode, filp);
+	case REISERFS_IOC_UNPACK:
+		if (S_ISREG(inode->i_mode)) {
+			if (arg)
+				return reiserfs_unpack(inode, filp);
 			else
 				return 0;
 		} else
 			return -ENOTTY;
-	/* following two cases are taken from fs/ext2/ioctl.c by Remy
-	   Card (card@masi.ibp.fr) */
+		/* following two cases are taken from fs/ext2/ioctl.c by Remy
+		   Card (card@masi.ibp.fr) */
 	case REISERFS_IOC_GETFLAGS:
-		flags = REISERFS_I(inode) -> i_attrs;
-		i_attrs_to_sd_attrs( inode, ( __u16 * ) &flags );
-		return put_user(flags, (int __user *) arg);
-	case REISERFS_IOC_SETFLAGS: {
-		if (IS_RDONLY(inode))
-			return -EROFS;
+		if (!reiserfs_attrs(inode->i_sb))
+			return -ENOTTY;
 
-		if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
-			return -EPERM;
+		flags = REISERFS_I(inode)->i_attrs;
+		i_attrs_to_sd_attrs(inode, (__u16 *) & flags);
+		return put_user(flags, (int __user *)arg);
+	case REISERFS_IOC_SETFLAGS:{
+			if (!reiserfs_attrs(inode->i_sb))
+				return -ENOTTY;
+
+			if (IS_RDONLY(inode))
+				return -EROFS;
+
+			if ((current->fsuid != inode->i_uid)
+			    && !capable(CAP_FOWNER))
+				return -EPERM;
+
+			if (get_user(flags, (int __user *)arg))
+				return -EFAULT;
+
+			if (((flags ^ REISERFS_I(inode)->
+			      i_attrs) & (REISERFS_IMMUTABLE_FL |
+					  REISERFS_APPEND_FL))
+			    && !capable(CAP_LINUX_IMMUTABLE))
+				return -EPERM;
 
-		if (get_user(flags, (int __user *) arg))
-			return -EFAULT;
-
-		if ( ( ( flags ^ REISERFS_I(inode) -> i_attrs) & ( REISERFS_IMMUTABLE_FL | REISERFS_APPEND_FL)) &&
-		     !capable( CAP_LINUX_IMMUTABLE ) )
-			return -EPERM;
-			
-		if( ( flags & REISERFS_NOTAIL_FL ) &&
-		    S_ISREG( inode -> i_mode ) ) {
+			if ((flags & REISERFS_NOTAIL_FL) &&
+			    S_ISREG(inode->i_mode)) {
 				int result;
 
-				result = reiserfs_unpack( inode, filp );
-				if( result )
+				result = reiserfs_unpack(inode, filp);
+				if (result)
 					return result;
+			}
+			sd_attrs_to_i_attrs(flags, inode);
+			REISERFS_I(inode)->i_attrs = flags;
+			inode->i_ctime = CURRENT_TIME_SEC;
+			mark_inode_dirty(inode);
+			return 0;
 		}
-		sd_attrs_to_i_attrs( flags, inode );
-		REISERFS_I(inode) -> i_attrs = flags;
-		inode->i_ctime = CURRENT_TIME_SEC;
-		mark_inode_dirty(inode);
-		return 0;
-	}
 	case REISERFS_IOC_GETVERSION:
-		return put_user(inode->i_generation, (int __user *) arg);
+		return put_user(inode->i_generation, (int __user *)arg);
 	case REISERFS_IOC_SETVERSION:
 		if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
 			return -EPERM;
 		if (IS_RDONLY(inode))
 			return -EROFS;
-		if (get_user(inode->i_generation, (int __user *) arg))
-			return -EFAULT;	
+		if (get_user(inode->i_generation, (int __user *)arg))
+			return -EFAULT;
 		inode->i_ctime = CURRENT_TIME_SEC;
 		mark_inode_dirty(inode);
 		return 0;
@@ -89,63 +98,65 @@ int reiserfs_ioctl (struct inode * inode
 ** Function try to convert tail from direct item into indirect.
 ** It set up nopack attribute in the REISERFS_I(inode)->nopack
 */
-static int reiserfs_unpack (struct inode * inode, struct file * filp)
+static int reiserfs_unpack(struct inode *inode, struct file *filp)
 {
-    int retval = 0;
-    int index ;
-    struct page *page ;
-    struct address_space *mapping ;
-    unsigned long write_from ;
-    unsigned long blocksize = inode->i_sb->s_blocksize ;
-    	
-    if (inode->i_size == 0) {
-        REISERFS_I(inode)->i_flags |= i_nopack_mask;
-        return 0 ;
-    }
-    /* ioctl already done */
-    if (REISERFS_I(inode)->i_flags & i_nopack_mask) {
-        return 0 ;
-    }
-    reiserfs_write_lock(inode->i_sb);
-
-    /* we need to make sure nobody is changing the file size beneath
-    ** us
-    */
-    down(&inode->i_sem) ;
-
-    write_from = inode->i_size & (blocksize - 1) ;
-    /* if we are on a block boundary, we are already unpacked.  */
-    if ( write_from == 0) {
+	int retval = 0;
+	int index;
+	struct page *page;
+	struct address_space *mapping;
+	unsigned long write_from;
+	unsigned long blocksize = inode->i_sb->s_blocksize;
+
+	if (inode->i_size == 0) {
+		REISERFS_I(inode)->i_flags |= i_nopack_mask;
+		return 0;
+	}
+	/* ioctl already done */
+	if (REISERFS_I(inode)->i_flags & i_nopack_mask) {
+		return 0;
+	}
+	reiserfs_write_lock(inode->i_sb);
+
+	/* we need to make sure nobody is changing the file size beneath
+	 ** us
+	 */
+	down(&inode->i_sem);
+
+	write_from = inode->i_size & (blocksize - 1);
+	/* if we are on a block boundary, we are already unpacked.  */
+	if (write_from == 0) {
+		REISERFS_I(inode)->i_flags |= i_nopack_mask;
+		goto out;
+	}
+
+	/* we unpack by finding the page with the tail, and calling
+	 ** reiserfs_prepare_write on that page.  This will force a 
+	 ** reiserfs_get_block to unpack the tail for us.
+	 */
+	index = inode->i_size >> PAGE_CACHE_SHIFT;
+	mapping = inode->i_mapping;
+	page = grab_cache_page(mapping, index);
+	retval = -ENOMEM;
+	if (!page) {
+		goto out;
+	}
+	retval =
+	    mapping->a_ops->prepare_write(NULL, page, write_from, write_from);
+	if (retval)
+		goto out_unlock;
+
+	/* conversion can change page contents, must flush */
+	flush_dcache_page(page);
+	retval =
+	    mapping->a_ops->commit_write(NULL, page, write_from, write_from);
 	REISERFS_I(inode)->i_flags |= i_nopack_mask;
-	goto out ;
-    }
 
-    /* we unpack by finding the page with the tail, and calling
-    ** reiserfs_prepare_write on that page.  This will force a 
-    ** reiserfs_get_block to unpack the tail for us.
-    */
-    index = inode->i_size >> PAGE_CACHE_SHIFT ;
-    mapping = inode->i_mapping ;
-    page = grab_cache_page(mapping, index) ;
-    retval = -ENOMEM;
-    if (!page) {
-        goto out ;
-    }
-    retval = mapping->a_ops->prepare_write(NULL, page, write_from, write_from) ;
-    if (retval)
-        goto out_unlock ;
-
-    /* conversion can change page contents, must flush */
-    flush_dcache_page(page) ;
-    retval = mapping->a_ops->commit_write(NULL, page, write_from, write_from) ;
-    REISERFS_I(inode)->i_flags |= i_nopack_mask;
-
-out_unlock:
-    unlock_page(page) ;
-    page_cache_release(page) ;
-
-out:
-    up(&inode->i_sem) ;
-    reiserfs_write_unlock(inode->i_sb);
-    return retval;
+      out_unlock:
+	unlock_page(page);
+	page_cache_release(page);
+
+      out:
+	up(&inode->i_sem);
+	reiserfs_write_unlock(inode->i_sb);
+	return retval;
 }
diff --git a/fs/reiserfs/item_ops.c b/fs/reiserfs/item_ops.c
--- a/fs/reiserfs/item_ops.c
+++ b/fs/reiserfs/item_ops.c
@@ -14,776 +14,741 @@
 //////////////////////////////////////////////////////////////////////////////
 // stat data functions
 //
-static int sd_bytes_number (struct item_head * ih, int block_size)
+static int sd_bytes_number(struct item_head *ih, int block_size)
 {
-  return 0;
+	return 0;
 }
 
-static void sd_decrement_key (struct cpu_key * key)
+static void sd_decrement_key(struct cpu_key *key)
 {
-    key->on_disk_key.k_objectid --;
-    set_cpu_key_k_type (key, TYPE_ANY);
-    set_cpu_key_k_offset(key, (loff_t)(-1));
+	key->on_disk_key.k_objectid--;
+	set_cpu_key_k_type(key, TYPE_ANY);
+	set_cpu_key_k_offset(key, (loff_t) (-1));
 }
 
-static int sd_is_left_mergeable (struct reiserfs_key * key, unsigned long bsize)
+static int sd_is_left_mergeable(struct reiserfs_key *key, unsigned long bsize)
 {
-    return 0;
+	return 0;
 }
 
-
-
-static char * print_time (time_t t)
+static char *print_time(time_t t)
 {
-    static char timebuf[256];
+	static char timebuf[256];
 
-    sprintf (timebuf, "%ld", t);
-    return timebuf;
+	sprintf(timebuf, "%ld", t);
+	return timebuf;
 }
 
-
-static void sd_print_item (struct item_head * ih, char * item)
+static void sd_print_item(struct item_head *ih, char *item)
 {
-    printk ("\tmode | size | nlinks | first direct | mtime\n");
-    if (stat_data_v1 (ih)) {
-      	struct stat_data_v1 * sd = (struct stat_data_v1 *)item;
+	printk("\tmode | size | nlinks | first direct | mtime\n");
+	if (stat_data_v1(ih)) {
+		struct stat_data_v1 *sd = (struct stat_data_v1 *)item;
 
-	printk ("\t0%-6o | %6u | %2u | %d | %s\n", sd_v1_mode(sd),
-                sd_v1_size(sd), sd_v1_nlink(sd), sd_v1_first_direct_byte(sd),
-                print_time( sd_v1_mtime(sd) ) );
-    } else {
-	struct stat_data * sd = (struct stat_data *)item;
+		printk("\t0%-6o | %6u | %2u | %d | %s\n", sd_v1_mode(sd),
+		       sd_v1_size(sd), sd_v1_nlink(sd),
+		       sd_v1_first_direct_byte(sd),
+		       print_time(sd_v1_mtime(sd)));
+	} else {
+		struct stat_data *sd = (struct stat_data *)item;
 
-	printk ("\t0%-6o | %6Lu | %2u | %d | %s\n", sd_v2_mode(sd),
-            (unsigned long long)sd_v2_size(sd), sd_v2_nlink(sd),
-            sd_v2_rdev(sd), print_time(sd_v2_mtime(sd)));
-    }
+		printk("\t0%-6o | %6Lu | %2u | %d | %s\n", sd_v2_mode(sd),
+		       (unsigned long long)sd_v2_size(sd), sd_v2_nlink(sd),
+		       sd_v2_rdev(sd), print_time(sd_v2_mtime(sd)));
+	}
 }
 
-static void sd_check_item (struct item_head * ih, char * item)
+static void sd_check_item(struct item_head *ih, char *item)
 {
-    // FIXME: type something here!
+	// FIXME: type something here!
 }
 
-
-static int sd_create_vi (struct virtual_node * vn,
-			 struct virtual_item * vi, 
-			 int is_affected, 
-			 int insert_size)
+static int sd_create_vi(struct virtual_node *vn,
+			struct virtual_item *vi,
+			int is_affected, int insert_size)
 {
-    vi->vi_index = TYPE_STAT_DATA;
-    //vi->vi_type |= VI_TYPE_STAT_DATA;// not needed?
-    return 0;
+	vi->vi_index = TYPE_STAT_DATA;
+	//vi->vi_type |= VI_TYPE_STAT_DATA;// not needed?
+	return 0;
 }
 
-
-static int sd_check_left (struct virtual_item * vi, int free, 
-			  int start_skip, int end_skip)
+static int sd_check_left(struct virtual_item *vi, int free,
+			 int start_skip, int end_skip)
 {
-    if (start_skip || end_skip)
-	BUG ();
-    return -1;
+	if (start_skip || end_skip)
+		BUG();
+	return -1;
 }
 
-
-static int sd_check_right (struct virtual_item * vi, int free)
+static int sd_check_right(struct virtual_item *vi, int free)
 {
-    return -1;
+	return -1;
 }
 
-static int sd_part_size (struct virtual_item * vi, int first, int count)
+static int sd_part_size(struct virtual_item *vi, int first, int count)
 {
-    if (count)
-	BUG ();
-    return 0;
+	if (count)
+		BUG();
+	return 0;
 }
 
-static int sd_unit_num (struct virtual_item * vi)
+static int sd_unit_num(struct virtual_item *vi)
 {
-    return vi->vi_item_len - IH_SIZE;
+	return vi->vi_item_len - IH_SIZE;
 }
 
-
-static void sd_print_vi (struct virtual_item * vi)
+static void sd_print_vi(struct virtual_item *vi)
 {
-    reiserfs_warning (NULL, "STATDATA, index %d, type 0x%x, %h",
-		      vi->vi_index, vi->vi_type, vi->vi_ih);
+	reiserfs_warning(NULL, "STATDATA, index %d, type 0x%x, %h",
+			 vi->vi_index, vi->vi_type, vi->vi_ih);
 }
 
 static struct item_operations stat_data_ops = {
-	.bytes_number		= sd_bytes_number,
-	.decrement_key		= sd_decrement_key,
-	.is_left_mergeable	= sd_is_left_mergeable,
-	.print_item		= sd_print_item,
-	.check_item		= sd_check_item,
-
-	.create_vi		= sd_create_vi,
-	.check_left		= sd_check_left,
-	.check_right		= sd_check_right,
-	.part_size		= sd_part_size,
-	.unit_num		= sd_unit_num,
-	.print_vi		= sd_print_vi
+	.bytes_number = sd_bytes_number,
+	.decrement_key = sd_decrement_key,
+	.is_left_mergeable = sd_is_left_mergeable,
+	.print_item = sd_print_item,
+	.check_item = sd_check_item,
+
+	.create_vi = sd_create_vi,
+	.check_left = sd_check_left,
+	.check_right = sd_check_right,
+	.part_size = sd_part_size,
+	.unit_num = sd_unit_num,
+	.print_vi = sd_print_vi
 };
 
-
-
 //////////////////////////////////////////////////////////////////////////////
 // direct item functions
 //
-static int direct_bytes_number (struct item_head * ih, int block_size)
+static int direct_bytes_number(struct item_head *ih, int block_size)
 {
-  return ih_item_len(ih);
+	return ih_item_len(ih);
 }
 
-
 // FIXME: this should probably switch to indirect as well
-static void direct_decrement_key (struct cpu_key * key)
+static void direct_decrement_key(struct cpu_key *key)
 {
-    cpu_key_k_offset_dec (key);
-    if (cpu_key_k_offset (key) == 0)
-	set_cpu_key_k_type (key, TYPE_STAT_DATA);	
+	cpu_key_k_offset_dec(key);
+	if (cpu_key_k_offset(key) == 0)
+		set_cpu_key_k_type(key, TYPE_STAT_DATA);
 }
 
-
-static int direct_is_left_mergeable (struct reiserfs_key * key, unsigned long bsize)
+static int direct_is_left_mergeable(struct reiserfs_key *key,
+				    unsigned long bsize)
 {
-    int version = le_key_version (key);
-    return ((le_key_k_offset (version, key) & (bsize - 1)) != 1);
+	int version = le_key_version(key);
+	return ((le_key_k_offset(version, key) & (bsize - 1)) != 1);
 }
 
-
-static void direct_print_item (struct item_head * ih, char * item)
+static void direct_print_item(struct item_head *ih, char *item)
 {
-    int j = 0;
+	int j = 0;
 
 //    return;
-    printk ("\"");
-    while (j < ih_item_len(ih))
-	printk ("%c", item[j++]);
-    printk ("\"\n");
+	printk("\"");
+	while (j < ih_item_len(ih))
+		printk("%c", item[j++]);
+	printk("\"\n");
 }
 
-
-static void direct_check_item (struct item_head * ih, char * item)
+static void direct_check_item(struct item_head *ih, char *item)
 {
-    // FIXME: type something here!
+	// FIXME: type something here!
 }
 
-
-static int direct_create_vi (struct virtual_node * vn,
-			     struct virtual_item * vi, 
-			     int is_affected, 
-			     int insert_size)
+static int direct_create_vi(struct virtual_node *vn,
+			    struct virtual_item *vi,
+			    int is_affected, int insert_size)
 {
-    vi->vi_index = TYPE_DIRECT;
-    //vi->vi_type |= VI_TYPE_DIRECT;
-    return 0;
+	vi->vi_index = TYPE_DIRECT;
+	//vi->vi_type |= VI_TYPE_DIRECT;
+	return 0;
 }
 
-static int direct_check_left (struct virtual_item * vi, int free,
-			      int start_skip, int end_skip)
+static int direct_check_left(struct virtual_item *vi, int free,
+			     int start_skip, int end_skip)
 {
-    int bytes;
+	int bytes;
 
-    bytes = free - free % 8;
-    return bytes ?: -1;    
+	bytes = free - free % 8;
+	return bytes ? : -1;
 }
 
-
-static int direct_check_right (struct virtual_item * vi, int free)
+static int direct_check_right(struct virtual_item *vi, int free)
 {
-    return direct_check_left (vi, free, 0, 0);
+	return direct_check_left(vi, free, 0, 0);
 }
 
-static int direct_part_size (struct virtual_item * vi, int first, int count)
+static int direct_part_size(struct virtual_item *vi, int first, int count)
 {
-    return count;
+	return count;
 }
 
-
-static int direct_unit_num (struct virtual_item * vi)
+static int direct_unit_num(struct virtual_item *vi)
 {
-    return vi->vi_item_len - IH_SIZE;
+	return vi->vi_item_len - IH_SIZE;
 }
 
-
-static void direct_print_vi (struct virtual_item * vi)
+static void direct_print_vi(struct virtual_item *vi)
 {
-    reiserfs_warning (NULL, "DIRECT, index %d, type 0x%x, %h",
-		      vi->vi_index, vi->vi_type, vi->vi_ih);
+	reiserfs_warning(NULL, "DIRECT, index %d, type 0x%x, %h",
+			 vi->vi_index, vi->vi_type, vi->vi_ih);
 }
 
 static struct item_operations direct_ops = {
-	.bytes_number		= direct_bytes_number,
-	.decrement_key		= direct_decrement_key,
-	.is_left_mergeable	= direct_is_left_mergeable,
-	.print_item		= direct_print_item,
-	.check_item		= direct_check_item,
-
-	.create_vi		= direct_create_vi,
-	.check_left		= direct_check_left,
-	.check_right		= direct_check_right,
-	.part_size		= direct_part_size,
-	.unit_num		= direct_unit_num,
-	.print_vi		= direct_print_vi
+	.bytes_number = direct_bytes_number,
+	.decrement_key = direct_decrement_key,
+	.is_left_mergeable = direct_is_left_mergeable,
+	.print_item = direct_print_item,
+	.check_item = direct_check_item,
+
+	.create_vi = direct_create_vi,
+	.check_left = direct_check_left,
+	.check_right = direct_check_right,
+	.part_size = direct_part_size,
+	.unit_num = direct_unit_num,
+	.print_vi = direct_print_vi
 };
 
-
-
 //////////////////////////////////////////////////////////////////////////////
 // indirect item functions
 //
 
-static int indirect_bytes_number (struct item_head * ih, int block_size)
+static int indirect_bytes_number(struct item_head *ih, int block_size)
 {
-  return ih_item_len(ih) / UNFM_P_SIZE * block_size; //- get_ih_free_space (ih);
+	return ih_item_len(ih) / UNFM_P_SIZE * block_size;	//- get_ih_free_space (ih);
 }
 
-
 // decrease offset, if it becomes 0, change type to stat data
-static void indirect_decrement_key (struct cpu_key * key)
+static void indirect_decrement_key(struct cpu_key *key)
 {
-    cpu_key_k_offset_dec (key);
-    if (cpu_key_k_offset (key) == 0)
-	set_cpu_key_k_type (key, TYPE_STAT_DATA);
+	cpu_key_k_offset_dec(key);
+	if (cpu_key_k_offset(key) == 0)
+		set_cpu_key_k_type(key, TYPE_STAT_DATA);
 }
 
-
 // if it is not first item of the body, then it is mergeable
-static int indirect_is_left_mergeable (struct reiserfs_key * key, unsigned long bsize)
+static int indirect_is_left_mergeable(struct reiserfs_key *key,
+				      unsigned long bsize)
 {
-    int version = le_key_version (key);
-    return (le_key_k_offset (version, key) != 1);
+	int version = le_key_version(key);
+	return (le_key_k_offset(version, key) != 1);
 }
 
-
 // printing of indirect item
-static void start_new_sequence (__u32 * start, int * len, __u32 new)
+static void start_new_sequence(__u32 * start, int *len, __u32 new)
 {
-    *start = new;
-    *len = 1;
+	*start = new;
+	*len = 1;
 }
 
-
-static int sequence_finished (__u32 start, int * len, __u32 new)
+static int sequence_finished(__u32 start, int *len, __u32 new)
 {
-    if (start == INT_MAX)
-	return 1;
+	if (start == INT_MAX)
+		return 1;
 
-    if (start == 0 && new == 0) {
-	(*len) ++;
-	return 0;
-    }
-    if (start != 0 && (start + *len) == new) {
-	(*len) ++;
-	return 0;
-    }
-    return 1;
+	if (start == 0 && new == 0) {
+		(*len)++;
+		return 0;
+	}
+	if (start != 0 && (start + *len) == new) {
+		(*len)++;
+		return 0;
+	}
+	return 1;
 }
 
-static void print_sequence (__u32 start, int len)
+static void print_sequence(__u32 start, int len)
 {
-    if (start == INT_MAX)
-	return;
+	if (start == INT_MAX)
+		return;
 
-    if (len == 1)
-	printk (" %d", start);
-    else
-	printk (" %d(%d)", start, len);
+	if (len == 1)
+		printk(" %d", start);
+	else
+		printk(" %d(%d)", start, len);
 }
 
-
-static void indirect_print_item (struct item_head * ih, char * item)
+static void indirect_print_item(struct item_head *ih, char *item)
 {
-    int j;
-    __le32 * unp;
-    __u32 prev = INT_MAX;
-    int num;
+	int j;
+	__le32 *unp;
+	__u32 prev = INT_MAX;
+	int num;
 
-    unp = (__le32 *)item;
+	unp = (__le32 *) item;
 
-    if (ih_item_len(ih) % UNFM_P_SIZE)
-	reiserfs_warning (NULL, "indirect_print_item: invalid item len");
+	if (ih_item_len(ih) % UNFM_P_SIZE)
+		reiserfs_warning(NULL, "indirect_print_item: invalid item len");
 
-    printk ("%d pointers\n[ ", (int)I_UNFM_NUM (ih));
-    for (j = 0; j < I_UNFM_NUM (ih); j ++) {
-	if (sequence_finished (prev, &num, get_block_num(unp, j))) {
-	    print_sequence (prev, num);
-	    start_new_sequence (&prev, &num, get_block_num(unp, j));
+	printk("%d pointers\n[ ", (int)I_UNFM_NUM(ih));
+	for (j = 0; j < I_UNFM_NUM(ih); j++) {
+		if (sequence_finished(prev, &num, get_block_num(unp, j))) {
+			print_sequence(prev, num);
+			start_new_sequence(&prev, &num, get_block_num(unp, j));
+		}
 	}
-    }
-    print_sequence (prev, num);
-    printk ("]\n");
+	print_sequence(prev, num);
+	printk("]\n");
 }
 
-static void indirect_check_item (struct item_head * ih, char * item)
+static void indirect_check_item(struct item_head *ih, char *item)
 {
-    // FIXME: type something here!
+	// FIXME: type something here!
 }
 
-
-static int indirect_create_vi (struct virtual_node * vn,
-			       struct virtual_item * vi, 
-			       int is_affected, 
-			       int insert_size)
+static int indirect_create_vi(struct virtual_node *vn,
+			      struct virtual_item *vi,
+			      int is_affected, int insert_size)
 {
-    vi->vi_index = TYPE_INDIRECT;
-    //vi->vi_type |= VI_TYPE_INDIRECT;
-    return 0;
+	vi->vi_index = TYPE_INDIRECT;
+	//vi->vi_type |= VI_TYPE_INDIRECT;
+	return 0;
 }
 
-static int indirect_check_left (struct virtual_item * vi, int free,
-				int start_skip, int end_skip)
+static int indirect_check_left(struct virtual_item *vi, int free,
+			       int start_skip, int end_skip)
 {
-    int bytes;
+	int bytes;
 
-    bytes = free - free % UNFM_P_SIZE;
-    return bytes ?: -1;    
+	bytes = free - free % UNFM_P_SIZE;
+	return bytes ? : -1;
 }
 
-
-static int indirect_check_right (struct virtual_item * vi, int free)
+static int indirect_check_right(struct virtual_item *vi, int free)
 {
-    return indirect_check_left (vi, free, 0, 0);
+	return indirect_check_left(vi, free, 0, 0);
 }
 
-
-
 // return size in bytes of 'units' units. If first == 0 - calculate from the head (left), otherwise - from tail (right)
-static int indirect_part_size (struct virtual_item * vi, int first, int units)
+static int indirect_part_size(struct virtual_item *vi, int first, int units)
 {
-    // unit of indirect item is byte (yet)
-    return units;
+	// unit of indirect item is byte (yet)
+	return units;
 }
 
-static int indirect_unit_num (struct virtual_item * vi)
+static int indirect_unit_num(struct virtual_item *vi)
 {
-    // unit of indirect item is byte (yet)
-    return vi->vi_item_len - IH_SIZE;
+	// unit of indirect item is byte (yet)
+	return vi->vi_item_len - IH_SIZE;
 }
 
-static void indirect_print_vi (struct virtual_item * vi)
+static void indirect_print_vi(struct virtual_item *vi)
 {
-    reiserfs_warning (NULL, "INDIRECT, index %d, type 0x%x, %h",
-		      vi->vi_index, vi->vi_type, vi->vi_ih);
+	reiserfs_warning(NULL, "INDIRECT, index %d, type 0x%x, %h",
+			 vi->vi_index, vi->vi_type, vi->vi_ih);
 }
 
 static struct item_operations indirect_ops = {
-	.bytes_number		= indirect_bytes_number,
-	.decrement_key		= indirect_decrement_key,
-	.is_left_mergeable	= indirect_is_left_mergeable,
-	.print_item		= indirect_print_item,
-	.check_item		= indirect_check_item,
-
-	.create_vi		= indirect_create_vi,
-	.check_left		= indirect_check_left,
-	.check_right		= indirect_check_right,
-	.part_size		= indirect_part_size,
-	.unit_num		= indirect_unit_num,
-	.print_vi		= indirect_print_vi
+	.bytes_number = indirect_bytes_number,
+	.decrement_key = indirect_decrement_key,
+	.is_left_mergeable = indirect_is_left_mergeable,
+	.print_item = indirect_print_item,
+	.check_item = indirect_check_item,
+
+	.create_vi = indirect_create_vi,
+	.check_left = indirect_check_left,
+	.check_right = indirect_check_right,
+	.part_size = indirect_part_size,
+	.unit_num = indirect_unit_num,
+	.print_vi = indirect_print_vi
 };
 
-
 //////////////////////////////////////////////////////////////////////////////
 // direntry functions
 //
 
-
-static int direntry_bytes_number (struct item_head * ih, int block_size)
+static int direntry_bytes_number(struct item_head *ih, int block_size)
 {
-    reiserfs_warning (NULL, "vs-16090: direntry_bytes_number: "
-		      "bytes number is asked for direntry");
-    return 0;
+	reiserfs_warning(NULL, "vs-16090: direntry_bytes_number: "
+			 "bytes number is asked for direntry");
+	return 0;
 }
 
-static void direntry_decrement_key (struct cpu_key * key)
+static void direntry_decrement_key(struct cpu_key *key)
 {
-    cpu_key_k_offset_dec (key);
-    if (cpu_key_k_offset (key) == 0)
-	set_cpu_key_k_type (key, TYPE_STAT_DATA);	
+	cpu_key_k_offset_dec(key);
+	if (cpu_key_k_offset(key) == 0)
+		set_cpu_key_k_type(key, TYPE_STAT_DATA);
 }
 
-
-static int direntry_is_left_mergeable (struct reiserfs_key * key, unsigned long bsize)
+static int direntry_is_left_mergeable(struct reiserfs_key *key,
+				      unsigned long bsize)
 {
-    if (le32_to_cpu (key->u.k_offset_v1.k_offset) == DOT_OFFSET)
-	return 0;
-    return 1;
-	
-}
+	if (le32_to_cpu(key->u.k_offset_v1.k_offset) == DOT_OFFSET)
+		return 0;
+	return 1;
 
+}
 
-static void direntry_print_item (struct item_head * ih, char * item)
+static void direntry_print_item(struct item_head *ih, char *item)
 {
-    int i;
-    int namelen;
-    struct reiserfs_de_head * deh;
-    char * name;
-    static char namebuf [80];
-
-
-    printk ("\n # %-15s%-30s%-15s%-15s%-15s\n", "Name", "Key of pointed object", "Hash", "Gen number", "Status");
-
-    deh = (struct reiserfs_de_head *)item;
-
-    for (i = 0; i < I_ENTRY_COUNT (ih); i ++, deh ++) {
-	namelen = (i ? (deh_location(deh - 1)) : ih_item_len(ih)) - deh_location(deh);
-	name = item + deh_location(deh);
-	if (name[namelen-1] == 0)
-	  namelen = strlen (name);
-	namebuf[0] = '"';
-	if (namelen > sizeof (namebuf) - 3) {
-	    strncpy (namebuf + 1, name, sizeof (namebuf) - 3);
-	    namebuf[sizeof (namebuf) - 2] = '"';
-	    namebuf[sizeof (namebuf) - 1] = 0;
-	} else {
-	    memcpy (namebuf + 1, name, namelen);
-	    namebuf[namelen + 1] = '"';
-	    namebuf[namelen + 2] = 0;
+	int i;
+	int namelen;
+	struct reiserfs_de_head *deh;
+	char *name;
+	static char namebuf[80];
+
+	printk("\n # %-15s%-30s%-15s%-15s%-15s\n", "Name",
+	       "Key of pointed object", "Hash", "Gen number", "Status");
+
+	deh = (struct reiserfs_de_head *)item;
+
+	for (i = 0; i < I_ENTRY_COUNT(ih); i++, deh++) {
+		namelen =
+		    (i ? (deh_location(deh - 1)) : ih_item_len(ih)) -
+		    deh_location(deh);
+		name = item + deh_location(deh);
+		if (name[namelen - 1] == 0)
+			namelen = strlen(name);
+		namebuf[0] = '"';
+		if (namelen > sizeof(namebuf) - 3) {
+			strncpy(namebuf + 1, name, sizeof(namebuf) - 3);
+			namebuf[sizeof(namebuf) - 2] = '"';
+			namebuf[sizeof(namebuf) - 1] = 0;
+		} else {
+			memcpy(namebuf + 1, name, namelen);
+			namebuf[namelen + 1] = '"';
+			namebuf[namelen + 2] = 0;
+		}
+
+		printk("%d:  %-15s%-15d%-15d%-15Ld%-15Ld(%s)\n",
+		       i, namebuf,
+		       deh_dir_id(deh), deh_objectid(deh),
+		       GET_HASH_VALUE(deh_offset(deh)),
+		       GET_GENERATION_NUMBER((deh_offset(deh))),
+		       (de_hidden(deh)) ? "HIDDEN" : "VISIBLE");
 	}
-
-	printk ("%d:  %-15s%-15d%-15d%-15Ld%-15Ld(%s)\n", 
-		i, namebuf,
-		deh_dir_id(deh), deh_objectid(deh),
-		GET_HASH_VALUE (deh_offset (deh)), GET_GENERATION_NUMBER ((deh_offset (deh))),
-		(de_hidden (deh)) ? "HIDDEN" : "VISIBLE");
-    }
 }
 
-
-static void direntry_check_item (struct item_head * ih, char * item)
+static void direntry_check_item(struct item_head *ih, char *item)
 {
-    int i;
-    struct reiserfs_de_head * deh;
+	int i;
+	struct reiserfs_de_head *deh;
 
-    // FIXME: type something here!
-    deh = (struct reiserfs_de_head *)item;
-    for (i = 0; i < I_ENTRY_COUNT (ih); i ++, deh ++) {
-	;
-    }
+	// FIXME: type something here!
+	deh = (struct reiserfs_de_head *)item;
+	for (i = 0; i < I_ENTRY_COUNT(ih); i++, deh++) {
+		;
+	}
 }
 
-
-
 #define DIRENTRY_VI_FIRST_DIRENTRY_ITEM 1
 
 /*
  * function returns old entry number in directory item in real node
  * using new entry number in virtual item in virtual node */
-static inline int old_entry_num (int is_affected, int virtual_entry_num, int pos_in_item, int mode)
+static inline int old_entry_num(int is_affected, int virtual_entry_num,
+				int pos_in_item, int mode)
 {
-    if ( mode == M_INSERT || mode == M_DELETE)
-	return virtual_entry_num;
-    
-    if (!is_affected)
-	/* cut or paste is applied to another item */
-	return virtual_entry_num;
-
-    if (virtual_entry_num < pos_in_item)
-	return virtual_entry_num;
-
-    if (mode == M_CUT)
-	return virtual_entry_num + 1;
-
-    RFALSE( mode != M_PASTE || virtual_entry_num == 0,
-	    "vs-8015: old_entry_num: mode must be M_PASTE (mode = \'%c\'", mode);
-    
-    return virtual_entry_num - 1;
-}
+	if (mode == M_INSERT || mode == M_DELETE)
+		return virtual_entry_num;
+
+	if (!is_affected)
+		/* cut or paste is applied to another item */
+		return virtual_entry_num;
 
+	if (virtual_entry_num < pos_in_item)
+		return virtual_entry_num;
 
+	if (mode == M_CUT)
+		return virtual_entry_num + 1;
 
+	RFALSE(mode != M_PASTE || virtual_entry_num == 0,
+	       "vs-8015: old_entry_num: mode must be M_PASTE (mode = \'%c\'",
+	       mode);
+
+	return virtual_entry_num - 1;
+}
 
 /* Create an array of sizes of directory entries for virtual
    item. Return space used by an item. FIXME: no control over
    consuming of space used by this item handler */
-static int direntry_create_vi (struct virtual_node * vn,
-			       struct virtual_item * vi, 
-			       int is_affected, 
-			       int insert_size)
-{
-    struct direntry_uarea * dir_u = vi->vi_uarea;
-    int i, j;
-    int size = sizeof (struct direntry_uarea);
-    struct reiserfs_de_head * deh;
-  
-    vi->vi_index = TYPE_DIRENTRY;
-
-    if (!(vi->vi_ih) || !vi->vi_item)
-	BUG ();
-
-
-    dir_u->flags = 0;
-    if (le_ih_k_offset (vi->vi_ih) == DOT_OFFSET)
-	dir_u->flags |= DIRENTRY_VI_FIRST_DIRENTRY_ITEM;
-
-    deh = (struct reiserfs_de_head *)(vi->vi_item);
-    
-    
-    /* virtual directory item have this amount of entry after */
-    dir_u->entry_count = ih_entry_count (vi->vi_ih) + 
-	((is_affected) ? ((vn->vn_mode == M_CUT) ? -1 :
-			  (vn->vn_mode == M_PASTE ? 1 : 0)) : 0);
-    
-    for (i = 0; i < dir_u->entry_count; i ++) {
-	j = old_entry_num (is_affected, i, vn->vn_pos_in_item, vn->vn_mode);
-        dir_u->entry_sizes[i] = (j ? deh_location( &(deh[j - 1]) ) :
-                                ih_item_len (vi->vi_ih)) -
-                                deh_location( &(deh[j])) + DEH_SIZE;
-    }
-
-    size += (dir_u->entry_count * sizeof (short));
-    
-    /* set size of pasted entry */
-    if (is_affected && vn->vn_mode == M_PASTE)
-	dir_u->entry_sizes[vn->vn_pos_in_item] = insert_size;
+static int direntry_create_vi(struct virtual_node *vn,
+			      struct virtual_item *vi,
+			      int is_affected, int insert_size)
+{
+	struct direntry_uarea *dir_u = vi->vi_uarea;
+	int i, j;
+	int size = sizeof(struct direntry_uarea);
+	struct reiserfs_de_head *deh;
+
+	vi->vi_index = TYPE_DIRENTRY;
+
+	if (!(vi->vi_ih) || !vi->vi_item)
+		BUG();
+
+	dir_u->flags = 0;
+	if (le_ih_k_offset(vi->vi_ih) == DOT_OFFSET)
+		dir_u->flags |= DIRENTRY_VI_FIRST_DIRENTRY_ITEM;
+
+	deh = (struct reiserfs_de_head *)(vi->vi_item);
+
+	/* virtual directory item have this amount of entry after */
+	dir_u->entry_count = ih_entry_count(vi->vi_ih) +
+	    ((is_affected) ? ((vn->vn_mode == M_CUT) ? -1 :
+			      (vn->vn_mode == M_PASTE ? 1 : 0)) : 0);
+
+	for (i = 0; i < dir_u->entry_count; i++) {
+		j = old_entry_num(is_affected, i, vn->vn_pos_in_item,
+				  vn->vn_mode);
+		dir_u->entry_sizes[i] =
+		    (j ? deh_location(&(deh[j - 1])) : ih_item_len(vi->vi_ih)) -
+		    deh_location(&(deh[j])) + DEH_SIZE;
+	}
 
+	size += (dir_u->entry_count * sizeof(short));
+
+	/* set size of pasted entry */
+	if (is_affected && vn->vn_mode == M_PASTE)
+		dir_u->entry_sizes[vn->vn_pos_in_item] = insert_size;
 
 #ifdef CONFIG_REISERFS_CHECK
-    /* compare total size of entries with item length */
-    {
-	int k, l;
-    
-	l = 0;
-	for (k = 0; k < dir_u->entry_count; k ++)
-	    l += dir_u->entry_sizes[k];
-    
-	if (l + IH_SIZE != vi->vi_item_len + 
-	    ((is_affected && (vn->vn_mode == M_PASTE || vn->vn_mode == M_CUT)) ? insert_size : 0) ) {
-	    reiserfs_panic (NULL, "vs-8025: set_entry_sizes: (mode==%c, insert_size==%d), invalid length of directory item",
-			    vn->vn_mode, insert_size);
+	/* compare total size of entries with item length */
+	{
+		int k, l;
+
+		l = 0;
+		for (k = 0; k < dir_u->entry_count; k++)
+			l += dir_u->entry_sizes[k];
+
+		if (l + IH_SIZE != vi->vi_item_len +
+		    ((is_affected
+		      && (vn->vn_mode == M_PASTE
+			  || vn->vn_mode == M_CUT)) ? insert_size : 0)) {
+			reiserfs_panic(NULL,
+				       "vs-8025: set_entry_sizes: (mode==%c, insert_size==%d), invalid length of directory item",
+				       vn->vn_mode, insert_size);
+		}
 	}
-    }
 #endif
 
-    return size;
-
+	return size;
 
 }
 
-
 //
 // return number of entries which may fit into specified amount of
 // free space, or -1 if free space is not enough even for 1 entry
 //
-static int direntry_check_left (struct virtual_item * vi, int free,
-				int start_skip, int end_skip)
+static int direntry_check_left(struct virtual_item *vi, int free,
+			       int start_skip, int end_skip)
 {
-    int i;
-    int entries = 0;
-    struct direntry_uarea * dir_u = vi->vi_uarea;
-
-    for (i = start_skip; i < dir_u->entry_count - end_skip; i ++) {
-	if (dir_u->entry_sizes[i] > free)
-	    /* i-th entry doesn't fit into the remaining free space */
-	    break;
-		  
-	free -= dir_u->entry_sizes[i];
-	entries ++;
-    }
-
-    if (entries == dir_u->entry_count) {
-	reiserfs_panic (NULL, "free space %d, entry_count %d\n", free, dir_u->entry_count);
-    }
-
-    /* "." and ".." can not be separated from each other */
-    if (start_skip == 0 && (dir_u->flags & DIRENTRY_VI_FIRST_DIRENTRY_ITEM) && entries < 2)
-	entries = 0;
-    
-    return entries ?: -1;
-}
+	int i;
+	int entries = 0;
+	struct direntry_uarea *dir_u = vi->vi_uarea;
+
+	for (i = start_skip; i < dir_u->entry_count - end_skip; i++) {
+		if (dir_u->entry_sizes[i] > free)
+			/* i-th entry doesn't fit into the remaining free space */
+			break;
+
+		free -= dir_u->entry_sizes[i];
+		entries++;
+	}
 
+	if (entries == dir_u->entry_count) {
+		reiserfs_panic(NULL, "free space %d, entry_count %d\n", free,
+			       dir_u->entry_count);
+	}
 
-static int direntry_check_right (struct virtual_item * vi, int free)
-{
-    int i;
-    int entries = 0;
-    struct direntry_uarea * dir_u = vi->vi_uarea;
-    
-    for (i = dir_u->entry_count - 1; i >= 0; i --) {
-	if (dir_u->entry_sizes[i] > free)
-	    /* i-th entry doesn't fit into the remaining free space */
-	    break;
-	
-	free -= dir_u->entry_sizes[i];
-	entries ++;
-    }
-    if (entries == dir_u->entry_count)
-	BUG ();
-
-    /* "." and ".." can not be separated from each other */
-    if ((dir_u->flags & DIRENTRY_VI_FIRST_DIRENTRY_ITEM) && entries > dir_u->entry_count - 2)
-	entries = dir_u->entry_count - 2;
+	/* "." and ".." can not be separated from each other */
+	if (start_skip == 0 && (dir_u->flags & DIRENTRY_VI_FIRST_DIRENTRY_ITEM)
+	    && entries < 2)
+		entries = 0;
 
-    return entries ?: -1;
+	return entries ? : -1;
 }
 
-
-/* sum of entry sizes between from-th and to-th entries including both edges */
-static int direntry_part_size (struct virtual_item * vi, int first, int count)
+static int direntry_check_right(struct virtual_item *vi, int free)
 {
-    int i, retval;
-    int from, to;
-    struct direntry_uarea * dir_u = vi->vi_uarea;
-    
-    retval = 0;
-    if (first == 0)
-	from = 0;
-    else
-	from = dir_u->entry_count - count;
-    to = from + count - 1;
+	int i;
+	int entries = 0;
+	struct direntry_uarea *dir_u = vi->vi_uarea;
 
-    for (i = from; i <= to; i ++)
-	retval += dir_u->entry_sizes[i];
+	for (i = dir_u->entry_count - 1; i >= 0; i--) {
+		if (dir_u->entry_sizes[i] > free)
+			/* i-th entry doesn't fit into the remaining free space */
+			break;
 
-    return retval;
+		free -= dir_u->entry_sizes[i];
+		entries++;
+	}
+	if (entries == dir_u->entry_count)
+		BUG();
+
+	/* "." and ".." can not be separated from each other */
+	if ((dir_u->flags & DIRENTRY_VI_FIRST_DIRENTRY_ITEM)
+	    && entries > dir_u->entry_count - 2)
+		entries = dir_u->entry_count - 2;
+
+	return entries ? : -1;
 }
 
-static int direntry_unit_num (struct virtual_item * vi)
+/* sum of entry sizes between from-th and to-th entries including both edges */
+static int direntry_part_size(struct virtual_item *vi, int first, int count)
 {
-    struct direntry_uarea * dir_u = vi->vi_uarea;
-    
-    return dir_u->entry_count;
+	int i, retval;
+	int from, to;
+	struct direntry_uarea *dir_u = vi->vi_uarea;
+
+	retval = 0;
+	if (first == 0)
+		from = 0;
+	else
+		from = dir_u->entry_count - count;
+	to = from + count - 1;
+
+	for (i = from; i <= to; i++)
+		retval += dir_u->entry_sizes[i];
+
+	return retval;
 }
 
+static int direntry_unit_num(struct virtual_item *vi)
+{
+	struct direntry_uarea *dir_u = vi->vi_uarea;
 
+	return dir_u->entry_count;
+}
 
-static void direntry_print_vi (struct virtual_item * vi)
+static void direntry_print_vi(struct virtual_item *vi)
 {
-    int i;
-    struct direntry_uarea * dir_u = vi->vi_uarea;
+	int i;
+	struct direntry_uarea *dir_u = vi->vi_uarea;
 
-    reiserfs_warning (NULL, "DIRENTRY, index %d, type 0x%x, %h, flags 0x%x",
-		      vi->vi_index, vi->vi_type, vi->vi_ih, dir_u->flags);
-    printk ("%d entries: ", dir_u->entry_count);
-    for (i = 0; i < dir_u->entry_count; i ++)
-	printk ("%d ", dir_u->entry_sizes[i]);
-    printk ("\n");
+	reiserfs_warning(NULL, "DIRENTRY, index %d, type 0x%x, %h, flags 0x%x",
+			 vi->vi_index, vi->vi_type, vi->vi_ih, dir_u->flags);
+	printk("%d entries: ", dir_u->entry_count);
+	for (i = 0; i < dir_u->entry_count; i++)
+		printk("%d ", dir_u->entry_sizes[i]);
+	printk("\n");
 }
 
 static struct item_operations direntry_ops = {
-	.bytes_number		= direntry_bytes_number,
-	.decrement_key		= direntry_decrement_key,
-	.is_left_mergeable	= direntry_is_left_mergeable,
-	.print_item		= direntry_print_item,
-	.check_item		= direntry_check_item,
-
-	.create_vi		= direntry_create_vi,
-	.check_left		= direntry_check_left,
-	.check_right		= direntry_check_right,
-	.part_size		= direntry_part_size,
-	.unit_num		= direntry_unit_num,
-	.print_vi		= direntry_print_vi
+	.bytes_number = direntry_bytes_number,
+	.decrement_key = direntry_decrement_key,
+	.is_left_mergeable = direntry_is_left_mergeable,
+	.print_item = direntry_print_item,
+	.check_item = direntry_check_item,
+
+	.create_vi = direntry_create_vi,
+	.check_left = direntry_check_left,
+	.check_right = direntry_check_right,
+	.part_size = direntry_part_size,
+	.unit_num = direntry_unit_num,
+	.print_vi = direntry_print_vi
 };
 
-
 //////////////////////////////////////////////////////////////////////////////
 // Error catching functions to catch errors caused by incorrect item types.
 //
-static int errcatch_bytes_number (struct item_head * ih, int block_size)
+static int errcatch_bytes_number(struct item_head *ih, int block_size)
 {
-    reiserfs_warning (NULL, "green-16001: Invalid item type observed, run fsck ASAP");
-    return 0;
+	reiserfs_warning(NULL,
+			 "green-16001: Invalid item type observed, run fsck ASAP");
+	return 0;
 }
 
-static void errcatch_decrement_key (struct cpu_key * key)
+static void errcatch_decrement_key(struct cpu_key *key)
 {
-    reiserfs_warning (NULL, "green-16002: Invalid item type observed, run fsck ASAP");
+	reiserfs_warning(NULL,
+			 "green-16002: Invalid item type observed, run fsck ASAP");
 }
 
-
-static int errcatch_is_left_mergeable (struct reiserfs_key * key, unsigned long bsize)
+static int errcatch_is_left_mergeable(struct reiserfs_key *key,
+				      unsigned long bsize)
 {
-    reiserfs_warning (NULL, "green-16003: Invalid item type observed, run fsck ASAP");
-    return 0;
+	reiserfs_warning(NULL,
+			 "green-16003: Invalid item type observed, run fsck ASAP");
+	return 0;
 }
 
-
-static void errcatch_print_item (struct item_head * ih, char * item)
+static void errcatch_print_item(struct item_head *ih, char *item)
 {
-    reiserfs_warning (NULL, "green-16004: Invalid item type observed, run fsck ASAP");
+	reiserfs_warning(NULL,
+			 "green-16004: Invalid item type observed, run fsck ASAP");
 }
 
-
-static void errcatch_check_item (struct item_head * ih, char * item)
+static void errcatch_check_item(struct item_head *ih, char *item)
 {
-    reiserfs_warning (NULL, "green-16005: Invalid item type observed, run fsck ASAP");
+	reiserfs_warning(NULL,
+			 "green-16005: Invalid item type observed, run fsck ASAP");
 }
 
-static int errcatch_create_vi (struct virtual_node * vn,
-			       struct virtual_item * vi, 
-			       int is_affected, 
-			       int insert_size)
+static int errcatch_create_vi(struct virtual_node *vn,
+			      struct virtual_item *vi,
+			      int is_affected, int insert_size)
 {
-    reiserfs_warning (NULL, "green-16006: Invalid item type observed, run fsck ASAP");
-    return 0;	// We might return -1 here as well, but it won't help as create_virtual_node() from where
-		// this operation is called from is of return type void.
+	reiserfs_warning(NULL,
+			 "green-16006: Invalid item type observed, run fsck ASAP");
+	return 0;		// We might return -1 here as well, but it won't help as create_virtual_node() from where
+	// this operation is called from is of return type void.
 }
 
-static int errcatch_check_left (struct virtual_item * vi, int free,
-				int start_skip, int end_skip)
+static int errcatch_check_left(struct virtual_item *vi, int free,
+			       int start_skip, int end_skip)
 {
-    reiserfs_warning (NULL, "green-16007: Invalid item type observed, run fsck ASAP");
-    return -1;
+	reiserfs_warning(NULL,
+			 "green-16007: Invalid item type observed, run fsck ASAP");
+	return -1;
 }
 
-
-static int errcatch_check_right (struct virtual_item * vi, int free)
+static int errcatch_check_right(struct virtual_item *vi, int free)
 {
-    reiserfs_warning (NULL, "green-16008: Invalid item type observed, run fsck ASAP");
-    return -1;
+	reiserfs_warning(NULL,
+			 "green-16008: Invalid item type observed, run fsck ASAP");
+	return -1;
 }
 
-static int errcatch_part_size (struct virtual_item * vi, int first, int count)
+static int errcatch_part_size(struct virtual_item *vi, int first, int count)
 {
-    reiserfs_warning (NULL, "green-16009: Invalid item type observed, run fsck ASAP");
-    return 0;
+	reiserfs_warning(NULL,
+			 "green-16009: Invalid item type observed, run fsck ASAP");
+	return 0;
 }
 
-static int errcatch_unit_num (struct virtual_item * vi)
+static int errcatch_unit_num(struct virtual_item *vi)
 {
-    reiserfs_warning (NULL, "green-16010: Invalid item type observed, run fsck ASAP");
-    return 0;
+	reiserfs_warning(NULL,
+			 "green-16010: Invalid item type observed, run fsck ASAP");
+	return 0;
 }
 
-static void errcatch_print_vi (struct virtual_item * vi)
+static void errcatch_print_vi(struct virtual_item *vi)
 {
-    reiserfs_warning (NULL, "green-16011: Invalid item type observed, run fsck ASAP");
+	reiserfs_warning(NULL,
+			 "green-16011: Invalid item type observed, run fsck ASAP");
 }
 
 static struct item_operations errcatch_ops = {
-    errcatch_bytes_number,
-    errcatch_decrement_key,
-    errcatch_is_left_mergeable,
-    errcatch_print_item,
-    errcatch_check_item,
-
-    errcatch_create_vi,
-    errcatch_check_left,
-    errcatch_check_right,
-    errcatch_part_size,
-    errcatch_unit_num,
-    errcatch_print_vi
+	errcatch_bytes_number,
+	errcatch_decrement_key,
+	errcatch_is_left_mergeable,
+	errcatch_print_item,
+	errcatch_check_item,
+
+	errcatch_create_vi,
+	errcatch_check_left,
+	errcatch_check_right,
+	errcatch_part_size,
+	errcatch_unit_num,
+	errcatch_print_vi
 };
 
-
-
 //////////////////////////////////////////////////////////////////////////////
 //
 //
 #if ! (TYPE_STAT_DATA == 0 && TYPE_INDIRECT == 1 && TYPE_DIRECT == 2 && TYPE_DIRENTRY == 3)
-  do not compile
+#error Item types must use disk-format assigned values.
 #endif
 
-struct item_operations * item_ops [TYPE_ANY + 1] = {
-  &stat_data_ops,
-  &indirect_ops,
-  &direct_ops,
-  &direntry_ops,
-  NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-  &errcatch_ops		/* This is to catch errors with invalid type (15th entry for TYPE_ANY) */
+struct item_operations *item_ops[TYPE_ANY + 1] = {
+	&stat_data_ops,
+	&indirect_ops,
+	&direct_ops,
+	&direntry_ops,
+	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+	&errcatch_ops		/* This is to catch errors with invalid type (15th entry for TYPE_ANY) */
 };
-
-
-
-
diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c
--- a/fs/reiserfs/journal.c
+++ b/fs/reiserfs/journal.c
@@ -55,7 +55,6 @@
 #include <linux/writeback.h>
 #include <linux/blkdev.h>
 
-
 /* gets a struct reiserfs_journal_list * from a list head */
 #define JOURNAL_LIST_ENTRY(h) (list_entry((h), struct reiserfs_journal_list, \
                                j_list))
@@ -69,55 +68,61 @@ static int reiserfs_mounted_fs_count;
 
 static struct workqueue_struct *commit_wq;
 
-#define JOURNAL_TRANS_HALF 1018   /* must be correct to keep the desc and commit
-				     structs at 4k */
-#define BUFNR 64 /*read ahead */
+#define JOURNAL_TRANS_HALF 1018	/* must be correct to keep the desc and commit
+				   structs at 4k */
+#define BUFNR 64		/*read ahead */
 
 /* cnode stat bits.  Move these into reiserfs_fs.h */
 
 #define BLOCK_FREED 2		/* this block was freed, and can't be written.  */
-#define BLOCK_FREED_HOLDER 3    /* this block was freed during this transaction, and can't be written */
+#define BLOCK_FREED_HOLDER 3	/* this block was freed during this transaction, and can't be written */
 
 #define BLOCK_NEEDS_FLUSH 4	/* used in flush_journal_list */
 #define BLOCK_DIRTIED 5
 
-
 /* journal list state bits */
 #define LIST_TOUCHED 1
 #define LIST_DIRTY   2
-#define LIST_COMMIT_PENDING  4		/* someone will commit this list */
+#define LIST_COMMIT_PENDING  4	/* someone will commit this list */
 
 /* flags for do_journal_end */
 #define FLUSH_ALL   1		/* flush commit and real blocks */
 #define COMMIT_NOW  2		/* end and commit this transaction */
-#define WAIT        4		/* wait for the log blocks to hit the disk*/
+#define WAIT        4		/* wait for the log blocks to hit the disk */
 
-static int do_journal_end(struct reiserfs_transaction_handle *,struct super_block *,unsigned long nblocks,int flags) ;
-static int flush_journal_list(struct super_block *s, struct reiserfs_journal_list *jl, int flushall) ;
-static int flush_commit_list(struct super_block *s, struct reiserfs_journal_list *jl, int flushall)  ;
-static int can_dirty(struct reiserfs_journal_cnode *cn) ;
-static int journal_join(struct reiserfs_transaction_handle *th, struct super_block *p_s_sb, unsigned long nblocks);
-static int release_journal_dev( struct super_block *super,
-				struct reiserfs_journal *journal );
+static int do_journal_end(struct reiserfs_transaction_handle *,
+			  struct super_block *, unsigned long nblocks,
+			  int flags);
+static int flush_journal_list(struct super_block *s,
+			      struct reiserfs_journal_list *jl, int flushall);
+static int flush_commit_list(struct super_block *s,
+			     struct reiserfs_journal_list *jl, int flushall);
+static int can_dirty(struct reiserfs_journal_cnode *cn);
+static int journal_join(struct reiserfs_transaction_handle *th,
+			struct super_block *p_s_sb, unsigned long nblocks);
+static int release_journal_dev(struct super_block *super,
+			       struct reiserfs_journal *journal);
 static int dirty_one_transaction(struct super_block *s,
-                                 struct reiserfs_journal_list *jl);
+				 struct reiserfs_journal_list *jl);
 static void flush_async_commits(void *p);
 static void queue_log_writer(struct super_block *s);
 
 /* values for join in do_journal_begin_r */
 enum {
-    JBEGIN_REG = 0, /* regular journal begin */
-    JBEGIN_JOIN = 1, /* join the running transaction if at all possible */
-    JBEGIN_ABORT = 2, /* called from cleanup code, ignores aborted flag */
+	JBEGIN_REG = 0,		/* regular journal begin */
+	JBEGIN_JOIN = 1,	/* join the running transaction if at all possible */
+	JBEGIN_ABORT = 2,	/* called from cleanup code, ignores aborted flag */
 };
 
 static int do_journal_begin_r(struct reiserfs_transaction_handle *th,
-                             struct super_block * p_s_sb,
-			     unsigned long nblocks,int join);
+			      struct super_block *p_s_sb,
+			      unsigned long nblocks, int join);
 
-static void init_journal_hash(struct super_block *p_s_sb) {
-  struct reiserfs_journal *journal = SB_JOURNAL (p_s_sb);
-  memset(journal->j_hash_table, 0, JOURNAL_HASH_SIZE * sizeof(struct reiserfs_journal_cnode *)) ;
+static void init_journal_hash(struct super_block *p_s_sb)
+{
+	struct reiserfs_journal *journal = SB_JOURNAL(p_s_sb);
+	memset(journal->j_hash_table, 0,
+	       JOURNAL_HASH_SIZE * sizeof(struct reiserfs_journal_cnode *));
 }
 
 /*
@@ -125,149 +130,159 @@ static void init_journal_hash(struct sup
 ** make schedule happen after I've freed a block.  Look at remove_from_transaction and journal_mark_freed for
 ** more details.
 */
-static int reiserfs_clean_and_file_buffer(struct buffer_head *bh) {
-  if (bh) {
-    clear_buffer_dirty(bh);
-    clear_buffer_journal_test(bh);
-  }
-  return 0 ;
+static int reiserfs_clean_and_file_buffer(struct buffer_head *bh)
+{
+	if (bh) {
+		clear_buffer_dirty(bh);
+		clear_buffer_journal_test(bh);
+	}
+	return 0;
 }
 
 static void disable_barrier(struct super_block *s)
 {
-    REISERFS_SB(s)->s_mount_opt &= ~(1 << REISERFS_BARRIER_FLUSH);
-    printk("reiserfs: disabling flush barriers on %s\n", reiserfs_bdevname(s));
+	REISERFS_SB(s)->s_mount_opt &= ~(1 << REISERFS_BARRIER_FLUSH);
+	printk("reiserfs: disabling flush barriers on %s\n",
+	       reiserfs_bdevname(s));
+}
+
+static struct reiserfs_bitmap_node *allocate_bitmap_node(struct super_block
+							 *p_s_sb)
+{
+	struct reiserfs_bitmap_node *bn;
+	static int id;
+
+	bn = reiserfs_kmalloc(sizeof(struct reiserfs_bitmap_node), GFP_NOFS,
+			      p_s_sb);
+	if (!bn) {
+		return NULL;
+	}
+	bn->data = reiserfs_kmalloc(p_s_sb->s_blocksize, GFP_NOFS, p_s_sb);
+	if (!bn->data) {
+		reiserfs_kfree(bn, sizeof(struct reiserfs_bitmap_node), p_s_sb);
+		return NULL;
+	}
+	bn->id = id++;
+	memset(bn->data, 0, p_s_sb->s_blocksize);
+	INIT_LIST_HEAD(&bn->list);
+	return bn;
 }
 
-static struct reiserfs_bitmap_node *
-allocate_bitmap_node(struct super_block *p_s_sb) {
-  struct reiserfs_bitmap_node *bn ;
-  static int id;
-
-  bn = reiserfs_kmalloc(sizeof(struct reiserfs_bitmap_node), GFP_NOFS, p_s_sb) ;
-  if (!bn) {
-    return NULL ;
-  }
-  bn->data = reiserfs_kmalloc(p_s_sb->s_blocksize, GFP_NOFS, p_s_sb) ;
-  if (!bn->data) {
-    reiserfs_kfree(bn, sizeof(struct reiserfs_bitmap_node), p_s_sb) ;
-    return NULL ;
-  }
-  bn->id = id++ ;
-  memset(bn->data, 0, p_s_sb->s_blocksize) ;
-  INIT_LIST_HEAD(&bn->list) ;
-  return bn ;
-}
-
-static struct reiserfs_bitmap_node *
-get_bitmap_node(struct super_block *p_s_sb) {
-  struct reiserfs_journal *journal = SB_JOURNAL (p_s_sb);
-  struct reiserfs_bitmap_node *bn = NULL;
-  struct list_head *entry = journal->j_bitmap_nodes.next ;
-
-  journal->j_used_bitmap_nodes++ ;
-repeat:
-
-  if(entry != &journal->j_bitmap_nodes) {
-    bn = list_entry(entry, struct reiserfs_bitmap_node, list) ;
-    list_del(entry) ;
-    memset(bn->data, 0, p_s_sb->s_blocksize) ;
-    journal->j_free_bitmap_nodes-- ;
-    return bn ;
-  }
-  bn = allocate_bitmap_node(p_s_sb) ;
-  if (!bn) {
-    yield();
-    goto repeat ;
-  }
-  return bn ;
+static struct reiserfs_bitmap_node *get_bitmap_node(struct super_block *p_s_sb)
+{
+	struct reiserfs_journal *journal = SB_JOURNAL(p_s_sb);
+	struct reiserfs_bitmap_node *bn = NULL;
+	struct list_head *entry = journal->j_bitmap_nodes.next;
+
+	journal->j_used_bitmap_nodes++;
+      repeat:
+
+	if (entry != &journal->j_bitmap_nodes) {
+		bn = list_entry(entry, struct reiserfs_bitmap_node, list);
+		list_del(entry);
+		memset(bn->data, 0, p_s_sb->s_blocksize);
+		journal->j_free_bitmap_nodes--;
+		return bn;
+	}
+	bn = allocate_bitmap_node(p_s_sb);
+	if (!bn) {
+		yield();
+		goto repeat;
+	}
+	return bn;
 }
 static inline void free_bitmap_node(struct super_block *p_s_sb,
-                                    struct reiserfs_bitmap_node *bn) {
-  struct reiserfs_journal *journal = SB_JOURNAL (p_s_sb);
-  journal->j_used_bitmap_nodes-- ;
-  if (journal->j_free_bitmap_nodes > REISERFS_MAX_BITMAP_NODES) {
-    reiserfs_kfree(bn->data, p_s_sb->s_blocksize, p_s_sb) ;
-    reiserfs_kfree(bn, sizeof(struct reiserfs_bitmap_node), p_s_sb) ;
-  } else {
-    list_add(&bn->list, &journal->j_bitmap_nodes) ;
-    journal->j_free_bitmap_nodes++ ;
-  }
-}
-
-static void allocate_bitmap_nodes(struct super_block *p_s_sb) {
-  int i ;
-  struct reiserfs_journal *journal = SB_JOURNAL (p_s_sb);
-  struct reiserfs_bitmap_node *bn = NULL ;
-  for (i = 0 ; i < REISERFS_MIN_BITMAP_NODES ; i++) {
-    bn = allocate_bitmap_node(p_s_sb) ;
-    if (bn) {
-      list_add(&bn->list, &journal->j_bitmap_nodes) ;
-      journal->j_free_bitmap_nodes++ ;
-    } else {
-      break ; // this is ok, we'll try again when more are needed 
-    }
-  }
+				    struct reiserfs_bitmap_node *bn)
+{
+	struct reiserfs_journal *journal = SB_JOURNAL(p_s_sb);
+	journal->j_used_bitmap_nodes--;
+	if (journal->j_free_bitmap_nodes > REISERFS_MAX_BITMAP_NODES) {
+		reiserfs_kfree(bn->data, p_s_sb->s_blocksize, p_s_sb);
+		reiserfs_kfree(bn, sizeof(struct reiserfs_bitmap_node), p_s_sb);
+	} else {
+		list_add(&bn->list, &journal->j_bitmap_nodes);
+		journal->j_free_bitmap_nodes++;
+	}
+}
+
+static void allocate_bitmap_nodes(struct super_block *p_s_sb)
+{
+	int i;
+	struct reiserfs_journal *journal = SB_JOURNAL(p_s_sb);
+	struct reiserfs_bitmap_node *bn = NULL;
+	for (i = 0; i < REISERFS_MIN_BITMAP_NODES; i++) {
+		bn = allocate_bitmap_node(p_s_sb);
+		if (bn) {
+			list_add(&bn->list, &journal->j_bitmap_nodes);
+			journal->j_free_bitmap_nodes++;
+		} else {
+			break;	// this is ok, we'll try again when more are needed 
+		}
+	}
 }
 
 static int set_bit_in_list_bitmap(struct super_block *p_s_sb, int block,
-                                  struct reiserfs_list_bitmap *jb) {
-  int bmap_nr = block / (p_s_sb->s_blocksize << 3) ;
-  int bit_nr = block % (p_s_sb->s_blocksize << 3) ;
-
-  if (!jb->bitmaps[bmap_nr]) {
-    jb->bitmaps[bmap_nr] = get_bitmap_node(p_s_sb) ;
-  }
-  set_bit(bit_nr, (unsigned long *)jb->bitmaps[bmap_nr]->data) ;
-  return 0 ;
+				  struct reiserfs_list_bitmap *jb)
+{
+	int bmap_nr = block / (p_s_sb->s_blocksize << 3);
+	int bit_nr = block % (p_s_sb->s_blocksize << 3);
+
+	if (!jb->bitmaps[bmap_nr]) {
+		jb->bitmaps[bmap_nr] = get_bitmap_node(p_s_sb);
+	}
+	set_bit(bit_nr, (unsigned long *)jb->bitmaps[bmap_nr]->data);
+	return 0;
 }
 
 static void cleanup_bitmap_list(struct super_block *p_s_sb,
-                                struct reiserfs_list_bitmap *jb) {
-  int i;
-  if (jb->bitmaps == NULL)
-    return;
-
-  for (i = 0 ; i < SB_BMAP_NR(p_s_sb) ; i++) {
-    if (jb->bitmaps[i]) {
-      free_bitmap_node(p_s_sb, jb->bitmaps[i]) ;
-      jb->bitmaps[i] = NULL ;
-    }
-  }
+				struct reiserfs_list_bitmap *jb)
+{
+	int i;
+	if (jb->bitmaps == NULL)
+		return;
+
+	for (i = 0; i < SB_BMAP_NR(p_s_sb); i++) {
+		if (jb->bitmaps[i]) {
+			free_bitmap_node(p_s_sb, jb->bitmaps[i]);
+			jb->bitmaps[i] = NULL;
+		}
+	}
 }
 
 /*
 ** only call this on FS unmount.
 */
 static int free_list_bitmaps(struct super_block *p_s_sb,
-                             struct reiserfs_list_bitmap *jb_array) {
-  int i ;
-  struct reiserfs_list_bitmap *jb ;
-  for (i = 0 ; i < JOURNAL_NUM_BITMAPS ; i++) {
-    jb = jb_array + i ;
-    jb->journal_list = NULL ;
-    cleanup_bitmap_list(p_s_sb, jb) ;
-    vfree(jb->bitmaps) ;
-    jb->bitmaps = NULL ;
-  }
-  return 0;
-}
-
-static int free_bitmap_nodes(struct super_block *p_s_sb) {
-  struct reiserfs_journal *journal = SB_JOURNAL (p_s_sb);
-  struct list_head *next = journal->j_bitmap_nodes.next ;
-  struct reiserfs_bitmap_node *bn ;
-
-  while(next != &journal->j_bitmap_nodes) {
-    bn = list_entry(next, struct reiserfs_bitmap_node, list) ;
-    list_del(next) ;
-    reiserfs_kfree(bn->data, p_s_sb->s_blocksize, p_s_sb) ;
-    reiserfs_kfree(bn, sizeof(struct reiserfs_bitmap_node), p_s_sb) ;
-    next = journal->j_bitmap_nodes.next ;
-    journal->j_free_bitmap_nodes-- ;
-  }
+			     struct reiserfs_list_bitmap *jb_array)
+{
+	int i;
+	struct reiserfs_list_bitmap *jb;
+	for (i = 0; i < JOURNAL_NUM_BITMAPS; i++) {
+		jb = jb_array + i;
+		jb->journal_list = NULL;
+		cleanup_bitmap_list(p_s_sb, jb);
+		vfree(jb->bitmaps);
+		jb->bitmaps = NULL;
+	}
+	return 0;
+}
+
+static int free_bitmap_nodes(struct super_block *p_s_sb)
+{
+	struct reiserfs_journal *journal = SB_JOURNAL(p_s_sb);
+	struct list_head *next = journal->j_bitmap_nodes.next;
+	struct reiserfs_bitmap_node *bn;
+
+	while (next != &journal->j_bitmap_nodes) {
+		bn = list_entry(next, struct reiserfs_bitmap_node, list);
+		list_del(next);
+		reiserfs_kfree(bn->data, p_s_sb->s_blocksize, p_s_sb);
+		reiserfs_kfree(bn, sizeof(struct reiserfs_bitmap_node), p_s_sb);
+		next = journal->j_bitmap_nodes.next;
+		journal->j_free_bitmap_nodes--;
+	}
 
-  return 0 ;
+	return 0;
 }
 
 /*
@@ -275,59 +290,65 @@ static int free_bitmap_nodes(struct supe
 ** jb_array is the array to be filled in.
 */
 int reiserfs_allocate_list_bitmaps(struct super_block *p_s_sb,
-                                   struct reiserfs_list_bitmap *jb_array,
-				   int bmap_nr) {
-  int i ;
-  int failed = 0 ;
-  struct reiserfs_list_bitmap *jb ;
-  int mem = bmap_nr * sizeof(struct reiserfs_bitmap_node *) ;
-
-  for (i = 0 ; i < JOURNAL_NUM_BITMAPS ; i++) {
-    jb = jb_array + i ;
-    jb->journal_list = NULL ;
-    jb->bitmaps = vmalloc( mem ) ;
-    if (!jb->bitmaps) {
-      reiserfs_warning(p_s_sb, "clm-2000, unable to allocate bitmaps for journal lists") ;
-      failed = 1;   
-      break ;
-    }
-    memset(jb->bitmaps, 0, mem) ;
-  }
-  if (failed) {
-    free_list_bitmaps(p_s_sb, jb_array) ;
-    return -1 ;
-  }
-  return 0 ;
+				   struct reiserfs_list_bitmap *jb_array,
+				   int bmap_nr)
+{
+	int i;
+	int failed = 0;
+	struct reiserfs_list_bitmap *jb;
+	int mem = bmap_nr * sizeof(struct reiserfs_bitmap_node *);
+
+	for (i = 0; i < JOURNAL_NUM_BITMAPS; i++) {
+		jb = jb_array + i;
+		jb->journal_list = NULL;
+		jb->bitmaps = vmalloc(mem);
+		if (!jb->bitmaps) {
+			reiserfs_warning(p_s_sb,
+					 "clm-2000, unable to allocate bitmaps for journal lists");
+			failed = 1;
+			break;
+		}
+		memset(jb->bitmaps, 0, mem);
+	}
+	if (failed) {
+		free_list_bitmaps(p_s_sb, jb_array);
+		return -1;
+	}
+	return 0;
 }
 
 /*
 ** find an available list bitmap.  If you can't find one, flush a commit list 
 ** and try again
 */
-static struct reiserfs_list_bitmap *
-get_list_bitmap(struct super_block *p_s_sb, struct reiserfs_journal_list *jl) {
-  int i,j ; 
-  struct reiserfs_journal *journal = SB_JOURNAL (p_s_sb);
-  struct reiserfs_list_bitmap *jb = NULL ;
-
-  for (j = 0 ; j < (JOURNAL_NUM_BITMAPS * 3) ; j++) {
-    i = journal->j_list_bitmap_index ;
-    journal->j_list_bitmap_index = (i + 1) % JOURNAL_NUM_BITMAPS ;
-    jb = journal->j_list_bitmap + i ;
-    if (journal->j_list_bitmap[i].journal_list) {
-      flush_commit_list(p_s_sb, journal->j_list_bitmap[i].journal_list, 1) ;
-      if (!journal->j_list_bitmap[i].journal_list) {
-	break ;
-      }
-    } else {
-      break ;
-    }
-  }
-  if (jb->journal_list) { /* double check to make sure if flushed correctly */
-    return NULL ;
-  }
-  jb->journal_list = jl ;
-  return jb ;
+static struct reiserfs_list_bitmap *get_list_bitmap(struct super_block *p_s_sb,
+						    struct reiserfs_journal_list
+						    *jl)
+{
+	int i, j;
+	struct reiserfs_journal *journal = SB_JOURNAL(p_s_sb);
+	struct reiserfs_list_bitmap *jb = NULL;
+
+	for (j = 0; j < (JOURNAL_NUM_BITMAPS * 3); j++) {
+		i = journal->j_list_bitmap_index;
+		journal->j_list_bitmap_index = (i + 1) % JOURNAL_NUM_BITMAPS;
+		jb = journal->j_list_bitmap + i;
+		if (journal->j_list_bitmap[i].journal_list) {
+			flush_commit_list(p_s_sb,
+					  journal->j_list_bitmap[i].
+					  journal_list, 1);
+			if (!journal->j_list_bitmap[i].journal_list) {
+				break;
+			}
+		} else {
+			break;
+		}
+	}
+	if (jb->journal_list) {	/* double check to make sure if flushed correctly */
+		return NULL;
+	}
+	jb->journal_list = jl;
+	return jb;
 }
 
 /* 
@@ -335,104 +356,114 @@ get_list_bitmap(struct super_block *p_s_
 ** Uses the cnode->next and cnode->prev pointers
 ** returns NULL on failure
 */
-static struct reiserfs_journal_cnode *allocate_cnodes(int num_cnodes) {
-  struct reiserfs_journal_cnode *head ;
-  int i ;
-  if (num_cnodes <= 0) {
-    return NULL ;
-  }
-  head = vmalloc(num_cnodes * sizeof(struct reiserfs_journal_cnode)) ;
-  if (!head) {
-    return NULL ;
-  }
-  memset(head, 0, num_cnodes * sizeof(struct reiserfs_journal_cnode)) ;
-  head[0].prev = NULL ;
-  head[0].next = head + 1 ;
-  for (i = 1 ; i < num_cnodes; i++) {
-    head[i].prev = head + (i - 1) ;
-    head[i].next = head + (i + 1) ; /* if last one, overwrite it after the if */
-  }
-  head[num_cnodes -1].next = NULL ;
-  return head ;
+static struct reiserfs_journal_cnode *allocate_cnodes(int num_cnodes)
+{
+	struct reiserfs_journal_cnode *head;
+	int i;
+	if (num_cnodes <= 0) {
+		return NULL;
+	}
+	head = vmalloc(num_cnodes * sizeof(struct reiserfs_journal_cnode));
+	if (!head) {
+		return NULL;
+	}
+	memset(head, 0, num_cnodes * sizeof(struct reiserfs_journal_cnode));
+	head[0].prev = NULL;
+	head[0].next = head + 1;
+	for (i = 1; i < num_cnodes; i++) {
+		head[i].prev = head + (i - 1);
+		head[i].next = head + (i + 1);	/* if last one, overwrite it after the if */
+	}
+	head[num_cnodes - 1].next = NULL;
+	return head;
 }
 
 /*
 ** pulls a cnode off the free list, or returns NULL on failure 
 */
-static struct reiserfs_journal_cnode *get_cnode(struct super_block *p_s_sb) {
-  struct reiserfs_journal_cnode *cn ;
-  struct reiserfs_journal *journal = SB_JOURNAL (p_s_sb);
-
-  reiserfs_check_lock_depth(p_s_sb, "get_cnode") ;
-
-  if (journal->j_cnode_free <= 0) {
-    return NULL ;
-  }
-  journal->j_cnode_used++ ;
-  journal->j_cnode_free-- ;
-  cn = journal->j_cnode_free_list ;
-  if (!cn) {
-    return cn ;
-  }
-  if (cn->next) {
-    cn->next->prev = NULL ;
-  }
-  journal->j_cnode_free_list = cn->next ;
-  memset(cn, 0, sizeof(struct reiserfs_journal_cnode)) ;
-  return cn ;
+static struct reiserfs_journal_cnode *get_cnode(struct super_block *p_s_sb)
+{
+	struct reiserfs_journal_cnode *cn;
+	struct reiserfs_journal *journal = SB_JOURNAL(p_s_sb);
+
+	reiserfs_check_lock_depth(p_s_sb, "get_cnode");
+
+	if (journal->j_cnode_free <= 0) {
+		return NULL;
+	}
+	journal->j_cnode_used++;
+	journal->j_cnode_free--;
+	cn = journal->j_cnode_free_list;
+	if (!cn) {
+		return cn;
+	}
+	if (cn->next) {
+		cn->next->prev = NULL;
+	}
+	journal->j_cnode_free_list = cn->next;
+	memset(cn, 0, sizeof(struct reiserfs_journal_cnode));
+	return cn;
 }
 
 /*
 ** returns a cnode to the free list 
 */
-static void free_cnode(struct super_block *p_s_sb, struct reiserfs_journal_cnode *cn) {
-  struct reiserfs_journal *journal = SB_JOURNAL (p_s_sb);
+static void free_cnode(struct super_block *p_s_sb,
+		       struct reiserfs_journal_cnode *cn)
+{
+	struct reiserfs_journal *journal = SB_JOURNAL(p_s_sb);
 
-  reiserfs_check_lock_depth(p_s_sb, "free_cnode") ;
+	reiserfs_check_lock_depth(p_s_sb, "free_cnode");
+
+	journal->j_cnode_used--;
+	journal->j_cnode_free++;
+	/* memset(cn, 0, sizeof(struct reiserfs_journal_cnode)) ; */
+	cn->next = journal->j_cnode_free_list;
+	if (journal->j_cnode_free_list) {
+		journal->j_cnode_free_list->prev = cn;
+	}
+	cn->prev = NULL;	/* not needed with the memset, but I might kill the memset, and forget to do this */
+	journal->j_cnode_free_list = cn;
+}
 
-  journal->j_cnode_used-- ;
-  journal->j_cnode_free++ ;
-  /* memset(cn, 0, sizeof(struct reiserfs_journal_cnode)) ; */
-  cn->next = journal->j_cnode_free_list ;
-  if (journal->j_cnode_free_list) {
-    journal->j_cnode_free_list->prev = cn ;
-  }
-  cn->prev = NULL ; /* not needed with the memset, but I might kill the memset, and forget to do this */
-  journal->j_cnode_free_list = cn ;
-}
-
-static void clear_prepared_bits(struct buffer_head *bh) {
-  clear_buffer_journal_prepared (bh);
-  clear_buffer_journal_restore_dirty (bh);
+static void clear_prepared_bits(struct buffer_head *bh)
+{
+	clear_buffer_journal_prepared(bh);
+	clear_buffer_journal_restore_dirty(bh);
 }
 
 /* utility function to force a BUG if it is called without the big
 ** kernel lock held.  caller is the string printed just before calling BUG()
 */
-void reiserfs_check_lock_depth(struct super_block *sb, char *caller) {
+void reiserfs_check_lock_depth(struct super_block *sb, char *caller)
+{
 #ifdef CONFIG_SMP
-  if (current->lock_depth < 0) {
-    reiserfs_panic (sb, "%s called without kernel lock held", caller) ;
-  }
+	if (current->lock_depth < 0) {
+		reiserfs_panic(sb, "%s called without kernel lock held",
+			       caller);
+	}
 #else
-  ;
+	;
 #endif
 }
 
 /* return a cnode with same dev, block number and size in table, or null if not found */
-static inline struct reiserfs_journal_cnode *
-get_journal_hash_dev(struct super_block *sb,
-		     struct reiserfs_journal_cnode **table,
-		     long bl)
-{
-  struct reiserfs_journal_cnode *cn ;
-  cn = journal_hash(table, sb, bl) ;
-  while(cn) {
-    if (cn->blocknr == bl && cn->sb == sb)
-      return cn ;
-    cn = cn->hnext ;
-  }
-  return (struct reiserfs_journal_cnode *)0 ;
+static inline struct reiserfs_journal_cnode *get_journal_hash_dev(struct
+								  super_block
+								  *sb,
+								  struct
+								  reiserfs_journal_cnode
+								  **table,
+								  long bl)
+{
+	struct reiserfs_journal_cnode *cn;
+	cn = journal_hash(table, sb, bl);
+	while (cn) {
+		if (cn->blocknr == bl && cn->sb == sb)
+			return cn;
+		cn = cn->hnext;
+	}
+	return (struct reiserfs_journal_cnode *)0;
 }
 
 /*
@@ -454,91 +485,103 @@ get_journal_hash_dev(struct super_block 
 **
 */
 int reiserfs_in_journal(struct super_block *p_s_sb,
-                        int bmap_nr, int bit_nr, int search_all, 
-			b_blocknr_t *next_zero_bit) {
-  struct reiserfs_journal *journal = SB_JOURNAL (p_s_sb);
-  struct reiserfs_journal_cnode *cn ;
-  struct reiserfs_list_bitmap *jb ;
-  int i ;
-  unsigned long bl;
-
-  *next_zero_bit = 0 ; /* always start this at zero. */
-
-  PROC_INFO_INC( p_s_sb, journal.in_journal );
-  /* If we aren't doing a search_all, this is a metablock, and it will be logged before use.
-  ** if we crash before the transaction that freed it commits,  this transaction won't
-  ** have committed either, and the block will never be written
-  */
-  if (search_all) {
-    for (i = 0 ; i < JOURNAL_NUM_BITMAPS ; i++) {
-      PROC_INFO_INC( p_s_sb, journal.in_journal_bitmap );
-      jb = journal->j_list_bitmap + i ;
-      if (jb->journal_list && jb->bitmaps[bmap_nr] &&
-          test_bit(bit_nr, (unsigned long *)jb->bitmaps[bmap_nr]->data)) {
-	*next_zero_bit = find_next_zero_bit((unsigned long *)
-	                             (jb->bitmaps[bmap_nr]->data),
-	                             p_s_sb->s_blocksize << 3, bit_nr+1) ; 
-	return 1 ;
-      }
-    }
-  }
-
-  bl = bmap_nr * (p_s_sb->s_blocksize << 3) + bit_nr;
-  /* is it in any old transactions? */
-  if (search_all && (cn = get_journal_hash_dev(p_s_sb, journal->j_list_hash_table, bl))) {
-    return 1; 
-  }
-
-  /* is it in the current transaction.  This should never happen */
-  if ((cn = get_journal_hash_dev(p_s_sb, journal->j_hash_table, bl))) {
-    BUG();
-    return 1; 
-  }
-
-  PROC_INFO_INC( p_s_sb, journal.in_journal_reusable );
-  /* safe for reuse */
-  return 0 ;
+			int bmap_nr, int bit_nr, int search_all,
+			b_blocknr_t * next_zero_bit)
+{
+	struct reiserfs_journal *journal = SB_JOURNAL(p_s_sb);
+	struct reiserfs_journal_cnode *cn;
+	struct reiserfs_list_bitmap *jb;
+	int i;
+	unsigned long bl;
+
+	*next_zero_bit = 0;	/* always start this at zero. */
+
+	PROC_INFO_INC(p_s_sb, journal.in_journal);
+	/* If we aren't doing a search_all, this is a metablock, and it will be logged before use.
+	 ** if we crash before the transaction that freed it commits,  this transaction won't
+	 ** have committed either, and the block will never be written
+	 */
+	if (search_all) {
+		for (i = 0; i < JOURNAL_NUM_BITMAPS; i++) {
+			PROC_INFO_INC(p_s_sb, journal.in_journal_bitmap);
+			jb = journal->j_list_bitmap + i;
+			if (jb->journal_list && jb->bitmaps[bmap_nr] &&
+			    test_bit(bit_nr,
+				     (unsigned long *)jb->bitmaps[bmap_nr]->
+				     data)) {
+				*next_zero_bit =
+				    find_next_zero_bit((unsigned long *)
+						       (jb->bitmaps[bmap_nr]->
+							data),
+						       p_s_sb->s_blocksize << 3,
+						       bit_nr + 1);
+				return 1;
+			}
+		}
+	}
+
+	bl = bmap_nr * (p_s_sb->s_blocksize << 3) + bit_nr;
+	/* is it in any old transactions? */
+	if (search_all
+	    && (cn =
+		get_journal_hash_dev(p_s_sb, journal->j_list_hash_table, bl))) {
+		return 1;
+	}
+
+	/* is it in the current transaction.  This should never happen */
+	if ((cn = get_journal_hash_dev(p_s_sb, journal->j_hash_table, bl))) {
+		BUG();
+		return 1;
+	}
+
+	PROC_INFO_INC(p_s_sb, journal.in_journal_reusable);
+	/* safe for reuse */
+	return 0;
 }
 
 /* insert cn into table
 */
-static inline void insert_journal_hash(struct reiserfs_journal_cnode **table, struct reiserfs_journal_cnode *cn) {
-  struct reiserfs_journal_cnode *cn_orig ;
+static inline void insert_journal_hash(struct reiserfs_journal_cnode **table,
+				       struct reiserfs_journal_cnode *cn)
+{
+	struct reiserfs_journal_cnode *cn_orig;
 
-  cn_orig = journal_hash(table, cn->sb, cn->blocknr) ;
-  cn->hnext = cn_orig ;
-  cn->hprev = NULL ;
-  if (cn_orig) {
-    cn_orig->hprev = cn ;
-  }
-  journal_hash(table, cn->sb, cn->blocknr) =  cn ;
+	cn_orig = journal_hash(table, cn->sb, cn->blocknr);
+	cn->hnext = cn_orig;
+	cn->hprev = NULL;
+	if (cn_orig) {
+		cn_orig->hprev = cn;
+	}
+	journal_hash(table, cn->sb, cn->blocknr) = cn;
 }
 
 /* lock the current transaction */
-inline static void lock_journal(struct super_block *p_s_sb) {
-    PROC_INFO_INC( p_s_sb, journal.lock_journal );
-    down(&SB_JOURNAL(p_s_sb)->j_lock);
+static inline void lock_journal(struct super_block *p_s_sb)
+{
+	PROC_INFO_INC(p_s_sb, journal.lock_journal);
+	down(&SB_JOURNAL(p_s_sb)->j_lock);
 }
 
 /* unlock the current transaction */
-inline static void unlock_journal(struct super_block *p_s_sb) {
-    up(&SB_JOURNAL(p_s_sb)->j_lock);
+static inline void unlock_journal(struct super_block *p_s_sb)
+{
+	up(&SB_JOURNAL(p_s_sb)->j_lock);
 }
 
 static inline void get_journal_list(struct reiserfs_journal_list *jl)
 {
-    jl->j_refcount++;
+	jl->j_refcount++;
 }
 
 static inline void put_journal_list(struct super_block *s,
-                                   struct reiserfs_journal_list *jl)
+				    struct reiserfs_journal_list *jl)
 {
-    if (jl->j_refcount < 1) {
-        reiserfs_panic (s, "trans id %lu, refcount at %d", jl->j_trans_id,
-	                                         jl->j_refcount);
-    }
-    if (--jl->j_refcount == 0)
-        reiserfs_kfree(jl, sizeof(struct reiserfs_journal_list), s);
+	if (jl->j_refcount < 1) {
+		reiserfs_panic(s, "trans id %lu, refcount at %d",
+			       jl->j_trans_id, jl->j_refcount);
+	}
+	if (--jl->j_refcount == 0)
+		reiserfs_kfree(jl, sizeof(struct reiserfs_journal_list), s);
 }
 
 /*
@@ -546,354 +589,375 @@ static inline void put_journal_list(stru
 ** it gets called by flush_commit_list, and cleans up any data stored about blocks freed during a
 ** transaction.
 */
-static void cleanup_freed_for_journal_list(struct super_block *p_s_sb, struct reiserfs_journal_list *jl) {
+static void cleanup_freed_for_journal_list(struct super_block *p_s_sb,
+					   struct reiserfs_journal_list *jl)
+{
 
-  struct reiserfs_list_bitmap *jb = jl->j_list_bitmap ;
-  if (jb) {
-    cleanup_bitmap_list(p_s_sb, jb) ;
-  }
-  jl->j_list_bitmap->journal_list = NULL ;
-  jl->j_list_bitmap = NULL ;
+	struct reiserfs_list_bitmap *jb = jl->j_list_bitmap;
+	if (jb) {
+		cleanup_bitmap_list(p_s_sb, jb);
+	}
+	jl->j_list_bitmap->journal_list = NULL;
+	jl->j_list_bitmap = NULL;
 }
 
 static int journal_list_still_alive(struct super_block *s,
-                                    unsigned long trans_id)
+				    unsigned long trans_id)
+{
+	struct reiserfs_journal *journal = SB_JOURNAL(s);
+	struct list_head *entry = &journal->j_journal_list;
+	struct reiserfs_journal_list *jl;
+
+	if (!list_empty(entry)) {
+		jl = JOURNAL_LIST_ENTRY(entry->next);
+		if (jl->j_trans_id <= trans_id) {
+			return 1;
+		}
+	}
+	return 0;
+}
+
+static void reiserfs_end_buffer_io_sync(struct buffer_head *bh, int uptodate)
+{
+	char b[BDEVNAME_SIZE];
+
+	if (buffer_journaled(bh)) {
+		reiserfs_warning(NULL,
+				 "clm-2084: pinned buffer %lu:%s sent to disk",
+				 bh->b_blocknr, bdevname(bh->b_bdev, b));
+	}
+	if (uptodate)
+		set_buffer_uptodate(bh);
+	else
+		clear_buffer_uptodate(bh);
+	unlock_buffer(bh);
+	put_bh(bh);
+}
+
+static void reiserfs_end_ordered_io(struct buffer_head *bh, int uptodate)
 {
-    struct reiserfs_journal *journal = SB_JOURNAL (s);
-    struct list_head *entry = &journal->j_journal_list;
-    struct reiserfs_journal_list *jl;
-
-    if (!list_empty(entry)) {
-        jl = JOURNAL_LIST_ENTRY(entry->next);
-	if (jl->j_trans_id <= trans_id) {
-	    return 1;
-	}
-    }
-    return 0;
-}
-
-static void reiserfs_end_buffer_io_sync(struct buffer_head *bh, int uptodate) {
-    char b[BDEVNAME_SIZE];
-
-    if (buffer_journaled(bh)) {
-        reiserfs_warning(NULL, "clm-2084: pinned buffer %lu:%s sent to disk",
-	                 bh->b_blocknr, bdevname(bh->b_bdev, b)) ;
-    }
-    if (uptodate)
-    	set_buffer_uptodate(bh) ;
-    else
-    	clear_buffer_uptodate(bh) ;
-    unlock_buffer(bh) ;
-    put_bh(bh) ;
-}
-
-static void reiserfs_end_ordered_io(struct buffer_head *bh, int uptodate) {
-    if (uptodate)
-    	set_buffer_uptodate(bh) ;
-    else
-    	clear_buffer_uptodate(bh) ;
-    unlock_buffer(bh) ;
-    put_bh(bh) ;
-}
-
-static void submit_logged_buffer(struct buffer_head *bh) {
-    get_bh(bh) ;
-    bh->b_end_io = reiserfs_end_buffer_io_sync ;
-    clear_buffer_journal_new (bh);
-    clear_buffer_dirty(bh) ;
-    if (!test_clear_buffer_journal_test (bh))
-        BUG();
-    if (!buffer_uptodate(bh))
-        BUG();
-    submit_bh(WRITE, bh) ;
-}
-
-static void submit_ordered_buffer(struct buffer_head *bh) {
-    get_bh(bh) ;
-    bh->b_end_io = reiserfs_end_ordered_io;
-    clear_buffer_dirty(bh) ;
-    if (!buffer_uptodate(bh))
-        BUG();
-    submit_bh(WRITE, bh) ;
-}
-
-static int submit_barrier_buffer(struct buffer_head *bh) {
-    get_bh(bh) ;
-    bh->b_end_io = reiserfs_end_ordered_io;
-    clear_buffer_dirty(bh) ;
-    if (!buffer_uptodate(bh))
-        BUG();
-    return submit_bh(WRITE_BARRIER, bh) ;
+	if (uptodate)
+		set_buffer_uptodate(bh);
+	else
+		clear_buffer_uptodate(bh);
+	unlock_buffer(bh);
+	put_bh(bh);
+}
+
+static void submit_logged_buffer(struct buffer_head *bh)
+{
+	get_bh(bh);
+	bh->b_end_io = reiserfs_end_buffer_io_sync;
+	clear_buffer_journal_new(bh);
+	clear_buffer_dirty(bh);
+	if (!test_clear_buffer_journal_test(bh))
+		BUG();
+	if (!buffer_uptodate(bh))
+		BUG();
+	submit_bh(WRITE, bh);
+}
+
+static void submit_ordered_buffer(struct buffer_head *bh)
+{
+	get_bh(bh);
+	bh->b_end_io = reiserfs_end_ordered_io;
+	clear_buffer_dirty(bh);
+	if (!buffer_uptodate(bh))
+		BUG();
+	submit_bh(WRITE, bh);
+}
+
+static int submit_barrier_buffer(struct buffer_head *bh)
+{
+	get_bh(bh);
+	bh->b_end_io = reiserfs_end_ordered_io;
+	clear_buffer_dirty(bh);
+	if (!buffer_uptodate(bh))
+		BUG();
+	return submit_bh(WRITE_BARRIER, bh);
 }
 
 static void check_barrier_completion(struct super_block *s,
-                                     struct buffer_head *bh) {
-    if (buffer_eopnotsupp(bh)) {
-	clear_buffer_eopnotsupp(bh);
-	disable_barrier(s);
-	set_buffer_uptodate(bh);
-	set_buffer_dirty(bh);
-	sync_dirty_buffer(bh);
-    }
+				     struct buffer_head *bh)
+{
+	if (buffer_eopnotsupp(bh)) {
+		clear_buffer_eopnotsupp(bh);
+		disable_barrier(s);
+		set_buffer_uptodate(bh);
+		set_buffer_dirty(bh);
+		sync_dirty_buffer(bh);
+	}
 }
 
 #define CHUNK_SIZE 32
 struct buffer_chunk {
-    struct buffer_head *bh[CHUNK_SIZE];
-    int nr;
+	struct buffer_head *bh[CHUNK_SIZE];
+	int nr;
 };
 
-static void write_chunk(struct buffer_chunk *chunk) {
-    int i;
-    for (i = 0; i < chunk->nr ; i++) {
-	submit_logged_buffer(chunk->bh[i]) ;
-    }
-    chunk->nr = 0;
+static void write_chunk(struct buffer_chunk *chunk)
+{
+	int i;
+	get_fs_excl();
+	for (i = 0; i < chunk->nr; i++) {
+		submit_logged_buffer(chunk->bh[i]);
+	}
+	chunk->nr = 0;
+	put_fs_excl();
 }
 
-static void write_ordered_chunk(struct buffer_chunk *chunk) {
-    int i;
-    for (i = 0; i < chunk->nr ; i++) {
-	submit_ordered_buffer(chunk->bh[i]) ;
-    }
-    chunk->nr = 0;
+static void write_ordered_chunk(struct buffer_chunk *chunk)
+{
+	int i;
+	get_fs_excl();
+	for (i = 0; i < chunk->nr; i++) {
+		submit_ordered_buffer(chunk->bh[i]);
+	}
+	chunk->nr = 0;
+	put_fs_excl();
 }
 
 static int add_to_chunk(struct buffer_chunk *chunk, struct buffer_head *bh,
-			 spinlock_t *lock,
-			 void (fn)(struct buffer_chunk *))
+			spinlock_t * lock, void (fn) (struct buffer_chunk *))
 {
-    int ret = 0;
-    if (chunk->nr >= CHUNK_SIZE)
-        BUG();
-    chunk->bh[chunk->nr++] = bh;
-    if (chunk->nr >= CHUNK_SIZE) {
-	ret = 1;
-        if (lock)
-	    spin_unlock(lock);
-        fn(chunk);
-        if (lock)
-	    spin_lock(lock);
-    }
-    return ret;
+	int ret = 0;
+	if (chunk->nr >= CHUNK_SIZE)
+		BUG();
+	chunk->bh[chunk->nr++] = bh;
+	if (chunk->nr >= CHUNK_SIZE) {
+		ret = 1;
+		if (lock)
+			spin_unlock(lock);
+		fn(chunk);
+		if (lock)
+			spin_lock(lock);
+	}
+	return ret;
 }
 
-
 static atomic_t nr_reiserfs_jh = ATOMIC_INIT(0);
-static struct reiserfs_jh *alloc_jh(void) {
-    struct reiserfs_jh *jh;
-    while(1) {
-	jh = kmalloc(sizeof(*jh), GFP_NOFS);
-	if (jh) {
-	    atomic_inc(&nr_reiserfs_jh);
-	    return jh;
+static struct reiserfs_jh *alloc_jh(void)
+{
+	struct reiserfs_jh *jh;
+	while (1) {
+		jh = kmalloc(sizeof(*jh), GFP_NOFS);
+		if (jh) {
+			atomic_inc(&nr_reiserfs_jh);
+			return jh;
+		}
+		yield();
 	}
-        yield();
-    }
 }
 
 /*
  * we want to free the jh when the buffer has been written
  * and waited on
  */
-void reiserfs_free_jh(struct buffer_head *bh) {
-    struct reiserfs_jh *jh;
+void reiserfs_free_jh(struct buffer_head *bh)
+{
+	struct reiserfs_jh *jh;
 
-    jh = bh->b_private;
-    if (jh) {
-	bh->b_private = NULL;
-	jh->bh = NULL;
-	list_del_init(&jh->list);
-	kfree(jh);
-	if (atomic_read(&nr_reiserfs_jh) <= 0)
-	    BUG();
-	atomic_dec(&nr_reiserfs_jh);
-	put_bh(bh);
-    }
+	jh = bh->b_private;
+	if (jh) {
+		bh->b_private = NULL;
+		jh->bh = NULL;
+		list_del_init(&jh->list);
+		kfree(jh);
+		if (atomic_read(&nr_reiserfs_jh) <= 0)
+			BUG();
+		atomic_dec(&nr_reiserfs_jh);
+		put_bh(bh);
+	}
 }
 
 static inline int __add_jh(struct reiserfs_journal *j, struct buffer_head *bh,
-                           int tail)
+			   int tail)
 {
-    struct reiserfs_jh *jh;
+	struct reiserfs_jh *jh;
 
-    if (bh->b_private) {
-	spin_lock(&j->j_dirty_buffers_lock);
-	if (!bh->b_private) {
-	    spin_unlock(&j->j_dirty_buffers_lock);
-	    goto no_jh;
-	}
-        jh = bh->b_private;
-	list_del_init(&jh->list);
-    } else {
-no_jh:
-	get_bh(bh);
-	jh = alloc_jh();
-	spin_lock(&j->j_dirty_buffers_lock);
-	/* buffer must be locked for __add_jh, should be able to have
-	 * two adds at the same time
-	 */
-	if (bh->b_private)
-	    BUG();
-	jh->bh = bh;
-	bh->b_private = jh;
-    }
-    jh->jl = j->j_current_jl;
-    if (tail)
-	list_add_tail(&jh->list, &jh->jl->j_tail_bh_list);
-    else {
-	list_add_tail(&jh->list, &jh->jl->j_bh_list);
-    }
-    spin_unlock(&j->j_dirty_buffers_lock);
-    return 0;
+	if (bh->b_private) {
+		spin_lock(&j->j_dirty_buffers_lock);
+		if (!bh->b_private) {
+			spin_unlock(&j->j_dirty_buffers_lock);
+			goto no_jh;
+		}
+		jh = bh->b_private;
+		list_del_init(&jh->list);
+	} else {
+	      no_jh:
+		get_bh(bh);
+		jh = alloc_jh();
+		spin_lock(&j->j_dirty_buffers_lock);
+		/* buffer must be locked for __add_jh, should be able to have
+		 * two adds at the same time
+		 */
+		if (bh->b_private)
+			BUG();
+		jh->bh = bh;
+		bh->b_private = jh;
+	}
+	jh->jl = j->j_current_jl;
+	if (tail)
+		list_add_tail(&jh->list, &jh->jl->j_tail_bh_list);
+	else {
+		list_add_tail(&jh->list, &jh->jl->j_bh_list);
+	}
+	spin_unlock(&j->j_dirty_buffers_lock);
+	return 0;
 }
 
-int reiserfs_add_tail_list(struct inode *inode, struct buffer_head *bh) {
-    return __add_jh(SB_JOURNAL(inode->i_sb), bh, 1);
+int reiserfs_add_tail_list(struct inode *inode, struct buffer_head *bh)
+{
+	return __add_jh(SB_JOURNAL(inode->i_sb), bh, 1);
 }
-int reiserfs_add_ordered_list(struct inode *inode, struct buffer_head *bh) {
-    return __add_jh(SB_JOURNAL(inode->i_sb), bh, 0);
+int reiserfs_add_ordered_list(struct inode *inode, struct buffer_head *bh)
+{
+	return __add_jh(SB_JOURNAL(inode->i_sb), bh, 0);
 }
 
 #define JH_ENTRY(l) list_entry((l), struct reiserfs_jh, list)
-static int write_ordered_buffers(spinlock_t *lock,
+static int write_ordered_buffers(spinlock_t * lock,
 				 struct reiserfs_journal *j,
-                                 struct reiserfs_journal_list *jl,
+				 struct reiserfs_journal_list *jl,
 				 struct list_head *list)
 {
-    struct buffer_head *bh;
-    struct reiserfs_jh *jh;
-    int ret = j->j_errno;
-    struct buffer_chunk chunk;
-    struct list_head tmp;
-    INIT_LIST_HEAD(&tmp);
-
-    chunk.nr = 0;
-    spin_lock(lock);
-    while(!list_empty(list)) {
-        jh = JH_ENTRY(list->next);
-	bh = jh->bh;
-	get_bh(bh);
-	if (test_set_buffer_locked(bh)) {
-	    if (!buffer_dirty(bh)) {
-		list_del_init(&jh->list);
-		list_add(&jh->list, &tmp);
-		goto loop_next;
-	    }
-	    spin_unlock(lock);
-	    if (chunk.nr)
+	struct buffer_head *bh;
+	struct reiserfs_jh *jh;
+	int ret = j->j_errno;
+	struct buffer_chunk chunk;
+	struct list_head tmp;
+	INIT_LIST_HEAD(&tmp);
+
+	chunk.nr = 0;
+	spin_lock(lock);
+	while (!list_empty(list)) {
+		jh = JH_ENTRY(list->next);
+		bh = jh->bh;
+		get_bh(bh);
+		if (test_set_buffer_locked(bh)) {
+			if (!buffer_dirty(bh)) {
+				list_del_init(&jh->list);
+				list_add(&jh->list, &tmp);
+				goto loop_next;
+			}
+			spin_unlock(lock);
+			if (chunk.nr)
+				write_ordered_chunk(&chunk);
+			wait_on_buffer(bh);
+			cond_resched();
+			spin_lock(lock);
+			goto loop_next;
+		}
+		if (buffer_dirty(bh)) {
+			list_del_init(&jh->list);
+			list_add(&jh->list, &tmp);
+			add_to_chunk(&chunk, bh, lock, write_ordered_chunk);
+		} else {
+			reiserfs_free_jh(bh);
+			unlock_buffer(bh);
+		}
+	      loop_next:
+		put_bh(bh);
+		cond_resched_lock(lock);
+	}
+	if (chunk.nr) {
+		spin_unlock(lock);
 		write_ordered_chunk(&chunk);
-	    wait_on_buffer(bh);
-	    cond_resched();
-	    spin_lock(lock);
-	    goto loop_next;
-        }
-	if (buffer_dirty(bh)) {
-	    list_del_init(&jh->list);
-	    list_add(&jh->list, &tmp);
-            add_to_chunk(&chunk, bh, lock, write_ordered_chunk);
-	} else {
-	    reiserfs_free_jh(bh);
-	    unlock_buffer(bh);
+		spin_lock(lock);
+	}
+	while (!list_empty(&tmp)) {
+		jh = JH_ENTRY(tmp.prev);
+		bh = jh->bh;
+		get_bh(bh);
+		reiserfs_free_jh(bh);
+
+		if (buffer_locked(bh)) {
+			spin_unlock(lock);
+			wait_on_buffer(bh);
+			spin_lock(lock);
+		}
+		if (!buffer_uptodate(bh)) {
+			ret = -EIO;
+		}
+		put_bh(bh);
+		cond_resched_lock(lock);
 	}
-loop_next:
-	put_bh(bh);
-	cond_resched_lock(lock);
-    }
-    if (chunk.nr) {
 	spin_unlock(lock);
-        write_ordered_chunk(&chunk);
-	spin_lock(lock);
-    }
-    while(!list_empty(&tmp)) {
-        jh = JH_ENTRY(tmp.prev);
-	bh = jh->bh;
-	get_bh(bh);
-	reiserfs_free_jh(bh);
+	return ret;
+}
 
-	if (buffer_locked(bh)) {
-	    spin_unlock(lock);
-	    wait_on_buffer(bh);
-	    spin_lock(lock);
-	}
-	if (!buffer_uptodate(bh)) {
-	    ret = -EIO;
-        }
-	put_bh(bh);
-	cond_resched_lock(lock);
-    }
-    spin_unlock(lock);
-    return ret;
-}
-
-static int flush_older_commits(struct super_block *s, struct reiserfs_journal_list *jl) {
-    struct reiserfs_journal *journal = SB_JOURNAL (s);
-    struct reiserfs_journal_list *other_jl;
-    struct reiserfs_journal_list *first_jl;
-    struct list_head *entry;
-    unsigned long trans_id = jl->j_trans_id;
-    unsigned long other_trans_id;
-    unsigned long first_trans_id;
-
-find_first:
-    /*
-     * first we walk backwards to find the oldest uncommitted transation
-     */
-    first_jl = jl;
-    entry = jl->j_list.prev;
-    while(1) {
-	other_jl = JOURNAL_LIST_ENTRY(entry);
-	if (entry == &journal->j_journal_list ||
-	    atomic_read(&other_jl->j_older_commits_done))
-	    break;
-
-        first_jl = other_jl;
-	entry = other_jl->j_list.prev;
-    }
-
-    /* if we didn't find any older uncommitted transactions, return now */
-    if (first_jl == jl) {
-        return 0;
-    }
+static int flush_older_commits(struct super_block *s,
+			       struct reiserfs_journal_list *jl)
+{
+	struct reiserfs_journal *journal = SB_JOURNAL(s);
+	struct reiserfs_journal_list *other_jl;
+	struct reiserfs_journal_list *first_jl;
+	struct list_head *entry;
+	unsigned long trans_id = jl->j_trans_id;
+	unsigned long other_trans_id;
+	unsigned long first_trans_id;
+
+      find_first:
+	/*
+	 * first we walk backwards to find the oldest uncommitted transation
+	 */
+	first_jl = jl;
+	entry = jl->j_list.prev;
+	while (1) {
+		other_jl = JOURNAL_LIST_ENTRY(entry);
+		if (entry == &journal->j_journal_list ||
+		    atomic_read(&other_jl->j_older_commits_done))
+			break;
 
-    first_trans_id = first_jl->j_trans_id;
+		first_jl = other_jl;
+		entry = other_jl->j_list.prev;
+	}
 
-    entry = &first_jl->j_list;
-    while(1) {
-	other_jl = JOURNAL_LIST_ENTRY(entry);
-	other_trans_id = other_jl->j_trans_id;
+	/* if we didn't find any older uncommitted transactions, return now */
+	if (first_jl == jl) {
+		return 0;
+	}
 
-	if (other_trans_id < trans_id) {
-	    if (atomic_read(&other_jl->j_commit_left) != 0) {
-		flush_commit_list(s, other_jl, 0);
-
-		/* list we were called with is gone, return */
-		if (!journal_list_still_alive(s, trans_id))
-		    return 1;
-
-		/* the one we just flushed is gone, this means all
-		 * older lists are also gone, so first_jl is no longer
-		 * valid either.  Go back to the beginning.
-		 */
-		if (!journal_list_still_alive(s, other_trans_id)) {
-		    goto find_first;
+	first_trans_id = first_jl->j_trans_id;
+
+	entry = &first_jl->j_list;
+	while (1) {
+		other_jl = JOURNAL_LIST_ENTRY(entry);
+		other_trans_id = other_jl->j_trans_id;
+
+		if (other_trans_id < trans_id) {
+			if (atomic_read(&other_jl->j_commit_left) != 0) {
+				flush_commit_list(s, other_jl, 0);
+
+				/* list we were called with is gone, return */
+				if (!journal_list_still_alive(s, trans_id))
+					return 1;
+
+				/* the one we just flushed is gone, this means all
+				 * older lists are also gone, so first_jl is no longer
+				 * valid either.  Go back to the beginning.
+				 */
+				if (!journal_list_still_alive
+				    (s, other_trans_id)) {
+					goto find_first;
+				}
+			}
+			entry = entry->next;
+			if (entry == &journal->j_journal_list)
+				return 0;
+		} else {
+			return 0;
 		}
-	    }
-	    entry = entry->next;
-	    if (entry == &journal->j_journal_list)
-		return 0;
-	} else {
-	    return 0;
 	}
-    }
-    return 0;
+	return 0;
 }
-int reiserfs_async_progress_wait(struct super_block *s) {
-    DEFINE_WAIT(wait);
-    struct reiserfs_journal *j = SB_JOURNAL(s);
-    if (atomic_read(&j->j_async_throttle))
-    	blk_congestion_wait(WRITE, HZ/10);
-    return 0;
+int reiserfs_async_progress_wait(struct super_block *s)
+{
+	DEFINE_WAIT(wait);
+	struct reiserfs_journal *j = SB_JOURNAL(s);
+	if (atomic_read(&j->j_async_throttle))
+		blk_congestion_wait(WRITE, HZ / 10);
+	return 0;
 }
 
 /*
@@ -903,209 +967,225 @@ int reiserfs_async_progress_wait(struct 
 ** Before the commit block can by written, every other log block must be safely on disk
 **
 */
-static int flush_commit_list(struct super_block *s, struct reiserfs_journal_list *jl, int flushall) {
-  int i;
-  int bn ;
-  struct buffer_head *tbh = NULL ;
-  unsigned long trans_id = jl->j_trans_id;
-  struct reiserfs_journal *journal = SB_JOURNAL (s);
-  int barrier = 0;
-  int retval = 0;
-
-  reiserfs_check_lock_depth(s, "flush_commit_list") ;
-
-  if (atomic_read(&jl->j_older_commits_done)) {
-    return 0 ;
-  }
-
-  /* before we can put our commit blocks on disk, we have to make sure everyone older than
-  ** us is on disk too
-  */
-  BUG_ON (jl->j_len <= 0);
-  BUG_ON (trans_id == journal->j_trans_id);
-
-  get_journal_list(jl);
-  if (flushall) {
-    if (flush_older_commits(s, jl) == 1) {
-      /* list disappeared during flush_older_commits.  return */
-      goto put_jl;
-    }
-  }
-
-  /* make sure nobody is trying to flush this one at the same time */
-  down(&jl->j_commit_lock);
-  if (!journal_list_still_alive(s, trans_id)) {
-    up(&jl->j_commit_lock);
-    goto put_jl;
-  }
-  BUG_ON (jl->j_trans_id == 0);
-
-  /* this commit is done, exit */
-  if (atomic_read(&(jl->j_commit_left)) <= 0) {
-    if (flushall) {
-      atomic_set(&(jl->j_older_commits_done), 1) ;
-    }
-    up(&jl->j_commit_lock);
-    goto put_jl;
-  }
-
-  if (!list_empty(&jl->j_bh_list)) {
-      unlock_kernel();
-      write_ordered_buffers(&journal->j_dirty_buffers_lock,
-                            journal, jl, &jl->j_bh_list);
-      lock_kernel();
-  }
-  BUG_ON (!list_empty(&jl->j_bh_list));
-  /*
-   * for the description block and all the log blocks, submit any buffers
-   * that haven't already reached the disk
-   */
-  atomic_inc(&journal->j_async_throttle);
-  for (i = 0 ; i < (jl->j_len + 1) ; i++) {
-    bn = SB_ONDISK_JOURNAL_1st_BLOCK(s) + (jl->j_start+i) %
-         SB_ONDISK_JOURNAL_SIZE(s);
-    tbh = journal_find_get_block(s, bn) ;
-    if (buffer_dirty(tbh)) /* redundant, ll_rw_block() checks */
-	ll_rw_block(WRITE, 1, &tbh) ;
-    put_bh(tbh) ;
-  }
-  atomic_dec(&journal->j_async_throttle);
-
-  /* wait on everything written so far before writing the commit
-   * if we are in barrier mode, send the commit down now
-   */
-  barrier = reiserfs_barrier_flush(s);
-  if (barrier) {
-      int ret;
-      lock_buffer(jl->j_commit_bh);
-      ret = submit_barrier_buffer(jl->j_commit_bh);
-      if (ret == -EOPNOTSUPP) {
-	  set_buffer_uptodate(jl->j_commit_bh);
-          disable_barrier(s);
-	  barrier = 0;
-      }
-  }
-  for (i = 0 ;  i < (jl->j_len + 1) ; i++) {
-    bn = SB_ONDISK_JOURNAL_1st_BLOCK(s) +
-	 (jl->j_start + i) % SB_ONDISK_JOURNAL_SIZE(s) ;
-    tbh = journal_find_get_block(s, bn) ;
-    wait_on_buffer(tbh) ;
-    // since we're using ll_rw_blk above, it might have skipped over
-    // a locked buffer.  Double check here
-    //
-    if (buffer_dirty(tbh)) /* redundant, sync_dirty_buffer() checks */
-      sync_dirty_buffer(tbh);
-    if (unlikely (!buffer_uptodate(tbh))) {
+static int flush_commit_list(struct super_block *s,
+			     struct reiserfs_journal_list *jl, int flushall)
+{
+	int i;
+	int bn;
+	struct buffer_head *tbh = NULL;
+	unsigned long trans_id = jl->j_trans_id;
+	struct reiserfs_journal *journal = SB_JOURNAL(s);
+	int barrier = 0;
+	int retval = 0;
+
+	reiserfs_check_lock_depth(s, "flush_commit_list");
+
+	if (atomic_read(&jl->j_older_commits_done)) {
+		return 0;
+	}
+
+	get_fs_excl();
+
+	/* before we can put our commit blocks on disk, we have to make sure everyone older than
+	 ** us is on disk too
+	 */
+	BUG_ON(jl->j_len <= 0);
+	BUG_ON(trans_id == journal->j_trans_id);
+
+	get_journal_list(jl);
+	if (flushall) {
+		if (flush_older_commits(s, jl) == 1) {
+			/* list disappeared during flush_older_commits.  return */
+			goto put_jl;
+		}
+	}
+
+	/* make sure nobody is trying to flush this one at the same time */
+	down(&jl->j_commit_lock);
+	if (!journal_list_still_alive(s, trans_id)) {
+		up(&jl->j_commit_lock);
+		goto put_jl;
+	}
+	BUG_ON(jl->j_trans_id == 0);
+
+	/* this commit is done, exit */
+	if (atomic_read(&(jl->j_commit_left)) <= 0) {
+		if (flushall) {
+			atomic_set(&(jl->j_older_commits_done), 1);
+		}
+		up(&jl->j_commit_lock);
+		goto put_jl;
+	}
+
+	if (!list_empty(&jl->j_bh_list)) {
+		unlock_kernel();
+		write_ordered_buffers(&journal->j_dirty_buffers_lock,
+				      journal, jl, &jl->j_bh_list);
+		lock_kernel();
+	}
+	BUG_ON(!list_empty(&jl->j_bh_list));
+	/*
+	 * for the description block and all the log blocks, submit any buffers
+	 * that haven't already reached the disk
+	 */
+	atomic_inc(&journal->j_async_throttle);
+	for (i = 0; i < (jl->j_len + 1); i++) {
+		bn = SB_ONDISK_JOURNAL_1st_BLOCK(s) + (jl->j_start + i) %
+		    SB_ONDISK_JOURNAL_SIZE(s);
+		tbh = journal_find_get_block(s, bn);
+		if (buffer_dirty(tbh))	/* redundant, ll_rw_block() checks */
+			ll_rw_block(WRITE, 1, &tbh);
+		put_bh(tbh);
+	}
+	atomic_dec(&journal->j_async_throttle);
+
+	/* wait on everything written so far before writing the commit
+	 * if we are in barrier mode, send the commit down now
+	 */
+	barrier = reiserfs_barrier_flush(s);
+	if (barrier) {
+		int ret;
+		lock_buffer(jl->j_commit_bh);
+		ret = submit_barrier_buffer(jl->j_commit_bh);
+		if (ret == -EOPNOTSUPP) {
+			set_buffer_uptodate(jl->j_commit_bh);
+			disable_barrier(s);
+			barrier = 0;
+		}
+	}
+	for (i = 0; i < (jl->j_len + 1); i++) {
+		bn = SB_ONDISK_JOURNAL_1st_BLOCK(s) +
+		    (jl->j_start + i) % SB_ONDISK_JOURNAL_SIZE(s);
+		tbh = journal_find_get_block(s, bn);
+		wait_on_buffer(tbh);
+		// since we're using ll_rw_blk above, it might have skipped over
+		// a locked buffer.  Double check here
+		//
+		if (buffer_dirty(tbh))	/* redundant, sync_dirty_buffer() checks */
+			sync_dirty_buffer(tbh);
+		if (unlikely(!buffer_uptodate(tbh))) {
 #ifdef CONFIG_REISERFS_CHECK
-      reiserfs_warning(s, "journal-601, buffer write failed") ;
+			reiserfs_warning(s, "journal-601, buffer write failed");
 #endif
-      retval = -EIO;
-    }
-    put_bh(tbh) ; /* once for journal_find_get_block */
-    put_bh(tbh) ;    /* once due to original getblk in do_journal_end */
-    atomic_dec(&(jl->j_commit_left)) ;
-  }
-
-  BUG_ON (atomic_read(&(jl->j_commit_left)) != 1);
-
-  if (!barrier) {
-      if (buffer_dirty(jl->j_commit_bh))
-	BUG();
-      mark_buffer_dirty(jl->j_commit_bh) ;
-      sync_dirty_buffer(jl->j_commit_bh) ;
-  } else
-      wait_on_buffer(jl->j_commit_bh);
-
-  check_barrier_completion(s, jl->j_commit_bh);
-
-  /* If there was a write error in the journal - we can't commit this
-   * transaction - it will be invalid and, if successful, will just end
-   * up propogating the write error out to the filesystem. */
-  if (unlikely (!buffer_uptodate(jl->j_commit_bh))) {
+			retval = -EIO;
+		}
+		put_bh(tbh);	/* once for journal_find_get_block */
+		put_bh(tbh);	/* once due to original getblk in do_journal_end */
+		atomic_dec(&(jl->j_commit_left));
+	}
+
+	BUG_ON(atomic_read(&(jl->j_commit_left)) != 1);
+
+	if (!barrier) {
+		if (buffer_dirty(jl->j_commit_bh))
+			BUG();
+		mark_buffer_dirty(jl->j_commit_bh);
+		sync_dirty_buffer(jl->j_commit_bh);
+	} else
+		wait_on_buffer(jl->j_commit_bh);
+
+	check_barrier_completion(s, jl->j_commit_bh);
+
+	/* If there was a write error in the journal - we can't commit this
+	 * transaction - it will be invalid and, if successful, will just end
+	 * up propogating the write error out to the filesystem. */
+	if (unlikely(!buffer_uptodate(jl->j_commit_bh))) {
 #ifdef CONFIG_REISERFS_CHECK
-    reiserfs_warning(s, "journal-615: buffer write failed") ;
+		reiserfs_warning(s, "journal-615: buffer write failed");
 #endif
-    retval = -EIO;
-  }
-  bforget(jl->j_commit_bh) ;
-  if (journal->j_last_commit_id != 0 &&
-     (jl->j_trans_id - journal->j_last_commit_id) != 1) {
-      reiserfs_warning(s, "clm-2200: last commit %lu, current %lu",
-                       journal->j_last_commit_id,
-		       jl->j_trans_id);
-  }
-  journal->j_last_commit_id = jl->j_trans_id;
-
-  /* now, every commit block is on the disk.  It is safe to allow blocks freed during this transaction to be reallocated */
-  cleanup_freed_for_journal_list(s, jl) ;
-
-  retval = retval ? retval : journal->j_errno;
-
-  /* mark the metadata dirty */
-  if (!retval)
-    dirty_one_transaction(s, jl);
-  atomic_dec(&(jl->j_commit_left)) ;
-
-  if (flushall) {
-    atomic_set(&(jl->j_older_commits_done), 1) ;
-  }
-  up(&jl->j_commit_lock);
-put_jl:
-  put_journal_list(s, jl);
-
-  if (retval)
-    reiserfs_abort (s, retval, "Journal write error in %s", __FUNCTION__);
-  return retval;
+		retval = -EIO;
+	}
+	bforget(jl->j_commit_bh);
+	if (journal->j_last_commit_id != 0 &&
+	    (jl->j_trans_id - journal->j_last_commit_id) != 1) {
+		reiserfs_warning(s, "clm-2200: last commit %lu, current %lu",
+				 journal->j_last_commit_id, jl->j_trans_id);
+	}
+	journal->j_last_commit_id = jl->j_trans_id;
+
+	/* now, every commit block is on the disk.  It is safe to allow blocks freed during this transaction to be reallocated */
+	cleanup_freed_for_journal_list(s, jl);
+
+	retval = retval ? retval : journal->j_errno;
+
+	/* mark the metadata dirty */
+	if (!retval)
+		dirty_one_transaction(s, jl);
+	atomic_dec(&(jl->j_commit_left));
+
+	if (flushall) {
+		atomic_set(&(jl->j_older_commits_done), 1);
+	}
+	up(&jl->j_commit_lock);
+      put_jl:
+	put_journal_list(s, jl);
+
+	if (retval)
+		reiserfs_abort(s, retval, "Journal write error in %s",
+			       __FUNCTION__);
+	put_fs_excl();
+	return retval;
 }
 
 /*
 ** flush_journal_list frequently needs to find a newer transaction for a given block.  This does that, or 
 ** returns NULL if it can't find anything 
 */
-static struct reiserfs_journal_list *find_newer_jl_for_cn(struct reiserfs_journal_cnode *cn) {
-  struct super_block *sb = cn->sb;
-  b_blocknr_t blocknr = cn->blocknr ;
-
-  cn = cn->hprev ;
-  while(cn) {
-    if (cn->sb == sb && cn->blocknr == blocknr && cn->jlist) {
-      return cn->jlist ;
-    }
-    cn = cn->hprev ;
-  }
-  return NULL ;
+static struct reiserfs_journal_list *find_newer_jl_for_cn(struct
+							  reiserfs_journal_cnode
+							  *cn)
+{
+	struct super_block *sb = cn->sb;
+	b_blocknr_t blocknr = cn->blocknr;
+
+	cn = cn->hprev;
+	while (cn) {
+		if (cn->sb == sb && cn->blocknr == blocknr && cn->jlist) {
+			return cn->jlist;
+		}
+		cn = cn->hprev;
+	}
+	return NULL;
 }
 
-static void remove_journal_hash(struct super_block *, struct reiserfs_journal_cnode **,
-struct reiserfs_journal_list *, unsigned long, int);
+static void remove_journal_hash(struct super_block *,
+				struct reiserfs_journal_cnode **,
+				struct reiserfs_journal_list *, unsigned long,
+				int);
 
 /*
 ** once all the real blocks have been flushed, it is safe to remove them from the
 ** journal list for this transaction.  Aside from freeing the cnode, this also allows the
 ** block to be reallocated for data blocks if it had been deleted.
 */
-static void remove_all_from_journal_list(struct super_block *p_s_sb, struct reiserfs_journal_list *jl, int debug) {
-  struct reiserfs_journal *journal = SB_JOURNAL (p_s_sb);
-  struct reiserfs_journal_cnode *cn, *last ;
-  cn = jl->j_realblock ;
-
-  /* which is better, to lock once around the whole loop, or
-  ** to lock for each call to remove_journal_hash?
-  */
-  while(cn) {
-    if (cn->blocknr != 0) {
-      if (debug) {
-       reiserfs_warning (p_s_sb, "block %u, bh is %d, state %ld", cn->blocknr,
-                         cn->bh ? 1: 0, cn->state) ;
-      }
-      cn->state = 0 ;
-      remove_journal_hash(p_s_sb, journal->j_list_hash_table, jl, cn->blocknr, 1) ;
-    }
-    last = cn ;
-    cn = cn->next ;
-    free_cnode(p_s_sb, last) ;
-  }
-  jl->j_realblock = NULL ;
+static void remove_all_from_journal_list(struct super_block *p_s_sb,
+					 struct reiserfs_journal_list *jl,
+					 int debug)
+{
+	struct reiserfs_journal *journal = SB_JOURNAL(p_s_sb);
+	struct reiserfs_journal_cnode *cn, *last;
+	cn = jl->j_realblock;
+
+	/* which is better, to lock once around the whole loop, or
+	 ** to lock for each call to remove_journal_hash?
+	 */
+	while (cn) {
+		if (cn->blocknr != 0) {
+			if (debug) {
+				reiserfs_warning(p_s_sb,
+						 "block %u, bh is %d, state %ld",
+						 cn->blocknr, cn->bh ? 1 : 0,
+						 cn->state);
+			}
+			cn->state = 0;
+			remove_journal_hash(p_s_sb, journal->j_list_hash_table,
+					    jl, cn->blocknr, 1);
+		}
+		last = cn;
+		cn = cn->next;
+		free_cnode(p_s_sb, last);
+	}
+	jl->j_realblock = NULL;
 }
 
 /*
@@ -1115,98 +1195,107 @@ static void remove_all_from_journal_list
 ** called by flush_journal_list, before it calls remove_all_from_journal_list
 **
 */
-static int _update_journal_header_block(struct super_block *p_s_sb, unsigned long offset, unsigned long trans_id) {
-  struct reiserfs_journal_header *jh ;
-  struct reiserfs_journal *journal = SB_JOURNAL (p_s_sb);
-
-  if (reiserfs_is_journal_aborted (journal))
-    return -EIO;
-
-  if (trans_id >= journal->j_last_flush_trans_id) {
-    if (buffer_locked((journal->j_header_bh)))  {
-      wait_on_buffer((journal->j_header_bh)) ;
-      if (unlikely (!buffer_uptodate(journal->j_header_bh))) {
+static int _update_journal_header_block(struct super_block *p_s_sb,
+					unsigned long offset,
+					unsigned long trans_id)
+{
+	struct reiserfs_journal_header *jh;
+	struct reiserfs_journal *journal = SB_JOURNAL(p_s_sb);
+
+	if (reiserfs_is_journal_aborted(journal))
+		return -EIO;
+
+	if (trans_id >= journal->j_last_flush_trans_id) {
+		if (buffer_locked((journal->j_header_bh))) {
+			wait_on_buffer((journal->j_header_bh));
+			if (unlikely(!buffer_uptodate(journal->j_header_bh))) {
 #ifdef CONFIG_REISERFS_CHECK
-        reiserfs_warning (p_s_sb, "journal-699: buffer write failed") ;
+				reiserfs_warning(p_s_sb,
+						 "journal-699: buffer write failed");
 #endif
-        return -EIO;
-      }
-    }
-    journal->j_last_flush_trans_id = trans_id ;
-    journal->j_first_unflushed_offset = offset ;
-    jh = (struct reiserfs_journal_header *)(journal->j_header_bh->b_data) ;
-    jh->j_last_flush_trans_id = cpu_to_le32(trans_id) ;
-    jh->j_first_unflushed_offset = cpu_to_le32(offset) ;
-    jh->j_mount_id = cpu_to_le32(journal->j_mount_id) ;
+				return -EIO;
+			}
+		}
+		journal->j_last_flush_trans_id = trans_id;
+		journal->j_first_unflushed_offset = offset;
+		jh = (struct reiserfs_journal_header *)(journal->j_header_bh->
+							b_data);
+		jh->j_last_flush_trans_id = cpu_to_le32(trans_id);
+		jh->j_first_unflushed_offset = cpu_to_le32(offset);
+		jh->j_mount_id = cpu_to_le32(journal->j_mount_id);
+
+		if (reiserfs_barrier_flush(p_s_sb)) {
+			int ret;
+			lock_buffer(journal->j_header_bh);
+			ret = submit_barrier_buffer(journal->j_header_bh);
+			if (ret == -EOPNOTSUPP) {
+				set_buffer_uptodate(journal->j_header_bh);
+				disable_barrier(p_s_sb);
+				goto sync;
+			}
+			wait_on_buffer(journal->j_header_bh);
+			check_barrier_completion(p_s_sb, journal->j_header_bh);
+		} else {
+		      sync:
+			set_buffer_dirty(journal->j_header_bh);
+			sync_dirty_buffer(journal->j_header_bh);
+		}
+		if (!buffer_uptodate(journal->j_header_bh)) {
+			reiserfs_warning(p_s_sb,
+					 "journal-837: IO error during journal replay");
+			return -EIO;
+		}
+	}
+	return 0;
+}
 
-    if (reiserfs_barrier_flush(p_s_sb)) {
-	int ret;
-	lock_buffer(journal->j_header_bh);
-	ret = submit_barrier_buffer(journal->j_header_bh);
-	if (ret == -EOPNOTSUPP) {
-	    set_buffer_uptodate(journal->j_header_bh);
-	    disable_barrier(p_s_sb);
-	    goto sync;
-	}
-	wait_on_buffer(journal->j_header_bh);
-	check_barrier_completion(p_s_sb, journal->j_header_bh);
-    } else {
-sync:
-	set_buffer_dirty(journal->j_header_bh) ;
-	sync_dirty_buffer(journal->j_header_bh) ;
-    }
-    if (!buffer_uptodate(journal->j_header_bh)) {
-      reiserfs_warning (p_s_sb, "journal-837: IO error during journal replay");
-      return -EIO ;
-    }
-  }
-  return 0 ;
-}
-
-static int update_journal_header_block(struct super_block *p_s_sb, 
-                                       unsigned long offset, 
-				       unsigned long trans_id) {
-    return _update_journal_header_block(p_s_sb, offset, trans_id);
+static int update_journal_header_block(struct super_block *p_s_sb,
+				       unsigned long offset,
+				       unsigned long trans_id)
+{
+	return _update_journal_header_block(p_s_sb, offset, trans_id);
 }
+
 /* 
 ** flush any and all journal lists older than you are 
 ** can only be called from flush_journal_list
 */
 static int flush_older_journal_lists(struct super_block *p_s_sb,
-                                     struct reiserfs_journal_list *jl)
+				     struct reiserfs_journal_list *jl)
 {
-    struct list_head *entry;
-    struct reiserfs_journal_list *other_jl ;
-    struct reiserfs_journal *journal = SB_JOURNAL (p_s_sb);
-    unsigned long trans_id = jl->j_trans_id;
-
-    /* we know we are the only ones flushing things, no extra race
-     * protection is required.
-     */
-restart:
-    entry = journal->j_journal_list.next;
-    /* Did we wrap? */
-    if (entry == &journal->j_journal_list)
-        return 0;
-    other_jl = JOURNAL_LIST_ENTRY(entry);
-    if (other_jl->j_trans_id < trans_id) {
-        BUG_ON (other_jl->j_refcount <= 0);
-	/* do not flush all */
-	flush_journal_list(p_s_sb, other_jl, 0) ;
-
-	/* other_jl is now deleted from the list */
-	goto restart;
-    }
-    return 0 ;
+	struct list_head *entry;
+	struct reiserfs_journal_list *other_jl;
+	struct reiserfs_journal *journal = SB_JOURNAL(p_s_sb);
+	unsigned long trans_id = jl->j_trans_id;
+
+	/* we know we are the only ones flushing things, no extra race
+	 * protection is required.
+	 */
+      restart:
+	entry = journal->j_journal_list.next;
+	/* Did we wrap? */
+	if (entry == &journal->j_journal_list)
+		return 0;
+	other_jl = JOURNAL_LIST_ENTRY(entry);
+	if (other_jl->j_trans_id < trans_id) {
+		BUG_ON(other_jl->j_refcount <= 0);
+		/* do not flush all */
+		flush_journal_list(p_s_sb, other_jl, 0);
+
+		/* other_jl is now deleted from the list */
+		goto restart;
+	}
+	return 0;
 }
 
 static void del_from_work_list(struct super_block *s,
-                               struct reiserfs_journal_list *jl) {
-    struct reiserfs_journal *journal = SB_JOURNAL (s);
-    if (!list_empty(&jl->j_working_list)) {
-	list_del_init(&jl->j_working_list);
-	journal->j_num_work_lists--;
-    }
+			       struct reiserfs_journal_list *jl)
+{
+	struct reiserfs_journal *journal = SB_JOURNAL(s);
+	if (!list_empty(&jl->j_working_list)) {
+		list_del_init(&jl->j_working_list);
+		journal->j_num_work_lists--;
+	}
 }
 
 /* flush a journal list, both commit and real blocks
@@ -1218,644 +1307,710 @@ static void del_from_work_list(struct su
 ** and the journal is locked.  That means it can only be called from 
 ** do_journal_end, or by journal_release
 */
-static int flush_journal_list(struct super_block *s, 
-                              struct reiserfs_journal_list *jl, int flushall) {
-  struct reiserfs_journal_list *pjl ;
-  struct reiserfs_journal_cnode *cn, *last ;
-  int count ;
-  int was_jwait = 0 ;
-  int was_dirty = 0 ;
-  struct buffer_head *saved_bh ; 
-  unsigned long j_len_saved = jl->j_len ;
-  struct reiserfs_journal *journal = SB_JOURNAL (s);
-  int err = 0;
-
-  BUG_ON (j_len_saved <= 0);
-
-  if (atomic_read(&journal->j_wcount) != 0) {
-    reiserfs_warning(s, "clm-2048: flush_journal_list called with wcount %d",
-                      atomic_read(&journal->j_wcount)) ;
-  }
-  BUG_ON (jl->j_trans_id == 0);
-
-  /* if flushall == 0, the lock is already held */
-  if (flushall) {
-      down(&journal->j_flush_sem);
-  } else if (!down_trylock(&journal->j_flush_sem)) {
-      BUG();
-  }
-
-  count = 0 ;
-  if (j_len_saved > journal->j_trans_max) {
-    reiserfs_panic(s, "journal-715: flush_journal_list, length is %lu, trans id %lu\n", j_len_saved, jl->j_trans_id);
-    return 0 ;
-  }
-
-  /* if all the work is already done, get out of here */
-  if (atomic_read(&(jl->j_nonzerolen)) <= 0 && 
-      atomic_read(&(jl->j_commit_left)) <= 0) {
-    goto flush_older_and_return ;
-  } 
-
-  /* start by putting the commit list on disk.  This will also flush 
-  ** the commit lists of any olders transactions
-  */
-  flush_commit_list(s, jl, 1) ;
-
-  if (!(jl->j_state & LIST_DIRTY) && !reiserfs_is_journal_aborted (journal))
-      BUG();
-
-  /* are we done now? */
-  if (atomic_read(&(jl->j_nonzerolen)) <= 0 && 
-      atomic_read(&(jl->j_commit_left)) <= 0) {
-    goto flush_older_and_return ;
-  }
-
-  /* loop through each cnode, see if we need to write it, 
-  ** or wait on a more recent transaction, or just ignore it 
-  */
-  if (atomic_read(&(journal->j_wcount)) != 0) {
-    reiserfs_panic(s, "journal-844: panic journal list is flushing, wcount is not 0\n") ;
-  }
-  cn = jl->j_realblock ;
-  while(cn) {
-    was_jwait = 0 ;
-    was_dirty = 0 ;
-    saved_bh = NULL ;
-    /* blocknr of 0 is no longer in the hash, ignore it */
-    if (cn->blocknr == 0) {
-      goto free_cnode ;
-    }
-
-    /* This transaction failed commit. Don't write out to the disk */
-    if (!(jl->j_state & LIST_DIRTY))
-        goto free_cnode;
-
-    pjl = find_newer_jl_for_cn(cn) ;
-    /* the order is important here.  We check pjl to make sure we
-    ** don't clear BH_JDirty_wait if we aren't the one writing this
-    ** block to disk
-    */
-    if (!pjl && cn->bh) {
-      saved_bh = cn->bh ;
-
-      /* we do this to make sure nobody releases the buffer while 
-      ** we are working with it 
-      */
-      get_bh(saved_bh) ;
-
-      if (buffer_journal_dirty(saved_bh)) {
-        BUG_ON (!can_dirty (cn));
-        was_jwait = 1 ;
-        was_dirty = 1 ;
-      } else if (can_dirty(cn)) {
-        /* everything with !pjl && jwait should be writable */
-	BUG();
-      }
-    }
-
-    /* if someone has this block in a newer transaction, just make
-    ** sure they are commited, and don't try writing it to disk
-    */
-    if (pjl) {
-      if (atomic_read(&pjl->j_commit_left))
-        flush_commit_list(s, pjl, 1) ;
-      goto free_cnode ;
-    }
-
-    /* bh == NULL when the block got to disk on its own, OR, 
-    ** the block got freed in a future transaction 
-    */
-    if (saved_bh == NULL) {
-      goto free_cnode ;
-    }
-
-    /* this should never happen.  kupdate_one_transaction has this list
-    ** locked while it works, so we should never see a buffer here that
-    ** is not marked JDirty_wait
-    */
-    if ((!was_jwait) && !buffer_locked(saved_bh)) {
-	reiserfs_warning (s, "journal-813: BAD! buffer %llu %cdirty %cjwait, "
-			  "not in a newer tranasction",
-			  (unsigned long long)saved_bh->b_blocknr,
-			  was_dirty ? ' ' : '!', was_jwait ? ' ' : '!') ;
-    }
-    if (was_dirty) { 
-      /* we inc again because saved_bh gets decremented at free_cnode */
-      get_bh(saved_bh) ;
-      set_bit(BLOCK_NEEDS_FLUSH, &cn->state) ;
-      lock_buffer(saved_bh);
-      BUG_ON (cn->blocknr != saved_bh->b_blocknr);
-      if (buffer_dirty(saved_bh))
-        submit_logged_buffer(saved_bh) ;
-      else
-        unlock_buffer(saved_bh);
-      count++ ;
-    } else {
-      reiserfs_warning (s, "clm-2082: Unable to flush buffer %llu in %s",
-                        (unsigned long long)saved_bh->b_blocknr, __FUNCTION__);
-    }
-free_cnode:
-    last = cn ;
-    cn = cn->next ;
-    if (saved_bh) {
-      /* we incremented this to keep others from taking the buffer head away */
-      put_bh(saved_bh) ;
-      if (atomic_read(&(saved_bh->b_count)) < 0) {
-        reiserfs_warning (s, "journal-945: saved_bh->b_count < 0");
-      }
-    }
-  }
-  if (count > 0) {
-    cn = jl->j_realblock ;
-    while(cn) {
-      if (test_bit(BLOCK_NEEDS_FLUSH, &cn->state)) {
-	if (!cn->bh) {
-	  reiserfs_panic(s, "journal-1011: cn->bh is NULL\n") ;
-	}
-	wait_on_buffer(cn->bh) ;
-	if (!cn->bh) {
-	  reiserfs_panic(s, "journal-1012: cn->bh is NULL\n") ;
+static int flush_journal_list(struct super_block *s,
+			      struct reiserfs_journal_list *jl, int flushall)
+{
+	struct reiserfs_journal_list *pjl;
+	struct reiserfs_journal_cnode *cn, *last;
+	int count;
+	int was_jwait = 0;
+	int was_dirty = 0;
+	struct buffer_head *saved_bh;
+	unsigned long j_len_saved = jl->j_len;
+	struct reiserfs_journal *journal = SB_JOURNAL(s);
+	int err = 0;
+
+	BUG_ON(j_len_saved <= 0);
+
+	if (atomic_read(&journal->j_wcount) != 0) {
+		reiserfs_warning(s,
+				 "clm-2048: flush_journal_list called with wcount %d",
+				 atomic_read(&journal->j_wcount));
 	}
-	if (unlikely (!buffer_uptodate(cn->bh))) {
-#ifdef CONFIG_REISERFS_CHECK
-	  reiserfs_warning(s, "journal-949: buffer write failed\n") ;
-#endif
-          err = -EIO;
-  	}
-	/* note, we must clear the JDirty_wait bit after the up to date
-	** check, otherwise we race against our flushpage routine
-	*/
-        BUG_ON (!test_clear_buffer_journal_dirty (cn->bh));
-
-        /* undo the inc from journal_mark_dirty */
-	put_bh(cn->bh) ;
-        brelse(cn->bh) ;
-      }
-      cn = cn->next ;
-    }
-  }
-
-  if (err)
-    reiserfs_abort (s, -EIO, "Write error while pushing transaction to disk in %s", __FUNCTION__);
-flush_older_and_return:
-
-
-  /* before we can update the journal header block, we _must_ flush all 
-  ** real blocks from all older transactions to disk.  This is because
-  ** once the header block is updated, this transaction will not be
-  ** replayed after a crash
-  */
-  if (flushall) {
-    flush_older_journal_lists(s, jl);
-  } 
-  
-  err = journal->j_errno;
-  /* before we can remove everything from the hash tables for this 
-  ** transaction, we must make sure it can never be replayed
-  **
-  ** since we are only called from do_journal_end, we know for sure there
-  ** are no allocations going on while we are flushing journal lists.  So,
-  ** we only need to update the journal header block for the last list
-  ** being flushed
-  */
-  if (!err && flushall) {
-    err = update_journal_header_block(s, (jl->j_start + jl->j_len + 2) % SB_ONDISK_JOURNAL_SIZE(s), jl->j_trans_id) ;
-    if (err)
-        reiserfs_abort (s, -EIO, "Write error while updating journal header in %s", __FUNCTION__);
-  }
-  remove_all_from_journal_list(s, jl, 0) ;
-  list_del_init(&jl->j_list);
-  journal->j_num_lists--;
-  del_from_work_list(s, jl);
-
-  if (journal->j_last_flush_id != 0 &&
-     (jl->j_trans_id - journal->j_last_flush_id) != 1) {
-      reiserfs_warning(s, "clm-2201: last flush %lu, current %lu",
-                       journal->j_last_flush_id,
-		       jl->j_trans_id);
-  }
-  journal->j_last_flush_id = jl->j_trans_id;
-
-  /* not strictly required since we are freeing the list, but it should
-   * help find code using dead lists later on
-   */
-  jl->j_len = 0 ;
-  atomic_set(&(jl->j_nonzerolen), 0) ;
-  jl->j_start = 0 ;
-  jl->j_realblock = NULL ;
-  jl->j_commit_bh = NULL ;
-  jl->j_trans_id = 0 ;
-  jl->j_state = 0;
-  put_journal_list(s, jl);
-  if (flushall)
-    up(&journal->j_flush_sem);
-  return err ;
-} 
+	BUG_ON(jl->j_trans_id == 0);
 
-static int write_one_transaction(struct super_block *s,
-                                 struct reiserfs_journal_list *jl,
-				 struct buffer_chunk *chunk)
-{
-    struct reiserfs_journal_cnode *cn;
-    int ret = 0 ;
+	/* if flushall == 0, the lock is already held */
+	if (flushall) {
+		down(&journal->j_flush_sem);
+	} else if (!down_trylock(&journal->j_flush_sem)) {
+		BUG();
+	}
 
-    jl->j_state |= LIST_TOUCHED;
-    del_from_work_list(s, jl);
-    if (jl->j_len == 0 || atomic_read(&jl->j_nonzerolen) == 0) {
-        return 0;
-    }
-
-    cn = jl->j_realblock ;
-    while(cn) {
-        /* if the blocknr == 0, this has been cleared from the hash,
-        ** skip it
-        */
-        if (cn->blocknr == 0) {
-            goto next ;
-        }
-        if (cn->bh && can_dirty(cn) && buffer_dirty(cn->bh)) {
-	    struct buffer_head *tmp_bh;
-	    /* we can race against journal_mark_freed when we try
-	     * to lock_buffer(cn->bh), so we have to inc the buffer
-	     * count, and recheck things after locking
-	     */
-	    tmp_bh = cn->bh;
-	    get_bh(tmp_bh);
-	    lock_buffer(tmp_bh);
-	    if (cn->bh && can_dirty(cn) && buffer_dirty(tmp_bh)) {
-		if (!buffer_journal_dirty(tmp_bh) ||
-		    buffer_journal_prepared(tmp_bh))
-		    BUG();
-		add_to_chunk(chunk, tmp_bh, NULL, write_chunk);
-		ret++;
-	    } else {
-		/* note, cn->bh might be null now */
-		unlock_buffer(tmp_bh);
-	    }
-	    put_bh(tmp_bh);
-        }
-next:
-        cn = cn->next ;
-	cond_resched();
-    }
-    return ret ;
-}
+	count = 0;
+	if (j_len_saved > journal->j_trans_max) {
+		reiserfs_panic(s,
+			       "journal-715: flush_journal_list, length is %lu, trans id %lu\n",
+			       j_len_saved, jl->j_trans_id);
+		return 0;
+	}
 
-/* used by flush_commit_list */
-static int dirty_one_transaction(struct super_block *s,
-                                 struct reiserfs_journal_list *jl)
-{
-    struct reiserfs_journal_cnode *cn;
-    struct reiserfs_journal_list *pjl;
-    int ret = 0 ;
-
-    jl->j_state |= LIST_DIRTY;
-    cn = jl->j_realblock ;
-    while(cn) {
-        /* look for a more recent transaction that logged this
-        ** buffer.  Only the most recent transaction with a buffer in
-        ** it is allowed to send that buffer to disk
-        */
-	pjl = find_newer_jl_for_cn(cn) ;
-        if (!pjl && cn->blocknr && cn->bh && buffer_journal_dirty(cn->bh))
-	{
-	    BUG_ON (!can_dirty(cn));
-	    /* if the buffer is prepared, it will either be logged
-	     * or restored.  If restored, we need to make sure
-	     * it actually gets marked dirty
-	     */
-            clear_buffer_journal_new (cn->bh);
-            if (buffer_journal_prepared (cn->bh)) {
-                set_buffer_journal_restore_dirty (cn->bh);
-	    } else {
-                set_buffer_journal_test (cn->bh);
-	        mark_buffer_dirty(cn->bh);
-	    }
-        } 
-        cn = cn->next ;
-    }
-    return ret ;
-}
+	get_fs_excl();
 
-static int kupdate_transactions(struct super_block *s,
-                                   struct reiserfs_journal_list *jl,
-				   struct reiserfs_journal_list **next_jl,
-				   unsigned long *next_trans_id,
-				   int num_blocks,
-				   int num_trans) {
-    int ret = 0;
-    int written = 0 ;
-    int transactions_flushed = 0;
-    unsigned long orig_trans_id = jl->j_trans_id;
-    struct buffer_chunk chunk;
-    struct list_head *entry;
-    struct reiserfs_journal *journal = SB_JOURNAL (s);
-    chunk.nr = 0;
-
-    down(&journal->j_flush_sem);
-    if (!journal_list_still_alive(s, orig_trans_id)) {
-	goto done;
-    }
-
-    /* we've got j_flush_sem held, nobody is going to delete any
-     * of these lists out from underneath us
-     */
-    while((num_trans && transactions_flushed < num_trans) ||
-          (!num_trans && written < num_blocks)) {
-
-	if (jl->j_len == 0 || (jl->j_state & LIST_TOUCHED) ||
-	    atomic_read(&jl->j_commit_left) || !(jl->j_state & LIST_DIRTY))
-	{
-	    del_from_work_list(s, jl);
-	    break;
-	}
-	ret = write_one_transaction(s, jl, &chunk);
-
-	if (ret < 0)
-	    goto done;
-	transactions_flushed++;
-	written += ret;
-	entry = jl->j_list.next;
-
-	/* did we wrap? */
-	if (entry == &journal->j_journal_list) {
-	    break;
-        }
-	jl = JOURNAL_LIST_ENTRY(entry);
-
-	/* don't bother with older transactions */
-	if (jl->j_trans_id <= orig_trans_id)
-	    break;
-    }
-    if (chunk.nr) {
-        write_chunk(&chunk);
-    }
-
-done:
-    up(&journal->j_flush_sem);
-    return ret;
-}
+	/* if all the work is already done, get out of here */
+	if (atomic_read(&(jl->j_nonzerolen)) <= 0 &&
+	    atomic_read(&(jl->j_commit_left)) <= 0) {
+		goto flush_older_and_return;
+	}
 
-/* for o_sync and fsync heavy applications, they tend to use
-** all the journa list slots with tiny transactions.  These
-** trigger lots and lots of calls to update the header block, which
-** adds seeks and slows things down.
-**
-** This function tries to clear out a large chunk of the journal lists
-** at once, which makes everything faster since only the newest journal
-** list updates the header block
-*/
-static int flush_used_journal_lists(struct super_block *s,
-                                    struct reiserfs_journal_list *jl) {
-    unsigned long len = 0;
-    unsigned long cur_len;
-    int ret;
-    int i;
-    int limit = 256;
-    struct reiserfs_journal_list *tjl;
-    struct reiserfs_journal_list *flush_jl;
-    unsigned long trans_id;
-    struct reiserfs_journal *journal = SB_JOURNAL (s);
-
-    flush_jl = tjl = jl;
-
-    /* in data logging mode, try harder to flush a lot of blocks */
-    if (reiserfs_data_log(s))
-	limit = 1024;
-    /* flush for 256 transactions or limit blocks, whichever comes first */
-    for(i = 0 ; i < 256 && len < limit ; i++) {
-	if (atomic_read(&tjl->j_commit_left) ||
-	    tjl->j_trans_id < jl->j_trans_id) {
-	    break;
-	}
-	cur_len = atomic_read(&tjl->j_nonzerolen);
-	if (cur_len > 0) {
-	    tjl->j_state &= ~LIST_TOUCHED;
-	}
-	len += cur_len;
-	flush_jl = tjl;
-	if (tjl->j_list.next == &journal->j_journal_list)
-	    break;
-	tjl = JOURNAL_LIST_ENTRY(tjl->j_list.next);
-    }
-    /* try to find a group of blocks we can flush across all the
-    ** transactions, but only bother if we've actually spanned
-    ** across multiple lists
-    */
-    if (flush_jl != jl) {
-        ret = kupdate_transactions(s, jl, &tjl, &trans_id, len, i);
-    }
-    flush_journal_list(s, flush_jl, 1);
-    return 0;
-}
+	/* start by putting the commit list on disk.  This will also flush 
+	 ** the commit lists of any olders transactions
+	 */
+	flush_commit_list(s, jl, 1);
+
+	if (!(jl->j_state & LIST_DIRTY)
+	    && !reiserfs_is_journal_aborted(journal))
+		BUG();
+
+	/* are we done now? */
+	if (atomic_read(&(jl->j_nonzerolen)) <= 0 &&
+	    atomic_read(&(jl->j_commit_left)) <= 0) {
+		goto flush_older_and_return;
+	}
+
+	/* loop through each cnode, see if we need to write it, 
+	 ** or wait on a more recent transaction, or just ignore it 
+	 */
+	if (atomic_read(&(journal->j_wcount)) != 0) {
+		reiserfs_panic(s,
+			       "journal-844: panic journal list is flushing, wcount is not 0\n");
+	}
+	cn = jl->j_realblock;
+	while (cn) {
+		was_jwait = 0;
+		was_dirty = 0;
+		saved_bh = NULL;
+		/* blocknr of 0 is no longer in the hash, ignore it */
+		if (cn->blocknr == 0) {
+			goto free_cnode;
+		}
+
+		/* This transaction failed commit. Don't write out to the disk */
+		if (!(jl->j_state & LIST_DIRTY))
+			goto free_cnode;
+
+		pjl = find_newer_jl_for_cn(cn);
+		/* the order is important here.  We check pjl to make sure we
+		 ** don't clear BH_JDirty_wait if we aren't the one writing this
+		 ** block to disk
+		 */
+		if (!pjl && cn->bh) {
+			saved_bh = cn->bh;
+
+			/* we do this to make sure nobody releases the buffer while 
+			 ** we are working with it 
+			 */
+			get_bh(saved_bh);
+
+			if (buffer_journal_dirty(saved_bh)) {
+				BUG_ON(!can_dirty(cn));
+				was_jwait = 1;
+				was_dirty = 1;
+			} else if (can_dirty(cn)) {
+				/* everything with !pjl && jwait should be writable */
+				BUG();
+			}
+		}
+
+		/* if someone has this block in a newer transaction, just make
+		 ** sure they are commited, and don't try writing it to disk
+		 */
+		if (pjl) {
+			if (atomic_read(&pjl->j_commit_left))
+				flush_commit_list(s, pjl, 1);
+			goto free_cnode;
+		}
+
+		/* bh == NULL when the block got to disk on its own, OR, 
+		 ** the block got freed in a future transaction 
+		 */
+		if (saved_bh == NULL) {
+			goto free_cnode;
+		}
+
+		/* this should never happen.  kupdate_one_transaction has this list
+		 ** locked while it works, so we should never see a buffer here that
+		 ** is not marked JDirty_wait
+		 */
+		if ((!was_jwait) && !buffer_locked(saved_bh)) {
+			reiserfs_warning(s,
+					 "journal-813: BAD! buffer %llu %cdirty %cjwait, "
+					 "not in a newer tranasction",
+					 (unsigned long long)saved_bh->
+					 b_blocknr, was_dirty ? ' ' : '!',
+					 was_jwait ? ' ' : '!');
+		}
+		if (was_dirty) {
+			/* we inc again because saved_bh gets decremented at free_cnode */
+			get_bh(saved_bh);
+			set_bit(BLOCK_NEEDS_FLUSH, &cn->state);
+			lock_buffer(saved_bh);
+			BUG_ON(cn->blocknr != saved_bh->b_blocknr);
+			if (buffer_dirty(saved_bh))
+				submit_logged_buffer(saved_bh);
+			else
+				unlock_buffer(saved_bh);
+			count++;
+		} else {
+			reiserfs_warning(s,
+					 "clm-2082: Unable to flush buffer %llu in %s",
+					 (unsigned long long)saved_bh->
+					 b_blocknr, __FUNCTION__);
+		}
+	      free_cnode:
+		last = cn;
+		cn = cn->next;
+		if (saved_bh) {
+			/* we incremented this to keep others from taking the buffer head away */
+			put_bh(saved_bh);
+			if (atomic_read(&(saved_bh->b_count)) < 0) {
+				reiserfs_warning(s,
+						 "journal-945: saved_bh->b_count < 0");
+			}
+		}
+	}
+	if (count > 0) {
+		cn = jl->j_realblock;
+		while (cn) {
+			if (test_bit(BLOCK_NEEDS_FLUSH, &cn->state)) {
+				if (!cn->bh) {
+					reiserfs_panic(s,
+						       "journal-1011: cn->bh is NULL\n");
+				}
+				wait_on_buffer(cn->bh);
+				if (!cn->bh) {
+					reiserfs_panic(s,
+						       "journal-1012: cn->bh is NULL\n");
+				}
+				if (unlikely(!buffer_uptodate(cn->bh))) {
+#ifdef CONFIG_REISERFS_CHECK
+					reiserfs_warning(s,
+							 "journal-949: buffer write failed\n");
+#endif
+					err = -EIO;
+				}
+				/* note, we must clear the JDirty_wait bit after the up to date
+				 ** check, otherwise we race against our flushpage routine
+				 */
+				BUG_ON(!test_clear_buffer_journal_dirty
+				       (cn->bh));
+
+				/* undo the inc from journal_mark_dirty */
+				put_bh(cn->bh);
+				brelse(cn->bh);
+			}
+			cn = cn->next;
+		}
+	}
+
+	if (err)
+		reiserfs_abort(s, -EIO,
+			       "Write error while pushing transaction to disk in %s",
+			       __FUNCTION__);
+      flush_older_and_return:
+
+	/* before we can update the journal header block, we _must_ flush all 
+	 ** real blocks from all older transactions to disk.  This is because
+	 ** once the header block is updated, this transaction will not be
+	 ** replayed after a crash
+	 */
+	if (flushall) {
+		flush_older_journal_lists(s, jl);
+	}
+
+	err = journal->j_errno;
+	/* before we can remove everything from the hash tables for this 
+	 ** transaction, we must make sure it can never be replayed
+	 **
+	 ** since we are only called from do_journal_end, we know for sure there
+	 ** are no allocations going on while we are flushing journal lists.  So,
+	 ** we only need to update the journal header block for the last list
+	 ** being flushed
+	 */
+	if (!err && flushall) {
+		err =
+		    update_journal_header_block(s,
+						(jl->j_start + jl->j_len +
+						 2) % SB_ONDISK_JOURNAL_SIZE(s),
+						jl->j_trans_id);
+		if (err)
+			reiserfs_abort(s, -EIO,
+				       "Write error while updating journal header in %s",
+				       __FUNCTION__);
+	}
+	remove_all_from_journal_list(s, jl, 0);
+	list_del_init(&jl->j_list);
+	journal->j_num_lists--;
+	del_from_work_list(s, jl);
+
+	if (journal->j_last_flush_id != 0 &&
+	    (jl->j_trans_id - journal->j_last_flush_id) != 1) {
+		reiserfs_warning(s, "clm-2201: last flush %lu, current %lu",
+				 journal->j_last_flush_id, jl->j_trans_id);
+	}
+	journal->j_last_flush_id = jl->j_trans_id;
+
+	/* not strictly required since we are freeing the list, but it should
+	 * help find code using dead lists later on
+	 */
+	jl->j_len = 0;
+	atomic_set(&(jl->j_nonzerolen), 0);
+	jl->j_start = 0;
+	jl->j_realblock = NULL;
+	jl->j_commit_bh = NULL;
+	jl->j_trans_id = 0;
+	jl->j_state = 0;
+	put_journal_list(s, jl);
+	if (flushall)
+		up(&journal->j_flush_sem);
+	put_fs_excl();
+	return err;
+}
+
+static int write_one_transaction(struct super_block *s,
+				 struct reiserfs_journal_list *jl,
+				 struct buffer_chunk *chunk)
+{
+	struct reiserfs_journal_cnode *cn;
+	int ret = 0;
+
+	jl->j_state |= LIST_TOUCHED;
+	del_from_work_list(s, jl);
+	if (jl->j_len == 0 || atomic_read(&jl->j_nonzerolen) == 0) {
+		return 0;
+	}
+
+	cn = jl->j_realblock;
+	while (cn) {
+		/* if the blocknr == 0, this has been cleared from the hash,
+		 ** skip it
+		 */
+		if (cn->blocknr == 0) {
+			goto next;
+		}
+		if (cn->bh && can_dirty(cn) && buffer_dirty(cn->bh)) {
+			struct buffer_head *tmp_bh;
+			/* we can race against journal_mark_freed when we try
+			 * to lock_buffer(cn->bh), so we have to inc the buffer
+			 * count, and recheck things after locking
+			 */
+			tmp_bh = cn->bh;
+			get_bh(tmp_bh);
+			lock_buffer(tmp_bh);
+			if (cn->bh && can_dirty(cn) && buffer_dirty(tmp_bh)) {
+				if (!buffer_journal_dirty(tmp_bh) ||
+				    buffer_journal_prepared(tmp_bh))
+					BUG();
+				add_to_chunk(chunk, tmp_bh, NULL, write_chunk);
+				ret++;
+			} else {
+				/* note, cn->bh might be null now */
+				unlock_buffer(tmp_bh);
+			}
+			put_bh(tmp_bh);
+		}
+	      next:
+		cn = cn->next;
+		cond_resched();
+	}
+	return ret;
+}
+
+/* used by flush_commit_list */
+static int dirty_one_transaction(struct super_block *s,
+				 struct reiserfs_journal_list *jl)
+{
+	struct reiserfs_journal_cnode *cn;
+	struct reiserfs_journal_list *pjl;
+	int ret = 0;
+
+	jl->j_state |= LIST_DIRTY;
+	cn = jl->j_realblock;
+	while (cn) {
+		/* look for a more recent transaction that logged this
+		 ** buffer.  Only the most recent transaction with a buffer in
+		 ** it is allowed to send that buffer to disk
+		 */
+		pjl = find_newer_jl_for_cn(cn);
+		if (!pjl && cn->blocknr && cn->bh
+		    && buffer_journal_dirty(cn->bh)) {
+			BUG_ON(!can_dirty(cn));
+			/* if the buffer is prepared, it will either be logged
+			 * or restored.  If restored, we need to make sure
+			 * it actually gets marked dirty
+			 */
+			clear_buffer_journal_new(cn->bh);
+			if (buffer_journal_prepared(cn->bh)) {
+				set_buffer_journal_restore_dirty(cn->bh);
+			} else {
+				set_buffer_journal_test(cn->bh);
+				mark_buffer_dirty(cn->bh);
+			}
+		}
+		cn = cn->next;
+	}
+	return ret;
+}
+
+static int kupdate_transactions(struct super_block *s,
+				struct reiserfs_journal_list *jl,
+				struct reiserfs_journal_list **next_jl,
+				unsigned long *next_trans_id,
+				int num_blocks, int num_trans)
+{
+	int ret = 0;
+	int written = 0;
+	int transactions_flushed = 0;
+	unsigned long orig_trans_id = jl->j_trans_id;
+	struct buffer_chunk chunk;
+	struct list_head *entry;
+	struct reiserfs_journal *journal = SB_JOURNAL(s);
+	chunk.nr = 0;
+
+	down(&journal->j_flush_sem);
+	if (!journal_list_still_alive(s, orig_trans_id)) {
+		goto done;
+	}
+
+	/* we've got j_flush_sem held, nobody is going to delete any
+	 * of these lists out from underneath us
+	 */
+	while ((num_trans && transactions_flushed < num_trans) ||
+	       (!num_trans && written < num_blocks)) {
+
+		if (jl->j_len == 0 || (jl->j_state & LIST_TOUCHED) ||
+		    atomic_read(&jl->j_commit_left)
+		    || !(jl->j_state & LIST_DIRTY)) {
+			del_from_work_list(s, jl);
+			break;
+		}
+		ret = write_one_transaction(s, jl, &chunk);
+
+		if (ret < 0)
+			goto done;
+		transactions_flushed++;
+		written += ret;
+		entry = jl->j_list.next;
+
+		/* did we wrap? */
+		if (entry == &journal->j_journal_list) {
+			break;
+		}
+		jl = JOURNAL_LIST_ENTRY(entry);
+
+		/* don't bother with older transactions */
+		if (jl->j_trans_id <= orig_trans_id)
+			break;
+	}
+	if (chunk.nr) {
+		write_chunk(&chunk);
+	}
+
+      done:
+	up(&journal->j_flush_sem);
+	return ret;
+}
+
+/* for o_sync and fsync heavy applications, they tend to use
+** all the journa list slots with tiny transactions.  These
+** trigger lots and lots of calls to update the header block, which
+** adds seeks and slows things down.
+**
+** This function tries to clear out a large chunk of the journal lists
+** at once, which makes everything faster since only the newest journal
+** list updates the header block
+*/
+static int flush_used_journal_lists(struct super_block *s,
+				    struct reiserfs_journal_list *jl)
+{
+	unsigned long len = 0;
+	unsigned long cur_len;
+	int ret;
+	int i;
+	int limit = 256;
+	struct reiserfs_journal_list *tjl;
+	struct reiserfs_journal_list *flush_jl;
+	unsigned long trans_id;
+	struct reiserfs_journal *journal = SB_JOURNAL(s);
+
+	flush_jl = tjl = jl;
+
+	/* in data logging mode, try harder to flush a lot of blocks */
+	if (reiserfs_data_log(s))
+		limit = 1024;
+	/* flush for 256 transactions or limit blocks, whichever comes first */
+	for (i = 0; i < 256 && len < limit; i++) {
+		if (atomic_read(&tjl->j_commit_left) ||
+		    tjl->j_trans_id < jl->j_trans_id) {
+			break;
+		}
+		cur_len = atomic_read(&tjl->j_nonzerolen);
+		if (cur_len > 0) {
+			tjl->j_state &= ~LIST_TOUCHED;
+		}
+		len += cur_len;
+		flush_jl = tjl;
+		if (tjl->j_list.next == &journal->j_journal_list)
+			break;
+		tjl = JOURNAL_LIST_ENTRY(tjl->j_list.next);
+	}
+	/* try to find a group of blocks we can flush across all the
+	 ** transactions, but only bother if we've actually spanned
+	 ** across multiple lists
+	 */
+	if (flush_jl != jl) {
+		ret = kupdate_transactions(s, jl, &tjl, &trans_id, len, i);
+	}
+	flush_journal_list(s, flush_jl, 1);
+	return 0;
+}
 
 /*
 ** removes any nodes in table with name block and dev as bh.
 ** only touchs the hnext and hprev pointers.
 */
 void remove_journal_hash(struct super_block *sb,
-			struct reiserfs_journal_cnode **table,
-			struct reiserfs_journal_list *jl,
-			unsigned long block, int remove_freed)
-{
-  struct reiserfs_journal_cnode *cur ;
-  struct reiserfs_journal_cnode **head ;
-
-  head= &(journal_hash(table, sb, block)) ;
-  if (!head) {
-    return ;
-  }
-  cur = *head ;
-  while(cur) {
-    if (cur->blocknr == block && cur->sb == sb && (jl == NULL || jl == cur->jlist) && 
-        (!test_bit(BLOCK_FREED, &cur->state) || remove_freed)) {
-      if (cur->hnext) {
-        cur->hnext->hprev = cur->hprev ;
-      }
-      if (cur->hprev) {
-	cur->hprev->hnext = cur->hnext ;
-      } else {
-	*head = cur->hnext ;
-      }
-      cur->blocknr = 0 ;
-      cur->sb = NULL ;
-      cur->state = 0 ;
-      if (cur->bh && cur->jlist) /* anybody who clears the cur->bh will also dec the nonzerolen */
-	atomic_dec(&(cur->jlist->j_nonzerolen)) ;
-      cur->bh = NULL ;
-      cur->jlist = NULL ;
-    } 
-    cur = cur->hnext ;
-  }
-}
-
-static void free_journal_ram(struct super_block *p_s_sb) {
-  struct reiserfs_journal *journal = SB_JOURNAL(p_s_sb);
-  reiserfs_kfree(journal->j_current_jl,
-                 sizeof(struct reiserfs_journal_list), p_s_sb);
-  journal->j_num_lists--;
-
-  vfree(journal->j_cnode_free_orig) ;
-  free_list_bitmaps(p_s_sb, journal->j_list_bitmap) ;
-  free_bitmap_nodes(p_s_sb) ; /* must be after free_list_bitmaps */
-  if (journal->j_header_bh) {
-    brelse(journal->j_header_bh) ;
-  }
-  /* j_header_bh is on the journal dev, make sure not to release the journal
-   * dev until we brelse j_header_bh
-   */
-  release_journal_dev(p_s_sb, journal);
-  vfree(journal) ;
+			 struct reiserfs_journal_cnode **table,
+			 struct reiserfs_journal_list *jl,
+			 unsigned long block, int remove_freed)
+{
+	struct reiserfs_journal_cnode *cur;
+	struct reiserfs_journal_cnode **head;
+
+	head = &(journal_hash(table, sb, block));
+	if (!head) {
+		return;
+	}
+	cur = *head;
+	while (cur) {
+		if (cur->blocknr == block && cur->sb == sb
+		    && (jl == NULL || jl == cur->jlist)
+		    && (!test_bit(BLOCK_FREED, &cur->state) || remove_freed)) {
+			if (cur->hnext) {
+				cur->hnext->hprev = cur->hprev;
+			}
+			if (cur->hprev) {
+				cur->hprev->hnext = cur->hnext;
+			} else {
+				*head = cur->hnext;
+			}
+			cur->blocknr = 0;
+			cur->sb = NULL;
+			cur->state = 0;
+			if (cur->bh && cur->jlist)	/* anybody who clears the cur->bh will also dec the nonzerolen */
+				atomic_dec(&(cur->jlist->j_nonzerolen));
+			cur->bh = NULL;
+			cur->jlist = NULL;
+		}
+		cur = cur->hnext;
+	}
+}
+
+static void free_journal_ram(struct super_block *p_s_sb)
+{
+	struct reiserfs_journal *journal = SB_JOURNAL(p_s_sb);
+	reiserfs_kfree(journal->j_current_jl,
+		       sizeof(struct reiserfs_journal_list), p_s_sb);
+	journal->j_num_lists--;
+
+	vfree(journal->j_cnode_free_orig);
+	free_list_bitmaps(p_s_sb, journal->j_list_bitmap);
+	free_bitmap_nodes(p_s_sb);	/* must be after free_list_bitmaps */
+	if (journal->j_header_bh) {
+		brelse(journal->j_header_bh);
+	}
+	/* j_header_bh is on the journal dev, make sure not to release the journal
+	 * dev until we brelse j_header_bh
+	 */
+	release_journal_dev(p_s_sb, journal);
+	vfree(journal);
 }
 
 /*
 ** call on unmount.  Only set error to 1 if you haven't made your way out
 ** of read_super() yet.  Any other caller must keep error at 0.
 */
-static int do_journal_release(struct reiserfs_transaction_handle *th, struct super_block *p_s_sb, int error) {
-  struct reiserfs_transaction_handle myth ;
-  int flushed = 0;
-  struct reiserfs_journal *journal = SB_JOURNAL(p_s_sb);
-
-  /* we only want to flush out transactions if we were called with error == 0
-  */
-  if (!error && !(p_s_sb->s_flags & MS_RDONLY)) {
-    /* end the current trans */
-    BUG_ON (!th->t_trans_id);
-    do_journal_end(th, p_s_sb,10, FLUSH_ALL) ;
-
-    /* make sure something gets logged to force our way into the flush code */
-    if (!journal_join(&myth, p_s_sb, 1)) {
-        reiserfs_prepare_for_journal(p_s_sb, SB_BUFFER_WITH_SB(p_s_sb), 1) ;
-        journal_mark_dirty(&myth, p_s_sb, SB_BUFFER_WITH_SB(p_s_sb)) ;
-        do_journal_end(&myth, p_s_sb,1, FLUSH_ALL) ;
-        flushed = 1;
-    }
-  }
-
-  /* this also catches errors during the do_journal_end above */
-  if (!error && reiserfs_is_journal_aborted(journal)) {
-      memset(&myth, 0, sizeof(myth));
-      if (!journal_join_abort(&myth, p_s_sb, 1)) {
-	  reiserfs_prepare_for_journal(p_s_sb, SB_BUFFER_WITH_SB(p_s_sb), 1) ;
-	  journal_mark_dirty(&myth, p_s_sb, SB_BUFFER_WITH_SB(p_s_sb)) ;
-          do_journal_end(&myth, p_s_sb, 1, FLUSH_ALL) ;
-      }
-  }
-
-  reiserfs_mounted_fs_count-- ;
-  /* wait for all commits to finish */
-  cancel_delayed_work(&SB_JOURNAL(p_s_sb)->j_work);
-  flush_workqueue(commit_wq);
-  if (!reiserfs_mounted_fs_count) {
-    destroy_workqueue(commit_wq);
-    commit_wq = NULL;
-  }
+static int do_journal_release(struct reiserfs_transaction_handle *th,
+			      struct super_block *p_s_sb, int error)
+{
+	struct reiserfs_transaction_handle myth;
+	int flushed = 0;
+	struct reiserfs_journal *journal = SB_JOURNAL(p_s_sb);
 
-  free_journal_ram(p_s_sb) ;
+	/* we only want to flush out transactions if we were called with error == 0
+	 */
+	if (!error && !(p_s_sb->s_flags & MS_RDONLY)) {
+		/* end the current trans */
+		BUG_ON(!th->t_trans_id);
+		do_journal_end(th, p_s_sb, 10, FLUSH_ALL);
+
+		/* make sure something gets logged to force our way into the flush code */
+		if (!journal_join(&myth, p_s_sb, 1)) {
+			reiserfs_prepare_for_journal(p_s_sb,
+						     SB_BUFFER_WITH_SB(p_s_sb),
+						     1);
+			journal_mark_dirty(&myth, p_s_sb,
+					   SB_BUFFER_WITH_SB(p_s_sb));
+			do_journal_end(&myth, p_s_sb, 1, FLUSH_ALL);
+			flushed = 1;
+		}
+	}
 
-  return 0 ;
+	/* this also catches errors during the do_journal_end above */
+	if (!error && reiserfs_is_journal_aborted(journal)) {
+		memset(&myth, 0, sizeof(myth));
+		if (!journal_join_abort(&myth, p_s_sb, 1)) {
+			reiserfs_prepare_for_journal(p_s_sb,
+						     SB_BUFFER_WITH_SB(p_s_sb),
+						     1);
+			journal_mark_dirty(&myth, p_s_sb,
+					   SB_BUFFER_WITH_SB(p_s_sb));
+			do_journal_end(&myth, p_s_sb, 1, FLUSH_ALL);
+		}
+	}
+
+	reiserfs_mounted_fs_count--;
+	/* wait for all commits to finish */
+	cancel_delayed_work(&SB_JOURNAL(p_s_sb)->j_work);
+	flush_workqueue(commit_wq);
+	if (!reiserfs_mounted_fs_count) {
+		destroy_workqueue(commit_wq);
+		commit_wq = NULL;
+	}
+
+	free_journal_ram(p_s_sb);
+
+	return 0;
 }
 
 /*
 ** call on unmount.  flush all journal trans, release all alloc'd ram
 */
-int journal_release(struct reiserfs_transaction_handle *th, struct super_block *p_s_sb) {
-  return do_journal_release(th, p_s_sb, 0) ;
+int journal_release(struct reiserfs_transaction_handle *th,
+		    struct super_block *p_s_sb)
+{
+	return do_journal_release(th, p_s_sb, 0);
 }
+
 /*
 ** only call from an error condition inside reiserfs_read_super!
 */
-int journal_release_error(struct reiserfs_transaction_handle *th, struct super_block *p_s_sb) {
-  return do_journal_release(th, p_s_sb, 1) ;
+int journal_release_error(struct reiserfs_transaction_handle *th,
+			  struct super_block *p_s_sb)
+{
+	return do_journal_release(th, p_s_sb, 1);
 }
 
 /* compares description block with commit block.  returns 1 if they differ, 0 if they are the same */
-static int journal_compare_desc_commit(struct super_block *p_s_sb, struct reiserfs_journal_desc *desc, 
-			               struct reiserfs_journal_commit *commit) {
-  if (get_commit_trans_id (commit) != get_desc_trans_id (desc) || 
-      get_commit_trans_len (commit) != get_desc_trans_len (desc) || 
-      get_commit_trans_len (commit) > SB_JOURNAL(p_s_sb)->j_trans_max ||
-      get_commit_trans_len (commit) <= 0 
-  ) {
-    return 1 ;
-  }
-  return 0 ;
+static int journal_compare_desc_commit(struct super_block *p_s_sb,
+				       struct reiserfs_journal_desc *desc,
+				       struct reiserfs_journal_commit *commit)
+{
+	if (get_commit_trans_id(commit) != get_desc_trans_id(desc) ||
+	    get_commit_trans_len(commit) != get_desc_trans_len(desc) ||
+	    get_commit_trans_len(commit) > SB_JOURNAL(p_s_sb)->j_trans_max ||
+	    get_commit_trans_len(commit) <= 0) {
+		return 1;
+	}
+	return 0;
 }
+
 /* returns 0 if it did not find a description block  
 ** returns -1 if it found a corrupt commit block
 ** returns 1 if both desc and commit were valid 
 */
-static int journal_transaction_is_valid(struct super_block *p_s_sb, struct buffer_head *d_bh, unsigned long *oldest_invalid_trans_id, unsigned long *newest_mount_id) {
-  struct reiserfs_journal_desc *desc ;
-  struct reiserfs_journal_commit *commit ;
-  struct buffer_head *c_bh ;
-  unsigned long offset ;
-
-  if (!d_bh)
-      return 0 ;
-
-  desc = (struct reiserfs_journal_desc *)d_bh->b_data ;
-  if (get_desc_trans_len(desc) > 0 && !memcmp(get_journal_desc_magic (d_bh), JOURNAL_DESC_MAGIC, 8)) {
-    if (oldest_invalid_trans_id && *oldest_invalid_trans_id && get_desc_trans_id(desc) > *oldest_invalid_trans_id) {
-      reiserfs_debug(p_s_sb, REISERFS_DEBUG_CODE, "journal-986: transaction "
-	              "is valid returning because trans_id %d is greater than "
-		      "oldest_invalid %lu", get_desc_trans_id(desc),
-		       *oldest_invalid_trans_id);
-      return 0 ;
-    }
-    if (newest_mount_id && *newest_mount_id > get_desc_mount_id (desc)) {
-      reiserfs_debug(p_s_sb, REISERFS_DEBUG_CODE, "journal-1087: transaction "
-                     "is valid returning because mount_id %d is less than "
-		     "newest_mount_id %lu", get_desc_mount_id (desc),
-		     *newest_mount_id) ;
-      return -1 ;
-    }
-    if ( get_desc_trans_len(desc) > SB_JOURNAL(p_s_sb)->j_trans_max ) {
-      reiserfs_warning(p_s_sb, "journal-2018: Bad transaction length %d encountered, ignoring transaction", get_desc_trans_len(desc));
-      return -1 ;
-    }
-    offset = d_bh->b_blocknr - SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) ;
-
-    /* ok, we have a journal description block, lets see if the transaction was valid */
-    c_bh = journal_bread(p_s_sb, SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) +
-		 ((offset + get_desc_trans_len(desc) + 1) % SB_ONDISK_JOURNAL_SIZE(p_s_sb))) ;
-    if (!c_bh)
-      return 0 ;
-    commit = (struct reiserfs_journal_commit *)c_bh->b_data ;
-    if (journal_compare_desc_commit(p_s_sb, desc, commit)) {
-      reiserfs_debug(p_s_sb, REISERFS_DEBUG_CODE, 
-                     "journal_transaction_is_valid, commit offset %ld had bad "
-		     "time %d or length %d",
-		     c_bh->b_blocknr -  SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb),
-		     get_commit_trans_id (commit), 
-		     get_commit_trans_len(commit));
-      brelse(c_bh) ;
-      if (oldest_invalid_trans_id) {
-	*oldest_invalid_trans_id = get_desc_trans_id(desc) ;
-	reiserfs_debug(p_s_sb, REISERFS_DEBUG_CODE, "journal-1004: "
-		       "transaction_is_valid setting oldest invalid trans_id "
-		       "to %d", get_desc_trans_id(desc)) ;
-      }
-      return -1; 
-    }
-    brelse(c_bh) ;
-    reiserfs_debug(p_s_sb, REISERFS_DEBUG_CODE, "journal-1006: found valid "
-                   "transaction start offset %llu, len %d id %d",
-		   d_bh->b_blocknr - SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb), 
-		   get_desc_trans_len(desc), get_desc_trans_id(desc)) ;
-    return 1 ;
-  } else {
-    return 0 ;
-  }
-}
-
-static void brelse_array(struct buffer_head **heads, int num) {
-  int i ;
-  for (i = 0 ; i < num ; i++) {
-    brelse(heads[i]) ;
-  }
+static int journal_transaction_is_valid(struct super_block *p_s_sb,
+					struct buffer_head *d_bh,
+					unsigned long *oldest_invalid_trans_id,
+					unsigned long *newest_mount_id)
+{
+	struct reiserfs_journal_desc *desc;
+	struct reiserfs_journal_commit *commit;
+	struct buffer_head *c_bh;
+	unsigned long offset;
+
+	if (!d_bh)
+		return 0;
+
+	desc = (struct reiserfs_journal_desc *)d_bh->b_data;
+	if (get_desc_trans_len(desc) > 0
+	    && !memcmp(get_journal_desc_magic(d_bh), JOURNAL_DESC_MAGIC, 8)) {
+		if (oldest_invalid_trans_id && *oldest_invalid_trans_id
+		    && get_desc_trans_id(desc) > *oldest_invalid_trans_id) {
+			reiserfs_debug(p_s_sb, REISERFS_DEBUG_CODE,
+				       "journal-986: transaction "
+				       "is valid returning because trans_id %d is greater than "
+				       "oldest_invalid %lu",
+				       get_desc_trans_id(desc),
+				       *oldest_invalid_trans_id);
+			return 0;
+		}
+		if (newest_mount_id
+		    && *newest_mount_id > get_desc_mount_id(desc)) {
+			reiserfs_debug(p_s_sb, REISERFS_DEBUG_CODE,
+				       "journal-1087: transaction "
+				       "is valid returning because mount_id %d is less than "
+				       "newest_mount_id %lu",
+				       get_desc_mount_id(desc),
+				       *newest_mount_id);
+			return -1;
+		}
+		if (get_desc_trans_len(desc) > SB_JOURNAL(p_s_sb)->j_trans_max) {
+			reiserfs_warning(p_s_sb,
+					 "journal-2018: Bad transaction length %d encountered, ignoring transaction",
+					 get_desc_trans_len(desc));
+			return -1;
+		}
+		offset = d_bh->b_blocknr - SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb);
+
+		/* ok, we have a journal description block, lets see if the transaction was valid */
+		c_bh =
+		    journal_bread(p_s_sb,
+				  SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) +
+				  ((offset + get_desc_trans_len(desc) +
+				    1) % SB_ONDISK_JOURNAL_SIZE(p_s_sb)));
+		if (!c_bh)
+			return 0;
+		commit = (struct reiserfs_journal_commit *)c_bh->b_data;
+		if (journal_compare_desc_commit(p_s_sb, desc, commit)) {
+			reiserfs_debug(p_s_sb, REISERFS_DEBUG_CODE,
+				       "journal_transaction_is_valid, commit offset %ld had bad "
+				       "time %d or length %d",
+				       c_bh->b_blocknr -
+				       SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb),
+				       get_commit_trans_id(commit),
+				       get_commit_trans_len(commit));
+			brelse(c_bh);
+			if (oldest_invalid_trans_id) {
+				*oldest_invalid_trans_id =
+				    get_desc_trans_id(desc);
+				reiserfs_debug(p_s_sb, REISERFS_DEBUG_CODE,
+					       "journal-1004: "
+					       "transaction_is_valid setting oldest invalid trans_id "
+					       "to %d",
+					       get_desc_trans_id(desc));
+			}
+			return -1;
+		}
+		brelse(c_bh);
+		reiserfs_debug(p_s_sb, REISERFS_DEBUG_CODE,
+			       "journal-1006: found valid "
+			       "transaction start offset %llu, len %d id %d",
+			       d_bh->b_blocknr -
+			       SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb),
+			       get_desc_trans_len(desc),
+			       get_desc_trans_id(desc));
+		return 1;
+	} else {
+		return 0;
+	}
+}
+
+static void brelse_array(struct buffer_head **heads, int num)
+{
+	int i;
+	for (i = 0; i < num; i++) {
+		brelse(heads[i]);
+	}
 }
 
 /*
@@ -1863,149 +2018,202 @@ static void brelse_array(struct buffer_h
 ** this either reads in a replays a transaction, or returns because the transaction
 ** is invalid, or too old.
 */
-static int journal_read_transaction(struct super_block *p_s_sb, unsigned long cur_dblock, unsigned long oldest_start, 
-				    unsigned long oldest_trans_id, unsigned long newest_mount_id) {
-  struct reiserfs_journal *journal = SB_JOURNAL (p_s_sb);
-  struct reiserfs_journal_desc *desc ;
-  struct reiserfs_journal_commit *commit ;
-  unsigned long trans_id = 0 ;
-  struct buffer_head *c_bh ;
-  struct buffer_head *d_bh ;
-  struct buffer_head **log_blocks = NULL ;
-  struct buffer_head **real_blocks = NULL ;
-  unsigned long trans_offset ;
-  int i;
-  int trans_half;
-
-  d_bh = journal_bread(p_s_sb, cur_dblock) ;
-  if (!d_bh)
-    return 1 ;
-  desc = (struct reiserfs_journal_desc *)d_bh->b_data ;
-  trans_offset = d_bh->b_blocknr - SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) ;
-  reiserfs_debug(p_s_sb, REISERFS_DEBUG_CODE, "journal-1037: "
-                 "journal_read_transaction, offset %llu, len %d mount_id %d",
-		 d_bh->b_blocknr - SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb), 
-		 get_desc_trans_len(desc), get_desc_mount_id(desc)) ;
-  if (get_desc_trans_id(desc) < oldest_trans_id) {
-    reiserfs_debug(p_s_sb, REISERFS_DEBUG_CODE, "journal-1039: "
-                   "journal_read_trans skipping because %lu is too old",
-		   cur_dblock - SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb)) ;
-    brelse(d_bh) ;
-    return 1 ;
-  }
-  if (get_desc_mount_id(desc) != newest_mount_id) {
-    reiserfs_debug(p_s_sb, REISERFS_DEBUG_CODE, "journal-1146: "
-                   "journal_read_trans skipping because %d is != "
-		   "newest_mount_id %lu", get_desc_mount_id(desc),
-		    newest_mount_id) ;
-    brelse(d_bh) ;
-    return 1 ;
-  }
-  c_bh = journal_bread(p_s_sb, SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) +
-		((trans_offset + get_desc_trans_len(desc) + 1) % 
-		 SB_ONDISK_JOURNAL_SIZE(p_s_sb))) ;
-  if (!c_bh) {
-    brelse(d_bh) ;
-    return 1 ;
-  }
-  commit = (struct reiserfs_journal_commit *)c_bh->b_data ;
-  if (journal_compare_desc_commit(p_s_sb, desc, commit)) {
-    reiserfs_debug(p_s_sb, REISERFS_DEBUG_CODE, "journal_read_transaction, "
-                   "commit offset %llu had bad time %d or length %d",
-		   c_bh->b_blocknr -  SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb), 
-		   get_commit_trans_id(commit), get_commit_trans_len(commit));
-    brelse(c_bh) ;
-    brelse(d_bh) ;
-    return 1; 
-  }
-  trans_id = get_desc_trans_id(desc) ;
-  /* now we know we've got a good transaction, and it was inside the valid time ranges */
-  log_blocks = reiserfs_kmalloc(get_desc_trans_len(desc) * sizeof(struct buffer_head *), GFP_NOFS, p_s_sb) ;
-  real_blocks = reiserfs_kmalloc(get_desc_trans_len(desc) * sizeof(struct buffer_head *), GFP_NOFS, p_s_sb) ;
-  if (!log_blocks  || !real_blocks) {
-    brelse(c_bh) ;
-    brelse(d_bh) ;
-    reiserfs_kfree(log_blocks, get_desc_trans_len(desc) * sizeof(struct buffer_head *), p_s_sb) ;
-    reiserfs_kfree(real_blocks, get_desc_trans_len(desc) * sizeof(struct buffer_head *), p_s_sb) ;
-    reiserfs_warning(p_s_sb, "journal-1169: kmalloc failed, unable to mount FS") ;
-    return -1 ;
-  }
-  /* get all the buffer heads */
-  trans_half = journal_trans_half (p_s_sb->s_blocksize) ;
-  for(i = 0 ; i < get_desc_trans_len(desc) ; i++) {
-    log_blocks[i] =  journal_getblk(p_s_sb,  SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) + (trans_offset + 1 + i) % SB_ONDISK_JOURNAL_SIZE(p_s_sb));
-    if (i < trans_half) {
-      real_blocks[i] = sb_getblk(p_s_sb, le32_to_cpu(desc->j_realblock[i])) ;
-    } else {
-      real_blocks[i] = sb_getblk(p_s_sb, le32_to_cpu(commit->j_realblock[i - trans_half])) ;
-    }
-    if ( real_blocks[i]->b_blocknr > SB_BLOCK_COUNT(p_s_sb) ) {
-      reiserfs_warning(p_s_sb, "journal-1207: REPLAY FAILURE fsck required! Block to replay is outside of filesystem");
-      goto abort_replay;
-    }
-    /* make sure we don't try to replay onto log or reserved area */
-    if (is_block_in_log_or_reserved_area(p_s_sb, real_blocks[i]->b_blocknr)) {
-      reiserfs_warning(p_s_sb, "journal-1204: REPLAY FAILURE fsck required! Trying to replay onto a log block") ;
-abort_replay:
-      brelse_array(log_blocks, i) ;
-      brelse_array(real_blocks, i) ;
-      brelse(c_bh) ;
-      brelse(d_bh) ;
-      reiserfs_kfree(log_blocks, get_desc_trans_len(desc) * sizeof(struct buffer_head *), p_s_sb) ;
-      reiserfs_kfree(real_blocks, get_desc_trans_len(desc) * sizeof(struct buffer_head *), p_s_sb) ;
-      return -1 ;
-    }
-  }
-  /* read in the log blocks, memcpy to the corresponding real block */
-  ll_rw_block(READ, get_desc_trans_len(desc), log_blocks) ;
-  for (i = 0 ; i < get_desc_trans_len(desc) ; i++) {
-    wait_on_buffer(log_blocks[i]) ;
-    if (!buffer_uptodate(log_blocks[i])) {
-      reiserfs_warning(p_s_sb, "journal-1212: REPLAY FAILURE fsck required! buffer write failed") ;
-      brelse_array(log_blocks + i, get_desc_trans_len(desc) - i) ;
-      brelse_array(real_blocks, get_desc_trans_len(desc)) ;
-      brelse(c_bh) ;
-      brelse(d_bh) ;
-      reiserfs_kfree(log_blocks, get_desc_trans_len(desc) * sizeof(struct buffer_head *), p_s_sb) ;
-      reiserfs_kfree(real_blocks, get_desc_trans_len(desc) * sizeof(struct buffer_head *), p_s_sb) ;
-      return -1 ;
-    }
-    memcpy(real_blocks[i]->b_data, log_blocks[i]->b_data, real_blocks[i]->b_size) ;
-    set_buffer_uptodate(real_blocks[i]) ;
-    brelse(log_blocks[i]) ;
-  }
-  /* flush out the real blocks */
-  for (i = 0 ; i < get_desc_trans_len(desc) ; i++) {
-    set_buffer_dirty(real_blocks[i]) ;
-    ll_rw_block(WRITE, 1, real_blocks + i) ;
-  }
-  for (i = 0 ; i < get_desc_trans_len(desc) ; i++) {
-    wait_on_buffer(real_blocks[i]) ; 
-    if (!buffer_uptodate(real_blocks[i])) {
-      reiserfs_warning(p_s_sb, "journal-1226: REPLAY FAILURE, fsck required! buffer write failed") ;
-      brelse_array(real_blocks + i, get_desc_trans_len(desc) - i) ;
-      brelse(c_bh) ;
-      brelse(d_bh) ;
-      reiserfs_kfree(log_blocks, get_desc_trans_len(desc) * sizeof(struct buffer_head *), p_s_sb) ;
-      reiserfs_kfree(real_blocks, get_desc_trans_len(desc) * sizeof(struct buffer_head *), p_s_sb) ;
-      return -1 ;
-    }
-    brelse(real_blocks[i]) ;
-  }
-  cur_dblock =  SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) + ((trans_offset + get_desc_trans_len(desc) + 2) % SB_ONDISK_JOURNAL_SIZE(p_s_sb)) ;
-  reiserfs_debug(p_s_sb, REISERFS_DEBUG_CODE, "journal-1095: setting journal "
-                 "start to offset %ld",
-		 cur_dblock -  SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb)) ;
-  
-  /* init starting values for the first transaction, in case this is the last transaction to be replayed. */
-  journal->j_start = cur_dblock - SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) ;
-  journal->j_last_flush_trans_id = trans_id ;
-  journal->j_trans_id = trans_id + 1;
-  brelse(c_bh) ;
-  brelse(d_bh) ;
-  reiserfs_kfree(log_blocks, le32_to_cpu(desc->j_len) * sizeof(struct buffer_head *), p_s_sb) ;
-  reiserfs_kfree(real_blocks, le32_to_cpu(desc->j_len) * sizeof(struct buffer_head *), p_s_sb) ;
-  return 0 ;
+static int journal_read_transaction(struct super_block *p_s_sb,
+				    unsigned long cur_dblock,
+				    unsigned long oldest_start,
+				    unsigned long oldest_trans_id,
+				    unsigned long newest_mount_id)
+{
+	struct reiserfs_journal *journal = SB_JOURNAL(p_s_sb);
+	struct reiserfs_journal_desc *desc;
+	struct reiserfs_journal_commit *commit;
+	unsigned long trans_id = 0;
+	struct buffer_head *c_bh;
+	struct buffer_head *d_bh;
+	struct buffer_head **log_blocks = NULL;
+	struct buffer_head **real_blocks = NULL;
+	unsigned long trans_offset;
+	int i;
+	int trans_half;
+
+	d_bh = journal_bread(p_s_sb, cur_dblock);
+	if (!d_bh)
+		return 1;
+	desc = (struct reiserfs_journal_desc *)d_bh->b_data;
+	trans_offset = d_bh->b_blocknr - SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb);
+	reiserfs_debug(p_s_sb, REISERFS_DEBUG_CODE, "journal-1037: "
+		       "journal_read_transaction, offset %llu, len %d mount_id %d",
+		       d_bh->b_blocknr - SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb),
+		       get_desc_trans_len(desc), get_desc_mount_id(desc));
+	if (get_desc_trans_id(desc) < oldest_trans_id) {
+		reiserfs_debug(p_s_sb, REISERFS_DEBUG_CODE, "journal-1039: "
+			       "journal_read_trans skipping because %lu is too old",
+			       cur_dblock -
+			       SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb));
+		brelse(d_bh);
+		return 1;
+	}
+	if (get_desc_mount_id(desc) != newest_mount_id) {
+		reiserfs_debug(p_s_sb, REISERFS_DEBUG_CODE, "journal-1146: "
+			       "journal_read_trans skipping because %d is != "
+			       "newest_mount_id %lu", get_desc_mount_id(desc),
+			       newest_mount_id);
+		brelse(d_bh);
+		return 1;
+	}
+	c_bh = journal_bread(p_s_sb, SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) +
+			     ((trans_offset + get_desc_trans_len(desc) + 1) %
+			      SB_ONDISK_JOURNAL_SIZE(p_s_sb)));
+	if (!c_bh) {
+		brelse(d_bh);
+		return 1;
+	}
+	commit = (struct reiserfs_journal_commit *)c_bh->b_data;
+	if (journal_compare_desc_commit(p_s_sb, desc, commit)) {
+		reiserfs_debug(p_s_sb, REISERFS_DEBUG_CODE,
+			       "journal_read_transaction, "
+			       "commit offset %llu had bad time %d or length %d",
+			       c_bh->b_blocknr -
+			       SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb),
+			       get_commit_trans_id(commit),
+			       get_commit_trans_len(commit));
+		brelse(c_bh);
+		brelse(d_bh);
+		return 1;
+	}
+	trans_id = get_desc_trans_id(desc);
+	/* now we know we've got a good transaction, and it was inside the valid time ranges */
+	log_blocks =
+	    reiserfs_kmalloc(get_desc_trans_len(desc) *
+			     sizeof(struct buffer_head *), GFP_NOFS, p_s_sb);
+	real_blocks =
+	    reiserfs_kmalloc(get_desc_trans_len(desc) *
+			     sizeof(struct buffer_head *), GFP_NOFS, p_s_sb);
+	if (!log_blocks || !real_blocks) {
+		brelse(c_bh);
+		brelse(d_bh);
+		reiserfs_kfree(log_blocks,
+			       get_desc_trans_len(desc) *
+			       sizeof(struct buffer_head *), p_s_sb);
+		reiserfs_kfree(real_blocks,
+			       get_desc_trans_len(desc) *
+			       sizeof(struct buffer_head *), p_s_sb);
+		reiserfs_warning(p_s_sb,
+				 "journal-1169: kmalloc failed, unable to mount FS");
+		return -1;
+	}
+	/* get all the buffer heads */
+	trans_half = journal_trans_half(p_s_sb->s_blocksize);
+	for (i = 0; i < get_desc_trans_len(desc); i++) {
+		log_blocks[i] =
+		    journal_getblk(p_s_sb,
+				   SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) +
+				   (trans_offset + 1 +
+				    i) % SB_ONDISK_JOURNAL_SIZE(p_s_sb));
+		if (i < trans_half) {
+			real_blocks[i] =
+			    sb_getblk(p_s_sb,
+				      le32_to_cpu(desc->j_realblock[i]));
+		} else {
+			real_blocks[i] =
+			    sb_getblk(p_s_sb,
+				      le32_to_cpu(commit->
+						  j_realblock[i - trans_half]));
+		}
+		if (real_blocks[i]->b_blocknr > SB_BLOCK_COUNT(p_s_sb)) {
+			reiserfs_warning(p_s_sb,
+					 "journal-1207: REPLAY FAILURE fsck required! Block to replay is outside of filesystem");
+			goto abort_replay;
+		}
+		/* make sure we don't try to replay onto log or reserved area */
+		if (is_block_in_log_or_reserved_area
+		    (p_s_sb, real_blocks[i]->b_blocknr)) {
+			reiserfs_warning(p_s_sb,
+					 "journal-1204: REPLAY FAILURE fsck required! Trying to replay onto a log block");
+		      abort_replay:
+			brelse_array(log_blocks, i);
+			brelse_array(real_blocks, i);
+			brelse(c_bh);
+			brelse(d_bh);
+			reiserfs_kfree(log_blocks,
+				       get_desc_trans_len(desc) *
+				       sizeof(struct buffer_head *), p_s_sb);
+			reiserfs_kfree(real_blocks,
+				       get_desc_trans_len(desc) *
+				       sizeof(struct buffer_head *), p_s_sb);
+			return -1;
+		}
+	}
+	/* read in the log blocks, memcpy to the corresponding real block */
+	ll_rw_block(READ, get_desc_trans_len(desc), log_blocks);
+	for (i = 0; i < get_desc_trans_len(desc); i++) {
+		wait_on_buffer(log_blocks[i]);
+		if (!buffer_uptodate(log_blocks[i])) {
+			reiserfs_warning(p_s_sb,
+					 "journal-1212: REPLAY FAILURE fsck required! buffer write failed");
+			brelse_array(log_blocks + i,
+				     get_desc_trans_len(desc) - i);
+			brelse_array(real_blocks, get_desc_trans_len(desc));
+			brelse(c_bh);
+			brelse(d_bh);
+			reiserfs_kfree(log_blocks,
+				       get_desc_trans_len(desc) *
+				       sizeof(struct buffer_head *), p_s_sb);
+			reiserfs_kfree(real_blocks,
+				       get_desc_trans_len(desc) *
+				       sizeof(struct buffer_head *), p_s_sb);
+			return -1;
+		}
+		memcpy(real_blocks[i]->b_data, log_blocks[i]->b_data,
+		       real_blocks[i]->b_size);
+		set_buffer_uptodate(real_blocks[i]);
+		brelse(log_blocks[i]);
+	}
+	/* flush out the real blocks */
+	for (i = 0; i < get_desc_trans_len(desc); i++) {
+		set_buffer_dirty(real_blocks[i]);
+		ll_rw_block(WRITE, 1, real_blocks + i);
+	}
+	for (i = 0; i < get_desc_trans_len(desc); i++) {
+		wait_on_buffer(real_blocks[i]);
+		if (!buffer_uptodate(real_blocks[i])) {
+			reiserfs_warning(p_s_sb,
+					 "journal-1226: REPLAY FAILURE, fsck required! buffer write failed");
+			brelse_array(real_blocks + i,
+				     get_desc_trans_len(desc) - i);
+			brelse(c_bh);
+			brelse(d_bh);
+			reiserfs_kfree(log_blocks,
+				       get_desc_trans_len(desc) *
+				       sizeof(struct buffer_head *), p_s_sb);
+			reiserfs_kfree(real_blocks,
+				       get_desc_trans_len(desc) *
+				       sizeof(struct buffer_head *), p_s_sb);
+			return -1;
+		}
+		brelse(real_blocks[i]);
+	}
+	cur_dblock =
+	    SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) +
+	    ((trans_offset + get_desc_trans_len(desc) +
+	      2) % SB_ONDISK_JOURNAL_SIZE(p_s_sb));
+	reiserfs_debug(p_s_sb, REISERFS_DEBUG_CODE,
+		       "journal-1095: setting journal " "start to offset %ld",
+		       cur_dblock - SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb));
+
+	/* init starting values for the first transaction, in case this is the last transaction to be replayed. */
+	journal->j_start = cur_dblock - SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb);
+	journal->j_last_flush_trans_id = trans_id;
+	journal->j_trans_id = trans_id + 1;
+	brelse(c_bh);
+	brelse(d_bh);
+	reiserfs_kfree(log_blocks,
+		       le32_to_cpu(desc->j_len) * sizeof(struct buffer_head *),
+		       p_s_sb);
+	reiserfs_kfree(real_blocks,
+		       le32_to_cpu(desc->j_len) * sizeof(struct buffer_head *),
+		       p_s_sb);
+	return 0;
 }
 
 /* This function reads blocks starting from block and to max_block of bufsize
@@ -2014,39 +2222,39 @@ abort_replay:
    Right now it is only used from journal code. But later we might use it
    from other places.
    Note: Do not use journal_getblk/sb_getblk functions here! */
-static struct buffer_head * reiserfs_breada (struct block_device *dev, int block, int bufsize,
-			    unsigned int max_block)
+static struct buffer_head *reiserfs_breada(struct block_device *dev, int block,
+					   int bufsize, unsigned int max_block)
 {
-	struct buffer_head * bhlist[BUFNR];
+	struct buffer_head *bhlist[BUFNR];
 	unsigned int blocks = BUFNR;
-	struct buffer_head * bh;
+	struct buffer_head *bh;
 	int i, j;
-	
-	bh = __getblk (dev, block, bufsize );
-	if (buffer_uptodate (bh))
-		return (bh);   
-		
+
+	bh = __getblk(dev, block, bufsize);
+	if (buffer_uptodate(bh))
+		return (bh);
+
 	if (block + BUFNR > max_block) {
 		blocks = max_block - block;
 	}
 	bhlist[0] = bh;
 	j = 1;
 	for (i = 1; i < blocks; i++) {
-		bh = __getblk (dev, block + i, bufsize);
-		if (buffer_uptodate (bh)) {
-			brelse (bh);
+		bh = __getblk(dev, block + i, bufsize);
+		if (buffer_uptodate(bh)) {
+			brelse(bh);
 			break;
-		}
-		else bhlist[j++] = bh;
+		} else
+			bhlist[j++] = bh;
 	}
-	ll_rw_block (READ, j, bhlist);
-	for(i = 1; i < j; i++) 
-		brelse (bhlist[i]);
+	ll_rw_block(READ, j, bhlist);
+	for (i = 1; i < j; i++)
+		brelse(bhlist[i]);
 	bh = bhlist[0];
-	wait_on_buffer (bh);
-	if (buffer_uptodate (bh))
+	wait_on_buffer(bh);
+	if (buffer_uptodate(bh))
 		return bh;
-	brelse (bh);
+	brelse(bh);
 	return NULL;
 }
 
@@ -2059,218 +2267,250 @@ static struct buffer_head * reiserfs_bre
 **
 ** On exit, it sets things up so the first transaction will work correctly.
 */
-static int journal_read(struct super_block *p_s_sb) {
-  struct reiserfs_journal *journal = SB_JOURNAL (p_s_sb);
-  struct reiserfs_journal_desc *desc ;
-  unsigned long oldest_trans_id = 0;
-  unsigned long oldest_invalid_trans_id = 0 ;
-  time_t start ;
-  unsigned long oldest_start = 0;
-  unsigned long cur_dblock = 0 ;
-  unsigned long newest_mount_id = 9 ;
-  struct buffer_head *d_bh ;
-  struct reiserfs_journal_header *jh ;
-  int valid_journal_header = 0 ;
-  int replay_count = 0 ;
-  int continue_replay = 1 ;
-  int ret ;
-  char b[BDEVNAME_SIZE];
-
-  cur_dblock = SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) ;
-  reiserfs_info (p_s_sb, "checking transaction log (%s)\n",
-	 bdevname(journal->j_dev_bd, b));
-  start = get_seconds();
-
-  /* step 1, read in the journal header block.  Check the transaction it says 
-  ** is the first unflushed, and if that transaction is not valid, 
-  ** replay is done
-  */
-  journal->j_header_bh = journal_bread(p_s_sb,
-					   SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) + 
-					   SB_ONDISK_JOURNAL_SIZE(p_s_sb));
-  if (!journal->j_header_bh) {
-    return 1 ;
-  }
-  jh = (struct reiserfs_journal_header *)(journal->j_header_bh->b_data) ;
-  if (le32_to_cpu(jh->j_first_unflushed_offset) >= 0 && 
-      le32_to_cpu(jh->j_first_unflushed_offset) < SB_ONDISK_JOURNAL_SIZE(p_s_sb) && 
-      le32_to_cpu(jh->j_last_flush_trans_id) > 0) {
-    oldest_start = SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) + 
-                       le32_to_cpu(jh->j_first_unflushed_offset) ;
-    oldest_trans_id = le32_to_cpu(jh->j_last_flush_trans_id) + 1;
-    newest_mount_id = le32_to_cpu(jh->j_mount_id);
-    reiserfs_debug(p_s_sb, REISERFS_DEBUG_CODE, "journal-1153: found in "
-                   "header: first_unflushed_offset %d, last_flushed_trans_id "
-		   "%lu", le32_to_cpu(jh->j_first_unflushed_offset),
-		   le32_to_cpu(jh->j_last_flush_trans_id)) ;
-    valid_journal_header = 1 ;
-
-    /* now, we try to read the first unflushed offset.  If it is not valid, 
-    ** there is nothing more we can do, and it makes no sense to read 
-    ** through the whole log.
-    */
-    d_bh = journal_bread(p_s_sb, SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) + le32_to_cpu(jh->j_first_unflushed_offset)) ;
-    ret = journal_transaction_is_valid(p_s_sb, d_bh, NULL, NULL) ;
-    if (!ret) {
-      continue_replay = 0 ;
-    }
-    brelse(d_bh) ;
-    goto start_log_replay;
-  }
-
-  if (continue_replay && bdev_read_only(p_s_sb->s_bdev)) {
-    reiserfs_warning (p_s_sb,
-		      "clm-2076: device is readonly, unable to replay log") ;
-    return -1 ;
-  }
-
-  /* ok, there are transactions that need to be replayed.  start with the first log block, find
-  ** all the valid transactions, and pick out the oldest.
-  */
-  while(continue_replay && cur_dblock < (SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) + SB_ONDISK_JOURNAL_SIZE(p_s_sb))) {
-    /* Note that it is required for blocksize of primary fs device and journal
-       device to be the same */
-    d_bh = reiserfs_breada(journal->j_dev_bd, cur_dblock, p_s_sb->s_blocksize,
-			   SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) + SB_ONDISK_JOURNAL_SIZE(p_s_sb)) ;
-    ret = journal_transaction_is_valid(p_s_sb, d_bh, &oldest_invalid_trans_id, &newest_mount_id) ;
-    if (ret == 1) {
-      desc = (struct reiserfs_journal_desc *)d_bh->b_data ;
-      if (oldest_start == 0) { /* init all oldest_ values */
-        oldest_trans_id = get_desc_trans_id(desc) ;
-	oldest_start = d_bh->b_blocknr ;
-	newest_mount_id = get_desc_mount_id(desc) ;
-	reiserfs_debug(p_s_sb, REISERFS_DEBUG_CODE, "journal-1179: Setting "
-	               "oldest_start to offset %llu, trans_id %lu",
-		       oldest_start - SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb), 
-		       oldest_trans_id) ;
-      } else if (oldest_trans_id > get_desc_trans_id(desc)) { 
-        /* one we just read was older */
-        oldest_trans_id = get_desc_trans_id(desc) ;
-	oldest_start = d_bh->b_blocknr ;
-	reiserfs_debug(p_s_sb, REISERFS_DEBUG_CODE, "journal-1180: Resetting "
-	               "oldest_start to offset %lu, trans_id %lu",
-			oldest_start - SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb), 
-			oldest_trans_id) ;
-      }
-      if (newest_mount_id < get_desc_mount_id(desc)) {
-        newest_mount_id = get_desc_mount_id(desc) ;
+static int journal_read(struct super_block *p_s_sb)
+{
+	struct reiserfs_journal *journal = SB_JOURNAL(p_s_sb);
+	struct reiserfs_journal_desc *desc;
+	unsigned long oldest_trans_id = 0;
+	unsigned long oldest_invalid_trans_id = 0;
+	time_t start;
+	unsigned long oldest_start = 0;
+	unsigned long cur_dblock = 0;
+	unsigned long newest_mount_id = 9;
+	struct buffer_head *d_bh;
+	struct reiserfs_journal_header *jh;
+	int valid_journal_header = 0;
+	int replay_count = 0;
+	int continue_replay = 1;
+	int ret;
+	char b[BDEVNAME_SIZE];
+
+	cur_dblock = SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb);
+	reiserfs_info(p_s_sb, "checking transaction log (%s)\n",
+		      bdevname(journal->j_dev_bd, b));
+	start = get_seconds();
+
+	/* step 1, read in the journal header block.  Check the transaction it says 
+	 ** is the first unflushed, and if that transaction is not valid, 
+	 ** replay is done
+	 */
+	journal->j_header_bh = journal_bread(p_s_sb,
+					     SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb)
+					     + SB_ONDISK_JOURNAL_SIZE(p_s_sb));
+	if (!journal->j_header_bh) {
+		return 1;
+	}
+	jh = (struct reiserfs_journal_header *)(journal->j_header_bh->b_data);
+	if (le32_to_cpu(jh->j_first_unflushed_offset) >= 0 &&
+	    le32_to_cpu(jh->j_first_unflushed_offset) <
+	    SB_ONDISK_JOURNAL_SIZE(p_s_sb)
+	    && le32_to_cpu(jh->j_last_flush_trans_id) > 0) {
+		oldest_start =
+		    SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) +
+		    le32_to_cpu(jh->j_first_unflushed_offset);
+		oldest_trans_id = le32_to_cpu(jh->j_last_flush_trans_id) + 1;
+		newest_mount_id = le32_to_cpu(jh->j_mount_id);
+		reiserfs_debug(p_s_sb, REISERFS_DEBUG_CODE,
+			       "journal-1153: found in "
+			       "header: first_unflushed_offset %d, last_flushed_trans_id "
+			       "%lu", le32_to_cpu(jh->j_first_unflushed_offset),
+			       le32_to_cpu(jh->j_last_flush_trans_id));
+		valid_journal_header = 1;
+
+		/* now, we try to read the first unflushed offset.  If it is not valid, 
+		 ** there is nothing more we can do, and it makes no sense to read 
+		 ** through the whole log.
+		 */
+		d_bh =
+		    journal_bread(p_s_sb,
+				  SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) +
+				  le32_to_cpu(jh->j_first_unflushed_offset));
+		ret = journal_transaction_is_valid(p_s_sb, d_bh, NULL, NULL);
+		if (!ret) {
+			continue_replay = 0;
+		}
+		brelse(d_bh);
+		goto start_log_replay;
+	}
+
+	if (continue_replay && bdev_read_only(p_s_sb->s_bdev)) {
+		reiserfs_warning(p_s_sb,
+				 "clm-2076: device is readonly, unable to replay log");
+		return -1;
+	}
+
+	/* ok, there are transactions that need to be replayed.  start with the first log block, find
+	 ** all the valid transactions, and pick out the oldest.
+	 */
+	while (continue_replay
+	       && cur_dblock <
+	       (SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) +
+		SB_ONDISK_JOURNAL_SIZE(p_s_sb))) {
+		/* Note that it is required for blocksize of primary fs device and journal
+		   device to be the same */
+		d_bh =
+		    reiserfs_breada(journal->j_dev_bd, cur_dblock,
+				    p_s_sb->s_blocksize,
+				    SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) +
+				    SB_ONDISK_JOURNAL_SIZE(p_s_sb));
+		ret =
+		    journal_transaction_is_valid(p_s_sb, d_bh,
+						 &oldest_invalid_trans_id,
+						 &newest_mount_id);
+		if (ret == 1) {
+			desc = (struct reiserfs_journal_desc *)d_bh->b_data;
+			if (oldest_start == 0) {	/* init all oldest_ values */
+				oldest_trans_id = get_desc_trans_id(desc);
+				oldest_start = d_bh->b_blocknr;
+				newest_mount_id = get_desc_mount_id(desc);
+				reiserfs_debug(p_s_sb, REISERFS_DEBUG_CODE,
+					       "journal-1179: Setting "
+					       "oldest_start to offset %llu, trans_id %lu",
+					       oldest_start -
+					       SB_ONDISK_JOURNAL_1st_BLOCK
+					       (p_s_sb), oldest_trans_id);
+			} else if (oldest_trans_id > get_desc_trans_id(desc)) {
+				/* one we just read was older */
+				oldest_trans_id = get_desc_trans_id(desc);
+				oldest_start = d_bh->b_blocknr;
+				reiserfs_debug(p_s_sb, REISERFS_DEBUG_CODE,
+					       "journal-1180: Resetting "
+					       "oldest_start to offset %lu, trans_id %lu",
+					       oldest_start -
+					       SB_ONDISK_JOURNAL_1st_BLOCK
+					       (p_s_sb), oldest_trans_id);
+			}
+			if (newest_mount_id < get_desc_mount_id(desc)) {
+				newest_mount_id = get_desc_mount_id(desc);
+				reiserfs_debug(p_s_sb, REISERFS_DEBUG_CODE,
+					       "journal-1299: Setting "
+					       "newest_mount_id to %d",
+					       get_desc_mount_id(desc));
+			}
+			cur_dblock += get_desc_trans_len(desc) + 2;
+		} else {
+			cur_dblock++;
+		}
+		brelse(d_bh);
+	}
+
+      start_log_replay:
+	cur_dblock = oldest_start;
+	if (oldest_trans_id) {
+		reiserfs_debug(p_s_sb, REISERFS_DEBUG_CODE,
+			       "journal-1206: Starting replay "
+			       "from offset %llu, trans_id %lu",
+			       cur_dblock - SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb),
+			       oldest_trans_id);
+
+	}
+	replay_count = 0;
+	while (continue_replay && oldest_trans_id > 0) {
+		ret =
+		    journal_read_transaction(p_s_sb, cur_dblock, oldest_start,
+					     oldest_trans_id, newest_mount_id);
+		if (ret < 0) {
+			return ret;
+		} else if (ret != 0) {
+			break;
+		}
+		cur_dblock =
+		    SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) + journal->j_start;
+		replay_count++;
+		if (cur_dblock == oldest_start)
+			break;
+	}
+
+	if (oldest_trans_id == 0) {
+		reiserfs_debug(p_s_sb, REISERFS_DEBUG_CODE,
+			       "journal-1225: No valid " "transactions found");
+	}
+	/* j_start does not get set correctly if we don't replay any transactions.
+	 ** if we had a valid journal_header, set j_start to the first unflushed transaction value,
+	 ** copy the trans_id from the header
+	 */
+	if (valid_journal_header && replay_count == 0) {
+		journal->j_start = le32_to_cpu(jh->j_first_unflushed_offset);
+		journal->j_trans_id =
+		    le32_to_cpu(jh->j_last_flush_trans_id) + 1;
+		journal->j_last_flush_trans_id =
+		    le32_to_cpu(jh->j_last_flush_trans_id);
+		journal->j_mount_id = le32_to_cpu(jh->j_mount_id) + 1;
+	} else {
+		journal->j_mount_id = newest_mount_id + 1;
+	}
 	reiserfs_debug(p_s_sb, REISERFS_DEBUG_CODE, "journal-1299: Setting "
-	              "newest_mount_id to %d", get_desc_mount_id(desc));
-      }
-      cur_dblock += get_desc_trans_len(desc) + 2 ;
-    } else {
-      cur_dblock++ ;
-    }
-    brelse(d_bh) ;
-  }
-
-start_log_replay:
-  cur_dblock = oldest_start ;
-  if (oldest_trans_id)  {
-    reiserfs_debug(p_s_sb, REISERFS_DEBUG_CODE, "journal-1206: Starting replay "
-                   "from offset %llu, trans_id %lu",
-		   cur_dblock - SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb), 
-		   oldest_trans_id) ;
-
-  }
-  replay_count = 0 ;
-  while(continue_replay && oldest_trans_id > 0) {
-    ret = journal_read_transaction(p_s_sb, cur_dblock, oldest_start, oldest_trans_id, newest_mount_id) ;
-    if (ret < 0) {
-      return ret ;
-    } else if (ret != 0) {
-      break ;
-    }
-    cur_dblock = SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) + journal->j_start ;
-    replay_count++ ;
-   if (cur_dblock == oldest_start)
-        break;
-  }
-
-  if (oldest_trans_id == 0) {
-    reiserfs_debug(p_s_sb, REISERFS_DEBUG_CODE, "journal-1225: No valid "
-                   "transactions found") ;
-  }
-  /* j_start does not get set correctly if we don't replay any transactions.
-  ** if we had a valid journal_header, set j_start to the first unflushed transaction value,
-  ** copy the trans_id from the header
-  */
-  if (valid_journal_header && replay_count == 0) { 
-    journal->j_start = le32_to_cpu(jh->j_first_unflushed_offset) ;
-    journal->j_trans_id = le32_to_cpu(jh->j_last_flush_trans_id) + 1;
-    journal->j_last_flush_trans_id = le32_to_cpu(jh->j_last_flush_trans_id) ;
-    journal->j_mount_id = le32_to_cpu(jh->j_mount_id) + 1;
-  } else {
-    journal->j_mount_id = newest_mount_id + 1 ;
-  }
-  reiserfs_debug(p_s_sb, REISERFS_DEBUG_CODE, "journal-1299: Setting "
-                 "newest_mount_id to %lu", journal->j_mount_id) ;
-  journal->j_first_unflushed_offset = journal->j_start ;
-  if (replay_count > 0) {
-    reiserfs_info (p_s_sb, "replayed %d transactions in %lu seconds\n",
-		   replay_count, get_seconds() - start) ;
-  }
-  if (!bdev_read_only(p_s_sb->s_bdev) && 
-       _update_journal_header_block(p_s_sb, journal->j_start,
-                                   journal->j_last_flush_trans_id))
-  {
-      /* replay failed, caller must call free_journal_ram and abort
-      ** the mount
-      */
-      return -1 ;
-  }
-  return 0 ;
+		       "newest_mount_id to %lu", journal->j_mount_id);
+	journal->j_first_unflushed_offset = journal->j_start;
+	if (replay_count > 0) {
+		reiserfs_info(p_s_sb,
+			      "replayed %d transactions in %lu seconds\n",
+			      replay_count, get_seconds() - start);
+	}
+	if (!bdev_read_only(p_s_sb->s_bdev) &&
+	    _update_journal_header_block(p_s_sb, journal->j_start,
+					 journal->j_last_flush_trans_id)) {
+		/* replay failed, caller must call free_journal_ram and abort
+		 ** the mount
+		 */
+		return -1;
+	}
+	return 0;
 }
 
 static struct reiserfs_journal_list *alloc_journal_list(struct super_block *s)
 {
-    struct reiserfs_journal_list *jl;
-retry:
-    jl = reiserfs_kmalloc(sizeof(struct reiserfs_journal_list), GFP_NOFS, s);
-    if (!jl) {
-	yield();
-	goto retry;
-    }
-    memset(jl, 0, sizeof(*jl));
-    INIT_LIST_HEAD(&jl->j_list);
-    INIT_LIST_HEAD(&jl->j_working_list);
-    INIT_LIST_HEAD(&jl->j_tail_bh_list);
-    INIT_LIST_HEAD(&jl->j_bh_list);
-    sema_init(&jl->j_commit_lock, 1);
-    SB_JOURNAL(s)->j_num_lists++;
-    get_journal_list(jl);
-    return jl;
-}
-
-static void journal_list_init(struct super_block *p_s_sb) {
-    SB_JOURNAL(p_s_sb)->j_current_jl = alloc_journal_list(p_s_sb);
-}
-
-static int release_journal_dev( struct super_block *super,
-				struct reiserfs_journal *journal )
-{
-    int result;
-    
-    result = 0;
-
-    if( journal -> j_dev_file != NULL ) {
-	result = filp_close( journal -> j_dev_file, NULL );
-	journal -> j_dev_file = NULL;
-	journal -> j_dev_bd = NULL;
-    } else if( journal -> j_dev_bd != NULL ) {
-	result = blkdev_put( journal -> j_dev_bd );
-	journal -> j_dev_bd = NULL;
-    }
-
-    if( result != 0 ) {
-	reiserfs_warning(super, "sh-457: release_journal_dev: Cannot release journal device: %i", result );
-    }
-    return result;
-}
-
-static int journal_init_dev( struct super_block *super, 
-			     struct reiserfs_journal *journal, 
-			     const char *jdev_name )
+	struct reiserfs_journal_list *jl;
+      retry:
+	jl = reiserfs_kmalloc(sizeof(struct reiserfs_journal_list), GFP_NOFS,
+			      s);
+	if (!jl) {
+		yield();
+		goto retry;
+	}
+	memset(jl, 0, sizeof(*jl));
+	INIT_LIST_HEAD(&jl->j_list);
+	INIT_LIST_HEAD(&jl->j_working_list);
+	INIT_LIST_HEAD(&jl->j_tail_bh_list);
+	INIT_LIST_HEAD(&jl->j_bh_list);
+	sema_init(&jl->j_commit_lock, 1);
+	SB_JOURNAL(s)->j_num_lists++;
+	get_journal_list(jl);
+	return jl;
+}
+
+static void journal_list_init(struct super_block *p_s_sb)
+{
+	SB_JOURNAL(p_s_sb)->j_current_jl = alloc_journal_list(p_s_sb);
+}
+
+static int release_journal_dev(struct super_block *super,
+			       struct reiserfs_journal *journal)
+{
+	int result;
+
+	result = 0;
+
+	if (journal->j_dev_file != NULL) {
+		result = filp_close(journal->j_dev_file, NULL);
+		journal->j_dev_file = NULL;
+		journal->j_dev_bd = NULL;
+	} else if (journal->j_dev_bd != NULL) {
+		result = blkdev_put(journal->j_dev_bd);
+		journal->j_dev_bd = NULL;
+	}
+
+	if (result != 0) {
+		reiserfs_warning(super,
+				 "sh-457: release_journal_dev: Cannot release journal device: %i",
+				 result);
+	}
+	return result;
+}
+
+static int journal_init_dev(struct super_block *super,
+			    struct reiserfs_journal *journal,
+			    const char *jdev_name)
 {
 	int result;
 	dev_t jdev;
@@ -2279,50 +2519,51 @@ static int journal_init_dev( struct supe
 
 	result = 0;
 
-	journal -> j_dev_bd = NULL;
-	journal -> j_dev_file = NULL;
-	jdev = SB_ONDISK_JOURNAL_DEVICE( super ) ?
-		new_decode_dev(SB_ONDISK_JOURNAL_DEVICE(super)) : super->s_dev;	
+	journal->j_dev_bd = NULL;
+	journal->j_dev_file = NULL;
+	jdev = SB_ONDISK_JOURNAL_DEVICE(super) ?
+	    new_decode_dev(SB_ONDISK_JOURNAL_DEVICE(super)) : super->s_dev;
 
 	if (bdev_read_only(super->s_bdev))
-	    blkdev_mode = FMODE_READ;
+		blkdev_mode = FMODE_READ;
 
 	/* there is no "jdev" option and journal is on separate device */
-	if( ( !jdev_name || !jdev_name[ 0 ] ) ) {
+	if ((!jdev_name || !jdev_name[0])) {
 		journal->j_dev_bd = open_by_devnum(jdev, blkdev_mode);
 		if (IS_ERR(journal->j_dev_bd)) {
 			result = PTR_ERR(journal->j_dev_bd);
 			journal->j_dev_bd = NULL;
-			reiserfs_warning (super, "sh-458: journal_init_dev: "
-					  "cannot init journal device '%s': %i",
-					  __bdevname(jdev, b), result );
+			reiserfs_warning(super, "sh-458: journal_init_dev: "
+					 "cannot init journal device '%s': %i",
+					 __bdevname(jdev, b), result);
 			return result;
 		} else if (jdev != super->s_dev)
 			set_blocksize(journal->j_dev_bd, super->s_blocksize);
 		return 0;
 	}
 
-	journal -> j_dev_file = filp_open( jdev_name, 0, 0 );
-	if( !IS_ERR( journal -> j_dev_file ) ) {
+	journal->j_dev_file = filp_open(jdev_name, 0, 0);
+	if (!IS_ERR(journal->j_dev_file)) {
 		struct inode *jdev_inode = journal->j_dev_file->f_mapping->host;
-		if( !S_ISBLK( jdev_inode -> i_mode ) ) {
+		if (!S_ISBLK(jdev_inode->i_mode)) {
 			reiserfs_warning(super, "journal_init_dev: '%s' is "
-					 "not a block device", jdev_name );
+					 "not a block device", jdev_name);
 			result = -ENOTBLK;
-			release_journal_dev( super, journal );
-		} else  {
+			release_journal_dev(super, journal);
+		} else {
 			/* ok */
 			journal->j_dev_bd = I_BDEV(jdev_inode);
 			set_blocksize(journal->j_dev_bd, super->s_blocksize);
-			reiserfs_info(super, "journal_init_dev: journal device: %s\n",
+			reiserfs_info(super,
+				      "journal_init_dev: journal device: %s\n",
 				      bdevname(journal->j_dev_bd, b));
 		}
 	} else {
-		result = PTR_ERR( journal -> j_dev_file );
-		journal -> j_dev_file = NULL;
-		reiserfs_warning (super,
-				  "journal_init_dev: Cannot open '%s': %i",
-				  jdev_name, result );
+		result = PTR_ERR(journal->j_dev_file);
+		journal->j_dev_file = NULL;
+		reiserfs_warning(super,
+				 "journal_init_dev: Cannot open '%s': %i",
+				 jdev_name, result);
 	}
 	return result;
 }
@@ -2330,193 +2571,214 @@ static int journal_init_dev( struct supe
 /*
 ** must be called once on fs mount.  calls journal_read for you
 */
-int journal_init(struct super_block *p_s_sb, const char * j_dev_name, int old_format, unsigned int commit_max_age) {
-    int num_cnodes = SB_ONDISK_JOURNAL_SIZE(p_s_sb) * 2 ;
-    struct buffer_head *bhjh;
-    struct reiserfs_super_block * rs;
-    struct reiserfs_journal_header *jh;
-    struct reiserfs_journal *journal;
-    struct reiserfs_journal_list *jl;
-    char b[BDEVNAME_SIZE];
-
-    journal = SB_JOURNAL(p_s_sb) = vmalloc(sizeof (struct reiserfs_journal)) ;
-    if (!journal) {
-	reiserfs_warning (p_s_sb, "journal-1256: unable to get memory for journal structure") ;
-	return 1 ;
-    }
-    memset(journal, 0, sizeof(struct reiserfs_journal)) ;
-    INIT_LIST_HEAD(&journal->j_bitmap_nodes) ;
-    INIT_LIST_HEAD (&journal->j_prealloc_list);
-    INIT_LIST_HEAD(&journal->j_working_list);
-    INIT_LIST_HEAD(&journal->j_journal_list);
-    journal->j_persistent_trans = 0;
-    if (reiserfs_allocate_list_bitmaps(p_s_sb,
-				       journal->j_list_bitmap,
- 				       SB_BMAP_NR(p_s_sb)))
-	goto free_and_return ;
-    allocate_bitmap_nodes(p_s_sb) ;
-
-    /* reserved for journal area support */
-    SB_JOURNAL_1st_RESERVED_BLOCK(p_s_sb) = (old_format ?
-					     REISERFS_OLD_DISK_OFFSET_IN_BYTES / p_s_sb->s_blocksize +
-					     SB_BMAP_NR(p_s_sb) + 1 :
-					     REISERFS_DISK_OFFSET_IN_BYTES / p_s_sb->s_blocksize + 2); 
-    
-    /* Sanity check to see is the standard journal fitting withing first bitmap
-       (actual for small blocksizes) */
-    if ( !SB_ONDISK_JOURNAL_DEVICE( p_s_sb ) &&
-         (SB_JOURNAL_1st_RESERVED_BLOCK(p_s_sb) + SB_ONDISK_JOURNAL_SIZE(p_s_sb) > p_s_sb->s_blocksize * 8) ) {
-	reiserfs_warning (p_s_sb, "journal-1393: journal does not fit for area "
-			  "addressed by first of bitmap blocks. It starts at "
-			  "%u and its size is %u. Block size %ld",
-			  SB_JOURNAL_1st_RESERVED_BLOCK(p_s_sb),
-			  SB_ONDISK_JOURNAL_SIZE(p_s_sb), p_s_sb->s_blocksize);
-	goto free_and_return;
-    }
-
-    if( journal_init_dev( p_s_sb, journal, j_dev_name ) != 0 ) {
-      reiserfs_warning (p_s_sb, "sh-462: unable to initialize jornal device");
-      goto free_and_return;
-    }
-
-     rs = SB_DISK_SUPER_BLOCK(p_s_sb);
-     
-     /* read journal header */
-     bhjh = journal_bread(p_s_sb,
-		   SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) + SB_ONDISK_JOURNAL_SIZE(p_s_sb));
-     if (!bhjh) {
-	 reiserfs_warning (p_s_sb, "sh-459: unable to read journal header");
-	 goto free_and_return;
-     }
-     jh = (struct reiserfs_journal_header *)(bhjh->b_data);
-     
-     /* make sure that journal matches to the super block */
-     if (is_reiserfs_jr(rs) && (le32_to_cpu(jh->jh_journal.jp_journal_magic) != sb_jp_journal_magic(rs))) {
-	 reiserfs_warning (p_s_sb, "sh-460: journal header magic %x "
-			   "(device %s) does not match to magic found in super "
-			   "block %x",
-			   jh->jh_journal.jp_journal_magic,
-			   bdevname( journal->j_dev_bd, b),
-			   sb_jp_journal_magic(rs));
-	 brelse (bhjh);
-	 goto free_and_return;
-  }
-     
-  journal->j_trans_max      = le32_to_cpu (jh->jh_journal.jp_journal_trans_max);
-  journal->j_max_batch      = le32_to_cpu (jh->jh_journal.jp_journal_max_batch);
-  journal->j_max_commit_age = le32_to_cpu (jh->jh_journal.jp_journal_max_commit_age);
-  journal->j_max_trans_age = JOURNAL_MAX_TRANS_AGE;
-
-  if (journal->j_trans_max) {
-    /* make sure these parameters are available, assign it if they are not */
-    __u32 initial = journal->j_trans_max;
-    __u32 ratio = 1;
-    
-    if (p_s_sb->s_blocksize < 4096)
-      ratio = 4096 / p_s_sb->s_blocksize;
-    
-    if (SB_ONDISK_JOURNAL_SIZE(p_s_sb)/journal->j_trans_max < JOURNAL_MIN_RATIO)
-      journal->j_trans_max = SB_ONDISK_JOURNAL_SIZE(p_s_sb) / JOURNAL_MIN_RATIO;
-    if (journal->j_trans_max > JOURNAL_TRANS_MAX_DEFAULT / ratio)
-      journal->j_trans_max = JOURNAL_TRANS_MAX_DEFAULT / ratio;
-    if (journal->j_trans_max < JOURNAL_TRANS_MIN_DEFAULT / ratio)
-      journal->j_trans_max = JOURNAL_TRANS_MIN_DEFAULT / ratio;
-    
-    if (journal->j_trans_max != initial)
-      reiserfs_warning (p_s_sb, "sh-461: journal_init: wrong transaction max size (%u). Changed to %u",
-	      initial, journal->j_trans_max);
-
-    journal->j_max_batch = journal->j_trans_max*
-      JOURNAL_MAX_BATCH_DEFAULT/JOURNAL_TRANS_MAX_DEFAULT;
-  }  
-  
-  if (!journal->j_trans_max) {
-    /*we have the file system was created by old version of mkreiserfs 
-      so this field contains zero value */
-    journal->j_trans_max      = JOURNAL_TRANS_MAX_DEFAULT ;
-    journal->j_max_batch      = JOURNAL_MAX_BATCH_DEFAULT ;
-    journal->j_max_commit_age = JOURNAL_MAX_COMMIT_AGE ;
-    
-    /* for blocksize >= 4096 - max transaction size is 1024. For block size < 4096
-       trans max size is decreased proportionally */
-    if (p_s_sb->s_blocksize < 4096) {
-      journal->j_trans_max /= (4096 / p_s_sb->s_blocksize) ;
-      journal->j_max_batch = (journal->j_trans_max) * 9 / 10 ;
-    }
-  }
-
-  journal->j_default_max_commit_age = journal->j_max_commit_age;
-
-  if (commit_max_age != 0) {
-      journal->j_max_commit_age = commit_max_age;
-      journal->j_max_trans_age = commit_max_age;
-  }
-
-  reiserfs_info (p_s_sb, "journal params: device %s, size %u, "
-		 "journal first block %u, max trans len %u, max batch %u, "
-		 "max commit age %u, max trans age %u\n",
-		 bdevname( journal->j_dev_bd, b),
-		 SB_ONDISK_JOURNAL_SIZE(p_s_sb),
-		 SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb),
-		 journal->j_trans_max,
-		 journal->j_max_batch,
-		 journal->j_max_commit_age,
-		 journal->j_max_trans_age);
-
-  brelse (bhjh);
-     
-  journal->j_list_bitmap_index = 0 ;
-  journal_list_init(p_s_sb) ;
-
-  memset(journal->j_list_hash_table, 0, JOURNAL_HASH_SIZE * sizeof(struct reiserfs_journal_cnode *)) ;
-
-  INIT_LIST_HEAD(&journal->j_dirty_buffers) ;
-  spin_lock_init(&journal->j_dirty_buffers_lock) ;
-
-  journal->j_start = 0 ;
-  journal->j_len = 0 ;
-  journal->j_len_alloc = 0 ;
-  atomic_set(&(journal->j_wcount), 0) ;
-  atomic_set(&(journal->j_async_throttle), 0) ;
-  journal->j_bcount = 0 ;
-  journal->j_trans_start_time = 0 ;
-  journal->j_last = NULL ;
-  journal->j_first = NULL ;
-  init_waitqueue_head(&(journal->j_join_wait)) ;
-  sema_init(&journal->j_lock, 1);
-  sema_init(&journal->j_flush_sem, 1);
-
-  journal->j_trans_id = 10 ;
-  journal->j_mount_id = 10 ;
-  journal->j_state = 0 ;
-  atomic_set(&(journal->j_jlock), 0) ;
-  journal->j_cnode_free_list = allocate_cnodes(num_cnodes) ;
-  journal->j_cnode_free_orig = journal->j_cnode_free_list ;
-  journal->j_cnode_free = journal->j_cnode_free_list ? num_cnodes : 0 ;
-  journal->j_cnode_used = 0 ;
-  journal->j_must_wait = 0 ;
-
-  init_journal_hash(p_s_sb) ;
-  jl = journal->j_current_jl;
-  jl->j_list_bitmap = get_list_bitmap(p_s_sb, jl);
-  if (!jl->j_list_bitmap) {
-    reiserfs_warning(p_s_sb, "journal-2005, get_list_bitmap failed for journal list 0") ;
-    goto free_and_return;
-  }
-  if (journal_read(p_s_sb) < 0) {
-    reiserfs_warning(p_s_sb, "Replay Failure, unable to mount") ;
-    goto free_and_return;
-  }
-
-  reiserfs_mounted_fs_count++ ;
-  if (reiserfs_mounted_fs_count <= 1)
-    commit_wq = create_workqueue("reiserfs");
-
-  INIT_WORK(&journal->j_work, flush_async_commits, p_s_sb);
-  return 0 ;
-free_and_return:
-  free_journal_ram(p_s_sb);
-  return 1;
+int journal_init(struct super_block *p_s_sb, const char *j_dev_name,
+		 int old_format, unsigned int commit_max_age)
+{
+	int num_cnodes = SB_ONDISK_JOURNAL_SIZE(p_s_sb) * 2;
+	struct buffer_head *bhjh;
+	struct reiserfs_super_block *rs;
+	struct reiserfs_journal_header *jh;
+	struct reiserfs_journal *journal;
+	struct reiserfs_journal_list *jl;
+	char b[BDEVNAME_SIZE];
+
+	journal = SB_JOURNAL(p_s_sb) = vmalloc(sizeof(struct reiserfs_journal));
+	if (!journal) {
+		reiserfs_warning(p_s_sb,
+				 "journal-1256: unable to get memory for journal structure");
+		return 1;
+	}
+	memset(journal, 0, sizeof(struct reiserfs_journal));
+	INIT_LIST_HEAD(&journal->j_bitmap_nodes);
+	INIT_LIST_HEAD(&journal->j_prealloc_list);
+	INIT_LIST_HEAD(&journal->j_working_list);
+	INIT_LIST_HEAD(&journal->j_journal_list);
+	journal->j_persistent_trans = 0;
+	if (reiserfs_allocate_list_bitmaps(p_s_sb,
+					   journal->j_list_bitmap,
+					   SB_BMAP_NR(p_s_sb)))
+		goto free_and_return;
+	allocate_bitmap_nodes(p_s_sb);
+
+	/* reserved for journal area support */
+	SB_JOURNAL_1st_RESERVED_BLOCK(p_s_sb) = (old_format ?
+						 REISERFS_OLD_DISK_OFFSET_IN_BYTES
+						 / p_s_sb->s_blocksize +
+						 SB_BMAP_NR(p_s_sb) +
+						 1 :
+						 REISERFS_DISK_OFFSET_IN_BYTES /
+						 p_s_sb->s_blocksize + 2);
+
+	/* Sanity check to see is the standard journal fitting withing first bitmap
+	   (actual for small blocksizes) */
+	if (!SB_ONDISK_JOURNAL_DEVICE(p_s_sb) &&
+	    (SB_JOURNAL_1st_RESERVED_BLOCK(p_s_sb) +
+	     SB_ONDISK_JOURNAL_SIZE(p_s_sb) > p_s_sb->s_blocksize * 8)) {
+		reiserfs_warning(p_s_sb,
+				 "journal-1393: journal does not fit for area "
+				 "addressed by first of bitmap blocks. It starts at "
+				 "%u and its size is %u. Block size %ld",
+				 SB_JOURNAL_1st_RESERVED_BLOCK(p_s_sb),
+				 SB_ONDISK_JOURNAL_SIZE(p_s_sb),
+				 p_s_sb->s_blocksize);
+		goto free_and_return;
+	}
+
+	if (journal_init_dev(p_s_sb, journal, j_dev_name) != 0) {
+		reiserfs_warning(p_s_sb,
+				 "sh-462: unable to initialize jornal device");
+		goto free_and_return;
+	}
+
+	rs = SB_DISK_SUPER_BLOCK(p_s_sb);
+
+	/* read journal header */
+	bhjh = journal_bread(p_s_sb,
+			     SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) +
+			     SB_ONDISK_JOURNAL_SIZE(p_s_sb));
+	if (!bhjh) {
+		reiserfs_warning(p_s_sb,
+				 "sh-459: unable to read journal header");
+		goto free_and_return;
+	}
+	jh = (struct reiserfs_journal_header *)(bhjh->b_data);
+
+	/* make sure that journal matches to the super block */
+	if (is_reiserfs_jr(rs)
+	    && (le32_to_cpu(jh->jh_journal.jp_journal_magic) !=
+		sb_jp_journal_magic(rs))) {
+		reiserfs_warning(p_s_sb,
+				 "sh-460: journal header magic %x "
+				 "(device %s) does not match to magic found in super "
+				 "block %x", jh->jh_journal.jp_journal_magic,
+				 bdevname(journal->j_dev_bd, b),
+				 sb_jp_journal_magic(rs));
+		brelse(bhjh);
+		goto free_and_return;
+	}
+
+	journal->j_trans_max = le32_to_cpu(jh->jh_journal.jp_journal_trans_max);
+	journal->j_max_batch = le32_to_cpu(jh->jh_journal.jp_journal_max_batch);
+	journal->j_max_commit_age =
+	    le32_to_cpu(jh->jh_journal.jp_journal_max_commit_age);
+	journal->j_max_trans_age = JOURNAL_MAX_TRANS_AGE;
+
+	if (journal->j_trans_max) {
+		/* make sure these parameters are available, assign it if they are not */
+		__u32 initial = journal->j_trans_max;
+		__u32 ratio = 1;
+
+		if (p_s_sb->s_blocksize < 4096)
+			ratio = 4096 / p_s_sb->s_blocksize;
+
+		if (SB_ONDISK_JOURNAL_SIZE(p_s_sb) / journal->j_trans_max <
+		    JOURNAL_MIN_RATIO)
+			journal->j_trans_max =
+			    SB_ONDISK_JOURNAL_SIZE(p_s_sb) / JOURNAL_MIN_RATIO;
+		if (journal->j_trans_max > JOURNAL_TRANS_MAX_DEFAULT / ratio)
+			journal->j_trans_max =
+			    JOURNAL_TRANS_MAX_DEFAULT / ratio;
+		if (journal->j_trans_max < JOURNAL_TRANS_MIN_DEFAULT / ratio)
+			journal->j_trans_max =
+			    JOURNAL_TRANS_MIN_DEFAULT / ratio;
+
+		if (journal->j_trans_max != initial)
+			reiserfs_warning(p_s_sb,
+					 "sh-461: journal_init: wrong transaction max size (%u). Changed to %u",
+					 initial, journal->j_trans_max);
+
+		journal->j_max_batch = journal->j_trans_max *
+		    JOURNAL_MAX_BATCH_DEFAULT / JOURNAL_TRANS_MAX_DEFAULT;
+	}
+
+	if (!journal->j_trans_max) {
+		/*we have the file system was created by old version of mkreiserfs 
+		   so this field contains zero value */
+		journal->j_trans_max = JOURNAL_TRANS_MAX_DEFAULT;
+		journal->j_max_batch = JOURNAL_MAX_BATCH_DEFAULT;
+		journal->j_max_commit_age = JOURNAL_MAX_COMMIT_AGE;
+
+		/* for blocksize >= 4096 - max transaction size is 1024. For block size < 4096
+		   trans max size is decreased proportionally */
+		if (p_s_sb->s_blocksize < 4096) {
+			journal->j_trans_max /= (4096 / p_s_sb->s_blocksize);
+			journal->j_max_batch = (journal->j_trans_max) * 9 / 10;
+		}
+	}
+
+	journal->j_default_max_commit_age = journal->j_max_commit_age;
+
+	if (commit_max_age != 0) {
+		journal->j_max_commit_age = commit_max_age;
+		journal->j_max_trans_age = commit_max_age;
+	}
+
+	reiserfs_info(p_s_sb, "journal params: device %s, size %u, "
+		      "journal first block %u, max trans len %u, max batch %u, "
+		      "max commit age %u, max trans age %u\n",
+		      bdevname(journal->j_dev_bd, b),
+		      SB_ONDISK_JOURNAL_SIZE(p_s_sb),
+		      SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb),
+		      journal->j_trans_max,
+		      journal->j_max_batch,
+		      journal->j_max_commit_age, journal->j_max_trans_age);
+
+	brelse(bhjh);
+
+	journal->j_list_bitmap_index = 0;
+	journal_list_init(p_s_sb);
+
+	memset(journal->j_list_hash_table, 0,
+	       JOURNAL_HASH_SIZE * sizeof(struct reiserfs_journal_cnode *));
+
+	INIT_LIST_HEAD(&journal->j_dirty_buffers);
+	spin_lock_init(&journal->j_dirty_buffers_lock);
+
+	journal->j_start = 0;
+	journal->j_len = 0;
+	journal->j_len_alloc = 0;
+	atomic_set(&(journal->j_wcount), 0);
+	atomic_set(&(journal->j_async_throttle), 0);
+	journal->j_bcount = 0;
+	journal->j_trans_start_time = 0;
+	journal->j_last = NULL;
+	journal->j_first = NULL;
+	init_waitqueue_head(&(journal->j_join_wait));
+	sema_init(&journal->j_lock, 1);
+	sema_init(&journal->j_flush_sem, 1);
+
+	journal->j_trans_id = 10;
+	journal->j_mount_id = 10;
+	journal->j_state = 0;
+	atomic_set(&(journal->j_jlock), 0);
+	journal->j_cnode_free_list = allocate_cnodes(num_cnodes);
+	journal->j_cnode_free_orig = journal->j_cnode_free_list;
+	journal->j_cnode_free = journal->j_cnode_free_list ? num_cnodes : 0;
+	journal->j_cnode_used = 0;
+	journal->j_must_wait = 0;
+
+	init_journal_hash(p_s_sb);
+	jl = journal->j_current_jl;
+	jl->j_list_bitmap = get_list_bitmap(p_s_sb, jl);
+	if (!jl->j_list_bitmap) {
+		reiserfs_warning(p_s_sb,
+				 "journal-2005, get_list_bitmap failed for journal list 0");
+		goto free_and_return;
+	}
+	if (journal_read(p_s_sb) < 0) {
+		reiserfs_warning(p_s_sb, "Replay Failure, unable to mount");
+		goto free_and_return;
+	}
+
+	reiserfs_mounted_fs_count++;
+	if (reiserfs_mounted_fs_count <= 1)
+		commit_wq = create_workqueue("reiserfs");
+
+	INIT_WORK(&journal->j_work, flush_async_commits, p_s_sb);
+	return 0;
+      free_and_return:
+	free_journal_ram(p_s_sb);
+	return 1;
 }
 
 /*
@@ -2524,96 +2786,102 @@ free_and_return:
 ** be used by delete to make sure they don't write more than can fit inside a single
 ** transaction
 */
-int journal_transaction_should_end(struct reiserfs_transaction_handle *th, int new_alloc) {
-  struct reiserfs_journal *journal = SB_JOURNAL (th->t_super);
-  time_t now = get_seconds() ;
-  /* cannot restart while nested */
-  BUG_ON (!th->t_trans_id);
-  if (th->t_refcount > 1)
-    return 0 ;
-  if ( journal->j_must_wait > 0 ||
-       (journal->j_len_alloc + new_alloc) >= journal->j_max_batch ||
-       atomic_read(&(journal->j_jlock)) ||
-      (now - journal->j_trans_start_time) > journal->j_max_trans_age ||
-       journal->j_cnode_free < (journal->j_trans_max * 3)) {
-    return 1 ;
-  }
-  return 0 ;
+int journal_transaction_should_end(struct reiserfs_transaction_handle *th,
+				   int new_alloc)
+{
+	struct reiserfs_journal *journal = SB_JOURNAL(th->t_super);
+	time_t now = get_seconds();
+	/* cannot restart while nested */
+	BUG_ON(!th->t_trans_id);
+	if (th->t_refcount > 1)
+		return 0;
+	if (journal->j_must_wait > 0 ||
+	    (journal->j_len_alloc + new_alloc) >= journal->j_max_batch ||
+	    atomic_read(&(journal->j_jlock)) ||
+	    (now - journal->j_trans_start_time) > journal->j_max_trans_age ||
+	    journal->j_cnode_free < (journal->j_trans_max * 3)) {
+		return 1;
+	}
+	return 0;
 }
 
 /* this must be called inside a transaction, and requires the 
 ** kernel_lock to be held
 */
-void reiserfs_block_writes(struct reiserfs_transaction_handle *th) {
-    struct reiserfs_journal *journal = SB_JOURNAL (th->t_super);
-    BUG_ON (!th->t_trans_id);
-    journal->j_must_wait = 1 ;
-    set_bit(J_WRITERS_BLOCKED, &journal->j_state) ;
-    return ;
+void reiserfs_block_writes(struct reiserfs_transaction_handle *th)
+{
+	struct reiserfs_journal *journal = SB_JOURNAL(th->t_super);
+	BUG_ON(!th->t_trans_id);
+	journal->j_must_wait = 1;
+	set_bit(J_WRITERS_BLOCKED, &journal->j_state);
+	return;
 }
 
 /* this must be called without a transaction started, and does not
 ** require BKL
 */
-void reiserfs_allow_writes(struct super_block *s) {
-    struct reiserfs_journal *journal = SB_JOURNAL (s);
-    clear_bit(J_WRITERS_BLOCKED, &journal->j_state) ;
-    wake_up(&journal->j_join_wait) ;
+void reiserfs_allow_writes(struct super_block *s)
+{
+	struct reiserfs_journal *journal = SB_JOURNAL(s);
+	clear_bit(J_WRITERS_BLOCKED, &journal->j_state);
+	wake_up(&journal->j_join_wait);
 }
 
 /* this must be called without a transaction started, and does not
 ** require BKL
 */
-void reiserfs_wait_on_write_block(struct super_block *s) {
-    struct reiserfs_journal *journal = SB_JOURNAL (s);
-    wait_event(journal->j_join_wait,
-               !test_bit(J_WRITERS_BLOCKED, &journal->j_state)) ;
-}
-
-static void queue_log_writer(struct super_block *s) {
-    wait_queue_t wait;
-    struct reiserfs_journal *journal = SB_JOURNAL (s);
-    set_bit(J_WRITERS_QUEUED, &journal->j_state);
-
-    /*
-     * we don't want to use wait_event here because
-     * we only want to wait once.
-     */
-    init_waitqueue_entry(&wait, current);
-    add_wait_queue(&journal->j_join_wait, &wait);
-    set_current_state(TASK_UNINTERRUPTIBLE);
-    if (test_bit(J_WRITERS_QUEUED, &journal->j_state))
-        schedule();
-    current->state = TASK_RUNNING;
-    remove_wait_queue(&journal->j_join_wait, &wait);
-}
-
-static void wake_queued_writers(struct super_block *s) {
-    struct reiserfs_journal *journal = SB_JOURNAL (s);
-    if (test_and_clear_bit(J_WRITERS_QUEUED, &journal->j_state))
-        wake_up(&journal->j_join_wait);
-}
-
-static void let_transaction_grow(struct super_block *sb,
-                                 unsigned long trans_id)
-{
-    struct reiserfs_journal *journal = SB_JOURNAL (sb);
-    unsigned long bcount = journal->j_bcount;
-    while(1) {
+void reiserfs_wait_on_write_block(struct super_block *s)
+{
+	struct reiserfs_journal *journal = SB_JOURNAL(s);
+	wait_event(journal->j_join_wait,
+		   !test_bit(J_WRITERS_BLOCKED, &journal->j_state));
+}
+
+static void queue_log_writer(struct super_block *s)
+{
+	wait_queue_t wait;
+	struct reiserfs_journal *journal = SB_JOURNAL(s);
+	set_bit(J_WRITERS_QUEUED, &journal->j_state);
+
+	/*
+	 * we don't want to use wait_event here because
+	 * we only want to wait once.
+	 */
+	init_waitqueue_entry(&wait, current);
+	add_wait_queue(&journal->j_join_wait, &wait);
 	set_current_state(TASK_UNINTERRUPTIBLE);
-	schedule_timeout(1);
-	journal->j_current_jl->j_state |= LIST_COMMIT_PENDING;
-        while ((atomic_read(&journal->j_wcount) > 0 ||
-	        atomic_read(&journal->j_jlock)) &&
-	       journal->j_trans_id == trans_id) {
-	    queue_log_writer(sb);
-	}
-	if (journal->j_trans_id != trans_id)
-	    break;
-	if (bcount == journal->j_bcount)
-	    break;
-	bcount = journal->j_bcount;
-    }
+	if (test_bit(J_WRITERS_QUEUED, &journal->j_state))
+		schedule();
+	current->state = TASK_RUNNING;
+	remove_wait_queue(&journal->j_join_wait, &wait);
+}
+
+static void wake_queued_writers(struct super_block *s)
+{
+	struct reiserfs_journal *journal = SB_JOURNAL(s);
+	if (test_and_clear_bit(J_WRITERS_QUEUED, &journal->j_state))
+		wake_up(&journal->j_join_wait);
+}
+
+static void let_transaction_grow(struct super_block *sb, unsigned long trans_id)
+{
+	struct reiserfs_journal *journal = SB_JOURNAL(sb);
+	unsigned long bcount = journal->j_bcount;
+	while (1) {
+		set_current_state(TASK_UNINTERRUPTIBLE);
+		schedule_timeout(1);
+		journal->j_current_jl->j_state |= LIST_COMMIT_PENDING;
+		while ((atomic_read(&journal->j_wcount) > 0 ||
+			atomic_read(&journal->j_jlock)) &&
+		       journal->j_trans_id == trans_id) {
+			queue_log_writer(sb);
+		}
+		if (journal->j_trans_id != trans_id)
+			break;
+		if (bcount == journal->j_bcount)
+			break;
+		bcount = journal->j_bcount;
+	}
 }
 
 /* join == true if you must join an existing transaction.
@@ -2622,221 +2890,244 @@ static void let_transaction_grow(struct 
 ** this will block until the transaction is joinable.  send the number of blocks you
 ** expect to use in nblocks.
 */
-static int do_journal_begin_r(struct reiserfs_transaction_handle *th, struct super_block * p_s_sb,unsigned long nblocks,int join) {
-  time_t now = get_seconds() ;
-  int old_trans_id  ;
-  struct reiserfs_journal *journal = SB_JOURNAL(p_s_sb);
-  struct reiserfs_transaction_handle myth;
-  int sched_count = 0;
-  int retval;
-
-  reiserfs_check_lock_depth(p_s_sb, "journal_begin") ;
-
-  PROC_INFO_INC( p_s_sb, journal.journal_being );
-  /* set here for journal_join */
-  th->t_refcount = 1;
-  th->t_super = p_s_sb ;
-
-relock:
-  lock_journal(p_s_sb) ;
-  if (join != JBEGIN_ABORT && reiserfs_is_journal_aborted (journal)) {
-    unlock_journal (p_s_sb);
-    retval = journal->j_errno;
-    goto out_fail;
-  }
-  journal->j_bcount++;
-
-  if (test_bit(J_WRITERS_BLOCKED, &journal->j_state)) {
-    unlock_journal(p_s_sb) ;
-    reiserfs_wait_on_write_block(p_s_sb) ;
-    PROC_INFO_INC( p_s_sb, journal.journal_relock_writers );
-    goto relock ;
-  }
-  now = get_seconds();
-
-  /* if there is no room in the journal OR
-  ** if this transaction is too old, and we weren't called joinable, wait for it to finish before beginning 
-  ** we don't sleep if there aren't other writers
-  */
-
-  if ( (!join && journal->j_must_wait > 0) ||
-     ( !join && (journal->j_len_alloc + nblocks + 2) >= journal->j_max_batch) ||
-     (!join && atomic_read(&journal->j_wcount) > 0 && journal->j_trans_start_time > 0 &&
-      (now - journal->j_trans_start_time) > journal->j_max_trans_age) ||
-     (!join && atomic_read(&journal->j_jlock)) ||
-     (!join && journal->j_cnode_free < (journal->j_trans_max * 3))) {
-
-    old_trans_id = journal->j_trans_id;
-    unlock_journal(p_s_sb) ; /* allow others to finish this transaction */
-
-    if (!join && (journal->j_len_alloc + nblocks + 2) >=
-        journal->j_max_batch &&
-	((journal->j_len + nblocks + 2) * 100) < (journal->j_len_alloc * 75))
-    {
-	if (atomic_read(&journal->j_wcount) > 10) {
-	    sched_count++;
-	    queue_log_writer(p_s_sb);
-	    goto relock;
-	}
-    }
-    /* don't mess with joining the transaction if all we have to do is
-     * wait for someone else to do a commit
-     */
-    if (atomic_read(&journal->j_jlock)) {
-	while (journal->j_trans_id == old_trans_id &&
-	       atomic_read(&journal->j_jlock)) {
-	    queue_log_writer(p_s_sb);
-        }
-	goto relock;
-    }
-    retval = journal_join(&myth, p_s_sb, 1) ;
-    if (retval)
-        goto out_fail;
-
-    /* someone might have ended the transaction while we joined */
-    if (old_trans_id != journal->j_trans_id) {
-        retval = do_journal_end(&myth, p_s_sb, 1, 0) ;
-    } else {
-        retval = do_journal_end(&myth, p_s_sb, 1, COMMIT_NOW) ;
-    }
-
-    if (retval)
-        goto out_fail;
-
-    PROC_INFO_INC( p_s_sb, journal.journal_relock_wcount );
-    goto relock ;
-  }
-  /* we are the first writer, set trans_id */
-  if (journal->j_trans_start_time == 0) {
-    journal->j_trans_start_time = get_seconds();
-  }
-  atomic_inc(&(journal->j_wcount)) ;
-  journal->j_len_alloc += nblocks ;
-  th->t_blocks_logged = 0 ;
-  th->t_blocks_allocated = nblocks ;
-  th->t_trans_id = journal->j_trans_id ;
-  unlock_journal(p_s_sb) ;
-  INIT_LIST_HEAD (&th->t_list);
-  return 0 ;
-
-out_fail:
-  memset (th, 0, sizeof (*th));
-  /* Re-set th->t_super, so we can properly keep track of how many
-   * persistent transactions there are. We need to do this so if this
-   * call is part of a failed restart_transaction, we can free it later */
-  th->t_super = p_s_sb;
-  return retval;
-}
-
-struct reiserfs_transaction_handle *
-reiserfs_persistent_transaction(struct super_block *s, int nblocks) {
-    int ret ;
-    struct reiserfs_transaction_handle *th ;
-
-    /* if we're nesting into an existing transaction.  It will be
-    ** persistent on its own
-    */
-    if (reiserfs_transaction_running(s)) {
-        th = current->journal_info ;
-	th->t_refcount++ ;
-	if (th->t_refcount < 2) {
-	    BUG() ;
-	}
-	return th ;
-    }
-    th = reiserfs_kmalloc(sizeof(struct reiserfs_transaction_handle), GFP_NOFS, s) ;
-    if (!th)
-       return NULL;
-    ret = journal_begin(th, s, nblocks) ;
-    if (ret) {
-	reiserfs_kfree(th, sizeof(struct reiserfs_transaction_handle), s) ;
-        return NULL;
-    }
-
-    SB_JOURNAL(s)->j_persistent_trans++;
-    return th ;
-}
-
-int
-reiserfs_end_persistent_transaction(struct reiserfs_transaction_handle *th) {
-    struct super_block *s = th->t_super;
-    int ret = 0;
-    if (th->t_trans_id)
-        ret = journal_end(th, th->t_super, th->t_blocks_allocated);
-    else
-        ret = -EIO;
-    if (th->t_refcount == 0) {
-        SB_JOURNAL(s)->j_persistent_trans--;
-	reiserfs_kfree(th, sizeof(struct reiserfs_transaction_handle), s) ;
-    }
-    return ret;
-}
-
-static int journal_join(struct reiserfs_transaction_handle *th, struct super_block *p_s_sb, unsigned long nblocks) {
-  struct reiserfs_transaction_handle *cur_th = current->journal_info;
-
-  /* this keeps do_journal_end from NULLing out the current->journal_info
-  ** pointer
-  */
-  th->t_handle_save = cur_th ;
-  if (cur_th && cur_th->t_refcount > 1) {
-      BUG() ;
-  }
-  return do_journal_begin_r(th, p_s_sb, nblocks, JBEGIN_JOIN) ;
-}
-
-int journal_join_abort(struct reiserfs_transaction_handle *th, struct super_block *p_s_sb, unsigned long nblocks) {
-  struct reiserfs_transaction_handle *cur_th = current->journal_info;
-
-  /* this keeps do_journal_end from NULLing out the current->journal_info
-  ** pointer
-  */
-  th->t_handle_save = cur_th ;
-  if (cur_th && cur_th->t_refcount > 1) {
-      BUG() ;
-  }
-  return do_journal_begin_r(th, p_s_sb, nblocks, JBEGIN_ABORT) ;
-}
-
-int journal_begin(struct reiserfs_transaction_handle *th, struct super_block  * p_s_sb, unsigned long nblocks) {
-    struct reiserfs_transaction_handle *cur_th = current->journal_info ;
-    int ret ;
-
-    th->t_handle_save = NULL ;
-    if (cur_th) {
-	/* we are nesting into the current transaction */
-	if (cur_th->t_super == p_s_sb) {
-              BUG_ON (!cur_th->t_refcount);
-	      cur_th->t_refcount++ ;
-	      memcpy(th, cur_th, sizeof(*th));
-	      if (th->t_refcount <= 1)
-		      reiserfs_warning (p_s_sb, "BAD: refcount <= 1, but journal_info != 0");
-	      return 0;
+static int do_journal_begin_r(struct reiserfs_transaction_handle *th,
+			      struct super_block *p_s_sb, unsigned long nblocks,
+			      int join)
+{
+	time_t now = get_seconds();
+	int old_trans_id;
+	struct reiserfs_journal *journal = SB_JOURNAL(p_s_sb);
+	struct reiserfs_transaction_handle myth;
+	int sched_count = 0;
+	int retval;
+
+	reiserfs_check_lock_depth(p_s_sb, "journal_begin");
+	if (nblocks > journal->j_trans_max)
+		BUG();
+
+	PROC_INFO_INC(p_s_sb, journal.journal_being);
+	/* set here for journal_join */
+	th->t_refcount = 1;
+	th->t_super = p_s_sb;
+
+      relock:
+	lock_journal(p_s_sb);
+	if (join != JBEGIN_ABORT && reiserfs_is_journal_aborted(journal)) {
+		unlock_journal(p_s_sb);
+		retval = journal->j_errno;
+		goto out_fail;
+	}
+	journal->j_bcount++;
+
+	if (test_bit(J_WRITERS_BLOCKED, &journal->j_state)) {
+		unlock_journal(p_s_sb);
+		reiserfs_wait_on_write_block(p_s_sb);
+		PROC_INFO_INC(p_s_sb, journal.journal_relock_writers);
+		goto relock;
+	}
+	now = get_seconds();
+
+	/* if there is no room in the journal OR
+	 ** if this transaction is too old, and we weren't called joinable, wait for it to finish before beginning 
+	 ** we don't sleep if there aren't other writers
+	 */
+
+	if ((!join && journal->j_must_wait > 0) ||
+	    (!join
+	     && (journal->j_len_alloc + nblocks + 2) >= journal->j_max_batch)
+	    || (!join && atomic_read(&journal->j_wcount) > 0
+		&& journal->j_trans_start_time > 0
+		&& (now - journal->j_trans_start_time) >
+		journal->j_max_trans_age) || (!join
+					      && atomic_read(&journal->j_jlock))
+	    || (!join && journal->j_cnode_free < (journal->j_trans_max * 3))) {
+
+		old_trans_id = journal->j_trans_id;
+		unlock_journal(p_s_sb);	/* allow others to finish this transaction */
+
+		if (!join && (journal->j_len_alloc + nblocks + 2) >=
+		    journal->j_max_batch &&
+		    ((journal->j_len + nblocks + 2) * 100) <
+		    (journal->j_len_alloc * 75)) {
+			if (atomic_read(&journal->j_wcount) > 10) {
+				sched_count++;
+				queue_log_writer(p_s_sb);
+				goto relock;
+			}
+		}
+		/* don't mess with joining the transaction if all we have to do is
+		 * wait for someone else to do a commit
+		 */
+		if (atomic_read(&journal->j_jlock)) {
+			while (journal->j_trans_id == old_trans_id &&
+			       atomic_read(&journal->j_jlock)) {
+				queue_log_writer(p_s_sb);
+			}
+			goto relock;
+		}
+		retval = journal_join(&myth, p_s_sb, 1);
+		if (retval)
+			goto out_fail;
+
+		/* someone might have ended the transaction while we joined */
+		if (old_trans_id != journal->j_trans_id) {
+			retval = do_journal_end(&myth, p_s_sb, 1, 0);
+		} else {
+			retval = do_journal_end(&myth, p_s_sb, 1, COMMIT_NOW);
+		}
+
+		if (retval)
+			goto out_fail;
+
+		PROC_INFO_INC(p_s_sb, journal.journal_relock_wcount);
+		goto relock;
+	}
+	/* we are the first writer, set trans_id */
+	if (journal->j_trans_start_time == 0) {
+		journal->j_trans_start_time = get_seconds();
+	}
+	atomic_inc(&(journal->j_wcount));
+	journal->j_len_alloc += nblocks;
+	th->t_blocks_logged = 0;
+	th->t_blocks_allocated = nblocks;
+	th->t_trans_id = journal->j_trans_id;
+	unlock_journal(p_s_sb);
+	INIT_LIST_HEAD(&th->t_list);
+	get_fs_excl();
+	return 0;
+
+      out_fail:
+	memset(th, 0, sizeof(*th));
+	/* Re-set th->t_super, so we can properly keep track of how many
+	 * persistent transactions there are. We need to do this so if this
+	 * call is part of a failed restart_transaction, we can free it later */
+	th->t_super = p_s_sb;
+	return retval;
+}
+
+struct reiserfs_transaction_handle *reiserfs_persistent_transaction(struct
+								    super_block
+								    *s,
+								    int nblocks)
+{
+	int ret;
+	struct reiserfs_transaction_handle *th;
+
+	/* if we're nesting into an existing transaction.  It will be
+	 ** persistent on its own
+	 */
+	if (reiserfs_transaction_running(s)) {
+		th = current->journal_info;
+		th->t_refcount++;
+		if (th->t_refcount < 2) {
+			BUG();
+		}
+		return th;
+	}
+	th = reiserfs_kmalloc(sizeof(struct reiserfs_transaction_handle),
+			      GFP_NOFS, s);
+	if (!th)
+		return NULL;
+	ret = journal_begin(th, s, nblocks);
+	if (ret) {
+		reiserfs_kfree(th, sizeof(struct reiserfs_transaction_handle),
+			       s);
+		return NULL;
+	}
+
+	SB_JOURNAL(s)->j_persistent_trans++;
+	return th;
+}
+
+int reiserfs_end_persistent_transaction(struct reiserfs_transaction_handle *th)
+{
+	struct super_block *s = th->t_super;
+	int ret = 0;
+	if (th->t_trans_id)
+		ret = journal_end(th, th->t_super, th->t_blocks_allocated);
+	else
+		ret = -EIO;
+	if (th->t_refcount == 0) {
+		SB_JOURNAL(s)->j_persistent_trans--;
+		reiserfs_kfree(th, sizeof(struct reiserfs_transaction_handle),
+			       s);
+	}
+	return ret;
+}
+
+static int journal_join(struct reiserfs_transaction_handle *th,
+			struct super_block *p_s_sb, unsigned long nblocks)
+{
+	struct reiserfs_transaction_handle *cur_th = current->journal_info;
+
+	/* this keeps do_journal_end from NULLing out the current->journal_info
+	 ** pointer
+	 */
+	th->t_handle_save = cur_th;
+	if (cur_th && cur_th->t_refcount > 1) {
+		BUG();
+	}
+	return do_journal_begin_r(th, p_s_sb, nblocks, JBEGIN_JOIN);
+}
+
+int journal_join_abort(struct reiserfs_transaction_handle *th,
+		       struct super_block *p_s_sb, unsigned long nblocks)
+{
+	struct reiserfs_transaction_handle *cur_th = current->journal_info;
+
+	/* this keeps do_journal_end from NULLing out the current->journal_info
+	 ** pointer
+	 */
+	th->t_handle_save = cur_th;
+	if (cur_th && cur_th->t_refcount > 1) {
+		BUG();
+	}
+	return do_journal_begin_r(th, p_s_sb, nblocks, JBEGIN_ABORT);
+}
+
+int journal_begin(struct reiserfs_transaction_handle *th,
+		  struct super_block *p_s_sb, unsigned long nblocks)
+{
+	struct reiserfs_transaction_handle *cur_th = current->journal_info;
+	int ret;
+
+	th->t_handle_save = NULL;
+	if (cur_th) {
+		/* we are nesting into the current transaction */
+		if (cur_th->t_super == p_s_sb) {
+			BUG_ON(!cur_th->t_refcount);
+			cur_th->t_refcount++;
+			memcpy(th, cur_th, sizeof(*th));
+			if (th->t_refcount <= 1)
+				reiserfs_warning(p_s_sb,
+						 "BAD: refcount <= 1, but journal_info != 0");
+			return 0;
+		} else {
+			/* we've ended up with a handle from a different filesystem.
+			 ** save it and restore on journal_end.  This should never
+			 ** really happen...
+			 */
+			reiserfs_warning(p_s_sb,
+					 "clm-2100: nesting info a different FS");
+			th->t_handle_save = current->journal_info;
+			current->journal_info = th;
+		}
 	} else {
-	    /* we've ended up with a handle from a different filesystem.
-	    ** save it and restore on journal_end.  This should never
-	    ** really happen...
-	    */
-	    reiserfs_warning(p_s_sb, "clm-2100: nesting info a different FS") ;
-	    th->t_handle_save = current->journal_info ;
-	    current->journal_info = th;
+		current->journal_info = th;
 	}
-    } else {
-	current->journal_info = th;
-    }
-    ret = do_journal_begin_r(th, p_s_sb, nblocks, JBEGIN_REG) ;
-    if (current->journal_info != th)
-        BUG() ;
-
-    /* I guess this boils down to being the reciprocal of clm-2100 above.
-     * If do_journal_begin_r fails, we need to put it back, since journal_end
-     * won't be called to do it. */
-    if (ret)
-        current->journal_info = th->t_handle_save;
-    else
-        BUG_ON (!th->t_refcount);
+	ret = do_journal_begin_r(th, p_s_sb, nblocks, JBEGIN_REG);
+	if (current->journal_info != th)
+		BUG();
+
+	/* I guess this boils down to being the reciprocal of clm-2100 above.
+	 * If do_journal_begin_r fails, we need to put it back, since journal_end
+	 * won't be called to do it. */
+	if (ret)
+		current->journal_info = th->t_handle_save;
+	else
+		BUG_ON(!th->t_refcount);
 
-    return ret ;
+	return ret;
 }
 
 /*
@@ -2848,129 +3139,140 @@ int journal_begin(struct reiserfs_transa
 ** 
 ** if j_len, is bigger than j_len_alloc, it pushes j_len_alloc to 10 + j_len.
 */
-int journal_mark_dirty(struct reiserfs_transaction_handle *th, struct super_block *p_s_sb, struct buffer_head *bh) {
-  struct reiserfs_journal *journal = SB_JOURNAL (p_s_sb);
-  struct reiserfs_journal_cnode *cn = NULL;
-  int count_already_incd = 0 ;
-  int prepared = 0 ;
-  BUG_ON (!th->t_trans_id);
-
-  PROC_INFO_INC( p_s_sb, journal.mark_dirty );
-  if (th->t_trans_id != journal->j_trans_id) {
-    reiserfs_panic(th->t_super, "journal-1577: handle trans id %ld != current trans id %ld\n", 
-                   th->t_trans_id, journal->j_trans_id);
-  }
-
-  p_s_sb->s_dirt = 1;
-
-  prepared = test_clear_buffer_journal_prepared (bh);
-  clear_buffer_journal_restore_dirty (bh);
-  /* already in this transaction, we are done */
-  if (buffer_journaled(bh)) {
-    PROC_INFO_INC( p_s_sb, journal.mark_dirty_already );
-    return 0 ;
-  }
-
-  /* this must be turned into a panic instead of a warning.  We can't allow
-  ** a dirty or journal_dirty or locked buffer to be logged, as some changes
-  ** could get to disk too early.  NOT GOOD.
-  */
-  if (!prepared || buffer_dirty(bh)) {
-    reiserfs_warning (p_s_sb, "journal-1777: buffer %llu bad state "
-		      "%cPREPARED %cLOCKED %cDIRTY %cJDIRTY_WAIT",
-		      (unsigned long long)bh->b_blocknr, prepared ? ' ' : '!',
-			    buffer_locked(bh) ? ' ' : '!',
-			    buffer_dirty(bh) ? ' ' : '!',
-			    buffer_journal_dirty(bh) ? ' ' : '!') ;
-  }
-
-  if (atomic_read(&(journal->j_wcount)) <= 0) {
-    reiserfs_warning (p_s_sb, "journal-1409: journal_mark_dirty returning because j_wcount was %d", atomic_read(&(journal->j_wcount))) ;
-    return 1 ;
-  }
-  /* this error means I've screwed up, and we've overflowed the transaction.  
-  ** Nothing can be done here, except make the FS readonly or panic.
-  */ 
-  if (journal->j_len >= journal->j_trans_max) {
-    reiserfs_panic(th->t_super, "journal-1413: journal_mark_dirty: j_len (%lu) is too big\n", journal->j_len) ;
-  }
-
-  if (buffer_journal_dirty(bh)) {
-    count_already_incd = 1 ;
-    PROC_INFO_INC( p_s_sb, journal.mark_dirty_notjournal );
-    clear_buffer_journal_dirty (bh);
-  }
-
-  if (journal->j_len > journal->j_len_alloc) {
-    journal->j_len_alloc = journal->j_len + JOURNAL_PER_BALANCE_CNT ;
-  }
-
-  set_buffer_journaled (bh);
-
-  /* now put this guy on the end */
-  if (!cn) {
-    cn = get_cnode(p_s_sb) ;
-    if (!cn) {
-      reiserfs_panic(p_s_sb, "get_cnode failed!\n"); 
-    }
-
-    if (th->t_blocks_logged == th->t_blocks_allocated) {
-      th->t_blocks_allocated += JOURNAL_PER_BALANCE_CNT ;
-      journal->j_len_alloc += JOURNAL_PER_BALANCE_CNT ;
-    }
-    th->t_blocks_logged++ ;
-    journal->j_len++ ;
-
-    cn->bh = bh ;
-    cn->blocknr = bh->b_blocknr ;
-    cn->sb = p_s_sb;
-    cn->jlist = NULL ;
-    insert_journal_hash(journal->j_hash_table, cn) ;
-    if (!count_already_incd) {
-      get_bh(bh) ;
-    }
-  }
-  cn->next = NULL ;
-  cn->prev = journal->j_last ;
-  cn->bh = bh ;
-  if (journal->j_last) {
-    journal->j_last->next = cn ;
-    journal->j_last = cn ;
-  } else {
-    journal->j_first = cn ;
-    journal->j_last = cn ;
-  }
-  return 0 ;
-}
-
-int journal_end(struct reiserfs_transaction_handle *th, struct super_block *p_s_sb, unsigned long nblocks) {
-  if (!current->journal_info && th->t_refcount > 1)
-    reiserfs_warning (p_s_sb, "REISER-NESTING: th NULL, refcount %d",
-                      th->t_refcount);
-
-  if (!th->t_trans_id) {
-    WARN_ON (1);
-    return -EIO;
-  }
-
-  th->t_refcount--;
-  if (th->t_refcount > 0) {
-    struct reiserfs_transaction_handle *cur_th = current->journal_info ;
-
-    /* we aren't allowed to close a nested transaction on a different
-    ** filesystem from the one in the task struct
-    */
-    if (cur_th->t_super != th->t_super)
-      BUG() ;
-
-    if (th != cur_th) {
-      memcpy(current->journal_info, th, sizeof(*th));
-      th->t_trans_id = 0;
-    }
-    return 0;
-  } else {
-    return do_journal_end(th, p_s_sb, nblocks, 0) ;
-  }
+int journal_mark_dirty(struct reiserfs_transaction_handle *th,
+		       struct super_block *p_s_sb, struct buffer_head *bh)
+{
+	struct reiserfs_journal *journal = SB_JOURNAL(p_s_sb);
+	struct reiserfs_journal_cnode *cn = NULL;
+	int count_already_incd = 0;
+	int prepared = 0;
+	BUG_ON(!th->t_trans_id);
+
+	PROC_INFO_INC(p_s_sb, journal.mark_dirty);
+	if (th->t_trans_id != journal->j_trans_id) {
+		reiserfs_panic(th->t_super,
+			       "journal-1577: handle trans id %ld != current trans id %ld\n",
+			       th->t_trans_id, journal->j_trans_id);
+	}
+
+	p_s_sb->s_dirt = 1;
+
+	prepared = test_clear_buffer_journal_prepared(bh);
+	clear_buffer_journal_restore_dirty(bh);
+	/* already in this transaction, we are done */
+	if (buffer_journaled(bh)) {
+		PROC_INFO_INC(p_s_sb, journal.mark_dirty_already);
+		return 0;
+	}
+
+	/* this must be turned into a panic instead of a warning.  We can't allow
+	 ** a dirty or journal_dirty or locked buffer to be logged, as some changes
+	 ** could get to disk too early.  NOT GOOD.
+	 */
+	if (!prepared || buffer_dirty(bh)) {
+		reiserfs_warning(p_s_sb, "journal-1777: buffer %llu bad state "
+				 "%cPREPARED %cLOCKED %cDIRTY %cJDIRTY_WAIT",
+				 (unsigned long long)bh->b_blocknr,
+				 prepared ? ' ' : '!',
+				 buffer_locked(bh) ? ' ' : '!',
+				 buffer_dirty(bh) ? ' ' : '!',
+				 buffer_journal_dirty(bh) ? ' ' : '!');
+	}
+
+	if (atomic_read(&(journal->j_wcount)) <= 0) {
+		reiserfs_warning(p_s_sb,
+				 "journal-1409: journal_mark_dirty returning because j_wcount was %d",
+				 atomic_read(&(journal->j_wcount)));
+		return 1;
+	}
+	/* this error means I've screwed up, and we've overflowed the transaction.  
+	 ** Nothing can be done here, except make the FS readonly or panic.
+	 */
+	if (journal->j_len >= journal->j_trans_max) {
+		reiserfs_panic(th->t_super,
+			       "journal-1413: journal_mark_dirty: j_len (%lu) is too big\n",
+			       journal->j_len);
+	}
+
+	if (buffer_journal_dirty(bh)) {
+		count_already_incd = 1;
+		PROC_INFO_INC(p_s_sb, journal.mark_dirty_notjournal);
+		clear_buffer_journal_dirty(bh);
+	}
+
+	if (journal->j_len > journal->j_len_alloc) {
+		journal->j_len_alloc = journal->j_len + JOURNAL_PER_BALANCE_CNT;
+	}
+
+	set_buffer_journaled(bh);
+
+	/* now put this guy on the end */
+	if (!cn) {
+		cn = get_cnode(p_s_sb);
+		if (!cn) {
+			reiserfs_panic(p_s_sb, "get_cnode failed!\n");
+		}
+
+		if (th->t_blocks_logged == th->t_blocks_allocated) {
+			th->t_blocks_allocated += JOURNAL_PER_BALANCE_CNT;
+			journal->j_len_alloc += JOURNAL_PER_BALANCE_CNT;
+		}
+		th->t_blocks_logged++;
+		journal->j_len++;
+
+		cn->bh = bh;
+		cn->blocknr = bh->b_blocknr;
+		cn->sb = p_s_sb;
+		cn->jlist = NULL;
+		insert_journal_hash(journal->j_hash_table, cn);
+		if (!count_already_incd) {
+			get_bh(bh);
+		}
+	}
+	cn->next = NULL;
+	cn->prev = journal->j_last;
+	cn->bh = bh;
+	if (journal->j_last) {
+		journal->j_last->next = cn;
+		journal->j_last = cn;
+	} else {
+		journal->j_first = cn;
+		journal->j_last = cn;
+	}
+	return 0;
+}
+
+int journal_end(struct reiserfs_transaction_handle *th,
+		struct super_block *p_s_sb, unsigned long nblocks)
+{
+	if (!current->journal_info && th->t_refcount > 1)
+		reiserfs_warning(p_s_sb, "REISER-NESTING: th NULL, refcount %d",
+				 th->t_refcount);
+
+	if (!th->t_trans_id) {
+		WARN_ON(1);
+		return -EIO;
+	}
+
+	th->t_refcount--;
+	if (th->t_refcount > 0) {
+		struct reiserfs_transaction_handle *cur_th =
+		    current->journal_info;
+
+		/* we aren't allowed to close a nested transaction on a different
+		 ** filesystem from the one in the task struct
+		 */
+		if (cur_th->t_super != th->t_super)
+			BUG();
+
+		if (th != cur_th) {
+			memcpy(current->journal_info, th, sizeof(*th));
+			th->t_trans_id = 0;
+		}
+		return 0;
+	} else {
+		return do_journal_end(th, p_s_sb, nblocks, 0);
+	}
 }
 
 /* removes from the current transaction, relsing and descrementing any counters.  
@@ -2980,47 +3282,51 @@ int journal_end(struct reiserfs_transact
 **
 ** returns 1 if it cleaned and relsed the buffer. 0 otherwise
 */
-static int remove_from_transaction(struct super_block *p_s_sb, b_blocknr_t blocknr, int already_cleaned) {
-  struct buffer_head *bh ;
-  struct reiserfs_journal_cnode *cn ;
-  struct reiserfs_journal *journal = SB_JOURNAL (p_s_sb);
-  int ret = 0;
-
-  cn = get_journal_hash_dev(p_s_sb, journal->j_hash_table, blocknr) ;
-  if (!cn || !cn->bh) {
-    return ret ;
-  }
-  bh = cn->bh ;
-  if (cn->prev) {
-    cn->prev->next = cn->next ;
-  }
-  if (cn->next) {
-    cn->next->prev = cn->prev ;
-  }
-  if (cn == journal->j_first) {
-    journal->j_first = cn->next ;
-  }
-  if (cn == journal->j_last) {
-    journal->j_last = cn->prev ;
-  }
-  if (bh)
-	remove_journal_hash(p_s_sb, journal->j_hash_table, NULL, bh->b_blocknr, 0) ;
-  clear_buffer_journaled  (bh); /* don't log this one */
-
-  if (!already_cleaned) {
-    clear_buffer_journal_dirty (bh);
-    clear_buffer_dirty(bh);
-    clear_buffer_journal_test (bh);
-    put_bh(bh) ;
-    if (atomic_read(&(bh->b_count)) < 0) {
-      reiserfs_warning (p_s_sb, "journal-1752: remove from trans, b_count < 0");
-    }
-    ret = 1 ;
-  }
-  journal->j_len-- ;
-  journal->j_len_alloc-- ;
-  free_cnode(p_s_sb, cn) ;
-  return ret ;
+static int remove_from_transaction(struct super_block *p_s_sb,
+				   b_blocknr_t blocknr, int already_cleaned)
+{
+	struct buffer_head *bh;
+	struct reiserfs_journal_cnode *cn;
+	struct reiserfs_journal *journal = SB_JOURNAL(p_s_sb);
+	int ret = 0;
+
+	cn = get_journal_hash_dev(p_s_sb, journal->j_hash_table, blocknr);
+	if (!cn || !cn->bh) {
+		return ret;
+	}
+	bh = cn->bh;
+	if (cn->prev) {
+		cn->prev->next = cn->next;
+	}
+	if (cn->next) {
+		cn->next->prev = cn->prev;
+	}
+	if (cn == journal->j_first) {
+		journal->j_first = cn->next;
+	}
+	if (cn == journal->j_last) {
+		journal->j_last = cn->prev;
+	}
+	if (bh)
+		remove_journal_hash(p_s_sb, journal->j_hash_table, NULL,
+				    bh->b_blocknr, 0);
+	clear_buffer_journaled(bh);	/* don't log this one */
+
+	if (!already_cleaned) {
+		clear_buffer_journal_dirty(bh);
+		clear_buffer_dirty(bh);
+		clear_buffer_journal_test(bh);
+		put_bh(bh);
+		if (atomic_read(&(bh->b_count)) < 0) {
+			reiserfs_warning(p_s_sb,
+					 "journal-1752: remove from trans, b_count < 0");
+		}
+		ret = 1;
+	}
+	journal->j_len--;
+	journal->j_len_alloc--;
+	free_cnode(p_s_sb, cn);
+	return ret;
 }
 
 /*
@@ -3033,120 +3339,129 @@ static int remove_from_transaction(struc
 ** blocks for a given transaction on disk
 **
 */
-static int can_dirty(struct reiserfs_journal_cnode *cn) {
-  struct super_block *sb = cn->sb;
-  b_blocknr_t blocknr = cn->blocknr  ;
-  struct reiserfs_journal_cnode *cur = cn->hprev ;
-  int can_dirty = 1 ;
-  
-  /* first test hprev.  These are all newer than cn, so any node here
-  ** with the same block number and dev means this node can't be sent
-  ** to disk right now.
-  */
-  while(cur && can_dirty) {
-    if (cur->jlist && cur->bh && cur->blocknr && cur->sb == sb && 
-        cur->blocknr == blocknr) {
-      can_dirty = 0 ;
-    }
-    cur = cur->hprev ;
-  }
-  /* then test hnext.  These are all older than cn.  As long as they
-  ** are committed to the log, it is safe to write cn to disk
-  */
-  cur = cn->hnext ;
-  while(cur && can_dirty) {
-    if (cur->jlist && cur->jlist->j_len > 0 && 
-        atomic_read(&(cur->jlist->j_commit_left)) > 0 && cur->bh && 
-        cur->blocknr && cur->sb == sb && cur->blocknr == blocknr) {
-      can_dirty = 0 ;
-    }
-    cur = cur->hnext ;
-  }
-  return can_dirty ;
+static int can_dirty(struct reiserfs_journal_cnode *cn)
+{
+	struct super_block *sb = cn->sb;
+	b_blocknr_t blocknr = cn->blocknr;
+	struct reiserfs_journal_cnode *cur = cn->hprev;
+	int can_dirty = 1;
+
+	/* first test hprev.  These are all newer than cn, so any node here
+	 ** with the same block number and dev means this node can't be sent
+	 ** to disk right now.
+	 */
+	while (cur && can_dirty) {
+		if (cur->jlist && cur->bh && cur->blocknr && cur->sb == sb &&
+		    cur->blocknr == blocknr) {
+			can_dirty = 0;
+		}
+		cur = cur->hprev;
+	}
+	/* then test hnext.  These are all older than cn.  As long as they
+	 ** are committed to the log, it is safe to write cn to disk
+	 */
+	cur = cn->hnext;
+	while (cur && can_dirty) {
+		if (cur->jlist && cur->jlist->j_len > 0 &&
+		    atomic_read(&(cur->jlist->j_commit_left)) > 0 && cur->bh &&
+		    cur->blocknr && cur->sb == sb && cur->blocknr == blocknr) {
+			can_dirty = 0;
+		}
+		cur = cur->hnext;
+	}
+	return can_dirty;
 }
 
 /* syncs the commit blocks, but does not force the real buffers to disk
 ** will wait until the current transaction is done/commited before returning 
 */
-int journal_end_sync(struct reiserfs_transaction_handle *th, struct super_block *p_s_sb, unsigned long nblocks) {
-  struct reiserfs_journal *journal = SB_JOURNAL (p_s_sb);
+int journal_end_sync(struct reiserfs_transaction_handle *th,
+		     struct super_block *p_s_sb, unsigned long nblocks)
+{
+	struct reiserfs_journal *journal = SB_JOURNAL(p_s_sb);
 
-  BUG_ON (!th->t_trans_id);
-  /* you can sync while nested, very, very bad */
-  if (th->t_refcount > 1) {
-    BUG() ;
-  }
-  if (journal->j_len == 0) {
-    reiserfs_prepare_for_journal(p_s_sb, SB_BUFFER_WITH_SB(p_s_sb), 1) ;
-    journal_mark_dirty(th, p_s_sb, SB_BUFFER_WITH_SB(p_s_sb)) ;
-  }
-  return do_journal_end(th, p_s_sb, nblocks, COMMIT_NOW | WAIT) ;
+	BUG_ON(!th->t_trans_id);
+	/* you can sync while nested, very, very bad */
+	if (th->t_refcount > 1) {
+		BUG();
+	}
+	if (journal->j_len == 0) {
+		reiserfs_prepare_for_journal(p_s_sb, SB_BUFFER_WITH_SB(p_s_sb),
+					     1);
+		journal_mark_dirty(th, p_s_sb, SB_BUFFER_WITH_SB(p_s_sb));
+	}
+	return do_journal_end(th, p_s_sb, nblocks, COMMIT_NOW | WAIT);
 }
 
 /*
 ** writeback the pending async commits to disk
 */
-static void flush_async_commits(void *p) {
-  struct super_block *p_s_sb = p;
-  struct reiserfs_journal *journal = SB_JOURNAL (p_s_sb);
-  struct reiserfs_journal_list *jl;
-  struct list_head *entry;
-
-  lock_kernel();
-  if (!list_empty(&journal->j_journal_list)) {
-      /* last entry is the youngest, commit it and you get everything */
-      entry = journal->j_journal_list.prev;
-      jl = JOURNAL_LIST_ENTRY(entry);
-      flush_commit_list(p_s_sb, jl, 1);
-  }
-  unlock_kernel();
-  /*
-   * this is a little racey, but there's no harm in missing
-   * the filemap_fdata_write
-   */
-  if (!atomic_read(&journal->j_async_throttle) && !reiserfs_is_journal_aborted (journal)) {
-      atomic_inc(&journal->j_async_throttle);
-      filemap_fdatawrite(p_s_sb->s_bdev->bd_inode->i_mapping);
-      atomic_dec(&journal->j_async_throttle);
-  }
+static void flush_async_commits(void *p)
+{
+	struct super_block *p_s_sb = p;
+	struct reiserfs_journal *journal = SB_JOURNAL(p_s_sb);
+	struct reiserfs_journal_list *jl;
+	struct list_head *entry;
+
+	lock_kernel();
+	if (!list_empty(&journal->j_journal_list)) {
+		/* last entry is the youngest, commit it and you get everything */
+		entry = journal->j_journal_list.prev;
+		jl = JOURNAL_LIST_ENTRY(entry);
+		flush_commit_list(p_s_sb, jl, 1);
+	}
+	unlock_kernel();
+	/*
+	 * this is a little racey, but there's no harm in missing
+	 * the filemap_fdata_write
+	 */
+	if (!atomic_read(&journal->j_async_throttle)
+	    && !reiserfs_is_journal_aborted(journal)) {
+		atomic_inc(&journal->j_async_throttle);
+		filemap_fdatawrite(p_s_sb->s_bdev->bd_inode->i_mapping);
+		atomic_dec(&journal->j_async_throttle);
+	}
 }
 
 /*
 ** flushes any old transactions to disk
 ** ends the current transaction if it is too old
 */
-int reiserfs_flush_old_commits(struct super_block *p_s_sb) {
-    time_t now ;
-    struct reiserfs_transaction_handle th ;
-    struct reiserfs_journal *journal = SB_JOURNAL (p_s_sb);
-
-    now = get_seconds();
-    /* safety check so we don't flush while we are replaying the log during
-     * mount
-     */
-    if (list_empty(&journal->j_journal_list)) {
-	return 0  ;
-    }
-
-    /* check the current transaction.  If there are no writers, and it is
-     * too old, finish it, and force the commit blocks to disk
-     */
-    if (atomic_read(&journal->j_wcount) <= 0 &&
-        journal->j_trans_start_time > 0 &&
-        journal->j_len > 0 &&
-        (now - journal->j_trans_start_time) > journal->j_max_trans_age)
-    {
-	if (!journal_join(&th, p_s_sb, 1)) {
-            reiserfs_prepare_for_journal(p_s_sb, SB_BUFFER_WITH_SB(p_s_sb), 1) ;
-            journal_mark_dirty(&th, p_s_sb, SB_BUFFER_WITH_SB(p_s_sb)) ;
-
-            /* we're only being called from kreiserfsd, it makes no sense to do
-            ** an async commit so that kreiserfsd can do it later
-            */
-            do_journal_end(&th, p_s_sb,1, COMMIT_NOW | WAIT) ;
-        }
-    }
-    return p_s_sb->s_dirt;
+int reiserfs_flush_old_commits(struct super_block *p_s_sb)
+{
+	time_t now;
+	struct reiserfs_transaction_handle th;
+	struct reiserfs_journal *journal = SB_JOURNAL(p_s_sb);
+
+	now = get_seconds();
+	/* safety check so we don't flush while we are replaying the log during
+	 * mount
+	 */
+	if (list_empty(&journal->j_journal_list)) {
+		return 0;
+	}
+
+	/* check the current transaction.  If there are no writers, and it is
+	 * too old, finish it, and force the commit blocks to disk
+	 */
+	if (atomic_read(&journal->j_wcount) <= 0 &&
+	    journal->j_trans_start_time > 0 &&
+	    journal->j_len > 0 &&
+	    (now - journal->j_trans_start_time) > journal->j_max_trans_age) {
+		if (!journal_join(&th, p_s_sb, 1)) {
+			reiserfs_prepare_for_journal(p_s_sb,
+						     SB_BUFFER_WITH_SB(p_s_sb),
+						     1);
+			journal_mark_dirty(&th, p_s_sb,
+					   SB_BUFFER_WITH_SB(p_s_sb));
+
+			/* we're only being called from kreiserfsd, it makes no sense to do
+			 ** an async commit so that kreiserfsd can do it later
+			 */
+			do_journal_end(&th, p_s_sb, 1, COMMIT_NOW | WAIT);
+		}
+	}
+	return p_s_sb->s_dirt;
 }
 
 /*
@@ -3160,101 +3475,108 @@ int reiserfs_flush_old_commits(struct su
 ** 
 ** Note, we can't allow the journal_end to proceed while there are still writers in the log.
 */
-static int check_journal_end(struct reiserfs_transaction_handle *th, struct super_block  * p_s_sb, 
-                             unsigned long nblocks, int flags) {
+static int check_journal_end(struct reiserfs_transaction_handle *th,
+			     struct super_block *p_s_sb, unsigned long nblocks,
+			     int flags)
+{
+
+	time_t now;
+	int flush = flags & FLUSH_ALL;
+	int commit_now = flags & COMMIT_NOW;
+	int wait_on_commit = flags & WAIT;
+	struct reiserfs_journal_list *jl;
+	struct reiserfs_journal *journal = SB_JOURNAL(p_s_sb);
+
+	BUG_ON(!th->t_trans_id);
+
+	if (th->t_trans_id != journal->j_trans_id) {
+		reiserfs_panic(th->t_super,
+			       "journal-1577: handle trans id %ld != current trans id %ld\n",
+			       th->t_trans_id, journal->j_trans_id);
+	}
+
+	journal->j_len_alloc -= (th->t_blocks_allocated - th->t_blocks_logged);
+	if (atomic_read(&(journal->j_wcount)) > 0) {	/* <= 0 is allowed.  unmounting might not call begin */
+		atomic_dec(&(journal->j_wcount));
+	}
 
-  time_t now ;
-  int flush = flags & FLUSH_ALL ;
-  int commit_now = flags & COMMIT_NOW ;
-  int wait_on_commit = flags & WAIT ;
-  struct reiserfs_journal_list *jl;
-  struct reiserfs_journal *journal = SB_JOURNAL (p_s_sb);
-
-  BUG_ON (!th->t_trans_id);
-
-  if (th->t_trans_id != journal->j_trans_id) {
-    reiserfs_panic(th->t_super, "journal-1577: handle trans id %ld != current trans id %ld\n", 
-                   th->t_trans_id, journal->j_trans_id);
-  }
-
-  journal->j_len_alloc -= (th->t_blocks_allocated - th->t_blocks_logged) ;
-  if (atomic_read(&(journal->j_wcount)) > 0) { /* <= 0 is allowed.  unmounting might not call begin */
-    atomic_dec(&(journal->j_wcount)) ;
-  }
-
-  /* BUG, deal with case where j_len is 0, but people previously freed blocks need to be released 
-  ** will be dealt with by next transaction that actually writes something, but should be taken
-  ** care of in this trans
-  */
-  if (journal->j_len == 0) {
-    BUG();
-  }
-  /* if wcount > 0, and we are called to with flush or commit_now,
-  ** we wait on j_join_wait.  We will wake up when the last writer has
-  ** finished the transaction, and started it on its way to the disk.
-  ** Then, we flush the commit or journal list, and just return 0 
-  ** because the rest of journal end was already done for this transaction.
-  */
-  if (atomic_read(&(journal->j_wcount)) > 0) {
-    if (flush || commit_now) {
-      unsigned trans_id ;
-
-      jl = journal->j_current_jl;
-      trans_id = jl->j_trans_id;
-      if (wait_on_commit)
-        jl->j_state |= LIST_COMMIT_PENDING;
-      atomic_set(&(journal->j_jlock), 1) ;
-      if (flush) {
-        journal->j_next_full_flush = 1 ;
-      }
-      unlock_journal(p_s_sb) ;
-
-      /* sleep while the current transaction is still j_jlocked */
-      while(journal->j_trans_id == trans_id) {
-	if (atomic_read(&journal->j_jlock)) {
-	    queue_log_writer(p_s_sb);
-        } else {
-	    lock_journal(p_s_sb);
-	    if (journal->j_trans_id == trans_id) {
-	        atomic_set(&(journal->j_jlock), 1) ;
-	    }
-	    unlock_journal(p_s_sb);
-	}
-      }
-      if (journal->j_trans_id == trans_id) {
-          BUG();
-      }
-      if (commit_now && journal_list_still_alive(p_s_sb, trans_id) &&
-          wait_on_commit)
-      {
-	  flush_commit_list(p_s_sb, jl, 1) ;
-      }
-      return 0 ;
-    } 
-    unlock_journal(p_s_sb) ;
-    return 0 ;
-  }
-
-  /* deal with old transactions where we are the last writers */
-  now = get_seconds();
-  if ((now - journal->j_trans_start_time) > journal->j_max_trans_age) {
-    commit_now = 1 ;
-    journal->j_next_async_flush = 1 ;
-  }
-  /* don't batch when someone is waiting on j_join_wait */
-  /* don't batch when syncing the commit or flushing the whole trans */
-  if (!(journal->j_must_wait > 0) && !(atomic_read(&(journal->j_jlock))) && !flush && !commit_now &&
-      (journal->j_len < journal->j_max_batch)  &&
-      journal->j_len_alloc < journal->j_max_batch && journal->j_cnode_free > (journal->j_trans_max * 3)) {
-    journal->j_bcount++ ;
-    unlock_journal(p_s_sb) ;
-    return 0 ;
-  }
-
-  if (journal->j_start > SB_ONDISK_JOURNAL_SIZE(p_s_sb)) {
-    reiserfs_panic(p_s_sb, "journal-003: journal_end: j_start (%ld) is too high\n", journal->j_start) ;
-  }
-  return 1 ;
+	/* BUG, deal with case where j_len is 0, but people previously freed blocks need to be released 
+	 ** will be dealt with by next transaction that actually writes something, but should be taken
+	 ** care of in this trans
+	 */
+	if (journal->j_len == 0) {
+		BUG();
+	}
+	/* if wcount > 0, and we are called to with flush or commit_now,
+	 ** we wait on j_join_wait.  We will wake up when the last writer has
+	 ** finished the transaction, and started it on its way to the disk.
+	 ** Then, we flush the commit or journal list, and just return 0 
+	 ** because the rest of journal end was already done for this transaction.
+	 */
+	if (atomic_read(&(journal->j_wcount)) > 0) {
+		if (flush || commit_now) {
+			unsigned trans_id;
+
+			jl = journal->j_current_jl;
+			trans_id = jl->j_trans_id;
+			if (wait_on_commit)
+				jl->j_state |= LIST_COMMIT_PENDING;
+			atomic_set(&(journal->j_jlock), 1);
+			if (flush) {
+				journal->j_next_full_flush = 1;
+			}
+			unlock_journal(p_s_sb);
+
+			/* sleep while the current transaction is still j_jlocked */
+			while (journal->j_trans_id == trans_id) {
+				if (atomic_read(&journal->j_jlock)) {
+					queue_log_writer(p_s_sb);
+				} else {
+					lock_journal(p_s_sb);
+					if (journal->j_trans_id == trans_id) {
+						atomic_set(&(journal->j_jlock),
+							   1);
+					}
+					unlock_journal(p_s_sb);
+				}
+			}
+			if (journal->j_trans_id == trans_id) {
+				BUG();
+			}
+			if (commit_now
+			    && journal_list_still_alive(p_s_sb, trans_id)
+			    && wait_on_commit) {
+				flush_commit_list(p_s_sb, jl, 1);
+			}
+			return 0;
+		}
+		unlock_journal(p_s_sb);
+		return 0;
+	}
+
+	/* deal with old transactions where we are the last writers */
+	now = get_seconds();
+	if ((now - journal->j_trans_start_time) > journal->j_max_trans_age) {
+		commit_now = 1;
+		journal->j_next_async_flush = 1;
+	}
+	/* don't batch when someone is waiting on j_join_wait */
+	/* don't batch when syncing the commit or flushing the whole trans */
+	if (!(journal->j_must_wait > 0) && !(atomic_read(&(journal->j_jlock)))
+	    && !flush && !commit_now && (journal->j_len < journal->j_max_batch)
+	    && journal->j_len_alloc < journal->j_max_batch
+	    && journal->j_cnode_free > (journal->j_trans_max * 3)) {
+		journal->j_bcount++;
+		unlock_journal(p_s_sb);
+		return 0;
+	}
+
+	if (journal->j_start > SB_ONDISK_JOURNAL_SIZE(p_s_sb)) {
+		reiserfs_panic(p_s_sb,
+			       "journal-003: journal_end: j_start (%ld) is too high\n",
+			       journal->j_start);
+	}
+	return 1;
 }
 
 /*
@@ -3271,83 +3593,95 @@ static int check_journal_end(struct reis
 **
 ** Then remove it from the current transaction, decrementing any counters and filing it on the clean list.
 */
-int journal_mark_freed(struct reiserfs_transaction_handle *th, struct super_block *p_s_sb, b_blocknr_t blocknr) {
-  struct reiserfs_journal *journal = SB_JOURNAL (p_s_sb);
-  struct reiserfs_journal_cnode *cn = NULL ;
-  struct buffer_head *bh = NULL ;
-  struct reiserfs_list_bitmap *jb = NULL ;
-  int cleaned = 0 ;
-  BUG_ON (!th->t_trans_id);
-
-  cn = get_journal_hash_dev(p_s_sb, journal->j_hash_table, blocknr);
-  if (cn && cn->bh) {
-      bh = cn->bh ;
-      get_bh(bh) ;
-  }
-  /* if it is journal new, we just remove it from this transaction */
-  if (bh && buffer_journal_new(bh)) {
-    clear_buffer_journal_new (bh);
-    clear_prepared_bits(bh) ;
-    reiserfs_clean_and_file_buffer(bh) ;
-    cleaned = remove_from_transaction(p_s_sb, blocknr, cleaned) ;
-  } else {
-    /* set the bit for this block in the journal bitmap for this transaction */
-    jb = journal->j_current_jl->j_list_bitmap;
-    if (!jb) {
-      reiserfs_panic(p_s_sb, "journal-1702: journal_mark_freed, journal_list_bitmap is NULL\n") ;
-    }
-    set_bit_in_list_bitmap(p_s_sb, blocknr, jb) ;
-
-    /* Note, the entire while loop is not allowed to schedule.  */
-
-    if (bh) {
-      clear_prepared_bits(bh) ;
-      reiserfs_clean_and_file_buffer(bh) ;
-    }
-    cleaned = remove_from_transaction(p_s_sb, blocknr, cleaned) ;
-
-    /* find all older transactions with this block, make sure they don't try to write it out */
-    cn = get_journal_hash_dev(p_s_sb,journal->j_list_hash_table,  blocknr) ;
-    while (cn) {
-      if (p_s_sb == cn->sb && blocknr == cn->blocknr) {
-	set_bit(BLOCK_FREED, &cn->state) ;
-	if (cn->bh) {
-	  if (!cleaned) {
-	    /* remove_from_transaction will brelse the buffer if it was 
-	    ** in the current trans
-	    */
-            clear_buffer_journal_dirty (cn->bh);
-	    clear_buffer_dirty(cn->bh);
-	    clear_buffer_journal_test(cn->bh);
-	    cleaned = 1 ;
-	    put_bh(cn->bh) ;
-	    if (atomic_read(&(cn->bh->b_count)) < 0) {
-	      reiserfs_warning (p_s_sb, "journal-2138: cn->bh->b_count < 0");
-	    }
-	  }
-	  if (cn->jlist) { /* since we are clearing the bh, we MUST dec nonzerolen */
-	    atomic_dec(&(cn->jlist->j_nonzerolen)) ;
-	  }
-	  cn->bh = NULL ; 
-	} 
-      }
-      cn = cn->hnext ;
-    }
-  }
-
-  if (bh) {
-    put_bh(bh) ; /* get_hash grabs the buffer */
-    if (atomic_read(&(bh->b_count)) < 0) {
-      reiserfs_warning (p_s_sb, "journal-2165: bh->b_count < 0");
-    }
-  }
-  return 0 ;
-}
-
-void reiserfs_update_inode_transaction(struct inode *inode) {
-  struct reiserfs_journal *journal = SB_JOURNAL (inode->i_sb);
-  REISERFS_I(inode)->i_jl = journal->j_current_jl;
-  REISERFS_I(inode)->i_trans_id = journal->j_trans_id ;
+int journal_mark_freed(struct reiserfs_transaction_handle *th,
+		       struct super_block *p_s_sb, b_blocknr_t blocknr)
+{
+	struct reiserfs_journal *journal = SB_JOURNAL(p_s_sb);
+	struct reiserfs_journal_cnode *cn = NULL;
+	struct buffer_head *bh = NULL;
+	struct reiserfs_list_bitmap *jb = NULL;
+	int cleaned = 0;
+	BUG_ON(!th->t_trans_id);
+
+	cn = get_journal_hash_dev(p_s_sb, journal->j_hash_table, blocknr);
+	if (cn && cn->bh) {
+		bh = cn->bh;
+		get_bh(bh);
+	}
+	/* if it is journal new, we just remove it from this transaction */
+	if (bh && buffer_journal_new(bh)) {
+		clear_buffer_journal_new(bh);
+		clear_prepared_bits(bh);
+		reiserfs_clean_and_file_buffer(bh);
+		cleaned = remove_from_transaction(p_s_sb, blocknr, cleaned);
+	} else {
+		/* set the bit for this block in the journal bitmap for this transaction */
+		jb = journal->j_current_jl->j_list_bitmap;
+		if (!jb) {
+			reiserfs_panic(p_s_sb,
+				       "journal-1702: journal_mark_freed, journal_list_bitmap is NULL\n");
+		}
+		set_bit_in_list_bitmap(p_s_sb, blocknr, jb);
+
+		/* Note, the entire while loop is not allowed to schedule.  */
+
+		if (bh) {
+			clear_prepared_bits(bh);
+			reiserfs_clean_and_file_buffer(bh);
+		}
+		cleaned = remove_from_transaction(p_s_sb, blocknr, cleaned);
+
+		/* find all older transactions with this block, make sure they don't try to write it out */
+		cn = get_journal_hash_dev(p_s_sb, journal->j_list_hash_table,
+					  blocknr);
+		while (cn) {
+			if (p_s_sb == cn->sb && blocknr == cn->blocknr) {
+				set_bit(BLOCK_FREED, &cn->state);
+				if (cn->bh) {
+					if (!cleaned) {
+						/* remove_from_transaction will brelse the buffer if it was 
+						 ** in the current trans
+						 */
+						clear_buffer_journal_dirty(cn->
+									   bh);
+						clear_buffer_dirty(cn->bh);
+						clear_buffer_journal_test(cn->
+									  bh);
+						cleaned = 1;
+						put_bh(cn->bh);
+						if (atomic_read
+						    (&(cn->bh->b_count)) < 0) {
+							reiserfs_warning(p_s_sb,
+									 "journal-2138: cn->bh->b_count < 0");
+						}
+					}
+					if (cn->jlist) {	/* since we are clearing the bh, we MUST dec nonzerolen */
+						atomic_dec(&
+							   (cn->jlist->
+							    j_nonzerolen));
+					}
+					cn->bh = NULL;
+				}
+			}
+			cn = cn->hnext;
+		}
+	}
+
+	if (bh) {
+		put_bh(bh);	/* get_hash grabs the buffer */
+		if (atomic_read(&(bh->b_count)) < 0) {
+			reiserfs_warning(p_s_sb,
+					 "journal-2165: bh->b_count < 0");
+		}
+	}
+	return 0;
+}
+
+void reiserfs_update_inode_transaction(struct inode *inode)
+{
+	struct reiserfs_journal *journal = SB_JOURNAL(inode->i_sb);
+	REISERFS_I(inode)->i_jl = journal->j_current_jl;
+	REISERFS_I(inode)->i_trans_id = journal->j_trans_id;
 }
 
 /*
@@ -3355,99 +3689,102 @@ void reiserfs_update_inode_transaction(s
  * if a transaction was actually committed and the barrier was done
  */
 static int __commit_trans_jl(struct inode *inode, unsigned long id,
-                                 struct reiserfs_journal_list *jl)
+			     struct reiserfs_journal_list *jl)
 {
-    struct reiserfs_transaction_handle th ;
-    struct super_block *sb = inode->i_sb ;
-    struct reiserfs_journal *journal = SB_JOURNAL (sb);
-    int ret = 0;
+	struct reiserfs_transaction_handle th;
+	struct super_block *sb = inode->i_sb;
+	struct reiserfs_journal *journal = SB_JOURNAL(sb);
+	int ret = 0;
+
+	/* is it from the current transaction, or from an unknown transaction? */
+	if (id == journal->j_trans_id) {
+		jl = journal->j_current_jl;
+		/* try to let other writers come in and grow this transaction */
+		let_transaction_grow(sb, id);
+		if (journal->j_trans_id != id) {
+			goto flush_commit_only;
+		}
 
-    /* is it from the current transaction, or from an unknown transaction? */
-    if (id == journal->j_trans_id) {
-	jl = journal->j_current_jl;
-	/* try to let other writers come in and grow this transaction */
-	let_transaction_grow(sb, id);
-	if (journal->j_trans_id != id) {
-	    goto flush_commit_only;
+		ret = journal_begin(&th, sb, 1);
+		if (ret)
+			return ret;
+
+		/* someone might have ended this transaction while we joined */
+		if (journal->j_trans_id != id) {
+			reiserfs_prepare_for_journal(sb, SB_BUFFER_WITH_SB(sb),
+						     1);
+			journal_mark_dirty(&th, sb, SB_BUFFER_WITH_SB(sb));
+			ret = journal_end(&th, sb, 1);
+			goto flush_commit_only;
+		}
+
+		ret = journal_end_sync(&th, sb, 1);
+		if (!ret)
+			ret = 1;
+
+	} else {
+		/* this gets tricky, we have to make sure the journal list in
+		 * the inode still exists.  We know the list is still around
+		 * if we've got a larger transaction id than the oldest list
+		 */
+	      flush_commit_only:
+		if (journal_list_still_alive(inode->i_sb, id)) {
+			/*
+			 * we only set ret to 1 when we know for sure
+			 * the barrier hasn't been started yet on the commit
+			 * block.
+			 */
+			if (atomic_read(&jl->j_commit_left) > 1)
+				ret = 1;
+			flush_commit_list(sb, jl, 1);
+			if (journal->j_errno)
+				ret = journal->j_errno;
+		}
 	}
+	/* otherwise the list is gone, and long since committed */
+	return ret;
+}
 
-	ret = journal_begin(&th, sb, 1) ;
-	if (ret)
-	    return ret;
+int reiserfs_commit_for_inode(struct inode *inode)
+{
+	unsigned long id = REISERFS_I(inode)->i_trans_id;
+	struct reiserfs_journal_list *jl = REISERFS_I(inode)->i_jl;
 
-	/* someone might have ended this transaction while we joined */
-	if (journal->j_trans_id != id) {
-	    reiserfs_prepare_for_journal(sb, SB_BUFFER_WITH_SB(sb), 1) ;
-	    journal_mark_dirty(&th, sb, SB_BUFFER_WITH_SB(sb)) ;
-	    ret = journal_end(&th, sb, 1) ;
-	    goto flush_commit_only;
-	}
-
-	ret = journal_end_sync(&th, sb, 1) ;
-	if (!ret)
-	    ret = 1;
-
-    } else {
-	/* this gets tricky, we have to make sure the journal list in
-	 * the inode still exists.  We know the list is still around
-	 * if we've got a larger transaction id than the oldest list
-	 */
-flush_commit_only:
-	if (journal_list_still_alive(inode->i_sb, id)) {
-	    /*
-	     * we only set ret to 1 when we know for sure
-	     * the barrier hasn't been started yet on the commit
-	     * block.
-	     */
-	    if (atomic_read(&jl->j_commit_left) > 1)
-	        ret = 1;
-	    flush_commit_list(sb, jl, 1) ;
-	    if (journal->j_errno)
-		ret = journal->j_errno;
-	}
-    }
-    /* otherwise the list is gone, and long since committed */
-    return ret;
-}
-
-int reiserfs_commit_for_inode(struct inode *inode) {
-    unsigned long id = REISERFS_I(inode)->i_trans_id;
-    struct reiserfs_journal_list *jl = REISERFS_I(inode)->i_jl;
-
-    /* for the whole inode, assume unset id means it was
-     * changed in the current transaction.  More conservative
-     */
-    if (!id || !jl) {
-	reiserfs_update_inode_transaction(inode) ;
-	id = REISERFS_I(inode)->i_trans_id;
-	/* jl will be updated in __commit_trans_jl */
-    }
-
-   return __commit_trans_jl(inode, id, jl);
-}
-
-void reiserfs_restore_prepared_buffer(struct super_block *p_s_sb, 
-                                      struct buffer_head *bh) {
-    struct reiserfs_journal *journal = SB_JOURNAL (p_s_sb);
-    PROC_INFO_INC( p_s_sb, journal.restore_prepared );
-    if (!bh) {
-	return ;
-    }
-    if (test_clear_buffer_journal_restore_dirty (bh) &&
-	buffer_journal_dirty(bh)) {
-	struct reiserfs_journal_cnode *cn;
-	cn = get_journal_hash_dev(p_s_sb,
-	                          journal->j_list_hash_table,
-				  bh->b_blocknr);
-	if (cn && can_dirty(cn)) {
-            set_buffer_journal_test (bh);
-	    mark_buffer_dirty(bh);
-        }
-    }
-    clear_buffer_journal_prepared (bh);
+	/* for the whole inode, assume unset id means it was
+	 * changed in the current transaction.  More conservative
+	 */
+	if (!id || !jl) {
+		reiserfs_update_inode_transaction(inode);
+		id = REISERFS_I(inode)->i_trans_id;
+		/* jl will be updated in __commit_trans_jl */
+	}
+
+	return __commit_trans_jl(inode, id, jl);
 }
 
-extern struct tree_balance *cur_tb ;
+void reiserfs_restore_prepared_buffer(struct super_block *p_s_sb,
+				      struct buffer_head *bh)
+{
+	struct reiserfs_journal *journal = SB_JOURNAL(p_s_sb);
+	PROC_INFO_INC(p_s_sb, journal.restore_prepared);
+	if (!bh) {
+		return;
+	}
+	if (test_clear_buffer_journal_restore_dirty(bh) &&
+	    buffer_journal_dirty(bh)) {
+		struct reiserfs_journal_cnode *cn;
+		cn = get_journal_hash_dev(p_s_sb,
+					  journal->j_list_hash_table,
+					  bh->b_blocknr);
+		if (cn && can_dirty(cn)) {
+			set_buffer_journal_test(bh);
+			mark_buffer_dirty(bh);
+		}
+	}
+	clear_buffer_journal_prepared(bh);
+}
+
+extern struct tree_balance *cur_tb;
 /*
 ** before we can change a metadata block, we have to make sure it won't
 ** be written to disk while we are altering it.  So, we must:
@@ -3456,39 +3793,41 @@ extern struct tree_balance *cur_tb ;
 ** 
 */
 int reiserfs_prepare_for_journal(struct super_block *p_s_sb,
-                                  struct buffer_head *bh, int wait) {
-  PROC_INFO_INC( p_s_sb, journal.prepare );
+				 struct buffer_head *bh, int wait)
+{
+	PROC_INFO_INC(p_s_sb, journal.prepare);
 
-    if (test_set_buffer_locked(bh)) {
-	if (!wait)
-	    return 0;
-	lock_buffer(bh);
-    }
-    set_buffer_journal_prepared (bh);
-    if (test_clear_buffer_dirty(bh) && buffer_journal_dirty(bh))  {
-        clear_buffer_journal_test (bh);
-        set_buffer_journal_restore_dirty (bh);
-    }
-    unlock_buffer(bh);
-    return 1;
-}
-
-static void flush_old_journal_lists(struct super_block *s) {
-    struct reiserfs_journal *journal = SB_JOURNAL (s);
-    struct reiserfs_journal_list *jl;
-    struct list_head *entry;
-    time_t now = get_seconds();
-
-    while(!list_empty(&journal->j_journal_list)) {
-        entry = journal->j_journal_list.next;
-	jl = JOURNAL_LIST_ENTRY(entry);
-	/* this check should always be run, to send old lists to disk */
-	if (jl->j_timestamp < (now - (JOURNAL_MAX_TRANS_AGE * 4))) {
-	    flush_used_journal_lists(s, jl);
-	} else {
-	    break;
+	if (test_set_buffer_locked(bh)) {
+		if (!wait)
+			return 0;
+		lock_buffer(bh);
+	}
+	set_buffer_journal_prepared(bh);
+	if (test_clear_buffer_dirty(bh) && buffer_journal_dirty(bh)) {
+		clear_buffer_journal_test(bh);
+		set_buffer_journal_restore_dirty(bh);
+	}
+	unlock_buffer(bh);
+	return 1;
+}
+
+static void flush_old_journal_lists(struct super_block *s)
+{
+	struct reiserfs_journal *journal = SB_JOURNAL(s);
+	struct reiserfs_journal_list *jl;
+	struct list_head *entry;
+	time_t now = get_seconds();
+
+	while (!list_empty(&journal->j_journal_list)) {
+		entry = journal->j_journal_list.next;
+		jl = JOURNAL_LIST_ENTRY(entry);
+		/* this check should always be run, to send old lists to disk */
+		if (jl->j_timestamp < (now - (JOURNAL_MAX_TRANS_AGE * 4))) {
+			flush_used_journal_lists(s, jl);
+		} else {
+			break;
+		}
 	}
-    }
 }
 
 /* 
@@ -3501,374 +3840,390 @@ static void flush_old_journal_lists(stru
 ** If the journal is aborted, we just clean up. Things like flushing
 ** journal lists, etc just won't happen.
 */
-static int do_journal_end(struct reiserfs_transaction_handle *th, struct super_block  * p_s_sb, unsigned long nblocks, 
-		          int flags) {
-  struct reiserfs_journal *journal = SB_JOURNAL (p_s_sb);
-  struct reiserfs_journal_cnode *cn, *next, *jl_cn; 
-  struct reiserfs_journal_cnode *last_cn = NULL;
-  struct reiserfs_journal_desc *desc ; 
-  struct reiserfs_journal_commit *commit ; 
-  struct buffer_head *c_bh ; /* commit bh */
-  struct buffer_head *d_bh ; /* desc bh */
-  int cur_write_start = 0 ; /* start index of current log write */
-  int old_start ;
-  int i ;
-  int flush = flags & FLUSH_ALL ;
-  int wait_on_commit = flags & WAIT ;
-  struct reiserfs_journal_list *jl, *temp_jl;
-  struct list_head *entry, *safe;
-  unsigned long jindex;
-  unsigned long commit_trans_id;
-  int trans_half;
-
-  BUG_ON (th->t_refcount > 1);
-  BUG_ON (!th->t_trans_id);
-
-  current->journal_info = th->t_handle_save;
-  reiserfs_check_lock_depth(p_s_sb, "journal end");
-  if (journal->j_len == 0) {
-      reiserfs_prepare_for_journal(p_s_sb, SB_BUFFER_WITH_SB(p_s_sb), 1) ;
-      journal_mark_dirty(th, p_s_sb, SB_BUFFER_WITH_SB(p_s_sb)) ;
-  }
-
-  lock_journal(p_s_sb) ;
-  if (journal->j_next_full_flush) {
-    flags |= FLUSH_ALL ;
-    flush = 1 ;
-  }
-  if (journal->j_next_async_flush) {
-    flags |= COMMIT_NOW | WAIT;
-    wait_on_commit = 1;
-  }
-
-  /* check_journal_end locks the journal, and unlocks if it does not return 1 
-  ** it tells us if we should continue with the journal_end, or just return
-  */
-  if (!check_journal_end(th, p_s_sb, nblocks, flags)) {
-    p_s_sb->s_dirt = 1;
-    wake_queued_writers(p_s_sb);
-    reiserfs_async_progress_wait(p_s_sb);
-    goto out ;
-  }
-
-  /* check_journal_end might set these, check again */
-  if (journal->j_next_full_flush) {
-    flush = 1 ;
-  }
-
-  /*
-  ** j must wait means we have to flush the log blocks, and the real blocks for
-  ** this transaction
-  */
-  if (journal->j_must_wait > 0) {
-    flush = 1 ;
-  }
+static int do_journal_end(struct reiserfs_transaction_handle *th,
+			  struct super_block *p_s_sb, unsigned long nblocks,
+			  int flags)
+{
+	struct reiserfs_journal *journal = SB_JOURNAL(p_s_sb);
+	struct reiserfs_journal_cnode *cn, *next, *jl_cn;
+	struct reiserfs_journal_cnode *last_cn = NULL;
+	struct reiserfs_journal_desc *desc;
+	struct reiserfs_journal_commit *commit;
+	struct buffer_head *c_bh;	/* commit bh */
+	struct buffer_head *d_bh;	/* desc bh */
+	int cur_write_start = 0;	/* start index of current log write */
+	int old_start;
+	int i;
+	int flush = flags & FLUSH_ALL;
+	int wait_on_commit = flags & WAIT;
+	struct reiserfs_journal_list *jl, *temp_jl;
+	struct list_head *entry, *safe;
+	unsigned long jindex;
+	unsigned long commit_trans_id;
+	int trans_half;
+
+	BUG_ON(th->t_refcount > 1);
+	BUG_ON(!th->t_trans_id);
+
+	put_fs_excl();
+	current->journal_info = th->t_handle_save;
+	reiserfs_check_lock_depth(p_s_sb, "journal end");
+	if (journal->j_len == 0) {
+		reiserfs_prepare_for_journal(p_s_sb, SB_BUFFER_WITH_SB(p_s_sb),
+					     1);
+		journal_mark_dirty(th, p_s_sb, SB_BUFFER_WITH_SB(p_s_sb));
+	}
+
+	lock_journal(p_s_sb);
+	if (journal->j_next_full_flush) {
+		flags |= FLUSH_ALL;
+		flush = 1;
+	}
+	if (journal->j_next_async_flush) {
+		flags |= COMMIT_NOW | WAIT;
+		wait_on_commit = 1;
+	}
+
+	/* check_journal_end locks the journal, and unlocks if it does not return 1 
+	 ** it tells us if we should continue with the journal_end, or just return
+	 */
+	if (!check_journal_end(th, p_s_sb, nblocks, flags)) {
+		p_s_sb->s_dirt = 1;
+		wake_queued_writers(p_s_sb);
+		reiserfs_async_progress_wait(p_s_sb);
+		goto out;
+	}
 
+	/* check_journal_end might set these, check again */
+	if (journal->j_next_full_flush) {
+		flush = 1;
+	}
+
+	/*
+	 ** j must wait means we have to flush the log blocks, and the real blocks for
+	 ** this transaction
+	 */
+	if (journal->j_must_wait > 0) {
+		flush = 1;
+	}
 #ifdef REISERFS_PREALLOCATE
-  /* quota ops might need to nest, setup the journal_info pointer for them */
-  current->journal_info = th ;
-  reiserfs_discard_all_prealloc(th); /* it should not involve new blocks into
-				      * the transaction */
-  current->journal_info = th->t_handle_save ;
+	/* quota ops might need to nest, setup the journal_info pointer for them */
+	current->journal_info = th;
+	reiserfs_discard_all_prealloc(th);	/* it should not involve new blocks into
+						 * the transaction */
+	current->journal_info = th->t_handle_save;
 #endif
-  
-  /* setup description block */
-  d_bh = journal_getblk(p_s_sb, SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) + journal->j_start) ;
-  set_buffer_uptodate(d_bh);
-  desc = (struct reiserfs_journal_desc *)(d_bh)->b_data ;
-  memset(d_bh->b_data, 0, d_bh->b_size) ;
-  memcpy(get_journal_desc_magic (d_bh), JOURNAL_DESC_MAGIC, 8) ;
-  set_desc_trans_id(desc, journal->j_trans_id) ;
-
-  /* setup commit block.  Don't write (keep it clean too) this one until after everyone else is written */
-  c_bh =  journal_getblk(p_s_sb, SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) + 
-		 ((journal->j_start + journal->j_len + 1) % SB_ONDISK_JOURNAL_SIZE(p_s_sb))) ;
-  commit = (struct reiserfs_journal_commit *)c_bh->b_data ;
-  memset(c_bh->b_data, 0, c_bh->b_size) ;
-  set_commit_trans_id(commit, journal->j_trans_id) ;
-  set_buffer_uptodate(c_bh) ;
-
-  /* init this journal list */
-  jl = journal->j_current_jl;
-
-  /* we lock the commit before doing anything because
-   * we want to make sure nobody tries to run flush_commit_list until
-   * the new transaction is fully setup, and we've already flushed the
-   * ordered bh list
-   */
-  down(&jl->j_commit_lock);
-
-  /* save the transaction id in case we need to commit it later */
-  commit_trans_id = jl->j_trans_id;
-
-  atomic_set(&jl->j_older_commits_done, 0) ;
-  jl->j_trans_id = journal->j_trans_id ;
-  jl->j_timestamp = journal->j_trans_start_time ;
-  jl->j_commit_bh = c_bh ;
-  jl->j_start = journal->j_start ;
-  jl->j_len = journal->j_len ;
-  atomic_set(&jl->j_nonzerolen, journal->j_len) ;
-  atomic_set(&jl->j_commit_left, journal->j_len + 2);
-  jl->j_realblock = NULL ;
-
-  /* The ENTIRE FOR LOOP MUST not cause schedule to occur.
-  **  for each real block, add it to the journal list hash,
-  ** copy into real block index array in the commit or desc block
-  */
-  trans_half = journal_trans_half(p_s_sb->s_blocksize);
-  for (i = 0, cn = journal->j_first ; cn ; cn = cn->next, i++) {
-    if (buffer_journaled (cn->bh)) {
-      jl_cn = get_cnode(p_s_sb) ;
-      if (!jl_cn) {
-        reiserfs_panic(p_s_sb, "journal-1676, get_cnode returned NULL\n") ;
-      }
-      if (i == 0) {
-        jl->j_realblock = jl_cn ;
-      }
-      jl_cn->prev = last_cn ;
-      jl_cn->next = NULL ;
-      if (last_cn) {
-        last_cn->next = jl_cn ;
-      }
-      last_cn = jl_cn ;
-      /* make sure the block we are trying to log is not a block 
-         of journal or reserved area */
-
-      if (is_block_in_log_or_reserved_area(p_s_sb, cn->bh->b_blocknr)) {
-        reiserfs_panic(p_s_sb, "journal-2332: Trying to log block %lu, which is a log block\n", cn->bh->b_blocknr) ;
-      }
-      jl_cn->blocknr = cn->bh->b_blocknr ; 
-      jl_cn->state = 0 ;
-      jl_cn->sb = p_s_sb;
-      jl_cn->bh = cn->bh ;
-      jl_cn->jlist = jl;
-      insert_journal_hash(journal->j_list_hash_table, jl_cn) ;
-      if (i < trans_half) {
-	desc->j_realblock[i] = cpu_to_le32(cn->bh->b_blocknr) ;
-      } else {
-	commit->j_realblock[i - trans_half] = cpu_to_le32(cn->bh->b_blocknr) ;
-      }
-    } else {
-      i-- ;
-    }
-  }
-  set_desc_trans_len(desc, journal->j_len) ;
-  set_desc_mount_id(desc, journal->j_mount_id) ;
-  set_desc_trans_id(desc, journal->j_trans_id) ;
-  set_commit_trans_len(commit, journal->j_len);
-
-  /* special check in case all buffers in the journal were marked for not logging */
-  if (journal->j_len == 0) {
-    BUG();
-  }
-
-  /* we're about to dirty all the log blocks, mark the description block
-   * dirty now too.  Don't mark the commit block dirty until all the
-   * others are on disk
-   */
-  mark_buffer_dirty(d_bh);
-
-  /* first data block is j_start + 1, so add one to cur_write_start wherever you use it */
-  cur_write_start = journal->j_start ;
-  cn = journal->j_first ;
-  jindex = 1 ; /* start at one so we don't get the desc again */
-  while(cn) {
-    clear_buffer_journal_new (cn->bh);
-    /* copy all the real blocks into log area.  dirty log blocks */
-    if (buffer_journaled (cn->bh)) {
-      struct buffer_head *tmp_bh ;
-      char *addr;
-      struct page *page;
-      tmp_bh =  journal_getblk(p_s_sb, SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) + 
-		       ((cur_write_start + jindex) % SB_ONDISK_JOURNAL_SIZE(p_s_sb))) ;
-      set_buffer_uptodate(tmp_bh);
-      page = cn->bh->b_page;
-      addr = kmap(page);
-      memcpy(tmp_bh->b_data, addr + offset_in_page(cn->bh->b_data),
-             cn->bh->b_size);
-      kunmap(page);
-      mark_buffer_dirty(tmp_bh);
-      jindex++ ;
-      set_buffer_journal_dirty (cn->bh);
-      clear_buffer_journaled (cn->bh);
-    } else {
-      /* JDirty cleared sometime during transaction.  don't log this one */
-      reiserfs_warning(p_s_sb, "journal-2048: do_journal_end: BAD, buffer in journal hash, but not JDirty!") ;
-      brelse(cn->bh) ;
-    }
-    next = cn->next ;
-    free_cnode(p_s_sb, cn) ;
-    cn = next ;
-    cond_resched();
-  }
-
-  /* we are done  with both the c_bh and d_bh, but
-  ** c_bh must be written after all other commit blocks,
-  ** so we dirty/relse c_bh in flush_commit_list, with commit_left <= 1.
-  */
-
-  journal->j_current_jl = alloc_journal_list(p_s_sb);
-
-  /* now it is safe to insert this transaction on the main list */
-  list_add_tail(&jl->j_list, &journal->j_journal_list);
-  list_add_tail(&jl->j_working_list, &journal->j_working_list);
-  journal->j_num_work_lists++;
-
-  /* reset journal values for the next transaction */
-  old_start = journal->j_start ;
-  journal->j_start = (journal->j_start + journal->j_len + 2) % SB_ONDISK_JOURNAL_SIZE(p_s_sb);
-  atomic_set(&(journal->j_wcount), 0) ;
-  journal->j_bcount = 0 ;
-  journal->j_last = NULL ;
-  journal->j_first = NULL ;
-  journal->j_len = 0 ;
-  journal->j_trans_start_time = 0 ;
-  journal->j_trans_id++ ;
-  journal->j_current_jl->j_trans_id = journal->j_trans_id;
-  journal->j_must_wait = 0 ;
-  journal->j_len_alloc = 0 ;
-  journal->j_next_full_flush = 0 ;
-  journal->j_next_async_flush = 0 ;
-  init_journal_hash(p_s_sb) ; 
-
-  // make sure reiserfs_add_jh sees the new current_jl before we
-  // write out the tails
-  smp_mb();
-
-  /* tail conversion targets have to hit the disk before we end the
-   * transaction.  Otherwise a later transaction might repack the tail
-   * before this transaction commits, leaving the data block unflushed and
-   * clean, if we crash before the later transaction commits, the data block
-   * is lost.
-   */
-  if (!list_empty(&jl->j_tail_bh_list)) {
-      unlock_kernel();
-      write_ordered_buffers(&journal->j_dirty_buffers_lock,
-			    journal, jl, &jl->j_tail_bh_list);
-      lock_kernel();
-  }
-  if (!list_empty(&jl->j_tail_bh_list))
-      BUG();
-  up(&jl->j_commit_lock);
-
-  /* honor the flush wishes from the caller, simple commits can
-  ** be done outside the journal lock, they are done below
-  **
-  ** if we don't flush the commit list right now, we put it into
-  ** the work queue so the people waiting on the async progress work
-  ** queue don't wait for this proc to flush journal lists and such.
-  */
-  if (flush) {
-    flush_commit_list(p_s_sb, jl, 1) ;
-    flush_journal_list(p_s_sb, jl, 1) ;
-  } else if (!(jl->j_state & LIST_COMMIT_PENDING))
-    queue_delayed_work(commit_wq, &journal->j_work, HZ/10);
-
-
-  /* if the next transaction has any chance of wrapping, flush 
-  ** transactions that might get overwritten.  If any journal lists are very 
-  ** old flush them as well.  
-  */
-first_jl:
-  list_for_each_safe(entry, safe, &journal->j_journal_list) {
-    temp_jl = JOURNAL_LIST_ENTRY(entry);
-    if (journal->j_start <= temp_jl->j_start) {
-      if ((journal->j_start + journal->j_trans_max + 1) >=
-          temp_jl->j_start)
-      {
-	flush_used_journal_lists(p_s_sb, temp_jl);
-	goto first_jl;
-      } else if ((journal->j_start +
-                  journal->j_trans_max + 1) <
-		  SB_ONDISK_JOURNAL_SIZE(p_s_sb))
-      {
-          /* if we don't cross into the next transaction and we don't
-	   * wrap, there is no way we can overlap any later transactions
-	   * break now
-	   */
-	  break;
-      }
-    } else if ((journal->j_start +
-                journal->j_trans_max + 1) >
-		SB_ONDISK_JOURNAL_SIZE(p_s_sb))
-    {
-      if (((journal->j_start + journal->j_trans_max + 1) %
-            SB_ONDISK_JOURNAL_SIZE(p_s_sb)) >= temp_jl->j_start)
-      {
-	flush_used_journal_lists(p_s_sb, temp_jl);
-	goto first_jl;
-      } else {
-	  /* we don't overlap anything from out start to the end of the
-	   * log, and our wrapped portion doesn't overlap anything at
-	   * the start of the log.  We can break
-	   */
-	  break;
-      }
-    }
-  }
-  flush_old_journal_lists(p_s_sb);
-
-  journal->j_current_jl->j_list_bitmap = get_list_bitmap(p_s_sb, journal->j_current_jl) ;
-
-  if (!(journal->j_current_jl->j_list_bitmap)) {
-    reiserfs_panic(p_s_sb, "journal-1996: do_journal_end, could not get a list bitmap\n") ;
-  }
-
-  atomic_set(&(journal->j_jlock), 0) ;
-  unlock_journal(p_s_sb) ;
-  /* wake up any body waiting to join. */
-  clear_bit(J_WRITERS_QUEUED, &journal->j_state);
-  wake_up(&(journal->j_join_wait)) ;
-
-  if (!flush && wait_on_commit &&
-      journal_list_still_alive(p_s_sb, commit_trans_id)) {
-	  flush_commit_list(p_s_sb, jl, 1) ;
-  }
-out:
-  reiserfs_check_lock_depth(p_s_sb, "journal end2");
-
-  memset (th, 0, sizeof (*th));
-  /* Re-set th->t_super, so we can properly keep track of how many
-   * persistent transactions there are. We need to do this so if this
-   * call is part of a failed restart_transaction, we can free it later */
-  th->t_super = p_s_sb;
-
-  return journal->j_errno;
-}
-
-static void
-__reiserfs_journal_abort_hard (struct super_block *sb)
-{
-    struct reiserfs_journal *journal = SB_JOURNAL (sb);
-    if (test_bit (J_ABORTED, &journal->j_state))
-        return;
 
-    printk (KERN_CRIT "REISERFS: Aborting journal for filesystem on %s\n",
-                      reiserfs_bdevname (sb));
+	/* setup description block */
+	d_bh =
+	    journal_getblk(p_s_sb,
+			   SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) +
+			   journal->j_start);
+	set_buffer_uptodate(d_bh);
+	desc = (struct reiserfs_journal_desc *)(d_bh)->b_data;
+	memset(d_bh->b_data, 0, d_bh->b_size);
+	memcpy(get_journal_desc_magic(d_bh), JOURNAL_DESC_MAGIC, 8);
+	set_desc_trans_id(desc, journal->j_trans_id);
+
+	/* setup commit block.  Don't write (keep it clean too) this one until after everyone else is written */
+	c_bh = journal_getblk(p_s_sb, SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) +
+			      ((journal->j_start + journal->j_len +
+				1) % SB_ONDISK_JOURNAL_SIZE(p_s_sb)));
+	commit = (struct reiserfs_journal_commit *)c_bh->b_data;
+	memset(c_bh->b_data, 0, c_bh->b_size);
+	set_commit_trans_id(commit, journal->j_trans_id);
+	set_buffer_uptodate(c_bh);
+
+	/* init this journal list */
+	jl = journal->j_current_jl;
+
+	/* we lock the commit before doing anything because
+	 * we want to make sure nobody tries to run flush_commit_list until
+	 * the new transaction is fully setup, and we've already flushed the
+	 * ordered bh list
+	 */
+	down(&jl->j_commit_lock);
+
+	/* save the transaction id in case we need to commit it later */
+	commit_trans_id = jl->j_trans_id;
+
+	atomic_set(&jl->j_older_commits_done, 0);
+	jl->j_trans_id = journal->j_trans_id;
+	jl->j_timestamp = journal->j_trans_start_time;
+	jl->j_commit_bh = c_bh;
+	jl->j_start = journal->j_start;
+	jl->j_len = journal->j_len;
+	atomic_set(&jl->j_nonzerolen, journal->j_len);
+	atomic_set(&jl->j_commit_left, journal->j_len + 2);
+	jl->j_realblock = NULL;
+
+	/* The ENTIRE FOR LOOP MUST not cause schedule to occur.
+	 **  for each real block, add it to the journal list hash,
+	 ** copy into real block index array in the commit or desc block
+	 */
+	trans_half = journal_trans_half(p_s_sb->s_blocksize);
+	for (i = 0, cn = journal->j_first; cn; cn = cn->next, i++) {
+		if (buffer_journaled(cn->bh)) {
+			jl_cn = get_cnode(p_s_sb);
+			if (!jl_cn) {
+				reiserfs_panic(p_s_sb,
+					       "journal-1676, get_cnode returned NULL\n");
+			}
+			if (i == 0) {
+				jl->j_realblock = jl_cn;
+			}
+			jl_cn->prev = last_cn;
+			jl_cn->next = NULL;
+			if (last_cn) {
+				last_cn->next = jl_cn;
+			}
+			last_cn = jl_cn;
+			/* make sure the block we are trying to log is not a block 
+			   of journal or reserved area */
+
+			if (is_block_in_log_or_reserved_area
+			    (p_s_sb, cn->bh->b_blocknr)) {
+				reiserfs_panic(p_s_sb,
+					       "journal-2332: Trying to log block %lu, which is a log block\n",
+					       cn->bh->b_blocknr);
+			}
+			jl_cn->blocknr = cn->bh->b_blocknr;
+			jl_cn->state = 0;
+			jl_cn->sb = p_s_sb;
+			jl_cn->bh = cn->bh;
+			jl_cn->jlist = jl;
+			insert_journal_hash(journal->j_list_hash_table, jl_cn);
+			if (i < trans_half) {
+				desc->j_realblock[i] =
+				    cpu_to_le32(cn->bh->b_blocknr);
+			} else {
+				commit->j_realblock[i - trans_half] =
+				    cpu_to_le32(cn->bh->b_blocknr);
+			}
+		} else {
+			i--;
+		}
+	}
+	set_desc_trans_len(desc, journal->j_len);
+	set_desc_mount_id(desc, journal->j_mount_id);
+	set_desc_trans_id(desc, journal->j_trans_id);
+	set_commit_trans_len(commit, journal->j_len);
+
+	/* special check in case all buffers in the journal were marked for not logging */
+	if (journal->j_len == 0) {
+		BUG();
+	}
+
+	/* we're about to dirty all the log blocks, mark the description block
+	 * dirty now too.  Don't mark the commit block dirty until all the
+	 * others are on disk
+	 */
+	mark_buffer_dirty(d_bh);
+
+	/* first data block is j_start + 1, so add one to cur_write_start wherever you use it */
+	cur_write_start = journal->j_start;
+	cn = journal->j_first;
+	jindex = 1;		/* start at one so we don't get the desc again */
+	while (cn) {
+		clear_buffer_journal_new(cn->bh);
+		/* copy all the real blocks into log area.  dirty log blocks */
+		if (buffer_journaled(cn->bh)) {
+			struct buffer_head *tmp_bh;
+			char *addr;
+			struct page *page;
+			tmp_bh =
+			    journal_getblk(p_s_sb,
+					   SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb) +
+					   ((cur_write_start +
+					     jindex) %
+					    SB_ONDISK_JOURNAL_SIZE(p_s_sb)));
+			set_buffer_uptodate(tmp_bh);
+			page = cn->bh->b_page;
+			addr = kmap(page);
+			memcpy(tmp_bh->b_data,
+			       addr + offset_in_page(cn->bh->b_data),
+			       cn->bh->b_size);
+			kunmap(page);
+			mark_buffer_dirty(tmp_bh);
+			jindex++;
+			set_buffer_journal_dirty(cn->bh);
+			clear_buffer_journaled(cn->bh);
+		} else {
+			/* JDirty cleared sometime during transaction.  don't log this one */
+			reiserfs_warning(p_s_sb,
+					 "journal-2048: do_journal_end: BAD, buffer in journal hash, but not JDirty!");
+			brelse(cn->bh);
+		}
+		next = cn->next;
+		free_cnode(p_s_sb, cn);
+		cn = next;
+		cond_resched();
+	}
+
+	/* we are done  with both the c_bh and d_bh, but
+	 ** c_bh must be written after all other commit blocks,
+	 ** so we dirty/relse c_bh in flush_commit_list, with commit_left <= 1.
+	 */
+
+	journal->j_current_jl = alloc_journal_list(p_s_sb);
+
+	/* now it is safe to insert this transaction on the main list */
+	list_add_tail(&jl->j_list, &journal->j_journal_list);
+	list_add_tail(&jl->j_working_list, &journal->j_working_list);
+	journal->j_num_work_lists++;
+
+	/* reset journal values for the next transaction */
+	old_start = journal->j_start;
+	journal->j_start =
+	    (journal->j_start + journal->j_len +
+	     2) % SB_ONDISK_JOURNAL_SIZE(p_s_sb);
+	atomic_set(&(journal->j_wcount), 0);
+	journal->j_bcount = 0;
+	journal->j_last = NULL;
+	journal->j_first = NULL;
+	journal->j_len = 0;
+	journal->j_trans_start_time = 0;
+	journal->j_trans_id++;
+	journal->j_current_jl->j_trans_id = journal->j_trans_id;
+	journal->j_must_wait = 0;
+	journal->j_len_alloc = 0;
+	journal->j_next_full_flush = 0;
+	journal->j_next_async_flush = 0;
+	init_journal_hash(p_s_sb);
+
+	// make sure reiserfs_add_jh sees the new current_jl before we
+	// write out the tails
+	smp_mb();
+
+	/* tail conversion targets have to hit the disk before we end the
+	 * transaction.  Otherwise a later transaction might repack the tail
+	 * before this transaction commits, leaving the data block unflushed and
+	 * clean, if we crash before the later transaction commits, the data block
+	 * is lost.
+	 */
+	if (!list_empty(&jl->j_tail_bh_list)) {
+		unlock_kernel();
+		write_ordered_buffers(&journal->j_dirty_buffers_lock,
+				      journal, jl, &jl->j_tail_bh_list);
+		lock_kernel();
+	}
+	if (!list_empty(&jl->j_tail_bh_list))
+		BUG();
+	up(&jl->j_commit_lock);
+
+	/* honor the flush wishes from the caller, simple commits can
+	 ** be done outside the journal lock, they are done below
+	 **
+	 ** if we don't flush the commit list right now, we put it into
+	 ** the work queue so the people waiting on the async progress work
+	 ** queue don't wait for this proc to flush journal lists and such.
+	 */
+	if (flush) {
+		flush_commit_list(p_s_sb, jl, 1);
+		flush_journal_list(p_s_sb, jl, 1);
+	} else if (!(jl->j_state & LIST_COMMIT_PENDING))
+		queue_delayed_work(commit_wq, &journal->j_work, HZ / 10);
+
+	/* if the next transaction has any chance of wrapping, flush 
+	 ** transactions that might get overwritten.  If any journal lists are very 
+	 ** old flush them as well.  
+	 */
+      first_jl:
+	list_for_each_safe(entry, safe, &journal->j_journal_list) {
+		temp_jl = JOURNAL_LIST_ENTRY(entry);
+		if (journal->j_start <= temp_jl->j_start) {
+			if ((journal->j_start + journal->j_trans_max + 1) >=
+			    temp_jl->j_start) {
+				flush_used_journal_lists(p_s_sb, temp_jl);
+				goto first_jl;
+			} else if ((journal->j_start +
+				    journal->j_trans_max + 1) <
+				   SB_ONDISK_JOURNAL_SIZE(p_s_sb)) {
+				/* if we don't cross into the next transaction and we don't
+				 * wrap, there is no way we can overlap any later transactions
+				 * break now
+				 */
+				break;
+			}
+		} else if ((journal->j_start +
+			    journal->j_trans_max + 1) >
+			   SB_ONDISK_JOURNAL_SIZE(p_s_sb)) {
+			if (((journal->j_start + journal->j_trans_max + 1) %
+			     SB_ONDISK_JOURNAL_SIZE(p_s_sb)) >=
+			    temp_jl->j_start) {
+				flush_used_journal_lists(p_s_sb, temp_jl);
+				goto first_jl;
+			} else {
+				/* we don't overlap anything from out start to the end of the
+				 * log, and our wrapped portion doesn't overlap anything at
+				 * the start of the log.  We can break
+				 */
+				break;
+			}
+		}
+	}
+	flush_old_journal_lists(p_s_sb);
+
+	journal->j_current_jl->j_list_bitmap =
+	    get_list_bitmap(p_s_sb, journal->j_current_jl);
+
+	if (!(journal->j_current_jl->j_list_bitmap)) {
+		reiserfs_panic(p_s_sb,
+			       "journal-1996: do_journal_end, could not get a list bitmap\n");
+	}
+
+	atomic_set(&(journal->j_jlock), 0);
+	unlock_journal(p_s_sb);
+	/* wake up any body waiting to join. */
+	clear_bit(J_WRITERS_QUEUED, &journal->j_state);
+	wake_up(&(journal->j_join_wait));
+
+	if (!flush && wait_on_commit &&
+	    journal_list_still_alive(p_s_sb, commit_trans_id)) {
+		flush_commit_list(p_s_sb, jl, 1);
+	}
+      out:
+	reiserfs_check_lock_depth(p_s_sb, "journal end2");
+
+	memset(th, 0, sizeof(*th));
+	/* Re-set th->t_super, so we can properly keep track of how many
+	 * persistent transactions there are. We need to do this so if this
+	 * call is part of a failed restart_transaction, we can free it later */
+	th->t_super = p_s_sb;
+
+	return journal->j_errno;
+}
+
+static void __reiserfs_journal_abort_hard(struct super_block *sb)
+{
+	struct reiserfs_journal *journal = SB_JOURNAL(sb);
+	if (test_bit(J_ABORTED, &journal->j_state))
+		return;
+
+	printk(KERN_CRIT "REISERFS: Aborting journal for filesystem on %s\n",
+	       reiserfs_bdevname(sb));
 
-    sb->s_flags |= MS_RDONLY;
-    set_bit (J_ABORTED, &journal->j_state);
+	sb->s_flags |= MS_RDONLY;
+	set_bit(J_ABORTED, &journal->j_state);
 
 #ifdef CONFIG_REISERFS_CHECK
-    dump_stack();
+	dump_stack();
 #endif
 }
 
-static void
-__reiserfs_journal_abort_soft (struct super_block *sb, int errno)
+static void __reiserfs_journal_abort_soft(struct super_block *sb, int errno)
 {
-    struct reiserfs_journal *journal = SB_JOURNAL (sb);
-    if (test_bit (J_ABORTED, &journal->j_state))
-        return;
+	struct reiserfs_journal *journal = SB_JOURNAL(sb);
+	if (test_bit(J_ABORTED, &journal->j_state))
+		return;
 
-    if (!journal->j_errno)
-        journal->j_errno = errno;
+	if (!journal->j_errno)
+		journal->j_errno = errno;
 
-    __reiserfs_journal_abort_hard (sb);
+	__reiserfs_journal_abort_hard(sb);
 }
 
-void
-reiserfs_journal_abort (struct super_block *sb, int errno)
+void reiserfs_journal_abort(struct super_block *sb, int errno)
 {
-    return __reiserfs_journal_abort_soft (sb, errno);
+	return __reiserfs_journal_abort_soft(sb, errno);
 }
diff --git a/fs/reiserfs/lbalance.c b/fs/reiserfs/lbalance.c
--- a/fs/reiserfs/lbalance.c
+++ b/fs/reiserfs/lbalance.c
@@ -21,648 +21,709 @@
    leaf_paste_entries
    */
 
-
 /* copy copy_count entries from source directory item to dest buffer (creating new item if needed) */
-static void leaf_copy_dir_entries (struct buffer_info * dest_bi, struct buffer_head * source, 
-				   int last_first, int item_num, int from, int copy_count)
+static void leaf_copy_dir_entries(struct buffer_info *dest_bi,
+				  struct buffer_head *source, int last_first,
+				  int item_num, int from, int copy_count)
 {
-    struct buffer_head * dest = dest_bi->bi_bh;
-    int item_num_in_dest;		/* either the number of target item,
-					   or if we must create a new item,
-					   the number of the item we will
-					   create it next to */
-    struct item_head * ih;
-    struct reiserfs_de_head * deh;
-    int copy_records_len;			/* length of all records in item to be copied */
-    char * records;
-
-    ih = B_N_PITEM_HEAD (source, item_num);
-
-    RFALSE( !is_direntry_le_ih (ih), "vs-10000: item must be directory item");
-
-    /* length of all record to be copied and first byte of the last of them */
-    deh = B_I_DEH (source, ih);
-    if (copy_count) {
-	copy_records_len = (from ? deh_location( &(deh[from - 1]) ) :
-            ih_item_len(ih)) - deh_location( &(deh[from + copy_count - 1]));
-	records = source->b_data + ih_location(ih) +
-                                deh_location( &(deh[from + copy_count - 1]));
-    } else {
-	copy_records_len = 0;
-	records = NULL;
-    }
-
-    /* when copy last to first, dest buffer can contain 0 items */
-    item_num_in_dest = (last_first == LAST_TO_FIRST) ? (( B_NR_ITEMS(dest) ) ? 0 : -1) : (B_NR_ITEMS(dest) - 1);
-
-    /* if there are no items in dest or the first/last item in dest is not item of the same directory */
-    if ( (item_num_in_dest == - 1) ||
-	(last_first == FIRST_TO_LAST && le_ih_k_offset (ih) == DOT_OFFSET) ||
-	    (last_first == LAST_TO_FIRST && comp_short_le_keys/*COMP_SHORT_KEYS*/ (&ih->ih_key, B_N_PKEY (dest, item_num_in_dest)))) {
-	/* create new item in dest */
-	struct item_head new_ih;
-
-	/* form item header */
-	memcpy (&new_ih.ih_key, &ih->ih_key, KEY_SIZE);
-	put_ih_version( &new_ih, KEY_FORMAT_3_5 );
-	/* calculate item len */
-	put_ih_item_len( &new_ih, DEH_SIZE * copy_count + copy_records_len );
-	put_ih_entry_count( &new_ih, 0 );
-    
-	if (last_first == LAST_TO_FIRST) {
-	    /* form key by the following way */
-	    if (from < I_ENTRY_COUNT(ih)) {
-		set_le_ih_k_offset( &new_ih, deh_offset( &(deh[from]) ) );
-		/*memcpy (&new_ih.ih_key.k_offset, &deh[from].deh_offset, SHORT_KEY_SIZE);*/
-	    } else {
-		/* no entries will be copied to this item in this function */
-		set_le_ih_k_offset (&new_ih, U32_MAX);
-		/* this item is not yet valid, but we want I_IS_DIRECTORY_ITEM to return 1 for it, so we -1 */
-	    }
-	    set_le_key_k_type (KEY_FORMAT_3_5, &(new_ih.ih_key), TYPE_DIRENTRY);
-	}
-    
-	/* insert item into dest buffer */
-	leaf_insert_into_buf (dest_bi, (last_first == LAST_TO_FIRST) ? 0 : B_NR_ITEMS(dest), &new_ih, NULL, 0);
-    } else {
-	/* prepare space for entries */
-	leaf_paste_in_buffer (dest_bi, (last_first==FIRST_TO_LAST) ? (B_NR_ITEMS(dest) - 1) : 0, MAX_US_INT,
-			      DEH_SIZE * copy_count + copy_records_len, records, 0
-	    );
-    }
-  
-    item_num_in_dest = (last_first == FIRST_TO_LAST) ? (B_NR_ITEMS(dest)-1) : 0;
-    
-    leaf_paste_entries (dest_bi->bi_bh, item_num_in_dest,
-			(last_first == FIRST_TO_LAST) ? I_ENTRY_COUNT(B_N_PITEM_HEAD (dest, item_num_in_dest)) : 0,
-			copy_count, deh + from, records,
-			DEH_SIZE * copy_count + copy_records_len
-	);
-}
+	struct buffer_head *dest = dest_bi->bi_bh;
+	int item_num_in_dest;	/* either the number of target item,
+				   or if we must create a new item,
+				   the number of the item we will
+				   create it next to */
+	struct item_head *ih;
+	struct reiserfs_de_head *deh;
+	int copy_records_len;	/* length of all records in item to be copied */
+	char *records;
+
+	ih = B_N_PITEM_HEAD(source, item_num);
+
+	RFALSE(!is_direntry_le_ih(ih), "vs-10000: item must be directory item");
+
+	/* length of all record to be copied and first byte of the last of them */
+	deh = B_I_DEH(source, ih);
+	if (copy_count) {
+		copy_records_len = (from ? deh_location(&(deh[from - 1])) :
+				    ih_item_len(ih)) -
+		    deh_location(&(deh[from + copy_count - 1]));
+		records =
+		    source->b_data + ih_location(ih) +
+		    deh_location(&(deh[from + copy_count - 1]));
+	} else {
+		copy_records_len = 0;
+		records = NULL;
+	}
 
+	/* when copy last to first, dest buffer can contain 0 items */
+	item_num_in_dest =
+	    (last_first ==
+	     LAST_TO_FIRST) ? ((B_NR_ITEMS(dest)) ? 0 : -1) : (B_NR_ITEMS(dest)
+							       - 1);
+
+	/* if there are no items in dest or the first/last item in dest is not item of the same directory */
+	if ((item_num_in_dest == -1) ||
+	    (last_first == FIRST_TO_LAST && le_ih_k_offset(ih) == DOT_OFFSET) ||
+	    (last_first == LAST_TO_FIRST
+	     && comp_short_le_keys /*COMP_SHORT_KEYS */ (&ih->ih_key,
+							 B_N_PKEY(dest,
+								  item_num_in_dest))))
+	{
+		/* create new item in dest */
+		struct item_head new_ih;
+
+		/* form item header */
+		memcpy(&new_ih.ih_key, &ih->ih_key, KEY_SIZE);
+		put_ih_version(&new_ih, KEY_FORMAT_3_5);
+		/* calculate item len */
+		put_ih_item_len(&new_ih,
+				DEH_SIZE * copy_count + copy_records_len);
+		put_ih_entry_count(&new_ih, 0);
+
+		if (last_first == LAST_TO_FIRST) {
+			/* form key by the following way */
+			if (from < I_ENTRY_COUNT(ih)) {
+				set_le_ih_k_offset(&new_ih,
+						   deh_offset(&(deh[from])));
+				/*memcpy (&new_ih.ih_key.k_offset, &deh[from].deh_offset, SHORT_KEY_SIZE); */
+			} else {
+				/* no entries will be copied to this item in this function */
+				set_le_ih_k_offset(&new_ih, U32_MAX);
+				/* this item is not yet valid, but we want I_IS_DIRECTORY_ITEM to return 1 for it, so we -1 */
+			}
+			set_le_key_k_type(KEY_FORMAT_3_5, &(new_ih.ih_key),
+					  TYPE_DIRENTRY);
+		}
+
+		/* insert item into dest buffer */
+		leaf_insert_into_buf(dest_bi,
+				     (last_first ==
+				      LAST_TO_FIRST) ? 0 : B_NR_ITEMS(dest),
+				     &new_ih, NULL, 0);
+	} else {
+		/* prepare space for entries */
+		leaf_paste_in_buffer(dest_bi,
+				     (last_first ==
+				      FIRST_TO_LAST) ? (B_NR_ITEMS(dest) -
+							1) : 0, MAX_US_INT,
+				     DEH_SIZE * copy_count + copy_records_len,
+				     records, 0);
+	}
+
+	item_num_in_dest =
+	    (last_first == FIRST_TO_LAST) ? (B_NR_ITEMS(dest) - 1) : 0;
+
+	leaf_paste_entries(dest_bi->bi_bh, item_num_in_dest,
+			   (last_first ==
+			    FIRST_TO_LAST) ? I_ENTRY_COUNT(B_N_PITEM_HEAD(dest,
+									  item_num_in_dest))
+			   : 0, copy_count, deh + from, records,
+			   DEH_SIZE * copy_count + copy_records_len);
+}
 
 /* Copy the first (if last_first == FIRST_TO_LAST) or last (last_first == LAST_TO_FIRST) item or 
    part of it or nothing (see the return 0 below) from SOURCE to the end 
    (if last_first) or beginning (!last_first) of the DEST */
 /* returns 1 if anything was copied, else 0 */
-static int leaf_copy_boundary_item (struct buffer_info * dest_bi, struct buffer_head * src, int last_first,
-				    int bytes_or_entries)
+static int leaf_copy_boundary_item(struct buffer_info *dest_bi,
+				   struct buffer_head *src, int last_first,
+				   int bytes_or_entries)
 {
-  struct buffer_head * dest = dest_bi->bi_bh;
-  int dest_nr_item, src_nr_item; /* number of items in the source and destination buffers */
-  struct item_head * ih;
-  struct item_head * dih;
-  
-  dest_nr_item = B_NR_ITEMS(dest);
-  
-  if ( last_first == FIRST_TO_LAST ) {
-    /* if ( DEST is empty or first item of SOURCE and last item of DEST are the items of different objects
-       or of different types ) then there is no need to treat this item differently from the other items
-       that we copy, so we return */
-    ih = B_N_PITEM_HEAD (src, 0);
-    dih = B_N_PITEM_HEAD (dest, dest_nr_item - 1);
-    if (!dest_nr_item || (!op_is_left_mergeable (&(ih->ih_key), src->b_size)))
-      /* there is nothing to merge */
-      return 0;
-      
-    RFALSE( ! ih_item_len(ih), "vs-10010: item can not have empty length");
-      
-    if ( is_direntry_le_ih (ih) ) {
-      if ( bytes_or_entries == -1 )
-	/* copy all entries to dest */
-	bytes_or_entries = ih_entry_count(ih);
-      leaf_copy_dir_entries (dest_bi, src, FIRST_TO_LAST, 0, 0, bytes_or_entries);
-      return 1;
-    }
-      
-    /* copy part of the body of the first item of SOURCE to the end of the body of the last item of the DEST
-       part defined by 'bytes_or_entries'; if bytes_or_entries == -1 copy whole body; don't create new item header
-       */
-    if ( bytes_or_entries == -1 )
-      bytes_or_entries = ih_item_len(ih);
+	struct buffer_head *dest = dest_bi->bi_bh;
+	int dest_nr_item, src_nr_item;	/* number of items in the source and destination buffers */
+	struct item_head *ih;
+	struct item_head *dih;
+
+	dest_nr_item = B_NR_ITEMS(dest);
+
+	if (last_first == FIRST_TO_LAST) {
+		/* if ( DEST is empty or first item of SOURCE and last item of DEST are the items of different objects
+		   or of different types ) then there is no need to treat this item differently from the other items
+		   that we copy, so we return */
+		ih = B_N_PITEM_HEAD(src, 0);
+		dih = B_N_PITEM_HEAD(dest, dest_nr_item - 1);
+		if (!dest_nr_item
+		    || (!op_is_left_mergeable(&(ih->ih_key), src->b_size)))
+			/* there is nothing to merge */
+			return 0;
+
+		RFALSE(!ih_item_len(ih),
+		       "vs-10010: item can not have empty length");
+
+		if (is_direntry_le_ih(ih)) {
+			if (bytes_or_entries == -1)
+				/* copy all entries to dest */
+				bytes_or_entries = ih_entry_count(ih);
+			leaf_copy_dir_entries(dest_bi, src, FIRST_TO_LAST, 0, 0,
+					      bytes_or_entries);
+			return 1;
+		}
+
+		/* copy part of the body of the first item of SOURCE to the end of the body of the last item of the DEST
+		   part defined by 'bytes_or_entries'; if bytes_or_entries == -1 copy whole body; don't create new item header
+		 */
+		if (bytes_or_entries == -1)
+			bytes_or_entries = ih_item_len(ih);
 
 #ifdef CONFIG_REISERFS_CHECK
-    else {
-      if (bytes_or_entries == ih_item_len(ih) && is_indirect_le_ih(ih))
-	if (get_ih_free_space (ih))
-	  reiserfs_panic (NULL, "vs-10020: leaf_copy_boundary_item: "
-			  "last unformatted node must be filled entirely (%h)",
-			  ih);
-    }
+		else {
+			if (bytes_or_entries == ih_item_len(ih)
+			    && is_indirect_le_ih(ih))
+				if (get_ih_free_space(ih))
+					reiserfs_panic(NULL,
+						       "vs-10020: leaf_copy_boundary_item: "
+						       "last unformatted node must be filled entirely (%h)",
+						       ih);
+		}
 #endif
-      
-    /* merge first item (or its part) of src buffer with the last
-       item of dest buffer. Both are of the same file */
-    leaf_paste_in_buffer (dest_bi,
-			  dest_nr_item - 1, ih_item_len(dih), bytes_or_entries, B_I_PITEM(src,ih), 0
-			  );
-      
-    if (is_indirect_le_ih (dih)) {
-      RFALSE( get_ih_free_space (dih),
-              "vs-10030: merge to left: last unformatted node of non-last indirect item %h must have zerto free space",
-              ih);
-      if (bytes_or_entries == ih_item_len(ih))
-	set_ih_free_space (dih, get_ih_free_space (ih));
-    }
-    
-    return 1;
-  }
-  
-
-  /* copy boundary item to right (last_first == LAST_TO_FIRST) */
-
-  /* ( DEST is empty or last item of SOURCE and first item of DEST
-     are the items of different object or of different types )
-     */
-  src_nr_item = B_NR_ITEMS (src);
-  ih = B_N_PITEM_HEAD (src, src_nr_item - 1);
-  dih = B_N_PITEM_HEAD (dest, 0);
-
-  if (!dest_nr_item || !op_is_left_mergeable (&(dih->ih_key), src->b_size))
-    return 0;
-  
-  if ( is_direntry_le_ih (ih)) {
-    if ( bytes_or_entries == -1 )
-      /* bytes_or_entries = entries number in last item body of SOURCE */
-      bytes_or_entries = ih_entry_count(ih);
-    
-    leaf_copy_dir_entries (dest_bi, src, LAST_TO_FIRST, src_nr_item - 1, ih_entry_count(ih) - bytes_or_entries, bytes_or_entries);
-    return 1;
-  }
-
-  /* copy part of the body of the last item of SOURCE to the begin of the body of the first item of the DEST;
-     part defined by 'bytes_or_entries'; if byte_or_entriess == -1 copy whole body; change first item key of the DEST;
-     don't create new item header
-     */
-  
-  RFALSE( is_indirect_le_ih(ih) && get_ih_free_space (ih),
-          "vs-10040: merge to right: last unformatted node of non-last indirect item must be filled entirely (%h)",
-		    ih);
-
-  if ( bytes_or_entries == -1 ) {
-    /* bytes_or_entries = length of last item body of SOURCE */
-    bytes_or_entries = ih_item_len(ih);
-
-    RFALSE( le_ih_k_offset (dih) !=
-            le_ih_k_offset (ih) + op_bytes_number (ih, src->b_size),
-            "vs-10050: items %h and %h do not match", ih, dih);
-
-    /* change first item key of the DEST */
-    set_le_ih_k_offset (dih, le_ih_k_offset (ih));
-
-    /* item becomes non-mergeable */
-    /* or mergeable if left item was */
-    set_le_ih_k_type (dih, le_ih_k_type (ih));
-  } else {
-    /* merge to right only part of item */
-    RFALSE( ih_item_len(ih) <= bytes_or_entries,
-            "vs-10060: no so much bytes %lu (needed %lu)",
-            ( unsigned long )ih_item_len(ih), ( unsigned long )bytes_or_entries);
-    
-    /* change first item key of the DEST */
-    if ( is_direct_le_ih (dih) ) {
-      RFALSE( le_ih_k_offset (dih) <= (unsigned long)bytes_or_entries,
-	      "vs-10070: dih %h, bytes_or_entries(%d)", dih, bytes_or_entries);
-      set_le_ih_k_offset (dih, le_ih_k_offset (dih) - bytes_or_entries);
-    } else {
-      RFALSE( le_ih_k_offset (dih) <=
-              (bytes_or_entries / UNFM_P_SIZE) * dest->b_size,
-              "vs-10080: dih %h, bytes_or_entries(%d)",
-              dih, (bytes_or_entries/UNFM_P_SIZE)*dest->b_size);
-      set_le_ih_k_offset (dih, le_ih_k_offset (dih) - ((bytes_or_entries / UNFM_P_SIZE) * dest->b_size));
-    }
-  }
-  
-  leaf_paste_in_buffer (dest_bi, 0, 0, bytes_or_entries, B_I_PITEM(src,ih) + ih_item_len(ih) - bytes_or_entries, 0);
-  return 1;
-}
 
+		/* merge first item (or its part) of src buffer with the last
+		   item of dest buffer. Both are of the same file */
+		leaf_paste_in_buffer(dest_bi,
+				     dest_nr_item - 1, ih_item_len(dih),
+				     bytes_or_entries, B_I_PITEM(src, ih), 0);
+
+		if (is_indirect_le_ih(dih)) {
+			RFALSE(get_ih_free_space(dih),
+			       "vs-10030: merge to left: last unformatted node of non-last indirect item %h must have zerto free space",
+			       ih);
+			if (bytes_or_entries == ih_item_len(ih))
+				set_ih_free_space(dih, get_ih_free_space(ih));
+		}
+
+		return 1;
+	}
+
+	/* copy boundary item to right (last_first == LAST_TO_FIRST) */
+
+	/* ( DEST is empty or last item of SOURCE and first item of DEST
+	   are the items of different object or of different types )
+	 */
+	src_nr_item = B_NR_ITEMS(src);
+	ih = B_N_PITEM_HEAD(src, src_nr_item - 1);
+	dih = B_N_PITEM_HEAD(dest, 0);
+
+	if (!dest_nr_item || !op_is_left_mergeable(&(dih->ih_key), src->b_size))
+		return 0;
+
+	if (is_direntry_le_ih(ih)) {
+		if (bytes_or_entries == -1)
+			/* bytes_or_entries = entries number in last item body of SOURCE */
+			bytes_or_entries = ih_entry_count(ih);
+
+		leaf_copy_dir_entries(dest_bi, src, LAST_TO_FIRST,
+				      src_nr_item - 1,
+				      ih_entry_count(ih) - bytes_or_entries,
+				      bytes_or_entries);
+		return 1;
+	}
+
+	/* copy part of the body of the last item of SOURCE to the begin of the body of the first item of the DEST;
+	   part defined by 'bytes_or_entries'; if byte_or_entriess == -1 copy whole body; change first item key of the DEST;
+	   don't create new item header
+	 */
+
+	RFALSE(is_indirect_le_ih(ih) && get_ih_free_space(ih),
+	       "vs-10040: merge to right: last unformatted node of non-last indirect item must be filled entirely (%h)",
+	       ih);
+
+	if (bytes_or_entries == -1) {
+		/* bytes_or_entries = length of last item body of SOURCE */
+		bytes_or_entries = ih_item_len(ih);
+
+		RFALSE(le_ih_k_offset(dih) !=
+		       le_ih_k_offset(ih) + op_bytes_number(ih, src->b_size),
+		       "vs-10050: items %h and %h do not match", ih, dih);
+
+		/* change first item key of the DEST */
+		set_le_ih_k_offset(dih, le_ih_k_offset(ih));
+
+		/* item becomes non-mergeable */
+		/* or mergeable if left item was */
+		set_le_ih_k_type(dih, le_ih_k_type(ih));
+	} else {
+		/* merge to right only part of item */
+		RFALSE(ih_item_len(ih) <= bytes_or_entries,
+		       "vs-10060: no so much bytes %lu (needed %lu)",
+		       (unsigned long)ih_item_len(ih),
+		       (unsigned long)bytes_or_entries);
+
+		/* change first item key of the DEST */
+		if (is_direct_le_ih(dih)) {
+			RFALSE(le_ih_k_offset(dih) <=
+			       (unsigned long)bytes_or_entries,
+			       "vs-10070: dih %h, bytes_or_entries(%d)", dih,
+			       bytes_or_entries);
+			set_le_ih_k_offset(dih,
+					   le_ih_k_offset(dih) -
+					   bytes_or_entries);
+		} else {
+			RFALSE(le_ih_k_offset(dih) <=
+			       (bytes_or_entries / UNFM_P_SIZE) * dest->b_size,
+			       "vs-10080: dih %h, bytes_or_entries(%d)",
+			       dih,
+			       (bytes_or_entries / UNFM_P_SIZE) * dest->b_size);
+			set_le_ih_k_offset(dih,
+					   le_ih_k_offset(dih) -
+					   ((bytes_or_entries / UNFM_P_SIZE) *
+					    dest->b_size));
+		}
+	}
+
+	leaf_paste_in_buffer(dest_bi, 0, 0, bytes_or_entries,
+			     B_I_PITEM(src,
+				       ih) + ih_item_len(ih) - bytes_or_entries,
+			     0);
+	return 1;
+}
 
 /* copy cpy_mun items from buffer src to buffer dest
  * last_first == FIRST_TO_LAST means, that we copy cpy_num  items beginning from first-th item in src to tail of dest
  * last_first == LAST_TO_FIRST means, that we copy cpy_num  items beginning from first-th item in src to head of dest
  */
-static void leaf_copy_items_entirely (struct buffer_info * dest_bi, struct buffer_head * src, int last_first,
-				      int first, int cpy_num)
+static void leaf_copy_items_entirely(struct buffer_info *dest_bi,
+				     struct buffer_head *src, int last_first,
+				     int first, int cpy_num)
 {
-    struct buffer_head * dest;
-    int nr, free_space;
-    int dest_before;
-    int last_loc, last_inserted_loc, location;
-    int i, j;
-    struct block_head * blkh;
-    struct item_head * ih;
-
-    RFALSE( last_first != LAST_TO_FIRST  && last_first != FIRST_TO_LAST,
-	    "vs-10090: bad last_first parameter %d", last_first);
-    RFALSE( B_NR_ITEMS (src) - first < cpy_num,
-	    "vs-10100: too few items in source %d, required %d from %d",
-	    B_NR_ITEMS(src), cpy_num, first);
-    RFALSE( cpy_num < 0, "vs-10110: can not copy negative amount of items");
-    RFALSE( ! dest_bi, "vs-10120: can not copy negative amount of items");
-
-    dest = dest_bi->bi_bh;
-
-    RFALSE( ! dest, "vs-10130: can not copy negative amount of items");
-
-    if (cpy_num == 0)
-	return;
-
-    blkh = B_BLK_HEAD(dest);
-    nr = blkh_nr_item( blkh );
-    free_space = blkh_free_space(blkh);
-  
-    /* we will insert items before 0-th or nr-th item in dest buffer. It depends of last_first parameter */
-    dest_before = (last_first == LAST_TO_FIRST) ? 0 : nr;
-
-    /* location of head of first new item */
-    ih = B_N_PITEM_HEAD (dest, dest_before);
-
-    RFALSE( blkh_free_space(blkh) < cpy_num * IH_SIZE,
-            "vs-10140: not enough free space for headers %d (needed %d)",
-            B_FREE_SPACE (dest), cpy_num * IH_SIZE);
-
-    /* prepare space for headers */
-    memmove (ih + cpy_num, ih, (nr-dest_before) * IH_SIZE);
-
-    /* copy item headers */
-    memcpy (ih, B_N_PITEM_HEAD (src, first), cpy_num * IH_SIZE);
-
-    free_space -= (IH_SIZE * cpy_num);
-    set_blkh_free_space( blkh, free_space );
-
-    /* location of unmovable item */
-    j = location = (dest_before == 0) ? dest->b_size : ih_location(ih-1);
-    for (i = dest_before; i < nr + cpy_num; i ++) {
-        location -= ih_item_len( ih + i - dest_before );
-        put_ih_location( ih + i - dest_before, location );
-    }
-
-    /* prepare space for items */
-    last_loc = ih_location( &(ih[nr+cpy_num-1-dest_before]) );
-    last_inserted_loc = ih_location( &(ih[cpy_num-1]) );
-
-    /* check free space */
-    RFALSE( free_space < j - last_inserted_loc,
-	    "vs-10150: not enough free space for items %d (needed %d)",
-            free_space, j - last_inserted_loc);
-
-    memmove (dest->b_data + last_loc,
-	     dest->b_data + last_loc + j - last_inserted_loc,
-	     last_inserted_loc - last_loc);
-
-    /* copy items */
-    memcpy (dest->b_data + last_inserted_loc, B_N_PITEM(src,(first + cpy_num - 1)),
-	    j - last_inserted_loc);
-
-    /* sizes, item number */
-    set_blkh_nr_item( blkh, nr + cpy_num );
-    set_blkh_free_space( blkh, free_space - (j - last_inserted_loc) );
-
-    do_balance_mark_leaf_dirty (dest_bi->tb, dest, 0);
-
-    if (dest_bi->bi_parent) {
-	struct disk_child *t_dc;
-	t_dc = B_N_CHILD (dest_bi->bi_parent, dest_bi->bi_position);
-	RFALSE( dc_block_number(t_dc) != dest->b_blocknr,
-	        "vs-10160: block number in bh does not match to field in disk_child structure %lu and %lu",
-                ( long unsigned ) dest->b_blocknr, 
-		( long unsigned ) dc_block_number(t_dc));
-	put_dc_size( t_dc, dc_size(t_dc) + (j - last_inserted_loc + IH_SIZE * cpy_num ) );
-    
-	do_balance_mark_internal_dirty (dest_bi->tb, dest_bi->bi_parent, 0);
-    }
-}
+	struct buffer_head *dest;
+	int nr, free_space;
+	int dest_before;
+	int last_loc, last_inserted_loc, location;
+	int i, j;
+	struct block_head *blkh;
+	struct item_head *ih;
+
+	RFALSE(last_first != LAST_TO_FIRST && last_first != FIRST_TO_LAST,
+	       "vs-10090: bad last_first parameter %d", last_first);
+	RFALSE(B_NR_ITEMS(src) - first < cpy_num,
+	       "vs-10100: too few items in source %d, required %d from %d",
+	       B_NR_ITEMS(src), cpy_num, first);
+	RFALSE(cpy_num < 0, "vs-10110: can not copy negative amount of items");
+	RFALSE(!dest_bi, "vs-10120: can not copy negative amount of items");
+
+	dest = dest_bi->bi_bh;
+
+	RFALSE(!dest, "vs-10130: can not copy negative amount of items");
+
+	if (cpy_num == 0)
+		return;
+
+	blkh = B_BLK_HEAD(dest);
+	nr = blkh_nr_item(blkh);
+	free_space = blkh_free_space(blkh);
+
+	/* we will insert items before 0-th or nr-th item in dest buffer. It depends of last_first parameter */
+	dest_before = (last_first == LAST_TO_FIRST) ? 0 : nr;
+
+	/* location of head of first new item */
+	ih = B_N_PITEM_HEAD(dest, dest_before);
+
+	RFALSE(blkh_free_space(blkh) < cpy_num * IH_SIZE,
+	       "vs-10140: not enough free space for headers %d (needed %d)",
+	       B_FREE_SPACE(dest), cpy_num * IH_SIZE);
+
+	/* prepare space for headers */
+	memmove(ih + cpy_num, ih, (nr - dest_before) * IH_SIZE);
+
+	/* copy item headers */
+	memcpy(ih, B_N_PITEM_HEAD(src, first), cpy_num * IH_SIZE);
+
+	free_space -= (IH_SIZE * cpy_num);
+	set_blkh_free_space(blkh, free_space);
+
+	/* location of unmovable item */
+	j = location = (dest_before == 0) ? dest->b_size : ih_location(ih - 1);
+	for (i = dest_before; i < nr + cpy_num; i++) {
+		location -= ih_item_len(ih + i - dest_before);
+		put_ih_location(ih + i - dest_before, location);
+	}
 
+	/* prepare space for items */
+	last_loc = ih_location(&(ih[nr + cpy_num - 1 - dest_before]));
+	last_inserted_loc = ih_location(&(ih[cpy_num - 1]));
+
+	/* check free space */
+	RFALSE(free_space < j - last_inserted_loc,
+	       "vs-10150: not enough free space for items %d (needed %d)",
+	       free_space, j - last_inserted_loc);
+
+	memmove(dest->b_data + last_loc,
+		dest->b_data + last_loc + j - last_inserted_loc,
+		last_inserted_loc - last_loc);
+
+	/* copy items */
+	memcpy(dest->b_data + last_inserted_loc,
+	       B_N_PITEM(src, (first + cpy_num - 1)), j - last_inserted_loc);
+
+	/* sizes, item number */
+	set_blkh_nr_item(blkh, nr + cpy_num);
+	set_blkh_free_space(blkh, free_space - (j - last_inserted_loc));
+
+	do_balance_mark_leaf_dirty(dest_bi->tb, dest, 0);
+
+	if (dest_bi->bi_parent) {
+		struct disk_child *t_dc;
+		t_dc = B_N_CHILD(dest_bi->bi_parent, dest_bi->bi_position);
+		RFALSE(dc_block_number(t_dc) != dest->b_blocknr,
+		       "vs-10160: block number in bh does not match to field in disk_child structure %lu and %lu",
+		       (long unsigned)dest->b_blocknr,
+		       (long unsigned)dc_block_number(t_dc));
+		put_dc_size(t_dc,
+			    dc_size(t_dc) + (j - last_inserted_loc +
+					     IH_SIZE * cpy_num));
+
+		do_balance_mark_internal_dirty(dest_bi->tb, dest_bi->bi_parent,
+					       0);
+	}
+}
 
 /* This function splits the (liquid) item into two items (useful when
    shifting part of an item into another node.) */
-static void leaf_item_bottle (struct buffer_info * dest_bi, struct buffer_head * src, int last_first,
-			      int item_num, int cpy_bytes)
+static void leaf_item_bottle(struct buffer_info *dest_bi,
+			     struct buffer_head *src, int last_first,
+			     int item_num, int cpy_bytes)
 {
-    struct buffer_head * dest = dest_bi->bi_bh;
-    struct item_head * ih;
-  
-    RFALSE( cpy_bytes == -1, "vs-10170: bytes == - 1 means: do not split item");
-
-    if ( last_first == FIRST_TO_LAST ) {
-	/* if ( if item in position item_num in buffer SOURCE is directory item ) */
-	if (is_direntry_le_ih (ih = B_N_PITEM_HEAD(src,item_num)))
-	    leaf_copy_dir_entries (dest_bi, src, FIRST_TO_LAST, item_num, 0, cpy_bytes);
-	else {
-	    struct item_head n_ih;
-      
-	    /* copy part of the body of the item number 'item_num' of SOURCE to the end of the DEST 
-	       part defined by 'cpy_bytes'; create new item header; change old item_header (????);
-	       n_ih = new item_header;
-	    */
-	    memcpy (&n_ih, ih, IH_SIZE);
-	    put_ih_item_len( &n_ih, cpy_bytes );
-	    if (is_indirect_le_ih (ih)) {
-		RFALSE( cpy_bytes == ih_item_len(ih) && get_ih_free_space(ih),
-		        "vs-10180: when whole indirect item is bottle to left neighbor, it must have free_space==0 (not %lu)",
-                        ( long unsigned ) get_ih_free_space (ih));
-		set_ih_free_space (&n_ih, 0);
-	    }
-
-	    RFALSE( op_is_left_mergeable (&(ih->ih_key), src->b_size),
-		    "vs-10190: bad mergeability of item %h", ih);
-	    n_ih.ih_version = ih->ih_version; /* JDM Endian safe, both le */
-	    leaf_insert_into_buf (dest_bi, B_NR_ITEMS(dest), &n_ih, B_N_PITEM (src, item_num), 0);
-	}
-    } else {
-	/*  if ( if item in position item_num in buffer SOURCE is directory item ) */
-	if (is_direntry_le_ih(ih = B_N_PITEM_HEAD (src, item_num)))
-	    leaf_copy_dir_entries (dest_bi, src, LAST_TO_FIRST, item_num, I_ENTRY_COUNT(ih) - cpy_bytes, cpy_bytes);
-	else {
-	    struct item_head n_ih;
-      
-	    /* copy part of the body of the item number 'item_num' of SOURCE to the begin of the DEST 
-	       part defined by 'cpy_bytes'; create new item header;
-	       n_ih = new item_header;
-	    */
-	    memcpy (&n_ih, ih, SHORT_KEY_SIZE);
-
-	    n_ih.ih_version = ih->ih_version; /* JDM Endian safe, both le */
-
-	    if (is_direct_le_ih (ih)) {
-		set_le_ih_k_offset (&n_ih, le_ih_k_offset (ih) + ih_item_len(ih) - cpy_bytes);
-		set_le_ih_k_type (&n_ih, TYPE_DIRECT);
-		set_ih_free_space (&n_ih, MAX_US_INT);
-	    } else {
-		/* indirect item */
-		RFALSE( !cpy_bytes && get_ih_free_space (ih),
-		        "vs-10200: ih->ih_free_space must be 0 when indirect item will be appended");
-		set_le_ih_k_offset (&n_ih, le_ih_k_offset (ih) + (ih_item_len(ih) - cpy_bytes) / UNFM_P_SIZE * dest->b_size);
-		set_le_ih_k_type (&n_ih, TYPE_INDIRECT);
-		set_ih_free_space (&n_ih, get_ih_free_space (ih));
-	    }
-      
-	    /* set item length */
-	    put_ih_item_len( &n_ih, cpy_bytes );
+	struct buffer_head *dest = dest_bi->bi_bh;
+	struct item_head *ih;
 
-	    n_ih.ih_version = ih->ih_version; /* JDM Endian safe, both le */
+	RFALSE(cpy_bytes == -1,
+	       "vs-10170: bytes == - 1 means: do not split item");
 
-	    leaf_insert_into_buf (dest_bi, 0, &n_ih, B_N_PITEM(src,item_num) + ih_item_len(ih) - cpy_bytes, 0);
+	if (last_first == FIRST_TO_LAST) {
+		/* if ( if item in position item_num in buffer SOURCE is directory item ) */
+		if (is_direntry_le_ih(ih = B_N_PITEM_HEAD(src, item_num)))
+			leaf_copy_dir_entries(dest_bi, src, FIRST_TO_LAST,
+					      item_num, 0, cpy_bytes);
+		else {
+			struct item_head n_ih;
+
+			/* copy part of the body of the item number 'item_num' of SOURCE to the end of the DEST 
+			   part defined by 'cpy_bytes'; create new item header; change old item_header (????);
+			   n_ih = new item_header;
+			 */
+			memcpy(&n_ih, ih, IH_SIZE);
+			put_ih_item_len(&n_ih, cpy_bytes);
+			if (is_indirect_le_ih(ih)) {
+				RFALSE(cpy_bytes == ih_item_len(ih)
+				       && get_ih_free_space(ih),
+				       "vs-10180: when whole indirect item is bottle to left neighbor, it must have free_space==0 (not %lu)",
+				       (long unsigned)get_ih_free_space(ih));
+				set_ih_free_space(&n_ih, 0);
+			}
+
+			RFALSE(op_is_left_mergeable(&(ih->ih_key), src->b_size),
+			       "vs-10190: bad mergeability of item %h", ih);
+			n_ih.ih_version = ih->ih_version;	/* JDM Endian safe, both le */
+			leaf_insert_into_buf(dest_bi, B_NR_ITEMS(dest), &n_ih,
+					     B_N_PITEM(src, item_num), 0);
+		}
+	} else {
+		/*  if ( if item in position item_num in buffer SOURCE is directory item ) */
+		if (is_direntry_le_ih(ih = B_N_PITEM_HEAD(src, item_num)))
+			leaf_copy_dir_entries(dest_bi, src, LAST_TO_FIRST,
+					      item_num,
+					      I_ENTRY_COUNT(ih) - cpy_bytes,
+					      cpy_bytes);
+		else {
+			struct item_head n_ih;
+
+			/* copy part of the body of the item number 'item_num' of SOURCE to the begin of the DEST 
+			   part defined by 'cpy_bytes'; create new item header;
+			   n_ih = new item_header;
+			 */
+			memcpy(&n_ih, ih, SHORT_KEY_SIZE);
+
+			n_ih.ih_version = ih->ih_version;	/* JDM Endian safe, both le */
+
+			if (is_direct_le_ih(ih)) {
+				set_le_ih_k_offset(&n_ih,
+						   le_ih_k_offset(ih) +
+						   ih_item_len(ih) - cpy_bytes);
+				set_le_ih_k_type(&n_ih, TYPE_DIRECT);
+				set_ih_free_space(&n_ih, MAX_US_INT);
+			} else {
+				/* indirect item */
+				RFALSE(!cpy_bytes && get_ih_free_space(ih),
+				       "vs-10200: ih->ih_free_space must be 0 when indirect item will be appended");
+				set_le_ih_k_offset(&n_ih,
+						   le_ih_k_offset(ih) +
+						   (ih_item_len(ih) -
+						    cpy_bytes) / UNFM_P_SIZE *
+						   dest->b_size);
+				set_le_ih_k_type(&n_ih, TYPE_INDIRECT);
+				set_ih_free_space(&n_ih, get_ih_free_space(ih));
+			}
+
+			/* set item length */
+			put_ih_item_len(&n_ih, cpy_bytes);
+
+			n_ih.ih_version = ih->ih_version;	/* JDM Endian safe, both le */
+
+			leaf_insert_into_buf(dest_bi, 0, &n_ih,
+					     B_N_PITEM(src,
+						       item_num) +
+					     ih_item_len(ih) - cpy_bytes, 0);
+		}
 	}
-    }
 }
 
-
 /* If cpy_bytes equals minus one than copy cpy_num whole items from SOURCE to DEST.
    If cpy_bytes not equal to minus one than copy cpy_num-1 whole items from SOURCE to DEST.
    From last item copy cpy_num bytes for regular item and cpy_num directory entries for
    directory item. */
-static int leaf_copy_items (struct buffer_info * dest_bi, struct buffer_head * src, int last_first, int cpy_num,
-			    int cpy_bytes)
+static int leaf_copy_items(struct buffer_info *dest_bi, struct buffer_head *src,
+			   int last_first, int cpy_num, int cpy_bytes)
 {
-  struct buffer_head * dest;
-  int pos, i, src_nr_item, bytes;
-
-  dest = dest_bi->bi_bh;
-  RFALSE( !dest || !src, "vs-10210: !dest || !src");
-  RFALSE( last_first != FIRST_TO_LAST && last_first != LAST_TO_FIRST,
-	  "vs-10220:last_first != FIRST_TO_LAST && last_first != LAST_TO_FIRST");
-  RFALSE( B_NR_ITEMS(src) < cpy_num,
-	  "vs-10230: No enough items: %d, req. %d", B_NR_ITEMS(src), cpy_num);
-  RFALSE( cpy_num < 0,"vs-10240: cpy_num < 0 (%d)", cpy_num);
+	struct buffer_head *dest;
+	int pos, i, src_nr_item, bytes;
 
- if ( cpy_num == 0 )
-   return 0;
- 
- if ( last_first == FIRST_TO_LAST ) {
-   /* copy items to left */
-   pos = 0;
-   if ( cpy_num == 1 )
-     bytes = cpy_bytes;
-   else
-     bytes = -1;
-   
-   /* copy the first item or it part or nothing to the end of the DEST (i = leaf_copy_boundary_item(DEST,SOURCE,0,bytes)) */
-   i = leaf_copy_boundary_item (dest_bi, src, FIRST_TO_LAST, bytes);
-   cpy_num -= i;
-   if ( cpy_num == 0 )
-     return i;
-   pos += i;
-   if ( cpy_bytes == -1 )
-     /* copy first cpy_num items starting from position 'pos' of SOURCE to end of DEST */
-     leaf_copy_items_entirely (dest_bi, src, FIRST_TO_LAST, pos, cpy_num);
-   else {
-     /* copy first cpy_num-1 items starting from position 'pos-1' of the SOURCE to the end of the DEST */
-     leaf_copy_items_entirely (dest_bi, src, FIRST_TO_LAST, pos, cpy_num-1);
-	     
-     /* copy part of the item which number is cpy_num+pos-1 to the end of the DEST */
-     leaf_item_bottle (dest_bi, src, FIRST_TO_LAST, cpy_num+pos-1, cpy_bytes);
-   } 
- } else {
-   /* copy items to right */
-   src_nr_item = B_NR_ITEMS (src);
-   if ( cpy_num == 1 )
-     bytes = cpy_bytes;
-   else
-     bytes = -1;
-   
-   /* copy the last item or it part or nothing to the begin of the DEST (i = leaf_copy_boundary_item(DEST,SOURCE,1,bytes)); */
-   i = leaf_copy_boundary_item (dest_bi, src, LAST_TO_FIRST, bytes);
-   
-   cpy_num -= i;
-   if ( cpy_num == 0 )
-     return i;
-   
-   pos = src_nr_item - cpy_num - i;
-   if ( cpy_bytes == -1 ) {
-     /* starting from position 'pos' copy last cpy_num items of SOURCE to begin of DEST */
-     leaf_copy_items_entirely (dest_bi, src, LAST_TO_FIRST, pos, cpy_num);
-   } else {
-     /* copy last cpy_num-1 items starting from position 'pos+1' of the SOURCE to the begin of the DEST; */
-     leaf_copy_items_entirely (dest_bi, src, LAST_TO_FIRST, pos+1, cpy_num-1);
-
-     /* copy part of the item which number is pos to the begin of the DEST */
-     leaf_item_bottle (dest_bi, src, LAST_TO_FIRST, pos, cpy_bytes);
-   }
- }
- return i;
+	dest = dest_bi->bi_bh;
+	RFALSE(!dest || !src, "vs-10210: !dest || !src");
+	RFALSE(last_first != FIRST_TO_LAST && last_first != LAST_TO_FIRST,
+	       "vs-10220:last_first != FIRST_TO_LAST && last_first != LAST_TO_FIRST");
+	RFALSE(B_NR_ITEMS(src) < cpy_num,
+	       "vs-10230: No enough items: %d, req. %d", B_NR_ITEMS(src),
+	       cpy_num);
+	RFALSE(cpy_num < 0, "vs-10240: cpy_num < 0 (%d)", cpy_num);
+
+	if (cpy_num == 0)
+		return 0;
+
+	if (last_first == FIRST_TO_LAST) {
+		/* copy items to left */
+		pos = 0;
+		if (cpy_num == 1)
+			bytes = cpy_bytes;
+		else
+			bytes = -1;
+
+		/* copy the first item or it part or nothing to the end of the DEST (i = leaf_copy_boundary_item(DEST,SOURCE,0,bytes)) */
+		i = leaf_copy_boundary_item(dest_bi, src, FIRST_TO_LAST, bytes);
+		cpy_num -= i;
+		if (cpy_num == 0)
+			return i;
+		pos += i;
+		if (cpy_bytes == -1)
+			/* copy first cpy_num items starting from position 'pos' of SOURCE to end of DEST */
+			leaf_copy_items_entirely(dest_bi, src, FIRST_TO_LAST,
+						 pos, cpy_num);
+		else {
+			/* copy first cpy_num-1 items starting from position 'pos-1' of the SOURCE to the end of the DEST */
+			leaf_copy_items_entirely(dest_bi, src, FIRST_TO_LAST,
+						 pos, cpy_num - 1);
+
+			/* copy part of the item which number is cpy_num+pos-1 to the end of the DEST */
+			leaf_item_bottle(dest_bi, src, FIRST_TO_LAST,
+					 cpy_num + pos - 1, cpy_bytes);
+		}
+	} else {
+		/* copy items to right */
+		src_nr_item = B_NR_ITEMS(src);
+		if (cpy_num == 1)
+			bytes = cpy_bytes;
+		else
+			bytes = -1;
+
+		/* copy the last item or it part or nothing to the begin of the DEST (i = leaf_copy_boundary_item(DEST,SOURCE,1,bytes)); */
+		i = leaf_copy_boundary_item(dest_bi, src, LAST_TO_FIRST, bytes);
+
+		cpy_num -= i;
+		if (cpy_num == 0)
+			return i;
+
+		pos = src_nr_item - cpy_num - i;
+		if (cpy_bytes == -1) {
+			/* starting from position 'pos' copy last cpy_num items of SOURCE to begin of DEST */
+			leaf_copy_items_entirely(dest_bi, src, LAST_TO_FIRST,
+						 pos, cpy_num);
+		} else {
+			/* copy last cpy_num-1 items starting from position 'pos+1' of the SOURCE to the begin of the DEST; */
+			leaf_copy_items_entirely(dest_bi, src, LAST_TO_FIRST,
+						 pos + 1, cpy_num - 1);
+
+			/* copy part of the item which number is pos to the begin of the DEST */
+			leaf_item_bottle(dest_bi, src, LAST_TO_FIRST, pos,
+					 cpy_bytes);
+		}
+	}
+	return i;
 }
 
-
 /* there are types of coping: from S[0] to L[0], from S[0] to R[0],
    from R[0] to L[0]. for each of these we have to define parent and
    positions of destination and source buffers */
-static void leaf_define_dest_src_infos (int shift_mode, struct tree_balance * tb, struct buffer_info * dest_bi,
-					struct buffer_info * src_bi, int * first_last,
-					struct buffer_head * Snew)
+static void leaf_define_dest_src_infos(int shift_mode, struct tree_balance *tb,
+				       struct buffer_info *dest_bi,
+				       struct buffer_info *src_bi,
+				       int *first_last,
+				       struct buffer_head *Snew)
 {
-    memset (dest_bi, 0, sizeof (struct buffer_info));
-    memset (src_bi, 0, sizeof (struct buffer_info));
+	memset(dest_bi, 0, sizeof(struct buffer_info));
+	memset(src_bi, 0, sizeof(struct buffer_info));
 
-    /* define dest, src, dest parent, dest position */
-    switch (shift_mode) {
-    case LEAF_FROM_S_TO_L:    /* it is used in leaf_shift_left */
-	src_bi->tb = tb;
-	src_bi->bi_bh = PATH_PLAST_BUFFER (tb->tb_path);
-	src_bi->bi_parent = PATH_H_PPARENT (tb->tb_path, 0);
-	src_bi->bi_position = PATH_H_B_ITEM_ORDER (tb->tb_path, 0);	/* src->b_item_order */
-	dest_bi->tb = tb;
-	dest_bi->bi_bh = tb->L[0];
-	dest_bi->bi_parent = tb->FL[0];
-	dest_bi->bi_position = get_left_neighbor_position (tb, 0);
-	*first_last = FIRST_TO_LAST;
-	break;
-
-    case LEAF_FROM_S_TO_R:  /* it is used in leaf_shift_right */
-	src_bi->tb = tb;
-	src_bi->bi_bh = PATH_PLAST_BUFFER (tb->tb_path);
-	src_bi->bi_parent = PATH_H_PPARENT (tb->tb_path, 0);
-	src_bi->bi_position = PATH_H_B_ITEM_ORDER (tb->tb_path, 0);
-	dest_bi->tb = tb;
-	dest_bi->bi_bh = tb->R[0];
-	dest_bi->bi_parent = tb->FR[0];
-	dest_bi->bi_position = get_right_neighbor_position (tb, 0);
-	*first_last = LAST_TO_FIRST;
-	break;
-
-    case LEAF_FROM_R_TO_L:  /* it is used in balance_leaf_when_delete */
-	src_bi->tb = tb;
-	src_bi->bi_bh = tb->R[0];
-	src_bi->bi_parent = tb->FR[0];
-	src_bi->bi_position = get_right_neighbor_position (tb, 0);
-	dest_bi->tb = tb;
-	dest_bi->bi_bh = tb->L[0];
-	dest_bi->bi_parent = tb->FL[0];
-	dest_bi->bi_position = get_left_neighbor_position (tb, 0);
-	*first_last = FIRST_TO_LAST;
-	break;
-    
-    case LEAF_FROM_L_TO_R:  /* it is used in balance_leaf_when_delete */
-	src_bi->tb = tb;
-	src_bi->bi_bh = tb->L[0];
-	src_bi->bi_parent = tb->FL[0];
-	src_bi->bi_position = get_left_neighbor_position (tb, 0);
-	dest_bi->tb = tb;
-	dest_bi->bi_bh = tb->R[0];
-	dest_bi->bi_parent = tb->FR[0];
-	dest_bi->bi_position = get_right_neighbor_position (tb, 0);
-	*first_last = LAST_TO_FIRST;
-	break;
-
-    case LEAF_FROM_S_TO_SNEW:
-	src_bi->tb = tb;
-	src_bi->bi_bh = PATH_PLAST_BUFFER (tb->tb_path);
-	src_bi->bi_parent = PATH_H_PPARENT (tb->tb_path, 0);
-	src_bi->bi_position = PATH_H_B_ITEM_ORDER (tb->tb_path, 0);
-	dest_bi->tb = tb;
-	dest_bi->bi_bh = Snew;
-	dest_bi->bi_parent = NULL;
-	dest_bi->bi_position = 0;
-	*first_last = LAST_TO_FIRST;
-	break;
-    
-    default:
-	reiserfs_panic (NULL, "vs-10250: leaf_define_dest_src_infos: shift type is unknown (%d)", shift_mode);
-    }
-    RFALSE( src_bi->bi_bh == 0 || dest_bi->bi_bh == 0,
-	    "vs-10260: mode==%d, source (%p) or dest (%p) buffer is initialized incorrectly",
-	    shift_mode, src_bi->bi_bh, dest_bi->bi_bh);
+	/* define dest, src, dest parent, dest position */
+	switch (shift_mode) {
+	case LEAF_FROM_S_TO_L:	/* it is used in leaf_shift_left */
+		src_bi->tb = tb;
+		src_bi->bi_bh = PATH_PLAST_BUFFER(tb->tb_path);
+		src_bi->bi_parent = PATH_H_PPARENT(tb->tb_path, 0);
+		src_bi->bi_position = PATH_H_B_ITEM_ORDER(tb->tb_path, 0);	/* src->b_item_order */
+		dest_bi->tb = tb;
+		dest_bi->bi_bh = tb->L[0];
+		dest_bi->bi_parent = tb->FL[0];
+		dest_bi->bi_position = get_left_neighbor_position(tb, 0);
+		*first_last = FIRST_TO_LAST;
+		break;
+
+	case LEAF_FROM_S_TO_R:	/* it is used in leaf_shift_right */
+		src_bi->tb = tb;
+		src_bi->bi_bh = PATH_PLAST_BUFFER(tb->tb_path);
+		src_bi->bi_parent = PATH_H_PPARENT(tb->tb_path, 0);
+		src_bi->bi_position = PATH_H_B_ITEM_ORDER(tb->tb_path, 0);
+		dest_bi->tb = tb;
+		dest_bi->bi_bh = tb->R[0];
+		dest_bi->bi_parent = tb->FR[0];
+		dest_bi->bi_position = get_right_neighbor_position(tb, 0);
+		*first_last = LAST_TO_FIRST;
+		break;
+
+	case LEAF_FROM_R_TO_L:	/* it is used in balance_leaf_when_delete */
+		src_bi->tb = tb;
+		src_bi->bi_bh = tb->R[0];
+		src_bi->bi_parent = tb->FR[0];
+		src_bi->bi_position = get_right_neighbor_position(tb, 0);
+		dest_bi->tb = tb;
+		dest_bi->bi_bh = tb->L[0];
+		dest_bi->bi_parent = tb->FL[0];
+		dest_bi->bi_position = get_left_neighbor_position(tb, 0);
+		*first_last = FIRST_TO_LAST;
+		break;
+
+	case LEAF_FROM_L_TO_R:	/* it is used in balance_leaf_when_delete */
+		src_bi->tb = tb;
+		src_bi->bi_bh = tb->L[0];
+		src_bi->bi_parent = tb->FL[0];
+		src_bi->bi_position = get_left_neighbor_position(tb, 0);
+		dest_bi->tb = tb;
+		dest_bi->bi_bh = tb->R[0];
+		dest_bi->bi_parent = tb->FR[0];
+		dest_bi->bi_position = get_right_neighbor_position(tb, 0);
+		*first_last = LAST_TO_FIRST;
+		break;
+
+	case LEAF_FROM_S_TO_SNEW:
+		src_bi->tb = tb;
+		src_bi->bi_bh = PATH_PLAST_BUFFER(tb->tb_path);
+		src_bi->bi_parent = PATH_H_PPARENT(tb->tb_path, 0);
+		src_bi->bi_position = PATH_H_B_ITEM_ORDER(tb->tb_path, 0);
+		dest_bi->tb = tb;
+		dest_bi->bi_bh = Snew;
+		dest_bi->bi_parent = NULL;
+		dest_bi->bi_position = 0;
+		*first_last = LAST_TO_FIRST;
+		break;
+
+	default:
+		reiserfs_panic(NULL,
+			       "vs-10250: leaf_define_dest_src_infos: shift type is unknown (%d)",
+			       shift_mode);
+	}
+	RFALSE(src_bi->bi_bh == 0 || dest_bi->bi_bh == 0,
+	       "vs-10260: mode==%d, source (%p) or dest (%p) buffer is initialized incorrectly",
+	       shift_mode, src_bi->bi_bh, dest_bi->bi_bh);
 }
 
-
-
-
 /* copy mov_num items and mov_bytes of the (mov_num-1)th item to
    neighbor. Delete them from source */
-int leaf_move_items (int shift_mode, struct tree_balance * tb, int mov_num, int mov_bytes, struct buffer_head * Snew)
+int leaf_move_items(int shift_mode, struct tree_balance *tb, int mov_num,
+		    int mov_bytes, struct buffer_head *Snew)
 {
-  int ret_value;
-  struct buffer_info dest_bi, src_bi;
-  int first_last;
-
-  leaf_define_dest_src_infos (shift_mode, tb, &dest_bi, &src_bi, &first_last, Snew);
-
-  ret_value = leaf_copy_items (&dest_bi, src_bi.bi_bh, first_last, mov_num, mov_bytes);
-
-  leaf_delete_items (&src_bi, first_last, (first_last == FIRST_TO_LAST) ? 0 : (B_NR_ITEMS(src_bi.bi_bh) - mov_num), mov_num, mov_bytes);
+	int ret_value;
+	struct buffer_info dest_bi, src_bi;
+	int first_last;
+
+	leaf_define_dest_src_infos(shift_mode, tb, &dest_bi, &src_bi,
+				   &first_last, Snew);
+
+	ret_value =
+	    leaf_copy_items(&dest_bi, src_bi.bi_bh, first_last, mov_num,
+			    mov_bytes);
+
+	leaf_delete_items(&src_bi, first_last,
+			  (first_last ==
+			   FIRST_TO_LAST) ? 0 : (B_NR_ITEMS(src_bi.bi_bh) -
+						 mov_num), mov_num, mov_bytes);
 
-  
-  return ret_value;
+	return ret_value;
 }
 
-
 /* Shift shift_num items (and shift_bytes of last shifted item if shift_bytes != -1)
    from S[0] to L[0] and replace the delimiting key */
-int leaf_shift_left (struct tree_balance * tb, int shift_num, int shift_bytes)
+int leaf_shift_left(struct tree_balance *tb, int shift_num, int shift_bytes)
 {
-  struct buffer_head * S0 = PATH_PLAST_BUFFER (tb->tb_path);
-  int i;
+	struct buffer_head *S0 = PATH_PLAST_BUFFER(tb->tb_path);
+	int i;
 
-  /* move shift_num (and shift_bytes bytes) items from S[0] to left neighbor L[0] */
-  i = leaf_move_items (LEAF_FROM_S_TO_L, tb, shift_num, shift_bytes, NULL);
+	/* move shift_num (and shift_bytes bytes) items from S[0] to left neighbor L[0] */
+	i = leaf_move_items(LEAF_FROM_S_TO_L, tb, shift_num, shift_bytes, NULL);
 
-  if ( shift_num ) {
-    if (B_NR_ITEMS (S0) == 0) { /* number of items in S[0] == 0 */
+	if (shift_num) {
+		if (B_NR_ITEMS(S0) == 0) {	/* number of items in S[0] == 0 */
 
-      RFALSE( shift_bytes != -1,
-	      "vs-10270: S0 is empty now, but shift_bytes != -1 (%d)", 
-	      shift_bytes);
+			RFALSE(shift_bytes != -1,
+			       "vs-10270: S0 is empty now, but shift_bytes != -1 (%d)",
+			       shift_bytes);
 #ifdef CONFIG_REISERFS_CHECK
-      if (tb->tb_mode == M_PASTE || tb->tb_mode == M_INSERT) {
-	print_cur_tb ("vs-10275");
-	reiserfs_panic (tb->tb_sb, "vs-10275: leaf_shift_left: balance condition corrupted (%c)", tb->tb_mode);
-      }
+			if (tb->tb_mode == M_PASTE || tb->tb_mode == M_INSERT) {
+				print_cur_tb("vs-10275");
+				reiserfs_panic(tb->tb_sb,
+					       "vs-10275: leaf_shift_left: balance condition corrupted (%c)",
+					       tb->tb_mode);
+			}
 #endif
 
-      if (PATH_H_POSITION (tb->tb_path, 1) == 0)
-	replace_key (tb, tb->CFL[0], tb->lkey[0], PATH_H_PPARENT (tb->tb_path, 0), 0);
+			if (PATH_H_POSITION(tb->tb_path, 1) == 0)
+				replace_key(tb, tb->CFL[0], tb->lkey[0],
+					    PATH_H_PPARENT(tb->tb_path, 0), 0);
+
+		} else {
+			/* replace lkey in CFL[0] by 0-th key from S[0]; */
+			replace_key(tb, tb->CFL[0], tb->lkey[0], S0, 0);
+
+			RFALSE((shift_bytes != -1 &&
+				!(is_direntry_le_ih(B_N_PITEM_HEAD(S0, 0))
+				  && !I_ENTRY_COUNT(B_N_PITEM_HEAD(S0, 0)))) &&
+			       (!op_is_left_mergeable
+				(B_N_PKEY(S0, 0), S0->b_size)),
+			       "vs-10280: item must be mergeable");
+		}
+	}
 
-    } else {     
-      /* replace lkey in CFL[0] by 0-th key from S[0]; */
-      replace_key (tb, tb->CFL[0], tb->lkey[0], S0, 0);
-      
-      RFALSE( (shift_bytes != -1 &&
-              !(is_direntry_le_ih (B_N_PITEM_HEAD (S0, 0))
-                && !I_ENTRY_COUNT (B_N_PITEM_HEAD (S0, 0)))) &&
-	      (!op_is_left_mergeable (B_N_PKEY (S0, 0), S0->b_size)),
-	      "vs-10280: item must be mergeable");
-    }
-  }
-  
-  return i;
+	return i;
 }
 
-
-
-
-
 /* CLEANING STOPPED HERE */
 
-
-
-
 /* Shift shift_num (shift_bytes) items from S[0] to the right neighbor, and replace the delimiting key */
-int	leaf_shift_right(
-		struct tree_balance * tb, 
-		int shift_num,
-		int shift_bytes
-	)
+int leaf_shift_right(struct tree_balance *tb, int shift_num, int shift_bytes)
 {
-  //  struct buffer_head * S0 = PATH_PLAST_BUFFER (tb->tb_path);
-  int ret_value;
-
-  /* move shift_num (and shift_bytes) items from S[0] to right neighbor R[0] */
-  ret_value = leaf_move_items (LEAF_FROM_S_TO_R, tb, shift_num, shift_bytes, NULL);
+	//  struct buffer_head * S0 = PATH_PLAST_BUFFER (tb->tb_path);
+	int ret_value;
 
-  /* replace rkey in CFR[0] by the 0-th key from R[0] */
-  if (shift_num) {
-    replace_key (tb, tb->CFR[0], tb->rkey[0], tb->R[0], 0);
+	/* move shift_num (and shift_bytes) items from S[0] to right neighbor R[0] */
+	ret_value =
+	    leaf_move_items(LEAF_FROM_S_TO_R, tb, shift_num, shift_bytes, NULL);
+
+	/* replace rkey in CFR[0] by the 0-th key from R[0] */
+	if (shift_num) {
+		replace_key(tb, tb->CFR[0], tb->rkey[0], tb->R[0], 0);
 
-  }
+	}
 
-  return ret_value;
+	return ret_value;
 }
 
-
-
-static void leaf_delete_items_entirely (struct buffer_info * bi,
-					int first, int del_num);
+static void leaf_delete_items_entirely(struct buffer_info *bi,
+				       int first, int del_num);
 /*  If del_bytes == -1, starting from position 'first' delete del_num items in whole in buffer CUR.
     If not. 
     If last_first == 0. Starting from position 'first' delete del_num-1 items in whole. Delete part of body of
@@ -670,287 +731,292 @@ static void leaf_delete_items_entirely (
     If last_first == 1. Starting from position 'first+1' delete del_num-1 items in whole. Delete part of body of
     the last item . Part defined by del_bytes. Don't delete last item header.
 */
-void leaf_delete_items (struct buffer_info * cur_bi, int last_first, 
-			int first, int del_num, int del_bytes)
+void leaf_delete_items(struct buffer_info *cur_bi, int last_first,
+		       int first, int del_num, int del_bytes)
 {
-    struct buffer_head * bh;
-    int item_amount = B_NR_ITEMS (bh = cur_bi->bi_bh);
+	struct buffer_head *bh;
+	int item_amount = B_NR_ITEMS(bh = cur_bi->bi_bh);
 
-    RFALSE( !bh, "10155: bh is not defined");
-    RFALSE( del_num < 0, "10160: del_num can not be < 0. del_num==%d", del_num);
-    RFALSE( first < 0 || first + del_num > item_amount,
-	    "10165: invalid number of first item to be deleted (%d) or "
-	    "no so much items (%d) to delete (only %d)", 
-	    first, first + del_num, item_amount);
-
-    if ( del_num == 0 )
-	return;
-
-    if ( first == 0 && del_num == item_amount && del_bytes == -1 ) {
-	make_empty_node (cur_bi);
-	do_balance_mark_leaf_dirty (cur_bi->tb, bh, 0);
-	return;
-    }
-
-    if ( del_bytes == -1 )
-	/* delete del_num items beginning from item in position first */
-	leaf_delete_items_entirely (cur_bi, first, del_num);
-    else {
-	if ( last_first == FIRST_TO_LAST ) {
-	    /* delete del_num-1 items beginning from item in position first  */
-	    leaf_delete_items_entirely (cur_bi, first, del_num-1);
-
-	    /* delete the part of the first item of the bh
-	       do not delete item header
-	    */
-	    leaf_cut_from_buffer (cur_bi, 0, 0, del_bytes);
-	} else  {
-	    struct item_head * ih;
-	    int len;
-
-	    /* delete del_num-1 items beginning from item in position first+1  */
-	    leaf_delete_items_entirely (cur_bi, first+1, del_num-1);
-
-	    if (is_direntry_le_ih (ih = B_N_PITEM_HEAD(bh, B_NR_ITEMS(bh)-1))) 	/* the last item is directory  */
-	        /* len = numbers of directory entries in this item */
-		len = ih_entry_count(ih);
-	    else
-	        /* len = body len of item */
-		len = ih_item_len(ih);
-
-	    /* delete the part of the last item of the bh 
-	       do not delete item header
-	    */
-	    leaf_cut_from_buffer (cur_bi, B_NR_ITEMS(bh)-1, len - del_bytes, del_bytes);
+	RFALSE(!bh, "10155: bh is not defined");
+	RFALSE(del_num < 0, "10160: del_num can not be < 0. del_num==%d",
+	       del_num);
+	RFALSE(first < 0
+	       || first + del_num > item_amount,
+	       "10165: invalid number of first item to be deleted (%d) or "
+	       "no so much items (%d) to delete (only %d)", first,
+	       first + del_num, item_amount);
+
+	if (del_num == 0)
+		return;
+
+	if (first == 0 && del_num == item_amount && del_bytes == -1) {
+		make_empty_node(cur_bi);
+		do_balance_mark_leaf_dirty(cur_bi->tb, bh, 0);
+		return;
 	}
-    }
-}
 
+	if (del_bytes == -1)
+		/* delete del_num items beginning from item in position first */
+		leaf_delete_items_entirely(cur_bi, first, del_num);
+	else {
+		if (last_first == FIRST_TO_LAST) {
+			/* delete del_num-1 items beginning from item in position first  */
+			leaf_delete_items_entirely(cur_bi, first, del_num - 1);
+
+			/* delete the part of the first item of the bh
+			   do not delete item header
+			 */
+			leaf_cut_from_buffer(cur_bi, 0, 0, del_bytes);
+		} else {
+			struct item_head *ih;
+			int len;
+
+			/* delete del_num-1 items beginning from item in position first+1  */
+			leaf_delete_items_entirely(cur_bi, first + 1,
+						   del_num - 1);
+
+			if (is_direntry_le_ih
+			    (ih = B_N_PITEM_HEAD(bh, B_NR_ITEMS(bh) - 1)))
+				/* the last item is directory  */
+				/* len = numbers of directory entries in this item */
+				len = ih_entry_count(ih);
+			else
+				/* len = body len of item */
+				len = ih_item_len(ih);
+
+			/* delete the part of the last item of the bh 
+			   do not delete item header
+			 */
+			leaf_cut_from_buffer(cur_bi, B_NR_ITEMS(bh) - 1,
+					     len - del_bytes, del_bytes);
+		}
+	}
+}
 
 /* insert item into the leaf node in position before */
-void leaf_insert_into_buf (struct buffer_info * bi, int before,
-			   struct item_head * inserted_item_ih,
-			   const char * inserted_item_body,
-			   int zeros_number)
+void leaf_insert_into_buf(struct buffer_info *bi, int before,
+			  struct item_head *inserted_item_ih,
+			  const char *inserted_item_body, int zeros_number)
 {
-    struct buffer_head * bh = bi->bi_bh;
-    int nr, free_space;
-    struct block_head * blkh;
-    struct item_head * ih;
-    int i;
-    int last_loc, unmoved_loc;
-    char * to;
-
-
-    blkh = B_BLK_HEAD(bh);
-    nr = blkh_nr_item(blkh);
-    free_space = blkh_free_space( blkh );
-
-    /* check free space */
-    RFALSE( free_space < ih_item_len(inserted_item_ih) + IH_SIZE,
-            "vs-10170: not enough free space in block %z, new item %h",
-            bh, inserted_item_ih);
-    RFALSE( zeros_number > ih_item_len(inserted_item_ih),
-	    "vs-10172: zero number == %d, item length == %d",
-            zeros_number, ih_item_len(inserted_item_ih));
-
-
-    /* get item new item must be inserted before */
-    ih = B_N_PITEM_HEAD (bh, before);
-
-    /* prepare space for the body of new item */
-    last_loc = nr ? ih_location( &(ih[nr - before - 1]) ) : bh->b_size;
-    unmoved_loc = before ? ih_location( ih-1 ) : bh->b_size;
-
-
-    memmove (bh->b_data + last_loc - ih_item_len(inserted_item_ih), 
-	     bh->b_data + last_loc, unmoved_loc - last_loc);
-
-    to = bh->b_data + unmoved_loc - ih_item_len(inserted_item_ih);
-    memset (to, 0, zeros_number);
-    to += zeros_number;
-
-    /* copy body to prepared space */
-    if (inserted_item_body)
-	memmove (to, inserted_item_body, ih_item_len(inserted_item_ih) - zeros_number);
-    else
-	memset(to, '\0', ih_item_len(inserted_item_ih) - zeros_number);
-  
-    /* insert item header */
-    memmove (ih + 1, ih, IH_SIZE * (nr - before));
-    memmove (ih, inserted_item_ih, IH_SIZE);
-  
-    /* change locations */
-    for (i = before; i < nr + 1; i ++)
-    {
-        unmoved_loc -= ih_item_len( &(ih[i-before]));
-	put_ih_location( &(ih[i-before]), unmoved_loc );
-    }
-  
-    /* sizes, free space, item number */
-    set_blkh_nr_item( blkh, blkh_nr_item(blkh) + 1 );
-    set_blkh_free_space( blkh,
-                    free_space - (IH_SIZE + ih_item_len(inserted_item_ih ) ) );
-    do_balance_mark_leaf_dirty (bi->tb, bh, 1);
-
-    if (bi->bi_parent) { 
-	struct disk_child *t_dc;
-	t_dc = B_N_CHILD (bi->bi_parent, bi->bi_position);
-	put_dc_size( t_dc, dc_size(t_dc) + (IH_SIZE + ih_item_len(inserted_item_ih)));
-	do_balance_mark_internal_dirty (bi->tb, bi->bi_parent, 0);
-    }
-}
+	struct buffer_head *bh = bi->bi_bh;
+	int nr, free_space;
+	struct block_head *blkh;
+	struct item_head *ih;
+	int i;
+	int last_loc, unmoved_loc;
+	char *to;
+
+	blkh = B_BLK_HEAD(bh);
+	nr = blkh_nr_item(blkh);
+	free_space = blkh_free_space(blkh);
+
+	/* check free space */
+	RFALSE(free_space < ih_item_len(inserted_item_ih) + IH_SIZE,
+	       "vs-10170: not enough free space in block %z, new item %h",
+	       bh, inserted_item_ih);
+	RFALSE(zeros_number > ih_item_len(inserted_item_ih),
+	       "vs-10172: zero number == %d, item length == %d",
+	       zeros_number, ih_item_len(inserted_item_ih));
+
+	/* get item new item must be inserted before */
+	ih = B_N_PITEM_HEAD(bh, before);
+
+	/* prepare space for the body of new item */
+	last_loc = nr ? ih_location(&(ih[nr - before - 1])) : bh->b_size;
+	unmoved_loc = before ? ih_location(ih - 1) : bh->b_size;
+
+	memmove(bh->b_data + last_loc - ih_item_len(inserted_item_ih),
+		bh->b_data + last_loc, unmoved_loc - last_loc);
+
+	to = bh->b_data + unmoved_loc - ih_item_len(inserted_item_ih);
+	memset(to, 0, zeros_number);
+	to += zeros_number;
+
+	/* copy body to prepared space */
+	if (inserted_item_body)
+		memmove(to, inserted_item_body,
+			ih_item_len(inserted_item_ih) - zeros_number);
+	else
+		memset(to, '\0', ih_item_len(inserted_item_ih) - zeros_number);
+
+	/* insert item header */
+	memmove(ih + 1, ih, IH_SIZE * (nr - before));
+	memmove(ih, inserted_item_ih, IH_SIZE);
+
+	/* change locations */
+	for (i = before; i < nr + 1; i++) {
+		unmoved_loc -= ih_item_len(&(ih[i - before]));
+		put_ih_location(&(ih[i - before]), unmoved_loc);
+	}
 
+	/* sizes, free space, item number */
+	set_blkh_nr_item(blkh, blkh_nr_item(blkh) + 1);
+	set_blkh_free_space(blkh,
+			    free_space - (IH_SIZE +
+					  ih_item_len(inserted_item_ih)));
+	do_balance_mark_leaf_dirty(bi->tb, bh, 1);
+
+	if (bi->bi_parent) {
+		struct disk_child *t_dc;
+		t_dc = B_N_CHILD(bi->bi_parent, bi->bi_position);
+		put_dc_size(t_dc,
+			    dc_size(t_dc) + (IH_SIZE +
+					     ih_item_len(inserted_item_ih)));
+		do_balance_mark_internal_dirty(bi->tb, bi->bi_parent, 0);
+	}
+}
 
 /* paste paste_size bytes to affected_item_num-th item. 
    When item is a directory, this only prepare space for new entries */
-void leaf_paste_in_buffer (struct buffer_info * bi, int affected_item_num,
-			   int pos_in_item, int paste_size,
-			   const char * body,
-			   int zeros_number)
+void leaf_paste_in_buffer(struct buffer_info *bi, int affected_item_num,
+			  int pos_in_item, int paste_size,
+			  const char *body, int zeros_number)
 {
-    struct buffer_head * bh = bi->bi_bh;
-    int nr, free_space;
-    struct block_head * blkh;
-    struct item_head * ih;
-    int i;
-    int last_loc, unmoved_loc;
-
-    blkh = B_BLK_HEAD(bh);
-    nr = blkh_nr_item(blkh);
-    free_space = blkh_free_space(blkh);
-
-
-    /* check free space */
-    RFALSE( free_space < paste_size,
-            "vs-10175: not enough free space: needed %d, available %d",
-            paste_size, free_space);
+	struct buffer_head *bh = bi->bi_bh;
+	int nr, free_space;
+	struct block_head *blkh;
+	struct item_head *ih;
+	int i;
+	int last_loc, unmoved_loc;
+
+	blkh = B_BLK_HEAD(bh);
+	nr = blkh_nr_item(blkh);
+	free_space = blkh_free_space(blkh);
+
+	/* check free space */
+	RFALSE(free_space < paste_size,
+	       "vs-10175: not enough free space: needed %d, available %d",
+	       paste_size, free_space);
 
 #ifdef CONFIG_REISERFS_CHECK
-    if (zeros_number > paste_size) {
-	print_cur_tb ("10177");
-	reiserfs_panic ( NULL, "vs-10177: leaf_paste_in_buffer: ero number == %d, paste_size == %d",
-                         zeros_number, paste_size);
-    }
-#endif /* CONFIG_REISERFS_CHECK */
-
-
-    /* item to be appended */
-    ih = B_N_PITEM_HEAD(bh, affected_item_num);
-
-    last_loc = ih_location( &(ih[nr - affected_item_num - 1]) );
-    unmoved_loc = affected_item_num ? ih_location( ih-1 ) : bh->b_size;
-
-    /* prepare space */
-    memmove (bh->b_data + last_loc - paste_size, bh->b_data + last_loc,
-	     unmoved_loc - last_loc);
-
-
-    /* change locations */
-    for (i = affected_item_num; i < nr; i ++)
-	put_ih_location( &(ih[i-affected_item_num]),
-                    ih_location( &(ih[i-affected_item_num])) - paste_size );
-
-    if ( body ) {
-	if (!is_direntry_le_ih (ih)) {
-	    if (!pos_in_item) {
-		/* shift data to right */
-		memmove (bh->b_data + ih_location(ih) + paste_size, 
-			 bh->b_data + ih_location(ih), ih_item_len(ih));
-		/* paste data in the head of item */
-		memset (bh->b_data + ih_location(ih), 0, zeros_number);
-		memcpy (bh->b_data + ih_location(ih) + zeros_number, body, paste_size - zeros_number);
-	    } else {
-		memset (bh->b_data + unmoved_loc - paste_size, 0, zeros_number);
-		memcpy (bh->b_data + unmoved_loc - paste_size + zeros_number, body, paste_size - zeros_number);
-	    }
-	}
-    }
-    else
-	memset(bh->b_data + unmoved_loc - paste_size, '\0', paste_size);
-
-    put_ih_item_len( ih, ih_item_len(ih) + paste_size );
-
-    /* change free space */
-    set_blkh_free_space( blkh, free_space - paste_size );
-
-    do_balance_mark_leaf_dirty (bi->tb, bh, 0);
-
-    if (bi->bi_parent) { 
-	struct disk_child *t_dc = B_N_CHILD (bi->bi_parent, bi->bi_position);
-	put_dc_size( t_dc, dc_size(t_dc) + paste_size );
-	do_balance_mark_internal_dirty (bi->tb, bi->bi_parent, 0);
-    }
-}
+	if (zeros_number > paste_size) {
+		print_cur_tb("10177");
+		reiserfs_panic(NULL,
+			       "vs-10177: leaf_paste_in_buffer: ero number == %d, paste_size == %d",
+			       zeros_number, paste_size);
+	}
+#endif				/* CONFIG_REISERFS_CHECK */
+
+	/* item to be appended */
+	ih = B_N_PITEM_HEAD(bh, affected_item_num);
+
+	last_loc = ih_location(&(ih[nr - affected_item_num - 1]));
+	unmoved_loc = affected_item_num ? ih_location(ih - 1) : bh->b_size;
 
+	/* prepare space */
+	memmove(bh->b_data + last_loc - paste_size, bh->b_data + last_loc,
+		unmoved_loc - last_loc);
+
+	/* change locations */
+	for (i = affected_item_num; i < nr; i++)
+		put_ih_location(&(ih[i - affected_item_num]),
+				ih_location(&(ih[i - affected_item_num])) -
+				paste_size);
+
+	if (body) {
+		if (!is_direntry_le_ih(ih)) {
+			if (!pos_in_item) {
+				/* shift data to right */
+				memmove(bh->b_data + ih_location(ih) +
+					paste_size,
+					bh->b_data + ih_location(ih),
+					ih_item_len(ih));
+				/* paste data in the head of item */
+				memset(bh->b_data + ih_location(ih), 0,
+				       zeros_number);
+				memcpy(bh->b_data + ih_location(ih) +
+				       zeros_number, body,
+				       paste_size - zeros_number);
+			} else {
+				memset(bh->b_data + unmoved_loc - paste_size, 0,
+				       zeros_number);
+				memcpy(bh->b_data + unmoved_loc - paste_size +
+				       zeros_number, body,
+				       paste_size - zeros_number);
+			}
+		}
+	} else
+		memset(bh->b_data + unmoved_loc - paste_size, '\0', paste_size);
+
+	put_ih_item_len(ih, ih_item_len(ih) + paste_size);
+
+	/* change free space */
+	set_blkh_free_space(blkh, free_space - paste_size);
+
+	do_balance_mark_leaf_dirty(bi->tb, bh, 0);
+
+	if (bi->bi_parent) {
+		struct disk_child *t_dc =
+		    B_N_CHILD(bi->bi_parent, bi->bi_position);
+		put_dc_size(t_dc, dc_size(t_dc) + paste_size);
+		do_balance_mark_internal_dirty(bi->tb, bi->bi_parent, 0);
+	}
+}
 
 /* cuts DEL_COUNT entries beginning from FROM-th entry. Directory item
    does not have free space, so it moves DEHs and remaining records as
    necessary. Return value is size of removed part of directory item
    in bytes. */
-static int	leaf_cut_entries (
-				struct buffer_head * bh,
-				struct item_head * ih, 
-				int from, 
-				int del_count
-			)
+static int leaf_cut_entries(struct buffer_head *bh,
+			    struct item_head *ih, int from, int del_count)
 {
-  char * item;
-  struct reiserfs_de_head * deh;
-  int prev_record_offset;	/* offset of record, that is (from-1)th */
-  char * prev_record;		/* */
-  int cut_records_len;		/* length of all removed records */
-  int i;
-
-
-  /* make sure, that item is directory and there are enough entries to
-     remove */
-  RFALSE( !is_direntry_le_ih (ih), "10180: item is not directory item");
-  RFALSE( I_ENTRY_COUNT(ih) < from + del_count,
-	  "10185: item contains not enough entries: entry_cout = %d, from = %d, to delete = %d",
-	  I_ENTRY_COUNT(ih), from, del_count);
-
-  if (del_count == 0)
-    return 0;
-
-  /* first byte of item */
-  item = bh->b_data + ih_location(ih);
-
-  /* entry head array */
-  deh = B_I_DEH (bh, ih);
-
-  /* first byte of remaining entries, those are BEFORE cut entries
-     (prev_record) and length of all removed records (cut_records_len) */
-  prev_record_offset = (from ? deh_location( &(deh[from - 1])) : ih_item_len(ih));
-  cut_records_len = prev_record_offset/*from_record*/ -
-                                deh_location( &(deh[from + del_count - 1]));
-  prev_record = item + prev_record_offset;
-
-
-  /* adjust locations of remaining entries */
-  for (i = I_ENTRY_COUNT(ih) - 1; i > from + del_count - 1; i --)
-    put_deh_location( &(deh[i]),
-                        deh_location( &deh[i] ) - (DEH_SIZE * del_count ) );
-
-  for (i = 0; i < from; i ++)
-    put_deh_location( &(deh[i]),
-        deh_location( &deh[i] ) - (DEH_SIZE * del_count + cut_records_len) );
-
-  put_ih_entry_count( ih, ih_entry_count(ih) - del_count );
-
-  /* shift entry head array and entries those are AFTER removed entries */
-  memmove ((char *)(deh + from),
-	   deh + from + del_count, 
-	   prev_record - cut_records_len - (char *)(deh + from + del_count));
-  
-  /* shift records, those are BEFORE removed entries */
-  memmove (prev_record - cut_records_len - DEH_SIZE * del_count,
-	   prev_record, item + ih_item_len(ih) - prev_record);
+	char *item;
+	struct reiserfs_de_head *deh;
+	int prev_record_offset;	/* offset of record, that is (from-1)th */
+	char *prev_record;	/* */
+	int cut_records_len;	/* length of all removed records */
+	int i;
+
+	/* make sure, that item is directory and there are enough entries to
+	   remove */
+	RFALSE(!is_direntry_le_ih(ih), "10180: item is not directory item");
+	RFALSE(I_ENTRY_COUNT(ih) < from + del_count,
+	       "10185: item contains not enough entries: entry_cout = %d, from = %d, to delete = %d",
+	       I_ENTRY_COUNT(ih), from, del_count);
+
+	if (del_count == 0)
+		return 0;
+
+	/* first byte of item */
+	item = bh->b_data + ih_location(ih);
+
+	/* entry head array */
+	deh = B_I_DEH(bh, ih);
+
+	/* first byte of remaining entries, those are BEFORE cut entries
+	   (prev_record) and length of all removed records (cut_records_len) */
+	prev_record_offset =
+	    (from ? deh_location(&(deh[from - 1])) : ih_item_len(ih));
+	cut_records_len = prev_record_offset /*from_record */  -
+	    deh_location(&(deh[from + del_count - 1]));
+	prev_record = item + prev_record_offset;
+
+	/* adjust locations of remaining entries */
+	for (i = I_ENTRY_COUNT(ih) - 1; i > from + del_count - 1; i--)
+		put_deh_location(&(deh[i]),
+				 deh_location(&deh[i]) -
+				 (DEH_SIZE * del_count));
+
+	for (i = 0; i < from; i++)
+		put_deh_location(&(deh[i]),
+				 deh_location(&deh[i]) - (DEH_SIZE * del_count +
+							  cut_records_len));
+
+	put_ih_entry_count(ih, ih_entry_count(ih) - del_count);
+
+	/* shift entry head array and entries those are AFTER removed entries */
+	memmove((char *)(deh + from),
+		deh + from + del_count,
+		prev_record - cut_records_len - (char *)(deh + from +
+							 del_count));
+
+	/* shift records, those are BEFORE removed entries */
+	memmove(prev_record - cut_records_len - DEH_SIZE * del_count,
+		prev_record, item + ih_item_len(ih) - prev_record);
 
-  return DEH_SIZE * del_count + cut_records_len;
+	return DEH_SIZE * del_count + cut_records_len;
 }
 
-
 /*  when cut item is part of regular file
         pos_in_item - first byte that must be cut
         cut_size - number of bytes to be cut beginning from pos_in_item
@@ -959,264 +1025,278 @@ static int	leaf_cut_entries (
         pos_in_item - number of first deleted entry
         cut_size - count of deleted entries
     */
-void leaf_cut_from_buffer (struct buffer_info * bi, int cut_item_num,
-			   int pos_in_item, int cut_size)
+void leaf_cut_from_buffer(struct buffer_info *bi, int cut_item_num,
+			  int pos_in_item, int cut_size)
 {
-    int nr;
-    struct buffer_head * bh = bi->bi_bh;
-    struct block_head * blkh;
-    struct item_head * ih;
-    int last_loc, unmoved_loc;
-    int i;
-
-    blkh = B_BLK_HEAD(bh);
-    nr = blkh_nr_item(blkh);
-
-    /* item head of truncated item */
-    ih = B_N_PITEM_HEAD (bh, cut_item_num);
-
-    if (is_direntry_le_ih (ih)) {
-        /* first cut entry ()*/
-        cut_size = leaf_cut_entries (bh, ih, pos_in_item, cut_size);
-        if (pos_in_item == 0) {
-	        /* change key */
-            RFALSE( cut_item_num,
-                    "when 0-th enrty of item is cut, that item must be first in the node, not %d-th", cut_item_num);
-            /* change item key by key of first entry in the item */
-	    set_le_ih_k_offset (ih, deh_offset(B_I_DEH (bh, ih)));
-            /*memcpy (&ih->ih_key.k_offset, &(B_I_DEH (bh, ih)->deh_offset), SHORT_KEY_SIZE);*/
-	    }
-    } else {
-        /* item is direct or indirect */
-        RFALSE( is_statdata_le_ih (ih), "10195: item is stat data");
-        RFALSE( pos_in_item && pos_in_item + cut_size != ih_item_len(ih),
-                "10200: invalid offset (%lu) or trunc_size (%lu) or ih_item_len (%lu)",
-                ( long unsigned ) pos_in_item, ( long unsigned ) cut_size, 
-		( long unsigned ) ih_item_len (ih));
-
-        /* shift item body to left if cut is from the head of item */
-        if (pos_in_item == 0) {
-            memmove( bh->b_data + ih_location(ih),
-		     bh->b_data + ih_location(ih) + cut_size,
-		     ih_item_len(ih) - cut_size);
-	    
-            /* change key of item */
-            if (is_direct_le_ih (ih))
-		set_le_ih_k_offset (ih, le_ih_k_offset (ih) + cut_size);
-            else {
-		set_le_ih_k_offset (ih, le_ih_k_offset (ih) + (cut_size / UNFM_P_SIZE) * bh->b_size);
-                RFALSE( ih_item_len(ih) == cut_size && get_ih_free_space (ih),
-                        "10205: invalid ih_free_space (%h)", ih);
-	        }
-	    }
-    }
-  
-
-    /* location of the last item */
-    last_loc = ih_location( &(ih[nr - cut_item_num - 1]) );
-
-    /* location of the item, which is remaining at the same place */
-    unmoved_loc = cut_item_num ? ih_location(ih-1) : bh->b_size;
-
-
-    /* shift */
-    memmove (bh->b_data + last_loc + cut_size, bh->b_data + last_loc,
-	       unmoved_loc - last_loc - cut_size);
-
-    /* change item length */
-    put_ih_item_len( ih, ih_item_len(ih) - cut_size );
-  
-    if (is_indirect_le_ih (ih)) {
-        if (pos_in_item)
-            set_ih_free_space (ih, 0);
-    }
-
-    /* change locations */
-    for (i = cut_item_num; i < nr; i ++)
-    put_ih_location( &(ih[i-cut_item_num]), ih_location( &ih[i-cut_item_num]) + cut_size );
-
-    /* size, free space */
-    set_blkh_free_space( blkh, blkh_free_space(blkh) + cut_size );
-
-    do_balance_mark_leaf_dirty (bi->tb, bh, 0);
-    
-    if (bi->bi_parent) { 
-      struct disk_child *t_dc;
-      t_dc = B_N_CHILD (bi->bi_parent, bi->bi_position);
-      put_dc_size( t_dc, dc_size(t_dc) - cut_size );
-      do_balance_mark_internal_dirty (bi->tb, bi->bi_parent, 0);
-    }
-}
+	int nr;
+	struct buffer_head *bh = bi->bi_bh;
+	struct block_head *blkh;
+	struct item_head *ih;
+	int last_loc, unmoved_loc;
+	int i;
+
+	blkh = B_BLK_HEAD(bh);
+	nr = blkh_nr_item(blkh);
+
+	/* item head of truncated item */
+	ih = B_N_PITEM_HEAD(bh, cut_item_num);
+
+	if (is_direntry_le_ih(ih)) {
+		/* first cut entry () */
+		cut_size = leaf_cut_entries(bh, ih, pos_in_item, cut_size);
+		if (pos_in_item == 0) {
+			/* change key */
+			RFALSE(cut_item_num,
+			       "when 0-th enrty of item is cut, that item must be first in the node, not %d-th",
+			       cut_item_num);
+			/* change item key by key of first entry in the item */
+			set_le_ih_k_offset(ih, deh_offset(B_I_DEH(bh, ih)));
+			/*memcpy (&ih->ih_key.k_offset, &(B_I_DEH (bh, ih)->deh_offset), SHORT_KEY_SIZE); */
+		}
+	} else {
+		/* item is direct or indirect */
+		RFALSE(is_statdata_le_ih(ih), "10195: item is stat data");
+		RFALSE(pos_in_item && pos_in_item + cut_size != ih_item_len(ih),
+		       "10200: invalid offset (%lu) or trunc_size (%lu) or ih_item_len (%lu)",
+		       (long unsigned)pos_in_item, (long unsigned)cut_size,
+		       (long unsigned)ih_item_len(ih));
+
+		/* shift item body to left if cut is from the head of item */
+		if (pos_in_item == 0) {
+			memmove(bh->b_data + ih_location(ih),
+				bh->b_data + ih_location(ih) + cut_size,
+				ih_item_len(ih) - cut_size);
+
+			/* change key of item */
+			if (is_direct_le_ih(ih))
+				set_le_ih_k_offset(ih,
+						   le_ih_k_offset(ih) +
+						   cut_size);
+			else {
+				set_le_ih_k_offset(ih,
+						   le_ih_k_offset(ih) +
+						   (cut_size / UNFM_P_SIZE) *
+						   bh->b_size);
+				RFALSE(ih_item_len(ih) == cut_size
+				       && get_ih_free_space(ih),
+				       "10205: invalid ih_free_space (%h)", ih);
+			}
+		}
+	}
 
+	/* location of the last item */
+	last_loc = ih_location(&(ih[nr - cut_item_num - 1]));
+
+	/* location of the item, which is remaining at the same place */
+	unmoved_loc = cut_item_num ? ih_location(ih - 1) : bh->b_size;
+
+	/* shift */
+	memmove(bh->b_data + last_loc + cut_size, bh->b_data + last_loc,
+		unmoved_loc - last_loc - cut_size);
+
+	/* change item length */
+	put_ih_item_len(ih, ih_item_len(ih) - cut_size);
+
+	if (is_indirect_le_ih(ih)) {
+		if (pos_in_item)
+			set_ih_free_space(ih, 0);
+	}
+
+	/* change locations */
+	for (i = cut_item_num; i < nr; i++)
+		put_ih_location(&(ih[i - cut_item_num]),
+				ih_location(&ih[i - cut_item_num]) + cut_size);
+
+	/* size, free space */
+	set_blkh_free_space(blkh, blkh_free_space(blkh) + cut_size);
+
+	do_balance_mark_leaf_dirty(bi->tb, bh, 0);
+
+	if (bi->bi_parent) {
+		struct disk_child *t_dc;
+		t_dc = B_N_CHILD(bi->bi_parent, bi->bi_position);
+		put_dc_size(t_dc, dc_size(t_dc) - cut_size);
+		do_balance_mark_internal_dirty(bi->tb, bi->bi_parent, 0);
+	}
+}
 
 /* delete del_num items from buffer starting from the first'th item */
-static void leaf_delete_items_entirely (struct buffer_info * bi,
-					int first, int del_num)
+static void leaf_delete_items_entirely(struct buffer_info *bi,
+				       int first, int del_num)
 {
-    struct buffer_head * bh = bi->bi_bh;
-    int nr;
-    int i, j;
-    int last_loc, last_removed_loc;
-    struct block_head * blkh;
-    struct item_head * ih;
-
-  RFALSE( bh == NULL, "10210: buffer is 0");
-  RFALSE( del_num < 0, "10215: del_num less than 0 (%d)", del_num);
-
-  if (del_num == 0)
-    return;
-
-  blkh = B_BLK_HEAD(bh);
-  nr = blkh_nr_item(blkh);
-
-  RFALSE( first < 0 || first + del_num > nr,
-          "10220: first=%d, number=%d, there is %d items", first, del_num, nr);
-
-  if (first == 0 && del_num == nr) {
-    /* this does not work */
-    make_empty_node (bi);
-    
-    do_balance_mark_leaf_dirty (bi->tb, bh, 0);
-    return;
-  }
-
-  ih = B_N_PITEM_HEAD (bh, first);
-  
-  /* location of unmovable item */
-  j = (first == 0) ? bh->b_size : ih_location(ih-1);
-      
-  /* delete items */
-  last_loc = ih_location( &(ih[nr-1-first]) );
-  last_removed_loc = ih_location( &(ih[del_num-1]) );
-
-  memmove (bh->b_data + last_loc + j - last_removed_loc,
-	   bh->b_data + last_loc, last_removed_loc - last_loc);
-  
-  /* delete item headers */
-  memmove (ih, ih + del_num, (nr - first - del_num) * IH_SIZE);
-  
-  /* change item location */
-  for (i = first; i < nr - del_num; i ++)
-    put_ih_location( &(ih[i-first]), ih_location( &(ih[i-first]) ) + (j - last_removed_loc) );
-
-  /* sizes, item number */
-  set_blkh_nr_item( blkh, blkh_nr_item(blkh) - del_num );
-  set_blkh_free_space( blkh, blkh_free_space(blkh) + (j - last_removed_loc + IH_SIZE * del_num) );
-
-  do_balance_mark_leaf_dirty (bi->tb, bh, 0);
-  
-  if (bi->bi_parent) {
-    struct disk_child *t_dc = B_N_CHILD (bi->bi_parent, bi->bi_position);
-    put_dc_size( t_dc, dc_size(t_dc) -
-				(j - last_removed_loc + IH_SIZE * del_num));
-    do_balance_mark_internal_dirty (bi->tb, bi->bi_parent, 0);
-  }
-}
+	struct buffer_head *bh = bi->bi_bh;
+	int nr;
+	int i, j;
+	int last_loc, last_removed_loc;
+	struct block_head *blkh;
+	struct item_head *ih;
+
+	RFALSE(bh == NULL, "10210: buffer is 0");
+	RFALSE(del_num < 0, "10215: del_num less than 0 (%d)", del_num);
+
+	if (del_num == 0)
+		return;
+
+	blkh = B_BLK_HEAD(bh);
+	nr = blkh_nr_item(blkh);
+
+	RFALSE(first < 0 || first + del_num > nr,
+	       "10220: first=%d, number=%d, there is %d items", first, del_num,
+	       nr);
+
+	if (first == 0 && del_num == nr) {
+		/* this does not work */
+		make_empty_node(bi);
 
+		do_balance_mark_leaf_dirty(bi->tb, bh, 0);
+		return;
+	}
 
+	ih = B_N_PITEM_HEAD(bh, first);
 
+	/* location of unmovable item */
+	j = (first == 0) ? bh->b_size : ih_location(ih - 1);
 
+	/* delete items */
+	last_loc = ih_location(&(ih[nr - 1 - first]));
+	last_removed_loc = ih_location(&(ih[del_num - 1]));
+
+	memmove(bh->b_data + last_loc + j - last_removed_loc,
+		bh->b_data + last_loc, last_removed_loc - last_loc);
+
+	/* delete item headers */
+	memmove(ih, ih + del_num, (nr - first - del_num) * IH_SIZE);
+
+	/* change item location */
+	for (i = first; i < nr - del_num; i++)
+		put_ih_location(&(ih[i - first]),
+				ih_location(&(ih[i - first])) + (j -
+								 last_removed_loc));
+
+	/* sizes, item number */
+	set_blkh_nr_item(blkh, blkh_nr_item(blkh) - del_num);
+	set_blkh_free_space(blkh,
+			    blkh_free_space(blkh) + (j - last_removed_loc +
+						     IH_SIZE * del_num));
+
+	do_balance_mark_leaf_dirty(bi->tb, bh, 0);
+
+	if (bi->bi_parent) {
+		struct disk_child *t_dc =
+		    B_N_CHILD(bi->bi_parent, bi->bi_position);
+		put_dc_size(t_dc,
+			    dc_size(t_dc) - (j - last_removed_loc +
+					     IH_SIZE * del_num));
+		do_balance_mark_internal_dirty(bi->tb, bi->bi_parent, 0);
+	}
+}
 
 /* paste new_entry_count entries (new_dehs, records) into position before to item_num-th item */
-void    leaf_paste_entries (
-			struct buffer_head * bh,
+void leaf_paste_entries(struct buffer_head *bh,
 			int item_num,
 			int before,
 			int new_entry_count,
-			struct reiserfs_de_head * new_dehs,
-			const char * records,
-			int paste_size
-		)
+			struct reiserfs_de_head *new_dehs,
+			const char *records, int paste_size)
 {
-    struct item_head * ih;
-    char * item;
-    struct reiserfs_de_head * deh;
-    char * insert_point;
-    int i, old_entry_num;
-
-    if (new_entry_count == 0)
-        return;
-
-    ih = B_N_PITEM_HEAD(bh, item_num);
-
-  /* make sure, that item is directory, and there are enough records in it */
-  RFALSE( !is_direntry_le_ih (ih), "10225: item is not directory item");
-  RFALSE( I_ENTRY_COUNT (ih) < before,
-	  "10230: there are no entry we paste entries before. entry_count = %d, before = %d",
-	  I_ENTRY_COUNT (ih), before);
-
-
-  /* first byte of dest item */
-  item = bh->b_data + ih_location(ih);
-
-  /* entry head array */
-  deh = B_I_DEH (bh, ih);
-
-  /* new records will be pasted at this point */
-  insert_point = item + (before ? deh_location( &(deh[before - 1])) : (ih_item_len(ih) - paste_size));
-
-  /* adjust locations of records that will be AFTER new records */
-  for (i = I_ENTRY_COUNT(ih) - 1; i >= before; i --)
-    put_deh_location( &(deh[i]),
-                deh_location(&(deh[i])) + (DEH_SIZE * new_entry_count )); 
-
-  /* adjust locations of records that will be BEFORE new records */
-  for (i = 0; i < before; i ++)
-    put_deh_location( &(deh[i]), deh_location(&(deh[i])) + paste_size );
-
-  old_entry_num = I_ENTRY_COUNT(ih);
-  put_ih_entry_count( ih, ih_entry_count(ih) + new_entry_count );
-
-  /* prepare space for pasted records */
-  memmove (insert_point + paste_size, insert_point, item + (ih_item_len(ih) - paste_size) - insert_point);
-
-  /* copy new records */
-  memcpy (insert_point + DEH_SIZE * new_entry_count, records,
-		   paste_size - DEH_SIZE * new_entry_count);
-  
-  /* prepare space for new entry heads */
-  deh += before;
-  memmove ((char *)(deh + new_entry_count), deh, insert_point - (char *)deh);
-
-  /* copy new entry heads */
-  deh = (struct reiserfs_de_head *)((char *)deh);
-  memcpy (deh, new_dehs, DEH_SIZE * new_entry_count);
-
-  /* set locations of new records */
-  for (i = 0; i < new_entry_count; i ++)
-  {
-    put_deh_location( &(deh[i]),
-        deh_location( &(deh[i] )) +
-        (- deh_location( &(new_dehs[new_entry_count - 1])) +
-        insert_point + DEH_SIZE * new_entry_count - item));
-  }
-
-
-  /* change item key if necessary (when we paste before 0-th entry */
-  if (!before)
-    {
-	set_le_ih_k_offset (ih, deh_offset(new_dehs));
+	struct item_head *ih;
+	char *item;
+	struct reiserfs_de_head *deh;
+	char *insert_point;
+	int i, old_entry_num;
+
+	if (new_entry_count == 0)
+		return;
+
+	ih = B_N_PITEM_HEAD(bh, item_num);
+
+	/* make sure, that item is directory, and there are enough records in it */
+	RFALSE(!is_direntry_le_ih(ih), "10225: item is not directory item");
+	RFALSE(I_ENTRY_COUNT(ih) < before,
+	       "10230: there are no entry we paste entries before. entry_count = %d, before = %d",
+	       I_ENTRY_COUNT(ih), before);
+
+	/* first byte of dest item */
+	item = bh->b_data + ih_location(ih);
+
+	/* entry head array */
+	deh = B_I_DEH(bh, ih);
+
+	/* new records will be pasted at this point */
+	insert_point =
+	    item +
+	    (before ? deh_location(&(deh[before - 1]))
+	     : (ih_item_len(ih) - paste_size));
+
+	/* adjust locations of records that will be AFTER new records */
+	for (i = I_ENTRY_COUNT(ih) - 1; i >= before; i--)
+		put_deh_location(&(deh[i]),
+				 deh_location(&(deh[i])) +
+				 (DEH_SIZE * new_entry_count));
+
+	/* adjust locations of records that will be BEFORE new records */
+	for (i = 0; i < before; i++)
+		put_deh_location(&(deh[i]),
+				 deh_location(&(deh[i])) + paste_size);
+
+	old_entry_num = I_ENTRY_COUNT(ih);
+	put_ih_entry_count(ih, ih_entry_count(ih) + new_entry_count);
+
+	/* prepare space for pasted records */
+	memmove(insert_point + paste_size, insert_point,
+		item + (ih_item_len(ih) - paste_size) - insert_point);
+
+	/* copy new records */
+	memcpy(insert_point + DEH_SIZE * new_entry_count, records,
+	       paste_size - DEH_SIZE * new_entry_count);
+
+	/* prepare space for new entry heads */
+	deh += before;
+	memmove((char *)(deh + new_entry_count), deh,
+		insert_point - (char *)deh);
+
+	/* copy new entry heads */
+	deh = (struct reiserfs_de_head *)((char *)deh);
+	memcpy(deh, new_dehs, DEH_SIZE * new_entry_count);
+
+	/* set locations of new records */
+	for (i = 0; i < new_entry_count; i++) {
+		put_deh_location(&(deh[i]),
+				 deh_location(&(deh[i])) +
+				 (-deh_location
+				  (&(new_dehs[new_entry_count - 1])) +
+				  insert_point + DEH_SIZE * new_entry_count -
+				  item));
+	}
+
+	/* change item key if necessary (when we paste before 0-th entry */
+	if (!before) {
+		set_le_ih_k_offset(ih, deh_offset(new_dehs));
 /*      memcpy (&ih->ih_key.k_offset, 
 		       &new_dehs->deh_offset, SHORT_KEY_SIZE);*/
-    }
-
+	}
 #ifdef CONFIG_REISERFS_CHECK
-  {
-    int prev, next;
-    /* check record locations */
-    deh = B_I_DEH (bh, ih);
-    for (i = 0; i < I_ENTRY_COUNT(ih); i ++) {
-      next = (i < I_ENTRY_COUNT(ih) - 1) ? deh_location( &(deh[i + 1])) : 0;
-      prev = (i != 0) ? deh_location( &(deh[i - 1]) ) : 0;
-      
-      if (prev && prev <= deh_location( &(deh[i])))
-	reiserfs_warning (NULL, "vs-10240: leaf_paste_entries: directory item (%h) corrupted (prev %a, cur(%d) %a)",
-			  ih, deh + i - 1, i, deh + i);
-      if (next && next >= deh_location( &(deh[i])))
-	reiserfs_warning (NULL, "vs-10250: leaf_paste_entries: directory item (%h) corrupted (cur(%d) %a, next %a)",
-			  ih, i, deh + i, deh + i + 1);
-    }
-  }
+	{
+		int prev, next;
+		/* check record locations */
+		deh = B_I_DEH(bh, ih);
+		for (i = 0; i < I_ENTRY_COUNT(ih); i++) {
+			next =
+			    (i <
+			     I_ENTRY_COUNT(ih) -
+			     1) ? deh_location(&(deh[i + 1])) : 0;
+			prev = (i != 0) ? deh_location(&(deh[i - 1])) : 0;
+
+			if (prev && prev <= deh_location(&(deh[i])))
+				reiserfs_warning(NULL,
+						 "vs-10240: leaf_paste_entries: directory item (%h) corrupted (prev %a, cur(%d) %a)",
+						 ih, deh + i - 1, i, deh + i);
+			if (next && next >= deh_location(&(deh[i])))
+				reiserfs_warning(NULL,
+						 "vs-10250: leaf_paste_entries: directory item (%h) corrupted (cur(%d) %a, next %a)",
+						 ih, i, deh + i, deh + i + 1);
+		}
+	}
 #endif
 
 }
diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c
--- a/fs/reiserfs/namei.c
+++ b/fs/reiserfs/namei.c
@@ -25,86 +25,85 @@
 
 // directory item contains array of entry headers. This performs
 // binary search through that array
-static int bin_search_in_dir_item (struct reiserfs_dir_entry * de, loff_t off)
+static int bin_search_in_dir_item(struct reiserfs_dir_entry *de, loff_t off)
 {
-    struct item_head * ih = de->de_ih;
-    struct reiserfs_de_head * deh = de->de_deh;
-    int rbound, lbound, j;
-
-    lbound = 0;
-    rbound = I_ENTRY_COUNT (ih) - 1;
-
-    for (j = (rbound + lbound) / 2; lbound <= rbound; j = (rbound + lbound) / 2) {
-	if (off < deh_offset (deh + j)) {
-	    rbound = j - 1;
-	    continue;
-	}
-	if (off > deh_offset (deh + j)) {
-	    lbound = j + 1;
-	    continue;
-	}
-	// this is not name found, but matched third key component
-	de->de_entry_num = j;
-	return NAME_FOUND;
-    }
+	struct item_head *ih = de->de_ih;
+	struct reiserfs_de_head *deh = de->de_deh;
+	int rbound, lbound, j;
+
+	lbound = 0;
+	rbound = I_ENTRY_COUNT(ih) - 1;
+
+	for (j = (rbound + lbound) / 2; lbound <= rbound;
+	     j = (rbound + lbound) / 2) {
+		if (off < deh_offset(deh + j)) {
+			rbound = j - 1;
+			continue;
+		}
+		if (off > deh_offset(deh + j)) {
+			lbound = j + 1;
+			continue;
+		}
+		// this is not name found, but matched third key component
+		de->de_entry_num = j;
+		return NAME_FOUND;
+	}
 
-    de->de_entry_num = lbound;
-    return NAME_NOT_FOUND;
+	de->de_entry_num = lbound;
+	return NAME_NOT_FOUND;
 }
 
-
 // comment?  maybe something like set de to point to what the path points to?
-static inline void set_de_item_location (struct reiserfs_dir_entry * de, struct path * path)
+static inline void set_de_item_location(struct reiserfs_dir_entry *de,
+					struct path *path)
 {
-    de->de_bh = get_last_bh (path);
-    de->de_ih = get_ih (path);
-    de->de_deh = B_I_DEH (de->de_bh, de->de_ih);
-    de->de_item_num = PATH_LAST_POSITION (path);
-} 
-
+	de->de_bh = get_last_bh(path);
+	de->de_ih = get_ih(path);
+	de->de_deh = B_I_DEH(de->de_bh, de->de_ih);
+	de->de_item_num = PATH_LAST_POSITION(path);
+}
 
 // de_bh, de_ih, de_deh (points to first element of array), de_item_num is set
-inline void set_de_name_and_namelen (struct reiserfs_dir_entry * de)
+inline void set_de_name_and_namelen(struct reiserfs_dir_entry *de)
 {
-    struct reiserfs_de_head * deh = de->de_deh + de->de_entry_num;
+	struct reiserfs_de_head *deh = de->de_deh + de->de_entry_num;
 
-    if (de->de_entry_num >= ih_entry_count (de->de_ih))
-	BUG ();
+	if (de->de_entry_num >= ih_entry_count(de->de_ih))
+		BUG();
 
-    de->de_entrylen = entry_length (de->de_bh, de->de_ih, de->de_entry_num);
-    de->de_namelen = de->de_entrylen - (de_with_sd (deh) ? SD_SIZE : 0);
-    de->de_name = B_I_PITEM (de->de_bh, de->de_ih) + deh_location(deh);
-    if (de->de_name[de->de_namelen - 1] == 0)
-	de->de_namelen = strlen (de->de_name);
+	de->de_entrylen = entry_length(de->de_bh, de->de_ih, de->de_entry_num);
+	de->de_namelen = de->de_entrylen - (de_with_sd(deh) ? SD_SIZE : 0);
+	de->de_name = B_I_PITEM(de->de_bh, de->de_ih) + deh_location(deh);
+	if (de->de_name[de->de_namelen - 1] == 0)
+		de->de_namelen = strlen(de->de_name);
 }
 
-
 // what entry points to
-static inline void set_de_object_key (struct reiserfs_dir_entry * de)
+static inline void set_de_object_key(struct reiserfs_dir_entry *de)
 {
-    if (de->de_entry_num >= ih_entry_count (de->de_ih))
-	BUG ();
-    de->de_dir_id = deh_dir_id( &(de->de_deh[de->de_entry_num]));
-    de->de_objectid = deh_objectid( &(de->de_deh[de->de_entry_num]));
+	if (de->de_entry_num >= ih_entry_count(de->de_ih))
+		BUG();
+	de->de_dir_id = deh_dir_id(&(de->de_deh[de->de_entry_num]));
+	de->de_objectid = deh_objectid(&(de->de_deh[de->de_entry_num]));
 }
 
-
-static inline void store_de_entry_key (struct reiserfs_dir_entry * de)
+static inline void store_de_entry_key(struct reiserfs_dir_entry *de)
 {
-    struct reiserfs_de_head * deh = de->de_deh + de->de_entry_num;
+	struct reiserfs_de_head *deh = de->de_deh + de->de_entry_num;
 
-    if (de->de_entry_num >= ih_entry_count (de->de_ih))
-	BUG ();
+	if (de->de_entry_num >= ih_entry_count(de->de_ih))
+		BUG();
 
-    /* store key of the found entry */
-    de->de_entry_key.version = KEY_FORMAT_3_5;
-    de->de_entry_key.on_disk_key.k_dir_id = le32_to_cpu (de->de_ih->ih_key.k_dir_id);
-    de->de_entry_key.on_disk_key.k_objectid = le32_to_cpu (de->de_ih->ih_key.k_objectid);
-    set_cpu_key_k_offset (&(de->de_entry_key), deh_offset (deh));
-    set_cpu_key_k_type (&(de->de_entry_key), TYPE_DIRENTRY);
+	/* store key of the found entry */
+	de->de_entry_key.version = KEY_FORMAT_3_5;
+	de->de_entry_key.on_disk_key.k_dir_id =
+	    le32_to_cpu(de->de_ih->ih_key.k_dir_id);
+	de->de_entry_key.on_disk_key.k_objectid =
+	    le32_to_cpu(de->de_ih->ih_key.k_objectid);
+	set_cpu_key_k_offset(&(de->de_entry_key), deh_offset(deh));
+	set_cpu_key_k_type(&(de->de_entry_key), TYPE_DIRENTRY);
 }
 
-
 /* We assign a key to each directory item, and place multiple entries
 in a single directory item.  A directory item has a key equal to the
 key of the first directory entry in it.
@@ -117,57 +116,59 @@ entry position in the item 
 */
 
 /* The function is NOT SCHEDULE-SAFE! */
-int search_by_entry_key (struct super_block * sb, const struct cpu_key * key,
-			 struct path * path, struct reiserfs_dir_entry * de)
+int search_by_entry_key(struct super_block *sb, const struct cpu_key *key,
+			struct path *path, struct reiserfs_dir_entry *de)
 {
-    int retval;
+	int retval;
 
-    retval = search_item (sb, key, path);
-    switch (retval) {
-    case ITEM_NOT_FOUND:
-	if (!PATH_LAST_POSITION (path)) {
-	    reiserfs_warning (sb, "vs-7000: search_by_entry_key: search_by_key returned item position == 0");
-	    pathrelse(path) ;
-	    return IO_ERROR ;
+	retval = search_item(sb, key, path);
+	switch (retval) {
+	case ITEM_NOT_FOUND:
+		if (!PATH_LAST_POSITION(path)) {
+			reiserfs_warning(sb,
+					 "vs-7000: search_by_entry_key: search_by_key returned item position == 0");
+			pathrelse(path);
+			return IO_ERROR;
+		}
+		PATH_LAST_POSITION(path)--;
+
+	case ITEM_FOUND:
+		break;
+
+	case IO_ERROR:
+		return retval;
+
+	default:
+		pathrelse(path);
+		reiserfs_warning(sb,
+				 "vs-7002: search_by_entry_key: no path to here");
+		return IO_ERROR;
 	}
-	PATH_LAST_POSITION (path) --;
 
-    case ITEM_FOUND:
-	break;
-
-    case IO_ERROR:
-	return retval;
-
-    default:
-	pathrelse (path);
-	reiserfs_warning (sb, "vs-7002: search_by_entry_key: no path to here");
-	return IO_ERROR;
-    }
-
-    set_de_item_location (de, path);
+	set_de_item_location(de, path);
 
 #ifdef CONFIG_REISERFS_CHECK
-    if (!is_direntry_le_ih (de->de_ih) || 
-	COMP_SHORT_KEYS (&(de->de_ih->ih_key), key)) {
-	print_block (de->de_bh, 0, -1, -1);
-	reiserfs_panic (sb, "vs-7005: search_by_entry_key: found item %h is not directory item or "
-                        "does not belong to the same directory as key %K", de->de_ih, key);
-    }
-#endif /* CONFIG_REISERFS_CHECK */
-
-    /* binary search in directory item by third componen t of the
-       key. sets de->de_entry_num of de */
-    retval = bin_search_in_dir_item (de, cpu_key_k_offset (key));
-    path->pos_in_item = de->de_entry_num;
-    if (retval != NAME_NOT_FOUND) {
-	// ugly, but rename needs de_bh, de_deh, de_name, de_namelen, de_objectid set
-	set_de_name_and_namelen (de);
-	set_de_object_key (de);
-    }
-    return retval;
-}
-
+	if (!is_direntry_le_ih(de->de_ih) ||
+	    COMP_SHORT_KEYS(&(de->de_ih->ih_key), key)) {
+		print_block(de->de_bh, 0, -1, -1);
+		reiserfs_panic(sb,
+			       "vs-7005: search_by_entry_key: found item %h is not directory item or "
+			       "does not belong to the same directory as key %K",
+			       de->de_ih, key);
+	}
+#endif				/* CONFIG_REISERFS_CHECK */
 
+	/* binary search in directory item by third componen t of the
+	   key. sets de->de_entry_num of de */
+	retval = bin_search_in_dir_item(de, cpu_key_k_offset(key));
+	path->pos_in_item = de->de_entry_num;
+	if (retval != NAME_NOT_FOUND) {
+		// ugly, but rename needs de_bh, de_deh, de_name, de_namelen, de_objectid set
+		set_de_name_and_namelen(de);
+		set_de_object_key(de);
+	}
+	return retval;
+}
 
 /* Keyed 32-bit hash function using TEA in a Davis-Meyer function */
 
@@ -176,238 +177,249 @@ int search_by_entry_key (struct super_bl
    but are thought about. This function should be moved to hashes.c
    Jedi, please do so.  -Hans */
 
-static __u32 get_third_component (struct super_block * s, 
-				  const char * name, int len)
+static __u32 get_third_component(struct super_block *s,
+				 const char *name, int len)
 {
-    __u32 res;
+	__u32 res;
 
-    if (!len || (len == 1 && name[0] == '.'))
-	return DOT_OFFSET;
-    if (len == 2 && name[0] == '.' && name[1] == '.')
-	return DOT_DOT_OFFSET;
+	if (!len || (len == 1 && name[0] == '.'))
+		return DOT_OFFSET;
+	if (len == 2 && name[0] == '.' && name[1] == '.')
+		return DOT_DOT_OFFSET;
 
-    res = REISERFS_SB(s)->s_hash_function (name, len);
+	res = REISERFS_SB(s)->s_hash_function(name, len);
 
-    // take bits from 7-th to 30-th including both bounds
-    res = GET_HASH_VALUE(res);
-    if (res == 0)
-	// needed to have no names before "." and ".." those have hash
-	// value == 0 and generation conters 1 and 2 accordingly
-	res = 128;
-    return res + MAX_GENERATION_NUMBER;
+	// take bits from 7-th to 30-th including both bounds
+	res = GET_HASH_VALUE(res);
+	if (res == 0)
+		// needed to have no names before "." and ".." those have hash
+		// value == 0 and generation conters 1 and 2 accordingly
+		res = 128;
+	return res + MAX_GENERATION_NUMBER;
 }
 
-
-static int reiserfs_match (struct reiserfs_dir_entry * de, 
-			   const char * name, int namelen)
+static int reiserfs_match(struct reiserfs_dir_entry *de,
+			  const char *name, int namelen)
 {
-    int retval = NAME_NOT_FOUND;
+	int retval = NAME_NOT_FOUND;
 
-    if ((namelen == de->de_namelen) &&
-	!memcmp(de->de_name, name, de->de_namelen))
-	retval = (de_visible (de->de_deh + de->de_entry_num) ? NAME_FOUND : NAME_FOUND_INVISIBLE);
+	if ((namelen == de->de_namelen) &&
+	    !memcmp(de->de_name, name, de->de_namelen))
+		retval =
+		    (de_visible(de->de_deh + de->de_entry_num) ? NAME_FOUND :
+		     NAME_FOUND_INVISIBLE);
 
-    return retval;
+	return retval;
 }
 
-
 /* de's de_bh, de_ih, de_deh, de_item_num, de_entry_num are set already */
 
 				/* used when hash collisions exist */
 
-
-static int linear_search_in_dir_item (struct cpu_key * key, struct reiserfs_dir_entry * de,
-				      const char * name, int namelen)
-{
-    struct reiserfs_de_head * deh = de->de_deh;
-    int retval;
-    int i;
-
-    i = de->de_entry_num;
-
-    if (i == I_ENTRY_COUNT (de->de_ih) ||
-	GET_HASH_VALUE (deh_offset (deh + i)) != GET_HASH_VALUE (cpu_key_k_offset (key))) {
-	i --;
-    }
-
-    RFALSE( de->de_deh != B_I_DEH (de->de_bh, de->de_ih),
-	    "vs-7010: array of entry headers not found");
-
-    deh += i;
-
-    for (; i >= 0; i --, deh --) {
-	if (GET_HASH_VALUE (deh_offset (deh)) !=
-	    GET_HASH_VALUE (cpu_key_k_offset (key))) {
-	    // hash value does not match, no need to check whole name
-	    return NAME_NOT_FOUND;
+static int linear_search_in_dir_item(struct cpu_key *key,
+				     struct reiserfs_dir_entry *de,
+				     const char *name, int namelen)
+{
+	struct reiserfs_de_head *deh = de->de_deh;
+	int retval;
+	int i;
+
+	i = de->de_entry_num;
+
+	if (i == I_ENTRY_COUNT(de->de_ih) ||
+	    GET_HASH_VALUE(deh_offset(deh + i)) !=
+	    GET_HASH_VALUE(cpu_key_k_offset(key))) {
+		i--;
 	}
-   
-	/* mark, that this generation number is used */
-	if (de->de_gen_number_bit_string)
-	    set_bit (GET_GENERATION_NUMBER (deh_offset (deh)), (unsigned long *)de->de_gen_number_bit_string);
-
-	// calculate pointer to name and namelen
-	de->de_entry_num = i;
-	set_de_name_and_namelen (de);
-
-	if ((retval = reiserfs_match (de, name, namelen)) != NAME_NOT_FOUND) {
-	    // de's de_name, de_namelen, de_recordlen are set. Fill the rest:
 
-	    // key of pointed object
-	    set_de_object_key (de);
+	RFALSE(de->de_deh != B_I_DEH(de->de_bh, de->de_ih),
+	       "vs-7010: array of entry headers not found");
 
-	    store_de_entry_key (de);
+	deh += i;
 
-	    // retval can be NAME_FOUND or NAME_FOUND_INVISIBLE
-	    return retval;
+	for (; i >= 0; i--, deh--) {
+		if (GET_HASH_VALUE(deh_offset(deh)) !=
+		    GET_HASH_VALUE(cpu_key_k_offset(key))) {
+			// hash value does not match, no need to check whole name
+			return NAME_NOT_FOUND;
+		}
+
+		/* mark, that this generation number is used */
+		if (de->de_gen_number_bit_string)
+			set_bit(GET_GENERATION_NUMBER(deh_offset(deh)),
+				(unsigned long *)de->de_gen_number_bit_string);
+
+		// calculate pointer to name and namelen
+		de->de_entry_num = i;
+		set_de_name_and_namelen(de);
+
+		if ((retval =
+		     reiserfs_match(de, name, namelen)) != NAME_NOT_FOUND) {
+			// de's de_name, de_namelen, de_recordlen are set. Fill the rest:
+
+			// key of pointed object
+			set_de_object_key(de);
+
+			store_de_entry_key(de);
+
+			// retval can be NAME_FOUND or NAME_FOUND_INVISIBLE
+			return retval;
+		}
 	}
-    }
 
-    if (GET_GENERATION_NUMBER (le_ih_k_offset (de->de_ih)) == 0)
-	/* we have reached left most entry in the node. In common we
-           have to go to the left neighbor, but if generation counter
-           is 0 already, we know for sure, that there is no name with
-           the same hash value */
-	// FIXME: this work correctly only because hash value can not
-	// be 0. Btw, in case of Yura's hash it is probably possible,
-	// so, this is a bug
-	return NAME_NOT_FOUND;
+	if (GET_GENERATION_NUMBER(le_ih_k_offset(de->de_ih)) == 0)
+		/* we have reached left most entry in the node. In common we
+		   have to go to the left neighbor, but if generation counter
+		   is 0 already, we know for sure, that there is no name with
+		   the same hash value */
+		// FIXME: this work correctly only because hash value can not
+		// be 0. Btw, in case of Yura's hash it is probably possible,
+		// so, this is a bug
+		return NAME_NOT_FOUND;
 
-    RFALSE( de->de_item_num,
-	    "vs-7015: two diritems of the same directory in one node?");
+	RFALSE(de->de_item_num,
+	       "vs-7015: two diritems of the same directory in one node?");
 
-    return GOTO_PREVIOUS_ITEM;
+	return GOTO_PREVIOUS_ITEM;
 }
 
-
 // may return NAME_FOUND, NAME_FOUND_INVISIBLE, NAME_NOT_FOUND
 // FIXME: should add something like IOERROR
-static int reiserfs_find_entry (struct inode * dir, const char * name, int namelen, 
-				struct path * path_to_entry, struct reiserfs_dir_entry * de)
-{
-    struct cpu_key key_to_search;
-    int retval;
-
-
-    if (namelen > REISERFS_MAX_NAME (dir->i_sb->s_blocksize))
-	return NAME_NOT_FOUND;
-
-    /* we will search for this key in the tree */
-    make_cpu_key (&key_to_search, dir, 
-		  get_third_component (dir->i_sb, name, namelen), TYPE_DIRENTRY, 3);
-
-    while (1) {
-	retval = search_by_entry_key (dir->i_sb, &key_to_search, path_to_entry, de);
-	if (retval == IO_ERROR) {
-	    reiserfs_warning (dir->i_sb, "zam-7001: io error in %s",
-			      __FUNCTION__);
-	    return IO_ERROR;
+static int reiserfs_find_entry(struct inode *dir, const char *name, int namelen,
+			       struct path *path_to_entry,
+			       struct reiserfs_dir_entry *de)
+{
+	struct cpu_key key_to_search;
+	int retval;
+
+	if (namelen > REISERFS_MAX_NAME(dir->i_sb->s_blocksize))
+		return NAME_NOT_FOUND;
+
+	/* we will search for this key in the tree */
+	make_cpu_key(&key_to_search, dir,
+		     get_third_component(dir->i_sb, name, namelen),
+		     TYPE_DIRENTRY, 3);
+
+	while (1) {
+		retval =
+		    search_by_entry_key(dir->i_sb, &key_to_search,
+					path_to_entry, de);
+		if (retval == IO_ERROR) {
+			reiserfs_warning(dir->i_sb, "zam-7001: io error in %s",
+					 __FUNCTION__);
+			return IO_ERROR;
+		}
+
+		/* compare names for all entries having given hash value */
+		retval =
+		    linear_search_in_dir_item(&key_to_search, de, name,
+					      namelen);
+		if (retval != GOTO_PREVIOUS_ITEM) {
+			/* there is no need to scan directory anymore. Given entry found or does not exist */
+			path_to_entry->pos_in_item = de->de_entry_num;
+			return retval;
+		}
+
+		/* there is left neighboring item of this directory and given entry can be there */
+		set_cpu_key_k_offset(&key_to_search,
+				     le_ih_k_offset(de->de_ih) - 1);
+		pathrelse(path_to_entry);
+
+	}			/* while (1) */
+}
+
+static struct dentry *reiserfs_lookup(struct inode *dir, struct dentry *dentry,
+				      struct nameidata *nd)
+{
+	int retval;
+	struct inode *inode = NULL;
+	struct reiserfs_dir_entry de;
+	INITIALIZE_PATH(path_to_entry);
+
+	if (REISERFS_MAX_NAME(dir->i_sb->s_blocksize) < dentry->d_name.len)
+		return ERR_PTR(-ENAMETOOLONG);
+
+	reiserfs_write_lock(dir->i_sb);
+	de.de_gen_number_bit_string = NULL;
+	retval =
+	    reiserfs_find_entry(dir, dentry->d_name.name, dentry->d_name.len,
+				&path_to_entry, &de);
+	pathrelse(&path_to_entry);
+	if (retval == NAME_FOUND) {
+		/* Hide the .reiserfs_priv directory */
+		if (reiserfs_xattrs(dir->i_sb) &&
+		    !old_format_only(dir->i_sb) &&
+		    REISERFS_SB(dir->i_sb)->priv_root &&
+		    REISERFS_SB(dir->i_sb)->priv_root->d_inode &&
+		    de.de_objectid ==
+		    le32_to_cpu(INODE_PKEY
+				(REISERFS_SB(dir->i_sb)->priv_root->d_inode)->
+				k_objectid)) {
+			reiserfs_write_unlock(dir->i_sb);
+			return ERR_PTR(-EACCES);
+		}
+
+		inode =
+		    reiserfs_iget(dir->i_sb, (struct cpu_key *)&(de.de_dir_id));
+		if (!inode || IS_ERR(inode)) {
+			reiserfs_write_unlock(dir->i_sb);
+			return ERR_PTR(-EACCES);
+		}
+
+		/* Propogate the priv_object flag so we know we're in the priv tree */
+		if (is_reiserfs_priv_object(dir))
+			reiserfs_mark_inode_private(inode);
 	}
-
-	/* compare names for all entries having given hash value */
-	retval = linear_search_in_dir_item (&key_to_search, de, name, namelen);
-	if (retval != GOTO_PREVIOUS_ITEM) {
-	    /* there is no need to scan directory anymore. Given entry found or does not exist */
-	    path_to_entry->pos_in_item = de->de_entry_num;
-	    return retval;
+	reiserfs_write_unlock(dir->i_sb);
+	if (retval == IO_ERROR) {
+		return ERR_PTR(-EIO);
 	}
 
-	/* there is left neighboring item of this directory and given entry can be there */
-	set_cpu_key_k_offset (&key_to_search, le_ih_k_offset (de->de_ih) - 1);
-	pathrelse (path_to_entry);
-
-    } /* while (1) */
-}
-
+	if (inode)
+		return d_splice_alias(inode, dentry);
 
-static struct dentry * reiserfs_lookup (struct inode * dir, struct dentry * dentry, struct nameidata *nd)
-{
-    int retval;
-    struct inode * inode = NULL;
-    struct reiserfs_dir_entry de;
-    INITIALIZE_PATH (path_to_entry);
-
-    if (REISERFS_MAX_NAME (dir->i_sb->s_blocksize) < dentry->d_name.len)
-	return ERR_PTR(-ENAMETOOLONG);
-
-    reiserfs_write_lock(dir->i_sb);
-    de.de_gen_number_bit_string = NULL;
-    retval = reiserfs_find_entry (dir, dentry->d_name.name, dentry->d_name.len, &path_to_entry, &de);
-    pathrelse (&path_to_entry);
-    if (retval == NAME_FOUND) {
-        /* Hide the .reiserfs_priv directory */
-	if (reiserfs_xattrs (dir->i_sb) &&
-	    !old_format_only(dir->i_sb) &&
-            REISERFS_SB(dir->i_sb)->priv_root &&
-            REISERFS_SB(dir->i_sb)->priv_root->d_inode &&
-	    de.de_objectid == le32_to_cpu (INODE_PKEY(REISERFS_SB(dir->i_sb)->priv_root->d_inode)->k_objectid)) {
-	  reiserfs_write_unlock (dir->i_sb);
-	  return ERR_PTR (-EACCES);
-	}
-
-	inode = reiserfs_iget (dir->i_sb, (struct cpu_key *)&(de.de_dir_id));
-	if (!inode || IS_ERR(inode)) {
-	    reiserfs_write_unlock(dir->i_sb);
-	    return ERR_PTR(-EACCES);
-        }
-
-	/* Propogate the priv_object flag so we know we're in the priv tree */
-	if (is_reiserfs_priv_object (dir))
-	    reiserfs_mark_inode_private (inode);
-    }
-    reiserfs_write_unlock(dir->i_sb);
-    if ( retval == IO_ERROR ) {
-	return ERR_PTR(-EIO);
-    }
-
-    if (inode)
-	    return d_splice_alias(inode, dentry);
-    
-    d_add(dentry, inode);
-    return NULL;
+	d_add(dentry, inode);
+	return NULL;
 }
 
-
 /* 
 ** looks up the dentry of the parent directory for child.
 ** taken from ext2_get_parent
 */
 struct dentry *reiserfs_get_parent(struct dentry *child)
 {
-    int retval;
-    struct inode * inode = NULL;
-    struct reiserfs_dir_entry de;
-    INITIALIZE_PATH (path_to_entry);
-    struct dentry *parent;
-    struct inode *dir = child->d_inode ;
-
-
-    if (dir->i_nlink == 0) {
-	return ERR_PTR(-ENOENT);
-    }
-    de.de_gen_number_bit_string = NULL;
-
-    reiserfs_write_lock(dir->i_sb);
-    retval = reiserfs_find_entry (dir, "..", 2, &path_to_entry, &de);
-    pathrelse (&path_to_entry);
-    if (retval != NAME_FOUND) {
+	int retval;
+	struct inode *inode = NULL;
+	struct reiserfs_dir_entry de;
+	INITIALIZE_PATH(path_to_entry);
+	struct dentry *parent;
+	struct inode *dir = child->d_inode;
+
+	if (dir->i_nlink == 0) {
+		return ERR_PTR(-ENOENT);
+	}
+	de.de_gen_number_bit_string = NULL;
+
+	reiserfs_write_lock(dir->i_sb);
+	retval = reiserfs_find_entry(dir, "..", 2, &path_to_entry, &de);
+	pathrelse(&path_to_entry);
+	if (retval != NAME_FOUND) {
+		reiserfs_write_unlock(dir->i_sb);
+		return ERR_PTR(-ENOENT);
+	}
+	inode = reiserfs_iget(dir->i_sb, (struct cpu_key *)&(de.de_dir_id));
 	reiserfs_write_unlock(dir->i_sb);
-	return ERR_PTR(-ENOENT);
-    }
-    inode = reiserfs_iget (dir->i_sb, (struct cpu_key *)&(de.de_dir_id));
-    reiserfs_write_unlock(dir->i_sb);
-
-    if (!inode || IS_ERR(inode)) {
-	return ERR_PTR(-EACCES);
-    }
-    parent = d_alloc_anon(inode);
-    if (!parent) {
-	iput(inode);
-	parent = ERR_PTR(-ENOMEM);
-    }
-    return parent;
-}
 
+	if (!inode || IS_ERR(inode)) {
+		return ERR_PTR(-EACCES);
+	}
+	parent = d_alloc_anon(inode);
+	if (!parent) {
+		iput(inode);
+		parent = ERR_PTR(-ENOMEM);
+	}
+	return parent;
+}
 
 /* add entry to the directory (entry can be hidden). 
 
@@ -415,132 +427,143 @@ insert definition of when hidden directo
 
  Does not mark dir   inode dirty, do it after successesfull call to it */
 
-static int reiserfs_add_entry (struct reiserfs_transaction_handle *th, struct inode * dir,
-                               const char * name, int namelen, struct inode * inode,
-			       int visible)
-{
-    struct cpu_key entry_key;
-    struct reiserfs_de_head * deh;
-    INITIALIZE_PATH (path);
-    struct reiserfs_dir_entry de;
-    int bit_string [MAX_GENERATION_NUMBER / (sizeof(int) * 8) + 1];
-    int gen_number;
-    char small_buf[32+DEH_SIZE] ; /* 48 bytes now and we avoid kmalloc
-                                     if we create file with short name */
-    char * buffer;
-    int buflen, paste_size;
-    int retval;
-
-    BUG_ON (!th->t_trans_id);
-
-    /* cannot allow items to be added into a busy deleted directory */
-    if (!namelen)
-	return -EINVAL;
-
-    if (namelen > REISERFS_MAX_NAME (dir->i_sb->s_blocksize))
-	return -ENAMETOOLONG;
-
-    /* each entry has unique key. compose it */
-    make_cpu_key (&entry_key, dir, 
-		  get_third_component (dir->i_sb, name, namelen), TYPE_DIRENTRY, 3);
-
-    /* get memory for composing the entry */
-    buflen = DEH_SIZE + ROUND_UP (namelen);
-    if (buflen > sizeof (small_buf)) {
-	buffer = reiserfs_kmalloc (buflen, GFP_NOFS, dir->i_sb);
-	if (buffer == 0)
-	    return -ENOMEM;
-    } else
-	buffer = small_buf;
-
-    paste_size = (get_inode_sd_version (dir) == STAT_DATA_V1) ? (DEH_SIZE + namelen) : buflen;
-
-    /* fill buffer : directory entry head, name[, dir objectid | , stat data | ,stat data, dir objectid ] */
-    deh = (struct reiserfs_de_head *)buffer;
-    deh->deh_location = 0; /* JDM Endian safe if 0 */
-    put_deh_offset( deh, cpu_key_k_offset( &entry_key ) );
-    deh->deh_state = 0; /* JDM Endian safe if 0 */
-    /* put key (ino analog) to de */
-    deh->deh_dir_id = INODE_PKEY (inode)->k_dir_id; /* safe: k_dir_id is le */
-    deh->deh_objectid = INODE_PKEY (inode)->k_objectid; /* safe: k_objectid is le */
-
-    /* copy name */
-    memcpy ((char *)(deh + 1), name, namelen);
-    /* padd by 0s to the 4 byte boundary */
-    padd_item ((char *)(deh + 1), ROUND_UP (namelen), namelen);
-
-    /* entry is ready to be pasted into tree, set 'visibility' and 'stat data in entry' attributes */
-    mark_de_without_sd (deh);
-    visible ? mark_de_visible (deh) : mark_de_hidden (deh);
-
-    /* find the proper place for the new entry */
-    memset (bit_string, 0, sizeof (bit_string));
-    de.de_gen_number_bit_string = (char *)bit_string;
-    retval = reiserfs_find_entry (dir, name, namelen, &path, &de);
-    if( retval != NAME_NOT_FOUND ) {
-	if (buffer != small_buf)
-	    reiserfs_kfree (buffer, buflen, dir->i_sb);
-	pathrelse (&path);
+static int reiserfs_add_entry(struct reiserfs_transaction_handle *th,
+			      struct inode *dir, const char *name, int namelen,
+			      struct inode *inode, int visible)
+{
+	struct cpu_key entry_key;
+	struct reiserfs_de_head *deh;
+	INITIALIZE_PATH(path);
+	struct reiserfs_dir_entry de;
+	int bit_string[MAX_GENERATION_NUMBER / (sizeof(int) * 8) + 1];
+	int gen_number;
+	char small_buf[32 + DEH_SIZE];	/* 48 bytes now and we avoid kmalloc
+					   if we create file with short name */
+	char *buffer;
+	int buflen, paste_size;
+	int retval;
+
+	BUG_ON(!th->t_trans_id);
+
+	/* cannot allow items to be added into a busy deleted directory */
+	if (!namelen)
+		return -EINVAL;
+
+	if (namelen > REISERFS_MAX_NAME(dir->i_sb->s_blocksize))
+		return -ENAMETOOLONG;
+
+	/* each entry has unique key. compose it */
+	make_cpu_key(&entry_key, dir,
+		     get_third_component(dir->i_sb, name, namelen),
+		     TYPE_DIRENTRY, 3);
+
+	/* get memory for composing the entry */
+	buflen = DEH_SIZE + ROUND_UP(namelen);
+	if (buflen > sizeof(small_buf)) {
+		buffer = reiserfs_kmalloc(buflen, GFP_NOFS, dir->i_sb);
+		if (buffer == 0)
+			return -ENOMEM;
+	} else
+		buffer = small_buf;
+
+	paste_size =
+	    (get_inode_sd_version(dir) ==
+	     STAT_DATA_V1) ? (DEH_SIZE + namelen) : buflen;
+
+	/* fill buffer : directory entry head, name[, dir objectid | , stat data | ,stat data, dir objectid ] */
+	deh = (struct reiserfs_de_head *)buffer;
+	deh->deh_location = 0;	/* JDM Endian safe if 0 */
+	put_deh_offset(deh, cpu_key_k_offset(&entry_key));
+	deh->deh_state = 0;	/* JDM Endian safe if 0 */
+	/* put key (ino analog) to de */
+	deh->deh_dir_id = INODE_PKEY(inode)->k_dir_id;	/* safe: k_dir_id is le */
+	deh->deh_objectid = INODE_PKEY(inode)->k_objectid;	/* safe: k_objectid is le */
+
+	/* copy name */
+	memcpy((char *)(deh + 1), name, namelen);
+	/* padd by 0s to the 4 byte boundary */
+	padd_item((char *)(deh + 1), ROUND_UP(namelen), namelen);
+
+	/* entry is ready to be pasted into tree, set 'visibility' and 'stat data in entry' attributes */
+	mark_de_without_sd(deh);
+	visible ? mark_de_visible(deh) : mark_de_hidden(deh);
+
+	/* find the proper place for the new entry */
+	memset(bit_string, 0, sizeof(bit_string));
+	de.de_gen_number_bit_string = (char *)bit_string;
+	retval = reiserfs_find_entry(dir, name, namelen, &path, &de);
+	if (retval != NAME_NOT_FOUND) {
+		if (buffer != small_buf)
+			reiserfs_kfree(buffer, buflen, dir->i_sb);
+		pathrelse(&path);
+
+		if (retval == IO_ERROR) {
+			return -EIO;
+		}
+
+		if (retval != NAME_FOUND) {
+			reiserfs_warning(dir->i_sb,
+					 "zam-7002:%s: \"reiserfs_find_entry\" "
+					 "has returned unexpected value (%d)",
+					 __FUNCTION__, retval);
+		}
 
-	if ( retval == IO_ERROR ) {
-	    return -EIO;
+		return -EEXIST;
 	}
 
-        if (retval != NAME_FOUND) {
-	    reiserfs_warning (dir->i_sb, "zam-7002:%s: \"reiserfs_find_entry\" "
-			      "has returned unexpected value (%d)",
-			      __FUNCTION__, retval);
-       }
-
-	return -EEXIST;
-    }
-
-    gen_number = find_first_zero_bit ((unsigned long *)bit_string, MAX_GENERATION_NUMBER + 1);
-    if (gen_number > MAX_GENERATION_NUMBER) {
-      /* there is no free generation number */
-      reiserfs_warning (dir->i_sb, "reiserfs_add_entry: Congratulations! we have got hash function screwed up");
-      if (buffer != small_buf)
-          reiserfs_kfree (buffer, buflen, dir->i_sb);
-      pathrelse (&path);
-      return -EBUSY;
-    }
-    /* adjust offset of directory enrty */
-    put_deh_offset(deh, SET_GENERATION_NUMBER(deh_offset(deh), gen_number));
-    set_cpu_key_k_offset (&entry_key, deh_offset(deh));
- 
-    /* update max-hash-collisions counter in reiserfs_sb_info */
-    PROC_INFO_MAX( th -> t_super, max_hash_collisions, gen_number );
- 		  
-    if (gen_number != 0) {	/* we need to re-search for the insertion point */
-      if (search_by_entry_key (dir->i_sb, &entry_key, &path, &de) != NAME_NOT_FOUND) {
-            reiserfs_warning (dir->i_sb, "vs-7032: reiserfs_add_entry: "
-                              "entry with this key (%K) already exists",
-                              &entry_key);
-
-	    if (buffer != small_buf)
-		reiserfs_kfree (buffer, buflen, dir->i_sb);
-	    pathrelse (&path);
-	    return -EBUSY;
-	}
-    }
-  
-    /* perform the insertion of the entry that we have prepared */
-    retval = reiserfs_paste_into_item (th, &path, &entry_key, dir, buffer, paste_size);
-    if (buffer != small_buf)
-	reiserfs_kfree (buffer, buflen, dir->i_sb);
-    if (retval) {
-	reiserfs_check_path(&path) ;
-	return retval;
-    }
+	gen_number =
+	    find_first_zero_bit((unsigned long *)bit_string,
+				MAX_GENERATION_NUMBER + 1);
+	if (gen_number > MAX_GENERATION_NUMBER) {
+		/* there is no free generation number */
+		reiserfs_warning(dir->i_sb,
+				 "reiserfs_add_entry: Congratulations! we have got hash function screwed up");
+		if (buffer != small_buf)
+			reiserfs_kfree(buffer, buflen, dir->i_sb);
+		pathrelse(&path);
+		return -EBUSY;
+	}
+	/* adjust offset of directory enrty */
+	put_deh_offset(deh, SET_GENERATION_NUMBER(deh_offset(deh), gen_number));
+	set_cpu_key_k_offset(&entry_key, deh_offset(deh));
+
+	/* update max-hash-collisions counter in reiserfs_sb_info */
+	PROC_INFO_MAX(th->t_super, max_hash_collisions, gen_number);
+
+	if (gen_number != 0) {	/* we need to re-search for the insertion point */
+		if (search_by_entry_key(dir->i_sb, &entry_key, &path, &de) !=
+		    NAME_NOT_FOUND) {
+			reiserfs_warning(dir->i_sb,
+					 "vs-7032: reiserfs_add_entry: "
+					 "entry with this key (%K) already exists",
+					 &entry_key);
+
+			if (buffer != small_buf)
+				reiserfs_kfree(buffer, buflen, dir->i_sb);
+			pathrelse(&path);
+			return -EBUSY;
+		}
+	}
 
-    dir->i_size += paste_size;
-    dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC;
-    if (!S_ISDIR (inode->i_mode) && visible)
-	// reiserfs_mkdir or reiserfs_rename will do that by itself
-	reiserfs_update_sd (th, dir);
+	/* perform the insertion of the entry that we have prepared */
+	retval =
+	    reiserfs_paste_into_item(th, &path, &entry_key, dir, buffer,
+				     paste_size);
+	if (buffer != small_buf)
+		reiserfs_kfree(buffer, buflen, dir->i_sb);
+	if (retval) {
+		reiserfs_check_path(&path);
+		return retval;
+	}
+
+	dir->i_size += paste_size;
+	dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC;
+	if (!S_ISDIR(inode->i_mode) && visible)
+		// reiserfs_mkdir or reiserfs_rename will do that by itself
+		reiserfs_update_sd(th, dir);
 
-    reiserfs_check_path(&path) ;
-    return 0;
+	reiserfs_check_path(&path);
+	return 0;
 }
 
 /* quota utility function, call if you've had to abort after calling
@@ -548,12 +571,13 @@ static int reiserfs_add_entry (struct re
 ** This should only be called on inodes that do not have stat data
 ** inserted into the tree yet.
 */
-static int drop_new_inode(struct inode *inode) {
-    DQUOT_DROP(inode);
-    make_bad_inode(inode) ;
-    inode->i_flags |= S_NOQUOTA;
-    iput(inode) ;
-    return 0 ;
+static int drop_new_inode(struct inode *inode)
+{
+	DQUOT_DROP(inode);
+	make_bad_inode(inode);
+	inode->i_flags |= S_NOQUOTA;
+	iput(inode);
+	return 0;
 }
 
 /* utility function that does setup for reiserfs_new_inode.  
@@ -561,902 +585,971 @@ static int drop_new_inode(struct inode *
 ** outside of a transaction, so we had to pull some bits of
 ** reiserfs_new_inode out into this func.
 */
-static int new_inode_init(struct inode *inode, struct inode *dir, int mode) {
+static int new_inode_init(struct inode *inode, struct inode *dir, int mode)
+{
 
-    /* the quota init calls have to know who to charge the quota to, so
-    ** we have to set uid and gid here
-    */
-    inode->i_uid = current->fsuid;
-    inode->i_mode = mode;
-
-    if (dir->i_mode & S_ISGID) {
-        inode->i_gid = dir->i_gid;
-        if (S_ISDIR(mode))
-            inode->i_mode |= S_ISGID;
-    } else {
-        inode->i_gid = current->fsgid;
-    }
-    DQUOT_INIT(inode);
-    return 0 ;
-}
-
-static int reiserfs_create (struct inode * dir, struct dentry *dentry, int mode,
-		struct nameidata *nd)
-{
-    int retval;
-    struct inode * inode;
-    /* We need blocks for transaction + (user+group)*(quotas for new inode + update of quota for directory owner) */
-    int jbegin_count = JOURNAL_PER_BALANCE_CNT * 2 + 2 * (REISERFS_QUOTA_INIT_BLOCKS+REISERFS_QUOTA_TRANS_BLOCKS);
-    struct reiserfs_transaction_handle th ;
-    int locked;
-
-    if (!(inode = new_inode(dir->i_sb))) {
-	return -ENOMEM ;
-    }
-    new_inode_init(inode, dir, mode);
-
-    locked = reiserfs_cache_default_acl (dir);
-
-    reiserfs_write_lock(dir->i_sb);
-
-    if (locked)
-        reiserfs_write_lock_xattrs (dir->i_sb);
-
-    retval = journal_begin(&th, dir->i_sb, jbegin_count);
-    if (retval) {
-        drop_new_inode (inode);
-        goto out_failed;
-    }
-
-    retval = reiserfs_new_inode (&th, dir, mode, NULL, 0/*i_size*/, dentry, inode);
-    if (retval)
-        goto out_failed;
-	
-    if (locked) {
-        reiserfs_write_unlock_xattrs (dir->i_sb);
-        locked = 0;
-    }
-
-    inode->i_op = &reiserfs_file_inode_operations;
-    inode->i_fop = &reiserfs_file_operations;
-    inode->i_mapping->a_ops = &reiserfs_address_space_operations ;
-
-    retval = reiserfs_add_entry (&th, dir, dentry->d_name.name, dentry->d_name.len, 
-				inode, 1/*visible*/);
-    if (retval) {
-        int err;
-	inode->i_nlink--;
-	reiserfs_update_sd (&th, inode);
-	err = journal_end(&th, dir->i_sb, jbegin_count) ;
-        if (err)
-            retval = err;
-	iput (inode);
-	goto out_failed;
-    }
-    reiserfs_update_inode_transaction(inode) ;
-    reiserfs_update_inode_transaction(dir) ;
+	/* the quota init calls have to know who to charge the quota to, so
+	 ** we have to set uid and gid here
+	 */
+	inode->i_uid = current->fsuid;
+	inode->i_mode = mode;
+	/* Make inode invalid - just in case we are going to drop it before
+	 * the initialization happens */
+	INODE_PKEY(inode)->k_objectid = 0;
+
+	if (dir->i_mode & S_ISGID) {
+		inode->i_gid = dir->i_gid;
+		if (S_ISDIR(mode))
+			inode->i_mode |= S_ISGID;
+	} else {
+		inode->i_gid = current->fsgid;
+	}
+	DQUOT_INIT(inode);
+	return 0;
+}
 
-    d_instantiate(dentry, inode);
-    retval = journal_end(&th, dir->i_sb, jbegin_count) ;
+static int reiserfs_create(struct inode *dir, struct dentry *dentry, int mode,
+			   struct nameidata *nd)
+{
+	int retval;
+	struct inode *inode;
+	/* We need blocks for transaction + (user+group)*(quotas for new inode + update of quota for directory owner) */
+	int jbegin_count =
+	    JOURNAL_PER_BALANCE_CNT * 2 +
+	    2 * (REISERFS_QUOTA_INIT_BLOCKS(dir->i_sb) +
+		 REISERFS_QUOTA_TRANS_BLOCKS(dir->i_sb));
+	struct reiserfs_transaction_handle th;
+	int locked;
 
-out_failed:
-    if (locked)
-        reiserfs_write_unlock_xattrs (dir->i_sb);
-    reiserfs_write_unlock(dir->i_sb);
-    return retval;
-}
+	if (!(inode = new_inode(dir->i_sb))) {
+		return -ENOMEM;
+	}
+	new_inode_init(inode, dir, mode);
 
+	locked = reiserfs_cache_default_acl(dir);
 
-static int reiserfs_mknod (struct inode * dir, struct dentry *dentry, int mode, dev_t rdev)
+	reiserfs_write_lock(dir->i_sb);
+
+	if (locked)
+		reiserfs_write_lock_xattrs(dir->i_sb);
+
+	retval = journal_begin(&th, dir->i_sb, jbegin_count);
+	if (retval) {
+		drop_new_inode(inode);
+		goto out_failed;
+	}
+
+	retval =
+	    reiserfs_new_inode(&th, dir, mode, NULL, 0 /*i_size */ , dentry,
+			       inode);
+	if (retval)
+		goto out_failed;
+
+	if (locked) {
+		reiserfs_write_unlock_xattrs(dir->i_sb);
+		locked = 0;
+	}
+
+	inode->i_op = &reiserfs_file_inode_operations;
+	inode->i_fop = &reiserfs_file_operations;
+	inode->i_mapping->a_ops = &reiserfs_address_space_operations;
+
+	retval =
+	    reiserfs_add_entry(&th, dir, dentry->d_name.name,
+			       dentry->d_name.len, inode, 1 /*visible */ );
+	if (retval) {
+		int err;
+		inode->i_nlink--;
+		reiserfs_update_sd(&th, inode);
+		err = journal_end(&th, dir->i_sb, jbegin_count);
+		if (err)
+			retval = err;
+		iput(inode);
+		goto out_failed;
+	}
+	reiserfs_update_inode_transaction(inode);
+	reiserfs_update_inode_transaction(dir);
+
+	d_instantiate(dentry, inode);
+	retval = journal_end(&th, dir->i_sb, jbegin_count);
+
+      out_failed:
+	if (locked)
+		reiserfs_write_unlock_xattrs(dir->i_sb);
+	reiserfs_write_unlock(dir->i_sb);
+	return retval;
+}
+
+static int reiserfs_mknod(struct inode *dir, struct dentry *dentry, int mode,
+			  dev_t rdev)
 {
-    int retval;
-    struct inode * inode;
-    struct reiserfs_transaction_handle th ;
-    /* We need blocks for transaction + (user+group)*(quotas for new inode + update of quota for directory owner) */
-    int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3 + 2 * (REISERFS_QUOTA_INIT_BLOCKS+REISERFS_QUOTA_TRANS_BLOCKS);
-    int locked;
+	int retval;
+	struct inode *inode;
+	struct reiserfs_transaction_handle th;
+	/* We need blocks for transaction + (user+group)*(quotas for new inode + update of quota for directory owner) */
+	int jbegin_count =
+	    JOURNAL_PER_BALANCE_CNT * 3 +
+	    2 * (REISERFS_QUOTA_INIT_BLOCKS(dir->i_sb) +
+		 REISERFS_QUOTA_TRANS_BLOCKS(dir->i_sb));
+	int locked;
 
-    if (!new_valid_dev(rdev))
-	return -EINVAL;
+	if (!new_valid_dev(rdev))
+		return -EINVAL;
 
-    if (!(inode = new_inode(dir->i_sb))) {
-	return -ENOMEM ;
-    }
-    new_inode_init(inode, dir, mode);
+	if (!(inode = new_inode(dir->i_sb))) {
+		return -ENOMEM;
+	}
+	new_inode_init(inode, dir, mode);
 
-    locked = reiserfs_cache_default_acl (dir);
+	locked = reiserfs_cache_default_acl(dir);
 
-    reiserfs_write_lock(dir->i_sb);
+	reiserfs_write_lock(dir->i_sb);
 
-    if (locked)
-        reiserfs_write_lock_xattrs (dir->i_sb);
+	if (locked)
+		reiserfs_write_lock_xattrs(dir->i_sb);
 
-    retval = journal_begin(&th, dir->i_sb, jbegin_count) ;
-    if (retval) {
-        drop_new_inode (inode);
-        goto out_failed;
-    }
+	retval = journal_begin(&th, dir->i_sb, jbegin_count);
+	if (retval) {
+		drop_new_inode(inode);
+		goto out_failed;
+	}
 
-    retval = reiserfs_new_inode (&th, dir, mode, NULL, 0/*i_size*/, dentry, inode);
-    if (retval) {
-        goto out_failed;
-    }
+	retval =
+	    reiserfs_new_inode(&th, dir, mode, NULL, 0 /*i_size */ , dentry,
+			       inode);
+	if (retval) {
+		goto out_failed;
+	}
 
-    if (locked) {
-        reiserfs_write_unlock_xattrs (dir->i_sb);
-        locked = 0;
-    }
+	if (locked) {
+		reiserfs_write_unlock_xattrs(dir->i_sb);
+		locked = 0;
+	}
 
+	inode->i_op = &reiserfs_special_inode_operations;
+	init_special_inode(inode, inode->i_mode, rdev);
 
-    inode->i_op = &reiserfs_special_inode_operations;
-    init_special_inode(inode, inode->i_mode, rdev) ;
+	//FIXME: needed for block and char devices only
+	reiserfs_update_sd(&th, inode);
 
-    //FIXME: needed for block and char devices only
-    reiserfs_update_sd (&th, inode);
+	reiserfs_update_inode_transaction(inode);
+	reiserfs_update_inode_transaction(dir);
 
-    reiserfs_update_inode_transaction(inode) ;
-    reiserfs_update_inode_transaction(dir) ;
+	retval =
+	    reiserfs_add_entry(&th, dir, dentry->d_name.name,
+			       dentry->d_name.len, inode, 1 /*visible */ );
+	if (retval) {
+		int err;
+		inode->i_nlink--;
+		reiserfs_update_sd(&th, inode);
+		err = journal_end(&th, dir->i_sb, jbegin_count);
+		if (err)
+			retval = err;
+		iput(inode);
+		goto out_failed;
+	}
 
-    retval = reiserfs_add_entry (&th, dir, dentry->d_name.name, dentry->d_name.len, 
-				 inode, 1/*visible*/);
-    if (retval) {
-        int err;
-	inode->i_nlink--;
-	reiserfs_update_sd (&th, inode);
-	err = journal_end(&th, dir->i_sb, jbegin_count) ;
-        if (err)
-	    retval = err;
-	iput (inode);
-	goto out_failed;
-    }
-
-    d_instantiate(dentry, inode);
-    retval = journal_end(&th, dir->i_sb, jbegin_count) ;
-
-out_failed:
-    if (locked)
-        reiserfs_write_unlock_xattrs (dir->i_sb);
-    reiserfs_write_unlock(dir->i_sb);
-    return retval;
-}
+	d_instantiate(dentry, inode);
+	retval = journal_end(&th, dir->i_sb, jbegin_count);
 
+      out_failed:
+	if (locked)
+		reiserfs_write_unlock_xattrs(dir->i_sb);
+	reiserfs_write_unlock(dir->i_sb);
+	return retval;
+}
 
-static int reiserfs_mkdir (struct inode * dir, struct dentry *dentry, int mode)
-{
-    int retval;
-    struct inode * inode;
-    struct reiserfs_transaction_handle th ;
-    /* We need blocks for transaction + (user+group)*(quotas for new inode + update of quota for directory owner) */
-    int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3 + 2 * (REISERFS_QUOTA_INIT_BLOCKS+REISERFS_QUOTA_TRANS_BLOCKS);
-    int locked;
+static int reiserfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
+{
+	int retval;
+	struct inode *inode;
+	struct reiserfs_transaction_handle th;
+	/* We need blocks for transaction + (user+group)*(quotas for new inode + update of quota for directory owner) */
+	int jbegin_count =
+	    JOURNAL_PER_BALANCE_CNT * 3 +
+	    2 * (REISERFS_QUOTA_INIT_BLOCKS(dir->i_sb) +
+		 REISERFS_QUOTA_TRANS_BLOCKS(dir->i_sb));
+	int locked;
 
 #ifdef DISPLACE_NEW_PACKING_LOCALITIES
-    /* set flag that new packing locality created and new blocks for the content     * of that directory are not displaced yet */
-    REISERFS_I(dir)->new_packing_locality = 1;
+	/* set flag that new packing locality created and new blocks for the content     * of that directory are not displaced yet */
+	REISERFS_I(dir)->new_packing_locality = 1;
 #endif
-    mode = S_IFDIR | mode;
-    if (!(inode = new_inode(dir->i_sb))) {
-	return -ENOMEM ;
-    }
-    new_inode_init(inode, dir, mode);
-
-    locked = reiserfs_cache_default_acl (dir);
-
-    reiserfs_write_lock(dir->i_sb);
-    if (locked)
-        reiserfs_write_lock_xattrs (dir->i_sb);
-
-    retval = journal_begin(&th, dir->i_sb, jbegin_count) ;
-    if (retval) {
-        drop_new_inode (inode);
-        goto out_failed;
-    }
-
-
-    /* inc the link count now, so another writer doesn't overflow it while
-    ** we sleep later on.
-    */
-    INC_DIR_INODE_NLINK(dir)
-
-    retval = reiserfs_new_inode (&th, dir, mode, NULL/*symlink*/,
-				old_format_only (dir->i_sb) ? 
-				EMPTY_DIR_SIZE_V1 : EMPTY_DIR_SIZE,
-				dentry, inode);
-    if (retval) {
-	dir->i_nlink-- ;
-	goto out_failed;
-    }
-
-    if (locked) {
-	reiserfs_write_unlock_xattrs (dir->i_sb);
-	locked = 0;
-    }
-
-    reiserfs_update_inode_transaction(inode) ;
-    reiserfs_update_inode_transaction(dir) ;
-
-    inode->i_op = &reiserfs_dir_inode_operations;
-    inode->i_fop = &reiserfs_dir_operations;
-
-    // note, _this_ add_entry will not update dir's stat data
-    retval = reiserfs_add_entry (&th, dir, dentry->d_name.name, dentry->d_name.len, 
-				inode, 1/*visible*/);
-    if (retval) {
-	int err;
-	inode->i_nlink = 0;
-	DEC_DIR_INODE_NLINK(dir);
-	reiserfs_update_sd (&th, inode);
-	err = journal_end(&th, dir->i_sb, jbegin_count) ;
-	if (err)
-	    retval = err;
-	iput (inode);
-	goto out_failed;
-    }
-
-    // the above add_entry did not update dir's stat data
-    reiserfs_update_sd (&th, dir);
-
-    d_instantiate(dentry, inode);
-    retval = journal_end(&th, dir->i_sb, jbegin_count) ;
-out_failed:
-    if (locked)
-        reiserfs_write_unlock_xattrs (dir->i_sb);
-    reiserfs_write_unlock(dir->i_sb);
-    return retval;
-}
-
-static inline int reiserfs_empty_dir(struct inode *inode) {
-    /* we can cheat because an old format dir cannot have
-    ** EMPTY_DIR_SIZE, and a new format dir cannot have
-    ** EMPTY_DIR_SIZE_V1.  So, if the inode is either size, 
-    ** regardless of disk format version, the directory is empty.
-    */
-    if (inode->i_size != EMPTY_DIR_SIZE &&
-        inode->i_size != EMPTY_DIR_SIZE_V1) {
-        return 0 ;
-    }
-    return 1 ;
-}
-
-static int reiserfs_rmdir (struct inode * dir, struct dentry *dentry)
-{
-    int retval, err;
-    struct inode * inode;
-    struct reiserfs_transaction_handle th ;
-    int jbegin_count; 
-    INITIALIZE_PATH (path);
-    struct reiserfs_dir_entry de;
-
-
-    /* we will be doing 2 balancings and update 2 stat data, we change quotas
-     * of the owner of the directory and of the owner of the parent directory */
-    jbegin_count = JOURNAL_PER_BALANCE_CNT * 2 + 2 + 2 * (REISERFS_QUOTA_INIT_BLOCKS+REISERFS_QUOTA_TRANS_BLOCKS);
-
-    reiserfs_write_lock(dir->i_sb);
-    retval = journal_begin(&th, dir->i_sb, jbegin_count) ;
-    if (retval)
-        goto out_rmdir;
-
-    de.de_gen_number_bit_string = NULL;
-    if ( (retval = reiserfs_find_entry (dir, dentry->d_name.name, dentry->d_name.len, &path, &de)) == NAME_NOT_FOUND) {
-	retval = -ENOENT;
-	goto end_rmdir;
-    } else if ( retval == IO_ERROR) {
-	retval = -EIO;
-	goto end_rmdir;
-    }
-
-    inode = dentry->d_inode;
-
-    reiserfs_update_inode_transaction(inode) ;
-    reiserfs_update_inode_transaction(dir) ;
-
-    if (de.de_objectid != inode->i_ino) {
-	// FIXME: compare key of an object and a key found in the
-	// entry
-	retval = -EIO;
-	goto end_rmdir;
-    }
-    if (!reiserfs_empty_dir(inode)) {
-	retval = -ENOTEMPTY;
-	goto end_rmdir;
-    }
-
-    /* cut entry from dir directory */
-    retval = reiserfs_cut_from_item (&th, &path, &(de.de_entry_key), dir, 
-                                     NULL, /* page */ 
-				     0/*new file size - not used here*/);
-    if (retval < 0)
-	goto end_rmdir;
-
-    if ( inode->i_nlink != 2 && inode->i_nlink != 1 )
-	reiserfs_warning (inode->i_sb, "%s: empty directory has nlink "
-			  "!= 2 (%d)", __FUNCTION__, inode->i_nlink);
-
-    inode->i_nlink = 0;
-    inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC;
-    reiserfs_update_sd (&th, inode);
-
-    DEC_DIR_INODE_NLINK(dir)
-    dir->i_size -= (DEH_SIZE + de.de_entrylen);
-    reiserfs_update_sd (&th, dir);
-
-    /* prevent empty directory from getting lost */
-    add_save_link (&th, inode, 0/* not truncate */);
-
-    retval = journal_end(&th, dir->i_sb, jbegin_count) ;
-    reiserfs_check_path(&path) ;
-out_rmdir:
-    reiserfs_write_unlock(dir->i_sb);
-    return retval;
-	
- end_rmdir:
-    /* we must release path, because we did not call
-       reiserfs_cut_from_item, or reiserfs_cut_from_item does not
-       release path if operation was not complete */
-    pathrelse (&path);
-    err = journal_end(&th, dir->i_sb, jbegin_count) ;
-    reiserfs_write_unlock(dir->i_sb);
-    return err ? err : retval;
-}
-
-static int reiserfs_unlink (struct inode * dir, struct dentry *dentry)
-{
-    int retval, err;
-    struct inode * inode;
-    struct reiserfs_dir_entry de;
-    INITIALIZE_PATH (path);
-    struct reiserfs_transaction_handle th ;
-    int jbegin_count;
-    unsigned long savelink;
-
-    inode = dentry->d_inode;
-
-    /* in this transaction we can be doing at max two balancings and update
-       two stat datas, we change quotas of the owner of the directory and of
-       the owner of the parent directory */
-    jbegin_count = JOURNAL_PER_BALANCE_CNT * 2 + 2 + 2 * (REISERFS_QUOTA_INIT_BLOCKS+REISERFS_QUOTA_TRANS_BLOCKS);
-
-    reiserfs_write_lock(dir->i_sb);
-    retval = journal_begin(&th, dir->i_sb, jbegin_count) ;
-    if (retval)
-        goto out_unlink;
-	
-    de.de_gen_number_bit_string = NULL;
-    if ( (retval = reiserfs_find_entry (dir, dentry->d_name.name, dentry->d_name.len, &path, &de)) == NAME_NOT_FOUND) {
-	retval = -ENOENT;
-	goto end_unlink;
-    } else if (retval == IO_ERROR) {
-	retval = -EIO;
-	goto end_unlink;
-    }
-
-    reiserfs_update_inode_transaction(inode) ;
-    reiserfs_update_inode_transaction(dir) ;
-
-    if (de.de_objectid != inode->i_ino) {
-	// FIXME: compare key of an object and a key found in the
-	// entry
-	retval = -EIO;
-	goto end_unlink;
-    }
-  
-    if (!inode->i_nlink) {
-	reiserfs_warning (inode->i_sb, "%s: deleting nonexistent file "
-			  "(%s:%lu), %d", __FUNCTION__,
-			  reiserfs_bdevname (inode->i_sb), inode->i_ino,
-			  inode->i_nlink);
-	inode->i_nlink = 1;
-    }
-
-    inode->i_nlink--;
-
-    /*
-     * we schedule before doing the add_save_link call, save the link
-     * count so we don't race
-     */
-    savelink = inode->i_nlink;
+	mode = S_IFDIR | mode;
+	if (!(inode = new_inode(dir->i_sb))) {
+		return -ENOMEM;
+	}
+	new_inode_init(inode, dir, mode);
 
+	locked = reiserfs_cache_default_acl(dir);
 
-    retval = reiserfs_cut_from_item (&th, &path, &(de.de_entry_key), dir, NULL, 0);
-    if (retval < 0) {
-	inode->i_nlink++;
-	goto end_unlink;
-    }
-    inode->i_ctime = CURRENT_TIME_SEC;
-    reiserfs_update_sd (&th, inode);
-
-    dir->i_size -= (de.de_entrylen + DEH_SIZE);
-    dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC;
-    reiserfs_update_sd (&th, dir);
-
-    if (!savelink)
-       /* prevent file from getting lost */
-       add_save_link (&th, inode, 0/* not truncate */);
-
-    retval = journal_end(&th, dir->i_sb, jbegin_count) ;
-    reiserfs_check_path(&path) ;
-    reiserfs_write_unlock(dir->i_sb);
-    return retval;
-
- end_unlink:
-    pathrelse (&path);
-    err = journal_end(&th, dir->i_sb, jbegin_count) ;
-    reiserfs_check_path(&path) ;
-    if (err)
-        retval = err;
-out_unlink:
-    reiserfs_write_unlock(dir->i_sb);
-    return retval;
-}
-
-static int reiserfs_symlink (struct inode * parent_dir, 
-                            struct dentry * dentry, const char * symname)
-{
-    int retval;
-    struct inode * inode;
-    char * name;
-    int item_len;
-    struct reiserfs_transaction_handle th ;
-    int mode = S_IFLNK | S_IRWXUGO;
-    /* We need blocks for transaction + (user+group)*(quotas for new inode + update of quota for directory owner) */
-    int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3 + 2 * (REISERFS_QUOTA_INIT_BLOCKS+REISERFS_QUOTA_TRANS_BLOCKS);
-
-    if (!(inode = new_inode(parent_dir->i_sb))) {
-	return -ENOMEM ;
-    }
-    new_inode_init(inode, parent_dir, mode);
-
-    reiserfs_write_lock(parent_dir->i_sb);
-    item_len = ROUND_UP (strlen (symname));
-    if (item_len > MAX_DIRECT_ITEM_LEN (parent_dir->i_sb->s_blocksize)) {
-	retval =  -ENAMETOOLONG;
-	drop_new_inode(inode);
-	goto out_failed;
-    }
-  
-    name = reiserfs_kmalloc (item_len, GFP_NOFS, parent_dir->i_sb);
-    if (!name) {
-	drop_new_inode(inode);
-	retval =  -ENOMEM;
-	goto out_failed;
-    }
-    memcpy (name, symname, strlen (symname));
-    padd_item (name, item_len, strlen (symname));
-
-    /* We would inherit the default ACL here, but symlinks don't get ACLs */
-
-    retval = journal_begin(&th, parent_dir->i_sb, jbegin_count) ;
-    if (retval) {
-        drop_new_inode (inode);
-        reiserfs_kfree (name, item_len, parent_dir->i_sb);
-        goto out_failed;
-    }
-
-    retval = reiserfs_new_inode (&th, parent_dir, mode, name, strlen (symname), 
-                                 dentry, inode);
-    reiserfs_kfree (name, item_len, parent_dir->i_sb);
-    if (retval) { /* reiserfs_new_inode iputs for us */
-	goto out_failed;
-    }
-
-    reiserfs_update_inode_transaction(inode) ;
-    reiserfs_update_inode_transaction(parent_dir) ;
-
-    inode->i_op = &reiserfs_symlink_inode_operations;
-    inode->i_mapping->a_ops = &reiserfs_address_space_operations;
-
-    // must be sure this inode is written with this transaction
-    //
-    //reiserfs_update_sd (&th, inode, READ_BLOCKS);
-
-    retval = reiserfs_add_entry (&th, parent_dir, dentry->d_name.name, 
-                                 dentry->d_name.len, inode, 1/*visible*/);
-    if (retval) {
-	int err;
-	inode->i_nlink--;
-	reiserfs_update_sd (&th, inode);
-	err = journal_end(&th, parent_dir->i_sb, jbegin_count) ;
-	if (err)
-	    retval = err;
-	iput (inode);
-	goto out_failed;
-    }
-
-    d_instantiate(dentry, inode);
-    retval = journal_end(&th, parent_dir->i_sb, jbegin_count) ;
-out_failed:
-    reiserfs_write_unlock(parent_dir->i_sb);
-    return retval;
-}
-
-static int reiserfs_link (struct dentry * old_dentry, struct inode * dir, struct dentry * dentry)
-{
-    int retval;
-    struct inode *inode = old_dentry->d_inode;
-    struct reiserfs_transaction_handle th ;
-    /* We need blocks for transaction + update of quotas for the owners of the directory */
-    int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3 + 2 * REISERFS_QUOTA_TRANS_BLOCKS;
-
-    reiserfs_write_lock(dir->i_sb);
-    if (inode->i_nlink >= REISERFS_LINK_MAX) {
-	//FIXME: sd_nlink is 32 bit for new files
+	reiserfs_write_lock(dir->i_sb);
+	if (locked)
+		reiserfs_write_lock_xattrs(dir->i_sb);
+
+	retval = journal_begin(&th, dir->i_sb, jbegin_count);
+	if (retval) {
+		drop_new_inode(inode);
+		goto out_failed;
+	}
+
+	/* inc the link count now, so another writer doesn't overflow it while
+	 ** we sleep later on.
+	 */
+	INC_DIR_INODE_NLINK(dir)
+
+	    retval = reiserfs_new_inode(&th, dir, mode, NULL /*symlink */ ,
+					old_format_only(dir->i_sb) ?
+					EMPTY_DIR_SIZE_V1 : EMPTY_DIR_SIZE,
+					dentry, inode);
+	if (retval) {
+		dir->i_nlink--;
+		goto out_failed;
+	}
+
+	if (locked) {
+		reiserfs_write_unlock_xattrs(dir->i_sb);
+		locked = 0;
+	}
+
+	reiserfs_update_inode_transaction(inode);
+	reiserfs_update_inode_transaction(dir);
+
+	inode->i_op = &reiserfs_dir_inode_operations;
+	inode->i_fop = &reiserfs_dir_operations;
+
+	// note, _this_ add_entry will not update dir's stat data
+	retval =
+	    reiserfs_add_entry(&th, dir, dentry->d_name.name,
+			       dentry->d_name.len, inode, 1 /*visible */ );
+	if (retval) {
+		int err;
+		inode->i_nlink = 0;
+		DEC_DIR_INODE_NLINK(dir);
+		reiserfs_update_sd(&th, inode);
+		err = journal_end(&th, dir->i_sb, jbegin_count);
+		if (err)
+			retval = err;
+		iput(inode);
+		goto out_failed;
+	}
+	// the above add_entry did not update dir's stat data
+	reiserfs_update_sd(&th, dir);
+
+	d_instantiate(dentry, inode);
+	retval = journal_end(&th, dir->i_sb, jbegin_count);
+      out_failed:
+	if (locked)
+		reiserfs_write_unlock_xattrs(dir->i_sb);
 	reiserfs_write_unlock(dir->i_sb);
-	return -EMLINK;
-    }
-    if (inode->i_nlink == 0) {
-        reiserfs_write_unlock(dir->i_sb);
-        return -ENOENT;
-    }
-
-    /* inc before scheduling so reiserfs_unlink knows we are here */
-    inode->i_nlink++;
-
-    retval = journal_begin(&th, dir->i_sb, jbegin_count) ;
-    if (retval) {
-        inode->i_nlink--;
-        reiserfs_write_unlock (dir->i_sb);
-        return retval;
-    }
-
-    /* create new entry */
-    retval = reiserfs_add_entry (&th, dir, dentry->d_name.name, dentry->d_name.len,
-				 inode, 1/*visible*/);
+	return retval;
+}
 
-    reiserfs_update_inode_transaction(inode) ;
-    reiserfs_update_inode_transaction(dir) ;
+static inline int reiserfs_empty_dir(struct inode *inode)
+{
+	/* we can cheat because an old format dir cannot have
+	 ** EMPTY_DIR_SIZE, and a new format dir cannot have
+	 ** EMPTY_DIR_SIZE_V1.  So, if the inode is either size, 
+	 ** regardless of disk format version, the directory is empty.
+	 */
+	if (inode->i_size != EMPTY_DIR_SIZE &&
+	    inode->i_size != EMPTY_DIR_SIZE_V1) {
+		return 0;
+	}
+	return 1;
+}
 
-    if (retval) {
-	int err;
-	inode->i_nlink--;
-	err = journal_end(&th, dir->i_sb, jbegin_count) ;
+static int reiserfs_rmdir(struct inode *dir, struct dentry *dentry)
+{
+	int retval, err;
+	struct inode *inode;
+	struct reiserfs_transaction_handle th;
+	int jbegin_count;
+	INITIALIZE_PATH(path);
+	struct reiserfs_dir_entry de;
+
+	/* we will be doing 2 balancings and update 2 stat data, we change quotas
+	 * of the owner of the directory and of the owner of the parent directory.
+	 * The quota structure is possibly deleted only on last iput => outside
+	 * of this transaction */
+	jbegin_count =
+	    JOURNAL_PER_BALANCE_CNT * 2 + 2 +
+	    4 * REISERFS_QUOTA_TRANS_BLOCKS(dir->i_sb);
+
+	reiserfs_write_lock(dir->i_sb);
+	retval = journal_begin(&th, dir->i_sb, jbegin_count);
+	if (retval)
+		goto out_rmdir;
+
+	de.de_gen_number_bit_string = NULL;
+	if ((retval =
+	     reiserfs_find_entry(dir, dentry->d_name.name, dentry->d_name.len,
+				 &path, &de)) == NAME_NOT_FOUND) {
+		retval = -ENOENT;
+		goto end_rmdir;
+	} else if (retval == IO_ERROR) {
+		retval = -EIO;
+		goto end_rmdir;
+	}
+
+	inode = dentry->d_inode;
+
+	reiserfs_update_inode_transaction(inode);
+	reiserfs_update_inode_transaction(dir);
+
+	if (de.de_objectid != inode->i_ino) {
+		// FIXME: compare key of an object and a key found in the
+		// entry
+		retval = -EIO;
+		goto end_rmdir;
+	}
+	if (!reiserfs_empty_dir(inode)) {
+		retval = -ENOTEMPTY;
+		goto end_rmdir;
+	}
+
+	/* cut entry from dir directory */
+	retval = reiserfs_cut_from_item(&th, &path, &(de.de_entry_key), dir, NULL,	/* page */
+					0 /*new file size - not used here */ );
+	if (retval < 0)
+		goto end_rmdir;
+
+	if (inode->i_nlink != 2 && inode->i_nlink != 1)
+		reiserfs_warning(inode->i_sb, "%s: empty directory has nlink "
+				 "!= 2 (%d)", __FUNCTION__, inode->i_nlink);
+
+	inode->i_nlink = 0;
+	inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC;
+	reiserfs_update_sd(&th, inode);
+
+	DEC_DIR_INODE_NLINK(dir)
+	    dir->i_size -= (DEH_SIZE + de.de_entrylen);
+	reiserfs_update_sd(&th, dir);
+
+	/* prevent empty directory from getting lost */
+	add_save_link(&th, inode, 0 /* not truncate */ );
+
+	retval = journal_end(&th, dir->i_sb, jbegin_count);
+	reiserfs_check_path(&path);
+      out_rmdir:
+	reiserfs_write_unlock(dir->i_sb);
+	return retval;
+
+      end_rmdir:
+	/* we must release path, because we did not call
+	   reiserfs_cut_from_item, or reiserfs_cut_from_item does not
+	   release path if operation was not complete */
+	pathrelse(&path);
+	err = journal_end(&th, dir->i_sb, jbegin_count);
 	reiserfs_write_unlock(dir->i_sb);
 	return err ? err : retval;
-    }
+}
 
-    inode->i_ctime = CURRENT_TIME_SEC;
-    reiserfs_update_sd (&th, inode);
+static int reiserfs_unlink(struct inode *dir, struct dentry *dentry)
+{
+	int retval, err;
+	struct inode *inode;
+	struct reiserfs_dir_entry de;
+	INITIALIZE_PATH(path);
+	struct reiserfs_transaction_handle th;
+	int jbegin_count;
+	unsigned long savelink;
+
+	inode = dentry->d_inode;
+
+	/* in this transaction we can be doing at max two balancings and update
+	 * two stat datas, we change quotas of the owner of the directory and of
+	 * the owner of the parent directory. The quota structure is possibly
+	 * deleted only on iput => outside of this transaction */
+	jbegin_count =
+	    JOURNAL_PER_BALANCE_CNT * 2 + 2 +
+	    4 * REISERFS_QUOTA_TRANS_BLOCKS(dir->i_sb);
+
+	reiserfs_write_lock(dir->i_sb);
+	retval = journal_begin(&th, dir->i_sb, jbegin_count);
+	if (retval)
+		goto out_unlink;
+
+	de.de_gen_number_bit_string = NULL;
+	if ((retval =
+	     reiserfs_find_entry(dir, dentry->d_name.name, dentry->d_name.len,
+				 &path, &de)) == NAME_NOT_FOUND) {
+		retval = -ENOENT;
+		goto end_unlink;
+	} else if (retval == IO_ERROR) {
+		retval = -EIO;
+		goto end_unlink;
+	}
 
-    atomic_inc(&inode->i_count) ;
-    d_instantiate(dentry, inode);
-    retval = journal_end(&th, dir->i_sb, jbegin_count) ;
-    reiserfs_write_unlock(dir->i_sb);
-    return retval;
-}
+	reiserfs_update_inode_transaction(inode);
+	reiserfs_update_inode_transaction(dir);
 
+	if (de.de_objectid != inode->i_ino) {
+		// FIXME: compare key of an object and a key found in the
+		// entry
+		retval = -EIO;
+		goto end_unlink;
+	}
 
-// de contains information pointing to an entry which 
-static int de_still_valid (const char * name, int len, struct reiserfs_dir_entry * de)
-{
-    struct reiserfs_dir_entry tmp = *de;
-    
-    // recalculate pointer to name and name length
-    set_de_name_and_namelen (&tmp);
-    // FIXME: could check more
-    if (tmp.de_namelen != len || memcmp (name, de->de_name, len))
-	return 0;
-    return 1;
+	if (!inode->i_nlink) {
+		reiserfs_warning(inode->i_sb, "%s: deleting nonexistent file "
+				 "(%s:%lu), %d", __FUNCTION__,
+				 reiserfs_bdevname(inode->i_sb), inode->i_ino,
+				 inode->i_nlink);
+		inode->i_nlink = 1;
+	}
+
+	inode->i_nlink--;
+
+	/*
+	 * we schedule before doing the add_save_link call, save the link
+	 * count so we don't race
+	 */
+	savelink = inode->i_nlink;
+
+	retval =
+	    reiserfs_cut_from_item(&th, &path, &(de.de_entry_key), dir, NULL,
+				   0);
+	if (retval < 0) {
+		inode->i_nlink++;
+		goto end_unlink;
+	}
+	inode->i_ctime = CURRENT_TIME_SEC;
+	reiserfs_update_sd(&th, inode);
+
+	dir->i_size -= (de.de_entrylen + DEH_SIZE);
+	dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC;
+	reiserfs_update_sd(&th, dir);
+
+	if (!savelink)
+		/* prevent file from getting lost */
+		add_save_link(&th, inode, 0 /* not truncate */ );
+
+	retval = journal_end(&th, dir->i_sb, jbegin_count);
+	reiserfs_check_path(&path);
+	reiserfs_write_unlock(dir->i_sb);
+	return retval;
+
+      end_unlink:
+	pathrelse(&path);
+	err = journal_end(&th, dir->i_sb, jbegin_count);
+	reiserfs_check_path(&path);
+	if (err)
+		retval = err;
+      out_unlink:
+	reiserfs_write_unlock(dir->i_sb);
+	return retval;
 }
 
+static int reiserfs_symlink(struct inode *parent_dir,
+			    struct dentry *dentry, const char *symname)
+{
+	int retval;
+	struct inode *inode;
+	char *name;
+	int item_len;
+	struct reiserfs_transaction_handle th;
+	int mode = S_IFLNK | S_IRWXUGO;
+	/* We need blocks for transaction + (user+group)*(quotas for new inode + update of quota for directory owner) */
+	int jbegin_count =
+	    JOURNAL_PER_BALANCE_CNT * 3 +
+	    2 * (REISERFS_QUOTA_INIT_BLOCKS(parent_dir->i_sb) +
+		 REISERFS_QUOTA_TRANS_BLOCKS(parent_dir->i_sb));
+
+	if (!(inode = new_inode(parent_dir->i_sb))) {
+		return -ENOMEM;
+	}
+	new_inode_init(inode, parent_dir, mode);
+
+	reiserfs_write_lock(parent_dir->i_sb);
+	item_len = ROUND_UP(strlen(symname));
+	if (item_len > MAX_DIRECT_ITEM_LEN(parent_dir->i_sb->s_blocksize)) {
+		retval = -ENAMETOOLONG;
+		drop_new_inode(inode);
+		goto out_failed;
+	}
+
+	name = reiserfs_kmalloc(item_len, GFP_NOFS, parent_dir->i_sb);
+	if (!name) {
+		drop_new_inode(inode);
+		retval = -ENOMEM;
+		goto out_failed;
+	}
+	memcpy(name, symname, strlen(symname));
+	padd_item(name, item_len, strlen(symname));
+
+	/* We would inherit the default ACL here, but symlinks don't get ACLs */
+
+	retval = journal_begin(&th, parent_dir->i_sb, jbegin_count);
+	if (retval) {
+		drop_new_inode(inode);
+		reiserfs_kfree(name, item_len, parent_dir->i_sb);
+		goto out_failed;
+	}
+
+	retval =
+	    reiserfs_new_inode(&th, parent_dir, mode, name, strlen(symname),
+			       dentry, inode);
+	reiserfs_kfree(name, item_len, parent_dir->i_sb);
+	if (retval) {		/* reiserfs_new_inode iputs for us */
+		goto out_failed;
+	}
+
+	reiserfs_update_inode_transaction(inode);
+	reiserfs_update_inode_transaction(parent_dir);
+
+	inode->i_op = &reiserfs_symlink_inode_operations;
+	inode->i_mapping->a_ops = &reiserfs_address_space_operations;
 
-static int entry_points_to_object (const char * name, int len, struct reiserfs_dir_entry * de, struct inode * inode)
+	// must be sure this inode is written with this transaction
+	//
+	//reiserfs_update_sd (&th, inode, READ_BLOCKS);
+
+	retval = reiserfs_add_entry(&th, parent_dir, dentry->d_name.name,
+				    dentry->d_name.len, inode, 1 /*visible */ );
+	if (retval) {
+		int err;
+		inode->i_nlink--;
+		reiserfs_update_sd(&th, inode);
+		err = journal_end(&th, parent_dir->i_sb, jbegin_count);
+		if (err)
+			retval = err;
+		iput(inode);
+		goto out_failed;
+	}
+
+	d_instantiate(dentry, inode);
+	retval = journal_end(&th, parent_dir->i_sb, jbegin_count);
+      out_failed:
+	reiserfs_write_unlock(parent_dir->i_sb);
+	return retval;
+}
+
+static int reiserfs_link(struct dentry *old_dentry, struct inode *dir,
+			 struct dentry *dentry)
 {
-    if (!de_still_valid (name, len, de))
-	return 0;
+	int retval;
+	struct inode *inode = old_dentry->d_inode;
+	struct reiserfs_transaction_handle th;
+	/* We need blocks for transaction + update of quotas for the owners of the directory */
+	int jbegin_count =
+	    JOURNAL_PER_BALANCE_CNT * 3 +
+	    2 * REISERFS_QUOTA_TRANS_BLOCKS(dir->i_sb);
+
+	reiserfs_write_lock(dir->i_sb);
+	if (inode->i_nlink >= REISERFS_LINK_MAX) {
+		//FIXME: sd_nlink is 32 bit for new files
+		reiserfs_write_unlock(dir->i_sb);
+		return -EMLINK;
+	}
+	if (inode->i_nlink == 0) {
+		reiserfs_write_unlock(dir->i_sb);
+		return -ENOENT;
+	}
 
-    if (inode) {
-	if (!de_visible (de->de_deh + de->de_entry_num))
-	    reiserfs_panic (NULL, "vs-7042: entry_points_to_object: entry must be visible");
-	return (de->de_objectid == inode->i_ino) ? 1 : 0;
-    }
-
-    /* this must be added hidden entry */
-    if (de_visible (de->de_deh + de->de_entry_num))
-	reiserfs_panic (NULL, "vs-7043: entry_points_to_object: entry must be visible");
+	/* inc before scheduling so reiserfs_unlink knows we are here */
+	inode->i_nlink++;
+
+	retval = journal_begin(&th, dir->i_sb, jbegin_count);
+	if (retval) {
+		inode->i_nlink--;
+		reiserfs_write_unlock(dir->i_sb);
+		return retval;
+	}
 
-    return 1;
+	/* create new entry */
+	retval =
+	    reiserfs_add_entry(&th, dir, dentry->d_name.name,
+			       dentry->d_name.len, inode, 1 /*visible */ );
+
+	reiserfs_update_inode_transaction(inode);
+	reiserfs_update_inode_transaction(dir);
+
+	if (retval) {
+		int err;
+		inode->i_nlink--;
+		err = journal_end(&th, dir->i_sb, jbegin_count);
+		reiserfs_write_unlock(dir->i_sb);
+		return err ? err : retval;
+	}
+
+	inode->i_ctime = CURRENT_TIME_SEC;
+	reiserfs_update_sd(&th, inode);
+
+	atomic_inc(&inode->i_count);
+	d_instantiate(dentry, inode);
+	retval = journal_end(&th, dir->i_sb, jbegin_count);
+	reiserfs_write_unlock(dir->i_sb);
+	return retval;
 }
 
+// de contains information pointing to an entry which 
+static int de_still_valid(const char *name, int len,
+			  struct reiserfs_dir_entry *de)
+{
+	struct reiserfs_dir_entry tmp = *de;
+
+	// recalculate pointer to name and name length
+	set_de_name_and_namelen(&tmp);
+	// FIXME: could check more
+	if (tmp.de_namelen != len || memcmp(name, de->de_name, len))
+		return 0;
+	return 1;
+}
+
+static int entry_points_to_object(const char *name, int len,
+				  struct reiserfs_dir_entry *de,
+				  struct inode *inode)
+{
+	if (!de_still_valid(name, len, de))
+		return 0;
+
+	if (inode) {
+		if (!de_visible(de->de_deh + de->de_entry_num))
+			reiserfs_panic(NULL,
+				       "vs-7042: entry_points_to_object: entry must be visible");
+		return (de->de_objectid == inode->i_ino) ? 1 : 0;
+	}
+
+	/* this must be added hidden entry */
+	if (de_visible(de->de_deh + de->de_entry_num))
+		reiserfs_panic(NULL,
+			       "vs-7043: entry_points_to_object: entry must be visible");
+
+	return 1;
+}
 
 /* sets key of objectid the entry has to point to */
-static void set_ino_in_dir_entry (struct reiserfs_dir_entry * de, struct reiserfs_key * key)
+static void set_ino_in_dir_entry(struct reiserfs_dir_entry *de,
+				 struct reiserfs_key *key)
 {
-    /* JDM These operations are endian safe - both are le */
-    de->de_deh[de->de_entry_num].deh_dir_id = key->k_dir_id;
-    de->de_deh[de->de_entry_num].deh_objectid = key->k_objectid;
+	/* JDM These operations are endian safe - both are le */
+	de->de_deh[de->de_entry_num].deh_dir_id = key->k_dir_id;
+	de->de_deh[de->de_entry_num].deh_objectid = key->k_objectid;
 }
 
-
 /* 
  * process, that is going to call fix_nodes/do_balance must hold only
  * one path. If it holds 2 or more, it can get into endless waiting in
  * get_empty_nodes or its clones 
  */
-static int reiserfs_rename (struct inode * old_dir, struct dentry *old_dentry,
-			    struct inode * new_dir, struct dentry *new_dentry)
+static int reiserfs_rename(struct inode *old_dir, struct dentry *old_dentry,
+			   struct inode *new_dir, struct dentry *new_dentry)
 {
-    int retval;
-    INITIALIZE_PATH (old_entry_path);
-    INITIALIZE_PATH (new_entry_path);
-    INITIALIZE_PATH (dot_dot_entry_path);
-    struct item_head new_entry_ih, old_entry_ih, dot_dot_ih ;
-    struct reiserfs_dir_entry old_de, new_de, dot_dot_de;
-    struct inode * old_inode, * new_dentry_inode;
-    struct reiserfs_transaction_handle th ;
-    int jbegin_count ; 
-    umode_t old_inode_mode;
-    unsigned long savelink = 1;
-    struct timespec ctime;
-
-    /* three balancings: (1) old name removal, (2) new name insertion
-       and (3) maybe "save" link insertion
-       stat data updates: (1) old directory,
-       (2) new directory and (3) maybe old object stat data (when it is
-       directory) and (4) maybe stat data of object to which new entry
-       pointed initially and (5) maybe block containing ".." of
-       renamed directory
-       quota updates: two parent directories */
-    jbegin_count = JOURNAL_PER_BALANCE_CNT * 3 + 5 + 4 * REISERFS_QUOTA_TRANS_BLOCKS;
-
-    old_inode = old_dentry->d_inode;
-    new_dentry_inode = new_dentry->d_inode;
-
-    // make sure, that oldname still exists and points to an object we
-    // are going to rename
-    old_de.de_gen_number_bit_string = NULL;
-    reiserfs_write_lock(old_dir->i_sb);
-    retval = reiserfs_find_entry (old_dir, old_dentry->d_name.name, old_dentry->d_name.len,
-				  &old_entry_path, &old_de);
-    pathrelse (&old_entry_path);
-    if (retval == IO_ERROR) {
-	reiserfs_write_unlock(old_dir->i_sb);
-	return -EIO;
-    }
+	int retval;
+	INITIALIZE_PATH(old_entry_path);
+	INITIALIZE_PATH(new_entry_path);
+	INITIALIZE_PATH(dot_dot_entry_path);
+	struct item_head new_entry_ih, old_entry_ih, dot_dot_ih;
+	struct reiserfs_dir_entry old_de, new_de, dot_dot_de;
+	struct inode *old_inode, *new_dentry_inode;
+	struct reiserfs_transaction_handle th;
+	int jbegin_count;
+	umode_t old_inode_mode;
+	unsigned long savelink = 1;
+	struct timespec ctime;
+
+	/* three balancings: (1) old name removal, (2) new name insertion
+	   and (3) maybe "save" link insertion
+	   stat data updates: (1) old directory,
+	   (2) new directory and (3) maybe old object stat data (when it is
+	   directory) and (4) maybe stat data of object to which new entry
+	   pointed initially and (5) maybe block containing ".." of
+	   renamed directory
+	   quota updates: two parent directories */
+	jbegin_count =
+	    JOURNAL_PER_BALANCE_CNT * 3 + 5 +
+	    4 * REISERFS_QUOTA_TRANS_BLOCKS(old_dir->i_sb);
+
+	old_inode = old_dentry->d_inode;
+	new_dentry_inode = new_dentry->d_inode;
+
+	// make sure, that oldname still exists and points to an object we
+	// are going to rename
+	old_de.de_gen_number_bit_string = NULL;
+	reiserfs_write_lock(old_dir->i_sb);
+	retval =
+	    reiserfs_find_entry(old_dir, old_dentry->d_name.name,
+				old_dentry->d_name.len, &old_entry_path,
+				&old_de);
+	pathrelse(&old_entry_path);
+	if (retval == IO_ERROR) {
+		reiserfs_write_unlock(old_dir->i_sb);
+		return -EIO;
+	}
 
-    if (retval != NAME_FOUND || old_de.de_objectid != old_inode->i_ino) {
-	reiserfs_write_unlock(old_dir->i_sb);
-	return -ENOENT;
-    }
+	if (retval != NAME_FOUND || old_de.de_objectid != old_inode->i_ino) {
+		reiserfs_write_unlock(old_dir->i_sb);
+		return -ENOENT;
+	}
 
-    old_inode_mode = old_inode->i_mode;
-    if (S_ISDIR(old_inode_mode)) {
-	// make sure, that directory being renamed has correct ".." 
-	// and that its new parent directory has not too many links
-	// already
+	old_inode_mode = old_inode->i_mode;
+	if (S_ISDIR(old_inode_mode)) {
+		// make sure, that directory being renamed has correct ".." 
+		// and that its new parent directory has not too many links
+		// already
+
+		if (new_dentry_inode) {
+			if (!reiserfs_empty_dir(new_dentry_inode)) {
+				reiserfs_write_unlock(old_dir->i_sb);
+				return -ENOTEMPTY;
+			}
+		}
+
+		/* directory is renamed, its parent directory will be changed, 
+		 ** so find ".." entry 
+		 */
+		dot_dot_de.de_gen_number_bit_string = NULL;
+		retval =
+		    reiserfs_find_entry(old_inode, "..", 2, &dot_dot_entry_path,
+					&dot_dot_de);
+		pathrelse(&dot_dot_entry_path);
+		if (retval != NAME_FOUND) {
+			reiserfs_write_unlock(old_dir->i_sb);
+			return -EIO;
+		}
+
+		/* inode number of .. must equal old_dir->i_ino */
+		if (dot_dot_de.de_objectid != old_dir->i_ino) {
+			reiserfs_write_unlock(old_dir->i_sb);
+			return -EIO;
+		}
+	}
 
-	if (new_dentry_inode) {
-	    if (!reiserfs_empty_dir(new_dentry_inode)) {
+	retval = journal_begin(&th, old_dir->i_sb, jbegin_count);
+	if (retval) {
 		reiserfs_write_unlock(old_dir->i_sb);
-		return -ENOTEMPTY;
-	    }
+		return retval;
 	}
-	
-	/* directory is renamed, its parent directory will be changed, 
-	** so find ".." entry 
-	*/
-	dot_dot_de.de_gen_number_bit_string = NULL;
-	retval = reiserfs_find_entry (old_inode, "..", 2, &dot_dot_entry_path, &dot_dot_de);
-	pathrelse (&dot_dot_entry_path);
-	if (retval != NAME_FOUND) {
-	    reiserfs_write_unlock(old_dir->i_sb);
-	    return -EIO;
+
+	/* add new entry (or find the existing one) */
+	retval =
+	    reiserfs_add_entry(&th, new_dir, new_dentry->d_name.name,
+			       new_dentry->d_name.len, old_inode, 0);
+	if (retval == -EEXIST) {
+		if (!new_dentry_inode) {
+			reiserfs_panic(old_dir->i_sb,
+				       "vs-7050: new entry is found, new inode == 0\n");
+		}
+	} else if (retval) {
+		int err = journal_end(&th, old_dir->i_sb, jbegin_count);
+		reiserfs_write_unlock(old_dir->i_sb);
+		return err ? err : retval;
 	}
 
-	/* inode number of .. must equal old_dir->i_ino */
-	if (dot_dot_de.de_objectid != old_dir->i_ino) {
-	    reiserfs_write_unlock(old_dir->i_sb);
-	    return -EIO;
-	}
-    }
-
-    retval = journal_begin(&th, old_dir->i_sb, jbegin_count) ;
-    if (retval) {
-        reiserfs_write_unlock (old_dir->i_sb);
-        return retval;
-    }
-
-    /* add new entry (or find the existing one) */
-    retval = reiserfs_add_entry (&th, new_dir, new_dentry->d_name.name, new_dentry->d_name.len, 
-				 old_inode, 0);
-    if (retval == -EEXIST) {
-	if (!new_dentry_inode) {
-	    reiserfs_panic (old_dir->i_sb,
-			    "vs-7050: new entry is found, new inode == 0\n");
+	reiserfs_update_inode_transaction(old_dir);
+	reiserfs_update_inode_transaction(new_dir);
+
+	/* this makes it so an fsync on an open fd for the old name will
+	 ** commit the rename operation
+	 */
+	reiserfs_update_inode_transaction(old_inode);
+
+	if (new_dentry_inode)
+		reiserfs_update_inode_transaction(new_dentry_inode);
+
+	while (1) {
+		// look for old name using corresponding entry key (found by reiserfs_find_entry)
+		if ((retval =
+		     search_by_entry_key(new_dir->i_sb, &old_de.de_entry_key,
+					 &old_entry_path,
+					 &old_de)) != NAME_FOUND) {
+			pathrelse(&old_entry_path);
+			journal_end(&th, old_dir->i_sb, jbegin_count);
+			reiserfs_write_unlock(old_dir->i_sb);
+			return -EIO;
+		}
+
+		copy_item_head(&old_entry_ih, get_ih(&old_entry_path));
+
+		reiserfs_prepare_for_journal(old_inode->i_sb, old_de.de_bh, 1);
+
+		// look for new name by reiserfs_find_entry
+		new_de.de_gen_number_bit_string = NULL;
+		retval =
+		    reiserfs_find_entry(new_dir, new_dentry->d_name.name,
+					new_dentry->d_name.len, &new_entry_path,
+					&new_de);
+		// reiserfs_add_entry should not return IO_ERROR, because it is called with essentially same parameters from
+		// reiserfs_add_entry above, and we'll catch any i/o errors before we get here.
+		if (retval != NAME_FOUND_INVISIBLE && retval != NAME_FOUND) {
+			pathrelse(&new_entry_path);
+			pathrelse(&old_entry_path);
+			journal_end(&th, old_dir->i_sb, jbegin_count);
+			reiserfs_write_unlock(old_dir->i_sb);
+			return -EIO;
+		}
+
+		copy_item_head(&new_entry_ih, get_ih(&new_entry_path));
+
+		reiserfs_prepare_for_journal(old_inode->i_sb, new_de.de_bh, 1);
+
+		if (S_ISDIR(old_inode->i_mode)) {
+			if ((retval =
+			     search_by_entry_key(new_dir->i_sb,
+						 &dot_dot_de.de_entry_key,
+						 &dot_dot_entry_path,
+						 &dot_dot_de)) != NAME_FOUND) {
+				pathrelse(&dot_dot_entry_path);
+				pathrelse(&new_entry_path);
+				pathrelse(&old_entry_path);
+				journal_end(&th, old_dir->i_sb, jbegin_count);
+				reiserfs_write_unlock(old_dir->i_sb);
+				return -EIO;
+			}
+			copy_item_head(&dot_dot_ih,
+				       get_ih(&dot_dot_entry_path));
+			// node containing ".." gets into transaction
+			reiserfs_prepare_for_journal(old_inode->i_sb,
+						     dot_dot_de.de_bh, 1);
+		}
+		/* we should check seals here, not do
+		   this stuff, yes? Then, having
+		   gathered everything into RAM we
+		   should lock the buffers, yes?  -Hans */
+		/* probably.  our rename needs to hold more 
+		 ** than one path at once.  The seals would 
+		 ** have to be written to deal with multi-path 
+		 ** issues -chris
+		 */
+		/* sanity checking before doing the rename - avoid races many
+		 ** of the above checks could have scheduled.  We have to be
+		 ** sure our items haven't been shifted by another process.
+		 */
+		if (item_moved(&new_entry_ih, &new_entry_path) ||
+		    !entry_points_to_object(new_dentry->d_name.name,
+					    new_dentry->d_name.len,
+					    &new_de, new_dentry_inode) ||
+		    item_moved(&old_entry_ih, &old_entry_path) ||
+		    !entry_points_to_object(old_dentry->d_name.name,
+					    old_dentry->d_name.len,
+					    &old_de, old_inode)) {
+			reiserfs_restore_prepared_buffer(old_inode->i_sb,
+							 new_de.de_bh);
+			reiserfs_restore_prepared_buffer(old_inode->i_sb,
+							 old_de.de_bh);
+			if (S_ISDIR(old_inode_mode))
+				reiserfs_restore_prepared_buffer(old_inode->
+								 i_sb,
+								 dot_dot_de.
+								 de_bh);
+			continue;
+		}
+		if (S_ISDIR(old_inode_mode)) {
+			if (item_moved(&dot_dot_ih, &dot_dot_entry_path) ||
+			    !entry_points_to_object("..", 2, &dot_dot_de,
+						    old_dir)) {
+				reiserfs_restore_prepared_buffer(old_inode->
+								 i_sb,
+								 old_de.de_bh);
+				reiserfs_restore_prepared_buffer(old_inode->
+								 i_sb,
+								 new_de.de_bh);
+				reiserfs_restore_prepared_buffer(old_inode->
+								 i_sb,
+								 dot_dot_de.
+								 de_bh);
+				continue;
+			}
+		}
+
+		RFALSE(S_ISDIR(old_inode_mode) &&
+		       !buffer_journal_prepared(dot_dot_de.de_bh), "");
+
+		break;
 	}
-    } else if (retval) {
-	int err = journal_end(&th, old_dir->i_sb, jbegin_count) ;
-	reiserfs_write_unlock(old_dir->i_sb);
-	return err ? err : retval;
-    }
 
-    reiserfs_update_inode_transaction(old_dir) ;
-    reiserfs_update_inode_transaction(new_dir) ;
+	/* ok, all the changes can be done in one fell swoop when we
+	   have claimed all the buffers needed. */
 
-    /* this makes it so an fsync on an open fd for the old name will
-    ** commit the rename operation
-    */
-    reiserfs_update_inode_transaction(old_inode) ;
-
-    if (new_dentry_inode) 
-	reiserfs_update_inode_transaction(new_dentry_inode) ;
-
-    while (1) {
-	// look for old name using corresponding entry key (found by reiserfs_find_entry)
-	if ((retval = search_by_entry_key (new_dir->i_sb, &old_de.de_entry_key,
-					   &old_entry_path, &old_de)) != NAME_FOUND) {
-	    pathrelse(&old_entry_path);
-	    journal_end(&th, old_dir->i_sb, jbegin_count);
-	    reiserfs_write_unlock(old_dir->i_sb);
-	    return -EIO;
-	}
-
-	copy_item_head(&old_entry_ih, get_ih(&old_entry_path)) ;
-
-	reiserfs_prepare_for_journal(old_inode->i_sb, old_de.de_bh, 1) ;
-
-	// look for new name by reiserfs_find_entry
-	new_de.de_gen_number_bit_string = NULL;
-	retval = reiserfs_find_entry (new_dir, new_dentry->d_name.name, new_dentry->d_name.len, 
-				      &new_entry_path, &new_de);
-	// reiserfs_add_entry should not return IO_ERROR, because it is called with essentially same parameters from
-        // reiserfs_add_entry above, and we'll catch any i/o errors before we get here.
-	if (retval != NAME_FOUND_INVISIBLE && retval != NAME_FOUND) {
-	    pathrelse(&new_entry_path);
-	    pathrelse(&old_entry_path);
-	    journal_end(&th, old_dir->i_sb, jbegin_count);
-	    reiserfs_write_unlock(old_dir->i_sb);
-	    return -EIO;
-	}
-
-	copy_item_head(&new_entry_ih, get_ih(&new_entry_path)) ;
-
-	reiserfs_prepare_for_journal(old_inode->i_sb, new_de.de_bh, 1) ;
-
-	if (S_ISDIR(old_inode->i_mode)) {
-	    if ((retval = search_by_entry_key (new_dir->i_sb, &dot_dot_de.de_entry_key,
-					       &dot_dot_entry_path, &dot_dot_de)) != NAME_FOUND) {
-		pathrelse(&dot_dot_entry_path);
-		pathrelse(&new_entry_path);
-		pathrelse(&old_entry_path);
-		journal_end(&th, old_dir->i_sb, jbegin_count);
-		reiserfs_write_unlock(old_dir->i_sb);
-		return -EIO;
-	    }
-	    copy_item_head(&dot_dot_ih, get_ih(&dot_dot_entry_path)) ;
-	    // node containing ".." gets into transaction
-	    reiserfs_prepare_for_journal(old_inode->i_sb, dot_dot_de.de_bh, 1) ;
-	}
-				/* we should check seals here, not do
-                                   this stuff, yes? Then, having
-                                   gathered everything into RAM we
-                                   should lock the buffers, yes?  -Hans */
-				/* probably.  our rename needs to hold more 
-				** than one path at once.  The seals would 
-				** have to be written to deal with multi-path 
-				** issues -chris
-				*/
-	/* sanity checking before doing the rename - avoid races many
-	** of the above checks could have scheduled.  We have to be
-	** sure our items haven't been shifted by another process.
-	*/
-	if (item_moved(&new_entry_ih, &new_entry_path) ||
-	    !entry_points_to_object(new_dentry->d_name.name, 
-	                            new_dentry->d_name.len,
-				    &new_de, new_dentry_inode) ||
-	    item_moved(&old_entry_ih, &old_entry_path) || 
-	    !entry_points_to_object (old_dentry->d_name.name, 
-	                             old_dentry->d_name.len,
-				     &old_de, old_inode)) {
-	    reiserfs_restore_prepared_buffer (old_inode->i_sb, new_de.de_bh);
-	    reiserfs_restore_prepared_buffer (old_inode->i_sb, old_de.de_bh);
-	    if (S_ISDIR(old_inode_mode))
-		reiserfs_restore_prepared_buffer (old_inode->i_sb, dot_dot_de.de_bh);
-	    continue;
+	mark_de_visible(new_de.de_deh + new_de.de_entry_num);
+	set_ino_in_dir_entry(&new_de, INODE_PKEY(old_inode));
+	journal_mark_dirty(&th, old_dir->i_sb, new_de.de_bh);
+
+	mark_de_hidden(old_de.de_deh + old_de.de_entry_num);
+	journal_mark_dirty(&th, old_dir->i_sb, old_de.de_bh);
+	ctime = CURRENT_TIME_SEC;
+	old_dir->i_ctime = old_dir->i_mtime = ctime;
+	new_dir->i_ctime = new_dir->i_mtime = ctime;
+	/* thanks to Alex Adriaanse <alex_a@caltech.edu> for patch which adds ctime update of
+	   renamed object */
+	old_inode->i_ctime = ctime;
+
+	if (new_dentry_inode) {
+		// adjust link number of the victim
+		if (S_ISDIR(new_dentry_inode->i_mode)) {
+			new_dentry_inode->i_nlink = 0;
+		} else {
+			new_dentry_inode->i_nlink--;
+		}
+		new_dentry_inode->i_ctime = ctime;
+		savelink = new_dentry_inode->i_nlink;
 	}
+
 	if (S_ISDIR(old_inode_mode)) {
-	    if ( item_moved(&dot_dot_ih, &dot_dot_entry_path) ||
-		!entry_points_to_object ( "..", 2, &dot_dot_de, old_dir) ) {
-		reiserfs_restore_prepared_buffer (old_inode->i_sb, old_de.de_bh);
-		reiserfs_restore_prepared_buffer (old_inode->i_sb, new_de.de_bh);
-		reiserfs_restore_prepared_buffer (old_inode->i_sb, dot_dot_de.de_bh);
-		continue;
-	    }
-	}
-
-	RFALSE( S_ISDIR(old_inode_mode) && 
-		 !buffer_journal_prepared(dot_dot_de.de_bh), "" );
-
-	break;
-    }
-
-    /* ok, all the changes can be done in one fell swoop when we
-       have claimed all the buffers needed.*/
-    
-    mark_de_visible (new_de.de_deh + new_de.de_entry_num);
-    set_ino_in_dir_entry (&new_de, INODE_PKEY (old_inode));
-    journal_mark_dirty (&th, old_dir->i_sb, new_de.de_bh);
-
-    mark_de_hidden (old_de.de_deh + old_de.de_entry_num);
-    journal_mark_dirty (&th, old_dir->i_sb, old_de.de_bh);
-    ctime = CURRENT_TIME_SEC;
-    old_dir->i_ctime = old_dir->i_mtime = ctime;
-    new_dir->i_ctime = new_dir->i_mtime = ctime;
-    /* thanks to Alex Adriaanse <alex_a@caltech.edu> for patch which adds ctime update of
-       renamed object */
-    old_inode->i_ctime = ctime;
-
-    if (new_dentry_inode) {
-	// adjust link number of the victim
-	if (S_ISDIR(new_dentry_inode->i_mode)) {
-	    new_dentry_inode->i_nlink  = 0;
-	} else {
-	    new_dentry_inode->i_nlink--;
+		// adjust ".." of renamed directory 
+		set_ino_in_dir_entry(&dot_dot_de, INODE_PKEY(new_dir));
+		journal_mark_dirty(&th, new_dir->i_sb, dot_dot_de.de_bh);
+
+		if (!new_dentry_inode)
+			/* there (in new_dir) was no directory, so it got new link
+			   (".."  of renamed directory) */
+			INC_DIR_INODE_NLINK(new_dir);
+
+		/* old directory lost one link - ".. " of renamed directory */
+		DEC_DIR_INODE_NLINK(old_dir);
 	}
-	new_dentry_inode->i_ctime = ctime;
-	savelink = new_dentry_inode->i_nlink;
-    }
-
-    if (S_ISDIR(old_inode_mode)) {
-	// adjust ".." of renamed directory 
-	set_ino_in_dir_entry (&dot_dot_de, INODE_PKEY (new_dir));
-	journal_mark_dirty (&th, new_dir->i_sb, dot_dot_de.de_bh);
-	
-        if (!new_dentry_inode)
-	    /* there (in new_dir) was no directory, so it got new link
-	       (".."  of renamed directory) */
-	    INC_DIR_INODE_NLINK(new_dir);
-		
-	/* old directory lost one link - ".. " of renamed directory */
-	DEC_DIR_INODE_NLINK(old_dir);
-    }
-
-    // looks like in 2.3.99pre3 brelse is atomic. so we can use pathrelse
-    pathrelse (&new_entry_path);
-    pathrelse (&dot_dot_entry_path);
-
-    // FIXME: this reiserfs_cut_from_item's return value may screw up
-    // anybody, but it will panic if will not be able to find the
-    // entry. This needs one more clean up
-    if (reiserfs_cut_from_item (&th, &old_entry_path, &(old_de.de_entry_key), old_dir, NULL, 0) < 0)
-	reiserfs_warning (old_dir->i_sb, "vs-7060: reiserfs_rename: couldn't not cut old name. Fsck later?");
-
-    old_dir->i_size -= DEH_SIZE + old_de.de_entrylen;
-
-    reiserfs_update_sd (&th, old_dir);
-    reiserfs_update_sd (&th, new_dir);
-    reiserfs_update_sd (&th, old_inode);
-
-    if (new_dentry_inode) {
-	if (savelink == 0)
-	    add_save_link (&th, new_dentry_inode, 0/* not truncate */);
-	reiserfs_update_sd (&th, new_dentry_inode);
-    }
-
-    retval = journal_end(&th, old_dir->i_sb, jbegin_count) ;
-    reiserfs_write_unlock(old_dir->i_sb);
-    return retval;
+	// looks like in 2.3.99pre3 brelse is atomic. so we can use pathrelse
+	pathrelse(&new_entry_path);
+	pathrelse(&dot_dot_entry_path);
+
+	// FIXME: this reiserfs_cut_from_item's return value may screw up
+	// anybody, but it will panic if will not be able to find the
+	// entry. This needs one more clean up
+	if (reiserfs_cut_from_item
+	    (&th, &old_entry_path, &(old_de.de_entry_key), old_dir, NULL,
+	     0) < 0)
+		reiserfs_warning(old_dir->i_sb,
+				 "vs-7060: reiserfs_rename: couldn't not cut old name. Fsck later?");
+
+	old_dir->i_size -= DEH_SIZE + old_de.de_entrylen;
+
+	reiserfs_update_sd(&th, old_dir);
+	reiserfs_update_sd(&th, new_dir);
+	reiserfs_update_sd(&th, old_inode);
+
+	if (new_dentry_inode) {
+		if (savelink == 0)
+			add_save_link(&th, new_dentry_inode,
+				      0 /* not truncate */ );
+		reiserfs_update_sd(&th, new_dentry_inode);
+	}
+
+	retval = journal_end(&th, old_dir->i_sb, jbegin_count);
+	reiserfs_write_unlock(old_dir->i_sb);
+	return retval;
 }
 
 /*
  * directories can handle most operations...
  */
 struct inode_operations reiserfs_dir_inode_operations = {
-  //&reiserfs_dir_operations,	/* default_file_ops */
-    .create	= reiserfs_create,
-    .lookup	= reiserfs_lookup,
-    .link	= reiserfs_link,
-    .unlink	= reiserfs_unlink,
-    .symlink	= reiserfs_symlink,
-    .mkdir	= reiserfs_mkdir,
-    .rmdir	= reiserfs_rmdir,
-    .mknod	= reiserfs_mknod,
-    .rename	= reiserfs_rename,
-    .setattr    = reiserfs_setattr,
-    .setxattr   = reiserfs_setxattr,
-    .getxattr   = reiserfs_getxattr,
-    .listxattr  = reiserfs_listxattr,
-    .removexattr = reiserfs_removexattr,
-    .permission     = reiserfs_permission,
+	//&reiserfs_dir_operations,   /* default_file_ops */
+	.create = reiserfs_create,
+	.lookup = reiserfs_lookup,
+	.link = reiserfs_link,
+	.unlink = reiserfs_unlink,
+	.symlink = reiserfs_symlink,
+	.mkdir = reiserfs_mkdir,
+	.rmdir = reiserfs_rmdir,
+	.mknod = reiserfs_mknod,
+	.rename = reiserfs_rename,
+	.setattr = reiserfs_setattr,
+	.setxattr = reiserfs_setxattr,
+	.getxattr = reiserfs_getxattr,
+	.listxattr = reiserfs_listxattr,
+	.removexattr = reiserfs_removexattr,
+	.permission = reiserfs_permission,
 };
 
 /*
@@ -1464,28 +1557,27 @@ struct inode_operations reiserfs_dir_ino
  * stuff added
  */
 struct inode_operations reiserfs_symlink_inode_operations = {
-    .readlink       = generic_readlink,
-    .follow_link    = page_follow_link_light,
-    .put_link       = page_put_link,
-    .setattr        = reiserfs_setattr,
-    .setxattr       = reiserfs_setxattr,
-    .getxattr       = reiserfs_getxattr,
-    .listxattr      = reiserfs_listxattr,
-    .removexattr    = reiserfs_removexattr,
-    .permission     = reiserfs_permission,
+	.readlink = generic_readlink,
+	.follow_link = page_follow_link_light,
+	.put_link = page_put_link,
+	.setattr = reiserfs_setattr,
+	.setxattr = reiserfs_setxattr,
+	.getxattr = reiserfs_getxattr,
+	.listxattr = reiserfs_listxattr,
+	.removexattr = reiserfs_removexattr,
+	.permission = reiserfs_permission,
 
 };
 
-
 /*
  * special file operations.. just xattr/acl stuff
  */
 struct inode_operations reiserfs_special_inode_operations = {
-    .setattr        = reiserfs_setattr,
-    .setxattr       = reiserfs_setxattr,
-    .getxattr       = reiserfs_getxattr,
-    .listxattr      = reiserfs_listxattr,
-    .removexattr    = reiserfs_removexattr,
-    .permission     = reiserfs_permission,
+	.setattr = reiserfs_setattr,
+	.setxattr = reiserfs_setxattr,
+	.getxattr = reiserfs_getxattr,
+	.listxattr = reiserfs_listxattr,
+	.removexattr = reiserfs_removexattr,
+	.permission = reiserfs_permission,
 
 };
diff --git a/fs/reiserfs/objectid.c b/fs/reiserfs/objectid.c
--- a/fs/reiserfs/objectid.c
+++ b/fs/reiserfs/objectid.c
@@ -14,24 +14,24 @@
                          (__le32 *)((struct reiserfs_super_block_v1 *)(rs) + 1) :\
 			 (__le32 *)((rs) + 1))
 
-
 #ifdef CONFIG_REISERFS_CHECK
 
-static void check_objectid_map (struct super_block * s, __le32 * map)
+static void check_objectid_map(struct super_block *s, __le32 * map)
 {
-    if (le32_to_cpu (map[0]) != 1)
-	reiserfs_panic (s, "vs-15010: check_objectid_map: map corrupted: %lx",
-			( long unsigned int ) le32_to_cpu (map[0]));
+	if (le32_to_cpu(map[0]) != 1)
+		reiserfs_panic(s,
+			       "vs-15010: check_objectid_map: map corrupted: %lx",
+			       (long unsigned int)le32_to_cpu(map[0]));
 
-    // FIXME: add something else here
+	// FIXME: add something else here
 }
 
 #else
-static void check_objectid_map (struct super_block * s, __le32 * map)
-{;}
+static void check_objectid_map(struct super_block *s, __le32 * map)
+{;
+}
 #endif
 
-
 /* When we allocate objectids we allocate the first unused objectid.
    Each sequence of objectids in use (the odd sequences) is followed
    by a sequence of objectids not in use (the even sequences).  We
@@ -46,161 +46,162 @@ static void check_objectid_map (struct s
    interesting optimizations of layout could result from complicating
    objectid assignment, but we have deferred making them for now. */
 
-
 /* get unique object identifier */
-__u32 reiserfs_get_unused_objectid (struct reiserfs_transaction_handle *th)
+__u32 reiserfs_get_unused_objectid(struct reiserfs_transaction_handle *th)
 {
-    struct super_block * s = th->t_super;
-    struct reiserfs_super_block * rs = SB_DISK_SUPER_BLOCK (s);
-    __le32 * map = objectid_map (s, rs);
-    __u32 unused_objectid;
-
-    BUG_ON (!th->t_trans_id);
-
-    check_objectid_map (s, map);
-
-    reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1) ;
-                                /* comment needed -Hans */
-    unused_objectid = le32_to_cpu (map[1]);
-    if (unused_objectid == U32_MAX) {
-	reiserfs_warning (s, "%s: no more object ids", __FUNCTION__);
-	reiserfs_restore_prepared_buffer(s, SB_BUFFER_WITH_SB(s)) ;
-	return 0;
-    }
+	struct super_block *s = th->t_super;
+	struct reiserfs_super_block *rs = SB_DISK_SUPER_BLOCK(s);
+	__le32 *map = objectid_map(s, rs);
+	__u32 unused_objectid;
+
+	BUG_ON(!th->t_trans_id);
+
+	check_objectid_map(s, map);
+
+	reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1);
+	/* comment needed -Hans */
+	unused_objectid = le32_to_cpu(map[1]);
+	if (unused_objectid == U32_MAX) {
+		reiserfs_warning(s, "%s: no more object ids", __FUNCTION__);
+		reiserfs_restore_prepared_buffer(s, SB_BUFFER_WITH_SB(s));
+		return 0;
+	}
 
-    /* This incrementation allocates the first unused objectid. That
-       is to say, the first entry on the objectid map is the first
-       unused objectid, and by incrementing it we use it.  See below
-       where we check to see if we eliminated a sequence of unused
-       objectids.... */
-    map[1] = cpu_to_le32 (unused_objectid + 1);
-
-    /* Now we check to see if we eliminated the last remaining member of
-       the first even sequence (and can eliminate the sequence by
-       eliminating its last objectid from oids), and can collapse the
-       first two odd sequences into one sequence.  If so, then the net
-       result is to eliminate a pair of objectids from oids.  We do this
-       by shifting the entire map to the left. */
-    if (sb_oid_cursize(rs) > 2 && map[1] == map[2]) {
-	memmove (map + 1, map + 3, (sb_oid_cursize(rs) - 3) * sizeof(__u32));
-        set_sb_oid_cursize( rs, sb_oid_cursize(rs) - 2 );
-    }
+	/* This incrementation allocates the first unused objectid. That
+	   is to say, the first entry on the objectid map is the first
+	   unused objectid, and by incrementing it we use it.  See below
+	   where we check to see if we eliminated a sequence of unused
+	   objectids.... */
+	map[1] = cpu_to_le32(unused_objectid + 1);
+
+	/* Now we check to see if we eliminated the last remaining member of
+	   the first even sequence (and can eliminate the sequence by
+	   eliminating its last objectid from oids), and can collapse the
+	   first two odd sequences into one sequence.  If so, then the net
+	   result is to eliminate a pair of objectids from oids.  We do this
+	   by shifting the entire map to the left. */
+	if (sb_oid_cursize(rs) > 2 && map[1] == map[2]) {
+		memmove(map + 1, map + 3,
+			(sb_oid_cursize(rs) - 3) * sizeof(__u32));
+		set_sb_oid_cursize(rs, sb_oid_cursize(rs) - 2);
+	}
 
-    journal_mark_dirty(th, s, SB_BUFFER_WITH_SB (s));
-    return unused_objectid;
+	journal_mark_dirty(th, s, SB_BUFFER_WITH_SB(s));
+	return unused_objectid;
 }
 
-
 /* makes object identifier unused */
-void reiserfs_release_objectid (struct reiserfs_transaction_handle *th, 
-				__u32 objectid_to_release)
+void reiserfs_release_objectid(struct reiserfs_transaction_handle *th,
+			       __u32 objectid_to_release)
 {
-    struct super_block * s = th->t_super;
-    struct reiserfs_super_block * rs = SB_DISK_SUPER_BLOCK (s);
-    __le32 * map = objectid_map (s, rs);
-    int i = 0;
-
-    BUG_ON (!th->t_trans_id);
-    //return;
-    check_objectid_map (s, map);
-
-    reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1) ;
-    journal_mark_dirty(th, s, SB_BUFFER_WITH_SB (s)); 
-
-    /* start at the beginning of the objectid map (i = 0) and go to
-       the end of it (i = disk_sb->s_oid_cursize).  Linear search is
-       what we use, though it is possible that binary search would be
-       more efficient after performing lots of deletions (which is
-       when oids is large.)  We only check even i's. */
-    while (i < sb_oid_cursize(rs)) {
-	if (objectid_to_release == le32_to_cpu (map[i])) {
-	    /* This incrementation unallocates the objectid. */
-	    //map[i]++;
-	    map[i] = cpu_to_le32 (le32_to_cpu (map[i]) + 1);
-
-	    /* Did we unallocate the last member of an odd sequence, and can shrink oids? */
-	    if (map[i] == map[i+1]) {
-		/* shrink objectid map */
-		memmove (map + i, map + i + 2, 
-			 (sb_oid_cursize(rs) - i - 2) * sizeof (__u32));
-		//disk_sb->s_oid_cursize -= 2;
-                set_sb_oid_cursize( rs, sb_oid_cursize(rs) - 2 );
-
-		RFALSE( sb_oid_cursize(rs) < 2 || 
-		        sb_oid_cursize(rs) > sb_oid_maxsize(rs),
-		        "vs-15005: objectid map corrupted cur_size == %d (max == %d)",
-                        sb_oid_cursize(rs), sb_oid_maxsize(rs));
-	    }
-	    return;
+	struct super_block *s = th->t_super;
+	struct reiserfs_super_block *rs = SB_DISK_SUPER_BLOCK(s);
+	__le32 *map = objectid_map(s, rs);
+	int i = 0;
+
+	BUG_ON(!th->t_trans_id);
+	//return;
+	check_objectid_map(s, map);
+
+	reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1);
+	journal_mark_dirty(th, s, SB_BUFFER_WITH_SB(s));
+
+	/* start at the beginning of the objectid map (i = 0) and go to
+	   the end of it (i = disk_sb->s_oid_cursize).  Linear search is
+	   what we use, though it is possible that binary search would be
+	   more efficient after performing lots of deletions (which is
+	   when oids is large.)  We only check even i's. */
+	while (i < sb_oid_cursize(rs)) {
+		if (objectid_to_release == le32_to_cpu(map[i])) {
+			/* This incrementation unallocates the objectid. */
+			//map[i]++;
+			map[i] = cpu_to_le32(le32_to_cpu(map[i]) + 1);
+
+			/* Did we unallocate the last member of an odd sequence, and can shrink oids? */
+			if (map[i] == map[i + 1]) {
+				/* shrink objectid map */
+				memmove(map + i, map + i + 2,
+					(sb_oid_cursize(rs) - i -
+					 2) * sizeof(__u32));
+				//disk_sb->s_oid_cursize -= 2;
+				set_sb_oid_cursize(rs, sb_oid_cursize(rs) - 2);
+
+				RFALSE(sb_oid_cursize(rs) < 2 ||
+				       sb_oid_cursize(rs) > sb_oid_maxsize(rs),
+				       "vs-15005: objectid map corrupted cur_size == %d (max == %d)",
+				       sb_oid_cursize(rs), sb_oid_maxsize(rs));
+			}
+			return;
+		}
+
+		if (objectid_to_release > le32_to_cpu(map[i]) &&
+		    objectid_to_release < le32_to_cpu(map[i + 1])) {
+			/* size of objectid map is not changed */
+			if (objectid_to_release + 1 == le32_to_cpu(map[i + 1])) {
+				//objectid_map[i+1]--;
+				map[i + 1] =
+				    cpu_to_le32(le32_to_cpu(map[i + 1]) - 1);
+				return;
+			}
+
+			/* JDM comparing two little-endian values for equality -- safe */
+			if (sb_oid_cursize(rs) == sb_oid_maxsize(rs)) {
+				/* objectid map must be expanded, but there is no space */
+				PROC_INFO_INC(s, leaked_oid);
+				return;
+			}
+
+			/* expand the objectid map */
+			memmove(map + i + 3, map + i + 1,
+				(sb_oid_cursize(rs) - i - 1) * sizeof(__u32));
+			map[i + 1] = cpu_to_le32(objectid_to_release);
+			map[i + 2] = cpu_to_le32(objectid_to_release + 1);
+			set_sb_oid_cursize(rs, sb_oid_cursize(rs) + 2);
+			return;
+		}
+		i += 2;
 	}
 
-	if (objectid_to_release > le32_to_cpu (map[i]) && 
-	    objectid_to_release < le32_to_cpu (map[i + 1])) {
-	    /* size of objectid map is not changed */
-	    if (objectid_to_release + 1 == le32_to_cpu (map[i + 1])) {
-		//objectid_map[i+1]--;
-		map[i + 1] = cpu_to_le32 (le32_to_cpu (map[i + 1]) - 1);
-		return;
-	    }
-
-            /* JDM comparing two little-endian values for equality -- safe */
-	if (sb_oid_cursize(rs) == sb_oid_maxsize(rs)) {
-		/* objectid map must be expanded, but there is no space */
-		PROC_INFO_INC( s, leaked_oid );
-		return;
-	}
+	reiserfs_warning(s,
+			 "vs-15011: reiserfs_release_objectid: tried to free free object id (%lu)",
+			 (long unsigned)objectid_to_release);
+}
 
-	    /* expand the objectid map*/
-	    memmove (map + i + 3, map + i + 1, 
-		     (sb_oid_cursize(rs) - i - 1) * sizeof(__u32));
-	    map[i + 1] = cpu_to_le32 (objectid_to_release);
-	    map[i + 2] = cpu_to_le32 (objectid_to_release + 1);
-            set_sb_oid_cursize( rs, sb_oid_cursize(rs) + 2 );
-	    return;
+int reiserfs_convert_objectid_map_v1(struct super_block *s)
+{
+	struct reiserfs_super_block *disk_sb = SB_DISK_SUPER_BLOCK(s);
+	int cur_size = sb_oid_cursize(disk_sb);
+	int new_size = (s->s_blocksize - SB_SIZE) / sizeof(__u32) / 2 * 2;
+	int old_max = sb_oid_maxsize(disk_sb);
+	struct reiserfs_super_block_v1 *disk_sb_v1;
+	__le32 *objectid_map, *new_objectid_map;
+	int i;
+
+	disk_sb_v1 =
+	    (struct reiserfs_super_block_v1 *)(SB_BUFFER_WITH_SB(s)->b_data);
+	objectid_map = (__le32 *) (disk_sb_v1 + 1);
+	new_objectid_map = (__le32 *) (disk_sb + 1);
+
+	if (cur_size > new_size) {
+		/* mark everyone used that was listed as free at the end of the objectid
+		 ** map 
+		 */
+		objectid_map[new_size - 1] = objectid_map[cur_size - 1];
+		set_sb_oid_cursize(disk_sb, new_size);
+	}
+	/* move the smaller objectid map past the end of the new super */
+	for (i = new_size - 1; i >= 0; i--) {
+		objectid_map[i + (old_max - new_size)] = objectid_map[i];
 	}
-	i += 2;
-    }
 
-    reiserfs_warning (s, "vs-15011: reiserfs_release_objectid: tried to free free object id (%lu)",
-		      ( long unsigned ) objectid_to_release);
-}
+	/* set the max size so we don't overflow later */
+	set_sb_oid_maxsize(disk_sb, new_size);
 
+	/* Zero out label and generate random UUID */
+	memset(disk_sb->s_label, 0, sizeof(disk_sb->s_label));
+	generate_random_uuid(disk_sb->s_uuid);
 
-int reiserfs_convert_objectid_map_v1(struct super_block *s) {
-    struct reiserfs_super_block *disk_sb = SB_DISK_SUPER_BLOCK (s);
-    int cur_size = sb_oid_cursize(disk_sb);
-    int new_size = (s->s_blocksize - SB_SIZE) / sizeof(__u32) / 2 * 2 ;
-    int old_max = sb_oid_maxsize(disk_sb);
-    struct reiserfs_super_block_v1 *disk_sb_v1 ;
-    __le32 *objectid_map, *new_objectid_map ;
-    int i ;
-
-    disk_sb_v1=(struct reiserfs_super_block_v1 *)(SB_BUFFER_WITH_SB(s)->b_data);
-    objectid_map = (__le32 *)(disk_sb_v1 + 1) ;
-    new_objectid_map = (__le32 *)(disk_sb + 1) ;
-
-    if (cur_size > new_size) {
-	/* mark everyone used that was listed as free at the end of the objectid
-	** map 
-	*/
-	objectid_map[new_size - 1] = objectid_map[cur_size - 1] ;
-	set_sb_oid_cursize(disk_sb,new_size) ;
-    }
-    /* move the smaller objectid map past the end of the new super */
-    for (i = new_size - 1 ; i >= 0 ; i--) {
-        objectid_map[i + (old_max - new_size)] = objectid_map[i] ; 
-    }
-
-
-    /* set the max size so we don't overflow later */
-    set_sb_oid_maxsize(disk_sb,new_size) ;
-
-    /* Zero out label and generate random UUID */
-    memset(disk_sb->s_label, 0, sizeof(disk_sb->s_label)) ;
-    generate_random_uuid(disk_sb->s_uuid);
-
-    /* finally, zero out the unused chunk of the new super */
-    memset(disk_sb->s_unused, 0, sizeof(disk_sb->s_unused)) ;
-    return 0 ;
+	/* finally, zero out the unused chunk of the new super */
+	memset(disk_sb->s_unused, 0, sizeof(disk_sb->s_unused));
+	return 0;
 }
-
diff --git a/fs/reiserfs/prints.c b/fs/reiserfs/prints.c
--- a/fs/reiserfs/prints.c
+++ b/fs/reiserfs/prints.c
@@ -15,168 +15,166 @@ static char error_buf[1024];
 static char fmt_buf[1024];
 static char off_buf[80];
 
-
-static char * reiserfs_cpu_offset (struct cpu_key * key)
-{
-  if (cpu_key_k_type(key) == TYPE_DIRENTRY)
-    sprintf (off_buf, "%Lu(%Lu)", 
-	     (unsigned long long)GET_HASH_VALUE (cpu_key_k_offset (key)),
-	     (unsigned long long)GET_GENERATION_NUMBER (cpu_key_k_offset (key)));
-  else
-    sprintf (off_buf, "0x%Lx", (unsigned long long)cpu_key_k_offset (key));
-  return off_buf;
-}
-
-
-static char * le_offset (struct reiserfs_key * key)
-{
-  int version;
-
-  version = le_key_version (key);
-  if (le_key_k_type (version, key) == TYPE_DIRENTRY)
-    sprintf (off_buf, "%Lu(%Lu)", 
-	     (unsigned long long)GET_HASH_VALUE (le_key_k_offset (version, key)),
-	     (unsigned long long)GET_GENERATION_NUMBER (le_key_k_offset (version, key)));
-  else
-    sprintf (off_buf, "0x%Lx", (unsigned long long)le_key_k_offset (version, key));
-  return off_buf;
-}
-
-
-static char * cpu_type (struct cpu_key * key)
+static char *reiserfs_cpu_offset(struct cpu_key *key)
 {
-    if (cpu_key_k_type (key) == TYPE_STAT_DATA)
-	return "SD";
-    if (cpu_key_k_type (key) == TYPE_DIRENTRY)
-	return "DIR";
-    if (cpu_key_k_type (key) == TYPE_DIRECT)
-	return "DIRECT";
-    if (cpu_key_k_type (key) == TYPE_INDIRECT)
-	return "IND";
-    return "UNKNOWN";
+	if (cpu_key_k_type(key) == TYPE_DIRENTRY)
+		sprintf(off_buf, "%Lu(%Lu)",
+			(unsigned long long)
+			GET_HASH_VALUE(cpu_key_k_offset(key)),
+			(unsigned long long)
+			GET_GENERATION_NUMBER(cpu_key_k_offset(key)));
+	else
+		sprintf(off_buf, "0x%Lx",
+			(unsigned long long)cpu_key_k_offset(key));
+	return off_buf;
+}
+
+static char *le_offset(struct reiserfs_key *key)
+{
+	int version;
+
+	version = le_key_version(key);
+	if (le_key_k_type(version, key) == TYPE_DIRENTRY)
+		sprintf(off_buf, "%Lu(%Lu)",
+			(unsigned long long)
+			GET_HASH_VALUE(le_key_k_offset(version, key)),
+			(unsigned long long)
+			GET_GENERATION_NUMBER(le_key_k_offset(version, key)));
+	else
+		sprintf(off_buf, "0x%Lx",
+			(unsigned long long)le_key_k_offset(version, key));
+	return off_buf;
+}
+
+static char *cpu_type(struct cpu_key *key)
+{
+	if (cpu_key_k_type(key) == TYPE_STAT_DATA)
+		return "SD";
+	if (cpu_key_k_type(key) == TYPE_DIRENTRY)
+		return "DIR";
+	if (cpu_key_k_type(key) == TYPE_DIRECT)
+		return "DIRECT";
+	if (cpu_key_k_type(key) == TYPE_INDIRECT)
+		return "IND";
+	return "UNKNOWN";
+}
+
+static char *le_type(struct reiserfs_key *key)
+{
+	int version;
+
+	version = le_key_version(key);
+
+	if (le_key_k_type(version, key) == TYPE_STAT_DATA)
+		return "SD";
+	if (le_key_k_type(version, key) == TYPE_DIRENTRY)
+		return "DIR";
+	if (le_key_k_type(version, key) == TYPE_DIRECT)
+		return "DIRECT";
+	if (le_key_k_type(version, key) == TYPE_INDIRECT)
+		return "IND";
+	return "UNKNOWN";
 }
 
-
-static char * le_type (struct reiserfs_key * key)
-{
-    int version;
-    
-    version = le_key_version (key);
-
-    if (le_key_k_type (version, key) == TYPE_STAT_DATA)
-	return "SD";
-    if (le_key_k_type (version, key) == TYPE_DIRENTRY)
-	return "DIR";
-    if (le_key_k_type (version, key) == TYPE_DIRECT)
-	return "DIRECT";
-    if (le_key_k_type (version, key) == TYPE_INDIRECT)
-	return "IND";
-    return "UNKNOWN";
-}
-
-
 /* %k */
-static void sprintf_le_key (char * buf, struct reiserfs_key * key)
+static void sprintf_le_key(char *buf, struct reiserfs_key *key)
 {
-  if (key)
-    sprintf (buf, "[%d %d %s %s]", le32_to_cpu (key->k_dir_id),
-	     le32_to_cpu (key->k_objectid), le_offset (key), le_type (key));
-  else
-    sprintf (buf, "[NULL]");
+	if (key)
+		sprintf(buf, "[%d %d %s %s]", le32_to_cpu(key->k_dir_id),
+			le32_to_cpu(key->k_objectid), le_offset(key),
+			le_type(key));
+	else
+		sprintf(buf, "[NULL]");
 }
 
-
 /* %K */
-static void sprintf_cpu_key (char * buf, struct cpu_key * key)
+static void sprintf_cpu_key(char *buf, struct cpu_key *key)
 {
-  if (key)
-    sprintf (buf, "[%d %d %s %s]", key->on_disk_key.k_dir_id,
-	     key->on_disk_key.k_objectid, reiserfs_cpu_offset (key),
-             cpu_type (key));
-  else
-    sprintf (buf, "[NULL]");
+	if (key)
+		sprintf(buf, "[%d %d %s %s]", key->on_disk_key.k_dir_id,
+			key->on_disk_key.k_objectid, reiserfs_cpu_offset(key),
+			cpu_type(key));
+	else
+		sprintf(buf, "[NULL]");
 }
 
-static void sprintf_de_head( char *buf, struct reiserfs_de_head *deh )
+static void sprintf_de_head(char *buf, struct reiserfs_de_head *deh)
 {
-    if( deh )
-        sprintf( buf, "[offset=%d dir_id=%d objectid=%d location=%d state=%04x]", deh_offset(deh), deh_dir_id(deh),
-                 deh_objectid(deh), deh_location(deh), deh_state(deh) );
-    else
-        sprintf( buf, "[NULL]" );
+	if (deh)
+		sprintf(buf,
+			"[offset=%d dir_id=%d objectid=%d location=%d state=%04x]",
+			deh_offset(deh), deh_dir_id(deh), deh_objectid(deh),
+			deh_location(deh), deh_state(deh));
+	else
+		sprintf(buf, "[NULL]");
 
 }
 
-static void sprintf_item_head (char * buf, struct item_head * ih)
+static void sprintf_item_head(char *buf, struct item_head *ih)
 {
-    if (ih) {
-	strcpy (buf, (ih_version (ih) == KEY_FORMAT_3_6) ? "*3.6* " : "*3.5*");
-	sprintf_le_key (buf + strlen (buf), &(ih->ih_key));
-	sprintf (buf + strlen (buf), ", item_len %d, item_location %d, "
-		 "free_space(entry_count) %d",
-		 ih_item_len(ih), ih_location(ih), ih_free_space (ih));
-    } else
-	sprintf (buf, "[NULL]");
+	if (ih) {
+		strcpy(buf,
+		       (ih_version(ih) == KEY_FORMAT_3_6) ? "*3.6* " : "*3.5*");
+		sprintf_le_key(buf + strlen(buf), &(ih->ih_key));
+		sprintf(buf + strlen(buf), ", item_len %d, item_location %d, "
+			"free_space(entry_count) %d",
+			ih_item_len(ih), ih_location(ih), ih_free_space(ih));
+	} else
+		sprintf(buf, "[NULL]");
 }
 
-
-static void sprintf_direntry (char * buf, struct reiserfs_dir_entry * de)
+static void sprintf_direntry(char *buf, struct reiserfs_dir_entry *de)
 {
-  char name[20];
+	char name[20];
 
-  memcpy (name, de->de_name, de->de_namelen > 19 ? 19 : de->de_namelen);
-  name [de->de_namelen > 19 ? 19 : de->de_namelen] = 0;
-  sprintf (buf, "\"%s\"==>[%d %d]", name, de->de_dir_id, de->de_objectid);
+	memcpy(name, de->de_name, de->de_namelen > 19 ? 19 : de->de_namelen);
+	name[de->de_namelen > 19 ? 19 : de->de_namelen] = 0;
+	sprintf(buf, "\"%s\"==>[%d %d]", name, de->de_dir_id, de->de_objectid);
 }
 
-
-static void sprintf_block_head (char * buf, struct buffer_head * bh)
+static void sprintf_block_head(char *buf, struct buffer_head *bh)
 {
-  sprintf (buf, "level=%d, nr_items=%d, free_space=%d rdkey ",
-	   B_LEVEL (bh), B_NR_ITEMS (bh), B_FREE_SPACE (bh));
+	sprintf(buf, "level=%d, nr_items=%d, free_space=%d rdkey ",
+		B_LEVEL(bh), B_NR_ITEMS(bh), B_FREE_SPACE(bh));
 }
 
-
-static void sprintf_buffer_head (char * buf, struct buffer_head * bh) 
+static void sprintf_buffer_head(char *buf, struct buffer_head *bh)
 {
-  char b[BDEVNAME_SIZE];
+	char b[BDEVNAME_SIZE];
 
-  sprintf (buf, "dev %s, size %d, blocknr %llu, count %d, state 0x%lx, page %p, (%s, %s, %s)",
-	   bdevname (bh->b_bdev, b), bh->b_size,
-	   (unsigned long long)bh->b_blocknr,
-	   atomic_read (&(bh->b_count)),
-	   bh->b_state, bh->b_page,
-	   buffer_uptodate (bh) ? "UPTODATE" : "!UPTODATE",
-	   buffer_dirty (bh) ? "DIRTY" : "CLEAN",
-	   buffer_locked (bh) ? "LOCKED" : "UNLOCKED");
+	sprintf(buf,
+		"dev %s, size %d, blocknr %llu, count %d, state 0x%lx, page %p, (%s, %s, %s)",
+		bdevname(bh->b_bdev, b), bh->b_size,
+		(unsigned long long)bh->b_blocknr, atomic_read(&(bh->b_count)),
+		bh->b_state, bh->b_page,
+		buffer_uptodate(bh) ? "UPTODATE" : "!UPTODATE",
+		buffer_dirty(bh) ? "DIRTY" : "CLEAN",
+		buffer_locked(bh) ? "LOCKED" : "UNLOCKED");
 }
 
-
-static void sprintf_disk_child (char * buf, struct disk_child * dc)
+static void sprintf_disk_child(char *buf, struct disk_child *dc)
 {
-  sprintf (buf, "[dc_number=%d, dc_size=%u]", dc_block_number(dc), dc_size(dc));
+	sprintf(buf, "[dc_number=%d, dc_size=%u]", dc_block_number(dc),
+		dc_size(dc));
 }
 
-
-static char * is_there_reiserfs_struct (char * fmt, int * what, int * skip)
+static char *is_there_reiserfs_struct(char *fmt, int *what, int *skip)
 {
-  char * k = fmt;
+	char *k = fmt;
 
-  *skip = 0;
-  
-  while ((k = strchr (k, '%')) != NULL)
-  {
-    if (k[1] == 'k' || k[1] == 'K' || k[1] == 'h' || k[1] == 't' ||
-	      k[1] == 'z' || k[1] == 'b' || k[1] == 'y' || k[1] == 'a' ) {
-      *what = k[1];
-      break;
-    }
-    (*skip) ++;
-    k ++;
-  }
-  return k;
-}
+	*skip = 0;
 
+	while ((k = strchr(k, '%')) != NULL) {
+		if (k[1] == 'k' || k[1] == 'K' || k[1] == 'h' || k[1] == 't' ||
+		    k[1] == 'z' || k[1] == 'b' || k[1] == 'y' || k[1] == 'a') {
+			*what = k[1];
+			break;
+		}
+		(*skip)++;
+		k++;
+	}
+	return k;
+}
 
 /* debugging reiserfs we used to print out a lot of different
    variables, like keys, item headers, buffer heads etc. Values of
@@ -191,60 +189,63 @@ static char * is_there_reiserfs_struct (
            key->k_offset, key->k_uniqueness); 
 */
 
-
-static void
-prepare_error_buf( const char *fmt, va_list args )
+static void prepare_error_buf(const char *fmt, va_list args)
 {
-    char * fmt1 = fmt_buf;
-    char * k;
-    char * p = error_buf;
-    int i, j, what, skip;
-
-    strcpy (fmt1, fmt);
-
-    while( (k = is_there_reiserfs_struct( fmt1, &what, &skip )) != NULL )
-    {
-        *k = 0;
-
-        p += vsprintf (p, fmt1, args);
-
-        for (i = 0; i < skip; i ++)
-            j = va_arg (args, int);
-
-        switch (what) {
-        case 'k':
-            sprintf_le_key (p, va_arg(args, struct reiserfs_key *));
-            break;
-        case 'K':
-            sprintf_cpu_key (p, va_arg(args, struct cpu_key *));
-            break;
-        case 'h':
-            sprintf_item_head (p, va_arg(args, struct item_head *));
-            break;
-        case 't':
-            sprintf_direntry (p, va_arg(args, struct reiserfs_dir_entry *));
-            break;
-        case 'y':
-            sprintf_disk_child (p, va_arg(args, struct disk_child *));
-            break;
-        case 'z':
-            sprintf_block_head (p, va_arg(args, struct buffer_head *));
-            break;
-        case 'b':
-            sprintf_buffer_head (p, va_arg(args, struct buffer_head *));
-            break;
-        case 'a':
-            sprintf_de_head (p, va_arg(args, struct reiserfs_de_head *));
-            break;
-        }
-
-        p += strlen (p);
-        fmt1 = k + 2;
-    }
-    vsprintf (p, fmt1, args);
+	char *fmt1 = fmt_buf;
+	char *k;
+	char *p = error_buf;
+	int i, j, what, skip;
+
+	strcpy(fmt1, fmt);
+
+	while ((k = is_there_reiserfs_struct(fmt1, &what, &skip)) != NULL) {
+		*k = 0;
+
+		p += vsprintf(p, fmt1, args);
+
+		for (i = 0; i < skip; i++)
+			j = va_arg(args, int);
+
+		switch (what) {
+		case 'k':
+			sprintf_le_key(p, va_arg(args, struct reiserfs_key *));
+			break;
+		case 'K':
+			sprintf_cpu_key(p, va_arg(args, struct cpu_key *));
+			break;
+		case 'h':
+			sprintf_item_head(p, va_arg(args, struct item_head *));
+			break;
+		case 't':
+			sprintf_direntry(p,
+					 va_arg(args,
+						struct reiserfs_dir_entry *));
+			break;
+		case 'y':
+			sprintf_disk_child(p,
+					   va_arg(args, struct disk_child *));
+			break;
+		case 'z':
+			sprintf_block_head(p,
+					   va_arg(args, struct buffer_head *));
+			break;
+		case 'b':
+			sprintf_buffer_head(p,
+					    va_arg(args, struct buffer_head *));
+			break;
+		case 'a':
+			sprintf_de_head(p,
+					va_arg(args,
+					       struct reiserfs_de_head *));
+			break;
+		}
 
-}
+		p += strlen(p);
+		fmt1 = k + 2;
+	}
+	vsprintf(p, fmt1, args);
 
+}
 
 /* in addition to usual conversion specifiers this accepts reiserfs
    specific conversion specifiers: 
@@ -264,43 +265,43 @@ prepare_error_buf( const char *fmt, va_l
     va_end( args );\
 }
 
-void reiserfs_warning (struct super_block *sb, const char * fmt, ...)
+void reiserfs_warning(struct super_block *sb, const char *fmt, ...)
 {
-  do_reiserfs_warning(fmt);
-  if (sb)
-      printk (KERN_WARNING "ReiserFS: %s: warning: %s\n",
-             reiserfs_bdevname (sb), error_buf);
-  else
-      printk (KERN_WARNING "ReiserFS: warning: %s\n", error_buf);
+	do_reiserfs_warning(fmt);
+	if (sb)
+		printk(KERN_WARNING "ReiserFS: %s: warning: %s\n",
+		       reiserfs_bdevname(sb), error_buf);
+	else
+		printk(KERN_WARNING "ReiserFS: warning: %s\n", error_buf);
 }
 
 /* No newline.. reiserfs_info calls can be followed by printk's */
-void reiserfs_info (struct super_block *sb, const char * fmt, ...)
+void reiserfs_info(struct super_block *sb, const char *fmt, ...)
 {
-  do_reiserfs_warning(fmt);
-  if (sb)
-      printk (KERN_NOTICE "ReiserFS: %s: %s",
-             reiserfs_bdevname (sb), error_buf);
-  else
-      printk (KERN_NOTICE "ReiserFS: %s", error_buf);
+	do_reiserfs_warning(fmt);
+	if (sb)
+		printk(KERN_NOTICE "ReiserFS: %s: %s",
+		       reiserfs_bdevname(sb), error_buf);
+	else
+		printk(KERN_NOTICE "ReiserFS: %s", error_buf);
 }
 
 /* No newline.. reiserfs_printk calls can be followed by printk's */
-static void reiserfs_printk (const char * fmt, ...)
+static void reiserfs_printk(const char *fmt, ...)
 {
-  do_reiserfs_warning(fmt);
-  printk (error_buf);
+	do_reiserfs_warning(fmt);
+	printk(error_buf);
 }
 
-void reiserfs_debug (struct super_block *s, int level, const char * fmt, ...)
+void reiserfs_debug(struct super_block *s, int level, const char *fmt, ...)
 {
 #ifdef CONFIG_REISERFS_CHECK
-  do_reiserfs_warning(fmt);
-  if (s)
-      printk (KERN_DEBUG "ReiserFS: %s: %s\n",
-             reiserfs_bdevname (s), error_buf);
-  else
-      printk (KERN_DEBUG "ReiserFS: %s\n", error_buf);
+	do_reiserfs_warning(fmt);
+	if (s)
+		printk(KERN_DEBUG "ReiserFS: %s: %s\n",
+		       reiserfs_bdevname(s), error_buf);
+	else
+		printk(KERN_DEBUG "ReiserFS: %s\n", error_buf);
 #endif
 }
 
@@ -349,379 +350,403 @@ void reiserfs_debug (struct super_block 
 
    .  */
 
-
 #ifdef CONFIG_REISERFS_CHECK
-extern struct tree_balance * cur_tb;
+extern struct tree_balance *cur_tb;
 #endif
 
-void reiserfs_panic (struct super_block * sb, const char * fmt, ...)
+void reiserfs_panic(struct super_block *sb, const char *fmt, ...)
 {
-  do_reiserfs_warning(fmt);
-  printk (KERN_EMERG "REISERFS: panic (device %s): %s\n",
-          reiserfs_bdevname (sb), error_buf);
-  BUG ();
+	do_reiserfs_warning(fmt);
+	printk(KERN_EMERG "REISERFS: panic (device %s): %s\n",
+	       reiserfs_bdevname(sb), error_buf);
+	BUG();
 
-  /* this is not actually called, but makes reiserfs_panic() "noreturn" */
-  panic ("REISERFS: panic (device %s): %s\n",
-	 reiserfs_bdevname (sb), error_buf);
+	/* this is not actually called, but makes reiserfs_panic() "noreturn" */
+	panic("REISERFS: panic (device %s): %s\n",
+	      reiserfs_bdevname(sb), error_buf);
 }
 
-void
-reiserfs_abort (struct super_block *sb, int errno, const char *fmt, ...)
+void reiserfs_abort(struct super_block *sb, int errno, const char *fmt, ...)
 {
-    do_reiserfs_warning (fmt);
+	do_reiserfs_warning(fmt);
 
-    if (reiserfs_error_panic (sb)) {
-        panic (KERN_CRIT "REISERFS: panic (device %s): %s\n",
-               reiserfs_bdevname (sb), error_buf);
-    }
+	if (reiserfs_error_panic(sb)) {
+		panic(KERN_CRIT "REISERFS: panic (device %s): %s\n",
+		      reiserfs_bdevname(sb), error_buf);
+	}
 
-    if (sb->s_flags & MS_RDONLY)
-        return;
+	if (sb->s_flags & MS_RDONLY)
+		return;
 
-    printk (KERN_CRIT "REISERFS: abort (device %s): %s\n",
-            reiserfs_bdevname (sb), error_buf);
+	printk(KERN_CRIT "REISERFS: abort (device %s): %s\n",
+	       reiserfs_bdevname(sb), error_buf);
 
-    sb->s_flags |= MS_RDONLY;
-    reiserfs_journal_abort (sb, errno);
+	sb->s_flags |= MS_RDONLY;
+	reiserfs_journal_abort(sb, errno);
 }
 
 /* this prints internal nodes (4 keys/items in line) (dc_number,
    dc_size)[k_dirid, k_objectid, k_offset, k_uniqueness](dc_number,
    dc_size)...*/
-static int print_internal (struct buffer_head * bh, int first, int last)
+static int print_internal(struct buffer_head *bh, int first, int last)
 {
-    struct reiserfs_key * key;
-    struct disk_child * dc;
-    int i;
-    int from, to;
-    
-    if (!B_IS_KEYS_LEVEL (bh))
-	return 1;
+	struct reiserfs_key *key;
+	struct disk_child *dc;
+	int i;
+	int from, to;
 
-    check_internal (bh);
-    
-    if (first == -1) {
-	from = 0;
-	to = B_NR_ITEMS (bh);
-    } else {
-	from = first;
-	to = last < B_NR_ITEMS (bh) ? last : B_NR_ITEMS (bh);
-    }
+	if (!B_IS_KEYS_LEVEL(bh))
+		return 1;
 
-    reiserfs_printk ("INTERNAL NODE (%ld) contains %z\n",  bh->b_blocknr, bh);
-    
-    dc = B_N_CHILD (bh, from);
-    reiserfs_printk ("PTR %d: %y ", from, dc);
-    
-    for (i = from, key = B_N_PDELIM_KEY (bh, from), dc ++; i < to; i ++, key ++, dc ++) {
-	reiserfs_printk ("KEY %d: %k PTR %d: %y ", i, key, i + 1, dc);
-	if (i && i % 4 == 0)
-	    printk ("\n");
-    }
-    printk ("\n");
-    return 0;
-}
+	check_internal(bh);
 
+	if (first == -1) {
+		from = 0;
+		to = B_NR_ITEMS(bh);
+	} else {
+		from = first;
+		to = last < B_NR_ITEMS(bh) ? last : B_NR_ITEMS(bh);
+	}
 
+	reiserfs_printk("INTERNAL NODE (%ld) contains %z\n", bh->b_blocknr, bh);
 
+	dc = B_N_CHILD(bh, from);
+	reiserfs_printk("PTR %d: %y ", from, dc);
 
+	for (i = from, key = B_N_PDELIM_KEY(bh, from), dc++; i < to;
+	     i++, key++, dc++) {
+		reiserfs_printk("KEY %d: %k PTR %d: %y ", i, key, i + 1, dc);
+		if (i && i % 4 == 0)
+			printk("\n");
+	}
+	printk("\n");
+	return 0;
+}
 
-static int print_leaf (struct buffer_head * bh, int print_mode, int first, int last)
+static int print_leaf(struct buffer_head *bh, int print_mode, int first,
+		      int last)
 {
-    struct block_head * blkh;
-    struct item_head * ih;
-    int i, nr;
-    int from, to;
-
-    if (!B_IS_ITEMS_LEVEL (bh))
-	return 1;
-
-    check_leaf (bh);
+	struct block_head *blkh;
+	struct item_head *ih;
+	int i, nr;
+	int from, to;
+
+	if (!B_IS_ITEMS_LEVEL(bh))
+		return 1;
+
+	check_leaf(bh);
+
+	blkh = B_BLK_HEAD(bh);
+	ih = B_N_PITEM_HEAD(bh, 0);
+	nr = blkh_nr_item(blkh);
+
+	printk
+	    ("\n===================================================================\n");
+	reiserfs_printk("LEAF NODE (%ld) contains %z\n", bh->b_blocknr, bh);
+
+	if (!(print_mode & PRINT_LEAF_ITEMS)) {
+		reiserfs_printk("FIRST ITEM_KEY: %k, LAST ITEM KEY: %k\n",
+				&(ih->ih_key), &((ih + nr - 1)->ih_key));
+		return 0;
+	}
 
-    blkh = B_BLK_HEAD (bh);
-    ih = B_N_PITEM_HEAD (bh,0);
-    nr = blkh_nr_item(blkh);
+	if (first < 0 || first > nr - 1)
+		from = 0;
+	else
+		from = first;
+
+	if (last < 0 || last > nr)
+		to = nr;
+	else
+		to = last;
+
+	ih += from;
+	printk
+	    ("-------------------------------------------------------------------------------\n");
+	printk
+	    ("|##|   type    |           key           | ilen | free_space | version | loc  |\n");
+	for (i = from; i < to; i++, ih++) {
+		printk
+		    ("-------------------------------------------------------------------------------\n");
+		reiserfs_printk("|%2d| %h |\n", i, ih);
+		if (print_mode & PRINT_LEAF_ITEMS)
+			op_print_item(ih, B_I_PITEM(bh, ih));
+	}
 
-    printk ("\n===================================================================\n");
-    reiserfs_printk ("LEAF NODE (%ld) contains %z\n", bh->b_blocknr, bh);
+	printk
+	    ("===================================================================\n");
 
-    if (!(print_mode & PRINT_LEAF_ITEMS)) {
-	reiserfs_printk ("FIRST ITEM_KEY: %k, LAST ITEM KEY: %k\n",
-			  &(ih->ih_key), &((ih + nr - 1)->ih_key));
 	return 0;
-    }
+}
 
-    if (first < 0 || first > nr - 1) 
-	from = 0;
-    else 
-	from = first;
-
-    if (last < 0 || last > nr )
-	to = nr;
-    else
-	to = last;
-
-    ih += from;
-    printk ("-------------------------------------------------------------------------------\n");
-    printk ("|##|   type    |           key           | ilen | free_space | version | loc  |\n");
-    for (i = from; i < to; i++, ih ++) {
-	printk ("-------------------------------------------------------------------------------\n");
-	reiserfs_printk ("|%2d| %h |\n", i, ih);
-	if (print_mode & PRINT_LEAF_ITEMS)
-	    op_print_item (ih, B_I_PITEM (bh, ih));
-    }
-
-    printk ("===================================================================\n");
-
-    return 0;
-}
-
-char * reiserfs_hashname(int code)
-{
-    if ( code == YURA_HASH)
-	return "rupasov";
-    if ( code == TEA_HASH)
-	return "tea";
-    if ( code == R5_HASH)
-	return "r5";
+char *reiserfs_hashname(int code)
+{
+	if (code == YURA_HASH)
+		return "rupasov";
+	if (code == TEA_HASH)
+		return "tea";
+	if (code == R5_HASH)
+		return "r5";
 
-    return "unknown";
+	return "unknown";
 }
 
 /* return 1 if this is not super block */
-static int print_super_block (struct buffer_head * bh)
+static int print_super_block(struct buffer_head *bh)
 {
-    struct reiserfs_super_block * rs = (struct reiserfs_super_block *)(bh->b_data);
-    int skipped, data_blocks;
-    char *version;
-    char b[BDEVNAME_SIZE];
-
-    if (is_reiserfs_3_5(rs)) {
-        version = "3.5";
-    } else if (is_reiserfs_3_6(rs)) {
-        version = "3.6";
-    } else if (is_reiserfs_jr(rs)) {
-      version = ((sb_version(rs) == REISERFS_VERSION_2) ?
- 		 "3.6" : "3.5");  
-    } else {
-	return 1;
-    }
-
-    printk ("%s\'s super block is in block %llu\n", bdevname (bh->b_bdev, b),
-            (unsigned long long)bh->b_blocknr);
-    printk ("Reiserfs version %s\n", version );
-    printk ("Block count %u\n", sb_block_count(rs));
-    printk ("Blocksize %d\n", sb_blocksize(rs));
-    printk ("Free blocks %u\n", sb_free_blocks(rs));
-    // FIXME: this would be confusing if
-    // someone stores reiserfs super block in some data block ;)
+	struct reiserfs_super_block *rs =
+	    (struct reiserfs_super_block *)(bh->b_data);
+	int skipped, data_blocks;
+	char *version;
+	char b[BDEVNAME_SIZE];
+
+	if (is_reiserfs_3_5(rs)) {
+		version = "3.5";
+	} else if (is_reiserfs_3_6(rs)) {
+		version = "3.6";
+	} else if (is_reiserfs_jr(rs)) {
+		version = ((sb_version(rs) == REISERFS_VERSION_2) ?
+			   "3.6" : "3.5");
+	} else {
+		return 1;
+	}
+
+	printk("%s\'s super block is in block %llu\n", bdevname(bh->b_bdev, b),
+	       (unsigned long long)bh->b_blocknr);
+	printk("Reiserfs version %s\n", version);
+	printk("Block count %u\n", sb_block_count(rs));
+	printk("Blocksize %d\n", sb_blocksize(rs));
+	printk("Free blocks %u\n", sb_free_blocks(rs));
+	// FIXME: this would be confusing if
+	// someone stores reiserfs super block in some data block ;)
 //    skipped = (bh->b_blocknr * bh->b_size) / sb_blocksize(rs);
-    skipped = bh->b_blocknr;
-    data_blocks = sb_block_count(rs) - skipped - 1 - sb_bmap_nr(rs) -
-	    (!is_reiserfs_jr(rs) ? sb_jp_journal_size(rs) + 1 : sb_reserved_for_journal(rs)) -	    
-	    sb_free_blocks(rs);
-    printk ("Busy blocks (skipped %d, bitmaps - %d, journal (or reserved) blocks - %d\n"
-	    "1 super block, %d data blocks\n", 
-	    skipped, sb_bmap_nr(rs), (!is_reiserfs_jr(rs) ? (sb_jp_journal_size(rs) + 1) :
-				      sb_reserved_for_journal(rs)) , data_blocks);
-    printk ("Root block %u\n", sb_root_block(rs));
-    printk ("Journal block (first) %d\n", sb_jp_journal_1st_block(rs));
-    printk ("Journal dev %d\n", sb_jp_journal_dev(rs));
-    printk ("Journal orig size %d\n", sb_jp_journal_size(rs));
-    printk ("FS state %d\n", sb_fs_state(rs));
-    printk ("Hash function \"%s\"\n",
-	    reiserfs_hashname(sb_hash_function_code(rs)));
-    
-    printk ("Tree height %d\n", sb_tree_height(rs));
-    return 0;
+	skipped = bh->b_blocknr;
+	data_blocks = sb_block_count(rs) - skipped - 1 - sb_bmap_nr(rs) -
+	    (!is_reiserfs_jr(rs) ? sb_jp_journal_size(rs) +
+	     1 : sb_reserved_for_journal(rs)) - sb_free_blocks(rs);
+	printk
+	    ("Busy blocks (skipped %d, bitmaps - %d, journal (or reserved) blocks - %d\n"
+	     "1 super block, %d data blocks\n", skipped, sb_bmap_nr(rs),
+	     (!is_reiserfs_jr(rs) ? (sb_jp_journal_size(rs) + 1) :
+	      sb_reserved_for_journal(rs)), data_blocks);
+	printk("Root block %u\n", sb_root_block(rs));
+	printk("Journal block (first) %d\n", sb_jp_journal_1st_block(rs));
+	printk("Journal dev %d\n", sb_jp_journal_dev(rs));
+	printk("Journal orig size %d\n", sb_jp_journal_size(rs));
+	printk("FS state %d\n", sb_fs_state(rs));
+	printk("Hash function \"%s\"\n",
+	       reiserfs_hashname(sb_hash_function_code(rs)));
+
+	printk("Tree height %d\n", sb_tree_height(rs));
+	return 0;
 }
 
-static int print_desc_block (struct buffer_head * bh)
+static int print_desc_block(struct buffer_head *bh)
 {
-    struct reiserfs_journal_desc * desc;
+	struct reiserfs_journal_desc *desc;
 
-    if (memcmp(get_journal_desc_magic (bh), JOURNAL_DESC_MAGIC, 8))
-	return 1;
+	if (memcmp(get_journal_desc_magic(bh), JOURNAL_DESC_MAGIC, 8))
+		return 1;
 
-    desc = (struct reiserfs_journal_desc *)(bh->b_data);
-    printk ("Desc block %llu (j_trans_id %d, j_mount_id %d, j_len %d)",
-	    (unsigned long long)bh->b_blocknr, get_desc_trans_id (desc), get_desc_mount_id (desc),
-	    get_desc_trans_len (desc));
+	desc = (struct reiserfs_journal_desc *)(bh->b_data);
+	printk("Desc block %llu (j_trans_id %d, j_mount_id %d, j_len %d)",
+	       (unsigned long long)bh->b_blocknr, get_desc_trans_id(desc),
+	       get_desc_mount_id(desc), get_desc_trans_len(desc));
 
-    return 0;
+	return 0;
 }
 
-
-void print_block (struct buffer_head * bh, ...)//int print_mode, int first, int last)
+void print_block(struct buffer_head *bh, ...)	//int print_mode, int first, int last)
 {
-    va_list args;
-    int mode, first, last;
+	va_list args;
+	int mode, first, last;
 
-    va_start (args, bh);
+	va_start(args, bh);
 
-    if ( ! bh ) {
-	printk("print_block: buffer is NULL\n");
-	return;
-    }
+	if (!bh) {
+		printk("print_block: buffer is NULL\n");
+		return;
+	}
 
-    mode = va_arg (args, int);
-    first = va_arg (args, int);
-    last = va_arg (args, int);
-    if (print_leaf (bh, mode, first, last))
-	if (print_internal (bh, first, last))
-	    if (print_super_block (bh))
-		if (print_desc_block (bh))
-		    printk ("Block %llu contains unformatted data\n", (unsigned long long)bh->b_blocknr);
+	mode = va_arg(args, int);
+	first = va_arg(args, int);
+	last = va_arg(args, int);
+	if (print_leaf(bh, mode, first, last))
+		if (print_internal(bh, first, last))
+			if (print_super_block(bh))
+				if (print_desc_block(bh))
+					printk
+					    ("Block %llu contains unformatted data\n",
+					     (unsigned long long)bh->b_blocknr);
 }
 
-
-
 static char print_tb_buf[2048];
 
 /* this stores initial state of tree balance in the print_tb_buf */
-void store_print_tb (struct tree_balance * tb)
+void store_print_tb(struct tree_balance *tb)
 {
-    int h = 0;
-    int i;
-    struct buffer_head * tbSh, * tbFh;
-
-    if (!tb)
-	return;
-
-    sprintf (print_tb_buf, "\n"
-	     "BALANCING %d\n"
-	     "MODE=%c, ITEM_POS=%d POS_IN_ITEM=%d\n" 
-	     "=====================================================================\n"
-	     "* h *    S    *    L    *    R    *   F   *   FL  *   FR  *  CFL  *  CFR  *\n",
-	     REISERFS_SB(tb->tb_sb)->s_do_balance,
-	     tb->tb_mode, PATH_LAST_POSITION (tb->tb_path), tb->tb_path->pos_in_item);
-  
-    for (h = 0; h < sizeof(tb->insert_size) / sizeof (tb->insert_size[0]); h ++) {
-	if (PATH_H_PATH_OFFSET (tb->tb_path, h) <= tb->tb_path->path_length && 
-	    PATH_H_PATH_OFFSET (tb->tb_path, h) > ILLEGAL_PATH_ELEMENT_OFFSET) {
-	    tbSh = PATH_H_PBUFFER (tb->tb_path, h);
-	    tbFh = PATH_H_PPARENT (tb->tb_path, h);
-	} else {
-	    tbSh = NULL;
-	    tbFh = NULL;
+	int h = 0;
+	int i;
+	struct buffer_head *tbSh, *tbFh;
+
+	if (!tb)
+		return;
+
+	sprintf(print_tb_buf, "\n"
+		"BALANCING %d\n"
+		"MODE=%c, ITEM_POS=%d POS_IN_ITEM=%d\n"
+		"=====================================================================\n"
+		"* h *    S    *    L    *    R    *   F   *   FL  *   FR  *  CFL  *  CFR  *\n",
+		REISERFS_SB(tb->tb_sb)->s_do_balance,
+		tb->tb_mode, PATH_LAST_POSITION(tb->tb_path),
+		tb->tb_path->pos_in_item);
+
+	for (h = 0; h < sizeof(tb->insert_size) / sizeof(tb->insert_size[0]);
+	     h++) {
+		if (PATH_H_PATH_OFFSET(tb->tb_path, h) <=
+		    tb->tb_path->path_length
+		    && PATH_H_PATH_OFFSET(tb->tb_path,
+					  h) > ILLEGAL_PATH_ELEMENT_OFFSET) {
+			tbSh = PATH_H_PBUFFER(tb->tb_path, h);
+			tbFh = PATH_H_PPARENT(tb->tb_path, h);
+		} else {
+			tbSh = NULL;
+			tbFh = NULL;
+		}
+		sprintf(print_tb_buf + strlen(print_tb_buf),
+			"* %d * %3lld(%2d) * %3lld(%2d) * %3lld(%2d) * %5lld * %5lld * %5lld * %5lld * %5lld *\n",
+			h,
+			(tbSh) ? (long long)(tbSh->b_blocknr) : (-1LL),
+			(tbSh) ? atomic_read(&(tbSh->b_count)) : -1,
+			(tb->L[h]) ? (long long)(tb->L[h]->b_blocknr) : (-1LL),
+			(tb->L[h]) ? atomic_read(&(tb->L[h]->b_count)) : -1,
+			(tb->R[h]) ? (long long)(tb->R[h]->b_blocknr) : (-1LL),
+			(tb->R[h]) ? atomic_read(&(tb->R[h]->b_count)) : -1,
+			(tbFh) ? (long long)(tbFh->b_blocknr) : (-1LL),
+			(tb->FL[h]) ? (long long)(tb->FL[h]->
+						  b_blocknr) : (-1LL),
+			(tb->FR[h]) ? (long long)(tb->FR[h]->
+						  b_blocknr) : (-1LL),
+			(tb->CFL[h]) ? (long long)(tb->CFL[h]->
+						   b_blocknr) : (-1LL),
+			(tb->CFR[h]) ? (long long)(tb->CFR[h]->
+						   b_blocknr) : (-1LL));
 	}
-	sprintf (print_tb_buf + strlen (print_tb_buf),
-		 "* %d * %3lld(%2d) * %3lld(%2d) * %3lld(%2d) * %5lld * %5lld * %5lld * %5lld * %5lld *\n",
-		 h, 
-		 (tbSh) ? (long long)(tbSh->b_blocknr):(-1LL),
-		 (tbSh) ? atomic_read (&(tbSh->b_count)) : -1,
-		 (tb->L[h]) ? (long long)(tb->L[h]->b_blocknr):(-1LL),
-		 (tb->L[h]) ? atomic_read (&(tb->L[h]->b_count)) : -1,
-		 (tb->R[h]) ? (long long)(tb->R[h]->b_blocknr):(-1LL),
-		 (tb->R[h]) ? atomic_read (&(tb->R[h]->b_count)) : -1,
-		 (tbFh) ? (long long)(tbFh->b_blocknr):(-1LL),
-		 (tb->FL[h]) ? (long long)(tb->FL[h]->b_blocknr):(-1LL),
-		 (tb->FR[h]) ? (long long)(tb->FR[h]->b_blocknr):(-1LL),
-		 (tb->CFL[h]) ? (long long)(tb->CFL[h]->b_blocknr):(-1LL),
-		 (tb->CFR[h]) ? (long long)(tb->CFR[h]->b_blocknr):(-1LL));
-    }
-
-    sprintf (print_tb_buf + strlen (print_tb_buf), 
-	     "=====================================================================\n"
-	     "* h * size * ln * lb * rn * rb * blkn * s0 * s1 * s1b * s2 * s2b * curb * lk * rk *\n"
-	     "* 0 * %4d * %2d * %2d * %2d * %2d * %4d * %2d * %2d * %3d * %2d * %3d * %4d * %2d * %2d *\n",
-	     tb->insert_size[0], tb->lnum[0], tb->lbytes, tb->rnum[0],tb->rbytes, tb->blknum[0], 
-	     tb->s0num, tb->s1num,tb->s1bytes,  tb->s2num, tb->s2bytes, tb->cur_blknum, tb->lkey[0], tb->rkey[0]);
-
-    /* this prints balance parameters for non-leaf levels */
-    h = 0;
-    do {
-	h++;
-	sprintf (print_tb_buf + strlen (print_tb_buf),
-		 "* %d * %4d * %2d *    * %2d *    * %2d *\n",
-		h, tb->insert_size[h], tb->lnum[h], tb->rnum[h], tb->blknum[h]);
-    } while (tb->insert_size[h]);
-
-    sprintf (print_tb_buf + strlen (print_tb_buf), 
-	     "=====================================================================\n"
-	     "FEB list: ");
-
-    /* print FEB list (list of buffers in form (bh (b_blocknr, b_count), that will be used for new nodes) */
-    h = 0;
-    for (i = 0; i < sizeof (tb->FEB) / sizeof (tb->FEB[0]); i ++)
-	sprintf (print_tb_buf + strlen (print_tb_buf),
-		 "%p (%llu %d)%s", tb->FEB[i], tb->FEB[i] ? (unsigned long long)tb->FEB[i]->b_blocknr : 0ULL,
-		 tb->FEB[i] ? atomic_read (&(tb->FEB[i]->b_count)) : 0, 
-		 (i == sizeof (tb->FEB) / sizeof (tb->FEB[0]) - 1) ? "\n" : ", ");
-
-    sprintf (print_tb_buf + strlen (print_tb_buf), 
-	     "======================== the end ====================================\n");
-}
-
-void print_cur_tb (char * mes)
-{
-    printk ("%s\n%s", mes, print_tb_buf);
-}
-
-static void check_leaf_block_head (struct buffer_head * bh)
-{
-  struct block_head * blkh;
-  int nr;
-
-  blkh = B_BLK_HEAD (bh);
-  nr = blkh_nr_item(blkh);
-  if ( nr > (bh->b_size - BLKH_SIZE) / IH_SIZE)
-    reiserfs_panic (NULL, "vs-6010: check_leaf_block_head: invalid item number %z", bh);
-  if ( blkh_free_space(blkh) > 
-      bh->b_size - BLKH_SIZE - IH_SIZE * nr )
-    reiserfs_panic (NULL, "vs-6020: check_leaf_block_head: invalid free space %z", bh);
-    
-}
 
-static void check_internal_block_head (struct buffer_head * bh)
-{
-    struct block_head * blkh;
-    
-    blkh = B_BLK_HEAD (bh);
-    if (!(B_LEVEL (bh) > DISK_LEAF_NODE_LEVEL && B_LEVEL (bh) <= MAX_HEIGHT))
-	reiserfs_panic (NULL, "vs-6025: check_internal_block_head: invalid level %z", bh);
+	sprintf(print_tb_buf + strlen(print_tb_buf),
+		"=====================================================================\n"
+		"* h * size * ln * lb * rn * rb * blkn * s0 * s1 * s1b * s2 * s2b * curb * lk * rk *\n"
+		"* 0 * %4d * %2d * %2d * %2d * %2d * %4d * %2d * %2d * %3d * %2d * %3d * %4d * %2d * %2d *\n",
+		tb->insert_size[0], tb->lnum[0], tb->lbytes, tb->rnum[0],
+		tb->rbytes, tb->blknum[0], tb->s0num, tb->s1num, tb->s1bytes,
+		tb->s2num, tb->s2bytes, tb->cur_blknum, tb->lkey[0],
+		tb->rkey[0]);
+
+	/* this prints balance parameters for non-leaf levels */
+	h = 0;
+	do {
+		h++;
+		sprintf(print_tb_buf + strlen(print_tb_buf),
+			"* %d * %4d * %2d *    * %2d *    * %2d *\n",
+			h, tb->insert_size[h], tb->lnum[h], tb->rnum[h],
+			tb->blknum[h]);
+	} while (tb->insert_size[h]);
 
-    if (B_NR_ITEMS (bh) > (bh->b_size - BLKH_SIZE) / IH_SIZE)
-	reiserfs_panic (NULL, "vs-6030: check_internal_block_head: invalid item number %z", bh);
+	sprintf(print_tb_buf + strlen(print_tb_buf),
+		"=====================================================================\n"
+		"FEB list: ");
 
-    if (B_FREE_SPACE (bh) != 
-	bh->b_size - BLKH_SIZE - KEY_SIZE * B_NR_ITEMS (bh) - DC_SIZE * (B_NR_ITEMS (bh) + 1))
-	reiserfs_panic (NULL, "vs-6040: check_internal_block_head: invalid free space %z", bh);
+	/* print FEB list (list of buffers in form (bh (b_blocknr, b_count), that will be used for new nodes) */
+	h = 0;
+	for (i = 0; i < sizeof(tb->FEB) / sizeof(tb->FEB[0]); i++)
+		sprintf(print_tb_buf + strlen(print_tb_buf),
+			"%p (%llu %d)%s", tb->FEB[i],
+			tb->FEB[i] ? (unsigned long long)tb->FEB[i]->
+			b_blocknr : 0ULL,
+			tb->FEB[i] ? atomic_read(&(tb->FEB[i]->b_count)) : 0,
+			(i ==
+			 sizeof(tb->FEB) / sizeof(tb->FEB[0]) -
+			 1) ? "\n" : ", ");
 
+	sprintf(print_tb_buf + strlen(print_tb_buf),
+		"======================== the end ====================================\n");
 }
 
+void print_cur_tb(char *mes)
+{
+	printk("%s\n%s", mes, print_tb_buf);
+}
 
-void check_leaf (struct buffer_head * bh)
+static void check_leaf_block_head(struct buffer_head *bh)
 {
-    int i;
-    struct item_head * ih;
+	struct block_head *blkh;
+	int nr;
+
+	blkh = B_BLK_HEAD(bh);
+	nr = blkh_nr_item(blkh);
+	if (nr > (bh->b_size - BLKH_SIZE) / IH_SIZE)
+		reiserfs_panic(NULL,
+			       "vs-6010: check_leaf_block_head: invalid item number %z",
+			       bh);
+	if (blkh_free_space(blkh) > bh->b_size - BLKH_SIZE - IH_SIZE * nr)
+		reiserfs_panic(NULL,
+			       "vs-6020: check_leaf_block_head: invalid free space %z",
+			       bh);
 
-    if (!bh)
-	return;
-    check_leaf_block_head (bh);
-    for (i = 0, ih = B_N_PITEM_HEAD (bh, 0); i < B_NR_ITEMS (bh); i ++, ih ++)
-	op_check_item (ih, B_I_PITEM (bh, ih));
 }
 
+static void check_internal_block_head(struct buffer_head *bh)
+{
+	struct block_head *blkh;
+
+	blkh = B_BLK_HEAD(bh);
+	if (!(B_LEVEL(bh) > DISK_LEAF_NODE_LEVEL && B_LEVEL(bh) <= MAX_HEIGHT))
+		reiserfs_panic(NULL,
+			       "vs-6025: check_internal_block_head: invalid level %z",
+			       bh);
+
+	if (B_NR_ITEMS(bh) > (bh->b_size - BLKH_SIZE) / IH_SIZE)
+		reiserfs_panic(NULL,
+			       "vs-6030: check_internal_block_head: invalid item number %z",
+			       bh);
 
-void check_internal (struct buffer_head * bh)
+	if (B_FREE_SPACE(bh) !=
+	    bh->b_size - BLKH_SIZE - KEY_SIZE * B_NR_ITEMS(bh) -
+	    DC_SIZE * (B_NR_ITEMS(bh) + 1))
+		reiserfs_panic(NULL,
+			       "vs-6040: check_internal_block_head: invalid free space %z",
+			       bh);
+
+}
+
+void check_leaf(struct buffer_head *bh)
 {
-  if (!bh)
-    return;
-  check_internal_block_head (bh);
+	int i;
+	struct item_head *ih;
+
+	if (!bh)
+		return;
+	check_leaf_block_head(bh);
+	for (i = 0, ih = B_N_PITEM_HEAD(bh, 0); i < B_NR_ITEMS(bh); i++, ih++)
+		op_check_item(ih, B_I_PITEM(bh, ih));
 }
 
+void check_internal(struct buffer_head *bh)
+{
+	if (!bh)
+		return;
+	check_internal_block_head(bh);
+}
 
-void print_statistics (struct super_block * s)
+void print_statistics(struct super_block *s)
 {
 
-  /*
-  printk ("reiserfs_put_super: session statistics: balances %d, fix_nodes %d, \
-bmap with search %d, without %d, dir2ind %d, ind2dir %d\n",
-	  REISERFS_SB(s)->s_do_balance, REISERFS_SB(s)->s_fix_nodes,
-	  REISERFS_SB(s)->s_bmaps, REISERFS_SB(s)->s_bmaps_without_search,
-	  REISERFS_SB(s)->s_direct2indirect, REISERFS_SB(s)->s_indirect2direct);
-  */
+	/*
+	   printk ("reiserfs_put_super: session statistics: balances %d, fix_nodes %d, \
+	   bmap with search %d, without %d, dir2ind %d, ind2dir %d\n",
+	   REISERFS_SB(s)->s_do_balance, REISERFS_SB(s)->s_fix_nodes,
+	   REISERFS_SB(s)->s_bmaps, REISERFS_SB(s)->s_bmaps_without_search,
+	   REISERFS_SB(s)->s_direct2indirect, REISERFS_SB(s)->s_indirect2direct);
+	 */
 
 }
diff --git a/fs/reiserfs/procfs.c b/fs/reiserfs/procfs.c
--- a/fs/reiserfs/procfs.c
+++ b/fs/reiserfs/procfs.c
@@ -33,28 +33,27 @@
 static int show_version(struct seq_file *m, struct super_block *sb)
 {
 	char *format;
-    
-	if ( REISERFS_SB(sb)->s_properties & (1 << REISERFS_3_6) ) {
+
+	if (REISERFS_SB(sb)->s_properties & (1 << REISERFS_3_6)) {
 		format = "3.6";
-	} else if ( REISERFS_SB(sb)->s_properties & (1 << REISERFS_3_5) ) {
+	} else if (REISERFS_SB(sb)->s_properties & (1 << REISERFS_3_5)) {
 		format = "3.5";
 	} else {
 		format = "unknown";
 	}
 
-	seq_printf(m, "%s format\twith checks %s\n",
-			format,
+	seq_printf(m, "%s format\twith checks %s\n", format,
 #if defined( CONFIG_REISERFS_CHECK )
-			"on"
+		   "on"
 #else
-			"off"
+		   "off"
 #endif
-		);
+	    );
 	return 0;
 }
 
-int reiserfs_global_version_in_proc( char *buffer, char **start, off_t offset,
-				     int count, int *eof, void *data )
+int reiserfs_global_version_in_proc(char *buffer, char **start, off_t offset,
+				    int count, int *eof, void *data)
 {
 	*start = buffer;
 	*eof = 1;
@@ -79,87 +78,68 @@ int reiserfs_global_version_in_proc( cha
 
 #define DJF( x ) le32_to_cpu( rs -> x )
 #define DJV( x ) le32_to_cpu( s_v1 -> x )
-#define DJP( x ) le32_to_cpu( jp -> x ) 
+#define DJP( x ) le32_to_cpu( jp -> x )
 #define JF( x ) ( r -> s_journal -> x )
 
 static int show_super(struct seq_file *m, struct super_block *sb)
 {
 	struct reiserfs_sb_info *r = REISERFS_SB(sb);
-    
-	seq_printf(m,	"state: \t%s\n"
-			"mount options: \t%s%s%s%s%s%s%s%s%s%s%s\n"
-			"gen. counter: \t%i\n"
-			"s_kmallocs: \t%i\n"
-			"s_disk_reads: \t%i\n"
-			"s_disk_writes: \t%i\n"
-			"s_fix_nodes: \t%i\n"
-			"s_do_balance: \t%i\n"
-			"s_unneeded_left_neighbor: \t%i\n"
-			"s_good_search_by_key_reada: \t%i\n"
-			"s_bmaps: \t%i\n"
-			"s_bmaps_without_search: \t%i\n"
-			"s_direct2indirect: \t%i\n"
-			"s_indirect2direct: \t%i\n"
-			"\n"
-			"max_hash_collisions: \t%i\n"
-
-			"breads: \t%lu\n"
-			"bread_misses: \t%lu\n"
-
-			"search_by_key: \t%lu\n"
-			"search_by_key_fs_changed: \t%lu\n"
-			"search_by_key_restarted: \t%lu\n"
-			
-			"insert_item_restarted: \t%lu\n"
-			"paste_into_item_restarted: \t%lu\n"
-			"cut_from_item_restarted: \t%lu\n"
-			"delete_solid_item_restarted: \t%lu\n"
-			"delete_item_restarted: \t%lu\n"
-
-			"leaked_oid: \t%lu\n"
-			"leaves_removable: \t%lu\n",
-
-			SF( s_mount_state ) == REISERFS_VALID_FS ?
-			"REISERFS_VALID_FS" : "REISERFS_ERROR_FS",
-			reiserfs_r5_hash( sb ) ? "FORCE_R5 " : "",
-			reiserfs_rupasov_hash( sb ) ? "FORCE_RUPASOV " : "",
-			reiserfs_tea_hash( sb ) ? "FORCE_TEA " : "",
-			reiserfs_hash_detect( sb ) ? "DETECT_HASH " : "",
-			reiserfs_no_border( sb ) ? "NO_BORDER " : "BORDER ",
-			reiserfs_no_unhashed_relocation( sb ) ? "NO_UNHASHED_RELOCATION " : "",
-			reiserfs_hashed_relocation( sb ) ? "UNHASHED_RELOCATION " : "",
-			reiserfs_test4( sb ) ? "TEST4 " : "",
-			have_large_tails( sb ) ? "TAILS " : have_small_tails(sb)?"SMALL_TAILS ":"NO_TAILS ",
-			replay_only( sb ) ? "REPLAY_ONLY " : "",
-			convert_reiserfs( sb ) ? "CONV " : "",
-
-			atomic_read( &r -> s_generation_counter ),
-			SF( s_kmallocs ),
-			SF( s_disk_reads ),
-			SF( s_disk_writes ),
-			SF( s_fix_nodes ),
-			SF( s_do_balance ),
-			SF( s_unneeded_left_neighbor ),
-			SF( s_good_search_by_key_reada ),
-			SF( s_bmaps ),
-			SF( s_bmaps_without_search ),
-			SF( s_direct2indirect ),
-			SF( s_indirect2direct ),
-			SFP( max_hash_collisions ),
-			SFP( breads ),
-			SFP( bread_miss ),
-			SFP( search_by_key ),
-			SFP( search_by_key_fs_changed ),
-			SFP( search_by_key_restarted ),
-
-			SFP( insert_item_restarted ),
-			SFP( paste_into_item_restarted ),
-			SFP( cut_from_item_restarted ),
-			SFP( delete_solid_item_restarted ),
-			SFP( delete_item_restarted ),
 
-			SFP( leaked_oid ),
-			SFP( leaves_removable ) );
+	seq_printf(m, "state: \t%s\n"
+		   "mount options: \t%s%s%s%s%s%s%s%s%s%s%s\n"
+		   "gen. counter: \t%i\n"
+		   "s_kmallocs: \t%i\n"
+		   "s_disk_reads: \t%i\n"
+		   "s_disk_writes: \t%i\n"
+		   "s_fix_nodes: \t%i\n"
+		   "s_do_balance: \t%i\n"
+		   "s_unneeded_left_neighbor: \t%i\n"
+		   "s_good_search_by_key_reada: \t%i\n"
+		   "s_bmaps: \t%i\n"
+		   "s_bmaps_without_search: \t%i\n"
+		   "s_direct2indirect: \t%i\n"
+		   "s_indirect2direct: \t%i\n"
+		   "\n"
+		   "max_hash_collisions: \t%i\n"
+		   "breads: \t%lu\n"
+		   "bread_misses: \t%lu\n"
+		   "search_by_key: \t%lu\n"
+		   "search_by_key_fs_changed: \t%lu\n"
+		   "search_by_key_restarted: \t%lu\n"
+		   "insert_item_restarted: \t%lu\n"
+		   "paste_into_item_restarted: \t%lu\n"
+		   "cut_from_item_restarted: \t%lu\n"
+		   "delete_solid_item_restarted: \t%lu\n"
+		   "delete_item_restarted: \t%lu\n"
+		   "leaked_oid: \t%lu\n"
+		   "leaves_removable: \t%lu\n",
+		   SF(s_mount_state) == REISERFS_VALID_FS ?
+		   "REISERFS_VALID_FS" : "REISERFS_ERROR_FS",
+		   reiserfs_r5_hash(sb) ? "FORCE_R5 " : "",
+		   reiserfs_rupasov_hash(sb) ? "FORCE_RUPASOV " : "",
+		   reiserfs_tea_hash(sb) ? "FORCE_TEA " : "",
+		   reiserfs_hash_detect(sb) ? "DETECT_HASH " : "",
+		   reiserfs_no_border(sb) ? "NO_BORDER " : "BORDER ",
+		   reiserfs_no_unhashed_relocation(sb) ?
+		   "NO_UNHASHED_RELOCATION " : "",
+		   reiserfs_hashed_relocation(sb) ? "UNHASHED_RELOCATION " : "",
+		   reiserfs_test4(sb) ? "TEST4 " : "",
+		   have_large_tails(sb) ? "TAILS " : have_small_tails(sb) ?
+		   "SMALL_TAILS " : "NO_TAILS ",
+		   replay_only(sb) ? "REPLAY_ONLY " : "",
+		   convert_reiserfs(sb) ? "CONV " : "",
+		   atomic_read(&r->s_generation_counter), SF(s_kmallocs),
+		   SF(s_disk_reads), SF(s_disk_writes), SF(s_fix_nodes),
+		   SF(s_do_balance), SF(s_unneeded_left_neighbor),
+		   SF(s_good_search_by_key_reada), SF(s_bmaps),
+		   SF(s_bmaps_without_search), SF(s_direct2indirect),
+		   SF(s_indirect2direct), SFP(max_hash_collisions), SFP(breads),
+		   SFP(bread_miss), SFP(search_by_key),
+		   SFP(search_by_key_fs_changed), SFP(search_by_key_restarted),
+		   SFP(insert_item_restarted), SFP(paste_into_item_restarted),
+		   SFP(cut_from_item_restarted),
+		   SFP(delete_solid_item_restarted), SFP(delete_item_restarted),
+		   SFP(leaked_oid), SFP(leaves_removable));
 
 	return 0;
 }
@@ -169,61 +149,55 @@ static int show_per_level(struct seq_fil
 	struct reiserfs_sb_info *r = REISERFS_SB(sb);
 	int level;
 
-	seq_printf(m,	"level\t"
-			"     balances"
-			" [sbk:  reads"
-			"   fs_changed"
-			"   restarted]"
-			"   free space"
-			"        items"
-			"   can_remove"
-			"         lnum"
-			"         rnum"
-			"       lbytes"
-			"       rbytes"
-			"     get_neig"
-			" get_neig_res"
-			"  need_l_neig"
-			"  need_r_neig"
-			"\n"
-			
-		);
-
-	for( level = 0 ; level < MAX_HEIGHT ; ++ level ) {
-		seq_printf(m,	"%i\t"
-				" %12lu"
-				" %12lu"
-				" %12lu"
-				" %12lu"
-				" %12lu"
-				" %12lu"
-				" %12lu"
-				" %12li"
-				" %12li"
-				" %12li"
-				" %12li"
-				" %12lu"
-				" %12lu"
-				" %12lu"
-				" %12lu"
-				"\n",
-				level, 
-				SFPL( balance_at ),
-				SFPL( sbk_read_at ),
-				SFPL( sbk_fs_changed ),
-				SFPL( sbk_restarted ),
-				SFPL( free_at ),
-				SFPL( items_at ),
-				SFPL( can_node_be_removed ),
-				SFPL( lnum ),
-				SFPL( rnum ),
-				SFPL( lbytes ),
-				SFPL( rbytes ),
-				SFPL( get_neighbors ),
-				SFPL( get_neighbors_restart ),
-				SFPL( need_l_neighbor ),
-				SFPL( need_r_neighbor )
-			);
+	seq_printf(m, "level\t"
+		   "     balances"
+		   " [sbk:  reads"
+		   "   fs_changed"
+		   "   restarted]"
+		   "   free space"
+		   "        items"
+		   "   can_remove"
+		   "         lnum"
+		   "         rnum"
+		   "       lbytes"
+		   "       rbytes"
+		   "     get_neig"
+		   " get_neig_res" "  need_l_neig" "  need_r_neig" "\n");
+
+	for (level = 0; level < MAX_HEIGHT; ++level) {
+		seq_printf(m, "%i\t"
+			   " %12lu"
+			   " %12lu"
+			   " %12lu"
+			   " %12lu"
+			   " %12lu"
+			   " %12lu"
+			   " %12lu"
+			   " %12li"
+			   " %12li"
+			   " %12li"
+			   " %12li"
+			   " %12lu"
+			   " %12lu"
+			   " %12lu"
+			   " %12lu"
+			   "\n",
+			   level,
+			   SFPL(balance_at),
+			   SFPL(sbk_read_at),
+			   SFPL(sbk_fs_changed),
+			   SFPL(sbk_restarted),
+			   SFPL(free_at),
+			   SFPL(items_at),
+			   SFPL(can_node_be_removed),
+			   SFPL(lnum),
+			   SFPL(rnum),
+			   SFPL(lbytes),
+			   SFPL(rbytes),
+			   SFPL(get_neighbors),
+			   SFPL(get_neighbors_restart),
+			   SFPL(need_l_neighbor), SFPL(need_r_neighbor)
+		    );
 	}
 	return 0;
 }
@@ -232,31 +206,30 @@ static int show_bitmap(struct seq_file *
 {
 	struct reiserfs_sb_info *r = REISERFS_SB(sb);
 
-	seq_printf(m,	"free_block: %lu\n"
-			"  scan_bitmap:"
-			"          wait"
-			"          bmap"
-			"         retry"
-			"        stolen"
-			"  journal_hint"
-			"journal_nohint"
-			"\n"
-			" %14lu"
-			" %14lu"
-			" %14lu"
-			" %14lu"
-			" %14lu"
-			" %14lu"
-			" %14lu"
-			"\n",
-			SFP( free_block ),
-			SFPF( call ), 
-			SFPF( wait ), 
-			SFPF( bmap ),
-			SFPF( retry ),
-			SFPF( stolen ),
-			SFPF( in_journal_hint ),
-			SFPF( in_journal_nohint ) );
+	seq_printf(m, "free_block: %lu\n"
+		   "  scan_bitmap:"
+		   "          wait"
+		   "          bmap"
+		   "         retry"
+		   "        stolen"
+		   "  journal_hint"
+		   "journal_nohint"
+		   "\n"
+		   " %14lu"
+		   " %14lu"
+		   " %14lu"
+		   " %14lu"
+		   " %14lu"
+		   " %14lu"
+		   " %14lu"
+		   "\n",
+		   SFP(free_block),
+		   SFPF(call),
+		   SFPF(wait),
+		   SFPF(bmap),
+		   SFPF(retry),
+		   SFPF(stolen),
+		   SFPF(in_journal_hint), SFPF(in_journal_nohint));
 
 	return 0;
 }
@@ -264,46 +237,42 @@ static int show_bitmap(struct seq_file *
 static int show_on_disk_super(struct seq_file *m, struct super_block *sb)
 {
 	struct reiserfs_sb_info *sb_info = REISERFS_SB(sb);
-	struct reiserfs_super_block *rs = sb_info -> s_rs;
-	int hash_code = DFL( s_hash_function_code );
-	__u32 flags = DJF( s_flags );
-
-	seq_printf(m,	"block_count: \t%i\n"
-			"free_blocks: \t%i\n"
-			"root_block: \t%i\n"
-			"blocksize: \t%i\n"
-			"oid_maxsize: \t%i\n"
-			"oid_cursize: \t%i\n"
-			"umount_state: \t%i\n"
-			"magic: \t%10.10s\n"
-			"fs_state: \t%i\n"
-			"hash: \t%s\n"
-			"tree_height: \t%i\n"
-			"bmap_nr: \t%i\n"
-			"version: \t%i\n"
-			"flags: \t%x[%s]\n"
-			"reserved_for_journal: \t%i\n",
-
-			DFL( s_block_count ),
-			DFL( s_free_blocks ),
-			DFL( s_root_block ),
-			DF( s_blocksize ),
-			DF( s_oid_maxsize ),
-			DF( s_oid_cursize ),
-			DF( s_umount_state ),
-			rs -> s_v1.s_magic,
-			DF( s_fs_state ),
-			hash_code == TEA_HASH ? "tea" :
-			( hash_code == YURA_HASH ) ? "rupasov" :
-			( hash_code == R5_HASH ) ? "r5" :
-			( hash_code == UNSET_HASH ) ? "unset" : "unknown",
-			DF( s_tree_height ),
-			DF( s_bmap_nr ),
-			DF( s_version ),
-			flags,
-			( flags & reiserfs_attrs_cleared )
-			? "attrs_cleared" : "",
-			DF (s_reserved_for_journal));
+	struct reiserfs_super_block *rs = sb_info->s_rs;
+	int hash_code = DFL(s_hash_function_code);
+	__u32 flags = DJF(s_flags);
+
+	seq_printf(m, "block_count: \t%i\n"
+		   "free_blocks: \t%i\n"
+		   "root_block: \t%i\n"
+		   "blocksize: \t%i\n"
+		   "oid_maxsize: \t%i\n"
+		   "oid_cursize: \t%i\n"
+		   "umount_state: \t%i\n"
+		   "magic: \t%10.10s\n"
+		   "fs_state: \t%i\n"
+		   "hash: \t%s\n"
+		   "tree_height: \t%i\n"
+		   "bmap_nr: \t%i\n"
+		   "version: \t%i\n"
+		   "flags: \t%x[%s]\n"
+		   "reserved_for_journal: \t%i\n",
+		   DFL(s_block_count),
+		   DFL(s_free_blocks),
+		   DFL(s_root_block),
+		   DF(s_blocksize),
+		   DF(s_oid_maxsize),
+		   DF(s_oid_cursize),
+		   DF(s_umount_state),
+		   rs->s_v1.s_magic,
+		   DF(s_fs_state),
+		   hash_code == TEA_HASH ? "tea" :
+		   (hash_code == YURA_HASH) ? "rupasov" :
+		   (hash_code == R5_HASH) ? "r5" :
+		   (hash_code == UNSET_HASH) ? "unset" : "unknown",
+		   DF(s_tree_height),
+		   DF(s_bmap_nr),
+		   DF(s_version), flags, (flags & reiserfs_attrs_cleared)
+		   ? "attrs_cleared" : "", DF(s_reserved_for_journal));
 
 	return 0;
 }
@@ -311,131 +280,122 @@ static int show_on_disk_super(struct seq
 static int show_oidmap(struct seq_file *m, struct super_block *sb)
 {
 	struct reiserfs_sb_info *sb_info = REISERFS_SB(sb);
-	struct reiserfs_super_block *rs = sb_info -> s_rs;
-	unsigned int mapsize = le16_to_cpu( rs -> s_v1.s_oid_cursize );
+	struct reiserfs_super_block *rs = sb_info->s_rs;
+	unsigned int mapsize = le16_to_cpu(rs->s_v1.s_oid_cursize);
 	unsigned long total_used = 0;
 	int i;
 
-	for( i = 0 ; i < mapsize ; ++i ) {
+	for (i = 0; i < mapsize; ++i) {
 		__u32 right;
 
-		right = ( i == mapsize - 1 ) ? MAX_KEY_OBJECTID : MAP( i + 1 );
+		right = (i == mapsize - 1) ? MAX_KEY_OBJECTID : MAP(i + 1);
 		seq_printf(m, "%s: [ %x .. %x )\n",
-				( i & 1 ) ? "free" : "used", MAP( i ), right );
-		if( ! ( i & 1 ) ) {
-			total_used += right - MAP( i );
+			   (i & 1) ? "free" : "used", MAP(i), right);
+		if (!(i & 1)) {
+			total_used += right - MAP(i);
 		}
 	}
 #if defined( REISERFS_USE_OIDMAPF )
-	if( sb_info -> oidmap.use_file && ( sb_info -> oidmap.mapf != NULL ) ) {
+	if (sb_info->oidmap.use_file && (sb_info->oidmap.mapf != NULL)) {
 		loff_t size = sb_info->oidmap.mapf->f_dentry->d_inode->i_size;
-		total_used += size / sizeof( reiserfs_oidinterval_d_t );
+		total_used += size / sizeof(reiserfs_oidinterval_d_t);
 	}
 #endif
-	seq_printf(m, "total: \t%i [%i/%i] used: %lu [exact]\n", 
-			mapsize, 
-			mapsize, le16_to_cpu( rs -> s_v1.s_oid_maxsize ),
-			total_used);
+	seq_printf(m, "total: \t%i [%i/%i] used: %lu [exact]\n",
+		   mapsize,
+		   mapsize, le16_to_cpu(rs->s_v1.s_oid_maxsize), total_used);
 	return 0;
 }
 
 static int show_journal(struct seq_file *m, struct super_block *sb)
 {
 	struct reiserfs_sb_info *r = REISERFS_SB(sb);
-	struct reiserfs_super_block *rs = r -> s_rs;
+	struct reiserfs_super_block *rs = r->s_rs;
 	struct journal_params *jp = &rs->s_v1.s_journal;
 	char b[BDEVNAME_SIZE];
-    
 
-	seq_printf(m,	 /* on-disk fields */
- 			"jp_journal_1st_block: \t%i\n"
- 			"jp_journal_dev: \t%s[%x]\n"
- 			"jp_journal_size: \t%i\n"
- 			"jp_journal_trans_max: \t%i\n"
- 			"jp_journal_magic: \t%i\n"
- 			"jp_journal_max_batch: \t%i\n"
- 			"jp_journal_max_commit_age: \t%i\n"
- 			"jp_journal_max_trans_age: \t%i\n"
-			/* incore fields */
-			"j_1st_reserved_block: \t%i\n"	  
-			"j_state: \t%li\n"			
-			"j_trans_id: \t%lu\n"
-			"j_mount_id: \t%lu\n"
-			"j_start: \t%lu\n"
-			"j_len: \t%lu\n"
-			"j_len_alloc: \t%lu\n"
-			"j_wcount: \t%i\n"
-			"j_bcount: \t%lu\n"
-			"j_first_unflushed_offset: \t%lu\n"
-			"j_last_flush_trans_id: \t%lu\n"
-			"j_trans_start_time: \t%li\n"
-			"j_list_bitmap_index: \t%i\n"
-			"j_must_wait: \t%i\n"
-			"j_next_full_flush: \t%i\n"
-			"j_next_async_flush: \t%i\n"
-			"j_cnode_used: \t%i\n"
-			"j_cnode_free: \t%i\n"
-			"\n"
-			/* reiserfs_proc_info_data_t.journal fields */
-			"in_journal: \t%12lu\n"
-			"in_journal_bitmap: \t%12lu\n"
-			"in_journal_reusable: \t%12lu\n"
-			"lock_journal: \t%12lu\n"
-			"lock_journal_wait: \t%12lu\n"
-			"journal_begin: \t%12lu\n"
-			"journal_relock_writers: \t%12lu\n"
-			"journal_relock_wcount: \t%12lu\n"
-			"mark_dirty: \t%12lu\n"
-			"mark_dirty_already: \t%12lu\n"
-			"mark_dirty_notjournal: \t%12lu\n"
-			"restore_prepared: \t%12lu\n"
-			"prepare: \t%12lu\n"
-			"prepare_retry: \t%12lu\n",
-
-                        DJP( jp_journal_1st_block ),
-                        bdevname(SB_JOURNAL(sb)->j_dev_bd, b),
-                        DJP( jp_journal_dev ),
-                        DJP( jp_journal_size ),
-                        DJP( jp_journal_trans_max ),
-                        DJP( jp_journal_magic ),
-                        DJP( jp_journal_max_batch ),
-			SB_JOURNAL(sb)->j_max_commit_age,
-                        DJP( jp_journal_max_trans_age ),
-
-			JF( j_1st_reserved_block ),			
-			JF( j_state ),			
-			JF( j_trans_id ),
-			JF( j_mount_id ),
-			JF( j_start ),
-			JF( j_len ),
-			JF( j_len_alloc ),
-			atomic_read( & r -> s_journal -> j_wcount ),
-			JF( j_bcount ),
-			JF( j_first_unflushed_offset ),
-			JF( j_last_flush_trans_id ),
-			JF( j_trans_start_time ),
-			JF( j_list_bitmap_index ),
-			JF( j_must_wait ),
-			JF( j_next_full_flush ),
-			JF( j_next_async_flush ),
-			JF( j_cnode_used ),
-			JF( j_cnode_free ),
-
-			SFPJ( in_journal ),
-			SFPJ( in_journal_bitmap ),
-			SFPJ( in_journal_reusable ),
-			SFPJ( lock_journal ),
-			SFPJ( lock_journal_wait ),
-			SFPJ( journal_being ),
-			SFPJ( journal_relock_writers ),
-			SFPJ( journal_relock_wcount ),
-			SFPJ( mark_dirty ),
-			SFPJ( mark_dirty_already ),
-			SFPJ( mark_dirty_notjournal ),
-			SFPJ( restore_prepared ),
-			SFPJ( prepare ),
-			SFPJ( prepare_retry )
-		);
+	seq_printf(m,		/* on-disk fields */
+		   "jp_journal_1st_block: \t%i\n"
+		   "jp_journal_dev: \t%s[%x]\n"
+		   "jp_journal_size: \t%i\n"
+		   "jp_journal_trans_max: \t%i\n"
+		   "jp_journal_magic: \t%i\n"
+		   "jp_journal_max_batch: \t%i\n"
+		   "jp_journal_max_commit_age: \t%i\n"
+		   "jp_journal_max_trans_age: \t%i\n"
+		   /* incore fields */
+		   "j_1st_reserved_block: \t%i\n"
+		   "j_state: \t%li\n"
+		   "j_trans_id: \t%lu\n"
+		   "j_mount_id: \t%lu\n"
+		   "j_start: \t%lu\n"
+		   "j_len: \t%lu\n"
+		   "j_len_alloc: \t%lu\n"
+		   "j_wcount: \t%i\n"
+		   "j_bcount: \t%lu\n"
+		   "j_first_unflushed_offset: \t%lu\n"
+		   "j_last_flush_trans_id: \t%lu\n"
+		   "j_trans_start_time: \t%li\n"
+		   "j_list_bitmap_index: \t%i\n"
+		   "j_must_wait: \t%i\n"
+		   "j_next_full_flush: \t%i\n"
+		   "j_next_async_flush: \t%i\n"
+		   "j_cnode_used: \t%i\n" "j_cnode_free: \t%i\n" "\n"
+		   /* reiserfs_proc_info_data_t.journal fields */
+		   "in_journal: \t%12lu\n"
+		   "in_journal_bitmap: \t%12lu\n"
+		   "in_journal_reusable: \t%12lu\n"
+		   "lock_journal: \t%12lu\n"
+		   "lock_journal_wait: \t%12lu\n"
+		   "journal_begin: \t%12lu\n"
+		   "journal_relock_writers: \t%12lu\n"
+		   "journal_relock_wcount: \t%12lu\n"
+		   "mark_dirty: \t%12lu\n"
+		   "mark_dirty_already: \t%12lu\n"
+		   "mark_dirty_notjournal: \t%12lu\n"
+		   "restore_prepared: \t%12lu\n"
+		   "prepare: \t%12lu\n"
+		   "prepare_retry: \t%12lu\n",
+		   DJP(jp_journal_1st_block),
+		   bdevname(SB_JOURNAL(sb)->j_dev_bd, b),
+		   DJP(jp_journal_dev),
+		   DJP(jp_journal_size),
+		   DJP(jp_journal_trans_max),
+		   DJP(jp_journal_magic),
+		   DJP(jp_journal_max_batch),
+		   SB_JOURNAL(sb)->j_max_commit_age,
+		   DJP(jp_journal_max_trans_age),
+		   JF(j_1st_reserved_block),
+		   JF(j_state),
+		   JF(j_trans_id),
+		   JF(j_mount_id),
+		   JF(j_start),
+		   JF(j_len),
+		   JF(j_len_alloc),
+		   atomic_read(&r->s_journal->j_wcount),
+		   JF(j_bcount),
+		   JF(j_first_unflushed_offset),
+		   JF(j_last_flush_trans_id),
+		   JF(j_trans_start_time),
+		   JF(j_list_bitmap_index),
+		   JF(j_must_wait),
+		   JF(j_next_full_flush),
+		   JF(j_next_async_flush),
+		   JF(j_cnode_used),
+		   JF(j_cnode_free),
+		   SFPJ(in_journal),
+		   SFPJ(in_journal_bitmap),
+		   SFPJ(in_journal_reusable),
+		   SFPJ(lock_journal),
+		   SFPJ(lock_journal_wait),
+		   SFPJ(journal_being),
+		   SFPJ(journal_relock_writers),
+		   SFPJ(journal_relock_wcount),
+		   SFPJ(mark_dirty),
+		   SFPJ(mark_dirty_already),
+		   SFPJ(mark_dirty_notjournal),
+		   SFPJ(restore_prepared), SFPJ(prepare), SFPJ(prepare_retry)
+	    );
 	return 0;
 }
 
@@ -450,7 +410,7 @@ static int set_sb(struct super_block *sb
 	return -ENOENT;
 }
 
-static void *r_start(struct seq_file *m, loff_t *pos)
+static void *r_start(struct seq_file *m, loff_t * pos)
 {
 	struct proc_dir_entry *de = m->private;
 	struct super_block *s = de->parent->data;
@@ -472,7 +432,7 @@ static void *r_start(struct seq_file *m,
 	return s;
 }
 
-static void *r_next(struct seq_file *m, void *v, loff_t *pos)
+static void *r_next(struct seq_file *m, void *v, loff_t * pos)
 {
 	++*pos;
 	if (v)
@@ -489,7 +449,7 @@ static void r_stop(struct seq_file *m, v
 static int r_show(struct seq_file *m, void *v)
 {
 	struct proc_dir_entry *de = m->private;
-	int (*show)(struct seq_file *, struct super_block *) = de->data;
+	int (*show) (struct seq_file *, struct super_block *) = de->data;
 	return show(m, v);
 }
 
@@ -512,17 +472,17 @@ static int r_open(struct inode *inode, s
 }
 
 static struct file_operations r_file_operations = {
-	.open		= r_open,
-	.read		= seq_read,
-	.llseek		= seq_lseek,
-	.release	= seq_release,
+	.open = r_open,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = seq_release,
 };
 
 static struct proc_dir_entry *proc_info_root = NULL;
 static const char proc_info_root_name[] = "fs/reiserfs";
 
 static void add_file(struct super_block *sb, char *name,
-	int (*func)(struct seq_file *, struct super_block *))
+		     int (*func) (struct seq_file *, struct super_block *))
 {
 	struct proc_dir_entry *de;
 	de = create_proc_entry(name, 0, REISERFS_SB(sb)->procdir);
@@ -532,11 +492,12 @@ static void add_file(struct super_block 
 	}
 }
 
-int reiserfs_proc_info_init( struct super_block *sb )
+int reiserfs_proc_info_init(struct super_block *sb)
 {
-	spin_lock_init( & __PINFO( sb ).lock );
-	REISERFS_SB(sb)->procdir = proc_mkdir(reiserfs_bdevname (sb), proc_info_root);
-	if( REISERFS_SB(sb)->procdir ) {
+	spin_lock_init(&__PINFO(sb).lock);
+	REISERFS_SB(sb)->procdir =
+	    proc_mkdir(reiserfs_bdevname(sb), proc_info_root);
+	if (REISERFS_SB(sb)->procdir) {
 		REISERFS_SB(sb)->procdir->owner = THIS_MODULE;
 		REISERFS_SB(sb)->procdir->data = sb;
 		add_file(sb, "version", show_version);
@@ -549,11 +510,11 @@ int reiserfs_proc_info_init( struct supe
 		return 0;
 	}
 	reiserfs_warning(sb, "reiserfs: cannot create /proc/%s/%s",
-			 proc_info_root_name, reiserfs_bdevname (sb) );
+			 proc_info_root_name, reiserfs_bdevname(sb));
 	return 1;
 }
 
-int reiserfs_proc_info_done( struct super_block *sb )
+int reiserfs_proc_info_done(struct super_block *sb)
 {
 	struct proc_dir_entry *de = REISERFS_SB(sb)->procdir;
 	if (de) {
@@ -565,48 +526,48 @@ int reiserfs_proc_info_done( struct supe
 		remove_proc_entry("super", de);
 		remove_proc_entry("version", de);
 	}
-	spin_lock( & __PINFO( sb ).lock );
-	__PINFO( sb ).exiting = 1;
-	spin_unlock( & __PINFO( sb ).lock );
-	if ( proc_info_root ) {
-		remove_proc_entry( reiserfs_bdevname (sb), proc_info_root );
+	spin_lock(&__PINFO(sb).lock);
+	__PINFO(sb).exiting = 1;
+	spin_unlock(&__PINFO(sb).lock);
+	if (proc_info_root) {
+		remove_proc_entry(reiserfs_bdevname(sb), proc_info_root);
 		REISERFS_SB(sb)->procdir = NULL;
 	}
 	return 0;
 }
 
-struct proc_dir_entry *reiserfs_proc_register_global( char *name, 
-						      read_proc_t *func )
+struct proc_dir_entry *reiserfs_proc_register_global(char *name,
+						     read_proc_t * func)
 {
-	return ( proc_info_root ) ? create_proc_read_entry( name, 0, 
-							    proc_info_root, 
-							    func, NULL ) : NULL;
+	return (proc_info_root) ? create_proc_read_entry(name, 0,
+							 proc_info_root,
+							 func, NULL) : NULL;
 }
 
-void reiserfs_proc_unregister_global( const char *name )
+void reiserfs_proc_unregister_global(const char *name)
 {
-	remove_proc_entry( name, proc_info_root );
+	remove_proc_entry(name, proc_info_root);
 }
 
-int reiserfs_proc_info_global_init( void )
+int reiserfs_proc_info_global_init(void)
 {
-	if( proc_info_root == NULL ) {
+	if (proc_info_root == NULL) {
 		proc_info_root = proc_mkdir(proc_info_root_name, NULL);
-		if( proc_info_root ) {
-			proc_info_root -> owner = THIS_MODULE;
+		if (proc_info_root) {
+			proc_info_root->owner = THIS_MODULE;
 		} else {
-			reiserfs_warning (NULL,
-					  "reiserfs: cannot create /proc/%s",
-					  proc_info_root_name );
+			reiserfs_warning(NULL,
+					 "reiserfs: cannot create /proc/%s",
+					 proc_info_root_name);
 			return 1;
 		}
 	}
 	return 0;
 }
 
-int reiserfs_proc_info_global_done( void )
+int reiserfs_proc_info_global_done(void)
 {
-	if ( proc_info_root != NULL ) {
+	if (proc_info_root != NULL) {
 		proc_info_root = NULL;
 		remove_proc_entry(proc_info_root_name, NULL);
 	}
@@ -616,22 +577,40 @@ int reiserfs_proc_info_global_done( void
 /* REISERFS_PROC_INFO */
 #else
 
-int reiserfs_proc_info_init( struct super_block *sb ) { return 0; }
-int reiserfs_proc_info_done( struct super_block *sb ) { return 0; }
+int reiserfs_proc_info_init(struct super_block *sb)
+{
+	return 0;
+}
+int reiserfs_proc_info_done(struct super_block *sb)
+{
+	return 0;
+}
+
+struct proc_dir_entry *reiserfs_proc_register_global(char *name,
+						     read_proc_t * func)
+{
+	return NULL;
+}
 
-struct proc_dir_entry *reiserfs_proc_register_global( char *name, 
-						      read_proc_t *func )
-{ return NULL; }
-
-void reiserfs_proc_unregister_global( const char *name ) {;}
-
-int reiserfs_proc_info_global_init( void ) { return 0; }
-int reiserfs_proc_info_global_done( void ) { return 0; }
-
-int reiserfs_global_version_in_proc( char *buffer, char **start, 
-				     off_t offset,
-				     int count, int *eof, void *data )
-{ return 0; }
+void reiserfs_proc_unregister_global(const char *name)
+{;
+}
+
+int reiserfs_proc_info_global_init(void)
+{
+	return 0;
+}
+int reiserfs_proc_info_global_done(void)
+{
+	return 0;
+}
+
+int reiserfs_global_version_in_proc(char *buffer, char **start,
+				    off_t offset,
+				    int count, int *eof, void *data)
+{
+	return 0;
+}
 
 /* REISERFS_PROC_INFO */
 #endif
diff --git a/fs/reiserfs/resize.c b/fs/reiserfs/resize.c
--- a/fs/reiserfs/resize.c
+++ b/fs/reiserfs/resize.c
@@ -1,7 +1,7 @@
 /* 
  * Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README
  */
- 
+
 /* 
  * Written by Alexander Zarochentcev.
  *
@@ -17,23 +17,23 @@
 #include <linux/reiserfs_fs_sb.h>
 #include <linux/buffer_head.h>
 
-int reiserfs_resize (struct super_block * s, unsigned long block_count_new)
+int reiserfs_resize(struct super_block *s, unsigned long block_count_new)
 {
-        int err = 0;
-	struct reiserfs_super_block * sb;
-        struct reiserfs_bitmap_info *bitmap;
+	int err = 0;
+	struct reiserfs_super_block *sb;
+	struct reiserfs_bitmap_info *bitmap;
 	struct reiserfs_bitmap_info *old_bitmap = SB_AP_BITMAP(s);
-	struct buffer_head * bh;
+	struct buffer_head *bh;
 	struct reiserfs_transaction_handle th;
 	unsigned int bmap_nr_new, bmap_nr;
 	unsigned int block_r_new, block_r;
-	
-	struct reiserfs_list_bitmap * jb;
+
+	struct reiserfs_list_bitmap *jb;
 	struct reiserfs_list_bitmap jbitmap[JOURNAL_NUM_BITMAPS];
-	
+
 	unsigned long int block_count, free_blocks;
 	int i;
-	int copy_size ;
+	int copy_size;
 
 	sb = SB_DISK_SUPER_BLOCK(s);
 
@@ -47,136 +47,145 @@ int reiserfs_resize (struct super_block 
 	if (!bh) {
 		printk("reiserfs_resize: can\'t read last block\n");
 		return -EINVAL;
-	}	
+	}
 	bforget(bh);
 
 	/* old disk layout detection; those partitions can be mounted, but
 	 * cannot be resized */
-	if (SB_BUFFER_WITH_SB(s)->b_blocknr *	SB_BUFFER_WITH_SB(s)->b_size 
-		!= REISERFS_DISK_OFFSET_IN_BYTES ) {
-		printk("reiserfs_resize: unable to resize a reiserfs without distributed bitmap (fs version < 3.5.12)\n");
+	if (SB_BUFFER_WITH_SB(s)->b_blocknr * SB_BUFFER_WITH_SB(s)->b_size
+	    != REISERFS_DISK_OFFSET_IN_BYTES) {
+		printk
+		    ("reiserfs_resize: unable to resize a reiserfs without distributed bitmap (fs version < 3.5.12)\n");
 		return -ENOTSUPP;
 	}
-       
+
 	/* count used bits in last bitmap block */
-	block_r = SB_BLOCK_COUNT(s) -
-	        (SB_BMAP_NR(s) - 1) * s->s_blocksize * 8;
-	
+	block_r = SB_BLOCK_COUNT(s) - (SB_BMAP_NR(s) - 1) * s->s_blocksize * 8;
+
 	/* count bitmap blocks in new fs */
-	bmap_nr_new = block_count_new / ( s->s_blocksize * 8 );
+	bmap_nr_new = block_count_new / (s->s_blocksize * 8);
 	block_r_new = block_count_new - bmap_nr_new * s->s_blocksize * 8;
-	if (block_r_new) 
+	if (block_r_new)
 		bmap_nr_new++;
 	else
 		block_r_new = s->s_blocksize * 8;
 
 	/* save old values */
 	block_count = SB_BLOCK_COUNT(s);
-	bmap_nr     = SB_BMAP_NR(s);
+	bmap_nr = SB_BMAP_NR(s);
 
 	/* resizing of reiserfs bitmaps (journal and real), if needed */
-	if (bmap_nr_new > bmap_nr) {	    
-	    /* reallocate journal bitmaps */
-	    if (reiserfs_allocate_list_bitmaps(s, jbitmap, bmap_nr_new) < 0) {
-		printk("reiserfs_resize: unable to allocate memory for journal bitmaps\n");
-		unlock_super(s) ;
-		return -ENOMEM ;
-	    }
-	    /* the new journal bitmaps are zero filled, now we copy in the bitmap
-	    ** node pointers from the old journal bitmap structs, and then
-	    ** transfer the new data structures into the journal struct.
-	    **
-	    ** using the copy_size var below allows this code to work for
-	    ** both shrinking and expanding the FS.
-	    */
-	    copy_size = bmap_nr_new < bmap_nr ? bmap_nr_new : bmap_nr ;
-	    copy_size = copy_size * sizeof(struct reiserfs_list_bitmap_node *) ;
-	    for (i = 0 ; i < JOURNAL_NUM_BITMAPS ; i++) {
-		struct reiserfs_bitmap_node **node_tmp ;
-		jb = SB_JOURNAL(s)->j_list_bitmap + i ;
-		memcpy(jbitmap[i].bitmaps, jb->bitmaps, copy_size) ;
-
-		/* just in case vfree schedules on us, copy the new
-		** pointer into the journal struct before freeing the 
-		** old one
-		*/
-		node_tmp = jb->bitmaps ;
-		jb->bitmaps = jbitmap[i].bitmaps ;
-		vfree(node_tmp) ;
-	    }	
-	
-	    /* allocate additional bitmap blocks, reallocate array of bitmap
-	     * block pointers */
-	    bitmap = vmalloc(sizeof(struct reiserfs_bitmap_info) * bmap_nr_new);
-	    if (!bitmap) {
-		/* Journal bitmaps are still supersized, but the memory isn't
-		 * leaked, so I guess it's ok */
-		printk("reiserfs_resize: unable to allocate memory.\n");
-		return -ENOMEM;
-	    }
-	    memset (bitmap, 0, sizeof (struct reiserfs_bitmap_info) * SB_BMAP_NR(s));
-	    for (i = 0; i < bmap_nr; i++)
-		bitmap[i] = old_bitmap[i];
-
-	    /* This doesn't go through the journal, but it doesn't have to.
-	     * The changes are still atomic: We're synced up when the journal
-	     * transaction begins, and the new bitmaps don't matter if the
-	     * transaction fails. */
-	    for (i = bmap_nr; i < bmap_nr_new; i++) {
-		bitmap[i].bh = sb_getblk(s, i * s->s_blocksize * 8);
-		memset(bitmap[i].bh->b_data, 0, sb_blocksize(sb));
-		reiserfs_test_and_set_le_bit(0, bitmap[i].bh->b_data);
-
-		set_buffer_uptodate(bitmap[i].bh);
-		mark_buffer_dirty(bitmap[i].bh) ;
-		sync_dirty_buffer(bitmap[i].bh);
-		// update bitmap_info stuff
-		bitmap[i].first_zero_hint=1;
-		bitmap[i].free_count = sb_blocksize(sb) * 8 - 1;
-	    }	
-	    /* free old bitmap blocks array */
-	    SB_AP_BITMAP(s) = bitmap;
-	    vfree (old_bitmap);
+	if (bmap_nr_new > bmap_nr) {
+		/* reallocate journal bitmaps */
+		if (reiserfs_allocate_list_bitmaps(s, jbitmap, bmap_nr_new) < 0) {
+			printk
+			    ("reiserfs_resize: unable to allocate memory for journal bitmaps\n");
+			unlock_super(s);
+			return -ENOMEM;
+		}
+		/* the new journal bitmaps are zero filled, now we copy in the bitmap
+		 ** node pointers from the old journal bitmap structs, and then
+		 ** transfer the new data structures into the journal struct.
+		 **
+		 ** using the copy_size var below allows this code to work for
+		 ** both shrinking and expanding the FS.
+		 */
+		copy_size = bmap_nr_new < bmap_nr ? bmap_nr_new : bmap_nr;
+		copy_size =
+		    copy_size * sizeof(struct reiserfs_list_bitmap_node *);
+		for (i = 0; i < JOURNAL_NUM_BITMAPS; i++) {
+			struct reiserfs_bitmap_node **node_tmp;
+			jb = SB_JOURNAL(s)->j_list_bitmap + i;
+			memcpy(jbitmap[i].bitmaps, jb->bitmaps, copy_size);
+
+			/* just in case vfree schedules on us, copy the new
+			 ** pointer into the journal struct before freeing the 
+			 ** old one
+			 */
+			node_tmp = jb->bitmaps;
+			jb->bitmaps = jbitmap[i].bitmaps;
+			vfree(node_tmp);
+		}
+
+		/* allocate additional bitmap blocks, reallocate array of bitmap
+		 * block pointers */
+		bitmap =
+		    vmalloc(sizeof(struct reiserfs_bitmap_info) * bmap_nr_new);
+		if (!bitmap) {
+			/* Journal bitmaps are still supersized, but the memory isn't
+			 * leaked, so I guess it's ok */
+			printk("reiserfs_resize: unable to allocate memory.\n");
+			return -ENOMEM;
+		}
+		memset(bitmap, 0,
+		       sizeof(struct reiserfs_bitmap_info) * SB_BMAP_NR(s));
+		for (i = 0; i < bmap_nr; i++)
+			bitmap[i] = old_bitmap[i];
+
+		/* This doesn't go through the journal, but it doesn't have to.
+		 * The changes are still atomic: We're synced up when the journal
+		 * transaction begins, and the new bitmaps don't matter if the
+		 * transaction fails. */
+		for (i = bmap_nr; i < bmap_nr_new; i++) {
+			bitmap[i].bh = sb_getblk(s, i * s->s_blocksize * 8);
+			memset(bitmap[i].bh->b_data, 0, sb_blocksize(sb));
+			reiserfs_test_and_set_le_bit(0, bitmap[i].bh->b_data);
+
+			set_buffer_uptodate(bitmap[i].bh);
+			mark_buffer_dirty(bitmap[i].bh);
+			sync_dirty_buffer(bitmap[i].bh);
+			// update bitmap_info stuff
+			bitmap[i].first_zero_hint = 1;
+			bitmap[i].free_count = sb_blocksize(sb) * 8 - 1;
+		}
+		/* free old bitmap blocks array */
+		SB_AP_BITMAP(s) = bitmap;
+		vfree(old_bitmap);
 	}
-	
+
 	/* begin transaction, if there was an error, it's fine. Yes, we have
 	 * incorrect bitmaps now, but none of it is ever going to touch the
 	 * disk anyway. */
 	err = journal_begin(&th, s, 10);
 	if (err)
-	    return err;
+		return err;
 
 	/* correct last bitmap blocks in old and new disk layout */
 	reiserfs_prepare_for_journal(s, SB_AP_BITMAP(s)[bmap_nr - 1].bh, 1);
 	for (i = block_r; i < s->s_blocksize * 8; i++)
-	    reiserfs_test_and_clear_le_bit(i, 
-					   SB_AP_BITMAP(s)[bmap_nr - 1].bh->b_data);
+		reiserfs_test_and_clear_le_bit(i,
+					       SB_AP_BITMAP(s)[bmap_nr -
+							       1].bh->b_data);
 	SB_AP_BITMAP(s)[bmap_nr - 1].free_count += s->s_blocksize * 8 - block_r;
-	if ( !SB_AP_BITMAP(s)[bmap_nr - 1].first_zero_hint)
-	    SB_AP_BITMAP(s)[bmap_nr - 1].first_zero_hint = block_r;
+	if (!SB_AP_BITMAP(s)[bmap_nr - 1].first_zero_hint)
+		SB_AP_BITMAP(s)[bmap_nr - 1].first_zero_hint = block_r;
 
 	journal_mark_dirty(&th, s, SB_AP_BITMAP(s)[bmap_nr - 1].bh);
 
 	reiserfs_prepare_for_journal(s, SB_AP_BITMAP(s)[bmap_nr_new - 1].bh, 1);
 	for (i = block_r_new; i < s->s_blocksize * 8; i++)
-	    reiserfs_test_and_set_le_bit(i,
-					 SB_AP_BITMAP(s)[bmap_nr_new - 1].bh->b_data);
+		reiserfs_test_and_set_le_bit(i,
+					     SB_AP_BITMAP(s)[bmap_nr_new -
+							     1].bh->b_data);
 	journal_mark_dirty(&th, s, SB_AP_BITMAP(s)[bmap_nr_new - 1].bh);
- 
-	SB_AP_BITMAP(s)[bmap_nr_new - 1].free_count -= s->s_blocksize * 8 - block_r_new;
+
+	SB_AP_BITMAP(s)[bmap_nr_new - 1].free_count -=
+	    s->s_blocksize * 8 - block_r_new;
 	/* Extreme case where last bitmap is the only valid block in itself. */
-	if ( !SB_AP_BITMAP(s)[bmap_nr_new - 1].free_count )
-	    SB_AP_BITMAP(s)[bmap_nr_new - 1].first_zero_hint = 0;
- 	/* update super */
-	reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1) ;
+	if (!SB_AP_BITMAP(s)[bmap_nr_new - 1].free_count)
+		SB_AP_BITMAP(s)[bmap_nr_new - 1].first_zero_hint = 0;
+	/* update super */
+	reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1);
 	free_blocks = SB_FREE_BLOCKS(s);
-	PUT_SB_FREE_BLOCKS(s, free_blocks + (block_count_new - block_count - (bmap_nr_new - bmap_nr)));
+	PUT_SB_FREE_BLOCKS(s,
+			   free_blocks + (block_count_new - block_count -
+					  (bmap_nr_new - bmap_nr)));
 	PUT_SB_BLOCK_COUNT(s, block_count_new);
 	PUT_SB_BMAP_NR(s, bmap_nr_new);
 	s->s_dirt = 1;
 
 	journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB(s));
-	
+
 	SB_JOURNAL(s)->j_must_wait = 1;
 	return journal_end(&th, s, 10);
 }
diff --git a/fs/reiserfs/stree.c b/fs/reiserfs/stree.c
--- a/fs/reiserfs/stree.c
+++ b/fs/reiserfs/stree.c
@@ -59,46 +59,45 @@
 #include <linux/quotaops.h>
 
 /* Does the buffer contain a disk block which is in the tree. */
-inline int B_IS_IN_TREE (const struct buffer_head * p_s_bh)
+inline int B_IS_IN_TREE(const struct buffer_head *p_s_bh)
 {
 
-  RFALSE( B_LEVEL (p_s_bh) > MAX_HEIGHT,
-	  "PAP-1010: block (%b) has too big level (%z)", p_s_bh, p_s_bh);
+	RFALSE(B_LEVEL(p_s_bh) > MAX_HEIGHT,
+	       "PAP-1010: block (%b) has too big level (%z)", p_s_bh, p_s_bh);
 
-  return ( B_LEVEL (p_s_bh) != FREE_LEVEL );
+	return (B_LEVEL(p_s_bh) != FREE_LEVEL);
 }
 
 //
 // to gets item head in le form
 //
-inline void copy_item_head(struct item_head * p_v_to, 
-			   const struct item_head * p_v_from)
+inline void copy_item_head(struct item_head *p_v_to,
+			   const struct item_head *p_v_from)
 {
-  memcpy (p_v_to, p_v_from, IH_SIZE);
+	memcpy(p_v_to, p_v_from, IH_SIZE);
 }
 
-
 /* k1 is pointer to on-disk structure which is stored in little-endian
    form. k2 is pointer to cpu variable. For key of items of the same
    object this returns 0.
    Returns: -1 if key1 < key2 
    0 if key1 == key2
    1 if key1 > key2 */
-inline int  comp_short_keys (const struct reiserfs_key * le_key,
-			     const struct cpu_key * cpu_key)
+inline int comp_short_keys(const struct reiserfs_key *le_key,
+			   const struct cpu_key *cpu_key)
 {
-  __u32 n;
-  n = le32_to_cpu(le_key->k_dir_id);
-  if (n < cpu_key->on_disk_key.k_dir_id)
-      return -1;
-  if (n > cpu_key->on_disk_key.k_dir_id)
-      return 1;
-  n = le32_to_cpu(le_key->k_objectid);
-  if (n < cpu_key->on_disk_key.k_objectid)
-      return -1;
-  if (n > cpu_key->on_disk_key.k_objectid)
-      return 1;
-  return 0;
+	__u32 n;
+	n = le32_to_cpu(le_key->k_dir_id);
+	if (n < cpu_key->on_disk_key.k_dir_id)
+		return -1;
+	if (n > cpu_key->on_disk_key.k_dir_id)
+		return 1;
+	n = le32_to_cpu(le_key->k_objectid);
+	if (n < cpu_key->on_disk_key.k_objectid)
+		return -1;
+	if (n > cpu_key->on_disk_key.k_objectid)
+		return 1;
+	return 0;
 }
 
 /* k1 is pointer to on-disk structure which is stored in little-endian
@@ -106,68 +105,72 @@ inline int  comp_short_keys (const struc
    Compare keys using all 4 key fields.
    Returns: -1 if key1 < key2 0
    if key1 = key2 1 if key1 > key2 */
-static inline int  comp_keys (const struct reiserfs_key * le_key, const struct cpu_key * cpu_key)
+static inline int comp_keys(const struct reiserfs_key *le_key,
+			    const struct cpu_key *cpu_key)
 {
-  int retval;
-
-  retval = comp_short_keys (le_key, cpu_key);
-  if (retval)
-      return retval;
-  if (le_key_k_offset (le_key_version(le_key), le_key) < cpu_key_k_offset (cpu_key))
-      return -1;
-  if (le_key_k_offset (le_key_version(le_key), le_key) > cpu_key_k_offset (cpu_key))
-      return 1;
-
-  if (cpu_key->key_length == 3)
-      return 0;
+	int retval;
 
-  /* this part is needed only when tail conversion is in progress */
-  if (le_key_k_type (le_key_version(le_key), le_key) < cpu_key_k_type (cpu_key))
-    return -1;
+	retval = comp_short_keys(le_key, cpu_key);
+	if (retval)
+		return retval;
+	if (le_key_k_offset(le_key_version(le_key), le_key) <
+	    cpu_key_k_offset(cpu_key))
+		return -1;
+	if (le_key_k_offset(le_key_version(le_key), le_key) >
+	    cpu_key_k_offset(cpu_key))
+		return 1;
+
+	if (cpu_key->key_length == 3)
+		return 0;
+
+	/* this part is needed only when tail conversion is in progress */
+	if (le_key_k_type(le_key_version(le_key), le_key) <
+	    cpu_key_k_type(cpu_key))
+		return -1;
+
+	if (le_key_k_type(le_key_version(le_key), le_key) >
+	    cpu_key_k_type(cpu_key))
+		return 1;
 
-  if (le_key_k_type (le_key_version(le_key), le_key) > cpu_key_k_type (cpu_key))
-    return 1;
-
-  return 0;
+	return 0;
 }
 
-
-inline int comp_short_le_keys (const struct reiserfs_key * key1, const struct reiserfs_key * key2)
+inline int comp_short_le_keys(const struct reiserfs_key *key1,
+			      const struct reiserfs_key *key2)
 {
-  __u32 * p_s_1_u32, * p_s_2_u32;
-  int n_key_length = REISERFS_SHORT_KEY_LEN;
+	__u32 *p_s_1_u32, *p_s_2_u32;
+	int n_key_length = REISERFS_SHORT_KEY_LEN;
 
-  p_s_1_u32 = (__u32 *)key1;
-  p_s_2_u32 = (__u32 *)key2;
-  for( ; n_key_length--; ++p_s_1_u32, ++p_s_2_u32 ) {
-    if ( le32_to_cpu (*p_s_1_u32) < le32_to_cpu (*p_s_2_u32) )
-      return -1;
-    if ( le32_to_cpu (*p_s_1_u32) > le32_to_cpu (*p_s_2_u32) )
-      return 1;
-  }
-  return 0;
+	p_s_1_u32 = (__u32 *) key1;
+	p_s_2_u32 = (__u32 *) key2;
+	for (; n_key_length--; ++p_s_1_u32, ++p_s_2_u32) {
+		if (le32_to_cpu(*p_s_1_u32) < le32_to_cpu(*p_s_2_u32))
+			return -1;
+		if (le32_to_cpu(*p_s_1_u32) > le32_to_cpu(*p_s_2_u32))
+			return 1;
+	}
+	return 0;
 }
 
-inline void le_key2cpu_key (struct cpu_key * to, const struct reiserfs_key * from)
+inline void le_key2cpu_key(struct cpu_key *to, const struct reiserfs_key *from)
 {
-    int version;
-    to->on_disk_key.k_dir_id = le32_to_cpu (from->k_dir_id);
-    to->on_disk_key.k_objectid = le32_to_cpu (from->k_objectid);
-    
-    // find out version of the key
-    version = le_key_version (from);
-    to->version = version;
-    to->on_disk_key.k_offset = le_key_k_offset(version, from);
-    to->on_disk_key.k_type = le_key_k_type(version, from);
+	int version;
+	to->on_disk_key.k_dir_id = le32_to_cpu(from->k_dir_id);
+	to->on_disk_key.k_objectid = le32_to_cpu(from->k_objectid);
+
+	// find out version of the key
+	version = le_key_version(from);
+	to->version = version;
+	to->on_disk_key.k_offset = le_key_k_offset(version, from);
+	to->on_disk_key.k_type = le_key_k_type(version, from);
 }
 
-
-
 // this does not say which one is bigger, it only returns 1 if keys
 // are not equal, 0 otherwise
-inline int comp_le_keys (const struct reiserfs_key * k1, const struct reiserfs_key * k2)
+inline int comp_le_keys(const struct reiserfs_key *k1,
+			const struct reiserfs_key *k2)
 {
-    return memcmp (k1, k2, sizeof (struct reiserfs_key));
+	return memcmp(k1, k2, sizeof(struct reiserfs_key));
 }
 
 /**************************************************************************
@@ -184,373 +187,396 @@ inline int comp_le_keys (const struct re
  there are no possible items, and we have not found it. With each examination we
  cut the number of possible items it could be by one more than half rounded down,
  or we find it. */
-static inline	int bin_search (
-              const void * p_v_key, /* Key to search for.                   */
-	      const void * p_v_base,/* First item in the array.             */
-	      int       p_n_num,    /* Number of items in the array.        */
-	      int       p_n_width,  /* Item size in the array.
-				       searched. Lest the reader be
-				       confused, note that this is crafted
-				       as a general function, and when it
-				       is applied specifically to the array
-				       of item headers in a node, p_n_width
-				       is actually the item header size not
-				       the item size.                      */
-	      int     * p_n_pos     /* Number of the searched for element. */
-            ) {
-    int   n_rbound, n_lbound, n_j;
-
-   for ( n_j = ((n_rbound = p_n_num - 1) + (n_lbound = 0))/2; n_lbound <= n_rbound; n_j = (n_rbound + n_lbound)/2 )
-     switch( comp_keys((struct reiserfs_key *)((char * )p_v_base + n_j * p_n_width), (struct cpu_key *)p_v_key) )  {
-     case -1: n_lbound = n_j + 1; continue;
-     case  1: n_rbound = n_j - 1; continue;
-     case  0: *p_n_pos = n_j;     return ITEM_FOUND; /* Key found in the array.  */
-        }
-
-    /* bin_search did not find given key, it returns position of key,
-        that is minimal and greater than the given one. */
-    *p_n_pos = n_lbound;
-    return ITEM_NOT_FOUND;
+static inline int bin_search(const void *p_v_key,	/* Key to search for.                   */
+			     const void *p_v_base,	/* First item in the array.             */
+			     int p_n_num,	/* Number of items in the array.        */
+			     int p_n_width,	/* Item size in the array.
+						   searched. Lest the reader be
+						   confused, note that this is crafted
+						   as a general function, and when it
+						   is applied specifically to the array
+						   of item headers in a node, p_n_width
+						   is actually the item header size not
+						   the item size.                      */
+			     int *p_n_pos	/* Number of the searched for element. */
+    )
+{
+	int n_rbound, n_lbound, n_j;
+
+	for (n_j = ((n_rbound = p_n_num - 1) + (n_lbound = 0)) / 2;
+	     n_lbound <= n_rbound; n_j = (n_rbound + n_lbound) / 2)
+		switch (comp_keys
+			((struct reiserfs_key *)((char *)p_v_base +
+						 n_j * p_n_width),
+			 (struct cpu_key *)p_v_key)) {
+		case -1:
+			n_lbound = n_j + 1;
+			continue;
+		case 1:
+			n_rbound = n_j - 1;
+			continue;
+		case 0:
+			*p_n_pos = n_j;
+			return ITEM_FOUND;	/* Key found in the array.  */
+		}
+
+	/* bin_search did not find given key, it returns position of key,
+	   that is minimal and greater than the given one. */
+	*p_n_pos = n_lbound;
+	return ITEM_NOT_FOUND;
 }
 
 #ifdef CONFIG_REISERFS_CHECK
-extern struct tree_balance * cur_tb;
+extern struct tree_balance *cur_tb;
 #endif
 
-
-
 /* Minimal possible key. It is never in the tree. */
-const struct reiserfs_key  MIN_KEY = {0, 0, {{0, 0},}};
+const struct reiserfs_key MIN_KEY = { 0, 0, {{0, 0},} };
 
 /* Maximal possible key. It is never in the tree. */
-const struct reiserfs_key  MAX_KEY = {
+static const struct reiserfs_key MAX_KEY = {
 	__constant_cpu_to_le32(0xffffffff),
 	__constant_cpu_to_le32(0xffffffff),
 	{{__constant_cpu_to_le32(0xffffffff),
-	__constant_cpu_to_le32(0xffffffff)},}
+	  __constant_cpu_to_le32(0xffffffff)},}
 };
 
-
 /* Get delimiting key of the buffer by looking for it in the buffers in the path, starting from the bottom
    of the path, and going upwards.  We must check the path's validity at each step.  If the key is not in
    the path, there is no delimiting key in the tree (buffer is first or last buffer in tree), and in this
    case we return a special key, either MIN_KEY or MAX_KEY. */
-static inline	const struct  reiserfs_key * get_lkey  (
-	                const struct path         * p_s_chk_path,
-                        const struct super_block  * p_s_sb
-                      ) {
-  int                   n_position, n_path_offset = p_s_chk_path->path_length;
-  struct buffer_head  * p_s_parent;
-  
-  RFALSE( n_path_offset < FIRST_PATH_ELEMENT_OFFSET, 
-	  "PAP-5010: invalid offset in the path");
-
-  /* While not higher in path than first element. */
-  while ( n_path_offset-- > FIRST_PATH_ELEMENT_OFFSET ) {
-
-    RFALSE( ! buffer_uptodate(PATH_OFFSET_PBUFFER(p_s_chk_path, n_path_offset)),
-	    "PAP-5020: parent is not uptodate");
-
-    /* Parent at the path is not in the tree now. */
-    if ( ! B_IS_IN_TREE(p_s_parent = PATH_OFFSET_PBUFFER(p_s_chk_path, n_path_offset)) )
-      return &MAX_KEY;
-    /* Check whether position in the parent is correct. */
-    if ( (n_position = PATH_OFFSET_POSITION(p_s_chk_path, n_path_offset)) > B_NR_ITEMS(p_s_parent) )
-       return &MAX_KEY;
-    /* Check whether parent at the path really points to the child. */
-    if ( B_N_CHILD_NUM(p_s_parent, n_position) !=
-	 PATH_OFFSET_PBUFFER(p_s_chk_path, n_path_offset + 1)->b_blocknr )
-      return &MAX_KEY;
-    /* Return delimiting key if position in the parent is not equal to zero. */
-    if ( n_position )
-      return B_N_PDELIM_KEY(p_s_parent, n_position - 1);
-  }
-  /* Return MIN_KEY if we are in the root of the buffer tree. */
-  if ( PATH_OFFSET_PBUFFER(p_s_chk_path, FIRST_PATH_ELEMENT_OFFSET)->b_blocknr ==
-       SB_ROOT_BLOCK (p_s_sb) )
-    return &MIN_KEY;
-  return  &MAX_KEY;
+static inline const struct reiserfs_key *get_lkey(const struct path
+						  *p_s_chk_path,
+						  const struct super_block
+						  *p_s_sb)
+{
+	int n_position, n_path_offset = p_s_chk_path->path_length;
+	struct buffer_head *p_s_parent;
+
+	RFALSE(n_path_offset < FIRST_PATH_ELEMENT_OFFSET,
+	       "PAP-5010: invalid offset in the path");
+
+	/* While not higher in path than first element. */
+	while (n_path_offset-- > FIRST_PATH_ELEMENT_OFFSET) {
+
+		RFALSE(!buffer_uptodate
+		       (PATH_OFFSET_PBUFFER(p_s_chk_path, n_path_offset)),
+		       "PAP-5020: parent is not uptodate");
+
+		/* Parent at the path is not in the tree now. */
+		if (!B_IS_IN_TREE
+		    (p_s_parent =
+		     PATH_OFFSET_PBUFFER(p_s_chk_path, n_path_offset)))
+			return &MAX_KEY;
+		/* Check whether position in the parent is correct. */
+		if ((n_position =
+		     PATH_OFFSET_POSITION(p_s_chk_path,
+					  n_path_offset)) >
+		    B_NR_ITEMS(p_s_parent))
+			return &MAX_KEY;
+		/* Check whether parent at the path really points to the child. */
+		if (B_N_CHILD_NUM(p_s_parent, n_position) !=
+		    PATH_OFFSET_PBUFFER(p_s_chk_path,
+					n_path_offset + 1)->b_blocknr)
+			return &MAX_KEY;
+		/* Return delimiting key if position in the parent is not equal to zero. */
+		if (n_position)
+			return B_N_PDELIM_KEY(p_s_parent, n_position - 1);
+	}
+	/* Return MIN_KEY if we are in the root of the buffer tree. */
+	if (PATH_OFFSET_PBUFFER(p_s_chk_path, FIRST_PATH_ELEMENT_OFFSET)->
+	    b_blocknr == SB_ROOT_BLOCK(p_s_sb))
+		return &MIN_KEY;
+	return &MAX_KEY;
 }
 
-
 /* Get delimiting key of the buffer at the path and its right neighbor. */
-inline	const struct  reiserfs_key * get_rkey  (
-	                const struct path         * p_s_chk_path,
-                        const struct super_block  * p_s_sb
-                      ) {
-  int                   n_position,
-    			n_path_offset = p_s_chk_path->path_length;
-  struct buffer_head  * p_s_parent;
-
-  RFALSE( n_path_offset < FIRST_PATH_ELEMENT_OFFSET,
-	  "PAP-5030: invalid offset in the path");
-
-  while ( n_path_offset-- > FIRST_PATH_ELEMENT_OFFSET ) {
-
-    RFALSE( ! buffer_uptodate(PATH_OFFSET_PBUFFER(p_s_chk_path, n_path_offset)),
-	    "PAP-5040: parent is not uptodate");
-
-    /* Parent at the path is not in the tree now. */
-    if ( ! B_IS_IN_TREE(p_s_parent = PATH_OFFSET_PBUFFER(p_s_chk_path, n_path_offset)) )
-      return &MIN_KEY;
-    /* Check whether position in the parent is correct. */
-    if ( (n_position = PATH_OFFSET_POSITION(p_s_chk_path, n_path_offset)) > B_NR_ITEMS(p_s_parent) )
-      return &MIN_KEY;
-    /* Check whether parent at the path really points to the child. */
-    if ( B_N_CHILD_NUM(p_s_parent, n_position) !=
-                                        PATH_OFFSET_PBUFFER(p_s_chk_path, n_path_offset + 1)->b_blocknr )
-      return &MIN_KEY;
-    /* Return delimiting key if position in the parent is not the last one. */
-    if ( n_position != B_NR_ITEMS(p_s_parent) )
-      return B_N_PDELIM_KEY(p_s_parent, n_position);
-  }
-  /* Return MAX_KEY if we are in the root of the buffer tree. */
-  if ( PATH_OFFSET_PBUFFER(p_s_chk_path, FIRST_PATH_ELEMENT_OFFSET)->b_blocknr ==
-       SB_ROOT_BLOCK (p_s_sb) )
-    return &MAX_KEY;
-  return  &MIN_KEY;
-}
+inline const struct reiserfs_key *get_rkey(const struct path *p_s_chk_path,
+					   const struct super_block *p_s_sb)
+{
+	int n_position, n_path_offset = p_s_chk_path->path_length;
+	struct buffer_head *p_s_parent;
+
+	RFALSE(n_path_offset < FIRST_PATH_ELEMENT_OFFSET,
+	       "PAP-5030: invalid offset in the path");
 
+	while (n_path_offset-- > FIRST_PATH_ELEMENT_OFFSET) {
+
+		RFALSE(!buffer_uptodate
+		       (PATH_OFFSET_PBUFFER(p_s_chk_path, n_path_offset)),
+		       "PAP-5040: parent is not uptodate");
+
+		/* Parent at the path is not in the tree now. */
+		if (!B_IS_IN_TREE
+		    (p_s_parent =
+		     PATH_OFFSET_PBUFFER(p_s_chk_path, n_path_offset)))
+			return &MIN_KEY;
+		/* Check whether position in the parent is correct. */
+		if ((n_position =
+		     PATH_OFFSET_POSITION(p_s_chk_path,
+					  n_path_offset)) >
+		    B_NR_ITEMS(p_s_parent))
+			return &MIN_KEY;
+		/* Check whether parent at the path really points to the child. */
+		if (B_N_CHILD_NUM(p_s_parent, n_position) !=
+		    PATH_OFFSET_PBUFFER(p_s_chk_path,
+					n_path_offset + 1)->b_blocknr)
+			return &MIN_KEY;
+		/* Return delimiting key if position in the parent is not the last one. */
+		if (n_position != B_NR_ITEMS(p_s_parent))
+			return B_N_PDELIM_KEY(p_s_parent, n_position);
+	}
+	/* Return MAX_KEY if we are in the root of the buffer tree. */
+	if (PATH_OFFSET_PBUFFER(p_s_chk_path, FIRST_PATH_ELEMENT_OFFSET)->
+	    b_blocknr == SB_ROOT_BLOCK(p_s_sb))
+		return &MAX_KEY;
+	return &MIN_KEY;
+}
 
 /* Check whether a key is contained in the tree rooted from a buffer at a path. */
 /* This works by looking at the left and right delimiting keys for the buffer in the last path_element in
    the path.  These delimiting keys are stored at least one level above that buffer in the tree. If the
    buffer is the first or last node in the tree order then one of the delimiting keys may be absent, and in
    this case get_lkey and get_rkey return a special key which is MIN_KEY or MAX_KEY. */
-static  inline  int key_in_buffer (
-                      struct path         * p_s_chk_path, /* Path which should be checked.  */
-                      const struct cpu_key      * p_s_key,      /* Key which should be checked.   */
-                      struct super_block  * p_s_sb        /* Super block pointer.           */
-		      ) {
-
-  RFALSE( ! p_s_key || p_s_chk_path->path_length < FIRST_PATH_ELEMENT_OFFSET ||
-	  p_s_chk_path->path_length > MAX_HEIGHT,
-	  "PAP-5050: pointer to the key(%p) is NULL or invalid path length(%d)",
-	  p_s_key, p_s_chk_path->path_length);
-  RFALSE( !PATH_PLAST_BUFFER(p_s_chk_path)->b_bdev,
-	  "PAP-5060: device must not be NODEV");
-
-  if ( comp_keys(get_lkey(p_s_chk_path, p_s_sb), p_s_key) == 1 )
-    /* left delimiting key is bigger, that the key we look for */
-    return 0;
-  //  if ( comp_keys(p_s_key, get_rkey(p_s_chk_path, p_s_sb)) != -1 )
-  if ( comp_keys(get_rkey(p_s_chk_path, p_s_sb), p_s_key) != 1 )
-    /* p_s_key must be less than right delimitiing key */
-    return 0;
-  return 1;
+static inline int key_in_buffer(struct path *p_s_chk_path,	/* Path which should be checked.  */
+				const struct cpu_key *p_s_key,	/* Key which should be checked.   */
+				struct super_block *p_s_sb	/* Super block pointer.           */
+    )
+{
+
+	RFALSE(!p_s_key || p_s_chk_path->path_length < FIRST_PATH_ELEMENT_OFFSET
+	       || p_s_chk_path->path_length > MAX_HEIGHT,
+	       "PAP-5050: pointer to the key(%p) is NULL or invalid path length(%d)",
+	       p_s_key, p_s_chk_path->path_length);
+	RFALSE(!PATH_PLAST_BUFFER(p_s_chk_path)->b_bdev,
+	       "PAP-5060: device must not be NODEV");
+
+	if (comp_keys(get_lkey(p_s_chk_path, p_s_sb), p_s_key) == 1)
+		/* left delimiting key is bigger, that the key we look for */
+		return 0;
+	//  if ( comp_keys(p_s_key, get_rkey(p_s_chk_path, p_s_sb)) != -1 )
+	if (comp_keys(get_rkey(p_s_chk_path, p_s_sb), p_s_key) != 1)
+		/* p_s_key must be less than right delimitiing key */
+		return 0;
+	return 1;
 }
 
-
-inline void decrement_bcount(
-              struct buffer_head  * p_s_bh
-            ) { 
-  if ( p_s_bh ) {
-    if ( atomic_read (&(p_s_bh->b_count)) ) {
-      put_bh(p_s_bh) ;
-      return;
-    }
-    reiserfs_panic(NULL, "PAP-5070: decrement_bcount: trying to free free buffer %b", p_s_bh);
-  }
+inline void decrement_bcount(struct buffer_head *p_s_bh)
+{
+	if (p_s_bh) {
+		if (atomic_read(&(p_s_bh->b_count))) {
+			put_bh(p_s_bh);
+			return;
+		}
+		reiserfs_panic(NULL,
+			       "PAP-5070: decrement_bcount: trying to free free buffer %b",
+			       p_s_bh);
+	}
 }
 
-
 /* Decrement b_count field of the all buffers in the path. */
-void decrement_counters_in_path (
-              struct path * p_s_search_path
-            ) {
-  int n_path_offset = p_s_search_path->path_length;
+void decrement_counters_in_path(struct path *p_s_search_path)
+{
+	int n_path_offset = p_s_search_path->path_length;
 
-  RFALSE( n_path_offset < ILLEGAL_PATH_ELEMENT_OFFSET ||
-	  n_path_offset > EXTENDED_MAX_HEIGHT - 1,
-	  "PAP-5080: invalid path offset of %d", n_path_offset);
+	RFALSE(n_path_offset < ILLEGAL_PATH_ELEMENT_OFFSET ||
+	       n_path_offset > EXTENDED_MAX_HEIGHT - 1,
+	       "PAP-5080: invalid path offset of %d", n_path_offset);
 
-  while ( n_path_offset > ILLEGAL_PATH_ELEMENT_OFFSET ) {
-    struct buffer_head * bh;
+	while (n_path_offset > ILLEGAL_PATH_ELEMENT_OFFSET) {
+		struct buffer_head *bh;
 
-    bh = PATH_OFFSET_PBUFFER(p_s_search_path, n_path_offset--);
-    decrement_bcount (bh);
-  }
-  p_s_search_path->path_length = ILLEGAL_PATH_ELEMENT_OFFSET;
+		bh = PATH_OFFSET_PBUFFER(p_s_search_path, n_path_offset--);
+		decrement_bcount(bh);
+	}
+	p_s_search_path->path_length = ILLEGAL_PATH_ELEMENT_OFFSET;
 }
 
-
-int reiserfs_check_path(struct path *p) {
-  RFALSE( p->path_length != ILLEGAL_PATH_ELEMENT_OFFSET,
-	  "path not properly relsed") ;
-  return 0 ;
+int reiserfs_check_path(struct path *p)
+{
+	RFALSE(p->path_length != ILLEGAL_PATH_ELEMENT_OFFSET,
+	       "path not properly relsed");
+	return 0;
 }
 
-
 /* Release all buffers in the path. Restore dirty bits clean
 ** when preparing the buffer for the log
 **
 ** only called from fix_nodes()
 */
-void  pathrelse_and_restore (
-	struct super_block *s, 
-        struct path * p_s_search_path
-      ) {
-  int n_path_offset = p_s_search_path->path_length;
-
-  RFALSE( n_path_offset < ILLEGAL_PATH_ELEMENT_OFFSET, 
-	  "clm-4000: invalid path offset");
-  
-  while ( n_path_offset > ILLEGAL_PATH_ELEMENT_OFFSET )  {
-    reiserfs_restore_prepared_buffer(s, PATH_OFFSET_PBUFFER(p_s_search_path, 
-                                     n_path_offset));
-    brelse(PATH_OFFSET_PBUFFER(p_s_search_path, n_path_offset--));
-  }
-  p_s_search_path->path_length = ILLEGAL_PATH_ELEMENT_OFFSET;
-}
-
-/* Release all buffers in the path. */
-void  pathrelse (
-        struct path * p_s_search_path
-      ) {
-  int n_path_offset = p_s_search_path->path_length;
+void pathrelse_and_restore(struct super_block *s, struct path *p_s_search_path)
+{
+	int n_path_offset = p_s_search_path->path_length;
 
-  RFALSE( n_path_offset < ILLEGAL_PATH_ELEMENT_OFFSET,
-	  "PAP-5090: invalid path offset");
-  
-  while ( n_path_offset > ILLEGAL_PATH_ELEMENT_OFFSET )  
-    brelse(PATH_OFFSET_PBUFFER(p_s_search_path, n_path_offset--));
+	RFALSE(n_path_offset < ILLEGAL_PATH_ELEMENT_OFFSET,
+	       "clm-4000: invalid path offset");
 
-  p_s_search_path->path_length = ILLEGAL_PATH_ELEMENT_OFFSET;
+	while (n_path_offset > ILLEGAL_PATH_ELEMENT_OFFSET) {
+		reiserfs_restore_prepared_buffer(s,
+						 PATH_OFFSET_PBUFFER
+						 (p_s_search_path,
+						  n_path_offset));
+		brelse(PATH_OFFSET_PBUFFER(p_s_search_path, n_path_offset--));
+	}
+	p_s_search_path->path_length = ILLEGAL_PATH_ELEMENT_OFFSET;
 }
 
-
-
-static int is_leaf (char * buf, int blocksize, struct buffer_head * bh)
+/* Release all buffers in the path. */
+void pathrelse(struct path *p_s_search_path)
 {
-    struct block_head * blkh;
-    struct item_head * ih;
-    int used_space;
-    int prev_location;
-    int i;
-    int nr;
+	int n_path_offset = p_s_search_path->path_length;
 
-    blkh = (struct block_head *)buf;
-    if ( blkh_level(blkh) != DISK_LEAF_NODE_LEVEL) {
-	reiserfs_warning (NULL, "is_leaf: this should be caught earlier");
-	return 0;
-    }
-
-    nr = blkh_nr_item(blkh);
-    if (nr < 1 || nr > ((blocksize - BLKH_SIZE) / (IH_SIZE + MIN_ITEM_LEN))) {
-	/* item number is too big or too small */
-	reiserfs_warning (NULL, "is_leaf: nr_item seems wrong: %z", bh);
-	return 0;
-    }
-    ih = (struct item_head *)(buf + BLKH_SIZE) + nr - 1;
-    used_space = BLKH_SIZE + IH_SIZE * nr + (blocksize - ih_location (ih));
-    if (used_space != blocksize - blkh_free_space(blkh)) {
-	/* free space does not match to calculated amount of use space */
-	reiserfs_warning (NULL, "is_leaf: free space seems wrong: %z", bh);
-	return 0;
-    }
+	RFALSE(n_path_offset < ILLEGAL_PATH_ELEMENT_OFFSET,
+	       "PAP-5090: invalid path offset");
 
-    // FIXME: it is_leaf will hit performance too much - we may have
-    // return 1 here
-
-    /* check tables of item heads */
-    ih = (struct item_head *)(buf + BLKH_SIZE);
-    prev_location = blocksize;
-    for (i = 0; i < nr; i ++, ih ++) {
-	if ( le_ih_k_type(ih) == TYPE_ANY) {
-	    reiserfs_warning (NULL, "is_leaf: wrong item type for item %h",ih);
-	    return 0;
-	}
-	if (ih_location (ih) >= blocksize || ih_location (ih) < IH_SIZE * nr) {
-	    reiserfs_warning (NULL, "is_leaf: item location seems wrong: %h", ih);
-	    return 0;
-	}
-	if (ih_item_len (ih) < 1 || ih_item_len (ih) > MAX_ITEM_LEN (blocksize)) {
-	    reiserfs_warning (NULL, "is_leaf: item length seems wrong: %h", ih);
-	    return 0;
-	}
-	if (prev_location - ih_location (ih) != ih_item_len (ih)) {
-	    reiserfs_warning (NULL, "is_leaf: item location seems wrong (second one): %h", ih);
-	    return 0;
+	while (n_path_offset > ILLEGAL_PATH_ELEMENT_OFFSET)
+		brelse(PATH_OFFSET_PBUFFER(p_s_search_path, n_path_offset--));
+
+	p_s_search_path->path_length = ILLEGAL_PATH_ELEMENT_OFFSET;
+}
+
+static int is_leaf(char *buf, int blocksize, struct buffer_head *bh)
+{
+	struct block_head *blkh;
+	struct item_head *ih;
+	int used_space;
+	int prev_location;
+	int i;
+	int nr;
+
+	blkh = (struct block_head *)buf;
+	if (blkh_level(blkh) != DISK_LEAF_NODE_LEVEL) {
+		reiserfs_warning(NULL,
+				 "is_leaf: this should be caught earlier");
+		return 0;
+	}
+
+	nr = blkh_nr_item(blkh);
+	if (nr < 1 || nr > ((blocksize - BLKH_SIZE) / (IH_SIZE + MIN_ITEM_LEN))) {
+		/* item number is too big or too small */
+		reiserfs_warning(NULL, "is_leaf: nr_item seems wrong: %z", bh);
+		return 0;
+	}
+	ih = (struct item_head *)(buf + BLKH_SIZE) + nr - 1;
+	used_space = BLKH_SIZE + IH_SIZE * nr + (blocksize - ih_location(ih));
+	if (used_space != blocksize - blkh_free_space(blkh)) {
+		/* free space does not match to calculated amount of use space */
+		reiserfs_warning(NULL, "is_leaf: free space seems wrong: %z",
+				 bh);
+		return 0;
+	}
+	// FIXME: it is_leaf will hit performance too much - we may have
+	// return 1 here
+
+	/* check tables of item heads */
+	ih = (struct item_head *)(buf + BLKH_SIZE);
+	prev_location = blocksize;
+	for (i = 0; i < nr; i++, ih++) {
+		if (le_ih_k_type(ih) == TYPE_ANY) {
+			reiserfs_warning(NULL,
+					 "is_leaf: wrong item type for item %h",
+					 ih);
+			return 0;
+		}
+		if (ih_location(ih) >= blocksize
+		    || ih_location(ih) < IH_SIZE * nr) {
+			reiserfs_warning(NULL,
+					 "is_leaf: item location seems wrong: %h",
+					 ih);
+			return 0;
+		}
+		if (ih_item_len(ih) < 1
+		    || ih_item_len(ih) > MAX_ITEM_LEN(blocksize)) {
+			reiserfs_warning(NULL,
+					 "is_leaf: item length seems wrong: %h",
+					 ih);
+			return 0;
+		}
+		if (prev_location - ih_location(ih) != ih_item_len(ih)) {
+			reiserfs_warning(NULL,
+					 "is_leaf: item location seems wrong (second one): %h",
+					 ih);
+			return 0;
+		}
+		prev_location = ih_location(ih);
 	}
-	prev_location = ih_location (ih);
-    }
 
-    // one may imagine much more checks
-    return 1;
+	// one may imagine much more checks
+	return 1;
 }
 
-
 /* returns 1 if buf looks like an internal node, 0 otherwise */
-static int is_internal (char * buf, int blocksize, struct buffer_head * bh)
+static int is_internal(char *buf, int blocksize, struct buffer_head *bh)
 {
-    struct block_head * blkh;
-    int nr;
-    int used_space;
-
-    blkh = (struct block_head *)buf;
-    nr = blkh_level(blkh);
-    if (nr <= DISK_LEAF_NODE_LEVEL || nr > MAX_HEIGHT) {
-	/* this level is not possible for internal nodes */
-	reiserfs_warning (NULL, "is_internal: this should be caught earlier");
-	return 0;
-    }
-    
-    nr = blkh_nr_item(blkh);
-    if (nr > (blocksize - BLKH_SIZE - DC_SIZE) / (KEY_SIZE + DC_SIZE)) {
-	/* for internal which is not root we might check min number of keys */
-	reiserfs_warning (NULL, "is_internal: number of key seems wrong: %z", bh);
-	return 0;
-    }
-
-    used_space = BLKH_SIZE + KEY_SIZE * nr + DC_SIZE * (nr + 1);
-    if (used_space != blocksize - blkh_free_space(blkh)) {
-	reiserfs_warning (NULL, "is_internal: free space seems wrong: %z", bh);
-	return 0;
-    }
-
-    // one may imagine much more checks
-    return 1;
+	struct block_head *blkh;
+	int nr;
+	int used_space;
+
+	blkh = (struct block_head *)buf;
+	nr = blkh_level(blkh);
+	if (nr <= DISK_LEAF_NODE_LEVEL || nr > MAX_HEIGHT) {
+		/* this level is not possible for internal nodes */
+		reiserfs_warning(NULL,
+				 "is_internal: this should be caught earlier");
+		return 0;
+	}
+
+	nr = blkh_nr_item(blkh);
+	if (nr > (blocksize - BLKH_SIZE - DC_SIZE) / (KEY_SIZE + DC_SIZE)) {
+		/* for internal which is not root we might check min number of keys */
+		reiserfs_warning(NULL,
+				 "is_internal: number of key seems wrong: %z",
+				 bh);
+		return 0;
+	}
+
+	used_space = BLKH_SIZE + KEY_SIZE * nr + DC_SIZE * (nr + 1);
+	if (used_space != blocksize - blkh_free_space(blkh)) {
+		reiserfs_warning(NULL,
+				 "is_internal: free space seems wrong: %z", bh);
+		return 0;
+	}
+	// one may imagine much more checks
+	return 1;
 }
 
-
 // make sure that bh contains formatted node of reiserfs tree of
 // 'level'-th level
-static int is_tree_node (struct buffer_head * bh, int level)
+static int is_tree_node(struct buffer_head *bh, int level)
 {
-    if (B_LEVEL (bh) != level) {
-	reiserfs_warning (NULL, "is_tree_node: node level %d does not match to the expected one %d",
-		B_LEVEL (bh), level);
-	return 0;
-    }
-    if (level == DISK_LEAF_NODE_LEVEL)
-	return is_leaf (bh->b_data, bh->b_size, bh);
+	if (B_LEVEL(bh) != level) {
+		reiserfs_warning(NULL,
+				 "is_tree_node: node level %d does not match to the expected one %d",
+				 B_LEVEL(bh), level);
+		return 0;
+	}
+	if (level == DISK_LEAF_NODE_LEVEL)
+		return is_leaf(bh->b_data, bh->b_size, bh);
 
-    return is_internal (bh->b_data, bh->b_size, bh);
+	return is_internal(bh->b_data, bh->b_size, bh);
 }
 
-
-
 #define SEARCH_BY_KEY_READA 16
 
 /* The function is NOT SCHEDULE-SAFE! */
-static void search_by_key_reada (struct super_block * s,
-                                 struct buffer_head **bh,
-				 unsigned long *b, int num)
-{
-    int i,j;
-  
-    for (i = 0 ; i < num ; i++) {
-	bh[i] = sb_getblk (s, b[i]);
-    }
-    for (j = 0 ; j < i ; j++) {
-	/*
-	 * note, this needs attention if we are getting rid of the BKL
-	 * you have to make sure the prepared bit isn't set on this buffer
-	 */
-	if (!buffer_uptodate(bh[j]))
-	    ll_rw_block(READA, 1, bh + j);
-    	brelse(bh[j]);
-    }
+static void search_by_key_reada(struct super_block *s,
+				struct buffer_head **bh,
+				unsigned long *b, int num)
+{
+	int i, j;
+
+	for (i = 0; i < num; i++) {
+		bh[i] = sb_getblk(s, b[i]);
+	}
+	for (j = 0; j < i; j++) {
+		/*
+		 * note, this needs attention if we are getting rid of the BKL
+		 * you have to make sure the prepared bit isn't set on this buffer
+		 */
+		if (!buffer_uptodate(bh[j]))
+			ll_rw_block(READA, 1, bh + j);
+		brelse(bh[j]);
+	}
 }
 
 /**************************************************************************
@@ -576,193 +602,199 @@ static void search_by_key_reada (struct 
    correctness of the top of the path but need not be checked for the
    correctness of the bottom of the path */
 /* The function is NOT SCHEDULE-SAFE! */
-int search_by_key (struct super_block * p_s_sb,
-		   const struct cpu_key * p_s_key, /* Key to search. */
-		   struct path * p_s_search_path, /* This structure was
-						     allocated and initialized
-						     by the calling
-						     function. It is filled up
-						     by this function.  */
-		   int n_stop_level /* How far down the tree to search. To
-                                       stop at leaf level - set to
-                                       DISK_LEAF_NODE_LEVEL */
-    ) {
-    int  n_block_number;
-    int  expected_level;
-    struct buffer_head  *       p_s_bh;
-    struct path_element *       p_s_last_element;
-    int				n_node_level, n_retval;
-    int 			right_neighbor_of_leaf_node;
-    int				fs_gen;
-    struct buffer_head *reada_bh[SEARCH_BY_KEY_READA];
-    unsigned long      reada_blocks[SEARCH_BY_KEY_READA];
-    int reada_count = 0;
+int search_by_key(struct super_block *p_s_sb, const struct cpu_key *p_s_key,	/* Key to search. */
+		  struct path *p_s_search_path,	/* This structure was
+						   allocated and initialized
+						   by the calling
+						   function. It is filled up
+						   by this function.  */
+		  int n_stop_level	/* How far down the tree to search. To
+					   stop at leaf level - set to
+					   DISK_LEAF_NODE_LEVEL */
+    )
+{
+	int n_block_number;
+	int expected_level;
+	struct buffer_head *p_s_bh;
+	struct path_element *p_s_last_element;
+	int n_node_level, n_retval;
+	int right_neighbor_of_leaf_node;
+	int fs_gen;
+	struct buffer_head *reada_bh[SEARCH_BY_KEY_READA];
+	unsigned long reada_blocks[SEARCH_BY_KEY_READA];
+	int reada_count = 0;
 
 #ifdef CONFIG_REISERFS_CHECK
-    int n_repeat_counter = 0;
+	int n_repeat_counter = 0;
 #endif
-    
-    PROC_INFO_INC( p_s_sb, search_by_key );
-    
-    /* As we add each node to a path we increase its count.  This means that
-       we must be careful to release all nodes in a path before we either
-       discard the path struct or re-use the path struct, as we do here. */
-
-    decrement_counters_in_path(p_s_search_path);
-
-    right_neighbor_of_leaf_node = 0;
-
-    /* With each iteration of this loop we search through the items in the
-       current node, and calculate the next current node(next path element)
-       for the next iteration of this loop.. */
-    n_block_number = SB_ROOT_BLOCK (p_s_sb);
-    expected_level = -1;
-    while ( 1 ) {
+
+	PROC_INFO_INC(p_s_sb, search_by_key);
+
+	/* As we add each node to a path we increase its count.  This means that
+	   we must be careful to release all nodes in a path before we either
+	   discard the path struct or re-use the path struct, as we do here. */
+
+	decrement_counters_in_path(p_s_search_path);
+
+	right_neighbor_of_leaf_node = 0;
+
+	/* With each iteration of this loop we search through the items in the
+	   current node, and calculate the next current node(next path element)
+	   for the next iteration of this loop.. */
+	n_block_number = SB_ROOT_BLOCK(p_s_sb);
+	expected_level = -1;
+	while (1) {
 
 #ifdef CONFIG_REISERFS_CHECK
-	if ( !(++n_repeat_counter % 50000) )
-	    reiserfs_warning (p_s_sb, "PAP-5100: search_by_key: %s:"
-			      "there were %d iterations of while loop "
-			      "looking for key %K",
-			      current->comm, n_repeat_counter, p_s_key);
+		if (!(++n_repeat_counter % 50000))
+			reiserfs_warning(p_s_sb, "PAP-5100: search_by_key: %s:"
+					 "there were %d iterations of while loop "
+					 "looking for key %K",
+					 current->comm, n_repeat_counter,
+					 p_s_key);
 #endif
 
-	/* prep path to have another element added to it. */
-	p_s_last_element = PATH_OFFSET_PELEMENT(p_s_search_path, ++p_s_search_path->path_length);
-	fs_gen = get_generation (p_s_sb);
-
-	/* Read the next tree node, and set the last element in the path to
-           have a pointer to it. */
-	if ((p_s_bh = p_s_last_element->pe_buffer =
-	     sb_getblk(p_s_sb, n_block_number)) ) {
-	    if (!buffer_uptodate(p_s_bh) && reada_count > 1) {
-		search_by_key_reada (p_s_sb, reada_bh,
-		                     reada_blocks, reada_count);
-	    }
-	    ll_rw_block(READ, 1, &p_s_bh);
-	    wait_on_buffer(p_s_bh);
-	    if (!buffer_uptodate(p_s_bh))
-	        goto io_error;
-	} else {
-io_error:
-	    p_s_search_path->path_length --;
-	    pathrelse(p_s_search_path);
-	    return IO_ERROR;
-	}
-	reada_count = 0;
-	if (expected_level == -1)
-		expected_level = SB_TREE_HEIGHT (p_s_sb);
-	expected_level --;
-
-	/* It is possible that schedule occurred. We must check whether the key
-	   to search is still in the tree rooted from the current buffer. If
-	   not then repeat search from the root. */
-	if ( fs_changed (fs_gen, p_s_sb) && 
-	    (!B_IS_IN_TREE (p_s_bh) ||
-	     B_LEVEL(p_s_bh) != expected_level ||
-	     !key_in_buffer(p_s_search_path, p_s_key, p_s_sb))) {
-	    PROC_INFO_INC( p_s_sb, search_by_key_fs_changed );
-	    PROC_INFO_INC( p_s_sb, search_by_key_restarted );
-	    PROC_INFO_INC( p_s_sb, sbk_restarted[ expected_level - 1 ] );
-	    decrement_counters_in_path(p_s_search_path);
-	    
-	    /* Get the root block number so that we can repeat the search
-	       starting from the root. */
-	    n_block_number = SB_ROOT_BLOCK (p_s_sb);
-	    expected_level = -1;
-	    right_neighbor_of_leaf_node = 0;
-	    
-	    /* repeat search from the root */
-	    continue;
-	}
-
-        /* only check that the key is in the buffer if p_s_key is not
-           equal to the MAX_KEY. Latter case is only possible in
-           "finish_unfinished()" processing during mount. */
-        RFALSE( comp_keys( &MAX_KEY, p_s_key ) &&
-                ! key_in_buffer(p_s_search_path, p_s_key, p_s_sb),
-		"PAP-5130: key is not in the buffer");
+		/* prep path to have another element added to it. */
+		p_s_last_element =
+		    PATH_OFFSET_PELEMENT(p_s_search_path,
+					 ++p_s_search_path->path_length);
+		fs_gen = get_generation(p_s_sb);
+
+		/* Read the next tree node, and set the last element in the path to
+		   have a pointer to it. */
+		if ((p_s_bh = p_s_last_element->pe_buffer =
+		     sb_getblk(p_s_sb, n_block_number))) {
+			if (!buffer_uptodate(p_s_bh) && reada_count > 1) {
+				search_by_key_reada(p_s_sb, reada_bh,
+						    reada_blocks, reada_count);
+			}
+			ll_rw_block(READ, 1, &p_s_bh);
+			wait_on_buffer(p_s_bh);
+			if (!buffer_uptodate(p_s_bh))
+				goto io_error;
+		} else {
+		      io_error:
+			p_s_search_path->path_length--;
+			pathrelse(p_s_search_path);
+			return IO_ERROR;
+		}
+		reada_count = 0;
+		if (expected_level == -1)
+			expected_level = SB_TREE_HEIGHT(p_s_sb);
+		expected_level--;
+
+		/* It is possible that schedule occurred. We must check whether the key
+		   to search is still in the tree rooted from the current buffer. If
+		   not then repeat search from the root. */
+		if (fs_changed(fs_gen, p_s_sb) &&
+		    (!B_IS_IN_TREE(p_s_bh) ||
+		     B_LEVEL(p_s_bh) != expected_level ||
+		     !key_in_buffer(p_s_search_path, p_s_key, p_s_sb))) {
+			PROC_INFO_INC(p_s_sb, search_by_key_fs_changed);
+			PROC_INFO_INC(p_s_sb, search_by_key_restarted);
+			PROC_INFO_INC(p_s_sb,
+				      sbk_restarted[expected_level - 1]);
+			decrement_counters_in_path(p_s_search_path);
+
+			/* Get the root block number so that we can repeat the search
+			   starting from the root. */
+			n_block_number = SB_ROOT_BLOCK(p_s_sb);
+			expected_level = -1;
+			right_neighbor_of_leaf_node = 0;
+
+			/* repeat search from the root */
+			continue;
+		}
+
+		/* only check that the key is in the buffer if p_s_key is not
+		   equal to the MAX_KEY. Latter case is only possible in
+		   "finish_unfinished()" processing during mount. */
+		RFALSE(comp_keys(&MAX_KEY, p_s_key) &&
+		       !key_in_buffer(p_s_search_path, p_s_key, p_s_sb),
+		       "PAP-5130: key is not in the buffer");
 #ifdef CONFIG_REISERFS_CHECK
-	if ( cur_tb ) {
-	    print_cur_tb ("5140");
-	    reiserfs_panic(p_s_sb, "PAP-5140: search_by_key: schedule occurred in do_balance!");
-	}
+		if (cur_tb) {
+			print_cur_tb("5140");
+			reiserfs_panic(p_s_sb,
+				       "PAP-5140: search_by_key: schedule occurred in do_balance!");
+		}
 #endif
 
-	// make sure, that the node contents look like a node of
-	// certain level
-	if (!is_tree_node (p_s_bh, expected_level)) {
-	    reiserfs_warning (p_s_sb, "vs-5150: search_by_key: "
-			      "invalid format found in block %ld. Fsck?",
-			      p_s_bh->b_blocknr);
-	    pathrelse (p_s_search_path);
-	    return IO_ERROR;
-	}
-	
-	/* ok, we have acquired next formatted node in the tree */
-	n_node_level = B_LEVEL (p_s_bh);
-
-	PROC_INFO_BH_STAT( p_s_sb, p_s_bh, n_node_level - 1 );
-
-	RFALSE( n_node_level < n_stop_level,
-		"vs-5152: tree level (%d) is less than stop level (%d)",
-		n_node_level, n_stop_level);
-
-	n_retval = bin_search( p_s_key, B_N_PITEM_HEAD(p_s_bh, 0),
-                B_NR_ITEMS(p_s_bh),
-                ( n_node_level == DISK_LEAF_NODE_LEVEL ) ? IH_SIZE : KEY_SIZE,
-                &(p_s_last_element->pe_position));
-	if (n_node_level == n_stop_level) {
-	    return n_retval;
-	}
-
-	/* we are not in the stop level */
-	if (n_retval == ITEM_FOUND)
-	    /* item has been found, so we choose the pointer which is to the right of the found one */
-	    p_s_last_element->pe_position++;
-
-	/* if item was not found we choose the position which is to
-	   the left of the found item. This requires no code,
-	   bin_search did it already.*/
-
-	/* So we have chosen a position in the current node which is
-	   an internal node.  Now we calculate child block number by
-	   position in the node. */
-	n_block_number = B_N_CHILD_NUM(p_s_bh, p_s_last_element->pe_position);
-
-	/* if we are going to read leaf nodes, try for read ahead as well */
-	if ((p_s_search_path->reada & PATH_READA) &&
-	    n_node_level == DISK_LEAF_NODE_LEVEL + 1)
-	{
-	    int pos = p_s_last_element->pe_position;
-	    int limit = B_NR_ITEMS(p_s_bh);
-	    struct reiserfs_key *le_key;
-
-	    if (p_s_search_path->reada & PATH_READA_BACK)
-		limit = 0;
-	    while(reada_count < SEARCH_BY_KEY_READA) {
-		if (pos == limit)
-		    break;
-	        reada_blocks[reada_count++] = B_N_CHILD_NUM(p_s_bh, pos);
-		if (p_s_search_path->reada & PATH_READA_BACK)
-		    pos--;
-		else
-		    pos++;
+		// make sure, that the node contents look like a node of
+		// certain level
+		if (!is_tree_node(p_s_bh, expected_level)) {
+			reiserfs_warning(p_s_sb, "vs-5150: search_by_key: "
+					 "invalid format found in block %ld. Fsck?",
+					 p_s_bh->b_blocknr);
+			pathrelse(p_s_search_path);
+			return IO_ERROR;
+		}
 
-		/*
-		 * check to make sure we're in the same object
-		 */
-		le_key = B_N_PDELIM_KEY(p_s_bh, pos);
-		if (le32_to_cpu(le_key->k_objectid) !=
-		    p_s_key->on_disk_key.k_objectid)
-		{
-		    break;
-		}
-	    }
-        }
-    }
-}
+		/* ok, we have acquired next formatted node in the tree */
+		n_node_level = B_LEVEL(p_s_bh);
 
+		PROC_INFO_BH_STAT(p_s_sb, p_s_bh, n_node_level - 1);
+
+		RFALSE(n_node_level < n_stop_level,
+		       "vs-5152: tree level (%d) is less than stop level (%d)",
+		       n_node_level, n_stop_level);
+
+		n_retval = bin_search(p_s_key, B_N_PITEM_HEAD(p_s_bh, 0),
+				      B_NR_ITEMS(p_s_bh),
+				      (n_node_level ==
+				       DISK_LEAF_NODE_LEVEL) ? IH_SIZE :
+				      KEY_SIZE,
+				      &(p_s_last_element->pe_position));
+		if (n_node_level == n_stop_level) {
+			return n_retval;
+		}
+
+		/* we are not in the stop level */
+		if (n_retval == ITEM_FOUND)
+			/* item has been found, so we choose the pointer which is to the right of the found one */
+			p_s_last_element->pe_position++;
+
+		/* if item was not found we choose the position which is to
+		   the left of the found item. This requires no code,
+		   bin_search did it already. */
+
+		/* So we have chosen a position in the current node which is
+		   an internal node.  Now we calculate child block number by
+		   position in the node. */
+		n_block_number =
+		    B_N_CHILD_NUM(p_s_bh, p_s_last_element->pe_position);
+
+		/* if we are going to read leaf nodes, try for read ahead as well */
+		if ((p_s_search_path->reada & PATH_READA) &&
+		    n_node_level == DISK_LEAF_NODE_LEVEL + 1) {
+			int pos = p_s_last_element->pe_position;
+			int limit = B_NR_ITEMS(p_s_bh);
+			struct reiserfs_key *le_key;
+
+			if (p_s_search_path->reada & PATH_READA_BACK)
+				limit = 0;
+			while (reada_count < SEARCH_BY_KEY_READA) {
+				if (pos == limit)
+					break;
+				reada_blocks[reada_count++] =
+				    B_N_CHILD_NUM(p_s_bh, pos);
+				if (p_s_search_path->reada & PATH_READA_BACK)
+					pos--;
+				else
+					pos++;
+
+				/*
+				 * check to make sure we're in the same object
+				 */
+				le_key = B_N_PDELIM_KEY(p_s_bh, pos);
+				if (le32_to_cpu(le_key->k_objectid) !=
+				    p_s_key->on_disk_key.k_objectid) {
+					break;
+				}
+			}
+		}
+	}
+}
 
 /* Form the path to an item and position in this item which contains
    file byte defined by p_s_key. If there is no such item
@@ -780,93 +812,96 @@ io_error:
    units of directory entries.  */
 
 /* The function is NOT SCHEDULE-SAFE! */
-int search_for_position_by_key (struct super_block  * p_s_sb,         /* Pointer to the super block.          */
-				const struct cpu_key  * p_cpu_key,      /* Key to search (cpu variable)         */
-				struct path         * p_s_search_path /* Filled up by this function.          */
-    ) {
-    struct item_head    * p_le_ih; /* pointer to on-disk structure */
-    int                   n_blk_size;
-    loff_t item_offset, offset;
-    struct reiserfs_dir_entry de;
-    int retval;
-
-    /* If searching for directory entry. */
-    if ( is_direntry_cpu_key (p_cpu_key) )
-	return  search_by_entry_key (p_s_sb, p_cpu_key, p_s_search_path, &de);
-
-    /* If not searching for directory entry. */
-    
-    /* If item is found. */
-    retval = search_item (p_s_sb, p_cpu_key, p_s_search_path);
-    if (retval == IO_ERROR)
-	return retval;
-    if ( retval == ITEM_FOUND )  {
+int search_for_position_by_key(struct super_block *p_s_sb,	/* Pointer to the super block.          */
+			       const struct cpu_key *p_cpu_key,	/* Key to search (cpu variable)         */
+			       struct path *p_s_search_path	/* Filled up by this function.          */
+    )
+{
+	struct item_head *p_le_ih;	/* pointer to on-disk structure */
+	int n_blk_size;
+	loff_t item_offset, offset;
+	struct reiserfs_dir_entry de;
+	int retval;
+
+	/* If searching for directory entry. */
+	if (is_direntry_cpu_key(p_cpu_key))
+		return search_by_entry_key(p_s_sb, p_cpu_key, p_s_search_path,
+					   &de);
+
+	/* If not searching for directory entry. */
+
+	/* If item is found. */
+	retval = search_item(p_s_sb, p_cpu_key, p_s_search_path);
+	if (retval == IO_ERROR)
+		return retval;
+	if (retval == ITEM_FOUND) {
 
-	RFALSE( ! ih_item_len(
-                B_N_PITEM_HEAD(PATH_PLAST_BUFFER(p_s_search_path),
-			       PATH_LAST_POSITION(p_s_search_path))),
-	        "PAP-5165: item length equals zero");
-
-	pos_in_item(p_s_search_path) = 0;
-	return POSITION_FOUND;
-    }
-
-    RFALSE( ! PATH_LAST_POSITION(p_s_search_path),
-	    "PAP-5170: position equals zero");
-
-    /* Item is not found. Set path to the previous item. */
-    p_le_ih = B_N_PITEM_HEAD(PATH_PLAST_BUFFER(p_s_search_path), --PATH_LAST_POSITION(p_s_search_path));
-    n_blk_size = p_s_sb->s_blocksize;
-
-    if (comp_short_keys (&(p_le_ih->ih_key), p_cpu_key)) {
-	return FILE_NOT_FOUND;
-    }
-
-    // FIXME: quite ugly this far
-
-    item_offset = le_ih_k_offset (p_le_ih);
-    offset = cpu_key_k_offset (p_cpu_key);
-
-    /* Needed byte is contained in the item pointed to by the path.*/
-    if (item_offset <= offset &&
-	item_offset + op_bytes_number (p_le_ih, n_blk_size) > offset) {
-	pos_in_item (p_s_search_path) = offset - item_offset;
-	if ( is_indirect_le_ih(p_le_ih) ) {
-	    pos_in_item (p_s_search_path) /= n_blk_size;
-	}
-	return POSITION_FOUND;
-    }
-
-    /* Needed byte is not contained in the item pointed to by the
-     path. Set pos_in_item out of the item. */
-    if ( is_indirect_le_ih (p_le_ih) )
-	pos_in_item (p_s_search_path) = ih_item_len(p_le_ih) / UNFM_P_SIZE;
-    else
-        pos_in_item (p_s_search_path) = ih_item_len( p_le_ih );
-  
-    return POSITION_NOT_FOUND;
-}
+		RFALSE(!ih_item_len
+		       (B_N_PITEM_HEAD
+			(PATH_PLAST_BUFFER(p_s_search_path),
+			 PATH_LAST_POSITION(p_s_search_path))),
+		       "PAP-5165: item length equals zero");
+
+		pos_in_item(p_s_search_path) = 0;
+		return POSITION_FOUND;
+	}
+
+	RFALSE(!PATH_LAST_POSITION(p_s_search_path),
+	       "PAP-5170: position equals zero");
+
+	/* Item is not found. Set path to the previous item. */
+	p_le_ih =
+	    B_N_PITEM_HEAD(PATH_PLAST_BUFFER(p_s_search_path),
+			   --PATH_LAST_POSITION(p_s_search_path));
+	n_blk_size = p_s_sb->s_blocksize;
 
+	if (comp_short_keys(&(p_le_ih->ih_key), p_cpu_key)) {
+		return FILE_NOT_FOUND;
+	}
+	// FIXME: quite ugly this far
 
-/* Compare given item and item pointed to by the path. */
-int comp_items (const struct item_head * stored_ih, const struct path * p_s_path)
-{
-    struct buffer_head  * p_s_bh;
-    struct item_head    * ih;
+	item_offset = le_ih_k_offset(p_le_ih);
+	offset = cpu_key_k_offset(p_cpu_key);
 
-    /* Last buffer at the path is not in the tree. */
-    if ( ! B_IS_IN_TREE(p_s_bh = PATH_PLAST_BUFFER(p_s_path)) )
-	return 1;
+	/* Needed byte is contained in the item pointed to by the path. */
+	if (item_offset <= offset &&
+	    item_offset + op_bytes_number(p_le_ih, n_blk_size) > offset) {
+		pos_in_item(p_s_search_path) = offset - item_offset;
+		if (is_indirect_le_ih(p_le_ih)) {
+			pos_in_item(p_s_search_path) /= n_blk_size;
+		}
+		return POSITION_FOUND;
+	}
 
-    /* Last path position is invalid. */
-    if ( PATH_LAST_POSITION(p_s_path) >= B_NR_ITEMS(p_s_bh) )
-	return 1;
+	/* Needed byte is not contained in the item pointed to by the
+	   path. Set pos_in_item out of the item. */
+	if (is_indirect_le_ih(p_le_ih))
+		pos_in_item(p_s_search_path) =
+		    ih_item_len(p_le_ih) / UNFM_P_SIZE;
+	else
+		pos_in_item(p_s_search_path) = ih_item_len(p_le_ih);
 
-    /* we need only to know, whether it is the same item */
-    ih = get_ih (p_s_path);
-    return memcmp (stored_ih, ih, IH_SIZE);
+	return POSITION_NOT_FOUND;
 }
 
+/* Compare given item and item pointed to by the path. */
+int comp_items(const struct item_head *stored_ih, const struct path *p_s_path)
+{
+	struct buffer_head *p_s_bh;
+	struct item_head *ih;
+
+	/* Last buffer at the path is not in the tree. */
+	if (!B_IS_IN_TREE(p_s_bh = PATH_PLAST_BUFFER(p_s_path)))
+		return 1;
+
+	/* Last path position is invalid. */
+	if (PATH_LAST_POSITION(p_s_path) >= B_NR_ITEMS(p_s_bh))
+		return 1;
+
+	/* we need only to know, whether it is the same item */
+	ih = get_ih(p_s_path);
+	return memcmp(stored_ih, ih, IH_SIZE);
+}
 
 /* unformatted nodes are not logged anymore, ever.  This is safe
 ** now
@@ -876,461 +911,466 @@ int comp_items (const struct item_head *
 // block can not be forgotten as it is in I/O or held by someone
 #define block_in_use(bh) (buffer_locked(bh) || (held_by_others(bh)))
 
-
-
 // prepare for delete or cut of direct item
-static inline int prepare_for_direct_item (struct path * path,
-					   struct item_head * le_ih,
-					   struct inode * inode,
-					   loff_t new_file_length,
-					   int * cut_size)
-{
-    loff_t round_len;
-
-
-    if ( new_file_length == max_reiserfs_offset (inode) ) {
-	/* item has to be deleted */
-	*cut_size = -(IH_SIZE + ih_item_len(le_ih));
-	return M_DELETE;
-    }
-	
-    // new file gets truncated
-    if (get_inode_item_key_version (inode) == KEY_FORMAT_3_6) {
-	// 
-	round_len = ROUND_UP (new_file_length); 
-	/* this was n_new_file_length < le_ih ... */
-	if ( round_len < le_ih_k_offset (le_ih) )  {
-	    *cut_size = -(IH_SIZE + ih_item_len(le_ih));
-	    return M_DELETE; /* Delete this item. */
+static inline int prepare_for_direct_item(struct path *path,
+					  struct item_head *le_ih,
+					  struct inode *inode,
+					  loff_t new_file_length, int *cut_size)
+{
+	loff_t round_len;
+
+	if (new_file_length == max_reiserfs_offset(inode)) {
+		/* item has to be deleted */
+		*cut_size = -(IH_SIZE + ih_item_len(le_ih));
+		return M_DELETE;
+	}
+	// new file gets truncated
+	if (get_inode_item_key_version(inode) == KEY_FORMAT_3_6) {
+		// 
+		round_len = ROUND_UP(new_file_length);
+		/* this was n_new_file_length < le_ih ... */
+		if (round_len < le_ih_k_offset(le_ih)) {
+			*cut_size = -(IH_SIZE + ih_item_len(le_ih));
+			return M_DELETE;	/* Delete this item. */
+		}
+		/* Calculate first position and size for cutting from item. */
+		pos_in_item(path) = round_len - (le_ih_k_offset(le_ih) - 1);
+		*cut_size = -(ih_item_len(le_ih) - pos_in_item(path));
+
+		return M_CUT;	/* Cut from this item. */
 	}
-	/* Calculate first position and size for cutting from item. */
-	pos_in_item (path) = round_len - (le_ih_k_offset (le_ih) - 1);
-	*cut_size = -(ih_item_len(le_ih) - pos_in_item(path));
-	
-	return M_CUT; /* Cut from this item. */
-    }
-
-
-    // old file: items may have any length
-
-    if ( new_file_length < le_ih_k_offset (le_ih) )  {
-	*cut_size = -(IH_SIZE + ih_item_len(le_ih));
-	return M_DELETE; /* Delete this item. */
-    }
-    /* Calculate first position and size for cutting from item. */
-    *cut_size = -(ih_item_len(le_ih) -
-		      (pos_in_item (path) = new_file_length + 1 - le_ih_k_offset (le_ih)));
-    return M_CUT; /* Cut from this item. */
-}
 
+	// old file: items may have any length
 
-static inline int prepare_for_direntry_item (struct path * path,
-					     struct item_head * le_ih,
-					     struct inode * inode,
-					     loff_t new_file_length,
-					     int * cut_size)
-{
-    if (le_ih_k_offset (le_ih) == DOT_OFFSET && 
-	new_file_length == max_reiserfs_offset (inode)) {
-	RFALSE( ih_entry_count (le_ih) != 2,
-	        "PAP-5220: incorrect empty directory item (%h)", le_ih);
-	*cut_size = -(IH_SIZE + ih_item_len(le_ih));
-	return M_DELETE; /* Delete the directory item containing "." and ".." entry. */
-    }
-    
-    if ( ih_entry_count (le_ih) == 1 )  {
-	/* Delete the directory item such as there is one record only
-	   in this item*/
-	*cut_size = -(IH_SIZE + ih_item_len(le_ih));
-	return M_DELETE;
-    }
-    
-    /* Cut one record from the directory item. */
-    *cut_size = -(DEH_SIZE + entry_length (get_last_bh (path), le_ih, pos_in_item (path)));
-    return M_CUT; 
+	if (new_file_length < le_ih_k_offset(le_ih)) {
+		*cut_size = -(IH_SIZE + ih_item_len(le_ih));
+		return M_DELETE;	/* Delete this item. */
+	}
+	/* Calculate first position and size for cutting from item. */
+	*cut_size = -(ih_item_len(le_ih) -
+		      (pos_in_item(path) =
+		       new_file_length + 1 - le_ih_k_offset(le_ih)));
+	return M_CUT;		/* Cut from this item. */
+}
+
+static inline int prepare_for_direntry_item(struct path *path,
+					    struct item_head *le_ih,
+					    struct inode *inode,
+					    loff_t new_file_length,
+					    int *cut_size)
+{
+	if (le_ih_k_offset(le_ih) == DOT_OFFSET &&
+	    new_file_length == max_reiserfs_offset(inode)) {
+		RFALSE(ih_entry_count(le_ih) != 2,
+		       "PAP-5220: incorrect empty directory item (%h)", le_ih);
+		*cut_size = -(IH_SIZE + ih_item_len(le_ih));
+		return M_DELETE;	/* Delete the directory item containing "." and ".." entry. */
+	}
+
+	if (ih_entry_count(le_ih) == 1) {
+		/* Delete the directory item such as there is one record only
+		   in this item */
+		*cut_size = -(IH_SIZE + ih_item_len(le_ih));
+		return M_DELETE;
+	}
+
+	/* Cut one record from the directory item. */
+	*cut_size =
+	    -(DEH_SIZE +
+	      entry_length(get_last_bh(path), le_ih, pos_in_item(path)));
+	return M_CUT;
 }
 
-
 /*  If the path points to a directory or direct item, calculate mode and the size cut, for balance.
     If the path points to an indirect item, remove some number of its unformatted nodes.
     In case of file truncate calculate whether this item must be deleted/truncated or last
     unformatted node of this item will be converted to a direct item.
     This function returns a determination of what balance mode the calling function should employ. */
-static char  prepare_for_delete_or_cut(
-				       struct reiserfs_transaction_handle *th, 
-				       struct inode * inode,
-				       struct path         * p_s_path,
-				       const struct cpu_key      * p_s_item_key,
-				       int                 * p_n_removed,      /* Number of unformatted nodes which were removed
-										  from end of the file. */
-				       int                 * p_n_cut_size,
-				       unsigned long long    n_new_file_length /* MAX_KEY_OFFSET in case of delete. */
-    ) {
-    struct super_block  * p_s_sb = inode->i_sb;
-    struct item_head    * p_le_ih = PATH_PITEM_HEAD(p_s_path);
-    struct buffer_head  * p_s_bh = PATH_PLAST_BUFFER(p_s_path);
-
-    BUG_ON (!th->t_trans_id);
-
-    /* Stat_data item. */
-    if ( is_statdata_le_ih (p_le_ih) ) {
-
-	RFALSE( n_new_file_length != max_reiserfs_offset (inode),
-		"PAP-5210: mode must be M_DELETE");
-
-	*p_n_cut_size = -(IH_SIZE + ih_item_len(p_le_ih));
-	return M_DELETE;
-    }
-
-
-    /* Directory item. */
-    if ( is_direntry_le_ih (p_le_ih) )
-	return prepare_for_direntry_item (p_s_path, p_le_ih, inode, n_new_file_length, p_n_cut_size);
-
-    /* Direct item. */
-    if ( is_direct_le_ih (p_le_ih) )
-	return prepare_for_direct_item (p_s_path, p_le_ih, inode, n_new_file_length, p_n_cut_size);
-
-
-    /* Case of an indirect item. */
-    {
-	int                   n_unfm_number,    /* Number of the item unformatted nodes. */
-	    n_counter,
-	    n_blk_size;
-	__le32               * p_n_unfm_pointer; /* Pointer to the unformatted node number. */
-	__u32 tmp;
-	struct item_head      s_ih;           /* Item header. */
-	char                  c_mode;           /* Returned mode of the balance. */
-	int need_research;
+static char prepare_for_delete_or_cut(struct reiserfs_transaction_handle *th, struct inode *inode, struct path *p_s_path, const struct cpu_key *p_s_item_key, int *p_n_removed,	/* Number of unformatted nodes which were removed
+																						   from end of the file. */
+				      int *p_n_cut_size, unsigned long long n_new_file_length	/* MAX_KEY_OFFSET in case of delete. */
+    )
+{
+	struct super_block *p_s_sb = inode->i_sb;
+	struct item_head *p_le_ih = PATH_PITEM_HEAD(p_s_path);
+	struct buffer_head *p_s_bh = PATH_PLAST_BUFFER(p_s_path);
 
+	BUG_ON(!th->t_trans_id);
 
-	n_blk_size = p_s_sb->s_blocksize;
+	/* Stat_data item. */
+	if (is_statdata_le_ih(p_le_ih)) {
 
-	/* Search for the needed object indirect item until there are no unformatted nodes to be removed. */
-	do  {
-	    need_research = 0;
-            p_s_bh = PATH_PLAST_BUFFER(p_s_path);
-	    /* Copy indirect item header to a temp variable. */
-	    copy_item_head(&s_ih, PATH_PITEM_HEAD(p_s_path));
-	    /* Calculate number of unformatted nodes in this item. */
-	    n_unfm_number = I_UNFM_NUM(&s_ih);
-
-	    RFALSE( ! is_indirect_le_ih(&s_ih) || ! n_unfm_number ||
-		    pos_in_item (p_s_path) + 1 !=  n_unfm_number,
-		    "PAP-5240: invalid item %h "
-		    "n_unfm_number = %d *p_n_pos_in_item = %d", 
-		    &s_ih, n_unfm_number, pos_in_item (p_s_path));
-
-	    /* Calculate balance mode and position in the item to remove unformatted nodes. */
-	    if ( n_new_file_length == max_reiserfs_offset (inode) ) {/* Case of delete. */
-		pos_in_item (p_s_path) = 0;
-		*p_n_cut_size = -(IH_SIZE + ih_item_len(&s_ih));
-		c_mode = M_DELETE;
-	    }
-	    else  { /* Case of truncate. */
-		if ( n_new_file_length < le_ih_k_offset (&s_ih) )  {
-		    pos_in_item (p_s_path) = 0;
-		    *p_n_cut_size = -(IH_SIZE + ih_item_len(&s_ih));
-		    c_mode = M_DELETE; /* Delete this item. */
-		}
-		else  {
-		    /* indirect item must be truncated starting from *p_n_pos_in_item-th position */
-		    pos_in_item (p_s_path) = (n_new_file_length + n_blk_size - le_ih_k_offset (&s_ih) ) >> p_s_sb->s_blocksize_bits;
-
-		    RFALSE( pos_in_item (p_s_path) > n_unfm_number,
-			    "PAP-5250: invalid position in the item");
-
-		    /* Either convert last unformatted node of indirect item to direct item or increase
-		       its free space.  */
-		    if ( pos_in_item (p_s_path) == n_unfm_number )  {
-			*p_n_cut_size = 0; /* Nothing to cut. */
-			return M_CONVERT; /* Maybe convert last unformatted node to the direct item. */
-		    }
-		    /* Calculate size to cut. */
-		    *p_n_cut_size = -(ih_item_len(&s_ih) - pos_in_item(p_s_path) * UNFM_P_SIZE);
-
-		    c_mode = M_CUT;     /* Cut from this indirect item. */
-		}
-	    }
-
-	    RFALSE( n_unfm_number <= pos_in_item (p_s_path),
-		    "PAP-5260: invalid position in the indirect item");
-
-	    /* pointers to be cut */
-	    n_unfm_number -= pos_in_item (p_s_path);
-	    /* Set pointer to the last unformatted node pointer that is to be cut. */
-	    p_n_unfm_pointer = (__le32 *)B_I_PITEM(p_s_bh, &s_ih) + I_UNFM_NUM(&s_ih) - 1 - *p_n_removed;
-
-
-	    /* We go through the unformatted nodes pointers of the indirect
-	       item and look for the unformatted nodes in the cache. If we
-	       found some of them we free it, zero corresponding indirect item
-	       entry and log buffer containing that indirect item. For this we
-	       need to prepare last path element for logging. If some
-	       unformatted node has b_count > 1 we must not free this
-	       unformatted node since it is in use. */
-	    reiserfs_prepare_for_journal(p_s_sb, p_s_bh, 1);
-	    // note: path could be changed, first line in for loop takes care
-	    // of it
-
-	    for (n_counter = *p_n_removed;
-		 n_counter < n_unfm_number; n_counter++, p_n_unfm_pointer-- ) {
-
-		cond_resched();
-		if (item_moved (&s_ih, p_s_path)) {
-		    need_research = 1 ;
-		    break;
-		}
-		RFALSE( p_n_unfm_pointer < (__le32 *)B_I_PITEM(p_s_bh, &s_ih) ||
-			p_n_unfm_pointer > (__le32 *)B_I_PITEM(p_s_bh, &s_ih) + I_UNFM_NUM(&s_ih) - 1,
-			"vs-5265: pointer out of range");
-
-		/* Hole, nothing to remove. */
-		if ( ! get_block_num(p_n_unfm_pointer,0) )  {
-			(*p_n_removed)++;
-			continue;
-		}
+		RFALSE(n_new_file_length != max_reiserfs_offset(inode),
+		       "PAP-5210: mode must be M_DELETE");
+
+		*p_n_cut_size = -(IH_SIZE + ih_item_len(p_le_ih));
+		return M_DELETE;
+	}
+
+	/* Directory item. */
+	if (is_direntry_le_ih(p_le_ih))
+		return prepare_for_direntry_item(p_s_path, p_le_ih, inode,
+						 n_new_file_length,
+						 p_n_cut_size);
 
-		(*p_n_removed)++;
+	/* Direct item. */
+	if (is_direct_le_ih(p_le_ih))
+		return prepare_for_direct_item(p_s_path, p_le_ih, inode,
+					       n_new_file_length, p_n_cut_size);
 
-		tmp = get_block_num(p_n_unfm_pointer,0);
-		put_block_num(p_n_unfm_pointer, 0, 0);
-		journal_mark_dirty (th, p_s_sb, p_s_bh);
-		reiserfs_free_block(th, inode, tmp, 1);
-		if ( item_moved (&s_ih, p_s_path) )  {
-			need_research = 1;
-			break ;
-		}
-	    }
-
-	    /* a trick.  If the buffer has been logged, this
-	    ** will do nothing.  If we've broken the loop without
-	    ** logging it, it will restore the buffer
-	    **
-	    */
-	    reiserfs_restore_prepared_buffer(p_s_sb, p_s_bh);
-
-	    /* This loop can be optimized. */
-	} while ( (*p_n_removed < n_unfm_number || need_research) &&
-		  search_for_position_by_key(p_s_sb, p_s_item_key, p_s_path) == POSITION_FOUND );
-
-	RFALSE( *p_n_removed < n_unfm_number, 
-		"PAP-5310: indirect item is not found");
-	RFALSE( item_moved (&s_ih, p_s_path), 
-		"after while, comp failed, retry") ;
-
-	if (c_mode == M_CUT)
-	    pos_in_item (p_s_path) *= UNFM_P_SIZE;
-	return c_mode;
-    }
+	/* Case of an indirect item. */
+	{
+		int n_unfm_number,	/* Number of the item unformatted nodes. */
+		 n_counter, n_blk_size;
+		__le32 *p_n_unfm_pointer;	/* Pointer to the unformatted node number. */
+		__u32 tmp;
+		struct item_head s_ih;	/* Item header. */
+		char c_mode;	/* Returned mode of the balance. */
+		int need_research;
+
+		n_blk_size = p_s_sb->s_blocksize;
+
+		/* Search for the needed object indirect item until there are no unformatted nodes to be removed. */
+		do {
+			need_research = 0;
+			p_s_bh = PATH_PLAST_BUFFER(p_s_path);
+			/* Copy indirect item header to a temp variable. */
+			copy_item_head(&s_ih, PATH_PITEM_HEAD(p_s_path));
+			/* Calculate number of unformatted nodes in this item. */
+			n_unfm_number = I_UNFM_NUM(&s_ih);
+
+			RFALSE(!is_indirect_le_ih(&s_ih) || !n_unfm_number ||
+			       pos_in_item(p_s_path) + 1 != n_unfm_number,
+			       "PAP-5240: invalid item %h "
+			       "n_unfm_number = %d *p_n_pos_in_item = %d",
+			       &s_ih, n_unfm_number, pos_in_item(p_s_path));
+
+			/* Calculate balance mode and position in the item to remove unformatted nodes. */
+			if (n_new_file_length == max_reiserfs_offset(inode)) {	/* Case of delete. */
+				pos_in_item(p_s_path) = 0;
+				*p_n_cut_size = -(IH_SIZE + ih_item_len(&s_ih));
+				c_mode = M_DELETE;
+			} else {	/* Case of truncate. */
+				if (n_new_file_length < le_ih_k_offset(&s_ih)) {
+					pos_in_item(p_s_path) = 0;
+					*p_n_cut_size =
+					    -(IH_SIZE + ih_item_len(&s_ih));
+					c_mode = M_DELETE;	/* Delete this item. */
+				} else {
+					/* indirect item must be truncated starting from *p_n_pos_in_item-th position */
+					pos_in_item(p_s_path) =
+					    (n_new_file_length + n_blk_size -
+					     le_ih_k_offset(&s_ih)) >> p_s_sb->
+					    s_blocksize_bits;
+
+					RFALSE(pos_in_item(p_s_path) >
+					       n_unfm_number,
+					       "PAP-5250: invalid position in the item");
+
+					/* Either convert last unformatted node of indirect item to direct item or increase
+					   its free space.  */
+					if (pos_in_item(p_s_path) ==
+					    n_unfm_number) {
+						*p_n_cut_size = 0;	/* Nothing to cut. */
+						return M_CONVERT;	/* Maybe convert last unformatted node to the direct item. */
+					}
+					/* Calculate size to cut. */
+					*p_n_cut_size =
+					    -(ih_item_len(&s_ih) -
+					      pos_in_item(p_s_path) *
+					      UNFM_P_SIZE);
+
+					c_mode = M_CUT;	/* Cut from this indirect item. */
+				}
+			}
+
+			RFALSE(n_unfm_number <= pos_in_item(p_s_path),
+			       "PAP-5260: invalid position in the indirect item");
+
+			/* pointers to be cut */
+			n_unfm_number -= pos_in_item(p_s_path);
+			/* Set pointer to the last unformatted node pointer that is to be cut. */
+			p_n_unfm_pointer =
+			    (__le32 *) B_I_PITEM(p_s_bh,
+						 &s_ih) + I_UNFM_NUM(&s_ih) -
+			    1 - *p_n_removed;
+
+			/* We go through the unformatted nodes pointers of the indirect
+			   item and look for the unformatted nodes in the cache. If we
+			   found some of them we free it, zero corresponding indirect item
+			   entry and log buffer containing that indirect item. For this we
+			   need to prepare last path element for logging. If some
+			   unformatted node has b_count > 1 we must not free this
+			   unformatted node since it is in use. */
+			reiserfs_prepare_for_journal(p_s_sb, p_s_bh, 1);
+			// note: path could be changed, first line in for loop takes care
+			// of it
+
+			for (n_counter = *p_n_removed;
+			     n_counter < n_unfm_number;
+			     n_counter++, p_n_unfm_pointer--) {
+
+				cond_resched();
+				if (item_moved(&s_ih, p_s_path)) {
+					need_research = 1;
+					break;
+				}
+				RFALSE(p_n_unfm_pointer <
+				       (__le32 *) B_I_PITEM(p_s_bh, &s_ih)
+				       || p_n_unfm_pointer >
+				       (__le32 *) B_I_PITEM(p_s_bh,
+							    &s_ih) +
+				       I_UNFM_NUM(&s_ih) - 1,
+				       "vs-5265: pointer out of range");
+
+				/* Hole, nothing to remove. */
+				if (!get_block_num(p_n_unfm_pointer, 0)) {
+					(*p_n_removed)++;
+					continue;
+				}
+
+				(*p_n_removed)++;
+
+				tmp = get_block_num(p_n_unfm_pointer, 0);
+				put_block_num(p_n_unfm_pointer, 0, 0);
+				journal_mark_dirty(th, p_s_sb, p_s_bh);
+				reiserfs_free_block(th, inode, tmp, 1);
+				if (item_moved(&s_ih, p_s_path)) {
+					need_research = 1;
+					break;
+				}
+			}
+
+			/* a trick.  If the buffer has been logged, this
+			 ** will do nothing.  If we've broken the loop without
+			 ** logging it, it will restore the buffer
+			 **
+			 */
+			reiserfs_restore_prepared_buffer(p_s_sb, p_s_bh);
+
+			/* This loop can be optimized. */
+		} while ((*p_n_removed < n_unfm_number || need_research) &&
+			 search_for_position_by_key(p_s_sb, p_s_item_key,
+						    p_s_path) ==
+			 POSITION_FOUND);
+
+		RFALSE(*p_n_removed < n_unfm_number,
+		       "PAP-5310: indirect item is not found");
+		RFALSE(item_moved(&s_ih, p_s_path),
+		       "after while, comp failed, retry");
+
+		if (c_mode == M_CUT)
+			pos_in_item(p_s_path) *= UNFM_P_SIZE;
+		return c_mode;
+	}
 }
 
 /* Calculate number of bytes which will be deleted or cut during balance */
-static int calc_deleted_bytes_number(
-    struct  tree_balance  * p_s_tb,
-    char                    c_mode
-    ) {
-    int                     n_del_size;
-    struct  item_head     * p_le_ih = PATH_PITEM_HEAD(p_s_tb->tb_path);
+static int calc_deleted_bytes_number(struct tree_balance *p_s_tb, char c_mode)
+{
+	int n_del_size;
+	struct item_head *p_le_ih = PATH_PITEM_HEAD(p_s_tb->tb_path);
 
-    if ( is_statdata_le_ih (p_le_ih) )
-	return 0;
+	if (is_statdata_le_ih(p_le_ih))
+		return 0;
 
-    n_del_size = ( c_mode == M_DELETE ) ? ih_item_len(p_le_ih) : -p_s_tb->insert_size[0];
-    if ( is_direntry_le_ih (p_le_ih) ) {
-	// return EMPTY_DIR_SIZE; /* We delete emty directoris only. */
-	// we can't use EMPTY_DIR_SIZE, as old format dirs have a different
-	// empty size.  ick. FIXME, is this right?
-	//
-	return n_del_size ;
-    }
+	n_del_size =
+	    (c_mode ==
+	     M_DELETE) ? ih_item_len(p_le_ih) : -p_s_tb->insert_size[0];
+	if (is_direntry_le_ih(p_le_ih)) {
+		// return EMPTY_DIR_SIZE; /* We delete emty directoris only. */
+		// we can't use EMPTY_DIR_SIZE, as old format dirs have a different
+		// empty size.  ick. FIXME, is this right?
+		//
+		return n_del_size;
+	}
 
-    if ( is_indirect_le_ih (p_le_ih) )
-	n_del_size = (n_del_size/UNFM_P_SIZE)*
-	  (PATH_PLAST_BUFFER(p_s_tb->tb_path)->b_size);// - get_ih_free_space (p_le_ih);
-    return n_del_size;
+	if (is_indirect_le_ih(p_le_ih))
+		n_del_size = (n_del_size / UNFM_P_SIZE) * (PATH_PLAST_BUFFER(p_s_tb->tb_path)->b_size);	// - get_ih_free_space (p_le_ih);
+	return n_del_size;
 }
 
-static void init_tb_struct(
-    struct reiserfs_transaction_handle *th,
-    struct tree_balance * p_s_tb,
-    struct super_block  * p_s_sb,
-    struct path         * p_s_path,
-    int                   n_size
-    ) {
+static void init_tb_struct(struct reiserfs_transaction_handle *th,
+			   struct tree_balance *p_s_tb,
+			   struct super_block *p_s_sb,
+			   struct path *p_s_path, int n_size)
+{
 
-    BUG_ON (!th->t_trans_id);
+	BUG_ON(!th->t_trans_id);
 
-    memset (p_s_tb,'\0',sizeof(struct tree_balance));
-    p_s_tb->transaction_handle = th ;
-    p_s_tb->tb_sb = p_s_sb;
-    p_s_tb->tb_path = p_s_path;
-    PATH_OFFSET_PBUFFER(p_s_path, ILLEGAL_PATH_ELEMENT_OFFSET) = NULL;
-    PATH_OFFSET_POSITION(p_s_path, ILLEGAL_PATH_ELEMENT_OFFSET) = 0;
-    p_s_tb->insert_size[0] = n_size;
+	memset(p_s_tb, '\0', sizeof(struct tree_balance));
+	p_s_tb->transaction_handle = th;
+	p_s_tb->tb_sb = p_s_sb;
+	p_s_tb->tb_path = p_s_path;
+	PATH_OFFSET_PBUFFER(p_s_path, ILLEGAL_PATH_ELEMENT_OFFSET) = NULL;
+	PATH_OFFSET_POSITION(p_s_path, ILLEGAL_PATH_ELEMENT_OFFSET) = 0;
+	p_s_tb->insert_size[0] = n_size;
 }
 
-
-
-void padd_item (char * item, int total_length, int length)
+void padd_item(char *item, int total_length, int length)
 {
-    int i;
+	int i;
 
-    for (i = total_length; i > length; )
-	item [--i] = 0;
+	for (i = total_length; i > length;)
+		item[--i] = 0;
 }
 
 #ifdef REISERQUOTA_DEBUG
 char key2type(struct reiserfs_key *ih)
 {
-  if (is_direntry_le_key(2, ih))
-    return 'd';
-  if (is_direct_le_key(2, ih))
-    return 'D';
-  if (is_indirect_le_key(2, ih))
-    return 'i';
-  if (is_statdata_le_key(2, ih))
-    return 's';
-  return 'u';
+	if (is_direntry_le_key(2, ih))
+		return 'd';
+	if (is_direct_le_key(2, ih))
+		return 'D';
+	if (is_indirect_le_key(2, ih))
+		return 'i';
+	if (is_statdata_le_key(2, ih))
+		return 's';
+	return 'u';
 }
 
 char head2type(struct item_head *ih)
 {
-  if (is_direntry_le_ih(ih))
-    return 'd';
-  if (is_direct_le_ih(ih))
-    return 'D';
-  if (is_indirect_le_ih(ih))
-    return 'i';
-  if (is_statdata_le_ih(ih))
-    return 's';
-  return 'u';
+	if (is_direntry_le_ih(ih))
+		return 'd';
+	if (is_direct_le_ih(ih))
+		return 'D';
+	if (is_indirect_le_ih(ih))
+		return 'i';
+	if (is_statdata_le_ih(ih))
+		return 's';
+	return 'u';
 }
 #endif
 
 /* Delete object item. */
-int reiserfs_delete_item (struct reiserfs_transaction_handle *th, 
-			  struct path * p_s_path, /* Path to the deleted item. */
-			  const struct cpu_key * p_s_item_key, /* Key to search for the deleted item.  */
-			  struct inode * p_s_inode,/* inode is here just to update i_blocks and quotas */
-			  struct buffer_head  * p_s_un_bh)    /* NULL or unformatted node pointer.    */
-{
-    struct super_block * p_s_sb = p_s_inode->i_sb;
-    struct tree_balance   s_del_balance;
-    struct item_head      s_ih;
-    struct item_head      *q_ih;
-    int			  quota_cut_bytes;
-    int                   n_ret_value,
-	n_del_size,
-	n_removed;
+int reiserfs_delete_item(struct reiserfs_transaction_handle *th, struct path *p_s_path,	/* Path to the deleted item. */
+			 const struct cpu_key *p_s_item_key,	/* Key to search for the deleted item.  */
+			 struct inode *p_s_inode,	/* inode is here just to update i_blocks and quotas */
+			 struct buffer_head *p_s_un_bh)
+{				/* NULL or unformatted node pointer.    */
+	struct super_block *p_s_sb = p_s_inode->i_sb;
+	struct tree_balance s_del_balance;
+	struct item_head s_ih;
+	struct item_head *q_ih;
+	int quota_cut_bytes;
+	int n_ret_value, n_del_size, n_removed;
 
 #ifdef CONFIG_REISERFS_CHECK
-    char                  c_mode;
-    int			n_iter = 0;
+	char c_mode;
+	int n_iter = 0;
 #endif
 
-    BUG_ON (!th->t_trans_id);
+	BUG_ON(!th->t_trans_id);
 
-    init_tb_struct(th, &s_del_balance, p_s_sb, p_s_path, 0/*size is unknown*/);
+	init_tb_struct(th, &s_del_balance, p_s_sb, p_s_path,
+		       0 /*size is unknown */ );
 
-    while ( 1 ) {
-	n_removed = 0;
+	while (1) {
+		n_removed = 0;
 
 #ifdef CONFIG_REISERFS_CHECK
-	n_iter++;
-	c_mode =
+		n_iter++;
+		c_mode =
 #endif
-	    prepare_for_delete_or_cut(th, p_s_inode, p_s_path, p_s_item_key, &n_removed, &n_del_size, max_reiserfs_offset (p_s_inode));
-
-	RFALSE( c_mode != M_DELETE, "PAP-5320: mode must be M_DELETE");
-
-	copy_item_head(&s_ih, PATH_PITEM_HEAD(p_s_path));
-	s_del_balance.insert_size[0] = n_del_size;
-
-	n_ret_value = fix_nodes(M_DELETE, &s_del_balance, NULL, NULL);
-	if ( n_ret_value != REPEAT_SEARCH )
-	    break;
-
-	PROC_INFO_INC( p_s_sb, delete_item_restarted );
+		    prepare_for_delete_or_cut(th, p_s_inode, p_s_path,
+					      p_s_item_key, &n_removed,
+					      &n_del_size,
+					      max_reiserfs_offset(p_s_inode));
+
+		RFALSE(c_mode != M_DELETE, "PAP-5320: mode must be M_DELETE");
+
+		copy_item_head(&s_ih, PATH_PITEM_HEAD(p_s_path));
+		s_del_balance.insert_size[0] = n_del_size;
+
+		n_ret_value = fix_nodes(M_DELETE, &s_del_balance, NULL, NULL);
+		if (n_ret_value != REPEAT_SEARCH)
+			break;
+
+		PROC_INFO_INC(p_s_sb, delete_item_restarted);
+
+		// file system changed, repeat search
+		n_ret_value =
+		    search_for_position_by_key(p_s_sb, p_s_item_key, p_s_path);
+		if (n_ret_value == IO_ERROR)
+			break;
+		if (n_ret_value == FILE_NOT_FOUND) {
+			reiserfs_warning(p_s_sb,
+					 "vs-5340: reiserfs_delete_item: "
+					 "no items of the file %K found",
+					 p_s_item_key);
+			break;
+		}
+	}			/* while (1) */
 
-	// file system changed, repeat search
-	n_ret_value = search_for_position_by_key(p_s_sb, p_s_item_key, p_s_path);
-	if (n_ret_value == IO_ERROR)
-	    break;
-	if (n_ret_value == FILE_NOT_FOUND) {
-	    reiserfs_warning (p_s_sb, "vs-5340: reiserfs_delete_item: "
-			      "no items of the file %K found", p_s_item_key);
-	    break;
+	if (n_ret_value != CARRY_ON) {
+		unfix_nodes(&s_del_balance);
+		return 0;
+	}
+	// reiserfs_delete_item returns item length when success
+	n_ret_value = calc_deleted_bytes_number(&s_del_balance, M_DELETE);
+	q_ih = get_ih(p_s_path);
+	quota_cut_bytes = ih_item_len(q_ih);
+
+	/* hack so the quota code doesn't have to guess if the file
+	 ** has a tail.  On tail insert, we allocate quota for 1 unformatted node.
+	 ** We test the offset because the tail might have been
+	 ** split into multiple items, and we only want to decrement for
+	 ** the unfm node once
+	 */
+	if (!S_ISLNK(p_s_inode->i_mode) && is_direct_le_ih(q_ih)) {
+		if ((le_ih_k_offset(q_ih) & (p_s_sb->s_blocksize - 1)) == 1) {
+			quota_cut_bytes = p_s_sb->s_blocksize + UNFM_P_SIZE;
+		} else {
+			quota_cut_bytes = 0;
+		}
 	}
-    } /* while (1) */
 
-    if ( n_ret_value != CARRY_ON ) {
-	unfix_nodes(&s_del_balance);
-	return 0;
-    }
+	if (p_s_un_bh) {
+		int off;
+		char *data;
+
+		/* We are in direct2indirect conversion, so move tail contents
+		   to the unformatted node */
+		/* note, we do the copy before preparing the buffer because we
+		 ** don't care about the contents of the unformatted node yet.
+		 ** the only thing we really care about is the direct item's data
+		 ** is in the unformatted node.
+		 **
+		 ** Otherwise, we would have to call reiserfs_prepare_for_journal on
+		 ** the unformatted node, which might schedule, meaning we'd have to
+		 ** loop all the way back up to the start of the while loop.
+		 **
+		 ** The unformatted node must be dirtied later on.  We can't be
+		 ** sure here if the entire tail has been deleted yet.
+		 **
+		 ** p_s_un_bh is from the page cache (all unformatted nodes are
+		 ** from the page cache) and might be a highmem page.  So, we
+		 ** can't use p_s_un_bh->b_data.
+		 ** -clm
+		 */
 
-    // reiserfs_delete_item returns item length when success
-    n_ret_value = calc_deleted_bytes_number(&s_del_balance, M_DELETE);
-    q_ih = get_ih(p_s_path) ;
-    quota_cut_bytes = ih_item_len(q_ih) ;
-
-    /* hack so the quota code doesn't have to guess if the file
-    ** has a tail.  On tail insert, we allocate quota for 1 unformatted node.
-    ** We test the offset because the tail might have been
-    ** split into multiple items, and we only want to decrement for
-    ** the unfm node once
-    */
-    if (!S_ISLNK (p_s_inode->i_mode) && is_direct_le_ih(q_ih)) {
-        if ((le_ih_k_offset(q_ih) & (p_s_sb->s_blocksize - 1)) == 1) {
-            quota_cut_bytes = p_s_sb->s_blocksize + UNFM_P_SIZE;
-        } else {
-	    quota_cut_bytes = 0 ;
-	}
-    }
-
-    if ( p_s_un_bh )  {
-	int off;
-        char *data ;
-
-	/* We are in direct2indirect conversion, so move tail contents
-           to the unformatted node */
-	/* note, we do the copy before preparing the buffer because we
-	** don't care about the contents of the unformatted node yet.
-	** the only thing we really care about is the direct item's data
-	** is in the unformatted node.
-	**
-	** Otherwise, we would have to call reiserfs_prepare_for_journal on
-	** the unformatted node, which might schedule, meaning we'd have to
-	** loop all the way back up to the start of the while loop.
-	**
-	** The unformatted node must be dirtied later on.  We can't be
-	** sure here if the entire tail has been deleted yet.
-        **
-        ** p_s_un_bh is from the page cache (all unformatted nodes are
-        ** from the page cache) and might be a highmem page.  So, we
-        ** can't use p_s_un_bh->b_data.
-	** -clm
-	*/
-
-        data = kmap_atomic(p_s_un_bh->b_page, KM_USER0);
-	off = ((le_ih_k_offset (&s_ih) - 1) & (PAGE_CACHE_SIZE - 1));
-	memcpy(data + off,
-	       B_I_PITEM(PATH_PLAST_BUFFER(p_s_path), &s_ih), n_ret_value);
-	kunmap_atomic(data, KM_USER0);
-    }
-    /* Perform balancing after all resources have been collected at once. */ 
-    do_balance(&s_del_balance, NULL, NULL, M_DELETE);
+		data = kmap_atomic(p_s_un_bh->b_page, KM_USER0);
+		off = ((le_ih_k_offset(&s_ih) - 1) & (PAGE_CACHE_SIZE - 1));
+		memcpy(data + off,
+		       B_I_PITEM(PATH_PLAST_BUFFER(p_s_path), &s_ih),
+		       n_ret_value);
+		kunmap_atomic(data, KM_USER0);
+	}
+	/* Perform balancing after all resources have been collected at once. */
+	do_balance(&s_del_balance, NULL, NULL, M_DELETE);
 
 #ifdef REISERQUOTA_DEBUG
-    reiserfs_debug (p_s_sb, REISERFS_DEBUG_CODE, "reiserquota delete_item(): freeing %u, id=%u type=%c", quota_cut_bytes, p_s_inode->i_uid, head2type(&s_ih));
+	reiserfs_debug(p_s_sb, REISERFS_DEBUG_CODE,
+		       "reiserquota delete_item(): freeing %u, id=%u type=%c",
+		       quota_cut_bytes, p_s_inode->i_uid, head2type(&s_ih));
 #endif
-    DQUOT_FREE_SPACE_NODIRTY(p_s_inode, quota_cut_bytes);
+	DQUOT_FREE_SPACE_NODIRTY(p_s_inode, quota_cut_bytes);
 
-    /* Return deleted body length */
-    return n_ret_value;
+	/* Return deleted body length */
+	return n_ret_value;
 }
 
-
 /* Summary Of Mechanisms For Handling Collisions Between Processes:
 
  deletion of the body of the object is performed by iput(), with the
@@ -1347,727 +1387,804 @@ int reiserfs_delete_item (struct reiserf
  - Hans
 */
 
-
 /* this deletes item which never gets split */
-void reiserfs_delete_solid_item (struct reiserfs_transaction_handle *th,
-				 struct inode *inode,
-				 struct reiserfs_key * key)
-{
-    struct tree_balance tb;
-    INITIALIZE_PATH (path);
-    int item_len = 0;
-    int tb_init = 0 ;
-    struct cpu_key cpu_key;
-    int retval;
-    int quota_cut_bytes = 0;
-
-    BUG_ON (!th->t_trans_id);
-    
-    le_key2cpu_key (&cpu_key, key);
-    
-    while (1) {
-	retval = search_item (th->t_super, &cpu_key, &path);
-	if (retval == IO_ERROR) {
-	    reiserfs_warning (th->t_super,
-			      "vs-5350: reiserfs_delete_solid_item: "
-			      "i/o failure occurred trying to delete %K",
-			      &cpu_key);
-	    break;
-	}
-	if (retval != ITEM_FOUND) {
-	    pathrelse (&path);
-	    // No need for a warning, if there is just no free space to insert '..' item into the newly-created subdir
-	    if ( !( (unsigned long long) GET_HASH_VALUE (le_key_k_offset (le_key_version (key), key)) == 0 && \
-		 (unsigned long long) GET_GENERATION_NUMBER (le_key_k_offset (le_key_version (key), key)) == 1 ) )
-		reiserfs_warning (th->t_super, "vs-5355: reiserfs_delete_solid_item: %k not found", key);
-	    break;
-	}
-	if (!tb_init) {
-	    tb_init = 1 ;
-	    item_len = ih_item_len( PATH_PITEM_HEAD(&path) );
-	    init_tb_struct (th, &tb, th->t_super, &path, - (IH_SIZE + item_len));
-	}
-	quota_cut_bytes = ih_item_len(PATH_PITEM_HEAD(&path)) ;
-
-	retval = fix_nodes (M_DELETE, &tb, NULL, NULL);
-	if (retval == REPEAT_SEARCH) {
-	    PROC_INFO_INC( th -> t_super, delete_solid_item_restarted );
-	    continue;
-	}
+void reiserfs_delete_solid_item(struct reiserfs_transaction_handle *th,
+				struct inode *inode, struct reiserfs_key *key)
+{
+	struct tree_balance tb;
+	INITIALIZE_PATH(path);
+	int item_len = 0;
+	int tb_init = 0;
+	struct cpu_key cpu_key;
+	int retval;
+	int quota_cut_bytes = 0;
+
+	BUG_ON(!th->t_trans_id);
+
+	le_key2cpu_key(&cpu_key, key);
+
+	while (1) {
+		retval = search_item(th->t_super, &cpu_key, &path);
+		if (retval == IO_ERROR) {
+			reiserfs_warning(th->t_super,
+					 "vs-5350: reiserfs_delete_solid_item: "
+					 "i/o failure occurred trying to delete %K",
+					 &cpu_key);
+			break;
+		}
+		if (retval != ITEM_FOUND) {
+			pathrelse(&path);
+			// No need for a warning, if there is just no free space to insert '..' item into the newly-created subdir
+			if (!
+			    ((unsigned long long)
+			     GET_HASH_VALUE(le_key_k_offset
+					    (le_key_version(key), key)) == 0
+			     && (unsigned long long)
+			     GET_GENERATION_NUMBER(le_key_k_offset
+						   (le_key_version(key),
+						    key)) == 1))
+				reiserfs_warning(th->t_super,
+						 "vs-5355: reiserfs_delete_solid_item: %k not found",
+						 key);
+			break;
+		}
+		if (!tb_init) {
+			tb_init = 1;
+			item_len = ih_item_len(PATH_PITEM_HEAD(&path));
+			init_tb_struct(th, &tb, th->t_super, &path,
+				       -(IH_SIZE + item_len));
+		}
+		quota_cut_bytes = ih_item_len(PATH_PITEM_HEAD(&path));
 
-	if (retval == CARRY_ON) {
-	    do_balance (&tb, NULL, NULL, M_DELETE);
-	    if (inode) {	/* Should we count quota for item? (we don't count quotas for save-links) */
+		retval = fix_nodes(M_DELETE, &tb, NULL, NULL);
+		if (retval == REPEAT_SEARCH) {
+			PROC_INFO_INC(th->t_super, delete_solid_item_restarted);
+			continue;
+		}
+
+		if (retval == CARRY_ON) {
+			do_balance(&tb, NULL, NULL, M_DELETE);
+			if (inode) {	/* Should we count quota for item? (we don't count quotas for save-links) */
 #ifdef REISERQUOTA_DEBUG
-		reiserfs_debug (th->t_super, REISERFS_DEBUG_CODE, "reiserquota delete_solid_item(): freeing %u id=%u type=%c", quota_cut_bytes, inode->i_uid, key2type(key));
+				reiserfs_debug(th->t_super, REISERFS_DEBUG_CODE,
+					       "reiserquota delete_solid_item(): freeing %u id=%u type=%c",
+					       quota_cut_bytes, inode->i_uid,
+					       key2type(key));
 #endif
-		DQUOT_FREE_SPACE_NODIRTY(inode, quota_cut_bytes);
-	    }
-	    break;
-	}
-
-	// IO_ERROR, NO_DISK_SPACE, etc
-	reiserfs_warning (th->t_super, "vs-5360: reiserfs_delete_solid_item: "
-			  "could not delete %K due to fix_nodes failure", &cpu_key);
-	unfix_nodes (&tb);
-	break;
-    }
-
-    reiserfs_check_path(&path) ;
-}
-
-
-int reiserfs_delete_object (struct reiserfs_transaction_handle *th, struct inode * inode)
-{
-    int err;
-    inode->i_size = 0;
-    BUG_ON (!th->t_trans_id);
+				DQUOT_FREE_SPACE_NODIRTY(inode,
+							 quota_cut_bytes);
+			}
+			break;
+		}
+		// IO_ERROR, NO_DISK_SPACE, etc
+		reiserfs_warning(th->t_super,
+				 "vs-5360: reiserfs_delete_solid_item: "
+				 "could not delete %K due to fix_nodes failure",
+				 &cpu_key);
+		unfix_nodes(&tb);
+		break;
+	}
+
+	reiserfs_check_path(&path);
+}
+
+int reiserfs_delete_object(struct reiserfs_transaction_handle *th,
+			   struct inode *inode)
+{
+	int err;
+	inode->i_size = 0;
+	BUG_ON(!th->t_trans_id);
+
+	/* for directory this deletes item containing "." and ".." */
+	err =
+	    reiserfs_do_truncate(th, inode, NULL, 0 /*no timestamp updates */ );
+	if (err)
+		return err;
 
-    /* for directory this deletes item containing "." and ".." */
-    err = reiserfs_do_truncate (th, inode, NULL, 0/*no timestamp updates*/);
-    if (err)
-        return err;
-    
 #if defined( USE_INODE_GENERATION_COUNTER )
-    if( !old_format_only ( th -> t_super ) )
-      {
-       __le32 *inode_generation;
-       
-       inode_generation = 
-         &REISERFS_SB(th -> t_super) -> s_rs -> s_inode_generation;
-       *inode_generation = cpu_to_le32( le32_to_cpu( *inode_generation ) + 1 );
-      }
+	if (!old_format_only(th->t_super)) {
+		__le32 *inode_generation;
+
+		inode_generation =
+		    &REISERFS_SB(th->t_super)->s_rs->s_inode_generation;
+		*inode_generation =
+		    cpu_to_le32(le32_to_cpu(*inode_generation) + 1);
+	}
 /* USE_INODE_GENERATION_COUNTER */
 #endif
-    reiserfs_delete_solid_item (th, inode, INODE_PKEY (inode));
+	reiserfs_delete_solid_item(th, inode, INODE_PKEY(inode));
 
-    return err;
+	return err;
 }
 
-static void
-unmap_buffers(struct page *page, loff_t pos) {
-    struct buffer_head *bh ;
-    struct buffer_head *head ;
-    struct buffer_head *next ;
-    unsigned long tail_index ;
-    unsigned long cur_index ;
-
-    if (page) {
-	if (page_has_buffers(page)) {
-	    tail_index = pos & (PAGE_CACHE_SIZE - 1) ;
-	    cur_index = 0 ;
-	    head = page_buffers(page) ;
-	    bh = head ;
-	    do {
-		next = bh->b_this_page ;
-
-		/* we want to unmap the buffers that contain the tail, and
-		** all the buffers after it (since the tail must be at the
-		** end of the file).  We don't want to unmap file data
-		** before the tail, since it might be dirty and waiting to
-		** reach disk
-		*/
-		cur_index += bh->b_size ;
-		if (cur_index > tail_index) {
-		    reiserfs_unmap_buffer(bh) ;
-		}
-		bh = next ;
-	    } while (bh != head) ;
-	    if ( PAGE_SIZE == bh->b_size ) {
-		clear_page_dirty(page);
-	    }
-	}
-    }
-}
-
-static int maybe_indirect_to_direct (struct reiserfs_transaction_handle *th, 
-			      struct inode * p_s_inode,
-			      struct page *page, 
-			      struct path         * p_s_path,
-			      const struct cpu_key      * p_s_item_key,
-			      loff_t         n_new_file_size,
-			      char                * p_c_mode
-			      ) {
-    struct super_block * p_s_sb = p_s_inode->i_sb;
-    int n_block_size = p_s_sb->s_blocksize;
-    int cut_bytes;
-    BUG_ON (!th->t_trans_id);
-
-    if (n_new_file_size != p_s_inode->i_size)
-	BUG ();
-
-    /* the page being sent in could be NULL if there was an i/o error
-    ** reading in the last block.  The user will hit problems trying to
-    ** read the file, but for now we just skip the indirect2direct
-    */
-    if (atomic_read(&p_s_inode->i_count) > 1 || 
-        !tail_has_to_be_packed (p_s_inode) || 
-	!page || (REISERFS_I(p_s_inode)->i_flags & i_nopack_mask)) {
-	// leave tail in an unformatted node	
-	*p_c_mode = M_SKIP_BALANCING;
-	cut_bytes = n_block_size - (n_new_file_size & (n_block_size - 1));
-	pathrelse(p_s_path);
-	return cut_bytes;
-    }
-    /* Permorm the conversion to a direct_item. */
-    /*return indirect_to_direct (p_s_inode, p_s_path, p_s_item_key, n_new_file_size, p_c_mode);*/
-    return indirect2direct (th, p_s_inode, page, p_s_path, p_s_item_key, n_new_file_size, p_c_mode);
+static void unmap_buffers(struct page *page, loff_t pos)
+{
+	struct buffer_head *bh;
+	struct buffer_head *head;
+	struct buffer_head *next;
+	unsigned long tail_index;
+	unsigned long cur_index;
+
+	if (page) {
+		if (page_has_buffers(page)) {
+			tail_index = pos & (PAGE_CACHE_SIZE - 1);
+			cur_index = 0;
+			head = page_buffers(page);
+			bh = head;
+			do {
+				next = bh->b_this_page;
+
+				/* we want to unmap the buffers that contain the tail, and
+				 ** all the buffers after it (since the tail must be at the
+				 ** end of the file).  We don't want to unmap file data
+				 ** before the tail, since it might be dirty and waiting to
+				 ** reach disk
+				 */
+				cur_index += bh->b_size;
+				if (cur_index > tail_index) {
+					reiserfs_unmap_buffer(bh);
+				}
+				bh = next;
+			} while (bh != head);
+			if (PAGE_SIZE == bh->b_size) {
+				clear_page_dirty(page);
+			}
+		}
+	}
 }
 
+static int maybe_indirect_to_direct(struct reiserfs_transaction_handle *th,
+				    struct inode *p_s_inode,
+				    struct page *page,
+				    struct path *p_s_path,
+				    const struct cpu_key *p_s_item_key,
+				    loff_t n_new_file_size, char *p_c_mode)
+{
+	struct super_block *p_s_sb = p_s_inode->i_sb;
+	int n_block_size = p_s_sb->s_blocksize;
+	int cut_bytes;
+	BUG_ON(!th->t_trans_id);
+
+	if (n_new_file_size != p_s_inode->i_size)
+		BUG();
+
+	/* the page being sent in could be NULL if there was an i/o error
+	 ** reading in the last block.  The user will hit problems trying to
+	 ** read the file, but for now we just skip the indirect2direct
+	 */
+	if (atomic_read(&p_s_inode->i_count) > 1 ||
+	    !tail_has_to_be_packed(p_s_inode) ||
+	    !page || (REISERFS_I(p_s_inode)->i_flags & i_nopack_mask)) {
+		// leave tail in an unformatted node    
+		*p_c_mode = M_SKIP_BALANCING;
+		cut_bytes =
+		    n_block_size - (n_new_file_size & (n_block_size - 1));
+		pathrelse(p_s_path);
+		return cut_bytes;
+	}
+	/* Permorm the conversion to a direct_item. */
+	/*return indirect_to_direct (p_s_inode, p_s_path, p_s_item_key, n_new_file_size, p_c_mode); */
+	return indirect2direct(th, p_s_inode, page, p_s_path, p_s_item_key,
+			       n_new_file_size, p_c_mode);
+}
 
 /* we did indirect_to_direct conversion. And we have inserted direct
    item successesfully, but there were no disk space to cut unfm
    pointer being converted. Therefore we have to delete inserted
    direct item(s) */
-static void indirect_to_direct_roll_back (struct reiserfs_transaction_handle *th, struct inode * inode, struct path * path)
+static void indirect_to_direct_roll_back(struct reiserfs_transaction_handle *th,
+					 struct inode *inode, struct path *path)
 {
-    struct cpu_key tail_key;
-    int tail_len;
-    int removed;
-    BUG_ON (!th->t_trans_id);
-
-    make_cpu_key (&tail_key, inode, inode->i_size + 1, TYPE_DIRECT, 4);// !!!!
-    tail_key.key_length = 4;
-
-    tail_len = (cpu_key_k_offset (&tail_key) & (inode->i_sb->s_blocksize - 1)) - 1;
-    while (tail_len) {
-	/* look for the last byte of the tail */
-	if (search_for_position_by_key (inode->i_sb, &tail_key, path) == POSITION_NOT_FOUND)
-	    reiserfs_panic (inode->i_sb, "vs-5615: indirect_to_direct_roll_back: found invalid item");
-	RFALSE( path->pos_in_item != ih_item_len(PATH_PITEM_HEAD (path)) - 1,
-	        "vs-5616: appended bytes found");
-	PATH_LAST_POSITION (path) --;
-	
-	removed = reiserfs_delete_item (th, path, &tail_key, inode, NULL/*unbh not needed*/);
-	RFALSE( removed <= 0 || removed > tail_len,
-	        "vs-5617: there was tail %d bytes, removed item length %d bytes",
-                tail_len, removed);
-	tail_len -= removed;
-	set_cpu_key_k_offset (&tail_key, cpu_key_k_offset (&tail_key) - removed);
-    }
-    reiserfs_warning (inode->i_sb, "indirect_to_direct_roll_back: indirect_to_direct conversion has been rolled back due to lack of disk space");
-    //mark_file_without_tail (inode);
-    mark_inode_dirty (inode);
+	struct cpu_key tail_key;
+	int tail_len;
+	int removed;
+	BUG_ON(!th->t_trans_id);
+
+	make_cpu_key(&tail_key, inode, inode->i_size + 1, TYPE_DIRECT, 4);	// !!!!
+	tail_key.key_length = 4;
+
+	tail_len =
+	    (cpu_key_k_offset(&tail_key) & (inode->i_sb->s_blocksize - 1)) - 1;
+	while (tail_len) {
+		/* look for the last byte of the tail */
+		if (search_for_position_by_key(inode->i_sb, &tail_key, path) ==
+		    POSITION_NOT_FOUND)
+			reiserfs_panic(inode->i_sb,
+				       "vs-5615: indirect_to_direct_roll_back: found invalid item");
+		RFALSE(path->pos_in_item !=
+		       ih_item_len(PATH_PITEM_HEAD(path)) - 1,
+		       "vs-5616: appended bytes found");
+		PATH_LAST_POSITION(path)--;
+
+		removed =
+		    reiserfs_delete_item(th, path, &tail_key, inode,
+					 NULL /*unbh not needed */ );
+		RFALSE(removed <= 0
+		       || removed > tail_len,
+		       "vs-5617: there was tail %d bytes, removed item length %d bytes",
+		       tail_len, removed);
+		tail_len -= removed;
+		set_cpu_key_k_offset(&tail_key,
+				     cpu_key_k_offset(&tail_key) - removed);
+	}
+	reiserfs_warning(inode->i_sb,
+			 "indirect_to_direct_roll_back: indirect_to_direct conversion has been rolled back due to lack of disk space");
+	//mark_file_without_tail (inode);
+	mark_inode_dirty(inode);
 }
 
-
 /* (Truncate or cut entry) or delete object item. Returns < 0 on failure */
-int reiserfs_cut_from_item (struct reiserfs_transaction_handle *th, 
-			    struct path * p_s_path,
-			    struct cpu_key * p_s_item_key,
-			    struct inode * p_s_inode,
-			    struct page *page, 
-			    loff_t n_new_file_size)
-{
-    struct super_block * p_s_sb = p_s_inode->i_sb;
-    /* Every function which is going to call do_balance must first
-       create a tree_balance structure.  Then it must fill up this
-       structure by using the init_tb_struct and fix_nodes functions.
-       After that we can make tree balancing. */
-    struct tree_balance s_cut_balance;
-    struct item_head *p_le_ih;
-    int n_cut_size = 0,        /* Amount to be cut. */
-	n_ret_value = CARRY_ON,
-	n_removed = 0,     /* Number of the removed unformatted nodes. */
-	n_is_inode_locked = 0;
-    char                c_mode;            /* Mode of the balance. */
-    int retval2 = -1;
-    int quota_cut_bytes;
-    loff_t tail_pos = 0;
-
-    BUG_ON (!th->t_trans_id);
-    
-    init_tb_struct(th, &s_cut_balance, p_s_inode->i_sb, p_s_path, n_cut_size);
-
-
-    /* Repeat this loop until we either cut the item without needing
-       to balance, or we fix_nodes without schedule occurring */
-    while ( 1 ) {
-	/* Determine the balance mode, position of the first byte to
-	   be cut, and size to be cut.  In case of the indirect item
-	   free unformatted nodes which are pointed to by the cut
-	   pointers. */
-      
-	c_mode = prepare_for_delete_or_cut(th, p_s_inode, p_s_path, p_s_item_key, &n_removed, 
-					   &n_cut_size, n_new_file_size);
-	if ( c_mode == M_CONVERT )  {
-	    /* convert last unformatted node to direct item or leave
-               tail in the unformatted node */
-	    RFALSE( n_ret_value != CARRY_ON, "PAP-5570: can not convert twice");
-
-	    n_ret_value = maybe_indirect_to_direct (th, p_s_inode, page, p_s_path, p_s_item_key,
-						    n_new_file_size, &c_mode);
-	    if ( c_mode == M_SKIP_BALANCING )
-		/* tail has been left in the unformatted node */
-		return n_ret_value;
-
-	    n_is_inode_locked = 1;
-	  
-	    /* removing of last unformatted node will change value we
-               have to return to truncate. Save it */
-	    retval2 = n_ret_value;
-	    /*retval2 = p_s_sb->s_blocksize - (n_new_file_size & (p_s_sb->s_blocksize - 1));*/
-	  
-	    /* So, we have performed the first part of the conversion:
-	       inserting the new direct item.  Now we are removing the
-	       last unformatted node pointer. Set key to search for
-	       it. */
-      	    set_cpu_key_k_type (p_s_item_key, TYPE_INDIRECT);
-	    p_s_item_key->key_length = 4;
-	    n_new_file_size -= (n_new_file_size & (p_s_sb->s_blocksize - 1));
-	    tail_pos = n_new_file_size;
-	    set_cpu_key_k_offset (p_s_item_key, n_new_file_size + 1);
-	    if ( search_for_position_by_key(p_s_sb, p_s_item_key, p_s_path) == POSITION_NOT_FOUND ){
-		print_block (PATH_PLAST_BUFFER (p_s_path), 3, PATH_LAST_POSITION (p_s_path) - 1, PATH_LAST_POSITION (p_s_path) + 1);
-		reiserfs_panic(p_s_sb, "PAP-5580: reiserfs_cut_from_item: item to convert does not exist (%K)", p_s_item_key);
-	    }
-	    continue;
-	}
-	if (n_cut_size == 0) {
-	    pathrelse (p_s_path);
-	    return 0;
-	}
-
-	s_cut_balance.insert_size[0] = n_cut_size;
-	
-	n_ret_value = fix_nodes(c_mode, &s_cut_balance, NULL, NULL);
-      	if ( n_ret_value != REPEAT_SEARCH )
-	    break;
-	
-	PROC_INFO_INC( p_s_sb, cut_from_item_restarted );
-
-	n_ret_value = search_for_position_by_key(p_s_sb, p_s_item_key, p_s_path);
-	if (n_ret_value == POSITION_FOUND)
-	    continue;
-
-	reiserfs_warning (p_s_sb, "PAP-5610: reiserfs_cut_from_item: item %K not found", p_s_item_key);
-	unfix_nodes (&s_cut_balance);
-	return (n_ret_value == IO_ERROR) ? -EIO : -ENOENT;
-    } /* while */
-  
-    // check fix_nodes results (IO_ERROR or NO_DISK_SPACE)
-    if ( n_ret_value != CARRY_ON ) {
-	if ( n_is_inode_locked ) {
-	    // FIXME: this seems to be not needed: we are always able
-	    // to cut item
-	    indirect_to_direct_roll_back (th, p_s_inode, p_s_path);
-	}
-	if (n_ret_value == NO_DISK_SPACE)
-	    reiserfs_warning (p_s_sb, "NO_DISK_SPACE");
-	unfix_nodes (&s_cut_balance);
-	return -EIO;
-    }
-
-    /* go ahead and perform balancing */
-    
-    RFALSE( c_mode == M_PASTE || c_mode == M_INSERT, "invalid mode");
-
-    /* Calculate number of bytes that need to be cut from the item. */
-    quota_cut_bytes = ( c_mode == M_DELETE ) ? ih_item_len(get_ih(p_s_path)) : -s_cut_balance.insert_size[0];
-    if (retval2 == -1)
-	n_ret_value = calc_deleted_bytes_number(&s_cut_balance, c_mode);
-    else
-	n_ret_value = retval2;
-
-
-    /* For direct items, we only change the quota when deleting the last
-    ** item.
-    */
-    p_le_ih = PATH_PITEM_HEAD (s_cut_balance.tb_path);
-    if (!S_ISLNK (p_s_inode->i_mode) && is_direct_le_ih(p_le_ih)) {
-        if (c_mode == M_DELETE &&
-	   (le_ih_k_offset (p_le_ih) & (p_s_sb->s_blocksize - 1)) == 1 ) {
-	    // FIXME: this is to keep 3.5 happy
-	    REISERFS_I(p_s_inode)->i_first_direct_byte = U32_MAX;
-	    quota_cut_bytes = p_s_sb->s_blocksize + UNFM_P_SIZE ;
-        } else {
-	    quota_cut_bytes = 0 ;
+int reiserfs_cut_from_item(struct reiserfs_transaction_handle *th,
+			   struct path *p_s_path,
+			   struct cpu_key *p_s_item_key,
+			   struct inode *p_s_inode,
+			   struct page *page, loff_t n_new_file_size)
+{
+	struct super_block *p_s_sb = p_s_inode->i_sb;
+	/* Every function which is going to call do_balance must first
+	   create a tree_balance structure.  Then it must fill up this
+	   structure by using the init_tb_struct and fix_nodes functions.
+	   After that we can make tree balancing. */
+	struct tree_balance s_cut_balance;
+	struct item_head *p_le_ih;
+	int n_cut_size = 0,	/* Amount to be cut. */
+	    n_ret_value = CARRY_ON, n_removed = 0,	/* Number of the removed unformatted nodes. */
+	    n_is_inode_locked = 0;
+	char c_mode;		/* Mode of the balance. */
+	int retval2 = -1;
+	int quota_cut_bytes;
+	loff_t tail_pos = 0;
+
+	BUG_ON(!th->t_trans_id);
+
+	init_tb_struct(th, &s_cut_balance, p_s_inode->i_sb, p_s_path,
+		       n_cut_size);
+
+	/* Repeat this loop until we either cut the item without needing
+	   to balance, or we fix_nodes without schedule occurring */
+	while (1) {
+		/* Determine the balance mode, position of the first byte to
+		   be cut, and size to be cut.  In case of the indirect item
+		   free unformatted nodes which are pointed to by the cut
+		   pointers. */
+
+		c_mode =
+		    prepare_for_delete_or_cut(th, p_s_inode, p_s_path,
+					      p_s_item_key, &n_removed,
+					      &n_cut_size, n_new_file_size);
+		if (c_mode == M_CONVERT) {
+			/* convert last unformatted node to direct item or leave
+			   tail in the unformatted node */
+			RFALSE(n_ret_value != CARRY_ON,
+			       "PAP-5570: can not convert twice");
+
+			n_ret_value =
+			    maybe_indirect_to_direct(th, p_s_inode, page,
+						     p_s_path, p_s_item_key,
+						     n_new_file_size, &c_mode);
+			if (c_mode == M_SKIP_BALANCING)
+				/* tail has been left in the unformatted node */
+				return n_ret_value;
+
+			n_is_inode_locked = 1;
+
+			/* removing of last unformatted node will change value we
+			   have to return to truncate. Save it */
+			retval2 = n_ret_value;
+			/*retval2 = p_s_sb->s_blocksize - (n_new_file_size & (p_s_sb->s_blocksize - 1)); */
+
+			/* So, we have performed the first part of the conversion:
+			   inserting the new direct item.  Now we are removing the
+			   last unformatted node pointer. Set key to search for
+			   it. */
+			set_cpu_key_k_type(p_s_item_key, TYPE_INDIRECT);
+			p_s_item_key->key_length = 4;
+			n_new_file_size -=
+			    (n_new_file_size & (p_s_sb->s_blocksize - 1));
+			tail_pos = n_new_file_size;
+			set_cpu_key_k_offset(p_s_item_key, n_new_file_size + 1);
+			if (search_for_position_by_key
+			    (p_s_sb, p_s_item_key,
+			     p_s_path) == POSITION_NOT_FOUND) {
+				print_block(PATH_PLAST_BUFFER(p_s_path), 3,
+					    PATH_LAST_POSITION(p_s_path) - 1,
+					    PATH_LAST_POSITION(p_s_path) + 1);
+				reiserfs_panic(p_s_sb,
+					       "PAP-5580: reiserfs_cut_from_item: item to convert does not exist (%K)",
+					       p_s_item_key);
+			}
+			continue;
+		}
+		if (n_cut_size == 0) {
+			pathrelse(p_s_path);
+			return 0;
+		}
+
+		s_cut_balance.insert_size[0] = n_cut_size;
+
+		n_ret_value = fix_nodes(c_mode, &s_cut_balance, NULL, NULL);
+		if (n_ret_value != REPEAT_SEARCH)
+			break;
+
+		PROC_INFO_INC(p_s_sb, cut_from_item_restarted);
+
+		n_ret_value =
+		    search_for_position_by_key(p_s_sb, p_s_item_key, p_s_path);
+		if (n_ret_value == POSITION_FOUND)
+			continue;
+
+		reiserfs_warning(p_s_sb,
+				 "PAP-5610: reiserfs_cut_from_item: item %K not found",
+				 p_s_item_key);
+		unfix_nodes(&s_cut_balance);
+		return (n_ret_value == IO_ERROR) ? -EIO : -ENOENT;
+	}			/* while */
+
+	// check fix_nodes results (IO_ERROR or NO_DISK_SPACE)
+	if (n_ret_value != CARRY_ON) {
+		if (n_is_inode_locked) {
+			// FIXME: this seems to be not needed: we are always able
+			// to cut item
+			indirect_to_direct_roll_back(th, p_s_inode, p_s_path);
+		}
+		if (n_ret_value == NO_DISK_SPACE)
+			reiserfs_warning(p_s_sb, "NO_DISK_SPACE");
+		unfix_nodes(&s_cut_balance);
+		return -EIO;
+	}
+
+	/* go ahead and perform balancing */
+
+	RFALSE(c_mode == M_PASTE || c_mode == M_INSERT, "invalid mode");
+
+	/* Calculate number of bytes that need to be cut from the item. */
+	quota_cut_bytes =
+	    (c_mode ==
+	     M_DELETE) ? ih_item_len(get_ih(p_s_path)) : -s_cut_balance.
+	    insert_size[0];
+	if (retval2 == -1)
+		n_ret_value = calc_deleted_bytes_number(&s_cut_balance, c_mode);
+	else
+		n_ret_value = retval2;
+
+	/* For direct items, we only change the quota when deleting the last
+	 ** item.
+	 */
+	p_le_ih = PATH_PITEM_HEAD(s_cut_balance.tb_path);
+	if (!S_ISLNK(p_s_inode->i_mode) && is_direct_le_ih(p_le_ih)) {
+		if (c_mode == M_DELETE &&
+		    (le_ih_k_offset(p_le_ih) & (p_s_sb->s_blocksize - 1)) ==
+		    1) {
+			// FIXME: this is to keep 3.5 happy
+			REISERFS_I(p_s_inode)->i_first_direct_byte = U32_MAX;
+			quota_cut_bytes = p_s_sb->s_blocksize + UNFM_P_SIZE;
+		} else {
+			quota_cut_bytes = 0;
+		}
 	}
-    }
 #ifdef CONFIG_REISERFS_CHECK
-    if (n_is_inode_locked) {
-	struct item_head * le_ih = PATH_PITEM_HEAD (s_cut_balance.tb_path);
-	/* we are going to complete indirect2direct conversion. Make
-           sure, that we exactly remove last unformatted node pointer
-           of the item */
-	if (!is_indirect_le_ih (le_ih))
-	    reiserfs_panic (p_s_sb, "vs-5652: reiserfs_cut_from_item: "
-			    "item must be indirect %h", le_ih);
-
-	if (c_mode == M_DELETE && ih_item_len(le_ih) != UNFM_P_SIZE)
-	    reiserfs_panic (p_s_sb, "vs-5653: reiserfs_cut_from_item: "
-			    "completing indirect2direct conversion indirect item %h "
-			    "being deleted must be of 4 byte long", le_ih);
-
-	if (c_mode == M_CUT && s_cut_balance.insert_size[0] != -UNFM_P_SIZE) {
-	    reiserfs_panic (p_s_sb, "vs-5654: reiserfs_cut_from_item: "
-			    "can not complete indirect2direct conversion of %h (CUT, insert_size==%d)",
-			    le_ih, s_cut_balance.insert_size[0]);
-	}
-	/* it would be useful to make sure, that right neighboring
-           item is direct item of this file */
-    }
+	if (n_is_inode_locked) {
+		struct item_head *le_ih =
+		    PATH_PITEM_HEAD(s_cut_balance.tb_path);
+		/* we are going to complete indirect2direct conversion. Make
+		   sure, that we exactly remove last unformatted node pointer
+		   of the item */
+		if (!is_indirect_le_ih(le_ih))
+			reiserfs_panic(p_s_sb,
+				       "vs-5652: reiserfs_cut_from_item: "
+				       "item must be indirect %h", le_ih);
+
+		if (c_mode == M_DELETE && ih_item_len(le_ih) != UNFM_P_SIZE)
+			reiserfs_panic(p_s_sb,
+				       "vs-5653: reiserfs_cut_from_item: "
+				       "completing indirect2direct conversion indirect item %h "
+				       "being deleted must be of 4 byte long",
+				       le_ih);
+
+		if (c_mode == M_CUT
+		    && s_cut_balance.insert_size[0] != -UNFM_P_SIZE) {
+			reiserfs_panic(p_s_sb,
+				       "vs-5654: reiserfs_cut_from_item: "
+				       "can not complete indirect2direct conversion of %h (CUT, insert_size==%d)",
+				       le_ih, s_cut_balance.insert_size[0]);
+		}
+		/* it would be useful to make sure, that right neighboring
+		   item is direct item of this file */
+	}
 #endif
-    
-    do_balance(&s_cut_balance, NULL, NULL, c_mode);
-    if ( n_is_inode_locked ) {
-	/* we've done an indirect->direct conversion.  when the data block
-	** was freed, it was removed from the list of blocks that must
-	** be flushed before the transaction commits, make sure to
-	** unmap and invalidate it
-	*/
-	unmap_buffers(page, tail_pos);
-	REISERFS_I(p_s_inode)->i_flags &= ~i_pack_on_close_mask ;
-    }
+
+	do_balance(&s_cut_balance, NULL, NULL, c_mode);
+	if (n_is_inode_locked) {
+		/* we've done an indirect->direct conversion.  when the data block
+		 ** was freed, it was removed from the list of blocks that must
+		 ** be flushed before the transaction commits, make sure to
+		 ** unmap and invalidate it
+		 */
+		unmap_buffers(page, tail_pos);
+		REISERFS_I(p_s_inode)->i_flags &= ~i_pack_on_close_mask;
+	}
 #ifdef REISERQUOTA_DEBUG
-    reiserfs_debug (p_s_inode->i_sb, REISERFS_DEBUG_CODE, "reiserquota cut_from_item(): freeing %u id=%u type=%c", quota_cut_bytes, p_s_inode->i_uid, '?');
+	reiserfs_debug(p_s_inode->i_sb, REISERFS_DEBUG_CODE,
+		       "reiserquota cut_from_item(): freeing %u id=%u type=%c",
+		       quota_cut_bytes, p_s_inode->i_uid, '?');
 #endif
-    DQUOT_FREE_SPACE_NODIRTY(p_s_inode, quota_cut_bytes);
-    return n_ret_value;
+	DQUOT_FREE_SPACE_NODIRTY(p_s_inode, quota_cut_bytes);
+	return n_ret_value;
 }
 
-static void truncate_directory (struct reiserfs_transaction_handle *th, struct inode * inode)
+static void truncate_directory(struct reiserfs_transaction_handle *th,
+			       struct inode *inode)
 {
-    BUG_ON (!th->t_trans_id);
-    if (inode->i_nlink)
-	reiserfs_warning (inode->i_sb,
-			  "vs-5655: truncate_directory: link count != 0");
-
-    set_le_key_k_offset (KEY_FORMAT_3_5, INODE_PKEY (inode), DOT_OFFSET);
-    set_le_key_k_type (KEY_FORMAT_3_5, INODE_PKEY (inode), TYPE_DIRENTRY);
-    reiserfs_delete_solid_item (th, inode, INODE_PKEY (inode));
-    reiserfs_update_sd(th, inode) ;
-    set_le_key_k_offset (KEY_FORMAT_3_5, INODE_PKEY (inode), SD_OFFSET);
-    set_le_key_k_type (KEY_FORMAT_3_5, INODE_PKEY (inode), TYPE_STAT_DATA);    
+	BUG_ON(!th->t_trans_id);
+	if (inode->i_nlink)
+		reiserfs_warning(inode->i_sb,
+				 "vs-5655: truncate_directory: link count != 0");
+
+	set_le_key_k_offset(KEY_FORMAT_3_5, INODE_PKEY(inode), DOT_OFFSET);
+	set_le_key_k_type(KEY_FORMAT_3_5, INODE_PKEY(inode), TYPE_DIRENTRY);
+	reiserfs_delete_solid_item(th, inode, INODE_PKEY(inode));
+	reiserfs_update_sd(th, inode);
+	set_le_key_k_offset(KEY_FORMAT_3_5, INODE_PKEY(inode), SD_OFFSET);
+	set_le_key_k_type(KEY_FORMAT_3_5, INODE_PKEY(inode), TYPE_STAT_DATA);
 }
 
-
-
-
 /* Truncate file to the new size. Note, this must be called with a transaction
    already started */
-int reiserfs_do_truncate (struct reiserfs_transaction_handle *th,
-			   struct  inode * p_s_inode, /* ->i_size contains new
-                                                         size */
-			   struct page *page, /* up to date for last block */
-			   int update_timestamps  /* when it is called by
-						     file_release to convert
-						     the tail - no timestamps
-						     should be updated */
-    ) {
-    INITIALIZE_PATH (s_search_path);       /* Path to the current object item. */
-    struct item_head    * p_le_ih;         /* Pointer to an item header. */
-    struct cpu_key      s_item_key;     /* Key to search for a previous file item. */
-    loff_t         n_file_size,    /* Old file size. */
-	n_new_file_size;/* New file size. */
-    int                   n_deleted;      /* Number of deleted or truncated bytes. */
-    int retval;
-    int err = 0;
-
-    BUG_ON (!th->t_trans_id);
-    if ( ! (S_ISREG(p_s_inode->i_mode) || S_ISDIR(p_s_inode->i_mode) || S_ISLNK(p_s_inode->i_mode)) )
-	return 0;
-
-    if (S_ISDIR(p_s_inode->i_mode)) {
-	// deletion of directory - no need to update timestamps
-	truncate_directory (th, p_s_inode);
-	return 0;
-    }
+int reiserfs_do_truncate(struct reiserfs_transaction_handle *th, struct inode *p_s_inode,	/* ->i_size contains new
+												   size */
+			 struct page *page,	/* up to date for last block */
+			 int update_timestamps	/* when it is called by
+						   file_release to convert
+						   the tail - no timestamps
+						   should be updated */
+    )
+{
+	INITIALIZE_PATH(s_search_path);	/* Path to the current object item. */
+	struct item_head *p_le_ih;	/* Pointer to an item header. */
+	struct cpu_key s_item_key;	/* Key to search for a previous file item. */
+	loff_t n_file_size,	/* Old file size. */
+	 n_new_file_size;	/* New file size. */
+	int n_deleted;		/* Number of deleted or truncated bytes. */
+	int retval;
+	int err = 0;
+
+	BUG_ON(!th->t_trans_id);
+	if (!
+	    (S_ISREG(p_s_inode->i_mode) || S_ISDIR(p_s_inode->i_mode)
+	     || S_ISLNK(p_s_inode->i_mode)))
+		return 0;
+
+	if (S_ISDIR(p_s_inode->i_mode)) {
+		// deletion of directory - no need to update timestamps
+		truncate_directory(th, p_s_inode);
+		return 0;
+	}
+
+	/* Get new file size. */
+	n_new_file_size = p_s_inode->i_size;
+
+	// FIXME: note, that key type is unimportant here
+	make_cpu_key(&s_item_key, p_s_inode, max_reiserfs_offset(p_s_inode),
+		     TYPE_DIRECT, 3);
+
+	retval =
+	    search_for_position_by_key(p_s_inode->i_sb, &s_item_key,
+				       &s_search_path);
+	if (retval == IO_ERROR) {
+		reiserfs_warning(p_s_inode->i_sb,
+				 "vs-5657: reiserfs_do_truncate: "
+				 "i/o failure occurred trying to truncate %K",
+				 &s_item_key);
+		err = -EIO;
+		goto out;
+	}
+	if (retval == POSITION_FOUND || retval == FILE_NOT_FOUND) {
+		reiserfs_warning(p_s_inode->i_sb,
+				 "PAP-5660: reiserfs_do_truncate: "
+				 "wrong result %d of search for %K", retval,
+				 &s_item_key);
+
+		err = -EIO;
+		goto out;
+	}
+
+	s_search_path.pos_in_item--;
+
+	/* Get real file size (total length of all file items) */
+	p_le_ih = PATH_PITEM_HEAD(&s_search_path);
+	if (is_statdata_le_ih(p_le_ih))
+		n_file_size = 0;
+	else {
+		loff_t offset = le_ih_k_offset(p_le_ih);
+		int bytes =
+		    op_bytes_number(p_le_ih, p_s_inode->i_sb->s_blocksize);
+
+		/* this may mismatch with real file size: if last direct item
+		   had no padding zeros and last unformatted node had no free
+		   space, this file would have this file size */
+		n_file_size = offset + bytes - 1;
+	}
+	/*
+	 * are we doing a full truncate or delete, if so
+	 * kick in the reada code
+	 */
+	if (n_new_file_size == 0)
+		s_search_path.reada = PATH_READA | PATH_READA_BACK;
 
-    /* Get new file size. */
-    n_new_file_size = p_s_inode->i_size;
+	if (n_file_size == 0 || n_file_size < n_new_file_size) {
+		goto update_and_out;
+	}
 
-    // FIXME: note, that key type is unimportant here
-    make_cpu_key (&s_item_key, p_s_inode, max_reiserfs_offset (p_s_inode), TYPE_DIRECT, 3);
+	/* Update key to search for the last file item. */
+	set_cpu_key_k_offset(&s_item_key, n_file_size);
+
+	do {
+		/* Cut or delete file item. */
+		n_deleted =
+		    reiserfs_cut_from_item(th, &s_search_path, &s_item_key,
+					   p_s_inode, page, n_new_file_size);
+		if (n_deleted < 0) {
+			reiserfs_warning(p_s_inode->i_sb,
+					 "vs-5665: reiserfs_do_truncate: reiserfs_cut_from_item failed");
+			reiserfs_check_path(&s_search_path);
+			return 0;
+		}
 
-    retval = search_for_position_by_key(p_s_inode->i_sb, &s_item_key, &s_search_path);
-    if (retval == IO_ERROR) {
-	reiserfs_warning (p_s_inode->i_sb, "vs-5657: reiserfs_do_truncate: "
-			  "i/o failure occurred trying to truncate %K", &s_item_key);
-        err = -EIO;
-        goto out;
-    }
-    if (retval == POSITION_FOUND || retval == FILE_NOT_FOUND) {
-	reiserfs_warning (p_s_inode->i_sb, "PAP-5660: reiserfs_do_truncate: "
-			  "wrong result %d of search for %K", retval, &s_item_key);
-
-        err = -EIO;
-        goto out;
-    }
-
-    s_search_path.pos_in_item --;
-
-    /* Get real file size (total length of all file items) */
-    p_le_ih = PATH_PITEM_HEAD(&s_search_path);
-    if ( is_statdata_le_ih (p_le_ih) )
-	n_file_size = 0;
-    else {
-	loff_t offset = le_ih_k_offset (p_le_ih);
-	int bytes = op_bytes_number (p_le_ih,p_s_inode->i_sb->s_blocksize);
-
-	/* this may mismatch with real file size: if last direct item
-           had no padding zeros and last unformatted node had no free
-           space, this file would have this file size */
-	n_file_size = offset + bytes - 1;
-    }
-    /*
-     * are we doing a full truncate or delete, if so
-     * kick in the reada code
-     */
-    if (n_new_file_size == 0)
-        s_search_path.reada = PATH_READA | PATH_READA_BACK;
-
-    if ( n_file_size == 0 || n_file_size < n_new_file_size ) {
-	goto update_and_out ;
-    }
-
-    /* Update key to search for the last file item. */
-    set_cpu_key_k_offset (&s_item_key, n_file_size);
-
-    do  {
-	/* Cut or delete file item. */
-	n_deleted = reiserfs_cut_from_item(th, &s_search_path, &s_item_key, p_s_inode,  page, n_new_file_size);
-	if (n_deleted < 0) {
-	    reiserfs_warning (p_s_inode->i_sb, "vs-5665: reiserfs_do_truncate: reiserfs_cut_from_item failed");
-	    reiserfs_check_path(&s_search_path) ;
-	    return 0;
-	}
-
-	RFALSE( n_deleted > n_file_size,
-		"PAP-5670: reiserfs_cut_from_item: too many bytes deleted: deleted %d, file_size %lu, item_key %K",
-		n_deleted, n_file_size, &s_item_key);
+		RFALSE(n_deleted > n_file_size,
+		       "PAP-5670: reiserfs_cut_from_item: too many bytes deleted: deleted %d, file_size %lu, item_key %K",
+		       n_deleted, n_file_size, &s_item_key);
 
-	/* Change key to search the last file item. */
-	n_file_size -= n_deleted;
+		/* Change key to search the last file item. */
+		n_file_size -= n_deleted;
 
-	set_cpu_key_k_offset (&s_item_key, n_file_size);
+		set_cpu_key_k_offset(&s_item_key, n_file_size);
 
-	/* While there are bytes to truncate and previous file item is presented in the tree. */
+		/* While there are bytes to truncate and previous file item is presented in the tree. */
 
-	/*
-	** This loop could take a really long time, and could log 
-	** many more blocks than a transaction can hold.  So, we do a polite
-	** journal end here, and if the transaction needs ending, we make
-	** sure the file is consistent before ending the current trans
-	** and starting a new one
-	*/
-        if (journal_transaction_should_end(th, th->t_blocks_allocated)) {
-	  int orig_len_alloc = th->t_blocks_allocated ;
-	  decrement_counters_in_path(&s_search_path) ;
-
-	  if (update_timestamps) {
-	      p_s_inode->i_mtime = p_s_inode->i_ctime = CURRENT_TIME_SEC;
-	  } 
-	  reiserfs_update_sd(th, p_s_inode) ;
-
-	  err = journal_end(th, p_s_inode->i_sb, orig_len_alloc) ;
-	  if (err)
-	    goto out;
-	  err = journal_begin (th, p_s_inode->i_sb,
-                               JOURNAL_PER_BALANCE_CNT * 6);
-	  if (err)
-	    goto out;
-	  reiserfs_update_inode_transaction(p_s_inode) ;
-	}
-    } while ( n_file_size > ROUND_UP (n_new_file_size) &&
-	      search_for_position_by_key(p_s_inode->i_sb, &s_item_key, &s_search_path) == POSITION_FOUND )  ;
-
-    RFALSE( n_file_size > ROUND_UP (n_new_file_size),
-	    "PAP-5680: truncate did not finish: new_file_size %Ld, current %Ld, oid %d",
-	    n_new_file_size, n_file_size, s_item_key.on_disk_key.k_objectid);
-
-update_and_out:
-    if (update_timestamps) {
-	// this is truncate, not file closing
-	    p_s_inode->i_mtime = p_s_inode->i_ctime = CURRENT_TIME_SEC;
-    }
-    reiserfs_update_sd (th, p_s_inode);
-
-out:
-    pathrelse(&s_search_path) ;
-    return err;
+		/*
+		 ** This loop could take a really long time, and could log 
+		 ** many more blocks than a transaction can hold.  So, we do a polite
+		 ** journal end here, and if the transaction needs ending, we make
+		 ** sure the file is consistent before ending the current trans
+		 ** and starting a new one
+		 */
+		if (journal_transaction_should_end(th, th->t_blocks_allocated)) {
+			int orig_len_alloc = th->t_blocks_allocated;
+			decrement_counters_in_path(&s_search_path);
+
+			if (update_timestamps) {
+				p_s_inode->i_mtime = p_s_inode->i_ctime =
+				    CURRENT_TIME_SEC;
+			}
+			reiserfs_update_sd(th, p_s_inode);
+
+			err = journal_end(th, p_s_inode->i_sb, orig_len_alloc);
+			if (err)
+				goto out;
+			err = journal_begin(th, p_s_inode->i_sb,
+					    JOURNAL_PER_BALANCE_CNT * 6);
+			if (err)
+				goto out;
+			reiserfs_update_inode_transaction(p_s_inode);
+		}
+	} while (n_file_size > ROUND_UP(n_new_file_size) &&
+		 search_for_position_by_key(p_s_inode->i_sb, &s_item_key,
+					    &s_search_path) == POSITION_FOUND);
+
+	RFALSE(n_file_size > ROUND_UP(n_new_file_size),
+	       "PAP-5680: truncate did not finish: new_file_size %Ld, current %Ld, oid %d",
+	       n_new_file_size, n_file_size, s_item_key.on_disk_key.k_objectid);
+
+      update_and_out:
+	if (update_timestamps) {
+		// this is truncate, not file closing
+		p_s_inode->i_mtime = p_s_inode->i_ctime = CURRENT_TIME_SEC;
+	}
+	reiserfs_update_sd(th, p_s_inode);
+
+      out:
+	pathrelse(&s_search_path);
+	return err;
 }
 
-
 #ifdef CONFIG_REISERFS_CHECK
 // this makes sure, that we __append__, not overwrite or add holes
-static void check_research_for_paste (struct path * path, 
-				      const struct cpu_key * p_s_key)
+static void check_research_for_paste(struct path *path,
+				     const struct cpu_key *p_s_key)
 {
-    struct item_head * found_ih = get_ih (path);
-    
-    if (is_direct_le_ih (found_ih)) {
-	if (le_ih_k_offset (found_ih) + op_bytes_number (found_ih, get_last_bh (path)->b_size) !=
-	    cpu_key_k_offset (p_s_key) ||
-	    op_bytes_number (found_ih, get_last_bh (path)->b_size) != pos_in_item (path))
-	    reiserfs_panic (NULL, "PAP-5720: check_research_for_paste: "
-			    "found direct item %h or position (%d) does not match to key %K",
-			    found_ih, pos_in_item (path), p_s_key);
-    }
-    if (is_indirect_le_ih (found_ih)) {
-	if (le_ih_k_offset (found_ih) + op_bytes_number (found_ih, get_last_bh (path)->b_size) != cpu_key_k_offset (p_s_key) || 
-	    I_UNFM_NUM (found_ih) != pos_in_item (path) ||
-	    get_ih_free_space (found_ih) != 0)
-	    reiserfs_panic (NULL, "PAP-5730: check_research_for_paste: "
-			    "found indirect item (%h) or position (%d) does not match to key (%K)",
-			    found_ih, pos_in_item (path), p_s_key);
-    }
-}
-#endif /* config reiserfs check */
+	struct item_head *found_ih = get_ih(path);
 
+	if (is_direct_le_ih(found_ih)) {
+		if (le_ih_k_offset(found_ih) +
+		    op_bytes_number(found_ih,
+				    get_last_bh(path)->b_size) !=
+		    cpu_key_k_offset(p_s_key)
+		    || op_bytes_number(found_ih,
+				       get_last_bh(path)->b_size) !=
+		    pos_in_item(path))
+			reiserfs_panic(NULL,
+				       "PAP-5720: check_research_for_paste: "
+				       "found direct item %h or position (%d) does not match to key %K",
+				       found_ih, pos_in_item(path), p_s_key);
+	}
+	if (is_indirect_le_ih(found_ih)) {
+		if (le_ih_k_offset(found_ih) +
+		    op_bytes_number(found_ih,
+				    get_last_bh(path)->b_size) !=
+		    cpu_key_k_offset(p_s_key)
+		    || I_UNFM_NUM(found_ih) != pos_in_item(path)
+		    || get_ih_free_space(found_ih) != 0)
+			reiserfs_panic(NULL,
+				       "PAP-5730: check_research_for_paste: "
+				       "found indirect item (%h) or position (%d) does not match to key (%K)",
+				       found_ih, pos_in_item(path), p_s_key);
+	}
+}
+#endif				/* config reiserfs check */
 
 /* Paste bytes to the existing item. Returns bytes number pasted into the item. */
-int reiserfs_paste_into_item (struct reiserfs_transaction_handle *th, 
-			      struct path         * p_s_search_path,	/* Path to the pasted item.          */
-			      const struct cpu_key      * p_s_key,        	/* Key to search for the needed item.*/
-			      struct inode	  * inode,		/* Inode item belongs to */
-			      const char          * p_c_body,       	/* Pointer to the bytes to paste.    */
-			      int                   n_pasted_size)  	/* Size of pasted bytes.             */
-{
-    struct tree_balance s_paste_balance;
-    int                 retval;
-    int			fs_gen;
+int reiserfs_paste_into_item(struct reiserfs_transaction_handle *th, struct path *p_s_search_path,	/* Path to the pasted item.          */
+			     const struct cpu_key *p_s_key,	/* Key to search for the needed item. */
+			     struct inode *inode,	/* Inode item belongs to */
+			     const char *p_c_body,	/* Pointer to the bytes to paste.    */
+			     int n_pasted_size)
+{				/* Size of pasted bytes.             */
+	struct tree_balance s_paste_balance;
+	int retval;
+	int fs_gen;
 
-    BUG_ON (!th->t_trans_id);
+	BUG_ON(!th->t_trans_id);
 
-    fs_gen = get_generation(inode->i_sb) ;
+	fs_gen = get_generation(inode->i_sb);
 
 #ifdef REISERQUOTA_DEBUG
-    reiserfs_debug (inode->i_sb, REISERFS_DEBUG_CODE, "reiserquota paste_into_item(): allocating %u id=%u type=%c", n_pasted_size, inode->i_uid, key2type(&(p_s_key->on_disk_key)));
+	reiserfs_debug(inode->i_sb, REISERFS_DEBUG_CODE,
+		       "reiserquota paste_into_item(): allocating %u id=%u type=%c",
+		       n_pasted_size, inode->i_uid,
+		       key2type(&(p_s_key->on_disk_key)));
 #endif
 
-    if (DQUOT_ALLOC_SPACE_NODIRTY(inode, n_pasted_size)) {
-	pathrelse(p_s_search_path);
-	return -EDQUOT;
-    }
-    init_tb_struct(th, &s_paste_balance, th->t_super, p_s_search_path, n_pasted_size);
+	if (DQUOT_ALLOC_SPACE_NODIRTY(inode, n_pasted_size)) {
+		pathrelse(p_s_search_path);
+		return -EDQUOT;
+	}
+	init_tb_struct(th, &s_paste_balance, th->t_super, p_s_search_path,
+		       n_pasted_size);
 #ifdef DISPLACE_NEW_PACKING_LOCALITIES
-    s_paste_balance.key = p_s_key->on_disk_key;
+	s_paste_balance.key = p_s_key->on_disk_key;
 #endif
 
-    /* DQUOT_* can schedule, must check before the fix_nodes */
-    if (fs_changed(fs_gen, inode->i_sb)) {
-	goto search_again;
-    }
-
-    while ((retval = fix_nodes(M_PASTE, &s_paste_balance, NULL, p_c_body)) ==
-REPEAT_SEARCH ) {
-search_again:
-	/* file system changed while we were in the fix_nodes */
-	PROC_INFO_INC( th -> t_super, paste_into_item_restarted );
-	retval = search_for_position_by_key (th->t_super, p_s_key, p_s_search_path);
-	if (retval == IO_ERROR) {
-	    retval = -EIO ;
-	    goto error_out ;
-	}
-	if (retval == POSITION_FOUND) {
-	    reiserfs_warning (inode->i_sb, "PAP-5710: reiserfs_paste_into_item: entry or pasted byte (%K) exists", p_s_key);
-	    retval = -EEXIST ;
-	    goto error_out ;
-	}
-	
+	/* DQUOT_* can schedule, must check before the fix_nodes */
+	if (fs_changed(fs_gen, inode->i_sb)) {
+		goto search_again;
+	}
+
+	while ((retval =
+		fix_nodes(M_PASTE, &s_paste_balance, NULL,
+			  p_c_body)) == REPEAT_SEARCH) {
+	      search_again:
+		/* file system changed while we were in the fix_nodes */
+		PROC_INFO_INC(th->t_super, paste_into_item_restarted);
+		retval =
+		    search_for_position_by_key(th->t_super, p_s_key,
+					       p_s_search_path);
+		if (retval == IO_ERROR) {
+			retval = -EIO;
+			goto error_out;
+		}
+		if (retval == POSITION_FOUND) {
+			reiserfs_warning(inode->i_sb,
+					 "PAP-5710: reiserfs_paste_into_item: entry or pasted byte (%K) exists",
+					 p_s_key);
+			retval = -EEXIST;
+			goto error_out;
+		}
 #ifdef CONFIG_REISERFS_CHECK
-	check_research_for_paste (p_s_search_path, p_s_key);
+		check_research_for_paste(p_s_search_path, p_s_key);
 #endif
-    }
+	}
 
-    /* Perform balancing after all resources are collected by fix_nodes, and
-       accessing them will not risk triggering schedule. */
-    if ( retval == CARRY_ON ) {
-	do_balance(&s_paste_balance, NULL/*ih*/, p_c_body, M_PASTE);
-	return 0;
-    }
-    retval = (retval == NO_DISK_SPACE) ? -ENOSPC : -EIO;
-error_out:
-    /* this also releases the path */
-    unfix_nodes(&s_paste_balance);
+	/* Perform balancing after all resources are collected by fix_nodes, and
+	   accessing them will not risk triggering schedule. */
+	if (retval == CARRY_ON) {
+		do_balance(&s_paste_balance, NULL /*ih */ , p_c_body, M_PASTE);
+		return 0;
+	}
+	retval = (retval == NO_DISK_SPACE) ? -ENOSPC : -EIO;
+      error_out:
+	/* this also releases the path */
+	unfix_nodes(&s_paste_balance);
 #ifdef REISERQUOTA_DEBUG
-    reiserfs_debug (inode->i_sb, REISERFS_DEBUG_CODE, "reiserquota paste_into_item(): freeing %u id=%u type=%c", n_pasted_size, inode->i_uid, key2type(&(p_s_key->on_disk_key)));
+	reiserfs_debug(inode->i_sb, REISERFS_DEBUG_CODE,
+		       "reiserquota paste_into_item(): freeing %u id=%u type=%c",
+		       n_pasted_size, inode->i_uid,
+		       key2type(&(p_s_key->on_disk_key)));
 #endif
-    DQUOT_FREE_SPACE_NODIRTY(inode, n_pasted_size);
-    return retval ;
+	DQUOT_FREE_SPACE_NODIRTY(inode, n_pasted_size);
+	return retval;
 }
 
-
 /* Insert new item into the buffer at the path. */
-int reiserfs_insert_item(struct reiserfs_transaction_handle *th, 
-			 struct path         * 	p_s_path,         /* Path to the inserteded item.         */
-			 const struct cpu_key      * key,
-			 struct item_head    * 	p_s_ih,           /* Pointer to the item header to insert.*/
-			 struct inode        * inode,
-			 const char          * 	p_c_body)         /* Pointer to the bytes to insert.      */
-{
-    struct tree_balance s_ins_balance;
-    int                 retval;
-    int fs_gen = 0 ;
-    int quota_bytes = 0 ;
-
-    BUG_ON (!th->t_trans_id);
+int reiserfs_insert_item(struct reiserfs_transaction_handle *th, struct path *p_s_path,	/* Path to the inserteded item.         */
+			 const struct cpu_key *key, struct item_head *p_s_ih,	/* Pointer to the item header to insert. */
+			 struct inode *inode, const char *p_c_body)
+{				/* Pointer to the bytes to insert.      */
+	struct tree_balance s_ins_balance;
+	int retval;
+	int fs_gen = 0;
+	int quota_bytes = 0;
+
+	BUG_ON(!th->t_trans_id);
+
+	if (inode) {		/* Do we count quotas for item? */
+		fs_gen = get_generation(inode->i_sb);
+		quota_bytes = ih_item_len(p_s_ih);
 
-    if (inode) {      /* Do we count quotas for item? */
-	fs_gen = get_generation(inode->i_sb);
-	quota_bytes = ih_item_len(p_s_ih);
-
-	/* hack so the quota code doesn't have to guess if the file has
-	 ** a tail, links are always tails, so there's no guessing needed
-	 */
-	if (!S_ISLNK (inode->i_mode) && is_direct_le_ih(p_s_ih)) {
-	    quota_bytes = inode->i_sb->s_blocksize + UNFM_P_SIZE ;
-	}
+		/* hack so the quota code doesn't have to guess if the file has
+		 ** a tail, links are always tails, so there's no guessing needed
+		 */
+		if (!S_ISLNK(inode->i_mode) && is_direct_le_ih(p_s_ih)) {
+			quota_bytes = inode->i_sb->s_blocksize + UNFM_P_SIZE;
+		}
 #ifdef REISERQUOTA_DEBUG
-	reiserfs_debug (inode->i_sb, REISERFS_DEBUG_CODE, "reiserquota insert_item(): allocating %u id=%u type=%c", quota_bytes, inode->i_uid, head2type(p_s_ih));
+		reiserfs_debug(inode->i_sb, REISERFS_DEBUG_CODE,
+			       "reiserquota insert_item(): allocating %u id=%u type=%c",
+			       quota_bytes, inode->i_uid, head2type(p_s_ih));
 #endif
-	/* We can't dirty inode here. It would be immediately written but
-	 * appropriate stat item isn't inserted yet... */
-	if (DQUOT_ALLOC_SPACE_NODIRTY(inode, quota_bytes)) {
-	    pathrelse(p_s_path);
-	    return -EDQUOT;
+		/* We can't dirty inode here. It would be immediately written but
+		 * appropriate stat item isn't inserted yet... */
+		if (DQUOT_ALLOC_SPACE_NODIRTY(inode, quota_bytes)) {
+			pathrelse(p_s_path);
+			return -EDQUOT;
+		}
 	}
-    }
-    init_tb_struct(th, &s_ins_balance, th->t_super, p_s_path, IH_SIZE + ih_item_len(p_s_ih));
+	init_tb_struct(th, &s_ins_balance, th->t_super, p_s_path,
+		       IH_SIZE + ih_item_len(p_s_ih));
 #ifdef DISPLACE_NEW_PACKING_LOCALITIES
-    s_ins_balance.key = key->on_disk_key;
+	s_ins_balance.key = key->on_disk_key;
 #endif
-    /* DQUOT_* can schedule, must check to be sure calling fix_nodes is safe */
-    if (inode && fs_changed(fs_gen, inode->i_sb)) {
-	goto search_again;
-    }
-
-    while ( (retval = fix_nodes(M_INSERT, &s_ins_balance, p_s_ih, p_c_body)) == REPEAT_SEARCH) {
-search_again:
-	/* file system changed while we were in the fix_nodes */
-	PROC_INFO_INC( th -> t_super, insert_item_restarted );
-	retval = search_item (th->t_super, key, p_s_path);
-	if (retval == IO_ERROR) {
-	    retval = -EIO;
-	    goto error_out ;
+	/* DQUOT_* can schedule, must check to be sure calling fix_nodes is safe */
+	if (inode && fs_changed(fs_gen, inode->i_sb)) {
+		goto search_again;
+	}
+
+	while ((retval =
+		fix_nodes(M_INSERT, &s_ins_balance, p_s_ih,
+			  p_c_body)) == REPEAT_SEARCH) {
+	      search_again:
+		/* file system changed while we were in the fix_nodes */
+		PROC_INFO_INC(th->t_super, insert_item_restarted);
+		retval = search_item(th->t_super, key, p_s_path);
+		if (retval == IO_ERROR) {
+			retval = -EIO;
+			goto error_out;
+		}
+		if (retval == ITEM_FOUND) {
+			reiserfs_warning(th->t_super,
+					 "PAP-5760: reiserfs_insert_item: "
+					 "key %K already exists in the tree",
+					 key);
+			retval = -EEXIST;
+			goto error_out;
+		}
 	}
-	if (retval == ITEM_FOUND) {
-	    reiserfs_warning (th->t_super, "PAP-5760: reiserfs_insert_item: "
-			      "key %K already exists in the tree", key);
-	    retval = -EEXIST ;
-	    goto error_out; 
-	}
-    }
-
-    /* make balancing after all resources will be collected at a time */ 
-    if ( retval == CARRY_ON ) {
-	do_balance (&s_ins_balance, p_s_ih, p_c_body, M_INSERT);
-	return 0;
-    }
 
-    retval = (retval == NO_DISK_SPACE) ? -ENOSPC : -EIO;
-error_out:
-    /* also releases the path */
-    unfix_nodes(&s_ins_balance);
+	/* make balancing after all resources will be collected at a time */
+	if (retval == CARRY_ON) {
+		do_balance(&s_ins_balance, p_s_ih, p_c_body, M_INSERT);
+		return 0;
+	}
+
+	retval = (retval == NO_DISK_SPACE) ? -ENOSPC : -EIO;
+      error_out:
+	/* also releases the path */
+	unfix_nodes(&s_ins_balance);
 #ifdef REISERQUOTA_DEBUG
-    reiserfs_debug (th->t_super, REISERFS_DEBUG_CODE, "reiserquota insert_item(): freeing %u id=%u type=%c", quota_bytes, inode->i_uid, head2type(p_s_ih));
+	reiserfs_debug(th->t_super, REISERFS_DEBUG_CODE,
+		       "reiserquota insert_item(): freeing %u id=%u type=%c",
+		       quota_bytes, inode->i_uid, head2type(p_s_ih));
 #endif
-    if (inode)
-	DQUOT_FREE_SPACE_NODIRTY(inode, quota_bytes) ;
-    return retval; 
+	if (inode)
+		DQUOT_FREE_SPACE_NODIRTY(inode, quota_bytes);
+	return retval;
 }
-
-
-
-
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
--- a/fs/reiserfs/super.c
+++ b/fs/reiserfs/super.c
@@ -35,83 +35,81 @@ static const char reiserfs_3_5_magic_str
 static const char reiserfs_3_6_magic_string[] = REISER2FS_SUPER_MAGIC_STRING;
 static const char reiserfs_jr_magic_string[] = REISER2FS_JR_SUPER_MAGIC_STRING;
 
-int is_reiserfs_3_5 (struct reiserfs_super_block * rs)
+int is_reiserfs_3_5(struct reiserfs_super_block *rs)
 {
-  return !strncmp (rs->s_v1.s_magic, reiserfs_3_5_magic_string,
-		   strlen (reiserfs_3_5_magic_string));
+	return !strncmp(rs->s_v1.s_magic, reiserfs_3_5_magic_string,
+			strlen(reiserfs_3_5_magic_string));
 }
 
-
-int is_reiserfs_3_6 (struct reiserfs_super_block * rs)
+int is_reiserfs_3_6(struct reiserfs_super_block *rs)
 {
-  return !strncmp (rs->s_v1.s_magic, reiserfs_3_6_magic_string,
- 		   strlen (reiserfs_3_6_magic_string));
+	return !strncmp(rs->s_v1.s_magic, reiserfs_3_6_magic_string,
+			strlen(reiserfs_3_6_magic_string));
 }
 
-
-int is_reiserfs_jr (struct reiserfs_super_block * rs)
+int is_reiserfs_jr(struct reiserfs_super_block *rs)
 {
-  return !strncmp (rs->s_v1.s_magic, reiserfs_jr_magic_string,
- 		   strlen (reiserfs_jr_magic_string));
+	return !strncmp(rs->s_v1.s_magic, reiserfs_jr_magic_string,
+			strlen(reiserfs_jr_magic_string));
 }
 
-
-static int is_any_reiserfs_magic_string (struct reiserfs_super_block * rs)
+static int is_any_reiserfs_magic_string(struct reiserfs_super_block *rs)
 {
-  return (is_reiserfs_3_5 (rs) || is_reiserfs_3_6 (rs) ||
-	  is_reiserfs_jr (rs));
+	return (is_reiserfs_3_5(rs) || is_reiserfs_3_6(rs) ||
+		is_reiserfs_jr(rs));
 }
 
-static int reiserfs_remount (struct super_block * s, int * flags, char * data);
-static int reiserfs_statfs (struct super_block * s, struct kstatfs * buf);
+static int reiserfs_remount(struct super_block *s, int *flags, char *data);
+static int reiserfs_statfs(struct super_block *s, struct kstatfs *buf);
 
-static int reiserfs_sync_fs (struct super_block * s, int wait)
+static int reiserfs_sync_fs(struct super_block *s, int wait)
 {
-    if (!(s->s_flags & MS_RDONLY)) {
-        struct reiserfs_transaction_handle th;
-	reiserfs_write_lock(s);
-	if (!journal_begin(&th, s, 1))
-            if (!journal_end_sync(&th, s, 1))
-                reiserfs_flush_old_commits(s);
-	s->s_dirt = 0; /* Even if it's not true.
-                        * We'll loop forever in sync_supers otherwise */
-	reiserfs_write_unlock(s);
-    } else {
-        s->s_dirt = 0;
-    }
-    return 0;
+	if (!(s->s_flags & MS_RDONLY)) {
+		struct reiserfs_transaction_handle th;
+		reiserfs_write_lock(s);
+		if (!journal_begin(&th, s, 1))
+			if (!journal_end_sync(&th, s, 1))
+				reiserfs_flush_old_commits(s);
+		s->s_dirt = 0;	/* Even if it's not true.
+				 * We'll loop forever in sync_supers otherwise */
+		reiserfs_write_unlock(s);
+	} else {
+		s->s_dirt = 0;
+	}
+	return 0;
 }
 
 static void reiserfs_write_super(struct super_block *s)
 {
-    reiserfs_sync_fs(s, 1);
+	reiserfs_sync_fs(s, 1);
 }
 
-static void reiserfs_write_super_lockfs (struct super_block * s)
+static void reiserfs_write_super_lockfs(struct super_block *s)
 {
-  struct reiserfs_transaction_handle th ;
-  reiserfs_write_lock(s);
-  if (!(s->s_flags & MS_RDONLY)) {
-    int err = journal_begin(&th, s, 1) ;
-    if (err) {
-        reiserfs_block_writes(&th) ;
-    } else {
-        reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1);
-        journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB (s));
-        reiserfs_block_writes(&th) ;
-        journal_end_sync(&th, s, 1) ;
-    }
-  }
-  s->s_dirt = 0;
-  reiserfs_write_unlock(s);
+	struct reiserfs_transaction_handle th;
+	reiserfs_write_lock(s);
+	if (!(s->s_flags & MS_RDONLY)) {
+		int err = journal_begin(&th, s, 1);
+		if (err) {
+			reiserfs_block_writes(&th);
+		} else {
+			reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s),
+						     1);
+			journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB(s));
+			reiserfs_block_writes(&th);
+			journal_end_sync(&th, s, 1);
+		}
+	}
+	s->s_dirt = 0;
+	reiserfs_write_unlock(s);
 }
 
-static void reiserfs_unlockfs(struct super_block *s) {
-  reiserfs_allow_writes(s) ;
+static void reiserfs_unlockfs(struct super_block *s)
+{
+	reiserfs_allow_writes(s);
 }
 
-extern const struct in_core_key  MAX_IN_CORE_KEY;
-
+extern const struct in_core_key MAX_IN_CORE_KEY;
 
 /* this is used to delete "save link" when there are no items of a
    file it points to. It can either happen if unlink is completed but
@@ -120,364 +118,387 @@ extern const struct in_core_key  MAX_IN_
    protecting unlink is bigger that a key lf "save link" which
    protects truncate), so there left no items to make truncate
    completion on */
-static int remove_save_link_only (struct super_block * s, struct reiserfs_key * key, int oid_free)
+static int remove_save_link_only(struct super_block *s,
+				 struct reiserfs_key *key, int oid_free)
 {
-    struct reiserfs_transaction_handle th;
-    int err;
+	struct reiserfs_transaction_handle th;
+	int err;
+
+	/* we are going to do one balancing */
+	err = journal_begin(&th, s, JOURNAL_PER_BALANCE_CNT);
+	if (err)
+		return err;
 
-     /* we are going to do one balancing */
-     err = journal_begin (&th, s, JOURNAL_PER_BALANCE_CNT);
-     if (err)
-        return err;
- 
-     reiserfs_delete_solid_item (&th, NULL, key);
-     if (oid_free)
-        /* removals are protected by direct items */
-        reiserfs_release_objectid (&th, le32_to_cpu (key->k_objectid));
+	reiserfs_delete_solid_item(&th, NULL, key);
+	if (oid_free)
+		/* removals are protected by direct items */
+		reiserfs_release_objectid(&th, le32_to_cpu(key->k_objectid));
 
-     return journal_end (&th, s, JOURNAL_PER_BALANCE_CNT);
+	return journal_end(&th, s, JOURNAL_PER_BALANCE_CNT);
 }
- 
+
 #ifdef CONFIG_QUOTA
 static int reiserfs_quota_on_mount(struct super_block *, int);
 #endif
- 
+
 /* look for uncompleted unlinks and truncates and complete them */
-static int finish_unfinished (struct super_block * s)
+static int finish_unfinished(struct super_block *s)
 {
-    INITIALIZE_PATH (path);
-    struct cpu_key max_cpu_key, obj_key;
-    struct reiserfs_key save_link_key;
-    int retval = 0;
-    struct item_head * ih;
-    struct buffer_head * bh;
-    int item_pos;
-    char * item;
-    int done;
-    struct inode * inode;
-    int truncate;
+	INITIALIZE_PATH(path);
+	struct cpu_key max_cpu_key, obj_key;
+	struct reiserfs_key save_link_key;
+	int retval = 0;
+	struct item_head *ih;
+	struct buffer_head *bh;
+	int item_pos;
+	char *item;
+	int done;
+	struct inode *inode;
+	int truncate;
 #ifdef CONFIG_QUOTA
-    int i;
-    int ms_active_set;
+	int i;
+	int ms_active_set;
 #endif
- 
- 
-    /* compose key to look for "save" links */
-    max_cpu_key.version = KEY_FORMAT_3_5;
-    max_cpu_key.on_disk_key.k_dir_id = ~0U;
-    max_cpu_key.on_disk_key.k_objectid = ~0U;
-    set_cpu_key_k_offset (&max_cpu_key, ~0U);
-    max_cpu_key.key_length = 3;
+
+	/* compose key to look for "save" links */
+	max_cpu_key.version = KEY_FORMAT_3_5;
+	max_cpu_key.on_disk_key.k_dir_id = ~0U;
+	max_cpu_key.on_disk_key.k_objectid = ~0U;
+	set_cpu_key_k_offset(&max_cpu_key, ~0U);
+	max_cpu_key.key_length = 3;
 
 #ifdef CONFIG_QUOTA
-    /* Needed for iput() to work correctly and not trash data */
-    if (s->s_flags & MS_ACTIVE) {
-	    ms_active_set = 0;
-    } else {
-	    ms_active_set = 1;
-	    s->s_flags |= MS_ACTIVE;
-    }
-    /* Turn on quotas so that they are updated correctly */
-    for (i = 0; i < MAXQUOTAS; i++) {
-	if (REISERFS_SB(s)->s_qf_names[i]) {
-	    int ret = reiserfs_quota_on_mount(s, i);
-	    if (ret < 0)
-		reiserfs_warning(s, "reiserfs: cannot turn on journalled quota: error %d", ret);
+	/* Needed for iput() to work correctly and not trash data */
+	if (s->s_flags & MS_ACTIVE) {
+		ms_active_set = 0;
+	} else {
+		ms_active_set = 1;
+		s->s_flags |= MS_ACTIVE;
+	}
+	/* Turn on quotas so that they are updated correctly */
+	for (i = 0; i < MAXQUOTAS; i++) {
+		if (REISERFS_SB(s)->s_qf_names[i]) {
+			int ret = reiserfs_quota_on_mount(s, i);
+			if (ret < 0)
+				reiserfs_warning(s,
+						 "reiserfs: cannot turn on journalled quota: error %d",
+						 ret);
+		}
 	}
-    }
 #endif
- 
-    done = 0;
-    REISERFS_SB(s)->s_is_unlinked_ok = 1;
-    while (!retval) {
-        retval = search_item (s, &max_cpu_key, &path);
-        if (retval != ITEM_NOT_FOUND) {
-            reiserfs_warning (s, "vs-2140: finish_unfinished: search_by_key returned %d",
-                              retval);
-            break;
-        }
-        
-        bh = get_last_bh (&path);
-        item_pos = get_item_pos (&path);
-        if (item_pos != B_NR_ITEMS (bh)) {
-            reiserfs_warning (s, "vs-2060: finish_unfinished: wrong position found");
-            break;
-        }
-        item_pos --;
-        ih = B_N_PITEM_HEAD (bh, item_pos);
- 
-        if (le32_to_cpu (ih->ih_key.k_dir_id) != MAX_KEY_OBJECTID)
-            /* there are no "save" links anymore */
-            break;
- 
-        save_link_key = ih->ih_key;
-        if (is_indirect_le_ih (ih))
-            truncate = 1;
-        else
-            truncate = 0;
- 
-        /* reiserfs_iget needs k_dirid and k_objectid only */
-        item = B_I_PITEM (bh, ih);
-        obj_key.on_disk_key.k_dir_id = le32_to_cpu (*(__le32 *)item);
-        obj_key.on_disk_key.k_objectid = le32_to_cpu (ih->ih_key.k_objectid);
-	obj_key.on_disk_key.k_offset = 0;
-	obj_key.on_disk_key.k_type = 0;
-	
-        pathrelse (&path);
- 
-        inode = reiserfs_iget (s, &obj_key);
-        if (!inode) {
-            /* the unlink almost completed, it just did not manage to remove
-	       "save" link and release objectid */
-            reiserfs_warning (s, "vs-2180: finish_unfinished: iget failed for %K",
-                              &obj_key);
-            retval = remove_save_link_only (s, &save_link_key, 1);
-            continue;
-        }
-
-	if (!truncate && inode->i_nlink) {
-	    /* file is not unlinked */
-            reiserfs_warning (s, "vs-2185: finish_unfinished: file %K is not unlinked",
-                              &obj_key);
-            retval = remove_save_link_only (s, &save_link_key, 0);
-            continue;
-	}
-	DQUOT_INIT(inode);
-
-	if (truncate && S_ISDIR (inode->i_mode) ) {
-	    /* We got a truncate request for a dir which is impossible.
-	       The only imaginable way is to execute unfinished truncate request
-	       then boot into old kernel, remove the file and create dir with
-	       the same key. */
-	    reiserfs_warning(s, "green-2101: impossible truncate on a directory %k. Please report", INODE_PKEY (inode));
-	    retval = remove_save_link_only (s, &save_link_key, 0);
-	    truncate = 0;
-	    iput (inode); 
-	    continue;
-	}
- 
-        if (truncate) {
-            REISERFS_I(inode) -> i_flags |= i_link_saved_truncate_mask;
-            /* not completed truncate found. New size was committed together
-	       with "save" link */
-            reiserfs_info (s, "Truncating %k to %Ld ..",
-                              INODE_PKEY (inode), inode->i_size);
-            reiserfs_truncate_file (inode, 0/*don't update modification time*/);
-            retval = remove_save_link (inode, truncate);
-        } else {
-            REISERFS_I(inode) -> i_flags |= i_link_saved_unlink_mask;
-            /* not completed unlink (rmdir) found */
-            reiserfs_info (s, "Removing %k..", INODE_PKEY (inode));
-            /* removal gets completed in iput */
-            retval = 0;
-        }
- 
-        iput (inode);
-        printk ("done\n");
-        done ++;
-    }
-    REISERFS_SB(s)->s_is_unlinked_ok = 0;
-     
+
+	done = 0;
+	REISERFS_SB(s)->s_is_unlinked_ok = 1;
+	while (!retval) {
+		retval = search_item(s, &max_cpu_key, &path);
+		if (retval != ITEM_NOT_FOUND) {
+			reiserfs_warning(s,
+					 "vs-2140: finish_unfinished: search_by_key returned %d",
+					 retval);
+			break;
+		}
+
+		bh = get_last_bh(&path);
+		item_pos = get_item_pos(&path);
+		if (item_pos != B_NR_ITEMS(bh)) {
+			reiserfs_warning(s,
+					 "vs-2060: finish_unfinished: wrong position found");
+			break;
+		}
+		item_pos--;
+		ih = B_N_PITEM_HEAD(bh, item_pos);
+
+		if (le32_to_cpu(ih->ih_key.k_dir_id) != MAX_KEY_OBJECTID)
+			/* there are no "save" links anymore */
+			break;
+
+		save_link_key = ih->ih_key;
+		if (is_indirect_le_ih(ih))
+			truncate = 1;
+		else
+			truncate = 0;
+
+		/* reiserfs_iget needs k_dirid and k_objectid only */
+		item = B_I_PITEM(bh, ih);
+		obj_key.on_disk_key.k_dir_id = le32_to_cpu(*(__le32 *) item);
+		obj_key.on_disk_key.k_objectid =
+		    le32_to_cpu(ih->ih_key.k_objectid);
+		obj_key.on_disk_key.k_offset = 0;
+		obj_key.on_disk_key.k_type = 0;
+
+		pathrelse(&path);
+
+		inode = reiserfs_iget(s, &obj_key);
+		if (!inode) {
+			/* the unlink almost completed, it just did not manage to remove
+			   "save" link and release objectid */
+			reiserfs_warning(s,
+					 "vs-2180: finish_unfinished: iget failed for %K",
+					 &obj_key);
+			retval = remove_save_link_only(s, &save_link_key, 1);
+			continue;
+		}
+
+		if (!truncate && inode->i_nlink) {
+			/* file is not unlinked */
+			reiserfs_warning(s,
+					 "vs-2185: finish_unfinished: file %K is not unlinked",
+					 &obj_key);
+			retval = remove_save_link_only(s, &save_link_key, 0);
+			continue;
+		}
+		DQUOT_INIT(inode);
+
+		if (truncate && S_ISDIR(inode->i_mode)) {
+			/* We got a truncate request for a dir which is impossible.
+			   The only imaginable way is to execute unfinished truncate request
+			   then boot into old kernel, remove the file and create dir with
+			   the same key. */
+			reiserfs_warning(s,
+					 "green-2101: impossible truncate on a directory %k. Please report",
+					 INODE_PKEY(inode));
+			retval = remove_save_link_only(s, &save_link_key, 0);
+			truncate = 0;
+			iput(inode);
+			continue;
+		}
+
+		if (truncate) {
+			REISERFS_I(inode)->i_flags |=
+			    i_link_saved_truncate_mask;
+			/* not completed truncate found. New size was committed together
+			   with "save" link */
+			reiserfs_info(s, "Truncating %k to %Ld ..",
+				      INODE_PKEY(inode), inode->i_size);
+			reiserfs_truncate_file(inode,
+					       0
+					       /*don't update modification time */
+					       );
+			retval = remove_save_link(inode, truncate);
+		} else {
+			REISERFS_I(inode)->i_flags |= i_link_saved_unlink_mask;
+			/* not completed unlink (rmdir) found */
+			reiserfs_info(s, "Removing %k..", INODE_PKEY(inode));
+			/* removal gets completed in iput */
+			retval = 0;
+		}
+
+		iput(inode);
+		printk("done\n");
+		done++;
+	}
+	REISERFS_SB(s)->s_is_unlinked_ok = 0;
+
 #ifdef CONFIG_QUOTA
-    /* Turn quotas off */
-    for (i = 0; i < MAXQUOTAS; i++) {
-            if (sb_dqopt(s)->files[i])
-                    vfs_quota_off_mount(s, i);
-    }
-    if (ms_active_set)
-	    /* Restore the flag back */
-	    s->s_flags &= ~MS_ACTIVE;
+	/* Turn quotas off */
+	for (i = 0; i < MAXQUOTAS; i++) {
+		if (sb_dqopt(s)->files[i])
+			vfs_quota_off_mount(s, i);
+	}
+	if (ms_active_set)
+		/* Restore the flag back */
+		s->s_flags &= ~MS_ACTIVE;
 #endif
-    pathrelse (&path);
-    if (done)
-        reiserfs_info (s, "There were %d uncompleted unlinks/truncates. "
-                          "Completed\n", done);
-    return retval;
+	pathrelse(&path);
+	if (done)
+		reiserfs_info(s, "There were %d uncompleted unlinks/truncates. "
+			      "Completed\n", done);
+	return retval;
 }
- 
+
 /* to protect file being unlinked from getting lost we "safe" link files
    being unlinked. This link will be deleted in the same transaction with last
    item of file. mounting the filesytem we scan all these links and remove
    files which almost got lost */
-void add_save_link (struct reiserfs_transaction_handle * th,
-		    struct inode * inode, int truncate)
+void add_save_link(struct reiserfs_transaction_handle *th,
+		   struct inode *inode, int truncate)
 {
-    INITIALIZE_PATH (path);
-    int retval;
-    struct cpu_key key;
-    struct item_head ih;
-    __le32 link;
-
-    BUG_ON (!th->t_trans_id);
-
-    /* file can only get one "save link" of each kind */
-    RFALSE( truncate && 
-	    ( REISERFS_I(inode) -> i_flags & i_link_saved_truncate_mask ),
-	    "saved link already exists for truncated inode %lx",
-	    ( long ) inode -> i_ino );
-    RFALSE( !truncate && 
-	    ( REISERFS_I(inode) -> i_flags & i_link_saved_unlink_mask ),
-	    "saved link already exists for unlinked inode %lx",
-	    ( long ) inode -> i_ino );
-
-    /* setup key of "save" link */
-    key.version = KEY_FORMAT_3_5;
-    key.on_disk_key.k_dir_id = MAX_KEY_OBJECTID;
-    key.on_disk_key.k_objectid = inode->i_ino;
-    if (!truncate) {
-	/* unlink, rmdir, rename */
-	set_cpu_key_k_offset (&key, 1 + inode->i_sb->s_blocksize);
-	set_cpu_key_k_type (&key, TYPE_DIRECT);
-
-	/* item head of "safe" link */
-	make_le_item_head (&ih, &key, key.version, 1 + inode->i_sb->s_blocksize, TYPE_DIRECT,
-			   4/*length*/, 0xffff/*free space*/);
-    } else {
-	/* truncate */
-	if (S_ISDIR (inode->i_mode))
-	    reiserfs_warning(inode->i_sb, "green-2102: Adding a truncate savelink for a directory %k! Please report", INODE_PKEY(inode));
-	set_cpu_key_k_offset (&key, 1);
-	set_cpu_key_k_type (&key, TYPE_INDIRECT);
-
-	/* item head of "safe" link */
-	make_le_item_head (&ih, &key, key.version, 1, TYPE_INDIRECT,
-			   4/*length*/, 0/*free space*/);
-    }
-    key.key_length = 3;
-
-    /* look for its place in the tree */
-    retval = search_item (inode->i_sb, &key, &path);
-    if (retval != ITEM_NOT_FOUND) {
-	if ( retval != -ENOSPC )
-	    reiserfs_warning (inode->i_sb, "vs-2100: add_save_link:"
-			  "search_by_key (%K) returned %d", &key, retval);
-	pathrelse (&path);
-	return;
-    }
-
-    /* body of "save" link */
-    link = INODE_PKEY (inode)->k_dir_id;
-
-    /* put "save" link inot tree, don't charge quota to anyone */
-    retval = reiserfs_insert_item (th, &path, &key, &ih, NULL, (char *)&link);
-    if (retval) {
-	if (retval != -ENOSPC)
-	    reiserfs_warning (inode->i_sb, "vs-2120: add_save_link: insert_item returned %d",
-			  retval);
-    } else {
-	if( truncate )
-	    REISERFS_I(inode) -> i_flags |= i_link_saved_truncate_mask;
-	else
-	    REISERFS_I(inode) -> i_flags |= i_link_saved_unlink_mask;
-    }
+	INITIALIZE_PATH(path);
+	int retval;
+	struct cpu_key key;
+	struct item_head ih;
+	__le32 link;
+
+	BUG_ON(!th->t_trans_id);
+
+	/* file can only get one "save link" of each kind */
+	RFALSE(truncate &&
+	       (REISERFS_I(inode)->i_flags & i_link_saved_truncate_mask),
+	       "saved link already exists for truncated inode %lx",
+	       (long)inode->i_ino);
+	RFALSE(!truncate &&
+	       (REISERFS_I(inode)->i_flags & i_link_saved_unlink_mask),
+	       "saved link already exists for unlinked inode %lx",
+	       (long)inode->i_ino);
+
+	/* setup key of "save" link */
+	key.version = KEY_FORMAT_3_5;
+	key.on_disk_key.k_dir_id = MAX_KEY_OBJECTID;
+	key.on_disk_key.k_objectid = inode->i_ino;
+	if (!truncate) {
+		/* unlink, rmdir, rename */
+		set_cpu_key_k_offset(&key, 1 + inode->i_sb->s_blocksize);
+		set_cpu_key_k_type(&key, TYPE_DIRECT);
+
+		/* item head of "safe" link */
+		make_le_item_head(&ih, &key, key.version,
+				  1 + inode->i_sb->s_blocksize, TYPE_DIRECT,
+				  4 /*length */ , 0xffff /*free space */ );
+	} else {
+		/* truncate */
+		if (S_ISDIR(inode->i_mode))
+			reiserfs_warning(inode->i_sb,
+					 "green-2102: Adding a truncate savelink for a directory %k! Please report",
+					 INODE_PKEY(inode));
+		set_cpu_key_k_offset(&key, 1);
+		set_cpu_key_k_type(&key, TYPE_INDIRECT);
+
+		/* item head of "safe" link */
+		make_le_item_head(&ih, &key, key.version, 1, TYPE_INDIRECT,
+				  4 /*length */ , 0 /*free space */ );
+	}
+	key.key_length = 3;
+
+	/* look for its place in the tree */
+	retval = search_item(inode->i_sb, &key, &path);
+	if (retval != ITEM_NOT_FOUND) {
+		if (retval != -ENOSPC)
+			reiserfs_warning(inode->i_sb, "vs-2100: add_save_link:"
+					 "search_by_key (%K) returned %d", &key,
+					 retval);
+		pathrelse(&path);
+		return;
+	}
+
+	/* body of "save" link */
+	link = INODE_PKEY(inode)->k_dir_id;
+
+	/* put "save" link inot tree, don't charge quota to anyone */
+	retval =
+	    reiserfs_insert_item(th, &path, &key, &ih, NULL, (char *)&link);
+	if (retval) {
+		if (retval != -ENOSPC)
+			reiserfs_warning(inode->i_sb,
+					 "vs-2120: add_save_link: insert_item returned %d",
+					 retval);
+	} else {
+		if (truncate)
+			REISERFS_I(inode)->i_flags |=
+			    i_link_saved_truncate_mask;
+		else
+			REISERFS_I(inode)->i_flags |= i_link_saved_unlink_mask;
+	}
 }
 
-
 /* this opens transaction unlike add_save_link */
-int remove_save_link (struct inode * inode, int truncate)
+int remove_save_link(struct inode *inode, int truncate)
 {
-    struct reiserfs_transaction_handle th;
-    struct reiserfs_key key;
-    int err;
- 
-    /* we are going to do one balancing only */
-    err = journal_begin (&th, inode->i_sb, JOURNAL_PER_BALANCE_CNT);
-    if (err)
-        return err;
- 
-    /* setup key of "save" link */
-    key.k_dir_id = cpu_to_le32 (MAX_KEY_OBJECTID);
-    key.k_objectid = INODE_PKEY (inode)->k_objectid;
-    if (!truncate) {
-        /* unlink, rmdir, rename */
-        set_le_key_k_offset (KEY_FORMAT_3_5, &key,
-			     1 + inode->i_sb->s_blocksize);
-        set_le_key_k_type (KEY_FORMAT_3_5, &key, TYPE_DIRECT);
-    } else {
-        /* truncate */
-        set_le_key_k_offset (KEY_FORMAT_3_5, &key, 1);
-        set_le_key_k_type (KEY_FORMAT_3_5, &key, TYPE_INDIRECT);
-    }
- 
-    if( ( truncate && 
-          ( REISERFS_I(inode) -> i_flags & i_link_saved_truncate_mask ) ) ||
-        ( !truncate && 
-          ( REISERFS_I(inode) -> i_flags & i_link_saved_unlink_mask ) ) )
-	/* don't take quota bytes from anywhere */
-	reiserfs_delete_solid_item (&th, NULL, &key);
-    if (!truncate) {
-	reiserfs_release_objectid (&th, inode->i_ino);
-	REISERFS_I(inode) -> i_flags &= ~i_link_saved_unlink_mask;
-    } else
-	REISERFS_I(inode) -> i_flags &= ~i_link_saved_truncate_mask;
- 
-    return journal_end (&th, inode->i_sb, JOURNAL_PER_BALANCE_CNT);
-}
-
-
-static void reiserfs_put_super (struct super_block * s)
-{
-  int i;
-  struct reiserfs_transaction_handle th ;
-  th.t_trans_id = 0;
-
-  if (REISERFS_SB(s)->xattr_root) {
-    d_invalidate (REISERFS_SB(s)->xattr_root);
-    dput (REISERFS_SB(s)->xattr_root);
-  }
-  
-  if (REISERFS_SB(s)->priv_root) {
-    d_invalidate (REISERFS_SB(s)->priv_root);
-    dput (REISERFS_SB(s)->priv_root);
-  }
-
-  /* change file system state to current state if it was mounted with read-write permissions */
-  if (!(s->s_flags & MS_RDONLY)) {
-    if (!journal_begin(&th, s, 10)) {
-        reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1) ;
-        set_sb_umount_state( SB_DISK_SUPER_BLOCK(s), REISERFS_SB(s)->s_mount_state );
-        journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB (s));
-    }
-  }
-
-  /* note, journal_release checks for readonly mount, and can decide not
-  ** to do a journal_end
-  */
-  journal_release(&th, s) ;
-
-  for (i = 0; i < SB_BMAP_NR (s); i ++)
-    brelse (SB_AP_BITMAP (s)[i].bh);
-
-  vfree (SB_AP_BITMAP (s));
-
-  brelse (SB_BUFFER_WITH_SB (s));
-
-  print_statistics (s);
-
-  if (REISERFS_SB(s)->s_kmallocs != 0) {
-    reiserfs_warning (s, "vs-2004: reiserfs_put_super: allocated memory left %d",
-		      REISERFS_SB(s)->s_kmallocs);
-  }
-
-  if (REISERFS_SB(s)->reserved_blocks != 0) {
-    reiserfs_warning (s, "green-2005: reiserfs_put_super: reserved blocks left %d",
-		      REISERFS_SB(s)->reserved_blocks);
-  }
-
-  reiserfs_proc_info_done( s );
+	struct reiserfs_transaction_handle th;
+	struct reiserfs_key key;
+	int err;
+
+	/* we are going to do one balancing only */
+	err = journal_begin(&th, inode->i_sb, JOURNAL_PER_BALANCE_CNT);
+	if (err)
+		return err;
+
+	/* setup key of "save" link */
+	key.k_dir_id = cpu_to_le32(MAX_KEY_OBJECTID);
+	key.k_objectid = INODE_PKEY(inode)->k_objectid;
+	if (!truncate) {
+		/* unlink, rmdir, rename */
+		set_le_key_k_offset(KEY_FORMAT_3_5, &key,
+				    1 + inode->i_sb->s_blocksize);
+		set_le_key_k_type(KEY_FORMAT_3_5, &key, TYPE_DIRECT);
+	} else {
+		/* truncate */
+		set_le_key_k_offset(KEY_FORMAT_3_5, &key, 1);
+		set_le_key_k_type(KEY_FORMAT_3_5, &key, TYPE_INDIRECT);
+	}
+
+	if ((truncate &&
+	     (REISERFS_I(inode)->i_flags & i_link_saved_truncate_mask)) ||
+	    (!truncate &&
+	     (REISERFS_I(inode)->i_flags & i_link_saved_unlink_mask)))
+		/* don't take quota bytes from anywhere */
+		reiserfs_delete_solid_item(&th, NULL, &key);
+	if (!truncate) {
+		reiserfs_release_objectid(&th, inode->i_ino);
+		REISERFS_I(inode)->i_flags &= ~i_link_saved_unlink_mask;
+	} else
+		REISERFS_I(inode)->i_flags &= ~i_link_saved_truncate_mask;
+
+	return journal_end(&th, inode->i_sb, JOURNAL_PER_BALANCE_CNT);
+}
+
+static void reiserfs_put_super(struct super_block *s)
+{
+	int i;
+	struct reiserfs_transaction_handle th;
+	th.t_trans_id = 0;
+
+	if (REISERFS_SB(s)->xattr_root) {
+		d_invalidate(REISERFS_SB(s)->xattr_root);
+		dput(REISERFS_SB(s)->xattr_root);
+	}
+
+	if (REISERFS_SB(s)->priv_root) {
+		d_invalidate(REISERFS_SB(s)->priv_root);
+		dput(REISERFS_SB(s)->priv_root);
+	}
+
+	/* change file system state to current state if it was mounted with read-write permissions */
+	if (!(s->s_flags & MS_RDONLY)) {
+		if (!journal_begin(&th, s, 10)) {
+			reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s),
+						     1);
+			set_sb_umount_state(SB_DISK_SUPER_BLOCK(s),
+					    REISERFS_SB(s)->s_mount_state);
+			journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB(s));
+		}
+	}
+
+	/* note, journal_release checks for readonly mount, and can decide not
+	 ** to do a journal_end
+	 */
+	journal_release(&th, s);
+
+	for (i = 0; i < SB_BMAP_NR(s); i++)
+		brelse(SB_AP_BITMAP(s)[i].bh);
+
+	vfree(SB_AP_BITMAP(s));
+
+	brelse(SB_BUFFER_WITH_SB(s));
+
+	print_statistics(s);
+
+	if (REISERFS_SB(s)->s_kmallocs != 0) {
+		reiserfs_warning(s,
+				 "vs-2004: reiserfs_put_super: allocated memory left %d",
+				 REISERFS_SB(s)->s_kmallocs);
+	}
+
+	if (REISERFS_SB(s)->reserved_blocks != 0) {
+		reiserfs_warning(s,
+				 "green-2005: reiserfs_put_super: reserved blocks left %d",
+				 REISERFS_SB(s)->reserved_blocks);
+	}
 
-  kfree(s->s_fs_info);
-  s->s_fs_info = NULL;
+	reiserfs_proc_info_done(s);
 
-  return;
+	kfree(s->s_fs_info);
+	s->s_fs_info = NULL;
+
+	return;
 }
 
-static kmem_cache_t * reiserfs_inode_cachep;
+static kmem_cache_t *reiserfs_inode_cachep;
 
 static struct inode *reiserfs_alloc_inode(struct super_block *sb)
 {
 	struct reiserfs_inode_info *ei;
-	ei = (struct reiserfs_inode_info *)kmem_cache_alloc(reiserfs_inode_cachep, SLAB_KERNEL);
+	ei = (struct reiserfs_inode_info *)
+	    kmem_cache_alloc(reiserfs_inode_cachep, SLAB_KERNEL);
 	if (!ei)
 		return NULL;
 	return &ei->vfs_inode;
@@ -488,25 +509,26 @@ static void reiserfs_destroy_inode(struc
 	kmem_cache_free(reiserfs_inode_cachep, REISERFS_I(inode));
 }
 
-static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags)
+static void init_once(void *foo, kmem_cache_t * cachep, unsigned long flags)
 {
-	struct reiserfs_inode_info *ei = (struct reiserfs_inode_info *) foo;
+	struct reiserfs_inode_info *ei = (struct reiserfs_inode_info *)foo;
 
-	if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
+	if ((flags & (SLAB_CTOR_VERIFY | SLAB_CTOR_CONSTRUCTOR)) ==
 	    SLAB_CTOR_CONSTRUCTOR) {
-		INIT_LIST_HEAD(&ei->i_prealloc_list) ;
+		INIT_LIST_HEAD(&ei->i_prealloc_list);
 		inode_init_once(&ei->vfs_inode);
 		ei->i_acl_access = NULL;
 		ei->i_acl_default = NULL;
 	}
 }
- 
+
 static int init_inodecache(void)
 {
 	reiserfs_inode_cachep = kmem_cache_create("reiser_inode_cache",
-					     sizeof(struct reiserfs_inode_info),
-					     0, SLAB_RECLAIM_ACCOUNT,
-					     init_once, NULL);
+						  sizeof(struct
+							 reiserfs_inode_info),
+						  0, SLAB_RECLAIM_ACCOUNT,
+						  init_once, NULL);
 	if (reiserfs_inode_cachep == NULL)
 		return -ENOMEM;
 	return 0;
@@ -515,72 +537,76 @@ static int init_inodecache(void)
 static void destroy_inodecache(void)
 {
 	if (kmem_cache_destroy(reiserfs_inode_cachep))
-		reiserfs_warning (NULL, "reiserfs_inode_cache: not all structures were freed");
+		reiserfs_warning(NULL,
+				 "reiserfs_inode_cache: not all structures were freed");
 }
 
 /* we don't mark inodes dirty, we just log them */
-static void reiserfs_dirty_inode (struct inode * inode) {
-    struct reiserfs_transaction_handle th ;
+static void reiserfs_dirty_inode(struct inode *inode)
+{
+	struct reiserfs_transaction_handle th;
 
-    int err = 0;
-    if (inode->i_sb->s_flags & MS_RDONLY) {
-        reiserfs_warning(inode->i_sb, "clm-6006: writing inode %lu on readonly FS",
-	                  inode->i_ino) ;
-        return ;
-    }
-    reiserfs_write_lock(inode->i_sb);
-
-    /* this is really only used for atime updates, so they don't have
-    ** to be included in O_SYNC or fsync
-    */
-    err = journal_begin(&th, inode->i_sb, 1) ;
-    if (err) {
-        reiserfs_write_unlock (inode->i_sb);
-        return;
-    }
-    reiserfs_update_sd (&th, inode);
-    journal_end(&th, inode->i_sb, 1) ;
-    reiserfs_write_unlock(inode->i_sb);
-}
-
-static void reiserfs_clear_inode (struct inode *inode)
-{
-    struct posix_acl *acl;
-
-    acl = REISERFS_I(inode)->i_acl_access;
-    if (acl && !IS_ERR (acl))
-        posix_acl_release (acl);
-    REISERFS_I(inode)->i_acl_access = NULL;
-
-    acl = REISERFS_I(inode)->i_acl_default;
-    if (acl && !IS_ERR (acl))
-        posix_acl_release (acl);
-    REISERFS_I(inode)->i_acl_default = NULL;
+	int err = 0;
+	if (inode->i_sb->s_flags & MS_RDONLY) {
+		reiserfs_warning(inode->i_sb,
+				 "clm-6006: writing inode %lu on readonly FS",
+				 inode->i_ino);
+		return;
+	}
+	reiserfs_write_lock(inode->i_sb);
+
+	/* this is really only used for atime updates, so they don't have
+	 ** to be included in O_SYNC or fsync
+	 */
+	err = journal_begin(&th, inode->i_sb, 1);
+	if (err) {
+		reiserfs_write_unlock(inode->i_sb);
+		return;
+	}
+	reiserfs_update_sd(&th, inode);
+	journal_end(&th, inode->i_sb, 1);
+	reiserfs_write_unlock(inode->i_sb);
+}
+
+static void reiserfs_clear_inode(struct inode *inode)
+{
+	struct posix_acl *acl;
+
+	acl = REISERFS_I(inode)->i_acl_access;
+	if (acl && !IS_ERR(acl))
+		posix_acl_release(acl);
+	REISERFS_I(inode)->i_acl_access = NULL;
+
+	acl = REISERFS_I(inode)->i_acl_default;
+	if (acl && !IS_ERR(acl))
+		posix_acl_release(acl);
+	REISERFS_I(inode)->i_acl_default = NULL;
 }
 
 #ifdef CONFIG_QUOTA
-static ssize_t reiserfs_quota_write(struct super_block *, int, const char *, size_t, loff_t);
-static ssize_t reiserfs_quota_read(struct super_block *, int, char *, size_t, loff_t);
+static ssize_t reiserfs_quota_write(struct super_block *, int, const char *,
+				    size_t, loff_t);
+static ssize_t reiserfs_quota_read(struct super_block *, int, char *, size_t,
+				   loff_t);
 #endif
 
-static struct super_operations reiserfs_sops =
-{
-  .alloc_inode = reiserfs_alloc_inode,
-  .destroy_inode = reiserfs_destroy_inode,
-  .write_inode = reiserfs_write_inode,
-  .dirty_inode = reiserfs_dirty_inode,
-  .delete_inode = reiserfs_delete_inode,
-  .clear_inode  = reiserfs_clear_inode,
-  .put_super = reiserfs_put_super,
-  .write_super = reiserfs_write_super,
-  .sync_fs = reiserfs_sync_fs,
-  .write_super_lockfs = reiserfs_write_super_lockfs,
-  .unlockfs = reiserfs_unlockfs,
-  .statfs = reiserfs_statfs,
-  .remount_fs = reiserfs_remount,
+static struct super_operations reiserfs_sops = {
+	.alloc_inode = reiserfs_alloc_inode,
+	.destroy_inode = reiserfs_destroy_inode,
+	.write_inode = reiserfs_write_inode,
+	.dirty_inode = reiserfs_dirty_inode,
+	.delete_inode = reiserfs_delete_inode,
+	.clear_inode = reiserfs_clear_inode,
+	.put_super = reiserfs_put_super,
+	.write_super = reiserfs_write_super,
+	.sync_fs = reiserfs_sync_fs,
+	.write_super_lockfs = reiserfs_write_super_lockfs,
+	.unlockfs = reiserfs_unlockfs,
+	.statfs = reiserfs_statfs,
+	.remount_fs = reiserfs_remount,
 #ifdef CONFIG_QUOTA
-  .quota_read = reiserfs_quota_read,
-  .quota_write = reiserfs_quota_write,
+	.quota_read = reiserfs_quota_read,
+	.quota_write = reiserfs_quota_write,
 #endif
 };
 
@@ -596,50 +622,48 @@ static int reiserfs_mark_dquot_dirty(str
 static int reiserfs_write_info(struct super_block *, int);
 static int reiserfs_quota_on(struct super_block *, int, int, char *);
 
-static struct dquot_operations reiserfs_quota_operations =
-{
-  .initialize = reiserfs_dquot_initialize,
-  .drop = reiserfs_dquot_drop,
-  .alloc_space = dquot_alloc_space,
-  .alloc_inode = dquot_alloc_inode,
-  .free_space = dquot_free_space,
-  .free_inode = dquot_free_inode,
-  .transfer = dquot_transfer,
-  .write_dquot = reiserfs_write_dquot,
-  .acquire_dquot = reiserfs_acquire_dquot,
-  .release_dquot = reiserfs_release_dquot,
-  .mark_dirty = reiserfs_mark_dquot_dirty,
-  .write_info = reiserfs_write_info,
+static struct dquot_operations reiserfs_quota_operations = {
+	.initialize = reiserfs_dquot_initialize,
+	.drop = reiserfs_dquot_drop,
+	.alloc_space = dquot_alloc_space,
+	.alloc_inode = dquot_alloc_inode,
+	.free_space = dquot_free_space,
+	.free_inode = dquot_free_inode,
+	.transfer = dquot_transfer,
+	.write_dquot = reiserfs_write_dquot,
+	.acquire_dquot = reiserfs_acquire_dquot,
+	.release_dquot = reiserfs_release_dquot,
+	.mark_dirty = reiserfs_mark_dquot_dirty,
+	.write_info = reiserfs_write_info,
 };
 
-static struct quotactl_ops reiserfs_qctl_operations =
-{
-  .quota_on = reiserfs_quota_on,
-  .quota_off = vfs_quota_off,
-  .quota_sync = vfs_quota_sync,
-  .get_info = vfs_get_dqinfo,
-  .set_info = vfs_set_dqinfo,
-  .get_dqblk = vfs_get_dqblk,
-  .set_dqblk = vfs_set_dqblk,
+static struct quotactl_ops reiserfs_qctl_operations = {
+	.quota_on = reiserfs_quota_on,
+	.quota_off = vfs_quota_off,
+	.quota_sync = vfs_quota_sync,
+	.get_info = vfs_get_dqinfo,
+	.set_info = vfs_set_dqinfo,
+	.get_dqblk = vfs_get_dqblk,
+	.set_dqblk = vfs_set_dqblk,
 };
 #endif
 
 static struct export_operations reiserfs_export_ops = {
-  .encode_fh = reiserfs_encode_fh,
-  .decode_fh = reiserfs_decode_fh,
-  .get_parent = reiserfs_get_parent,
-  .get_dentry = reiserfs_get_dentry,
-} ;
+	.encode_fh = reiserfs_encode_fh,
+	.decode_fh = reiserfs_decode_fh,
+	.get_parent = reiserfs_get_parent,
+	.get_dentry = reiserfs_get_dentry,
+};
 
 /* this struct is used in reiserfs_getopt () for containing the value for those
    mount options that have values rather than being toggles. */
 typedef struct {
-    char * value;
-    int setmask; /* bitmask which is to set on mount_options bitmask when this
-                    value is found, 0 is no bits are to be changed. */
-    int clrmask; /* bitmask which is to clear on mount_options bitmask when  this
-		    value is found, 0 is no bits are to be changed. This is
-		    applied BEFORE setmask */
+	char *value;
+	int setmask;		/* bitmask which is to set on mount_options bitmask when this
+				   value is found, 0 is no bits are to be changed. */
+	int clrmask;		/* bitmask which is to clear on mount_options bitmask when  this
+				   value is found, 0 is no bits are to be changed. This is
+				   applied BEFORE setmask */
 } arg_desc_t;
 
 /* Set this bit in arg_required to allow empty arguments */
@@ -648,67 +672,70 @@ typedef struct {
 /* this struct is used in reiserfs_getopt() for describing the set of reiserfs
    mount options */
 typedef struct {
-    char * option_name;
-    int arg_required; /* 0 if argument is not required, not 0 otherwise */
-    const arg_desc_t * values; /* list of values accepted by an option */
-    int setmask; /* bitmask which is to set on mount_options bitmask when this
-                    value is found, 0 is no bits are to be changed. */
-    int clrmask; /* bitmask which is to clear on mount_options bitmask when  this
-		    value is found, 0 is no bits are to be changed. This is
-		    applied BEFORE setmask */
+	char *option_name;
+	int arg_required;	/* 0 if argument is not required, not 0 otherwise */
+	const arg_desc_t *values;	/* list of values accepted by an option */
+	int setmask;		/* bitmask which is to set on mount_options bitmask when this
+				   value is found, 0 is no bits are to be changed. */
+	int clrmask;		/* bitmask which is to clear on mount_options bitmask when  this
+				   value is found, 0 is no bits are to be changed. This is
+				   applied BEFORE setmask */
 } opt_desc_t;
 
 /* possible values for -o data= */
 static const arg_desc_t logging_mode[] = {
-    {"ordered", 1<<REISERFS_DATA_ORDERED, (1<<REISERFS_DATA_LOG|1<<REISERFS_DATA_WRITEBACK)},
-    {"journal", 1<<REISERFS_DATA_LOG, (1<<REISERFS_DATA_ORDERED|1<<REISERFS_DATA_WRITEBACK)},
-    {"writeback", 1<<REISERFS_DATA_WRITEBACK, (1<<REISERFS_DATA_ORDERED|1<<REISERFS_DATA_LOG)},
-    {NULL, 0}
+	{"ordered", 1 << REISERFS_DATA_ORDERED,
+	 (1 << REISERFS_DATA_LOG | 1 << REISERFS_DATA_WRITEBACK)},
+	{"journal", 1 << REISERFS_DATA_LOG,
+	 (1 << REISERFS_DATA_ORDERED | 1 << REISERFS_DATA_WRITEBACK)},
+	{"writeback", 1 << REISERFS_DATA_WRITEBACK,
+	 (1 << REISERFS_DATA_ORDERED | 1 << REISERFS_DATA_LOG)},
+	{NULL, 0}
 };
 
 /* possible values for -o barrier= */
 static const arg_desc_t barrier_mode[] = {
-    {"none", 1<<REISERFS_BARRIER_NONE, 1<<REISERFS_BARRIER_FLUSH},
-    {"flush", 1<<REISERFS_BARRIER_FLUSH, 1<<REISERFS_BARRIER_NONE},
-    {NULL, 0}
+	{"none", 1 << REISERFS_BARRIER_NONE, 1 << REISERFS_BARRIER_FLUSH},
+	{"flush", 1 << REISERFS_BARRIER_FLUSH, 1 << REISERFS_BARRIER_NONE},
+	{NULL, 0}
 };
 
 /* possible values for "-o block-allocator=" and bits which are to be set in
    s_mount_opt of reiserfs specific part of in-core super block */
 static const arg_desc_t balloc[] = {
-    {"noborder", 1<<REISERFS_NO_BORDER, 0},
-    {"border", 0, 1<<REISERFS_NO_BORDER},
-    {"no_unhashed_relocation", 1<<REISERFS_NO_UNHASHED_RELOCATION, 0},
-    {"hashed_relocation", 1<<REISERFS_HASHED_RELOCATION, 0},
-    {"test4", 1<<REISERFS_TEST4, 0},
-    {"notest4", 0, 1<<REISERFS_TEST4},
-    {NULL, 0, 0}
+	{"noborder", 1 << REISERFS_NO_BORDER, 0},
+	{"border", 0, 1 << REISERFS_NO_BORDER},
+	{"no_unhashed_relocation", 1 << REISERFS_NO_UNHASHED_RELOCATION, 0},
+	{"hashed_relocation", 1 << REISERFS_HASHED_RELOCATION, 0},
+	{"test4", 1 << REISERFS_TEST4, 0},
+	{"notest4", 0, 1 << REISERFS_TEST4},
+	{NULL, 0, 0}
 };
 
 static const arg_desc_t tails[] = {
-    {"on", 1<<REISERFS_LARGETAIL, 1<<REISERFS_SMALLTAIL},
-    {"off", 0, (1<<REISERFS_LARGETAIL)|(1<<REISERFS_SMALLTAIL)},
-    {"small", 1<<REISERFS_SMALLTAIL, 1<<REISERFS_LARGETAIL},
-    {NULL, 0, 0}
+	{"on", 1 << REISERFS_LARGETAIL, 1 << REISERFS_SMALLTAIL},
+	{"off", 0, (1 << REISERFS_LARGETAIL) | (1 << REISERFS_SMALLTAIL)},
+	{"small", 1 << REISERFS_SMALLTAIL, 1 << REISERFS_LARGETAIL},
+	{NULL, 0, 0}
 };
 
 static const arg_desc_t error_actions[] = {
-    {"panic", 1 << REISERFS_ERROR_PANIC,
-              (1 << REISERFS_ERROR_RO | 1 << REISERFS_ERROR_CONTINUE)},
-    {"ro-remount", 1 << REISERFS_ERROR_RO,
-              (1 << REISERFS_ERROR_PANIC | 1 << REISERFS_ERROR_CONTINUE)},
+	{"panic", 1 << REISERFS_ERROR_PANIC,
+	 (1 << REISERFS_ERROR_RO | 1 << REISERFS_ERROR_CONTINUE)},
+	{"ro-remount", 1 << REISERFS_ERROR_RO,
+	 (1 << REISERFS_ERROR_PANIC | 1 << REISERFS_ERROR_CONTINUE)},
 #ifdef REISERFS_JOURNAL_ERROR_ALLOWS_NO_LOG
-    {"continue", 1 << REISERFS_ERROR_CONTINUE,
-              (1 << REISERFS_ERROR_PANIC | 1 << REISERFS_ERROR_RO)},
+	{"continue", 1 << REISERFS_ERROR_CONTINUE,
+	 (1 << REISERFS_ERROR_PANIC | 1 << REISERFS_ERROR_RO)},
 #endif
-    {NULL, 0, 0},
+	{NULL, 0, 0},
 };
 
-int reiserfs_default_io_size = 128 * 1024; /* Default recommended I/O size is 128k.
-					      There might be broken applications that are
-					      confused by this. Use nolargeio mount option
-					      to get usual i/o size = PAGE_SIZE.
-					    */
+int reiserfs_default_io_size = 128 * 1024;	/* Default recommended I/O size is 128k.
+						   There might be broken applications that are
+						   confused by this. Use nolargeio mount option
+						   to get usual i/o size = PAGE_SIZE.
+						 */
 
 /* proceed only one option from a list *cur - string containing of mount options
    opts - array of options which are accepted
@@ -716,476 +743,530 @@ int reiserfs_default_io_size = 128 * 102
    in the input - pointer to the argument is stored here
    bit_flags - if option requires to set a certain bit - it is set here
    return -1 if unknown option is found, opt->arg_required otherwise */
-static int reiserfs_getopt ( struct super_block * s, char ** cur, opt_desc_t * opts, char ** opt_arg,
-			    unsigned long * bit_flags)
+static int reiserfs_getopt(struct super_block *s, char **cur, opt_desc_t * opts,
+			   char **opt_arg, unsigned long *bit_flags)
 {
-    char * p;
-    /* foo=bar, 
-       ^   ^  ^
-       |   |  +-- option_end
-       |   +-- arg_start
-       +-- option_start
-    */
-    const opt_desc_t * opt;
-    const arg_desc_t * arg;
-    
-    
-    p = *cur;
-    
-    /* assume argument cannot contain commas */
-    *cur = strchr (p, ',');
-    if (*cur) {
-	*(*cur) = '\0';
-	(*cur) ++;
-    }
-
-    if ( !strncmp (p, "alloc=", 6) ) {
-	/* Ugly special case, probably we should redo options parser so that
-	   it can understand several arguments for some options, also so that
-	   it can fill several bitfields with option values. */
-	if ( reiserfs_parse_alloc_options( s, p + 6) ) {
-	    return -1;
-	} else {
-	    return 0;
+	char *p;
+	/* foo=bar, 
+	   ^   ^  ^
+	   |   |  +-- option_end
+	   |   +-- arg_start
+	   +-- option_start
+	 */
+	const opt_desc_t *opt;
+	const arg_desc_t *arg;
+
+	p = *cur;
+
+	/* assume argument cannot contain commas */
+	*cur = strchr(p, ',');
+	if (*cur) {
+		*(*cur) = '\0';
+		(*cur)++;
+	}
+
+	if (!strncmp(p, "alloc=", 6)) {
+		/* Ugly special case, probably we should redo options parser so that
+		   it can understand several arguments for some options, also so that
+		   it can fill several bitfields with option values. */
+		if (reiserfs_parse_alloc_options(s, p + 6)) {
+			return -1;
+		} else {
+			return 0;
+		}
 	}
-    }
 
- 
-    /* for every option in the list */
-    for (opt = opts; opt->option_name; opt ++) {
-	if (!strncmp (p, opt->option_name, strlen (opt->option_name))) {
-	    if (bit_flags) {
-                if (opt->clrmask == (1 << REISERFS_UNSUPPORTED_OPT))
-                    reiserfs_warning (s, "%s not supported.", p);
-                else
-                    *bit_flags &= ~opt->clrmask;
-                if (opt->setmask == (1 << REISERFS_UNSUPPORTED_OPT))
-                    reiserfs_warning (s, "%s not supported.", p);
-                else
-                    *bit_flags |= opt->setmask;
-	    }
-	    break;
-	}
-    }
-    if (!opt->option_name) {
-	reiserfs_warning (s, "unknown mount option \"%s\"", p);
-	return -1;
-    }
-    
-    p += strlen (opt->option_name);
-    switch (*p) {
-    case '=':
-	if (!opt->arg_required) {
-	    reiserfs_warning (s, "the option \"%s\" does not require an argument",
-		    opt->option_name);
-	    return -1;
-	}
-	break;
-	
-    case 0:
-	if (opt->arg_required) {
-	    reiserfs_warning (s, "the option \"%s\" requires an argument", opt->option_name);
-	    return -1;
-	}
-	break;
-    default:
-	reiserfs_warning (s, "head of option \"%s\" is only correct", opt->option_name);
-	return -1;
-    }
+	/* for every option in the list */
+	for (opt = opts; opt->option_name; opt++) {
+		if (!strncmp(p, opt->option_name, strlen(opt->option_name))) {
+			if (bit_flags) {
+				if (opt->clrmask ==
+				    (1 << REISERFS_UNSUPPORTED_OPT))
+					reiserfs_warning(s, "%s not supported.",
+							 p);
+				else
+					*bit_flags &= ~opt->clrmask;
+				if (opt->setmask ==
+				    (1 << REISERFS_UNSUPPORTED_OPT))
+					reiserfs_warning(s, "%s not supported.",
+							 p);
+				else
+					*bit_flags |= opt->setmask;
+			}
+			break;
+		}
+	}
+	if (!opt->option_name) {
+		reiserfs_warning(s, "unknown mount option \"%s\"", p);
+		return -1;
+	}
+
+	p += strlen(opt->option_name);
+	switch (*p) {
+	case '=':
+		if (!opt->arg_required) {
+			reiserfs_warning(s,
+					 "the option \"%s\" does not require an argument",
+					 opt->option_name);
+			return -1;
+		}
+		break;
+
+	case 0:
+		if (opt->arg_required) {
+			reiserfs_warning(s,
+					 "the option \"%s\" requires an argument",
+					 opt->option_name);
+			return -1;
+		}
+		break;
+	default:
+		reiserfs_warning(s, "head of option \"%s\" is only correct",
+				 opt->option_name);
+		return -1;
+	}
+
+	/* move to the argument, or to next option if argument is not required */
+	p++;
+
+	if (opt->arg_required
+	    && !(opt->arg_required & (1 << REISERFS_OPT_ALLOWEMPTY))
+	    && !strlen(p)) {
+		/* this catches "option=," if not allowed */
+		reiserfs_warning(s, "empty argument for \"%s\"",
+				 opt->option_name);
+		return -1;
+	}
+
+	if (!opt->values) {
+		/* *=NULLopt_arg contains pointer to argument */
+		*opt_arg = p;
+		return opt->arg_required & ~(1 << REISERFS_OPT_ALLOWEMPTY);
+	}
+
+	/* values possible for this option are listed in opt->values */
+	for (arg = opt->values; arg->value; arg++) {
+		if (!strcmp(p, arg->value)) {
+			if (bit_flags) {
+				*bit_flags &= ~arg->clrmask;
+				*bit_flags |= arg->setmask;
+			}
+			return opt->arg_required;
+		}
+	}
 
-    /* move to the argument, or to next option if argument is not required */
-    p ++;
-    
-    if ( opt->arg_required && !(opt->arg_required & (1<<REISERFS_OPT_ALLOWEMPTY)) && !strlen (p) ) {
-	/* this catches "option=," if not allowed */
-	reiserfs_warning (s, "empty argument for \"%s\"", opt->option_name);
+	reiserfs_warning(s, "bad value \"%s\" for option \"%s\"", p,
+			 opt->option_name);
 	return -1;
-    }
-    
-    if (!opt->values) {
-	/* *=NULLopt_arg contains pointer to argument */
-	*opt_arg = p;
-	return opt->arg_required & ~(1<<REISERFS_OPT_ALLOWEMPTY);
-    }
-    
-    /* values possible for this option are listed in opt->values */
-    for (arg = opt->values; arg->value; arg ++) {
-	if (!strcmp (p, arg->value)) {
-	    if (bit_flags) {
-		*bit_flags &= ~arg->clrmask;
-		*bit_flags |= arg->setmask;
-	    }
-	    return opt->arg_required;
-	}
-    }
-    
-    reiserfs_warning (s, "bad value \"%s\" for option \"%s\"", p, opt->option_name);
-    return -1;
 }
 
 /* returns 0 if something is wrong in option string, 1 - otherwise */
-static int reiserfs_parse_options (struct super_block * s, char * options, /* string given via mount's -o */
-				   unsigned long * mount_options,
-				   /* after the parsing phase, contains the
-				      collection of bitflags defining what
-				      mount options were selected. */
-				   unsigned long * blocks, /* strtol-ed from NNN of resize=NNN */
-				   char ** jdev_name,
-				   unsigned int * commit_max_age)
-{
-    int c;
-    char * arg = NULL;
-    char * pos;
-    opt_desc_t opts[] = {
-	/* Compatibility stuff, so that -o notail for old setups still work */
-	{"tails",	.arg_required = 't', .values = tails},
-	{"notail",	.clrmask = (1<<REISERFS_LARGETAIL)|(1<<REISERFS_SMALLTAIL)},
-	{"conv",	.setmask = 1<<REISERFS_CONVERT},
-	{"attrs",	.setmask = 1<<REISERFS_ATTRS},
-	{"noattrs",	.clrmask = 1<<REISERFS_ATTRS},
+static int reiserfs_parse_options(struct super_block *s, char *options,	/* string given via mount's -o */
+				  unsigned long *mount_options,
+				  /* after the parsing phase, contains the
+				     collection of bitflags defining what
+				     mount options were selected. */
+				  unsigned long *blocks,	/* strtol-ed from NNN of resize=NNN */
+				  char **jdev_name,
+				  unsigned int *commit_max_age)
+{
+	int c;
+	char *arg = NULL;
+	char *pos;
+	opt_desc_t opts[] = {
+		/* Compatibility stuff, so that -o notail for old setups still work */
+		{"tails",.arg_required = 't',.values = tails},
+		{"notail",.clrmask =
+		 (1 << REISERFS_LARGETAIL) | (1 << REISERFS_SMALLTAIL)},
+		{"conv",.setmask = 1 << REISERFS_CONVERT},
+		{"attrs",.setmask = 1 << REISERFS_ATTRS},
+		{"noattrs",.clrmask = 1 << REISERFS_ATTRS},
 #ifdef CONFIG_REISERFS_FS_XATTR
-	{"user_xattr",	.setmask = 1<<REISERFS_XATTRS_USER},
-	{"nouser_xattr",.clrmask = 1<<REISERFS_XATTRS_USER},
+		{"user_xattr",.setmask = 1 << REISERFS_XATTRS_USER},
+		{"nouser_xattr",.clrmask = 1 << REISERFS_XATTRS_USER},
 #else
-	{"user_xattr",	.setmask = 1<<REISERFS_UNSUPPORTED_OPT},
-	{"nouser_xattr",.clrmask = 1<<REISERFS_UNSUPPORTED_OPT},
+		{"user_xattr",.setmask = 1 << REISERFS_UNSUPPORTED_OPT},
+		{"nouser_xattr",.clrmask = 1 << REISERFS_UNSUPPORTED_OPT},
 #endif
 #ifdef CONFIG_REISERFS_FS_POSIX_ACL
-	{"acl",		.setmask = 1<<REISERFS_POSIXACL},
-	{"noacl",	.clrmask = 1<<REISERFS_POSIXACL},
+		{"acl",.setmask = 1 << REISERFS_POSIXACL},
+		{"noacl",.clrmask = 1 << REISERFS_POSIXACL},
 #else
-	{"acl",		.setmask = 1<<REISERFS_UNSUPPORTED_OPT},
-	{"noacl",	.clrmask = 1<<REISERFS_UNSUPPORTED_OPT},
+		{"acl",.setmask = 1 << REISERFS_UNSUPPORTED_OPT},
+		{"noacl",.clrmask = 1 << REISERFS_UNSUPPORTED_OPT},
 #endif
-	{"nolog",},	 /* This is unsupported */
-	{"replayonly",	.setmask = 1<<REPLAYONLY},
-	{"block-allocator", .arg_required = 'a', .values = balloc},
-	{"data",	.arg_required = 'd', .values = logging_mode},
-	{"barrier",	.arg_required = 'b', .values = barrier_mode},
-	{"resize",	.arg_required = 'r', .values = NULL},
-	{"jdev",	.arg_required = 'j', .values = NULL},
-	{"nolargeio",	.arg_required = 'w', .values = NULL},
-	{"commit",	.arg_required = 'c', .values = NULL},
-	{"usrquota",},
-	{"grpquota",},
-	{"errors", 	.arg_required = 'e', .values = error_actions},
-	{"usrjquota",	.arg_required = 'u'|(1<<REISERFS_OPT_ALLOWEMPTY), .values = NULL},
-	{"grpjquota",	.arg_required = 'g'|(1<<REISERFS_OPT_ALLOWEMPTY), .values = NULL},
-	{"jqfmt",	.arg_required = 'f', .values = NULL},
-	{NULL,}
-    };
-	
-    *blocks = 0;
-    if (!options || !*options)
-	/* use default configuration: create tails, journaling on, no
-	   conversion to newest format */
-	return 1;
-    
-    for (pos = options; pos; ) {
-	c = reiserfs_getopt (s, &pos, opts, &arg, mount_options);
-	if (c == -1)
-	    /* wrong option is given */
-	    return 0;
-	
-	if (c == 'r') {
-	    char * p;
-	    
-	    p = NULL;
-	    /* "resize=NNN" or "resize=auto" */
-
-	    if (!strcmp(arg, "auto")) {
-		    /* From JFS code, to auto-get the size.*/
-		    *blocks = s->s_bdev->bd_inode->i_size >> s->s_blocksize_bits;
-	    } else {
-		    *blocks = simple_strtoul (arg, &p, 0);
-		    if (*p != '\0') {
-			/* NNN does not look like a number */
-			reiserfs_warning (s, "reiserfs_parse_options: bad value %s", arg);
+		{"nolog",},	/* This is unsupported */
+		{"replayonly",.setmask = 1 << REPLAYONLY},
+		{"block-allocator",.arg_required = 'a',.values = balloc},
+		{"data",.arg_required = 'd',.values = logging_mode},
+		{"barrier",.arg_required = 'b',.values = barrier_mode},
+		{"resize",.arg_required = 'r',.values = NULL},
+		{"jdev",.arg_required = 'j',.values = NULL},
+		{"nolargeio",.arg_required = 'w',.values = NULL},
+		{"commit",.arg_required = 'c',.values = NULL},
+		{"usrquota",.setmask = 1 << REISERFS_QUOTA},
+		{"grpquota",.setmask = 1 << REISERFS_QUOTA},
+		{"noquota",.clrmask = 1 << REISERFS_QUOTA},
+		{"errors",.arg_required = 'e',.values = error_actions},
+		{"usrjquota",.arg_required =
+		 'u' | (1 << REISERFS_OPT_ALLOWEMPTY),.values = NULL},
+		{"grpjquota",.arg_required =
+		 'g' | (1 << REISERFS_OPT_ALLOWEMPTY),.values = NULL},
+		{"jqfmt",.arg_required = 'f',.values = NULL},
+		{NULL,}
+	};
+
+	*blocks = 0;
+	if (!options || !*options)
+		/* use default configuration: create tails, journaling on, no
+		   conversion to newest format */
+		return 1;
+
+	for (pos = options; pos;) {
+		c = reiserfs_getopt(s, &pos, opts, &arg, mount_options);
+		if (c == -1)
+			/* wrong option is given */
 			return 0;
-		    }
-	    }
-	}
 
-	if ( c == 'c' ) {
-		char *p = NULL;
-		unsigned long val = simple_strtoul (arg, &p, 0);
-		/* commit=NNN (time in seconds) */
-		if ( *p != '\0' || val >= (unsigned int)-1) {
-			reiserfs_warning (s, "reiserfs_parse_options: bad value %s", arg);
-			return 0;
+		if (c == 'r') {
+			char *p;
+
+			p = NULL;
+			/* "resize=NNN" or "resize=auto" */
+
+			if (!strcmp(arg, "auto")) {
+				/* From JFS code, to auto-get the size. */
+				*blocks =
+				    s->s_bdev->bd_inode->i_size >> s->
+				    s_blocksize_bits;
+			} else {
+				*blocks = simple_strtoul(arg, &p, 0);
+				if (*p != '\0') {
+					/* NNN does not look like a number */
+					reiserfs_warning(s,
+							 "reiserfs_parse_options: bad value %s",
+							 arg);
+					return 0;
+				}
+			}
+		}
+
+		if (c == 'c') {
+			char *p = NULL;
+			unsigned long val = simple_strtoul(arg, &p, 0);
+			/* commit=NNN (time in seconds) */
+			if (*p != '\0' || val >= (unsigned int)-1) {
+				reiserfs_warning(s,
+						 "reiserfs_parse_options: bad value %s",
+						 arg);
+				return 0;
+			}
+			*commit_max_age = (unsigned int)val;
 		}
-		*commit_max_age = (unsigned int)val;
-	}
 
-	if ( c == 'w' ) {
-		char *p=NULL;
-		int val = simple_strtoul (arg, &p, 0);
+		if (c == 'w') {
+			char *p = NULL;
+			int val = simple_strtoul(arg, &p, 0);
+
+			if (*p != '\0') {
+				reiserfs_warning(s,
+						 "reiserfs_parse_options: non-numeric value %s for nolargeio option",
+						 arg);
+				return 0;
+			}
+			if (val)
+				reiserfs_default_io_size = PAGE_SIZE;
+			else
+				reiserfs_default_io_size = 128 * 1024;
+		}
 
-		if ( *p != '\0') {
-		    reiserfs_warning (s, "reiserfs_parse_options: non-numeric value %s for nolargeio option", arg);
-		    return 0;
+		if (c == 'j') {
+			if (arg && *arg && jdev_name) {
+				if (*jdev_name) {	//Hm, already assigned?
+					reiserfs_warning(s,
+							 "reiserfs_parse_options: journal device was already  specified to be %s",
+							 *jdev_name);
+					return 0;
+				}
+				*jdev_name = arg;
+			}
 		}
-		if ( val ) 
-		    reiserfs_default_io_size = PAGE_SIZE;
-		else
-		    reiserfs_default_io_size = 128 * 1024;
-	}
+#ifdef CONFIG_QUOTA
+		if (c == 'u' || c == 'g') {
+			int qtype = c == 'u' ? USRQUOTA : GRPQUOTA;
 
-	if (c == 'j') {
-	    if (arg && *arg && jdev_name) {
-		if ( *jdev_name ) { //Hm, already assigned?
-		    reiserfs_warning (s, "reiserfs_parse_options: journal device was already  specified to be %s", *jdev_name);
-		    return 0;
+			if (sb_any_quota_enabled(s)) {
+				reiserfs_warning(s,
+						 "reiserfs_parse_options: cannot change journalled quota options when quota turned on.");
+				return 0;
+			}
+			if (*arg) {	/* Some filename specified? */
+				if (REISERFS_SB(s)->s_qf_names[qtype]
+				    && strcmp(REISERFS_SB(s)->s_qf_names[qtype],
+					      arg)) {
+					reiserfs_warning(s,
+							 "reiserfs_parse_options: %s quota file already specified.",
+							 QTYPE2NAME(qtype));
+					return 0;
+				}
+				if (strchr(arg, '/')) {
+					reiserfs_warning(s,
+							 "reiserfs_parse_options: quotafile must be on filesystem root.");
+					return 0;
+				}
+				REISERFS_SB(s)->s_qf_names[qtype] =
+				    kmalloc(strlen(arg) + 1, GFP_KERNEL);
+				if (!REISERFS_SB(s)->s_qf_names[qtype]) {
+					reiserfs_warning(s,
+							 "reiserfs_parse_options: not enough memory for storing quotafile name.");
+					return 0;
+				}
+				strcpy(REISERFS_SB(s)->s_qf_names[qtype], arg);
+				*mount_options |= 1 << REISERFS_QUOTA;
+			} else {
+				if (REISERFS_SB(s)->s_qf_names[qtype]) {
+					kfree(REISERFS_SB(s)->
+					      s_qf_names[qtype]);
+					REISERFS_SB(s)->s_qf_names[qtype] =
+					    NULL;
+				}
+			}
+		}
+		if (c == 'f') {
+			if (!strcmp(arg, "vfsold"))
+				REISERFS_SB(s)->s_jquota_fmt = QFMT_VFS_OLD;
+			else if (!strcmp(arg, "vfsv0"))
+				REISERFS_SB(s)->s_jquota_fmt = QFMT_VFS_V0;
+			else {
+				reiserfs_warning(s,
+						 "reiserfs_parse_options: unknown quota format specified.");
+				return 0;
+			}
+		}
+#else
+		if (c == 'u' || c == 'g' || c == 'f') {
+			reiserfs_warning(s,
+					 "reiserfs_parse_options: journalled quota options not supported.");
+			return 0;
 		}
-		*jdev_name = arg;
-	    }
+#endif
 	}
 
 #ifdef CONFIG_QUOTA
-	if (c == 'u' || c == 'g') {
-	    int qtype = c == 'u' ? USRQUOTA : GRPQUOTA;
-
-	    if (sb_any_quota_enabled(s)) {
-		reiserfs_warning(s, "reiserfs_parse_options: cannot change journalled quota options when quota turned on.");
-		return 0;
-	    }
-	    if (*arg) {	/* Some filename specified? */
-	        if (REISERFS_SB(s)->s_qf_names[qtype] && strcmp(REISERFS_SB(s)->s_qf_names[qtype], arg)) {
-		    reiserfs_warning(s, "reiserfs_parse_options: %s quota file already specified.", QTYPE2NAME(qtype));
-		    return 0;
-		}
-		if (strchr(arg, '/')) {
-		    reiserfs_warning(s, "reiserfs_parse_options: quotafile must be on filesystem root.");
-		    return 0;
-		}
-	    	REISERFS_SB(s)->s_qf_names[qtype] = kmalloc(strlen(arg)+1, GFP_KERNEL);
-		if (!REISERFS_SB(s)->s_qf_names[qtype]) {
-		    reiserfs_warning(s, "reiserfs_parse_options: not enough memory for storing quotafile name.");
-		    return 0;
-		}
-		strcpy(REISERFS_SB(s)->s_qf_names[qtype], arg);
-	    }
-	    else {
-		if (REISERFS_SB(s)->s_qf_names[qtype]) {
-		    kfree(REISERFS_SB(s)->s_qf_names[qtype]);
-		    REISERFS_SB(s)->s_qf_names[qtype] = NULL;
-		}
-	    }
-	}
-	if (c == 'f') {
-	    if (!strcmp(arg, "vfsold"))
-		REISERFS_SB(s)->s_jquota_fmt = QFMT_VFS_OLD;
-	    else if (!strcmp(arg, "vfsv0"))
-		REISERFS_SB(s)->s_jquota_fmt = QFMT_VFS_V0;
-	    else {
-		reiserfs_warning(s, "reiserfs_parse_options: unknown quota format specified.");
+	if (!REISERFS_SB(s)->s_jquota_fmt
+	    && (REISERFS_SB(s)->s_qf_names[USRQUOTA]
+		|| REISERFS_SB(s)->s_qf_names[GRPQUOTA])) {
+		reiserfs_warning(s,
+				 "reiserfs_parse_options: journalled quota format not specified.");
 		return 0;
-	    }
 	}
-#else
-	if (c == 'u' || c == 'g' || c == 'f') {
-	    reiserfs_warning(s, "reiserfs_parse_options: journalled quota options not supported.");
-	    return 0;
+	/* This checking is not precise wrt the quota type but for our purposes it is sufficient */
+	if (!(*mount_options & (1 << REISERFS_QUOTA))
+	    && sb_any_quota_enabled(s)) {
+		reiserfs_warning(s,
+				 "reiserfs_parse_options: quota options must be present when quota is turned on.");
+		return 0;
 	}
 #endif
-    }
-    
-#ifdef CONFIG_QUOTA
-    if (!REISERFS_SB(s)->s_jquota_fmt && (REISERFS_SB(s)->s_qf_names[USRQUOTA] || REISERFS_SB(s)->s_qf_names[GRPQUOTA])) {
-	reiserfs_warning(s, "reiserfs_parse_options: journalled quota format not specified.");
-	return 0;
-    }
-#endif
-    return 1;
+
+	return 1;
 }
 
-static void switch_data_mode(struct super_block *s, unsigned long mode) {
-    REISERFS_SB(s)->s_mount_opt &= ~((1 << REISERFS_DATA_LOG) |
-                                       (1 << REISERFS_DATA_ORDERED) |
-				       (1 << REISERFS_DATA_WRITEBACK));
-    REISERFS_SB(s)->s_mount_opt |= (1 << mode);
+static void switch_data_mode(struct super_block *s, unsigned long mode)
+{
+	REISERFS_SB(s)->s_mount_opt &= ~((1 << REISERFS_DATA_LOG) |
+					 (1 << REISERFS_DATA_ORDERED) |
+					 (1 << REISERFS_DATA_WRITEBACK));
+	REISERFS_SB(s)->s_mount_opt |= (1 << mode);
 }
 
 static void handle_data_mode(struct super_block *s, unsigned long mount_options)
 {
-    if (mount_options & (1 << REISERFS_DATA_LOG)) {
-        if (!reiserfs_data_log(s)) {
-	    switch_data_mode(s, REISERFS_DATA_LOG);
-	    reiserfs_info (s, "switching to journaled data mode\n");
-	}
-    } else if (mount_options & (1 << REISERFS_DATA_ORDERED)) {
-        if (!reiserfs_data_ordered(s)) {
-	    switch_data_mode(s, REISERFS_DATA_ORDERED);
-	    reiserfs_info (s, "switching to ordered data mode\n");
-	}
-    } else if (mount_options & (1 << REISERFS_DATA_WRITEBACK)) {
-        if (!reiserfs_data_writeback(s)) {
-	    switch_data_mode(s, REISERFS_DATA_WRITEBACK);
-	    reiserfs_info (s, "switching to writeback data mode\n");
-	}
-    }
-}
-
-static void handle_barrier_mode(struct super_block *s, unsigned long bits) {
-    int flush = (1 << REISERFS_BARRIER_FLUSH);
-    int none = (1 << REISERFS_BARRIER_NONE);
-    int all_barrier = flush | none;
-
-    if (bits & all_barrier) {
-        REISERFS_SB(s)->s_mount_opt &= ~all_barrier;
-	if (bits & flush) {
-	    REISERFS_SB(s)->s_mount_opt |= flush;
-	    printk("reiserfs: enabling write barrier flush mode\n");
-	} else if (bits & none) {
-	    REISERFS_SB(s)->s_mount_opt |= none;
-	    printk("reiserfs: write barriers turned off\n");
-	}
-   }
-}
-
-static void handle_attrs( struct super_block *s )
-{
-	struct reiserfs_super_block * rs;
-
-	if( reiserfs_attrs( s ) ) {
-		rs = SB_DISK_SUPER_BLOCK (s);
-		if( old_format_only(s) ) {
-			reiserfs_warning(s, "reiserfs: cannot support attributes on 3.5.x disk format" );
-			REISERFS_SB(s) -> s_mount_opt &= ~ ( 1 << REISERFS_ATTRS );
+	if (mount_options & (1 << REISERFS_DATA_LOG)) {
+		if (!reiserfs_data_log(s)) {
+			switch_data_mode(s, REISERFS_DATA_LOG);
+			reiserfs_info(s, "switching to journaled data mode\n");
+		}
+	} else if (mount_options & (1 << REISERFS_DATA_ORDERED)) {
+		if (!reiserfs_data_ordered(s)) {
+			switch_data_mode(s, REISERFS_DATA_ORDERED);
+			reiserfs_info(s, "switching to ordered data mode\n");
+		}
+	} else if (mount_options & (1 << REISERFS_DATA_WRITEBACK)) {
+		if (!reiserfs_data_writeback(s)) {
+			switch_data_mode(s, REISERFS_DATA_WRITEBACK);
+			reiserfs_info(s, "switching to writeback data mode\n");
+		}
+	}
+}
+
+static void handle_barrier_mode(struct super_block *s, unsigned long bits)
+{
+	int flush = (1 << REISERFS_BARRIER_FLUSH);
+	int none = (1 << REISERFS_BARRIER_NONE);
+	int all_barrier = flush | none;
+
+	if (bits & all_barrier) {
+		REISERFS_SB(s)->s_mount_opt &= ~all_barrier;
+		if (bits & flush) {
+			REISERFS_SB(s)->s_mount_opt |= flush;
+			printk("reiserfs: enabling write barrier flush mode\n");
+		} else if (bits & none) {
+			REISERFS_SB(s)->s_mount_opt |= none;
+			printk("reiserfs: write barriers turned off\n");
+		}
+	}
+}
+
+static void handle_attrs(struct super_block *s)
+{
+	struct reiserfs_super_block *rs = SB_DISK_SUPER_BLOCK(s);
+
+	if (reiserfs_attrs(s)) {
+		if (old_format_only(s)) {
+			reiserfs_warning(s,
+					 "reiserfs: cannot support attributes on 3.5.x disk format");
+			REISERFS_SB(s)->s_mount_opt &= ~(1 << REISERFS_ATTRS);
 			return;
 		}
-		if( !( le32_to_cpu( rs -> s_flags ) & reiserfs_attrs_cleared ) ) {
-				reiserfs_warning(s, "reiserfs: cannot support attributes until flag is set in super-block" );
-				REISERFS_SB(s) -> s_mount_opt &= ~ ( 1 << REISERFS_ATTRS );
+		if (!(le32_to_cpu(rs->s_flags) & reiserfs_attrs_cleared)) {
+			reiserfs_warning(s,
+					 "reiserfs: cannot support attributes until flag is set in super-block");
+			REISERFS_SB(s)->s_mount_opt &= ~(1 << REISERFS_ATTRS);
 		}
+	} else if (le32_to_cpu(rs->s_flags) & reiserfs_attrs_cleared) {
+		REISERFS_SB(s)->s_mount_opt |= REISERFS_ATTRS;
 	}
 }
 
-static int reiserfs_remount (struct super_block * s, int * mount_flags, char * arg)
+static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg)
 {
-  struct reiserfs_super_block * rs;
-  struct reiserfs_transaction_handle th ;
-  unsigned long blocks;
-  unsigned long mount_options = REISERFS_SB(s)->s_mount_opt;
-  unsigned long safe_mask = 0;
-  unsigned int commit_max_age = (unsigned int)-1;
-  struct reiserfs_journal *journal = SB_JOURNAL(s);
-  int err;
+	struct reiserfs_super_block *rs;
+	struct reiserfs_transaction_handle th;
+	unsigned long blocks;
+	unsigned long mount_options = REISERFS_SB(s)->s_mount_opt;
+	unsigned long safe_mask = 0;
+	unsigned int commit_max_age = (unsigned int)-1;
+	struct reiserfs_journal *journal = SB_JOURNAL(s);
+	int err;
 #ifdef CONFIG_QUOTA
-  int i;
+	int i;
 #endif
 
-  rs = SB_DISK_SUPER_BLOCK (s);
+	rs = SB_DISK_SUPER_BLOCK(s);
 
-  if (!reiserfs_parse_options(s, arg, &mount_options, &blocks, NULL, &commit_max_age)) {
+	if (!reiserfs_parse_options
+	    (s, arg, &mount_options, &blocks, NULL, &commit_max_age)) {
 #ifdef CONFIG_QUOTA
-    for (i = 0; i < MAXQUOTAS; i++)
-	if (REISERFS_SB(s)->s_qf_names[i]) {
-	    kfree(REISERFS_SB(s)->s_qf_names[i]);
-	    REISERFS_SB(s)->s_qf_names[i] = NULL;
-	}
+		for (i = 0; i < MAXQUOTAS; i++)
+			if (REISERFS_SB(s)->s_qf_names[i]) {
+				kfree(REISERFS_SB(s)->s_qf_names[i]);
+				REISERFS_SB(s)->s_qf_names[i] = NULL;
+			}
 #endif
-    return -EINVAL;
-  }
-  
-  handle_attrs(s);
-
-  /* Add options that are safe here */
-  safe_mask |= 1 << REISERFS_SMALLTAIL;
-  safe_mask |= 1 << REISERFS_LARGETAIL;
-  safe_mask |= 1 << REISERFS_NO_BORDER;
-  safe_mask |= 1 << REISERFS_NO_UNHASHED_RELOCATION;
-  safe_mask |= 1 << REISERFS_HASHED_RELOCATION;
-  safe_mask |= 1 << REISERFS_TEST4;
-  safe_mask |= 1 << REISERFS_ATTRS;
-  safe_mask |= 1 << REISERFS_XATTRS_USER;
-  safe_mask |= 1 << REISERFS_POSIXACL;
-  safe_mask |= 1 << REISERFS_BARRIER_FLUSH;
-  safe_mask |= 1 << REISERFS_BARRIER_NONE;
-  safe_mask |= 1 << REISERFS_ERROR_RO;
-  safe_mask |= 1 << REISERFS_ERROR_CONTINUE;
-  safe_mask |= 1 << REISERFS_ERROR_PANIC;
-
-  /* Update the bitmask, taking care to keep
-   * the bits we're not allowed to change here */
-  REISERFS_SB(s)->s_mount_opt = (REISERFS_SB(s)->s_mount_opt & ~safe_mask) |  (mount_options & safe_mask);
-
-  if(commit_max_age != 0 && commit_max_age != (unsigned int)-1) {
-    journal->j_max_commit_age = commit_max_age;
-    journal->j_max_trans_age = commit_max_age;
-  }
-  else if(commit_max_age == 0)
-  {
-    /* 0 means restore defaults. */
-    journal->j_max_commit_age = journal->j_default_max_commit_age;
-    journal->j_max_trans_age = JOURNAL_MAX_TRANS_AGE;
-  }
-
-  if(blocks) {
-    int rc = reiserfs_resize(s, blocks);
-    if (rc != 0)
-      return rc;
-  }
-
-  if (*mount_flags & MS_RDONLY) {
-    reiserfs_xattr_init (s, *mount_flags);
-    /* remount read-only */
-    if (s->s_flags & MS_RDONLY)
-      /* it is read-only already */
-      return 0;
-    /* try to remount file system with read-only permissions */
-    if (sb_umount_state(rs) == REISERFS_VALID_FS || REISERFS_SB(s)->s_mount_state != REISERFS_VALID_FS) {
-      return 0;
-    }
-
-    err = journal_begin(&th, s, 10) ;
-    if (err)
-        return err;
-
-    /* Mounting a rw partition read-only. */
-    reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1) ;
-    set_sb_umount_state( rs, REISERFS_SB(s)->s_mount_state );
-    journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB (s));
-  } else {
-    /* remount read-write */
-    if (!(s->s_flags & MS_RDONLY)) {
-	reiserfs_xattr_init (s, *mount_flags);
-	return 0; /* We are read-write already */
-    }
-
-    if (reiserfs_is_journal_aborted (journal))
-	return journal->j_errno;
-
-    handle_data_mode(s, mount_options);
-    handle_barrier_mode(s, mount_options);
-    REISERFS_SB(s)->s_mount_state = sb_umount_state(rs) ;
-    s->s_flags &= ~MS_RDONLY ; /* now it is safe to call journal_begin */
-    err = journal_begin(&th, s, 10) ;
-    if (err)
-	return err;
-    
-    /* Mount a partition which is read-only, read-write */
-    reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1) ;
-    REISERFS_SB(s)->s_mount_state = sb_umount_state(rs);
-    s->s_flags &= ~MS_RDONLY;
-    set_sb_umount_state( rs, REISERFS_ERROR_FS );
-    /* mark_buffer_dirty (SB_BUFFER_WITH_SB (s), 1); */
-    journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB (s));
-    REISERFS_SB(s)->s_mount_state = REISERFS_VALID_FS ;
-  }
-  /* this will force a full flush of all journal lists */
-  SB_JOURNAL(s)->j_must_wait = 1 ;
-  err = journal_end(&th, s, 10) ;
-  if (err)
-    return err;
-  s->s_dirt = 0;
-
-  if (!( *mount_flags & MS_RDONLY ) ) {
-    finish_unfinished( s );
-    reiserfs_xattr_init (s, *mount_flags);
-  }
+		return -EINVAL;
+	}
 
-  return 0;
+	handle_attrs(s);
+
+	/* Add options that are safe here */
+	safe_mask |= 1 << REISERFS_SMALLTAIL;
+	safe_mask |= 1 << REISERFS_LARGETAIL;
+	safe_mask |= 1 << REISERFS_NO_BORDER;
+	safe_mask |= 1 << REISERFS_NO_UNHASHED_RELOCATION;
+	safe_mask |= 1 << REISERFS_HASHED_RELOCATION;
+	safe_mask |= 1 << REISERFS_TEST4;
+	safe_mask |= 1 << REISERFS_ATTRS;
+	safe_mask |= 1 << REISERFS_XATTRS_USER;
+	safe_mask |= 1 << REISERFS_POSIXACL;
+	safe_mask |= 1 << REISERFS_BARRIER_FLUSH;
+	safe_mask |= 1 << REISERFS_BARRIER_NONE;
+	safe_mask |= 1 << REISERFS_ERROR_RO;
+	safe_mask |= 1 << REISERFS_ERROR_CONTINUE;
+	safe_mask |= 1 << REISERFS_ERROR_PANIC;
+	safe_mask |= 1 << REISERFS_QUOTA;
+
+	/* Update the bitmask, taking care to keep
+	 * the bits we're not allowed to change here */
+	REISERFS_SB(s)->s_mount_opt =
+	    (REISERFS_SB(s)->
+	     s_mount_opt & ~safe_mask) | (mount_options & safe_mask);
+
+	if (commit_max_age != 0 && commit_max_age != (unsigned int)-1) {
+		journal->j_max_commit_age = commit_max_age;
+		journal->j_max_trans_age = commit_max_age;
+	} else if (commit_max_age == 0) {
+		/* 0 means restore defaults. */
+		journal->j_max_commit_age = journal->j_default_max_commit_age;
+		journal->j_max_trans_age = JOURNAL_MAX_TRANS_AGE;
+	}
+
+	if (blocks) {
+		int rc = reiserfs_resize(s, blocks);
+		if (rc != 0)
+			return rc;
+	}
+
+	if (*mount_flags & MS_RDONLY) {
+		reiserfs_xattr_init(s, *mount_flags);
+		/* remount read-only */
+		if (s->s_flags & MS_RDONLY)
+			/* it is read-only already */
+			return 0;
+		/* try to remount file system with read-only permissions */
+		if (sb_umount_state(rs) == REISERFS_VALID_FS
+		    || REISERFS_SB(s)->s_mount_state != REISERFS_VALID_FS) {
+			return 0;
+		}
+
+		err = journal_begin(&th, s, 10);
+		if (err)
+			return err;
+
+		/* Mounting a rw partition read-only. */
+		reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1);
+		set_sb_umount_state(rs, REISERFS_SB(s)->s_mount_state);
+		journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB(s));
+	} else {
+		/* remount read-write */
+		if (!(s->s_flags & MS_RDONLY)) {
+			reiserfs_xattr_init(s, *mount_flags);
+			return 0;	/* We are read-write already */
+		}
+
+		if (reiserfs_is_journal_aborted(journal))
+			return journal->j_errno;
+
+		handle_data_mode(s, mount_options);
+		handle_barrier_mode(s, mount_options);
+		REISERFS_SB(s)->s_mount_state = sb_umount_state(rs);
+		s->s_flags &= ~MS_RDONLY;	/* now it is safe to call journal_begin */
+		err = journal_begin(&th, s, 10);
+		if (err)
+			return err;
+
+		/* Mount a partition which is read-only, read-write */
+		reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1);
+		REISERFS_SB(s)->s_mount_state = sb_umount_state(rs);
+		s->s_flags &= ~MS_RDONLY;
+		set_sb_umount_state(rs, REISERFS_ERROR_FS);
+		/* mark_buffer_dirty (SB_BUFFER_WITH_SB (s), 1); */
+		journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB(s));
+		REISERFS_SB(s)->s_mount_state = REISERFS_VALID_FS;
+	}
+	/* this will force a full flush of all journal lists */
+	SB_JOURNAL(s)->j_must_wait = 1;
+	err = journal_end(&th, s, 10);
+	if (err)
+		return err;
+	s->s_dirt = 0;
+
+	if (!(*mount_flags & MS_RDONLY)) {
+		finish_unfinished(s);
+		reiserfs_xattr_init(s, *mount_flags);
+	}
+
+	return 0;
 }
 
 /* load_bitmap_info_data - Sets up the reiserfs_bitmap_info structure from disk.
@@ -1204,791 +1285,879 @@ static int reiserfs_remount (struct supe
  * free blocks at all.
  */
 
-static void load_bitmap_info_data (struct super_block *sb,
-                                   struct reiserfs_bitmap_info *bi)
+static void load_bitmap_info_data(struct super_block *sb,
+				  struct reiserfs_bitmap_info *bi)
 {
-    unsigned long *cur = (unsigned long *)bi->bh->b_data;
+	unsigned long *cur = (unsigned long *)bi->bh->b_data;
 
-    while ((char *)cur < (bi->bh->b_data + sb->s_blocksize)) {
+	while ((char *)cur < (bi->bh->b_data + sb->s_blocksize)) {
 
-	/* No need to scan if all 0's or all 1's.
-	 * Since we're only counting 0's, we can simply ignore all 1's */
-	if (*cur == 0) {
-	    if (bi->first_zero_hint == 0) {
-		bi->first_zero_hint = ((char *)cur - bi->bh->b_data) << 3;
-	    }
-	    bi->free_count += sizeof(unsigned long)*8;
-	} else if (*cur != ~0L) {
-	    int b;
-	    for (b = 0; b < sizeof(unsigned long)*8; b++) {
-		if (!reiserfs_test_le_bit (b, cur)) {
-		    bi->free_count ++;
-		    if (bi->first_zero_hint == 0)
-			bi->first_zero_hint =
-					(((char *)cur - bi->bh->b_data) << 3) + b;
-		    }
-		}
-	    }
-	cur ++;
-    }
+		/* No need to scan if all 0's or all 1's.
+		 * Since we're only counting 0's, we can simply ignore all 1's */
+		if (*cur == 0) {
+			if (bi->first_zero_hint == 0) {
+				bi->first_zero_hint =
+				    ((char *)cur - bi->bh->b_data) << 3;
+			}
+			bi->free_count += sizeof(unsigned long) * 8;
+		} else if (*cur != ~0L) {
+			int b;
+			for (b = 0; b < sizeof(unsigned long) * 8; b++) {
+				if (!reiserfs_test_le_bit(b, cur)) {
+					bi->free_count++;
+					if (bi->first_zero_hint == 0)
+						bi->first_zero_hint =
+						    (((char *)cur -
+						      bi->bh->b_data) << 3) + b;
+				}
+			}
+		}
+		cur++;
+	}
 
 #ifdef CONFIG_REISERFS_CHECK
 // This outputs a lot of unneded info on big FSes
 //    reiserfs_warning ("bitmap loaded from block %d: %d free blocks",
-//		      bi->bh->b_blocknr, bi->free_count);
+//                    bi->bh->b_blocknr, bi->free_count);
 #endif
 }
-  
-static int read_bitmaps (struct super_block * s)
+
+static int read_bitmaps(struct super_block *s)
 {
-    int i, bmap_nr;
+	int i, bmap_nr;
 
-    SB_AP_BITMAP (s) = vmalloc (sizeof (struct reiserfs_bitmap_info) * SB_BMAP_NR(s));
-    if (SB_AP_BITMAP (s) == 0)
-	return 1;
-    memset (SB_AP_BITMAP (s), 0, sizeof (struct reiserfs_bitmap_info) * SB_BMAP_NR(s));
-    for (i = 0, bmap_nr = REISERFS_DISK_OFFSET_IN_BYTES / s->s_blocksize + 1;
-	 i < SB_BMAP_NR(s); i++, bmap_nr = s->s_blocksize * 8 * i) {
-	SB_AP_BITMAP (s)[i].bh = sb_getblk(s, bmap_nr);
-	if (!buffer_uptodate(SB_AP_BITMAP(s)[i].bh))
-	    ll_rw_block(READ, 1, &SB_AP_BITMAP(s)[i].bh);
-    }
-    for (i = 0; i < SB_BMAP_NR(s); i++) {
-	wait_on_buffer(SB_AP_BITMAP (s)[i].bh);
-	if (!buffer_uptodate(SB_AP_BITMAP(s)[i].bh)) {
-	    reiserfs_warning(s,"sh-2029: reiserfs read_bitmaps: "
-			 "bitmap block (#%lu) reading failed",
-			 SB_AP_BITMAP(s)[i].bh->b_blocknr);
-	    for (i = 0; i < SB_BMAP_NR(s); i++)
-		brelse(SB_AP_BITMAP(s)[i].bh);
-	    vfree(SB_AP_BITMAP(s));
-	    SB_AP_BITMAP(s) = NULL;
-	    return 1;
-	}
-	load_bitmap_info_data (s, SB_AP_BITMAP (s) + i);
-    }
-    return 0;
-}
-
-static int read_old_bitmaps (struct super_block * s)
-{
-  int i ;
-  struct reiserfs_super_block * rs = SB_DISK_SUPER_BLOCK(s);
-  int bmp1 = (REISERFS_OLD_DISK_OFFSET_IN_BYTES / s->s_blocksize) + 1;  /* first of bitmap blocks */
-
-  /* read true bitmap */
-  SB_AP_BITMAP (s) = vmalloc (sizeof (struct reiserfs_buffer_info *) * sb_bmap_nr(rs));
-  if (SB_AP_BITMAP (s) == 0)
-    return 1;
-
-  memset (SB_AP_BITMAP (s), 0, sizeof (struct reiserfs_buffer_info *) * sb_bmap_nr(rs));
-
-  for (i = 0; i < sb_bmap_nr(rs); i ++) {
-    SB_AP_BITMAP (s)[i].bh = sb_bread (s, bmp1 + i);
-    if (!SB_AP_BITMAP (s)[i].bh)
-      return 1;
-    load_bitmap_info_data (s, SB_AP_BITMAP (s) + i);
-  }
-
-  return 0;
-}
-
-static int read_super_block (struct super_block * s, int offset)
-{
-    struct buffer_head * bh;
-    struct reiserfs_super_block * rs;
-    int fs_blocksize;
- 
-
-    bh = sb_bread (s, offset / s->s_blocksize);
-    if (!bh) {
-      reiserfs_warning (s, "sh-2006: read_super_block: "
-              "bread failed (dev %s, block %lu, size %lu)",
-              reiserfs_bdevname (s), offset / s->s_blocksize, s->s_blocksize);
-      return 1;
-    }
- 
-    rs = (struct reiserfs_super_block *)bh->b_data;
-    if (!is_any_reiserfs_magic_string (rs)) {
-      brelse (bh);
-      return 1;
-    }
- 
-    //
-    // ok, reiserfs signature (old or new) found in at the given offset
-    //    
-    fs_blocksize = sb_blocksize(rs);
-    brelse (bh);
-    sb_set_blocksize (s, fs_blocksize);
-    
-    bh = sb_bread (s, offset / s->s_blocksize);
-    if (!bh) {
-	reiserfs_warning (s, "sh-2007: read_super_block: "
-                "bread failed (dev %s, block %lu, size %lu)\n",
-                reiserfs_bdevname (s), offset / s->s_blocksize, s->s_blocksize);
-	return 1;
-    }
-    
-    rs = (struct reiserfs_super_block *)bh->b_data;
-    if (sb_blocksize(rs) != s->s_blocksize) {
-	reiserfs_warning (s, "sh-2011: read_super_block: "
-		"can't find a reiserfs filesystem on (dev %s, block %Lu, size %lu)\n",
-		reiserfs_bdevname (s), (unsigned long long)bh->b_blocknr, s->s_blocksize);
-	brelse (bh);
-	return 1;
-    }
+	SB_AP_BITMAP(s) =
+	    vmalloc(sizeof(struct reiserfs_bitmap_info) * SB_BMAP_NR(s));
+	if (SB_AP_BITMAP(s) == 0)
+		return 1;
+	memset(SB_AP_BITMAP(s), 0,
+	       sizeof(struct reiserfs_bitmap_info) * SB_BMAP_NR(s));
+	for (i = 0, bmap_nr =
+	     REISERFS_DISK_OFFSET_IN_BYTES / s->s_blocksize + 1;
+	     i < SB_BMAP_NR(s); i++, bmap_nr = s->s_blocksize * 8 * i) {
+		SB_AP_BITMAP(s)[i].bh = sb_getblk(s, bmap_nr);
+		if (!buffer_uptodate(SB_AP_BITMAP(s)[i].bh))
+			ll_rw_block(READ, 1, &SB_AP_BITMAP(s)[i].bh);
+	}
+	for (i = 0; i < SB_BMAP_NR(s); i++) {
+		wait_on_buffer(SB_AP_BITMAP(s)[i].bh);
+		if (!buffer_uptodate(SB_AP_BITMAP(s)[i].bh)) {
+			reiserfs_warning(s, "sh-2029: reiserfs read_bitmaps: "
+					 "bitmap block (#%lu) reading failed",
+					 SB_AP_BITMAP(s)[i].bh->b_blocknr);
+			for (i = 0; i < SB_BMAP_NR(s); i++)
+				brelse(SB_AP_BITMAP(s)[i].bh);
+			vfree(SB_AP_BITMAP(s));
+			SB_AP_BITMAP(s) = NULL;
+			return 1;
+		}
+		load_bitmap_info_data(s, SB_AP_BITMAP(s) + i);
+	}
+	return 0;
+}
 
-    if ( rs->s_v1.s_root_block == cpu_to_le32(-1) ) {
-       brelse(bh) ;
-       reiserfs_warning (s, "Unfinished reiserfsck --rebuild-tree run detected. Please run\n"
-              "reiserfsck --rebuild-tree and wait for a completion. If that fails\n"
-              "get newer reiserfsprogs package");
-       return 1;
-    }
-
-    SB_BUFFER_WITH_SB (s) = bh;
-    SB_DISK_SUPER_BLOCK (s) = rs;
-
-    if (is_reiserfs_jr (rs)) {
-	/* magic is of non-standard journal filesystem, look at s_version to
-	   find which format is in use */
-	if (sb_version(rs) == REISERFS_VERSION_2)
-	  reiserfs_warning (s, "read_super_block: found reiserfs format \"3.6\""
-		  " with non-standard journal");
-	else if (sb_version(rs) == REISERFS_VERSION_1)
-	  reiserfs_warning (s, "read_super_block: found reiserfs format \"3.5\""
-		  " with non-standard journal");
-	else {
-	  reiserfs_warning (s, "sh-2012: read_super_block: found unknown "
-			    "format \"%u\" of reiserfs with non-standard magic",
-			    sb_version(rs));
-	return 1;
+static int read_old_bitmaps(struct super_block *s)
+{
+	int i;
+	struct reiserfs_super_block *rs = SB_DISK_SUPER_BLOCK(s);
+	int bmp1 = (REISERFS_OLD_DISK_OFFSET_IN_BYTES / s->s_blocksize) + 1;	/* first of bitmap blocks */
+
+	/* read true bitmap */
+	SB_AP_BITMAP(s) =
+	    vmalloc(sizeof(struct reiserfs_buffer_info *) * sb_bmap_nr(rs));
+	if (SB_AP_BITMAP(s) == 0)
+		return 1;
+
+	memset(SB_AP_BITMAP(s), 0,
+	       sizeof(struct reiserfs_buffer_info *) * sb_bmap_nr(rs));
+
+	for (i = 0; i < sb_bmap_nr(rs); i++) {
+		SB_AP_BITMAP(s)[i].bh = sb_bread(s, bmp1 + i);
+		if (!SB_AP_BITMAP(s)[i].bh)
+			return 1;
+		load_bitmap_info_data(s, SB_AP_BITMAP(s) + i);
 	}
-    }
-    else
-      /* s_version of standard format may contain incorrect information,
-	 so we just look at the magic string */
-      reiserfs_info (s, "found reiserfs format \"%s\" with standard journal\n",
-	      is_reiserfs_3_5 (rs) ? "3.5" : "3.6");
 
-    s->s_op = &reiserfs_sops;
-    s->s_export_op = &reiserfs_export_ops;
+	return 0;
+}
+
+static int read_super_block(struct super_block *s, int offset)
+{
+	struct buffer_head *bh;
+	struct reiserfs_super_block *rs;
+	int fs_blocksize;
+
+	bh = sb_bread(s, offset / s->s_blocksize);
+	if (!bh) {
+		reiserfs_warning(s, "sh-2006: read_super_block: "
+				 "bread failed (dev %s, block %lu, size %lu)",
+				 reiserfs_bdevname(s), offset / s->s_blocksize,
+				 s->s_blocksize);
+		return 1;
+	}
+
+	rs = (struct reiserfs_super_block *)bh->b_data;
+	if (!is_any_reiserfs_magic_string(rs)) {
+		brelse(bh);
+		return 1;
+	}
+	//
+	// ok, reiserfs signature (old or new) found in at the given offset
+	//    
+	fs_blocksize = sb_blocksize(rs);
+	brelse(bh);
+	sb_set_blocksize(s, fs_blocksize);
+
+	bh = sb_bread(s, offset / s->s_blocksize);
+	if (!bh) {
+		reiserfs_warning(s, "sh-2007: read_super_block: "
+				 "bread failed (dev %s, block %lu, size %lu)\n",
+				 reiserfs_bdevname(s), offset / s->s_blocksize,
+				 s->s_blocksize);
+		return 1;
+	}
+
+	rs = (struct reiserfs_super_block *)bh->b_data;
+	if (sb_blocksize(rs) != s->s_blocksize) {
+		reiserfs_warning(s, "sh-2011: read_super_block: "
+				 "can't find a reiserfs filesystem on (dev %s, block %Lu, size %lu)\n",
+				 reiserfs_bdevname(s),
+				 (unsigned long long)bh->b_blocknr,
+				 s->s_blocksize);
+		brelse(bh);
+		return 1;
+	}
+
+	if (rs->s_v1.s_root_block == cpu_to_le32(-1)) {
+		brelse(bh);
+		reiserfs_warning(s,
+				 "Unfinished reiserfsck --rebuild-tree run detected. Please run\n"
+				 "reiserfsck --rebuild-tree and wait for a completion. If that fails\n"
+				 "get newer reiserfsprogs package");
+		return 1;
+	}
+
+	SB_BUFFER_WITH_SB(s) = bh;
+	SB_DISK_SUPER_BLOCK(s) = rs;
+
+	if (is_reiserfs_jr(rs)) {
+		/* magic is of non-standard journal filesystem, look at s_version to
+		   find which format is in use */
+		if (sb_version(rs) == REISERFS_VERSION_2)
+			reiserfs_warning(s,
+					 "read_super_block: found reiserfs format \"3.6\""
+					 " with non-standard journal");
+		else if (sb_version(rs) == REISERFS_VERSION_1)
+			reiserfs_warning(s,
+					 "read_super_block: found reiserfs format \"3.5\""
+					 " with non-standard journal");
+		else {
+			reiserfs_warning(s,
+					 "sh-2012: read_super_block: found unknown "
+					 "format \"%u\" of reiserfs with non-standard magic",
+					 sb_version(rs));
+			return 1;
+		}
+	} else
+		/* s_version of standard format may contain incorrect information,
+		   so we just look at the magic string */
+		reiserfs_info(s,
+			      "found reiserfs format \"%s\" with standard journal\n",
+			      is_reiserfs_3_5(rs) ? "3.5" : "3.6");
+
+	s->s_op = &reiserfs_sops;
+	s->s_export_op = &reiserfs_export_ops;
 #ifdef CONFIG_QUOTA
-    s->s_qcop = &reiserfs_qctl_operations;
-    s->dq_op = &reiserfs_quota_operations;
+	s->s_qcop = &reiserfs_qctl_operations;
+	s->dq_op = &reiserfs_quota_operations;
 #endif
 
-    /* new format is limited by the 32 bit wide i_blocks field, want to
-    ** be one full block below that.
-    */
-    s->s_maxbytes = (512LL << 32) - s->s_blocksize ;
-    return 0;
+	/* new format is limited by the 32 bit wide i_blocks field, want to
+	 ** be one full block below that.
+	 */
+	s->s_maxbytes = (512LL << 32) - s->s_blocksize;
+	return 0;
 }
 
-
-
 /* after journal replay, reread all bitmap and super blocks */
-static int reread_meta_blocks(struct super_block *s) {
-  int i ;
-  ll_rw_block(READ, 1, &(SB_BUFFER_WITH_SB(s))) ;
-  wait_on_buffer(SB_BUFFER_WITH_SB(s)) ;
-  if (!buffer_uptodate(SB_BUFFER_WITH_SB(s))) {
-    reiserfs_warning (s, "reread_meta_blocks, error reading the super") ;
-    return 1 ;
-  }
-
-  for (i = 0; i < SB_BMAP_NR(s) ; i++) {
-    ll_rw_block(READ, 1, &(SB_AP_BITMAP(s)[i].bh)) ;
-    wait_on_buffer(SB_AP_BITMAP(s)[i].bh) ;
-    if (!buffer_uptodate(SB_AP_BITMAP(s)[i].bh)) {
-      reiserfs_warning (s, "reread_meta_blocks, error reading bitmap block number %d at %llu",
-        i, (unsigned long long)SB_AP_BITMAP(s)[i].bh->b_blocknr) ;
-      return 1 ;
-    }
-  }
-  return 0 ;
+static int reread_meta_blocks(struct super_block *s)
+{
+	int i;
+	ll_rw_block(READ, 1, &(SB_BUFFER_WITH_SB(s)));
+	wait_on_buffer(SB_BUFFER_WITH_SB(s));
+	if (!buffer_uptodate(SB_BUFFER_WITH_SB(s))) {
+		reiserfs_warning(s,
+				 "reread_meta_blocks, error reading the super");
+		return 1;
+	}
+
+	for (i = 0; i < SB_BMAP_NR(s); i++) {
+		ll_rw_block(READ, 1, &(SB_AP_BITMAP(s)[i].bh));
+		wait_on_buffer(SB_AP_BITMAP(s)[i].bh);
+		if (!buffer_uptodate(SB_AP_BITMAP(s)[i].bh)) {
+			reiserfs_warning(s,
+					 "reread_meta_blocks, error reading bitmap block number %d at %llu",
+					 i,
+					 (unsigned long long)SB_AP_BITMAP(s)[i].
+					 bh->b_blocknr);
+			return 1;
+		}
+	}
+	return 0;
 
 }
 
-
 /////////////////////////////////////////////////////
 // hash detection stuff
 
-
 // if root directory is empty - we set default - Yura's - hash and
 // warn about it
 // FIXME: we look for only one name in a directory. If tea and yura
 // bith have the same value - we ask user to send report to the
 // mailing list
-static __u32 find_hash_out (struct super_block * s)
+static __u32 find_hash_out(struct super_block *s)
 {
-    int retval;
-    struct inode * inode;
-    struct cpu_key key;
-    INITIALIZE_PATH (path);
-    struct reiserfs_dir_entry de;
-    __u32 hash = DEFAULT_HASH;
-
-    inode = s->s_root->d_inode;
-
-    do { // Some serious "goto"-hater was there ;)
-	u32 teahash, r5hash, yurahash;
-
-	make_cpu_key (&key, inode, ~0, TYPE_DIRENTRY, 3);
-	retval = search_by_entry_key (s, &key, &path, &de);
-	if (retval == IO_ERROR) {
-	    pathrelse (&path);
-	    return UNSET_HASH ;
-	}
-	if (retval == NAME_NOT_FOUND)
-	    de.de_entry_num --;
-	set_de_name_and_namelen (&de);
-	if (deh_offset( &(de.de_deh[de.de_entry_num]) ) == DOT_DOT_OFFSET) {
-	    /* allow override in this case */
-	    if (reiserfs_rupasov_hash(s)) {
-		hash = YURA_HASH ;
-	    }
-	    reiserfs_warning(s,"FS seems to be empty, autodetect "
-	                     "is using the default hash");
-	    break;
-	}
-	r5hash=GET_HASH_VALUE (r5_hash (de.de_name, de.de_namelen));
-	teahash=GET_HASH_VALUE (keyed_hash (de.de_name, de.de_namelen));
-	yurahash=GET_HASH_VALUE (yura_hash (de.de_name, de.de_namelen));
-	if ( ( (teahash == r5hash) && (GET_HASH_VALUE( deh_offset(&(de.de_deh[de.de_entry_num]))) == r5hash) ) ||
-	     ( (teahash == yurahash) && (yurahash == GET_HASH_VALUE( deh_offset(&(de.de_deh[de.de_entry_num])))) ) ||
-	     ( (r5hash == yurahash) && (yurahash == GET_HASH_VALUE( deh_offset(&(de.de_deh[de.de_entry_num])))) ) ) {
-	    reiserfs_warning(s,"Unable to automatically detect hash function. "
-			     "Please mount with -o hash={tea,rupasov,r5}",
-			     reiserfs_bdevname (s));
-	    hash = UNSET_HASH;
-	    break;
-	}
-	if (GET_HASH_VALUE( deh_offset(&(de.de_deh[de.de_entry_num])) ) == yurahash)
-	    hash = YURA_HASH;
-	else if (GET_HASH_VALUE( deh_offset(&(de.de_deh[de.de_entry_num])) ) == teahash)
-	    hash = TEA_HASH;
-	else if (GET_HASH_VALUE( deh_offset(&(de.de_deh[de.de_entry_num])) ) == r5hash)
-	    hash = R5_HASH;
-	else {
-	    reiserfs_warning (s,"Unrecognised hash function");
-	    hash = UNSET_HASH;
-	}
-    } while (0);
+	int retval;
+	struct inode *inode;
+	struct cpu_key key;
+	INITIALIZE_PATH(path);
+	struct reiserfs_dir_entry de;
+	__u32 hash = DEFAULT_HASH;
+
+	inode = s->s_root->d_inode;
+
+	do {			// Some serious "goto"-hater was there ;)
+		u32 teahash, r5hash, yurahash;
+
+		make_cpu_key(&key, inode, ~0, TYPE_DIRENTRY, 3);
+		retval = search_by_entry_key(s, &key, &path, &de);
+		if (retval == IO_ERROR) {
+			pathrelse(&path);
+			return UNSET_HASH;
+		}
+		if (retval == NAME_NOT_FOUND)
+			de.de_entry_num--;
+		set_de_name_and_namelen(&de);
+		if (deh_offset(&(de.de_deh[de.de_entry_num])) == DOT_DOT_OFFSET) {
+			/* allow override in this case */
+			if (reiserfs_rupasov_hash(s)) {
+				hash = YURA_HASH;
+			}
+			reiserfs_warning(s, "FS seems to be empty, autodetect "
+					 "is using the default hash");
+			break;
+		}
+		r5hash = GET_HASH_VALUE(r5_hash(de.de_name, de.de_namelen));
+		teahash = GET_HASH_VALUE(keyed_hash(de.de_name, de.de_namelen));
+		yurahash = GET_HASH_VALUE(yura_hash(de.de_name, de.de_namelen));
+		if (((teahash == r5hash)
+		     &&
+		     (GET_HASH_VALUE(deh_offset(&(de.de_deh[de.de_entry_num])))
+		      == r5hash)) || ((teahash == yurahash)
+				      && (yurahash ==
+					  GET_HASH_VALUE(deh_offset
+							 (&
+							  (de.
+							   de_deh[de.
+								  de_entry_num])))))
+		    || ((r5hash == yurahash)
+			&& (yurahash ==
+			    GET_HASH_VALUE(deh_offset
+					   (&(de.de_deh[de.de_entry_num])))))) {
+			reiserfs_warning(s,
+					 "Unable to automatically detect hash function. "
+					 "Please mount with -o hash={tea,rupasov,r5}",
+					 reiserfs_bdevname(s));
+			hash = UNSET_HASH;
+			break;
+		}
+		if (GET_HASH_VALUE(deh_offset(&(de.de_deh[de.de_entry_num]))) ==
+		    yurahash)
+			hash = YURA_HASH;
+		else if (GET_HASH_VALUE
+			 (deh_offset(&(de.de_deh[de.de_entry_num]))) == teahash)
+			hash = TEA_HASH;
+		else if (GET_HASH_VALUE
+			 (deh_offset(&(de.de_deh[de.de_entry_num]))) == r5hash)
+			hash = R5_HASH;
+		else {
+			reiserfs_warning(s, "Unrecognised hash function");
+			hash = UNSET_HASH;
+		}
+	} while (0);
 
-    pathrelse (&path);
-    return hash;
+	pathrelse(&path);
+	return hash;
 }
 
 // finds out which hash names are sorted with
-static int what_hash (struct super_block * s)
+static int what_hash(struct super_block *s)
 {
-    __u32 code;
+	__u32 code;
 
-    code = sb_hash_function_code(SB_DISK_SUPER_BLOCK(s));
+	code = sb_hash_function_code(SB_DISK_SUPER_BLOCK(s));
+
+	/* reiserfs_hash_detect() == true if any of the hash mount options
+	 ** were used.  We must check them to make sure the user isn't
+	 ** using a bad hash value
+	 */
+	if (code == UNSET_HASH || reiserfs_hash_detect(s))
+		code = find_hash_out(s);
+
+	if (code != UNSET_HASH && reiserfs_hash_detect(s)) {
+		/* detection has found the hash, and we must check against the 
+		 ** mount options 
+		 */
+		if (reiserfs_rupasov_hash(s) && code != YURA_HASH) {
+			reiserfs_warning(s, "Error, %s hash detected, "
+					 "unable to force rupasov hash",
+					 reiserfs_hashname(code));
+			code = UNSET_HASH;
+		} else if (reiserfs_tea_hash(s) && code != TEA_HASH) {
+			reiserfs_warning(s, "Error, %s hash detected, "
+					 "unable to force tea hash",
+					 reiserfs_hashname(code));
+			code = UNSET_HASH;
+		} else if (reiserfs_r5_hash(s) && code != R5_HASH) {
+			reiserfs_warning(s, "Error, %s hash detected, "
+					 "unable to force r5 hash",
+					 reiserfs_hashname(code));
+			code = UNSET_HASH;
+		}
+	} else {
+		/* find_hash_out was not called or could not determine the hash */
+		if (reiserfs_rupasov_hash(s)) {
+			code = YURA_HASH;
+		} else if (reiserfs_tea_hash(s)) {
+			code = TEA_HASH;
+		} else if (reiserfs_r5_hash(s)) {
+			code = R5_HASH;
+		}
+	}
 
-    /* reiserfs_hash_detect() == true if any of the hash mount options
-    ** were used.  We must check them to make sure the user isn't
-    ** using a bad hash value
-    */
-    if (code == UNSET_HASH || reiserfs_hash_detect(s))
-	code = find_hash_out (s);
-
-    if (code != UNSET_HASH && reiserfs_hash_detect(s)) {
-	/* detection has found the hash, and we must check against the 
-	** mount options 
-	*/
-	if (reiserfs_rupasov_hash(s) && code != YURA_HASH) {
-	    reiserfs_warning (s, "Error, %s hash detected, "
-		   "unable to force rupasov hash", reiserfs_hashname(code)) ;
-	    code = UNSET_HASH ;
-	} else if (reiserfs_tea_hash(s) && code != TEA_HASH) {
-	    reiserfs_warning (s, "Error, %s hash detected, "
-		   "unable to force tea hash", reiserfs_hashname(code)) ;
-	    code = UNSET_HASH ;
-	} else if (reiserfs_r5_hash(s) && code != R5_HASH) {
-	    reiserfs_warning (s, "Error, %s hash detected, "
-		   "unable to force r5 hash", reiserfs_hashname(code)) ;
-	    code = UNSET_HASH ;
-	} 
-    } else { 
-        /* find_hash_out was not called or could not determine the hash */
-	if (reiserfs_rupasov_hash(s)) {
-	    code = YURA_HASH ;
-	} else if (reiserfs_tea_hash(s)) {
-	    code = TEA_HASH ;
-	} else if (reiserfs_r5_hash(s)) {
-	    code = R5_HASH ;
-	} 
-    }
-
-    /* if we are mounted RW, and we have a new valid hash code, update 
-    ** the super
-    */
-    if (code != UNSET_HASH && 
-	!(s->s_flags & MS_RDONLY) && 
-        code != sb_hash_function_code(SB_DISK_SUPER_BLOCK(s))) {
-        set_sb_hash_function_code(SB_DISK_SUPER_BLOCK(s), code);
-    }
-    return code;
+	/* if we are mounted RW, and we have a new valid hash code, update 
+	 ** the super
+	 */
+	if (code != UNSET_HASH &&
+	    !(s->s_flags & MS_RDONLY) &&
+	    code != sb_hash_function_code(SB_DISK_SUPER_BLOCK(s))) {
+		set_sb_hash_function_code(SB_DISK_SUPER_BLOCK(s), code);
+	}
+	return code;
 }
 
 // return pointer to appropriate function
-static hashf_t hash_function (struct super_block * s)
+static hashf_t hash_function(struct super_block *s)
 {
-    switch (what_hash (s)) {
-    case TEA_HASH:
-	reiserfs_info (s, "Using tea hash to sort names\n");
-	return keyed_hash;
-    case YURA_HASH:
-	reiserfs_info (s, "Using rupasov hash to sort names\n");
-	return yura_hash;
-    case R5_HASH:
-	reiserfs_info (s, "Using r5 hash to sort names\n");
-	return r5_hash;
-    }
-    return NULL;
+	switch (what_hash(s)) {
+	case TEA_HASH:
+		reiserfs_info(s, "Using tea hash to sort names\n");
+		return keyed_hash;
+	case YURA_HASH:
+		reiserfs_info(s, "Using rupasov hash to sort names\n");
+		return yura_hash;
+	case R5_HASH:
+		reiserfs_info(s, "Using r5 hash to sort names\n");
+		return r5_hash;
+	}
+	return NULL;
 }
 
 // this is used to set up correct value for old partitions
-static int function2code (hashf_t func)
+static int function2code(hashf_t func)
 {
-    if (func == keyed_hash)
-	return TEA_HASH;
-    if (func == yura_hash)
-	return YURA_HASH;
-    if (func == r5_hash)
-	return R5_HASH;
+	if (func == keyed_hash)
+		return TEA_HASH;
+	if (func == yura_hash)
+		return YURA_HASH;
+	if (func == r5_hash)
+		return R5_HASH;
 
-    BUG() ; // should never happen
+	BUG();			// should never happen
 
-    return 0;
+	return 0;
 }
 
 #define SWARN(silent, s, ...)			\
 	if (!(silent))				\
 		reiserfs_warning (s, __VA_ARGS__)
 
-static int reiserfs_fill_super (struct super_block * s, void * data, int silent)
+static int reiserfs_fill_super(struct super_block *s, void *data, int silent)
 {
-    struct inode *root_inode;
-    int j;
-    struct reiserfs_transaction_handle th ;
-    int old_format = 0;
-    unsigned long blocks;
-    unsigned int commit_max_age = 0;
-    int jinit_done = 0 ;
-    struct reiserfs_iget_args args ;
-    struct reiserfs_super_block * rs;
-    char *jdev_name;
-    struct reiserfs_sb_info *sbi;
-    int errval = -EINVAL;
-
-    sbi = kmalloc(sizeof(struct reiserfs_sb_info), GFP_KERNEL);
-    if (!sbi) {
-	errval = -ENOMEM;
-	goto error;
-    }
-    s->s_fs_info = sbi;
-    memset (sbi, 0, sizeof (struct reiserfs_sb_info));
-    /* Set default values for options: non-aggressive tails, RO on errors */
-    REISERFS_SB(s)->s_mount_opt |= (1 << REISERFS_SMALLTAIL);
-    REISERFS_SB(s)->s_mount_opt |= (1 << REISERFS_ERROR_RO);
-    /* no preallocation minimum, be smart in
-       reiserfs_file_write instead */
-    REISERFS_SB(s)->s_alloc_options.preallocmin = 0;
-    /* Preallocate by 16 blocks (17-1) at once */
-    REISERFS_SB(s)->s_alloc_options.preallocsize = 17;
-    /* Initialize the rwsem for xattr dir */
-    init_rwsem(&REISERFS_SB(s)->xattr_dir_sem);
-
-    /* setup default block allocator options */
-    reiserfs_init_alloc_options(s);
-
-    jdev_name = NULL;
-    if (reiserfs_parse_options (s, (char *) data, &(sbi->s_mount_opt), &blocks, &jdev_name, &commit_max_age) == 0) {
-	goto error;
-    }
-
-    if (blocks) {
-	SWARN (silent, s, "jmacd-7: reiserfs_fill_super: resize option "
-	       "for remount only");
-	goto error;
-    }	
-
-    /* try old format (undistributed bitmap, super block in 8-th 1k block of a device) */
-    if (!read_super_block (s, REISERFS_OLD_DISK_OFFSET_IN_BYTES))
-      old_format = 1;
-    /* try new format (64-th 1k block), which can contain reiserfs super block */
-    else if (read_super_block (s, REISERFS_DISK_OFFSET_IN_BYTES)) {
-      SWARN(silent, s, "sh-2021: reiserfs_fill_super: can not find reiserfs on %s", reiserfs_bdevname (s));
-      goto error;
-    }
-
-    rs = SB_DISK_SUPER_BLOCK (s);
-    /* Let's do basic sanity check to verify that underlying device is not
-       smaller than the filesystem. If the check fails then abort and scream,
-       because bad stuff will happen otherwise. */
-    if ( s->s_bdev && s->s_bdev->bd_inode && i_size_read(s->s_bdev->bd_inode) < sb_block_count(rs)*sb_blocksize(rs)) {
-	SWARN (silent, s, "Filesystem on %s cannot be mounted because it is bigger than the device", reiserfs_bdevname(s));
-	SWARN(silent, s, "You may need to run fsck or increase size of your LVM partition");
-	SWARN(silent, s, "Or may be you forgot to reboot after fdisk when it told you to");
-	goto error;
-    }
-
-    sbi->s_mount_state = SB_REISERFS_STATE(s);
-    sbi->s_mount_state = REISERFS_VALID_FS ;
-
-    if (old_format ? read_old_bitmaps(s) : read_bitmaps(s)) {
-	SWARN(silent, s, "jmacd-8: reiserfs_fill_super: unable to read bitmap");
-	goto error;
-    }
+	struct inode *root_inode;
+	int j;
+	struct reiserfs_transaction_handle th;
+	int old_format = 0;
+	unsigned long blocks;
+	unsigned int commit_max_age = 0;
+	int jinit_done = 0;
+	struct reiserfs_iget_args args;
+	struct reiserfs_super_block *rs;
+	char *jdev_name;
+	struct reiserfs_sb_info *sbi;
+	int errval = -EINVAL;
+
+	sbi = kmalloc(sizeof(struct reiserfs_sb_info), GFP_KERNEL);
+	if (!sbi) {
+		errval = -ENOMEM;
+		goto error;
+	}
+	s->s_fs_info = sbi;
+	memset(sbi, 0, sizeof(struct reiserfs_sb_info));
+	/* Set default values for options: non-aggressive tails, RO on errors */
+	REISERFS_SB(s)->s_mount_opt |= (1 << REISERFS_SMALLTAIL);
+	REISERFS_SB(s)->s_mount_opt |= (1 << REISERFS_ERROR_RO);
+	/* no preallocation minimum, be smart in
+	   reiserfs_file_write instead */
+	REISERFS_SB(s)->s_alloc_options.preallocmin = 0;
+	/* Preallocate by 16 blocks (17-1) at once */
+	REISERFS_SB(s)->s_alloc_options.preallocsize = 17;
+	/* Initialize the rwsem for xattr dir */
+	init_rwsem(&REISERFS_SB(s)->xattr_dir_sem);
+
+	/* setup default block allocator options */
+	reiserfs_init_alloc_options(s);
+
+	jdev_name = NULL;
+	if (reiserfs_parse_options
+	    (s, (char *)data, &(sbi->s_mount_opt), &blocks, &jdev_name,
+	     &commit_max_age) == 0) {
+		goto error;
+	}
+
+	if (blocks) {
+		SWARN(silent, s, "jmacd-7: reiserfs_fill_super: resize option "
+		      "for remount only");
+		goto error;
+	}
+
+	/* try old format (undistributed bitmap, super block in 8-th 1k block of a device) */
+	if (!read_super_block(s, REISERFS_OLD_DISK_OFFSET_IN_BYTES))
+		old_format = 1;
+	/* try new format (64-th 1k block), which can contain reiserfs super block */
+	else if (read_super_block(s, REISERFS_DISK_OFFSET_IN_BYTES)) {
+		SWARN(silent, s,
+		      "sh-2021: reiserfs_fill_super: can not find reiserfs on %s",
+		      reiserfs_bdevname(s));
+		goto error;
+	}
+
+	rs = SB_DISK_SUPER_BLOCK(s);
+	/* Let's do basic sanity check to verify that underlying device is not
+	   smaller than the filesystem. If the check fails then abort and scream,
+	   because bad stuff will happen otherwise. */
+	if (s->s_bdev && s->s_bdev->bd_inode
+	    && i_size_read(s->s_bdev->bd_inode) <
+	    sb_block_count(rs) * sb_blocksize(rs)) {
+		SWARN(silent, s,
+		      "Filesystem on %s cannot be mounted because it is bigger than the device",
+		      reiserfs_bdevname(s));
+		SWARN(silent, s,
+		      "You may need to run fsck or increase size of your LVM partition");
+		SWARN(silent, s,
+		      "Or may be you forgot to reboot after fdisk when it told you to");
+		goto error;
+	}
+
+	sbi->s_mount_state = SB_REISERFS_STATE(s);
+	sbi->s_mount_state = REISERFS_VALID_FS;
+
+	if (old_format ? read_old_bitmaps(s) : read_bitmaps(s)) {
+		SWARN(silent, s,
+		      "jmacd-8: reiserfs_fill_super: unable to read bitmap");
+		goto error;
+	}
 #ifdef CONFIG_REISERFS_CHECK
-    SWARN (silent, s, "CONFIG_REISERFS_CHECK is set ON");
-    SWARN (silent, s, "- it is slow mode for debugging.");
+	SWARN(silent, s, "CONFIG_REISERFS_CHECK is set ON");
+	SWARN(silent, s, "- it is slow mode for debugging.");
 #endif
 
-    /* make data=ordered the default */
-    if (!reiserfs_data_log(s) && !reiserfs_data_ordered(s) &&
-        !reiserfs_data_writeback(s))
-    {
-         REISERFS_SB(s)->s_mount_opt |= (1 << REISERFS_DATA_ORDERED);
-    }
-
-    if (reiserfs_data_log(s)) {
-        reiserfs_info (s, "using journaled data mode\n");
-    } else if (reiserfs_data_ordered(s)) {
-        reiserfs_info (s, "using ordered data mode\n");
-    } else {
-        reiserfs_info (s, "using writeback data mode\n");
-    }
-    if (reiserfs_barrier_flush(s)) {
-    	printk("reiserfs: using flush barriers\n");
-    }
-
-    // set_device_ro(s->s_dev, 1) ;
-    if( journal_init(s, jdev_name, old_format, commit_max_age) ) {
-	SWARN(silent, s, "sh-2022: reiserfs_fill_super: unable to initialize journal space") ;
-	goto error ;
-    } else {
-	jinit_done = 1 ; /* once this is set, journal_release must be called
-			 ** if we error out of the mount
-			 */
-    }
-    if (reread_meta_blocks(s)) {
-	SWARN(silent, s, "jmacd-9: reiserfs_fill_super: unable to reread meta blocks after journal init") ;
-	goto error ;
-    }
-
-    if (replay_only (s))
-	goto error;
-
-    if (bdev_read_only(s->s_bdev) && !(s->s_flags & MS_RDONLY)) {
-        SWARN(silent, s, "clm-7000: Detected readonly device, marking FS readonly") ;
-	s->s_flags |= MS_RDONLY ;
-    }
-    args.objectid = REISERFS_ROOT_OBJECTID ;
-    args.dirid = REISERFS_ROOT_PARENT_OBJECTID ;
-    root_inode = iget5_locked (s, REISERFS_ROOT_OBJECTID, reiserfs_find_actor, reiserfs_init_locked_inode, (void *)(&args));
-    if (!root_inode) {
-	SWARN(silent, s, "jmacd-10: reiserfs_fill_super: get root inode failed");
-	goto error;
-    }
-
-    if (root_inode->i_state & I_NEW) {
-	reiserfs_read_locked_inode(root_inode, &args);
-	unlock_new_inode(root_inode);
-    }
-
-    s->s_root = d_alloc_root(root_inode);  
-    if (!s->s_root) {
-	iput(root_inode);
-	goto error;
-    }
-
-    // define and initialize hash function
-    sbi->s_hash_function = hash_function (s);
-    if (sbi->s_hash_function == NULL) {
-      dput(s->s_root) ;
-      s->s_root = NULL ;
-      goto error ;
-    }
-
-    if (is_reiserfs_3_5 (rs) || (is_reiserfs_jr (rs) && SB_VERSION (s) == REISERFS_VERSION_1))
-	set_bit(REISERFS_3_5, &(sbi->s_properties));
-    else
-	set_bit(REISERFS_3_6, &(sbi->s_properties));
-    
-    if (!(s->s_flags & MS_RDONLY)) {
-
-	errval = journal_begin(&th, s, 1) ;
-        if (errval) {
-	    dput (s->s_root);
-	    s->s_root = NULL;
-	    goto error;
-        }
-	reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1) ;
-
-        set_sb_umount_state( rs, REISERFS_ERROR_FS );
-	set_sb_fs_state (rs, 0);
-	
-	if (old_format_only(s)) {
-	  /* filesystem of format 3.5 either with standard or non-standard
-	     journal */
-	  if (convert_reiserfs (s)) {
-	    /* and -o conv is given */
-	    if(!silent)
-	      reiserfs_info (s,"converting 3.5 filesystem to the 3.6 format") ;
-
-	    if (is_reiserfs_3_5 (rs))
-	      /* put magic string of 3.6 format. 2.2 will not be able to
-		 mount this filesystem anymore */
-	      memcpy (rs->s_v1.s_magic, reiserfs_3_6_magic_string,
-		      sizeof (reiserfs_3_6_magic_string));
-
-	    set_sb_version(rs,REISERFS_VERSION_2);
-	    reiserfs_convert_objectid_map_v1(s) ;
-	    set_bit(REISERFS_3_6, &(sbi->s_properties));
-	    clear_bit(REISERFS_3_5, &(sbi->s_properties));
-	  } else if (!silent){
-	    reiserfs_info (s, "using 3.5.x disk format\n") ;
-	  }
-	}
-
-	journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB (s));
-	errval = journal_end(&th, s, 1) ;
-	if (errval) {
-	    dput (s->s_root);
-	    s->s_root = NULL;
-	    goto error;
-	}
-
-	if ((errval = reiserfs_xattr_init (s, s->s_flags))) {
-	    dput (s->s_root);
-	    s->s_root = NULL;
-	    goto error;
-	}
-
-	/* look for files which were to be removed in previous session */
-	finish_unfinished (s);
-    } else {
-	if ( old_format_only(s) && !silent) {
-	    reiserfs_info (s, "using 3.5.x disk format\n") ;
-	}
-
-	if ((errval = reiserfs_xattr_init (s, s->s_flags))) {
-	    dput (s->s_root);
-	    s->s_root = NULL;
-	    goto error;
-	}
-    }
-    // mark hash in super block: it could be unset. overwrite should be ok
-    set_sb_hash_function_code( rs, function2code(sbi->s_hash_function ) );
-
-    handle_attrs( s );
-
-    reiserfs_proc_info_init( s );
-
-    init_waitqueue_head (&(sbi->s_wait));
-    spin_lock_init(&sbi->bitmap_lock);
-
-    return (0);
-
- error:
-    if (jinit_done) { /* kill the commit thread, free journal ram */
-	journal_release_error(NULL, s) ;
-    }
-    if (SB_DISK_SUPER_BLOCK (s)) {
-	for (j = 0; j < SB_BMAP_NR (s); j ++) {
-	    if (SB_AP_BITMAP (s))
-		brelse (SB_AP_BITMAP (s)[j].bh);
-	}
-	if (SB_AP_BITMAP (s))
-	    vfree (SB_AP_BITMAP (s));
-    }
-    if (SB_BUFFER_WITH_SB (s))
-	brelse(SB_BUFFER_WITH_SB (s));
+	/* make data=ordered the default */
+	if (!reiserfs_data_log(s) && !reiserfs_data_ordered(s) &&
+	    !reiserfs_data_writeback(s)) {
+		REISERFS_SB(s)->s_mount_opt |= (1 << REISERFS_DATA_ORDERED);
+	}
+
+	if (reiserfs_data_log(s)) {
+		reiserfs_info(s, "using journaled data mode\n");
+	} else if (reiserfs_data_ordered(s)) {
+		reiserfs_info(s, "using ordered data mode\n");
+	} else {
+		reiserfs_info(s, "using writeback data mode\n");
+	}
+	if (reiserfs_barrier_flush(s)) {
+		printk("reiserfs: using flush barriers\n");
+	}
+	// set_device_ro(s->s_dev, 1) ;
+	if (journal_init(s, jdev_name, old_format, commit_max_age)) {
+		SWARN(silent, s,
+		      "sh-2022: reiserfs_fill_super: unable to initialize journal space");
+		goto error;
+	} else {
+		jinit_done = 1;	/* once this is set, journal_release must be called
+				 ** if we error out of the mount
+				 */
+	}
+	if (reread_meta_blocks(s)) {
+		SWARN(silent, s,
+		      "jmacd-9: reiserfs_fill_super: unable to reread meta blocks after journal init");
+		goto error;
+	}
+
+	if (replay_only(s))
+		goto error;
+
+	if (bdev_read_only(s->s_bdev) && !(s->s_flags & MS_RDONLY)) {
+		SWARN(silent, s,
+		      "clm-7000: Detected readonly device, marking FS readonly");
+		s->s_flags |= MS_RDONLY;
+	}
+	args.objectid = REISERFS_ROOT_OBJECTID;
+	args.dirid = REISERFS_ROOT_PARENT_OBJECTID;
+	root_inode =
+	    iget5_locked(s, REISERFS_ROOT_OBJECTID, reiserfs_find_actor,
+			 reiserfs_init_locked_inode, (void *)(&args));
+	if (!root_inode) {
+		SWARN(silent, s,
+		      "jmacd-10: reiserfs_fill_super: get root inode failed");
+		goto error;
+	}
+
+	if (root_inode->i_state & I_NEW) {
+		reiserfs_read_locked_inode(root_inode, &args);
+		unlock_new_inode(root_inode);
+	}
+
+	s->s_root = d_alloc_root(root_inode);
+	if (!s->s_root) {
+		iput(root_inode);
+		goto error;
+	}
+	// define and initialize hash function
+	sbi->s_hash_function = hash_function(s);
+	if (sbi->s_hash_function == NULL) {
+		dput(s->s_root);
+		s->s_root = NULL;
+		goto error;
+	}
+
+	if (is_reiserfs_3_5(rs)
+	    || (is_reiserfs_jr(rs) && SB_VERSION(s) == REISERFS_VERSION_1))
+		set_bit(REISERFS_3_5, &(sbi->s_properties));
+	else
+		set_bit(REISERFS_3_6, &(sbi->s_properties));
+
+	if (!(s->s_flags & MS_RDONLY)) {
+
+		errval = journal_begin(&th, s, 1);
+		if (errval) {
+			dput(s->s_root);
+			s->s_root = NULL;
+			goto error;
+		}
+		reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1);
+
+		set_sb_umount_state(rs, REISERFS_ERROR_FS);
+		set_sb_fs_state(rs, 0);
+
+		if (old_format_only(s)) {
+			/* filesystem of format 3.5 either with standard or non-standard
+			   journal */
+			if (convert_reiserfs(s)) {
+				/* and -o conv is given */
+				if (!silent)
+					reiserfs_info(s,
+						      "converting 3.5 filesystem to the 3.6 format");
+
+				if (is_reiserfs_3_5(rs))
+					/* put magic string of 3.6 format. 2.2 will not be able to
+					   mount this filesystem anymore */
+					memcpy(rs->s_v1.s_magic,
+					       reiserfs_3_6_magic_string,
+					       sizeof
+					       (reiserfs_3_6_magic_string));
+
+				set_sb_version(rs, REISERFS_VERSION_2);
+				reiserfs_convert_objectid_map_v1(s);
+				set_bit(REISERFS_3_6, &(sbi->s_properties));
+				clear_bit(REISERFS_3_5, &(sbi->s_properties));
+			} else if (!silent) {
+				reiserfs_info(s, "using 3.5.x disk format\n");
+			}
+		}
+
+		journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB(s));
+		errval = journal_end(&th, s, 1);
+		if (errval) {
+			dput(s->s_root);
+			s->s_root = NULL;
+			goto error;
+		}
+
+		if ((errval = reiserfs_xattr_init(s, s->s_flags))) {
+			dput(s->s_root);
+			s->s_root = NULL;
+			goto error;
+		}
+
+		/* look for files which were to be removed in previous session */
+		finish_unfinished(s);
+	} else {
+		if (old_format_only(s) && !silent) {
+			reiserfs_info(s, "using 3.5.x disk format\n");
+		}
+
+		if ((errval = reiserfs_xattr_init(s, s->s_flags))) {
+			dput(s->s_root);
+			s->s_root = NULL;
+			goto error;
+		}
+	}
+	// mark hash in super block: it could be unset. overwrite should be ok
+	set_sb_hash_function_code(rs, function2code(sbi->s_hash_function));
+
+	handle_attrs(s);
+
+	reiserfs_proc_info_init(s);
+
+	init_waitqueue_head(&(sbi->s_wait));
+	spin_lock_init(&sbi->bitmap_lock);
+
+	return (0);
+
+      error:
+	if (jinit_done) {	/* kill the commit thread, free journal ram */
+		journal_release_error(NULL, s);
+	}
+	if (SB_DISK_SUPER_BLOCK(s)) {
+		for (j = 0; j < SB_BMAP_NR(s); j++) {
+			if (SB_AP_BITMAP(s))
+				brelse(SB_AP_BITMAP(s)[j].bh);
+		}
+		if (SB_AP_BITMAP(s))
+			vfree(SB_AP_BITMAP(s));
+	}
+	if (SB_BUFFER_WITH_SB(s))
+		brelse(SB_BUFFER_WITH_SB(s));
 #ifdef CONFIG_QUOTA
-    for (j = 0; j < MAXQUOTAS; j++) {
-	if (sbi->s_qf_names[j])
-	    kfree(sbi->s_qf_names[j]);
-    }
+	for (j = 0; j < MAXQUOTAS; j++) {
+		if (sbi->s_qf_names[j])
+			kfree(sbi->s_qf_names[j]);
+	}
 #endif
-    if (sbi != NULL) {
-	kfree(sbi);
-    }
-
-    s->s_fs_info = NULL;
-    return errval;
+	if (sbi != NULL) {
+		kfree(sbi);
+	}
+
+	s->s_fs_info = NULL;
+	return errval;
 }
 
+static int reiserfs_statfs(struct super_block *s, struct kstatfs *buf)
+{
+	struct reiserfs_super_block *rs = SB_DISK_SUPER_BLOCK(s);
 
-static int reiserfs_statfs (struct super_block * s, struct kstatfs * buf)
-{
-  struct reiserfs_super_block * rs = SB_DISK_SUPER_BLOCK (s);
-  
-  buf->f_namelen = (REISERFS_MAX_NAME (s->s_blocksize));
-  buf->f_bfree   = sb_free_blocks(rs);
-  buf->f_bavail  = buf->f_bfree;
-  buf->f_blocks  = sb_block_count(rs) - sb_bmap_nr(rs) - 1;
-  buf->f_bsize   = s->s_blocksize;
-  /* changed to accommodate gcc folks.*/
-  buf->f_type    =  REISERFS_SUPER_MAGIC;
-  return 0;
+	buf->f_namelen = (REISERFS_MAX_NAME(s->s_blocksize));
+	buf->f_bfree = sb_free_blocks(rs);
+	buf->f_bavail = buf->f_bfree;
+	buf->f_blocks = sb_block_count(rs) - sb_bmap_nr(rs) - 1;
+	buf->f_bsize = s->s_blocksize;
+	/* changed to accommodate gcc folks. */
+	buf->f_type = REISERFS_SUPER_MAGIC;
+	return 0;
 }
 
 #ifdef CONFIG_QUOTA
 static int reiserfs_dquot_initialize(struct inode *inode, int type)
 {
-    struct reiserfs_transaction_handle th;
-    int ret;
+	struct reiserfs_transaction_handle th;
+	int ret, err;
 
-    /* We may create quota structure so we need to reserve enough blocks */
-    reiserfs_write_lock(inode->i_sb);
-    journal_begin(&th, inode->i_sb, 2*REISERFS_QUOTA_INIT_BLOCKS);
-    ret = dquot_initialize(inode, type);
-    journal_end(&th, inode->i_sb, 2*REISERFS_QUOTA_INIT_BLOCKS);
-    reiserfs_write_unlock(inode->i_sb);
-    return ret;
+	/* We may create quota structure so we need to reserve enough blocks */
+	reiserfs_write_lock(inode->i_sb);
+	ret =
+	    journal_begin(&th, inode->i_sb,
+			  2 * REISERFS_QUOTA_INIT_BLOCKS(inode->i_sb));
+	if (ret)
+		goto out;
+	ret = dquot_initialize(inode, type);
+	err =
+	    journal_end(&th, inode->i_sb,
+			2 * REISERFS_QUOTA_INIT_BLOCKS(inode->i_sb));
+	if (!ret && err)
+		ret = err;
+      out:
+	reiserfs_write_unlock(inode->i_sb);
+	return ret;
 }
 
 static int reiserfs_dquot_drop(struct inode *inode)
 {
-    struct reiserfs_transaction_handle th;
-    int ret;
+	struct reiserfs_transaction_handle th;
+	int ret, err;
 
-    /* We may delete quota structure so we need to reserve enough blocks */
-    reiserfs_write_lock(inode->i_sb);
-    journal_begin(&th, inode->i_sb, 2*REISERFS_QUOTA_INIT_BLOCKS);
-    ret = dquot_drop(inode);
-    journal_end(&th, inode->i_sb, 2*REISERFS_QUOTA_INIT_BLOCKS);
-    reiserfs_write_unlock(inode->i_sb);
-    return ret;
+	/* We may delete quota structure so we need to reserve enough blocks */
+	reiserfs_write_lock(inode->i_sb);
+	ret =
+	    journal_begin(&th, inode->i_sb,
+			  2 * REISERFS_QUOTA_DEL_BLOCKS(inode->i_sb));
+	if (ret)
+		goto out;
+	ret = dquot_drop(inode);
+	err =
+	    journal_end(&th, inode->i_sb,
+			2 * REISERFS_QUOTA_DEL_BLOCKS(inode->i_sb));
+	if (!ret && err)
+		ret = err;
+      out:
+	reiserfs_write_unlock(inode->i_sb);
+	return ret;
 }
 
 static int reiserfs_write_dquot(struct dquot *dquot)
 {
-    struct reiserfs_transaction_handle th;
-    int ret;
+	struct reiserfs_transaction_handle th;
+	int ret, err;
 
-    reiserfs_write_lock(dquot->dq_sb);
-    journal_begin(&th, dquot->dq_sb, REISERFS_QUOTA_TRANS_BLOCKS);
-    ret = dquot_commit(dquot);
-    journal_end(&th, dquot->dq_sb, REISERFS_QUOTA_TRANS_BLOCKS);
-    reiserfs_write_unlock(dquot->dq_sb);
-    return ret;
+	reiserfs_write_lock(dquot->dq_sb);
+	ret =
+	    journal_begin(&th, dquot->dq_sb,
+			  REISERFS_QUOTA_TRANS_BLOCKS(dquot->dq_sb));
+	if (ret)
+		goto out;
+	ret = dquot_commit(dquot);
+	err =
+	    journal_end(&th, dquot->dq_sb,
+			REISERFS_QUOTA_TRANS_BLOCKS(dquot->dq_sb));
+	if (!ret && err)
+		ret = err;
+      out:
+	reiserfs_write_unlock(dquot->dq_sb);
+	return ret;
 }
 
 static int reiserfs_acquire_dquot(struct dquot *dquot)
 {
-    struct reiserfs_transaction_handle th;
-    int ret;
+	struct reiserfs_transaction_handle th;
+	int ret, err;
 
-    reiserfs_write_lock(dquot->dq_sb);
-    journal_begin(&th, dquot->dq_sb, REISERFS_QUOTA_INIT_BLOCKS);
-    ret = dquot_acquire(dquot);
-    journal_end(&th, dquot->dq_sb, REISERFS_QUOTA_INIT_BLOCKS);
-    reiserfs_write_unlock(dquot->dq_sb);
-    return ret;
+	reiserfs_write_lock(dquot->dq_sb);
+	ret =
+	    journal_begin(&th, dquot->dq_sb,
+			  REISERFS_QUOTA_INIT_BLOCKS(dquot->dq_sb));
+	if (ret)
+		goto out;
+	ret = dquot_acquire(dquot);
+	err =
+	    journal_end(&th, dquot->dq_sb,
+			REISERFS_QUOTA_INIT_BLOCKS(dquot->dq_sb));
+	if (!ret && err)
+		ret = err;
+      out:
+	reiserfs_write_unlock(dquot->dq_sb);
+	return ret;
 }
 
 static int reiserfs_release_dquot(struct dquot *dquot)
 {
-    struct reiserfs_transaction_handle th;
-    int ret;
+	struct reiserfs_transaction_handle th;
+	int ret, err;
 
-    reiserfs_write_lock(dquot->dq_sb);
-    journal_begin(&th, dquot->dq_sb, REISERFS_QUOTA_INIT_BLOCKS);
-    ret = dquot_release(dquot);
-    journal_end(&th, dquot->dq_sb, REISERFS_QUOTA_INIT_BLOCKS);
-    reiserfs_write_unlock(dquot->dq_sb);
-    return ret;
+	reiserfs_write_lock(dquot->dq_sb);
+	ret =
+	    journal_begin(&th, dquot->dq_sb,
+			  REISERFS_QUOTA_DEL_BLOCKS(dquot->dq_sb));
+	if (ret)
+		goto out;
+	ret = dquot_release(dquot);
+	err =
+	    journal_end(&th, dquot->dq_sb,
+			REISERFS_QUOTA_DEL_BLOCKS(dquot->dq_sb));
+	if (!ret && err)
+		ret = err;
+      out:
+	reiserfs_write_unlock(dquot->dq_sb);
+	return ret;
 }
 
 static int reiserfs_mark_dquot_dirty(struct dquot *dquot)
 {
-    /* Are we journalling quotas? */
-    if (REISERFS_SB(dquot->dq_sb)->s_qf_names[USRQUOTA] ||
-        REISERFS_SB(dquot->dq_sb)->s_qf_names[GRPQUOTA]) {
-	dquot_mark_dquot_dirty(dquot);
-	return reiserfs_write_dquot(dquot);
-    }
-    else
-	return dquot_mark_dquot_dirty(dquot);
+	/* Are we journalling quotas? */
+	if (REISERFS_SB(dquot->dq_sb)->s_qf_names[USRQUOTA] ||
+	    REISERFS_SB(dquot->dq_sb)->s_qf_names[GRPQUOTA]) {
+		dquot_mark_dquot_dirty(dquot);
+		return reiserfs_write_dquot(dquot);
+	} else
+		return dquot_mark_dquot_dirty(dquot);
 }
 
 static int reiserfs_write_info(struct super_block *sb, int type)
 {
-    struct reiserfs_transaction_handle th;
-    int ret;
+	struct reiserfs_transaction_handle th;
+	int ret, err;
 
-    /* Data block + inode block */
-    reiserfs_write_lock(sb);
-    journal_begin(&th, sb, 2);
-    ret = dquot_commit_info(sb, type);
-    journal_end(&th, sb, 2);
-    reiserfs_write_unlock(sb);
-    return ret;
+	/* Data block + inode block */
+	reiserfs_write_lock(sb);
+	ret = journal_begin(&th, sb, 2);
+	if (ret)
+		goto out;
+	ret = dquot_commit_info(sb, type);
+	err = journal_end(&th, sb, 2);
+	if (!ret && err)
+		ret = err;
+      out:
+	reiserfs_write_unlock(sb);
+	return ret;
 }
 
 /*
- * Turn on quotas during mount time - we need to find
- * the quota file and such...
+ * Turn on quotas during mount time - we need to find the quota file and such...
  */
 static int reiserfs_quota_on_mount(struct super_block *sb, int type)
 {
-    int err;
-    struct dentry *dentry;
-    struct qstr name = { .name = REISERFS_SB(sb)->s_qf_names[type],
-                         .hash = 0,
-                         .len = strlen(REISERFS_SB(sb)->s_qf_names[type])};
-
-    dentry = lookup_hash(&name, sb->s_root);
-    if (IS_ERR(dentry))
-            return PTR_ERR(dentry);
-    err = vfs_quota_on_mount(type, REISERFS_SB(sb)->s_jquota_fmt, dentry);
-    /* Now invalidate and put the dentry - quota got its own reference
-     * to inode and dentry has at least wrong hash so we had better
-     * throw it away */
-    d_invalidate(dentry);
-    dput(dentry);
-    return err;
+	return vfs_quota_on_mount(sb, REISERFS_SB(sb)->s_qf_names[type],
+				  REISERFS_SB(sb)->s_jquota_fmt, type);
 }
 
 /*
  * Standard function to be called on quota_on
  */
-static int reiserfs_quota_on(struct super_block *sb, int type, int format_id, char *path)
+static int reiserfs_quota_on(struct super_block *sb, int type, int format_id,
+			     char *path)
 {
-    int err;
-    struct nameidata nd;
+	int err;
+	struct nameidata nd;
 
-    err = path_lookup(path, LOOKUP_FOLLOW, &nd);
-    if (err)
-        return err;
-    /* Quotafile not on the same filesystem? */
-    if (nd.mnt->mnt_sb != sb) {
-	path_release(&nd);
-        return -EXDEV;
-    }
-    /* We must not pack tails for quota files on reiserfs for quota IO to work */
-    if (!REISERFS_I(nd.dentry->d_inode)->i_flags & i_nopack_mask) {
-	reiserfs_warning(sb, "reiserfs: Quota file must have tail packing disabled.");
-	path_release(&nd);
-	return -EINVAL;
-    }
-    /* Not journalling quota? No more tests needed... */
-    if (!REISERFS_SB(sb)->s_qf_names[USRQUOTA] &&
-        !REISERFS_SB(sb)->s_qf_names[GRPQUOTA]) {
+	if (!(REISERFS_SB(sb)->s_mount_opt & (1 << REISERFS_QUOTA)))
+		return -EINVAL;
+	err = path_lookup(path, LOOKUP_FOLLOW, &nd);
+	if (err)
+		return err;
+	/* Quotafile not on the same filesystem? */
+	if (nd.mnt->mnt_sb != sb) {
+		path_release(&nd);
+		return -EXDEV;
+	}
+	/* We must not pack tails for quota files on reiserfs for quota IO to work */
+	if (!REISERFS_I(nd.dentry->d_inode)->i_flags & i_nopack_mask) {
+		reiserfs_warning(sb,
+				 "reiserfs: Quota file must have tail packing disabled.");
+		path_release(&nd);
+		return -EINVAL;
+	}
+	/* Not journalling quota? No more tests needed... */
+	if (!REISERFS_SB(sb)->s_qf_names[USRQUOTA] &&
+	    !REISERFS_SB(sb)->s_qf_names[GRPQUOTA]) {
+		path_release(&nd);
+		return vfs_quota_on(sb, type, format_id, path);
+	}
+	/* Quotafile not of fs root? */
+	if (nd.dentry->d_parent->d_inode != sb->s_root->d_inode)
+		reiserfs_warning(sb,
+				 "reiserfs: Quota file not on filesystem root. "
+				 "Journalled quota will not work.");
 	path_release(&nd);
-        return vfs_quota_on(sb, type, format_id, path);
-    }
-    /* Quotafile not of fs root? */
-    if (nd.dentry->d_parent->d_inode != sb->s_root->d_inode)
-	reiserfs_warning(sb, "reiserfs: Quota file not on filesystem root. "
-                             "Journalled quota will not work.");
-    path_release(&nd);
-    return vfs_quota_on(sb, type, format_id, path);
+	return vfs_quota_on(sb, type, format_id, path);
 }
 
 /* Read data from quotafile - avoid pagecache and such because we cannot afford
@@ -1998,42 +2167,44 @@ static int reiserfs_quota_on(struct supe
 static ssize_t reiserfs_quota_read(struct super_block *sb, int type, char *data,
 				   size_t len, loff_t off)
 {
-    struct inode *inode = sb_dqopt(sb)->files[type];
-    unsigned long blk = off >> sb->s_blocksize_bits;
-    int err = 0, offset = off & (sb->s_blocksize - 1), tocopy;
-    size_t toread;
-    struct buffer_head tmp_bh, *bh;
-    loff_t i_size = i_size_read(inode);
+	struct inode *inode = sb_dqopt(sb)->files[type];
+	unsigned long blk = off >> sb->s_blocksize_bits;
+	int err = 0, offset = off & (sb->s_blocksize - 1), tocopy;
+	size_t toread;
+	struct buffer_head tmp_bh, *bh;
+	loff_t i_size = i_size_read(inode);
 
-    if (off > i_size)
-	return 0;
-    if (off+len > i_size)
-	len = i_size-off;
-    toread = len;
-    while (toread > 0) {
-	tocopy = sb->s_blocksize - offset < toread ? sb->s_blocksize - offset : toread;
-	tmp_bh.b_state = 0;
-	/* Quota files are without tails so we can safely use this function */
-	reiserfs_write_lock(sb);
-	err = reiserfs_get_block(inode, blk, &tmp_bh, 0);
-	reiserfs_write_unlock(sb);
-	if (err)
-	    return err;
-	if (!buffer_mapped(&tmp_bh))    /* A hole? */
-	    memset(data, 0, tocopy);
-	else {
-	    bh = sb_bread(sb, tmp_bh.b_blocknr);
-	    if (!bh)
-		return -EIO;
-	    memcpy(data, bh->b_data+offset, tocopy);
-	    brelse(bh);
-	}
-	offset = 0;
-	toread -= tocopy;
-	data += tocopy;
-	blk++;
-    }
-    return len;
+	if (off > i_size)
+		return 0;
+	if (off + len > i_size)
+		len = i_size - off;
+	toread = len;
+	while (toread > 0) {
+		tocopy =
+		    sb->s_blocksize - offset <
+		    toread ? sb->s_blocksize - offset : toread;
+		tmp_bh.b_state = 0;
+		/* Quota files are without tails so we can safely use this function */
+		reiserfs_write_lock(sb);
+		err = reiserfs_get_block(inode, blk, &tmp_bh, 0);
+		reiserfs_write_unlock(sb);
+		if (err)
+			return err;
+		if (!buffer_mapped(&tmp_bh))	/* A hole? */
+			memset(data, 0, tocopy);
+		else {
+			bh = sb_bread(sb, tmp_bh.b_blocknr);
+			if (!bh)
+				return -EIO;
+			memcpy(data, bh->b_data + offset, tocopy);
+			brelse(bh);
+		}
+		offset = 0;
+		toread -= tocopy;
+		data += tocopy;
+		blk++;
+	}
+	return len;
 }
 
 /* Write to quotafile (we know the transaction is already started and has
@@ -2041,117 +2212,116 @@ static ssize_t reiserfs_quota_read(struc
 static ssize_t reiserfs_quota_write(struct super_block *sb, int type,
 				    const char *data, size_t len, loff_t off)
 {
-    struct inode *inode = sb_dqopt(sb)->files[type];
-    unsigned long blk = off >> sb->s_blocksize_bits;
-    int err = 0, offset = off & (sb->s_blocksize - 1), tocopy;
-    int journal_quota = REISERFS_SB(sb)->s_qf_names[type] != NULL;
-    size_t towrite = len;
-    struct buffer_head tmp_bh, *bh;
-
-    down(&inode->i_sem);
-    while (towrite > 0) {
-	tocopy = sb->s_blocksize - offset < towrite ?
-	         sb->s_blocksize - offset : towrite;
-	tmp_bh.b_state = 0;
-	err = reiserfs_get_block(inode, blk, &tmp_bh, GET_BLOCK_CREATE);
-	if (err)
-	    goto out;
-	if (offset || tocopy != sb->s_blocksize)
-	    bh = sb_bread(sb, tmp_bh.b_blocknr);
-	else
-	    bh = sb_getblk(sb, tmp_bh.b_blocknr);
-	if (!bh) {
-	    err = -EIO;
-	    goto out;
-	}
-	lock_buffer(bh);
-	memcpy(bh->b_data+offset, data, tocopy);
-	flush_dcache_page(bh->b_page);
-	set_buffer_uptodate(bh);
-	unlock_buffer(bh);
-	reiserfs_prepare_for_journal(sb, bh, 1);
-	journal_mark_dirty(current->journal_info, sb, bh);
-	if (!journal_quota)
-		reiserfs_add_ordered_list(inode, bh);
-	brelse(bh);
-	offset = 0;
-	towrite -= tocopy;
-	data += tocopy;
-	blk++;
-    }
-out:
-    if (len == towrite)
-	return err;
-    if (inode->i_size < off+len-towrite)
-	i_size_write(inode, off+len-towrite);
-    inode->i_version++;
-    inode->i_mtime = inode->i_ctime = CURRENT_TIME;
-    mark_inode_dirty(inode);
-    up(&inode->i_sem);
-    return len - towrite;
+	struct inode *inode = sb_dqopt(sb)->files[type];
+	unsigned long blk = off >> sb->s_blocksize_bits;
+	int err = 0, offset = off & (sb->s_blocksize - 1), tocopy;
+	int journal_quota = REISERFS_SB(sb)->s_qf_names[type] != NULL;
+	size_t towrite = len;
+	struct buffer_head tmp_bh, *bh;
+
+	down(&inode->i_sem);
+	while (towrite > 0) {
+		tocopy = sb->s_blocksize - offset < towrite ?
+		    sb->s_blocksize - offset : towrite;
+		tmp_bh.b_state = 0;
+		err = reiserfs_get_block(inode, blk, &tmp_bh, GET_BLOCK_CREATE);
+		if (err)
+			goto out;
+		if (offset || tocopy != sb->s_blocksize)
+			bh = sb_bread(sb, tmp_bh.b_blocknr);
+		else
+			bh = sb_getblk(sb, tmp_bh.b_blocknr);
+		if (!bh) {
+			err = -EIO;
+			goto out;
+		}
+		lock_buffer(bh);
+		memcpy(bh->b_data + offset, data, tocopy);
+		flush_dcache_page(bh->b_page);
+		set_buffer_uptodate(bh);
+		unlock_buffer(bh);
+		reiserfs_prepare_for_journal(sb, bh, 1);
+		journal_mark_dirty(current->journal_info, sb, bh);
+		if (!journal_quota)
+			reiserfs_add_ordered_list(inode, bh);
+		brelse(bh);
+		offset = 0;
+		towrite -= tocopy;
+		data += tocopy;
+		blk++;
+	}
+      out:
+	if (len == towrite)
+		return err;
+	if (inode->i_size < off + len - towrite)
+		i_size_write(inode, off + len - towrite);
+	inode->i_version++;
+	inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+	mark_inode_dirty(inode);
+	up(&inode->i_sem);
+	return len - towrite;
 }
 
 #endif
 
-static struct super_block*
-get_super_block (struct file_system_type *fs_type, int flags,
-		 const char *dev_name, void *data)
+static struct super_block *get_super_block(struct file_system_type *fs_type,
+					   int flags, const char *dev_name,
+					   void *data)
 {
 	return get_sb_bdev(fs_type, flags, dev_name, data, reiserfs_fill_super);
 }
 
-static int __init
-init_reiserfs_fs ( void )
+static int __init init_reiserfs_fs(void)
 {
 	int ret;
 
-	if ((ret = init_inodecache ())) {
+	if ((ret = init_inodecache())) {
 		return ret;
 	}
 
-        if ((ret = reiserfs_xattr_register_handlers ()))
-            goto failed_reiserfs_xattr_register_handlers;
+	if ((ret = reiserfs_xattr_register_handlers()))
+		goto failed_reiserfs_xattr_register_handlers;
 
-	reiserfs_proc_info_global_init ();
-	reiserfs_proc_register_global ("version", reiserfs_global_version_in_proc);
+	reiserfs_proc_info_global_init();
+	reiserfs_proc_register_global("version",
+				      reiserfs_global_version_in_proc);
 
-        ret = register_filesystem (& reiserfs_fs_type);
+	ret = register_filesystem(&reiserfs_fs_type);
 
 	if (ret == 0) {
 		return 0;
 	}
 
-        reiserfs_xattr_unregister_handlers ();
+	reiserfs_xattr_unregister_handlers();
 
-failed_reiserfs_xattr_register_handlers:
-	reiserfs_proc_unregister_global ("version");
-	reiserfs_proc_info_global_done ();
-	destroy_inodecache ();
+      failed_reiserfs_xattr_register_handlers:
+	reiserfs_proc_unregister_global("version");
+	reiserfs_proc_info_global_done();
+	destroy_inodecache();
 
 	return ret;
 }
 
-static void __exit
-exit_reiserfs_fs ( void )
+static void __exit exit_reiserfs_fs(void)
 {
-        reiserfs_xattr_unregister_handlers ();
-	reiserfs_proc_unregister_global ("version");
-	reiserfs_proc_info_global_done ();
-        unregister_filesystem (& reiserfs_fs_type);
-	destroy_inodecache ();
+	reiserfs_xattr_unregister_handlers();
+	reiserfs_proc_unregister_global("version");
+	reiserfs_proc_info_global_done();
+	unregister_filesystem(&reiserfs_fs_type);
+	destroy_inodecache();
 }
 
 struct file_system_type reiserfs_fs_type = {
-	.owner		= THIS_MODULE,
-	.name		= "reiserfs",
-	.get_sb		= get_super_block,
-	.kill_sb	= kill_block_super,
-	.fs_flags	= FS_REQUIRES_DEV,
+	.owner = THIS_MODULE,
+	.name = "reiserfs",
+	.get_sb = get_super_block,
+	.kill_sb = kill_block_super,
+	.fs_flags = FS_REQUIRES_DEV,
 };
 
-MODULE_DESCRIPTION ("ReiserFS journaled filesystem");
-MODULE_AUTHOR      ("Hans Reiser <reiser@namesys.com>");
-MODULE_LICENSE     ("GPL");
+MODULE_DESCRIPTION("ReiserFS journaled filesystem");
+MODULE_AUTHOR("Hans Reiser <reiser@namesys.com>");
+MODULE_LICENSE("GPL");
 
-module_init (init_reiserfs_fs);
-module_exit (exit_reiserfs_fs);
+module_init(init_reiserfs_fs);
+module_exit(exit_reiserfs_fs);
diff --git a/fs/reiserfs/tail_conversion.c b/fs/reiserfs/tail_conversion.c
--- a/fs/reiserfs/tail_conversion.c
+++ b/fs/reiserfs/tail_conversion.c
@@ -11,156 +11,159 @@
 /* access to tail : when one is going to read tail it must make sure, that is not running.
  direct2indirect and indirect2direct can not run concurrently */
 
-
 /* Converts direct items to an unformatted node. Panics if file has no
    tail. -ENOSPC if no disk space for conversion */
 /* path points to first direct item of the file regarless of how many of
    them are there */
-int direct2indirect (struct reiserfs_transaction_handle *th, struct inode * inode, 
-		     struct path * path, struct buffer_head * unbh,
-		     loff_t tail_offset)
+int direct2indirect(struct reiserfs_transaction_handle *th, struct inode *inode,
+		    struct path *path, struct buffer_head *unbh,
+		    loff_t tail_offset)
 {
-    struct super_block * sb = inode->i_sb;
-    struct buffer_head *up_to_date_bh ;
-    struct item_head * p_le_ih = PATH_PITEM_HEAD (path);
-    unsigned long total_tail = 0 ;
-    struct cpu_key end_key;  /* Key to search for the last byte of the
-				converted item. */
-    struct item_head ind_ih; /* new indirect item to be inserted or
-                                key of unfm pointer to be pasted */
-    int	n_blk_size,
-      n_retval;	  /* returned value for reiserfs_insert_item and clones */
-    unp_t unfm_ptr;  /* Handle on an unformatted node
-				       that will be inserted in the
-				       tree. */
-
-    BUG_ON (!th->t_trans_id);
-
-    REISERFS_SB(sb)->s_direct2indirect ++;
-
-    n_blk_size = sb->s_blocksize;
-
-    /* and key to search for append or insert pointer to the new
-       unformatted node. */
-    copy_item_head (&ind_ih, p_le_ih);
-    set_le_ih_k_offset (&ind_ih, tail_offset);
-    set_le_ih_k_type (&ind_ih, TYPE_INDIRECT);
-
-    /* Set the key to search for the place for new unfm pointer */
-    make_cpu_key (&end_key, inode, tail_offset, TYPE_INDIRECT, 4);
-
-    // FIXME: we could avoid this 
-    if ( search_for_position_by_key (sb, &end_key, path) == POSITION_FOUND ) {
-	reiserfs_warning (sb, "PAP-14030: direct2indirect: "
-			"pasted or inserted byte exists in the tree %K. "
-			"Use fsck to repair.", &end_key);
-	pathrelse(path);
-	return -EIO;
-    }
-    
-    p_le_ih = PATH_PITEM_HEAD (path);
-
-    unfm_ptr = cpu_to_le32 (unbh->b_blocknr);
-    
-    if ( is_statdata_le_ih (p_le_ih) )  {
-	/* Insert new indirect item. */
-	set_ih_free_space (&ind_ih, 0); /* delete at nearest future */
-        put_ih_item_len( &ind_ih, UNFM_P_SIZE );
-	PATH_LAST_POSITION (path)++;
-	n_retval = reiserfs_insert_item (th, path, &end_key, &ind_ih, inode,
+	struct super_block *sb = inode->i_sb;
+	struct buffer_head *up_to_date_bh;
+	struct item_head *p_le_ih = PATH_PITEM_HEAD(path);
+	unsigned long total_tail = 0;
+	struct cpu_key end_key;	/* Key to search for the last byte of the
+				   converted item. */
+	struct item_head ind_ih;	/* new indirect item to be inserted or
+					   key of unfm pointer to be pasted */
+	int n_blk_size, n_retval;	/* returned value for reiserfs_insert_item and clones */
+	unp_t unfm_ptr;		/* Handle on an unformatted node
+				   that will be inserted in the
+				   tree. */
+
+	BUG_ON(!th->t_trans_id);
+
+	REISERFS_SB(sb)->s_direct2indirect++;
+
+	n_blk_size = sb->s_blocksize;
+
+	/* and key to search for append or insert pointer to the new
+	   unformatted node. */
+	copy_item_head(&ind_ih, p_le_ih);
+	set_le_ih_k_offset(&ind_ih, tail_offset);
+	set_le_ih_k_type(&ind_ih, TYPE_INDIRECT);
+
+	/* Set the key to search for the place for new unfm pointer */
+	make_cpu_key(&end_key, inode, tail_offset, TYPE_INDIRECT, 4);
+
+	// FIXME: we could avoid this 
+	if (search_for_position_by_key(sb, &end_key, path) == POSITION_FOUND) {
+		reiserfs_warning(sb, "PAP-14030: direct2indirect: "
+				 "pasted or inserted byte exists in the tree %K. "
+				 "Use fsck to repair.", &end_key);
+		pathrelse(path);
+		return -EIO;
+	}
+
+	p_le_ih = PATH_PITEM_HEAD(path);
+
+	unfm_ptr = cpu_to_le32(unbh->b_blocknr);
+
+	if (is_statdata_le_ih(p_le_ih)) {
+		/* Insert new indirect item. */
+		set_ih_free_space(&ind_ih, 0);	/* delete at nearest future */
+		put_ih_item_len(&ind_ih, UNFM_P_SIZE);
+		PATH_LAST_POSITION(path)++;
+		n_retval =
+		    reiserfs_insert_item(th, path, &end_key, &ind_ih, inode,
 					 (char *)&unfm_ptr);
-    } else {
-	/* Paste into last indirect item of an object. */
-	n_retval = reiserfs_paste_into_item(th, path, &end_key, inode,
-					    (char *)&unfm_ptr, UNFM_P_SIZE);
-    }
-    if ( n_retval ) {
-	return n_retval;
-    }
-
-    // note: from here there are two keys which have matching first
-    // three key components. They only differ by the fourth one.
-
-
-    /* Set the key to search for the direct items of the file */
-    make_cpu_key (&end_key, inode, max_reiserfs_offset (inode), TYPE_DIRECT, 4);
-
-    /* Move bytes from the direct items to the new unformatted node
-       and delete them. */
-    while (1)  {
-	int tail_size;
-
-	/* end_key.k_offset is set so, that we will always have found
-           last item of the file */
-	if ( search_for_position_by_key (sb, &end_key, path) == POSITION_FOUND )
-	    reiserfs_panic (sb, "PAP-14050: direct2indirect: "
-			    "direct item (%K) not found", &end_key);
-	p_le_ih = PATH_PITEM_HEAD (path);
-	RFALSE( !is_direct_le_ih (p_le_ih),
-	        "vs-14055: direct item expected(%K), found %h",
-                &end_key, p_le_ih);
-        tail_size = (le_ih_k_offset (p_le_ih) & (n_blk_size - 1))
-            + ih_item_len(p_le_ih) - 1;
-
-	/* we only send the unbh pointer if the buffer is not up to date.
-	** this avoids overwriting good data from writepage() with old data
-	** from the disk or buffer cache
-	** Special case: unbh->b_page will be NULL if we are coming through
-	** DIRECT_IO handler here.
-	*/
-	if (!unbh->b_page || buffer_uptodate(unbh) || PageUptodate(unbh->b_page)) {
-	    up_to_date_bh = NULL ;
 	} else {
-	    up_to_date_bh = unbh ;
+		/* Paste into last indirect item of an object. */
+		n_retval = reiserfs_paste_into_item(th, path, &end_key, inode,
+						    (char *)&unfm_ptr,
+						    UNFM_P_SIZE);
+	}
+	if (n_retval) {
+		return n_retval;
 	}
-	n_retval = reiserfs_delete_item (th, path, &end_key, inode, 
-	                                 up_to_date_bh) ;
+	// note: from here there are two keys which have matching first
+	// three key components. They only differ by the fourth one.
 
-	total_tail += n_retval ;
-	if (tail_size == n_retval)
-	    // done: file does not have direct items anymore
-	    break;
-
-    }
-    /* if we've copied bytes from disk into the page, we need to zero
-    ** out the unused part of the block (it was not up to date before)
-    */
-    if (up_to_date_bh) {
-        unsigned pgoff = (tail_offset + total_tail - 1) & (PAGE_CACHE_SIZE - 1);
-	char *kaddr=kmap_atomic(up_to_date_bh->b_page, KM_USER0);
-	memset(kaddr + pgoff, 0, n_blk_size - total_tail) ;
-	kunmap_atomic(kaddr, KM_USER0);
-    }
+	/* Set the key to search for the direct items of the file */
+	make_cpu_key(&end_key, inode, max_reiserfs_offset(inode), TYPE_DIRECT,
+		     4);
+
+	/* Move bytes from the direct items to the new unformatted node
+	   and delete them. */
+	while (1) {
+		int tail_size;
+
+		/* end_key.k_offset is set so, that we will always have found
+		   last item of the file */
+		if (search_for_position_by_key(sb, &end_key, path) ==
+		    POSITION_FOUND)
+			reiserfs_panic(sb,
+				       "PAP-14050: direct2indirect: "
+				       "direct item (%K) not found", &end_key);
+		p_le_ih = PATH_PITEM_HEAD(path);
+		RFALSE(!is_direct_le_ih(p_le_ih),
+		       "vs-14055: direct item expected(%K), found %h",
+		       &end_key, p_le_ih);
+		tail_size = (le_ih_k_offset(p_le_ih) & (n_blk_size - 1))
+		    + ih_item_len(p_le_ih) - 1;
+
+		/* we only send the unbh pointer if the buffer is not up to date.
+		 ** this avoids overwriting good data from writepage() with old data
+		 ** from the disk or buffer cache
+		 ** Special case: unbh->b_page will be NULL if we are coming through
+		 ** DIRECT_IO handler here.
+		 */
+		if (!unbh->b_page || buffer_uptodate(unbh)
+		    || PageUptodate(unbh->b_page)) {
+			up_to_date_bh = NULL;
+		} else {
+			up_to_date_bh = unbh;
+		}
+		n_retval = reiserfs_delete_item(th, path, &end_key, inode,
+						up_to_date_bh);
+
+		total_tail += n_retval;
+		if (tail_size == n_retval)
+			// done: file does not have direct items anymore
+			break;
 
-    REISERFS_I(inode)->i_first_direct_byte = U32_MAX;
+	}
+	/* if we've copied bytes from disk into the page, we need to zero
+	 ** out the unused part of the block (it was not up to date before)
+	 */
+	if (up_to_date_bh) {
+		unsigned pgoff =
+		    (tail_offset + total_tail - 1) & (PAGE_CACHE_SIZE - 1);
+		char *kaddr = kmap_atomic(up_to_date_bh->b_page, KM_USER0);
+		memset(kaddr + pgoff, 0, n_blk_size - total_tail);
+		kunmap_atomic(kaddr, KM_USER0);
+	}
 
-    return 0;
-}
+	REISERFS_I(inode)->i_first_direct_byte = U32_MAX;
 
+	return 0;
+}
 
 /* stolen from fs/buffer.c */
-void reiserfs_unmap_buffer(struct buffer_head *bh) {
-    lock_buffer(bh) ;
-    if (buffer_journaled(bh) || buffer_journal_dirty(bh)) {
-      BUG() ;
-    }
-    clear_buffer_dirty(bh) ;
-    /* Remove the buffer from whatever list it belongs to. We are mostly
-       interested in removing it from per-sb j_dirty_buffers list, to avoid
-        BUG() on attempt to write not mapped buffer */
-    if ( (!list_empty(&bh->b_assoc_buffers) || bh->b_private) && bh->b_page) {
-	struct inode *inode = bh->b_page->mapping->host;
-	struct reiserfs_journal *j = SB_JOURNAL(inode->i_sb);
-	spin_lock(&j->j_dirty_buffers_lock);
-	list_del_init(&bh->b_assoc_buffers);
-	reiserfs_free_jh(bh);
-	spin_unlock(&j->j_dirty_buffers_lock);
-    }
-    clear_buffer_mapped(bh) ;
-    clear_buffer_req(bh) ;
-    clear_buffer_new(bh);
-    bh->b_bdev = NULL;
-    unlock_buffer(bh) ;
+void reiserfs_unmap_buffer(struct buffer_head *bh)
+{
+	lock_buffer(bh);
+	if (buffer_journaled(bh) || buffer_journal_dirty(bh)) {
+		BUG();
+	}
+	clear_buffer_dirty(bh);
+	/* Remove the buffer from whatever list it belongs to. We are mostly
+	   interested in removing it from per-sb j_dirty_buffers list, to avoid
+	   BUG() on attempt to write not mapped buffer */
+	if ((!list_empty(&bh->b_assoc_buffers) || bh->b_private) && bh->b_page) {
+		struct inode *inode = bh->b_page->mapping->host;
+		struct reiserfs_journal *j = SB_JOURNAL(inode->i_sb);
+		spin_lock(&j->j_dirty_buffers_lock);
+		list_del_init(&bh->b_assoc_buffers);
+		reiserfs_free_jh(bh);
+		spin_unlock(&j->j_dirty_buffers_lock);
+	}
+	clear_buffer_mapped(bh);
+	clear_buffer_req(bh);
+	clear_buffer_new(bh);
+	bh->b_bdev = NULL;
+	unlock_buffer(bh);
 }
 
 /* this first locks inode (neither reads nor sync are permitted),
@@ -169,108 +172,108 @@ void reiserfs_unmap_buffer(struct buffer
    what we expect from it (number of cut bytes). But when tail remains
    in the unformatted node, we set mode to SKIP_BALANCING and unlock
    inode */
-int indirect2direct (struct reiserfs_transaction_handle *th, 
-		     struct inode * p_s_inode,
-		     struct page *page, 
-		     struct path * p_s_path, /* path to the indirect item. */
-		     const struct cpu_key * p_s_item_key, /* Key to look for unformatted node pointer to be cut. */
-		     loff_t n_new_file_size, /* New file size. */
-		     char * p_c_mode)
+int indirect2direct(struct reiserfs_transaction_handle *th, struct inode *p_s_inode, struct page *page, struct path *p_s_path,	/* path to the indirect item. */
+		    const struct cpu_key *p_s_item_key,	/* Key to look for unformatted node pointer to be cut. */
+		    loff_t n_new_file_size,	/* New file size. */
+		    char *p_c_mode)
 {
-    struct super_block * p_s_sb = p_s_inode->i_sb;
-    struct item_head      s_ih;
-    unsigned long n_block_size = p_s_sb->s_blocksize;
-    char * tail;
-    int tail_len, round_tail_len;
-    loff_t pos, pos1; /* position of first byte of the tail */
-    struct cpu_key key;
-
-    BUG_ON (!th->t_trans_id);
-
-    REISERFS_SB(p_s_sb)->s_indirect2direct ++;
-
-    *p_c_mode = M_SKIP_BALANCING;
-
-    /* store item head path points to. */
-    copy_item_head (&s_ih, PATH_PITEM_HEAD(p_s_path));
-
-    tail_len = (n_new_file_size & (n_block_size - 1));
-    if (get_inode_sd_version (p_s_inode) == STAT_DATA_V2)
-	round_tail_len = ROUND_UP (tail_len);
-    else
-	round_tail_len = tail_len;
-
-    pos = le_ih_k_offset (&s_ih) - 1 + (ih_item_len(&s_ih) / UNFM_P_SIZE - 1) * p_s_sb->s_blocksize;
-    pos1 = pos;
-
-    // we are protected by i_sem. The tail can not disapper, not
-    // append can be done either
-    // we are in truncate or packing tail in file_release
-
-    tail = (char *)kmap(page) ; /* this can schedule */
-
-    if (path_changed (&s_ih, p_s_path)) {
-	/* re-search indirect item */
-	if ( search_for_position_by_key (p_s_sb, p_s_item_key, p_s_path) == POSITION_NOT_FOUND )
-	    reiserfs_panic(p_s_sb, "PAP-5520: indirect2direct: "
-			   "item to be converted %K does not exist", p_s_item_key);
-	copy_item_head(&s_ih, PATH_PITEM_HEAD(p_s_path));
-#ifdef CONFIG_REISERFS_CHECK
-	pos = le_ih_k_offset (&s_ih) - 1 + 
-	    (ih_item_len(&s_ih) / UNFM_P_SIZE - 1) * p_s_sb->s_blocksize;
-	if (pos != pos1)
-	    reiserfs_panic (p_s_sb, "vs-5530: indirect2direct: "
-			    "tail position changed while we were reading it");
-#endif
-    }
+	struct super_block *p_s_sb = p_s_inode->i_sb;
+	struct item_head s_ih;
+	unsigned long n_block_size = p_s_sb->s_blocksize;
+	char *tail;
+	int tail_len, round_tail_len;
+	loff_t pos, pos1;	/* position of first byte of the tail */
+	struct cpu_key key;
 
+	BUG_ON(!th->t_trans_id);
 
-    /* Set direct item header to insert. */
-    make_le_item_head (&s_ih, NULL, get_inode_item_key_version (p_s_inode), pos1 + 1,
-		       TYPE_DIRECT, round_tail_len, 0xffff/*ih_free_space*/);
-
-    /* we want a pointer to the first byte of the tail in the page.
-    ** the page was locked and this part of the page was up to date when
-    ** indirect2direct was called, so we know the bytes are still valid
-    */
-    tail = tail + (pos & (PAGE_CACHE_SIZE - 1)) ;
-
-    PATH_LAST_POSITION(p_s_path)++;
-
-    key = *p_s_item_key;
-    set_cpu_key_k_type (&key, TYPE_DIRECT);
-    key.key_length = 4;
-    /* Insert tail as new direct item in the tree */
-    if ( reiserfs_insert_item(th, p_s_path, &key, &s_ih, p_s_inode,
-			      tail ? tail : NULL) < 0 ) {
-	/* No disk memory. So we can not convert last unformatted node
-	   to the direct item.  In this case we used to adjust
-	   indirect items's ih_free_space. Now ih_free_space is not
-	   used, it would be ideal to write zeros to corresponding
-	   unformatted node. For now i_size is considered as guard for
-	   going out of file size */
-	kunmap(page) ;
-	return n_block_size - round_tail_len;
-    }
-    kunmap(page) ;
+	REISERFS_SB(p_s_sb)->s_indirect2direct++;
 
-    /* make sure to get the i_blocks changes from reiserfs_insert_item */
-    reiserfs_update_sd(th, p_s_inode);
+	*p_c_mode = M_SKIP_BALANCING;
 
-    // note: we have now the same as in above direct2indirect
-    // conversion: there are two keys which have matching first three
-    // key components. They only differ by the fouhth one.
-
-    /* We have inserted new direct item and must remove last
-       unformatted node. */
-    *p_c_mode = M_CUT;
+	/* store item head path points to. */
+	copy_item_head(&s_ih, PATH_PITEM_HEAD(p_s_path));
 
-    /* we store position of first direct item in the in-core inode */
-    //mark_file_with_tail (p_s_inode, pos1 + 1);
-    REISERFS_I(p_s_inode)->i_first_direct_byte = pos1 + 1;
+	tail_len = (n_new_file_size & (n_block_size - 1));
+	if (get_inode_sd_version(p_s_inode) == STAT_DATA_V2)
+		round_tail_len = ROUND_UP(tail_len);
+	else
+		round_tail_len = tail_len;
+
+	pos =
+	    le_ih_k_offset(&s_ih) - 1 + (ih_item_len(&s_ih) / UNFM_P_SIZE -
+					 1) * p_s_sb->s_blocksize;
+	pos1 = pos;
+
+	// we are protected by i_sem. The tail can not disapper, not
+	// append can be done either
+	// we are in truncate or packing tail in file_release
+
+	tail = (char *)kmap(page);	/* this can schedule */
+
+	if (path_changed(&s_ih, p_s_path)) {
+		/* re-search indirect item */
+		if (search_for_position_by_key(p_s_sb, p_s_item_key, p_s_path)
+		    == POSITION_NOT_FOUND)
+			reiserfs_panic(p_s_sb,
+				       "PAP-5520: indirect2direct: "
+				       "item to be converted %K does not exist",
+				       p_s_item_key);
+		copy_item_head(&s_ih, PATH_PITEM_HEAD(p_s_path));
+#ifdef CONFIG_REISERFS_CHECK
+		pos = le_ih_k_offset(&s_ih) - 1 +
+		    (ih_item_len(&s_ih) / UNFM_P_SIZE -
+		     1) * p_s_sb->s_blocksize;
+		if (pos != pos1)
+			reiserfs_panic(p_s_sb, "vs-5530: indirect2direct: "
+				       "tail position changed while we were reading it");
+#endif
+	}
 
-    return n_block_size - round_tail_len;
-}
+	/* Set direct item header to insert. */
+	make_le_item_head(&s_ih, NULL, get_inode_item_key_version(p_s_inode),
+			  pos1 + 1, TYPE_DIRECT, round_tail_len,
+			  0xffff /*ih_free_space */ );
+
+	/* we want a pointer to the first byte of the tail in the page.
+	 ** the page was locked and this part of the page was up to date when
+	 ** indirect2direct was called, so we know the bytes are still valid
+	 */
+	tail = tail + (pos & (PAGE_CACHE_SIZE - 1));
+
+	PATH_LAST_POSITION(p_s_path)++;
+
+	key = *p_s_item_key;
+	set_cpu_key_k_type(&key, TYPE_DIRECT);
+	key.key_length = 4;
+	/* Insert tail as new direct item in the tree */
+	if (reiserfs_insert_item(th, p_s_path, &key, &s_ih, p_s_inode,
+				 tail ? tail : NULL) < 0) {
+		/* No disk memory. So we can not convert last unformatted node
+		   to the direct item.  In this case we used to adjust
+		   indirect items's ih_free_space. Now ih_free_space is not
+		   used, it would be ideal to write zeros to corresponding
+		   unformatted node. For now i_size is considered as guard for
+		   going out of file size */
+		kunmap(page);
+		return n_block_size - round_tail_len;
+	}
+	kunmap(page);
 
+	/* make sure to get the i_blocks changes from reiserfs_insert_item */
+	reiserfs_update_sd(th, p_s_inode);
 
+	// note: we have now the same as in above direct2indirect
+	// conversion: there are two keys which have matching first three
+	// key components. They only differ by the fouhth one.
+
+	/* We have inserted new direct item and must remove last
+	   unformatted node. */
+	*p_c_mode = M_CUT;
+
+	/* we store position of first direct item in the in-core inode */
+	//mark_file_with_tail (p_s_inode, pos1 + 1);
+	REISERFS_I(p_s_inode)->i_first_direct_byte = pos1 + 1;
 
+	return n_block_size - round_tail_len;
+}
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c
--- a/fs/reiserfs/xattr.c
+++ b/fs/reiserfs/xattr.c
@@ -39,7 +39,6 @@
 #include <linux/xattr.h>
 #include <linux/reiserfs_xattr.h>
 #include <linux/reiserfs_acl.h>
-#include <linux/mbcache.h>
 #include <asm/uaccess.h>
 #include <asm/checksum.h>
 #include <linux/smp_lock.h>
@@ -51,67 +50,68 @@
 #define PRIVROOT_NAME ".reiserfs_priv"
 #define XAROOT_NAME   "xattrs"
 
-static struct reiserfs_xattr_handler *find_xattr_handler_prefix (const char *prefix);
+static struct reiserfs_xattr_handler *find_xattr_handler_prefix(const char
+								*prefix);
 
-static struct dentry *
-create_xa_root (struct super_block *sb)
+static struct dentry *create_xa_root(struct super_block *sb)
 {
-    struct dentry *privroot = dget (REISERFS_SB(sb)->priv_root);
-    struct dentry *xaroot;
+	struct dentry *privroot = dget(REISERFS_SB(sb)->priv_root);
+	struct dentry *xaroot;
 
-    /* This needs to be created at mount-time */
-    if (!privroot)
-        return ERR_PTR(-EOPNOTSUPP);
-
-    xaroot = lookup_one_len (XAROOT_NAME, privroot, strlen (XAROOT_NAME));
-    if (IS_ERR (xaroot)) {
-        goto out;
-    } else if (!xaroot->d_inode) {
-        int err;
-        down (&privroot->d_inode->i_sem);
-        err = privroot->d_inode->i_op->mkdir (privroot->d_inode, xaroot, 0700);
-        up (&privroot->d_inode->i_sem);
-
-        if (err) {
-            dput (xaroot);
-            dput (privroot);
-            return ERR_PTR (err);
-        }
-        REISERFS_SB(sb)->xattr_root = dget (xaroot);
-    }
-
-out:
-    dput (privroot);
-    return xaroot;
+	/* This needs to be created at mount-time */
+	if (!privroot)
+		return ERR_PTR(-EOPNOTSUPP);
+
+	xaroot = lookup_one_len(XAROOT_NAME, privroot, strlen(XAROOT_NAME));
+	if (IS_ERR(xaroot)) {
+		goto out;
+	} else if (!xaroot->d_inode) {
+		int err;
+		down(&privroot->d_inode->i_sem);
+		err =
+		    privroot->d_inode->i_op->mkdir(privroot->d_inode, xaroot,
+						   0700);
+		up(&privroot->d_inode->i_sem);
+
+		if (err) {
+			dput(xaroot);
+			dput(privroot);
+			return ERR_PTR(err);
+		}
+		REISERFS_SB(sb)->xattr_root = dget(xaroot);
+	}
+
+      out:
+	dput(privroot);
+	return xaroot;
 }
 
 /* This will return a dentry, or error, refering to the xa root directory.
  * If the xa root doesn't exist yet, the dentry will be returned without
  * an associated inode. This dentry can be used with ->mkdir to create
  * the xa directory. */
-static struct dentry *
-__get_xa_root (struct super_block *s)
+static struct dentry *__get_xa_root(struct super_block *s)
 {
-    struct dentry *privroot = dget (REISERFS_SB(s)->priv_root);
-    struct dentry *xaroot = NULL;
+	struct dentry *privroot = dget(REISERFS_SB(s)->priv_root);
+	struct dentry *xaroot = NULL;
+
+	if (IS_ERR(privroot) || !privroot)
+		return privroot;
+
+	xaroot = lookup_one_len(XAROOT_NAME, privroot, strlen(XAROOT_NAME));
+	if (IS_ERR(xaroot)) {
+		goto out;
+	} else if (!xaroot->d_inode) {
+		dput(xaroot);
+		xaroot = NULL;
+		goto out;
+	}
 
-    if (IS_ERR (privroot) || !privroot)
-        return privroot;
+	REISERFS_SB(s)->xattr_root = dget(xaroot);
 
-    xaroot = lookup_one_len (XAROOT_NAME, privroot, strlen (XAROOT_NAME));
-    if (IS_ERR (xaroot)) {
-        goto out;
-    } else if (!xaroot->d_inode) {
-        dput (xaroot);
-        xaroot = NULL;
-        goto out;
-    }
-
-    REISERFS_SB(s)->xattr_root = dget (xaroot);
-
-out:
-    dput (privroot);
-    return xaroot;
+      out:
+	dput(privroot);
+	return xaroot;
 }
 
 /* Returns the dentry (or NULL) referring to the root of the extended
@@ -119,147 +119,145 @@ out:
  * Otherwise, we attempt to retreive it from disk. It may also return
  * a pointer-encoded error.
  */
-static inline struct dentry *
-get_xa_root (struct super_block *s)
+static inline struct dentry *get_xa_root(struct super_block *s)
 {
-    struct dentry *dentry = dget (REISERFS_SB(s)->xattr_root);
+	struct dentry *dentry = dget(REISERFS_SB(s)->xattr_root);
 
-    if (!dentry)
-        dentry = __get_xa_root (s);
+	if (!dentry)
+		dentry = __get_xa_root(s);
 
-    return dentry;
+	return dentry;
 }
 
 /* Opens the directory corresponding to the inode's extended attribute store.
  * If flags allow, the tree to the directory may be created. If creation is
  * prohibited, -ENODATA is returned. */
-static struct dentry *
-open_xa_dir (const struct inode *inode, int flags)
+static struct dentry *open_xa_dir(const struct inode *inode, int flags)
 {
-    struct dentry *xaroot, *xadir;
-    char namebuf[17];
+	struct dentry *xaroot, *xadir;
+	char namebuf[17];
 
-    xaroot = get_xa_root (inode->i_sb);
-    if (IS_ERR (xaroot)) {
-        return xaroot;
-    } else if (!xaroot) {
-        if (flags == 0 || flags & XATTR_CREATE) {
-            xaroot = create_xa_root (inode->i_sb);
-            if (IS_ERR (xaroot))
-                return xaroot;
-        }
-        if (!xaroot)
-            return ERR_PTR (-ENODATA);
-    }
-
-    /* ok, we have xaroot open */
-
-    snprintf (namebuf, sizeof (namebuf), "%X.%X",
-              le32_to_cpu (INODE_PKEY (inode)->k_objectid),
-              inode->i_generation);
-    xadir = lookup_one_len (namebuf, xaroot, strlen (namebuf));
-    if (IS_ERR (xadir)) {
-        dput (xaroot);
-        return xadir;
-    }
-
-    if (!xadir->d_inode) {
-        int err;
-        if (flags == 0 || flags & XATTR_CREATE) {
-            /* Although there is nothing else trying to create this directory,
-             * another directory with the same hash may be created, so we need
-             * to protect against that */
-            err = xaroot->d_inode->i_op->mkdir (xaroot->d_inode, xadir, 0700);
-            if (err) {
-                dput (xaroot);
-                dput (xadir);
-                return ERR_PTR (err);
-            }
-        }
-        if (!xadir->d_inode) {
-            dput (xaroot);
-            dput (xadir);
-            return ERR_PTR (-ENODATA);
-        }
-    }
+	xaroot = get_xa_root(inode->i_sb);
+	if (IS_ERR(xaroot)) {
+		return xaroot;
+	} else if (!xaroot) {
+		if (flags == 0 || flags & XATTR_CREATE) {
+			xaroot = create_xa_root(inode->i_sb);
+			if (IS_ERR(xaroot))
+				return xaroot;
+		}
+		if (!xaroot)
+			return ERR_PTR(-ENODATA);
+	}
+
+	/* ok, we have xaroot open */
+
+	snprintf(namebuf, sizeof(namebuf), "%X.%X",
+		 le32_to_cpu(INODE_PKEY(inode)->k_objectid),
+		 inode->i_generation);
+	xadir = lookup_one_len(namebuf, xaroot, strlen(namebuf));
+	if (IS_ERR(xadir)) {
+		dput(xaroot);
+		return xadir;
+	}
 
-    dput (xaroot);
-    return xadir;
+	if (!xadir->d_inode) {
+		int err;
+		if (flags == 0 || flags & XATTR_CREATE) {
+			/* Although there is nothing else trying to create this directory,
+			 * another directory with the same hash may be created, so we need
+			 * to protect against that */
+			err =
+			    xaroot->d_inode->i_op->mkdir(xaroot->d_inode, xadir,
+							 0700);
+			if (err) {
+				dput(xaroot);
+				dput(xadir);
+				return ERR_PTR(err);
+			}
+		}
+		if (!xadir->d_inode) {
+			dput(xaroot);
+			dput(xadir);
+			return ERR_PTR(-ENODATA);
+		}
+	}
+
+	dput(xaroot);
+	return xadir;
 }
 
 /* Returns a dentry corresponding to a specific extended attribute file
  * for the inode. If flags allow, the file is created. Otherwise, a
  * valid or negative dentry, or an error is returned. */
-static struct dentry *
-get_xa_file_dentry (const struct inode *inode, const char *name, int flags)
+static struct dentry *get_xa_file_dentry(const struct inode *inode,
+					 const char *name, int flags)
 {
-    struct dentry *xadir, *xafile;
-    int err = 0;
+	struct dentry *xadir, *xafile;
+	int err = 0;
 
-    xadir = open_xa_dir (inode, flags);
-    if (IS_ERR (xadir)) {
-        return ERR_PTR (PTR_ERR (xadir));
-    } else if (xadir && !xadir->d_inode) {
-        dput (xadir);
-        return ERR_PTR (-ENODATA);
-    }
-
-    xafile = lookup_one_len (name, xadir, strlen (name));
-    if (IS_ERR (xafile)) {
-        dput (xadir);
-        return ERR_PTR (PTR_ERR (xafile));
-    }
-
-    if (xafile->d_inode) { /* file exists */
-        if (flags & XATTR_CREATE) {
-            err = -EEXIST;
-            dput (xafile);
-            goto out;
-        }
-    } else if (flags & XATTR_REPLACE || flags & FL_READONLY) {
-        goto out;
-    } else {
-        /* inode->i_sem is down, so nothing else can try to create
-         * the same xattr */
-        err = xadir->d_inode->i_op->create (xadir->d_inode, xafile,
-                                            0700|S_IFREG, NULL);
-
-        if (err) {
-            dput (xafile);
-            goto out;
-        }
-    }
-
-out:
-    dput (xadir);
-    if (err)
-        xafile = ERR_PTR (err);
-    return xafile;
-}
+	xadir = open_xa_dir(inode, flags);
+	if (IS_ERR(xadir)) {
+		return ERR_PTR(PTR_ERR(xadir));
+	} else if (xadir && !xadir->d_inode) {
+		dput(xadir);
+		return ERR_PTR(-ENODATA);
+	}
 
+	xafile = lookup_one_len(name, xadir, strlen(name));
+	if (IS_ERR(xafile)) {
+		dput(xadir);
+		return ERR_PTR(PTR_ERR(xafile));
+	}
+
+	if (xafile->d_inode) {	/* file exists */
+		if (flags & XATTR_CREATE) {
+			err = -EEXIST;
+			dput(xafile);
+			goto out;
+		}
+	} else if (flags & XATTR_REPLACE || flags & FL_READONLY) {
+		goto out;
+	} else {
+		/* inode->i_sem is down, so nothing else can try to create
+		 * the same xattr */
+		err = xadir->d_inode->i_op->create(xadir->d_inode, xafile,
+						   0700 | S_IFREG, NULL);
+
+		if (err) {
+			dput(xafile);
+			goto out;
+		}
+	}
+
+      out:
+	dput(xadir);
+	if (err)
+		xafile = ERR_PTR(err);
+	return xafile;
+}
 
 /* Opens a file pointer to the attribute associated with inode */
-static struct file *
-open_xa_file (const struct inode *inode, const char *name, int flags)
+static struct file *open_xa_file(const struct inode *inode, const char *name,
+				 int flags)
 {
-    struct dentry *xafile;
-    struct file *fp;
+	struct dentry *xafile;
+	struct file *fp;
 
-    xafile = get_xa_file_dentry (inode, name, flags);
-    if (IS_ERR (xafile))
-        return ERR_PTR (PTR_ERR (xafile));
-    else if (!xafile->d_inode) {
-        dput (xafile);
-        return ERR_PTR (-ENODATA);
-    }
+	xafile = get_xa_file_dentry(inode, name, flags);
+	if (IS_ERR(xafile))
+		return ERR_PTR(PTR_ERR(xafile));
+	else if (!xafile->d_inode) {
+		dput(xafile);
+		return ERR_PTR(-ENODATA);
+	}
 
-    fp = dentry_open (xafile, NULL, O_RDWR);
-    /* dentry_open dputs the dentry if it fails */
+	fp = dentry_open(xafile, NULL, O_RDWR);
+	/* dentry_open dputs the dentry if it fails */
 
-    return fp;
+	return fp;
 }
 
-
 /*
  * this is very similar to fs/reiserfs/dir.c:reiserfs_readdir, but
  * we need to drop the path before calling the filldir struct.  That
@@ -273,139 +271,146 @@ open_xa_file (const struct inode *inode,
  * we're called with i_sem held, so there are no worries about the directory
  * changing underneath us.
  */
-static int __xattr_readdir(struct file * filp, void * dirent, filldir_t filldir)
+static int __xattr_readdir(struct file *filp, void *dirent, filldir_t filldir)
 {
-    struct inode *inode = filp->f_dentry->d_inode;
-    struct cpu_key pos_key;	/* key of current position in the directory (key of directory entry) */
-    INITIALIZE_PATH (path_to_entry);
-    struct buffer_head * bh;
-    int entry_num;
-    struct item_head * ih, tmp_ih;
-    int search_res;
-    char * local_buf;
-    loff_t next_pos;
-    char small_buf[32] ; /* avoid kmalloc if we can */
-    struct reiserfs_de_head *deh;
-    int d_reclen;
-    char * d_name;
-    off_t d_off;
-    ino_t d_ino;
-    struct reiserfs_dir_entry de;
-
-
-    /* form key for search the next directory entry using f_pos field of
-       file structure */
-    next_pos = max_reiserfs_offset(inode);
-
-    while (1) {
-research:
-	if (next_pos <= DOT_DOT_OFFSET)
-	    break;
-	make_cpu_key (&pos_key, inode, next_pos, TYPE_DIRENTRY, 3);
-
-	search_res = search_by_entry_key(inode->i_sb, &pos_key, &path_to_entry, &de);
-	if (search_res == IO_ERROR) {
-	    // FIXME: we could just skip part of directory which could
-	    // not be read
-	    pathrelse(&path_to_entry);
-	    return -EIO;
-	}
-
-	if (search_res == NAME_NOT_FOUND)
-	    de.de_entry_num--;
-
-	set_de_name_and_namelen(&de);
-	entry_num = de.de_entry_num;
-	deh = &(de.de_deh[entry_num]);
-
-	bh = de.de_bh;
-	ih = de.de_ih;
-
-	if (!is_direntry_le_ih(ih)) {
-            reiserfs_warning(inode->i_sb, "not direntry %h", ih);
-	    break;
-        }
-	copy_item_head(&tmp_ih, ih);
-
-	/* we must have found item, that is item of this directory, */
-	RFALSE( COMP_SHORT_KEYS (&(ih->ih_key), &pos_key),
-		"vs-9000: found item %h does not match to dir we readdir %K",
-		ih, &pos_key);
-
-	if (deh_offset(deh) <= DOT_DOT_OFFSET) {
-	    break;
-	}
-
-	/* look for the previous entry in the directory */
-	next_pos = deh_offset (deh) - 1;
-
-	if (!de_visible (deh))
-	    /* it is hidden entry */
-	    continue;
-
-	d_reclen = entry_length(bh, ih, entry_num);
-	d_name = B_I_DEH_ENTRY_FILE_NAME (bh, ih, deh);
-	d_off = deh_offset (deh);
-	d_ino = deh_objectid (deh);
-
-	if (!d_name[d_reclen - 1])
-	    d_reclen = strlen (d_name);
-
-	if (d_reclen > REISERFS_MAX_NAME(inode->i_sb->s_blocksize)){
-	    /* too big to send back to VFS */
-	    continue ;
-	}
-
-        /* Ignore the .reiserfs_priv entry */
-        if (reiserfs_xattrs (inode->i_sb) &&
-            !old_format_only(inode->i_sb) &&
-            deh_objectid (deh) == le32_to_cpu (INODE_PKEY(REISERFS_SB(inode->i_sb)->priv_root->d_inode)->k_objectid))
-          continue;
+	struct inode *inode = filp->f_dentry->d_inode;
+	struct cpu_key pos_key;	/* key of current position in the directory (key of directory entry) */
+	INITIALIZE_PATH(path_to_entry);
+	struct buffer_head *bh;
+	int entry_num;
+	struct item_head *ih, tmp_ih;
+	int search_res;
+	char *local_buf;
+	loff_t next_pos;
+	char small_buf[32];	/* avoid kmalloc if we can */
+	struct reiserfs_de_head *deh;
+	int d_reclen;
+	char *d_name;
+	off_t d_off;
+	ino_t d_ino;
+	struct reiserfs_dir_entry de;
+
+	/* form key for search the next directory entry using f_pos field of
+	   file structure */
+	next_pos = max_reiserfs_offset(inode);
+
+	while (1) {
+	      research:
+		if (next_pos <= DOT_DOT_OFFSET)
+			break;
+		make_cpu_key(&pos_key, inode, next_pos, TYPE_DIRENTRY, 3);
+
+		search_res =
+		    search_by_entry_key(inode->i_sb, &pos_key, &path_to_entry,
+					&de);
+		if (search_res == IO_ERROR) {
+			// FIXME: we could just skip part of directory which could
+			// not be read
+			pathrelse(&path_to_entry);
+			return -EIO;
+		}
 
-	if (d_reclen <= 32) {
-	  local_buf = small_buf ;
-	} else {
-	    local_buf = reiserfs_kmalloc(d_reclen, GFP_NOFS, inode->i_sb) ;
-	    if (!local_buf) {
-		pathrelse (&path_to_entry);
-		return -ENOMEM ;
-	    }
-	    if (item_moved (&tmp_ih, &path_to_entry)) {
-		reiserfs_kfree(local_buf, d_reclen, inode->i_sb) ;
-
-		/* sigh, must retry.  Do this same offset again */
-		next_pos = d_off;
-		goto research;
-	    }
-	}
-
-	// Note, that we copy name to user space via temporary
-	// buffer (local_buf) because filldir will block if
-	// user space buffer is swapped out. At that time
-	// entry can move to somewhere else
-	memcpy (local_buf, d_name, d_reclen);
-
-	/* the filldir function might need to start transactions,
-	 * or do who knows what.  Release the path now that we've
-	 * copied all the important stuff out of the deh
-	 */
-	pathrelse (&path_to_entry);
+		if (search_res == NAME_NOT_FOUND)
+			de.de_entry_num--;
+
+		set_de_name_and_namelen(&de);
+		entry_num = de.de_entry_num;
+		deh = &(de.de_deh[entry_num]);
+
+		bh = de.de_bh;
+		ih = de.de_ih;
+
+		if (!is_direntry_le_ih(ih)) {
+			reiserfs_warning(inode->i_sb, "not direntry %h", ih);
+			break;
+		}
+		copy_item_head(&tmp_ih, ih);
+
+		/* we must have found item, that is item of this directory, */
+		RFALSE(COMP_SHORT_KEYS(&(ih->ih_key), &pos_key),
+		       "vs-9000: found item %h does not match to dir we readdir %K",
+		       ih, &pos_key);
+
+		if (deh_offset(deh) <= DOT_DOT_OFFSET) {
+			break;
+		}
+
+		/* look for the previous entry in the directory */
+		next_pos = deh_offset(deh) - 1;
+
+		if (!de_visible(deh))
+			/* it is hidden entry */
+			continue;
+
+		d_reclen = entry_length(bh, ih, entry_num);
+		d_name = B_I_DEH_ENTRY_FILE_NAME(bh, ih, deh);
+		d_off = deh_offset(deh);
+		d_ino = deh_objectid(deh);
+
+		if (!d_name[d_reclen - 1])
+			d_reclen = strlen(d_name);
+
+		if (d_reclen > REISERFS_MAX_NAME(inode->i_sb->s_blocksize)) {
+			/* too big to send back to VFS */
+			continue;
+		}
+
+		/* Ignore the .reiserfs_priv entry */
+		if (reiserfs_xattrs(inode->i_sb) &&
+		    !old_format_only(inode->i_sb) &&
+		    deh_objectid(deh) ==
+		    le32_to_cpu(INODE_PKEY
+				(REISERFS_SB(inode->i_sb)->priv_root->d_inode)->
+				k_objectid))
+			continue;
+
+		if (d_reclen <= 32) {
+			local_buf = small_buf;
+		} else {
+			local_buf =
+			    reiserfs_kmalloc(d_reclen, GFP_NOFS, inode->i_sb);
+			if (!local_buf) {
+				pathrelse(&path_to_entry);
+				return -ENOMEM;
+			}
+			if (item_moved(&tmp_ih, &path_to_entry)) {
+				reiserfs_kfree(local_buf, d_reclen,
+					       inode->i_sb);
+
+				/* sigh, must retry.  Do this same offset again */
+				next_pos = d_off;
+				goto research;
+			}
+		}
+
+		// Note, that we copy name to user space via temporary
+		// buffer (local_buf) because filldir will block if
+		// user space buffer is swapped out. At that time
+		// entry can move to somewhere else
+		memcpy(local_buf, d_name, d_reclen);
+
+		/* the filldir function might need to start transactions,
+		 * or do who knows what.  Release the path now that we've
+		 * copied all the important stuff out of the deh
+		 */
+		pathrelse(&path_to_entry);
+
+		if (filldir(dirent, local_buf, d_reclen, d_off, d_ino,
+			    DT_UNKNOWN) < 0) {
+			if (local_buf != small_buf) {
+				reiserfs_kfree(local_buf, d_reclen,
+					       inode->i_sb);
+			}
+			goto end;
+		}
+		if (local_buf != small_buf) {
+			reiserfs_kfree(local_buf, d_reclen, inode->i_sb);
+		}
+	}			/* while */
 
-	if (filldir (dirent, local_buf, d_reclen, d_off, d_ino,
-		     DT_UNKNOWN) < 0) {
-	    if (local_buf != small_buf) {
-		reiserfs_kfree(local_buf, d_reclen, inode->i_sb) ;
-	    }
-	    goto end;
-	}
-	if (local_buf != small_buf) {
-	    reiserfs_kfree(local_buf, d_reclen, inode->i_sb) ;
-	}
-    } /* while */
-
-end:
-    pathrelse (&path_to_entry);
-    return 0;
+      end:
+	pathrelse(&path_to_entry);
+	return 0;
 }
 
 /*
@@ -417,63 +422,59 @@ end:
 static
 int xattr_readdir(struct file *file, filldir_t filler, void *buf)
 {
-        struct inode *inode = file->f_dentry->d_inode;
-        int res = -ENOTDIR;
-        if (!file->f_op || !file->f_op->readdir)
-                goto out;
-        down(&inode->i_sem);
+	struct inode *inode = file->f_dentry->d_inode;
+	int res = -ENOTDIR;
+	if (!file->f_op || !file->f_op->readdir)
+		goto out;
+	down(&inode->i_sem);
 //        down(&inode->i_zombie);
-        res = -ENOENT;
-        if (!IS_DEADDIR(inode)) {
-                lock_kernel();
-                res = __xattr_readdir(file, buf, filler);
-                unlock_kernel();
-        }
+	res = -ENOENT;
+	if (!IS_DEADDIR(inode)) {
+		lock_kernel();
+		res = __xattr_readdir(file, buf, filler);
+		unlock_kernel();
+	}
 //        up(&inode->i_zombie);
-        up(&inode->i_sem);
-out:
-        return res;
+	up(&inode->i_sem);
+      out:
+	return res;
 }
 
-
 /* Internal operations on file data */
-static inline void
-reiserfs_put_page(struct page *page)
+static inline void reiserfs_put_page(struct page *page)
 {
-        kunmap(page);
-        page_cache_release(page);
+	kunmap(page);
+	page_cache_release(page);
 }
 
-static struct page *
-reiserfs_get_page(struct inode *dir, unsigned long n)
-{
-        struct address_space *mapping = dir->i_mapping;
-        struct page *page;
-        /* We can deadlock if we try to free dentries,
-           and an unlink/rmdir has just occured - GFP_NOFS avoids this */
-        mapping->flags = (mapping->flags & ~__GFP_BITS_MASK) | GFP_NOFS;
-        page = read_cache_page (mapping, n,
-                                (filler_t*)mapping->a_ops->readpage, NULL);
-        if (!IS_ERR(page)) {
-                wait_on_page_locked(page);
-                kmap(page);
-                if (!PageUptodate(page))
-                        goto fail;
-
-                if (PageError(page))
-                        goto fail;
-        }
-        return page;
-
-fail:
-        reiserfs_put_page(page);
-        return ERR_PTR(-EIO);
+static struct page *reiserfs_get_page(struct inode *dir, unsigned long n)
+{
+	struct address_space *mapping = dir->i_mapping;
+	struct page *page;
+	/* We can deadlock if we try to free dentries,
+	   and an unlink/rmdir has just occured - GFP_NOFS avoids this */
+	mapping->flags = (mapping->flags & ~__GFP_BITS_MASK) | GFP_NOFS;
+	page = read_cache_page(mapping, n,
+			       (filler_t *) mapping->a_ops->readpage, NULL);
+	if (!IS_ERR(page)) {
+		wait_on_page_locked(page);
+		kmap(page);
+		if (!PageUptodate(page))
+			goto fail;
+
+		if (PageError(page))
+			goto fail;
+	}
+	return page;
+
+      fail:
+	reiserfs_put_page(page);
+	return ERR_PTR(-EIO);
 }
 
-static inline __u32
-xattr_hash (const char *msg, int len)
+static inline __u32 xattr_hash(const char *msg, int len)
 {
-    return csum_partial (msg, len, 0);
+	return csum_partial(msg, len, 0);
 }
 
 /* Generic extended attribute operations that can be used by xa plugins */
@@ -482,294 +483,300 @@ xattr_hash (const char *msg, int len)
  * inode->i_sem: down
  */
 int
-reiserfs_xattr_set (struct inode *inode, const char *name, const void *buffer,
-                    size_t buffer_size, int flags)
+reiserfs_xattr_set(struct inode *inode, const char *name, const void *buffer,
+		   size_t buffer_size, int flags)
 {
-    int err = 0;
-    struct file *fp;
-    struct page *page;
-    char *data;
-    struct address_space *mapping;
-    size_t file_pos = 0;
-    size_t buffer_pos = 0;
-    struct inode *xinode;
-    struct iattr newattrs;
-    __u32 xahash = 0;
-
-    if (IS_RDONLY (inode))
-        return -EROFS;
-
-    if (IS_IMMUTABLE (inode) || IS_APPEND (inode))
-        return -EPERM;
-
-    if (get_inode_sd_version (inode) == STAT_DATA_V1)
-        return -EOPNOTSUPP;
-
-    /* Empty xattrs are ok, they're just empty files, no hash */
-    if (buffer && buffer_size)
-        xahash = xattr_hash (buffer, buffer_size);
-
-open_file:
-    fp = open_xa_file (inode, name, flags);
-    if (IS_ERR (fp)) {
-        err = PTR_ERR (fp);
-        goto out;
-    }
+	int err = 0;
+	struct file *fp;
+	struct page *page;
+	char *data;
+	struct address_space *mapping;
+	size_t file_pos = 0;
+	size_t buffer_pos = 0;
+	struct inode *xinode;
+	struct iattr newattrs;
+	__u32 xahash = 0;
+
+	if (IS_RDONLY(inode))
+		return -EROFS;
+
+	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
+		return -EPERM;
+
+	if (get_inode_sd_version(inode) == STAT_DATA_V1)
+		return -EOPNOTSUPP;
+
+	/* Empty xattrs are ok, they're just empty files, no hash */
+	if (buffer && buffer_size)
+		xahash = xattr_hash(buffer, buffer_size);
+
+      open_file:
+	fp = open_xa_file(inode, name, flags);
+	if (IS_ERR(fp)) {
+		err = PTR_ERR(fp);
+		goto out;
+	}
+
+	xinode = fp->f_dentry->d_inode;
+	REISERFS_I(inode)->i_flags |= i_has_xattr_dir;
+
+	/* we need to copy it off.. */
+	if (xinode->i_nlink > 1) {
+		fput(fp);
+		err = reiserfs_xattr_del(inode, name);
+		if (err < 0)
+			goto out;
+		/* We just killed the old one, we're not replacing anymore */
+		if (flags & XATTR_REPLACE)
+			flags &= ~XATTR_REPLACE;
+		goto open_file;
+	}
 
-    xinode = fp->f_dentry->d_inode;
-    REISERFS_I(inode)->i_flags |= i_has_xattr_dir;
+	/* Resize it so we're ok to write there */
+	newattrs.ia_size = buffer_size;
+	newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME;
+	down(&xinode->i_sem);
+	err = notify_change(fp->f_dentry, &newattrs);
+	if (err)
+		goto out_filp;
+
+	mapping = xinode->i_mapping;
+	while (buffer_pos < buffer_size || buffer_pos == 0) {
+		size_t chunk;
+		size_t skip = 0;
+		size_t page_offset = (file_pos & (PAGE_CACHE_SIZE - 1));
+		if (buffer_size - buffer_pos > PAGE_CACHE_SIZE)
+			chunk = PAGE_CACHE_SIZE;
+		else
+			chunk = buffer_size - buffer_pos;
+
+		page = reiserfs_get_page(xinode, file_pos >> PAGE_CACHE_SHIFT);
+		if (IS_ERR(page)) {
+			err = PTR_ERR(page);
+			goto out_filp;
+		}
+
+		lock_page(page);
+		data = page_address(page);
 
-    /* we need to copy it off.. */
-    if (xinode->i_nlink > 1) {
+		if (file_pos == 0) {
+			struct reiserfs_xattr_header *rxh;
+			skip = file_pos = sizeof(struct reiserfs_xattr_header);
+			if (chunk + skip > PAGE_CACHE_SIZE)
+				chunk = PAGE_CACHE_SIZE - skip;
+			rxh = (struct reiserfs_xattr_header *)data;
+			rxh->h_magic = cpu_to_le32(REISERFS_XATTR_MAGIC);
+			rxh->h_hash = cpu_to_le32(xahash);
+		}
+
+		err = mapping->a_ops->prepare_write(fp, page, page_offset,
+						    page_offset + chunk + skip);
+		if (!err) {
+			if (buffer)
+				memcpy(data + skip, buffer + buffer_pos, chunk);
+			err =
+			    mapping->a_ops->commit_write(fp, page, page_offset,
+							 page_offset + chunk +
+							 skip);
+		}
+		unlock_page(page);
+		reiserfs_put_page(page);
+		buffer_pos += chunk;
+		file_pos += chunk;
+		skip = 0;
+		if (err || buffer_size == 0 || !buffer)
+			break;
+	}
+
+	/* We can't mark the inode dirty if it's not hashed. This is the case
+	 * when we're inheriting the default ACL. If we dirty it, the inode
+	 * gets marked dirty, but won't (ever) make it onto the dirty list until
+	 * it's synced explicitly to clear I_DIRTY. This is bad. */
+	if (!hlist_unhashed(&inode->i_hash)) {
+		inode->i_ctime = CURRENT_TIME_SEC;
+		mark_inode_dirty(inode);
+	}
+
+      out_filp:
+	up(&xinode->i_sem);
 	fput(fp);
-        err = reiserfs_xattr_del (inode, name);
-        if (err < 0)
-            goto out;
-        /* We just killed the old one, we're not replacing anymore */
-        if (flags & XATTR_REPLACE)
-            flags &= ~XATTR_REPLACE;
-        goto open_file;
-    }
-
-    /* Resize it so we're ok to write there */
-    newattrs.ia_size = buffer_size;
-    newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME;
-    down (&xinode->i_sem);
-    err = notify_change(fp->f_dentry, &newattrs);
-    if (err)
-        goto out_filp;
-
-    mapping = xinode->i_mapping;
-    while (buffer_pos < buffer_size || buffer_pos == 0) {
-        size_t chunk;
-        size_t skip = 0;
-        size_t page_offset = (file_pos & (PAGE_CACHE_SIZE - 1));
-        if (buffer_size - buffer_pos > PAGE_CACHE_SIZE)
-            chunk = PAGE_CACHE_SIZE;
-        else
-            chunk = buffer_size - buffer_pos;
-
-        page = reiserfs_get_page (xinode, file_pos >> PAGE_CACHE_SHIFT);
-        if (IS_ERR (page)) {
-            err = PTR_ERR (page);
-            goto out_filp;
-        }
-
-        lock_page (page);
-        data = page_address (page);
-
-        if (file_pos == 0) {
-            struct reiserfs_xattr_header *rxh;
-            skip = file_pos = sizeof (struct reiserfs_xattr_header);
-            if (chunk + skip > PAGE_CACHE_SIZE)
-                chunk = PAGE_CACHE_SIZE - skip;
-            rxh = (struct reiserfs_xattr_header *)data;
-            rxh->h_magic = cpu_to_le32 (REISERFS_XATTR_MAGIC);
-            rxh->h_hash = cpu_to_le32 (xahash);
-        }
-
-        err = mapping->a_ops->prepare_write (fp, page, page_offset,
-                                             page_offset + chunk + skip);
-        if (!err) {
-	    if (buffer)
-		memcpy (data + skip, buffer + buffer_pos, chunk);
-            err = mapping->a_ops->commit_write (fp, page, page_offset,
-                                                page_offset + chunk + skip);
-	}
-        unlock_page (page);
-        reiserfs_put_page (page);
-        buffer_pos += chunk;
-        file_pos += chunk;
-        skip = 0;
-        if (err || buffer_size == 0 || !buffer)
-            break;
-    }
-
-    /* We can't mark the inode dirty if it's not hashed. This is the case
-     * when we're inheriting the default ACL. If we dirty it, the inode
-     * gets marked dirty, but won't (ever) make it onto the dirty list until
-     * it's synced explicitly to clear I_DIRTY. This is bad. */
-    if (!hlist_unhashed(&inode->i_hash)) {
-        inode->i_ctime = CURRENT_TIME_SEC;
-        mark_inode_dirty (inode);
-    }
-
-out_filp:
-    up (&xinode->i_sem);
-    fput(fp);
 
-out:
-    return err;
+      out:
+	return err;
 }
 
 /*
  * inode->i_sem: down
  */
 int
-reiserfs_xattr_get (const struct inode *inode, const char *name, void *buffer,
-                    size_t buffer_size)
+reiserfs_xattr_get(const struct inode *inode, const char *name, void *buffer,
+		   size_t buffer_size)
 {
-    ssize_t err = 0;
-    struct file *fp;
-    size_t isize;
-    size_t file_pos = 0;
-    size_t buffer_pos = 0;
-    struct page *page;
-    struct inode *xinode;
-    __u32 hash = 0;
-
-    if (name == NULL)
-        return -EINVAL;
-
-    /* We can't have xattrs attached to v1 items since they don't have
-     * generation numbers */
-    if (get_inode_sd_version (inode) == STAT_DATA_V1)
-        return -EOPNOTSUPP;
-
-    fp = open_xa_file (inode, name, FL_READONLY);
-    if (IS_ERR (fp)) {
-        err = PTR_ERR (fp);
-        goto out;
-    }
-
-    xinode = fp->f_dentry->d_inode;
-    isize = xinode->i_size;
-    REISERFS_I(inode)->i_flags |= i_has_xattr_dir;
-
-    /* Just return the size needed */
-    if (buffer == NULL) {
-        err = isize - sizeof (struct reiserfs_xattr_header);
-        goto out_dput;
-    }
-
-    if (buffer_size < isize - sizeof (struct reiserfs_xattr_header)) {
-        err = -ERANGE;
-        goto out_dput;
-    }
-
-    while (file_pos < isize) {
-        size_t chunk;
-        char *data;
-        size_t skip = 0;
-        if (isize - file_pos > PAGE_CACHE_SIZE)
-            chunk = PAGE_CACHE_SIZE;
-        else
-            chunk = isize - file_pos;
-
-        page = reiserfs_get_page (xinode, file_pos >> PAGE_CACHE_SHIFT);
-        if (IS_ERR (page)) {
-            err = PTR_ERR (page);
-            goto out_dput;
-        }
-
-        lock_page (page);
-        data = page_address (page);
-        if (file_pos == 0) {
-            struct reiserfs_xattr_header *rxh =
-                                        (struct reiserfs_xattr_header *)data;
-            skip = file_pos = sizeof (struct reiserfs_xattr_header);
-            chunk -= skip;
-            /* Magic doesn't match up.. */
-            if (rxh->h_magic != cpu_to_le32 (REISERFS_XATTR_MAGIC)) {
-                unlock_page (page);
-                reiserfs_put_page (page);
-                reiserfs_warning (inode->i_sb, "Invalid magic for xattr (%s) "
-                                  "associated with %k", name,
-                                  INODE_PKEY (inode));
-                err = -EIO;
-                goto out_dput;
-            }
-            hash = le32_to_cpu (rxh->h_hash);
-        }
-        memcpy (buffer + buffer_pos, data + skip, chunk);
-        unlock_page (page);
-        reiserfs_put_page (page);
-        file_pos += chunk;
-        buffer_pos += chunk;
-        skip = 0;
-    }
-    err = isize - sizeof (struct reiserfs_xattr_header);
-
-    if (xattr_hash (buffer, isize - sizeof (struct reiserfs_xattr_header)) != hash) {
-        reiserfs_warning (inode->i_sb, "Invalid hash for xattr (%s) associated "
-                          "with %k", name, INODE_PKEY (inode));
-        err = -EIO;
-    }
+	ssize_t err = 0;
+	struct file *fp;
+	size_t isize;
+	size_t file_pos = 0;
+	size_t buffer_pos = 0;
+	struct page *page;
+	struct inode *xinode;
+	__u32 hash = 0;
+
+	if (name == NULL)
+		return -EINVAL;
+
+	/* We can't have xattrs attached to v1 items since they don't have
+	 * generation numbers */
+	if (get_inode_sd_version(inode) == STAT_DATA_V1)
+		return -EOPNOTSUPP;
+
+	fp = open_xa_file(inode, name, FL_READONLY);
+	if (IS_ERR(fp)) {
+		err = PTR_ERR(fp);
+		goto out;
+	}
+
+	xinode = fp->f_dentry->d_inode;
+	isize = xinode->i_size;
+	REISERFS_I(inode)->i_flags |= i_has_xattr_dir;
+
+	/* Just return the size needed */
+	if (buffer == NULL) {
+		err = isize - sizeof(struct reiserfs_xattr_header);
+		goto out_dput;
+	}
+
+	if (buffer_size < isize - sizeof(struct reiserfs_xattr_header)) {
+		err = -ERANGE;
+		goto out_dput;
+	}
+
+	while (file_pos < isize) {
+		size_t chunk;
+		char *data;
+		size_t skip = 0;
+		if (isize - file_pos > PAGE_CACHE_SIZE)
+			chunk = PAGE_CACHE_SIZE;
+		else
+			chunk = isize - file_pos;
+
+		page = reiserfs_get_page(xinode, file_pos >> PAGE_CACHE_SHIFT);
+		if (IS_ERR(page)) {
+			err = PTR_ERR(page);
+			goto out_dput;
+		}
+
+		lock_page(page);
+		data = page_address(page);
+		if (file_pos == 0) {
+			struct reiserfs_xattr_header *rxh =
+			    (struct reiserfs_xattr_header *)data;
+			skip = file_pos = sizeof(struct reiserfs_xattr_header);
+			chunk -= skip;
+			/* Magic doesn't match up.. */
+			if (rxh->h_magic != cpu_to_le32(REISERFS_XATTR_MAGIC)) {
+				unlock_page(page);
+				reiserfs_put_page(page);
+				reiserfs_warning(inode->i_sb,
+						 "Invalid magic for xattr (%s) "
+						 "associated with %k", name,
+						 INODE_PKEY(inode));
+				err = -EIO;
+				goto out_dput;
+			}
+			hash = le32_to_cpu(rxh->h_hash);
+		}
+		memcpy(buffer + buffer_pos, data + skip, chunk);
+		unlock_page(page);
+		reiserfs_put_page(page);
+		file_pos += chunk;
+		buffer_pos += chunk;
+		skip = 0;
+	}
+	err = isize - sizeof(struct reiserfs_xattr_header);
+
+	if (xattr_hash(buffer, isize - sizeof(struct reiserfs_xattr_header)) !=
+	    hash) {
+		reiserfs_warning(inode->i_sb,
+				 "Invalid hash for xattr (%s) associated "
+				 "with %k", name, INODE_PKEY(inode));
+		err = -EIO;
+	}
 
-out_dput:
-    fput(fp);
+      out_dput:
+	fput(fp);
 
-out:
-    return err;
+      out:
+	return err;
 }
 
 static int
-__reiserfs_xattr_del (struct dentry *xadir, const char *name, int namelen)
+__reiserfs_xattr_del(struct dentry *xadir, const char *name, int namelen)
 {
-    struct dentry *dentry;
-    struct inode *dir = xadir->d_inode;
-    int err = 0;
-
-    dentry = lookup_one_len (name, xadir, namelen);
-    if (IS_ERR (dentry)) {
-        err = PTR_ERR (dentry);
-        goto out;
-    } else if (!dentry->d_inode) {
-        err = -ENODATA;
-        goto out_file;
-    }
-
-    /* Skip directories.. */
-    if (S_ISDIR (dentry->d_inode->i_mode))
-        goto out_file;
-
-    if (!is_reiserfs_priv_object (dentry->d_inode)) {
-        reiserfs_warning (dir->i_sb, "OID %08x [%.*s/%.*s] doesn't have "
-                                     "priv flag set [parent is %sset].",
-                        le32_to_cpu (INODE_PKEY (dentry->d_inode)->k_objectid),
-                        xadir->d_name.len, xadir->d_name.name, namelen, name,
-                        is_reiserfs_priv_object (xadir->d_inode) ? "" : "not ");
-        dput (dentry);
-        return -EIO;
-    }
-
-    err = dir->i_op->unlink (dir, dentry);
-    if (!err)
-        d_delete (dentry);
+	struct dentry *dentry;
+	struct inode *dir = xadir->d_inode;
+	int err = 0;
+
+	dentry = lookup_one_len(name, xadir, namelen);
+	if (IS_ERR(dentry)) {
+		err = PTR_ERR(dentry);
+		goto out;
+	} else if (!dentry->d_inode) {
+		err = -ENODATA;
+		goto out_file;
+	}
 
-out_file:
-    dput (dentry);
+	/* Skip directories.. */
+	if (S_ISDIR(dentry->d_inode->i_mode))
+		goto out_file;
+
+	if (!is_reiserfs_priv_object(dentry->d_inode)) {
+		reiserfs_warning(dir->i_sb, "OID %08x [%.*s/%.*s] doesn't have "
+				 "priv flag set [parent is %sset].",
+				 le32_to_cpu(INODE_PKEY(dentry->d_inode)->
+					     k_objectid), xadir->d_name.len,
+				 xadir->d_name.name, namelen, name,
+				 is_reiserfs_priv_object(xadir->
+							 d_inode) ? "" :
+				 "not ");
+		dput(dentry);
+		return -EIO;
+	}
 
-out:
-    return err;
-}
+	err = dir->i_op->unlink(dir, dentry);
+	if (!err)
+		d_delete(dentry);
 
+      out_file:
+	dput(dentry);
 
-int
-reiserfs_xattr_del (struct inode *inode, const char *name)
+      out:
+	return err;
+}
+
+int reiserfs_xattr_del(struct inode *inode, const char *name)
 {
-    struct dentry *dir;
-    int err;
+	struct dentry *dir;
+	int err;
 
-    if (IS_RDONLY (inode))
-        return -EROFS;
+	if (IS_RDONLY(inode))
+		return -EROFS;
 
-    dir = open_xa_dir (inode, FL_READONLY);
-    if (IS_ERR (dir)) {
-        err = PTR_ERR (dir);
-        goto out;
-    }
-
-    err = __reiserfs_xattr_del (dir, name, strlen (name));
-    dput (dir);
-
-    if (!err) {
-        inode->i_ctime = CURRENT_TIME_SEC;
-        mark_inode_dirty (inode);
-    }
+	dir = open_xa_dir(inode, FL_READONLY);
+	if (IS_ERR(dir)) {
+		err = PTR_ERR(dir);
+		goto out;
+	}
+
+	err = __reiserfs_xattr_del(dir, name, strlen(name));
+	dput(dir);
 
-out:
-    return err;
+	if (!err) {
+		inode->i_ctime = CURRENT_TIME_SEC;
+		mark_inode_dirty(inode);
+	}
+
+      out:
+	return err;
 }
 
 /* The following are side effects of other operations that aren't explicitly
@@ -777,167 +784,163 @@ out:
  * or ownership changes, object deletions, etc. */
 
 static int
-reiserfs_delete_xattrs_filler (void *buf, const char *name, int namelen,
-                               loff_t offset, ino_t ino, unsigned int d_type)
+reiserfs_delete_xattrs_filler(void *buf, const char *name, int namelen,
+			      loff_t offset, ino_t ino, unsigned int d_type)
 {
-    struct dentry *xadir = (struct dentry *)buf;
+	struct dentry *xadir = (struct dentry *)buf;
 
-    return __reiserfs_xattr_del (xadir, name, namelen);
+	return __reiserfs_xattr_del(xadir, name, namelen);
 
 }
 
 /* This is called w/ inode->i_sem downed */
-int
-reiserfs_delete_xattrs (struct inode *inode)
+int reiserfs_delete_xattrs(struct inode *inode)
 {
-    struct file *fp;
-    struct dentry *dir, *root;
-    int err = 0;
-
-    /* Skip out, an xattr has no xattrs associated with it */
-    if (is_reiserfs_priv_object (inode) ||
-        get_inode_sd_version (inode) == STAT_DATA_V1 ||
-        !reiserfs_xattrs(inode->i_sb))
-    {
-        return 0;
-    }
-    reiserfs_read_lock_xattrs (inode->i_sb);
-    dir = open_xa_dir (inode, FL_READONLY);
-    reiserfs_read_unlock_xattrs (inode->i_sb);
-    if (IS_ERR (dir)) {
-        err = PTR_ERR (dir);
-        goto out;
-    } else if (!dir->d_inode) {
-        dput (dir);
-        return 0;
-    }
-
-    fp = dentry_open (dir, NULL, O_RDWR);
-    if (IS_ERR (fp)) {
-        err = PTR_ERR (fp);
-        /* dentry_open dputs the dentry if it fails */
-        goto out;
-    }
-
-    lock_kernel ();
-    err = xattr_readdir (fp, reiserfs_delete_xattrs_filler, dir);
-    if (err) {
-        unlock_kernel ();
-        goto out_dir;
-    }
-
-    /* Leftovers besides . and .. -- that's not good. */
-    if (dir->d_inode->i_nlink <= 2) {
-        root = get_xa_root (inode->i_sb);
-        reiserfs_write_lock_xattrs (inode->i_sb);
-        err = vfs_rmdir (root->d_inode, dir);
-        reiserfs_write_unlock_xattrs (inode->i_sb);
-        dput (root);
-    } else {
-        reiserfs_warning (inode->i_sb,
-                          "Couldn't remove all entries in directory");
-    }
-    unlock_kernel ();
-
-out_dir:
-    fput(fp);
-
-out:
-    if (!err)
-        REISERFS_I(inode)->i_flags = REISERFS_I(inode)->i_flags & ~i_has_xattr_dir;
-    return err;
+	struct file *fp;
+	struct dentry *dir, *root;
+	int err = 0;
+
+	/* Skip out, an xattr has no xattrs associated with it */
+	if (is_reiserfs_priv_object(inode) ||
+	    get_inode_sd_version(inode) == STAT_DATA_V1 ||
+	    !reiserfs_xattrs(inode->i_sb)) {
+		return 0;
+	}
+	reiserfs_read_lock_xattrs(inode->i_sb);
+	dir = open_xa_dir(inode, FL_READONLY);
+	reiserfs_read_unlock_xattrs(inode->i_sb);
+	if (IS_ERR(dir)) {
+		err = PTR_ERR(dir);
+		goto out;
+	} else if (!dir->d_inode) {
+		dput(dir);
+		return 0;
+	}
+
+	fp = dentry_open(dir, NULL, O_RDWR);
+	if (IS_ERR(fp)) {
+		err = PTR_ERR(fp);
+		/* dentry_open dputs the dentry if it fails */
+		goto out;
+	}
+
+	lock_kernel();
+	err = xattr_readdir(fp, reiserfs_delete_xattrs_filler, dir);
+	if (err) {
+		unlock_kernel();
+		goto out_dir;
+	}
+
+	/* Leftovers besides . and .. -- that's not good. */
+	if (dir->d_inode->i_nlink <= 2) {
+		root = get_xa_root(inode->i_sb);
+		reiserfs_write_lock_xattrs(inode->i_sb);
+		err = vfs_rmdir(root->d_inode, dir);
+		reiserfs_write_unlock_xattrs(inode->i_sb);
+		dput(root);
+	} else {
+		reiserfs_warning(inode->i_sb,
+				 "Couldn't remove all entries in directory");
+	}
+	unlock_kernel();
+
+      out_dir:
+	fput(fp);
+
+      out:
+	if (!err)
+		REISERFS_I(inode)->i_flags =
+		    REISERFS_I(inode)->i_flags & ~i_has_xattr_dir;
+	return err;
 }
 
 struct reiserfs_chown_buf {
-    struct inode *inode;
-    struct dentry *xadir;
-    struct iattr *attrs;
+	struct inode *inode;
+	struct dentry *xadir;
+	struct iattr *attrs;
 };
 
 /* XXX: If there is a better way to do this, I'd love to hear about it */
 static int
-reiserfs_chown_xattrs_filler (void *buf, const char *name, int namelen,
-                               loff_t offset, ino_t ino, unsigned int d_type)
+reiserfs_chown_xattrs_filler(void *buf, const char *name, int namelen,
+			     loff_t offset, ino_t ino, unsigned int d_type)
 {
-    struct reiserfs_chown_buf *chown_buf = (struct reiserfs_chown_buf *)buf;
-    struct dentry *xafile, *xadir = chown_buf->xadir;
-    struct iattr *attrs = chown_buf->attrs;
-    int err = 0;
-
-    xafile = lookup_one_len (name, xadir, namelen);
-    if (IS_ERR (xafile))
-        return PTR_ERR (xafile);
-    else if (!xafile->d_inode) {
-        dput (xafile);
-        return -ENODATA;
-    }
-
-    if (!S_ISDIR (xafile->d_inode->i_mode))
-        err = notify_change (xafile, attrs);
-    dput (xafile);
+	struct reiserfs_chown_buf *chown_buf = (struct reiserfs_chown_buf *)buf;
+	struct dentry *xafile, *xadir = chown_buf->xadir;
+	struct iattr *attrs = chown_buf->attrs;
+	int err = 0;
+
+	xafile = lookup_one_len(name, xadir, namelen);
+	if (IS_ERR(xafile))
+		return PTR_ERR(xafile);
+	else if (!xafile->d_inode) {
+		dput(xafile);
+		return -ENODATA;
+	}
+
+	if (!S_ISDIR(xafile->d_inode->i_mode))
+		err = notify_change(xafile, attrs);
+	dput(xafile);
 
-    return err;
+	return err;
 }
 
-int
-reiserfs_chown_xattrs (struct inode *inode, struct iattr *attrs)
+int reiserfs_chown_xattrs(struct inode *inode, struct iattr *attrs)
 {
-    struct file *fp;
-    struct dentry *dir;
-    int err = 0;
-    struct reiserfs_chown_buf buf;
-    unsigned int ia_valid = attrs->ia_valid;
-
-    /* Skip out, an xattr has no xattrs associated with it */
-    if (is_reiserfs_priv_object (inode) ||
-        get_inode_sd_version (inode) == STAT_DATA_V1 ||
-        !reiserfs_xattrs(inode->i_sb))
-    {
-        return 0;
-    }
-    reiserfs_read_lock_xattrs (inode->i_sb);
-    dir = open_xa_dir (inode, FL_READONLY);
-    reiserfs_read_unlock_xattrs (inode->i_sb);
-    if (IS_ERR (dir)) {
-        if (PTR_ERR (dir) != -ENODATA)
-            err = PTR_ERR (dir);
-        goto out;
-    } else if (!dir->d_inode) {
-        dput (dir);
-        goto out;
-    }
-
-    fp = dentry_open (dir, NULL, O_RDWR);
-    if (IS_ERR (fp)) {
-        err = PTR_ERR (fp);
-        /* dentry_open dputs the dentry if it fails */
-        goto out;
-    }
-
-    lock_kernel ();
-
-    attrs->ia_valid &= (ATTR_UID | ATTR_GID | ATTR_CTIME);
-    buf.xadir = dir;
-    buf.attrs = attrs;
-    buf.inode = inode;
-
-    err = xattr_readdir (fp, reiserfs_chown_xattrs_filler, &buf);
-    if (err) {
-        unlock_kernel ();
-        goto out_dir;
-    }
-
-    err = notify_change (dir, attrs);
-    unlock_kernel ();
-
-out_dir:
-    fput(fp);
-
-out:
-    attrs->ia_valid = ia_valid;
-    return err;
-}
+	struct file *fp;
+	struct dentry *dir;
+	int err = 0;
+	struct reiserfs_chown_buf buf;
+	unsigned int ia_valid = attrs->ia_valid;
+
+	/* Skip out, an xattr has no xattrs associated with it */
+	if (is_reiserfs_priv_object(inode) ||
+	    get_inode_sd_version(inode) == STAT_DATA_V1 ||
+	    !reiserfs_xattrs(inode->i_sb)) {
+		return 0;
+	}
+	reiserfs_read_lock_xattrs(inode->i_sb);
+	dir = open_xa_dir(inode, FL_READONLY);
+	reiserfs_read_unlock_xattrs(inode->i_sb);
+	if (IS_ERR(dir)) {
+		if (PTR_ERR(dir) != -ENODATA)
+			err = PTR_ERR(dir);
+		goto out;
+	} else if (!dir->d_inode) {
+		dput(dir);
+		goto out;
+	}
+
+	fp = dentry_open(dir, NULL, O_RDWR);
+	if (IS_ERR(fp)) {
+		err = PTR_ERR(fp);
+		/* dentry_open dputs the dentry if it fails */
+		goto out;
+	}
+
+	lock_kernel();
+
+	attrs->ia_valid &= (ATTR_UID | ATTR_GID | ATTR_CTIME);
+	buf.xadir = dir;
+	buf.attrs = attrs;
+	buf.inode = inode;
+
+	err = xattr_readdir(fp, reiserfs_chown_xattrs_filler, &buf);
+	if (err) {
+		unlock_kernel();
+		goto out_dir;
+	}
+
+	err = notify_change(dir, attrs);
+	unlock_kernel();
 
+      out_dir:
+	fput(fp);
+
+      out:
+	attrs->ia_valid = ia_valid;
+	return err;
+}
 
 /* Actual operations that are exported to VFS-land */
 
@@ -946,61 +949,60 @@ out:
  * Preliminary locking: we down dentry->d_inode->i_sem
  */
 ssize_t
-reiserfs_getxattr (struct dentry *dentry, const char *name, void *buffer,
-                   size_t size)
+reiserfs_getxattr(struct dentry * dentry, const char *name, void *buffer,
+		  size_t size)
 {
-    struct reiserfs_xattr_handler *xah = find_xattr_handler_prefix (name);
-    int err;
+	struct reiserfs_xattr_handler *xah = find_xattr_handler_prefix(name);
+	int err;
 
-    if (!xah || !reiserfs_xattrs(dentry->d_sb) ||
-        get_inode_sd_version (dentry->d_inode) == STAT_DATA_V1)
-        return -EOPNOTSUPP;
-
-    reiserfs_read_lock_xattr_i (dentry->d_inode);
-    reiserfs_read_lock_xattrs (dentry->d_sb);
-    err = xah->get (dentry->d_inode, name, buffer, size);
-    reiserfs_read_unlock_xattrs (dentry->d_sb);
-    reiserfs_read_unlock_xattr_i (dentry->d_inode);
-    return err;
+	if (!xah || !reiserfs_xattrs(dentry->d_sb) ||
+	    get_inode_sd_version(dentry->d_inode) == STAT_DATA_V1)
+		return -EOPNOTSUPP;
+
+	reiserfs_read_lock_xattr_i(dentry->d_inode);
+	reiserfs_read_lock_xattrs(dentry->d_sb);
+	err = xah->get(dentry->d_inode, name, buffer, size);
+	reiserfs_read_unlock_xattrs(dentry->d_sb);
+	reiserfs_read_unlock_xattr_i(dentry->d_inode);
+	return err;
 }
 
-
 /*
  * Inode operation setxattr()
  *
  * dentry->d_inode->i_sem down
  */
 int
-reiserfs_setxattr (struct dentry *dentry, const char *name, const void *value,
-                   size_t size, int flags)
+reiserfs_setxattr(struct dentry *dentry, const char *name, const void *value,
+		  size_t size, int flags)
 {
-    struct reiserfs_xattr_handler *xah = find_xattr_handler_prefix (name);
-    int err;
-    int lock;
-
-    if (!xah || !reiserfs_xattrs(dentry->d_sb) ||
-        get_inode_sd_version (dentry->d_inode) == STAT_DATA_V1)
-        return -EOPNOTSUPP;
-
-    if (IS_RDONLY (dentry->d_inode))
-        return -EROFS;
-
-    if (IS_IMMUTABLE (dentry->d_inode) || IS_APPEND (dentry->d_inode))
-        return -EROFS;
-
-    reiserfs_write_lock_xattr_i (dentry->d_inode);
-    lock = !has_xattr_dir (dentry->d_inode);
-    if (lock)
-        reiserfs_write_lock_xattrs (dentry->d_sb);
-    else
-        reiserfs_read_lock_xattrs (dentry->d_sb);
-    err = xah->set (dentry->d_inode, name, value, size, flags);
-    if (lock)
-        reiserfs_write_unlock_xattrs (dentry->d_sb);
-    else
-        reiserfs_read_unlock_xattrs (dentry->d_sb);
-    reiserfs_write_unlock_xattr_i (dentry->d_inode);
-    return err;
+	struct reiserfs_xattr_handler *xah = find_xattr_handler_prefix(name);
+	int err;
+	int lock;
+
+	if (!xah || !reiserfs_xattrs(dentry->d_sb) ||
+	    get_inode_sd_version(dentry->d_inode) == STAT_DATA_V1)
+		return -EOPNOTSUPP;
+
+	if (IS_RDONLY(dentry->d_inode))
+		return -EROFS;
+
+	if (IS_IMMUTABLE(dentry->d_inode) || IS_APPEND(dentry->d_inode))
+		return -EROFS;
+
+	reiserfs_write_lock_xattr_i(dentry->d_inode);
+	lock = !has_xattr_dir(dentry->d_inode);
+	if (lock)
+		reiserfs_write_lock_xattrs(dentry->d_sb);
+	else
+		reiserfs_read_lock_xattrs(dentry->d_sb);
+	err = xah->set(dentry->d_inode, name, value, size, flags);
+	if (lock)
+		reiserfs_write_unlock_xattrs(dentry->d_sb);
+	else
+		reiserfs_read_unlock_xattrs(dentry->d_sb);
+	reiserfs_write_unlock_xattr_i(dentry->d_inode);
+	return err;
 }
 
 /*
@@ -1008,344 +1010,343 @@ reiserfs_setxattr (struct dentry *dentry
  *
  * dentry->d_inode->i_sem down
  */
-int
-reiserfs_removexattr (struct dentry *dentry, const char *name)
+int reiserfs_removexattr(struct dentry *dentry, const char *name)
 {
-    int err;
-    struct reiserfs_xattr_handler *xah = find_xattr_handler_prefix (name);
+	int err;
+	struct reiserfs_xattr_handler *xah = find_xattr_handler_prefix(name);
 
-    if (!xah || !reiserfs_xattrs(dentry->d_sb) ||
-        get_inode_sd_version (dentry->d_inode) == STAT_DATA_V1)
-        return -EOPNOTSUPP;
+	if (!xah || !reiserfs_xattrs(dentry->d_sb) ||
+	    get_inode_sd_version(dentry->d_inode) == STAT_DATA_V1)
+		return -EOPNOTSUPP;
 
-    if (IS_RDONLY (dentry->d_inode))
-        return -EROFS;
+	if (IS_RDONLY(dentry->d_inode))
+		return -EROFS;
 
-    if (IS_IMMUTABLE (dentry->d_inode) || IS_APPEND (dentry->d_inode))
-        return -EPERM;
+	if (IS_IMMUTABLE(dentry->d_inode) || IS_APPEND(dentry->d_inode))
+		return -EPERM;
 
-    reiserfs_write_lock_xattr_i (dentry->d_inode);
-    reiserfs_read_lock_xattrs (dentry->d_sb);
+	reiserfs_write_lock_xattr_i(dentry->d_inode);
+	reiserfs_read_lock_xattrs(dentry->d_sb);
 
-    /* Deletion pre-operation */
-    if (xah->del) {
-        err = xah->del (dentry->d_inode, name);
-        if (err)
-            goto out;
-    }
+	/* Deletion pre-operation */
+	if (xah->del) {
+		err = xah->del(dentry->d_inode, name);
+		if (err)
+			goto out;
+	}
 
-    err = reiserfs_xattr_del (dentry->d_inode, name);
+	err = reiserfs_xattr_del(dentry->d_inode, name);
 
-    dentry->d_inode->i_ctime = CURRENT_TIME_SEC;
-    mark_inode_dirty (dentry->d_inode);
+	dentry->d_inode->i_ctime = CURRENT_TIME_SEC;
+	mark_inode_dirty(dentry->d_inode);
 
-out:
-    reiserfs_read_unlock_xattrs (dentry->d_sb);
-    reiserfs_write_unlock_xattr_i (dentry->d_inode);
-    return err;
+      out:
+	reiserfs_read_unlock_xattrs(dentry->d_sb);
+	reiserfs_write_unlock_xattr_i(dentry->d_inode);
+	return err;
 }
 
-
 /* This is what filldir will use:
  * r_pos will always contain the amount of space required for the entire
  * list. If r_pos becomes larger than r_size, we need more space and we
  * return an error indicating this. If r_pos is less than r_size, then we've
  * filled the buffer successfully and we return success */
 struct reiserfs_listxattr_buf {
-    int r_pos;
-    int r_size;
-    char *r_buf;
-    struct inode *r_inode;
+	int r_pos;
+	int r_size;
+	char *r_buf;
+	struct inode *r_inode;
 };
 
 static int
-reiserfs_listxattr_filler (void *buf, const char *name, int namelen,
-                           loff_t offset, ino_t ino, unsigned int d_type)
+reiserfs_listxattr_filler(void *buf, const char *name, int namelen,
+			  loff_t offset, ino_t ino, unsigned int d_type)
 {
-    struct reiserfs_listxattr_buf *b = (struct reiserfs_listxattr_buf *)buf;
-    int len = 0;
-    if (name[0] != '.' || (namelen != 1 && (name[1] != '.' || namelen != 2))) {
-        struct reiserfs_xattr_handler *xah = find_xattr_handler_prefix (name);
-        if (!xah) return 0; /* Unsupported xattr name, skip it */
-
-        /* We call ->list() twice because the operation isn't required to just
-         * return the name back - we want to make sure we have enough space */
-        len += xah->list (b->r_inode, name, namelen, NULL);
-
-        if (len) {
-            if (b->r_pos + len + 1 <= b->r_size) {
-                char *p = b->r_buf + b->r_pos;
-                p += xah->list (b->r_inode, name, namelen, p);
-                *p++ = '\0';
-            }
-            b->r_pos += len + 1;
-        }
-    }
+	struct reiserfs_listxattr_buf *b = (struct reiserfs_listxattr_buf *)buf;
+	int len = 0;
+	if (name[0] != '.'
+	    || (namelen != 1 && (name[1] != '.' || namelen != 2))) {
+		struct reiserfs_xattr_handler *xah =
+		    find_xattr_handler_prefix(name);
+		if (!xah)
+			return 0;	/* Unsupported xattr name, skip it */
+
+		/* We call ->list() twice because the operation isn't required to just
+		 * return the name back - we want to make sure we have enough space */
+		len += xah->list(b->r_inode, name, namelen, NULL);
+
+		if (len) {
+			if (b->r_pos + len + 1 <= b->r_size) {
+				char *p = b->r_buf + b->r_pos;
+				p += xah->list(b->r_inode, name, namelen, p);
+				*p++ = '\0';
+			}
+			b->r_pos += len + 1;
+		}
+	}
 
-    return 0;
+	return 0;
 }
+
 /*
  * Inode operation listxattr()
  *
  * Preliminary locking: we down dentry->d_inode->i_sem
  */
-ssize_t
-reiserfs_listxattr (struct dentry *dentry, char *buffer, size_t size)
+ssize_t reiserfs_listxattr(struct dentry * dentry, char *buffer, size_t size)
 {
-    struct file *fp;
-    struct dentry *dir;
-    int err = 0;
-    struct reiserfs_listxattr_buf buf;
-
-    if (!dentry->d_inode)
-        return -EINVAL;
-
-    if (!reiserfs_xattrs(dentry->d_sb) ||
-        get_inode_sd_version (dentry->d_inode) == STAT_DATA_V1)
-        return -EOPNOTSUPP;
-
-    reiserfs_read_lock_xattr_i (dentry->d_inode);
-    reiserfs_read_lock_xattrs (dentry->d_sb);
-    dir = open_xa_dir (dentry->d_inode, FL_READONLY);
-    reiserfs_read_unlock_xattrs (dentry->d_sb);
-    if (IS_ERR (dir)) {
-        err = PTR_ERR (dir);
-        if (err == -ENODATA)
-            err = 0; /* Not an error if there aren't any xattrs */
-        goto out;
-    }
-
-    fp = dentry_open (dir, NULL, O_RDWR);
-    if (IS_ERR (fp)) {
-        err = PTR_ERR (fp);
-        /* dentry_open dputs the dentry if it fails */
-        goto out;
-    }
-
-    buf.r_buf = buffer;
-    buf.r_size = buffer ? size : 0;
-    buf.r_pos = 0;
-    buf.r_inode = dentry->d_inode;
-
-    REISERFS_I(dentry->d_inode)->i_flags |= i_has_xattr_dir;
-
-    err = xattr_readdir (fp, reiserfs_listxattr_filler, &buf);
-    if (err)
-        goto out_dir;
-
-    if (buf.r_pos > buf.r_size && buffer != NULL)
-        err = -ERANGE;
-    else
-        err = buf.r_pos;
-
-out_dir:
-    fput(fp);
-
-out:
-    reiserfs_read_unlock_xattr_i (dentry->d_inode);
-    return err;
+	struct file *fp;
+	struct dentry *dir;
+	int err = 0;
+	struct reiserfs_listxattr_buf buf;
+
+	if (!dentry->d_inode)
+		return -EINVAL;
+
+	if (!reiserfs_xattrs(dentry->d_sb) ||
+	    get_inode_sd_version(dentry->d_inode) == STAT_DATA_V1)
+		return -EOPNOTSUPP;
+
+	reiserfs_read_lock_xattr_i(dentry->d_inode);
+	reiserfs_read_lock_xattrs(dentry->d_sb);
+	dir = open_xa_dir(dentry->d_inode, FL_READONLY);
+	reiserfs_read_unlock_xattrs(dentry->d_sb);
+	if (IS_ERR(dir)) {
+		err = PTR_ERR(dir);
+		if (err == -ENODATA)
+			err = 0;	/* Not an error if there aren't any xattrs */
+		goto out;
+	}
+
+	fp = dentry_open(dir, NULL, O_RDWR);
+	if (IS_ERR(fp)) {
+		err = PTR_ERR(fp);
+		/* dentry_open dputs the dentry if it fails */
+		goto out;
+	}
+
+	buf.r_buf = buffer;
+	buf.r_size = buffer ? size : 0;
+	buf.r_pos = 0;
+	buf.r_inode = dentry->d_inode;
+
+	REISERFS_I(dentry->d_inode)->i_flags |= i_has_xattr_dir;
+
+	err = xattr_readdir(fp, reiserfs_listxattr_filler, &buf);
+	if (err)
+		goto out_dir;
+
+	if (buf.r_pos > buf.r_size && buffer != NULL)
+		err = -ERANGE;
+	else
+		err = buf.r_pos;
+
+      out_dir:
+	fput(fp);
+
+      out:
+	reiserfs_read_unlock_xattr_i(dentry->d_inode);
+	return err;
 }
 
 /* This is the implementation for the xattr plugin infrastructure */
-static struct list_head xattr_handlers = LIST_HEAD_INIT (xattr_handlers);
+static struct list_head xattr_handlers = LIST_HEAD_INIT(xattr_handlers);
 static DEFINE_RWLOCK(handler_lock);
 
-static struct reiserfs_xattr_handler *
-find_xattr_handler_prefix (const char *prefix)
+static struct reiserfs_xattr_handler *find_xattr_handler_prefix(const char
+								*prefix)
 {
-    struct reiserfs_xattr_handler *xah = NULL;
-    struct list_head *p;
+	struct reiserfs_xattr_handler *xah = NULL;
+	struct list_head *p;
 
-    read_lock (&handler_lock);
-    list_for_each (p, &xattr_handlers) {
-        xah = list_entry (p, struct reiserfs_xattr_handler, handlers);
-        if (strncmp (xah->prefix, prefix, strlen (xah->prefix)) == 0)
-            break;
-        xah = NULL;
-    }
+	read_lock(&handler_lock);
+	list_for_each(p, &xattr_handlers) {
+		xah = list_entry(p, struct reiserfs_xattr_handler, handlers);
+		if (strncmp(xah->prefix, prefix, strlen(xah->prefix)) == 0)
+			break;
+		xah = NULL;
+	}
 
-    read_unlock (&handler_lock);
-    return xah;
+	read_unlock(&handler_lock);
+	return xah;
 }
 
-static void
-__unregister_handlers (void)
+static void __unregister_handlers(void)
 {
-    struct reiserfs_xattr_handler *xah;
-    struct list_head *p, *tmp;
+	struct reiserfs_xattr_handler *xah;
+	struct list_head *p, *tmp;
 
-    list_for_each_safe (p, tmp, &xattr_handlers) {
-        xah = list_entry (p, struct reiserfs_xattr_handler, handlers);
-        if (xah->exit)
-            xah->exit();
+	list_for_each_safe(p, tmp, &xattr_handlers) {
+		xah = list_entry(p, struct reiserfs_xattr_handler, handlers);
+		if (xah->exit)
+			xah->exit();
 
-        list_del_init (p);
-    }
-    INIT_LIST_HEAD (&xattr_handlers);
+		list_del_init(p);
+	}
+	INIT_LIST_HEAD(&xattr_handlers);
 }
 
-int __init
-reiserfs_xattr_register_handlers (void)
+int __init reiserfs_xattr_register_handlers(void)
 {
-    int err = 0;
-    struct reiserfs_xattr_handler *xah;
-    struct list_head *p;
+	int err = 0;
+	struct reiserfs_xattr_handler *xah;
+	struct list_head *p;
 
-    write_lock (&handler_lock);
+	write_lock(&handler_lock);
 
-    /* If we're already initialized, nothing to do */
-    if (!list_empty (&xattr_handlers)) {
-        write_unlock (&handler_lock);
-        return 0;
-    }
+	/* If we're already initialized, nothing to do */
+	if (!list_empty(&xattr_handlers)) {
+		write_unlock(&handler_lock);
+		return 0;
+	}
 
-    /* Add the handlers */
-    list_add_tail (&user_handler.handlers, &xattr_handlers);
-    list_add_tail (&trusted_handler.handlers, &xattr_handlers);
+	/* Add the handlers */
+	list_add_tail(&user_handler.handlers, &xattr_handlers);
+	list_add_tail(&trusted_handler.handlers, &xattr_handlers);
 #ifdef CONFIG_REISERFS_FS_SECURITY
-    list_add_tail (&security_handler.handlers, &xattr_handlers);
+	list_add_tail(&security_handler.handlers, &xattr_handlers);
 #endif
 #ifdef CONFIG_REISERFS_FS_POSIX_ACL
-    list_add_tail (&posix_acl_access_handler.handlers, &xattr_handlers);
-    list_add_tail (&posix_acl_default_handler.handlers, &xattr_handlers);
+	list_add_tail(&posix_acl_access_handler.handlers, &xattr_handlers);
+	list_add_tail(&posix_acl_default_handler.handlers, &xattr_handlers);
 #endif
 
-    /* Run initializers, if available */
-    list_for_each (p, &xattr_handlers) {
-        xah = list_entry (p, struct reiserfs_xattr_handler, handlers);
-        if (xah->init) {
-            err = xah->init ();
-            if (err) {
-                list_del_init (p);
-                break;
-            }
-        }
-    }
-
-    /* Clean up other handlers, if any failed */
-    if (err)
-        __unregister_handlers ();
-
-    write_unlock (&handler_lock);
-    return err;
-}
-
-void
-reiserfs_xattr_unregister_handlers (void)
-{
-    write_lock (&handler_lock);
-    __unregister_handlers ();
-    write_unlock (&handler_lock);
+	/* Run initializers, if available */
+	list_for_each(p, &xattr_handlers) {
+		xah = list_entry(p, struct reiserfs_xattr_handler, handlers);
+		if (xah->init) {
+			err = xah->init();
+			if (err) {
+				list_del_init(p);
+				break;
+			}
+		}
+	}
+
+	/* Clean up other handlers, if any failed */
+	if (err)
+		__unregister_handlers();
+
+	write_unlock(&handler_lock);
+	return err;
+}
+
+void reiserfs_xattr_unregister_handlers(void)
+{
+	write_lock(&handler_lock);
+	__unregister_handlers();
+	write_unlock(&handler_lock);
 }
 
 /* This will catch lookups from the fs root to .reiserfs_priv */
 static int
-xattr_lookup_poison (struct dentry *dentry, struct qstr *q1, struct qstr *name)
+xattr_lookup_poison(struct dentry *dentry, struct qstr *q1, struct qstr *name)
 {
-    struct dentry *priv_root = REISERFS_SB(dentry->d_sb)->priv_root;
-    if (name->len == priv_root->d_name.len &&
-        name->hash == priv_root->d_name.hash &&
-        !memcmp (name->name, priv_root->d_name.name, name->len)) {
-            return -ENOENT;
-    } else if (q1->len == name->len &&
-               !memcmp(q1->name, name->name, name->len))
-        return 0;
-    return 1;
+	struct dentry *priv_root = REISERFS_SB(dentry->d_sb)->priv_root;
+	if (name->len == priv_root->d_name.len &&
+	    name->hash == priv_root->d_name.hash &&
+	    !memcmp(name->name, priv_root->d_name.name, name->len)) {
+		return -ENOENT;
+	} else if (q1->len == name->len &&
+		   !memcmp(q1->name, name->name, name->len))
+		return 0;
+	return 1;
 }
 
 static struct dentry_operations xattr_lookup_poison_ops = {
-    .d_compare = xattr_lookup_poison,
+	.d_compare = xattr_lookup_poison,
 };
 
-
 /* We need to take a copy of the mount flags since things like
  * MS_RDONLY don't get set until *after* we're called.
  * mount_flags != mount_options */
-int
-reiserfs_xattr_init (struct super_block *s, int mount_flags)
+int reiserfs_xattr_init(struct super_block *s, int mount_flags)
 {
-  int err = 0;
+	int err = 0;
+
+	/* We need generation numbers to ensure that the oid mapping is correct
+	 * v3.5 filesystems don't have them. */
+	if (!old_format_only(s)) {
+		set_bit(REISERFS_XATTRS, &(REISERFS_SB(s)->s_mount_opt));
+	} else if (reiserfs_xattrs_optional(s)) {
+		/* Old format filesystem, but optional xattrs have been enabled
+		 * at mount time. Error out. */
+		reiserfs_warning(s, "xattrs/ACLs not supported on pre v3.6 "
+				 "format filesystem. Failing mount.");
+		err = -EOPNOTSUPP;
+		goto error;
+	} else {
+		/* Old format filesystem, but no optional xattrs have been enabled. This
+		 * means we silently disable xattrs on the filesystem. */
+		clear_bit(REISERFS_XATTRS, &(REISERFS_SB(s)->s_mount_opt));
+	}
+
+	/* If we don't have the privroot located yet - go find it */
+	if (reiserfs_xattrs(s) && !REISERFS_SB(s)->priv_root) {
+		struct dentry *dentry;
+		dentry = lookup_one_len(PRIVROOT_NAME, s->s_root,
+					strlen(PRIVROOT_NAME));
+		if (!IS_ERR(dentry)) {
+			if (!(mount_flags & MS_RDONLY) && !dentry->d_inode) {
+				struct inode *inode = dentry->d_parent->d_inode;
+				down(&inode->i_sem);
+				err = inode->i_op->mkdir(inode, dentry, 0700);
+				up(&inode->i_sem);
+				if (err) {
+					dput(dentry);
+					dentry = NULL;
+				}
+
+				if (dentry && dentry->d_inode)
+					reiserfs_warning(s,
+							 "Created %s on %s - reserved for "
+							 "xattr storage.",
+							 PRIVROOT_NAME,
+							 reiserfs_bdevname
+							 (inode->i_sb));
+			} else if (!dentry->d_inode) {
+				dput(dentry);
+				dentry = NULL;
+			}
+		} else
+			err = PTR_ERR(dentry);
+
+		if (!err && dentry) {
+			s->s_root->d_op = &xattr_lookup_poison_ops;
+			reiserfs_mark_inode_private(dentry->d_inode);
+			REISERFS_SB(s)->priv_root = dentry;
+		} else if (!(mount_flags & MS_RDONLY)) {	/* xattrs are unavailable */
+			/* If we're read-only it just means that the dir hasn't been
+			 * created. Not an error -- just no xattrs on the fs. We'll
+			 * check again if we go read-write */
+			reiserfs_warning(s, "xattrs/ACLs enabled and couldn't "
+					 "find/create .reiserfs_priv. Failing mount.");
+			err = -EOPNOTSUPP;
+		}
+	}
 
-  /* We need generation numbers to ensure that the oid mapping is correct
-   * v3.5 filesystems don't have them. */
-  if (!old_format_only (s)) {
-    set_bit (REISERFS_XATTRS, &(REISERFS_SB(s)->s_mount_opt));
-  } else if (reiserfs_xattrs_optional (s)) {
-    /* Old format filesystem, but optional xattrs have been enabled
-     * at mount time. Error out. */
-    reiserfs_warning (s, "xattrs/ACLs not supported on pre v3.6 "
-                      "format filesystem. Failing mount.");
-    err = -EOPNOTSUPP;
-    goto error;
-  } else {
-    /* Old format filesystem, but no optional xattrs have been enabled. This
-     * means we silently disable xattrs on the filesystem. */
-    clear_bit (REISERFS_XATTRS, &(REISERFS_SB(s)->s_mount_opt));
-  }
-
-  /* If we don't have the privroot located yet - go find it */
-  if (reiserfs_xattrs (s) && !REISERFS_SB(s)->priv_root) {
-      struct dentry *dentry;
-      dentry = lookup_one_len (PRIVROOT_NAME, s->s_root,
-                               strlen (PRIVROOT_NAME));
-      if (!IS_ERR (dentry)) {
-        if (!(mount_flags & MS_RDONLY) && !dentry->d_inode) {
-            struct inode *inode = dentry->d_parent->d_inode;
-            down (&inode->i_sem);
-            err = inode->i_op->mkdir (inode, dentry, 0700);
-            up (&inode->i_sem);
-            if (err) {
-                dput (dentry);
-                dentry = NULL;
-            }
-
-            if (dentry && dentry->d_inode)
-                reiserfs_warning (s, "Created %s on %s - reserved for "
-                                  "xattr storage.", PRIVROOT_NAME,
-                                  reiserfs_bdevname (inode->i_sb));
-        } else if (!dentry->d_inode) {
-            dput (dentry);
-            dentry = NULL;
-        }
-      } else
-        err = PTR_ERR (dentry);
-
-      if (!err && dentry) {
-          s->s_root->d_op = &xattr_lookup_poison_ops;
-          reiserfs_mark_inode_private (dentry->d_inode);
-          REISERFS_SB(s)->priv_root = dentry;
-      } else if (!(mount_flags & MS_RDONLY)) { /* xattrs are unavailable */
-          /* If we're read-only it just means that the dir hasn't been
-           * created. Not an error -- just no xattrs on the fs. We'll
-           * check again if we go read-write */
-          reiserfs_warning (s, "xattrs/ACLs enabled and couldn't "
-                            "find/create .reiserfs_priv. Failing mount.");
-          err = -EOPNOTSUPP;
-      }
-  }
-
-error:
-   /* This is only nonzero if there was an error initializing the xattr
-    * directory or if there is a condition where we don't support them. */
-    if (err) {
-          clear_bit (REISERFS_XATTRS, &(REISERFS_SB(s)->s_mount_opt));
-          clear_bit (REISERFS_XATTRS_USER, &(REISERFS_SB(s)->s_mount_opt));
-          clear_bit (REISERFS_POSIXACL, &(REISERFS_SB(s)->s_mount_opt));
-    }
-
-    /* The super_block MS_POSIXACL must mirror the (no)acl mount option. */
-    s->s_flags = s->s_flags & ~MS_POSIXACL;
-    if (reiserfs_posixacl (s))
-	s->s_flags |= MS_POSIXACL;
+      error:
+	/* This is only nonzero if there was an error initializing the xattr
+	 * directory or if there is a condition where we don't support them. */
+	if (err) {
+		clear_bit(REISERFS_XATTRS, &(REISERFS_SB(s)->s_mount_opt));
+		clear_bit(REISERFS_XATTRS_USER, &(REISERFS_SB(s)->s_mount_opt));
+		clear_bit(REISERFS_POSIXACL, &(REISERFS_SB(s)->s_mount_opt));
+	}
 
-    return err;
+	/* The super_block MS_POSIXACL must mirror the (no)acl mount option. */
+	s->s_flags = s->s_flags & ~MS_POSIXACL;
+	if (reiserfs_posixacl(s))
+		s->s_flags |= MS_POSIXACL;
+
+	return err;
 }
 
 static int
-__reiserfs_permission (struct inode *inode, int mask, struct nameidata *nd,
-                       int need_lock)
+__reiserfs_permission(struct inode *inode, int mask, struct nameidata *nd,
+		      int need_lock)
 {
-	umode_t			mode = inode->i_mode;
+	umode_t mode = inode->i_mode;
 
 	if (mask & MAY_WRITE) {
 		/*
@@ -1363,50 +1364,50 @@ __reiserfs_permission (struct inode *ino
 	}
 
 	/* We don't do permission checks on the internal objects.
-	* Permissions are determined by the "owning" object. */
-        if (is_reiserfs_priv_object (inode))
+	 * Permissions are determined by the "owning" object. */
+	if (is_reiserfs_priv_object(inode))
 		return 0;
 
 	if (current->fsuid == inode->i_uid) {
 		mode >>= 6;
 #ifdef CONFIG_REISERFS_FS_POSIX_ACL
 	} else if (reiserfs_posixacl(inode->i_sb) &&
-                   get_inode_sd_version (inode) != STAT_DATA_V1) {
-                struct posix_acl *acl;
+		   get_inode_sd_version(inode) != STAT_DATA_V1) {
+		struct posix_acl *acl;
 
 		/* ACL can't contain additional permissions if
 		   the ACL_MASK entry is 0 */
 		if (!(mode & S_IRWXG))
 			goto check_groups;
 
-                if (need_lock) {
-		    reiserfs_read_lock_xattr_i (inode);
-                    reiserfs_read_lock_xattrs (inode->i_sb);
-		}
-                acl = reiserfs_get_acl (inode, ACL_TYPE_ACCESS);
-                if (need_lock) {
-                    reiserfs_read_unlock_xattrs (inode->i_sb);
-		    reiserfs_read_unlock_xattr_i (inode);
-		}
-                if (IS_ERR (acl)) {
-                    if (PTR_ERR (acl) == -ENODATA)
-                        goto check_groups;
-                    return PTR_ERR (acl);
-                }
-
-                if (acl) {
-                    int err = posix_acl_permission (inode, acl, mask);
-                    posix_acl_release (acl);
-                    if (err == -EACCES) {
-                        goto check_capabilities;
-                    }
-                    return err;
+		if (need_lock) {
+			reiserfs_read_lock_xattr_i(inode);
+			reiserfs_read_lock_xattrs(inode->i_sb);
+		}
+		acl = reiserfs_get_acl(inode, ACL_TYPE_ACCESS);
+		if (need_lock) {
+			reiserfs_read_unlock_xattrs(inode->i_sb);
+			reiserfs_read_unlock_xattr_i(inode);
+		}
+		if (IS_ERR(acl)) {
+			if (PTR_ERR(acl) == -ENODATA)
+				goto check_groups;
+			return PTR_ERR(acl);
+		}
+
+		if (acl) {
+			int err = posix_acl_permission(inode, acl, mask);
+			posix_acl_release(acl);
+			if (err == -EACCES) {
+				goto check_capabilities;
+			}
+			return err;
 		} else {
 			goto check_groups;
-                }
+		}
 #endif
 	} else {
-check_groups:
+	      check_groups:
 		if (in_group_p(inode->i_gid))
 			mode >>= 3;
 	}
@@ -1414,10 +1415,10 @@ check_groups:
 	/*
 	 * If the DACs are ok we don't need any capability check.
 	 */
-	if (((mode & mask & (MAY_READ|MAY_WRITE|MAY_EXEC)) == mask))
+	if (((mode & mask & (MAY_READ | MAY_WRITE | MAY_EXEC)) == mask))
 		return 0;
 
-check_capabilities:
+      check_capabilities:
 	/*
 	 * Read/write DACs are always overridable.
 	 * Executable DACs are overridable if at least one exec bit is set.
@@ -1437,14 +1438,13 @@ check_capabilities:
 	return -EACCES;
 }
 
-int
-reiserfs_permission (struct inode *inode, int mask, struct nameidata *nd)
+int reiserfs_permission(struct inode *inode, int mask, struct nameidata *nd)
 {
-    return __reiserfs_permission (inode, mask, nd, 1);
+	return __reiserfs_permission(inode, mask, nd, 1);
 }
 
 int
-reiserfs_permission_locked (struct inode *inode, int mask, struct nameidata *nd)
+reiserfs_permission_locked(struct inode *inode, int mask, struct nameidata *nd)
 {
-    return __reiserfs_permission (inode, mask, nd, 0);
+	return __reiserfs_permission(inode, mask, nd, 0);
 }
diff --git a/fs/reiserfs/xattr_acl.c b/fs/reiserfs/xattr_acl.c
--- a/fs/reiserfs/xattr_acl.c
+++ b/fs/reiserfs/xattr_acl.c
@@ -4,12 +4,13 @@
 #include <linux/errno.h>
 #include <linux/pagemap.h>
 #include <linux/xattr.h>
-#include <linux/xattr_acl.h>
+#include <linux/posix_acl_xattr.h>
 #include <linux/reiserfs_xattr.h>
 #include <linux/reiserfs_acl.h>
 #include <asm/uaccess.h>
 
-static int reiserfs_set_acl(struct inode *inode, int type, struct posix_acl *acl);
+static int reiserfs_set_acl(struct inode *inode, int type,
+			    struct posix_acl *acl);
 
 static int
 xattr_set_acl(struct inode *inode, int type, const void *value, size_t size)
@@ -34,14 +35,13 @@ xattr_set_acl(struct inode *inode, int t
 	} else
 		acl = NULL;
 
-	error = reiserfs_set_acl (inode, type, acl);
+	error = reiserfs_set_acl(inode, type, acl);
 
-release_and_out:
+      release_and_out:
 	posix_acl_release(acl);
 	return error;
 }
 
-
 static int
 xattr_get_acl(struct inode *inode, int type, void *buffer, size_t size)
 {
@@ -51,7 +51,7 @@ xattr_get_acl(struct inode *inode, int t
 	if (!reiserfs_posixacl(inode->i_sb))
 		return -EOPNOTSUPP;
 
-	acl = reiserfs_get_acl (inode, type);
+	acl = reiserfs_get_acl(inode, type);
 	if (IS_ERR(acl))
 		return PTR_ERR(acl);
 	if (acl == NULL)
@@ -62,12 +62,10 @@ xattr_get_acl(struct inode *inode, int t
 	return error;
 }
 
-
 /*
  * Convert from filesystem to in-memory representation.
  */
-static struct posix_acl *
-posix_acl_from_disk(const void *value, size_t size)
+static struct posix_acl *posix_acl_from_disk(const void *value, size_t size)
 {
 	const char *end = (char *)value + size;
 	int n, count;
@@ -76,8 +74,8 @@ posix_acl_from_disk(const void *value, s
 	if (!value)
 		return NULL;
 	if (size < sizeof(reiserfs_acl_header))
-		 return ERR_PTR(-EINVAL);
-	if (((reiserfs_acl_header *)value)->a_version !=
+		return ERR_PTR(-EINVAL);
+	if (((reiserfs_acl_header *) value)->a_version !=
 	    cpu_to_le32(REISERFS_ACL_VERSION))
 		return ERR_PTR(-EINVAL);
 	value = (char *)value + sizeof(reiserfs_acl_header);
@@ -89,41 +87,39 @@ posix_acl_from_disk(const void *value, s
 	acl = posix_acl_alloc(count, GFP_NOFS);
 	if (!acl)
 		return ERR_PTR(-ENOMEM);
-	for (n=0; n < count; n++) {
-		reiserfs_acl_entry *entry =
-			(reiserfs_acl_entry *)value;
+	for (n = 0; n < count; n++) {
+		reiserfs_acl_entry *entry = (reiserfs_acl_entry *) value;
 		if ((char *)value + sizeof(reiserfs_acl_entry_short) > end)
 			goto fail;
-		acl->a_entries[n].e_tag  = le16_to_cpu(entry->e_tag);
+		acl->a_entries[n].e_tag = le16_to_cpu(entry->e_tag);
 		acl->a_entries[n].e_perm = le16_to_cpu(entry->e_perm);
-		switch(acl->a_entries[n].e_tag) {
-			case ACL_USER_OBJ:
-			case ACL_GROUP_OBJ:
-			case ACL_MASK:
-			case ACL_OTHER:
-				value = (char *)value +
-					sizeof(reiserfs_acl_entry_short);
-				acl->a_entries[n].e_id = ACL_UNDEFINED_ID;
-				break;
-
-			case ACL_USER:
-			case ACL_GROUP:
-				value = (char *)value + sizeof(reiserfs_acl_entry);
-				if ((char *)value > end)
-					goto fail;
-				acl->a_entries[n].e_id =
-					le32_to_cpu(entry->e_id);
-				break;
-
-			default:
+		switch (acl->a_entries[n].e_tag) {
+		case ACL_USER_OBJ:
+		case ACL_GROUP_OBJ:
+		case ACL_MASK:
+		case ACL_OTHER:
+			value = (char *)value +
+			    sizeof(reiserfs_acl_entry_short);
+			acl->a_entries[n].e_id = ACL_UNDEFINED_ID;
+			break;
+
+		case ACL_USER:
+		case ACL_GROUP:
+			value = (char *)value + sizeof(reiserfs_acl_entry);
+			if ((char *)value > end)
 				goto fail;
+			acl->a_entries[n].e_id = le32_to_cpu(entry->e_id);
+			break;
+
+		default:
+			goto fail;
 		}
 	}
 	if (value != end)
 		goto fail;
 	return acl;
 
-fail:
+      fail:
 	posix_acl_release(acl);
 	return ERR_PTR(-EINVAL);
 }
@@ -131,46 +127,46 @@ fail:
 /*
  * Convert from in-memory to filesystem representation.
  */
-static void *
-posix_acl_to_disk(const struct posix_acl *acl, size_t *size)
+static void *posix_acl_to_disk(const struct posix_acl *acl, size_t * size)
 {
 	reiserfs_acl_header *ext_acl;
 	char *e;
 	int n;
 
 	*size = reiserfs_acl_size(acl->a_count);
-	ext_acl = (reiserfs_acl_header *)kmalloc(sizeof(reiserfs_acl_header) +
-		acl->a_count * sizeof(reiserfs_acl_entry), GFP_NOFS);
+	ext_acl = (reiserfs_acl_header *) kmalloc(sizeof(reiserfs_acl_header) +
+						  acl->a_count *
+						  sizeof(reiserfs_acl_entry),
+						  GFP_NOFS);
 	if (!ext_acl)
 		return ERR_PTR(-ENOMEM);
 	ext_acl->a_version = cpu_to_le32(REISERFS_ACL_VERSION);
 	e = (char *)ext_acl + sizeof(reiserfs_acl_header);
-	for (n=0; n < acl->a_count; n++) {
-		reiserfs_acl_entry *entry = (reiserfs_acl_entry *)e;
-		entry->e_tag  = cpu_to_le16(acl->a_entries[n].e_tag);
+	for (n = 0; n < acl->a_count; n++) {
+		reiserfs_acl_entry *entry = (reiserfs_acl_entry *) e;
+		entry->e_tag = cpu_to_le16(acl->a_entries[n].e_tag);
 		entry->e_perm = cpu_to_le16(acl->a_entries[n].e_perm);
-		switch(acl->a_entries[n].e_tag) {
-			case ACL_USER:
-			case ACL_GROUP:
-				entry->e_id =
-					cpu_to_le32(acl->a_entries[n].e_id);
-				e += sizeof(reiserfs_acl_entry);
-				break;
-
-			case ACL_USER_OBJ:
-			case ACL_GROUP_OBJ:
-			case ACL_MASK:
-			case ACL_OTHER:
-				e += sizeof(reiserfs_acl_entry_short);
-				break;
+		switch (acl->a_entries[n].e_tag) {
+		case ACL_USER:
+		case ACL_GROUP:
+			entry->e_id = cpu_to_le32(acl->a_entries[n].e_id);
+			e += sizeof(reiserfs_acl_entry);
+			break;
+
+		case ACL_USER_OBJ:
+		case ACL_GROUP_OBJ:
+		case ACL_MASK:
+		case ACL_OTHER:
+			e += sizeof(reiserfs_acl_entry_short);
+			break;
 
-			default:
-				goto fail;
+		default:
+			goto fail;
 		}
 	}
 	return (char *)ext_acl;
 
-fail:
+      fail:
 	kfree(ext_acl);
 	return ERR_PTR(-EINVAL);
 }
@@ -181,59 +177,58 @@ fail:
  * inode->i_sem: down
  * BKL held [before 2.5.x]
  */
-struct posix_acl *
-reiserfs_get_acl(struct inode *inode, int type)
+struct posix_acl *reiserfs_get_acl(struct inode *inode, int type)
 {
 	char *name, *value;
 	struct posix_acl *acl, **p_acl;
 	size_t size;
 	int retval;
-        struct reiserfs_inode_info *reiserfs_i = REISERFS_I(inode);
+	struct reiserfs_inode_info *reiserfs_i = REISERFS_I(inode);
 
-        switch (type) {
-            case ACL_TYPE_ACCESS:
-                name = XATTR_NAME_ACL_ACCESS;
-                p_acl = &reiserfs_i->i_acl_access;
-                break;
-            case ACL_TYPE_DEFAULT:
-                name = XATTR_NAME_ACL_DEFAULT;
-                p_acl = &reiserfs_i->i_acl_default;
-                break;
-            default:
-                return ERR_PTR (-EINVAL);
-        }
-
-        if (IS_ERR (*p_acl)) {
-            if (PTR_ERR (*p_acl) == -ENODATA)
-                return NULL;
-        } else if (*p_acl != NULL)
-            return posix_acl_dup (*p_acl);
-
-        size = reiserfs_xattr_get (inode, name, NULL, 0);
-        if ((int)size < 0) {
-            if (size == -ENODATA || size == -ENOSYS) {
-		*p_acl = ERR_PTR (-ENODATA);
-		return NULL;
-            }
-            return ERR_PTR (size);
-        }
-
-        value = kmalloc (size, GFP_NOFS);
-        if (!value)
-            return ERR_PTR (-ENOMEM);
+	switch (type) {
+	case ACL_TYPE_ACCESS:
+		name = POSIX_ACL_XATTR_ACCESS;
+		p_acl = &reiserfs_i->i_acl_access;
+		break;
+	case ACL_TYPE_DEFAULT:
+		name = POSIX_ACL_XATTR_DEFAULT;
+		p_acl = &reiserfs_i->i_acl_default;
+		break;
+	default:
+		return ERR_PTR(-EINVAL);
+	}
+
+	if (IS_ERR(*p_acl)) {
+		if (PTR_ERR(*p_acl) == -ENODATA)
+			return NULL;
+	} else if (*p_acl != NULL)
+		return posix_acl_dup(*p_acl);
+
+	size = reiserfs_xattr_get(inode, name, NULL, 0);
+	if ((int)size < 0) {
+		if (size == -ENODATA || size == -ENOSYS) {
+			*p_acl = ERR_PTR(-ENODATA);
+			return NULL;
+		}
+		return ERR_PTR(size);
+	}
+
+	value = kmalloc(size, GFP_NOFS);
+	if (!value)
+		return ERR_PTR(-ENOMEM);
 
 	retval = reiserfs_xattr_get(inode, name, value, size);
 	if (retval == -ENODATA || retval == -ENOSYS) {
 		/* This shouldn't actually happen as it should have
 		   been caught above.. but just in case */
 		acl = NULL;
-		*p_acl = ERR_PTR (-ENODATA);
-        } else if (retval < 0) {
+		*p_acl = ERR_PTR(-ENODATA);
+	} else if (retval < 0) {
 		acl = ERR_PTR(retval);
 	} else {
 		acl = posix_acl_from_disk(value, retval);
-		*p_acl = posix_acl_dup (acl);
-        }
+		*p_acl = posix_acl_dup(acl);
+	}
 
 	kfree(value);
 	return acl;
@@ -248,72 +243,72 @@ reiserfs_get_acl(struct inode *inode, in
 static int
 reiserfs_set_acl(struct inode *inode, int type, struct posix_acl *acl)
 {
-        char *name;
+	char *name;
 	void *value = NULL;
 	struct posix_acl **p_acl;
 	size_t size;
 	int error;
-        struct reiserfs_inode_info *reiserfs_i = REISERFS_I(inode);
+	struct reiserfs_inode_info *reiserfs_i = REISERFS_I(inode);
 
 	if (S_ISLNK(inode->i_mode))
 		return -EOPNOTSUPP;
 
-        switch (type) {
-            case ACL_TYPE_ACCESS:
-                name = XATTR_NAME_ACL_ACCESS;
-                p_acl = &reiserfs_i->i_acl_access;
-                if (acl) {
-                    mode_t mode = inode->i_mode;
-                    error = posix_acl_equiv_mode (acl, &mode);
-                    if (error < 0)
-                        return error;
-                    else {
-                        inode->i_mode = mode;
-                        if (error == 0)
-                            acl = NULL;
-                    }
-                }
-                break;
-            case ACL_TYPE_DEFAULT:
-                name = XATTR_NAME_ACL_DEFAULT;
-                p_acl = &reiserfs_i->i_acl_default;
-                if (!S_ISDIR (inode->i_mode))
-                    return acl ? -EACCES : 0;
-                break;
-            default:
-                return -EINVAL;
-        }
-
- 	if (acl) {
-            value = posix_acl_to_disk(acl, &size);
-            if (IS_ERR(value))
-                return (int)PTR_ERR(value);
-            error = reiserfs_xattr_set(inode, name, value, size, 0);
+	switch (type) {
+	case ACL_TYPE_ACCESS:
+		name = POSIX_ACL_XATTR_ACCESS;
+		p_acl = &reiserfs_i->i_acl_access;
+		if (acl) {
+			mode_t mode = inode->i_mode;
+			error = posix_acl_equiv_mode(acl, &mode);
+			if (error < 0)
+				return error;
+			else {
+				inode->i_mode = mode;
+				if (error == 0)
+					acl = NULL;
+			}
+		}
+		break;
+	case ACL_TYPE_DEFAULT:
+		name = POSIX_ACL_XATTR_DEFAULT;
+		p_acl = &reiserfs_i->i_acl_default;
+		if (!S_ISDIR(inode->i_mode))
+			return acl ? -EACCES : 0;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	if (acl) {
+		value = posix_acl_to_disk(acl, &size);
+		if (IS_ERR(value))
+			return (int)PTR_ERR(value);
+		error = reiserfs_xattr_set(inode, name, value, size, 0);
 	} else {
-            error = reiserfs_xattr_del (inode, name);
-            if (error == -ENODATA) {
-                /* This may seem odd here, but it means that the ACL was set
-                 * with a value representable with mode bits. If there was
-                 * an ACL before, reiserfs_xattr_del already dirtied the inode.
-                 */
-                mark_inode_dirty (inode);
-                error = 0;
-            }
-        }
+		error = reiserfs_xattr_del(inode, name);
+		if (error == -ENODATA) {
+			/* This may seem odd here, but it means that the ACL was set
+			 * with a value representable with mode bits. If there was
+			 * an ACL before, reiserfs_xattr_del already dirtied the inode.
+			 */
+			mark_inode_dirty(inode);
+			error = 0;
+		}
+	}
 
 	if (value)
 		kfree(value);
 
-        if (!error) {
-            /* Release the old one */
-            if (!IS_ERR (*p_acl) && *p_acl)
-                posix_acl_release (*p_acl);
-
-            if (acl == NULL)
-                *p_acl = ERR_PTR (-ENODATA);
-            else
-                *p_acl = posix_acl_dup (acl);
-        }
+	if (!error) {
+		/* Release the old one */
+		if (!IS_ERR(*p_acl) && *p_acl)
+			posix_acl_release(*p_acl);
+
+		if (acl == NULL)
+			*p_acl = ERR_PTR(-ENODATA);
+		else
+			*p_acl = posix_acl_dup(acl);
+	}
 
 	return error;
 }
@@ -321,196 +316,194 @@ reiserfs_set_acl(struct inode *inode, in
 /* dir->i_sem: down,
  * inode is new and not released into the wild yet */
 int
-reiserfs_inherit_default_acl (struct inode *dir, struct dentry *dentry, struct inode *inode)
+reiserfs_inherit_default_acl(struct inode *dir, struct dentry *dentry,
+			     struct inode *inode)
 {
-    struct posix_acl *acl;
-    int err = 0;
+	struct posix_acl *acl;
+	int err = 0;
+
+	/* ACLs only get applied to files and directories */
+	if (S_ISLNK(inode->i_mode))
+		return 0;
+
+	/* ACLs can only be used on "new" objects, so if it's an old object
+	 * there is nothing to inherit from */
+	if (get_inode_sd_version(dir) == STAT_DATA_V1)
+		goto apply_umask;
+
+	/* Don't apply ACLs to objects in the .reiserfs_priv tree.. This
+	 * would be useless since permissions are ignored, and a pain because
+	 * it introduces locking cycles */
+	if (is_reiserfs_priv_object(dir)) {
+		reiserfs_mark_inode_private(inode);
+		goto apply_umask;
+	}
+
+	acl = reiserfs_get_acl(dir, ACL_TYPE_DEFAULT);
+	if (IS_ERR(acl)) {
+		if (PTR_ERR(acl) == -ENODATA)
+			goto apply_umask;
+		return PTR_ERR(acl);
+	}
+
+	if (acl) {
+		struct posix_acl *acl_copy;
+		mode_t mode = inode->i_mode;
+		int need_acl;
+
+		/* Copy the default ACL to the default ACL of a new directory */
+		if (S_ISDIR(inode->i_mode)) {
+			err = reiserfs_set_acl(inode, ACL_TYPE_DEFAULT, acl);
+			if (err)
+				goto cleanup;
+		}
 
-    /* ACLs only get applied to files and directories */
-    if (S_ISLNK (inode->i_mode))
-        return 0;
-
-    /* ACLs can only be used on "new" objects, so if it's an old object
-     * there is nothing to inherit from */
-    if (get_inode_sd_version (dir) == STAT_DATA_V1)
-        goto apply_umask;
-
-    /* Don't apply ACLs to objects in the .reiserfs_priv tree.. This
-     * would be useless since permissions are ignored, and a pain because
-     * it introduces locking cycles */
-    if (is_reiserfs_priv_object (dir)) {
-        reiserfs_mark_inode_private (inode);
-        goto apply_umask;
-    }
-
-    acl = reiserfs_get_acl (dir, ACL_TYPE_DEFAULT);
-    if (IS_ERR (acl)) {
-        if (PTR_ERR (acl) == -ENODATA)
-            goto apply_umask;
-        return PTR_ERR (acl);
-    }
-
-    if (acl) {
-        struct posix_acl *acl_copy;
-        mode_t mode = inode->i_mode;
-        int need_acl;
-
-        /* Copy the default ACL to the default ACL of a new directory */
-        if (S_ISDIR (inode->i_mode)) {
-            err = reiserfs_set_acl (inode, ACL_TYPE_DEFAULT, acl);
-            if (err)
-                goto cleanup;
-        }
-
-        /* Now we reconcile the new ACL and the mode,
-           potentially modifying both */
-        acl_copy = posix_acl_clone (acl, GFP_NOFS);
-        if (!acl_copy) {
-            err = -ENOMEM;
-            goto cleanup;
-        }
-
-
-        need_acl = posix_acl_create_masq (acl_copy, &mode);
-        if (need_acl >= 0) {
-            if (mode != inode->i_mode) {
-                inode->i_mode = mode;
-            }
-
-            /* If we need an ACL.. */
-            if (need_acl > 0) {
-                err = reiserfs_set_acl (inode, ACL_TYPE_ACCESS, acl_copy);
-                if (err)
-                    goto cleanup_copy;
-            }
-        }
-cleanup_copy:
-        posix_acl_release (acl_copy);
-cleanup:
-        posix_acl_release (acl);
-    } else {
-apply_umask:
-        /* no ACL, apply umask */
-        inode->i_mode &= ~current->fs->umask;
-    }
+		/* Now we reconcile the new ACL and the mode,
+		   potentially modifying both */
+		acl_copy = posix_acl_clone(acl, GFP_NOFS);
+		if (!acl_copy) {
+			err = -ENOMEM;
+			goto cleanup;
+		}
+
+		need_acl = posix_acl_create_masq(acl_copy, &mode);
+		if (need_acl >= 0) {
+			if (mode != inode->i_mode) {
+				inode->i_mode = mode;
+			}
+
+			/* If we need an ACL.. */
+			if (need_acl > 0) {
+				err =
+				    reiserfs_set_acl(inode, ACL_TYPE_ACCESS,
+						     acl_copy);
+				if (err)
+					goto cleanup_copy;
+			}
+		}
+	      cleanup_copy:
+		posix_acl_release(acl_copy);
+	      cleanup:
+		posix_acl_release(acl);
+	} else {
+	      apply_umask:
+		/* no ACL, apply umask */
+		inode->i_mode &= ~current->fs->umask;
+	}
 
-    return err;
+	return err;
 }
 
 /* Looks up and caches the result of the default ACL.
  * We do this so that we don't need to carry the xattr_sem into
  * reiserfs_new_inode if we don't need to */
-int
-reiserfs_cache_default_acl (struct inode *inode)
+int reiserfs_cache_default_acl(struct inode *inode)
 {
-    int ret = 0;
-    if (reiserfs_posixacl (inode->i_sb) &&
-        !is_reiserfs_priv_object (inode)) {
-        struct posix_acl *acl;
-        reiserfs_read_lock_xattr_i (inode);
-        reiserfs_read_lock_xattrs (inode->i_sb);
-        acl = reiserfs_get_acl (inode, ACL_TYPE_DEFAULT);
-        reiserfs_read_unlock_xattrs (inode->i_sb);
-        reiserfs_read_unlock_xattr_i (inode);
-        ret = acl ? 1 : 0;
-        posix_acl_release (acl);
-    }
+	int ret = 0;
+	if (reiserfs_posixacl(inode->i_sb) && !is_reiserfs_priv_object(inode)) {
+		struct posix_acl *acl;
+		reiserfs_read_lock_xattr_i(inode);
+		reiserfs_read_lock_xattrs(inode->i_sb);
+		acl = reiserfs_get_acl(inode, ACL_TYPE_DEFAULT);
+		reiserfs_read_unlock_xattrs(inode->i_sb);
+		reiserfs_read_unlock_xattr_i(inode);
+		ret = acl ? 1 : 0;
+		posix_acl_release(acl);
+	}
 
-    return ret;
+	return ret;
 }
 
-int
-reiserfs_acl_chmod (struct inode *inode)
+int reiserfs_acl_chmod(struct inode *inode)
 {
-        struct posix_acl *acl, *clone;
-        int error;
+	struct posix_acl *acl, *clone;
+	int error;
 
-        if (S_ISLNK(inode->i_mode))
-                return -EOPNOTSUPP;
+	if (S_ISLNK(inode->i_mode))
+		return -EOPNOTSUPP;
 
-	if (get_inode_sd_version (inode) == STAT_DATA_V1 ||
-	    !reiserfs_posixacl(inode->i_sb))
-        {
-	    return 0;
-	}
-
-        reiserfs_read_lock_xattrs (inode->i_sb);
-        acl = reiserfs_get_acl(inode, ACL_TYPE_ACCESS);
-        reiserfs_read_unlock_xattrs (inode->i_sb);
-        if (!acl)
-                return 0;
-        if (IS_ERR(acl))
-                return PTR_ERR(acl);
-        clone = posix_acl_clone(acl, GFP_NOFS);
-        posix_acl_release(acl);
-        if (!clone)
-                return -ENOMEM;
-        error = posix_acl_chmod_masq(clone, inode->i_mode);
-        if (!error) {
-                int lock = !has_xattr_dir (inode);
-                reiserfs_write_lock_xattr_i (inode);
-                if (lock)
-                    reiserfs_write_lock_xattrs (inode->i_sb);
-                else
-                    reiserfs_read_lock_xattrs (inode->i_sb);
-                error = reiserfs_set_acl(inode, ACL_TYPE_ACCESS, clone);
-                if (lock)
-                    reiserfs_write_unlock_xattrs (inode->i_sb);
-                else
-                    reiserfs_read_unlock_xattrs (inode->i_sb);
-                reiserfs_write_unlock_xattr_i (inode);
-        }
-        posix_acl_release(clone);
-        return error;
+	if (get_inode_sd_version(inode) == STAT_DATA_V1 ||
+	    !reiserfs_posixacl(inode->i_sb)) {
+		return 0;
+	}
+
+	reiserfs_read_lock_xattrs(inode->i_sb);
+	acl = reiserfs_get_acl(inode, ACL_TYPE_ACCESS);
+	reiserfs_read_unlock_xattrs(inode->i_sb);
+	if (!acl)
+		return 0;
+	if (IS_ERR(acl))
+		return PTR_ERR(acl);
+	clone = posix_acl_clone(acl, GFP_NOFS);
+	posix_acl_release(acl);
+	if (!clone)
+		return -ENOMEM;
+	error = posix_acl_chmod_masq(clone, inode->i_mode);
+	if (!error) {
+		int lock = !has_xattr_dir(inode);
+		reiserfs_write_lock_xattr_i(inode);
+		if (lock)
+			reiserfs_write_lock_xattrs(inode->i_sb);
+		else
+			reiserfs_read_lock_xattrs(inode->i_sb);
+		error = reiserfs_set_acl(inode, ACL_TYPE_ACCESS, clone);
+		if (lock)
+			reiserfs_write_unlock_xattrs(inode->i_sb);
+		else
+			reiserfs_read_unlock_xattrs(inode->i_sb);
+		reiserfs_write_unlock_xattr_i(inode);
+	}
+	posix_acl_release(clone);
+	return error;
 }
 
 static int
 posix_acl_access_get(struct inode *inode, const char *name,
-			  void *buffer, size_t size)
+		     void *buffer, size_t size)
 {
-	if (strlen(name) != sizeof(XATTR_NAME_ACL_ACCESS)-1)
+	if (strlen(name) != sizeof(POSIX_ACL_XATTR_ACCESS) - 1)
 		return -EINVAL;
 	return xattr_get_acl(inode, ACL_TYPE_ACCESS, buffer, size);
 }
 
 static int
 posix_acl_access_set(struct inode *inode, const char *name,
-			  const void *value, size_t size, int flags)
+		     const void *value, size_t size, int flags)
 {
-	if (strlen(name) != sizeof(XATTR_NAME_ACL_ACCESS)-1)
+	if (strlen(name) != sizeof(POSIX_ACL_XATTR_ACCESS) - 1)
 		return -EINVAL;
 	return xattr_set_acl(inode, ACL_TYPE_ACCESS, value, size);
 }
 
-static int
-posix_acl_access_del (struct inode *inode, const char *name)
+static int posix_acl_access_del(struct inode *inode, const char *name)
 {
-    struct reiserfs_inode_info *reiserfs_i = REISERFS_I(inode);
-    struct posix_acl **acl = &reiserfs_i->i_acl_access;
-    if (strlen(name) != sizeof(XATTR_NAME_ACL_ACCESS)-1)
-	return -EINVAL;
-    if (!IS_ERR (*acl) && *acl) {
-        posix_acl_release (*acl);
-        *acl = ERR_PTR (-ENODATA);
-    }
+	struct reiserfs_inode_info *reiserfs_i = REISERFS_I(inode);
+	struct posix_acl **acl = &reiserfs_i->i_acl_access;
+	if (strlen(name) != sizeof(POSIX_ACL_XATTR_ACCESS) - 1)
+		return -EINVAL;
+	if (!IS_ERR(*acl) && *acl) {
+		posix_acl_release(*acl);
+		*acl = ERR_PTR(-ENODATA);
+	}
 
-    return 0;
+	return 0;
 }
 
 static int
-posix_acl_access_list (struct inode *inode, const char *name, int namelen, char *out)
+posix_acl_access_list(struct inode *inode, const char *name, int namelen,
+		      char *out)
 {
-    int len = namelen;
-    if (!reiserfs_posixacl (inode->i_sb))
-        return 0;
-    if (out)
-        memcpy (out, name, len);
+	int len = namelen;
+	if (!reiserfs_posixacl(inode->i_sb))
+		return 0;
+	if (out)
+		memcpy(out, name, len);
 
-    return len;
+	return len;
 }
 
 struct reiserfs_xattr_handler posix_acl_access_handler = {
-	.prefix = XATTR_NAME_ACL_ACCESS,
+	.prefix = POSIX_ACL_XATTR_ACCESS,
 	.get = posix_acl_access_get,
 	.set = posix_acl_access_set,
 	.del = posix_acl_access_del,
@@ -518,52 +511,52 @@ struct reiserfs_xattr_handler posix_acl_
 };
 
 static int
-posix_acl_default_get (struct inode *inode, const char *name,
-			   void *buffer, size_t size)
+posix_acl_default_get(struct inode *inode, const char *name,
+		      void *buffer, size_t size)
 {
-	if (strlen(name) != sizeof(XATTR_NAME_ACL_DEFAULT)-1)
+	if (strlen(name) != sizeof(POSIX_ACL_XATTR_DEFAULT) - 1)
 		return -EINVAL;
 	return xattr_get_acl(inode, ACL_TYPE_DEFAULT, buffer, size);
 }
 
 static int
 posix_acl_default_set(struct inode *inode, const char *name,
-			   const void *value, size_t size, int flags)
+		      const void *value, size_t size, int flags)
 {
-	if (strlen(name) != sizeof(XATTR_NAME_ACL_DEFAULT)-1)
+	if (strlen(name) != sizeof(POSIX_ACL_XATTR_DEFAULT) - 1)
 		return -EINVAL;
 	return xattr_set_acl(inode, ACL_TYPE_DEFAULT, value, size);
 }
 
-static int
-posix_acl_default_del (struct inode *inode, const char *name)
+static int posix_acl_default_del(struct inode *inode, const char *name)
 {
-    struct reiserfs_inode_info *reiserfs_i = REISERFS_I(inode);
-    struct posix_acl **acl = &reiserfs_i->i_acl_default;
-    if (strlen(name) != sizeof(XATTR_NAME_ACL_DEFAULT)-1)
-	return -EINVAL;
-    if (!IS_ERR (*acl) && *acl) {
-        posix_acl_release (*acl);
-        *acl = ERR_PTR (-ENODATA);
-    }
+	struct reiserfs_inode_info *reiserfs_i = REISERFS_I(inode);
+	struct posix_acl **acl = &reiserfs_i->i_acl_default;
+	if (strlen(name) != sizeof(POSIX_ACL_XATTR_DEFAULT) - 1)
+		return -EINVAL;
+	if (!IS_ERR(*acl) && *acl) {
+		posix_acl_release(*acl);
+		*acl = ERR_PTR(-ENODATA);
+	}
 
-    return 0;
+	return 0;
 }
 
 static int
-posix_acl_default_list (struct inode *inode, const char *name, int namelen, char *out)
+posix_acl_default_list(struct inode *inode, const char *name, int namelen,
+		       char *out)
 {
-    int len = namelen;
-    if (!reiserfs_posixacl (inode->i_sb))
-        return 0;
-    if (out)
-        memcpy (out, name, len);
+	int len = namelen;
+	if (!reiserfs_posixacl(inode->i_sb))
+		return 0;
+	if (out)
+		memcpy(out, name, len);
 
-    return len;
+	return len;
 }
 
 struct reiserfs_xattr_handler posix_acl_default_handler = {
-	.prefix = XATTR_NAME_ACL_DEFAULT,
+	.prefix = POSIX_ACL_XATTR_DEFAULT,
 	.get = posix_acl_default_get,
 	.set = posix_acl_default_set,
 	.del = posix_acl_default_del,
diff --git a/fs/reiserfs/xattr_security.c b/fs/reiserfs/xattr_security.c
--- a/fs/reiserfs/xattr_security.c
+++ b/fs/reiserfs/xattr_security.c
@@ -9,57 +9,55 @@
 #define XATTR_SECURITY_PREFIX "security."
 
 static int
-security_get (struct inode *inode, const char *name, void *buffer, size_t size)
+security_get(struct inode *inode, const char *name, void *buffer, size_t size)
 {
-    if (strlen(name) < sizeof(XATTR_SECURITY_PREFIX))
-        return -EINVAL;
+	if (strlen(name) < sizeof(XATTR_SECURITY_PREFIX))
+		return -EINVAL;
 
-    if (is_reiserfs_priv_object(inode))
-        return -EPERM;
+	if (is_reiserfs_priv_object(inode))
+		return -EPERM;
 
-    return reiserfs_xattr_get (inode, name, buffer, size);
+	return reiserfs_xattr_get(inode, name, buffer, size);
 }
 
 static int
-security_set (struct inode *inode, const char *name, const void *buffer,
-          size_t size, int flags)
+security_set(struct inode *inode, const char *name, const void *buffer,
+	     size_t size, int flags)
 {
-    if (strlen(name) < sizeof(XATTR_SECURITY_PREFIX))
-        return -EINVAL;
+	if (strlen(name) < sizeof(XATTR_SECURITY_PREFIX))
+		return -EINVAL;
 
-    if (is_reiserfs_priv_object(inode))
-        return -EPERM;
+	if (is_reiserfs_priv_object(inode))
+		return -EPERM;
 
-    return reiserfs_xattr_set (inode, name, buffer, size, flags);
+	return reiserfs_xattr_set(inode, name, buffer, size, flags);
 }
 
-static int
-security_del (struct inode *inode, const char *name)
+static int security_del(struct inode *inode, const char *name)
 {
-    if (strlen(name) < sizeof(XATTR_SECURITY_PREFIX))
-        return -EINVAL;
+	if (strlen(name) < sizeof(XATTR_SECURITY_PREFIX))
+		return -EINVAL;
 
-    if (is_reiserfs_priv_object(inode))
-        return -EPERM;
+	if (is_reiserfs_priv_object(inode))
+		return -EPERM;
 
-    return 0;
+	return 0;
 }
 
 static int
-security_list (struct inode *inode, const char *name, int namelen, char *out)
+security_list(struct inode *inode, const char *name, int namelen, char *out)
 {
-    int len = namelen;
+	int len = namelen;
 
-    if (is_reiserfs_priv_object(inode))
-        return 0;
+	if (is_reiserfs_priv_object(inode))
+		return 0;
 
-    if (out)
-        memcpy (out, name, len);
+	if (out)
+		memcpy(out, name, len);
 
-    return len;
+	return len;
 }
 
-
 struct reiserfs_xattr_handler security_handler = {
 	.prefix = XATTR_SECURITY_PREFIX,
 	.get = security_get,
diff --git a/fs/reiserfs/xattr_trusted.c b/fs/reiserfs/xattr_trusted.c
--- a/fs/reiserfs/xattr_trusted.c
+++ b/fs/reiserfs/xattr_trusted.c
@@ -9,69 +9,67 @@
 #define XATTR_TRUSTED_PREFIX "trusted."
 
 static int
-trusted_get (struct inode *inode, const char *name, void *buffer, size_t size)
+trusted_get(struct inode *inode, const char *name, void *buffer, size_t size)
 {
-    if (strlen(name) < sizeof(XATTR_TRUSTED_PREFIX))
-        return -EINVAL;
+	if (strlen(name) < sizeof(XATTR_TRUSTED_PREFIX))
+		return -EINVAL;
 
-    if (!reiserfs_xattrs (inode->i_sb))
-        return -EOPNOTSUPP;
+	if (!reiserfs_xattrs(inode->i_sb))
+		return -EOPNOTSUPP;
 
-    if (!(capable(CAP_SYS_ADMIN) || is_reiserfs_priv_object(inode)))
-        return -EPERM;
+	if (!(capable(CAP_SYS_ADMIN) || is_reiserfs_priv_object(inode)))
+		return -EPERM;
 
-    return reiserfs_xattr_get (inode, name, buffer, size);
+	return reiserfs_xattr_get(inode, name, buffer, size);
 }
 
 static int
-trusted_set (struct inode *inode, const char *name, const void *buffer,
-          size_t size, int flags)
+trusted_set(struct inode *inode, const char *name, const void *buffer,
+	    size_t size, int flags)
 {
-    if (strlen(name) < sizeof(XATTR_TRUSTED_PREFIX))
-        return -EINVAL;
+	if (strlen(name) < sizeof(XATTR_TRUSTED_PREFIX))
+		return -EINVAL;
 
-    if (!reiserfs_xattrs (inode->i_sb))
-        return -EOPNOTSUPP;
+	if (!reiserfs_xattrs(inode->i_sb))
+		return -EOPNOTSUPP;
 
-    if (!(capable(CAP_SYS_ADMIN) || is_reiserfs_priv_object(inode)))
-        return -EPERM;
+	if (!(capable(CAP_SYS_ADMIN) || is_reiserfs_priv_object(inode)))
+		return -EPERM;
 
-    return reiserfs_xattr_set (inode, name, buffer, size, flags);
+	return reiserfs_xattr_set(inode, name, buffer, size, flags);
 }
 
-static int
-trusted_del (struct inode *inode, const char *name)
+static int trusted_del(struct inode *inode, const char *name)
 {
-    if (strlen(name) < sizeof(XATTR_TRUSTED_PREFIX))
-        return -EINVAL;
+	if (strlen(name) < sizeof(XATTR_TRUSTED_PREFIX))
+		return -EINVAL;
 
-    if (!reiserfs_xattrs (inode->i_sb))
-        return -EOPNOTSUPP;
+	if (!reiserfs_xattrs(inode->i_sb))
+		return -EOPNOTSUPP;
 
-    if (!(capable(CAP_SYS_ADMIN) || is_reiserfs_priv_object(inode)))
-        return -EPERM;
+	if (!(capable(CAP_SYS_ADMIN) || is_reiserfs_priv_object(inode)))
+		return -EPERM;
 
-    return 0;
+	return 0;
 }
 
 static int
-trusted_list (struct inode *inode, const char *name, int namelen, char *out)
+trusted_list(struct inode *inode, const char *name, int namelen, char *out)
 {
-    int len = namelen;
+	int len = namelen;
 
-    if (!reiserfs_xattrs (inode->i_sb))
-        return 0;
+	if (!reiserfs_xattrs(inode->i_sb))
+		return 0;
 
-    if (!(capable(CAP_SYS_ADMIN) || is_reiserfs_priv_object(inode)))
-        return 0;
+	if (!(capable(CAP_SYS_ADMIN) || is_reiserfs_priv_object(inode)))
+		return 0;
 
-    if (out)
-        memcpy (out, name, len);
+	if (out)
+		memcpy(out, name, len);
 
-    return len;
+	return len;
 }
 
-
 struct reiserfs_xattr_handler trusted_handler = {
 	.prefix = XATTR_TRUSTED_PREFIX,
 	.get = trusted_get,
diff --git a/fs/reiserfs/xattr_user.c b/fs/reiserfs/xattr_user.c
--- a/fs/reiserfs/xattr_user.c
+++ b/fs/reiserfs/xattr_user.c
@@ -13,81 +13,80 @@
 #define XATTR_USER_PREFIX "user."
 
 static int
-user_get (struct inode *inode, const char *name, void *buffer, size_t size)
+user_get(struct inode *inode, const char *name, void *buffer, size_t size)
 {
 
-    int error;
+	int error;
 
-    if (strlen(name) < sizeof(XATTR_USER_PREFIX))
-        return -EINVAL;
+	if (strlen(name) < sizeof(XATTR_USER_PREFIX))
+		return -EINVAL;
 
-    if (!reiserfs_xattrs_user (inode->i_sb))
-        return -EOPNOTSUPP;
+	if (!reiserfs_xattrs_user(inode->i_sb))
+		return -EOPNOTSUPP;
 
-    error = reiserfs_permission_locked (inode, MAY_READ, NULL);
-    if (error)
-        return error;
+	error = reiserfs_permission_locked(inode, MAY_READ, NULL);
+	if (error)
+		return error;
 
-    return reiserfs_xattr_get (inode, name, buffer, size);
+	return reiserfs_xattr_get(inode, name, buffer, size);
 }
 
 static int
-user_set (struct inode *inode, const char *name, const void *buffer,
-          size_t size, int flags)
+user_set(struct inode *inode, const char *name, const void *buffer,
+	 size_t size, int flags)
 {
 
-    int error;
+	int error;
 
-    if (strlen(name) < sizeof(XATTR_USER_PREFIX))
-        return -EINVAL;
+	if (strlen(name) < sizeof(XATTR_USER_PREFIX))
+		return -EINVAL;
 
-    if (!reiserfs_xattrs_user (inode->i_sb))
-        return -EOPNOTSUPP;
+	if (!reiserfs_xattrs_user(inode->i_sb))
+		return -EOPNOTSUPP;
 
-    if (!S_ISREG (inode->i_mode) &&
-        (!S_ISDIR (inode->i_mode) || inode->i_mode & S_ISVTX))
-        return -EPERM;
+	if (!S_ISREG(inode->i_mode) &&
+	    (!S_ISDIR(inode->i_mode) || inode->i_mode & S_ISVTX))
+		return -EPERM;
 
-    error = reiserfs_permission_locked (inode, MAY_WRITE, NULL);
-    if (error)
-        return error;
+	error = reiserfs_permission_locked(inode, MAY_WRITE, NULL);
+	if (error)
+		return error;
 
-    return reiserfs_xattr_set (inode, name, buffer, size, flags);
+	return reiserfs_xattr_set(inode, name, buffer, size, flags);
 }
 
-static int
-user_del (struct inode *inode, const char *name)
+static int user_del(struct inode *inode, const char *name)
 {
-    int error;
+	int error;
 
-    if (strlen(name) < sizeof(XATTR_USER_PREFIX))
-        return -EINVAL;
+	if (strlen(name) < sizeof(XATTR_USER_PREFIX))
+		return -EINVAL;
 
-    if (!reiserfs_xattrs_user (inode->i_sb))
-        return -EOPNOTSUPP;
+	if (!reiserfs_xattrs_user(inode->i_sb))
+		return -EOPNOTSUPP;
 
-    if (!S_ISREG (inode->i_mode) &&
-        (!S_ISDIR (inode->i_mode) || inode->i_mode & S_ISVTX))
-        return -EPERM;
+	if (!S_ISREG(inode->i_mode) &&
+	    (!S_ISDIR(inode->i_mode) || inode->i_mode & S_ISVTX))
+		return -EPERM;
 
-    error = reiserfs_permission_locked (inode, MAY_WRITE, NULL);
-    if (error)
-        return error;
+	error = reiserfs_permission_locked(inode, MAY_WRITE, NULL);
+	if (error)
+		return error;
 
-    return 0;
+	return 0;
 }
 
 static int
-user_list (struct inode *inode, const char *name, int namelen, char *out)
+user_list(struct inode *inode, const char *name, int namelen, char *out)
 {
-    int len = namelen;
-    if (!reiserfs_xattrs_user (inode->i_sb))
-        return 0;
+	int len = namelen;
+	if (!reiserfs_xattrs_user(inode->i_sb))
+		return 0;
 
-    if (out)
-        memcpy (out, name, len);
+	if (out)
+		memcpy(out, name, len);
 
-    return len;
+	return len;
 }
 
 struct reiserfs_xattr_handler user_handler = {
diff --git a/fs/smbfs/symlink.c b/fs/smbfs/symlink.c
--- a/fs/smbfs/symlink.c
+++ b/fs/smbfs/symlink.c
@@ -34,7 +34,7 @@ int smb_symlink(struct inode *inode, str
 	return smb_proc_symlink(server_from_dentry(dentry), dentry, oldname);
 }
 
-static int smb_follow_link(struct dentry *dentry, struct nameidata *nd)
+static void *smb_follow_link(struct dentry *dentry, struct nameidata *nd)
 {
 	char *link = __getname();
 	DEBUG1("followlink of %s/%s\n", DENTRY_PATH(dentry));
@@ -52,10 +52,10 @@ static int smb_follow_link(struct dentry
 		}
 	}
 	nd_set_link(nd, link);
-	return 0;
+	return NULL;
 }
 
-static void smb_put_link(struct dentry *dentry, struct nameidata *nd)
+static void smb_put_link(struct dentry *dentry, struct nameidata *nd, void *p)
 {
 	char *s = nd_get_link(nd);
 	if (!IS_ERR(s))
diff --git a/fs/super.c b/fs/super.c
--- a/fs/super.c
+++ b/fs/super.c
@@ -341,20 +341,22 @@ static inline void write_super(struct su
  */
 void sync_supers(void)
 {
-	struct super_block * sb;
-restart:
+	struct super_block *sb;
+
 	spin_lock(&sb_lock);
-	sb = sb_entry(super_blocks.next);
-	while (sb != sb_entry(&super_blocks))
+restart:
+	list_for_each_entry(sb, &super_blocks, s_list) {
 		if (sb->s_dirt) {
 			sb->s_count++;
 			spin_unlock(&sb_lock);
 			down_read(&sb->s_umount);
 			write_super(sb);
-			drop_super(sb);
-			goto restart;
-		} else
-			sb = sb_entry(sb->s_list.next);
+			up_read(&sb->s_umount);
+			spin_lock(&sb_lock);
+			if (__put_super_and_need_restart(sb))
+				goto restart;
+		}
+	}
 	spin_unlock(&sb_lock);
 }
 
@@ -381,20 +383,16 @@ void sync_filesystems(int wait)
 
 	down(&mutex);		/* Could be down_interruptible */
 	spin_lock(&sb_lock);
-	for (sb = sb_entry(super_blocks.next); sb != sb_entry(&super_blocks);
-			sb = sb_entry(sb->s_list.next)) {
+	list_for_each_entry(sb, &super_blocks, s_list) {
 		if (!sb->s_op->sync_fs)
 			continue;
 		if (sb->s_flags & MS_RDONLY)
 			continue;
 		sb->s_need_sync_fs = 1;
 	}
-	spin_unlock(&sb_lock);
 
 restart:
-	spin_lock(&sb_lock);
-	for (sb = sb_entry(super_blocks.next); sb != sb_entry(&super_blocks);
-			sb = sb_entry(sb->s_list.next)) {
+	list_for_each_entry(sb, &super_blocks, s_list) {
 		if (!sb->s_need_sync_fs)
 			continue;
 		sb->s_need_sync_fs = 0;
@@ -405,8 +403,11 @@ restart:
 		down_read(&sb->s_umount);
 		if (sb->s_root && (wait || sb->s_dirt))
 			sb->s_op->sync_fs(sb, wait);
-		drop_super(sb);
-		goto restart;
+		up_read(&sb->s_umount);
+		/* restart only when sb is no longer on the list */
+		spin_lock(&sb_lock);
+		if (__put_super_and_need_restart(sb))
+			goto restart;
 	}
 	spin_unlock(&sb_lock);
 	up(&mutex);
@@ -422,21 +423,25 @@ restart:
 
 struct super_block * get_super(struct block_device *bdev)
 {
-	struct list_head *p;
+	struct super_block *sb;
+
 	if (!bdev)
 		return NULL;
-rescan:
+
 	spin_lock(&sb_lock);
-	list_for_each(p, &super_blocks) {
-		struct super_block *s = sb_entry(p);
-		if (s->s_bdev == bdev) {
-			s->s_count++;
+rescan:
+	list_for_each_entry(sb, &super_blocks, s_list) {
+		if (sb->s_bdev == bdev) {
+			sb->s_count++;
 			spin_unlock(&sb_lock);
-			down_read(&s->s_umount);
-			if (s->s_root)
-				return s;
-			drop_super(s);
-			goto rescan;
+			down_read(&sb->s_umount);
+			if (sb->s_root)
+				return sb;
+			up_read(&sb->s_umount);
+			/* restart only when sb is no longer on the list */
+			spin_lock(&sb_lock);
+			if (__put_super_and_need_restart(sb))
+				goto rescan;
 		}
 	}
 	spin_unlock(&sb_lock);
@@ -447,20 +452,22 @@ EXPORT_SYMBOL(get_super);
  
 struct super_block * user_get_super(dev_t dev)
 {
-	struct list_head *p;
+	struct super_block *sb;
 
-rescan:
 	spin_lock(&sb_lock);
-	list_for_each(p, &super_blocks) {
-		struct super_block *s = sb_entry(p);
-		if (s->s_dev ==  dev) {
-			s->s_count++;
+rescan:
+	list_for_each_entry(sb, &super_blocks, s_list) {
+		if (sb->s_dev ==  dev) {
+			sb->s_count++;
 			spin_unlock(&sb_lock);
-			down_read(&s->s_umount);
-			if (s->s_root)
-				return s;
-			drop_super(s);
-			goto rescan;
+			down_read(&sb->s_umount);
+			if (sb->s_root)
+				return sb;
+			up_read(&sb->s_umount);
+			/* restart only when sb is no longer on the list */
+			spin_lock(&sb_lock);
+			if (__put_super_and_need_restart(sb))
+				goto rescan;
 		}
 	}
 	spin_unlock(&sb_lock);
@@ -833,8 +840,8 @@ do_kern_mount(const char *fstype, int fl
 	mnt->mnt_root = dget(sb->s_root);
 	mnt->mnt_mountpoint = sb->s_root;
 	mnt->mnt_parent = mnt;
-	mnt->mnt_namespace = current->namespace;
 	up_write(&sb->s_umount);
+	free_secdata(secdata);
 	put_filesystem(type);
 	return mnt;
 out_sb:
diff --git a/fs/sysfs/bin.c b/fs/sysfs/bin.c
--- a/fs/sysfs/bin.c
+++ b/fs/sysfs/bin.c
@@ -25,7 +25,7 @@ fill_read(struct dentry *dentry, char *b
 	struct kobject * kobj = to_kobj(dentry->d_parent);
 
 	if (!attr->read)
-		return -EINVAL;
+		return -EIO;
 
 	return attr->read(kobj, buffer, off, count);
 }
@@ -71,7 +71,7 @@ flush_write(struct dentry *dentry, char 
 	struct kobject *kobj = to_kobj(dentry->d_parent);
 
 	if (!attr->write)
-		return -EINVAL;
+		return -EIO;
 
 	return attr->write(kobj, buffer, offset, count);
 }
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
--- a/fs/sysfs/dir.c
+++ b/fs/sysfs/dir.c
@@ -8,6 +8,7 @@
 #include <linux/mount.h>
 #include <linux/module.h>
 #include <linux/kobject.h>
+#include <linux/namei.h>
 #include "sysfs.h"
 
 DECLARE_RWSEM(sysfs_rename_sem);
@@ -99,20 +100,21 @@ static int create_dir(struct kobject * k
 	umode_t mode = S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO;
 
 	down(&p->d_inode->i_sem);
-	*d = sysfs_get_dentry(p,n);
+	*d = lookup_one_len(n, p, strlen(n));
 	if (!IS_ERR(*d)) {
-		error = sysfs_create(*d, mode, init_dir);
+		error = sysfs_make_dirent(p->d_fsdata, *d, k, mode, SYSFS_DIR);
 		if (!error) {
-			error = sysfs_make_dirent(p->d_fsdata, *d, k, mode,
-						SYSFS_DIR);
+			error = sysfs_create(*d, mode, init_dir);
 			if (!error) {
 				p->d_inode->i_nlink++;
 				(*d)->d_op = &sysfs_dentry_ops;
 				d_rehash(*d);
 			}
 		}
-		if (error && (error != -EEXIST))
+		if (error && (error != -EEXIST)) {
+			sysfs_put((*d)->d_fsdata);
 			d_drop(*d);
+		}
 		dput(*d);
 	} else
 		error = PTR_ERR(*d);
@@ -171,17 +173,19 @@ static int sysfs_attach_attr(struct sysf
                 init = init_file;
         }
 
+	dentry->d_fsdata = sysfs_get(sd);
+	sd->s_dentry = dentry;
 	error = sysfs_create(dentry, (attr->mode & S_IALLUGO) | S_IFREG, init);
-	if (error)
+	if (error) {
+		sysfs_put(sd);
 		return error;
+	}
 
         if (bin_attr) {
 		dentry->d_inode->i_size = bin_attr->size;
 		dentry->d_inode->i_fop = &bin_fops;
 	}
 	dentry->d_op = &sysfs_dentry_ops;
-	dentry->d_fsdata = sysfs_get(sd);
-	sd->s_dentry = dentry;
 	d_rehash(dentry);
 
 	return 0;
@@ -191,13 +195,15 @@ static int sysfs_attach_link(struct sysf
 {
 	int err = 0;
 
+	dentry->d_fsdata = sysfs_get(sd);
+	sd->s_dentry = dentry;
 	err = sysfs_create(dentry, S_IFLNK|S_IRWXUGO, init_symlink);
 	if (!err) {
 		dentry->d_op = &sysfs_dentry_ops;
-		dentry->d_fsdata = sysfs_get(sd);
-		sd->s_dentry = dentry;
 		d_rehash(dentry);
-	}
+	} else
+		sysfs_put(sd);
+
 	return err;
 }
 
@@ -228,6 +234,7 @@ static struct dentry * sysfs_lookup(stru
 
 struct inode_operations sysfs_dir_inode_operations = {
 	.lookup		= sysfs_lookup,
+	.setattr	= sysfs_setattr,
 };
 
 static void remove_dir(struct dentry * d)
@@ -309,7 +316,7 @@ int sysfs_rename_dir(struct kobject * ko
 
 	down(&parent->d_inode->i_sem);
 
-	new_dentry = sysfs_get_dentry(parent, new_name);
+	new_dentry = lookup_one_len(new_name, parent, strlen(new_name));
 	if (!IS_ERR(new_dentry)) {
   		if (!new_dentry->d_inode) {
 			error = kobject_set_name(kobj, "%s", new_name);
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
--- a/fs/sysfs/file.c
+++ b/fs/sysfs/file.c
@@ -3,8 +3,9 @@
  */
 
 #include <linux/module.h>
-#include <linux/dnotify.h>
+#include <linux/fsnotify.h>
 #include <linux/kobject.h>
+#include <linux/namei.h>
 #include <asm/uaccess.h>
 #include <asm/semaphore.h>
 
@@ -13,7 +14,7 @@
 #define to_subsys(k) container_of(k,struct subsystem,kset.kobj)
 #define to_sattr(a) container_of(a,struct subsys_attribute,attr)
 
-/**
+/*
  * Subsystem file operations.
  * These operations allow subsystems to have files that can be 
  * read/written. 
@@ -23,7 +24,7 @@ subsys_attr_show(struct kobject * kobj, 
 {
 	struct subsystem * s = to_subsys(kobj);
 	struct subsys_attribute * sattr = to_sattr(attr);
-	ssize_t ret = 0;
+	ssize_t ret = -EIO;
 
 	if (sattr->show)
 		ret = sattr->show(s,page);
@@ -36,7 +37,7 @@ subsys_attr_store(struct kobject * kobj,
 {
 	struct subsystem * s = to_subsys(kobj);
 	struct subsys_attribute * sattr = to_sattr(attr);
-	ssize_t ret = 0;
+	ssize_t ret = -EIO;
 
 	if (sattr->store)
 		ret = sattr->store(s,page,count);
@@ -182,7 +183,7 @@ fill_write_buffer(struct sysfs_buffer * 
 		return -ENOMEM;
 
 	if (count >= PAGE_SIZE)
-		count = PAGE_SIZE - 1;
+		count = PAGE_SIZE;
 	error = copy_from_user(buffer->page,buf,count);
 	buffer->needs_read_fill = 1;
 	return error ? -EFAULT : count;
@@ -191,8 +192,9 @@ fill_write_buffer(struct sysfs_buffer * 
 
 /**
  *	flush_write_buffer - push buffer to kobject.
- *	@file:		file pointer.
+ *	@dentry:	dentry to the attribute
  *	@buffer:	data buffer for file.
+ *	@count:		number of bytes
  *
  *	Get the correct pointers for the kobject and the attribute we're
  *	dealing with, then call the store() method for the attribute, 
@@ -389,9 +391,6 @@ int sysfs_create_file(struct kobject * k
  * sysfs_update_file - update the modified timestamp on an object attribute.
  * @kobj: object we're acting for.
  * @attr: attribute descriptor.
- *
- * Also call dnotify for the dentry, which lots of userspace programs
- * use.
  */
 int sysfs_update_file(struct kobject * kobj, const struct attribute * attr)
 {
@@ -400,13 +399,13 @@ int sysfs_update_file(struct kobject * k
 	int res = -ENOENT;
 
 	down(&dir->d_inode->i_sem);
-	victim = sysfs_get_dentry(dir, attr->name);
+	victim = lookup_one_len(attr->name, dir, strlen(attr->name));
 	if (!IS_ERR(victim)) {
 		/* make sure dentry is really there */
 		if (victim->d_inode && 
 		    (victim->d_parent->d_inode == dir->d_inode)) {
 			victim->d_inode->i_mtime = CURRENT_TIME;
-			dnotify_parent(victim, DN_MODIFY);
+			fsnotify_modify(victim);
 
 			/**
 			 * Drop reference from initial sysfs_get_dentry().
@@ -438,22 +437,24 @@ int sysfs_chmod_file(struct kobject *kob
 {
 	struct dentry *dir = kobj->dentry;
 	struct dentry *victim;
-	struct sysfs_dirent *sd;
-	umode_t umode = (mode & S_IALLUGO) | S_IFREG;
+	struct inode * inode;
+	struct iattr newattrs;
 	int res = -ENOENT;
 
 	down(&dir->d_inode->i_sem);
-	victim = sysfs_get_dentry(dir, attr->name);
+	victim = lookup_one_len(attr->name, dir, strlen(attr->name));
 	if (!IS_ERR(victim)) {
 		if (victim->d_inode &&
 		    (victim->d_parent->d_inode == dir->d_inode)) {
-			sd = victim->d_fsdata;
-			attr->mode = mode;
-			sd->s_mode = umode;
-			victim->d_inode->i_mode = umode;
-			dput(victim);
-			res = 0;
+			inode = victim->d_inode;
+			down(&inode->i_sem);
+			newattrs.ia_mode = (mode & S_IALLUGO) |
+						(inode->i_mode & ~S_IALLUGO);
+			newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
+			res = notify_change(victim, &newattrs);
+			up(&inode->i_sem);
 		}
+		dput(victim);
 	}
 	up(&dir->d_inode->i_sem);
 
diff --git a/fs/sysfs/group.c b/fs/sysfs/group.c
--- a/fs/sysfs/group.c
+++ b/fs/sysfs/group.c
@@ -11,6 +11,7 @@
 #include <linux/kobject.h>
 #include <linux/module.h>
 #include <linux/dcache.h>
+#include <linux/namei.h>
 #include <linux/err.h>
 #include "sysfs.h"
 
@@ -68,7 +69,8 @@ void sysfs_remove_group(struct kobject *
 	struct dentry * dir;
 
 	if (grp->name)
-		dir = sysfs_get_dentry(kobj->dentry,grp->name);
+		dir = lookup_one_len(grp->name, kobj->dentry,
+				strlen(grp->name));
 	else
 		dir = dget(kobj->dentry);
 
diff --git a/fs/sysfs/inode.c b/fs/sysfs/inode.c
--- a/fs/sysfs/inode.c
+++ b/fs/sysfs/inode.c
@@ -26,18 +26,107 @@ static struct backing_dev_info sysfs_bac
 	.capabilities	= BDI_CAP_NO_ACCT_DIRTY | BDI_CAP_NO_WRITEBACK,
 };
 
-struct inode * sysfs_new_inode(mode_t mode)
+static struct inode_operations sysfs_inode_operations ={
+	.setattr	= sysfs_setattr,
+};
+
+int sysfs_setattr(struct dentry * dentry, struct iattr * iattr)
+{
+	struct inode * inode = dentry->d_inode;
+	struct sysfs_dirent * sd = dentry->d_fsdata;
+	struct iattr * sd_iattr;
+	unsigned int ia_valid = iattr->ia_valid;
+	int error;
+
+	if (!sd)
+		return -EINVAL;
+
+	sd_iattr = sd->s_iattr;
+
+	error = inode_change_ok(inode, iattr);
+	if (error)
+		return error;
+
+	error = inode_setattr(inode, iattr);
+	if (error)
+		return error;
+
+	if (!sd_iattr) {
+		/* setting attributes for the first time, allocate now */
+		sd_iattr = kmalloc(sizeof(struct iattr), GFP_KERNEL);
+		if (!sd_iattr)
+			return -ENOMEM;
+		/* assign default attributes */
+		memset(sd_iattr, 0, sizeof(struct iattr));
+		sd_iattr->ia_mode = sd->s_mode;
+		sd_iattr->ia_uid = 0;
+		sd_iattr->ia_gid = 0;
+		sd_iattr->ia_atime = sd_iattr->ia_mtime = sd_iattr->ia_ctime = CURRENT_TIME;
+		sd->s_iattr = sd_iattr;
+	}
+
+	/* attributes were changed atleast once in past */
+
+	if (ia_valid & ATTR_UID)
+		sd_iattr->ia_uid = iattr->ia_uid;
+	if (ia_valid & ATTR_GID)
+		sd_iattr->ia_gid = iattr->ia_gid;
+	if (ia_valid & ATTR_ATIME)
+		sd_iattr->ia_atime = timespec_trunc(iattr->ia_atime,
+						inode->i_sb->s_time_gran);
+	if (ia_valid & ATTR_MTIME)
+		sd_iattr->ia_mtime = timespec_trunc(iattr->ia_mtime,
+						inode->i_sb->s_time_gran);
+	if (ia_valid & ATTR_CTIME)
+		sd_iattr->ia_ctime = timespec_trunc(iattr->ia_ctime,
+						inode->i_sb->s_time_gran);
+	if (ia_valid & ATTR_MODE) {
+		umode_t mode = iattr->ia_mode;
+
+		if (!in_group_p(inode->i_gid) && !capable(CAP_FSETID))
+			mode &= ~S_ISGID;
+		sd_iattr->ia_mode = sd->s_mode = mode;
+	}
+
+	return error;
+}
+
+static inline void set_default_inode_attr(struct inode * inode, mode_t mode)
+{
+	inode->i_mode = mode;
+	inode->i_uid = 0;
+	inode->i_gid = 0;
+	inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+}
+
+static inline void set_inode_attr(struct inode * inode, struct iattr * iattr)
+{
+	inode->i_mode = iattr->ia_mode;
+	inode->i_uid = iattr->ia_uid;
+	inode->i_gid = iattr->ia_gid;
+	inode->i_atime = iattr->ia_atime;
+	inode->i_mtime = iattr->ia_mtime;
+	inode->i_ctime = iattr->ia_ctime;
+}
+
+struct inode * sysfs_new_inode(mode_t mode, struct sysfs_dirent * sd)
 {
 	struct inode * inode = new_inode(sysfs_sb);
 	if (inode) {
-		inode->i_mode = mode;
-		inode->i_uid = 0;
-		inode->i_gid = 0;
 		inode->i_blksize = PAGE_CACHE_SIZE;
 		inode->i_blocks = 0;
-		inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
 		inode->i_mapping->a_ops = &sysfs_aops;
 		inode->i_mapping->backing_dev_info = &sysfs_backing_dev_info;
+		inode->i_op = &sysfs_inode_operations;
+
+		if (sd->s_iattr) {
+			/* sysfs_dirent has non-default attributes
+			 * get them for the new inode from persistent copy
+			 * in sysfs_dirent
+			 */
+			set_inode_attr(inode, sd->s_iattr);
+		} else
+			set_default_inode_attr(inode, mode);
 	}
 	return inode;
 }
@@ -48,7 +137,8 @@ int sysfs_create(struct dentry * dentry,
 	struct inode * inode = NULL;
 	if (dentry) {
 		if (!dentry->d_inode) {
-			if ((inode = sysfs_new_inode(mode))) {
+			struct sysfs_dirent * sd = dentry->d_fsdata;
+			if ((inode = sysfs_new_inode(mode, sd))) {
 				if (dentry->d_parent && dentry->d_parent->d_inode) {
 					struct inode *p_inode = dentry->d_parent->d_inode;
 					p_inode->i_mtime = p_inode->i_ctime = CURRENT_TIME;
@@ -76,16 +166,6 @@ int sysfs_create(struct dentry * dentry,
 	return error;
 }
 
-struct dentry * sysfs_get_dentry(struct dentry * parent, const char * name)
-{
-	struct qstr qstr;
-
-	qstr.name = name;
-	qstr.len = strlen(name);
-	qstr.hash = full_name_hash(name,qstr.len);
-	return lookup_hash(&qstr,parent);
-}
-
 /*
  * Get the name for corresponding element represented by the given sysfs_dirent
  */
@@ -148,6 +228,10 @@ void sysfs_hash_and_remove(struct dentry
 	struct sysfs_dirent * sd;
 	struct sysfs_dirent * parent_sd = dir->d_fsdata;
 
+	if (dir->d_inode == NULL)
+		/* no inode means this hasn't been made visible yet */
+		return;
+
 	down(&dir->d_inode->i_sem);
 	list_for_each_entry(sd, &parent_sd->s_children, s_sibling) {
 		if (!sd->s_element)
diff --git a/fs/sysfs/mount.c b/fs/sysfs/mount.c
--- a/fs/sysfs/mount.c
+++ b/fs/sysfs/mount.c
@@ -28,6 +28,7 @@ static struct sysfs_dirent sysfs_root = 
 	.s_children	= LIST_HEAD_INIT(sysfs_root.s_children),
 	.s_element	= NULL,
 	.s_type		= SYSFS_ROOT,
+	.s_iattr	= NULL,
 };
 
 static int sysfs_fill_super(struct super_block *sb, void *data, int silent)
@@ -42,7 +43,8 @@ static int sysfs_fill_super(struct super
 	sb->s_time_gran = 1;
 	sysfs_sb = sb;
 
-	inode = sysfs_new_inode(S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO);
+	inode = sysfs_new_inode(S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO,
+				 &sysfs_root);
 	if (inode) {
 		inode->i_op = &sysfs_dir_inode_operations;
 		inode->i_fop = &sysfs_dir_operations;
diff --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c
--- a/fs/sysfs/symlink.c
+++ b/fs/sysfs/symlink.c
@@ -43,7 +43,7 @@ static void fill_object_path(struct kobj
 	}
 }
 
-static int sysfs_add_link(struct dentry * parent, char * name, struct kobject * target)
+static int sysfs_add_link(struct dentry * parent, const char * name, struct kobject * target)
 {
 	struct sysfs_dirent * parent_sd = parent->d_fsdata;
 	struct sysfs_symlink * sl;
@@ -79,7 +79,7 @@ exit1:
  *	@target:	object we're pointing to.
  *	@name:		name of the symlink.
  */
-int sysfs_create_link(struct kobject * kobj, struct kobject * target, char * name)
+int sysfs_create_link(struct kobject * kobj, struct kobject * target, const char * name)
 {
 	struct dentry * dentry = kobj->dentry;
 	int error = 0;
@@ -99,13 +99,13 @@ int sysfs_create_link(struct kobject * k
  *	@name:	name of the symlink to remove.
  */
 
-void sysfs_remove_link(struct kobject * kobj, char * name)
+void sysfs_remove_link(struct kobject * kobj, const char * name)
 {
 	sysfs_hash_and_remove(kobj->dentry,name);
 }
 
 static int sysfs_get_target_path(struct kobject * kobj, struct kobject * target,
-				   char *path)
+				 char *path)
 {
 	char * s;
 	int depth, size;
@@ -151,17 +151,17 @@ static int sysfs_getlink(struct dentry *
 
 }
 
-static int sysfs_follow_link(struct dentry *dentry, struct nameidata *nd)
+static void *sysfs_follow_link(struct dentry *dentry, struct nameidata *nd)
 {
 	int error = -ENOMEM;
 	unsigned long page = get_zeroed_page(GFP_KERNEL);
 	if (page)
 		error = sysfs_getlink(dentry, (char *) page); 
 	nd_set_link(nd, error ? ERR_PTR(error) : (char *)page);
-	return 0;
+	return NULL;
 }
 
-static void sysfs_put_link(struct dentry *dentry, struct nameidata *nd)
+static void sysfs_put_link(struct dentry *dentry, struct nameidata *nd, void *cookie)
 {
 	char *page = nd_get_link(nd);
 	if (!IS_ERR(page))
diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h
--- a/fs/sysfs/sysfs.h
+++ b/fs/sysfs/sysfs.h
@@ -2,12 +2,11 @@
 extern struct vfsmount * sysfs_mount;
 extern kmem_cache_t *sysfs_dir_cachep;
 
-extern struct inode * sysfs_new_inode(mode_t mode);
+extern struct inode * sysfs_new_inode(mode_t mode, struct sysfs_dirent *);
 extern int sysfs_create(struct dentry *, int mode, int (*init)(struct inode *));
 
 extern int sysfs_make_dirent(struct sysfs_dirent *, struct dentry *, void *,
 				umode_t, int);
-extern struct dentry * sysfs_get_dentry(struct dentry *, const char *);
 
 extern int sysfs_add_file(struct dentry *, const struct attribute *, int);
 extern void sysfs_hash_and_remove(struct dentry * dir, const char * name);
@@ -17,6 +16,7 @@ extern void sysfs_remove_subdir(struct d
 
 extern const unsigned char * sysfs_get_name(struct sysfs_dirent *sd);
 extern void sysfs_drop_dentry(struct sysfs_dirent *sd, struct dentry *parent);
+extern int sysfs_setattr(struct dentry *dentry, struct iattr *iattr);
 
 extern struct rw_semaphore sysfs_rename_sem;
 extern struct super_block * sysfs_sb;
@@ -75,6 +75,7 @@ static inline void release_sysfs_dirent(
 		kobject_put(sl->target_kobj);
 		kfree(sl);
 	}
+	kfree(sd->s_iattr);
 	kmem_cache_free(sysfs_dir_cachep, sd);
 }
 
diff --git a/fs/sysv/symlink.c b/fs/sysv/symlink.c
--- a/fs/sysv/symlink.c
+++ b/fs/sysv/symlink.c
@@ -8,10 +8,10 @@
 #include "sysv.h"
 #include <linux/namei.h>
 
-static int sysv_follow_link(struct dentry *dentry, struct nameidata *nd)
+static void *sysv_follow_link(struct dentry *dentry, struct nameidata *nd)
 {
 	nd_set_link(nd, (char *)SYSV_I(dentry->d_inode)->i_data);
-	return 0;
+	return NULL;
 }
 
 struct inode_operations sysv_fast_symlink_inode_operations = {
diff --git a/fs/udf/namei.c b/fs/udf/namei.c
--- a/fs/udf/namei.c
+++ b/fs/udf/namei.c
@@ -159,14 +159,12 @@ udf_find_entry(struct inode *dir, struct
 	char *nameptr;
 	uint8_t lfi;
 	uint16_t liu;
-	loff_t size = (udf_ext0_offset(dir) + dir->i_size) >> 2;
+	loff_t size;
 	kernel_lb_addr bloc, eloc;
 	uint32_t extoffset, elen, offset;
 	struct buffer_head *bh = NULL;
 
-	if (!dir)
-		return NULL;
-
+	size = (udf_ext0_offset(dir) + dir->i_size) >> 2;
 	f_pos = (udf_ext0_offset(dir) >> 2);
 
 	fibh->soffset = fibh->eoffset = (f_pos & ((dir->i_sb->s_blocksize - 1) >> 2)) << 2;
diff --git a/fs/ufs/symlink.c b/fs/ufs/symlink.c
--- a/fs/ufs/symlink.c
+++ b/fs/ufs/symlink.c
@@ -29,11 +29,11 @@
 #include <linux/namei.h>
 #include <linux/ufs_fs.h>
 
-static int ufs_follow_link(struct dentry *dentry, struct nameidata *nd)
+static void *ufs_follow_link(struct dentry *dentry, struct nameidata *nd)
 {
 	struct ufs_inode_info *p = UFS_I(dentry->d_inode);
 	nd_set_link(nd, (char*)p->i_u1.i_symlink);
-	return 0;
+	return NULL;
 }
 
 struct inode_operations ufs_fast_symlink_inode_operations = {
diff --git a/fs/xattr.c b/fs/xattr.c
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -16,6 +16,7 @@
 #include <linux/security.h>
 #include <linux/syscalls.h>
 #include <linux/module.h>
+#include <linux/fsnotify.h>
 #include <asm/uaccess.h>
 
 /*
@@ -57,8 +58,10 @@ setxattr(struct dentry *d, char __user *
 		if (error)
 			goto out;
 		error = d->d_inode->i_op->setxattr(d, kname, kvalue, size, flags);
-		if (!error)
+		if (!error) {
+			fsnotify_xattr(d);
 			security_inode_post_setxattr(d, kname, kvalue, size, flags);
+		}
 out:
 		up(&d->d_inode->i_sem);
 	}
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c
--- a/fs/xfs/linux-2.6/xfs_aops.c
+++ b/fs/xfs/linux-2.6/xfs_aops.c
@@ -149,11 +149,12 @@ linvfs_unwritten_convert(
  */
 STATIC void
 linvfs_unwritten_convert_direct(
-	struct inode	*inode,
+	struct kiocb	*iocb,
 	loff_t		offset,
 	ssize_t		size,
 	void		*private)
 {
+	struct inode	*inode = iocb->ki_filp->f_dentry->d_inode;
 	ASSERT(!private || inode == (struct inode *)private);
 
 	/* private indicates an unwritten extent lay beneath this IO */
diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c
--- a/fs/xfs/linux-2.6/xfs_buf.c
+++ b/fs/xfs/linux-2.6/xfs_buf.c
@@ -61,12 +61,13 @@
  * File wide globals
  */
 
-STATIC kmem_cache_t *pagebuf_cache;
+STATIC kmem_cache_t *pagebuf_zone;
 STATIC kmem_shaker_t pagebuf_shake;
-STATIC int pagebuf_daemon_wakeup(int, unsigned int);
+STATIC int xfsbufd_wakeup(int, unsigned int);
 STATIC void pagebuf_delwri_queue(xfs_buf_t *, int);
-STATIC struct workqueue_struct *pagebuf_logio_workqueue;
-STATIC struct workqueue_struct *pagebuf_dataio_workqueue;
+
+STATIC struct workqueue_struct *xfslogd_workqueue;
+STATIC struct workqueue_struct *xfsdatad_workqueue;
 
 /*
  * Pagebuf debugging
@@ -123,9 +124,9 @@ ktrace_t *pagebuf_trace_buf;
 
 
 #define pagebuf_allocate(flags) \
-	kmem_zone_alloc(pagebuf_cache, pb_to_km(flags))
+	kmem_zone_alloc(pagebuf_zone, pb_to_km(flags))
 #define pagebuf_deallocate(pb) \
-	kmem_zone_free(pagebuf_cache, (pb));
+	kmem_zone_free(pagebuf_zone, (pb));
 
 /*
  * Page Region interfaces.
@@ -425,7 +426,7 @@ _pagebuf_lookup_pages(
 					__FUNCTION__, gfp_mask);
 
 			XFS_STATS_INC(pb_page_retries);
-			pagebuf_daemon_wakeup(0, gfp_mask);
+			xfsbufd_wakeup(0, gfp_mask);
 			blk_congestion_wait(WRITE, HZ/50);
 			goto retry;
 		}
@@ -1136,8 +1137,8 @@ pagebuf_iodone(
 	if ((pb->pb_iodone) || (pb->pb_flags & PBF_ASYNC)) {
 		if (schedule) {
 			INIT_WORK(&pb->pb_iodone_work, pagebuf_iodone_work, pb);
-			queue_work(dataio ? pagebuf_dataio_workqueue :
-				pagebuf_logio_workqueue, &pb->pb_iodone_work);
+			queue_work(dataio ? xfsdatad_workqueue :
+				xfslogd_workqueue, &pb->pb_iodone_work);
 		} else {
 			pagebuf_iodone_work(pb);
 		}
@@ -1562,16 +1563,6 @@ xfs_free_buftarg(
 	kmem_free(btp, sizeof(*btp));
 }
 
-void
-xfs_incore_relse(
-	xfs_buftarg_t		*btp,
-	int			delwri_only,
-	int			wait)
-{
-	invalidate_bdev(btp->pbr_bdev, 1);
-	truncate_inode_pages(btp->pbr_mapping, 0LL);
-}
-
 STATIC int
 xfs_setsize_buftarg_flags(
 	xfs_buftarg_t		*btp,
@@ -1742,27 +1733,27 @@ pagebuf_runall_queues(
 }
 
 /* Defines for pagebuf daemon */
-STATIC DECLARE_COMPLETION(pagebuf_daemon_done);
-STATIC struct task_struct *pagebuf_daemon_task;
-STATIC int pagebuf_daemon_active;
-STATIC int force_flush;
-STATIC int force_sleep;
+STATIC DECLARE_COMPLETION(xfsbufd_done);
+STATIC struct task_struct *xfsbufd_task;
+STATIC int xfsbufd_active;
+STATIC int xfsbufd_force_flush;
+STATIC int xfsbufd_force_sleep;
 
 STATIC int
-pagebuf_daemon_wakeup(
+xfsbufd_wakeup(
 	int			priority,
 	unsigned int		mask)
 {
-	if (force_sleep)
+	if (xfsbufd_force_sleep)
 		return 0;
-	force_flush = 1;
+	xfsbufd_force_flush = 1;
 	barrier();
-	wake_up_process(pagebuf_daemon_task);
+	wake_up_process(xfsbufd_task);
 	return 0;
 }
 
 STATIC int
-pagebuf_daemon(
+xfsbufd(
 	void			*data)
 {
 	struct list_head	tmp;
@@ -1774,17 +1765,17 @@ pagebuf_daemon(
 	daemonize("xfsbufd");
 	current->flags |= PF_MEMALLOC;
 
-	pagebuf_daemon_task = current;
-	pagebuf_daemon_active = 1;
+	xfsbufd_task = current;
+	xfsbufd_active = 1;
 	barrier();
 
 	INIT_LIST_HEAD(&tmp);
 	do {
-		if (unlikely(current->flags & PF_FREEZE)) {
-			force_sleep = 1;
-			refrigerator(PF_FREEZE);
+		if (unlikely(freezing(current))) {
+			xfsbufd_force_sleep = 1;
+			refrigerator();
 		} else {
-			force_sleep = 0;
+			xfsbufd_force_sleep = 0;
 		}
 
 		set_current_state(TASK_INTERRUPTIBLE);
@@ -1797,7 +1788,7 @@ pagebuf_daemon(
 			ASSERT(pb->pb_flags & PBF_DELWRI);
 
 			if (!pagebuf_ispin(pb) && !pagebuf_cond_lock(pb)) {
-				if (!force_flush &&
+				if (!xfsbufd_force_flush &&
 				    time_before(jiffies,
 						pb->pb_queuetime + age)) {
 					pagebuf_unlock(pb);
@@ -1824,10 +1815,10 @@ pagebuf_daemon(
 		if (as_list_len > 0)
 			purge_addresses();
 
-		force_flush = 0;
-	} while (pagebuf_daemon_active);
+		xfsbufd_force_flush = 0;
+	} while (xfsbufd_active);
 
-	complete_and_exit(&pagebuf_daemon_done, 0);
+	complete_and_exit(&xfsbufd_done, 0);
 }
 
 /*
@@ -1844,8 +1835,8 @@ xfs_flush_buftarg(
 	xfs_buf_t		*pb, *n;
 	int			pincount = 0;
 
-	pagebuf_runall_queues(pagebuf_dataio_workqueue);
-	pagebuf_runall_queues(pagebuf_logio_workqueue);
+	pagebuf_runall_queues(xfsdatad_workqueue);
+	pagebuf_runall_queues(xfslogd_workqueue);
 
 	INIT_LIST_HEAD(&tmp);
 	spin_lock(&pbd_delwrite_lock);
@@ -1898,43 +1889,43 @@ xfs_flush_buftarg(
 }
 
 STATIC int
-pagebuf_daemon_start(void)
+xfs_buf_daemons_start(void)
 {
-	int		rval;
+	int		error = -ENOMEM;
 
-	pagebuf_logio_workqueue = create_workqueue("xfslogd");
-	if (!pagebuf_logio_workqueue)
-		return -ENOMEM;
+	xfslogd_workqueue = create_workqueue("xfslogd");
+	if (!xfslogd_workqueue)
+		goto out;
 
-	pagebuf_dataio_workqueue = create_workqueue("xfsdatad");
-	if (!pagebuf_dataio_workqueue) {
-		destroy_workqueue(pagebuf_logio_workqueue);
-		return -ENOMEM;
-	}
+	xfsdatad_workqueue = create_workqueue("xfsdatad");
+	if (!xfsdatad_workqueue)
+		goto out_destroy_xfslogd_workqueue;
 
-	rval = kernel_thread(pagebuf_daemon, NULL, CLONE_FS|CLONE_FILES);
-	if (rval < 0) {
-		destroy_workqueue(pagebuf_logio_workqueue);
-		destroy_workqueue(pagebuf_dataio_workqueue);
-	}
+	error = kernel_thread(xfsbufd, NULL, CLONE_FS|CLONE_FILES);
+	if (error < 0)
+		goto out_destroy_xfsdatad_workqueue;
+	return 0;
 
-	return rval;
+ out_destroy_xfsdatad_workqueue:
+	destroy_workqueue(xfsdatad_workqueue);
+ out_destroy_xfslogd_workqueue:
+	destroy_workqueue(xfslogd_workqueue);
+ out:
+	return error;
 }
 
 /*
- * pagebuf_daemon_stop
- *
  * Note: do not mark as __exit, it is called from pagebuf_terminate.
  */
 STATIC void
-pagebuf_daemon_stop(void)
+xfs_buf_daemons_stop(void)
 {
-	pagebuf_daemon_active = 0;
+	xfsbufd_active = 0;
 	barrier();
-	wait_for_completion(&pagebuf_daemon_done);
+	wait_for_completion(&xfsbufd_done);
 
-	destroy_workqueue(pagebuf_logio_workqueue);
-	destroy_workqueue(pagebuf_dataio_workqueue);
+	destroy_workqueue(xfslogd_workqueue);
+	destroy_workqueue(xfsdatad_workqueue);
 }
 
 /*
@@ -1944,27 +1935,37 @@ pagebuf_daemon_stop(void)
 int __init
 pagebuf_init(void)
 {
-	pagebuf_cache = kmem_cache_create("xfs_buf_t", sizeof(xfs_buf_t), 0,
-			SLAB_HWCACHE_ALIGN, NULL, NULL);
-	if (pagebuf_cache == NULL) {
-		printk("XFS: couldn't init xfs_buf_t cache\n");
-		pagebuf_terminate();
-		return -ENOMEM;
-	}
+	int		error = -ENOMEM;
+
+	pagebuf_zone = kmem_zone_init(sizeof(xfs_buf_t), "xfs_buf");
+	if (!pagebuf_zone)
+		goto out;
 
 #ifdef PAGEBUF_TRACE
 	pagebuf_trace_buf = ktrace_alloc(PAGEBUF_TRACE_SIZE, KM_SLEEP);
 #endif
 
-	pagebuf_daemon_start();
+	error = xfs_buf_daemons_start();
+	if (error)
+		goto out_free_buf_zone;
 
-	pagebuf_shake = kmem_shake_register(pagebuf_daemon_wakeup);
-	if (pagebuf_shake == NULL) {
-		pagebuf_terminate();
-		return -ENOMEM;
+	pagebuf_shake = kmem_shake_register(xfsbufd_wakeup);
+	if (!pagebuf_shake) {
+		error = -ENOMEM;
+		goto out_stop_daemons;
 	}
 
 	return 0;
+
+ out_stop_daemons:
+	xfs_buf_daemons_stop();
+ out_free_buf_zone:
+#ifdef PAGEBUF_TRACE
+	ktrace_free(pagebuf_trace_buf);
+#endif
+	kmem_zone_destroy(pagebuf_zone);
+ out:
+	return error;
 }
 
 
@@ -1976,12 +1977,12 @@ pagebuf_init(void)
 void
 pagebuf_terminate(void)
 {
-	pagebuf_daemon_stop();
+	xfs_buf_daemons_stop();
 
 #ifdef PAGEBUF_TRACE
 	ktrace_free(pagebuf_trace_buf);
 #endif
 
-	kmem_zone_destroy(pagebuf_cache);
+	kmem_zone_destroy(pagebuf_zone);
 	kmem_shake_deregister(pagebuf_shake);
 }
diff --git a/fs/xfs/linux-2.6/xfs_buf.h b/fs/xfs/linux-2.6/xfs_buf.h
--- a/fs/xfs/linux-2.6/xfs_buf.h
+++ b/fs/xfs/linux-2.6/xfs_buf.h
@@ -576,7 +576,6 @@ extern xfs_buftarg_t *xfs_alloc_buftarg(
 extern void xfs_free_buftarg(xfs_buftarg_t *, int);
 extern void xfs_wait_buftarg(xfs_buftarg_t *);
 extern int xfs_setsize_buftarg(xfs_buftarg_t *, unsigned int, unsigned int);
-extern void xfs_incore_relse(xfs_buftarg_t *, int, int);
 extern int xfs_flush_buftarg(xfs_buftarg_t *, int);
 
 #define xfs_getsize_buftarg(buftarg) \
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c
--- a/fs/xfs/linux-2.6/xfs_file.c
+++ b/fs/xfs/linux-2.6/xfs_file.c
@@ -57,7 +57,9 @@
 #include <linux/smp_lock.h>
 
 static struct vm_operations_struct linvfs_file_vm_ops;
-
+#ifdef CONFIG_XFS_DMAPI
+static struct vm_operations_struct linvfs_dmapi_file_vm_ops;
+#endif
 
 STATIC inline ssize_t
 __linvfs_read(
@@ -388,6 +390,14 @@ done:
 	return -error;
 }
 
+#ifdef CONFIG_XFS_DMAPI
+STATIC void
+linvfs_mmap_close(
+	struct vm_area_struct	*vma)
+{
+	xfs_dm_mm_put(vma);
+}
+#endif /* CONFIG_XFS_DMAPI */
 
 STATIC int
 linvfs_file_mmap(
@@ -399,16 +409,19 @@ linvfs_file_mmap(
 	vattr_t		va = { .va_mask = XFS_AT_UPDATIME };
 	int		error;
 
+	vma->vm_ops = &linvfs_file_vm_ops;
+
 	if (vp->v_vfsp->vfs_flag & VFS_DMI) {
 		xfs_mount_t	*mp = XFS_VFSTOM(vp->v_vfsp);
 
 		error = -XFS_SEND_MMAP(mp, vma, 0);
 		if (error)
 			return error;
+#ifdef CONFIG_XFS_DMAPI
+		vma->vm_ops = &linvfs_dmapi_file_vm_ops;
+#endif
 	}
 
-	vma->vm_ops = &linvfs_file_vm_ops;
-
 	VOP_SETATTR(vp, &va, XFS_AT_UPDATIME, NULL, error);
 	if (!error)
 		vn_revalidate(vp);	/* update Linux inode flags */
@@ -609,7 +622,15 @@ struct file_operations linvfs_dir_operat
 static struct vm_operations_struct linvfs_file_vm_ops = {
 	.nopage		= filemap_nopage,
 	.populate	= filemap_populate,
+};
+
+#ifdef CONFIG_XFS_DMAPI
+static struct vm_operations_struct linvfs_dmapi_file_vm_ops = {
+	.close		= linvfs_mmap_close,
+	.nopage		= filemap_nopage,
+	.populate	= filemap_populate,
 #ifdef HAVE_VMOP_MPROTECT
 	.mprotect	= linvfs_mprotect,
 #endif
 };
+#endif /* CONFIG_XFS_DMAPI */
diff --git a/fs/xfs/linux-2.6/xfs_ioctl.c b/fs/xfs/linux-2.6/xfs_ioctl.c
--- a/fs/xfs/linux-2.6/xfs_ioctl.c
+++ b/fs/xfs/linux-2.6/xfs_ioctl.c
@@ -1174,7 +1174,8 @@ xfs_ioc_xattr(
 
 	switch (cmd) {
 	case XFS_IOC_FSGETXATTR: {
-		va.va_mask = XFS_AT_XFLAGS|XFS_AT_EXTSIZE|XFS_AT_NEXTENTS;
+		va.va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE | \
+			     XFS_AT_NEXTENTS | XFS_AT_PROJID;
 		VOP_GETATTR(vp, &va, 0, NULL, error);
 		if (error)
 			return -error;
@@ -1182,6 +1183,7 @@ xfs_ioc_xattr(
 		fa.fsx_xflags	= va.va_xflags;
 		fa.fsx_extsize	= va.va_extsize;
 		fa.fsx_nextents = va.va_nextents;
+		fa.fsx_projid	= va.va_projid;
 
 		if (copy_to_user(arg, &fa, sizeof(fa)))
 			return -XFS_ERROR(EFAULT);
@@ -1196,9 +1198,10 @@ xfs_ioc_xattr(
 		if (filp->f_flags & (O_NDELAY|O_NONBLOCK))
 			attr_flags |= ATTR_NONBLOCK;
 
-		va.va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE;
+		va.va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE | XFS_AT_PROJID;
 		va.va_xflags  = fa.fsx_xflags;
 		va.va_extsize = fa.fsx_extsize;
+		va.va_projid  = fa.fsx_projid;
 
 		VOP_SETATTR(vp, &va, attr_flags, NULL, error);
 		if (!error)
@@ -1207,7 +1210,8 @@ xfs_ioc_xattr(
 	}
 
 	case XFS_IOC_FSGETXATTRA: {
-		va.va_mask = XFS_AT_XFLAGS|XFS_AT_EXTSIZE|XFS_AT_ANEXTENTS;
+		va.va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE | \
+			     XFS_AT_ANEXTENTS | XFS_AT_PROJID;
 		VOP_GETATTR(vp, &va, 0, NULL, error);
 		if (error)
 			return -error;
@@ -1215,6 +1219,7 @@ xfs_ioc_xattr(
 		fa.fsx_xflags	= va.va_xflags;
 		fa.fsx_extsize	= va.va_extsize;
 		fa.fsx_nextents = va.va_anextents;
+		fa.fsx_projid	= va.va_projid;
 
 		if (copy_to_user(arg, &fa, sizeof(fa)))
 			return -XFS_ERROR(EFAULT);
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c
--- a/fs/xfs/linux-2.6/xfs_iops.c
+++ b/fs/xfs/linux-2.6/xfs_iops.c
@@ -374,7 +374,7 @@ linvfs_rename(
  * we need to be very careful about how much stack we use.
  * uio is kmalloced for this reason...
  */
-STATIC int
+STATIC void *
 linvfs_follow_link(
 	struct dentry		*dentry,
 	struct nameidata	*nd)
@@ -391,14 +391,14 @@ linvfs_follow_link(
 	link = (char *)kmalloc(MAXNAMELEN+1, GFP_KERNEL);
 	if (!link) {
 		nd_set_link(nd, ERR_PTR(-ENOMEM));
-		return 0;
+		return NULL;
 	}
 
 	uio = (uio_t *)kmalloc(sizeof(uio_t), GFP_KERNEL);
 	if (!uio) {
 		kfree(link);
 		nd_set_link(nd, ERR_PTR(-ENOMEM));
-		return 0;
+		return NULL;
 	}
 
 	vp = LINVFS_GET_VP(dentry->d_inode);
@@ -422,10 +422,10 @@ linvfs_follow_link(
 	kfree(uio);
 
 	nd_set_link(nd, link);
-	return 0;
+	return NULL;
 }
 
-static void linvfs_put_link(struct dentry *dentry, struct nameidata *nd)
+static void linvfs_put_link(struct dentry *dentry, struct nameidata *nd, void *p)
 {
 	char *s = nd_get_link(nd);
 	if (!IS_ERR(s))
diff --git a/fs/xfs/linux-2.6/xfs_linux.h b/fs/xfs/linux-2.6/xfs_linux.h
--- a/fs/xfs/linux-2.6/xfs_linux.h
+++ b/fs/xfs/linux-2.6/xfs_linux.h
@@ -145,10 +145,10 @@ static inline void set_buffer_unwritten_
 #define xfs_inherit_nosymlinks	xfs_params.inherit_nosym.val
 #define xfs_rotorstep		xfs_params.rotorstep.val
 
-#ifndef __smp_processor_id
-#define __smp_processor_id()	smp_processor_id()
+#ifndef raw_smp_processor_id
+#define raw_smp_processor_id()	smp_processor_id()
 #endif
-#define current_cpu()		__smp_processor_id()
+#define current_cpu()		raw_smp_processor_id()
 #define current_pid()		(current->pid)
 #define current_fsuid(cred)	(current->fsuid)
 #define current_fsgid(cred)	(current->fsgid)
@@ -230,8 +230,10 @@ static inline void set_buffer_unwritten_
  * field (see the QCMD macro in quota.h).  These macros help keep the
  * code portable - they are not visible from the syscall interface.
  */
-#define Q_XSETGQLIM	XQM_CMD(0x8)	/* set groups disk limits */
-#define Q_XGETGQUOTA	XQM_CMD(0x9)	/* get groups disk limits */
+#define Q_XSETGQLIM	XQM_CMD(8)	/* set groups disk limits */
+#define Q_XGETGQUOTA	XQM_CMD(9)	/* get groups disk limits */
+#define Q_XSETPQLIM	XQM_CMD(10)	/* set projects disk limits */
+#define Q_XGETPQUOTA	XQM_CMD(11)	/* get projects disk limits */
 
 /* IRIX uses a dynamic sizing algorithm (ndquot = 200 + numprocs*2) */
 /* we may well need to fine-tune this if it ever becomes an issue.  */
diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c
--- a/fs/xfs/linux-2.6/xfs_lrw.c
+++ b/fs/xfs/linux-2.6/xfs_lrw.c
@@ -209,30 +209,6 @@ unlock:
 	return (-status);
 }
 
-/*
- * xfs_inval_cached_pages
- * 
- * This routine is responsible for keeping direct I/O and buffered I/O
- * somewhat coherent.  From here we make sure that we're at least
- * temporarily holding the inode I/O lock exclusively and then call
- * the page cache to flush and invalidate any cached pages.  If there
- * are no cached pages this routine will be very quick.
- */
-void
-xfs_inval_cached_pages(
-	vnode_t		*vp,
-	xfs_iocore_t	*io,
-	xfs_off_t	offset,
-	int		write,
-	int		relock)
-{
-	if (VN_CACHED(vp)) {
-		xfs_inval_cached_trace(io, offset, -1, ctooff(offtoct(offset)), -1);
-		VOP_FLUSHINVAL_PAGES(vp, ctooff(offtoct(offset)), -1, FI_REMAPF_LOCKED);
-	}
-
-}
-
 ssize_t			/* bytes read, or (-)  error */
 xfs_read(
 	bhv_desc_t		*bdp,
@@ -304,10 +280,11 @@ xfs_read(
 	if (DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_READ) &&
 	    !(ioflags & IO_INVIS)) {
 		vrwlock_t locktype = VRWLOCK_READ;
+		int dmflags = FILP_DELAY_FLAG(file) | DM_SEM_FLAG_RD(ioflags);
 
 		ret = -XFS_SEND_DATA(mp, DM_EVENT_READ,
 					BHV_TO_VNODE(bdp), *offset, size,
-					FILP_DELAY_FLAG(file), &locktype);
+					dmflags, &locktype);
 		if (ret) {
 			xfs_iunlock(ip, XFS_IOLOCK_SHARED);
 			goto unlock_isem;
@@ -867,11 +844,15 @@ retry:
 	    !(ioflags & IO_INVIS)) {
 
 		xfs_rwunlock(bdp, locktype);
+		if (need_isem)
+			up(&inode->i_sem);
 		error = XFS_SEND_NAMESP(xip->i_mount, DM_EVENT_NOSPACE, vp,
 				DM_RIGHT_NULL, vp, DM_RIGHT_NULL, NULL, NULL,
 				0, 0, 0); /* Delay flag intentionally  unused */
 		if (error)
-			goto out_unlock_isem;
+			goto out_nounlocks;
+		if (need_isem)
+			down(&inode->i_sem);
 		xfs_rwlock(bdp, locktype);
 		pos = xip->i_d.di_size;
 		ret = 0;
@@ -986,6 +967,7 @@ retry:
  out_unlock_isem:
 	if (need_isem)
 		up(&inode->i_sem);
+ out_nounlocks:
 	return -error;
 }
 
diff --git a/fs/xfs/linux-2.6/xfs_lrw.h b/fs/xfs/linux-2.6/xfs_lrw.h
--- a/fs/xfs/linux-2.6/xfs_lrw.h
+++ b/fs/xfs/linux-2.6/xfs_lrw.h
@@ -94,8 +94,6 @@ extern int xfs_bdstrat_cb(struct xfs_buf
 
 extern int xfs_zero_eof(struct vnode *, struct xfs_iocore *, xfs_off_t,
 				xfs_fsize_t, xfs_fsize_t);
-extern void xfs_inval_cached_pages(struct vnode	*, struct xfs_iocore *,
-				xfs_off_t, int, int);
 extern ssize_t xfs_read(struct bhv_desc *, struct kiocb *,
 				const struct iovec *, unsigned int,
 				loff_t *, int, struct cred *);
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c
--- a/fs/xfs/linux-2.6/xfs_super.c
+++ b/fs/xfs/linux-2.6/xfs_super.c
@@ -483,7 +483,7 @@ xfssyncd(
 		set_current_state(TASK_INTERRUPTIBLE);
 		timeleft = schedule_timeout(timeleft);
 		/* swsusp */
-		try_to_freeze(PF_FREEZE);
+		try_to_freeze();
 		if (vfsp->vfs_flag & VFS_UMOUNT)
 			break;
 
@@ -590,8 +590,10 @@ linvfs_sync_super(
 	int		error;
 	int		flags = SYNC_FSDATA;
 
-	if (wait)
-		flags |= SYNC_WAIT;
+	if (unlikely(sb->s_frozen == SB_FREEZE_WRITE))
+		flags = SYNC_QUIESCE;
+	else
+		flags = SYNC_FSDATA | (wait ? SYNC_WAIT : 0);
 
 	VFS_SYNC(vfsp, flags, NULL, error);
 	sb->s_dirt = 0;
@@ -701,7 +703,8 @@ linvfs_getxquota(
 	struct vfs		*vfsp = LINVFS_GET_VFS(sb);
 	int			error, getmode;
 
-	getmode = (type == GRPQUOTA) ? Q_XGETGQUOTA : Q_XGETQUOTA;
+	getmode = (type == USRQUOTA) ? Q_XGETQUOTA :
+		 ((type == GRPQUOTA) ? Q_XGETGQUOTA : Q_XGETPQUOTA);
 	VFS_QUOTACTL(vfsp, getmode, id, (caddr_t)fdq, error);
 	return -error;
 }
@@ -716,7 +719,8 @@ linvfs_setxquota(
 	struct vfs		*vfsp = LINVFS_GET_VFS(sb);
 	int			error, setmode;
 
-	setmode = (type == GRPQUOTA) ? Q_XSETGQLIM : Q_XSETQLIM;
+	setmode = (type == USRQUOTA) ? Q_XSETQLIM :
+		 ((type == GRPQUOTA) ? Q_XSETGQLIM : Q_XSETPQLIM);
 	VFS_QUOTACTL(vfsp, setmode, id, (caddr_t)fdq, error);
 	return -error;
 }
diff --git a/fs/xfs/linux-2.6/xfs_vfs.h b/fs/xfs/linux-2.6/xfs_vfs.h
--- a/fs/xfs/linux-2.6/xfs_vfs.h
+++ b/fs/xfs/linux-2.6/xfs_vfs.h
@@ -107,6 +107,7 @@ typedef enum {
 #define SYNC_FSDATA		0x0020	/* flush fs data (e.g. superblocks) */
 #define SYNC_REFCACHE		0x0040  /* prune some of the nfs ref cache */
 #define SYNC_REMOUNT		0x0080  /* remount readonly, no dummy LRs */
+#define SYNC_QUIESCE		0x0100  /* quiesce fileystem for a snapshot */
 
 typedef int	(*vfs_mount_t)(bhv_desc_t *,
 				struct xfs_mount_args *, struct cred *);
diff --git a/fs/xfs/linux-2.6/xfs_vnode.c b/fs/xfs/linux-2.6/xfs_vnode.c
--- a/fs/xfs/linux-2.6/xfs_vnode.c
+++ b/fs/xfs/linux-2.6/xfs_vnode.c
@@ -411,13 +411,13 @@ vn_remove(
 /*  0 */		(void *)(__psint_t)(vk),		\
 /*  1 */		(void *)(s),				\
 /*  2 */		(void *)(__psint_t) line,		\
-/*  3 */		(void *)(vn_count(vp)), \
+/*  3 */		(void *)(__psint_t)(vn_count(vp)),	\
 /*  4 */		(void *)(ra),				\
 /*  5 */		(void *)(__psunsigned_t)(vp)->v_flag,	\
 /*  6 */		(void *)(__psint_t)current_cpu(),	\
 /*  7 */		(void *)(__psint_t)current_pid(),	\
 /*  8 */		(void *)__return_address,		\
-/*  9 */		0, 0, 0, 0, 0, 0, 0)
+/*  9 */		NULL, NULL, NULL, NULL, NULL, NULL, NULL)
 
 /*
  * Vnode tracing code.
diff --git a/fs/xfs/linux-2.6/xfs_vnode.h b/fs/xfs/linux-2.6/xfs_vnode.h
--- a/fs/xfs/linux-2.6/xfs_vnode.h
+++ b/fs/xfs/linux-2.6/xfs_vnode.h
@@ -426,7 +426,7 @@ typedef struct vattr {
 	u_long		va_extsize;	/* file extent size */
 	u_long		va_nextents;	/* number of extents in file */
 	u_long		va_anextents;	/* number of attr extents in file */
-	int		va_projid;	/* project id */
+	prid_t		va_projid;	/* project id */
 } vattr_t;
 
 /*
diff --git a/fs/xfs/quota/xfs_dquot.c b/fs/xfs/quota/xfs_dquot.c
--- a/fs/xfs/quota/xfs_dquot.c
+++ b/fs/xfs/quota/xfs_dquot.c
@@ -101,7 +101,7 @@ int xfs_dqerror_mod = 33;
  * is the d_id field. The idea is to fill in the entire q_core
  * when we read in the on disk dquot.
  */
-xfs_dquot_t *
+STATIC xfs_dquot_t *
 xfs_qm_dqinit(
 	xfs_mount_t  *mp,
 	xfs_dqid_t   id,
@@ -286,7 +286,9 @@ xfs_qm_adjust_dqlimits(
  * We also return 0 as the values of the timers in Q_GETQUOTA calls, when
  * enforcement's off.
  * In contrast, warnings are a little different in that they don't
- * 'automatically' get started when limits get exceeded.
+ * 'automatically' get started when limits get exceeded.  They do
+ * get reset to zero, however, when we find the count to be under
+ * the soft limit (they are only ever set non-zero via userspace).
  */
 void
 xfs_qm_adjust_dqtimers(
@@ -315,6 +317,8 @@ xfs_qm_adjust_dqtimers(
 				INT_GET(d->d_blk_hardlimit, ARCH_CONVERT)))) {
 			INT_SET(d->d_btimer, ARCH_CONVERT,
 				get_seconds() + XFS_QI_BTIMELIMIT(mp));
+		} else {
+			d->d_bwarns = 0;
 		}
 	} else {
 		if ((!d->d_blk_softlimit ||
@@ -336,6 +340,8 @@ xfs_qm_adjust_dqtimers(
 				INT_GET(d->d_ino_hardlimit, ARCH_CONVERT)))) {
 			INT_SET(d->d_itimer, ARCH_CONVERT,
 				get_seconds() + XFS_QI_ITIMELIMIT(mp));
+		} else {
+			d->d_iwarns = 0;
 		}
 	} else {
 		if ((!d->d_ino_softlimit ||
@@ -357,6 +363,8 @@ xfs_qm_adjust_dqtimers(
 				INT_GET(d->d_rtb_hardlimit, ARCH_CONVERT)))) {
 			INT_SET(d->d_rtbtimer, ARCH_CONVERT,
 				get_seconds() + XFS_QI_RTBTIMELIMIT(mp));
+		} else {
+			d->d_rtbwarns = 0;
 		}
 	} else {
 		if ((!d->d_rtb_softlimit ||
@@ -371,68 +379,6 @@ xfs_qm_adjust_dqtimers(
 }
 
 /*
- * Increment or reset warnings of a given dquot.
- */
-int
-xfs_qm_dqwarn(
-	xfs_disk_dquot_t	*d,
-	uint			flags)
-{
-	int	warned;
-
-	/*
-	 * root's limits are not real limits.
-	 */
-	if (!d->d_id)
-		return (0);
-
-	warned = 0;
-	if (INT_GET(d->d_blk_softlimit, ARCH_CONVERT) &&
-	    (INT_GET(d->d_bcount, ARCH_CONVERT) >=
-	     INT_GET(d->d_blk_softlimit, ARCH_CONVERT))) {
-		if (flags & XFS_QMOPT_DOWARN) {
-			INT_MOD(d->d_bwarns, ARCH_CONVERT, +1);
-			warned++;
-		}
-	} else {
-		if (!d->d_blk_softlimit ||
-		    (INT_GET(d->d_bcount, ARCH_CONVERT) <
-		     INT_GET(d->d_blk_softlimit, ARCH_CONVERT))) {
-			d->d_bwarns = 0;
-		}
-	}
-
-	if (INT_GET(d->d_ino_softlimit, ARCH_CONVERT) > 0 &&
-	    (INT_GET(d->d_icount, ARCH_CONVERT) >=
-	     INT_GET(d->d_ino_softlimit, ARCH_CONVERT))) {
-		if (flags & XFS_QMOPT_DOWARN) {
-			INT_MOD(d->d_iwarns, ARCH_CONVERT, +1);
-			warned++;
-		}
-	} else {
-		if (!d->d_ino_softlimit ||
-		    (INT_GET(d->d_icount, ARCH_CONVERT) <
-		     INT_GET(d->d_ino_softlimit, ARCH_CONVERT))) {
-			d->d_iwarns = 0;
-		}
-	}
-#ifdef QUOTADEBUG
-	if (INT_GET(d->d_iwarns, ARCH_CONVERT))
-		cmn_err(CE_DEBUG,
-			"--------@@Inode warnings running : %Lu >= %Lu",
-			INT_GET(d->d_icount, ARCH_CONVERT),
-			INT_GET(d->d_ino_softlimit, ARCH_CONVERT));
-	if (INT_GET(d->d_bwarns, ARCH_CONVERT))
-		cmn_err(CE_DEBUG,
-			"--------@@Blks warnings running : %Lu >= %Lu",
-			INT_GET(d->d_bcount, ARCH_CONVERT),
-			INT_GET(d->d_blk_softlimit, ARCH_CONVERT));
-#endif
-	return (warned);
-}
-
-
-/*
  * initialize a buffer full of dquots and log the whole thing
  */
 STATIC void
@@ -461,9 +407,9 @@ xfs_qm_init_dquot_blk(
 	for (i = 0; i < XFS_QM_DQPERBLK(mp); i++, d++, curid++)
 		xfs_qm_dqinit_core(curid, type, d);
 	xfs_trans_dquot_buf(tp, bp,
-			    type & XFS_DQ_USER ?
-			    XFS_BLI_UDQUOT_BUF :
-			    XFS_BLI_GDQUOT_BUF);
+			    (type & XFS_DQ_USER ? XFS_BLI_UDQUOT_BUF :
+			    ((type & XFS_DQ_PROJ) ? XFS_BLI_PDQUOT_BUF :
+			     XFS_BLI_GDQUOT_BUF)));
 	xfs_trans_log_buf(tp, bp, 0, BBTOB(XFS_QI_DQCHUNKLEN(mp)) - 1);
 }
 
@@ -544,8 +490,7 @@ xfs_qm_dqalloc(
 	 * the entire thing.
 	 */
 	xfs_qm_init_dquot_blk(tp, mp, INT_GET(dqp->q_core.d_id, ARCH_CONVERT),
-			      dqp->dq_flags & (XFS_DQ_USER|XFS_DQ_GROUP),
-			      bp);
+			      dqp->dq_flags & XFS_DQ_ALLTYPES, bp);
 
 	if ((error = xfs_bmap_finish(&tp, &flist, firstblock, &committed))) {
 		goto error1;
@@ -675,8 +620,7 @@ xfs_qm_dqtobp(
 	/*
 	 * A simple sanity check in case we got a corrupted dquot...
 	 */
-	if (xfs_qm_dqcheck(ddq, id,
-			   dqp->dq_flags & (XFS_DQ_USER|XFS_DQ_GROUP),
+	if (xfs_qm_dqcheck(ddq, id, dqp->dq_flags & XFS_DQ_ALLTYPES,
 			   flags & (XFS_QMOPT_DQREPAIR|XFS_QMOPT_DOWARN),
 			   "dqtobp")) {
 		if (!(flags & XFS_QMOPT_DQREPAIR)) {
@@ -953,8 +897,8 @@ int
 xfs_qm_dqget(
 	xfs_mount_t	*mp,
 	xfs_inode_t	*ip,	  /* locked inode (optional) */
-	xfs_dqid_t	id,	  /* gid or uid, depending on type */
-	uint		type,	  /* UDQUOT or GDQUOT */
+	xfs_dqid_t	id,	  /* uid/projid/gid depending on type */
+	uint		type,	  /* XFS_DQ_USER/XFS_DQ_PROJ/XFS_DQ_GROUP */
 	uint		flags,	  /* DQALLOC, DQSUSER, DQREPAIR, DOWARN */
 	xfs_dquot_t	**O_dqpp) /* OUT : locked incore dquot */
 {
@@ -965,6 +909,7 @@ xfs_qm_dqget(
 
 	ASSERT(XFS_IS_QUOTA_RUNNING(mp));
 	if ((! XFS_IS_UQUOTA_ON(mp) && type == XFS_DQ_USER) ||
+	    (! XFS_IS_PQUOTA_ON(mp) && type == XFS_DQ_PROJ) ||
 	    (! XFS_IS_GQUOTA_ON(mp) && type == XFS_DQ_GROUP)) {
 		return (ESRCH);
 	}
@@ -983,7 +928,9 @@ xfs_qm_dqget(
  again:
 
 #ifdef DEBUG
-	ASSERT(type == XFS_DQ_USER || type == XFS_DQ_GROUP);
+	ASSERT(type == XFS_DQ_USER ||
+	       type == XFS_DQ_PROJ ||
+	       type == XFS_DQ_GROUP);
 	if (ip) {
 		ASSERT(XFS_ISLOCKED_INODE_EXCL(ip));
 		if (type == XFS_DQ_USER)
@@ -1306,8 +1253,8 @@ xfs_qm_dqflush(
 		return (error);
 	}
 
-	if (xfs_qm_dqcheck(&dqp->q_core, INT_GET(ddqp->d_id, ARCH_CONVERT), 0, XFS_QMOPT_DOWARN,
-			   "dqflush (incore copy)")) {
+	if (xfs_qm_dqcheck(&dqp->q_core, INT_GET(ddqp->d_id, ARCH_CONVERT),
+			   0, XFS_QMOPT_DOWARN, "dqflush (incore copy)")) {
 		xfs_force_shutdown(dqp->q_mount, XFS_CORRUPT_INCORE);
 		return XFS_ERROR(EIO);
 	}
@@ -1459,7 +1406,8 @@ xfs_dqlock2(
 {
 	if (d1 && d2) {
 		ASSERT(d1 != d2);
-		if (INT_GET(d1->q_core.d_id, ARCH_CONVERT) > INT_GET(d2->q_core.d_id, ARCH_CONVERT)) {
+		if (INT_GET(d1->q_core.d_id, ARCH_CONVERT) >
+		    INT_GET(d2->q_core.d_id, ARCH_CONVERT)) {
 			xfs_dqlock(d2);
 			xfs_dqlock(d1);
 		} else {
@@ -1582,8 +1530,7 @@ xfs_qm_dqprint(xfs_dquot_t *dqp)
 	cmn_err(CE_DEBUG, "-----------KERNEL DQUOT----------------");
 	cmn_err(CE_DEBUG, "---- dquotID =  %d",
 		(int)INT_GET(dqp->q_core.d_id, ARCH_CONVERT));
-	cmn_err(CE_DEBUG, "---- type    =  %s",
-		XFS_QM_ISUDQ(dqp) ? "USR" : "GRP");
+	cmn_err(CE_DEBUG, "---- type    =  %s", DQFLAGTO_TYPESTR(dqp));
 	cmn_err(CE_DEBUG, "---- fs      =  0x%p", dqp->q_mount);
 	cmn_err(CE_DEBUG, "---- blkno   =  0x%x", (int) dqp->q_blkno);
 	cmn_err(CE_DEBUG, "---- boffset =  0x%x", (int) dqp->q_bufoffset);
diff --git a/fs/xfs/quota/xfs_dquot.h b/fs/xfs/quota/xfs_dquot.h
--- a/fs/xfs/quota/xfs_dquot.h
+++ b/fs/xfs/quota/xfs_dquot.h
@@ -114,25 +114,18 @@ typedef struct xfs_dquot {
 #define XFS_DQHOLD(dqp)		((dqp)->q_nrefs++)
 
 /*
- * Quota Accounting flags
+ * Quota Accounting/Enforcement flags
  */
-#define XFS_ALL_QUOTA_ACCT	(XFS_UQUOTA_ACCT | XFS_GQUOTA_ACCT)
-#define XFS_ALL_QUOTA_ENFD	(XFS_UQUOTA_ENFD | XFS_GQUOTA_ENFD)
-#define XFS_ALL_QUOTA_CHKD	(XFS_UQUOTA_CHKD | XFS_GQUOTA_CHKD)
-#define XFS_ALL_QUOTA_ACTV	(XFS_UQUOTA_ACTIVE | XFS_GQUOTA_ACTIVE)
-#define XFS_ALL_QUOTA_ACCT_ENFD (XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD|\
-				 XFS_GQUOTA_ACCT|XFS_GQUOTA_ENFD)
-
-#define XFS_IS_QUOTA_RUNNING(mp)  ((mp)->m_qflags & XFS_ALL_QUOTA_ACCT)
-#define XFS_IS_UQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_UQUOTA_ACCT)
-#define XFS_IS_GQUOTA_RUNNING(mp) ((mp)->m_qflags & XFS_GQUOTA_ACCT)
+#define XFS_ALL_QUOTA_ACCT	\
+		(XFS_UQUOTA_ACCT | XFS_GQUOTA_ACCT | XFS_PQUOTA_ACCT)
+#define XFS_ALL_QUOTA_ENFD	(XFS_UQUOTA_ENFD | XFS_OQUOTA_ENFD)
+#define XFS_ALL_QUOTA_CHKD	(XFS_UQUOTA_CHKD | XFS_OQUOTA_CHKD)
 
-/*
- * Quota Limit Enforcement flags
- */
+#define XFS_IS_QUOTA_RUNNING(mp)	((mp)->m_qflags & XFS_ALL_QUOTA_ACCT)
 #define XFS_IS_QUOTA_ENFORCED(mp)	((mp)->m_qflags & XFS_ALL_QUOTA_ENFD)
-#define XFS_IS_UQUOTA_ENFORCED(mp)	((mp)->m_qflags & XFS_UQUOTA_ENFD)
-#define XFS_IS_GQUOTA_ENFORCED(mp)	((mp)->m_qflags & XFS_GQUOTA_ENFD)
+#define XFS_IS_UQUOTA_RUNNING(mp)	((mp)->m_qflags & XFS_UQUOTA_ACCT)
+#define XFS_IS_PQUOTA_RUNNING(mp)	((mp)->m_qflags & XFS_PQUOTA_ACCT)
+#define XFS_IS_GQUOTA_RUNNING(mp)	((mp)->m_qflags & XFS_GQUOTA_ACCT)
 
 #ifdef DEBUG
 static inline int
@@ -167,6 +160,8 @@ XFS_DQ_IS_LOCKED(xfs_dquot_t *dqp)
 #define XFS_DQ_IS_ON_FREELIST(dqp)  ((dqp)->dq_flnext != (dqp))
 #define XFS_DQ_IS_DIRTY(dqp)	((dqp)->dq_flags & XFS_DQ_DIRTY)
 #define XFS_QM_ISUDQ(dqp)	((dqp)->dq_flags & XFS_DQ_USER)
+#define XFS_QM_ISPDQ(dqp)	((dqp)->dq_flags & XFS_DQ_PROJ)
+#define XFS_QM_ISGDQ(dqp)	((dqp)->dq_flags & XFS_DQ_GROUP)
 #define XFS_DQ_TO_QINF(dqp)	((dqp)->q_mount->m_quotainfo)
 #define XFS_DQ_TO_QIP(dqp)	(XFS_QM_ISUDQ(dqp) ? \
 				 XFS_DQ_TO_QINF(dqp)->qi_uquotaip : \
@@ -174,7 +169,7 @@ XFS_DQ_IS_LOCKED(xfs_dquot_t *dqp)
 
 #define XFS_IS_THIS_QUOTA_OFF(d) (! (XFS_QM_ISUDQ(d) ? \
 				     (XFS_IS_UQUOTA_ON((d)->q_mount)) : \
-				     (XFS_IS_GQUOTA_ON((d)->q_mount))))
+				     (XFS_IS_OQUOTA_ON((d)->q_mount))))
 
 #ifdef XFS_DQUOT_TRACE
 /*
@@ -211,7 +206,6 @@ extern void		xfs_qm_adjust_dqtimers(xfs_
 					xfs_disk_dquot_t *);
 extern void		xfs_qm_adjust_dqlimits(xfs_mount_t *,
 					xfs_disk_dquot_t *);
-extern int		xfs_qm_dqwarn(xfs_disk_dquot_t *, uint);
 extern int		xfs_qm_dqget(xfs_mount_t *, xfs_inode_t *,
 					xfs_dqid_t, uint, uint, xfs_dquot_t **);
 extern void		xfs_qm_dqput(xfs_dquot_t *);
diff --git a/fs/xfs/quota/xfs_dquot_item.c b/fs/xfs/quota/xfs_dquot_item.c
--- a/fs/xfs/quota/xfs_dquot_item.c
+++ b/fs/xfs/quota/xfs_dquot_item.c
@@ -428,7 +428,7 @@ xfs_qm_dquot_logitem_committing(
 /*
  * This is the ops vector for dquots
  */
-struct xfs_item_ops xfs_dquot_item_ops = {
+STATIC struct xfs_item_ops xfs_dquot_item_ops = {
 	.iop_size	= (uint(*)(xfs_log_item_t*))xfs_qm_dquot_logitem_size,
 	.iop_format	= (void(*)(xfs_log_item_t*, xfs_log_iovec_t*))
 					xfs_qm_dquot_logitem_format,
@@ -646,7 +646,7 @@ xfs_qm_qoffend_logitem_committing(xfs_qo
 	return;
 }
 
-struct xfs_item_ops xfs_qm_qoffend_logitem_ops = {
+STATIC struct xfs_item_ops xfs_qm_qoffend_logitem_ops = {
 	.iop_size	= (uint(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_size,
 	.iop_format	= (void(*)(xfs_log_item_t*, xfs_log_iovec_t*))
 					xfs_qm_qoff_logitem_format,
@@ -669,7 +669,7 @@ struct xfs_item_ops xfs_qm_qoffend_logit
 /*
  * This is the ops vector shared by all quotaoff-start log items.
  */
-struct xfs_item_ops xfs_qm_qoff_logitem_ops = {
+STATIC struct xfs_item_ops xfs_qm_qoff_logitem_ops = {
 	.iop_size	= (uint(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_size,
 	.iop_format	= (void(*)(xfs_log_item_t*, xfs_log_iovec_t*))
 					xfs_qm_qoff_logitem_format,
diff --git a/fs/xfs/quota/xfs_qm.c b/fs/xfs/quota/xfs_qm.c
--- a/fs/xfs/quota/xfs_qm.c
+++ b/fs/xfs/quota/xfs_qm.c
@@ -81,12 +81,18 @@ struct xfs_qm	*xfs_Gqm;
 
 kmem_zone_t	*qm_dqzone;
 kmem_zone_t	*qm_dqtrxzone;
-kmem_shaker_t	xfs_qm_shaker;
+STATIC kmem_shaker_t	xfs_qm_shaker;
 
 STATIC void	xfs_qm_list_init(xfs_dqlist_t *, char *, int);
 STATIC void	xfs_qm_list_destroy(xfs_dqlist_t *);
 
+STATIC void	xfs_qm_freelist_init(xfs_frlist_t *);
+STATIC void	xfs_qm_freelist_destroy(xfs_frlist_t *);
+STATIC int	xfs_qm_mplist_nowait(xfs_mount_t *);
+STATIC int	xfs_qm_dqhashlock_nowait(xfs_dquot_t *);
+
 STATIC int	xfs_qm_init_quotainos(xfs_mount_t *);
+STATIC int	xfs_qm_init_quotainfo(xfs_mount_t *);
 STATIC int	xfs_qm_shake(int, unsigned int);
 
 #ifdef DEBUG
@@ -184,7 +190,7 @@ xfs_Gqm_init(void)
 /*
  * Destroy the global quota manager when its reference count goes to zero.
  */
-void
+STATIC void
 xfs_qm_destroy(
 	struct xfs_qm	*xqm)
 {
@@ -304,9 +310,9 @@ xfs_qm_mount_quotainit(
 	uint		flags)
 {
 	/*
-	 * User or group quotas has to be on.
+	 * User, projects or group quotas has to be on.
 	 */
-	ASSERT(flags & (XFSMNT_UQUOTA | XFSMNT_GQUOTA));
+	ASSERT(flags & (XFSMNT_UQUOTA | XFSMNT_PQUOTA | XFSMNT_GQUOTA));
 
 	/*
 	 * Initialize the flags in the mount structure. From this point
@@ -324,7 +330,11 @@ xfs_qm_mount_quotainit(
 	if (flags & XFSMNT_GQUOTA) {
 		mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE);
 		if (flags & XFSMNT_GQUOTAENF)
-			mp->m_qflags |= XFS_GQUOTA_ENFD;
+			mp->m_qflags |= XFS_OQUOTA_ENFD;
+	} else if (flags & XFSMNT_PQUOTA) {
+		mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE);
+		if (flags & XFSMNT_PQUOTAENF)
+			mp->m_qflags |= XFS_OQUOTA_ENFD;
 	}
 }
 
@@ -357,11 +367,11 @@ xfs_qm_mount_quotas(
 
 	/*
 	 * If a file system had quotas running earlier, but decided to
-	 * mount without -o quota/uquota/gquota options, revoke the
+	 * mount without -o uquota/pquota/gquota options, revoke the
 	 * quotachecked license, and bail out.
 	 */
 	if (! XFS_IS_QUOTA_ON(mp) &&
-	    (mp->m_sb.sb_qflags & (XFS_UQUOTA_ACCT|XFS_GQUOTA_ACCT))) {
+	    (mp->m_sb.sb_qflags & XFS_ALL_QUOTA_ACCT)) {
 		mp->m_qflags = 0;
 		goto write_changes;
 	}
@@ -509,7 +519,7 @@ out:
  * Flush all dquots of the given file system to disk. The dquots are
  * _not_ purged from memory here, just their data written to disk.
  */
-int
+STATIC int
 xfs_qm_dqflush_all(
 	xfs_mount_t	*mp,
 	int		flags)
@@ -613,7 +623,7 @@ xfs_qm_detach_gdquots(
 STATIC int
 xfs_qm_dqpurge_int(
 	xfs_mount_t	*mp,
-	uint		flags) /* QUOTAOFF/UMOUNTING/UQUOTA/GQUOTA */
+	uint		flags) /* QUOTAOFF/UMOUNTING/UQUOTA/PQUOTA/GQUOTA */
 {
 	xfs_dquot_t	*dqp;
 	uint		dqtype;
@@ -625,6 +635,7 @@ xfs_qm_dqpurge_int(
 		return (0);
 
 	dqtype = (flags & XFS_QMOPT_UQUOTA) ? XFS_DQ_USER : 0;
+	dqtype |= (flags & XFS_QMOPT_PQUOTA) ? XFS_DQ_PROJ : 0;
 	dqtype |= (flags & XFS_QMOPT_GQUOTA) ? XFS_DQ_GROUP : 0;
 
 	xfs_qm_mplist_lock(mp);
@@ -734,11 +745,11 @@ xfs_qm_dqattach_one(
 
 	/*
 	 * udqhint is the i_udquot field in inode, and is non-NULL only
-	 * when the type arg is XFS_DQ_GROUP. Its purpose is to save a
+	 * when the type arg is group/project. Its purpose is to save a
 	 * lookup by dqid (xfs_qm_dqget) by caching a group dquot inside
 	 * the user dquot.
 	 */
-	ASSERT(!udqhint || type == XFS_DQ_GROUP);
+	ASSERT(!udqhint || type == XFS_DQ_GROUP || type == XFS_DQ_PROJ);
 	if (udqhint && !dolock)
 		xfs_dqlock(udqhint);
 
@@ -897,8 +908,8 @@ xfs_qm_dqattach_grouphint(
 
 
 /*
- * Given a locked inode, attach dquot(s) to it, taking UQUOTAON / GQUOTAON
- * in to account.
+ * Given a locked inode, attach dquot(s) to it, taking U/G/P-QUOTAON
+ * into account.
  * If XFS_QMOPT_DQALLOC, the dquot(s) will be allocated if needed.
  * If XFS_QMOPT_DQLOCK, the dquot(s) will be returned locked. This option pretty
  * much made this code a complete mess, but it has been pretty useful.
@@ -937,8 +948,13 @@ xfs_qm_dqattach(
 		nquotas++;
 	}
 	ASSERT(XFS_ISLOCKED_INODE_EXCL(ip));
-	if (XFS_IS_GQUOTA_ON(mp)) {
-		error = xfs_qm_dqattach_one(ip, ip->i_d.di_gid, XFS_DQ_GROUP,
+	if (XFS_IS_OQUOTA_ON(mp)) {
+		error = XFS_IS_GQUOTA_ON(mp) ?
+			xfs_qm_dqattach_one(ip, ip->i_d.di_gid, XFS_DQ_GROUP,
+						flags & XFS_QMOPT_DQALLOC,
+						flags & XFS_QMOPT_DQLOCK,
+						ip->i_udquot, &ip->i_gdquot) :
+			xfs_qm_dqattach_one(ip, ip->i_d.di_projid, XFS_DQ_PROJ,
 						flags & XFS_QMOPT_DQALLOC,
 						flags & XFS_QMOPT_DQLOCK,
 						ip->i_udquot, &ip->i_gdquot);
@@ -989,7 +1005,7 @@ xfs_qm_dqattach(
 		}
 		if (XFS_IS_UQUOTA_ON(mp))
 			ASSERT(ip->i_udquot);
-		if (XFS_IS_GQUOTA_ON(mp))
+		if (XFS_IS_OQUOTA_ON(mp))
 			ASSERT(ip->i_gdquot);
 	}
 #endif
@@ -1018,13 +1034,13 @@ xfs_qm_dqdetach(
 
 	ASSERT(ip->i_ino != ip->i_mount->m_sb.sb_uquotino);
 	ASSERT(ip->i_ino != ip->i_mount->m_sb.sb_gquotino);
-	if (ip->i_udquot)
-		xfs_dqtrace_entry_ino(ip->i_udquot, "DQDETTACH", ip);
 	if (ip->i_udquot) {
+		xfs_dqtrace_entry_ino(ip->i_udquot, "DQDETTACH", ip);
 		xfs_qm_dqrele(ip->i_udquot);
 		ip->i_udquot = NULL;
 	}
 	if (ip->i_gdquot) {
+		xfs_dqtrace_entry_ino(ip->i_gdquot, "DQDETTACH", ip);
 		xfs_qm_dqrele(ip->i_gdquot);
 		ip->i_gdquot = NULL;
 	}
@@ -1149,7 +1165,7 @@ xfs_qm_sync(
  * This initializes all the quota information that's kept in the
  * mount structure
  */
-int
+STATIC int
 xfs_qm_init_quotainfo(
 	xfs_mount_t	*mp)
 {
@@ -1202,8 +1218,9 @@ xfs_qm_init_quotainfo(
 	 * and group quotas, at least not at this point.
 	 */
 	error = xfs_qm_dqget(mp, NULL, (xfs_dqid_t)0,
-			     (XFS_IS_UQUOTA_RUNNING(mp)) ?
-			     XFS_DQ_USER : XFS_DQ_GROUP,
+			     XFS_IS_UQUOTA_RUNNING(mp) ? XFS_DQ_USER : 
+			     (XFS_IS_GQUOTA_RUNNING(mp) ? XFS_DQ_GROUP :
+				XFS_DQ_PROJ),
 			     XFS_QMOPT_DQSUSER|XFS_QMOPT_DOWARN,
 			     &dqp);
 	if (! error) {
@@ -1234,6 +1251,10 @@ xfs_qm_init_quotainfo(
 				INT_GET(ddqp->d_iwarns, ARCH_CONVERT) ?
 				INT_GET(ddqp->d_iwarns, ARCH_CONVERT) :
 				XFS_QM_IWARNLIMIT;
+		qinf->qi_rtbwarnlimit =
+				INT_GET(ddqp->d_rtbwarns, ARCH_CONVERT) ?
+				INT_GET(ddqp->d_rtbwarns, ARCH_CONVERT) :
+				XFS_QM_RTBWARNLIMIT;
 		qinf->qi_bhardlimit =
 				INT_GET(ddqp->d_blk_hardlimit, ARCH_CONVERT);
 		qinf->qi_bsoftlimit =
@@ -1259,6 +1280,7 @@ xfs_qm_init_quotainfo(
 		qinf->qi_rtbtimelimit = XFS_QM_RTBTIMELIMIT;
 		qinf->qi_bwarnlimit = XFS_QM_BWARNLIMIT;
 		qinf->qi_iwarnlimit = XFS_QM_IWARNLIMIT;
+		qinf->qi_rtbwarnlimit = XFS_QM_RTBWARNLIMIT;
 	}
 
 	return (0);
@@ -1366,13 +1388,20 @@ xfs_qm_dqget_noattach(
 		ASSERT(udqp);
 	}
 
-	if (XFS_IS_GQUOTA_ON(mp)) {
+	if (XFS_IS_OQUOTA_ON(mp)) {
 		ASSERT(ip->i_gdquot == NULL);
 		if (udqp)
 			xfs_dqunlock(udqp);
-		if ((error = xfs_qm_dqget(mp, ip, ip->i_d.di_gid, XFS_DQ_GROUP,
-					 XFS_QMOPT_DQALLOC|XFS_QMOPT_DOWARN,
-					 &gdqp))) {
+		error = XFS_IS_GQUOTA_ON(mp) ?
+				xfs_qm_dqget(mp, ip,
+					     ip->i_d.di_gid, XFS_DQ_GROUP,
+					     XFS_QMOPT_DQALLOC|XFS_QMOPT_DOWARN,
+					     &gdqp) :
+				xfs_qm_dqget(mp, ip,
+					     ip->i_d.di_projid, XFS_DQ_PROJ,
+					     XFS_QMOPT_DQALLOC|XFS_QMOPT_DOWARN,
+					     &gdqp);
+		if (error) {
 			if (udqp)
 				xfs_qm_dqrele(udqp);
 			ASSERT(error != ESRCH);
@@ -1521,8 +1550,10 @@ xfs_qm_reset_dqcounts(
 		INT_SET(ddq->d_rtbcount, ARCH_CONVERT, 0ULL);
 		INT_SET(ddq->d_btimer, ARCH_CONVERT, (time_t)0);
 		INT_SET(ddq->d_itimer, ARCH_CONVERT, (time_t)0);
+		INT_SET(ddq->d_rtbtimer, ARCH_CONVERT, (time_t)0);
 		INT_SET(ddq->d_bwarns, ARCH_CONVERT, 0UL);
 		INT_SET(ddq->d_iwarns, ARCH_CONVERT, 0UL);
+		INT_SET(ddq->d_rtbwarns, ARCH_CONVERT, 0UL);
 		ddq = (xfs_disk_dquot_t *) ((xfs_dqblk_t *)ddq + 1);
 	}
 
@@ -1541,11 +1572,14 @@ xfs_qm_dqiter_bufs(
 	int		error;
 	int		notcommitted;
 	int		incr;
+	int		type;
 
 	ASSERT(blkcnt > 0);
 	notcommitted = 0;
 	incr = (blkcnt > XFS_QM_MAX_DQCLUSTER_LOGSZ) ?
 		XFS_QM_MAX_DQCLUSTER_LOGSZ : blkcnt;
+	type = flags & XFS_QMOPT_UQUOTA ? XFS_DQ_USER :
+		(flags & XFS_QMOPT_PQUOTA ? XFS_DQ_PROJ : XFS_DQ_GROUP);
 	error = 0;
 
 	/*
@@ -1564,9 +1598,7 @@ xfs_qm_dqiter_bufs(
 		if (error)
 			break;
 
-		(void) xfs_qm_reset_dqcounts(mp, bp, firstid,
-					     flags & XFS_QMOPT_UQUOTA ?
-					     XFS_DQ_USER : XFS_DQ_GROUP);
+		(void) xfs_qm_reset_dqcounts(mp, bp, firstid, type);
 		xfs_bdwrite(mp, bp);
 		/*
 		 * goto the next block.
@@ -1578,7 +1610,7 @@ xfs_qm_dqiter_bufs(
 }
 
 /*
- * Iterate over all allocated USR/GRP dquots in the system, calling a
+ * Iterate over all allocated USR/GRP/PRJ dquots in the system, calling a
  * caller supplied function for every chunk of dquots that we find.
  */
 STATIC int
@@ -1849,7 +1881,7 @@ xfs_qm_dqusage_adjust(
 		xfs_qm_quotacheck_dqadjust(udqp, nblks, rtblks);
 		xfs_qm_dqput(udqp);
 	}
-	if (XFS_IS_GQUOTA_ON(mp)) {
+	if (XFS_IS_OQUOTA_ON(mp)) {
 		ASSERT(gdqp);
 		xfs_qm_quotacheck_dqadjust(gdqp, nblks, rtblks);
 		xfs_qm_dqput(gdqp);
@@ -1898,7 +1930,7 @@ xfs_qm_quotacheck(
 	cmn_err(CE_NOTE, "XFS quotacheck %s: Please wait.", mp->m_fsname);
 
 	/*
-	 * First we go thru all the dquots on disk, USR and GRP, and reset
+	 * First we go thru all the dquots on disk, USR and GRP/PRJ, and reset
 	 * their counters to zero. We need a clean slate.
 	 * We don't log our changes till later.
 	 */
@@ -1909,9 +1941,10 @@ xfs_qm_quotacheck(
 	}
 
 	if ((gip = XFS_QI_GQIP(mp))) {
-		if ((error = xfs_qm_dqiterate(mp, gip, XFS_QMOPT_GQUOTA)))
+		if ((error = xfs_qm_dqiterate(mp, gip, XFS_IS_GQUOTA_ON(mp) ?
+					XFS_QMOPT_GQUOTA : XFS_QMOPT_PQUOTA)))
 			goto error_return;
-		flags |= XFS_GQUOTA_CHKD;
+		flags |= XFS_OQUOTA_CHKD;
 	}
 
 	do {
@@ -1938,7 +1971,7 @@ xfs_qm_quotacheck(
 	if (error) {
 		xfs_qm_dqpurge_all(mp,
 				   XFS_QMOPT_UQUOTA|XFS_QMOPT_GQUOTA|
-				   XFS_QMOPT_QUOTAOFF);
+				   XFS_QMOPT_PQUOTA|XFS_QMOPT_QUOTAOFF);
 		goto error_return;
 	}
 	/*
@@ -1961,7 +1994,7 @@ xfs_qm_quotacheck(
 	 * quotachecked status, since we won't be doing accounting for
 	 * that type anymore.
 	 */
-	mp->m_qflags &= ~(XFS_GQUOTA_CHKD | XFS_UQUOTA_CHKD);
+	mp->m_qflags &= ~(XFS_OQUOTA_CHKD | XFS_UQUOTA_CHKD);
 	mp->m_qflags |= flags;
 
 	XQM_LIST_PRINT(&(XFS_QI_MPL_LIST(mp)), MPL_NEXT, "++++ Mp list +++");
@@ -2013,7 +2046,7 @@ xfs_qm_init_quotainos(
 					     0, 0, &uip, 0)))
 				return XFS_ERROR(error);
 		}
-		if (XFS_IS_GQUOTA_ON(mp) &&
+		if (XFS_IS_OQUOTA_ON(mp) &&
 		    mp->m_sb.sb_gquotino != NULLFSINO) {
 			ASSERT(mp->m_sb.sb_gquotino > 0);
 			if ((error = xfs_iget(mp, NULL, mp->m_sb.sb_gquotino,
@@ -2043,10 +2076,12 @@ xfs_qm_init_quotainos(
 
 		flags &= ~XFS_QMOPT_SBVERSION;
 	}
-	if (XFS_IS_GQUOTA_ON(mp) && gip == NULL) {
-		if ((error = xfs_qm_qino_alloc(mp, &gip,
-					      sbflags | XFS_SB_GQUOTINO,
-					      flags | XFS_QMOPT_GQUOTA))) {
+	if (XFS_IS_OQUOTA_ON(mp) && gip == NULL) {
+		flags |= (XFS_IS_GQUOTA_ON(mp) ?
+				XFS_QMOPT_GQUOTA : XFS_QMOPT_PQUOTA);
+		error = xfs_qm_qino_alloc(mp, &gip,
+					  sbflags | XFS_SB_GQUOTINO, flags);
+		if (error) {
 			if (uip)
 				VN_RELE(XFS_ITOV(uip));
 
@@ -2452,6 +2487,7 @@ xfs_qm_vop_dqalloc(
 	xfs_inode_t	*ip,
 	uid_t		uid,
 	gid_t		gid,
+	prid_t		prid,
 	uint		flags,
 	xfs_dquot_t	**O_udqpp,
 	xfs_dquot_t	**O_gdqpp)
@@ -2483,8 +2519,7 @@ xfs_qm_vop_dqalloc(
 	}
 
 	uq = gq = NULL;
-	if ((flags & XFS_QMOPT_UQUOTA) &&
-	    XFS_IS_UQUOTA_ON(mp)) {
+	if ((flags & XFS_QMOPT_UQUOTA) && XFS_IS_UQUOTA_ON(mp)) {
 		if (ip->i_d.di_uid != uid) {
 			/*
 			 * What we need is the dquot that has this uid, and
@@ -2522,8 +2557,7 @@ xfs_qm_vop_dqalloc(
 			xfs_dqunlock(uq);
 		}
 	}
-	if ((flags & XFS_QMOPT_GQUOTA) &&
-	    XFS_IS_GQUOTA_ON(mp)) {
+	if ((flags & XFS_QMOPT_GQUOTA) && XFS_IS_GQUOTA_ON(mp)) {
 		if (ip->i_d.di_gid != gid) {
 			xfs_iunlock(ip, lockflags);
 			if ((error = xfs_qm_dqget(mp, NULL, (xfs_dqid_t)gid,
@@ -2546,6 +2580,29 @@ xfs_qm_vop_dqalloc(
 			XFS_DQHOLD(gq);
 			xfs_dqunlock(gq);
 		}
+	} else if ((flags & XFS_QMOPT_PQUOTA) && XFS_IS_PQUOTA_ON(mp)) {
+		if (ip->i_d.di_projid != prid) {
+			xfs_iunlock(ip, lockflags);
+			if ((error = xfs_qm_dqget(mp, NULL, (xfs_dqid_t)prid,
+						 XFS_DQ_PROJ,
+						 XFS_QMOPT_DQALLOC |
+						 XFS_QMOPT_DOWARN,
+						 &gq))) {
+				if (uq)
+					xfs_qm_dqrele(uq);
+				ASSERT(error != ENOENT);
+				return (error);
+			}
+			xfs_dqunlock(gq);
+			lockflags = XFS_ILOCK_SHARED;
+			xfs_ilock(ip, lockflags);
+		} else {
+			ASSERT(ip->i_gdquot);
+			gq = ip->i_gdquot;
+			xfs_dqlock(gq);
+			XFS_DQHOLD(gq);
+			xfs_dqunlock(gq);
+		}
 	}
 	if (uq)
 		xfs_dqtrace_entry_ino(uq, "DQALLOC", ip);
@@ -2574,6 +2631,9 @@ xfs_qm_vop_chown(
 	xfs_dquot_t	*newdq)
 {
 	xfs_dquot_t	*prevdq;
+	uint		bfield = XFS_IS_REALTIME_INODE(ip) ?
+				 XFS_TRANS_DQ_RTBCOUNT : XFS_TRANS_DQ_BCOUNT;
+
 	ASSERT(XFS_ISLOCKED_INODE_EXCL(ip));
 	ASSERT(XFS_IS_QUOTA_RUNNING(ip->i_mount));
 
@@ -2582,20 +2642,12 @@ xfs_qm_vop_chown(
 	ASSERT(prevdq);
 	ASSERT(prevdq != newdq);
 
-	xfs_trans_mod_dquot(tp, prevdq,
-			    XFS_TRANS_DQ_BCOUNT,
-			    -(ip->i_d.di_nblocks));
-	xfs_trans_mod_dquot(tp, prevdq,
-			    XFS_TRANS_DQ_ICOUNT,
-			    -1);
+	xfs_trans_mod_dquot(tp, prevdq, bfield, -(ip->i_d.di_nblocks));
+	xfs_trans_mod_dquot(tp, prevdq, XFS_TRANS_DQ_ICOUNT, -1);
 
 	/* the sparkling new dquot */
-	xfs_trans_mod_dquot(tp, newdq,
-			    XFS_TRANS_DQ_BCOUNT,
-			    ip->i_d.di_nblocks);
-	xfs_trans_mod_dquot(tp, newdq,
-			    XFS_TRANS_DQ_ICOUNT,
-			    1);
+	xfs_trans_mod_dquot(tp, newdq, bfield, ip->i_d.di_nblocks);
+	xfs_trans_mod_dquot(tp, newdq, XFS_TRANS_DQ_ICOUNT, 1);
 
 	/*
 	 * Take an extra reference, because the inode
@@ -2611,7 +2663,7 @@ xfs_qm_vop_chown(
 }
 
 /*
- * Quota reservations for setattr(AT_UID|AT_GID).
+ * Quota reservations for setattr(AT_UID|AT_GID|AT_PROJID).
  */
 int
 xfs_qm_vop_chown_reserve(
@@ -2623,7 +2675,7 @@ xfs_qm_vop_chown_reserve(
 {
 	int		error;
 	xfs_mount_t	*mp;
-	uint		delblks;
+	uint		delblks, blkflags;
 	xfs_dquot_t	*unresudq, *unresgdq, *delblksudq, *delblksgdq;
 
 	ASSERT(XFS_ISLOCKED_INODE(ip));
@@ -2632,6 +2684,8 @@ xfs_qm_vop_chown_reserve(
 
 	delblks = ip->i_delayed_blks;
 	delblksudq = delblksgdq = unresudq = unresgdq = NULL;
+	blkflags = XFS_IS_REALTIME_INODE(ip) ?
+			XFS_QMOPT_RES_RTBLKS : XFS_QMOPT_RES_REGBLKS;
 
 	if (XFS_IS_UQUOTA_ON(mp) && udqp &&
 	    ip->i_d.di_uid != (uid_t)INT_GET(udqp->q_core.d_id, ARCH_CONVERT)) {
@@ -2646,18 +2700,22 @@ xfs_qm_vop_chown_reserve(
 			unresudq = ip->i_udquot;
 		}
 	}
-	if (XFS_IS_GQUOTA_ON(ip->i_mount) && gdqp &&
-	    ip->i_d.di_gid != INT_GET(gdqp->q_core.d_id, ARCH_CONVERT)) {
-		delblksgdq = gdqp;
-		if (delblks) {
-			ASSERT(ip->i_gdquot);
-			unresgdq = ip->i_gdquot;
+	if (XFS_IS_OQUOTA_ON(ip->i_mount) && gdqp) {
+		if ((XFS_IS_GQUOTA_ON(ip->i_mount) && ip->i_d.di_gid !=
+				INT_GET(gdqp->q_core.d_id, ARCH_CONVERT)) ||
+		    (XFS_IS_PQUOTA_ON(ip->i_mount) && ip->i_d.di_projid !=
+				INT_GET(gdqp->q_core.d_id, ARCH_CONVERT))) {
+			delblksgdq = gdqp;
+			if (delblks) {
+				ASSERT(ip->i_gdquot);
+				unresgdq = ip->i_gdquot;
+			}
 		}
 	}
 
 	if ((error = xfs_trans_reserve_quota_bydquots(tp, ip->i_mount,
 				delblksudq, delblksgdq, ip->i_d.di_nblocks, 1,
-				flags | XFS_QMOPT_RES_REGBLKS)))
+				flags | blkflags)))
 		return (error);
 
 	/*
@@ -2674,11 +2732,11 @@ xfs_qm_vop_chown_reserve(
 		ASSERT(unresudq || unresgdq);
 		if ((error = xfs_trans_reserve_quota_bydquots(NULL, ip->i_mount,
 				delblksudq, delblksgdq, (xfs_qcnt_t)delblks, 0,
-				flags | XFS_QMOPT_RES_REGBLKS)))
+				flags | blkflags)))
 			return (error);
 		xfs_trans_reserve_quota_bydquots(NULL, ip->i_mount,
 				unresudq, unresgdq, -((xfs_qcnt_t)delblks), 0,
-				XFS_QMOPT_RES_REGBLKS);
+				blkflags);
 	}
 
 	return (0);
@@ -2751,7 +2809,7 @@ xfs_qm_vop_dqattach_and_dqmod_newinode(
 }
 
 /* ------------- list stuff -----------------*/
-void
+STATIC void
 xfs_qm_freelist_init(xfs_frlist_t *ql)
 {
 	ql->qh_next = ql->qh_prev = (xfs_dquot_t *) ql;
@@ -2760,7 +2818,7 @@ xfs_qm_freelist_init(xfs_frlist_t *ql)
 	ql->qh_nelems = 0;
 }
 
-void
+STATIC void
 xfs_qm_freelist_destroy(xfs_frlist_t *ql)
 {
 	xfs_dquot_t	*dqp, *nextdqp;
@@ -2786,7 +2844,7 @@ xfs_qm_freelist_destroy(xfs_frlist_t *ql
 	ASSERT(ql->qh_nelems == 0);
 }
 
-void
+STATIC void
 xfs_qm_freelist_insert(xfs_frlist_t *ql, xfs_dquot_t *dq)
 {
 	dq->dq_flnext = ql->qh_next;
@@ -2816,7 +2874,7 @@ xfs_qm_freelist_append(xfs_frlist_t *ql,
 	xfs_qm_freelist_insert((xfs_frlist_t *)ql->qh_prev, dq);
 }
 
-int
+STATIC int
 xfs_qm_dqhashlock_nowait(
 	xfs_dquot_t *dqp)
 {
@@ -2836,7 +2894,7 @@ xfs_qm_freelist_lock_nowait(
 	return (locked);
 }
 
-int
+STATIC int
 xfs_qm_mplist_nowait(
 	xfs_mount_t	*mp)
 {
diff --git a/fs/xfs/quota/xfs_qm.h b/fs/xfs/quota/xfs_qm.h
--- a/fs/xfs/quota/xfs_qm.h
+++ b/fs/xfs/quota/xfs_qm.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2004 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 2000-2005 Silicon Graphics, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -133,8 +133,9 @@ typedef struct xfs_quotainfo {
 	time_t		 qi_btimelimit;	 /* limit for blks timer */
 	time_t		 qi_itimelimit;	 /* limit for inodes timer */
 	time_t		 qi_rtbtimelimit;/* limit for rt blks timer */
-	xfs_qwarncnt_t	 qi_bwarnlimit;	 /* limit for num warnings */
-	xfs_qwarncnt_t	 qi_iwarnlimit;	 /* limit for num warnings */
+	xfs_qwarncnt_t	 qi_bwarnlimit;	 /* limit for blks warnings */
+	xfs_qwarncnt_t	 qi_iwarnlimit;	 /* limit for inodes warnings */
+	xfs_qwarncnt_t	 qi_rtbwarnlimit;/* limit for rt blks warnings */
 	mutex_t		 qi_quotaofflock;/* to serialize quotaoff */
 	xfs_filblks_t	 qi_dqchunklen;	 /* # BBs in a chunk of dqs */
 	uint		 qi_dqperchunk;	 /* # ondisk dqs in above chunk */
@@ -176,6 +177,7 @@ typedef struct xfs_dquot_acct {
 
 #define XFS_QM_BWARNLIMIT	5
 #define XFS_QM_IWARNLIMIT	5
+#define XFS_QM_RTBWARNLIMIT	5
 
 #define XFS_QM_LOCK(xqm)	(mutex_lock(&xqm##_lock, PINOD))
 #define XFS_QM_UNLOCK(xqm)	(mutex_unlock(&xqm##_lock))
@@ -184,7 +186,6 @@ typedef struct xfs_dquot_acct {
 
 extern void		xfs_mount_reset_sbqflags(xfs_mount_t *);
 
-extern int		xfs_qm_init_quotainfo(xfs_mount_t *);
 extern void		xfs_qm_destroy_quotainfo(xfs_mount_t *);
 extern int		xfs_qm_mount_quotas(xfs_mount_t *, int);
 extern void		xfs_qm_mount_quotainit(xfs_mount_t *, uint);
@@ -203,7 +204,7 @@ extern void		xfs_qm_dqrele_all_inodes(xf
 
 /* vop stuff */
 extern int		xfs_qm_vop_dqalloc(xfs_mount_t *, xfs_inode_t *,
-					uid_t, gid_t, uint,
+					uid_t, gid_t, prid_t, uint,
 					xfs_dquot_t **, xfs_dquot_t **);
 extern void		xfs_qm_vop_dqattach_and_dqmod_newinode(
 					xfs_trans_t *, xfs_inode_t *,
@@ -215,14 +216,9 @@ extern int		xfs_qm_vop_chown_reserve(xfs
 					xfs_dquot_t *, xfs_dquot_t *, uint);
 
 /* list stuff */
-extern void		xfs_qm_freelist_init(xfs_frlist_t *);
-extern void		xfs_qm_freelist_destroy(xfs_frlist_t *);
-extern void		xfs_qm_freelist_insert(xfs_frlist_t *, xfs_dquot_t *);
 extern void		xfs_qm_freelist_append(xfs_frlist_t *, xfs_dquot_t *);
 extern void		xfs_qm_freelist_unlink(xfs_dquot_t *);
 extern int		xfs_qm_freelist_lock_nowait(xfs_qm_t *);
-extern int		xfs_qm_mplist_nowait(xfs_mount_t *);
-extern int		xfs_qm_dqhashlock_nowait(xfs_dquot_t *);
 
 /* system call interface */
 extern int		xfs_qm_quotactl(bhv_desc_t *, int, int, xfs_caddr_t);
diff --git a/fs/xfs/quota/xfs_qm_bhv.c b/fs/xfs/quota/xfs_qm_bhv.c
--- a/fs/xfs/quota/xfs_qm_bhv.c
+++ b/fs/xfs/quota/xfs_qm_bhv.c
@@ -71,10 +71,13 @@
 #define MNTOPT_NOQUOTA	"noquota"	/* no quotas */
 #define MNTOPT_USRQUOTA	"usrquota"	/* user quota enabled */
 #define MNTOPT_GRPQUOTA	"grpquota"	/* group quota enabled */
+#define MNTOPT_PRJQUOTA	"prjquota"	/* project quota enabled */
 #define MNTOPT_UQUOTA	"uquota"	/* user quota (IRIX variant) */
 #define MNTOPT_GQUOTA	"gquota"	/* group quota (IRIX variant) */
+#define MNTOPT_PQUOTA	"pquota"	/* project quota (IRIX variant) */
 #define MNTOPT_UQUOTANOENF "uqnoenforce"/* user quota limit enforcement */
 #define MNTOPT_GQUOTANOENF "gqnoenforce"/* group quota limit enforcement */
+#define MNTOPT_PQUOTANOENF "pqnoenforce"/* project quota limit enforcement */
 #define MNTOPT_QUOTANOENF  "qnoenforce"	/* same as uqnoenforce */
 
 STATIC int
@@ -109,6 +112,14 @@ xfs_qm_parseargs(
 			args->flags |= XFSMNT_UQUOTA;
 			args->flags &= ~XFSMNT_UQUOTAENF;
 			referenced = 1;
+		} else if (!strcmp(this_char, MNTOPT_PQUOTA) ||
+			   !strcmp(this_char, MNTOPT_PRJQUOTA)) {
+			args->flags |= XFSMNT_PQUOTA | XFSMNT_PQUOTAENF;
+			referenced = 1;
+		} else if (!strcmp(this_char, MNTOPT_PQUOTANOENF)) {
+			args->flags |= XFSMNT_PQUOTA;
+			args->flags &= ~XFSMNT_PQUOTAENF;
+			referenced = 1;
 		} else if (!strcmp(this_char, MNTOPT_GQUOTA) ||
 			   !strcmp(this_char, MNTOPT_GRPQUOTA)) {
 			args->flags |= XFSMNT_GQUOTA | XFSMNT_GQUOTAENF;
@@ -127,6 +138,12 @@ xfs_qm_parseargs(
 			*this_char++ = ',';
 	}
 
+	if ((args->flags & XFSMNT_GQUOTA) && (args->flags & XFSMNT_PQUOTA)) {
+		cmn_err(CE_WARN,
+			"XFS: cannot mount with both project and group quota");
+		return XFS_ERROR(EINVAL);
+	}
+
 	PVFS_PARSEARGS(BHV_NEXT(bhv), options, args, update, error);
 	if (!error && !referenced)
 		bhv_remove_vfsops(bhvtovfs(bhv), VFS_POSITION_QM);
@@ -148,13 +165,19 @@ xfs_qm_showargs(
 			seq_puts(m, "," MNTOPT_UQUOTANOENF);
 	}
 
+	if (mp->m_qflags & XFS_PQUOTA_ACCT) {
+		(mp->m_qflags & XFS_OQUOTA_ENFD) ?
+			seq_puts(m, "," MNTOPT_PRJQUOTA) :
+			seq_puts(m, "," MNTOPT_PQUOTANOENF);
+	}
+
 	if (mp->m_qflags & XFS_GQUOTA_ACCT) {
-		(mp->m_qflags & XFS_GQUOTA_ENFD) ?
+		(mp->m_qflags & XFS_OQUOTA_ENFD) ?
 			seq_puts(m, "," MNTOPT_GRPQUOTA) :
 			seq_puts(m, "," MNTOPT_GQUOTANOENF);
 	}
 
-	if (!(mp->m_qflags & (XFS_UQUOTA_ACCT|XFS_GQUOTA_ACCT)))
+	if (!(mp->m_qflags & XFS_ALL_QUOTA_ACCT))
 		seq_puts(m, "," MNTOPT_NOQUOTA);
 
 	PVFS_SHOWARGS(BHV_NEXT(bhv), m, error);
@@ -171,7 +194,7 @@ xfs_qm_mount(
 	struct xfs_mount	*mp = XFS_VFSTOM(vfsp);
 	int			error;
 
-	if (args->flags & (XFSMNT_UQUOTA | XFSMNT_GQUOTA))
+	if (args->flags & (XFSMNT_UQUOTA | XFSMNT_GQUOTA | XFSMNT_PQUOTA))
 		xfs_qm_mount_quotainit(mp, args->flags);
 	PVFS_MOUNT(BHV_NEXT(bhv), args, cr, error);
 	return error;
@@ -255,16 +278,17 @@ xfs_qm_newmount(
 	uint		*quotaflags)
 {
 	uint		quotaondisk;
-	uint		uquotaondisk = 0, gquotaondisk = 0;
+	uint		uquotaondisk = 0, gquotaondisk = 0, pquotaondisk = 0;
 
 	*quotaflags = 0;
 	*needquotamount = B_FALSE;
 
 	quotaondisk = XFS_SB_VERSION_HASQUOTA(&mp->m_sb) &&
-		mp->m_sb.sb_qflags & (XFS_UQUOTA_ACCT|XFS_GQUOTA_ACCT);
+				(mp->m_sb.sb_qflags & XFS_ALL_QUOTA_ACCT);
 
 	if (quotaondisk) {
 		uquotaondisk = mp->m_sb.sb_qflags & XFS_UQUOTA_ACCT;
+		pquotaondisk = mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT;
 		gquotaondisk = mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT;
 	}
 
@@ -277,13 +301,16 @@ xfs_qm_newmount(
 
 	if (((uquotaondisk && !XFS_IS_UQUOTA_ON(mp)) ||
 	    (!uquotaondisk &&  XFS_IS_UQUOTA_ON(mp)) ||
+	     (pquotaondisk && !XFS_IS_PQUOTA_ON(mp)) ||
+	    (!pquotaondisk &&  XFS_IS_PQUOTA_ON(mp)) ||
 	     (gquotaondisk && !XFS_IS_GQUOTA_ON(mp)) ||
-	    (!gquotaondisk &&  XFS_IS_GQUOTA_ON(mp)))  &&
+	    (!gquotaondisk &&  XFS_IS_OQUOTA_ON(mp)))  &&
 	    xfs_dev_is_read_only(mp, "changing quota state")) {
 		cmn_err(CE_WARN,
-			"XFS: please mount with%s%s%s.",
+			"XFS: please mount with%s%s%s%s.",
 			(!quotaondisk ? "out quota" : ""),
 			(uquotaondisk ? " usrquota" : ""),
+			(pquotaondisk ? " prjquota" : ""),
 			(gquotaondisk ? " grpquota" : ""));
 		return XFS_ERROR(EPERM);
 	}
@@ -359,7 +386,7 @@ xfs_qm_dqrele_null(
 }
 
 
-struct xfs_qmops xfs_qmcore_xfs = {
+STATIC struct xfs_qmops xfs_qmcore_xfs = {
 	.xfs_qminit		= xfs_qm_newmount,
 	.xfs_qmdone		= xfs_qm_unmount_quotadestroy,
 	.xfs_qmmount		= xfs_qm_endmount,
diff --git a/fs/xfs/quota/xfs_qm_syscalls.c b/fs/xfs/quota/xfs_qm_syscalls.c
--- a/fs/xfs/quota/xfs_qm_syscalls.c
+++ b/fs/xfs/quota/xfs_qm_syscalls.c
@@ -118,40 +118,41 @@ xfs_qm_quotactl(
 	 * The following commands are valid even when quotaoff.
 	 */
 	switch (cmd) {
+	case Q_XQUOTARM:
 		/*
-		 * truncate quota files. quota must be off.
+		 * Truncate quota files. quota must be off.
 		 */
-	      case Q_XQUOTARM:
 		if (XFS_IS_QUOTA_ON(mp) || addr == NULL)
 			return XFS_ERROR(EINVAL);
 		if (vfsp->vfs_flag & VFS_RDONLY)
 			return XFS_ERROR(EROFS);
 		return (xfs_qm_scall_trunc_qfiles(mp,
 			       xfs_qm_import_qtype_flags(*(uint *)addr)));
+
+	case Q_XGETQSTAT:
 		/*
 		 * Get quota status information.
 		 */
-	      case Q_XGETQSTAT:
 		return (xfs_qm_scall_getqstat(mp, (fs_quota_stat_t *)addr));
 
+	case Q_XQUOTAON:
 		/*
-		 * QUOTAON for root f/s and quota enforcement on others..
-		 * Quota accounting for non-root f/s's must be turned on
-		 * at mount time.
+		 * QUOTAON - enabling quota enforcement.
+		 * Quota accounting must be turned on at mount time.
 		 */
-	      case Q_XQUOTAON:
 		if (addr == NULL)
 			return XFS_ERROR(EINVAL);
 		if (vfsp->vfs_flag & VFS_RDONLY)
 			return XFS_ERROR(EROFS);
 		return (xfs_qm_scall_quotaon(mp,
 					  xfs_qm_import_flags(*(uint *)addr)));
-	      case Q_XQUOTAOFF:
+
+	case Q_XQUOTAOFF:
 		if (vfsp->vfs_flag & VFS_RDONLY)
 			return XFS_ERROR(EROFS);
 		break;
 
-	      default:
+	default:
 		break;
 	}
 
@@ -159,7 +160,7 @@ xfs_qm_quotactl(
 		return XFS_ERROR(ESRCH);
 
 	switch (cmd) {
-	      case Q_XQUOTAOFF:
+	case Q_XQUOTAOFF:
 		if (vfsp->vfs_flag & VFS_RDONLY)
 			return XFS_ERROR(EROFS);
 		error = xfs_qm_scall_quotaoff(mp,
@@ -167,42 +168,39 @@ xfs_qm_quotactl(
 					    B_FALSE);
 		break;
 
-		/*
-		 * Defaults to XFS_GETUQUOTA.
-		 */
-	      case Q_XGETQUOTA:
+	case Q_XGETQUOTA:
 		error = xfs_qm_scall_getquota(mp, (xfs_dqid_t)id, XFS_DQ_USER,
 					(fs_disk_quota_t *)addr);
 		break;
-		/*
-		 * Set limits, both hard and soft. Defaults to Q_SETUQLIM.
-		 */
-	      case Q_XSETQLIM:
+	case Q_XGETGQUOTA:
+		error = xfs_qm_scall_getquota(mp, (xfs_dqid_t)id, XFS_DQ_GROUP,
+					(fs_disk_quota_t *)addr);
+		break;
+	case Q_XGETPQUOTA:
+		error = xfs_qm_scall_getquota(mp, (xfs_dqid_t)id, XFS_DQ_PROJ,
+					(fs_disk_quota_t *)addr);
+		break;
+
+	case Q_XSETQLIM:
 		if (vfsp->vfs_flag & VFS_RDONLY)
 			return XFS_ERROR(EROFS);
 		error = xfs_qm_scall_setqlim(mp, (xfs_dqid_t)id, XFS_DQ_USER,
 					     (fs_disk_quota_t *)addr);
 		break;
-
-	       case Q_XSETGQLIM:
+	case Q_XSETGQLIM:
 		if (vfsp->vfs_flag & VFS_RDONLY)
 			return XFS_ERROR(EROFS);
 		error = xfs_qm_scall_setqlim(mp, (xfs_dqid_t)id, XFS_DQ_GROUP,
 					     (fs_disk_quota_t *)addr);
 		break;
-
-
-	      case Q_XGETGQUOTA:
-		error = xfs_qm_scall_getquota(mp, (xfs_dqid_t)id, XFS_DQ_GROUP,
-					(fs_disk_quota_t *)addr);
+	case Q_XSETPQLIM:
+		if (vfsp->vfs_flag & VFS_RDONLY)
+			return XFS_ERROR(EROFS);
+		error = xfs_qm_scall_setqlim(mp, (xfs_dqid_t)id, XFS_DQ_PROJ,
+					     (fs_disk_quota_t *)addr);
 		break;
 
-		/*
-		 * Quotas are entirely undefined after quotaoff in XFS quotas.
-		 * For instance, there's no way to set limits when quotaoff.
-		 */
-
-	      default:
+	default:
 		error = XFS_ERROR(EINVAL);
 		break;
 	}
@@ -286,8 +284,12 @@ xfs_qm_scall_quotaoff(
 	}
 	if (flags & XFS_GQUOTA_ACCT) {
 		dqtype |= XFS_QMOPT_GQUOTA;
-		flags |= (XFS_GQUOTA_CHKD | XFS_GQUOTA_ENFD);
+		flags |= (XFS_OQUOTA_CHKD | XFS_OQUOTA_ENFD);
 		inactivate_flags |= XFS_GQUOTA_ACTIVE;
+	} else if (flags & XFS_PQUOTA_ACCT) {
+		dqtype |= XFS_QMOPT_PQUOTA;
+		flags |= (XFS_OQUOTA_CHKD | XFS_OQUOTA_ENFD);
+		inactivate_flags |= XFS_PQUOTA_ACTIVE;
 	}
 
 	/*
@@ -364,7 +366,8 @@ xfs_qm_scall_quotaoff(
 	/*
 	 * If quotas is completely disabled, close shop.
 	 */
-	if ((flags & XFS_MOUNT_QUOTA_ALL) == XFS_MOUNT_QUOTA_ALL) {
+	if (((flags & XFS_MOUNT_QUOTA_ALL) == XFS_MOUNT_QUOTA_SET1) ||
+	    ((flags & XFS_MOUNT_QUOTA_ALL) == XFS_MOUNT_QUOTA_SET2)) {
 		mutex_unlock(&(XFS_QI_QOFFLOCK(mp)));
 		xfs_qm_destroy_quotainfo(mp);
 		return (0);
@@ -378,7 +381,7 @@ xfs_qm_scall_quotaoff(
 		XFS_PURGE_INODE(XFS_QI_UQIP(mp));
 		XFS_QI_UQIP(mp) = NULL;
 	}
-	if ((dqtype & XFS_QMOPT_GQUOTA) && XFS_QI_GQIP(mp)) {
+	if ((dqtype & (XFS_QMOPT_GQUOTA|XFS_QMOPT_PQUOTA)) && XFS_QI_GQIP(mp)) {
 		XFS_PURGE_INODE(XFS_QI_GQIP(mp));
 		XFS_QI_GQIP(mp) = NULL;
 	}
@@ -411,7 +414,8 @@ xfs_qm_scall_trunc_qfiles(
 		}
 	}
 
-	if ((flags & XFS_DQ_GROUP) && mp->m_sb.sb_gquotino != NULLFSINO) {
+	if ((flags & (XFS_DQ_GROUP|XFS_DQ_PROJ)) &&
+	    mp->m_sb.sb_gquotino != NULLFSINO) {
 		error = xfs_iget(mp, NULL, mp->m_sb.sb_gquotino, 0, 0, &qip, 0);
 		if (! error) {
 			(void) xfs_truncate_file(mp, qip);
@@ -434,7 +438,7 @@ xfs_qm_scall_quotaon(
 	uint		flags)
 {
 	int		error;
-	unsigned long s;
+	unsigned long	s;
 	uint		qf;
 	uint		accflags;
 	__int64_t	sbflags;
@@ -468,9 +472,13 @@ xfs_qm_scall_quotaon(
 	    (mp->m_sb.sb_qflags & XFS_UQUOTA_ACCT) == 0 &&
 	    (flags & XFS_UQUOTA_ENFD))
 	    ||
+	    ((flags & XFS_PQUOTA_ACCT) == 0 &&
+	    (mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT) == 0 &&
+	    (flags & XFS_OQUOTA_ENFD))
+	    ||
 	    ((flags & XFS_GQUOTA_ACCT) == 0 &&
 	    (mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT) == 0 &&
-	    (flags & XFS_GQUOTA_ENFD))) {
+	    (flags & XFS_OQUOTA_ENFD))) {
 		qdprintk("Can't enforce without acct, flags=%x sbflags=%x\n",
 			flags, mp->m_sb.sb_qflags);
 		return XFS_ERROR(EINVAL);
@@ -504,6 +512,10 @@ xfs_qm_scall_quotaon(
 	 */
 	if  (((mp->m_sb.sb_qflags & XFS_UQUOTA_ACCT) !=
 	     (mp->m_qflags & XFS_UQUOTA_ACCT)) ||
+	     ((mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT) !=
+	     (mp->m_qflags & XFS_PQUOTA_ACCT)) ||
+	     ((mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT) !=
+	     (mp->m_qflags & XFS_GQUOTA_ACCT)) ||
 	    (flags & XFS_ALL_QUOTA_ENFD) == 0)
 		return (0);
 
@@ -521,7 +533,6 @@ xfs_qm_scall_quotaon(
 }
 
 
-
 /*
  * Return quota status information, such as uquota-off, enforcements, etc.
  */
@@ -606,7 +617,8 @@ xfs_qm_scall_setqlim(
 	if (!capable(CAP_SYS_ADMIN))
 		return XFS_ERROR(EPERM);
 
-	if ((newlim->d_fieldmask & (FS_DQ_LIMIT_MASK|FS_DQ_TIMER_MASK)) == 0)
+	if ((newlim->d_fieldmask &
+	    (FS_DQ_LIMIT_MASK|FS_DQ_TIMER_MASK|FS_DQ_WARNS_MASK)) == 0)
 		return (0);
 
 	tp = xfs_trans_alloc(mp, XFS_TRANS_QM_SETQLIM);
@@ -691,12 +703,23 @@ xfs_qm_scall_setqlim(
 		qdprintk("ihard %Ld < isoft %Ld\n", hard, soft);
 	}
 
+	/*
+	 * Update warnings counter(s) if requested
+	 */
+	if (newlim->d_fieldmask & FS_DQ_BWARNS)
+		INT_SET(ddq->d_bwarns, ARCH_CONVERT, newlim->d_bwarns);
+	if (newlim->d_fieldmask & FS_DQ_IWARNS)
+		INT_SET(ddq->d_iwarns, ARCH_CONVERT, newlim->d_iwarns);
+	if (newlim->d_fieldmask & FS_DQ_RTBWARNS)
+		INT_SET(ddq->d_rtbwarns, ARCH_CONVERT, newlim->d_rtbwarns);
+
 	if (id == 0) {
 		/*
 		 * Timelimits for the super user set the relative time
 		 * the other users can be over quota for this file system.
 		 * If it is zero a default is used.  Ditto for the default
-		 * soft and hard limit values (already done, above).
+		 * soft and hard limit values (already done, above), and
+		 * for warnings.
 		 */
 		if (newlim->d_fieldmask & FS_DQ_BTIMER) {
 			mp->m_quotainfo->qi_btimelimit = newlim->d_btimer;
@@ -710,7 +733,13 @@ xfs_qm_scall_setqlim(
 			mp->m_quotainfo->qi_rtbtimelimit = newlim->d_rtbtimer;
 			INT_SET(ddq->d_rtbtimer, ARCH_CONVERT, newlim->d_rtbtimer);
 		}
-	} else /* if (XFS_IS_QUOTA_ENFORCED(mp)) */ {
+		if (newlim->d_fieldmask & FS_DQ_BWARNS)
+			mp->m_quotainfo->qi_bwarnlimit = newlim->d_bwarns;
+		if (newlim->d_fieldmask & FS_DQ_IWARNS)
+			mp->m_quotainfo->qi_iwarnlimit = newlim->d_iwarns;
+		if (newlim->d_fieldmask & FS_DQ_RTBWARNS)
+			mp->m_quotainfo->qi_rtbwarnlimit = newlim->d_rtbwarns;
+	} else {
 		/*
 		 * If the user is now over quota, start the timelimit.
 		 * The user will not be 'warned'.
@@ -776,9 +805,9 @@ xfs_qm_log_quotaoff_end(
 	xfs_qoff_logitem_t	*startqoff,
 	uint			flags)
 {
-	xfs_trans_t	       *tp;
+	xfs_trans_t		*tp;
 	int			error;
-	xfs_qoff_logitem_t     *qoffi;
+	xfs_qoff_logitem_t	*qoffi;
 
 	tp = xfs_trans_alloc(mp, XFS_TRANS_QM_QUOTAOFF_END);
 
@@ -928,18 +957,26 @@ xfs_qm_export_dquot(
 
 STATIC uint
 xfs_qm_import_qtype_flags(
-	uint uflags)
+	uint		uflags)
 {
+	uint		oflags = 0;
+
 	/*
-	 * Can't be both at the same time.
+	 * Can't be more than one, or none.
 	 */
 	if (((uflags & (XFS_GROUP_QUOTA | XFS_USER_QUOTA)) ==
-	     (XFS_GROUP_QUOTA | XFS_USER_QUOTA)) ||
-	    ((uflags & (XFS_GROUP_QUOTA | XFS_USER_QUOTA)) == 0))
+			(XFS_GROUP_QUOTA | XFS_USER_QUOTA)) ||
+	    ((uflags & (XFS_GROUP_QUOTA | XFS_PROJ_QUOTA)) ==
+			(XFS_GROUP_QUOTA | XFS_PROJ_QUOTA)) ||
+	    ((uflags & (XFS_USER_QUOTA | XFS_PROJ_QUOTA)) ==
+			(XFS_USER_QUOTA | XFS_PROJ_QUOTA)) ||
+	    ((uflags & (XFS_GROUP_QUOTA|XFS_USER_QUOTA|XFS_PROJ_QUOTA)) == 0))
 		return (0);
 
-	return (uflags & XFS_USER_QUOTA) ?
-		XFS_DQ_USER : XFS_DQ_GROUP;
+	oflags |= (uflags & XFS_USER_QUOTA) ? XFS_DQ_USER : 0;
+	oflags |= (uflags & XFS_PROJ_QUOTA) ? XFS_DQ_PROJ : 0;
+	oflags |= (uflags & XFS_GROUP_QUOTA) ? XFS_DQ_GROUP: 0;
+	return oflags;
 }
 
 STATIC uint
@@ -947,14 +984,19 @@ xfs_qm_export_qtype_flags(
 	uint flags)
 {
 	/*
-	 * Can't be both at the same time.
+	 * Can't be more than one, or none.
 	 */
-	ASSERT((flags & (XFS_GROUP_QUOTA | XFS_USER_QUOTA)) !=
-		(XFS_GROUP_QUOTA | XFS_USER_QUOTA));
-	ASSERT((flags & (XFS_GROUP_QUOTA | XFS_USER_QUOTA)) != 0);
+	ASSERT((flags & (XFS_PROJ_QUOTA | XFS_USER_QUOTA)) !=
+		(XFS_PROJ_QUOTA | XFS_USER_QUOTA));
+	ASSERT((flags & (XFS_PROJ_QUOTA | XFS_GROUP_QUOTA)) !=
+		(XFS_PROJ_QUOTA | XFS_GROUP_QUOTA));
+	ASSERT((flags & (XFS_USER_QUOTA | XFS_GROUP_QUOTA)) !=
+		(XFS_USER_QUOTA | XFS_GROUP_QUOTA));
+	ASSERT((flags & (XFS_PROJ_QUOTA|XFS_USER_QUOTA|XFS_GROUP_QUOTA)) != 0);
 
 	return (flags & XFS_DQ_USER) ?
-		XFS_USER_QUOTA : XFS_GROUP_QUOTA;
+		XFS_USER_QUOTA : (flags & XFS_DQ_PROJ) ?
+			XFS_PROJ_QUOTA : XFS_GROUP_QUOTA;
 }
 
 STATIC uint
@@ -965,12 +1007,14 @@ xfs_qm_import_flags(
 
 	if (uflags & XFS_QUOTA_UDQ_ACCT)
 		flags |= XFS_UQUOTA_ACCT;
+	if (uflags & XFS_QUOTA_PDQ_ACCT)
+		flags |= XFS_PQUOTA_ACCT;
 	if (uflags & XFS_QUOTA_GDQ_ACCT)
 		flags |= XFS_GQUOTA_ACCT;
 	if (uflags & XFS_QUOTA_UDQ_ENFD)
 		flags |= XFS_UQUOTA_ENFD;
-	if (uflags & XFS_QUOTA_GDQ_ENFD)
-		flags |= XFS_GQUOTA_ENFD;
+	if (uflags & (XFS_QUOTA_PDQ_ENFD|XFS_QUOTA_GDQ_ENFD))
+		flags |= XFS_OQUOTA_ENFD;
 	return (flags);
 }
 
@@ -984,12 +1028,16 @@ xfs_qm_export_flags(
 	uflags = 0;
 	if (flags & XFS_UQUOTA_ACCT)
 		uflags |= XFS_QUOTA_UDQ_ACCT;
+	if (flags & XFS_PQUOTA_ACCT)
+		uflags |= XFS_QUOTA_PDQ_ACCT;
 	if (flags & XFS_GQUOTA_ACCT)
 		uflags |= XFS_QUOTA_GDQ_ACCT;
 	if (flags & XFS_UQUOTA_ENFD)
 		uflags |= XFS_QUOTA_UDQ_ENFD;
-	if (flags & XFS_GQUOTA_ENFD)
-		uflags |= XFS_QUOTA_GDQ_ENFD;
+	if (flags & (XFS_OQUOTA_ENFD)) {
+		uflags |= (flags & XFS_GQUOTA_ACCT) ?
+			XFS_QUOTA_GDQ_ENFD : XFS_QUOTA_PDQ_ENFD;
+	}
 	return (uflags);
 }
 
@@ -1070,7 +1118,7 @@ again:
 			xfs_qm_dqrele(ip->i_udquot);
 			ip->i_udquot = NULL;
 		}
-		if ((flags & XFS_GQUOTA_ACCT) && ip->i_gdquot) {
+		if (flags & (XFS_PQUOTA_ACCT|XFS_GQUOTA_ACCT) && ip->i_gdquot) {
 			xfs_qm_dqrele(ip->i_gdquot);
 			ip->i_gdquot = NULL;
 		}
@@ -1160,7 +1208,6 @@ xfs_qm_dqtest_print(
 {
 	cmn_err(CE_DEBUG, "-----------DQTEST DQUOT----------------");
 	cmn_err(CE_DEBUG, "---- dquot ID = %d", d->d_id);
-	cmn_err(CE_DEBUG, "---- type     = %s", XFS_QM_ISUDQ(d)? "USR" : "GRP");
 	cmn_err(CE_DEBUG, "---- fs       = 0x%p", d->q_mount);
 	cmn_err(CE_DEBUG, "---- bcount   = %Lu (0x%x)",
 		d->d_bcount, (int)d->d_bcount);
@@ -1231,7 +1278,7 @@ xfs_dqtest_cmp2(
 #ifdef QUOTADEBUG
 	if (!err) {
 		cmn_err(CE_DEBUG, "%d [%s] [0x%p] qchecked",
-			d->d_id, XFS_QM_ISUDQ(d) ? "USR" : "GRP", d->q_mount);
+			d->d_id, DQFLAGTO_TYPESTR(d), d->q_mount);
 	}
 #endif
 	return (err);
@@ -1287,6 +1334,7 @@ STATIC void
 xfs_qm_internalqcheck_get_dquots(
 	xfs_mount_t	*mp,
 	xfs_dqid_t	uid,
+	xfs_dqid_t	projid,
 	xfs_dqid_t	gid,
 	xfs_dqtest_t	**ud,
 	xfs_dqtest_t	**gd)
@@ -1295,6 +1343,8 @@ xfs_qm_internalqcheck_get_dquots(
 		xfs_qm_internalqcheck_dqget(mp, uid, XFS_DQ_USER, ud);
 	if (XFS_IS_GQUOTA_ON(mp))
 		xfs_qm_internalqcheck_dqget(mp, gid, XFS_DQ_GROUP, gd);
+	else if (XFS_IS_PQUOTA_ON(mp))
+		xfs_qm_internalqcheck_dqget(mp, projid, XFS_DQ_PROJ, gd);
 }
 
 
@@ -1362,13 +1412,14 @@ xfs_qm_internalqcheck_adjust(
 	}
 	xfs_qm_internalqcheck_get_dquots(mp,
 					(xfs_dqid_t) ip->i_d.di_uid,
+					(xfs_dqid_t) ip->i_d.di_projid,
 					(xfs_dqid_t) ip->i_d.di_gid,
 					&ud, &gd);
 	if (XFS_IS_UQUOTA_ON(mp)) {
 		ASSERT(ud);
 		xfs_qm_internalqcheck_dqadjust(ip, ud);
 	}
-	if (XFS_IS_GQUOTA_ON(mp)) {
+	if (XFS_IS_OQUOTA_ON(mp)) {
 		ASSERT(gd);
 		xfs_qm_internalqcheck_dqadjust(ip, gd);
 	}
diff --git a/fs/xfs/quota/xfs_quota_priv.h b/fs/xfs/quota/xfs_quota_priv.h
--- a/fs/xfs/quota/xfs_quota_priv.h
+++ b/fs/xfs/quota/xfs_quota_priv.h
@@ -56,6 +56,7 @@
 #define XFS_QI_RTBTIMELIMIT(mp) ((mp)->m_quotainfo->qi_rtbtimelimit)
 #define XFS_QI_ITIMELIMIT(mp)	((mp)->m_quotainfo->qi_itimelimit)
 #define XFS_QI_BWARNLIMIT(mp)	((mp)->m_quotainfo->qi_bwarnlimit)
+#define XFS_QI_RTBWARNLIMIT(mp)	((mp)->m_quotainfo->qi_rtbwarnlimit)
 #define XFS_QI_IWARNLIMIT(mp)	((mp)->m_quotainfo->qi_iwarnlimit)
 #define XFS_QI_QOFFLOCK(mp)	((mp)->m_quotainfo->qi_quotaofflock)
 
@@ -102,7 +103,8 @@ static inline int XQMISLCKD(struct xfs_d
 				     (xfs_Gqm->qm_grp_dqhtable + \
 				      XFS_DQ_HASHVAL(mp, id)))
 #define XFS_IS_DQTYPE_ON(mp, type)   (type == XFS_DQ_USER ? \
-				      XFS_IS_UQUOTA_ON(mp):XFS_IS_GQUOTA_ON(mp))
+					XFS_IS_UQUOTA_ON(mp) : \
+					XFS_IS_OQUOTA_ON(mp))
 #define XFS_IS_DQUOT_UNINITIALIZED(dqp) ( \
 	!dqp->q_core.d_blk_hardlimit && \
 	!dqp->q_core.d_blk_softlimit && \
@@ -177,16 +179,11 @@ for ((dqp) = (qlist)->qh_next; (dqp) != 
 	(!((dqp)->q_core.d_id))
 
 #define XFS_PURGE_INODE(ip)		\
-	{				\
-	  vmap_t dqvmap;		\
-	  vnode_t *dqvp;		\
-	  dqvp = XFS_ITOV(ip);		\
-	  VMAP(dqvp, dqvmap);		\
-	  VN_RELE(dqvp);		\
-	}
+	IRELE(ip);
 
 #define DQFLAGTO_TYPESTR(d)	(((d)->dq_flags & XFS_DQ_USER) ? "USR" : \
-				 (((d)->dq_flags & XFS_DQ_GROUP) ? "GRP" : "???"))
+				 (((d)->dq_flags & XFS_DQ_GROUP) ? "GRP" : \
+				 (((d)->dq_flags & XFS_DQ_PROJ) ? "PRJ":"???")))
 #define DQFLAGTO_DIRTYSTR(d)	(XFS_DQ_IS_DIRTY(d) ? "DIRTY" : "NOTDIRTY")
 
 #endif	/* __XFS_QUOTA_PRIV_H__ */
diff --git a/fs/xfs/quota/xfs_trans_dquot.c b/fs/xfs/quota/xfs_trans_dquot.c
--- a/fs/xfs/quota/xfs_trans_dquot.c
+++ b/fs/xfs/quota/xfs_trans_dquot.c
@@ -187,7 +187,7 @@ xfs_trans_dup_dqinfo(
 /*
  * Wrap around mod_dquot to account for both user and group quotas.
  */
-void
+STATIC void
 xfs_trans_mod_dquot_byino(
 	xfs_trans_t	*tp,
 	xfs_inode_t	*ip,
@@ -207,12 +207,10 @@ xfs_trans_mod_dquot_byino(
 	if (tp->t_dqinfo == NULL)
 		xfs_trans_alloc_dqinfo(tp);
 
-	if (XFS_IS_UQUOTA_ON(mp) && ip->i_udquot) {
+	if (XFS_IS_UQUOTA_ON(mp) && ip->i_udquot)
 		(void) xfs_trans_mod_dquot(tp, ip->i_udquot, field, delta);
-	}
-	if (XFS_IS_GQUOTA_ON(mp) && ip->i_gdquot) {
+	if (XFS_IS_OQUOTA_ON(mp) && ip->i_gdquot)
 		(void) xfs_trans_mod_dquot(tp, ip->i_gdquot, field, delta);
-	}
 }
 
 STATIC xfs_dqtrx_t *
@@ -368,7 +366,7 @@ xfs_trans_dqlockedjoin(
  * Unreserve just the reservations done by this transaction.
  * dquot is still left locked at exit.
  */
-void
+STATIC void
 xfs_trans_apply_dquot_deltas(
 	xfs_trans_t		*tp)
 {
@@ -499,7 +497,7 @@ xfs_trans_apply_dquot_deltas(
 			 * Adjust the RT reservation.
 			 */
 			if (qtrx->qt_rtblk_res != 0) {
-				if (qtrx->qt_blk_res != qtrx->qt_blk_res_used) {
+				if (qtrx->qt_rtblk_res != qtrx->qt_rtblk_res_used) {
 					if (qtrx->qt_rtblk_res >
 					    qtrx->qt_rtblk_res_used)
 					       dqp->q_res_rtbcount -= (xfs_qcnt_t)
@@ -532,12 +530,6 @@ xfs_trans_apply_dquot_deltas(
 					    (xfs_qcnt_t)qtrx->qt_icount_delta;
 			}
 
-
-#ifdef QUOTADEBUG
-			if (qtrx->qt_rtblk_res != 0)
-				cmn_err(CE_DEBUG, "RT res %d for 0x%p\n",
-					(int) qtrx->qt_rtblk_res, dqp);
-#endif
 			ASSERT(dqp->q_res_bcount >=
 				INT_GET(dqp->q_core.d_bcount, ARCH_CONVERT));
 			ASSERT(dqp->q_res_icount >=
@@ -638,7 +630,10 @@ xfs_trans_dqresv(
 	int		error;
 	xfs_qcnt_t	hardlimit;
 	xfs_qcnt_t	softlimit;
-	time_t		btimer;
+	time_t		timer;
+	xfs_qwarncnt_t	warns;
+	xfs_qwarncnt_t	warnlimit;
+	xfs_qcnt_t	count;
 	xfs_qcnt_t	*resbcountp;
 	xfs_quotainfo_t	*q = mp->m_quotainfo;
 
@@ -653,7 +648,9 @@ xfs_trans_dqresv(
 		softlimit = INT_GET(dqp->q_core.d_blk_softlimit, ARCH_CONVERT);
 		if (!softlimit)
 			softlimit = q->qi_bsoftlimit;
-		btimer = INT_GET(dqp->q_core.d_btimer, ARCH_CONVERT);
+		timer = INT_GET(dqp->q_core.d_btimer, ARCH_CONVERT);
+		warns = INT_GET(dqp->q_core.d_bwarns, ARCH_CONVERT);
+		warnlimit = XFS_QI_BWARNLIMIT(dqp->q_mount);
 		resbcountp = &dqp->q_res_bcount;
 	} else {
 		ASSERT(flags & XFS_TRANS_DQ_RES_RTBLKS);
@@ -663,7 +660,9 @@ xfs_trans_dqresv(
 		softlimit = INT_GET(dqp->q_core.d_rtb_softlimit, ARCH_CONVERT);
 		if (!softlimit)
 			softlimit = q->qi_rtbsoftlimit;
-		btimer = INT_GET(dqp->q_core.d_rtbtimer, ARCH_CONVERT);
+		timer = INT_GET(dqp->q_core.d_rtbtimer, ARCH_CONVERT);
+		warns = INT_GET(dqp->q_core.d_rtbwarns, ARCH_CONVERT);
+		warnlimit = XFS_QI_RTBWARNLIMIT(dqp->q_mount);
 		resbcountp = &dqp->q_res_rtbcount;
 	}
 	error = 0;
@@ -693,37 +692,36 @@ xfs_trans_dqresv(
 				 * If timer or warnings has expired,
 				 * return EDQUOT
 				 */
-				if ((btimer != 0 && get_seconds() > btimer) ||
-				    (dqp->q_core.d_bwarns &&
-				     INT_GET(dqp->q_core.d_bwarns, ARCH_CONVERT) >=
-				     XFS_QI_BWARNLIMIT(dqp->q_mount))) {
+				if ((timer != 0 && get_seconds() > timer) ||
+				    (warns != 0 && warns >= warnlimit)) {
 					error = EDQUOT;
 					goto error_return;
 				}
 			}
 		}
 		if (ninos > 0) {
-			hardlimit = INT_GET(dqp->q_core.d_ino_hardlimit, ARCH_CONVERT);
+			count = INT_GET(dqp->q_core.d_icount, ARCH_CONVERT);
+			timer = INT_GET(dqp->q_core.d_itimer, ARCH_CONVERT);
+			warns = INT_GET(dqp->q_core.d_iwarns, ARCH_CONVERT);
+			warnlimit = XFS_QI_IWARNLIMIT(dqp->q_mount);
+			hardlimit = INT_GET(dqp->q_core.d_ino_hardlimit,
+						ARCH_CONVERT);
 			if (!hardlimit)
 				hardlimit = q->qi_ihardlimit;
-			softlimit = INT_GET(dqp->q_core.d_ino_softlimit, ARCH_CONVERT);
+			softlimit = INT_GET(dqp->q_core.d_ino_softlimit,
+						ARCH_CONVERT);
 			if (!softlimit)
 				softlimit = q->qi_isoftlimit;
-			if (hardlimit > 0ULL &&
-			    INT_GET(dqp->q_core.d_icount, ARCH_CONVERT) >= hardlimit) {
+			if (hardlimit > 0ULL && count >= hardlimit) {
 				error = EDQUOT;
 				goto error_return;
-			} else if (softlimit > 0ULL &&
-				   INT_GET(dqp->q_core.d_icount, ARCH_CONVERT) >= softlimit) {
+			} else if (softlimit > 0ULL && count >= softlimit) {
 				/*
 				 * If timer or warnings has expired,
 				 * return EDQUOT
 				 */
-				if ((dqp->q_core.d_itimer &&
-				     get_seconds() > INT_GET(dqp->q_core.d_itimer, ARCH_CONVERT)) ||
-				    (dqp->q_core.d_iwarns &&
-				     INT_GET(dqp->q_core.d_iwarns, ARCH_CONVERT) >=
-				     XFS_QI_IWARNLIMIT(dqp->q_mount))) {
+				if ((timer != 0 && get_seconds() > timer) ||
+				     (warns != 0 && warns >= warnlimit)) {
 					error = EDQUOT;
 					goto error_return;
 				}
diff --git a/fs/xfs/support/debug.c b/fs/xfs/support/debug.c
--- a/fs/xfs/support/debug.c
+++ b/fs/xfs/support/debug.c
@@ -36,7 +36,6 @@
 #include <linux/sched.h>
 #include <linux/kernel.h>
 
-int			doass = 1;
 static char		message[256];	/* keep it off the stack */
 static DEFINE_SPINLOCK(xfs_err_lock);
 
diff --git a/fs/xfs/support/debug.h b/fs/xfs/support/debug.h
--- a/fs/xfs/support/debug.h
+++ b/fs/xfs/support/debug.h
@@ -50,16 +50,11 @@ extern void cmn_err(int, char *, ...);
 #endif
 
 #ifdef DEBUG
-# ifdef lint
-#  define ASSERT(EX)	((void)0) /* avoid "constant in conditional" babble */
-# else
-#  define ASSERT(EX) ((!doass||(EX))?((void)0):assfail(#EX, __FILE__, __LINE__))
-# endif	/* lint */
+# define ASSERT(EX)	((EX) ? ((void)0) : assfail(#EX, __FILE__, __LINE__))
 #else
 # define ASSERT(x)	((void)0)
 #endif
 
-extern int doass;		/* dynamically turn off asserts */
 extern void assfail(char *, char *, int);
 #ifdef DEBUG
 extern unsigned long random(void);
diff --git a/fs/xfs/xfs_alloc.c b/fs/xfs/xfs_alloc.c
--- a/fs/xfs/xfs_alloc.c
+++ b/fs/xfs/xfs_alloc.c
@@ -59,7 +59,7 @@
 #define	XFSA_FIXUP_BNO_OK	1
 #define	XFSA_FIXUP_CNT_OK	2
 
-int
+STATIC int
 xfs_alloc_search_busy(xfs_trans_t *tp,
 		    xfs_agnumber_t agno,
 		    xfs_agblock_t bno,
@@ -2562,7 +2562,7 @@ xfs_alloc_clear_busy(xfs_trans_t *tp,
 /*
  * returns non-zero if any of (agno,bno):len is in a busy list
  */
-int
+STATIC int
 xfs_alloc_search_busy(xfs_trans_t *tp,
 		    xfs_agnumber_t agno,
 		    xfs_agblock_t bno,
diff --git a/fs/xfs/xfs_attr.c b/fs/xfs/xfs_attr.c
--- a/fs/xfs/xfs_attr.c
+++ b/fs/xfs/xfs_attr.c
@@ -71,6 +71,11 @@
  * Provide the external interfaces to manage attribute lists.
  */
 
+#define ATTR_SYSCOUNT	2
+STATIC struct attrnames posix_acl_access;
+STATIC struct attrnames posix_acl_default;
+STATIC struct attrnames *attr_system_names[ATTR_SYSCOUNT];
+
 /*========================================================================
  * Function prototypes for the kernel.
  *========================================================================*/
@@ -83,6 +88,7 @@ STATIC int xfs_attr_shortform_addname(xf
 /*
  * Internal routines when attribute list is one block.
  */
+STATIC int xfs_attr_leaf_get(xfs_da_args_t *args);
 STATIC int xfs_attr_leaf_addname(xfs_da_args_t *args);
 STATIC int xfs_attr_leaf_removename(xfs_da_args_t *args);
 STATIC int xfs_attr_leaf_list(xfs_attr_list_context_t *context);
@@ -90,6 +96,7 @@ STATIC int xfs_attr_leaf_list(xfs_attr_l
 /*
  * Internal routines when attribute list is more than one block.
  */
+STATIC int xfs_attr_node_get(xfs_da_args_t *args);
 STATIC int xfs_attr_node_addname(xfs_da_args_t *args);
 STATIC int xfs_attr_node_removename(xfs_da_args_t *args);
 STATIC int xfs_attr_node_list(xfs_attr_list_context_t *context);
@@ -1102,7 +1109,7 @@ xfs_attr_leaf_removename(xfs_da_args_t *
  * This leaf block cannot have a "remote" value, we only call this routine
  * if bmap_one_block() says there is only one block (ie: no remote blks).
  */
-int
+STATIC int
 xfs_attr_leaf_get(xfs_da_args_t *args)
 {
 	xfs_dabuf_t *bp;
@@ -1707,7 +1714,7 @@ xfs_attr_refillstate(xfs_da_state_t *sta
  * block, ie: both true Btree attr lists and for single-leaf-blocks with
  * "remote" values taking up more blocks.
  */
-int
+STATIC int
 xfs_attr_node_get(xfs_da_args_t *args)
 {
 	xfs_da_state_t *state;
@@ -2398,7 +2405,7 @@ posix_acl_default_exists(
 	return xfs_acl_vhasacl_default(vp);
 }
 
-struct attrnames posix_acl_access = {
+STATIC struct attrnames posix_acl_access = {
 	.attr_name	= "posix_acl_access",
 	.attr_namelen	= sizeof("posix_acl_access") - 1,
 	.attr_get	= posix_acl_access_get,
@@ -2407,7 +2414,7 @@ struct attrnames posix_acl_access = {
 	.attr_exists	= posix_acl_access_exists,
 };
 
-struct attrnames posix_acl_default = {
+STATIC struct attrnames posix_acl_default = {
 	.attr_name	= "posix_acl_default",
 	.attr_namelen	= sizeof("posix_acl_default") - 1,
 	.attr_get	= posix_acl_default_get,
@@ -2416,7 +2423,7 @@ struct attrnames posix_acl_default = {
 	.attr_exists	= posix_acl_default_exists,
 };
 
-struct attrnames *attr_system_names[] =
+STATIC struct attrnames *attr_system_names[] =
 	{ &posix_acl_access, &posix_acl_default };
 
 
diff --git a/fs/xfs/xfs_attr.h b/fs/xfs/xfs_attr.h
--- a/fs/xfs/xfs_attr.h
+++ b/fs/xfs/xfs_attr.h
@@ -76,11 +76,6 @@ extern struct attrnames attr_system;
 extern struct attrnames attr_trusted;
 extern struct attrnames *attr_namespaces[ATTR_NAMECOUNT];
 
-#define ATTR_SYSCOUNT	2
-extern struct attrnames posix_acl_access;
-extern struct attrnames posix_acl_default;
-extern struct attrnames *attr_system_names[ATTR_SYSCOUNT];
-
 extern attrnames_t *attr_lookup_namespace(char *, attrnames_t **, int);
 extern int attr_generic_list(struct vnode *, void *, size_t, int, ssize_t *);
 
@@ -184,8 +179,6 @@ int xfs_attr_list(bhv_desc_t *, char *, 
 			 struct attrlist_cursor_kern *, struct cred *);
 int xfs_attr_inactive(struct xfs_inode *dp);
 
-int xfs_attr_node_get(struct xfs_da_args *);
-int xfs_attr_leaf_get(struct xfs_da_args *);
 int xfs_attr_shortform_getvalue(struct xfs_da_args *);
 int xfs_attr_fetch(struct xfs_inode *, char *, int,
 			char *, int *, int, struct cred *);
diff --git a/fs/xfs/xfs_attr_leaf.c b/fs/xfs/xfs_attr_leaf.c
--- a/fs/xfs/xfs_attr_leaf.c
+++ b/fs/xfs/xfs_attr_leaf.c
@@ -79,6 +79,8 @@
 /*
  * Routines used for growing the Btree.
  */
+STATIC int xfs_attr_leaf_create(xfs_da_args_t *args, xfs_dablk_t which_block,
+				    xfs_dabuf_t **bpp);
 STATIC int xfs_attr_leaf_add_work(xfs_dabuf_t *leaf_buffer, xfs_da_args_t *args,
 					      int freemap_index);
 STATIC void xfs_attr_leaf_compact(xfs_trans_t *trans, xfs_dabuf_t *leaf_buffer);
@@ -92,6 +94,16 @@ STATIC int xfs_attr_leaf_figure_balance(
 					   int *number_usedbytes_in_blk1);
 
 /*
+ * Routines used for shrinking the Btree.
+ */
+STATIC int xfs_attr_node_inactive(xfs_trans_t **trans, xfs_inode_t *dp,
+				  xfs_dabuf_t *bp, int level);
+STATIC int xfs_attr_leaf_inactive(xfs_trans_t **trans, xfs_inode_t *dp,
+				  xfs_dabuf_t *bp);
+STATIC int xfs_attr_leaf_freextent(xfs_trans_t **trans, xfs_inode_t *dp,
+				   xfs_dablk_t blkno, int blkcnt);
+
+/*
  * Utility routines.
  */
 STATIC void xfs_attr_leaf_moveents(xfs_attr_leafblock_t *src_leaf,
@@ -99,6 +111,10 @@ STATIC void xfs_attr_leaf_moveents(xfs_a
 					 xfs_attr_leafblock_t *dst_leaf,
 					 int dst_start, int move_count,
 					 xfs_mount_t *mp);
+STATIC int xfs_attr_leaf_entsize(xfs_attr_leafblock_t *leaf, int index);
+STATIC int xfs_attr_put_listent(xfs_attr_list_context_t *context,
+			     attrnames_t *, char *name, int namelen,
+			     int valuelen);
 
 
 /*========================================================================
@@ -774,7 +790,7 @@ out:
  * Create the initial contents of a leaf attribute list
  * or a leaf in a node attribute list.
  */
-int
+STATIC int
 xfs_attr_leaf_create(xfs_da_args_t *args, xfs_dablk_t blkno, xfs_dabuf_t **bpp)
 {
 	xfs_attr_leafblock_t *leaf;
@@ -2209,7 +2225,7 @@ xfs_attr_leaf_lasthash(xfs_dabuf_t *bp, 
  * Calculate the number of bytes used to store the indicated attribute
  * (whether local or remote only calculate bytes in this block).
  */
-int
+STATIC int
 xfs_attr_leaf_entsize(xfs_attr_leafblock_t *leaf, int index)
 {
 	xfs_attr_leaf_name_local_t *name_loc;
@@ -2380,7 +2396,7 @@ xfs_attr_leaf_list_int(xfs_dabuf_t *bp, 
  * we may be reading them directly out of a user buffer.
  */
 /*ARGSUSED*/
-int
+STATIC int
 xfs_attr_put_listent(xfs_attr_list_context_t *context,
 		     attrnames_t *namesp, char *name, int namelen, int valuelen)
 {
@@ -2740,7 +2756,7 @@ xfs_attr_root_inactive(xfs_trans_t **tra
  * Recurse (gasp!) through the attribute nodes until we find leaves.
  * We're doing a depth-first traversal in order to invalidate everything.
  */
-int
+STATIC int
 xfs_attr_node_inactive(xfs_trans_t **trans, xfs_inode_t *dp, xfs_dabuf_t *bp,
 				   int level)
 {
@@ -2849,7 +2865,7 @@ xfs_attr_node_inactive(xfs_trans_t **tra
  * Note that we must release the lock on the buffer so that we are not
  * caught holding something that the logging code wants to flush to disk.
  */
-int
+STATIC int
 xfs_attr_leaf_inactive(xfs_trans_t **trans, xfs_inode_t *dp, xfs_dabuf_t *bp)
 {
 	xfs_attr_leafblock_t *leaf;
@@ -2934,7 +2950,7 @@ xfs_attr_leaf_inactive(xfs_trans_t **tra
  * Look at all the extents for this logical region,
  * invalidate any buffers that are incore/in transactions.
  */
-int
+STATIC int
 xfs_attr_leaf_freextent(xfs_trans_t **trans, xfs_inode_t *dp,
 				    xfs_dablk_t blkno, int blkcnt)
 {
diff --git a/fs/xfs/xfs_attr_leaf.h b/fs/xfs/xfs_attr_leaf.h
--- a/fs/xfs/xfs_attr_leaf.h
+++ b/fs/xfs/xfs_attr_leaf.h
@@ -261,8 +261,6 @@ int	xfs_attr_leaf_flipflags(xfs_da_args_
 /*
  * Routines used for growing the Btree.
  */
-int	xfs_attr_leaf_create(struct xfs_da_args *args, xfs_dablk_t which_block,
-				    struct xfs_dabuf **bpp);
 int	xfs_attr_leaf_split(struct xfs_da_state *state,
 				   struct xfs_da_state_blk *oldblk,
 				   struct xfs_da_state_blk *newblk);
@@ -284,12 +282,6 @@ void	xfs_attr_leaf_unbalance(struct xfs_
 				       struct xfs_da_state_blk *drop_blk,
 				       struct xfs_da_state_blk *save_blk);
 int	xfs_attr_root_inactive(struct xfs_trans **trans, struct xfs_inode *dp);
-int	xfs_attr_node_inactive(struct xfs_trans **trans, struct xfs_inode *dp,
-				      struct xfs_dabuf *bp, int level);
-int	xfs_attr_leaf_inactive(struct xfs_trans **trans, struct xfs_inode *dp,
-				      struct xfs_dabuf *bp);
-int	xfs_attr_leaf_freextent(struct xfs_trans **trans, struct xfs_inode *dp,
-				       xfs_dablk_t blkno, int blkcnt);
 
 /*
  * Utility routines.
@@ -299,10 +291,6 @@ int	xfs_attr_leaf_order(struct xfs_dabuf
 				   struct xfs_dabuf *leaf2_bp);
 int	xfs_attr_leaf_newentsize(struct xfs_da_args *args, int blocksize,
 					int *local);
-int	xfs_attr_leaf_entsize(struct xfs_attr_leafblock *leaf, int index);
-int	xfs_attr_put_listent(struct xfs_attr_list_context *context,
-			     struct attrnames *, char *name, int namelen,
-			     int valuelen);
 int	xfs_attr_rolltrans(struct xfs_trans **transp, struct xfs_inode *dp);
 
 #endif	/* __XFS_ATTR_LEAF_H__ */
diff --git a/fs/xfs/xfs_bit.c b/fs/xfs/xfs_bit.c
--- a/fs/xfs/xfs_bit.c
+++ b/fs/xfs/xfs_bit.c
@@ -45,7 +45,7 @@
 /*
  * Index of high bit number in byte, -1 for none set, 0..7 otherwise.
  */
-const char xfs_highbit[256] = {
+STATIC const char xfs_highbit[256] = {
        -1, 0, 1, 1, 2, 2, 2, 2,			/* 00 .. 07 */
 	3, 3, 3, 3, 3, 3, 3, 3,			/* 08 .. 0f */
 	4, 4, 4, 4, 4, 4, 4, 4,			/* 10 .. 17 */
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c
--- a/fs/xfs/xfs_bmap.c
+++ b/fs/xfs/xfs_bmap.c
@@ -301,6 +301,19 @@ xfs_bmap_search_extents(
 	xfs_bmbt_irec_t	*gotp,		/* out: extent entry found */
 	xfs_bmbt_irec_t	*prevp);	/* out: previous extent entry found */
 
+/*
+ * Check the last inode extent to determine whether this allocation will result
+ * in blocks being allocated at the end of the file. When we allocate new data
+ * blocks at the end of the file which do not start at the previous data block,
+ * we will try to align the new blocks at stripe unit boundaries.
+ */
+STATIC int				/* error */
+xfs_bmap_isaeof(
+	xfs_inode_t	*ip,		/* incore inode pointer */
+	xfs_fileoff_t   off,		/* file offset in fsblocks */
+	int             whichfork,	/* data or attribute fork */
+	char		*aeof);		/* return value */
+
 #ifdef XFS_BMAP_TRACE
 /*
  * Add a bmap trace buffer entry.  Base routine for the others.
@@ -4532,18 +4545,17 @@ xfs_bmapi(
 	xfs_extlen_t	alen;		/* allocated extent length */
 	xfs_fileoff_t	aoff;		/* allocated file offset */
 	xfs_bmalloca_t	bma;		/* args for xfs_bmap_alloc */
-	char		contig;		/* allocation must be one extent */
 	xfs_btree_cur_t	*cur;		/* bmap btree cursor */
-	char		delay;		/* this request is for delayed alloc */
 	xfs_fileoff_t	end;		/* end of mapped file region */
 	int		eof;		/* we've hit the end of extent list */
+	char		contig;		/* allocation must be one extent */
+	char		delay;		/* this request is for delayed alloc */
+	char		exact;		/* don't do all of wasdelayed extent */
 	xfs_bmbt_rec_t	*ep;		/* extent list entry pointer */
 	int		error;		/* error return */
-	char		exact;		/* don't do all of wasdelayed extent */
 	xfs_bmbt_irec_t	got;		/* current extent list record */
 	xfs_ifork_t	*ifp;		/* inode fork pointer */
 	xfs_extlen_t	indlen;		/* indirect blocks length */
-	char		inhole;		/* current location is hole in file */
 	xfs_extnum_t	lastx;		/* last useful extent number */
 	int		logflags;	/* flags for transaction logging */
 	xfs_extlen_t	minleft;	/* min blocks left after allocation */
@@ -4554,13 +4566,15 @@ xfs_bmapi(
 	xfs_extnum_t	nextents;	/* number of extents in file */
 	xfs_fileoff_t	obno;		/* old block number (offset) */
 	xfs_bmbt_irec_t	prev;		/* previous extent list record */
-	char		stateless;	/* ignore state flag set */
 	int		tmp_logflags;	/* temp flags holder */
+	int		whichfork;	/* data or attr fork */
+	char		inhole;		/* current location is hole in file */
+	char		stateless;	/* ignore state flag set */
 	char		trim;		/* output trimmed to match range */
 	char		userdata;	/* allocating non-metadata */
 	char		wasdelay;	/* old extent was delayed */
-	int		whichfork;	/* data or attr fork */
 	char		wr;		/* this is a write request */
+	char		rt;		/* this is a realtime file */
 	char		rsvd;		/* OK to allocate reserved blocks */
 #ifdef DEBUG
 	xfs_fileoff_t	orig_bno;	/* original block number value */
@@ -4590,6 +4604,7 @@ xfs_bmapi(
 	}
 	if (XFS_FORCED_SHUTDOWN(mp))
 		return XFS_ERROR(EIO);
+	rt = XFS_IS_REALTIME_INODE(ip);
 	ifp = XFS_IFORK_PTR(ip, whichfork);
 	ASSERT(ifp->if_ext_max ==
 	       XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t));
@@ -4694,9 +4709,16 @@ xfs_bmapi(
 			}
 			minlen = contig ? alen : 1;
 			if (delay) {
-				indlen = (xfs_extlen_t)
-					xfs_bmap_worst_indlen(ip, alen);
-				ASSERT(indlen > 0);
+				xfs_extlen_t	extsz = 0;
+
+				/* Figure out the extent size, adjust alen */
+				if (rt) {
+					if (!(extsz = ip->i_d.di_extsize))
+						extsz = mp->m_sb.sb_rextsize;
+					alen = roundup(alen, extsz);
+					extsz = alen / mp->m_sb.sb_rextsize;
+				}
+
 				/*
 				 * Make a transaction-less quota reservation for
 				 * delayed allocation blocks. This number gets
@@ -4704,8 +4726,10 @@ xfs_bmapi(
 				 * We return EDQUOT if we haven't allocated
 				 * blks already inside this loop;
 				 */
-				if (XFS_TRANS_RESERVE_BLKQUOTA(
-						mp, NULL, ip, (long)alen)) {
+				if (XFS_TRANS_RESERVE_QUOTA_NBLKS(
+						mp, NULL, ip, (long)alen, 0,
+						rt ? XFS_QMOPT_RES_RTBLKS :
+						     XFS_QMOPT_RES_REGBLKS)) {
 					if (n == 0) {
 						*nmap = 0;
 						ASSERT(cur == NULL);
@@ -4718,40 +4742,34 @@ xfs_bmapi(
 				 * Split changing sb for alen and indlen since
 				 * they could be coming from different places.
 				 */
-				if (ip->i_d.di_flags & XFS_DIFLAG_REALTIME) {
-					xfs_extlen_t	extsz;
-					xfs_extlen_t	ralen;
-					if (!(extsz = ip->i_d.di_extsize))
-						extsz = mp->m_sb.sb_rextsize;
-					ralen = roundup(alen, extsz);
-					ralen = ralen / mp->m_sb.sb_rextsize;
-					if (xfs_mod_incore_sb(mp,
-						XFS_SBS_FREXTENTS,
-						-(ralen), rsvd)) {
-						if (XFS_IS_QUOTA_ON(ip->i_mount))
-							XFS_TRANS_UNRESERVE_BLKQUOTA(
-						     		mp, NULL, ip,
-								(long)alen);
-						break;
-					}
-				} else {
-					if (xfs_mod_incore_sb(mp,
-							      XFS_SBS_FDBLOCKS,
-							      -(alen), rsvd)) {
-						if (XFS_IS_QUOTA_ON(ip->i_mount))
-							XFS_TRANS_UNRESERVE_BLKQUOTA(
-								mp, NULL, ip,
-								(long)alen);
-						break;
-					}
-				}
+				indlen = (xfs_extlen_t)
+					xfs_bmap_worst_indlen(ip, alen);
+				ASSERT(indlen > 0);
 
-				if (xfs_mod_incore_sb(mp, XFS_SBS_FDBLOCKS,
-						-(indlen), rsvd)) {
-					XFS_TRANS_UNRESERVE_BLKQUOTA(
-						mp, NULL, ip, (long)alen);
+				if (rt)
+					error = xfs_mod_incore_sb(mp,
+							XFS_SBS_FREXTENTS,
+							-(extsz), rsvd);
+				else
+					error = xfs_mod_incore_sb(mp,
+							XFS_SBS_FDBLOCKS,
+							-(alen), rsvd);
+				if (!error)
+					error = xfs_mod_incore_sb(mp,
+							XFS_SBS_FDBLOCKS,
+							-(indlen), rsvd);
+
+				if (error) {
+					if (XFS_IS_QUOTA_ON(ip->i_mount))
+						/* unreserve the blocks now */
+						XFS_TRANS_UNRESERVE_QUOTA_NBLKS(
+							mp, NULL, ip,
+							(long)alen, 0, rt ?
+							XFS_QMOPT_RES_RTBLKS :
+							XFS_QMOPT_RES_REGBLKS);
 					break;
 				}
+
 				ip->i_delayed_blks += alen;
 				abno = NULLSTARTBLOCK(indlen);
 			} else {
@@ -5376,13 +5394,24 @@ xfs_bunmapi(
 		}
 		if (wasdel) {
 			ASSERT(STARTBLOCKVAL(del.br_startblock) > 0);
-			xfs_mod_incore_sb(mp, XFS_SBS_FDBLOCKS,
-				(int)del.br_blockcount, rsvd);
-			/* Unreserve our quota space */
-			XFS_TRANS_RESERVE_QUOTA_NBLKS(
-				mp, NULL, ip, -((long)del.br_blockcount), 0,
-				isrt ?	XFS_QMOPT_RES_RTBLKS :
+			/* Update realtim/data freespace, unreserve quota */
+			if (isrt) {
+				xfs_filblks_t rtexts;
+
+				rtexts = XFS_FSB_TO_B(mp, del.br_blockcount);
+				do_div(rtexts, mp->m_sb.sb_rextsize);
+				xfs_mod_incore_sb(mp, XFS_SBS_FREXTENTS,
+						(int)rtexts, rsvd);
+				XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, NULL, ip,
+					-((long)del.br_blockcount), 0,
+					XFS_QMOPT_RES_RTBLKS);
+			} else {
+				xfs_mod_incore_sb(mp, XFS_SBS_FDBLOCKS,
+						(int)del.br_blockcount, rsvd);
+				XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, NULL, ip,
+					-((long)del.br_blockcount), 0,
 					XFS_QMOPT_RES_REGBLKS);
+			}
 			ip->i_delayed_blks -= del.br_blockcount;
 			if (cur)
 				cur->bc_private.b.flags |=
@@ -5714,7 +5743,7 @@ unlock_and_return:
  * blocks at the end of the file which do not start at the previous data block,
  * we will try to align the new blocks at stripe unit boundaries.
  */
-int					/* error */
+STATIC int				/* error */
 xfs_bmap_isaeof(
 	xfs_inode_t	*ip,		/* incore inode pointer */
 	xfs_fileoff_t   off,		/* file offset in fsblocks */
diff --git a/fs/xfs/xfs_bmap.h b/fs/xfs/xfs_bmap.h
--- a/fs/xfs/xfs_bmap.h
+++ b/fs/xfs/xfs_bmap.h
@@ -332,19 +332,6 @@ xfs_getbmap(
 	int			iflags);	/* interface flags */
 
 /*
- * Check the last inode extent to determine whether this allocation will result
- * in blocks being allocated at the end of the file. When we allocate new data
- * blocks at the end of the file which do not start at the previous data block,
- * we will try to align the new blocks at stripe unit boundaries.
- */
-int
-xfs_bmap_isaeof(
-	struct xfs_inode	*ip,
-	xfs_fileoff_t		off,
-	int			whichfork,
-	char			*aeof);
-
-/*
  * Check if the endoff is outside the last extent. If so the caller will grow
  * the allocation to a stripe unit boundary
  */
diff --git a/fs/xfs/xfs_bmap_btree.c b/fs/xfs/xfs_bmap_btree.c
--- a/fs/xfs/xfs_bmap_btree.c
+++ b/fs/xfs/xfs_bmap_btree.c
@@ -2331,20 +2331,6 @@ xfs_bmbt_lookup_ge(
 	return xfs_bmbt_lookup(cur, XFS_LOOKUP_GE, stat);
 }
 
-int					/* error */
-xfs_bmbt_lookup_le(
-	xfs_btree_cur_t	*cur,
-	xfs_fileoff_t	off,
-	xfs_fsblock_t	bno,
-	xfs_filblks_t	len,
-	int		*stat)		/* success/failure */
-{
-	cur->bc_rec.b.br_startoff = off;
-	cur->bc_rec.b.br_startblock = bno;
-	cur->bc_rec.b.br_blockcount = len;
-	return xfs_bmbt_lookup(cur, XFS_LOOKUP_LE, stat);
-}
-
 /*
  * Give the bmap btree a new root block.  Copy the old broot contents
  * down into a real block and make the broot point to it.
diff --git a/fs/xfs/xfs_bmap_btree.h b/fs/xfs/xfs_bmap_btree.h
--- a/fs/xfs/xfs_bmap_btree.h
+++ b/fs/xfs/xfs_bmap_btree.h
@@ -580,14 +580,6 @@ xfs_bmbt_lookup_ge(
 	xfs_filblks_t,
 	int *);
 
-int
-xfs_bmbt_lookup_le(
-	struct xfs_btree_cur *,
-	xfs_fileoff_t,
-	xfs_fsblock_t,
-	xfs_filblks_t,
-	int *);
-
 /*
  * Give the bmap btree a new root block.  Copy the old broot contents
  * down into a real block and make the broot point to it.
diff --git a/fs/xfs/xfs_btree.c b/fs/xfs/xfs_btree.c
--- a/fs/xfs/xfs_btree.c
+++ b/fs/xfs/xfs_btree.c
@@ -90,6 +90,16 @@ xfs_btree_maxrecs(
  */
 
 /*
+ * Retrieve the block pointer from the cursor at the given level.
+ * This may be a bmap btree root or from a buffer.
+ */
+STATIC xfs_btree_block_t *			/* generic btree block pointer */
+xfs_btree_get_block(
+	xfs_btree_cur_t		*cur,	/* btree cursor */
+	int			level,	/* level in btree */
+	struct xfs_buf		**bpp);	/* buffer containing the block */
+
+/*
  * Checking routine: return maxrecs for the block.
  */
 STATIC int				/* number of records fitting in block */
@@ -497,7 +507,7 @@ xfs_btree_firstrec(
  * Retrieve the block pointer from the cursor at the given level.
  * This may be a bmap btree root or from a buffer.
  */
-xfs_btree_block_t *			/* generic btree block pointer */
+STATIC xfs_btree_block_t *		/* generic btree block pointer */
 xfs_btree_get_block(
 	xfs_btree_cur_t		*cur,	/* btree cursor */
 	int			level,	/* level in btree */
diff --git a/fs/xfs/xfs_btree.h b/fs/xfs/xfs_btree.h
--- a/fs/xfs/xfs_btree.h
+++ b/fs/xfs/xfs_btree.h
@@ -325,16 +325,6 @@ xfs_btree_firstrec(
 	int			level);	/* level to change */
 
 /*
- * Retrieve the block pointer from the cursor at the given level.
- * This may be a bmap btree root or from a buffer.
- */
-xfs_btree_block_t *			/* generic btree block pointer */
-xfs_btree_get_block(
-	xfs_btree_cur_t		*cur,	/* btree cursor */
-	int			level,	/* level in btree */
-	struct xfs_buf		**bpp);	/* buffer containing the block */
-
-/*
  * Get a buffer for the block, return it with no data read.
  * Long-form addressing.
  */
diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c
--- a/fs/xfs/xfs_buf_item.c
+++ b/fs/xfs/xfs_buf_item.c
@@ -172,7 +172,7 @@ STATIC void	xfs_buf_do_callbacks(xfs_buf
  *
  * If the XFS_BLI_STALE flag has been set, then log nothing.
  */
-uint
+STATIC uint
 xfs_buf_item_size(
 	xfs_buf_log_item_t	*bip)
 {
@@ -240,7 +240,7 @@ xfs_buf_item_size(
  * format structure, and the rest point to contiguous chunks
  * within the buffer.
  */
-void
+STATIC void
 xfs_buf_item_format(
 	xfs_buf_log_item_t	*bip,
 	xfs_log_iovec_t		*log_vector)
@@ -365,7 +365,7 @@ xfs_buf_item_format(
  * item in memory so it cannot be written out.  Simply call bpin()
  * on the buffer to do this.
  */
-void
+STATIC void
 xfs_buf_item_pin(
 	xfs_buf_log_item_t	*bip)
 {
@@ -391,7 +391,7 @@ xfs_buf_item_pin(
  * If the XFS_BLI_STALE flag is set and we are the last reference,
  * then free up the buf log item and unlock the buffer.
  */
-void
+STATIC void
 xfs_buf_item_unpin(
 	xfs_buf_log_item_t	*bip,
 	int			stale)
@@ -446,7 +446,7 @@ xfs_buf_item_unpin(
  * so we need to free the item's descriptor (that points to the item)
  * in the transaction.
  */
-void
+STATIC void
 xfs_buf_item_unpin_remove(
 	xfs_buf_log_item_t	*bip,
 	xfs_trans_t		*tp)
@@ -493,7 +493,7 @@ xfs_buf_item_unpin_remove(
  * the lock right away, return 0.  If we can get the lock, pull the
  * buffer from the free list, mark it busy, and return 1.
  */
-uint
+STATIC uint
 xfs_buf_item_trylock(
 	xfs_buf_log_item_t	*bip)
 {
@@ -537,7 +537,7 @@ xfs_buf_item_trylock(
  * This is for support of xfs_trans_bhold(). Make sure the
  * XFS_BLI_HOLD field is cleared if we don't free the item.
  */
-void
+STATIC void
 xfs_buf_item_unlock(
 	xfs_buf_log_item_t	*bip)
 {
@@ -635,7 +635,7 @@ xfs_buf_item_unlock(
  * by returning the original lsn of that transaction here rather than
  * the current one.
  */
-xfs_lsn_t
+STATIC xfs_lsn_t
 xfs_buf_item_committed(
 	xfs_buf_log_item_t	*bip,
 	xfs_lsn_t		lsn)
@@ -654,7 +654,7 @@ xfs_buf_item_committed(
  * and have aborted this transaction, we'll trap this buffer when it tries to
  * get written out.
  */
-void
+STATIC void
 xfs_buf_item_abort(
 	xfs_buf_log_item_t	*bip)
 {
@@ -674,7 +674,7 @@ xfs_buf_item_abort(
  * B_DELWRI set, then get it going out to disk with a call to bawrite().
  * If not, then just release the buffer.
  */
-void
+STATIC void
 xfs_buf_item_push(
 	xfs_buf_log_item_t	*bip)
 {
@@ -693,7 +693,7 @@ xfs_buf_item_push(
 }
 
 /* ARGSUSED */
-void
+STATIC void
 xfs_buf_item_committing(xfs_buf_log_item_t *bip, xfs_lsn_t commit_lsn)
 {
 }
@@ -701,7 +701,7 @@ xfs_buf_item_committing(xfs_buf_log_item
 /*
  * This is the ops vector shared by all buf log items.
  */
-struct xfs_item_ops xfs_buf_item_ops = {
+STATIC struct xfs_item_ops xfs_buf_item_ops = {
 	.iop_size	= (uint(*)(xfs_log_item_t*))xfs_buf_item_size,
 	.iop_format	= (void(*)(xfs_log_item_t*, xfs_log_iovec_t*))
 					xfs_buf_item_format,
diff --git a/fs/xfs/xfs_buf_item.h b/fs/xfs/xfs_buf_item.h
--- a/fs/xfs/xfs_buf_item.h
+++ b/fs/xfs/xfs_buf_item.h
@@ -80,7 +80,7 @@ typedef struct xfs_buf_log_format_t {
  * user or group dquots and may require special recovery handling.
  */
 #define	XFS_BLI_UDQUOT_BUF	0x4
-/* #define XFS_BLI_PDQUOT_BUF	0x8 */
+#define XFS_BLI_PDQUOT_BUF	0x8
 #define	XFS_BLI_GDQUOT_BUF	0x10
 
 #define	XFS_BLI_CHUNK		128
diff --git a/fs/xfs/xfs_da_btree.c b/fs/xfs/xfs_da_btree.c
--- a/fs/xfs/xfs_da_btree.c
+++ b/fs/xfs/xfs_da_btree.c
@@ -113,7 +113,10 @@ STATIC void xfs_da_node_unbalance(xfs_da
 STATIC uint	xfs_da_node_lasthash(xfs_dabuf_t *bp, int *count);
 STATIC int	xfs_da_node_order(xfs_dabuf_t *node1_bp, xfs_dabuf_t *node2_bp);
 STATIC xfs_dabuf_t *xfs_da_buf_make(int nbuf, xfs_buf_t **bps, inst_t *ra);
-
+STATIC int	xfs_da_blk_unlink(xfs_da_state_t *state,
+				  xfs_da_state_blk_t *drop_blk,
+				  xfs_da_state_blk_t *save_blk);
+STATIC void	xfs_da_state_kill_altpath(xfs_da_state_t *state);
 
 /*========================================================================
  * Routines used for growing the Btree.
@@ -1424,7 +1427,7 @@ xfs_da_node_lasthash(xfs_dabuf_t *bp, in
 /*
  * Unlink a block from a doubly linked list of blocks.
  */
-int							/* error */
+STATIC int						/* error */
 xfs_da_blk_unlink(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk,
 				 xfs_da_state_blk_t *save_blk)
 {
@@ -2381,7 +2384,7 @@ xfs_da_state_alloc(void)
 /*
  * Kill the altpath contents of a da-state structure.
  */
-void
+STATIC void
 xfs_da_state_kill_altpath(xfs_da_state_t *state)
 {
 	int	i;
diff --git a/fs/xfs/xfs_da_btree.h b/fs/xfs/xfs_da_btree.h
--- a/fs/xfs/xfs_da_btree.h
+++ b/fs/xfs/xfs_da_btree.h
@@ -296,8 +296,6 @@ int	xfs_da_path_shift(xfs_da_state_t *st
 /*
  * Utility routines.
  */
-int	xfs_da_blk_unlink(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk,
-					 xfs_da_state_blk_t *save_blk);
 int	xfs_da_blk_link(xfs_da_state_t *state, xfs_da_state_blk_t *old_blk,
 				       xfs_da_state_blk_t *new_blk);
 
@@ -320,7 +318,6 @@ uint xfs_da_hashname(uchar_t *name_strin
 uint xfs_da_log2_roundup(uint i);
 xfs_da_state_t *xfs_da_state_alloc(void);
 void xfs_da_state_free(xfs_da_state_t *state);
-void xfs_da_state_kill_altpath(xfs_da_state_t *state);
 
 void xfs_da_buf_done(xfs_dabuf_t *dabuf);
 void xfs_da_log_buf(struct xfs_trans *tp, xfs_dabuf_t *dabuf, uint first,
diff --git a/fs/xfs/xfs_dfrag.c b/fs/xfs/xfs_dfrag.c
--- a/fs/xfs/xfs_dfrag.c
+++ b/fs/xfs/xfs_dfrag.c
@@ -180,9 +180,10 @@ xfs_swapext(
 		goto error0;
 	}
 
-	if (VN_CACHED(tvp) != 0)
-		xfs_inval_cached_pages(XFS_ITOV(tip), &(tip->i_iocore),
-						(xfs_off_t)0, 0, 0);
+	if (VN_CACHED(tvp) != 0) {
+		xfs_inval_cached_trace(&tip->i_iocore, 0, -1, 0, -1);
+		VOP_FLUSHINVAL_PAGES(tvp, 0, -1, FI_REMAPF_LOCKED);
+	}
 
 	/* Verify O_DIRECT for ftmp */
 	if (VN_CACHED(tvp) != 0) {
diff --git a/fs/xfs/xfs_dir2_data.c b/fs/xfs/xfs_dir2_data.c
--- a/fs/xfs/xfs_dir2_data.c
+++ b/fs/xfs/xfs_dir2_data.c
@@ -304,7 +304,7 @@ xfs_dir2_data_freeinsert(
 /*
  * Remove a bestfree entry from the table.
  */
-void
+STATIC void
 xfs_dir2_data_freeremove(
 	xfs_dir2_data_t		*d,		/* data block pointer */
 	xfs_dir2_data_free_t	*dfp,		/* bestfree entry pointer */
diff --git a/fs/xfs/xfs_dir2_data.h b/fs/xfs/xfs_dir2_data.h
--- a/fs/xfs/xfs_dir2_data.h
+++ b/fs/xfs/xfs_dir2_data.h
@@ -193,10 +193,6 @@ extern xfs_dir2_data_free_t *
 				 xfs_dir2_data_unused_t *dup, int *loghead);
 
 extern void
-	xfs_dir2_data_freeremove(xfs_dir2_data_t *d,
-				 xfs_dir2_data_free_t *dfp, int *loghead);
-
-extern void
 	xfs_dir2_data_freescan(struct xfs_mount *mp, xfs_dir2_data_t *d,
 			       int *loghead, char *aendp);
 
diff --git a/fs/xfs/xfs_dir2_leaf.c b/fs/xfs/xfs_dir2_leaf.c
--- a/fs/xfs/xfs_dir2_leaf.c
+++ b/fs/xfs/xfs_dir2_leaf.c
@@ -77,6 +77,10 @@ static void xfs_dir2_leaf_check(xfs_inod
 #endif
 static int xfs_dir2_leaf_lookup_int(xfs_da_args_t *args, xfs_dabuf_t **lbpp,
 				    int *indexp, xfs_dabuf_t **dbpp);
+static void xfs_dir2_leaf_log_bests(struct xfs_trans *tp, struct xfs_dabuf *bp,
+				    int first, int last);
+static void xfs_dir2_leaf_log_tail(struct xfs_trans *tp, struct xfs_dabuf *bp);
+
 
 /*
  * Convert a block form directory to a leaf form directory.
@@ -1214,7 +1218,7 @@ xfs_dir2_leaf_init(
 /*
  * Log the bests entries indicated from a leaf1 block.
  */
-void
+static void
 xfs_dir2_leaf_log_bests(
 	xfs_trans_t		*tp,		/* transaction pointer */
 	xfs_dabuf_t		*bp,		/* leaf buffer */
@@ -1278,7 +1282,7 @@ xfs_dir2_leaf_log_header(
 /*
  * Log the tail of the leaf1 block.
  */
-void
+STATIC void
 xfs_dir2_leaf_log_tail(
 	xfs_trans_t		*tp,		/* transaction pointer */
 	xfs_dabuf_t		*bp)		/* leaf buffer */
diff --git a/fs/xfs/xfs_dir2_leaf.h b/fs/xfs/xfs_dir2_leaf.h
--- a/fs/xfs/xfs_dir2_leaf.h
+++ b/fs/xfs/xfs_dir2_leaf.h
@@ -330,15 +330,8 @@ extern void
 			       int first, int last);
 
 extern void
-	xfs_dir2_leaf_log_bests(struct xfs_trans *tp, struct xfs_dabuf *bp,
-				int first, int last);
-
-extern void
 	xfs_dir2_leaf_log_header(struct xfs_trans *tp, struct xfs_dabuf *bp);
 
-extern void
-	xfs_dir2_leaf_log_tail(struct xfs_trans *tp, struct xfs_dabuf *bp);
-
 extern int
 	xfs_dir2_leaf_lookup(struct xfs_da_args *args);
 
diff --git a/fs/xfs/xfs_dir_leaf.c b/fs/xfs/xfs_dir_leaf.c
--- a/fs/xfs/xfs_dir_leaf.c
+++ b/fs/xfs/xfs_dir_leaf.c
@@ -91,6 +91,10 @@ STATIC int xfs_dir_leaf_figure_balance(x
 					  int *number_entries_in_blk1,
 					  int *number_namebytes_in_blk1);
 
+STATIC int xfs_dir_leaf_create(struct xfs_da_args *args,
+				xfs_dablk_t which_block,
+				struct xfs_dabuf **bpp);
+
 /*
  * Utility routines.
  */
@@ -781,7 +785,7 @@ xfs_dir_leaf_to_node(xfs_da_args_t *args
  * Create the initial contents of a leaf directory
  * or a leaf in a node directory.
  */
-int
+STATIC int
 xfs_dir_leaf_create(xfs_da_args_t *args, xfs_dablk_t blkno, xfs_dabuf_t **bpp)
 {
 	xfs_dir_leafblock_t *leaf;
diff --git a/fs/xfs/xfs_dir_leaf.h b/fs/xfs/xfs_dir_leaf.h
--- a/fs/xfs/xfs_dir_leaf.h
+++ b/fs/xfs/xfs_dir_leaf.h
@@ -202,8 +202,6 @@ int xfs_dir_leaf_to_shortform(struct xfs
 /*
  * Routines used for growing the Btree.
  */
-int	xfs_dir_leaf_create(struct xfs_da_args *args, xfs_dablk_t which_block,
-				   struct xfs_dabuf **bpp);
 int	xfs_dir_leaf_split(struct xfs_da_state *state,
 				  struct xfs_da_state_blk *oldblk,
 				  struct xfs_da_state_blk *newblk);
diff --git a/fs/xfs/xfs_dmapi.h b/fs/xfs/xfs_dmapi.h
--- a/fs/xfs/xfs_dmapi.h
+++ b/fs/xfs/xfs_dmapi.h
@@ -166,27 +166,32 @@ typedef enum {
 #define DM_FLAGS_NDELAY		0x001	/* return EAGAIN after dm_pending() */
 #define DM_FLAGS_UNWANTED	0x002	/* event not in fsys dm_eventset_t */
 #define DM_FLAGS_ISEM		0x004	/* thread holds i_sem */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21)
-/* i_alloc_sem was added in 2.4.22-pre1 */
 #define DM_FLAGS_IALLOCSEM_RD	0x010	/* thread holds i_alloc_sem rd */
 #define DM_FLAGS_IALLOCSEM_WR	0x020	/* thread holds i_alloc_sem wr */
-#endif
-#endif
 
 /*
  *	Based on IO_ISDIRECT, decide which i_ flag is set.
  */
-#ifdef DM_FLAGS_IALLOCSEM_RD
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)
+#define DM_SEM_FLAG_RD(ioflags) (((ioflags) & IO_ISDIRECT) ? \
+			      DM_FLAGS_ISEM : 0)
+#define DM_SEM_FLAG_WR	(DM_FLAGS_IALLOCSEM_WR | DM_FLAGS_ISEM)
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) && \
+    (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22))
 #define DM_SEM_FLAG_RD(ioflags) (((ioflags) & IO_ISDIRECT) ? \
 			      DM_FLAGS_IALLOCSEM_RD : DM_FLAGS_ISEM)
 #define DM_SEM_FLAG_WR	(DM_FLAGS_IALLOCSEM_WR | DM_FLAGS_ISEM)
-#else
+#endif
+
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,4,21)
 #define DM_SEM_FLAG_RD(ioflags) (((ioflags) & IO_ISDIRECT) ? \
 			      0 : DM_FLAGS_ISEM)
 #define DM_SEM_FLAG_WR	(DM_FLAGS_ISEM)
 #endif
 
+
 /*
  *	Macros to turn caller specified delay/block flags into
  *	dm_send_xxxx_event flag DM_FLAGS_NDELAY.
diff --git a/fs/xfs/xfs_error.c b/fs/xfs/xfs_error.c
--- a/fs/xfs/xfs_error.c
+++ b/fs/xfs/xfs_error.c
@@ -280,7 +280,7 @@ xfs_error_report(
 	}
 }
 
-void
+STATIC void
 xfs_hex_dump(void *p, int length)
 {
 	__uint8_t *uip = (__uint8_t*)p;
diff --git a/fs/xfs/xfs_error.h b/fs/xfs/xfs_error.h
--- a/fs/xfs/xfs_error.h
+++ b/fs/xfs/xfs_error.h
@@ -73,9 +73,6 @@ xfs_corruption_error(
 	int		linenum,
 	inst_t		*ra);
 
-extern void
-xfs_hex_dump(void *p, int length);
-
 #define	XFS_ERROR_REPORT(e, lvl, mp)	\
 	xfs_error_report(e, lvl, mp, __FILE__, __LINE__, __return_address)
 #define	XFS_CORRUPTION_ERROR(e, lvl, mp, mem)	\
diff --git a/fs/xfs/xfs_extfree_item.c b/fs/xfs/xfs_extfree_item.c
--- a/fs/xfs/xfs_extfree_item.c
+++ b/fs/xfs/xfs_extfree_item.c
@@ -59,6 +59,18 @@ STATIC void	xfs_efi_item_abort(xfs_efi_l
 STATIC void	xfs_efd_item_abort(xfs_efd_log_item_t *);
 
 
+void
+xfs_efi_item_free(xfs_efi_log_item_t *efip)
+{
+	int nexts = efip->efi_format.efi_nextents;
+
+	if (nexts > XFS_EFI_MAX_FAST_EXTENTS) {
+		kmem_free(efip, sizeof(xfs_efi_log_item_t) +
+				(nexts - 1) * sizeof(xfs_extent_t));
+	} else {
+		kmem_zone_free(xfs_efi_zone, efip);
+	}
+}
 
 /*
  * This returns the number of iovecs needed to log the given efi item.
@@ -120,8 +132,6 @@ xfs_efi_item_pin(xfs_efi_log_item_t *efi
 STATIC void
 xfs_efi_item_unpin(xfs_efi_log_item_t *efip, int stale)
 {
-	int		nexts;
-	int		size;
 	xfs_mount_t	*mp;
 	SPLDECL(s);
 
@@ -132,21 +142,11 @@ xfs_efi_item_unpin(xfs_efi_log_item_t *e
 		 * xfs_trans_delete_ail() drops the AIL lock.
 		 */
 		xfs_trans_delete_ail(mp, (xfs_log_item_t *)efip, s);
-
-		nexts = efip->efi_format.efi_nextents;
-		if (nexts > XFS_EFI_MAX_FAST_EXTENTS) {
-			size = sizeof(xfs_efi_log_item_t);
-			size += (nexts - 1) * sizeof(xfs_extent_t);
-			kmem_free(efip, size);
-		} else {
-			kmem_zone_free(xfs_efi_zone, efip);
-		}
+		xfs_efi_item_free(efip);
 	} else {
 		efip->efi_flags |= XFS_EFI_COMMITTED;
 		AIL_UNLOCK(mp, s);
 	}
-
-	return;
 }
 
 /*
@@ -159,8 +159,6 @@ xfs_efi_item_unpin(xfs_efi_log_item_t *e
 STATIC void
 xfs_efi_item_unpin_remove(xfs_efi_log_item_t *efip, xfs_trans_t *tp)
 {
-	int		nexts;
-	int		size;
 	xfs_mount_t	*mp;
 	xfs_log_item_desc_t	*lidp;
 	SPLDECL(s);
@@ -178,23 +176,11 @@ xfs_efi_item_unpin_remove(xfs_efi_log_it
 		 * xfs_trans_delete_ail() drops the AIL lock.
 		 */
 		xfs_trans_delete_ail(mp, (xfs_log_item_t *)efip, s);
-		/*
-		 * now free the item itself
-		 */
-		nexts = efip->efi_format.efi_nextents;
-		if (nexts > XFS_EFI_MAX_FAST_EXTENTS) {
-			size = sizeof(xfs_efi_log_item_t);
-			size += (nexts - 1) * sizeof(xfs_extent_t);
-			kmem_free(efip, size);
-		} else {
-			kmem_zone_free(xfs_efi_zone, efip);
-		}
+		xfs_efi_item_free(efip);
 	} else {
 		efip->efi_flags |= XFS_EFI_COMMITTED;
 		AIL_UNLOCK(mp, s);
 	}
-
-	return;
 }
 
 /*
@@ -245,18 +231,7 @@ xfs_efi_item_committed(xfs_efi_log_item_
 STATIC void
 xfs_efi_item_abort(xfs_efi_log_item_t *efip)
 {
-	int	nexts;
-	int	size;
-
-	nexts = efip->efi_format.efi_nextents;
-	if (nexts > XFS_EFI_MAX_FAST_EXTENTS) {
-		size = sizeof(xfs_efi_log_item_t);
-		size += (nexts - 1) * sizeof(xfs_extent_t);
-		kmem_free(efip, size);
-	} else {
-		kmem_zone_free(xfs_efi_zone, efip);
-	}
-	return;
+	xfs_efi_item_free(efip);
 }
 
 /*
@@ -288,7 +263,7 @@ xfs_efi_item_committing(xfs_efi_log_item
 /*
  * This is the ops vector shared by all efi log items.
  */
-struct xfs_item_ops xfs_efi_item_ops = {
+STATIC struct xfs_item_ops xfs_efi_item_ops = {
 	.iop_size	= (uint(*)(xfs_log_item_t*))xfs_efi_item_size,
 	.iop_format	= (void(*)(xfs_log_item_t*, xfs_log_iovec_t*))
 					xfs_efi_item_format,
@@ -355,8 +330,6 @@ xfs_efi_release(xfs_efi_log_item_t	*efip
 {
 	xfs_mount_t	*mp;
 	int		extents_left;
-	uint		size;
-	int		nexts;
 	SPLDECL(s);
 
 	mp = efip->efi_item.li_mountp;
@@ -372,20 +345,10 @@ xfs_efi_release(xfs_efi_log_item_t	*efip
 		 * xfs_trans_delete_ail() drops the AIL lock.
 		 */
 		xfs_trans_delete_ail(mp, (xfs_log_item_t *)efip, s);
+		xfs_efi_item_free(efip);
 	} else {
 		AIL_UNLOCK(mp, s);
 	}
-
-	if (extents_left == 0) {
-		nexts = efip->efi_format.efi_nextents;
-		if (nexts > XFS_EFI_MAX_FAST_EXTENTS) {
-			size = sizeof(xfs_efi_log_item_t);
-			size += (nexts - 1) * sizeof(xfs_extent_t);
-			kmem_free(efip, size);
-		} else {
-			kmem_zone_free(xfs_efi_zone, efip);
-		}
-	}
 }
 
 /*
@@ -398,8 +361,6 @@ STATIC void
 xfs_efi_cancel(
 	xfs_efi_log_item_t	*efip)
 {
-	int		nexts;
-	int		size;
 	xfs_mount_t	*mp;
 	SPLDECL(s);
 
@@ -410,26 +371,25 @@ xfs_efi_cancel(
 		 * xfs_trans_delete_ail() drops the AIL lock.
 		 */
 		xfs_trans_delete_ail(mp, (xfs_log_item_t *)efip, s);
-
-		nexts = efip->efi_format.efi_nextents;
-		if (nexts > XFS_EFI_MAX_FAST_EXTENTS) {
-			size = sizeof(xfs_efi_log_item_t);
-			size += (nexts - 1) * sizeof(xfs_extent_t);
-			kmem_free(efip, size);
-		} else {
-			kmem_zone_free(xfs_efi_zone, efip);
-		}
+		xfs_efi_item_free(efip);
 	} else {
 		efip->efi_flags |= XFS_EFI_CANCELED;
 		AIL_UNLOCK(mp, s);
 	}
-
-	return;
 }
 
+STATIC void
+xfs_efd_item_free(xfs_efd_log_item_t *efdp)
+{
+	int nexts = efdp->efd_format.efd_nextents;
 
-
-
+	if (nexts > XFS_EFD_MAX_FAST_EXTENTS) {
+		kmem_free(efdp, sizeof(xfs_efd_log_item_t) +
+				(nexts - 1) * sizeof(xfs_extent_t));
+	} else {
+		kmem_zone_free(xfs_efd_zone, efdp);
+	}
+}
 
 /*
  * This returns the number of iovecs needed to log the given efd item.
@@ -533,9 +493,6 @@ xfs_efd_item_unlock(xfs_efd_log_item_t *
 STATIC xfs_lsn_t
 xfs_efd_item_committed(xfs_efd_log_item_t *efdp, xfs_lsn_t lsn)
 {
-	uint	size;
-	int	nexts;
-
 	/*
 	 * If we got a log I/O error, it's always the case that the LR with the
 	 * EFI got unpinned and freed before the EFD got aborted.
@@ -543,15 +500,7 @@ xfs_efd_item_committed(xfs_efd_log_item_
 	if ((efdp->efd_item.li_flags & XFS_LI_ABORTED) == 0)
 		xfs_efi_release(efdp->efd_efip, efdp->efd_format.efd_nextents);
 
-	nexts = efdp->efd_format.efd_nextents;
-	if (nexts > XFS_EFD_MAX_FAST_EXTENTS) {
-		size = sizeof(xfs_efd_log_item_t);
-		size += (nexts - 1) * sizeof(xfs_extent_t);
-		kmem_free(efdp, size);
-	} else {
-		kmem_zone_free(xfs_efd_zone, efdp);
-	}
-
+	xfs_efd_item_free(efdp);
 	return (xfs_lsn_t)-1;
 }
 
@@ -565,9 +514,6 @@ xfs_efd_item_committed(xfs_efd_log_item_
 STATIC void
 xfs_efd_item_abort(xfs_efd_log_item_t *efdp)
 {
-	int	nexts;
-	int	size;
-
 	/*
 	 * If we got a log I/O error, it's always the case that the LR with the
 	 * EFI got unpinned and freed before the EFD got aborted. So don't
@@ -576,15 +522,7 @@ xfs_efd_item_abort(xfs_efd_log_item_t *e
 	if ((efdp->efd_item.li_flags & XFS_LI_ABORTED) == 0)
 		xfs_efi_cancel(efdp->efd_efip);
 
-	nexts = efdp->efd_format.efd_nextents;
-	if (nexts > XFS_EFD_MAX_FAST_EXTENTS) {
-		size = sizeof(xfs_efd_log_item_t);
-		size += (nexts - 1) * sizeof(xfs_extent_t);
-		kmem_free(efdp, size);
-	} else {
-		kmem_zone_free(xfs_efd_zone, efdp);
-	}
-	return;
+	xfs_efd_item_free(efdp);
 }
 
 /*
@@ -615,7 +553,7 @@ xfs_efd_item_committing(xfs_efd_log_item
 /*
  * This is the ops vector shared by all efd log items.
  */
-struct xfs_item_ops xfs_efd_item_ops = {
+STATIC struct xfs_item_ops xfs_efd_item_ops = {
 	.iop_size	= (uint(*)(xfs_log_item_t*))xfs_efd_item_size,
 	.iop_format	= (void(*)(xfs_log_item_t*, xfs_log_iovec_t*))
 					xfs_efd_item_format,
diff --git a/fs/xfs/xfs_extfree_item.h b/fs/xfs/xfs_extfree_item.h
--- a/fs/xfs/xfs_extfree_item.h
+++ b/fs/xfs/xfs_extfree_item.h
@@ -118,6 +118,8 @@ xfs_efi_log_item_t	*xfs_efi_init(struct 
 xfs_efd_log_item_t	*xfs_efd_init(struct xfs_mount *, xfs_efi_log_item_t *,
 				      uint);
 
+void			xfs_efi_item_free(xfs_efi_log_item_t *);
+
 #endif	/* __KERNEL__ */
 
 #endif	/* __XFS_EXTFREE_ITEM_H__ */
diff --git a/fs/xfs/xfs_fs.h b/fs/xfs/xfs_fs.h
--- a/fs/xfs/xfs_fs.h
+++ b/fs/xfs/xfs_fs.h
@@ -60,7 +60,8 @@ struct fsxattr {
 	__u32		fsx_xflags;	/* xflags field value (get/set) */
 	__u32		fsx_extsize;	/* extsize field value (get/set)*/
 	__u32		fsx_nextents;	/* nextents field value (get)	*/
-	unsigned char	fsx_pad[16];
+	__u32		fsx_projid;	/* project identifier (get/set) */
+	unsigned char	fsx_pad[12];
 };
 #endif
 
diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c
--- a/fs/xfs/xfs_fsops.c
+++ b/fs/xfs/xfs_fsops.c
@@ -559,32 +559,6 @@ xfs_reserve_blocks(
 	return(0);
 }
 
-void
-xfs_fs_log_dummy(xfs_mount_t *mp)
-{
-	xfs_trans_t *tp;
-	xfs_inode_t *ip;
-
-
-	tp = _xfs_trans_alloc(mp, XFS_TRANS_DUMMY1);
-	atomic_inc(&mp->m_active_trans);
-	if (xfs_trans_reserve(tp, 0, XFS_ICHANGE_LOG_RES(mp), 0, 0, 0)) {
-		xfs_trans_cancel(tp, 0);
-		return;
-	}
-
-	ip = mp->m_rootip;
-	xfs_ilock(ip, XFS_ILOCK_EXCL);
-
-	xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
-	xfs_trans_ihold(tp, ip);
-	xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
-	xfs_trans_set_sync(tp);
-	xfs_trans_commit(tp, 0, NULL);
-
-	xfs_iunlock(ip, XFS_ILOCK_EXCL);
-}
-
 int
 xfs_fs_goingdown(
 	xfs_mount_t	*mp,
diff --git a/fs/xfs/xfs_ialloc_btree.h b/fs/xfs/xfs_ialloc_btree.h
--- a/fs/xfs/xfs_ialloc_btree.h
+++ b/fs/xfs/xfs_ialloc_btree.h
@@ -100,9 +100,13 @@ xfs_inofree_t xfs_inobt_mask(int i);
 #endif
 #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_INOBT_IS_FREE)
 int xfs_inobt_is_free(xfs_inobt_rec_t *rp, int i);
-#define	XFS_INOBT_IS_FREE(rp,i)	xfs_inobt_is_free(rp,i)
+#define	XFS_INOBT_IS_FREE(rp,i)		xfs_inobt_is_free(rp,i)
+#define	XFS_INOBT_IS_FREE_DISK(rp,i)	xfs_inobt_is_free_disk(rp,i)
 #else
-#define	XFS_INOBT_IS_FREE(rp,i)	(((rp)->ir_free & XFS_INOBT_MASK(i)) != 0)
+#define	XFS_INOBT_IS_FREE(rp,i)	\
+	(((rp)->ir_free & XFS_INOBT_MASK(i)) != 0)
+#define XFS_INOBT_IS_FREE_DISK(rp,i) \
+	((INT_GET((rp)->ir_free, ARCH_CONVERT) & XFS_INOBT_MASK(i)) != 0)
 #endif
 #if XFS_WANT_FUNCS || (XFS_WANT_SPACE && XFSSO_XFS_INOBT_SET_FREE)
 void xfs_inobt_set_free(xfs_inobt_rec_t *rp, int i);
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -146,51 +146,6 @@ xfs_inobp_check(
 #endif
 
 /*
- * called from bwrite on xfs inode buffers
- */
-void
-xfs_inobp_bwcheck(xfs_buf_t *bp)
-{
-	xfs_mount_t	*mp;
-	int		i;
-	int		j;
-	xfs_dinode_t	*dip;
-
-	ASSERT(XFS_BUF_FSPRIVATE3(bp, void *) != NULL);
-
-	mp = XFS_BUF_FSPRIVATE3(bp, xfs_mount_t *);
-
-
-	j = mp->m_inode_cluster_size >> mp->m_sb.sb_inodelog;
-
-	for (i = 0; i < j; i++)  {
-		dip = (xfs_dinode_t *) xfs_buf_offset(bp,
-						i * mp->m_sb.sb_inodesize);
-		if (INT_GET(dip->di_core.di_magic, ARCH_CONVERT) != XFS_DINODE_MAGIC) {
-			cmn_err(CE_WARN,
-"Bad magic # 0x%x in XFS inode buffer 0x%Lx, starting blockno %Ld, offset 0x%x",
-				INT_GET(dip->di_core.di_magic, ARCH_CONVERT),
-				(__uint64_t)(__psunsigned_t) bp,
-				(__int64_t) XFS_BUF_ADDR(bp),
-				xfs_buf_offset(bp, i * mp->m_sb.sb_inodesize));
-			xfs_fs_cmn_err(CE_WARN, mp,
-				"corrupt, unmount and run xfs_repair");
-		}
-		if (!dip->di_next_unlinked)  {
-			cmn_err(CE_WARN,
-"Bad next_unlinked field (0) in XFS inode buffer 0x%p, starting blockno %Ld, offset 0x%x",
-				(__uint64_t)(__psunsigned_t) bp,
-				(__int64_t) XFS_BUF_ADDR(bp),
-				xfs_buf_offset(bp, i * mp->m_sb.sb_inodesize));
-			xfs_fs_cmn_err(CE_WARN, mp,
-				"corrupt, unmount and run xfs_repair");
-		}
-	}
-
-	return;
-}
-
-/*
  * This routine is called to map an inode number within a file
  * system to the buffer containing the on-disk version of the
  * inode.  It returns a pointer to the buffer containing the
@@ -203,7 +158,7 @@ xfs_inobp_bwcheck(xfs_buf_t *bp)
  * Use xfs_imap() to determine the size and location of the
  * buffer to read from disk.
  */
-int
+STATIC int
 xfs_inotobp(
 	xfs_mount_t	*mp,
 	xfs_trans_t	*tp,
@@ -1247,26 +1202,32 @@ xfs_ialloc(
 	case S_IFREG:
 	case S_IFDIR:
 		if (unlikely(pip->i_d.di_flags & XFS_DIFLAG_ANY)) {
-			if (pip->i_d.di_flags & XFS_DIFLAG_RTINHERIT) {
-				if ((mode & S_IFMT) == S_IFDIR) {
-					ip->i_d.di_flags |= XFS_DIFLAG_RTINHERIT;
-				} else {
-					ip->i_d.di_flags |= XFS_DIFLAG_REALTIME;
+			uint	di_flags = 0;
+
+			if ((mode & S_IFMT) == S_IFDIR) {
+				if (pip->i_d.di_flags & XFS_DIFLAG_RTINHERIT)
+					di_flags |= XFS_DIFLAG_RTINHERIT;
+			} else {
+				if (pip->i_d.di_flags & XFS_DIFLAG_RTINHERIT) {
+					di_flags |= XFS_DIFLAG_REALTIME;
 					ip->i_iocore.io_flags |= XFS_IOCORE_RT;
 				}
 			}
 			if ((pip->i_d.di_flags & XFS_DIFLAG_NOATIME) &&
 			    xfs_inherit_noatime)
-				ip->i_d.di_flags |= XFS_DIFLAG_NOATIME;
+				di_flags |= XFS_DIFLAG_NOATIME;
 			if ((pip->i_d.di_flags & XFS_DIFLAG_NODUMP) &&
 			    xfs_inherit_nodump)
-				ip->i_d.di_flags |= XFS_DIFLAG_NODUMP;
+				di_flags |= XFS_DIFLAG_NODUMP;
 			if ((pip->i_d.di_flags & XFS_DIFLAG_SYNC) &&
 			    xfs_inherit_sync)
-				ip->i_d.di_flags |= XFS_DIFLAG_SYNC;
+				di_flags |= XFS_DIFLAG_SYNC;
 			if ((pip->i_d.di_flags & XFS_DIFLAG_NOSYMLINKS) &&
 			    xfs_inherit_nosymlinks)
-				ip->i_d.di_flags |= XFS_DIFLAG_NOSYMLINKS;
+				di_flags |= XFS_DIFLAG_NOSYMLINKS;
+			if (pip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT)
+				di_flags |= XFS_DIFLAG_PROJINHERIT;
+			ip->i_d.di_flags |= di_flags;
 		}
 		/* FALLTHROUGH */
 	case S_IFLNK:
@@ -2156,7 +2117,7 @@ static __inline__ int xfs_inode_clean(xf
 		(ip->i_update_core == 0));
 }
 
-void
+STATIC void
 xfs_ifree_cluster(
 	xfs_inode_t	*free_ip,
 	xfs_trans_t	*tp,
@@ -2875,7 +2836,7 @@ xfs_iunpin(
  * be subsequently pinned once someone is waiting for it to be
  * unpinned.
  */
-void
+STATIC void
 xfs_iunpin_wait(
 	xfs_inode_t	*ip)
 {
@@ -3601,107 +3562,43 @@ corrupt_out:
 
 
 /*
- * Flush all inactive inodes in mp.  Return true if no user references
- * were found, false otherwise.
+ * Flush all inactive inodes in mp.
  */
-int
+void
 xfs_iflush_all(
-	xfs_mount_t	*mp,
-	int		flag)
+	xfs_mount_t	*mp)
 {
-	int		busy;
-	int		done;
-	int		purged;
 	xfs_inode_t	*ip;
-	vmap_t		vmap;
 	vnode_t		*vp;
 
-	busy = done = 0;
-	while (!done) {
-		purged = 0;
-		XFS_MOUNT_ILOCK(mp);
-		ip = mp->m_inodes;
-		if (ip == NULL) {
-			break;
+ again:
+	XFS_MOUNT_ILOCK(mp);
+	ip = mp->m_inodes;
+	if (ip == NULL)
+		goto out;
+
+	do {
+		/* Make sure we skip markers inserted by sync */
+		if (ip->i_mount == NULL) {
+			ip = ip->i_mnext;
+			continue;
 		}
-		do {
-			/* Make sure we skip markers inserted by sync */
-			if (ip->i_mount == NULL) {
-				ip = ip->i_mnext;
-				continue;
-			}
 
-			/*
-			 * It's up to our caller to purge the root
-			 * and quota vnodes later.
-			 */
-			vp = XFS_ITOV_NULL(ip);
-
-			if (!vp) {
-				XFS_MOUNT_IUNLOCK(mp);
-				xfs_finish_reclaim(ip, 0, XFS_IFLUSH_ASYNC);
-				purged = 1;
-				break;
-			}
-
-			if (vn_count(vp) != 0) {
-				if (vn_count(vp) == 1 &&
-				    (ip == mp->m_rootip ||
-				     (mp->m_quotainfo &&
-				      (ip->i_ino == mp->m_sb.sb_uquotino ||
-				       ip->i_ino == mp->m_sb.sb_gquotino)))) {
-
-					ip = ip->i_mnext;
-					continue;
-				}
-				if (!(flag & XFS_FLUSH_ALL)) {
-					busy = 1;
-					done = 1;
-					break;
-				}
-				/*
-				 * Ignore busy inodes but continue flushing
-				 * others.
-				 */
-				ip = ip->i_mnext;
-				continue;
-			}
-			/*
-			 * Sample vp mapping while holding mp locked on MP
-			 * systems, so we don't purge a reclaimed or
-			 * nonexistent vnode.  We break from the loop
-			 * since we know that we modify
-			 * it by pulling ourselves from it in xfs_reclaim()
-			 * called via vn_purge() below.  Set ip to the next
-			 * entry in the list anyway so we'll know below
-			 * whether we reached the end or not.
-			 */
-			VMAP(vp, vmap);
+		vp = XFS_ITOV_NULL(ip);
+		if (!vp) {
 			XFS_MOUNT_IUNLOCK(mp);
+			xfs_finish_reclaim(ip, 0, XFS_IFLUSH_ASYNC);
+			goto again;
+		}
 
-			vn_purge(vp, &vmap);
+		ASSERT(vn_count(vp) == 0);
 
-			purged = 1;
-			break;
-		} while (ip != mp->m_inodes);
-		/*
-		 * We need to distinguish between when we exit the loop
-		 * after a purge and when we simply hit the end of the
-		 * list.  We can't use the (ip == mp->m_inodes) test,
-		 * because when we purge an inode at the start of the list
-		 * the next inode on the list becomes mp->m_inodes.  That
-		 * would cause such a test to bail out early.  The purged
-		 * variable tells us how we got out of the loop.
-		 */
-		if (!purged) {
-			done = 1;
-		}
-	}
+		ip = ip->i_mnext;
+	} while (ip != mp->m_inodes);
+ out:
 	XFS_MOUNT_IUNLOCK(mp);
-	return !busy;
 }
 
-
 /*
  * xfs_iaccess: check accessibility of inode for mode.
  */
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h
--- a/fs/xfs/xfs_inode.h
+++ b/fs/xfs/xfs_inode.h
@@ -412,11 +412,6 @@ void xfs_ifork_next_set(xfs_inode_t *ip,
 #define	XFS_IFLUSH_DELWRI		5
 
 /*
- * Flags for xfs_iflush_all.
- */
-#define	XFS_FLUSH_ALL		0x1
-
-/*
  * Flags for xfs_itruncate_start().
  */
 #define	XFS_ITRUNC_DEFINITE	0x1
@@ -487,8 +482,6 @@ int		xfs_finish_reclaim_all(struct xfs_m
 /*
  * xfs_inode.c prototypes.
  */
-int		xfs_inotobp(struct xfs_mount *, struct xfs_trans *, xfs_ino_t,
-			    xfs_dinode_t **, struct xfs_buf **, int *);
 int		xfs_itobp(struct xfs_mount *, struct xfs_trans *,
 			  xfs_inode_t *, xfs_dinode_t **, struct xfs_buf **,
 			  xfs_daddr_t);
@@ -522,7 +515,7 @@ void		xfs_ipin(xfs_inode_t *);
 void		xfs_iunpin(xfs_inode_t *);
 int		xfs_iextents_copy(xfs_inode_t *, xfs_bmbt_rec_t *, int);
 int		xfs_iflush(xfs_inode_t *, uint);
-int		xfs_iflush_all(struct xfs_mount *, int);
+void		xfs_iflush_all(struct xfs_mount *);
 int		xfs_iaccess(xfs_inode_t *, mode_t, cred_t *);
 uint		xfs_iroundup(uint);
 void		xfs_ichgtime(xfs_inode_t *, int);
diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c
--- a/fs/xfs/xfs_inode_item.c
+++ b/fs/xfs/xfs_inode_item.c
@@ -910,7 +910,7 @@ xfs_inode_item_committing(
 /*
  * This is the ops vector shared by all buf log items.
  */
-struct xfs_item_ops xfs_inode_item_ops = {
+STATIC struct xfs_item_ops xfs_inode_item_ops = {
 	.iop_size	= (uint(*)(xfs_log_item_t*))xfs_inode_item_size,
 	.iop_format	= (void(*)(xfs_log_item_t*, xfs_log_iovec_t*))
 					xfs_inode_item_format,
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
--- a/fs/xfs/xfs_iomap.c
+++ b/fs/xfs/xfs_iomap.c
@@ -385,15 +385,15 @@ xfs_iomap_write_direct(
 	int		nimaps, maps;
 	int		error;
 	int		bmapi_flag;
+	int		quota_flag;
 	int		rt;
 	xfs_trans_t	*tp;
 	xfs_bmbt_irec_t imap[XFS_WRITE_IMAPS], *imapp;
 	xfs_bmap_free_t free_list;
 	int		aeof;
-	xfs_filblks_t	datablocks;
+	xfs_filblks_t	datablocks, qblocks, resblks;
 	int		committed;
 	int		numrtextents;
-	uint		resblks;
 
 	/*
 	 * Make sure that the dquots are there. This doesn't hold
@@ -419,7 +419,6 @@ xfs_iomap_write_direct(
 		xfs_fileoff_t	map_last_fsb;
 
 		map_last_fsb = ret_imap->br_blockcount + ret_imap->br_startoff;
-
 		if (map_last_fsb < last_fsb) {
 			last_fsb = map_last_fsb;
 			count_fsb = last_fsb - offset_fsb;
@@ -428,56 +427,47 @@ xfs_iomap_write_direct(
 	}
 
 	/*
-	 * determine if reserving space on
-	 * the data or realtime partition.
+	 * Determine if reserving space on the data or realtime partition.
 	 */
 	if ((rt = XFS_IS_REALTIME_INODE(ip))) {
-		int	sbrtextsize, iprtextsize;
+		xfs_extlen_t	extsz;
 
-		sbrtextsize = mp->m_sb.sb_rextsize;
-		iprtextsize =
-			ip->i_d.di_extsize ? ip->i_d.di_extsize : sbrtextsize;
-		numrtextents = (count_fsb + iprtextsize - 1);
-		do_div(numrtextents, sbrtextsize);
+		if (!(extsz = ip->i_d.di_extsize))
+			extsz = mp->m_sb.sb_rextsize;
+		numrtextents = qblocks = (count_fsb + extsz - 1);
+		do_div(numrtextents, mp->m_sb.sb_rextsize);
+		quota_flag = XFS_QMOPT_RES_RTBLKS;
 		datablocks = 0;
 	} else {
-		datablocks = count_fsb;
+		datablocks = qblocks = count_fsb;
+		quota_flag = XFS_QMOPT_RES_REGBLKS;
 		numrtextents = 0;
 	}
 
 	/*
-	 * allocate and setup the transaction
+	 * Allocate and setup the transaction
 	 */
 	xfs_iunlock(ip, XFS_ILOCK_EXCL);
 	tp = xfs_trans_alloc(mp, XFS_TRANS_DIOSTRAT);
-
 	resblks = XFS_DIOSTRAT_SPACE_RES(mp, datablocks);
-
 	error = xfs_trans_reserve(tp, resblks,
 			XFS_WRITE_LOG_RES(mp), numrtextents,
 			XFS_TRANS_PERM_LOG_RES,
 			XFS_WRITE_LOG_COUNT);
 
 	/*
-	 * check for running out of space
+	 * Check for running out of space, note: need lock to return
 	 */
 	if (error)
-		/*
-		 * Free the transaction structure.
-		 */
 		xfs_trans_cancel(tp, 0);
-
 	xfs_ilock(ip, XFS_ILOCK_EXCL);
-
 	if (error)
-		goto error_out; /* Don't return in above if .. trans ..,
-					need lock to return */
+		goto error_out;
 
-	if (XFS_TRANS_RESERVE_BLKQUOTA(mp, tp, ip, resblks)) {
+	if (XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, tp, ip, qblocks, 0, quota_flag)) {
 		error = (EDQUOT);
 		goto error1;
 	}
-	nimaps = 1;
 
 	bmapi_flag = XFS_BMAPI_WRITE;
 	xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
@@ -487,31 +477,29 @@ xfs_iomap_write_direct(
 		bmapi_flag |= XFS_BMAPI_PREALLOC;
 
 	/*
-	 * issue the bmapi() call to allocate the blocks
+	 * Issue the bmapi() call to allocate the blocks
 	 */
 	XFS_BMAP_INIT(&free_list, &firstfsb);
+	nimaps = 1;
 	imapp = &imap[0];
 	error = xfs_bmapi(tp, ip, offset_fsb, count_fsb,
 		bmapi_flag, &firstfsb, 0, imapp, &nimaps, &free_list);
-	if (error) {
+	if (error)
 		goto error0;
-	}
 
 	/*
-	 * complete the transaction
+	 * Complete the transaction
 	 */
-
 	error = xfs_bmap_finish(&tp, &free_list, firstfsb, &committed);
-	if (error) {
+	if (error)
 		goto error0;
-	}
-
 	error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL);
-	if (error) {
+	if (error)
 		goto error_out;
-	}
 
-	/* copy any maps to caller's array and return any error. */
+	/*
+	 * Copy any maps to caller's array and return any error.
+	 */
 	if (nimaps == 0) {
 		error = (ENOSPC);
 		goto error_out;
@@ -530,10 +518,11 @@ xfs_iomap_write_direct(
         }
 	return 0;
 
- error0:	/* Cancel bmap, unlock inode, and cancel trans */
+error0:	/* Cancel bmap, unlock inode, unreserve quota blocks, cancel trans */
 	xfs_bmap_cancel(&free_list);
+	XFS_TRANS_UNRESERVE_QUOTA_NBLKS(mp, tp, ip, qblocks, 0, quota_flag);
 
- error1:	/* Just cancel transaction */
+error1:	/* Just cancel transaction */
 	xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT);
 	*nmaps = 0;	/* nothing set-up here */
 
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c
--- a/fs/xfs/xfs_log.c
+++ b/fs/xfs/xfs_log.c
@@ -134,7 +134,7 @@ STATIC void	xlog_verify_tail_lsn(xlog_t 
 #define xlog_verify_tail_lsn(a,b,c)
 #endif
 
-int		xlog_iclogs_empty(xlog_t *log);
+STATIC int	xlog_iclogs_empty(xlog_t *log);
 
 #ifdef DEBUG
 int xlog_do_error = 0;
@@ -1857,7 +1857,7 @@ xlog_write(xfs_mount_t *	mp,
  *
  * State Change: DIRTY -> ACTIVE
  */
-void
+STATIC void
 xlog_state_clean_log(xlog_t *log)
 {
 	xlog_in_core_t	*iclog;
@@ -3542,7 +3542,7 @@ xfs_log_force_umount(
 	return (retval);
 }
 
-int
+STATIC int
 xlog_iclogs_empty(xlog_t *log)
 {
 	xlog_in_core_t	*iclog;
diff --git a/fs/xfs/xfs_log_priv.h b/fs/xfs/xfs_log_priv.h
--- a/fs/xfs/xfs_log_priv.h
+++ b/fs/xfs/xfs_log_priv.h
@@ -535,7 +535,6 @@ typedef struct log {
 
 /* common routines */
 extern xfs_lsn_t xlog_assign_tail_lsn(struct xfs_mount *mp);
-extern int	 xlog_find_head(xlog_t *log, xfs_daddr_t *head_blk);
 extern int	 xlog_find_tail(xlog_t	*log,
 				xfs_daddr_t *head_blk,
 				xfs_daddr_t *tail_blk,
@@ -548,7 +547,6 @@ extern void	 xlog_recover_process_iunlin
 extern struct xfs_buf *xlog_get_bp(xlog_t *, int);
 extern void	 xlog_put_bp(struct xfs_buf *);
 extern int	 xlog_bread(xlog_t *, xfs_daddr_t, int, struct xfs_buf *);
-extern xfs_caddr_t xlog_align(xlog_t *, xfs_daddr_t, int, struct xfs_buf *);
 
 /* iclog tracing */
 #define XLOG_TRACE_GRAB_FLUSH  1
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
--- a/fs/xfs/xfs_log_recover.c
+++ b/fs/xfs/xfs_log_recover.c
@@ -148,7 +148,7 @@ xlog_bread(
  * The buffer is kept locked across the write and is returned locked.
  * This can only be used for synchronous log writes.
  */
-int
+STATIC int
 xlog_bwrite(
 	xlog_t		*log,
 	xfs_daddr_t	blk_no,
@@ -179,7 +179,7 @@ xlog_bwrite(
 	return error;
 }
 
-xfs_caddr_t
+STATIC xfs_caddr_t
 xlog_align(
 	xlog_t		*log,
 	xfs_daddr_t	blk_no,
@@ -528,7 +528,7 @@ out:
  *
  * Return: zero if normal, non-zero if error.
  */
-int
+STATIC int
 xlog_find_head(
 	xlog_t 		*log,
 	xfs_daddr_t	*return_head_blk)
@@ -1964,7 +1964,8 @@ xlog_recover_do_reg_buffer(
 		 * probably a good thing to do for other buf types also.
 		 */
 		error = 0;
-		if (buf_f->blf_flags & (XFS_BLI_UDQUOT_BUF|XFS_BLI_GDQUOT_BUF)) {
+		if (buf_f->blf_flags &
+		   (XFS_BLI_UDQUOT_BUF|XFS_BLI_PDQUOT_BUF|XFS_BLI_GDQUOT_BUF)) {
 			error = xfs_qm_dqcheck((xfs_disk_dquot_t *)
 					       item->ri_buf[i].i_addr,
 					       -1, 0, XFS_QMOPT_DOWARN,
@@ -2030,6 +2031,7 @@ xfs_qm_dqcheck(
 	}
 
 	if (INT_GET(ddq->d_flags, ARCH_CONVERT) != XFS_DQ_USER &&
+	    INT_GET(ddq->d_flags, ARCH_CONVERT) != XFS_DQ_PROJ &&
 	    INT_GET(ddq->d_flags, ARCH_CONVERT) != XFS_DQ_GROUP) {
 		if (flags & XFS_QMOPT_DOWARN)
 			cmn_err(CE_ALERT,
@@ -2135,6 +2137,8 @@ xlog_recover_do_dquot_buffer(
 	type = 0;
 	if (buf_f->blf_flags & XFS_BLI_UDQUOT_BUF)
 		type |= XFS_DQ_USER;
+	if (buf_f->blf_flags & XFS_BLI_PDQUOT_BUF)
+		type |= XFS_DQ_PROJ;
 	if (buf_f->blf_flags & XFS_BLI_GDQUOT_BUF)
 		type |= XFS_DQ_GROUP;
 	/*
@@ -2247,7 +2251,8 @@ xlog_recover_do_buffer_trans(
 	error = 0;
 	if (flags & XFS_BLI_INODE_BUF) {
 		error = xlog_recover_do_inode_buffer(mp, item, bp, buf_f);
-	} else if (flags & (XFS_BLI_UDQUOT_BUF | XFS_BLI_GDQUOT_BUF)) {
+	} else if (flags &
+		  (XFS_BLI_UDQUOT_BUF|XFS_BLI_PDQUOT_BUF|XFS_BLI_GDQUOT_BUF)) {
 		xlog_recover_do_dquot_buffer(mp, log, item, bp, buf_f);
 	} else {
 		xlog_recover_do_reg_buffer(mp, item, bp, buf_f);
@@ -2619,7 +2624,7 @@ xlog_recover_do_dquot_trans(
 	 * This type of quotas was turned off, so ignore this record.
 	 */
 	type = INT_GET(recddq->d_flags, ARCH_CONVERT) &
-			(XFS_DQ_USER | XFS_DQ_GROUP);
+			(XFS_DQ_USER | XFS_DQ_PROJ | XFS_DQ_GROUP);
 	ASSERT(type);
 	if (log->l_quotaoffs_flag & type)
 		return (0);
@@ -2742,7 +2747,6 @@ xlog_recover_do_efd_trans(
 	xfs_efi_log_item_t	*efip = NULL;
 	xfs_log_item_t		*lip;
 	int			gen;
-	int			nexts;
 	__uint64_t		efi_id;
 	SPLDECL(s);
 
@@ -2777,22 +2781,15 @@ xlog_recover_do_efd_trans(
 		}
 		lip = xfs_trans_next_ail(mp, lip, &gen, NULL);
 	}
-	if (lip == NULL) {
-		AIL_UNLOCK(mp, s);
-	}
 
 	/*
 	 * If we found it, then free it up.  If it wasn't there, it
 	 * must have been overwritten in the log.  Oh well.
 	 */
 	if (lip != NULL) {
-		nexts = efip->efi_format.efi_nextents;
-		if (nexts > XFS_EFI_MAX_FAST_EXTENTS) {
-			kmem_free(lip, sizeof(xfs_efi_log_item_t) +
-				  ((nexts - 1) * sizeof(xfs_extent_t)));
-		} else {
-			kmem_zone_free(xfs_efi_zone, efip);
-		}
+		xfs_efi_item_free(efip);
+	} else {
+		AIL_UNLOCK(mp, s);
 	}
 }
 
diff --git a/fs/xfs/xfs_macros.c b/fs/xfs/xfs_macros.c
--- a/fs/xfs/xfs_macros.c
+++ b/fs/xfs/xfs_macros.c
@@ -1658,6 +1658,11 @@ xfs_inobt_is_free(xfs_inobt_rec_t *rp, i
 {
 	return XFS_INOBT_IS_FREE(rp, i);
 }
+int
+xfs_inobt_is_free_disk(xfs_inobt_rec_t *rp, int i)
+{
+	return XFS_INOBT_IS_FREE_DISK(rp, i);
+}
 #endif
 
 #if XFS_WANT_FUNCS_C || (XFS_WANT_SPACE_C && XFSSO_XFS_INOBT_IS_LAST_REC)
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -64,6 +64,7 @@
 STATIC void	xfs_mount_log_sbunit(xfs_mount_t *, __int64_t);
 STATIC int	xfs_uuid_mount(xfs_mount_t *);
 STATIC void	xfs_uuid_unmount(xfs_mount_t *mp);
+STATIC void	xfs_unmountfs_wait(xfs_mount_t *);
 
 static struct {
     short offset;
@@ -555,7 +556,7 @@ xfs_readsb(xfs_mount_t *mp)
  * fields from the superblock associated with the given
  * mount structure
  */
-void
+STATIC void
 xfs_mount_common(xfs_mount_t *mp, xfs_sb_t *sbp)
 {
 	int	i;
@@ -1081,7 +1082,7 @@ xfs_unmountfs(xfs_mount_t *mp, struct cr
 	int64_t		fsid;
 #endif
 
-	xfs_iflush_all(mp, XFS_FLUSH_ALL);
+	xfs_iflush_all(mp);
 
 	XFS_QM_DQPURGEALL(mp,
 		XFS_QMOPT_UQUOTA | XFS_QMOPT_GQUOTA | XFS_QMOPT_UMOUNTING);
@@ -1111,15 +1112,6 @@ xfs_unmountfs(xfs_mount_t *mp, struct cr
 	 */
 	ASSERT(mp->m_inodes == NULL);
 
-	/*
-	 * We may have bufs that are in the process of getting written still.
-	 * We must wait for the I/O completion of those. The sync flag here
-	 * does a two pass iteration thru the bufcache.
-	 */
-	if (XFS_FORCED_SHUTDOWN(mp)) {
-		xfs_incore_relse(mp->m_ddev_targp, 0, 1); /* synchronous */
-	}
-
 	xfs_unmountfs_close(mp, cr);
 	if ((mp->m_flags & XFS_MOUNT_NOUUID) == 0)
 		xfs_uuid_unmount(mp);
@@ -1146,7 +1138,7 @@ xfs_unmountfs_close(xfs_mount_t *mp, str
 	xfs_free_buftarg(mp->m_ddev_targp, 0);
 }
 
-void
+STATIC void
 xfs_unmountfs_wait(xfs_mount_t *mp)
 {
 	if (mp->m_logdev_targp != mp->m_ddev_targp)
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -141,7 +141,7 @@ typedef int	(*xfs_dqattach_t)(struct xfs
 typedef void	(*xfs_dqdetach_t)(struct xfs_inode *);
 typedef int	(*xfs_dqpurgeall_t)(struct xfs_mount *, uint);
 typedef int	(*xfs_dqvopalloc_t)(struct xfs_mount *,
-			struct xfs_inode *, uid_t, gid_t, uint,
+			struct xfs_inode *, uid_t, gid_t, prid_t, uint,
 			struct xfs_dquot **, struct xfs_dquot **);
 typedef void	(*xfs_dqvopcreate_t)(struct xfs_trans *, struct xfs_inode *,
 			struct xfs_dquot *, struct xfs_dquot *);
@@ -185,8 +185,8 @@ typedef struct xfs_qmops {
 	(*(mp)->m_qm_ops.xfs_dqdetach)(ip)
 #define XFS_QM_DQPURGEALL(mp, fl) \
 	(*(mp)->m_qm_ops.xfs_dqpurgeall)(mp, fl)
-#define XFS_QM_DQVOPALLOC(mp, ip, uid, gid, fl, dq1, dq2) \
-	(*(mp)->m_qm_ops.xfs_dqvopalloc)(mp, ip, uid, gid, fl, dq1, dq2)
+#define XFS_QM_DQVOPALLOC(mp, ip, uid, gid, prid, fl, dq1, dq2) \
+	(*(mp)->m_qm_ops.xfs_dqvopalloc)(mp, ip, uid, gid, prid, fl, dq1, dq2)
 #define XFS_QM_DQVOPCREATE(mp, tp, ip, dq1, dq2) \
 	(*(mp)->m_qm_ops.xfs_dqvopcreate)(tp, ip, dq1, dq2)
 #define XFS_QM_DQVOPRENAME(mp, ip) \
@@ -544,7 +544,6 @@ extern void	xfs_mount_free(xfs_mount_t *
 extern int	xfs_mountfs(struct vfs *, xfs_mount_t *mp, int);
 
 extern int	xfs_unmountfs(xfs_mount_t *, struct cred *);
-extern void	xfs_unmountfs_wait(xfs_mount_t *);
 extern void	xfs_unmountfs_close(xfs_mount_t *, struct cred *);
 extern int	xfs_unmountfs_writesb(xfs_mount_t *);
 extern int	xfs_unmount_flush(xfs_mount_t *, int);
diff --git a/fs/xfs/xfs_quota.h b/fs/xfs/xfs_quota.h
--- a/fs/xfs/xfs_quota.h
+++ b/fs/xfs/xfs_quota.h
@@ -96,7 +96,7 @@ typedef struct xfs_dqblk {
  * flags for q_flags field in the dquot.
  */
 #define XFS_DQ_USER		0x0001		/* a user quota */
-/* #define XFS_DQ_PROJ		0x0002		-- project quota (IRIX) */
+#define XFS_DQ_PROJ		0x0002		/* project quota */
 #define XFS_DQ_GROUP		0x0004		/* a group quota */
 #define XFS_DQ_FLOCKED		0x0008		/* flush lock taken */
 #define XFS_DQ_DIRTY		0x0010		/* dquot is dirty */
@@ -104,6 +104,8 @@ typedef struct xfs_dqblk {
 #define XFS_DQ_INACTIVE		0x0040		/* dq off mplist & hashlist */
 #define XFS_DQ_MARKER		0x0080		/* sentinel */
 
+#define XFS_DQ_ALLTYPES		(XFS_DQ_USER|XFS_DQ_PROJ|XFS_DQ_GROUP)
+
 /*
  * In the worst case, when both user and group quotas are on,
  * we can have a max of three dquots changing in a single transaction.
@@ -124,7 +126,7 @@ typedef struct xfs_dqblk {
 typedef struct xfs_dq_logformat {
 	__uint16_t		qlf_type;      /* dquot log item type */
 	__uint16_t		qlf_size;      /* size of this item */
-	xfs_dqid_t		qlf_id;	       /* usr/grp id number : 32 bits */
+	xfs_dqid_t		qlf_id;	       /* usr/grp/proj id : 32 bits */
 	__int64_t		qlf_blkno;     /* blkno of dquot buffer */
 	__int32_t		qlf_len;       /* len of dquot buffer */
 	__uint32_t		qlf_boffset;   /* off of dquot in buffer */
@@ -152,9 +154,9 @@ typedef struct xfs_qoff_logformat {
 #define XFS_UQUOTA_ACCT	0x0001  /* user quota accounting ON */
 #define XFS_UQUOTA_ENFD	0x0002  /* user quota limits enforced */
 #define XFS_UQUOTA_CHKD	0x0004  /* quotacheck run on usr quotas */
-#define XFS_PQUOTA_ACCT	0x0008  /* (IRIX) project quota accounting ON */
-#define XFS_GQUOTA_ENFD	0x0010  /* group quota limits enforced */
-#define XFS_GQUOTA_CHKD	0x0020  /* quotacheck run on grp quotas */
+#define XFS_PQUOTA_ACCT	0x0008  /* project quota accounting ON */
+#define XFS_OQUOTA_ENFD	0x0010  /* other (grp/prj) quota limits enforced */
+#define XFS_OQUOTA_CHKD	0x0020  /* quotacheck run on other (grp/prj) quotas */
 #define XFS_GQUOTA_ACCT	0x0040  /* group quota accounting ON */
 
 /*
@@ -162,17 +164,22 @@ typedef struct xfs_qoff_logformat {
  * are in the process of getting turned off. These flags are in m_qflags but
  * never in sb_qflags.
  */
-#define XFS_UQUOTA_ACTIVE	0x0080  /* uquotas are being turned off */
-#define XFS_GQUOTA_ACTIVE	0x0100  /* gquotas are being turned off */
+#define XFS_UQUOTA_ACTIVE	0x0100  /* uquotas are being turned off */
+#define XFS_PQUOTA_ACTIVE	0x0200  /* pquotas are being turned off */
+#define XFS_GQUOTA_ACTIVE	0x0400  /* gquotas are being turned off */
 
 /*
  * Checking XFS_IS_*QUOTA_ON() while holding any inode lock guarantees
  * quota will be not be switched off as long as that inode lock is held.
  */
 #define XFS_IS_QUOTA_ON(mp)	((mp)->m_qflags & (XFS_UQUOTA_ACTIVE | \
-						   XFS_GQUOTA_ACTIVE))
+						   XFS_GQUOTA_ACTIVE | \
+						   XFS_PQUOTA_ACTIVE))
+#define XFS_IS_OQUOTA_ON(mp)	((mp)->m_qflags & (XFS_GQUOTA_ACTIVE | \
+						   XFS_PQUOTA_ACTIVE))
 #define XFS_IS_UQUOTA_ON(mp)	((mp)->m_qflags & XFS_UQUOTA_ACTIVE)
 #define XFS_IS_GQUOTA_ON(mp)	((mp)->m_qflags & XFS_GQUOTA_ACTIVE)
+#define XFS_IS_PQUOTA_ON(mp)	((mp)->m_qflags & XFS_PQUOTA_ACTIVE)
 
 /*
  * Flags to tell various functions what to do. Not all of these are meaningful
@@ -182,7 +189,7 @@ typedef struct xfs_qoff_logformat {
 #define XFS_QMOPT_DQLOCK	0x0000001 /* dqlock */
 #define XFS_QMOPT_DQALLOC	0x0000002 /* alloc dquot ondisk if needed */
 #define XFS_QMOPT_UQUOTA	0x0000004 /* user dquot requested */
-#define XFS_QMOPT_GQUOTA	0x0000008 /* group dquot requested */
+#define XFS_QMOPT_PQUOTA	0x0000008 /* project dquot requested */
 #define XFS_QMOPT_FORCE_RES	0x0000010 /* ignore quota limits */
 #define XFS_QMOPT_DQSUSER	0x0000020 /* don't cache super users dquot */
 #define XFS_QMOPT_SBVERSION	0x0000040 /* change superblock version num */
@@ -192,6 +199,7 @@ typedef struct xfs_qoff_logformat {
 #define XFS_QMOPT_DOWARN        0x0000400 /* increase warning cnt if necessary */
 #define XFS_QMOPT_ILOCKED	0x0000800 /* inode is already locked (excl) */
 #define XFS_QMOPT_DQREPAIR	0x0001000 /* repair dquot, if damaged. */
+#define XFS_QMOPT_GQUOTA	0x0002000 /* group dquot requested */
 
 /*
  * flags to xfs_trans_mod_dquot to indicate which field needs to be
@@ -231,7 +239,8 @@ typedef struct xfs_qoff_logformat {
 #define XFS_TRANS_DQ_DELRTBCOUNT XFS_QMOPT_DELRTBCOUNT
 
 
-#define XFS_QMOPT_QUOTALL	(XFS_QMOPT_UQUOTA|XFS_QMOPT_GQUOTA)
+#define XFS_QMOPT_QUOTALL	\
+		(XFS_QMOPT_UQUOTA | XFS_QMOPT_PQUOTA | XFS_QMOPT_GQUOTA)
 #define XFS_QMOPT_RESBLK_MASK	(XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_RES_RTBLKS)
 
 #ifdef __KERNEL__
@@ -246,21 +255,33 @@ typedef struct xfs_qoff_logformat {
  */
 #define XFS_NOT_DQATTACHED(mp, ip) ((XFS_IS_UQUOTA_ON(mp) &&\
 				     (ip)->i_udquot == NULL) || \
-				    (XFS_IS_GQUOTA_ON(mp) && \
+				    (XFS_IS_OQUOTA_ON(mp) && \
 				     (ip)->i_gdquot == NULL))
 
-#define XFS_QM_NEED_QUOTACHECK(mp) ((XFS_IS_UQUOTA_ON(mp) && \
-				     (mp->m_sb.sb_qflags & \
-				      XFS_UQUOTA_CHKD) == 0) || \
-				    (XFS_IS_GQUOTA_ON(mp) && \
-				     (mp->m_sb.sb_qflags & \
-				      XFS_GQUOTA_CHKD) == 0))
+#define XFS_QM_NEED_QUOTACHECK(mp) \
+	((XFS_IS_UQUOTA_ON(mp) && \
+		(mp->m_sb.sb_qflags & XFS_UQUOTA_CHKD) == 0) || \
+	 (XFS_IS_GQUOTA_ON(mp) && \
+		((mp->m_sb.sb_qflags & XFS_OQUOTA_CHKD) == 0 || \
+		 (mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT))) || \
+	 (XFS_IS_PQUOTA_ON(mp) && \
+		((mp->m_sb.sb_qflags & XFS_OQUOTA_CHKD) == 0 || \
+		 (mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT))))
+
+#define XFS_MOUNT_QUOTA_SET1	(XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD|\
+				 XFS_UQUOTA_CHKD|XFS_PQUOTA_ACCT|\
+				 XFS_OQUOTA_ENFD|XFS_OQUOTA_CHKD)
 
-#define XFS_MOUNT_QUOTA_ALL	(XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD|\
+#define XFS_MOUNT_QUOTA_SET2	(XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD|\
 				 XFS_UQUOTA_CHKD|XFS_GQUOTA_ACCT|\
-				 XFS_GQUOTA_ENFD|XFS_GQUOTA_CHKD)
+				 XFS_OQUOTA_ENFD|XFS_OQUOTA_CHKD)
+
+#define XFS_MOUNT_QUOTA_ALL	(XFS_UQUOTA_ACCT|XFS_UQUOTA_ENFD|\
+				 XFS_UQUOTA_CHKD|XFS_PQUOTA_ACCT|\
+				 XFS_OQUOTA_ENFD|XFS_OQUOTA_CHKD|\
+				 XFS_GQUOTA_ACCT)
 #define XFS_MOUNT_QUOTA_MASK	(XFS_MOUNT_QUOTA_ALL | XFS_UQUOTA_ACTIVE | \
-				 XFS_GQUOTA_ACTIVE)
+				 XFS_GQUOTA_ACTIVE | XFS_PQUOTA_ACTIVE)
 
 
 /*
@@ -331,15 +352,8 @@ typedef struct xfs_dqtrxops {
 #define XFS_TRANS_UNRESERVE_AND_MOD_DQUOTS(mp, tp) \
 	XFS_DQTRXOP_VOID(mp, tp, qo_unreserve_and_mod_dquots)
 
-#define XFS_TRANS_RESERVE_BLKQUOTA(mp, tp, ip, nblks) \
-	XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, tp, ip, nblks, 0, \
-				XFS_QMOPT_RES_REGBLKS)
-#define XFS_TRANS_RESERVE_BLKQUOTA_FORCE(mp, tp, ip, nblks) \
-	XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, tp, ip, nblks, 0, \
-				XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_FORCE_RES)
-#define XFS_TRANS_UNRESERVE_BLKQUOTA(mp, tp, ip, nblks) \
-	XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, tp, ip, -(nblks), 0, \
-				XFS_QMOPT_RES_REGBLKS)
+#define XFS_TRANS_UNRESERVE_QUOTA_NBLKS(mp, tp, ip, nblks, ninos, flags) \
+	XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, tp, ip, -(nblks), -(ninos), flags)
 #define XFS_TRANS_RESERVE_QUOTA(mp, tp, ud, gd, nb, ni, f) \
 	XFS_TRANS_RESERVE_QUOTA_BYDQUOTS(mp, tp, ud, gd, nb, ni, \
 				f | XFS_QMOPT_RES_REGBLKS)
diff --git a/fs/xfs/xfs_rename.c b/fs/xfs/xfs_rename.c
--- a/fs/xfs/xfs_rename.c
+++ b/fs/xfs/xfs_rename.c
@@ -234,9 +234,6 @@ xfs_lock_for_rename(
 	return 0;
 }
 
-
-int rename_which_error_return = 0;
-
 /*
  * xfs_rename
  */
@@ -316,7 +313,6 @@ xfs_rename(
 			&num_inodes);
 
 	if (error) {
-		rename_which_error_return = __LINE__;
 		/*
 		 * We have nothing locked, no inode references, and
 		 * no transaction, so just get out.
@@ -332,7 +328,6 @@ xfs_rename(
 		 */
 		if (target_ip == NULL && (src_dp != target_dp) &&
 		    target_dp->i_d.di_nlink >= XFS_MAXLINK) {
-			rename_which_error_return = __LINE__;
 			error = XFS_ERROR(EMLINK);
 			xfs_rename_unlock4(inodes, XFS_ILOCK_SHARED);
 			goto rele_return;
@@ -359,7 +354,6 @@ xfs_rename(
 				XFS_TRANS_PERM_LOG_RES, XFS_RENAME_LOG_COUNT);
 	}
 	if (error) {
-		rename_which_error_return = __LINE__;
 		xfs_trans_cancel(tp, 0);
 		goto rele_return;
 	}
@@ -369,7 +363,6 @@ xfs_rename(
 	 */
 	if ((error = XFS_QM_DQVOPRENAME(mp, inodes))) {
 		xfs_trans_cancel(tp, cancel_flags);
-		rename_which_error_return = __LINE__;
 		goto rele_return;
 	}
 
@@ -413,7 +406,6 @@ xfs_rename(
 		if (spaceres == 0 &&
 		    (error = XFS_DIR_CANENTER(mp, tp, target_dp, target_name,
 				target_namelen))) {
-			rename_which_error_return = __LINE__;
 			goto error_return;
 		}
 		/*
@@ -425,11 +417,9 @@ xfs_rename(
 					   target_namelen, src_ip->i_ino,
 					   &first_block, &free_list, spaceres);
 		if (error == ENOSPC) {
-			rename_which_error_return = __LINE__;
 			goto error_return;
 		}
 		if (error) {
-			rename_which_error_return = __LINE__;
 			goto abort_return;
 		}
 		xfs_ichgtime(target_dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
@@ -437,7 +427,6 @@ xfs_rename(
 		if (new_parent && src_is_directory) {
 			error = xfs_bumplink(tp, target_dp);
 			if (error) {
-				rename_which_error_return = __LINE__;
 				goto abort_return;
 			}
 		}
@@ -455,7 +444,6 @@ xfs_rename(
 			if (!(XFS_DIR_ISEMPTY(target_ip->i_mount, target_ip)) ||
 			    (target_ip->i_d.di_nlink > 2)) {
 				error = XFS_ERROR(EEXIST);
-				rename_which_error_return = __LINE__;
 				goto error_return;
 			}
 		}
@@ -473,7 +461,6 @@ xfs_rename(
 			target_namelen, src_ip->i_ino, &first_block,
 			&free_list, spaceres);
 		if (error) {
-			rename_which_error_return = __LINE__;
 			goto abort_return;
 		}
 		xfs_ichgtime(target_dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
@@ -484,7 +471,6 @@ xfs_rename(
 		 */
 		error = xfs_droplink(tp, target_ip);
 		if (error) {
-			rename_which_error_return = __LINE__;
 			goto abort_return;
 		}
 		target_ip_dropped = 1;
@@ -495,7 +481,6 @@ xfs_rename(
 			 */
 			error = xfs_droplink(tp, target_ip);
 			if (error) {
-				rename_which_error_return = __LINE__;
 				goto abort_return;
 			}
 		}
@@ -519,7 +504,6 @@ xfs_rename(
 					&free_list, spaceres);
 		ASSERT(error != EEXIST);
 		if (error) {
-			rename_which_error_return = __LINE__;
 			goto abort_return;
 		}
 		xfs_ichgtime(src_ip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
@@ -550,7 +534,6 @@ xfs_rename(
 		 */
 		error = xfs_droplink(tp, src_dp);
 		if (error) {
-			rename_which_error_return = __LINE__;
 			goto abort_return;
 		}
 	}
@@ -558,7 +541,6 @@ xfs_rename(
 	error = XFS_DIR_REMOVENAME(mp, tp, src_dp, src_name, src_namelen,
 			src_ip->i_ino, &first_block, &free_list, spaceres);
 	if (error) {
-		rename_which_error_return = __LINE__;
 		goto abort_return;
 	}
 	xfs_ichgtime(src_dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c
--- a/fs/xfs/xfs_trans.c
+++ b/fs/xfs/xfs_trans.c
@@ -332,25 +332,6 @@ undo_blocks:
 
 
 /*
- * This is called to set the a callback to be called when the given
- * transaction is committed to disk.  The transaction pointer and the
- * argument pointer will be passed to the callback routine.
- *
- * Only one callback can be associated with any single transaction.
- */
-void
-xfs_trans_callback(
-	xfs_trans_t		*tp,
-	xfs_trans_callback_t	callback,
-	void			*arg)
-{
-	ASSERT(tp->t_callback == NULL);
-	tp->t_callback = callback;
-	tp->t_callarg = arg;
-}
-
-
-/*
  * Record the indicated change to the given field for application
  * to the file system's superblock when the transaction commits.
  * For now, just store the change in the transaction structure.
@@ -551,7 +532,7 @@ xfs_trans_apply_sb_deltas(
  *
  * This is done efficiently with a single call to xfs_mod_incore_sb_batch().
  */
-void
+STATIC void
 xfs_trans_unreserve_and_mod_sb(
 	xfs_trans_t	*tp)
 {
diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h
--- a/fs/xfs/xfs_trans.h
+++ b/fs/xfs/xfs_trans.h
@@ -987,8 +987,6 @@ xfs_trans_t	*_xfs_trans_alloc(struct xfs
 xfs_trans_t	*xfs_trans_dup(xfs_trans_t *);
 int		xfs_trans_reserve(xfs_trans_t *, uint, uint, uint,
 				  uint, uint);
-void		xfs_trans_callback(xfs_trans_t *,
-				   void (*)(xfs_trans_t *, void *), void *);
 void		xfs_trans_mod_sb(xfs_trans_t *, uint, long);
 struct xfs_buf	*xfs_trans_get_buf(xfs_trans_t *, struct xfs_buftarg *, xfs_daddr_t,
 				   int, uint);
@@ -1010,7 +1008,6 @@ int		xfs_trans_iget(struct xfs_mount *, 
 			       xfs_ino_t , uint, uint, struct xfs_inode **);
 void		xfs_trans_ijoin(xfs_trans_t *, struct xfs_inode *, uint);
 void		xfs_trans_ihold(xfs_trans_t *, struct xfs_inode *);
-void		xfs_trans_ihold_release(xfs_trans_t *, struct xfs_inode *);
 void		xfs_trans_log_buf(xfs_trans_t *, struct xfs_buf *, uint, uint);
 void		xfs_trans_log_inode(xfs_trans_t *, struct xfs_inode *, uint);
 struct xfs_efi_log_item	*xfs_trans_get_efi(xfs_trans_t *, uint);
diff --git a/fs/xfs/xfs_trans_buf.c b/fs/xfs/xfs_trans_buf.c
--- a/fs/xfs/xfs_trans_buf.c
+++ b/fs/xfs/xfs_trans_buf.c
@@ -976,6 +976,7 @@ xfs_trans_dquot_buf(
 	ASSERT(XFS_BUF_FSPRIVATE2(bp, xfs_trans_t *) == tp);
 	ASSERT(XFS_BUF_FSPRIVATE(bp, void *) != NULL);
 	ASSERT(type == XFS_BLI_UDQUOT_BUF ||
+	       type == XFS_BLI_PDQUOT_BUF ||
 	       type == XFS_BLI_GDQUOT_BUF);
 
 	bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *);
diff --git a/fs/xfs/xfs_trans_inode.c b/fs/xfs/xfs_trans_inode.c
--- a/fs/xfs/xfs_trans_inode.c
+++ b/fs/xfs/xfs_trans_inode.c
@@ -253,24 +253,6 @@ xfs_trans_ihold(
 	ip->i_itemp->ili_flags |= XFS_ILI_HOLD;
 }
 
-/*
- * Cancel the previous inode hold request made on this inode
- * for this transaction.
- */
-/*ARGSUSED*/
-void
-xfs_trans_ihold_release(
-	xfs_trans_t	*tp,
-	xfs_inode_t	*ip)
-{
-	ASSERT(ip->i_transp == tp);
-	ASSERT(ip->i_itemp != NULL);
-	ASSERT(ismrlocked(&ip->i_lock, MR_UPDATE));
-	ASSERT(ip->i_itemp->ili_flags & XFS_ILI_HOLD);
-
-	ip->i_itemp->ili_flags &= ~XFS_ILI_HOLD;
-}
-
 
 /*
  * This is called to mark the fields indicated in fieldmask as needing
diff --git a/fs/xfs/xfs_types.h b/fs/xfs/xfs_types.h
--- a/fs/xfs/xfs_types.h
+++ b/fs/xfs/xfs_types.h
@@ -55,7 +55,7 @@ typedef signed long long int	__int64_t;
 typedef unsigned long long int	__uint64_t;
 
 typedef enum { B_FALSE,B_TRUE }	boolean_t;
-typedef __int64_t		prid_t;		/* project ID */
+typedef __uint32_t		prid_t;		/* project ID */
 typedef __uint32_t		inst_t;		/* an instruction */
 
 typedef __s64			xfs_off_t;	/* <file offset> type */
diff --git a/fs/xfs/xfs_utils.c b/fs/xfs/xfs_utils.c
--- a/fs/xfs/xfs_utils.c
+++ b/fs/xfs/xfs_utils.c
@@ -428,7 +428,7 @@ xfs_truncate_file(
 		if (ip->i_ino != mp->m_sb.sb_uquotino)
 			ASSERT(ip->i_udquot);
 	}
-	if (XFS_IS_GQUOTA_ON(mp)) {
+	if (XFS_IS_OQUOTA_ON(mp)) {
 		if (ip->i_ino != mp->m_sb.sb_gquotino)
 			ASSERT(ip->i_gdquot);
 	}
diff --git a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c
--- a/fs/xfs/xfs_vfsops.c
+++ b/fs/xfs/xfs_vfsops.c
@@ -368,16 +368,6 @@ xfs_finish_flags(
 	}
 
 	/*
-	 * disallow mount attempts with (IRIX) project quota enabled
-	 */
-	if (XFS_SB_VERSION_HASQUOTA(&mp->m_sb) &&
-	    (mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT)) {
-		cmn_err(CE_WARN,
-	"XFS: cannot mount a filesystem with IRIX project quota enabled");
-		return XFS_ERROR(ENOSYS);
-	}
-
-	/*
 	 * check for shared mount.
 	 */
 	if (ap->flags & XFSMNT_SHARED) {
@@ -622,7 +612,34 @@ out:
 	return XFS_ERROR(error);
 }
 
-#define REMOUNT_READONLY_FLAGS	(SYNC_REMOUNT|SYNC_ATTR|SYNC_WAIT)
+STATIC int
+xfs_quiesce_fs(
+	xfs_mount_t		*mp)
+{
+	int			count = 0, pincount;
+		
+	xfs_refcache_purge_mp(mp);
+	xfs_flush_buftarg(mp->m_ddev_targp, 0);
+	xfs_finish_reclaim_all(mp, 0);
+
+	/* This loop must run at least twice.
+	 * The first instance of the loop will flush
+	 * most meta data but that will generate more
+	 * meta data (typically directory updates).
+	 * Which then must be flushed and logged before
+	 * we can write the unmount record.
+	 */ 
+	do {
+		xfs_syncsub(mp, SYNC_REMOUNT|SYNC_ATTR|SYNC_WAIT, 0, NULL);
+		pincount = xfs_flush_buftarg(mp->m_ddev_targp, 1);
+		if (!pincount) {
+			delay(50);
+			count++;
+		}
+	} while (count < 2);
+
+	return 0;
+}
 
 STATIC int
 xfs_mntupdate(
@@ -632,8 +649,7 @@ xfs_mntupdate(
 {
 	struct vfs	*vfsp = bhvtovfs(bdp);
 	xfs_mount_t	*mp = XFS_BHVTOM(bdp);
-	int		pincount, error;
-	int		count = 0;
+	int		error;
 
 	if (args->flags & XFSMNT_NOATIME)
 		mp->m_flags |= XFS_MOUNT_NOATIME;
@@ -645,25 +661,7 @@ xfs_mntupdate(
 	}
 
 	if (*flags & MS_RDONLY) {
-		xfs_refcache_purge_mp(mp);
-		xfs_flush_buftarg(mp->m_ddev_targp, 0);
-		xfs_finish_reclaim_all(mp, 0);
-
-		/* This loop must run at least twice.
-		 * The first instance of the loop will flush
-		 * most meta data but that will generate more
-		 * meta data (typically directory updates).
-		 * Which then must be flushed and logged before
-		 * we can write the unmount record.
-		 */ 
-		do {
-			VFS_SYNC(vfsp, REMOUNT_READONLY_FLAGS, NULL, error);
-			pincount = xfs_flush_buftarg(mp->m_ddev_targp, 1);
-			if (!pincount) {
-				delay(50);
-				count++;
-			}
-		} while (count < 2);
+		xfs_quiesce_fs(mp);
 
 		/* Ok now write out an unmount record */
 		xfs_log_unmount_write(mp);
@@ -879,10 +877,12 @@ xfs_sync(
 	int		flags,
 	cred_t		*credp)
 {
-	xfs_mount_t	*mp;
+	xfs_mount_t	*mp = XFS_BHVTOM(bdp);
 
-	mp = XFS_BHVTOM(bdp);
-	return (xfs_syncsub(mp, flags, 0, NULL));
+	if (unlikely(flags == SYNC_QUIESCE))
+		return xfs_quiesce_fs(mp);
+	else
+		return xfs_syncsub(mp, flags, 0, NULL);
 }
 
 /*
@@ -1681,7 +1681,7 @@ suffix_strtoul(const char *cp, char **en
 	return simple_strtoul(cp, endp, base) << shift_left_factor;
 }
 
-int
+STATIC int
 xfs_parseargs(
 	struct bhv_desc		*bhv,
 	char			*options,
@@ -1867,7 +1867,7 @@ printk("XFS: irixsgid is now a sysctl(2)
 	return 0;
 }
 
-int
+STATIC int
 xfs_showargs(
 	struct bhv_desc		*bhv,
 	struct seq_file		*m)
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
--- a/fs/xfs/xfs_vnodeops.c
+++ b/fs/xfs/xfs_vnodeops.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2004 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 2000-2005 Silicon Graphics, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -351,21 +351,28 @@ xfs_setattr(
 	 * If the IDs do change before we take the ilock, we're covered
 	 * because the i_*dquot fields will get updated anyway.
 	 */
-	if (XFS_IS_QUOTA_ON(mp) && (mask & (XFS_AT_UID|XFS_AT_GID))) {
+	if (XFS_IS_QUOTA_ON(mp) &&
+	    (mask & (XFS_AT_UID|XFS_AT_GID|XFS_AT_PROJID))) {
 		uint	qflags = 0;
 
-		if (mask & XFS_AT_UID) {
+		if ((mask & XFS_AT_UID) && XFS_IS_UQUOTA_ON(mp)) {
 			uid = vap->va_uid;
 			qflags |= XFS_QMOPT_UQUOTA;
 		} else {
 			uid = ip->i_d.di_uid;
 		}
-		if (mask & XFS_AT_GID) {
+		if ((mask & XFS_AT_GID) && XFS_IS_GQUOTA_ON(mp)) {
 			gid = vap->va_gid;
 			qflags |= XFS_QMOPT_GQUOTA;
 		}  else {
 			gid = ip->i_d.di_gid;
 		}
+		if ((mask & XFS_AT_PROJID) && XFS_IS_PQUOTA_ON(mp)) {
+			projid = vap->va_projid;
+			qflags |= XFS_QMOPT_PQUOTA;
+		}  else {
+			projid = ip->i_d.di_projid;
+		}
 		/*
 		 * We take a reference when we initialize udqp and gdqp,
 		 * so it is important that we never blindly double trip on
@@ -373,7 +380,8 @@ xfs_setattr(
 		 */
 		ASSERT(udqp == NULL);
 		ASSERT(gdqp == NULL);
-		code = XFS_QM_DQVOPALLOC(mp, ip, uid,gid, qflags, &udqp, &gdqp);
+		code = XFS_QM_DQVOPALLOC(mp, ip, uid, gid, projid, qflags,
+					 &udqp, &gdqp);
 		if (code)
 			return (code);
 	}
@@ -499,8 +507,6 @@ xfs_setattr(
 		 * that the group ID supplied to the chown() function
 		 * shall be equal to either the group ID or one of the
 		 * supplementary group IDs of the calling process.
-		 *
-		 * XXX: How does restricted_chown affect projid?
 		 */
 		if (restricted_chown &&
 		    (iuid != uid || (igid != gid &&
@@ -510,10 +516,11 @@ xfs_setattr(
 			goto error_return;
 		}
 		/*
-		 * Do a quota reservation only if uid or gid is actually
+		 * Do a quota reservation only if uid/projid/gid is actually
 		 * going to change.
 		 */
 		if ((XFS_IS_UQUOTA_ON(mp) && iuid != uid) ||
+		    (XFS_IS_PQUOTA_ON(mp) && iprojid != projid) ||
 		    (XFS_IS_GQUOTA_ON(mp) && igid != gid)) {
 			ASSERT(tp);
 			code = XFS_QM_DQVOPCHOWNRESV(mp, tp, ip, udqp, gdqp,
@@ -774,6 +781,7 @@ xfs_setattr(
 		}
 		if (igid != gid) {
 			if (XFS_IS_GQUOTA_ON(mp)) {
+				ASSERT(!XFS_IS_PQUOTA_ON(mp));
 				ASSERT(mask & XFS_AT_GID);
 				ASSERT(gdqp);
 				olddquot2 = XFS_QM_DQVOPCHOWN(mp, tp, ip,
@@ -782,6 +790,13 @@ xfs_setattr(
 			ip->i_d.di_gid = gid;
 		}
 		if (iprojid != projid) {
+			if (XFS_IS_PQUOTA_ON(mp)) {
+				ASSERT(!XFS_IS_GQUOTA_ON(mp));
+				ASSERT(mask & XFS_AT_PROJID);
+				ASSERT(gdqp);
+				olddquot2 = XFS_QM_DQVOPCHOWN(mp, tp, ip,
+							&ip->i_gdquot, gdqp);
+			}
 			ip->i_d.di_projid = projid;
 			/*
 			 * We may have to rev the inode as well as
@@ -843,6 +858,8 @@ xfs_setattr(
 				di_flags |= XFS_DIFLAG_NOATIME;
 			if (vap->va_xflags & XFS_XFLAG_NODUMP)
 				di_flags |= XFS_DIFLAG_NODUMP;
+			if (vap->va_xflags & XFS_XFLAG_PROJINHERIT)
+				di_flags |= XFS_DIFLAG_PROJINHERIT;
 			if ((ip->i_d.di_mode & S_IFMT) == S_IFDIR) {
 				if (vap->va_xflags & XFS_XFLAG_RTINHERIT)
 					di_flags |= XFS_DIFLAG_RTINHERIT;
@@ -1898,7 +1915,9 @@ xfs_create(
 	/* Return through std_return after this point. */
 
 	udqp = gdqp = NULL;
-	if (vap->va_mask & XFS_AT_PROJID)
+	if (dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT)
+		prid = dp->i_d.di_projid;
+	else if (vap->va_mask & XFS_AT_PROJID)
 		prid = (xfs_prid_t)vap->va_projid;
 	else
 		prid = (xfs_prid_t)dfltprid;
@@ -1907,7 +1926,7 @@ xfs_create(
 	 * Make sure that we have allocated dquot(s) on disk.
 	 */
 	error = XFS_QM_DQVOPALLOC(mp, dp,
-			current_fsuid(credp), current_fsgid(credp),
+			current_fsuid(credp), current_fsgid(credp), prid,
 			XFS_QMOPT_QUOTALL|XFS_QMOPT_INHERIT, &udqp, &gdqp);
 	if (error)
 		goto std_return;
@@ -2604,17 +2623,7 @@ xfs_link(
 	if (src_vp->v_type == VDIR)
 		return XFS_ERROR(EPERM);
 
-	/*
-	 * For now, manually find the XFS behavior descriptor for
-	 * the source vnode.  If it doesn't exist then something
-	 * is wrong and we should just return an error.
-	 * Eventually we need to figure out how link is going to
-	 * work in the face of stacked vnodes.
-	 */
 	src_bdp = vn_bhv_lookup_unlocked(VN_BHV_HEAD(src_vp), &xfs_vnodeops);
-	if (src_bdp == NULL) {
-		return XFS_ERROR(EXDEV);
-	}
 	sip = XFS_BHVTOI(src_bdp);
 	tdp = XFS_BHVTOI(target_dir_bdp);
 	mp = tdp->i_mount;
@@ -2681,6 +2690,17 @@ xfs_link(
 		goto error_return;
 	}
 
+	/*
+	 * If we are using project inheritance, we only allow hard link
+	 * creation in our tree when the project IDs are the same; else
+	 * the tree quota mechanism could be circumvented.
+	 */
+	if (unlikely((tdp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) &&
+		     (tdp->i_d.di_projid != sip->i_d.di_projid))) {
+		error = XFS_ERROR(EPERM);
+		goto error_return;
+	}
+
 	if (resblks == 0 &&
 	    (error = XFS_DIR_CANENTER(mp, tp, tdp, target_name,
 			target_namelen)))
@@ -2803,7 +2823,9 @@ xfs_mkdir(
 
 	mp = dp->i_mount;
 	udqp = gdqp = NULL;
-	if (vap->va_mask & XFS_AT_PROJID)
+	if (dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT)
+		prid = dp->i_d.di_projid;
+	else if (vap->va_mask & XFS_AT_PROJID)
 		prid = (xfs_prid_t)vap->va_projid;
 	else
 		prid = (xfs_prid_t)dfltprid;
@@ -2812,7 +2834,7 @@ xfs_mkdir(
 	 * Make sure that we have allocated dquot(s) on disk.
 	 */
 	error = XFS_QM_DQVOPALLOC(mp, dp,
-			current_fsuid(credp), current_fsgid(credp),
+			current_fsuid(credp), current_fsgid(credp), prid,
 			XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT, &udqp, &gdqp);
 	if (error)
 		goto std_return;
@@ -3357,7 +3379,9 @@ xfs_symlink(
 	/* Return through std_return after this point. */
 
 	udqp = gdqp = NULL;
-	if (vap->va_mask & XFS_AT_PROJID)
+	if (dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT)
+		prid = dp->i_d.di_projid;
+	else if (vap->va_mask & XFS_AT_PROJID)
 		prid = (xfs_prid_t)vap->va_projid;
 	else
 		prid = (xfs_prid_t)dfltprid;
@@ -3366,7 +3390,7 @@ xfs_symlink(
 	 * Make sure that we have allocated dquot(s) on disk.
 	 */
 	error = XFS_QM_DQVOPALLOC(mp, dp,
-			current_fsuid(credp), current_fsgid(credp),
+			current_fsuid(credp), current_fsgid(credp), prid,
 			XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT, &udqp, &gdqp);
 	if (error)
 		goto std_return;
@@ -4028,7 +4052,7 @@ xfs_finish_reclaim_all(xfs_mount_t *mp, 
  *      errno on error
  *
  */
-int
+STATIC int
 xfs_alloc_file_space(
 	xfs_inode_t		*ip,
 	xfs_off_t		offset,
@@ -4151,9 +4175,8 @@ retry:
 			break;
 		}
 		xfs_ilock(ip, XFS_ILOCK_EXCL);
-		error = XFS_TRANS_RESERVE_QUOTA_BYDQUOTS(mp, tp,
-				ip->i_udquot, ip->i_gdquot, resblks, 0, rt ?
-				XFS_QMOPT_RES_RTBLKS : XFS_QMOPT_RES_REGBLKS);
+		error = XFS_TRANS_RESERVE_QUOTA(mp, tp,
+				ip->i_udquot, ip->i_gdquot, resblks, 0, 0);
 		if (error)
 			goto error1;
 
@@ -4305,6 +4328,7 @@ xfs_free_file_space(
 	xfs_off_t		len,
 	int			attr_flags)
 {
+	vnode_t			*vp;
 	int			committed;
 	int			done;
 	xfs_off_t		end_dmi_offset;
@@ -4325,9 +4349,11 @@ xfs_free_file_space(
 	xfs_trans_t		*tp;
 	int			need_iolock = 1;
 
-	vn_trace_entry(XFS_ITOV(ip), __FUNCTION__, (inst_t *)__return_address);
+	vp = XFS_ITOV(ip);
 	mp = ip->i_mount;
 
+	vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
+
 	if ((error = XFS_QM_DQATTACH(mp, ip, 0)))
 		return error;
 
@@ -4344,7 +4370,7 @@ xfs_free_file_space(
 	    DM_EVENT_ENABLED(XFS_MTOVFS(mp), ip, DM_EVENT_WRITE)) {
 		if (end_dmi_offset > ip->i_d.di_size)
 			end_dmi_offset = ip->i_d.di_size;
-		error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, XFS_ITOV(ip),
+		error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, vp,
 				offset, end_dmi_offset - offset,
 				AT_DELAY_FLAG(attr_flags), NULL);
 		if (error)
@@ -4363,7 +4389,14 @@ xfs_free_file_space(
 	ioffset = offset & ~(rounding - 1);
 	if (ilen & (rounding - 1))
 		ilen = (ilen + rounding) & ~(rounding - 1);
-	xfs_inval_cached_pages(XFS_ITOV(ip), &(ip->i_iocore), ioffset, 0, 0);
+
+	if (VN_CACHED(vp) != 0) {
+		xfs_inval_cached_trace(&ip->i_iocore, ioffset, -1,
+				ctooff(offtoct(ioffset)), -1);
+		VOP_FLUSHINVAL_PAGES(vp, ctooff(offtoct(ioffset)),
+				-1, FI_REMAPF_LOCKED);
+	}
+
 	/*
 	 * Need to zero the stuff we're not freeing, on disk.
 	 * If its a realtime file & can't use unwritten extents then we
diff --git a/include/acpi/acconfig.h b/include/acpi/acconfig.h
--- a/include/acpi/acconfig.h
+++ b/include/acpi/acconfig.h
@@ -64,7 +64,7 @@
 
 /* Version string */
 
-#define ACPI_CA_VERSION                 0x20050309
+#define ACPI_CA_VERSION                 0x20050408
 
 /*
  * OS name, used for the _OS object.  The _OS object is essentially obsolete,
@@ -130,9 +130,8 @@
 #define ACPI_MAX_GPE_BLOCKS             2
 #define ACPI_GPE_REGISTER_WIDTH         8
 
-/*
- * Method info (in WALK_STATE), containing local variables and argumetns
- */
+/* Method info (in WALK_STATE), containing local variables and argumetns */
+
 #define ACPI_METHOD_NUM_LOCALS          8
 #define ACPI_METHOD_MAX_LOCAL           7
 
diff --git a/include/acpi/acdebug.h b/include/acpi/acdebug.h
--- a/include/acpi/acdebug.h
+++ b/include/acpi/acdebug.h
@@ -61,9 +61,7 @@ struct argument_info
 
 
 #define PARAM_LIST(pl)                  pl
-
 #define DBTEST_OUTPUT_LEVEL(lvl)        if (acpi_gbl_db_opt_verbose)
-
 #define VERBOSE_PRINT(fp)               DBTEST_OUTPUT_LEVEL(lvl) {\
 			  acpi_os_printf PARAM_LIST(fp);}
 
@@ -71,13 +69,9 @@ struct argument_info
 #define EX_SINGLE_STEP                  2
 
 
-/* Prototypes */
-
-
 /*
  * dbxface - external debugger interfaces
  */
-
 acpi_status
 acpi_db_initialize (
 	void);
@@ -92,20 +86,10 @@ acpi_db_single_step (
 	union acpi_parse_object         *op,
 	u32                             op_type);
 
-acpi_status
-acpi_db_start_command (
-	struct acpi_walk_state          *walk_state,
-	union acpi_parse_object         *op);
-
-void
-acpi_db_method_end (
-	struct acpi_walk_state          *walk_state);
-
 
 /*
  * dbcmds - debug commands and output routines
  */
-
 acpi_status
 acpi_db_disassemble_method (
 	char                            *name);
@@ -177,57 +161,30 @@ acpi_db_find_references (
 	char                            *object_arg);
 
 void
-acpi_db_display_locks (void);
-
+acpi_db_display_locks (
+	void);
 
 void
 acpi_db_display_resources (
 	char                            *object_arg);
 
 void
-acpi_db_display_gpes (void);
+acpi_db_display_gpes (
+	void);
 
 void
 acpi_db_check_integrity (
 	void);
 
-acpi_status
-acpi_db_integrity_walk (
-	acpi_handle                     obj_handle,
-	u32                             nesting_level,
-	void                            *context,
-	void                            **return_value);
-
-acpi_status
-acpi_db_walk_and_match_name (
-	acpi_handle                     obj_handle,
-	u32                             nesting_level,
-	void                            *context,
-	void                            **return_value);
-
-acpi_status
-acpi_db_walk_for_references (
-	acpi_handle                     obj_handle,
-	u32                             nesting_level,
-	void                            *context,
-	void                            **return_value);
-
-acpi_status
-acpi_db_walk_for_specific_objects (
-	acpi_handle                     obj_handle,
-	u32                             nesting_level,
-	void                            *context,
-	void                            **return_value);
-
 void
 acpi_db_generate_gpe (
 	char                            *gpe_arg,
 	char                            *block_arg);
 
+
 /*
  * dbdisply - debug display commands
  */
-
 void
 acpi_db_display_method_info (
 	union acpi_parse_object         *op);
@@ -271,19 +228,10 @@ acpi_db_display_argument_object (
 	union acpi_operand_object       *obj_desc,
 	struct acpi_walk_state          *walk_state);
 
-void
-acpi_db_dump_parser_descriptor (
-	union acpi_parse_object         *op);
-
-void *
-acpi_db_get_pointer (
-	void                            *target);
-
 
 /*
  * dbexec - debugger control method execution
  */
-
 void
 acpi_db_execute (
 	char                            *name,
@@ -296,44 +244,15 @@ acpi_db_create_execution_threads (
 	char                            *num_loops_arg,
 	char                            *method_name_arg);
 
-acpi_status
-acpi_db_execute_method (
-	struct acpi_db_method_info      *info,
-	struct acpi_buffer              *return_obj);
-
-void
-acpi_db_execute_setup (
-	struct acpi_db_method_info      *info);
-
-u32
-acpi_db_get_outstanding_allocations (
-	void);
-
-void ACPI_SYSTEM_XFACE
-acpi_db_method_thread (
-	void                            *context);
-
-acpi_status
-acpi_db_execution_walk (
-	acpi_handle                     obj_handle,
-	u32                             nesting_level,
-	void                            *context,
-	void                            **return_value);
-
 
 /*
  * dbfileio - Debugger file I/O commands
  */
-
 acpi_object_type
 acpi_db_match_argument (
 	char                            *user_argument,
 	struct argument_info            *arguments);
 
-acpi_status
-ae_local_load_table (
-	struct acpi_table_header        *table_ptr);
-
 void
 acpi_db_close_debug_file (
 	void);
@@ -356,16 +275,17 @@ acpi_db_read_table_from_file (
 	char                            *filename,
 	struct acpi_table_header        **table);
 
+
 /*
  * dbhistry - debugger HISTORY command
  */
-
 void
 acpi_db_add_to_history (
 	char                            *command_line);
 
 void
-acpi_db_display_history (void);
+acpi_db_display_history (
+	void);
 
 char *
 acpi_db_get_from_history (
@@ -375,7 +295,6 @@ acpi_db_get_from_history (
 /*
  * dbinput - user front-end to the AML debugger
  */
-
 acpi_status
 acpi_db_command_dispatch (
 	char                            *input_buffer,
@@ -386,71 +305,28 @@ void ACPI_SYSTEM_XFACE
 acpi_db_execute_thread (
 	void                            *context);
 
-void
-acpi_db_display_help (
-	char                            *help_type);
-
-char *
-acpi_db_get_next_token (
-	char                            *string,
-	char                            **next);
-
-u32
-acpi_db_get_line (
-	char                            *input_buffer);
-
-u32
-acpi_db_match_command (
-	char                            *user_command);
-
-void
-acpi_db_single_thread (
-	void);
-
 
 /*
  * dbstats - Generation and display of ACPI table statistics
  */
-
 void
 acpi_db_generate_statistics (
 	union acpi_parse_object         *root,
 	u8                              is_method);
 
-
 acpi_status
 acpi_db_display_statistics (
 	char                            *type_arg);
 
-acpi_status
-acpi_db_classify_one_object (
-	acpi_handle                     obj_handle,
-	u32                             nesting_level,
-	void                            *context,
-	void                            **return_value);
-
-void
-acpi_db_count_namespace_objects (
-	void);
-
-void
-acpi_db_enumerate_object (
-	union acpi_operand_object       *obj_desc);
-
 
 /*
  * dbutils - AML debugger utilities
  */
-
 void
 acpi_db_set_output_destination (
 	u32                             where);
 
 void
-acpi_db_dump_buffer (
-	u32                             address);
-
-void
 acpi_db_dump_object (
 	union acpi_object               *obj_desc,
 	u32                             level);
@@ -459,14 +335,8 @@ void
 acpi_db_prep_namestring (
 	char                            *name);
 
-
-acpi_status
-acpi_db_second_pass_parse (
-	union acpi_parse_object         *root);
-
 struct acpi_namespace_node *
 acpi_db_local_ns_lookup (
 	char                            *name);
 
-
 #endif  /* __ACDEBUG_H__ */
diff --git a/include/acpi/acdisasm.h b/include/acpi/acdisasm.h
--- a/include/acpi/acdisasm.h
+++ b/include/acpi/acdisasm.h
@@ -102,58 +102,16 @@ acpi_status (*asl_walk_callback) (
 /*
  * dmwalk
  */
-
-void
-acpi_dm_walk_parse_tree (
-	union acpi_parse_object         *op,
-	asl_walk_callback               descending_callback,
-	asl_walk_callback               ascending_callback,
-	void                            *context);
-
-acpi_status
-acpi_dm_descending_op (
-	union acpi_parse_object         *op,
-	u32                             level,
-	void                            *context);
-
-acpi_status
-acpi_dm_ascending_op (
-	union acpi_parse_object         *op,
-	u32                             level,
-	void                            *context);
-
-
-/*
- * dmopcode
- */
-
-void
-acpi_dm_validate_name (
-	char                            *name,
-	union acpi_parse_object         *op);
-
-u32
-acpi_dm_dump_name (
-	char                            *name);
-
-void
-acpi_dm_unicode (
-	union acpi_parse_object         *op);
-
 void
 acpi_dm_disassemble (
 	struct acpi_walk_state          *walk_state,
 	union acpi_parse_object         *origin,
 	u32                             num_opcodes);
 
-void
-acpi_dm_namestring (
-	char                            *name);
-
-void
-acpi_dm_display_path (
-	union acpi_parse_object         *op);
 
+/*
+ * dmopcode
+ */
 void
 acpi_dm_disassemble_one_op (
 	struct acpi_walk_state          *walk_state,
@@ -165,18 +123,9 @@ acpi_dm_decode_internal_object (
 	union acpi_operand_object       *obj_desc);
 
 u32
-acpi_dm_block_type (
-	union acpi_parse_object         *op);
-
-u32
 acpi_dm_list_type (
 	union acpi_parse_object         *op);
 
-acpi_status
-acpi_ps_display_object_pathname (
-	struct acpi_walk_state          *walk_state,
-	union acpi_parse_object         *op);
-
 void
 acpi_dm_method_flags (
 	union acpi_parse_object         *op);
@@ -197,10 +146,6 @@ void
 acpi_dm_match_op (
 	union acpi_parse_object         *op);
 
-void
-acpi_dm_match_keyword (
-	union acpi_parse_object         *op);
-
 u8
 acpi_dm_comma_if_list_member (
 	union acpi_parse_object         *op);
@@ -211,13 +156,25 @@ acpi_dm_comma_if_field_member (
 
 
 /*
- * dmobject
+ * dmnames
  */
+u32
+acpi_dm_dump_name (
+	char                            *name);
+
+acpi_status
+acpi_ps_display_object_pathname (
+	struct acpi_walk_state          *walk_state,
+	union acpi_parse_object         *op);
 
 void
-acpi_dm_decode_node (
-	struct acpi_namespace_node      *node);
+acpi_dm_namestring (
+	char                            *name);
+
 
+/*
+ * dmobject
+ */
 void
 acpi_dm_display_internal_object (
 	union acpi_operand_object       *obj_desc,
@@ -241,6 +198,16 @@ acpi_dm_dump_method_info (
 /*
  * dmbuffer
  */
+void
+acpi_dm_disasm_byte_list (
+	u32                             level,
+	u8                              *byte_data,
+	u32                             byte_count);
+
+void
+acpi_dm_byte_list (
+	struct acpi_op_walk_info        *info,
+	union acpi_parse_object         *op);
 
 void
 acpi_is_eisa_id (
@@ -262,18 +229,6 @@ acpi_dm_is_string_buffer (
 /*
  * dmresrc
  */
-
-void
-acpi_dm_disasm_byte_list (
-	u32                             level,
-	u8                              *byte_data,
-	u32                             byte_count);
-
-void
-acpi_dm_byte_list (
-	struct acpi_op_walk_info        *info,
-	union acpi_parse_object         *op);
-
 void
 acpi_dm_resource_descriptor (
 	struct acpi_op_walk_info        *info,
@@ -296,19 +251,10 @@ void
 acpi_dm_decode_attribute (
 	u8                              attribute);
 
+
 /*
  * dmresrcl
  */
-
-void
-acpi_dm_io_flags (
-		u8                          flags);
-
-void
-acpi_dm_memory_flags (
-	u8                              flags,
-	u8                              specific_flags);
-
 void
 acpi_dm_word_descriptor (
 	struct asl_word_address_desc    *resource,
@@ -373,7 +319,6 @@ acpi_dm_vendor_large_descriptor (
 /*
  * dmresrcs
  */
-
 void
 acpi_dm_irq_descriptor (
 	struct asl_irq_format_desc      *resource,
@@ -420,7 +365,6 @@ acpi_dm_vendor_small_descriptor (
 /*
  * dmutils
  */
-
 void
 acpi_dm_add_to_external_list (
 	char                            *path);
diff --git a/include/acpi/acdispat.h b/include/acpi/acdispat.h
--- a/include/acpi/acdispat.h
+++ b/include/acpi/acdispat.h
@@ -50,40 +50,9 @@
 #define NAMEOF_ARG_NTE      "__A0"
 
 
-/* Common interfaces */
-
-acpi_status
-acpi_ds_obj_stack_push (
-	void                            *object,
-	struct acpi_walk_state          *walk_state);
-
-acpi_status
-acpi_ds_obj_stack_pop (
-	u32                             pop_count,
-	struct acpi_walk_state          *walk_state);
-
-#ifdef ACPI_FUTURE_USAGE
-void *
-acpi_ds_obj_stack_get_value (
-	u32                             index,
-	struct acpi_walk_state          *walk_state);
-#endif
-
-acpi_status
-acpi_ds_obj_stack_pop_object (
-	union acpi_operand_object       **object,
-	struct acpi_walk_state          *walk_state);
-
-
-/* dsopcode - support for late evaluation */
-
-acpi_status
-acpi_ds_execute_arguments (
-	struct acpi_namespace_node      *node,
-	struct acpi_namespace_node      *scope_node,
-	u32                             aml_length,
-	u8                              *aml_start);
-
+/*
+ * dsopcode - support for late evaluation
+ */
 acpi_status
 acpi_ds_get_buffer_field_arguments (
 	union acpi_operand_object       *obj_desc);
@@ -101,15 +70,6 @@ acpi_ds_get_package_arguments (
 	union acpi_operand_object       *obj_desc);
 
 acpi_status
-acpi_ds_init_buffer_field (
-	u16                             aml_opcode,
-	union acpi_operand_object       *obj_desc,
-	union acpi_operand_object       *buffer_desc,
-	union acpi_operand_object       *offset_desc,
-	union acpi_operand_object       *length_desc,
-	union acpi_operand_object       *result_desc);
-
-acpi_status
 acpi_ds_eval_buffer_field_operands (
 	struct acpi_walk_state          *walk_state,
 	union acpi_parse_object         *op);
@@ -130,9 +90,9 @@ acpi_ds_initialize_region (
 	acpi_handle                     obj_handle);
 
 
-/* dsctrl - Parser/Interpreter interface, control stack routines */
-
-
+/*
+ * dsctrl - Parser/Interpreter interface, control stack routines
+ */
 acpi_status
 acpi_ds_exec_begin_control_op (
 	struct acpi_walk_state          *walk_state,
@@ -144,9 +104,9 @@ acpi_ds_exec_end_control_op (
 	union acpi_parse_object         *op);
 
 
-/* dsexec - Parser/Interpreter interface, method execution callbacks */
-
-
+/*
+ * dsexec - Parser/Interpreter interface, method execution callbacks
+ */
 acpi_status
 acpi_ds_get_predicate_value (
 	struct acpi_walk_state          *walk_state,
@@ -162,14 +122,9 @@ acpi_ds_exec_end_op (
 	struct acpi_walk_state          *state);
 
 
-/* dsfield - Parser/Interpreter interface for AML fields */
-
-acpi_status
-acpi_ds_get_field_names (
-	struct acpi_create_field_info   *info,
-	struct acpi_walk_state          *walk_state,
-	union acpi_parse_object         *arg);
-
+/*
+ * dsfield - Parser/Interpreter interface for AML fields
+ */
 acpi_status
 acpi_ds_create_field (
 	union acpi_parse_object         *op,
@@ -199,8 +154,9 @@ acpi_ds_init_field_objects (
 	struct acpi_walk_state          *walk_state);
 
 
-/* dsload - Parser/Interpreter interface, namespace load callbacks */
-
+/*
+ * dsload - Parser/Interpreter interface, namespace load callbacks
+ */
 acpi_status
 acpi_ds_load1_begin_op (
 	struct acpi_walk_state          *walk_state,
@@ -225,9 +181,9 @@ acpi_ds_init_callbacks (
 	u32                             pass_number);
 
 
-/* dsmthdat - method data (locals/args) */
-
-
+/*
+ * dsmthdat - method data (locals/args)
+ */
 acpi_status
 acpi_ds_store_object_to_local (
 	u16                             opcode,
@@ -250,14 +206,6 @@ u8
 acpi_ds_is_method_value (
 	union acpi_operand_object       *obj_desc);
 
-#ifdef ACPI_FUTURE_USAGE
-acpi_object_type
-acpi_ds_method_data_get_type (
-	u16                             opcode,
-	u32                             index,
-	struct acpi_walk_state          *walk_state);
-#endif
-
 acpi_status
 acpi_ds_method_data_get_value (
 	u16                             opcode,
@@ -265,12 +213,6 @@ acpi_ds_method_data_get_value (
 	struct acpi_walk_state          *walk_state,
 	union acpi_operand_object       **dest_desc);
 
-void
-acpi_ds_method_data_delete_value (
-	u16                             opcode,
-	u32                             index,
-	struct acpi_walk_state          *walk_state);
-
 acpi_status
 acpi_ds_method_data_init_args (
 	union acpi_operand_object       **params,
@@ -288,16 +230,10 @@ void
 acpi_ds_method_data_init (
 	struct acpi_walk_state          *walk_state);
 
-acpi_status
-acpi_ds_method_data_set_value (
-	u16                             opcode,
-	u32                             index,
-	union acpi_operand_object       *object,
-	struct acpi_walk_state          *walk_state);
-
-
-/* dsmethod - Parser/Interpreter interface - control method parsing */
 
+/*
+ * dsmethod - Parser/Interpreter interface - control method parsing
+ */
 acpi_status
 acpi_ds_parse_method (
 	acpi_handle                     obj_handle);
@@ -324,20 +260,18 @@ acpi_ds_begin_method_execution (
 	struct acpi_namespace_node      *calling_method_node);
 
 
-/* dsobj - Parser/Interpreter interface - object initialization and conversion */
-
-acpi_status
-acpi_ds_init_one_object (
-	acpi_handle                     obj_handle,
-	u32                             level,
-	void                            *context,
-	void                            **return_value);
-
+/*
+ * dsinit
+ */
 acpi_status
 acpi_ds_initialize_objects (
 	struct acpi_table_desc          *table_desc,
 	struct acpi_namespace_node      *start_node);
 
+
+/*
+ * dsobject - Parser/Interpreter interface - object initialization and conversion
+ */
 acpi_status
 acpi_ds_build_internal_buffer_obj (
 	struct acpi_walk_state          *walk_state,
@@ -353,12 +287,6 @@ acpi_ds_build_internal_package_obj (
 	union acpi_operand_object       **obj_desc);
 
 acpi_status
-acpi_ds_build_internal_object (
-	struct acpi_walk_state          *walk_state,
-	union acpi_parse_object         *op,
-	union acpi_operand_object       **obj_desc_ptr);
-
-acpi_status
 acpi_ds_init_object_from_op (
 	struct acpi_walk_state          *walk_state,
 	union acpi_parse_object         *op,
@@ -372,8 +300,9 @@ acpi_ds_create_node (
 	union acpi_parse_object         *op);
 
 
-/* dsutils - Parser/Interpreter interface utility routines */
-
+/*
+ * dsutils - Parser/Interpreter interface utility routines
+ */
 void
 acpi_ds_clear_implicit_return (
 	struct acpi_walk_state          *walk_state);
@@ -418,7 +347,6 @@ acpi_ds_clear_operands (
 /*
  * dswscope - Scope Stack manipulation
  */
-
 acpi_status
 acpi_ds_scope_stack_push (
 	struct acpi_namespace_node      *node,
@@ -435,7 +363,18 @@ acpi_ds_scope_stack_clear (
 	struct acpi_walk_state          *walk_state);
 
 
-/* dswstate - parser WALK_STATE management routines */
+/*
+ * dswstate - parser WALK_STATE management routines
+ */
+acpi_status
+acpi_ds_obj_stack_push (
+	void                            *object,
+	struct acpi_walk_state          *walk_state);
+
+acpi_status
+acpi_ds_obj_stack_pop (
+	u32                             pop_count,
+	struct acpi_walk_state          *walk_state);
 
 struct acpi_walk_state *
 acpi_ds_create_walk_state (
@@ -454,12 +393,6 @@ acpi_ds_init_aml_walk (
 	struct acpi_parameter_info      *info,
 	u32                             pass_number);
 
-#ifdef ACPI_FUTURE_USAGE
-acpi_status
-acpi_ds_obj_stack_delete_all (
-	struct acpi_walk_state          *walk_state);
-#endif
-
 acpi_status
 acpi_ds_obj_stack_pop_and_delete (
 	u32                             pop_count,
@@ -494,20 +427,8 @@ struct acpi_walk_state *
 acpi_ds_get_current_walk_state (
 	struct acpi_thread_state        *thread);
 
-#ifdef ACPI_ENABLE_OBJECT_CACHE
-void
-acpi_ds_delete_walk_state_cache (
-	void);
-#endif
-
 #ifdef ACPI_FUTURE_USAGE
 acpi_status
-acpi_ds_result_insert (
-	void                            *object,
-	u32                             index,
-	struct acpi_walk_state          *walk_state);
-
-acpi_status
 acpi_ds_result_remove (
 	union acpi_operand_object       **object,
 	u32                             index,
@@ -529,4 +450,10 @@ acpi_ds_result_pop_from_bottom (
 	union acpi_operand_object       **object,
 	struct acpi_walk_state          *walk_state);
 
+#ifdef ACPI_ENABLE_OBJECT_CACHE
+void
+acpi_ds_delete_walk_state_cache (
+	void);
+#endif
+
 #endif /* _ACDISPAT_H_ */
diff --git a/include/acpi/acevents.h b/include/acpi/acevents.h
--- a/include/acpi/acevents.h
+++ b/include/acpi/acevents.h
@@ -45,6 +45,9 @@
 #define __ACEVENTS_H__
 
 
+/*
+ * evevent
+ */
 acpi_status
 acpi_ev_initialize_events (
 	void);
@@ -53,28 +56,14 @@ acpi_status
 acpi_ev_install_xrupt_handlers (
 	void);
 
-
-/*
- * Evfixed - Fixed event handling
- */
-
-acpi_status
-acpi_ev_fixed_event_initialize (
-	void);
-
 u32
 acpi_ev_fixed_event_detect (
 	void);
 
-u32
-acpi_ev_fixed_event_dispatch (
-	u32                             event);
-
 
 /*
- * Evmisc
+ * evmisc
  */
-
 u8
 acpi_ev_is_notify_object (
 	struct acpi_namespace_node      *node);
@@ -100,24 +89,10 @@ acpi_ev_queue_notify_request (
 	struct acpi_namespace_node      *node,
 	u32                             notify_value);
 
-void ACPI_SYSTEM_XFACE
-acpi_ev_notify_dispatch (
-	void                            *context);
-
 
 /*
- * Evgpe - GPE handling and dispatch
+ * evgpe - GPE handling and dispatch
  */
-
-acpi_status
-acpi_ev_walk_gpe_list (
-	ACPI_GPE_CALLBACK       gpe_walk_callback,
-	u32                             flags);
-
-u8
-acpi_ev_valid_gpe_event (
-	struct acpi_gpe_event_info      *gpe_event_info);
-
 acpi_status
 acpi_ev_update_gpe_enable_masks (
 	struct acpi_gpe_event_info      *gpe_event_info,
@@ -137,9 +112,23 @@ acpi_ev_get_gpe_event_info (
 	acpi_handle                     gpe_device,
 	u32                             gpe_number);
 
+
+/*
+ * evgpeblk
+ */
+u8
+acpi_ev_valid_gpe_event (
+	struct acpi_gpe_event_info      *gpe_event_info);
+
 acpi_status
-acpi_ev_gpe_initialize (
-	void);
+acpi_ev_walk_gpe_list (
+	ACPI_GPE_CALLBACK       gpe_walk_callback,
+	u32                             flags);
+
+acpi_status
+acpi_ev_delete_gpe_handlers (
+	struct acpi_gpe_xrupt_info      *gpe_xrupt_info,
+	struct acpi_gpe_block_info      *gpe_block);
 
 acpi_status
 acpi_ev_create_gpe_block (
@@ -154,11 +143,6 @@ acpi_status
 acpi_ev_delete_gpe_block (
 	struct acpi_gpe_block_info      *gpe_block);
 
-acpi_status
-acpi_ev_delete_gpe_handlers (
-	struct acpi_gpe_xrupt_info      *gpe_xrupt_info,
-	struct acpi_gpe_block_info      *gpe_block);
-
 u32
 acpi_ev_gpe_dispatch (
 	struct acpi_gpe_event_info      *gpe_event_info,
@@ -177,10 +161,14 @@ acpi_status
 acpi_ev_check_for_wake_only_gpe (
 	struct acpi_gpe_event_info      *gpe_event_info);
 
+acpi_status
+acpi_ev_gpe_initialize (
+	void);
+
+
 /*
- * Evregion - Address Space handling
+ * evregion - Address Space handling
  */
-
 acpi_status
 acpi_ev_install_region_handlers (
 	void);
@@ -198,13 +186,6 @@ acpi_ev_address_space_dispatch (
 	void                            *value);
 
 acpi_status
-acpi_ev_install_handler (
-	acpi_handle                     obj_handle,
-	u32                             level,
-	void                            *context,
-	void                            **return_value);
-
-acpi_status
 acpi_ev_attach_region (
 	union acpi_operand_object       *handler_obj,
 	union acpi_operand_object       *region_obj,
@@ -233,17 +214,10 @@ acpi_ev_execute_reg_method (
 	union acpi_operand_object      *region_obj,
 	u32                             function);
 
-acpi_status
-acpi_ev_reg_run (
-	acpi_handle                     obj_handle,
-	u32                             level,
-	void                            *context,
-	void                            **return_value);
 
 /*
- * Evregini - Region initialization and setup
+ * evregini - Region initialization and setup
  */
-
 acpi_status
 acpi_ev_system_memory_region_setup (
 	acpi_handle                     handle,
@@ -293,9 +267,8 @@ acpi_ev_initialize_region (
 
 
 /*
- * Evsci - SCI (System Control Interrupt) handling/dispatch
+ * evsci - SCI (System Control Interrupt) handling/dispatch
  */
-
 u32 ACPI_SYSTEM_XFACE
 acpi_ev_gpe_xrupt_handler (
 	void                            *context);
diff --git a/include/acpi/acexcep.h b/include/acpi/acexcep.h
--- a/include/acpi/acexcep.h
+++ b/include/acpi/acexcep.h
@@ -48,7 +48,6 @@
 /*
  * Exceptions returned by external ACPI interfaces
  */
-
 #define AE_CODE_ENVIRONMENTAL           0x0000
 #define AE_CODE_PROGRAMMER              0x1000
 #define AE_CODE_ACPI_TABLES             0x2000
@@ -99,6 +98,7 @@
 
 #define AE_CODE_ENV_MAX                 0x001E
 
+
 /*
  * Programmer exceptions
  */
@@ -168,6 +168,7 @@
 
 #define AE_CODE_AML_MAX                 0x0021
 
+
 /*
  * Internal exceptions used for control
  */
@@ -188,6 +189,7 @@
 
 #ifdef DEFINE_ACPI_GLOBALS
 
+
 /*
  * String versions of the exception codes above
  * These strings must match the corresponding defines exactly
@@ -304,5 +306,4 @@ char const   *acpi_gbl_exception_names_c
 
 #endif /* ACPI GLOBALS */
 
-
 #endif /* __ACEXCEP_H__ */
diff --git a/include/acpi/acglobal.h b/include/acpi/acglobal.h
--- a/include/acpi/acglobal.h
+++ b/include/acpi/acglobal.h
@@ -146,15 +146,15 @@ ACPI_EXTERN struct acpi_table_header    
 ACPI_EXTERN FACS_DESCRIPTOR            *acpi_gbl_FACS;
 ACPI_EXTERN struct acpi_common_facs             acpi_gbl_common_fACS;
 /*
- * Since there may be multiple SSDTs and PSDTS, a single pointer is not
+ * Since there may be multiple SSDTs and PSDTs, a single pointer is not
  * sufficient; Therefore, there isn't one!
  */
 
 
 /*
- * Handle both ACPI 1.0 and ACPI 2.0 Integer widths
- * If we are running a method that exists in a 32-bit ACPI table.
- * Use only 32 bits of the Integer for conversion.
+ * Handle both ACPI 1.0 and ACPI 2.0 Integer widths:
+ * If we are executing a method that exists in a 32-bit ACPI table,
+ * use only the lower 32 bits of the (internal) 64-bit Integer.
  */
 ACPI_EXTERN u8                                  acpi_gbl_integer_bit_width;
 ACPI_EXTERN u8                                  acpi_gbl_integer_byte_width;
@@ -246,6 +246,7 @@ ACPI_EXTERN acpi_size                   
 ACPI_EXTERN u32                                 acpi_gbl_deepest_nesting;
 #endif
 
+
 /*****************************************************************************
  *
  * Interpreter globals
@@ -268,6 +269,7 @@ ACPI_EXTERN u8                          
 
 ACPI_EXTERN union acpi_parse_object            *acpi_gbl_parsed_namespace_root;
 
+
 /*****************************************************************************
  *
  * Hardware globals
@@ -298,7 +300,6 @@ ACPI_EXTERN acpi_handle                 
  *
  ****************************************************************************/
 
-
 ACPI_EXTERN u8                                  acpi_gbl_db_output_flags;
 
 #ifdef ACPI_DISASSEMBLER
@@ -353,5 +354,4 @@ ACPI_EXTERN u32                         
 
 #endif /* ACPI_DEBUGGER */
 
-
 #endif /* __ACGLOBAL_H__ */
diff --git a/include/acpi/achware.h b/include/acpi/achware.h
--- a/include/acpi/achware.h
+++ b/include/acpi/achware.h
@@ -46,22 +46,26 @@
 
 
 /* PM Timer ticks per second (HZ) */
+
 #define PM_TIMER_FREQUENCY  3579545
 
+/* Values for the _SST reserved method */
 
-/* Prototypes */
+#define ACPI_SST_INDICATOR_OFF  0
+#define ACPI_SST_WORKING        1
+#define ACPI_SST_WAKING         2
+#define ACPI_SST_SLEEPING       3
+#define ACPI_SST_SLEEP_CONTEXT  4
 
 
-acpi_status
-acpi_hw_initialize (
-	void);
+/* Prototypes */
 
-acpi_status
-acpi_hw_shutdown (
-	void);
 
+/*
+ * hwacpi - high level functions
+ */
 acpi_status
-acpi_hw_initialize_system_info (
+acpi_hw_initialize (
 	void);
 
 acpi_status
@@ -72,12 +76,10 @@ u32
 acpi_hw_get_mode (
 	void);
 
-u32
-acpi_hw_get_mode_capabilities (
-	void);
-
-/* Register I/O Prototypes */
 
+/*
+ * hwregs - ACPI Register I/O
+ */
 struct acpi_bit_register_info *
 acpi_hw_get_bit_register_info (
 	u32                             register_id);
@@ -111,8 +113,9 @@ acpi_hw_clear_acpi_status (
 	u32                             flags);
 
 
-/* GPE support */
-
+/*
+ * hwgpe - GPE support
+ */
 acpi_status
 acpi_hw_write_gpe_enable_reg (
 	struct acpi_gpe_event_info      *gpe_event_info);
@@ -131,12 +134,12 @@ acpi_hw_clear_gpe_block (
 	struct acpi_gpe_xrupt_info      *gpe_xrupt_info,
 	struct acpi_gpe_block_info      *gpe_block);
 
-#ifdef ACPI_FUTURE_USAGE
+#ifdef	ACPI_FUTURE_USAGE
 acpi_status
 acpi_hw_get_gpe_status (
 	struct acpi_gpe_event_info      *gpe_event_info,
 	acpi_event_status               *event_status);
-#endif
+#endif	/* ACPI_FUTURE_USAGE */
 
 acpi_status
 acpi_hw_disable_all_gpes (
@@ -155,15 +158,11 @@ acpi_hw_enable_runtime_gpe_block (
 	struct acpi_gpe_xrupt_info      *gpe_xrupt_info,
 	struct acpi_gpe_block_info      *gpe_block);
 
-acpi_status
-acpi_hw_enable_wakeup_gpe_block (
-	struct acpi_gpe_xrupt_info      *gpe_xrupt_info,
-	struct acpi_gpe_block_info      *gpe_block);
-
 
-/* ACPI Timer prototypes */
-
-#ifdef ACPI_FUTURE_USAGE
+#ifdef	ACPI_FUTURE_USAGE
+/*
+ * hwtimer - ACPI Timer prototypes
+ */
 acpi_status
 acpi_get_timer_resolution (
 	u32                             *resolution);
@@ -177,6 +176,7 @@ acpi_get_timer_duration (
 	u32                             start_ticks,
 	u32                             end_ticks,
 	u32                             *time_elapsed);
-#endif  /*  ACPI_FUTURE_USAGE  */
+#endif	/* ACPI_FUTURE_USAGE */
+
 
 #endif /* __ACHWARE_H__ */
diff --git a/include/acpi/acinterp.h b/include/acpi/acinterp.h
--- a/include/acpi/acinterp.h
+++ b/include/acpi/acinterp.h
@@ -48,37 +48,9 @@
 #define ACPI_WALK_OPERANDS       (&(walk_state->operands [walk_state->num_operands -1]))
 
 
-acpi_status
-acpi_ex_resolve_operands (
-	u16                             opcode,
-	union acpi_operand_object       **stack_ptr,
-	struct acpi_walk_state          *walk_state);
-
-acpi_status
-acpi_ex_check_object_type (
-	acpi_object_type                type_needed,
-	acpi_object_type                this_type,
-	void                            *object);
-
-/*
- * exxface - External interpreter interfaces
- */
-
-acpi_status
-acpi_ex_load_table (
-	acpi_table_type                 table_id);
-
-acpi_status
-acpi_ex_execute_method (
-	struct acpi_namespace_node      *method_node,
-	union acpi_operand_object       **params,
-	union acpi_operand_object       **return_obj_desc);
-
-
 /*
  * exconvrt - object conversion
  */
-
 acpi_status
 acpi_ex_convert_to_integer (
 	union acpi_operand_object       *obj_desc,
@@ -110,17 +82,10 @@ acpi_ex_convert_to_target_type (
 	union acpi_operand_object       **result_desc,
 	struct acpi_walk_state          *walk_state);
 
-u32
-acpi_ex_convert_to_ascii (
-	acpi_integer                    integer,
-	u16                             base,
-	u8                              *string,
-	u8                              max_length);
 
 /*
  * exfield - ACPI AML (p-code) execution - field manipulation
  */
-
 acpi_status
 acpi_ex_common_buffer_setup (
 	union acpi_operand_object       *obj_desc,
@@ -128,42 +93,6 @@ acpi_ex_common_buffer_setup (
 	u32                             *datum_count);
 
 acpi_status
-acpi_ex_extract_from_field (
-	union acpi_operand_object       *obj_desc,
-	void                            *buffer,
-	u32                             buffer_length);
-
-acpi_status
-acpi_ex_insert_into_field (
-	union acpi_operand_object       *obj_desc,
-	void                            *buffer,
-	u32                             buffer_length);
-
-acpi_status
-acpi_ex_setup_region (
-	union acpi_operand_object       *obj_desc,
-	u32                             field_datum_byte_offset);
-
-acpi_status
-acpi_ex_access_region (
-	union acpi_operand_object       *obj_desc,
-	u32                             field_datum_byte_offset,
-	acpi_integer                    *value,
-	u32                             read_write);
-
-u8
-acpi_ex_register_overflow (
-	union acpi_operand_object       *obj_desc,
-	acpi_integer                    value);
-
-acpi_status
-acpi_ex_field_datum_io (
-	union acpi_operand_object       *obj_desc,
-	u32                             field_datum_byte_offset,
-	acpi_integer                    *value,
-	u32                             read_write);
-
-acpi_status
 acpi_ex_write_with_update_rule (
 	union acpi_operand_object       *obj_desc,
 	acpi_integer                    mask,
@@ -198,28 +127,33 @@ acpi_ex_write_data_to_field (
 	union acpi_operand_object       *obj_desc,
 	union acpi_operand_object       **result_desc);
 
+
 /*
- * exmisc - ACPI AML (p-code) execution - specific opcodes
+ * exfldio - low level field I/O
  */
-
 acpi_status
-acpi_ex_opcode_3A_0T_0R (
-	struct acpi_walk_state          *walk_state);
+acpi_ex_extract_from_field (
+	union acpi_operand_object       *obj_desc,
+	void                            *buffer,
+	u32                             buffer_length);
 
 acpi_status
-acpi_ex_opcode_3A_1T_1R (
-	struct acpi_walk_state          *walk_state);
+acpi_ex_insert_into_field (
+	union acpi_operand_object       *obj_desc,
+	void                            *buffer,
+	u32                             buffer_length);
 
 acpi_status
-acpi_ex_opcode_6A_0T_1R (
-	struct acpi_walk_state          *walk_state);
+acpi_ex_access_region (
+	union acpi_operand_object       *obj_desc,
+	u32                             field_datum_byte_offset,
+	acpi_integer                    *value,
+	u32                             read_write);
 
-u8
-acpi_ex_do_match (
-	u32                             match_op,
-	union acpi_operand_object       *package_obj,
-	union acpi_operand_object       *match_obj);
 
+/*
+ * exmisc - misc support routines
+ */
 acpi_status
 acpi_ex_get_object_reference (
 	union acpi_operand_object       *obj_desc,
@@ -227,13 +161,6 @@ acpi_ex_get_object_reference (
 	struct acpi_walk_state          *walk_state);
 
 acpi_status
-acpi_ex_resolve_multiple (
-	struct acpi_walk_state          *walk_state,
-	union acpi_operand_object       *operand,
-	acpi_object_type                *return_type,
-	union acpi_operand_object       **return_desc);
-
-acpi_status
 acpi_ex_concat_template (
 	union acpi_operand_object       *obj_desc,
 	union acpi_operand_object       *obj_desc2,
@@ -308,13 +235,6 @@ acpi_ex_create_method (
 /*
  * exconfig - dynamic table load/unload
  */
-
-acpi_status
-acpi_ex_add_table (
-	struct acpi_table_header        *table,
-	struct acpi_namespace_node      *parent_node,
-	union acpi_operand_object       **ddb_handle);
-
 acpi_status
 acpi_ex_load_op (
 	union acpi_operand_object       *obj_desc,
@@ -334,7 +254,6 @@ acpi_ex_unload_table (
 /*
  * exmutex - mutex support
  */
-
 acpi_status
 acpi_ex_acquire_mutex (
 	union acpi_operand_object       *time_desc,
@@ -354,15 +273,10 @@ void
 acpi_ex_unlink_mutex (
 	union acpi_operand_object       *obj_desc);
 
-void
-acpi_ex_link_mutex (
-	union acpi_operand_object       *obj_desc,
-	struct acpi_thread_state        *thread);
 
 /*
- * exprep - ACPI AML (p-code) execution - prep utilities
+ * exprep - ACPI AML execution - prep utilities
  */
-
 acpi_status
 acpi_ex_prep_common_field_object (
 	union acpi_operand_object       *obj_desc,
@@ -375,10 +289,10 @@ acpi_status
 acpi_ex_prep_field_value (
 	struct acpi_create_field_info   *info);
 
+
 /*
  * exsystem - Interface to OS services
  */
-
 acpi_status
 acpi_ex_system_do_notify_op (
 	union acpi_operand_object       *value,
@@ -421,9 +335,8 @@ acpi_ex_system_wait_semaphore (
 
 
 /*
- * exmonadic - ACPI AML (p-code) execution, monadic operators
+ * exoparg1 - ACPI AML execution, 1 operand
  */
-
 acpi_status
 acpi_ex_opcode_0A_0T_1R (
 	struct acpi_walk_state          *walk_state);
@@ -445,9 +358,8 @@ acpi_ex_opcode_1A_1T_0R (
 	struct acpi_walk_state          *walk_state);
 
 /*
- * exdyadic - ACPI AML (p-code) execution, dyadic operators
+ * exoparg2 - ACPI AML execution, 2 operands
  */
-
 acpi_status
 acpi_ex_opcode_2A_0T_0R (
 	struct acpi_walk_state          *walk_state);
@@ -466,21 +378,56 @@ acpi_ex_opcode_2A_2T_1R (
 
 
 /*
- * exresolv  - Object resolution and get value functions
+ * exoparg3 - ACPI AML execution, 3 operands
+ */
+acpi_status
+acpi_ex_opcode_3A_0T_0R (
+	struct acpi_walk_state          *walk_state);
+
+acpi_status
+acpi_ex_opcode_3A_1T_1R (
+	struct acpi_walk_state          *walk_state);
+
+
+/*
+ * exoparg6 - ACPI AML execution, 6 operands
  */
+acpi_status
+acpi_ex_opcode_6A_0T_1R (
+	struct acpi_walk_state          *walk_state);
+
 
+/*
+ * exresolv - Object resolution and get value functions
+ */
 acpi_status
 acpi_ex_resolve_to_value (
 	union acpi_operand_object       **stack_ptr,
 	struct acpi_walk_state          *walk_state);
 
 acpi_status
+acpi_ex_resolve_multiple (
+	struct acpi_walk_state          *walk_state,
+	union acpi_operand_object       *operand,
+	acpi_object_type                *return_type,
+	union acpi_operand_object       **return_desc);
+
+
+/*
+ * exresnte - resolve namespace node
+ */
+acpi_status
 acpi_ex_resolve_node_to_value (
 	struct acpi_namespace_node      **stack_ptr,
 	struct acpi_walk_state          *walk_state);
 
+
+/*
+ * exresop - resolve operand to value
+ */
 acpi_status
-acpi_ex_resolve_object_to_value (
+acpi_ex_resolve_operands (
+	u16                             opcode,
 	union acpi_operand_object       **stack_ptr,
 	struct acpi_walk_state          *walk_state);
 
@@ -488,7 +435,6 @@ acpi_ex_resolve_object_to_value (
 /*
  * exdump - Interpreter debug output routines
  */
-
 void
 acpi_ex_dump_operand (
 	union acpi_operand_object       *obj_desc,
@@ -504,7 +450,7 @@ acpi_ex_dump_operands (
 	char                            *module_name,
 	u32                             line_number);
 
-#ifdef ACPI_FUTURE_USAGE
+#ifdef	ACPI_FUTURE_USAGE
 void
 acpi_ex_dump_object_descriptor (
 	union acpi_operand_object       *object,
@@ -514,46 +460,12 @@ void
 acpi_ex_dump_node (
 	struct acpi_namespace_node      *node,
 	u32                             flags);
+#endif	/* ACPI_FUTURE_USAGE */
 
-void
-acpi_ex_out_string (
-	char                            *title,
-	char                            *value);
-
-void
-acpi_ex_out_pointer (
-	char                            *title,
-	void                            *value);
-
-void
-acpi_ex_out_integer (
-	char                            *title,
-	u32                             value);
-
-void
-acpi_ex_out_address (
-	char                            *title,
-	acpi_physical_address           value);
-#endif  /*  ACPI_FUTURE_USAGE  */
 
 /*
- * exnames - interpreter/scanner name load/execute
+ * exnames - AML namestring support
  */
-
-char *
-acpi_ex_allocate_name_string (
-	u32                             prefix_count,
-	u32                             num_name_segs);
-
-u32
-acpi_ex_good_char (
-	u32                             character);
-
-acpi_status
-acpi_ex_name_segment (
-	u8                              **in_aml_address,
-	char                            *name_string);
-
 acpi_status
 acpi_ex_get_name_string (
 	acpi_object_type                data_type,
@@ -561,16 +473,10 @@ acpi_ex_get_name_string (
 	char                            **out_name_string,
 	u32                             *out_name_length);
 
-acpi_status
-acpi_ex_do_name (
-	acpi_object_type                data_type,
-	acpi_interpreter_mode           load_exec_mode);
-
 
 /*
  * exstore - Object store support
  */
-
 acpi_status
 acpi_ex_store (
 	union acpi_operand_object       *val_desc,
@@ -578,12 +484,6 @@ acpi_ex_store (
 	struct acpi_walk_state          *walk_state);
 
 acpi_status
-acpi_ex_store_object_to_index (
-	union acpi_operand_object       *val_desc,
-	union acpi_operand_object       *dest_desc,
-	struct acpi_walk_state          *walk_state);
-
-acpi_status
 acpi_ex_store_object_to_node (
 	union acpi_operand_object       *source_desc,
 	struct acpi_namespace_node      *node,
@@ -593,10 +493,10 @@ acpi_ex_store_object_to_node (
 #define ACPI_IMPLICIT_CONVERSION        TRUE
 #define ACPI_NO_IMPLICIT_CONVERSION     FALSE
 
+
 /*
- * exstoren
+ * exstoren - resolve/store object
  */
-
 acpi_status
 acpi_ex_resolve_object (
 	union acpi_operand_object       **source_desc_ptr,
@@ -612,9 +512,8 @@ acpi_ex_store_object_to_object (
 
 
 /*
- * excopy - object copy
+ * exstorob - store object - buffer/string
  */
-
 acpi_status
 acpi_ex_store_buffer_to_buffer (
 	union acpi_operand_object       *source_desc,
@@ -625,6 +524,10 @@ acpi_ex_store_string_to_string (
 	union acpi_operand_object       *source_desc,
 	union acpi_operand_object       *target_desc);
 
+
+/*
+ * excopy - object copy
+ */
 acpi_status
 acpi_ex_copy_integer_to_index_field (
 	union acpi_operand_object       *source_desc,
@@ -645,10 +548,10 @@ acpi_ex_copy_integer_to_buffer_field (
 	union acpi_operand_object       *source_desc,
 	union acpi_operand_object       *target_desc);
 
+
 /*
  * exutils - interpreter/scanner utilities
  */
-
 acpi_status
 acpi_ex_enter_interpreter (
 	void);
@@ -669,11 +572,6 @@ void
 acpi_ex_release_global_lock (
 	u8                              locked);
 
-u32
-acpi_ex_digits_needed (
-	acpi_integer                    value,
-	u32                             base);
-
 void
 acpi_ex_eisa_id_to_string (
 	u32                             numeric_id,
@@ -688,7 +586,6 @@ acpi_ex_unsigned_integer_to_string (
 /*
  * exregion - default op_region handlers
  */
-
 acpi_status
 acpi_ex_system_memory_space_handler (
 	u32                             function,
diff --git a/include/acpi/aclocal.h b/include/acpi/aclocal.h
--- a/include/acpi/aclocal.h
+++ b/include/acpi/aclocal.h
@@ -72,7 +72,6 @@ typedef u32                             
  *
  * NOTE: any changes here must be reflected in the acpi_gbl_mutex_names table also!
  */
-
 #define ACPI_MTX_EXECUTE                0
 #define ACPI_MTX_INTERPRETER            1
 #define ACPI_MTX_PARSER                 2
@@ -151,13 +150,13 @@ typedef u16                             
 #define ACPI_FIELD_DWORD_GRANULARITY    4
 #define ACPI_FIELD_QWORD_GRANULARITY    8
 
+
 /*****************************************************************************
  *
  * Namespace typedefs and structs
  *
  ****************************************************************************/
 
-
 /* Operational modes of the AML interpreter/scanner */
 
 typedef enum
@@ -176,7 +175,6 @@ typedef enum
  * data_type is used to differentiate between internal descriptors, and MUST
  * be the first byte in this structure.
  */
-
 union acpi_name_union
 {
 	u32                                 integer;
@@ -415,7 +413,6 @@ struct acpi_field_info
  *
  ****************************************************************************/
 
-
 #define ACPI_CONTROL_NORMAL                  0xC0
 #define ACPI_CONTROL_CONDITIONAL_EXECUTING   0xC1
 #define ACPI_CONTROL_PREDICATE_EXECUTING     0xC2
@@ -424,6 +421,7 @@ struct acpi_field_info
 
 
 /* Forward declarations */
+
 struct acpi_walk_state        ;
 struct acpi_obj_mutex;
 union acpi_parse_object        ;
@@ -601,7 +599,6 @@ struct acpi_opcode_info
 	u8                                  type;           /* Opcode type */
 };
 
-
 union acpi_parse_value
 {
 	acpi_integer                        integer;        /* Integer constant (Up to 64 bits) */
@@ -613,7 +610,6 @@ union acpi_parse_value
 	union acpi_parse_object             *arg;           /* arguments and contained ops */
 };
 
-
 #define ACPI_PARSE_COMMON \
 	u8                                  data_type;      /* To differentiate various internal objs */\
 	u8                                  flags;          /* Type of Op */\
@@ -691,7 +687,6 @@ struct acpi_parse_obj_asl
 	char                                parse_op_name[12];
 };
 
-
 union acpi_parse_object
 {
 	struct acpi_parse_obj_common        common;
@@ -834,7 +829,6 @@ struct acpi_bit_register_info
  *
  ****************************************************************************/
 
-
 /* resource_type values */
 
 #define ACPI_RESOURCE_TYPE_MEMORY_RANGE         0
diff --git a/include/acpi/acmacros.h b/include/acpi/acmacros.h
--- a/include/acpi/acmacros.h
+++ b/include/acpi/acmacros.h
@@ -539,11 +539,6 @@
 
 
 #define ACPI_DUMP_ENTRY(a,b)            acpi_ns_dump_entry (a,b)
-
-#ifdef ACPI_FUTURE_USAGE
-#define ACPI_DUMP_TABLES(a,b)           acpi_ns_dump_tables(a,b)
-#endif
-
 #define ACPI_DUMP_PATHNAME(a,b,c,d)     acpi_ns_dump_pathname(a,b,c,d)
 #define ACPI_DUMP_RESOURCE_LIST(a)      acpi_rs_dump_resource_list(a)
 #define ACPI_DUMP_BUFFER(a,b)           acpi_ut_dump_buffer((u8 *)a,b,DB_BYTE_DISPLAY,_COMPONENT)
@@ -596,11 +591,6 @@
 #define ACPI_DUMP_STACK_ENTRY(a)
 #define ACPI_DUMP_OPERANDS(a,b,c,d,e)
 #define ACPI_DUMP_ENTRY(a,b)
-
-#ifdef ACPI_FUTURE_USAGE
-#define ACPI_DUMP_TABLES(a,b)
-#endif
-
 #define ACPI_DUMP_PATHNAME(a,b,c,d)
 #define ACPI_DUMP_RESOURCE_LIST(a)
 #define ACPI_DUMP_BUFFER(a,b)
diff --git a/include/acpi/acnames.h b/include/acpi/acnames.h
new file mode 100644
--- /dev/null
+++ b/include/acpi/acnames.h
@@ -0,0 +1,84 @@
+/******************************************************************************
+ *
+ * Name: acnames.h - Global names and strings
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#ifndef __ACNAMES_H__
+#define __ACNAMES_H__
+
+/* Method names - these methods can appear anywhere in the namespace */
+
+#define METHOD_NAME__HID        "_HID"
+#define METHOD_NAME__CID        "_CID"
+#define METHOD_NAME__UID        "_UID"
+#define METHOD_NAME__ADR        "_ADR"
+#define METHOD_NAME__INI        "_INI"
+#define METHOD_NAME__STA        "_STA"
+#define METHOD_NAME__REG        "_REG"
+#define METHOD_NAME__SEG        "_SEG"
+#define METHOD_NAME__BBN        "_BBN"
+#define METHOD_NAME__PRT        "_PRT"
+#define METHOD_NAME__CRS        "_CRS"
+#define METHOD_NAME__PRS        "_PRS"
+#define METHOD_NAME__PRW        "_PRW"
+#define METHOD_NAME__SRS        "_SRS"
+
+/* Method names - these methods must appear at the namespace root */
+
+#define METHOD_NAME__BFS        "\\_BFS"
+#define METHOD_NAME__GTS        "\\_GTS"
+#define METHOD_NAME__PTS        "\\_PTS"
+#define METHOD_NAME__SST        "\\_SI._SST"
+#define METHOD_NAME__WAK        "\\_WAK"
+
+/* Definitions of the predefined namespace names  */
+
+#define ACPI_UNKNOWN_NAME       (u32) 0x3F3F3F3F     /* Unknown name is  "????" */
+#define ACPI_ROOT_NAME          (u32) 0x5F5F5F5C     /* Root name is     "\___" */
+#define ACPI_SYS_BUS_NAME       (u32) 0x5F53425F     /* Sys bus name is  "_SB_" */
+
+#define ACPI_NS_ROOT_PATH       "\\"
+#define ACPI_NS_SYSTEM_BUS      "_SB_"
+
+
+#endif  /* __ACNAMES_H__  */
+
+
diff --git a/include/acpi/acnamesp.h b/include/acpi/acnamesp.h
--- a/include/acpi/acnamesp.h
+++ b/include/acpi/acnamesp.h
@@ -57,17 +57,6 @@
 #define ACPI_NS_NEWSCOPE            1   /* a definition of this type opens a name scope */
 #define ACPI_NS_LOCAL               2   /* suppress search of enclosing scopes */
 
-
-/* Definitions of the predefined namespace names  */
-
-#define ACPI_UNKNOWN_NAME           (u32) 0x3F3F3F3F     /* Unknown name is  "????" */
-#define ACPI_ROOT_NAME              (u32) 0x5F5F5F5C     /* Root name is     "\___" */
-#define ACPI_SYS_BUS_NAME           (u32) 0x5F53425F     /* Sys bus name is  "_SB_" */
-
-#define ACPI_NS_ROOT_PATH           "\\"
-#define ACPI_NS_SYSTEM_BUS          "_SB_"
-
-
 /* Flags for acpi_ns_lookup, acpi_ns_search_and_enter */
 
 #define ACPI_NS_NO_UPSEARCH         0
@@ -80,10 +69,9 @@
 #define ACPI_NS_WALK_NO_UNLOCK      FALSE
 
 
-acpi_status
-acpi_ns_load_namespace (
-	void);
-
+/*
+ * nsinit - Namespace initialization
+ */
 acpi_status
 acpi_ns_initialize_objects (
 	void);
@@ -93,23 +81,22 @@ acpi_ns_initialize_devices (
 	void);
 
 
-/* Namespace init - nsxfinit */
-
+/*
+ * nsload -  Namespace loading
+ */
 acpi_status
-acpi_ns_init_one_device (
-	acpi_handle                     obj_handle,
-	u32                             nesting_level,
-	void                            *context,
-	void                            **return_value);
+acpi_ns_load_namespace (
+	void);
 
 acpi_status
-acpi_ns_init_one_object (
-	acpi_handle                     obj_handle,
-	u32                             level,
-	void                            *context,
-	void                            **return_value);
+acpi_ns_load_table (
+	struct acpi_table_desc          *table_desc,
+	struct acpi_namespace_node      *node);
 
 
+/*
+ * nswalk - walk the namespace
+ */
 acpi_status
 acpi_ns_walk_namespace (
 	acpi_object_type                type,
@@ -126,37 +113,24 @@ acpi_ns_get_next_node (
 	struct acpi_namespace_node      *parent,
 	struct acpi_namespace_node      *child);
 
-void
-acpi_ns_delete_namespace_by_owner (
-	u16                             table_id);
-
-
-/* Namespace loading - nsload */
-
-acpi_status
-acpi_ns_one_complete_parse (
-	u32                             pass_number,
-	struct acpi_table_desc          *table_desc);
 
+/*
+ * nsparse - table parsing
+ */
 acpi_status
 acpi_ns_parse_table (
 	struct acpi_table_desc          *table_desc,
 	struct acpi_namespace_node      *scope);
 
 acpi_status
-acpi_ns_load_table (
-	struct acpi_table_desc          *table_desc,
-	struct acpi_namespace_node      *node);
-
-acpi_status
-acpi_ns_load_table_by_type (
-	acpi_table_type                 table_type);
+acpi_ns_one_complete_parse (
+	u32                             pass_number,
+	struct acpi_table_desc          *table_desc);
 
 
 /*
- * Top-level namespace access - nsaccess
+ * nsaccess - Top-level namespace access
  */
-
 acpi_status
 acpi_ns_root_initialize (
 	void);
@@ -173,9 +147,8 @@ acpi_ns_lookup (
 
 
 /*
- * Named object allocation/deallocation - nsalloc
+ * nsalloc - Named object allocation/deallocation
  */
-
 struct acpi_namespace_node *
 acpi_ns_create_node (
 	u32                             name);
@@ -189,6 +162,10 @@ acpi_ns_delete_namespace_subtree (
 	struct acpi_namespace_node      *parent_handle);
 
 void
+acpi_ns_delete_namespace_by_owner (
+	u16                             table_id);
+
+void
 acpi_ns_detach_object (
 	struct acpi_namespace_node      *node);
 
@@ -201,36 +178,16 @@ acpi_ns_compare_names (
 	char                            *name1,
 	char                            *name2);
 
-void
-acpi_ns_remove_reference (
-	struct acpi_namespace_node      *node);
-
 
 /*
- * Namespace modification - nsmodify
+ * nsdump - Namespace dump/print utilities
  */
-
-#ifdef ACPI_FUTURE_USAGE
-acpi_status
-acpi_ns_unload_namespace (
-	acpi_handle                     handle);
-
-acpi_status
-acpi_ns_delete_subtree (
-	acpi_handle                     start_handle);
-#endif
-
-
-/*
- * Namespace dump/print utilities - nsdump
- */
-
-#ifdef ACPI_FUTURE_USAGE
+#ifdef	ACPI_FUTURE_USAGE
 void
 acpi_ns_dump_tables (
 	acpi_handle                     search_base,
 	u32                             max_depth);
-#endif
+#endif	/* ACPI_FUTURE_USAGE */
 
 void
 acpi_ns_dump_entry (
@@ -249,19 +206,6 @@ acpi_ns_print_pathname (
 	u32                             num_segments,
 	char                            *pathname);
 
-#ifdef ACPI_FUTURE_USAGE
-acpi_status
-acpi_ns_dump_one_device (
-	acpi_handle                     obj_handle,
-	u32                             level,
-	void                            *context,
-	void                            **return_value);
-
-void
-acpi_ns_dump_root_devices (
-	void);
-#endif  /*  ACPI_FUTURE_USAGE  */
-
 acpi_status
 acpi_ns_dump_one_object (
 	acpi_handle                     obj_handle,
@@ -269,7 +213,7 @@ acpi_ns_dump_one_object (
 	void                            *context,
 	void                            **return_value);
 
-#ifdef ACPI_FUTURE_USAGE
+#ifdef	ACPI_FUTURE_USAGE
 void
 acpi_ns_dump_objects (
 	acpi_object_type                type,
@@ -277,13 +221,12 @@ acpi_ns_dump_objects (
 	u32                             max_depth,
 	u32                             ownder_id,
 	acpi_handle                     start_handle);
-#endif
+#endif	/* ACPI_FUTURE_USAGE */
 
 
 /*
- * Namespace evaluation functions - nseval
+ * nseval - Namespace evaluation functions
  */
-
 acpi_status
 acpi_ns_evaluate_by_handle (
 	struct acpi_parameter_info      *info);
@@ -298,40 +241,14 @@ acpi_ns_evaluate_relative (
 	char                            *pathname,
 	struct acpi_parameter_info      *info);
 
-acpi_status
-acpi_ns_execute_control_method (
-	struct acpi_parameter_info      *info);
-
-acpi_status
-acpi_ns_get_object_value (
-	struct acpi_parameter_info      *info);
-
-
-/*
- * Parent/Child/Peer utility functions
- */
-
-#ifdef ACPI_FUTURE_USAGE
-acpi_name
-acpi_ns_find_parent_name (
-	struct acpi_namespace_node      *node_to_search);
-#endif
-
 
 /*
- * Name and Scope manipulation - nsnames
+ * nsnames - Name and Scope manipulation
  */
-
 u32
 acpi_ns_opens_scope (
 	acpi_object_type                type);
 
-void
-acpi_ns_build_external_path (
-	struct acpi_namespace_node      *node,
-	acpi_size                       size,
-	char                            *name_buffer);
-
 char *
 acpi_ns_get_external_pathname (
 	struct acpi_namespace_node      *node);
@@ -363,9 +280,8 @@ acpi_ns_get_pathname_length (
 
 
 /*
- * Object management for namespace nodes - nsobject
+ * nsobject - Object management for namespace nodes
  */
-
 acpi_status
 acpi_ns_attach_object (
 	struct acpi_namespace_node      *node,
@@ -399,9 +315,8 @@ acpi_ns_get_attached_data (
 
 
 /*
- * Namespace searching and entry - nssearch
+ * nssearch - Namespace searching and entry
  */
-
 acpi_status
 acpi_ns_search_and_enter (
 	u32                             entry_name,
@@ -428,17 +343,12 @@ acpi_ns_install_node (
 
 
 /*
- * Utility functions - nsutils
+ * nsutils - Utility functions
  */
-
 u8
 acpi_ns_valid_root_prefix (
 	char                            prefix);
 
-u8
-acpi_ns_valid_path_separator (
-	char                            sep);
-
 acpi_object_type
 acpi_ns_get_type (
 	struct acpi_namespace_node      *node);
@@ -511,5 +421,4 @@ struct acpi_namespace_node *
 acpi_ns_get_next_valid_node (
 	struct acpi_namespace_node      *node);
 
-
 #endif /* __ACNAMESP_H__ */
diff --git a/include/acpi/acobject.h b/include/acpi/acobject.h
--- a/include/acpi/acobject.h
+++ b/include/acpi/acobject.h
@@ -133,6 +133,7 @@ struct acpi_object_integer
 	acpi_integer                            value;
 };
 
+
 /*
  * Note: The String and Buffer object must be identical through the Pointer
  * element.  There is code that depends on this.
@@ -468,7 +469,6 @@ union acpi_operand_object
  *
  *****************************************************************************/
 
-
 /* Object descriptor types */
 
 #define ACPI_DESC_TYPE_CACHED           0x01        /* Used only when object is cached */
diff --git a/include/acpi/acopcode.h b/include/acpi/acopcode.h
new file mode 100644
--- /dev/null
+++ b/include/acpi/acopcode.h
@@ -0,0 +1,325 @@
+/******************************************************************************
+ *
+ * Name: acopcode.h - AML opcode information for the AML parser and interpreter
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2005, R. Byron Moore
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#ifndef __ACOPCODE_H__
+#define __ACOPCODE_H__
+
+#define MAX_EXTENDED_OPCODE         0x88
+#define NUM_EXTENDED_OPCODE         (MAX_EXTENDED_OPCODE + 1)
+#define MAX_INTERNAL_OPCODE
+#define NUM_INTERNAL_OPCODE         (MAX_INTERNAL_OPCODE + 1)
+
+/* Used for non-assigned opcodes */
+
+#define _UNK                        0x6B
+
+/*
+ * Reserved ASCII characters.  Do not use any of these for
+ * internal opcodes, since they are used to differentiate
+ * name strings from AML opcodes
+ */
+#define _ASC                        0x6C
+#define _NAM                        0x6C
+#define _PFX                        0x6D
+
+
+/*
+ * All AML opcodes and the parse-time arguments for each.  Used by the AML
+ * parser  Each list is compressed into a 32-bit number and stored in the
+ * master opcode table (in psopcode.c).
+ */
+#define ARGP_ACCESSFIELD_OP             ARGP_LIST1 (ARGP_NAMESTRING)
+#define ARGP_ACQUIRE_OP                 ARGP_LIST2 (ARGP_SUPERNAME,  ARGP_WORDDATA)
+#define ARGP_ADD_OP                     ARGP_LIST3 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_TARGET)
+#define ARGP_ALIAS_OP                   ARGP_LIST2 (ARGP_NAMESTRING, ARGP_NAME)
+#define ARGP_ARG0                       ARG_NONE
+#define ARGP_ARG1                       ARG_NONE
+#define ARGP_ARG2                       ARG_NONE
+#define ARGP_ARG3                       ARG_NONE
+#define ARGP_ARG4                       ARG_NONE
+#define ARGP_ARG5                       ARG_NONE
+#define ARGP_ARG6                       ARG_NONE
+#define ARGP_BANK_FIELD_OP              ARGP_LIST6 (ARGP_PKGLENGTH,  ARGP_NAMESTRING,    ARGP_NAMESTRING,ARGP_TERMARG,   ARGP_BYTEDATA,  ARGP_FIELDLIST)
+#define ARGP_BIT_AND_OP                 ARGP_LIST3 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_TARGET)
+#define ARGP_BIT_NAND_OP                ARGP_LIST3 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_TARGET)
+#define ARGP_BIT_NOR_OP                 ARGP_LIST3 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_TARGET)
+#define ARGP_BIT_NOT_OP                 ARGP_LIST2 (ARGP_TERMARG,    ARGP_TARGET)
+#define ARGP_BIT_OR_OP                  ARGP_LIST3 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_TARGET)
+#define ARGP_BIT_XOR_OP                 ARGP_LIST3 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_TARGET)
+#define ARGP_BREAK_OP                   ARG_NONE
+#define ARGP_BREAK_POINT_OP             ARG_NONE
+#define ARGP_BUFFER_OP                  ARGP_LIST3 (ARGP_PKGLENGTH,  ARGP_TERMARG,       ARGP_BYTELIST)
+#define ARGP_BYTE_OP                    ARGP_LIST1 (ARGP_BYTEDATA)
+#define ARGP_BYTELIST_OP                ARGP_LIST1 (ARGP_NAMESTRING)
+#define ARGP_CONCAT_OP                  ARGP_LIST3 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_TARGET)
+#define ARGP_CONCAT_RES_OP              ARGP_LIST3 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_TARGET)
+#define ARGP_COND_REF_OF_OP             ARGP_LIST2 (ARGP_SUPERNAME,  ARGP_SUPERNAME)
+#define ARGP_CONTINUE_OP                ARG_NONE
+#define ARGP_COPY_OP                    ARGP_LIST2 (ARGP_SUPERNAME,  ARGP_SIMPLENAME)
+#define ARGP_CREATE_BIT_FIELD_OP        ARGP_LIST3 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_NAME)
+#define ARGP_CREATE_BYTE_FIELD_OP       ARGP_LIST3 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_NAME)
+#define ARGP_CREATE_DWORD_FIELD_OP      ARGP_LIST3 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_NAME)
+#define ARGP_CREATE_FIELD_OP            ARGP_LIST4 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_TERMARG,   ARGP_NAME)
+#define ARGP_CREATE_QWORD_FIELD_OP      ARGP_LIST3 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_NAME)
+#define ARGP_CREATE_WORD_FIELD_OP       ARGP_LIST3 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_NAME)
+#define ARGP_DATA_REGION_OP             ARGP_LIST4 (ARGP_NAME,       ARGP_TERMARG,       ARGP_TERMARG,   ARGP_TERMARG)
+#define ARGP_DEBUG_OP                   ARG_NONE
+#define ARGP_DECREMENT_OP               ARGP_LIST1 (ARGP_SUPERNAME)
+#define ARGP_DEREF_OF_OP                ARGP_LIST1 (ARGP_TERMARG)
+#define ARGP_DEVICE_OP                  ARGP_LIST3 (ARGP_PKGLENGTH,  ARGP_NAME,          ARGP_OBJLIST)
+#define ARGP_DIVIDE_OP                  ARGP_LIST4 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_TARGET,    ARGP_TARGET)
+#define ARGP_DWORD_OP                   ARGP_LIST1 (ARGP_DWORDDATA)
+#define ARGP_ELSE_OP                    ARGP_LIST2 (ARGP_PKGLENGTH,  ARGP_TERMLIST)
+#define ARGP_EVENT_OP                   ARGP_LIST1 (ARGP_NAME)
+#define ARGP_FATAL_OP                   ARGP_LIST3 (ARGP_BYTEDATA,   ARGP_DWORDDATA,     ARGP_TERMARG)
+#define ARGP_FIELD_OP                   ARGP_LIST4 (ARGP_PKGLENGTH,  ARGP_NAMESTRING,    ARGP_BYTEDATA,  ARGP_FIELDLIST)
+#define ARGP_FIND_SET_LEFT_BIT_OP       ARGP_LIST2 (ARGP_TERMARG,    ARGP_TARGET)
+#define ARGP_FIND_SET_RIGHT_BIT_OP      ARGP_LIST2 (ARGP_TERMARG,    ARGP_TARGET)
+#define ARGP_FROM_BCD_OP                ARGP_LIST2 (ARGP_TERMARG,    ARGP_TARGET)
+#define ARGP_IF_OP                      ARGP_LIST3 (ARGP_PKGLENGTH,  ARGP_TERMARG,       ARGP_TERMLIST)
+#define ARGP_INCREMENT_OP               ARGP_LIST1 (ARGP_SUPERNAME)
+#define ARGP_INDEX_FIELD_OP             ARGP_LIST5 (ARGP_PKGLENGTH,  ARGP_NAMESTRING,    ARGP_NAMESTRING,ARGP_BYTEDATA,  ARGP_FIELDLIST)
+#define ARGP_INDEX_OP                   ARGP_LIST3 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_TARGET)
+#define ARGP_LAND_OP                    ARGP_LIST2 (ARGP_TERMARG,    ARGP_TERMARG)
+#define ARGP_LEQUAL_OP                  ARGP_LIST2 (ARGP_TERMARG,    ARGP_TERMARG)
+#define ARGP_LGREATER_OP                ARGP_LIST2 (ARGP_TERMARG,    ARGP_TERMARG)
+#define ARGP_LGREATEREQUAL_OP           ARGP_LIST2 (ARGP_TERMARG,    ARGP_TERMARG)
+#define ARGP_LLESS_OP                   ARGP_LIST2 (ARGP_TERMARG,    ARGP_TERMARG)
+#define ARGP_LLESSEQUAL_OP              ARGP_LIST2 (ARGP_TERMARG,    ARGP_TERMARG)
+#define ARGP_LNOT_OP                    ARGP_LIST1 (ARGP_TERMARG)
+#define ARGP_LNOTEQUAL_OP               ARGP_LIST2 (ARGP_TERMARG,    ARGP_TERMARG)
+#define ARGP_LOAD_OP                    ARGP_LIST2 (ARGP_NAMESTRING, ARGP_SUPERNAME)
+#define ARGP_LOAD_TABLE_OP              ARGP_LIST6 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_TERMARG,   ARGP_TERMARG,  ARGP_TERMARG,   ARGP_TERMARG)
+#define ARGP_LOCAL0                     ARG_NONE
+#define ARGP_LOCAL1                     ARG_NONE
+#define ARGP_LOCAL2                     ARG_NONE
+#define ARGP_LOCAL3                     ARG_NONE
+#define ARGP_LOCAL4                     ARG_NONE
+#define ARGP_LOCAL5                     ARG_NONE
+#define ARGP_LOCAL6                     ARG_NONE
+#define ARGP_LOCAL7                     ARG_NONE
+#define ARGP_LOR_OP                     ARGP_LIST2 (ARGP_TERMARG,    ARGP_TERMARG)
+#define ARGP_MATCH_OP                   ARGP_LIST6 (ARGP_TERMARG,    ARGP_BYTEDATA,      ARGP_TERMARG,   ARGP_BYTEDATA,  ARGP_TERMARG,   ARGP_TERMARG)
+#define ARGP_METHOD_OP                  ARGP_LIST4 (ARGP_PKGLENGTH,  ARGP_NAME,          ARGP_BYTEDATA,  ARGP_TERMLIST)
+#define ARGP_METHODCALL_OP              ARGP_LIST1 (ARGP_NAMESTRING)
+#define ARGP_MID_OP                     ARGP_LIST4 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_TERMARG,   ARGP_TARGET)
+#define ARGP_MOD_OP                     ARGP_LIST3 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_TARGET)
+#define ARGP_MULTIPLY_OP                ARGP_LIST3 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_TARGET)
+#define ARGP_MUTEX_OP                   ARGP_LIST2 (ARGP_NAME,       ARGP_BYTEDATA)
+#define ARGP_NAME_OP                    ARGP_LIST2 (ARGP_NAME,       ARGP_DATAOBJ)
+#define ARGP_NAMEDFIELD_OP              ARGP_LIST1 (ARGP_NAMESTRING)
+#define ARGP_NAMEPATH_OP                ARGP_LIST1 (ARGP_NAMESTRING)
+#define ARGP_NOOP_OP                    ARG_NONE
+#define ARGP_NOTIFY_OP                  ARGP_LIST2 (ARGP_SUPERNAME,  ARGP_TERMARG)
+#define ARGP_ONE_OP                     ARG_NONE
+#define ARGP_ONES_OP                    ARG_NONE
+#define ARGP_PACKAGE_OP                 ARGP_LIST3 (ARGP_PKGLENGTH,  ARGP_BYTEDATA,      ARGP_DATAOBJLIST)
+#define ARGP_POWER_RES_OP               ARGP_LIST5 (ARGP_PKGLENGTH,  ARGP_NAME,          ARGP_BYTEDATA,  ARGP_WORDDATA,  ARGP_OBJLIST)
+#define ARGP_PROCESSOR_OP               ARGP_LIST6 (ARGP_PKGLENGTH,  ARGP_NAME,          ARGP_BYTEDATA,  ARGP_DWORDDATA, ARGP_BYTEDATA,  ARGP_OBJLIST)
+#define ARGP_QWORD_OP                   ARGP_LIST1 (ARGP_QWORDDATA)
+#define ARGP_REF_OF_OP                  ARGP_LIST1 (ARGP_SUPERNAME)
+#define ARGP_REGION_OP                  ARGP_LIST4 (ARGP_NAME,       ARGP_BYTEDATA,      ARGP_TERMARG,   ARGP_TERMARG)
+#define ARGP_RELEASE_OP                 ARGP_LIST1 (ARGP_SUPERNAME)
+#define ARGP_RESERVEDFIELD_OP           ARGP_LIST1 (ARGP_NAMESTRING)
+#define ARGP_RESET_OP                   ARGP_LIST1 (ARGP_SUPERNAME)
+#define ARGP_RETURN_OP                  ARGP_LIST1 (ARGP_TERMARG)
+#define ARGP_REVISION_OP                ARG_NONE
+#define ARGP_SCOPE_OP                   ARGP_LIST3 (ARGP_PKGLENGTH,  ARGP_NAME,          ARGP_TERMLIST)
+#define ARGP_SHIFT_LEFT_OP              ARGP_LIST3 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_TARGET)
+#define ARGP_SHIFT_RIGHT_OP             ARGP_LIST3 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_TARGET)
+#define ARGP_SIGNAL_OP                  ARGP_LIST1 (ARGP_SUPERNAME)
+#define ARGP_SIZE_OF_OP                 ARGP_LIST1 (ARGP_SUPERNAME)
+#define ARGP_SLEEP_OP                   ARGP_LIST1 (ARGP_TERMARG)
+#define ARGP_STALL_OP                   ARGP_LIST1 (ARGP_TERMARG)
+#define ARGP_STATICSTRING_OP            ARGP_LIST1 (ARGP_NAMESTRING)
+#define ARGP_STORE_OP                   ARGP_LIST2 (ARGP_TERMARG,    ARGP_SUPERNAME)
+#define ARGP_STRING_OP                  ARGP_LIST1 (ARGP_CHARLIST)
+#define ARGP_SUBTRACT_OP                ARGP_LIST3 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_TARGET)
+#define ARGP_THERMAL_ZONE_OP            ARGP_LIST3 (ARGP_PKGLENGTH,  ARGP_NAME,          ARGP_OBJLIST)
+#define ARGP_TIMER_OP                   ARG_NONE
+#define ARGP_TO_BCD_OP                  ARGP_LIST2 (ARGP_TERMARG,    ARGP_TARGET)
+#define ARGP_TO_BUFFER_OP               ARGP_LIST2 (ARGP_TERMARG,    ARGP_TARGET)
+#define ARGP_TO_DEC_STR_OP              ARGP_LIST2 (ARGP_TERMARG,    ARGP_TARGET)
+#define ARGP_TO_HEX_STR_OP              ARGP_LIST2 (ARGP_TERMARG,    ARGP_TARGET)
+#define ARGP_TO_INTEGER_OP              ARGP_LIST2 (ARGP_TERMARG,    ARGP_TARGET)
+#define ARGP_TO_STRING_OP               ARGP_LIST3 (ARGP_TERMARG,    ARGP_TERMARG,       ARGP_TARGET)
+#define ARGP_TYPE_OP                    ARGP_LIST1 (ARGP_SUPERNAME)
+#define ARGP_UNLOAD_OP                  ARGP_LIST1 (ARGP_SUPERNAME)
+#define ARGP_VAR_PACKAGE_OP             ARGP_LIST3 (ARGP_PKGLENGTH,  ARGP_TERMARG,       ARGP_DATAOBJLIST)
+#define ARGP_WAIT_OP                    ARGP_LIST2 (ARGP_SUPERNAME,  ARGP_TERMARG)
+#define ARGP_WHILE_OP                   ARGP_LIST3 (ARGP_PKGLENGTH,  ARGP_TERMARG,       ARGP_TERMLIST)
+#define ARGP_WORD_OP                    ARGP_LIST1 (ARGP_WORDDATA)
+#define ARGP_ZERO_OP                    ARG_NONE
+
+
+/*
+ * All AML opcodes and the runtime arguments for each.  Used by the AML
+ * interpreter  Each list is compressed into a 32-bit number and stored
+ * in the master opcode table (in psopcode.c).
+ *
+ * (Used by prep_operands procedure and the ASL Compiler)
+ */
+#define ARGI_ACCESSFIELD_OP             ARGI_INVALID_OPCODE
+#define ARGI_ACQUIRE_OP                 ARGI_LIST2 (ARGI_MUTEX,      ARGI_INTEGER)
+#define ARGI_ADD_OP                     ARGI_LIST3 (ARGI_INTEGER,    ARGI_INTEGER,       ARGI_TARGETREF)
+#define ARGI_ALIAS_OP                   ARGI_INVALID_OPCODE
+#define ARGI_ARG0                       ARG_NONE
+#define ARGI_ARG1                       ARG_NONE
+#define ARGI_ARG2                       ARG_NONE
+#define ARGI_ARG3                       ARG_NONE
+#define ARGI_ARG4                       ARG_NONE
+#define ARGI_ARG5                       ARG_NONE
+#define ARGI_ARG6                       ARG_NONE
+#define ARGI_BANK_FIELD_OP              ARGI_INVALID_OPCODE
+#define ARGI_BIT_AND_OP                 ARGI_LIST3 (ARGI_INTEGER,    ARGI_INTEGER,       ARGI_TARGETREF)
+#define ARGI_BIT_NAND_OP                ARGI_LIST3 (ARGI_INTEGER,    ARGI_INTEGER,       ARGI_TARGETREF)
+#define ARGI_BIT_NOR_OP                 ARGI_LIST3 (ARGI_INTEGER,    ARGI_INTEGER,       ARGI_TARGETREF)
+#define ARGI_BIT_NOT_OP                 ARGI_LIST2 (ARGI_INTEGER,    ARGI_TARGETREF)
+#define ARGI_BIT_OR_OP                  ARGI_LIST3 (ARGI_INTEGER,    ARGI_INTEGER,       ARGI_TARGETREF)
+#define ARGI_BIT_XOR_OP                 ARGI_LIST3 (ARGI_INTEGER,    ARGI_INTEGER,       ARGI_TARGETREF)
+#define ARGI_BREAK_OP                   ARG_NONE
+#define ARGI_BREAK_POINT_OP             ARG_NONE
+#define ARGI_BUFFER_OP                  ARGI_LIST1 (ARGI_INTEGER)
+#define ARGI_BYTE_OP                    ARGI_INVALID_OPCODE
+#define ARGI_BYTELIST_OP                ARGI_INVALID_OPCODE
+#define ARGI_CONCAT_OP                  ARGI_LIST3 (ARGI_COMPUTEDATA,ARGI_COMPUTEDATA,   ARGI_TARGETREF)
+#define ARGI_CONCAT_RES_OP              ARGI_LIST3 (ARGI_BUFFER,     ARGI_BUFFER,        ARGI_TARGETREF)
+#define ARGI_COND_REF_OF_OP             ARGI_LIST2 (ARGI_OBJECT_REF, ARGI_TARGETREF)
+#define ARGI_CONTINUE_OP                ARGI_INVALID_OPCODE
+#define ARGI_COPY_OP                    ARGI_LIST2 (ARGI_ANYTYPE,    ARGI_SIMPLE_TARGET)
+#define ARGI_CREATE_BIT_FIELD_OP        ARGI_LIST3 (ARGI_BUFFER,     ARGI_INTEGER,       ARGI_REFERENCE)
+#define ARGI_CREATE_BYTE_FIELD_OP       ARGI_LIST3 (ARGI_BUFFER,     ARGI_INTEGER,       ARGI_REFERENCE)
+#define ARGI_CREATE_DWORD_FIELD_OP      ARGI_LIST3 (ARGI_BUFFER,     ARGI_INTEGER,       ARGI_REFERENCE)
+#define ARGI_CREATE_FIELD_OP            ARGI_LIST4 (ARGI_BUFFER,     ARGI_INTEGER,       ARGI_INTEGER,      ARGI_REFERENCE)
+#define ARGI_CREATE_QWORD_FIELD_OP      ARGI_LIST3 (ARGI_BUFFER,     ARGI_INTEGER,       ARGI_REFERENCE)
+#define ARGI_CREATE_WORD_FIELD_OP       ARGI_LIST3 (ARGI_BUFFER,     ARGI_INTEGER,       ARGI_REFERENCE)
+#define ARGI_DATA_REGION_OP             ARGI_LIST3 (ARGI_STRING,     ARGI_STRING,        ARGI_STRING)
+#define ARGI_DEBUG_OP                   ARG_NONE
+#define ARGI_DECREMENT_OP               ARGI_LIST1 (ARGI_INTEGER_REF)
+#define ARGI_DEREF_OF_OP                ARGI_LIST1 (ARGI_REF_OR_STRING)
+#define ARGI_DEVICE_OP                  ARGI_INVALID_OPCODE
+#define ARGI_DIVIDE_OP                  ARGI_LIST4 (ARGI_INTEGER,    ARGI_INTEGER,       ARGI_TARGETREF,    ARGI_TARGETREF)
+#define ARGI_DWORD_OP                   ARGI_INVALID_OPCODE
+#define ARGI_ELSE_OP                    ARGI_INVALID_OPCODE
+#define ARGI_EVENT_OP                   ARGI_INVALID_OPCODE
+#define ARGI_FATAL_OP                   ARGI_LIST3 (ARGI_INTEGER,    ARGI_INTEGER,       ARGI_INTEGER)
+#define ARGI_FIELD_OP                   ARGI_INVALID_OPCODE
+#define ARGI_FIND_SET_LEFT_BIT_OP       ARGI_LIST2 (ARGI_INTEGER,    ARGI_TARGETREF)
+#define ARGI_FIND_SET_RIGHT_BIT_OP      ARGI_LIST2 (ARGI_INTEGER,    ARGI_TARGETREF)
+#define ARGI_FROM_BCD_OP                ARGI_LIST2 (ARGI_INTEGER,    ARGI_TARGETREF)
+#define ARGI_IF_OP                      ARGI_INVALID_OPCODE
+#define ARGI_INCREMENT_OP               ARGI_LIST1 (ARGI_INTEGER_REF)
+#define ARGI_INDEX_FIELD_OP             ARGI_INVALID_OPCODE
+#define ARGI_INDEX_OP                   ARGI_LIST3 (ARGI_COMPLEXOBJ, ARGI_INTEGER,       ARGI_TARGETREF)
+#define ARGI_LAND_OP                    ARGI_LIST2 (ARGI_INTEGER,    ARGI_INTEGER)
+#define ARGI_LEQUAL_OP                  ARGI_LIST2 (ARGI_COMPUTEDATA,ARGI_COMPUTEDATA)
+#define ARGI_LGREATER_OP                ARGI_LIST2 (ARGI_COMPUTEDATA,ARGI_COMPUTEDATA)
+#define ARGI_LGREATEREQUAL_OP           ARGI_INVALID_OPCODE
+#define ARGI_LLESS_OP                   ARGI_LIST2 (ARGI_COMPUTEDATA,ARGI_COMPUTEDATA)
+#define ARGI_LLESSEQUAL_OP              ARGI_INVALID_OPCODE
+#define ARGI_LNOT_OP                    ARGI_LIST1 (ARGI_INTEGER)
+#define ARGI_LNOTEQUAL_OP               ARGI_INVALID_OPCODE
+#define ARGI_LOAD_OP                    ARGI_LIST2 (ARGI_REGION_OR_FIELD,ARGI_TARGETREF)
+#define ARGI_LOAD_TABLE_OP              ARGI_LIST6 (ARGI_STRING,     ARGI_STRING,        ARGI_STRING,       ARGI_STRING,    ARGI_STRING, ARGI_ANYTYPE)
+#define ARGI_LOCAL0                     ARG_NONE
+#define ARGI_LOCAL1                     ARG_NONE
+#define ARGI_LOCAL2                     ARG_NONE
+#define ARGI_LOCAL3                     ARG_NONE
+#define ARGI_LOCAL4                     ARG_NONE
+#define ARGI_LOCAL5                     ARG_NONE
+#define ARGI_LOCAL6                     ARG_NONE
+#define ARGI_LOCAL7                     ARG_NONE
+#define ARGI_LOR_OP                     ARGI_LIST2 (ARGI_INTEGER,    ARGI_INTEGER)
+#define ARGI_MATCH_OP                   ARGI_LIST6 (ARGI_PACKAGE,    ARGI_INTEGER,   ARGI_COMPUTEDATA,      ARGI_INTEGER,ARGI_COMPUTEDATA,ARGI_INTEGER)
+#define ARGI_METHOD_OP                  ARGI_INVALID_OPCODE
+#define ARGI_METHODCALL_OP              ARGI_INVALID_OPCODE
+#define ARGI_MID_OP                     ARGI_LIST4 (ARGI_BUFFER_OR_STRING,ARGI_INTEGER,  ARGI_INTEGER,      ARGI_TARGETREF)
+#define ARGI_MOD_OP                     ARGI_LIST3 (ARGI_INTEGER,    ARGI_INTEGER,       ARGI_TARGETREF)
+#define ARGI_MULTIPLY_OP                ARGI_LIST3 (ARGI_INTEGER,    ARGI_INTEGER,       ARGI_TARGETREF)
+#define ARGI_MUTEX_OP                   ARGI_INVALID_OPCODE
+#define ARGI_NAME_OP                    ARGI_INVALID_OPCODE
+#define ARGI_NAMEDFIELD_OP              ARGI_INVALID_OPCODE
+#define ARGI_NAMEPATH_OP                ARGI_INVALID_OPCODE
+#define ARGI_NOOP_OP                    ARG_NONE
+#define ARGI_NOTIFY_OP                  ARGI_LIST2 (ARGI_DEVICE_REF, ARGI_INTEGER)
+#define ARGI_ONE_OP                     ARG_NONE
+#define ARGI_ONES_OP                    ARG_NONE
+#define ARGI_PACKAGE_OP                 ARGI_LIST1 (ARGI_INTEGER)
+#define ARGI_POWER_RES_OP               ARGI_INVALID_OPCODE
+#define ARGI_PROCESSOR_OP               ARGI_INVALID_OPCODE
+#define ARGI_QWORD_OP                   ARGI_INVALID_OPCODE
+#define ARGI_REF_OF_OP                  ARGI_LIST1 (ARGI_OBJECT_REF)
+#define ARGI_REGION_OP                  ARGI_LIST2 (ARGI_INTEGER,    ARGI_INTEGER)
+#define ARGI_RELEASE_OP                 ARGI_LIST1 (ARGI_MUTEX)
+#define ARGI_RESERVEDFIELD_OP           ARGI_INVALID_OPCODE
+#define ARGI_RESET_OP                   ARGI_LIST1 (ARGI_EVENT)
+#define ARGI_RETURN_OP                  ARGI_INVALID_OPCODE
+#define ARGI_REVISION_OP                ARG_NONE
+#define ARGI_SCOPE_OP                   ARGI_INVALID_OPCODE
+#define ARGI_SHIFT_LEFT_OP              ARGI_LIST3 (ARGI_INTEGER,    ARGI_INTEGER,       ARGI_TARGETREF)
+#define ARGI_SHIFT_RIGHT_OP             ARGI_LIST3 (ARGI_INTEGER,    ARGI_INTEGER,       ARGI_TARGETREF)
+#define ARGI_SIGNAL_OP                  ARGI_LIST1 (ARGI_EVENT)
+#define ARGI_SIZE_OF_OP                 ARGI_LIST1 (ARGI_DATAOBJECT)
+#define ARGI_SLEEP_OP                   ARGI_LIST1 (ARGI_INTEGER)
+#define ARGI_STALL_OP                   ARGI_LIST1 (ARGI_INTEGER)
+#define ARGI_STATICSTRING_OP            ARGI_INVALID_OPCODE
+#define ARGI_STORE_OP                   ARGI_LIST2 (ARGI_DATAREFOBJ, ARGI_TARGETREF)
+#define ARGI_STRING_OP                  ARGI_INVALID_OPCODE
+#define ARGI_SUBTRACT_OP                ARGI_LIST3 (ARGI_INTEGER,    ARGI_INTEGER,       ARGI_TARGETREF)
+#define ARGI_THERMAL_ZONE_OP            ARGI_INVALID_OPCODE
+#define ARGI_TIMER_OP                   ARG_NONE
+#define ARGI_TO_BCD_OP                  ARGI_LIST2 (ARGI_INTEGER,    ARGI_FIXED_TARGET)
+#define ARGI_TO_BUFFER_OP               ARGI_LIST2 (ARGI_COMPUTEDATA,ARGI_FIXED_TARGET)
+#define ARGI_TO_DEC_STR_OP              ARGI_LIST2 (ARGI_COMPUTEDATA,ARGI_FIXED_TARGET)
+#define ARGI_TO_HEX_STR_OP              ARGI_LIST2 (ARGI_COMPUTEDATA,ARGI_FIXED_TARGET)
+#define ARGI_TO_INTEGER_OP              ARGI_LIST2 (ARGI_COMPUTEDATA,ARGI_FIXED_TARGET)
+#define ARGI_TO_STRING_OP               ARGI_LIST3 (ARGI_BUFFER,     ARGI_INTEGER,       ARGI_FIXED_TARGET)
+#define ARGI_TYPE_OP                    ARGI_LIST1 (ARGI_ANYTYPE)
+#define ARGI_UNLOAD_OP                  ARGI_LIST1 (ARGI_DDBHANDLE)
+#define ARGI_VAR_PACKAGE_OP             ARGI_LIST1 (ARGI_INTEGER)
+#define ARGI_WAIT_OP                    ARGI_LIST2 (ARGI_EVENT,      ARGI_INTEGER)
+#define ARGI_WHILE_OP                   ARGI_INVALID_OPCODE
+#define ARGI_WORD_OP                    ARGI_INVALID_OPCODE
+#define ARGI_ZERO_OP                    ARG_NONE
+
+#endif /* __ACOPCODE_H__ */
diff --git a/include/acpi/acparser.h b/include/acpi/acparser.h
--- a/include/acpi/acparser.h
+++ b/include/acpi/acparser.h
@@ -64,8 +64,17 @@
 
 #define ACPI_PARSE_DEFERRED_OP          0x0100
 
-/* Parser external interfaces */
 
+/******************************************************************************
+ *
+ * Parser interfaces
+ *
+ *****************************************************************************/
+
+
+/*
+ * psxface - Parser external interfaces
+ */
 acpi_status
 acpi_psx_load_table (
 	u8                              *pcode_addr,
@@ -76,23 +85,13 @@ acpi_psx_execute (
 	struct acpi_parameter_info      *info);
 
 
-/******************************************************************************
- *
- * Parser interfaces
- *
- *****************************************************************************/
-
-
-/* psargs - Parse AML opcode arguments */
-
+/*
+ * psargs - Parse AML opcode arguments
+ */
 u8 *
 acpi_ps_get_next_package_end (
 	struct acpi_parse_state         *parser_state);
 
-u32
-acpi_ps_get_next_package_length (
-	struct acpi_parse_state         *parser_state);
-
 char *
 acpi_ps_get_next_namestring (
 	struct acpi_parse_state         *parser_state);
@@ -110,10 +109,6 @@ acpi_ps_get_next_namepath (
 	union acpi_parse_object         *arg,
 	u8                              method_call);
 
-union acpi_parse_object *
-acpi_ps_get_next_field (
-	struct acpi_parse_state         *parser_state);
-
 acpi_status
 acpi_ps_get_next_arg (
 	struct acpi_walk_state          *walk_state,
@@ -122,8 +117,9 @@ acpi_ps_get_next_arg (
 	union acpi_parse_object         **return_arg);
 
 
-/* psfind */
-
+/*
+ * psfind
+ */
 union acpi_parse_object *
 acpi_ps_find_name (
 	union acpi_parse_object         *scope,
@@ -135,8 +131,9 @@ acpi_ps_get_parent (
 	union acpi_parse_object         *op);
 
 
-/* psopcode - AML Opcode information */
-
+/*
+ * psopcode - AML Opcode information
+ */
 const struct acpi_opcode_info *
 acpi_ps_get_opcode_info (
 	u16                             opcode);
@@ -146,56 +143,25 @@ acpi_ps_get_opcode_name (
 	u16                             opcode);
 
 
-/* psparse - top level parsing routines */
-
-u32
-acpi_ps_get_opcode_size (
-	u32                             opcode);
-
-void
-acpi_ps_complete_this_op (
-	struct acpi_walk_state          *walk_state,
-	union acpi_parse_object         *op);
-
-acpi_status
-acpi_ps_next_parse_state (
-	struct acpi_walk_state          *walk_state,
-	union acpi_parse_object         *op,
-	acpi_status                     callback_status);
-
-acpi_status
-acpi_ps_find_object (
-	struct acpi_walk_state          *walk_state,
-	union acpi_parse_object         **out_op);
-
-void
-acpi_ps_delete_parse_tree (
-	union acpi_parse_object         *root);
-
-acpi_status
-acpi_ps_parse_loop (
-	struct acpi_walk_state          *walk_state);
-
+/*
+ * psparse - top level parsing routines
+ */
 acpi_status
 acpi_ps_parse_aml (
 	struct acpi_walk_state          *walk_state);
 
-acpi_status
-acpi_ps_parse_table (
-	u8                              *aml,
-	u32                             aml_size,
-	acpi_parse_downwards            descending_callback,
-	acpi_parse_upwards              ascending_callback,
-	union acpi_parse_object         **root_object);
+u32
+acpi_ps_get_opcode_size (
+	u32                             opcode);
 
 u16
 acpi_ps_peek_opcode (
 	struct acpi_parse_state         *state);
 
 
-/* psscope - Scope stack management routines */
-
-
+/*
+ * psscope - Scope stack management routines
+ */
 acpi_status
 acpi_ps_init_scope (
 	struct acpi_parse_state         *parser_state,
@@ -228,8 +194,9 @@ acpi_ps_cleanup_scope (
 	struct acpi_parse_state         *state);
 
 
-/* pstree - parse tree manipulation routines */
-
+/*
+ * pstree - parse tree manipulation routines
+ */
 void
 acpi_ps_append_arg(
 	union acpi_parse_object         *op,
@@ -247,20 +214,17 @@ acpi_ps_get_arg(
 	union acpi_parse_object         *op,
 	u32                              argn);
 
-#ifdef ACPI_FUTURE_USAGE
-union acpi_parse_object *
-acpi_ps_get_child (
-	union acpi_parse_object         *op);
-
+#ifdef	ACPI_FUTURE_USAGE
 union acpi_parse_object *
 acpi_ps_get_depth_next (
 	union acpi_parse_object         *origin,
 	union acpi_parse_object         *op);
-#endif  /*  ACPI_FUTURE_USAGE  */
-
+#endif	/* ACPI_FUTURE_USAGE */
 
-/* pswalk - parse tree walk routines */
 
+/*
+ * pswalk - parse tree walk routines
+ */
 acpi_status
 acpi_ps_walk_parsed_aml (
 	union acpi_parse_object         *start_op,
@@ -283,9 +247,14 @@ acpi_status
 acpi_ps_delete_completed_op (
 	struct acpi_walk_state          *walk_state);
 
+void
+acpi_ps_delete_parse_tree (
+	union acpi_parse_object         *root);
 
-/* psutils - parser utilities */
 
+/*
+ * psutils - parser utilities
+ */
 union acpi_parse_object *
 acpi_ps_create_scope_op (
 	void);
@@ -303,12 +272,6 @@ void
 acpi_ps_free_op (
 	union acpi_parse_object         *op);
 
-#ifdef ACPI_ENABLE_OBJECT_CACHE
-void
-acpi_ps_delete_parse_cache (
-	void);
-#endif
-
 u8
 acpi_ps_is_leading_char (
 	u32                             c);
@@ -317,20 +280,27 @@ u8
 acpi_ps_is_prefix_char (
 	u32                             c);
 
-#ifdef ACPI_FUTURE_USAGE
+#ifdef	ACPI_FUTURE_USAGE
 u32
 acpi_ps_get_name(
 	union acpi_parse_object         *op);
-#endif
+#endif	/* ACPI_FUTURE_USAGE */
 
 void
 acpi_ps_set_name(
 	union acpi_parse_object         *op,
 	u32                             name);
 
+#ifdef ACPI_ENABLE_OBJECT_CACHE
+void
+acpi_ps_delete_parse_cache (
+	void);
+#endif
 
-/* psdump - display parser tree */
 
+/*
+ * psdump - display parser tree
+ */
 u32
 acpi_ps_sprint_path (
 	char                            *buffer_start,
diff --git a/include/acpi/acpi.h b/include/acpi/acpi.h
--- a/include/acpi/acpi.h
+++ b/include/acpi/acpi.h
@@ -49,6 +49,7 @@
  * We put them here because we don't want to duplicate them
  * in the rest of the source code again and again.
  */
+#include "acnames.h"            /* Global ACPI names and strings */
 #include "acconfig.h"           /* Configuration constants */
 #include "platform/acenv.h"     /* Target environment specific items */
 #include "actypes.h"            /* Fundamental common data types */
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -108,6 +108,21 @@ typedef int (*acpi_op_unbind)	(struct ac
 typedef int (*acpi_op_match)	(struct acpi_device *device,
 				 struct acpi_driver *driver);
 
+struct acpi_bus_ops {
+	u32 			acpi_op_add:1;
+	u32			acpi_op_remove:1;
+	u32			acpi_op_lock:1;
+	u32			acpi_op_start:1;
+	u32			acpi_op_stop:1;
+	u32			acpi_op_suspend:1;
+	u32			acpi_op_resume:1;
+	u32			acpi_op_scan:1;
+	u32			acpi_op_bind:1;
+	u32			acpi_op_unbind:1;
+	u32			acpi_op_match:1;
+	u32			reserved:21;
+};
+
 struct acpi_device_ops {
 	acpi_op_add		add;
 	acpi_op_remove		remove;
@@ -327,15 +342,36 @@ int acpi_bus_generate_event (struct acpi
 int acpi_bus_receive_event (struct acpi_bus_event *event);
 int acpi_bus_register_driver (struct acpi_driver *driver);
 int acpi_bus_unregister_driver (struct acpi_driver *driver);
-int acpi_bus_scan (struct acpi_device *start);
 int acpi_bus_add (struct acpi_device **child, struct acpi_device *parent,
 		acpi_handle handle, int type);
+int acpi_bus_start (struct acpi_device *device);
 
 
 int acpi_match_ids (struct acpi_device	*device, char	*ids);
 int acpi_create_dir(struct acpi_device *);
 void acpi_remove_dir(struct acpi_device *);
 
+
+/*
+ * Bind physical devices with ACPI devices
+ */
+#include <linux/device.h>
+struct acpi_bus_type {
+	struct list_head	list;
+	struct bus_type		*bus;
+	/* For general devices under the bus*/
+	int (*find_device)(struct device *, acpi_handle*);
+	/* For bridges, such as PCI root bridge, IDE controller */
+	int (*find_bridge)(struct device *, acpi_handle *);
+};
+int register_acpi_bus_type(struct acpi_bus_type *);
+int unregister_acpi_bus_type(struct acpi_bus_type *);
+struct device *acpi_get_physical_device(acpi_handle);
+/* helper */
+acpi_handle acpi_get_child(acpi_handle, acpi_integer);
+acpi_handle acpi_get_pci_rootbridge_handle(unsigned int, unsigned int);
+#define DEVICE_ACPI_HANDLE(dev) ((acpi_handle)((dev)->firmware_data))
+
 #endif /*CONFIG_ACPI_BUS*/
 
 #endif /*__ACPI_BUS_H__*/
diff --git a/include/acpi/acpi_drivers.h b/include/acpi/acpi_drivers.h
--- a/include/acpi/acpi_drivers.h
+++ b/include/acpi/acpi_drivers.h
@@ -56,8 +56,9 @@
 /* ACPI PCI Interrupt Link (pci_link.c) */
 
 int acpi_irq_penalty_init (void);
-int acpi_pci_link_get_irq (acpi_handle handle, int index, int *edge_level,
+int acpi_pci_link_allocate_irq (acpi_handle handle, int index, int *edge_level,
 	int *active_high_low, char **name);
+int acpi_pci_link_free_irq(acpi_handle handle);
 
 /* ACPI PCI Interrupt Routing (pci_irq.c) */
 
@@ -68,6 +69,7 @@ void acpi_pci_irq_del_prt (int segment, 
 
 struct pci_bus;
 
+acpi_status acpi_get_pci_id (acpi_handle handle, struct acpi_pci_id *id);
 int acpi_pci_bind (struct acpi_device *device);
 int acpi_pci_unbind (struct acpi_device *device);
 int acpi_pci_bind_root (struct acpi_device *device, struct acpi_pci_id *id, struct pci_bus *bus);
@@ -108,5 +110,10 @@ int acpi_ec_ecdt_probe (void);
 
 int acpi_processor_set_thermal_limit(acpi_handle handle, int type);
 
+/* --------------------------------------------------------------------------
+                                    Hot Keys
+   -------------------------------------------------------------------------- */
+
+extern int acpi_specific_hotkey_enabled;
 
 #endif /*__ACPI_DRIVERS_H__*/
diff --git a/include/acpi/acpiosxf.h b/include/acpi/acpiosxf.h
--- a/include/acpi/acpiosxf.h
+++ b/include/acpi/acpiosxf.h
@@ -79,7 +79,6 @@ struct acpi_signal_fatal_info
 /*
  * OSL Initialization and shutdown primitives
  */
-
 acpi_status
 acpi_os_initialize (
 	void);
@@ -92,7 +91,6 @@ acpi_os_terminate (
 /*
  * ACPI Table interfaces
  */
-
 acpi_status
 acpi_os_get_root_pointer (
 	u32                             flags,
@@ -112,7 +110,6 @@ acpi_os_table_override (
 /*
  * Synchronization primitives
  */
-
 acpi_status
 acpi_os_create_semaphore (
 	u32                             max_units,
@@ -156,7 +153,6 @@ acpi_os_release_lock (
 /*
  * Memory allocation and mapping
  */
-
 void *
 acpi_os_allocate (
 	acpi_size                       size);
@@ -187,7 +183,6 @@ acpi_os_get_physical_address (
 /*
  * Interrupt handlers
  */
-
 acpi_status
 acpi_os_install_interrupt_handler (
 	u32                             gsi,
@@ -203,7 +198,6 @@ acpi_os_remove_interrupt_handler (
 /*
  * Threads and Scheduling
  */
-
 u32
 acpi_os_get_thread_id (
 	void);
@@ -234,7 +228,6 @@ acpi_os_stall (
 /*
  * Platform and hardware-independent I/O interfaces
  */
-
 acpi_status
 acpi_os_read_port (
 	acpi_io_address                 address,
@@ -251,7 +244,6 @@ acpi_os_write_port (
 /*
  * Platform and hardware-independent physical memory interfaces
  */
-
 acpi_status
 acpi_os_read_memory (
 	acpi_physical_address           address,
@@ -270,7 +262,6 @@ acpi_os_write_memory (
  * Note: Can't use "Register" as a parameter, changed to "Reg" --
  * certain compilers complain.
  */
-
 acpi_status
 acpi_os_read_pci_configuration (
 	struct acpi_pci_id              *pci_id,
@@ -288,7 +279,6 @@ acpi_os_write_pci_configuration (
 /*
  * Interim function needed for PCI IRQ routing
  */
-
 void
 acpi_os_derive_pci_id(
 	acpi_handle                     rhandle,
@@ -298,7 +288,6 @@ acpi_os_derive_pci_id(
 /*
  * Miscellaneous
  */
-
 u8
 acpi_os_readable (
 	void                            *pointer,
@@ -323,7 +312,6 @@ acpi_os_signal (
 /*
  * Debug print routines
  */
-
 void ACPI_INTERNAL_VAR_XFACE
 acpi_os_printf (
 	const char                      *format,
@@ -339,11 +327,10 @@ acpi_os_redirect_output (
 	void                            *destination);
 
 
+#ifdef ACPI_FUTURE_USAGE
 /*
  * Debug input
  */
-
-#ifdef ACPI_FUTURE_USAGE
 u32
 acpi_os_get_line (
 	char                            *buffer);
@@ -353,7 +340,6 @@ acpi_os_get_line (
 /*
  * Directory manipulation
  */
-
 void *
 acpi_os_open_directory (
 	char                            *pathname,
@@ -377,7 +363,6 @@ acpi_os_close_directory (
 /*
  * Debug
  */
-
 void
 acpi_os_dbg_assert(
 	void                            *failed_assertion,
@@ -385,5 +370,4 @@ acpi_os_dbg_assert(
 	u32                             line_number,
 	char                            *message);
 
-
 #endif /* __ACPIOSXF_H__ */
diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h
--- a/include/acpi/acpixf.h
+++ b/include/acpi/acpixf.h
@@ -50,10 +50,9 @@
 #include "actbl.h"
 
 
- /*
+/*
  * Global interfaces
  */
-
 acpi_status
 acpi_initialize_subsystem (
 	void);
@@ -106,9 +105,8 @@ acpi_install_initialization_handler (
 #endif
 
 /*
- * ACPI Memory manager
+ * ACPI Memory managment
  */
-
 void *
 acpi_allocate (
 	u32                             size);
@@ -125,7 +123,6 @@ acpi_free (
 /*
  * ACPI table manipulation interfaces
  */
-
 acpi_status
 acpi_find_root_pointer (
 	u32                             flags,
@@ -168,7 +165,6 @@ acpi_get_firmware_table (
 /*
  * Namespace and name interfaces
  */
-
 acpi_status
 acpi_walk_namespace (
 	acpi_object_type                type,
@@ -218,7 +214,6 @@ acpi_get_data (
 /*
  * Object manipulation and enumeration
  */
-
 acpi_status
 acpi_evaluate_object (
 	acpi_handle                     object,
@@ -262,7 +257,6 @@ acpi_get_parent (
 /*
  * Event handler interfaces
  */
-
 acpi_status
 acpi_install_fixed_event_handler (
 	u32                             acpi_event,
@@ -319,7 +313,6 @@ acpi_install_exception_handler (
 /*
  * Event interfaces
  */
-
 acpi_status
 acpi_acquire_global_lock (
 	u16                             timeout,
@@ -404,7 +397,6 @@ acpi_remove_gpe_block (
 /*
  * Resource interfaces
  */
-
 typedef
 acpi_status (*ACPI_WALK_RESOURCE_CALLBACK) (
 	struct acpi_resource            *resource,
@@ -448,7 +440,6 @@ acpi_resource_to_address64 (
 /*
  * Hardware (ACPI device) interfaces
  */
-
 acpi_status
 acpi_get_register (
 	u32                             register_id,
diff --git a/include/acpi/acresrc.h b/include/acpi/acresrc.h
--- a/include/acpi/acresrc.h
+++ b/include/acpi/acresrc.h
@@ -48,7 +48,6 @@
 /*
  *  Function prototypes called from Acpi* APIs
  */
-
 acpi_status
 acpi_rs_get_prt_method_data (
 	acpi_handle                     handle,
@@ -60,12 +59,12 @@ acpi_rs_get_crs_method_data (
 	acpi_handle                     handle,
 	struct acpi_buffer              *ret_buffer);
 
-#ifdef ACPI_FUTURE_USAGE
+#ifdef	ACPI_FUTURE_USAGE
 acpi_status
 acpi_rs_get_prs_method_data (
 	acpi_handle                     handle,
 	struct acpi_buffer              *ret_buffer);
-#endif
+#endif	/* ACPI_FUTURE_USAGE */
 
 acpi_status
 acpi_rs_get_method_data (
@@ -95,61 +94,9 @@ acpi_rs_create_pci_routing_table (
 
 
 /*
- * Function prototypes called from acpi_rs_create*
+ * rsdump
  */
-#ifdef ACPI_FUTURE_USAGE
-void
-acpi_rs_dump_irq (
-	union acpi_resource_data        *data);
-
-void
-acpi_rs_dump_address16 (
-	union acpi_resource_data        *data);
-
-void
-acpi_rs_dump_address32 (
-	union acpi_resource_data        *data);
-
-void
-acpi_rs_dump_address64 (
-	union acpi_resource_data        *data);
-
-void
-acpi_rs_dump_dma (
-	union acpi_resource_data        *data);
-
-void
-acpi_rs_dump_io (
-	union acpi_resource_data        *data);
-
-void
-acpi_rs_dump_extended_irq (
-	union acpi_resource_data        *data);
-
-void
-acpi_rs_dump_fixed_io (
-	union acpi_resource_data        *data);
-
-void
-acpi_rs_dump_fixed_memory32 (
-	union acpi_resource_data        *data);
-
-void
-acpi_rs_dump_memory24 (
-	union acpi_resource_data        *data);
-
-void
-acpi_rs_dump_memory32 (
-	union acpi_resource_data        *data);
-
-void
-acpi_rs_dump_start_depend_fns (
-	union acpi_resource_data        *data);
-
-void
-acpi_rs_dump_vendor_specific (
-	union acpi_resource_data        *data);
-
+#ifdef	ACPI_FUTURE_USAGE
 void
 acpi_rs_dump_resource_list (
 	struct acpi_resource            *resource);
@@ -157,8 +104,12 @@ acpi_rs_dump_resource_list (
 void
 acpi_rs_dump_irq_list (
 	u8                              *route_table);
-#endif  /*  ACPI_FUTURE_USAGE  */
+#endif	/* ACPI_FUTURE_USAGE */
 
+
+/*
+ * rscalc
+ */
 acpi_status
 acpi_rs_get_byte_stream_start (
 	u8                              *byte_stream_buffer,
diff --git a/include/acpi/acstruct.h b/include/acpi/acstruct.h
--- a/include/acpi/acstruct.h
+++ b/include/acpi/acstruct.h
@@ -56,7 +56,6 @@
  * Walk state - current state of a parse tree walk.  Used for both a leisurely stroll through
  * the tree (for whatever reason), and for control method execution.
  */
-
 #define ACPI_NEXT_OP_DOWNWARD       1
 #define ACPI_NEXT_OP_UPWARD         2
 
diff --git a/include/acpi/actables.h b/include/acpi/actables.h
--- a/include/acpi/actables.h
+++ b/include/acpi/actables.h
@@ -50,17 +50,9 @@
 #define SIZE_IN_HEADER          0
 
 
-#ifdef ACPI_FUTURE_USAGE
-acpi_status
-acpi_tb_handle_to_object (
-	u16                             table_id,
-	struct acpi_table_desc          **table_desc);
-#endif
-
 /*
  * tbconvrt - Table conversion routines
  */
-
 acpi_status
 acpi_tb_convert_to_xsdt (
 	struct acpi_table_desc          *table_info);
@@ -78,10 +70,10 @@ acpi_tb_get_table_count (
 	struct rsdp_descriptor          *RSDP,
 	struct acpi_table_header        *RSDT);
 
+
 /*
  * tbget - Table "get" routines
  */
-
 acpi_status
 acpi_tb_get_table (
 	struct acpi_pointer             *address,
@@ -99,17 +91,6 @@ acpi_tb_get_table_body (
 	struct acpi_table_desc          *table_info);
 
 acpi_status
-acpi_tb_get_this_table (
-	struct acpi_pointer             *address,
-	struct acpi_table_header        *header,
-	struct acpi_table_desc          *table_info);
-
-acpi_status
-acpi_tb_table_override (
-	struct acpi_table_header        *header,
-	struct acpi_table_desc          *table_info);
-
-acpi_status
 acpi_tb_get_table_ptr (
 	acpi_table_type                 table_type,
 	u32                             instance,
@@ -127,36 +108,23 @@ acpi_status
 acpi_tb_validate_rsdt (
 	struct acpi_table_header        *table_ptr);
 
+
+/*
+ * tbgetall - get multiple required tables
+ */
 acpi_status
 acpi_tb_get_required_tables (
 	void);
 
-acpi_status
-acpi_tb_get_primary_table (
-	struct acpi_pointer             *address,
-	struct acpi_table_desc          *table_info);
-
-acpi_status
-acpi_tb_get_secondary_table (
-	struct acpi_pointer             *address,
-	acpi_string                     signature,
-	struct acpi_table_desc          *table_info);
 
 /*
  * tbinstall - Table installation
  */
-
 acpi_status
 acpi_tb_install_table (
 	struct acpi_table_desc          *table_info);
 
 acpi_status
-acpi_tb_match_signature (
-	char                            *signature,
-	struct acpi_table_desc          *table_info,
-	u8                              search_type);
-
-acpi_status
 acpi_tb_recognize_table (
 	struct acpi_table_desc          *table_info,
 	u8                              search_type);
@@ -170,7 +138,6 @@ acpi_tb_init_table_descriptor (
 /*
  * tbremove - Table removal and deletion
  */
-
 void
 acpi_tb_delete_all_tables (
 	void);
@@ -189,35 +156,23 @@ acpi_tb_uninstall_table (
 
 
 /*
- * tbrsd - RSDP, RSDT utilities
+ * tbxfroot - RSDP, RSDT utilities
  */
+acpi_status
+acpi_tb_find_table (
+	char                            *signature,
+	char                            *oem_id,
+	char                            *oem_table_id,
+	struct acpi_table_header        **table_ptr);
 
 acpi_status
 acpi_tb_get_table_rsdt (
 	void);
 
-u8 *
-acpi_tb_scan_memory_for_rsdp (
-	u8                              *start_address,
-	u32                             length);
-
-acpi_status
-acpi_tb_find_rsdp (
-	struct acpi_table_desc          *table_info,
-	u32                             flags);
-
 
 /*
  * tbutils - common table utilities
  */
-
-acpi_status
-acpi_tb_find_table (
-	char                            *signature,
-	char                            *oem_id,
-	char                            *oem_table_id,
-	struct acpi_table_header        **table_ptr);
-
 acpi_status
 acpi_tb_verify_table_checksum (
 	struct acpi_table_header        *table_header);
@@ -231,5 +186,4 @@ acpi_status
 acpi_tb_validate_table_header (
 	struct acpi_table_header        *table_header);
 
-
 #endif /* __ACTABLES_H__ */
diff --git a/include/acpi/actbl.h b/include/acpi/actbl.h
--- a/include/acpi/actbl.h
+++ b/include/acpi/actbl.h
@@ -133,7 +133,6 @@ struct acpi_table_header         /* ACPI
 #define DUAL_PIC                0
 #define MULTIPLE_APIC           1
 
-
 /* Master MADT */
 
 struct multiple_apic_table
@@ -144,7 +143,6 @@ struct multiple_apic_table
 	u32                             reserved1       : 31;
 };
 
-
 /* Values for Type in APIC_HEADER_DEF */
 
 #define APIC_PROCESSOR          0
diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h
--- a/include/acpi/actypes.h
+++ b/include/acpi/actypes.h
@@ -478,7 +478,6 @@ typedef u32                             
 #define ACPI_TYPE_INVALID               0x1E
 #define ACPI_TYPE_NOT_FOUND             0xFF
 
-
 /*
  * Bitmapped ACPI types.  Used internally only
  */
@@ -803,7 +802,6 @@ struct acpi_system_info
 /*
  * Types specific to the OS service interfaces
  */
-
 typedef u32
 (ACPI_SYSTEM_XFACE *acpi_osd_handler) (
 	void                            *context);
diff --git a/include/acpi/acutils.h b/include/acpi/acutils.h
--- a/include/acpi/acutils.h
+++ b/include/acpi/acutils.h
@@ -52,13 +52,6 @@ acpi_status (*acpi_pkg_callback) (
 	union acpi_generic_state        *state,
 	void                            *context);
 
-acpi_status
-acpi_ut_walk_package_tree (
-	union acpi_operand_object       *source_object,
-	void                            *target_object,
-	acpi_pkg_callback               walk_callback,
-	void                            *context);
-
 struct acpi_pkg_info
 {
 	u8                              *free_space;
@@ -79,37 +72,13 @@ struct acpi_pkg_info
 #define DB_QWORD_DISPLAY    8
 
 
-/* Global initialization interfaces */
-
-void
-acpi_ut_init_globals (
-	void);
-
-void
-acpi_ut_terminate (
-	void);
-
-
 /*
- * ut_init - miscellaneous initialization and shutdown
+ * utglobal - Global data structures and procedures
  */
-
-acpi_status
-acpi_ut_hardware_initialize (
-	void);
-
 void
-acpi_ut_subsystem_shutdown (
-	void);
-
-acpi_status
-acpi_ut_validate_fadt (
+acpi_ut_init_globals (
 	void);
 
-/*
- * ut_global - Global data structures and procedures
- */
-
 #if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
 
 char *
@@ -157,9 +126,24 @@ acpi_ut_allocate_owner_id (
 
 
 /*
- * ut_clib - Local implementations of C library functions
+ * utinit - miscellaneous initialization and shutdown
  */
+acpi_status
+acpi_ut_hardware_initialize (
+	void);
+
+void
+acpi_ut_subsystem_shutdown (
+	void);
 
+acpi_status
+acpi_ut_validate_fadt (
+	void);
+
+
+/*
+ * utclib - Local implementations of C library functions
+ */
 #ifndef ACPI_USE_SYSTEM_CLIBRARY
 
 acpi_size
@@ -260,10 +244,10 @@ extern const u8 _acpi_ctype[];
 
 #endif /* ACPI_USE_SYSTEM_CLIBRARY */
 
+
 /*
- * ut_copy - Object construction and conversion interfaces
+ * utcopy - Object construction and conversion interfaces
  */
-
 acpi_status
 acpi_ut_build_simple_object(
 	union acpi_operand_object       *obj,
@@ -278,30 +262,11 @@ acpi_ut_build_package_object (
 	u32                             *space_used);
 
 acpi_status
-acpi_ut_copy_ielement_to_eelement (
-	u8                              object_type,
-	union acpi_operand_object       *source_object,
-	union acpi_generic_state        *state,
-	void                            *context);
-
-acpi_status
-acpi_ut_copy_ielement_to_ielement (
-	u8                              object_type,
-	union acpi_operand_object       *source_object,
-	union acpi_generic_state        *state,
-	void                            *context);
-
-acpi_status
 acpi_ut_copy_iobject_to_eobject (
 	union acpi_operand_object       *obj,
 	struct acpi_buffer              *ret_buffer);
 
 acpi_status
-acpi_ut_copy_esimple_to_isimple(
-	union acpi_object               *user_obj,
-	union acpi_operand_object       **return_obj);
-
-acpi_status
 acpi_ut_copy_eobject_to_iobject (
 	union acpi_object               *obj,
 	union acpi_operand_object       **internal_obj);
@@ -312,17 +277,6 @@ acpi_ut_copy_isimple_to_isimple (
 	union acpi_operand_object       *dest_obj);
 
 acpi_status
-acpi_ut_copy_ipackage_to_ipackage (
-	union acpi_operand_object       *source_obj,
-	union acpi_operand_object       *dest_obj,
-	struct acpi_walk_state          *walk_state);
-
-acpi_status
-acpi_ut_copy_simple_object (
-	union acpi_operand_object       *source_desc,
-	union acpi_operand_object       *dest_desc);
-
-acpi_status
 acpi_ut_copy_iobject_to_iobject (
 	union acpi_operand_object       *source_desc,
 	union acpi_operand_object       **dest_desc,
@@ -330,9 +284,8 @@ acpi_ut_copy_iobject_to_iobject (
 
 
 /*
- * ut_create - Object creation
+ * utcreate - Object creation
  */
-
 acpi_status
 acpi_ut_update_object_reference (
 	union acpi_operand_object       *object,
@@ -340,9 +293,8 @@ acpi_ut_update_object_reference (
 
 
 /*
- * ut_debug - Debug interfaces
+ * utdebug - Debug interfaces
  */
-
 void
 acpi_ut_init_stack_ptr_trace (
 	void);
@@ -440,11 +392,14 @@ acpi_ut_debug_print_raw (
 
 
 /*
- * ut_delete - Object deletion
+ * utdelete - Object deletion and reference counts
  */
+void
+acpi_ut_add_reference (
+	union acpi_operand_object       *object);
 
 void
-acpi_ut_delete_internal_obj (
+acpi_ut_remove_reference (
 	union acpi_operand_object       *object);
 
 void
@@ -461,25 +416,8 @@ acpi_ut_delete_internal_object_list (
 
 
 /*
- * ut_eval - object evaluation
+ * uteval - object evaluation
  */
-
-/* Method name strings */
-
-#define METHOD_NAME__HID        "_HID"
-#define METHOD_NAME__CID        "_CID"
-#define METHOD_NAME__UID        "_UID"
-#define METHOD_NAME__ADR        "_ADR"
-#define METHOD_NAME__STA        "_STA"
-#define METHOD_NAME__REG        "_REG"
-#define METHOD_NAME__SEG        "_SEG"
-#define METHOD_NAME__BBN        "_BBN"
-#define METHOD_NAME__PRT        "_PRT"
-#define METHOD_NAME__CRS        "_CRS"
-#define METHOD_NAME__PRS        "_PRS"
-#define METHOD_NAME__PRW        "_PRW"
-
-
 acpi_status
 acpi_ut_osi_implementation (
 	struct acpi_walk_state          *walk_state);
@@ -522,39 +460,10 @@ acpi_ut_execute_sxds (
 	struct acpi_namespace_node      *device_node,
 	u8                              *highest);
 
-/*
- * ut_mutex - mutual exclusion interfaces
- */
-
-acpi_status
-acpi_ut_mutex_initialize (
-	void);
-
-void
-acpi_ut_mutex_terminate (
-	void);
-
-acpi_status
-acpi_ut_create_mutex (
-	acpi_mutex_handle               mutex_id);
-
-acpi_status
-acpi_ut_delete_mutex (
-	acpi_mutex_handle               mutex_id);
-
-acpi_status
-acpi_ut_acquire_mutex (
-	acpi_mutex_handle               mutex_id);
-
-acpi_status
-acpi_ut_release_mutex (
-	acpi_mutex_handle               mutex_id);
-
 
 /*
- * ut_object - internal object create/delete/cache routines
+ * utobject - internal object create/delete/cache routines
  */
-
 union acpi_operand_object    *
 acpi_ut_create_internal_object_dbg (
 	char                            *module_name,
@@ -587,50 +496,15 @@ union acpi_operand_object *
 acpi_ut_create_string_object (
 	acpi_size                       string_size);
 
-
-/*
- * ut_ref_cnt - Object reference count management
- */
-
-void
-acpi_ut_add_reference (
-	union acpi_operand_object       *object);
-
-void
-acpi_ut_remove_reference (
-	union acpi_operand_object       *object);
-
-/*
- * ut_size - Object size routines
- */
-
-acpi_status
-acpi_ut_get_simple_object_size (
-	union acpi_operand_object       *obj,
-	acpi_size                       *obj_length);
-
-acpi_status
-acpi_ut_get_package_object_size (
-	union acpi_operand_object       *obj,
-	acpi_size                       *obj_length);
-
 acpi_status
 acpi_ut_get_object_size(
 	union acpi_operand_object       *obj,
 	acpi_size                       *obj_length);
 
-acpi_status
-acpi_ut_get_element_length (
-	u8                              object_type,
-	union acpi_operand_object       *source_object,
-	union acpi_generic_state        *state,
-	void                            *context);
-
 
 /*
- * ut_state - Generic state creation/cache routines
+ * utstate - Generic state creation/cache routines
  */
-
 void
 acpi_ut_push_generic_state (
 	union acpi_generic_state        **list_head,
@@ -666,14 +540,14 @@ acpi_ut_create_update_state_and_push (
 	u16                             action,
 	union acpi_generic_state        **state_list);
 
-#ifdef ACPI_FUTURE_USAGE
+#ifdef	ACPI_FUTURE_USAGE
 acpi_status
 acpi_ut_create_pkg_state_and_push (
 	void                            *internal_object,
 	void                            *external_object,
 	u16                             index,
 	union acpi_generic_state        **state_list);
-#endif
+#endif	/* ACPI_FUTURE_USAGE */
 
 union acpi_generic_state *
 acpi_ut_create_control_state (
@@ -693,15 +567,10 @@ acpi_ut_delete_object_cache (
 	void);
 #endif
 
+
 /*
- * utmisc
+ * utmath
  */
-
-void
-acpi_ut_print_string (
-	char                            *string,
-	u8                              max_length);
-
 acpi_status
 acpi_ut_divide (
 	acpi_integer                    in_dividend,
@@ -716,6 +585,25 @@ acpi_ut_short_divide (
 	acpi_integer                    *out_quotient,
 	u32                             *out_remainder);
 
+/*
+ * utmisc
+ */
+acpi_status
+acpi_ut_walk_package_tree (
+	union acpi_operand_object       *source_object,
+	void                            *target_object,
+	acpi_pkg_callback               walk_callback,
+	void                            *context);
+
+char *
+acpi_ut_strupr (
+	char                            *src_string);
+
+void
+acpi_ut_print_string (
+	char                            *string,
+	u8                              max_length);
+
 u8
 acpi_ut_valid_acpi_name (
 	u32                             name);
@@ -734,11 +622,21 @@ acpi_ut_strtoul64 (
 
 #define ACPI_ANY_BASE        0
 
-#ifdef ACPI_FUTURE_USAGE
-char *
-acpi_ut_strupr (
-	char                            *src_string);
-#endif
+acpi_status
+acpi_ut_mutex_initialize (
+	void);
+
+void
+acpi_ut_mutex_terminate (
+	void);
+
+acpi_status
+acpi_ut_acquire_mutex (
+	acpi_mutex_handle               mutex_id);
+
+acpi_status
+acpi_ut_release_mutex (
+	acpi_mutex_handle               mutex_id);
 
 u8 *
 acpi_ut_get_resource_end_tag (
@@ -768,9 +666,8 @@ acpi_ut_display_init_pathname (
 
 
 /*
- * Utalloc - memory allocation and object caching
+ * utalloc - memory allocation and object caching
  */
-
 void *
 acpi_ut_acquire_from_cache (
 	u32                             list_id);
@@ -795,9 +692,6 @@ acpi_ut_initialize_buffer (
 	struct acpi_buffer              *buffer,
 	acpi_size                       required_length);
 
-
-/* Memory allocation functions */
-
 void *
 acpi_ut_allocate (
 	acpi_size                       size,
@@ -812,9 +706,7 @@ acpi_ut_callocate (
 	char                            *module,
 	u32                             line);
 
-
 #ifdef ACPI_DBG_TRACK_ALLOCATIONS
-
 void *
 acpi_ut_allocate_and_track (
 	acpi_size                       size,
@@ -836,34 +728,11 @@ acpi_ut_free_and_track (
 	char                            *module,
 	u32                             line);
 
-struct acpi_debug_mem_block *
-acpi_ut_find_allocation (
-	u32                             list_id,
-	void                            *allocation);
-
-acpi_status
-acpi_ut_track_allocation (
-	u32                             list_id,
-	struct acpi_debug_mem_block     *address,
-	acpi_size                       size,
-	u8                              alloc_type,
-	u32                             component,
-	char                            *module,
-	u32                             line);
-
-acpi_status
-acpi_ut_remove_allocation (
-	u32                             list_id,
-	struct acpi_debug_mem_block     *address,
-	u32                             component,
-	char                            *module,
-	u32                             line);
-
-#ifdef ACPI_FUTURE_USAGE
+#ifdef	ACPI_FUTURE_USAGE
 void
 acpi_ut_dump_allocation_info (
 	void);
-#endif
+#endif	/* ACPI_FUTURE_USAGE */
 
 void
 acpi_ut_dump_allocations (
@@ -871,5 +740,4 @@ acpi_ut_dump_allocations (
 	char                            *module);
 #endif
 
-
 #endif /* _ACUTILS_H */
diff --git a/include/acpi/amlcode.h b/include/acpi/amlcode.h
--- a/include/acpi/amlcode.h
+++ b/include/acpi/amlcode.h
@@ -146,8 +146,7 @@
 
 /* prefixed opcodes */
 
-#define AML_EXTOP                   (u16) 0x005b
-
+#define AML_EXTOP                   (u16) 0x005b     /* prefix for 2-byte opcodes */
 
 #define AML_MUTEX_OP                (u16) 0x5b01
 #define AML_EVENT_OP                (u16) 0x5b02
@@ -194,7 +193,6 @@
  * Use only "Unknown" AML opcodes, don't attempt to use
  * any valid ACPI ASCII values (A-Z, 0-9, '-')
  */
-
 #define AML_INT_NAMEPATH_OP         (u16) 0x002d
 #define AML_INT_NAMEDFIELD_OP       (u16) 0x0030
 #define AML_INT_RESERVEDFIELD_OP    (u16) 0x0031
@@ -214,7 +212,6 @@
  * There can be up to 31 unique argument types
  * Zero is reserved as end-of-list indicator
  */
-
 #define ARGP_BYTEDATA               0x01
 #define ARGP_BYTELIST               0x02
 #define ARGP_CHARLIST               0x03
@@ -295,7 +292,6 @@
 /*
  * opcode groups and types
  */
-
 #define OPGRP_NAMED                 0x01
 #define OPGRP_FIELD                 0x02
 #define OPGRP_BYTELIST              0x04
@@ -381,6 +377,12 @@
 #define AML_TYPE_UNDEFINED          0x19
 #define AML_TYPE_BOGUS              0x1A
 
+/* AML Package Length encodings */
+
+#define ACPI_AML_PACKAGE_TYPE1      0x40
+#define ACPI_AML_PACKAGE_TYPE2      0x4000
+#define ACPI_AML_PACKAGE_TYPE3      0x400000
+#define ACPI_AML_PACKAGE_TYPE4      0x40000000
 
 /*
  * Opcode classes
diff --git a/include/acpi/pdc_intel.h b/include/acpi/pdc_intel.h
new file mode 100644
--- /dev/null
+++ b/include/acpi/pdc_intel.h
@@ -0,0 +1,29 @@
+
+/* _PDC bit definition for Intel processors */
+
+#ifndef __PDC_INTEL_H__
+#define __PDC_INTEL_H__
+
+#define ACPI_PDC_P_FFH			(0x0001)
+#define ACPI_PDC_C_C1_HALT		(0x0002)
+#define ACPI_PDC_T_FFH			(0x0004)
+#define ACPI_PDC_SMP_C1PT		(0x0008)
+#define ACPI_PDC_SMP_C2C3		(0x0010)
+#define ACPI_PDC_SMP_P_SWCOORD		(0x0020)
+#define ACPI_PDC_SMP_C_SWCOORD		(0x0040)
+#define ACPI_PDC_SMP_T_SWCOORD		(0x0080)
+#define ACPI_PDC_C_C1_FFH		(0x0100)
+
+
+#define ACPI_PDC_EST_CAPABILITY_SMP	(ACPI_PDC_SMP_C1PT | \
+					 ACPI_PDC_C_C1_HALT)
+
+#define ACPI_PDC_EST_CAPABILITY_SMP_MSR	(ACPI_PDC_EST_CAPABILITY_SMP | \
+					 ACPI_PDC_P_FFH)
+
+#define ACPI_PDC_C_CAPABILITY_SMP	(ACPI_PDC_SMP_C2C3 | \
+					 ACPI_PDC_SMP_C1PT | \
+					 ACPI_PDC_C_C1_HALT)
+
+#endif /* __PDC_INTEL_H__ */
+
diff --git a/include/acpi/platform/acenv.h b/include/acpi/platform/acenv.h
--- a/include/acpi/platform/acenv.h
+++ b/include/acpi/platform/acenv.h
@@ -198,6 +198,7 @@
 #endif
 #endif /* !DEBUGGER_THREADING */
 
+
 /******************************************************************************
  *
  * C library configuration
@@ -209,7 +210,6 @@
  * Use the standard C library headers.
  * We want to keep these to a minimum.
  */
-
 #ifdef ACPI_USE_STANDARD_HEADERS
 /*
  * Use the standard headers from the standard locations
@@ -224,14 +224,8 @@
 /*
  * We will be linking to the standard Clib functions
  */
-
 #define ACPI_STRSTR(s1,s2)      strstr((s1), (s2))
 #define ACPI_STRCHR(s1,c)       strchr((s1), (c))
-
-#ifdef ACPI_FUTURE_USAGE
-#define ACPI_STRUPR(s)          (void) acpi_ut_strupr ((s))
-#endif
-
 #define ACPI_STRLEN(s)          (acpi_size) strlen((s))
 #define ACPI_STRCPY(d,s)        (void) strcpy((d), (s))
 #define ACPI_STRNCPY(d,s,n)     (void) strncpy((d), (s), (acpi_size)(n))
@@ -254,14 +248,15 @@
 #define ACPI_IS_ALPHA           isalpha
 #define ACPI_IS_ASCII           isascii
 
+#else
+
 /******************************************************************************
  *
  * Not using native C library, use local implementations
  *
  *****************************************************************************/
-#else
 
-/*
+ /*
  * Use local definitions of C library macros and functions
  * NOTE: The function implementations may not be as efficient
  * as an inline or assembly code implementation provided by a
@@ -278,14 +273,12 @@ typedef char *va_list;
 /*
  * Storage alignment properties
  */
-
 #define  _AUPBND                (sizeof (acpi_native_int) - 1)
 #define  _ADNBND                (sizeof (acpi_native_int) - 1)
 
 /*
  * Variable argument list macro definitions
  */
-
 #define _bnd(X, bnd)            (((sizeof (X)) + (bnd)) & (~(bnd)))
 #define va_arg(ap, T)           (*(T *)(((ap) += (_bnd (T, _AUPBND))) - (_bnd (T,_ADNBND))))
 #define va_end(ap)              (void) 0
@@ -296,11 +289,6 @@ typedef char *va_list;
 
 #define ACPI_STRSTR(s1,s2)      acpi_ut_strstr ((s1), (s2))
 #define ACPI_STRCHR(s1,c)       acpi_ut_strchr ((s1), (c))
-
-#ifdef ACPI_FUTURE_USAGE
-#define ACPI_STRUPR(s)          (void) acpi_ut_strupr ((s))
-#endif
-
 #define ACPI_STRLEN(s)          (acpi_size) acpi_ut_strlen ((s))
 #define ACPI_STRCPY(d,s)        (void) acpi_ut_strcpy ((d), (s))
 #define ACPI_STRNCPY(d,s,n)     (void) acpi_ut_strncpy ((d), (s), (acpi_size)(n))
diff --git a/include/acpi/processor.h b/include/acpi/processor.h
--- a/include/acpi/processor.h
+++ b/include/acpi/processor.h
@@ -4,6 +4,8 @@
 #include <linux/kernel.h>
 #include <linux/config.h>
 
+#include <asm/acpi.h>
+
 #define ACPI_PROCESSOR_BUSY_METRIC	10
 
 #define ACPI_PROCESSOR_MAX_POWER	8
@@ -14,6 +16,8 @@
 #define ACPI_PROCESSOR_MAX_THROTTLE	250	/* 25% */
 #define ACPI_PROCESSOR_MAX_DUTY_WIDTH	4
 
+#define ACPI_PDC_REVISION_ID		0x1
+
 /* Power Management */
 
 struct acpi_processor_cx;
@@ -59,6 +63,9 @@ struct acpi_processor_power {
 	u32			bm_activity;
 	int			count;
 	struct acpi_processor_cx states[ACPI_PROCESSOR_MAX_POWER];
+
+	/* the _PDC objects passed by the driver, if any */
+	struct acpi_object_list *pdc;
 };
 
 /* Performance Management */
@@ -82,8 +89,6 @@ struct acpi_processor_px {
 	acpi_integer		status;			/* success indicator */
 };
 
-#define ACPI_PDC_REVISION_ID                   0x1
-
 struct acpi_processor_performance {
 	unsigned int		 state;
 	unsigned int		 platform_limit;
@@ -179,7 +184,32 @@ int acpi_processor_notify_smm(struct mod
 extern struct acpi_processor	*processors[NR_CPUS];
 extern struct acpi_processor_errata errata;
 
+int acpi_processor_set_pdc(struct acpi_processor *pr,
+		struct acpi_object_list *pdc_in);
+
+#ifdef ARCH_HAS_POWER_PDC_INIT
+void acpi_processor_power_init_pdc(struct acpi_processor_power *pow,
+		unsigned int cpu);
+void acpi_processor_power_init_bm_check(struct acpi_processor_flags *flags,
+		unsigned int cpu);
+#else
+static inline void acpi_processor_power_init_pdc(
+		struct acpi_processor_power *pow, unsigned int cpu)
+{
+	pow->pdc = NULL;
+	return;
+}
+
+static inline void acpi_processor_power_init_bm_check(
+		struct acpi_processor_flags *flags, unsigned int cpu)
+{
+	flags->bm_check = 1;
+	return;
+}
+#endif
+
 /* in processor_perflib.c */
+
 #ifdef CONFIG_CPU_FREQ
 void acpi_processor_ppc_init(void);
 void acpi_processor_ppc_exit(void);
diff --git a/include/asm-alpha/emergency-restart.h b/include/asm-alpha/emergency-restart.h
new file mode 100644
--- /dev/null
+++ b/include/asm-alpha/emergency-restart.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_EMERGENCY_RESTART_H
+#define _ASM_EMERGENCY_RESTART_H
+
+#include <asm-generic/emergency-restart.h>
+
+#endif /* _ASM_EMERGENCY_RESTART_H */
diff --git a/include/asm-alpha/mmzone.h b/include/asm-alpha/mmzone.h
--- a/include/asm-alpha/mmzone.h
+++ b/include/asm-alpha/mmzone.h
@@ -57,7 +57,6 @@ PLAT_NODE_DATA_LOCALNR(unsigned long p, 
  * Given a kernel address, find the home node of the underlying memory.
  */
 #define kvaddr_to_nid(kaddr)	pa_to_nid(__pa(kaddr))
-#define node_mem_map(nid)	(NODE_DATA(nid)->node_mem_map)
 #define node_start_pfn(nid)	(NODE_DATA(nid)->node_start_pfn)
 
 #define local_mapnr(kvaddr) \
@@ -108,7 +107,7 @@ PLAT_NODE_DATA_LOCALNR(unsigned long p, 
 #define pfn_to_page(pfn)						\
 ({									\
  	unsigned long kaddr = (unsigned long)__va((pfn) << PAGE_SHIFT);	\
-	(node_mem_map(kvaddr_to_nid(kaddr)) + local_mapnr(kaddr));	\
+	(NODE_DATA(kvaddr_to_nid(kaddr))->node_mem_map + local_mapnr(kaddr));	\
 })
 
 #define page_to_pfn(page)						\
diff --git a/include/asm-alpha/pci.h b/include/asm-alpha/pci.h
--- a/include/asm-alpha/pci.h
+++ b/include/asm-alpha/pci.h
@@ -58,7 +58,7 @@ struct pci_controller {
 
 extern void pcibios_set_master(struct pci_dev *dev);
 
-extern inline void pcibios_penalize_isa_irq(int irq)
+extern inline void pcibios_penalize_isa_irq(int irq, int active)
 {
 	/* We don't do dynamic PCI IRQ allocation */
 }
@@ -223,6 +223,25 @@ pci_dac_dma_sync_single_for_device(struc
 	/* Nothing to do. */
 }
 
+#ifdef CONFIG_PCI
+static inline void pci_dma_burst_advice(struct pci_dev *pdev,
+					enum pci_dma_burst_strategy *strat,
+					unsigned long *strategy_parameter)
+{
+	unsigned long cacheline_size;
+	u8 byte;
+
+	pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &byte);
+	if (byte == 0)
+		cacheline_size = 1024;
+	else
+		cacheline_size = (int) byte * 4;
+
+	*strat = PCI_DMA_BURST_BOUNDARY;
+	*strategy_parameter = cacheline_size;
+}
+#endif
+
 /* TODO: integrate with include/asm-generic/pci.h ? */
 static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel)
 {
@@ -232,6 +251,9 @@ static inline int pci_get_legacy_ide_irq
 extern void pcibios_resource_to_bus(struct pci_dev *, struct pci_bus_region *,
 				    struct resource *);
 
+extern void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
+				    struct pci_bus_region *region);
+
 #define pci_domain_nr(bus) ((struct pci_controller *)(bus)->sysdata)->index
 
 static inline int pci_proc_domain(struct pci_bus *bus)
diff --git a/include/asm-alpha/pgtable.h b/include/asm-alpha/pgtable.h
--- a/include/asm-alpha/pgtable.h
+++ b/include/asm-alpha/pgtable.h
@@ -133,6 +133,12 @@
 #define __S111	_PAGE_S(0)
 
 /*
+ * pgprot_noncached() is only for infiniband pci support, and a real
+ * implementation for RAM would be more complicated.
+ */
+#define pgprot_noncached(prot)	(prot)
+
+/*
  * BAD_PAGETABLE is used when we need a bogus page-table, while
  * BAD_PAGE is used for a bogus page.
  *
diff --git a/include/asm-alpha/serial.h b/include/asm-alpha/serial.h
--- a/include/asm-alpha/serial.h
+++ b/include/asm-alpha/serial.h
@@ -22,54 +22,9 @@
 #define STD_COM4_FLAGS ASYNC_BOOT_AUTOCONF
 #endif
 
-#ifdef CONFIG_SERIAL_MANY_PORTS
-#define FOURPORT_FLAGS ASYNC_FOURPORT
-#define ACCENT_FLAGS 0
-#define BOCA_FLAGS 0
-#endif
-	
-#define STD_SERIAL_PORT_DEFNS			\
+#define SERIAL_PORT_DFNS			\
 	/* UART CLK   PORT IRQ     FLAGS        */			\
 	{ 0, BASE_BAUD, 0x3F8, 4, STD_COM_FLAGS },	/* ttyS0 */	\
 	{ 0, BASE_BAUD, 0x2F8, 3, STD_COM_FLAGS },	/* ttyS1 */	\
 	{ 0, BASE_BAUD, 0x3E8, 4, STD_COM_FLAGS },	/* ttyS2 */	\
 	{ 0, BASE_BAUD, 0x2E8, 3, STD_COM4_FLAGS },	/* ttyS3 */
-
-
-#ifdef CONFIG_SERIAL_MANY_PORTS
-#define EXTRA_SERIAL_PORT_DEFNS			\
-	{ 0, BASE_BAUD, 0x1A0, 9, FOURPORT_FLAGS }, 	/* ttyS4 */	\
-	{ 0, BASE_BAUD, 0x1A8, 9, FOURPORT_FLAGS },	/* ttyS5 */	\
-	{ 0, BASE_BAUD, 0x1B0, 9, FOURPORT_FLAGS },	/* ttyS6 */	\
-	{ 0, BASE_BAUD, 0x1B8, 9, FOURPORT_FLAGS },	/* ttyS7 */	\
-	{ 0, BASE_BAUD, 0x2A0, 5, FOURPORT_FLAGS },	/* ttyS8 */	\
-	{ 0, BASE_BAUD, 0x2A8, 5, FOURPORT_FLAGS },	/* ttyS9 */	\
-	{ 0, BASE_BAUD, 0x2B0, 5, FOURPORT_FLAGS },	/* ttyS10 */	\
-	{ 0, BASE_BAUD, 0x2B8, 5, FOURPORT_FLAGS },	/* ttyS11 */	\
-	{ 0, BASE_BAUD, 0x330, 4, ACCENT_FLAGS },	/* ttyS12 */	\
-	{ 0, BASE_BAUD, 0x338, 4, ACCENT_FLAGS },	/* ttyS13 */	\
-	{ 0, BASE_BAUD, 0x000, 0, 0 },	/* ttyS14 (spare) */		\
-	{ 0, BASE_BAUD, 0x000, 0, 0 },	/* ttyS15 (spare) */		\
-	{ 0, BASE_BAUD, 0x100, 12, BOCA_FLAGS },	/* ttyS16 */	\
-	{ 0, BASE_BAUD, 0x108, 12, BOCA_FLAGS },	/* ttyS17 */	\
-	{ 0, BASE_BAUD, 0x110, 12, BOCA_FLAGS },	/* ttyS18 */	\
-	{ 0, BASE_BAUD, 0x118, 12, BOCA_FLAGS },	/* ttyS19 */	\
-	{ 0, BASE_BAUD, 0x120, 12, BOCA_FLAGS },	/* ttyS20 */	\
-	{ 0, BASE_BAUD, 0x128, 12, BOCA_FLAGS },	/* ttyS21 */	\
-	{ 0, BASE_BAUD, 0x130, 12, BOCA_FLAGS },	/* ttyS22 */	\
-	{ 0, BASE_BAUD, 0x138, 12, BOCA_FLAGS },	/* ttyS23 */	\
-	{ 0, BASE_BAUD, 0x140, 12, BOCA_FLAGS },	/* ttyS24 */	\
-	{ 0, BASE_BAUD, 0x148, 12, BOCA_FLAGS },	/* ttyS25 */	\
-	{ 0, BASE_BAUD, 0x150, 12, BOCA_FLAGS },	/* ttyS26 */	\
-	{ 0, BASE_BAUD, 0x158, 12, BOCA_FLAGS },	/* ttyS27 */	\
-	{ 0, BASE_BAUD, 0x160, 12, BOCA_FLAGS },	/* ttyS28 */	\
-	{ 0, BASE_BAUD, 0x168, 12, BOCA_FLAGS },	/* ttyS29 */	\
-	{ 0, BASE_BAUD, 0x170, 12, BOCA_FLAGS },	/* ttyS30 */	\
-	{ 0, BASE_BAUD, 0x178, 12, BOCA_FLAGS },	/* ttyS31 */
-#else
-#define EXTRA_SERIAL_PORT_DEFNS
-#endif
-
-#define SERIAL_PORT_DFNS		\
-	STD_SERIAL_PORT_DEFNS		\
-	EXTRA_SERIAL_PORT_DEFNS
diff --git a/include/asm-alpha/smp.h b/include/asm-alpha/smp.h
--- a/include/asm-alpha/smp.h
+++ b/include/asm-alpha/smp.h
@@ -43,7 +43,7 @@ extern struct cpuinfo_alpha cpu_data[NR_
 #define PROC_CHANGE_PENALTY     20
 
 #define hard_smp_processor_id()	__hard_smp_processor_id()
-#define smp_processor_id()	(current_thread_info()->cpu)
+#define raw_smp_processor_id()	(current_thread_info()->cpu)
 
 extern cpumask_t cpu_present_mask;
 extern cpumask_t cpu_online_map;
diff --git a/include/asm-alpha/system.h b/include/asm-alpha/system.h
--- a/include/asm-alpha/system.h
+++ b/include/asm-alpha/system.h
@@ -443,22 +443,19 @@ __xchg_u64(volatile long *m, unsigned lo
    if something tries to do an invalid xchg().  */
 extern void __xchg_called_with_bad_pointer(void);
 
-static inline unsigned long
-__xchg(volatile void *ptr, unsigned long x, int size)
-{
-	switch (size) {
-		case 1:
-			return __xchg_u8(ptr, x);
-		case 2:
-			return __xchg_u16(ptr, x);
-		case 4:
-			return __xchg_u32(ptr, x);
-		case 8:
-			return __xchg_u64(ptr, x);
-	}
-	__xchg_called_with_bad_pointer();
-	return x;
-}
+#define __xchg(ptr, x, size) \
+({ \
+	unsigned long __xchg__res; \
+	volatile void *__xchg__ptr = (ptr); \
+	switch (size) { \
+		case 1: __xchg__res = __xchg_u8(__xchg__ptr, x); break; \
+		case 2: __xchg__res = __xchg_u16(__xchg__ptr, x); break; \
+		case 4: __xchg__res = __xchg_u32(__xchg__ptr, x); break; \
+		case 8: __xchg__res = __xchg_u64(__xchg__ptr, x); break; \
+		default: __xchg_called_with_bad_pointer(); __xchg__res = x; \
+	} \
+	__xchg__res; \
+})
 
 #define xchg(ptr,x)							     \
   ({									     \
diff --git a/include/asm-alpha/unistd.h b/include/asm-alpha/unistd.h
--- a/include/asm-alpha/unistd.h
+++ b/include/asm-alpha/unistd.h
@@ -377,8 +377,13 @@
 #define __NR_add_key			439
 #define __NR_request_key		440
 #define __NR_keyctl			441
+#define __NR_ioprio_set			442
+#define __NR_ioprio_get			443
+#define __NR_inotify_init		444
+#define __NR_inotify_add_watch		445
+#define __NR_inotify_rm_watch		446
 
-#define NR_SYSCALLS			442
+#define NR_SYSCALLS			447
 
 #if defined(__GNUC__)
 
diff --git a/include/asm-arm/arch-aaec2000/aaec2000.h b/include/asm-arm/arch-aaec2000/aaec2000.h
new file mode 100644
--- /dev/null
+++ b/include/asm-arm/arch-aaec2000/aaec2000.h
@@ -0,0 +1,151 @@
+/*
+ *  linux/include/asm-arm/arch-aaec2000/aaec2000.h
+ *
+ *  AAEC-2000 registers definition
+ *
+ *  Copyright (c) 2005 Nicolas Bellido Y Ortega
+ *
+ *  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.
+ */
+
+#ifndef __ASM_ARCH_AAEC2000_H
+#define __ASM_ARCH_AAEC2000_H
+
+#ifndef __ASM_ARCH_HARDWARE_H
+#error You must include hardware.h not this file
+#endif /* __ASM_ARCH_HARDWARE_H */
+
+/* Interrupt controller */
+#define IRQ_BASE	__REG(0x80000500)
+#define IRQ_INTSR	__REG(0x80000500)	/* Int Status Register */
+#define IRQ_INTRSR	__REG(0x80000504)	/* Int Raw (unmasked) Status */
+#define IRQ_INTENS	__REG(0x80000508)	/* Int Enable Set */
+#define IRQ_INTENC	__REG(0x8000050c)	/* Int Enable Clear */
+
+/* UART 1 */
+#define UART1_BASE	__REG(0x80000600)
+#define UART1_DR	__REG(0x80000600) /* Data/FIFO Register */
+#define UART1_LCR	__REG(0x80000604) /* Link Control Register */
+#define UART1_BRCR	__REG(0x80000608) /* Baud Rate Control Register */
+#define UART1_CR	__REG(0x8000060c) /* Control Register */
+#define UART1_SR	__REG(0x80000610) /* Status Register */
+#define UART1_INT	__REG(0x80000614) /* Interrupt Status Register */
+#define UART1_INTM	__REG(0x80000618) /* Interrupt Mask Register */
+#define UART1_INTRES	__REG(0x8000061c) /* Int Result (masked status) Register */
+
+/* UART 2 */
+#define UART2_BASE	__REG(0x80000700)
+#define UART2_DR	__REG(0x80000700) /* Data/FIFO Register */
+#define UART2_LCR	__REG(0x80000704) /* Link Control Register */
+#define UART2_BRCR	__REG(0x80000708) /* Baud Rate Control Register */
+#define UART2_CR	__REG(0x8000070c) /* Control Register */
+#define UART2_SR	__REG(0x80000710) /* Status Register */
+#define UART2_INT	__REG(0x80000714) /* Interrupt Status Register */
+#define UART2_INTM	__REG(0x80000718) /* Interrupt Mask Register */
+#define UART2_INTRES	__REG(0x8000071c) /* Int Result (masked status) Register */
+
+/* UART 3 */
+#define UART3_BASE	__REG(0x80000800)
+#define UART3_DR	__REG(0x80000800) /* Data/FIFO Register */
+#define UART3_LCR	__REG(0x80000804) /* Link Control Register */
+#define UART3_BRCR	__REG(0x80000808) /* Baud Rate Control Register */
+#define UART3_CR	__REG(0x8000080c) /* Control Register */
+#define UART3_SR	__REG(0x80000810) /* Status Register */
+#define UART3_INT	__REG(0x80000814) /* Interrupt Status Register */
+#define UART3_INTM	__REG(0x80000818) /* Interrupt Mask Register */
+#define UART3_INTRES	__REG(0x8000081c) /* Int Result (masked status) Register */
+
+/* These are used in some places */
+#define _UART1_BASE __PREG(UART1_BASE)
+#define _UART2_BASE __PREG(UART2_BASE)
+#define _UART3_BASE __PREG(UART3_BASE)
+
+/* UART Registers Offsets */
+#define UART_DR		0x00
+#define UART_LCR	0x04
+#define UART_BRCR	0x08
+#define UART_CR		0x0c
+#define UART_SR		0x10
+#define UART_INT	0x14
+#define UART_INTM	0x18
+#define UART_INTRES	0x1c
+
+/* UART_LCR Bitmask */
+#define UART_LCR_BRK	(1 << 0) /* Send Break */
+#define UART_LCR_PEN	(1 << 1) /* Parity Enable */
+#define UART_LCR_EP	(1 << 2) /* Even/Odd Parity */
+#define UART_LCR_S2	(1 << 3) /* One/Two Stop bits */
+#define UART_LCR_FIFO	(1 << 4) /* FIFO Enable */
+#define UART_LCR_WL5	(0 << 5) /* Word Length - 5 bits */
+#define UART_LCR_WL6	(1 << 5) /* Word Length - 6 bits */
+#define UART_LCR_WL7	(1 << 6) /* Word Length - 7 bits */
+#define UART_LCR_WL8	(1 << 7) /* Word Length - 8 bits */
+
+/* UART_CR Bitmask */
+#define UART_CR_EN	(1 << 0) /* UART Enable */
+#define UART_CR_SIR	(1 << 1) /* IrDA SIR Enable */
+#define UART_CR_SIRLP	(1 << 2) /* Low Power IrDA Enable */
+#define UART_CR_RXP	(1 << 3) /* Receive Pin Polarity */
+#define UART_CR_TXP	(1 << 4) /* Transmit Pin Polarity */
+#define UART_CR_MXP	(1 << 5) /* Modem Pin Polarity */
+#define UART_CR_LOOP	(1 << 6) /* Loopback Mode */
+
+/* UART_SR Bitmask */
+#define UART_SR_CTS	(1 << 0) /* Clear To Send Status */
+#define UART_SR_DSR	(1 << 1) /* Data Set Ready Status */
+#define UART_SR_DCD	(1 << 2) /* Data Carrier Detect Status */
+#define UART_SR_TxBSY	(1 << 3) /* Transmitter Busy Status */
+#define UART_SR_RxFE	(1 << 4) /* Receive FIFO Empty Status */
+#define UART_SR_TxFF	(1 << 5) /* Transmit FIFO Full Status */
+#define UART_SR_RxFF	(1 << 6) /* Receive FIFO Full Status */
+#define UART_SR_TxFE	(1 << 7) /* Transmit FIFO Empty Status */
+
+/* UART_INT Bitmask */
+#define UART_INT_RIS	(1 << 0) /* Rx Interrupt */
+#define UART_INT_TIS	(1 << 1) /* Tx Interrupt */
+#define UART_INT_MIS	(1 << 2) /* Modem Interrupt */
+#define UART_INT_RTIS	(1 << 3) /* Receive Timeout Interrupt */
+
+/* Timer 1 */
+#define TIMER1_BASE	__REG(0x80000c00)
+#define TIMER1_LOAD	__REG(0x80000c00)	/* Timer 1 Load Register */
+#define TIMER1_VAL	__REG(0x80000c04)	/* Timer 1 Value Register */
+#define TIMER1_CTRL	__REG(0x80000c08)	/* Timer 1 Control Register */
+#define TIMER1_CLEAR	__REG(0x80000c0c)	/* Timer 1 Clear Register */
+
+/* Timer 2 */
+#define TIMER2_BASE	__REG(0x80000d00)
+#define TIMER2_LOAD	__REG(0x80000d00)	/* Timer 2 Load Register */
+#define TIMER2_VAL	__REG(0x80000d04)	/* Timer 2 Value Register */
+#define TIMER2_CTRL	__REG(0x80000d08)	/* Timer 2 Control Register */
+#define TIMER2_CLEAR	__REG(0x80000d0c)	/* Timer 2 Clear Register */
+
+/* Timer 3 */
+#define TIMER3_BASE	__REG(0x80000e00)
+#define TIMER3_LOAD	__REG(0x80000e00)	/* Timer 3 Load Register */
+#define TIMER3_VAL	__REG(0x80000e04)	/* Timer 3 Value Register */
+#define TIMER3_CTRL	__REG(0x80000e08)	/* Timer 3 Control Register */
+#define TIMER3_CLEAR	__REG(0x80000e0c)	/* Timer 3 Clear Register */
+
+/* Timer Control register bits */
+#define TIMER_CTRL_ENABLE	(1 << 7) /* Enable (StartÂ° Timer */
+#define TIMER_CTRL_PERIODIC	(1 << 6) /* Periodic Running Mode */
+#define TIMER_CTRL_FREE_RUNNING (0 << 6) /* Normal Running Mode */
+#define TIMER_CTRL_CLKSEL_508K	(1 << 3) /* 508KHz Clock select (Timer 1, 2) */
+#define TIMER_CTRL_CLKSEL_2K	(0 << 3) /* 2KHz Clock Select (Timer 1, 2)*/
+
+/* Power and State Control */
+#define POWER_BASE	__REG(0x80000400)
+#define POWER_PWRSR	__REG(0x80000400) /* Power Status Register */
+#define POWER_PWRCNT	__REG(0x80000404) /* Power/Clock control */
+#define POWER_HALT	__REG(0x80000408) /* Power Idle Mode */
+#define POWER_STDBY	__REG(0x8000040c) /* Power Standby Mode */
+#define POWER_BLEOI	__REG(0x80000410) /* Battery Low End of Interrupt */
+#define POWER_MCEOI	__REG(0x80000414) /* Media Changed EoI */
+#define POWER_TEOI	__REG(0x80000418) /* Tick EoI */
+#define POWER_STFCLR	__REG(0x8000041c) /* NbFlg, RSTFlg, PFFlg, CLDFlg Clear */
+#define POWER_CLKSET	__REG(0x80000420) /* Clock Speed Control */
+
+#endif /* __ARM_ARCH_AAEC2000_H */
diff --git a/include/asm-arm/arch-aaec2000/debug-macro.S b/include/asm-arm/arch-aaec2000/debug-macro.S
new file mode 100644
--- /dev/null
+++ b/include/asm-arm/arch-aaec2000/debug-macro.S
@@ -0,0 +1,36 @@
+/*  linux/include/asm-arm/arch-aaec2000/debug-macro.S
+ *
+ *  Debugging macro include header
+ *
+ *  Copyright (c) 2005 Nicolas Bellido Y Ortega
+ *
+ *  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.
+ */
+
+		.macro	addruart,rx
+		mrc	p15, 0, \rx, c1, c0
+		tst	\rx, #1			@ MMU enabled?
+		moveq	\rx, #0x80000000		@ physical
+		movne	\rx, #io_p2v(0x80000000)	@ virtual
+		orr	\rx, \rx, #0x00000800
+		.endm
+
+		.macro	senduart,rd,rx
+		str	\rd, [\rx, #0]
+		.endm
+
+		.macro	busyuart,rd,rx
+1002:		ldr	\rd, [\rx, #0x10]
+		tst	\rd, #(1 << 7)
+		beq	1002b
+		.endm
+
+		.macro	waituart,rd,rx
+#if 0
+1001:		ldr	\rd, [\rx, #0x10]
+		tst	\rd, #(1 << 5)
+		beq	1001b
+#endif
+		.endm
diff --git a/include/asm-arm/arch-aaec2000/dma.h b/include/asm-arm/arch-aaec2000/dma.h
new file mode 100644
--- /dev/null
+++ b/include/asm-arm/arch-aaec2000/dma.h
@@ -0,0 +1,17 @@
+/*
+ *  linux/include/asm-arm/arch-aaec2000/dma.h
+ *
+ *  Copyright (c) 2005 Nicolas Bellido Y Ortega
+ *
+ *  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.
+ */
+
+#ifndef __ASM_ARCH_DMA_H
+#define __ASM_ARCH_DMA_H
+
+#define MAX_DMA_ADDRESS         0xffffffff
+#define MAX_DMA_CHANNELS        0
+
+#endif
diff --git a/include/asm-arm/arch-aaec2000/entry-macro.S b/include/asm-arm/arch-aaec2000/entry-macro.S
new file mode 100644
--- /dev/null
+++ b/include/asm-arm/arch-aaec2000/entry-macro.S
@@ -0,0 +1,33 @@
+/*
+ *  linux/include/asm-arm/arch-aaec2000/entry-macro.S
+ *
+ *  Low-level IRQ helper for aaec-2000 based platforms
+ *
+ *  Copyright (c) 2005 Nicolas Bellido Y Ortega
+ *
+ *  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.
+ *
+ */
+
+		.macro	disable_fiq
+		.endm
+
+		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
+		mov	r4, #0xf8000000
+		add	r4, r4, #0x00000500
+		mov	\base, r4
+		ldr	\irqstat, [\base, #0]
+		cmp	\irqstat, #0
+		bne	1001f
+		ldr	\irqnr, =NR_IRQS+1
+		b       1003f
+1001:		mov	\irqnr, #0
+1002:		ands	\tmp, \irqstat, #1
+		mov	\irqstat, \irqstat, LSR #1
+		add	\irqnr, \irqnr, #1
+		beq	1002b
+		sub	\irqnr, \irqnr, #1
+1003:
+		.endm
diff --git a/include/asm-arm/arch-aaec2000/hardware.h b/include/asm-arm/arch-aaec2000/hardware.h
new file mode 100644
--- /dev/null
+++ b/include/asm-arm/arch-aaec2000/hardware.h
@@ -0,0 +1,49 @@
+/*
+ *  linux/include/asm-arm/arch-aaec2000/hardware.h
+ *
+ *  Copyright (c) 2005 Nicolas Bellido Y Ortega
+ *
+ *  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.
+ */
+
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+#include <linux/config.h>
+
+/* The kernel is loaded at physical address 0xf8000000.
+ * We map the IO space a bit after
+ */
+#define PIO_APB_BASE	0x80000000
+#define VIO_APB_BASE	0xf8000000
+#define IO_APB_LENGTH	0x2000
+#define PIO_AHB_BASE	0x80002000
+#define VIO_AHB_BASE	0xf8002000
+#define IO_AHB_LENGTH	0x2000
+
+#define VIO_BASE    VIO_APB_BASE
+#define PIO_BASE    PIO_APB_BASE
+
+#define io_p2v(x) ( (x) - PIO_BASE + VIO_BASE )
+#define io_v2p(x) ( (x) + PIO_BASE - VIO_BASE )
+
+#ifndef __ASSEMBLY__
+
+#include <asm/types.h>
+
+/* FIXME: Is it needed to optimize this a la pxa ?? */
+#define __REG(x)    (*((volatile u32 *)io_p2v(x)))
+#define __PREG(x)   (io_v2p((u32)&(x)))
+
+#else /* __ASSEMBLY__ */
+
+#define __REG(x)    io_p2v(x)
+#define __PREG(x)   io_v2p(x)
+
+#endif
+
+#include "aaec2000.h"
+
+#endif /* __ASM_ARCH_HARDWARE_H */
diff --git a/include/asm-arm/arch-aaec2000/io.h b/include/asm-arm/arch-aaec2000/io.h
new file mode 100644
--- /dev/null
+++ b/include/asm-arm/arch-aaec2000/io.h
@@ -0,0 +1,19 @@
+/*
+ *  linux/include/asm-arm/arch-aaec2000/io.h
+ *
+ *  Copied from asm/arch/sa1100/io.h
+ */
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+/*
+ * We don't actually have real ISA nor PCI buses, but there is so many
+ * drivers out there that might just work if we fake them...
+ */
+#define __io(a)			((void __iomem *)(a))
+#define __mem_pci(a)		(a)
+#define __mem_isa(a)		(a)
+
+#endif
diff --git a/include/asm-arm/arch-aaec2000/irqs.h b/include/asm-arm/arch-aaec2000/irqs.h
new file mode 100644
--- /dev/null
+++ b/include/asm-arm/arch-aaec2000/irqs.h
@@ -0,0 +1,46 @@
+/*
+ *  linux/include/asm-arm/arch-aaec2000/irqs.h
+ *
+ *  Copyright (c) 2005 Nicolas Bellido Y Ortega
+ *
+ *  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.
+ */
+
+#ifndef __ASM_ARCH_IRQS_H
+#define __ASM_ARCH_IRQS_H
+
+
+#define INT_GPIOF0_FIQ	0  /* External GPIO Port F O Fast Interrupt Input */
+#define INT_BL_FIQ	1  /* Battery Low Fast Interrupt */
+#define INT_WE_FIQ	2  /* Watchdog Expired Fast Interrupt */
+#define INT_MV_FIQ	3  /* Media Changed Interrupt */
+#define INT_SC		4  /* Sound Codec Interrupt */
+#define INT_GPIO1	5  /* GPIO Port F Configurable Int 1 */
+#define INT_GPIO2	6  /* GPIO Port F Configurable Int 2 */
+#define INT_GPIO3	7  /* GPIO Port F Configurable Int 3 */
+#define INT_TMR1_OFL	8  /* Timer 1 Overflow Interrupt */
+#define INT_TMR2_OFL	9  /* Timer 2 Overflow Interrupt */
+#define INT_RTC_CM	10 /* RTC Compare Match Interrupt */
+#define INT_TICK	11 /* 64Hz Tick Interrupt */
+#define INT_UART1	12 /* UART1 Interrupt */
+#define INT_UART2	13 /* UART2 & Modem State Changed Interrupt */
+#define INT_LCD		14 /* LCD Interrupt */
+#define INT_SSI		15 /* SSI End of Transfer Interrupt */
+#define INT_UART3	16 /* UART3 Interrupt */
+#define INT_SCI		17 /* SCI Interrupt */
+#define INT_AAC		18 /* Advanced Audio Codec Interrupt */
+#define INT_MMC		19 /* MMC Interrupt */
+#define INT_USB		20 /* USB Interrupt */
+#define INT_DMA		21 /* DMA Interrupt */
+#define INT_TMR3_UOFL	22 /* Timer 3 Underflow Interrupt */
+#define INT_GPIO4	23 /* GPIO Port F Configurable Int 4 */
+#define INT_GPIO5	24 /* GPIO Port F Configurable Int 4 */
+#define INT_GPIO6	25 /* GPIO Port F Configurable Int 4 */
+#define INT_GPIO7	26 /* GPIO Port F Configurable Int 4 */
+#define INT_BMI		27 /* BMI Interrupt */
+
+#define NR_IRQS		(INT_BMI + 1)
+
+#endif /* __ASM_ARCH_IRQS_H */
diff --git a/include/asm-arm/arch-aaec2000/memory.h b/include/asm-arm/arch-aaec2000/memory.h
new file mode 100644
--- /dev/null
+++ b/include/asm-arm/arch-aaec2000/memory.h
@@ -0,0 +1,73 @@
+/*
+ *  linux/include/asm-arm/arch-aaec2000/memory.h
+ *
+ *  Copyright (c) 2005 Nicolas Bellido Y Ortega
+ *
+ *  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.
+ */
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+#include <linux/config.h>
+
+#define PHYS_OFFSET	(0xf0000000UL)
+
+#define __virt_to_bus(x)	__virt_to_phys(x)
+#define __bus_to_virt(x)	__phys_to_virt(x)
+
+#ifdef CONFIG_DISCONTIGMEM
+
+/*
+ * The nodes are the followings:
+ *
+ *   node 0: 0xf000.0000 - 0xf3ff.ffff
+ *   node 1: 0xf400.0000 - 0xf7ff.ffff
+ *   node 2: 0xf800.0000 - 0xfbff.ffff
+ *   node 3: 0xfc00.0000 - 0xffff.ffff
+ */
+
+/*
+ * Given a kernel address, find the home node of the underlying memory.
+ */
+#define KVADDR_TO_NID(addr) \
+	(((unsigned long)(addr) - PAGE_OFFSET) >> NODE_MAX_MEM_SHIFT)
+
+/*
+ * Given a page frame number, convert it to a node id.
+ */
+#define PFN_TO_NID(pfn) \
+	(((pfn) - PHYS_PFN_OFFSET) >> (NODE_MAX_MEM_SHIFT - PAGE_SHIFT))
+
+/*
+ * Given a kaddr, ADDR_TO_MAPBASE finds the owning node of the memory
+ * and return the mem_map of that node.
+ */
+#define ADDR_TO_MAPBASE(kaddr)  NODE_MEM_MAP(KVADDR_TO_NID(kaddr))
+
+/*
+ * Given a page frame number, find the owning node of the memory
+ * and return the mem_map of that node.
+ */
+#define PFN_TO_MAPBASE(pfn)     NODE_MEM_MAP(PFN_TO_NID(pfn))
+
+/*
+ *  Given a kaddr, LOCAL_MEM_MAP finds the owning node of the memory
+ *  and returns the index corresponding to the appropriate page in the
+ *  node's mem_map.
+ */
+#define LOCAL_MAP_NR(addr) \
+        (((unsigned long)(addr) & (NODE_MAX_MEM_SIZE - 1)) >> PAGE_SHIFT)
+
+#define NODE_MAX_MEM_SHIFT	26
+#define NODE_MAX_MEM_SIZE	(1 << NODE_MAX_MEM_SHIFT)
+
+#else
+
+#define PFN_TO_NID(addr)	(0)
+
+#endif /* CONFIG_DISCONTIGMEM */
+
+#endif /* __ASM_ARCH_MEMORY_H */
diff --git a/include/asm-arm/arch-aaec2000/param.h b/include/asm-arm/arch-aaec2000/param.h
new file mode 100644
--- /dev/null
+++ b/include/asm-arm/arch-aaec2000/param.h
@@ -0,0 +1,15 @@
+/*
+ *  linux/include/asm-arm/arch-aaec2000/param.h
+ *
+ *  Copyright (c) 2005 Nicolas Bellido Y Ortega
+ *
+ *  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.
+ */
+
+#ifndef __ASM_ARCH_PARAM_H
+#define __ASM_ARCH_PARAM_H
+
+#endif /* __ASM_ARCH_PARAM_H */
+
diff --git a/include/asm-arm/arch-aaec2000/system.h b/include/asm-arm/arch-aaec2000/system.h
new file mode 100644
--- /dev/null
+++ b/include/asm-arm/arch-aaec2000/system.h
@@ -0,0 +1,24 @@
+/*
+ *  linux/include/asm-arm/arch-aaed2000/system.h
+ *
+ *  Copyright (c) 2005 Nicolas Bellido Y Ortega
+ *
+ *  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.
+ */
+
+#ifndef __ASM_ARCH_SYSTEM_H
+#define __ASM_ARCH_SYSTEM_H
+
+static inline void arch_idle(void)
+{
+	cpu_do_idle();
+}
+
+static inline void arch_reset(char mode)
+{
+	cpu_reset(0);
+}
+
+#endif /* __ASM_ARCH_SYSTEM_H */
diff --git a/include/asm-arm/arch-aaec2000/timex.h b/include/asm-arm/arch-aaec2000/timex.h
new file mode 100644
--- /dev/null
+++ b/include/asm-arm/arch-aaec2000/timex.h
@@ -0,0 +1,18 @@
+/*
+ *  linux/include/asm-arm/arch-aaec2000/timex.h
+ *
+ *  AAEC-2000 Architecture timex specification
+ *
+ *  Copyright (c) 2005 Nicolas Bellido Y Ortega
+ *
+ *  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.
+ */
+
+#ifndef __ASM_ARCH_TIMEX_H
+#define __ASM_ARCH_TIMEX_H
+
+#define CLOCK_TICK_RATE		508000
+
+#endif /* __ASM_ARCH_TIMEX_H */
diff --git a/include/asm-arm/arch-aaec2000/uncompress.h b/include/asm-arm/arch-aaec2000/uncompress.h
new file mode 100644
--- /dev/null
+++ b/include/asm-arm/arch-aaec2000/uncompress.h
@@ -0,0 +1,47 @@
+/*
+ *  linux/include/asm-arm/arch-aaec2000/uncompress.h
+ *
+ *  Copyright (c) 2005 Nicolas Bellido Y Ortega
+ *
+ *  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.
+ */
+
+#ifndef __ASM_ARCH_UNCOMPRESS_H
+#define __ASM_ARCH_UNCOMPRESS_H
+
+#include "hardware.h"
+
+#define UART(x)         (*(volatile unsigned long *)(serial_port + (x)))
+
+static void putstr( const char *s )
+{
+	unsigned long serial_port;
+        do {
+		serial_port = _UART3_BASE;
+		if (UART(UART_CR) & UART_CR_EN) break;
+		serial_port = _UART1_BASE;
+		if (UART(UART_CR) & UART_CR_EN) break;
+		serial_port = _UART2_BASE;
+		if (UART(UART_CR) & UART_CR_EN) break;
+		return;
+	} while (0);
+
+	for (; *s; s++) {
+		/* wait for space in the UART's transmitter */
+		while ((UART(UART_SR) & UART_SR_TxFF));
+		/* send the character out. */
+		UART(UART_DR) = *s;
+		/* if a LF, also do CR... */
+		if (*s == 10) {
+			while ((UART(UART_SR) & UART_SR_TxFF));
+			UART(UART_DR) = 13;
+		}
+	}
+}
+
+#define arch_decomp_setup()
+#define arch_decomp_wdog()
+
+#endif /* __ASM_ARCH_UNCOMPRESS_H */
diff --git a/include/asm-arm/arch-aaec2000/vmalloc.h b/include/asm-arm/arch-aaec2000/vmalloc.h
new file mode 100644
--- /dev/null
+++ b/include/asm-arm/arch-aaec2000/vmalloc.h
@@ -0,0 +1,16 @@
+/*
+ *  linux/include/asm-arm/arch-aaec2000/vmalloc.h
+ *
+ *  Copyright (c) 2005 Nicolas Bellido Y Ortega
+ *
+ *  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.
+ */
+
+#ifndef __ASM_ARCH_VMALLOC_H
+#define __ASM_ARCH_VMALLOC_H
+
+#define VMALLOC_END		(PAGE_OFFSET + 0x10000000)
+
+#endif /* __ASM_ARCH_VMALLOC_H */
diff --git a/include/asm-arm/arch-imx/imxfb.h b/include/asm-arm/arch-imx/imxfb.h
--- a/include/asm-arm/arch-imx/imxfb.h
+++ b/include/asm-arm/arch-imx/imxfb.h
@@ -25,6 +25,7 @@ struct imxfb_mach_info {
 	u_int		pcr;
 	u_int		pwmr;
 	u_int		lscr1;
+	u_int		dmacr;
 
 	u_char * fixed_screen_cpu;
 	dma_addr_t fixed_screen_dma;
diff --git a/include/asm-arm/arch-integrator/smp.h b/include/asm-arm/arch-integrator/smp.h
new file mode 100644
--- /dev/null
+++ b/include/asm-arm/arch-integrator/smp.h
@@ -0,0 +1,19 @@
+#ifndef ASMARM_ARCH_SMP_H
+#define ASMARM_ARCH_SMP_H
+
+#include <linux/config.h>
+
+#include <asm/arch/hardware.h>
+#include <asm/io.h>
+
+#define hard_smp_processor_id()				\
+	({						\
+		unsigned int cpunum;			\
+		__asm__("mrc p15, 0, %0, c0, c0, 5"	\
+			: "=r" (cpunum));		\
+		cpunum &= 0x0F;				\
+	})
+
+extern void secondary_scan_irqs(void);
+
+#endif
diff --git a/include/asm-arm/arch-ixp2000/gpio.h b/include/asm-arm/arch-ixp2000/gpio.h
--- a/include/asm-arm/arch-ixp2000/gpio.h
+++ b/include/asm-arm/arch-ixp2000/gpio.h
@@ -1,5 +1,5 @@
 /*
- * include/asm-arm/arch-ixp2000/ixp2000-gpio.h
+ * include/asm-arm/arch-ixp2000/gpio.h
  *
  * Copyright (C) 2002 Intel Corporation.
  *
@@ -16,26 +16,18 @@
  * Use this instead of directly setting the GPIO registers.
  * GPIOs may also be used as GPIOs (e.g. for emulating i2c/smb)
  */
-#ifndef _ASM_ARCH_IXP2000_GPIO_H_
-#define _ASM_ARCH_IXP2000_GPIO_H_
+#ifndef __ASM_ARCH_GPIO_H
+#define __ASM_ARCH_GPIO_H
 
 #ifndef __ASSEMBLY__
-#define GPIO_OUT			0x0
-#define GPIO_IN				0x80
+
+#define GPIO_IN				0
+#define GPIO_OUT			1
 
 #define IXP2000_GPIO_LOW		0
 #define IXP2000_GPIO_HIGH		1
 
-#define GPIO_NO_EDGES           	0
-#define GPIO_FALLING_EDGE       	1
-#define GPIO_RISING_EDGE        	2
-#define GPIO_BOTH_EDGES         	3
-#define GPIO_LEVEL_LOW          	4
-#define GPIO_LEVEL_HIGH         	8
-
-extern void set_GPIO_IRQ_edge(int gpio_nr, int edge);
-extern void set_GPIO_IRQ_level(int gpio_nr, int level);
-extern void gpio_line_config(int line, int style);
+extern void gpio_line_config(int line, int direction);
 
 static inline int gpio_line_get(int line)
 {
@@ -45,11 +37,12 @@ static inline int gpio_line_get(int line
 static inline void gpio_line_set(int line, int value)
 {
 	if (value == IXP2000_GPIO_HIGH) {
-		ixp_reg_write(IXP2000_GPIO_POSR, BIT(line));
-	} else if (value == IXP2000_GPIO_LOW)
-		ixp_reg_write(IXP2000_GPIO_POCR, BIT(line));
+		ixp2000_reg_write(IXP2000_GPIO_POSR, 1 << line);
+	} else if (value == IXP2000_GPIO_LOW) {
+		ixp2000_reg_write(IXP2000_GPIO_POCR, 1 << line);
+	}
 }
 
 #endif /* !__ASSEMBLY__ */
-#endif /* ASM_ARCH_IXP2000_GPIO_H_ */
 
+#endif /* ASM_ARCH_IXP2000_GPIO_H_ */
diff --git a/include/asm-arm/arch-ixp2000/io.h b/include/asm-arm/arch-ixp2000/io.h
--- a/include/asm-arm/arch-ixp2000/io.h
+++ b/include/asm-arm/arch-ixp2000/io.h
@@ -17,18 +17,23 @@
 
 #define IO_SPACE_LIMIT		0xffffffff
 #define __mem_pci(a)		(a)
-#define ___io(p)		((void __iomem *)((p)+IXP2000_PCI_IO_VIRT_BASE))
 
 /*
- * The IXP2400 before revision B0 asserts byte lanes for PCI I/O
+ * The A? revisions of the IXP2000s assert byte lanes for PCI I/O
  * transactions the other way round (MEM transactions don't have this
- * issue), so we need to override the standard functions.  B0 and later
- * have a bit that can be set to 1 to get the 'proper' behavior, but
- * since that isn't available on the A? revisions we just keep doing
- * things manually.
+ * issue), so if we want to support those models, we need to override
+ * the standard I/O functions.
+ *
+ * B0 and later have a bit that can be set to 1 to get the proper
+ * behavior for I/O transactions, which then allows us to use the
+ * standard I/O functions.  This is what we do if the user does not
+ * explicitly ask for support for pre-B0.
  */
-#define alignb(addr)		(void __iomem *)((unsigned long)addr ^ 3)
-#define alignw(addr)		(void __iomem *)((unsigned long)addr ^ 2)
+#ifdef CONFIG_IXP2000_SUPPORT_BROKEN_PCI_IO
+#define ___io(p)		((void __iomem *)((p)+IXP2000_PCI_IO_VIRT_BASE))
+
+#define alignb(addr)		(void __iomem *)((unsigned long)(addr) ^ 3)
+#define alignw(addr)		(void __iomem *)((unsigned long)(addr) ^ 2)
 
 #define outb(v,p)		__raw_writeb((v),alignb(___io(p)))
 #define outw(v,p)		__raw_writew((v),alignw(___io(p)))
@@ -48,6 +53,81 @@
 #define insw(p,d,l)		__raw_readsw(alignw(___io(p)),d,l)
 #define insl(p,d,l)		__raw_readsl(___io(p),d,l)
 
+#define __is_io_address(p)	((((unsigned long)(p)) & ~(IXP2000_PCI_IO_SIZE - 1)) == IXP2000_PCI_IO_VIRT_BASE)
+
+#define ioread8(p)						\
+	({							\
+		unsigned int __v;				\
+								\
+		if (__is_io_address(p)) {			\
+			__v = __raw_readb(alignb(p));		\
+		} else {					\
+			__v = __raw_readb(p);			\
+		}						\
+								\
+		__v;						\
+	})							\
+
+#define ioread16(p)						\
+	({							\
+		unsigned int __v;				\
+								\
+		if (__is_io_address(p)) {			\
+			__v = __raw_readw(alignw(p));		\
+		} else {					\
+			__v = le16_to_cpu(__raw_readw(p));	\
+		}						\
+								\
+		__v;						\
+	})
+
+#define ioread32(p)						\
+	({							\
+		unsigned int __v;				\
+								\
+		if (__is_io_address(p)) {			\
+			__v = __raw_readl(p);			\
+		} else {					\
+			__v = le32_to_cpu(__raw_readl(p));	\
+		}						\
+								\
+		 __v;						\
+	})
+
+#define iowrite8(v,p)						\
+	({							\
+		if (__is_io_address(p)) {			\
+			__raw_writeb((v), alignb(p));		\
+		} else {					\
+			__raw_writeb((v), p);			\
+		}						\
+	})
+
+#define iowrite16(v,p)						\
+	({							\
+		if (__is_io_address(p)) {			\
+			__raw_writew((v), alignw(p));		\
+		} else {					\
+			__raw_writew(cpu_to_le16(v), p);	\
+		}						\
+	})
+
+#define iowrite32(v,p)						\
+	({							\
+		if (__is_io_address(p)) {			\
+			__raw_writel((v), p);			\
+		} else {					\
+			__raw_writel(cpu_to_le32(v), p);	\
+		}						\
+	})
+
+#define ioport_map(port, nr)	___io(port)
+
+#define ioport_unmap(addr)
+#else
+#define __io(p)			((void __iomem *)((p)+IXP2000_PCI_IO_VIRT_BASE))
+#endif
+
 
 #ifdef CONFIG_ARCH_IXDP2X01
 /*
diff --git a/include/asm-arm/arch-ixp2000/ixdp2x00.h b/include/asm-arm/arch-ixp2000/ixdp2x00.h
--- a/include/asm-arm/arch-ixp2000/ixdp2x00.h
+++ b/include/asm-arm/arch-ixp2000/ixdp2x00.h
@@ -21,8 +21,8 @@
  * On board CPLD memory map
  */
 #define IXDP2X00_PHYS_CPLD_BASE		0xc7000000
-#define IXDP2X00_VIRT_CPLD_BASE		0xfafff000
-#define IXDP2X00_CPLD_SIZE		0x00001000
+#define IXDP2X00_VIRT_CPLD_BASE		0xfe000000
+#define IXDP2X00_CPLD_SIZE		0x00100000
 
 
 #define IXDP2X00_CPLD_REG(x)  	\
diff --git a/include/asm-arm/arch-ixp2000/ixdp2x01.h b/include/asm-arm/arch-ixp2000/ixdp2x01.h
--- a/include/asm-arm/arch-ixp2000/ixdp2x01.h
+++ b/include/asm-arm/arch-ixp2000/ixdp2x01.h
@@ -18,8 +18,8 @@
 #define __IXDP2X01_H__
 
 #define	IXDP2X01_PHYS_CPLD_BASE		0xc6024000
-#define	IXDP2X01_VIRT_CPLD_BASE		0xfafff000
-#define	IXDP2X01_CPLD_REGION_SIZE	0x00001000
+#define	IXDP2X01_VIRT_CPLD_BASE		0xfe000000
+#define	IXDP2X01_CPLD_REGION_SIZE	0x00100000
 
 #define IXDP2X01_CPLD_VIRT_REG(reg) (volatile unsigned long*)(IXDP2X01_VIRT_CPLD_BASE | reg)
 #define IXDP2X01_CPLD_PHYS_REG(reg) (volatile u32*)(IXDP2X01_PHYS_CPLD_BASE | reg)
diff --git a/include/asm-arm/arch-ixp2000/ixp2000-regs.h b/include/asm-arm/arch-ixp2000/ixp2000-regs.h
--- a/include/asm-arm/arch-ixp2000/ixp2000-regs.h
+++ b/include/asm-arm/arch-ixp2000/ixp2000-regs.h
@@ -18,6 +18,21 @@
 #ifndef _IXP2000_REGS_H_
 #define _IXP2000_REGS_H_
 
+/*
+ * IXP2000 linux memory map:
+ *
+ * virt		phys		size
+ * fb000000	db000000	16M		PCI CFG1
+ * fc000000	da000000	16M		PCI CFG0
+ * fd000000	d8000000	16M		PCI I/O
+ * fe[0-7]00000			8M		per-platform mappings
+ * feb00000	c8000000	1M		MSF
+ * fec00000	df000000	1M		PCI CSRs
+ * fed00000	de000000	1M		PCI CREG
+ * fee00000	d6000000	1M		INTCTL
+ * fef00000	c0000000	1M		CAP
+ */
+
 /* 
  * Static I/O regions.
  *
@@ -71,6 +86,10 @@
 #define	IXP2000_PCI_CSR_VIRT_BASE	0xfec00000
 #define	IXP2000_PCI_CSR_SIZE		0x00100000
 
+#define IXP2000_MSF_PHYS_BASE		0xc8000000
+#define IXP2000_MSF_VIRT_BASE		0xfeb00000
+#define IXP2000_MSF_SIZE		0x00100000
+
 #define IXP2000_PCI_IO_PHYS_BASE	0xd8000000
 #define	IXP2000_PCI_IO_VIRT_BASE	0xfd000000
 #define IXP2000_PCI_IO_SIZE     	0x01000000
@@ -241,7 +260,7 @@
 #define PCI_CONTROL_BE_DEI		(1 << 21)	/* Big Endian Data Enable In  */
 #define PCI_CONTROL_BE_BEO		(1 << 20)	/* Big Endian Byte Enable Out */
 #define PCI_CONTROL_BE_BEI		(1 << 19)	/* Big Endian Byte Enable In  */
-#define PCI_CONTROL_PNR			(1 << 17)	/* PCI Not Reset bit */
+#define PCI_CONTROL_IEE			(1 << 17)	/* I/O cycle Endian swap Enable */
 
 #define IXP2000_PCI_RST_REL		(1 << 2)
 #define CFG_RST_DIR			(*IXP2000_PCI_CONTROL & IXP2000_PCICNTL_PCF)
@@ -363,6 +382,7 @@
 #define IXP2000_MIN_REV_MASK	      	0x0000000F
 #define IXP2000_PROD_ID_MASK		0xFFFFFFFF
 
+#define IXP2000_PRODUCT_ID		GLOBAL_REG(0x00)
 #define IXP2000_MISC_CONTROL		GLOBAL_REG(0x04)
 #define IXP2000_MSF_CLK_CNTRL  		GLOBAL_REG(0x08)
 #define IXP2000_RESET0      		GLOBAL_REG(0x0c)
diff --git a/include/asm-arm/arch-ixp2000/platform.h b/include/asm-arm/arch-ixp2000/platform.h
--- a/include/asm-arm/arch-ixp2000/platform.h
+++ b/include/asm-arm/arch-ixp2000/platform.h
@@ -115,6 +115,7 @@ static inline unsigned int ixp2000_is_pc
 }
 
 void ixp2000_map_io(void);
+void ixp2000_uart_init(void);
 void ixp2000_init_irq(void);
 void ixp2000_init_time(unsigned long);
 unsigned long ixp2000_gettimeoffset(void);
@@ -138,30 +139,10 @@ struct ixp2000_flash_data {
 	unsigned long (*bank_setup)(unsigned long);
 };
 
-/*
- * GPIO helper functions
- */
-#define	GPIO_IN		0
-#define	GPIO_OUT	1
-
-extern void gpio_line_config(int line, int style);
-
-static inline int gpio_line_get(int line)
-{
-	return (((*IXP2000_GPIO_PLR) >> line) & 1);
-}
-
-static inline void gpio_line_set(int line, int value)
-{
-	if (value) 
-		ixp2000_reg_write(IXP2000_GPIO_POSR, (1 << line));
-	else 
-		ixp2000_reg_write(IXP2000_GPIO_POCR, (1 << line));
-}
-
 struct ixp2000_i2c_pins {
 	unsigned long sda_pin;
 	unsigned long scl_pin;
 };
 
+
 #endif /*  !__ASSEMBLY__ */
diff --git a/include/asm-arm/arch-ixp2000/vmalloc.h b/include/asm-arm/arch-ixp2000/vmalloc.h
--- a/include/asm-arm/arch-ixp2000/vmalloc.h
+++ b/include/asm-arm/arch-ixp2000/vmalloc.h
@@ -17,4 +17,4 @@
  * The vmalloc() routines leaves a hole of 4kB between each vmalloced
  * area for the same reason. ;)
  */
-#define VMALLOC_END	    0xfaffefff
+#define VMALLOC_END	    0xfb000000
diff --git a/include/asm-arm/arch-ixp4xx/debug-macro.S b/include/asm-arm/arch-ixp4xx/debug-macro.S
--- a/include/asm-arm/arch-ixp4xx/debug-macro.S
+++ b/include/asm-arm/arch-ixp4xx/debug-macro.S
@@ -15,6 +15,7 @@
                 tst     \rx, #1                 @ MMU enabled?
                 moveq   \rx, #0xc8000000
                 movne   \rx, #0xff000000
+		orrne	\rx, \rx, #0x00b00000
                 add     \rx,\rx,#3              @ Uart regs are at off set of 3 if
 						@ byte writes used - Big Endian.
                 .endm
diff --git a/include/asm-arm/arch-ixp4xx/io.h b/include/asm-arm/arch-ixp4xx/io.h
--- a/include/asm-arm/arch-ixp4xx/io.h
+++ b/include/asm-arm/arch-ixp4xx/io.h
@@ -3,7 +3,7 @@
  *
  * Author: Deepak Saxena <dsaxena@plexity.net>
  *
- * Copyright (C) 2002-2004  MontaVista Software, Inc.
+ * Copyright (C) 2002-2005  MontaVista Software, Inc.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -383,6 +383,180 @@ __ixp4xx_insl(u32 io_addr, u32 *vaddr, u
 		*vaddr++ = inl(io_addr);
 }
 
+#define	__is_io_address(p)	(((unsigned long)p >= 0x0) && \
+					((unsigned long)p <= 0x0000ffff))
+static inline unsigned int
+__ixp4xx_ioread8(void __iomem *port)
+{
+	if (__is_io_address(port))
+		return	(unsigned int)__ixp4xx_inb((unsigned int)port);
+	else
+#ifndef CONFIG_IXP4XX_INDIRECT_PCI
+		return (unsigned int)__raw_readb((u32)port);
+#else
+		return (unsigned int)__ixp4xx_readb((u32)port);
+#endif
+}
+
+static inline void
+__ixp4xx_ioread8_rep(u32 port, u8 *vaddr, u32 count)
+{
+	if (__is_io_address(port))
+		__ixp4xx_insb(port, vaddr, count);
+	else
+#ifndef	CONFIG_IXP4XX_INDIRECT_PCI
+		__raw_readsb((void __iomem *)port, vaddr, count);
+#else
+		__ixp4xx_readsb(port, vaddr, count);
+#endif
+}
+
+static inline unsigned int
+__ixp4xx_ioread16(void __iomem *port)
+{
+	if (__is_io_address(port))
+		return	(unsigned int)__ixp4xx_inw((unsigned int)port);
+	else
+#ifndef CONFIG_IXP4XX_INDIRECT_PCI
+		return le16_to_cpu(__raw_readw((u32)port));
+#else
+		return (unsigned int)__ixp4xx_readw((u32)port);
+#endif
+}
+
+static inline void
+__ixp4xx_ioread16_rep(u32 port, u16 *vaddr, u32 count)
+{
+	if (__is_io_address(port))
+		__ixp4xx_insw(port, vaddr, count);
+	else
+#ifndef	CONFIG_IXP4XX_INDIRECT_PCI
+		__raw_readsw((void __iomem *)port, vaddr, count);
+#else
+		__ixp4xx_readsw(port, vaddr, count);
+#endif
+}
+
+static inline unsigned int
+__ixp4xx_ioread32(void __iomem *port)
+{
+	if (__is_io_address(port))
+		return	(unsigned int)__ixp4xx_inl((unsigned int)port);
+	else {
+#ifndef CONFIG_IXP4XX_INDIRECT_PCI
+		return le32_to_cpu(__raw_readl((u32)port));
+#else
+		return (unsigned int)__ixp4xx_readl((u32)port);
+#endif
+	}
+}
+
+static inline void
+__ixp4xx_ioread32_rep(u32 port, u32 *vaddr, u32 count)
+{
+	if (__is_io_address(port))
+		__ixp4xx_insl(port, vaddr, count);
+	else
+#ifndef	CONFIG_IXP4XX_INDIRECT_PCI
+		__raw_readsl((void __iomem *)port, vaddr, count);
+#else
+		__ixp4xx_readsl(port, vaddr, count);
+#endif
+}
+
+static inline void
+__ixp4xx_iowrite8(u8 value, void __iomem *port)
+{
+	if (__is_io_address(port))
+		__ixp4xx_outb(value, (unsigned int)port);
+	else
+#ifndef CONFIG_IXP4XX_INDIRECT_PCI
+		__raw_writeb(value, (u32)port);
+#else
+		__ixp4xx_writeb(value, (u32)port);
+#endif
+}
+
+static inline void
+__ixp4xx_iowrite8_rep(u32 port, u8 *vaddr, u32 count)
+{
+	if (__is_io_address(port))
+		__ixp4xx_outsb(port, vaddr, count);
+#ifndef CONFIG_IXP4XX_INDIRECT_PCI
+		__raw_writesb((void __iomem *)port, vaddr, count);
+#else
+		__ixp4xx_writesb(port, vaddr, count);
+#endif
+}
+
+static inline void
+__ixp4xx_iowrite16(u16 value, void __iomem *port)
+{
+	if (__is_io_address(port))
+		__ixp4xx_outw(value, (unsigned int)port);
+	else
+#ifndef CONFIG_IXP4XX_INDIRECT_PCI
+		__raw_writew(cpu_to_le16(value), (u32)port);
+#else
+		__ixp4xx_writew(value, (u32)port);
+#endif
+}
+
+static inline void
+__ixp4xx_iowrite16_rep(u32 port, u16 *vaddr, u32 count)
+{
+	if (__is_io_address(port))
+		__ixp4xx_outsw(port, vaddr, count);
+#ifndef CONFIG_IXP4XX_INDIRECT_PCI
+		__raw_readsw((void __iomem *)port, vaddr, count);
+#else
+		__ixp4xx_writesw(port, vaddr, count);
+#endif
+}
+
+static inline void
+__ixp4xx_iowrite32(u32 value, void __iomem *port)
+{
+	if (__is_io_address(port))
+		__ixp4xx_outl(value, (unsigned int)port);
+	else
+#ifndef CONFIG_IXP4XX_INDIRECT_PCI
+		__raw_writel(cpu_to_le32(value), (u32)port);
+#else
+		__ixp4xx_writel(value, (u32)port);
+#endif
+}
+
+static inline void
+__ixp4xx_iowrite32_rep(u32 port, u32 *vaddr, u32 count)
+{
+	if (__is_io_address(port))
+		__ixp4xx_outsl(port, vaddr, count);
+#ifndef CONFIG_IXP4XX_INDIRECT_PCI
+		__raw_readsl((void __iomem *)port, vaddr, count);
+#else
+		__ixp4xx_outsl(port, vaddr, count);
+#endif
+}
+
+#define	ioread8(p)			__ixp4xx_ioread8(p)
+#define	ioread16(p)			__ixp4xx_ioread16(p)
+#define	ioread32(p)			__ixp4xx_ioread32(p)
+
+#define	ioread8_rep(p, v, c)		__ixp4xx_ioread8_rep(p, v, c)
+#define	ioread16_rep(p, v, c)		__ixp4xx_ioread16_rep(p, v, c)
+#define	ioread32_rep(p, v, c)		__ixp4xx_ioread32_rep(p, v, c)
+
+#define	iowrite8(v,p)			__ixp4xx_iowrite8(v,p)
+#define	iowrite16(v,p)			__ixp4xx_iowrite16(v,p)
+#define	iowrite32(v,p)			__ixp4xx_iowrite32(v,p)
+
+#define	iowrite8_rep(p, v, c)		__ixp4xx_iowrite8_rep(p, v, c)
+#define	iowrite16_rep(p, v, c)		__ixp4xx_iowrite16_rep(p, v, c)
+#define	iowrite32_rep(p, v, c)		__ixp4xx_iowrite32_rep(p, v, c)
+
+#define	ioport_map(port, nr)		((void __iomem*)port)
+#define	ioport_unmap(addr)
 
 #endif	//  __ASM_ARM_ARCH_IO_H
 
diff --git a/include/asm-arm/arch-ixp4xx/ixp4xx-regs.h b/include/asm-arm/arch-ixp4xx/ixp4xx-regs.h
--- a/include/asm-arm/arch-ixp4xx/ixp4xx-regs.h
+++ b/include/asm-arm/arch-ixp4xx/ixp4xx-regs.h
@@ -69,6 +69,16 @@
 #define IXP4XX_PERIPHERAL_BASE_VIRT	(0xFFBF2000)
 #define IXP4XX_PERIPHERAL_REGION_SIZE	(0x0000C000)
 
+/*
+ * Debug UART
+ *
+ * This is basically a remap of UART1 into a region that is section
+ * aligned so that it * can be used with the low-level debug code.
+ */
+#define	IXP4XX_DEBUG_UART_BASE_PHYS	(0xC8000000)
+#define	IXP4XX_DEBUG_UART_BASE_VIRT	(0xffb00000)
+#define	IXP4XX_DEBUG_UART_REGION_SIZE	(0x00001000)
+
 #define IXP4XX_EXP_CS0_OFFSET	0x00
 #define IXP4XX_EXP_CS1_OFFSET   0x04
 #define IXP4XX_EXP_CS2_OFFSET   0x08
diff --git a/include/asm-arm/arch-ixp4xx/timex.h b/include/asm-arm/arch-ixp4xx/timex.h
--- a/include/asm-arm/arch-ixp4xx/timex.h
+++ b/include/asm-arm/arch-ixp4xx/timex.h
@@ -7,7 +7,9 @@
 
 /*
  * We use IXP425 General purpose timer for our timer needs, it runs at 
- * 66.66... MHz
+ * 66.66... MHz. We do a convulted calculation of CLOCK_TICK_RATE b/c the
+ * timer register ignores the bottom 2 bits of the LATCH value.
  */
-#define CLOCK_TICK_RATE (66666666)
+#define FREQ 66666666
+#define CLOCK_TICK_RATE (((FREQ / HZ & ~IXP4XX_OST_RELOAD_MASK) + 1) * HZ)
 
diff --git a/include/asm-arm/arch-omap/board-h2.h b/include/asm-arm/arch-omap/board-h2.h
--- a/include/asm-arm/arch-omap/board-h2.h
+++ b/include/asm-arm/arch-omap/board-h2.h
@@ -34,11 +34,6 @@
 /* At OMAP1610 Innovator the Ethernet is directly connected to CS1 */
 #define OMAP1610_ETHR_START		0x04000300
 
-/* Intel STRATA NOR flash at CS3 or CS2B(NAND Boot) */
-#define OMAP_NOR_FLASH_SIZE             SZ_32M
-#define OMAP_NOR_FLASH_START1           0x0C000000 /* CS3 */
-#define OMAP_NOR_FLASH_START2           0x0A000000 /* CS2B */
-
 /* Samsung NAND flash at CS2B or CS3(NAND Boot) */
 #define OMAP_NAND_FLASH_START1           0x0A000000 /* CS2B */
 #define OMAP_NAND_FLASH_START2           0x0C000000 /* CS3 */
diff --git a/include/asm-arm/arch-omap/board-h3.h b/include/asm-arm/arch-omap/board-h3.h
--- a/include/asm-arm/arch-omap/board-h3.h
+++ b/include/asm-arm/arch-omap/board-h3.h
@@ -30,11 +30,6 @@
 /* In OMAP1710 H3 the Ethernet is directly connected to CS1 */
 #define OMAP1710_ETHR_START		0x04000300
 
-/* Intel STRATA NOR flash at CS3 or CS2B(NAND Boot) */
-#define OMAP_NOR_FLASH_SIZE             SZ_32M
-#define OMAP_NOR_FLASH_START1 		0x0C000000 /* CS3 */
-#define OMAP_NOR_FLASH_START2 		0x0A000000 /* CS2B */
-
 /* Samsung NAND flash at CS2B or CS3(NAND Boot) */
 #define OMAP_NAND_FLASH_START1           0x0A000000 /* CS2B */
 #define OMAP_NAND_FLASH_START2           0x0C000000 /* CS3 */
diff --git a/include/asm-arm/arch-omap/board-osk.h b/include/asm-arm/arch-omap/board-osk.h
--- a/include/asm-arm/arch-omap/board-osk.h
+++ b/include/asm-arm/arch-omap/board-osk.h
@@ -32,10 +32,5 @@
 /* At OMAP5912 OSK the Ethernet is directly connected to CS1 */
 #define OMAP_OSK_ETHR_START		0x04800300
 
-/* Micron NOR flash at CS3 mapped to address 0x0 if BM bit is 1 */
-#define OMAP_OSK_NOR_FLASH_BASE		0xD8000000
-#define OMAP_OSK_NOR_FLASH_SIZE		SZ_32M
-#define OMAP_OSK_NOR_FLASH_START	0x00000000
-
 #endif /*  __ASM_ARCH_OMAP_OSK_H */
 
diff --git a/include/asm-arm/arch-omap/board.h b/include/asm-arm/arch-omap/board.h
--- a/include/asm-arm/arch-omap/board.h
+++ b/include/asm-arm/arch-omap/board.h
@@ -16,10 +16,11 @@
 /* Different peripheral ids */
 #define OMAP_TAG_CLOCK		0x4f01
 #define OMAP_TAG_MMC		0x4f02
-#define OMAP_TAG_UART		0x4f03
+#define OMAP_TAG_SERIAL_CONSOLE 0x4f03
 #define OMAP_TAG_USB		0x4f04
 #define OMAP_TAG_LCD		0x4f05
 #define OMAP_TAG_GPIO_SWITCH	0x4f06
+#define OMAP_TAG_UART		0x4f07
 
 #define OMAP_TAG_BOOT_REASON    0x4f80
 #define OMAP_TAG_FLASH_PART	0x4f81
@@ -35,7 +36,7 @@ struct omap_mmc_config {
 	s16 mmc1_switch_pin, mmc2_switch_pin;
 };
 
-struct omap_uart_config {
+struct omap_serial_console_config {
 	u8 console_uart;
 	u32 console_speed;
 };
@@ -82,7 +83,8 @@ struct omap_lcd_config {
  */
 #define OMAP_GPIO_SWITCH_TYPE_COVER		0x0000
 #define OMAP_GPIO_SWITCH_TYPE_CONNECTION	0x0001
-#define OMAP_GPIO_SWITCH_FLAG_INVERTED          0x0001
+#define OMAP_GPIO_SWITCH_FLAG_INVERTED		0x0001
+#define OMAP_GPIO_SWITCH_FLAG_OUTPUT		0x0002
 struct omap_gpio_switch_config {
 	char name[12];
 	u16 gpio;
@@ -99,6 +101,10 @@ struct omap_boot_reason_config {
 	char reason_str[12];
 };
 
+struct omap_uart_config {
+	/* Bit field of UARTs present; bit 0 --> UART1 */
+	unsigned int enabled_uarts;
+};
 
 struct omap_board_config_entry {
 	u16 tag;
diff --git a/include/asm-arm/arch-omap/common.h b/include/asm-arm/arch-omap/common.h
new file mode 100644
--- /dev/null
+++ b/include/asm-arm/arch-omap/common.h
@@ -0,0 +1,36 @@
+/*
+ * linux/include/asm-arm/arch-omap/common.h
+ *
+ * Header for code common to all OMAP machines.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the  GNU General Public License along
+ * with this program; if not, write  to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP_COMMON_H
+#define __ARCH_ARM_MACH_OMAP_COMMON_H
+
+struct sys_timer;
+
+extern void omap_map_common_io(void);
+extern struct sys_timer omap_timer;
+extern void omap_serial_init(int ports[]);
+
+#endif /* __ARCH_ARM_MACH_OMAP_COMMON_H */
diff --git a/include/asm-arm/arch-omap/dma.h b/include/asm-arm/arch-omap/dma.h
--- a/include/asm-arm/arch-omap/dma.h
+++ b/include/asm-arm/arch-omap/dma.h
@@ -241,6 +241,7 @@ extern void omap_dma_unlink_lch (int lch
 extern dma_addr_t omap_get_dma_src_pos(int lch);
 extern dma_addr_t omap_get_dma_dst_pos(int lch);
 extern void omap_clear_dma(int lch);
+extern int omap_dma_running(void);
 
 /* Returns 1 if the DMA module is in OMAP1510-compatible mode, 0 otherwise */
 extern int omap_dma_in_1510_mode(void);
diff --git a/include/asm-arm/arch-omap/hardware.h b/include/asm-arm/arch-omap/hardware.h
--- a/include/asm-arm/arch-omap/hardware.h
+++ b/include/asm-arm/arch-omap/hardware.h
@@ -54,6 +54,19 @@
 
 /*
  * ----------------------------------------------------------------------------
+ * Timers
+ * ----------------------------------------------------------------------------
+ */
+#define OMAP_MPU_TIMER1_BASE	(0xfffec500)
+#define OMAP_MPU_TIMER2_BASE	(0xfffec600)
+#define OMAP_MPU_TIMER3_BASE	(0xfffec700)
+#define MPU_TIMER_FREE		(1 << 6)
+#define MPU_TIMER_CLOCK_ENABLE	(1 << 5)
+#define MPU_TIMER_AR		(1 << 1)
+#define MPU_TIMER_ST		(1 << 0)
+
+/*
+ * ----------------------------------------------------------------------------
  * Clocks
  * ----------------------------------------------------------------------------
  */
@@ -78,6 +91,7 @@
 
 /* DSP clock control */
 #define DSP_CONFIG_REG_BASE     (0xe1008000)
+#define DSP_CKCTL		(DSP_CONFIG_REG_BASE + 0x0)
 #define DSP_IDLECT1		(DSP_CONFIG_REG_BASE + 0x4)
 #define DSP_IDLECT2		(DSP_CONFIG_REG_BASE + 0x8)
 
@@ -88,6 +102,7 @@
  */
 #define ULPD_REG_BASE		(0xfffe0800)
 #define ULPD_IT_STATUS		(ULPD_REG_BASE + 0x14)
+#define ULPD_SETUP_ANALOG_CELL_3	(ULPD_REG_BASE + 0x24)
 #define ULPD_CLOCK_CTRL		(ULPD_REG_BASE + 0x30)
 #	define DIS_USB_PVCI_CLK		(1 << 5)	/* no USB/FAC synch */
 #	define USB_MCLK_EN		(1 << 4)	/* enable W4_USB_CLKO */
@@ -268,17 +283,10 @@
  * Processor specific defines
  * ---------------------------------------------------------------------------
  */
-#ifdef CONFIG_ARCH_OMAP730
-#include "omap730.h"
-#endif
 
-#ifdef CONFIG_ARCH_OMAP1510
+#include "omap730.h"
 #include "omap1510.h"
-#endif
-
-#ifdef CONFIG_ARCH_OMAP16XX
 #include "omap16xx.h"
-#endif
 
 /*
  * ---------------------------------------------------------------------------
diff --git a/include/asm-arm/arch-omap/irqs.h b/include/asm-arm/arch-omap/irqs.h
--- a/include/asm-arm/arch-omap/irqs.h
+++ b/include/asm-arm/arch-omap/irqs.h
@@ -159,6 +159,7 @@
 #define INT_1610_GPIO_BANK3	(41 + IH2_BASE)
 #define INT_1610_MMC2		(42 + IH2_BASE)
 #define INT_1610_CF		(43 + IH2_BASE)
+#define INT_1610_WAKE_UP_REQ	(46 + IH2_BASE)
 #define INT_1610_GPIO_BANK4	(48 + IH2_BASE)
 #define INT_1610_SPI		(49 + IH2_BASE)
 #define INT_1610_DMA_CH6	(53 + IH2_BASE)
@@ -238,6 +239,8 @@
 #define IH_MPUIO_BASE		(OMAP_MAX_GPIO_LINES + IH_GPIO_BASE)
 #define IH_BOARD_BASE		(16 + IH_MPUIO_BASE)
 
+#define OMAP_IRQ_BIT(irq)	(1 << ((irq) % 32))
+
 #ifndef __ASSEMBLY__
 extern void omap_init_irq(void);
 #endif
diff --git a/include/asm-arm/arch-omap/mux.h b/include/asm-arm/arch-omap/mux.h
--- a/include/asm-arm/arch-omap/mux.h
+++ b/include/asm-arm/arch-omap/mux.h
@@ -231,7 +231,7 @@ typedef enum {
 	J19_1610_ETM_D6,
 	J18_1610_ETM_D7,
 
-	/* OMAP-1610 GPIO */
+	/* OMAP16XX GPIO */
 	P20_1610_GPIO4,
 	V9_1610_GPIO7,
 	W8_1610_GPIO9,
@@ -241,6 +241,9 @@ typedef enum {
 	AA20_1610_GPIO_41,
 	W19_1610_GPIO48,
 	M7_1610_GPIO62,
+	V14_16XX_GPIO37,
+	R9_16XX_GPIO18,
+	L14_16XX_GPIO49,
 
 	/* OMAP-1610 uWire */
 	V19_1610_UWIRE_SCLK,
@@ -285,12 +288,13 @@ typedef enum {
 	V6_USB2_TXD,
 	W5_USB2_SE0,
 
-	/* UART1 1610 */
-
+	/* 16XX UART */
 	R13_1610_UART1_TX,
-	V14_1610_UART1_RX,
+	V14_16XX_UART1_RX,
 	R14_1610_UART1_CTS,
 	AA15_1610_UART1_RTS,
+	R9_16XX_UART2_RX,
+	L14_16XX_UART3_RX,
 
 	/* I2C OMAP-1610 */
 	I2C_SCL,
@@ -332,7 +336,7 @@ typedef enum {
  * Table of various FUNC_MUX and PULL_DWN combinations for each device.
  * See also reg_cfg_t above for the lookup table.
  */
-static reg_cfg_set __initdata_or_module
+static const reg_cfg_set __initdata_or_module
 reg_cfg_table[] = {
 /*
  *	 description		mux  mode   mux	 pull pull  pull  pu_pd	 pu  dbg
@@ -455,7 +459,7 @@ MUX_CFG("L19_1610_ETM_D0",	 5,   18,    
 MUX_CFG("J19_1610_ETM_D6",	 5,    0,    1,	  0,  20,   0,	  0,	 0,  1)
 MUX_CFG("J18_1610_ETM_D7",	 5,   27,    1,	  0,  19,   0,	  0,	 0,  1)
 
-/* OMAP-1610 GPIO */
+/* OMAP16XX GPIO */
 MUX_CFG("P20_1610_GPIO4",	 6,   27,    0,	  1,   7,   0,	  1,	 1,  1)
 MUX_CFG("V9_1610_GPIO7",	 B,   12,    1,	  2,  20,   0,	  2,	 1,  1)
 MUX_CFG("W8_1610_GPIO9",	 B,   21,    0,	  2,  23,   0,	  2,	 1,  1)
@@ -465,6 +469,9 @@ MUX_CFG("V5_1610_GPIO24",	 B,   15,    7
 MUX_CFG("AA20_1610_GPIO_41",	 9,    9,    7,	  1,  31,   0,	  1,	 1,  1)
 MUX_CFG("W19_1610_GPIO48",	 8,   15,    7,   1,  23,   1,    1,     0,  1)
 MUX_CFG("M7_1610_GPIO62",	10,    0,    0,   4,  24,   0,    4,     0,  1)
+MUX_CFG("V14_16XX_GPIO37",	 9,   18,    7,	  2,   2,   0,	  2,	 2,  0)
+MUX_CFG("R9_16XX_GPIO18",	 C,   18,    7,   3,   0,   0,    3,     0,  0)
+MUX_CFG("L14_16XX_GPIO49",	 6,    3,    7,   0,  31,   0,    0,    31,  0)
 
 /* OMAP-1610 uWire */
 MUX_CFG("V19_1610_UWIRE_SCLK",	 8,    6,    0,	  1,  20,   0,	  1,	 1,  1)
@@ -503,16 +510,17 @@ MUX_CFG("Y10_USB0_SUSP",	 B,   3,     5,
 MUX_CFG("W9_USB2_TXEN",		 B,   9,     1,	 NA,   0,   0,	 NA,	 0,  1)
 MUX_CFG("AA9_USB2_VP",		 B,   6,     1,	 NA,   0,   0,	 NA,	 0,  1)
 MUX_CFG("Y5_USB2_RCV",		 C,  21,     1,	 NA,   0,   0,	 NA,	 0,  1)
-MUX_CFG("R8_USB2_VM",		 C,  18,     1,	 NA,   0,   0,	 NA,	 0,  1)
+MUX_CFG("R9_USB2_VM",		 C,  18,     1,	 NA,   0,   0,	 NA,	 0,  1)
 MUX_CFG("V6_USB2_TXD",		 C,  27,     2,	 NA,   0,   0,	 NA,	 0,  1)
 MUX_CFG("W5_USB2_SE0",		 C,  24,     2,	 NA,   0,   0,	 NA,	 0,  1)
 
-
-/* UART1 */
+/* 16XX UART */
 MUX_CFG("R13_1610_UART1_TX",	 A,  12,     6,	  2,  10,   0,	  2,	10,  1)
-MUX_CFG("V14_1610_UART1_RX",	 9,  18,     0,	  2,   2,   0,	  2,	 2,  1)
+MUX_CFG("V14_16XX_UART1_RX",	 9,  18,     0,	  2,   2,   0,	  2,	 2,  1)
 MUX_CFG("R14_1610_UART1_CTS",	 9,  15,     0,	  2,   1,   0,	  2,	 1,  1)
 MUX_CFG("AA15_1610_UART1_RTS",	 9,  12,     1,	  2,   0,   0,	  2,	 0,  1)
+MUX_CFG("R9_16XX_UART2_RX",	 C,  18,     0,   3,   0,   0,    3,     0,  1)
+MUX_CFG("L14_16XX_UART3_RX",	 6,   3,     0,   0,  31,   0,    0,    31,  1)
 
 /* I2C interface */
 MUX_CFG("I2C_SCL",		 7,  24,     0,	 NA,   0,   0,	 NA,	 0,  0)
diff --git a/include/asm-arm/arch-omap/omap16xx.h b/include/asm-arm/arch-omap/omap16xx.h
--- a/include/asm-arm/arch-omap/omap16xx.h
+++ b/include/asm-arm/arch-omap/omap16xx.h
@@ -183,5 +183,37 @@
 #define OMAP16XX_PWL_ENABLE	(OMAP16XX_PWL_BASE + 0x00)
 #define OMAP16XX_PWL_CLK_ENABLE	(OMAP16XX_PWL_BASE + 0x04)
 
+/*
+ * ---------------------------------------------------------------------------
+ * Watchdog timer
+ * ---------------------------------------------------------------------------
+ */
+
+/* 32-bit Watchdog timer in OMAP 16XX */
+#define OMAP_16XX_WATCHDOG_BASE        (0xfffeb000)
+#define OMAP_16XX_WIDR         (OMAP_16XX_WATCHDOG_BASE + 0x00)
+#define OMAP_16XX_WD_SYSCONFIG (OMAP_16XX_WATCHDOG_BASE + 0x10)
+#define OMAP_16XX_WD_SYSSTATUS (OMAP_16XX_WATCHDOG_BASE + 0x14)
+#define OMAP_16XX_WCLR         (OMAP_16XX_WATCHDOG_BASE + 0x24)
+#define OMAP_16XX_WCRR         (OMAP_16XX_WATCHDOG_BASE + 0x28)
+#define OMAP_16XX_WLDR         (OMAP_16XX_WATCHDOG_BASE + 0x2c)
+#define OMAP_16XX_WTGR         (OMAP_16XX_WATCHDOG_BASE + 0x30)
+#define OMAP_16XX_WWPS         (OMAP_16XX_WATCHDOG_BASE + 0x34)
+#define OMAP_16XX_WSPR         (OMAP_16XX_WATCHDOG_BASE + 0x48)
+
+#define WCLR_PRE_SHIFT         5
+#define WCLR_PTV_SHIFT         2
+
+#define WWPS_W_PEND_WSPR       (1 << 4)
+#define WWPS_W_PEND_WTGR       (1 << 3)
+#define WWPS_W_PEND_WLDR       (1 << 2)
+#define WWPS_W_PEND_WCRR       (1 << 1)
+#define WWPS_W_PEND_WCLR       (1 << 0)
+
+#define WSPR_ENABLE_0          (0x0000bbbb)
+#define WSPR_ENABLE_1          (0x00004444)
+#define WSPR_DISABLE_0         (0x0000aaaa)
+#define WSPR_DISABLE_1         (0x00005555)
+
 #endif /*  __ASM_ARCH_OMAP16XX_H */
 
diff --git a/include/asm-arm/arch-omap/system.h b/include/asm-arm/arch-omap/system.h
--- a/include/asm-arm/arch-omap/system.h
+++ b/include/asm-arm/arch-omap/system.h
@@ -5,7 +5,9 @@
 #ifndef __ASM_ARCH_SYSTEM_H
 #define __ASM_ARCH_SYSTEM_H
 #include <linux/config.h>
+#include <asm/mach-types.h>
 #include <asm/arch/hardware.h>
+#include <asm/mach-types.h>
 
 static inline void arch_idle(void)
 {
@@ -14,7 +16,24 @@ static inline void arch_idle(void)
 
 static inline void arch_reset(char mode)
 {
-	omap_writew(1, ARM_RSTCT1);
+
+#ifdef CONFIG_ARCH_OMAP16XX
+	/*
+	 * Workaround for 5912/1611b bug mentioned in sprz209d.pdf p. 28
+	 * "Global Software Reset Affects Traffic Controller Frequency".
+	 */
+	if (cpu_is_omap5912()) {
+		omap_writew(omap_readw(DPLL_CTL) & ~(1 << 4),
+				 DPLL_CTL);
+		omap_writew(0x8, ARM_RSTCT1);
+	}
+#endif
+#ifdef CONFIG_MACH_VOICEBLUE
+	if (machine_is_voiceblue())
+		voiceblue_reset();
+	else
+#endif
+		omap_writew(1, ARM_RSTCT1);
 }
 
 #endif
diff --git a/include/asm-arm/arch-omap/tps65010.h b/include/asm-arm/arch-omap/tps65010.h
--- a/include/asm-arm/arch-omap/tps65010.h
+++ b/include/asm-arm/arch-omap/tps65010.h
@@ -30,6 +30,66 @@
 
 /*
  * ----------------------------------------------------------------------------
+ * Registers, all 8 bits
+ * ----------------------------------------------------------------------------
+ */
+
+#define	TPS_CHGSTATUS		0x01
+#	define	TPS_CHG_USB		(1 << 7)
+#	define	TPS_CHG_AC		(1 << 6)
+#	define	TPS_CHG_THERM		(1 << 5)
+#	define	TPS_CHG_TERM		(1 << 4)
+#	define	TPS_CHG_TAPER_TMO	(1 << 3)
+#	define	TPS_CHG_CHG_TMO		(1 << 2)
+#	define	TPS_CHG_PRECHG_TMO	(1 << 1)
+#	define	TPS_CHG_TEMP_ERR	(1 << 0)
+#define	TPS_REGSTATUS		0x02
+#	define	TPS_REG_ONOFF		(1 << 7)
+#	define	TPS_REG_COVER		(1 << 6)
+#	define	TPS_REG_UVLO		(1 << 5)
+#	define	TPS_REG_NO_CHG		(1 << 4)	/* tps65013 */
+#	define	TPS_REG_PG_LD02		(1 << 3)
+#	define	TPS_REG_PG_LD01		(1 << 2)
+#	define	TPS_REG_PG_MAIN		(1 << 1)
+#	define	TPS_REG_PG_CORE		(1 << 0)
+#define	TPS_MASK1		0x03
+#define	TPS_MASK2		0x04
+#define	TPS_ACKINT1		0x05
+#define	TPS_ACKINT2		0x06
+#define	TPS_CHGCONFIG		0x07
+#	define	TPS_CHARGE_POR		(1 << 7)	/* 65010/65012 */
+#	define	TPS65013_AUA		(1 << 7)	/* 65011/65013 */
+#	define	TPS_CHARGE_RESET	(1 << 6)
+#	define	TPS_CHARGE_FAST		(1 << 5)
+#	define	TPS_CHARGE_CURRENT	(3 << 3)
+#	define	TPS_VBUS_500MA		(1 << 2)
+#	define	TPS_VBUS_CHARGING	(1 << 1)
+#	define	TPS_CHARGE_ENABLE	(1 << 0)
+#define	TPS_LED1_ON		0x08
+#define	TPS_LED1_PER		0x09
+#define	TPS_LED2_ON		0x0a
+#define	TPS_LED2_PER		0x0b
+#define	TPS_VDCDC1		0x0c
+#	define	TPS_ENABLE_LP		(1 << 3)
+#define	TPS_VDCDC2		0x0d
+#define	TPS_VREGS1		0x0e
+#	define	TPS_LDO2_ENABLE	(1 << 7)
+#	define	TPS_LDO2_OFF	(1 << 6)
+#	define	TPS_VLDO2_3_0V	(3 << 4)
+#	define	TPS_VLDO2_2_75V	(2 << 4)
+#	define	TPS_VLDO2_2_5V	(1 << 4)
+#	define	TPS_VLDO2_1_8V	(0 << 4)
+#	define	TPS_LDO1_ENABLE	(1 << 3)
+#	define	TPS_LDO1_OFF	(1 << 2)
+#	define	TPS_VLDO1_3_0V	(3 << 0)
+#	define	TPS_VLDO1_2_75V	(2 << 0)
+#	define	TPS_VLDO1_2_5V	(1 << 0)
+#	define	TPS_VLDO1_ADJ	(0 << 0)
+#define	TPS_MASK3		0x0f
+#define	TPS_DEFGPIO		0x10
+
+/*
+ * ----------------------------------------------------------------------------
  * Macros used by exported functions
  * ----------------------------------------------------------------------------
  */
@@ -71,10 +131,26 @@ extern int tps65010_set_gpio_out_value(u
  */
 extern int tps65010_set_led(unsigned led, unsigned mode);
 
+/* tps65010_set_vib parameter:
+ * value: ON or OFF
+ */
+extern int tps65010_set_vib(unsigned value);
+
 /* tps65010_set_low_pwr parameter:
  * mode: ON or OFF
  */
 extern int tps65010_set_low_pwr(unsigned mode);
 
+/* tps65010_config_vregs1 parameter:
+ * value to be written to VREGS1 register
+ * Note: The complete register is written, set all bits you need
+ */
+extern int tps65010_config_vregs1(unsigned value);
+
+/* tps65013_set_low_pwr parameter:
+ * mode: ON or OFF
+ */
+extern int tps65013_set_low_pwr(unsigned mode);
+
 #endif /*  __ASM_ARCH_TPS65010_H */
 
diff --git a/include/asm-arm/arch-omap/usb.h b/include/asm-arm/arch-omap/usb.h
--- a/include/asm-arm/arch-omap/usb.h
+++ b/include/asm-arm/arch-omap/usb.h
@@ -47,6 +47,15 @@
 #	define	 HMC_TLLATTACH		(1 << 6)
 #	define	 OTG_HMC(w)		(((w)>>0)&0x3f)
 #define OTG_CTRL_REG			OTG_REG32(0x0c)
+#	define	 OTG_USB2_EN		(1 << 29)
+#	define	 OTG_USB2_DP		(1 << 28)
+#	define	 OTG_USB2_DM		(1 << 27)
+#	define	 OTG_USB1_EN		(1 << 26)
+#	define	 OTG_USB1_DP		(1 << 25)
+#	define	 OTG_USB1_DM		(1 << 24)
+#	define	 OTG_USB0_EN		(1 << 23)
+#	define	 OTG_USB0_DP		(1 << 22)
+#	define	 OTG_USB0_DM		(1 << 21)
 #	define	 OTG_ASESSVLD		(1 << 20)
 #	define	 OTG_BSESSEND		(1 << 19)
 #	define	 OTG_BSESSVLD		(1 << 18)
diff --git a/include/asm-arm/arch-pxa/debug-macro.S b/include/asm-arm/arch-pxa/debug-macro.S
--- a/include/asm-arm/arch-pxa/debug-macro.S
+++ b/include/asm-arm/arch-pxa/debug-macro.S
@@ -11,6 +11,8 @@
  *
 */
 
+#include "hardware.h"
+
 		.macro	addruart,rx
 		mrc	p15, 0, \rx, c1, c0
 		tst	\rx, #1			@ MMU enabled?
diff --git a/include/asm-arm/arch-pxa/mtd-xip.h b/include/asm-arm/arch-pxa/mtd-xip.h
new file mode 100644
--- /dev/null
+++ b/include/asm-arm/arch-pxa/mtd-xip.h
@@ -0,0 +1,37 @@
+/*
+ * MTD primitives for XIP support. Architecture specific functions
+ *
+ * Do not include this file directly. It's included from linux/mtd/xip.h
+ * 
+ * Author:	Nicolas Pitre
+ * Created:	Nov 2, 2004
+ * Copyright:	(C) 2004 MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * $Id: xip.h,v 1.2 2004/12/01 15:49:10 nico Exp $
+ */
+
+#ifndef __ARCH_PXA_MTD_XIP_H__
+#define __ARCH_PXA_MTD_XIP_H__
+
+#include <asm/arch/pxa-regs.h>
+
+#define xip_irqpending()	(ICIP & ICMR)
+
+/* we sample OSCR and convert desired delta to usec (1/4 ~= 1000000/3686400) */
+#define xip_currtime()		(OSCR)
+#define xip_elapsed_since(x)	(signed)((OSCR - (x)) / 4)
+
+/*
+ * xip_cpu_idle() is used when waiting for a delay equal or larger than
+ * the system timer tick period.  This should put the CPU into idle mode
+ * to save power and to be woken up only when some interrupts are pending.
+ * As above, this should not rely upon standard kernel code.
+ */
+
+#define xip_cpu_idle()  asm volatile ("mcr p14, 0, %0, c7, c0, 0" :: "r" (1))
+
+#endif /* __ARCH_PXA_MTD_XIP_H__ */
diff --git a/include/asm-arm/arch-pxa/pxa-regs.h b/include/asm-arm/arch-pxa/pxa-regs.h
--- a/include/asm-arm/arch-pxa/pxa-regs.h
+++ b/include/asm-arm/arch-pxa/pxa-regs.h
@@ -1505,6 +1505,7 @@
 #define PSSR_OTGPH	(1 << 6)	/* OTG Peripheral control Hold */
 #define PSSR_RDH	(1 << 5)	/* Read Disable Hold */
 #define PSSR_PH		(1 << 4)	/* Peripheral Control Hold */
+#define PSSR_STS	(1 << 3)	/* Standby Mode Status */
 #define PSSR_VFS	(1 << 2)	/* VDD Fault Status */
 #define PSSR_BFS	(1 << 1)	/* Battery Fault Status */
 #define PSSR_SSS	(1 << 0)	/* Software Sleep Status */
@@ -1965,6 +1966,7 @@
 #define MECR_NOS	(1 << 0)	/* Number Of Sockets: 0 -> 1 sock, 1 -> 2 sock */
 #define MECR_CIT	(1 << 1)	/* Card Is There: 0 -> no card, 1 -> card inserted */
 
+#define MDREFR_K0DB4	(1 << 29)	/* SDCLK0 Divide by 4 Control/Status */
 #define MDREFR_K2FREE	(1 << 25)	/* SDRAM Free-Running Control */
 #define MDREFR_K1FREE	(1 << 24)	/* SDRAM Free-Running Control */
 #define MDREFR_K0FREE	(1 << 23)	/* SDRAM Free-Running Control */
diff --git a/include/asm-arm/arch-s3c2410/audio.h b/include/asm-arm/arch-s3c2410/audio.h
new file mode 100644
--- /dev/null
+++ b/include/asm-arm/arch-s3c2410/audio.h
@@ -0,0 +1,49 @@
+/* linux/include/asm-arm/arch-s3c2410/audio.h
+ *
+ * (c) 2004-2005 Simtec Electronics
+ *	http://www.simtec.co.uk/products/SWLINUX/
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C24XX - Audio platfrom_device info
+ *
+ * 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.
+ *
+ * Changelog:
+ *	20-Nov-2004 BJD  Created file
+ *	07-Mar-2005 BJD  Added suspend/resume calls
+*/
+
+#ifndef __ASM_ARCH_AUDIO_H
+#define __ASM_ARCH_AUDIO_H __FILE__
+
+/* struct s3c24xx_iis_ops
+ *
+ * called from the s3c24xx audio core to deal with the architecture
+ * or the codec's setup and control.
+ *
+ * the pointer to itself is passed through in case the caller wants to
+ * embed this in an larger structure for easy reference to it's context.
+*/
+
+struct s3c24xx_iis_ops {
+	struct module *owner;
+
+	int	(*startup)(struct s3c24xx_iis_ops *me);
+	void	(*shutdown)(struct s3c24xx_iis_ops *me);
+	int	(*suspend)(struct s3c24xx_iis_ops *me);
+	int	(*resume)(struct s3c24xx_iis_ops *me);
+
+	int	(*open)(struct s3c24xx_iis_ops *me, snd_pcm_substream_t *strm);
+	int	(*close)(struct s3c24xx_iis_ops *me, snd_pcm_substream_t *strm);
+	int	(*prepare)(struct s3c24xx_iis_ops *me, snd_pcm_substream_t *strm, snd_pcm_runtime_t *rt);
+};
+
+struct s3c24xx_platdata_iis {
+	const char		*codec_clk;
+	struct s3c24xx_iis_ops	*ops;
+	int			(*match_dev)(struct device *dev);
+};
+
+#endif /* __ASM_ARCH_AUDIO_H */
diff --git a/include/asm-arm/arch-s3c2410/regs-iis.h b/include/asm-arm/arch-s3c2410/regs-iis.h
--- a/include/asm-arm/arch-s3c2410/regs-iis.h
+++ b/include/asm-arm/arch-s3c2410/regs-iis.h
@@ -15,6 +15,9 @@
  *    12-03-2004     BJD     Updated include protection
  *    07-03-2005     BJD     Added FIFO size flags and S3C2440 MPLL
  *    05-04-2005     LCVR    Added IISFCON definitions for the S3C2400
+ *    18-07-2005     DA      Change IISCON_MPLL to IISMOD_MPLL
+ *                           Correct IISMOD_256FS and IISMOD_384FS
+ *                           Add IISCON_PSCEN
  */
 
 #ifndef __ASM_ARCH_REGS_IIS_H
@@ -22,7 +25,6 @@
 
 #define S3C2410_IISCON	 (0x00)
 
-#define S3C2440_IISCON_MPLL	  (1<<9)
 #define S3C2410_IISCON_LRINDEX	  (1<<8)
 #define S3C2410_IISCON_TXFIFORDY  (1<<7)
 #define S3C2410_IISCON_RXFIFORDY  (1<<6)
@@ -30,10 +32,12 @@
 #define S3C2410_IISCON_RXDMAEN	  (1<<4)
 #define S3C2410_IISCON_TXIDLE	  (1<<3)
 #define S3C2410_IISCON_RXIDLE	  (1<<2)
+#define S3C2410_IISCON_PSCEN	  (1<<1)
 #define S3C2410_IISCON_IISEN	  (1<<0)
 
 #define S3C2410_IISMOD	 (0x04)
 
+#define S3C2440_IISMOD_MPLL	  (1<<9)
 #define S3C2410_IISMOD_SLAVE	  (1<<8)
 #define S3C2410_IISMOD_NOXFER	  (0<<6)
 #define S3C2410_IISMOD_RXMODE	  (1<<6)
@@ -46,8 +50,8 @@
 #define S3C2410_IISMOD_8BIT	  (0<<3)
 #define S3C2410_IISMOD_16BIT	  (1<<3)
 #define S3C2410_IISMOD_BITMASK	  (1<<3)
-#define S3C2410_IISMOD_256FS	  (0<<1)
-#define S3C2410_IISMOD_384FS	  (1<<1)
+#define S3C2410_IISMOD_256FS	  (0<<2)
+#define S3C2410_IISMOD_384FS	  (1<<2)
 #define S3C2410_IISMOD_16FS	  (0<<0)
 #define S3C2410_IISMOD_32FS	  (1<<0)
 #define S3C2410_IISMOD_48FS	  (2<<0)
diff --git a/include/asm-arm/arch-s3c2410/usb-control.h b/include/asm-arm/arch-s3c2410/usb-control.h
--- a/include/asm-arm/arch-s3c2410/usb-control.h
+++ b/include/asm-arm/arch-s3c2410/usb-control.h
@@ -12,6 +12,7 @@
  * Changelog:
  *  11-Sep-2004 BJD  Created file
  *  21-Sep-2004 BJD  Updated port info
+ *  09-Aug-2005 BJD  Renamed s3c2410_report_oc s3c2410_usb_report_oc
 */
 
 #ifndef __ASM_ARCH_USBCONTROL_H
@@ -35,7 +36,7 @@ struct s3c2410_hcd_info {
 	void		(*report_oc)(struct s3c2410_hcd_info *, int ports);
 };
 
-static void inline s3c2410_report_oc(struct s3c2410_hcd_info *info, int ports)
+static void inline s3c2410_usb_report_oc(struct s3c2410_hcd_info *info, int ports)
 {
 	if (info->report_oc != NULL) {
 		(info->report_oc)(info, ports);
diff --git a/include/asm-arm/arch-sa1100/mtd-xip.h b/include/asm-arm/arch-sa1100/mtd-xip.h
new file mode 100644
--- /dev/null
+++ b/include/asm-arm/arch-sa1100/mtd-xip.h
@@ -0,0 +1,26 @@
+/*
+ * MTD primitives for XIP support. Architecture specific functions
+ *
+ * Do not include this file directly. It's included from linux/mtd/xip.h
+ * 
+ * Author:	Nicolas Pitre
+ * Created:	Nov 2, 2004
+ * Copyright:	(C) 2004 MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * $Id: xip.h,v 1.2 2004/12/01 15:49:10 nico Exp $
+ */
+
+#ifndef __ARCH_SA1100_MTD_XIP_H__
+#define __ARCH_SA1100_MTD_XIP_H__
+
+#define xip_irqpending()	(ICIP & ICMR)
+
+/* we sample OSCR and convert desired delta to usec (1/4 ~= 1000000/3686400) */
+#define xip_currtime()		(OSCR)
+#define xip_elapsed_since(x)	(signed)((OSCR - (x)) / 4)
+
+#endif /* __ARCH_SA1100_MTD_XIP_H__ */
diff --git a/include/asm-arm/arch-shark/io.h b/include/asm-arm/arch-shark/io.h
--- a/include/asm-arm/arch-shark/io.h
+++ b/include/asm-arm/arch-shark/io.h
@@ -21,38 +21,8 @@
  */
 #define __PORT_PCIO(x)	(!((x) & 0x80000000))
 
-/*
- * Dynamic IO functions - let the compiler
- * optimize the expressions
- */
-#define DECLARE_DYN_OUT(fnsuffix,instr)						\
-static inline void __out##fnsuffix (unsigned int value, unsigned int port)	\
-{										\
-	unsigned long temp;							\
-	__asm__ __volatile__(							\
-	"tst	%2, #0x80000000\n\t"						\
-	"mov	%0, %4\n\t"							\
-	"addeq	%0, %0, %3\n\t"							\
-	"str" instr "	%1, [%0, %2]	@ out" #fnsuffix			\
-	: "=&r" (temp)								\
-	: "r" (value), "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE)	\
-	: "cc");								\
-}
+#define __io(a)                 ((void __iomem *)(PCIO_BASE + (a)))
 
-#define DECLARE_DYN_IN(sz,fnsuffix,instr)					\
-static inline unsigned sz __in##fnsuffix (unsigned int port)		\
-{										\
-	unsigned long temp, value;						\
-	__asm__ __volatile__(							\
-	"tst	%2, #0x80000000\n\t"						\
-	"mov	%0, %4\n\t"							\
-	"addeq	%0, %0, %3\n\t"							\
-	"ldr" instr "	%1, [%0, %2]	@ in" #fnsuffix				\
-	: "=&r" (temp), "=r" (value)						\
-	: "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE)		\
-	: "cc");								\
-	return (unsigned sz)value;						\
-}
 
 static inline unsigned int __ioaddr (unsigned int port)			\
 {										\
@@ -62,123 +32,8 @@ static inline unsigned int __ioaddr (uns
 		return (unsigned int)(IO_BASE + (port));			\
 }
 
-#define DECLARE_IO(sz,fnsuffix,instr)	\
-	DECLARE_DYN_OUT(fnsuffix,instr)	\
-	DECLARE_DYN_IN(sz,fnsuffix,instr)
-
-DECLARE_IO(char,b,"b")
-DECLARE_IO(short,w,"h")
-DECLARE_IO(long,l,"")
-
-#undef DECLARE_IO
-#undef DECLARE_DYN_OUT
-#undef DECLARE_DYN_IN
-
-/*
- * Constant address IO functions
- *
- * These have to be macros for the 'J' constraint to work -
- * +/-4096 immediate operand.
- */
-#define __outbc(value,port)							\
-({										\
-	if (__PORT_PCIO((port)))						\
-		__asm__ __volatile__(						\
-		"strb	%0, [%1, %2]		@ outbc"			\
-		: : "r" (value), "r" (PCIO_BASE), "Jr" (port));		\
-	else									\
-		__asm__ __volatile__(						\
-		"strb	%0, [%1, %2]		@ outbc"			\
-		: : "r" (value), "r" (IO_BASE), "r" (port));		\
-})
-
-#define __inbc(port)								\
-({										\
-	unsigned char result;                                                   \
-	if (__PORT_PCIO((port)))						\
-		__asm__ __volatile__(						\
-		"ldrb	%0, [%1, %2]		@ inbc"				\
-		: "=r" (result) : "r" (PCIO_BASE), "Jr" (port));		\
-	else									\
-		__asm__ __volatile__(						\
-		"ldrb	%0, [%1, %2]		@ inbc"				\
-		: "=r" (result) : "r" (IO_BASE), "r" (port));		\
-	result;									\
-})
-
-#define __outwc(value,port)							\
-({										\
-	unsigned long v = value;						\
-	if (__PORT_PCIO((port)))						\
-		__asm__ __volatile__(						\
-		"strh	%0, [%1, %2]		@ outwc"			\
-		: : "r" (v|v<<16), "r" (PCIO_BASE), "Jr" (port));	\
-	else									\
-		__asm__ __volatile__(						\
-		"strh	%0, [%1, %2]		@ outwc"			\
-		: : "r" (v|v<<16), "r" (IO_BASE), "r" (port));		\
-})
-
-#define __inwc(port)								\
-({										\
-	unsigned short result;							\
-	if (__PORT_PCIO((port)))						\
-		__asm__ __volatile__(						\
-		"ldrh	%0, [%1, %2]		@ inwc"				\
-		: "=r" (result) : "r" (PCIO_BASE), "Jr" (port));		\
-	else									\
-		__asm__ __volatile__(						\
-		"ldrh	%0, [%1, %2]		@ inwc"				\
-		: "=r" (result) : "r" (IO_BASE), "r" (port));		\
-	result & 0xffff;							\
-})
-
-#define __outlc(value,port)								\
-({										\
-	unsigned long v = value;						\
-	if (__PORT_PCIO((port)))						\
-		__asm__ __volatile__(						\
-		"str	%0, [%1, %2]		@ outlc"			\
-		: : "r" (v), "r" (PCIO_BASE), "Jr" (port));		\
-	else									\
-		__asm__ __volatile__(						\
-		"str	%0, [%1, %2]		@ outlc"			\
-		: : "r" (v), "r" (IO_BASE), "r" (port));			\
-})
-
-#define __inlc(port)								\
-({										\
-	unsigned long result;							\
-	if (__PORT_PCIO((port)))						\
-		__asm__ __volatile__(						\
-		"ldr	%0, [%1, %2]		@ inlc"				\
-		: "=r" (result) : "r" (PCIO_BASE), "Jr" (port));		\
-	else									\
-		__asm__ __volatile__(						\
-		"ldr	%0, [%1, %2]		@ inlc"				\
-		: "=r" (result) : "r" (IO_BASE), "r" (port));		\
-	result;									\
-})
-
-#define __ioaddrc(port)								\
-({										\
-	unsigned long addr;							\
-	if (__PORT_PCIO((port)))						\
-		addr = PCIO_BASE + (port);				\
-	else									\
-		addr = IO_BASE + (port);					\
-	addr;									\
-})
-
 #define __mem_pci(addr) (addr)
 
-#define inb(p)	 	(__builtin_constant_p((p)) ? __inbc(p)    : __inb(p))
-#define inw(p)	 	(__builtin_constant_p((p)) ? __inwc(p)    : __inw(p))
-#define inl(p)	 	(__builtin_constant_p((p)) ? __inlc(p)    : __inl(p))
-#define outb(v,p)	(__builtin_constant_p((p)) ? __outbc(v,p) : __outb(v,p))
-#define outw(v,p)	(__builtin_constant_p((p)) ? __outwc(v,p) : __outw(v,p))
-#define outl(v,p)	(__builtin_constant_p((p)) ? __outlc(v,p) : __outl(v,p))
-
 /*
  * Translated address IO functions
  *
diff --git a/include/asm-arm/arch-versatile/hardware.h b/include/asm-arm/arch-versatile/hardware.h
--- a/include/asm-arm/arch-versatile/hardware.h
+++ b/include/asm-arm/arch-versatile/hardware.h
@@ -25,19 +25,26 @@
 #include <asm/sizes.h>
 #include <asm/arch/platform.h>
 
-// FIXME = PCI settings need to be fixed!!!!!
-
 /*
- * Similar to above, but for PCI addresses (memory, IO, Config and the
- * V3 chip itself).  WARNING: this has to mirror definitions in platform.h
+ * PCI space virtual addresses
  */
-#define PCI_MEMORY_VADDR       0xe8000000
-#define PCI_CONFIG_VADDR       0xec000000
-#define PCI_V3_VADDR           0xed000000
-#define PCI_IO_VADDR           0xee000000
+#define VERSATILE_PCI_VIRT_BASE		0xe8000000
+#define VERSATILE_PCI_CFG_VIRT_BASE	0xe9000000
+
+#if 0
+#define VERSATILE_PCI_VIRT_MEM_BASE0	0xf4000000
+#define VERSATILE_PCI_VIRT_MEM_BASE1	0xf5000000
+#define VERSATILE_PCI_VIRT_MEM_BASE2	0xf6000000
+
+#define PCIO_BASE			VERSATILE_PCI_VIRT_MEM_BASE0
+#define PCIMEM_BASE			VERSATILE_PCI_VIRT_MEM_BASE1
+#endif
+
+/* CIK guesswork */
+#define PCIBIOS_MIN_IO			0x44000000
+#define PCIBIOS_MIN_MEM			0x50000000
 
-#define PCIO_BASE		PCI_IO_VADDR
-#define PCIMEM_BASE		PCI_MEMORY_VADDR
+#define pcibios_assign_all_busses()     1
 
 /* macro to get at IO space when running virtually */
 #define IO_ADDRESS(x)		(((x) & 0x0fffffff) + (((x) >> 4) & 0x0f000000) + 0xf0000000)
diff --git a/include/asm-arm/arch-versatile/io.h b/include/asm-arm/arch-versatile/io.h
--- a/include/asm-arm/arch-versatile/io.h
+++ b/include/asm-arm/arch-versatile/io.h
@@ -20,7 +20,7 @@
 #ifndef __ASM_ARM_ARCH_IO_H
 #define __ASM_ARM_ARCH_IO_H
 
-#define IO_SPACE_LIMIT 0xffff
+#define IO_SPACE_LIMIT 0xffffffff
 
 #define __io(a)			((void __iomem *)(a))
 #define __mem_pci(a)		(a)
diff --git a/include/asm-arm/arch-versatile/platform.h b/include/asm-arm/arch-versatile/platform.h
--- a/include/asm-arm/arch-versatile/platform.h
+++ b/include/asm-arm/arch-versatile/platform.h
@@ -76,7 +76,7 @@
 #define VERSATILE_SYS_NVFLAGSSET_OFFSET       0x38
 #define VERSATILE_SYS_NVFLAGSCLR_OFFSET       0x3C
 #define VERSATILE_SYS_RESETCTL_OFFSET         0x40
-#define VERSATILE_SYS_PICCTL_OFFSET           0x44
+#define VERSATILE_SYS_PCICTL_OFFSET           0x44
 #define VERSATILE_SYS_MCI_OFFSET              0x48
 #define VERSATILE_SYS_FLASH_OFFSET            0x4C
 #define VERSATILE_SYS_CLCD_OFFSET             0x50
@@ -114,7 +114,7 @@
 #define VERSATILE_SYS_NVFLAGSSET              (VERSATILE_SYS_BASE + VERSATILE_SYS_NVFLAGSSET_OFFSET)
 #define VERSATILE_SYS_NVFLAGSCLR              (VERSATILE_SYS_BASE + VERSATILE_SYS_NVFLAGSCLR_OFFSET)
 #define VERSATILE_SYS_RESETCTL                (VERSATILE_SYS_BASE + VERSATILE_SYS_RESETCTL_OFFSET)
-#define VERSATILE_SYS_PICCTL                  (VERSATILE_SYS_BASE + VERSATILE_SYS_PICCTL_OFFSET)
+#define VERSATILE_SYS_PCICTL                  (VERSATILE_SYS_BASE + VERSATILE_SYS_PCICTL_OFFSET)
 #define VERSATILE_SYS_MCI                     (VERSATILE_SYS_BASE + VERSATILE_SYS_MCI_OFFSET)
 #define VERSATILE_SYS_FLASH                   (VERSATILE_SYS_BASE + VERSATILE_SYS_FLASH_OFFSET)
 #define VERSATILE_SYS_CLCD                    (VERSATILE_SYS_BASE + VERSATILE_SYS_CLCD_OFFSET)
@@ -225,7 +225,20 @@
 #define VERSATILE_SSMC_BASE            0x20000000	/* SSMC */
 #define VERSATILE_IB2_BASE             0x24000000	/* IB2 module */
 #define VERSATILE_MBX_BASE             0x40000000	/* MBX */
+
+/* PCI space */
 #define VERSATILE_PCI_BASE             0x41000000	/* PCI Interface */
+#define VERSATILE_PCI_CFG_BASE	       0x42000000
+#define VERSATILE_PCI_MEM_BASE0        0x44000000
+#define VERSATILE_PCI_MEM_BASE1        0x50000000
+#define VERSATILE_PCI_MEM_BASE2        0x60000000
+/* Sizes of above maps */
+#define VERSATILE_PCI_BASE_SIZE	       0x01000000
+#define VERSATILE_PCI_CFG_BASE_SIZE    0x02000000
+#define VERSATILE_PCI_MEM_BASE0_SIZE   0x0c000000	/* 32Mb */
+#define VERSATILE_PCI_MEM_BASE1_SIZE   0x10000000	/* 256Mb */
+#define VERSATILE_PCI_MEM_BASE2_SIZE   0x10000000	/* 256Mb */
+
 #define VERSATILE_SDRAM67_BASE         0x70000000	/* SDRAM banks 6 and 7 */
 #define VERSATILE_LT_BASE              0x80000000	/* Logic Tile expansion */
 
diff --git a/include/asm-arm/bitops.h b/include/asm-arm/bitops.h
--- a/include/asm-arm/bitops.h
+++ b/include/asm-arm/bitops.h
@@ -21,8 +21,8 @@
 
 #include <asm/system.h>
 
-#define smp_mb__before_clear_bit()	do { } while (0)
-#define smp_mb__after_clear_bit()	do { } while (0)
+#define smp_mb__before_clear_bit()	mb()
+#define smp_mb__after_clear_bit()	mb()
 
 /*
  * These functions are the basis of our bit ops.
@@ -229,6 +229,7 @@ extern int _find_next_zero_bit_be(const 
 extern int _find_first_bit_be(const unsigned long *p, unsigned size);
 extern int _find_next_bit_be(const unsigned long *p, int size, int offset);
 
+#ifndef CONFIG_SMP
 /*
  * The __* form of bitops are non-atomic and may be reordered.
  */
@@ -241,6 +242,10 @@ extern int _find_next_bit_be(const unsig
 	(__builtin_constant_p(nr) ?		\
 	 ____atomic_##name(nr, p) :		\
 	 _##name##_be(nr,p))
+#else
+#define ATOMIC_BITOP_LE(name,nr,p)	_##name##_le(nr,p)
+#define ATOMIC_BITOP_BE(name,nr,p)	_##name##_be(nr,p)
+#endif
 
 #define NONATOMIC_BITOP(name,nr,p)		\
 	(____nonatomic_##name(nr, p))
diff --git a/include/asm-arm/bug.h b/include/asm-arm/bug.h
--- a/include/asm-arm/bug.h
+++ b/include/asm-arm/bug.h
@@ -5,7 +5,7 @@
 
 #ifdef CONFIG_BUG
 #ifdef CONFIG_DEBUG_BUGVERBOSE
-extern volatile void __bug(const char *file, int line, void *data);
+extern void __bug(const char *file, int line, void *data) __attribute__((noreturn));
 
 /* give file/line information */
 #define BUG()		__bug(__FILE__, __LINE__, NULL)
diff --git a/include/asm-arm/cacheflush.h b/include/asm-arm/cacheflush.h
--- a/include/asm-arm/cacheflush.h
+++ b/include/asm-arm/cacheflush.h
@@ -16,6 +16,9 @@
 
 #include <asm/mman.h>
 #include <asm/glue.h>
+#include <asm/shmparam.h>
+
+#define CACHE_COLOUR(vaddr)	((vaddr & (SHMLBA - 1)) >> PAGE_SHIFT)
 
 /*
  *	Cache Model
diff --git a/include/asm-arm/cpu-multi32.h b/include/asm-arm/cpu-multi32.h
--- a/include/asm-arm/cpu-multi32.h
+++ b/include/asm-arm/cpu-multi32.h
@@ -31,7 +31,7 @@ extern struct processor {
 	/*
 	 * Special stuff for a reset
 	 */
-	volatile void (*reset)(unsigned long addr);
+	void (*reset)(unsigned long addr) __attribute__((noreturn));
 	/*
 	 * Idle the processor
 	 */
diff --git a/include/asm-arm/cpu-single.h b/include/asm-arm/cpu-single.h
--- a/include/asm-arm/cpu-single.h
+++ b/include/asm-arm/cpu-single.h
@@ -41,4 +41,4 @@ extern int cpu_do_idle(void);
 extern void cpu_dcache_clean_area(void *, int);
 extern void cpu_do_switch_mm(unsigned long pgd_phys, struct mm_struct *mm);
 extern void cpu_set_pte(pte_t *ptep, pte_t pte);
-extern volatile void cpu_reset(unsigned long addr);
+extern void cpu_reset(unsigned long addr) __attribute__((noreturn));
diff --git a/include/asm-arm/emergency-restart.h b/include/asm-arm/emergency-restart.h
new file mode 100644
--- /dev/null
+++ b/include/asm-arm/emergency-restart.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_EMERGENCY_RESTART_H
+#define _ASM_EMERGENCY_RESTART_H
+
+#include <asm-generic/emergency-restart.h>
+
+#endif /* _ASM_EMERGENCY_RESTART_H */
diff --git a/include/asm-arm/hardware/arm_timer.h b/include/asm-arm/hardware/arm_timer.h
new file mode 100644
--- /dev/null
+++ b/include/asm-arm/hardware/arm_timer.h
@@ -0,0 +1,21 @@
+#ifndef __ASM_ARM_HARDWARE_ARM_TIMER_H
+#define __ASM_ARM_HARDWARE_ARM_TIMER_H
+
+#define TIMER_LOAD	0x00
+#define TIMER_VALUE	0x04
+#define TIMER_CTRL	0x08
+#define TIMER_CTRL_ONESHOT	(1 << 0)
+#define TIMER_CTRL_32BIT	(1 << 1)
+#define TIMER_CTRL_DIV1		(0 << 2)
+#define TIMER_CTRL_DIV16	(1 << 2)
+#define TIMER_CTRL_DIV256	(2 << 2)
+#define TIMER_CTRL_IE		(1 << 5)	/* Interrupt Enable (versatile only) */
+#define TIMER_CTRL_PERIODIC	(1 << 6)
+#define TIMER_CTRL_ENABLE	(1 << 7)
+
+#define TIMER_INTCLR	0x0c
+#define TIMER_RIS	0x10
+#define TIMER_MIS	0x14
+#define TIMER_BGLOAD	0x18
+
+#endif
diff --git a/include/asm-arm/ide.h b/include/asm-arm/ide.h
--- a/include/asm-arm/ide.h
+++ b/include/asm-arm/ide.h
@@ -5,7 +5,7 @@
  */
 
 /*
- *  This file contains the i386 architecture specific IDE code.
+ *  This file contains the ARM architecture specific IDE code.
  */
 
 #ifndef __ASMARM_IDE_H
diff --git a/include/asm-arm/io.h b/include/asm-arm/io.h
--- a/include/asm-arm/io.h
+++ b/include/asm-arm/io.h
@@ -82,7 +82,7 @@ extern void __readwrite_bug(const char *
  * only.  Their primary purpose is to access PCI and ISA peripherals.
  *
  * Note that for a big endian machine, this implies that the following
- * big endian mode connectivity is in place, as described by numerious
+ * big endian mode connectivity is in place, as described by numerous
  * ARM documents:
  *
  *    PCI:  D0-D7   D8-D15 D16-D23 D24-D31
@@ -273,6 +273,35 @@ extern void __iounmap(void __iomem *addr
 #endif
 
 /*
+ * io{read,write}{8,16,32} macros
+ */
+#ifndef ioread8
+#define ioread8(p)	({ unsigned int __v = __raw_readb(p); __v; })
+#define ioread16(p)	({ unsigned int __v = le16_to_cpu(__raw_readw(p)); __v; })
+#define ioread32(p)	({ unsigned int __v = le32_to_cpu(__raw_readl(p)); __v; })
+
+#define iowrite8(v,p)	__raw_writeb(v, p)
+#define iowrite16(v,p)	__raw_writew(cpu_to_le16(v), p)
+#define iowrite32(v,p)	__raw_writel(cpu_to_le32(v), p)
+
+#define ioread8_rep(p,d,c)	__raw_readsb(p,d,c)
+#define ioread16_rep(p,d,c)	__raw_readsw(p,d,c)
+#define ioread32_rep(p,d,c)	__raw_readsl(p,d,c)
+
+#define iowrite8_rep(p,s,c)	__raw_writesb(p,s,c)
+#define iowrite16_rep(p,s,c)	__raw_writesw(p,s,c)
+#define iowrite32_rep(p,s,c)	__raw_writesl(p,s,c)
+
+extern void __iomem *ioport_map(unsigned long port, unsigned int nr);
+extern void ioport_unmap(void __iomem *addr);
+#endif
+
+struct pci_dev;
+
+extern void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen);
+extern void pci_iounmap(struct pci_dev *dev, void __iomem *addr);
+
+/*
  * can the hardware map this into one segment or not, given no other
  * constraints.
  */
diff --git a/include/asm-arm/locks.h b/include/asm-arm/locks.h
--- a/include/asm-arm/locks.h
+++ b/include/asm-arm/locks.h
@@ -28,7 +28,8 @@
 "	blmi	" #fail				\
 	:					\
 	: "r" (ptr), "I" (1)			\
-	: "ip", "lr", "cc", "memory");		\
+	: "ip", "lr", "cc");			\
+	smp_mb();				\
 	})
 
 #define __down_op_ret(ptr,fail)			\
@@ -48,12 +49,14 @@
 "	mov	%0, ip"				\
 	: "=&r" (ret)				\
 	: "r" (ptr), "I" (1)			\
-	: "ip", "lr", "cc", "memory");		\
+	: "ip", "lr", "cc");			\
+	smp_mb();				\
 	ret;					\
 	})
 
 #define __up_op(ptr,wake)			\
 	({					\
+	smp_mb();				\
 	__asm__ __volatile__(			\
 	"@ up_op\n"				\
 "1:	ldrex	lr, [%0]\n"			\
@@ -61,12 +64,12 @@
 "	strex	ip, lr, [%0]\n"			\
 "	teq	ip, #0\n"			\
 "	bne	1b\n"				\
-"	teq	lr, #0\n"			\
+"	cmp	lr, #0\n"			\
 "	movle	ip, %0\n"			\
 "	blle	" #wake				\
 	:					\
 	: "r" (ptr), "I" (1)			\
-	: "ip", "lr", "cc", "memory");		\
+	: "ip", "lr", "cc");			\
 	})
 
 /*
@@ -92,15 +95,17 @@
 "	blne	" #fail				\
 	:					\
 	: "r" (ptr), "I" (RW_LOCK_BIAS)		\
-	: "ip", "lr", "cc", "memory");		\
+	: "ip", "lr", "cc");			\
+	smp_mb();				\
 	})
 
 #define __up_op_write(ptr,wake)			\
 	({					\
+	smp_mb();				\
 	__asm__ __volatile__(			\
 	"@ up_op_read\n"			\
 "1:	ldrex	lr, [%0]\n"			\
-"	add	lr, lr, %1\n"			\
+"	adds	lr, lr, %1\n"			\
 "	strex	ip, lr, [%0]\n"			\
 "	teq	ip, #0\n"			\
 "	bne	1b\n"				\
@@ -108,7 +113,7 @@
 "	blcs	" #wake				\
 	:					\
 	: "r" (ptr), "I" (RW_LOCK_BIAS)		\
-	: "ip", "lr", "cc", "memory");		\
+	: "ip", "lr", "cc");			\
 	})
 
 #define __down_op_read(ptr,fail)		\
@@ -116,6 +121,7 @@
 
 #define __up_op_read(ptr,wake)			\
 	({					\
+	smp_mb();				\
 	__asm__ __volatile__(			\
 	"@ up_op_read\n"			\
 "1:	ldrex	lr, [%0]\n"			\
@@ -128,7 +134,7 @@
 "	bleq	" #wake				\
 	:					\
 	: "r" (ptr), "I" (1)			\
-	: "ip", "lr", "cc", "memory");		\
+	: "ip", "lr", "cc");			\
 	})
 
 #else
@@ -148,7 +154,8 @@
 "	blmi	" #fail				\
 	:					\
 	: "r" (ptr), "I" (1)			\
-	: "ip", "lr", "cc", "memory");		\
+	: "ip", "lr", "cc");			\
+	smp_mb();				\
 	})
 
 #define __down_op_ret(ptr,fail)			\
@@ -169,12 +176,14 @@
 "	mov	%0, ip"				\
 	: "=&r" (ret)				\
 	: "r" (ptr), "I" (1)			\
-	: "ip", "lr", "cc", "memory");		\
+	: "ip", "lr", "cc");			\
+	smp_mb();				\
 	ret;					\
 	})
 
 #define __up_op(ptr,wake)			\
 	({					\
+	smp_mb();				\
 	__asm__ __volatile__(			\
 	"@ up_op\n"				\
 "	mrs	ip, cpsr\n"			\
@@ -188,7 +197,7 @@
 "	blle	" #wake				\
 	:					\
 	: "r" (ptr), "I" (1)			\
-	: "ip", "lr", "cc", "memory");		\
+	: "ip", "lr", "cc");			\
 	})
 
 /*
@@ -215,7 +224,8 @@
 "	blne	" #fail				\
 	:					\
 	: "r" (ptr), "I" (RW_LOCK_BIAS)		\
-	: "ip", "lr", "cc", "memory");		\
+	: "ip", "lr", "cc");			\
+	smp_mb();				\
 	})
 
 #define __up_op_write(ptr,wake)			\
@@ -233,7 +243,8 @@
 "	blcs	" #wake				\
 	:					\
 	: "r" (ptr), "I" (RW_LOCK_BIAS)		\
-	: "ip", "lr", "cc", "memory");		\
+	: "ip", "lr", "cc");			\
+	smp_mb();				\
 	})
 
 #define __down_op_read(ptr,fail)		\
@@ -241,6 +252,7 @@
 
 #define __up_op_read(ptr,wake)			\
 	({					\
+	smp_mb();				\
 	__asm__ __volatile__(			\
 	"@ up_op_read\n"			\
 "	mrs	ip, cpsr\n"			\
@@ -254,7 +266,7 @@
 "	bleq	" #wake				\
 	:					\
 	: "r" (ptr), "I" (1)			\
-	: "ip", "lr", "cc", "memory");		\
+	: "ip", "lr", "cc");			\
 	})
 
 #endif
diff --git a/include/asm-arm/mach/arch.h b/include/asm-arm/mach/arch.h
--- a/include/asm-arm/mach/arch.h
+++ b/include/asm-arm/mach/arch.h
@@ -26,7 +26,7 @@ struct machine_desc {
 						 * page tabe entry	*/
 
 	const char		*name;		/* architecture name	*/
-	unsigned int		param_offset;	/* parameter page	*/
+	unsigned long		boot_params;	/* tagged list		*/
 
 	unsigned int		video_start;	/* start of video RAM	*/
 	unsigned int		video_end;	/* end of video RAM	*/
@@ -54,38 +54,6 @@ const struct machine_desc __mach_desc_##
 	.nr		= MACH_TYPE_##_type,	\
 	.name		= _name,
 
-#define MAINTAINER(n)
-
-#define BOOT_MEM(_pram,_pio,_vio)		\
-	.phys_ram	= _pram,		\
-	.phys_io	= _pio,			\
-	.io_pg_offst	= ((_vio)>>18)&0xfffc,
-
-#define BOOT_PARAMS(_params)			\
-	.param_offset	= _params,
-
-#define VIDEO(_start,_end)			\
-	.video_start	= _start,		\
-	.video_end	= _end,
-
-#define DISABLE_PARPORT(_n)			\
-	.reserve_lp##_n	= 1,
-
-#define SOFT_REBOOT				\
-	.soft_reboot	= 1,
-
-#define FIXUP(_func)				\
-	.fixup		= _func,
-
-#define MAPIO(_func)				\
-	.map_io		= _func,
-
-#define INITIRQ(_func)				\
-	.init_irq	= _func,
-
-#define INIT_MACHINE(_func)			\
-	.init_machine	= _func,
-
 #define MACHINE_END				\
 };
 
diff --git a/include/asm-arm/mach/time.h b/include/asm-arm/mach/time.h
--- a/include/asm-arm/mach/time.h
+++ b/include/asm-arm/mach/time.h
@@ -39,8 +39,31 @@ struct sys_timer {
 	void			(*suspend)(void);
 	void			(*resume)(void);
 	unsigned long		(*offset)(void);
+
+#ifdef CONFIG_NO_IDLE_HZ
+	struct dyn_tick_timer	*dyn_tick;
+#endif
+};
+
+#ifdef CONFIG_NO_IDLE_HZ
+
+#define DYN_TICK_SKIPPING	(1 << 2)
+#define DYN_TICK_ENABLED	(1 << 1)
+#define DYN_TICK_SUITABLE	(1 << 0)
+
+struct dyn_tick_timer {
+	unsigned int	state;			/* Current state */
+	int		(*enable)(void);	/* Enables dynamic tick */
+	int		(*disable)(void);	/* Disables dynamic tick */
+	void		(*reprogram)(unsigned long); /* Reprograms the timer */
+	int		(*handler)(int, void *, struct pt_regs *);
 };
 
+void timer_dyn_reprogram(void);
+#else
+#define timer_dyn_reprogram()	do { } while (0)
+#endif
+
 extern struct sys_timer *system_timer;
 extern void timer_tick(struct pt_regs *);
 
diff --git a/include/asm-arm/mtd-xip.h b/include/asm-arm/mtd-xip.h
new file mode 100644
--- /dev/null
+++ b/include/asm-arm/mtd-xip.h
@@ -0,0 +1,26 @@
+/*
+ * MTD primitives for XIP support. Architecture specific functions
+ *
+ * Do not include this file directly. It's included from linux/mtd/xip.h
+ * 
+ * Author:	Nicolas Pitre
+ * Created:	Nov 2, 2004
+ * Copyright:	(C) 2004 MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * $Id: xip.h,v 1.2 2004/12/01 15:49:10 nico Exp $
+ */
+
+#ifndef __ARM_MTD_XIP_H__
+#define __ARM_MTD_XIP_H__
+
+#include <asm/hardware.h>
+#include <asm/arch/mtd-xip.h>
+
+/* fill instruction prefetch */
+#define xip_iprefetch() 	do { asm volatile (".rep 8; nop; .endr"); } while (0)
+
+#endif /* __ARM_MTD_XIP_H__ */
diff --git a/include/asm-arm/pci.h b/include/asm-arm/pci.h
--- a/include/asm-arm/pci.h
+++ b/include/asm-arm/pci.h
@@ -14,7 +14,7 @@ static inline void pcibios_set_master(st
 	/* No special bus mastering setup handling */
 }
 
-static inline void pcibios_penalize_isa_irq(int irq)
+static inline void pcibios_penalize_isa_irq(int irq, int active)
 {
 	/* We don't do dynamic PCI IRQ allocation */
 }
@@ -42,6 +42,16 @@ static inline void pcibios_penalize_isa_
 #define pci_unmap_len(PTR, LEN_NAME)		((PTR)->LEN_NAME)
 #define pci_unmap_len_set(PTR, LEN_NAME, VAL)	(((PTR)->LEN_NAME) = (VAL))
 
+#ifdef CONFIG_PCI
+static inline void pci_dma_burst_advice(struct pci_dev *pdev,
+					enum pci_dma_burst_strategy *strat,
+					unsigned long *strategy_parameter)
+{
+	*strat = PCI_DMA_BURST_INFINITY;
+	*strategy_parameter = ~0UL;
+}
+#endif
+
 #define HAVE_PCI_MMAP
 extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
                                enum pci_mmap_state mmap_state, int write_combine);
@@ -50,6 +60,10 @@ extern void
 pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
 			 struct resource *res);
 
+extern void
+pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
+			struct pci_bus_region *region);
+
 static inline void pcibios_add_platform_entries(struct pci_dev *dev)
 {
 }
diff --git a/include/asm-arm/pgalloc.h b/include/asm-arm/pgalloc.h
--- a/include/asm-arm/pgalloc.h
+++ b/include/asm-arm/pgalloc.h
@@ -89,6 +89,13 @@ static inline void pte_free(struct page 
 	__free_page(pte);
 }
 
+static inline void __pmd_populate(pmd_t *pmdp, unsigned long pmdval)
+{
+	pmdp[0] = __pmd(pmdval);
+	pmdp[1] = __pmd(pmdval + 256 * sizeof(pte_t));
+	flush_pmd_entry(pmdp);
+}
+
 /*
  * Populate the pmdp entry with a pointer to the pte.  This pmd is part
  * of the mm address space.
@@ -99,32 +106,19 @@ static inline void
 pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmdp, pte_t *ptep)
 {
 	unsigned long pte_ptr = (unsigned long)ptep;
-	unsigned long pmdval;
-
-	BUG_ON(mm != &init_mm);
 
 	/*
 	 * The pmd must be loaded with the physical
 	 * address of the PTE table
 	 */
 	pte_ptr -= PTRS_PER_PTE * sizeof(void *);
-	pmdval = __pa(pte_ptr) | _PAGE_KERNEL_TABLE;
-	pmdp[0] = __pmd(pmdval);
-	pmdp[1] = __pmd(pmdval + 256 * sizeof(pte_t));
-	flush_pmd_entry(pmdp);
+	__pmd_populate(pmdp, __pa(pte_ptr) | _PAGE_KERNEL_TABLE);
 }
 
 static inline void
 pmd_populate(struct mm_struct *mm, pmd_t *pmdp, struct page *ptep)
 {
-	unsigned long pmdval;
-
-	BUG_ON(mm == &init_mm);
-
-	pmdval = page_to_pfn(ptep) << PAGE_SHIFT | _PAGE_USER_TABLE;
-	pmdp[0] = __pmd(pmdval);
-	pmdp[1] = __pmd(pmdval + 256 * sizeof(pte_t));
-	flush_pmd_entry(pmdp);
+	__pmd_populate(pmdp, page_to_pfn(ptep) << PAGE_SHIFT | _PAGE_USER_TABLE);
 }
 
 #endif
diff --git a/include/asm-arm/pgtable.h b/include/asm-arm/pgtable.h
--- a/include/asm-arm/pgtable.h
+++ b/include/asm-arm/pgtable.h
@@ -188,12 +188,18 @@ extern void __pgd_error(const char *file
 /*
  *   - extended small page/tiny page
  */
+#define PTE_EXT_XN		(1 << 0)	/* v6 */
 #define PTE_EXT_AP_MASK		(3 << 4)
+#define PTE_EXT_AP0		(1 << 4)
+#define PTE_EXT_AP1		(2 << 4)
 #define PTE_EXT_AP_UNO_SRO	(0 << 4)
-#define PTE_EXT_AP_UNO_SRW	(1 << 4)
-#define PTE_EXT_AP_URO_SRW	(2 << 4)
-#define PTE_EXT_AP_URW_SRW	(3 << 4)
+#define PTE_EXT_AP_UNO_SRW	(PTE_EXT_AP0)
+#define PTE_EXT_AP_URO_SRW	(PTE_EXT_AP1)
+#define PTE_EXT_AP_URW_SRW	(PTE_EXT_AP1|PTE_EXT_AP0)
 #define PTE_EXT_TEX(x)		((x) << 6)	/* v5 */
+#define PTE_EXT_APX		(1 << 9)	/* v6 */
+#define PTE_EXT_SHARED		(1 << 10)	/* v6 */
+#define PTE_EXT_NG		(1 << 11)	/* v6 */
 
 /*
  *   - small page
@@ -224,6 +230,8 @@ extern void __pgd_error(const char *file
 #define L_PTE_WRITE		(1 << 5)
 #define L_PTE_EXEC		(1 << 6)
 #define L_PTE_DIRTY		(1 << 7)
+#define L_PTE_SHARED		(1 << 10)	/* shared between CPUs (v6) */
+#define L_PTE_ASID		(1 << 11)	/* non-global (use ASID, v6) */
 
 #ifndef __ASSEMBLY__
 
diff --git a/include/asm-arm/signal.h b/include/asm-arm/signal.h
--- a/include/asm-arm/signal.h
+++ b/include/asm-arm/signal.h
@@ -114,6 +114,7 @@ typedef unsigned long sigset_t;
 #define SIGSTKSZ	8192
 
 #ifdef __KERNEL__
+#define SA_TIMER		0x40000000
 #define SA_IRQNOMASK		0x08000000
 #endif
 
diff --git a/include/asm-arm/smp.h b/include/asm-arm/smp.h
--- a/include/asm-arm/smp.h
+++ b/include/asm-arm/smp.h
@@ -21,10 +21,7 @@
 # error "<asm-arm/smp.h> included in non-SMP build"
 #endif
 
-#define smp_processor_id()	(current_thread_info()->cpu)
-
-extern cpumask_t cpu_present_mask;
-#define cpu_possible_map cpu_present_mask
+#define raw_smp_processor_id() (current_thread_info()->cpu)
 
 /*
  * at the moment, there's not a big penalty for changing CPUs
@@ -55,4 +52,18 @@ extern void smp_cross_call(cpumask_t cal
  */
 extern int boot_secondary(unsigned int cpu, struct task_struct *);
 
+/*
+ * Perform platform specific initialisation of the specified CPU.
+ */
+extern void platform_secondary_init(unsigned int cpu);
+
+/*
+ * Initial data for bringing up a secondary CPU.
+ */
+struct secondary_data {
+	unsigned long pgdir;
+	void *stack;
+};
+extern struct secondary_data secondary_data;
+
 #endif /* ifndef __ASM_ARM_SMP_H */
diff --git a/include/asm-arm/spinlock.h b/include/asm-arm/spinlock.h
--- a/include/asm-arm/spinlock.h
+++ b/include/asm-arm/spinlock.h
@@ -8,9 +8,10 @@
 /*
  * ARMv6 Spin-locking.
  *
- * We (exclusively) read the old value, and decrement it.  If it
- * hits zero, we may have won the lock, so we try (exclusively)
- * storing it.
+ * We exclusively read the old value.  If it is zero, we may have
+ * won the lock, so we try exclusively storing it.  A memory barrier
+ * is required after we get a lock, and before we release it, because
+ * V6 CPUs are assumed to have weakly ordered memory.
  *
  * Unlocked value: 0
  * Locked value: 1
@@ -41,7 +42,9 @@ static inline void _raw_spin_lock(spinlo
 "	bne	1b"
 	: "=&r" (tmp)
 	: "r" (&lock->lock), "r" (1)
-	: "cc", "memory");
+	: "cc");
+
+	smp_mb();
 }
 
 static inline int _raw_spin_trylock(spinlock_t *lock)
@@ -54,18 +57,25 @@ static inline int _raw_spin_trylock(spin
 "	strexeq	%0, %2, [%1]"
 	: "=&r" (tmp)
 	: "r" (&lock->lock), "r" (1)
-	: "cc", "memory");
+	: "cc");
 
-	return tmp == 0;
+	if (tmp == 0) {
+		smp_mb();
+		return 1;
+	} else {
+		return 0;
+	}
 }
 
 static inline void _raw_spin_unlock(spinlock_t *lock)
 {
+	smp_mb();
+
 	__asm__ __volatile__(
 "	str	%1, [%0]"
 	:
 	: "r" (&lock->lock), "r" (0)
-	: "cc", "memory");
+	: "cc");
 }
 
 /*
@@ -79,7 +89,8 @@ typedef struct {
 } rwlock_t;
 
 #define RW_LOCK_UNLOCKED	(rwlock_t) { 0 }
-#define rwlock_init(x)		do { *(x) + RW_LOCK_UNLOCKED; } while (0)
+#define rwlock_init(x)		do { *(x) = RW_LOCK_UNLOCKED; } while (0)
+#define rwlock_is_locked(x)	(*((volatile unsigned int *)(x)) != 0)
 
 /*
  * Write locks are easy - we just set bit 31.  When unlocking, we can
@@ -97,16 +108,40 @@ static inline void _raw_write_lock(rwloc
 "	bne	1b"
 	: "=&r" (tmp)
 	: "r" (&rw->lock), "r" (0x80000000)
-	: "cc", "memory");
+	: "cc");
+
+	smp_mb();
+}
+
+static inline int _raw_write_trylock(rwlock_t *rw)
+{
+	unsigned long tmp;
+
+	__asm__ __volatile__(
+"1:	ldrex	%0, [%1]\n"
+"	teq	%0, #0\n"
+"	strexeq	%0, %2, [%1]"
+	: "=&r" (tmp)
+	: "r" (&rw->lock), "r" (0x80000000)
+	: "cc");
+
+	if (tmp == 0) {
+		smp_mb();
+		return 1;
+	} else {
+		return 0;
+	}
 }
 
 static inline void _raw_write_unlock(rwlock_t *rw)
 {
+	smp_mb();
+
 	__asm__ __volatile__(
 	"str	%1, [%0]"
 	:
 	: "r" (&rw->lock), "r" (0)
-	: "cc", "memory");
+	: "cc");
 }
 
 /*
@@ -133,11 +168,17 @@ static inline void _raw_read_lock(rwlock
 "	bmi	1b"
 	: "=&r" (tmp), "=&r" (tmp2)
 	: "r" (&rw->lock)
-	: "cc", "memory");
+	: "cc");
+
+	smp_mb();
 }
 
 static inline void _raw_read_unlock(rwlock_t *rw)
 {
+	unsigned long tmp, tmp2;
+
+	smp_mb();
+
 	__asm__ __volatile__(
 "1:	ldrex	%0, [%2]\n"
 "	sub	%0, %0, #1\n"
@@ -146,24 +187,9 @@ static inline void _raw_read_unlock(rwlo
 "	bne	1b"
 	: "=&r" (tmp), "=&r" (tmp2)
 	: "r" (&rw->lock)
-	: "cc", "memory");
+	: "cc");
 }
 
 #define _raw_read_trylock(lock) generic_raw_read_trylock(lock)
 
-static inline int _raw_write_trylock(rwlock_t *rw)
-{
-	unsigned long tmp;
-
-	__asm__ __volatile__(
-"1:	ldrex	%0, [%1]\n"
-"	teq	%0, #0\n"
-"	strexeq	%0, %2, [%1]"
-	: "=&r" (tmp)
-	: "r" (&rw->lock), "r" (0x80000000)
-	: "cc", "memory");
-
-	return tmp == 0;
-}
-
 #endif /* __ASM_SPINLOCK_H */
diff --git a/include/asm-arm/stat.h b/include/asm-arm/stat.h
--- a/include/asm-arm/stat.h
+++ b/include/asm-arm/stat.h
@@ -89,6 +89,6 @@ struct stat64 {
 	unsigned long	st_ctime_nsec;
 
 	unsigned long long	st_ino;
-};
+} __attribute__((packed));
 
 #endif
diff --git a/include/asm-arm/system.h b/include/asm-arm/system.h
--- a/include/asm-arm/system.h
+++ b/include/asm-arm/system.h
@@ -85,7 +85,9 @@ struct pt_regs;
 void die(const char *msg, struct pt_regs *regs, int err)
 		__attribute__((noreturn));
 
-void die_if_kernel(const char *str, struct pt_regs *regs, int err);
+struct siginfo;
+void notify_die(const char *str, struct pt_regs *regs, struct siginfo *info,
+		unsigned long err, unsigned long trap);
 
 void hook_fault_code(int nr, int (*fn)(unsigned long, unsigned int,
 				       struct pt_regs *),
@@ -104,6 +106,7 @@ extern void show_pte(struct mm_struct *m
 extern void __show_regs(struct pt_regs *);
 
 extern int cpu_architecture(void);
+extern void cpu_init(void);
 
 #define set_cr(x)					\
 	__asm__ __volatile__(				\
@@ -136,7 +139,12 @@ extern unsigned int user_debug;
 #define vectors_high()	(0)
 #endif
 
+#if __LINUX_ARM_ARCH__ >= 6
+#define mb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" \
+                                   : : "r" (0) : "memory")
+#else
 #define mb() __asm__ __volatile__ ("" : : : "memory")
+#endif
 #define rmb() mb()
 #define wmb() mb()
 #define read_barrier_depends() do { } while(0)
@@ -144,34 +152,12 @@ extern unsigned int user_debug;
 #define set_wmb(var, value) do { var = value; wmb(); } while (0)
 #define nop() __asm__ __volatile__("mov\tr0,r0\t@ nop\n\t");
 
-#ifdef CONFIG_SMP
 /*
- * Define our own context switch locking.  This allows us to enable
- * interrupts over the context switch, otherwise we end up with high
- * interrupt latency.  The real problem area is switch_mm() which may
- * do a full cache flush.
+ * switch_mm() may do a full cache flush over the context switch,
+ * so enable interrupts over the context switch to avoid high
+ * latency.
  */
-#define prepare_arch_switch(rq,next)					\
-do {									\
-	spin_lock(&(next)->switch_lock);				\
-	spin_unlock_irq(&(rq)->lock);					\
-} while (0)
-
-#define finish_arch_switch(rq,prev)					\
-	spin_unlock(&(prev)->switch_lock)
-
-#define task_running(rq,p)						\
-	((rq)->curr == (p) || spin_is_locked(&(p)->switch_lock))
-#else
-/*
- * Our UP-case is more simple, but we assume knowledge of how
- * spin_unlock_irq() and friends are implemented.  This avoids
- * us needlessly decrementing and incrementing the preempt count.
- */
-#define prepare_arch_switch(rq,next)	local_irq_enable()
-#define finish_arch_switch(rq,prev)	spin_unlock(&(rq)->lock)
-#define task_running(rq,p)		((rq)->curr == (p))
-#endif
+#define __ARCH_WANT_INTERRUPTS_ON_CTXSW
 
 /*
  * switch_to(prev, next) should switch from task `prev' to `next'
@@ -307,11 +293,10 @@ do {									\
 ({					\
 	unsigned long flags;		\
 	local_save_flags(flags);	\
-	flags & PSR_I_BIT;		\
+	(int)(flags & PSR_I_BIT);	\
 })
 
 #ifdef CONFIG_SMP
-#error SMP not supported
 
 #define smp_mb()		mb()
 #define smp_rmb()		rmb()
@@ -325,6 +310,8 @@ do {									\
 #define smp_wmb()		barrier()
 #define smp_read_barrier_depends()		do { } while(0)
 
+#endif /* CONFIG_SMP */
+
 #if defined(CONFIG_CPU_SA1100) || defined(CONFIG_CPU_SA110)
 /*
  * On the StrongARM, "swp" is terminally broken since it bypasses the
@@ -337,6 +324,9 @@ do {									\
  *
  * We choose (1) since its the "easiest" to achieve here and is not
  * dependent on the processor type.
+ *
+ * NOTE that this solution won't work on an SMP system, so explcitly
+ * forbid it here.
  */
 #define swp_is_buggy
 #endif
@@ -348,42 +338,73 @@ static inline unsigned long __xchg(unsig
 #ifdef swp_is_buggy
 	unsigned long flags;
 #endif
+#if __LINUX_ARM_ARCH__ >= 6
+	unsigned int tmp;
+#endif
 
 	switch (size) {
-#ifdef swp_is_buggy
-		case 1:
-			local_irq_save(flags);
-			ret = *(volatile unsigned char *)ptr;
-			*(volatile unsigned char *)ptr = x;
-			local_irq_restore(flags);
-			break;
-
-		case 4:
-			local_irq_save(flags);
-			ret = *(volatile unsigned long *)ptr;
-			*(volatile unsigned long *)ptr = x;
-			local_irq_restore(flags);
-			break;
+#if __LINUX_ARM_ARCH__ >= 6
+	case 1:
+		asm volatile("@	__xchg1\n"
+		"1:	ldrexb	%0, [%3]\n"
+		"	strexb	%1, %2, [%3]\n"
+		"	teq	%1, #0\n"
+		"	bne	1b"
+			: "=&r" (ret), "=&r" (tmp)
+			: "r" (x), "r" (ptr)
+			: "memory", "cc");
+		break;
+	case 4:
+		asm volatile("@	__xchg4\n"
+		"1:	ldrex	%0, [%3]\n"
+		"	strex	%1, %2, [%3]\n"
+		"	teq	%1, #0\n"
+		"	bne	1b"
+			: "=&r" (ret), "=&r" (tmp)
+			: "r" (x), "r" (ptr)
+			: "memory", "cc");
+		break;
+#elif defined(swp_is_buggy)
+#ifdef CONFIG_SMP
+#error SMP is not supported on this platform
+#endif
+	case 1:
+		local_irq_save(flags);
+		ret = *(volatile unsigned char *)ptr;
+		*(volatile unsigned char *)ptr = x;
+		local_irq_restore(flags);
+		break;
+
+	case 4:
+		local_irq_save(flags);
+		ret = *(volatile unsigned long *)ptr;
+		*(volatile unsigned long *)ptr = x;
+		local_irq_restore(flags);
+		break;
 #else
-		case 1:	__asm__ __volatile__ ("swpb %0, %1, [%2]"
-					: "=&r" (ret)
-					: "r" (x), "r" (ptr)
-					: "memory", "cc");
-			break;
-		case 4:	__asm__ __volatile__ ("swp %0, %1, [%2]"
-					: "=&r" (ret)
-					: "r" (x), "r" (ptr)
-					: "memory", "cc");
-			break;
+	case 1:
+		asm volatile("@	__xchg1\n"
+		"	swpb	%0, %1, [%2]"
+			: "=&r" (ret)
+			: "r" (x), "r" (ptr)
+			: "memory", "cc");
+		break;
+	case 4:
+		asm volatile("@	__xchg4\n"
+		"	swp	%0, %1, [%2]"
+			: "=&r" (ret)
+			: "r" (x), "r" (ptr)
+			: "memory", "cc");
+		break;
 #endif
-		default: __bad_xchg(ptr, size), ret = 0;
+	default:
+		__bad_xchg(ptr, size), ret = 0;
+		break;
 	}
 
 	return ret;
 }
 
-#endif /* CONFIG_SMP */
-
 #endif /* __ASSEMBLY__ */
 
 #define arch_align_stack(x) (x)
diff --git a/include/asm-arm/thread_info.h b/include/asm-arm/thread_info.h
--- a/include/asm-arm/thread_info.h
+++ b/include/asm-arm/thread_info.h
@@ -49,7 +49,7 @@ struct cpu_context_save {
  */
 struct thread_info {
 	unsigned long		flags;		/* low level flags */
-	__s32			preempt_count;	/* 0 => preemptable, <0 => bug */
+	int			preempt_count;	/* 0 => preemptable, <0 => bug */
 	mm_segment_t		addr_limit;	/* address limit */
 	struct task_struct	*task;		/* main task structure */
 	struct exec_domain	*exec_domain;	/* execution domain */
diff --git a/include/asm-arm/tlbflush.h b/include/asm-arm/tlbflush.h
--- a/include/asm-arm/tlbflush.h
+++ b/include/asm-arm/tlbflush.h
@@ -235,7 +235,7 @@ extern struct cpu_tlb_fns cpu_tlb;
 
 #define tlb_flag(f)	((always_tlb_flags & (f)) || (__tlb_flag & possible_tlb_flags & (f)))
 
-static inline void flush_tlb_all(void)
+static inline void local_flush_tlb_all(void)
 {
 	const int zero = 0;
 	const unsigned int __tlb_flag = __cpu_tlb_flags;
@@ -253,7 +253,7 @@ static inline void flush_tlb_all(void)
 		asm("mcr%? p15, 0, %0, c8, c5, 0" : : "r" (zero));
 }
 
-static inline void flush_tlb_mm(struct mm_struct *mm)
+static inline void local_flush_tlb_mm(struct mm_struct *mm)
 {
 	const int zero = 0;
 	const int asid = ASID(mm);
@@ -282,7 +282,7 @@ static inline void flush_tlb_mm(struct m
 }
 
 static inline void
-flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr)
+local_flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr)
 {
 	const int zero = 0;
 	const unsigned int __tlb_flag = __cpu_tlb_flags;
@@ -313,7 +313,7 @@ flush_tlb_page(struct vm_area_struct *vm
 		asm("mcr%? p15, 0, %0, c8, c5, 1" : : "r" (uaddr));
 }
 
-static inline void flush_tlb_kernel_page(unsigned long kaddr)
+static inline void local_flush_tlb_kernel_page(unsigned long kaddr)
 {
 	const int zero = 0;
 	const unsigned int __tlb_flag = __cpu_tlb_flags;
@@ -384,8 +384,24 @@ static inline void clean_pmd_entry(pmd_t
 /*
  * Convert calls to our calling convention.
  */
-#define flush_tlb_range(vma,start,end)	__cpu_flush_user_tlb_range(start,end,vma)
-#define flush_tlb_kernel_range(s,e)	__cpu_flush_kern_tlb_range(s,e)
+#define local_flush_tlb_range(vma,start,end)	__cpu_flush_user_tlb_range(start,end,vma)
+#define local_flush_tlb_kernel_range(s,e)	__cpu_flush_kern_tlb_range(s,e)
+
+#ifndef CONFIG_SMP
+#define flush_tlb_all		local_flush_tlb_all
+#define flush_tlb_mm		local_flush_tlb_mm
+#define flush_tlb_page		local_flush_tlb_page
+#define flush_tlb_kernel_page	local_flush_tlb_kernel_page
+#define flush_tlb_range		local_flush_tlb_range
+#define flush_tlb_kernel_range	local_flush_tlb_kernel_range
+#else
+extern void flush_tlb_all(void);
+extern void flush_tlb_mm(struct mm_struct *mm);
+extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr);
+extern void flush_tlb_kernel_page(unsigned long kaddr);
+extern void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned long end);
+extern void flush_tlb_kernel_range(unsigned long start, unsigned long end);
+#endif
 
 /*
  * if PG_dcache_dirty is set for the page, we need to ensure that any
diff --git a/include/asm-arm/unistd.h b/include/asm-arm/unistd.h
--- a/include/asm-arm/unistd.h
+++ b/include/asm-arm/unistd.h
@@ -350,6 +350,11 @@
 #endif
 
 #define __NR_vserver			(__NR_SYSCALL_BASE+313)
+#define __NR_ioprio_set			(__NR_SYSCALL_BASE+314)
+#define __NR_ioprio_get			(__NR_SYSCALL_BASE+315)
+#define __NR_inotify_init		(__NR_SYSCALL_BASE+316)
+#define __NR_inotify_add_watch		(__NR_SYSCALL_BASE+317)
+#define __NR_inotify_rm_watch		(__NR_SYSCALL_BASE+318)
 
 /*
  * The following SWIs are ARM private.
diff --git a/include/asm-arm26/emergency-restart.h b/include/asm-arm26/emergency-restart.h
new file mode 100644
--- /dev/null
+++ b/include/asm-arm26/emergency-restart.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_EMERGENCY_RESTART_H
+#define _ASM_EMERGENCY_RESTART_H
+
+#include <asm-generic/emergency-restart.h>
+
+#endif /* _ASM_EMERGENCY_RESTART_H */
diff --git a/include/asm-arm26/serial.h b/include/asm-arm26/serial.h
--- a/include/asm-arm26/serial.h
+++ b/include/asm-arm26/serial.h
@@ -30,34 +30,16 @@
 #if defined(CONFIG_ARCH_A5K)
      /* UART CLK        PORT  IRQ     FLAGS        */
 
-#define STD_SERIAL_PORT_DEFNS                                           \
+#define SERIAL_PORT_DFNS                                                \
         { 0, BASE_BAUD, 0x3F8, 10, STD_COM_FLAGS },     /* ttyS0 */     \
         { 0, BASE_BAUD, 0x2F8, 10, STD_COM_FLAGS },     /* ttyS1 */
 
 #else
 
-#define STD_SERIAL_PORT_DEFNS                                           \
+#define SERIAL_PORT_DFNS                                                \
         { 0, BASE_BAUD, 0    ,  0, STD_COM_FLAGS },     /* ttyS0 */     \
         { 0, BASE_BAUD, 0    ,  0, STD_COM_FLAGS },     /* ttyS1 */
 
 #endif
 
-#define EXTRA_SERIAL_PORT_DEFNS \
-        { 0, BASE_BAUD, 0    ,  0, STD_COM_FLAGS },     /* ttyS2 */     \
-        { 0, BASE_BAUD, 0    ,  0, STD_COM_FLAGS },     /* ttyS3 */     \
-        { 0, BASE_BAUD, 0    ,  0, STD_COM_FLAGS },     /* ttyS4 */     \
-        { 0, BASE_BAUD, 0    ,  0, STD_COM_FLAGS },     /* ttyS5 */     \
-        { 0, BASE_BAUD, 0    ,  0, STD_COM_FLAGS },     /* ttyS6 */     \
-        { 0, BASE_BAUD, 0    ,  0, STD_COM_FLAGS },     /* ttyS7 */     \
-        { 0, BASE_BAUD, 0    ,  0, STD_COM_FLAGS },     /* ttyS8 */     \
-        { 0, BASE_BAUD, 0    ,  0, STD_COM_FLAGS },     /* ttyS9 */     \
-        { 0, BASE_BAUD, 0    ,  0, STD_COM_FLAGS },     /* ttyS10 */    \
-        { 0, BASE_BAUD, 0    ,  0, STD_COM_FLAGS },     /* ttyS11 */    \
-        { 0, BASE_BAUD, 0    ,  0, STD_COM_FLAGS },     /* ttyS12 */    \
-        { 0, BASE_BAUD, 0    ,  0, STD_COM_FLAGS },     /* ttyS13 */
-
-#define SERIAL_PORT_DFNS		\
-	STD_SERIAL_PORT_DEFNS		\
-	EXTRA_SERIAL_PORT_DEFNS
-
 #endif
diff --git a/include/asm-arm26/thread_info.h b/include/asm-arm26/thread_info.h
--- a/include/asm-arm26/thread_info.h
+++ b/include/asm-arm26/thread_info.h
@@ -44,7 +44,7 @@ struct cpu_context_save {
  */
 struct thread_info {
 	unsigned long		flags;		/* low level flags */
-	__s32			preempt_count;	/* 0 => preemptable, <0 => bug */
+	int			preempt_count;	/* 0 => preemptable, <0 => bug */
 	mm_segment_t		addr_limit;	/* address limit */
 	struct task_struct	*task;		/* main task structure */
 	struct exec_domain      *exec_domain;   /* execution domain */
diff --git a/include/asm-cris/arch-v10/atomic.h b/include/asm-cris/arch-v10/atomic.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v10/atomic.h
@@ -0,0 +1,7 @@
+#ifndef __ASM_CRIS_ARCH_ATOMIC__
+#define __ASM_CRIS_ARCH_ATOMIC__
+
+#define cris_atomic_save(addr, flags) local_irq_save(flags);
+#define cris_atomic_restore(addr, flags) local_irq_restore(flags);
+
+#endif
diff --git a/include/asm-cris/arch-v10/bitops.h b/include/asm-cris/arch-v10/bitops.h
--- a/include/asm-cris/arch-v10/bitops.h
+++ b/include/asm-cris/arch-v10/bitops.h
@@ -51,7 +51,7 @@ extern inline unsigned long ffz(unsigned
  *
  * Undefined if no bit exists, so code should check against 0 first.
  */
-extern __inline__ unsigned long __ffs(unsigned long word)
+extern inline unsigned long __ffs(unsigned long word)
 {
 	return cris_swapnwbrlz(~word);
 }
diff --git a/include/asm-cris/arch-v10/dma.h b/include/asm-cris/arch-v10/dma.h
--- a/include/asm-cris/arch-v10/dma.h
+++ b/include/asm-cris/arch-v10/dma.h
@@ -44,3 +44,31 @@
 #define USB_RX_DMA_NBR 9
 
 #endif
+
+enum dma_owner
+{
+  dma_eth,
+  dma_ser0,
+  dma_ser1, /* Async and sync */
+  dma_ser2,
+  dma_ser3, /* Async and sync */
+  dma_ata,
+  dma_par0,
+  dma_par1,
+  dma_ext0,
+  dma_ext1,
+  dma_int6,
+  dma_int7,
+  dma_usb,
+  dma_scsi0,
+  dma_scsi1
+};
+
+/* Masks used by cris_request_dma options: */
+#define DMA_VERBOSE_ON_ERROR    (1<<0)
+#define DMA_PANIC_ON_ERROR     ((1<<1)|DMA_VERBOSE_ON_ERROR)
+
+int cris_request_dma(unsigned int dmanr, const char * device_id,
+                     unsigned options, enum dma_owner owner);
+
+void cris_free_dma(unsigned int dmanr, const char * device_id);
diff --git a/include/asm-cris/arch-v10/elf.h b/include/asm-cris/arch-v10/elf.h
--- a/include/asm-cris/arch-v10/elf.h
+++ b/include/asm-cris/arch-v10/elf.h
@@ -1,6 +1,16 @@
 #ifndef __ASMCRIS_ARCH_ELF_H
 #define __ASMCRIS_ARCH_ELF_H
 
+#define ELF_MACH EF_CRIS_VARIANT_ANY_V0_V10
+
+/*
+ * This is used to ensure we don't load something for the wrong architecture.
+ */
+#define elf_check_arch(x)			\
+ ((x)->e_machine == EM_CRIS			\
+  && ((((x)->e_flags & EF_CRIS_VARIANT_MASK) == EF_CRIS_VARIANT_ANY_V0_V10	\
+      || (((x)->e_flags & EF_CRIS_VARIANT_MASK) == EF_CRIS_VARIANT_COMMON_V10_V32))))
+
 /*
  * ELF register definitions..
  */
diff --git a/include/asm-cris/arch-v10/ide.h b/include/asm-cris/arch-v10/ide.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v10/ide.h
@@ -0,0 +1,99 @@
+/*
+ *  linux/include/asm-cris/ide.h
+ *
+ *  Copyright (C) 2000, 2001, 2002  Axis Communications AB
+ *
+ *  Authors:    Bjorn Wesen
+ *
+ */
+
+/*
+ *  This file contains the ETRAX 100LX specific IDE code.
+ */
+
+#ifndef __ASMCRIS_IDE_H
+#define __ASMCRIS_IDE_H
+
+#ifdef __KERNEL__
+
+#include <asm/arch/svinto.h>
+#include <asm/io.h>
+#include <asm-generic/ide_iops.h>
+
+
+/* ETRAX 100 can support 4 IDE busses on the same pins (serialized) */
+
+#define MAX_HWIFS	4
+
+extern __inline__ int ide_default_irq(unsigned long base)
+{
+	/* all IDE busses share the same IRQ, number 4.
+	 * this has the side-effect that ide-probe.c will cluster our 4 interfaces
+	 * together in a hwgroup, and will serialize accesses. this is good, because
+	 * we can't access more than one interface at the same time on ETRAX100.
+	 */
+	return 4;
+}
+
+extern __inline__ unsigned long ide_default_io_base(int index)
+{
+	/* we have no real I/O base address per interface, since all go through the
+	 * same register. but in a bitfield in that register, we have the i/f number.
+	 * so we can use the io_base to remember that bitfield.
+	 */
+	static const unsigned long io_bases[MAX_HWIFS] = {
+		IO_FIELD(R_ATA_CTRL_DATA, sel, 0),
+		IO_FIELD(R_ATA_CTRL_DATA, sel, 1),
+		IO_FIELD(R_ATA_CTRL_DATA, sel, 2),
+		IO_FIELD(R_ATA_CTRL_DATA, sel, 3)
+	};
+	return io_bases[index];
+}
+
+/* this is called once for each interface, to setup the port addresses. data_port is the result
+ * of the ide_default_io_base call above. ctrl_port will be 0, but that is don't care for us.
+ */
+
+extern __inline__ void ide_init_hwif_ports(hw_regs_t *hw, unsigned long data_port, unsigned long ctrl_port, int *irq)
+{
+	int i;
+
+	/* fill in ports for ATA addresses 0 to 7 */
+
+	for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
+		hw->io_ports[i] = data_port |
+			IO_FIELD(R_ATA_CTRL_DATA, addr, i) |
+			IO_STATE(R_ATA_CTRL_DATA, cs0, active);
+	}
+
+	/* the IDE control register is at ATA address 6, with CS1 active instead of CS0 */
+
+	hw->io_ports[IDE_CONTROL_OFFSET] = data_port |
+			IO_FIELD(R_ATA_CTRL_DATA, addr, 6) |
+			IO_STATE(R_ATA_CTRL_DATA, cs1, active);
+
+	/* whats this for ? */
+
+	hw->io_ports[IDE_IRQ_OFFSET] = 0;
+}
+
+extern __inline__ void ide_init_default_hwifs(void)
+{
+	hw_regs_t hw;
+	int index;
+
+	for(index = 0; index < MAX_HWIFS; index++) {
+		ide_init_hwif_ports(&hw, ide_default_io_base(index), 0, NULL);
+		hw.irq = ide_default_irq(ide_default_io_base(index));
+		ide_register_hw(&hw, NULL);
+	}
+}
+
+/* some configuration options we don't need */
+
+#undef SUPPORT_VLB_SYNC
+#define SUPPORT_VLB_SYNC 0
+
+#endif /* __KERNEL__ */
+
+#endif /* __ASMCRIS_IDE_H */
diff --git a/include/asm-cris/arch-v10/io.h b/include/asm-cris/arch-v10/io.h
--- a/include/asm-cris/arch-v10/io.h
+++ b/include/asm-cris/arch-v10/io.h
@@ -6,6 +6,7 @@
 
 /* Etrax shadow registers - which live in arch/cris/kernel/shadows.c */
 
+extern unsigned long gen_config_ii_shadow;
 extern unsigned long port_g_data_shadow;
 extern unsigned char port_pa_dir_shadow;
 extern unsigned char port_pa_data_shadow;
diff --git a/include/asm-cris/arch-v10/io_interface_mux.h b/include/asm-cris/arch-v10/io_interface_mux.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v10/io_interface_mux.h
@@ -0,0 +1,75 @@
+/* IO interface mux allocator for ETRAX100LX.
+ * Copyright 2004, Axis Communications AB
+ * $Id: io_interface_mux.h,v 1.1 2004/12/13 12:21:53 starvik Exp $
+ */
+
+
+#ifndef _IO_INTERFACE_MUX_H
+#define _IO_INTERFACE_MUX_H
+
+
+/* C.f. ETRAX100LX Designer's Reference 20.9 */
+
+/* The order in enum must match the order of interfaces[] in
+ * io_interface_mux.c */
+enum cris_io_interface {
+	/* Begin Non-multiplexed interfaces */
+	if_eth = 0,
+	if_serial_0,
+	/* End Non-multiplexed interfaces */
+	if_serial_1,
+	if_serial_2,
+	if_serial_3,
+	if_sync_serial_1,
+	if_sync_serial_3,
+	if_shared_ram,
+	if_shared_ram_w,
+	if_par_0,
+	if_par_1,
+	if_par_w,
+	if_scsi8_0,
+	if_scsi8_1,
+	if_scsi_w,
+	if_ata,
+	if_csp,
+	if_i2c,
+	if_usb_1,
+	if_usb_2,
+	/* GPIO pins */
+	if_gpio_grp_a,
+	if_gpio_grp_b,
+	if_gpio_grp_c,
+	if_gpio_grp_d,
+	if_gpio_grp_e,
+	if_gpio_grp_f,
+	if_max_interfaces,
+	if_unclaimed
+};
+
+int cris_request_io_interface(enum cris_io_interface ioif, const char *device_id);
+
+void cris_free_io_interface(enum cris_io_interface ioif);
+
+/* port can be 'a', 'b' or 'g' */
+int cris_io_interface_allocate_pins(const enum cris_io_interface ioif,
+				    const char port,
+				    const unsigned start_bit,
+				    const unsigned stop_bit);
+
+/* port can be 'a', 'b' or 'g' */
+int cris_io_interface_free_pins(const enum cris_io_interface ioif,
+                                const char port,
+                                const unsigned start_bit,
+                                const unsigned stop_bit);
+
+int cris_io_interface_register_watcher(void (*notify)(const unsigned int gpio_in_available,
+						      const unsigned int gpio_out_available,
+						      const unsigned char pa_available,
+						      const unsigned char pb_available));
+
+void cris_io_interface_delete_watcher(void (*notify)(const unsigned int gpio_in_available,
+						     const unsigned int gpio_out_available,
+                                                     const unsigned char pa_available,
+						     const unsigned char pb_available));
+
+#endif /* _IO_INTERFACE_MUX_H */
diff --git a/include/asm-cris/arch-v10/irq.h b/include/asm-cris/arch-v10/irq.h
--- a/include/asm-cris/arch-v10/irq.h
+++ b/include/asm-cris/arch-v10/irq.h
@@ -74,12 +74,9 @@ struct etrax_interrupt_vector {
 };
 
 extern struct etrax_interrupt_vector *etrax_irv;
-void set_int_vector(int n, irqvectptr addr, irqvectptr saddr);
+void set_int_vector(int n, irqvectptr addr);
 void set_break_vector(int n, irqvectptr addr);
 
-#define mask_irq(irq_nr) (*R_VECT_MASK_CLR = 1 << (irq_nr));
-#define unmask_irq(irq_nr) (*R_VECT_MASK_SET = 1 << (irq_nr));
-
 #define __STR(x) #x
 #define STR(x) __STR(x)
  
@@ -121,26 +118,17 @@ void set_break_vector(int n, irqvectptr 
 
 #define BUILD_IRQ(nr,mask) \
 void IRQ_NAME(nr); \
-void sIRQ_NAME(nr); \
-void BAD_IRQ_NAME(nr); \
 __asm__ ( \
           ".text\n\t" \
           "IRQ" #nr "_interrupt:\n\t" \
 	  SAVE_ALL \
-	  "sIRQ" #nr "_interrupt:\n\t" /* shortcut for the multiple irq handler */ \
 	  BLOCK_IRQ(mask,nr) /* this must be done to prevent irq loops when we ei later */ \
 	  "moveq "#nr",$r10\n\t" \
 	  "move.d $sp,$r11\n\t" \
 	  "jsr do_IRQ\n\t" /* irq.c, r10 and r11 are arguments */ \
 	  UNBLOCK_IRQ(mask) \
 	  "moveq 0,$r9\n\t" /* make ret_from_intr realise we came from an irq */ \
-	  "jump ret_from_intr\n\t" \
-          "bad_IRQ" #nr "_interrupt:\n\t" \
-	  "push $r0\n\t" \
-	  BLOCK_IRQ(mask,nr) \
-	  "pop $r0\n\t" \
-          "reti\n\t" \
-          "nop\n");
+	  "jump ret_from_intr\n\t");
 
 /* This is subtle. The timer interrupt is crucial and it should not be disabled for 
  * too long. However, if it had been a normal interrupt as per BUILD_IRQ, it would
@@ -159,23 +147,14 @@ __asm__ ( \
 
 #define BUILD_TIMER_IRQ(nr,mask) \
 void IRQ_NAME(nr); \
-void sIRQ_NAME(nr); \
-void BAD_IRQ_NAME(nr); \
 __asm__ ( \
           ".text\n\t" \
           "IRQ" #nr "_interrupt:\n\t" \
 	  SAVE_ALL \
-	  "sIRQ" #nr "_interrupt:\n\t" /* shortcut for the multiple irq handler */ \
 	  "moveq "#nr",$r10\n\t" \
 	  "move.d $sp,$r11\n\t" \
 	  "jsr do_IRQ\n\t" /* irq.c, r10 and r11 are arguments */ \
 	  "moveq 0,$r9\n\t" /* make ret_from_intr realise we came from an irq */ \
-	  "jump ret_from_intr\n\t" \
-          "bad_IRQ" #nr "_interrupt:\n\t" \
-	  "push $r0\n\t" \
-	  BLOCK_IRQ(mask,nr) \
-	  "pop $r0\n\t" \
-          "reti\n\t" \
-          "nop\n");
+	  "jump ret_from_intr\n\t");
 
 #endif
diff --git a/include/asm-cris/arch-v10/memmap.h b/include/asm-cris/arch-v10/memmap.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v10/memmap.h
@@ -0,0 +1,22 @@
+#ifndef _ASM_ARCH_MEMMAP_H
+#define _ASM_ARCH_MEMMAP_H
+
+#define MEM_CSE0_START (0x00000000)
+#define MEM_CSE0_SIZE (0x04000000)
+#define MEM_CSE1_START (0x04000000)
+#define MEM_CSE1_SIZE (0x04000000)
+#define MEM_CSR0_START (0x08000000)
+#define MEM_CSR1_START (0x0c000000)
+#define MEM_CSP0_START (0x10000000)
+#define MEM_CSP1_START (0x14000000)
+#define MEM_CSP2_START (0x18000000)
+#define MEM_CSP3_START (0x1c000000)
+#define MEM_CSP4_START (0x20000000)
+#define MEM_CSP5_START (0x24000000)
+#define MEM_CSP6_START (0x28000000)
+#define MEM_CSP7_START (0x2c000000)
+#define MEM_DRAM_START (0x40000000)
+
+#define MEM_NON_CACHEABLE (0x80000000)
+
+#endif
diff --git a/include/asm-cris/arch-v10/mmu.h b/include/asm-cris/arch-v10/mmu.h
--- a/include/asm-cris/arch-v10/mmu.h
+++ b/include/asm-cris/arch-v10/mmu.h
@@ -7,7 +7,10 @@
 
 /* type used in struct mm to couple an MMU context to an active mm */
 
-typedef unsigned int mm_context_t;
+typedef struct
+{
+  unsigned int page_id;
+} mm_context_t;
 
 /* kernel memory segments */
 
diff --git a/include/asm-cris/arch-v10/offset.h b/include/asm-cris/arch-v10/offset.h
--- a/include/asm-cris/arch-v10/offset.h
+++ b/include/asm-cris/arch-v10/offset.h
@@ -25,7 +25,7 @@
 #define THREAD_usp 4 /* offsetof(struct thread_struct, usp) */
 #define THREAD_dccr 8 /* offsetof(struct thread_struct, dccr) */
 
-#define TASK_pid 133 /* offsetof(struct task_struct, pid) */
+#define TASK_pid 141 /* offsetof(struct task_struct, pid) */
 
 #define LCLONE_VM 256 /* CLONE_VM */
 #define LCLONE_UNTRACED 8388608 /* CLONE_UNTRACED */
diff --git a/include/asm-cris/arch-v10/processor.h b/include/asm-cris/arch-v10/processor.h
--- a/include/asm-cris/arch-v10/processor.h
+++ b/include/asm-cris/arch-v10/processor.h
@@ -59,4 +59,12 @@ struct thread_struct {
 	wrusp(usp);           \
 } while(0)
 
+/* Called when handling a kernel bus fault fixup.
+ *
+ * After a fixup we do not want to return by restoring the CPU-state
+ * anymore, so switch frame-types (see ptrace.h)
+ */
+#define arch_fixup(regs) \
+   regs->frametype = CRIS_FRAME_NORMAL;
+
 #endif
diff --git a/include/asm-cris/arch-v10/system.h b/include/asm-cris/arch-v10/system.h
--- a/include/asm-cris/arch-v10/system.h
+++ b/include/asm-cris/arch-v10/system.h
@@ -11,6 +11,8 @@ extern inline unsigned long rdvr(void) {
 	return vr;
 }
 
+#define cris_machine_name "cris"
+
 /* read/write the user-mode stackpointer */
 
 extern inline unsigned long rdusp(void) {
diff --git a/include/asm-cris/arch-v32/arbiter.h b/include/asm-cris/arch-v32/arbiter.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/arbiter.h
@@ -0,0 +1,30 @@
+#ifndef _ASM_CRIS_ARCH_ARBITER_H
+#define _ASM_CRIS_ARCH_ARBITER_H
+
+#define EXT_REGION 0
+#define INT_REGION 1
+
+typedef void (watch_callback)(void);
+
+enum
+{
+  arbiter_all_dmas = 0x3ff,
+  arbiter_cpu = 0xc00,
+  arbiter_all_clients = 0x3fff
+};
+
+enum
+{
+  arbiter_all_read = 0x55,
+  arbiter_all_write = 0xaa,
+  arbiter_all_accesses = 0xff
+};
+
+int crisv32_arbiter_allocate_bandwith(int client, int region,
+                                      unsigned long bandwidth);
+int crisv32_arbiter_watch(unsigned long start, unsigned long size,
+                          unsigned long clients, unsigned long accesses,
+                          watch_callback* cb);
+int crisv32_arbiter_unwatch(int id);
+
+#endif
diff --git a/include/asm-cris/arch-v32/atomic.h b/include/asm-cris/arch-v32/atomic.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/atomic.h
@@ -0,0 +1,36 @@
+#ifndef __ASM_CRIS_ARCH_ATOMIC__
+#define __ASM_CRIS_ARCH_ATOMIC__
+
+#include <asm/system.h>
+
+extern void cris_spin_unlock(void *l, int val);
+extern void cris_spin_lock(void *l);
+extern int cris_spin_trylock(void* l);
+
+#ifndef CONFIG_SMP
+#define cris_atomic_save(addr, flags) local_irq_save(flags);
+#define cris_atomic_restore(addr, flags) local_irq_restore(flags);
+#else
+
+extern spinlock_t cris_atomic_locks[];
+#define LOCK_COUNT 128
+#define HASH_ADDR(a) (((int)a) & 127)
+
+#define cris_atomic_save(addr, flags) \
+  local_irq_save(flags); \
+  cris_spin_lock((void*)&cris_atomic_locks[HASH_ADDR(addr)].lock);
+
+#define cris_atomic_restore(addr, flags) \
+  { \
+    spinlock_t *lock = (void*)&cris_atomic_locks[HASH_ADDR(addr)]; \
+    __asm__ volatile ("move.d %1,%0" \
+	                  : "=m" (lock->lock) \
+			  : "r" (1) \
+			  : "memory"); \
+    local_irq_restore(flags); \
+  }
+
+#endif
+
+#endif
+
diff --git a/include/asm-cris/arch-v32/bitops.h b/include/asm-cris/arch-v32/bitops.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/bitops.h
@@ -0,0 +1,64 @@
+#ifndef _ASM_CRIS_ARCH_BITOPS_H
+#define _ASM_CRIS_ARCH_BITOPS_H
+
+/*
+ * Helper functions for the core of the ff[sz] functions. They compute the
+ * number of leading zeroes of a bits-in-byte, byte-in-word and
+ * word-in-dword-swapped number. They differ in that the first function also
+ * inverts all bits in the input.
+ */
+
+extern inline unsigned long
+cris_swapnwbrlz(unsigned long w)
+{
+	unsigned long res;
+
+	__asm__ __volatile__ ("swapnwbr %0\n\t"
+			      "lz %0,%0"
+			      : "=r" (res) : "0" (w));
+
+	return res;
+}
+
+extern inline unsigned long
+cris_swapwbrlz(unsigned long w)
+{
+	unsigned long res;
+
+	__asm__ __volatile__ ("swapwbr %0\n\t"
+			      "lz %0,%0"
+			      : "=r" (res) : "0" (w));
+
+	return res;
+}
+
+/*
+ * Find First Zero in word. Undefined if no zero exist, so the caller should
+ * check against ~0 first.
+ */
+extern inline unsigned long
+ffz(unsigned long w)
+{
+	return cris_swapnwbrlz(w);
+}
+
+/*
+ * Find First Set bit in word. Undefined if no 1 exist, so the caller
+ * should check against 0 first.
+ */
+extern inline unsigned long
+__ffs(unsigned long w)
+{
+	return cris_swapnwbrlz(~w);
+}
+
+/*
+ * Find First Bit that is set.
+ */
+extern inline unsigned long
+kernel_ffs(unsigned long w)
+{
+	return w ? cris_swapwbrlz (w) + 1 : 0;
+}
+
+#endif /* _ASM_CRIS_ARCH_BITOPS_H */
diff --git a/include/asm-cris/arch-v32/byteorder.h b/include/asm-cris/arch-v32/byteorder.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/byteorder.h
@@ -0,0 +1,20 @@
+#ifndef _ASM_CRIS_ARCH_BYTEORDER_H
+#define _ASM_CRIS_ARCH_BYTEORDER_H
+
+#include <asm/types.h>
+
+extern __inline__ __const__ __u32
+___arch__swab32(__u32 x)
+{
+	__asm__ __volatile__ ("swapwb %0" : "=r" (x) : "0" (x));
+	return (x);
+}
+
+extern __inline__ __const__ __u16
+___arch__swab16(__u16 x)
+{
+	__asm__ __volatile__ ("swapb %0" : "=r" (x) : "0" (x));
+	return (x);
+}
+
+#endif /* _ASM_CRIS_ARCH_BYTEORDER_H */
diff --git a/include/asm-cris/arch-v32/cache.h b/include/asm-cris/arch-v32/cache.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/cache.h
@@ -0,0 +1,9 @@
+#ifndef _ASM_CRIS_ARCH_CACHE_H
+#define _ASM_CRIS_ARCH_CACHE_H
+
+/* A cache-line is 32 bytes. */
+#define L1_CACHE_BYTES 32
+#define L1_CACHE_SHIFT 5
+#define L1_CACHE_SHIFT_MAX 5
+
+#endif /* _ASM_CRIS_ARCH_CACHE_H */
diff --git a/include/asm-cris/arch-v32/checksum.h b/include/asm-cris/arch-v32/checksum.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/checksum.h
@@ -0,0 +1,29 @@
+#ifndef _ASM_CRIS_ARCH_CHECKSUM_H
+#define _ASM_CRIS_ARCH_CHECKSUM_H
+
+/*
+ * Check values used in TCP/UDP headers.
+ *
+ * The gain of doing this in assembler instead of C, is that C doesn't
+ * generate carry-additions for the 32-bit components of the
+ * checksum. Which means it would be necessary to split all those into
+ * 16-bit components and then add.
+ */
+extern inline unsigned int
+csum_tcpudp_nofold(unsigned long saddr, unsigned long daddr,
+		   unsigned short len, unsigned short proto, unsigned int sum)
+{
+	int res;
+
+	__asm__ __volatile__ ("add.d %2, %0\n\t"
+			      "addc %3, %0\n\t"
+			      "addc %4, %0\n\t"
+			      "addc 0, %0\n\t"
+			      : "=r" (res)
+			      : "0" (sum), "r" (daddr), "r" (saddr), \
+			      "r" ((ntohs(len) << 16) + (proto << 8)));
+
+	return res;
+}
+
+#endif /* _ASM_CRIS_ARCH_CHECKSUM_H */
diff --git a/include/asm-cris/arch-v32/cryptocop.h b/include/asm-cris/arch-v32/cryptocop.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/cryptocop.h
@@ -0,0 +1,272 @@
+/*
+ * The device /dev/cryptocop is accessible using this driver using
+ * CRYPTOCOP_MAJOR (254) and minor number 0.
+ */
+
+#ifndef CRYPTOCOP_H
+#define CRYPTOCOP_H
+
+#include <linux/uio.h>
+
+
+#define CRYPTOCOP_SESSION_ID_NONE (0)
+
+typedef unsigned long long int cryptocop_session_id;
+
+/* cryptocop ioctls */
+#define ETRAXCRYPTOCOP_IOCTYPE         (250)
+
+#define CRYPTOCOP_IO_CREATE_SESSION    _IOWR(ETRAXCRYPTOCOP_IOCTYPE, 1, struct strcop_session_op)
+#define CRYPTOCOP_IO_CLOSE_SESSION     _IOW(ETRAXCRYPTOCOP_IOCTYPE, 2, struct strcop_session_op)
+#define CRYPTOCOP_IO_PROCESS_OP        _IOWR(ETRAXCRYPTOCOP_IOCTYPE, 3, struct strcop_crypto_op)
+#define CRYPTOCOP_IO_MAXNR             (3)
+
+typedef enum {
+	cryptocop_cipher_des = 0,
+	cryptocop_cipher_3des = 1,
+	cryptocop_cipher_aes = 2,
+	cryptocop_cipher_m2m = 3, /* mem2mem is essentially a NULL cipher with blocklength=1 */
+	cryptocop_cipher_none
+} cryptocop_cipher_type;
+
+typedef enum {
+	cryptocop_digest_sha1 = 0,
+	cryptocop_digest_md5 = 1,
+	cryptocop_digest_none
+} cryptocop_digest_type;
+
+typedef enum {
+	cryptocop_csum_le = 0,
+	cryptocop_csum_be = 1,
+	cryptocop_csum_none
+} cryptocop_csum_type;
+
+typedef enum {
+	cryptocop_cipher_mode_ecb = 0,
+	cryptocop_cipher_mode_cbc,
+	cryptocop_cipher_mode_none
+} cryptocop_cipher_mode;
+
+typedef enum {
+	cryptocop_3des_eee = 0,
+	cryptocop_3des_eed = 1,
+	cryptocop_3des_ede = 2,
+	cryptocop_3des_edd = 3,
+	cryptocop_3des_dee = 4,
+	cryptocop_3des_ded = 5,
+	cryptocop_3des_dde = 6,
+	cryptocop_3des_ddd = 7
+} cryptocop_3des_mode;
+
+/* Usermode accessible (ioctl) operations. */
+struct strcop_session_op{
+	cryptocop_session_id    ses_id;
+
+	cryptocop_cipher_type   cipher; /* AES, DES, 3DES, m2m, none */
+
+	cryptocop_cipher_mode   cmode; /* ECB, CBC, none */
+	cryptocop_3des_mode     des3_mode;
+
+	cryptocop_digest_type   digest; /* MD5, SHA1, none */
+
+	cryptocop_csum_type     csum;   /* BE, LE, none */
+
+	unsigned char           *key;
+	size_t                  keylen;
+};
+
+#define CRYPTOCOP_CSUM_LENGTH         (2)
+#define CRYPTOCOP_MAX_DIGEST_LENGTH   (20)  /* SHA-1 20, MD5 16 */
+#define CRYPTOCOP_MAX_IV_LENGTH       (16)  /* (3)DES==8, AES == 16 */
+#define CRYPTOCOP_MAX_KEY_LENGTH      (32)
+
+struct strcop_crypto_op{
+	cryptocop_session_id ses_id;
+
+	/* Indata. */
+	unsigned char            *indata;
+	size_t                   inlen; /* Total indata length. */
+
+	/* Cipher configuration. */
+	unsigned char            do_cipher:1;
+	unsigned char            decrypt:1; /* 1 == decrypt, 0 == encrypt */
+	unsigned char            cipher_explicit:1;
+	size_t                   cipher_start;
+	size_t                   cipher_len;
+	/* cipher_iv is used if do_cipher and cipher_explicit and the cipher
+	   mode is CBC.  The length is controlled by the type of cipher,
+	   e.g. DES/3DES 8 octets and AES 16 octets. */
+	unsigned char            cipher_iv[CRYPTOCOP_MAX_IV_LENGTH];
+	/* Outdata. */
+	unsigned char            *cipher_outdata;
+	size_t                   cipher_outlen;
+
+	/* digest configuration. */
+	unsigned char            do_digest:1;
+	size_t                   digest_start;
+	size_t                   digest_len;
+	/* Outdata.  The actual length is determined by the type of the digest. */
+	unsigned char            digest[CRYPTOCOP_MAX_DIGEST_LENGTH];
+
+	/* Checksum configuration. */
+	unsigned char            do_csum:1;
+	size_t                   csum_start;
+	size_t                   csum_len;
+	/* Outdata. */
+	unsigned char            csum[CRYPTOCOP_CSUM_LENGTH];
+};
+
+
+
+#ifdef __KERNEL__
+
+/********** The API to use from inside the kernel. ************/
+
+#include <asm/arch/hwregs/dma.h>
+
+typedef enum {
+	cryptocop_alg_csum = 0,
+	cryptocop_alg_mem2mem,
+	cryptocop_alg_md5,
+	cryptocop_alg_sha1,
+	cryptocop_alg_des,
+	cryptocop_alg_3des,
+	cryptocop_alg_aes,
+	cryptocop_no_alg,
+} cryptocop_algorithm;
+
+typedef u8 cryptocop_tfrm_id;
+
+
+struct cryptocop_operation;
+
+typedef void (cryptocop_callback)(struct cryptocop_operation*, void*);
+
+struct cryptocop_transform_init {
+	cryptocop_algorithm    alg;
+	/* Keydata for ciphers. */
+	unsigned char          key[CRYPTOCOP_MAX_KEY_LENGTH];
+	unsigned int           keylen;
+	cryptocop_cipher_mode  cipher_mode;
+	cryptocop_3des_mode    tdes_mode;
+	cryptocop_csum_type    csum_mode; /* cryptocop_csum_none is not allowed when alg==cryptocop_alg_csum */
+
+	cryptocop_tfrm_id tid; /* Locally unique in session; assigned by user, checked by driver. */
+	struct cryptocop_transform_init *next;
+};
+
+
+typedef enum {
+	cryptocop_source_dma = 0,
+	cryptocop_source_des,
+	cryptocop_source_3des,
+	cryptocop_source_aes,
+	cryptocop_source_md5,
+	cryptocop_source_sha1,
+	cryptocop_source_csum,
+	cryptocop_source_none,
+} cryptocop_source;
+
+
+struct cryptocop_desc_cfg {
+	cryptocop_tfrm_id tid;
+	cryptocop_source src;
+	unsigned int last:1; /* Last use of this transform in the operation.  Will push outdata when encountered. */
+	struct cryptocop_desc_cfg *next;
+};
+
+struct cryptocop_desc {
+	size_t length;
+	struct cryptocop_desc_cfg *cfg;
+	struct cryptocop_desc *next;
+};
+
+
+/* Flags for cryptocop_tfrm_cfg */
+#define CRYPTOCOP_NO_FLAG     (0x00)
+#define CRYPTOCOP_ENCRYPT     (0x01)
+#define CRYPTOCOP_DECRYPT     (0x02)
+#define CRYPTOCOP_EXPLICIT_IV (0x04)
+
+struct cryptocop_tfrm_cfg {
+	cryptocop_tfrm_id tid;
+
+	unsigned int flags; /* DECRYPT, ENCRYPT, EXPLICIT_IV */
+
+	/* CBC initialisation vector for cihers. */
+	u8 iv[CRYPTOCOP_MAX_IV_LENGTH];
+
+	/* The position in output where to write the transform output.  The order
+	   in which the driver writes the output is unspecified, hence if several
+	   transforms write on the same positions in the output the result is
+	   unspecified. */
+	size_t inject_ix;
+
+	struct cryptocop_tfrm_cfg *next;
+};
+
+
+
+struct cryptocop_dma_list_operation{
+	/* The consumer can provide DMA lists to send to the co-processor.  'use_dmalists' in
+	   struct cryptocop_operation must be set for the driver to use them.  outlist,
+	   out_data_buf, inlist and in_data_buf must all be physical addresses since they will
+	   be loaded to DMA . */
+	dma_descr_data *outlist; /* Out from memory to the co-processor. */
+	char           *out_data_buf;
+	dma_descr_data *inlist; /* In from the co-processor to memory. */
+	char           *in_data_buf;
+
+	cryptocop_3des_mode tdes_mode;
+	cryptocop_csum_type csum_mode;
+};
+
+
+struct cryptocop_tfrm_operation{
+	/* Operation configuration, if not 'use_dmalists' is set. */
+	struct cryptocop_tfrm_cfg *tfrm_cfg;
+	struct cryptocop_desc *desc;
+
+	struct iovec *indata;
+	size_t incount;
+	size_t inlen; /* Total inlength. */
+
+	struct iovec *outdata;
+	size_t outcount;
+	size_t outlen; /* Total outlength. */
+};
+
+
+struct cryptocop_operation {
+	cryptocop_callback *cb;
+	void *cb_data;
+
+	cryptocop_session_id sid;
+
+	/* The status of the operation when returned to consumer. */
+	int operation_status; /* 0, -EAGAIN */
+
+	/* Flags */
+	unsigned int use_dmalists:1;  /* Use outlist and inlist instead of the desc/tfrm_cfg configuration. */
+	unsigned int in_interrupt:1;  /* Set if inserting job from interrupt context. */
+	unsigned int fast_callback:1; /* Set if fast callback wanted, i.e. from interrupt context. */
+
+	union{
+		struct cryptocop_dma_list_operation list_op;
+		struct cryptocop_tfrm_operation tfrm_op;
+	};
+};
+
+
+int cryptocop_new_session(cryptocop_session_id *sid, struct cryptocop_transform_init *tinit, int alloc_flag);
+int cryptocop_free_session(cryptocop_session_id sid);
+
+int cryptocop_job_queue_insert_csum(struct cryptocop_operation *operation);
+
+int cryptocop_job_queue_insert_crypto(struct cryptocop_operation *operation);
+
+int cryptocop_job_queue_insert_user_job(struct cryptocop_operation *operation);
+
+#endif /* __KERNEL__ */
+
+#endif /* CRYPTOCOP_H */
diff --git a/include/asm-cris/arch-v32/delay.h b/include/asm-cris/arch-v32/delay.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/delay.h
@@ -0,0 +1,18 @@
+#ifndef _ASM_CRIS_ARCH_DELAY_H
+#define _ASM_CRIS_ARCH_DELAY_H
+
+extern __inline__ void
+__delay(int loops)
+{
+	__asm__ __volatile__ (
+		"move.d %0, $r9\n\t"
+		"beq 2f\n\t"
+		"subq 1, $r9\n\t"
+		"1:\n\t"
+		"bne 1b\n\t"
+		"subq 1, $r9\n"
+		"2:"
+		: : "g" (loops) : "r9");
+}
+
+#endif /* _ASM_CRIS_ARCH_DELAY_H */
diff --git a/include/asm-cris/arch-v32/dma.h b/include/asm-cris/arch-v32/dma.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/dma.h
@@ -0,0 +1,79 @@
+#ifndef _ASM_ARCH_CRIS_DMA_H
+#define _ASM_ARCH_CRIS_DMA_H
+
+/* Defines for using and allocating dma channels. */
+
+#define MAX_DMA_CHANNELS	10
+
+#define NETWORK_ETH0_TX_DMA_NBR 0	/* Ethernet 0 out. */
+#define NETWORK_ETH0 RX_DMA_NBR 1	/* Ethernet 0 in. */
+
+#define IO_PROC_DMA0_TX_DMA_NBR 2	/* IO processor DMA0 out. */
+#define IO_PROC_DMA0_RX_DMA_NBR 3	/* IO processor DMA0 in. */
+
+#define ATA_TX_DMA_NBR 2		/* ATA interface out. */
+#define ATA_RX_DMA_NBR 3		/* ATA interface in. */
+
+#define ASYNC_SER2_TX_DMA_NBR 2		/* Asynchronous serial port 2 out. */
+#define ASYNC_SER2_RX_DMA_NBR 3		/* Asynchronous serial port 2 in. */
+
+#define IO_PROC_DMA1_TX_DMA_NBR 4	/* IO processor DMA1 out. */
+#define IO_PROC_DMA1_RX_DMA_NBR 5	/* IO processor DMA1 in. */
+
+#define ASYNC_SER1_TX_DMA_NBR 4		/* Asynchronous serial port 1 out. */
+#define ASYNC_SER1_RX_DMA_NBR 5		/* Asynchronous serial port 1 in. */
+
+#define SYNC_SER0_TX_DMA_NBR 4		/* Synchronous serial port 0 out. */
+#define SYNC_SER0_RX_DMA_NBR 5		/* Synchronous serial port 0 in. */
+
+#define EXTDMA0_TX_DMA_NBR 6		/* External DMA 0 out. */
+#define EXTDMA1_RX_DMA_NBR 7		/* External DMA 1 in. */
+
+#define ASYNC_SER0_TX_DMA_NBR 6		/* Asynchronous serial port 0 out. */
+#define ASYNC_SER0_RX_DMA_NBR 7		/* Asynchronous serial port 0 in. */
+
+#define SYNC_SER1_TX_DMA_NBR 6		/* Synchronous serial port 1 out. */
+#define SYNC_SER1_RX_DMA_NBR 7		/* Synchronous serial port 1 in. */
+
+#define NETWORK_ETH1_TX_DMA_NBR 6	/* Ethernet 1 out. */
+#define NETWORK_ETH1_RX_DMA_NBR 7	/* Ethernet 1 in. */
+
+#define EXTDMA2_TX_DMA_NBR 8		/* External DMA 2 out. */
+#define EXTDMA3_RX_DMA_NBR 9		/* External DMA 3 in. */
+
+#define STRCOP_TX_DMA_NBR 8		/* Stream co-processor out. */
+#define STRCOP_RX_DMA_NBR 9		/* Stream co-processor in. */
+
+#define ASYNC_SER3_TX_DMA_NBR 8		/* Asynchronous serial port 3 out. */
+#define ASYNC_SER3_RX_DMA_NBR 9		/* Asynchronous serial port 3 in. */
+
+enum dma_owner
+{
+  dma_eth0,
+  dma_eth1,
+  dma_iop0,
+  dma_iop1,
+  dma_ser0,
+  dma_ser1,
+  dma_ser2,
+  dma_ser3,
+  dma_sser0,
+  dma_sser1,
+  dma_ata,
+  dma_strp,
+  dma_ext0,
+  dma_ext1,
+  dma_ext2,
+  dma_ext3
+};
+
+int crisv32_request_dma(unsigned int dmanr, const char * device_id,
+                        unsigned options, unsigned bandwidth, enum dma_owner owner);
+void crisv32_free_dma(unsigned int dmanr);
+
+/* Masks used by crisv32_request_dma options: */
+#define DMA_VERBOSE_ON_ERROR 1
+#define DMA_PANIC_ON_ERROR (2|DMA_VERBOSE_ON_ERROR)
+#define DMA_INT_MEM 4
+
+#endif /* _ASM_ARCH_CRIS_DMA_H */
diff --git a/include/asm-cris/arch-v32/elf.h b/include/asm-cris/arch-v32/elf.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/elf.h
@@ -0,0 +1,73 @@
+#ifndef _ASM_CRIS_ELF_H
+#define _ASM_CRIS_ELF_H
+
+#define ELF_CORE_EFLAGS EF_CRIS_VARIANT_V32
+
+/*
+ * This is used to ensure we don't load something for the wrong architecture.
+ */
+#define elf_check_arch(x)			\
+ ((x)->e_machine == EM_CRIS			\
+  && ((((x)->e_flags & EF_CRIS_VARIANT_MASK) == EF_CRIS_VARIANT_V32	\
+      || (((x)->e_flags & EF_CRIS_VARIANT_MASK) == EF_CRIS_VARIANT_COMMON_V10_V32))))
+
+/* CRISv32 ELF register definitions. */
+
+#include <asm/ptrace.h>
+
+/* Explicitly zero out registers to increase determinism. */
+#define ELF_PLAT_INIT(_r, load_addr)    do { \
+        (_r)->r13 = 0; (_r)->r12 = 0; (_r)->r11 = 0; (_r)->r10 = 0; \
+        (_r)->r9 = 0;  (_r)->r8 = 0;  (_r)->r7 = 0;  (_r)->r6 = 0;  \
+        (_r)->r5 = 0;  (_r)->r4 = 0;  (_r)->r3 = 0;  (_r)->r2 = 0;  \
+        (_r)->r1 = 0;  (_r)->r0 = 0;  (_r)->mof = 0; (_r)->srp = 0; \
+        (_r)->acr = 0; \
+} while (0)
+
+/*
+ * An executable for which elf_read_implies_exec() returns TRUE will
+ * have the READ_IMPLIES_EXEC personality flag set automatically.
+ */
+#define elf_read_implies_exec_binary(ex, have_pt_gnu_stack)	(!(have_pt_gnu_stack))
+
+/*
+ * This is basically a pt_regs with the additional definition
+ * of the stack pointer since it's needed in a core dump.
+ * pr_regs is a elf_gregset_t and should be filled according
+ * to the layout of user_regs_struct.
+ */
+#define ELF_CORE_COPY_REGS(pr_reg, regs)                   \
+        pr_reg[0] = regs->r0;                              \
+        pr_reg[1] = regs->r1;                              \
+        pr_reg[2] = regs->r2;                              \
+        pr_reg[3] = regs->r3;                              \
+        pr_reg[4] = regs->r4;                              \
+        pr_reg[5] = regs->r5;                              \
+        pr_reg[6] = regs->r6;                              \
+        pr_reg[7] = regs->r7;                              \
+        pr_reg[8] = regs->r8;                              \
+        pr_reg[9] = regs->r9;                              \
+        pr_reg[10] = regs->r10;                            \
+        pr_reg[11] = regs->r11;                            \
+        pr_reg[12] = regs->r12;                            \
+        pr_reg[13] = regs->r13;                            \
+        pr_reg[14] = rdusp();               /* SP */       \
+        pr_reg[15] = regs->acr;             /* ACR */      \
+        pr_reg[16] = 0;                     /* BZ */       \
+        pr_reg[17] = rdvr();                /* VR */       \
+        pr_reg[18] = 0;                     /* PID */      \
+        pr_reg[19] = regs->srs;             /* SRS */      \
+        pr_reg[20] = 0;                     /* WZ */       \
+        pr_reg[21] = regs->exs;             /* EXS */      \
+        pr_reg[22] = regs->eda;             /* EDA */      \
+        pr_reg[23] = regs->mof;             /* MOF */      \
+        pr_reg[24] = 0;                     /* DZ */       \
+        pr_reg[25] = 0;                     /* EBP */      \
+        pr_reg[26] = regs->erp;             /* ERP */      \
+        pr_reg[27] = regs->srp;             /* SRP */      \
+        pr_reg[28] = 0;                     /* NRP */      \
+        pr_reg[29] = regs->ccs;             /* CCS */      \
+        pr_reg[30] = rdusp();               /* USP */      \
+        pr_reg[31] = regs->spc;             /* SPC */      \
+
+#endif /* _ASM_CRIS_ELF_H */
diff --git a/include/asm-cris/arch-v32/hwregs/Makefile b/include/asm-cris/arch-v32/hwregs/Makefile
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/Makefile
@@ -0,0 +1,187 @@
+# $Id: Makefile,v 1.8 2004/01/07 21:16:18 johana Exp $
+# Makefile to generate or copy the latest register definitions
+# and related datastructures and helpermacros.
+# The offical place for these files is at:
+RELEASE ?= r1_alfa5
+OFFICIAL_INCDIR = /n/asic/projects/guinness/releases/$(RELEASE)/design/top/sw/include/
+
+# which is updated on each new release.
+INCL_ASMFILES   =
+INCL_FILES      = ata_defs.h
+INCL_FILES     += bif_core_defs.h
+INCL_ASMFILES  += bif_core_defs_asm.h
+INCL_FILES     += bif_slave_defs.h
+#INCL_FILES     += bif_slave_ext_defs.h
+INCL_FILES     += config_defs.h
+INCL_ASMFILES  += config_defs_asm.h
+INCL_FILES     += cpu_vect.h
+#INCL_FILES     += cris_defs.h
+#INCL_FILES     += cris_supp_reg.h # In handcrafted supp_reg.h
+INCL_FILES     += dma.h
+INCL_FILES     += dma_defs.h
+INCL_FILES     += eth_defs.h
+INCL_FILES     += extmem_defs.h
+INCL_FILES     += gio_defs.h
+INCL_ASMFILES  += gio_defs_asm.h
+INCL_FILES     += intr_vect.h
+INCL_FILES     += intr_vect_defs.h
+INCL_ASMFILES  += intr_vect_defs_asm.h
+INCL_FILES     += marb_bp_defs.h
+INCL_FILES     += marb_defs.h
+INCL_ASMFILES  += mmu_defs_asm.h
+#INCL_FILES     += mmu_supp_reg.h # In handcrafted supp_reg.h
+#INCL_FILES     += par_defs.h # No useful content
+INCL_FILES     += pinmux_defs.h
+INCL_FILES     += reg_map.h
+INCL_ASMFILES  += reg_map_asm.h
+INCL_FILES     += reg_rdwr.h
+INCL_FILES     += ser_defs.h
+#INCL_FILES     += spec_reg.h # In handcrafted supp_reg.h
+INCL_FILES     += sser_defs.h
+INCL_FILES     += strcop_defs.h
+#INCL_FILES     += strcop.h # Where is this?
+INCL_FILES     += strmux_defs.h
+#INCL_FILES     += supp_reg.h # Handcrafted instead
+INCL_FILES     += timer_defs.h
+
+REGDESC =
+REGDESC += $(BASEDIR)/io/ata/rtl/ata_regs.r
+REGDESC += $(BASEDIR)/io/bif/rtl/bif_core_regs.r
+REGDESC += $(BASEDIR)/io/bif/rtl/bif_slave_regs.r
+#REGDESC += $(BASEDIR)/io/bif/sw/bif_slave_ext_regs.r
+REGDESC += $(DESIGNDIR)/top/rtl/config_regs.r
+REGDESC += $(BASEDIR)/mod/dma_common/rtl/dma_regdes.r
+REGDESC += $(BASEDIR)/io/eth/rtl/eth_regs.r
+REGDESC += $(BASEDIR)/io/bif/mod/extmem/extmem_regs.r
+REGDESC += $(DESIGNDIR)/gio/rtl/gio_regs.r
+REGDESC += $(BASEDIR)/core/cpu/intr_vect/rtl/guinness/ivmask.config.r
+REGDESC += $(BASEDIR)/core/memarb/rtl/guinness/marb_top.r
+REGDESC += $(BASEDIR)/core/cpu/mmu/doc/mmu_regs.r
+#REGDESC += $(BASEDIR)/io/par_port/rtl/par_regs.r
+REGDESC += $(BASEDIR)/io/pinmux/rtl/guinness/pinmux_regs.r
+REGDESC += $(BASEDIR)/io/ser/rtl/ser_regs.r
+REGDESC += $(BASEDIR)/core/strcop/rtl/strcop_regs.r
+REGDESC += $(BASEDIR)/io/strmux/rtl/guinness/strmux_regs.r
+REGDESC += $(BASEDIR)/io/timer/rtl/timer_regs.r
+#REGDESC += $(BASEDIR)/io/usb/usb1_1/rtl/usb_regs.r
+
+
+BASEDIR = /n/asic/design
+DESIGNDIR = /n/asic/projects/guinness/design
+RDES2C = /n/asic/bin/rdes2c
+RDES2C = /n/asic/design/tools/rdesc/rdes2c
+RDES2INTR = /n/asic/design/tools/rdesc/rdes2intr
+RDES2TXT = /n/asic/design/tools/rdesc/rdes2txt
+
+## all    - Just print help - you probably want to do 'make gen'
+all: help
+
+# Disable implicit rule that may generate deleted files from RCS/ directory.
+%.r:
+
+%.h:
+
+## help   - This help
+help:
+	@grep '^## ' Makefile
+
+## gen    - Generate include files
+gen: $(INCL_FILES) $(INCL_ASMFILES)
+
+ata_defs.h: $(BASEDIR)/io/ata/rtl/ata_regs.r
+	$(RDES2C) $<
+config_defs.h: $(DESIGNDIR)/top/rtl/config_regs.r
+	$(RDES2C) $<
+config_defs_asm.h: $(DESIGNDIR)/top/rtl/config_regs.r
+	$(RDES2C) -asm $<
+# Can't generate cpu_vect.h yet
+#cpu_vect.h: $(DESIGNDIR)/top/rtl/cpu_vect.r # ????
+#	$(RDES2INTR) $<
+cpu_vect.h: $(OFFICIAL_INCDIR)cpu_vect.h
+	cat $< | sed -e 's/\$$Id\:/id\:/g' >$@
+dma_defs.h: $(BASEDIR)/core/dma/rtl/common/dma_regdes.r
+	$(RDES2C) $<
+$(BASEDIR)/core/dma/sw/dma.h:
+dma.h: $(BASEDIR)/core/dma/sw/dma.h
+	cat $< | sed -e 's/\$$Id\:/id\:/g' >$@
+eth_defs.h: $(BASEDIR)/io/eth/rtl/eth_regs.r
+	$(RDES2C) $<
+extmem_defs.h: $(BASEDIR)/io/bif/mod/extmem/extmem_regs.r
+	$(RDES2C) $<
+gio_defs.h: $(DESIGNDIR)/gio/rtl/gio_regs.r
+	$(RDES2C) $<
+intr_vect_defs.h: $(BASEDIR)/core/cpu/intr_vect/rtl/guinness/ivmask.config.r
+	$(RDES2C) $<
+intr_vect_defs_asm.h: $(BASEDIR)/core/cpu/intr_vect/rtl/guinness/ivmask.config.r
+	$(RDES2C) -asm $<
+# Can't generate intr_vect.h yet
+#intr_vect.h: $(BASEDIR)/core/cpu/intr_vect/rtl/guinness/ivmask.config.r
+#	$(RDES2INTR) $<
+intr_vect.h: $(OFFICIAL_INCDIR)intr_vect.h
+	cat $< | sed -e 's/\$$Id\:/id\:/g' >$@
+mmu_defs_asm.h: $(BASEDIR)/core/cpu/mmu/doc/mmu_regs.r
+	$(RDES2C) -asm $<
+par_defs.h: $(BASEDIR)/io/par_port/rtl/par_regs.r
+	$(RDES2C) $<
+
+# From /n/asic/projects/guinness/design/
+reg_map.h: $(DESIGNDIR)/top/rtl/global.rmap $(DESIGNDIR)/top/mod/modreg.rmap
+	$(RDES2C) -base 0xb0000000 $^
+reg_map_asm.h: $(DESIGNDIR)/top/rtl/global.rmap $(DESIGNDIR)/top/mod/modreg.rmap
+	$(RDES2C) -base 0xb0000000 -asm -outfile $@ $^
+
+reg_rdwr.h: $(DESIGNDIR)/top/sw/include/reg_rdwr.h
+	cat $< | sed -e 's/\$$Id\:/id\:/g' >$@
+
+ser_defs.h: $(BASEDIR)/io/ser/rtl/ser_regs.r
+	$(RDES2C) $<
+strcop_defs.h: $(BASEDIR)/core/strcop/rtl/strcop_regs.r
+	$(RDES2C) $<
+strcop.h: $(BASEDIR)/core/strcop/rtl/strcop.h
+	cat $< | sed -e 's/\$$Id\:/id\:/g' >$@
+strmux_defs.h: $(BASEDIR)/io/strmux/rtl/guinness/strmux_regs.r
+	$(RDES2C) $<
+timer_defs.h: $(BASEDIR)/io/timer/rtl/timer_regs.r
+	$(RDES2C) $<
+usb_defs.h: $(BASEDIR)/io/usb/usb1_1/rtl/usb_regs.r
+	$(RDES2C) $<
+
+## copy   - Copy files from official location
+copy:
+	@for HFILE in $(INCL_FILES); do \
+		echo "  $$HFILE"; \
+		cat $(OFFICIAL_INCDIR)$$HFILE | sed -e 's/\$$Id\:/id\:/g' > $$HFILE; \
+	done
+	@for HFILE in $(INCL_ASMFILES); do \
+		echo "  $$HFILE"; \
+		cat $(OFFICIAL_INCDIR)asm/$$HFILE | sed -e 's/\$$Id\:/id\:/g' > $$HFILE; \
+	done
+## ls_official - List official location
+ls_official:
+	(cd $(OFFICIAL_INCDIR); ls -l *.h )
+
+## diff_official - Diff current directory with official location
+diff_official:
+	diff . $(OFFICIAL_INCDIR)
+
+## doc    - Generate .axw files from register description.
+doc: $(REGDESC)
+	for RDES in $^; do \
+		$(RDES2TXT) $$RDES; \
+	done
+
+.PHONY: axw
+## %.axw  - Generate the specified .axw file (doesn't work for all files
+##          due to inconsistent naming ir .r files.
+%.axw: axw
+	@for RDES in $(REGDESC); do \
+		if echo "$$RDES" | grep $* ; then \
+		  $(RDES2TXT) $$RDES; \
+		fi \
+	done
+
+.PHONY: clean
+## clean  - Remove .h files and .axw files.
+clean:
+	rm -rf $(INCL_FILES) *.axw
+
diff --git a/include/asm-cris/arch-v32/hwregs/asm/ata_defs_asm.h b/include/asm-cris/arch-v32/hwregs/asm/ata_defs_asm.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/asm/ata_defs_asm.h
@@ -0,0 +1,222 @@
+#ifndef __ata_defs_asm_h
+#define __ata_defs_asm_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/ata/rtl/ata_regs.r
+ *     id:           ata_regs.r,v 1.11 2005/02/09 08:27:36 kriskn Exp
+ *     last modfied: Mon Apr 11 16:06:25 2005
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c -asm --outfile asm/ata_defs_asm.h ../../inst/ata/rtl/ata_regs.r
+ *      id: $Id: ata_defs_asm.h,v 1.1 2005/04/24 18:31:04 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+
+#ifndef REG_FIELD
+#define REG_FIELD( scope, reg, field, value ) \
+  REG_FIELD_X_( value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_FIELD_X_( value, shift ) ((value) << shift)
+#endif
+
+#ifndef REG_STATE
+#define REG_STATE( scope, reg, field, symbolic_value ) \
+  REG_STATE_X_( regk_##scope##_##symbolic_value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_STATE_X_( k, shift ) (k << shift)
+#endif
+
+#ifndef REG_MASK
+#define REG_MASK( scope, reg, field ) \
+  REG_MASK_X_( reg_##scope##_##reg##___##field##___width, reg_##scope##_##reg##___##field##___lsb )
+#define REG_MASK_X_( width, lsb ) (((1 << width)-1) << lsb)
+#endif
+
+#ifndef REG_LSB
+#define REG_LSB( scope, reg, field ) reg_##scope##_##reg##___##field##___lsb
+#endif
+
+#ifndef REG_BIT
+#define REG_BIT( scope, reg, field ) reg_##scope##_##reg##___##field##___bit
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) REG_ADDR_X_(inst, reg_##scope##_##reg##_offset)
+#define REG_ADDR_X_( inst, offs ) ((inst) + offs)
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+         REG_ADDR_VECT_X_(inst, reg_##scope##_##reg##_offset, index, \
+			 STRIDE_##scope##_##reg )
+#define REG_ADDR_VECT_X_( inst, offs, index, stride ) \
+                          ((inst) + offs + (index) * stride)
+#endif
+
+/* Register rw_ctrl0, scope ata, type rw */
+#define reg_ata_rw_ctrl0___pio_hold___lsb 0
+#define reg_ata_rw_ctrl0___pio_hold___width 6
+#define reg_ata_rw_ctrl0___pio_strb___lsb 6
+#define reg_ata_rw_ctrl0___pio_strb___width 6
+#define reg_ata_rw_ctrl0___pio_setup___lsb 12
+#define reg_ata_rw_ctrl0___pio_setup___width 6
+#define reg_ata_rw_ctrl0___dma_hold___lsb 18
+#define reg_ata_rw_ctrl0___dma_hold___width 6
+#define reg_ata_rw_ctrl0___dma_strb___lsb 24
+#define reg_ata_rw_ctrl0___dma_strb___width 6
+#define reg_ata_rw_ctrl0___rst___lsb 30
+#define reg_ata_rw_ctrl0___rst___width 1
+#define reg_ata_rw_ctrl0___rst___bit 30
+#define reg_ata_rw_ctrl0___en___lsb 31
+#define reg_ata_rw_ctrl0___en___width 1
+#define reg_ata_rw_ctrl0___en___bit 31
+#define reg_ata_rw_ctrl0_offset 12
+
+/* Register rw_ctrl1, scope ata, type rw */
+#define reg_ata_rw_ctrl1___udma_tcyc___lsb 0
+#define reg_ata_rw_ctrl1___udma_tcyc___width 4
+#define reg_ata_rw_ctrl1___udma_tdvs___lsb 4
+#define reg_ata_rw_ctrl1___udma_tdvs___width 4
+#define reg_ata_rw_ctrl1_offset 16
+
+/* Register rw_ctrl2, scope ata, type rw */
+#define reg_ata_rw_ctrl2___data___lsb 0
+#define reg_ata_rw_ctrl2___data___width 16
+#define reg_ata_rw_ctrl2___dma_size___lsb 19
+#define reg_ata_rw_ctrl2___dma_size___width 1
+#define reg_ata_rw_ctrl2___dma_size___bit 19
+#define reg_ata_rw_ctrl2___multi___lsb 20
+#define reg_ata_rw_ctrl2___multi___width 1
+#define reg_ata_rw_ctrl2___multi___bit 20
+#define reg_ata_rw_ctrl2___hsh___lsb 21
+#define reg_ata_rw_ctrl2___hsh___width 2
+#define reg_ata_rw_ctrl2___trf_mode___lsb 23
+#define reg_ata_rw_ctrl2___trf_mode___width 1
+#define reg_ata_rw_ctrl2___trf_mode___bit 23
+#define reg_ata_rw_ctrl2___rw___lsb 24
+#define reg_ata_rw_ctrl2___rw___width 1
+#define reg_ata_rw_ctrl2___rw___bit 24
+#define reg_ata_rw_ctrl2___addr___lsb 25
+#define reg_ata_rw_ctrl2___addr___width 3
+#define reg_ata_rw_ctrl2___cs0___lsb 28
+#define reg_ata_rw_ctrl2___cs0___width 1
+#define reg_ata_rw_ctrl2___cs0___bit 28
+#define reg_ata_rw_ctrl2___cs1___lsb 29
+#define reg_ata_rw_ctrl2___cs1___width 1
+#define reg_ata_rw_ctrl2___cs1___bit 29
+#define reg_ata_rw_ctrl2___sel___lsb 30
+#define reg_ata_rw_ctrl2___sel___width 2
+#define reg_ata_rw_ctrl2_offset 0
+
+/* Register rs_stat_data, scope ata, type rs */
+#define reg_ata_rs_stat_data___data___lsb 0
+#define reg_ata_rs_stat_data___data___width 16
+#define reg_ata_rs_stat_data___dav___lsb 16
+#define reg_ata_rs_stat_data___dav___width 1
+#define reg_ata_rs_stat_data___dav___bit 16
+#define reg_ata_rs_stat_data___busy___lsb 17
+#define reg_ata_rs_stat_data___busy___width 1
+#define reg_ata_rs_stat_data___busy___bit 17
+#define reg_ata_rs_stat_data_offset 4
+
+/* Register r_stat_data, scope ata, type r */
+#define reg_ata_r_stat_data___data___lsb 0
+#define reg_ata_r_stat_data___data___width 16
+#define reg_ata_r_stat_data___dav___lsb 16
+#define reg_ata_r_stat_data___dav___width 1
+#define reg_ata_r_stat_data___dav___bit 16
+#define reg_ata_r_stat_data___busy___lsb 17
+#define reg_ata_r_stat_data___busy___width 1
+#define reg_ata_r_stat_data___busy___bit 17
+#define reg_ata_r_stat_data_offset 8
+
+/* Register rw_trf_cnt, scope ata, type rw */
+#define reg_ata_rw_trf_cnt___cnt___lsb 0
+#define reg_ata_rw_trf_cnt___cnt___width 17
+#define reg_ata_rw_trf_cnt_offset 20
+
+/* Register r_stat_misc, scope ata, type r */
+#define reg_ata_r_stat_misc___crc___lsb 0
+#define reg_ata_r_stat_misc___crc___width 16
+#define reg_ata_r_stat_misc_offset 24
+
+/* Register rw_intr_mask, scope ata, type rw */
+#define reg_ata_rw_intr_mask___bus0___lsb 0
+#define reg_ata_rw_intr_mask___bus0___width 1
+#define reg_ata_rw_intr_mask___bus0___bit 0
+#define reg_ata_rw_intr_mask___bus1___lsb 1
+#define reg_ata_rw_intr_mask___bus1___width 1
+#define reg_ata_rw_intr_mask___bus1___bit 1
+#define reg_ata_rw_intr_mask___bus2___lsb 2
+#define reg_ata_rw_intr_mask___bus2___width 1
+#define reg_ata_rw_intr_mask___bus2___bit 2
+#define reg_ata_rw_intr_mask___bus3___lsb 3
+#define reg_ata_rw_intr_mask___bus3___width 1
+#define reg_ata_rw_intr_mask___bus3___bit 3
+#define reg_ata_rw_intr_mask_offset 28
+
+/* Register rw_ack_intr, scope ata, type rw */
+#define reg_ata_rw_ack_intr___bus0___lsb 0
+#define reg_ata_rw_ack_intr___bus0___width 1
+#define reg_ata_rw_ack_intr___bus0___bit 0
+#define reg_ata_rw_ack_intr___bus1___lsb 1
+#define reg_ata_rw_ack_intr___bus1___width 1
+#define reg_ata_rw_ack_intr___bus1___bit 1
+#define reg_ata_rw_ack_intr___bus2___lsb 2
+#define reg_ata_rw_ack_intr___bus2___width 1
+#define reg_ata_rw_ack_intr___bus2___bit 2
+#define reg_ata_rw_ack_intr___bus3___lsb 3
+#define reg_ata_rw_ack_intr___bus3___width 1
+#define reg_ata_rw_ack_intr___bus3___bit 3
+#define reg_ata_rw_ack_intr_offset 32
+
+/* Register r_intr, scope ata, type r */
+#define reg_ata_r_intr___bus0___lsb 0
+#define reg_ata_r_intr___bus0___width 1
+#define reg_ata_r_intr___bus0___bit 0
+#define reg_ata_r_intr___bus1___lsb 1
+#define reg_ata_r_intr___bus1___width 1
+#define reg_ata_r_intr___bus1___bit 1
+#define reg_ata_r_intr___bus2___lsb 2
+#define reg_ata_r_intr___bus2___width 1
+#define reg_ata_r_intr___bus2___bit 2
+#define reg_ata_r_intr___bus3___lsb 3
+#define reg_ata_r_intr___bus3___width 1
+#define reg_ata_r_intr___bus3___bit 3
+#define reg_ata_r_intr_offset 36
+
+/* Register r_masked_intr, scope ata, type r */
+#define reg_ata_r_masked_intr___bus0___lsb 0
+#define reg_ata_r_masked_intr___bus0___width 1
+#define reg_ata_r_masked_intr___bus0___bit 0
+#define reg_ata_r_masked_intr___bus1___lsb 1
+#define reg_ata_r_masked_intr___bus1___width 1
+#define reg_ata_r_masked_intr___bus1___bit 1
+#define reg_ata_r_masked_intr___bus2___lsb 2
+#define reg_ata_r_masked_intr___bus2___width 1
+#define reg_ata_r_masked_intr___bus2___bit 2
+#define reg_ata_r_masked_intr___bus3___lsb 3
+#define reg_ata_r_masked_intr___bus3___width 1
+#define reg_ata_r_masked_intr___bus3___bit 3
+#define reg_ata_r_masked_intr_offset 40
+
+
+/* Constants */
+#define regk_ata_active                           0x00000001
+#define regk_ata_byte                             0x00000001
+#define regk_ata_data                             0x00000001
+#define regk_ata_dma                              0x00000001
+#define regk_ata_inactive                         0x00000000
+#define regk_ata_no                               0x00000000
+#define regk_ata_nodata                           0x00000000
+#define regk_ata_pio                              0x00000000
+#define regk_ata_rd                               0x00000001
+#define regk_ata_reg                              0x00000000
+#define regk_ata_rw_ctrl0_default                 0x00000000
+#define regk_ata_rw_ctrl2_default                 0x00000000
+#define regk_ata_rw_intr_mask_default             0x00000000
+#define regk_ata_udma                             0x00000002
+#define regk_ata_word                             0x00000000
+#define regk_ata_wr                               0x00000000
+#define regk_ata_yes                              0x00000001
+#endif /* __ata_defs_asm_h */
diff --git a/include/asm-cris/arch-v32/hwregs/asm/bif_core_defs_asm.h b/include/asm-cris/arch-v32/hwregs/asm/bif_core_defs_asm.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/asm/bif_core_defs_asm.h
@@ -0,0 +1,319 @@
+#ifndef __bif_core_defs_asm_h
+#define __bif_core_defs_asm_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/bif/rtl/bif_core_regs.r
+ *     id:           bif_core_regs.r,v 1.17 2005/02/04 13:28:22 np Exp
+ *     last modfied: Mon Apr 11 16:06:33 2005
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c -asm --outfile asm/bif_core_defs_asm.h ../../inst/bif/rtl/bif_core_regs.r
+ *      id: $Id: bif_core_defs_asm.h,v 1.1 2005/04/24 18:31:04 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+
+#ifndef REG_FIELD
+#define REG_FIELD( scope, reg, field, value ) \
+  REG_FIELD_X_( value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_FIELD_X_( value, shift ) ((value) << shift)
+#endif
+
+#ifndef REG_STATE
+#define REG_STATE( scope, reg, field, symbolic_value ) \
+  REG_STATE_X_( regk_##scope##_##symbolic_value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_STATE_X_( k, shift ) (k << shift)
+#endif
+
+#ifndef REG_MASK
+#define REG_MASK( scope, reg, field ) \
+  REG_MASK_X_( reg_##scope##_##reg##___##field##___width, reg_##scope##_##reg##___##field##___lsb )
+#define REG_MASK_X_( width, lsb ) (((1 << width)-1) << lsb)
+#endif
+
+#ifndef REG_LSB
+#define REG_LSB( scope, reg, field ) reg_##scope##_##reg##___##field##___lsb
+#endif
+
+#ifndef REG_BIT
+#define REG_BIT( scope, reg, field ) reg_##scope##_##reg##___##field##___bit
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) REG_ADDR_X_(inst, reg_##scope##_##reg##_offset)
+#define REG_ADDR_X_( inst, offs ) ((inst) + offs)
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+         REG_ADDR_VECT_X_(inst, reg_##scope##_##reg##_offset, index, \
+			 STRIDE_##scope##_##reg )
+#define REG_ADDR_VECT_X_( inst, offs, index, stride ) \
+                          ((inst) + offs + (index) * stride)
+#endif
+
+/* Register rw_grp1_cfg, scope bif_core, type rw */
+#define reg_bif_core_rw_grp1_cfg___lw___lsb 0
+#define reg_bif_core_rw_grp1_cfg___lw___width 6
+#define reg_bif_core_rw_grp1_cfg___ew___lsb 6
+#define reg_bif_core_rw_grp1_cfg___ew___width 3
+#define reg_bif_core_rw_grp1_cfg___zw___lsb 9
+#define reg_bif_core_rw_grp1_cfg___zw___width 3
+#define reg_bif_core_rw_grp1_cfg___aw___lsb 12
+#define reg_bif_core_rw_grp1_cfg___aw___width 2
+#define reg_bif_core_rw_grp1_cfg___dw___lsb 14
+#define reg_bif_core_rw_grp1_cfg___dw___width 2
+#define reg_bif_core_rw_grp1_cfg___ewb___lsb 16
+#define reg_bif_core_rw_grp1_cfg___ewb___width 2
+#define reg_bif_core_rw_grp1_cfg___bw___lsb 18
+#define reg_bif_core_rw_grp1_cfg___bw___width 1
+#define reg_bif_core_rw_grp1_cfg___bw___bit 18
+#define reg_bif_core_rw_grp1_cfg___wr_extend___lsb 19
+#define reg_bif_core_rw_grp1_cfg___wr_extend___width 1
+#define reg_bif_core_rw_grp1_cfg___wr_extend___bit 19
+#define reg_bif_core_rw_grp1_cfg___erc_en___lsb 20
+#define reg_bif_core_rw_grp1_cfg___erc_en___width 1
+#define reg_bif_core_rw_grp1_cfg___erc_en___bit 20
+#define reg_bif_core_rw_grp1_cfg___mode___lsb 21
+#define reg_bif_core_rw_grp1_cfg___mode___width 1
+#define reg_bif_core_rw_grp1_cfg___mode___bit 21
+#define reg_bif_core_rw_grp1_cfg_offset 0
+
+/* Register rw_grp2_cfg, scope bif_core, type rw */
+#define reg_bif_core_rw_grp2_cfg___lw___lsb 0
+#define reg_bif_core_rw_grp2_cfg___lw___width 6
+#define reg_bif_core_rw_grp2_cfg___ew___lsb 6
+#define reg_bif_core_rw_grp2_cfg___ew___width 3
+#define reg_bif_core_rw_grp2_cfg___zw___lsb 9
+#define reg_bif_core_rw_grp2_cfg___zw___width 3
+#define reg_bif_core_rw_grp2_cfg___aw___lsb 12
+#define reg_bif_core_rw_grp2_cfg___aw___width 2
+#define reg_bif_core_rw_grp2_cfg___dw___lsb 14
+#define reg_bif_core_rw_grp2_cfg___dw___width 2
+#define reg_bif_core_rw_grp2_cfg___ewb___lsb 16
+#define reg_bif_core_rw_grp2_cfg___ewb___width 2
+#define reg_bif_core_rw_grp2_cfg___bw___lsb 18
+#define reg_bif_core_rw_grp2_cfg___bw___width 1
+#define reg_bif_core_rw_grp2_cfg___bw___bit 18
+#define reg_bif_core_rw_grp2_cfg___wr_extend___lsb 19
+#define reg_bif_core_rw_grp2_cfg___wr_extend___width 1
+#define reg_bif_core_rw_grp2_cfg___wr_extend___bit 19
+#define reg_bif_core_rw_grp2_cfg___erc_en___lsb 20
+#define reg_bif_core_rw_grp2_cfg___erc_en___width 1
+#define reg_bif_core_rw_grp2_cfg___erc_en___bit 20
+#define reg_bif_core_rw_grp2_cfg___mode___lsb 21
+#define reg_bif_core_rw_grp2_cfg___mode___width 1
+#define reg_bif_core_rw_grp2_cfg___mode___bit 21
+#define reg_bif_core_rw_grp2_cfg_offset 4
+
+/* Register rw_grp3_cfg, scope bif_core, type rw */
+#define reg_bif_core_rw_grp3_cfg___lw___lsb 0
+#define reg_bif_core_rw_grp3_cfg___lw___width 6
+#define reg_bif_core_rw_grp3_cfg___ew___lsb 6
+#define reg_bif_core_rw_grp3_cfg___ew___width 3
+#define reg_bif_core_rw_grp3_cfg___zw___lsb 9
+#define reg_bif_core_rw_grp3_cfg___zw___width 3
+#define reg_bif_core_rw_grp3_cfg___aw___lsb 12
+#define reg_bif_core_rw_grp3_cfg___aw___width 2
+#define reg_bif_core_rw_grp3_cfg___dw___lsb 14
+#define reg_bif_core_rw_grp3_cfg___dw___width 2
+#define reg_bif_core_rw_grp3_cfg___ewb___lsb 16
+#define reg_bif_core_rw_grp3_cfg___ewb___width 2
+#define reg_bif_core_rw_grp3_cfg___bw___lsb 18
+#define reg_bif_core_rw_grp3_cfg___bw___width 1
+#define reg_bif_core_rw_grp3_cfg___bw___bit 18
+#define reg_bif_core_rw_grp3_cfg___wr_extend___lsb 19
+#define reg_bif_core_rw_grp3_cfg___wr_extend___width 1
+#define reg_bif_core_rw_grp3_cfg___wr_extend___bit 19
+#define reg_bif_core_rw_grp3_cfg___erc_en___lsb 20
+#define reg_bif_core_rw_grp3_cfg___erc_en___width 1
+#define reg_bif_core_rw_grp3_cfg___erc_en___bit 20
+#define reg_bif_core_rw_grp3_cfg___mode___lsb 21
+#define reg_bif_core_rw_grp3_cfg___mode___width 1
+#define reg_bif_core_rw_grp3_cfg___mode___bit 21
+#define reg_bif_core_rw_grp3_cfg___gated_csp0___lsb 24
+#define reg_bif_core_rw_grp3_cfg___gated_csp0___width 2
+#define reg_bif_core_rw_grp3_cfg___gated_csp1___lsb 26
+#define reg_bif_core_rw_grp3_cfg___gated_csp1___width 2
+#define reg_bif_core_rw_grp3_cfg___gated_csp2___lsb 28
+#define reg_bif_core_rw_grp3_cfg___gated_csp2___width 2
+#define reg_bif_core_rw_grp3_cfg___gated_csp3___lsb 30
+#define reg_bif_core_rw_grp3_cfg___gated_csp3___width 2
+#define reg_bif_core_rw_grp3_cfg_offset 8
+
+/* Register rw_grp4_cfg, scope bif_core, type rw */
+#define reg_bif_core_rw_grp4_cfg___lw___lsb 0
+#define reg_bif_core_rw_grp4_cfg___lw___width 6
+#define reg_bif_core_rw_grp4_cfg___ew___lsb 6
+#define reg_bif_core_rw_grp4_cfg___ew___width 3
+#define reg_bif_core_rw_grp4_cfg___zw___lsb 9
+#define reg_bif_core_rw_grp4_cfg___zw___width 3
+#define reg_bif_core_rw_grp4_cfg___aw___lsb 12
+#define reg_bif_core_rw_grp4_cfg___aw___width 2
+#define reg_bif_core_rw_grp4_cfg___dw___lsb 14
+#define reg_bif_core_rw_grp4_cfg___dw___width 2
+#define reg_bif_core_rw_grp4_cfg___ewb___lsb 16
+#define reg_bif_core_rw_grp4_cfg___ewb___width 2
+#define reg_bif_core_rw_grp4_cfg___bw___lsb 18
+#define reg_bif_core_rw_grp4_cfg___bw___width 1
+#define reg_bif_core_rw_grp4_cfg___bw___bit 18
+#define reg_bif_core_rw_grp4_cfg___wr_extend___lsb 19
+#define reg_bif_core_rw_grp4_cfg___wr_extend___width 1
+#define reg_bif_core_rw_grp4_cfg___wr_extend___bit 19
+#define reg_bif_core_rw_grp4_cfg___erc_en___lsb 20
+#define reg_bif_core_rw_grp4_cfg___erc_en___width 1
+#define reg_bif_core_rw_grp4_cfg___erc_en___bit 20
+#define reg_bif_core_rw_grp4_cfg___mode___lsb 21
+#define reg_bif_core_rw_grp4_cfg___mode___width 1
+#define reg_bif_core_rw_grp4_cfg___mode___bit 21
+#define reg_bif_core_rw_grp4_cfg___gated_csp4___lsb 26
+#define reg_bif_core_rw_grp4_cfg___gated_csp4___width 2
+#define reg_bif_core_rw_grp4_cfg___gated_csp5___lsb 28
+#define reg_bif_core_rw_grp4_cfg___gated_csp5___width 2
+#define reg_bif_core_rw_grp4_cfg___gated_csp6___lsb 30
+#define reg_bif_core_rw_grp4_cfg___gated_csp6___width 2
+#define reg_bif_core_rw_grp4_cfg_offset 12
+
+/* Register rw_sdram_cfg_grp0, scope bif_core, type rw */
+#define reg_bif_core_rw_sdram_cfg_grp0___bank_sel___lsb 0
+#define reg_bif_core_rw_sdram_cfg_grp0___bank_sel___width 5
+#define reg_bif_core_rw_sdram_cfg_grp0___ca___lsb 5
+#define reg_bif_core_rw_sdram_cfg_grp0___ca___width 3
+#define reg_bif_core_rw_sdram_cfg_grp0___type___lsb 8
+#define reg_bif_core_rw_sdram_cfg_grp0___type___width 1
+#define reg_bif_core_rw_sdram_cfg_grp0___type___bit 8
+#define reg_bif_core_rw_sdram_cfg_grp0___bw___lsb 9
+#define reg_bif_core_rw_sdram_cfg_grp0___bw___width 1
+#define reg_bif_core_rw_sdram_cfg_grp0___bw___bit 9
+#define reg_bif_core_rw_sdram_cfg_grp0___sh___lsb 10
+#define reg_bif_core_rw_sdram_cfg_grp0___sh___width 3
+#define reg_bif_core_rw_sdram_cfg_grp0___wmm___lsb 13
+#define reg_bif_core_rw_sdram_cfg_grp0___wmm___width 1
+#define reg_bif_core_rw_sdram_cfg_grp0___wmm___bit 13
+#define reg_bif_core_rw_sdram_cfg_grp0___sh16___lsb 14
+#define reg_bif_core_rw_sdram_cfg_grp0___sh16___width 1
+#define reg_bif_core_rw_sdram_cfg_grp0___sh16___bit 14
+#define reg_bif_core_rw_sdram_cfg_grp0___grp_sel___lsb 15
+#define reg_bif_core_rw_sdram_cfg_grp0___grp_sel___width 5
+#define reg_bif_core_rw_sdram_cfg_grp0_offset 16
+
+/* Register rw_sdram_cfg_grp1, scope bif_core, type rw */
+#define reg_bif_core_rw_sdram_cfg_grp1___bank_sel___lsb 0
+#define reg_bif_core_rw_sdram_cfg_grp1___bank_sel___width 5
+#define reg_bif_core_rw_sdram_cfg_grp1___ca___lsb 5
+#define reg_bif_core_rw_sdram_cfg_grp1___ca___width 3
+#define reg_bif_core_rw_sdram_cfg_grp1___type___lsb 8
+#define reg_bif_core_rw_sdram_cfg_grp1___type___width 1
+#define reg_bif_core_rw_sdram_cfg_grp1___type___bit 8
+#define reg_bif_core_rw_sdram_cfg_grp1___bw___lsb 9
+#define reg_bif_core_rw_sdram_cfg_grp1___bw___width 1
+#define reg_bif_core_rw_sdram_cfg_grp1___bw___bit 9
+#define reg_bif_core_rw_sdram_cfg_grp1___sh___lsb 10
+#define reg_bif_core_rw_sdram_cfg_grp1___sh___width 3
+#define reg_bif_core_rw_sdram_cfg_grp1___wmm___lsb 13
+#define reg_bif_core_rw_sdram_cfg_grp1___wmm___width 1
+#define reg_bif_core_rw_sdram_cfg_grp1___wmm___bit 13
+#define reg_bif_core_rw_sdram_cfg_grp1___sh16___lsb 14
+#define reg_bif_core_rw_sdram_cfg_grp1___sh16___width 1
+#define reg_bif_core_rw_sdram_cfg_grp1___sh16___bit 14
+#define reg_bif_core_rw_sdram_cfg_grp1_offset 20
+
+/* Register rw_sdram_timing, scope bif_core, type rw */
+#define reg_bif_core_rw_sdram_timing___cl___lsb 0
+#define reg_bif_core_rw_sdram_timing___cl___width 3
+#define reg_bif_core_rw_sdram_timing___rcd___lsb 3
+#define reg_bif_core_rw_sdram_timing___rcd___width 3
+#define reg_bif_core_rw_sdram_timing___rp___lsb 6
+#define reg_bif_core_rw_sdram_timing___rp___width 3
+#define reg_bif_core_rw_sdram_timing___rc___lsb 9
+#define reg_bif_core_rw_sdram_timing___rc___width 2
+#define reg_bif_core_rw_sdram_timing___dpl___lsb 11
+#define reg_bif_core_rw_sdram_timing___dpl___width 2
+#define reg_bif_core_rw_sdram_timing___pde___lsb 13
+#define reg_bif_core_rw_sdram_timing___pde___width 1
+#define reg_bif_core_rw_sdram_timing___pde___bit 13
+#define reg_bif_core_rw_sdram_timing___ref___lsb 14
+#define reg_bif_core_rw_sdram_timing___ref___width 2
+#define reg_bif_core_rw_sdram_timing___cpd___lsb 16
+#define reg_bif_core_rw_sdram_timing___cpd___width 1
+#define reg_bif_core_rw_sdram_timing___cpd___bit 16
+#define reg_bif_core_rw_sdram_timing___sdcke___lsb 17
+#define reg_bif_core_rw_sdram_timing___sdcke___width 1
+#define reg_bif_core_rw_sdram_timing___sdcke___bit 17
+#define reg_bif_core_rw_sdram_timing___sdclk___lsb 18
+#define reg_bif_core_rw_sdram_timing___sdclk___width 1
+#define reg_bif_core_rw_sdram_timing___sdclk___bit 18
+#define reg_bif_core_rw_sdram_timing_offset 24
+
+/* Register rw_sdram_cmd, scope bif_core, type rw */
+#define reg_bif_core_rw_sdram_cmd___cmd___lsb 0
+#define reg_bif_core_rw_sdram_cmd___cmd___width 3
+#define reg_bif_core_rw_sdram_cmd___mrs_data___lsb 3
+#define reg_bif_core_rw_sdram_cmd___mrs_data___width 15
+#define reg_bif_core_rw_sdram_cmd_offset 28
+
+/* Register rs_sdram_ref_stat, scope bif_core, type rs */
+#define reg_bif_core_rs_sdram_ref_stat___ok___lsb 0
+#define reg_bif_core_rs_sdram_ref_stat___ok___width 1
+#define reg_bif_core_rs_sdram_ref_stat___ok___bit 0
+#define reg_bif_core_rs_sdram_ref_stat_offset 32
+
+/* Register r_sdram_ref_stat, scope bif_core, type r */
+#define reg_bif_core_r_sdram_ref_stat___ok___lsb 0
+#define reg_bif_core_r_sdram_ref_stat___ok___width 1
+#define reg_bif_core_r_sdram_ref_stat___ok___bit 0
+#define reg_bif_core_r_sdram_ref_stat_offset 36
+
+
+/* Constants */
+#define regk_bif_core_bank2                       0x00000000
+#define regk_bif_core_bank4                       0x00000001
+#define regk_bif_core_bit10                       0x0000000a
+#define regk_bif_core_bit11                       0x0000000b
+#define regk_bif_core_bit12                       0x0000000c
+#define regk_bif_core_bit13                       0x0000000d
+#define regk_bif_core_bit14                       0x0000000e
+#define regk_bif_core_bit15                       0x0000000f
+#define regk_bif_core_bit16                       0x00000010
+#define regk_bif_core_bit17                       0x00000011
+#define regk_bif_core_bit18                       0x00000012
+#define regk_bif_core_bit19                       0x00000013
+#define regk_bif_core_bit20                       0x00000014
+#define regk_bif_core_bit21                       0x00000015
+#define regk_bif_core_bit22                       0x00000016
+#define regk_bif_core_bit23                       0x00000017
+#define regk_bif_core_bit24                       0x00000018
+#define regk_bif_core_bit25                       0x00000019
+#define regk_bif_core_bit26                       0x0000001a
+#define regk_bif_core_bit27                       0x0000001b
+#define regk_bif_core_bit28                       0x0000001c
+#define regk_bif_core_bit29                       0x0000001d
+#define regk_bif_core_bit9                        0x00000009
+#define regk_bif_core_bw16                        0x00000001
+#define regk_bif_core_bw32                        0x00000000
+#define regk_bif_core_bwe                         0x00000000
+#define regk_bif_core_cwe                         0x00000001
+#define regk_bif_core_e15us                       0x00000001
+#define regk_bif_core_e7800ns                     0x00000002
+#define regk_bif_core_grp0                        0x00000000
+#define regk_bif_core_grp1                        0x00000001
+#define regk_bif_core_mrs                         0x00000003
+#define regk_bif_core_no                          0x00000000
+#define regk_bif_core_none                        0x00000000
+#define regk_bif_core_nop                         0x00000000
+#define regk_bif_core_off                         0x00000000
+#define regk_bif_core_pre                         0x00000002
+#define regk_bif_core_r_sdram_ref_stat_default    0x00000001
+#define regk_bif_core_rd                          0x00000002
+#define regk_bif_core_ref                         0x00000001
+#define regk_bif_core_rs_sdram_ref_stat_default   0x00000001
+#define regk_bif_core_rw_grp1_cfg_default         0x000006cf
+#define regk_bif_core_rw_grp2_cfg_default         0x000006cf
+#define regk_bif_core_rw_grp3_cfg_default         0x000006cf
+#define regk_bif_core_rw_grp4_cfg_default         0x000006cf
+#define regk_bif_core_rw_sdram_cfg_grp1_default   0x00000000
+#define regk_bif_core_slf                         0x00000004
+#define regk_bif_core_wr                          0x00000001
+#define regk_bif_core_yes                         0x00000001
+#endif /* __bif_core_defs_asm_h */
diff --git a/include/asm-cris/arch-v32/hwregs/asm/bif_dma_defs_asm.h b/include/asm-cris/arch-v32/hwregs/asm/bif_dma_defs_asm.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/asm/bif_dma_defs_asm.h
@@ -0,0 +1,495 @@
+#ifndef __bif_dma_defs_asm_h
+#define __bif_dma_defs_asm_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/bif/rtl/bif_dma_regs.r
+ *     id:           bif_dma_regs.r,v 1.6 2005/02/04 13:28:31 perz Exp
+ *     last modfied: Mon Apr 11 16:06:33 2005
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c -asm --outfile asm/bif_dma_defs_asm.h ../../inst/bif/rtl/bif_dma_regs.r
+ *      id: $Id: bif_dma_defs_asm.h,v 1.1 2005/04/24 18:31:04 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+
+#ifndef REG_FIELD
+#define REG_FIELD( scope, reg, field, value ) \
+  REG_FIELD_X_( value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_FIELD_X_( value, shift ) ((value) << shift)
+#endif
+
+#ifndef REG_STATE
+#define REG_STATE( scope, reg, field, symbolic_value ) \
+  REG_STATE_X_( regk_##scope##_##symbolic_value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_STATE_X_( k, shift ) (k << shift)
+#endif
+
+#ifndef REG_MASK
+#define REG_MASK( scope, reg, field ) \
+  REG_MASK_X_( reg_##scope##_##reg##___##field##___width, reg_##scope##_##reg##___##field##___lsb )
+#define REG_MASK_X_( width, lsb ) (((1 << width)-1) << lsb)
+#endif
+
+#ifndef REG_LSB
+#define REG_LSB( scope, reg, field ) reg_##scope##_##reg##___##field##___lsb
+#endif
+
+#ifndef REG_BIT
+#define REG_BIT( scope, reg, field ) reg_##scope##_##reg##___##field##___bit
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) REG_ADDR_X_(inst, reg_##scope##_##reg##_offset)
+#define REG_ADDR_X_( inst, offs ) ((inst) + offs)
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+         REG_ADDR_VECT_X_(inst, reg_##scope##_##reg##_offset, index, \
+			 STRIDE_##scope##_##reg )
+#define REG_ADDR_VECT_X_( inst, offs, index, stride ) \
+                          ((inst) + offs + (index) * stride)
+#endif
+
+/* Register rw_ch0_ctrl, scope bif_dma, type rw */
+#define reg_bif_dma_rw_ch0_ctrl___bw___lsb 0
+#define reg_bif_dma_rw_ch0_ctrl___bw___width 2
+#define reg_bif_dma_rw_ch0_ctrl___burst_len___lsb 2
+#define reg_bif_dma_rw_ch0_ctrl___burst_len___width 1
+#define reg_bif_dma_rw_ch0_ctrl___burst_len___bit 2
+#define reg_bif_dma_rw_ch0_ctrl___cont___lsb 3
+#define reg_bif_dma_rw_ch0_ctrl___cont___width 1
+#define reg_bif_dma_rw_ch0_ctrl___cont___bit 3
+#define reg_bif_dma_rw_ch0_ctrl___end_pad___lsb 4
+#define reg_bif_dma_rw_ch0_ctrl___end_pad___width 1
+#define reg_bif_dma_rw_ch0_ctrl___end_pad___bit 4
+#define reg_bif_dma_rw_ch0_ctrl___cnt___lsb 5
+#define reg_bif_dma_rw_ch0_ctrl___cnt___width 1
+#define reg_bif_dma_rw_ch0_ctrl___cnt___bit 5
+#define reg_bif_dma_rw_ch0_ctrl___dreq_pin___lsb 6
+#define reg_bif_dma_rw_ch0_ctrl___dreq_pin___width 3
+#define reg_bif_dma_rw_ch0_ctrl___dreq_mode___lsb 9
+#define reg_bif_dma_rw_ch0_ctrl___dreq_mode___width 2
+#define reg_bif_dma_rw_ch0_ctrl___tc_in_pin___lsb 11
+#define reg_bif_dma_rw_ch0_ctrl___tc_in_pin___width 3
+#define reg_bif_dma_rw_ch0_ctrl___tc_in_mode___lsb 14
+#define reg_bif_dma_rw_ch0_ctrl___tc_in_mode___width 2
+#define reg_bif_dma_rw_ch0_ctrl___bus_mode___lsb 16
+#define reg_bif_dma_rw_ch0_ctrl___bus_mode___width 2
+#define reg_bif_dma_rw_ch0_ctrl___rate_en___lsb 18
+#define reg_bif_dma_rw_ch0_ctrl___rate_en___width 1
+#define reg_bif_dma_rw_ch0_ctrl___rate_en___bit 18
+#define reg_bif_dma_rw_ch0_ctrl___wr_all___lsb 19
+#define reg_bif_dma_rw_ch0_ctrl___wr_all___width 1
+#define reg_bif_dma_rw_ch0_ctrl___wr_all___bit 19
+#define reg_bif_dma_rw_ch0_ctrl_offset 0
+
+/* Register rw_ch0_addr, scope bif_dma, type rw */
+#define reg_bif_dma_rw_ch0_addr___addr___lsb 0
+#define reg_bif_dma_rw_ch0_addr___addr___width 32
+#define reg_bif_dma_rw_ch0_addr_offset 4
+
+/* Register rw_ch0_start, scope bif_dma, type rw */
+#define reg_bif_dma_rw_ch0_start___run___lsb 0
+#define reg_bif_dma_rw_ch0_start___run___width 1
+#define reg_bif_dma_rw_ch0_start___run___bit 0
+#define reg_bif_dma_rw_ch0_start_offset 8
+
+/* Register rw_ch0_cnt, scope bif_dma, type rw */
+#define reg_bif_dma_rw_ch0_cnt___start_cnt___lsb 0
+#define reg_bif_dma_rw_ch0_cnt___start_cnt___width 16
+#define reg_bif_dma_rw_ch0_cnt_offset 12
+
+/* Register r_ch0_stat, scope bif_dma, type r */
+#define reg_bif_dma_r_ch0_stat___cnt___lsb 0
+#define reg_bif_dma_r_ch0_stat___cnt___width 16
+#define reg_bif_dma_r_ch0_stat___run___lsb 31
+#define reg_bif_dma_r_ch0_stat___run___width 1
+#define reg_bif_dma_r_ch0_stat___run___bit 31
+#define reg_bif_dma_r_ch0_stat_offset 16
+
+/* Register rw_ch1_ctrl, scope bif_dma, type rw */
+#define reg_bif_dma_rw_ch1_ctrl___bw___lsb 0
+#define reg_bif_dma_rw_ch1_ctrl___bw___width 2
+#define reg_bif_dma_rw_ch1_ctrl___burst_len___lsb 2
+#define reg_bif_dma_rw_ch1_ctrl___burst_len___width 1
+#define reg_bif_dma_rw_ch1_ctrl___burst_len___bit 2
+#define reg_bif_dma_rw_ch1_ctrl___cont___lsb 3
+#define reg_bif_dma_rw_ch1_ctrl___cont___width 1
+#define reg_bif_dma_rw_ch1_ctrl___cont___bit 3
+#define reg_bif_dma_rw_ch1_ctrl___end_discard___lsb 4
+#define reg_bif_dma_rw_ch1_ctrl___end_discard___width 1
+#define reg_bif_dma_rw_ch1_ctrl___end_discard___bit 4
+#define reg_bif_dma_rw_ch1_ctrl___cnt___lsb 5
+#define reg_bif_dma_rw_ch1_ctrl___cnt___width 1
+#define reg_bif_dma_rw_ch1_ctrl___cnt___bit 5
+#define reg_bif_dma_rw_ch1_ctrl___dreq_pin___lsb 6
+#define reg_bif_dma_rw_ch1_ctrl___dreq_pin___width 3
+#define reg_bif_dma_rw_ch1_ctrl___dreq_mode___lsb 9
+#define reg_bif_dma_rw_ch1_ctrl___dreq_mode___width 2
+#define reg_bif_dma_rw_ch1_ctrl___tc_in_pin___lsb 11
+#define reg_bif_dma_rw_ch1_ctrl___tc_in_pin___width 3
+#define reg_bif_dma_rw_ch1_ctrl___tc_in_mode___lsb 14
+#define reg_bif_dma_rw_ch1_ctrl___tc_in_mode___width 2
+#define reg_bif_dma_rw_ch1_ctrl___bus_mode___lsb 16
+#define reg_bif_dma_rw_ch1_ctrl___bus_mode___width 2
+#define reg_bif_dma_rw_ch1_ctrl___rate_en___lsb 18
+#define reg_bif_dma_rw_ch1_ctrl___rate_en___width 1
+#define reg_bif_dma_rw_ch1_ctrl___rate_en___bit 18
+#define reg_bif_dma_rw_ch1_ctrl_offset 32
+
+/* Register rw_ch1_addr, scope bif_dma, type rw */
+#define reg_bif_dma_rw_ch1_addr___addr___lsb 0
+#define reg_bif_dma_rw_ch1_addr___addr___width 32
+#define reg_bif_dma_rw_ch1_addr_offset 36
+
+/* Register rw_ch1_start, scope bif_dma, type rw */
+#define reg_bif_dma_rw_ch1_start___run___lsb 0
+#define reg_bif_dma_rw_ch1_start___run___width 1
+#define reg_bif_dma_rw_ch1_start___run___bit 0
+#define reg_bif_dma_rw_ch1_start_offset 40
+
+/* Register rw_ch1_cnt, scope bif_dma, type rw */
+#define reg_bif_dma_rw_ch1_cnt___start_cnt___lsb 0
+#define reg_bif_dma_rw_ch1_cnt___start_cnt___width 16
+#define reg_bif_dma_rw_ch1_cnt_offset 44
+
+/* Register r_ch1_stat, scope bif_dma, type r */
+#define reg_bif_dma_r_ch1_stat___cnt___lsb 0
+#define reg_bif_dma_r_ch1_stat___cnt___width 16
+#define reg_bif_dma_r_ch1_stat___run___lsb 31
+#define reg_bif_dma_r_ch1_stat___run___width 1
+#define reg_bif_dma_r_ch1_stat___run___bit 31
+#define reg_bif_dma_r_ch1_stat_offset 48
+
+/* Register rw_ch2_ctrl, scope bif_dma, type rw */
+#define reg_bif_dma_rw_ch2_ctrl___bw___lsb 0
+#define reg_bif_dma_rw_ch2_ctrl___bw___width 2
+#define reg_bif_dma_rw_ch2_ctrl___burst_len___lsb 2
+#define reg_bif_dma_rw_ch2_ctrl___burst_len___width 1
+#define reg_bif_dma_rw_ch2_ctrl___burst_len___bit 2
+#define reg_bif_dma_rw_ch2_ctrl___cont___lsb 3
+#define reg_bif_dma_rw_ch2_ctrl___cont___width 1
+#define reg_bif_dma_rw_ch2_ctrl___cont___bit 3
+#define reg_bif_dma_rw_ch2_ctrl___end_pad___lsb 4
+#define reg_bif_dma_rw_ch2_ctrl___end_pad___width 1
+#define reg_bif_dma_rw_ch2_ctrl___end_pad___bit 4
+#define reg_bif_dma_rw_ch2_ctrl___cnt___lsb 5
+#define reg_bif_dma_rw_ch2_ctrl___cnt___width 1
+#define reg_bif_dma_rw_ch2_ctrl___cnt___bit 5
+#define reg_bif_dma_rw_ch2_ctrl___dreq_pin___lsb 6
+#define reg_bif_dma_rw_ch2_ctrl___dreq_pin___width 3
+#define reg_bif_dma_rw_ch2_ctrl___dreq_mode___lsb 9
+#define reg_bif_dma_rw_ch2_ctrl___dreq_mode___width 2
+#define reg_bif_dma_rw_ch2_ctrl___tc_in_pin___lsb 11
+#define reg_bif_dma_rw_ch2_ctrl___tc_in_pin___width 3
+#define reg_bif_dma_rw_ch2_ctrl___tc_in_mode___lsb 14
+#define reg_bif_dma_rw_ch2_ctrl___tc_in_mode___width 2
+#define reg_bif_dma_rw_ch2_ctrl___bus_mode___lsb 16
+#define reg_bif_dma_rw_ch2_ctrl___bus_mode___width 2
+#define reg_bif_dma_rw_ch2_ctrl___rate_en___lsb 18
+#define reg_bif_dma_rw_ch2_ctrl___rate_en___width 1
+#define reg_bif_dma_rw_ch2_ctrl___rate_en___bit 18
+#define reg_bif_dma_rw_ch2_ctrl___wr_all___lsb 19
+#define reg_bif_dma_rw_ch2_ctrl___wr_all___width 1
+#define reg_bif_dma_rw_ch2_ctrl___wr_all___bit 19
+#define reg_bif_dma_rw_ch2_ctrl_offset 64
+
+/* Register rw_ch2_addr, scope bif_dma, type rw */
+#define reg_bif_dma_rw_ch2_addr___addr___lsb 0
+#define reg_bif_dma_rw_ch2_addr___addr___width 32
+#define reg_bif_dma_rw_ch2_addr_offset 68
+
+/* Register rw_ch2_start, scope bif_dma, type rw */
+#define reg_bif_dma_rw_ch2_start___run___lsb 0
+#define reg_bif_dma_rw_ch2_start___run___width 1
+#define reg_bif_dma_rw_ch2_start___run___bit 0
+#define reg_bif_dma_rw_ch2_start_offset 72
+
+/* Register rw_ch2_cnt, scope bif_dma, type rw */
+#define reg_bif_dma_rw_ch2_cnt___start_cnt___lsb 0
+#define reg_bif_dma_rw_ch2_cnt___start_cnt___width 16
+#define reg_bif_dma_rw_ch2_cnt_offset 76
+
+/* Register r_ch2_stat, scope bif_dma, type r */
+#define reg_bif_dma_r_ch2_stat___cnt___lsb 0
+#define reg_bif_dma_r_ch2_stat___cnt___width 16
+#define reg_bif_dma_r_ch2_stat___run___lsb 31
+#define reg_bif_dma_r_ch2_stat___run___width 1
+#define reg_bif_dma_r_ch2_stat___run___bit 31
+#define reg_bif_dma_r_ch2_stat_offset 80
+
+/* Register rw_ch3_ctrl, scope bif_dma, type rw */
+#define reg_bif_dma_rw_ch3_ctrl___bw___lsb 0
+#define reg_bif_dma_rw_ch3_ctrl___bw___width 2
+#define reg_bif_dma_rw_ch3_ctrl___burst_len___lsb 2
+#define reg_bif_dma_rw_ch3_ctrl___burst_len___width 1
+#define reg_bif_dma_rw_ch3_ctrl___burst_len___bit 2
+#define reg_bif_dma_rw_ch3_ctrl___cont___lsb 3
+#define reg_bif_dma_rw_ch3_ctrl___cont___width 1
+#define reg_bif_dma_rw_ch3_ctrl___cont___bit 3
+#define reg_bif_dma_rw_ch3_ctrl___end_discard___lsb 4
+#define reg_bif_dma_rw_ch3_ctrl___end_discard___width 1
+#define reg_bif_dma_rw_ch3_ctrl___end_discard___bit 4
+#define reg_bif_dma_rw_ch3_ctrl___cnt___lsb 5
+#define reg_bif_dma_rw_ch3_ctrl___cnt___width 1
+#define reg_bif_dma_rw_ch3_ctrl___cnt___bit 5
+#define reg_bif_dma_rw_ch3_ctrl___dreq_pin___lsb 6
+#define reg_bif_dma_rw_ch3_ctrl___dreq_pin___width 3
+#define reg_bif_dma_rw_ch3_ctrl___dreq_mode___lsb 9
+#define reg_bif_dma_rw_ch3_ctrl___dreq_mode___width 2
+#define reg_bif_dma_rw_ch3_ctrl___tc_in_pin___lsb 11
+#define reg_bif_dma_rw_ch3_ctrl___tc_in_pin___width 3
+#define reg_bif_dma_rw_ch3_ctrl___tc_in_mode___lsb 14
+#define reg_bif_dma_rw_ch3_ctrl___tc_in_mode___width 2
+#define reg_bif_dma_rw_ch3_ctrl___bus_mode___lsb 16
+#define reg_bif_dma_rw_ch3_ctrl___bus_mode___width 2
+#define reg_bif_dma_rw_ch3_ctrl___rate_en___lsb 18
+#define reg_bif_dma_rw_ch3_ctrl___rate_en___width 1
+#define reg_bif_dma_rw_ch3_ctrl___rate_en___bit 18
+#define reg_bif_dma_rw_ch3_ctrl_offset 96
+
+/* Register rw_ch3_addr, scope bif_dma, type rw */
+#define reg_bif_dma_rw_ch3_addr___addr___lsb 0
+#define reg_bif_dma_rw_ch3_addr___addr___width 32
+#define reg_bif_dma_rw_ch3_addr_offset 100
+
+/* Register rw_ch3_start, scope bif_dma, type rw */
+#define reg_bif_dma_rw_ch3_start___run___lsb 0
+#define reg_bif_dma_rw_ch3_start___run___width 1
+#define reg_bif_dma_rw_ch3_start___run___bit 0
+#define reg_bif_dma_rw_ch3_start_offset 104
+
+/* Register rw_ch3_cnt, scope bif_dma, type rw */
+#define reg_bif_dma_rw_ch3_cnt___start_cnt___lsb 0
+#define reg_bif_dma_rw_ch3_cnt___start_cnt___width 16
+#define reg_bif_dma_rw_ch3_cnt_offset 108
+
+/* Register r_ch3_stat, scope bif_dma, type r */
+#define reg_bif_dma_r_ch3_stat___cnt___lsb 0
+#define reg_bif_dma_r_ch3_stat___cnt___width 16
+#define reg_bif_dma_r_ch3_stat___run___lsb 31
+#define reg_bif_dma_r_ch3_stat___run___width 1
+#define reg_bif_dma_r_ch3_stat___run___bit 31
+#define reg_bif_dma_r_ch3_stat_offset 112
+
+/* Register rw_intr_mask, scope bif_dma, type rw */
+#define reg_bif_dma_rw_intr_mask___ext_dma0___lsb 0
+#define reg_bif_dma_rw_intr_mask___ext_dma0___width 1
+#define reg_bif_dma_rw_intr_mask___ext_dma0___bit 0
+#define reg_bif_dma_rw_intr_mask___ext_dma1___lsb 1
+#define reg_bif_dma_rw_intr_mask___ext_dma1___width 1
+#define reg_bif_dma_rw_intr_mask___ext_dma1___bit 1
+#define reg_bif_dma_rw_intr_mask___ext_dma2___lsb 2
+#define reg_bif_dma_rw_intr_mask___ext_dma2___width 1
+#define reg_bif_dma_rw_intr_mask___ext_dma2___bit 2
+#define reg_bif_dma_rw_intr_mask___ext_dma3___lsb 3
+#define reg_bif_dma_rw_intr_mask___ext_dma3___width 1
+#define reg_bif_dma_rw_intr_mask___ext_dma3___bit 3
+#define reg_bif_dma_rw_intr_mask_offset 128
+
+/* Register rw_ack_intr, scope bif_dma, type rw */
+#define reg_bif_dma_rw_ack_intr___ext_dma0___lsb 0
+#define reg_bif_dma_rw_ack_intr___ext_dma0___width 1
+#define reg_bif_dma_rw_ack_intr___ext_dma0___bit 0
+#define reg_bif_dma_rw_ack_intr___ext_dma1___lsb 1
+#define reg_bif_dma_rw_ack_intr___ext_dma1___width 1
+#define reg_bif_dma_rw_ack_intr___ext_dma1___bit 1
+#define reg_bif_dma_rw_ack_intr___ext_dma2___lsb 2
+#define reg_bif_dma_rw_ack_intr___ext_dma2___width 1
+#define reg_bif_dma_rw_ack_intr___ext_dma2___bit 2
+#define reg_bif_dma_rw_ack_intr___ext_dma3___lsb 3
+#define reg_bif_dma_rw_ack_intr___ext_dma3___width 1
+#define reg_bif_dma_rw_ack_intr___ext_dma3___bit 3
+#define reg_bif_dma_rw_ack_intr_offset 132
+
+/* Register r_intr, scope bif_dma, type r */
+#define reg_bif_dma_r_intr___ext_dma0___lsb 0
+#define reg_bif_dma_r_intr___ext_dma0___width 1
+#define reg_bif_dma_r_intr___ext_dma0___bit 0
+#define reg_bif_dma_r_intr___ext_dma1___lsb 1
+#define reg_bif_dma_r_intr___ext_dma1___width 1
+#define reg_bif_dma_r_intr___ext_dma1___bit 1
+#define reg_bif_dma_r_intr___ext_dma2___lsb 2
+#define reg_bif_dma_r_intr___ext_dma2___width 1
+#define reg_bif_dma_r_intr___ext_dma2___bit 2
+#define reg_bif_dma_r_intr___ext_dma3___lsb 3
+#define reg_bif_dma_r_intr___ext_dma3___width 1
+#define reg_bif_dma_r_intr___ext_dma3___bit 3
+#define reg_bif_dma_r_intr_offset 136
+
+/* Register r_masked_intr, scope bif_dma, type r */
+#define reg_bif_dma_r_masked_intr___ext_dma0___lsb 0
+#define reg_bif_dma_r_masked_intr___ext_dma0___width 1
+#define reg_bif_dma_r_masked_intr___ext_dma0___bit 0
+#define reg_bif_dma_r_masked_intr___ext_dma1___lsb 1
+#define reg_bif_dma_r_masked_intr___ext_dma1___width 1
+#define reg_bif_dma_r_masked_intr___ext_dma1___bit 1
+#define reg_bif_dma_r_masked_intr___ext_dma2___lsb 2
+#define reg_bif_dma_r_masked_intr___ext_dma2___width 1
+#define reg_bif_dma_r_masked_intr___ext_dma2___bit 2
+#define reg_bif_dma_r_masked_intr___ext_dma3___lsb 3
+#define reg_bif_dma_r_masked_intr___ext_dma3___width 1
+#define reg_bif_dma_r_masked_intr___ext_dma3___bit 3
+#define reg_bif_dma_r_masked_intr_offset 140
+
+/* Register rw_pin0_cfg, scope bif_dma, type rw */
+#define reg_bif_dma_rw_pin0_cfg___master_ch___lsb 0
+#define reg_bif_dma_rw_pin0_cfg___master_ch___width 2
+#define reg_bif_dma_rw_pin0_cfg___master_mode___lsb 2
+#define reg_bif_dma_rw_pin0_cfg___master_mode___width 3
+#define reg_bif_dma_rw_pin0_cfg___slave_ch___lsb 5
+#define reg_bif_dma_rw_pin0_cfg___slave_ch___width 2
+#define reg_bif_dma_rw_pin0_cfg___slave_mode___lsb 7
+#define reg_bif_dma_rw_pin0_cfg___slave_mode___width 3
+#define reg_bif_dma_rw_pin0_cfg_offset 160
+
+/* Register rw_pin1_cfg, scope bif_dma, type rw */
+#define reg_bif_dma_rw_pin1_cfg___master_ch___lsb 0
+#define reg_bif_dma_rw_pin1_cfg___master_ch___width 2
+#define reg_bif_dma_rw_pin1_cfg___master_mode___lsb 2
+#define reg_bif_dma_rw_pin1_cfg___master_mode___width 3
+#define reg_bif_dma_rw_pin1_cfg___slave_ch___lsb 5
+#define reg_bif_dma_rw_pin1_cfg___slave_ch___width 2
+#define reg_bif_dma_rw_pin1_cfg___slave_mode___lsb 7
+#define reg_bif_dma_rw_pin1_cfg___slave_mode___width 3
+#define reg_bif_dma_rw_pin1_cfg_offset 164
+
+/* Register rw_pin2_cfg, scope bif_dma, type rw */
+#define reg_bif_dma_rw_pin2_cfg___master_ch___lsb 0
+#define reg_bif_dma_rw_pin2_cfg___master_ch___width 2
+#define reg_bif_dma_rw_pin2_cfg___master_mode___lsb 2
+#define reg_bif_dma_rw_pin2_cfg___master_mode___width 3
+#define reg_bif_dma_rw_pin2_cfg___slave_ch___lsb 5
+#define reg_bif_dma_rw_pin2_cfg___slave_ch___width 2
+#define reg_bif_dma_rw_pin2_cfg___slave_mode___lsb 7
+#define reg_bif_dma_rw_pin2_cfg___slave_mode___width 3
+#define reg_bif_dma_rw_pin2_cfg_offset 168
+
+/* Register rw_pin3_cfg, scope bif_dma, type rw */
+#define reg_bif_dma_rw_pin3_cfg___master_ch___lsb 0
+#define reg_bif_dma_rw_pin3_cfg___master_ch___width 2
+#define reg_bif_dma_rw_pin3_cfg___master_mode___lsb 2
+#define reg_bif_dma_rw_pin3_cfg___master_mode___width 3
+#define reg_bif_dma_rw_pin3_cfg___slave_ch___lsb 5
+#define reg_bif_dma_rw_pin3_cfg___slave_ch___width 2
+#define reg_bif_dma_rw_pin3_cfg___slave_mode___lsb 7
+#define reg_bif_dma_rw_pin3_cfg___slave_mode___width 3
+#define reg_bif_dma_rw_pin3_cfg_offset 172
+
+/* Register rw_pin4_cfg, scope bif_dma, type rw */
+#define reg_bif_dma_rw_pin4_cfg___master_ch___lsb 0
+#define reg_bif_dma_rw_pin4_cfg___master_ch___width 2
+#define reg_bif_dma_rw_pin4_cfg___master_mode___lsb 2
+#define reg_bif_dma_rw_pin4_cfg___master_mode___width 3
+#define reg_bif_dma_rw_pin4_cfg___slave_ch___lsb 5
+#define reg_bif_dma_rw_pin4_cfg___slave_ch___width 2
+#define reg_bif_dma_rw_pin4_cfg___slave_mode___lsb 7
+#define reg_bif_dma_rw_pin4_cfg___slave_mode___width 3
+#define reg_bif_dma_rw_pin4_cfg_offset 176
+
+/* Register rw_pin5_cfg, scope bif_dma, type rw */
+#define reg_bif_dma_rw_pin5_cfg___master_ch___lsb 0
+#define reg_bif_dma_rw_pin5_cfg___master_ch___width 2
+#define reg_bif_dma_rw_pin5_cfg___master_mode___lsb 2
+#define reg_bif_dma_rw_pin5_cfg___master_mode___width 3
+#define reg_bif_dma_rw_pin5_cfg___slave_ch___lsb 5
+#define reg_bif_dma_rw_pin5_cfg___slave_ch___width 2
+#define reg_bif_dma_rw_pin5_cfg___slave_mode___lsb 7
+#define reg_bif_dma_rw_pin5_cfg___slave_mode___width 3
+#define reg_bif_dma_rw_pin5_cfg_offset 180
+
+/* Register rw_pin6_cfg, scope bif_dma, type rw */
+#define reg_bif_dma_rw_pin6_cfg___master_ch___lsb 0
+#define reg_bif_dma_rw_pin6_cfg___master_ch___width 2
+#define reg_bif_dma_rw_pin6_cfg___master_mode___lsb 2
+#define reg_bif_dma_rw_pin6_cfg___master_mode___width 3
+#define reg_bif_dma_rw_pin6_cfg___slave_ch___lsb 5
+#define reg_bif_dma_rw_pin6_cfg___slave_ch___width 2
+#define reg_bif_dma_rw_pin6_cfg___slave_mode___lsb 7
+#define reg_bif_dma_rw_pin6_cfg___slave_mode___width 3
+#define reg_bif_dma_rw_pin6_cfg_offset 184
+
+/* Register rw_pin7_cfg, scope bif_dma, type rw */
+#define reg_bif_dma_rw_pin7_cfg___master_ch___lsb 0
+#define reg_bif_dma_rw_pin7_cfg___master_ch___width 2
+#define reg_bif_dma_rw_pin7_cfg___master_mode___lsb 2
+#define reg_bif_dma_rw_pin7_cfg___master_mode___width 3
+#define reg_bif_dma_rw_pin7_cfg___slave_ch___lsb 5
+#define reg_bif_dma_rw_pin7_cfg___slave_ch___width 2
+#define reg_bif_dma_rw_pin7_cfg___slave_mode___lsb 7
+#define reg_bif_dma_rw_pin7_cfg___slave_mode___width 3
+#define reg_bif_dma_rw_pin7_cfg_offset 188
+
+/* Register r_pin_stat, scope bif_dma, type r */
+#define reg_bif_dma_r_pin_stat___pin0___lsb 0
+#define reg_bif_dma_r_pin_stat___pin0___width 1
+#define reg_bif_dma_r_pin_stat___pin0___bit 0
+#define reg_bif_dma_r_pin_stat___pin1___lsb 1
+#define reg_bif_dma_r_pin_stat___pin1___width 1
+#define reg_bif_dma_r_pin_stat___pin1___bit 1
+#define reg_bif_dma_r_pin_stat___pin2___lsb 2
+#define reg_bif_dma_r_pin_stat___pin2___width 1
+#define reg_bif_dma_r_pin_stat___pin2___bit 2
+#define reg_bif_dma_r_pin_stat___pin3___lsb 3
+#define reg_bif_dma_r_pin_stat___pin3___width 1
+#define reg_bif_dma_r_pin_stat___pin3___bit 3
+#define reg_bif_dma_r_pin_stat___pin4___lsb 4
+#define reg_bif_dma_r_pin_stat___pin4___width 1
+#define reg_bif_dma_r_pin_stat___pin4___bit 4
+#define reg_bif_dma_r_pin_stat___pin5___lsb 5
+#define reg_bif_dma_r_pin_stat___pin5___width 1
+#define reg_bif_dma_r_pin_stat___pin5___bit 5
+#define reg_bif_dma_r_pin_stat___pin6___lsb 6
+#define reg_bif_dma_r_pin_stat___pin6___width 1
+#define reg_bif_dma_r_pin_stat___pin6___bit 6
+#define reg_bif_dma_r_pin_stat___pin7___lsb 7
+#define reg_bif_dma_r_pin_stat___pin7___width 1
+#define reg_bif_dma_r_pin_stat___pin7___bit 7
+#define reg_bif_dma_r_pin_stat_offset 192
+
+
+/* Constants */
+#define regk_bif_dma_as_master                    0x00000001
+#define regk_bif_dma_as_slave                     0x00000001
+#define regk_bif_dma_burst1                       0x00000000
+#define regk_bif_dma_burst8                       0x00000001
+#define regk_bif_dma_bw16                         0x00000001
+#define regk_bif_dma_bw32                         0x00000002
+#define regk_bif_dma_bw8                          0x00000000
+#define regk_bif_dma_dack                         0x00000006
+#define regk_bif_dma_dack_inv                     0x00000007
+#define regk_bif_dma_force                        0x00000001
+#define regk_bif_dma_hi                           0x00000003
+#define regk_bif_dma_inv                          0x00000003
+#define regk_bif_dma_lo                           0x00000002
+#define regk_bif_dma_master                       0x00000001
+#define regk_bif_dma_no                           0x00000000
+#define regk_bif_dma_norm                         0x00000002
+#define regk_bif_dma_off                          0x00000000
+#define regk_bif_dma_rw_ch0_ctrl_default          0x00000000
+#define regk_bif_dma_rw_ch0_start_default         0x00000000
+#define regk_bif_dma_rw_ch1_ctrl_default          0x00000000
+#define regk_bif_dma_rw_ch1_start_default         0x00000000
+#define regk_bif_dma_rw_ch2_ctrl_default          0x00000000
+#define regk_bif_dma_rw_ch2_start_default         0x00000000
+#define regk_bif_dma_rw_ch3_ctrl_default          0x00000000
+#define regk_bif_dma_rw_ch3_start_default         0x00000000
+#define regk_bif_dma_rw_intr_mask_default         0x00000000
+#define regk_bif_dma_rw_pin0_cfg_default          0x00000000
+#define regk_bif_dma_rw_pin1_cfg_default          0x00000000
+#define regk_bif_dma_rw_pin2_cfg_default          0x00000000
+#define regk_bif_dma_rw_pin3_cfg_default          0x00000000
+#define regk_bif_dma_rw_pin4_cfg_default          0x00000000
+#define regk_bif_dma_rw_pin5_cfg_default          0x00000000
+#define regk_bif_dma_rw_pin6_cfg_default          0x00000000
+#define regk_bif_dma_rw_pin7_cfg_default          0x00000000
+#define regk_bif_dma_slave                        0x00000002
+#define regk_bif_dma_sreq                         0x00000006
+#define regk_bif_dma_sreq_inv                     0x00000007
+#define regk_bif_dma_tc                           0x00000004
+#define regk_bif_dma_tc_inv                       0x00000005
+#define regk_bif_dma_yes                          0x00000001
+#endif /* __bif_dma_defs_asm_h */
diff --git a/include/asm-cris/arch-v32/hwregs/asm/bif_slave_defs_asm.h b/include/asm-cris/arch-v32/hwregs/asm/bif_slave_defs_asm.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/asm/bif_slave_defs_asm.h
@@ -0,0 +1,249 @@
+#ifndef __bif_slave_defs_asm_h
+#define __bif_slave_defs_asm_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/bif/rtl/bif_slave_regs.r
+ *     id:           bif_slave_regs.r,v 1.5 2005/02/04 13:55:28 perz Exp
+ *     last modfied: Mon Apr 11 16:06:34 2005
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c -asm --outfile asm/bif_slave_defs_asm.h ../../inst/bif/rtl/bif_slave_regs.r
+ *      id: $Id: bif_slave_defs_asm.h,v 1.1 2005/04/24 18:31:04 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+
+#ifndef REG_FIELD
+#define REG_FIELD( scope, reg, field, value ) \
+  REG_FIELD_X_( value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_FIELD_X_( value, shift ) ((value) << shift)
+#endif
+
+#ifndef REG_STATE
+#define REG_STATE( scope, reg, field, symbolic_value ) \
+  REG_STATE_X_( regk_##scope##_##symbolic_value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_STATE_X_( k, shift ) (k << shift)
+#endif
+
+#ifndef REG_MASK
+#define REG_MASK( scope, reg, field ) \
+  REG_MASK_X_( reg_##scope##_##reg##___##field##___width, reg_##scope##_##reg##___##field##___lsb )
+#define REG_MASK_X_( width, lsb ) (((1 << width)-1) << lsb)
+#endif
+
+#ifndef REG_LSB
+#define REG_LSB( scope, reg, field ) reg_##scope##_##reg##___##field##___lsb
+#endif
+
+#ifndef REG_BIT
+#define REG_BIT( scope, reg, field ) reg_##scope##_##reg##___##field##___bit
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) REG_ADDR_X_(inst, reg_##scope##_##reg##_offset)
+#define REG_ADDR_X_( inst, offs ) ((inst) + offs)
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+         REG_ADDR_VECT_X_(inst, reg_##scope##_##reg##_offset, index, \
+			 STRIDE_##scope##_##reg )
+#define REG_ADDR_VECT_X_( inst, offs, index, stride ) \
+                          ((inst) + offs + (index) * stride)
+#endif
+
+/* Register rw_slave_cfg, scope bif_slave, type rw */
+#define reg_bif_slave_rw_slave_cfg___slave_id___lsb 0
+#define reg_bif_slave_rw_slave_cfg___slave_id___width 3
+#define reg_bif_slave_rw_slave_cfg___use_slave_id___lsb 3
+#define reg_bif_slave_rw_slave_cfg___use_slave_id___width 1
+#define reg_bif_slave_rw_slave_cfg___use_slave_id___bit 3
+#define reg_bif_slave_rw_slave_cfg___boot_rdy___lsb 4
+#define reg_bif_slave_rw_slave_cfg___boot_rdy___width 1
+#define reg_bif_slave_rw_slave_cfg___boot_rdy___bit 4
+#define reg_bif_slave_rw_slave_cfg___loopback___lsb 5
+#define reg_bif_slave_rw_slave_cfg___loopback___width 1
+#define reg_bif_slave_rw_slave_cfg___loopback___bit 5
+#define reg_bif_slave_rw_slave_cfg___dis___lsb 6
+#define reg_bif_slave_rw_slave_cfg___dis___width 1
+#define reg_bif_slave_rw_slave_cfg___dis___bit 6
+#define reg_bif_slave_rw_slave_cfg_offset 0
+
+/* Register r_slave_mode, scope bif_slave, type r */
+#define reg_bif_slave_r_slave_mode___ch0_mode___lsb 0
+#define reg_bif_slave_r_slave_mode___ch0_mode___width 1
+#define reg_bif_slave_r_slave_mode___ch0_mode___bit 0
+#define reg_bif_slave_r_slave_mode___ch1_mode___lsb 1
+#define reg_bif_slave_r_slave_mode___ch1_mode___width 1
+#define reg_bif_slave_r_slave_mode___ch1_mode___bit 1
+#define reg_bif_slave_r_slave_mode___ch2_mode___lsb 2
+#define reg_bif_slave_r_slave_mode___ch2_mode___width 1
+#define reg_bif_slave_r_slave_mode___ch2_mode___bit 2
+#define reg_bif_slave_r_slave_mode___ch3_mode___lsb 3
+#define reg_bif_slave_r_slave_mode___ch3_mode___width 1
+#define reg_bif_slave_r_slave_mode___ch3_mode___bit 3
+#define reg_bif_slave_r_slave_mode_offset 4
+
+/* Register rw_ch0_cfg, scope bif_slave, type rw */
+#define reg_bif_slave_rw_ch0_cfg___rd_hold___lsb 0
+#define reg_bif_slave_rw_ch0_cfg___rd_hold___width 2
+#define reg_bif_slave_rw_ch0_cfg___access_mode___lsb 2
+#define reg_bif_slave_rw_ch0_cfg___access_mode___width 1
+#define reg_bif_slave_rw_ch0_cfg___access_mode___bit 2
+#define reg_bif_slave_rw_ch0_cfg___access_ctrl___lsb 3
+#define reg_bif_slave_rw_ch0_cfg___access_ctrl___width 1
+#define reg_bif_slave_rw_ch0_cfg___access_ctrl___bit 3
+#define reg_bif_slave_rw_ch0_cfg___data_cs___lsb 4
+#define reg_bif_slave_rw_ch0_cfg___data_cs___width 2
+#define reg_bif_slave_rw_ch0_cfg_offset 16
+
+/* Register rw_ch1_cfg, scope bif_slave, type rw */
+#define reg_bif_slave_rw_ch1_cfg___rd_hold___lsb 0
+#define reg_bif_slave_rw_ch1_cfg___rd_hold___width 2
+#define reg_bif_slave_rw_ch1_cfg___access_mode___lsb 2
+#define reg_bif_slave_rw_ch1_cfg___access_mode___width 1
+#define reg_bif_slave_rw_ch1_cfg___access_mode___bit 2
+#define reg_bif_slave_rw_ch1_cfg___access_ctrl___lsb 3
+#define reg_bif_slave_rw_ch1_cfg___access_ctrl___width 1
+#define reg_bif_slave_rw_ch1_cfg___access_ctrl___bit 3
+#define reg_bif_slave_rw_ch1_cfg___data_cs___lsb 4
+#define reg_bif_slave_rw_ch1_cfg___data_cs___width 2
+#define reg_bif_slave_rw_ch1_cfg_offset 20
+
+/* Register rw_ch2_cfg, scope bif_slave, type rw */
+#define reg_bif_slave_rw_ch2_cfg___rd_hold___lsb 0
+#define reg_bif_slave_rw_ch2_cfg___rd_hold___width 2
+#define reg_bif_slave_rw_ch2_cfg___access_mode___lsb 2
+#define reg_bif_slave_rw_ch2_cfg___access_mode___width 1
+#define reg_bif_slave_rw_ch2_cfg___access_mode___bit 2
+#define reg_bif_slave_rw_ch2_cfg___access_ctrl___lsb 3
+#define reg_bif_slave_rw_ch2_cfg___access_ctrl___width 1
+#define reg_bif_slave_rw_ch2_cfg___access_ctrl___bit 3
+#define reg_bif_slave_rw_ch2_cfg___data_cs___lsb 4
+#define reg_bif_slave_rw_ch2_cfg___data_cs___width 2
+#define reg_bif_slave_rw_ch2_cfg_offset 24
+
+/* Register rw_ch3_cfg, scope bif_slave, type rw */
+#define reg_bif_slave_rw_ch3_cfg___rd_hold___lsb 0
+#define reg_bif_slave_rw_ch3_cfg___rd_hold___width 2
+#define reg_bif_slave_rw_ch3_cfg___access_mode___lsb 2
+#define reg_bif_slave_rw_ch3_cfg___access_mode___width 1
+#define reg_bif_slave_rw_ch3_cfg___access_mode___bit 2
+#define reg_bif_slave_rw_ch3_cfg___access_ctrl___lsb 3
+#define reg_bif_slave_rw_ch3_cfg___access_ctrl___width 1
+#define reg_bif_slave_rw_ch3_cfg___access_ctrl___bit 3
+#define reg_bif_slave_rw_ch3_cfg___data_cs___lsb 4
+#define reg_bif_slave_rw_ch3_cfg___data_cs___width 2
+#define reg_bif_slave_rw_ch3_cfg_offset 28
+
+/* Register rw_arb_cfg, scope bif_slave, type rw */
+#define reg_bif_slave_rw_arb_cfg___brin_mode___lsb 0
+#define reg_bif_slave_rw_arb_cfg___brin_mode___width 1
+#define reg_bif_slave_rw_arb_cfg___brin_mode___bit 0
+#define reg_bif_slave_rw_arb_cfg___brout_mode___lsb 1
+#define reg_bif_slave_rw_arb_cfg___brout_mode___width 3
+#define reg_bif_slave_rw_arb_cfg___bg_mode___lsb 4
+#define reg_bif_slave_rw_arb_cfg___bg_mode___width 3
+#define reg_bif_slave_rw_arb_cfg___release___lsb 7
+#define reg_bif_slave_rw_arb_cfg___release___width 2
+#define reg_bif_slave_rw_arb_cfg___acquire___lsb 9
+#define reg_bif_slave_rw_arb_cfg___acquire___width 1
+#define reg_bif_slave_rw_arb_cfg___acquire___bit 9
+#define reg_bif_slave_rw_arb_cfg___settle_time___lsb 10
+#define reg_bif_slave_rw_arb_cfg___settle_time___width 2
+#define reg_bif_slave_rw_arb_cfg___dram_ctrl___lsb 12
+#define reg_bif_slave_rw_arb_cfg___dram_ctrl___width 1
+#define reg_bif_slave_rw_arb_cfg___dram_ctrl___bit 12
+#define reg_bif_slave_rw_arb_cfg_offset 32
+
+/* Register r_arb_stat, scope bif_slave, type r */
+#define reg_bif_slave_r_arb_stat___init_mode___lsb 0
+#define reg_bif_slave_r_arb_stat___init_mode___width 1
+#define reg_bif_slave_r_arb_stat___init_mode___bit 0
+#define reg_bif_slave_r_arb_stat___mode___lsb 1
+#define reg_bif_slave_r_arb_stat___mode___width 1
+#define reg_bif_slave_r_arb_stat___mode___bit 1
+#define reg_bif_slave_r_arb_stat___brin___lsb 2
+#define reg_bif_slave_r_arb_stat___brin___width 1
+#define reg_bif_slave_r_arb_stat___brin___bit 2
+#define reg_bif_slave_r_arb_stat___brout___lsb 3
+#define reg_bif_slave_r_arb_stat___brout___width 1
+#define reg_bif_slave_r_arb_stat___brout___bit 3
+#define reg_bif_slave_r_arb_stat___bg___lsb 4
+#define reg_bif_slave_r_arb_stat___bg___width 1
+#define reg_bif_slave_r_arb_stat___bg___bit 4
+#define reg_bif_slave_r_arb_stat_offset 36
+
+/* Register rw_intr_mask, scope bif_slave, type rw */
+#define reg_bif_slave_rw_intr_mask___bus_release___lsb 0
+#define reg_bif_slave_rw_intr_mask___bus_release___width 1
+#define reg_bif_slave_rw_intr_mask___bus_release___bit 0
+#define reg_bif_slave_rw_intr_mask___bus_acquire___lsb 1
+#define reg_bif_slave_rw_intr_mask___bus_acquire___width 1
+#define reg_bif_slave_rw_intr_mask___bus_acquire___bit 1
+#define reg_bif_slave_rw_intr_mask_offset 64
+
+/* Register rw_ack_intr, scope bif_slave, type rw */
+#define reg_bif_slave_rw_ack_intr___bus_release___lsb 0
+#define reg_bif_slave_rw_ack_intr___bus_release___width 1
+#define reg_bif_slave_rw_ack_intr___bus_release___bit 0
+#define reg_bif_slave_rw_ack_intr___bus_acquire___lsb 1
+#define reg_bif_slave_rw_ack_intr___bus_acquire___width 1
+#define reg_bif_slave_rw_ack_intr___bus_acquire___bit 1
+#define reg_bif_slave_rw_ack_intr_offset 68
+
+/* Register r_intr, scope bif_slave, type r */
+#define reg_bif_slave_r_intr___bus_release___lsb 0
+#define reg_bif_slave_r_intr___bus_release___width 1
+#define reg_bif_slave_r_intr___bus_release___bit 0
+#define reg_bif_slave_r_intr___bus_acquire___lsb 1
+#define reg_bif_slave_r_intr___bus_acquire___width 1
+#define reg_bif_slave_r_intr___bus_acquire___bit 1
+#define reg_bif_slave_r_intr_offset 72
+
+/* Register r_masked_intr, scope bif_slave, type r */
+#define reg_bif_slave_r_masked_intr___bus_release___lsb 0
+#define reg_bif_slave_r_masked_intr___bus_release___width 1
+#define reg_bif_slave_r_masked_intr___bus_release___bit 0
+#define reg_bif_slave_r_masked_intr___bus_acquire___lsb 1
+#define reg_bif_slave_r_masked_intr___bus_acquire___width 1
+#define reg_bif_slave_r_masked_intr___bus_acquire___bit 1
+#define reg_bif_slave_r_masked_intr_offset 76
+
+
+/* Constants */
+#define regk_bif_slave_active_hi                  0x00000003
+#define regk_bif_slave_active_lo                  0x00000002
+#define regk_bif_slave_addr                       0x00000000
+#define regk_bif_slave_always                     0x00000001
+#define regk_bif_slave_at_idle                    0x00000002
+#define regk_bif_slave_burst_end                  0x00000003
+#define regk_bif_slave_dma                        0x00000001
+#define regk_bif_slave_hi                         0x00000003
+#define regk_bif_slave_inv                        0x00000001
+#define regk_bif_slave_lo                         0x00000002
+#define regk_bif_slave_local                      0x00000001
+#define regk_bif_slave_master                     0x00000000
+#define regk_bif_slave_mode_reg                   0x00000001
+#define regk_bif_slave_no                         0x00000000
+#define regk_bif_slave_norm                       0x00000000
+#define regk_bif_slave_on_access                  0x00000000
+#define regk_bif_slave_rw_arb_cfg_default         0x00000000
+#define regk_bif_slave_rw_ch0_cfg_default         0x00000000
+#define regk_bif_slave_rw_ch1_cfg_default         0x00000000
+#define regk_bif_slave_rw_ch2_cfg_default         0x00000000
+#define regk_bif_slave_rw_ch3_cfg_default         0x00000000
+#define regk_bif_slave_rw_intr_mask_default       0x00000000
+#define regk_bif_slave_rw_slave_cfg_default       0x00000000
+#define regk_bif_slave_shared                     0x00000000
+#define regk_bif_slave_slave                      0x00000001
+#define regk_bif_slave_t0ns                       0x00000003
+#define regk_bif_slave_t10ns                      0x00000002
+#define regk_bif_slave_t20ns                      0x00000003
+#define regk_bif_slave_t30ns                      0x00000002
+#define regk_bif_slave_t40ns                      0x00000001
+#define regk_bif_slave_t50ns                      0x00000000
+#define regk_bif_slave_yes                        0x00000001
+#define regk_bif_slave_z                          0x00000004
+#endif /* __bif_slave_defs_asm_h */
diff --git a/include/asm-cris/arch-v32/hwregs/asm/config_defs_asm.h b/include/asm-cris/arch-v32/hwregs/asm/config_defs_asm.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/asm/config_defs_asm.h
@@ -0,0 +1,131 @@
+#ifndef __config_defs_asm_h
+#define __config_defs_asm_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../rtl/config_regs.r
+ *     id:           config_regs.r,v 1.23 2004/03/04 11:34:42 mikaeln Exp
+ *     last modfied: Thu Mar  4 12:34:39 2004
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c -asm --outfile asm/config_defs_asm.h ../../rtl/config_regs.r
+ *      id: $Id: config_defs_asm.h,v 1.1 2005/04/24 18:31:04 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+
+#ifndef REG_FIELD
+#define REG_FIELD( scope, reg, field, value ) \
+  REG_FIELD_X_( value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_FIELD_X_( value, shift ) ((value) << shift)
+#endif
+
+#ifndef REG_STATE
+#define REG_STATE( scope, reg, field, symbolic_value ) \
+  REG_STATE_X_( regk_##scope##_##symbolic_value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_STATE_X_( k, shift ) (k << shift)
+#endif
+
+#ifndef REG_MASK
+#define REG_MASK( scope, reg, field ) \
+  REG_MASK_X_( reg_##scope##_##reg##___##field##___width, reg_##scope##_##reg##___##field##___lsb )
+#define REG_MASK_X_( width, lsb ) (((1 << width)-1) << lsb)
+#endif
+
+#ifndef REG_LSB
+#define REG_LSB( scope, reg, field ) reg_##scope##_##reg##___##field##___lsb
+#endif
+
+#ifndef REG_BIT
+#define REG_BIT( scope, reg, field ) reg_##scope##_##reg##___##field##___bit
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) REG_ADDR_X_(inst, reg_##scope##_##reg##_offset)
+#define REG_ADDR_X_( inst, offs ) ((inst) + offs)
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+         REG_ADDR_VECT_X_(inst, reg_##scope##_##reg##_offset, index, \
+			 STRIDE_##scope##_##reg )
+#define REG_ADDR_VECT_X_( inst, offs, index, stride ) \
+                          ((inst) + offs + (index) * stride)
+#endif
+
+/* Register r_bootsel, scope config, type r */
+#define reg_config_r_bootsel___boot_mode___lsb 0
+#define reg_config_r_bootsel___boot_mode___width 3
+#define reg_config_r_bootsel___full_duplex___lsb 3
+#define reg_config_r_bootsel___full_duplex___width 1
+#define reg_config_r_bootsel___full_duplex___bit 3
+#define reg_config_r_bootsel___user___lsb 4
+#define reg_config_r_bootsel___user___width 1
+#define reg_config_r_bootsel___user___bit 4
+#define reg_config_r_bootsel___pll___lsb 5
+#define reg_config_r_bootsel___pll___width 1
+#define reg_config_r_bootsel___pll___bit 5
+#define reg_config_r_bootsel___flash_bw___lsb 6
+#define reg_config_r_bootsel___flash_bw___width 1
+#define reg_config_r_bootsel___flash_bw___bit 6
+#define reg_config_r_bootsel_offset 0
+
+/* Register rw_clk_ctrl, scope config, type rw */
+#define reg_config_rw_clk_ctrl___pll___lsb 0
+#define reg_config_rw_clk_ctrl___pll___width 1
+#define reg_config_rw_clk_ctrl___pll___bit 0
+#define reg_config_rw_clk_ctrl___cpu___lsb 1
+#define reg_config_rw_clk_ctrl___cpu___width 1
+#define reg_config_rw_clk_ctrl___cpu___bit 1
+#define reg_config_rw_clk_ctrl___iop___lsb 2
+#define reg_config_rw_clk_ctrl___iop___width 1
+#define reg_config_rw_clk_ctrl___iop___bit 2
+#define reg_config_rw_clk_ctrl___dma01_eth0___lsb 3
+#define reg_config_rw_clk_ctrl___dma01_eth0___width 1
+#define reg_config_rw_clk_ctrl___dma01_eth0___bit 3
+#define reg_config_rw_clk_ctrl___dma23___lsb 4
+#define reg_config_rw_clk_ctrl___dma23___width 1
+#define reg_config_rw_clk_ctrl___dma23___bit 4
+#define reg_config_rw_clk_ctrl___dma45___lsb 5
+#define reg_config_rw_clk_ctrl___dma45___width 1
+#define reg_config_rw_clk_ctrl___dma45___bit 5
+#define reg_config_rw_clk_ctrl___dma67___lsb 6
+#define reg_config_rw_clk_ctrl___dma67___width 1
+#define reg_config_rw_clk_ctrl___dma67___bit 6
+#define reg_config_rw_clk_ctrl___dma89_strcop___lsb 7
+#define reg_config_rw_clk_ctrl___dma89_strcop___width 1
+#define reg_config_rw_clk_ctrl___dma89_strcop___bit 7
+#define reg_config_rw_clk_ctrl___bif___lsb 8
+#define reg_config_rw_clk_ctrl___bif___width 1
+#define reg_config_rw_clk_ctrl___bif___bit 8
+#define reg_config_rw_clk_ctrl___fix_io___lsb 9
+#define reg_config_rw_clk_ctrl___fix_io___width 1
+#define reg_config_rw_clk_ctrl___fix_io___bit 9
+#define reg_config_rw_clk_ctrl_offset 4
+
+/* Register rw_pad_ctrl, scope config, type rw */
+#define reg_config_rw_pad_ctrl___usb_susp___lsb 0
+#define reg_config_rw_pad_ctrl___usb_susp___width 1
+#define reg_config_rw_pad_ctrl___usb_susp___bit 0
+#define reg_config_rw_pad_ctrl___phyrst_n___lsb 1
+#define reg_config_rw_pad_ctrl___phyrst_n___width 1
+#define reg_config_rw_pad_ctrl___phyrst_n___bit 1
+#define reg_config_rw_pad_ctrl_offset 8
+
+
+/* Constants */
+#define regk_config_bw16                          0x00000000
+#define regk_config_bw32                          0x00000001
+#define regk_config_master                        0x00000005
+#define regk_config_nand                          0x00000003
+#define regk_config_net_rx                        0x00000001
+#define regk_config_net_tx_rx                     0x00000002
+#define regk_config_no                            0x00000000
+#define regk_config_none                          0x00000007
+#define regk_config_nor                           0x00000000
+#define regk_config_rw_clk_ctrl_default           0x00000002
+#define regk_config_rw_pad_ctrl_default           0x00000000
+#define regk_config_ser                           0x00000004
+#define regk_config_slave                         0x00000006
+#define regk_config_yes                           0x00000001
+#endif /* __config_defs_asm_h */
diff --git a/include/asm-cris/arch-v32/hwregs/asm/cpu_vect.h b/include/asm-cris/arch-v32/hwregs/asm/cpu_vect.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/asm/cpu_vect.h
@@ -0,0 +1,41 @@
+/* Interrupt vector numbers autogenerated by /n/asic/design/tools/rdesc/src/rdes2intr version
+ from ../../inst/crisp/doc/cpu_vect.r
+version . */
+
+#ifndef _______INST_CRISP_DOC_CPU_VECT_R
+#define _______INST_CRISP_DOC_CPU_VECT_R
+#define NMI_INTR_VECT	0x00
+#define RESERVED_1_INTR_VECT	0x01
+#define RESERVED_2_INTR_VECT	0x02
+#define SINGLE_STEP_INTR_VECT	0x03
+#define INSTR_TLB_REFILL_INTR_VECT	0x04
+#define INSTR_TLB_INV_INTR_VECT	0x05
+#define INSTR_TLB_ACC_INTR_VECT	0x06
+#define TLB_EX_INTR_VECT	0x07
+#define DATA_TLB_REFILL_INTR_VECT	0x08
+#define DATA_TLB_INV_INTR_VECT	0x09
+#define DATA_TLB_ACC_INTR_VECT	0x0a
+#define DATA_TLB_WE_INTR_VECT	0x0b
+#define HW_BP_INTR_VECT	0x0c
+#define RESERVED_D_INTR_VECT	0x0d
+#define RESERVED_E_INTR_VECT	0x0e
+#define RESERVED_F_INTR_VECT	0x0f
+#define BREAK_0_INTR_VECT	0x10
+#define BREAK_1_INTR_VECT	0x11
+#define BREAK_2_INTR_VECT	0x12
+#define BREAK_3_INTR_VECT	0x13
+#define BREAK_4_INTR_VECT	0x14
+#define BREAK_5_INTR_VECT	0x15
+#define BREAK_6_INTR_VECT	0x16
+#define BREAK_7_INTR_VECT	0x17
+#define BREAK_8_INTR_VECT	0x18
+#define BREAK_9_INTR_VECT	0x19
+#define BREAK_10_INTR_VECT	0x1a
+#define BREAK_11_INTR_VECT	0x1b
+#define BREAK_12_INTR_VECT	0x1c
+#define BREAK_13_INTR_VECT	0x1d
+#define BREAK_14_INTR_VECT	0x1e
+#define BREAK_15_INTR_VECT	0x1f
+#define MULTIPLE_INTR_VECT	0x30
+
+#endif
diff --git a/include/asm-cris/arch-v32/hwregs/asm/cris_defs_asm.h b/include/asm-cris/arch-v32/hwregs/asm/cris_defs_asm.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/asm/cris_defs_asm.h
@@ -0,0 +1,114 @@
+#ifndef __cris_defs_asm_h
+#define __cris_defs_asm_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/crisp/doc/cris.r
+ *     id:           cris.r,v 1.6 2004/05/05 07:41:12 perz Exp
+ *     last modfied: Mon Apr 11 16:06:39 2005
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c -asm --outfile asm/cris_defs_asm.h ../../inst/crisp/doc/cris.r
+ *      id: $Id: cris_defs_asm.h,v 1.1 2005/04/24 18:31:04 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+
+#ifndef REG_FIELD
+#define REG_FIELD( scope, reg, field, value ) \
+  REG_FIELD_X_( value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_FIELD_X_( value, shift ) ((value) << shift)
+#endif
+
+#ifndef REG_STATE
+#define REG_STATE( scope, reg, field, symbolic_value ) \
+  REG_STATE_X_( regk_##scope##_##symbolic_value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_STATE_X_( k, shift ) (k << shift)
+#endif
+
+#ifndef REG_MASK
+#define REG_MASK( scope, reg, field ) \
+  REG_MASK_X_( reg_##scope##_##reg##___##field##___width, reg_##scope##_##reg##___##field##___lsb )
+#define REG_MASK_X_( width, lsb ) (((1 << width)-1) << lsb)
+#endif
+
+#ifndef REG_LSB
+#define REG_LSB( scope, reg, field ) reg_##scope##_##reg##___##field##___lsb
+#endif
+
+#ifndef REG_BIT
+#define REG_BIT( scope, reg, field ) reg_##scope##_##reg##___##field##___bit
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) REG_ADDR_X_(inst, reg_##scope##_##reg##_offset)
+#define REG_ADDR_X_( inst, offs ) ((inst) + offs)
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+         REG_ADDR_VECT_X_(inst, reg_##scope##_##reg##_offset, index, \
+			 STRIDE_##scope##_##reg )
+#define REG_ADDR_VECT_X_( inst, offs, index, stride ) \
+                          ((inst) + offs + (index) * stride)
+#endif
+
+/* Register rw_gc_cfg, scope cris, type rw */
+#define reg_cris_rw_gc_cfg___ic___lsb 0
+#define reg_cris_rw_gc_cfg___ic___width 1
+#define reg_cris_rw_gc_cfg___ic___bit 0
+#define reg_cris_rw_gc_cfg___dc___lsb 1
+#define reg_cris_rw_gc_cfg___dc___width 1
+#define reg_cris_rw_gc_cfg___dc___bit 1
+#define reg_cris_rw_gc_cfg___im___lsb 2
+#define reg_cris_rw_gc_cfg___im___width 1
+#define reg_cris_rw_gc_cfg___im___bit 2
+#define reg_cris_rw_gc_cfg___dm___lsb 3
+#define reg_cris_rw_gc_cfg___dm___width 1
+#define reg_cris_rw_gc_cfg___dm___bit 3
+#define reg_cris_rw_gc_cfg___gb___lsb 4
+#define reg_cris_rw_gc_cfg___gb___width 1
+#define reg_cris_rw_gc_cfg___gb___bit 4
+#define reg_cris_rw_gc_cfg___gk___lsb 5
+#define reg_cris_rw_gc_cfg___gk___width 1
+#define reg_cris_rw_gc_cfg___gk___bit 5
+#define reg_cris_rw_gc_cfg___gp___lsb 6
+#define reg_cris_rw_gc_cfg___gp___width 1
+#define reg_cris_rw_gc_cfg___gp___bit 6
+#define reg_cris_rw_gc_cfg_offset 0
+
+/* Register rw_gc_ccs, scope cris, type rw */
+#define reg_cris_rw_gc_ccs_offset 4
+
+/* Register rw_gc_srs, scope cris, type rw */
+#define reg_cris_rw_gc_srs___srs___lsb 0
+#define reg_cris_rw_gc_srs___srs___width 8
+#define reg_cris_rw_gc_srs_offset 8
+
+/* Register rw_gc_nrp, scope cris, type rw */
+#define reg_cris_rw_gc_nrp_offset 12
+
+/* Register rw_gc_exs, scope cris, type rw */
+#define reg_cris_rw_gc_exs_offset 16
+
+/* Register rw_gc_eda, scope cris, type rw */
+#define reg_cris_rw_gc_eda_offset 20
+
+/* Register rw_gc_r0, scope cris, type rw */
+#define reg_cris_rw_gc_r0_offset 32
+
+/* Register rw_gc_r1, scope cris, type rw */
+#define reg_cris_rw_gc_r1_offset 36
+
+/* Register rw_gc_r2, scope cris, type rw */
+#define reg_cris_rw_gc_r2_offset 40
+
+/* Register rw_gc_r3, scope cris, type rw */
+#define reg_cris_rw_gc_r3_offset 44
+
+
+/* Constants */
+#define regk_cris_no                              0x00000000
+#define regk_cris_rw_gc_cfg_default               0x00000000
+#define regk_cris_yes                             0x00000001
+#endif /* __cris_defs_asm_h */
diff --git a/include/asm-cris/arch-v32/hwregs/asm/cris_supp_reg.h b/include/asm-cris/arch-v32/hwregs/asm/cris_supp_reg.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/asm/cris_supp_reg.h
@@ -0,0 +1,10 @@
+#define RW_GC_CFG	0
+#define RW_GC_CCS	1
+#define RW_GC_SRS	2
+#define RW_GC_NRP	3
+#define RW_GC_EXS	4
+#define RW_GC_EDA	5
+#define RW_GC_R0	8
+#define RW_GC_R1	9
+#define RW_GC_R2	10
+#define RW_GC_R3	11
diff --git a/include/asm-cris/arch-v32/hwregs/asm/dma_defs_asm.h b/include/asm-cris/arch-v32/hwregs/asm/dma_defs_asm.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/asm/dma_defs_asm.h
@@ -0,0 +1,368 @@
+#ifndef __dma_defs_asm_h
+#define __dma_defs_asm_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/dma/inst/dma_common/rtl/dma_regdes.r
+ *     id:           dma_regdes.r,v 1.39 2005/02/10 14:07:23 janb Exp
+ *     last modfied: Mon Apr 11 16:06:51 2005
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c -asm --outfile asm/dma_defs_asm.h ../../inst/dma/inst/dma_common/rtl/dma_regdes.r
+ *      id: $Id: dma_defs_asm.h,v 1.1 2005/04/24 18:31:04 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+
+#ifndef REG_FIELD
+#define REG_FIELD( scope, reg, field, value ) \
+  REG_FIELD_X_( value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_FIELD_X_( value, shift ) ((value) << shift)
+#endif
+
+#ifndef REG_STATE
+#define REG_STATE( scope, reg, field, symbolic_value ) \
+  REG_STATE_X_( regk_##scope##_##symbolic_value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_STATE_X_( k, shift ) (k << shift)
+#endif
+
+#ifndef REG_MASK
+#define REG_MASK( scope, reg, field ) \
+  REG_MASK_X_( reg_##scope##_##reg##___##field##___width, reg_##scope##_##reg##___##field##___lsb )
+#define REG_MASK_X_( width, lsb ) (((1 << width)-1) << lsb)
+#endif
+
+#ifndef REG_LSB
+#define REG_LSB( scope, reg, field ) reg_##scope##_##reg##___##field##___lsb
+#endif
+
+#ifndef REG_BIT
+#define REG_BIT( scope, reg, field ) reg_##scope##_##reg##___##field##___bit
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) REG_ADDR_X_(inst, reg_##scope##_##reg##_offset)
+#define REG_ADDR_X_( inst, offs ) ((inst) + offs)
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+         REG_ADDR_VECT_X_(inst, reg_##scope##_##reg##_offset, index, \
+			 STRIDE_##scope##_##reg )
+#define REG_ADDR_VECT_X_( inst, offs, index, stride ) \
+                          ((inst) + offs + (index) * stride)
+#endif
+
+/* Register rw_data, scope dma, type rw */
+#define reg_dma_rw_data_offset 0
+
+/* Register rw_data_next, scope dma, type rw */
+#define reg_dma_rw_data_next_offset 4
+
+/* Register rw_data_buf, scope dma, type rw */
+#define reg_dma_rw_data_buf_offset 8
+
+/* Register rw_data_ctrl, scope dma, type rw */
+#define reg_dma_rw_data_ctrl___eol___lsb 0
+#define reg_dma_rw_data_ctrl___eol___width 1
+#define reg_dma_rw_data_ctrl___eol___bit 0
+#define reg_dma_rw_data_ctrl___out_eop___lsb 3
+#define reg_dma_rw_data_ctrl___out_eop___width 1
+#define reg_dma_rw_data_ctrl___out_eop___bit 3
+#define reg_dma_rw_data_ctrl___intr___lsb 4
+#define reg_dma_rw_data_ctrl___intr___width 1
+#define reg_dma_rw_data_ctrl___intr___bit 4
+#define reg_dma_rw_data_ctrl___wait___lsb 5
+#define reg_dma_rw_data_ctrl___wait___width 1
+#define reg_dma_rw_data_ctrl___wait___bit 5
+#define reg_dma_rw_data_ctrl_offset 12
+
+/* Register rw_data_stat, scope dma, type rw */
+#define reg_dma_rw_data_stat___in_eop___lsb 3
+#define reg_dma_rw_data_stat___in_eop___width 1
+#define reg_dma_rw_data_stat___in_eop___bit 3
+#define reg_dma_rw_data_stat_offset 16
+
+/* Register rw_data_md, scope dma, type rw */
+#define reg_dma_rw_data_md___md___lsb 0
+#define reg_dma_rw_data_md___md___width 16
+#define reg_dma_rw_data_md_offset 20
+
+/* Register rw_data_md_s, scope dma, type rw */
+#define reg_dma_rw_data_md_s___md_s___lsb 0
+#define reg_dma_rw_data_md_s___md_s___width 16
+#define reg_dma_rw_data_md_s_offset 24
+
+/* Register rw_data_after, scope dma, type rw */
+#define reg_dma_rw_data_after_offset 28
+
+/* Register rw_ctxt, scope dma, type rw */
+#define reg_dma_rw_ctxt_offset 32
+
+/* Register rw_ctxt_next, scope dma, type rw */
+#define reg_dma_rw_ctxt_next_offset 36
+
+/* Register rw_ctxt_ctrl, scope dma, type rw */
+#define reg_dma_rw_ctxt_ctrl___eol___lsb 0
+#define reg_dma_rw_ctxt_ctrl___eol___width 1
+#define reg_dma_rw_ctxt_ctrl___eol___bit 0
+#define reg_dma_rw_ctxt_ctrl___intr___lsb 4
+#define reg_dma_rw_ctxt_ctrl___intr___width 1
+#define reg_dma_rw_ctxt_ctrl___intr___bit 4
+#define reg_dma_rw_ctxt_ctrl___store_mode___lsb 6
+#define reg_dma_rw_ctxt_ctrl___store_mode___width 1
+#define reg_dma_rw_ctxt_ctrl___store_mode___bit 6
+#define reg_dma_rw_ctxt_ctrl___en___lsb 7
+#define reg_dma_rw_ctxt_ctrl___en___width 1
+#define reg_dma_rw_ctxt_ctrl___en___bit 7
+#define reg_dma_rw_ctxt_ctrl_offset 40
+
+/* Register rw_ctxt_stat, scope dma, type rw */
+#define reg_dma_rw_ctxt_stat___dis___lsb 7
+#define reg_dma_rw_ctxt_stat___dis___width 1
+#define reg_dma_rw_ctxt_stat___dis___bit 7
+#define reg_dma_rw_ctxt_stat_offset 44
+
+/* Register rw_ctxt_md0, scope dma, type rw */
+#define reg_dma_rw_ctxt_md0___md0___lsb 0
+#define reg_dma_rw_ctxt_md0___md0___width 16
+#define reg_dma_rw_ctxt_md0_offset 48
+
+/* Register rw_ctxt_md0_s, scope dma, type rw */
+#define reg_dma_rw_ctxt_md0_s___md0_s___lsb 0
+#define reg_dma_rw_ctxt_md0_s___md0_s___width 16
+#define reg_dma_rw_ctxt_md0_s_offset 52
+
+/* Register rw_ctxt_md1, scope dma, type rw */
+#define reg_dma_rw_ctxt_md1_offset 56
+
+/* Register rw_ctxt_md1_s, scope dma, type rw */
+#define reg_dma_rw_ctxt_md1_s_offset 60
+
+/* Register rw_ctxt_md2, scope dma, type rw */
+#define reg_dma_rw_ctxt_md2_offset 64
+
+/* Register rw_ctxt_md2_s, scope dma, type rw */
+#define reg_dma_rw_ctxt_md2_s_offset 68
+
+/* Register rw_ctxt_md3, scope dma, type rw */
+#define reg_dma_rw_ctxt_md3_offset 72
+
+/* Register rw_ctxt_md3_s, scope dma, type rw */
+#define reg_dma_rw_ctxt_md3_s_offset 76
+
+/* Register rw_ctxt_md4, scope dma, type rw */
+#define reg_dma_rw_ctxt_md4_offset 80
+
+/* Register rw_ctxt_md4_s, scope dma, type rw */
+#define reg_dma_rw_ctxt_md4_s_offset 84
+
+/* Register rw_saved_data, scope dma, type rw */
+#define reg_dma_rw_saved_data_offset 88
+
+/* Register rw_saved_data_buf, scope dma, type rw */
+#define reg_dma_rw_saved_data_buf_offset 92
+
+/* Register rw_group, scope dma, type rw */
+#define reg_dma_rw_group_offset 96
+
+/* Register rw_group_next, scope dma, type rw */
+#define reg_dma_rw_group_next_offset 100
+
+/* Register rw_group_ctrl, scope dma, type rw */
+#define reg_dma_rw_group_ctrl___eol___lsb 0
+#define reg_dma_rw_group_ctrl___eol___width 1
+#define reg_dma_rw_group_ctrl___eol___bit 0
+#define reg_dma_rw_group_ctrl___tol___lsb 1
+#define reg_dma_rw_group_ctrl___tol___width 1
+#define reg_dma_rw_group_ctrl___tol___bit 1
+#define reg_dma_rw_group_ctrl___bol___lsb 2
+#define reg_dma_rw_group_ctrl___bol___width 1
+#define reg_dma_rw_group_ctrl___bol___bit 2
+#define reg_dma_rw_group_ctrl___intr___lsb 4
+#define reg_dma_rw_group_ctrl___intr___width 1
+#define reg_dma_rw_group_ctrl___intr___bit 4
+#define reg_dma_rw_group_ctrl___en___lsb 7
+#define reg_dma_rw_group_ctrl___en___width 1
+#define reg_dma_rw_group_ctrl___en___bit 7
+#define reg_dma_rw_group_ctrl_offset 104
+
+/* Register rw_group_stat, scope dma, type rw */
+#define reg_dma_rw_group_stat___dis___lsb 7
+#define reg_dma_rw_group_stat___dis___width 1
+#define reg_dma_rw_group_stat___dis___bit 7
+#define reg_dma_rw_group_stat_offset 108
+
+/* Register rw_group_md, scope dma, type rw */
+#define reg_dma_rw_group_md___md___lsb 0
+#define reg_dma_rw_group_md___md___width 16
+#define reg_dma_rw_group_md_offset 112
+
+/* Register rw_group_md_s, scope dma, type rw */
+#define reg_dma_rw_group_md_s___md_s___lsb 0
+#define reg_dma_rw_group_md_s___md_s___width 16
+#define reg_dma_rw_group_md_s_offset 116
+
+/* Register rw_group_up, scope dma, type rw */
+#define reg_dma_rw_group_up_offset 120
+
+/* Register rw_group_down, scope dma, type rw */
+#define reg_dma_rw_group_down_offset 124
+
+/* Register rw_cmd, scope dma, type rw */
+#define reg_dma_rw_cmd___cont_data___lsb 0
+#define reg_dma_rw_cmd___cont_data___width 1
+#define reg_dma_rw_cmd___cont_data___bit 0
+#define reg_dma_rw_cmd_offset 128
+
+/* Register rw_cfg, scope dma, type rw */
+#define reg_dma_rw_cfg___en___lsb 0
+#define reg_dma_rw_cfg___en___width 1
+#define reg_dma_rw_cfg___en___bit 0
+#define reg_dma_rw_cfg___stop___lsb 1
+#define reg_dma_rw_cfg___stop___width 1
+#define reg_dma_rw_cfg___stop___bit 1
+#define reg_dma_rw_cfg_offset 132
+
+/* Register rw_stat, scope dma, type rw */
+#define reg_dma_rw_stat___mode___lsb 0
+#define reg_dma_rw_stat___mode___width 5
+#define reg_dma_rw_stat___list_state___lsb 5
+#define reg_dma_rw_stat___list_state___width 3
+#define reg_dma_rw_stat___stream_cmd_src___lsb 8
+#define reg_dma_rw_stat___stream_cmd_src___width 8
+#define reg_dma_rw_stat___buf___lsb 24
+#define reg_dma_rw_stat___buf___width 8
+#define reg_dma_rw_stat_offset 136
+
+/* Register rw_intr_mask, scope dma, type rw */
+#define reg_dma_rw_intr_mask___group___lsb 0
+#define reg_dma_rw_intr_mask___group___width 1
+#define reg_dma_rw_intr_mask___group___bit 0
+#define reg_dma_rw_intr_mask___ctxt___lsb 1
+#define reg_dma_rw_intr_mask___ctxt___width 1
+#define reg_dma_rw_intr_mask___ctxt___bit 1
+#define reg_dma_rw_intr_mask___data___lsb 2
+#define reg_dma_rw_intr_mask___data___width 1
+#define reg_dma_rw_intr_mask___data___bit 2
+#define reg_dma_rw_intr_mask___in_eop___lsb 3
+#define reg_dma_rw_intr_mask___in_eop___width 1
+#define reg_dma_rw_intr_mask___in_eop___bit 3
+#define reg_dma_rw_intr_mask___stream_cmd___lsb 4
+#define reg_dma_rw_intr_mask___stream_cmd___width 1
+#define reg_dma_rw_intr_mask___stream_cmd___bit 4
+#define reg_dma_rw_intr_mask_offset 140
+
+/* Register rw_ack_intr, scope dma, type rw */
+#define reg_dma_rw_ack_intr___group___lsb 0
+#define reg_dma_rw_ack_intr___group___width 1
+#define reg_dma_rw_ack_intr___group___bit 0
+#define reg_dma_rw_ack_intr___ctxt___lsb 1
+#define reg_dma_rw_ack_intr___ctxt___width 1
+#define reg_dma_rw_ack_intr___ctxt___bit 1
+#define reg_dma_rw_ack_intr___data___lsb 2
+#define reg_dma_rw_ack_intr___data___width 1
+#define reg_dma_rw_ack_intr___data___bit 2
+#define reg_dma_rw_ack_intr___in_eop___lsb 3
+#define reg_dma_rw_ack_intr___in_eop___width 1
+#define reg_dma_rw_ack_intr___in_eop___bit 3
+#define reg_dma_rw_ack_intr___stream_cmd___lsb 4
+#define reg_dma_rw_ack_intr___stream_cmd___width 1
+#define reg_dma_rw_ack_intr___stream_cmd___bit 4
+#define reg_dma_rw_ack_intr_offset 144
+
+/* Register r_intr, scope dma, type r */
+#define reg_dma_r_intr___group___lsb 0
+#define reg_dma_r_intr___group___width 1
+#define reg_dma_r_intr___group___bit 0
+#define reg_dma_r_intr___ctxt___lsb 1
+#define reg_dma_r_intr___ctxt___width 1
+#define reg_dma_r_intr___ctxt___bit 1
+#define reg_dma_r_intr___data___lsb 2
+#define reg_dma_r_intr___data___width 1
+#define reg_dma_r_intr___data___bit 2
+#define reg_dma_r_intr___in_eop___lsb 3
+#define reg_dma_r_intr___in_eop___width 1
+#define reg_dma_r_intr___in_eop___bit 3
+#define reg_dma_r_intr___stream_cmd___lsb 4
+#define reg_dma_r_intr___stream_cmd___width 1
+#define reg_dma_r_intr___stream_cmd___bit 4
+#define reg_dma_r_intr_offset 148
+
+/* Register r_masked_intr, scope dma, type r */
+#define reg_dma_r_masked_intr___group___lsb 0
+#define reg_dma_r_masked_intr___group___width 1
+#define reg_dma_r_masked_intr___group___bit 0
+#define reg_dma_r_masked_intr___ctxt___lsb 1
+#define reg_dma_r_masked_intr___ctxt___width 1
+#define reg_dma_r_masked_intr___ctxt___bit 1
+#define reg_dma_r_masked_intr___data___lsb 2
+#define reg_dma_r_masked_intr___data___width 1
+#define reg_dma_r_masked_intr___data___bit 2
+#define reg_dma_r_masked_intr___in_eop___lsb 3
+#define reg_dma_r_masked_intr___in_eop___width 1
+#define reg_dma_r_masked_intr___in_eop___bit 3
+#define reg_dma_r_masked_intr___stream_cmd___lsb 4
+#define reg_dma_r_masked_intr___stream_cmd___width 1
+#define reg_dma_r_masked_intr___stream_cmd___bit 4
+#define reg_dma_r_masked_intr_offset 152
+
+/* Register rw_stream_cmd, scope dma, type rw */
+#define reg_dma_rw_stream_cmd___cmd___lsb 0
+#define reg_dma_rw_stream_cmd___cmd___width 10
+#define reg_dma_rw_stream_cmd___n___lsb 16
+#define reg_dma_rw_stream_cmd___n___width 8
+#define reg_dma_rw_stream_cmd___busy___lsb 31
+#define reg_dma_rw_stream_cmd___busy___width 1
+#define reg_dma_rw_stream_cmd___busy___bit 31
+#define reg_dma_rw_stream_cmd_offset 156
+
+
+/* Constants */
+#define regk_dma_ack_pkt                          0x00000100
+#define regk_dma_anytime                          0x00000001
+#define regk_dma_array                            0x00000008
+#define regk_dma_burst                            0x00000020
+#define regk_dma_client                           0x00000002
+#define regk_dma_copy_next                        0x00000010
+#define regk_dma_copy_up                          0x00000020
+#define regk_dma_data_at_eol                      0x00000001
+#define regk_dma_dis_c                            0x00000010
+#define regk_dma_dis_g                            0x00000020
+#define regk_dma_idle                             0x00000001
+#define regk_dma_intern                           0x00000004
+#define regk_dma_load_c                           0x00000200
+#define regk_dma_load_c_n                         0x00000280
+#define regk_dma_load_c_next                      0x00000240
+#define regk_dma_load_d                           0x00000140
+#define regk_dma_load_g                           0x00000300
+#define regk_dma_load_g_down                      0x000003c0
+#define regk_dma_load_g_next                      0x00000340
+#define regk_dma_load_g_up                        0x00000380
+#define regk_dma_next_en                          0x00000010
+#define regk_dma_next_pkt                         0x00000010
+#define regk_dma_no                               0x00000000
+#define regk_dma_only_at_wait                     0x00000000
+#define regk_dma_restore                          0x00000020
+#define regk_dma_rst                              0x00000001
+#define regk_dma_running                          0x00000004
+#define regk_dma_rw_cfg_default                   0x00000000
+#define regk_dma_rw_cmd_default                   0x00000000
+#define regk_dma_rw_intr_mask_default             0x00000000
+#define regk_dma_rw_stat_default                  0x00000101
+#define regk_dma_rw_stream_cmd_default            0x00000000
+#define regk_dma_save_down                        0x00000020
+#define regk_dma_save_up                          0x00000020
+#define regk_dma_set_reg                          0x00000050
+#define regk_dma_set_w_size1                      0x00000190
+#define regk_dma_set_w_size2                      0x000001a0
+#define regk_dma_set_w_size4                      0x000001c0
+#define regk_dma_stopped                          0x00000002
+#define regk_dma_store_c                          0x00000002
+#define regk_dma_store_descr                      0x00000000
+#define regk_dma_store_g                          0x00000004
+#define regk_dma_store_md                         0x00000001
+#define regk_dma_sw                               0x00000008
+#define regk_dma_update_down                      0x00000020
+#define regk_dma_yes                              0x00000001
+#endif /* __dma_defs_asm_h */
diff --git a/include/asm-cris/arch-v32/hwregs/asm/eth_defs_asm.h b/include/asm-cris/arch-v32/hwregs/asm/eth_defs_asm.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/asm/eth_defs_asm.h
@@ -0,0 +1,498 @@
+#ifndef __eth_defs_asm_h
+#define __eth_defs_asm_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/eth/rtl/eth_regs.r
+ *     id:           eth_regs.r,v 1.11 2005/02/09 10:48:38 kriskn Exp
+ *     last modfied: Mon Apr 11 16:07:03 2005
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c -asm --outfile asm/eth_defs_asm.h ../../inst/eth/rtl/eth_regs.r
+ *      id: $Id: eth_defs_asm.h,v 1.1 2005/04/24 18:31:04 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+
+#ifndef REG_FIELD
+#define REG_FIELD( scope, reg, field, value ) \
+  REG_FIELD_X_( value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_FIELD_X_( value, shift ) ((value) << shift)
+#endif
+
+#ifndef REG_STATE
+#define REG_STATE( scope, reg, field, symbolic_value ) \
+  REG_STATE_X_( regk_##scope##_##symbolic_value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_STATE_X_( k, shift ) (k << shift)
+#endif
+
+#ifndef REG_MASK
+#define REG_MASK( scope, reg, field ) \
+  REG_MASK_X_( reg_##scope##_##reg##___##field##___width, reg_##scope##_##reg##___##field##___lsb )
+#define REG_MASK_X_( width, lsb ) (((1 << width)-1) << lsb)
+#endif
+
+#ifndef REG_LSB
+#define REG_LSB( scope, reg, field ) reg_##scope##_##reg##___##field##___lsb
+#endif
+
+#ifndef REG_BIT
+#define REG_BIT( scope, reg, field ) reg_##scope##_##reg##___##field##___bit
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) REG_ADDR_X_(inst, reg_##scope##_##reg##_offset)
+#define REG_ADDR_X_( inst, offs ) ((inst) + offs)
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+         REG_ADDR_VECT_X_(inst, reg_##scope##_##reg##_offset, index, \
+			 STRIDE_##scope##_##reg )
+#define REG_ADDR_VECT_X_( inst, offs, index, stride ) \
+                          ((inst) + offs + (index) * stride)
+#endif
+
+/* Register rw_ma0_lo, scope eth, type rw */
+#define reg_eth_rw_ma0_lo___addr___lsb 0
+#define reg_eth_rw_ma0_lo___addr___width 32
+#define reg_eth_rw_ma0_lo_offset 0
+
+/* Register rw_ma0_hi, scope eth, type rw */
+#define reg_eth_rw_ma0_hi___addr___lsb 0
+#define reg_eth_rw_ma0_hi___addr___width 16
+#define reg_eth_rw_ma0_hi_offset 4
+
+/* Register rw_ma1_lo, scope eth, type rw */
+#define reg_eth_rw_ma1_lo___addr___lsb 0
+#define reg_eth_rw_ma1_lo___addr___width 32
+#define reg_eth_rw_ma1_lo_offset 8
+
+/* Register rw_ma1_hi, scope eth, type rw */
+#define reg_eth_rw_ma1_hi___addr___lsb 0
+#define reg_eth_rw_ma1_hi___addr___width 16
+#define reg_eth_rw_ma1_hi_offset 12
+
+/* Register rw_ga_lo, scope eth, type rw */
+#define reg_eth_rw_ga_lo___table___lsb 0
+#define reg_eth_rw_ga_lo___table___width 32
+#define reg_eth_rw_ga_lo_offset 16
+
+/* Register rw_ga_hi, scope eth, type rw */
+#define reg_eth_rw_ga_hi___table___lsb 0
+#define reg_eth_rw_ga_hi___table___width 32
+#define reg_eth_rw_ga_hi_offset 20
+
+/* Register rw_gen_ctrl, scope eth, type rw */
+#define reg_eth_rw_gen_ctrl___en___lsb 0
+#define reg_eth_rw_gen_ctrl___en___width 1
+#define reg_eth_rw_gen_ctrl___en___bit 0
+#define reg_eth_rw_gen_ctrl___phy___lsb 1
+#define reg_eth_rw_gen_ctrl___phy___width 2
+#define reg_eth_rw_gen_ctrl___protocol___lsb 3
+#define reg_eth_rw_gen_ctrl___protocol___width 1
+#define reg_eth_rw_gen_ctrl___protocol___bit 3
+#define reg_eth_rw_gen_ctrl___loopback___lsb 4
+#define reg_eth_rw_gen_ctrl___loopback___width 1
+#define reg_eth_rw_gen_ctrl___loopback___bit 4
+#define reg_eth_rw_gen_ctrl___flow_ctrl_dis___lsb 5
+#define reg_eth_rw_gen_ctrl___flow_ctrl_dis___width 1
+#define reg_eth_rw_gen_ctrl___flow_ctrl_dis___bit 5
+#define reg_eth_rw_gen_ctrl_offset 24
+
+/* Register rw_rec_ctrl, scope eth, type rw */
+#define reg_eth_rw_rec_ctrl___ma0___lsb 0
+#define reg_eth_rw_rec_ctrl___ma0___width 1
+#define reg_eth_rw_rec_ctrl___ma0___bit 0
+#define reg_eth_rw_rec_ctrl___ma1___lsb 1
+#define reg_eth_rw_rec_ctrl___ma1___width 1
+#define reg_eth_rw_rec_ctrl___ma1___bit 1
+#define reg_eth_rw_rec_ctrl___individual___lsb 2
+#define reg_eth_rw_rec_ctrl___individual___width 1
+#define reg_eth_rw_rec_ctrl___individual___bit 2
+#define reg_eth_rw_rec_ctrl___broadcast___lsb 3
+#define reg_eth_rw_rec_ctrl___broadcast___width 1
+#define reg_eth_rw_rec_ctrl___broadcast___bit 3
+#define reg_eth_rw_rec_ctrl___undersize___lsb 4
+#define reg_eth_rw_rec_ctrl___undersize___width 1
+#define reg_eth_rw_rec_ctrl___undersize___bit 4
+#define reg_eth_rw_rec_ctrl___oversize___lsb 5
+#define reg_eth_rw_rec_ctrl___oversize___width 1
+#define reg_eth_rw_rec_ctrl___oversize___bit 5
+#define reg_eth_rw_rec_ctrl___bad_crc___lsb 6
+#define reg_eth_rw_rec_ctrl___bad_crc___width 1
+#define reg_eth_rw_rec_ctrl___bad_crc___bit 6
+#define reg_eth_rw_rec_ctrl___duplex___lsb 7
+#define reg_eth_rw_rec_ctrl___duplex___width 1
+#define reg_eth_rw_rec_ctrl___duplex___bit 7
+#define reg_eth_rw_rec_ctrl___max_size___lsb 8
+#define reg_eth_rw_rec_ctrl___max_size___width 1
+#define reg_eth_rw_rec_ctrl___max_size___bit 8
+#define reg_eth_rw_rec_ctrl_offset 28
+
+/* Register rw_tr_ctrl, scope eth, type rw */
+#define reg_eth_rw_tr_ctrl___crc___lsb 0
+#define reg_eth_rw_tr_ctrl___crc___width 1
+#define reg_eth_rw_tr_ctrl___crc___bit 0
+#define reg_eth_rw_tr_ctrl___pad___lsb 1
+#define reg_eth_rw_tr_ctrl___pad___width 1
+#define reg_eth_rw_tr_ctrl___pad___bit 1
+#define reg_eth_rw_tr_ctrl___retry___lsb 2
+#define reg_eth_rw_tr_ctrl___retry___width 1
+#define reg_eth_rw_tr_ctrl___retry___bit 2
+#define reg_eth_rw_tr_ctrl___ignore_col___lsb 3
+#define reg_eth_rw_tr_ctrl___ignore_col___width 1
+#define reg_eth_rw_tr_ctrl___ignore_col___bit 3
+#define reg_eth_rw_tr_ctrl___cancel___lsb 4
+#define reg_eth_rw_tr_ctrl___cancel___width 1
+#define reg_eth_rw_tr_ctrl___cancel___bit 4
+#define reg_eth_rw_tr_ctrl___hsh_delay___lsb 5
+#define reg_eth_rw_tr_ctrl___hsh_delay___width 1
+#define reg_eth_rw_tr_ctrl___hsh_delay___bit 5
+#define reg_eth_rw_tr_ctrl___ignore_crs___lsb 6
+#define reg_eth_rw_tr_ctrl___ignore_crs___width 1
+#define reg_eth_rw_tr_ctrl___ignore_crs___bit 6
+#define reg_eth_rw_tr_ctrl_offset 32
+
+/* Register rw_clr_err, scope eth, type rw */
+#define reg_eth_rw_clr_err___clr___lsb 0
+#define reg_eth_rw_clr_err___clr___width 1
+#define reg_eth_rw_clr_err___clr___bit 0
+#define reg_eth_rw_clr_err_offset 36
+
+/* Register rw_mgm_ctrl, scope eth, type rw */
+#define reg_eth_rw_mgm_ctrl___mdio___lsb 0
+#define reg_eth_rw_mgm_ctrl___mdio___width 1
+#define reg_eth_rw_mgm_ctrl___mdio___bit 0
+#define reg_eth_rw_mgm_ctrl___mdoe___lsb 1
+#define reg_eth_rw_mgm_ctrl___mdoe___width 1
+#define reg_eth_rw_mgm_ctrl___mdoe___bit 1
+#define reg_eth_rw_mgm_ctrl___mdc___lsb 2
+#define reg_eth_rw_mgm_ctrl___mdc___width 1
+#define reg_eth_rw_mgm_ctrl___mdc___bit 2
+#define reg_eth_rw_mgm_ctrl___phyclk___lsb 3
+#define reg_eth_rw_mgm_ctrl___phyclk___width 1
+#define reg_eth_rw_mgm_ctrl___phyclk___bit 3
+#define reg_eth_rw_mgm_ctrl___txdata___lsb 4
+#define reg_eth_rw_mgm_ctrl___txdata___width 4
+#define reg_eth_rw_mgm_ctrl___txen___lsb 8
+#define reg_eth_rw_mgm_ctrl___txen___width 1
+#define reg_eth_rw_mgm_ctrl___txen___bit 8
+#define reg_eth_rw_mgm_ctrl_offset 40
+
+/* Register r_stat, scope eth, type r */
+#define reg_eth_r_stat___mdio___lsb 0
+#define reg_eth_r_stat___mdio___width 1
+#define reg_eth_r_stat___mdio___bit 0
+#define reg_eth_r_stat___exc_col___lsb 1
+#define reg_eth_r_stat___exc_col___width 1
+#define reg_eth_r_stat___exc_col___bit 1
+#define reg_eth_r_stat___urun___lsb 2
+#define reg_eth_r_stat___urun___width 1
+#define reg_eth_r_stat___urun___bit 2
+#define reg_eth_r_stat___phyclk___lsb 3
+#define reg_eth_r_stat___phyclk___width 1
+#define reg_eth_r_stat___phyclk___bit 3
+#define reg_eth_r_stat___txdata___lsb 4
+#define reg_eth_r_stat___txdata___width 4
+#define reg_eth_r_stat___txen___lsb 8
+#define reg_eth_r_stat___txen___width 1
+#define reg_eth_r_stat___txen___bit 8
+#define reg_eth_r_stat___col___lsb 9
+#define reg_eth_r_stat___col___width 1
+#define reg_eth_r_stat___col___bit 9
+#define reg_eth_r_stat___crs___lsb 10
+#define reg_eth_r_stat___crs___width 1
+#define reg_eth_r_stat___crs___bit 10
+#define reg_eth_r_stat___txclk___lsb 11
+#define reg_eth_r_stat___txclk___width 1
+#define reg_eth_r_stat___txclk___bit 11
+#define reg_eth_r_stat___rxdata___lsb 12
+#define reg_eth_r_stat___rxdata___width 4
+#define reg_eth_r_stat___rxer___lsb 16
+#define reg_eth_r_stat___rxer___width 1
+#define reg_eth_r_stat___rxer___bit 16
+#define reg_eth_r_stat___rxdv___lsb 17
+#define reg_eth_r_stat___rxdv___width 1
+#define reg_eth_r_stat___rxdv___bit 17
+#define reg_eth_r_stat___rxclk___lsb 18
+#define reg_eth_r_stat___rxclk___width 1
+#define reg_eth_r_stat___rxclk___bit 18
+#define reg_eth_r_stat_offset 44
+
+/* Register rs_rec_cnt, scope eth, type rs */
+#define reg_eth_rs_rec_cnt___crc_err___lsb 0
+#define reg_eth_rs_rec_cnt___crc_err___width 8
+#define reg_eth_rs_rec_cnt___align_err___lsb 8
+#define reg_eth_rs_rec_cnt___align_err___width 8
+#define reg_eth_rs_rec_cnt___oversize___lsb 16
+#define reg_eth_rs_rec_cnt___oversize___width 8
+#define reg_eth_rs_rec_cnt___congestion___lsb 24
+#define reg_eth_rs_rec_cnt___congestion___width 8
+#define reg_eth_rs_rec_cnt_offset 48
+
+/* Register r_rec_cnt, scope eth, type r */
+#define reg_eth_r_rec_cnt___crc_err___lsb 0
+#define reg_eth_r_rec_cnt___crc_err___width 8
+#define reg_eth_r_rec_cnt___align_err___lsb 8
+#define reg_eth_r_rec_cnt___align_err___width 8
+#define reg_eth_r_rec_cnt___oversize___lsb 16
+#define reg_eth_r_rec_cnt___oversize___width 8
+#define reg_eth_r_rec_cnt___congestion___lsb 24
+#define reg_eth_r_rec_cnt___congestion___width 8
+#define reg_eth_r_rec_cnt_offset 52
+
+/* Register rs_tr_cnt, scope eth, type rs */
+#define reg_eth_rs_tr_cnt___single_col___lsb 0
+#define reg_eth_rs_tr_cnt___single_col___width 8
+#define reg_eth_rs_tr_cnt___mult_col___lsb 8
+#define reg_eth_rs_tr_cnt___mult_col___width 8
+#define reg_eth_rs_tr_cnt___late_col___lsb 16
+#define reg_eth_rs_tr_cnt___late_col___width 8
+#define reg_eth_rs_tr_cnt___deferred___lsb 24
+#define reg_eth_rs_tr_cnt___deferred___width 8
+#define reg_eth_rs_tr_cnt_offset 56
+
+/* Register r_tr_cnt, scope eth, type r */
+#define reg_eth_r_tr_cnt___single_col___lsb 0
+#define reg_eth_r_tr_cnt___single_col___width 8
+#define reg_eth_r_tr_cnt___mult_col___lsb 8
+#define reg_eth_r_tr_cnt___mult_col___width 8
+#define reg_eth_r_tr_cnt___late_col___lsb 16
+#define reg_eth_r_tr_cnt___late_col___width 8
+#define reg_eth_r_tr_cnt___deferred___lsb 24
+#define reg_eth_r_tr_cnt___deferred___width 8
+#define reg_eth_r_tr_cnt_offset 60
+
+/* Register rs_phy_cnt, scope eth, type rs */
+#define reg_eth_rs_phy_cnt___carrier_loss___lsb 0
+#define reg_eth_rs_phy_cnt___carrier_loss___width 8
+#define reg_eth_rs_phy_cnt___sqe_err___lsb 8
+#define reg_eth_rs_phy_cnt___sqe_err___width 8
+#define reg_eth_rs_phy_cnt_offset 64
+
+/* Register r_phy_cnt, scope eth, type r */
+#define reg_eth_r_phy_cnt___carrier_loss___lsb 0
+#define reg_eth_r_phy_cnt___carrier_loss___width 8
+#define reg_eth_r_phy_cnt___sqe_err___lsb 8
+#define reg_eth_r_phy_cnt___sqe_err___width 8
+#define reg_eth_r_phy_cnt_offset 68
+
+/* Register rw_test_ctrl, scope eth, type rw */
+#define reg_eth_rw_test_ctrl___snmp_inc___lsb 0
+#define reg_eth_rw_test_ctrl___snmp_inc___width 1
+#define reg_eth_rw_test_ctrl___snmp_inc___bit 0
+#define reg_eth_rw_test_ctrl___snmp___lsb 1
+#define reg_eth_rw_test_ctrl___snmp___width 1
+#define reg_eth_rw_test_ctrl___snmp___bit 1
+#define reg_eth_rw_test_ctrl___backoff___lsb 2
+#define reg_eth_rw_test_ctrl___backoff___width 1
+#define reg_eth_rw_test_ctrl___backoff___bit 2
+#define reg_eth_rw_test_ctrl_offset 72
+
+/* Register rw_intr_mask, scope eth, type rw */
+#define reg_eth_rw_intr_mask___crc___lsb 0
+#define reg_eth_rw_intr_mask___crc___width 1
+#define reg_eth_rw_intr_mask___crc___bit 0
+#define reg_eth_rw_intr_mask___align___lsb 1
+#define reg_eth_rw_intr_mask___align___width 1
+#define reg_eth_rw_intr_mask___align___bit 1
+#define reg_eth_rw_intr_mask___oversize___lsb 2
+#define reg_eth_rw_intr_mask___oversize___width 1
+#define reg_eth_rw_intr_mask___oversize___bit 2
+#define reg_eth_rw_intr_mask___congestion___lsb 3
+#define reg_eth_rw_intr_mask___congestion___width 1
+#define reg_eth_rw_intr_mask___congestion___bit 3
+#define reg_eth_rw_intr_mask___single_col___lsb 4
+#define reg_eth_rw_intr_mask___single_col___width 1
+#define reg_eth_rw_intr_mask___single_col___bit 4
+#define reg_eth_rw_intr_mask___mult_col___lsb 5
+#define reg_eth_rw_intr_mask___mult_col___width 1
+#define reg_eth_rw_intr_mask___mult_col___bit 5
+#define reg_eth_rw_intr_mask___late_col___lsb 6
+#define reg_eth_rw_intr_mask___late_col___width 1
+#define reg_eth_rw_intr_mask___late_col___bit 6
+#define reg_eth_rw_intr_mask___deferred___lsb 7
+#define reg_eth_rw_intr_mask___deferred___width 1
+#define reg_eth_rw_intr_mask___deferred___bit 7
+#define reg_eth_rw_intr_mask___carrier_loss___lsb 8
+#define reg_eth_rw_intr_mask___carrier_loss___width 1
+#define reg_eth_rw_intr_mask___carrier_loss___bit 8
+#define reg_eth_rw_intr_mask___sqe_test_err___lsb 9
+#define reg_eth_rw_intr_mask___sqe_test_err___width 1
+#define reg_eth_rw_intr_mask___sqe_test_err___bit 9
+#define reg_eth_rw_intr_mask___orun___lsb 10
+#define reg_eth_rw_intr_mask___orun___width 1
+#define reg_eth_rw_intr_mask___orun___bit 10
+#define reg_eth_rw_intr_mask___urun___lsb 11
+#define reg_eth_rw_intr_mask___urun___width 1
+#define reg_eth_rw_intr_mask___urun___bit 11
+#define reg_eth_rw_intr_mask___excessive_col___lsb 12
+#define reg_eth_rw_intr_mask___excessive_col___width 1
+#define reg_eth_rw_intr_mask___excessive_col___bit 12
+#define reg_eth_rw_intr_mask___mdio___lsb 13
+#define reg_eth_rw_intr_mask___mdio___width 1
+#define reg_eth_rw_intr_mask___mdio___bit 13
+#define reg_eth_rw_intr_mask_offset 76
+
+/* Register rw_ack_intr, scope eth, type rw */
+#define reg_eth_rw_ack_intr___crc___lsb 0
+#define reg_eth_rw_ack_intr___crc___width 1
+#define reg_eth_rw_ack_intr___crc___bit 0
+#define reg_eth_rw_ack_intr___align___lsb 1
+#define reg_eth_rw_ack_intr___align___width 1
+#define reg_eth_rw_ack_intr___align___bit 1
+#define reg_eth_rw_ack_intr___oversize___lsb 2
+#define reg_eth_rw_ack_intr___oversize___width 1
+#define reg_eth_rw_ack_intr___oversize___bit 2
+#define reg_eth_rw_ack_intr___congestion___lsb 3
+#define reg_eth_rw_ack_intr___congestion___width 1
+#define reg_eth_rw_ack_intr___congestion___bit 3
+#define reg_eth_rw_ack_intr___single_col___lsb 4
+#define reg_eth_rw_ack_intr___single_col___width 1
+#define reg_eth_rw_ack_intr___single_col___bit 4
+#define reg_eth_rw_ack_intr___mult_col___lsb 5
+#define reg_eth_rw_ack_intr___mult_col___width 1
+#define reg_eth_rw_ack_intr___mult_col___bit 5
+#define reg_eth_rw_ack_intr___late_col___lsb 6
+#define reg_eth_rw_ack_intr___late_col___width 1
+#define reg_eth_rw_ack_intr___late_col___bit 6
+#define reg_eth_rw_ack_intr___deferred___lsb 7
+#define reg_eth_rw_ack_intr___deferred___width 1
+#define reg_eth_rw_ack_intr___deferred___bit 7
+#define reg_eth_rw_ack_intr___carrier_loss___lsb 8
+#define reg_eth_rw_ack_intr___carrier_loss___width 1
+#define reg_eth_rw_ack_intr___carrier_loss___bit 8
+#define reg_eth_rw_ack_intr___sqe_test_err___lsb 9
+#define reg_eth_rw_ack_intr___sqe_test_err___width 1
+#define reg_eth_rw_ack_intr___sqe_test_err___bit 9
+#define reg_eth_rw_ack_intr___orun___lsb 10
+#define reg_eth_rw_ack_intr___orun___width 1
+#define reg_eth_rw_ack_intr___orun___bit 10
+#define reg_eth_rw_ack_intr___urun___lsb 11
+#define reg_eth_rw_ack_intr___urun___width 1
+#define reg_eth_rw_ack_intr___urun___bit 11
+#define reg_eth_rw_ack_intr___excessive_col___lsb 12
+#define reg_eth_rw_ack_intr___excessive_col___width 1
+#define reg_eth_rw_ack_intr___excessive_col___bit 12
+#define reg_eth_rw_ack_intr___mdio___lsb 13
+#define reg_eth_rw_ack_intr___mdio___width 1
+#define reg_eth_rw_ack_intr___mdio___bit 13
+#define reg_eth_rw_ack_intr_offset 80
+
+/* Register r_intr, scope eth, type r */
+#define reg_eth_r_intr___crc___lsb 0
+#define reg_eth_r_intr___crc___width 1
+#define reg_eth_r_intr___crc___bit 0
+#define reg_eth_r_intr___align___lsb 1
+#define reg_eth_r_intr___align___width 1
+#define reg_eth_r_intr___align___bit 1
+#define reg_eth_r_intr___oversize___lsb 2
+#define reg_eth_r_intr___oversize___width 1
+#define reg_eth_r_intr___oversize___bit 2
+#define reg_eth_r_intr___congestion___lsb 3
+#define reg_eth_r_intr___congestion___width 1
+#define reg_eth_r_intr___congestion___bit 3
+#define reg_eth_r_intr___single_col___lsb 4
+#define reg_eth_r_intr___single_col___width 1
+#define reg_eth_r_intr___single_col___bit 4
+#define reg_eth_r_intr___mult_col___lsb 5
+#define reg_eth_r_intr___mult_col___width 1
+#define reg_eth_r_intr___mult_col___bit 5
+#define reg_eth_r_intr___late_col___lsb 6
+#define reg_eth_r_intr___late_col___width 1
+#define reg_eth_r_intr___late_col___bit 6
+#define reg_eth_r_intr___deferred___lsb 7
+#define reg_eth_r_intr___deferred___width 1
+#define reg_eth_r_intr___deferred___bit 7
+#define reg_eth_r_intr___carrier_loss___lsb 8
+#define reg_eth_r_intr___carrier_loss___width 1
+#define reg_eth_r_intr___carrier_loss___bit 8
+#define reg_eth_r_intr___sqe_test_err___lsb 9
+#define reg_eth_r_intr___sqe_test_err___width 1
+#define reg_eth_r_intr___sqe_test_err___bit 9
+#define reg_eth_r_intr___orun___lsb 10
+#define reg_eth_r_intr___orun___width 1
+#define reg_eth_r_intr___orun___bit 10
+#define reg_eth_r_intr___urun___lsb 11
+#define reg_eth_r_intr___urun___width 1
+#define reg_eth_r_intr___urun___bit 11
+#define reg_eth_r_intr___excessive_col___lsb 12
+#define reg_eth_r_intr___excessive_col___width 1
+#define reg_eth_r_intr___excessive_col___bit 12
+#define reg_eth_r_intr___mdio___lsb 13
+#define reg_eth_r_intr___mdio___width 1
+#define reg_eth_r_intr___mdio___bit 13
+#define reg_eth_r_intr_offset 84
+
+/* Register r_masked_intr, scope eth, type r */
+#define reg_eth_r_masked_intr___crc___lsb 0
+#define reg_eth_r_masked_intr___crc___width 1
+#define reg_eth_r_masked_intr___crc___bit 0
+#define reg_eth_r_masked_intr___align___lsb 1
+#define reg_eth_r_masked_intr___align___width 1
+#define reg_eth_r_masked_intr___align___bit 1
+#define reg_eth_r_masked_intr___oversize___lsb 2
+#define reg_eth_r_masked_intr___oversize___width 1
+#define reg_eth_r_masked_intr___oversize___bit 2
+#define reg_eth_r_masked_intr___congestion___lsb 3
+#define reg_eth_r_masked_intr___congestion___width 1
+#define reg_eth_r_masked_intr___congestion___bit 3
+#define reg_eth_r_masked_intr___single_col___lsb 4
+#define reg_eth_r_masked_intr___single_col___width 1
+#define reg_eth_r_masked_intr___single_col___bit 4
+#define reg_eth_r_masked_intr___mult_col___lsb 5
+#define reg_eth_r_masked_intr___mult_col___width 1
+#define reg_eth_r_masked_intr___mult_col___bit 5
+#define reg_eth_r_masked_intr___late_col___lsb 6
+#define reg_eth_r_masked_intr___late_col___width 1
+#define reg_eth_r_masked_intr___late_col___bit 6
+#define reg_eth_r_masked_intr___deferred___lsb 7
+#define reg_eth_r_masked_intr___deferred___width 1
+#define reg_eth_r_masked_intr___deferred___bit 7
+#define reg_eth_r_masked_intr___carrier_loss___lsb 8
+#define reg_eth_r_masked_intr___carrier_loss___width 1
+#define reg_eth_r_masked_intr___carrier_loss___bit 8
+#define reg_eth_r_masked_intr___sqe_test_err___lsb 9
+#define reg_eth_r_masked_intr___sqe_test_err___width 1
+#define reg_eth_r_masked_intr___sqe_test_err___bit 9
+#define reg_eth_r_masked_intr___orun___lsb 10
+#define reg_eth_r_masked_intr___orun___width 1
+#define reg_eth_r_masked_intr___orun___bit 10
+#define reg_eth_r_masked_intr___urun___lsb 11
+#define reg_eth_r_masked_intr___urun___width 1
+#define reg_eth_r_masked_intr___urun___bit 11
+#define reg_eth_r_masked_intr___excessive_col___lsb 12
+#define reg_eth_r_masked_intr___excessive_col___width 1
+#define reg_eth_r_masked_intr___excessive_col___bit 12
+#define reg_eth_r_masked_intr___mdio___lsb 13
+#define reg_eth_r_masked_intr___mdio___width 1
+#define reg_eth_r_masked_intr___mdio___bit 13
+#define reg_eth_r_masked_intr_offset 88
+
+
+/* Constants */
+#define regk_eth_discard                          0x00000000
+#define regk_eth_ether                            0x00000000
+#define regk_eth_full                             0x00000001
+#define regk_eth_half                             0x00000000
+#define regk_eth_hsh                              0x00000001
+#define regk_eth_mii                              0x00000001
+#define regk_eth_mii_clk                          0x00000000
+#define regk_eth_mii_rec                          0x00000002
+#define regk_eth_no                               0x00000000
+#define regk_eth_rec                              0x00000001
+#define regk_eth_rw_ga_hi_default                 0x00000000
+#define regk_eth_rw_ga_lo_default                 0x00000000
+#define regk_eth_rw_gen_ctrl_default              0x00000000
+#define regk_eth_rw_intr_mask_default             0x00000000
+#define regk_eth_rw_ma0_hi_default                0x00000000
+#define regk_eth_rw_ma0_lo_default                0x00000000
+#define regk_eth_rw_ma1_hi_default                0x00000000
+#define regk_eth_rw_ma1_lo_default                0x00000000
+#define regk_eth_rw_mgm_ctrl_default              0x00000000
+#define regk_eth_rw_test_ctrl_default             0x00000000
+#define regk_eth_size1518                         0x00000000
+#define regk_eth_size1522                         0x00000001
+#define regk_eth_yes                              0x00000001
+#endif /* __eth_defs_asm_h */
diff --git a/include/asm-cris/arch-v32/hwregs/asm/gio_defs_asm.h b/include/asm-cris/arch-v32/hwregs/asm/gio_defs_asm.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/asm/gio_defs_asm.h
@@ -0,0 +1,276 @@
+#ifndef __gio_defs_asm_h
+#define __gio_defs_asm_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/gio/rtl/gio_regs.r
+ *     id:           gio_regs.r,v 1.5 2005/02/04 09:43:21 perz Exp
+ *     last modfied: Mon Apr 11 16:07:47 2005
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c -asm --outfile asm/gio_defs_asm.h ../../inst/gio/rtl/gio_regs.r
+ *      id: $Id: gio_defs_asm.h,v 1.1 2005/04/24 18:31:04 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+
+#ifndef REG_FIELD
+#define REG_FIELD( scope, reg, field, value ) \
+  REG_FIELD_X_( value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_FIELD_X_( value, shift ) ((value) << shift)
+#endif
+
+#ifndef REG_STATE
+#define REG_STATE( scope, reg, field, symbolic_value ) \
+  REG_STATE_X_( regk_##scope##_##symbolic_value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_STATE_X_( k, shift ) (k << shift)
+#endif
+
+#ifndef REG_MASK
+#define REG_MASK( scope, reg, field ) \
+  REG_MASK_X_( reg_##scope##_##reg##___##field##___width, reg_##scope##_##reg##___##field##___lsb )
+#define REG_MASK_X_( width, lsb ) (((1 << width)-1) << lsb)
+#endif
+
+#ifndef REG_LSB
+#define REG_LSB( scope, reg, field ) reg_##scope##_##reg##___##field##___lsb
+#endif
+
+#ifndef REG_BIT
+#define REG_BIT( scope, reg, field ) reg_##scope##_##reg##___##field##___bit
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) REG_ADDR_X_(inst, reg_##scope##_##reg##_offset)
+#define REG_ADDR_X_( inst, offs ) ((inst) + offs)
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+         REG_ADDR_VECT_X_(inst, reg_##scope##_##reg##_offset, index, \
+			 STRIDE_##scope##_##reg )
+#define REG_ADDR_VECT_X_( inst, offs, index, stride ) \
+                          ((inst) + offs + (index) * stride)
+#endif
+
+/* Register rw_pa_dout, scope gio, type rw */
+#define reg_gio_rw_pa_dout___data___lsb 0
+#define reg_gio_rw_pa_dout___data___width 8
+#define reg_gio_rw_pa_dout_offset 0
+
+/* Register r_pa_din, scope gio, type r */
+#define reg_gio_r_pa_din___data___lsb 0
+#define reg_gio_r_pa_din___data___width 8
+#define reg_gio_r_pa_din_offset 4
+
+/* Register rw_pa_oe, scope gio, type rw */
+#define reg_gio_rw_pa_oe___oe___lsb 0
+#define reg_gio_rw_pa_oe___oe___width 8
+#define reg_gio_rw_pa_oe_offset 8
+
+/* Register rw_intr_cfg, scope gio, type rw */
+#define reg_gio_rw_intr_cfg___pa0___lsb 0
+#define reg_gio_rw_intr_cfg___pa0___width 3
+#define reg_gio_rw_intr_cfg___pa1___lsb 3
+#define reg_gio_rw_intr_cfg___pa1___width 3
+#define reg_gio_rw_intr_cfg___pa2___lsb 6
+#define reg_gio_rw_intr_cfg___pa2___width 3
+#define reg_gio_rw_intr_cfg___pa3___lsb 9
+#define reg_gio_rw_intr_cfg___pa3___width 3
+#define reg_gio_rw_intr_cfg___pa4___lsb 12
+#define reg_gio_rw_intr_cfg___pa4___width 3
+#define reg_gio_rw_intr_cfg___pa5___lsb 15
+#define reg_gio_rw_intr_cfg___pa5___width 3
+#define reg_gio_rw_intr_cfg___pa6___lsb 18
+#define reg_gio_rw_intr_cfg___pa6___width 3
+#define reg_gio_rw_intr_cfg___pa7___lsb 21
+#define reg_gio_rw_intr_cfg___pa7___width 3
+#define reg_gio_rw_intr_cfg_offset 12
+
+/* Register rw_intr_mask, scope gio, type rw */
+#define reg_gio_rw_intr_mask___pa0___lsb 0
+#define reg_gio_rw_intr_mask___pa0___width 1
+#define reg_gio_rw_intr_mask___pa0___bit 0
+#define reg_gio_rw_intr_mask___pa1___lsb 1
+#define reg_gio_rw_intr_mask___pa1___width 1
+#define reg_gio_rw_intr_mask___pa1___bit 1
+#define reg_gio_rw_intr_mask___pa2___lsb 2
+#define reg_gio_rw_intr_mask___pa2___width 1
+#define reg_gio_rw_intr_mask___pa2___bit 2
+#define reg_gio_rw_intr_mask___pa3___lsb 3
+#define reg_gio_rw_intr_mask___pa3___width 1
+#define reg_gio_rw_intr_mask___pa3___bit 3
+#define reg_gio_rw_intr_mask___pa4___lsb 4
+#define reg_gio_rw_intr_mask___pa4___width 1
+#define reg_gio_rw_intr_mask___pa4___bit 4
+#define reg_gio_rw_intr_mask___pa5___lsb 5
+#define reg_gio_rw_intr_mask___pa5___width 1
+#define reg_gio_rw_intr_mask___pa5___bit 5
+#define reg_gio_rw_intr_mask___pa6___lsb 6
+#define reg_gio_rw_intr_mask___pa6___width 1
+#define reg_gio_rw_intr_mask___pa6___bit 6
+#define reg_gio_rw_intr_mask___pa7___lsb 7
+#define reg_gio_rw_intr_mask___pa7___width 1
+#define reg_gio_rw_intr_mask___pa7___bit 7
+#define reg_gio_rw_intr_mask_offset 16
+
+/* Register rw_ack_intr, scope gio, type rw */
+#define reg_gio_rw_ack_intr___pa0___lsb 0
+#define reg_gio_rw_ack_intr___pa0___width 1
+#define reg_gio_rw_ack_intr___pa0___bit 0
+#define reg_gio_rw_ack_intr___pa1___lsb 1
+#define reg_gio_rw_ack_intr___pa1___width 1
+#define reg_gio_rw_ack_intr___pa1___bit 1
+#define reg_gio_rw_ack_intr___pa2___lsb 2
+#define reg_gio_rw_ack_intr___pa2___width 1
+#define reg_gio_rw_ack_intr___pa2___bit 2
+#define reg_gio_rw_ack_intr___pa3___lsb 3
+#define reg_gio_rw_ack_intr___pa3___width 1
+#define reg_gio_rw_ack_intr___pa3___bit 3
+#define reg_gio_rw_ack_intr___pa4___lsb 4
+#define reg_gio_rw_ack_intr___pa4___width 1
+#define reg_gio_rw_ack_intr___pa4___bit 4
+#define reg_gio_rw_ack_intr___pa5___lsb 5
+#define reg_gio_rw_ack_intr___pa5___width 1
+#define reg_gio_rw_ack_intr___pa5___bit 5
+#define reg_gio_rw_ack_intr___pa6___lsb 6
+#define reg_gio_rw_ack_intr___pa6___width 1
+#define reg_gio_rw_ack_intr___pa6___bit 6
+#define reg_gio_rw_ack_intr___pa7___lsb 7
+#define reg_gio_rw_ack_intr___pa7___width 1
+#define reg_gio_rw_ack_intr___pa7___bit 7
+#define reg_gio_rw_ack_intr_offset 20
+
+/* Register r_intr, scope gio, type r */
+#define reg_gio_r_intr___pa0___lsb 0
+#define reg_gio_r_intr___pa0___width 1
+#define reg_gio_r_intr___pa0___bit 0
+#define reg_gio_r_intr___pa1___lsb 1
+#define reg_gio_r_intr___pa1___width 1
+#define reg_gio_r_intr___pa1___bit 1
+#define reg_gio_r_intr___pa2___lsb 2
+#define reg_gio_r_intr___pa2___width 1
+#define reg_gio_r_intr___pa2___bit 2
+#define reg_gio_r_intr___pa3___lsb 3
+#define reg_gio_r_intr___pa3___width 1
+#define reg_gio_r_intr___pa3___bit 3
+#define reg_gio_r_intr___pa4___lsb 4
+#define reg_gio_r_intr___pa4___width 1
+#define reg_gio_r_intr___pa4___bit 4
+#define reg_gio_r_intr___pa5___lsb 5
+#define reg_gio_r_intr___pa5___width 1
+#define reg_gio_r_intr___pa5___bit 5
+#define reg_gio_r_intr___pa6___lsb 6
+#define reg_gio_r_intr___pa6___width 1
+#define reg_gio_r_intr___pa6___bit 6
+#define reg_gio_r_intr___pa7___lsb 7
+#define reg_gio_r_intr___pa7___width 1
+#define reg_gio_r_intr___pa7___bit 7
+#define reg_gio_r_intr_offset 24
+
+/* Register r_masked_intr, scope gio, type r */
+#define reg_gio_r_masked_intr___pa0___lsb 0
+#define reg_gio_r_masked_intr___pa0___width 1
+#define reg_gio_r_masked_intr___pa0___bit 0
+#define reg_gio_r_masked_intr___pa1___lsb 1
+#define reg_gio_r_masked_intr___pa1___width 1
+#define reg_gio_r_masked_intr___pa1___bit 1
+#define reg_gio_r_masked_intr___pa2___lsb 2
+#define reg_gio_r_masked_intr___pa2___width 1
+#define reg_gio_r_masked_intr___pa2___bit 2
+#define reg_gio_r_masked_intr___pa3___lsb 3
+#define reg_gio_r_masked_intr___pa3___width 1
+#define reg_gio_r_masked_intr___pa3___bit 3
+#define reg_gio_r_masked_intr___pa4___lsb 4
+#define reg_gio_r_masked_intr___pa4___width 1
+#define reg_gio_r_masked_intr___pa4___bit 4
+#define reg_gio_r_masked_intr___pa5___lsb 5
+#define reg_gio_r_masked_intr___pa5___width 1
+#define reg_gio_r_masked_intr___pa5___bit 5
+#define reg_gio_r_masked_intr___pa6___lsb 6
+#define reg_gio_r_masked_intr___pa6___width 1
+#define reg_gio_r_masked_intr___pa6___bit 6
+#define reg_gio_r_masked_intr___pa7___lsb 7
+#define reg_gio_r_masked_intr___pa7___width 1
+#define reg_gio_r_masked_intr___pa7___bit 7
+#define reg_gio_r_masked_intr_offset 28
+
+/* Register rw_pb_dout, scope gio, type rw */
+#define reg_gio_rw_pb_dout___data___lsb 0
+#define reg_gio_rw_pb_dout___data___width 18
+#define reg_gio_rw_pb_dout_offset 32
+
+/* Register r_pb_din, scope gio, type r */
+#define reg_gio_r_pb_din___data___lsb 0
+#define reg_gio_r_pb_din___data___width 18
+#define reg_gio_r_pb_din_offset 36
+
+/* Register rw_pb_oe, scope gio, type rw */
+#define reg_gio_rw_pb_oe___oe___lsb 0
+#define reg_gio_rw_pb_oe___oe___width 18
+#define reg_gio_rw_pb_oe_offset 40
+
+/* Register rw_pc_dout, scope gio, type rw */
+#define reg_gio_rw_pc_dout___data___lsb 0
+#define reg_gio_rw_pc_dout___data___width 18
+#define reg_gio_rw_pc_dout_offset 48
+
+/* Register r_pc_din, scope gio, type r */
+#define reg_gio_r_pc_din___data___lsb 0
+#define reg_gio_r_pc_din___data___width 18
+#define reg_gio_r_pc_din_offset 52
+
+/* Register rw_pc_oe, scope gio, type rw */
+#define reg_gio_rw_pc_oe___oe___lsb 0
+#define reg_gio_rw_pc_oe___oe___width 18
+#define reg_gio_rw_pc_oe_offset 56
+
+/* Register rw_pd_dout, scope gio, type rw */
+#define reg_gio_rw_pd_dout___data___lsb 0
+#define reg_gio_rw_pd_dout___data___width 18
+#define reg_gio_rw_pd_dout_offset 64
+
+/* Register r_pd_din, scope gio, type r */
+#define reg_gio_r_pd_din___data___lsb 0
+#define reg_gio_r_pd_din___data___width 18
+#define reg_gio_r_pd_din_offset 68
+
+/* Register rw_pd_oe, scope gio, type rw */
+#define reg_gio_rw_pd_oe___oe___lsb 0
+#define reg_gio_rw_pd_oe___oe___width 18
+#define reg_gio_rw_pd_oe_offset 72
+
+/* Register rw_pe_dout, scope gio, type rw */
+#define reg_gio_rw_pe_dout___data___lsb 0
+#define reg_gio_rw_pe_dout___data___width 18
+#define reg_gio_rw_pe_dout_offset 80
+
+/* Register r_pe_din, scope gio, type r */
+#define reg_gio_r_pe_din___data___lsb 0
+#define reg_gio_r_pe_din___data___width 18
+#define reg_gio_r_pe_din_offset 84
+
+/* Register rw_pe_oe, scope gio, type rw */
+#define reg_gio_rw_pe_oe___oe___lsb 0
+#define reg_gio_rw_pe_oe___oe___width 18
+#define reg_gio_rw_pe_oe_offset 88
+
+
+/* Constants */
+#define regk_gio_anyedge                          0x00000007
+#define regk_gio_hi                               0x00000001
+#define regk_gio_lo                               0x00000002
+#define regk_gio_negedge                          0x00000006
+#define regk_gio_no                               0x00000000
+#define regk_gio_off                              0x00000000
+#define regk_gio_posedge                          0x00000005
+#define regk_gio_rw_intr_cfg_default              0x00000000
+#define regk_gio_rw_intr_mask_default             0x00000000
+#define regk_gio_rw_pa_oe_default                 0x00000000
+#define regk_gio_rw_pb_oe_default                 0x00000000
+#define regk_gio_rw_pc_oe_default                 0x00000000
+#define regk_gio_rw_pd_oe_default                 0x00000000
+#define regk_gio_rw_pe_oe_default                 0x00000000
+#define regk_gio_set                              0x00000003
+#define regk_gio_yes                              0x00000001
+#endif /* __gio_defs_asm_h */
diff --git a/include/asm-cris/arch-v32/hwregs/asm/intr_vect.h b/include/asm-cris/arch-v32/hwregs/asm/intr_vect.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/asm/intr_vect.h
@@ -0,0 +1,38 @@
+/* Interrupt vector numbers autogenerated by /n/asic/design/tools/rdesc/src/rdes2intr version
+ from ../../inst/intr_vect/rtl/guinness/ivmask.config.r
+version . */
+
+#ifndef _______INST_INTR_VECT_RTL_GUINNESS_IVMASK_CONFIG_R
+#define _______INST_INTR_VECT_RTL_GUINNESS_IVMASK_CONFIG_R
+#define MEMARB_INTR_VECT	0x31
+#define GEN_IO_INTR_VECT	0x32
+#define IOP0_INTR_VECT	0x33
+#define IOP1_INTR_VECT	0x34
+#define IOP2_INTR_VECT	0x35
+#define IOP3_INTR_VECT	0x36
+#define DMA0_INTR_VECT	0x37
+#define DMA1_INTR_VECT	0x38
+#define DMA2_INTR_VECT	0x39
+#define DMA3_INTR_VECT	0x3a
+#define DMA4_INTR_VECT	0x3b
+#define DMA5_INTR_VECT	0x3c
+#define DMA6_INTR_VECT	0x3d
+#define DMA7_INTR_VECT	0x3e
+#define DMA8_INTR_VECT	0x3f
+#define DMA9_INTR_VECT	0x40
+#define ATA_INTR_VECT	0x41
+#define SSER0_INTR_VECT	0x42
+#define SSER1_INTR_VECT	0x43
+#define SER0_INTR_VECT	0x44
+#define SER1_INTR_VECT	0x45
+#define SER2_INTR_VECT	0x46
+#define SER3_INTR_VECT	0x47
+#define P21_INTR_VECT	0x48
+#define ETH0_INTR_VECT	0x49
+#define ETH1_INTR_VECT	0x4a
+#define TIMER_INTR_VECT	0x4b
+#define BIF_ARB_INTR_VECT	0x4c
+#define BIF_DMA_INTR_VECT	0x4d
+#define EXT_INTR_VECT	0x4e
+
+#endif
diff --git a/include/asm-cris/arch-v32/hwregs/asm/intr_vect_defs_asm.h b/include/asm-cris/arch-v32/hwregs/asm/intr_vect_defs_asm.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/asm/intr_vect_defs_asm.h
@@ -0,0 +1,355 @@
+#ifndef __intr_vect_defs_asm_h
+#define __intr_vect_defs_asm_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/intr_vect/rtl/guinness/ivmask.config.r
+ *     id:           ivmask.config.r,v 1.4 2005/02/15 16:05:38 stefans Exp
+ *     last modfied: Mon Apr 11 16:08:03 2005
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c -asm --outfile asm/intr_vect_defs_asm.h ../../inst/intr_vect/rtl/guinness/ivmask.config.r
+ *      id: $Id: intr_vect_defs_asm.h,v 1.1 2005/04/24 18:31:04 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+
+#ifndef REG_FIELD
+#define REG_FIELD( scope, reg, field, value ) \
+  REG_FIELD_X_( value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_FIELD_X_( value, shift ) ((value) << shift)
+#endif
+
+#ifndef REG_STATE
+#define REG_STATE( scope, reg, field, symbolic_value ) \
+  REG_STATE_X_( regk_##scope##_##symbolic_value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_STATE_X_( k, shift ) (k << shift)
+#endif
+
+#ifndef REG_MASK
+#define REG_MASK( scope, reg, field ) \
+  REG_MASK_X_( reg_##scope##_##reg##___##field##___width, reg_##scope##_##reg##___##field##___lsb )
+#define REG_MASK_X_( width, lsb ) (((1 << width)-1) << lsb)
+#endif
+
+#ifndef REG_LSB
+#define REG_LSB( scope, reg, field ) reg_##scope##_##reg##___##field##___lsb
+#endif
+
+#ifndef REG_BIT
+#define REG_BIT( scope, reg, field ) reg_##scope##_##reg##___##field##___bit
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) REG_ADDR_X_(inst, reg_##scope##_##reg##_offset)
+#define REG_ADDR_X_( inst, offs ) ((inst) + offs)
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+         REG_ADDR_VECT_X_(inst, reg_##scope##_##reg##_offset, index, \
+			 STRIDE_##scope##_##reg )
+#define REG_ADDR_VECT_X_( inst, offs, index, stride ) \
+                          ((inst) + offs + (index) * stride)
+#endif
+
+/* Register rw_mask, scope intr_vect, type rw */
+#define reg_intr_vect_rw_mask___memarb___lsb 0
+#define reg_intr_vect_rw_mask___memarb___width 1
+#define reg_intr_vect_rw_mask___memarb___bit 0
+#define reg_intr_vect_rw_mask___gen_io___lsb 1
+#define reg_intr_vect_rw_mask___gen_io___width 1
+#define reg_intr_vect_rw_mask___gen_io___bit 1
+#define reg_intr_vect_rw_mask___iop0___lsb 2
+#define reg_intr_vect_rw_mask___iop0___width 1
+#define reg_intr_vect_rw_mask___iop0___bit 2
+#define reg_intr_vect_rw_mask___iop1___lsb 3
+#define reg_intr_vect_rw_mask___iop1___width 1
+#define reg_intr_vect_rw_mask___iop1___bit 3
+#define reg_intr_vect_rw_mask___iop2___lsb 4
+#define reg_intr_vect_rw_mask___iop2___width 1
+#define reg_intr_vect_rw_mask___iop2___bit 4
+#define reg_intr_vect_rw_mask___iop3___lsb 5
+#define reg_intr_vect_rw_mask___iop3___width 1
+#define reg_intr_vect_rw_mask___iop3___bit 5
+#define reg_intr_vect_rw_mask___dma0___lsb 6
+#define reg_intr_vect_rw_mask___dma0___width 1
+#define reg_intr_vect_rw_mask___dma0___bit 6
+#define reg_intr_vect_rw_mask___dma1___lsb 7
+#define reg_intr_vect_rw_mask___dma1___width 1
+#define reg_intr_vect_rw_mask___dma1___bit 7
+#define reg_intr_vect_rw_mask___dma2___lsb 8
+#define reg_intr_vect_rw_mask___dma2___width 1
+#define reg_intr_vect_rw_mask___dma2___bit 8
+#define reg_intr_vect_rw_mask___dma3___lsb 9
+#define reg_intr_vect_rw_mask___dma3___width 1
+#define reg_intr_vect_rw_mask___dma3___bit 9
+#define reg_intr_vect_rw_mask___dma4___lsb 10
+#define reg_intr_vect_rw_mask___dma4___width 1
+#define reg_intr_vect_rw_mask___dma4___bit 10
+#define reg_intr_vect_rw_mask___dma5___lsb 11
+#define reg_intr_vect_rw_mask___dma5___width 1
+#define reg_intr_vect_rw_mask___dma5___bit 11
+#define reg_intr_vect_rw_mask___dma6___lsb 12
+#define reg_intr_vect_rw_mask___dma6___width 1
+#define reg_intr_vect_rw_mask___dma6___bit 12
+#define reg_intr_vect_rw_mask___dma7___lsb 13
+#define reg_intr_vect_rw_mask___dma7___width 1
+#define reg_intr_vect_rw_mask___dma7___bit 13
+#define reg_intr_vect_rw_mask___dma8___lsb 14
+#define reg_intr_vect_rw_mask___dma8___width 1
+#define reg_intr_vect_rw_mask___dma8___bit 14
+#define reg_intr_vect_rw_mask___dma9___lsb 15
+#define reg_intr_vect_rw_mask___dma9___width 1
+#define reg_intr_vect_rw_mask___dma9___bit 15
+#define reg_intr_vect_rw_mask___ata___lsb 16
+#define reg_intr_vect_rw_mask___ata___width 1
+#define reg_intr_vect_rw_mask___ata___bit 16
+#define reg_intr_vect_rw_mask___sser0___lsb 17
+#define reg_intr_vect_rw_mask___sser0___width 1
+#define reg_intr_vect_rw_mask___sser0___bit 17
+#define reg_intr_vect_rw_mask___sser1___lsb 18
+#define reg_intr_vect_rw_mask___sser1___width 1
+#define reg_intr_vect_rw_mask___sser1___bit 18
+#define reg_intr_vect_rw_mask___ser0___lsb 19
+#define reg_intr_vect_rw_mask___ser0___width 1
+#define reg_intr_vect_rw_mask___ser0___bit 19
+#define reg_intr_vect_rw_mask___ser1___lsb 20
+#define reg_intr_vect_rw_mask___ser1___width 1
+#define reg_intr_vect_rw_mask___ser1___bit 20
+#define reg_intr_vect_rw_mask___ser2___lsb 21
+#define reg_intr_vect_rw_mask___ser2___width 1
+#define reg_intr_vect_rw_mask___ser2___bit 21
+#define reg_intr_vect_rw_mask___ser3___lsb 22
+#define reg_intr_vect_rw_mask___ser3___width 1
+#define reg_intr_vect_rw_mask___ser3___bit 22
+#define reg_intr_vect_rw_mask___p21___lsb 23
+#define reg_intr_vect_rw_mask___p21___width 1
+#define reg_intr_vect_rw_mask___p21___bit 23
+#define reg_intr_vect_rw_mask___eth0___lsb 24
+#define reg_intr_vect_rw_mask___eth0___width 1
+#define reg_intr_vect_rw_mask___eth0___bit 24
+#define reg_intr_vect_rw_mask___eth1___lsb 25
+#define reg_intr_vect_rw_mask___eth1___width 1
+#define reg_intr_vect_rw_mask___eth1___bit 25
+#define reg_intr_vect_rw_mask___timer___lsb 26
+#define reg_intr_vect_rw_mask___timer___width 1
+#define reg_intr_vect_rw_mask___timer___bit 26
+#define reg_intr_vect_rw_mask___bif_arb___lsb 27
+#define reg_intr_vect_rw_mask___bif_arb___width 1
+#define reg_intr_vect_rw_mask___bif_arb___bit 27
+#define reg_intr_vect_rw_mask___bif_dma___lsb 28
+#define reg_intr_vect_rw_mask___bif_dma___width 1
+#define reg_intr_vect_rw_mask___bif_dma___bit 28
+#define reg_intr_vect_rw_mask___ext___lsb 29
+#define reg_intr_vect_rw_mask___ext___width 1
+#define reg_intr_vect_rw_mask___ext___bit 29
+#define reg_intr_vect_rw_mask_offset 0
+
+/* Register r_vect, scope intr_vect, type r */
+#define reg_intr_vect_r_vect___memarb___lsb 0
+#define reg_intr_vect_r_vect___memarb___width 1
+#define reg_intr_vect_r_vect___memarb___bit 0
+#define reg_intr_vect_r_vect___gen_io___lsb 1
+#define reg_intr_vect_r_vect___gen_io___width 1
+#define reg_intr_vect_r_vect___gen_io___bit 1
+#define reg_intr_vect_r_vect___iop0___lsb 2
+#define reg_intr_vect_r_vect___iop0___width 1
+#define reg_intr_vect_r_vect___iop0___bit 2
+#define reg_intr_vect_r_vect___iop1___lsb 3
+#define reg_intr_vect_r_vect___iop1___width 1
+#define reg_intr_vect_r_vect___iop1___bit 3
+#define reg_intr_vect_r_vect___iop2___lsb 4
+#define reg_intr_vect_r_vect___iop2___width 1
+#define reg_intr_vect_r_vect___iop2___bit 4
+#define reg_intr_vect_r_vect___iop3___lsb 5
+#define reg_intr_vect_r_vect___iop3___width 1
+#define reg_intr_vect_r_vect___iop3___bit 5
+#define reg_intr_vect_r_vect___dma0___lsb 6
+#define reg_intr_vect_r_vect___dma0___width 1
+#define reg_intr_vect_r_vect___dma0___bit 6
+#define reg_intr_vect_r_vect___dma1___lsb 7
+#define reg_intr_vect_r_vect___dma1___width 1
+#define reg_intr_vect_r_vect___dma1___bit 7
+#define reg_intr_vect_r_vect___dma2___lsb 8
+#define reg_intr_vect_r_vect___dma2___width 1
+#define reg_intr_vect_r_vect___dma2___bit 8
+#define reg_intr_vect_r_vect___dma3___lsb 9
+#define reg_intr_vect_r_vect___dma3___width 1
+#define reg_intr_vect_r_vect___dma3___bit 9
+#define reg_intr_vect_r_vect___dma4___lsb 10
+#define reg_intr_vect_r_vect___dma4___width 1
+#define reg_intr_vect_r_vect___dma4___bit 10
+#define reg_intr_vect_r_vect___dma5___lsb 11
+#define reg_intr_vect_r_vect___dma5___width 1
+#define reg_intr_vect_r_vect___dma5___bit 11
+#define reg_intr_vect_r_vect___dma6___lsb 12
+#define reg_intr_vect_r_vect___dma6___width 1
+#define reg_intr_vect_r_vect___dma6___bit 12
+#define reg_intr_vect_r_vect___dma7___lsb 13
+#define reg_intr_vect_r_vect___dma7___width 1
+#define reg_intr_vect_r_vect___dma7___bit 13
+#define reg_intr_vect_r_vect___dma8___lsb 14
+#define reg_intr_vect_r_vect___dma8___width 1
+#define reg_intr_vect_r_vect___dma8___bit 14
+#define reg_intr_vect_r_vect___dma9___lsb 15
+#define reg_intr_vect_r_vect___dma9___width 1
+#define reg_intr_vect_r_vect___dma9___bit 15
+#define reg_intr_vect_r_vect___ata___lsb 16
+#define reg_intr_vect_r_vect___ata___width 1
+#define reg_intr_vect_r_vect___ata___bit 16
+#define reg_intr_vect_r_vect___sser0___lsb 17
+#define reg_intr_vect_r_vect___sser0___width 1
+#define reg_intr_vect_r_vect___sser0___bit 17
+#define reg_intr_vect_r_vect___sser1___lsb 18
+#define reg_intr_vect_r_vect___sser1___width 1
+#define reg_intr_vect_r_vect___sser1___bit 18
+#define reg_intr_vect_r_vect___ser0___lsb 19
+#define reg_intr_vect_r_vect___ser0___width 1
+#define reg_intr_vect_r_vect___ser0___bit 19
+#define reg_intr_vect_r_vect___ser1___lsb 20
+#define reg_intr_vect_r_vect___ser1___width 1
+#define reg_intr_vect_r_vect___ser1___bit 20
+#define reg_intr_vect_r_vect___ser2___lsb 21
+#define reg_intr_vect_r_vect___ser2___width 1
+#define reg_intr_vect_r_vect___ser2___bit 21
+#define reg_intr_vect_r_vect___ser3___lsb 22
+#define reg_intr_vect_r_vect___ser3___width 1
+#define reg_intr_vect_r_vect___ser3___bit 22
+#define reg_intr_vect_r_vect___p21___lsb 23
+#define reg_intr_vect_r_vect___p21___width 1
+#define reg_intr_vect_r_vect___p21___bit 23
+#define reg_intr_vect_r_vect___eth0___lsb 24
+#define reg_intr_vect_r_vect___eth0___width 1
+#define reg_intr_vect_r_vect___eth0___bit 24
+#define reg_intr_vect_r_vect___eth1___lsb 25
+#define reg_intr_vect_r_vect___eth1___width 1
+#define reg_intr_vect_r_vect___eth1___bit 25
+#define reg_intr_vect_r_vect___timer___lsb 26
+#define reg_intr_vect_r_vect___timer___width 1
+#define reg_intr_vect_r_vect___timer___bit 26
+#define reg_intr_vect_r_vect___bif_arb___lsb 27
+#define reg_intr_vect_r_vect___bif_arb___width 1
+#define reg_intr_vect_r_vect___bif_arb___bit 27
+#define reg_intr_vect_r_vect___bif_dma___lsb 28
+#define reg_intr_vect_r_vect___bif_dma___width 1
+#define reg_intr_vect_r_vect___bif_dma___bit 28
+#define reg_intr_vect_r_vect___ext___lsb 29
+#define reg_intr_vect_r_vect___ext___width 1
+#define reg_intr_vect_r_vect___ext___bit 29
+#define reg_intr_vect_r_vect_offset 4
+
+/* Register r_masked_vect, scope intr_vect, type r */
+#define reg_intr_vect_r_masked_vect___memarb___lsb 0
+#define reg_intr_vect_r_masked_vect___memarb___width 1
+#define reg_intr_vect_r_masked_vect___memarb___bit 0
+#define reg_intr_vect_r_masked_vect___gen_io___lsb 1
+#define reg_intr_vect_r_masked_vect___gen_io___width 1
+#define reg_intr_vect_r_masked_vect___gen_io___bit 1
+#define reg_intr_vect_r_masked_vect___iop0___lsb 2
+#define reg_intr_vect_r_masked_vect___iop0___width 1
+#define reg_intr_vect_r_masked_vect___iop0___bit 2
+#define reg_intr_vect_r_masked_vect___iop1___lsb 3
+#define reg_intr_vect_r_masked_vect___iop1___width 1
+#define reg_intr_vect_r_masked_vect___iop1___bit 3
+#define reg_intr_vect_r_masked_vect___iop2___lsb 4
+#define reg_intr_vect_r_masked_vect___iop2___width 1
+#define reg_intr_vect_r_masked_vect___iop2___bit 4
+#define reg_intr_vect_r_masked_vect___iop3___lsb 5
+#define reg_intr_vect_r_masked_vect___iop3___width 1
+#define reg_intr_vect_r_masked_vect___iop3___bit 5
+#define reg_intr_vect_r_masked_vect___dma0___lsb 6
+#define reg_intr_vect_r_masked_vect___dma0___width 1
+#define reg_intr_vect_r_masked_vect___dma0___bit 6
+#define reg_intr_vect_r_masked_vect___dma1___lsb 7
+#define reg_intr_vect_r_masked_vect___dma1___width 1
+#define reg_intr_vect_r_masked_vect___dma1___bit 7
+#define reg_intr_vect_r_masked_vect___dma2___lsb 8
+#define reg_intr_vect_r_masked_vect___dma2___width 1
+#define reg_intr_vect_r_masked_vect___dma2___bit 8
+#define reg_intr_vect_r_masked_vect___dma3___lsb 9
+#define reg_intr_vect_r_masked_vect___dma3___width 1
+#define reg_intr_vect_r_masked_vect___dma3___bit 9
+#define reg_intr_vect_r_masked_vect___dma4___lsb 10
+#define reg_intr_vect_r_masked_vect___dma4___width 1
+#define reg_intr_vect_r_masked_vect___dma4___bit 10
+#define reg_intr_vect_r_masked_vect___dma5___lsb 11
+#define reg_intr_vect_r_masked_vect___dma5___width 1
+#define reg_intr_vect_r_masked_vect___dma5___bit 11
+#define reg_intr_vect_r_masked_vect___dma6___lsb 12
+#define reg_intr_vect_r_masked_vect___dma6___width 1
+#define reg_intr_vect_r_masked_vect___dma6___bit 12
+#define reg_intr_vect_r_masked_vect___dma7___lsb 13
+#define reg_intr_vect_r_masked_vect___dma7___width 1
+#define reg_intr_vect_r_masked_vect___dma7___bit 13
+#define reg_intr_vect_r_masked_vect___dma8___lsb 14
+#define reg_intr_vect_r_masked_vect___dma8___width 1
+#define reg_intr_vect_r_masked_vect___dma8___bit 14
+#define reg_intr_vect_r_masked_vect___dma9___lsb 15
+#define reg_intr_vect_r_masked_vect___dma9___width 1
+#define reg_intr_vect_r_masked_vect___dma9___bit 15
+#define reg_intr_vect_r_masked_vect___ata___lsb 16
+#define reg_intr_vect_r_masked_vect___ata___width 1
+#define reg_intr_vect_r_masked_vect___ata___bit 16
+#define reg_intr_vect_r_masked_vect___sser0___lsb 17
+#define reg_intr_vect_r_masked_vect___sser0___width 1
+#define reg_intr_vect_r_masked_vect___sser0___bit 17
+#define reg_intr_vect_r_masked_vect___sser1___lsb 18
+#define reg_intr_vect_r_masked_vect___sser1___width 1
+#define reg_intr_vect_r_masked_vect___sser1___bit 18
+#define reg_intr_vect_r_masked_vect___ser0___lsb 19
+#define reg_intr_vect_r_masked_vect___ser0___width 1
+#define reg_intr_vect_r_masked_vect___ser0___bit 19
+#define reg_intr_vect_r_masked_vect___ser1___lsb 20
+#define reg_intr_vect_r_masked_vect___ser1___width 1
+#define reg_intr_vect_r_masked_vect___ser1___bit 20
+#define reg_intr_vect_r_masked_vect___ser2___lsb 21
+#define reg_intr_vect_r_masked_vect___ser2___width 1
+#define reg_intr_vect_r_masked_vect___ser2___bit 21
+#define reg_intr_vect_r_masked_vect___ser3___lsb 22
+#define reg_intr_vect_r_masked_vect___ser3___width 1
+#define reg_intr_vect_r_masked_vect___ser3___bit 22
+#define reg_intr_vect_r_masked_vect___p21___lsb 23
+#define reg_intr_vect_r_masked_vect___p21___width 1
+#define reg_intr_vect_r_masked_vect___p21___bit 23
+#define reg_intr_vect_r_masked_vect___eth0___lsb 24
+#define reg_intr_vect_r_masked_vect___eth0___width 1
+#define reg_intr_vect_r_masked_vect___eth0___bit 24
+#define reg_intr_vect_r_masked_vect___eth1___lsb 25
+#define reg_intr_vect_r_masked_vect___eth1___width 1
+#define reg_intr_vect_r_masked_vect___eth1___bit 25
+#define reg_intr_vect_r_masked_vect___timer___lsb 26
+#define reg_intr_vect_r_masked_vect___timer___width 1
+#define reg_intr_vect_r_masked_vect___timer___bit 26
+#define reg_intr_vect_r_masked_vect___bif_arb___lsb 27
+#define reg_intr_vect_r_masked_vect___bif_arb___width 1
+#define reg_intr_vect_r_masked_vect___bif_arb___bit 27
+#define reg_intr_vect_r_masked_vect___bif_dma___lsb 28
+#define reg_intr_vect_r_masked_vect___bif_dma___width 1
+#define reg_intr_vect_r_masked_vect___bif_dma___bit 28
+#define reg_intr_vect_r_masked_vect___ext___lsb 29
+#define reg_intr_vect_r_masked_vect___ext___width 1
+#define reg_intr_vect_r_masked_vect___ext___bit 29
+#define reg_intr_vect_r_masked_vect_offset 8
+
+/* Register r_nmi, scope intr_vect, type r */
+#define reg_intr_vect_r_nmi___ext___lsb 0
+#define reg_intr_vect_r_nmi___ext___width 1
+#define reg_intr_vect_r_nmi___ext___bit 0
+#define reg_intr_vect_r_nmi___watchdog___lsb 1
+#define reg_intr_vect_r_nmi___watchdog___width 1
+#define reg_intr_vect_r_nmi___watchdog___bit 1
+#define reg_intr_vect_r_nmi_offset 12
+
+/* Register r_guru, scope intr_vect, type r */
+#define reg_intr_vect_r_guru___jtag___lsb 0
+#define reg_intr_vect_r_guru___jtag___width 1
+#define reg_intr_vect_r_guru___jtag___bit 0
+#define reg_intr_vect_r_guru_offset 16
+
+
+/* Constants */
+#define regk_intr_vect_off                        0x00000000
+#define regk_intr_vect_on                         0x00000001
+#define regk_intr_vect_rw_mask_default            0x00000000
+#endif /* __intr_vect_defs_asm_h */
diff --git a/include/asm-cris/arch-v32/hwregs/asm/irq_nmi_defs_asm.h b/include/asm-cris/arch-v32/hwregs/asm/irq_nmi_defs_asm.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/asm/irq_nmi_defs_asm.h
@@ -0,0 +1,69 @@
+#ifndef __irq_nmi_defs_asm_h
+#define __irq_nmi_defs_asm_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../mod/irq_nmi.r
+ *     id:           <not found>
+ *     last modfied: Thu Jan 22 09:22:43 2004
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c -asm --outfile asm/irq_nmi_defs_asm.h ../../mod/irq_nmi.r
+ *      id: $Id: irq_nmi_defs_asm.h,v 1.1 2005/04/24 18:31:04 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+
+#ifndef REG_FIELD
+#define REG_FIELD( scope, reg, field, value ) \
+  REG_FIELD_X_( value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_FIELD_X_( value, shift ) ((value) << shift)
+#endif
+
+#ifndef REG_STATE
+#define REG_STATE( scope, reg, field, symbolic_value ) \
+  REG_STATE_X_( regk_##scope##_##symbolic_value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_STATE_X_( k, shift ) (k << shift)
+#endif
+
+#ifndef REG_MASK
+#define REG_MASK( scope, reg, field ) \
+  REG_MASK_X_( reg_##scope##_##reg##___##field##___width, reg_##scope##_##reg##___##field##___lsb )
+#define REG_MASK_X_( width, lsb ) (((1 << width)-1) << lsb)
+#endif
+
+#ifndef REG_LSB
+#define REG_LSB( scope, reg, field ) reg_##scope##_##reg##___##field##___lsb
+#endif
+
+#ifndef REG_BIT
+#define REG_BIT( scope, reg, field ) reg_##scope##_##reg##___##field##___bit
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) REG_ADDR_X_(inst, reg_##scope##_##reg##_offset)
+#define REG_ADDR_X_( inst, offs ) ((inst) + offs)
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+         REG_ADDR_VECT_X_(inst, reg_##scope##_##reg##_offset, index, \
+			 STRIDE_##scope##_##reg )
+#define REG_ADDR_VECT_X_( inst, offs, index, stride ) \
+                          ((inst) + offs + (index) * stride)
+#endif
+
+/* Register rw_cmd, scope irq_nmi, type rw */
+#define reg_irq_nmi_rw_cmd___delay___lsb 0
+#define reg_irq_nmi_rw_cmd___delay___width 16
+#define reg_irq_nmi_rw_cmd___op___lsb 16
+#define reg_irq_nmi_rw_cmd___op___width 2
+#define reg_irq_nmi_rw_cmd_offset 0
+
+
+/* Constants */
+#define regk_irq_nmi_ack_irq                      0x00000002
+#define regk_irq_nmi_ack_nmi                      0x00000003
+#define regk_irq_nmi_irq                          0x00000000
+#define regk_irq_nmi_nmi                          0x00000001
+#endif /* __irq_nmi_defs_asm_h */
diff --git a/include/asm-cris/arch-v32/hwregs/asm/marb_defs_asm.h b/include/asm-cris/arch-v32/hwregs/asm/marb_defs_asm.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/asm/marb_defs_asm.h
@@ -0,0 +1,579 @@
+#ifndef __marb_defs_asm_h
+#define __marb_defs_asm_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/memarb/rtl/guinness/marb_top.r
+ *     id:           <not found>
+ *     last modfied: Mon Apr 11 16:12:16 2005
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c -asm --outfile asm/marb_defs_asm.h ../../inst/memarb/rtl/guinness/marb_top.r
+ *      id: $Id: marb_defs_asm.h,v 1.1 2005/04/24 18:31:04 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+
+#ifndef REG_FIELD
+#define REG_FIELD( scope, reg, field, value ) \
+  REG_FIELD_X_( value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_FIELD_X_( value, shift ) ((value) << shift)
+#endif
+
+#ifndef REG_STATE
+#define REG_STATE( scope, reg, field, symbolic_value ) \
+  REG_STATE_X_( regk_##scope##_##symbolic_value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_STATE_X_( k, shift ) (k << shift)
+#endif
+
+#ifndef REG_MASK
+#define REG_MASK( scope, reg, field ) \
+  REG_MASK_X_( reg_##scope##_##reg##___##field##___width, reg_##scope##_##reg##___##field##___lsb )
+#define REG_MASK_X_( width, lsb ) (((1 << width)-1) << lsb)
+#endif
+
+#ifndef REG_LSB
+#define REG_LSB( scope, reg, field ) reg_##scope##_##reg##___##field##___lsb
+#endif
+
+#ifndef REG_BIT
+#define REG_BIT( scope, reg, field ) reg_##scope##_##reg##___##field##___bit
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) REG_ADDR_X_(inst, reg_##scope##_##reg##_offset)
+#define REG_ADDR_X_( inst, offs ) ((inst) + offs)
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+         REG_ADDR_VECT_X_(inst, reg_##scope##_##reg##_offset, index, \
+			 STRIDE_##scope##_##reg )
+#define REG_ADDR_VECT_X_( inst, offs, index, stride ) \
+                          ((inst) + offs + (index) * stride)
+#endif
+
+#define STRIDE_marb_rw_int_slots 4
+/* Register rw_int_slots, scope marb, type rw */
+#define reg_marb_rw_int_slots___owner___lsb 0
+#define reg_marb_rw_int_slots___owner___width 4
+#define reg_marb_rw_int_slots_offset 0
+
+#define STRIDE_marb_rw_ext_slots 4
+/* Register rw_ext_slots, scope marb, type rw */
+#define reg_marb_rw_ext_slots___owner___lsb 0
+#define reg_marb_rw_ext_slots___owner___width 4
+#define reg_marb_rw_ext_slots_offset 256
+
+#define STRIDE_marb_rw_regs_slots 4
+/* Register rw_regs_slots, scope marb, type rw */
+#define reg_marb_rw_regs_slots___owner___lsb 0
+#define reg_marb_rw_regs_slots___owner___width 4
+#define reg_marb_rw_regs_slots_offset 512
+
+/* Register rw_intr_mask, scope marb, type rw */
+#define reg_marb_rw_intr_mask___bp0___lsb 0
+#define reg_marb_rw_intr_mask___bp0___width 1
+#define reg_marb_rw_intr_mask___bp0___bit 0
+#define reg_marb_rw_intr_mask___bp1___lsb 1
+#define reg_marb_rw_intr_mask___bp1___width 1
+#define reg_marb_rw_intr_mask___bp1___bit 1
+#define reg_marb_rw_intr_mask___bp2___lsb 2
+#define reg_marb_rw_intr_mask___bp2___width 1
+#define reg_marb_rw_intr_mask___bp2___bit 2
+#define reg_marb_rw_intr_mask___bp3___lsb 3
+#define reg_marb_rw_intr_mask___bp3___width 1
+#define reg_marb_rw_intr_mask___bp3___bit 3
+#define reg_marb_rw_intr_mask_offset 528
+
+/* Register rw_ack_intr, scope marb, type rw */
+#define reg_marb_rw_ack_intr___bp0___lsb 0
+#define reg_marb_rw_ack_intr___bp0___width 1
+#define reg_marb_rw_ack_intr___bp0___bit 0
+#define reg_marb_rw_ack_intr___bp1___lsb 1
+#define reg_marb_rw_ack_intr___bp1___width 1
+#define reg_marb_rw_ack_intr___bp1___bit 1
+#define reg_marb_rw_ack_intr___bp2___lsb 2
+#define reg_marb_rw_ack_intr___bp2___width 1
+#define reg_marb_rw_ack_intr___bp2___bit 2
+#define reg_marb_rw_ack_intr___bp3___lsb 3
+#define reg_marb_rw_ack_intr___bp3___width 1
+#define reg_marb_rw_ack_intr___bp3___bit 3
+#define reg_marb_rw_ack_intr_offset 532
+
+/* Register r_intr, scope marb, type r */
+#define reg_marb_r_intr___bp0___lsb 0
+#define reg_marb_r_intr___bp0___width 1
+#define reg_marb_r_intr___bp0___bit 0
+#define reg_marb_r_intr___bp1___lsb 1
+#define reg_marb_r_intr___bp1___width 1
+#define reg_marb_r_intr___bp1___bit 1
+#define reg_marb_r_intr___bp2___lsb 2
+#define reg_marb_r_intr___bp2___width 1
+#define reg_marb_r_intr___bp2___bit 2
+#define reg_marb_r_intr___bp3___lsb 3
+#define reg_marb_r_intr___bp3___width 1
+#define reg_marb_r_intr___bp3___bit 3
+#define reg_marb_r_intr_offset 536
+
+/* Register r_masked_intr, scope marb, type r */
+#define reg_marb_r_masked_intr___bp0___lsb 0
+#define reg_marb_r_masked_intr___bp0___width 1
+#define reg_marb_r_masked_intr___bp0___bit 0
+#define reg_marb_r_masked_intr___bp1___lsb 1
+#define reg_marb_r_masked_intr___bp1___width 1
+#define reg_marb_r_masked_intr___bp1___bit 1
+#define reg_marb_r_masked_intr___bp2___lsb 2
+#define reg_marb_r_masked_intr___bp2___width 1
+#define reg_marb_r_masked_intr___bp2___bit 2
+#define reg_marb_r_masked_intr___bp3___lsb 3
+#define reg_marb_r_masked_intr___bp3___width 1
+#define reg_marb_r_masked_intr___bp3___bit 3
+#define reg_marb_r_masked_intr_offset 540
+
+/* Register rw_stop_mask, scope marb, type rw */
+#define reg_marb_rw_stop_mask___dma0___lsb 0
+#define reg_marb_rw_stop_mask___dma0___width 1
+#define reg_marb_rw_stop_mask___dma0___bit 0
+#define reg_marb_rw_stop_mask___dma1___lsb 1
+#define reg_marb_rw_stop_mask___dma1___width 1
+#define reg_marb_rw_stop_mask___dma1___bit 1
+#define reg_marb_rw_stop_mask___dma2___lsb 2
+#define reg_marb_rw_stop_mask___dma2___width 1
+#define reg_marb_rw_stop_mask___dma2___bit 2
+#define reg_marb_rw_stop_mask___dma3___lsb 3
+#define reg_marb_rw_stop_mask___dma3___width 1
+#define reg_marb_rw_stop_mask___dma3___bit 3
+#define reg_marb_rw_stop_mask___dma4___lsb 4
+#define reg_marb_rw_stop_mask___dma4___width 1
+#define reg_marb_rw_stop_mask___dma4___bit 4
+#define reg_marb_rw_stop_mask___dma5___lsb 5
+#define reg_marb_rw_stop_mask___dma5___width 1
+#define reg_marb_rw_stop_mask___dma5___bit 5
+#define reg_marb_rw_stop_mask___dma6___lsb 6
+#define reg_marb_rw_stop_mask___dma6___width 1
+#define reg_marb_rw_stop_mask___dma6___bit 6
+#define reg_marb_rw_stop_mask___dma7___lsb 7
+#define reg_marb_rw_stop_mask___dma7___width 1
+#define reg_marb_rw_stop_mask___dma7___bit 7
+#define reg_marb_rw_stop_mask___dma8___lsb 8
+#define reg_marb_rw_stop_mask___dma8___width 1
+#define reg_marb_rw_stop_mask___dma8___bit 8
+#define reg_marb_rw_stop_mask___dma9___lsb 9
+#define reg_marb_rw_stop_mask___dma9___width 1
+#define reg_marb_rw_stop_mask___dma9___bit 9
+#define reg_marb_rw_stop_mask___cpui___lsb 10
+#define reg_marb_rw_stop_mask___cpui___width 1
+#define reg_marb_rw_stop_mask___cpui___bit 10
+#define reg_marb_rw_stop_mask___cpud___lsb 11
+#define reg_marb_rw_stop_mask___cpud___width 1
+#define reg_marb_rw_stop_mask___cpud___bit 11
+#define reg_marb_rw_stop_mask___iop___lsb 12
+#define reg_marb_rw_stop_mask___iop___width 1
+#define reg_marb_rw_stop_mask___iop___bit 12
+#define reg_marb_rw_stop_mask___slave___lsb 13
+#define reg_marb_rw_stop_mask___slave___width 1
+#define reg_marb_rw_stop_mask___slave___bit 13
+#define reg_marb_rw_stop_mask_offset 544
+
+/* Register r_stopped, scope marb, type r */
+#define reg_marb_r_stopped___dma0___lsb 0
+#define reg_marb_r_stopped___dma0___width 1
+#define reg_marb_r_stopped___dma0___bit 0
+#define reg_marb_r_stopped___dma1___lsb 1
+#define reg_marb_r_stopped___dma1___width 1
+#define reg_marb_r_stopped___dma1___bit 1
+#define reg_marb_r_stopped___dma2___lsb 2
+#define reg_marb_r_stopped___dma2___width 1
+#define reg_marb_r_stopped___dma2___bit 2
+#define reg_marb_r_stopped___dma3___lsb 3
+#define reg_marb_r_stopped___dma3___width 1
+#define reg_marb_r_stopped___dma3___bit 3
+#define reg_marb_r_stopped___dma4___lsb 4
+#define reg_marb_r_stopped___dma4___width 1
+#define reg_marb_r_stopped___dma4___bit 4
+#define reg_marb_r_stopped___dma5___lsb 5
+#define reg_marb_r_stopped___dma5___width 1
+#define reg_marb_r_stopped___dma5___bit 5
+#define reg_marb_r_stopped___dma6___lsb 6
+#define reg_marb_r_stopped___dma6___width 1
+#define reg_marb_r_stopped___dma6___bit 6
+#define reg_marb_r_stopped___dma7___lsb 7
+#define reg_marb_r_stopped___dma7___width 1
+#define reg_marb_r_stopped___dma7___bit 7
+#define reg_marb_r_stopped___dma8___lsb 8
+#define reg_marb_r_stopped___dma8___width 1
+#define reg_marb_r_stopped___dma8___bit 8
+#define reg_marb_r_stopped___dma9___lsb 9
+#define reg_marb_r_stopped___dma9___width 1
+#define reg_marb_r_stopped___dma9___bit 9
+#define reg_marb_r_stopped___cpui___lsb 10
+#define reg_marb_r_stopped___cpui___width 1
+#define reg_marb_r_stopped___cpui___bit 10
+#define reg_marb_r_stopped___cpud___lsb 11
+#define reg_marb_r_stopped___cpud___width 1
+#define reg_marb_r_stopped___cpud___bit 11
+#define reg_marb_r_stopped___iop___lsb 12
+#define reg_marb_r_stopped___iop___width 1
+#define reg_marb_r_stopped___iop___bit 12
+#define reg_marb_r_stopped___slave___lsb 13
+#define reg_marb_r_stopped___slave___width 1
+#define reg_marb_r_stopped___slave___bit 13
+#define reg_marb_r_stopped_offset 548
+
+/* Register rw_no_snoop, scope marb, type rw */
+#define reg_marb_rw_no_snoop___dma0___lsb 0
+#define reg_marb_rw_no_snoop___dma0___width 1
+#define reg_marb_rw_no_snoop___dma0___bit 0
+#define reg_marb_rw_no_snoop___dma1___lsb 1
+#define reg_marb_rw_no_snoop___dma1___width 1
+#define reg_marb_rw_no_snoop___dma1___bit 1
+#define reg_marb_rw_no_snoop___dma2___lsb 2
+#define reg_marb_rw_no_snoop___dma2___width 1
+#define reg_marb_rw_no_snoop___dma2___bit 2
+#define reg_marb_rw_no_snoop___dma3___lsb 3
+#define reg_marb_rw_no_snoop___dma3___width 1
+#define reg_marb_rw_no_snoop___dma3___bit 3
+#define reg_marb_rw_no_snoop___dma4___lsb 4
+#define reg_marb_rw_no_snoop___dma4___width 1
+#define reg_marb_rw_no_snoop___dma4___bit 4
+#define reg_marb_rw_no_snoop___dma5___lsb 5
+#define reg_marb_rw_no_snoop___dma5___width 1
+#define reg_marb_rw_no_snoop___dma5___bit 5
+#define reg_marb_rw_no_snoop___dma6___lsb 6
+#define reg_marb_rw_no_snoop___dma6___width 1
+#define reg_marb_rw_no_snoop___dma6___bit 6
+#define reg_marb_rw_no_snoop___dma7___lsb 7
+#define reg_marb_rw_no_snoop___dma7___width 1
+#define reg_marb_rw_no_snoop___dma7___bit 7
+#define reg_marb_rw_no_snoop___dma8___lsb 8
+#define reg_marb_rw_no_snoop___dma8___width 1
+#define reg_marb_rw_no_snoop___dma8___bit 8
+#define reg_marb_rw_no_snoop___dma9___lsb 9
+#define reg_marb_rw_no_snoop___dma9___width 1
+#define reg_marb_rw_no_snoop___dma9___bit 9
+#define reg_marb_rw_no_snoop___cpui___lsb 10
+#define reg_marb_rw_no_snoop___cpui___width 1
+#define reg_marb_rw_no_snoop___cpui___bit 10
+#define reg_marb_rw_no_snoop___cpud___lsb 11
+#define reg_marb_rw_no_snoop___cpud___width 1
+#define reg_marb_rw_no_snoop___cpud___bit 11
+#define reg_marb_rw_no_snoop___iop___lsb 12
+#define reg_marb_rw_no_snoop___iop___width 1
+#define reg_marb_rw_no_snoop___iop___bit 12
+#define reg_marb_rw_no_snoop___slave___lsb 13
+#define reg_marb_rw_no_snoop___slave___width 1
+#define reg_marb_rw_no_snoop___slave___bit 13
+#define reg_marb_rw_no_snoop_offset 832
+
+/* Register rw_no_snoop_rq, scope marb, type rw */
+#define reg_marb_rw_no_snoop_rq___cpui___lsb 10
+#define reg_marb_rw_no_snoop_rq___cpui___width 1
+#define reg_marb_rw_no_snoop_rq___cpui___bit 10
+#define reg_marb_rw_no_snoop_rq___cpud___lsb 11
+#define reg_marb_rw_no_snoop_rq___cpud___width 1
+#define reg_marb_rw_no_snoop_rq___cpud___bit 11
+#define reg_marb_rw_no_snoop_rq_offset 836
+
+
+/* Constants */
+#define regk_marb_cpud                            0x0000000b
+#define regk_marb_cpui                            0x0000000a
+#define regk_marb_dma0                            0x00000000
+#define regk_marb_dma1                            0x00000001
+#define regk_marb_dma2                            0x00000002
+#define regk_marb_dma3                            0x00000003
+#define regk_marb_dma4                            0x00000004
+#define regk_marb_dma5                            0x00000005
+#define regk_marb_dma6                            0x00000006
+#define regk_marb_dma7                            0x00000007
+#define regk_marb_dma8                            0x00000008
+#define regk_marb_dma9                            0x00000009
+#define regk_marb_iop                             0x0000000c
+#define regk_marb_no                              0x00000000
+#define regk_marb_r_stopped_default               0x00000000
+#define regk_marb_rw_ext_slots_default            0x00000000
+#define regk_marb_rw_ext_slots_size               0x00000040
+#define regk_marb_rw_int_slots_default            0x00000000
+#define regk_marb_rw_int_slots_size               0x00000040
+#define regk_marb_rw_intr_mask_default            0x00000000
+#define regk_marb_rw_no_snoop_default             0x00000000
+#define regk_marb_rw_no_snoop_rq_default          0x00000000
+#define regk_marb_rw_regs_slots_default           0x00000000
+#define regk_marb_rw_regs_slots_size              0x00000004
+#define regk_marb_rw_stop_mask_default            0x00000000
+#define regk_marb_slave                           0x0000000d
+#define regk_marb_yes                             0x00000001
+#endif /* __marb_defs_asm_h */
+#ifndef __marb_bp_defs_asm_h
+#define __marb_bp_defs_asm_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/memarb/rtl/guinness/marb_top.r
+ *     id:           <not found>
+ *     last modfied: Mon Apr 11 16:12:16 2005
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c -asm --outfile asm/marb_defs_asm.h ../../inst/memarb/rtl/guinness/marb_top.r
+ *      id: $Id: marb_defs_asm.h,v 1.1 2005/04/24 18:31:04 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+
+#ifndef REG_FIELD
+#define REG_FIELD( scope, reg, field, value ) \
+  REG_FIELD_X_( value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_FIELD_X_( value, shift ) ((value) << shift)
+#endif
+
+#ifndef REG_STATE
+#define REG_STATE( scope, reg, field, symbolic_value ) \
+  REG_STATE_X_( regk_##scope##_##symbolic_value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_STATE_X_( k, shift ) (k << shift)
+#endif
+
+#ifndef REG_MASK
+#define REG_MASK( scope, reg, field ) \
+  REG_MASK_X_( reg_##scope##_##reg##___##field##___width, reg_##scope##_##reg##___##field##___lsb )
+#define REG_MASK_X_( width, lsb ) (((1 << width)-1) << lsb)
+#endif
+
+#ifndef REG_LSB
+#define REG_LSB( scope, reg, field ) reg_##scope##_##reg##___##field##___lsb
+#endif
+
+#ifndef REG_BIT
+#define REG_BIT( scope, reg, field ) reg_##scope##_##reg##___##field##___bit
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) REG_ADDR_X_(inst, reg_##scope##_##reg##_offset)
+#define REG_ADDR_X_( inst, offs ) ((inst) + offs)
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+         REG_ADDR_VECT_X_(inst, reg_##scope##_##reg##_offset, index, \
+			 STRIDE_##scope##_##reg )
+#define REG_ADDR_VECT_X_( inst, offs, index, stride ) \
+                          ((inst) + offs + (index) * stride)
+#endif
+
+/* Register rw_first_addr, scope marb_bp, type rw */
+#define reg_marb_bp_rw_first_addr_offset 0
+
+/* Register rw_last_addr, scope marb_bp, type rw */
+#define reg_marb_bp_rw_last_addr_offset 4
+
+/* Register rw_op, scope marb_bp, type rw */
+#define reg_marb_bp_rw_op___rd___lsb 0
+#define reg_marb_bp_rw_op___rd___width 1
+#define reg_marb_bp_rw_op___rd___bit 0
+#define reg_marb_bp_rw_op___wr___lsb 1
+#define reg_marb_bp_rw_op___wr___width 1
+#define reg_marb_bp_rw_op___wr___bit 1
+#define reg_marb_bp_rw_op___rd_excl___lsb 2
+#define reg_marb_bp_rw_op___rd_excl___width 1
+#define reg_marb_bp_rw_op___rd_excl___bit 2
+#define reg_marb_bp_rw_op___pri_wr___lsb 3
+#define reg_marb_bp_rw_op___pri_wr___width 1
+#define reg_marb_bp_rw_op___pri_wr___bit 3
+#define reg_marb_bp_rw_op___us_rd___lsb 4
+#define reg_marb_bp_rw_op___us_rd___width 1
+#define reg_marb_bp_rw_op___us_rd___bit 4
+#define reg_marb_bp_rw_op___us_wr___lsb 5
+#define reg_marb_bp_rw_op___us_wr___width 1
+#define reg_marb_bp_rw_op___us_wr___bit 5
+#define reg_marb_bp_rw_op___us_rd_excl___lsb 6
+#define reg_marb_bp_rw_op___us_rd_excl___width 1
+#define reg_marb_bp_rw_op___us_rd_excl___bit 6
+#define reg_marb_bp_rw_op___us_pri_wr___lsb 7
+#define reg_marb_bp_rw_op___us_pri_wr___width 1
+#define reg_marb_bp_rw_op___us_pri_wr___bit 7
+#define reg_marb_bp_rw_op_offset 8
+
+/* Register rw_clients, scope marb_bp, type rw */
+#define reg_marb_bp_rw_clients___dma0___lsb 0
+#define reg_marb_bp_rw_clients___dma0___width 1
+#define reg_marb_bp_rw_clients___dma0___bit 0
+#define reg_marb_bp_rw_clients___dma1___lsb 1
+#define reg_marb_bp_rw_clients___dma1___width 1
+#define reg_marb_bp_rw_clients___dma1___bit 1
+#define reg_marb_bp_rw_clients___dma2___lsb 2
+#define reg_marb_bp_rw_clients___dma2___width 1
+#define reg_marb_bp_rw_clients___dma2___bit 2
+#define reg_marb_bp_rw_clients___dma3___lsb 3
+#define reg_marb_bp_rw_clients___dma3___width 1
+#define reg_marb_bp_rw_clients___dma3___bit 3
+#define reg_marb_bp_rw_clients___dma4___lsb 4
+#define reg_marb_bp_rw_clients___dma4___width 1
+#define reg_marb_bp_rw_clients___dma4___bit 4
+#define reg_marb_bp_rw_clients___dma5___lsb 5
+#define reg_marb_bp_rw_clients___dma5___width 1
+#define reg_marb_bp_rw_clients___dma5___bit 5
+#define reg_marb_bp_rw_clients___dma6___lsb 6
+#define reg_marb_bp_rw_clients___dma6___width 1
+#define reg_marb_bp_rw_clients___dma6___bit 6
+#define reg_marb_bp_rw_clients___dma7___lsb 7
+#define reg_marb_bp_rw_clients___dma7___width 1
+#define reg_marb_bp_rw_clients___dma7___bit 7
+#define reg_marb_bp_rw_clients___dma8___lsb 8
+#define reg_marb_bp_rw_clients___dma8___width 1
+#define reg_marb_bp_rw_clients___dma8___bit 8
+#define reg_marb_bp_rw_clients___dma9___lsb 9
+#define reg_marb_bp_rw_clients___dma9___width 1
+#define reg_marb_bp_rw_clients___dma9___bit 9
+#define reg_marb_bp_rw_clients___cpui___lsb 10
+#define reg_marb_bp_rw_clients___cpui___width 1
+#define reg_marb_bp_rw_clients___cpui___bit 10
+#define reg_marb_bp_rw_clients___cpud___lsb 11
+#define reg_marb_bp_rw_clients___cpud___width 1
+#define reg_marb_bp_rw_clients___cpud___bit 11
+#define reg_marb_bp_rw_clients___iop___lsb 12
+#define reg_marb_bp_rw_clients___iop___width 1
+#define reg_marb_bp_rw_clients___iop___bit 12
+#define reg_marb_bp_rw_clients___slave___lsb 13
+#define reg_marb_bp_rw_clients___slave___width 1
+#define reg_marb_bp_rw_clients___slave___bit 13
+#define reg_marb_bp_rw_clients_offset 12
+
+/* Register rw_options, scope marb_bp, type rw */
+#define reg_marb_bp_rw_options___wrap___lsb 0
+#define reg_marb_bp_rw_options___wrap___width 1
+#define reg_marb_bp_rw_options___wrap___bit 0
+#define reg_marb_bp_rw_options_offset 16
+
+/* Register r_brk_addr, scope marb_bp, type r */
+#define reg_marb_bp_r_brk_addr_offset 20
+
+/* Register r_brk_op, scope marb_bp, type r */
+#define reg_marb_bp_r_brk_op___rd___lsb 0
+#define reg_marb_bp_r_brk_op___rd___width 1
+#define reg_marb_bp_r_brk_op___rd___bit 0
+#define reg_marb_bp_r_brk_op___wr___lsb 1
+#define reg_marb_bp_r_brk_op___wr___width 1
+#define reg_marb_bp_r_brk_op___wr___bit 1
+#define reg_marb_bp_r_brk_op___rd_excl___lsb 2
+#define reg_marb_bp_r_brk_op___rd_excl___width 1
+#define reg_marb_bp_r_brk_op___rd_excl___bit 2
+#define reg_marb_bp_r_brk_op___pri_wr___lsb 3
+#define reg_marb_bp_r_brk_op___pri_wr___width 1
+#define reg_marb_bp_r_brk_op___pri_wr___bit 3
+#define reg_marb_bp_r_brk_op___us_rd___lsb 4
+#define reg_marb_bp_r_brk_op___us_rd___width 1
+#define reg_marb_bp_r_brk_op___us_rd___bit 4
+#define reg_marb_bp_r_brk_op___us_wr___lsb 5
+#define reg_marb_bp_r_brk_op___us_wr___width 1
+#define reg_marb_bp_r_brk_op___us_wr___bit 5
+#define reg_marb_bp_r_brk_op___us_rd_excl___lsb 6
+#define reg_marb_bp_r_brk_op___us_rd_excl___width 1
+#define reg_marb_bp_r_brk_op___us_rd_excl___bit 6
+#define reg_marb_bp_r_brk_op___us_pri_wr___lsb 7
+#define reg_marb_bp_r_brk_op___us_pri_wr___width 1
+#define reg_marb_bp_r_brk_op___us_pri_wr___bit 7
+#define reg_marb_bp_r_brk_op_offset 24
+
+/* Register r_brk_clients, scope marb_bp, type r */
+#define reg_marb_bp_r_brk_clients___dma0___lsb 0
+#define reg_marb_bp_r_brk_clients___dma0___width 1
+#define reg_marb_bp_r_brk_clients___dma0___bit 0
+#define reg_marb_bp_r_brk_clients___dma1___lsb 1
+#define reg_marb_bp_r_brk_clients___dma1___width 1
+#define reg_marb_bp_r_brk_clients___dma1___bit 1
+#define reg_marb_bp_r_brk_clients___dma2___lsb 2
+#define reg_marb_bp_r_brk_clients___dma2___width 1
+#define reg_marb_bp_r_brk_clients___dma2___bit 2
+#define reg_marb_bp_r_brk_clients___dma3___lsb 3
+#define reg_marb_bp_r_brk_clients___dma3___width 1
+#define reg_marb_bp_r_brk_clients___dma3___bit 3
+#define reg_marb_bp_r_brk_clients___dma4___lsb 4
+#define reg_marb_bp_r_brk_clients___dma4___width 1
+#define reg_marb_bp_r_brk_clients___dma4___bit 4
+#define reg_marb_bp_r_brk_clients___dma5___lsb 5
+#define reg_marb_bp_r_brk_clients___dma5___width 1
+#define reg_marb_bp_r_brk_clients___dma5___bit 5
+#define reg_marb_bp_r_brk_clients___dma6___lsb 6
+#define reg_marb_bp_r_brk_clients___dma6___width 1
+#define reg_marb_bp_r_brk_clients___dma6___bit 6
+#define reg_marb_bp_r_brk_clients___dma7___lsb 7
+#define reg_marb_bp_r_brk_clients___dma7___width 1
+#define reg_marb_bp_r_brk_clients___dma7___bit 7
+#define reg_marb_bp_r_brk_clients___dma8___lsb 8
+#define reg_marb_bp_r_brk_clients___dma8___width 1
+#define reg_marb_bp_r_brk_clients___dma8___bit 8
+#define reg_marb_bp_r_brk_clients___dma9___lsb 9
+#define reg_marb_bp_r_brk_clients___dma9___width 1
+#define reg_marb_bp_r_brk_clients___dma9___bit 9
+#define reg_marb_bp_r_brk_clients___cpui___lsb 10
+#define reg_marb_bp_r_brk_clients___cpui___width 1
+#define reg_marb_bp_r_brk_clients___cpui___bit 10
+#define reg_marb_bp_r_brk_clients___cpud___lsb 11
+#define reg_marb_bp_r_brk_clients___cpud___width 1
+#define reg_marb_bp_r_brk_clients___cpud___bit 11
+#define reg_marb_bp_r_brk_clients___iop___lsb 12
+#define reg_marb_bp_r_brk_clients___iop___width 1
+#define reg_marb_bp_r_brk_clients___iop___bit 12
+#define reg_marb_bp_r_brk_clients___slave___lsb 13
+#define reg_marb_bp_r_brk_clients___slave___width 1
+#define reg_marb_bp_r_brk_clients___slave___bit 13
+#define reg_marb_bp_r_brk_clients_offset 28
+
+/* Register r_brk_first_client, scope marb_bp, type r */
+#define reg_marb_bp_r_brk_first_client___dma0___lsb 0
+#define reg_marb_bp_r_brk_first_client___dma0___width 1
+#define reg_marb_bp_r_brk_first_client___dma0___bit 0
+#define reg_marb_bp_r_brk_first_client___dma1___lsb 1
+#define reg_marb_bp_r_brk_first_client___dma1___width 1
+#define reg_marb_bp_r_brk_first_client___dma1___bit 1
+#define reg_marb_bp_r_brk_first_client___dma2___lsb 2
+#define reg_marb_bp_r_brk_first_client___dma2___width 1
+#define reg_marb_bp_r_brk_first_client___dma2___bit 2
+#define reg_marb_bp_r_brk_first_client___dma3___lsb 3
+#define reg_marb_bp_r_brk_first_client___dma3___width 1
+#define reg_marb_bp_r_brk_first_client___dma3___bit 3
+#define reg_marb_bp_r_brk_first_client___dma4___lsb 4
+#define reg_marb_bp_r_brk_first_client___dma4___width 1
+#define reg_marb_bp_r_brk_first_client___dma4___bit 4
+#define reg_marb_bp_r_brk_first_client___dma5___lsb 5
+#define reg_marb_bp_r_brk_first_client___dma5___width 1
+#define reg_marb_bp_r_brk_first_client___dma5___bit 5
+#define reg_marb_bp_r_brk_first_client___dma6___lsb 6
+#define reg_marb_bp_r_brk_first_client___dma6___width 1
+#define reg_marb_bp_r_brk_first_client___dma6___bit 6
+#define reg_marb_bp_r_brk_first_client___dma7___lsb 7
+#define reg_marb_bp_r_brk_first_client___dma7___width 1
+#define reg_marb_bp_r_brk_first_client___dma7___bit 7
+#define reg_marb_bp_r_brk_first_client___dma8___lsb 8
+#define reg_marb_bp_r_brk_first_client___dma8___width 1
+#define reg_marb_bp_r_brk_first_client___dma8___bit 8
+#define reg_marb_bp_r_brk_first_client___dma9___lsb 9
+#define reg_marb_bp_r_brk_first_client___dma9___width 1
+#define reg_marb_bp_r_brk_first_client___dma9___bit 9
+#define reg_marb_bp_r_brk_first_client___cpui___lsb 10
+#define reg_marb_bp_r_brk_first_client___cpui___width 1
+#define reg_marb_bp_r_brk_first_client___cpui___bit 10
+#define reg_marb_bp_r_brk_first_client___cpud___lsb 11
+#define reg_marb_bp_r_brk_first_client___cpud___width 1
+#define reg_marb_bp_r_brk_first_client___cpud___bit 11
+#define reg_marb_bp_r_brk_first_client___iop___lsb 12
+#define reg_marb_bp_r_brk_first_client___iop___width 1
+#define reg_marb_bp_r_brk_first_client___iop___bit 12
+#define reg_marb_bp_r_brk_first_client___slave___lsb 13
+#define reg_marb_bp_r_brk_first_client___slave___width 1
+#define reg_marb_bp_r_brk_first_client___slave___bit 13
+#define reg_marb_bp_r_brk_first_client_offset 32
+
+/* Register r_brk_size, scope marb_bp, type r */
+#define reg_marb_bp_r_brk_size_offset 36
+
+/* Register rw_ack, scope marb_bp, type rw */
+#define reg_marb_bp_rw_ack_offset 40
+
+
+/* Constants */
+#define regk_marb_bp_no                           0x00000000
+#define regk_marb_bp_rw_op_default                0x00000000
+#define regk_marb_bp_rw_options_default           0x00000000
+#define regk_marb_bp_yes                          0x00000001
+#endif /* __marb_bp_defs_asm_h */
diff --git a/include/asm-cris/arch-v32/hwregs/asm/mmu_defs_asm.h b/include/asm-cris/arch-v32/hwregs/asm/mmu_defs_asm.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/asm/mmu_defs_asm.h
@@ -0,0 +1,212 @@
+#ifndef __mmu_defs_asm_h
+#define __mmu_defs_asm_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/mmu/doc/mmu_regs.r
+ *     id:           mmu_regs.r,v 1.12 2004/05/06 13:48:45 mikaeln Exp
+ *     last modfied: Mon Apr 11 17:03:20 2005
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c -asm --outfile asm/mmu_defs_asm.h ../../inst/mmu/doc/mmu_regs.r
+ *      id: $Id: mmu_defs_asm.h,v 1.1 2005/04/24 18:31:04 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+
+#ifndef REG_FIELD
+#define REG_FIELD( scope, reg, field, value ) \
+  REG_FIELD_X_( value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_FIELD_X_( value, shift ) ((value) << shift)
+#endif
+
+#ifndef REG_STATE
+#define REG_STATE( scope, reg, field, symbolic_value ) \
+  REG_STATE_X_( regk_##scope##_##symbolic_value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_STATE_X_( k, shift ) (k << shift)
+#endif
+
+#ifndef REG_MASK
+#define REG_MASK( scope, reg, field ) \
+  REG_MASK_X_( reg_##scope##_##reg##___##field##___width, reg_##scope##_##reg##___##field##___lsb )
+#define REG_MASK_X_( width, lsb ) (((1 << width)-1) << lsb)
+#endif
+
+#ifndef REG_LSB
+#define REG_LSB( scope, reg, field ) reg_##scope##_##reg##___##field##___lsb
+#endif
+
+#ifndef REG_BIT
+#define REG_BIT( scope, reg, field ) reg_##scope##_##reg##___##field##___bit
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) REG_ADDR_X_(inst, reg_##scope##_##reg##_offset)
+#define REG_ADDR_X_( inst, offs ) ((inst) + offs)
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+         REG_ADDR_VECT_X_(inst, reg_##scope##_##reg##_offset, index, \
+			 STRIDE_##scope##_##reg )
+#define REG_ADDR_VECT_X_( inst, offs, index, stride ) \
+                          ((inst) + offs + (index) * stride)
+#endif
+
+/* Register rw_mm_cfg, scope mmu, type rw */
+#define reg_mmu_rw_mm_cfg___seg_0___lsb 0
+#define reg_mmu_rw_mm_cfg___seg_0___width 1
+#define reg_mmu_rw_mm_cfg___seg_0___bit 0
+#define reg_mmu_rw_mm_cfg___seg_1___lsb 1
+#define reg_mmu_rw_mm_cfg___seg_1___width 1
+#define reg_mmu_rw_mm_cfg___seg_1___bit 1
+#define reg_mmu_rw_mm_cfg___seg_2___lsb 2
+#define reg_mmu_rw_mm_cfg___seg_2___width 1
+#define reg_mmu_rw_mm_cfg___seg_2___bit 2
+#define reg_mmu_rw_mm_cfg___seg_3___lsb 3
+#define reg_mmu_rw_mm_cfg___seg_3___width 1
+#define reg_mmu_rw_mm_cfg___seg_3___bit 3
+#define reg_mmu_rw_mm_cfg___seg_4___lsb 4
+#define reg_mmu_rw_mm_cfg___seg_4___width 1
+#define reg_mmu_rw_mm_cfg___seg_4___bit 4
+#define reg_mmu_rw_mm_cfg___seg_5___lsb 5
+#define reg_mmu_rw_mm_cfg___seg_5___width 1
+#define reg_mmu_rw_mm_cfg___seg_5___bit 5
+#define reg_mmu_rw_mm_cfg___seg_6___lsb 6
+#define reg_mmu_rw_mm_cfg___seg_6___width 1
+#define reg_mmu_rw_mm_cfg___seg_6___bit 6
+#define reg_mmu_rw_mm_cfg___seg_7___lsb 7
+#define reg_mmu_rw_mm_cfg___seg_7___width 1
+#define reg_mmu_rw_mm_cfg___seg_7___bit 7
+#define reg_mmu_rw_mm_cfg___seg_8___lsb 8
+#define reg_mmu_rw_mm_cfg___seg_8___width 1
+#define reg_mmu_rw_mm_cfg___seg_8___bit 8
+#define reg_mmu_rw_mm_cfg___seg_9___lsb 9
+#define reg_mmu_rw_mm_cfg___seg_9___width 1
+#define reg_mmu_rw_mm_cfg___seg_9___bit 9
+#define reg_mmu_rw_mm_cfg___seg_a___lsb 10
+#define reg_mmu_rw_mm_cfg___seg_a___width 1
+#define reg_mmu_rw_mm_cfg___seg_a___bit 10
+#define reg_mmu_rw_mm_cfg___seg_b___lsb 11
+#define reg_mmu_rw_mm_cfg___seg_b___width 1
+#define reg_mmu_rw_mm_cfg___seg_b___bit 11
+#define reg_mmu_rw_mm_cfg___seg_c___lsb 12
+#define reg_mmu_rw_mm_cfg___seg_c___width 1
+#define reg_mmu_rw_mm_cfg___seg_c___bit 12
+#define reg_mmu_rw_mm_cfg___seg_d___lsb 13
+#define reg_mmu_rw_mm_cfg___seg_d___width 1
+#define reg_mmu_rw_mm_cfg___seg_d___bit 13
+#define reg_mmu_rw_mm_cfg___seg_e___lsb 14
+#define reg_mmu_rw_mm_cfg___seg_e___width 1
+#define reg_mmu_rw_mm_cfg___seg_e___bit 14
+#define reg_mmu_rw_mm_cfg___seg_f___lsb 15
+#define reg_mmu_rw_mm_cfg___seg_f___width 1
+#define reg_mmu_rw_mm_cfg___seg_f___bit 15
+#define reg_mmu_rw_mm_cfg___inv___lsb 16
+#define reg_mmu_rw_mm_cfg___inv___width 1
+#define reg_mmu_rw_mm_cfg___inv___bit 16
+#define reg_mmu_rw_mm_cfg___ex___lsb 17
+#define reg_mmu_rw_mm_cfg___ex___width 1
+#define reg_mmu_rw_mm_cfg___ex___bit 17
+#define reg_mmu_rw_mm_cfg___acc___lsb 18
+#define reg_mmu_rw_mm_cfg___acc___width 1
+#define reg_mmu_rw_mm_cfg___acc___bit 18
+#define reg_mmu_rw_mm_cfg___we___lsb 19
+#define reg_mmu_rw_mm_cfg___we___width 1
+#define reg_mmu_rw_mm_cfg___we___bit 19
+#define reg_mmu_rw_mm_cfg_offset 0
+
+/* Register rw_mm_kbase_lo, scope mmu, type rw */
+#define reg_mmu_rw_mm_kbase_lo___base_0___lsb 0
+#define reg_mmu_rw_mm_kbase_lo___base_0___width 4
+#define reg_mmu_rw_mm_kbase_lo___base_1___lsb 4
+#define reg_mmu_rw_mm_kbase_lo___base_1___width 4
+#define reg_mmu_rw_mm_kbase_lo___base_2___lsb 8
+#define reg_mmu_rw_mm_kbase_lo___base_2___width 4
+#define reg_mmu_rw_mm_kbase_lo___base_3___lsb 12
+#define reg_mmu_rw_mm_kbase_lo___base_3___width 4
+#define reg_mmu_rw_mm_kbase_lo___base_4___lsb 16
+#define reg_mmu_rw_mm_kbase_lo___base_4___width 4
+#define reg_mmu_rw_mm_kbase_lo___base_5___lsb 20
+#define reg_mmu_rw_mm_kbase_lo___base_5___width 4
+#define reg_mmu_rw_mm_kbase_lo___base_6___lsb 24
+#define reg_mmu_rw_mm_kbase_lo___base_6___width 4
+#define reg_mmu_rw_mm_kbase_lo___base_7___lsb 28
+#define reg_mmu_rw_mm_kbase_lo___base_7___width 4
+#define reg_mmu_rw_mm_kbase_lo_offset 4
+
+/* Register rw_mm_kbase_hi, scope mmu, type rw */
+#define reg_mmu_rw_mm_kbase_hi___base_8___lsb 0
+#define reg_mmu_rw_mm_kbase_hi___base_8___width 4
+#define reg_mmu_rw_mm_kbase_hi___base_9___lsb 4
+#define reg_mmu_rw_mm_kbase_hi___base_9___width 4
+#define reg_mmu_rw_mm_kbase_hi___base_a___lsb 8
+#define reg_mmu_rw_mm_kbase_hi___base_a___width 4
+#define reg_mmu_rw_mm_kbase_hi___base_b___lsb 12
+#define reg_mmu_rw_mm_kbase_hi___base_b___width 4
+#define reg_mmu_rw_mm_kbase_hi___base_c___lsb 16
+#define reg_mmu_rw_mm_kbase_hi___base_c___width 4
+#define reg_mmu_rw_mm_kbase_hi___base_d___lsb 20
+#define reg_mmu_rw_mm_kbase_hi___base_d___width 4
+#define reg_mmu_rw_mm_kbase_hi___base_e___lsb 24
+#define reg_mmu_rw_mm_kbase_hi___base_e___width 4
+#define reg_mmu_rw_mm_kbase_hi___base_f___lsb 28
+#define reg_mmu_rw_mm_kbase_hi___base_f___width 4
+#define reg_mmu_rw_mm_kbase_hi_offset 8
+
+/* Register r_mm_cause, scope mmu, type r */
+#define reg_mmu_r_mm_cause___pid___lsb 0
+#define reg_mmu_r_mm_cause___pid___width 8
+#define reg_mmu_r_mm_cause___op___lsb 8
+#define reg_mmu_r_mm_cause___op___width 2
+#define reg_mmu_r_mm_cause___vpn___lsb 13
+#define reg_mmu_r_mm_cause___vpn___width 19
+#define reg_mmu_r_mm_cause_offset 12
+
+/* Register rw_mm_tlb_sel, scope mmu, type rw */
+#define reg_mmu_rw_mm_tlb_sel___idx___lsb 0
+#define reg_mmu_rw_mm_tlb_sel___idx___width 4
+#define reg_mmu_rw_mm_tlb_sel___set___lsb 4
+#define reg_mmu_rw_mm_tlb_sel___set___width 2
+#define reg_mmu_rw_mm_tlb_sel_offset 16
+
+/* Register rw_mm_tlb_lo, scope mmu, type rw */
+#define reg_mmu_rw_mm_tlb_lo___x___lsb 0
+#define reg_mmu_rw_mm_tlb_lo___x___width 1
+#define reg_mmu_rw_mm_tlb_lo___x___bit 0
+#define reg_mmu_rw_mm_tlb_lo___w___lsb 1
+#define reg_mmu_rw_mm_tlb_lo___w___width 1
+#define reg_mmu_rw_mm_tlb_lo___w___bit 1
+#define reg_mmu_rw_mm_tlb_lo___k___lsb 2
+#define reg_mmu_rw_mm_tlb_lo___k___width 1
+#define reg_mmu_rw_mm_tlb_lo___k___bit 2
+#define reg_mmu_rw_mm_tlb_lo___v___lsb 3
+#define reg_mmu_rw_mm_tlb_lo___v___width 1
+#define reg_mmu_rw_mm_tlb_lo___v___bit 3
+#define reg_mmu_rw_mm_tlb_lo___g___lsb 4
+#define reg_mmu_rw_mm_tlb_lo___g___width 1
+#define reg_mmu_rw_mm_tlb_lo___g___bit 4
+#define reg_mmu_rw_mm_tlb_lo___pfn___lsb 13
+#define reg_mmu_rw_mm_tlb_lo___pfn___width 19
+#define reg_mmu_rw_mm_tlb_lo_offset 20
+
+/* Register rw_mm_tlb_hi, scope mmu, type rw */
+#define reg_mmu_rw_mm_tlb_hi___pid___lsb 0
+#define reg_mmu_rw_mm_tlb_hi___pid___width 8
+#define reg_mmu_rw_mm_tlb_hi___vpn___lsb 13
+#define reg_mmu_rw_mm_tlb_hi___vpn___width 19
+#define reg_mmu_rw_mm_tlb_hi_offset 24
+
+
+/* Constants */
+#define regk_mmu_execute                          0x00000000
+#define regk_mmu_flush                            0x00000003
+#define regk_mmu_linear                           0x00000001
+#define regk_mmu_no                               0x00000000
+#define regk_mmu_off                              0x00000000
+#define regk_mmu_on                               0x00000001
+#define regk_mmu_page                             0x00000000
+#define regk_mmu_read                             0x00000001
+#define regk_mmu_write                            0x00000002
+#define regk_mmu_yes                              0x00000001
+#endif /* __mmu_defs_asm_h */
diff --git a/include/asm-cris/arch-v32/hwregs/asm/mmu_supp_reg.h b/include/asm-cris/arch-v32/hwregs/asm/mmu_supp_reg.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/asm/mmu_supp_reg.h
@@ -0,0 +1,7 @@
+#define RW_MM_CFG	0
+#define RW_MM_KBASE_LO	1
+#define RW_MM_KBASE_HI	2
+#define R_MM_CAUSE	3
+#define RW_MM_TLB_SEL	4
+#define RW_MM_TLB_LO	5
+#define RW_MM_TLB_HI	6
diff --git a/include/asm-cris/arch-v32/hwregs/asm/pinmux_defs_asm.h b/include/asm-cris/arch-v32/hwregs/asm/pinmux_defs_asm.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/asm/pinmux_defs_asm.h
@@ -0,0 +1,632 @@
+#ifndef __pinmux_defs_asm_h
+#define __pinmux_defs_asm_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/pinmux/rtl/guinness/pinmux_regs.r
+ *     id:           pinmux_regs.r,v 1.40 2005/02/09 16:22:59 perz Exp
+ *     last modfied: Mon Apr 11 16:09:11 2005
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c -asm --outfile asm/pinmux_defs_asm.h ../../inst/pinmux/rtl/guinness/pinmux_regs.r
+ *      id: $Id: pinmux_defs_asm.h,v 1.1 2005/04/24 18:31:04 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+
+#ifndef REG_FIELD
+#define REG_FIELD( scope, reg, field, value ) \
+  REG_FIELD_X_( value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_FIELD_X_( value, shift ) ((value) << shift)
+#endif
+
+#ifndef REG_STATE
+#define REG_STATE( scope, reg, field, symbolic_value ) \
+  REG_STATE_X_( regk_##scope##_##symbolic_value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_STATE_X_( k, shift ) (k << shift)
+#endif
+
+#ifndef REG_MASK
+#define REG_MASK( scope, reg, field ) \
+  REG_MASK_X_( reg_##scope##_##reg##___##field##___width, reg_##scope##_##reg##___##field##___lsb )
+#define REG_MASK_X_( width, lsb ) (((1 << width)-1) << lsb)
+#endif
+
+#ifndef REG_LSB
+#define REG_LSB( scope, reg, field ) reg_##scope##_##reg##___##field##___lsb
+#endif
+
+#ifndef REG_BIT
+#define REG_BIT( scope, reg, field ) reg_##scope##_##reg##___##field##___bit
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) REG_ADDR_X_(inst, reg_##scope##_##reg##_offset)
+#define REG_ADDR_X_( inst, offs ) ((inst) + offs)
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+         REG_ADDR_VECT_X_(inst, reg_##scope##_##reg##_offset, index, \
+			 STRIDE_##scope##_##reg )
+#define REG_ADDR_VECT_X_( inst, offs, index, stride ) \
+                          ((inst) + offs + (index) * stride)
+#endif
+
+/* Register rw_pa, scope pinmux, type rw */
+#define reg_pinmux_rw_pa___pa0___lsb 0
+#define reg_pinmux_rw_pa___pa0___width 1
+#define reg_pinmux_rw_pa___pa0___bit 0
+#define reg_pinmux_rw_pa___pa1___lsb 1
+#define reg_pinmux_rw_pa___pa1___width 1
+#define reg_pinmux_rw_pa___pa1___bit 1
+#define reg_pinmux_rw_pa___pa2___lsb 2
+#define reg_pinmux_rw_pa___pa2___width 1
+#define reg_pinmux_rw_pa___pa2___bit 2
+#define reg_pinmux_rw_pa___pa3___lsb 3
+#define reg_pinmux_rw_pa___pa3___width 1
+#define reg_pinmux_rw_pa___pa3___bit 3
+#define reg_pinmux_rw_pa___pa4___lsb 4
+#define reg_pinmux_rw_pa___pa4___width 1
+#define reg_pinmux_rw_pa___pa4___bit 4
+#define reg_pinmux_rw_pa___pa5___lsb 5
+#define reg_pinmux_rw_pa___pa5___width 1
+#define reg_pinmux_rw_pa___pa5___bit 5
+#define reg_pinmux_rw_pa___pa6___lsb 6
+#define reg_pinmux_rw_pa___pa6___width 1
+#define reg_pinmux_rw_pa___pa6___bit 6
+#define reg_pinmux_rw_pa___pa7___lsb 7
+#define reg_pinmux_rw_pa___pa7___width 1
+#define reg_pinmux_rw_pa___pa7___bit 7
+#define reg_pinmux_rw_pa___csp2_n___lsb 8
+#define reg_pinmux_rw_pa___csp2_n___width 1
+#define reg_pinmux_rw_pa___csp2_n___bit 8
+#define reg_pinmux_rw_pa___csp3_n___lsb 9
+#define reg_pinmux_rw_pa___csp3_n___width 1
+#define reg_pinmux_rw_pa___csp3_n___bit 9
+#define reg_pinmux_rw_pa___csp5_n___lsb 10
+#define reg_pinmux_rw_pa___csp5_n___width 1
+#define reg_pinmux_rw_pa___csp5_n___bit 10
+#define reg_pinmux_rw_pa___csp6_n___lsb 11
+#define reg_pinmux_rw_pa___csp6_n___width 1
+#define reg_pinmux_rw_pa___csp6_n___bit 11
+#define reg_pinmux_rw_pa___hsh4___lsb 12
+#define reg_pinmux_rw_pa___hsh4___width 1
+#define reg_pinmux_rw_pa___hsh4___bit 12
+#define reg_pinmux_rw_pa___hsh5___lsb 13
+#define reg_pinmux_rw_pa___hsh5___width 1
+#define reg_pinmux_rw_pa___hsh5___bit 13
+#define reg_pinmux_rw_pa___hsh6___lsb 14
+#define reg_pinmux_rw_pa___hsh6___width 1
+#define reg_pinmux_rw_pa___hsh6___bit 14
+#define reg_pinmux_rw_pa___hsh7___lsb 15
+#define reg_pinmux_rw_pa___hsh7___width 1
+#define reg_pinmux_rw_pa___hsh7___bit 15
+#define reg_pinmux_rw_pa_offset 0
+
+/* Register rw_hwprot, scope pinmux, type rw */
+#define reg_pinmux_rw_hwprot___ser1___lsb 0
+#define reg_pinmux_rw_hwprot___ser1___width 1
+#define reg_pinmux_rw_hwprot___ser1___bit 0
+#define reg_pinmux_rw_hwprot___ser2___lsb 1
+#define reg_pinmux_rw_hwprot___ser2___width 1
+#define reg_pinmux_rw_hwprot___ser2___bit 1
+#define reg_pinmux_rw_hwprot___ser3___lsb 2
+#define reg_pinmux_rw_hwprot___ser3___width 1
+#define reg_pinmux_rw_hwprot___ser3___bit 2
+#define reg_pinmux_rw_hwprot___sser0___lsb 3
+#define reg_pinmux_rw_hwprot___sser0___width 1
+#define reg_pinmux_rw_hwprot___sser0___bit 3
+#define reg_pinmux_rw_hwprot___sser1___lsb 4
+#define reg_pinmux_rw_hwprot___sser1___width 1
+#define reg_pinmux_rw_hwprot___sser1___bit 4
+#define reg_pinmux_rw_hwprot___ata0___lsb 5
+#define reg_pinmux_rw_hwprot___ata0___width 1
+#define reg_pinmux_rw_hwprot___ata0___bit 5
+#define reg_pinmux_rw_hwprot___ata1___lsb 6
+#define reg_pinmux_rw_hwprot___ata1___width 1
+#define reg_pinmux_rw_hwprot___ata1___bit 6
+#define reg_pinmux_rw_hwprot___ata2___lsb 7
+#define reg_pinmux_rw_hwprot___ata2___width 1
+#define reg_pinmux_rw_hwprot___ata2___bit 7
+#define reg_pinmux_rw_hwprot___ata3___lsb 8
+#define reg_pinmux_rw_hwprot___ata3___width 1
+#define reg_pinmux_rw_hwprot___ata3___bit 8
+#define reg_pinmux_rw_hwprot___ata___lsb 9
+#define reg_pinmux_rw_hwprot___ata___width 1
+#define reg_pinmux_rw_hwprot___ata___bit 9
+#define reg_pinmux_rw_hwprot___eth1___lsb 10
+#define reg_pinmux_rw_hwprot___eth1___width 1
+#define reg_pinmux_rw_hwprot___eth1___bit 10
+#define reg_pinmux_rw_hwprot___eth1_mgm___lsb 11
+#define reg_pinmux_rw_hwprot___eth1_mgm___width 1
+#define reg_pinmux_rw_hwprot___eth1_mgm___bit 11
+#define reg_pinmux_rw_hwprot___timer___lsb 12
+#define reg_pinmux_rw_hwprot___timer___width 1
+#define reg_pinmux_rw_hwprot___timer___bit 12
+#define reg_pinmux_rw_hwprot___p21___lsb 13
+#define reg_pinmux_rw_hwprot___p21___width 1
+#define reg_pinmux_rw_hwprot___p21___bit 13
+#define reg_pinmux_rw_hwprot_offset 4
+
+/* Register rw_pb_gio, scope pinmux, type rw */
+#define reg_pinmux_rw_pb_gio___pb0___lsb 0
+#define reg_pinmux_rw_pb_gio___pb0___width 1
+#define reg_pinmux_rw_pb_gio___pb0___bit 0
+#define reg_pinmux_rw_pb_gio___pb1___lsb 1
+#define reg_pinmux_rw_pb_gio___pb1___width 1
+#define reg_pinmux_rw_pb_gio___pb1___bit 1
+#define reg_pinmux_rw_pb_gio___pb2___lsb 2
+#define reg_pinmux_rw_pb_gio___pb2___width 1
+#define reg_pinmux_rw_pb_gio___pb2___bit 2
+#define reg_pinmux_rw_pb_gio___pb3___lsb 3
+#define reg_pinmux_rw_pb_gio___pb3___width 1
+#define reg_pinmux_rw_pb_gio___pb3___bit 3
+#define reg_pinmux_rw_pb_gio___pb4___lsb 4
+#define reg_pinmux_rw_pb_gio___pb4___width 1
+#define reg_pinmux_rw_pb_gio___pb4___bit 4
+#define reg_pinmux_rw_pb_gio___pb5___lsb 5
+#define reg_pinmux_rw_pb_gio___pb5___width 1
+#define reg_pinmux_rw_pb_gio___pb5___bit 5
+#define reg_pinmux_rw_pb_gio___pb6___lsb 6
+#define reg_pinmux_rw_pb_gio___pb6___width 1
+#define reg_pinmux_rw_pb_gio___pb6___bit 6
+#define reg_pinmux_rw_pb_gio___pb7___lsb 7
+#define reg_pinmux_rw_pb_gio___pb7___width 1
+#define reg_pinmux_rw_pb_gio___pb7___bit 7
+#define reg_pinmux_rw_pb_gio___pb8___lsb 8
+#define reg_pinmux_rw_pb_gio___pb8___width 1
+#define reg_pinmux_rw_pb_gio___pb8___bit 8
+#define reg_pinmux_rw_pb_gio___pb9___lsb 9
+#define reg_pinmux_rw_pb_gio___pb9___width 1
+#define reg_pinmux_rw_pb_gio___pb9___bit 9
+#define reg_pinmux_rw_pb_gio___pb10___lsb 10
+#define reg_pinmux_rw_pb_gio___pb10___width 1
+#define reg_pinmux_rw_pb_gio___pb10___bit 10
+#define reg_pinmux_rw_pb_gio___pb11___lsb 11
+#define reg_pinmux_rw_pb_gio___pb11___width 1
+#define reg_pinmux_rw_pb_gio___pb11___bit 11
+#define reg_pinmux_rw_pb_gio___pb12___lsb 12
+#define reg_pinmux_rw_pb_gio___pb12___width 1
+#define reg_pinmux_rw_pb_gio___pb12___bit 12
+#define reg_pinmux_rw_pb_gio___pb13___lsb 13
+#define reg_pinmux_rw_pb_gio___pb13___width 1
+#define reg_pinmux_rw_pb_gio___pb13___bit 13
+#define reg_pinmux_rw_pb_gio___pb14___lsb 14
+#define reg_pinmux_rw_pb_gio___pb14___width 1
+#define reg_pinmux_rw_pb_gio___pb14___bit 14
+#define reg_pinmux_rw_pb_gio___pb15___lsb 15
+#define reg_pinmux_rw_pb_gio___pb15___width 1
+#define reg_pinmux_rw_pb_gio___pb15___bit 15
+#define reg_pinmux_rw_pb_gio___pb16___lsb 16
+#define reg_pinmux_rw_pb_gio___pb16___width 1
+#define reg_pinmux_rw_pb_gio___pb16___bit 16
+#define reg_pinmux_rw_pb_gio___pb17___lsb 17
+#define reg_pinmux_rw_pb_gio___pb17___width 1
+#define reg_pinmux_rw_pb_gio___pb17___bit 17
+#define reg_pinmux_rw_pb_gio_offset 8
+
+/* Register rw_pb_iop, scope pinmux, type rw */
+#define reg_pinmux_rw_pb_iop___pb0___lsb 0
+#define reg_pinmux_rw_pb_iop___pb0___width 1
+#define reg_pinmux_rw_pb_iop___pb0___bit 0
+#define reg_pinmux_rw_pb_iop___pb1___lsb 1
+#define reg_pinmux_rw_pb_iop___pb1___width 1
+#define reg_pinmux_rw_pb_iop___pb1___bit 1
+#define reg_pinmux_rw_pb_iop___pb2___lsb 2
+#define reg_pinmux_rw_pb_iop___pb2___width 1
+#define reg_pinmux_rw_pb_iop___pb2___bit 2
+#define reg_pinmux_rw_pb_iop___pb3___lsb 3
+#define reg_pinmux_rw_pb_iop___pb3___width 1
+#define reg_pinmux_rw_pb_iop___pb3___bit 3
+#define reg_pinmux_rw_pb_iop___pb4___lsb 4
+#define reg_pinmux_rw_pb_iop___pb4___width 1
+#define reg_pinmux_rw_pb_iop___pb4___bit 4
+#define reg_pinmux_rw_pb_iop___pb5___lsb 5
+#define reg_pinmux_rw_pb_iop___pb5___width 1
+#define reg_pinmux_rw_pb_iop___pb5___bit 5
+#define reg_pinmux_rw_pb_iop___pb6___lsb 6
+#define reg_pinmux_rw_pb_iop___pb6___width 1
+#define reg_pinmux_rw_pb_iop___pb6___bit 6
+#define reg_pinmux_rw_pb_iop___pb7___lsb 7
+#define reg_pinmux_rw_pb_iop___pb7___width 1
+#define reg_pinmux_rw_pb_iop___pb7___bit 7
+#define reg_pinmux_rw_pb_iop___pb8___lsb 8
+#define reg_pinmux_rw_pb_iop___pb8___width 1
+#define reg_pinmux_rw_pb_iop___pb8___bit 8
+#define reg_pinmux_rw_pb_iop___pb9___lsb 9
+#define reg_pinmux_rw_pb_iop___pb9___width 1
+#define reg_pinmux_rw_pb_iop___pb9___bit 9
+#define reg_pinmux_rw_pb_iop___pb10___lsb 10
+#define reg_pinmux_rw_pb_iop___pb10___width 1
+#define reg_pinmux_rw_pb_iop___pb10___bit 10
+#define reg_pinmux_rw_pb_iop___pb11___lsb 11
+#define reg_pinmux_rw_pb_iop___pb11___width 1
+#define reg_pinmux_rw_pb_iop___pb11___bit 11
+#define reg_pinmux_rw_pb_iop___pb12___lsb 12
+#define reg_pinmux_rw_pb_iop___pb12___width 1
+#define reg_pinmux_rw_pb_iop___pb12___bit 12
+#define reg_pinmux_rw_pb_iop___pb13___lsb 13
+#define reg_pinmux_rw_pb_iop___pb13___width 1
+#define reg_pinmux_rw_pb_iop___pb13___bit 13
+#define reg_pinmux_rw_pb_iop___pb14___lsb 14
+#define reg_pinmux_rw_pb_iop___pb14___width 1
+#define reg_pinmux_rw_pb_iop___pb14___bit 14
+#define reg_pinmux_rw_pb_iop___pb15___lsb 15
+#define reg_pinmux_rw_pb_iop___pb15___width 1
+#define reg_pinmux_rw_pb_iop___pb15___bit 15
+#define reg_pinmux_rw_pb_iop___pb16___lsb 16
+#define reg_pinmux_rw_pb_iop___pb16___width 1
+#define reg_pinmux_rw_pb_iop___pb16___bit 16
+#define reg_pinmux_rw_pb_iop___pb17___lsb 17
+#define reg_pinmux_rw_pb_iop___pb17___width 1
+#define reg_pinmux_rw_pb_iop___pb17___bit 17
+#define reg_pinmux_rw_pb_iop_offset 12
+
+/* Register rw_pc_gio, scope pinmux, type rw */
+#define reg_pinmux_rw_pc_gio___pc0___lsb 0
+#define reg_pinmux_rw_pc_gio___pc0___width 1
+#define reg_pinmux_rw_pc_gio___pc0___bit 0
+#define reg_pinmux_rw_pc_gio___pc1___lsb 1
+#define reg_pinmux_rw_pc_gio___pc1___width 1
+#define reg_pinmux_rw_pc_gio___pc1___bit 1
+#define reg_pinmux_rw_pc_gio___pc2___lsb 2
+#define reg_pinmux_rw_pc_gio___pc2___width 1
+#define reg_pinmux_rw_pc_gio___pc2___bit 2
+#define reg_pinmux_rw_pc_gio___pc3___lsb 3
+#define reg_pinmux_rw_pc_gio___pc3___width 1
+#define reg_pinmux_rw_pc_gio___pc3___bit 3
+#define reg_pinmux_rw_pc_gio___pc4___lsb 4
+#define reg_pinmux_rw_pc_gio___pc4___width 1
+#define reg_pinmux_rw_pc_gio___pc4___bit 4
+#define reg_pinmux_rw_pc_gio___pc5___lsb 5
+#define reg_pinmux_rw_pc_gio___pc5___width 1
+#define reg_pinmux_rw_pc_gio___pc5___bit 5
+#define reg_pinmux_rw_pc_gio___pc6___lsb 6
+#define reg_pinmux_rw_pc_gio___pc6___width 1
+#define reg_pinmux_rw_pc_gio___pc6___bit 6
+#define reg_pinmux_rw_pc_gio___pc7___lsb 7
+#define reg_pinmux_rw_pc_gio___pc7___width 1
+#define reg_pinmux_rw_pc_gio___pc7___bit 7
+#define reg_pinmux_rw_pc_gio___pc8___lsb 8
+#define reg_pinmux_rw_pc_gio___pc8___width 1
+#define reg_pinmux_rw_pc_gio___pc8___bit 8
+#define reg_pinmux_rw_pc_gio___pc9___lsb 9
+#define reg_pinmux_rw_pc_gio___pc9___width 1
+#define reg_pinmux_rw_pc_gio___pc9___bit 9
+#define reg_pinmux_rw_pc_gio___pc10___lsb 10
+#define reg_pinmux_rw_pc_gio___pc10___width 1
+#define reg_pinmux_rw_pc_gio___pc10___bit 10
+#define reg_pinmux_rw_pc_gio___pc11___lsb 11
+#define reg_pinmux_rw_pc_gio___pc11___width 1
+#define reg_pinmux_rw_pc_gio___pc11___bit 11
+#define reg_pinmux_rw_pc_gio___pc12___lsb 12
+#define reg_pinmux_rw_pc_gio___pc12___width 1
+#define reg_pinmux_rw_pc_gio___pc12___bit 12
+#define reg_pinmux_rw_pc_gio___pc13___lsb 13
+#define reg_pinmux_rw_pc_gio___pc13___width 1
+#define reg_pinmux_rw_pc_gio___pc13___bit 13
+#define reg_pinmux_rw_pc_gio___pc14___lsb 14
+#define reg_pinmux_rw_pc_gio___pc14___width 1
+#define reg_pinmux_rw_pc_gio___pc14___bit 14
+#define reg_pinmux_rw_pc_gio___pc15___lsb 15
+#define reg_pinmux_rw_pc_gio___pc15___width 1
+#define reg_pinmux_rw_pc_gio___pc15___bit 15
+#define reg_pinmux_rw_pc_gio___pc16___lsb 16
+#define reg_pinmux_rw_pc_gio___pc16___width 1
+#define reg_pinmux_rw_pc_gio___pc16___bit 16
+#define reg_pinmux_rw_pc_gio___pc17___lsb 17
+#define reg_pinmux_rw_pc_gio___pc17___width 1
+#define reg_pinmux_rw_pc_gio___pc17___bit 17
+#define reg_pinmux_rw_pc_gio_offset 16
+
+/* Register rw_pc_iop, scope pinmux, type rw */
+#define reg_pinmux_rw_pc_iop___pc0___lsb 0
+#define reg_pinmux_rw_pc_iop___pc0___width 1
+#define reg_pinmux_rw_pc_iop___pc0___bit 0
+#define reg_pinmux_rw_pc_iop___pc1___lsb 1
+#define reg_pinmux_rw_pc_iop___pc1___width 1
+#define reg_pinmux_rw_pc_iop___pc1___bit 1
+#define reg_pinmux_rw_pc_iop___pc2___lsb 2
+#define reg_pinmux_rw_pc_iop___pc2___width 1
+#define reg_pinmux_rw_pc_iop___pc2___bit 2
+#define reg_pinmux_rw_pc_iop___pc3___lsb 3
+#define reg_pinmux_rw_pc_iop___pc3___width 1
+#define reg_pinmux_rw_pc_iop___pc3___bit 3
+#define reg_pinmux_rw_pc_iop___pc4___lsb 4
+#define reg_pinmux_rw_pc_iop___pc4___width 1
+#define reg_pinmux_rw_pc_iop___pc4___bit 4
+#define reg_pinmux_rw_pc_iop___pc5___lsb 5
+#define reg_pinmux_rw_pc_iop___pc5___width 1
+#define reg_pinmux_rw_pc_iop___pc5___bit 5
+#define reg_pinmux_rw_pc_iop___pc6___lsb 6
+#define reg_pinmux_rw_pc_iop___pc6___width 1
+#define reg_pinmux_rw_pc_iop___pc6___bit 6
+#define reg_pinmux_rw_pc_iop___pc7___lsb 7
+#define reg_pinmux_rw_pc_iop___pc7___width 1
+#define reg_pinmux_rw_pc_iop___pc7___bit 7
+#define reg_pinmux_rw_pc_iop___pc8___lsb 8
+#define reg_pinmux_rw_pc_iop___pc8___width 1
+#define reg_pinmux_rw_pc_iop___pc8___bit 8
+#define reg_pinmux_rw_pc_iop___pc9___lsb 9
+#define reg_pinmux_rw_pc_iop___pc9___width 1
+#define reg_pinmux_rw_pc_iop___pc9___bit 9
+#define reg_pinmux_rw_pc_iop___pc10___lsb 10
+#define reg_pinmux_rw_pc_iop___pc10___width 1
+#define reg_pinmux_rw_pc_iop___pc10___bit 10
+#define reg_pinmux_rw_pc_iop___pc11___lsb 11
+#define reg_pinmux_rw_pc_iop___pc11___width 1
+#define reg_pinmux_rw_pc_iop___pc11___bit 11
+#define reg_pinmux_rw_pc_iop___pc12___lsb 12
+#define reg_pinmux_rw_pc_iop___pc12___width 1
+#define reg_pinmux_rw_pc_iop___pc12___bit 12
+#define reg_pinmux_rw_pc_iop___pc13___lsb 13
+#define reg_pinmux_rw_pc_iop___pc13___width 1
+#define reg_pinmux_rw_pc_iop___pc13___bit 13
+#define reg_pinmux_rw_pc_iop___pc14___lsb 14
+#define reg_pinmux_rw_pc_iop___pc14___width 1
+#define reg_pinmux_rw_pc_iop___pc14___bit 14
+#define reg_pinmux_rw_pc_iop___pc15___lsb 15
+#define reg_pinmux_rw_pc_iop___pc15___width 1
+#define reg_pinmux_rw_pc_iop___pc15___bit 15
+#define reg_pinmux_rw_pc_iop___pc16___lsb 16
+#define reg_pinmux_rw_pc_iop___pc16___width 1
+#define reg_pinmux_rw_pc_iop___pc16___bit 16
+#define reg_pinmux_rw_pc_iop___pc17___lsb 17
+#define reg_pinmux_rw_pc_iop___pc17___width 1
+#define reg_pinmux_rw_pc_iop___pc17___bit 17
+#define reg_pinmux_rw_pc_iop_offset 20
+
+/* Register rw_pd_gio, scope pinmux, type rw */
+#define reg_pinmux_rw_pd_gio___pd0___lsb 0
+#define reg_pinmux_rw_pd_gio___pd0___width 1
+#define reg_pinmux_rw_pd_gio___pd0___bit 0
+#define reg_pinmux_rw_pd_gio___pd1___lsb 1
+#define reg_pinmux_rw_pd_gio___pd1___width 1
+#define reg_pinmux_rw_pd_gio___pd1___bit 1
+#define reg_pinmux_rw_pd_gio___pd2___lsb 2
+#define reg_pinmux_rw_pd_gio___pd2___width 1
+#define reg_pinmux_rw_pd_gio___pd2___bit 2
+#define reg_pinmux_rw_pd_gio___pd3___lsb 3
+#define reg_pinmux_rw_pd_gio___pd3___width 1
+#define reg_pinmux_rw_pd_gio___pd3___bit 3
+#define reg_pinmux_rw_pd_gio___pd4___lsb 4
+#define reg_pinmux_rw_pd_gio___pd4___width 1
+#define reg_pinmux_rw_pd_gio___pd4___bit 4
+#define reg_pinmux_rw_pd_gio___pd5___lsb 5
+#define reg_pinmux_rw_pd_gio___pd5___width 1
+#define reg_pinmux_rw_pd_gio___pd5___bit 5
+#define reg_pinmux_rw_pd_gio___pd6___lsb 6
+#define reg_pinmux_rw_pd_gio___pd6___width 1
+#define reg_pinmux_rw_pd_gio___pd6___bit 6
+#define reg_pinmux_rw_pd_gio___pd7___lsb 7
+#define reg_pinmux_rw_pd_gio___pd7___width 1
+#define reg_pinmux_rw_pd_gio___pd7___bit 7
+#define reg_pinmux_rw_pd_gio___pd8___lsb 8
+#define reg_pinmux_rw_pd_gio___pd8___width 1
+#define reg_pinmux_rw_pd_gio___pd8___bit 8
+#define reg_pinmux_rw_pd_gio___pd9___lsb 9
+#define reg_pinmux_rw_pd_gio___pd9___width 1
+#define reg_pinmux_rw_pd_gio___pd9___bit 9
+#define reg_pinmux_rw_pd_gio___pd10___lsb 10
+#define reg_pinmux_rw_pd_gio___pd10___width 1
+#define reg_pinmux_rw_pd_gio___pd10___bit 10
+#define reg_pinmux_rw_pd_gio___pd11___lsb 11
+#define reg_pinmux_rw_pd_gio___pd11___width 1
+#define reg_pinmux_rw_pd_gio___pd11___bit 11
+#define reg_pinmux_rw_pd_gio___pd12___lsb 12
+#define reg_pinmux_rw_pd_gio___pd12___width 1
+#define reg_pinmux_rw_pd_gio___pd12___bit 12
+#define reg_pinmux_rw_pd_gio___pd13___lsb 13
+#define reg_pinmux_rw_pd_gio___pd13___width 1
+#define reg_pinmux_rw_pd_gio___pd13___bit 13
+#define reg_pinmux_rw_pd_gio___pd14___lsb 14
+#define reg_pinmux_rw_pd_gio___pd14___width 1
+#define reg_pinmux_rw_pd_gio___pd14___bit 14
+#define reg_pinmux_rw_pd_gio___pd15___lsb 15
+#define reg_pinmux_rw_pd_gio___pd15___width 1
+#define reg_pinmux_rw_pd_gio___pd15___bit 15
+#define reg_pinmux_rw_pd_gio___pd16___lsb 16
+#define reg_pinmux_rw_pd_gio___pd16___width 1
+#define reg_pinmux_rw_pd_gio___pd16___bit 16
+#define reg_pinmux_rw_pd_gio___pd17___lsb 17
+#define reg_pinmux_rw_pd_gio___pd17___width 1
+#define reg_pinmux_rw_pd_gio___pd17___bit 17
+#define reg_pinmux_rw_pd_gio_offset 24
+
+/* Register rw_pd_iop, scope pinmux, type rw */
+#define reg_pinmux_rw_pd_iop___pd0___lsb 0
+#define reg_pinmux_rw_pd_iop___pd0___width 1
+#define reg_pinmux_rw_pd_iop___pd0___bit 0
+#define reg_pinmux_rw_pd_iop___pd1___lsb 1
+#define reg_pinmux_rw_pd_iop___pd1___width 1
+#define reg_pinmux_rw_pd_iop___pd1___bit 1
+#define reg_pinmux_rw_pd_iop___pd2___lsb 2
+#define reg_pinmux_rw_pd_iop___pd2___width 1
+#define reg_pinmux_rw_pd_iop___pd2___bit 2
+#define reg_pinmux_rw_pd_iop___pd3___lsb 3
+#define reg_pinmux_rw_pd_iop___pd3___width 1
+#define reg_pinmux_rw_pd_iop___pd3___bit 3
+#define reg_pinmux_rw_pd_iop___pd4___lsb 4
+#define reg_pinmux_rw_pd_iop___pd4___width 1
+#define reg_pinmux_rw_pd_iop___pd4___bit 4
+#define reg_pinmux_rw_pd_iop___pd5___lsb 5
+#define reg_pinmux_rw_pd_iop___pd5___width 1
+#define reg_pinmux_rw_pd_iop___pd5___bit 5
+#define reg_pinmux_rw_pd_iop___pd6___lsb 6
+#define reg_pinmux_rw_pd_iop___pd6___width 1
+#define reg_pinmux_rw_pd_iop___pd6___bit 6
+#define reg_pinmux_rw_pd_iop___pd7___lsb 7
+#define reg_pinmux_rw_pd_iop___pd7___width 1
+#define reg_pinmux_rw_pd_iop___pd7___bit 7
+#define reg_pinmux_rw_pd_iop___pd8___lsb 8
+#define reg_pinmux_rw_pd_iop___pd8___width 1
+#define reg_pinmux_rw_pd_iop___pd8___bit 8
+#define reg_pinmux_rw_pd_iop___pd9___lsb 9
+#define reg_pinmux_rw_pd_iop___pd9___width 1
+#define reg_pinmux_rw_pd_iop___pd9___bit 9
+#define reg_pinmux_rw_pd_iop___pd10___lsb 10
+#define reg_pinmux_rw_pd_iop___pd10___width 1
+#define reg_pinmux_rw_pd_iop___pd10___bit 10
+#define reg_pinmux_rw_pd_iop___pd11___lsb 11
+#define reg_pinmux_rw_pd_iop___pd11___width 1
+#define reg_pinmux_rw_pd_iop___pd11___bit 11
+#define reg_pinmux_rw_pd_iop___pd12___lsb 12
+#define reg_pinmux_rw_pd_iop___pd12___width 1
+#define reg_pinmux_rw_pd_iop___pd12___bit 12
+#define reg_pinmux_rw_pd_iop___pd13___lsb 13
+#define reg_pinmux_rw_pd_iop___pd13___width 1
+#define reg_pinmux_rw_pd_iop___pd13___bit 13
+#define reg_pinmux_rw_pd_iop___pd14___lsb 14
+#define reg_pinmux_rw_pd_iop___pd14___width 1
+#define reg_pinmux_rw_pd_iop___pd14___bit 14
+#define reg_pinmux_rw_pd_iop___pd15___lsb 15
+#define reg_pinmux_rw_pd_iop___pd15___width 1
+#define reg_pinmux_rw_pd_iop___pd15___bit 15
+#define reg_pinmux_rw_pd_iop___pd16___lsb 16
+#define reg_pinmux_rw_pd_iop___pd16___width 1
+#define reg_pinmux_rw_pd_iop___pd16___bit 16
+#define reg_pinmux_rw_pd_iop___pd17___lsb 17
+#define reg_pinmux_rw_pd_iop___pd17___width 1
+#define reg_pinmux_rw_pd_iop___pd17___bit 17
+#define reg_pinmux_rw_pd_iop_offset 28
+
+/* Register rw_pe_gio, scope pinmux, type rw */
+#define reg_pinmux_rw_pe_gio___pe0___lsb 0
+#define reg_pinmux_rw_pe_gio___pe0___width 1
+#define reg_pinmux_rw_pe_gio___pe0___bit 0
+#define reg_pinmux_rw_pe_gio___pe1___lsb 1
+#define reg_pinmux_rw_pe_gio___pe1___width 1
+#define reg_pinmux_rw_pe_gio___pe1___bit 1
+#define reg_pinmux_rw_pe_gio___pe2___lsb 2
+#define reg_pinmux_rw_pe_gio___pe2___width 1
+#define reg_pinmux_rw_pe_gio___pe2___bit 2
+#define reg_pinmux_rw_pe_gio___pe3___lsb 3
+#define reg_pinmux_rw_pe_gio___pe3___width 1
+#define reg_pinmux_rw_pe_gio___pe3___bit 3
+#define reg_pinmux_rw_pe_gio___pe4___lsb 4
+#define reg_pinmux_rw_pe_gio___pe4___width 1
+#define reg_pinmux_rw_pe_gio___pe4___bit 4
+#define reg_pinmux_rw_pe_gio___pe5___lsb 5
+#define reg_pinmux_rw_pe_gio___pe5___width 1
+#define reg_pinmux_rw_pe_gio___pe5___bit 5
+#define reg_pinmux_rw_pe_gio___pe6___lsb 6
+#define reg_pinmux_rw_pe_gio___pe6___width 1
+#define reg_pinmux_rw_pe_gio___pe6___bit 6
+#define reg_pinmux_rw_pe_gio___pe7___lsb 7
+#define reg_pinmux_rw_pe_gio___pe7___width 1
+#define reg_pinmux_rw_pe_gio___pe7___bit 7
+#define reg_pinmux_rw_pe_gio___pe8___lsb 8
+#define reg_pinmux_rw_pe_gio___pe8___width 1
+#define reg_pinmux_rw_pe_gio___pe8___bit 8
+#define reg_pinmux_rw_pe_gio___pe9___lsb 9
+#define reg_pinmux_rw_pe_gio___pe9___width 1
+#define reg_pinmux_rw_pe_gio___pe9___bit 9
+#define reg_pinmux_rw_pe_gio___pe10___lsb 10
+#define reg_pinmux_rw_pe_gio___pe10___width 1
+#define reg_pinmux_rw_pe_gio___pe10___bit 10
+#define reg_pinmux_rw_pe_gio___pe11___lsb 11
+#define reg_pinmux_rw_pe_gio___pe11___width 1
+#define reg_pinmux_rw_pe_gio___pe11___bit 11
+#define reg_pinmux_rw_pe_gio___pe12___lsb 12
+#define reg_pinmux_rw_pe_gio___pe12___width 1
+#define reg_pinmux_rw_pe_gio___pe12___bit 12
+#define reg_pinmux_rw_pe_gio___pe13___lsb 13
+#define reg_pinmux_rw_pe_gio___pe13___width 1
+#define reg_pinmux_rw_pe_gio___pe13___bit 13
+#define reg_pinmux_rw_pe_gio___pe14___lsb 14
+#define reg_pinmux_rw_pe_gio___pe14___width 1
+#define reg_pinmux_rw_pe_gio___pe14___bit 14
+#define reg_pinmux_rw_pe_gio___pe15___lsb 15
+#define reg_pinmux_rw_pe_gio___pe15___width 1
+#define reg_pinmux_rw_pe_gio___pe15___bit 15
+#define reg_pinmux_rw_pe_gio___pe16___lsb 16
+#define reg_pinmux_rw_pe_gio___pe16___width 1
+#define reg_pinmux_rw_pe_gio___pe16___bit 16
+#define reg_pinmux_rw_pe_gio___pe17___lsb 17
+#define reg_pinmux_rw_pe_gio___pe17___width 1
+#define reg_pinmux_rw_pe_gio___pe17___bit 17
+#define reg_pinmux_rw_pe_gio_offset 32
+
+/* Register rw_pe_iop, scope pinmux, type rw */
+#define reg_pinmux_rw_pe_iop___pe0___lsb 0
+#define reg_pinmux_rw_pe_iop___pe0___width 1
+#define reg_pinmux_rw_pe_iop___pe0___bit 0
+#define reg_pinmux_rw_pe_iop___pe1___lsb 1
+#define reg_pinmux_rw_pe_iop___pe1___width 1
+#define reg_pinmux_rw_pe_iop___pe1___bit 1
+#define reg_pinmux_rw_pe_iop___pe2___lsb 2
+#define reg_pinmux_rw_pe_iop___pe2___width 1
+#define reg_pinmux_rw_pe_iop___pe2___bit 2
+#define reg_pinmux_rw_pe_iop___pe3___lsb 3
+#define reg_pinmux_rw_pe_iop___pe3___width 1
+#define reg_pinmux_rw_pe_iop___pe3___bit 3
+#define reg_pinmux_rw_pe_iop___pe4___lsb 4
+#define reg_pinmux_rw_pe_iop___pe4___width 1
+#define reg_pinmux_rw_pe_iop___pe4___bit 4
+#define reg_pinmux_rw_pe_iop___pe5___lsb 5
+#define reg_pinmux_rw_pe_iop___pe5___width 1
+#define reg_pinmux_rw_pe_iop___pe5___bit 5
+#define reg_pinmux_rw_pe_iop___pe6___lsb 6
+#define reg_pinmux_rw_pe_iop___pe6___width 1
+#define reg_pinmux_rw_pe_iop___pe6___bit 6
+#define reg_pinmux_rw_pe_iop___pe7___lsb 7
+#define reg_pinmux_rw_pe_iop___pe7___width 1
+#define reg_pinmux_rw_pe_iop___pe7___bit 7
+#define reg_pinmux_rw_pe_iop___pe8___lsb 8
+#define reg_pinmux_rw_pe_iop___pe8___width 1
+#define reg_pinmux_rw_pe_iop___pe8___bit 8
+#define reg_pinmux_rw_pe_iop___pe9___lsb 9
+#define reg_pinmux_rw_pe_iop___pe9___width 1
+#define reg_pinmux_rw_pe_iop___pe9___bit 9
+#define reg_pinmux_rw_pe_iop___pe10___lsb 10
+#define reg_pinmux_rw_pe_iop___pe10___width 1
+#define reg_pinmux_rw_pe_iop___pe10___bit 10
+#define reg_pinmux_rw_pe_iop___pe11___lsb 11
+#define reg_pinmux_rw_pe_iop___pe11___width 1
+#define reg_pinmux_rw_pe_iop___pe11___bit 11
+#define reg_pinmux_rw_pe_iop___pe12___lsb 12
+#define reg_pinmux_rw_pe_iop___pe12___width 1
+#define reg_pinmux_rw_pe_iop___pe12___bit 12
+#define reg_pinmux_rw_pe_iop___pe13___lsb 13
+#define reg_pinmux_rw_pe_iop___pe13___width 1
+#define reg_pinmux_rw_pe_iop___pe13___bit 13
+#define reg_pinmux_rw_pe_iop___pe14___lsb 14
+#define reg_pinmux_rw_pe_iop___pe14___width 1
+#define reg_pinmux_rw_pe_iop___pe14___bit 14
+#define reg_pinmux_rw_pe_iop___pe15___lsb 15
+#define reg_pinmux_rw_pe_iop___pe15___width 1
+#define reg_pinmux_rw_pe_iop___pe15___bit 15
+#define reg_pinmux_rw_pe_iop___pe16___lsb 16
+#define reg_pinmux_rw_pe_iop___pe16___width 1
+#define reg_pinmux_rw_pe_iop___pe16___bit 16
+#define reg_pinmux_rw_pe_iop___pe17___lsb 17
+#define reg_pinmux_rw_pe_iop___pe17___width 1
+#define reg_pinmux_rw_pe_iop___pe17___bit 17
+#define reg_pinmux_rw_pe_iop_offset 36
+
+/* Register rw_usb_phy, scope pinmux, type rw */
+#define reg_pinmux_rw_usb_phy___en_usb0___lsb 0
+#define reg_pinmux_rw_usb_phy___en_usb0___width 1
+#define reg_pinmux_rw_usb_phy___en_usb0___bit 0
+#define reg_pinmux_rw_usb_phy___en_usb1___lsb 1
+#define reg_pinmux_rw_usb_phy___en_usb1___width 1
+#define reg_pinmux_rw_usb_phy___en_usb1___bit 1
+#define reg_pinmux_rw_usb_phy_offset 40
+
+
+/* Constants */
+#define regk_pinmux_no                            0x00000000
+#define regk_pinmux_rw_hwprot_default             0x00000000
+#define regk_pinmux_rw_pa_default                 0x00000000
+#define regk_pinmux_rw_pb_gio_default             0x00000000
+#define regk_pinmux_rw_pb_iop_default             0x00000000
+#define regk_pinmux_rw_pc_gio_default             0x00000000
+#define regk_pinmux_rw_pc_iop_default             0x00000000
+#define regk_pinmux_rw_pd_gio_default             0x00000000
+#define regk_pinmux_rw_pd_iop_default             0x00000000
+#define regk_pinmux_rw_pe_gio_default             0x00000000
+#define regk_pinmux_rw_pe_iop_default             0x00000000
+#define regk_pinmux_rw_usb_phy_default            0x00000000
+#define regk_pinmux_yes                           0x00000001
+#endif /* __pinmux_defs_asm_h */
diff --git a/include/asm-cris/arch-v32/hwregs/asm/reg_map_asm.h b/include/asm-cris/arch-v32/hwregs/asm/reg_map_asm.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/asm/reg_map_asm.h
@@ -0,0 +1,96 @@
+#ifndef __reg_map_h
+#define __reg_map_h
+
+/*
+ * This file is autogenerated from
+ *   file:            ../../mod/fakereg.rmap
+ *     id:            fakereg.rmap,v 1.3 2004/02/11 19:53:22 ronny Exp
+ *     last modified: Wed Feb 11 20:53:25 2004
+ *   file:            ../../rtl/global.rmap
+ *     id:            global.rmap,v 1.3 2003/08/18 15:08:23 mikaeln Exp
+ *     last modified: Mon Aug 18 17:08:23 2003
+ *   file:            ../../mod/modreg.rmap
+ *     id:            modreg.rmap,v 1.31 2004/02/20 15:40:04 stefans Exp
+ *     last modified: Fri Feb 20 16:40:04 2004
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c -asm --outfile asm/reg_map_asm.h -base 0xb0000000 ../../rtl/global.rmap ../../mod/modreg.rmap ../../inst/memarb/rtl/guinness/marb_top.r ../../mod/fakereg.rmap
+ *      id: $Id: reg_map_asm.h,v 1.1 2005/04/24 18:31:04 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+#define regi_artpec_mod                           0xb7044000
+#define regi_ata                                  0xb0032000
+#define regi_ata_mod                              0xb7006000
+#define regi_barber                               0xb701a000
+#define regi_bif_core                             0xb0014000
+#define regi_bif_dma                              0xb0016000
+#define regi_bif_slave                            0xb0018000
+#define regi_bif_slave_ext                        0xac000000
+#define regi_bus_master                           0xb703c000
+#define regi_config                               0xb003c000
+#define regi_dma0                                 0xb0000000
+#define regi_dma1                                 0xb0002000
+#define regi_dma2                                 0xb0004000
+#define regi_dma3                                 0xb0006000
+#define regi_dma4                                 0xb0008000
+#define regi_dma5                                 0xb000a000
+#define regi_dma6                                 0xb000c000
+#define regi_dma7                                 0xb000e000
+#define regi_dma8                                 0xb0010000
+#define regi_dma9                                 0xb0012000
+#define regi_eth0                                 0xb0034000
+#define regi_eth1                                 0xb0036000
+#define regi_eth_mod                              0xb7004000
+#define regi_eth_mod1                             0xb701c000
+#define regi_eth_strmod                           0xb7008000
+#define regi_eth_strmod1                          0xb7032000
+#define regi_ext_dma                              0xb703a000
+#define regi_ext_mem                              0xb7046000
+#define regi_gen_io                               0xb7016000
+#define regi_gio                                  0xb001a000
+#define regi_hook                                 0xb7000000
+#define regi_iop                                  0xb0020000
+#define regi_irq                                  0xb001c000
+#define regi_irq_nmi                              0xb701e000
+#define regi_marb                                 0xb003e000
+#define regi_marb_bp0                             0xb003e240
+#define regi_marb_bp1                             0xb003e280
+#define regi_marb_bp2                             0xb003e2c0
+#define regi_marb_bp3                             0xb003e300
+#define regi_nand_mod                             0xb7014000
+#define regi_p21                                  0xb002e000
+#define regi_p21_mod                              0xb7042000
+#define regi_pci_mod                              0xb7010000
+#define regi_pin_test                             0xb7018000
+#define regi_pinmux                               0xb0038000
+#define regi_sdram_chk                            0xb703e000
+#define regi_sdram_mod                            0xb7012000
+#define regi_ser0                                 0xb0026000
+#define regi_ser1                                 0xb0028000
+#define regi_ser2                                 0xb002a000
+#define regi_ser3                                 0xb002c000
+#define regi_ser_mod0                             0xb7020000
+#define regi_ser_mod1                             0xb7022000
+#define regi_ser_mod2                             0xb7024000
+#define regi_ser_mod3                             0xb7026000
+#define regi_smif_stat                            0xb700e000
+#define regi_sser0                                0xb0022000
+#define regi_sser1                                0xb0024000
+#define regi_sser_mod0                            0xb700a000
+#define regi_sser_mod1                            0xb700c000
+#define regi_strcop                               0xb0030000
+#define regi_strmux                               0xb003a000
+#define regi_strmux_tst                           0xb7040000
+#define regi_tap                                  0xb7002000
+#define regi_timer                                0xb001e000
+#define regi_timer_mod                            0xb7034000
+#define regi_trace                                0xb0040000
+#define regi_usb0                                 0xb7028000
+#define regi_usb1                                 0xb702a000
+#define regi_usb2                                 0xb702c000
+#define regi_usb3                                 0xb702e000
+#define regi_usb_dev                              0xb7030000
+#define regi_utmi_mod0                            0xb7036000
+#define regi_utmi_mod1                            0xb7038000
+#endif /* __reg_map_h */
diff --git a/include/asm-cris/arch-v32/hwregs/asm/rt_trace_defs_asm.h b/include/asm-cris/arch-v32/hwregs/asm/rt_trace_defs_asm.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/asm/rt_trace_defs_asm.h
@@ -0,0 +1,142 @@
+#ifndef __rt_trace_defs_asm_h
+#define __rt_trace_defs_asm_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/rt_trace/rtl/rt_regs.r
+ *     id:           rt_regs.r,v 1.18 2005/02/08 15:45:00 stefans Exp
+ *     last modfied: Mon Apr 11 16:09:14 2005
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c -asm --outfile asm/rt_trace_defs_asm.h ../../inst/rt_trace/rtl/rt_regs.r
+ *      id: $Id: rt_trace_defs_asm.h,v 1.1 2005/04/24 18:31:04 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+
+#ifndef REG_FIELD
+#define REG_FIELD( scope, reg, field, value ) \
+  REG_FIELD_X_( value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_FIELD_X_( value, shift ) ((value) << shift)
+#endif
+
+#ifndef REG_STATE
+#define REG_STATE( scope, reg, field, symbolic_value ) \
+  REG_STATE_X_( regk_##scope##_##symbolic_value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_STATE_X_( k, shift ) (k << shift)
+#endif
+
+#ifndef REG_MASK
+#define REG_MASK( scope, reg, field ) \
+  REG_MASK_X_( reg_##scope##_##reg##___##field##___width, reg_##scope##_##reg##___##field##___lsb )
+#define REG_MASK_X_( width, lsb ) (((1 << width)-1) << lsb)
+#endif
+
+#ifndef REG_LSB
+#define REG_LSB( scope, reg, field ) reg_##scope##_##reg##___##field##___lsb
+#endif
+
+#ifndef REG_BIT
+#define REG_BIT( scope, reg, field ) reg_##scope##_##reg##___##field##___bit
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) REG_ADDR_X_(inst, reg_##scope##_##reg##_offset)
+#define REG_ADDR_X_( inst, offs ) ((inst) + offs)
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+         REG_ADDR_VECT_X_(inst, reg_##scope##_##reg##_offset, index, \
+			 STRIDE_##scope##_##reg )
+#define REG_ADDR_VECT_X_( inst, offs, index, stride ) \
+                          ((inst) + offs + (index) * stride)
+#endif
+
+/* Register rw_cfg, scope rt_trace, type rw */
+#define reg_rt_trace_rw_cfg___en___lsb 0
+#define reg_rt_trace_rw_cfg___en___width 1
+#define reg_rt_trace_rw_cfg___en___bit 0
+#define reg_rt_trace_rw_cfg___mode___lsb 1
+#define reg_rt_trace_rw_cfg___mode___width 1
+#define reg_rt_trace_rw_cfg___mode___bit 1
+#define reg_rt_trace_rw_cfg___owner___lsb 2
+#define reg_rt_trace_rw_cfg___owner___width 1
+#define reg_rt_trace_rw_cfg___owner___bit 2
+#define reg_rt_trace_rw_cfg___wp___lsb 3
+#define reg_rt_trace_rw_cfg___wp___width 1
+#define reg_rt_trace_rw_cfg___wp___bit 3
+#define reg_rt_trace_rw_cfg___stall___lsb 4
+#define reg_rt_trace_rw_cfg___stall___width 1
+#define reg_rt_trace_rw_cfg___stall___bit 4
+#define reg_rt_trace_rw_cfg___wp_start___lsb 8
+#define reg_rt_trace_rw_cfg___wp_start___width 7
+#define reg_rt_trace_rw_cfg___wp_stop___lsb 16
+#define reg_rt_trace_rw_cfg___wp_stop___width 7
+#define reg_rt_trace_rw_cfg_offset 0
+
+/* Register rw_tap_ctrl, scope rt_trace, type rw */
+#define reg_rt_trace_rw_tap_ctrl___ack_data___lsb 0
+#define reg_rt_trace_rw_tap_ctrl___ack_data___width 1
+#define reg_rt_trace_rw_tap_ctrl___ack_data___bit 0
+#define reg_rt_trace_rw_tap_ctrl___ack_guru___lsb 1
+#define reg_rt_trace_rw_tap_ctrl___ack_guru___width 1
+#define reg_rt_trace_rw_tap_ctrl___ack_guru___bit 1
+#define reg_rt_trace_rw_tap_ctrl_offset 4
+
+/* Register r_tap_stat, scope rt_trace, type r */
+#define reg_rt_trace_r_tap_stat___dav___lsb 0
+#define reg_rt_trace_r_tap_stat___dav___width 1
+#define reg_rt_trace_r_tap_stat___dav___bit 0
+#define reg_rt_trace_r_tap_stat___empty___lsb 1
+#define reg_rt_trace_r_tap_stat___empty___width 1
+#define reg_rt_trace_r_tap_stat___empty___bit 1
+#define reg_rt_trace_r_tap_stat_offset 8
+
+/* Register rw_tap_data, scope rt_trace, type rw */
+#define reg_rt_trace_rw_tap_data_offset 12
+
+/* Register rw_tap_hdata, scope rt_trace, type rw */
+#define reg_rt_trace_rw_tap_hdata___op___lsb 0
+#define reg_rt_trace_rw_tap_hdata___op___width 4
+#define reg_rt_trace_rw_tap_hdata___sub_op___lsb 4
+#define reg_rt_trace_rw_tap_hdata___sub_op___width 4
+#define reg_rt_trace_rw_tap_hdata_offset 16
+
+/* Register r_redir, scope rt_trace, type r */
+#define reg_rt_trace_r_redir_offset 20
+
+
+/* Constants */
+#define regk_rt_trace_brk                         0x0000000c
+#define regk_rt_trace_dbg                         0x00000003
+#define regk_rt_trace_dbgdi                       0x00000004
+#define regk_rt_trace_dbgdo                       0x00000005
+#define regk_rt_trace_gmode                       0x00000000
+#define regk_rt_trace_no                          0x00000000
+#define regk_rt_trace_nop                         0x00000000
+#define regk_rt_trace_normal                      0x00000000
+#define regk_rt_trace_rdmem                       0x00000007
+#define regk_rt_trace_rdmemb                      0x00000009
+#define regk_rt_trace_rdpreg                      0x00000002
+#define regk_rt_trace_rdreg                       0x00000001
+#define regk_rt_trace_rdsreg                      0x00000003
+#define regk_rt_trace_redir                       0x00000006
+#define regk_rt_trace_ret                         0x0000000b
+#define regk_rt_trace_rw_cfg_default              0x00000000
+#define regk_rt_trace_trcfg                       0x00000001
+#define regk_rt_trace_wp                          0x00000001
+#define regk_rt_trace_wp0                         0x00000001
+#define regk_rt_trace_wp1                         0x00000002
+#define regk_rt_trace_wp2                         0x00000004
+#define regk_rt_trace_wp3                         0x00000008
+#define regk_rt_trace_wp4                         0x00000010
+#define regk_rt_trace_wp5                         0x00000020
+#define regk_rt_trace_wp6                         0x00000040
+#define regk_rt_trace_wrmem                       0x00000008
+#define regk_rt_trace_wrmemb                      0x0000000a
+#define regk_rt_trace_wrpreg                      0x00000005
+#define regk_rt_trace_wrreg                       0x00000004
+#define regk_rt_trace_wrsreg                      0x00000006
+#define regk_rt_trace_yes                         0x00000001
+#endif /* __rt_trace_defs_asm_h */
diff --git a/include/asm-cris/arch-v32/hwregs/asm/ser_defs_asm.h b/include/asm-cris/arch-v32/hwregs/asm/ser_defs_asm.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/asm/ser_defs_asm.h
@@ -0,0 +1,359 @@
+#ifndef __ser_defs_asm_h
+#define __ser_defs_asm_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/ser/rtl/ser_regs.r
+ *     id:           ser_regs.r,v 1.23 2005/02/08 13:58:35 perz Exp
+ *     last modfied: Mon Apr 11 16:09:21 2005
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c -asm --outfile asm/ser_defs_asm.h ../../inst/ser/rtl/ser_regs.r
+ *      id: $Id: ser_defs_asm.h,v 1.1 2005/04/24 18:31:04 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+
+#ifndef REG_FIELD
+#define REG_FIELD( scope, reg, field, value ) \
+  REG_FIELD_X_( value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_FIELD_X_( value, shift ) ((value) << shift)
+#endif
+
+#ifndef REG_STATE
+#define REG_STATE( scope, reg, field, symbolic_value ) \
+  REG_STATE_X_( regk_##scope##_##symbolic_value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_STATE_X_( k, shift ) (k << shift)
+#endif
+
+#ifndef REG_MASK
+#define REG_MASK( scope, reg, field ) \
+  REG_MASK_X_( reg_##scope##_##reg##___##field##___width, reg_##scope##_##reg##___##field##___lsb )
+#define REG_MASK_X_( width, lsb ) (((1 << width)-1) << lsb)
+#endif
+
+#ifndef REG_LSB
+#define REG_LSB( scope, reg, field ) reg_##scope##_##reg##___##field##___lsb
+#endif
+
+#ifndef REG_BIT
+#define REG_BIT( scope, reg, field ) reg_##scope##_##reg##___##field##___bit
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) REG_ADDR_X_(inst, reg_##scope##_##reg##_offset)
+#define REG_ADDR_X_( inst, offs ) ((inst) + offs)
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+         REG_ADDR_VECT_X_(inst, reg_##scope##_##reg##_offset, index, \
+			 STRIDE_##scope##_##reg )
+#define REG_ADDR_VECT_X_( inst, offs, index, stride ) \
+                          ((inst) + offs + (index) * stride)
+#endif
+
+/* Register rw_tr_ctrl, scope ser, type rw */
+#define reg_ser_rw_tr_ctrl___base_freq___lsb 0
+#define reg_ser_rw_tr_ctrl___base_freq___width 3
+#define reg_ser_rw_tr_ctrl___en___lsb 3
+#define reg_ser_rw_tr_ctrl___en___width 1
+#define reg_ser_rw_tr_ctrl___en___bit 3
+#define reg_ser_rw_tr_ctrl___par___lsb 4
+#define reg_ser_rw_tr_ctrl___par___width 2
+#define reg_ser_rw_tr_ctrl___par_en___lsb 6
+#define reg_ser_rw_tr_ctrl___par_en___width 1
+#define reg_ser_rw_tr_ctrl___par_en___bit 6
+#define reg_ser_rw_tr_ctrl___data_bits___lsb 7
+#define reg_ser_rw_tr_ctrl___data_bits___width 1
+#define reg_ser_rw_tr_ctrl___data_bits___bit 7
+#define reg_ser_rw_tr_ctrl___stop_bits___lsb 8
+#define reg_ser_rw_tr_ctrl___stop_bits___width 1
+#define reg_ser_rw_tr_ctrl___stop_bits___bit 8
+#define reg_ser_rw_tr_ctrl___stop___lsb 9
+#define reg_ser_rw_tr_ctrl___stop___width 1
+#define reg_ser_rw_tr_ctrl___stop___bit 9
+#define reg_ser_rw_tr_ctrl___rts_delay___lsb 10
+#define reg_ser_rw_tr_ctrl___rts_delay___width 3
+#define reg_ser_rw_tr_ctrl___rts_setup___lsb 13
+#define reg_ser_rw_tr_ctrl___rts_setup___width 1
+#define reg_ser_rw_tr_ctrl___rts_setup___bit 13
+#define reg_ser_rw_tr_ctrl___auto_rts___lsb 14
+#define reg_ser_rw_tr_ctrl___auto_rts___width 1
+#define reg_ser_rw_tr_ctrl___auto_rts___bit 14
+#define reg_ser_rw_tr_ctrl___txd___lsb 15
+#define reg_ser_rw_tr_ctrl___txd___width 1
+#define reg_ser_rw_tr_ctrl___txd___bit 15
+#define reg_ser_rw_tr_ctrl___auto_cts___lsb 16
+#define reg_ser_rw_tr_ctrl___auto_cts___width 1
+#define reg_ser_rw_tr_ctrl___auto_cts___bit 16
+#define reg_ser_rw_tr_ctrl_offset 0
+
+/* Register rw_tr_dma_en, scope ser, type rw */
+#define reg_ser_rw_tr_dma_en___en___lsb 0
+#define reg_ser_rw_tr_dma_en___en___width 1
+#define reg_ser_rw_tr_dma_en___en___bit 0
+#define reg_ser_rw_tr_dma_en_offset 4
+
+/* Register rw_rec_ctrl, scope ser, type rw */
+#define reg_ser_rw_rec_ctrl___base_freq___lsb 0
+#define reg_ser_rw_rec_ctrl___base_freq___width 3
+#define reg_ser_rw_rec_ctrl___en___lsb 3
+#define reg_ser_rw_rec_ctrl___en___width 1
+#define reg_ser_rw_rec_ctrl___en___bit 3
+#define reg_ser_rw_rec_ctrl___par___lsb 4
+#define reg_ser_rw_rec_ctrl___par___width 2
+#define reg_ser_rw_rec_ctrl___par_en___lsb 6
+#define reg_ser_rw_rec_ctrl___par_en___width 1
+#define reg_ser_rw_rec_ctrl___par_en___bit 6
+#define reg_ser_rw_rec_ctrl___data_bits___lsb 7
+#define reg_ser_rw_rec_ctrl___data_bits___width 1
+#define reg_ser_rw_rec_ctrl___data_bits___bit 7
+#define reg_ser_rw_rec_ctrl___dma_mode___lsb 8
+#define reg_ser_rw_rec_ctrl___dma_mode___width 1
+#define reg_ser_rw_rec_ctrl___dma_mode___bit 8
+#define reg_ser_rw_rec_ctrl___dma_err___lsb 9
+#define reg_ser_rw_rec_ctrl___dma_err___width 1
+#define reg_ser_rw_rec_ctrl___dma_err___bit 9
+#define reg_ser_rw_rec_ctrl___sampling___lsb 10
+#define reg_ser_rw_rec_ctrl___sampling___width 1
+#define reg_ser_rw_rec_ctrl___sampling___bit 10
+#define reg_ser_rw_rec_ctrl___timeout___lsb 11
+#define reg_ser_rw_rec_ctrl___timeout___width 3
+#define reg_ser_rw_rec_ctrl___auto_eop___lsb 14
+#define reg_ser_rw_rec_ctrl___auto_eop___width 1
+#define reg_ser_rw_rec_ctrl___auto_eop___bit 14
+#define reg_ser_rw_rec_ctrl___half_duplex___lsb 15
+#define reg_ser_rw_rec_ctrl___half_duplex___width 1
+#define reg_ser_rw_rec_ctrl___half_duplex___bit 15
+#define reg_ser_rw_rec_ctrl___rts_n___lsb 16
+#define reg_ser_rw_rec_ctrl___rts_n___width 1
+#define reg_ser_rw_rec_ctrl___rts_n___bit 16
+#define reg_ser_rw_rec_ctrl___loopback___lsb 17
+#define reg_ser_rw_rec_ctrl___loopback___width 1
+#define reg_ser_rw_rec_ctrl___loopback___bit 17
+#define reg_ser_rw_rec_ctrl_offset 8
+
+/* Register rw_tr_baud_div, scope ser, type rw */
+#define reg_ser_rw_tr_baud_div___div___lsb 0
+#define reg_ser_rw_tr_baud_div___div___width 16
+#define reg_ser_rw_tr_baud_div_offset 12
+
+/* Register rw_rec_baud_div, scope ser, type rw */
+#define reg_ser_rw_rec_baud_div___div___lsb 0
+#define reg_ser_rw_rec_baud_div___div___width 16
+#define reg_ser_rw_rec_baud_div_offset 16
+
+/* Register rw_xoff, scope ser, type rw */
+#define reg_ser_rw_xoff___chr___lsb 0
+#define reg_ser_rw_xoff___chr___width 8
+#define reg_ser_rw_xoff___automatic___lsb 8
+#define reg_ser_rw_xoff___automatic___width 1
+#define reg_ser_rw_xoff___automatic___bit 8
+#define reg_ser_rw_xoff_offset 20
+
+/* Register rw_xoff_clr, scope ser, type rw */
+#define reg_ser_rw_xoff_clr___clr___lsb 0
+#define reg_ser_rw_xoff_clr___clr___width 1
+#define reg_ser_rw_xoff_clr___clr___bit 0
+#define reg_ser_rw_xoff_clr_offset 24
+
+/* Register rw_dout, scope ser, type rw */
+#define reg_ser_rw_dout___data___lsb 0
+#define reg_ser_rw_dout___data___width 8
+#define reg_ser_rw_dout_offset 28
+
+/* Register rs_stat_din, scope ser, type rs */
+#define reg_ser_rs_stat_din___data___lsb 0
+#define reg_ser_rs_stat_din___data___width 8
+#define reg_ser_rs_stat_din___dav___lsb 16
+#define reg_ser_rs_stat_din___dav___width 1
+#define reg_ser_rs_stat_din___dav___bit 16
+#define reg_ser_rs_stat_din___framing_err___lsb 17
+#define reg_ser_rs_stat_din___framing_err___width 1
+#define reg_ser_rs_stat_din___framing_err___bit 17
+#define reg_ser_rs_stat_din___par_err___lsb 18
+#define reg_ser_rs_stat_din___par_err___width 1
+#define reg_ser_rs_stat_din___par_err___bit 18
+#define reg_ser_rs_stat_din___orun___lsb 19
+#define reg_ser_rs_stat_din___orun___width 1
+#define reg_ser_rs_stat_din___orun___bit 19
+#define reg_ser_rs_stat_din___rec_err___lsb 20
+#define reg_ser_rs_stat_din___rec_err___width 1
+#define reg_ser_rs_stat_din___rec_err___bit 20
+#define reg_ser_rs_stat_din___rxd___lsb 21
+#define reg_ser_rs_stat_din___rxd___width 1
+#define reg_ser_rs_stat_din___rxd___bit 21
+#define reg_ser_rs_stat_din___tr_idle___lsb 22
+#define reg_ser_rs_stat_din___tr_idle___width 1
+#define reg_ser_rs_stat_din___tr_idle___bit 22
+#define reg_ser_rs_stat_din___tr_empty___lsb 23
+#define reg_ser_rs_stat_din___tr_empty___width 1
+#define reg_ser_rs_stat_din___tr_empty___bit 23
+#define reg_ser_rs_stat_din___tr_rdy___lsb 24
+#define reg_ser_rs_stat_din___tr_rdy___width 1
+#define reg_ser_rs_stat_din___tr_rdy___bit 24
+#define reg_ser_rs_stat_din___cts_n___lsb 25
+#define reg_ser_rs_stat_din___cts_n___width 1
+#define reg_ser_rs_stat_din___cts_n___bit 25
+#define reg_ser_rs_stat_din___xoff_detect___lsb 26
+#define reg_ser_rs_stat_din___xoff_detect___width 1
+#define reg_ser_rs_stat_din___xoff_detect___bit 26
+#define reg_ser_rs_stat_din___rts_n___lsb 27
+#define reg_ser_rs_stat_din___rts_n___width 1
+#define reg_ser_rs_stat_din___rts_n___bit 27
+#define reg_ser_rs_stat_din___txd___lsb 28
+#define reg_ser_rs_stat_din___txd___width 1
+#define reg_ser_rs_stat_din___txd___bit 28
+#define reg_ser_rs_stat_din_offset 32
+
+/* Register r_stat_din, scope ser, type r */
+#define reg_ser_r_stat_din___data___lsb 0
+#define reg_ser_r_stat_din___data___width 8
+#define reg_ser_r_stat_din___dav___lsb 16
+#define reg_ser_r_stat_din___dav___width 1
+#define reg_ser_r_stat_din___dav___bit 16
+#define reg_ser_r_stat_din___framing_err___lsb 17
+#define reg_ser_r_stat_din___framing_err___width 1
+#define reg_ser_r_stat_din___framing_err___bit 17
+#define reg_ser_r_stat_din___par_err___lsb 18
+#define reg_ser_r_stat_din___par_err___width 1
+#define reg_ser_r_stat_din___par_err___bit 18
+#define reg_ser_r_stat_din___orun___lsb 19
+#define reg_ser_r_stat_din___orun___width 1
+#define reg_ser_r_stat_din___orun___bit 19
+#define reg_ser_r_stat_din___rec_err___lsb 20
+#define reg_ser_r_stat_din___rec_err___width 1
+#define reg_ser_r_stat_din___rec_err___bit 20
+#define reg_ser_r_stat_din___rxd___lsb 21
+#define reg_ser_r_stat_din___rxd___width 1
+#define reg_ser_r_stat_din___rxd___bit 21
+#define reg_ser_r_stat_din___tr_idle___lsb 22
+#define reg_ser_r_stat_din___tr_idle___width 1
+#define reg_ser_r_stat_din___tr_idle___bit 22
+#define reg_ser_r_stat_din___tr_empty___lsb 23
+#define reg_ser_r_stat_din___tr_empty___width 1
+#define reg_ser_r_stat_din___tr_empty___bit 23
+#define reg_ser_r_stat_din___tr_rdy___lsb 24
+#define reg_ser_r_stat_din___tr_rdy___width 1
+#define reg_ser_r_stat_din___tr_rdy___bit 24
+#define reg_ser_r_stat_din___cts_n___lsb 25
+#define reg_ser_r_stat_din___cts_n___width 1
+#define reg_ser_r_stat_din___cts_n___bit 25
+#define reg_ser_r_stat_din___xoff_detect___lsb 26
+#define reg_ser_r_stat_din___xoff_detect___width 1
+#define reg_ser_r_stat_din___xoff_detect___bit 26
+#define reg_ser_r_stat_din___rts_n___lsb 27
+#define reg_ser_r_stat_din___rts_n___width 1
+#define reg_ser_r_stat_din___rts_n___bit 27
+#define reg_ser_r_stat_din___txd___lsb 28
+#define reg_ser_r_stat_din___txd___width 1
+#define reg_ser_r_stat_din___txd___bit 28
+#define reg_ser_r_stat_din_offset 36
+
+/* Register rw_rec_eop, scope ser, type rw */
+#define reg_ser_rw_rec_eop___set___lsb 0
+#define reg_ser_rw_rec_eop___set___width 1
+#define reg_ser_rw_rec_eop___set___bit 0
+#define reg_ser_rw_rec_eop_offset 40
+
+/* Register rw_intr_mask, scope ser, type rw */
+#define reg_ser_rw_intr_mask___tr_rdy___lsb 0
+#define reg_ser_rw_intr_mask___tr_rdy___width 1
+#define reg_ser_rw_intr_mask___tr_rdy___bit 0
+#define reg_ser_rw_intr_mask___tr_empty___lsb 1
+#define reg_ser_rw_intr_mask___tr_empty___width 1
+#define reg_ser_rw_intr_mask___tr_empty___bit 1
+#define reg_ser_rw_intr_mask___tr_idle___lsb 2
+#define reg_ser_rw_intr_mask___tr_idle___width 1
+#define reg_ser_rw_intr_mask___tr_idle___bit 2
+#define reg_ser_rw_intr_mask___dav___lsb 3
+#define reg_ser_rw_intr_mask___dav___width 1
+#define reg_ser_rw_intr_mask___dav___bit 3
+#define reg_ser_rw_intr_mask_offset 44
+
+/* Register rw_ack_intr, scope ser, type rw */
+#define reg_ser_rw_ack_intr___tr_rdy___lsb 0
+#define reg_ser_rw_ack_intr___tr_rdy___width 1
+#define reg_ser_rw_ack_intr___tr_rdy___bit 0
+#define reg_ser_rw_ack_intr___tr_empty___lsb 1
+#define reg_ser_rw_ack_intr___tr_empty___width 1
+#define reg_ser_rw_ack_intr___tr_empty___bit 1
+#define reg_ser_rw_ack_intr___tr_idle___lsb 2
+#define reg_ser_rw_ack_intr___tr_idle___width 1
+#define reg_ser_rw_ack_intr___tr_idle___bit 2
+#define reg_ser_rw_ack_intr___dav___lsb 3
+#define reg_ser_rw_ack_intr___dav___width 1
+#define reg_ser_rw_ack_intr___dav___bit 3
+#define reg_ser_rw_ack_intr_offset 48
+
+/* Register r_intr, scope ser, type r */
+#define reg_ser_r_intr___tr_rdy___lsb 0
+#define reg_ser_r_intr___tr_rdy___width 1
+#define reg_ser_r_intr___tr_rdy___bit 0
+#define reg_ser_r_intr___tr_empty___lsb 1
+#define reg_ser_r_intr___tr_empty___width 1
+#define reg_ser_r_intr___tr_empty___bit 1
+#define reg_ser_r_intr___tr_idle___lsb 2
+#define reg_ser_r_intr___tr_idle___width 1
+#define reg_ser_r_intr___tr_idle___bit 2
+#define reg_ser_r_intr___dav___lsb 3
+#define reg_ser_r_intr___dav___width 1
+#define reg_ser_r_intr___dav___bit 3
+#define reg_ser_r_intr_offset 52
+
+/* Register r_masked_intr, scope ser, type r */
+#define reg_ser_r_masked_intr___tr_rdy___lsb 0
+#define reg_ser_r_masked_intr___tr_rdy___width 1
+#define reg_ser_r_masked_intr___tr_rdy___bit 0
+#define reg_ser_r_masked_intr___tr_empty___lsb 1
+#define reg_ser_r_masked_intr___tr_empty___width 1
+#define reg_ser_r_masked_intr___tr_empty___bit 1
+#define reg_ser_r_masked_intr___tr_idle___lsb 2
+#define reg_ser_r_masked_intr___tr_idle___width 1
+#define reg_ser_r_masked_intr___tr_idle___bit 2
+#define reg_ser_r_masked_intr___dav___lsb 3
+#define reg_ser_r_masked_intr___dav___width 1
+#define reg_ser_r_masked_intr___dav___bit 3
+#define reg_ser_r_masked_intr_offset 56
+
+
+/* Constants */
+#define regk_ser_active                           0x00000000
+#define regk_ser_bits1                            0x00000000
+#define regk_ser_bits2                            0x00000001
+#define regk_ser_bits7                            0x00000001
+#define regk_ser_bits8                            0x00000000
+#define regk_ser_del0_5                           0x00000000
+#define regk_ser_del1                             0x00000001
+#define regk_ser_del1_5                           0x00000002
+#define regk_ser_del2                             0x00000003
+#define regk_ser_del2_5                           0x00000004
+#define regk_ser_del3                             0x00000005
+#define regk_ser_del3_5                           0x00000006
+#define regk_ser_del4                             0x00000007
+#define regk_ser_even                             0x00000000
+#define regk_ser_ext                              0x00000001
+#define regk_ser_f100                             0x00000007
+#define regk_ser_f29_493                          0x00000004
+#define regk_ser_f32                              0x00000005
+#define regk_ser_f32_768                          0x00000006
+#define regk_ser_ignore                           0x00000001
+#define regk_ser_inactive                         0x00000001
+#define regk_ser_majority                         0x00000001
+#define regk_ser_mark                             0x00000002
+#define regk_ser_middle                           0x00000000
+#define regk_ser_no                               0x00000000
+#define regk_ser_odd                              0x00000001
+#define regk_ser_off                              0x00000000
+#define regk_ser_rw_intr_mask_default             0x00000000
+#define regk_ser_rw_rec_baud_div_default          0x00000000
+#define regk_ser_rw_rec_ctrl_default              0x00010000
+#define regk_ser_rw_tr_baud_div_default           0x00000000
+#define regk_ser_rw_tr_ctrl_default               0x00008000
+#define regk_ser_rw_tr_dma_en_default             0x00000000
+#define regk_ser_rw_xoff_default                  0x00000000
+#define regk_ser_space                            0x00000003
+#define regk_ser_stop                             0x00000000
+#define regk_ser_yes                              0x00000001
+#endif /* __ser_defs_asm_h */
diff --git a/include/asm-cris/arch-v32/hwregs/asm/sser_defs_asm.h b/include/asm-cris/arch-v32/hwregs/asm/sser_defs_asm.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/asm/sser_defs_asm.h
@@ -0,0 +1,462 @@
+#ifndef __sser_defs_asm_h
+#define __sser_defs_asm_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/syncser/rtl/sser_regs.r
+ *     id:           sser_regs.r,v 1.24 2005/02/11 14:27:36 gunnard Exp
+ *     last modfied: Mon Apr 11 16:09:48 2005
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c -asm --outfile asm/sser_defs_asm.h ../../inst/syncser/rtl/sser_regs.r
+ *      id: $Id: sser_defs_asm.h,v 1.1 2005/04/24 18:31:04 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+
+#ifndef REG_FIELD
+#define REG_FIELD( scope, reg, field, value ) \
+  REG_FIELD_X_( value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_FIELD_X_( value, shift ) ((value) << shift)
+#endif
+
+#ifndef REG_STATE
+#define REG_STATE( scope, reg, field, symbolic_value ) \
+  REG_STATE_X_( regk_##scope##_##symbolic_value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_STATE_X_( k, shift ) (k << shift)
+#endif
+
+#ifndef REG_MASK
+#define REG_MASK( scope, reg, field ) \
+  REG_MASK_X_( reg_##scope##_##reg##___##field##___width, reg_##scope##_##reg##___##field##___lsb )
+#define REG_MASK_X_( width, lsb ) (((1 << width)-1) << lsb)
+#endif
+
+#ifndef REG_LSB
+#define REG_LSB( scope, reg, field ) reg_##scope##_##reg##___##field##___lsb
+#endif
+
+#ifndef REG_BIT
+#define REG_BIT( scope, reg, field ) reg_##scope##_##reg##___##field##___bit
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) REG_ADDR_X_(inst, reg_##scope##_##reg##_offset)
+#define REG_ADDR_X_( inst, offs ) ((inst) + offs)
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+         REG_ADDR_VECT_X_(inst, reg_##scope##_##reg##_offset, index, \
+			 STRIDE_##scope##_##reg )
+#define REG_ADDR_VECT_X_( inst, offs, index, stride ) \
+                          ((inst) + offs + (index) * stride)
+#endif
+
+/* Register rw_cfg, scope sser, type rw */
+#define reg_sser_rw_cfg___clk_div___lsb 0
+#define reg_sser_rw_cfg___clk_div___width 16
+#define reg_sser_rw_cfg___base_freq___lsb 16
+#define reg_sser_rw_cfg___base_freq___width 3
+#define reg_sser_rw_cfg___gate_clk___lsb 19
+#define reg_sser_rw_cfg___gate_clk___width 1
+#define reg_sser_rw_cfg___gate_clk___bit 19
+#define reg_sser_rw_cfg___clkgate_ctrl___lsb 20
+#define reg_sser_rw_cfg___clkgate_ctrl___width 1
+#define reg_sser_rw_cfg___clkgate_ctrl___bit 20
+#define reg_sser_rw_cfg___clkgate_in___lsb 21
+#define reg_sser_rw_cfg___clkgate_in___width 1
+#define reg_sser_rw_cfg___clkgate_in___bit 21
+#define reg_sser_rw_cfg___clk_dir___lsb 22
+#define reg_sser_rw_cfg___clk_dir___width 1
+#define reg_sser_rw_cfg___clk_dir___bit 22
+#define reg_sser_rw_cfg___clk_od_mode___lsb 23
+#define reg_sser_rw_cfg___clk_od_mode___width 1
+#define reg_sser_rw_cfg___clk_od_mode___bit 23
+#define reg_sser_rw_cfg___out_clk_pol___lsb 24
+#define reg_sser_rw_cfg___out_clk_pol___width 1
+#define reg_sser_rw_cfg___out_clk_pol___bit 24
+#define reg_sser_rw_cfg___out_clk_src___lsb 25
+#define reg_sser_rw_cfg___out_clk_src___width 2
+#define reg_sser_rw_cfg___clk_in_sel___lsb 27
+#define reg_sser_rw_cfg___clk_in_sel___width 1
+#define reg_sser_rw_cfg___clk_in_sel___bit 27
+#define reg_sser_rw_cfg___hold_pol___lsb 28
+#define reg_sser_rw_cfg___hold_pol___width 1
+#define reg_sser_rw_cfg___hold_pol___bit 28
+#define reg_sser_rw_cfg___prepare___lsb 29
+#define reg_sser_rw_cfg___prepare___width 1
+#define reg_sser_rw_cfg___prepare___bit 29
+#define reg_sser_rw_cfg___en___lsb 30
+#define reg_sser_rw_cfg___en___width 1
+#define reg_sser_rw_cfg___en___bit 30
+#define reg_sser_rw_cfg_offset 0
+
+/* Register rw_frm_cfg, scope sser, type rw */
+#define reg_sser_rw_frm_cfg___wordrate___lsb 0
+#define reg_sser_rw_frm_cfg___wordrate___width 10
+#define reg_sser_rw_frm_cfg___rec_delay___lsb 10
+#define reg_sser_rw_frm_cfg___rec_delay___width 3
+#define reg_sser_rw_frm_cfg___tr_delay___lsb 13
+#define reg_sser_rw_frm_cfg___tr_delay___width 3
+#define reg_sser_rw_frm_cfg___early_wend___lsb 16
+#define reg_sser_rw_frm_cfg___early_wend___width 1
+#define reg_sser_rw_frm_cfg___early_wend___bit 16
+#define reg_sser_rw_frm_cfg___level___lsb 17
+#define reg_sser_rw_frm_cfg___level___width 2
+#define reg_sser_rw_frm_cfg___type___lsb 19
+#define reg_sser_rw_frm_cfg___type___width 1
+#define reg_sser_rw_frm_cfg___type___bit 19
+#define reg_sser_rw_frm_cfg___clk_pol___lsb 20
+#define reg_sser_rw_frm_cfg___clk_pol___width 1
+#define reg_sser_rw_frm_cfg___clk_pol___bit 20
+#define reg_sser_rw_frm_cfg___fr_in_rxclk___lsb 21
+#define reg_sser_rw_frm_cfg___fr_in_rxclk___width 1
+#define reg_sser_rw_frm_cfg___fr_in_rxclk___bit 21
+#define reg_sser_rw_frm_cfg___clk_src___lsb 22
+#define reg_sser_rw_frm_cfg___clk_src___width 1
+#define reg_sser_rw_frm_cfg___clk_src___bit 22
+#define reg_sser_rw_frm_cfg___out_off___lsb 23
+#define reg_sser_rw_frm_cfg___out_off___width 1
+#define reg_sser_rw_frm_cfg___out_off___bit 23
+#define reg_sser_rw_frm_cfg___out_on___lsb 24
+#define reg_sser_rw_frm_cfg___out_on___width 1
+#define reg_sser_rw_frm_cfg___out_on___bit 24
+#define reg_sser_rw_frm_cfg___frame_pin_dir___lsb 25
+#define reg_sser_rw_frm_cfg___frame_pin_dir___width 1
+#define reg_sser_rw_frm_cfg___frame_pin_dir___bit 25
+#define reg_sser_rw_frm_cfg___frame_pin_use___lsb 26
+#define reg_sser_rw_frm_cfg___frame_pin_use___width 2
+#define reg_sser_rw_frm_cfg___status_pin_dir___lsb 28
+#define reg_sser_rw_frm_cfg___status_pin_dir___width 1
+#define reg_sser_rw_frm_cfg___status_pin_dir___bit 28
+#define reg_sser_rw_frm_cfg___status_pin_use___lsb 29
+#define reg_sser_rw_frm_cfg___status_pin_use___width 2
+#define reg_sser_rw_frm_cfg_offset 4
+
+/* Register rw_tr_cfg, scope sser, type rw */
+#define reg_sser_rw_tr_cfg___tr_en___lsb 0
+#define reg_sser_rw_tr_cfg___tr_en___width 1
+#define reg_sser_rw_tr_cfg___tr_en___bit 0
+#define reg_sser_rw_tr_cfg___stop___lsb 1
+#define reg_sser_rw_tr_cfg___stop___width 1
+#define reg_sser_rw_tr_cfg___stop___bit 1
+#define reg_sser_rw_tr_cfg___urun_stop___lsb 2
+#define reg_sser_rw_tr_cfg___urun_stop___width 1
+#define reg_sser_rw_tr_cfg___urun_stop___bit 2
+#define reg_sser_rw_tr_cfg___eop_stop___lsb 3
+#define reg_sser_rw_tr_cfg___eop_stop___width 1
+#define reg_sser_rw_tr_cfg___eop_stop___bit 3
+#define reg_sser_rw_tr_cfg___sample_size___lsb 4
+#define reg_sser_rw_tr_cfg___sample_size___width 6
+#define reg_sser_rw_tr_cfg___sh_dir___lsb 10
+#define reg_sser_rw_tr_cfg___sh_dir___width 1
+#define reg_sser_rw_tr_cfg___sh_dir___bit 10
+#define reg_sser_rw_tr_cfg___clk_pol___lsb 11
+#define reg_sser_rw_tr_cfg___clk_pol___width 1
+#define reg_sser_rw_tr_cfg___clk_pol___bit 11
+#define reg_sser_rw_tr_cfg___clk_src___lsb 12
+#define reg_sser_rw_tr_cfg___clk_src___width 1
+#define reg_sser_rw_tr_cfg___clk_src___bit 12
+#define reg_sser_rw_tr_cfg___use_dma___lsb 13
+#define reg_sser_rw_tr_cfg___use_dma___width 1
+#define reg_sser_rw_tr_cfg___use_dma___bit 13
+#define reg_sser_rw_tr_cfg___mode___lsb 14
+#define reg_sser_rw_tr_cfg___mode___width 2
+#define reg_sser_rw_tr_cfg___frm_src___lsb 16
+#define reg_sser_rw_tr_cfg___frm_src___width 1
+#define reg_sser_rw_tr_cfg___frm_src___bit 16
+#define reg_sser_rw_tr_cfg___use60958___lsb 17
+#define reg_sser_rw_tr_cfg___use60958___width 1
+#define reg_sser_rw_tr_cfg___use60958___bit 17
+#define reg_sser_rw_tr_cfg___iec60958_ckdiv___lsb 18
+#define reg_sser_rw_tr_cfg___iec60958_ckdiv___width 2
+#define reg_sser_rw_tr_cfg___rate_ctrl___lsb 20
+#define reg_sser_rw_tr_cfg___rate_ctrl___width 1
+#define reg_sser_rw_tr_cfg___rate_ctrl___bit 20
+#define reg_sser_rw_tr_cfg___use_md___lsb 21
+#define reg_sser_rw_tr_cfg___use_md___width 1
+#define reg_sser_rw_tr_cfg___use_md___bit 21
+#define reg_sser_rw_tr_cfg___dual_i2s___lsb 22
+#define reg_sser_rw_tr_cfg___dual_i2s___width 1
+#define reg_sser_rw_tr_cfg___dual_i2s___bit 22
+#define reg_sser_rw_tr_cfg___data_pin_use___lsb 23
+#define reg_sser_rw_tr_cfg___data_pin_use___width 2
+#define reg_sser_rw_tr_cfg___od_mode___lsb 25
+#define reg_sser_rw_tr_cfg___od_mode___width 1
+#define reg_sser_rw_tr_cfg___od_mode___bit 25
+#define reg_sser_rw_tr_cfg___bulk_wspace___lsb 26
+#define reg_sser_rw_tr_cfg___bulk_wspace___width 2
+#define reg_sser_rw_tr_cfg_offset 8
+
+/* Register rw_rec_cfg, scope sser, type rw */
+#define reg_sser_rw_rec_cfg___rec_en___lsb 0
+#define reg_sser_rw_rec_cfg___rec_en___width 1
+#define reg_sser_rw_rec_cfg___rec_en___bit 0
+#define reg_sser_rw_rec_cfg___force_eop___lsb 1
+#define reg_sser_rw_rec_cfg___force_eop___width 1
+#define reg_sser_rw_rec_cfg___force_eop___bit 1
+#define reg_sser_rw_rec_cfg___stop___lsb 2
+#define reg_sser_rw_rec_cfg___stop___width 1
+#define reg_sser_rw_rec_cfg___stop___bit 2
+#define reg_sser_rw_rec_cfg___orun_stop___lsb 3
+#define reg_sser_rw_rec_cfg___orun_stop___width 1
+#define reg_sser_rw_rec_cfg___orun_stop___bit 3
+#define reg_sser_rw_rec_cfg___eop_stop___lsb 4
+#define reg_sser_rw_rec_cfg___eop_stop___width 1
+#define reg_sser_rw_rec_cfg___eop_stop___bit 4
+#define reg_sser_rw_rec_cfg___sample_size___lsb 5
+#define reg_sser_rw_rec_cfg___sample_size___width 6
+#define reg_sser_rw_rec_cfg___sh_dir___lsb 11
+#define reg_sser_rw_rec_cfg___sh_dir___width 1
+#define reg_sser_rw_rec_cfg___sh_dir___bit 11
+#define reg_sser_rw_rec_cfg___clk_pol___lsb 12
+#define reg_sser_rw_rec_cfg___clk_pol___width 1
+#define reg_sser_rw_rec_cfg___clk_pol___bit 12
+#define reg_sser_rw_rec_cfg___clk_src___lsb 13
+#define reg_sser_rw_rec_cfg___clk_src___width 1
+#define reg_sser_rw_rec_cfg___clk_src___bit 13
+#define reg_sser_rw_rec_cfg___use_dma___lsb 14
+#define reg_sser_rw_rec_cfg___use_dma___width 1
+#define reg_sser_rw_rec_cfg___use_dma___bit 14
+#define reg_sser_rw_rec_cfg___mode___lsb 15
+#define reg_sser_rw_rec_cfg___mode___width 2
+#define reg_sser_rw_rec_cfg___frm_src___lsb 17
+#define reg_sser_rw_rec_cfg___frm_src___width 2
+#define reg_sser_rw_rec_cfg___use60958___lsb 19
+#define reg_sser_rw_rec_cfg___use60958___width 1
+#define reg_sser_rw_rec_cfg___use60958___bit 19
+#define reg_sser_rw_rec_cfg___iec60958_ui_len___lsb 20
+#define reg_sser_rw_rec_cfg___iec60958_ui_len___width 5
+#define reg_sser_rw_rec_cfg___slave2_en___lsb 25
+#define reg_sser_rw_rec_cfg___slave2_en___width 1
+#define reg_sser_rw_rec_cfg___slave2_en___bit 25
+#define reg_sser_rw_rec_cfg___slave3_en___lsb 26
+#define reg_sser_rw_rec_cfg___slave3_en___width 1
+#define reg_sser_rw_rec_cfg___slave3_en___bit 26
+#define reg_sser_rw_rec_cfg___fifo_thr___lsb 27
+#define reg_sser_rw_rec_cfg___fifo_thr___width 2
+#define reg_sser_rw_rec_cfg_offset 12
+
+/* Register rw_tr_data, scope sser, type rw */
+#define reg_sser_rw_tr_data___data___lsb 0
+#define reg_sser_rw_tr_data___data___width 16
+#define reg_sser_rw_tr_data___md___lsb 16
+#define reg_sser_rw_tr_data___md___width 1
+#define reg_sser_rw_tr_data___md___bit 16
+#define reg_sser_rw_tr_data_offset 16
+
+/* Register r_rec_data, scope sser, type r */
+#define reg_sser_r_rec_data___data___lsb 0
+#define reg_sser_r_rec_data___data___width 16
+#define reg_sser_r_rec_data___md___lsb 16
+#define reg_sser_r_rec_data___md___width 1
+#define reg_sser_r_rec_data___md___bit 16
+#define reg_sser_r_rec_data___ext_clk___lsb 17
+#define reg_sser_r_rec_data___ext_clk___width 1
+#define reg_sser_r_rec_data___ext_clk___bit 17
+#define reg_sser_r_rec_data___status_in___lsb 18
+#define reg_sser_r_rec_data___status_in___width 1
+#define reg_sser_r_rec_data___status_in___bit 18
+#define reg_sser_r_rec_data___frame_in___lsb 19
+#define reg_sser_r_rec_data___frame_in___width 1
+#define reg_sser_r_rec_data___frame_in___bit 19
+#define reg_sser_r_rec_data___din___lsb 20
+#define reg_sser_r_rec_data___din___width 1
+#define reg_sser_r_rec_data___din___bit 20
+#define reg_sser_r_rec_data___data_in___lsb 21
+#define reg_sser_r_rec_data___data_in___width 1
+#define reg_sser_r_rec_data___data_in___bit 21
+#define reg_sser_r_rec_data___clk_in___lsb 22
+#define reg_sser_r_rec_data___clk_in___width 1
+#define reg_sser_r_rec_data___clk_in___bit 22
+#define reg_sser_r_rec_data_offset 20
+
+/* Register rw_extra, scope sser, type rw */
+#define reg_sser_rw_extra___clkoff_cycles___lsb 0
+#define reg_sser_rw_extra___clkoff_cycles___width 20
+#define reg_sser_rw_extra___clkoff_en___lsb 20
+#define reg_sser_rw_extra___clkoff_en___width 1
+#define reg_sser_rw_extra___clkoff_en___bit 20
+#define reg_sser_rw_extra___clkon_en___lsb 21
+#define reg_sser_rw_extra___clkon_en___width 1
+#define reg_sser_rw_extra___clkon_en___bit 21
+#define reg_sser_rw_extra___dout_delay___lsb 22
+#define reg_sser_rw_extra___dout_delay___width 5
+#define reg_sser_rw_extra_offset 24
+
+/* Register rw_intr_mask, scope sser, type rw */
+#define reg_sser_rw_intr_mask___trdy___lsb 0
+#define reg_sser_rw_intr_mask___trdy___width 1
+#define reg_sser_rw_intr_mask___trdy___bit 0
+#define reg_sser_rw_intr_mask___rdav___lsb 1
+#define reg_sser_rw_intr_mask___rdav___width 1
+#define reg_sser_rw_intr_mask___rdav___bit 1
+#define reg_sser_rw_intr_mask___tidle___lsb 2
+#define reg_sser_rw_intr_mask___tidle___width 1
+#define reg_sser_rw_intr_mask___tidle___bit 2
+#define reg_sser_rw_intr_mask___rstop___lsb 3
+#define reg_sser_rw_intr_mask___rstop___width 1
+#define reg_sser_rw_intr_mask___rstop___bit 3
+#define reg_sser_rw_intr_mask___urun___lsb 4
+#define reg_sser_rw_intr_mask___urun___width 1
+#define reg_sser_rw_intr_mask___urun___bit 4
+#define reg_sser_rw_intr_mask___orun___lsb 5
+#define reg_sser_rw_intr_mask___orun___width 1
+#define reg_sser_rw_intr_mask___orun___bit 5
+#define reg_sser_rw_intr_mask___md_rec___lsb 6
+#define reg_sser_rw_intr_mask___md_rec___width 1
+#define reg_sser_rw_intr_mask___md_rec___bit 6
+#define reg_sser_rw_intr_mask___md_sent___lsb 7
+#define reg_sser_rw_intr_mask___md_sent___width 1
+#define reg_sser_rw_intr_mask___md_sent___bit 7
+#define reg_sser_rw_intr_mask___r958err___lsb 8
+#define reg_sser_rw_intr_mask___r958err___width 1
+#define reg_sser_rw_intr_mask___r958err___bit 8
+#define reg_sser_rw_intr_mask_offset 28
+
+/* Register rw_ack_intr, scope sser, type rw */
+#define reg_sser_rw_ack_intr___trdy___lsb 0
+#define reg_sser_rw_ack_intr___trdy___width 1
+#define reg_sser_rw_ack_intr___trdy___bit 0
+#define reg_sser_rw_ack_intr___rdav___lsb 1
+#define reg_sser_rw_ack_intr___rdav___width 1
+#define reg_sser_rw_ack_intr___rdav___bit 1
+#define reg_sser_rw_ack_intr___tidle___lsb 2
+#define reg_sser_rw_ack_intr___tidle___width 1
+#define reg_sser_rw_ack_intr___tidle___bit 2
+#define reg_sser_rw_ack_intr___rstop___lsb 3
+#define reg_sser_rw_ack_intr___rstop___width 1
+#define reg_sser_rw_ack_intr___rstop___bit 3
+#define reg_sser_rw_ack_intr___urun___lsb 4
+#define reg_sser_rw_ack_intr___urun___width 1
+#define reg_sser_rw_ack_intr___urun___bit 4
+#define reg_sser_rw_ack_intr___orun___lsb 5
+#define reg_sser_rw_ack_intr___orun___width 1
+#define reg_sser_rw_ack_intr___orun___bit 5
+#define reg_sser_rw_ack_intr___md_rec___lsb 6
+#define reg_sser_rw_ack_intr___md_rec___width 1
+#define reg_sser_rw_ack_intr___md_rec___bit 6
+#define reg_sser_rw_ack_intr___md_sent___lsb 7
+#define reg_sser_rw_ack_intr___md_sent___width 1
+#define reg_sser_rw_ack_intr___md_sent___bit 7
+#define reg_sser_rw_ack_intr___r958err___lsb 8
+#define reg_sser_rw_ack_intr___r958err___width 1
+#define reg_sser_rw_ack_intr___r958err___bit 8
+#define reg_sser_rw_ack_intr_offset 32
+
+/* Register r_intr, scope sser, type r */
+#define reg_sser_r_intr___trdy___lsb 0
+#define reg_sser_r_intr___trdy___width 1
+#define reg_sser_r_intr___trdy___bit 0
+#define reg_sser_r_intr___rdav___lsb 1
+#define reg_sser_r_intr___rdav___width 1
+#define reg_sser_r_intr___rdav___bit 1
+#define reg_sser_r_intr___tidle___lsb 2
+#define reg_sser_r_intr___tidle___width 1
+#define reg_sser_r_intr___tidle___bit 2
+#define reg_sser_r_intr___rstop___lsb 3
+#define reg_sser_r_intr___rstop___width 1
+#define reg_sser_r_intr___rstop___bit 3
+#define reg_sser_r_intr___urun___lsb 4
+#define reg_sser_r_intr___urun___width 1
+#define reg_sser_r_intr___urun___bit 4
+#define reg_sser_r_intr___orun___lsb 5
+#define reg_sser_r_intr___orun___width 1
+#define reg_sser_r_intr___orun___bit 5
+#define reg_sser_r_intr___md_rec___lsb 6
+#define reg_sser_r_intr___md_rec___width 1
+#define reg_sser_r_intr___md_rec___bit 6
+#define reg_sser_r_intr___md_sent___lsb 7
+#define reg_sser_r_intr___md_sent___width 1
+#define reg_sser_r_intr___md_sent___bit 7
+#define reg_sser_r_intr___r958err___lsb 8
+#define reg_sser_r_intr___r958err___width 1
+#define reg_sser_r_intr___r958err___bit 8
+#define reg_sser_r_intr_offset 36
+
+/* Register r_masked_intr, scope sser, type r */
+#define reg_sser_r_masked_intr___trdy___lsb 0
+#define reg_sser_r_masked_intr___trdy___width 1
+#define reg_sser_r_masked_intr___trdy___bit 0
+#define reg_sser_r_masked_intr___rdav___lsb 1
+#define reg_sser_r_masked_intr___rdav___width 1
+#define reg_sser_r_masked_intr___rdav___bit 1
+#define reg_sser_r_masked_intr___tidle___lsb 2
+#define reg_sser_r_masked_intr___tidle___width 1
+#define reg_sser_r_masked_intr___tidle___bit 2
+#define reg_sser_r_masked_intr___rstop___lsb 3
+#define reg_sser_r_masked_intr___rstop___width 1
+#define reg_sser_r_masked_intr___rstop___bit 3
+#define reg_sser_r_masked_intr___urun___lsb 4
+#define reg_sser_r_masked_intr___urun___width 1
+#define reg_sser_r_masked_intr___urun___bit 4
+#define reg_sser_r_masked_intr___orun___lsb 5
+#define reg_sser_r_masked_intr___orun___width 1
+#define reg_sser_r_masked_intr___orun___bit 5
+#define reg_sser_r_masked_intr___md_rec___lsb 6
+#define reg_sser_r_masked_intr___md_rec___width 1
+#define reg_sser_r_masked_intr___md_rec___bit 6
+#define reg_sser_r_masked_intr___md_sent___lsb 7
+#define reg_sser_r_masked_intr___md_sent___width 1
+#define reg_sser_r_masked_intr___md_sent___bit 7
+#define reg_sser_r_masked_intr___r958err___lsb 8
+#define reg_sser_r_masked_intr___r958err___width 1
+#define reg_sser_r_masked_intr___r958err___bit 8
+#define reg_sser_r_masked_intr_offset 40
+
+
+/* Constants */
+#define regk_sser_both                            0x00000002
+#define regk_sser_bulk                            0x00000001
+#define regk_sser_clk100                          0x00000000
+#define regk_sser_clk_in                          0x00000000
+#define regk_sser_const0                          0x00000003
+#define regk_sser_dout                            0x00000002
+#define regk_sser_edge                            0x00000000
+#define regk_sser_ext                             0x00000001
+#define regk_sser_ext_clk                         0x00000001
+#define regk_sser_f100                            0x00000000
+#define regk_sser_f29_493                         0x00000004
+#define regk_sser_f32                             0x00000005
+#define regk_sser_f32_768                         0x00000006
+#define regk_sser_frm                             0x00000003
+#define regk_sser_gio0                            0x00000000
+#define regk_sser_gio1                            0x00000001
+#define regk_sser_hispeed                         0x00000001
+#define regk_sser_hold                            0x00000002
+#define regk_sser_in                              0x00000000
+#define regk_sser_inf                             0x00000003
+#define regk_sser_intern                          0x00000000
+#define regk_sser_intern_clk                      0x00000001
+#define regk_sser_intern_tb                       0x00000000
+#define regk_sser_iso                             0x00000000
+#define regk_sser_level                           0x00000001
+#define regk_sser_lospeed                         0x00000000
+#define regk_sser_lsbfirst                        0x00000000
+#define regk_sser_msbfirst                        0x00000001
+#define regk_sser_neg                             0x00000001
+#define regk_sser_neg_lo                          0x00000000
+#define regk_sser_no                              0x00000000
+#define regk_sser_no_clk                          0x00000007
+#define regk_sser_nojitter                        0x00000002
+#define regk_sser_out                             0x00000001
+#define regk_sser_pos                             0x00000000
+#define regk_sser_pos_hi                          0x00000001
+#define regk_sser_rec                             0x00000000
+#define regk_sser_rw_cfg_default                  0x00000000
+#define regk_sser_rw_extra_default                0x00000000
+#define regk_sser_rw_frm_cfg_default              0x00000000
+#define regk_sser_rw_intr_mask_default            0x00000000
+#define regk_sser_rw_rec_cfg_default              0x00000000
+#define regk_sser_rw_tr_cfg_default               0x01800000
+#define regk_sser_rw_tr_data_default              0x00000000
+#define regk_sser_thr16                           0x00000001
+#define regk_sser_thr32                           0x00000002
+#define regk_sser_thr8                            0x00000000
+#define regk_sser_tr                              0x00000001
+#define regk_sser_ts_out                          0x00000003
+#define regk_sser_tx_bulk                         0x00000002
+#define regk_sser_wiresave                        0x00000002
+#define regk_sser_yes                             0x00000001
+#endif /* __sser_defs_asm_h */
diff --git a/include/asm-cris/arch-v32/hwregs/asm/strcop_defs_asm.h b/include/asm-cris/arch-v32/hwregs/asm/strcop_defs_asm.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/asm/strcop_defs_asm.h
@@ -0,0 +1,84 @@
+#ifndef __strcop_defs_asm_h
+#define __strcop_defs_asm_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/strcop/rtl/strcop_regs.r
+ *     id:           strcop_regs.r,v 1.5 2003/10/15 12:09:45 kriskn Exp
+ *     last modfied: Mon Apr 11 16:09:38 2005
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c -asm --outfile asm/strcop_defs_asm.h ../../inst/strcop/rtl/strcop_regs.r
+ *      id: $Id: strcop_defs_asm.h,v 1.1 2005/04/24 18:31:04 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+
+#ifndef REG_FIELD
+#define REG_FIELD( scope, reg, field, value ) \
+  REG_FIELD_X_( value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_FIELD_X_( value, shift ) ((value) << shift)
+#endif
+
+#ifndef REG_STATE
+#define REG_STATE( scope, reg, field, symbolic_value ) \
+  REG_STATE_X_( regk_##scope##_##symbolic_value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_STATE_X_( k, shift ) (k << shift)
+#endif
+
+#ifndef REG_MASK
+#define REG_MASK( scope, reg, field ) \
+  REG_MASK_X_( reg_##scope##_##reg##___##field##___width, reg_##scope##_##reg##___##field##___lsb )
+#define REG_MASK_X_( width, lsb ) (((1 << width)-1) << lsb)
+#endif
+
+#ifndef REG_LSB
+#define REG_LSB( scope, reg, field ) reg_##scope##_##reg##___##field##___lsb
+#endif
+
+#ifndef REG_BIT
+#define REG_BIT( scope, reg, field ) reg_##scope##_##reg##___##field##___bit
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) REG_ADDR_X_(inst, reg_##scope##_##reg##_offset)
+#define REG_ADDR_X_( inst, offs ) ((inst) + offs)
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+         REG_ADDR_VECT_X_(inst, reg_##scope##_##reg##_offset, index, \
+			 STRIDE_##scope##_##reg )
+#define REG_ADDR_VECT_X_( inst, offs, index, stride ) \
+                          ((inst) + offs + (index) * stride)
+#endif
+
+/* Register rw_cfg, scope strcop, type rw */
+#define reg_strcop_rw_cfg___td3___lsb 0
+#define reg_strcop_rw_cfg___td3___width 1
+#define reg_strcop_rw_cfg___td3___bit 0
+#define reg_strcop_rw_cfg___td2___lsb 1
+#define reg_strcop_rw_cfg___td2___width 1
+#define reg_strcop_rw_cfg___td2___bit 1
+#define reg_strcop_rw_cfg___td1___lsb 2
+#define reg_strcop_rw_cfg___td1___width 1
+#define reg_strcop_rw_cfg___td1___bit 2
+#define reg_strcop_rw_cfg___ipend___lsb 3
+#define reg_strcop_rw_cfg___ipend___width 1
+#define reg_strcop_rw_cfg___ipend___bit 3
+#define reg_strcop_rw_cfg___ignore_sync___lsb 4
+#define reg_strcop_rw_cfg___ignore_sync___width 1
+#define reg_strcop_rw_cfg___ignore_sync___bit 4
+#define reg_strcop_rw_cfg___en___lsb 5
+#define reg_strcop_rw_cfg___en___width 1
+#define reg_strcop_rw_cfg___en___bit 5
+#define reg_strcop_rw_cfg_offset 0
+
+
+/* Constants */
+#define regk_strcop_big                           0x00000001
+#define regk_strcop_d                             0x00000001
+#define regk_strcop_e                             0x00000000
+#define regk_strcop_little                        0x00000000
+#define regk_strcop_rw_cfg_default                0x00000002
+#endif /* __strcop_defs_asm_h */
diff --git a/include/asm-cris/arch-v32/hwregs/asm/strmux_defs_asm.h b/include/asm-cris/arch-v32/hwregs/asm/strmux_defs_asm.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/asm/strmux_defs_asm.h
@@ -0,0 +1,100 @@
+#ifndef __strmux_defs_asm_h
+#define __strmux_defs_asm_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/strmux/rtl/guinness/strmux_regs.r
+ *     id:           strmux_regs.r,v 1.10 2005/02/10 10:10:46 perz Exp
+ *     last modfied: Mon Apr 11 16:09:43 2005
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c -asm --outfile asm/strmux_defs_asm.h ../../inst/strmux/rtl/guinness/strmux_regs.r
+ *      id: $Id: strmux_defs_asm.h,v 1.1 2005/04/24 18:31:04 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+
+#ifndef REG_FIELD
+#define REG_FIELD( scope, reg, field, value ) \
+  REG_FIELD_X_( value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_FIELD_X_( value, shift ) ((value) << shift)
+#endif
+
+#ifndef REG_STATE
+#define REG_STATE( scope, reg, field, symbolic_value ) \
+  REG_STATE_X_( regk_##scope##_##symbolic_value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_STATE_X_( k, shift ) (k << shift)
+#endif
+
+#ifndef REG_MASK
+#define REG_MASK( scope, reg, field ) \
+  REG_MASK_X_( reg_##scope##_##reg##___##field##___width, reg_##scope##_##reg##___##field##___lsb )
+#define REG_MASK_X_( width, lsb ) (((1 << width)-1) << lsb)
+#endif
+
+#ifndef REG_LSB
+#define REG_LSB( scope, reg, field ) reg_##scope##_##reg##___##field##___lsb
+#endif
+
+#ifndef REG_BIT
+#define REG_BIT( scope, reg, field ) reg_##scope##_##reg##___##field##___bit
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) REG_ADDR_X_(inst, reg_##scope##_##reg##_offset)
+#define REG_ADDR_X_( inst, offs ) ((inst) + offs)
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+         REG_ADDR_VECT_X_(inst, reg_##scope##_##reg##_offset, index, \
+			 STRIDE_##scope##_##reg )
+#define REG_ADDR_VECT_X_( inst, offs, index, stride ) \
+                          ((inst) + offs + (index) * stride)
+#endif
+
+/* Register rw_cfg, scope strmux, type rw */
+#define reg_strmux_rw_cfg___dma0___lsb 0
+#define reg_strmux_rw_cfg___dma0___width 3
+#define reg_strmux_rw_cfg___dma1___lsb 3
+#define reg_strmux_rw_cfg___dma1___width 3
+#define reg_strmux_rw_cfg___dma2___lsb 6
+#define reg_strmux_rw_cfg___dma2___width 3
+#define reg_strmux_rw_cfg___dma3___lsb 9
+#define reg_strmux_rw_cfg___dma3___width 3
+#define reg_strmux_rw_cfg___dma4___lsb 12
+#define reg_strmux_rw_cfg___dma4___width 3
+#define reg_strmux_rw_cfg___dma5___lsb 15
+#define reg_strmux_rw_cfg___dma5___width 3
+#define reg_strmux_rw_cfg___dma6___lsb 18
+#define reg_strmux_rw_cfg___dma6___width 3
+#define reg_strmux_rw_cfg___dma7___lsb 21
+#define reg_strmux_rw_cfg___dma7___width 3
+#define reg_strmux_rw_cfg___dma8___lsb 24
+#define reg_strmux_rw_cfg___dma8___width 3
+#define reg_strmux_rw_cfg___dma9___lsb 27
+#define reg_strmux_rw_cfg___dma9___width 3
+#define reg_strmux_rw_cfg_offset 0
+
+
+/* Constants */
+#define regk_strmux_ata                           0x00000003
+#define regk_strmux_eth0                          0x00000001
+#define regk_strmux_eth1                          0x00000004
+#define regk_strmux_ext0                          0x00000001
+#define regk_strmux_ext1                          0x00000001
+#define regk_strmux_ext2                          0x00000001
+#define regk_strmux_ext3                          0x00000001
+#define regk_strmux_iop0                          0x00000002
+#define regk_strmux_iop1                          0x00000001
+#define regk_strmux_off                           0x00000000
+#define regk_strmux_p21                           0x00000004
+#define regk_strmux_rw_cfg_default                0x00000000
+#define regk_strmux_ser0                          0x00000002
+#define regk_strmux_ser1                          0x00000002
+#define regk_strmux_ser2                          0x00000004
+#define regk_strmux_ser3                          0x00000003
+#define regk_strmux_sser0                         0x00000003
+#define regk_strmux_sser1                         0x00000003
+#define regk_strmux_strcop                        0x00000002
+#endif /* __strmux_defs_asm_h */
diff --git a/include/asm-cris/arch-v32/hwregs/asm/timer_defs_asm.h b/include/asm-cris/arch-v32/hwregs/asm/timer_defs_asm.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/asm/timer_defs_asm.h
@@ -0,0 +1,229 @@
+#ifndef __timer_defs_asm_h
+#define __timer_defs_asm_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/timer/rtl/timer_regs.r
+ *     id:           timer_regs.r,v 1.7 2003/03/11 11:16:59 perz Exp
+ *     last modfied: Mon Apr 11 16:09:53 2005
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c -asm --outfile asm/timer_defs_asm.h ../../inst/timer/rtl/timer_regs.r
+ *      id: $Id: timer_defs_asm.h,v 1.1 2005/04/24 18:31:04 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+
+#ifndef REG_FIELD
+#define REG_FIELD( scope, reg, field, value ) \
+  REG_FIELD_X_( value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_FIELD_X_( value, shift ) ((value) << shift)
+#endif
+
+#ifndef REG_STATE
+#define REG_STATE( scope, reg, field, symbolic_value ) \
+  REG_STATE_X_( regk_##scope##_##symbolic_value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_STATE_X_( k, shift ) (k << shift)
+#endif
+
+#ifndef REG_MASK
+#define REG_MASK( scope, reg, field ) \
+  REG_MASK_X_( reg_##scope##_##reg##___##field##___width, reg_##scope##_##reg##___##field##___lsb )
+#define REG_MASK_X_( width, lsb ) (((1 << width)-1) << lsb)
+#endif
+
+#ifndef REG_LSB
+#define REG_LSB( scope, reg, field ) reg_##scope##_##reg##___##field##___lsb
+#endif
+
+#ifndef REG_BIT
+#define REG_BIT( scope, reg, field ) reg_##scope##_##reg##___##field##___bit
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) REG_ADDR_X_(inst, reg_##scope##_##reg##_offset)
+#define REG_ADDR_X_( inst, offs ) ((inst) + offs)
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+         REG_ADDR_VECT_X_(inst, reg_##scope##_##reg##_offset, index, \
+			 STRIDE_##scope##_##reg )
+#define REG_ADDR_VECT_X_( inst, offs, index, stride ) \
+                          ((inst) + offs + (index) * stride)
+#endif
+
+/* Register rw_tmr0_div, scope timer, type rw */
+#define reg_timer_rw_tmr0_div_offset 0
+
+/* Register r_tmr0_data, scope timer, type r */
+#define reg_timer_r_tmr0_data_offset 4
+
+/* Register rw_tmr0_ctrl, scope timer, type rw */
+#define reg_timer_rw_tmr0_ctrl___op___lsb 0
+#define reg_timer_rw_tmr0_ctrl___op___width 2
+#define reg_timer_rw_tmr0_ctrl___freq___lsb 2
+#define reg_timer_rw_tmr0_ctrl___freq___width 3
+#define reg_timer_rw_tmr0_ctrl_offset 8
+
+/* Register rw_tmr1_div, scope timer, type rw */
+#define reg_timer_rw_tmr1_div_offset 16
+
+/* Register r_tmr1_data, scope timer, type r */
+#define reg_timer_r_tmr1_data_offset 20
+
+/* Register rw_tmr1_ctrl, scope timer, type rw */
+#define reg_timer_rw_tmr1_ctrl___op___lsb 0
+#define reg_timer_rw_tmr1_ctrl___op___width 2
+#define reg_timer_rw_tmr1_ctrl___freq___lsb 2
+#define reg_timer_rw_tmr1_ctrl___freq___width 3
+#define reg_timer_rw_tmr1_ctrl_offset 24
+
+/* Register rs_cnt_data, scope timer, type rs */
+#define reg_timer_rs_cnt_data___tmr___lsb 0
+#define reg_timer_rs_cnt_data___tmr___width 24
+#define reg_timer_rs_cnt_data___cnt___lsb 24
+#define reg_timer_rs_cnt_data___cnt___width 8
+#define reg_timer_rs_cnt_data_offset 32
+
+/* Register r_cnt_data, scope timer, type r */
+#define reg_timer_r_cnt_data___tmr___lsb 0
+#define reg_timer_r_cnt_data___tmr___width 24
+#define reg_timer_r_cnt_data___cnt___lsb 24
+#define reg_timer_r_cnt_data___cnt___width 8
+#define reg_timer_r_cnt_data_offset 36
+
+/* Register rw_cnt_cfg, scope timer, type rw */
+#define reg_timer_rw_cnt_cfg___clk___lsb 0
+#define reg_timer_rw_cnt_cfg___clk___width 2
+#define reg_timer_rw_cnt_cfg_offset 40
+
+/* Register rw_trig, scope timer, type rw */
+#define reg_timer_rw_trig_offset 48
+
+/* Register rw_trig_cfg, scope timer, type rw */
+#define reg_timer_rw_trig_cfg___tmr___lsb 0
+#define reg_timer_rw_trig_cfg___tmr___width 2
+#define reg_timer_rw_trig_cfg_offset 52
+
+/* Register r_time, scope timer, type r */
+#define reg_timer_r_time_offset 56
+
+/* Register rw_out, scope timer, type rw */
+#define reg_timer_rw_out___tmr___lsb 0
+#define reg_timer_rw_out___tmr___width 2
+#define reg_timer_rw_out_offset 60
+
+/* Register rw_wd_ctrl, scope timer, type rw */
+#define reg_timer_rw_wd_ctrl___cnt___lsb 0
+#define reg_timer_rw_wd_ctrl___cnt___width 8
+#define reg_timer_rw_wd_ctrl___cmd___lsb 8
+#define reg_timer_rw_wd_ctrl___cmd___width 1
+#define reg_timer_rw_wd_ctrl___cmd___bit 8
+#define reg_timer_rw_wd_ctrl___key___lsb 9
+#define reg_timer_rw_wd_ctrl___key___width 7
+#define reg_timer_rw_wd_ctrl_offset 64
+
+/* Register r_wd_stat, scope timer, type r */
+#define reg_timer_r_wd_stat___cnt___lsb 0
+#define reg_timer_r_wd_stat___cnt___width 8
+#define reg_timer_r_wd_stat___cmd___lsb 8
+#define reg_timer_r_wd_stat___cmd___width 1
+#define reg_timer_r_wd_stat___cmd___bit 8
+#define reg_timer_r_wd_stat_offset 68
+
+/* Register rw_intr_mask, scope timer, type rw */
+#define reg_timer_rw_intr_mask___tmr0___lsb 0
+#define reg_timer_rw_intr_mask___tmr0___width 1
+#define reg_timer_rw_intr_mask___tmr0___bit 0
+#define reg_timer_rw_intr_mask___tmr1___lsb 1
+#define reg_timer_rw_intr_mask___tmr1___width 1
+#define reg_timer_rw_intr_mask___tmr1___bit 1
+#define reg_timer_rw_intr_mask___cnt___lsb 2
+#define reg_timer_rw_intr_mask___cnt___width 1
+#define reg_timer_rw_intr_mask___cnt___bit 2
+#define reg_timer_rw_intr_mask___trig___lsb 3
+#define reg_timer_rw_intr_mask___trig___width 1
+#define reg_timer_rw_intr_mask___trig___bit 3
+#define reg_timer_rw_intr_mask_offset 72
+
+/* Register rw_ack_intr, scope timer, type rw */
+#define reg_timer_rw_ack_intr___tmr0___lsb 0
+#define reg_timer_rw_ack_intr___tmr0___width 1
+#define reg_timer_rw_ack_intr___tmr0___bit 0
+#define reg_timer_rw_ack_intr___tmr1___lsb 1
+#define reg_timer_rw_ack_intr___tmr1___width 1
+#define reg_timer_rw_ack_intr___tmr1___bit 1
+#define reg_timer_rw_ack_intr___cnt___lsb 2
+#define reg_timer_rw_ack_intr___cnt___width 1
+#define reg_timer_rw_ack_intr___cnt___bit 2
+#define reg_timer_rw_ack_intr___trig___lsb 3
+#define reg_timer_rw_ack_intr___trig___width 1
+#define reg_timer_rw_ack_intr___trig___bit 3
+#define reg_timer_rw_ack_intr_offset 76
+
+/* Register r_intr, scope timer, type r */
+#define reg_timer_r_intr___tmr0___lsb 0
+#define reg_timer_r_intr___tmr0___width 1
+#define reg_timer_r_intr___tmr0___bit 0
+#define reg_timer_r_intr___tmr1___lsb 1
+#define reg_timer_r_intr___tmr1___width 1
+#define reg_timer_r_intr___tmr1___bit 1
+#define reg_timer_r_intr___cnt___lsb 2
+#define reg_timer_r_intr___cnt___width 1
+#define reg_timer_r_intr___cnt___bit 2
+#define reg_timer_r_intr___trig___lsb 3
+#define reg_timer_r_intr___trig___width 1
+#define reg_timer_r_intr___trig___bit 3
+#define reg_timer_r_intr_offset 80
+
+/* Register r_masked_intr, scope timer, type r */
+#define reg_timer_r_masked_intr___tmr0___lsb 0
+#define reg_timer_r_masked_intr___tmr0___width 1
+#define reg_timer_r_masked_intr___tmr0___bit 0
+#define reg_timer_r_masked_intr___tmr1___lsb 1
+#define reg_timer_r_masked_intr___tmr1___width 1
+#define reg_timer_r_masked_intr___tmr1___bit 1
+#define reg_timer_r_masked_intr___cnt___lsb 2
+#define reg_timer_r_masked_intr___cnt___width 1
+#define reg_timer_r_masked_intr___cnt___bit 2
+#define reg_timer_r_masked_intr___trig___lsb 3
+#define reg_timer_r_masked_intr___trig___width 1
+#define reg_timer_r_masked_intr___trig___bit 3
+#define reg_timer_r_masked_intr_offset 84
+
+/* Register rw_test, scope timer, type rw */
+#define reg_timer_rw_test___dis___lsb 0
+#define reg_timer_rw_test___dis___width 1
+#define reg_timer_rw_test___dis___bit 0
+#define reg_timer_rw_test___en___lsb 1
+#define reg_timer_rw_test___en___width 1
+#define reg_timer_rw_test___en___bit 1
+#define reg_timer_rw_test_offset 88
+
+
+/* Constants */
+#define regk_timer_ext                            0x00000001
+#define regk_timer_f100                           0x00000007
+#define regk_timer_f29_493                        0x00000004
+#define regk_timer_f32                            0x00000005
+#define regk_timer_f32_768                        0x00000006
+#define regk_timer_hold                           0x00000001
+#define regk_timer_ld                             0x00000000
+#define regk_timer_no                             0x00000000
+#define regk_timer_off                            0x00000000
+#define regk_timer_run                            0x00000002
+#define regk_timer_rw_cnt_cfg_default             0x00000000
+#define regk_timer_rw_intr_mask_default           0x00000000
+#define regk_timer_rw_out_default                 0x00000000
+#define regk_timer_rw_test_default                0x00000000
+#define regk_timer_rw_tmr0_ctrl_default           0x00000000
+#define regk_timer_rw_tmr1_ctrl_default           0x00000000
+#define regk_timer_rw_trig_cfg_default            0x00000000
+#define regk_timer_start                          0x00000001
+#define regk_timer_stop                           0x00000000
+#define regk_timer_time                           0x00000001
+#define regk_timer_tmr0                           0x00000002
+#define regk_timer_tmr1                           0x00000003
+#define regk_timer_yes                            0x00000001
+#endif /* __timer_defs_asm_h */
diff --git a/include/asm-cris/arch-v32/hwregs/ata_defs.h b/include/asm-cris/arch-v32/hwregs/ata_defs.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/ata_defs.h
@@ -0,0 +1,222 @@
+#ifndef __ata_defs_h
+#define __ata_defs_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/ata/rtl/ata_regs.r
+ *     id:           ata_regs.r,v 1.11 2005/02/09 08:27:36 kriskn Exp
+ *     last modfied: Mon Apr 11 16:06:25 2005
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c --outfile ata_defs.h ../../inst/ata/rtl/ata_regs.r
+ *      id: $Id: ata_defs.h,v 1.7 2005/04/24 18:30:58 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+/* Main access macros */
+#ifndef REG_RD
+#define REG_RD( scope, inst, reg ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR
+#define REG_WR( scope, inst, reg, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_VECT
+#define REG_RD_VECT( scope, inst, reg, index ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_VECT
+#define REG_WR_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT
+#define REG_RD_INT( scope, inst, reg ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT
+#define REG_WR_INT( scope, inst, reg, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT_VECT
+#define REG_RD_INT_VECT( scope, inst, reg, index ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT_VECT
+#define REG_WR_INT_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_TYPE_CONV
+#define REG_TYPE_CONV( type, orgtype, val ) \
+  ( { union { orgtype o; type n; } r; r.o = val; r.n; } )
+#endif
+
+#ifndef reg_page_size
+#define reg_page_size 8192
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg + \
+    (index) * STRIDE_##scope##_##reg )
+#endif
+
+/* C-code for register scope ata */
+
+/* Register rw_ctrl0, scope ata, type rw */
+typedef struct {
+  unsigned int pio_hold  : 6;
+  unsigned int pio_strb  : 6;
+  unsigned int pio_setup : 6;
+  unsigned int dma_hold  : 6;
+  unsigned int dma_strb  : 6;
+  unsigned int rst       : 1;
+  unsigned int en        : 1;
+} reg_ata_rw_ctrl0;
+#define REG_RD_ADDR_ata_rw_ctrl0 12
+#define REG_WR_ADDR_ata_rw_ctrl0 12
+
+/* Register rw_ctrl1, scope ata, type rw */
+typedef struct {
+  unsigned int udma_tcyc : 4;
+  unsigned int udma_tdvs : 4;
+  unsigned int dummy1    : 24;
+} reg_ata_rw_ctrl1;
+#define REG_RD_ADDR_ata_rw_ctrl1 16
+#define REG_WR_ADDR_ata_rw_ctrl1 16
+
+/* Register rw_ctrl2, scope ata, type rw */
+typedef struct {
+  unsigned int data     : 16;
+  unsigned int dummy1   : 3;
+  unsigned int dma_size : 1;
+  unsigned int multi    : 1;
+  unsigned int hsh      : 2;
+  unsigned int trf_mode : 1;
+  unsigned int rw       : 1;
+  unsigned int addr     : 3;
+  unsigned int cs0      : 1;
+  unsigned int cs1      : 1;
+  unsigned int sel      : 2;
+} reg_ata_rw_ctrl2;
+#define REG_RD_ADDR_ata_rw_ctrl2 0
+#define REG_WR_ADDR_ata_rw_ctrl2 0
+
+/* Register rs_stat_data, scope ata, type rs */
+typedef struct {
+  unsigned int data : 16;
+  unsigned int dav  : 1;
+  unsigned int busy : 1;
+  unsigned int dummy1 : 14;
+} reg_ata_rs_stat_data;
+#define REG_RD_ADDR_ata_rs_stat_data 4
+
+/* Register r_stat_data, scope ata, type r */
+typedef struct {
+  unsigned int data : 16;
+  unsigned int dav  : 1;
+  unsigned int busy : 1;
+  unsigned int dummy1 : 14;
+} reg_ata_r_stat_data;
+#define REG_RD_ADDR_ata_r_stat_data 8
+
+/* Register rw_trf_cnt, scope ata, type rw */
+typedef struct {
+  unsigned int cnt : 17;
+  unsigned int dummy1 : 15;
+} reg_ata_rw_trf_cnt;
+#define REG_RD_ADDR_ata_rw_trf_cnt 20
+#define REG_WR_ADDR_ata_rw_trf_cnt 20
+
+/* Register r_stat_misc, scope ata, type r */
+typedef struct {
+  unsigned int crc : 16;
+  unsigned int dummy1 : 16;
+} reg_ata_r_stat_misc;
+#define REG_RD_ADDR_ata_r_stat_misc 24
+
+/* Register rw_intr_mask, scope ata, type rw */
+typedef struct {
+  unsigned int bus0 : 1;
+  unsigned int bus1 : 1;
+  unsigned int bus2 : 1;
+  unsigned int bus3 : 1;
+  unsigned int dummy1 : 28;
+} reg_ata_rw_intr_mask;
+#define REG_RD_ADDR_ata_rw_intr_mask 28
+#define REG_WR_ADDR_ata_rw_intr_mask 28
+
+/* Register rw_ack_intr, scope ata, type rw */
+typedef struct {
+  unsigned int bus0 : 1;
+  unsigned int bus1 : 1;
+  unsigned int bus2 : 1;
+  unsigned int bus3 : 1;
+  unsigned int dummy1 : 28;
+} reg_ata_rw_ack_intr;
+#define REG_RD_ADDR_ata_rw_ack_intr 32
+#define REG_WR_ADDR_ata_rw_ack_intr 32
+
+/* Register r_intr, scope ata, type r */
+typedef struct {
+  unsigned int bus0 : 1;
+  unsigned int bus1 : 1;
+  unsigned int bus2 : 1;
+  unsigned int bus3 : 1;
+  unsigned int dummy1 : 28;
+} reg_ata_r_intr;
+#define REG_RD_ADDR_ata_r_intr 36
+
+/* Register r_masked_intr, scope ata, type r */
+typedef struct {
+  unsigned int bus0 : 1;
+  unsigned int bus1 : 1;
+  unsigned int bus2 : 1;
+  unsigned int bus3 : 1;
+  unsigned int dummy1 : 28;
+} reg_ata_r_masked_intr;
+#define REG_RD_ADDR_ata_r_masked_intr 40
+
+
+/* Constants */
+enum {
+  regk_ata_active                          = 0x00000001,
+  regk_ata_byte                            = 0x00000001,
+  regk_ata_data                            = 0x00000001,
+  regk_ata_dma                             = 0x00000001,
+  regk_ata_inactive                        = 0x00000000,
+  regk_ata_no                              = 0x00000000,
+  regk_ata_nodata                          = 0x00000000,
+  regk_ata_pio                             = 0x00000000,
+  regk_ata_rd                              = 0x00000001,
+  regk_ata_reg                             = 0x00000000,
+  regk_ata_rw_ctrl0_default                = 0x00000000,
+  regk_ata_rw_ctrl2_default                = 0x00000000,
+  regk_ata_rw_intr_mask_default            = 0x00000000,
+  regk_ata_udma                            = 0x00000002,
+  regk_ata_word                            = 0x00000000,
+  regk_ata_wr                              = 0x00000000,
+  regk_ata_yes                             = 0x00000001
+};
+#endif /* __ata_defs_h */
diff --git a/include/asm-cris/arch-v32/hwregs/bif_core_defs.h b/include/asm-cris/arch-v32/hwregs/bif_core_defs.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/bif_core_defs.h
@@ -0,0 +1,284 @@
+#ifndef __bif_core_defs_h
+#define __bif_core_defs_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/bif/rtl/bif_core_regs.r
+ *     id:           bif_core_regs.r,v 1.17 2005/02/04 13:28:22 np Exp
+ *     last modfied: Mon Apr 11 16:06:33 2005
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c --outfile bif_core_defs.h ../../inst/bif/rtl/bif_core_regs.r
+ *      id: $Id: bif_core_defs.h,v 1.3 2005/04/24 18:30:58 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+/* Main access macros */
+#ifndef REG_RD
+#define REG_RD( scope, inst, reg ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR
+#define REG_WR( scope, inst, reg, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_VECT
+#define REG_RD_VECT( scope, inst, reg, index ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_VECT
+#define REG_WR_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT
+#define REG_RD_INT( scope, inst, reg ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT
+#define REG_WR_INT( scope, inst, reg, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT_VECT
+#define REG_RD_INT_VECT( scope, inst, reg, index ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT_VECT
+#define REG_WR_INT_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_TYPE_CONV
+#define REG_TYPE_CONV( type, orgtype, val ) \
+  ( { union { orgtype o; type n; } r; r.o = val; r.n; } )
+#endif
+
+#ifndef reg_page_size
+#define reg_page_size 8192
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg + \
+    (index) * STRIDE_##scope##_##reg )
+#endif
+
+/* C-code for register scope bif_core */
+
+/* Register rw_grp1_cfg, scope bif_core, type rw */
+typedef struct {
+  unsigned int lw        : 6;
+  unsigned int ew        : 3;
+  unsigned int zw        : 3;
+  unsigned int aw        : 2;
+  unsigned int dw        : 2;
+  unsigned int ewb       : 2;
+  unsigned int bw        : 1;
+  unsigned int wr_extend : 1;
+  unsigned int erc_en    : 1;
+  unsigned int mode      : 1;
+  unsigned int dummy1    : 10;
+} reg_bif_core_rw_grp1_cfg;
+#define REG_RD_ADDR_bif_core_rw_grp1_cfg 0
+#define REG_WR_ADDR_bif_core_rw_grp1_cfg 0
+
+/* Register rw_grp2_cfg, scope bif_core, type rw */
+typedef struct {
+  unsigned int lw        : 6;
+  unsigned int ew        : 3;
+  unsigned int zw        : 3;
+  unsigned int aw        : 2;
+  unsigned int dw        : 2;
+  unsigned int ewb       : 2;
+  unsigned int bw        : 1;
+  unsigned int wr_extend : 1;
+  unsigned int erc_en    : 1;
+  unsigned int mode      : 1;
+  unsigned int dummy1    : 10;
+} reg_bif_core_rw_grp2_cfg;
+#define REG_RD_ADDR_bif_core_rw_grp2_cfg 4
+#define REG_WR_ADDR_bif_core_rw_grp2_cfg 4
+
+/* Register rw_grp3_cfg, scope bif_core, type rw */
+typedef struct {
+  unsigned int lw         : 6;
+  unsigned int ew         : 3;
+  unsigned int zw         : 3;
+  unsigned int aw         : 2;
+  unsigned int dw         : 2;
+  unsigned int ewb        : 2;
+  unsigned int bw         : 1;
+  unsigned int wr_extend  : 1;
+  unsigned int erc_en     : 1;
+  unsigned int mode       : 1;
+  unsigned int dummy1     : 2;
+  unsigned int gated_csp0 : 2;
+  unsigned int gated_csp1 : 2;
+  unsigned int gated_csp2 : 2;
+  unsigned int gated_csp3 : 2;
+} reg_bif_core_rw_grp3_cfg;
+#define REG_RD_ADDR_bif_core_rw_grp3_cfg 8
+#define REG_WR_ADDR_bif_core_rw_grp3_cfg 8
+
+/* Register rw_grp4_cfg, scope bif_core, type rw */
+typedef struct {
+  unsigned int lw         : 6;
+  unsigned int ew         : 3;
+  unsigned int zw         : 3;
+  unsigned int aw         : 2;
+  unsigned int dw         : 2;
+  unsigned int ewb        : 2;
+  unsigned int bw         : 1;
+  unsigned int wr_extend  : 1;
+  unsigned int erc_en     : 1;
+  unsigned int mode       : 1;
+  unsigned int dummy1     : 4;
+  unsigned int gated_csp4 : 2;
+  unsigned int gated_csp5 : 2;
+  unsigned int gated_csp6 : 2;
+} reg_bif_core_rw_grp4_cfg;
+#define REG_RD_ADDR_bif_core_rw_grp4_cfg 12
+#define REG_WR_ADDR_bif_core_rw_grp4_cfg 12
+
+/* Register rw_sdram_cfg_grp0, scope bif_core, type rw */
+typedef struct {
+  unsigned int bank_sel : 5;
+  unsigned int ca       : 3;
+  unsigned int type     : 1;
+  unsigned int bw       : 1;
+  unsigned int sh       : 3;
+  unsigned int wmm      : 1;
+  unsigned int sh16     : 1;
+  unsigned int grp_sel  : 5;
+  unsigned int dummy1   : 12;
+} reg_bif_core_rw_sdram_cfg_grp0;
+#define REG_RD_ADDR_bif_core_rw_sdram_cfg_grp0 16
+#define REG_WR_ADDR_bif_core_rw_sdram_cfg_grp0 16
+
+/* Register rw_sdram_cfg_grp1, scope bif_core, type rw */
+typedef struct {
+  unsigned int bank_sel : 5;
+  unsigned int ca       : 3;
+  unsigned int type     : 1;
+  unsigned int bw       : 1;
+  unsigned int sh       : 3;
+  unsigned int wmm      : 1;
+  unsigned int sh16     : 1;
+  unsigned int dummy1   : 17;
+} reg_bif_core_rw_sdram_cfg_grp1;
+#define REG_RD_ADDR_bif_core_rw_sdram_cfg_grp1 20
+#define REG_WR_ADDR_bif_core_rw_sdram_cfg_grp1 20
+
+/* Register rw_sdram_timing, scope bif_core, type rw */
+typedef struct {
+  unsigned int cl    : 3;
+  unsigned int rcd   : 3;
+  unsigned int rp    : 3;
+  unsigned int rc    : 2;
+  unsigned int dpl   : 2;
+  unsigned int pde   : 1;
+  unsigned int ref   : 2;
+  unsigned int cpd   : 1;
+  unsigned int sdcke : 1;
+  unsigned int sdclk : 1;
+  unsigned int dummy1 : 13;
+} reg_bif_core_rw_sdram_timing;
+#define REG_RD_ADDR_bif_core_rw_sdram_timing 24
+#define REG_WR_ADDR_bif_core_rw_sdram_timing 24
+
+/* Register rw_sdram_cmd, scope bif_core, type rw */
+typedef struct {
+  unsigned int cmd      : 3;
+  unsigned int mrs_data : 15;
+  unsigned int dummy1   : 14;
+} reg_bif_core_rw_sdram_cmd;
+#define REG_RD_ADDR_bif_core_rw_sdram_cmd 28
+#define REG_WR_ADDR_bif_core_rw_sdram_cmd 28
+
+/* Register rs_sdram_ref_stat, scope bif_core, type rs */
+typedef struct {
+  unsigned int ok : 1;
+  unsigned int dummy1 : 31;
+} reg_bif_core_rs_sdram_ref_stat;
+#define REG_RD_ADDR_bif_core_rs_sdram_ref_stat 32
+
+/* Register r_sdram_ref_stat, scope bif_core, type r */
+typedef struct {
+  unsigned int ok : 1;
+  unsigned int dummy1 : 31;
+} reg_bif_core_r_sdram_ref_stat;
+#define REG_RD_ADDR_bif_core_r_sdram_ref_stat 36
+
+
+/* Constants */
+enum {
+  regk_bif_core_bank2                      = 0x00000000,
+  regk_bif_core_bank4                      = 0x00000001,
+  regk_bif_core_bit10                      = 0x0000000a,
+  regk_bif_core_bit11                      = 0x0000000b,
+  regk_bif_core_bit12                      = 0x0000000c,
+  regk_bif_core_bit13                      = 0x0000000d,
+  regk_bif_core_bit14                      = 0x0000000e,
+  regk_bif_core_bit15                      = 0x0000000f,
+  regk_bif_core_bit16                      = 0x00000010,
+  regk_bif_core_bit17                      = 0x00000011,
+  regk_bif_core_bit18                      = 0x00000012,
+  regk_bif_core_bit19                      = 0x00000013,
+  regk_bif_core_bit20                      = 0x00000014,
+  regk_bif_core_bit21                      = 0x00000015,
+  regk_bif_core_bit22                      = 0x00000016,
+  regk_bif_core_bit23                      = 0x00000017,
+  regk_bif_core_bit24                      = 0x00000018,
+  regk_bif_core_bit25                      = 0x00000019,
+  regk_bif_core_bit26                      = 0x0000001a,
+  regk_bif_core_bit27                      = 0x0000001b,
+  regk_bif_core_bit28                      = 0x0000001c,
+  regk_bif_core_bit29                      = 0x0000001d,
+  regk_bif_core_bit9                       = 0x00000009,
+  regk_bif_core_bw16                       = 0x00000001,
+  regk_bif_core_bw32                       = 0x00000000,
+  regk_bif_core_bwe                        = 0x00000000,
+  regk_bif_core_cwe                        = 0x00000001,
+  regk_bif_core_e15us                      = 0x00000001,
+  regk_bif_core_e7800ns                    = 0x00000002,
+  regk_bif_core_grp0                       = 0x00000000,
+  regk_bif_core_grp1                       = 0x00000001,
+  regk_bif_core_mrs                        = 0x00000003,
+  regk_bif_core_no                         = 0x00000000,
+  regk_bif_core_none                       = 0x00000000,
+  regk_bif_core_nop                        = 0x00000000,
+  regk_bif_core_off                        = 0x00000000,
+  regk_bif_core_pre                        = 0x00000002,
+  regk_bif_core_r_sdram_ref_stat_default   = 0x00000001,
+  regk_bif_core_rd                         = 0x00000002,
+  regk_bif_core_ref                        = 0x00000001,
+  regk_bif_core_rs_sdram_ref_stat_default  = 0x00000001,
+  regk_bif_core_rw_grp1_cfg_default        = 0x000006cf,
+  regk_bif_core_rw_grp2_cfg_default        = 0x000006cf,
+  regk_bif_core_rw_grp3_cfg_default        = 0x000006cf,
+  regk_bif_core_rw_grp4_cfg_default        = 0x000006cf,
+  regk_bif_core_rw_sdram_cfg_grp1_default  = 0x00000000,
+  regk_bif_core_slf                        = 0x00000004,
+  regk_bif_core_wr                         = 0x00000001,
+  regk_bif_core_yes                        = 0x00000001
+};
+#endif /* __bif_core_defs_h */
diff --git a/include/asm-cris/arch-v32/hwregs/bif_dma_defs.h b/include/asm-cris/arch-v32/hwregs/bif_dma_defs.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/bif_dma_defs.h
@@ -0,0 +1,473 @@
+#ifndef __bif_dma_defs_h
+#define __bif_dma_defs_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/bif/rtl/bif_dma_regs.r
+ *     id:           bif_dma_regs.r,v 1.6 2005/02/04 13:28:31 perz Exp
+ *     last modfied: Mon Apr 11 16:06:33 2005
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c --outfile bif_dma_defs.h ../../inst/bif/rtl/bif_dma_regs.r
+ *      id: $Id: bif_dma_defs.h,v 1.2 2005/04/24 18:30:58 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+/* Main access macros */
+#ifndef REG_RD
+#define REG_RD( scope, inst, reg ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR
+#define REG_WR( scope, inst, reg, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_VECT
+#define REG_RD_VECT( scope, inst, reg, index ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_VECT
+#define REG_WR_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT
+#define REG_RD_INT( scope, inst, reg ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT
+#define REG_WR_INT( scope, inst, reg, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT_VECT
+#define REG_RD_INT_VECT( scope, inst, reg, index ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT_VECT
+#define REG_WR_INT_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_TYPE_CONV
+#define REG_TYPE_CONV( type, orgtype, val ) \
+  ( { union { orgtype o; type n; } r; r.o = val; r.n; } )
+#endif
+
+#ifndef reg_page_size
+#define reg_page_size 8192
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg + \
+    (index) * STRIDE_##scope##_##reg )
+#endif
+
+/* C-code for register scope bif_dma */
+
+/* Register rw_ch0_ctrl, scope bif_dma, type rw */
+typedef struct {
+  unsigned int bw         : 2;
+  unsigned int burst_len  : 1;
+  unsigned int cont       : 1;
+  unsigned int end_pad    : 1;
+  unsigned int cnt        : 1;
+  unsigned int dreq_pin   : 3;
+  unsigned int dreq_mode  : 2;
+  unsigned int tc_in_pin  : 3;
+  unsigned int tc_in_mode : 2;
+  unsigned int bus_mode   : 2;
+  unsigned int rate_en    : 1;
+  unsigned int wr_all     : 1;
+  unsigned int dummy1     : 12;
+} reg_bif_dma_rw_ch0_ctrl;
+#define REG_RD_ADDR_bif_dma_rw_ch0_ctrl 0
+#define REG_WR_ADDR_bif_dma_rw_ch0_ctrl 0
+
+/* Register rw_ch0_addr, scope bif_dma, type rw */
+typedef struct {
+  unsigned int addr : 32;
+} reg_bif_dma_rw_ch0_addr;
+#define REG_RD_ADDR_bif_dma_rw_ch0_addr 4
+#define REG_WR_ADDR_bif_dma_rw_ch0_addr 4
+
+/* Register rw_ch0_start, scope bif_dma, type rw */
+typedef struct {
+  unsigned int run : 1;
+  unsigned int dummy1 : 31;
+} reg_bif_dma_rw_ch0_start;
+#define REG_RD_ADDR_bif_dma_rw_ch0_start 8
+#define REG_WR_ADDR_bif_dma_rw_ch0_start 8
+
+/* Register rw_ch0_cnt, scope bif_dma, type rw */
+typedef struct {
+  unsigned int start_cnt : 16;
+  unsigned int dummy1    : 16;
+} reg_bif_dma_rw_ch0_cnt;
+#define REG_RD_ADDR_bif_dma_rw_ch0_cnt 12
+#define REG_WR_ADDR_bif_dma_rw_ch0_cnt 12
+
+/* Register r_ch0_stat, scope bif_dma, type r */
+typedef struct {
+  unsigned int cnt : 16;
+  unsigned int dummy1 : 15;
+  unsigned int run : 1;
+} reg_bif_dma_r_ch0_stat;
+#define REG_RD_ADDR_bif_dma_r_ch0_stat 16
+
+/* Register rw_ch1_ctrl, scope bif_dma, type rw */
+typedef struct {
+  unsigned int bw          : 2;
+  unsigned int burst_len   : 1;
+  unsigned int cont        : 1;
+  unsigned int end_discard : 1;
+  unsigned int cnt         : 1;
+  unsigned int dreq_pin    : 3;
+  unsigned int dreq_mode   : 2;
+  unsigned int tc_in_pin   : 3;
+  unsigned int tc_in_mode  : 2;
+  unsigned int bus_mode    : 2;
+  unsigned int rate_en     : 1;
+  unsigned int dummy1      : 13;
+} reg_bif_dma_rw_ch1_ctrl;
+#define REG_RD_ADDR_bif_dma_rw_ch1_ctrl 32
+#define REG_WR_ADDR_bif_dma_rw_ch1_ctrl 32
+
+/* Register rw_ch1_addr, scope bif_dma, type rw */
+typedef struct {
+  unsigned int addr : 32;
+} reg_bif_dma_rw_ch1_addr;
+#define REG_RD_ADDR_bif_dma_rw_ch1_addr 36
+#define REG_WR_ADDR_bif_dma_rw_ch1_addr 36
+
+/* Register rw_ch1_start, scope bif_dma, type rw */
+typedef struct {
+  unsigned int run : 1;
+  unsigned int dummy1 : 31;
+} reg_bif_dma_rw_ch1_start;
+#define REG_RD_ADDR_bif_dma_rw_ch1_start 40
+#define REG_WR_ADDR_bif_dma_rw_ch1_start 40
+
+/* Register rw_ch1_cnt, scope bif_dma, type rw */
+typedef struct {
+  unsigned int start_cnt : 16;
+  unsigned int dummy1    : 16;
+} reg_bif_dma_rw_ch1_cnt;
+#define REG_RD_ADDR_bif_dma_rw_ch1_cnt 44
+#define REG_WR_ADDR_bif_dma_rw_ch1_cnt 44
+
+/* Register r_ch1_stat, scope bif_dma, type r */
+typedef struct {
+  unsigned int cnt : 16;
+  unsigned int dummy1 : 15;
+  unsigned int run : 1;
+} reg_bif_dma_r_ch1_stat;
+#define REG_RD_ADDR_bif_dma_r_ch1_stat 48
+
+/* Register rw_ch2_ctrl, scope bif_dma, type rw */
+typedef struct {
+  unsigned int bw         : 2;
+  unsigned int burst_len  : 1;
+  unsigned int cont       : 1;
+  unsigned int end_pad    : 1;
+  unsigned int cnt        : 1;
+  unsigned int dreq_pin   : 3;
+  unsigned int dreq_mode  : 2;
+  unsigned int tc_in_pin  : 3;
+  unsigned int tc_in_mode : 2;
+  unsigned int bus_mode   : 2;
+  unsigned int rate_en    : 1;
+  unsigned int wr_all     : 1;
+  unsigned int dummy1     : 12;
+} reg_bif_dma_rw_ch2_ctrl;
+#define REG_RD_ADDR_bif_dma_rw_ch2_ctrl 64
+#define REG_WR_ADDR_bif_dma_rw_ch2_ctrl 64
+
+/* Register rw_ch2_addr, scope bif_dma, type rw */
+typedef struct {
+  unsigned int addr : 32;
+} reg_bif_dma_rw_ch2_addr;
+#define REG_RD_ADDR_bif_dma_rw_ch2_addr 68
+#define REG_WR_ADDR_bif_dma_rw_ch2_addr 68
+
+/* Register rw_ch2_start, scope bif_dma, type rw */
+typedef struct {
+  unsigned int run : 1;
+  unsigned int dummy1 : 31;
+} reg_bif_dma_rw_ch2_start;
+#define REG_RD_ADDR_bif_dma_rw_ch2_start 72
+#define REG_WR_ADDR_bif_dma_rw_ch2_start 72
+
+/* Register rw_ch2_cnt, scope bif_dma, type rw */
+typedef struct {
+  unsigned int start_cnt : 16;
+  unsigned int dummy1    : 16;
+} reg_bif_dma_rw_ch2_cnt;
+#define REG_RD_ADDR_bif_dma_rw_ch2_cnt 76
+#define REG_WR_ADDR_bif_dma_rw_ch2_cnt 76
+
+/* Register r_ch2_stat, scope bif_dma, type r */
+typedef struct {
+  unsigned int cnt : 16;
+  unsigned int dummy1 : 15;
+  unsigned int run : 1;
+} reg_bif_dma_r_ch2_stat;
+#define REG_RD_ADDR_bif_dma_r_ch2_stat 80
+
+/* Register rw_ch3_ctrl, scope bif_dma, type rw */
+typedef struct {
+  unsigned int bw          : 2;
+  unsigned int burst_len   : 1;
+  unsigned int cont        : 1;
+  unsigned int end_discard : 1;
+  unsigned int cnt         : 1;
+  unsigned int dreq_pin    : 3;
+  unsigned int dreq_mode   : 2;
+  unsigned int tc_in_pin   : 3;
+  unsigned int tc_in_mode  : 2;
+  unsigned int bus_mode    : 2;
+  unsigned int rate_en     : 1;
+  unsigned int dummy1      : 13;
+} reg_bif_dma_rw_ch3_ctrl;
+#define REG_RD_ADDR_bif_dma_rw_ch3_ctrl 96
+#define REG_WR_ADDR_bif_dma_rw_ch3_ctrl 96
+
+/* Register rw_ch3_addr, scope bif_dma, type rw */
+typedef struct {
+  unsigned int addr : 32;
+} reg_bif_dma_rw_ch3_addr;
+#define REG_RD_ADDR_bif_dma_rw_ch3_addr 100
+#define REG_WR_ADDR_bif_dma_rw_ch3_addr 100
+
+/* Register rw_ch3_start, scope bif_dma, type rw */
+typedef struct {
+  unsigned int run : 1;
+  unsigned int dummy1 : 31;
+} reg_bif_dma_rw_ch3_start;
+#define REG_RD_ADDR_bif_dma_rw_ch3_start 104
+#define REG_WR_ADDR_bif_dma_rw_ch3_start 104
+
+/* Register rw_ch3_cnt, scope bif_dma, type rw */
+typedef struct {
+  unsigned int start_cnt : 16;
+  unsigned int dummy1    : 16;
+} reg_bif_dma_rw_ch3_cnt;
+#define REG_RD_ADDR_bif_dma_rw_ch3_cnt 108
+#define REG_WR_ADDR_bif_dma_rw_ch3_cnt 108
+
+/* Register r_ch3_stat, scope bif_dma, type r */
+typedef struct {
+  unsigned int cnt : 16;
+  unsigned int dummy1 : 15;
+  unsigned int run : 1;
+} reg_bif_dma_r_ch3_stat;
+#define REG_RD_ADDR_bif_dma_r_ch3_stat 112
+
+/* Register rw_intr_mask, scope bif_dma, type rw */
+typedef struct {
+  unsigned int ext_dma0 : 1;
+  unsigned int ext_dma1 : 1;
+  unsigned int ext_dma2 : 1;
+  unsigned int ext_dma3 : 1;
+  unsigned int dummy1   : 28;
+} reg_bif_dma_rw_intr_mask;
+#define REG_RD_ADDR_bif_dma_rw_intr_mask 128
+#define REG_WR_ADDR_bif_dma_rw_intr_mask 128
+
+/* Register rw_ack_intr, scope bif_dma, type rw */
+typedef struct {
+  unsigned int ext_dma0 : 1;
+  unsigned int ext_dma1 : 1;
+  unsigned int ext_dma2 : 1;
+  unsigned int ext_dma3 : 1;
+  unsigned int dummy1   : 28;
+} reg_bif_dma_rw_ack_intr;
+#define REG_RD_ADDR_bif_dma_rw_ack_intr 132
+#define REG_WR_ADDR_bif_dma_rw_ack_intr 132
+
+/* Register r_intr, scope bif_dma, type r */
+typedef struct {
+  unsigned int ext_dma0 : 1;
+  unsigned int ext_dma1 : 1;
+  unsigned int ext_dma2 : 1;
+  unsigned int ext_dma3 : 1;
+  unsigned int dummy1   : 28;
+} reg_bif_dma_r_intr;
+#define REG_RD_ADDR_bif_dma_r_intr 136
+
+/* Register r_masked_intr, scope bif_dma, type r */
+typedef struct {
+  unsigned int ext_dma0 : 1;
+  unsigned int ext_dma1 : 1;
+  unsigned int ext_dma2 : 1;
+  unsigned int ext_dma3 : 1;
+  unsigned int dummy1   : 28;
+} reg_bif_dma_r_masked_intr;
+#define REG_RD_ADDR_bif_dma_r_masked_intr 140
+
+/* Register rw_pin0_cfg, scope bif_dma, type rw */
+typedef struct {
+  unsigned int master_ch   : 2;
+  unsigned int master_mode : 3;
+  unsigned int slave_ch    : 2;
+  unsigned int slave_mode  : 3;
+  unsigned int dummy1      : 22;
+} reg_bif_dma_rw_pin0_cfg;
+#define REG_RD_ADDR_bif_dma_rw_pin0_cfg 160
+#define REG_WR_ADDR_bif_dma_rw_pin0_cfg 160
+
+/* Register rw_pin1_cfg, scope bif_dma, type rw */
+typedef struct {
+  unsigned int master_ch   : 2;
+  unsigned int master_mode : 3;
+  unsigned int slave_ch    : 2;
+  unsigned int slave_mode  : 3;
+  unsigned int dummy1      : 22;
+} reg_bif_dma_rw_pin1_cfg;
+#define REG_RD_ADDR_bif_dma_rw_pin1_cfg 164
+#define REG_WR_ADDR_bif_dma_rw_pin1_cfg 164
+
+/* Register rw_pin2_cfg, scope bif_dma, type rw */
+typedef struct {
+  unsigned int master_ch   : 2;
+  unsigned int master_mode : 3;
+  unsigned int slave_ch    : 2;
+  unsigned int slave_mode  : 3;
+  unsigned int dummy1      : 22;
+} reg_bif_dma_rw_pin2_cfg;
+#define REG_RD_ADDR_bif_dma_rw_pin2_cfg 168
+#define REG_WR_ADDR_bif_dma_rw_pin2_cfg 168
+
+/* Register rw_pin3_cfg, scope bif_dma, type rw */
+typedef struct {
+  unsigned int master_ch   : 2;
+  unsigned int master_mode : 3;
+  unsigned int slave_ch    : 2;
+  unsigned int slave_mode  : 3;
+  unsigned int dummy1      : 22;
+} reg_bif_dma_rw_pin3_cfg;
+#define REG_RD_ADDR_bif_dma_rw_pin3_cfg 172
+#define REG_WR_ADDR_bif_dma_rw_pin3_cfg 172
+
+/* Register rw_pin4_cfg, scope bif_dma, type rw */
+typedef struct {
+  unsigned int master_ch   : 2;
+  unsigned int master_mode : 3;
+  unsigned int slave_ch    : 2;
+  unsigned int slave_mode  : 3;
+  unsigned int dummy1      : 22;
+} reg_bif_dma_rw_pin4_cfg;
+#define REG_RD_ADDR_bif_dma_rw_pin4_cfg 176
+#define REG_WR_ADDR_bif_dma_rw_pin4_cfg 176
+
+/* Register rw_pin5_cfg, scope bif_dma, type rw */
+typedef struct {
+  unsigned int master_ch   : 2;
+  unsigned int master_mode : 3;
+  unsigned int slave_ch    : 2;
+  unsigned int slave_mode  : 3;
+  unsigned int dummy1      : 22;
+} reg_bif_dma_rw_pin5_cfg;
+#define REG_RD_ADDR_bif_dma_rw_pin5_cfg 180
+#define REG_WR_ADDR_bif_dma_rw_pin5_cfg 180
+
+/* Register rw_pin6_cfg, scope bif_dma, type rw */
+typedef struct {
+  unsigned int master_ch   : 2;
+  unsigned int master_mode : 3;
+  unsigned int slave_ch    : 2;
+  unsigned int slave_mode  : 3;
+  unsigned int dummy1      : 22;
+} reg_bif_dma_rw_pin6_cfg;
+#define REG_RD_ADDR_bif_dma_rw_pin6_cfg 184
+#define REG_WR_ADDR_bif_dma_rw_pin6_cfg 184
+
+/* Register rw_pin7_cfg, scope bif_dma, type rw */
+typedef struct {
+  unsigned int master_ch   : 2;
+  unsigned int master_mode : 3;
+  unsigned int slave_ch    : 2;
+  unsigned int slave_mode  : 3;
+  unsigned int dummy1      : 22;
+} reg_bif_dma_rw_pin7_cfg;
+#define REG_RD_ADDR_bif_dma_rw_pin7_cfg 188
+#define REG_WR_ADDR_bif_dma_rw_pin7_cfg 188
+
+/* Register r_pin_stat, scope bif_dma, type r */
+typedef struct {
+  unsigned int pin0 : 1;
+  unsigned int pin1 : 1;
+  unsigned int pin2 : 1;
+  unsigned int pin3 : 1;
+  unsigned int pin4 : 1;
+  unsigned int pin5 : 1;
+  unsigned int pin6 : 1;
+  unsigned int pin7 : 1;
+  unsigned int dummy1 : 24;
+} reg_bif_dma_r_pin_stat;
+#define REG_RD_ADDR_bif_dma_r_pin_stat 192
+
+
+/* Constants */
+enum {
+  regk_bif_dma_as_master                   = 0x00000001,
+  regk_bif_dma_as_slave                    = 0x00000001,
+  regk_bif_dma_burst1                      = 0x00000000,
+  regk_bif_dma_burst8                      = 0x00000001,
+  regk_bif_dma_bw16                        = 0x00000001,
+  regk_bif_dma_bw32                        = 0x00000002,
+  regk_bif_dma_bw8                         = 0x00000000,
+  regk_bif_dma_dack                        = 0x00000006,
+  regk_bif_dma_dack_inv                    = 0x00000007,
+  regk_bif_dma_force                       = 0x00000001,
+  regk_bif_dma_hi                          = 0x00000003,
+  regk_bif_dma_inv                         = 0x00000003,
+  regk_bif_dma_lo                          = 0x00000002,
+  regk_bif_dma_master                      = 0x00000001,
+  regk_bif_dma_no                          = 0x00000000,
+  regk_bif_dma_norm                        = 0x00000002,
+  regk_bif_dma_off                         = 0x00000000,
+  regk_bif_dma_rw_ch0_ctrl_default         = 0x00000000,
+  regk_bif_dma_rw_ch0_start_default        = 0x00000000,
+  regk_bif_dma_rw_ch1_ctrl_default         = 0x00000000,
+  regk_bif_dma_rw_ch1_start_default        = 0x00000000,
+  regk_bif_dma_rw_ch2_ctrl_default         = 0x00000000,
+  regk_bif_dma_rw_ch2_start_default        = 0x00000000,
+  regk_bif_dma_rw_ch3_ctrl_default         = 0x00000000,
+  regk_bif_dma_rw_ch3_start_default        = 0x00000000,
+  regk_bif_dma_rw_intr_mask_default        = 0x00000000,
+  regk_bif_dma_rw_pin0_cfg_default         = 0x00000000,
+  regk_bif_dma_rw_pin1_cfg_default         = 0x00000000,
+  regk_bif_dma_rw_pin2_cfg_default         = 0x00000000,
+  regk_bif_dma_rw_pin3_cfg_default         = 0x00000000,
+  regk_bif_dma_rw_pin4_cfg_default         = 0x00000000,
+  regk_bif_dma_rw_pin5_cfg_default         = 0x00000000,
+  regk_bif_dma_rw_pin6_cfg_default         = 0x00000000,
+  regk_bif_dma_rw_pin7_cfg_default         = 0x00000000,
+  regk_bif_dma_slave                       = 0x00000002,
+  regk_bif_dma_sreq                        = 0x00000006,
+  regk_bif_dma_sreq_inv                    = 0x00000007,
+  regk_bif_dma_tc                          = 0x00000004,
+  regk_bif_dma_tc_inv                      = 0x00000005,
+  regk_bif_dma_yes                         = 0x00000001
+};
+#endif /* __bif_dma_defs_h */
diff --git a/include/asm-cris/arch-v32/hwregs/bif_slave_defs.h b/include/asm-cris/arch-v32/hwregs/bif_slave_defs.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/bif_slave_defs.h
@@ -0,0 +1,249 @@
+#ifndef __bif_slave_defs_h
+#define __bif_slave_defs_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/bif/rtl/bif_slave_regs.r
+ *     id:           bif_slave_regs.r,v 1.5 2005/02/04 13:55:28 perz Exp
+ *     last modfied: Mon Apr 11 16:06:34 2005
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c --outfile bif_slave_defs.h ../../inst/bif/rtl/bif_slave_regs.r
+ *      id: $Id: bif_slave_defs.h,v 1.2 2005/04/24 18:30:58 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+/* Main access macros */
+#ifndef REG_RD
+#define REG_RD( scope, inst, reg ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR
+#define REG_WR( scope, inst, reg, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_VECT
+#define REG_RD_VECT( scope, inst, reg, index ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_VECT
+#define REG_WR_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT
+#define REG_RD_INT( scope, inst, reg ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT
+#define REG_WR_INT( scope, inst, reg, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT_VECT
+#define REG_RD_INT_VECT( scope, inst, reg, index ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT_VECT
+#define REG_WR_INT_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_TYPE_CONV
+#define REG_TYPE_CONV( type, orgtype, val ) \
+  ( { union { orgtype o; type n; } r; r.o = val; r.n; } )
+#endif
+
+#ifndef reg_page_size
+#define reg_page_size 8192
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg + \
+    (index) * STRIDE_##scope##_##reg )
+#endif
+
+/* C-code for register scope bif_slave */
+
+/* Register rw_slave_cfg, scope bif_slave, type rw */
+typedef struct {
+  unsigned int slave_id     : 3;
+  unsigned int use_slave_id : 1;
+  unsigned int boot_rdy     : 1;
+  unsigned int loopback     : 1;
+  unsigned int dis          : 1;
+  unsigned int dummy1       : 25;
+} reg_bif_slave_rw_slave_cfg;
+#define REG_RD_ADDR_bif_slave_rw_slave_cfg 0
+#define REG_WR_ADDR_bif_slave_rw_slave_cfg 0
+
+/* Register r_slave_mode, scope bif_slave, type r */
+typedef struct {
+  unsigned int ch0_mode : 1;
+  unsigned int ch1_mode : 1;
+  unsigned int ch2_mode : 1;
+  unsigned int ch3_mode : 1;
+  unsigned int dummy1   : 28;
+} reg_bif_slave_r_slave_mode;
+#define REG_RD_ADDR_bif_slave_r_slave_mode 4
+
+/* Register rw_ch0_cfg, scope bif_slave, type rw */
+typedef struct {
+  unsigned int rd_hold     : 2;
+  unsigned int access_mode : 1;
+  unsigned int access_ctrl : 1;
+  unsigned int data_cs     : 2;
+  unsigned int dummy1      : 26;
+} reg_bif_slave_rw_ch0_cfg;
+#define REG_RD_ADDR_bif_slave_rw_ch0_cfg 16
+#define REG_WR_ADDR_bif_slave_rw_ch0_cfg 16
+
+/* Register rw_ch1_cfg, scope bif_slave, type rw */
+typedef struct {
+  unsigned int rd_hold     : 2;
+  unsigned int access_mode : 1;
+  unsigned int access_ctrl : 1;
+  unsigned int data_cs     : 2;
+  unsigned int dummy1      : 26;
+} reg_bif_slave_rw_ch1_cfg;
+#define REG_RD_ADDR_bif_slave_rw_ch1_cfg 20
+#define REG_WR_ADDR_bif_slave_rw_ch1_cfg 20
+
+/* Register rw_ch2_cfg, scope bif_slave, type rw */
+typedef struct {
+  unsigned int rd_hold     : 2;
+  unsigned int access_mode : 1;
+  unsigned int access_ctrl : 1;
+  unsigned int data_cs     : 2;
+  unsigned int dummy1      : 26;
+} reg_bif_slave_rw_ch2_cfg;
+#define REG_RD_ADDR_bif_slave_rw_ch2_cfg 24
+#define REG_WR_ADDR_bif_slave_rw_ch2_cfg 24
+
+/* Register rw_ch3_cfg, scope bif_slave, type rw */
+typedef struct {
+  unsigned int rd_hold     : 2;
+  unsigned int access_mode : 1;
+  unsigned int access_ctrl : 1;
+  unsigned int data_cs     : 2;
+  unsigned int dummy1      : 26;
+} reg_bif_slave_rw_ch3_cfg;
+#define REG_RD_ADDR_bif_slave_rw_ch3_cfg 28
+#define REG_WR_ADDR_bif_slave_rw_ch3_cfg 28
+
+/* Register rw_arb_cfg, scope bif_slave, type rw */
+typedef struct {
+  unsigned int brin_mode   : 1;
+  unsigned int brout_mode  : 3;
+  unsigned int bg_mode     : 3;
+  unsigned int release     : 2;
+  unsigned int acquire     : 1;
+  unsigned int settle_time : 2;
+  unsigned int dram_ctrl   : 1;
+  unsigned int dummy1      : 19;
+} reg_bif_slave_rw_arb_cfg;
+#define REG_RD_ADDR_bif_slave_rw_arb_cfg 32
+#define REG_WR_ADDR_bif_slave_rw_arb_cfg 32
+
+/* Register r_arb_stat, scope bif_slave, type r */
+typedef struct {
+  unsigned int init_mode : 1;
+  unsigned int mode      : 1;
+  unsigned int brin      : 1;
+  unsigned int brout     : 1;
+  unsigned int bg        : 1;
+  unsigned int dummy1    : 27;
+} reg_bif_slave_r_arb_stat;
+#define REG_RD_ADDR_bif_slave_r_arb_stat 36
+
+/* Register rw_intr_mask, scope bif_slave, type rw */
+typedef struct {
+  unsigned int bus_release : 1;
+  unsigned int bus_acquire : 1;
+  unsigned int dummy1      : 30;
+} reg_bif_slave_rw_intr_mask;
+#define REG_RD_ADDR_bif_slave_rw_intr_mask 64
+#define REG_WR_ADDR_bif_slave_rw_intr_mask 64
+
+/* Register rw_ack_intr, scope bif_slave, type rw */
+typedef struct {
+  unsigned int bus_release : 1;
+  unsigned int bus_acquire : 1;
+  unsigned int dummy1      : 30;
+} reg_bif_slave_rw_ack_intr;
+#define REG_RD_ADDR_bif_slave_rw_ack_intr 68
+#define REG_WR_ADDR_bif_slave_rw_ack_intr 68
+
+/* Register r_intr, scope bif_slave, type r */
+typedef struct {
+  unsigned int bus_release : 1;
+  unsigned int bus_acquire : 1;
+  unsigned int dummy1      : 30;
+} reg_bif_slave_r_intr;
+#define REG_RD_ADDR_bif_slave_r_intr 72
+
+/* Register r_masked_intr, scope bif_slave, type r */
+typedef struct {
+  unsigned int bus_release : 1;
+  unsigned int bus_acquire : 1;
+  unsigned int dummy1      : 30;
+} reg_bif_slave_r_masked_intr;
+#define REG_RD_ADDR_bif_slave_r_masked_intr 76
+
+
+/* Constants */
+enum {
+  regk_bif_slave_active_hi                 = 0x00000003,
+  regk_bif_slave_active_lo                 = 0x00000002,
+  regk_bif_slave_addr                      = 0x00000000,
+  regk_bif_slave_always                    = 0x00000001,
+  regk_bif_slave_at_idle                   = 0x00000002,
+  regk_bif_slave_burst_end                 = 0x00000003,
+  regk_bif_slave_dma                       = 0x00000001,
+  regk_bif_slave_hi                        = 0x00000003,
+  regk_bif_slave_inv                       = 0x00000001,
+  regk_bif_slave_lo                        = 0x00000002,
+  regk_bif_slave_local                     = 0x00000001,
+  regk_bif_slave_master                    = 0x00000000,
+  regk_bif_slave_mode_reg                  = 0x00000001,
+  regk_bif_slave_no                        = 0x00000000,
+  regk_bif_slave_norm                      = 0x00000000,
+  regk_bif_slave_on_access                 = 0x00000000,
+  regk_bif_slave_rw_arb_cfg_default        = 0x00000000,
+  regk_bif_slave_rw_ch0_cfg_default        = 0x00000000,
+  regk_bif_slave_rw_ch1_cfg_default        = 0x00000000,
+  regk_bif_slave_rw_ch2_cfg_default        = 0x00000000,
+  regk_bif_slave_rw_ch3_cfg_default        = 0x00000000,
+  regk_bif_slave_rw_intr_mask_default      = 0x00000000,
+  regk_bif_slave_rw_slave_cfg_default      = 0x00000000,
+  regk_bif_slave_shared                    = 0x00000000,
+  regk_bif_slave_slave                     = 0x00000001,
+  regk_bif_slave_t0ns                      = 0x00000003,
+  regk_bif_slave_t10ns                     = 0x00000002,
+  regk_bif_slave_t20ns                     = 0x00000003,
+  regk_bif_slave_t30ns                     = 0x00000002,
+  regk_bif_slave_t40ns                     = 0x00000001,
+  regk_bif_slave_t50ns                     = 0x00000000,
+  regk_bif_slave_yes                       = 0x00000001,
+  regk_bif_slave_z                         = 0x00000004
+};
+#endif /* __bif_slave_defs_h */
diff --git a/include/asm-cris/arch-v32/hwregs/config_defs.h b/include/asm-cris/arch-v32/hwregs/config_defs.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/config_defs.h
@@ -0,0 +1,142 @@
+#ifndef __config_defs_h
+#define __config_defs_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../rtl/config_regs.r
+ *     id:           config_regs.r,v 1.23 2004/03/04 11:34:42 mikaeln Exp
+ *     last modfied: Thu Mar  4 12:34:39 2004
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c --outfile config_defs.h ../../rtl/config_regs.r
+ *      id: $Id: config_defs.h,v 1.6 2005/04/24 18:30:58 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+/* Main access macros */
+#ifndef REG_RD
+#define REG_RD( scope, inst, reg ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR
+#define REG_WR( scope, inst, reg, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_VECT
+#define REG_RD_VECT( scope, inst, reg, index ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_VECT
+#define REG_WR_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT
+#define REG_RD_INT( scope, inst, reg ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT
+#define REG_WR_INT( scope, inst, reg, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT_VECT
+#define REG_RD_INT_VECT( scope, inst, reg, index ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT_VECT
+#define REG_WR_INT_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_TYPE_CONV
+#define REG_TYPE_CONV( type, orgtype, val ) \
+  ( { union { orgtype o; type n; } r; r.o = val; r.n; } )
+#endif
+
+#ifndef reg_page_size
+#define reg_page_size 8192
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg + \
+    (index) * STRIDE_##scope##_##reg )
+#endif
+
+/* C-code for register scope config */
+
+/* Register r_bootsel, scope config, type r */
+typedef struct {
+  unsigned int boot_mode   : 3;
+  unsigned int full_duplex : 1;
+  unsigned int user        : 1;
+  unsigned int pll         : 1;
+  unsigned int flash_bw    : 1;
+  unsigned int dummy1      : 25;
+} reg_config_r_bootsel;
+#define REG_RD_ADDR_config_r_bootsel 0
+
+/* Register rw_clk_ctrl, scope config, type rw */
+typedef struct {
+  unsigned int pll          : 1;
+  unsigned int cpu          : 1;
+  unsigned int iop          : 1;
+  unsigned int dma01_eth0   : 1;
+  unsigned int dma23        : 1;
+  unsigned int dma45        : 1;
+  unsigned int dma67        : 1;
+  unsigned int dma89_strcop : 1;
+  unsigned int bif          : 1;
+  unsigned int fix_io       : 1;
+  unsigned int dummy1       : 22;
+} reg_config_rw_clk_ctrl;
+#define REG_RD_ADDR_config_rw_clk_ctrl 4
+#define REG_WR_ADDR_config_rw_clk_ctrl 4
+
+/* Register rw_pad_ctrl, scope config, type rw */
+typedef struct {
+  unsigned int usb_susp : 1;
+  unsigned int phyrst_n : 1;
+  unsigned int dummy1   : 30;
+} reg_config_rw_pad_ctrl;
+#define REG_RD_ADDR_config_rw_pad_ctrl 8
+#define REG_WR_ADDR_config_rw_pad_ctrl 8
+
+
+/* Constants */
+enum {
+  regk_config_bw16                         = 0x00000000,
+  regk_config_bw32                         = 0x00000001,
+  regk_config_master                       = 0x00000005,
+  regk_config_nand                         = 0x00000003,
+  regk_config_net_rx                       = 0x00000001,
+  regk_config_net_tx_rx                    = 0x00000002,
+  regk_config_no                           = 0x00000000,
+  regk_config_none                         = 0x00000007,
+  regk_config_nor                          = 0x00000000,
+  regk_config_rw_clk_ctrl_default          = 0x00000002,
+  regk_config_rw_pad_ctrl_default          = 0x00000000,
+  regk_config_ser                          = 0x00000004,
+  regk_config_slave                        = 0x00000006,
+  regk_config_yes                          = 0x00000001
+};
+#endif /* __config_defs_h */
diff --git a/include/asm-cris/arch-v32/hwregs/cpu_vect.h b/include/asm-cris/arch-v32/hwregs/cpu_vect.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/cpu_vect.h
@@ -0,0 +1,41 @@
+/* Interrupt vector numbers autogenerated by /n/asic/design/tools/rdesc/src/rdes2intr version
+ from ../../inst/crisp/doc/cpu_vect.r
+version . */
+
+#ifndef _______INST_CRISP_DOC_CPU_VECT_R
+#define _______INST_CRISP_DOC_CPU_VECT_R
+#define NMI_INTR_VECT	0x00
+#define RESERVED_1_INTR_VECT	0x01
+#define RESERVED_2_INTR_VECT	0x02
+#define SINGLE_STEP_INTR_VECT	0x03
+#define INSTR_TLB_REFILL_INTR_VECT	0x04
+#define INSTR_TLB_INV_INTR_VECT	0x05
+#define INSTR_TLB_ACC_INTR_VECT	0x06
+#define TLB_EX_INTR_VECT	0x07
+#define DATA_TLB_REFILL_INTR_VECT	0x08
+#define DATA_TLB_INV_INTR_VECT	0x09
+#define DATA_TLB_ACC_INTR_VECT	0x0a
+#define DATA_TLB_WE_INTR_VECT	0x0b
+#define HW_BP_INTR_VECT	0x0c
+#define RESERVED_D_INTR_VECT	0x0d
+#define RESERVED_E_INTR_VECT	0x0e
+#define RESERVED_F_INTR_VECT	0x0f
+#define BREAK_0_INTR_VECT	0x10
+#define BREAK_1_INTR_VECT	0x11
+#define BREAK_2_INTR_VECT	0x12
+#define BREAK_3_INTR_VECT	0x13
+#define BREAK_4_INTR_VECT	0x14
+#define BREAK_5_INTR_VECT	0x15
+#define BREAK_6_INTR_VECT	0x16
+#define BREAK_7_INTR_VECT	0x17
+#define BREAK_8_INTR_VECT	0x18
+#define BREAK_9_INTR_VECT	0x19
+#define BREAK_10_INTR_VECT	0x1a
+#define BREAK_11_INTR_VECT	0x1b
+#define BREAK_12_INTR_VECT	0x1c
+#define BREAK_13_INTR_VECT	0x1d
+#define BREAK_14_INTR_VECT	0x1e
+#define BREAK_15_INTR_VECT	0x1f
+#define MULTIPLE_INTR_VECT	0x30
+
+#endif
diff --git a/include/asm-cris/arch-v32/hwregs/dma.h b/include/asm-cris/arch-v32/hwregs/dma.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/dma.h
@@ -0,0 +1,128 @@
+/* $Id: dma.h,v 1.7 2005/04/24 18:30:58 starvik Exp $
+ *
+ * DMA C definitions and help macros
+ *
+ */
+
+#ifndef dma_h
+#define dma_h
+
+/* registers */ /* Really needed, since both are listed in sw.list? */
+#include "dma_defs.h"
+
+
+/* descriptors */
+
+// ------------------------------------------------------------ dma_descr_group
+typedef struct dma_descr_group {
+  struct dma_descr_group       *next;
+  unsigned                      eol        : 1;
+  unsigned                      tol        : 1;
+  unsigned                      bol        : 1;
+  unsigned                                 : 1;
+  unsigned                      intr       : 1;
+  unsigned                                 : 2;
+  unsigned                      en         : 1;
+  unsigned                                 : 7;
+  unsigned                      dis        : 1;
+  unsigned                      md         : 16;
+  struct dma_descr_group       *up;
+  union {
+    struct dma_descr_context   *context;
+    struct dma_descr_group     *group;
+  }                             down;
+} dma_descr_group;
+
+// ---------------------------------------------------------- dma_descr_context
+typedef struct dma_descr_context {
+  struct dma_descr_context     *next;
+  unsigned                      eol        : 1;
+  unsigned                                 : 3;
+  unsigned                      intr       : 1;
+  unsigned                                 : 1;
+  unsigned                      store_mode : 1;
+  unsigned                      en         : 1;
+  unsigned                                 : 7;
+  unsigned                      dis        : 1;
+  unsigned                      md0        : 16;
+  unsigned                      md1;
+  unsigned                      md2;
+  unsigned                      md3;
+  unsigned                      md4;
+  struct dma_descr_data        *saved_data;
+  char                         *saved_data_buf;
+} dma_descr_context;
+
+// ------------------------------------------------------------- dma_descr_data
+typedef struct dma_descr_data {
+  struct dma_descr_data        *next;
+  char                         *buf;
+  unsigned                      eol        : 1;
+  unsigned                                 : 2;
+  unsigned                      out_eop    : 1;
+  unsigned                      intr       : 1;
+  unsigned                      wait       : 1;
+  unsigned                                 : 2;
+  unsigned                                 : 3;
+  unsigned                      in_eop     : 1;
+  unsigned                                 : 4;
+  unsigned                      md         : 16;
+  char                         *after;
+} dma_descr_data;
+
+// --------------------------------------------------------------------- macros
+
+// enable DMA channel
+#define DMA_ENABLE( inst ) \
+   do { reg_dma_rw_cfg e = REG_RD( dma, inst, rw_cfg );\
+        e.en = regk_dma_yes; \
+        REG_WR( dma, inst, rw_cfg, e); } while( 0 )
+
+// reset DMA channel
+#define DMA_RESET( inst ) \
+   do { reg_dma_rw_cfg r = REG_RD( dma, inst, rw_cfg );\
+        r.en = regk_dma_no; \
+        REG_WR( dma, inst, rw_cfg, r); } while( 0 )
+
+// stop DMA channel
+#define DMA_STOP( inst ) \
+   do { reg_dma_rw_cfg s = REG_RD( dma, inst, rw_cfg );\
+        s.stop = regk_dma_yes; \
+        REG_WR( dma, inst, rw_cfg, s); } while( 0 )
+
+// continue DMA channel operation
+#define DMA_CONTINUE( inst ) \
+   do { reg_dma_rw_cfg c = REG_RD( dma, inst, rw_cfg );\
+        c.stop = regk_dma_no; \
+        REG_WR( dma, inst, rw_cfg, c); } while( 0 )
+
+// give stream command
+#define DMA_WR_CMD( inst, cmd_par ) \
+   do { reg_dma_rw_stream_cmd r = {0}; \
+        do { r = REG_RD( dma, inst, rw_stream_cmd ); } while( r.busy ); \
+        r.cmd = (cmd_par); \
+        REG_WR( dma, inst, rw_stream_cmd, r ); \
+      } while( 0 )
+
+// load: g,c,d:burst
+#define DMA_START_GROUP( inst, group_descr ) \
+   do { REG_WR_INT( dma, inst, rw_group, (int) group_descr ); \
+        DMA_WR_CMD( inst, regk_dma_load_g ); \
+        DMA_WR_CMD( inst, regk_dma_load_c ); \
+        DMA_WR_CMD( inst, regk_dma_load_d | regk_dma_burst ); \
+      } while( 0 )
+
+// load: c,d:burst
+#define DMA_START_CONTEXT( inst, ctx_descr ) \
+   do { REG_WR_INT( dma, inst, rw_group_down, (int) ctx_descr ); \
+        DMA_WR_CMD( inst, regk_dma_load_c ); \
+        DMA_WR_CMD( inst, regk_dma_load_d | regk_dma_burst ); \
+      } while( 0 )
+
+// if the DMA is at the end of the data list, the last data descr is reloaded
+#define DMA_CONTINUE_DATA( inst ) \
+do { reg_dma_rw_cmd c = {0}; \
+     c.cont_data = regk_dma_yes;\
+     REG_WR( dma, inst, rw_cmd, c ); } while( 0 )
+
+#endif
diff --git a/include/asm-cris/arch-v32/hwregs/dma_defs.h b/include/asm-cris/arch-v32/hwregs/dma_defs.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/dma_defs.h
@@ -0,0 +1,436 @@
+#ifndef __dma_defs_h
+#define __dma_defs_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/dma/inst/dma_common/rtl/dma_regdes.r
+ *     id:           dma_regdes.r,v 1.39 2005/02/10 14:07:23 janb Exp
+ *     last modfied: Mon Apr 11 16:06:51 2005
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c --outfile dma_defs.h ../../inst/dma/inst/dma_common/rtl/dma_regdes.r
+ *      id: $Id: dma_defs.h,v 1.7 2005/04/24 18:30:58 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+/* Main access macros */
+#ifndef REG_RD
+#define REG_RD( scope, inst, reg ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR
+#define REG_WR( scope, inst, reg, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_VECT
+#define REG_RD_VECT( scope, inst, reg, index ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_VECT
+#define REG_WR_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT
+#define REG_RD_INT( scope, inst, reg ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT
+#define REG_WR_INT( scope, inst, reg, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT_VECT
+#define REG_RD_INT_VECT( scope, inst, reg, index ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT_VECT
+#define REG_WR_INT_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_TYPE_CONV
+#define REG_TYPE_CONV( type, orgtype, val ) \
+  ( { union { orgtype o; type n; } r; r.o = val; r.n; } )
+#endif
+
+#ifndef reg_page_size
+#define reg_page_size 8192
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg + \
+    (index) * STRIDE_##scope##_##reg )
+#endif
+
+/* C-code for register scope dma */
+
+/* Register rw_data, scope dma, type rw */
+typedef unsigned int reg_dma_rw_data;
+#define REG_RD_ADDR_dma_rw_data 0
+#define REG_WR_ADDR_dma_rw_data 0
+
+/* Register rw_data_next, scope dma, type rw */
+typedef unsigned int reg_dma_rw_data_next;
+#define REG_RD_ADDR_dma_rw_data_next 4
+#define REG_WR_ADDR_dma_rw_data_next 4
+
+/* Register rw_data_buf, scope dma, type rw */
+typedef unsigned int reg_dma_rw_data_buf;
+#define REG_RD_ADDR_dma_rw_data_buf 8
+#define REG_WR_ADDR_dma_rw_data_buf 8
+
+/* Register rw_data_ctrl, scope dma, type rw */
+typedef struct {
+  unsigned int eol     : 1;
+  unsigned int dummy1  : 2;
+  unsigned int out_eop : 1;
+  unsigned int intr    : 1;
+  unsigned int wait    : 1;
+  unsigned int dummy2  : 26;
+} reg_dma_rw_data_ctrl;
+#define REG_RD_ADDR_dma_rw_data_ctrl 12
+#define REG_WR_ADDR_dma_rw_data_ctrl 12
+
+/* Register rw_data_stat, scope dma, type rw */
+typedef struct {
+  unsigned int dummy1 : 3;
+  unsigned int in_eop : 1;
+  unsigned int dummy2 : 28;
+} reg_dma_rw_data_stat;
+#define REG_RD_ADDR_dma_rw_data_stat 16
+#define REG_WR_ADDR_dma_rw_data_stat 16
+
+/* Register rw_data_md, scope dma, type rw */
+typedef struct {
+  unsigned int md : 16;
+  unsigned int dummy1 : 16;
+} reg_dma_rw_data_md;
+#define REG_RD_ADDR_dma_rw_data_md 20
+#define REG_WR_ADDR_dma_rw_data_md 20
+
+/* Register rw_data_md_s, scope dma, type rw */
+typedef struct {
+  unsigned int md_s : 16;
+  unsigned int dummy1 : 16;
+} reg_dma_rw_data_md_s;
+#define REG_RD_ADDR_dma_rw_data_md_s 24
+#define REG_WR_ADDR_dma_rw_data_md_s 24
+
+/* Register rw_data_after, scope dma, type rw */
+typedef unsigned int reg_dma_rw_data_after;
+#define REG_RD_ADDR_dma_rw_data_after 28
+#define REG_WR_ADDR_dma_rw_data_after 28
+
+/* Register rw_ctxt, scope dma, type rw */
+typedef unsigned int reg_dma_rw_ctxt;
+#define REG_RD_ADDR_dma_rw_ctxt 32
+#define REG_WR_ADDR_dma_rw_ctxt 32
+
+/* Register rw_ctxt_next, scope dma, type rw */
+typedef unsigned int reg_dma_rw_ctxt_next;
+#define REG_RD_ADDR_dma_rw_ctxt_next 36
+#define REG_WR_ADDR_dma_rw_ctxt_next 36
+
+/* Register rw_ctxt_ctrl, scope dma, type rw */
+typedef struct {
+  unsigned int eol        : 1;
+  unsigned int dummy1     : 3;
+  unsigned int intr       : 1;
+  unsigned int dummy2     : 1;
+  unsigned int store_mode : 1;
+  unsigned int en         : 1;
+  unsigned int dummy3     : 24;
+} reg_dma_rw_ctxt_ctrl;
+#define REG_RD_ADDR_dma_rw_ctxt_ctrl 40
+#define REG_WR_ADDR_dma_rw_ctxt_ctrl 40
+
+/* Register rw_ctxt_stat, scope dma, type rw */
+typedef struct {
+  unsigned int dummy1 : 7;
+  unsigned int dis : 1;
+  unsigned int dummy2 : 24;
+} reg_dma_rw_ctxt_stat;
+#define REG_RD_ADDR_dma_rw_ctxt_stat 44
+#define REG_WR_ADDR_dma_rw_ctxt_stat 44
+
+/* Register rw_ctxt_md0, scope dma, type rw */
+typedef struct {
+  unsigned int md0 : 16;
+  unsigned int dummy1 : 16;
+} reg_dma_rw_ctxt_md0;
+#define REG_RD_ADDR_dma_rw_ctxt_md0 48
+#define REG_WR_ADDR_dma_rw_ctxt_md0 48
+
+/* Register rw_ctxt_md0_s, scope dma, type rw */
+typedef struct {
+  unsigned int md0_s : 16;
+  unsigned int dummy1 : 16;
+} reg_dma_rw_ctxt_md0_s;
+#define REG_RD_ADDR_dma_rw_ctxt_md0_s 52
+#define REG_WR_ADDR_dma_rw_ctxt_md0_s 52
+
+/* Register rw_ctxt_md1, scope dma, type rw */
+typedef unsigned int reg_dma_rw_ctxt_md1;
+#define REG_RD_ADDR_dma_rw_ctxt_md1 56
+#define REG_WR_ADDR_dma_rw_ctxt_md1 56
+
+/* Register rw_ctxt_md1_s, scope dma, type rw */
+typedef unsigned int reg_dma_rw_ctxt_md1_s;
+#define REG_RD_ADDR_dma_rw_ctxt_md1_s 60
+#define REG_WR_ADDR_dma_rw_ctxt_md1_s 60
+
+/* Register rw_ctxt_md2, scope dma, type rw */
+typedef unsigned int reg_dma_rw_ctxt_md2;
+#define REG_RD_ADDR_dma_rw_ctxt_md2 64
+#define REG_WR_ADDR_dma_rw_ctxt_md2 64
+
+/* Register rw_ctxt_md2_s, scope dma, type rw */
+typedef unsigned int reg_dma_rw_ctxt_md2_s;
+#define REG_RD_ADDR_dma_rw_ctxt_md2_s 68
+#define REG_WR_ADDR_dma_rw_ctxt_md2_s 68
+
+/* Register rw_ctxt_md3, scope dma, type rw */
+typedef unsigned int reg_dma_rw_ctxt_md3;
+#define REG_RD_ADDR_dma_rw_ctxt_md3 72
+#define REG_WR_ADDR_dma_rw_ctxt_md3 72
+
+/* Register rw_ctxt_md3_s, scope dma, type rw */
+typedef unsigned int reg_dma_rw_ctxt_md3_s;
+#define REG_RD_ADDR_dma_rw_ctxt_md3_s 76
+#define REG_WR_ADDR_dma_rw_ctxt_md3_s 76
+
+/* Register rw_ctxt_md4, scope dma, type rw */
+typedef unsigned int reg_dma_rw_ctxt_md4;
+#define REG_RD_ADDR_dma_rw_ctxt_md4 80
+#define REG_WR_ADDR_dma_rw_ctxt_md4 80
+
+/* Register rw_ctxt_md4_s, scope dma, type rw */
+typedef unsigned int reg_dma_rw_ctxt_md4_s;
+#define REG_RD_ADDR_dma_rw_ctxt_md4_s 84
+#define REG_WR_ADDR_dma_rw_ctxt_md4_s 84
+
+/* Register rw_saved_data, scope dma, type rw */
+typedef unsigned int reg_dma_rw_saved_data;
+#define REG_RD_ADDR_dma_rw_saved_data 88
+#define REG_WR_ADDR_dma_rw_saved_data 88
+
+/* Register rw_saved_data_buf, scope dma, type rw */
+typedef unsigned int reg_dma_rw_saved_data_buf;
+#define REG_RD_ADDR_dma_rw_saved_data_buf 92
+#define REG_WR_ADDR_dma_rw_saved_data_buf 92
+
+/* Register rw_group, scope dma, type rw */
+typedef unsigned int reg_dma_rw_group;
+#define REG_RD_ADDR_dma_rw_group 96
+#define REG_WR_ADDR_dma_rw_group 96
+
+/* Register rw_group_next, scope dma, type rw */
+typedef unsigned int reg_dma_rw_group_next;
+#define REG_RD_ADDR_dma_rw_group_next 100
+#define REG_WR_ADDR_dma_rw_group_next 100
+
+/* Register rw_group_ctrl, scope dma, type rw */
+typedef struct {
+  unsigned int eol  : 1;
+  unsigned int tol  : 1;
+  unsigned int bol  : 1;
+  unsigned int dummy1 : 1;
+  unsigned int intr : 1;
+  unsigned int dummy2 : 2;
+  unsigned int en   : 1;
+  unsigned int dummy3 : 24;
+} reg_dma_rw_group_ctrl;
+#define REG_RD_ADDR_dma_rw_group_ctrl 104
+#define REG_WR_ADDR_dma_rw_group_ctrl 104
+
+/* Register rw_group_stat, scope dma, type rw */
+typedef struct {
+  unsigned int dummy1 : 7;
+  unsigned int dis : 1;
+  unsigned int dummy2 : 24;
+} reg_dma_rw_group_stat;
+#define REG_RD_ADDR_dma_rw_group_stat 108
+#define REG_WR_ADDR_dma_rw_group_stat 108
+
+/* Register rw_group_md, scope dma, type rw */
+typedef struct {
+  unsigned int md : 16;
+  unsigned int dummy1 : 16;
+} reg_dma_rw_group_md;
+#define REG_RD_ADDR_dma_rw_group_md 112
+#define REG_WR_ADDR_dma_rw_group_md 112
+
+/* Register rw_group_md_s, scope dma, type rw */
+typedef struct {
+  unsigned int md_s : 16;
+  unsigned int dummy1 : 16;
+} reg_dma_rw_group_md_s;
+#define REG_RD_ADDR_dma_rw_group_md_s 116
+#define REG_WR_ADDR_dma_rw_group_md_s 116
+
+/* Register rw_group_up, scope dma, type rw */
+typedef unsigned int reg_dma_rw_group_up;
+#define REG_RD_ADDR_dma_rw_group_up 120
+#define REG_WR_ADDR_dma_rw_group_up 120
+
+/* Register rw_group_down, scope dma, type rw */
+typedef unsigned int reg_dma_rw_group_down;
+#define REG_RD_ADDR_dma_rw_group_down 124
+#define REG_WR_ADDR_dma_rw_group_down 124
+
+/* Register rw_cmd, scope dma, type rw */
+typedef struct {
+  unsigned int cont_data : 1;
+  unsigned int dummy1    : 31;
+} reg_dma_rw_cmd;
+#define REG_RD_ADDR_dma_rw_cmd 128
+#define REG_WR_ADDR_dma_rw_cmd 128
+
+/* Register rw_cfg, scope dma, type rw */
+typedef struct {
+  unsigned int en   : 1;
+  unsigned int stop : 1;
+  unsigned int dummy1 : 30;
+} reg_dma_rw_cfg;
+#define REG_RD_ADDR_dma_rw_cfg 132
+#define REG_WR_ADDR_dma_rw_cfg 132
+
+/* Register rw_stat, scope dma, type rw */
+typedef struct {
+  unsigned int mode           : 5;
+  unsigned int list_state     : 3;
+  unsigned int stream_cmd_src : 8;
+  unsigned int dummy1         : 8;
+  unsigned int buf            : 8;
+} reg_dma_rw_stat;
+#define REG_RD_ADDR_dma_rw_stat 136
+#define REG_WR_ADDR_dma_rw_stat 136
+
+/* Register rw_intr_mask, scope dma, type rw */
+typedef struct {
+  unsigned int group      : 1;
+  unsigned int ctxt       : 1;
+  unsigned int data       : 1;
+  unsigned int in_eop     : 1;
+  unsigned int stream_cmd : 1;
+  unsigned int dummy1     : 27;
+} reg_dma_rw_intr_mask;
+#define REG_RD_ADDR_dma_rw_intr_mask 140
+#define REG_WR_ADDR_dma_rw_intr_mask 140
+
+/* Register rw_ack_intr, scope dma, type rw */
+typedef struct {
+  unsigned int group      : 1;
+  unsigned int ctxt       : 1;
+  unsigned int data       : 1;
+  unsigned int in_eop     : 1;
+  unsigned int stream_cmd : 1;
+  unsigned int dummy1     : 27;
+} reg_dma_rw_ack_intr;
+#define REG_RD_ADDR_dma_rw_ack_intr 144
+#define REG_WR_ADDR_dma_rw_ack_intr 144
+
+/* Register r_intr, scope dma, type r */
+typedef struct {
+  unsigned int group      : 1;
+  unsigned int ctxt       : 1;
+  unsigned int data       : 1;
+  unsigned int in_eop     : 1;
+  unsigned int stream_cmd : 1;
+  unsigned int dummy1     : 27;
+} reg_dma_r_intr;
+#define REG_RD_ADDR_dma_r_intr 148
+
+/* Register r_masked_intr, scope dma, type r */
+typedef struct {
+  unsigned int group      : 1;
+  unsigned int ctxt       : 1;
+  unsigned int data       : 1;
+  unsigned int in_eop     : 1;
+  unsigned int stream_cmd : 1;
+  unsigned int dummy1     : 27;
+} reg_dma_r_masked_intr;
+#define REG_RD_ADDR_dma_r_masked_intr 152
+
+/* Register rw_stream_cmd, scope dma, type rw */
+typedef struct {
+  unsigned int cmd  : 10;
+  unsigned int dummy1 : 6;
+  unsigned int n    : 8;
+  unsigned int dummy2 : 7;
+  unsigned int busy : 1;
+} reg_dma_rw_stream_cmd;
+#define REG_RD_ADDR_dma_rw_stream_cmd 156
+#define REG_WR_ADDR_dma_rw_stream_cmd 156
+
+
+/* Constants */
+enum {
+  regk_dma_ack_pkt                         = 0x00000100,
+  regk_dma_anytime                         = 0x00000001,
+  regk_dma_array                           = 0x00000008,
+  regk_dma_burst                           = 0x00000020,
+  regk_dma_client                          = 0x00000002,
+  regk_dma_copy_next                       = 0x00000010,
+  regk_dma_copy_up                         = 0x00000020,
+  regk_dma_data_at_eol                     = 0x00000001,
+  regk_dma_dis_c                           = 0x00000010,
+  regk_dma_dis_g                           = 0x00000020,
+  regk_dma_idle                            = 0x00000001,
+  regk_dma_intern                          = 0x00000004,
+  regk_dma_load_c                          = 0x00000200,
+  regk_dma_load_c_n                        = 0x00000280,
+  regk_dma_load_c_next                     = 0x00000240,
+  regk_dma_load_d                          = 0x00000140,
+  regk_dma_load_g                          = 0x00000300,
+  regk_dma_load_g_down                     = 0x000003c0,
+  regk_dma_load_g_next                     = 0x00000340,
+  regk_dma_load_g_up                       = 0x00000380,
+  regk_dma_next_en                         = 0x00000010,
+  regk_dma_next_pkt                        = 0x00000010,
+  regk_dma_no                              = 0x00000000,
+  regk_dma_only_at_wait                    = 0x00000000,
+  regk_dma_restore                         = 0x00000020,
+  regk_dma_rst                             = 0x00000001,
+  regk_dma_running                         = 0x00000004,
+  regk_dma_rw_cfg_default                  = 0x00000000,
+  regk_dma_rw_cmd_default                  = 0x00000000,
+  regk_dma_rw_intr_mask_default            = 0x00000000,
+  regk_dma_rw_stat_default                 = 0x00000101,
+  regk_dma_rw_stream_cmd_default           = 0x00000000,
+  regk_dma_save_down                       = 0x00000020,
+  regk_dma_save_up                         = 0x00000020,
+  regk_dma_set_reg                         = 0x00000050,
+  regk_dma_set_w_size1                     = 0x00000190,
+  regk_dma_set_w_size2                     = 0x000001a0,
+  regk_dma_set_w_size4                     = 0x000001c0,
+  regk_dma_stopped                         = 0x00000002,
+  regk_dma_store_c                         = 0x00000002,
+  regk_dma_store_descr                     = 0x00000000,
+  regk_dma_store_g                         = 0x00000004,
+  regk_dma_store_md                        = 0x00000001,
+  regk_dma_sw                              = 0x00000008,
+  regk_dma_update_down                     = 0x00000020,
+  regk_dma_yes                             = 0x00000001
+};
+#endif /* __dma_defs_h */
diff --git a/include/asm-cris/arch-v32/hwregs/eth_defs.h b/include/asm-cris/arch-v32/hwregs/eth_defs.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/eth_defs.h
@@ -0,0 +1,384 @@
+#ifndef __eth_defs_h
+#define __eth_defs_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/eth/rtl/eth_regs.r
+ *     id:           eth_regs.r,v 1.11 2005/02/09 10:48:38 kriskn Exp
+ *     last modfied: Mon Apr 11 16:07:03 2005
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c --outfile eth_defs.h ../../inst/eth/rtl/eth_regs.r
+ *      id: $Id: eth_defs.h,v 1.6 2005/04/24 18:30:58 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+/* Main access macros */
+#ifndef REG_RD
+#define REG_RD( scope, inst, reg ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR
+#define REG_WR( scope, inst, reg, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_VECT
+#define REG_RD_VECT( scope, inst, reg, index ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_VECT
+#define REG_WR_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT
+#define REG_RD_INT( scope, inst, reg ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT
+#define REG_WR_INT( scope, inst, reg, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT_VECT
+#define REG_RD_INT_VECT( scope, inst, reg, index ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT_VECT
+#define REG_WR_INT_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_TYPE_CONV
+#define REG_TYPE_CONV( type, orgtype, val ) \
+  ( { union { orgtype o; type n; } r; r.o = val; r.n; } )
+#endif
+
+#ifndef reg_page_size
+#define reg_page_size 8192
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg + \
+    (index) * STRIDE_##scope##_##reg )
+#endif
+
+/* C-code for register scope eth */
+
+/* Register rw_ma0_lo, scope eth, type rw */
+typedef struct {
+  unsigned int addr : 32;
+} reg_eth_rw_ma0_lo;
+#define REG_RD_ADDR_eth_rw_ma0_lo 0
+#define REG_WR_ADDR_eth_rw_ma0_lo 0
+
+/* Register rw_ma0_hi, scope eth, type rw */
+typedef struct {
+  unsigned int addr : 16;
+  unsigned int dummy1 : 16;
+} reg_eth_rw_ma0_hi;
+#define REG_RD_ADDR_eth_rw_ma0_hi 4
+#define REG_WR_ADDR_eth_rw_ma0_hi 4
+
+/* Register rw_ma1_lo, scope eth, type rw */
+typedef struct {
+  unsigned int addr : 32;
+} reg_eth_rw_ma1_lo;
+#define REG_RD_ADDR_eth_rw_ma1_lo 8
+#define REG_WR_ADDR_eth_rw_ma1_lo 8
+
+/* Register rw_ma1_hi, scope eth, type rw */
+typedef struct {
+  unsigned int addr : 16;
+  unsigned int dummy1 : 16;
+} reg_eth_rw_ma1_hi;
+#define REG_RD_ADDR_eth_rw_ma1_hi 12
+#define REG_WR_ADDR_eth_rw_ma1_hi 12
+
+/* Register rw_ga_lo, scope eth, type rw */
+typedef struct {
+  unsigned int table : 32;
+} reg_eth_rw_ga_lo;
+#define REG_RD_ADDR_eth_rw_ga_lo 16
+#define REG_WR_ADDR_eth_rw_ga_lo 16
+
+/* Register rw_ga_hi, scope eth, type rw */
+typedef struct {
+  unsigned int table : 32;
+} reg_eth_rw_ga_hi;
+#define REG_RD_ADDR_eth_rw_ga_hi 20
+#define REG_WR_ADDR_eth_rw_ga_hi 20
+
+/* Register rw_gen_ctrl, scope eth, type rw */
+typedef struct {
+  unsigned int en            : 1;
+  unsigned int phy           : 2;
+  unsigned int protocol      : 1;
+  unsigned int loopback      : 1;
+  unsigned int flow_ctrl_dis : 1;
+  unsigned int dummy1        : 26;
+} reg_eth_rw_gen_ctrl;
+#define REG_RD_ADDR_eth_rw_gen_ctrl 24
+#define REG_WR_ADDR_eth_rw_gen_ctrl 24
+
+/* Register rw_rec_ctrl, scope eth, type rw */
+typedef struct {
+  unsigned int ma0        : 1;
+  unsigned int ma1        : 1;
+  unsigned int individual : 1;
+  unsigned int broadcast  : 1;
+  unsigned int undersize  : 1;
+  unsigned int oversize   : 1;
+  unsigned int bad_crc    : 1;
+  unsigned int duplex     : 1;
+  unsigned int max_size   : 1;
+  unsigned int dummy1     : 23;
+} reg_eth_rw_rec_ctrl;
+#define REG_RD_ADDR_eth_rw_rec_ctrl 28
+#define REG_WR_ADDR_eth_rw_rec_ctrl 28
+
+/* Register rw_tr_ctrl, scope eth, type rw */
+typedef struct {
+  unsigned int crc        : 1;
+  unsigned int pad        : 1;
+  unsigned int retry      : 1;
+  unsigned int ignore_col : 1;
+  unsigned int cancel     : 1;
+  unsigned int hsh_delay  : 1;
+  unsigned int ignore_crs : 1;
+  unsigned int dummy1     : 25;
+} reg_eth_rw_tr_ctrl;
+#define REG_RD_ADDR_eth_rw_tr_ctrl 32
+#define REG_WR_ADDR_eth_rw_tr_ctrl 32
+
+/* Register rw_clr_err, scope eth, type rw */
+typedef struct {
+  unsigned int clr : 1;
+  unsigned int dummy1 : 31;
+} reg_eth_rw_clr_err;
+#define REG_RD_ADDR_eth_rw_clr_err 36
+#define REG_WR_ADDR_eth_rw_clr_err 36
+
+/* Register rw_mgm_ctrl, scope eth, type rw */
+typedef struct {
+  unsigned int mdio   : 1;
+  unsigned int mdoe   : 1;
+  unsigned int mdc    : 1;
+  unsigned int phyclk : 1;
+  unsigned int txdata : 4;
+  unsigned int txen   : 1;
+  unsigned int dummy1 : 23;
+} reg_eth_rw_mgm_ctrl;
+#define REG_RD_ADDR_eth_rw_mgm_ctrl 40
+#define REG_WR_ADDR_eth_rw_mgm_ctrl 40
+
+/* Register r_stat, scope eth, type r */
+typedef struct {
+  unsigned int mdio    : 1;
+  unsigned int exc_col : 1;
+  unsigned int urun    : 1;
+  unsigned int phyclk  : 1;
+  unsigned int txdata  : 4;
+  unsigned int txen    : 1;
+  unsigned int col     : 1;
+  unsigned int crs     : 1;
+  unsigned int txclk   : 1;
+  unsigned int rxdata  : 4;
+  unsigned int rxer    : 1;
+  unsigned int rxdv    : 1;
+  unsigned int rxclk   : 1;
+  unsigned int dummy1  : 13;
+} reg_eth_r_stat;
+#define REG_RD_ADDR_eth_r_stat 44
+
+/* Register rs_rec_cnt, scope eth, type rs */
+typedef struct {
+  unsigned int crc_err    : 8;
+  unsigned int align_err  : 8;
+  unsigned int oversize   : 8;
+  unsigned int congestion : 8;
+} reg_eth_rs_rec_cnt;
+#define REG_RD_ADDR_eth_rs_rec_cnt 48
+
+/* Register r_rec_cnt, scope eth, type r */
+typedef struct {
+  unsigned int crc_err    : 8;
+  unsigned int align_err  : 8;
+  unsigned int oversize   : 8;
+  unsigned int congestion : 8;
+} reg_eth_r_rec_cnt;
+#define REG_RD_ADDR_eth_r_rec_cnt 52
+
+/* Register rs_tr_cnt, scope eth, type rs */
+typedef struct {
+  unsigned int single_col : 8;
+  unsigned int mult_col   : 8;
+  unsigned int late_col   : 8;
+  unsigned int deferred   : 8;
+} reg_eth_rs_tr_cnt;
+#define REG_RD_ADDR_eth_rs_tr_cnt 56
+
+/* Register r_tr_cnt, scope eth, type r */
+typedef struct {
+  unsigned int single_col : 8;
+  unsigned int mult_col   : 8;
+  unsigned int late_col   : 8;
+  unsigned int deferred   : 8;
+} reg_eth_r_tr_cnt;
+#define REG_RD_ADDR_eth_r_tr_cnt 60
+
+/* Register rs_phy_cnt, scope eth, type rs */
+typedef struct {
+  unsigned int carrier_loss : 8;
+  unsigned int sqe_err      : 8;
+  unsigned int dummy1       : 16;
+} reg_eth_rs_phy_cnt;
+#define REG_RD_ADDR_eth_rs_phy_cnt 64
+
+/* Register r_phy_cnt, scope eth, type r */
+typedef struct {
+  unsigned int carrier_loss : 8;
+  unsigned int sqe_err      : 8;
+  unsigned int dummy1       : 16;
+} reg_eth_r_phy_cnt;
+#define REG_RD_ADDR_eth_r_phy_cnt 68
+
+/* Register rw_test_ctrl, scope eth, type rw */
+typedef struct {
+  unsigned int snmp_inc : 1;
+  unsigned int snmp     : 1;
+  unsigned int backoff  : 1;
+  unsigned int dummy1   : 29;
+} reg_eth_rw_test_ctrl;
+#define REG_RD_ADDR_eth_rw_test_ctrl 72
+#define REG_WR_ADDR_eth_rw_test_ctrl 72
+
+/* Register rw_intr_mask, scope eth, type rw */
+typedef struct {
+  unsigned int crc           : 1;
+  unsigned int align         : 1;
+  unsigned int oversize      : 1;
+  unsigned int congestion    : 1;
+  unsigned int single_col    : 1;
+  unsigned int mult_col      : 1;
+  unsigned int late_col      : 1;
+  unsigned int deferred      : 1;
+  unsigned int carrier_loss  : 1;
+  unsigned int sqe_test_err  : 1;
+  unsigned int orun          : 1;
+  unsigned int urun          : 1;
+  unsigned int excessive_col : 1;
+  unsigned int mdio          : 1;
+  unsigned int dummy1        : 18;
+} reg_eth_rw_intr_mask;
+#define REG_RD_ADDR_eth_rw_intr_mask 76
+#define REG_WR_ADDR_eth_rw_intr_mask 76
+
+/* Register rw_ack_intr, scope eth, type rw */
+typedef struct {
+  unsigned int crc           : 1;
+  unsigned int align         : 1;
+  unsigned int oversize      : 1;
+  unsigned int congestion    : 1;
+  unsigned int single_col    : 1;
+  unsigned int mult_col      : 1;
+  unsigned int late_col      : 1;
+  unsigned int deferred      : 1;
+  unsigned int carrier_loss  : 1;
+  unsigned int sqe_test_err  : 1;
+  unsigned int orun          : 1;
+  unsigned int urun          : 1;
+  unsigned int excessive_col : 1;
+  unsigned int mdio          : 1;
+  unsigned int dummy1        : 18;
+} reg_eth_rw_ack_intr;
+#define REG_RD_ADDR_eth_rw_ack_intr 80
+#define REG_WR_ADDR_eth_rw_ack_intr 80
+
+/* Register r_intr, scope eth, type r */
+typedef struct {
+  unsigned int crc           : 1;
+  unsigned int align         : 1;
+  unsigned int oversize      : 1;
+  unsigned int congestion    : 1;
+  unsigned int single_col    : 1;
+  unsigned int mult_col      : 1;
+  unsigned int late_col      : 1;
+  unsigned int deferred      : 1;
+  unsigned int carrier_loss  : 1;
+  unsigned int sqe_test_err  : 1;
+  unsigned int orun          : 1;
+  unsigned int urun          : 1;
+  unsigned int excessive_col : 1;
+  unsigned int mdio          : 1;
+  unsigned int dummy1        : 18;
+} reg_eth_r_intr;
+#define REG_RD_ADDR_eth_r_intr 84
+
+/* Register r_masked_intr, scope eth, type r */
+typedef struct {
+  unsigned int crc           : 1;
+  unsigned int align         : 1;
+  unsigned int oversize      : 1;
+  unsigned int congestion    : 1;
+  unsigned int single_col    : 1;
+  unsigned int mult_col      : 1;
+  unsigned int late_col      : 1;
+  unsigned int deferred      : 1;
+  unsigned int carrier_loss  : 1;
+  unsigned int sqe_test_err  : 1;
+  unsigned int orun          : 1;
+  unsigned int urun          : 1;
+  unsigned int excessive_col : 1;
+  unsigned int mdio          : 1;
+  unsigned int dummy1        : 18;
+} reg_eth_r_masked_intr;
+#define REG_RD_ADDR_eth_r_masked_intr 88
+
+
+/* Constants */
+enum {
+  regk_eth_discard                         = 0x00000000,
+  regk_eth_ether                           = 0x00000000,
+  regk_eth_full                            = 0x00000001,
+  regk_eth_half                            = 0x00000000,
+  regk_eth_hsh                             = 0x00000001,
+  regk_eth_mii                             = 0x00000001,
+  regk_eth_mii_clk                         = 0x00000000,
+  regk_eth_mii_rec                         = 0x00000002,
+  regk_eth_no                              = 0x00000000,
+  regk_eth_rec                             = 0x00000001,
+  regk_eth_rw_ga_hi_default                = 0x00000000,
+  regk_eth_rw_ga_lo_default                = 0x00000000,
+  regk_eth_rw_gen_ctrl_default             = 0x00000000,
+  regk_eth_rw_intr_mask_default            = 0x00000000,
+  regk_eth_rw_ma0_hi_default               = 0x00000000,
+  regk_eth_rw_ma0_lo_default               = 0x00000000,
+  regk_eth_rw_ma1_hi_default               = 0x00000000,
+  regk_eth_rw_ma1_lo_default               = 0x00000000,
+  regk_eth_rw_mgm_ctrl_default             = 0x00000000,
+  regk_eth_rw_test_ctrl_default            = 0x00000000,
+  regk_eth_size1518                        = 0x00000000,
+  regk_eth_size1522                        = 0x00000001,
+  regk_eth_yes                             = 0x00000001
+};
+#endif /* __eth_defs_h */
diff --git a/include/asm-cris/arch-v32/hwregs/extmem_defs.h b/include/asm-cris/arch-v32/hwregs/extmem_defs.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/extmem_defs.h
@@ -0,0 +1,369 @@
+#ifndef __extmem_defs_h
+#define __extmem_defs_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/ext_mem/mod/extmem_regs.r
+ *     id:           extmem_regs.r,v 1.1 2004/02/16 13:29:30 np Exp
+ *     last modfied: Tue Mar 30 22:26:21 2004
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c --outfile extmem_defs.h ../../inst/ext_mem/mod/extmem_regs.r
+ *      id: $Id: extmem_defs.h,v 1.5 2004/06/04 07:15:33 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+/* Main access macros */
+#ifndef REG_RD
+#define REG_RD( scope, inst, reg ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR
+#define REG_WR( scope, inst, reg, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_VECT
+#define REG_RD_VECT( scope, inst, reg, index ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_VECT
+#define REG_WR_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT
+#define REG_RD_INT( scope, inst, reg ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT
+#define REG_WR_INT( scope, inst, reg, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT_VECT
+#define REG_RD_INT_VECT( scope, inst, reg, index ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT_VECT
+#define REG_WR_INT_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_TYPE_CONV
+#define REG_TYPE_CONV( type, orgtype, val ) \
+  ( { union { orgtype o; type n; } r; r.o = val; r.n; } )
+#endif
+
+#ifndef reg_page_size
+#define reg_page_size 8192
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg + \
+    (index) * STRIDE_##scope##_##reg )
+#endif
+
+/* C-code for register scope extmem */
+
+/* Register rw_cse0_cfg, scope extmem, type rw */
+typedef struct {
+  unsigned int lw     : 6;
+  unsigned int ew     : 3;
+  unsigned int zw     : 3;
+  unsigned int aw     : 2;
+  unsigned int dw     : 2;
+  unsigned int ewb    : 2;
+  unsigned int bw     : 1;
+  unsigned int mode   : 1;
+  unsigned int erc_en : 1;
+  unsigned int dummy1 : 6;
+  unsigned int size   : 3;
+  unsigned int log    : 1;
+  unsigned int en     : 1;
+} reg_extmem_rw_cse0_cfg;
+#define REG_RD_ADDR_extmem_rw_cse0_cfg 0
+#define REG_WR_ADDR_extmem_rw_cse0_cfg 0
+
+/* Register rw_cse1_cfg, scope extmem, type rw */
+typedef struct {
+  unsigned int lw     : 6;
+  unsigned int ew     : 3;
+  unsigned int zw     : 3;
+  unsigned int aw     : 2;
+  unsigned int dw     : 2;
+  unsigned int ewb    : 2;
+  unsigned int bw     : 1;
+  unsigned int mode   : 1;
+  unsigned int erc_en : 1;
+  unsigned int dummy1 : 6;
+  unsigned int size   : 3;
+  unsigned int log    : 1;
+  unsigned int en     : 1;
+} reg_extmem_rw_cse1_cfg;
+#define REG_RD_ADDR_extmem_rw_cse1_cfg 4
+#define REG_WR_ADDR_extmem_rw_cse1_cfg 4
+
+/* Register rw_csr0_cfg, scope extmem, type rw */
+typedef struct {
+  unsigned int lw     : 6;
+  unsigned int ew     : 3;
+  unsigned int zw     : 3;
+  unsigned int aw     : 2;
+  unsigned int dw     : 2;
+  unsigned int ewb    : 2;
+  unsigned int bw     : 1;
+  unsigned int mode   : 1;
+  unsigned int erc_en : 1;
+  unsigned int dummy1 : 6;
+  unsigned int size   : 3;
+  unsigned int log    : 1;
+  unsigned int en     : 1;
+} reg_extmem_rw_csr0_cfg;
+#define REG_RD_ADDR_extmem_rw_csr0_cfg 8
+#define REG_WR_ADDR_extmem_rw_csr0_cfg 8
+
+/* Register rw_csr1_cfg, scope extmem, type rw */
+typedef struct {
+  unsigned int lw     : 6;
+  unsigned int ew     : 3;
+  unsigned int zw     : 3;
+  unsigned int aw     : 2;
+  unsigned int dw     : 2;
+  unsigned int ewb    : 2;
+  unsigned int bw     : 1;
+  unsigned int mode   : 1;
+  unsigned int erc_en : 1;
+  unsigned int dummy1 : 6;
+  unsigned int size   : 3;
+  unsigned int log    : 1;
+  unsigned int en     : 1;
+} reg_extmem_rw_csr1_cfg;
+#define REG_RD_ADDR_extmem_rw_csr1_cfg 12
+#define REG_WR_ADDR_extmem_rw_csr1_cfg 12
+
+/* Register rw_csp0_cfg, scope extmem, type rw */
+typedef struct {
+  unsigned int lw     : 6;
+  unsigned int ew     : 3;
+  unsigned int zw     : 3;
+  unsigned int aw     : 2;
+  unsigned int dw     : 2;
+  unsigned int ewb    : 2;
+  unsigned int bw     : 1;
+  unsigned int mode   : 1;
+  unsigned int erc_en : 1;
+  unsigned int dummy1 : 6;
+  unsigned int size   : 3;
+  unsigned int log    : 1;
+  unsigned int en     : 1;
+} reg_extmem_rw_csp0_cfg;
+#define REG_RD_ADDR_extmem_rw_csp0_cfg 16
+#define REG_WR_ADDR_extmem_rw_csp0_cfg 16
+
+/* Register rw_csp1_cfg, scope extmem, type rw */
+typedef struct {
+  unsigned int lw     : 6;
+  unsigned int ew     : 3;
+  unsigned int zw     : 3;
+  unsigned int aw     : 2;
+  unsigned int dw     : 2;
+  unsigned int ewb    : 2;
+  unsigned int bw     : 1;
+  unsigned int mode   : 1;
+  unsigned int erc_en : 1;
+  unsigned int dummy1 : 6;
+  unsigned int size   : 3;
+  unsigned int log    : 1;
+  unsigned int en     : 1;
+} reg_extmem_rw_csp1_cfg;
+#define REG_RD_ADDR_extmem_rw_csp1_cfg 20
+#define REG_WR_ADDR_extmem_rw_csp1_cfg 20
+
+/* Register rw_csp2_cfg, scope extmem, type rw */
+typedef struct {
+  unsigned int lw     : 6;
+  unsigned int ew     : 3;
+  unsigned int zw     : 3;
+  unsigned int aw     : 2;
+  unsigned int dw     : 2;
+  unsigned int ewb    : 2;
+  unsigned int bw     : 1;
+  unsigned int mode   : 1;
+  unsigned int erc_en : 1;
+  unsigned int dummy1 : 6;
+  unsigned int size   : 3;
+  unsigned int log    : 1;
+  unsigned int en     : 1;
+} reg_extmem_rw_csp2_cfg;
+#define REG_RD_ADDR_extmem_rw_csp2_cfg 24
+#define REG_WR_ADDR_extmem_rw_csp2_cfg 24
+
+/* Register rw_csp3_cfg, scope extmem, type rw */
+typedef struct {
+  unsigned int lw     : 6;
+  unsigned int ew     : 3;
+  unsigned int zw     : 3;
+  unsigned int aw     : 2;
+  unsigned int dw     : 2;
+  unsigned int ewb    : 2;
+  unsigned int bw     : 1;
+  unsigned int mode   : 1;
+  unsigned int erc_en : 1;
+  unsigned int dummy1 : 6;
+  unsigned int size   : 3;
+  unsigned int log    : 1;
+  unsigned int en     : 1;
+} reg_extmem_rw_csp3_cfg;
+#define REG_RD_ADDR_extmem_rw_csp3_cfg 28
+#define REG_WR_ADDR_extmem_rw_csp3_cfg 28
+
+/* Register rw_csp4_cfg, scope extmem, type rw */
+typedef struct {
+  unsigned int lw     : 6;
+  unsigned int ew     : 3;
+  unsigned int zw     : 3;
+  unsigned int aw     : 2;
+  unsigned int dw     : 2;
+  unsigned int ewb    : 2;
+  unsigned int bw     : 1;
+  unsigned int mode   : 1;
+  unsigned int erc_en : 1;
+  unsigned int dummy1 : 6;
+  unsigned int size   : 3;
+  unsigned int log    : 1;
+  unsigned int en     : 1;
+} reg_extmem_rw_csp4_cfg;
+#define REG_RD_ADDR_extmem_rw_csp4_cfg 32
+#define REG_WR_ADDR_extmem_rw_csp4_cfg 32
+
+/* Register rw_csp5_cfg, scope extmem, type rw */
+typedef struct {
+  unsigned int lw     : 6;
+  unsigned int ew     : 3;
+  unsigned int zw     : 3;
+  unsigned int aw     : 2;
+  unsigned int dw     : 2;
+  unsigned int ewb    : 2;
+  unsigned int bw     : 1;
+  unsigned int mode   : 1;
+  unsigned int erc_en : 1;
+  unsigned int dummy1 : 6;
+  unsigned int size   : 3;
+  unsigned int log    : 1;
+  unsigned int en     : 1;
+} reg_extmem_rw_csp5_cfg;
+#define REG_RD_ADDR_extmem_rw_csp5_cfg 36
+#define REG_WR_ADDR_extmem_rw_csp5_cfg 36
+
+/* Register rw_csp6_cfg, scope extmem, type rw */
+typedef struct {
+  unsigned int lw     : 6;
+  unsigned int ew     : 3;
+  unsigned int zw     : 3;
+  unsigned int aw     : 2;
+  unsigned int dw     : 2;
+  unsigned int ewb    : 2;
+  unsigned int bw     : 1;
+  unsigned int mode   : 1;
+  unsigned int erc_en : 1;
+  unsigned int dummy1 : 6;
+  unsigned int size   : 3;
+  unsigned int log    : 1;
+  unsigned int en     : 1;
+} reg_extmem_rw_csp6_cfg;
+#define REG_RD_ADDR_extmem_rw_csp6_cfg 40
+#define REG_WR_ADDR_extmem_rw_csp6_cfg 40
+
+/* Register rw_css_cfg, scope extmem, type rw */
+typedef struct {
+  unsigned int lw     : 6;
+  unsigned int ew     : 3;
+  unsigned int zw     : 3;
+  unsigned int aw     : 2;
+  unsigned int dw     : 2;
+  unsigned int ewb    : 2;
+  unsigned int bw     : 1;
+  unsigned int mode   : 1;
+  unsigned int erc_en : 1;
+  unsigned int dummy1 : 6;
+  unsigned int size   : 3;
+  unsigned int log    : 1;
+  unsigned int en     : 1;
+} reg_extmem_rw_css_cfg;
+#define REG_RD_ADDR_extmem_rw_css_cfg 44
+#define REG_WR_ADDR_extmem_rw_css_cfg 44
+
+/* Register rw_status_handle, scope extmem, type rw */
+typedef struct {
+  unsigned int h : 32;
+} reg_extmem_rw_status_handle;
+#define REG_RD_ADDR_extmem_rw_status_handle 48
+#define REG_WR_ADDR_extmem_rw_status_handle 48
+
+/* Register rw_wait_pin, scope extmem, type rw */
+typedef struct {
+  unsigned int val   : 16;
+  unsigned int dummy1 : 15;
+  unsigned int start : 1;
+} reg_extmem_rw_wait_pin;
+#define REG_RD_ADDR_extmem_rw_wait_pin 52
+#define REG_WR_ADDR_extmem_rw_wait_pin 52
+
+/* Register rw_gated_csp, scope extmem, type rw */
+typedef struct {
+  unsigned int dummy1 : 31;
+  unsigned int en : 1;
+} reg_extmem_rw_gated_csp;
+#define REG_RD_ADDR_extmem_rw_gated_csp 56
+#define REG_WR_ADDR_extmem_rw_gated_csp 56
+
+
+/* Constants */
+enum {
+  regk_extmem_b16                          = 0x00000001,
+  regk_extmem_b32                          = 0x00000000,
+  regk_extmem_bwe                          = 0x00000000,
+  regk_extmem_cwe                          = 0x00000001,
+  regk_extmem_no                           = 0x00000000,
+  regk_extmem_rw_cse0_cfg_default          = 0x000006cf,
+  regk_extmem_rw_cse1_cfg_default          = 0x000006cf,
+  regk_extmem_rw_csp0_cfg_default          = 0x000006cf,
+  regk_extmem_rw_csp1_cfg_default          = 0x000006cf,
+  regk_extmem_rw_csp2_cfg_default          = 0x000006cf,
+  regk_extmem_rw_csp3_cfg_default          = 0x000006cf,
+  regk_extmem_rw_csp4_cfg_default          = 0x000006cf,
+  regk_extmem_rw_csp5_cfg_default          = 0x000006cf,
+  regk_extmem_rw_csp6_cfg_default          = 0x000006cf,
+  regk_extmem_rw_csr0_cfg_default          = 0x000006cf,
+  regk_extmem_rw_csr1_cfg_default          = 0x000006cf,
+  regk_extmem_rw_css_cfg_default           = 0x000006cf,
+  regk_extmem_s128KB                       = 0x00000000,
+  regk_extmem_s16MB                        = 0x00000005,
+  regk_extmem_s1MB                         = 0x00000001,
+  regk_extmem_s2MB                         = 0x00000002,
+  regk_extmem_s32MB                        = 0x00000006,
+  regk_extmem_s4MB                         = 0x00000003,
+  regk_extmem_s64MB                        = 0x00000007,
+  regk_extmem_s8MB                         = 0x00000004,
+  regk_extmem_yes                          = 0x00000001
+};
+#endif /* __extmem_defs_h */
diff --git a/include/asm-cris/arch-v32/hwregs/gio_defs.h b/include/asm-cris/arch-v32/hwregs/gio_defs.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/gio_defs.h
@@ -0,0 +1,295 @@
+#ifndef __gio_defs_h
+#define __gio_defs_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/gio/rtl/gio_regs.r
+ *     id:           gio_regs.r,v 1.5 2005/02/04 09:43:21 perz Exp
+ *     last modfied: Mon Apr 11 16:07:47 2005
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c --outfile gio_defs.h ../../inst/gio/rtl/gio_regs.r
+ *      id: $Id: gio_defs.h,v 1.6 2005/04/24 18:30:58 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+/* Main access macros */
+#ifndef REG_RD
+#define REG_RD( scope, inst, reg ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR
+#define REG_WR( scope, inst, reg, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_VECT
+#define REG_RD_VECT( scope, inst, reg, index ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_VECT
+#define REG_WR_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT
+#define REG_RD_INT( scope, inst, reg ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT
+#define REG_WR_INT( scope, inst, reg, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT_VECT
+#define REG_RD_INT_VECT( scope, inst, reg, index ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT_VECT
+#define REG_WR_INT_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_TYPE_CONV
+#define REG_TYPE_CONV( type, orgtype, val ) \
+  ( { union { orgtype o; type n; } r; r.o = val; r.n; } )
+#endif
+
+#ifndef reg_page_size
+#define reg_page_size 8192
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg + \
+    (index) * STRIDE_##scope##_##reg )
+#endif
+
+/* C-code for register scope gio */
+
+/* Register rw_pa_dout, scope gio, type rw */
+typedef struct {
+  unsigned int data : 8;
+  unsigned int dummy1 : 24;
+} reg_gio_rw_pa_dout;
+#define REG_RD_ADDR_gio_rw_pa_dout 0
+#define REG_WR_ADDR_gio_rw_pa_dout 0
+
+/* Register r_pa_din, scope gio, type r */
+typedef struct {
+  unsigned int data : 8;
+  unsigned int dummy1 : 24;
+} reg_gio_r_pa_din;
+#define REG_RD_ADDR_gio_r_pa_din 4
+
+/* Register rw_pa_oe, scope gio, type rw */
+typedef struct {
+  unsigned int oe : 8;
+  unsigned int dummy1 : 24;
+} reg_gio_rw_pa_oe;
+#define REG_RD_ADDR_gio_rw_pa_oe 8
+#define REG_WR_ADDR_gio_rw_pa_oe 8
+
+/* Register rw_intr_cfg, scope gio, type rw */
+typedef struct {
+  unsigned int pa0 : 3;
+  unsigned int pa1 : 3;
+  unsigned int pa2 : 3;
+  unsigned int pa3 : 3;
+  unsigned int pa4 : 3;
+  unsigned int pa5 : 3;
+  unsigned int pa6 : 3;
+  unsigned int pa7 : 3;
+  unsigned int dummy1 : 8;
+} reg_gio_rw_intr_cfg;
+#define REG_RD_ADDR_gio_rw_intr_cfg 12
+#define REG_WR_ADDR_gio_rw_intr_cfg 12
+
+/* Register rw_intr_mask, scope gio, type rw */
+typedef struct {
+  unsigned int pa0 : 1;
+  unsigned int pa1 : 1;
+  unsigned int pa2 : 1;
+  unsigned int pa3 : 1;
+  unsigned int pa4 : 1;
+  unsigned int pa5 : 1;
+  unsigned int pa6 : 1;
+  unsigned int pa7 : 1;
+  unsigned int dummy1 : 24;
+} reg_gio_rw_intr_mask;
+#define REG_RD_ADDR_gio_rw_intr_mask 16
+#define REG_WR_ADDR_gio_rw_intr_mask 16
+
+/* Register rw_ack_intr, scope gio, type rw */
+typedef struct {
+  unsigned int pa0 : 1;
+  unsigned int pa1 : 1;
+  unsigned int pa2 : 1;
+  unsigned int pa3 : 1;
+  unsigned int pa4 : 1;
+  unsigned int pa5 : 1;
+  unsigned int pa6 : 1;
+  unsigned int pa7 : 1;
+  unsigned int dummy1 : 24;
+} reg_gio_rw_ack_intr;
+#define REG_RD_ADDR_gio_rw_ack_intr 20
+#define REG_WR_ADDR_gio_rw_ack_intr 20
+
+/* Register r_intr, scope gio, type r */
+typedef struct {
+  unsigned int pa0 : 1;
+  unsigned int pa1 : 1;
+  unsigned int pa2 : 1;
+  unsigned int pa3 : 1;
+  unsigned int pa4 : 1;
+  unsigned int pa5 : 1;
+  unsigned int pa6 : 1;
+  unsigned int pa7 : 1;
+  unsigned int dummy1 : 24;
+} reg_gio_r_intr;
+#define REG_RD_ADDR_gio_r_intr 24
+
+/* Register r_masked_intr, scope gio, type r */
+typedef struct {
+  unsigned int pa0 : 1;
+  unsigned int pa1 : 1;
+  unsigned int pa2 : 1;
+  unsigned int pa3 : 1;
+  unsigned int pa4 : 1;
+  unsigned int pa5 : 1;
+  unsigned int pa6 : 1;
+  unsigned int pa7 : 1;
+  unsigned int dummy1 : 24;
+} reg_gio_r_masked_intr;
+#define REG_RD_ADDR_gio_r_masked_intr 28
+
+/* Register rw_pb_dout, scope gio, type rw */
+typedef struct {
+  unsigned int data : 18;
+  unsigned int dummy1 : 14;
+} reg_gio_rw_pb_dout;
+#define REG_RD_ADDR_gio_rw_pb_dout 32
+#define REG_WR_ADDR_gio_rw_pb_dout 32
+
+/* Register r_pb_din, scope gio, type r */
+typedef struct {
+  unsigned int data : 18;
+  unsigned int dummy1 : 14;
+} reg_gio_r_pb_din;
+#define REG_RD_ADDR_gio_r_pb_din 36
+
+/* Register rw_pb_oe, scope gio, type rw */
+typedef struct {
+  unsigned int oe : 18;
+  unsigned int dummy1 : 14;
+} reg_gio_rw_pb_oe;
+#define REG_RD_ADDR_gio_rw_pb_oe 40
+#define REG_WR_ADDR_gio_rw_pb_oe 40
+
+/* Register rw_pc_dout, scope gio, type rw */
+typedef struct {
+  unsigned int data : 18;
+  unsigned int dummy1 : 14;
+} reg_gio_rw_pc_dout;
+#define REG_RD_ADDR_gio_rw_pc_dout 48
+#define REG_WR_ADDR_gio_rw_pc_dout 48
+
+/* Register r_pc_din, scope gio, type r */
+typedef struct {
+  unsigned int data : 18;
+  unsigned int dummy1 : 14;
+} reg_gio_r_pc_din;
+#define REG_RD_ADDR_gio_r_pc_din 52
+
+/* Register rw_pc_oe, scope gio, type rw */
+typedef struct {
+  unsigned int oe : 18;
+  unsigned int dummy1 : 14;
+} reg_gio_rw_pc_oe;
+#define REG_RD_ADDR_gio_rw_pc_oe 56
+#define REG_WR_ADDR_gio_rw_pc_oe 56
+
+/* Register rw_pd_dout, scope gio, type rw */
+typedef struct {
+  unsigned int data : 18;
+  unsigned int dummy1 : 14;
+} reg_gio_rw_pd_dout;
+#define REG_RD_ADDR_gio_rw_pd_dout 64
+#define REG_WR_ADDR_gio_rw_pd_dout 64
+
+/* Register r_pd_din, scope gio, type r */
+typedef struct {
+  unsigned int data : 18;
+  unsigned int dummy1 : 14;
+} reg_gio_r_pd_din;
+#define REG_RD_ADDR_gio_r_pd_din 68
+
+/* Register rw_pd_oe, scope gio, type rw */
+typedef struct {
+  unsigned int oe : 18;
+  unsigned int dummy1 : 14;
+} reg_gio_rw_pd_oe;
+#define REG_RD_ADDR_gio_rw_pd_oe 72
+#define REG_WR_ADDR_gio_rw_pd_oe 72
+
+/* Register rw_pe_dout, scope gio, type rw */
+typedef struct {
+  unsigned int data : 18;
+  unsigned int dummy1 : 14;
+} reg_gio_rw_pe_dout;
+#define REG_RD_ADDR_gio_rw_pe_dout 80
+#define REG_WR_ADDR_gio_rw_pe_dout 80
+
+/* Register r_pe_din, scope gio, type r */
+typedef struct {
+  unsigned int data : 18;
+  unsigned int dummy1 : 14;
+} reg_gio_r_pe_din;
+#define REG_RD_ADDR_gio_r_pe_din 84
+
+/* Register rw_pe_oe, scope gio, type rw */
+typedef struct {
+  unsigned int oe : 18;
+  unsigned int dummy1 : 14;
+} reg_gio_rw_pe_oe;
+#define REG_RD_ADDR_gio_rw_pe_oe 88
+#define REG_WR_ADDR_gio_rw_pe_oe 88
+
+
+/* Constants */
+enum {
+  regk_gio_anyedge                         = 0x00000007,
+  regk_gio_hi                              = 0x00000001,
+  regk_gio_lo                              = 0x00000002,
+  regk_gio_negedge                         = 0x00000006,
+  regk_gio_no                              = 0x00000000,
+  regk_gio_off                             = 0x00000000,
+  regk_gio_posedge                         = 0x00000005,
+  regk_gio_rw_intr_cfg_default             = 0x00000000,
+  regk_gio_rw_intr_mask_default            = 0x00000000,
+  regk_gio_rw_pa_oe_default                = 0x00000000,
+  regk_gio_rw_pb_oe_default                = 0x00000000,
+  regk_gio_rw_pc_oe_default                = 0x00000000,
+  regk_gio_rw_pd_oe_default                = 0x00000000,
+  regk_gio_rw_pe_oe_default                = 0x00000000,
+  regk_gio_set                             = 0x00000003,
+  regk_gio_yes                             = 0x00000001
+};
+#endif /* __gio_defs_h */
diff --git a/include/asm-cris/arch-v32/hwregs/intr_vect.h b/include/asm-cris/arch-v32/hwregs/intr_vect.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/intr_vect.h
@@ -0,0 +1,39 @@
+/* Interrupt vector numbers autogenerated by /n/asic/design/tools/rdesc/src/rdes2intr version
+ from ../../inst/intr_vect/rtl/guinness/ivmask.config.r
+version . */
+
+#ifndef _______INST_INTR_VECT_RTL_GUINNESS_IVMASK_CONFIG_R
+#define _______INST_INTR_VECT_RTL_GUINNESS_IVMASK_CONFIG_R
+#define MEMARB_INTR_VECT	0x31
+#define GEN_IO_INTR_VECT	0x32
+#define IOP0_INTR_VECT	0x33
+#define IOP1_INTR_VECT	0x34
+#define IOP2_INTR_VECT	0x35
+#define IOP3_INTR_VECT	0x36
+#define DMA0_INTR_VECT	0x37
+#define DMA1_INTR_VECT	0x38
+#define DMA2_INTR_VECT	0x39
+#define DMA3_INTR_VECT	0x3a
+#define DMA4_INTR_VECT	0x3b
+#define DMA5_INTR_VECT	0x3c
+#define DMA6_INTR_VECT	0x3d
+#define DMA7_INTR_VECT	0x3e
+#define DMA8_INTR_VECT	0x3f
+#define DMA9_INTR_VECT	0x40
+#define ATA_INTR_VECT	0x41
+#define SSER0_INTR_VECT	0x42
+#define SSER1_INTR_VECT	0x43
+#define SER0_INTR_VECT	0x44
+#define SER1_INTR_VECT	0x45
+#define SER2_INTR_VECT	0x46
+#define SER3_INTR_VECT	0x47
+#define P21_INTR_VECT	0x48
+#define ETH0_INTR_VECT	0x49
+#define ETH1_INTR_VECT	0x4a
+#define TIMER_INTR_VECT	0x4b
+#define BIF_ARB_INTR_VECT	0x4c
+#define BIF_DMA_INTR_VECT	0x4d
+#define EXT_INTR_VECT	0x4e
+#define IPI_INTR_VECT	0x4f
+
+#endif
diff --git a/include/asm-cris/arch-v32/hwregs/intr_vect_defs.h b/include/asm-cris/arch-v32/hwregs/intr_vect_defs.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/intr_vect_defs.h
@@ -0,0 +1,225 @@
+#ifndef __intr_vect_defs_h
+#define __intr_vect_defs_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/intr_vect/rtl/guinness/ivmask.config.r
+ *     id:           ivmask.config.r,v 1.4 2005/02/15 16:05:38 stefans Exp
+ *     last modfied: Mon Apr 11 16:08:03 2005
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c --outfile intr_vect_defs.h ../../inst/intr_vect/rtl/guinness/ivmask.config.r
+ *      id: $Id: intr_vect_defs.h,v 1.8 2005/04/24 18:30:58 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+/* Main access macros */
+#ifndef REG_RD
+#define REG_RD( scope, inst, reg ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR
+#define REG_WR( scope, inst, reg, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_VECT
+#define REG_RD_VECT( scope, inst, reg, index ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_VECT
+#define REG_WR_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT
+#define REG_RD_INT( scope, inst, reg ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT
+#define REG_WR_INT( scope, inst, reg, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT_VECT
+#define REG_RD_INT_VECT( scope, inst, reg, index ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT_VECT
+#define REG_WR_INT_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_TYPE_CONV
+#define REG_TYPE_CONV( type, orgtype, val ) \
+  ( { union { orgtype o; type n; } r; r.o = val; r.n; } )
+#endif
+
+#ifndef reg_page_size
+#define reg_page_size 8192
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg + \
+    (index) * STRIDE_##scope##_##reg )
+#endif
+
+/* C-code for register scope intr_vect */
+
+/* Register rw_mask, scope intr_vect, type rw */
+typedef struct {
+  unsigned int memarb  : 1;
+  unsigned int gen_io  : 1;
+  unsigned int iop0    : 1;
+  unsigned int iop1    : 1;
+  unsigned int iop2    : 1;
+  unsigned int iop3    : 1;
+  unsigned int dma0    : 1;
+  unsigned int dma1    : 1;
+  unsigned int dma2    : 1;
+  unsigned int dma3    : 1;
+  unsigned int dma4    : 1;
+  unsigned int dma5    : 1;
+  unsigned int dma6    : 1;
+  unsigned int dma7    : 1;
+  unsigned int dma8    : 1;
+  unsigned int dma9    : 1;
+  unsigned int ata     : 1;
+  unsigned int sser0   : 1;
+  unsigned int sser1   : 1;
+  unsigned int ser0    : 1;
+  unsigned int ser1    : 1;
+  unsigned int ser2    : 1;
+  unsigned int ser3    : 1;
+  unsigned int p21     : 1;
+  unsigned int eth0    : 1;
+  unsigned int eth1    : 1;
+  unsigned int timer   : 1;
+  unsigned int bif_arb : 1;
+  unsigned int bif_dma : 1;
+  unsigned int ext     : 1;
+  unsigned int dummy1  : 2;
+} reg_intr_vect_rw_mask;
+#define REG_RD_ADDR_intr_vect_rw_mask 0
+#define REG_WR_ADDR_intr_vect_rw_mask 0
+
+/* Register r_vect, scope intr_vect, type r */
+typedef struct {
+  unsigned int memarb  : 1;
+  unsigned int gen_io  : 1;
+  unsigned int iop0    : 1;
+  unsigned int iop1    : 1;
+  unsigned int iop2    : 1;
+  unsigned int iop3    : 1;
+  unsigned int dma0    : 1;
+  unsigned int dma1    : 1;
+  unsigned int dma2    : 1;
+  unsigned int dma3    : 1;
+  unsigned int dma4    : 1;
+  unsigned int dma5    : 1;
+  unsigned int dma6    : 1;
+  unsigned int dma7    : 1;
+  unsigned int dma8    : 1;
+  unsigned int dma9    : 1;
+  unsigned int ata     : 1;
+  unsigned int sser0   : 1;
+  unsigned int sser1   : 1;
+  unsigned int ser0    : 1;
+  unsigned int ser1    : 1;
+  unsigned int ser2    : 1;
+  unsigned int ser3    : 1;
+  unsigned int p21     : 1;
+  unsigned int eth0    : 1;
+  unsigned int eth1    : 1;
+  unsigned int timer   : 1;
+  unsigned int bif_arb : 1;
+  unsigned int bif_dma : 1;
+  unsigned int ext     : 1;
+  unsigned int dummy1  : 2;
+} reg_intr_vect_r_vect;
+#define REG_RD_ADDR_intr_vect_r_vect 4
+
+/* Register r_masked_vect, scope intr_vect, type r */
+typedef struct {
+  unsigned int memarb  : 1;
+  unsigned int gen_io  : 1;
+  unsigned int iop0    : 1;
+  unsigned int iop1    : 1;
+  unsigned int iop2    : 1;
+  unsigned int iop3    : 1;
+  unsigned int dma0    : 1;
+  unsigned int dma1    : 1;
+  unsigned int dma2    : 1;
+  unsigned int dma3    : 1;
+  unsigned int dma4    : 1;
+  unsigned int dma5    : 1;
+  unsigned int dma6    : 1;
+  unsigned int dma7    : 1;
+  unsigned int dma8    : 1;
+  unsigned int dma9    : 1;
+  unsigned int ata     : 1;
+  unsigned int sser0   : 1;
+  unsigned int sser1   : 1;
+  unsigned int ser0    : 1;
+  unsigned int ser1    : 1;
+  unsigned int ser2    : 1;
+  unsigned int ser3    : 1;
+  unsigned int p21     : 1;
+  unsigned int eth0    : 1;
+  unsigned int eth1    : 1;
+  unsigned int timer   : 1;
+  unsigned int bif_arb : 1;
+  unsigned int bif_dma : 1;
+  unsigned int ext     : 1;
+  unsigned int dummy1  : 2;
+} reg_intr_vect_r_masked_vect;
+#define REG_RD_ADDR_intr_vect_r_masked_vect 8
+
+/* Register r_nmi, scope intr_vect, type r */
+typedef struct {
+  unsigned int ext      : 1;
+  unsigned int watchdog : 1;
+  unsigned int dummy1   : 30;
+} reg_intr_vect_r_nmi;
+#define REG_RD_ADDR_intr_vect_r_nmi 12
+
+/* Register r_guru, scope intr_vect, type r */
+typedef struct {
+  unsigned int jtag : 1;
+  unsigned int dummy1 : 31;
+} reg_intr_vect_r_guru;
+#define REG_RD_ADDR_intr_vect_r_guru 16
+
+/* Register rw_ipi, scope intr_vect, type rw */
+typedef struct
+{
+  unsigned int vector;
+} reg_intr_vect_rw_ipi;
+#define REG_RD_ADDR_intr_vect_rw_ipi 20
+#define REG_WR_ADDR_intr_vect_rw_ipi 20
+
+/* Constants */
+enum {
+  regk_intr_vect_off                       = 0x00000000,
+  regk_intr_vect_on                        = 0x00000001,
+  regk_intr_vect_rw_mask_default           = 0x00000000
+};
+#endif /* __intr_vect_defs_h */
diff --git a/include/asm-cris/arch-v32/hwregs/iop/Makefile b/include/asm-cris/arch-v32/hwregs/iop/Makefile
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/iop/Makefile
@@ -0,0 +1,146 @@
+# $Id: Makefile,v 1.3 2004/01/07 20:34:55 johana Exp $
+# Makefile to generate or copy the latest register definitions
+# and related datastructures and helpermacros.
+# The offical place for these files is probably at:
+RELEASE ?= r1_alfa5
+IOPOFFICIAL_INCDIR = /n/asic/projects/guinness/releases/$(RELEASE)/design/top/sw/include/
+
+IOPROCDIR = /n/asic/design/io/io_proc/rtl
+
+IOPROCINCL_FILES =
+IOPROCINCL_FILES2=
+IOPROCINCL_FILES += iop_crc_par_defs.h
+IOPROCINCL_FILES += iop_dmc_in_defs.h
+IOPROCINCL_FILES += iop_dmc_out_defs.h
+IOPROCINCL_FILES += iop_fifo_in_defs.h
+IOPROCINCL_FILES += iop_fifo_in_xtra_defs.h
+IOPROCINCL_FILES += iop_fifo_out_defs.h
+IOPROCINCL_FILES += iop_fifo_out_xtra_defs.h
+IOPROCINCL_FILES += iop_mpu_defs.h
+IOPROCINCL_FILES2+= iop_mpu_macros.h
+IOPROCINCL_FILES2+= iop_reg_space.h
+IOPROCINCL_FILES += iop_sap_in_defs.h
+IOPROCINCL_FILES += iop_sap_out_defs.h
+IOPROCINCL_FILES += iop_scrc_in_defs.h
+IOPROCINCL_FILES += iop_scrc_out_defs.h
+IOPROCINCL_FILES += iop_spu_defs.h
+# in guiness/
+IOPROCINCL_FILES += iop_sw_cfg_defs.h
+IOPROCINCL_FILES += iop_sw_cpu_defs.h
+IOPROCINCL_FILES += iop_sw_mpu_defs.h
+IOPROCINCL_FILES += iop_sw_spu_defs.h
+#
+IOPROCINCL_FILES += iop_timer_grp_defs.h
+IOPROCINCL_FILES += iop_trigger_grp_defs.h
+# in guiness/
+IOPROCINCL_FILES += iop_version_defs.h
+
+IOPROCASMINCL_FILES = $(patsubst %_defs.h,%_defs_asm.h,$(IOPROCINCL_FILES))
+IOPROCASMINCL_FILES+= iop_reg_space_asm.h
+
+
+IOPROCREGDESC =
+IOPROCREGDESC += $(IOPROCDIR)/iop_crc_par.r
+#IOPROCREGDESC += $(IOPROCDIR)/iop_crc_ser.r
+IOPROCREGDESC += $(IOPROCDIR)/iop_dmc_in.r
+IOPROCREGDESC += $(IOPROCDIR)/iop_dmc_out.r
+IOPROCREGDESC += $(IOPROCDIR)/iop_fifo_in.r
+IOPROCREGDESC += $(IOPROCDIR)/iop_fifo_in_xtra.r
+IOPROCREGDESC += $(IOPROCDIR)/iop_fifo_out.r
+IOPROCREGDESC += $(IOPROCDIR)/iop_fifo_out_xtra.r
+IOPROCREGDESC += $(IOPROCDIR)/iop_mpu.r
+IOPROCREGDESC += $(IOPROCDIR)/iop_sap_in.r
+IOPROCREGDESC += $(IOPROCDIR)/iop_sap_out.r
+IOPROCREGDESC += $(IOPROCDIR)/iop_scrc_in.r
+IOPROCREGDESC += $(IOPROCDIR)/iop_scrc_out.r
+IOPROCREGDESC += $(IOPROCDIR)/iop_spu.r
+IOPROCREGDESC += $(IOPROCDIR)/guinness/iop_sw_cfg.r
+IOPROCREGDESC += $(IOPROCDIR)/guinness/iop_sw_cpu.r
+IOPROCREGDESC += $(IOPROCDIR)/guinness/iop_sw_mpu.r
+IOPROCREGDESC += $(IOPROCDIR)/guinness/iop_sw_spu.r
+IOPROCREGDESC += $(IOPROCDIR)/iop_timer_grp.r
+IOPROCREGDESC += $(IOPROCDIR)/iop_trigger_grp.r
+IOPROCREGDESC += $(IOPROCDIR)/guinness/iop_version.r
+
+
+RDES2C = /n/asic/bin/rdes2c
+RDES2C = /n/asic/design/tools/rdesc/rdes2c
+RDES2INTR = /n/asic/design/tools/rdesc/rdes2intr
+RDES2TXT = /n/asic/design/tools/rdesc/rdes2txt
+
+## all    - Just print help - you probably want to do 'make gen'
+all: help
+
+## help   - This help
+help:
+	@grep '^## ' Makefile
+
+## gen    - Generate include files
+gen: $(IOPROCINCL_FILES) $(IOPROCINCL_FILES2) $(IOPROCASMINCL_FILES)
+	echo "INCL: $(IOPROCINCL_FILES)"
+	echo "INCL2: $(IOPROCINCL_FILES2)"
+	echo "ASMINCL: $(IOPROCASMINCL_FILES)"
+
+# From the official location...
+iop_reg_space.h: $(IOPOFFICIAL_INCDIR)/iop_reg_space.h
+	cat $< | sed -e 's/\$$Id\:/id\:/g' >$@
+iop_mpu_macros.h: $(IOPOFFICIAL_INCDIR)/iop_mpu_macros.h
+	cat $< | sed -e 's/\$$Id\:/id\:/g' >$@
+
+## copy   - Copy files from official location
+copy:
+	@echo "## Copying and fixing iop files ##"
+	@for HFILE in $(IOPROCINCL_FILES); do \
+		echo "  $$HFILE"; \
+		cat $(IOPOFFICIAL_INCDIR)$$HFILE | sed -e 's/\$$Id\:/id\:/g' > $$HFILE; \
+	done
+	@for HFILE in $(IOPROCINCL_FILES2); do \
+		echo "  $$HFILE"; \
+		cat $(IOPOFFICIAL_INCDIR)$$HFILE | sed -e 's/\$$Id\:/id\:/g' > $$HFILE; \
+	done
+	@echo "## Copying and fixing iop asm files ##"
+	@for HFILE in $(IOPROCASMINCL_FILES); do \
+		echo "  $$HFILE"; \
+		cat $(IOPOFFICIAL_INCDIR)asm/$$HFILE | sed -e 's/\$$Id\:/id\:/g' > asm/$$HFILE; \
+	done
+
+# I/O processor files:
+## iop    - Generate I/O processor include files
+iop: $(IOPROCINCL_FILES) $(IOPROCINCL_FILES2) $(IOPROCASMINCL_FILES)
+iop_sw_%_defs.h: $(IOPROCDIR)/guinness/iop_sw_%.r
+	$(RDES2C) $<
+iop_version_defs.h: $(IOPROCDIR)/guinness/iop_version.r
+	$(RDES2C) $<
+%_defs.h: $(IOPROCDIR)/%.r
+	$(RDES2C) $<
+%_defs_asm.h: $(IOPROCDIR)/%.r
+	$(RDES2C) -asm $<
+iop_version_defs_asm.h: $(IOPROCDIR)/guinness/iop_version.r
+	$(RDES2C) -asm $<
+
+## doc    - Generate .axw files from register description.
+doc: $(IOPROCREGDESC)
+	for RDES in $^; do \
+		$(RDES2TXT) $$RDES; \
+	done
+
+.PHONY: axw
+## %.axw  - Generate the specified .axw file (doesn't work for all files
+##          due to inconsistent naming of .r files.
+%.axw: axw
+	@for RDES in $(IOPROCREGDESC); do \
+		if echo "$$RDES" | grep $* ; then \
+		  $(RDES2TXT) $$RDES; \
+		fi \
+	done
+
+.PHONY: clean
+## clean  - Remove .h files and .axw files.
+clean:
+	rm -rf $(IOPROCINCL_FILES) *.axw
+
+.PHONY: cleandoc
+## cleandoc  - Remove .axw files.
+cleandoc:
+	rm -rf *.axw
+
diff --git a/include/asm-cris/arch-v32/hwregs/iop/asm/iop_crc_par_defs_asm.h b/include/asm-cris/arch-v32/hwregs/iop/asm/iop_crc_par_defs_asm.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/iop/asm/iop_crc_par_defs_asm.h
@@ -0,0 +1,171 @@
+#ifndef __iop_crc_par_defs_asm_h
+#define __iop_crc_par_defs_asm_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/io_proc/rtl/iop_crc_par.r
+ *     id:           <not found>
+ *     last modfied: Mon Apr 11 16:08:45 2005
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c -asm --outfile asm/iop_crc_par_defs_asm.h ../../inst/io_proc/rtl/iop_crc_par.r
+ *      id: $Id: iop_crc_par_defs_asm.h,v 1.5 2005/04/24 18:31:06 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+
+#ifndef REG_FIELD
+#define REG_FIELD( scope, reg, field, value ) \
+  REG_FIELD_X_( value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_FIELD_X_( value, shift ) ((value) << shift)
+#endif
+
+#ifndef REG_STATE
+#define REG_STATE( scope, reg, field, symbolic_value ) \
+  REG_STATE_X_( regk_##scope##_##symbolic_value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_STATE_X_( k, shift ) (k << shift)
+#endif
+
+#ifndef REG_MASK
+#define REG_MASK( scope, reg, field ) \
+  REG_MASK_X_( reg_##scope##_##reg##___##field##___width, reg_##scope##_##reg##___##field##___lsb )
+#define REG_MASK_X_( width, lsb ) (((1 << width)-1) << lsb)
+#endif
+
+#ifndef REG_LSB
+#define REG_LSB( scope, reg, field ) reg_##scope##_##reg##___##field##___lsb
+#endif
+
+#ifndef REG_BIT
+#define REG_BIT( scope, reg, field ) reg_##scope##_##reg##___##field##___bit
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) REG_ADDR_X_(inst, reg_##scope##_##reg##_offset)
+#define REG_ADDR_X_( inst, offs ) ((inst) + offs)
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+         REG_ADDR_VECT_X_(inst, reg_##scope##_##reg##_offset, index, \
+			 STRIDE_##scope##_##reg )
+#define REG_ADDR_VECT_X_( inst, offs, index, stride ) \
+                          ((inst) + offs + (index) * stride)
+#endif
+
+/* Register rw_cfg, scope iop_crc_par, type rw */
+#define reg_iop_crc_par_rw_cfg___mode___lsb 0
+#define reg_iop_crc_par_rw_cfg___mode___width 1
+#define reg_iop_crc_par_rw_cfg___mode___bit 0
+#define reg_iop_crc_par_rw_cfg___crc_out___lsb 1
+#define reg_iop_crc_par_rw_cfg___crc_out___width 1
+#define reg_iop_crc_par_rw_cfg___crc_out___bit 1
+#define reg_iop_crc_par_rw_cfg___rev_out___lsb 2
+#define reg_iop_crc_par_rw_cfg___rev_out___width 1
+#define reg_iop_crc_par_rw_cfg___rev_out___bit 2
+#define reg_iop_crc_par_rw_cfg___inv_out___lsb 3
+#define reg_iop_crc_par_rw_cfg___inv_out___width 1
+#define reg_iop_crc_par_rw_cfg___inv_out___bit 3
+#define reg_iop_crc_par_rw_cfg___trig___lsb 4
+#define reg_iop_crc_par_rw_cfg___trig___width 2
+#define reg_iop_crc_par_rw_cfg___poly___lsb 6
+#define reg_iop_crc_par_rw_cfg___poly___width 3
+#define reg_iop_crc_par_rw_cfg_offset 0
+
+/* Register rw_init_crc, scope iop_crc_par, type rw */
+#define reg_iop_crc_par_rw_init_crc_offset 4
+
+/* Register rw_correct_crc, scope iop_crc_par, type rw */
+#define reg_iop_crc_par_rw_correct_crc_offset 8
+
+/* Register rw_ctrl, scope iop_crc_par, type rw */
+#define reg_iop_crc_par_rw_ctrl___en___lsb 0
+#define reg_iop_crc_par_rw_ctrl___en___width 1
+#define reg_iop_crc_par_rw_ctrl___en___bit 0
+#define reg_iop_crc_par_rw_ctrl_offset 12
+
+/* Register rw_set_last, scope iop_crc_par, type rw */
+#define reg_iop_crc_par_rw_set_last___tr_dif___lsb 0
+#define reg_iop_crc_par_rw_set_last___tr_dif___width 1
+#define reg_iop_crc_par_rw_set_last___tr_dif___bit 0
+#define reg_iop_crc_par_rw_set_last_offset 16
+
+/* Register rw_wr1byte, scope iop_crc_par, type rw */
+#define reg_iop_crc_par_rw_wr1byte___data___lsb 0
+#define reg_iop_crc_par_rw_wr1byte___data___width 8
+#define reg_iop_crc_par_rw_wr1byte_offset 20
+
+/* Register rw_wr2byte, scope iop_crc_par, type rw */
+#define reg_iop_crc_par_rw_wr2byte___data___lsb 0
+#define reg_iop_crc_par_rw_wr2byte___data___width 16
+#define reg_iop_crc_par_rw_wr2byte_offset 24
+
+/* Register rw_wr3byte, scope iop_crc_par, type rw */
+#define reg_iop_crc_par_rw_wr3byte___data___lsb 0
+#define reg_iop_crc_par_rw_wr3byte___data___width 24
+#define reg_iop_crc_par_rw_wr3byte_offset 28
+
+/* Register rw_wr4byte, scope iop_crc_par, type rw */
+#define reg_iop_crc_par_rw_wr4byte___data___lsb 0
+#define reg_iop_crc_par_rw_wr4byte___data___width 32
+#define reg_iop_crc_par_rw_wr4byte_offset 32
+
+/* Register rw_wr1byte_last, scope iop_crc_par, type rw */
+#define reg_iop_crc_par_rw_wr1byte_last___data___lsb 0
+#define reg_iop_crc_par_rw_wr1byte_last___data___width 8
+#define reg_iop_crc_par_rw_wr1byte_last_offset 36
+
+/* Register rw_wr2byte_last, scope iop_crc_par, type rw */
+#define reg_iop_crc_par_rw_wr2byte_last___data___lsb 0
+#define reg_iop_crc_par_rw_wr2byte_last___data___width 16
+#define reg_iop_crc_par_rw_wr2byte_last_offset 40
+
+/* Register rw_wr3byte_last, scope iop_crc_par, type rw */
+#define reg_iop_crc_par_rw_wr3byte_last___data___lsb 0
+#define reg_iop_crc_par_rw_wr3byte_last___data___width 24
+#define reg_iop_crc_par_rw_wr3byte_last_offset 44
+
+/* Register rw_wr4byte_last, scope iop_crc_par, type rw */
+#define reg_iop_crc_par_rw_wr4byte_last___data___lsb 0
+#define reg_iop_crc_par_rw_wr4byte_last___data___width 32
+#define reg_iop_crc_par_rw_wr4byte_last_offset 48
+
+/* Register r_stat, scope iop_crc_par, type r */
+#define reg_iop_crc_par_r_stat___err___lsb 0
+#define reg_iop_crc_par_r_stat___err___width 1
+#define reg_iop_crc_par_r_stat___err___bit 0
+#define reg_iop_crc_par_r_stat___busy___lsb 1
+#define reg_iop_crc_par_r_stat___busy___width 1
+#define reg_iop_crc_par_r_stat___busy___bit 1
+#define reg_iop_crc_par_r_stat_offset 52
+
+/* Register r_sh_reg, scope iop_crc_par, type r */
+#define reg_iop_crc_par_r_sh_reg_offset 56
+
+/* Register r_crc, scope iop_crc_par, type r */
+#define reg_iop_crc_par_r_crc_offset 60
+
+/* Register rw_strb_rec_dif_in, scope iop_crc_par, type rw */
+#define reg_iop_crc_par_rw_strb_rec_dif_in___last___lsb 0
+#define reg_iop_crc_par_rw_strb_rec_dif_in___last___width 2
+#define reg_iop_crc_par_rw_strb_rec_dif_in_offset 64
+
+
+/* Constants */
+#define regk_iop_crc_par_calc                     0x00000001
+#define regk_iop_crc_par_ccitt                    0x00000002
+#define regk_iop_crc_par_check                    0x00000000
+#define regk_iop_crc_par_crc16                    0x00000001
+#define regk_iop_crc_par_crc32                    0x00000000
+#define regk_iop_crc_par_crc5                     0x00000003
+#define regk_iop_crc_par_crc5_11                  0x00000004
+#define regk_iop_crc_par_dif_in                   0x00000002
+#define regk_iop_crc_par_hi                       0x00000000
+#define regk_iop_crc_par_neg                      0x00000002
+#define regk_iop_crc_par_no                       0x00000000
+#define regk_iop_crc_par_pos                      0x00000001
+#define regk_iop_crc_par_pos_neg                  0x00000003
+#define regk_iop_crc_par_rw_cfg_default           0x00000000
+#define regk_iop_crc_par_rw_ctrl_default          0x00000000
+#define regk_iop_crc_par_yes                      0x00000001
+#endif /* __iop_crc_par_defs_asm_h */
diff --git a/include/asm-cris/arch-v32/hwregs/iop/asm/iop_dmc_in_defs_asm.h b/include/asm-cris/arch-v32/hwregs/iop/asm/iop_dmc_in_defs_asm.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/iop/asm/iop_dmc_in_defs_asm.h
@@ -0,0 +1,321 @@
+#ifndef __iop_dmc_in_defs_asm_h
+#define __iop_dmc_in_defs_asm_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/io_proc/rtl/iop_dmc_in.r
+ *     id:           iop_dmc_in.r,v 1.26 2005/02/16 09:14:17 niklaspa Exp
+ *     last modfied: Mon Apr 11 16:08:45 2005
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c -asm --outfile asm/iop_dmc_in_defs_asm.h ../../inst/io_proc/rtl/iop_dmc_in.r
+ *      id: $Id: iop_dmc_in_defs_asm.h,v 1.5 2005/04/24 18:31:06 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+
+#ifndef REG_FIELD
+#define REG_FIELD( scope, reg, field, value ) \
+  REG_FIELD_X_( value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_FIELD_X_( value, shift ) ((value) << shift)
+#endif
+
+#ifndef REG_STATE
+#define REG_STATE( scope, reg, field, symbolic_value ) \
+  REG_STATE_X_( regk_##scope##_##symbolic_value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_STATE_X_( k, shift ) (k << shift)
+#endif
+
+#ifndef REG_MASK
+#define REG_MASK( scope, reg, field ) \
+  REG_MASK_X_( reg_##scope##_##reg##___##field##___width, reg_##scope##_##reg##___##field##___lsb )
+#define REG_MASK_X_( width, lsb ) (((1 << width)-1) << lsb)
+#endif
+
+#ifndef REG_LSB
+#define REG_LSB( scope, reg, field ) reg_##scope##_##reg##___##field##___lsb
+#endif
+
+#ifndef REG_BIT
+#define REG_BIT( scope, reg, field ) reg_##scope##_##reg##___##field##___bit
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) REG_ADDR_X_(inst, reg_##scope##_##reg##_offset)
+#define REG_ADDR_X_( inst, offs ) ((inst) + offs)
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+         REG_ADDR_VECT_X_(inst, reg_##scope##_##reg##_offset, index, \
+			 STRIDE_##scope##_##reg )
+#define REG_ADDR_VECT_X_( inst, offs, index, stride ) \
+                          ((inst) + offs + (index) * stride)
+#endif
+
+/* Register rw_cfg, scope iop_dmc_in, type rw */
+#define reg_iop_dmc_in_rw_cfg___sth_intr___lsb 0
+#define reg_iop_dmc_in_rw_cfg___sth_intr___width 3
+#define reg_iop_dmc_in_rw_cfg___last_dis_dif___lsb 3
+#define reg_iop_dmc_in_rw_cfg___last_dis_dif___width 1
+#define reg_iop_dmc_in_rw_cfg___last_dis_dif___bit 3
+#define reg_iop_dmc_in_rw_cfg_offset 0
+
+/* Register rw_ctrl, scope iop_dmc_in, type rw */
+#define reg_iop_dmc_in_rw_ctrl___dif_en___lsb 0
+#define reg_iop_dmc_in_rw_ctrl___dif_en___width 1
+#define reg_iop_dmc_in_rw_ctrl___dif_en___bit 0
+#define reg_iop_dmc_in_rw_ctrl___dif_dis___lsb 1
+#define reg_iop_dmc_in_rw_ctrl___dif_dis___width 1
+#define reg_iop_dmc_in_rw_ctrl___dif_dis___bit 1
+#define reg_iop_dmc_in_rw_ctrl___stream_clr___lsb 2
+#define reg_iop_dmc_in_rw_ctrl___stream_clr___width 1
+#define reg_iop_dmc_in_rw_ctrl___stream_clr___bit 2
+#define reg_iop_dmc_in_rw_ctrl_offset 4
+
+/* Register r_stat, scope iop_dmc_in, type r */
+#define reg_iop_dmc_in_r_stat___dif_en___lsb 0
+#define reg_iop_dmc_in_r_stat___dif_en___width 1
+#define reg_iop_dmc_in_r_stat___dif_en___bit 0
+#define reg_iop_dmc_in_r_stat_offset 8
+
+/* Register rw_stream_cmd, scope iop_dmc_in, type rw */
+#define reg_iop_dmc_in_rw_stream_cmd___cmd___lsb 0
+#define reg_iop_dmc_in_rw_stream_cmd___cmd___width 10
+#define reg_iop_dmc_in_rw_stream_cmd___n___lsb 16
+#define reg_iop_dmc_in_rw_stream_cmd___n___width 8
+#define reg_iop_dmc_in_rw_stream_cmd_offset 12
+
+/* Register rw_stream_wr_data, scope iop_dmc_in, type rw */
+#define reg_iop_dmc_in_rw_stream_wr_data_offset 16
+
+/* Register rw_stream_wr_data_last, scope iop_dmc_in, type rw */
+#define reg_iop_dmc_in_rw_stream_wr_data_last_offset 20
+
+/* Register rw_stream_ctrl, scope iop_dmc_in, type rw */
+#define reg_iop_dmc_in_rw_stream_ctrl___eop___lsb 0
+#define reg_iop_dmc_in_rw_stream_ctrl___eop___width 1
+#define reg_iop_dmc_in_rw_stream_ctrl___eop___bit 0
+#define reg_iop_dmc_in_rw_stream_ctrl___wait___lsb 1
+#define reg_iop_dmc_in_rw_stream_ctrl___wait___width 1
+#define reg_iop_dmc_in_rw_stream_ctrl___wait___bit 1
+#define reg_iop_dmc_in_rw_stream_ctrl___keep_md___lsb 2
+#define reg_iop_dmc_in_rw_stream_ctrl___keep_md___width 1
+#define reg_iop_dmc_in_rw_stream_ctrl___keep_md___bit 2
+#define reg_iop_dmc_in_rw_stream_ctrl___size___lsb 3
+#define reg_iop_dmc_in_rw_stream_ctrl___size___width 3
+#define reg_iop_dmc_in_rw_stream_ctrl_offset 24
+
+/* Register r_stream_stat, scope iop_dmc_in, type r */
+#define reg_iop_dmc_in_r_stream_stat___sth___lsb 0
+#define reg_iop_dmc_in_r_stream_stat___sth___width 7
+#define reg_iop_dmc_in_r_stream_stat___full___lsb 16
+#define reg_iop_dmc_in_r_stream_stat___full___width 1
+#define reg_iop_dmc_in_r_stream_stat___full___bit 16
+#define reg_iop_dmc_in_r_stream_stat___last_pkt___lsb 17
+#define reg_iop_dmc_in_r_stream_stat___last_pkt___width 1
+#define reg_iop_dmc_in_r_stream_stat___last_pkt___bit 17
+#define reg_iop_dmc_in_r_stream_stat___data_md_valid___lsb 18
+#define reg_iop_dmc_in_r_stream_stat___data_md_valid___width 1
+#define reg_iop_dmc_in_r_stream_stat___data_md_valid___bit 18
+#define reg_iop_dmc_in_r_stream_stat___ctxt_md_valid___lsb 19
+#define reg_iop_dmc_in_r_stream_stat___ctxt_md_valid___width 1
+#define reg_iop_dmc_in_r_stream_stat___ctxt_md_valid___bit 19
+#define reg_iop_dmc_in_r_stream_stat___group_md_valid___lsb 20
+#define reg_iop_dmc_in_r_stream_stat___group_md_valid___width 1
+#define reg_iop_dmc_in_r_stream_stat___group_md_valid___bit 20
+#define reg_iop_dmc_in_r_stream_stat___stream_busy___lsb 21
+#define reg_iop_dmc_in_r_stream_stat___stream_busy___width 1
+#define reg_iop_dmc_in_r_stream_stat___stream_busy___bit 21
+#define reg_iop_dmc_in_r_stream_stat___cmd_rdy___lsb 22
+#define reg_iop_dmc_in_r_stream_stat___cmd_rdy___width 1
+#define reg_iop_dmc_in_r_stream_stat___cmd_rdy___bit 22
+#define reg_iop_dmc_in_r_stream_stat_offset 28
+
+/* Register r_data_descr, scope iop_dmc_in, type r */
+#define reg_iop_dmc_in_r_data_descr___ctrl___lsb 0
+#define reg_iop_dmc_in_r_data_descr___ctrl___width 8
+#define reg_iop_dmc_in_r_data_descr___stat___lsb 8
+#define reg_iop_dmc_in_r_data_descr___stat___width 8
+#define reg_iop_dmc_in_r_data_descr___md___lsb 16
+#define reg_iop_dmc_in_r_data_descr___md___width 16
+#define reg_iop_dmc_in_r_data_descr_offset 32
+
+/* Register r_ctxt_descr, scope iop_dmc_in, type r */
+#define reg_iop_dmc_in_r_ctxt_descr___ctrl___lsb 0
+#define reg_iop_dmc_in_r_ctxt_descr___ctrl___width 8
+#define reg_iop_dmc_in_r_ctxt_descr___stat___lsb 8
+#define reg_iop_dmc_in_r_ctxt_descr___stat___width 8
+#define reg_iop_dmc_in_r_ctxt_descr___md0___lsb 16
+#define reg_iop_dmc_in_r_ctxt_descr___md0___width 16
+#define reg_iop_dmc_in_r_ctxt_descr_offset 36
+
+/* Register r_ctxt_descr_md1, scope iop_dmc_in, type r */
+#define reg_iop_dmc_in_r_ctxt_descr_md1_offset 40
+
+/* Register r_ctxt_descr_md2, scope iop_dmc_in, type r */
+#define reg_iop_dmc_in_r_ctxt_descr_md2_offset 44
+
+/* Register r_group_descr, scope iop_dmc_in, type r */
+#define reg_iop_dmc_in_r_group_descr___ctrl___lsb 0
+#define reg_iop_dmc_in_r_group_descr___ctrl___width 8
+#define reg_iop_dmc_in_r_group_descr___stat___lsb 8
+#define reg_iop_dmc_in_r_group_descr___stat___width 8
+#define reg_iop_dmc_in_r_group_descr___md___lsb 16
+#define reg_iop_dmc_in_r_group_descr___md___width 16
+#define reg_iop_dmc_in_r_group_descr_offset 56
+
+/* Register rw_data_descr, scope iop_dmc_in, type rw */
+#define reg_iop_dmc_in_rw_data_descr___md___lsb 16
+#define reg_iop_dmc_in_rw_data_descr___md___width 16
+#define reg_iop_dmc_in_rw_data_descr_offset 60
+
+/* Register rw_ctxt_descr, scope iop_dmc_in, type rw */
+#define reg_iop_dmc_in_rw_ctxt_descr___md0___lsb 16
+#define reg_iop_dmc_in_rw_ctxt_descr___md0___width 16
+#define reg_iop_dmc_in_rw_ctxt_descr_offset 64
+
+/* Register rw_ctxt_descr_md1, scope iop_dmc_in, type rw */
+#define reg_iop_dmc_in_rw_ctxt_descr_md1_offset 68
+
+/* Register rw_ctxt_descr_md2, scope iop_dmc_in, type rw */
+#define reg_iop_dmc_in_rw_ctxt_descr_md2_offset 72
+
+/* Register rw_group_descr, scope iop_dmc_in, type rw */
+#define reg_iop_dmc_in_rw_group_descr___md___lsb 16
+#define reg_iop_dmc_in_rw_group_descr___md___width 16
+#define reg_iop_dmc_in_rw_group_descr_offset 84
+
+/* Register rw_intr_mask, scope iop_dmc_in, type rw */
+#define reg_iop_dmc_in_rw_intr_mask___data_md___lsb 0
+#define reg_iop_dmc_in_rw_intr_mask___data_md___width 1
+#define reg_iop_dmc_in_rw_intr_mask___data_md___bit 0
+#define reg_iop_dmc_in_rw_intr_mask___ctxt_md___lsb 1
+#define reg_iop_dmc_in_rw_intr_mask___ctxt_md___width 1
+#define reg_iop_dmc_in_rw_intr_mask___ctxt_md___bit 1
+#define reg_iop_dmc_in_rw_intr_mask___group_md___lsb 2
+#define reg_iop_dmc_in_rw_intr_mask___group_md___width 1
+#define reg_iop_dmc_in_rw_intr_mask___group_md___bit 2
+#define reg_iop_dmc_in_rw_intr_mask___cmd_rdy___lsb 3
+#define reg_iop_dmc_in_rw_intr_mask___cmd_rdy___width 1
+#define reg_iop_dmc_in_rw_intr_mask___cmd_rdy___bit 3
+#define reg_iop_dmc_in_rw_intr_mask___sth___lsb 4
+#define reg_iop_dmc_in_rw_intr_mask___sth___width 1
+#define reg_iop_dmc_in_rw_intr_mask___sth___bit 4
+#define reg_iop_dmc_in_rw_intr_mask___full___lsb 5
+#define reg_iop_dmc_in_rw_intr_mask___full___width 1
+#define reg_iop_dmc_in_rw_intr_mask___full___bit 5
+#define reg_iop_dmc_in_rw_intr_mask_offset 88
+
+/* Register rw_ack_intr, scope iop_dmc_in, type rw */
+#define reg_iop_dmc_in_rw_ack_intr___data_md___lsb 0
+#define reg_iop_dmc_in_rw_ack_intr___data_md___width 1
+#define reg_iop_dmc_in_rw_ack_intr___data_md___bit 0
+#define reg_iop_dmc_in_rw_ack_intr___ctxt_md___lsb 1
+#define reg_iop_dmc_in_rw_ack_intr___ctxt_md___width 1
+#define reg_iop_dmc_in_rw_ack_intr___ctxt_md___bit 1
+#define reg_iop_dmc_in_rw_ack_intr___group_md___lsb 2
+#define reg_iop_dmc_in_rw_ack_intr___group_md___width 1
+#define reg_iop_dmc_in_rw_ack_intr___group_md___bit 2
+#define reg_iop_dmc_in_rw_ack_intr___cmd_rdy___lsb 3
+#define reg_iop_dmc_in_rw_ack_intr___cmd_rdy___width 1
+#define reg_iop_dmc_in_rw_ack_intr___cmd_rdy___bit 3
+#define reg_iop_dmc_in_rw_ack_intr___sth___lsb 4
+#define reg_iop_dmc_in_rw_ack_intr___sth___width 1
+#define reg_iop_dmc_in_rw_ack_intr___sth___bit 4
+#define reg_iop_dmc_in_rw_ack_intr___full___lsb 5
+#define reg_iop_dmc_in_rw_ack_intr___full___width 1
+#define reg_iop_dmc_in_rw_ack_intr___full___bit 5
+#define reg_iop_dmc_in_rw_ack_intr_offset 92
+
+/* Register r_intr, scope iop_dmc_in, type r */
+#define reg_iop_dmc_in_r_intr___data_md___lsb 0
+#define reg_iop_dmc_in_r_intr___data_md___width 1
+#define reg_iop_dmc_in_r_intr___data_md___bit 0
+#define reg_iop_dmc_in_r_intr___ctxt_md___lsb 1
+#define reg_iop_dmc_in_r_intr___ctxt_md___width 1
+#define reg_iop_dmc_in_r_intr___ctxt_md___bit 1
+#define reg_iop_dmc_in_r_intr___group_md___lsb 2
+#define reg_iop_dmc_in_r_intr___group_md___width 1
+#define reg_iop_dmc_in_r_intr___group_md___bit 2
+#define reg_iop_dmc_in_r_intr___cmd_rdy___lsb 3
+#define reg_iop_dmc_in_r_intr___cmd_rdy___width 1
+#define reg_iop_dmc_in_r_intr___cmd_rdy___bit 3
+#define reg_iop_dmc_in_r_intr___sth___lsb 4
+#define reg_iop_dmc_in_r_intr___sth___width 1
+#define reg_iop_dmc_in_r_intr___sth___bit 4
+#define reg_iop_dmc_in_r_intr___full___lsb 5
+#define reg_iop_dmc_in_r_intr___full___width 1
+#define reg_iop_dmc_in_r_intr___full___bit 5
+#define reg_iop_dmc_in_r_intr_offset 96
+
+/* Register r_masked_intr, scope iop_dmc_in, type r */
+#define reg_iop_dmc_in_r_masked_intr___data_md___lsb 0
+#define reg_iop_dmc_in_r_masked_intr___data_md___width 1
+#define reg_iop_dmc_in_r_masked_intr___data_md___bit 0
+#define reg_iop_dmc_in_r_masked_intr___ctxt_md___lsb 1
+#define reg_iop_dmc_in_r_masked_intr___ctxt_md___width 1
+#define reg_iop_dmc_in_r_masked_intr___ctxt_md___bit 1
+#define reg_iop_dmc_in_r_masked_intr___group_md___lsb 2
+#define reg_iop_dmc_in_r_masked_intr___group_md___width 1
+#define reg_iop_dmc_in_r_masked_intr___group_md___bit 2
+#define reg_iop_dmc_in_r_masked_intr___cmd_rdy___lsb 3
+#define reg_iop_dmc_in_r_masked_intr___cmd_rdy___width 1
+#define reg_iop_dmc_in_r_masked_intr___cmd_rdy___bit 3
+#define reg_iop_dmc_in_r_masked_intr___sth___lsb 4
+#define reg_iop_dmc_in_r_masked_intr___sth___width 1
+#define reg_iop_dmc_in_r_masked_intr___sth___bit 4
+#define reg_iop_dmc_in_r_masked_intr___full___lsb 5
+#define reg_iop_dmc_in_r_masked_intr___full___width 1
+#define reg_iop_dmc_in_r_masked_intr___full___bit 5
+#define reg_iop_dmc_in_r_masked_intr_offset 100
+
+
+/* Constants */
+#define regk_iop_dmc_in_ack_pkt                   0x00000100
+#define regk_iop_dmc_in_array                     0x00000008
+#define regk_iop_dmc_in_burst                     0x00000020
+#define regk_iop_dmc_in_copy_next                 0x00000010
+#define regk_iop_dmc_in_copy_up                   0x00000020
+#define regk_iop_dmc_in_dis_c                     0x00000010
+#define regk_iop_dmc_in_dis_g                     0x00000020
+#define regk_iop_dmc_in_lim1                      0x00000000
+#define regk_iop_dmc_in_lim16                     0x00000004
+#define regk_iop_dmc_in_lim2                      0x00000001
+#define regk_iop_dmc_in_lim32                     0x00000005
+#define regk_iop_dmc_in_lim4                      0x00000002
+#define regk_iop_dmc_in_lim64                     0x00000006
+#define regk_iop_dmc_in_lim8                      0x00000003
+#define regk_iop_dmc_in_load_c                    0x00000200
+#define regk_iop_dmc_in_load_c_n                  0x00000280
+#define regk_iop_dmc_in_load_c_next               0x00000240
+#define regk_iop_dmc_in_load_d                    0x00000140
+#define regk_iop_dmc_in_load_g                    0x00000300
+#define regk_iop_dmc_in_load_g_down               0x000003c0
+#define regk_iop_dmc_in_load_g_next               0x00000340
+#define regk_iop_dmc_in_load_g_up                 0x00000380
+#define regk_iop_dmc_in_next_en                   0x00000010
+#define regk_iop_dmc_in_next_pkt                  0x00000010
+#define regk_iop_dmc_in_no                        0x00000000
+#define regk_iop_dmc_in_restore                   0x00000020
+#define regk_iop_dmc_in_rw_cfg_default            0x00000000
+#define regk_iop_dmc_in_rw_ctxt_descr_default     0x00000000
+#define regk_iop_dmc_in_rw_ctxt_descr_md1_default  0x00000000
+#define regk_iop_dmc_in_rw_ctxt_descr_md2_default  0x00000000
+#define regk_iop_dmc_in_rw_data_descr_default     0x00000000
+#define regk_iop_dmc_in_rw_group_descr_default    0x00000000
+#define regk_iop_dmc_in_rw_intr_mask_default      0x00000000
+#define regk_iop_dmc_in_rw_stream_ctrl_default    0x00000000
+#define regk_iop_dmc_in_save_down                 0x00000020
+#define regk_iop_dmc_in_save_up                   0x00000020
+#define regk_iop_dmc_in_set_reg                   0x00000050
+#define regk_iop_dmc_in_set_w_size1               0x00000190
+#define regk_iop_dmc_in_set_w_size2               0x000001a0
+#define regk_iop_dmc_in_set_w_size4               0x000001c0
+#define regk_iop_dmc_in_store_c                   0x00000002
+#define regk_iop_dmc_in_store_descr               0x00000000
+#define regk_iop_dmc_in_store_g                   0x00000004
+#define regk_iop_dmc_in_store_md                  0x00000001
+#define regk_iop_dmc_in_update_down               0x00000020
+#define regk_iop_dmc_in_yes                       0x00000001
+#endif /* __iop_dmc_in_defs_asm_h */
diff --git a/include/asm-cris/arch-v32/hwregs/iop/asm/iop_dmc_out_defs_asm.h b/include/asm-cris/arch-v32/hwregs/iop/asm/iop_dmc_out_defs_asm.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/iop/asm/iop_dmc_out_defs_asm.h
@@ -0,0 +1,349 @@
+#ifndef __iop_dmc_out_defs_asm_h
+#define __iop_dmc_out_defs_asm_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/io_proc/rtl/iop_dmc_out.r
+ *     id:           iop_dmc_out.r,v 1.30 2005/02/16 09:14:11 niklaspa Exp
+ *     last modfied: Mon Apr 11 16:08:45 2005
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c -asm --outfile asm/iop_dmc_out_defs_asm.h ../../inst/io_proc/rtl/iop_dmc_out.r
+ *      id: $Id: iop_dmc_out_defs_asm.h,v 1.5 2005/04/24 18:31:06 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+
+#ifndef REG_FIELD
+#define REG_FIELD( scope, reg, field, value ) \
+  REG_FIELD_X_( value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_FIELD_X_( value, shift ) ((value) << shift)
+#endif
+
+#ifndef REG_STATE
+#define REG_STATE( scope, reg, field, symbolic_value ) \
+  REG_STATE_X_( regk_##scope##_##symbolic_value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_STATE_X_( k, shift ) (k << shift)
+#endif
+
+#ifndef REG_MASK
+#define REG_MASK( scope, reg, field ) \
+  REG_MASK_X_( reg_##scope##_##reg##___##field##___width, reg_##scope##_##reg##___##field##___lsb )
+#define REG_MASK_X_( width, lsb ) (((1 << width)-1) << lsb)
+#endif
+
+#ifndef REG_LSB
+#define REG_LSB( scope, reg, field ) reg_##scope##_##reg##___##field##___lsb
+#endif
+
+#ifndef REG_BIT
+#define REG_BIT( scope, reg, field ) reg_##scope##_##reg##___##field##___bit
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) REG_ADDR_X_(inst, reg_##scope##_##reg##_offset)
+#define REG_ADDR_X_( inst, offs ) ((inst) + offs)
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+         REG_ADDR_VECT_X_(inst, reg_##scope##_##reg##_offset, index, \
+			 STRIDE_##scope##_##reg )
+#define REG_ADDR_VECT_X_( inst, offs, index, stride ) \
+                          ((inst) + offs + (index) * stride)
+#endif
+
+/* Register rw_cfg, scope iop_dmc_out, type rw */
+#define reg_iop_dmc_out_rw_cfg___trf_lim___lsb 0
+#define reg_iop_dmc_out_rw_cfg___trf_lim___width 16
+#define reg_iop_dmc_out_rw_cfg___last_at_trf_lim___lsb 16
+#define reg_iop_dmc_out_rw_cfg___last_at_trf_lim___width 1
+#define reg_iop_dmc_out_rw_cfg___last_at_trf_lim___bit 16
+#define reg_iop_dmc_out_rw_cfg___dth_intr___lsb 17
+#define reg_iop_dmc_out_rw_cfg___dth_intr___width 3
+#define reg_iop_dmc_out_rw_cfg_offset 0
+
+/* Register rw_ctrl, scope iop_dmc_out, type rw */
+#define reg_iop_dmc_out_rw_ctrl___dif_en___lsb 0
+#define reg_iop_dmc_out_rw_ctrl___dif_en___width 1
+#define reg_iop_dmc_out_rw_ctrl___dif_en___bit 0
+#define reg_iop_dmc_out_rw_ctrl___dif_dis___lsb 1
+#define reg_iop_dmc_out_rw_ctrl___dif_dis___width 1
+#define reg_iop_dmc_out_rw_ctrl___dif_dis___bit 1
+#define reg_iop_dmc_out_rw_ctrl_offset 4
+
+/* Register r_stat, scope iop_dmc_out, type r */
+#define reg_iop_dmc_out_r_stat___dif_en___lsb 0
+#define reg_iop_dmc_out_r_stat___dif_en___width 1
+#define reg_iop_dmc_out_r_stat___dif_en___bit 0
+#define reg_iop_dmc_out_r_stat_offset 8
+
+/* Register rw_stream_cmd, scope iop_dmc_out, type rw */
+#define reg_iop_dmc_out_rw_stream_cmd___cmd___lsb 0
+#define reg_iop_dmc_out_rw_stream_cmd___cmd___width 10
+#define reg_iop_dmc_out_rw_stream_cmd___n___lsb 16
+#define reg_iop_dmc_out_rw_stream_cmd___n___width 8
+#define reg_iop_dmc_out_rw_stream_cmd_offset 12
+
+/* Register rs_stream_data, scope iop_dmc_out, type rs */
+#define reg_iop_dmc_out_rs_stream_data_offset 16
+
+/* Register r_stream_data, scope iop_dmc_out, type r */
+#define reg_iop_dmc_out_r_stream_data_offset 20
+
+/* Register r_stream_stat, scope iop_dmc_out, type r */
+#define reg_iop_dmc_out_r_stream_stat___dth___lsb 0
+#define reg_iop_dmc_out_r_stream_stat___dth___width 7
+#define reg_iop_dmc_out_r_stream_stat___dv___lsb 16
+#define reg_iop_dmc_out_r_stream_stat___dv___width 1
+#define reg_iop_dmc_out_r_stream_stat___dv___bit 16
+#define reg_iop_dmc_out_r_stream_stat___all_avail___lsb 17
+#define reg_iop_dmc_out_r_stream_stat___all_avail___width 1
+#define reg_iop_dmc_out_r_stream_stat___all_avail___bit 17
+#define reg_iop_dmc_out_r_stream_stat___last___lsb 18
+#define reg_iop_dmc_out_r_stream_stat___last___width 1
+#define reg_iop_dmc_out_r_stream_stat___last___bit 18
+#define reg_iop_dmc_out_r_stream_stat___size___lsb 19
+#define reg_iop_dmc_out_r_stream_stat___size___width 3
+#define reg_iop_dmc_out_r_stream_stat___data_md_valid___lsb 22
+#define reg_iop_dmc_out_r_stream_stat___data_md_valid___width 1
+#define reg_iop_dmc_out_r_stream_stat___data_md_valid___bit 22
+#define reg_iop_dmc_out_r_stream_stat___ctxt_md_valid___lsb 23
+#define reg_iop_dmc_out_r_stream_stat___ctxt_md_valid___width 1
+#define reg_iop_dmc_out_r_stream_stat___ctxt_md_valid___bit 23
+#define reg_iop_dmc_out_r_stream_stat___group_md_valid___lsb 24
+#define reg_iop_dmc_out_r_stream_stat___group_md_valid___width 1
+#define reg_iop_dmc_out_r_stream_stat___group_md_valid___bit 24
+#define reg_iop_dmc_out_r_stream_stat___stream_busy___lsb 25
+#define reg_iop_dmc_out_r_stream_stat___stream_busy___width 1
+#define reg_iop_dmc_out_r_stream_stat___stream_busy___bit 25
+#define reg_iop_dmc_out_r_stream_stat___cmd_rdy___lsb 26
+#define reg_iop_dmc_out_r_stream_stat___cmd_rdy___width 1
+#define reg_iop_dmc_out_r_stream_stat___cmd_rdy___bit 26
+#define reg_iop_dmc_out_r_stream_stat___cmd_rq___lsb 27
+#define reg_iop_dmc_out_r_stream_stat___cmd_rq___width 1
+#define reg_iop_dmc_out_r_stream_stat___cmd_rq___bit 27
+#define reg_iop_dmc_out_r_stream_stat_offset 24
+
+/* Register r_data_descr, scope iop_dmc_out, type r */
+#define reg_iop_dmc_out_r_data_descr___ctrl___lsb 0
+#define reg_iop_dmc_out_r_data_descr___ctrl___width 8
+#define reg_iop_dmc_out_r_data_descr___stat___lsb 8
+#define reg_iop_dmc_out_r_data_descr___stat___width 8
+#define reg_iop_dmc_out_r_data_descr___md___lsb 16
+#define reg_iop_dmc_out_r_data_descr___md___width 16
+#define reg_iop_dmc_out_r_data_descr_offset 28
+
+/* Register r_ctxt_descr, scope iop_dmc_out, type r */
+#define reg_iop_dmc_out_r_ctxt_descr___ctrl___lsb 0
+#define reg_iop_dmc_out_r_ctxt_descr___ctrl___width 8
+#define reg_iop_dmc_out_r_ctxt_descr___stat___lsb 8
+#define reg_iop_dmc_out_r_ctxt_descr___stat___width 8
+#define reg_iop_dmc_out_r_ctxt_descr___md0___lsb 16
+#define reg_iop_dmc_out_r_ctxt_descr___md0___width 16
+#define reg_iop_dmc_out_r_ctxt_descr_offset 32
+
+/* Register r_ctxt_descr_md1, scope iop_dmc_out, type r */
+#define reg_iop_dmc_out_r_ctxt_descr_md1_offset 36
+
+/* Register r_ctxt_descr_md2, scope iop_dmc_out, type r */
+#define reg_iop_dmc_out_r_ctxt_descr_md2_offset 40
+
+/* Register r_group_descr, scope iop_dmc_out, type r */
+#define reg_iop_dmc_out_r_group_descr___ctrl___lsb 0
+#define reg_iop_dmc_out_r_group_descr___ctrl___width 8
+#define reg_iop_dmc_out_r_group_descr___stat___lsb 8
+#define reg_iop_dmc_out_r_group_descr___stat___width 8
+#define reg_iop_dmc_out_r_group_descr___md___lsb 16
+#define reg_iop_dmc_out_r_group_descr___md___width 16
+#define reg_iop_dmc_out_r_group_descr_offset 52
+
+/* Register rw_data_descr, scope iop_dmc_out, type rw */
+#define reg_iop_dmc_out_rw_data_descr___md___lsb 16
+#define reg_iop_dmc_out_rw_data_descr___md___width 16
+#define reg_iop_dmc_out_rw_data_descr_offset 56
+
+/* Register rw_ctxt_descr, scope iop_dmc_out, type rw */
+#define reg_iop_dmc_out_rw_ctxt_descr___md0___lsb 16
+#define reg_iop_dmc_out_rw_ctxt_descr___md0___width 16
+#define reg_iop_dmc_out_rw_ctxt_descr_offset 60
+
+/* Register rw_ctxt_descr_md1, scope iop_dmc_out, type rw */
+#define reg_iop_dmc_out_rw_ctxt_descr_md1_offset 64
+
+/* Register rw_ctxt_descr_md2, scope iop_dmc_out, type rw */
+#define reg_iop_dmc_out_rw_ctxt_descr_md2_offset 68
+
+/* Register rw_group_descr, scope iop_dmc_out, type rw */
+#define reg_iop_dmc_out_rw_group_descr___md___lsb 16
+#define reg_iop_dmc_out_rw_group_descr___md___width 16
+#define reg_iop_dmc_out_rw_group_descr_offset 80
+
+/* Register rw_intr_mask, scope iop_dmc_out, type rw */
+#define reg_iop_dmc_out_rw_intr_mask___data_md___lsb 0
+#define reg_iop_dmc_out_rw_intr_mask___data_md___width 1
+#define reg_iop_dmc_out_rw_intr_mask___data_md___bit 0
+#define reg_iop_dmc_out_rw_intr_mask___ctxt_md___lsb 1
+#define reg_iop_dmc_out_rw_intr_mask___ctxt_md___width 1
+#define reg_iop_dmc_out_rw_intr_mask___ctxt_md___bit 1
+#define reg_iop_dmc_out_rw_intr_mask___group_md___lsb 2
+#define reg_iop_dmc_out_rw_intr_mask___group_md___width 1
+#define reg_iop_dmc_out_rw_intr_mask___group_md___bit 2
+#define reg_iop_dmc_out_rw_intr_mask___cmd_rdy___lsb 3
+#define reg_iop_dmc_out_rw_intr_mask___cmd_rdy___width 1
+#define reg_iop_dmc_out_rw_intr_mask___cmd_rdy___bit 3
+#define reg_iop_dmc_out_rw_intr_mask___dth___lsb 4
+#define reg_iop_dmc_out_rw_intr_mask___dth___width 1
+#define reg_iop_dmc_out_rw_intr_mask___dth___bit 4
+#define reg_iop_dmc_out_rw_intr_mask___dv___lsb 5
+#define reg_iop_dmc_out_rw_intr_mask___dv___width 1
+#define reg_iop_dmc_out_rw_intr_mask___dv___bit 5
+#define reg_iop_dmc_out_rw_intr_mask___last_data___lsb 6
+#define reg_iop_dmc_out_rw_intr_mask___last_data___width 1
+#define reg_iop_dmc_out_rw_intr_mask___last_data___bit 6
+#define reg_iop_dmc_out_rw_intr_mask___trf_lim___lsb 7
+#define reg_iop_dmc_out_rw_intr_mask___trf_lim___width 1
+#define reg_iop_dmc_out_rw_intr_mask___trf_lim___bit 7
+#define reg_iop_dmc_out_rw_intr_mask___cmd_rq___lsb 8
+#define reg_iop_dmc_out_rw_intr_mask___cmd_rq___width 1
+#define reg_iop_dmc_out_rw_intr_mask___cmd_rq___bit 8
+#define reg_iop_dmc_out_rw_intr_mask_offset 84
+
+/* Register rw_ack_intr, scope iop_dmc_out, type rw */
+#define reg_iop_dmc_out_rw_ack_intr___data_md___lsb 0
+#define reg_iop_dmc_out_rw_ack_intr___data_md___width 1
+#define reg_iop_dmc_out_rw_ack_intr___data_md___bit 0
+#define reg_iop_dmc_out_rw_ack_intr___ctxt_md___lsb 1
+#define reg_iop_dmc_out_rw_ack_intr___ctxt_md___width 1
+#define reg_iop_dmc_out_rw_ack_intr___ctxt_md___bit 1
+#define reg_iop_dmc_out_rw_ack_intr___group_md___lsb 2
+#define reg_iop_dmc_out_rw_ack_intr___group_md___width 1
+#define reg_iop_dmc_out_rw_ack_intr___group_md___bit 2
+#define reg_iop_dmc_out_rw_ack_intr___cmd_rdy___lsb 3
+#define reg_iop_dmc_out_rw_ack_intr___cmd_rdy___width 1
+#define reg_iop_dmc_out_rw_ack_intr___cmd_rdy___bit 3
+#define reg_iop_dmc_out_rw_ack_intr___dth___lsb 4
+#define reg_iop_dmc_out_rw_ack_intr___dth___width 1
+#define reg_iop_dmc_out_rw_ack_intr___dth___bit 4
+#define reg_iop_dmc_out_rw_ack_intr___dv___lsb 5
+#define reg_iop_dmc_out_rw_ack_intr___dv___width 1
+#define reg_iop_dmc_out_rw_ack_intr___dv___bit 5
+#define reg_iop_dmc_out_rw_ack_intr___last_data___lsb 6
+#define reg_iop_dmc_out_rw_ack_intr___last_data___width 1
+#define reg_iop_dmc_out_rw_ack_intr___last_data___bit 6
+#define reg_iop_dmc_out_rw_ack_intr___trf_lim___lsb 7
+#define reg_iop_dmc_out_rw_ack_intr___trf_lim___width 1
+#define reg_iop_dmc_out_rw_ack_intr___trf_lim___bit 7
+#define reg_iop_dmc_out_rw_ack_intr___cmd_rq___lsb 8
+#define reg_iop_dmc_out_rw_ack_intr___cmd_rq___width 1
+#define reg_iop_dmc_out_rw_ack_intr___cmd_rq___bit 8
+#define reg_iop_dmc_out_rw_ack_intr_offset 88
+
+/* Register r_intr, scope iop_dmc_out, type r */
+#define reg_iop_dmc_out_r_intr___data_md___lsb 0
+#define reg_iop_dmc_out_r_intr___data_md___width 1
+#define reg_iop_dmc_out_r_intr___data_md___bit 0
+#define reg_iop_dmc_out_r_intr___ctxt_md___lsb 1
+#define reg_iop_dmc_out_r_intr___ctxt_md___width 1
+#define reg_iop_dmc_out_r_intr___ctxt_md___bit 1
+#define reg_iop_dmc_out_r_intr___group_md___lsb 2
+#define reg_iop_dmc_out_r_intr___group_md___width 1
+#define reg_iop_dmc_out_r_intr___group_md___bit 2
+#define reg_iop_dmc_out_r_intr___cmd_rdy___lsb 3
+#define reg_iop_dmc_out_r_intr___cmd_rdy___width 1
+#define reg_iop_dmc_out_r_intr___cmd_rdy___bit 3
+#define reg_iop_dmc_out_r_intr___dth___lsb 4
+#define reg_iop_dmc_out_r_intr___dth___width 1
+#define reg_iop_dmc_out_r_intr___dth___bit 4
+#define reg_iop_dmc_out_r_intr___dv___lsb 5
+#define reg_iop_dmc_out_r_intr___dv___width 1
+#define reg_iop_dmc_out_r_intr___dv___bit 5
+#define reg_iop_dmc_out_r_intr___last_data___lsb 6
+#define reg_iop_dmc_out_r_intr___last_data___width 1
+#define reg_iop_dmc_out_r_intr___last_data___bit 6
+#define reg_iop_dmc_out_r_intr___trf_lim___lsb 7
+#define reg_iop_dmc_out_r_intr___trf_lim___width 1
+#define reg_iop_dmc_out_r_intr___trf_lim___bit 7
+#define reg_iop_dmc_out_r_intr___cmd_rq___lsb 8
+#define reg_iop_dmc_out_r_intr___cmd_rq___width 1
+#define reg_iop_dmc_out_r_intr___cmd_rq___bit 8
+#define reg_iop_dmc_out_r_intr_offset 92
+
+/* Register r_masked_intr, scope iop_dmc_out, type r */
+#define reg_iop_dmc_out_r_masked_intr___data_md___lsb 0
+#define reg_iop_dmc_out_r_masked_intr___data_md___width 1
+#define reg_iop_dmc_out_r_masked_intr___data_md___bit 0
+#define reg_iop_dmc_out_r_masked_intr___ctxt_md___lsb 1
+#define reg_iop_dmc_out_r_masked_intr___ctxt_md___width 1
+#define reg_iop_dmc_out_r_masked_intr___ctxt_md___bit 1
+#define reg_iop_dmc_out_r_masked_intr___group_md___lsb 2
+#define reg_iop_dmc_out_r_masked_intr___group_md___width 1
+#define reg_iop_dmc_out_r_masked_intr___group_md___bit 2
+#define reg_iop_dmc_out_r_masked_intr___cmd_rdy___lsb 3
+#define reg_iop_dmc_out_r_masked_intr___cmd_rdy___width 1
+#define reg_iop_dmc_out_r_masked_intr___cmd_rdy___bit 3
+#define reg_iop_dmc_out_r_masked_intr___dth___lsb 4
+#define reg_iop_dmc_out_r_masked_intr___dth___width 1
+#define reg_iop_dmc_out_r_masked_intr___dth___bit 4
+#define reg_iop_dmc_out_r_masked_intr___dv___lsb 5
+#define reg_iop_dmc_out_r_masked_intr___dv___width 1
+#define reg_iop_dmc_out_r_masked_intr___dv___bit 5
+#define reg_iop_dmc_out_r_masked_intr___last_data___lsb 6
+#define reg_iop_dmc_out_r_masked_intr___last_data___width 1
+#define reg_iop_dmc_out_r_masked_intr___last_data___bit 6
+#define reg_iop_dmc_out_r_masked_intr___trf_lim___lsb 7
+#define reg_iop_dmc_out_r_masked_intr___trf_lim___width 1
+#define reg_iop_dmc_out_r_masked_intr___trf_lim___bit 7
+#define reg_iop_dmc_out_r_masked_intr___cmd_rq___lsb 8
+#define reg_iop_dmc_out_r_masked_intr___cmd_rq___width 1
+#define reg_iop_dmc_out_r_masked_intr___cmd_rq___bit 8
+#define reg_iop_dmc_out_r_masked_intr_offset 96
+
+
+/* Constants */
+#define regk_iop_dmc_out_ack_pkt                  0x00000100
+#define regk_iop_dmc_out_array                    0x00000008
+#define regk_iop_dmc_out_burst                    0x00000020
+#define regk_iop_dmc_out_copy_next                0x00000010
+#define regk_iop_dmc_out_copy_up                  0x00000020
+#define regk_iop_dmc_out_dis_c                    0x00000010
+#define regk_iop_dmc_out_dis_g                    0x00000020
+#define regk_iop_dmc_out_lim1                     0x00000000
+#define regk_iop_dmc_out_lim16                    0x00000004
+#define regk_iop_dmc_out_lim2                     0x00000001
+#define regk_iop_dmc_out_lim32                    0x00000005
+#define regk_iop_dmc_out_lim4                     0x00000002
+#define regk_iop_dmc_out_lim64                    0x00000006
+#define regk_iop_dmc_out_lim8                     0x00000003
+#define regk_iop_dmc_out_load_c                   0x00000200
+#define regk_iop_dmc_out_load_c_n                 0x00000280
+#define regk_iop_dmc_out_load_c_next              0x00000240
+#define regk_iop_dmc_out_load_d                   0x00000140
+#define regk_iop_dmc_out_load_g                   0x00000300
+#define regk_iop_dmc_out_load_g_down              0x000003c0
+#define regk_iop_dmc_out_load_g_next              0x00000340
+#define regk_iop_dmc_out_load_g_up                0x00000380
+#define regk_iop_dmc_out_next_en                  0x00000010
+#define regk_iop_dmc_out_next_pkt                 0x00000010
+#define regk_iop_dmc_out_no                       0x00000000
+#define regk_iop_dmc_out_restore                  0x00000020
+#define regk_iop_dmc_out_rw_cfg_default           0x00000000
+#define regk_iop_dmc_out_rw_ctxt_descr_default    0x00000000
+#define regk_iop_dmc_out_rw_ctxt_descr_md1_default  0x00000000
+#define regk_iop_dmc_out_rw_ctxt_descr_md2_default  0x00000000
+#define regk_iop_dmc_out_rw_data_descr_default    0x00000000
+#define regk_iop_dmc_out_rw_group_descr_default   0x00000000
+#define regk_iop_dmc_out_rw_intr_mask_default     0x00000000
+#define regk_iop_dmc_out_save_down                0x00000020
+#define regk_iop_dmc_out_save_up                  0x00000020
+#define regk_iop_dmc_out_set_reg                  0x00000050
+#define regk_iop_dmc_out_set_w_size1              0x00000190
+#define regk_iop_dmc_out_set_w_size2              0x000001a0
+#define regk_iop_dmc_out_set_w_size4              0x000001c0
+#define regk_iop_dmc_out_store_c                  0x00000002
+#define regk_iop_dmc_out_store_descr              0x00000000
+#define regk_iop_dmc_out_store_g                  0x00000004
+#define regk_iop_dmc_out_store_md                 0x00000001
+#define regk_iop_dmc_out_update_down              0x00000020
+#define regk_iop_dmc_out_yes                      0x00000001
+#endif /* __iop_dmc_out_defs_asm_h */
diff --git a/include/asm-cris/arch-v32/hwregs/iop/asm/iop_fifo_in_defs_asm.h b/include/asm-cris/arch-v32/hwregs/iop/asm/iop_fifo_in_defs_asm.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/iop/asm/iop_fifo_in_defs_asm.h
@@ -0,0 +1,234 @@
+#ifndef __iop_fifo_in_defs_asm_h
+#define __iop_fifo_in_defs_asm_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/io_proc/rtl/iop_fifo_in.r
+ *     id:           <not found>
+ *     last modfied: Mon Apr 11 16:10:07 2005
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c -asm --outfile asm/iop_fifo_in_defs_asm.h ../../inst/io_proc/rtl/iop_fifo_in.r
+ *      id: $Id: iop_fifo_in_defs_asm.h,v 1.5 2005/04/24 18:31:06 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+
+#ifndef REG_FIELD
+#define REG_FIELD( scope, reg, field, value ) \
+  REG_FIELD_X_( value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_FIELD_X_( value, shift ) ((value) << shift)
+#endif
+
+#ifndef REG_STATE
+#define REG_STATE( scope, reg, field, symbolic_value ) \
+  REG_STATE_X_( regk_##scope##_##symbolic_value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_STATE_X_( k, shift ) (k << shift)
+#endif
+
+#ifndef REG_MASK
+#define REG_MASK( scope, reg, field ) \
+  REG_MASK_X_( reg_##scope##_##reg##___##field##___width, reg_##scope##_##reg##___##field##___lsb )
+#define REG_MASK_X_( width, lsb ) (((1 << width)-1) << lsb)
+#endif
+
+#ifndef REG_LSB
+#define REG_LSB( scope, reg, field ) reg_##scope##_##reg##___##field##___lsb
+#endif
+
+#ifndef REG_BIT
+#define REG_BIT( scope, reg, field ) reg_##scope##_##reg##___##field##___bit
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) REG_ADDR_X_(inst, reg_##scope##_##reg##_offset)
+#define REG_ADDR_X_( inst, offs ) ((inst) + offs)
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+         REG_ADDR_VECT_X_(inst, reg_##scope##_##reg##_offset, index, \
+			 STRIDE_##scope##_##reg )
+#define REG_ADDR_VECT_X_( inst, offs, index, stride ) \
+                          ((inst) + offs + (index) * stride)
+#endif
+
+/* Register rw_cfg, scope iop_fifo_in, type rw */
+#define reg_iop_fifo_in_rw_cfg___avail_lim___lsb 0
+#define reg_iop_fifo_in_rw_cfg___avail_lim___width 3
+#define reg_iop_fifo_in_rw_cfg___byte_order___lsb 3
+#define reg_iop_fifo_in_rw_cfg___byte_order___width 2
+#define reg_iop_fifo_in_rw_cfg___trig___lsb 5
+#define reg_iop_fifo_in_rw_cfg___trig___width 2
+#define reg_iop_fifo_in_rw_cfg___last_dis_dif_in___lsb 7
+#define reg_iop_fifo_in_rw_cfg___last_dis_dif_in___width 1
+#define reg_iop_fifo_in_rw_cfg___last_dis_dif_in___bit 7
+#define reg_iop_fifo_in_rw_cfg___mode___lsb 8
+#define reg_iop_fifo_in_rw_cfg___mode___width 2
+#define reg_iop_fifo_in_rw_cfg_offset 0
+
+/* Register rw_ctrl, scope iop_fifo_in, type rw */
+#define reg_iop_fifo_in_rw_ctrl___dif_in_en___lsb 0
+#define reg_iop_fifo_in_rw_ctrl___dif_in_en___width 1
+#define reg_iop_fifo_in_rw_ctrl___dif_in_en___bit 0
+#define reg_iop_fifo_in_rw_ctrl___dif_out_en___lsb 1
+#define reg_iop_fifo_in_rw_ctrl___dif_out_en___width 1
+#define reg_iop_fifo_in_rw_ctrl___dif_out_en___bit 1
+#define reg_iop_fifo_in_rw_ctrl_offset 4
+
+/* Register r_stat, scope iop_fifo_in, type r */
+#define reg_iop_fifo_in_r_stat___avail_bytes___lsb 0
+#define reg_iop_fifo_in_r_stat___avail_bytes___width 4
+#define reg_iop_fifo_in_r_stat___last___lsb 4
+#define reg_iop_fifo_in_r_stat___last___width 8
+#define reg_iop_fifo_in_r_stat___dif_in_en___lsb 12
+#define reg_iop_fifo_in_r_stat___dif_in_en___width 1
+#define reg_iop_fifo_in_r_stat___dif_in_en___bit 12
+#define reg_iop_fifo_in_r_stat___dif_out_en___lsb 13
+#define reg_iop_fifo_in_r_stat___dif_out_en___width 1
+#define reg_iop_fifo_in_r_stat___dif_out_en___bit 13
+#define reg_iop_fifo_in_r_stat_offset 8
+
+/* Register rs_rd1byte, scope iop_fifo_in, type rs */
+#define reg_iop_fifo_in_rs_rd1byte___data___lsb 0
+#define reg_iop_fifo_in_rs_rd1byte___data___width 8
+#define reg_iop_fifo_in_rs_rd1byte_offset 12
+
+/* Register r_rd1byte, scope iop_fifo_in, type r */
+#define reg_iop_fifo_in_r_rd1byte___data___lsb 0
+#define reg_iop_fifo_in_r_rd1byte___data___width 8
+#define reg_iop_fifo_in_r_rd1byte_offset 16
+
+/* Register rs_rd2byte, scope iop_fifo_in, type rs */
+#define reg_iop_fifo_in_rs_rd2byte___data___lsb 0
+#define reg_iop_fifo_in_rs_rd2byte___data___width 16
+#define reg_iop_fifo_in_rs_rd2byte_offset 20
+
+/* Register r_rd2byte, scope iop_fifo_in, type r */
+#define reg_iop_fifo_in_r_rd2byte___data___lsb 0
+#define reg_iop_fifo_in_r_rd2byte___data___width 16
+#define reg_iop_fifo_in_r_rd2byte_offset 24
+
+/* Register rs_rd3byte, scope iop_fifo_in, type rs */
+#define reg_iop_fifo_in_rs_rd3byte___data___lsb 0
+#define reg_iop_fifo_in_rs_rd3byte___data___width 24
+#define reg_iop_fifo_in_rs_rd3byte_offset 28
+
+/* Register r_rd3byte, scope iop_fifo_in, type r */
+#define reg_iop_fifo_in_r_rd3byte___data___lsb 0
+#define reg_iop_fifo_in_r_rd3byte___data___width 24
+#define reg_iop_fifo_in_r_rd3byte_offset 32
+
+/* Register rs_rd4byte, scope iop_fifo_in, type rs */
+#define reg_iop_fifo_in_rs_rd4byte___data___lsb 0
+#define reg_iop_fifo_in_rs_rd4byte___data___width 32
+#define reg_iop_fifo_in_rs_rd4byte_offset 36
+
+/* Register r_rd4byte, scope iop_fifo_in, type r */
+#define reg_iop_fifo_in_r_rd4byte___data___lsb 0
+#define reg_iop_fifo_in_r_rd4byte___data___width 32
+#define reg_iop_fifo_in_r_rd4byte_offset 40
+
+/* Register rw_set_last, scope iop_fifo_in, type rw */
+#define reg_iop_fifo_in_rw_set_last_offset 44
+
+/* Register rw_strb_dif_in, scope iop_fifo_in, type rw */
+#define reg_iop_fifo_in_rw_strb_dif_in___last___lsb 0
+#define reg_iop_fifo_in_rw_strb_dif_in___last___width 2
+#define reg_iop_fifo_in_rw_strb_dif_in_offset 48
+
+/* Register rw_intr_mask, scope iop_fifo_in, type rw */
+#define reg_iop_fifo_in_rw_intr_mask___urun___lsb 0
+#define reg_iop_fifo_in_rw_intr_mask___urun___width 1
+#define reg_iop_fifo_in_rw_intr_mask___urun___bit 0
+#define reg_iop_fifo_in_rw_intr_mask___last_data___lsb 1
+#define reg_iop_fifo_in_rw_intr_mask___last_data___width 1
+#define reg_iop_fifo_in_rw_intr_mask___last_data___bit 1
+#define reg_iop_fifo_in_rw_intr_mask___dav___lsb 2
+#define reg_iop_fifo_in_rw_intr_mask___dav___width 1
+#define reg_iop_fifo_in_rw_intr_mask___dav___bit 2
+#define reg_iop_fifo_in_rw_intr_mask___avail___lsb 3
+#define reg_iop_fifo_in_rw_intr_mask___avail___width 1
+#define reg_iop_fifo_in_rw_intr_mask___avail___bit 3
+#define reg_iop_fifo_in_rw_intr_mask___orun___lsb 4
+#define reg_iop_fifo_in_rw_intr_mask___orun___width 1
+#define reg_iop_fifo_in_rw_intr_mask___orun___bit 4
+#define reg_iop_fifo_in_rw_intr_mask_offset 52
+
+/* Register rw_ack_intr, scope iop_fifo_in, type rw */
+#define reg_iop_fifo_in_rw_ack_intr___urun___lsb 0
+#define reg_iop_fifo_in_rw_ack_intr___urun___width 1
+#define reg_iop_fifo_in_rw_ack_intr___urun___bit 0
+#define reg_iop_fifo_in_rw_ack_intr___last_data___lsb 1
+#define reg_iop_fifo_in_rw_ack_intr___last_data___width 1
+#define reg_iop_fifo_in_rw_ack_intr___last_data___bit 1
+#define reg_iop_fifo_in_rw_ack_intr___dav___lsb 2
+#define reg_iop_fifo_in_rw_ack_intr___dav___width 1
+#define reg_iop_fifo_in_rw_ack_intr___dav___bit 2
+#define reg_iop_fifo_in_rw_ack_intr___avail___lsb 3
+#define reg_iop_fifo_in_rw_ack_intr___avail___width 1
+#define reg_iop_fifo_in_rw_ack_intr___avail___bit 3
+#define reg_iop_fifo_in_rw_ack_intr___orun___lsb 4
+#define reg_iop_fifo_in_rw_ack_intr___orun___width 1
+#define reg_iop_fifo_in_rw_ack_intr___orun___bit 4
+#define reg_iop_fifo_in_rw_ack_intr_offset 56
+
+/* Register r_intr, scope iop_fifo_in, type r */
+#define reg_iop_fifo_in_r_intr___urun___lsb 0
+#define reg_iop_fifo_in_r_intr___urun___width 1
+#define reg_iop_fifo_in_r_intr___urun___bit 0
+#define reg_iop_fifo_in_r_intr___last_data___lsb 1
+#define reg_iop_fifo_in_r_intr___last_data___width 1
+#define reg_iop_fifo_in_r_intr___last_data___bit 1
+#define reg_iop_fifo_in_r_intr___dav___lsb 2
+#define reg_iop_fifo_in_r_intr___dav___width 1
+#define reg_iop_fifo_in_r_intr___dav___bit 2
+#define reg_iop_fifo_in_r_intr___avail___lsb 3
+#define reg_iop_fifo_in_r_intr___avail___width 1
+#define reg_iop_fifo_in_r_intr___avail___bit 3
+#define reg_iop_fifo_in_r_intr___orun___lsb 4
+#define reg_iop_fifo_in_r_intr___orun___width 1
+#define reg_iop_fifo_in_r_intr___orun___bit 4
+#define reg_iop_fifo_in_r_intr_offset 60
+
+/* Register r_masked_intr, scope iop_fifo_in, type r */
+#define reg_iop_fifo_in_r_masked_intr___urun___lsb 0
+#define reg_iop_fifo_in_r_masked_intr___urun___width 1
+#define reg_iop_fifo_in_r_masked_intr___urun___bit 0
+#define reg_iop_fifo_in_r_masked_intr___last_data___lsb 1
+#define reg_iop_fifo_in_r_masked_intr___last_data___width 1
+#define reg_iop_fifo_in_r_masked_intr___last_data___bit 1
+#define reg_iop_fifo_in_r_masked_intr___dav___lsb 2
+#define reg_iop_fifo_in_r_masked_intr___dav___width 1
+#define reg_iop_fifo_in_r_masked_intr___dav___bit 2
+#define reg_iop_fifo_in_r_masked_intr___avail___lsb 3
+#define reg_iop_fifo_in_r_masked_intr___avail___width 1
+#define reg_iop_fifo_in_r_masked_intr___avail___bit 3
+#define reg_iop_fifo_in_r_masked_intr___orun___lsb 4
+#define reg_iop_fifo_in_r_masked_intr___orun___width 1
+#define reg_iop_fifo_in_r_masked_intr___orun___bit 4
+#define reg_iop_fifo_in_r_masked_intr_offset 64
+
+
+/* Constants */
+#define regk_iop_fifo_in_dif_in                   0x00000002
+#define regk_iop_fifo_in_hi                       0x00000000
+#define regk_iop_fifo_in_neg                      0x00000002
+#define regk_iop_fifo_in_no                       0x00000000
+#define regk_iop_fifo_in_order16                  0x00000001
+#define regk_iop_fifo_in_order24                  0x00000002
+#define regk_iop_fifo_in_order32                  0x00000003
+#define regk_iop_fifo_in_order8                   0x00000000
+#define regk_iop_fifo_in_pos                      0x00000001
+#define regk_iop_fifo_in_pos_neg                  0x00000003
+#define regk_iop_fifo_in_rw_cfg_default           0x00000024
+#define regk_iop_fifo_in_rw_ctrl_default          0x00000000
+#define regk_iop_fifo_in_rw_intr_mask_default     0x00000000
+#define regk_iop_fifo_in_rw_set_last_default      0x00000000
+#define regk_iop_fifo_in_rw_strb_dif_in_default   0x00000000
+#define regk_iop_fifo_in_size16                   0x00000002
+#define regk_iop_fifo_in_size24                   0x00000001
+#define regk_iop_fifo_in_size32                   0x00000000
+#define regk_iop_fifo_in_size8                    0x00000003
+#define regk_iop_fifo_in_yes                      0x00000001
+#endif /* __iop_fifo_in_defs_asm_h */
diff --git a/include/asm-cris/arch-v32/hwregs/iop/asm/iop_fifo_in_extra_defs_asm.h b/include/asm-cris/arch-v32/hwregs/iop/asm/iop_fifo_in_extra_defs_asm.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/iop/asm/iop_fifo_in_extra_defs_asm.h
@@ -0,0 +1,155 @@
+#ifndef __iop_fifo_in_extra_defs_asm_h
+#define __iop_fifo_in_extra_defs_asm_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/io_proc/rtl/iop_fifo_in_extra.r
+ *     id:           <not found>
+ *     last modfied: Mon Apr 11 16:10:08 2005
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c -asm --outfile asm/iop_fifo_in_extra_defs_asm.h ../../inst/io_proc/rtl/iop_fifo_in_extra.r
+ *      id: $Id: iop_fifo_in_extra_defs_asm.h,v 1.1 2005/04/24 18:31:06 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+
+#ifndef REG_FIELD
+#define REG_FIELD( scope, reg, field, value ) \
+  REG_FIELD_X_( value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_FIELD_X_( value, shift ) ((value) << shift)
+#endif
+
+#ifndef REG_STATE
+#define REG_STATE( scope, reg, field, symbolic_value ) \
+  REG_STATE_X_( regk_##scope##_##symbolic_value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_STATE_X_( k, shift ) (k << shift)
+#endif
+
+#ifndef REG_MASK
+#define REG_MASK( scope, reg, field ) \
+  REG_MASK_X_( reg_##scope##_##reg##___##field##___width, reg_##scope##_##reg##___##field##___lsb )
+#define REG_MASK_X_( width, lsb ) (((1 << width)-1) << lsb)
+#endif
+
+#ifndef REG_LSB
+#define REG_LSB( scope, reg, field ) reg_##scope##_##reg##___##field##___lsb
+#endif
+
+#ifndef REG_BIT
+#define REG_BIT( scope, reg, field ) reg_##scope##_##reg##___##field##___bit
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) REG_ADDR_X_(inst, reg_##scope##_##reg##_offset)
+#define REG_ADDR_X_( inst, offs ) ((inst) + offs)
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+         REG_ADDR_VECT_X_(inst, reg_##scope##_##reg##_offset, index, \
+			 STRIDE_##scope##_##reg )
+#define REG_ADDR_VECT_X_( inst, offs, index, stride ) \
+                          ((inst) + offs + (index) * stride)
+#endif
+
+/* Register rw_wr_data, scope iop_fifo_in_extra, type rw */
+#define reg_iop_fifo_in_extra_rw_wr_data_offset 0
+
+/* Register r_stat, scope iop_fifo_in_extra, type r */
+#define reg_iop_fifo_in_extra_r_stat___avail_bytes___lsb 0
+#define reg_iop_fifo_in_extra_r_stat___avail_bytes___width 4
+#define reg_iop_fifo_in_extra_r_stat___last___lsb 4
+#define reg_iop_fifo_in_extra_r_stat___last___width 8
+#define reg_iop_fifo_in_extra_r_stat___dif_in_en___lsb 12
+#define reg_iop_fifo_in_extra_r_stat___dif_in_en___width 1
+#define reg_iop_fifo_in_extra_r_stat___dif_in_en___bit 12
+#define reg_iop_fifo_in_extra_r_stat___dif_out_en___lsb 13
+#define reg_iop_fifo_in_extra_r_stat___dif_out_en___width 1
+#define reg_iop_fifo_in_extra_r_stat___dif_out_en___bit 13
+#define reg_iop_fifo_in_extra_r_stat_offset 4
+
+/* Register rw_strb_dif_in, scope iop_fifo_in_extra, type rw */
+#define reg_iop_fifo_in_extra_rw_strb_dif_in___last___lsb 0
+#define reg_iop_fifo_in_extra_rw_strb_dif_in___last___width 2
+#define reg_iop_fifo_in_extra_rw_strb_dif_in_offset 8
+
+/* Register rw_intr_mask, scope iop_fifo_in_extra, type rw */
+#define reg_iop_fifo_in_extra_rw_intr_mask___urun___lsb 0
+#define reg_iop_fifo_in_extra_rw_intr_mask___urun___width 1
+#define reg_iop_fifo_in_extra_rw_intr_mask___urun___bit 0
+#define reg_iop_fifo_in_extra_rw_intr_mask___last_data___lsb 1
+#define reg_iop_fifo_in_extra_rw_intr_mask___last_data___width 1
+#define reg_iop_fifo_in_extra_rw_intr_mask___last_data___bit 1
+#define reg_iop_fifo_in_extra_rw_intr_mask___dav___lsb 2
+#define reg_iop_fifo_in_extra_rw_intr_mask___dav___width 1
+#define reg_iop_fifo_in_extra_rw_intr_mask___dav___bit 2
+#define reg_iop_fifo_in_extra_rw_intr_mask___avail___lsb 3
+#define reg_iop_fifo_in_extra_rw_intr_mask___avail___width 1
+#define reg_iop_fifo_in_extra_rw_intr_mask___avail___bit 3
+#define reg_iop_fifo_in_extra_rw_intr_mask___orun___lsb 4
+#define reg_iop_fifo_in_extra_rw_intr_mask___orun___width 1
+#define reg_iop_fifo_in_extra_rw_intr_mask___orun___bit 4
+#define reg_iop_fifo_in_extra_rw_intr_mask_offset 12
+
+/* Register rw_ack_intr, scope iop_fifo_in_extra, type rw */
+#define reg_iop_fifo_in_extra_rw_ack_intr___urun___lsb 0
+#define reg_iop_fifo_in_extra_rw_ack_intr___urun___width 1
+#define reg_iop_fifo_in_extra_rw_ack_intr___urun___bit 0
+#define reg_iop_fifo_in_extra_rw_ack_intr___last_data___lsb 1
+#define reg_iop_fifo_in_extra_rw_ack_intr___last_data___width 1
+#define reg_iop_fifo_in_extra_rw_ack_intr___last_data___bit 1
+#define reg_iop_fifo_in_extra_rw_ack_intr___dav___lsb 2
+#define reg_iop_fifo_in_extra_rw_ack_intr___dav___width 1
+#define reg_iop_fifo_in_extra_rw_ack_intr___dav___bit 2
+#define reg_iop_fifo_in_extra_rw_ack_intr___avail___lsb 3
+#define reg_iop_fifo_in_extra_rw_ack_intr___avail___width 1
+#define reg_iop_fifo_in_extra_rw_ack_intr___avail___bit 3
+#define reg_iop_fifo_in_extra_rw_ack_intr___orun___lsb 4
+#define reg_iop_fifo_in_extra_rw_ack_intr___orun___width 1
+#define reg_iop_fifo_in_extra_rw_ack_intr___orun___bit 4
+#define reg_iop_fifo_in_extra_rw_ack_intr_offset 16
+
+/* Register r_intr, scope iop_fifo_in_extra, type r */
+#define reg_iop_fifo_in_extra_r_intr___urun___lsb 0
+#define reg_iop_fifo_in_extra_r_intr___urun___width 1
+#define reg_iop_fifo_in_extra_r_intr___urun___bit 0
+#define reg_iop_fifo_in_extra_r_intr___last_data___lsb 1
+#define reg_iop_fifo_in_extra_r_intr___last_data___width 1
+#define reg_iop_fifo_in_extra_r_intr___last_data___bit 1
+#define reg_iop_fifo_in_extra_r_intr___dav___lsb 2
+#define reg_iop_fifo_in_extra_r_intr___dav___width 1
+#define reg_iop_fifo_in_extra_r_intr___dav___bit 2
+#define reg_iop_fifo_in_extra_r_intr___avail___lsb 3
+#define reg_iop_fifo_in_extra_r_intr___avail___width 1
+#define reg_iop_fifo_in_extra_r_intr___avail___bit 3
+#define reg_iop_fifo_in_extra_r_intr___orun___lsb 4
+#define reg_iop_fifo_in_extra_r_intr___orun___width 1
+#define reg_iop_fifo_in_extra_r_intr___orun___bit 4
+#define reg_iop_fifo_in_extra_r_intr_offset 20
+
+/* Register r_masked_intr, scope iop_fifo_in_extra, type r */
+#define reg_iop_fifo_in_extra_r_masked_intr___urun___lsb 0
+#define reg_iop_fifo_in_extra_r_masked_intr___urun___width 1
+#define reg_iop_fifo_in_extra_r_masked_intr___urun___bit 0
+#define reg_iop_fifo_in_extra_r_masked_intr___last_data___lsb 1
+#define reg_iop_fifo_in_extra_r_masked_intr___last_data___width 1
+#define reg_iop_fifo_in_extra_r_masked_intr___last_data___bit 1
+#define reg_iop_fifo_in_extra_r_masked_intr___dav___lsb 2
+#define reg_iop_fifo_in_extra_r_masked_intr___dav___width 1
+#define reg_iop_fifo_in_extra_r_masked_intr___dav___bit 2
+#define reg_iop_fifo_in_extra_r_masked_intr___avail___lsb 3
+#define reg_iop_fifo_in_extra_r_masked_intr___avail___width 1
+#define reg_iop_fifo_in_extra_r_masked_intr___avail___bit 3
+#define reg_iop_fifo_in_extra_r_masked_intr___orun___lsb 4
+#define reg_iop_fifo_in_extra_r_masked_intr___orun___width 1
+#define reg_iop_fifo_in_extra_r_masked_intr___orun___bit 4
+#define reg_iop_fifo_in_extra_r_masked_intr_offset 24
+
+
+/* Constants */
+#define regk_iop_fifo_in_extra_fifo_in            0x00000002
+#define regk_iop_fifo_in_extra_no                 0x00000000
+#define regk_iop_fifo_in_extra_rw_intr_mask_default  0x00000000
+#define regk_iop_fifo_in_extra_yes                0x00000001
+#endif /* __iop_fifo_in_extra_defs_asm_h */
diff --git a/include/asm-cris/arch-v32/hwregs/iop/asm/iop_fifo_out_defs_asm.h b/include/asm-cris/arch-v32/hwregs/iop/asm/iop_fifo_out_defs_asm.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/iop/asm/iop_fifo_out_defs_asm.h
@@ -0,0 +1,254 @@
+#ifndef __iop_fifo_out_defs_asm_h
+#define __iop_fifo_out_defs_asm_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/io_proc/rtl/iop_fifo_out.r
+ *     id:           <not found>
+ *     last modfied: Mon Apr 11 16:10:09 2005
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c -asm --outfile asm/iop_fifo_out_defs_asm.h ../../inst/io_proc/rtl/iop_fifo_out.r
+ *      id: $Id: iop_fifo_out_defs_asm.h,v 1.5 2005/04/24 18:31:06 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+
+#ifndef REG_FIELD
+#define REG_FIELD( scope, reg, field, value ) \
+  REG_FIELD_X_( value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_FIELD_X_( value, shift ) ((value) << shift)
+#endif
+
+#ifndef REG_STATE
+#define REG_STATE( scope, reg, field, symbolic_value ) \
+  REG_STATE_X_( regk_##scope##_##symbolic_value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_STATE_X_( k, shift ) (k << shift)
+#endif
+
+#ifndef REG_MASK
+#define REG_MASK( scope, reg, field ) \
+  REG_MASK_X_( reg_##scope##_##reg##___##field##___width, reg_##scope##_##reg##___##field##___lsb )
+#define REG_MASK_X_( width, lsb ) (((1 << width)-1) << lsb)
+#endif
+
+#ifndef REG_LSB
+#define REG_LSB( scope, reg, field ) reg_##scope##_##reg##___##field##___lsb
+#endif
+
+#ifndef REG_BIT
+#define REG_BIT( scope, reg, field ) reg_##scope##_##reg##___##field##___bit
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) REG_ADDR_X_(inst, reg_##scope##_##reg##_offset)
+#define REG_ADDR_X_( inst, offs ) ((inst) + offs)
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+         REG_ADDR_VECT_X_(inst, reg_##scope##_##reg##_offset, index, \
+			 STRIDE_##scope##_##reg )
+#define REG_ADDR_VECT_X_( inst, offs, index, stride ) \
+                          ((inst) + offs + (index) * stride)
+#endif
+
+/* Register rw_cfg, scope iop_fifo_out, type rw */
+#define reg_iop_fifo_out_rw_cfg___free_lim___lsb 0
+#define reg_iop_fifo_out_rw_cfg___free_lim___width 3
+#define reg_iop_fifo_out_rw_cfg___byte_order___lsb 3
+#define reg_iop_fifo_out_rw_cfg___byte_order___width 2
+#define reg_iop_fifo_out_rw_cfg___trig___lsb 5
+#define reg_iop_fifo_out_rw_cfg___trig___width 2
+#define reg_iop_fifo_out_rw_cfg___last_dis_dif_in___lsb 7
+#define reg_iop_fifo_out_rw_cfg___last_dis_dif_in___width 1
+#define reg_iop_fifo_out_rw_cfg___last_dis_dif_in___bit 7
+#define reg_iop_fifo_out_rw_cfg___mode___lsb 8
+#define reg_iop_fifo_out_rw_cfg___mode___width 2
+#define reg_iop_fifo_out_rw_cfg___delay_out_last___lsb 10
+#define reg_iop_fifo_out_rw_cfg___delay_out_last___width 1
+#define reg_iop_fifo_out_rw_cfg___delay_out_last___bit 10
+#define reg_iop_fifo_out_rw_cfg___last_dis_dif_out___lsb 11
+#define reg_iop_fifo_out_rw_cfg___last_dis_dif_out___width 1
+#define reg_iop_fifo_out_rw_cfg___last_dis_dif_out___bit 11
+#define reg_iop_fifo_out_rw_cfg_offset 0
+
+/* Register rw_ctrl, scope iop_fifo_out, type rw */
+#define reg_iop_fifo_out_rw_ctrl___dif_in_en___lsb 0
+#define reg_iop_fifo_out_rw_ctrl___dif_in_en___width 1
+#define reg_iop_fifo_out_rw_ctrl___dif_in_en___bit 0
+#define reg_iop_fifo_out_rw_ctrl___dif_out_en___lsb 1
+#define reg_iop_fifo_out_rw_ctrl___dif_out_en___width 1
+#define reg_iop_fifo_out_rw_ctrl___dif_out_en___bit 1
+#define reg_iop_fifo_out_rw_ctrl_offset 4
+
+/* Register r_stat, scope iop_fifo_out, type r */
+#define reg_iop_fifo_out_r_stat___avail_bytes___lsb 0
+#define reg_iop_fifo_out_r_stat___avail_bytes___width 4
+#define reg_iop_fifo_out_r_stat___last___lsb 4
+#define reg_iop_fifo_out_r_stat___last___width 8
+#define reg_iop_fifo_out_r_stat___dif_in_en___lsb 12
+#define reg_iop_fifo_out_r_stat___dif_in_en___width 1
+#define reg_iop_fifo_out_r_stat___dif_in_en___bit 12
+#define reg_iop_fifo_out_r_stat___dif_out_en___lsb 13
+#define reg_iop_fifo_out_r_stat___dif_out_en___width 1
+#define reg_iop_fifo_out_r_stat___dif_out_en___bit 13
+#define reg_iop_fifo_out_r_stat___zero_data_last___lsb 14
+#define reg_iop_fifo_out_r_stat___zero_data_last___width 1
+#define reg_iop_fifo_out_r_stat___zero_data_last___bit 14
+#define reg_iop_fifo_out_r_stat_offset 8
+
+/* Register rw_wr1byte, scope iop_fifo_out, type rw */
+#define reg_iop_fifo_out_rw_wr1byte___data___lsb 0
+#define reg_iop_fifo_out_rw_wr1byte___data___width 8
+#define reg_iop_fifo_out_rw_wr1byte_offset 12
+
+/* Register rw_wr2byte, scope iop_fifo_out, type rw */
+#define reg_iop_fifo_out_rw_wr2byte___data___lsb 0
+#define reg_iop_fifo_out_rw_wr2byte___data___width 16
+#define reg_iop_fifo_out_rw_wr2byte_offset 16
+
+/* Register rw_wr3byte, scope iop_fifo_out, type rw */
+#define reg_iop_fifo_out_rw_wr3byte___data___lsb 0
+#define reg_iop_fifo_out_rw_wr3byte___data___width 24
+#define reg_iop_fifo_out_rw_wr3byte_offset 20
+
+/* Register rw_wr4byte, scope iop_fifo_out, type rw */
+#define reg_iop_fifo_out_rw_wr4byte___data___lsb 0
+#define reg_iop_fifo_out_rw_wr4byte___data___width 32
+#define reg_iop_fifo_out_rw_wr4byte_offset 24
+
+/* Register rw_wr1byte_last, scope iop_fifo_out, type rw */
+#define reg_iop_fifo_out_rw_wr1byte_last___data___lsb 0
+#define reg_iop_fifo_out_rw_wr1byte_last___data___width 8
+#define reg_iop_fifo_out_rw_wr1byte_last_offset 28
+
+/* Register rw_wr2byte_last, scope iop_fifo_out, type rw */
+#define reg_iop_fifo_out_rw_wr2byte_last___data___lsb 0
+#define reg_iop_fifo_out_rw_wr2byte_last___data___width 16
+#define reg_iop_fifo_out_rw_wr2byte_last_offset 32
+
+/* Register rw_wr3byte_last, scope iop_fifo_out, type rw */
+#define reg_iop_fifo_out_rw_wr3byte_last___data___lsb 0
+#define reg_iop_fifo_out_rw_wr3byte_last___data___width 24
+#define reg_iop_fifo_out_rw_wr3byte_last_offset 36
+
+/* Register rw_wr4byte_last, scope iop_fifo_out, type rw */
+#define reg_iop_fifo_out_rw_wr4byte_last___data___lsb 0
+#define reg_iop_fifo_out_rw_wr4byte_last___data___width 32
+#define reg_iop_fifo_out_rw_wr4byte_last_offset 40
+
+/* Register rw_set_last, scope iop_fifo_out, type rw */
+#define reg_iop_fifo_out_rw_set_last_offset 44
+
+/* Register rs_rd_data, scope iop_fifo_out, type rs */
+#define reg_iop_fifo_out_rs_rd_data_offset 48
+
+/* Register r_rd_data, scope iop_fifo_out, type r */
+#define reg_iop_fifo_out_r_rd_data_offset 52
+
+/* Register rw_strb_dif_out, scope iop_fifo_out, type rw */
+#define reg_iop_fifo_out_rw_strb_dif_out_offset 56
+
+/* Register rw_intr_mask, scope iop_fifo_out, type rw */
+#define reg_iop_fifo_out_rw_intr_mask___urun___lsb 0
+#define reg_iop_fifo_out_rw_intr_mask___urun___width 1
+#define reg_iop_fifo_out_rw_intr_mask___urun___bit 0
+#define reg_iop_fifo_out_rw_intr_mask___last_data___lsb 1
+#define reg_iop_fifo_out_rw_intr_mask___last_data___width 1
+#define reg_iop_fifo_out_rw_intr_mask___last_data___bit 1
+#define reg_iop_fifo_out_rw_intr_mask___dav___lsb 2
+#define reg_iop_fifo_out_rw_intr_mask___dav___width 1
+#define reg_iop_fifo_out_rw_intr_mask___dav___bit 2
+#define reg_iop_fifo_out_rw_intr_mask___free___lsb 3
+#define reg_iop_fifo_out_rw_intr_mask___free___width 1
+#define reg_iop_fifo_out_rw_intr_mask___free___bit 3
+#define reg_iop_fifo_out_rw_intr_mask___orun___lsb 4
+#define reg_iop_fifo_out_rw_intr_mask___orun___width 1
+#define reg_iop_fifo_out_rw_intr_mask___orun___bit 4
+#define reg_iop_fifo_out_rw_intr_mask_offset 60
+
+/* Register rw_ack_intr, scope iop_fifo_out, type rw */
+#define reg_iop_fifo_out_rw_ack_intr___urun___lsb 0
+#define reg_iop_fifo_out_rw_ack_intr___urun___width 1
+#define reg_iop_fifo_out_rw_ack_intr___urun___bit 0
+#define reg_iop_fifo_out_rw_ack_intr___last_data___lsb 1
+#define reg_iop_fifo_out_rw_ack_intr___last_data___width 1
+#define reg_iop_fifo_out_rw_ack_intr___last_data___bit 1
+#define reg_iop_fifo_out_rw_ack_intr___dav___lsb 2
+#define reg_iop_fifo_out_rw_ack_intr___dav___width 1
+#define reg_iop_fifo_out_rw_ack_intr___dav___bit 2
+#define reg_iop_fifo_out_rw_ack_intr___free___lsb 3
+#define reg_iop_fifo_out_rw_ack_intr___free___width 1
+#define reg_iop_fifo_out_rw_ack_intr___free___bit 3
+#define reg_iop_fifo_out_rw_ack_intr___orun___lsb 4
+#define reg_iop_fifo_out_rw_ack_intr___orun___width 1
+#define reg_iop_fifo_out_rw_ack_intr___orun___bit 4
+#define reg_iop_fifo_out_rw_ack_intr_offset 64
+
+/* Register r_intr, scope iop_fifo_out, type r */
+#define reg_iop_fifo_out_r_intr___urun___lsb 0
+#define reg_iop_fifo_out_r_intr___urun___width 1
+#define reg_iop_fifo_out_r_intr___urun___bit 0
+#define reg_iop_fifo_out_r_intr___last_data___lsb 1
+#define reg_iop_fifo_out_r_intr___last_data___width 1
+#define reg_iop_fifo_out_r_intr___last_data___bit 1
+#define reg_iop_fifo_out_r_intr___dav___lsb 2
+#define reg_iop_fifo_out_r_intr___dav___width 1
+#define reg_iop_fifo_out_r_intr___dav___bit 2
+#define reg_iop_fifo_out_r_intr___free___lsb 3
+#define reg_iop_fifo_out_r_intr___free___width 1
+#define reg_iop_fifo_out_r_intr___free___bit 3
+#define reg_iop_fifo_out_r_intr___orun___lsb 4
+#define reg_iop_fifo_out_r_intr___orun___width 1
+#define reg_iop_fifo_out_r_intr___orun___bit 4
+#define reg_iop_fifo_out_r_intr_offset 68
+
+/* Register r_masked_intr, scope iop_fifo_out, type r */
+#define reg_iop_fifo_out_r_masked_intr___urun___lsb 0
+#define reg_iop_fifo_out_r_masked_intr___urun___width 1
+#define reg_iop_fifo_out_r_masked_intr___urun___bit 0
+#define reg_iop_fifo_out_r_masked_intr___last_data___lsb 1
+#define reg_iop_fifo_out_r_masked_intr___last_data___width 1
+#define reg_iop_fifo_out_r_masked_intr___last_data___bit 1
+#define reg_iop_fifo_out_r_masked_intr___dav___lsb 2
+#define reg_iop_fifo_out_r_masked_intr___dav___width 1
+#define reg_iop_fifo_out_r_masked_intr___dav___bit 2
+#define reg_iop_fifo_out_r_masked_intr___free___lsb 3
+#define reg_iop_fifo_out_r_masked_intr___free___width 1
+#define reg_iop_fifo_out_r_masked_intr___free___bit 3
+#define reg_iop_fifo_out_r_masked_intr___orun___lsb 4
+#define reg_iop_fifo_out_r_masked_intr___orun___width 1
+#define reg_iop_fifo_out_r_masked_intr___orun___bit 4
+#define reg_iop_fifo_out_r_masked_intr_offset 72
+
+
+/* Constants */
+#define regk_iop_fifo_out_hi                      0x00000000
+#define regk_iop_fifo_out_neg                     0x00000002
+#define regk_iop_fifo_out_no                      0x00000000
+#define regk_iop_fifo_out_order16                 0x00000001
+#define regk_iop_fifo_out_order24                 0x00000002
+#define regk_iop_fifo_out_order32                 0x00000003
+#define regk_iop_fifo_out_order8                  0x00000000
+#define regk_iop_fifo_out_pos                     0x00000001
+#define regk_iop_fifo_out_pos_neg                 0x00000003
+#define regk_iop_fifo_out_rw_cfg_default          0x00000024
+#define regk_iop_fifo_out_rw_ctrl_default         0x00000000
+#define regk_iop_fifo_out_rw_intr_mask_default    0x00000000
+#define regk_iop_fifo_out_rw_set_last_default     0x00000000
+#define regk_iop_fifo_out_rw_strb_dif_out_default  0x00000000
+#define regk_iop_fifo_out_rw_wr1byte_default      0x00000000
+#define regk_iop_fifo_out_rw_wr1byte_last_default  0x00000000
+#define regk_iop_fifo_out_rw_wr2byte_default      0x00000000
+#define regk_iop_fifo_out_rw_wr2byte_last_default  0x00000000
+#define regk_iop_fifo_out_rw_wr3byte_default      0x00000000
+#define regk_iop_fifo_out_rw_wr3byte_last_default  0x00000000
+#define regk_iop_fifo_out_rw_wr4byte_default      0x00000000
+#define regk_iop_fifo_out_rw_wr4byte_last_default  0x00000000
+#define regk_iop_fifo_out_size16                  0x00000002
+#define regk_iop_fifo_out_size24                  0x00000001
+#define regk_iop_fifo_out_size32                  0x00000000
+#define regk_iop_fifo_out_size8                   0x00000003
+#define regk_iop_fifo_out_yes                     0x00000001
+#endif /* __iop_fifo_out_defs_asm_h */
diff --git a/include/asm-cris/arch-v32/hwregs/iop/asm/iop_fifo_out_extra_defs_asm.h b/include/asm-cris/arch-v32/hwregs/iop/asm/iop_fifo_out_extra_defs_asm.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/iop/asm/iop_fifo_out_extra_defs_asm.h
@@ -0,0 +1,158 @@
+#ifndef __iop_fifo_out_extra_defs_asm_h
+#define __iop_fifo_out_extra_defs_asm_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/io_proc/rtl/iop_fifo_out_extra.r
+ *     id:           <not found>
+ *     last modfied: Mon Apr 11 16:10:10 2005
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c -asm --outfile asm/iop_fifo_out_extra_defs_asm.h ../../inst/io_proc/rtl/iop_fifo_out_extra.r
+ *      id: $Id: iop_fifo_out_extra_defs_asm.h,v 1.1 2005/04/24 18:31:06 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+
+#ifndef REG_FIELD
+#define REG_FIELD( scope, reg, field, value ) \
+  REG_FIELD_X_( value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_FIELD_X_( value, shift ) ((value) << shift)
+#endif
+
+#ifndef REG_STATE
+#define REG_STATE( scope, reg, field, symbolic_value ) \
+  REG_STATE_X_( regk_##scope##_##symbolic_value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_STATE_X_( k, shift ) (k << shift)
+#endif
+
+#ifndef REG_MASK
+#define REG_MASK( scope, reg, field ) \
+  REG_MASK_X_( reg_##scope##_##reg##___##field##___width, reg_##scope##_##reg##___##field##___lsb )
+#define REG_MASK_X_( width, lsb ) (((1 << width)-1) << lsb)
+#endif
+
+#ifndef REG_LSB
+#define REG_LSB( scope, reg, field ) reg_##scope##_##reg##___##field##___lsb
+#endif
+
+#ifndef REG_BIT
+#define REG_BIT( scope, reg, field ) reg_##scope##_##reg##___##field##___bit
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) REG_ADDR_X_(inst, reg_##scope##_##reg##_offset)
+#define REG_ADDR_X_( inst, offs ) ((inst) + offs)
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+         REG_ADDR_VECT_X_(inst, reg_##scope##_##reg##_offset, index, \
+			 STRIDE_##scope##_##reg )
+#define REG_ADDR_VECT_X_( inst, offs, index, stride ) \
+                          ((inst) + offs + (index) * stride)
+#endif
+
+/* Register rs_rd_data, scope iop_fifo_out_extra, type rs */
+#define reg_iop_fifo_out_extra_rs_rd_data_offset 0
+
+/* Register r_rd_data, scope iop_fifo_out_extra, type r */
+#define reg_iop_fifo_out_extra_r_rd_data_offset 4
+
+/* Register r_stat, scope iop_fifo_out_extra, type r */
+#define reg_iop_fifo_out_extra_r_stat___avail_bytes___lsb 0
+#define reg_iop_fifo_out_extra_r_stat___avail_bytes___width 4
+#define reg_iop_fifo_out_extra_r_stat___last___lsb 4
+#define reg_iop_fifo_out_extra_r_stat___last___width 8
+#define reg_iop_fifo_out_extra_r_stat___dif_in_en___lsb 12
+#define reg_iop_fifo_out_extra_r_stat___dif_in_en___width 1
+#define reg_iop_fifo_out_extra_r_stat___dif_in_en___bit 12
+#define reg_iop_fifo_out_extra_r_stat___dif_out_en___lsb 13
+#define reg_iop_fifo_out_extra_r_stat___dif_out_en___width 1
+#define reg_iop_fifo_out_extra_r_stat___dif_out_en___bit 13
+#define reg_iop_fifo_out_extra_r_stat___zero_data_last___lsb 14
+#define reg_iop_fifo_out_extra_r_stat___zero_data_last___width 1
+#define reg_iop_fifo_out_extra_r_stat___zero_data_last___bit 14
+#define reg_iop_fifo_out_extra_r_stat_offset 8
+
+/* Register rw_strb_dif_out, scope iop_fifo_out_extra, type rw */
+#define reg_iop_fifo_out_extra_rw_strb_dif_out_offset 12
+
+/* Register rw_intr_mask, scope iop_fifo_out_extra, type rw */
+#define reg_iop_fifo_out_extra_rw_intr_mask___urun___lsb 0
+#define reg_iop_fifo_out_extra_rw_intr_mask___urun___width 1
+#define reg_iop_fifo_out_extra_rw_intr_mask___urun___bit 0
+#define reg_iop_fifo_out_extra_rw_intr_mask___last_data___lsb 1
+#define reg_iop_fifo_out_extra_rw_intr_mask___last_data___width 1
+#define reg_iop_fifo_out_extra_rw_intr_mask___last_data___bit 1
+#define reg_iop_fifo_out_extra_rw_intr_mask___dav___lsb 2
+#define reg_iop_fifo_out_extra_rw_intr_mask___dav___width 1
+#define reg_iop_fifo_out_extra_rw_intr_mask___dav___bit 2
+#define reg_iop_fifo_out_extra_rw_intr_mask___free___lsb 3
+#define reg_iop_fifo_out_extra_rw_intr_mask___free___width 1
+#define reg_iop_fifo_out_extra_rw_intr_mask___free___bit 3
+#define reg_iop_fifo_out_extra_rw_intr_mask___orun___lsb 4
+#define reg_iop_fifo_out_extra_rw_intr_mask___orun___width 1
+#define reg_iop_fifo_out_extra_rw_intr_mask___orun___bit 4
+#define reg_iop_fifo_out_extra_rw_intr_mask_offset 16
+
+/* Register rw_ack_intr, scope iop_fifo_out_extra, type rw */
+#define reg_iop_fifo_out_extra_rw_ack_intr___urun___lsb 0
+#define reg_iop_fifo_out_extra_rw_ack_intr___urun___width 1
+#define reg_iop_fifo_out_extra_rw_ack_intr___urun___bit 0
+#define reg_iop_fifo_out_extra_rw_ack_intr___last_data___lsb 1
+#define reg_iop_fifo_out_extra_rw_ack_intr___last_data___width 1
+#define reg_iop_fifo_out_extra_rw_ack_intr___last_data___bit 1
+#define reg_iop_fifo_out_extra_rw_ack_intr___dav___lsb 2
+#define reg_iop_fifo_out_extra_rw_ack_intr___dav___width 1
+#define reg_iop_fifo_out_extra_rw_ack_intr___dav___bit 2
+#define reg_iop_fifo_out_extra_rw_ack_intr___free___lsb 3
+#define reg_iop_fifo_out_extra_rw_ack_intr___free___width 1
+#define reg_iop_fifo_out_extra_rw_ack_intr___free___bit 3
+#define reg_iop_fifo_out_extra_rw_ack_intr___orun___lsb 4
+#define reg_iop_fifo_out_extra_rw_ack_intr___orun___width 1
+#define reg_iop_fifo_out_extra_rw_ack_intr___orun___bit 4
+#define reg_iop_fifo_out_extra_rw_ack_intr_offset 20
+
+/* Register r_intr, scope iop_fifo_out_extra, type r */
+#define reg_iop_fifo_out_extra_r_intr___urun___lsb 0
+#define reg_iop_fifo_out_extra_r_intr___urun___width 1
+#define reg_iop_fifo_out_extra_r_intr___urun___bit 0
+#define reg_iop_fifo_out_extra_r_intr___last_data___lsb 1
+#define reg_iop_fifo_out_extra_r_intr___last_data___width 1
+#define reg_iop_fifo_out_extra_r_intr___last_data___bit 1
+#define reg_iop_fifo_out_extra_r_intr___dav___lsb 2
+#define reg_iop_fifo_out_extra_r_intr___dav___width 1
+#define reg_iop_fifo_out_extra_r_intr___dav___bit 2
+#define reg_iop_fifo_out_extra_r_intr___free___lsb 3
+#define reg_iop_fifo_out_extra_r_intr___free___width 1
+#define reg_iop_fifo_out_extra_r_intr___free___bit 3
+#define reg_iop_fifo_out_extra_r_intr___orun___lsb 4
+#define reg_iop_fifo_out_extra_r_intr___orun___width 1
+#define reg_iop_fifo_out_extra_r_intr___orun___bit 4
+#define reg_iop_fifo_out_extra_r_intr_offset 24
+
+/* Register r_masked_intr, scope iop_fifo_out_extra, type r */
+#define reg_iop_fifo_out_extra_r_masked_intr___urun___lsb 0
+#define reg_iop_fifo_out_extra_r_masked_intr___urun___width 1
+#define reg_iop_fifo_out_extra_r_masked_intr___urun___bit 0
+#define reg_iop_fifo_out_extra_r_masked_intr___last_data___lsb 1
+#define reg_iop_fifo_out_extra_r_masked_intr___last_data___width 1
+#define reg_iop_fifo_out_extra_r_masked_intr___last_data___bit 1
+#define reg_iop_fifo_out_extra_r_masked_intr___dav___lsb 2
+#define reg_iop_fifo_out_extra_r_masked_intr___dav___width 1
+#define reg_iop_fifo_out_extra_r_masked_intr___dav___bit 2
+#define reg_iop_fifo_out_extra_r_masked_intr___free___lsb 3
+#define reg_iop_fifo_out_extra_r_masked_intr___free___width 1
+#define reg_iop_fifo_out_extra_r_masked_intr___free___bit 3
+#define reg_iop_fifo_out_extra_r_masked_intr___orun___lsb 4
+#define reg_iop_fifo_out_extra_r_masked_intr___orun___width 1
+#define reg_iop_fifo_out_extra_r_masked_intr___orun___bit 4
+#define reg_iop_fifo_out_extra_r_masked_intr_offset 28
+
+
+/* Constants */
+#define regk_iop_fifo_out_extra_no                0x00000000
+#define regk_iop_fifo_out_extra_rw_intr_mask_default  0x00000000
+#define regk_iop_fifo_out_extra_yes               0x00000001
+#endif /* __iop_fifo_out_extra_defs_asm_h */
diff --git a/include/asm-cris/arch-v32/hwregs/iop/asm/iop_mpu_defs_asm.h b/include/asm-cris/arch-v32/hwregs/iop/asm/iop_mpu_defs_asm.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/iop/asm/iop_mpu_defs_asm.h
@@ -0,0 +1,177 @@
+#ifndef __iop_mpu_defs_asm_h
+#define __iop_mpu_defs_asm_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/io_proc/rtl/iop_mpu.r
+ *     id:           iop_mpu.r,v 1.30 2005/02/17 08:12:33 niklaspa Exp
+ *     last modfied: Mon Apr 11 16:08:45 2005
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c -asm --outfile asm/iop_mpu_defs_asm.h ../../inst/io_proc/rtl/iop_mpu.r
+ *      id: $Id: iop_mpu_defs_asm.h,v 1.5 2005/04/24 18:31:06 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+
+#ifndef REG_FIELD
+#define REG_FIELD( scope, reg, field, value ) \
+  REG_FIELD_X_( value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_FIELD_X_( value, shift ) ((value) << shift)
+#endif
+
+#ifndef REG_STATE
+#define REG_STATE( scope, reg, field, symbolic_value ) \
+  REG_STATE_X_( regk_##scope##_##symbolic_value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_STATE_X_( k, shift ) (k << shift)
+#endif
+
+#ifndef REG_MASK
+#define REG_MASK( scope, reg, field ) \
+  REG_MASK_X_( reg_##scope##_##reg##___##field##___width, reg_##scope##_##reg##___##field##___lsb )
+#define REG_MASK_X_( width, lsb ) (((1 << width)-1) << lsb)
+#endif
+
+#ifndef REG_LSB
+#define REG_LSB( scope, reg, field ) reg_##scope##_##reg##___##field##___lsb
+#endif
+
+#ifndef REG_BIT
+#define REG_BIT( scope, reg, field ) reg_##scope##_##reg##___##field##___bit
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) REG_ADDR_X_(inst, reg_##scope##_##reg##_offset)
+#define REG_ADDR_X_( inst, offs ) ((inst) + offs)
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+         REG_ADDR_VECT_X_(inst, reg_##scope##_##reg##_offset, index, \
+			 STRIDE_##scope##_##reg )
+#define REG_ADDR_VECT_X_( inst, offs, index, stride ) \
+                          ((inst) + offs + (index) * stride)
+#endif
+
+#define STRIDE_iop_mpu_rw_r 4
+/* Register rw_r, scope iop_mpu, type rw */
+#define reg_iop_mpu_rw_r_offset 0
+
+/* Register rw_ctrl, scope iop_mpu, type rw */
+#define reg_iop_mpu_rw_ctrl___en___lsb 0
+#define reg_iop_mpu_rw_ctrl___en___width 1
+#define reg_iop_mpu_rw_ctrl___en___bit 0
+#define reg_iop_mpu_rw_ctrl_offset 128
+
+/* Register r_pc, scope iop_mpu, type r */
+#define reg_iop_mpu_r_pc___addr___lsb 0
+#define reg_iop_mpu_r_pc___addr___width 12
+#define reg_iop_mpu_r_pc_offset 132
+
+/* Register r_stat, scope iop_mpu, type r */
+#define reg_iop_mpu_r_stat___instr_reg_busy___lsb 0
+#define reg_iop_mpu_r_stat___instr_reg_busy___width 1
+#define reg_iop_mpu_r_stat___instr_reg_busy___bit 0
+#define reg_iop_mpu_r_stat___intr_busy___lsb 1
+#define reg_iop_mpu_r_stat___intr_busy___width 1
+#define reg_iop_mpu_r_stat___intr_busy___bit 1
+#define reg_iop_mpu_r_stat___intr_vect___lsb 2
+#define reg_iop_mpu_r_stat___intr_vect___width 16
+#define reg_iop_mpu_r_stat_offset 136
+
+/* Register rw_instr, scope iop_mpu, type rw */
+#define reg_iop_mpu_rw_instr_offset 140
+
+/* Register rw_immediate, scope iop_mpu, type rw */
+#define reg_iop_mpu_rw_immediate_offset 144
+
+/* Register r_trace, scope iop_mpu, type r */
+#define reg_iop_mpu_r_trace___intr_vect___lsb 0
+#define reg_iop_mpu_r_trace___intr_vect___width 16
+#define reg_iop_mpu_r_trace___pc___lsb 16
+#define reg_iop_mpu_r_trace___pc___width 12
+#define reg_iop_mpu_r_trace___en___lsb 28
+#define reg_iop_mpu_r_trace___en___width 1
+#define reg_iop_mpu_r_trace___en___bit 28
+#define reg_iop_mpu_r_trace___instr_reg_busy___lsb 29
+#define reg_iop_mpu_r_trace___instr_reg_busy___width 1
+#define reg_iop_mpu_r_trace___instr_reg_busy___bit 29
+#define reg_iop_mpu_r_trace___intr_busy___lsb 30
+#define reg_iop_mpu_r_trace___intr_busy___width 1
+#define reg_iop_mpu_r_trace___intr_busy___bit 30
+#define reg_iop_mpu_r_trace_offset 148
+
+/* Register r_wr_stat, scope iop_mpu, type r */
+#define reg_iop_mpu_r_wr_stat___r0___lsb 0
+#define reg_iop_mpu_r_wr_stat___r0___width 1
+#define reg_iop_mpu_r_wr_stat___r0___bit 0
+#define reg_iop_mpu_r_wr_stat___r1___lsb 1
+#define reg_iop_mpu_r_wr_stat___r1___width 1
+#define reg_iop_mpu_r_wr_stat___r1___bit 1
+#define reg_iop_mpu_r_wr_stat___r2___lsb 2
+#define reg_iop_mpu_r_wr_stat___r2___width 1
+#define reg_iop_mpu_r_wr_stat___r2___bit 2
+#define reg_iop_mpu_r_wr_stat___r3___lsb 3
+#define reg_iop_mpu_r_wr_stat___r3___width 1
+#define reg_iop_mpu_r_wr_stat___r3___bit 3
+#define reg_iop_mpu_r_wr_stat___r4___lsb 4
+#define reg_iop_mpu_r_wr_stat___r4___width 1
+#define reg_iop_mpu_r_wr_stat___r4___bit 4
+#define reg_iop_mpu_r_wr_stat___r5___lsb 5
+#define reg_iop_mpu_r_wr_stat___r5___width 1
+#define reg_iop_mpu_r_wr_stat___r5___bit 5
+#define reg_iop_mpu_r_wr_stat___r6___lsb 6
+#define reg_iop_mpu_r_wr_stat___r6___width 1
+#define reg_iop_mpu_r_wr_stat___r6___bit 6
+#define reg_iop_mpu_r_wr_stat___r7___lsb 7
+#define reg_iop_mpu_r_wr_stat___r7___width 1
+#define reg_iop_mpu_r_wr_stat___r7___bit 7
+#define reg_iop_mpu_r_wr_stat___r8___lsb 8
+#define reg_iop_mpu_r_wr_stat___r8___width 1
+#define reg_iop_mpu_r_wr_stat___r8___bit 8
+#define reg_iop_mpu_r_wr_stat___r9___lsb 9
+#define reg_iop_mpu_r_wr_stat___r9___width 1
+#define reg_iop_mpu_r_wr_stat___r9___bit 9
+#define reg_iop_mpu_r_wr_stat___r10___lsb 10
+#define reg_iop_mpu_r_wr_stat___r10___width 1
+#define reg_iop_mpu_r_wr_stat___r10___bit 10
+#define reg_iop_mpu_r_wr_stat___r11___lsb 11
+#define reg_iop_mpu_r_wr_stat___r11___width 1
+#define reg_iop_mpu_r_wr_stat___r11___bit 11
+#define reg_iop_mpu_r_wr_stat___r12___lsb 12
+#define reg_iop_mpu_r_wr_stat___r12___width 1
+#define reg_iop_mpu_r_wr_stat___r12___bit 12
+#define reg_iop_mpu_r_wr_stat___r13___lsb 13
+#define reg_iop_mpu_r_wr_stat___r13___width 1
+#define reg_iop_mpu_r_wr_stat___r13___bit 13
+#define reg_iop_mpu_r_wr_stat___r14___lsb 14
+#define reg_iop_mpu_r_wr_stat___r14___width 1
+#define reg_iop_mpu_r_wr_stat___r14___bit 14
+#define reg_iop_mpu_r_wr_stat___r15___lsb 15
+#define reg_iop_mpu_r_wr_stat___r15___width 1
+#define reg_iop_mpu_r_wr_stat___r15___bit 15
+#define reg_iop_mpu_r_wr_stat_offset 152
+
+#define STRIDE_iop_mpu_rw_thread 4
+/* Register rw_thread, scope iop_mpu, type rw */
+#define reg_iop_mpu_rw_thread___addr___lsb 0
+#define reg_iop_mpu_rw_thread___addr___width 12
+#define reg_iop_mpu_rw_thread_offset 156
+
+#define STRIDE_iop_mpu_rw_intr 4
+/* Register rw_intr, scope iop_mpu, type rw */
+#define reg_iop_mpu_rw_intr___addr___lsb 0
+#define reg_iop_mpu_rw_intr___addr___width 12
+#define reg_iop_mpu_rw_intr_offset 196
+
+
+/* Constants */
+#define regk_iop_mpu_no                           0x00000000
+#define regk_iop_mpu_r_pc_default                 0x00000000
+#define regk_iop_mpu_rw_ctrl_default              0x00000000
+#define regk_iop_mpu_rw_intr_size                 0x00000010
+#define regk_iop_mpu_rw_r_size                    0x00000010
+#define regk_iop_mpu_rw_thread_default            0x00000000
+#define regk_iop_mpu_rw_thread_size               0x00000004
+#define regk_iop_mpu_yes                          0x00000001
+#endif /* __iop_mpu_defs_asm_h */
diff --git a/include/asm-cris/arch-v32/hwregs/iop/asm/iop_reg_space_asm.h b/include/asm-cris/arch-v32/hwregs/iop/asm/iop_reg_space_asm.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/iop/asm/iop_reg_space_asm.h
@@ -0,0 +1,44 @@
+/* Autogenerated Changes here will be lost!
+ * generated by ../gen_sw.pl Mon Apr 11 16:10:18 2005 iop_sw.cfg
+ */
+#define iop_version 0
+#define iop_fifo_in0_extra 64
+#define iop_fifo_in1_extra 128
+#define iop_fifo_out0_extra 192
+#define iop_fifo_out1_extra 256
+#define iop_trigger_grp0 320
+#define iop_trigger_grp1 384
+#define iop_trigger_grp2 448
+#define iop_trigger_grp3 512
+#define iop_trigger_grp4 576
+#define iop_trigger_grp5 640
+#define iop_trigger_grp6 704
+#define iop_trigger_grp7 768
+#define iop_crc_par0 896
+#define iop_crc_par1 1024
+#define iop_dmc_in0 1152
+#define iop_dmc_in1 1280
+#define iop_dmc_out0 1408
+#define iop_dmc_out1 1536
+#define iop_fifo_in0 1664
+#define iop_fifo_in1 1792
+#define iop_fifo_out0 1920
+#define iop_fifo_out1 2048
+#define iop_scrc_in0 2176
+#define iop_scrc_in1 2304
+#define iop_scrc_out0 2432
+#define iop_scrc_out1 2560
+#define iop_timer_grp0 2688
+#define iop_timer_grp1 2816
+#define iop_timer_grp2 2944
+#define iop_timer_grp3 3072
+#define iop_sap_in 3328
+#define iop_sap_out 3584
+#define iop_spu0 3840
+#define iop_spu1 4096
+#define iop_sw_cfg 4352
+#define iop_sw_cpu 4608
+#define iop_sw_mpu 4864
+#define iop_sw_spu0 5120
+#define iop_sw_spu1 5376
+#define iop_mpu 5632
diff --git a/include/asm-cris/arch-v32/hwregs/iop/asm/iop_sap_in_defs_asm.h b/include/asm-cris/arch-v32/hwregs/iop/asm/iop_sap_in_defs_asm.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/iop/asm/iop_sap_in_defs_asm.h
@@ -0,0 +1,182 @@
+#ifndef __iop_sap_in_defs_asm_h
+#define __iop_sap_in_defs_asm_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/io_proc/rtl/iop_sap_in.r
+ *     id:           <not found>
+ *     last modfied: Mon Apr 11 16:08:45 2005
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c -asm --outfile asm/iop_sap_in_defs_asm.h ../../inst/io_proc/rtl/iop_sap_in.r
+ *      id: $Id: iop_sap_in_defs_asm.h,v 1.5 2005/04/24 18:31:06 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+
+#ifndef REG_FIELD
+#define REG_FIELD( scope, reg, field, value ) \
+  REG_FIELD_X_( value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_FIELD_X_( value, shift ) ((value) << shift)
+#endif
+
+#ifndef REG_STATE
+#define REG_STATE( scope, reg, field, symbolic_value ) \
+  REG_STATE_X_( regk_##scope##_##symbolic_value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_STATE_X_( k, shift ) (k << shift)
+#endif
+
+#ifndef REG_MASK
+#define REG_MASK( scope, reg, field ) \
+  REG_MASK_X_( reg_##scope##_##reg##___##field##___width, reg_##scope##_##reg##___##field##___lsb )
+#define REG_MASK_X_( width, lsb ) (((1 << width)-1) << lsb)
+#endif
+
+#ifndef REG_LSB
+#define REG_LSB( scope, reg, field ) reg_##scope##_##reg##___##field##___lsb
+#endif
+
+#ifndef REG_BIT
+#define REG_BIT( scope, reg, field ) reg_##scope##_##reg##___##field##___bit
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) REG_ADDR_X_(inst, reg_##scope##_##reg##_offset)
+#define REG_ADDR_X_( inst, offs ) ((inst) + offs)
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+         REG_ADDR_VECT_X_(inst, reg_##scope##_##reg##_offset, index, \
+			 STRIDE_##scope##_##reg )
+#define REG_ADDR_VECT_X_( inst, offs, index, stride ) \
+                          ((inst) + offs + (index) * stride)
+#endif
+
+/* Register rw_bus0_sync, scope iop_sap_in, type rw */
+#define reg_iop_sap_in_rw_bus0_sync___byte0_sel___lsb 0
+#define reg_iop_sap_in_rw_bus0_sync___byte0_sel___width 2
+#define reg_iop_sap_in_rw_bus0_sync___byte0_ext_src___lsb 2
+#define reg_iop_sap_in_rw_bus0_sync___byte0_ext_src___width 3
+#define reg_iop_sap_in_rw_bus0_sync___byte0_edge___lsb 5
+#define reg_iop_sap_in_rw_bus0_sync___byte0_edge___width 2
+#define reg_iop_sap_in_rw_bus0_sync___byte0_delay___lsb 7
+#define reg_iop_sap_in_rw_bus0_sync___byte0_delay___width 1
+#define reg_iop_sap_in_rw_bus0_sync___byte0_delay___bit 7
+#define reg_iop_sap_in_rw_bus0_sync___byte1_sel___lsb 8
+#define reg_iop_sap_in_rw_bus0_sync___byte1_sel___width 2
+#define reg_iop_sap_in_rw_bus0_sync___byte1_ext_src___lsb 10
+#define reg_iop_sap_in_rw_bus0_sync___byte1_ext_src___width 3
+#define reg_iop_sap_in_rw_bus0_sync___byte1_edge___lsb 13
+#define reg_iop_sap_in_rw_bus0_sync___byte1_edge___width 2
+#define reg_iop_sap_in_rw_bus0_sync___byte1_delay___lsb 15
+#define reg_iop_sap_in_rw_bus0_sync___byte1_delay___width 1
+#define reg_iop_sap_in_rw_bus0_sync___byte1_delay___bit 15
+#define reg_iop_sap_in_rw_bus0_sync___byte2_sel___lsb 16
+#define reg_iop_sap_in_rw_bus0_sync___byte2_sel___width 2
+#define reg_iop_sap_in_rw_bus0_sync___byte2_ext_src___lsb 18
+#define reg_iop_sap_in_rw_bus0_sync___byte2_ext_src___width 3
+#define reg_iop_sap_in_rw_bus0_sync___byte2_edge___lsb 21
+#define reg_iop_sap_in_rw_bus0_sync___byte2_edge___width 2
+#define reg_iop_sap_in_rw_bus0_sync___byte2_delay___lsb 23
+#define reg_iop_sap_in_rw_bus0_sync___byte2_delay___width 1
+#define reg_iop_sap_in_rw_bus0_sync___byte2_delay___bit 23
+#define reg_iop_sap_in_rw_bus0_sync___byte3_sel___lsb 24
+#define reg_iop_sap_in_rw_bus0_sync___byte3_sel___width 2
+#define reg_iop_sap_in_rw_bus0_sync___byte3_ext_src___lsb 26
+#define reg_iop_sap_in_rw_bus0_sync___byte3_ext_src___width 3
+#define reg_iop_sap_in_rw_bus0_sync___byte3_edge___lsb 29
+#define reg_iop_sap_in_rw_bus0_sync___byte3_edge___width 2
+#define reg_iop_sap_in_rw_bus0_sync___byte3_delay___lsb 31
+#define reg_iop_sap_in_rw_bus0_sync___byte3_delay___width 1
+#define reg_iop_sap_in_rw_bus0_sync___byte3_delay___bit 31
+#define reg_iop_sap_in_rw_bus0_sync_offset 0
+
+/* Register rw_bus1_sync, scope iop_sap_in, type rw */
+#define reg_iop_sap_in_rw_bus1_sync___byte0_sel___lsb 0
+#define reg_iop_sap_in_rw_bus1_sync___byte0_sel___width 2
+#define reg_iop_sap_in_rw_bus1_sync___byte0_ext_src___lsb 2
+#define reg_iop_sap_in_rw_bus1_sync___byte0_ext_src___width 3
+#define reg_iop_sap_in_rw_bus1_sync___byte0_edge___lsb 5
+#define reg_iop_sap_in_rw_bus1_sync___byte0_edge___width 2
+#define reg_iop_sap_in_rw_bus1_sync___byte0_delay___lsb 7
+#define reg_iop_sap_in_rw_bus1_sync___byte0_delay___width 1
+#define reg_iop_sap_in_rw_bus1_sync___byte0_delay___bit 7
+#define reg_iop_sap_in_rw_bus1_sync___byte1_sel___lsb 8
+#define reg_iop_sap_in_rw_bus1_sync___byte1_sel___width 2
+#define reg_iop_sap_in_rw_bus1_sync___byte1_ext_src___lsb 10
+#define reg_iop_sap_in_rw_bus1_sync___byte1_ext_src___width 3
+#define reg_iop_sap_in_rw_bus1_sync___byte1_edge___lsb 13
+#define reg_iop_sap_in_rw_bus1_sync___byte1_edge___width 2
+#define reg_iop_sap_in_rw_bus1_sync___byte1_delay___lsb 15
+#define reg_iop_sap_in_rw_bus1_sync___byte1_delay___width 1
+#define reg_iop_sap_in_rw_bus1_sync___byte1_delay___bit 15
+#define reg_iop_sap_in_rw_bus1_sync___byte2_sel___lsb 16
+#define reg_iop_sap_in_rw_bus1_sync___byte2_sel___width 2
+#define reg_iop_sap_in_rw_bus1_sync___byte2_ext_src___lsb 18
+#define reg_iop_sap_in_rw_bus1_sync___byte2_ext_src___width 3
+#define reg_iop_sap_in_rw_bus1_sync___byte2_edge___lsb 21
+#define reg_iop_sap_in_rw_bus1_sync___byte2_edge___width 2
+#define reg_iop_sap_in_rw_bus1_sync___byte2_delay___lsb 23
+#define reg_iop_sap_in_rw_bus1_sync___byte2_delay___width 1
+#define reg_iop_sap_in_rw_bus1_sync___byte2_delay___bit 23
+#define reg_iop_sap_in_rw_bus1_sync___byte3_sel___lsb 24
+#define reg_iop_sap_in_rw_bus1_sync___byte3_sel___width 2
+#define reg_iop_sap_in_rw_bus1_sync___byte3_ext_src___lsb 26
+#define reg_iop_sap_in_rw_bus1_sync___byte3_ext_src___width 3
+#define reg_iop_sap_in_rw_bus1_sync___byte3_edge___lsb 29
+#define reg_iop_sap_in_rw_bus1_sync___byte3_edge___width 2
+#define reg_iop_sap_in_rw_bus1_sync___byte3_delay___lsb 31
+#define reg_iop_sap_in_rw_bus1_sync___byte3_delay___width 1
+#define reg_iop_sap_in_rw_bus1_sync___byte3_delay___bit 31
+#define reg_iop_sap_in_rw_bus1_sync_offset 4
+
+#define STRIDE_iop_sap_in_rw_gio 4
+/* Register rw_gio, scope iop_sap_in, type rw */
+#define reg_iop_sap_in_rw_gio___sync_sel___lsb 0
+#define reg_iop_sap_in_rw_gio___sync_sel___width 2
+#define reg_iop_sap_in_rw_gio___sync_ext_src___lsb 2
+#define reg_iop_sap_in_rw_gio___sync_ext_src___width 3
+#define reg_iop_sap_in_rw_gio___sync_edge___lsb 5
+#define reg_iop_sap_in_rw_gio___sync_edge___width 2
+#define reg_iop_sap_in_rw_gio___delay___lsb 7
+#define reg_iop_sap_in_rw_gio___delay___width 1
+#define reg_iop_sap_in_rw_gio___delay___bit 7
+#define reg_iop_sap_in_rw_gio___logic___lsb 8
+#define reg_iop_sap_in_rw_gio___logic___width 2
+#define reg_iop_sap_in_rw_gio_offset 8
+
+
+/* Constants */
+#define regk_iop_sap_in_and                       0x00000002
+#define regk_iop_sap_in_ext_clk200                0x00000003
+#define regk_iop_sap_in_gio1                      0x00000000
+#define regk_iop_sap_in_gio13                     0x00000005
+#define regk_iop_sap_in_gio18                     0x00000003
+#define regk_iop_sap_in_gio19                     0x00000004
+#define regk_iop_sap_in_gio21                     0x00000006
+#define regk_iop_sap_in_gio23                     0x00000005
+#define regk_iop_sap_in_gio29                     0x00000007
+#define regk_iop_sap_in_gio5                      0x00000004
+#define regk_iop_sap_in_gio6                      0x00000001
+#define regk_iop_sap_in_gio7                      0x00000002
+#define regk_iop_sap_in_inv                       0x00000001
+#define regk_iop_sap_in_neg                       0x00000002
+#define regk_iop_sap_in_no                        0x00000000
+#define regk_iop_sap_in_no_del_ext_clk200         0x00000001
+#define regk_iop_sap_in_none                      0x00000000
+#define regk_iop_sap_in_or                        0x00000003
+#define regk_iop_sap_in_pos                       0x00000001
+#define regk_iop_sap_in_pos_neg                   0x00000003
+#define regk_iop_sap_in_rw_bus0_sync_default      0x02020202
+#define regk_iop_sap_in_rw_bus1_sync_default      0x02020202
+#define regk_iop_sap_in_rw_gio_default            0x00000002
+#define regk_iop_sap_in_rw_gio_size               0x00000020
+#define regk_iop_sap_in_timer_grp0_tmr3           0x00000006
+#define regk_iop_sap_in_timer_grp1_tmr3           0x00000004
+#define regk_iop_sap_in_timer_grp2_tmr3           0x00000005
+#define regk_iop_sap_in_timer_grp3_tmr3           0x00000007
+#define regk_iop_sap_in_tmr_clk200                0x00000000
+#define regk_iop_sap_in_two_clk200                0x00000002
+#define regk_iop_sap_in_yes                       0x00000001
+#endif /* __iop_sap_in_defs_asm_h */
diff --git a/include/asm-cris/arch-v32/hwregs/iop/asm/iop_sap_out_defs_asm.h b/include/asm-cris/arch-v32/hwregs/iop/asm/iop_sap_out_defs_asm.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/iop/asm/iop_sap_out_defs_asm.h
@@ -0,0 +1,346 @@
+#ifndef __iop_sap_out_defs_asm_h
+#define __iop_sap_out_defs_asm_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/io_proc/rtl/iop_sap_out.r
+ *     id:           <not found>
+ *     last modfied: Mon Apr 11 16:08:46 2005
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c -asm --outfile asm/iop_sap_out_defs_asm.h ../../inst/io_proc/rtl/iop_sap_out.r
+ *      id: $Id: iop_sap_out_defs_asm.h,v 1.5 2005/04/24 18:31:06 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+
+#ifndef REG_FIELD
+#define REG_FIELD( scope, reg, field, value ) \
+  REG_FIELD_X_( value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_FIELD_X_( value, shift ) ((value) << shift)
+#endif
+
+#ifndef REG_STATE
+#define REG_STATE( scope, reg, field, symbolic_value ) \
+  REG_STATE_X_( regk_##scope##_##symbolic_value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_STATE_X_( k, shift ) (k << shift)
+#endif
+
+#ifndef REG_MASK
+#define REG_MASK( scope, reg, field ) \
+  REG_MASK_X_( reg_##scope##_##reg##___##field##___width, reg_##scope##_##reg##___##field##___lsb )
+#define REG_MASK_X_( width, lsb ) (((1 << width)-1) << lsb)
+#endif
+
+#ifndef REG_LSB
+#define REG_LSB( scope, reg, field ) reg_##scope##_##reg##___##field##___lsb
+#endif
+
+#ifndef REG_BIT
+#define REG_BIT( scope, reg, field ) reg_##scope##_##reg##___##field##___bit
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) REG_ADDR_X_(inst, reg_##scope##_##reg##_offset)
+#define REG_ADDR_X_( inst, offs ) ((inst) + offs)
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+         REG_ADDR_VECT_X_(inst, reg_##scope##_##reg##_offset, index, \
+			 STRIDE_##scope##_##reg )
+#define REG_ADDR_VECT_X_( inst, offs, index, stride ) \
+                          ((inst) + offs + (index) * stride)
+#endif
+
+/* Register rw_gen_gated, scope iop_sap_out, type rw */
+#define reg_iop_sap_out_rw_gen_gated___clk0_src___lsb 0
+#define reg_iop_sap_out_rw_gen_gated___clk0_src___width 2
+#define reg_iop_sap_out_rw_gen_gated___clk0_gate_src___lsb 2
+#define reg_iop_sap_out_rw_gen_gated___clk0_gate_src___width 2
+#define reg_iop_sap_out_rw_gen_gated___clk0_force_src___lsb 4
+#define reg_iop_sap_out_rw_gen_gated___clk0_force_src___width 3
+#define reg_iop_sap_out_rw_gen_gated___clk1_src___lsb 7
+#define reg_iop_sap_out_rw_gen_gated___clk1_src___width 2
+#define reg_iop_sap_out_rw_gen_gated___clk1_gate_src___lsb 9
+#define reg_iop_sap_out_rw_gen_gated___clk1_gate_src___width 2
+#define reg_iop_sap_out_rw_gen_gated___clk1_force_src___lsb 11
+#define reg_iop_sap_out_rw_gen_gated___clk1_force_src___width 3
+#define reg_iop_sap_out_rw_gen_gated___clk2_src___lsb 14
+#define reg_iop_sap_out_rw_gen_gated___clk2_src___width 2
+#define reg_iop_sap_out_rw_gen_gated___clk2_gate_src___lsb 16
+#define reg_iop_sap_out_rw_gen_gated___clk2_gate_src___width 2
+#define reg_iop_sap_out_rw_gen_gated___clk2_force_src___lsb 18
+#define reg_iop_sap_out_rw_gen_gated___clk2_force_src___width 3
+#define reg_iop_sap_out_rw_gen_gated___clk3_src___lsb 21
+#define reg_iop_sap_out_rw_gen_gated___clk3_src___width 2
+#define reg_iop_sap_out_rw_gen_gated___clk3_gate_src___lsb 23
+#define reg_iop_sap_out_rw_gen_gated___clk3_gate_src___width 2
+#define reg_iop_sap_out_rw_gen_gated___clk3_force_src___lsb 25
+#define reg_iop_sap_out_rw_gen_gated___clk3_force_src___width 3
+#define reg_iop_sap_out_rw_gen_gated_offset 0
+
+/* Register rw_bus0, scope iop_sap_out, type rw */
+#define reg_iop_sap_out_rw_bus0___byte0_clk_sel___lsb 0
+#define reg_iop_sap_out_rw_bus0___byte0_clk_sel___width 3
+#define reg_iop_sap_out_rw_bus0___byte0_gated_clk___lsb 3
+#define reg_iop_sap_out_rw_bus0___byte0_gated_clk___width 2
+#define reg_iop_sap_out_rw_bus0___byte0_clk_inv___lsb 5
+#define reg_iop_sap_out_rw_bus0___byte0_clk_inv___width 1
+#define reg_iop_sap_out_rw_bus0___byte0_clk_inv___bit 5
+#define reg_iop_sap_out_rw_bus0___byte1_clk_sel___lsb 6
+#define reg_iop_sap_out_rw_bus0___byte1_clk_sel___width 3
+#define reg_iop_sap_out_rw_bus0___byte1_gated_clk___lsb 9
+#define reg_iop_sap_out_rw_bus0___byte1_gated_clk___width 2
+#define reg_iop_sap_out_rw_bus0___byte1_clk_inv___lsb 11
+#define reg_iop_sap_out_rw_bus0___byte1_clk_inv___width 1
+#define reg_iop_sap_out_rw_bus0___byte1_clk_inv___bit 11
+#define reg_iop_sap_out_rw_bus0___byte2_clk_sel___lsb 12
+#define reg_iop_sap_out_rw_bus0___byte2_clk_sel___width 3
+#define reg_iop_sap_out_rw_bus0___byte2_gated_clk___lsb 15
+#define reg_iop_sap_out_rw_bus0___byte2_gated_clk___width 2
+#define reg_iop_sap_out_rw_bus0___byte2_clk_inv___lsb 17
+#define reg_iop_sap_out_rw_bus0___byte2_clk_inv___width 1
+#define reg_iop_sap_out_rw_bus0___byte2_clk_inv___bit 17
+#define reg_iop_sap_out_rw_bus0___byte3_clk_sel___lsb 18
+#define reg_iop_sap_out_rw_bus0___byte3_clk_sel___width 3
+#define reg_iop_sap_out_rw_bus0___byte3_gated_clk___lsb 21
+#define reg_iop_sap_out_rw_bus0___byte3_gated_clk___width 2
+#define reg_iop_sap_out_rw_bus0___byte3_clk_inv___lsb 23
+#define reg_iop_sap_out_rw_bus0___byte3_clk_inv___width 1
+#define reg_iop_sap_out_rw_bus0___byte3_clk_inv___bit 23
+#define reg_iop_sap_out_rw_bus0_offset 4
+
+/* Register rw_bus1, scope iop_sap_out, type rw */
+#define reg_iop_sap_out_rw_bus1___byte0_clk_sel___lsb 0
+#define reg_iop_sap_out_rw_bus1___byte0_clk_sel___width 3
+#define reg_iop_sap_out_rw_bus1___byte0_gated_clk___lsb 3
+#define reg_iop_sap_out_rw_bus1___byte0_gated_clk___width 2
+#define reg_iop_sap_out_rw_bus1___byte0_clk_inv___lsb 5
+#define reg_iop_sap_out_rw_bus1___byte0_clk_inv___width 1
+#define reg_iop_sap_out_rw_bus1___byte0_clk_inv___bit 5
+#define reg_iop_sap_out_rw_bus1___byte1_clk_sel___lsb 6
+#define reg_iop_sap_out_rw_bus1___byte1_clk_sel___width 3
+#define reg_iop_sap_out_rw_bus1___byte1_gated_clk___lsb 9
+#define reg_iop_sap_out_rw_bus1___byte1_gated_clk___width 2
+#define reg_iop_sap_out_rw_bus1___byte1_clk_inv___lsb 11
+#define reg_iop_sap_out_rw_bus1___byte1_clk_inv___width 1
+#define reg_iop_sap_out_rw_bus1___byte1_clk_inv___bit 11
+#define reg_iop_sap_out_rw_bus1___byte2_clk_sel___lsb 12
+#define reg_iop_sap_out_rw_bus1___byte2_clk_sel___width 3
+#define reg_iop_sap_out_rw_bus1___byte2_gated_clk___lsb 15
+#define reg_iop_sap_out_rw_bus1___byte2_gated_clk___width 2
+#define reg_iop_sap_out_rw_bus1___byte2_clk_inv___lsb 17
+#define reg_iop_sap_out_rw_bus1___byte2_clk_inv___width 1
+#define reg_iop_sap_out_rw_bus1___byte2_clk_inv___bit 17
+#define reg_iop_sap_out_rw_bus1___byte3_clk_sel___lsb 18
+#define reg_iop_sap_out_rw_bus1___byte3_clk_sel___width 3
+#define reg_iop_sap_out_rw_bus1___byte3_gated_clk___lsb 21
+#define reg_iop_sap_out_rw_bus1___byte3_gated_clk___width 2
+#define reg_iop_sap_out_rw_bus1___byte3_clk_inv___lsb 23
+#define reg_iop_sap_out_rw_bus1___byte3_clk_inv___width 1
+#define reg_iop_sap_out_rw_bus1___byte3_clk_inv___bit 23
+#define reg_iop_sap_out_rw_bus1_offset 8
+
+/* Register rw_bus0_lo_oe, scope iop_sap_out, type rw */
+#define reg_iop_sap_out_rw_bus0_lo_oe___byte0_clk_sel___lsb 0
+#define reg_iop_sap_out_rw_bus0_lo_oe___byte0_clk_sel___width 3
+#define reg_iop_sap_out_rw_bus0_lo_oe___byte0_clk_ext___lsb 3
+#define reg_iop_sap_out_rw_bus0_lo_oe___byte0_clk_ext___width 3
+#define reg_iop_sap_out_rw_bus0_lo_oe___byte0_gated_clk___lsb 6
+#define reg_iop_sap_out_rw_bus0_lo_oe___byte0_gated_clk___width 2
+#define reg_iop_sap_out_rw_bus0_lo_oe___byte0_clk_inv___lsb 8
+#define reg_iop_sap_out_rw_bus0_lo_oe___byte0_clk_inv___width 1
+#define reg_iop_sap_out_rw_bus0_lo_oe___byte0_clk_inv___bit 8
+#define reg_iop_sap_out_rw_bus0_lo_oe___byte0_logic___lsb 9
+#define reg_iop_sap_out_rw_bus0_lo_oe___byte0_logic___width 2
+#define reg_iop_sap_out_rw_bus0_lo_oe___byte1_clk_sel___lsb 11
+#define reg_iop_sap_out_rw_bus0_lo_oe___byte1_clk_sel___width 3
+#define reg_iop_sap_out_rw_bus0_lo_oe___byte1_clk_ext___lsb 14
+#define reg_iop_sap_out_rw_bus0_lo_oe___byte1_clk_ext___width 3
+#define reg_iop_sap_out_rw_bus0_lo_oe___byte1_gated_clk___lsb 17
+#define reg_iop_sap_out_rw_bus0_lo_oe___byte1_gated_clk___width 2
+#define reg_iop_sap_out_rw_bus0_lo_oe___byte1_clk_inv___lsb 19
+#define reg_iop_sap_out_rw_bus0_lo_oe___byte1_clk_inv___width 1
+#define reg_iop_sap_out_rw_bus0_lo_oe___byte1_clk_inv___bit 19
+#define reg_iop_sap_out_rw_bus0_lo_oe___byte1_logic___lsb 20
+#define reg_iop_sap_out_rw_bus0_lo_oe___byte1_logic___width 2
+#define reg_iop_sap_out_rw_bus0_lo_oe_offset 12
+
+/* Register rw_bus0_hi_oe, scope iop_sap_out, type rw */
+#define reg_iop_sap_out_rw_bus0_hi_oe___byte2_clk_sel___lsb 0
+#define reg_iop_sap_out_rw_bus0_hi_oe___byte2_clk_sel___width 3
+#define reg_iop_sap_out_rw_bus0_hi_oe___byte2_clk_ext___lsb 3
+#define reg_iop_sap_out_rw_bus0_hi_oe___byte2_clk_ext___width 3
+#define reg_iop_sap_out_rw_bus0_hi_oe___byte2_gated_clk___lsb 6
+#define reg_iop_sap_out_rw_bus0_hi_oe___byte2_gated_clk___width 2
+#define reg_iop_sap_out_rw_bus0_hi_oe___byte2_clk_inv___lsb 8
+#define reg_iop_sap_out_rw_bus0_hi_oe___byte2_clk_inv___width 1
+#define reg_iop_sap_out_rw_bus0_hi_oe___byte2_clk_inv___bit 8
+#define reg_iop_sap_out_rw_bus0_hi_oe___byte2_logic___lsb 9
+#define reg_iop_sap_out_rw_bus0_hi_oe___byte2_logic___width 2
+#define reg_iop_sap_out_rw_bus0_hi_oe___byte3_clk_sel___lsb 11
+#define reg_iop_sap_out_rw_bus0_hi_oe___byte3_clk_sel___width 3
+#define reg_iop_sap_out_rw_bus0_hi_oe___byte3_clk_ext___lsb 14
+#define reg_iop_sap_out_rw_bus0_hi_oe___byte3_clk_ext___width 3
+#define reg_iop_sap_out_rw_bus0_hi_oe___byte3_gated_clk___lsb 17
+#define reg_iop_sap_out_rw_bus0_hi_oe___byte3_gated_clk___width 2
+#define reg_iop_sap_out_rw_bus0_hi_oe___byte3_clk_inv___lsb 19
+#define reg_iop_sap_out_rw_bus0_hi_oe___byte3_clk_inv___width 1
+#define reg_iop_sap_out_rw_bus0_hi_oe___byte3_clk_inv___bit 19
+#define reg_iop_sap_out_rw_bus0_hi_oe___byte3_logic___lsb 20
+#define reg_iop_sap_out_rw_bus0_hi_oe___byte3_logic___width 2
+#define reg_iop_sap_out_rw_bus0_hi_oe_offset 16
+
+/* Register rw_bus1_lo_oe, scope iop_sap_out, type rw */
+#define reg_iop_sap_out_rw_bus1_lo_oe___byte0_clk_sel___lsb 0
+#define reg_iop_sap_out_rw_bus1_lo_oe___byte0_clk_sel___width 3
+#define reg_iop_sap_out_rw_bus1_lo_oe___byte0_clk_ext___lsb 3
+#define reg_iop_sap_out_rw_bus1_lo_oe___byte0_clk_ext___width 3
+#define reg_iop_sap_out_rw_bus1_lo_oe___byte0_gated_clk___lsb 6
+#define reg_iop_sap_out_rw_bus1_lo_oe___byte0_gated_clk___width 2
+#define reg_iop_sap_out_rw_bus1_lo_oe___byte0_clk_inv___lsb 8
+#define reg_iop_sap_out_rw_bus1_lo_oe___byte0_clk_inv___width 1
+#define reg_iop_sap_out_rw_bus1_lo_oe___byte0_clk_inv___bit 8
+#define reg_iop_sap_out_rw_bus1_lo_oe___byte0_logic___lsb 9
+#define reg_iop_sap_out_rw_bus1_lo_oe___byte0_logic___width 2
+#define reg_iop_sap_out_rw_bus1_lo_oe___byte1_clk_sel___lsb 11
+#define reg_iop_sap_out_rw_bus1_lo_oe___byte1_clk_sel___width 3
+#define reg_iop_sap_out_rw_bus1_lo_oe___byte1_clk_ext___lsb 14
+#define reg_iop_sap_out_rw_bus1_lo_oe___byte1_clk_ext___width 3
+#define reg_iop_sap_out_rw_bus1_lo_oe___byte1_gated_clk___lsb 17
+#define reg_iop_sap_out_rw_bus1_lo_oe___byte1_gated_clk___width 2
+#define reg_iop_sap_out_rw_bus1_lo_oe___byte1_clk_inv___lsb 19
+#define reg_iop_sap_out_rw_bus1_lo_oe___byte1_clk_inv___width 1
+#define reg_iop_sap_out_rw_bus1_lo_oe___byte1_clk_inv___bit 19
+#define reg_iop_sap_out_rw_bus1_lo_oe___byte1_logic___lsb 20
+#define reg_iop_sap_out_rw_bus1_lo_oe___byte1_logic___width 2
+#define reg_iop_sap_out_rw_bus1_lo_oe_offset 20
+
+/* Register rw_bus1_hi_oe, scope iop_sap_out, type rw */
+#define reg_iop_sap_out_rw_bus1_hi_oe___byte2_clk_sel___lsb 0
+#define reg_iop_sap_out_rw_bus1_hi_oe___byte2_clk_sel___width 3
+#define reg_iop_sap_out_rw_bus1_hi_oe___byte2_clk_ext___lsb 3
+#define reg_iop_sap_out_rw_bus1_hi_oe___byte2_clk_ext___width 3
+#define reg_iop_sap_out_rw_bus1_hi_oe___byte2_gated_clk___lsb 6
+#define reg_iop_sap_out_rw_bus1_hi_oe___byte2_gated_clk___width 2
+#define reg_iop_sap_out_rw_bus1_hi_oe___byte2_clk_inv___lsb 8
+#define reg_iop_sap_out_rw_bus1_hi_oe___byte2_clk_inv___width 1
+#define reg_iop_sap_out_rw_bus1_hi_oe___byte2_clk_inv___bit 8
+#define reg_iop_sap_out_rw_bus1_hi_oe___byte2_logic___lsb 9
+#define reg_iop_sap_out_rw_bus1_hi_oe___byte2_logic___width 2
+#define reg_iop_sap_out_rw_bus1_hi_oe___byte3_clk_sel___lsb 11
+#define reg_iop_sap_out_rw_bus1_hi_oe___byte3_clk_sel___width 3
+#define reg_iop_sap_out_rw_bus1_hi_oe___byte3_clk_ext___lsb 14
+#define reg_iop_sap_out_rw_bus1_hi_oe___byte3_clk_ext___width 3
+#define reg_iop_sap_out_rw_bus1_hi_oe___byte3_gated_clk___lsb 17
+#define reg_iop_sap_out_rw_bus1_hi_oe___byte3_gated_clk___width 2
+#define reg_iop_sap_out_rw_bus1_hi_oe___byte3_clk_inv___lsb 19
+#define reg_iop_sap_out_rw_bus1_hi_oe___byte3_clk_inv___width 1
+#define reg_iop_sap_out_rw_bus1_hi_oe___byte3_clk_inv___bit 19
+#define reg_iop_sap_out_rw_bus1_hi_oe___byte3_logic___lsb 20
+#define reg_iop_sap_out_rw_bus1_hi_oe___byte3_logic___width 2
+#define reg_iop_sap_out_rw_bus1_hi_oe_offset 24
+
+#define STRIDE_iop_sap_out_rw_gio 4
+/* Register rw_gio, scope iop_sap_out, type rw */
+#define reg_iop_sap_out_rw_gio___out_clk_sel___lsb 0
+#define reg_iop_sap_out_rw_gio___out_clk_sel___width 3
+#define reg_iop_sap_out_rw_gio___out_clk_ext___lsb 3
+#define reg_iop_sap_out_rw_gio___out_clk_ext___width 4
+#define reg_iop_sap_out_rw_gio___out_gated_clk___lsb 7
+#define reg_iop_sap_out_rw_gio___out_gated_clk___width 2
+#define reg_iop_sap_out_rw_gio___out_clk_inv___lsb 9
+#define reg_iop_sap_out_rw_gio___out_clk_inv___width 1
+#define reg_iop_sap_out_rw_gio___out_clk_inv___bit 9
+#define reg_iop_sap_out_rw_gio___out_logic___lsb 10
+#define reg_iop_sap_out_rw_gio___out_logic___width 1
+#define reg_iop_sap_out_rw_gio___out_logic___bit 10
+#define reg_iop_sap_out_rw_gio___oe_clk_sel___lsb 11
+#define reg_iop_sap_out_rw_gio___oe_clk_sel___width 3
+#define reg_iop_sap_out_rw_gio___oe_clk_ext___lsb 14
+#define reg_iop_sap_out_rw_gio___oe_clk_ext___width 3
+#define reg_iop_sap_out_rw_gio___oe_gated_clk___lsb 17
+#define reg_iop_sap_out_rw_gio___oe_gated_clk___width 2
+#define reg_iop_sap_out_rw_gio___oe_clk_inv___lsb 19
+#define reg_iop_sap_out_rw_gio___oe_clk_inv___width 1
+#define reg_iop_sap_out_rw_gio___oe_clk_inv___bit 19
+#define reg_iop_sap_out_rw_gio___oe_logic___lsb 20
+#define reg_iop_sap_out_rw_gio___oe_logic___width 2
+#define reg_iop_sap_out_rw_gio_offset 28
+
+
+/* Constants */
+#define regk_iop_sap_out_and                      0x00000002
+#define regk_iop_sap_out_clk0                     0x00000000
+#define regk_iop_sap_out_clk1                     0x00000001
+#define regk_iop_sap_out_clk12                    0x00000002
+#define regk_iop_sap_out_clk2                     0x00000002
+#define regk_iop_sap_out_clk200                   0x00000001
+#define regk_iop_sap_out_clk3                     0x00000003
+#define regk_iop_sap_out_ext                      0x00000003
+#define regk_iop_sap_out_gated                    0x00000004
+#define regk_iop_sap_out_gio1                     0x00000000
+#define regk_iop_sap_out_gio13                    0x00000002
+#define regk_iop_sap_out_gio13_clk                0x0000000c
+#define regk_iop_sap_out_gio15                    0x00000001
+#define regk_iop_sap_out_gio18                    0x00000003
+#define regk_iop_sap_out_gio18_clk                0x0000000d
+#define regk_iop_sap_out_gio1_clk                 0x00000008
+#define regk_iop_sap_out_gio21_clk                0x0000000e
+#define regk_iop_sap_out_gio23                    0x00000002
+#define regk_iop_sap_out_gio29_clk                0x0000000f
+#define regk_iop_sap_out_gio31                    0x00000003
+#define regk_iop_sap_out_gio5                     0x00000001
+#define regk_iop_sap_out_gio5_clk                 0x00000009
+#define regk_iop_sap_out_gio6_clk                 0x0000000a
+#define regk_iop_sap_out_gio7                     0x00000000
+#define regk_iop_sap_out_gio7_clk                 0x0000000b
+#define regk_iop_sap_out_gio_in13                 0x00000001
+#define regk_iop_sap_out_gio_in21                 0x00000002
+#define regk_iop_sap_out_gio_in29                 0x00000003
+#define regk_iop_sap_out_gio_in5                  0x00000000
+#define regk_iop_sap_out_inv                      0x00000001
+#define regk_iop_sap_out_nand                     0x00000003
+#define regk_iop_sap_out_no                       0x00000000
+#define regk_iop_sap_out_none                     0x00000000
+#define regk_iop_sap_out_rw_bus0_default          0x00000000
+#define regk_iop_sap_out_rw_bus0_hi_oe_default    0x00000000
+#define regk_iop_sap_out_rw_bus0_lo_oe_default    0x00000000
+#define regk_iop_sap_out_rw_bus1_default          0x00000000
+#define regk_iop_sap_out_rw_bus1_hi_oe_default    0x00000000
+#define regk_iop_sap_out_rw_bus1_lo_oe_default    0x00000000
+#define regk_iop_sap_out_rw_gen_gated_default     0x00000000
+#define regk_iop_sap_out_rw_gio_default           0x00000000
+#define regk_iop_sap_out_rw_gio_size              0x00000020
+#define regk_iop_sap_out_spu0_gio0                0x00000002
+#define regk_iop_sap_out_spu0_gio1                0x00000003
+#define regk_iop_sap_out_spu0_gio12               0x00000004
+#define regk_iop_sap_out_spu0_gio13               0x00000004
+#define regk_iop_sap_out_spu0_gio14               0x00000004
+#define regk_iop_sap_out_spu0_gio15               0x00000004
+#define regk_iop_sap_out_spu0_gio2                0x00000002
+#define regk_iop_sap_out_spu0_gio3                0x00000003
+#define regk_iop_sap_out_spu0_gio4                0x00000002
+#define regk_iop_sap_out_spu0_gio5                0x00000003
+#define regk_iop_sap_out_spu0_gio6                0x00000002
+#define regk_iop_sap_out_spu0_gio7                0x00000003
+#define regk_iop_sap_out_spu1_gio0                0x00000005
+#define regk_iop_sap_out_spu1_gio1                0x00000006
+#define regk_iop_sap_out_spu1_gio12               0x00000007
+#define regk_iop_sap_out_spu1_gio13               0x00000007
+#define regk_iop_sap_out_spu1_gio14               0x00000007
+#define regk_iop_sap_out_spu1_gio15               0x00000007
+#define regk_iop_sap_out_spu1_gio2                0x00000005
+#define regk_iop_sap_out_spu1_gio3                0x00000006
+#define regk_iop_sap_out_spu1_gio4                0x00000005
+#define regk_iop_sap_out_spu1_gio5                0x00000006
+#define regk_iop_sap_out_spu1_gio6                0x00000005
+#define regk_iop_sap_out_spu1_gio7                0x00000006
+#define regk_iop_sap_out_timer_grp0_tmr2          0x00000004
+#define regk_iop_sap_out_timer_grp1_tmr2          0x00000005
+#define regk_iop_sap_out_timer_grp2_tmr2          0x00000006
+#define regk_iop_sap_out_timer_grp3_tmr2          0x00000007
+#define regk_iop_sap_out_tmr                      0x00000005
+#define regk_iop_sap_out_yes                      0x00000001
+#endif /* __iop_sap_out_defs_asm_h */
diff --git a/include/asm-cris/arch-v32/hwregs/iop/asm/iop_scrc_in_defs_asm.h b/include/asm-cris/arch-v32/hwregs/iop/asm/iop_scrc_in_defs_asm.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/iop/asm/iop_scrc_in_defs_asm.h
@@ -0,0 +1,111 @@
+#ifndef __iop_scrc_in_defs_asm_h
+#define __iop_scrc_in_defs_asm_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/io_proc/rtl/iop_scrc_in.r
+ *     id:           iop_scrc_in.r,v 1.10 2005/02/16 09:13:58 niklaspa Exp
+ *     last modfied: Mon Apr 11 16:08:46 2005
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c -asm --outfile asm/iop_scrc_in_defs_asm.h ../../inst/io_proc/rtl/iop_scrc_in.r
+ *      id: $Id: iop_scrc_in_defs_asm.h,v 1.5 2005/04/24 18:31:06 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+
+#ifndef REG_FIELD
+#define REG_FIELD( scope, reg, field, value ) \
+  REG_FIELD_X_( value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_FIELD_X_( value, shift ) ((value) << shift)
+#endif
+
+#ifndef REG_STATE
+#define REG_STATE( scope, reg, field, symbolic_value ) \
+  REG_STATE_X_( regk_##scope##_##symbolic_value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_STATE_X_( k, shift ) (k << shift)
+#endif
+
+#ifndef REG_MASK
+#define REG_MASK( scope, reg, field ) \
+  REG_MASK_X_( reg_##scope##_##reg##___##field##___width, reg_##scope##_##reg##___##field##___lsb )
+#define REG_MASK_X_( width, lsb ) (((1 << width)-1) << lsb)
+#endif
+
+#ifndef REG_LSB
+#define REG_LSB( scope, reg, field ) reg_##scope##_##reg##___##field##___lsb
+#endif
+
+#ifndef REG_BIT
+#define REG_BIT( scope, reg, field ) reg_##scope##_##reg##___##field##___bit
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) REG_ADDR_X_(inst, reg_##scope##_##reg##_offset)
+#define REG_ADDR_X_( inst, offs ) ((inst) + offs)
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+         REG_ADDR_VECT_X_(inst, reg_##scope##_##reg##_offset, index, \
+			 STRIDE_##scope##_##reg )
+#define REG_ADDR_VECT_X_( inst, offs, index, stride ) \
+                          ((inst) + offs + (index) * stride)
+#endif
+
+/* Register rw_cfg, scope iop_scrc_in, type rw */
+#define reg_iop_scrc_in_rw_cfg___trig___lsb 0
+#define reg_iop_scrc_in_rw_cfg___trig___width 2
+#define reg_iop_scrc_in_rw_cfg_offset 0
+
+/* Register rw_ctrl, scope iop_scrc_in, type rw */
+#define reg_iop_scrc_in_rw_ctrl___dif_in_en___lsb 0
+#define reg_iop_scrc_in_rw_ctrl___dif_in_en___width 1
+#define reg_iop_scrc_in_rw_ctrl___dif_in_en___bit 0
+#define reg_iop_scrc_in_rw_ctrl_offset 4
+
+/* Register r_stat, scope iop_scrc_in, type r */
+#define reg_iop_scrc_in_r_stat___err___lsb 0
+#define reg_iop_scrc_in_r_stat___err___width 1
+#define reg_iop_scrc_in_r_stat___err___bit 0
+#define reg_iop_scrc_in_r_stat_offset 8
+
+/* Register rw_init_crc, scope iop_scrc_in, type rw */
+#define reg_iop_scrc_in_rw_init_crc_offset 12
+
+/* Register rs_computed_crc, scope iop_scrc_in, type rs */
+#define reg_iop_scrc_in_rs_computed_crc_offset 16
+
+/* Register r_computed_crc, scope iop_scrc_in, type r */
+#define reg_iop_scrc_in_r_computed_crc_offset 20
+
+/* Register rw_crc, scope iop_scrc_in, type rw */
+#define reg_iop_scrc_in_rw_crc_offset 24
+
+/* Register rw_correct_crc, scope iop_scrc_in, type rw */
+#define reg_iop_scrc_in_rw_correct_crc_offset 28
+
+/* Register rw_wr1bit, scope iop_scrc_in, type rw */
+#define reg_iop_scrc_in_rw_wr1bit___data___lsb 0
+#define reg_iop_scrc_in_rw_wr1bit___data___width 2
+#define reg_iop_scrc_in_rw_wr1bit___last___lsb 2
+#define reg_iop_scrc_in_rw_wr1bit___last___width 2
+#define reg_iop_scrc_in_rw_wr1bit_offset 32
+
+
+/* Constants */
+#define regk_iop_scrc_in_dif_in                   0x00000002
+#define regk_iop_scrc_in_hi                       0x00000000
+#define regk_iop_scrc_in_neg                      0x00000002
+#define regk_iop_scrc_in_no                       0x00000000
+#define regk_iop_scrc_in_pos                      0x00000001
+#define regk_iop_scrc_in_pos_neg                  0x00000003
+#define regk_iop_scrc_in_r_computed_crc_default   0x00000000
+#define regk_iop_scrc_in_rs_computed_crc_default  0x00000000
+#define regk_iop_scrc_in_rw_cfg_default           0x00000000
+#define regk_iop_scrc_in_rw_ctrl_default          0x00000000
+#define regk_iop_scrc_in_rw_init_crc_default      0x00000000
+#define regk_iop_scrc_in_set0                     0x00000000
+#define regk_iop_scrc_in_set1                     0x00000001
+#define regk_iop_scrc_in_yes                      0x00000001
+#endif /* __iop_scrc_in_defs_asm_h */
diff --git a/include/asm-cris/arch-v32/hwregs/iop/asm/iop_scrc_out_defs_asm.h b/include/asm-cris/arch-v32/hwregs/iop/asm/iop_scrc_out_defs_asm.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/iop/asm/iop_scrc_out_defs_asm.h
@@ -0,0 +1,105 @@
+#ifndef __iop_scrc_out_defs_asm_h
+#define __iop_scrc_out_defs_asm_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/io_proc/rtl/iop_scrc_out.r
+ *     id:           iop_scrc_out.r,v 1.11 2005/02/16 09:13:38 niklaspa Exp
+ *     last modfied: Mon Apr 11 16:08:46 2005
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c -asm --outfile asm/iop_scrc_out_defs_asm.h ../../inst/io_proc/rtl/iop_scrc_out.r
+ *      id: $Id: iop_scrc_out_defs_asm.h,v 1.5 2005/04/24 18:31:06 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+
+#ifndef REG_FIELD
+#define REG_FIELD( scope, reg, field, value ) \
+  REG_FIELD_X_( value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_FIELD_X_( value, shift ) ((value) << shift)
+#endif
+
+#ifndef REG_STATE
+#define REG_STATE( scope, reg, field, symbolic_value ) \
+  REG_STATE_X_( regk_##scope##_##symbolic_value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_STATE_X_( k, shift ) (k << shift)
+#endif
+
+#ifndef REG_MASK
+#define REG_MASK( scope, reg, field ) \
+  REG_MASK_X_( reg_##scope##_##reg##___##field##___width, reg_##scope##_##reg##___##field##___lsb )
+#define REG_MASK_X_( width, lsb ) (((1 << width)-1) << lsb)
+#endif
+
+#ifndef REG_LSB
+#define REG_LSB( scope, reg, field ) reg_##scope##_##reg##___##field##___lsb
+#endif
+
+#ifndef REG_BIT
+#define REG_BIT( scope, reg, field ) reg_##scope##_##reg##___##field##___bit
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) REG_ADDR_X_(inst, reg_##scope##_##reg##_offset)
+#define REG_ADDR_X_( inst, offs ) ((inst) + offs)
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+         REG_ADDR_VECT_X_(inst, reg_##scope##_##reg##_offset, index, \
+			 STRIDE_##scope##_##reg )
+#define REG_ADDR_VECT_X_( inst, offs, index, stride ) \
+                          ((inst) + offs + (index) * stride)
+#endif
+
+/* Register rw_cfg, scope iop_scrc_out, type rw */
+#define reg_iop_scrc_out_rw_cfg___trig___lsb 0
+#define reg_iop_scrc_out_rw_cfg___trig___width 2
+#define reg_iop_scrc_out_rw_cfg___inv_crc___lsb 2
+#define reg_iop_scrc_out_rw_cfg___inv_crc___width 1
+#define reg_iop_scrc_out_rw_cfg___inv_crc___bit 2
+#define reg_iop_scrc_out_rw_cfg_offset 0
+
+/* Register rw_ctrl, scope iop_scrc_out, type rw */
+#define reg_iop_scrc_out_rw_ctrl___strb_src___lsb 0
+#define reg_iop_scrc_out_rw_ctrl___strb_src___width 1
+#define reg_iop_scrc_out_rw_ctrl___strb_src___bit 0
+#define reg_iop_scrc_out_rw_ctrl___out_src___lsb 1
+#define reg_iop_scrc_out_rw_ctrl___out_src___width 1
+#define reg_iop_scrc_out_rw_ctrl___out_src___bit 1
+#define reg_iop_scrc_out_rw_ctrl_offset 4
+
+/* Register rw_init_crc, scope iop_scrc_out, type rw */
+#define reg_iop_scrc_out_rw_init_crc_offset 8
+
+/* Register rw_crc, scope iop_scrc_out, type rw */
+#define reg_iop_scrc_out_rw_crc_offset 12
+
+/* Register rw_data, scope iop_scrc_out, type rw */
+#define reg_iop_scrc_out_rw_data___val___lsb 0
+#define reg_iop_scrc_out_rw_data___val___width 1
+#define reg_iop_scrc_out_rw_data___val___bit 0
+#define reg_iop_scrc_out_rw_data_offset 16
+
+/* Register r_computed_crc, scope iop_scrc_out, type r */
+#define reg_iop_scrc_out_r_computed_crc_offset 20
+
+
+/* Constants */
+#define regk_iop_scrc_out_crc                     0x00000001
+#define regk_iop_scrc_out_data                    0x00000000
+#define regk_iop_scrc_out_dif                     0x00000001
+#define regk_iop_scrc_out_hi                      0x00000000
+#define regk_iop_scrc_out_neg                     0x00000002
+#define regk_iop_scrc_out_no                      0x00000000
+#define regk_iop_scrc_out_pos                     0x00000001
+#define regk_iop_scrc_out_pos_neg                 0x00000003
+#define regk_iop_scrc_out_reg                     0x00000000
+#define regk_iop_scrc_out_rw_cfg_default          0x00000000
+#define regk_iop_scrc_out_rw_crc_default          0x00000000
+#define regk_iop_scrc_out_rw_ctrl_default         0x00000000
+#define regk_iop_scrc_out_rw_data_default         0x00000000
+#define regk_iop_scrc_out_rw_init_crc_default     0x00000000
+#define regk_iop_scrc_out_yes                     0x00000001
+#endif /* __iop_scrc_out_defs_asm_h */
diff --git a/include/asm-cris/arch-v32/hwregs/iop/asm/iop_spu_defs_asm.h b/include/asm-cris/arch-v32/hwregs/iop/asm/iop_spu_defs_asm.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/iop/asm/iop_spu_defs_asm.h
@@ -0,0 +1,573 @@
+#ifndef __iop_spu_defs_asm_h
+#define __iop_spu_defs_asm_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/io_proc/rtl/iop_spu.r
+ *     id:           <not found>
+ *     last modfied: Mon Apr 11 16:08:46 2005
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c -asm --outfile asm/iop_spu_defs_asm.h ../../inst/io_proc/rtl/iop_spu.r
+ *      id: $Id: iop_spu_defs_asm.h,v 1.5 2005/04/24 18:31:06 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+
+#ifndef REG_FIELD
+#define REG_FIELD( scope, reg, field, value ) \
+  REG_FIELD_X_( value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_FIELD_X_( value, shift ) ((value) << shift)
+#endif
+
+#ifndef REG_STATE
+#define REG_STATE( scope, reg, field, symbolic_value ) \
+  REG_STATE_X_( regk_##scope##_##symbolic_value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_STATE_X_( k, shift ) (k << shift)
+#endif
+
+#ifndef REG_MASK
+#define REG_MASK( scope, reg, field ) \
+  REG_MASK_X_( reg_##scope##_##reg##___##field##___width, reg_##scope##_##reg##___##field##___lsb )
+#define REG_MASK_X_( width, lsb ) (((1 << width)-1) << lsb)
+#endif
+
+#ifndef REG_LSB
+#define REG_LSB( scope, reg, field ) reg_##scope##_##reg##___##field##___lsb
+#endif
+
+#ifndef REG_BIT
+#define REG_BIT( scope, reg, field ) reg_##scope##_##reg##___##field##___bit
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) REG_ADDR_X_(inst, reg_##scope##_##reg##_offset)
+#define REG_ADDR_X_( inst, offs ) ((inst) + offs)
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+         REG_ADDR_VECT_X_(inst, reg_##scope##_##reg##_offset, index, \
+			 STRIDE_##scope##_##reg )
+#define REG_ADDR_VECT_X_( inst, offs, index, stride ) \
+                          ((inst) + offs + (index) * stride)
+#endif
+
+#define STRIDE_iop_spu_rw_r 4
+/* Register rw_r, scope iop_spu, type rw */
+#define reg_iop_spu_rw_r_offset 0
+
+/* Register rw_seq_pc, scope iop_spu, type rw */
+#define reg_iop_spu_rw_seq_pc___addr___lsb 0
+#define reg_iop_spu_rw_seq_pc___addr___width 12
+#define reg_iop_spu_rw_seq_pc_offset 64
+
+/* Register rw_fsm_pc, scope iop_spu, type rw */
+#define reg_iop_spu_rw_fsm_pc___addr___lsb 0
+#define reg_iop_spu_rw_fsm_pc___addr___width 12
+#define reg_iop_spu_rw_fsm_pc_offset 68
+
+/* Register rw_ctrl, scope iop_spu, type rw */
+#define reg_iop_spu_rw_ctrl___fsm___lsb 0
+#define reg_iop_spu_rw_ctrl___fsm___width 1
+#define reg_iop_spu_rw_ctrl___fsm___bit 0
+#define reg_iop_spu_rw_ctrl___en___lsb 1
+#define reg_iop_spu_rw_ctrl___en___width 1
+#define reg_iop_spu_rw_ctrl___en___bit 1
+#define reg_iop_spu_rw_ctrl_offset 72
+
+/* Register rw_fsm_inputs3_0, scope iop_spu, type rw */
+#define reg_iop_spu_rw_fsm_inputs3_0___val0___lsb 0
+#define reg_iop_spu_rw_fsm_inputs3_0___val0___width 5
+#define reg_iop_spu_rw_fsm_inputs3_0___src0___lsb 5
+#define reg_iop_spu_rw_fsm_inputs3_0___src0___width 3
+#define reg_iop_spu_rw_fsm_inputs3_0___val1___lsb 8
+#define reg_iop_spu_rw_fsm_inputs3_0___val1___width 5
+#define reg_iop_spu_rw_fsm_inputs3_0___src1___lsb 13
+#define reg_iop_spu_rw_fsm_inputs3_0___src1___width 3
+#define reg_iop_spu_rw_fsm_inputs3_0___val2___lsb 16
+#define reg_iop_spu_rw_fsm_inputs3_0___val2___width 5
+#define reg_iop_spu_rw_fsm_inputs3_0___src2___lsb 21
+#define reg_iop_spu_rw_fsm_inputs3_0___src2___width 3
+#define reg_iop_spu_rw_fsm_inputs3_0___val3___lsb 24
+#define reg_iop_spu_rw_fsm_inputs3_0___val3___width 5
+#define reg_iop_spu_rw_fsm_inputs3_0___src3___lsb 29
+#define reg_iop_spu_rw_fsm_inputs3_0___src3___width 3
+#define reg_iop_spu_rw_fsm_inputs3_0_offset 76
+
+/* Register rw_fsm_inputs7_4, scope iop_spu, type rw */
+#define reg_iop_spu_rw_fsm_inputs7_4___val4___lsb 0
+#define reg_iop_spu_rw_fsm_inputs7_4___val4___width 5
+#define reg_iop_spu_rw_fsm_inputs7_4___src4___lsb 5
+#define reg_iop_spu_rw_fsm_inputs7_4___src4___width 3
+#define reg_iop_spu_rw_fsm_inputs7_4___val5___lsb 8
+#define reg_iop_spu_rw_fsm_inputs7_4___val5___width 5
+#define reg_iop_spu_rw_fsm_inputs7_4___src5___lsb 13
+#define reg_iop_spu_rw_fsm_inputs7_4___src5___width 3
+#define reg_iop_spu_rw_fsm_inputs7_4___val6___lsb 16
+#define reg_iop_spu_rw_fsm_inputs7_4___val6___width 5
+#define reg_iop_spu_rw_fsm_inputs7_4___src6___lsb 21
+#define reg_iop_spu_rw_fsm_inputs7_4___src6___width 3
+#define reg_iop_spu_rw_fsm_inputs7_4___val7___lsb 24
+#define reg_iop_spu_rw_fsm_inputs7_4___val7___width 5
+#define reg_iop_spu_rw_fsm_inputs7_4___src7___lsb 29
+#define reg_iop_spu_rw_fsm_inputs7_4___src7___width 3
+#define reg_iop_spu_rw_fsm_inputs7_4_offset 80
+
+/* Register rw_gio_out, scope iop_spu, type rw */
+#define reg_iop_spu_rw_gio_out_offset 84
+
+/* Register rw_bus0_out, scope iop_spu, type rw */
+#define reg_iop_spu_rw_bus0_out_offset 88
+
+/* Register rw_bus1_out, scope iop_spu, type rw */
+#define reg_iop_spu_rw_bus1_out_offset 92
+
+/* Register r_gio_in, scope iop_spu, type r */
+#define reg_iop_spu_r_gio_in_offset 96
+
+/* Register r_bus0_in, scope iop_spu, type r */
+#define reg_iop_spu_r_bus0_in_offset 100
+
+/* Register r_bus1_in, scope iop_spu, type r */
+#define reg_iop_spu_r_bus1_in_offset 104
+
+/* Register rw_gio_out_set, scope iop_spu, type rw */
+#define reg_iop_spu_rw_gio_out_set_offset 108
+
+/* Register rw_gio_out_clr, scope iop_spu, type rw */
+#define reg_iop_spu_rw_gio_out_clr_offset 112
+
+/* Register rs_wr_stat, scope iop_spu, type rs */
+#define reg_iop_spu_rs_wr_stat___r0___lsb 0
+#define reg_iop_spu_rs_wr_stat___r0___width 1
+#define reg_iop_spu_rs_wr_stat___r0___bit 0
+#define reg_iop_spu_rs_wr_stat___r1___lsb 1
+#define reg_iop_spu_rs_wr_stat___r1___width 1
+#define reg_iop_spu_rs_wr_stat___r1___bit 1
+#define reg_iop_spu_rs_wr_stat___r2___lsb 2
+#define reg_iop_spu_rs_wr_stat___r2___width 1
+#define reg_iop_spu_rs_wr_stat___r2___bit 2
+#define reg_iop_spu_rs_wr_stat___r3___lsb 3
+#define reg_iop_spu_rs_wr_stat___r3___width 1
+#define reg_iop_spu_rs_wr_stat___r3___bit 3
+#define reg_iop_spu_rs_wr_stat___r4___lsb 4
+#define reg_iop_spu_rs_wr_stat___r4___width 1
+#define reg_iop_spu_rs_wr_stat___r4___bit 4
+#define reg_iop_spu_rs_wr_stat___r5___lsb 5
+#define reg_iop_spu_rs_wr_stat___r5___width 1
+#define reg_iop_spu_rs_wr_stat___r5___bit 5
+#define reg_iop_spu_rs_wr_stat___r6___lsb 6
+#define reg_iop_spu_rs_wr_stat___r6___width 1
+#define reg_iop_spu_rs_wr_stat___r6___bit 6
+#define reg_iop_spu_rs_wr_stat___r7___lsb 7
+#define reg_iop_spu_rs_wr_stat___r7___width 1
+#define reg_iop_spu_rs_wr_stat___r7___bit 7
+#define reg_iop_spu_rs_wr_stat___r8___lsb 8
+#define reg_iop_spu_rs_wr_stat___r8___width 1
+#define reg_iop_spu_rs_wr_stat___r8___bit 8
+#define reg_iop_spu_rs_wr_stat___r9___lsb 9
+#define reg_iop_spu_rs_wr_stat___r9___width 1
+#define reg_iop_spu_rs_wr_stat___r9___bit 9
+#define reg_iop_spu_rs_wr_stat___r10___lsb 10
+#define reg_iop_spu_rs_wr_stat___r10___width 1
+#define reg_iop_spu_rs_wr_stat___r10___bit 10
+#define reg_iop_spu_rs_wr_stat___r11___lsb 11
+#define reg_iop_spu_rs_wr_stat___r11___width 1
+#define reg_iop_spu_rs_wr_stat___r11___bit 11
+#define reg_iop_spu_rs_wr_stat___r12___lsb 12
+#define reg_iop_spu_rs_wr_stat___r12___width 1
+#define reg_iop_spu_rs_wr_stat___r12___bit 12
+#define reg_iop_spu_rs_wr_stat___r13___lsb 13
+#define reg_iop_spu_rs_wr_stat___r13___width 1
+#define reg_iop_spu_rs_wr_stat___r13___bit 13
+#define reg_iop_spu_rs_wr_stat___r14___lsb 14
+#define reg_iop_spu_rs_wr_stat___r14___width 1
+#define reg_iop_spu_rs_wr_stat___r14___bit 14
+#define reg_iop_spu_rs_wr_stat___r15___lsb 15
+#define reg_iop_spu_rs_wr_stat___r15___width 1
+#define reg_iop_spu_rs_wr_stat___r15___bit 15
+#define reg_iop_spu_rs_wr_stat_offset 116
+
+/* Register r_wr_stat, scope iop_spu, type r */
+#define reg_iop_spu_r_wr_stat___r0___lsb 0
+#define reg_iop_spu_r_wr_stat___r0___width 1
+#define reg_iop_spu_r_wr_stat___r0___bit 0
+#define reg_iop_spu_r_wr_stat___r1___lsb 1
+#define reg_iop_spu_r_wr_stat___r1___width 1
+#define reg_iop_spu_r_wr_stat___r1___bit 1
+#define reg_iop_spu_r_wr_stat___r2___lsb 2
+#define reg_iop_spu_r_wr_stat___r2___width 1
+#define reg_iop_spu_r_wr_stat___r2___bit 2
+#define reg_iop_spu_r_wr_stat___r3___lsb 3
+#define reg_iop_spu_r_wr_stat___r3___width 1
+#define reg_iop_spu_r_wr_stat___r3___bit 3
+#define reg_iop_spu_r_wr_stat___r4___lsb 4
+#define reg_iop_spu_r_wr_stat___r4___width 1
+#define reg_iop_spu_r_wr_stat___r4___bit 4
+#define reg_iop_spu_r_wr_stat___r5___lsb 5
+#define reg_iop_spu_r_wr_stat___r5___width 1
+#define reg_iop_spu_r_wr_stat___r5___bit 5
+#define reg_iop_spu_r_wr_stat___r6___lsb 6
+#define reg_iop_spu_r_wr_stat___r6___width 1
+#define reg_iop_spu_r_wr_stat___r6___bit 6
+#define reg_iop_spu_r_wr_stat___r7___lsb 7
+#define reg_iop_spu_r_wr_stat___r7___width 1
+#define reg_iop_spu_r_wr_stat___r7___bit 7
+#define reg_iop_spu_r_wr_stat___r8___lsb 8
+#define reg_iop_spu_r_wr_stat___r8___width 1
+#define reg_iop_spu_r_wr_stat___r8___bit 8
+#define reg_iop_spu_r_wr_stat___r9___lsb 9
+#define reg_iop_spu_r_wr_stat___r9___width 1
+#define reg_iop_spu_r_wr_stat___r9___bit 9
+#define reg_iop_spu_r_wr_stat___r10___lsb 10
+#define reg_iop_spu_r_wr_stat___r10___width 1
+#define reg_iop_spu_r_wr_stat___r10___bit 10
+#define reg_iop_spu_r_wr_stat___r11___lsb 11
+#define reg_iop_spu_r_wr_stat___r11___width 1
+#define reg_iop_spu_r_wr_stat___r11___bit 11
+#define reg_iop_spu_r_wr_stat___r12___lsb 12
+#define reg_iop_spu_r_wr_stat___r12___width 1
+#define reg_iop_spu_r_wr_stat___r12___bit 12
+#define reg_iop_spu_r_wr_stat___r13___lsb 13
+#define reg_iop_spu_r_wr_stat___r13___width 1
+#define reg_iop_spu_r_wr_stat___r13___bit 13
+#define reg_iop_spu_r_wr_stat___r14___lsb 14
+#define reg_iop_spu_r_wr_stat___r14___width 1
+#define reg_iop_spu_r_wr_stat___r14___bit 14
+#define reg_iop_spu_r_wr_stat___r15___lsb 15
+#define reg_iop_spu_r_wr_stat___r15___width 1
+#define reg_iop_spu_r_wr_stat___r15___bit 15
+#define reg_iop_spu_r_wr_stat_offset 120
+
+/* Register r_reg_indexed_by_bus0_in, scope iop_spu, type r */
+#define reg_iop_spu_r_reg_indexed_by_bus0_in_offset 124
+
+/* Register r_stat_in, scope iop_spu, type r */
+#define reg_iop_spu_r_stat_in___timer_grp_lo___lsb 0
+#define reg_iop_spu_r_stat_in___timer_grp_lo___width 4
+#define reg_iop_spu_r_stat_in___fifo_out_last___lsb 4
+#define reg_iop_spu_r_stat_in___fifo_out_last___width 1
+#define reg_iop_spu_r_stat_in___fifo_out_last___bit 4
+#define reg_iop_spu_r_stat_in___fifo_out_rdy___lsb 5
+#define reg_iop_spu_r_stat_in___fifo_out_rdy___width 1
+#define reg_iop_spu_r_stat_in___fifo_out_rdy___bit 5
+#define reg_iop_spu_r_stat_in___fifo_out_all___lsb 6
+#define reg_iop_spu_r_stat_in___fifo_out_all___width 1
+#define reg_iop_spu_r_stat_in___fifo_out_all___bit 6
+#define reg_iop_spu_r_stat_in___fifo_in_rdy___lsb 7
+#define reg_iop_spu_r_stat_in___fifo_in_rdy___width 1
+#define reg_iop_spu_r_stat_in___fifo_in_rdy___bit 7
+#define reg_iop_spu_r_stat_in___dmc_out_all___lsb 8
+#define reg_iop_spu_r_stat_in___dmc_out_all___width 1
+#define reg_iop_spu_r_stat_in___dmc_out_all___bit 8
+#define reg_iop_spu_r_stat_in___dmc_out_dth___lsb 9
+#define reg_iop_spu_r_stat_in___dmc_out_dth___width 1
+#define reg_iop_spu_r_stat_in___dmc_out_dth___bit 9
+#define reg_iop_spu_r_stat_in___dmc_out_eop___lsb 10
+#define reg_iop_spu_r_stat_in___dmc_out_eop___width 1
+#define reg_iop_spu_r_stat_in___dmc_out_eop___bit 10
+#define reg_iop_spu_r_stat_in___dmc_out_dv___lsb 11
+#define reg_iop_spu_r_stat_in___dmc_out_dv___width 1
+#define reg_iop_spu_r_stat_in___dmc_out_dv___bit 11
+#define reg_iop_spu_r_stat_in___dmc_out_last___lsb 12
+#define reg_iop_spu_r_stat_in___dmc_out_last___width 1
+#define reg_iop_spu_r_stat_in___dmc_out_last___bit 12
+#define reg_iop_spu_r_stat_in___dmc_out_cmd_rq___lsb 13
+#define reg_iop_spu_r_stat_in___dmc_out_cmd_rq___width 1
+#define reg_iop_spu_r_stat_in___dmc_out_cmd_rq___bit 13
+#define reg_iop_spu_r_stat_in___dmc_out_cmd_rdy___lsb 14
+#define reg_iop_spu_r_stat_in___dmc_out_cmd_rdy___width 1
+#define reg_iop_spu_r_stat_in___dmc_out_cmd_rdy___bit 14
+#define reg_iop_spu_r_stat_in___pcrc_correct___lsb 15
+#define reg_iop_spu_r_stat_in___pcrc_correct___width 1
+#define reg_iop_spu_r_stat_in___pcrc_correct___bit 15
+#define reg_iop_spu_r_stat_in___timer_grp_hi___lsb 16
+#define reg_iop_spu_r_stat_in___timer_grp_hi___width 4
+#define reg_iop_spu_r_stat_in___dmc_in_sth___lsb 20
+#define reg_iop_spu_r_stat_in___dmc_in_sth___width 1
+#define reg_iop_spu_r_stat_in___dmc_in_sth___bit 20
+#define reg_iop_spu_r_stat_in___dmc_in_full___lsb 21
+#define reg_iop_spu_r_stat_in___dmc_in_full___width 1
+#define reg_iop_spu_r_stat_in___dmc_in_full___bit 21
+#define reg_iop_spu_r_stat_in___dmc_in_cmd_rdy___lsb 22
+#define reg_iop_spu_r_stat_in___dmc_in_cmd_rdy___width 1
+#define reg_iop_spu_r_stat_in___dmc_in_cmd_rdy___bit 22
+#define reg_iop_spu_r_stat_in___spu_gio_out___lsb 23
+#define reg_iop_spu_r_stat_in___spu_gio_out___width 4
+#define reg_iop_spu_r_stat_in___sync_clk12___lsb 27
+#define reg_iop_spu_r_stat_in___sync_clk12___width 1
+#define reg_iop_spu_r_stat_in___sync_clk12___bit 27
+#define reg_iop_spu_r_stat_in___scrc_out_data___lsb 28
+#define reg_iop_spu_r_stat_in___scrc_out_data___width 1
+#define reg_iop_spu_r_stat_in___scrc_out_data___bit 28
+#define reg_iop_spu_r_stat_in___scrc_in_err___lsb 29
+#define reg_iop_spu_r_stat_in___scrc_in_err___width 1
+#define reg_iop_spu_r_stat_in___scrc_in_err___bit 29
+#define reg_iop_spu_r_stat_in___mc_busy___lsb 30
+#define reg_iop_spu_r_stat_in___mc_busy___width 1
+#define reg_iop_spu_r_stat_in___mc_busy___bit 30
+#define reg_iop_spu_r_stat_in___mc_owned___lsb 31
+#define reg_iop_spu_r_stat_in___mc_owned___width 1
+#define reg_iop_spu_r_stat_in___mc_owned___bit 31
+#define reg_iop_spu_r_stat_in_offset 128
+
+/* Register r_trigger_in, scope iop_spu, type r */
+#define reg_iop_spu_r_trigger_in_offset 132
+
+/* Register r_special_stat, scope iop_spu, type r */
+#define reg_iop_spu_r_special_stat___c_flag___lsb 0
+#define reg_iop_spu_r_special_stat___c_flag___width 1
+#define reg_iop_spu_r_special_stat___c_flag___bit 0
+#define reg_iop_spu_r_special_stat___v_flag___lsb 1
+#define reg_iop_spu_r_special_stat___v_flag___width 1
+#define reg_iop_spu_r_special_stat___v_flag___bit 1
+#define reg_iop_spu_r_special_stat___z_flag___lsb 2
+#define reg_iop_spu_r_special_stat___z_flag___width 1
+#define reg_iop_spu_r_special_stat___z_flag___bit 2
+#define reg_iop_spu_r_special_stat___n_flag___lsb 3
+#define reg_iop_spu_r_special_stat___n_flag___width 1
+#define reg_iop_spu_r_special_stat___n_flag___bit 3
+#define reg_iop_spu_r_special_stat___xor_bus0_r2_0___lsb 4
+#define reg_iop_spu_r_special_stat___xor_bus0_r2_0___width 1
+#define reg_iop_spu_r_special_stat___xor_bus0_r2_0___bit 4
+#define reg_iop_spu_r_special_stat___xor_bus1_r3_0___lsb 5
+#define reg_iop_spu_r_special_stat___xor_bus1_r3_0___width 1
+#define reg_iop_spu_r_special_stat___xor_bus1_r3_0___bit 5
+#define reg_iop_spu_r_special_stat___xor_bus0m_r2_0___lsb 6
+#define reg_iop_spu_r_special_stat___xor_bus0m_r2_0___width 1
+#define reg_iop_spu_r_special_stat___xor_bus0m_r2_0___bit 6
+#define reg_iop_spu_r_special_stat___xor_bus1m_r3_0___lsb 7
+#define reg_iop_spu_r_special_stat___xor_bus1m_r3_0___width 1
+#define reg_iop_spu_r_special_stat___xor_bus1m_r3_0___bit 7
+#define reg_iop_spu_r_special_stat___fsm_in0___lsb 8
+#define reg_iop_spu_r_special_stat___fsm_in0___width 1
+#define reg_iop_spu_r_special_stat___fsm_in0___bit 8
+#define reg_iop_spu_r_special_stat___fsm_in1___lsb 9
+#define reg_iop_spu_r_special_stat___fsm_in1___width 1
+#define reg_iop_spu_r_special_stat___fsm_in1___bit 9
+#define reg_iop_spu_r_special_stat___fsm_in2___lsb 10
+#define reg_iop_spu_r_special_stat___fsm_in2___width 1
+#define reg_iop_spu_r_special_stat___fsm_in2___bit 10
+#define reg_iop_spu_r_special_stat___fsm_in3___lsb 11
+#define reg_iop_spu_r_special_stat___fsm_in3___width 1
+#define reg_iop_spu_r_special_stat___fsm_in3___bit 11
+#define reg_iop_spu_r_special_stat___fsm_in4___lsb 12
+#define reg_iop_spu_r_special_stat___fsm_in4___width 1
+#define reg_iop_spu_r_special_stat___fsm_in4___bit 12
+#define reg_iop_spu_r_special_stat___fsm_in5___lsb 13
+#define reg_iop_spu_r_special_stat___fsm_in5___width 1
+#define reg_iop_spu_r_special_stat___fsm_in5___bit 13
+#define reg_iop_spu_r_special_stat___fsm_in6___lsb 14
+#define reg_iop_spu_r_special_stat___fsm_in6___width 1
+#define reg_iop_spu_r_special_stat___fsm_in6___bit 14
+#define reg_iop_spu_r_special_stat___fsm_in7___lsb 15
+#define reg_iop_spu_r_special_stat___fsm_in7___width 1
+#define reg_iop_spu_r_special_stat___fsm_in7___bit 15
+#define reg_iop_spu_r_special_stat___event0___lsb 16
+#define reg_iop_spu_r_special_stat___event0___width 1
+#define reg_iop_spu_r_special_stat___event0___bit 16
+#define reg_iop_spu_r_special_stat___event1___lsb 17
+#define reg_iop_spu_r_special_stat___event1___width 1
+#define reg_iop_spu_r_special_stat___event1___bit 17
+#define reg_iop_spu_r_special_stat___event2___lsb 18
+#define reg_iop_spu_r_special_stat___event2___width 1
+#define reg_iop_spu_r_special_stat___event2___bit 18
+#define reg_iop_spu_r_special_stat___event3___lsb 19
+#define reg_iop_spu_r_special_stat___event3___width 1
+#define reg_iop_spu_r_special_stat___event3___bit 19
+#define reg_iop_spu_r_special_stat_offset 136
+
+/* Register rw_reg_access, scope iop_spu, type rw */
+#define reg_iop_spu_rw_reg_access___addr___lsb 0
+#define reg_iop_spu_rw_reg_access___addr___width 13
+#define reg_iop_spu_rw_reg_access___imm_hi___lsb 16
+#define reg_iop_spu_rw_reg_access___imm_hi___width 16
+#define reg_iop_spu_rw_reg_access_offset 140
+
+#define STRIDE_iop_spu_rw_event_cfg 4
+/* Register rw_event_cfg, scope iop_spu, type rw */
+#define reg_iop_spu_rw_event_cfg___addr___lsb 0
+#define reg_iop_spu_rw_event_cfg___addr___width 12
+#define reg_iop_spu_rw_event_cfg___src___lsb 12
+#define reg_iop_spu_rw_event_cfg___src___width 2
+#define reg_iop_spu_rw_event_cfg___eq_en___lsb 14
+#define reg_iop_spu_rw_event_cfg___eq_en___width 1
+#define reg_iop_spu_rw_event_cfg___eq_en___bit 14
+#define reg_iop_spu_rw_event_cfg___eq_inv___lsb 15
+#define reg_iop_spu_rw_event_cfg___eq_inv___width 1
+#define reg_iop_spu_rw_event_cfg___eq_inv___bit 15
+#define reg_iop_spu_rw_event_cfg___gt_en___lsb 16
+#define reg_iop_spu_rw_event_cfg___gt_en___width 1
+#define reg_iop_spu_rw_event_cfg___gt_en___bit 16
+#define reg_iop_spu_rw_event_cfg___gt_inv___lsb 17
+#define reg_iop_spu_rw_event_cfg___gt_inv___width 1
+#define reg_iop_spu_rw_event_cfg___gt_inv___bit 17
+#define reg_iop_spu_rw_event_cfg_offset 144
+
+#define STRIDE_iop_spu_rw_event_mask 4
+/* Register rw_event_mask, scope iop_spu, type rw */
+#define reg_iop_spu_rw_event_mask_offset 160
+
+#define STRIDE_iop_spu_rw_event_val 4
+/* Register rw_event_val, scope iop_spu, type rw */
+#define reg_iop_spu_rw_event_val_offset 176
+
+/* Register rw_event_ret, scope iop_spu, type rw */
+#define reg_iop_spu_rw_event_ret___addr___lsb 0
+#define reg_iop_spu_rw_event_ret___addr___width 12
+#define reg_iop_spu_rw_event_ret_offset 192
+
+/* Register r_trace, scope iop_spu, type r */
+#define reg_iop_spu_r_trace___fsm___lsb 0
+#define reg_iop_spu_r_trace___fsm___width 1
+#define reg_iop_spu_r_trace___fsm___bit 0
+#define reg_iop_spu_r_trace___en___lsb 1
+#define reg_iop_spu_r_trace___en___width 1
+#define reg_iop_spu_r_trace___en___bit 1
+#define reg_iop_spu_r_trace___c_flag___lsb 2
+#define reg_iop_spu_r_trace___c_flag___width 1
+#define reg_iop_spu_r_trace___c_flag___bit 2
+#define reg_iop_spu_r_trace___v_flag___lsb 3
+#define reg_iop_spu_r_trace___v_flag___width 1
+#define reg_iop_spu_r_trace___v_flag___bit 3
+#define reg_iop_spu_r_trace___z_flag___lsb 4
+#define reg_iop_spu_r_trace___z_flag___width 1
+#define reg_iop_spu_r_trace___z_flag___bit 4
+#define reg_iop_spu_r_trace___n_flag___lsb 5
+#define reg_iop_spu_r_trace___n_flag___width 1
+#define reg_iop_spu_r_trace___n_flag___bit 5
+#define reg_iop_spu_r_trace___seq_addr___lsb 6
+#define reg_iop_spu_r_trace___seq_addr___width 12
+#define reg_iop_spu_r_trace___fsm_addr___lsb 20
+#define reg_iop_spu_r_trace___fsm_addr___width 12
+#define reg_iop_spu_r_trace_offset 196
+
+/* Register r_fsm_trace, scope iop_spu, type r */
+#define reg_iop_spu_r_fsm_trace___fsm___lsb 0
+#define reg_iop_spu_r_fsm_trace___fsm___width 1
+#define reg_iop_spu_r_fsm_trace___fsm___bit 0
+#define reg_iop_spu_r_fsm_trace___en___lsb 1
+#define reg_iop_spu_r_fsm_trace___en___width 1
+#define reg_iop_spu_r_fsm_trace___en___bit 1
+#define reg_iop_spu_r_fsm_trace___tmr_done___lsb 2
+#define reg_iop_spu_r_fsm_trace___tmr_done___width 1
+#define reg_iop_spu_r_fsm_trace___tmr_done___bit 2
+#define reg_iop_spu_r_fsm_trace___inp0___lsb 3
+#define reg_iop_spu_r_fsm_trace___inp0___width 1
+#define reg_iop_spu_r_fsm_trace___inp0___bit 3
+#define reg_iop_spu_r_fsm_trace___inp1___lsb 4
+#define reg_iop_spu_r_fsm_trace___inp1___width 1
+#define reg_iop_spu_r_fsm_trace___inp1___bit 4
+#define reg_iop_spu_r_fsm_trace___inp2___lsb 5
+#define reg_iop_spu_r_fsm_trace___inp2___width 1
+#define reg_iop_spu_r_fsm_trace___inp2___bit 5
+#define reg_iop_spu_r_fsm_trace___inp3___lsb 6
+#define reg_iop_spu_r_fsm_trace___inp3___width 1
+#define reg_iop_spu_r_fsm_trace___inp3___bit 6
+#define reg_iop_spu_r_fsm_trace___event0___lsb 7
+#define reg_iop_spu_r_fsm_trace___event0___width 1
+#define reg_iop_spu_r_fsm_trace___event0___bit 7
+#define reg_iop_spu_r_fsm_trace___event1___lsb 8
+#define reg_iop_spu_r_fsm_trace___event1___width 1
+#define reg_iop_spu_r_fsm_trace___event1___bit 8
+#define reg_iop_spu_r_fsm_trace___event2___lsb 9
+#define reg_iop_spu_r_fsm_trace___event2___width 1
+#define reg_iop_spu_r_fsm_trace___event2___bit 9
+#define reg_iop_spu_r_fsm_trace___event3___lsb 10
+#define reg_iop_spu_r_fsm_trace___event3___width 1
+#define reg_iop_spu_r_fsm_trace___event3___bit 10
+#define reg_iop_spu_r_fsm_trace___gio_out___lsb 11
+#define reg_iop_spu_r_fsm_trace___gio_out___width 8
+#define reg_iop_spu_r_fsm_trace___fsm_addr___lsb 20
+#define reg_iop_spu_r_fsm_trace___fsm_addr___width 12
+#define reg_iop_spu_r_fsm_trace_offset 200
+
+#define STRIDE_iop_spu_rw_brp 4
+/* Register rw_brp, scope iop_spu, type rw */
+#define reg_iop_spu_rw_brp___addr___lsb 0
+#define reg_iop_spu_rw_brp___addr___width 12
+#define reg_iop_spu_rw_brp___fsm___lsb 12
+#define reg_iop_spu_rw_brp___fsm___width 1
+#define reg_iop_spu_rw_brp___fsm___bit 12
+#define reg_iop_spu_rw_brp___en___lsb 13
+#define reg_iop_spu_rw_brp___en___width 1
+#define reg_iop_spu_rw_brp___en___bit 13
+#define reg_iop_spu_rw_brp_offset 204
+
+
+/* Constants */
+#define regk_iop_spu_attn_hi                      0x00000005
+#define regk_iop_spu_attn_lo                      0x00000005
+#define regk_iop_spu_attn_r0                      0x00000000
+#define regk_iop_spu_attn_r1                      0x00000001
+#define regk_iop_spu_attn_r10                     0x00000002
+#define regk_iop_spu_attn_r11                     0x00000003
+#define regk_iop_spu_attn_r12                     0x00000004
+#define regk_iop_spu_attn_r13                     0x00000005
+#define regk_iop_spu_attn_r14                     0x00000006
+#define regk_iop_spu_attn_r15                     0x00000007
+#define regk_iop_spu_attn_r2                      0x00000002
+#define regk_iop_spu_attn_r3                      0x00000003
+#define regk_iop_spu_attn_r4                      0x00000004
+#define regk_iop_spu_attn_r5                      0x00000005
+#define regk_iop_spu_attn_r6                      0x00000006
+#define regk_iop_spu_attn_r7                      0x00000007
+#define regk_iop_spu_attn_r8                      0x00000000
+#define regk_iop_spu_attn_r9                      0x00000001
+#define regk_iop_spu_c                            0x00000000
+#define regk_iop_spu_flag                         0x00000002
+#define regk_iop_spu_gio_in                       0x00000000
+#define regk_iop_spu_gio_out                      0x00000005
+#define regk_iop_spu_gio_out0                     0x00000008
+#define regk_iop_spu_gio_out1                     0x00000009
+#define regk_iop_spu_gio_out2                     0x0000000a
+#define regk_iop_spu_gio_out3                     0x0000000b
+#define regk_iop_spu_gio_out4                     0x0000000c
+#define regk_iop_spu_gio_out5                     0x0000000d
+#define regk_iop_spu_gio_out6                     0x0000000e
+#define regk_iop_spu_gio_out7                     0x0000000f
+#define regk_iop_spu_n                            0x00000003
+#define regk_iop_spu_no                           0x00000000
+#define regk_iop_spu_r0                           0x00000008
+#define regk_iop_spu_r1                           0x00000009
+#define regk_iop_spu_r10                          0x0000000a
+#define regk_iop_spu_r11                          0x0000000b
+#define regk_iop_spu_r12                          0x0000000c
+#define regk_iop_spu_r13                          0x0000000d
+#define regk_iop_spu_r14                          0x0000000e
+#define regk_iop_spu_r15                          0x0000000f
+#define regk_iop_spu_r2                           0x0000000a
+#define regk_iop_spu_r3                           0x0000000b
+#define regk_iop_spu_r4                           0x0000000c
+#define regk_iop_spu_r5                           0x0000000d
+#define regk_iop_spu_r6                           0x0000000e
+#define regk_iop_spu_r7                           0x0000000f
+#define regk_iop_spu_r8                           0x00000008
+#define regk_iop_spu_r9                           0x00000009
+#define regk_iop_spu_reg_hi                       0x00000002
+#define regk_iop_spu_reg_lo                       0x00000002
+#define regk_iop_spu_rw_brp_default               0x00000000
+#define regk_iop_spu_rw_brp_size                  0x00000004
+#define regk_iop_spu_rw_ctrl_default              0x00000000
+#define regk_iop_spu_rw_event_cfg_size            0x00000004
+#define regk_iop_spu_rw_event_mask_size           0x00000004
+#define regk_iop_spu_rw_event_val_size            0x00000004
+#define regk_iop_spu_rw_gio_out_default           0x00000000
+#define regk_iop_spu_rw_r_size                    0x00000010
+#define regk_iop_spu_rw_reg_access_default        0x00000000
+#define regk_iop_spu_stat_in                      0x00000002
+#define regk_iop_spu_statin_hi                    0x00000004
+#define regk_iop_spu_statin_lo                    0x00000004
+#define regk_iop_spu_trig                         0x00000003
+#define regk_iop_spu_trigger                      0x00000006
+#define regk_iop_spu_v                            0x00000001
+#define regk_iop_spu_wsts_gioout_spec             0x00000001
+#define regk_iop_spu_xor                          0x00000003
+#define regk_iop_spu_xor_bus0_r2_0                0x00000000
+#define regk_iop_spu_xor_bus0m_r2_0               0x00000002
+#define regk_iop_spu_xor_bus1_r3_0                0x00000001
+#define regk_iop_spu_xor_bus1m_r3_0               0x00000003
+#define regk_iop_spu_yes                          0x00000001
+#define regk_iop_spu_z                            0x00000002
+#endif /* __iop_spu_defs_asm_h */
diff --git a/include/asm-cris/arch-v32/hwregs/iop/asm/iop_sw_cfg_defs_asm.h b/include/asm-cris/arch-v32/hwregs/iop/asm/iop_sw_cfg_defs_asm.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/iop/asm/iop_sw_cfg_defs_asm.h
@@ -0,0 +1,1052 @@
+#ifndef __iop_sw_cfg_defs_asm_h
+#define __iop_sw_cfg_defs_asm_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/io_proc/rtl/guinness/iop_sw_cfg.r
+ *     id:           <not found>
+ *     last modfied: Mon Apr 11 16:10:19 2005
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c -asm --outfile asm/iop_sw_cfg_defs_asm.h ../../inst/io_proc/rtl/guinness/iop_sw_cfg.r
+ *      id: $Id: iop_sw_cfg_defs_asm.h,v 1.5 2005/04/24 18:31:07 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+
+#ifndef REG_FIELD
+#define REG_FIELD( scope, reg, field, value ) \
+  REG_FIELD_X_( value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_FIELD_X_( value, shift ) ((value) << shift)
+#endif
+
+#ifndef REG_STATE
+#define REG_STATE( scope, reg, field, symbolic_value ) \
+  REG_STATE_X_( regk_##scope##_##symbolic_value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_STATE_X_( k, shift ) (k << shift)
+#endif
+
+#ifndef REG_MASK
+#define REG_MASK( scope, reg, field ) \
+  REG_MASK_X_( reg_##scope##_##reg##___##field##___width, reg_##scope##_##reg##___##field##___lsb )
+#define REG_MASK_X_( width, lsb ) (((1 << width)-1) << lsb)
+#endif
+
+#ifndef REG_LSB
+#define REG_LSB( scope, reg, field ) reg_##scope##_##reg##___##field##___lsb
+#endif
+
+#ifndef REG_BIT
+#define REG_BIT( scope, reg, field ) reg_##scope##_##reg##___##field##___bit
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) REG_ADDR_X_(inst, reg_##scope##_##reg##_offset)
+#define REG_ADDR_X_( inst, offs ) ((inst) + offs)
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+         REG_ADDR_VECT_X_(inst, reg_##scope##_##reg##_offset, index, \
+			 STRIDE_##scope##_##reg )
+#define REG_ADDR_VECT_X_( inst, offs, index, stride ) \
+                          ((inst) + offs + (index) * stride)
+#endif
+
+/* Register rw_crc_par0_owner, scope iop_sw_cfg, type rw */
+#define reg_iop_sw_cfg_rw_crc_par0_owner___cfg___lsb 0
+#define reg_iop_sw_cfg_rw_crc_par0_owner___cfg___width 2
+#define reg_iop_sw_cfg_rw_crc_par0_owner_offset 0
+
+/* Register rw_crc_par1_owner, scope iop_sw_cfg, type rw */
+#define reg_iop_sw_cfg_rw_crc_par1_owner___cfg___lsb 0
+#define reg_iop_sw_cfg_rw_crc_par1_owner___cfg___width 2
+#define reg_iop_sw_cfg_rw_crc_par1_owner_offset 4
+
+/* Register rw_dmc_in0_owner, scope iop_sw_cfg, type rw */
+#define reg_iop_sw_cfg_rw_dmc_in0_owner___cfg___lsb 0
+#define reg_iop_sw_cfg_rw_dmc_in0_owner___cfg___width 2
+#define reg_iop_sw_cfg_rw_dmc_in0_owner_offset 8
+
+/* Register rw_dmc_in1_owner, scope iop_sw_cfg, type rw */
+#define reg_iop_sw_cfg_rw_dmc_in1_owner___cfg___lsb 0
+#define reg_iop_sw_cfg_rw_dmc_in1_owner___cfg___width 2
+#define reg_iop_sw_cfg_rw_dmc_in1_owner_offset 12
+
+/* Register rw_dmc_out0_owner, scope iop_sw_cfg, type rw */
+#define reg_iop_sw_cfg_rw_dmc_out0_owner___cfg___lsb 0
+#define reg_iop_sw_cfg_rw_dmc_out0_owner___cfg___width 2
+#define reg_iop_sw_cfg_rw_dmc_out0_owner_offset 16
+
+/* Register rw_dmc_out1_owner, scope iop_sw_cfg, type rw */
+#define reg_iop_sw_cfg_rw_dmc_out1_owner___cfg___lsb 0
+#define reg_iop_sw_cfg_rw_dmc_out1_owner___cfg___width 2
+#define reg_iop_sw_cfg_rw_dmc_out1_owner_offset 20
+
+/* Register rw_fifo_in0_owner, scope iop_sw_cfg, type rw */
+#define reg_iop_sw_cfg_rw_fifo_in0_owner___cfg___lsb 0
+#define reg_iop_sw_cfg_rw_fifo_in0_owner___cfg___width 2
+#define reg_iop_sw_cfg_rw_fifo_in0_owner_offset 24
+
+/* Register rw_fifo_in0_extra_owner, scope iop_sw_cfg, type rw */
+#define reg_iop_sw_cfg_rw_fifo_in0_extra_owner___cfg___lsb 0
+#define reg_iop_sw_cfg_rw_fifo_in0_extra_owner___cfg___width 2
+#define reg_iop_sw_cfg_rw_fifo_in0_extra_owner_offset 28
+
+/* Register rw_fifo_in1_owner, scope iop_sw_cfg, type rw */
+#define reg_iop_sw_cfg_rw_fifo_in1_owner___cfg___lsb 0
+#define reg_iop_sw_cfg_rw_fifo_in1_owner___cfg___width 2
+#define reg_iop_sw_cfg_rw_fifo_in1_owner_offset 32
+
+/* Register rw_fifo_in1_extra_owner, scope iop_sw_cfg, type rw */
+#define reg_iop_sw_cfg_rw_fifo_in1_extra_owner___cfg___lsb 0
+#define reg_iop_sw_cfg_rw_fifo_in1_extra_owner___cfg___width 2
+#define reg_iop_sw_cfg_rw_fifo_in1_extra_owner_offset 36
+
+/* Register rw_fifo_out0_owner, scope iop_sw_cfg, type rw */
+#define reg_iop_sw_cfg_rw_fifo_out0_owner___cfg___lsb 0
+#define reg_iop_sw_cfg_rw_fifo_out0_owner___cfg___width 2
+#define reg_iop_sw_cfg_rw_fifo_out0_owner_offset 40
+
+/* Register rw_fifo_out0_extra_owner, scope iop_sw_cfg, type rw */
+#define reg_iop_sw_cfg_rw_fifo_out0_extra_owner___cfg___lsb 0
+#define reg_iop_sw_cfg_rw_fifo_out0_extra_owner___cfg___width 2
+#define reg_iop_sw_cfg_rw_fifo_out0_extra_owner_offset 44
+
+/* Register rw_fifo_out1_owner, scope iop_sw_cfg, type rw */
+#define reg_iop_sw_cfg_rw_fifo_out1_owner___cfg___lsb 0
+#define reg_iop_sw_cfg_rw_fifo_out1_owner___cfg___width 2
+#define reg_iop_sw_cfg_rw_fifo_out1_owner_offset 48
+
+/* Register rw_fifo_out1_extra_owner, scope iop_sw_cfg, type rw */
+#define reg_iop_sw_cfg_rw_fifo_out1_extra_owner___cfg___lsb 0
+#define reg_iop_sw_cfg_rw_fifo_out1_extra_owner___cfg___width 2
+#define reg_iop_sw_cfg_rw_fifo_out1_extra_owner_offset 52
+
+/* Register rw_sap_in_owner, scope iop_sw_cfg, type rw */
+#define reg_iop_sw_cfg_rw_sap_in_owner___cfg___lsb 0
+#define reg_iop_sw_cfg_rw_sap_in_owner___cfg___width 2
+#define reg_iop_sw_cfg_rw_sap_in_owner_offset 56
+
+/* Register rw_sap_out_owner, scope iop_sw_cfg, type rw */
+#define reg_iop_sw_cfg_rw_sap_out_owner___cfg___lsb 0
+#define reg_iop_sw_cfg_rw_sap_out_owner___cfg___width 2
+#define reg_iop_sw_cfg_rw_sap_out_owner_offset 60
+
+/* Register rw_scrc_in0_owner, scope iop_sw_cfg, type rw */
+#define reg_iop_sw_cfg_rw_scrc_in0_owner___cfg___lsb 0
+#define reg_iop_sw_cfg_rw_scrc_in0_owner___cfg___width 2
+#define reg_iop_sw_cfg_rw_scrc_in0_owner_offset 64
+
+/* Register rw_scrc_in1_owner, scope iop_sw_cfg, type rw */
+#define reg_iop_sw_cfg_rw_scrc_in1_owner___cfg___lsb 0
+#define reg_iop_sw_cfg_rw_scrc_in1_owner___cfg___width 2
+#define reg_iop_sw_cfg_rw_scrc_in1_owner_offset 68
+
+/* Register rw_scrc_out0_owner, scope iop_sw_cfg, type rw */
+#define reg_iop_sw_cfg_rw_scrc_out0_owner___cfg___lsb 0
+#define reg_iop_sw_cfg_rw_scrc_out0_owner___cfg___width 2
+#define reg_iop_sw_cfg_rw_scrc_out0_owner_offset 72
+
+/* Register rw_scrc_out1_owner, scope iop_sw_cfg, type rw */
+#define reg_iop_sw_cfg_rw_scrc_out1_owner___cfg___lsb 0
+#define reg_iop_sw_cfg_rw_scrc_out1_owner___cfg___width 2
+#define reg_iop_sw_cfg_rw_scrc_out1_owner_offset 76
+
+/* Register rw_spu0_owner, scope iop_sw_cfg, type rw */
+#define reg_iop_sw_cfg_rw_spu0_owner___cfg___lsb 0
+#define reg_iop_sw_cfg_rw_spu0_owner___cfg___width 2
+#define reg_iop_sw_cfg_rw_spu0_owner_offset 80
+
+/* Register rw_spu1_owner, scope iop_sw_cfg, type rw */
+#define reg_iop_sw_cfg_rw_spu1_owner___cfg___lsb 0
+#define reg_iop_sw_cfg_rw_spu1_owner___cfg___width 2
+#define reg_iop_sw_cfg_rw_spu1_owner_offset 84
+
+/* Register rw_timer_grp0_owner, scope iop_sw_cfg, type rw */
+#define reg_iop_sw_cfg_rw_timer_grp0_owner___cfg___lsb 0
+#define reg_iop_sw_cfg_rw_timer_grp0_owner___cfg___width 2
+#define reg_iop_sw_cfg_rw_timer_grp0_owner_offset 88
+
+/* Register rw_timer_grp1_owner, scope iop_sw_cfg, type rw */
+#define reg_iop_sw_cfg_rw_timer_grp1_owner___cfg___lsb 0
+#define reg_iop_sw_cfg_rw_timer_grp1_owner___cfg___width 2
+#define reg_iop_sw_cfg_rw_timer_grp1_owner_offset 92
+
+/* Register rw_timer_grp2_owner, scope iop_sw_cfg, type rw */
+#define reg_iop_sw_cfg_rw_timer_grp2_owner___cfg___lsb 0
+#define reg_iop_sw_cfg_rw_timer_grp2_owner___cfg___width 2
+#define reg_iop_sw_cfg_rw_timer_grp2_owner_offset 96
+
+/* Register rw_timer_grp3_owner, scope iop_sw_cfg, type rw */
+#define reg_iop_sw_cfg_rw_timer_grp3_owner___cfg___lsb 0
+#define reg_iop_sw_cfg_rw_timer_grp3_owner___cfg___width 2
+#define reg_iop_sw_cfg_rw_timer_grp3_owner_offset 100
+
+/* Register rw_trigger_grp0_owner, scope iop_sw_cfg, type rw */
+#define reg_iop_sw_cfg_rw_trigger_grp0_owner___cfg___lsb 0
+#define reg_iop_sw_cfg_rw_trigger_grp0_owner___cfg___width 2
+#define reg_iop_sw_cfg_rw_trigger_grp0_owner_offset 104
+
+/* Register rw_trigger_grp1_owner, scope iop_sw_cfg, type rw */
+#define reg_iop_sw_cfg_rw_trigger_grp1_owner___cfg___lsb 0
+#define reg_iop_sw_cfg_rw_trigger_grp1_owner___cfg___width 2
+#define reg_iop_sw_cfg_rw_trigger_grp1_owner_offset 108
+
+/* Register rw_trigger_grp2_owner, scope iop_sw_cfg, type rw */
+#define reg_iop_sw_cfg_rw_trigger_grp2_owner___cfg___lsb 0
+#define reg_iop_sw_cfg_rw_trigger_grp2_owner___cfg___width 2
+#define reg_iop_sw_cfg_rw_trigger_grp2_owner_offset 112
+
+/* Register rw_trigger_grp3_owner, scope iop_sw_cfg, type rw */
+#define reg_iop_sw_cfg_rw_trigger_grp3_owner___cfg___lsb 0
+#define reg_iop_sw_cfg_rw_trigger_grp3_owner___cfg___width 2
+#define reg_iop_sw_cfg_rw_trigger_grp3_owner_offset 116
+
+/* Register rw_trigger_grp4_owner, scope iop_sw_cfg, type rw */
+#define reg_iop_sw_cfg_rw_trigger_grp4_owner___cfg___lsb 0
+#define reg_iop_sw_cfg_rw_trigger_grp4_owner___cfg___width 2
+#define reg_iop_sw_cfg_rw_trigger_grp4_owner_offset 120
+
+/* Register rw_trigger_grp5_owner, scope iop_sw_cfg, type rw */
+#define reg_iop_sw_cfg_rw_trigger_grp5_owner___cfg___lsb 0
+#define reg_iop_sw_cfg_rw_trigger_grp5_owner___cfg___width 2
+#define reg_iop_sw_cfg_rw_trigger_grp5_owner_offset 124
+
+/* Register rw_trigger_grp6_owner, scope iop_sw_cfg, type rw */
+#define reg_iop_sw_cfg_rw_trigger_grp6_owner___cfg___lsb 0
+#define reg_iop_sw_cfg_rw_trigger_grp6_owner___cfg___width 2
+#define reg_iop_sw_cfg_rw_trigger_grp6_owner_offset 128
+
+/* Register rw_trigger_grp7_owner, scope iop_sw_cfg, type rw */
+#define reg_iop_sw_cfg_rw_trigger_grp7_owner___cfg___lsb 0
+#define reg_iop_sw_cfg_rw_trigger_grp7_owner___cfg___width 2
+#define reg_iop_sw_cfg_rw_trigger_grp7_owner_offset 132
+
+/* Register rw_bus0_mask, scope iop_sw_cfg, type rw */
+#define reg_iop_sw_cfg_rw_bus0_mask___byte0___lsb 0
+#define reg_iop_sw_cfg_rw_bus0_mask___byte0___width 8
+#define reg_iop_sw_cfg_rw_bus0_mask___byte1___lsb 8
+#define reg_iop_sw_cfg_rw_bus0_mask___byte1___width 8
+#define reg_iop_sw_cfg_rw_bus0_mask___byte2___lsb 16
+#define reg_iop_sw_cfg_rw_bus0_mask___byte2___width 8
+#define reg_iop_sw_cfg_rw_bus0_mask___byte3___lsb 24
+#define reg_iop_sw_cfg_rw_bus0_mask___byte3___width 8
+#define reg_iop_sw_cfg_rw_bus0_mask_offset 136
+
+/* Register rw_bus0_oe_mask, scope iop_sw_cfg, type rw */
+#define reg_iop_sw_cfg_rw_bus0_oe_mask___byte0___lsb 0
+#define reg_iop_sw_cfg_rw_bus0_oe_mask___byte0___width 1
+#define reg_iop_sw_cfg_rw_bus0_oe_mask___byte0___bit 0
+#define reg_iop_sw_cfg_rw_bus0_oe_mask___byte1___lsb 1
+#define reg_iop_sw_cfg_rw_bus0_oe_mask___byte1___width 1
+#define reg_iop_sw_cfg_rw_bus0_oe_mask___byte1___bit 1
+#define reg_iop_sw_cfg_rw_bus0_oe_mask___byte2___lsb 2
+#define reg_iop_sw_cfg_rw_bus0_oe_mask___byte2___width 1
+#define reg_iop_sw_cfg_rw_bus0_oe_mask___byte2___bit 2
+#define reg_iop_sw_cfg_rw_bus0_oe_mask___byte3___lsb 3
+#define reg_iop_sw_cfg_rw_bus0_oe_mask___byte3___width 1
+#define reg_iop_sw_cfg_rw_bus0_oe_mask___byte3___bit 3
+#define reg_iop_sw_cfg_rw_bus0_oe_mask_offset 140
+
+/* Register rw_bus1_mask, scope iop_sw_cfg, type rw */
+#define reg_iop_sw_cfg_rw_bus1_mask___byte0___lsb 0
+#define reg_iop_sw_cfg_rw_bus1_mask___byte0___width 8
+#define reg_iop_sw_cfg_rw_bus1_mask___byte1___lsb 8
+#define reg_iop_sw_cfg_rw_bus1_mask___byte1___width 8
+#define reg_iop_sw_cfg_rw_bus1_mask___byte2___lsb 16
+#define reg_iop_sw_cfg_rw_bus1_mask___byte2___width 8
+#define reg_iop_sw_cfg_rw_bus1_mask___byte3___lsb 24
+#define reg_iop_sw_cfg_rw_bus1_mask___byte3___width 8
+#define reg_iop_sw_cfg_rw_bus1_mask_offset 144
+
+/* Register rw_bus1_oe_mask, scope iop_sw_cfg, type rw */
+#define reg_iop_sw_cfg_rw_bus1_oe_mask___byte0___lsb 0
+#define reg_iop_sw_cfg_rw_bus1_oe_mask___byte0___width 1
+#define reg_iop_sw_cfg_rw_bus1_oe_mask___byte0___bit 0
+#define reg_iop_sw_cfg_rw_bus1_oe_mask___byte1___lsb 1
+#define reg_iop_sw_cfg_rw_bus1_oe_mask___byte1___width 1
+#define reg_iop_sw_cfg_rw_bus1_oe_mask___byte1___bit 1
+#define reg_iop_sw_cfg_rw_bus1_oe_mask___byte2___lsb 2
+#define reg_iop_sw_cfg_rw_bus1_oe_mask___byte2___width 1
+#define reg_iop_sw_cfg_rw_bus1_oe_mask___byte2___bit 2
+#define reg_iop_sw_cfg_rw_bus1_oe_mask___byte3___lsb 3
+#define reg_iop_sw_cfg_rw_bus1_oe_mask___byte3___width 1
+#define reg_iop_sw_cfg_rw_bus1_oe_mask___byte3___bit 3
+#define reg_iop_sw_cfg_rw_bus1_oe_mask_offset 148
+
+/* Register rw_gio_mask, scope iop_sw_cfg, type rw */
+#define reg_iop_sw_cfg_rw_gio_mask___val___lsb 0
+#define reg_iop_sw_cfg_rw_gio_mask___val___width 32
+#define reg_iop_sw_cfg_rw_gio_mask_offset 152
+
+/* Register rw_gio_oe_mask, scope iop_sw_cfg, type rw */
+#define reg_iop_sw_cfg_rw_gio_oe_mask___val___lsb 0
+#define reg_iop_sw_cfg_rw_gio_oe_mask___val___width 32
+#define reg_iop_sw_cfg_rw_gio_oe_mask_offset 156
+
+/* Register rw_pinmapping, scope iop_sw_cfg, type rw */
+#define reg_iop_sw_cfg_rw_pinmapping___bus0_byte0___lsb 0
+#define reg_iop_sw_cfg_rw_pinmapping___bus0_byte0___width 2
+#define reg_iop_sw_cfg_rw_pinmapping___bus0_byte1___lsb 2
+#define reg_iop_sw_cfg_rw_pinmapping___bus0_byte1___width 2
+#define reg_iop_sw_cfg_rw_pinmapping___bus0_byte2___lsb 4
+#define reg_iop_sw_cfg_rw_pinmapping___bus0_byte2___width 2
+#define reg_iop_sw_cfg_rw_pinmapping___bus0_byte3___lsb 6
+#define reg_iop_sw_cfg_rw_pinmapping___bus0_byte3___width 2
+#define reg_iop_sw_cfg_rw_pinmapping___bus1_byte0___lsb 8
+#define reg_iop_sw_cfg_rw_pinmapping___bus1_byte0___width 2
+#define reg_iop_sw_cfg_rw_pinmapping___bus1_byte1___lsb 10
+#define reg_iop_sw_cfg_rw_pinmapping___bus1_byte1___width 2
+#define reg_iop_sw_cfg_rw_pinmapping___bus1_byte2___lsb 12
+#define reg_iop_sw_cfg_rw_pinmapping___bus1_byte2___width 2
+#define reg_iop_sw_cfg_rw_pinmapping___bus1_byte3___lsb 14
+#define reg_iop_sw_cfg_rw_pinmapping___bus1_byte3___width 2
+#define reg_iop_sw_cfg_rw_pinmapping___gio3_0___lsb 16
+#define reg_iop_sw_cfg_rw_pinmapping___gio3_0___width 2
+#define reg_iop_sw_cfg_rw_pinmapping___gio7_4___lsb 18
+#define reg_iop_sw_cfg_rw_pinmapping___gio7_4___width 2
+#define reg_iop_sw_cfg_rw_pinmapping___gio11_8___lsb 20
+#define reg_iop_sw_cfg_rw_pinmapping___gio11_8___width 2
+#define reg_iop_sw_cfg_rw_pinmapping___gio15_12___lsb 22
+#define reg_iop_sw_cfg_rw_pinmapping___gio15_12___width 2
+#define reg_iop_sw_cfg_rw_pinmapping___gio19_16___lsb 24
+#define reg_iop_sw_cfg_rw_pinmapping___gio19_16___width 2
+#define reg_iop_sw_cfg_rw_pinmapping___gio23_20___lsb 26
+#define reg_iop_sw_cfg_rw_pinmapping___gio23_20___width 2
+#define reg_iop_sw_cfg_rw_pinmapping___gio27_24___lsb 28
+#define reg_iop_sw_cfg_rw_pinmapping___gio27_24___width 2
+#define reg_iop_sw_cfg_rw_pinmapping___gio31_28___lsb 30
+#define reg_iop_sw_cfg_rw_pinmapping___gio31_28___width 2
+#define reg_iop_sw_cfg_rw_pinmapping_offset 160
+
+/* Register rw_bus_out_cfg, scope iop_sw_cfg, type rw */
+#define reg_iop_sw_cfg_rw_bus_out_cfg___bus0_lo___lsb 0
+#define reg_iop_sw_cfg_rw_bus_out_cfg___bus0_lo___width 3
+#define reg_iop_sw_cfg_rw_bus_out_cfg___bus0_hi___lsb 3
+#define reg_iop_sw_cfg_rw_bus_out_cfg___bus0_hi___width 3
+#define reg_iop_sw_cfg_rw_bus_out_cfg___bus0_lo_oe___lsb 6
+#define reg_iop_sw_cfg_rw_bus_out_cfg___bus0_lo_oe___width 3
+#define reg_iop_sw_cfg_rw_bus_out_cfg___bus0_hi_oe___lsb 9
+#define reg_iop_sw_cfg_rw_bus_out_cfg___bus0_hi_oe___width 3
+#define reg_iop_sw_cfg_rw_bus_out_cfg___bus1_lo___lsb 12
+#define reg_iop_sw_cfg_rw_bus_out_cfg___bus1_lo___width 3
+#define reg_iop_sw_cfg_rw_bus_out_cfg___bus1_hi___lsb 15
+#define reg_iop_sw_cfg_rw_bus_out_cfg___bus1_hi___width 3
+#define reg_iop_sw_cfg_rw_bus_out_cfg___bus1_lo_oe___lsb 18
+#define reg_iop_sw_cfg_rw_bus_out_cfg___bus1_lo_oe___width 3
+#define reg_iop_sw_cfg_rw_bus_out_cfg___bus1_hi_oe___lsb 21
+#define reg_iop_sw_cfg_rw_bus_out_cfg___bus1_hi_oe___width 3
+#define reg_iop_sw_cfg_rw_bus_out_cfg_offset 164
+
+/* Register rw_gio_out_grp0_cfg, scope iop_sw_cfg, type rw */
+#define reg_iop_sw_cfg_rw_gio_out_grp0_cfg___gio0___lsb 0
+#define reg_iop_sw_cfg_rw_gio_out_grp0_cfg___gio0___width 4
+#define reg_iop_sw_cfg_rw_gio_out_grp0_cfg___gio0_oe___lsb 4
+#define reg_iop_sw_cfg_rw_gio_out_grp0_cfg___gio0_oe___width 2
+#define reg_iop_sw_cfg_rw_gio_out_grp0_cfg___gio1___lsb 6
+#define reg_iop_sw_cfg_rw_gio_out_grp0_cfg___gio1___width 4
+#define reg_iop_sw_cfg_rw_gio_out_grp0_cfg___gio1_oe___lsb 10
+#define reg_iop_sw_cfg_rw_gio_out_grp0_cfg___gio1_oe___width 2
+#define reg_iop_sw_cfg_rw_gio_out_grp0_cfg___gio2___lsb 12
+#define reg_iop_sw_cfg_rw_gio_out_grp0_cfg___gio2___width 4
+#define reg_iop_sw_cfg_rw_gio_out_grp0_cfg___gio2_oe___lsb 16
+#define reg_iop_sw_cfg_rw_gio_out_grp0_cfg___gio2_oe___width 2
+#define reg_iop_sw_cfg_rw_gio_out_grp0_cfg___gio3___lsb 18
+#define reg_iop_sw_cfg_rw_gio_out_grp0_cfg___gio3___width 4
+#define reg_iop_sw_cfg_rw_gio_out_grp0_cfg___gio3_oe___lsb 22
+#define reg_iop_sw_cfg_rw_gio_out_grp0_cfg___gio3_oe___width 2
+#define reg_iop_sw_cfg_rw_gio_out_grp0_cfg_offset 168
+
+/* Register rw_gio_out_grp1_cfg, scope iop_sw_cfg, type rw */
+#define reg_iop_sw_cfg_rw_gio_out_grp1_cfg___gio4___lsb 0
+#define reg_iop_sw_cfg_rw_gio_out_grp1_cfg___gio4___width 4
+#define reg_iop_sw_cfg_rw_gio_out_grp1_cfg___gio4_oe___lsb 4
+#define reg_iop_sw_cfg_rw_gio_out_grp1_cfg___gio4_oe___width 2
+#define reg_iop_sw_cfg_rw_gio_out_grp1_cfg___gio5___lsb 6
+#define reg_iop_sw_cfg_rw_gio_out_grp1_cfg___gio5___width 4
+#define reg_iop_sw_cfg_rw_gio_out_grp1_cfg___gio5_oe___lsb 10
+#define reg_iop_sw_cfg_rw_gio_out_grp1_cfg___gio5_oe___width 2
+#define reg_iop_sw_cfg_rw_gio_out_grp1_cfg___gio6___lsb 12
+#define reg_iop_sw_cfg_rw_gio_out_grp1_cfg___gio6___width 4
+#define reg_iop_sw_cfg_rw_gio_out_grp1_cfg___gio6_oe___lsb 16
+#define reg_iop_sw_cfg_rw_gio_out_grp1_cfg___gio6_oe___width 2
+#define reg_iop_sw_cfg_rw_gio_out_grp1_cfg___gio7___lsb 18
+#define reg_iop_sw_cfg_rw_gio_out_grp1_cfg___gio7___width 4
+#define reg_iop_sw_cfg_rw_gio_out_grp1_cfg___gio7_oe___lsb 22
+#define reg_iop_sw_cfg_rw_gio_out_grp1_cfg___gio7_oe___width 2
+#define reg_iop_sw_cfg_rw_gio_out_grp1_cfg_offset 172
+
+/* Register rw_gio_out_grp2_cfg, scope iop_sw_cfg, type rw */
+#define reg_iop_sw_cfg_rw_gio_out_grp2_cfg___gio8___lsb 0
+#define reg_iop_sw_cfg_rw_gio_out_grp2_cfg___gio8___width 4
+#define reg_iop_sw_cfg_rw_gio_out_grp2_cfg___gio8_oe___lsb 4
+#define reg_iop_sw_cfg_rw_gio_out_grp2_cfg___gio8_oe___width 2
+#define reg_iop_sw_cfg_rw_gio_out_grp2_cfg___gio9___lsb 6
+#define reg_iop_sw_cfg_rw_gio_out_grp2_cfg___gio9___width 4
+#define reg_iop_sw_cfg_rw_gio_out_grp2_cfg___gio9_oe___lsb 10
+#define reg_iop_sw_cfg_rw_gio_out_grp2_cfg___gio9_oe___width 2
+#define reg_iop_sw_cfg_rw_gio_out_grp2_cfg___gio10___lsb 12
+#define reg_iop_sw_cfg_rw_gio_out_grp2_cfg___gio10___width 4
+#define reg_iop_sw_cfg_rw_gio_out_grp2_cfg___gio10_oe___lsb 16
+#define reg_iop_sw_cfg_rw_gio_out_grp2_cfg___gio10_oe___width 2
+#define reg_iop_sw_cfg_rw_gio_out_grp2_cfg___gio11___lsb 18
+#define reg_iop_sw_cfg_rw_gio_out_grp2_cfg___gio11___width 4
+#define reg_iop_sw_cfg_rw_gio_out_grp2_cfg___gio11_oe___lsb 22
+#define reg_iop_sw_cfg_rw_gio_out_grp2_cfg___gio11_oe___width 2
+#define reg_iop_sw_cfg_rw_gio_out_grp2_cfg_offset 176
+
+/* Register rw_gio_out_grp3_cfg, scope iop_sw_cfg, type rw */
+#define reg_iop_sw_cfg_rw_gio_out_grp3_cfg___gio12___lsb 0
+#define reg_iop_sw_cfg_rw_gio_out_grp3_cfg___gio12___width 4
+#define reg_iop_sw_cfg_rw_gio_out_grp3_cfg___gio12_oe___lsb 4
+#define reg_iop_sw_cfg_rw_gio_out_grp3_cfg___gio12_oe___width 2
+#define reg_iop_sw_cfg_rw_gio_out_grp3_cfg___gio13___lsb 6
+#define reg_iop_sw_cfg_rw_gio_out_grp3_cfg___gio13___width 4
+#define reg_iop_sw_cfg_rw_gio_out_grp3_cfg___gio13_oe___lsb 10
+#define reg_iop_sw_cfg_rw_gio_out_grp3_cfg___gio13_oe___width 2
+#define reg_iop_sw_cfg_rw_gio_out_grp3_cfg___gio14___lsb 12
+#define reg_iop_sw_cfg_rw_gio_out_grp3_cfg___gio14___width 4
+#define reg_iop_sw_cfg_rw_gio_out_grp3_cfg___gio14_oe___lsb 16
+#define reg_iop_sw_cfg_rw_gio_out_grp3_cfg___gio14_oe___width 2
+#define reg_iop_sw_cfg_rw_gio_out_grp3_cfg___gio15___lsb 18
+#define reg_iop_sw_cfg_rw_gio_out_grp3_cfg___gio15___width 4
+#define reg_iop_sw_cfg_rw_gio_out_grp3_cfg___gio15_oe___lsb 22
+#define reg_iop_sw_cfg_rw_gio_out_grp3_cfg___gio15_oe___width 2
+#define reg_iop_sw_cfg_rw_gio_out_grp3_cfg_offset 180
+
+/* Register rw_gio_out_grp4_cfg, scope iop_sw_cfg, type rw */
+#define reg_iop_sw_cfg_rw_gio_out_grp4_cfg___gio16___lsb 0
+#define reg_iop_sw_cfg_rw_gio_out_grp4_cfg___gio16___width 4
+#define reg_iop_sw_cfg_rw_gio_out_grp4_cfg___gio16_oe___lsb 4
+#define reg_iop_sw_cfg_rw_gio_out_grp4_cfg___gio16_oe___width 2
+#define reg_iop_sw_cfg_rw_gio_out_grp4_cfg___gio17___lsb 6
+#define reg_iop_sw_cfg_rw_gio_out_grp4_cfg___gio17___width 4
+#define reg_iop_sw_cfg_rw_gio_out_grp4_cfg___gio17_oe___lsb 10
+#define reg_iop_sw_cfg_rw_gio_out_grp4_cfg___gio17_oe___width 2
+#define reg_iop_sw_cfg_rw_gio_out_grp4_cfg___gio18___lsb 12
+#define reg_iop_sw_cfg_rw_gio_out_grp4_cfg___gio18___width 4
+#define reg_iop_sw_cfg_rw_gio_out_grp4_cfg___gio18_oe___lsb 16
+#define reg_iop_sw_cfg_rw_gio_out_grp4_cfg___gio18_oe___width 2
+#define reg_iop_sw_cfg_rw_gio_out_grp4_cfg___gio19___lsb 18
+#define reg_iop_sw_cfg_rw_gio_out_grp4_cfg___gio19___width 4
+#define reg_iop_sw_cfg_rw_gio_out_grp4_cfg___gio19_oe___lsb 22
+#define reg_iop_sw_cfg_rw_gio_out_grp4_cfg___gio19_oe___width 2
+#define reg_iop_sw_cfg_rw_gio_out_grp4_cfg_offset 184
+
+/* Register rw_gio_out_grp5_cfg, scope iop_sw_cfg, type rw */
+#define reg_iop_sw_cfg_rw_gio_out_grp5_cfg___gio20___lsb 0
+#define reg_iop_sw_cfg_rw_gio_out_grp5_cfg___gio20___width 4
+#define reg_iop_sw_cfg_rw_gio_out_grp5_cfg___gio20_oe___lsb 4
+#define reg_iop_sw_cfg_rw_gio_out_grp5_cfg___gio20_oe___width 2
+#define reg_iop_sw_cfg_rw_gio_out_grp5_cfg___gio21___lsb 6
+#define reg_iop_sw_cfg_rw_gio_out_grp5_cfg___gio21___width 4
+#define reg_iop_sw_cfg_rw_gio_out_grp5_cfg___gio21_oe___lsb 10
+#define reg_iop_sw_cfg_rw_gio_out_grp5_cfg___gio21_oe___width 2
+#define reg_iop_sw_cfg_rw_gio_out_grp5_cfg___gio22___lsb 12
+#define reg_iop_sw_cfg_rw_gio_out_grp5_cfg___gio22___width 4
+#define reg_iop_sw_cfg_rw_gio_out_grp5_cfg___gio22_oe___lsb 16
+#define reg_iop_sw_cfg_rw_gio_out_grp5_cfg___gio22_oe___width 2
+#define reg_iop_sw_cfg_rw_gio_out_grp5_cfg___gio23___lsb 18
+#define reg_iop_sw_cfg_rw_gio_out_grp5_cfg___gio23___width 4
+#define reg_iop_sw_cfg_rw_gio_out_grp5_cfg___gio23_oe___lsb 22
+#define reg_iop_sw_cfg_rw_gio_out_grp5_cfg___gio23_oe___width 2
+#define reg_iop_sw_cfg_rw_gio_out_grp5_cfg_offset 188
+
+/* Register rw_gio_out_grp6_cfg, scope iop_sw_cfg, type rw */
+#define reg_iop_sw_cfg_rw_gio_out_grp6_cfg___gio24___lsb 0
+#define reg_iop_sw_cfg_rw_gio_out_grp6_cfg___gio24___width 4
+#define reg_iop_sw_cfg_rw_gio_out_grp6_cfg___gio24_oe___lsb 4
+#define reg_iop_sw_cfg_rw_gio_out_grp6_cfg___gio24_oe___width 2
+#define reg_iop_sw_cfg_rw_gio_out_grp6_cfg___gio25___lsb 6
+#define reg_iop_sw_cfg_rw_gio_out_grp6_cfg___gio25___width 4
+#define reg_iop_sw_cfg_rw_gio_out_grp6_cfg___gio25_oe___lsb 10
+#define reg_iop_sw_cfg_rw_gio_out_grp6_cfg___gio25_oe___width 2
+#define reg_iop_sw_cfg_rw_gio_out_grp6_cfg___gio26___lsb 12
+#define reg_iop_sw_cfg_rw_gio_out_grp6_cfg___gio26___width 4
+#define reg_iop_sw_cfg_rw_gio_out_grp6_cfg___gio26_oe___lsb 16
+#define reg_iop_sw_cfg_rw_gio_out_grp6_cfg___gio26_oe___width 2
+#define reg_iop_sw_cfg_rw_gio_out_grp6_cfg___gio27___lsb 18
+#define reg_iop_sw_cfg_rw_gio_out_grp6_cfg___gio27___width 4
+#define reg_iop_sw_cfg_rw_gio_out_grp6_cfg___gio27_oe___lsb 22
+#define reg_iop_sw_cfg_rw_gio_out_grp6_cfg___gio27_oe___width 2
+#define reg_iop_sw_cfg_rw_gio_out_grp6_cfg_offset 192
+
+/* Register rw_gio_out_grp7_cfg, scope iop_sw_cfg, type rw */
+#define reg_iop_sw_cfg_rw_gio_out_grp7_cfg___gio28___lsb 0
+#define reg_iop_sw_cfg_rw_gio_out_grp7_cfg___gio28___width 4
+#define reg_iop_sw_cfg_rw_gio_out_grp7_cfg___gio28_oe___lsb 4
+#define reg_iop_sw_cfg_rw_gio_out_grp7_cfg___gio28_oe___width 2
+#define reg_iop_sw_cfg_rw_gio_out_grp7_cfg___gio29___lsb 6
+#define reg_iop_sw_cfg_rw_gio_out_grp7_cfg___gio29___width 4
+#define reg_iop_sw_cfg_rw_gio_out_grp7_cfg___gio29_oe___lsb 10
+#define reg_iop_sw_cfg_rw_gio_out_grp7_cfg___gio29_oe___width 2
+#define reg_iop_sw_cfg_rw_gio_out_grp7_cfg___gio30___lsb 12
+#define reg_iop_sw_cfg_rw_gio_out_grp7_cfg___gio30___width 4
+#define reg_iop_sw_cfg_rw_gio_out_grp7_cfg___gio30_oe___lsb 16
+#define reg_iop_sw_cfg_rw_gio_out_grp7_cfg___gio30_oe___width 2
+#define reg_iop_sw_cfg_rw_gio_out_grp7_cfg___gio31___lsb 18
+#define reg_iop_sw_cfg_rw_gio_out_grp7_cfg___gio31___width 4
+#define reg_iop_sw_cfg_rw_gio_out_grp7_cfg___gio31_oe___lsb 22
+#define reg_iop_sw_cfg_rw_gio_out_grp7_cfg___gio31_oe___width 2
+#define reg_iop_sw_cfg_rw_gio_out_grp7_cfg_offset 196
+
+/* Register rw_spu0_cfg, scope iop_sw_cfg, type rw */
+#define reg_iop_sw_cfg_rw_spu0_cfg___bus0_in___lsb 0
+#define reg_iop_sw_cfg_rw_spu0_cfg___bus0_in___width 2
+#define reg_iop_sw_cfg_rw_spu0_cfg___bus1_in___lsb 2
+#define reg_iop_sw_cfg_rw_spu0_cfg___bus1_in___width 2
+#define reg_iop_sw_cfg_rw_spu0_cfg_offset 200
+
+/* Register rw_spu1_cfg, scope iop_sw_cfg, type rw */
+#define reg_iop_sw_cfg_rw_spu1_cfg___bus0_in___lsb 0
+#define reg_iop_sw_cfg_rw_spu1_cfg___bus0_in___width 2
+#define reg_iop_sw_cfg_rw_spu1_cfg___bus1_in___lsb 2
+#define reg_iop_sw_cfg_rw_spu1_cfg___bus1_in___width 2
+#define reg_iop_sw_cfg_rw_spu1_cfg_offset 204
+
+/* Register rw_timer_grp0_cfg, scope iop_sw_cfg, type rw */
+#define reg_iop_sw_cfg_rw_timer_grp0_cfg___ext_clk___lsb 0
+#define reg_iop_sw_cfg_rw_timer_grp0_cfg___ext_clk___width 3
+#define reg_iop_sw_cfg_rw_timer_grp0_cfg___tmr0_en___lsb 3
+#define reg_iop_sw_cfg_rw_timer_grp0_cfg___tmr0_en___width 1
+#define reg_iop_sw_cfg_rw_timer_grp0_cfg___tmr0_en___bit 3
+#define reg_iop_sw_cfg_rw_timer_grp0_cfg___tmr1_en___lsb 4
+#define reg_iop_sw_cfg_rw_timer_grp0_cfg___tmr1_en___width 1
+#define reg_iop_sw_cfg_rw_timer_grp0_cfg___tmr1_en___bit 4
+#define reg_iop_sw_cfg_rw_timer_grp0_cfg___tmr2_en___lsb 5
+#define reg_iop_sw_cfg_rw_timer_grp0_cfg___tmr2_en___width 1
+#define reg_iop_sw_cfg_rw_timer_grp0_cfg___tmr2_en___bit 5
+#define reg_iop_sw_cfg_rw_timer_grp0_cfg___tmr3_en___lsb 6
+#define reg_iop_sw_cfg_rw_timer_grp0_cfg___tmr3_en___width 1
+#define reg_iop_sw_cfg_rw_timer_grp0_cfg___tmr3_en___bit 6
+#define reg_iop_sw_cfg_rw_timer_grp0_cfg___tmr0_dis___lsb 7
+#define reg_iop_sw_cfg_rw_timer_grp0_cfg___tmr0_dis___width 1
+#define reg_iop_sw_cfg_rw_timer_grp0_cfg___tmr0_dis___bit 7
+#define reg_iop_sw_cfg_rw_timer_grp0_cfg___tmr1_dis___lsb 8
+#define reg_iop_sw_cfg_rw_timer_grp0_cfg___tmr1_dis___width 1
+#define reg_iop_sw_cfg_rw_timer_grp0_cfg___tmr1_dis___bit 8
+#define reg_iop_sw_cfg_rw_timer_grp0_cfg___tmr2_dis___lsb 9
+#define reg_iop_sw_cfg_rw_timer_grp0_cfg___tmr2_dis___width 1
+#define reg_iop_sw_cfg_rw_timer_grp0_cfg___tmr2_dis___bit 9
+#define reg_iop_sw_cfg_rw_timer_grp0_cfg___tmr3_dis___lsb 10
+#define reg_iop_sw_cfg_rw_timer_grp0_cfg___tmr3_dis___width 1
+#define reg_iop_sw_cfg_rw_timer_grp0_cfg___tmr3_dis___bit 10
+#define reg_iop_sw_cfg_rw_timer_grp0_cfg_offset 208
+
+/* Register rw_timer_grp1_cfg, scope iop_sw_cfg, type rw */
+#define reg_iop_sw_cfg_rw_timer_grp1_cfg___ext_clk___lsb 0
+#define reg_iop_sw_cfg_rw_timer_grp1_cfg___ext_clk___width 3
+#define reg_iop_sw_cfg_rw_timer_grp1_cfg___tmr0_en___lsb 3
+#define reg_iop_sw_cfg_rw_timer_grp1_cfg___tmr0_en___width 1
+#define reg_iop_sw_cfg_rw_timer_grp1_cfg___tmr0_en___bit 3
+#define reg_iop_sw_cfg_rw_timer_grp1_cfg___tmr1_en___lsb 4
+#define reg_iop_sw_cfg_rw_timer_grp1_cfg___tmr1_en___width 1
+#define reg_iop_sw_cfg_rw_timer_grp1_cfg___tmr1_en___bit 4
+#define reg_iop_sw_cfg_rw_timer_grp1_cfg___tmr2_en___lsb 5
+#define reg_iop_sw_cfg_rw_timer_grp1_cfg___tmr2_en___width 1
+#define reg_iop_sw_cfg_rw_timer_grp1_cfg___tmr2_en___bit 5
+#define reg_iop_sw_cfg_rw_timer_grp1_cfg___tmr3_en___lsb 6
+#define reg_iop_sw_cfg_rw_timer_grp1_cfg___tmr3_en___width 1
+#define reg_iop_sw_cfg_rw_timer_grp1_cfg___tmr3_en___bit 6
+#define reg_iop_sw_cfg_rw_timer_grp1_cfg___tmr0_dis___lsb 7
+#define reg_iop_sw_cfg_rw_timer_grp1_cfg___tmr0_dis___width 1
+#define reg_iop_sw_cfg_rw_timer_grp1_cfg___tmr0_dis___bit 7
+#define reg_iop_sw_cfg_rw_timer_grp1_cfg___tmr1_dis___lsb 8
+#define reg_iop_sw_cfg_rw_timer_grp1_cfg___tmr1_dis___width 1
+#define reg_iop_sw_cfg_rw_timer_grp1_cfg___tmr1_dis___bit 8
+#define reg_iop_sw_cfg_rw_timer_grp1_cfg___tmr2_dis___lsb 9
+#define reg_iop_sw_cfg_rw_timer_grp1_cfg___tmr2_dis___width 1
+#define reg_iop_sw_cfg_rw_timer_grp1_cfg___tmr2_dis___bit 9
+#define reg_iop_sw_cfg_rw_timer_grp1_cfg___tmr3_dis___lsb 10
+#define reg_iop_sw_cfg_rw_timer_grp1_cfg___tmr3_dis___width 1
+#define reg_iop_sw_cfg_rw_timer_grp1_cfg___tmr3_dis___bit 10
+#define reg_iop_sw_cfg_rw_timer_grp1_cfg_offset 212
+
+/* Register rw_timer_grp2_cfg, scope iop_sw_cfg, type rw */
+#define reg_iop_sw_cfg_rw_timer_grp2_cfg___ext_clk___lsb 0
+#define reg_iop_sw_cfg_rw_timer_grp2_cfg___ext_clk___width 3
+#define reg_iop_sw_cfg_rw_timer_grp2_cfg___tmr0_en___lsb 3
+#define reg_iop_sw_cfg_rw_timer_grp2_cfg___tmr0_en___width 1
+#define reg_iop_sw_cfg_rw_timer_grp2_cfg___tmr0_en___bit 3
+#define reg_iop_sw_cfg_rw_timer_grp2_cfg___tmr1_en___lsb 4
+#define reg_iop_sw_cfg_rw_timer_grp2_cfg___tmr1_en___width 1
+#define reg_iop_sw_cfg_rw_timer_grp2_cfg___tmr1_en___bit 4
+#define reg_iop_sw_cfg_rw_timer_grp2_cfg___tmr2_en___lsb 5
+#define reg_iop_sw_cfg_rw_timer_grp2_cfg___tmr2_en___width 1
+#define reg_iop_sw_cfg_rw_timer_grp2_cfg___tmr2_en___bit 5
+#define reg_iop_sw_cfg_rw_timer_grp2_cfg___tmr3_en___lsb 6
+#define reg_iop_sw_cfg_rw_timer_grp2_cfg___tmr3_en___width 1
+#define reg_iop_sw_cfg_rw_timer_grp2_cfg___tmr3_en___bit 6
+#define reg_iop_sw_cfg_rw_timer_grp2_cfg___tmr0_dis___lsb 7
+#define reg_iop_sw_cfg_rw_timer_grp2_cfg___tmr0_dis___width 1
+#define reg_iop_sw_cfg_rw_timer_grp2_cfg___tmr0_dis___bit 7
+#define reg_iop_sw_cfg_rw_timer_grp2_cfg___tmr1_dis___lsb 8
+#define reg_iop_sw_cfg_rw_timer_grp2_cfg___tmr1_dis___width 1
+#define reg_iop_sw_cfg_rw_timer_grp2_cfg___tmr1_dis___bit 8
+#define reg_iop_sw_cfg_rw_timer_grp2_cfg___tmr2_dis___lsb 9
+#define reg_iop_sw_cfg_rw_timer_grp2_cfg___tmr2_dis___width 1
+#define reg_iop_sw_cfg_rw_timer_grp2_cfg___tmr2_dis___bit 9
+#define reg_iop_sw_cfg_rw_timer_grp2_cfg___tmr3_dis___lsb 10
+#define reg_iop_sw_cfg_rw_timer_grp2_cfg___tmr3_dis___width 1
+#define reg_iop_sw_cfg_rw_timer_grp2_cfg___tmr3_dis___bit 10
+#define reg_iop_sw_cfg_rw_timer_grp2_cfg_offset 216
+
+/* Register rw_timer_grp3_cfg, scope iop_sw_cfg, type rw */
+#define reg_iop_sw_cfg_rw_timer_grp3_cfg___ext_clk___lsb 0
+#define reg_iop_sw_cfg_rw_timer_grp3_cfg___ext_clk___width 3
+#define reg_iop_sw_cfg_rw_timer_grp3_cfg___tmr0_en___lsb 3
+#define reg_iop_sw_cfg_rw_timer_grp3_cfg___tmr0_en___width 1
+#define reg_iop_sw_cfg_rw_timer_grp3_cfg___tmr0_en___bit 3
+#define reg_iop_sw_cfg_rw_timer_grp3_cfg___tmr1_en___lsb 4
+#define reg_iop_sw_cfg_rw_timer_grp3_cfg___tmr1_en___width 1
+#define reg_iop_sw_cfg_rw_timer_grp3_cfg___tmr1_en___bit 4
+#define reg_iop_sw_cfg_rw_timer_grp3_cfg___tmr2_en___lsb 5
+#define reg_iop_sw_cfg_rw_timer_grp3_cfg___tmr2_en___width 1
+#define reg_iop_sw_cfg_rw_timer_grp3_cfg___tmr2_en___bit 5
+#define reg_iop_sw_cfg_rw_timer_grp3_cfg___tmr3_en___lsb 6
+#define reg_iop_sw_cfg_rw_timer_grp3_cfg___tmr3_en___width 1
+#define reg_iop_sw_cfg_rw_timer_grp3_cfg___tmr3_en___bit 6
+#define reg_iop_sw_cfg_rw_timer_grp3_cfg___tmr0_dis___lsb 7
+#define reg_iop_sw_cfg_rw_timer_grp3_cfg___tmr0_dis___width 1
+#define reg_iop_sw_cfg_rw_timer_grp3_cfg___tmr0_dis___bit 7
+#define reg_iop_sw_cfg_rw_timer_grp3_cfg___tmr1_dis___lsb 8
+#define reg_iop_sw_cfg_rw_timer_grp3_cfg___tmr1_dis___width 1
+#define reg_iop_sw_cfg_rw_timer_grp3_cfg___tmr1_dis___bit 8
+#define reg_iop_sw_cfg_rw_timer_grp3_cfg___tmr2_dis___lsb 9
+#define reg_iop_sw_cfg_rw_timer_grp3_cfg___tmr2_dis___width 1
+#define reg_iop_sw_cfg_rw_timer_grp3_cfg___tmr2_dis___bit 9
+#define reg_iop_sw_cfg_rw_timer_grp3_cfg___tmr3_dis___lsb 10
+#define reg_iop_sw_cfg_rw_timer_grp3_cfg___tmr3_dis___width 1
+#define reg_iop_sw_cfg_rw_timer_grp3_cfg___tmr3_dis___bit 10
+#define reg_iop_sw_cfg_rw_timer_grp3_cfg_offset 220
+
+/* Register rw_trigger_grps_cfg, scope iop_sw_cfg, type rw */
+#define reg_iop_sw_cfg_rw_trigger_grps_cfg___grp0_dis___lsb 0
+#define reg_iop_sw_cfg_rw_trigger_grps_cfg___grp0_dis___width 1
+#define reg_iop_sw_cfg_rw_trigger_grps_cfg___grp0_dis___bit 0
+#define reg_iop_sw_cfg_rw_trigger_grps_cfg___grp0_en___lsb 1
+#define reg_iop_sw_cfg_rw_trigger_grps_cfg___grp0_en___width 1
+#define reg_iop_sw_cfg_rw_trigger_grps_cfg___grp0_en___bit 1
+#define reg_iop_sw_cfg_rw_trigger_grps_cfg___grp1_dis___lsb 2
+#define reg_iop_sw_cfg_rw_trigger_grps_cfg___grp1_dis___width 1
+#define reg_iop_sw_cfg_rw_trigger_grps_cfg___grp1_dis___bit 2
+#define reg_iop_sw_cfg_rw_trigger_grps_cfg___grp1_en___lsb 3
+#define reg_iop_sw_cfg_rw_trigger_grps_cfg___grp1_en___width 1
+#define reg_iop_sw_cfg_rw_trigger_grps_cfg___grp1_en___bit 3
+#define reg_iop_sw_cfg_rw_trigger_grps_cfg___grp2_dis___lsb 4
+#define reg_iop_sw_cfg_rw_trigger_grps_cfg___grp2_dis___width 1
+#define reg_iop_sw_cfg_rw_trigger_grps_cfg___grp2_dis___bit 4
+#define reg_iop_sw_cfg_rw_trigger_grps_cfg___grp2_en___lsb 5
+#define reg_iop_sw_cfg_rw_trigger_grps_cfg___grp2_en___width 1
+#define reg_iop_sw_cfg_rw_trigger_grps_cfg___grp2_en___bit 5
+#define reg_iop_sw_cfg_rw_trigger_grps_cfg___grp3_dis___lsb 6
+#define reg_iop_sw_cfg_rw_trigger_grps_cfg___grp3_dis___width 1
+#define reg_iop_sw_cfg_rw_trigger_grps_cfg___grp3_dis___bit 6
+#define reg_iop_sw_cfg_rw_trigger_grps_cfg___grp3_en___lsb 7
+#define reg_iop_sw_cfg_rw_trigger_grps_cfg___grp3_en___width 1
+#define reg_iop_sw_cfg_rw_trigger_grps_cfg___grp3_en___bit 7
+#define reg_iop_sw_cfg_rw_trigger_grps_cfg___grp4_dis___lsb 8
+#define reg_iop_sw_cfg_rw_trigger_grps_cfg___grp4_dis___width 1
+#define reg_iop_sw_cfg_rw_trigger_grps_cfg___grp4_dis___bit 8
+#define reg_iop_sw_cfg_rw_trigger_grps_cfg___grp4_en___lsb 9
+#define reg_iop_sw_cfg_rw_trigger_grps_cfg___grp4_en___width 1
+#define reg_iop_sw_cfg_rw_trigger_grps_cfg___grp4_en___bit 9
+#define reg_iop_sw_cfg_rw_trigger_grps_cfg___grp5_dis___lsb 10
+#define reg_iop_sw_cfg_rw_trigger_grps_cfg___grp5_dis___width 1
+#define reg_iop_sw_cfg_rw_trigger_grps_cfg___grp5_dis___bit 10
+#define reg_iop_sw_cfg_rw_trigger_grps_cfg___grp5_en___lsb 11
+#define reg_iop_sw_cfg_rw_trigger_grps_cfg___grp5_en___width 1
+#define reg_iop_sw_cfg_rw_trigger_grps_cfg___grp5_en___bit 11
+#define reg_iop_sw_cfg_rw_trigger_grps_cfg___grp6_dis___lsb 12
+#define reg_iop_sw_cfg_rw_trigger_grps_cfg___grp6_dis___width 1
+#define reg_iop_sw_cfg_rw_trigger_grps_cfg___grp6_dis___bit 12
+#define reg_iop_sw_cfg_rw_trigger_grps_cfg___grp6_en___lsb 13
+#define reg_iop_sw_cfg_rw_trigger_grps_cfg___grp6_en___width 1
+#define reg_iop_sw_cfg_rw_trigger_grps_cfg___grp6_en___bit 13
+#define reg_iop_sw_cfg_rw_trigger_grps_cfg___grp7_dis___lsb 14
+#define reg_iop_sw_cfg_rw_trigger_grps_cfg___grp7_dis___width 1
+#define reg_iop_sw_cfg_rw_trigger_grps_cfg___grp7_dis___bit 14
+#define reg_iop_sw_cfg_rw_trigger_grps_cfg___grp7_en___lsb 15
+#define reg_iop_sw_cfg_rw_trigger_grps_cfg___grp7_en___width 1
+#define reg_iop_sw_cfg_rw_trigger_grps_cfg___grp7_en___bit 15
+#define reg_iop_sw_cfg_rw_trigger_grps_cfg_offset 224
+
+/* Register rw_pdp0_cfg, scope iop_sw_cfg, type rw */
+#define reg_iop_sw_cfg_rw_pdp0_cfg___dmc0_usr___lsb 0
+#define reg_iop_sw_cfg_rw_pdp0_cfg___dmc0_usr___width 1
+#define reg_iop_sw_cfg_rw_pdp0_cfg___dmc0_usr___bit 0
+#define reg_iop_sw_cfg_rw_pdp0_cfg___out_strb___lsb 1
+#define reg_iop_sw_cfg_rw_pdp0_cfg___out_strb___width 5
+#define reg_iop_sw_cfg_rw_pdp0_cfg___in_src___lsb 6
+#define reg_iop_sw_cfg_rw_pdp0_cfg___in_src___width 3
+#define reg_iop_sw_cfg_rw_pdp0_cfg___in_size___lsb 9
+#define reg_iop_sw_cfg_rw_pdp0_cfg___in_size___width 3
+#define reg_iop_sw_cfg_rw_pdp0_cfg___in_last___lsb 12
+#define reg_iop_sw_cfg_rw_pdp0_cfg___in_last___width 2
+#define reg_iop_sw_cfg_rw_pdp0_cfg___in_strb___lsb 14
+#define reg_iop_sw_cfg_rw_pdp0_cfg___in_strb___width 4
+#define reg_iop_sw_cfg_rw_pdp0_cfg___out_src___lsb 18
+#define reg_iop_sw_cfg_rw_pdp0_cfg___out_src___width 1
+#define reg_iop_sw_cfg_rw_pdp0_cfg___out_src___bit 18
+#define reg_iop_sw_cfg_rw_pdp0_cfg_offset 228
+
+/* Register rw_pdp1_cfg, scope iop_sw_cfg, type rw */
+#define reg_iop_sw_cfg_rw_pdp1_cfg___dmc1_usr___lsb 0
+#define reg_iop_sw_cfg_rw_pdp1_cfg___dmc1_usr___width 1
+#define reg_iop_sw_cfg_rw_pdp1_cfg___dmc1_usr___bit 0
+#define reg_iop_sw_cfg_rw_pdp1_cfg___out_strb___lsb 1
+#define reg_iop_sw_cfg_rw_pdp1_cfg___out_strb___width 5
+#define reg_iop_sw_cfg_rw_pdp1_cfg___in_src___lsb 6
+#define reg_iop_sw_cfg_rw_pdp1_cfg___in_src___width 3
+#define reg_iop_sw_cfg_rw_pdp1_cfg___in_size___lsb 9
+#define reg_iop_sw_cfg_rw_pdp1_cfg___in_size___width 3
+#define reg_iop_sw_cfg_rw_pdp1_cfg___in_last___lsb 12
+#define reg_iop_sw_cfg_rw_pdp1_cfg___in_last___width 2
+#define reg_iop_sw_cfg_rw_pdp1_cfg___in_strb___lsb 14
+#define reg_iop_sw_cfg_rw_pdp1_cfg___in_strb___width 4
+#define reg_iop_sw_cfg_rw_pdp1_cfg___out_src___lsb 18
+#define reg_iop_sw_cfg_rw_pdp1_cfg___out_src___width 1
+#define reg_iop_sw_cfg_rw_pdp1_cfg___out_src___bit 18
+#define reg_iop_sw_cfg_rw_pdp1_cfg_offset 232
+
+/* Register rw_sdp_cfg, scope iop_sw_cfg, type rw */
+#define reg_iop_sw_cfg_rw_sdp_cfg___sdp_out0_strb___lsb 0
+#define reg_iop_sw_cfg_rw_sdp_cfg___sdp_out0_strb___width 3
+#define reg_iop_sw_cfg_rw_sdp_cfg___sdp_out1_strb___lsb 3
+#define reg_iop_sw_cfg_rw_sdp_cfg___sdp_out1_strb___width 3
+#define reg_iop_sw_cfg_rw_sdp_cfg___sdp_in0_data___lsb 6
+#define reg_iop_sw_cfg_rw_sdp_cfg___sdp_in0_data___width 3
+#define reg_iop_sw_cfg_rw_sdp_cfg___sdp_in0_last___lsb 9
+#define reg_iop_sw_cfg_rw_sdp_cfg___sdp_in0_last___width 2
+#define reg_iop_sw_cfg_rw_sdp_cfg___sdp_in0_strb___lsb 11
+#define reg_iop_sw_cfg_rw_sdp_cfg___sdp_in0_strb___width 3
+#define reg_iop_sw_cfg_rw_sdp_cfg___sdp_in1_data___lsb 14
+#define reg_iop_sw_cfg_rw_sdp_cfg___sdp_in1_data___width 3
+#define reg_iop_sw_cfg_rw_sdp_cfg___sdp_in1_last___lsb 17
+#define reg_iop_sw_cfg_rw_sdp_cfg___sdp_in1_last___width 2
+#define reg_iop_sw_cfg_rw_sdp_cfg___sdp_in1_strb___lsb 19
+#define reg_iop_sw_cfg_rw_sdp_cfg___sdp_in1_strb___width 3
+#define reg_iop_sw_cfg_rw_sdp_cfg_offset 236
+
+
+/* Constants */
+#define regk_iop_sw_cfg_a                         0x00000001
+#define regk_iop_sw_cfg_b                         0x00000002
+#define regk_iop_sw_cfg_bus0                      0x00000000
+#define regk_iop_sw_cfg_bus0_rot16                0x00000004
+#define regk_iop_sw_cfg_bus0_rot24                0x00000006
+#define regk_iop_sw_cfg_bus0_rot8                 0x00000002
+#define regk_iop_sw_cfg_bus1                      0x00000001
+#define regk_iop_sw_cfg_bus1_rot16                0x00000005
+#define regk_iop_sw_cfg_bus1_rot24                0x00000007
+#define regk_iop_sw_cfg_bus1_rot8                 0x00000003
+#define regk_iop_sw_cfg_clk12                     0x00000000
+#define regk_iop_sw_cfg_cpu                       0x00000000
+#define regk_iop_sw_cfg_dmc0                      0x00000000
+#define regk_iop_sw_cfg_dmc1                      0x00000001
+#define regk_iop_sw_cfg_gated_clk0                0x00000010
+#define regk_iop_sw_cfg_gated_clk1                0x00000011
+#define regk_iop_sw_cfg_gated_clk2                0x00000012
+#define regk_iop_sw_cfg_gated_clk3                0x00000013
+#define regk_iop_sw_cfg_gio0                      0x00000004
+#define regk_iop_sw_cfg_gio1                      0x00000001
+#define regk_iop_sw_cfg_gio2                      0x00000005
+#define regk_iop_sw_cfg_gio3                      0x00000002
+#define regk_iop_sw_cfg_gio4                      0x00000006
+#define regk_iop_sw_cfg_gio5                      0x00000003
+#define regk_iop_sw_cfg_gio6                      0x00000007
+#define regk_iop_sw_cfg_gio7                      0x00000004
+#define regk_iop_sw_cfg_gio_in0                   0x00000000
+#define regk_iop_sw_cfg_gio_in1                   0x00000001
+#define regk_iop_sw_cfg_gio_in10                  0x00000002
+#define regk_iop_sw_cfg_gio_in11                  0x00000003
+#define regk_iop_sw_cfg_gio_in14                  0x00000004
+#define regk_iop_sw_cfg_gio_in15                  0x00000005
+#define regk_iop_sw_cfg_gio_in18                  0x00000002
+#define regk_iop_sw_cfg_gio_in19                  0x00000003
+#define regk_iop_sw_cfg_gio_in20                  0x00000004
+#define regk_iop_sw_cfg_gio_in21                  0x00000005
+#define regk_iop_sw_cfg_gio_in26                  0x00000006
+#define regk_iop_sw_cfg_gio_in27                  0x00000007
+#define regk_iop_sw_cfg_gio_in28                  0x00000006
+#define regk_iop_sw_cfg_gio_in29                  0x00000007
+#define regk_iop_sw_cfg_gio_in4                   0x00000000
+#define regk_iop_sw_cfg_gio_in5                   0x00000001
+#define regk_iop_sw_cfg_last_timer_grp0_tmr2      0x00000001
+#define regk_iop_sw_cfg_last_timer_grp1_tmr2      0x00000001
+#define regk_iop_sw_cfg_last_timer_grp2_tmr2      0x00000002
+#define regk_iop_sw_cfg_last_timer_grp2_tmr3      0x00000003
+#define regk_iop_sw_cfg_last_timer_grp3_tmr2      0x00000002
+#define regk_iop_sw_cfg_last_timer_grp3_tmr3      0x00000003
+#define regk_iop_sw_cfg_mpu                       0x00000001
+#define regk_iop_sw_cfg_none                      0x00000000
+#define regk_iop_sw_cfg_par0                      0x00000000
+#define regk_iop_sw_cfg_par1                      0x00000001
+#define regk_iop_sw_cfg_pdp_out0                  0x00000002
+#define regk_iop_sw_cfg_pdp_out0_hi               0x00000001
+#define regk_iop_sw_cfg_pdp_out0_hi_rot8          0x00000005
+#define regk_iop_sw_cfg_pdp_out0_lo               0x00000000
+#define regk_iop_sw_cfg_pdp_out0_lo_rot8          0x00000004
+#define regk_iop_sw_cfg_pdp_out1                  0x00000003
+#define regk_iop_sw_cfg_pdp_out1_hi               0x00000003
+#define regk_iop_sw_cfg_pdp_out1_hi_rot8          0x00000005
+#define regk_iop_sw_cfg_pdp_out1_lo               0x00000002
+#define regk_iop_sw_cfg_pdp_out1_lo_rot8          0x00000004
+#define regk_iop_sw_cfg_rw_bus0_mask_default      0x00000000
+#define regk_iop_sw_cfg_rw_bus0_oe_mask_default   0x00000000
+#define regk_iop_sw_cfg_rw_bus1_mask_default      0x00000000
+#define regk_iop_sw_cfg_rw_bus1_oe_mask_default   0x00000000
+#define regk_iop_sw_cfg_rw_bus_out_cfg_default    0x00000000
+#define regk_iop_sw_cfg_rw_crc_par0_owner_default  0x00000000
+#define regk_iop_sw_cfg_rw_crc_par1_owner_default  0x00000000
+#define regk_iop_sw_cfg_rw_dmc_in0_owner_default  0x00000000
+#define regk_iop_sw_cfg_rw_dmc_in1_owner_default  0x00000000
+#define regk_iop_sw_cfg_rw_dmc_out0_owner_default  0x00000000
+#define regk_iop_sw_cfg_rw_dmc_out1_owner_default  0x00000000
+#define regk_iop_sw_cfg_rw_fifo_in0_extra_owner_default  0x00000000
+#define regk_iop_sw_cfg_rw_fifo_in0_owner_default  0x00000000
+#define regk_iop_sw_cfg_rw_fifo_in1_extra_owner_default  0x00000000
+#define regk_iop_sw_cfg_rw_fifo_in1_owner_default  0x00000000
+#define regk_iop_sw_cfg_rw_fifo_out0_extra_owner_default  0x00000000
+#define regk_iop_sw_cfg_rw_fifo_out0_owner_default  0x00000000
+#define regk_iop_sw_cfg_rw_fifo_out1_extra_owner_default  0x00000000
+#define regk_iop_sw_cfg_rw_fifo_out1_owner_default  0x00000000
+#define regk_iop_sw_cfg_rw_gio_mask_default       0x00000000
+#define regk_iop_sw_cfg_rw_gio_oe_mask_default    0x00000000
+#define regk_iop_sw_cfg_rw_gio_out_grp0_cfg_default  0x00000000
+#define regk_iop_sw_cfg_rw_gio_out_grp1_cfg_default  0x00000000
+#define regk_iop_sw_cfg_rw_gio_out_grp2_cfg_default  0x00000000
+#define regk_iop_sw_cfg_rw_gio_out_grp3_cfg_default  0x00000000
+#define regk_iop_sw_cfg_rw_gio_out_grp4_cfg_default  0x00000000
+#define regk_iop_sw_cfg_rw_gio_out_grp5_cfg_default  0x00000000
+#define regk_iop_sw_cfg_rw_gio_out_grp6_cfg_default  0x00000000
+#define regk_iop_sw_cfg_rw_gio_out_grp7_cfg_default  0x00000000
+#define regk_iop_sw_cfg_rw_pdp0_cfg_default       0x00000000
+#define regk_iop_sw_cfg_rw_pdp1_cfg_default       0x00000000
+#define regk_iop_sw_cfg_rw_pinmapping_default     0x55555555
+#define regk_iop_sw_cfg_rw_sap_in_owner_default   0x00000000
+#define regk_iop_sw_cfg_rw_sap_out_owner_default  0x00000000
+#define regk_iop_sw_cfg_rw_scrc_in0_owner_default  0x00000000
+#define regk_iop_sw_cfg_rw_scrc_in1_owner_default  0x00000000
+#define regk_iop_sw_cfg_rw_scrc_out0_owner_default  0x00000000
+#define regk_iop_sw_cfg_rw_scrc_out1_owner_default  0x00000000
+#define regk_iop_sw_cfg_rw_sdp_cfg_default        0x00000000
+#define regk_iop_sw_cfg_rw_spu0_cfg_default       0x00000000
+#define regk_iop_sw_cfg_rw_spu0_owner_default     0x00000000
+#define regk_iop_sw_cfg_rw_spu1_cfg_default       0x00000000
+#define regk_iop_sw_cfg_rw_spu1_owner_default     0x00000000
+#define regk_iop_sw_cfg_rw_timer_grp0_cfg_default  0x00000000
+#define regk_iop_sw_cfg_rw_timer_grp0_owner_default  0x00000000
+#define regk_iop_sw_cfg_rw_timer_grp1_cfg_default  0x00000000
+#define regk_iop_sw_cfg_rw_timer_grp1_owner_default  0x00000000
+#define regk_iop_sw_cfg_rw_timer_grp2_cfg_default  0x00000000
+#define regk_iop_sw_cfg_rw_timer_grp2_owner_default  0x00000000
+#define regk_iop_sw_cfg_rw_timer_grp3_cfg_default  0x00000000
+#define regk_iop_sw_cfg_rw_timer_grp3_owner_default  0x00000000
+#define regk_iop_sw_cfg_rw_trigger_grp0_owner_default  0x00000000
+#define regk_iop_sw_cfg_rw_trigger_grp1_owner_default  0x00000000
+#define regk_iop_sw_cfg_rw_trigger_grp2_owner_default  0x00000000
+#define regk_iop_sw_cfg_rw_trigger_grp3_owner_default  0x00000000
+#define regk_iop_sw_cfg_rw_trigger_grp4_owner_default  0x00000000
+#define regk_iop_sw_cfg_rw_trigger_grp5_owner_default  0x00000000
+#define regk_iop_sw_cfg_rw_trigger_grp6_owner_default  0x00000000
+#define regk_iop_sw_cfg_rw_trigger_grp7_owner_default  0x00000000
+#define regk_iop_sw_cfg_rw_trigger_grps_cfg_default  0x00000000
+#define regk_iop_sw_cfg_sdp_out0                  0x00000008
+#define regk_iop_sw_cfg_sdp_out1                  0x00000009
+#define regk_iop_sw_cfg_size16                    0x00000002
+#define regk_iop_sw_cfg_size24                    0x00000003
+#define regk_iop_sw_cfg_size32                    0x00000004
+#define regk_iop_sw_cfg_size8                     0x00000001
+#define regk_iop_sw_cfg_spu0                      0x00000002
+#define regk_iop_sw_cfg_spu0_bus_out0_hi          0x00000006
+#define regk_iop_sw_cfg_spu0_bus_out0_lo          0x00000006
+#define regk_iop_sw_cfg_spu0_bus_out1_hi          0x00000007
+#define regk_iop_sw_cfg_spu0_bus_out1_lo          0x00000007
+#define regk_iop_sw_cfg_spu0_g0                   0x0000000e
+#define regk_iop_sw_cfg_spu0_g1                   0x0000000e
+#define regk_iop_sw_cfg_spu0_g2                   0x0000000e
+#define regk_iop_sw_cfg_spu0_g3                   0x0000000e
+#define regk_iop_sw_cfg_spu0_g4                   0x0000000e
+#define regk_iop_sw_cfg_spu0_g5                   0x0000000e
+#define regk_iop_sw_cfg_spu0_g6                   0x0000000e
+#define regk_iop_sw_cfg_spu0_g7                   0x0000000e
+#define regk_iop_sw_cfg_spu0_gio0                 0x00000000
+#define regk_iop_sw_cfg_spu0_gio1                 0x00000001
+#define regk_iop_sw_cfg_spu0_gio2                 0x00000000
+#define regk_iop_sw_cfg_spu0_gio5                 0x00000005
+#define regk_iop_sw_cfg_spu0_gio6                 0x00000006
+#define regk_iop_sw_cfg_spu0_gio7                 0x00000007
+#define regk_iop_sw_cfg_spu0_gio_out0             0x00000008
+#define regk_iop_sw_cfg_spu0_gio_out1             0x00000009
+#define regk_iop_sw_cfg_spu0_gio_out2             0x0000000a
+#define regk_iop_sw_cfg_spu0_gio_out3             0x0000000b
+#define regk_iop_sw_cfg_spu0_gio_out4             0x0000000c
+#define regk_iop_sw_cfg_spu0_gio_out5             0x0000000d
+#define regk_iop_sw_cfg_spu0_gio_out6             0x0000000e
+#define regk_iop_sw_cfg_spu0_gio_out7             0x0000000f
+#define regk_iop_sw_cfg_spu0_gioout0              0x00000000
+#define regk_iop_sw_cfg_spu0_gioout1              0x00000000
+#define regk_iop_sw_cfg_spu0_gioout10             0x0000000e
+#define regk_iop_sw_cfg_spu0_gioout11             0x0000000e
+#define regk_iop_sw_cfg_spu0_gioout12             0x0000000e
+#define regk_iop_sw_cfg_spu0_gioout13             0x0000000e
+#define regk_iop_sw_cfg_spu0_gioout14             0x0000000e
+#define regk_iop_sw_cfg_spu0_gioout15             0x0000000e
+#define regk_iop_sw_cfg_spu0_gioout16             0x0000000e
+#define regk_iop_sw_cfg_spu0_gioout17             0x0000000e
+#define regk_iop_sw_cfg_spu0_gioout18             0x0000000e
+#define regk_iop_sw_cfg_spu0_gioout19             0x0000000e
+#define regk_iop_sw_cfg_spu0_gioout2              0x00000002
+#define regk_iop_sw_cfg_spu0_gioout20             0x0000000e
+#define regk_iop_sw_cfg_spu0_gioout21             0x0000000e
+#define regk_iop_sw_cfg_spu0_gioout22             0x0000000e
+#define regk_iop_sw_cfg_spu0_gioout23             0x0000000e
+#define regk_iop_sw_cfg_spu0_gioout24             0x0000000e
+#define regk_iop_sw_cfg_spu0_gioout25             0x0000000e
+#define regk_iop_sw_cfg_spu0_gioout26             0x0000000e
+#define regk_iop_sw_cfg_spu0_gioout27             0x0000000e
+#define regk_iop_sw_cfg_spu0_gioout28             0x0000000e
+#define regk_iop_sw_cfg_spu0_gioout29             0x0000000e
+#define regk_iop_sw_cfg_spu0_gioout3              0x00000002
+#define regk_iop_sw_cfg_spu0_gioout30             0x0000000e
+#define regk_iop_sw_cfg_spu0_gioout31             0x0000000e
+#define regk_iop_sw_cfg_spu0_gioout4              0x00000004
+#define regk_iop_sw_cfg_spu0_gioout5              0x00000004
+#define regk_iop_sw_cfg_spu0_gioout6              0x00000006
+#define regk_iop_sw_cfg_spu0_gioout7              0x00000006
+#define regk_iop_sw_cfg_spu0_gioout8              0x0000000e
+#define regk_iop_sw_cfg_spu0_gioout9              0x0000000e
+#define regk_iop_sw_cfg_spu1                      0x00000003
+#define regk_iop_sw_cfg_spu1_bus_out0_hi          0x00000006
+#define regk_iop_sw_cfg_spu1_bus_out0_lo          0x00000006
+#define regk_iop_sw_cfg_spu1_bus_out1_hi          0x00000007
+#define regk_iop_sw_cfg_spu1_bus_out1_lo          0x00000007
+#define regk_iop_sw_cfg_spu1_g0                   0x0000000f
+#define regk_iop_sw_cfg_spu1_g1                   0x0000000f
+#define regk_iop_sw_cfg_spu1_g2                   0x0000000f
+#define regk_iop_sw_cfg_spu1_g3                   0x0000000f
+#define regk_iop_sw_cfg_spu1_g4                   0x0000000f
+#define regk_iop_sw_cfg_spu1_g5                   0x0000000f
+#define regk_iop_sw_cfg_spu1_g6                   0x0000000f
+#define regk_iop_sw_cfg_spu1_g7                   0x0000000f
+#define regk_iop_sw_cfg_spu1_gio0                 0x00000002
+#define regk_iop_sw_cfg_spu1_gio1                 0x00000003
+#define regk_iop_sw_cfg_spu1_gio2                 0x00000002
+#define regk_iop_sw_cfg_spu1_gio5                 0x00000005
+#define regk_iop_sw_cfg_spu1_gio6                 0x00000006
+#define regk_iop_sw_cfg_spu1_gio7                 0x00000007
+#define regk_iop_sw_cfg_spu1_gio_out0             0x00000008
+#define regk_iop_sw_cfg_spu1_gio_out1             0x00000009
+#define regk_iop_sw_cfg_spu1_gio_out2             0x0000000a
+#define regk_iop_sw_cfg_spu1_gio_out3             0x0000000b
+#define regk_iop_sw_cfg_spu1_gio_out4             0x0000000c
+#define regk_iop_sw_cfg_spu1_gio_out5             0x0000000d
+#define regk_iop_sw_cfg_spu1_gio_out6             0x0000000e
+#define regk_iop_sw_cfg_spu1_gio_out7             0x0000000f
+#define regk_iop_sw_cfg_spu1_gioout0              0x00000001
+#define regk_iop_sw_cfg_spu1_gioout1              0x00000001
+#define regk_iop_sw_cfg_spu1_gioout10             0x0000000f
+#define regk_iop_sw_cfg_spu1_gioout11             0x0000000f
+#define regk_iop_sw_cfg_spu1_gioout12             0x0000000f
+#define regk_iop_sw_cfg_spu1_gioout13             0x0000000f
+#define regk_iop_sw_cfg_spu1_gioout14             0x0000000f
+#define regk_iop_sw_cfg_spu1_gioout15             0x0000000f
+#define regk_iop_sw_cfg_spu1_gioout16             0x0000000f
+#define regk_iop_sw_cfg_spu1_gioout17             0x0000000f
+#define regk_iop_sw_cfg_spu1_gioout18             0x0000000f
+#define regk_iop_sw_cfg_spu1_gioout19             0x0000000f
+#define regk_iop_sw_cfg_spu1_gioout2              0x00000003
+#define regk_iop_sw_cfg_spu1_gioout20             0x0000000f
+#define regk_iop_sw_cfg_spu1_gioout21             0x0000000f
+#define regk_iop_sw_cfg_spu1_gioout22             0x0000000f
+#define regk_iop_sw_cfg_spu1_gioout23             0x0000000f
+#define regk_iop_sw_cfg_spu1_gioout24             0x0000000f
+#define regk_iop_sw_cfg_spu1_gioout25             0x0000000f
+#define regk_iop_sw_cfg_spu1_gioout26             0x0000000f
+#define regk_iop_sw_cfg_spu1_gioout27             0x0000000f
+#define regk_iop_sw_cfg_spu1_gioout28             0x0000000f
+#define regk_iop_sw_cfg_spu1_gioout29             0x0000000f
+#define regk_iop_sw_cfg_spu1_gioout3              0x00000003
+#define regk_iop_sw_cfg_spu1_gioout30             0x0000000f
+#define regk_iop_sw_cfg_spu1_gioout31             0x0000000f
+#define regk_iop_sw_cfg_spu1_gioout4              0x00000005
+#define regk_iop_sw_cfg_spu1_gioout5              0x00000005
+#define regk_iop_sw_cfg_spu1_gioout6              0x00000007
+#define regk_iop_sw_cfg_spu1_gioout7              0x00000007
+#define regk_iop_sw_cfg_spu1_gioout8              0x0000000f
+#define regk_iop_sw_cfg_spu1_gioout9              0x0000000f
+#define regk_iop_sw_cfg_strb_timer_grp0_tmr0      0x00000001
+#define regk_iop_sw_cfg_strb_timer_grp0_tmr1      0x00000002
+#define regk_iop_sw_cfg_strb_timer_grp1_tmr0      0x00000001
+#define regk_iop_sw_cfg_strb_timer_grp1_tmr1      0x00000002
+#define regk_iop_sw_cfg_strb_timer_grp2_tmr0      0x00000003
+#define regk_iop_sw_cfg_strb_timer_grp2_tmr1      0x00000002
+#define regk_iop_sw_cfg_strb_timer_grp3_tmr0      0x00000003
+#define regk_iop_sw_cfg_strb_timer_grp3_tmr1      0x00000002
+#define regk_iop_sw_cfg_timer_grp0                0x00000000
+#define regk_iop_sw_cfg_timer_grp0_rot            0x00000001
+#define regk_iop_sw_cfg_timer_grp0_strb0          0x0000000a
+#define regk_iop_sw_cfg_timer_grp0_strb1          0x0000000a
+#define regk_iop_sw_cfg_timer_grp0_strb2          0x0000000a
+#define regk_iop_sw_cfg_timer_grp0_strb3          0x0000000a
+#define regk_iop_sw_cfg_timer_grp0_tmr0           0x00000004
+#define regk_iop_sw_cfg_timer_grp0_tmr1           0x00000004
+#define regk_iop_sw_cfg_timer_grp1                0x00000000
+#define regk_iop_sw_cfg_timer_grp1_rot            0x00000001
+#define regk_iop_sw_cfg_timer_grp1_strb0          0x0000000b
+#define regk_iop_sw_cfg_timer_grp1_strb1          0x0000000b
+#define regk_iop_sw_cfg_timer_grp1_strb2          0x0000000b
+#define regk_iop_sw_cfg_timer_grp1_strb3          0x0000000b
+#define regk_iop_sw_cfg_timer_grp1_tmr0           0x00000005
+#define regk_iop_sw_cfg_timer_grp1_tmr1           0x00000005
+#define regk_iop_sw_cfg_timer_grp2                0x00000000
+#define regk_iop_sw_cfg_timer_grp2_rot            0x00000001
+#define regk_iop_sw_cfg_timer_grp2_strb0          0x0000000c
+#define regk_iop_sw_cfg_timer_grp2_strb1          0x0000000c
+#define regk_iop_sw_cfg_timer_grp2_strb2          0x0000000c
+#define regk_iop_sw_cfg_timer_grp2_strb3          0x0000000c
+#define regk_iop_sw_cfg_timer_grp2_tmr0           0x00000006
+#define regk_iop_sw_cfg_timer_grp2_tmr1           0x00000006
+#define regk_iop_sw_cfg_timer_grp3                0x00000000
+#define regk_iop_sw_cfg_timer_grp3_rot            0x00000001
+#define regk_iop_sw_cfg_timer_grp3_strb0          0x0000000d
+#define regk_iop_sw_cfg_timer_grp3_strb1          0x0000000d
+#define regk_iop_sw_cfg_timer_grp3_strb2          0x0000000d
+#define regk_iop_sw_cfg_timer_grp3_strb3          0x0000000d
+#define regk_iop_sw_cfg_timer_grp3_tmr0           0x00000007
+#define regk_iop_sw_cfg_timer_grp3_tmr1           0x00000007
+#define regk_iop_sw_cfg_trig0_0                   0x00000000
+#define regk_iop_sw_cfg_trig0_1                   0x00000000
+#define regk_iop_sw_cfg_trig0_2                   0x00000000
+#define regk_iop_sw_cfg_trig0_3                   0x00000000
+#define regk_iop_sw_cfg_trig1_0                   0x00000000
+#define regk_iop_sw_cfg_trig1_1                   0x00000000
+#define regk_iop_sw_cfg_trig1_2                   0x00000000
+#define regk_iop_sw_cfg_trig1_3                   0x00000000
+#define regk_iop_sw_cfg_trig2_0                   0x00000000
+#define regk_iop_sw_cfg_trig2_1                   0x00000000
+#define regk_iop_sw_cfg_trig2_2                   0x00000000
+#define regk_iop_sw_cfg_trig2_3                   0x00000000
+#define regk_iop_sw_cfg_trig3_0                   0x00000000
+#define regk_iop_sw_cfg_trig3_1                   0x00000000
+#define regk_iop_sw_cfg_trig3_2                   0x00000000
+#define regk_iop_sw_cfg_trig3_3                   0x00000000
+#define regk_iop_sw_cfg_trig4_0                   0x00000001
+#define regk_iop_sw_cfg_trig4_1                   0x00000001
+#define regk_iop_sw_cfg_trig4_2                   0x00000001
+#define regk_iop_sw_cfg_trig4_3                   0x00000001
+#define regk_iop_sw_cfg_trig5_0                   0x00000001
+#define regk_iop_sw_cfg_trig5_1                   0x00000001
+#define regk_iop_sw_cfg_trig5_2                   0x00000001
+#define regk_iop_sw_cfg_trig5_3                   0x00000001
+#define regk_iop_sw_cfg_trig6_0                   0x00000001
+#define regk_iop_sw_cfg_trig6_1                   0x00000001
+#define regk_iop_sw_cfg_trig6_2                   0x00000001
+#define regk_iop_sw_cfg_trig6_3                   0x00000001
+#define regk_iop_sw_cfg_trig7_0                   0x00000001
+#define regk_iop_sw_cfg_trig7_1                   0x00000001
+#define regk_iop_sw_cfg_trig7_2                   0x00000001
+#define regk_iop_sw_cfg_trig7_3                   0x00000001
+#endif /* __iop_sw_cfg_defs_asm_h */
diff --git a/include/asm-cris/arch-v32/hwregs/iop/asm/iop_sw_cpu_defs_asm.h b/include/asm-cris/arch-v32/hwregs/iop/asm/iop_sw_cpu_defs_asm.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/iop/asm/iop_sw_cpu_defs_asm.h
@@ -0,0 +1,1758 @@
+#ifndef __iop_sw_cpu_defs_asm_h
+#define __iop_sw_cpu_defs_asm_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/io_proc/rtl/guinness/iop_sw_cpu.r
+ *     id:           <not found>
+ *     last modfied: Mon Apr 11 16:10:19 2005
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c -asm --outfile asm/iop_sw_cpu_defs_asm.h ../../inst/io_proc/rtl/guinness/iop_sw_cpu.r
+ *      id: $Id: iop_sw_cpu_defs_asm.h,v 1.5 2005/04/24 18:31:07 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+
+#ifndef REG_FIELD
+#define REG_FIELD( scope, reg, field, value ) \
+  REG_FIELD_X_( value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_FIELD_X_( value, shift ) ((value) << shift)
+#endif
+
+#ifndef REG_STATE
+#define REG_STATE( scope, reg, field, symbolic_value ) \
+  REG_STATE_X_( regk_##scope##_##symbolic_value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_STATE_X_( k, shift ) (k << shift)
+#endif
+
+#ifndef REG_MASK
+#define REG_MASK( scope, reg, field ) \
+  REG_MASK_X_( reg_##scope##_##reg##___##field##___width, reg_##scope##_##reg##___##field##___lsb )
+#define REG_MASK_X_( width, lsb ) (((1 << width)-1) << lsb)
+#endif
+
+#ifndef REG_LSB
+#define REG_LSB( scope, reg, field ) reg_##scope##_##reg##___##field##___lsb
+#endif
+
+#ifndef REG_BIT
+#define REG_BIT( scope, reg, field ) reg_##scope##_##reg##___##field##___bit
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) REG_ADDR_X_(inst, reg_##scope##_##reg##_offset)
+#define REG_ADDR_X_( inst, offs ) ((inst) + offs)
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+         REG_ADDR_VECT_X_(inst, reg_##scope##_##reg##_offset, index, \
+			 STRIDE_##scope##_##reg )
+#define REG_ADDR_VECT_X_( inst, offs, index, stride ) \
+                          ((inst) + offs + (index) * stride)
+#endif
+
+/* Register rw_mc_ctrl, scope iop_sw_cpu, type rw */
+#define reg_iop_sw_cpu_rw_mc_ctrl___keep_owner___lsb 0
+#define reg_iop_sw_cpu_rw_mc_ctrl___keep_owner___width 1
+#define reg_iop_sw_cpu_rw_mc_ctrl___keep_owner___bit 0
+#define reg_iop_sw_cpu_rw_mc_ctrl___cmd___lsb 1
+#define reg_iop_sw_cpu_rw_mc_ctrl___cmd___width 2
+#define reg_iop_sw_cpu_rw_mc_ctrl___size___lsb 3
+#define reg_iop_sw_cpu_rw_mc_ctrl___size___width 3
+#define reg_iop_sw_cpu_rw_mc_ctrl___wr_spu0_mem___lsb 6
+#define reg_iop_sw_cpu_rw_mc_ctrl___wr_spu0_mem___width 1
+#define reg_iop_sw_cpu_rw_mc_ctrl___wr_spu0_mem___bit 6
+#define reg_iop_sw_cpu_rw_mc_ctrl___wr_spu1_mem___lsb 7
+#define reg_iop_sw_cpu_rw_mc_ctrl___wr_spu1_mem___width 1
+#define reg_iop_sw_cpu_rw_mc_ctrl___wr_spu1_mem___bit 7
+#define reg_iop_sw_cpu_rw_mc_ctrl_offset 0
+
+/* Register rw_mc_data, scope iop_sw_cpu, type rw */
+#define reg_iop_sw_cpu_rw_mc_data___val___lsb 0
+#define reg_iop_sw_cpu_rw_mc_data___val___width 32
+#define reg_iop_sw_cpu_rw_mc_data_offset 4
+
+/* Register rw_mc_addr, scope iop_sw_cpu, type rw */
+#define reg_iop_sw_cpu_rw_mc_addr_offset 8
+
+/* Register rs_mc_data, scope iop_sw_cpu, type rs */
+#define reg_iop_sw_cpu_rs_mc_data_offset 12
+
+/* Register r_mc_data, scope iop_sw_cpu, type r */
+#define reg_iop_sw_cpu_r_mc_data_offset 16
+
+/* Register r_mc_stat, scope iop_sw_cpu, type r */
+#define reg_iop_sw_cpu_r_mc_stat___busy_cpu___lsb 0
+#define reg_iop_sw_cpu_r_mc_stat___busy_cpu___width 1
+#define reg_iop_sw_cpu_r_mc_stat___busy_cpu___bit 0
+#define reg_iop_sw_cpu_r_mc_stat___busy_mpu___lsb 1
+#define reg_iop_sw_cpu_r_mc_stat___busy_mpu___width 1
+#define reg_iop_sw_cpu_r_mc_stat___busy_mpu___bit 1
+#define reg_iop_sw_cpu_r_mc_stat___busy_spu0___lsb 2
+#define reg_iop_sw_cpu_r_mc_stat___busy_spu0___width 1
+#define reg_iop_sw_cpu_r_mc_stat___busy_spu0___bit 2
+#define reg_iop_sw_cpu_r_mc_stat___busy_spu1___lsb 3
+#define reg_iop_sw_cpu_r_mc_stat___busy_spu1___width 1
+#define reg_iop_sw_cpu_r_mc_stat___busy_spu1___bit 3
+#define reg_iop_sw_cpu_r_mc_stat___owned_by_cpu___lsb 4
+#define reg_iop_sw_cpu_r_mc_stat___owned_by_cpu___width 1
+#define reg_iop_sw_cpu_r_mc_stat___owned_by_cpu___bit 4
+#define reg_iop_sw_cpu_r_mc_stat___owned_by_mpu___lsb 5
+#define reg_iop_sw_cpu_r_mc_stat___owned_by_mpu___width 1
+#define reg_iop_sw_cpu_r_mc_stat___owned_by_mpu___bit 5
+#define reg_iop_sw_cpu_r_mc_stat___owned_by_spu0___lsb 6
+#define reg_iop_sw_cpu_r_mc_stat___owned_by_spu0___width 1
+#define reg_iop_sw_cpu_r_mc_stat___owned_by_spu0___bit 6
+#define reg_iop_sw_cpu_r_mc_stat___owned_by_spu1___lsb 7
+#define reg_iop_sw_cpu_r_mc_stat___owned_by_spu1___width 1
+#define reg_iop_sw_cpu_r_mc_stat___owned_by_spu1___bit 7
+#define reg_iop_sw_cpu_r_mc_stat_offset 20
+
+/* Register rw_bus0_clr_mask, scope iop_sw_cpu, type rw */
+#define reg_iop_sw_cpu_rw_bus0_clr_mask___byte0___lsb 0
+#define reg_iop_sw_cpu_rw_bus0_clr_mask___byte0___width 8
+#define reg_iop_sw_cpu_rw_bus0_clr_mask___byte1___lsb 8
+#define reg_iop_sw_cpu_rw_bus0_clr_mask___byte1___width 8
+#define reg_iop_sw_cpu_rw_bus0_clr_mask___byte2___lsb 16
+#define reg_iop_sw_cpu_rw_bus0_clr_mask___byte2___width 8
+#define reg_iop_sw_cpu_rw_bus0_clr_mask___byte3___lsb 24
+#define reg_iop_sw_cpu_rw_bus0_clr_mask___byte3___width 8
+#define reg_iop_sw_cpu_rw_bus0_clr_mask_offset 24
+
+/* Register rw_bus0_set_mask, scope iop_sw_cpu, type rw */
+#define reg_iop_sw_cpu_rw_bus0_set_mask___byte0___lsb 0
+#define reg_iop_sw_cpu_rw_bus0_set_mask___byte0___width 8
+#define reg_iop_sw_cpu_rw_bus0_set_mask___byte1___lsb 8
+#define reg_iop_sw_cpu_rw_bus0_set_mask___byte1___width 8
+#define reg_iop_sw_cpu_rw_bus0_set_mask___byte2___lsb 16
+#define reg_iop_sw_cpu_rw_bus0_set_mask___byte2___width 8
+#define reg_iop_sw_cpu_rw_bus0_set_mask___byte3___lsb 24
+#define reg_iop_sw_cpu_rw_bus0_set_mask___byte3___width 8
+#define reg_iop_sw_cpu_rw_bus0_set_mask_offset 28
+
+/* Register rw_bus0_oe_clr_mask, scope iop_sw_cpu, type rw */
+#define reg_iop_sw_cpu_rw_bus0_oe_clr_mask___byte0___lsb 0
+#define reg_iop_sw_cpu_rw_bus0_oe_clr_mask___byte0___width 1
+#define reg_iop_sw_cpu_rw_bus0_oe_clr_mask___byte0___bit 0
+#define reg_iop_sw_cpu_rw_bus0_oe_clr_mask___byte1___lsb 1
+#define reg_iop_sw_cpu_rw_bus0_oe_clr_mask___byte1___width 1
+#define reg_iop_sw_cpu_rw_bus0_oe_clr_mask___byte1___bit 1
+#define reg_iop_sw_cpu_rw_bus0_oe_clr_mask___byte2___lsb 2
+#define reg_iop_sw_cpu_rw_bus0_oe_clr_mask___byte2___width 1
+#define reg_iop_sw_cpu_rw_bus0_oe_clr_mask___byte2___bit 2
+#define reg_iop_sw_cpu_rw_bus0_oe_clr_mask___byte3___lsb 3
+#define reg_iop_sw_cpu_rw_bus0_oe_clr_mask___byte3___width 1
+#define reg_iop_sw_cpu_rw_bus0_oe_clr_mask___byte3___bit 3
+#define reg_iop_sw_cpu_rw_bus0_oe_clr_mask_offset 32
+
+/* Register rw_bus0_oe_set_mask, scope iop_sw_cpu, type rw */
+#define reg_iop_sw_cpu_rw_bus0_oe_set_mask___byte0___lsb 0
+#define reg_iop_sw_cpu_rw_bus0_oe_set_mask___byte0___width 1
+#define reg_iop_sw_cpu_rw_bus0_oe_set_mask___byte0___bit 0
+#define reg_iop_sw_cpu_rw_bus0_oe_set_mask___byte1___lsb 1
+#define reg_iop_sw_cpu_rw_bus0_oe_set_mask___byte1___width 1
+#define reg_iop_sw_cpu_rw_bus0_oe_set_mask___byte1___bit 1
+#define reg_iop_sw_cpu_rw_bus0_oe_set_mask___byte2___lsb 2
+#define reg_iop_sw_cpu_rw_bus0_oe_set_mask___byte2___width 1
+#define reg_iop_sw_cpu_rw_bus0_oe_set_mask___byte2___bit 2
+#define reg_iop_sw_cpu_rw_bus0_oe_set_mask___byte3___lsb 3
+#define reg_iop_sw_cpu_rw_bus0_oe_set_mask___byte3___width 1
+#define reg_iop_sw_cpu_rw_bus0_oe_set_mask___byte3___bit 3
+#define reg_iop_sw_cpu_rw_bus0_oe_set_mask_offset 36
+
+/* Register r_bus0_in, scope iop_sw_cpu, type r */
+#define reg_iop_sw_cpu_r_bus0_in_offset 40
+
+/* Register rw_bus1_clr_mask, scope iop_sw_cpu, type rw */
+#define reg_iop_sw_cpu_rw_bus1_clr_mask___byte0___lsb 0
+#define reg_iop_sw_cpu_rw_bus1_clr_mask___byte0___width 8
+#define reg_iop_sw_cpu_rw_bus1_clr_mask___byte1___lsb 8
+#define reg_iop_sw_cpu_rw_bus1_clr_mask___byte1___width 8
+#define reg_iop_sw_cpu_rw_bus1_clr_mask___byte2___lsb 16
+#define reg_iop_sw_cpu_rw_bus1_clr_mask___byte2___width 8
+#define reg_iop_sw_cpu_rw_bus1_clr_mask___byte3___lsb 24
+#define reg_iop_sw_cpu_rw_bus1_clr_mask___byte3___width 8
+#define reg_iop_sw_cpu_rw_bus1_clr_mask_offset 44
+
+/* Register rw_bus1_set_mask, scope iop_sw_cpu, type rw */
+#define reg_iop_sw_cpu_rw_bus1_set_mask___byte0___lsb 0
+#define reg_iop_sw_cpu_rw_bus1_set_mask___byte0___width 8
+#define reg_iop_sw_cpu_rw_bus1_set_mask___byte1___lsb 8
+#define reg_iop_sw_cpu_rw_bus1_set_mask___byte1___width 8
+#define reg_iop_sw_cpu_rw_bus1_set_mask___byte2___lsb 16
+#define reg_iop_sw_cpu_rw_bus1_set_mask___byte2___width 8
+#define reg_iop_sw_cpu_rw_bus1_set_mask___byte3___lsb 24
+#define reg_iop_sw_cpu_rw_bus1_set_mask___byte3___width 8
+#define reg_iop_sw_cpu_rw_bus1_set_mask_offset 48
+
+/* Register rw_bus1_oe_clr_mask, scope iop_sw_cpu, type rw */
+#define reg_iop_sw_cpu_rw_bus1_oe_clr_mask___byte0___lsb 0
+#define reg_iop_sw_cpu_rw_bus1_oe_clr_mask___byte0___width 1
+#define reg_iop_sw_cpu_rw_bus1_oe_clr_mask___byte0___bit 0
+#define reg_iop_sw_cpu_rw_bus1_oe_clr_mask___byte1___lsb 1
+#define reg_iop_sw_cpu_rw_bus1_oe_clr_mask___byte1___width 1
+#define reg_iop_sw_cpu_rw_bus1_oe_clr_mask___byte1___bit 1
+#define reg_iop_sw_cpu_rw_bus1_oe_clr_mask___byte2___lsb 2
+#define reg_iop_sw_cpu_rw_bus1_oe_clr_mask___byte2___width 1
+#define reg_iop_sw_cpu_rw_bus1_oe_clr_mask___byte2___bit 2
+#define reg_iop_sw_cpu_rw_bus1_oe_clr_mask___byte3___lsb 3
+#define reg_iop_sw_cpu_rw_bus1_oe_clr_mask___byte3___width 1
+#define reg_iop_sw_cpu_rw_bus1_oe_clr_mask___byte3___bit 3
+#define reg_iop_sw_cpu_rw_bus1_oe_clr_mask_offset 52
+
+/* Register rw_bus1_oe_set_mask, scope iop_sw_cpu, type rw */
+#define reg_iop_sw_cpu_rw_bus1_oe_set_mask___byte0___lsb 0
+#define reg_iop_sw_cpu_rw_bus1_oe_set_mask___byte0___width 1
+#define reg_iop_sw_cpu_rw_bus1_oe_set_mask___byte0___bit 0
+#define reg_iop_sw_cpu_rw_bus1_oe_set_mask___byte1___lsb 1
+#define reg_iop_sw_cpu_rw_bus1_oe_set_mask___byte1___width 1
+#define reg_iop_sw_cpu_rw_bus1_oe_set_mask___byte1___bit 1
+#define reg_iop_sw_cpu_rw_bus1_oe_set_mask___byte2___lsb 2
+#define reg_iop_sw_cpu_rw_bus1_oe_set_mask___byte2___width 1
+#define reg_iop_sw_cpu_rw_bus1_oe_set_mask___byte2___bit 2
+#define reg_iop_sw_cpu_rw_bus1_oe_set_mask___byte3___lsb 3
+#define reg_iop_sw_cpu_rw_bus1_oe_set_mask___byte3___width 1
+#define reg_iop_sw_cpu_rw_bus1_oe_set_mask___byte3___bit 3
+#define reg_iop_sw_cpu_rw_bus1_oe_set_mask_offset 56
+
+/* Register r_bus1_in, scope iop_sw_cpu, type r */
+#define reg_iop_sw_cpu_r_bus1_in_offset 60
+
+/* Register rw_gio_clr_mask, scope iop_sw_cpu, type rw */
+#define reg_iop_sw_cpu_rw_gio_clr_mask___val___lsb 0
+#define reg_iop_sw_cpu_rw_gio_clr_mask___val___width 32
+#define reg_iop_sw_cpu_rw_gio_clr_mask_offset 64
+
+/* Register rw_gio_set_mask, scope iop_sw_cpu, type rw */
+#define reg_iop_sw_cpu_rw_gio_set_mask___val___lsb 0
+#define reg_iop_sw_cpu_rw_gio_set_mask___val___width 32
+#define reg_iop_sw_cpu_rw_gio_set_mask_offset 68
+
+/* Register rw_gio_oe_clr_mask, scope iop_sw_cpu, type rw */
+#define reg_iop_sw_cpu_rw_gio_oe_clr_mask___val___lsb 0
+#define reg_iop_sw_cpu_rw_gio_oe_clr_mask___val___width 32
+#define reg_iop_sw_cpu_rw_gio_oe_clr_mask_offset 72
+
+/* Register rw_gio_oe_set_mask, scope iop_sw_cpu, type rw */
+#define reg_iop_sw_cpu_rw_gio_oe_set_mask___val___lsb 0
+#define reg_iop_sw_cpu_rw_gio_oe_set_mask___val___width 32
+#define reg_iop_sw_cpu_rw_gio_oe_set_mask_offset 76
+
+/* Register r_gio_in, scope iop_sw_cpu, type r */
+#define reg_iop_sw_cpu_r_gio_in_offset 80
+
+/* Register rw_intr0_mask, scope iop_sw_cpu, type rw */
+#define reg_iop_sw_cpu_rw_intr0_mask___mpu_0___lsb 0
+#define reg_iop_sw_cpu_rw_intr0_mask___mpu_0___width 1
+#define reg_iop_sw_cpu_rw_intr0_mask___mpu_0___bit 0
+#define reg_iop_sw_cpu_rw_intr0_mask___mpu_1___lsb 1
+#define reg_iop_sw_cpu_rw_intr0_mask___mpu_1___width 1
+#define reg_iop_sw_cpu_rw_intr0_mask___mpu_1___bit 1
+#define reg_iop_sw_cpu_rw_intr0_mask___mpu_2___lsb 2
+#define reg_iop_sw_cpu_rw_intr0_mask___mpu_2___width 1
+#define reg_iop_sw_cpu_rw_intr0_mask___mpu_2___bit 2
+#define reg_iop_sw_cpu_rw_intr0_mask___mpu_3___lsb 3
+#define reg_iop_sw_cpu_rw_intr0_mask___mpu_3___width 1
+#define reg_iop_sw_cpu_rw_intr0_mask___mpu_3___bit 3
+#define reg_iop_sw_cpu_rw_intr0_mask___mpu_4___lsb 4
+#define reg_iop_sw_cpu_rw_intr0_mask___mpu_4___width 1
+#define reg_iop_sw_cpu_rw_intr0_mask___mpu_4___bit 4
+#define reg_iop_sw_cpu_rw_intr0_mask___mpu_5___lsb 5
+#define reg_iop_sw_cpu_rw_intr0_mask___mpu_5___width 1
+#define reg_iop_sw_cpu_rw_intr0_mask___mpu_5___bit 5
+#define reg_iop_sw_cpu_rw_intr0_mask___mpu_6___lsb 6
+#define reg_iop_sw_cpu_rw_intr0_mask___mpu_6___width 1
+#define reg_iop_sw_cpu_rw_intr0_mask___mpu_6___bit 6
+#define reg_iop_sw_cpu_rw_intr0_mask___mpu_7___lsb 7
+#define reg_iop_sw_cpu_rw_intr0_mask___mpu_7___width 1
+#define reg_iop_sw_cpu_rw_intr0_mask___mpu_7___bit 7
+#define reg_iop_sw_cpu_rw_intr0_mask___mpu_8___lsb 8
+#define reg_iop_sw_cpu_rw_intr0_mask___mpu_8___width 1
+#define reg_iop_sw_cpu_rw_intr0_mask___mpu_8___bit 8
+#define reg_iop_sw_cpu_rw_intr0_mask___mpu_9___lsb 9
+#define reg_iop_sw_cpu_rw_intr0_mask___mpu_9___width 1
+#define reg_iop_sw_cpu_rw_intr0_mask___mpu_9___bit 9
+#define reg_iop_sw_cpu_rw_intr0_mask___mpu_10___lsb 10
+#define reg_iop_sw_cpu_rw_intr0_mask___mpu_10___width 1
+#define reg_iop_sw_cpu_rw_intr0_mask___mpu_10___bit 10
+#define reg_iop_sw_cpu_rw_intr0_mask___mpu_11___lsb 11
+#define reg_iop_sw_cpu_rw_intr0_mask___mpu_11___width 1
+#define reg_iop_sw_cpu_rw_intr0_mask___mpu_11___bit 11
+#define reg_iop_sw_cpu_rw_intr0_mask___mpu_12___lsb 12
+#define reg_iop_sw_cpu_rw_intr0_mask___mpu_12___width 1
+#define reg_iop_sw_cpu_rw_intr0_mask___mpu_12___bit 12
+#define reg_iop_sw_cpu_rw_intr0_mask___mpu_13___lsb 13
+#define reg_iop_sw_cpu_rw_intr0_mask___mpu_13___width 1
+#define reg_iop_sw_cpu_rw_intr0_mask___mpu_13___bit 13
+#define reg_iop_sw_cpu_rw_intr0_mask___mpu_14___lsb 14
+#define reg_iop_sw_cpu_rw_intr0_mask___mpu_14___width 1
+#define reg_iop_sw_cpu_rw_intr0_mask___mpu_14___bit 14
+#define reg_iop_sw_cpu_rw_intr0_mask___mpu_15___lsb 15
+#define reg_iop_sw_cpu_rw_intr0_mask___mpu_15___width 1
+#define reg_iop_sw_cpu_rw_intr0_mask___mpu_15___bit 15
+#define reg_iop_sw_cpu_rw_intr0_mask___spu0_0___lsb 16
+#define reg_iop_sw_cpu_rw_intr0_mask___spu0_0___width 1
+#define reg_iop_sw_cpu_rw_intr0_mask___spu0_0___bit 16
+#define reg_iop_sw_cpu_rw_intr0_mask___spu0_1___lsb 17
+#define reg_iop_sw_cpu_rw_intr0_mask___spu0_1___width 1
+#define reg_iop_sw_cpu_rw_intr0_mask___spu0_1___bit 17
+#define reg_iop_sw_cpu_rw_intr0_mask___spu0_2___lsb 18
+#define reg_iop_sw_cpu_rw_intr0_mask___spu0_2___width 1
+#define reg_iop_sw_cpu_rw_intr0_mask___spu0_2___bit 18
+#define reg_iop_sw_cpu_rw_intr0_mask___spu0_3___lsb 19
+#define reg_iop_sw_cpu_rw_intr0_mask___spu0_3___width 1
+#define reg_iop_sw_cpu_rw_intr0_mask___spu0_3___bit 19
+#define reg_iop_sw_cpu_rw_intr0_mask___spu0_4___lsb 20
+#define reg_iop_sw_cpu_rw_intr0_mask___spu0_4___width 1
+#define reg_iop_sw_cpu_rw_intr0_mask___spu0_4___bit 20
+#define reg_iop_sw_cpu_rw_intr0_mask___spu0_5___lsb 21
+#define reg_iop_sw_cpu_rw_intr0_mask___spu0_5___width 1
+#define reg_iop_sw_cpu_rw_intr0_mask___spu0_5___bit 21
+#define reg_iop_sw_cpu_rw_intr0_mask___spu0_6___lsb 22
+#define reg_iop_sw_cpu_rw_intr0_mask___spu0_6___width 1
+#define reg_iop_sw_cpu_rw_intr0_mask___spu0_6___bit 22
+#define reg_iop_sw_cpu_rw_intr0_mask___spu0_7___lsb 23
+#define reg_iop_sw_cpu_rw_intr0_mask___spu0_7___width 1
+#define reg_iop_sw_cpu_rw_intr0_mask___spu0_7___bit 23
+#define reg_iop_sw_cpu_rw_intr0_mask___spu1_8___lsb 24
+#define reg_iop_sw_cpu_rw_intr0_mask___spu1_8___width 1
+#define reg_iop_sw_cpu_rw_intr0_mask___spu1_8___bit 24
+#define reg_iop_sw_cpu_rw_intr0_mask___spu1_9___lsb 25
+#define reg_iop_sw_cpu_rw_intr0_mask___spu1_9___width 1
+#define reg_iop_sw_cpu_rw_intr0_mask___spu1_9___bit 25
+#define reg_iop_sw_cpu_rw_intr0_mask___spu1_10___lsb 26
+#define reg_iop_sw_cpu_rw_intr0_mask___spu1_10___width 1
+#define reg_iop_sw_cpu_rw_intr0_mask___spu1_10___bit 26
+#define reg_iop_sw_cpu_rw_intr0_mask___spu1_11___lsb 27
+#define reg_iop_sw_cpu_rw_intr0_mask___spu1_11___width 1
+#define reg_iop_sw_cpu_rw_intr0_mask___spu1_11___bit 27
+#define reg_iop_sw_cpu_rw_intr0_mask___spu1_12___lsb 28
+#define reg_iop_sw_cpu_rw_intr0_mask___spu1_12___width 1
+#define reg_iop_sw_cpu_rw_intr0_mask___spu1_12___bit 28
+#define reg_iop_sw_cpu_rw_intr0_mask___spu1_13___lsb 29
+#define reg_iop_sw_cpu_rw_intr0_mask___spu1_13___width 1
+#define reg_iop_sw_cpu_rw_intr0_mask___spu1_13___bit 29
+#define reg_iop_sw_cpu_rw_intr0_mask___spu1_14___lsb 30
+#define reg_iop_sw_cpu_rw_intr0_mask___spu1_14___width 1
+#define reg_iop_sw_cpu_rw_intr0_mask___spu1_14___bit 30
+#define reg_iop_sw_cpu_rw_intr0_mask___spu1_15___lsb 31
+#define reg_iop_sw_cpu_rw_intr0_mask___spu1_15___width 1
+#define reg_iop_sw_cpu_rw_intr0_mask___spu1_15___bit 31
+#define reg_iop_sw_cpu_rw_intr0_mask_offset 84
+
+/* Register rw_ack_intr0, scope iop_sw_cpu, type rw */
+#define reg_iop_sw_cpu_rw_ack_intr0___mpu_0___lsb 0
+#define reg_iop_sw_cpu_rw_ack_intr0___mpu_0___width 1
+#define reg_iop_sw_cpu_rw_ack_intr0___mpu_0___bit 0
+#define reg_iop_sw_cpu_rw_ack_intr0___mpu_1___lsb 1
+#define reg_iop_sw_cpu_rw_ack_intr0___mpu_1___width 1
+#define reg_iop_sw_cpu_rw_ack_intr0___mpu_1___bit 1
+#define reg_iop_sw_cpu_rw_ack_intr0___mpu_2___lsb 2
+#define reg_iop_sw_cpu_rw_ack_intr0___mpu_2___width 1
+#define reg_iop_sw_cpu_rw_ack_intr0___mpu_2___bit 2
+#define reg_iop_sw_cpu_rw_ack_intr0___mpu_3___lsb 3
+#define reg_iop_sw_cpu_rw_ack_intr0___mpu_3___width 1
+#define reg_iop_sw_cpu_rw_ack_intr0___mpu_3___bit 3
+#define reg_iop_sw_cpu_rw_ack_intr0___mpu_4___lsb 4
+#define reg_iop_sw_cpu_rw_ack_intr0___mpu_4___width 1
+#define reg_iop_sw_cpu_rw_ack_intr0___mpu_4___bit 4
+#define reg_iop_sw_cpu_rw_ack_intr0___mpu_5___lsb 5
+#define reg_iop_sw_cpu_rw_ack_intr0___mpu_5___width 1
+#define reg_iop_sw_cpu_rw_ack_intr0___mpu_5___bit 5
+#define reg_iop_sw_cpu_rw_ack_intr0___mpu_6___lsb 6
+#define reg_iop_sw_cpu_rw_ack_intr0___mpu_6___width 1
+#define reg_iop_sw_cpu_rw_ack_intr0___mpu_6___bit 6
+#define reg_iop_sw_cpu_rw_ack_intr0___mpu_7___lsb 7
+#define reg_iop_sw_cpu_rw_ack_intr0___mpu_7___width 1
+#define reg_iop_sw_cpu_rw_ack_intr0___mpu_7___bit 7
+#define reg_iop_sw_cpu_rw_ack_intr0___mpu_8___lsb 8
+#define reg_iop_sw_cpu_rw_ack_intr0___mpu_8___width 1
+#define reg_iop_sw_cpu_rw_ack_intr0___mpu_8___bit 8
+#define reg_iop_sw_cpu_rw_ack_intr0___mpu_9___lsb 9
+#define reg_iop_sw_cpu_rw_ack_intr0___mpu_9___width 1
+#define reg_iop_sw_cpu_rw_ack_intr0___mpu_9___bit 9
+#define reg_iop_sw_cpu_rw_ack_intr0___mpu_10___lsb 10
+#define reg_iop_sw_cpu_rw_ack_intr0___mpu_10___width 1
+#define reg_iop_sw_cpu_rw_ack_intr0___mpu_10___bit 10
+#define reg_iop_sw_cpu_rw_ack_intr0___mpu_11___lsb 11
+#define reg_iop_sw_cpu_rw_ack_intr0___mpu_11___width 1
+#define reg_iop_sw_cpu_rw_ack_intr0___mpu_11___bit 11
+#define reg_iop_sw_cpu_rw_ack_intr0___mpu_12___lsb 12
+#define reg_iop_sw_cpu_rw_ack_intr0___mpu_12___width 1
+#define reg_iop_sw_cpu_rw_ack_intr0___mpu_12___bit 12
+#define reg_iop_sw_cpu_rw_ack_intr0___mpu_13___lsb 13
+#define reg_iop_sw_cpu_rw_ack_intr0___mpu_13___width 1
+#define reg_iop_sw_cpu_rw_ack_intr0___mpu_13___bit 13
+#define reg_iop_sw_cpu_rw_ack_intr0___mpu_14___lsb 14
+#define reg_iop_sw_cpu_rw_ack_intr0___mpu_14___width 1
+#define reg_iop_sw_cpu_rw_ack_intr0___mpu_14___bit 14
+#define reg_iop_sw_cpu_rw_ack_intr0___mpu_15___lsb 15
+#define reg_iop_sw_cpu_rw_ack_intr0___mpu_15___width 1
+#define reg_iop_sw_cpu_rw_ack_intr0___mpu_15___bit 15
+#define reg_iop_sw_cpu_rw_ack_intr0___spu0_0___lsb 16
+#define reg_iop_sw_cpu_rw_ack_intr0___spu0_0___width 1
+#define reg_iop_sw_cpu_rw_ack_intr0___spu0_0___bit 16
+#define reg_iop_sw_cpu_rw_ack_intr0___spu0_1___lsb 17
+#define reg_iop_sw_cpu_rw_ack_intr0___spu0_1___width 1
+#define reg_iop_sw_cpu_rw_ack_intr0___spu0_1___bit 17
+#define reg_iop_sw_cpu_rw_ack_intr0___spu0_2___lsb 18
+#define reg_iop_sw_cpu_rw_ack_intr0___spu0_2___width 1
+#define reg_iop_sw_cpu_rw_ack_intr0___spu0_2___bit 18
+#define reg_iop_sw_cpu_rw_ack_intr0___spu0_3___lsb 19
+#define reg_iop_sw_cpu_rw_ack_intr0___spu0_3___width 1
+#define reg_iop_sw_cpu_rw_ack_intr0___spu0_3___bit 19
+#define reg_iop_sw_cpu_rw_ack_intr0___spu0_4___lsb 20
+#define reg_iop_sw_cpu_rw_ack_intr0___spu0_4___width 1
+#define reg_iop_sw_cpu_rw_ack_intr0___spu0_4___bit 20
+#define reg_iop_sw_cpu_rw_ack_intr0___spu0_5___lsb 21
+#define reg_iop_sw_cpu_rw_ack_intr0___spu0_5___width 1
+#define reg_iop_sw_cpu_rw_ack_intr0___spu0_5___bit 21
+#define reg_iop_sw_cpu_rw_ack_intr0___spu0_6___lsb 22
+#define reg_iop_sw_cpu_rw_ack_intr0___spu0_6___width 1
+#define reg_iop_sw_cpu_rw_ack_intr0___spu0_6___bit 22
+#define reg_iop_sw_cpu_rw_ack_intr0___spu0_7___lsb 23
+#define reg_iop_sw_cpu_rw_ack_intr0___spu0_7___width 1
+#define reg_iop_sw_cpu_rw_ack_intr0___spu0_7___bit 23
+#define reg_iop_sw_cpu_rw_ack_intr0___spu1_8___lsb 24
+#define reg_iop_sw_cpu_rw_ack_intr0___spu1_8___width 1
+#define reg_iop_sw_cpu_rw_ack_intr0___spu1_8___bit 24
+#define reg_iop_sw_cpu_rw_ack_intr0___spu1_9___lsb 25
+#define reg_iop_sw_cpu_rw_ack_intr0___spu1_9___width 1
+#define reg_iop_sw_cpu_rw_ack_intr0___spu1_9___bit 25
+#define reg_iop_sw_cpu_rw_ack_intr0___spu1_10___lsb 26
+#define reg_iop_sw_cpu_rw_ack_intr0___spu1_10___width 1
+#define reg_iop_sw_cpu_rw_ack_intr0___spu1_10___bit 26
+#define reg_iop_sw_cpu_rw_ack_intr0___spu1_11___lsb 27
+#define reg_iop_sw_cpu_rw_ack_intr0___spu1_11___width 1
+#define reg_iop_sw_cpu_rw_ack_intr0___spu1_11___bit 27
+#define reg_iop_sw_cpu_rw_ack_intr0___spu1_12___lsb 28
+#define reg_iop_sw_cpu_rw_ack_intr0___spu1_12___width 1
+#define reg_iop_sw_cpu_rw_ack_intr0___spu1_12___bit 28
+#define reg_iop_sw_cpu_rw_ack_intr0___spu1_13___lsb 29
+#define reg_iop_sw_cpu_rw_ack_intr0___spu1_13___width 1
+#define reg_iop_sw_cpu_rw_ack_intr0___spu1_13___bit 29
+#define reg_iop_sw_cpu_rw_ack_intr0___spu1_14___lsb 30
+#define reg_iop_sw_cpu_rw_ack_intr0___spu1_14___width 1
+#define reg_iop_sw_cpu_rw_ack_intr0___spu1_14___bit 30
+#define reg_iop_sw_cpu_rw_ack_intr0___spu1_15___lsb 31
+#define reg_iop_sw_cpu_rw_ack_intr0___spu1_15___width 1
+#define reg_iop_sw_cpu_rw_ack_intr0___spu1_15___bit 31
+#define reg_iop_sw_cpu_rw_ack_intr0_offset 88
+
+/* Register r_intr0, scope iop_sw_cpu, type r */
+#define reg_iop_sw_cpu_r_intr0___mpu_0___lsb 0
+#define reg_iop_sw_cpu_r_intr0___mpu_0___width 1
+#define reg_iop_sw_cpu_r_intr0___mpu_0___bit 0
+#define reg_iop_sw_cpu_r_intr0___mpu_1___lsb 1
+#define reg_iop_sw_cpu_r_intr0___mpu_1___width 1
+#define reg_iop_sw_cpu_r_intr0___mpu_1___bit 1
+#define reg_iop_sw_cpu_r_intr0___mpu_2___lsb 2
+#define reg_iop_sw_cpu_r_intr0___mpu_2___width 1
+#define reg_iop_sw_cpu_r_intr0___mpu_2___bit 2
+#define reg_iop_sw_cpu_r_intr0___mpu_3___lsb 3
+#define reg_iop_sw_cpu_r_intr0___mpu_3___width 1
+#define reg_iop_sw_cpu_r_intr0___mpu_3___bit 3
+#define reg_iop_sw_cpu_r_intr0___mpu_4___lsb 4
+#define reg_iop_sw_cpu_r_intr0___mpu_4___width 1
+#define reg_iop_sw_cpu_r_intr0___mpu_4___bit 4
+#define reg_iop_sw_cpu_r_intr0___mpu_5___lsb 5
+#define reg_iop_sw_cpu_r_intr0___mpu_5___width 1
+#define reg_iop_sw_cpu_r_intr0___mpu_5___bit 5
+#define reg_iop_sw_cpu_r_intr0___mpu_6___lsb 6
+#define reg_iop_sw_cpu_r_intr0___mpu_6___width 1
+#define reg_iop_sw_cpu_r_intr0___mpu_6___bit 6
+#define reg_iop_sw_cpu_r_intr0___mpu_7___lsb 7
+#define reg_iop_sw_cpu_r_intr0___mpu_7___width 1
+#define reg_iop_sw_cpu_r_intr0___mpu_7___bit 7
+#define reg_iop_sw_cpu_r_intr0___mpu_8___lsb 8
+#define reg_iop_sw_cpu_r_intr0___mpu_8___width 1
+#define reg_iop_sw_cpu_r_intr0___mpu_8___bit 8
+#define reg_iop_sw_cpu_r_intr0___mpu_9___lsb 9
+#define reg_iop_sw_cpu_r_intr0___mpu_9___width 1
+#define reg_iop_sw_cpu_r_intr0___mpu_9___bit 9
+#define reg_iop_sw_cpu_r_intr0___mpu_10___lsb 10
+#define reg_iop_sw_cpu_r_intr0___mpu_10___width 1
+#define reg_iop_sw_cpu_r_intr0___mpu_10___bit 10
+#define reg_iop_sw_cpu_r_intr0___mpu_11___lsb 11
+#define reg_iop_sw_cpu_r_intr0___mpu_11___width 1
+#define reg_iop_sw_cpu_r_intr0___mpu_11___bit 11
+#define reg_iop_sw_cpu_r_intr0___mpu_12___lsb 12
+#define reg_iop_sw_cpu_r_intr0___mpu_12___width 1
+#define reg_iop_sw_cpu_r_intr0___mpu_12___bit 12
+#define reg_iop_sw_cpu_r_intr0___mpu_13___lsb 13
+#define reg_iop_sw_cpu_r_intr0___mpu_13___width 1
+#define reg_iop_sw_cpu_r_intr0___mpu_13___bit 13
+#define reg_iop_sw_cpu_r_intr0___mpu_14___lsb 14
+#define reg_iop_sw_cpu_r_intr0___mpu_14___width 1
+#define reg_iop_sw_cpu_r_intr0___mpu_14___bit 14
+#define reg_iop_sw_cpu_r_intr0___mpu_15___lsb 15
+#define reg_iop_sw_cpu_r_intr0___mpu_15___width 1
+#define reg_iop_sw_cpu_r_intr0___mpu_15___bit 15
+#define reg_iop_sw_cpu_r_intr0___spu0_0___lsb 16
+#define reg_iop_sw_cpu_r_intr0___spu0_0___width 1
+#define reg_iop_sw_cpu_r_intr0___spu0_0___bit 16
+#define reg_iop_sw_cpu_r_intr0___spu0_1___lsb 17
+#define reg_iop_sw_cpu_r_intr0___spu0_1___width 1
+#define reg_iop_sw_cpu_r_intr0___spu0_1___bit 17
+#define reg_iop_sw_cpu_r_intr0___spu0_2___lsb 18
+#define reg_iop_sw_cpu_r_intr0___spu0_2___width 1
+#define reg_iop_sw_cpu_r_intr0___spu0_2___bit 18
+#define reg_iop_sw_cpu_r_intr0___spu0_3___lsb 19
+#define reg_iop_sw_cpu_r_intr0___spu0_3___width 1
+#define reg_iop_sw_cpu_r_intr0___spu0_3___bit 19
+#define reg_iop_sw_cpu_r_intr0___spu0_4___lsb 20
+#define reg_iop_sw_cpu_r_intr0___spu0_4___width 1
+#define reg_iop_sw_cpu_r_intr0___spu0_4___bit 20
+#define reg_iop_sw_cpu_r_intr0___spu0_5___lsb 21
+#define reg_iop_sw_cpu_r_intr0___spu0_5___width 1
+#define reg_iop_sw_cpu_r_intr0___spu0_5___bit 21
+#define reg_iop_sw_cpu_r_intr0___spu0_6___lsb 22
+#define reg_iop_sw_cpu_r_intr0___spu0_6___width 1
+#define reg_iop_sw_cpu_r_intr0___spu0_6___bit 22
+#define reg_iop_sw_cpu_r_intr0___spu0_7___lsb 23
+#define reg_iop_sw_cpu_r_intr0___spu0_7___width 1
+#define reg_iop_sw_cpu_r_intr0___spu0_7___bit 23
+#define reg_iop_sw_cpu_r_intr0___spu1_8___lsb 24
+#define reg_iop_sw_cpu_r_intr0___spu1_8___width 1
+#define reg_iop_sw_cpu_r_intr0___spu1_8___bit 24
+#define reg_iop_sw_cpu_r_intr0___spu1_9___lsb 25
+#define reg_iop_sw_cpu_r_intr0___spu1_9___width 1
+#define reg_iop_sw_cpu_r_intr0___spu1_9___bit 25
+#define reg_iop_sw_cpu_r_intr0___spu1_10___lsb 26
+#define reg_iop_sw_cpu_r_intr0___spu1_10___width 1
+#define reg_iop_sw_cpu_r_intr0___spu1_10___bit 26
+#define reg_iop_sw_cpu_r_intr0___spu1_11___lsb 27
+#define reg_iop_sw_cpu_r_intr0___spu1_11___width 1
+#define reg_iop_sw_cpu_r_intr0___spu1_11___bit 27
+#define reg_iop_sw_cpu_r_intr0___spu1_12___lsb 28
+#define reg_iop_sw_cpu_r_intr0___spu1_12___width 1
+#define reg_iop_sw_cpu_r_intr0___spu1_12___bit 28
+#define reg_iop_sw_cpu_r_intr0___spu1_13___lsb 29
+#define reg_iop_sw_cpu_r_intr0___spu1_13___width 1
+#define reg_iop_sw_cpu_r_intr0___spu1_13___bit 29
+#define reg_iop_sw_cpu_r_intr0___spu1_14___lsb 30
+#define reg_iop_sw_cpu_r_intr0___spu1_14___width 1
+#define reg_iop_sw_cpu_r_intr0___spu1_14___bit 30
+#define reg_iop_sw_cpu_r_intr0___spu1_15___lsb 31
+#define reg_iop_sw_cpu_r_intr0___spu1_15___width 1
+#define reg_iop_sw_cpu_r_intr0___spu1_15___bit 31
+#define reg_iop_sw_cpu_r_intr0_offset 92
+
+/* Register r_masked_intr0, scope iop_sw_cpu, type r */
+#define reg_iop_sw_cpu_r_masked_intr0___mpu_0___lsb 0
+#define reg_iop_sw_cpu_r_masked_intr0___mpu_0___width 1
+#define reg_iop_sw_cpu_r_masked_intr0___mpu_0___bit 0
+#define reg_iop_sw_cpu_r_masked_intr0___mpu_1___lsb 1
+#define reg_iop_sw_cpu_r_masked_intr0___mpu_1___width 1
+#define reg_iop_sw_cpu_r_masked_intr0___mpu_1___bit 1
+#define reg_iop_sw_cpu_r_masked_intr0___mpu_2___lsb 2
+#define reg_iop_sw_cpu_r_masked_intr0___mpu_2___width 1
+#define reg_iop_sw_cpu_r_masked_intr0___mpu_2___bit 2
+#define reg_iop_sw_cpu_r_masked_intr0___mpu_3___lsb 3
+#define reg_iop_sw_cpu_r_masked_intr0___mpu_3___width 1
+#define reg_iop_sw_cpu_r_masked_intr0___mpu_3___bit 3
+#define reg_iop_sw_cpu_r_masked_intr0___mpu_4___lsb 4
+#define reg_iop_sw_cpu_r_masked_intr0___mpu_4___width 1
+#define reg_iop_sw_cpu_r_masked_intr0___mpu_4___bit 4
+#define reg_iop_sw_cpu_r_masked_intr0___mpu_5___lsb 5
+#define reg_iop_sw_cpu_r_masked_intr0___mpu_5___width 1
+#define reg_iop_sw_cpu_r_masked_intr0___mpu_5___bit 5
+#define reg_iop_sw_cpu_r_masked_intr0___mpu_6___lsb 6
+#define reg_iop_sw_cpu_r_masked_intr0___mpu_6___width 1
+#define reg_iop_sw_cpu_r_masked_intr0___mpu_6___bit 6
+#define reg_iop_sw_cpu_r_masked_intr0___mpu_7___lsb 7
+#define reg_iop_sw_cpu_r_masked_intr0___mpu_7___width 1
+#define reg_iop_sw_cpu_r_masked_intr0___mpu_7___bit 7
+#define reg_iop_sw_cpu_r_masked_intr0___mpu_8___lsb 8
+#define reg_iop_sw_cpu_r_masked_intr0___mpu_8___width 1
+#define reg_iop_sw_cpu_r_masked_intr0___mpu_8___bit 8
+#define reg_iop_sw_cpu_r_masked_intr0___mpu_9___lsb 9
+#define reg_iop_sw_cpu_r_masked_intr0___mpu_9___width 1
+#define reg_iop_sw_cpu_r_masked_intr0___mpu_9___bit 9
+#define reg_iop_sw_cpu_r_masked_intr0___mpu_10___lsb 10
+#define reg_iop_sw_cpu_r_masked_intr0___mpu_10___width 1
+#define reg_iop_sw_cpu_r_masked_intr0___mpu_10___bit 10
+#define reg_iop_sw_cpu_r_masked_intr0___mpu_11___lsb 11
+#define reg_iop_sw_cpu_r_masked_intr0___mpu_11___width 1
+#define reg_iop_sw_cpu_r_masked_intr0___mpu_11___bit 11
+#define reg_iop_sw_cpu_r_masked_intr0___mpu_12___lsb 12
+#define reg_iop_sw_cpu_r_masked_intr0___mpu_12___width 1
+#define reg_iop_sw_cpu_r_masked_intr0___mpu_12___bit 12
+#define reg_iop_sw_cpu_r_masked_intr0___mpu_13___lsb 13
+#define reg_iop_sw_cpu_r_masked_intr0___mpu_13___width 1
+#define reg_iop_sw_cpu_r_masked_intr0___mpu_13___bit 13
+#define reg_iop_sw_cpu_r_masked_intr0___mpu_14___lsb 14
+#define reg_iop_sw_cpu_r_masked_intr0___mpu_14___width 1
+#define reg_iop_sw_cpu_r_masked_intr0___mpu_14___bit 14
+#define reg_iop_sw_cpu_r_masked_intr0___mpu_15___lsb 15
+#define reg_iop_sw_cpu_r_masked_intr0___mpu_15___width 1
+#define reg_iop_sw_cpu_r_masked_intr0___mpu_15___bit 15
+#define reg_iop_sw_cpu_r_masked_intr0___spu0_0___lsb 16
+#define reg_iop_sw_cpu_r_masked_intr0___spu0_0___width 1
+#define reg_iop_sw_cpu_r_masked_intr0___spu0_0___bit 16
+#define reg_iop_sw_cpu_r_masked_intr0___spu0_1___lsb 17
+#define reg_iop_sw_cpu_r_masked_intr0___spu0_1___width 1
+#define reg_iop_sw_cpu_r_masked_intr0___spu0_1___bit 17
+#define reg_iop_sw_cpu_r_masked_intr0___spu0_2___lsb 18
+#define reg_iop_sw_cpu_r_masked_intr0___spu0_2___width 1
+#define reg_iop_sw_cpu_r_masked_intr0___spu0_2___bit 18
+#define reg_iop_sw_cpu_r_masked_intr0___spu0_3___lsb 19
+#define reg_iop_sw_cpu_r_masked_intr0___spu0_3___width 1
+#define reg_iop_sw_cpu_r_masked_intr0___spu0_3___bit 19
+#define reg_iop_sw_cpu_r_masked_intr0___spu0_4___lsb 20
+#define reg_iop_sw_cpu_r_masked_intr0___spu0_4___width 1
+#define reg_iop_sw_cpu_r_masked_intr0___spu0_4___bit 20
+#define reg_iop_sw_cpu_r_masked_intr0___spu0_5___lsb 21
+#define reg_iop_sw_cpu_r_masked_intr0___spu0_5___width 1
+#define reg_iop_sw_cpu_r_masked_intr0___spu0_5___bit 21
+#define reg_iop_sw_cpu_r_masked_intr0___spu0_6___lsb 22
+#define reg_iop_sw_cpu_r_masked_intr0___spu0_6___width 1
+#define reg_iop_sw_cpu_r_masked_intr0___spu0_6___bit 22
+#define reg_iop_sw_cpu_r_masked_intr0___spu0_7___lsb 23
+#define reg_iop_sw_cpu_r_masked_intr0___spu0_7___width 1
+#define reg_iop_sw_cpu_r_masked_intr0___spu0_7___bit 23
+#define reg_iop_sw_cpu_r_masked_intr0___spu1_8___lsb 24
+#define reg_iop_sw_cpu_r_masked_intr0___spu1_8___width 1
+#define reg_iop_sw_cpu_r_masked_intr0___spu1_8___bit 24
+#define reg_iop_sw_cpu_r_masked_intr0___spu1_9___lsb 25
+#define reg_iop_sw_cpu_r_masked_intr0___spu1_9___width 1
+#define reg_iop_sw_cpu_r_masked_intr0___spu1_9___bit 25
+#define reg_iop_sw_cpu_r_masked_intr0___spu1_10___lsb 26
+#define reg_iop_sw_cpu_r_masked_intr0___spu1_10___width 1
+#define reg_iop_sw_cpu_r_masked_intr0___spu1_10___bit 26
+#define reg_iop_sw_cpu_r_masked_intr0___spu1_11___lsb 27
+#define reg_iop_sw_cpu_r_masked_intr0___spu1_11___width 1
+#define reg_iop_sw_cpu_r_masked_intr0___spu1_11___bit 27
+#define reg_iop_sw_cpu_r_masked_intr0___spu1_12___lsb 28
+#define reg_iop_sw_cpu_r_masked_intr0___spu1_12___width 1
+#define reg_iop_sw_cpu_r_masked_intr0___spu1_12___bit 28
+#define reg_iop_sw_cpu_r_masked_intr0___spu1_13___lsb 29
+#define reg_iop_sw_cpu_r_masked_intr0___spu1_13___width 1
+#define reg_iop_sw_cpu_r_masked_intr0___spu1_13___bit 29
+#define reg_iop_sw_cpu_r_masked_intr0___spu1_14___lsb 30
+#define reg_iop_sw_cpu_r_masked_intr0___spu1_14___width 1
+#define reg_iop_sw_cpu_r_masked_intr0___spu1_14___bit 30
+#define reg_iop_sw_cpu_r_masked_intr0___spu1_15___lsb 31
+#define reg_iop_sw_cpu_r_masked_intr0___spu1_15___width 1
+#define reg_iop_sw_cpu_r_masked_intr0___spu1_15___bit 31
+#define reg_iop_sw_cpu_r_masked_intr0_offset 96
+
+/* Register rw_intr1_mask, scope iop_sw_cpu, type rw */
+#define reg_iop_sw_cpu_rw_intr1_mask___mpu_16___lsb 0
+#define reg_iop_sw_cpu_rw_intr1_mask___mpu_16___width 1
+#define reg_iop_sw_cpu_rw_intr1_mask___mpu_16___bit 0
+#define reg_iop_sw_cpu_rw_intr1_mask___mpu_17___lsb 1
+#define reg_iop_sw_cpu_rw_intr1_mask___mpu_17___width 1
+#define reg_iop_sw_cpu_rw_intr1_mask___mpu_17___bit 1
+#define reg_iop_sw_cpu_rw_intr1_mask___mpu_18___lsb 2
+#define reg_iop_sw_cpu_rw_intr1_mask___mpu_18___width 1
+#define reg_iop_sw_cpu_rw_intr1_mask___mpu_18___bit 2
+#define reg_iop_sw_cpu_rw_intr1_mask___mpu_19___lsb 3
+#define reg_iop_sw_cpu_rw_intr1_mask___mpu_19___width 1
+#define reg_iop_sw_cpu_rw_intr1_mask___mpu_19___bit 3
+#define reg_iop_sw_cpu_rw_intr1_mask___mpu_20___lsb 4
+#define reg_iop_sw_cpu_rw_intr1_mask___mpu_20___width 1
+#define reg_iop_sw_cpu_rw_intr1_mask___mpu_20___bit 4
+#define reg_iop_sw_cpu_rw_intr1_mask___mpu_21___lsb 5
+#define reg_iop_sw_cpu_rw_intr1_mask___mpu_21___width 1
+#define reg_iop_sw_cpu_rw_intr1_mask___mpu_21___bit 5
+#define reg_iop_sw_cpu_rw_intr1_mask___mpu_22___lsb 6
+#define reg_iop_sw_cpu_rw_intr1_mask___mpu_22___width 1
+#define reg_iop_sw_cpu_rw_intr1_mask___mpu_22___bit 6
+#define reg_iop_sw_cpu_rw_intr1_mask___mpu_23___lsb 7
+#define reg_iop_sw_cpu_rw_intr1_mask___mpu_23___width 1
+#define reg_iop_sw_cpu_rw_intr1_mask___mpu_23___bit 7
+#define reg_iop_sw_cpu_rw_intr1_mask___mpu_24___lsb 8
+#define reg_iop_sw_cpu_rw_intr1_mask___mpu_24___width 1
+#define reg_iop_sw_cpu_rw_intr1_mask___mpu_24___bit 8
+#define reg_iop_sw_cpu_rw_intr1_mask___mpu_25___lsb 9
+#define reg_iop_sw_cpu_rw_intr1_mask___mpu_25___width 1
+#define reg_iop_sw_cpu_rw_intr1_mask___mpu_25___bit 9
+#define reg_iop_sw_cpu_rw_intr1_mask___mpu_26___lsb 10
+#define reg_iop_sw_cpu_rw_intr1_mask___mpu_26___width 1
+#define reg_iop_sw_cpu_rw_intr1_mask___mpu_26___bit 10
+#define reg_iop_sw_cpu_rw_intr1_mask___mpu_27___lsb 11
+#define reg_iop_sw_cpu_rw_intr1_mask___mpu_27___width 1
+#define reg_iop_sw_cpu_rw_intr1_mask___mpu_27___bit 11
+#define reg_iop_sw_cpu_rw_intr1_mask___mpu_28___lsb 12
+#define reg_iop_sw_cpu_rw_intr1_mask___mpu_28___width 1
+#define reg_iop_sw_cpu_rw_intr1_mask___mpu_28___bit 12
+#define reg_iop_sw_cpu_rw_intr1_mask___mpu_29___lsb 13
+#define reg_iop_sw_cpu_rw_intr1_mask___mpu_29___width 1
+#define reg_iop_sw_cpu_rw_intr1_mask___mpu_29___bit 13
+#define reg_iop_sw_cpu_rw_intr1_mask___mpu_30___lsb 14
+#define reg_iop_sw_cpu_rw_intr1_mask___mpu_30___width 1
+#define reg_iop_sw_cpu_rw_intr1_mask___mpu_30___bit 14
+#define reg_iop_sw_cpu_rw_intr1_mask___mpu_31___lsb 15
+#define reg_iop_sw_cpu_rw_intr1_mask___mpu_31___width 1
+#define reg_iop_sw_cpu_rw_intr1_mask___mpu_31___bit 15
+#define reg_iop_sw_cpu_rw_intr1_mask___spu0_8___lsb 16
+#define reg_iop_sw_cpu_rw_intr1_mask___spu0_8___width 1
+#define reg_iop_sw_cpu_rw_intr1_mask___spu0_8___bit 16
+#define reg_iop_sw_cpu_rw_intr1_mask___spu0_9___lsb 17
+#define reg_iop_sw_cpu_rw_intr1_mask___spu0_9___width 1
+#define reg_iop_sw_cpu_rw_intr1_mask___spu0_9___bit 17
+#define reg_iop_sw_cpu_rw_intr1_mask___spu0_10___lsb 18
+#define reg_iop_sw_cpu_rw_intr1_mask___spu0_10___width 1
+#define reg_iop_sw_cpu_rw_intr1_mask___spu0_10___bit 18
+#define reg_iop_sw_cpu_rw_intr1_mask___spu0_11___lsb 19
+#define reg_iop_sw_cpu_rw_intr1_mask___spu0_11___width 1
+#define reg_iop_sw_cpu_rw_intr1_mask___spu0_11___bit 19
+#define reg_iop_sw_cpu_rw_intr1_mask___spu0_12___lsb 20
+#define reg_iop_sw_cpu_rw_intr1_mask___spu0_12___width 1
+#define reg_iop_sw_cpu_rw_intr1_mask___spu0_12___bit 20
+#define reg_iop_sw_cpu_rw_intr1_mask___spu0_13___lsb 21
+#define reg_iop_sw_cpu_rw_intr1_mask___spu0_13___width 1
+#define reg_iop_sw_cpu_rw_intr1_mask___spu0_13___bit 21
+#define reg_iop_sw_cpu_rw_intr1_mask___spu0_14___lsb 22
+#define reg_iop_sw_cpu_rw_intr1_mask___spu0_14___width 1
+#define reg_iop_sw_cpu_rw_intr1_mask___spu0_14___bit 22
+#define reg_iop_sw_cpu_rw_intr1_mask___spu0_15___lsb 23
+#define reg_iop_sw_cpu_rw_intr1_mask___spu0_15___width 1
+#define reg_iop_sw_cpu_rw_intr1_mask___spu0_15___bit 23
+#define reg_iop_sw_cpu_rw_intr1_mask___spu1_0___lsb 24
+#define reg_iop_sw_cpu_rw_intr1_mask___spu1_0___width 1
+#define reg_iop_sw_cpu_rw_intr1_mask___spu1_0___bit 24
+#define reg_iop_sw_cpu_rw_intr1_mask___spu1_1___lsb 25
+#define reg_iop_sw_cpu_rw_intr1_mask___spu1_1___width 1
+#define reg_iop_sw_cpu_rw_intr1_mask___spu1_1___bit 25
+#define reg_iop_sw_cpu_rw_intr1_mask___spu1_2___lsb 26
+#define reg_iop_sw_cpu_rw_intr1_mask___spu1_2___width 1
+#define reg_iop_sw_cpu_rw_intr1_mask___spu1_2___bit 26
+#define reg_iop_sw_cpu_rw_intr1_mask___spu1_3___lsb 27
+#define reg_iop_sw_cpu_rw_intr1_mask___spu1_3___width 1
+#define reg_iop_sw_cpu_rw_intr1_mask___spu1_3___bit 27
+#define reg_iop_sw_cpu_rw_intr1_mask___spu1_4___lsb 28
+#define reg_iop_sw_cpu_rw_intr1_mask___spu1_4___width 1
+#define reg_iop_sw_cpu_rw_intr1_mask___spu1_4___bit 28
+#define reg_iop_sw_cpu_rw_intr1_mask___spu1_5___lsb 29
+#define reg_iop_sw_cpu_rw_intr1_mask___spu1_5___width 1
+#define reg_iop_sw_cpu_rw_intr1_mask___spu1_5___bit 29
+#define reg_iop_sw_cpu_rw_intr1_mask___spu1_6___lsb 30
+#define reg_iop_sw_cpu_rw_intr1_mask___spu1_6___width 1
+#define reg_iop_sw_cpu_rw_intr1_mask___spu1_6___bit 30
+#define reg_iop_sw_cpu_rw_intr1_mask___spu1_7___lsb 31
+#define reg_iop_sw_cpu_rw_intr1_mask___spu1_7___width 1
+#define reg_iop_sw_cpu_rw_intr1_mask___spu1_7___bit 31
+#define reg_iop_sw_cpu_rw_intr1_mask_offset 100
+
+/* Register rw_ack_intr1, scope iop_sw_cpu, type rw */
+#define reg_iop_sw_cpu_rw_ack_intr1___mpu_16___lsb 0
+#define reg_iop_sw_cpu_rw_ack_intr1___mpu_16___width 1
+#define reg_iop_sw_cpu_rw_ack_intr1___mpu_16___bit 0
+#define reg_iop_sw_cpu_rw_ack_intr1___mpu_17___lsb 1
+#define reg_iop_sw_cpu_rw_ack_intr1___mpu_17___width 1
+#define reg_iop_sw_cpu_rw_ack_intr1___mpu_17___bit 1
+#define reg_iop_sw_cpu_rw_ack_intr1___mpu_18___lsb 2
+#define reg_iop_sw_cpu_rw_ack_intr1___mpu_18___width 1
+#define reg_iop_sw_cpu_rw_ack_intr1___mpu_18___bit 2
+#define reg_iop_sw_cpu_rw_ack_intr1___mpu_19___lsb 3
+#define reg_iop_sw_cpu_rw_ack_intr1___mpu_19___width 1
+#define reg_iop_sw_cpu_rw_ack_intr1___mpu_19___bit 3
+#define reg_iop_sw_cpu_rw_ack_intr1___mpu_20___lsb 4
+#define reg_iop_sw_cpu_rw_ack_intr1___mpu_20___width 1
+#define reg_iop_sw_cpu_rw_ack_intr1___mpu_20___bit 4
+#define reg_iop_sw_cpu_rw_ack_intr1___mpu_21___lsb 5
+#define reg_iop_sw_cpu_rw_ack_intr1___mpu_21___width 1
+#define reg_iop_sw_cpu_rw_ack_intr1___mpu_21___bit 5
+#define reg_iop_sw_cpu_rw_ack_intr1___mpu_22___lsb 6
+#define reg_iop_sw_cpu_rw_ack_intr1___mpu_22___width 1
+#define reg_iop_sw_cpu_rw_ack_intr1___mpu_22___bit 6
+#define reg_iop_sw_cpu_rw_ack_intr1___mpu_23___lsb 7
+#define reg_iop_sw_cpu_rw_ack_intr1___mpu_23___width 1
+#define reg_iop_sw_cpu_rw_ack_intr1___mpu_23___bit 7
+#define reg_iop_sw_cpu_rw_ack_intr1___mpu_24___lsb 8
+#define reg_iop_sw_cpu_rw_ack_intr1___mpu_24___width 1
+#define reg_iop_sw_cpu_rw_ack_intr1___mpu_24___bit 8
+#define reg_iop_sw_cpu_rw_ack_intr1___mpu_25___lsb 9
+#define reg_iop_sw_cpu_rw_ack_intr1___mpu_25___width 1
+#define reg_iop_sw_cpu_rw_ack_intr1___mpu_25___bit 9
+#define reg_iop_sw_cpu_rw_ack_intr1___mpu_26___lsb 10
+#define reg_iop_sw_cpu_rw_ack_intr1___mpu_26___width 1
+#define reg_iop_sw_cpu_rw_ack_intr1___mpu_26___bit 10
+#define reg_iop_sw_cpu_rw_ack_intr1___mpu_27___lsb 11
+#define reg_iop_sw_cpu_rw_ack_intr1___mpu_27___width 1
+#define reg_iop_sw_cpu_rw_ack_intr1___mpu_27___bit 11
+#define reg_iop_sw_cpu_rw_ack_intr1___mpu_28___lsb 12
+#define reg_iop_sw_cpu_rw_ack_intr1___mpu_28___width 1
+#define reg_iop_sw_cpu_rw_ack_intr1___mpu_28___bit 12
+#define reg_iop_sw_cpu_rw_ack_intr1___mpu_29___lsb 13
+#define reg_iop_sw_cpu_rw_ack_intr1___mpu_29___width 1
+#define reg_iop_sw_cpu_rw_ack_intr1___mpu_29___bit 13
+#define reg_iop_sw_cpu_rw_ack_intr1___mpu_30___lsb 14
+#define reg_iop_sw_cpu_rw_ack_intr1___mpu_30___width 1
+#define reg_iop_sw_cpu_rw_ack_intr1___mpu_30___bit 14
+#define reg_iop_sw_cpu_rw_ack_intr1___mpu_31___lsb 15
+#define reg_iop_sw_cpu_rw_ack_intr1___mpu_31___width 1
+#define reg_iop_sw_cpu_rw_ack_intr1___mpu_31___bit 15
+#define reg_iop_sw_cpu_rw_ack_intr1___spu0_8___lsb 16
+#define reg_iop_sw_cpu_rw_ack_intr1___spu0_8___width 1
+#define reg_iop_sw_cpu_rw_ack_intr1___spu0_8___bit 16
+#define reg_iop_sw_cpu_rw_ack_intr1___spu0_9___lsb 17
+#define reg_iop_sw_cpu_rw_ack_intr1___spu0_9___width 1
+#define reg_iop_sw_cpu_rw_ack_intr1___spu0_9___bit 17
+#define reg_iop_sw_cpu_rw_ack_intr1___spu0_10___lsb 18
+#define reg_iop_sw_cpu_rw_ack_intr1___spu0_10___width 1
+#define reg_iop_sw_cpu_rw_ack_intr1___spu0_10___bit 18
+#define reg_iop_sw_cpu_rw_ack_intr1___spu0_11___lsb 19
+#define reg_iop_sw_cpu_rw_ack_intr1___spu0_11___width 1
+#define reg_iop_sw_cpu_rw_ack_intr1___spu0_11___bit 19
+#define reg_iop_sw_cpu_rw_ack_intr1___spu0_12___lsb 20
+#define reg_iop_sw_cpu_rw_ack_intr1___spu0_12___width 1
+#define reg_iop_sw_cpu_rw_ack_intr1___spu0_12___bit 20
+#define reg_iop_sw_cpu_rw_ack_intr1___spu0_13___lsb 21
+#define reg_iop_sw_cpu_rw_ack_intr1___spu0_13___width 1
+#define reg_iop_sw_cpu_rw_ack_intr1___spu0_13___bit 21
+#define reg_iop_sw_cpu_rw_ack_intr1___spu0_14___lsb 22
+#define reg_iop_sw_cpu_rw_ack_intr1___spu0_14___width 1
+#define reg_iop_sw_cpu_rw_ack_intr1___spu0_14___bit 22
+#define reg_iop_sw_cpu_rw_ack_intr1___spu0_15___lsb 23
+#define reg_iop_sw_cpu_rw_ack_intr1___spu0_15___width 1
+#define reg_iop_sw_cpu_rw_ack_intr1___spu0_15___bit 23
+#define reg_iop_sw_cpu_rw_ack_intr1___spu1_0___lsb 24
+#define reg_iop_sw_cpu_rw_ack_intr1___spu1_0___width 1
+#define reg_iop_sw_cpu_rw_ack_intr1___spu1_0___bit 24
+#define reg_iop_sw_cpu_rw_ack_intr1___spu1_1___lsb 25
+#define reg_iop_sw_cpu_rw_ack_intr1___spu1_1___width 1
+#define reg_iop_sw_cpu_rw_ack_intr1___spu1_1___bit 25
+#define reg_iop_sw_cpu_rw_ack_intr1___spu1_2___lsb 26
+#define reg_iop_sw_cpu_rw_ack_intr1___spu1_2___width 1
+#define reg_iop_sw_cpu_rw_ack_intr1___spu1_2___bit 26
+#define reg_iop_sw_cpu_rw_ack_intr1___spu1_3___lsb 27
+#define reg_iop_sw_cpu_rw_ack_intr1___spu1_3___width 1
+#define reg_iop_sw_cpu_rw_ack_intr1___spu1_3___bit 27
+#define reg_iop_sw_cpu_rw_ack_intr1___spu1_4___lsb 28
+#define reg_iop_sw_cpu_rw_ack_intr1___spu1_4___width 1
+#define reg_iop_sw_cpu_rw_ack_intr1___spu1_4___bit 28
+#define reg_iop_sw_cpu_rw_ack_intr1___spu1_5___lsb 29
+#define reg_iop_sw_cpu_rw_ack_intr1___spu1_5___width 1
+#define reg_iop_sw_cpu_rw_ack_intr1___spu1_5___bit 29
+#define reg_iop_sw_cpu_rw_ack_intr1___spu1_6___lsb 30
+#define reg_iop_sw_cpu_rw_ack_intr1___spu1_6___width 1
+#define reg_iop_sw_cpu_rw_ack_intr1___spu1_6___bit 30
+#define reg_iop_sw_cpu_rw_ack_intr1___spu1_7___lsb 31
+#define reg_iop_sw_cpu_rw_ack_intr1___spu1_7___width 1
+#define reg_iop_sw_cpu_rw_ack_intr1___spu1_7___bit 31
+#define reg_iop_sw_cpu_rw_ack_intr1_offset 104
+
+/* Register r_intr1, scope iop_sw_cpu, type r */
+#define reg_iop_sw_cpu_r_intr1___mpu_16___lsb 0
+#define reg_iop_sw_cpu_r_intr1___mpu_16___width 1
+#define reg_iop_sw_cpu_r_intr1___mpu_16___bit 0
+#define reg_iop_sw_cpu_r_intr1___mpu_17___lsb 1
+#define reg_iop_sw_cpu_r_intr1___mpu_17___width 1
+#define reg_iop_sw_cpu_r_intr1___mpu_17___bit 1
+#define reg_iop_sw_cpu_r_intr1___mpu_18___lsb 2
+#define reg_iop_sw_cpu_r_intr1___mpu_18___width 1
+#define reg_iop_sw_cpu_r_intr1___mpu_18___bit 2
+#define reg_iop_sw_cpu_r_intr1___mpu_19___lsb 3
+#define reg_iop_sw_cpu_r_intr1___mpu_19___width 1
+#define reg_iop_sw_cpu_r_intr1___mpu_19___bit 3
+#define reg_iop_sw_cpu_r_intr1___mpu_20___lsb 4
+#define reg_iop_sw_cpu_r_intr1___mpu_20___width 1
+#define reg_iop_sw_cpu_r_intr1___mpu_20___bit 4
+#define reg_iop_sw_cpu_r_intr1___mpu_21___lsb 5
+#define reg_iop_sw_cpu_r_intr1___mpu_21___width 1
+#define reg_iop_sw_cpu_r_intr1___mpu_21___bit 5
+#define reg_iop_sw_cpu_r_intr1___mpu_22___lsb 6
+#define reg_iop_sw_cpu_r_intr1___mpu_22___width 1
+#define reg_iop_sw_cpu_r_intr1___mpu_22___bit 6
+#define reg_iop_sw_cpu_r_intr1___mpu_23___lsb 7
+#define reg_iop_sw_cpu_r_intr1___mpu_23___width 1
+#define reg_iop_sw_cpu_r_intr1___mpu_23___bit 7
+#define reg_iop_sw_cpu_r_intr1___mpu_24___lsb 8
+#define reg_iop_sw_cpu_r_intr1___mpu_24___width 1
+#define reg_iop_sw_cpu_r_intr1___mpu_24___bit 8
+#define reg_iop_sw_cpu_r_intr1___mpu_25___lsb 9
+#define reg_iop_sw_cpu_r_intr1___mpu_25___width 1
+#define reg_iop_sw_cpu_r_intr1___mpu_25___bit 9
+#define reg_iop_sw_cpu_r_intr1___mpu_26___lsb 10
+#define reg_iop_sw_cpu_r_intr1___mpu_26___width 1
+#define reg_iop_sw_cpu_r_intr1___mpu_26___bit 10
+#define reg_iop_sw_cpu_r_intr1___mpu_27___lsb 11
+#define reg_iop_sw_cpu_r_intr1___mpu_27___width 1
+#define reg_iop_sw_cpu_r_intr1___mpu_27___bit 11
+#define reg_iop_sw_cpu_r_intr1___mpu_28___lsb 12
+#define reg_iop_sw_cpu_r_intr1___mpu_28___width 1
+#define reg_iop_sw_cpu_r_intr1___mpu_28___bit 12
+#define reg_iop_sw_cpu_r_intr1___mpu_29___lsb 13
+#define reg_iop_sw_cpu_r_intr1___mpu_29___width 1
+#define reg_iop_sw_cpu_r_intr1___mpu_29___bit 13
+#define reg_iop_sw_cpu_r_intr1___mpu_30___lsb 14
+#define reg_iop_sw_cpu_r_intr1___mpu_30___width 1
+#define reg_iop_sw_cpu_r_intr1___mpu_30___bit 14
+#define reg_iop_sw_cpu_r_intr1___mpu_31___lsb 15
+#define reg_iop_sw_cpu_r_intr1___mpu_31___width 1
+#define reg_iop_sw_cpu_r_intr1___mpu_31___bit 15
+#define reg_iop_sw_cpu_r_intr1___spu0_8___lsb 16
+#define reg_iop_sw_cpu_r_intr1___spu0_8___width 1
+#define reg_iop_sw_cpu_r_intr1___spu0_8___bit 16
+#define reg_iop_sw_cpu_r_intr1___spu0_9___lsb 17
+#define reg_iop_sw_cpu_r_intr1___spu0_9___width 1
+#define reg_iop_sw_cpu_r_intr1___spu0_9___bit 17
+#define reg_iop_sw_cpu_r_intr1___spu0_10___lsb 18
+#define reg_iop_sw_cpu_r_intr1___spu0_10___width 1
+#define reg_iop_sw_cpu_r_intr1___spu0_10___bit 18
+#define reg_iop_sw_cpu_r_intr1___spu0_11___lsb 19
+#define reg_iop_sw_cpu_r_intr1___spu0_11___width 1
+#define reg_iop_sw_cpu_r_intr1___spu0_11___bit 19
+#define reg_iop_sw_cpu_r_intr1___spu0_12___lsb 20
+#define reg_iop_sw_cpu_r_intr1___spu0_12___width 1
+#define reg_iop_sw_cpu_r_intr1___spu0_12___bit 20
+#define reg_iop_sw_cpu_r_intr1___spu0_13___lsb 21
+#define reg_iop_sw_cpu_r_intr1___spu0_13___width 1
+#define reg_iop_sw_cpu_r_intr1___spu0_13___bit 21
+#define reg_iop_sw_cpu_r_intr1___spu0_14___lsb 22
+#define reg_iop_sw_cpu_r_intr1___spu0_14___width 1
+#define reg_iop_sw_cpu_r_intr1___spu0_14___bit 22
+#define reg_iop_sw_cpu_r_intr1___spu0_15___lsb 23
+#define reg_iop_sw_cpu_r_intr1___spu0_15___width 1
+#define reg_iop_sw_cpu_r_intr1___spu0_15___bit 23
+#define reg_iop_sw_cpu_r_intr1___spu1_0___lsb 24
+#define reg_iop_sw_cpu_r_intr1___spu1_0___width 1
+#define reg_iop_sw_cpu_r_intr1___spu1_0___bit 24
+#define reg_iop_sw_cpu_r_intr1___spu1_1___lsb 25
+#define reg_iop_sw_cpu_r_intr1___spu1_1___width 1
+#define reg_iop_sw_cpu_r_intr1___spu1_1___bit 25
+#define reg_iop_sw_cpu_r_intr1___spu1_2___lsb 26
+#define reg_iop_sw_cpu_r_intr1___spu1_2___width 1
+#define reg_iop_sw_cpu_r_intr1___spu1_2___bit 26
+#define reg_iop_sw_cpu_r_intr1___spu1_3___lsb 27
+#define reg_iop_sw_cpu_r_intr1___spu1_3___width 1
+#define reg_iop_sw_cpu_r_intr1___spu1_3___bit 27
+#define reg_iop_sw_cpu_r_intr1___spu1_4___lsb 28
+#define reg_iop_sw_cpu_r_intr1___spu1_4___width 1
+#define reg_iop_sw_cpu_r_intr1___spu1_4___bit 28
+#define reg_iop_sw_cpu_r_intr1___spu1_5___lsb 29
+#define reg_iop_sw_cpu_r_intr1___spu1_5___width 1
+#define reg_iop_sw_cpu_r_intr1___spu1_5___bit 29
+#define reg_iop_sw_cpu_r_intr1___spu1_6___lsb 30
+#define reg_iop_sw_cpu_r_intr1___spu1_6___width 1
+#define reg_iop_sw_cpu_r_intr1___spu1_6___bit 30
+#define reg_iop_sw_cpu_r_intr1___spu1_7___lsb 31
+#define reg_iop_sw_cpu_r_intr1___spu1_7___width 1
+#define reg_iop_sw_cpu_r_intr1___spu1_7___bit 31
+#define reg_iop_sw_cpu_r_intr1_offset 108
+
+/* Register r_masked_intr1, scope iop_sw_cpu, type r */
+#define reg_iop_sw_cpu_r_masked_intr1___mpu_16___lsb 0
+#define reg_iop_sw_cpu_r_masked_intr1___mpu_16___width 1
+#define reg_iop_sw_cpu_r_masked_intr1___mpu_16___bit 0
+#define reg_iop_sw_cpu_r_masked_intr1___mpu_17___lsb 1
+#define reg_iop_sw_cpu_r_masked_intr1___mpu_17___width 1
+#define reg_iop_sw_cpu_r_masked_intr1___mpu_17___bit 1
+#define reg_iop_sw_cpu_r_masked_intr1___mpu_18___lsb 2
+#define reg_iop_sw_cpu_r_masked_intr1___mpu_18___width 1
+#define reg_iop_sw_cpu_r_masked_intr1___mpu_18___bit 2
+#define reg_iop_sw_cpu_r_masked_intr1___mpu_19___lsb 3
+#define reg_iop_sw_cpu_r_masked_intr1___mpu_19___width 1
+#define reg_iop_sw_cpu_r_masked_intr1___mpu_19___bit 3
+#define reg_iop_sw_cpu_r_masked_intr1___mpu_20___lsb 4
+#define reg_iop_sw_cpu_r_masked_intr1___mpu_20___width 1
+#define reg_iop_sw_cpu_r_masked_intr1___mpu_20___bit 4
+#define reg_iop_sw_cpu_r_masked_intr1___mpu_21___lsb 5
+#define reg_iop_sw_cpu_r_masked_intr1___mpu_21___width 1
+#define reg_iop_sw_cpu_r_masked_intr1___mpu_21___bit 5
+#define reg_iop_sw_cpu_r_masked_intr1___mpu_22___lsb 6
+#define reg_iop_sw_cpu_r_masked_intr1___mpu_22___width 1
+#define reg_iop_sw_cpu_r_masked_intr1___mpu_22___bit 6
+#define reg_iop_sw_cpu_r_masked_intr1___mpu_23___lsb 7
+#define reg_iop_sw_cpu_r_masked_intr1___mpu_23___width 1
+#define reg_iop_sw_cpu_r_masked_intr1___mpu_23___bit 7
+#define reg_iop_sw_cpu_r_masked_intr1___mpu_24___lsb 8
+#define reg_iop_sw_cpu_r_masked_intr1___mpu_24___width 1
+#define reg_iop_sw_cpu_r_masked_intr1___mpu_24___bit 8
+#define reg_iop_sw_cpu_r_masked_intr1___mpu_25___lsb 9
+#define reg_iop_sw_cpu_r_masked_intr1___mpu_25___width 1
+#define reg_iop_sw_cpu_r_masked_intr1___mpu_25___bit 9
+#define reg_iop_sw_cpu_r_masked_intr1___mpu_26___lsb 10
+#define reg_iop_sw_cpu_r_masked_intr1___mpu_26___width 1
+#define reg_iop_sw_cpu_r_masked_intr1___mpu_26___bit 10
+#define reg_iop_sw_cpu_r_masked_intr1___mpu_27___lsb 11
+#define reg_iop_sw_cpu_r_masked_intr1___mpu_27___width 1
+#define reg_iop_sw_cpu_r_masked_intr1___mpu_27___bit 11
+#define reg_iop_sw_cpu_r_masked_intr1___mpu_28___lsb 12
+#define reg_iop_sw_cpu_r_masked_intr1___mpu_28___width 1
+#define reg_iop_sw_cpu_r_masked_intr1___mpu_28___bit 12
+#define reg_iop_sw_cpu_r_masked_intr1___mpu_29___lsb 13
+#define reg_iop_sw_cpu_r_masked_intr1___mpu_29___width 1
+#define reg_iop_sw_cpu_r_masked_intr1___mpu_29___bit 13
+#define reg_iop_sw_cpu_r_masked_intr1___mpu_30___lsb 14
+#define reg_iop_sw_cpu_r_masked_intr1___mpu_30___width 1
+#define reg_iop_sw_cpu_r_masked_intr1___mpu_30___bit 14
+#define reg_iop_sw_cpu_r_masked_intr1___mpu_31___lsb 15
+#define reg_iop_sw_cpu_r_masked_intr1___mpu_31___width 1
+#define reg_iop_sw_cpu_r_masked_intr1___mpu_31___bit 15
+#define reg_iop_sw_cpu_r_masked_intr1___spu0_8___lsb 16
+#define reg_iop_sw_cpu_r_masked_intr1___spu0_8___width 1
+#define reg_iop_sw_cpu_r_masked_intr1___spu0_8___bit 16
+#define reg_iop_sw_cpu_r_masked_intr1___spu0_9___lsb 17
+#define reg_iop_sw_cpu_r_masked_intr1___spu0_9___width 1
+#define reg_iop_sw_cpu_r_masked_intr1___spu0_9___bit 17
+#define reg_iop_sw_cpu_r_masked_intr1___spu0_10___lsb 18
+#define reg_iop_sw_cpu_r_masked_intr1___spu0_10___width 1
+#define reg_iop_sw_cpu_r_masked_intr1___spu0_10___bit 18
+#define reg_iop_sw_cpu_r_masked_intr1___spu0_11___lsb 19
+#define reg_iop_sw_cpu_r_masked_intr1___spu0_11___width 1
+#define reg_iop_sw_cpu_r_masked_intr1___spu0_11___bit 19
+#define reg_iop_sw_cpu_r_masked_intr1___spu0_12___lsb 20
+#define reg_iop_sw_cpu_r_masked_intr1___spu0_12___width 1
+#define reg_iop_sw_cpu_r_masked_intr1___spu0_12___bit 20
+#define reg_iop_sw_cpu_r_masked_intr1___spu0_13___lsb 21
+#define reg_iop_sw_cpu_r_masked_intr1___spu0_13___width 1
+#define reg_iop_sw_cpu_r_masked_intr1___spu0_13___bit 21
+#define reg_iop_sw_cpu_r_masked_intr1___spu0_14___lsb 22
+#define reg_iop_sw_cpu_r_masked_intr1___spu0_14___width 1
+#define reg_iop_sw_cpu_r_masked_intr1___spu0_14___bit 22
+#define reg_iop_sw_cpu_r_masked_intr1___spu0_15___lsb 23
+#define reg_iop_sw_cpu_r_masked_intr1___spu0_15___width 1
+#define reg_iop_sw_cpu_r_masked_intr1___spu0_15___bit 23
+#define reg_iop_sw_cpu_r_masked_intr1___spu1_0___lsb 24
+#define reg_iop_sw_cpu_r_masked_intr1___spu1_0___width 1
+#define reg_iop_sw_cpu_r_masked_intr1___spu1_0___bit 24
+#define reg_iop_sw_cpu_r_masked_intr1___spu1_1___lsb 25
+#define reg_iop_sw_cpu_r_masked_intr1___spu1_1___width 1
+#define reg_iop_sw_cpu_r_masked_intr1___spu1_1___bit 25
+#define reg_iop_sw_cpu_r_masked_intr1___spu1_2___lsb 26
+#define reg_iop_sw_cpu_r_masked_intr1___spu1_2___width 1
+#define reg_iop_sw_cpu_r_masked_intr1___spu1_2___bit 26
+#define reg_iop_sw_cpu_r_masked_intr1___spu1_3___lsb 27
+#define reg_iop_sw_cpu_r_masked_intr1___spu1_3___width 1
+#define reg_iop_sw_cpu_r_masked_intr1___spu1_3___bit 27
+#define reg_iop_sw_cpu_r_masked_intr1___spu1_4___lsb 28
+#define reg_iop_sw_cpu_r_masked_intr1___spu1_4___width 1
+#define reg_iop_sw_cpu_r_masked_intr1___spu1_4___bit 28
+#define reg_iop_sw_cpu_r_masked_intr1___spu1_5___lsb 29
+#define reg_iop_sw_cpu_r_masked_intr1___spu1_5___width 1
+#define reg_iop_sw_cpu_r_masked_intr1___spu1_5___bit 29
+#define reg_iop_sw_cpu_r_masked_intr1___spu1_6___lsb 30
+#define reg_iop_sw_cpu_r_masked_intr1___spu1_6___width 1
+#define reg_iop_sw_cpu_r_masked_intr1___spu1_6___bit 30
+#define reg_iop_sw_cpu_r_masked_intr1___spu1_7___lsb 31
+#define reg_iop_sw_cpu_r_masked_intr1___spu1_7___width 1
+#define reg_iop_sw_cpu_r_masked_intr1___spu1_7___bit 31
+#define reg_iop_sw_cpu_r_masked_intr1_offset 112
+
+/* Register rw_intr2_mask, scope iop_sw_cpu, type rw */
+#define reg_iop_sw_cpu_rw_intr2_mask___mpu_0___lsb 0
+#define reg_iop_sw_cpu_rw_intr2_mask___mpu_0___width 1
+#define reg_iop_sw_cpu_rw_intr2_mask___mpu_0___bit 0
+#define reg_iop_sw_cpu_rw_intr2_mask___mpu_1___lsb 1
+#define reg_iop_sw_cpu_rw_intr2_mask___mpu_1___width 1
+#define reg_iop_sw_cpu_rw_intr2_mask___mpu_1___bit 1
+#define reg_iop_sw_cpu_rw_intr2_mask___mpu_2___lsb 2
+#define reg_iop_sw_cpu_rw_intr2_mask___mpu_2___width 1
+#define reg_iop_sw_cpu_rw_intr2_mask___mpu_2___bit 2
+#define reg_iop_sw_cpu_rw_intr2_mask___mpu_3___lsb 3
+#define reg_iop_sw_cpu_rw_intr2_mask___mpu_3___width 1
+#define reg_iop_sw_cpu_rw_intr2_mask___mpu_3___bit 3
+#define reg_iop_sw_cpu_rw_intr2_mask___mpu_4___lsb 4
+#define reg_iop_sw_cpu_rw_intr2_mask___mpu_4___width 1
+#define reg_iop_sw_cpu_rw_intr2_mask___mpu_4___bit 4
+#define reg_iop_sw_cpu_rw_intr2_mask___mpu_5___lsb 5
+#define reg_iop_sw_cpu_rw_intr2_mask___mpu_5___width 1
+#define reg_iop_sw_cpu_rw_intr2_mask___mpu_5___bit 5
+#define reg_iop_sw_cpu_rw_intr2_mask___mpu_6___lsb 6
+#define reg_iop_sw_cpu_rw_intr2_mask___mpu_6___width 1
+#define reg_iop_sw_cpu_rw_intr2_mask___mpu_6___bit 6
+#define reg_iop_sw_cpu_rw_intr2_mask___mpu_7___lsb 7
+#define reg_iop_sw_cpu_rw_intr2_mask___mpu_7___width 1
+#define reg_iop_sw_cpu_rw_intr2_mask___mpu_7___bit 7
+#define reg_iop_sw_cpu_rw_intr2_mask___spu0_0___lsb 8
+#define reg_iop_sw_cpu_rw_intr2_mask___spu0_0___width 1
+#define reg_iop_sw_cpu_rw_intr2_mask___spu0_0___bit 8
+#define reg_iop_sw_cpu_rw_intr2_mask___spu0_1___lsb 9
+#define reg_iop_sw_cpu_rw_intr2_mask___spu0_1___width 1
+#define reg_iop_sw_cpu_rw_intr2_mask___spu0_1___bit 9
+#define reg_iop_sw_cpu_rw_intr2_mask___spu0_2___lsb 10
+#define reg_iop_sw_cpu_rw_intr2_mask___spu0_2___width 1
+#define reg_iop_sw_cpu_rw_intr2_mask___spu0_2___bit 10
+#define reg_iop_sw_cpu_rw_intr2_mask___spu0_3___lsb 11
+#define reg_iop_sw_cpu_rw_intr2_mask___spu0_3___width 1
+#define reg_iop_sw_cpu_rw_intr2_mask___spu0_3___bit 11
+#define reg_iop_sw_cpu_rw_intr2_mask___spu0_4___lsb 12
+#define reg_iop_sw_cpu_rw_intr2_mask___spu0_4___width 1
+#define reg_iop_sw_cpu_rw_intr2_mask___spu0_4___bit 12
+#define reg_iop_sw_cpu_rw_intr2_mask___spu0_5___lsb 13
+#define reg_iop_sw_cpu_rw_intr2_mask___spu0_5___width 1
+#define reg_iop_sw_cpu_rw_intr2_mask___spu0_5___bit 13
+#define reg_iop_sw_cpu_rw_intr2_mask___spu0_6___lsb 14
+#define reg_iop_sw_cpu_rw_intr2_mask___spu0_6___width 1
+#define reg_iop_sw_cpu_rw_intr2_mask___spu0_6___bit 14
+#define reg_iop_sw_cpu_rw_intr2_mask___spu0_7___lsb 15
+#define reg_iop_sw_cpu_rw_intr2_mask___spu0_7___width 1
+#define reg_iop_sw_cpu_rw_intr2_mask___spu0_7___bit 15
+#define reg_iop_sw_cpu_rw_intr2_mask___dmc_in0___lsb 16
+#define reg_iop_sw_cpu_rw_intr2_mask___dmc_in0___width 1
+#define reg_iop_sw_cpu_rw_intr2_mask___dmc_in0___bit 16
+#define reg_iop_sw_cpu_rw_intr2_mask___dmc_out0___lsb 17
+#define reg_iop_sw_cpu_rw_intr2_mask___dmc_out0___width 1
+#define reg_iop_sw_cpu_rw_intr2_mask___dmc_out0___bit 17
+#define reg_iop_sw_cpu_rw_intr2_mask___fifo_in0___lsb 18
+#define reg_iop_sw_cpu_rw_intr2_mask___fifo_in0___width 1
+#define reg_iop_sw_cpu_rw_intr2_mask___fifo_in0___bit 18
+#define reg_iop_sw_cpu_rw_intr2_mask___fifo_out0___lsb 19
+#define reg_iop_sw_cpu_rw_intr2_mask___fifo_out0___width 1
+#define reg_iop_sw_cpu_rw_intr2_mask___fifo_out0___bit 19
+#define reg_iop_sw_cpu_rw_intr2_mask___fifo_in0_extra___lsb 20
+#define reg_iop_sw_cpu_rw_intr2_mask___fifo_in0_extra___width 1
+#define reg_iop_sw_cpu_rw_intr2_mask___fifo_in0_extra___bit 20
+#define reg_iop_sw_cpu_rw_intr2_mask___fifo_out0_extra___lsb 21
+#define reg_iop_sw_cpu_rw_intr2_mask___fifo_out0_extra___width 1
+#define reg_iop_sw_cpu_rw_intr2_mask___fifo_out0_extra___bit 21
+#define reg_iop_sw_cpu_rw_intr2_mask___trigger_grp0___lsb 22
+#define reg_iop_sw_cpu_rw_intr2_mask___trigger_grp0___width 1
+#define reg_iop_sw_cpu_rw_intr2_mask___trigger_grp0___bit 22
+#define reg_iop_sw_cpu_rw_intr2_mask___trigger_grp1___lsb 23
+#define reg_iop_sw_cpu_rw_intr2_mask___trigger_grp1___width 1
+#define reg_iop_sw_cpu_rw_intr2_mask___trigger_grp1___bit 23
+#define reg_iop_sw_cpu_rw_intr2_mask___trigger_grp2___lsb 24
+#define reg_iop_sw_cpu_rw_intr2_mask___trigger_grp2___width 1
+#define reg_iop_sw_cpu_rw_intr2_mask___trigger_grp2___bit 24
+#define reg_iop_sw_cpu_rw_intr2_mask___trigger_grp3___lsb 25
+#define reg_iop_sw_cpu_rw_intr2_mask___trigger_grp3___width 1
+#define reg_iop_sw_cpu_rw_intr2_mask___trigger_grp3___bit 25
+#define reg_iop_sw_cpu_rw_intr2_mask___trigger_grp4___lsb 26
+#define reg_iop_sw_cpu_rw_intr2_mask___trigger_grp4___width 1
+#define reg_iop_sw_cpu_rw_intr2_mask___trigger_grp4___bit 26
+#define reg_iop_sw_cpu_rw_intr2_mask___trigger_grp5___lsb 27
+#define reg_iop_sw_cpu_rw_intr2_mask___trigger_grp5___width 1
+#define reg_iop_sw_cpu_rw_intr2_mask___trigger_grp5___bit 27
+#define reg_iop_sw_cpu_rw_intr2_mask___trigger_grp6___lsb 28
+#define reg_iop_sw_cpu_rw_intr2_mask___trigger_grp6___width 1
+#define reg_iop_sw_cpu_rw_intr2_mask___trigger_grp6___bit 28
+#define reg_iop_sw_cpu_rw_intr2_mask___trigger_grp7___lsb 29
+#define reg_iop_sw_cpu_rw_intr2_mask___trigger_grp7___width 1
+#define reg_iop_sw_cpu_rw_intr2_mask___trigger_grp7___bit 29
+#define reg_iop_sw_cpu_rw_intr2_mask___timer_grp0___lsb 30
+#define reg_iop_sw_cpu_rw_intr2_mask___timer_grp0___width 1
+#define reg_iop_sw_cpu_rw_intr2_mask___timer_grp0___bit 30
+#define reg_iop_sw_cpu_rw_intr2_mask___timer_grp1___lsb 31
+#define reg_iop_sw_cpu_rw_intr2_mask___timer_grp1___width 1
+#define reg_iop_sw_cpu_rw_intr2_mask___timer_grp1___bit 31
+#define reg_iop_sw_cpu_rw_intr2_mask_offset 116
+
+/* Register rw_ack_intr2, scope iop_sw_cpu, type rw */
+#define reg_iop_sw_cpu_rw_ack_intr2___mpu_0___lsb 0
+#define reg_iop_sw_cpu_rw_ack_intr2___mpu_0___width 1
+#define reg_iop_sw_cpu_rw_ack_intr2___mpu_0___bit 0
+#define reg_iop_sw_cpu_rw_ack_intr2___mpu_1___lsb 1
+#define reg_iop_sw_cpu_rw_ack_intr2___mpu_1___width 1
+#define reg_iop_sw_cpu_rw_ack_intr2___mpu_1___bit 1
+#define reg_iop_sw_cpu_rw_ack_intr2___mpu_2___lsb 2
+#define reg_iop_sw_cpu_rw_ack_intr2___mpu_2___width 1
+#define reg_iop_sw_cpu_rw_ack_intr2___mpu_2___bit 2
+#define reg_iop_sw_cpu_rw_ack_intr2___mpu_3___lsb 3
+#define reg_iop_sw_cpu_rw_ack_intr2___mpu_3___width 1
+#define reg_iop_sw_cpu_rw_ack_intr2___mpu_3___bit 3
+#define reg_iop_sw_cpu_rw_ack_intr2___mpu_4___lsb 4
+#define reg_iop_sw_cpu_rw_ack_intr2___mpu_4___width 1
+#define reg_iop_sw_cpu_rw_ack_intr2___mpu_4___bit 4
+#define reg_iop_sw_cpu_rw_ack_intr2___mpu_5___lsb 5
+#define reg_iop_sw_cpu_rw_ack_intr2___mpu_5___width 1
+#define reg_iop_sw_cpu_rw_ack_intr2___mpu_5___bit 5
+#define reg_iop_sw_cpu_rw_ack_intr2___mpu_6___lsb 6
+#define reg_iop_sw_cpu_rw_ack_intr2___mpu_6___width 1
+#define reg_iop_sw_cpu_rw_ack_intr2___mpu_6___bit 6
+#define reg_iop_sw_cpu_rw_ack_intr2___mpu_7___lsb 7
+#define reg_iop_sw_cpu_rw_ack_intr2___mpu_7___width 1
+#define reg_iop_sw_cpu_rw_ack_intr2___mpu_7___bit 7
+#define reg_iop_sw_cpu_rw_ack_intr2___spu0_0___lsb 8
+#define reg_iop_sw_cpu_rw_ack_intr2___spu0_0___width 1
+#define reg_iop_sw_cpu_rw_ack_intr2___spu0_0___bit 8
+#define reg_iop_sw_cpu_rw_ack_intr2___spu0_1___lsb 9
+#define reg_iop_sw_cpu_rw_ack_intr2___spu0_1___width 1
+#define reg_iop_sw_cpu_rw_ack_intr2___spu0_1___bit 9
+#define reg_iop_sw_cpu_rw_ack_intr2___spu0_2___lsb 10
+#define reg_iop_sw_cpu_rw_ack_intr2___spu0_2___width 1
+#define reg_iop_sw_cpu_rw_ack_intr2___spu0_2___bit 10
+#define reg_iop_sw_cpu_rw_ack_intr2___spu0_3___lsb 11
+#define reg_iop_sw_cpu_rw_ack_intr2___spu0_3___width 1
+#define reg_iop_sw_cpu_rw_ack_intr2___spu0_3___bit 11
+#define reg_iop_sw_cpu_rw_ack_intr2___spu0_4___lsb 12
+#define reg_iop_sw_cpu_rw_ack_intr2___spu0_4___width 1
+#define reg_iop_sw_cpu_rw_ack_intr2___spu0_4___bit 12
+#define reg_iop_sw_cpu_rw_ack_intr2___spu0_5___lsb 13
+#define reg_iop_sw_cpu_rw_ack_intr2___spu0_5___width 1
+#define reg_iop_sw_cpu_rw_ack_intr2___spu0_5___bit 13
+#define reg_iop_sw_cpu_rw_ack_intr2___spu0_6___lsb 14
+#define reg_iop_sw_cpu_rw_ack_intr2___spu0_6___width 1
+#define reg_iop_sw_cpu_rw_ack_intr2___spu0_6___bit 14
+#define reg_iop_sw_cpu_rw_ack_intr2___spu0_7___lsb 15
+#define reg_iop_sw_cpu_rw_ack_intr2___spu0_7___width 1
+#define reg_iop_sw_cpu_rw_ack_intr2___spu0_7___bit 15
+#define reg_iop_sw_cpu_rw_ack_intr2_offset 120
+
+/* Register r_intr2, scope iop_sw_cpu, type r */
+#define reg_iop_sw_cpu_r_intr2___mpu_0___lsb 0
+#define reg_iop_sw_cpu_r_intr2___mpu_0___width 1
+#define reg_iop_sw_cpu_r_intr2___mpu_0___bit 0
+#define reg_iop_sw_cpu_r_intr2___mpu_1___lsb 1
+#define reg_iop_sw_cpu_r_intr2___mpu_1___width 1
+#define reg_iop_sw_cpu_r_intr2___mpu_1___bit 1
+#define reg_iop_sw_cpu_r_intr2___mpu_2___lsb 2
+#define reg_iop_sw_cpu_r_intr2___mpu_2___width 1
+#define reg_iop_sw_cpu_r_intr2___mpu_2___bit 2
+#define reg_iop_sw_cpu_r_intr2___mpu_3___lsb 3
+#define reg_iop_sw_cpu_r_intr2___mpu_3___width 1
+#define reg_iop_sw_cpu_r_intr2___mpu_3___bit 3
+#define reg_iop_sw_cpu_r_intr2___mpu_4___lsb 4
+#define reg_iop_sw_cpu_r_intr2___mpu_4___width 1
+#define reg_iop_sw_cpu_r_intr2___mpu_4___bit 4
+#define reg_iop_sw_cpu_r_intr2___mpu_5___lsb 5
+#define reg_iop_sw_cpu_r_intr2___mpu_5___width 1
+#define reg_iop_sw_cpu_r_intr2___mpu_5___bit 5
+#define reg_iop_sw_cpu_r_intr2___mpu_6___lsb 6
+#define reg_iop_sw_cpu_r_intr2___mpu_6___width 1
+#define reg_iop_sw_cpu_r_intr2___mpu_6___bit 6
+#define reg_iop_sw_cpu_r_intr2___mpu_7___lsb 7
+#define reg_iop_sw_cpu_r_intr2___mpu_7___width 1
+#define reg_iop_sw_cpu_r_intr2___mpu_7___bit 7
+#define reg_iop_sw_cpu_r_intr2___spu0_0___lsb 8
+#define reg_iop_sw_cpu_r_intr2___spu0_0___width 1
+#define reg_iop_sw_cpu_r_intr2___spu0_0___bit 8
+#define reg_iop_sw_cpu_r_intr2___spu0_1___lsb 9
+#define reg_iop_sw_cpu_r_intr2___spu0_1___width 1
+#define reg_iop_sw_cpu_r_intr2___spu0_1___bit 9
+#define reg_iop_sw_cpu_r_intr2___spu0_2___lsb 10
+#define reg_iop_sw_cpu_r_intr2___spu0_2___width 1
+#define reg_iop_sw_cpu_r_intr2___spu0_2___bit 10
+#define reg_iop_sw_cpu_r_intr2___spu0_3___lsb 11
+#define reg_iop_sw_cpu_r_intr2___spu0_3___width 1
+#define reg_iop_sw_cpu_r_intr2___spu0_3___bit 11
+#define reg_iop_sw_cpu_r_intr2___spu0_4___lsb 12
+#define reg_iop_sw_cpu_r_intr2___spu0_4___width 1
+#define reg_iop_sw_cpu_r_intr2___spu0_4___bit 12
+#define reg_iop_sw_cpu_r_intr2___spu0_5___lsb 13
+#define reg_iop_sw_cpu_r_intr2___spu0_5___width 1
+#define reg_iop_sw_cpu_r_intr2___spu0_5___bit 13
+#define reg_iop_sw_cpu_r_intr2___spu0_6___lsb 14
+#define reg_iop_sw_cpu_r_intr2___spu0_6___width 1
+#define reg_iop_sw_cpu_r_intr2___spu0_6___bit 14
+#define reg_iop_sw_cpu_r_intr2___spu0_7___lsb 15
+#define reg_iop_sw_cpu_r_intr2___spu0_7___width 1
+#define reg_iop_sw_cpu_r_intr2___spu0_7___bit 15
+#define reg_iop_sw_cpu_r_intr2___dmc_in0___lsb 16
+#define reg_iop_sw_cpu_r_intr2___dmc_in0___width 1
+#define reg_iop_sw_cpu_r_intr2___dmc_in0___bit 16
+#define reg_iop_sw_cpu_r_intr2___dmc_out0___lsb 17
+#define reg_iop_sw_cpu_r_intr2___dmc_out0___width 1
+#define reg_iop_sw_cpu_r_intr2___dmc_out0___bit 17
+#define reg_iop_sw_cpu_r_intr2___fifo_in0___lsb 18
+#define reg_iop_sw_cpu_r_intr2___fifo_in0___width 1
+#define reg_iop_sw_cpu_r_intr2___fifo_in0___bit 18
+#define reg_iop_sw_cpu_r_intr2___fifo_out0___lsb 19
+#define reg_iop_sw_cpu_r_intr2___fifo_out0___width 1
+#define reg_iop_sw_cpu_r_intr2___fifo_out0___bit 19
+#define reg_iop_sw_cpu_r_intr2___fifo_in0_extra___lsb 20
+#define reg_iop_sw_cpu_r_intr2___fifo_in0_extra___width 1
+#define reg_iop_sw_cpu_r_intr2___fifo_in0_extra___bit 20
+#define reg_iop_sw_cpu_r_intr2___fifo_out0_extra___lsb 21
+#define reg_iop_sw_cpu_r_intr2___fifo_out0_extra___width 1
+#define reg_iop_sw_cpu_r_intr2___fifo_out0_extra___bit 21
+#define reg_iop_sw_cpu_r_intr2___trigger_grp0___lsb 22
+#define reg_iop_sw_cpu_r_intr2___trigger_grp0___width 1
+#define reg_iop_sw_cpu_r_intr2___trigger_grp0___bit 22
+#define reg_iop_sw_cpu_r_intr2___trigger_grp1___lsb 23
+#define reg_iop_sw_cpu_r_intr2___trigger_grp1___width 1
+#define reg_iop_sw_cpu_r_intr2___trigger_grp1___bit 23
+#define reg_iop_sw_cpu_r_intr2___trigger_grp2___lsb 24
+#define reg_iop_sw_cpu_r_intr2___trigger_grp2___width 1
+#define reg_iop_sw_cpu_r_intr2___trigger_grp2___bit 24
+#define reg_iop_sw_cpu_r_intr2___trigger_grp3___lsb 25
+#define reg_iop_sw_cpu_r_intr2___trigger_grp3___width 1
+#define reg_iop_sw_cpu_r_intr2___trigger_grp3___bit 25
+#define reg_iop_sw_cpu_r_intr2___trigger_grp4___lsb 26
+#define reg_iop_sw_cpu_r_intr2___trigger_grp4___width 1
+#define reg_iop_sw_cpu_r_intr2___trigger_grp4___bit 26
+#define reg_iop_sw_cpu_r_intr2___trigger_grp5___lsb 27
+#define reg_iop_sw_cpu_r_intr2___trigger_grp5___width 1
+#define reg_iop_sw_cpu_r_intr2___trigger_grp5___bit 27
+#define reg_iop_sw_cpu_r_intr2___trigger_grp6___lsb 28
+#define reg_iop_sw_cpu_r_intr2___trigger_grp6___width 1
+#define reg_iop_sw_cpu_r_intr2___trigger_grp6___bit 28
+#define reg_iop_sw_cpu_r_intr2___trigger_grp7___lsb 29
+#define reg_iop_sw_cpu_r_intr2___trigger_grp7___width 1
+#define reg_iop_sw_cpu_r_intr2___trigger_grp7___bit 29
+#define reg_iop_sw_cpu_r_intr2___timer_grp0___lsb 30
+#define reg_iop_sw_cpu_r_intr2___timer_grp0___width 1
+#define reg_iop_sw_cpu_r_intr2___timer_grp0___bit 30
+#define reg_iop_sw_cpu_r_intr2___timer_grp1___lsb 31
+#define reg_iop_sw_cpu_r_intr2___timer_grp1___width 1
+#define reg_iop_sw_cpu_r_intr2___timer_grp1___bit 31
+#define reg_iop_sw_cpu_r_intr2_offset 124
+
+/* Register r_masked_intr2, scope iop_sw_cpu, type r */
+#define reg_iop_sw_cpu_r_masked_intr2___mpu_0___lsb 0
+#define reg_iop_sw_cpu_r_masked_intr2___mpu_0___width 1
+#define reg_iop_sw_cpu_r_masked_intr2___mpu_0___bit 0
+#define reg_iop_sw_cpu_r_masked_intr2___mpu_1___lsb 1
+#define reg_iop_sw_cpu_r_masked_intr2___mpu_1___width 1
+#define reg_iop_sw_cpu_r_masked_intr2___mpu_1___bit 1
+#define reg_iop_sw_cpu_r_masked_intr2___mpu_2___lsb 2
+#define reg_iop_sw_cpu_r_masked_intr2___mpu_2___width 1
+#define reg_iop_sw_cpu_r_masked_intr2___mpu_2___bit 2
+#define reg_iop_sw_cpu_r_masked_intr2___mpu_3___lsb 3
+#define reg_iop_sw_cpu_r_masked_intr2___mpu_3___width 1
+#define reg_iop_sw_cpu_r_masked_intr2___mpu_3___bit 3
+#define reg_iop_sw_cpu_r_masked_intr2___mpu_4___lsb 4
+#define reg_iop_sw_cpu_r_masked_intr2___mpu_4___width 1
+#define reg_iop_sw_cpu_r_masked_intr2___mpu_4___bit 4
+#define reg_iop_sw_cpu_r_masked_intr2___mpu_5___lsb 5
+#define reg_iop_sw_cpu_r_masked_intr2___mpu_5___width 1
+#define reg_iop_sw_cpu_r_masked_intr2___mpu_5___bit 5
+#define reg_iop_sw_cpu_r_masked_intr2___mpu_6___lsb 6
+#define reg_iop_sw_cpu_r_masked_intr2___mpu_6___width 1
+#define reg_iop_sw_cpu_r_masked_intr2___mpu_6___bit 6
+#define reg_iop_sw_cpu_r_masked_intr2___mpu_7___lsb 7
+#define reg_iop_sw_cpu_r_masked_intr2___mpu_7___width 1
+#define reg_iop_sw_cpu_r_masked_intr2___mpu_7___bit 7
+#define reg_iop_sw_cpu_r_masked_intr2___spu0_0___lsb 8
+#define reg_iop_sw_cpu_r_masked_intr2___spu0_0___width 1
+#define reg_iop_sw_cpu_r_masked_intr2___spu0_0___bit 8
+#define reg_iop_sw_cpu_r_masked_intr2___spu0_1___lsb 9
+#define reg_iop_sw_cpu_r_masked_intr2___spu0_1___width 1
+#define reg_iop_sw_cpu_r_masked_intr2___spu0_1___bit 9
+#define reg_iop_sw_cpu_r_masked_intr2___spu0_2___lsb 10
+#define reg_iop_sw_cpu_r_masked_intr2___spu0_2___width 1
+#define reg_iop_sw_cpu_r_masked_intr2___spu0_2___bit 10
+#define reg_iop_sw_cpu_r_masked_intr2___spu0_3___lsb 11
+#define reg_iop_sw_cpu_r_masked_intr2___spu0_3___width 1
+#define reg_iop_sw_cpu_r_masked_intr2___spu0_3___bit 11
+#define reg_iop_sw_cpu_r_masked_intr2___spu0_4___lsb 12
+#define reg_iop_sw_cpu_r_masked_intr2___spu0_4___width 1
+#define reg_iop_sw_cpu_r_masked_intr2___spu0_4___bit 12
+#define reg_iop_sw_cpu_r_masked_intr2___spu0_5___lsb 13
+#define reg_iop_sw_cpu_r_masked_intr2___spu0_5___width 1
+#define reg_iop_sw_cpu_r_masked_intr2___spu0_5___bit 13
+#define reg_iop_sw_cpu_r_masked_intr2___spu0_6___lsb 14
+#define reg_iop_sw_cpu_r_masked_intr2___spu0_6___width 1
+#define reg_iop_sw_cpu_r_masked_intr2___spu0_6___bit 14
+#define reg_iop_sw_cpu_r_masked_intr2___spu0_7___lsb 15
+#define reg_iop_sw_cpu_r_masked_intr2___spu0_7___width 1
+#define reg_iop_sw_cpu_r_masked_intr2___spu0_7___bit 15
+#define reg_iop_sw_cpu_r_masked_intr2___dmc_in0___lsb 16
+#define reg_iop_sw_cpu_r_masked_intr2___dmc_in0___width 1
+#define reg_iop_sw_cpu_r_masked_intr2___dmc_in0___bit 16
+#define reg_iop_sw_cpu_r_masked_intr2___dmc_out0___lsb 17
+#define reg_iop_sw_cpu_r_masked_intr2___dmc_out0___width 1
+#define reg_iop_sw_cpu_r_masked_intr2___dmc_out0___bit 17
+#define reg_iop_sw_cpu_r_masked_intr2___fifo_in0___lsb 18
+#define reg_iop_sw_cpu_r_masked_intr2___fifo_in0___width 1
+#define reg_iop_sw_cpu_r_masked_intr2___fifo_in0___bit 18
+#define reg_iop_sw_cpu_r_masked_intr2___fifo_out0___lsb 19
+#define reg_iop_sw_cpu_r_masked_intr2___fifo_out0___width 1
+#define reg_iop_sw_cpu_r_masked_intr2___fifo_out0___bit 19
+#define reg_iop_sw_cpu_r_masked_intr2___fifo_in0_extra___lsb 20
+#define reg_iop_sw_cpu_r_masked_intr2___fifo_in0_extra___width 1
+#define reg_iop_sw_cpu_r_masked_intr2___fifo_in0_extra___bit 20
+#define reg_iop_sw_cpu_r_masked_intr2___fifo_out0_extra___lsb 21
+#define reg_iop_sw_cpu_r_masked_intr2___fifo_out0_extra___width 1
+#define reg_iop_sw_cpu_r_masked_intr2___fifo_out0_extra___bit 21
+#define reg_iop_sw_cpu_r_masked_intr2___trigger_grp0___lsb 22
+#define reg_iop_sw_cpu_r_masked_intr2___trigger_grp0___width 1
+#define reg_iop_sw_cpu_r_masked_intr2___trigger_grp0___bit 22
+#define reg_iop_sw_cpu_r_masked_intr2___trigger_grp1___lsb 23
+#define reg_iop_sw_cpu_r_masked_intr2___trigger_grp1___width 1
+#define reg_iop_sw_cpu_r_masked_intr2___trigger_grp1___bit 23
+#define reg_iop_sw_cpu_r_masked_intr2___trigger_grp2___lsb 24
+#define reg_iop_sw_cpu_r_masked_intr2___trigger_grp2___width 1
+#define reg_iop_sw_cpu_r_masked_intr2___trigger_grp2___bit 24
+#define reg_iop_sw_cpu_r_masked_intr2___trigger_grp3___lsb 25
+#define reg_iop_sw_cpu_r_masked_intr2___trigger_grp3___width 1
+#define reg_iop_sw_cpu_r_masked_intr2___trigger_grp3___bit 25
+#define reg_iop_sw_cpu_r_masked_intr2___trigger_grp4___lsb 26
+#define reg_iop_sw_cpu_r_masked_intr2___trigger_grp4___width 1
+#define reg_iop_sw_cpu_r_masked_intr2___trigger_grp4___bit 26
+#define reg_iop_sw_cpu_r_masked_intr2___trigger_grp5___lsb 27
+#define reg_iop_sw_cpu_r_masked_intr2___trigger_grp5___width 1
+#define reg_iop_sw_cpu_r_masked_intr2___trigger_grp5___bit 27
+#define reg_iop_sw_cpu_r_masked_intr2___trigger_grp6___lsb 28
+#define reg_iop_sw_cpu_r_masked_intr2___trigger_grp6___width 1
+#define reg_iop_sw_cpu_r_masked_intr2___trigger_grp6___bit 28
+#define reg_iop_sw_cpu_r_masked_intr2___trigger_grp7___lsb 29
+#define reg_iop_sw_cpu_r_masked_intr2___trigger_grp7___width 1
+#define reg_iop_sw_cpu_r_masked_intr2___trigger_grp7___bit 29
+#define reg_iop_sw_cpu_r_masked_intr2___timer_grp0___lsb 30
+#define reg_iop_sw_cpu_r_masked_intr2___timer_grp0___width 1
+#define reg_iop_sw_cpu_r_masked_intr2___timer_grp0___bit 30
+#define reg_iop_sw_cpu_r_masked_intr2___timer_grp1___lsb 31
+#define reg_iop_sw_cpu_r_masked_intr2___timer_grp1___width 1
+#define reg_iop_sw_cpu_r_masked_intr2___timer_grp1___bit 31
+#define reg_iop_sw_cpu_r_masked_intr2_offset 128
+
+/* Register rw_intr3_mask, scope iop_sw_cpu, type rw */
+#define reg_iop_sw_cpu_rw_intr3_mask___mpu_16___lsb 0
+#define reg_iop_sw_cpu_rw_intr3_mask___mpu_16___width 1
+#define reg_iop_sw_cpu_rw_intr3_mask___mpu_16___bit 0
+#define reg_iop_sw_cpu_rw_intr3_mask___mpu_17___lsb 1
+#define reg_iop_sw_cpu_rw_intr3_mask___mpu_17___width 1
+#define reg_iop_sw_cpu_rw_intr3_mask___mpu_17___bit 1
+#define reg_iop_sw_cpu_rw_intr3_mask___mpu_18___lsb 2
+#define reg_iop_sw_cpu_rw_intr3_mask___mpu_18___width 1
+#define reg_iop_sw_cpu_rw_intr3_mask___mpu_18___bit 2
+#define reg_iop_sw_cpu_rw_intr3_mask___mpu_19___lsb 3
+#define reg_iop_sw_cpu_rw_intr3_mask___mpu_19___width 1
+#define reg_iop_sw_cpu_rw_intr3_mask___mpu_19___bit 3
+#define reg_iop_sw_cpu_rw_intr3_mask___mpu_20___lsb 4
+#define reg_iop_sw_cpu_rw_intr3_mask___mpu_20___width 1
+#define reg_iop_sw_cpu_rw_intr3_mask___mpu_20___bit 4
+#define reg_iop_sw_cpu_rw_intr3_mask___mpu_21___lsb 5
+#define reg_iop_sw_cpu_rw_intr3_mask___mpu_21___width 1
+#define reg_iop_sw_cpu_rw_intr3_mask___mpu_21___bit 5
+#define reg_iop_sw_cpu_rw_intr3_mask___mpu_22___lsb 6
+#define reg_iop_sw_cpu_rw_intr3_mask___mpu_22___width 1
+#define reg_iop_sw_cpu_rw_intr3_mask___mpu_22___bit 6
+#define reg_iop_sw_cpu_rw_intr3_mask___mpu_23___lsb 7
+#define reg_iop_sw_cpu_rw_intr3_mask___mpu_23___width 1
+#define reg_iop_sw_cpu_rw_intr3_mask___mpu_23___bit 7
+#define reg_iop_sw_cpu_rw_intr3_mask___spu1_0___lsb 8
+#define reg_iop_sw_cpu_rw_intr3_mask___spu1_0___width 1
+#define reg_iop_sw_cpu_rw_intr3_mask___spu1_0___bit 8
+#define reg_iop_sw_cpu_rw_intr3_mask___spu1_1___lsb 9
+#define reg_iop_sw_cpu_rw_intr3_mask___spu1_1___width 1
+#define reg_iop_sw_cpu_rw_intr3_mask___spu1_1___bit 9
+#define reg_iop_sw_cpu_rw_intr3_mask___spu1_2___lsb 10
+#define reg_iop_sw_cpu_rw_intr3_mask___spu1_2___width 1
+#define reg_iop_sw_cpu_rw_intr3_mask___spu1_2___bit 10
+#define reg_iop_sw_cpu_rw_intr3_mask___spu1_3___lsb 11
+#define reg_iop_sw_cpu_rw_intr3_mask___spu1_3___width 1
+#define reg_iop_sw_cpu_rw_intr3_mask___spu1_3___bit 11
+#define reg_iop_sw_cpu_rw_intr3_mask___spu1_4___lsb 12
+#define reg_iop_sw_cpu_rw_intr3_mask___spu1_4___width 1
+#define reg_iop_sw_cpu_rw_intr3_mask___spu1_4___bit 12
+#define reg_iop_sw_cpu_rw_intr3_mask___spu1_5___lsb 13
+#define reg_iop_sw_cpu_rw_intr3_mask___spu1_5___width 1
+#define reg_iop_sw_cpu_rw_intr3_mask___spu1_5___bit 13
+#define reg_iop_sw_cpu_rw_intr3_mask___spu1_6___lsb 14
+#define reg_iop_sw_cpu_rw_intr3_mask___spu1_6___width 1
+#define reg_iop_sw_cpu_rw_intr3_mask___spu1_6___bit 14
+#define reg_iop_sw_cpu_rw_intr3_mask___spu1_7___lsb 15
+#define reg_iop_sw_cpu_rw_intr3_mask___spu1_7___width 1
+#define reg_iop_sw_cpu_rw_intr3_mask___spu1_7___bit 15
+#define reg_iop_sw_cpu_rw_intr3_mask___dmc_in1___lsb 16
+#define reg_iop_sw_cpu_rw_intr3_mask___dmc_in1___width 1
+#define reg_iop_sw_cpu_rw_intr3_mask___dmc_in1___bit 16
+#define reg_iop_sw_cpu_rw_intr3_mask___dmc_out1___lsb 17
+#define reg_iop_sw_cpu_rw_intr3_mask___dmc_out1___width 1
+#define reg_iop_sw_cpu_rw_intr3_mask___dmc_out1___bit 17
+#define reg_iop_sw_cpu_rw_intr3_mask___fifo_in1___lsb 18
+#define reg_iop_sw_cpu_rw_intr3_mask___fifo_in1___width 1
+#define reg_iop_sw_cpu_rw_intr3_mask___fifo_in1___bit 18
+#define reg_iop_sw_cpu_rw_intr3_mask___fifo_out1___lsb 19
+#define reg_iop_sw_cpu_rw_intr3_mask___fifo_out1___width 1
+#define reg_iop_sw_cpu_rw_intr3_mask___fifo_out1___bit 19
+#define reg_iop_sw_cpu_rw_intr3_mask___fifo_in1_extra___lsb 20
+#define reg_iop_sw_cpu_rw_intr3_mask___fifo_in1_extra___width 1
+#define reg_iop_sw_cpu_rw_intr3_mask___fifo_in1_extra___bit 20
+#define reg_iop_sw_cpu_rw_intr3_mask___fifo_out1_extra___lsb 21
+#define reg_iop_sw_cpu_rw_intr3_mask___fifo_out1_extra___width 1
+#define reg_iop_sw_cpu_rw_intr3_mask___fifo_out1_extra___bit 21
+#define reg_iop_sw_cpu_rw_intr3_mask___trigger_grp0___lsb 22
+#define reg_iop_sw_cpu_rw_intr3_mask___trigger_grp0___width 1
+#define reg_iop_sw_cpu_rw_intr3_mask___trigger_grp0___bit 22
+#define reg_iop_sw_cpu_rw_intr3_mask___trigger_grp1___lsb 23
+#define reg_iop_sw_cpu_rw_intr3_mask___trigger_grp1___width 1
+#define reg_iop_sw_cpu_rw_intr3_mask___trigger_grp1___bit 23
+#define reg_iop_sw_cpu_rw_intr3_mask___trigger_grp2___lsb 24
+#define reg_iop_sw_cpu_rw_intr3_mask___trigger_grp2___width 1
+#define reg_iop_sw_cpu_rw_intr3_mask___trigger_grp2___bit 24
+#define reg_iop_sw_cpu_rw_intr3_mask___trigger_grp3___lsb 25
+#define reg_iop_sw_cpu_rw_intr3_mask___trigger_grp3___width 1
+#define reg_iop_sw_cpu_rw_intr3_mask___trigger_grp3___bit 25
+#define reg_iop_sw_cpu_rw_intr3_mask___trigger_grp4___lsb 26
+#define reg_iop_sw_cpu_rw_intr3_mask___trigger_grp4___width 1
+#define reg_iop_sw_cpu_rw_intr3_mask___trigger_grp4___bit 26
+#define reg_iop_sw_cpu_rw_intr3_mask___trigger_grp5___lsb 27
+#define reg_iop_sw_cpu_rw_intr3_mask___trigger_grp5___width 1
+#define reg_iop_sw_cpu_rw_intr3_mask___trigger_grp5___bit 27
+#define reg_iop_sw_cpu_rw_intr3_mask___trigger_grp6___lsb 28
+#define reg_iop_sw_cpu_rw_intr3_mask___trigger_grp6___width 1
+#define reg_iop_sw_cpu_rw_intr3_mask___trigger_grp6___bit 28
+#define reg_iop_sw_cpu_rw_intr3_mask___trigger_grp7___lsb 29
+#define reg_iop_sw_cpu_rw_intr3_mask___trigger_grp7___width 1
+#define reg_iop_sw_cpu_rw_intr3_mask___trigger_grp7___bit 29
+#define reg_iop_sw_cpu_rw_intr3_mask___timer_grp2___lsb 30
+#define reg_iop_sw_cpu_rw_intr3_mask___timer_grp2___width 1
+#define reg_iop_sw_cpu_rw_intr3_mask___timer_grp2___bit 30
+#define reg_iop_sw_cpu_rw_intr3_mask___timer_grp3___lsb 31
+#define reg_iop_sw_cpu_rw_intr3_mask___timer_grp3___width 1
+#define reg_iop_sw_cpu_rw_intr3_mask___timer_grp3___bit 31
+#define reg_iop_sw_cpu_rw_intr3_mask_offset 132
+
+/* Register rw_ack_intr3, scope iop_sw_cpu, type rw */
+#define reg_iop_sw_cpu_rw_ack_intr3___mpu_16___lsb 0
+#define reg_iop_sw_cpu_rw_ack_intr3___mpu_16___width 1
+#define reg_iop_sw_cpu_rw_ack_intr3___mpu_16___bit 0
+#define reg_iop_sw_cpu_rw_ack_intr3___mpu_17___lsb 1
+#define reg_iop_sw_cpu_rw_ack_intr3___mpu_17___width 1
+#define reg_iop_sw_cpu_rw_ack_intr3___mpu_17___bit 1
+#define reg_iop_sw_cpu_rw_ack_intr3___mpu_18___lsb 2
+#define reg_iop_sw_cpu_rw_ack_intr3___mpu_18___width 1
+#define reg_iop_sw_cpu_rw_ack_intr3___mpu_18___bit 2
+#define reg_iop_sw_cpu_rw_ack_intr3___mpu_19___lsb 3
+#define reg_iop_sw_cpu_rw_ack_intr3___mpu_19___width 1
+#define reg_iop_sw_cpu_rw_ack_intr3___mpu_19___bit 3
+#define reg_iop_sw_cpu_rw_ack_intr3___mpu_20___lsb 4
+#define reg_iop_sw_cpu_rw_ack_intr3___mpu_20___width 1
+#define reg_iop_sw_cpu_rw_ack_intr3___mpu_20___bit 4
+#define reg_iop_sw_cpu_rw_ack_intr3___mpu_21___lsb 5
+#define reg_iop_sw_cpu_rw_ack_intr3___mpu_21___width 1
+#define reg_iop_sw_cpu_rw_ack_intr3___mpu_21___bit 5
+#define reg_iop_sw_cpu_rw_ack_intr3___mpu_22___lsb 6
+#define reg_iop_sw_cpu_rw_ack_intr3___mpu_22___width 1
+#define reg_iop_sw_cpu_rw_ack_intr3___mpu_22___bit 6
+#define reg_iop_sw_cpu_rw_ack_intr3___mpu_23___lsb 7
+#define reg_iop_sw_cpu_rw_ack_intr3___mpu_23___width 1
+#define reg_iop_sw_cpu_rw_ack_intr3___mpu_23___bit 7
+#define reg_iop_sw_cpu_rw_ack_intr3___spu1_0___lsb 8
+#define reg_iop_sw_cpu_rw_ack_intr3___spu1_0___width 1
+#define reg_iop_sw_cpu_rw_ack_intr3___spu1_0___bit 8
+#define reg_iop_sw_cpu_rw_ack_intr3___spu1_1___lsb 9
+#define reg_iop_sw_cpu_rw_ack_intr3___spu1_1___width 1
+#define reg_iop_sw_cpu_rw_ack_intr3___spu1_1___bit 9
+#define reg_iop_sw_cpu_rw_ack_intr3___spu1_2___lsb 10
+#define reg_iop_sw_cpu_rw_ack_intr3___spu1_2___width 1
+#define reg_iop_sw_cpu_rw_ack_intr3___spu1_2___bit 10
+#define reg_iop_sw_cpu_rw_ack_intr3___spu1_3___lsb 11
+#define reg_iop_sw_cpu_rw_ack_intr3___spu1_3___width 1
+#define reg_iop_sw_cpu_rw_ack_intr3___spu1_3___bit 11
+#define reg_iop_sw_cpu_rw_ack_intr3___spu1_4___lsb 12
+#define reg_iop_sw_cpu_rw_ack_intr3___spu1_4___width 1
+#define reg_iop_sw_cpu_rw_ack_intr3___spu1_4___bit 12
+#define reg_iop_sw_cpu_rw_ack_intr3___spu1_5___lsb 13
+#define reg_iop_sw_cpu_rw_ack_intr3___spu1_5___width 1
+#define reg_iop_sw_cpu_rw_ack_intr3___spu1_5___bit 13
+#define reg_iop_sw_cpu_rw_ack_intr3___spu1_6___lsb 14
+#define reg_iop_sw_cpu_rw_ack_intr3___spu1_6___width 1
+#define reg_iop_sw_cpu_rw_ack_intr3___spu1_6___bit 14
+#define reg_iop_sw_cpu_rw_ack_intr3___spu1_7___lsb 15
+#define reg_iop_sw_cpu_rw_ack_intr3___spu1_7___width 1
+#define reg_iop_sw_cpu_rw_ack_intr3___spu1_7___bit 15
+#define reg_iop_sw_cpu_rw_ack_intr3_offset 136
+
+/* Register r_intr3, scope iop_sw_cpu, type r */
+#define reg_iop_sw_cpu_r_intr3___mpu_16___lsb 0
+#define reg_iop_sw_cpu_r_intr3___mpu_16___width 1
+#define reg_iop_sw_cpu_r_intr3___mpu_16___bit 0
+#define reg_iop_sw_cpu_r_intr3___mpu_17___lsb 1
+#define reg_iop_sw_cpu_r_intr3___mpu_17___width 1
+#define reg_iop_sw_cpu_r_intr3___mpu_17___bit 1
+#define reg_iop_sw_cpu_r_intr3___mpu_18___lsb 2
+#define reg_iop_sw_cpu_r_intr3___mpu_18___width 1
+#define reg_iop_sw_cpu_r_intr3___mpu_18___bit 2
+#define reg_iop_sw_cpu_r_intr3___mpu_19___lsb 3
+#define reg_iop_sw_cpu_r_intr3___mpu_19___width 1
+#define reg_iop_sw_cpu_r_intr3___mpu_19___bit 3
+#define reg_iop_sw_cpu_r_intr3___mpu_20___lsb 4
+#define reg_iop_sw_cpu_r_intr3___mpu_20___width 1
+#define reg_iop_sw_cpu_r_intr3___mpu_20___bit 4
+#define reg_iop_sw_cpu_r_intr3___mpu_21___lsb 5
+#define reg_iop_sw_cpu_r_intr3___mpu_21___width 1
+#define reg_iop_sw_cpu_r_intr3___mpu_21___bit 5
+#define reg_iop_sw_cpu_r_intr3___mpu_22___lsb 6
+#define reg_iop_sw_cpu_r_intr3___mpu_22___width 1
+#define reg_iop_sw_cpu_r_intr3___mpu_22___bit 6
+#define reg_iop_sw_cpu_r_intr3___mpu_23___lsb 7
+#define reg_iop_sw_cpu_r_intr3___mpu_23___width 1
+#define reg_iop_sw_cpu_r_intr3___mpu_23___bit 7
+#define reg_iop_sw_cpu_r_intr3___spu1_0___lsb 8
+#define reg_iop_sw_cpu_r_intr3___spu1_0___width 1
+#define reg_iop_sw_cpu_r_intr3___spu1_0___bit 8
+#define reg_iop_sw_cpu_r_intr3___spu1_1___lsb 9
+#define reg_iop_sw_cpu_r_intr3___spu1_1___width 1
+#define reg_iop_sw_cpu_r_intr3___spu1_1___bit 9
+#define reg_iop_sw_cpu_r_intr3___spu1_2___lsb 10
+#define reg_iop_sw_cpu_r_intr3___spu1_2___width 1
+#define reg_iop_sw_cpu_r_intr3___spu1_2___bit 10
+#define reg_iop_sw_cpu_r_intr3___spu1_3___lsb 11
+#define reg_iop_sw_cpu_r_intr3___spu1_3___width 1
+#define reg_iop_sw_cpu_r_intr3___spu1_3___bit 11
+#define reg_iop_sw_cpu_r_intr3___spu1_4___lsb 12
+#define reg_iop_sw_cpu_r_intr3___spu1_4___width 1
+#define reg_iop_sw_cpu_r_intr3___spu1_4___bit 12
+#define reg_iop_sw_cpu_r_intr3___spu1_5___lsb 13
+#define reg_iop_sw_cpu_r_intr3___spu1_5___width 1
+#define reg_iop_sw_cpu_r_intr3___spu1_5___bit 13
+#define reg_iop_sw_cpu_r_intr3___spu1_6___lsb 14
+#define reg_iop_sw_cpu_r_intr3___spu1_6___width 1
+#define reg_iop_sw_cpu_r_intr3___spu1_6___bit 14
+#define reg_iop_sw_cpu_r_intr3___spu1_7___lsb 15
+#define reg_iop_sw_cpu_r_intr3___spu1_7___width 1
+#define reg_iop_sw_cpu_r_intr3___spu1_7___bit 15
+#define reg_iop_sw_cpu_r_intr3___dmc_in1___lsb 16
+#define reg_iop_sw_cpu_r_intr3___dmc_in1___width 1
+#define reg_iop_sw_cpu_r_intr3___dmc_in1___bit 16
+#define reg_iop_sw_cpu_r_intr3___dmc_out1___lsb 17
+#define reg_iop_sw_cpu_r_intr3___dmc_out1___width 1
+#define reg_iop_sw_cpu_r_intr3___dmc_out1___bit 17
+#define reg_iop_sw_cpu_r_intr3___fifo_in1___lsb 18
+#define reg_iop_sw_cpu_r_intr3___fifo_in1___width 1
+#define reg_iop_sw_cpu_r_intr3___fifo_in1___bit 18
+#define reg_iop_sw_cpu_r_intr3___fifo_out1___lsb 19
+#define reg_iop_sw_cpu_r_intr3___fifo_out1___width 1
+#define reg_iop_sw_cpu_r_intr3___fifo_out1___bit 19
+#define reg_iop_sw_cpu_r_intr3___fifo_in1_extra___lsb 20
+#define reg_iop_sw_cpu_r_intr3___fifo_in1_extra___width 1
+#define reg_iop_sw_cpu_r_intr3___fifo_in1_extra___bit 20
+#define reg_iop_sw_cpu_r_intr3___fifo_out1_extra___lsb 21
+#define reg_iop_sw_cpu_r_intr3___fifo_out1_extra___width 1
+#define reg_iop_sw_cpu_r_intr3___fifo_out1_extra___bit 21
+#define reg_iop_sw_cpu_r_intr3___trigger_grp0___lsb 22
+#define reg_iop_sw_cpu_r_intr3___trigger_grp0___width 1
+#define reg_iop_sw_cpu_r_intr3___trigger_grp0___bit 22
+#define reg_iop_sw_cpu_r_intr3___trigger_grp1___lsb 23
+#define reg_iop_sw_cpu_r_intr3___trigger_grp1___width 1
+#define reg_iop_sw_cpu_r_intr3___trigger_grp1___bit 23
+#define reg_iop_sw_cpu_r_intr3___trigger_grp2___lsb 24
+#define reg_iop_sw_cpu_r_intr3___trigger_grp2___width 1
+#define reg_iop_sw_cpu_r_intr3___trigger_grp2___bit 24
+#define reg_iop_sw_cpu_r_intr3___trigger_grp3___lsb 25
+#define reg_iop_sw_cpu_r_intr3___trigger_grp3___width 1
+#define reg_iop_sw_cpu_r_intr3___trigger_grp3___bit 25
+#define reg_iop_sw_cpu_r_intr3___trigger_grp4___lsb 26
+#define reg_iop_sw_cpu_r_intr3___trigger_grp4___width 1
+#define reg_iop_sw_cpu_r_intr3___trigger_grp4___bit 26
+#define reg_iop_sw_cpu_r_intr3___trigger_grp5___lsb 27
+#define reg_iop_sw_cpu_r_intr3___trigger_grp5___width 1
+#define reg_iop_sw_cpu_r_intr3___trigger_grp5___bit 27
+#define reg_iop_sw_cpu_r_intr3___trigger_grp6___lsb 28
+#define reg_iop_sw_cpu_r_intr3___trigger_grp6___width 1
+#define reg_iop_sw_cpu_r_intr3___trigger_grp6___bit 28
+#define reg_iop_sw_cpu_r_intr3___trigger_grp7___lsb 29
+#define reg_iop_sw_cpu_r_intr3___trigger_grp7___width 1
+#define reg_iop_sw_cpu_r_intr3___trigger_grp7___bit 29
+#define reg_iop_sw_cpu_r_intr3___timer_grp2___lsb 30
+#define reg_iop_sw_cpu_r_intr3___timer_grp2___width 1
+#define reg_iop_sw_cpu_r_intr3___timer_grp2___bit 30
+#define reg_iop_sw_cpu_r_intr3___timer_grp3___lsb 31
+#define reg_iop_sw_cpu_r_intr3___timer_grp3___width 1
+#define reg_iop_sw_cpu_r_intr3___timer_grp3___bit 31
+#define reg_iop_sw_cpu_r_intr3_offset 140
+
+/* Register r_masked_intr3, scope iop_sw_cpu, type r */
+#define reg_iop_sw_cpu_r_masked_intr3___mpu_16___lsb 0
+#define reg_iop_sw_cpu_r_masked_intr3___mpu_16___width 1
+#define reg_iop_sw_cpu_r_masked_intr3___mpu_16___bit 0
+#define reg_iop_sw_cpu_r_masked_intr3___mpu_17___lsb 1
+#define reg_iop_sw_cpu_r_masked_intr3___mpu_17___width 1
+#define reg_iop_sw_cpu_r_masked_intr3___mpu_17___bit 1
+#define reg_iop_sw_cpu_r_masked_intr3___mpu_18___lsb 2
+#define reg_iop_sw_cpu_r_masked_intr3___mpu_18___width 1
+#define reg_iop_sw_cpu_r_masked_intr3___mpu_18___bit 2
+#define reg_iop_sw_cpu_r_masked_intr3___mpu_19___lsb 3
+#define reg_iop_sw_cpu_r_masked_intr3___mpu_19___width 1
+#define reg_iop_sw_cpu_r_masked_intr3___mpu_19___bit 3
+#define reg_iop_sw_cpu_r_masked_intr3___mpu_20___lsb 4
+#define reg_iop_sw_cpu_r_masked_intr3___mpu_20___width 1
+#define reg_iop_sw_cpu_r_masked_intr3___mpu_20___bit 4
+#define reg_iop_sw_cpu_r_masked_intr3___mpu_21___lsb 5
+#define reg_iop_sw_cpu_r_masked_intr3___mpu_21___width 1
+#define reg_iop_sw_cpu_r_masked_intr3___mpu_21___bit 5
+#define reg_iop_sw_cpu_r_masked_intr3___mpu_22___lsb 6
+#define reg_iop_sw_cpu_r_masked_intr3___mpu_22___width 1
+#define reg_iop_sw_cpu_r_masked_intr3___mpu_22___bit 6
+#define reg_iop_sw_cpu_r_masked_intr3___mpu_23___lsb 7
+#define reg_iop_sw_cpu_r_masked_intr3___mpu_23___width 1
+#define reg_iop_sw_cpu_r_masked_intr3___mpu_23___bit 7
+#define reg_iop_sw_cpu_r_masked_intr3___spu1_0___lsb 8
+#define reg_iop_sw_cpu_r_masked_intr3___spu1_0___width 1
+#define reg_iop_sw_cpu_r_masked_intr3___spu1_0___bit 8
+#define reg_iop_sw_cpu_r_masked_intr3___spu1_1___lsb 9
+#define reg_iop_sw_cpu_r_masked_intr3___spu1_1___width 1
+#define reg_iop_sw_cpu_r_masked_intr3___spu1_1___bit 9
+#define reg_iop_sw_cpu_r_masked_intr3___spu1_2___lsb 10
+#define reg_iop_sw_cpu_r_masked_intr3___spu1_2___width 1
+#define reg_iop_sw_cpu_r_masked_intr3___spu1_2___bit 10
+#define reg_iop_sw_cpu_r_masked_intr3___spu1_3___lsb 11
+#define reg_iop_sw_cpu_r_masked_intr3___spu1_3___width 1
+#define reg_iop_sw_cpu_r_masked_intr3___spu1_3___bit 11
+#define reg_iop_sw_cpu_r_masked_intr3___spu1_4___lsb 12
+#define reg_iop_sw_cpu_r_masked_intr3___spu1_4___width 1
+#define reg_iop_sw_cpu_r_masked_intr3___spu1_4___bit 12
+#define reg_iop_sw_cpu_r_masked_intr3___spu1_5___lsb 13
+#define reg_iop_sw_cpu_r_masked_intr3___spu1_5___width 1
+#define reg_iop_sw_cpu_r_masked_intr3___spu1_5___bit 13
+#define reg_iop_sw_cpu_r_masked_intr3___spu1_6___lsb 14
+#define reg_iop_sw_cpu_r_masked_intr3___spu1_6___width 1
+#define reg_iop_sw_cpu_r_masked_intr3___spu1_6___bit 14
+#define reg_iop_sw_cpu_r_masked_intr3___spu1_7___lsb 15
+#define reg_iop_sw_cpu_r_masked_intr3___spu1_7___width 1
+#define reg_iop_sw_cpu_r_masked_intr3___spu1_7___bit 15
+#define reg_iop_sw_cpu_r_masked_intr3___dmc_in1___lsb 16
+#define reg_iop_sw_cpu_r_masked_intr3___dmc_in1___width 1
+#define reg_iop_sw_cpu_r_masked_intr3___dmc_in1___bit 16
+#define reg_iop_sw_cpu_r_masked_intr3___dmc_out1___lsb 17
+#define reg_iop_sw_cpu_r_masked_intr3___dmc_out1___width 1
+#define reg_iop_sw_cpu_r_masked_intr3___dmc_out1___bit 17
+#define reg_iop_sw_cpu_r_masked_intr3___fifo_in1___lsb 18
+#define reg_iop_sw_cpu_r_masked_intr3___fifo_in1___width 1
+#define reg_iop_sw_cpu_r_masked_intr3___fifo_in1___bit 18
+#define reg_iop_sw_cpu_r_masked_intr3___fifo_out1___lsb 19
+#define reg_iop_sw_cpu_r_masked_intr3___fifo_out1___width 1
+#define reg_iop_sw_cpu_r_masked_intr3___fifo_out1___bit 19
+#define reg_iop_sw_cpu_r_masked_intr3___fifo_in1_extra___lsb 20
+#define reg_iop_sw_cpu_r_masked_intr3___fifo_in1_extra___width 1
+#define reg_iop_sw_cpu_r_masked_intr3___fifo_in1_extra___bit 20
+#define reg_iop_sw_cpu_r_masked_intr3___fifo_out1_extra___lsb 21
+#define reg_iop_sw_cpu_r_masked_intr3___fifo_out1_extra___width 1
+#define reg_iop_sw_cpu_r_masked_intr3___fifo_out1_extra___bit 21
+#define reg_iop_sw_cpu_r_masked_intr3___trigger_grp0___lsb 22
+#define reg_iop_sw_cpu_r_masked_intr3___trigger_grp0___width 1
+#define reg_iop_sw_cpu_r_masked_intr3___trigger_grp0___bit 22
+#define reg_iop_sw_cpu_r_masked_intr3___trigger_grp1___lsb 23
+#define reg_iop_sw_cpu_r_masked_intr3___trigger_grp1___width 1
+#define reg_iop_sw_cpu_r_masked_intr3___trigger_grp1___bit 23
+#define reg_iop_sw_cpu_r_masked_intr3___trigger_grp2___lsb 24
+#define reg_iop_sw_cpu_r_masked_intr3___trigger_grp2___width 1
+#define reg_iop_sw_cpu_r_masked_intr3___trigger_grp2___bit 24
+#define reg_iop_sw_cpu_r_masked_intr3___trigger_grp3___lsb 25
+#define reg_iop_sw_cpu_r_masked_intr3___trigger_grp3___width 1
+#define reg_iop_sw_cpu_r_masked_intr3___trigger_grp3___bit 25
+#define reg_iop_sw_cpu_r_masked_intr3___trigger_grp4___lsb 26
+#define reg_iop_sw_cpu_r_masked_intr3___trigger_grp4___width 1
+#define reg_iop_sw_cpu_r_masked_intr3___trigger_grp4___bit 26
+#define reg_iop_sw_cpu_r_masked_intr3___trigger_grp5___lsb 27
+#define reg_iop_sw_cpu_r_masked_intr3___trigger_grp5___width 1
+#define reg_iop_sw_cpu_r_masked_intr3___trigger_grp5___bit 27
+#define reg_iop_sw_cpu_r_masked_intr3___trigger_grp6___lsb 28
+#define reg_iop_sw_cpu_r_masked_intr3___trigger_grp6___width 1
+#define reg_iop_sw_cpu_r_masked_intr3___trigger_grp6___bit 28
+#define reg_iop_sw_cpu_r_masked_intr3___trigger_grp7___lsb 29
+#define reg_iop_sw_cpu_r_masked_intr3___trigger_grp7___width 1
+#define reg_iop_sw_cpu_r_masked_intr3___trigger_grp7___bit 29
+#define reg_iop_sw_cpu_r_masked_intr3___timer_grp2___lsb 30
+#define reg_iop_sw_cpu_r_masked_intr3___timer_grp2___width 1
+#define reg_iop_sw_cpu_r_masked_intr3___timer_grp2___bit 30
+#define reg_iop_sw_cpu_r_masked_intr3___timer_grp3___lsb 31
+#define reg_iop_sw_cpu_r_masked_intr3___timer_grp3___width 1
+#define reg_iop_sw_cpu_r_masked_intr3___timer_grp3___bit 31
+#define reg_iop_sw_cpu_r_masked_intr3_offset 144
+
+
+/* Constants */
+#define regk_iop_sw_cpu_copy                      0x00000000
+#define regk_iop_sw_cpu_no                        0x00000000
+#define regk_iop_sw_cpu_rd                        0x00000002
+#define regk_iop_sw_cpu_reg_copy                  0x00000001
+#define regk_iop_sw_cpu_rw_bus0_clr_mask_default  0x00000000
+#define regk_iop_sw_cpu_rw_bus0_oe_clr_mask_default  0x00000000
+#define regk_iop_sw_cpu_rw_bus0_oe_set_mask_default  0x00000000
+#define regk_iop_sw_cpu_rw_bus0_set_mask_default  0x00000000
+#define regk_iop_sw_cpu_rw_bus1_clr_mask_default  0x00000000
+#define regk_iop_sw_cpu_rw_bus1_oe_clr_mask_default  0x00000000
+#define regk_iop_sw_cpu_rw_bus1_oe_set_mask_default  0x00000000
+#define regk_iop_sw_cpu_rw_bus1_set_mask_default  0x00000000
+#define regk_iop_sw_cpu_rw_gio_clr_mask_default   0x00000000
+#define regk_iop_sw_cpu_rw_gio_oe_clr_mask_default  0x00000000
+#define regk_iop_sw_cpu_rw_gio_oe_set_mask_default  0x00000000
+#define regk_iop_sw_cpu_rw_gio_set_mask_default   0x00000000
+#define regk_iop_sw_cpu_rw_intr0_mask_default     0x00000000
+#define regk_iop_sw_cpu_rw_intr1_mask_default     0x00000000
+#define regk_iop_sw_cpu_rw_intr2_mask_default     0x00000000
+#define regk_iop_sw_cpu_rw_intr3_mask_default     0x00000000
+#define regk_iop_sw_cpu_wr                        0x00000003
+#define regk_iop_sw_cpu_yes                       0x00000001
+#endif /* __iop_sw_cpu_defs_asm_h */
diff --git a/include/asm-cris/arch-v32/hwregs/iop/asm/iop_sw_mpu_defs_asm.h b/include/asm-cris/arch-v32/hwregs/iop/asm/iop_sw_mpu_defs_asm.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/iop/asm/iop_sw_mpu_defs_asm.h
@@ -0,0 +1,1776 @@
+#ifndef __iop_sw_mpu_defs_asm_h
+#define __iop_sw_mpu_defs_asm_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/io_proc/rtl/guinness/iop_sw_mpu.r
+ *     id:           <not found>
+ *     last modfied: Mon Apr 11 16:10:19 2005
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c -asm --outfile asm/iop_sw_mpu_defs_asm.h ../../inst/io_proc/rtl/guinness/iop_sw_mpu.r
+ *      id: $Id: iop_sw_mpu_defs_asm.h,v 1.5 2005/04/24 18:31:07 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+
+#ifndef REG_FIELD
+#define REG_FIELD( scope, reg, field, value ) \
+  REG_FIELD_X_( value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_FIELD_X_( value, shift ) ((value) << shift)
+#endif
+
+#ifndef REG_STATE
+#define REG_STATE( scope, reg, field, symbolic_value ) \
+  REG_STATE_X_( regk_##scope##_##symbolic_value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_STATE_X_( k, shift ) (k << shift)
+#endif
+
+#ifndef REG_MASK
+#define REG_MASK( scope, reg, field ) \
+  REG_MASK_X_( reg_##scope##_##reg##___##field##___width, reg_##scope##_##reg##___##field##___lsb )
+#define REG_MASK_X_( width, lsb ) (((1 << width)-1) << lsb)
+#endif
+
+#ifndef REG_LSB
+#define REG_LSB( scope, reg, field ) reg_##scope##_##reg##___##field##___lsb
+#endif
+
+#ifndef REG_BIT
+#define REG_BIT( scope, reg, field ) reg_##scope##_##reg##___##field##___bit
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) REG_ADDR_X_(inst, reg_##scope##_##reg##_offset)
+#define REG_ADDR_X_( inst, offs ) ((inst) + offs)
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+         REG_ADDR_VECT_X_(inst, reg_##scope##_##reg##_offset, index, \
+			 STRIDE_##scope##_##reg )
+#define REG_ADDR_VECT_X_( inst, offs, index, stride ) \
+                          ((inst) + offs + (index) * stride)
+#endif
+
+/* Register rw_sw_cfg_owner, scope iop_sw_mpu, type rw */
+#define reg_iop_sw_mpu_rw_sw_cfg_owner___cfg___lsb 0
+#define reg_iop_sw_mpu_rw_sw_cfg_owner___cfg___width 2
+#define reg_iop_sw_mpu_rw_sw_cfg_owner_offset 0
+
+/* Register rw_mc_ctrl, scope iop_sw_mpu, type rw */
+#define reg_iop_sw_mpu_rw_mc_ctrl___keep_owner___lsb 0
+#define reg_iop_sw_mpu_rw_mc_ctrl___keep_owner___width 1
+#define reg_iop_sw_mpu_rw_mc_ctrl___keep_owner___bit 0
+#define reg_iop_sw_mpu_rw_mc_ctrl___cmd___lsb 1
+#define reg_iop_sw_mpu_rw_mc_ctrl___cmd___width 2
+#define reg_iop_sw_mpu_rw_mc_ctrl___size___lsb 3
+#define reg_iop_sw_mpu_rw_mc_ctrl___size___width 3
+#define reg_iop_sw_mpu_rw_mc_ctrl___wr_spu0_mem___lsb 6
+#define reg_iop_sw_mpu_rw_mc_ctrl___wr_spu0_mem___width 1
+#define reg_iop_sw_mpu_rw_mc_ctrl___wr_spu0_mem___bit 6
+#define reg_iop_sw_mpu_rw_mc_ctrl___wr_spu1_mem___lsb 7
+#define reg_iop_sw_mpu_rw_mc_ctrl___wr_spu1_mem___width 1
+#define reg_iop_sw_mpu_rw_mc_ctrl___wr_spu1_mem___bit 7
+#define reg_iop_sw_mpu_rw_mc_ctrl_offset 4
+
+/* Register rw_mc_data, scope iop_sw_mpu, type rw */
+#define reg_iop_sw_mpu_rw_mc_data___val___lsb 0
+#define reg_iop_sw_mpu_rw_mc_data___val___width 32
+#define reg_iop_sw_mpu_rw_mc_data_offset 8
+
+/* Register rw_mc_addr, scope iop_sw_mpu, type rw */
+#define reg_iop_sw_mpu_rw_mc_addr_offset 12
+
+/* Register rs_mc_data, scope iop_sw_mpu, type rs */
+#define reg_iop_sw_mpu_rs_mc_data_offset 16
+
+/* Register r_mc_data, scope iop_sw_mpu, type r */
+#define reg_iop_sw_mpu_r_mc_data_offset 20
+
+/* Register r_mc_stat, scope iop_sw_mpu, type r */
+#define reg_iop_sw_mpu_r_mc_stat___busy_cpu___lsb 0
+#define reg_iop_sw_mpu_r_mc_stat___busy_cpu___width 1
+#define reg_iop_sw_mpu_r_mc_stat___busy_cpu___bit 0
+#define reg_iop_sw_mpu_r_mc_stat___busy_mpu___lsb 1
+#define reg_iop_sw_mpu_r_mc_stat___busy_mpu___width 1
+#define reg_iop_sw_mpu_r_mc_stat___busy_mpu___bit 1
+#define reg_iop_sw_mpu_r_mc_stat___busy_spu0___lsb 2
+#define reg_iop_sw_mpu_r_mc_stat___busy_spu0___width 1
+#define reg_iop_sw_mpu_r_mc_stat___busy_spu0___bit 2
+#define reg_iop_sw_mpu_r_mc_stat___busy_spu1___lsb 3
+#define reg_iop_sw_mpu_r_mc_stat___busy_spu1___width 1
+#define reg_iop_sw_mpu_r_mc_stat___busy_spu1___bit 3
+#define reg_iop_sw_mpu_r_mc_stat___owned_by_cpu___lsb 4
+#define reg_iop_sw_mpu_r_mc_stat___owned_by_cpu___width 1
+#define reg_iop_sw_mpu_r_mc_stat___owned_by_cpu___bit 4
+#define reg_iop_sw_mpu_r_mc_stat___owned_by_mpu___lsb 5
+#define reg_iop_sw_mpu_r_mc_stat___owned_by_mpu___width 1
+#define reg_iop_sw_mpu_r_mc_stat___owned_by_mpu___bit 5
+#define reg_iop_sw_mpu_r_mc_stat___owned_by_spu0___lsb 6
+#define reg_iop_sw_mpu_r_mc_stat___owned_by_spu0___width 1
+#define reg_iop_sw_mpu_r_mc_stat___owned_by_spu0___bit 6
+#define reg_iop_sw_mpu_r_mc_stat___owned_by_spu1___lsb 7
+#define reg_iop_sw_mpu_r_mc_stat___owned_by_spu1___width 1
+#define reg_iop_sw_mpu_r_mc_stat___owned_by_spu1___bit 7
+#define reg_iop_sw_mpu_r_mc_stat_offset 24
+
+/* Register rw_bus0_clr_mask, scope iop_sw_mpu, type rw */
+#define reg_iop_sw_mpu_rw_bus0_clr_mask___byte0___lsb 0
+#define reg_iop_sw_mpu_rw_bus0_clr_mask___byte0___width 8
+#define reg_iop_sw_mpu_rw_bus0_clr_mask___byte1___lsb 8
+#define reg_iop_sw_mpu_rw_bus0_clr_mask___byte1___width 8
+#define reg_iop_sw_mpu_rw_bus0_clr_mask___byte2___lsb 16
+#define reg_iop_sw_mpu_rw_bus0_clr_mask___byte2___width 8
+#define reg_iop_sw_mpu_rw_bus0_clr_mask___byte3___lsb 24
+#define reg_iop_sw_mpu_rw_bus0_clr_mask___byte3___width 8
+#define reg_iop_sw_mpu_rw_bus0_clr_mask_offset 28
+
+/* Register rw_bus0_set_mask, scope iop_sw_mpu, type rw */
+#define reg_iop_sw_mpu_rw_bus0_set_mask___byte0___lsb 0
+#define reg_iop_sw_mpu_rw_bus0_set_mask___byte0___width 8
+#define reg_iop_sw_mpu_rw_bus0_set_mask___byte1___lsb 8
+#define reg_iop_sw_mpu_rw_bus0_set_mask___byte1___width 8
+#define reg_iop_sw_mpu_rw_bus0_set_mask___byte2___lsb 16
+#define reg_iop_sw_mpu_rw_bus0_set_mask___byte2___width 8
+#define reg_iop_sw_mpu_rw_bus0_set_mask___byte3___lsb 24
+#define reg_iop_sw_mpu_rw_bus0_set_mask___byte3___width 8
+#define reg_iop_sw_mpu_rw_bus0_set_mask_offset 32
+
+/* Register rw_bus0_oe_clr_mask, scope iop_sw_mpu, type rw */
+#define reg_iop_sw_mpu_rw_bus0_oe_clr_mask___byte0___lsb 0
+#define reg_iop_sw_mpu_rw_bus0_oe_clr_mask___byte0___width 1
+#define reg_iop_sw_mpu_rw_bus0_oe_clr_mask___byte0___bit 0
+#define reg_iop_sw_mpu_rw_bus0_oe_clr_mask___byte1___lsb 1
+#define reg_iop_sw_mpu_rw_bus0_oe_clr_mask___byte1___width 1
+#define reg_iop_sw_mpu_rw_bus0_oe_clr_mask___byte1___bit 1
+#define reg_iop_sw_mpu_rw_bus0_oe_clr_mask___byte2___lsb 2
+#define reg_iop_sw_mpu_rw_bus0_oe_clr_mask___byte2___width 1
+#define reg_iop_sw_mpu_rw_bus0_oe_clr_mask___byte2___bit 2
+#define reg_iop_sw_mpu_rw_bus0_oe_clr_mask___byte3___lsb 3
+#define reg_iop_sw_mpu_rw_bus0_oe_clr_mask___byte3___width 1
+#define reg_iop_sw_mpu_rw_bus0_oe_clr_mask___byte3___bit 3
+#define reg_iop_sw_mpu_rw_bus0_oe_clr_mask_offset 36
+
+/* Register rw_bus0_oe_set_mask, scope iop_sw_mpu, type rw */
+#define reg_iop_sw_mpu_rw_bus0_oe_set_mask___byte0___lsb 0
+#define reg_iop_sw_mpu_rw_bus0_oe_set_mask___byte0___width 1
+#define reg_iop_sw_mpu_rw_bus0_oe_set_mask___byte0___bit 0
+#define reg_iop_sw_mpu_rw_bus0_oe_set_mask___byte1___lsb 1
+#define reg_iop_sw_mpu_rw_bus0_oe_set_mask___byte1___width 1
+#define reg_iop_sw_mpu_rw_bus0_oe_set_mask___byte1___bit 1
+#define reg_iop_sw_mpu_rw_bus0_oe_set_mask___byte2___lsb 2
+#define reg_iop_sw_mpu_rw_bus0_oe_set_mask___byte2___width 1
+#define reg_iop_sw_mpu_rw_bus0_oe_set_mask___byte2___bit 2
+#define reg_iop_sw_mpu_rw_bus0_oe_set_mask___byte3___lsb 3
+#define reg_iop_sw_mpu_rw_bus0_oe_set_mask___byte3___width 1
+#define reg_iop_sw_mpu_rw_bus0_oe_set_mask___byte3___bit 3
+#define reg_iop_sw_mpu_rw_bus0_oe_set_mask_offset 40
+
+/* Register r_bus0_in, scope iop_sw_mpu, type r */
+#define reg_iop_sw_mpu_r_bus0_in_offset 44
+
+/* Register rw_bus1_clr_mask, scope iop_sw_mpu, type rw */
+#define reg_iop_sw_mpu_rw_bus1_clr_mask___byte0___lsb 0
+#define reg_iop_sw_mpu_rw_bus1_clr_mask___byte0___width 8
+#define reg_iop_sw_mpu_rw_bus1_clr_mask___byte1___lsb 8
+#define reg_iop_sw_mpu_rw_bus1_clr_mask___byte1___width 8
+#define reg_iop_sw_mpu_rw_bus1_clr_mask___byte2___lsb 16
+#define reg_iop_sw_mpu_rw_bus1_clr_mask___byte2___width 8
+#define reg_iop_sw_mpu_rw_bus1_clr_mask___byte3___lsb 24
+#define reg_iop_sw_mpu_rw_bus1_clr_mask___byte3___width 8
+#define reg_iop_sw_mpu_rw_bus1_clr_mask_offset 48
+
+/* Register rw_bus1_set_mask, scope iop_sw_mpu, type rw */
+#define reg_iop_sw_mpu_rw_bus1_set_mask___byte0___lsb 0
+#define reg_iop_sw_mpu_rw_bus1_set_mask___byte0___width 8
+#define reg_iop_sw_mpu_rw_bus1_set_mask___byte1___lsb 8
+#define reg_iop_sw_mpu_rw_bus1_set_mask___byte1___width 8
+#define reg_iop_sw_mpu_rw_bus1_set_mask___byte2___lsb 16
+#define reg_iop_sw_mpu_rw_bus1_set_mask___byte2___width 8
+#define reg_iop_sw_mpu_rw_bus1_set_mask___byte3___lsb 24
+#define reg_iop_sw_mpu_rw_bus1_set_mask___byte3___width 8
+#define reg_iop_sw_mpu_rw_bus1_set_mask_offset 52
+
+/* Register rw_bus1_oe_clr_mask, scope iop_sw_mpu, type rw */
+#define reg_iop_sw_mpu_rw_bus1_oe_clr_mask___byte0___lsb 0
+#define reg_iop_sw_mpu_rw_bus1_oe_clr_mask___byte0___width 1
+#define reg_iop_sw_mpu_rw_bus1_oe_clr_mask___byte0___bit 0
+#define reg_iop_sw_mpu_rw_bus1_oe_clr_mask___byte1___lsb 1
+#define reg_iop_sw_mpu_rw_bus1_oe_clr_mask___byte1___width 1
+#define reg_iop_sw_mpu_rw_bus1_oe_clr_mask___byte1___bit 1
+#define reg_iop_sw_mpu_rw_bus1_oe_clr_mask___byte2___lsb 2
+#define reg_iop_sw_mpu_rw_bus1_oe_clr_mask___byte2___width 1
+#define reg_iop_sw_mpu_rw_bus1_oe_clr_mask___byte2___bit 2
+#define reg_iop_sw_mpu_rw_bus1_oe_clr_mask___byte3___lsb 3
+#define reg_iop_sw_mpu_rw_bus1_oe_clr_mask___byte3___width 1
+#define reg_iop_sw_mpu_rw_bus1_oe_clr_mask___byte3___bit 3
+#define reg_iop_sw_mpu_rw_bus1_oe_clr_mask_offset 56
+
+/* Register rw_bus1_oe_set_mask, scope iop_sw_mpu, type rw */
+#define reg_iop_sw_mpu_rw_bus1_oe_set_mask___byte0___lsb 0
+#define reg_iop_sw_mpu_rw_bus1_oe_set_mask___byte0___width 1
+#define reg_iop_sw_mpu_rw_bus1_oe_set_mask___byte0___bit 0
+#define reg_iop_sw_mpu_rw_bus1_oe_set_mask___byte1___lsb 1
+#define reg_iop_sw_mpu_rw_bus1_oe_set_mask___byte1___width 1
+#define reg_iop_sw_mpu_rw_bus1_oe_set_mask___byte1___bit 1
+#define reg_iop_sw_mpu_rw_bus1_oe_set_mask___byte2___lsb 2
+#define reg_iop_sw_mpu_rw_bus1_oe_set_mask___byte2___width 1
+#define reg_iop_sw_mpu_rw_bus1_oe_set_mask___byte2___bit 2
+#define reg_iop_sw_mpu_rw_bus1_oe_set_mask___byte3___lsb 3
+#define reg_iop_sw_mpu_rw_bus1_oe_set_mask___byte3___width 1
+#define reg_iop_sw_mpu_rw_bus1_oe_set_mask___byte3___bit 3
+#define reg_iop_sw_mpu_rw_bus1_oe_set_mask_offset 60
+
+/* Register r_bus1_in, scope iop_sw_mpu, type r */
+#define reg_iop_sw_mpu_r_bus1_in_offset 64
+
+/* Register rw_gio_clr_mask, scope iop_sw_mpu, type rw */
+#define reg_iop_sw_mpu_rw_gio_clr_mask___val___lsb 0
+#define reg_iop_sw_mpu_rw_gio_clr_mask___val___width 32
+#define reg_iop_sw_mpu_rw_gio_clr_mask_offset 68
+
+/* Register rw_gio_set_mask, scope iop_sw_mpu, type rw */
+#define reg_iop_sw_mpu_rw_gio_set_mask___val___lsb 0
+#define reg_iop_sw_mpu_rw_gio_set_mask___val___width 32
+#define reg_iop_sw_mpu_rw_gio_set_mask_offset 72
+
+/* Register rw_gio_oe_clr_mask, scope iop_sw_mpu, type rw */
+#define reg_iop_sw_mpu_rw_gio_oe_clr_mask___val___lsb 0
+#define reg_iop_sw_mpu_rw_gio_oe_clr_mask___val___width 32
+#define reg_iop_sw_mpu_rw_gio_oe_clr_mask_offset 76
+
+/* Register rw_gio_oe_set_mask, scope iop_sw_mpu, type rw */
+#define reg_iop_sw_mpu_rw_gio_oe_set_mask___val___lsb 0
+#define reg_iop_sw_mpu_rw_gio_oe_set_mask___val___width 32
+#define reg_iop_sw_mpu_rw_gio_oe_set_mask_offset 80
+
+/* Register r_gio_in, scope iop_sw_mpu, type r */
+#define reg_iop_sw_mpu_r_gio_in_offset 84
+
+/* Register rw_cpu_intr, scope iop_sw_mpu, type rw */
+#define reg_iop_sw_mpu_rw_cpu_intr___intr0___lsb 0
+#define reg_iop_sw_mpu_rw_cpu_intr___intr0___width 1
+#define reg_iop_sw_mpu_rw_cpu_intr___intr0___bit 0
+#define reg_iop_sw_mpu_rw_cpu_intr___intr1___lsb 1
+#define reg_iop_sw_mpu_rw_cpu_intr___intr1___width 1
+#define reg_iop_sw_mpu_rw_cpu_intr___intr1___bit 1
+#define reg_iop_sw_mpu_rw_cpu_intr___intr2___lsb 2
+#define reg_iop_sw_mpu_rw_cpu_intr___intr2___width 1
+#define reg_iop_sw_mpu_rw_cpu_intr___intr2___bit 2
+#define reg_iop_sw_mpu_rw_cpu_intr___intr3___lsb 3
+#define reg_iop_sw_mpu_rw_cpu_intr___intr3___width 1
+#define reg_iop_sw_mpu_rw_cpu_intr___intr3___bit 3
+#define reg_iop_sw_mpu_rw_cpu_intr___intr4___lsb 4
+#define reg_iop_sw_mpu_rw_cpu_intr___intr4___width 1
+#define reg_iop_sw_mpu_rw_cpu_intr___intr4___bit 4
+#define reg_iop_sw_mpu_rw_cpu_intr___intr5___lsb 5
+#define reg_iop_sw_mpu_rw_cpu_intr___intr5___width 1
+#define reg_iop_sw_mpu_rw_cpu_intr___intr5___bit 5
+#define reg_iop_sw_mpu_rw_cpu_intr___intr6___lsb 6
+#define reg_iop_sw_mpu_rw_cpu_intr___intr6___width 1
+#define reg_iop_sw_mpu_rw_cpu_intr___intr6___bit 6
+#define reg_iop_sw_mpu_rw_cpu_intr___intr7___lsb 7
+#define reg_iop_sw_mpu_rw_cpu_intr___intr7___width 1
+#define reg_iop_sw_mpu_rw_cpu_intr___intr7___bit 7
+#define reg_iop_sw_mpu_rw_cpu_intr___intr8___lsb 8
+#define reg_iop_sw_mpu_rw_cpu_intr___intr8___width 1
+#define reg_iop_sw_mpu_rw_cpu_intr___intr8___bit 8
+#define reg_iop_sw_mpu_rw_cpu_intr___intr9___lsb 9
+#define reg_iop_sw_mpu_rw_cpu_intr___intr9___width 1
+#define reg_iop_sw_mpu_rw_cpu_intr___intr9___bit 9
+#define reg_iop_sw_mpu_rw_cpu_intr___intr10___lsb 10
+#define reg_iop_sw_mpu_rw_cpu_intr___intr10___width 1
+#define reg_iop_sw_mpu_rw_cpu_intr___intr10___bit 10
+#define reg_iop_sw_mpu_rw_cpu_intr___intr11___lsb 11
+#define reg_iop_sw_mpu_rw_cpu_intr___intr11___width 1
+#define reg_iop_sw_mpu_rw_cpu_intr___intr11___bit 11
+#define reg_iop_sw_mpu_rw_cpu_intr___intr12___lsb 12
+#define reg_iop_sw_mpu_rw_cpu_intr___intr12___width 1
+#define reg_iop_sw_mpu_rw_cpu_intr___intr12___bit 12
+#define reg_iop_sw_mpu_rw_cpu_intr___intr13___lsb 13
+#define reg_iop_sw_mpu_rw_cpu_intr___intr13___width 1
+#define reg_iop_sw_mpu_rw_cpu_intr___intr13___bit 13
+#define reg_iop_sw_mpu_rw_cpu_intr___intr14___lsb 14
+#define reg_iop_sw_mpu_rw_cpu_intr___intr14___width 1
+#define reg_iop_sw_mpu_rw_cpu_intr___intr14___bit 14
+#define reg_iop_sw_mpu_rw_cpu_intr___intr15___lsb 15
+#define reg_iop_sw_mpu_rw_cpu_intr___intr15___width 1
+#define reg_iop_sw_mpu_rw_cpu_intr___intr15___bit 15
+#define reg_iop_sw_mpu_rw_cpu_intr___intr16___lsb 16
+#define reg_iop_sw_mpu_rw_cpu_intr___intr16___width 1
+#define reg_iop_sw_mpu_rw_cpu_intr___intr16___bit 16
+#define reg_iop_sw_mpu_rw_cpu_intr___intr17___lsb 17
+#define reg_iop_sw_mpu_rw_cpu_intr___intr17___width 1
+#define reg_iop_sw_mpu_rw_cpu_intr___intr17___bit 17
+#define reg_iop_sw_mpu_rw_cpu_intr___intr18___lsb 18
+#define reg_iop_sw_mpu_rw_cpu_intr___intr18___width 1
+#define reg_iop_sw_mpu_rw_cpu_intr___intr18___bit 18
+#define reg_iop_sw_mpu_rw_cpu_intr___intr19___lsb 19
+#define reg_iop_sw_mpu_rw_cpu_intr___intr19___width 1
+#define reg_iop_sw_mpu_rw_cpu_intr___intr19___bit 19
+#define reg_iop_sw_mpu_rw_cpu_intr___intr20___lsb 20
+#define reg_iop_sw_mpu_rw_cpu_intr___intr20___width 1
+#define reg_iop_sw_mpu_rw_cpu_intr___intr20___bit 20
+#define reg_iop_sw_mpu_rw_cpu_intr___intr21___lsb 21
+#define reg_iop_sw_mpu_rw_cpu_intr___intr21___width 1
+#define reg_iop_sw_mpu_rw_cpu_intr___intr21___bit 21
+#define reg_iop_sw_mpu_rw_cpu_intr___intr22___lsb 22
+#define reg_iop_sw_mpu_rw_cpu_intr___intr22___width 1
+#define reg_iop_sw_mpu_rw_cpu_intr___intr22___bit 22
+#define reg_iop_sw_mpu_rw_cpu_intr___intr23___lsb 23
+#define reg_iop_sw_mpu_rw_cpu_intr___intr23___width 1
+#define reg_iop_sw_mpu_rw_cpu_intr___intr23___bit 23
+#define reg_iop_sw_mpu_rw_cpu_intr___intr24___lsb 24
+#define reg_iop_sw_mpu_rw_cpu_intr___intr24___width 1
+#define reg_iop_sw_mpu_rw_cpu_intr___intr24___bit 24
+#define reg_iop_sw_mpu_rw_cpu_intr___intr25___lsb 25
+#define reg_iop_sw_mpu_rw_cpu_intr___intr25___width 1
+#define reg_iop_sw_mpu_rw_cpu_intr___intr25___bit 25
+#define reg_iop_sw_mpu_rw_cpu_intr___intr26___lsb 26
+#define reg_iop_sw_mpu_rw_cpu_intr___intr26___width 1
+#define reg_iop_sw_mpu_rw_cpu_intr___intr26___bit 26
+#define reg_iop_sw_mpu_rw_cpu_intr___intr27___lsb 27
+#define reg_iop_sw_mpu_rw_cpu_intr___intr27___width 1
+#define reg_iop_sw_mpu_rw_cpu_intr___intr27___bit 27
+#define reg_iop_sw_mpu_rw_cpu_intr___intr28___lsb 28
+#define reg_iop_sw_mpu_rw_cpu_intr___intr28___width 1
+#define reg_iop_sw_mpu_rw_cpu_intr___intr28___bit 28
+#define reg_iop_sw_mpu_rw_cpu_intr___intr29___lsb 29
+#define reg_iop_sw_mpu_rw_cpu_intr___intr29___width 1
+#define reg_iop_sw_mpu_rw_cpu_intr___intr29___bit 29
+#define reg_iop_sw_mpu_rw_cpu_intr___intr30___lsb 30
+#define reg_iop_sw_mpu_rw_cpu_intr___intr30___width 1
+#define reg_iop_sw_mpu_rw_cpu_intr___intr30___bit 30
+#define reg_iop_sw_mpu_rw_cpu_intr___intr31___lsb 31
+#define reg_iop_sw_mpu_rw_cpu_intr___intr31___width 1
+#define reg_iop_sw_mpu_rw_cpu_intr___intr31___bit 31
+#define reg_iop_sw_mpu_rw_cpu_intr_offset 88
+
+/* Register r_cpu_intr, scope iop_sw_mpu, type r */
+#define reg_iop_sw_mpu_r_cpu_intr___intr0___lsb 0
+#define reg_iop_sw_mpu_r_cpu_intr___intr0___width 1
+#define reg_iop_sw_mpu_r_cpu_intr___intr0___bit 0
+#define reg_iop_sw_mpu_r_cpu_intr___intr1___lsb 1
+#define reg_iop_sw_mpu_r_cpu_intr___intr1___width 1
+#define reg_iop_sw_mpu_r_cpu_intr___intr1___bit 1
+#define reg_iop_sw_mpu_r_cpu_intr___intr2___lsb 2
+#define reg_iop_sw_mpu_r_cpu_intr___intr2___width 1
+#define reg_iop_sw_mpu_r_cpu_intr___intr2___bit 2
+#define reg_iop_sw_mpu_r_cpu_intr___intr3___lsb 3
+#define reg_iop_sw_mpu_r_cpu_intr___intr3___width 1
+#define reg_iop_sw_mpu_r_cpu_intr___intr3___bit 3
+#define reg_iop_sw_mpu_r_cpu_intr___intr4___lsb 4
+#define reg_iop_sw_mpu_r_cpu_intr___intr4___width 1
+#define reg_iop_sw_mpu_r_cpu_intr___intr4___bit 4
+#define reg_iop_sw_mpu_r_cpu_intr___intr5___lsb 5
+#define reg_iop_sw_mpu_r_cpu_intr___intr5___width 1
+#define reg_iop_sw_mpu_r_cpu_intr___intr5___bit 5
+#define reg_iop_sw_mpu_r_cpu_intr___intr6___lsb 6
+#define reg_iop_sw_mpu_r_cpu_intr___intr6___width 1
+#define reg_iop_sw_mpu_r_cpu_intr___intr6___bit 6
+#define reg_iop_sw_mpu_r_cpu_intr___intr7___lsb 7
+#define reg_iop_sw_mpu_r_cpu_intr___intr7___width 1
+#define reg_iop_sw_mpu_r_cpu_intr___intr7___bit 7
+#define reg_iop_sw_mpu_r_cpu_intr___intr8___lsb 8
+#define reg_iop_sw_mpu_r_cpu_intr___intr8___width 1
+#define reg_iop_sw_mpu_r_cpu_intr___intr8___bit 8
+#define reg_iop_sw_mpu_r_cpu_intr___intr9___lsb 9
+#define reg_iop_sw_mpu_r_cpu_intr___intr9___width 1
+#define reg_iop_sw_mpu_r_cpu_intr___intr9___bit 9
+#define reg_iop_sw_mpu_r_cpu_intr___intr10___lsb 10
+#define reg_iop_sw_mpu_r_cpu_intr___intr10___width 1
+#define reg_iop_sw_mpu_r_cpu_intr___intr10___bit 10
+#define reg_iop_sw_mpu_r_cpu_intr___intr11___lsb 11
+#define reg_iop_sw_mpu_r_cpu_intr___intr11___width 1
+#define reg_iop_sw_mpu_r_cpu_intr___intr11___bit 11
+#define reg_iop_sw_mpu_r_cpu_intr___intr12___lsb 12
+#define reg_iop_sw_mpu_r_cpu_intr___intr12___width 1
+#define reg_iop_sw_mpu_r_cpu_intr___intr12___bit 12
+#define reg_iop_sw_mpu_r_cpu_intr___intr13___lsb 13
+#define reg_iop_sw_mpu_r_cpu_intr___intr13___width 1
+#define reg_iop_sw_mpu_r_cpu_intr___intr13___bit 13
+#define reg_iop_sw_mpu_r_cpu_intr___intr14___lsb 14
+#define reg_iop_sw_mpu_r_cpu_intr___intr14___width 1
+#define reg_iop_sw_mpu_r_cpu_intr___intr14___bit 14
+#define reg_iop_sw_mpu_r_cpu_intr___intr15___lsb 15
+#define reg_iop_sw_mpu_r_cpu_intr___intr15___width 1
+#define reg_iop_sw_mpu_r_cpu_intr___intr15___bit 15
+#define reg_iop_sw_mpu_r_cpu_intr___intr16___lsb 16
+#define reg_iop_sw_mpu_r_cpu_intr___intr16___width 1
+#define reg_iop_sw_mpu_r_cpu_intr___intr16___bit 16
+#define reg_iop_sw_mpu_r_cpu_intr___intr17___lsb 17
+#define reg_iop_sw_mpu_r_cpu_intr___intr17___width 1
+#define reg_iop_sw_mpu_r_cpu_intr___intr17___bit 17
+#define reg_iop_sw_mpu_r_cpu_intr___intr18___lsb 18
+#define reg_iop_sw_mpu_r_cpu_intr___intr18___width 1
+#define reg_iop_sw_mpu_r_cpu_intr___intr18___bit 18
+#define reg_iop_sw_mpu_r_cpu_intr___intr19___lsb 19
+#define reg_iop_sw_mpu_r_cpu_intr___intr19___width 1
+#define reg_iop_sw_mpu_r_cpu_intr___intr19___bit 19
+#define reg_iop_sw_mpu_r_cpu_intr___intr20___lsb 20
+#define reg_iop_sw_mpu_r_cpu_intr___intr20___width 1
+#define reg_iop_sw_mpu_r_cpu_intr___intr20___bit 20
+#define reg_iop_sw_mpu_r_cpu_intr___intr21___lsb 21
+#define reg_iop_sw_mpu_r_cpu_intr___intr21___width 1
+#define reg_iop_sw_mpu_r_cpu_intr___intr21___bit 21
+#define reg_iop_sw_mpu_r_cpu_intr___intr22___lsb 22
+#define reg_iop_sw_mpu_r_cpu_intr___intr22___width 1
+#define reg_iop_sw_mpu_r_cpu_intr___intr22___bit 22
+#define reg_iop_sw_mpu_r_cpu_intr___intr23___lsb 23
+#define reg_iop_sw_mpu_r_cpu_intr___intr23___width 1
+#define reg_iop_sw_mpu_r_cpu_intr___intr23___bit 23
+#define reg_iop_sw_mpu_r_cpu_intr___intr24___lsb 24
+#define reg_iop_sw_mpu_r_cpu_intr___intr24___width 1
+#define reg_iop_sw_mpu_r_cpu_intr___intr24___bit 24
+#define reg_iop_sw_mpu_r_cpu_intr___intr25___lsb 25
+#define reg_iop_sw_mpu_r_cpu_intr___intr25___width 1
+#define reg_iop_sw_mpu_r_cpu_intr___intr25___bit 25
+#define reg_iop_sw_mpu_r_cpu_intr___intr26___lsb 26
+#define reg_iop_sw_mpu_r_cpu_intr___intr26___width 1
+#define reg_iop_sw_mpu_r_cpu_intr___intr26___bit 26
+#define reg_iop_sw_mpu_r_cpu_intr___intr27___lsb 27
+#define reg_iop_sw_mpu_r_cpu_intr___intr27___width 1
+#define reg_iop_sw_mpu_r_cpu_intr___intr27___bit 27
+#define reg_iop_sw_mpu_r_cpu_intr___intr28___lsb 28
+#define reg_iop_sw_mpu_r_cpu_intr___intr28___width 1
+#define reg_iop_sw_mpu_r_cpu_intr___intr28___bit 28
+#define reg_iop_sw_mpu_r_cpu_intr___intr29___lsb 29
+#define reg_iop_sw_mpu_r_cpu_intr___intr29___width 1
+#define reg_iop_sw_mpu_r_cpu_intr___intr29___bit 29
+#define reg_iop_sw_mpu_r_cpu_intr___intr30___lsb 30
+#define reg_iop_sw_mpu_r_cpu_intr___intr30___width 1
+#define reg_iop_sw_mpu_r_cpu_intr___intr30___bit 30
+#define reg_iop_sw_mpu_r_cpu_intr___intr31___lsb 31
+#define reg_iop_sw_mpu_r_cpu_intr___intr31___width 1
+#define reg_iop_sw_mpu_r_cpu_intr___intr31___bit 31
+#define reg_iop_sw_mpu_r_cpu_intr_offset 92
+
+/* Register rw_intr_grp0_mask, scope iop_sw_mpu, type rw */
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___spu0_intr0___lsb 0
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___spu0_intr0___width 1
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___spu0_intr0___bit 0
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___spu1_intr0___lsb 1
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___spu1_intr0___width 1
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___spu1_intr0___bit 1
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___trigger_grp0___lsb 2
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___trigger_grp0___width 1
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___trigger_grp0___bit 2
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___trigger_grp4___lsb 3
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___trigger_grp4___width 1
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___trigger_grp4___bit 3
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___timer_grp0___lsb 4
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___timer_grp0___width 1
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___timer_grp0___bit 4
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___fifo_out0___lsb 5
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___fifo_out0___width 1
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___fifo_out0___bit 5
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___fifo_out0_extra___lsb 6
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___fifo_out0_extra___width 1
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___fifo_out0_extra___bit 6
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___dmc_out0___lsb 7
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___dmc_out0___width 1
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___dmc_out0___bit 7
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___spu0_intr1___lsb 8
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___spu0_intr1___width 1
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___spu0_intr1___bit 8
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___spu1_intr1___lsb 9
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___spu1_intr1___width 1
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___spu1_intr1___bit 9
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___trigger_grp1___lsb 10
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___trigger_grp1___width 1
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___trigger_grp1___bit 10
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___trigger_grp5___lsb 11
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___trigger_grp5___width 1
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___trigger_grp5___bit 11
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___timer_grp1___lsb 12
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___timer_grp1___width 1
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___timer_grp1___bit 12
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___fifo_in0___lsb 13
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___fifo_in0___width 1
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___fifo_in0___bit 13
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___fifo_in0_extra___lsb 14
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___fifo_in0_extra___width 1
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___fifo_in0_extra___bit 14
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___dmc_in0___lsb 15
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___dmc_in0___width 1
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___dmc_in0___bit 15
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___spu0_intr2___lsb 16
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___spu0_intr2___width 1
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___spu0_intr2___bit 16
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___spu1_intr2___lsb 17
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___spu1_intr2___width 1
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___spu1_intr2___bit 17
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___trigger_grp2___lsb 18
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___trigger_grp2___width 1
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___trigger_grp2___bit 18
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___trigger_grp6___lsb 19
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___trigger_grp6___width 1
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___trigger_grp6___bit 19
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___timer_grp2___lsb 20
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___timer_grp2___width 1
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___timer_grp2___bit 20
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___fifo_out1___lsb 21
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___fifo_out1___width 1
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___fifo_out1___bit 21
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___fifo_out1_extra___lsb 22
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___fifo_out1_extra___width 1
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___fifo_out1_extra___bit 22
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___dmc_out1___lsb 23
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___dmc_out1___width 1
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___dmc_out1___bit 23
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___spu0_intr3___lsb 24
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___spu0_intr3___width 1
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___spu0_intr3___bit 24
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___spu1_intr3___lsb 25
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___spu1_intr3___width 1
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___spu1_intr3___bit 25
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___trigger_grp3___lsb 26
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___trigger_grp3___width 1
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___trigger_grp3___bit 26
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___trigger_grp7___lsb 27
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___trigger_grp7___width 1
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___trigger_grp7___bit 27
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___timer_grp3___lsb 28
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___timer_grp3___width 1
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___timer_grp3___bit 28
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___fifo_in1___lsb 29
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___fifo_in1___width 1
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___fifo_in1___bit 29
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___fifo_in1_extra___lsb 30
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___fifo_in1_extra___width 1
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___fifo_in1_extra___bit 30
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___dmc_in1___lsb 31
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___dmc_in1___width 1
+#define reg_iop_sw_mpu_rw_intr_grp0_mask___dmc_in1___bit 31
+#define reg_iop_sw_mpu_rw_intr_grp0_mask_offset 96
+
+/* Register rw_ack_intr_grp0, scope iop_sw_mpu, type rw */
+#define reg_iop_sw_mpu_rw_ack_intr_grp0___spu0_intr0___lsb 0
+#define reg_iop_sw_mpu_rw_ack_intr_grp0___spu0_intr0___width 1
+#define reg_iop_sw_mpu_rw_ack_intr_grp0___spu0_intr0___bit 0
+#define reg_iop_sw_mpu_rw_ack_intr_grp0___spu1_intr0___lsb 1
+#define reg_iop_sw_mpu_rw_ack_intr_grp0___spu1_intr0___width 1
+#define reg_iop_sw_mpu_rw_ack_intr_grp0___spu1_intr0___bit 1
+#define reg_iop_sw_mpu_rw_ack_intr_grp0___spu0_intr1___lsb 8
+#define reg_iop_sw_mpu_rw_ack_intr_grp0___spu0_intr1___width 1
+#define reg_iop_sw_mpu_rw_ack_intr_grp0___spu0_intr1___bit 8
+#define reg_iop_sw_mpu_rw_ack_intr_grp0___spu1_intr1___lsb 9
+#define reg_iop_sw_mpu_rw_ack_intr_grp0___spu1_intr1___width 1
+#define reg_iop_sw_mpu_rw_ack_intr_grp0___spu1_intr1___bit 9
+#define reg_iop_sw_mpu_rw_ack_intr_grp0___spu0_intr2___lsb 16
+#define reg_iop_sw_mpu_rw_ack_intr_grp0___spu0_intr2___width 1
+#define reg_iop_sw_mpu_rw_ack_intr_grp0___spu0_intr2___bit 16
+#define reg_iop_sw_mpu_rw_ack_intr_grp0___spu1_intr2___lsb 17
+#define reg_iop_sw_mpu_rw_ack_intr_grp0___spu1_intr2___width 1
+#define reg_iop_sw_mpu_rw_ack_intr_grp0___spu1_intr2___bit 17
+#define reg_iop_sw_mpu_rw_ack_intr_grp0___spu0_intr3___lsb 24
+#define reg_iop_sw_mpu_rw_ack_intr_grp0___spu0_intr3___width 1
+#define reg_iop_sw_mpu_rw_ack_intr_grp0___spu0_intr3___bit 24
+#define reg_iop_sw_mpu_rw_ack_intr_grp0___spu1_intr3___lsb 25
+#define reg_iop_sw_mpu_rw_ack_intr_grp0___spu1_intr3___width 1
+#define reg_iop_sw_mpu_rw_ack_intr_grp0___spu1_intr3___bit 25
+#define reg_iop_sw_mpu_rw_ack_intr_grp0_offset 100
+
+/* Register r_intr_grp0, scope iop_sw_mpu, type r */
+#define reg_iop_sw_mpu_r_intr_grp0___spu0_intr0___lsb 0
+#define reg_iop_sw_mpu_r_intr_grp0___spu0_intr0___width 1
+#define reg_iop_sw_mpu_r_intr_grp0___spu0_intr0___bit 0
+#define reg_iop_sw_mpu_r_intr_grp0___spu1_intr0___lsb 1
+#define reg_iop_sw_mpu_r_intr_grp0___spu1_intr0___width 1
+#define reg_iop_sw_mpu_r_intr_grp0___spu1_intr0___bit 1
+#define reg_iop_sw_mpu_r_intr_grp0___trigger_grp0___lsb 2
+#define reg_iop_sw_mpu_r_intr_grp0___trigger_grp0___width 1
+#define reg_iop_sw_mpu_r_intr_grp0___trigger_grp0___bit 2
+#define reg_iop_sw_mpu_r_intr_grp0___trigger_grp4___lsb 3
+#define reg_iop_sw_mpu_r_intr_grp0___trigger_grp4___width 1
+#define reg_iop_sw_mpu_r_intr_grp0___trigger_grp4___bit 3
+#define reg_iop_sw_mpu_r_intr_grp0___timer_grp0___lsb 4
+#define reg_iop_sw_mpu_r_intr_grp0___timer_grp0___width 1
+#define reg_iop_sw_mpu_r_intr_grp0___timer_grp0___bit 4
+#define reg_iop_sw_mpu_r_intr_grp0___fifo_out0___lsb 5
+#define reg_iop_sw_mpu_r_intr_grp0___fifo_out0___width 1
+#define reg_iop_sw_mpu_r_intr_grp0___fifo_out0___bit 5
+#define reg_iop_sw_mpu_r_intr_grp0___fifo_out0_extra___lsb 6
+#define reg_iop_sw_mpu_r_intr_grp0___fifo_out0_extra___width 1
+#define reg_iop_sw_mpu_r_intr_grp0___fifo_out0_extra___bit 6
+#define reg_iop_sw_mpu_r_intr_grp0___dmc_out0___lsb 7
+#define reg_iop_sw_mpu_r_intr_grp0___dmc_out0___width 1
+#define reg_iop_sw_mpu_r_intr_grp0___dmc_out0___bit 7
+#define reg_iop_sw_mpu_r_intr_grp0___spu0_intr1___lsb 8
+#define reg_iop_sw_mpu_r_intr_grp0___spu0_intr1___width 1
+#define reg_iop_sw_mpu_r_intr_grp0___spu0_intr1___bit 8
+#define reg_iop_sw_mpu_r_intr_grp0___spu1_intr1___lsb 9
+#define reg_iop_sw_mpu_r_intr_grp0___spu1_intr1___width 1
+#define reg_iop_sw_mpu_r_intr_grp0___spu1_intr1___bit 9
+#define reg_iop_sw_mpu_r_intr_grp0___trigger_grp1___lsb 10
+#define reg_iop_sw_mpu_r_intr_grp0___trigger_grp1___width 1
+#define reg_iop_sw_mpu_r_intr_grp0___trigger_grp1___bit 10
+#define reg_iop_sw_mpu_r_intr_grp0___trigger_grp5___lsb 11
+#define reg_iop_sw_mpu_r_intr_grp0___trigger_grp5___width 1
+#define reg_iop_sw_mpu_r_intr_grp0___trigger_grp5___bit 11
+#define reg_iop_sw_mpu_r_intr_grp0___timer_grp1___lsb 12
+#define reg_iop_sw_mpu_r_intr_grp0___timer_grp1___width 1
+#define reg_iop_sw_mpu_r_intr_grp0___timer_grp1___bit 12
+#define reg_iop_sw_mpu_r_intr_grp0___fifo_in0___lsb 13
+#define reg_iop_sw_mpu_r_intr_grp0___fifo_in0___width 1
+#define reg_iop_sw_mpu_r_intr_grp0___fifo_in0___bit 13
+#define reg_iop_sw_mpu_r_intr_grp0___fifo_in0_extra___lsb 14
+#define reg_iop_sw_mpu_r_intr_grp0___fifo_in0_extra___width 1
+#define reg_iop_sw_mpu_r_intr_grp0___fifo_in0_extra___bit 14
+#define reg_iop_sw_mpu_r_intr_grp0___dmc_in0___lsb 15
+#define reg_iop_sw_mpu_r_intr_grp0___dmc_in0___width 1
+#define reg_iop_sw_mpu_r_intr_grp0___dmc_in0___bit 15
+#define reg_iop_sw_mpu_r_intr_grp0___spu0_intr2___lsb 16
+#define reg_iop_sw_mpu_r_intr_grp0___spu0_intr2___width 1
+#define reg_iop_sw_mpu_r_intr_grp0___spu0_intr2___bit 16
+#define reg_iop_sw_mpu_r_intr_grp0___spu1_intr2___lsb 17
+#define reg_iop_sw_mpu_r_intr_grp0___spu1_intr2___width 1
+#define reg_iop_sw_mpu_r_intr_grp0___spu1_intr2___bit 17
+#define reg_iop_sw_mpu_r_intr_grp0___trigger_grp2___lsb 18
+#define reg_iop_sw_mpu_r_intr_grp0___trigger_grp2___width 1
+#define reg_iop_sw_mpu_r_intr_grp0___trigger_grp2___bit 18
+#define reg_iop_sw_mpu_r_intr_grp0___trigger_grp6___lsb 19
+#define reg_iop_sw_mpu_r_intr_grp0___trigger_grp6___width 1
+#define reg_iop_sw_mpu_r_intr_grp0___trigger_grp6___bit 19
+#define reg_iop_sw_mpu_r_intr_grp0___timer_grp2___lsb 20
+#define reg_iop_sw_mpu_r_intr_grp0___timer_grp2___width 1
+#define reg_iop_sw_mpu_r_intr_grp0___timer_grp2___bit 20
+#define reg_iop_sw_mpu_r_intr_grp0___fifo_out1___lsb 21
+#define reg_iop_sw_mpu_r_intr_grp0___fifo_out1___width 1
+#define reg_iop_sw_mpu_r_intr_grp0___fifo_out1___bit 21
+#define reg_iop_sw_mpu_r_intr_grp0___fifo_out1_extra___lsb 22
+#define reg_iop_sw_mpu_r_intr_grp0___fifo_out1_extra___width 1
+#define reg_iop_sw_mpu_r_intr_grp0___fifo_out1_extra___bit 22
+#define reg_iop_sw_mpu_r_intr_grp0___dmc_out1___lsb 23
+#define reg_iop_sw_mpu_r_intr_grp0___dmc_out1___width 1
+#define reg_iop_sw_mpu_r_intr_grp0___dmc_out1___bit 23
+#define reg_iop_sw_mpu_r_intr_grp0___spu0_intr3___lsb 24
+#define reg_iop_sw_mpu_r_intr_grp0___spu0_intr3___width 1
+#define reg_iop_sw_mpu_r_intr_grp0___spu0_intr3___bit 24
+#define reg_iop_sw_mpu_r_intr_grp0___spu1_intr3___lsb 25
+#define reg_iop_sw_mpu_r_intr_grp0___spu1_intr3___width 1
+#define reg_iop_sw_mpu_r_intr_grp0___spu1_intr3___bit 25
+#define reg_iop_sw_mpu_r_intr_grp0___trigger_grp3___lsb 26
+#define reg_iop_sw_mpu_r_intr_grp0___trigger_grp3___width 1
+#define reg_iop_sw_mpu_r_intr_grp0___trigger_grp3___bit 26
+#define reg_iop_sw_mpu_r_intr_grp0___trigger_grp7___lsb 27
+#define reg_iop_sw_mpu_r_intr_grp0___trigger_grp7___width 1
+#define reg_iop_sw_mpu_r_intr_grp0___trigger_grp7___bit 27
+#define reg_iop_sw_mpu_r_intr_grp0___timer_grp3___lsb 28
+#define reg_iop_sw_mpu_r_intr_grp0___timer_grp3___width 1
+#define reg_iop_sw_mpu_r_intr_grp0___timer_grp3___bit 28
+#define reg_iop_sw_mpu_r_intr_grp0___fifo_in1___lsb 29
+#define reg_iop_sw_mpu_r_intr_grp0___fifo_in1___width 1
+#define reg_iop_sw_mpu_r_intr_grp0___fifo_in1___bit 29
+#define reg_iop_sw_mpu_r_intr_grp0___fifo_in1_extra___lsb 30
+#define reg_iop_sw_mpu_r_intr_grp0___fifo_in1_extra___width 1
+#define reg_iop_sw_mpu_r_intr_grp0___fifo_in1_extra___bit 30
+#define reg_iop_sw_mpu_r_intr_grp0___dmc_in1___lsb 31
+#define reg_iop_sw_mpu_r_intr_grp0___dmc_in1___width 1
+#define reg_iop_sw_mpu_r_intr_grp0___dmc_in1___bit 31
+#define reg_iop_sw_mpu_r_intr_grp0_offset 104
+
+/* Register r_masked_intr_grp0, scope iop_sw_mpu, type r */
+#define reg_iop_sw_mpu_r_masked_intr_grp0___spu0_intr0___lsb 0
+#define reg_iop_sw_mpu_r_masked_intr_grp0___spu0_intr0___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp0___spu0_intr0___bit 0
+#define reg_iop_sw_mpu_r_masked_intr_grp0___spu1_intr0___lsb 1
+#define reg_iop_sw_mpu_r_masked_intr_grp0___spu1_intr0___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp0___spu1_intr0___bit 1
+#define reg_iop_sw_mpu_r_masked_intr_grp0___trigger_grp0___lsb 2
+#define reg_iop_sw_mpu_r_masked_intr_grp0___trigger_grp0___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp0___trigger_grp0___bit 2
+#define reg_iop_sw_mpu_r_masked_intr_grp0___trigger_grp4___lsb 3
+#define reg_iop_sw_mpu_r_masked_intr_grp0___trigger_grp4___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp0___trigger_grp4___bit 3
+#define reg_iop_sw_mpu_r_masked_intr_grp0___timer_grp0___lsb 4
+#define reg_iop_sw_mpu_r_masked_intr_grp0___timer_grp0___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp0___timer_grp0___bit 4
+#define reg_iop_sw_mpu_r_masked_intr_grp0___fifo_out0___lsb 5
+#define reg_iop_sw_mpu_r_masked_intr_grp0___fifo_out0___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp0___fifo_out0___bit 5
+#define reg_iop_sw_mpu_r_masked_intr_grp0___fifo_out0_extra___lsb 6
+#define reg_iop_sw_mpu_r_masked_intr_grp0___fifo_out0_extra___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp0___fifo_out0_extra___bit 6
+#define reg_iop_sw_mpu_r_masked_intr_grp0___dmc_out0___lsb 7
+#define reg_iop_sw_mpu_r_masked_intr_grp0___dmc_out0___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp0___dmc_out0___bit 7
+#define reg_iop_sw_mpu_r_masked_intr_grp0___spu0_intr1___lsb 8
+#define reg_iop_sw_mpu_r_masked_intr_grp0___spu0_intr1___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp0___spu0_intr1___bit 8
+#define reg_iop_sw_mpu_r_masked_intr_grp0___spu1_intr1___lsb 9
+#define reg_iop_sw_mpu_r_masked_intr_grp0___spu1_intr1___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp0___spu1_intr1___bit 9
+#define reg_iop_sw_mpu_r_masked_intr_grp0___trigger_grp1___lsb 10
+#define reg_iop_sw_mpu_r_masked_intr_grp0___trigger_grp1___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp0___trigger_grp1___bit 10
+#define reg_iop_sw_mpu_r_masked_intr_grp0___trigger_grp5___lsb 11
+#define reg_iop_sw_mpu_r_masked_intr_grp0___trigger_grp5___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp0___trigger_grp5___bit 11
+#define reg_iop_sw_mpu_r_masked_intr_grp0___timer_grp1___lsb 12
+#define reg_iop_sw_mpu_r_masked_intr_grp0___timer_grp1___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp0___timer_grp1___bit 12
+#define reg_iop_sw_mpu_r_masked_intr_grp0___fifo_in0___lsb 13
+#define reg_iop_sw_mpu_r_masked_intr_grp0___fifo_in0___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp0___fifo_in0___bit 13
+#define reg_iop_sw_mpu_r_masked_intr_grp0___fifo_in0_extra___lsb 14
+#define reg_iop_sw_mpu_r_masked_intr_grp0___fifo_in0_extra___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp0___fifo_in0_extra___bit 14
+#define reg_iop_sw_mpu_r_masked_intr_grp0___dmc_in0___lsb 15
+#define reg_iop_sw_mpu_r_masked_intr_grp0___dmc_in0___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp0___dmc_in0___bit 15
+#define reg_iop_sw_mpu_r_masked_intr_grp0___spu0_intr2___lsb 16
+#define reg_iop_sw_mpu_r_masked_intr_grp0___spu0_intr2___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp0___spu0_intr2___bit 16
+#define reg_iop_sw_mpu_r_masked_intr_grp0___spu1_intr2___lsb 17
+#define reg_iop_sw_mpu_r_masked_intr_grp0___spu1_intr2___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp0___spu1_intr2___bit 17
+#define reg_iop_sw_mpu_r_masked_intr_grp0___trigger_grp2___lsb 18
+#define reg_iop_sw_mpu_r_masked_intr_grp0___trigger_grp2___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp0___trigger_grp2___bit 18
+#define reg_iop_sw_mpu_r_masked_intr_grp0___trigger_grp6___lsb 19
+#define reg_iop_sw_mpu_r_masked_intr_grp0___trigger_grp6___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp0___trigger_grp6___bit 19
+#define reg_iop_sw_mpu_r_masked_intr_grp0___timer_grp2___lsb 20
+#define reg_iop_sw_mpu_r_masked_intr_grp0___timer_grp2___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp0___timer_grp2___bit 20
+#define reg_iop_sw_mpu_r_masked_intr_grp0___fifo_out1___lsb 21
+#define reg_iop_sw_mpu_r_masked_intr_grp0___fifo_out1___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp0___fifo_out1___bit 21
+#define reg_iop_sw_mpu_r_masked_intr_grp0___fifo_out1_extra___lsb 22
+#define reg_iop_sw_mpu_r_masked_intr_grp0___fifo_out1_extra___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp0___fifo_out1_extra___bit 22
+#define reg_iop_sw_mpu_r_masked_intr_grp0___dmc_out1___lsb 23
+#define reg_iop_sw_mpu_r_masked_intr_grp0___dmc_out1___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp0___dmc_out1___bit 23
+#define reg_iop_sw_mpu_r_masked_intr_grp0___spu0_intr3___lsb 24
+#define reg_iop_sw_mpu_r_masked_intr_grp0___spu0_intr3___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp0___spu0_intr3___bit 24
+#define reg_iop_sw_mpu_r_masked_intr_grp0___spu1_intr3___lsb 25
+#define reg_iop_sw_mpu_r_masked_intr_grp0___spu1_intr3___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp0___spu1_intr3___bit 25
+#define reg_iop_sw_mpu_r_masked_intr_grp0___trigger_grp3___lsb 26
+#define reg_iop_sw_mpu_r_masked_intr_grp0___trigger_grp3___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp0___trigger_grp3___bit 26
+#define reg_iop_sw_mpu_r_masked_intr_grp0___trigger_grp7___lsb 27
+#define reg_iop_sw_mpu_r_masked_intr_grp0___trigger_grp7___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp0___trigger_grp7___bit 27
+#define reg_iop_sw_mpu_r_masked_intr_grp0___timer_grp3___lsb 28
+#define reg_iop_sw_mpu_r_masked_intr_grp0___timer_grp3___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp0___timer_grp3___bit 28
+#define reg_iop_sw_mpu_r_masked_intr_grp0___fifo_in1___lsb 29
+#define reg_iop_sw_mpu_r_masked_intr_grp0___fifo_in1___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp0___fifo_in1___bit 29
+#define reg_iop_sw_mpu_r_masked_intr_grp0___fifo_in1_extra___lsb 30
+#define reg_iop_sw_mpu_r_masked_intr_grp0___fifo_in1_extra___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp0___fifo_in1_extra___bit 30
+#define reg_iop_sw_mpu_r_masked_intr_grp0___dmc_in1___lsb 31
+#define reg_iop_sw_mpu_r_masked_intr_grp0___dmc_in1___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp0___dmc_in1___bit 31
+#define reg_iop_sw_mpu_r_masked_intr_grp0_offset 108
+
+/* Register rw_intr_grp1_mask, scope iop_sw_mpu, type rw */
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___spu0_intr4___lsb 0
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___spu0_intr4___width 1
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___spu0_intr4___bit 0
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___spu1_intr4___lsb 1
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___spu1_intr4___width 1
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___spu1_intr4___bit 1
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___trigger_grp0___lsb 2
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___trigger_grp0___width 1
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___trigger_grp0___bit 2
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___trigger_grp5___lsb 3
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___trigger_grp5___width 1
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___trigger_grp5___bit 3
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___timer_grp0___lsb 4
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___timer_grp0___width 1
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___timer_grp0___bit 4
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___fifo_in0___lsb 5
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___fifo_in0___width 1
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___fifo_in0___bit 5
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___fifo_in0_extra___lsb 6
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___fifo_in0_extra___width 1
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___fifo_in0_extra___bit 6
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___dmc_out0___lsb 7
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___dmc_out0___width 1
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___dmc_out0___bit 7
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___spu0_intr5___lsb 8
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___spu0_intr5___width 1
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___spu0_intr5___bit 8
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___spu1_intr5___lsb 9
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___spu1_intr5___width 1
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___spu1_intr5___bit 9
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___trigger_grp1___lsb 10
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___trigger_grp1___width 1
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___trigger_grp1___bit 10
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___trigger_grp6___lsb 11
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___trigger_grp6___width 1
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___trigger_grp6___bit 11
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___timer_grp1___lsb 12
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___timer_grp1___width 1
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___timer_grp1___bit 12
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___fifo_out1___lsb 13
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___fifo_out1___width 1
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___fifo_out1___bit 13
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___fifo_out0_extra___lsb 14
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___fifo_out0_extra___width 1
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___fifo_out0_extra___bit 14
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___dmc_in0___lsb 15
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___dmc_in0___width 1
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___dmc_in0___bit 15
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___spu0_intr6___lsb 16
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___spu0_intr6___width 1
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___spu0_intr6___bit 16
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___spu1_intr6___lsb 17
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___spu1_intr6___width 1
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___spu1_intr6___bit 17
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___trigger_grp2___lsb 18
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___trigger_grp2___width 1
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___trigger_grp2___bit 18
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___trigger_grp7___lsb 19
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___trigger_grp7___width 1
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___trigger_grp7___bit 19
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___timer_grp2___lsb 20
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___timer_grp2___width 1
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___timer_grp2___bit 20
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___fifo_in1___lsb 21
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___fifo_in1___width 1
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___fifo_in1___bit 21
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___fifo_in1_extra___lsb 22
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___fifo_in1_extra___width 1
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___fifo_in1_extra___bit 22
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___dmc_out1___lsb 23
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___dmc_out1___width 1
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___dmc_out1___bit 23
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___spu0_intr7___lsb 24
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___spu0_intr7___width 1
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___spu0_intr7___bit 24
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___spu1_intr7___lsb 25
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___spu1_intr7___width 1
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___spu1_intr7___bit 25
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___trigger_grp3___lsb 26
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___trigger_grp3___width 1
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___trigger_grp3___bit 26
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___trigger_grp4___lsb 27
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___trigger_grp4___width 1
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___trigger_grp4___bit 27
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___timer_grp3___lsb 28
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___timer_grp3___width 1
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___timer_grp3___bit 28
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___fifo_out0___lsb 29
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___fifo_out0___width 1
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___fifo_out0___bit 29
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___fifo_out1_extra___lsb 30
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___fifo_out1_extra___width 1
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___fifo_out1_extra___bit 30
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___dmc_in1___lsb 31
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___dmc_in1___width 1
+#define reg_iop_sw_mpu_rw_intr_grp1_mask___dmc_in1___bit 31
+#define reg_iop_sw_mpu_rw_intr_grp1_mask_offset 112
+
+/* Register rw_ack_intr_grp1, scope iop_sw_mpu, type rw */
+#define reg_iop_sw_mpu_rw_ack_intr_grp1___spu0_intr4___lsb 0
+#define reg_iop_sw_mpu_rw_ack_intr_grp1___spu0_intr4___width 1
+#define reg_iop_sw_mpu_rw_ack_intr_grp1___spu0_intr4___bit 0
+#define reg_iop_sw_mpu_rw_ack_intr_grp1___spu1_intr4___lsb 1
+#define reg_iop_sw_mpu_rw_ack_intr_grp1___spu1_intr4___width 1
+#define reg_iop_sw_mpu_rw_ack_intr_grp1___spu1_intr4___bit 1
+#define reg_iop_sw_mpu_rw_ack_intr_grp1___spu0_intr5___lsb 8
+#define reg_iop_sw_mpu_rw_ack_intr_grp1___spu0_intr5___width 1
+#define reg_iop_sw_mpu_rw_ack_intr_grp1___spu0_intr5___bit 8
+#define reg_iop_sw_mpu_rw_ack_intr_grp1___spu1_intr5___lsb 9
+#define reg_iop_sw_mpu_rw_ack_intr_grp1___spu1_intr5___width 1
+#define reg_iop_sw_mpu_rw_ack_intr_grp1___spu1_intr5___bit 9
+#define reg_iop_sw_mpu_rw_ack_intr_grp1___spu0_intr6___lsb 16
+#define reg_iop_sw_mpu_rw_ack_intr_grp1___spu0_intr6___width 1
+#define reg_iop_sw_mpu_rw_ack_intr_grp1___spu0_intr6___bit 16
+#define reg_iop_sw_mpu_rw_ack_intr_grp1___spu1_intr6___lsb 17
+#define reg_iop_sw_mpu_rw_ack_intr_grp1___spu1_intr6___width 1
+#define reg_iop_sw_mpu_rw_ack_intr_grp1___spu1_intr6___bit 17
+#define reg_iop_sw_mpu_rw_ack_intr_grp1___spu0_intr7___lsb 24
+#define reg_iop_sw_mpu_rw_ack_intr_grp1___spu0_intr7___width 1
+#define reg_iop_sw_mpu_rw_ack_intr_grp1___spu0_intr7___bit 24
+#define reg_iop_sw_mpu_rw_ack_intr_grp1___spu1_intr7___lsb 25
+#define reg_iop_sw_mpu_rw_ack_intr_grp1___spu1_intr7___width 1
+#define reg_iop_sw_mpu_rw_ack_intr_grp1___spu1_intr7___bit 25
+#define reg_iop_sw_mpu_rw_ack_intr_grp1_offset 116
+
+/* Register r_intr_grp1, scope iop_sw_mpu, type r */
+#define reg_iop_sw_mpu_r_intr_grp1___spu0_intr4___lsb 0
+#define reg_iop_sw_mpu_r_intr_grp1___spu0_intr4___width 1
+#define reg_iop_sw_mpu_r_intr_grp1___spu0_intr4___bit 0
+#define reg_iop_sw_mpu_r_intr_grp1___spu1_intr4___lsb 1
+#define reg_iop_sw_mpu_r_intr_grp1___spu1_intr4___width 1
+#define reg_iop_sw_mpu_r_intr_grp1___spu1_intr4___bit 1
+#define reg_iop_sw_mpu_r_intr_grp1___trigger_grp0___lsb 2
+#define reg_iop_sw_mpu_r_intr_grp1___trigger_grp0___width 1
+#define reg_iop_sw_mpu_r_intr_grp1___trigger_grp0___bit 2
+#define reg_iop_sw_mpu_r_intr_grp1___trigger_grp5___lsb 3
+#define reg_iop_sw_mpu_r_intr_grp1___trigger_grp5___width 1
+#define reg_iop_sw_mpu_r_intr_grp1___trigger_grp5___bit 3
+#define reg_iop_sw_mpu_r_intr_grp1___timer_grp0___lsb 4
+#define reg_iop_sw_mpu_r_intr_grp1___timer_grp0___width 1
+#define reg_iop_sw_mpu_r_intr_grp1___timer_grp0___bit 4
+#define reg_iop_sw_mpu_r_intr_grp1___fifo_in0___lsb 5
+#define reg_iop_sw_mpu_r_intr_grp1___fifo_in0___width 1
+#define reg_iop_sw_mpu_r_intr_grp1___fifo_in0___bit 5
+#define reg_iop_sw_mpu_r_intr_grp1___fifo_in0_extra___lsb 6
+#define reg_iop_sw_mpu_r_intr_grp1___fifo_in0_extra___width 1
+#define reg_iop_sw_mpu_r_intr_grp1___fifo_in0_extra___bit 6
+#define reg_iop_sw_mpu_r_intr_grp1___dmc_out0___lsb 7
+#define reg_iop_sw_mpu_r_intr_grp1___dmc_out0___width 1
+#define reg_iop_sw_mpu_r_intr_grp1___dmc_out0___bit 7
+#define reg_iop_sw_mpu_r_intr_grp1___spu0_intr5___lsb 8
+#define reg_iop_sw_mpu_r_intr_grp1___spu0_intr5___width 1
+#define reg_iop_sw_mpu_r_intr_grp1___spu0_intr5___bit 8
+#define reg_iop_sw_mpu_r_intr_grp1___spu1_intr5___lsb 9
+#define reg_iop_sw_mpu_r_intr_grp1___spu1_intr5___width 1
+#define reg_iop_sw_mpu_r_intr_grp1___spu1_intr5___bit 9
+#define reg_iop_sw_mpu_r_intr_grp1___trigger_grp1___lsb 10
+#define reg_iop_sw_mpu_r_intr_grp1___trigger_grp1___width 1
+#define reg_iop_sw_mpu_r_intr_grp1___trigger_grp1___bit 10
+#define reg_iop_sw_mpu_r_intr_grp1___trigger_grp6___lsb 11
+#define reg_iop_sw_mpu_r_intr_grp1___trigger_grp6___width 1
+#define reg_iop_sw_mpu_r_intr_grp1___trigger_grp6___bit 11
+#define reg_iop_sw_mpu_r_intr_grp1___timer_grp1___lsb 12
+#define reg_iop_sw_mpu_r_intr_grp1___timer_grp1___width 1
+#define reg_iop_sw_mpu_r_intr_grp1___timer_grp1___bit 12
+#define reg_iop_sw_mpu_r_intr_grp1___fifo_out1___lsb 13
+#define reg_iop_sw_mpu_r_intr_grp1___fifo_out1___width 1
+#define reg_iop_sw_mpu_r_intr_grp1___fifo_out1___bit 13
+#define reg_iop_sw_mpu_r_intr_grp1___fifo_out0_extra___lsb 14
+#define reg_iop_sw_mpu_r_intr_grp1___fifo_out0_extra___width 1
+#define reg_iop_sw_mpu_r_intr_grp1___fifo_out0_extra___bit 14
+#define reg_iop_sw_mpu_r_intr_grp1___dmc_in0___lsb 15
+#define reg_iop_sw_mpu_r_intr_grp1___dmc_in0___width 1
+#define reg_iop_sw_mpu_r_intr_grp1___dmc_in0___bit 15
+#define reg_iop_sw_mpu_r_intr_grp1___spu0_intr6___lsb 16
+#define reg_iop_sw_mpu_r_intr_grp1___spu0_intr6___width 1
+#define reg_iop_sw_mpu_r_intr_grp1___spu0_intr6___bit 16
+#define reg_iop_sw_mpu_r_intr_grp1___spu1_intr6___lsb 17
+#define reg_iop_sw_mpu_r_intr_grp1___spu1_intr6___width 1
+#define reg_iop_sw_mpu_r_intr_grp1___spu1_intr6___bit 17
+#define reg_iop_sw_mpu_r_intr_grp1___trigger_grp2___lsb 18
+#define reg_iop_sw_mpu_r_intr_grp1___trigger_grp2___width 1
+#define reg_iop_sw_mpu_r_intr_grp1___trigger_grp2___bit 18
+#define reg_iop_sw_mpu_r_intr_grp1___trigger_grp7___lsb 19
+#define reg_iop_sw_mpu_r_intr_grp1___trigger_grp7___width 1
+#define reg_iop_sw_mpu_r_intr_grp1___trigger_grp7___bit 19
+#define reg_iop_sw_mpu_r_intr_grp1___timer_grp2___lsb 20
+#define reg_iop_sw_mpu_r_intr_grp1___timer_grp2___width 1
+#define reg_iop_sw_mpu_r_intr_grp1___timer_grp2___bit 20
+#define reg_iop_sw_mpu_r_intr_grp1___fifo_in1___lsb 21
+#define reg_iop_sw_mpu_r_intr_grp1___fifo_in1___width 1
+#define reg_iop_sw_mpu_r_intr_grp1___fifo_in1___bit 21
+#define reg_iop_sw_mpu_r_intr_grp1___fifo_in1_extra___lsb 22
+#define reg_iop_sw_mpu_r_intr_grp1___fifo_in1_extra___width 1
+#define reg_iop_sw_mpu_r_intr_grp1___fifo_in1_extra___bit 22
+#define reg_iop_sw_mpu_r_intr_grp1___dmc_out1___lsb 23
+#define reg_iop_sw_mpu_r_intr_grp1___dmc_out1___width 1
+#define reg_iop_sw_mpu_r_intr_grp1___dmc_out1___bit 23
+#define reg_iop_sw_mpu_r_intr_grp1___spu0_intr7___lsb 24
+#define reg_iop_sw_mpu_r_intr_grp1___spu0_intr7___width 1
+#define reg_iop_sw_mpu_r_intr_grp1___spu0_intr7___bit 24
+#define reg_iop_sw_mpu_r_intr_grp1___spu1_intr7___lsb 25
+#define reg_iop_sw_mpu_r_intr_grp1___spu1_intr7___width 1
+#define reg_iop_sw_mpu_r_intr_grp1___spu1_intr7___bit 25
+#define reg_iop_sw_mpu_r_intr_grp1___trigger_grp3___lsb 26
+#define reg_iop_sw_mpu_r_intr_grp1___trigger_grp3___width 1
+#define reg_iop_sw_mpu_r_intr_grp1___trigger_grp3___bit 26
+#define reg_iop_sw_mpu_r_intr_grp1___trigger_grp4___lsb 27
+#define reg_iop_sw_mpu_r_intr_grp1___trigger_grp4___width 1
+#define reg_iop_sw_mpu_r_intr_grp1___trigger_grp4___bit 27
+#define reg_iop_sw_mpu_r_intr_grp1___timer_grp3___lsb 28
+#define reg_iop_sw_mpu_r_intr_grp1___timer_grp3___width 1
+#define reg_iop_sw_mpu_r_intr_grp1___timer_grp3___bit 28
+#define reg_iop_sw_mpu_r_intr_grp1___fifo_out0___lsb 29
+#define reg_iop_sw_mpu_r_intr_grp1___fifo_out0___width 1
+#define reg_iop_sw_mpu_r_intr_grp1___fifo_out0___bit 29
+#define reg_iop_sw_mpu_r_intr_grp1___fifo_out1_extra___lsb 30
+#define reg_iop_sw_mpu_r_intr_grp1___fifo_out1_extra___width 1
+#define reg_iop_sw_mpu_r_intr_grp1___fifo_out1_extra___bit 30
+#define reg_iop_sw_mpu_r_intr_grp1___dmc_in1___lsb 31
+#define reg_iop_sw_mpu_r_intr_grp1___dmc_in1___width 1
+#define reg_iop_sw_mpu_r_intr_grp1___dmc_in1___bit 31
+#define reg_iop_sw_mpu_r_intr_grp1_offset 120
+
+/* Register r_masked_intr_grp1, scope iop_sw_mpu, type r */
+#define reg_iop_sw_mpu_r_masked_intr_grp1___spu0_intr4___lsb 0
+#define reg_iop_sw_mpu_r_masked_intr_grp1___spu0_intr4___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp1___spu0_intr4___bit 0
+#define reg_iop_sw_mpu_r_masked_intr_grp1___spu1_intr4___lsb 1
+#define reg_iop_sw_mpu_r_masked_intr_grp1___spu1_intr4___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp1___spu1_intr4___bit 1
+#define reg_iop_sw_mpu_r_masked_intr_grp1___trigger_grp0___lsb 2
+#define reg_iop_sw_mpu_r_masked_intr_grp1___trigger_grp0___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp1___trigger_grp0___bit 2
+#define reg_iop_sw_mpu_r_masked_intr_grp1___trigger_grp5___lsb 3
+#define reg_iop_sw_mpu_r_masked_intr_grp1___trigger_grp5___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp1___trigger_grp5___bit 3
+#define reg_iop_sw_mpu_r_masked_intr_grp1___timer_grp0___lsb 4
+#define reg_iop_sw_mpu_r_masked_intr_grp1___timer_grp0___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp1___timer_grp0___bit 4
+#define reg_iop_sw_mpu_r_masked_intr_grp1___fifo_in0___lsb 5
+#define reg_iop_sw_mpu_r_masked_intr_grp1___fifo_in0___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp1___fifo_in0___bit 5
+#define reg_iop_sw_mpu_r_masked_intr_grp1___fifo_in0_extra___lsb 6
+#define reg_iop_sw_mpu_r_masked_intr_grp1___fifo_in0_extra___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp1___fifo_in0_extra___bit 6
+#define reg_iop_sw_mpu_r_masked_intr_grp1___dmc_out0___lsb 7
+#define reg_iop_sw_mpu_r_masked_intr_grp1___dmc_out0___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp1___dmc_out0___bit 7
+#define reg_iop_sw_mpu_r_masked_intr_grp1___spu0_intr5___lsb 8
+#define reg_iop_sw_mpu_r_masked_intr_grp1___spu0_intr5___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp1___spu0_intr5___bit 8
+#define reg_iop_sw_mpu_r_masked_intr_grp1___spu1_intr5___lsb 9
+#define reg_iop_sw_mpu_r_masked_intr_grp1___spu1_intr5___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp1___spu1_intr5___bit 9
+#define reg_iop_sw_mpu_r_masked_intr_grp1___trigger_grp1___lsb 10
+#define reg_iop_sw_mpu_r_masked_intr_grp1___trigger_grp1___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp1___trigger_grp1___bit 10
+#define reg_iop_sw_mpu_r_masked_intr_grp1___trigger_grp6___lsb 11
+#define reg_iop_sw_mpu_r_masked_intr_grp1___trigger_grp6___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp1___trigger_grp6___bit 11
+#define reg_iop_sw_mpu_r_masked_intr_grp1___timer_grp1___lsb 12
+#define reg_iop_sw_mpu_r_masked_intr_grp1___timer_grp1___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp1___timer_grp1___bit 12
+#define reg_iop_sw_mpu_r_masked_intr_grp1___fifo_out1___lsb 13
+#define reg_iop_sw_mpu_r_masked_intr_grp1___fifo_out1___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp1___fifo_out1___bit 13
+#define reg_iop_sw_mpu_r_masked_intr_grp1___fifo_out0_extra___lsb 14
+#define reg_iop_sw_mpu_r_masked_intr_grp1___fifo_out0_extra___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp1___fifo_out0_extra___bit 14
+#define reg_iop_sw_mpu_r_masked_intr_grp1___dmc_in0___lsb 15
+#define reg_iop_sw_mpu_r_masked_intr_grp1___dmc_in0___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp1___dmc_in0___bit 15
+#define reg_iop_sw_mpu_r_masked_intr_grp1___spu0_intr6___lsb 16
+#define reg_iop_sw_mpu_r_masked_intr_grp1___spu0_intr6___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp1___spu0_intr6___bit 16
+#define reg_iop_sw_mpu_r_masked_intr_grp1___spu1_intr6___lsb 17
+#define reg_iop_sw_mpu_r_masked_intr_grp1___spu1_intr6___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp1___spu1_intr6___bit 17
+#define reg_iop_sw_mpu_r_masked_intr_grp1___trigger_grp2___lsb 18
+#define reg_iop_sw_mpu_r_masked_intr_grp1___trigger_grp2___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp1___trigger_grp2___bit 18
+#define reg_iop_sw_mpu_r_masked_intr_grp1___trigger_grp7___lsb 19
+#define reg_iop_sw_mpu_r_masked_intr_grp1___trigger_grp7___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp1___trigger_grp7___bit 19
+#define reg_iop_sw_mpu_r_masked_intr_grp1___timer_grp2___lsb 20
+#define reg_iop_sw_mpu_r_masked_intr_grp1___timer_grp2___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp1___timer_grp2___bit 20
+#define reg_iop_sw_mpu_r_masked_intr_grp1___fifo_in1___lsb 21
+#define reg_iop_sw_mpu_r_masked_intr_grp1___fifo_in1___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp1___fifo_in1___bit 21
+#define reg_iop_sw_mpu_r_masked_intr_grp1___fifo_in1_extra___lsb 22
+#define reg_iop_sw_mpu_r_masked_intr_grp1___fifo_in1_extra___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp1___fifo_in1_extra___bit 22
+#define reg_iop_sw_mpu_r_masked_intr_grp1___dmc_out1___lsb 23
+#define reg_iop_sw_mpu_r_masked_intr_grp1___dmc_out1___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp1___dmc_out1___bit 23
+#define reg_iop_sw_mpu_r_masked_intr_grp1___spu0_intr7___lsb 24
+#define reg_iop_sw_mpu_r_masked_intr_grp1___spu0_intr7___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp1___spu0_intr7___bit 24
+#define reg_iop_sw_mpu_r_masked_intr_grp1___spu1_intr7___lsb 25
+#define reg_iop_sw_mpu_r_masked_intr_grp1___spu1_intr7___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp1___spu1_intr7___bit 25
+#define reg_iop_sw_mpu_r_masked_intr_grp1___trigger_grp3___lsb 26
+#define reg_iop_sw_mpu_r_masked_intr_grp1___trigger_grp3___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp1___trigger_grp3___bit 26
+#define reg_iop_sw_mpu_r_masked_intr_grp1___trigger_grp4___lsb 27
+#define reg_iop_sw_mpu_r_masked_intr_grp1___trigger_grp4___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp1___trigger_grp4___bit 27
+#define reg_iop_sw_mpu_r_masked_intr_grp1___timer_grp3___lsb 28
+#define reg_iop_sw_mpu_r_masked_intr_grp1___timer_grp3___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp1___timer_grp3___bit 28
+#define reg_iop_sw_mpu_r_masked_intr_grp1___fifo_out0___lsb 29
+#define reg_iop_sw_mpu_r_masked_intr_grp1___fifo_out0___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp1___fifo_out0___bit 29
+#define reg_iop_sw_mpu_r_masked_intr_grp1___fifo_out1_extra___lsb 30
+#define reg_iop_sw_mpu_r_masked_intr_grp1___fifo_out1_extra___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp1___fifo_out1_extra___bit 30
+#define reg_iop_sw_mpu_r_masked_intr_grp1___dmc_in1___lsb 31
+#define reg_iop_sw_mpu_r_masked_intr_grp1___dmc_in1___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp1___dmc_in1___bit 31
+#define reg_iop_sw_mpu_r_masked_intr_grp1_offset 124
+
+/* Register rw_intr_grp2_mask, scope iop_sw_mpu, type rw */
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___spu0_intr8___lsb 0
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___spu0_intr8___width 1
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___spu0_intr8___bit 0
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___spu1_intr8___lsb 1
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___spu1_intr8___width 1
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___spu1_intr8___bit 1
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___trigger_grp0___lsb 2
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___trigger_grp0___width 1
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___trigger_grp0___bit 2
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___trigger_grp6___lsb 3
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___trigger_grp6___width 1
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___trigger_grp6___bit 3
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___timer_grp0___lsb 4
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___timer_grp0___width 1
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___timer_grp0___bit 4
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___fifo_out1___lsb 5
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___fifo_out1___width 1
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___fifo_out1___bit 5
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___fifo_out1_extra___lsb 6
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___fifo_out1_extra___width 1
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___fifo_out1_extra___bit 6
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___dmc_out0___lsb 7
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___dmc_out0___width 1
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___dmc_out0___bit 7
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___spu0_intr9___lsb 8
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___spu0_intr9___width 1
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___spu0_intr9___bit 8
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___spu1_intr9___lsb 9
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___spu1_intr9___width 1
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___spu1_intr9___bit 9
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___trigger_grp1___lsb 10
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___trigger_grp1___width 1
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___trigger_grp1___bit 10
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___trigger_grp7___lsb 11
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___trigger_grp7___width 1
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___trigger_grp7___bit 11
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___timer_grp1___lsb 12
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___timer_grp1___width 1
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___timer_grp1___bit 12
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___fifo_in1___lsb 13
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___fifo_in1___width 1
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___fifo_in1___bit 13
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___fifo_in1_extra___lsb 14
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___fifo_in1_extra___width 1
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___fifo_in1_extra___bit 14
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___dmc_in0___lsb 15
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___dmc_in0___width 1
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___dmc_in0___bit 15
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___spu0_intr10___lsb 16
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___spu0_intr10___width 1
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___spu0_intr10___bit 16
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___spu1_intr10___lsb 17
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___spu1_intr10___width 1
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___spu1_intr10___bit 17
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___trigger_grp2___lsb 18
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___trigger_grp2___width 1
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___trigger_grp2___bit 18
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___trigger_grp4___lsb 19
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___trigger_grp4___width 1
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___trigger_grp4___bit 19
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___timer_grp2___lsb 20
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___timer_grp2___width 1
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___timer_grp2___bit 20
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___fifo_out0___lsb 21
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___fifo_out0___width 1
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___fifo_out0___bit 21
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___fifo_out0_extra___lsb 22
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___fifo_out0_extra___width 1
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___fifo_out0_extra___bit 22
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___dmc_out1___lsb 23
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___dmc_out1___width 1
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___dmc_out1___bit 23
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___spu0_intr11___lsb 24
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___spu0_intr11___width 1
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___spu0_intr11___bit 24
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___spu1_intr11___lsb 25
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___spu1_intr11___width 1
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___spu1_intr11___bit 25
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___trigger_grp3___lsb 26
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___trigger_grp3___width 1
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___trigger_grp3___bit 26
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___trigger_grp5___lsb 27
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___trigger_grp5___width 1
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___trigger_grp5___bit 27
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___timer_grp3___lsb 28
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___timer_grp3___width 1
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___timer_grp3___bit 28
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___fifo_in0___lsb 29
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___fifo_in0___width 1
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___fifo_in0___bit 29
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___fifo_in0_extra___lsb 30
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___fifo_in0_extra___width 1
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___fifo_in0_extra___bit 30
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___dmc_in1___lsb 31
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___dmc_in1___width 1
+#define reg_iop_sw_mpu_rw_intr_grp2_mask___dmc_in1___bit 31
+#define reg_iop_sw_mpu_rw_intr_grp2_mask_offset 128
+
+/* Register rw_ack_intr_grp2, scope iop_sw_mpu, type rw */
+#define reg_iop_sw_mpu_rw_ack_intr_grp2___spu0_intr8___lsb 0
+#define reg_iop_sw_mpu_rw_ack_intr_grp2___spu0_intr8___width 1
+#define reg_iop_sw_mpu_rw_ack_intr_grp2___spu0_intr8___bit 0
+#define reg_iop_sw_mpu_rw_ack_intr_grp2___spu1_intr8___lsb 1
+#define reg_iop_sw_mpu_rw_ack_intr_grp2___spu1_intr8___width 1
+#define reg_iop_sw_mpu_rw_ack_intr_grp2___spu1_intr8___bit 1
+#define reg_iop_sw_mpu_rw_ack_intr_grp2___spu0_intr9___lsb 8
+#define reg_iop_sw_mpu_rw_ack_intr_grp2___spu0_intr9___width 1
+#define reg_iop_sw_mpu_rw_ack_intr_grp2___spu0_intr9___bit 8
+#define reg_iop_sw_mpu_rw_ack_intr_grp2___spu1_intr9___lsb 9
+#define reg_iop_sw_mpu_rw_ack_intr_grp2___spu1_intr9___width 1
+#define reg_iop_sw_mpu_rw_ack_intr_grp2___spu1_intr9___bit 9
+#define reg_iop_sw_mpu_rw_ack_intr_grp2___spu0_intr10___lsb 16
+#define reg_iop_sw_mpu_rw_ack_intr_grp2___spu0_intr10___width 1
+#define reg_iop_sw_mpu_rw_ack_intr_grp2___spu0_intr10___bit 16
+#define reg_iop_sw_mpu_rw_ack_intr_grp2___spu1_intr10___lsb 17
+#define reg_iop_sw_mpu_rw_ack_intr_grp2___spu1_intr10___width 1
+#define reg_iop_sw_mpu_rw_ack_intr_grp2___spu1_intr10___bit 17
+#define reg_iop_sw_mpu_rw_ack_intr_grp2___spu0_intr11___lsb 24
+#define reg_iop_sw_mpu_rw_ack_intr_grp2___spu0_intr11___width 1
+#define reg_iop_sw_mpu_rw_ack_intr_grp2___spu0_intr11___bit 24
+#define reg_iop_sw_mpu_rw_ack_intr_grp2___spu1_intr11___lsb 25
+#define reg_iop_sw_mpu_rw_ack_intr_grp2___spu1_intr11___width 1
+#define reg_iop_sw_mpu_rw_ack_intr_grp2___spu1_intr11___bit 25
+#define reg_iop_sw_mpu_rw_ack_intr_grp2_offset 132
+
+/* Register r_intr_grp2, scope iop_sw_mpu, type r */
+#define reg_iop_sw_mpu_r_intr_grp2___spu0_intr8___lsb 0
+#define reg_iop_sw_mpu_r_intr_grp2___spu0_intr8___width 1
+#define reg_iop_sw_mpu_r_intr_grp2___spu0_intr8___bit 0
+#define reg_iop_sw_mpu_r_intr_grp2___spu1_intr8___lsb 1
+#define reg_iop_sw_mpu_r_intr_grp2___spu1_intr8___width 1
+#define reg_iop_sw_mpu_r_intr_grp2___spu1_intr8___bit 1
+#define reg_iop_sw_mpu_r_intr_grp2___trigger_grp0___lsb 2
+#define reg_iop_sw_mpu_r_intr_grp2___trigger_grp0___width 1
+#define reg_iop_sw_mpu_r_intr_grp2___trigger_grp0___bit 2
+#define reg_iop_sw_mpu_r_intr_grp2___trigger_grp6___lsb 3
+#define reg_iop_sw_mpu_r_intr_grp2___trigger_grp6___width 1
+#define reg_iop_sw_mpu_r_intr_grp2___trigger_grp6___bit 3
+#define reg_iop_sw_mpu_r_intr_grp2___timer_grp0___lsb 4
+#define reg_iop_sw_mpu_r_intr_grp2___timer_grp0___width 1
+#define reg_iop_sw_mpu_r_intr_grp2___timer_grp0___bit 4
+#define reg_iop_sw_mpu_r_intr_grp2___fifo_out1___lsb 5
+#define reg_iop_sw_mpu_r_intr_grp2___fifo_out1___width 1
+#define reg_iop_sw_mpu_r_intr_grp2___fifo_out1___bit 5
+#define reg_iop_sw_mpu_r_intr_grp2___fifo_out1_extra___lsb 6
+#define reg_iop_sw_mpu_r_intr_grp2___fifo_out1_extra___width 1
+#define reg_iop_sw_mpu_r_intr_grp2___fifo_out1_extra___bit 6
+#define reg_iop_sw_mpu_r_intr_grp2___dmc_out0___lsb 7
+#define reg_iop_sw_mpu_r_intr_grp2___dmc_out0___width 1
+#define reg_iop_sw_mpu_r_intr_grp2___dmc_out0___bit 7
+#define reg_iop_sw_mpu_r_intr_grp2___spu0_intr9___lsb 8
+#define reg_iop_sw_mpu_r_intr_grp2___spu0_intr9___width 1
+#define reg_iop_sw_mpu_r_intr_grp2___spu0_intr9___bit 8
+#define reg_iop_sw_mpu_r_intr_grp2___spu1_intr9___lsb 9
+#define reg_iop_sw_mpu_r_intr_grp2___spu1_intr9___width 1
+#define reg_iop_sw_mpu_r_intr_grp2___spu1_intr9___bit 9
+#define reg_iop_sw_mpu_r_intr_grp2___trigger_grp1___lsb 10
+#define reg_iop_sw_mpu_r_intr_grp2___trigger_grp1___width 1
+#define reg_iop_sw_mpu_r_intr_grp2___trigger_grp1___bit 10
+#define reg_iop_sw_mpu_r_intr_grp2___trigger_grp7___lsb 11
+#define reg_iop_sw_mpu_r_intr_grp2___trigger_grp7___width 1
+#define reg_iop_sw_mpu_r_intr_grp2___trigger_grp7___bit 11
+#define reg_iop_sw_mpu_r_intr_grp2___timer_grp1___lsb 12
+#define reg_iop_sw_mpu_r_intr_grp2___timer_grp1___width 1
+#define reg_iop_sw_mpu_r_intr_grp2___timer_grp1___bit 12
+#define reg_iop_sw_mpu_r_intr_grp2___fifo_in1___lsb 13
+#define reg_iop_sw_mpu_r_intr_grp2___fifo_in1___width 1
+#define reg_iop_sw_mpu_r_intr_grp2___fifo_in1___bit 13
+#define reg_iop_sw_mpu_r_intr_grp2___fifo_in1_extra___lsb 14
+#define reg_iop_sw_mpu_r_intr_grp2___fifo_in1_extra___width 1
+#define reg_iop_sw_mpu_r_intr_grp2___fifo_in1_extra___bit 14
+#define reg_iop_sw_mpu_r_intr_grp2___dmc_in0___lsb 15
+#define reg_iop_sw_mpu_r_intr_grp2___dmc_in0___width 1
+#define reg_iop_sw_mpu_r_intr_grp2___dmc_in0___bit 15
+#define reg_iop_sw_mpu_r_intr_grp2___spu0_intr10___lsb 16
+#define reg_iop_sw_mpu_r_intr_grp2___spu0_intr10___width 1
+#define reg_iop_sw_mpu_r_intr_grp2___spu0_intr10___bit 16
+#define reg_iop_sw_mpu_r_intr_grp2___spu1_intr10___lsb 17
+#define reg_iop_sw_mpu_r_intr_grp2___spu1_intr10___width 1
+#define reg_iop_sw_mpu_r_intr_grp2___spu1_intr10___bit 17
+#define reg_iop_sw_mpu_r_intr_grp2___trigger_grp2___lsb 18
+#define reg_iop_sw_mpu_r_intr_grp2___trigger_grp2___width 1
+#define reg_iop_sw_mpu_r_intr_grp2___trigger_grp2___bit 18
+#define reg_iop_sw_mpu_r_intr_grp2___trigger_grp4___lsb 19
+#define reg_iop_sw_mpu_r_intr_grp2___trigger_grp4___width 1
+#define reg_iop_sw_mpu_r_intr_grp2___trigger_grp4___bit 19
+#define reg_iop_sw_mpu_r_intr_grp2___timer_grp2___lsb 20
+#define reg_iop_sw_mpu_r_intr_grp2___timer_grp2___width 1
+#define reg_iop_sw_mpu_r_intr_grp2___timer_grp2___bit 20
+#define reg_iop_sw_mpu_r_intr_grp2___fifo_out0___lsb 21
+#define reg_iop_sw_mpu_r_intr_grp2___fifo_out0___width 1
+#define reg_iop_sw_mpu_r_intr_grp2___fifo_out0___bit 21
+#define reg_iop_sw_mpu_r_intr_grp2___fifo_out0_extra___lsb 22
+#define reg_iop_sw_mpu_r_intr_grp2___fifo_out0_extra___width 1
+#define reg_iop_sw_mpu_r_intr_grp2___fifo_out0_extra___bit 22
+#define reg_iop_sw_mpu_r_intr_grp2___dmc_out1___lsb 23
+#define reg_iop_sw_mpu_r_intr_grp2___dmc_out1___width 1
+#define reg_iop_sw_mpu_r_intr_grp2___dmc_out1___bit 23
+#define reg_iop_sw_mpu_r_intr_grp2___spu0_intr11___lsb 24
+#define reg_iop_sw_mpu_r_intr_grp2___spu0_intr11___width 1
+#define reg_iop_sw_mpu_r_intr_grp2___spu0_intr11___bit 24
+#define reg_iop_sw_mpu_r_intr_grp2___spu1_intr11___lsb 25
+#define reg_iop_sw_mpu_r_intr_grp2___spu1_intr11___width 1
+#define reg_iop_sw_mpu_r_intr_grp2___spu1_intr11___bit 25
+#define reg_iop_sw_mpu_r_intr_grp2___trigger_grp3___lsb 26
+#define reg_iop_sw_mpu_r_intr_grp2___trigger_grp3___width 1
+#define reg_iop_sw_mpu_r_intr_grp2___trigger_grp3___bit 26
+#define reg_iop_sw_mpu_r_intr_grp2___trigger_grp5___lsb 27
+#define reg_iop_sw_mpu_r_intr_grp2___trigger_grp5___width 1
+#define reg_iop_sw_mpu_r_intr_grp2___trigger_grp5___bit 27
+#define reg_iop_sw_mpu_r_intr_grp2___timer_grp3___lsb 28
+#define reg_iop_sw_mpu_r_intr_grp2___timer_grp3___width 1
+#define reg_iop_sw_mpu_r_intr_grp2___timer_grp3___bit 28
+#define reg_iop_sw_mpu_r_intr_grp2___fifo_in0___lsb 29
+#define reg_iop_sw_mpu_r_intr_grp2___fifo_in0___width 1
+#define reg_iop_sw_mpu_r_intr_grp2___fifo_in0___bit 29
+#define reg_iop_sw_mpu_r_intr_grp2___fifo_in0_extra___lsb 30
+#define reg_iop_sw_mpu_r_intr_grp2___fifo_in0_extra___width 1
+#define reg_iop_sw_mpu_r_intr_grp2___fifo_in0_extra___bit 30
+#define reg_iop_sw_mpu_r_intr_grp2___dmc_in1___lsb 31
+#define reg_iop_sw_mpu_r_intr_grp2___dmc_in1___width 1
+#define reg_iop_sw_mpu_r_intr_grp2___dmc_in1___bit 31
+#define reg_iop_sw_mpu_r_intr_grp2_offset 136
+
+/* Register r_masked_intr_grp2, scope iop_sw_mpu, type r */
+#define reg_iop_sw_mpu_r_masked_intr_grp2___spu0_intr8___lsb 0
+#define reg_iop_sw_mpu_r_masked_intr_grp2___spu0_intr8___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp2___spu0_intr8___bit 0
+#define reg_iop_sw_mpu_r_masked_intr_grp2___spu1_intr8___lsb 1
+#define reg_iop_sw_mpu_r_masked_intr_grp2___spu1_intr8___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp2___spu1_intr8___bit 1
+#define reg_iop_sw_mpu_r_masked_intr_grp2___trigger_grp0___lsb 2
+#define reg_iop_sw_mpu_r_masked_intr_grp2___trigger_grp0___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp2___trigger_grp0___bit 2
+#define reg_iop_sw_mpu_r_masked_intr_grp2___trigger_grp6___lsb 3
+#define reg_iop_sw_mpu_r_masked_intr_grp2___trigger_grp6___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp2___trigger_grp6___bit 3
+#define reg_iop_sw_mpu_r_masked_intr_grp2___timer_grp0___lsb 4
+#define reg_iop_sw_mpu_r_masked_intr_grp2___timer_grp0___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp2___timer_grp0___bit 4
+#define reg_iop_sw_mpu_r_masked_intr_grp2___fifo_out1___lsb 5
+#define reg_iop_sw_mpu_r_masked_intr_grp2___fifo_out1___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp2___fifo_out1___bit 5
+#define reg_iop_sw_mpu_r_masked_intr_grp2___fifo_out1_extra___lsb 6
+#define reg_iop_sw_mpu_r_masked_intr_grp2___fifo_out1_extra___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp2___fifo_out1_extra___bit 6
+#define reg_iop_sw_mpu_r_masked_intr_grp2___dmc_out0___lsb 7
+#define reg_iop_sw_mpu_r_masked_intr_grp2___dmc_out0___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp2___dmc_out0___bit 7
+#define reg_iop_sw_mpu_r_masked_intr_grp2___spu0_intr9___lsb 8
+#define reg_iop_sw_mpu_r_masked_intr_grp2___spu0_intr9___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp2___spu0_intr9___bit 8
+#define reg_iop_sw_mpu_r_masked_intr_grp2___spu1_intr9___lsb 9
+#define reg_iop_sw_mpu_r_masked_intr_grp2___spu1_intr9___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp2___spu1_intr9___bit 9
+#define reg_iop_sw_mpu_r_masked_intr_grp2___trigger_grp1___lsb 10
+#define reg_iop_sw_mpu_r_masked_intr_grp2___trigger_grp1___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp2___trigger_grp1___bit 10
+#define reg_iop_sw_mpu_r_masked_intr_grp2___trigger_grp7___lsb 11
+#define reg_iop_sw_mpu_r_masked_intr_grp2___trigger_grp7___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp2___trigger_grp7___bit 11
+#define reg_iop_sw_mpu_r_masked_intr_grp2___timer_grp1___lsb 12
+#define reg_iop_sw_mpu_r_masked_intr_grp2___timer_grp1___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp2___timer_grp1___bit 12
+#define reg_iop_sw_mpu_r_masked_intr_grp2___fifo_in1___lsb 13
+#define reg_iop_sw_mpu_r_masked_intr_grp2___fifo_in1___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp2___fifo_in1___bit 13
+#define reg_iop_sw_mpu_r_masked_intr_grp2___fifo_in1_extra___lsb 14
+#define reg_iop_sw_mpu_r_masked_intr_grp2___fifo_in1_extra___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp2___fifo_in1_extra___bit 14
+#define reg_iop_sw_mpu_r_masked_intr_grp2___dmc_in0___lsb 15
+#define reg_iop_sw_mpu_r_masked_intr_grp2___dmc_in0___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp2___dmc_in0___bit 15
+#define reg_iop_sw_mpu_r_masked_intr_grp2___spu0_intr10___lsb 16
+#define reg_iop_sw_mpu_r_masked_intr_grp2___spu0_intr10___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp2___spu0_intr10___bit 16
+#define reg_iop_sw_mpu_r_masked_intr_grp2___spu1_intr10___lsb 17
+#define reg_iop_sw_mpu_r_masked_intr_grp2___spu1_intr10___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp2___spu1_intr10___bit 17
+#define reg_iop_sw_mpu_r_masked_intr_grp2___trigger_grp2___lsb 18
+#define reg_iop_sw_mpu_r_masked_intr_grp2___trigger_grp2___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp2___trigger_grp2___bit 18
+#define reg_iop_sw_mpu_r_masked_intr_grp2___trigger_grp4___lsb 19
+#define reg_iop_sw_mpu_r_masked_intr_grp2___trigger_grp4___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp2___trigger_grp4___bit 19
+#define reg_iop_sw_mpu_r_masked_intr_grp2___timer_grp2___lsb 20
+#define reg_iop_sw_mpu_r_masked_intr_grp2___timer_grp2___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp2___timer_grp2___bit 20
+#define reg_iop_sw_mpu_r_masked_intr_grp2___fifo_out0___lsb 21
+#define reg_iop_sw_mpu_r_masked_intr_grp2___fifo_out0___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp2___fifo_out0___bit 21
+#define reg_iop_sw_mpu_r_masked_intr_grp2___fifo_out0_extra___lsb 22
+#define reg_iop_sw_mpu_r_masked_intr_grp2___fifo_out0_extra___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp2___fifo_out0_extra___bit 22
+#define reg_iop_sw_mpu_r_masked_intr_grp2___dmc_out1___lsb 23
+#define reg_iop_sw_mpu_r_masked_intr_grp2___dmc_out1___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp2___dmc_out1___bit 23
+#define reg_iop_sw_mpu_r_masked_intr_grp2___spu0_intr11___lsb 24
+#define reg_iop_sw_mpu_r_masked_intr_grp2___spu0_intr11___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp2___spu0_intr11___bit 24
+#define reg_iop_sw_mpu_r_masked_intr_grp2___spu1_intr11___lsb 25
+#define reg_iop_sw_mpu_r_masked_intr_grp2___spu1_intr11___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp2___spu1_intr11___bit 25
+#define reg_iop_sw_mpu_r_masked_intr_grp2___trigger_grp3___lsb 26
+#define reg_iop_sw_mpu_r_masked_intr_grp2___trigger_grp3___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp2___trigger_grp3___bit 26
+#define reg_iop_sw_mpu_r_masked_intr_grp2___trigger_grp5___lsb 27
+#define reg_iop_sw_mpu_r_masked_intr_grp2___trigger_grp5___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp2___trigger_grp5___bit 27
+#define reg_iop_sw_mpu_r_masked_intr_grp2___timer_grp3___lsb 28
+#define reg_iop_sw_mpu_r_masked_intr_grp2___timer_grp3___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp2___timer_grp3___bit 28
+#define reg_iop_sw_mpu_r_masked_intr_grp2___fifo_in0___lsb 29
+#define reg_iop_sw_mpu_r_masked_intr_grp2___fifo_in0___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp2___fifo_in0___bit 29
+#define reg_iop_sw_mpu_r_masked_intr_grp2___fifo_in0_extra___lsb 30
+#define reg_iop_sw_mpu_r_masked_intr_grp2___fifo_in0_extra___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp2___fifo_in0_extra___bit 30
+#define reg_iop_sw_mpu_r_masked_intr_grp2___dmc_in1___lsb 31
+#define reg_iop_sw_mpu_r_masked_intr_grp2___dmc_in1___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp2___dmc_in1___bit 31
+#define reg_iop_sw_mpu_r_masked_intr_grp2_offset 140
+
+/* Register rw_intr_grp3_mask, scope iop_sw_mpu, type rw */
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___spu0_intr12___lsb 0
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___spu0_intr12___width 1
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___spu0_intr12___bit 0
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___spu1_intr12___lsb 1
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___spu1_intr12___width 1
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___spu1_intr12___bit 1
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___trigger_grp0___lsb 2
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___trigger_grp0___width 1
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___trigger_grp0___bit 2
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___trigger_grp7___lsb 3
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___trigger_grp7___width 1
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___trigger_grp7___bit 3
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___timer_grp0___lsb 4
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___timer_grp0___width 1
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___timer_grp0___bit 4
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___fifo_in1___lsb 5
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___fifo_in1___width 1
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___fifo_in1___bit 5
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___fifo_in1_extra___lsb 6
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___fifo_in1_extra___width 1
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___fifo_in1_extra___bit 6
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___dmc_out0___lsb 7
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___dmc_out0___width 1
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___dmc_out0___bit 7
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___spu0_intr13___lsb 8
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___spu0_intr13___width 1
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___spu0_intr13___bit 8
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___spu1_intr13___lsb 9
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___spu1_intr13___width 1
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___spu1_intr13___bit 9
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___trigger_grp1___lsb 10
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___trigger_grp1___width 1
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___trigger_grp1___bit 10
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___trigger_grp4___lsb 11
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___trigger_grp4___width 1
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___trigger_grp4___bit 11
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___timer_grp1___lsb 12
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___timer_grp1___width 1
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___timer_grp1___bit 12
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___fifo_out0___lsb 13
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___fifo_out0___width 1
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___fifo_out0___bit 13
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___fifo_out0_extra___lsb 14
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___fifo_out0_extra___width 1
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___fifo_out0_extra___bit 14
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___dmc_in0___lsb 15
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___dmc_in0___width 1
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___dmc_in0___bit 15
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___spu0_intr14___lsb 16
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___spu0_intr14___width 1
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___spu0_intr14___bit 16
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___spu1_intr14___lsb 17
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___spu1_intr14___width 1
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___spu1_intr14___bit 17
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___trigger_grp2___lsb 18
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___trigger_grp2___width 1
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___trigger_grp2___bit 18
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___trigger_grp5___lsb 19
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___trigger_grp5___width 1
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___trigger_grp5___bit 19
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___timer_grp2___lsb 20
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___timer_grp2___width 1
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___timer_grp2___bit 20
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___fifo_in0___lsb 21
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___fifo_in0___width 1
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___fifo_in0___bit 21
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___fifo_in0_extra___lsb 22
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___fifo_in0_extra___width 1
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___fifo_in0_extra___bit 22
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___dmc_out1___lsb 23
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___dmc_out1___width 1
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___dmc_out1___bit 23
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___spu0_intr15___lsb 24
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___spu0_intr15___width 1
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___spu0_intr15___bit 24
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___spu1_intr15___lsb 25
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___spu1_intr15___width 1
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___spu1_intr15___bit 25
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___trigger_grp3___lsb 26
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___trigger_grp3___width 1
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___trigger_grp3___bit 26
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___trigger_grp6___lsb 27
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___trigger_grp6___width 1
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___trigger_grp6___bit 27
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___timer_grp3___lsb 28
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___timer_grp3___width 1
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___timer_grp3___bit 28
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___fifo_out1___lsb 29
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___fifo_out1___width 1
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___fifo_out1___bit 29
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___fifo_out1_extra___lsb 30
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___fifo_out1_extra___width 1
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___fifo_out1_extra___bit 30
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___dmc_in1___lsb 31
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___dmc_in1___width 1
+#define reg_iop_sw_mpu_rw_intr_grp3_mask___dmc_in1___bit 31
+#define reg_iop_sw_mpu_rw_intr_grp3_mask_offset 144
+
+/* Register rw_ack_intr_grp3, scope iop_sw_mpu, type rw */
+#define reg_iop_sw_mpu_rw_ack_intr_grp3___spu0_intr12___lsb 0
+#define reg_iop_sw_mpu_rw_ack_intr_grp3___spu0_intr12___width 1
+#define reg_iop_sw_mpu_rw_ack_intr_grp3___spu0_intr12___bit 0
+#define reg_iop_sw_mpu_rw_ack_intr_grp3___spu1_intr12___lsb 1
+#define reg_iop_sw_mpu_rw_ack_intr_grp3___spu1_intr12___width 1
+#define reg_iop_sw_mpu_rw_ack_intr_grp3___spu1_intr12___bit 1
+#define reg_iop_sw_mpu_rw_ack_intr_grp3___spu0_intr13___lsb 8
+#define reg_iop_sw_mpu_rw_ack_intr_grp3___spu0_intr13___width 1
+#define reg_iop_sw_mpu_rw_ack_intr_grp3___spu0_intr13___bit 8
+#define reg_iop_sw_mpu_rw_ack_intr_grp3___spu1_intr13___lsb 9
+#define reg_iop_sw_mpu_rw_ack_intr_grp3___spu1_intr13___width 1
+#define reg_iop_sw_mpu_rw_ack_intr_grp3___spu1_intr13___bit 9
+#define reg_iop_sw_mpu_rw_ack_intr_grp3___spu0_intr14___lsb 16
+#define reg_iop_sw_mpu_rw_ack_intr_grp3___spu0_intr14___width 1
+#define reg_iop_sw_mpu_rw_ack_intr_grp3___spu0_intr14___bit 16
+#define reg_iop_sw_mpu_rw_ack_intr_grp3___spu1_intr14___lsb 17
+#define reg_iop_sw_mpu_rw_ack_intr_grp3___spu1_intr14___width 1
+#define reg_iop_sw_mpu_rw_ack_intr_grp3___spu1_intr14___bit 17
+#define reg_iop_sw_mpu_rw_ack_intr_grp3___spu0_intr15___lsb 24
+#define reg_iop_sw_mpu_rw_ack_intr_grp3___spu0_intr15___width 1
+#define reg_iop_sw_mpu_rw_ack_intr_grp3___spu0_intr15___bit 24
+#define reg_iop_sw_mpu_rw_ack_intr_grp3___spu1_intr15___lsb 25
+#define reg_iop_sw_mpu_rw_ack_intr_grp3___spu1_intr15___width 1
+#define reg_iop_sw_mpu_rw_ack_intr_grp3___spu1_intr15___bit 25
+#define reg_iop_sw_mpu_rw_ack_intr_grp3_offset 148
+
+/* Register r_intr_grp3, scope iop_sw_mpu, type r */
+#define reg_iop_sw_mpu_r_intr_grp3___spu0_intr12___lsb 0
+#define reg_iop_sw_mpu_r_intr_grp3___spu0_intr12___width 1
+#define reg_iop_sw_mpu_r_intr_grp3___spu0_intr12___bit 0
+#define reg_iop_sw_mpu_r_intr_grp3___spu1_intr12___lsb 1
+#define reg_iop_sw_mpu_r_intr_grp3___spu1_intr12___width 1
+#define reg_iop_sw_mpu_r_intr_grp3___spu1_intr12___bit 1
+#define reg_iop_sw_mpu_r_intr_grp3___trigger_grp0___lsb 2
+#define reg_iop_sw_mpu_r_intr_grp3___trigger_grp0___width 1
+#define reg_iop_sw_mpu_r_intr_grp3___trigger_grp0___bit 2
+#define reg_iop_sw_mpu_r_intr_grp3___trigger_grp7___lsb 3
+#define reg_iop_sw_mpu_r_intr_grp3___trigger_grp7___width 1
+#define reg_iop_sw_mpu_r_intr_grp3___trigger_grp7___bit 3
+#define reg_iop_sw_mpu_r_intr_grp3___timer_grp0___lsb 4
+#define reg_iop_sw_mpu_r_intr_grp3___timer_grp0___width 1
+#define reg_iop_sw_mpu_r_intr_grp3___timer_grp0___bit 4
+#define reg_iop_sw_mpu_r_intr_grp3___fifo_in1___lsb 5
+#define reg_iop_sw_mpu_r_intr_grp3___fifo_in1___width 1
+#define reg_iop_sw_mpu_r_intr_grp3___fifo_in1___bit 5
+#define reg_iop_sw_mpu_r_intr_grp3___fifo_in1_extra___lsb 6
+#define reg_iop_sw_mpu_r_intr_grp3___fifo_in1_extra___width 1
+#define reg_iop_sw_mpu_r_intr_grp3___fifo_in1_extra___bit 6
+#define reg_iop_sw_mpu_r_intr_grp3___dmc_out0___lsb 7
+#define reg_iop_sw_mpu_r_intr_grp3___dmc_out0___width 1
+#define reg_iop_sw_mpu_r_intr_grp3___dmc_out0___bit 7
+#define reg_iop_sw_mpu_r_intr_grp3___spu0_intr13___lsb 8
+#define reg_iop_sw_mpu_r_intr_grp3___spu0_intr13___width 1
+#define reg_iop_sw_mpu_r_intr_grp3___spu0_intr13___bit 8
+#define reg_iop_sw_mpu_r_intr_grp3___spu1_intr13___lsb 9
+#define reg_iop_sw_mpu_r_intr_grp3___spu1_intr13___width 1
+#define reg_iop_sw_mpu_r_intr_grp3___spu1_intr13___bit 9
+#define reg_iop_sw_mpu_r_intr_grp3___trigger_grp1___lsb 10
+#define reg_iop_sw_mpu_r_intr_grp3___trigger_grp1___width 1
+#define reg_iop_sw_mpu_r_intr_grp3___trigger_grp1___bit 10
+#define reg_iop_sw_mpu_r_intr_grp3___trigger_grp4___lsb 11
+#define reg_iop_sw_mpu_r_intr_grp3___trigger_grp4___width 1
+#define reg_iop_sw_mpu_r_intr_grp3___trigger_grp4___bit 11
+#define reg_iop_sw_mpu_r_intr_grp3___timer_grp1___lsb 12
+#define reg_iop_sw_mpu_r_intr_grp3___timer_grp1___width 1
+#define reg_iop_sw_mpu_r_intr_grp3___timer_grp1___bit 12
+#define reg_iop_sw_mpu_r_intr_grp3___fifo_out0___lsb 13
+#define reg_iop_sw_mpu_r_intr_grp3___fifo_out0___width 1
+#define reg_iop_sw_mpu_r_intr_grp3___fifo_out0___bit 13
+#define reg_iop_sw_mpu_r_intr_grp3___fifo_out0_extra___lsb 14
+#define reg_iop_sw_mpu_r_intr_grp3___fifo_out0_extra___width 1
+#define reg_iop_sw_mpu_r_intr_grp3___fifo_out0_extra___bit 14
+#define reg_iop_sw_mpu_r_intr_grp3___dmc_in0___lsb 15
+#define reg_iop_sw_mpu_r_intr_grp3___dmc_in0___width 1
+#define reg_iop_sw_mpu_r_intr_grp3___dmc_in0___bit 15
+#define reg_iop_sw_mpu_r_intr_grp3___spu0_intr14___lsb 16
+#define reg_iop_sw_mpu_r_intr_grp3___spu0_intr14___width 1
+#define reg_iop_sw_mpu_r_intr_grp3___spu0_intr14___bit 16
+#define reg_iop_sw_mpu_r_intr_grp3___spu1_intr14___lsb 17
+#define reg_iop_sw_mpu_r_intr_grp3___spu1_intr14___width 1
+#define reg_iop_sw_mpu_r_intr_grp3___spu1_intr14___bit 17
+#define reg_iop_sw_mpu_r_intr_grp3___trigger_grp2___lsb 18
+#define reg_iop_sw_mpu_r_intr_grp3___trigger_grp2___width 1
+#define reg_iop_sw_mpu_r_intr_grp3___trigger_grp2___bit 18
+#define reg_iop_sw_mpu_r_intr_grp3___trigger_grp5___lsb 19
+#define reg_iop_sw_mpu_r_intr_grp3___trigger_grp5___width 1
+#define reg_iop_sw_mpu_r_intr_grp3___trigger_grp5___bit 19
+#define reg_iop_sw_mpu_r_intr_grp3___timer_grp2___lsb 20
+#define reg_iop_sw_mpu_r_intr_grp3___timer_grp2___width 1
+#define reg_iop_sw_mpu_r_intr_grp3___timer_grp2___bit 20
+#define reg_iop_sw_mpu_r_intr_grp3___fifo_in0___lsb 21
+#define reg_iop_sw_mpu_r_intr_grp3___fifo_in0___width 1
+#define reg_iop_sw_mpu_r_intr_grp3___fifo_in0___bit 21
+#define reg_iop_sw_mpu_r_intr_grp3___fifo_in0_extra___lsb 22
+#define reg_iop_sw_mpu_r_intr_grp3___fifo_in0_extra___width 1
+#define reg_iop_sw_mpu_r_intr_grp3___fifo_in0_extra___bit 22
+#define reg_iop_sw_mpu_r_intr_grp3___dmc_out1___lsb 23
+#define reg_iop_sw_mpu_r_intr_grp3___dmc_out1___width 1
+#define reg_iop_sw_mpu_r_intr_grp3___dmc_out1___bit 23
+#define reg_iop_sw_mpu_r_intr_grp3___spu0_intr15___lsb 24
+#define reg_iop_sw_mpu_r_intr_grp3___spu0_intr15___width 1
+#define reg_iop_sw_mpu_r_intr_grp3___spu0_intr15___bit 24
+#define reg_iop_sw_mpu_r_intr_grp3___spu1_intr15___lsb 25
+#define reg_iop_sw_mpu_r_intr_grp3___spu1_intr15___width 1
+#define reg_iop_sw_mpu_r_intr_grp3___spu1_intr15___bit 25
+#define reg_iop_sw_mpu_r_intr_grp3___trigger_grp3___lsb 26
+#define reg_iop_sw_mpu_r_intr_grp3___trigger_grp3___width 1
+#define reg_iop_sw_mpu_r_intr_grp3___trigger_grp3___bit 26
+#define reg_iop_sw_mpu_r_intr_grp3___trigger_grp6___lsb 27
+#define reg_iop_sw_mpu_r_intr_grp3___trigger_grp6___width 1
+#define reg_iop_sw_mpu_r_intr_grp3___trigger_grp6___bit 27
+#define reg_iop_sw_mpu_r_intr_grp3___timer_grp3___lsb 28
+#define reg_iop_sw_mpu_r_intr_grp3___timer_grp3___width 1
+#define reg_iop_sw_mpu_r_intr_grp3___timer_grp3___bit 28
+#define reg_iop_sw_mpu_r_intr_grp3___fifo_out1___lsb 29
+#define reg_iop_sw_mpu_r_intr_grp3___fifo_out1___width 1
+#define reg_iop_sw_mpu_r_intr_grp3___fifo_out1___bit 29
+#define reg_iop_sw_mpu_r_intr_grp3___fifo_out1_extra___lsb 30
+#define reg_iop_sw_mpu_r_intr_grp3___fifo_out1_extra___width 1
+#define reg_iop_sw_mpu_r_intr_grp3___fifo_out1_extra___bit 30
+#define reg_iop_sw_mpu_r_intr_grp3___dmc_in1___lsb 31
+#define reg_iop_sw_mpu_r_intr_grp3___dmc_in1___width 1
+#define reg_iop_sw_mpu_r_intr_grp3___dmc_in1___bit 31
+#define reg_iop_sw_mpu_r_intr_grp3_offset 152
+
+/* Register r_masked_intr_grp3, scope iop_sw_mpu, type r */
+#define reg_iop_sw_mpu_r_masked_intr_grp3___spu0_intr12___lsb 0
+#define reg_iop_sw_mpu_r_masked_intr_grp3___spu0_intr12___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp3___spu0_intr12___bit 0
+#define reg_iop_sw_mpu_r_masked_intr_grp3___spu1_intr12___lsb 1
+#define reg_iop_sw_mpu_r_masked_intr_grp3___spu1_intr12___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp3___spu1_intr12___bit 1
+#define reg_iop_sw_mpu_r_masked_intr_grp3___trigger_grp0___lsb 2
+#define reg_iop_sw_mpu_r_masked_intr_grp3___trigger_grp0___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp3___trigger_grp0___bit 2
+#define reg_iop_sw_mpu_r_masked_intr_grp3___trigger_grp7___lsb 3
+#define reg_iop_sw_mpu_r_masked_intr_grp3___trigger_grp7___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp3___trigger_grp7___bit 3
+#define reg_iop_sw_mpu_r_masked_intr_grp3___timer_grp0___lsb 4
+#define reg_iop_sw_mpu_r_masked_intr_grp3___timer_grp0___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp3___timer_grp0___bit 4
+#define reg_iop_sw_mpu_r_masked_intr_grp3___fifo_in1___lsb 5
+#define reg_iop_sw_mpu_r_masked_intr_grp3___fifo_in1___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp3___fifo_in1___bit 5
+#define reg_iop_sw_mpu_r_masked_intr_grp3___fifo_in1_extra___lsb 6
+#define reg_iop_sw_mpu_r_masked_intr_grp3___fifo_in1_extra___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp3___fifo_in1_extra___bit 6
+#define reg_iop_sw_mpu_r_masked_intr_grp3___dmc_out0___lsb 7
+#define reg_iop_sw_mpu_r_masked_intr_grp3___dmc_out0___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp3___dmc_out0___bit 7
+#define reg_iop_sw_mpu_r_masked_intr_grp3___spu0_intr13___lsb 8
+#define reg_iop_sw_mpu_r_masked_intr_grp3___spu0_intr13___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp3___spu0_intr13___bit 8
+#define reg_iop_sw_mpu_r_masked_intr_grp3___spu1_intr13___lsb 9
+#define reg_iop_sw_mpu_r_masked_intr_grp3___spu1_intr13___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp3___spu1_intr13___bit 9
+#define reg_iop_sw_mpu_r_masked_intr_grp3___trigger_grp1___lsb 10
+#define reg_iop_sw_mpu_r_masked_intr_grp3___trigger_grp1___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp3___trigger_grp1___bit 10
+#define reg_iop_sw_mpu_r_masked_intr_grp3___trigger_grp4___lsb 11
+#define reg_iop_sw_mpu_r_masked_intr_grp3___trigger_grp4___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp3___trigger_grp4___bit 11
+#define reg_iop_sw_mpu_r_masked_intr_grp3___timer_grp1___lsb 12
+#define reg_iop_sw_mpu_r_masked_intr_grp3___timer_grp1___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp3___timer_grp1___bit 12
+#define reg_iop_sw_mpu_r_masked_intr_grp3___fifo_out0___lsb 13
+#define reg_iop_sw_mpu_r_masked_intr_grp3___fifo_out0___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp3___fifo_out0___bit 13
+#define reg_iop_sw_mpu_r_masked_intr_grp3___fifo_out0_extra___lsb 14
+#define reg_iop_sw_mpu_r_masked_intr_grp3___fifo_out0_extra___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp3___fifo_out0_extra___bit 14
+#define reg_iop_sw_mpu_r_masked_intr_grp3___dmc_in0___lsb 15
+#define reg_iop_sw_mpu_r_masked_intr_grp3___dmc_in0___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp3___dmc_in0___bit 15
+#define reg_iop_sw_mpu_r_masked_intr_grp3___spu0_intr14___lsb 16
+#define reg_iop_sw_mpu_r_masked_intr_grp3___spu0_intr14___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp3___spu0_intr14___bit 16
+#define reg_iop_sw_mpu_r_masked_intr_grp3___spu1_intr14___lsb 17
+#define reg_iop_sw_mpu_r_masked_intr_grp3___spu1_intr14___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp3___spu1_intr14___bit 17
+#define reg_iop_sw_mpu_r_masked_intr_grp3___trigger_grp2___lsb 18
+#define reg_iop_sw_mpu_r_masked_intr_grp3___trigger_grp2___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp3___trigger_grp2___bit 18
+#define reg_iop_sw_mpu_r_masked_intr_grp3___trigger_grp5___lsb 19
+#define reg_iop_sw_mpu_r_masked_intr_grp3___trigger_grp5___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp3___trigger_grp5___bit 19
+#define reg_iop_sw_mpu_r_masked_intr_grp3___timer_grp2___lsb 20
+#define reg_iop_sw_mpu_r_masked_intr_grp3___timer_grp2___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp3___timer_grp2___bit 20
+#define reg_iop_sw_mpu_r_masked_intr_grp3___fifo_in0___lsb 21
+#define reg_iop_sw_mpu_r_masked_intr_grp3___fifo_in0___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp3___fifo_in0___bit 21
+#define reg_iop_sw_mpu_r_masked_intr_grp3___fifo_in0_extra___lsb 22
+#define reg_iop_sw_mpu_r_masked_intr_grp3___fifo_in0_extra___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp3___fifo_in0_extra___bit 22
+#define reg_iop_sw_mpu_r_masked_intr_grp3___dmc_out1___lsb 23
+#define reg_iop_sw_mpu_r_masked_intr_grp3___dmc_out1___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp3___dmc_out1___bit 23
+#define reg_iop_sw_mpu_r_masked_intr_grp3___spu0_intr15___lsb 24
+#define reg_iop_sw_mpu_r_masked_intr_grp3___spu0_intr15___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp3___spu0_intr15___bit 24
+#define reg_iop_sw_mpu_r_masked_intr_grp3___spu1_intr15___lsb 25
+#define reg_iop_sw_mpu_r_masked_intr_grp3___spu1_intr15___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp3___spu1_intr15___bit 25
+#define reg_iop_sw_mpu_r_masked_intr_grp3___trigger_grp3___lsb 26
+#define reg_iop_sw_mpu_r_masked_intr_grp3___trigger_grp3___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp3___trigger_grp3___bit 26
+#define reg_iop_sw_mpu_r_masked_intr_grp3___trigger_grp6___lsb 27
+#define reg_iop_sw_mpu_r_masked_intr_grp3___trigger_grp6___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp3___trigger_grp6___bit 27
+#define reg_iop_sw_mpu_r_masked_intr_grp3___timer_grp3___lsb 28
+#define reg_iop_sw_mpu_r_masked_intr_grp3___timer_grp3___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp3___timer_grp3___bit 28
+#define reg_iop_sw_mpu_r_masked_intr_grp3___fifo_out1___lsb 29
+#define reg_iop_sw_mpu_r_masked_intr_grp3___fifo_out1___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp3___fifo_out1___bit 29
+#define reg_iop_sw_mpu_r_masked_intr_grp3___fifo_out1_extra___lsb 30
+#define reg_iop_sw_mpu_r_masked_intr_grp3___fifo_out1_extra___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp3___fifo_out1_extra___bit 30
+#define reg_iop_sw_mpu_r_masked_intr_grp3___dmc_in1___lsb 31
+#define reg_iop_sw_mpu_r_masked_intr_grp3___dmc_in1___width 1
+#define reg_iop_sw_mpu_r_masked_intr_grp3___dmc_in1___bit 31
+#define reg_iop_sw_mpu_r_masked_intr_grp3_offset 156
+
+
+/* Constants */
+#define regk_iop_sw_mpu_copy                      0x00000000
+#define regk_iop_sw_mpu_cpu                       0x00000000
+#define regk_iop_sw_mpu_mpu                       0x00000001
+#define regk_iop_sw_mpu_no                        0x00000000
+#define regk_iop_sw_mpu_nop                       0x00000000
+#define regk_iop_sw_mpu_rd                        0x00000002
+#define regk_iop_sw_mpu_reg_copy                  0x00000001
+#define regk_iop_sw_mpu_rw_bus0_clr_mask_default  0x00000000
+#define regk_iop_sw_mpu_rw_bus0_oe_clr_mask_default  0x00000000
+#define regk_iop_sw_mpu_rw_bus0_oe_set_mask_default  0x00000000
+#define regk_iop_sw_mpu_rw_bus0_set_mask_default  0x00000000
+#define regk_iop_sw_mpu_rw_bus1_clr_mask_default  0x00000000
+#define regk_iop_sw_mpu_rw_bus1_oe_clr_mask_default  0x00000000
+#define regk_iop_sw_mpu_rw_bus1_oe_set_mask_default  0x00000000
+#define regk_iop_sw_mpu_rw_bus1_set_mask_default  0x00000000
+#define regk_iop_sw_mpu_rw_gio_clr_mask_default   0x00000000
+#define regk_iop_sw_mpu_rw_gio_oe_clr_mask_default  0x00000000
+#define regk_iop_sw_mpu_rw_gio_oe_set_mask_default  0x00000000
+#define regk_iop_sw_mpu_rw_gio_set_mask_default   0x00000000
+#define regk_iop_sw_mpu_rw_intr_grp0_mask_default  0x00000000
+#define regk_iop_sw_mpu_rw_intr_grp1_mask_default  0x00000000
+#define regk_iop_sw_mpu_rw_intr_grp2_mask_default  0x00000000
+#define regk_iop_sw_mpu_rw_intr_grp3_mask_default  0x00000000
+#define regk_iop_sw_mpu_rw_sw_cfg_owner_default   0x00000000
+#define regk_iop_sw_mpu_set                       0x00000001
+#define regk_iop_sw_mpu_spu0                      0x00000002
+#define regk_iop_sw_mpu_spu1                      0x00000003
+#define regk_iop_sw_mpu_wr                        0x00000003
+#define regk_iop_sw_mpu_yes                       0x00000001
+#endif /* __iop_sw_mpu_defs_asm_h */
diff --git a/include/asm-cris/arch-v32/hwregs/iop/asm/iop_sw_spu_defs_asm.h b/include/asm-cris/arch-v32/hwregs/iop/asm/iop_sw_spu_defs_asm.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/iop/asm/iop_sw_spu_defs_asm.h
@@ -0,0 +1,691 @@
+#ifndef __iop_sw_spu_defs_asm_h
+#define __iop_sw_spu_defs_asm_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/io_proc/rtl/guinness/iop_sw_spu.r
+ *     id:           <not found>
+ *     last modfied: Mon Apr 11 16:10:19 2005
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c -asm --outfile asm/iop_sw_spu_defs_asm.h ../../inst/io_proc/rtl/guinness/iop_sw_spu.r
+ *      id: $Id: iop_sw_spu_defs_asm.h,v 1.5 2005/04/24 18:31:07 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+
+#ifndef REG_FIELD
+#define REG_FIELD( scope, reg, field, value ) \
+  REG_FIELD_X_( value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_FIELD_X_( value, shift ) ((value) << shift)
+#endif
+
+#ifndef REG_STATE
+#define REG_STATE( scope, reg, field, symbolic_value ) \
+  REG_STATE_X_( regk_##scope##_##symbolic_value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_STATE_X_( k, shift ) (k << shift)
+#endif
+
+#ifndef REG_MASK
+#define REG_MASK( scope, reg, field ) \
+  REG_MASK_X_( reg_##scope##_##reg##___##field##___width, reg_##scope##_##reg##___##field##___lsb )
+#define REG_MASK_X_( width, lsb ) (((1 << width)-1) << lsb)
+#endif
+
+#ifndef REG_LSB
+#define REG_LSB( scope, reg, field ) reg_##scope##_##reg##___##field##___lsb
+#endif
+
+#ifndef REG_BIT
+#define REG_BIT( scope, reg, field ) reg_##scope##_##reg##___##field##___bit
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) REG_ADDR_X_(inst, reg_##scope##_##reg##_offset)
+#define REG_ADDR_X_( inst, offs ) ((inst) + offs)
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+         REG_ADDR_VECT_X_(inst, reg_##scope##_##reg##_offset, index, \
+			 STRIDE_##scope##_##reg )
+#define REG_ADDR_VECT_X_( inst, offs, index, stride ) \
+                          ((inst) + offs + (index) * stride)
+#endif
+
+/* Register rw_mc_ctrl, scope iop_sw_spu, type rw */
+#define reg_iop_sw_spu_rw_mc_ctrl___keep_owner___lsb 0
+#define reg_iop_sw_spu_rw_mc_ctrl___keep_owner___width 1
+#define reg_iop_sw_spu_rw_mc_ctrl___keep_owner___bit 0
+#define reg_iop_sw_spu_rw_mc_ctrl___cmd___lsb 1
+#define reg_iop_sw_spu_rw_mc_ctrl___cmd___width 2
+#define reg_iop_sw_spu_rw_mc_ctrl___size___lsb 3
+#define reg_iop_sw_spu_rw_mc_ctrl___size___width 3
+#define reg_iop_sw_spu_rw_mc_ctrl___wr_spu0_mem___lsb 6
+#define reg_iop_sw_spu_rw_mc_ctrl___wr_spu0_mem___width 1
+#define reg_iop_sw_spu_rw_mc_ctrl___wr_spu0_mem___bit 6
+#define reg_iop_sw_spu_rw_mc_ctrl___wr_spu1_mem___lsb 7
+#define reg_iop_sw_spu_rw_mc_ctrl___wr_spu1_mem___width 1
+#define reg_iop_sw_spu_rw_mc_ctrl___wr_spu1_mem___bit 7
+#define reg_iop_sw_spu_rw_mc_ctrl_offset 0
+
+/* Register rw_mc_data, scope iop_sw_spu, type rw */
+#define reg_iop_sw_spu_rw_mc_data___val___lsb 0
+#define reg_iop_sw_spu_rw_mc_data___val___width 32
+#define reg_iop_sw_spu_rw_mc_data_offset 4
+
+/* Register rw_mc_addr, scope iop_sw_spu, type rw */
+#define reg_iop_sw_spu_rw_mc_addr_offset 8
+
+/* Register rs_mc_data, scope iop_sw_spu, type rs */
+#define reg_iop_sw_spu_rs_mc_data_offset 12
+
+/* Register r_mc_data, scope iop_sw_spu, type r */
+#define reg_iop_sw_spu_r_mc_data_offset 16
+
+/* Register r_mc_stat, scope iop_sw_spu, type r */
+#define reg_iop_sw_spu_r_mc_stat___busy_cpu___lsb 0
+#define reg_iop_sw_spu_r_mc_stat___busy_cpu___width 1
+#define reg_iop_sw_spu_r_mc_stat___busy_cpu___bit 0
+#define reg_iop_sw_spu_r_mc_stat___busy_mpu___lsb 1
+#define reg_iop_sw_spu_r_mc_stat___busy_mpu___width 1
+#define reg_iop_sw_spu_r_mc_stat___busy_mpu___bit 1
+#define reg_iop_sw_spu_r_mc_stat___busy_spu0___lsb 2
+#define reg_iop_sw_spu_r_mc_stat___busy_spu0___width 1
+#define reg_iop_sw_spu_r_mc_stat___busy_spu0___bit 2
+#define reg_iop_sw_spu_r_mc_stat___busy_spu1___lsb 3
+#define reg_iop_sw_spu_r_mc_stat___busy_spu1___width 1
+#define reg_iop_sw_spu_r_mc_stat___busy_spu1___bit 3
+#define reg_iop_sw_spu_r_mc_stat___owned_by_cpu___lsb 4
+#define reg_iop_sw_spu_r_mc_stat___owned_by_cpu___width 1
+#define reg_iop_sw_spu_r_mc_stat___owned_by_cpu___bit 4
+#define reg_iop_sw_spu_r_mc_stat___owned_by_mpu___lsb 5
+#define reg_iop_sw_spu_r_mc_stat___owned_by_mpu___width 1
+#define reg_iop_sw_spu_r_mc_stat___owned_by_mpu___bit 5
+#define reg_iop_sw_spu_r_mc_stat___owned_by_spu0___lsb 6
+#define reg_iop_sw_spu_r_mc_stat___owned_by_spu0___width 1
+#define reg_iop_sw_spu_r_mc_stat___owned_by_spu0___bit 6
+#define reg_iop_sw_spu_r_mc_stat___owned_by_spu1___lsb 7
+#define reg_iop_sw_spu_r_mc_stat___owned_by_spu1___width 1
+#define reg_iop_sw_spu_r_mc_stat___owned_by_spu1___bit 7
+#define reg_iop_sw_spu_r_mc_stat_offset 20
+
+/* Register rw_bus0_clr_mask, scope iop_sw_spu, type rw */
+#define reg_iop_sw_spu_rw_bus0_clr_mask___byte0___lsb 0
+#define reg_iop_sw_spu_rw_bus0_clr_mask___byte0___width 8
+#define reg_iop_sw_spu_rw_bus0_clr_mask___byte1___lsb 8
+#define reg_iop_sw_spu_rw_bus0_clr_mask___byte1___width 8
+#define reg_iop_sw_spu_rw_bus0_clr_mask___byte2___lsb 16
+#define reg_iop_sw_spu_rw_bus0_clr_mask___byte2___width 8
+#define reg_iop_sw_spu_rw_bus0_clr_mask___byte3___lsb 24
+#define reg_iop_sw_spu_rw_bus0_clr_mask___byte3___width 8
+#define reg_iop_sw_spu_rw_bus0_clr_mask_offset 24
+
+/* Register rw_bus0_set_mask, scope iop_sw_spu, type rw */
+#define reg_iop_sw_spu_rw_bus0_set_mask___byte0___lsb 0
+#define reg_iop_sw_spu_rw_bus0_set_mask___byte0___width 8
+#define reg_iop_sw_spu_rw_bus0_set_mask___byte1___lsb 8
+#define reg_iop_sw_spu_rw_bus0_set_mask___byte1___width 8
+#define reg_iop_sw_spu_rw_bus0_set_mask___byte2___lsb 16
+#define reg_iop_sw_spu_rw_bus0_set_mask___byte2___width 8
+#define reg_iop_sw_spu_rw_bus0_set_mask___byte3___lsb 24
+#define reg_iop_sw_spu_rw_bus0_set_mask___byte3___width 8
+#define reg_iop_sw_spu_rw_bus0_set_mask_offset 28
+
+/* Register rw_bus0_oe_clr_mask, scope iop_sw_spu, type rw */
+#define reg_iop_sw_spu_rw_bus0_oe_clr_mask___byte0___lsb 0
+#define reg_iop_sw_spu_rw_bus0_oe_clr_mask___byte0___width 1
+#define reg_iop_sw_spu_rw_bus0_oe_clr_mask___byte0___bit 0
+#define reg_iop_sw_spu_rw_bus0_oe_clr_mask___byte1___lsb 1
+#define reg_iop_sw_spu_rw_bus0_oe_clr_mask___byte1___width 1
+#define reg_iop_sw_spu_rw_bus0_oe_clr_mask___byte1___bit 1
+#define reg_iop_sw_spu_rw_bus0_oe_clr_mask___byte2___lsb 2
+#define reg_iop_sw_spu_rw_bus0_oe_clr_mask___byte2___width 1
+#define reg_iop_sw_spu_rw_bus0_oe_clr_mask___byte2___bit 2
+#define reg_iop_sw_spu_rw_bus0_oe_clr_mask___byte3___lsb 3
+#define reg_iop_sw_spu_rw_bus0_oe_clr_mask___byte3___width 1
+#define reg_iop_sw_spu_rw_bus0_oe_clr_mask___byte3___bit 3
+#define reg_iop_sw_spu_rw_bus0_oe_clr_mask_offset 32
+
+/* Register rw_bus0_oe_set_mask, scope iop_sw_spu, type rw */
+#define reg_iop_sw_spu_rw_bus0_oe_set_mask___byte0___lsb 0
+#define reg_iop_sw_spu_rw_bus0_oe_set_mask___byte0___width 1
+#define reg_iop_sw_spu_rw_bus0_oe_set_mask___byte0___bit 0
+#define reg_iop_sw_spu_rw_bus0_oe_set_mask___byte1___lsb 1
+#define reg_iop_sw_spu_rw_bus0_oe_set_mask___byte1___width 1
+#define reg_iop_sw_spu_rw_bus0_oe_set_mask___byte1___bit 1
+#define reg_iop_sw_spu_rw_bus0_oe_set_mask___byte2___lsb 2
+#define reg_iop_sw_spu_rw_bus0_oe_set_mask___byte2___width 1
+#define reg_iop_sw_spu_rw_bus0_oe_set_mask___byte2___bit 2
+#define reg_iop_sw_spu_rw_bus0_oe_set_mask___byte3___lsb 3
+#define reg_iop_sw_spu_rw_bus0_oe_set_mask___byte3___width 1
+#define reg_iop_sw_spu_rw_bus0_oe_set_mask___byte3___bit 3
+#define reg_iop_sw_spu_rw_bus0_oe_set_mask_offset 36
+
+/* Register r_bus0_in, scope iop_sw_spu, type r */
+#define reg_iop_sw_spu_r_bus0_in_offset 40
+
+/* Register rw_bus1_clr_mask, scope iop_sw_spu, type rw */
+#define reg_iop_sw_spu_rw_bus1_clr_mask___byte0___lsb 0
+#define reg_iop_sw_spu_rw_bus1_clr_mask___byte0___width 8
+#define reg_iop_sw_spu_rw_bus1_clr_mask___byte1___lsb 8
+#define reg_iop_sw_spu_rw_bus1_clr_mask___byte1___width 8
+#define reg_iop_sw_spu_rw_bus1_clr_mask___byte2___lsb 16
+#define reg_iop_sw_spu_rw_bus1_clr_mask___byte2___width 8
+#define reg_iop_sw_spu_rw_bus1_clr_mask___byte3___lsb 24
+#define reg_iop_sw_spu_rw_bus1_clr_mask___byte3___width 8
+#define reg_iop_sw_spu_rw_bus1_clr_mask_offset 44
+
+/* Register rw_bus1_set_mask, scope iop_sw_spu, type rw */
+#define reg_iop_sw_spu_rw_bus1_set_mask___byte0___lsb 0
+#define reg_iop_sw_spu_rw_bus1_set_mask___byte0___width 8
+#define reg_iop_sw_spu_rw_bus1_set_mask___byte1___lsb 8
+#define reg_iop_sw_spu_rw_bus1_set_mask___byte1___width 8
+#define reg_iop_sw_spu_rw_bus1_set_mask___byte2___lsb 16
+#define reg_iop_sw_spu_rw_bus1_set_mask___byte2___width 8
+#define reg_iop_sw_spu_rw_bus1_set_mask___byte3___lsb 24
+#define reg_iop_sw_spu_rw_bus1_set_mask___byte3___width 8
+#define reg_iop_sw_spu_rw_bus1_set_mask_offset 48
+
+/* Register rw_bus1_oe_clr_mask, scope iop_sw_spu, type rw */
+#define reg_iop_sw_spu_rw_bus1_oe_clr_mask___byte0___lsb 0
+#define reg_iop_sw_spu_rw_bus1_oe_clr_mask___byte0___width 1
+#define reg_iop_sw_spu_rw_bus1_oe_clr_mask___byte0___bit 0
+#define reg_iop_sw_spu_rw_bus1_oe_clr_mask___byte1___lsb 1
+#define reg_iop_sw_spu_rw_bus1_oe_clr_mask___byte1___width 1
+#define reg_iop_sw_spu_rw_bus1_oe_clr_mask___byte1___bit 1
+#define reg_iop_sw_spu_rw_bus1_oe_clr_mask___byte2___lsb 2
+#define reg_iop_sw_spu_rw_bus1_oe_clr_mask___byte2___width 1
+#define reg_iop_sw_spu_rw_bus1_oe_clr_mask___byte2___bit 2
+#define reg_iop_sw_spu_rw_bus1_oe_clr_mask___byte3___lsb 3
+#define reg_iop_sw_spu_rw_bus1_oe_clr_mask___byte3___width 1
+#define reg_iop_sw_spu_rw_bus1_oe_clr_mask___byte3___bit 3
+#define reg_iop_sw_spu_rw_bus1_oe_clr_mask_offset 52
+
+/* Register rw_bus1_oe_set_mask, scope iop_sw_spu, type rw */
+#define reg_iop_sw_spu_rw_bus1_oe_set_mask___byte0___lsb 0
+#define reg_iop_sw_spu_rw_bus1_oe_set_mask___byte0___width 1
+#define reg_iop_sw_spu_rw_bus1_oe_set_mask___byte0___bit 0
+#define reg_iop_sw_spu_rw_bus1_oe_set_mask___byte1___lsb 1
+#define reg_iop_sw_spu_rw_bus1_oe_set_mask___byte1___width 1
+#define reg_iop_sw_spu_rw_bus1_oe_set_mask___byte1___bit 1
+#define reg_iop_sw_spu_rw_bus1_oe_set_mask___byte2___lsb 2
+#define reg_iop_sw_spu_rw_bus1_oe_set_mask___byte2___width 1
+#define reg_iop_sw_spu_rw_bus1_oe_set_mask___byte2___bit 2
+#define reg_iop_sw_spu_rw_bus1_oe_set_mask___byte3___lsb 3
+#define reg_iop_sw_spu_rw_bus1_oe_set_mask___byte3___width 1
+#define reg_iop_sw_spu_rw_bus1_oe_set_mask___byte3___bit 3
+#define reg_iop_sw_spu_rw_bus1_oe_set_mask_offset 56
+
+/* Register r_bus1_in, scope iop_sw_spu, type r */
+#define reg_iop_sw_spu_r_bus1_in_offset 60
+
+/* Register rw_gio_clr_mask, scope iop_sw_spu, type rw */
+#define reg_iop_sw_spu_rw_gio_clr_mask___val___lsb 0
+#define reg_iop_sw_spu_rw_gio_clr_mask___val___width 32
+#define reg_iop_sw_spu_rw_gio_clr_mask_offset 64
+
+/* Register rw_gio_set_mask, scope iop_sw_spu, type rw */
+#define reg_iop_sw_spu_rw_gio_set_mask___val___lsb 0
+#define reg_iop_sw_spu_rw_gio_set_mask___val___width 32
+#define reg_iop_sw_spu_rw_gio_set_mask_offset 68
+
+/* Register rw_gio_oe_clr_mask, scope iop_sw_spu, type rw */
+#define reg_iop_sw_spu_rw_gio_oe_clr_mask___val___lsb 0
+#define reg_iop_sw_spu_rw_gio_oe_clr_mask___val___width 32
+#define reg_iop_sw_spu_rw_gio_oe_clr_mask_offset 72
+
+/* Register rw_gio_oe_set_mask, scope iop_sw_spu, type rw */
+#define reg_iop_sw_spu_rw_gio_oe_set_mask___val___lsb 0
+#define reg_iop_sw_spu_rw_gio_oe_set_mask___val___width 32
+#define reg_iop_sw_spu_rw_gio_oe_set_mask_offset 76
+
+/* Register r_gio_in, scope iop_sw_spu, type r */
+#define reg_iop_sw_spu_r_gio_in_offset 80
+
+/* Register rw_bus0_clr_mask_lo, scope iop_sw_spu, type rw */
+#define reg_iop_sw_spu_rw_bus0_clr_mask_lo___byte0___lsb 0
+#define reg_iop_sw_spu_rw_bus0_clr_mask_lo___byte0___width 8
+#define reg_iop_sw_spu_rw_bus0_clr_mask_lo___byte1___lsb 8
+#define reg_iop_sw_spu_rw_bus0_clr_mask_lo___byte1___width 8
+#define reg_iop_sw_spu_rw_bus0_clr_mask_lo_offset 84
+
+/* Register rw_bus0_clr_mask_hi, scope iop_sw_spu, type rw */
+#define reg_iop_sw_spu_rw_bus0_clr_mask_hi___byte2___lsb 0
+#define reg_iop_sw_spu_rw_bus0_clr_mask_hi___byte2___width 8
+#define reg_iop_sw_spu_rw_bus0_clr_mask_hi___byte3___lsb 8
+#define reg_iop_sw_spu_rw_bus0_clr_mask_hi___byte3___width 8
+#define reg_iop_sw_spu_rw_bus0_clr_mask_hi_offset 88
+
+/* Register rw_bus0_set_mask_lo, scope iop_sw_spu, type rw */
+#define reg_iop_sw_spu_rw_bus0_set_mask_lo___byte0___lsb 0
+#define reg_iop_sw_spu_rw_bus0_set_mask_lo___byte0___width 8
+#define reg_iop_sw_spu_rw_bus0_set_mask_lo___byte1___lsb 8
+#define reg_iop_sw_spu_rw_bus0_set_mask_lo___byte1___width 8
+#define reg_iop_sw_spu_rw_bus0_set_mask_lo_offset 92
+
+/* Register rw_bus0_set_mask_hi, scope iop_sw_spu, type rw */
+#define reg_iop_sw_spu_rw_bus0_set_mask_hi___byte2___lsb 0
+#define reg_iop_sw_spu_rw_bus0_set_mask_hi___byte2___width 8
+#define reg_iop_sw_spu_rw_bus0_set_mask_hi___byte3___lsb 8
+#define reg_iop_sw_spu_rw_bus0_set_mask_hi___byte3___width 8
+#define reg_iop_sw_spu_rw_bus0_set_mask_hi_offset 96
+
+/* Register rw_bus1_clr_mask_lo, scope iop_sw_spu, type rw */
+#define reg_iop_sw_spu_rw_bus1_clr_mask_lo___byte0___lsb 0
+#define reg_iop_sw_spu_rw_bus1_clr_mask_lo___byte0___width 8
+#define reg_iop_sw_spu_rw_bus1_clr_mask_lo___byte1___lsb 8
+#define reg_iop_sw_spu_rw_bus1_clr_mask_lo___byte1___width 8
+#define reg_iop_sw_spu_rw_bus1_clr_mask_lo_offset 100
+
+/* Register rw_bus1_clr_mask_hi, scope iop_sw_spu, type rw */
+#define reg_iop_sw_spu_rw_bus1_clr_mask_hi___byte2___lsb 0
+#define reg_iop_sw_spu_rw_bus1_clr_mask_hi___byte2___width 8
+#define reg_iop_sw_spu_rw_bus1_clr_mask_hi___byte3___lsb 8
+#define reg_iop_sw_spu_rw_bus1_clr_mask_hi___byte3___width 8
+#define reg_iop_sw_spu_rw_bus1_clr_mask_hi_offset 104
+
+/* Register rw_bus1_set_mask_lo, scope iop_sw_spu, type rw */
+#define reg_iop_sw_spu_rw_bus1_set_mask_lo___byte0___lsb 0
+#define reg_iop_sw_spu_rw_bus1_set_mask_lo___byte0___width 8
+#define reg_iop_sw_spu_rw_bus1_set_mask_lo___byte1___lsb 8
+#define reg_iop_sw_spu_rw_bus1_set_mask_lo___byte1___width 8
+#define reg_iop_sw_spu_rw_bus1_set_mask_lo_offset 108
+
+/* Register rw_bus1_set_mask_hi, scope iop_sw_spu, type rw */
+#define reg_iop_sw_spu_rw_bus1_set_mask_hi___byte2___lsb 0
+#define reg_iop_sw_spu_rw_bus1_set_mask_hi___byte2___width 8
+#define reg_iop_sw_spu_rw_bus1_set_mask_hi___byte3___lsb 8
+#define reg_iop_sw_spu_rw_bus1_set_mask_hi___byte3___width 8
+#define reg_iop_sw_spu_rw_bus1_set_mask_hi_offset 112
+
+/* Register rw_gio_clr_mask_lo, scope iop_sw_spu, type rw */
+#define reg_iop_sw_spu_rw_gio_clr_mask_lo___val___lsb 0
+#define reg_iop_sw_spu_rw_gio_clr_mask_lo___val___width 16
+#define reg_iop_sw_spu_rw_gio_clr_mask_lo_offset 116
+
+/* Register rw_gio_clr_mask_hi, scope iop_sw_spu, type rw */
+#define reg_iop_sw_spu_rw_gio_clr_mask_hi___val___lsb 0
+#define reg_iop_sw_spu_rw_gio_clr_mask_hi___val___width 16
+#define reg_iop_sw_spu_rw_gio_clr_mask_hi_offset 120
+
+/* Register rw_gio_set_mask_lo, scope iop_sw_spu, type rw */
+#define reg_iop_sw_spu_rw_gio_set_mask_lo___val___lsb 0
+#define reg_iop_sw_spu_rw_gio_set_mask_lo___val___width 16
+#define reg_iop_sw_spu_rw_gio_set_mask_lo_offset 124
+
+/* Register rw_gio_set_mask_hi, scope iop_sw_spu, type rw */
+#define reg_iop_sw_spu_rw_gio_set_mask_hi___val___lsb 0
+#define reg_iop_sw_spu_rw_gio_set_mask_hi___val___width 16
+#define reg_iop_sw_spu_rw_gio_set_mask_hi_offset 128
+
+/* Register rw_gio_oe_clr_mask_lo, scope iop_sw_spu, type rw */
+#define reg_iop_sw_spu_rw_gio_oe_clr_mask_lo___val___lsb 0
+#define reg_iop_sw_spu_rw_gio_oe_clr_mask_lo___val___width 16
+#define reg_iop_sw_spu_rw_gio_oe_clr_mask_lo_offset 132
+
+/* Register rw_gio_oe_clr_mask_hi, scope iop_sw_spu, type rw */
+#define reg_iop_sw_spu_rw_gio_oe_clr_mask_hi___val___lsb 0
+#define reg_iop_sw_spu_rw_gio_oe_clr_mask_hi___val___width 16
+#define reg_iop_sw_spu_rw_gio_oe_clr_mask_hi_offset 136
+
+/* Register rw_gio_oe_set_mask_lo, scope iop_sw_spu, type rw */
+#define reg_iop_sw_spu_rw_gio_oe_set_mask_lo___val___lsb 0
+#define reg_iop_sw_spu_rw_gio_oe_set_mask_lo___val___width 16
+#define reg_iop_sw_spu_rw_gio_oe_set_mask_lo_offset 140
+
+/* Register rw_gio_oe_set_mask_hi, scope iop_sw_spu, type rw */
+#define reg_iop_sw_spu_rw_gio_oe_set_mask_hi___val___lsb 0
+#define reg_iop_sw_spu_rw_gio_oe_set_mask_hi___val___width 16
+#define reg_iop_sw_spu_rw_gio_oe_set_mask_hi_offset 144
+
+/* Register rw_cpu_intr, scope iop_sw_spu, type rw */
+#define reg_iop_sw_spu_rw_cpu_intr___intr0___lsb 0
+#define reg_iop_sw_spu_rw_cpu_intr___intr0___width 1
+#define reg_iop_sw_spu_rw_cpu_intr___intr0___bit 0
+#define reg_iop_sw_spu_rw_cpu_intr___intr1___lsb 1
+#define reg_iop_sw_spu_rw_cpu_intr___intr1___width 1
+#define reg_iop_sw_spu_rw_cpu_intr___intr1___bit 1
+#define reg_iop_sw_spu_rw_cpu_intr___intr2___lsb 2
+#define reg_iop_sw_spu_rw_cpu_intr___intr2___width 1
+#define reg_iop_sw_spu_rw_cpu_intr___intr2___bit 2
+#define reg_iop_sw_spu_rw_cpu_intr___intr3___lsb 3
+#define reg_iop_sw_spu_rw_cpu_intr___intr3___width 1
+#define reg_iop_sw_spu_rw_cpu_intr___intr3___bit 3
+#define reg_iop_sw_spu_rw_cpu_intr___intr4___lsb 4
+#define reg_iop_sw_spu_rw_cpu_intr___intr4___width 1
+#define reg_iop_sw_spu_rw_cpu_intr___intr4___bit 4
+#define reg_iop_sw_spu_rw_cpu_intr___intr5___lsb 5
+#define reg_iop_sw_spu_rw_cpu_intr___intr5___width 1
+#define reg_iop_sw_spu_rw_cpu_intr___intr5___bit 5
+#define reg_iop_sw_spu_rw_cpu_intr___intr6___lsb 6
+#define reg_iop_sw_spu_rw_cpu_intr___intr6___width 1
+#define reg_iop_sw_spu_rw_cpu_intr___intr6___bit 6
+#define reg_iop_sw_spu_rw_cpu_intr___intr7___lsb 7
+#define reg_iop_sw_spu_rw_cpu_intr___intr7___width 1
+#define reg_iop_sw_spu_rw_cpu_intr___intr7___bit 7
+#define reg_iop_sw_spu_rw_cpu_intr___intr8___lsb 8
+#define reg_iop_sw_spu_rw_cpu_intr___intr8___width 1
+#define reg_iop_sw_spu_rw_cpu_intr___intr8___bit 8
+#define reg_iop_sw_spu_rw_cpu_intr___intr9___lsb 9
+#define reg_iop_sw_spu_rw_cpu_intr___intr9___width 1
+#define reg_iop_sw_spu_rw_cpu_intr___intr9___bit 9
+#define reg_iop_sw_spu_rw_cpu_intr___intr10___lsb 10
+#define reg_iop_sw_spu_rw_cpu_intr___intr10___width 1
+#define reg_iop_sw_spu_rw_cpu_intr___intr10___bit 10
+#define reg_iop_sw_spu_rw_cpu_intr___intr11___lsb 11
+#define reg_iop_sw_spu_rw_cpu_intr___intr11___width 1
+#define reg_iop_sw_spu_rw_cpu_intr___intr11___bit 11
+#define reg_iop_sw_spu_rw_cpu_intr___intr12___lsb 12
+#define reg_iop_sw_spu_rw_cpu_intr___intr12___width 1
+#define reg_iop_sw_spu_rw_cpu_intr___intr12___bit 12
+#define reg_iop_sw_spu_rw_cpu_intr___intr13___lsb 13
+#define reg_iop_sw_spu_rw_cpu_intr___intr13___width 1
+#define reg_iop_sw_spu_rw_cpu_intr___intr13___bit 13
+#define reg_iop_sw_spu_rw_cpu_intr___intr14___lsb 14
+#define reg_iop_sw_spu_rw_cpu_intr___intr14___width 1
+#define reg_iop_sw_spu_rw_cpu_intr___intr14___bit 14
+#define reg_iop_sw_spu_rw_cpu_intr___intr15___lsb 15
+#define reg_iop_sw_spu_rw_cpu_intr___intr15___width 1
+#define reg_iop_sw_spu_rw_cpu_intr___intr15___bit 15
+#define reg_iop_sw_spu_rw_cpu_intr_offset 148
+
+/* Register r_cpu_intr, scope iop_sw_spu, type r */
+#define reg_iop_sw_spu_r_cpu_intr___intr0___lsb 0
+#define reg_iop_sw_spu_r_cpu_intr___intr0___width 1
+#define reg_iop_sw_spu_r_cpu_intr___intr0___bit 0
+#define reg_iop_sw_spu_r_cpu_intr___intr1___lsb 1
+#define reg_iop_sw_spu_r_cpu_intr___intr1___width 1
+#define reg_iop_sw_spu_r_cpu_intr___intr1___bit 1
+#define reg_iop_sw_spu_r_cpu_intr___intr2___lsb 2
+#define reg_iop_sw_spu_r_cpu_intr___intr2___width 1
+#define reg_iop_sw_spu_r_cpu_intr___intr2___bit 2
+#define reg_iop_sw_spu_r_cpu_intr___intr3___lsb 3
+#define reg_iop_sw_spu_r_cpu_intr___intr3___width 1
+#define reg_iop_sw_spu_r_cpu_intr___intr3___bit 3
+#define reg_iop_sw_spu_r_cpu_intr___intr4___lsb 4
+#define reg_iop_sw_spu_r_cpu_intr___intr4___width 1
+#define reg_iop_sw_spu_r_cpu_intr___intr4___bit 4
+#define reg_iop_sw_spu_r_cpu_intr___intr5___lsb 5
+#define reg_iop_sw_spu_r_cpu_intr___intr5___width 1
+#define reg_iop_sw_spu_r_cpu_intr___intr5___bit 5
+#define reg_iop_sw_spu_r_cpu_intr___intr6___lsb 6
+#define reg_iop_sw_spu_r_cpu_intr___intr6___width 1
+#define reg_iop_sw_spu_r_cpu_intr___intr6___bit 6
+#define reg_iop_sw_spu_r_cpu_intr___intr7___lsb 7
+#define reg_iop_sw_spu_r_cpu_intr___intr7___width 1
+#define reg_iop_sw_spu_r_cpu_intr___intr7___bit 7
+#define reg_iop_sw_spu_r_cpu_intr___intr8___lsb 8
+#define reg_iop_sw_spu_r_cpu_intr___intr8___width 1
+#define reg_iop_sw_spu_r_cpu_intr___intr8___bit 8
+#define reg_iop_sw_spu_r_cpu_intr___intr9___lsb 9
+#define reg_iop_sw_spu_r_cpu_intr___intr9___width 1
+#define reg_iop_sw_spu_r_cpu_intr___intr9___bit 9
+#define reg_iop_sw_spu_r_cpu_intr___intr10___lsb 10
+#define reg_iop_sw_spu_r_cpu_intr___intr10___width 1
+#define reg_iop_sw_spu_r_cpu_intr___intr10___bit 10
+#define reg_iop_sw_spu_r_cpu_intr___intr11___lsb 11
+#define reg_iop_sw_spu_r_cpu_intr___intr11___width 1
+#define reg_iop_sw_spu_r_cpu_intr___intr11___bit 11
+#define reg_iop_sw_spu_r_cpu_intr___intr12___lsb 12
+#define reg_iop_sw_spu_r_cpu_intr___intr12___width 1
+#define reg_iop_sw_spu_r_cpu_intr___intr12___bit 12
+#define reg_iop_sw_spu_r_cpu_intr___intr13___lsb 13
+#define reg_iop_sw_spu_r_cpu_intr___intr13___width 1
+#define reg_iop_sw_spu_r_cpu_intr___intr13___bit 13
+#define reg_iop_sw_spu_r_cpu_intr___intr14___lsb 14
+#define reg_iop_sw_spu_r_cpu_intr___intr14___width 1
+#define reg_iop_sw_spu_r_cpu_intr___intr14___bit 14
+#define reg_iop_sw_spu_r_cpu_intr___intr15___lsb 15
+#define reg_iop_sw_spu_r_cpu_intr___intr15___width 1
+#define reg_iop_sw_spu_r_cpu_intr___intr15___bit 15
+#define reg_iop_sw_spu_r_cpu_intr_offset 152
+
+/* Register r_hw_intr, scope iop_sw_spu, type r */
+#define reg_iop_sw_spu_r_hw_intr___trigger_grp0___lsb 0
+#define reg_iop_sw_spu_r_hw_intr___trigger_grp0___width 1
+#define reg_iop_sw_spu_r_hw_intr___trigger_grp0___bit 0
+#define reg_iop_sw_spu_r_hw_intr___trigger_grp1___lsb 1
+#define reg_iop_sw_spu_r_hw_intr___trigger_grp1___width 1
+#define reg_iop_sw_spu_r_hw_intr___trigger_grp1___bit 1
+#define reg_iop_sw_spu_r_hw_intr___trigger_grp2___lsb 2
+#define reg_iop_sw_spu_r_hw_intr___trigger_grp2___width 1
+#define reg_iop_sw_spu_r_hw_intr___trigger_grp2___bit 2
+#define reg_iop_sw_spu_r_hw_intr___trigger_grp3___lsb 3
+#define reg_iop_sw_spu_r_hw_intr___trigger_grp3___width 1
+#define reg_iop_sw_spu_r_hw_intr___trigger_grp3___bit 3
+#define reg_iop_sw_spu_r_hw_intr___trigger_grp4___lsb 4
+#define reg_iop_sw_spu_r_hw_intr___trigger_grp4___width 1
+#define reg_iop_sw_spu_r_hw_intr___trigger_grp4___bit 4
+#define reg_iop_sw_spu_r_hw_intr___trigger_grp5___lsb 5
+#define reg_iop_sw_spu_r_hw_intr___trigger_grp5___width 1
+#define reg_iop_sw_spu_r_hw_intr___trigger_grp5___bit 5
+#define reg_iop_sw_spu_r_hw_intr___trigger_grp6___lsb 6
+#define reg_iop_sw_spu_r_hw_intr___trigger_grp6___width 1
+#define reg_iop_sw_spu_r_hw_intr___trigger_grp6___bit 6
+#define reg_iop_sw_spu_r_hw_intr___trigger_grp7___lsb 7
+#define reg_iop_sw_spu_r_hw_intr___trigger_grp7___width 1
+#define reg_iop_sw_spu_r_hw_intr___trigger_grp7___bit 7
+#define reg_iop_sw_spu_r_hw_intr___timer_grp0___lsb 8
+#define reg_iop_sw_spu_r_hw_intr___timer_grp0___width 1
+#define reg_iop_sw_spu_r_hw_intr___timer_grp0___bit 8
+#define reg_iop_sw_spu_r_hw_intr___timer_grp1___lsb 9
+#define reg_iop_sw_spu_r_hw_intr___timer_grp1___width 1
+#define reg_iop_sw_spu_r_hw_intr___timer_grp1___bit 9
+#define reg_iop_sw_spu_r_hw_intr___timer_grp2___lsb 10
+#define reg_iop_sw_spu_r_hw_intr___timer_grp2___width 1
+#define reg_iop_sw_spu_r_hw_intr___timer_grp2___bit 10
+#define reg_iop_sw_spu_r_hw_intr___timer_grp3___lsb 11
+#define reg_iop_sw_spu_r_hw_intr___timer_grp3___width 1
+#define reg_iop_sw_spu_r_hw_intr___timer_grp3___bit 11
+#define reg_iop_sw_spu_r_hw_intr___fifo_out0___lsb 12
+#define reg_iop_sw_spu_r_hw_intr___fifo_out0___width 1
+#define reg_iop_sw_spu_r_hw_intr___fifo_out0___bit 12
+#define reg_iop_sw_spu_r_hw_intr___fifo_out0_extra___lsb 13
+#define reg_iop_sw_spu_r_hw_intr___fifo_out0_extra___width 1
+#define reg_iop_sw_spu_r_hw_intr___fifo_out0_extra___bit 13
+#define reg_iop_sw_spu_r_hw_intr___fifo_in0___lsb 14
+#define reg_iop_sw_spu_r_hw_intr___fifo_in0___width 1
+#define reg_iop_sw_spu_r_hw_intr___fifo_in0___bit 14
+#define reg_iop_sw_spu_r_hw_intr___fifo_in0_extra___lsb 15
+#define reg_iop_sw_spu_r_hw_intr___fifo_in0_extra___width 1
+#define reg_iop_sw_spu_r_hw_intr___fifo_in0_extra___bit 15
+#define reg_iop_sw_spu_r_hw_intr___fifo_out1___lsb 16
+#define reg_iop_sw_spu_r_hw_intr___fifo_out1___width 1
+#define reg_iop_sw_spu_r_hw_intr___fifo_out1___bit 16
+#define reg_iop_sw_spu_r_hw_intr___fifo_out1_extra___lsb 17
+#define reg_iop_sw_spu_r_hw_intr___fifo_out1_extra___width 1
+#define reg_iop_sw_spu_r_hw_intr___fifo_out1_extra___bit 17
+#define reg_iop_sw_spu_r_hw_intr___fifo_in1___lsb 18
+#define reg_iop_sw_spu_r_hw_intr___fifo_in1___width 1
+#define reg_iop_sw_spu_r_hw_intr___fifo_in1___bit 18
+#define reg_iop_sw_spu_r_hw_intr___fifo_in1_extra___lsb 19
+#define reg_iop_sw_spu_r_hw_intr___fifo_in1_extra___width 1
+#define reg_iop_sw_spu_r_hw_intr___fifo_in1_extra___bit 19
+#define reg_iop_sw_spu_r_hw_intr___dmc_out0___lsb 20
+#define reg_iop_sw_spu_r_hw_intr___dmc_out0___width 1
+#define reg_iop_sw_spu_r_hw_intr___dmc_out0___bit 20
+#define reg_iop_sw_spu_r_hw_intr___dmc_in0___lsb 21
+#define reg_iop_sw_spu_r_hw_intr___dmc_in0___width 1
+#define reg_iop_sw_spu_r_hw_intr___dmc_in0___bit 21
+#define reg_iop_sw_spu_r_hw_intr___dmc_out1___lsb 22
+#define reg_iop_sw_spu_r_hw_intr___dmc_out1___width 1
+#define reg_iop_sw_spu_r_hw_intr___dmc_out1___bit 22
+#define reg_iop_sw_spu_r_hw_intr___dmc_in1___lsb 23
+#define reg_iop_sw_spu_r_hw_intr___dmc_in1___width 1
+#define reg_iop_sw_spu_r_hw_intr___dmc_in1___bit 23
+#define reg_iop_sw_spu_r_hw_intr_offset 156
+
+/* Register rw_mpu_intr, scope iop_sw_spu, type rw */
+#define reg_iop_sw_spu_rw_mpu_intr___intr0___lsb 0
+#define reg_iop_sw_spu_rw_mpu_intr___intr0___width 1
+#define reg_iop_sw_spu_rw_mpu_intr___intr0___bit 0
+#define reg_iop_sw_spu_rw_mpu_intr___intr1___lsb 1
+#define reg_iop_sw_spu_rw_mpu_intr___intr1___width 1
+#define reg_iop_sw_spu_rw_mpu_intr___intr1___bit 1
+#define reg_iop_sw_spu_rw_mpu_intr___intr2___lsb 2
+#define reg_iop_sw_spu_rw_mpu_intr___intr2___width 1
+#define reg_iop_sw_spu_rw_mpu_intr___intr2___bit 2
+#define reg_iop_sw_spu_rw_mpu_intr___intr3___lsb 3
+#define reg_iop_sw_spu_rw_mpu_intr___intr3___width 1
+#define reg_iop_sw_spu_rw_mpu_intr___intr3___bit 3
+#define reg_iop_sw_spu_rw_mpu_intr___intr4___lsb 4
+#define reg_iop_sw_spu_rw_mpu_intr___intr4___width 1
+#define reg_iop_sw_spu_rw_mpu_intr___intr4___bit 4
+#define reg_iop_sw_spu_rw_mpu_intr___intr5___lsb 5
+#define reg_iop_sw_spu_rw_mpu_intr___intr5___width 1
+#define reg_iop_sw_spu_rw_mpu_intr___intr5___bit 5
+#define reg_iop_sw_spu_rw_mpu_intr___intr6___lsb 6
+#define reg_iop_sw_spu_rw_mpu_intr___intr6___width 1
+#define reg_iop_sw_spu_rw_mpu_intr___intr6___bit 6
+#define reg_iop_sw_spu_rw_mpu_intr___intr7___lsb 7
+#define reg_iop_sw_spu_rw_mpu_intr___intr7___width 1
+#define reg_iop_sw_spu_rw_mpu_intr___intr7___bit 7
+#define reg_iop_sw_spu_rw_mpu_intr___intr8___lsb 8
+#define reg_iop_sw_spu_rw_mpu_intr___intr8___width 1
+#define reg_iop_sw_spu_rw_mpu_intr___intr8___bit 8
+#define reg_iop_sw_spu_rw_mpu_intr___intr9___lsb 9
+#define reg_iop_sw_spu_rw_mpu_intr___intr9___width 1
+#define reg_iop_sw_spu_rw_mpu_intr___intr9___bit 9
+#define reg_iop_sw_spu_rw_mpu_intr___intr10___lsb 10
+#define reg_iop_sw_spu_rw_mpu_intr___intr10___width 1
+#define reg_iop_sw_spu_rw_mpu_intr___intr10___bit 10
+#define reg_iop_sw_spu_rw_mpu_intr___intr11___lsb 11
+#define reg_iop_sw_spu_rw_mpu_intr___intr11___width 1
+#define reg_iop_sw_spu_rw_mpu_intr___intr11___bit 11
+#define reg_iop_sw_spu_rw_mpu_intr___intr12___lsb 12
+#define reg_iop_sw_spu_rw_mpu_intr___intr12___width 1
+#define reg_iop_sw_spu_rw_mpu_intr___intr12___bit 12
+#define reg_iop_sw_spu_rw_mpu_intr___intr13___lsb 13
+#define reg_iop_sw_spu_rw_mpu_intr___intr13___width 1
+#define reg_iop_sw_spu_rw_mpu_intr___intr13___bit 13
+#define reg_iop_sw_spu_rw_mpu_intr___intr14___lsb 14
+#define reg_iop_sw_spu_rw_mpu_intr___intr14___width 1
+#define reg_iop_sw_spu_rw_mpu_intr___intr14___bit 14
+#define reg_iop_sw_spu_rw_mpu_intr___intr15___lsb 15
+#define reg_iop_sw_spu_rw_mpu_intr___intr15___width 1
+#define reg_iop_sw_spu_rw_mpu_intr___intr15___bit 15
+#define reg_iop_sw_spu_rw_mpu_intr_offset 160
+
+/* Register r_mpu_intr, scope iop_sw_spu, type r */
+#define reg_iop_sw_spu_r_mpu_intr___intr0___lsb 0
+#define reg_iop_sw_spu_r_mpu_intr___intr0___width 1
+#define reg_iop_sw_spu_r_mpu_intr___intr0___bit 0
+#define reg_iop_sw_spu_r_mpu_intr___intr1___lsb 1
+#define reg_iop_sw_spu_r_mpu_intr___intr1___width 1
+#define reg_iop_sw_spu_r_mpu_intr___intr1___bit 1
+#define reg_iop_sw_spu_r_mpu_intr___intr2___lsb 2
+#define reg_iop_sw_spu_r_mpu_intr___intr2___width 1
+#define reg_iop_sw_spu_r_mpu_intr___intr2___bit 2
+#define reg_iop_sw_spu_r_mpu_intr___intr3___lsb 3
+#define reg_iop_sw_spu_r_mpu_intr___intr3___width 1
+#define reg_iop_sw_spu_r_mpu_intr___intr3___bit 3
+#define reg_iop_sw_spu_r_mpu_intr___intr4___lsb 4
+#define reg_iop_sw_spu_r_mpu_intr___intr4___width 1
+#define reg_iop_sw_spu_r_mpu_intr___intr4___bit 4
+#define reg_iop_sw_spu_r_mpu_intr___intr5___lsb 5
+#define reg_iop_sw_spu_r_mpu_intr___intr5___width 1
+#define reg_iop_sw_spu_r_mpu_intr___intr5___bit 5
+#define reg_iop_sw_spu_r_mpu_intr___intr6___lsb 6
+#define reg_iop_sw_spu_r_mpu_intr___intr6___width 1
+#define reg_iop_sw_spu_r_mpu_intr___intr6___bit 6
+#define reg_iop_sw_spu_r_mpu_intr___intr7___lsb 7
+#define reg_iop_sw_spu_r_mpu_intr___intr7___width 1
+#define reg_iop_sw_spu_r_mpu_intr___intr7___bit 7
+#define reg_iop_sw_spu_r_mpu_intr___intr8___lsb 8
+#define reg_iop_sw_spu_r_mpu_intr___intr8___width 1
+#define reg_iop_sw_spu_r_mpu_intr___intr8___bit 8
+#define reg_iop_sw_spu_r_mpu_intr___intr9___lsb 9
+#define reg_iop_sw_spu_r_mpu_intr___intr9___width 1
+#define reg_iop_sw_spu_r_mpu_intr___intr9___bit 9
+#define reg_iop_sw_spu_r_mpu_intr___intr10___lsb 10
+#define reg_iop_sw_spu_r_mpu_intr___intr10___width 1
+#define reg_iop_sw_spu_r_mpu_intr___intr10___bit 10
+#define reg_iop_sw_spu_r_mpu_intr___intr11___lsb 11
+#define reg_iop_sw_spu_r_mpu_intr___intr11___width 1
+#define reg_iop_sw_spu_r_mpu_intr___intr11___bit 11
+#define reg_iop_sw_spu_r_mpu_intr___intr12___lsb 12
+#define reg_iop_sw_spu_r_mpu_intr___intr12___width 1
+#define reg_iop_sw_spu_r_mpu_intr___intr12___bit 12
+#define reg_iop_sw_spu_r_mpu_intr___intr13___lsb 13
+#define reg_iop_sw_spu_r_mpu_intr___intr13___width 1
+#define reg_iop_sw_spu_r_mpu_intr___intr13___bit 13
+#define reg_iop_sw_spu_r_mpu_intr___intr14___lsb 14
+#define reg_iop_sw_spu_r_mpu_intr___intr14___width 1
+#define reg_iop_sw_spu_r_mpu_intr___intr14___bit 14
+#define reg_iop_sw_spu_r_mpu_intr___intr15___lsb 15
+#define reg_iop_sw_spu_r_mpu_intr___intr15___width 1
+#define reg_iop_sw_spu_r_mpu_intr___intr15___bit 15
+#define reg_iop_sw_spu_r_mpu_intr___other_spu_intr0___lsb 16
+#define reg_iop_sw_spu_r_mpu_intr___other_spu_intr0___width 1
+#define reg_iop_sw_spu_r_mpu_intr___other_spu_intr0___bit 16
+#define reg_iop_sw_spu_r_mpu_intr___other_spu_intr1___lsb 17
+#define reg_iop_sw_spu_r_mpu_intr___other_spu_intr1___width 1
+#define reg_iop_sw_spu_r_mpu_intr___other_spu_intr1___bit 17
+#define reg_iop_sw_spu_r_mpu_intr___other_spu_intr2___lsb 18
+#define reg_iop_sw_spu_r_mpu_intr___other_spu_intr2___width 1
+#define reg_iop_sw_spu_r_mpu_intr___other_spu_intr2___bit 18
+#define reg_iop_sw_spu_r_mpu_intr___other_spu_intr3___lsb 19
+#define reg_iop_sw_spu_r_mpu_intr___other_spu_intr3___width 1
+#define reg_iop_sw_spu_r_mpu_intr___other_spu_intr3___bit 19
+#define reg_iop_sw_spu_r_mpu_intr___other_spu_intr4___lsb 20
+#define reg_iop_sw_spu_r_mpu_intr___other_spu_intr4___width 1
+#define reg_iop_sw_spu_r_mpu_intr___other_spu_intr4___bit 20
+#define reg_iop_sw_spu_r_mpu_intr___other_spu_intr5___lsb 21
+#define reg_iop_sw_spu_r_mpu_intr___other_spu_intr5___width 1
+#define reg_iop_sw_spu_r_mpu_intr___other_spu_intr5___bit 21
+#define reg_iop_sw_spu_r_mpu_intr___other_spu_intr6___lsb 22
+#define reg_iop_sw_spu_r_mpu_intr___other_spu_intr6___width 1
+#define reg_iop_sw_spu_r_mpu_intr___other_spu_intr6___bit 22
+#define reg_iop_sw_spu_r_mpu_intr___other_spu_intr7___lsb 23
+#define reg_iop_sw_spu_r_mpu_intr___other_spu_intr7___width 1
+#define reg_iop_sw_spu_r_mpu_intr___other_spu_intr7___bit 23
+#define reg_iop_sw_spu_r_mpu_intr___other_spu_intr8___lsb 24
+#define reg_iop_sw_spu_r_mpu_intr___other_spu_intr8___width 1
+#define reg_iop_sw_spu_r_mpu_intr___other_spu_intr8___bit 24
+#define reg_iop_sw_spu_r_mpu_intr___other_spu_intr9___lsb 25
+#define reg_iop_sw_spu_r_mpu_intr___other_spu_intr9___width 1
+#define reg_iop_sw_spu_r_mpu_intr___other_spu_intr9___bit 25
+#define reg_iop_sw_spu_r_mpu_intr___other_spu_intr10___lsb 26
+#define reg_iop_sw_spu_r_mpu_intr___other_spu_intr10___width 1
+#define reg_iop_sw_spu_r_mpu_intr___other_spu_intr10___bit 26
+#define reg_iop_sw_spu_r_mpu_intr___other_spu_intr11___lsb 27
+#define reg_iop_sw_spu_r_mpu_intr___other_spu_intr11___width 1
+#define reg_iop_sw_spu_r_mpu_intr___other_spu_intr11___bit 27
+#define reg_iop_sw_spu_r_mpu_intr___other_spu_intr12___lsb 28
+#define reg_iop_sw_spu_r_mpu_intr___other_spu_intr12___width 1
+#define reg_iop_sw_spu_r_mpu_intr___other_spu_intr12___bit 28
+#define reg_iop_sw_spu_r_mpu_intr___other_spu_intr13___lsb 29
+#define reg_iop_sw_spu_r_mpu_intr___other_spu_intr13___width 1
+#define reg_iop_sw_spu_r_mpu_intr___other_spu_intr13___bit 29
+#define reg_iop_sw_spu_r_mpu_intr___other_spu_intr14___lsb 30
+#define reg_iop_sw_spu_r_mpu_intr___other_spu_intr14___width 1
+#define reg_iop_sw_spu_r_mpu_intr___other_spu_intr14___bit 30
+#define reg_iop_sw_spu_r_mpu_intr___other_spu_intr15___lsb 31
+#define reg_iop_sw_spu_r_mpu_intr___other_spu_intr15___width 1
+#define reg_iop_sw_spu_r_mpu_intr___other_spu_intr15___bit 31
+#define reg_iop_sw_spu_r_mpu_intr_offset 164
+
+
+/* Constants */
+#define regk_iop_sw_spu_copy                      0x00000000
+#define regk_iop_sw_spu_no                        0x00000000
+#define regk_iop_sw_spu_nop                       0x00000000
+#define regk_iop_sw_spu_rd                        0x00000002
+#define regk_iop_sw_spu_reg_copy                  0x00000001
+#define regk_iop_sw_spu_rw_bus0_clr_mask_default  0x00000000
+#define regk_iop_sw_spu_rw_bus0_oe_clr_mask_default  0x00000000
+#define regk_iop_sw_spu_rw_bus0_oe_set_mask_default  0x00000000
+#define regk_iop_sw_spu_rw_bus0_set_mask_default  0x00000000
+#define regk_iop_sw_spu_rw_bus1_clr_mask_default  0x00000000
+#define regk_iop_sw_spu_rw_bus1_oe_clr_mask_default  0x00000000
+#define regk_iop_sw_spu_rw_bus1_oe_set_mask_default  0x00000000
+#define regk_iop_sw_spu_rw_bus1_set_mask_default  0x00000000
+#define regk_iop_sw_spu_rw_gio_clr_mask_default   0x00000000
+#define regk_iop_sw_spu_rw_gio_oe_clr_mask_default  0x00000000
+#define regk_iop_sw_spu_rw_gio_oe_set_mask_default  0x00000000
+#define regk_iop_sw_spu_rw_gio_set_mask_default   0x00000000
+#define regk_iop_sw_spu_set                       0x00000001
+#define regk_iop_sw_spu_wr                        0x00000003
+#define regk_iop_sw_spu_yes                       0x00000001
+#endif /* __iop_sw_spu_defs_asm_h */
diff --git a/include/asm-cris/arch-v32/hwregs/iop/asm/iop_timer_grp_defs_asm.h b/include/asm-cris/arch-v32/hwregs/iop/asm/iop_timer_grp_defs_asm.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/iop/asm/iop_timer_grp_defs_asm.h
@@ -0,0 +1,237 @@
+#ifndef __iop_timer_grp_defs_asm_h
+#define __iop_timer_grp_defs_asm_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/io_proc/rtl/iop_timer_grp.r
+ *     id:           iop_timer_grp.r,v 1.29 2005/02/16 09:13:27 niklaspa Exp
+ *     last modfied: Mon Apr 11 16:08:46 2005
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c -asm --outfile asm/iop_timer_grp_defs_asm.h ../../inst/io_proc/rtl/iop_timer_grp.r
+ *      id: $Id: iop_timer_grp_defs_asm.h,v 1.5 2005/04/24 18:31:07 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+
+#ifndef REG_FIELD
+#define REG_FIELD( scope, reg, field, value ) \
+  REG_FIELD_X_( value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_FIELD_X_( value, shift ) ((value) << shift)
+#endif
+
+#ifndef REG_STATE
+#define REG_STATE( scope, reg, field, symbolic_value ) \
+  REG_STATE_X_( regk_##scope##_##symbolic_value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_STATE_X_( k, shift ) (k << shift)
+#endif
+
+#ifndef REG_MASK
+#define REG_MASK( scope, reg, field ) \
+  REG_MASK_X_( reg_##scope##_##reg##___##field##___width, reg_##scope##_##reg##___##field##___lsb )
+#define REG_MASK_X_( width, lsb ) (((1 << width)-1) << lsb)
+#endif
+
+#ifndef REG_LSB
+#define REG_LSB( scope, reg, field ) reg_##scope##_##reg##___##field##___lsb
+#endif
+
+#ifndef REG_BIT
+#define REG_BIT( scope, reg, field ) reg_##scope##_##reg##___##field##___bit
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) REG_ADDR_X_(inst, reg_##scope##_##reg##_offset)
+#define REG_ADDR_X_( inst, offs ) ((inst) + offs)
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+         REG_ADDR_VECT_X_(inst, reg_##scope##_##reg##_offset, index, \
+			 STRIDE_##scope##_##reg )
+#define REG_ADDR_VECT_X_( inst, offs, index, stride ) \
+                          ((inst) + offs + (index) * stride)
+#endif
+
+/* Register rw_cfg, scope iop_timer_grp, type rw */
+#define reg_iop_timer_grp_rw_cfg___clk_src___lsb 0
+#define reg_iop_timer_grp_rw_cfg___clk_src___width 1
+#define reg_iop_timer_grp_rw_cfg___clk_src___bit 0
+#define reg_iop_timer_grp_rw_cfg___trig___lsb 1
+#define reg_iop_timer_grp_rw_cfg___trig___width 2
+#define reg_iop_timer_grp_rw_cfg___clk_gen_div___lsb 3
+#define reg_iop_timer_grp_rw_cfg___clk_gen_div___width 8
+#define reg_iop_timer_grp_rw_cfg___clk_div___lsb 11
+#define reg_iop_timer_grp_rw_cfg___clk_div___width 8
+#define reg_iop_timer_grp_rw_cfg_offset 0
+
+/* Register rw_half_period, scope iop_timer_grp, type rw */
+#define reg_iop_timer_grp_rw_half_period___quota_lo___lsb 0
+#define reg_iop_timer_grp_rw_half_period___quota_lo___width 15
+#define reg_iop_timer_grp_rw_half_period___quota_hi___lsb 15
+#define reg_iop_timer_grp_rw_half_period___quota_hi___width 15
+#define reg_iop_timer_grp_rw_half_period___quota_hi_sel___lsb 30
+#define reg_iop_timer_grp_rw_half_period___quota_hi_sel___width 1
+#define reg_iop_timer_grp_rw_half_period___quota_hi_sel___bit 30
+#define reg_iop_timer_grp_rw_half_period_offset 4
+
+/* Register rw_half_period_len, scope iop_timer_grp, type rw */
+#define reg_iop_timer_grp_rw_half_period_len_offset 8
+
+#define STRIDE_iop_timer_grp_rw_tmr_cfg 4
+/* Register rw_tmr_cfg, scope iop_timer_grp, type rw */
+#define reg_iop_timer_grp_rw_tmr_cfg___clk_src___lsb 0
+#define reg_iop_timer_grp_rw_tmr_cfg___clk_src___width 3
+#define reg_iop_timer_grp_rw_tmr_cfg___strb___lsb 3
+#define reg_iop_timer_grp_rw_tmr_cfg___strb___width 2
+#define reg_iop_timer_grp_rw_tmr_cfg___run_mode___lsb 5
+#define reg_iop_timer_grp_rw_tmr_cfg___run_mode___width 2
+#define reg_iop_timer_grp_rw_tmr_cfg___out_mode___lsb 7
+#define reg_iop_timer_grp_rw_tmr_cfg___out_mode___width 1
+#define reg_iop_timer_grp_rw_tmr_cfg___out_mode___bit 7
+#define reg_iop_timer_grp_rw_tmr_cfg___active_on_tmr___lsb 8
+#define reg_iop_timer_grp_rw_tmr_cfg___active_on_tmr___width 2
+#define reg_iop_timer_grp_rw_tmr_cfg___inv___lsb 10
+#define reg_iop_timer_grp_rw_tmr_cfg___inv___width 1
+#define reg_iop_timer_grp_rw_tmr_cfg___inv___bit 10
+#define reg_iop_timer_grp_rw_tmr_cfg___en_by_tmr___lsb 11
+#define reg_iop_timer_grp_rw_tmr_cfg___en_by_tmr___width 2
+#define reg_iop_timer_grp_rw_tmr_cfg___dis_by_tmr___lsb 13
+#define reg_iop_timer_grp_rw_tmr_cfg___dis_by_tmr___width 2
+#define reg_iop_timer_grp_rw_tmr_cfg___en_only_by_reg___lsb 15
+#define reg_iop_timer_grp_rw_tmr_cfg___en_only_by_reg___width 1
+#define reg_iop_timer_grp_rw_tmr_cfg___en_only_by_reg___bit 15
+#define reg_iop_timer_grp_rw_tmr_cfg___dis_only_by_reg___lsb 16
+#define reg_iop_timer_grp_rw_tmr_cfg___dis_only_by_reg___width 1
+#define reg_iop_timer_grp_rw_tmr_cfg___dis_only_by_reg___bit 16
+#define reg_iop_timer_grp_rw_tmr_cfg___rst_at_en_strb___lsb 17
+#define reg_iop_timer_grp_rw_tmr_cfg___rst_at_en_strb___width 1
+#define reg_iop_timer_grp_rw_tmr_cfg___rst_at_en_strb___bit 17
+#define reg_iop_timer_grp_rw_tmr_cfg_offset 12
+
+#define STRIDE_iop_timer_grp_rw_tmr_len 4
+/* Register rw_tmr_len, scope iop_timer_grp, type rw */
+#define reg_iop_timer_grp_rw_tmr_len___val___lsb 0
+#define reg_iop_timer_grp_rw_tmr_len___val___width 16
+#define reg_iop_timer_grp_rw_tmr_len_offset 44
+
+/* Register rw_cmd, scope iop_timer_grp, type rw */
+#define reg_iop_timer_grp_rw_cmd___rst___lsb 0
+#define reg_iop_timer_grp_rw_cmd___rst___width 4
+#define reg_iop_timer_grp_rw_cmd___en___lsb 4
+#define reg_iop_timer_grp_rw_cmd___en___width 4
+#define reg_iop_timer_grp_rw_cmd___dis___lsb 8
+#define reg_iop_timer_grp_rw_cmd___dis___width 4
+#define reg_iop_timer_grp_rw_cmd___strb___lsb 12
+#define reg_iop_timer_grp_rw_cmd___strb___width 4
+#define reg_iop_timer_grp_rw_cmd_offset 60
+
+/* Register r_clk_gen_cnt, scope iop_timer_grp, type r */
+#define reg_iop_timer_grp_r_clk_gen_cnt_offset 64
+
+#define STRIDE_iop_timer_grp_rs_tmr_cnt 8
+/* Register rs_tmr_cnt, scope iop_timer_grp, type rs */
+#define reg_iop_timer_grp_rs_tmr_cnt___val___lsb 0
+#define reg_iop_timer_grp_rs_tmr_cnt___val___width 16
+#define reg_iop_timer_grp_rs_tmr_cnt_offset 68
+
+#define STRIDE_iop_timer_grp_r_tmr_cnt 8
+/* Register r_tmr_cnt, scope iop_timer_grp, type r */
+#define reg_iop_timer_grp_r_tmr_cnt___val___lsb 0
+#define reg_iop_timer_grp_r_tmr_cnt___val___width 16
+#define reg_iop_timer_grp_r_tmr_cnt_offset 72
+
+/* Register rw_intr_mask, scope iop_timer_grp, type rw */
+#define reg_iop_timer_grp_rw_intr_mask___tmr0___lsb 0
+#define reg_iop_timer_grp_rw_intr_mask___tmr0___width 1
+#define reg_iop_timer_grp_rw_intr_mask___tmr0___bit 0
+#define reg_iop_timer_grp_rw_intr_mask___tmr1___lsb 1
+#define reg_iop_timer_grp_rw_intr_mask___tmr1___width 1
+#define reg_iop_timer_grp_rw_intr_mask___tmr1___bit 1
+#define reg_iop_timer_grp_rw_intr_mask___tmr2___lsb 2
+#define reg_iop_timer_grp_rw_intr_mask___tmr2___width 1
+#define reg_iop_timer_grp_rw_intr_mask___tmr2___bit 2
+#define reg_iop_timer_grp_rw_intr_mask___tmr3___lsb 3
+#define reg_iop_timer_grp_rw_intr_mask___tmr3___width 1
+#define reg_iop_timer_grp_rw_intr_mask___tmr3___bit 3
+#define reg_iop_timer_grp_rw_intr_mask_offset 100
+
+/* Register rw_ack_intr, scope iop_timer_grp, type rw */
+#define reg_iop_timer_grp_rw_ack_intr___tmr0___lsb 0
+#define reg_iop_timer_grp_rw_ack_intr___tmr0___width 1
+#define reg_iop_timer_grp_rw_ack_intr___tmr0___bit 0
+#define reg_iop_timer_grp_rw_ack_intr___tmr1___lsb 1
+#define reg_iop_timer_grp_rw_ack_intr___tmr1___width 1
+#define reg_iop_timer_grp_rw_ack_intr___tmr1___bit 1
+#define reg_iop_timer_grp_rw_ack_intr___tmr2___lsb 2
+#define reg_iop_timer_grp_rw_ack_intr___tmr2___width 1
+#define reg_iop_timer_grp_rw_ack_intr___tmr2___bit 2
+#define reg_iop_timer_grp_rw_ack_intr___tmr3___lsb 3
+#define reg_iop_timer_grp_rw_ack_intr___tmr3___width 1
+#define reg_iop_timer_grp_rw_ack_intr___tmr3___bit 3
+#define reg_iop_timer_grp_rw_ack_intr_offset 104
+
+/* Register r_intr, scope iop_timer_grp, type r */
+#define reg_iop_timer_grp_r_intr___tmr0___lsb 0
+#define reg_iop_timer_grp_r_intr___tmr0___width 1
+#define reg_iop_timer_grp_r_intr___tmr0___bit 0
+#define reg_iop_timer_grp_r_intr___tmr1___lsb 1
+#define reg_iop_timer_grp_r_intr___tmr1___width 1
+#define reg_iop_timer_grp_r_intr___tmr1___bit 1
+#define reg_iop_timer_grp_r_intr___tmr2___lsb 2
+#define reg_iop_timer_grp_r_intr___tmr2___width 1
+#define reg_iop_timer_grp_r_intr___tmr2___bit 2
+#define reg_iop_timer_grp_r_intr___tmr3___lsb 3
+#define reg_iop_timer_grp_r_intr___tmr3___width 1
+#define reg_iop_timer_grp_r_intr___tmr3___bit 3
+#define reg_iop_timer_grp_r_intr_offset 108
+
+/* Register r_masked_intr, scope iop_timer_grp, type r */
+#define reg_iop_timer_grp_r_masked_intr___tmr0___lsb 0
+#define reg_iop_timer_grp_r_masked_intr___tmr0___width 1
+#define reg_iop_timer_grp_r_masked_intr___tmr0___bit 0
+#define reg_iop_timer_grp_r_masked_intr___tmr1___lsb 1
+#define reg_iop_timer_grp_r_masked_intr___tmr1___width 1
+#define reg_iop_timer_grp_r_masked_intr___tmr1___bit 1
+#define reg_iop_timer_grp_r_masked_intr___tmr2___lsb 2
+#define reg_iop_timer_grp_r_masked_intr___tmr2___width 1
+#define reg_iop_timer_grp_r_masked_intr___tmr2___bit 2
+#define reg_iop_timer_grp_r_masked_intr___tmr3___lsb 3
+#define reg_iop_timer_grp_r_masked_intr___tmr3___width 1
+#define reg_iop_timer_grp_r_masked_intr___tmr3___bit 3
+#define reg_iop_timer_grp_r_masked_intr_offset 112
+
+
+/* Constants */
+#define regk_iop_timer_grp_clk200                 0x00000000
+#define regk_iop_timer_grp_clk_gen                0x00000002
+#define regk_iop_timer_grp_complete               0x00000002
+#define regk_iop_timer_grp_div_clk200             0x00000001
+#define regk_iop_timer_grp_div_clk_gen            0x00000003
+#define regk_iop_timer_grp_ext                    0x00000001
+#define regk_iop_timer_grp_hi                     0x00000000
+#define regk_iop_timer_grp_long_period            0x00000001
+#define regk_iop_timer_grp_neg                    0x00000002
+#define regk_iop_timer_grp_no                     0x00000000
+#define regk_iop_timer_grp_once                   0x00000003
+#define regk_iop_timer_grp_pause                  0x00000001
+#define regk_iop_timer_grp_pos                    0x00000001
+#define regk_iop_timer_grp_pos_neg                0x00000003
+#define regk_iop_timer_grp_pulse                  0x00000000
+#define regk_iop_timer_grp_r_tmr_cnt_size         0x00000004
+#define regk_iop_timer_grp_rs_tmr_cnt_size        0x00000004
+#define regk_iop_timer_grp_rw_cfg_default         0x00000002
+#define regk_iop_timer_grp_rw_intr_mask_default   0x00000000
+#define regk_iop_timer_grp_rw_tmr_cfg_default0    0x00018000
+#define regk_iop_timer_grp_rw_tmr_cfg_default1    0x0001a900
+#define regk_iop_timer_grp_rw_tmr_cfg_default2    0x0001d200
+#define regk_iop_timer_grp_rw_tmr_cfg_default3    0x0001fb00
+#define regk_iop_timer_grp_rw_tmr_cfg_size        0x00000004
+#define regk_iop_timer_grp_rw_tmr_len_default     0x00000000
+#define regk_iop_timer_grp_rw_tmr_len_size        0x00000004
+#define regk_iop_timer_grp_short_period           0x00000000
+#define regk_iop_timer_grp_stop                   0x00000000
+#define regk_iop_timer_grp_tmr                    0x00000004
+#define regk_iop_timer_grp_toggle                 0x00000001
+#define regk_iop_timer_grp_yes                    0x00000001
+#endif /* __iop_timer_grp_defs_asm_h */
diff --git a/include/asm-cris/arch-v32/hwregs/iop/asm/iop_trigger_grp_defs_asm.h b/include/asm-cris/arch-v32/hwregs/iop/asm/iop_trigger_grp_defs_asm.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/iop/asm/iop_trigger_grp_defs_asm.h
@@ -0,0 +1,157 @@
+#ifndef __iop_trigger_grp_defs_asm_h
+#define __iop_trigger_grp_defs_asm_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/io_proc/rtl/iop_trigger_grp.r
+ *     id:           iop_trigger_grp.r,v 0.20 2005/02/16 09:13:20 niklaspa Exp
+ *     last modfied: Mon Apr 11 16:08:46 2005
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c -asm --outfile asm/iop_trigger_grp_defs_asm.h ../../inst/io_proc/rtl/iop_trigger_grp.r
+ *      id: $Id: iop_trigger_grp_defs_asm.h,v 1.5 2005/04/24 18:31:07 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+
+#ifndef REG_FIELD
+#define REG_FIELD( scope, reg, field, value ) \
+  REG_FIELD_X_( value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_FIELD_X_( value, shift ) ((value) << shift)
+#endif
+
+#ifndef REG_STATE
+#define REG_STATE( scope, reg, field, symbolic_value ) \
+  REG_STATE_X_( regk_##scope##_##symbolic_value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_STATE_X_( k, shift ) (k << shift)
+#endif
+
+#ifndef REG_MASK
+#define REG_MASK( scope, reg, field ) \
+  REG_MASK_X_( reg_##scope##_##reg##___##field##___width, reg_##scope##_##reg##___##field##___lsb )
+#define REG_MASK_X_( width, lsb ) (((1 << width)-1) << lsb)
+#endif
+
+#ifndef REG_LSB
+#define REG_LSB( scope, reg, field ) reg_##scope##_##reg##___##field##___lsb
+#endif
+
+#ifndef REG_BIT
+#define REG_BIT( scope, reg, field ) reg_##scope##_##reg##___##field##___bit
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) REG_ADDR_X_(inst, reg_##scope##_##reg##_offset)
+#define REG_ADDR_X_( inst, offs ) ((inst) + offs)
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+         REG_ADDR_VECT_X_(inst, reg_##scope##_##reg##_offset, index, \
+			 STRIDE_##scope##_##reg )
+#define REG_ADDR_VECT_X_( inst, offs, index, stride ) \
+                          ((inst) + offs + (index) * stride)
+#endif
+
+#define STRIDE_iop_trigger_grp_rw_cfg 4
+/* Register rw_cfg, scope iop_trigger_grp, type rw */
+#define reg_iop_trigger_grp_rw_cfg___action___lsb 0
+#define reg_iop_trigger_grp_rw_cfg___action___width 2
+#define reg_iop_trigger_grp_rw_cfg___once___lsb 2
+#define reg_iop_trigger_grp_rw_cfg___once___width 1
+#define reg_iop_trigger_grp_rw_cfg___once___bit 2
+#define reg_iop_trigger_grp_rw_cfg___trig___lsb 3
+#define reg_iop_trigger_grp_rw_cfg___trig___width 3
+#define reg_iop_trigger_grp_rw_cfg___en_only_by_reg___lsb 6
+#define reg_iop_trigger_grp_rw_cfg___en_only_by_reg___width 1
+#define reg_iop_trigger_grp_rw_cfg___en_only_by_reg___bit 6
+#define reg_iop_trigger_grp_rw_cfg___dis_only_by_reg___lsb 7
+#define reg_iop_trigger_grp_rw_cfg___dis_only_by_reg___width 1
+#define reg_iop_trigger_grp_rw_cfg___dis_only_by_reg___bit 7
+#define reg_iop_trigger_grp_rw_cfg_offset 0
+
+/* Register rw_cmd, scope iop_trigger_grp, type rw */
+#define reg_iop_trigger_grp_rw_cmd___dis___lsb 0
+#define reg_iop_trigger_grp_rw_cmd___dis___width 4
+#define reg_iop_trigger_grp_rw_cmd___en___lsb 4
+#define reg_iop_trigger_grp_rw_cmd___en___width 4
+#define reg_iop_trigger_grp_rw_cmd_offset 16
+
+/* Register rw_intr_mask, scope iop_trigger_grp, type rw */
+#define reg_iop_trigger_grp_rw_intr_mask___trig0___lsb 0
+#define reg_iop_trigger_grp_rw_intr_mask___trig0___width 1
+#define reg_iop_trigger_grp_rw_intr_mask___trig0___bit 0
+#define reg_iop_trigger_grp_rw_intr_mask___trig1___lsb 1
+#define reg_iop_trigger_grp_rw_intr_mask___trig1___width 1
+#define reg_iop_trigger_grp_rw_intr_mask___trig1___bit 1
+#define reg_iop_trigger_grp_rw_intr_mask___trig2___lsb 2
+#define reg_iop_trigger_grp_rw_intr_mask___trig2___width 1
+#define reg_iop_trigger_grp_rw_intr_mask___trig2___bit 2
+#define reg_iop_trigger_grp_rw_intr_mask___trig3___lsb 3
+#define reg_iop_trigger_grp_rw_intr_mask___trig3___width 1
+#define reg_iop_trigger_grp_rw_intr_mask___trig3___bit 3
+#define reg_iop_trigger_grp_rw_intr_mask_offset 20
+
+/* Register rw_ack_intr, scope iop_trigger_grp, type rw */
+#define reg_iop_trigger_grp_rw_ack_intr___trig0___lsb 0
+#define reg_iop_trigger_grp_rw_ack_intr___trig0___width 1
+#define reg_iop_trigger_grp_rw_ack_intr___trig0___bit 0
+#define reg_iop_trigger_grp_rw_ack_intr___trig1___lsb 1
+#define reg_iop_trigger_grp_rw_ack_intr___trig1___width 1
+#define reg_iop_trigger_grp_rw_ack_intr___trig1___bit 1
+#define reg_iop_trigger_grp_rw_ack_intr___trig2___lsb 2
+#define reg_iop_trigger_grp_rw_ack_intr___trig2___width 1
+#define reg_iop_trigger_grp_rw_ack_intr___trig2___bit 2
+#define reg_iop_trigger_grp_rw_ack_intr___trig3___lsb 3
+#define reg_iop_trigger_grp_rw_ack_intr___trig3___width 1
+#define reg_iop_trigger_grp_rw_ack_intr___trig3___bit 3
+#define reg_iop_trigger_grp_rw_ack_intr_offset 24
+
+/* Register r_intr, scope iop_trigger_grp, type r */
+#define reg_iop_trigger_grp_r_intr___trig0___lsb 0
+#define reg_iop_trigger_grp_r_intr___trig0___width 1
+#define reg_iop_trigger_grp_r_intr___trig0___bit 0
+#define reg_iop_trigger_grp_r_intr___trig1___lsb 1
+#define reg_iop_trigger_grp_r_intr___trig1___width 1
+#define reg_iop_trigger_grp_r_intr___trig1___bit 1
+#define reg_iop_trigger_grp_r_intr___trig2___lsb 2
+#define reg_iop_trigger_grp_r_intr___trig2___width 1
+#define reg_iop_trigger_grp_r_intr___trig2___bit 2
+#define reg_iop_trigger_grp_r_intr___trig3___lsb 3
+#define reg_iop_trigger_grp_r_intr___trig3___width 1
+#define reg_iop_trigger_grp_r_intr___trig3___bit 3
+#define reg_iop_trigger_grp_r_intr_offset 28
+
+/* Register r_masked_intr, scope iop_trigger_grp, type r */
+#define reg_iop_trigger_grp_r_masked_intr___trig0___lsb 0
+#define reg_iop_trigger_grp_r_masked_intr___trig0___width 1
+#define reg_iop_trigger_grp_r_masked_intr___trig0___bit 0
+#define reg_iop_trigger_grp_r_masked_intr___trig1___lsb 1
+#define reg_iop_trigger_grp_r_masked_intr___trig1___width 1
+#define reg_iop_trigger_grp_r_masked_intr___trig1___bit 1
+#define reg_iop_trigger_grp_r_masked_intr___trig2___lsb 2
+#define reg_iop_trigger_grp_r_masked_intr___trig2___width 1
+#define reg_iop_trigger_grp_r_masked_intr___trig2___bit 2
+#define reg_iop_trigger_grp_r_masked_intr___trig3___lsb 3
+#define reg_iop_trigger_grp_r_masked_intr___trig3___width 1
+#define reg_iop_trigger_grp_r_masked_intr___trig3___bit 3
+#define reg_iop_trigger_grp_r_masked_intr_offset 32
+
+
+/* Constants */
+#define regk_iop_trigger_grp_fall                 0x00000002
+#define regk_iop_trigger_grp_fall_lo              0x00000006
+#define regk_iop_trigger_grp_no                   0x00000000
+#define regk_iop_trigger_grp_off                  0x00000000
+#define regk_iop_trigger_grp_pulse                0x00000000
+#define regk_iop_trigger_grp_rise                 0x00000001
+#define regk_iop_trigger_grp_rise_fall            0x00000003
+#define regk_iop_trigger_grp_rise_fall_hi         0x00000007
+#define regk_iop_trigger_grp_rise_fall_lo         0x00000004
+#define regk_iop_trigger_grp_rise_hi              0x00000005
+#define regk_iop_trigger_grp_rw_cfg_default       0x000000c0
+#define regk_iop_trigger_grp_rw_cfg_size          0x00000004
+#define regk_iop_trigger_grp_rw_intr_mask_default  0x00000000
+#define regk_iop_trigger_grp_toggle               0x00000003
+#define regk_iop_trigger_grp_yes                  0x00000001
+#endif /* __iop_trigger_grp_defs_asm_h */
diff --git a/include/asm-cris/arch-v32/hwregs/iop/asm/iop_version_defs_asm.h b/include/asm-cris/arch-v32/hwregs/iop/asm/iop_version_defs_asm.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/iop/asm/iop_version_defs_asm.h
@@ -0,0 +1,64 @@
+#ifndef __iop_version_defs_asm_h
+#define __iop_version_defs_asm_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/io_proc/rtl/guinness/iop_version.r
+ *     id:           iop_version.r,v 1.3 2004/04/22 12:37:54 jonaso Exp
+ *     last modfied: Mon Apr 11 16:08:44 2005
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c -asm --outfile asm/iop_version_defs_asm.h ../../inst/io_proc/rtl/guinness/iop_version.r
+ *      id: $Id: iop_version_defs_asm.h,v 1.5 2005/04/24 18:31:07 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+
+#ifndef REG_FIELD
+#define REG_FIELD( scope, reg, field, value ) \
+  REG_FIELD_X_( value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_FIELD_X_( value, shift ) ((value) << shift)
+#endif
+
+#ifndef REG_STATE
+#define REG_STATE( scope, reg, field, symbolic_value ) \
+  REG_STATE_X_( regk_##scope##_##symbolic_value, reg_##scope##_##reg##___##field##___lsb )
+#define REG_STATE_X_( k, shift ) (k << shift)
+#endif
+
+#ifndef REG_MASK
+#define REG_MASK( scope, reg, field ) \
+  REG_MASK_X_( reg_##scope##_##reg##___##field##___width, reg_##scope##_##reg##___##field##___lsb )
+#define REG_MASK_X_( width, lsb ) (((1 << width)-1) << lsb)
+#endif
+
+#ifndef REG_LSB
+#define REG_LSB( scope, reg, field ) reg_##scope##_##reg##___##field##___lsb
+#endif
+
+#ifndef REG_BIT
+#define REG_BIT( scope, reg, field ) reg_##scope##_##reg##___##field##___bit
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) REG_ADDR_X_(inst, reg_##scope##_##reg##_offset)
+#define REG_ADDR_X_( inst, offs ) ((inst) + offs)
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+         REG_ADDR_VECT_X_(inst, reg_##scope##_##reg##_offset, index, \
+			 STRIDE_##scope##_##reg )
+#define REG_ADDR_VECT_X_( inst, offs, index, stride ) \
+                          ((inst) + offs + (index) * stride)
+#endif
+
+/* Register r_version, scope iop_version, type r */
+#define reg_iop_version_r_version___nr___lsb 0
+#define reg_iop_version_r_version___nr___width 8
+#define reg_iop_version_r_version_offset 0
+
+
+/* Constants */
+#define regk_iop_version_v1_0                     0x00000001
+#endif /* __iop_version_defs_asm_h */
diff --git a/include/asm-cris/arch-v32/hwregs/iop/iop_crc_par_defs.h b/include/asm-cris/arch-v32/hwregs/iop/iop_crc_par_defs.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/iop/iop_crc_par_defs.h
@@ -0,0 +1,232 @@
+#ifndef __iop_crc_par_defs_h
+#define __iop_crc_par_defs_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/io_proc/rtl/iop_crc_par.r
+ *     id:           <not found>
+ *     last modfied: Mon Apr 11 16:08:45 2005
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c --outfile iop_crc_par_defs.h ../../inst/io_proc/rtl/iop_crc_par.r
+ *      id: $Id: iop_crc_par_defs.h,v 1.5 2005/04/24 18:31:05 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+/* Main access macros */
+#ifndef REG_RD
+#define REG_RD( scope, inst, reg ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR
+#define REG_WR( scope, inst, reg, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_VECT
+#define REG_RD_VECT( scope, inst, reg, index ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_VECT
+#define REG_WR_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT
+#define REG_RD_INT( scope, inst, reg ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT
+#define REG_WR_INT( scope, inst, reg, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT_VECT
+#define REG_RD_INT_VECT( scope, inst, reg, index ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT_VECT
+#define REG_WR_INT_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_TYPE_CONV
+#define REG_TYPE_CONV( type, orgtype, val ) \
+  ( { union { orgtype o; type n; } r; r.o = val; r.n; } )
+#endif
+
+#ifndef reg_page_size
+#define reg_page_size 8192
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg + \
+    (index) * STRIDE_##scope##_##reg )
+#endif
+
+/* C-code for register scope iop_crc_par */
+
+/* Register rw_cfg, scope iop_crc_par, type rw */
+typedef struct {
+  unsigned int mode    : 1;
+  unsigned int crc_out : 1;
+  unsigned int rev_out : 1;
+  unsigned int inv_out : 1;
+  unsigned int trig    : 2;
+  unsigned int poly    : 3;
+  unsigned int dummy1  : 23;
+} reg_iop_crc_par_rw_cfg;
+#define REG_RD_ADDR_iop_crc_par_rw_cfg 0
+#define REG_WR_ADDR_iop_crc_par_rw_cfg 0
+
+/* Register rw_init_crc, scope iop_crc_par, type rw */
+typedef unsigned int reg_iop_crc_par_rw_init_crc;
+#define REG_RD_ADDR_iop_crc_par_rw_init_crc 4
+#define REG_WR_ADDR_iop_crc_par_rw_init_crc 4
+
+/* Register rw_correct_crc, scope iop_crc_par, type rw */
+typedef unsigned int reg_iop_crc_par_rw_correct_crc;
+#define REG_RD_ADDR_iop_crc_par_rw_correct_crc 8
+#define REG_WR_ADDR_iop_crc_par_rw_correct_crc 8
+
+/* Register rw_ctrl, scope iop_crc_par, type rw */
+typedef struct {
+  unsigned int en : 1;
+  unsigned int dummy1 : 31;
+} reg_iop_crc_par_rw_ctrl;
+#define REG_RD_ADDR_iop_crc_par_rw_ctrl 12
+#define REG_WR_ADDR_iop_crc_par_rw_ctrl 12
+
+/* Register rw_set_last, scope iop_crc_par, type rw */
+typedef struct {
+  unsigned int tr_dif : 1;
+  unsigned int dummy1 : 31;
+} reg_iop_crc_par_rw_set_last;
+#define REG_RD_ADDR_iop_crc_par_rw_set_last 16
+#define REG_WR_ADDR_iop_crc_par_rw_set_last 16
+
+/* Register rw_wr1byte, scope iop_crc_par, type rw */
+typedef struct {
+  unsigned int data : 8;
+  unsigned int dummy1 : 24;
+} reg_iop_crc_par_rw_wr1byte;
+#define REG_RD_ADDR_iop_crc_par_rw_wr1byte 20
+#define REG_WR_ADDR_iop_crc_par_rw_wr1byte 20
+
+/* Register rw_wr2byte, scope iop_crc_par, type rw */
+typedef struct {
+  unsigned int data : 16;
+  unsigned int dummy1 : 16;
+} reg_iop_crc_par_rw_wr2byte;
+#define REG_RD_ADDR_iop_crc_par_rw_wr2byte 24
+#define REG_WR_ADDR_iop_crc_par_rw_wr2byte 24
+
+/* Register rw_wr3byte, scope iop_crc_par, type rw */
+typedef struct {
+  unsigned int data : 24;
+  unsigned int dummy1 : 8;
+} reg_iop_crc_par_rw_wr3byte;
+#define REG_RD_ADDR_iop_crc_par_rw_wr3byte 28
+#define REG_WR_ADDR_iop_crc_par_rw_wr3byte 28
+
+/* Register rw_wr4byte, scope iop_crc_par, type rw */
+typedef struct {
+  unsigned int data : 32;
+} reg_iop_crc_par_rw_wr4byte;
+#define REG_RD_ADDR_iop_crc_par_rw_wr4byte 32
+#define REG_WR_ADDR_iop_crc_par_rw_wr4byte 32
+
+/* Register rw_wr1byte_last, scope iop_crc_par, type rw */
+typedef struct {
+  unsigned int data : 8;
+  unsigned int dummy1 : 24;
+} reg_iop_crc_par_rw_wr1byte_last;
+#define REG_RD_ADDR_iop_crc_par_rw_wr1byte_last 36
+#define REG_WR_ADDR_iop_crc_par_rw_wr1byte_last 36
+
+/* Register rw_wr2byte_last, scope iop_crc_par, type rw */
+typedef struct {
+  unsigned int data : 16;
+  unsigned int dummy1 : 16;
+} reg_iop_crc_par_rw_wr2byte_last;
+#define REG_RD_ADDR_iop_crc_par_rw_wr2byte_last 40
+#define REG_WR_ADDR_iop_crc_par_rw_wr2byte_last 40
+
+/* Register rw_wr3byte_last, scope iop_crc_par, type rw */
+typedef struct {
+  unsigned int data : 24;
+  unsigned int dummy1 : 8;
+} reg_iop_crc_par_rw_wr3byte_last;
+#define REG_RD_ADDR_iop_crc_par_rw_wr3byte_last 44
+#define REG_WR_ADDR_iop_crc_par_rw_wr3byte_last 44
+
+/* Register rw_wr4byte_last, scope iop_crc_par, type rw */
+typedef struct {
+  unsigned int data : 32;
+} reg_iop_crc_par_rw_wr4byte_last;
+#define REG_RD_ADDR_iop_crc_par_rw_wr4byte_last 48
+#define REG_WR_ADDR_iop_crc_par_rw_wr4byte_last 48
+
+/* Register r_stat, scope iop_crc_par, type r */
+typedef struct {
+  unsigned int err  : 1;
+  unsigned int busy : 1;
+  unsigned int dummy1 : 30;
+} reg_iop_crc_par_r_stat;
+#define REG_RD_ADDR_iop_crc_par_r_stat 52
+
+/* Register r_sh_reg, scope iop_crc_par, type r */
+typedef unsigned int reg_iop_crc_par_r_sh_reg;
+#define REG_RD_ADDR_iop_crc_par_r_sh_reg 56
+
+/* Register r_crc, scope iop_crc_par, type r */
+typedef unsigned int reg_iop_crc_par_r_crc;
+#define REG_RD_ADDR_iop_crc_par_r_crc 60
+
+/* Register rw_strb_rec_dif_in, scope iop_crc_par, type rw */
+typedef struct {
+  unsigned int last : 2;
+  unsigned int dummy1 : 30;
+} reg_iop_crc_par_rw_strb_rec_dif_in;
+#define REG_RD_ADDR_iop_crc_par_rw_strb_rec_dif_in 64
+#define REG_WR_ADDR_iop_crc_par_rw_strb_rec_dif_in 64
+
+
+/* Constants */
+enum {
+  regk_iop_crc_par_calc                    = 0x00000001,
+  regk_iop_crc_par_ccitt                   = 0x00000002,
+  regk_iop_crc_par_check                   = 0x00000000,
+  regk_iop_crc_par_crc16                   = 0x00000001,
+  regk_iop_crc_par_crc32                   = 0x00000000,
+  regk_iop_crc_par_crc5                    = 0x00000003,
+  regk_iop_crc_par_crc5_11                 = 0x00000004,
+  regk_iop_crc_par_dif_in                  = 0x00000002,
+  regk_iop_crc_par_hi                      = 0x00000000,
+  regk_iop_crc_par_neg                     = 0x00000002,
+  regk_iop_crc_par_no                      = 0x00000000,
+  regk_iop_crc_par_pos                     = 0x00000001,
+  regk_iop_crc_par_pos_neg                 = 0x00000003,
+  regk_iop_crc_par_rw_cfg_default          = 0x00000000,
+  regk_iop_crc_par_rw_ctrl_default         = 0x00000000,
+  regk_iop_crc_par_yes                     = 0x00000001
+};
+#endif /* __iop_crc_par_defs_h */
diff --git a/include/asm-cris/arch-v32/hwregs/iop/iop_dmc_in_defs.h b/include/asm-cris/arch-v32/hwregs/iop/iop_dmc_in_defs.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/iop/iop_dmc_in_defs.h
@@ -0,0 +1,325 @@
+#ifndef __iop_dmc_in_defs_h
+#define __iop_dmc_in_defs_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/io_proc/rtl/iop_dmc_in.r
+ *     id:           iop_dmc_in.r,v 1.26 2005/02/16 09:14:17 niklaspa Exp
+ *     last modfied: Mon Apr 11 16:08:45 2005
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c --outfile iop_dmc_in_defs.h ../../inst/io_proc/rtl/iop_dmc_in.r
+ *      id: $Id: iop_dmc_in_defs.h,v 1.5 2005/04/24 18:31:05 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+/* Main access macros */
+#ifndef REG_RD
+#define REG_RD( scope, inst, reg ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR
+#define REG_WR( scope, inst, reg, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_VECT
+#define REG_RD_VECT( scope, inst, reg, index ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_VECT
+#define REG_WR_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT
+#define REG_RD_INT( scope, inst, reg ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT
+#define REG_WR_INT( scope, inst, reg, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT_VECT
+#define REG_RD_INT_VECT( scope, inst, reg, index ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT_VECT
+#define REG_WR_INT_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_TYPE_CONV
+#define REG_TYPE_CONV( type, orgtype, val ) \
+  ( { union { orgtype o; type n; } r; r.o = val; r.n; } )
+#endif
+
+#ifndef reg_page_size
+#define reg_page_size 8192
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg + \
+    (index) * STRIDE_##scope##_##reg )
+#endif
+
+/* C-code for register scope iop_dmc_in */
+
+/* Register rw_cfg, scope iop_dmc_in, type rw */
+typedef struct {
+  unsigned int sth_intr     : 3;
+  unsigned int last_dis_dif : 1;
+  unsigned int dummy1       : 28;
+} reg_iop_dmc_in_rw_cfg;
+#define REG_RD_ADDR_iop_dmc_in_rw_cfg 0
+#define REG_WR_ADDR_iop_dmc_in_rw_cfg 0
+
+/* Register rw_ctrl, scope iop_dmc_in, type rw */
+typedef struct {
+  unsigned int dif_en     : 1;
+  unsigned int dif_dis    : 1;
+  unsigned int stream_clr : 1;
+  unsigned int dummy1     : 29;
+} reg_iop_dmc_in_rw_ctrl;
+#define REG_RD_ADDR_iop_dmc_in_rw_ctrl 4
+#define REG_WR_ADDR_iop_dmc_in_rw_ctrl 4
+
+/* Register r_stat, scope iop_dmc_in, type r */
+typedef struct {
+  unsigned int dif_en : 1;
+  unsigned int dummy1 : 31;
+} reg_iop_dmc_in_r_stat;
+#define REG_RD_ADDR_iop_dmc_in_r_stat 8
+
+/* Register rw_stream_cmd, scope iop_dmc_in, type rw */
+typedef struct {
+  unsigned int cmd : 10;
+  unsigned int dummy1 : 6;
+  unsigned int n   : 8;
+  unsigned int dummy2 : 8;
+} reg_iop_dmc_in_rw_stream_cmd;
+#define REG_RD_ADDR_iop_dmc_in_rw_stream_cmd 12
+#define REG_WR_ADDR_iop_dmc_in_rw_stream_cmd 12
+
+/* Register rw_stream_wr_data, scope iop_dmc_in, type rw */
+typedef unsigned int reg_iop_dmc_in_rw_stream_wr_data;
+#define REG_RD_ADDR_iop_dmc_in_rw_stream_wr_data 16
+#define REG_WR_ADDR_iop_dmc_in_rw_stream_wr_data 16
+
+/* Register rw_stream_wr_data_last, scope iop_dmc_in, type rw */
+typedef unsigned int reg_iop_dmc_in_rw_stream_wr_data_last;
+#define REG_RD_ADDR_iop_dmc_in_rw_stream_wr_data_last 20
+#define REG_WR_ADDR_iop_dmc_in_rw_stream_wr_data_last 20
+
+/* Register rw_stream_ctrl, scope iop_dmc_in, type rw */
+typedef struct {
+  unsigned int eop     : 1;
+  unsigned int wait    : 1;
+  unsigned int keep_md : 1;
+  unsigned int size    : 3;
+  unsigned int dummy1  : 26;
+} reg_iop_dmc_in_rw_stream_ctrl;
+#define REG_RD_ADDR_iop_dmc_in_rw_stream_ctrl 24
+#define REG_WR_ADDR_iop_dmc_in_rw_stream_ctrl 24
+
+/* Register r_stream_stat, scope iop_dmc_in, type r */
+typedef struct {
+  unsigned int sth            : 7;
+  unsigned int dummy1         : 9;
+  unsigned int full           : 1;
+  unsigned int last_pkt       : 1;
+  unsigned int data_md_valid  : 1;
+  unsigned int ctxt_md_valid  : 1;
+  unsigned int group_md_valid : 1;
+  unsigned int stream_busy    : 1;
+  unsigned int cmd_rdy        : 1;
+  unsigned int dummy2         : 9;
+} reg_iop_dmc_in_r_stream_stat;
+#define REG_RD_ADDR_iop_dmc_in_r_stream_stat 28
+
+/* Register r_data_descr, scope iop_dmc_in, type r */
+typedef struct {
+  unsigned int ctrl : 8;
+  unsigned int stat : 8;
+  unsigned int md   : 16;
+} reg_iop_dmc_in_r_data_descr;
+#define REG_RD_ADDR_iop_dmc_in_r_data_descr 32
+
+/* Register r_ctxt_descr, scope iop_dmc_in, type r */
+typedef struct {
+  unsigned int ctrl : 8;
+  unsigned int stat : 8;
+  unsigned int md0  : 16;
+} reg_iop_dmc_in_r_ctxt_descr;
+#define REG_RD_ADDR_iop_dmc_in_r_ctxt_descr 36
+
+/* Register r_ctxt_descr_md1, scope iop_dmc_in, type r */
+typedef unsigned int reg_iop_dmc_in_r_ctxt_descr_md1;
+#define REG_RD_ADDR_iop_dmc_in_r_ctxt_descr_md1 40
+
+/* Register r_ctxt_descr_md2, scope iop_dmc_in, type r */
+typedef unsigned int reg_iop_dmc_in_r_ctxt_descr_md2;
+#define REG_RD_ADDR_iop_dmc_in_r_ctxt_descr_md2 44
+
+/* Register r_group_descr, scope iop_dmc_in, type r */
+typedef struct {
+  unsigned int ctrl : 8;
+  unsigned int stat : 8;
+  unsigned int md   : 16;
+} reg_iop_dmc_in_r_group_descr;
+#define REG_RD_ADDR_iop_dmc_in_r_group_descr 56
+
+/* Register rw_data_descr, scope iop_dmc_in, type rw */
+typedef struct {
+  unsigned int dummy1 : 16;
+  unsigned int md : 16;
+} reg_iop_dmc_in_rw_data_descr;
+#define REG_RD_ADDR_iop_dmc_in_rw_data_descr 60
+#define REG_WR_ADDR_iop_dmc_in_rw_data_descr 60
+
+/* Register rw_ctxt_descr, scope iop_dmc_in, type rw */
+typedef struct {
+  unsigned int dummy1 : 16;
+  unsigned int md0 : 16;
+} reg_iop_dmc_in_rw_ctxt_descr;
+#define REG_RD_ADDR_iop_dmc_in_rw_ctxt_descr 64
+#define REG_WR_ADDR_iop_dmc_in_rw_ctxt_descr 64
+
+/* Register rw_ctxt_descr_md1, scope iop_dmc_in, type rw */
+typedef unsigned int reg_iop_dmc_in_rw_ctxt_descr_md1;
+#define REG_RD_ADDR_iop_dmc_in_rw_ctxt_descr_md1 68
+#define REG_WR_ADDR_iop_dmc_in_rw_ctxt_descr_md1 68
+
+/* Register rw_ctxt_descr_md2, scope iop_dmc_in, type rw */
+typedef unsigned int reg_iop_dmc_in_rw_ctxt_descr_md2;
+#define REG_RD_ADDR_iop_dmc_in_rw_ctxt_descr_md2 72
+#define REG_WR_ADDR_iop_dmc_in_rw_ctxt_descr_md2 72
+
+/* Register rw_group_descr, scope iop_dmc_in, type rw */
+typedef struct {
+  unsigned int dummy1 : 16;
+  unsigned int md : 16;
+} reg_iop_dmc_in_rw_group_descr;
+#define REG_RD_ADDR_iop_dmc_in_rw_group_descr 84
+#define REG_WR_ADDR_iop_dmc_in_rw_group_descr 84
+
+/* Register rw_intr_mask, scope iop_dmc_in, type rw */
+typedef struct {
+  unsigned int data_md  : 1;
+  unsigned int ctxt_md  : 1;
+  unsigned int group_md : 1;
+  unsigned int cmd_rdy  : 1;
+  unsigned int sth      : 1;
+  unsigned int full     : 1;
+  unsigned int dummy1   : 26;
+} reg_iop_dmc_in_rw_intr_mask;
+#define REG_RD_ADDR_iop_dmc_in_rw_intr_mask 88
+#define REG_WR_ADDR_iop_dmc_in_rw_intr_mask 88
+
+/* Register rw_ack_intr, scope iop_dmc_in, type rw */
+typedef struct {
+  unsigned int data_md  : 1;
+  unsigned int ctxt_md  : 1;
+  unsigned int group_md : 1;
+  unsigned int cmd_rdy  : 1;
+  unsigned int sth      : 1;
+  unsigned int full     : 1;
+  unsigned int dummy1   : 26;
+} reg_iop_dmc_in_rw_ack_intr;
+#define REG_RD_ADDR_iop_dmc_in_rw_ack_intr 92
+#define REG_WR_ADDR_iop_dmc_in_rw_ack_intr 92
+
+/* Register r_intr, scope iop_dmc_in, type r */
+typedef struct {
+  unsigned int data_md  : 1;
+  unsigned int ctxt_md  : 1;
+  unsigned int group_md : 1;
+  unsigned int cmd_rdy  : 1;
+  unsigned int sth      : 1;
+  unsigned int full     : 1;
+  unsigned int dummy1   : 26;
+} reg_iop_dmc_in_r_intr;
+#define REG_RD_ADDR_iop_dmc_in_r_intr 96
+
+/* Register r_masked_intr, scope iop_dmc_in, type r */
+typedef struct {
+  unsigned int data_md  : 1;
+  unsigned int ctxt_md  : 1;
+  unsigned int group_md : 1;
+  unsigned int cmd_rdy  : 1;
+  unsigned int sth      : 1;
+  unsigned int full     : 1;
+  unsigned int dummy1   : 26;
+} reg_iop_dmc_in_r_masked_intr;
+#define REG_RD_ADDR_iop_dmc_in_r_masked_intr 100
+
+
+/* Constants */
+enum {
+  regk_iop_dmc_in_ack_pkt                  = 0x00000100,
+  regk_iop_dmc_in_array                    = 0x00000008,
+  regk_iop_dmc_in_burst                    = 0x00000020,
+  regk_iop_dmc_in_copy_next                = 0x00000010,
+  regk_iop_dmc_in_copy_up                  = 0x00000020,
+  regk_iop_dmc_in_dis_c                    = 0x00000010,
+  regk_iop_dmc_in_dis_g                    = 0x00000020,
+  regk_iop_dmc_in_lim1                     = 0x00000000,
+  regk_iop_dmc_in_lim16                    = 0x00000004,
+  regk_iop_dmc_in_lim2                     = 0x00000001,
+  regk_iop_dmc_in_lim32                    = 0x00000005,
+  regk_iop_dmc_in_lim4                     = 0x00000002,
+  regk_iop_dmc_in_lim64                    = 0x00000006,
+  regk_iop_dmc_in_lim8                     = 0x00000003,
+  regk_iop_dmc_in_load_c                   = 0x00000200,
+  regk_iop_dmc_in_load_c_n                 = 0x00000280,
+  regk_iop_dmc_in_load_c_next              = 0x00000240,
+  regk_iop_dmc_in_load_d                   = 0x00000140,
+  regk_iop_dmc_in_load_g                   = 0x00000300,
+  regk_iop_dmc_in_load_g_down              = 0x000003c0,
+  regk_iop_dmc_in_load_g_next              = 0x00000340,
+  regk_iop_dmc_in_load_g_up                = 0x00000380,
+  regk_iop_dmc_in_next_en                  = 0x00000010,
+  regk_iop_dmc_in_next_pkt                 = 0x00000010,
+  regk_iop_dmc_in_no                       = 0x00000000,
+  regk_iop_dmc_in_restore                  = 0x00000020,
+  regk_iop_dmc_in_rw_cfg_default           = 0x00000000,
+  regk_iop_dmc_in_rw_ctxt_descr_default    = 0x00000000,
+  regk_iop_dmc_in_rw_ctxt_descr_md1_default = 0x00000000,
+  regk_iop_dmc_in_rw_ctxt_descr_md2_default = 0x00000000,
+  regk_iop_dmc_in_rw_data_descr_default    = 0x00000000,
+  regk_iop_dmc_in_rw_group_descr_default   = 0x00000000,
+  regk_iop_dmc_in_rw_intr_mask_default     = 0x00000000,
+  regk_iop_dmc_in_rw_stream_ctrl_default   = 0x00000000,
+  regk_iop_dmc_in_save_down                = 0x00000020,
+  regk_iop_dmc_in_save_up                  = 0x00000020,
+  regk_iop_dmc_in_set_reg                  = 0x00000050,
+  regk_iop_dmc_in_set_w_size1              = 0x00000190,
+  regk_iop_dmc_in_set_w_size2              = 0x000001a0,
+  regk_iop_dmc_in_set_w_size4              = 0x000001c0,
+  regk_iop_dmc_in_store_c                  = 0x00000002,
+  regk_iop_dmc_in_store_descr              = 0x00000000,
+  regk_iop_dmc_in_store_g                  = 0x00000004,
+  regk_iop_dmc_in_store_md                 = 0x00000001,
+  regk_iop_dmc_in_update_down              = 0x00000020,
+  regk_iop_dmc_in_yes                      = 0x00000001
+};
+#endif /* __iop_dmc_in_defs_h */
diff --git a/include/asm-cris/arch-v32/hwregs/iop/iop_dmc_out_defs.h b/include/asm-cris/arch-v32/hwregs/iop/iop_dmc_out_defs.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/iop/iop_dmc_out_defs.h
@@ -0,0 +1,326 @@
+#ifndef __iop_dmc_out_defs_h
+#define __iop_dmc_out_defs_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/io_proc/rtl/iop_dmc_out.r
+ *     id:           iop_dmc_out.r,v 1.30 2005/02/16 09:14:11 niklaspa Exp
+ *     last modfied: Mon Apr 11 16:08:45 2005
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c --outfile iop_dmc_out_defs.h ../../inst/io_proc/rtl/iop_dmc_out.r
+ *      id: $Id: iop_dmc_out_defs.h,v 1.5 2005/04/24 18:31:05 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+/* Main access macros */
+#ifndef REG_RD
+#define REG_RD( scope, inst, reg ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR
+#define REG_WR( scope, inst, reg, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_VECT
+#define REG_RD_VECT( scope, inst, reg, index ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_VECT
+#define REG_WR_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT
+#define REG_RD_INT( scope, inst, reg ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT
+#define REG_WR_INT( scope, inst, reg, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT_VECT
+#define REG_RD_INT_VECT( scope, inst, reg, index ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT_VECT
+#define REG_WR_INT_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_TYPE_CONV
+#define REG_TYPE_CONV( type, orgtype, val ) \
+  ( { union { orgtype o; type n; } r; r.o = val; r.n; } )
+#endif
+
+#ifndef reg_page_size
+#define reg_page_size 8192
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg + \
+    (index) * STRIDE_##scope##_##reg )
+#endif
+
+/* C-code for register scope iop_dmc_out */
+
+/* Register rw_cfg, scope iop_dmc_out, type rw */
+typedef struct {
+  unsigned int trf_lim         : 16;
+  unsigned int last_at_trf_lim : 1;
+  unsigned int dth_intr        : 3;
+  unsigned int dummy1          : 12;
+} reg_iop_dmc_out_rw_cfg;
+#define REG_RD_ADDR_iop_dmc_out_rw_cfg 0
+#define REG_WR_ADDR_iop_dmc_out_rw_cfg 0
+
+/* Register rw_ctrl, scope iop_dmc_out, type rw */
+typedef struct {
+  unsigned int dif_en  : 1;
+  unsigned int dif_dis : 1;
+  unsigned int dummy1  : 30;
+} reg_iop_dmc_out_rw_ctrl;
+#define REG_RD_ADDR_iop_dmc_out_rw_ctrl 4
+#define REG_WR_ADDR_iop_dmc_out_rw_ctrl 4
+
+/* Register r_stat, scope iop_dmc_out, type r */
+typedef struct {
+  unsigned int dif_en : 1;
+  unsigned int dummy1 : 31;
+} reg_iop_dmc_out_r_stat;
+#define REG_RD_ADDR_iop_dmc_out_r_stat 8
+
+/* Register rw_stream_cmd, scope iop_dmc_out, type rw */
+typedef struct {
+  unsigned int cmd : 10;
+  unsigned int dummy1 : 6;
+  unsigned int n   : 8;
+  unsigned int dummy2 : 8;
+} reg_iop_dmc_out_rw_stream_cmd;
+#define REG_RD_ADDR_iop_dmc_out_rw_stream_cmd 12
+#define REG_WR_ADDR_iop_dmc_out_rw_stream_cmd 12
+
+/* Register rs_stream_data, scope iop_dmc_out, type rs */
+typedef unsigned int reg_iop_dmc_out_rs_stream_data;
+#define REG_RD_ADDR_iop_dmc_out_rs_stream_data 16
+
+/* Register r_stream_data, scope iop_dmc_out, type r */
+typedef unsigned int reg_iop_dmc_out_r_stream_data;
+#define REG_RD_ADDR_iop_dmc_out_r_stream_data 20
+
+/* Register r_stream_stat, scope iop_dmc_out, type r */
+typedef struct {
+  unsigned int dth            : 7;
+  unsigned int dummy1         : 9;
+  unsigned int dv             : 1;
+  unsigned int all_avail      : 1;
+  unsigned int last           : 1;
+  unsigned int size           : 3;
+  unsigned int data_md_valid  : 1;
+  unsigned int ctxt_md_valid  : 1;
+  unsigned int group_md_valid : 1;
+  unsigned int stream_busy    : 1;
+  unsigned int cmd_rdy        : 1;
+  unsigned int cmd_rq         : 1;
+  unsigned int dummy2         : 4;
+} reg_iop_dmc_out_r_stream_stat;
+#define REG_RD_ADDR_iop_dmc_out_r_stream_stat 24
+
+/* Register r_data_descr, scope iop_dmc_out, type r */
+typedef struct {
+  unsigned int ctrl : 8;
+  unsigned int stat : 8;
+  unsigned int md   : 16;
+} reg_iop_dmc_out_r_data_descr;
+#define REG_RD_ADDR_iop_dmc_out_r_data_descr 28
+
+/* Register r_ctxt_descr, scope iop_dmc_out, type r */
+typedef struct {
+  unsigned int ctrl : 8;
+  unsigned int stat : 8;
+  unsigned int md0  : 16;
+} reg_iop_dmc_out_r_ctxt_descr;
+#define REG_RD_ADDR_iop_dmc_out_r_ctxt_descr 32
+
+/* Register r_ctxt_descr_md1, scope iop_dmc_out, type r */
+typedef unsigned int reg_iop_dmc_out_r_ctxt_descr_md1;
+#define REG_RD_ADDR_iop_dmc_out_r_ctxt_descr_md1 36
+
+/* Register r_ctxt_descr_md2, scope iop_dmc_out, type r */
+typedef unsigned int reg_iop_dmc_out_r_ctxt_descr_md2;
+#define REG_RD_ADDR_iop_dmc_out_r_ctxt_descr_md2 40
+
+/* Register r_group_descr, scope iop_dmc_out, type r */
+typedef struct {
+  unsigned int ctrl : 8;
+  unsigned int stat : 8;
+  unsigned int md   : 16;
+} reg_iop_dmc_out_r_group_descr;
+#define REG_RD_ADDR_iop_dmc_out_r_group_descr 52
+
+/* Register rw_data_descr, scope iop_dmc_out, type rw */
+typedef struct {
+  unsigned int dummy1 : 16;
+  unsigned int md : 16;
+} reg_iop_dmc_out_rw_data_descr;
+#define REG_RD_ADDR_iop_dmc_out_rw_data_descr 56
+#define REG_WR_ADDR_iop_dmc_out_rw_data_descr 56
+
+/* Register rw_ctxt_descr, scope iop_dmc_out, type rw */
+typedef struct {
+  unsigned int dummy1 : 16;
+  unsigned int md0 : 16;
+} reg_iop_dmc_out_rw_ctxt_descr;
+#define REG_RD_ADDR_iop_dmc_out_rw_ctxt_descr 60
+#define REG_WR_ADDR_iop_dmc_out_rw_ctxt_descr 60
+
+/* Register rw_ctxt_descr_md1, scope iop_dmc_out, type rw */
+typedef unsigned int reg_iop_dmc_out_rw_ctxt_descr_md1;
+#define REG_RD_ADDR_iop_dmc_out_rw_ctxt_descr_md1 64
+#define REG_WR_ADDR_iop_dmc_out_rw_ctxt_descr_md1 64
+
+/* Register rw_ctxt_descr_md2, scope iop_dmc_out, type rw */
+typedef unsigned int reg_iop_dmc_out_rw_ctxt_descr_md2;
+#define REG_RD_ADDR_iop_dmc_out_rw_ctxt_descr_md2 68
+#define REG_WR_ADDR_iop_dmc_out_rw_ctxt_descr_md2 68
+
+/* Register rw_group_descr, scope iop_dmc_out, type rw */
+typedef struct {
+  unsigned int dummy1 : 16;
+  unsigned int md : 16;
+} reg_iop_dmc_out_rw_group_descr;
+#define REG_RD_ADDR_iop_dmc_out_rw_group_descr 80
+#define REG_WR_ADDR_iop_dmc_out_rw_group_descr 80
+
+/* Register rw_intr_mask, scope iop_dmc_out, type rw */
+typedef struct {
+  unsigned int data_md   : 1;
+  unsigned int ctxt_md   : 1;
+  unsigned int group_md  : 1;
+  unsigned int cmd_rdy   : 1;
+  unsigned int dth       : 1;
+  unsigned int dv        : 1;
+  unsigned int last_data : 1;
+  unsigned int trf_lim   : 1;
+  unsigned int cmd_rq    : 1;
+  unsigned int dummy1    : 23;
+} reg_iop_dmc_out_rw_intr_mask;
+#define REG_RD_ADDR_iop_dmc_out_rw_intr_mask 84
+#define REG_WR_ADDR_iop_dmc_out_rw_intr_mask 84
+
+/* Register rw_ack_intr, scope iop_dmc_out, type rw */
+typedef struct {
+  unsigned int data_md   : 1;
+  unsigned int ctxt_md   : 1;
+  unsigned int group_md  : 1;
+  unsigned int cmd_rdy   : 1;
+  unsigned int dth       : 1;
+  unsigned int dv        : 1;
+  unsigned int last_data : 1;
+  unsigned int trf_lim   : 1;
+  unsigned int cmd_rq    : 1;
+  unsigned int dummy1    : 23;
+} reg_iop_dmc_out_rw_ack_intr;
+#define REG_RD_ADDR_iop_dmc_out_rw_ack_intr 88
+#define REG_WR_ADDR_iop_dmc_out_rw_ack_intr 88
+
+/* Register r_intr, scope iop_dmc_out, type r */
+typedef struct {
+  unsigned int data_md   : 1;
+  unsigned int ctxt_md   : 1;
+  unsigned int group_md  : 1;
+  unsigned int cmd_rdy   : 1;
+  unsigned int dth       : 1;
+  unsigned int dv        : 1;
+  unsigned int last_data : 1;
+  unsigned int trf_lim   : 1;
+  unsigned int cmd_rq    : 1;
+  unsigned int dummy1    : 23;
+} reg_iop_dmc_out_r_intr;
+#define REG_RD_ADDR_iop_dmc_out_r_intr 92
+
+/* Register r_masked_intr, scope iop_dmc_out, type r */
+typedef struct {
+  unsigned int data_md   : 1;
+  unsigned int ctxt_md   : 1;
+  unsigned int group_md  : 1;
+  unsigned int cmd_rdy   : 1;
+  unsigned int dth       : 1;
+  unsigned int dv        : 1;
+  unsigned int last_data : 1;
+  unsigned int trf_lim   : 1;
+  unsigned int cmd_rq    : 1;
+  unsigned int dummy1    : 23;
+} reg_iop_dmc_out_r_masked_intr;
+#define REG_RD_ADDR_iop_dmc_out_r_masked_intr 96
+
+
+/* Constants */
+enum {
+  regk_iop_dmc_out_ack_pkt                 = 0x00000100,
+  regk_iop_dmc_out_array                   = 0x00000008,
+  regk_iop_dmc_out_burst                   = 0x00000020,
+  regk_iop_dmc_out_copy_next               = 0x00000010,
+  regk_iop_dmc_out_copy_up                 = 0x00000020,
+  regk_iop_dmc_out_dis_c                   = 0x00000010,
+  regk_iop_dmc_out_dis_g                   = 0x00000020,
+  regk_iop_dmc_out_lim1                    = 0x00000000,
+  regk_iop_dmc_out_lim16                   = 0x00000004,
+  regk_iop_dmc_out_lim2                    = 0x00000001,
+  regk_iop_dmc_out_lim32                   = 0x00000005,
+  regk_iop_dmc_out_lim4                    = 0x00000002,
+  regk_iop_dmc_out_lim64                   = 0x00000006,
+  regk_iop_dmc_out_lim8                    = 0x00000003,
+  regk_iop_dmc_out_load_c                  = 0x00000200,
+  regk_iop_dmc_out_load_c_n                = 0x00000280,
+  regk_iop_dmc_out_load_c_next             = 0x00000240,
+  regk_iop_dmc_out_load_d                  = 0x00000140,
+  regk_iop_dmc_out_load_g                  = 0x00000300,
+  regk_iop_dmc_out_load_g_down             = 0x000003c0,
+  regk_iop_dmc_out_load_g_next             = 0x00000340,
+  regk_iop_dmc_out_load_g_up               = 0x00000380,
+  regk_iop_dmc_out_next_en                 = 0x00000010,
+  regk_iop_dmc_out_next_pkt                = 0x00000010,
+  regk_iop_dmc_out_no                      = 0x00000000,
+  regk_iop_dmc_out_restore                 = 0x00000020,
+  regk_iop_dmc_out_rw_cfg_default          = 0x00000000,
+  regk_iop_dmc_out_rw_ctxt_descr_default   = 0x00000000,
+  regk_iop_dmc_out_rw_ctxt_descr_md1_default = 0x00000000,
+  regk_iop_dmc_out_rw_ctxt_descr_md2_default = 0x00000000,
+  regk_iop_dmc_out_rw_data_descr_default   = 0x00000000,
+  regk_iop_dmc_out_rw_group_descr_default  = 0x00000000,
+  regk_iop_dmc_out_rw_intr_mask_default    = 0x00000000,
+  regk_iop_dmc_out_save_down               = 0x00000020,
+  regk_iop_dmc_out_save_up                 = 0x00000020,
+  regk_iop_dmc_out_set_reg                 = 0x00000050,
+  regk_iop_dmc_out_set_w_size1             = 0x00000190,
+  regk_iop_dmc_out_set_w_size2             = 0x000001a0,
+  regk_iop_dmc_out_set_w_size4             = 0x000001c0,
+  regk_iop_dmc_out_store_c                 = 0x00000002,
+  regk_iop_dmc_out_store_descr             = 0x00000000,
+  regk_iop_dmc_out_store_g                 = 0x00000004,
+  regk_iop_dmc_out_store_md                = 0x00000001,
+  regk_iop_dmc_out_update_down             = 0x00000020,
+  regk_iop_dmc_out_yes                     = 0x00000001
+};
+#endif /* __iop_dmc_out_defs_h */
diff --git a/include/asm-cris/arch-v32/hwregs/iop/iop_fifo_in_defs.h b/include/asm-cris/arch-v32/hwregs/iop/iop_fifo_in_defs.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/iop/iop_fifo_in_defs.h
@@ -0,0 +1,255 @@
+#ifndef __iop_fifo_in_defs_h
+#define __iop_fifo_in_defs_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/io_proc/rtl/iop_fifo_in.r
+ *     id:           <not found>
+ *     last modfied: Mon Apr 11 16:10:07 2005
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c --outfile iop_fifo_in_defs.h ../../inst/io_proc/rtl/iop_fifo_in.r
+ *      id: $Id: iop_fifo_in_defs.h,v 1.4 2005/04/24 18:31:05 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+/* Main access macros */
+#ifndef REG_RD
+#define REG_RD( scope, inst, reg ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR
+#define REG_WR( scope, inst, reg, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_VECT
+#define REG_RD_VECT( scope, inst, reg, index ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_VECT
+#define REG_WR_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT
+#define REG_RD_INT( scope, inst, reg ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT
+#define REG_WR_INT( scope, inst, reg, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT_VECT
+#define REG_RD_INT_VECT( scope, inst, reg, index ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT_VECT
+#define REG_WR_INT_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_TYPE_CONV
+#define REG_TYPE_CONV( type, orgtype, val ) \
+  ( { union { orgtype o; type n; } r; r.o = val; r.n; } )
+#endif
+
+#ifndef reg_page_size
+#define reg_page_size 8192
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg + \
+    (index) * STRIDE_##scope##_##reg )
+#endif
+
+/* C-code for register scope iop_fifo_in */
+
+/* Register rw_cfg, scope iop_fifo_in, type rw */
+typedef struct {
+  unsigned int avail_lim       : 3;
+  unsigned int byte_order      : 2;
+  unsigned int trig            : 2;
+  unsigned int last_dis_dif_in : 1;
+  unsigned int mode            : 2;
+  unsigned int dummy1          : 22;
+} reg_iop_fifo_in_rw_cfg;
+#define REG_RD_ADDR_iop_fifo_in_rw_cfg 0
+#define REG_WR_ADDR_iop_fifo_in_rw_cfg 0
+
+/* Register rw_ctrl, scope iop_fifo_in, type rw */
+typedef struct {
+  unsigned int dif_in_en  : 1;
+  unsigned int dif_out_en : 1;
+  unsigned int dummy1     : 30;
+} reg_iop_fifo_in_rw_ctrl;
+#define REG_RD_ADDR_iop_fifo_in_rw_ctrl 4
+#define REG_WR_ADDR_iop_fifo_in_rw_ctrl 4
+
+/* Register r_stat, scope iop_fifo_in, type r */
+typedef struct {
+  unsigned int avail_bytes : 4;
+  unsigned int last        : 8;
+  unsigned int dif_in_en   : 1;
+  unsigned int dif_out_en  : 1;
+  unsigned int dummy1      : 18;
+} reg_iop_fifo_in_r_stat;
+#define REG_RD_ADDR_iop_fifo_in_r_stat 8
+
+/* Register rs_rd1byte, scope iop_fifo_in, type rs */
+typedef struct {
+  unsigned int data : 8;
+  unsigned int dummy1 : 24;
+} reg_iop_fifo_in_rs_rd1byte;
+#define REG_RD_ADDR_iop_fifo_in_rs_rd1byte 12
+
+/* Register r_rd1byte, scope iop_fifo_in, type r */
+typedef struct {
+  unsigned int data : 8;
+  unsigned int dummy1 : 24;
+} reg_iop_fifo_in_r_rd1byte;
+#define REG_RD_ADDR_iop_fifo_in_r_rd1byte 16
+
+/* Register rs_rd2byte, scope iop_fifo_in, type rs */
+typedef struct {
+  unsigned int data : 16;
+  unsigned int dummy1 : 16;
+} reg_iop_fifo_in_rs_rd2byte;
+#define REG_RD_ADDR_iop_fifo_in_rs_rd2byte 20
+
+/* Register r_rd2byte, scope iop_fifo_in, type r */
+typedef struct {
+  unsigned int data : 16;
+  unsigned int dummy1 : 16;
+} reg_iop_fifo_in_r_rd2byte;
+#define REG_RD_ADDR_iop_fifo_in_r_rd2byte 24
+
+/* Register rs_rd3byte, scope iop_fifo_in, type rs */
+typedef struct {
+  unsigned int data : 24;
+  unsigned int dummy1 : 8;
+} reg_iop_fifo_in_rs_rd3byte;
+#define REG_RD_ADDR_iop_fifo_in_rs_rd3byte 28
+
+/* Register r_rd3byte, scope iop_fifo_in, type r */
+typedef struct {
+  unsigned int data : 24;
+  unsigned int dummy1 : 8;
+} reg_iop_fifo_in_r_rd3byte;
+#define REG_RD_ADDR_iop_fifo_in_r_rd3byte 32
+
+/* Register rs_rd4byte, scope iop_fifo_in, type rs */
+typedef struct {
+  unsigned int data : 32;
+} reg_iop_fifo_in_rs_rd4byte;
+#define REG_RD_ADDR_iop_fifo_in_rs_rd4byte 36
+
+/* Register r_rd4byte, scope iop_fifo_in, type r */
+typedef struct {
+  unsigned int data : 32;
+} reg_iop_fifo_in_r_rd4byte;
+#define REG_RD_ADDR_iop_fifo_in_r_rd4byte 40
+
+/* Register rw_set_last, scope iop_fifo_in, type rw */
+typedef unsigned int reg_iop_fifo_in_rw_set_last;
+#define REG_RD_ADDR_iop_fifo_in_rw_set_last 44
+#define REG_WR_ADDR_iop_fifo_in_rw_set_last 44
+
+/* Register rw_strb_dif_in, scope iop_fifo_in, type rw */
+typedef struct {
+  unsigned int last : 2;
+  unsigned int dummy1 : 30;
+} reg_iop_fifo_in_rw_strb_dif_in;
+#define REG_RD_ADDR_iop_fifo_in_rw_strb_dif_in 48
+#define REG_WR_ADDR_iop_fifo_in_rw_strb_dif_in 48
+
+/* Register rw_intr_mask, scope iop_fifo_in, type rw */
+typedef struct {
+  unsigned int urun      : 1;
+  unsigned int last_data : 1;
+  unsigned int dav       : 1;
+  unsigned int avail     : 1;
+  unsigned int orun      : 1;
+  unsigned int dummy1    : 27;
+} reg_iop_fifo_in_rw_intr_mask;
+#define REG_RD_ADDR_iop_fifo_in_rw_intr_mask 52
+#define REG_WR_ADDR_iop_fifo_in_rw_intr_mask 52
+
+/* Register rw_ack_intr, scope iop_fifo_in, type rw */
+typedef struct {
+  unsigned int urun      : 1;
+  unsigned int last_data : 1;
+  unsigned int dav       : 1;
+  unsigned int avail     : 1;
+  unsigned int orun      : 1;
+  unsigned int dummy1    : 27;
+} reg_iop_fifo_in_rw_ack_intr;
+#define REG_RD_ADDR_iop_fifo_in_rw_ack_intr 56
+#define REG_WR_ADDR_iop_fifo_in_rw_ack_intr 56
+
+/* Register r_intr, scope iop_fifo_in, type r */
+typedef struct {
+  unsigned int urun      : 1;
+  unsigned int last_data : 1;
+  unsigned int dav       : 1;
+  unsigned int avail     : 1;
+  unsigned int orun      : 1;
+  unsigned int dummy1    : 27;
+} reg_iop_fifo_in_r_intr;
+#define REG_RD_ADDR_iop_fifo_in_r_intr 60
+
+/* Register r_masked_intr, scope iop_fifo_in, type r */
+typedef struct {
+  unsigned int urun      : 1;
+  unsigned int last_data : 1;
+  unsigned int dav       : 1;
+  unsigned int avail     : 1;
+  unsigned int orun      : 1;
+  unsigned int dummy1    : 27;
+} reg_iop_fifo_in_r_masked_intr;
+#define REG_RD_ADDR_iop_fifo_in_r_masked_intr 64
+
+
+/* Constants */
+enum {
+  regk_iop_fifo_in_dif_in                  = 0x00000002,
+  regk_iop_fifo_in_hi                      = 0x00000000,
+  regk_iop_fifo_in_neg                     = 0x00000002,
+  regk_iop_fifo_in_no                      = 0x00000000,
+  regk_iop_fifo_in_order16                 = 0x00000001,
+  regk_iop_fifo_in_order24                 = 0x00000002,
+  regk_iop_fifo_in_order32                 = 0x00000003,
+  regk_iop_fifo_in_order8                  = 0x00000000,
+  regk_iop_fifo_in_pos                     = 0x00000001,
+  regk_iop_fifo_in_pos_neg                 = 0x00000003,
+  regk_iop_fifo_in_rw_cfg_default          = 0x00000024,
+  regk_iop_fifo_in_rw_ctrl_default         = 0x00000000,
+  regk_iop_fifo_in_rw_intr_mask_default    = 0x00000000,
+  regk_iop_fifo_in_rw_set_last_default     = 0x00000000,
+  regk_iop_fifo_in_rw_strb_dif_in_default  = 0x00000000,
+  regk_iop_fifo_in_size16                  = 0x00000002,
+  regk_iop_fifo_in_size24                  = 0x00000001,
+  regk_iop_fifo_in_size32                  = 0x00000000,
+  regk_iop_fifo_in_size8                   = 0x00000003,
+  regk_iop_fifo_in_yes                     = 0x00000001
+};
+#endif /* __iop_fifo_in_defs_h */
diff --git a/include/asm-cris/arch-v32/hwregs/iop/iop_fifo_in_extra_defs.h b/include/asm-cris/arch-v32/hwregs/iop/iop_fifo_in_extra_defs.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/iop/iop_fifo_in_extra_defs.h
@@ -0,0 +1,164 @@
+#ifndef __iop_fifo_in_extra_defs_h
+#define __iop_fifo_in_extra_defs_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/io_proc/rtl/iop_fifo_in_extra.r
+ *     id:           <not found>
+ *     last modfied: Mon Apr 11 16:10:08 2005
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c --outfile iop_fifo_in_extra_defs.h ../../inst/io_proc/rtl/iop_fifo_in_extra.r
+ *      id: $Id: iop_fifo_in_extra_defs.h,v 1.1 2005/04/24 18:31:05 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+/* Main access macros */
+#ifndef REG_RD
+#define REG_RD( scope, inst, reg ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR
+#define REG_WR( scope, inst, reg, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_VECT
+#define REG_RD_VECT( scope, inst, reg, index ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_VECT
+#define REG_WR_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT
+#define REG_RD_INT( scope, inst, reg ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT
+#define REG_WR_INT( scope, inst, reg, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT_VECT
+#define REG_RD_INT_VECT( scope, inst, reg, index ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT_VECT
+#define REG_WR_INT_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_TYPE_CONV
+#define REG_TYPE_CONV( type, orgtype, val ) \
+  ( { union { orgtype o; type n; } r; r.o = val; r.n; } )
+#endif
+
+#ifndef reg_page_size
+#define reg_page_size 8192
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg + \
+    (index) * STRIDE_##scope##_##reg )
+#endif
+
+/* C-code for register scope iop_fifo_in_extra */
+
+/* Register rw_wr_data, scope iop_fifo_in_extra, type rw */
+typedef unsigned int reg_iop_fifo_in_extra_rw_wr_data;
+#define REG_RD_ADDR_iop_fifo_in_extra_rw_wr_data 0
+#define REG_WR_ADDR_iop_fifo_in_extra_rw_wr_data 0
+
+/* Register r_stat, scope iop_fifo_in_extra, type r */
+typedef struct {
+  unsigned int avail_bytes : 4;
+  unsigned int last        : 8;
+  unsigned int dif_in_en   : 1;
+  unsigned int dif_out_en  : 1;
+  unsigned int dummy1      : 18;
+} reg_iop_fifo_in_extra_r_stat;
+#define REG_RD_ADDR_iop_fifo_in_extra_r_stat 4
+
+/* Register rw_strb_dif_in, scope iop_fifo_in_extra, type rw */
+typedef struct {
+  unsigned int last : 2;
+  unsigned int dummy1 : 30;
+} reg_iop_fifo_in_extra_rw_strb_dif_in;
+#define REG_RD_ADDR_iop_fifo_in_extra_rw_strb_dif_in 8
+#define REG_WR_ADDR_iop_fifo_in_extra_rw_strb_dif_in 8
+
+/* Register rw_intr_mask, scope iop_fifo_in_extra, type rw */
+typedef struct {
+  unsigned int urun      : 1;
+  unsigned int last_data : 1;
+  unsigned int dav       : 1;
+  unsigned int avail     : 1;
+  unsigned int orun      : 1;
+  unsigned int dummy1    : 27;
+} reg_iop_fifo_in_extra_rw_intr_mask;
+#define REG_RD_ADDR_iop_fifo_in_extra_rw_intr_mask 12
+#define REG_WR_ADDR_iop_fifo_in_extra_rw_intr_mask 12
+
+/* Register rw_ack_intr, scope iop_fifo_in_extra, type rw */
+typedef struct {
+  unsigned int urun      : 1;
+  unsigned int last_data : 1;
+  unsigned int dav       : 1;
+  unsigned int avail     : 1;
+  unsigned int orun      : 1;
+  unsigned int dummy1    : 27;
+} reg_iop_fifo_in_extra_rw_ack_intr;
+#define REG_RD_ADDR_iop_fifo_in_extra_rw_ack_intr 16
+#define REG_WR_ADDR_iop_fifo_in_extra_rw_ack_intr 16
+
+/* Register r_intr, scope iop_fifo_in_extra, type r */
+typedef struct {
+  unsigned int urun      : 1;
+  unsigned int last_data : 1;
+  unsigned int dav       : 1;
+  unsigned int avail     : 1;
+  unsigned int orun      : 1;
+  unsigned int dummy1    : 27;
+} reg_iop_fifo_in_extra_r_intr;
+#define REG_RD_ADDR_iop_fifo_in_extra_r_intr 20
+
+/* Register r_masked_intr, scope iop_fifo_in_extra, type r */
+typedef struct {
+  unsigned int urun      : 1;
+  unsigned int last_data : 1;
+  unsigned int dav       : 1;
+  unsigned int avail     : 1;
+  unsigned int orun      : 1;
+  unsigned int dummy1    : 27;
+} reg_iop_fifo_in_extra_r_masked_intr;
+#define REG_RD_ADDR_iop_fifo_in_extra_r_masked_intr 24
+
+
+/* Constants */
+enum {
+  regk_iop_fifo_in_extra_fifo_in           = 0x00000002,
+  regk_iop_fifo_in_extra_no                = 0x00000000,
+  regk_iop_fifo_in_extra_rw_intr_mask_default = 0x00000000,
+  regk_iop_fifo_in_extra_yes               = 0x00000001
+};
+#endif /* __iop_fifo_in_extra_defs_h */
diff --git a/include/asm-cris/arch-v32/hwregs/iop/iop_fifo_out_defs.h b/include/asm-cris/arch-v32/hwregs/iop/iop_fifo_out_defs.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/iop/iop_fifo_out_defs.h
@@ -0,0 +1,278 @@
+#ifndef __iop_fifo_out_defs_h
+#define __iop_fifo_out_defs_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/io_proc/rtl/iop_fifo_out.r
+ *     id:           <not found>
+ *     last modfied: Mon Apr 11 16:10:09 2005
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c --outfile iop_fifo_out_defs.h ../../inst/io_proc/rtl/iop_fifo_out.r
+ *      id: $Id: iop_fifo_out_defs.h,v 1.4 2005/04/24 18:31:05 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+/* Main access macros */
+#ifndef REG_RD
+#define REG_RD( scope, inst, reg ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR
+#define REG_WR( scope, inst, reg, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_VECT
+#define REG_RD_VECT( scope, inst, reg, index ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_VECT
+#define REG_WR_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT
+#define REG_RD_INT( scope, inst, reg ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT
+#define REG_WR_INT( scope, inst, reg, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT_VECT
+#define REG_RD_INT_VECT( scope, inst, reg, index ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT_VECT
+#define REG_WR_INT_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_TYPE_CONV
+#define REG_TYPE_CONV( type, orgtype, val ) \
+  ( { union { orgtype o; type n; } r; r.o = val; r.n; } )
+#endif
+
+#ifndef reg_page_size
+#define reg_page_size 8192
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg + \
+    (index) * STRIDE_##scope##_##reg )
+#endif
+
+/* C-code for register scope iop_fifo_out */
+
+/* Register rw_cfg, scope iop_fifo_out, type rw */
+typedef struct {
+  unsigned int free_lim         : 3;
+  unsigned int byte_order       : 2;
+  unsigned int trig             : 2;
+  unsigned int last_dis_dif_in  : 1;
+  unsigned int mode             : 2;
+  unsigned int delay_out_last   : 1;
+  unsigned int last_dis_dif_out : 1;
+  unsigned int dummy1           : 20;
+} reg_iop_fifo_out_rw_cfg;
+#define REG_RD_ADDR_iop_fifo_out_rw_cfg 0
+#define REG_WR_ADDR_iop_fifo_out_rw_cfg 0
+
+/* Register rw_ctrl, scope iop_fifo_out, type rw */
+typedef struct {
+  unsigned int dif_in_en  : 1;
+  unsigned int dif_out_en : 1;
+  unsigned int dummy1     : 30;
+} reg_iop_fifo_out_rw_ctrl;
+#define REG_RD_ADDR_iop_fifo_out_rw_ctrl 4
+#define REG_WR_ADDR_iop_fifo_out_rw_ctrl 4
+
+/* Register r_stat, scope iop_fifo_out, type r */
+typedef struct {
+  unsigned int avail_bytes    : 4;
+  unsigned int last           : 8;
+  unsigned int dif_in_en      : 1;
+  unsigned int dif_out_en     : 1;
+  unsigned int zero_data_last : 1;
+  unsigned int dummy1         : 17;
+} reg_iop_fifo_out_r_stat;
+#define REG_RD_ADDR_iop_fifo_out_r_stat 8
+
+/* Register rw_wr1byte, scope iop_fifo_out, type rw */
+typedef struct {
+  unsigned int data : 8;
+  unsigned int dummy1 : 24;
+} reg_iop_fifo_out_rw_wr1byte;
+#define REG_RD_ADDR_iop_fifo_out_rw_wr1byte 12
+#define REG_WR_ADDR_iop_fifo_out_rw_wr1byte 12
+
+/* Register rw_wr2byte, scope iop_fifo_out, type rw */
+typedef struct {
+  unsigned int data : 16;
+  unsigned int dummy1 : 16;
+} reg_iop_fifo_out_rw_wr2byte;
+#define REG_RD_ADDR_iop_fifo_out_rw_wr2byte 16
+#define REG_WR_ADDR_iop_fifo_out_rw_wr2byte 16
+
+/* Register rw_wr3byte, scope iop_fifo_out, type rw */
+typedef struct {
+  unsigned int data : 24;
+  unsigned int dummy1 : 8;
+} reg_iop_fifo_out_rw_wr3byte;
+#define REG_RD_ADDR_iop_fifo_out_rw_wr3byte 20
+#define REG_WR_ADDR_iop_fifo_out_rw_wr3byte 20
+
+/* Register rw_wr4byte, scope iop_fifo_out, type rw */
+typedef struct {
+  unsigned int data : 32;
+} reg_iop_fifo_out_rw_wr4byte;
+#define REG_RD_ADDR_iop_fifo_out_rw_wr4byte 24
+#define REG_WR_ADDR_iop_fifo_out_rw_wr4byte 24
+
+/* Register rw_wr1byte_last, scope iop_fifo_out, type rw */
+typedef struct {
+  unsigned int data : 8;
+  unsigned int dummy1 : 24;
+} reg_iop_fifo_out_rw_wr1byte_last;
+#define REG_RD_ADDR_iop_fifo_out_rw_wr1byte_last 28
+#define REG_WR_ADDR_iop_fifo_out_rw_wr1byte_last 28
+
+/* Register rw_wr2byte_last, scope iop_fifo_out, type rw */
+typedef struct {
+  unsigned int data : 16;
+  unsigned int dummy1 : 16;
+} reg_iop_fifo_out_rw_wr2byte_last;
+#define REG_RD_ADDR_iop_fifo_out_rw_wr2byte_last 32
+#define REG_WR_ADDR_iop_fifo_out_rw_wr2byte_last 32
+
+/* Register rw_wr3byte_last, scope iop_fifo_out, type rw */
+typedef struct {
+  unsigned int data : 24;
+  unsigned int dummy1 : 8;
+} reg_iop_fifo_out_rw_wr3byte_last;
+#define REG_RD_ADDR_iop_fifo_out_rw_wr3byte_last 36
+#define REG_WR_ADDR_iop_fifo_out_rw_wr3byte_last 36
+
+/* Register rw_wr4byte_last, scope iop_fifo_out, type rw */
+typedef struct {
+  unsigned int data : 32;
+} reg_iop_fifo_out_rw_wr4byte_last;
+#define REG_RD_ADDR_iop_fifo_out_rw_wr4byte_last 40
+#define REG_WR_ADDR_iop_fifo_out_rw_wr4byte_last 40
+
+/* Register rw_set_last, scope iop_fifo_out, type rw */
+typedef unsigned int reg_iop_fifo_out_rw_set_last;
+#define REG_RD_ADDR_iop_fifo_out_rw_set_last 44
+#define REG_WR_ADDR_iop_fifo_out_rw_set_last 44
+
+/* Register rs_rd_data, scope iop_fifo_out, type rs */
+typedef unsigned int reg_iop_fifo_out_rs_rd_data;
+#define REG_RD_ADDR_iop_fifo_out_rs_rd_data 48
+
+/* Register r_rd_data, scope iop_fifo_out, type r */
+typedef unsigned int reg_iop_fifo_out_r_rd_data;
+#define REG_RD_ADDR_iop_fifo_out_r_rd_data 52
+
+/* Register rw_strb_dif_out, scope iop_fifo_out, type rw */
+typedef unsigned int reg_iop_fifo_out_rw_strb_dif_out;
+#define REG_RD_ADDR_iop_fifo_out_rw_strb_dif_out 56
+#define REG_WR_ADDR_iop_fifo_out_rw_strb_dif_out 56
+
+/* Register rw_intr_mask, scope iop_fifo_out, type rw */
+typedef struct {
+  unsigned int urun      : 1;
+  unsigned int last_data : 1;
+  unsigned int dav       : 1;
+  unsigned int free      : 1;
+  unsigned int orun      : 1;
+  unsigned int dummy1    : 27;
+} reg_iop_fifo_out_rw_intr_mask;
+#define REG_RD_ADDR_iop_fifo_out_rw_intr_mask 60
+#define REG_WR_ADDR_iop_fifo_out_rw_intr_mask 60
+
+/* Register rw_ack_intr, scope iop_fifo_out, type rw */
+typedef struct {
+  unsigned int urun      : 1;
+  unsigned int last_data : 1;
+  unsigned int dav       : 1;
+  unsigned int free      : 1;
+  unsigned int orun      : 1;
+  unsigned int dummy1    : 27;
+} reg_iop_fifo_out_rw_ack_intr;
+#define REG_RD_ADDR_iop_fifo_out_rw_ack_intr 64
+#define REG_WR_ADDR_iop_fifo_out_rw_ack_intr 64
+
+/* Register r_intr, scope iop_fifo_out, type r */
+typedef struct {
+  unsigned int urun      : 1;
+  unsigned int last_data : 1;
+  unsigned int dav       : 1;
+  unsigned int free      : 1;
+  unsigned int orun      : 1;
+  unsigned int dummy1    : 27;
+} reg_iop_fifo_out_r_intr;
+#define REG_RD_ADDR_iop_fifo_out_r_intr 68
+
+/* Register r_masked_intr, scope iop_fifo_out, type r */
+typedef struct {
+  unsigned int urun      : 1;
+  unsigned int last_data : 1;
+  unsigned int dav       : 1;
+  unsigned int free      : 1;
+  unsigned int orun      : 1;
+  unsigned int dummy1    : 27;
+} reg_iop_fifo_out_r_masked_intr;
+#define REG_RD_ADDR_iop_fifo_out_r_masked_intr 72
+
+
+/* Constants */
+enum {
+  regk_iop_fifo_out_hi                     = 0x00000000,
+  regk_iop_fifo_out_neg                    = 0x00000002,
+  regk_iop_fifo_out_no                     = 0x00000000,
+  regk_iop_fifo_out_order16                = 0x00000001,
+  regk_iop_fifo_out_order24                = 0x00000002,
+  regk_iop_fifo_out_order32                = 0x00000003,
+  regk_iop_fifo_out_order8                 = 0x00000000,
+  regk_iop_fifo_out_pos                    = 0x00000001,
+  regk_iop_fifo_out_pos_neg                = 0x00000003,
+  regk_iop_fifo_out_rw_cfg_default         = 0x00000024,
+  regk_iop_fifo_out_rw_ctrl_default        = 0x00000000,
+  regk_iop_fifo_out_rw_intr_mask_default   = 0x00000000,
+  regk_iop_fifo_out_rw_set_last_default    = 0x00000000,
+  regk_iop_fifo_out_rw_strb_dif_out_default = 0x00000000,
+  regk_iop_fifo_out_rw_wr1byte_default     = 0x00000000,
+  regk_iop_fifo_out_rw_wr1byte_last_default = 0x00000000,
+  regk_iop_fifo_out_rw_wr2byte_default     = 0x00000000,
+  regk_iop_fifo_out_rw_wr2byte_last_default = 0x00000000,
+  regk_iop_fifo_out_rw_wr3byte_default     = 0x00000000,
+  regk_iop_fifo_out_rw_wr3byte_last_default = 0x00000000,
+  regk_iop_fifo_out_rw_wr4byte_default     = 0x00000000,
+  regk_iop_fifo_out_rw_wr4byte_last_default = 0x00000000,
+  regk_iop_fifo_out_size16                 = 0x00000002,
+  regk_iop_fifo_out_size24                 = 0x00000001,
+  regk_iop_fifo_out_size32                 = 0x00000000,
+  regk_iop_fifo_out_size8                  = 0x00000003,
+  regk_iop_fifo_out_yes                    = 0x00000001
+};
+#endif /* __iop_fifo_out_defs_h */
diff --git a/include/asm-cris/arch-v32/hwregs/iop/iop_fifo_out_extra_defs.h b/include/asm-cris/arch-v32/hwregs/iop/iop_fifo_out_extra_defs.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/iop/iop_fifo_out_extra_defs.h
@@ -0,0 +1,164 @@
+#ifndef __iop_fifo_out_extra_defs_h
+#define __iop_fifo_out_extra_defs_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/io_proc/rtl/iop_fifo_out_extra.r
+ *     id:           <not found>
+ *     last modfied: Mon Apr 11 16:10:10 2005
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c --outfile iop_fifo_out_extra_defs.h ../../inst/io_proc/rtl/iop_fifo_out_extra.r
+ *      id: $Id: iop_fifo_out_extra_defs.h,v 1.1 2005/04/24 18:31:05 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+/* Main access macros */
+#ifndef REG_RD
+#define REG_RD( scope, inst, reg ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR
+#define REG_WR( scope, inst, reg, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_VECT
+#define REG_RD_VECT( scope, inst, reg, index ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_VECT
+#define REG_WR_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT
+#define REG_RD_INT( scope, inst, reg ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT
+#define REG_WR_INT( scope, inst, reg, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT_VECT
+#define REG_RD_INT_VECT( scope, inst, reg, index ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT_VECT
+#define REG_WR_INT_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_TYPE_CONV
+#define REG_TYPE_CONV( type, orgtype, val ) \
+  ( { union { orgtype o; type n; } r; r.o = val; r.n; } )
+#endif
+
+#ifndef reg_page_size
+#define reg_page_size 8192
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg + \
+    (index) * STRIDE_##scope##_##reg )
+#endif
+
+/* C-code for register scope iop_fifo_out_extra */
+
+/* Register rs_rd_data, scope iop_fifo_out_extra, type rs */
+typedef unsigned int reg_iop_fifo_out_extra_rs_rd_data;
+#define REG_RD_ADDR_iop_fifo_out_extra_rs_rd_data 0
+
+/* Register r_rd_data, scope iop_fifo_out_extra, type r */
+typedef unsigned int reg_iop_fifo_out_extra_r_rd_data;
+#define REG_RD_ADDR_iop_fifo_out_extra_r_rd_data 4
+
+/* Register r_stat, scope iop_fifo_out_extra, type r */
+typedef struct {
+  unsigned int avail_bytes    : 4;
+  unsigned int last           : 8;
+  unsigned int dif_in_en      : 1;
+  unsigned int dif_out_en     : 1;
+  unsigned int zero_data_last : 1;
+  unsigned int dummy1         : 17;
+} reg_iop_fifo_out_extra_r_stat;
+#define REG_RD_ADDR_iop_fifo_out_extra_r_stat 8
+
+/* Register rw_strb_dif_out, scope iop_fifo_out_extra, type rw */
+typedef unsigned int reg_iop_fifo_out_extra_rw_strb_dif_out;
+#define REG_RD_ADDR_iop_fifo_out_extra_rw_strb_dif_out 12
+#define REG_WR_ADDR_iop_fifo_out_extra_rw_strb_dif_out 12
+
+/* Register rw_intr_mask, scope iop_fifo_out_extra, type rw */
+typedef struct {
+  unsigned int urun      : 1;
+  unsigned int last_data : 1;
+  unsigned int dav       : 1;
+  unsigned int free      : 1;
+  unsigned int orun      : 1;
+  unsigned int dummy1    : 27;
+} reg_iop_fifo_out_extra_rw_intr_mask;
+#define REG_RD_ADDR_iop_fifo_out_extra_rw_intr_mask 16
+#define REG_WR_ADDR_iop_fifo_out_extra_rw_intr_mask 16
+
+/* Register rw_ack_intr, scope iop_fifo_out_extra, type rw */
+typedef struct {
+  unsigned int urun      : 1;
+  unsigned int last_data : 1;
+  unsigned int dav       : 1;
+  unsigned int free      : 1;
+  unsigned int orun      : 1;
+  unsigned int dummy1    : 27;
+} reg_iop_fifo_out_extra_rw_ack_intr;
+#define REG_RD_ADDR_iop_fifo_out_extra_rw_ack_intr 20
+#define REG_WR_ADDR_iop_fifo_out_extra_rw_ack_intr 20
+
+/* Register r_intr, scope iop_fifo_out_extra, type r */
+typedef struct {
+  unsigned int urun      : 1;
+  unsigned int last_data : 1;
+  unsigned int dav       : 1;
+  unsigned int free      : 1;
+  unsigned int orun      : 1;
+  unsigned int dummy1    : 27;
+} reg_iop_fifo_out_extra_r_intr;
+#define REG_RD_ADDR_iop_fifo_out_extra_r_intr 24
+
+/* Register r_masked_intr, scope iop_fifo_out_extra, type r */
+typedef struct {
+  unsigned int urun      : 1;
+  unsigned int last_data : 1;
+  unsigned int dav       : 1;
+  unsigned int free      : 1;
+  unsigned int orun      : 1;
+  unsigned int dummy1    : 27;
+} reg_iop_fifo_out_extra_r_masked_intr;
+#define REG_RD_ADDR_iop_fifo_out_extra_r_masked_intr 28
+
+
+/* Constants */
+enum {
+  regk_iop_fifo_out_extra_no               = 0x00000000,
+  regk_iop_fifo_out_extra_rw_intr_mask_default = 0x00000000,
+  regk_iop_fifo_out_extra_yes              = 0x00000001
+};
+#endif /* __iop_fifo_out_extra_defs_h */
diff --git a/include/asm-cris/arch-v32/hwregs/iop/iop_mpu_defs.h b/include/asm-cris/arch-v32/hwregs/iop/iop_mpu_defs.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/iop/iop_mpu_defs.h
@@ -0,0 +1,190 @@
+#ifndef __iop_mpu_defs_h
+#define __iop_mpu_defs_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/io_proc/rtl/iop_mpu.r
+ *     id:           iop_mpu.r,v 1.30 2005/02/17 08:12:33 niklaspa Exp
+ *     last modfied: Mon Apr 11 16:08:45 2005
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c --outfile iop_mpu_defs.h ../../inst/io_proc/rtl/iop_mpu.r
+ *      id: $Id: iop_mpu_defs.h,v 1.5 2005/04/24 18:31:05 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+/* Main access macros */
+#ifndef REG_RD
+#define REG_RD( scope, inst, reg ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR
+#define REG_WR( scope, inst, reg, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_VECT
+#define REG_RD_VECT( scope, inst, reg, index ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_VECT
+#define REG_WR_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT
+#define REG_RD_INT( scope, inst, reg ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT
+#define REG_WR_INT( scope, inst, reg, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT_VECT
+#define REG_RD_INT_VECT( scope, inst, reg, index ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT_VECT
+#define REG_WR_INT_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_TYPE_CONV
+#define REG_TYPE_CONV( type, orgtype, val ) \
+  ( { union { orgtype o; type n; } r; r.o = val; r.n; } )
+#endif
+
+#ifndef reg_page_size
+#define reg_page_size 8192
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg + \
+    (index) * STRIDE_##scope##_##reg )
+#endif
+
+/* C-code for register scope iop_mpu */
+
+#define STRIDE_iop_mpu_rw_r 4
+/* Register rw_r, scope iop_mpu, type rw */
+typedef unsigned int reg_iop_mpu_rw_r;
+#define REG_RD_ADDR_iop_mpu_rw_r 0
+#define REG_WR_ADDR_iop_mpu_rw_r 0
+
+/* Register rw_ctrl, scope iop_mpu, type rw */
+typedef struct {
+  unsigned int en : 1;
+  unsigned int dummy1 : 31;
+} reg_iop_mpu_rw_ctrl;
+#define REG_RD_ADDR_iop_mpu_rw_ctrl 128
+#define REG_WR_ADDR_iop_mpu_rw_ctrl 128
+
+/* Register r_pc, scope iop_mpu, type r */
+typedef struct {
+  unsigned int addr : 12;
+  unsigned int dummy1 : 20;
+} reg_iop_mpu_r_pc;
+#define REG_RD_ADDR_iop_mpu_r_pc 132
+
+/* Register r_stat, scope iop_mpu, type r */
+typedef struct {
+  unsigned int instr_reg_busy : 1;
+  unsigned int intr_busy      : 1;
+  unsigned int intr_vect      : 16;
+  unsigned int dummy1         : 14;
+} reg_iop_mpu_r_stat;
+#define REG_RD_ADDR_iop_mpu_r_stat 136
+
+/* Register rw_instr, scope iop_mpu, type rw */
+typedef unsigned int reg_iop_mpu_rw_instr;
+#define REG_RD_ADDR_iop_mpu_rw_instr 140
+#define REG_WR_ADDR_iop_mpu_rw_instr 140
+
+/* Register rw_immediate, scope iop_mpu, type rw */
+typedef unsigned int reg_iop_mpu_rw_immediate;
+#define REG_RD_ADDR_iop_mpu_rw_immediate 144
+#define REG_WR_ADDR_iop_mpu_rw_immediate 144
+
+/* Register r_trace, scope iop_mpu, type r */
+typedef struct {
+  unsigned int intr_vect      : 16;
+  unsigned int pc             : 12;
+  unsigned int en             : 1;
+  unsigned int instr_reg_busy : 1;
+  unsigned int intr_busy      : 1;
+  unsigned int dummy1         : 1;
+} reg_iop_mpu_r_trace;
+#define REG_RD_ADDR_iop_mpu_r_trace 148
+
+/* Register r_wr_stat, scope iop_mpu, type r */
+typedef struct {
+  unsigned int r0  : 1;
+  unsigned int r1  : 1;
+  unsigned int r2  : 1;
+  unsigned int r3  : 1;
+  unsigned int r4  : 1;
+  unsigned int r5  : 1;
+  unsigned int r6  : 1;
+  unsigned int r7  : 1;
+  unsigned int r8  : 1;
+  unsigned int r9  : 1;
+  unsigned int r10 : 1;
+  unsigned int r11 : 1;
+  unsigned int r12 : 1;
+  unsigned int r13 : 1;
+  unsigned int r14 : 1;
+  unsigned int r15 : 1;
+  unsigned int dummy1 : 16;
+} reg_iop_mpu_r_wr_stat;
+#define REG_RD_ADDR_iop_mpu_r_wr_stat 152
+
+#define STRIDE_iop_mpu_rw_thread 4
+/* Register rw_thread, scope iop_mpu, type rw */
+typedef struct {
+  unsigned int addr : 12;
+  unsigned int dummy1 : 20;
+} reg_iop_mpu_rw_thread;
+#define REG_RD_ADDR_iop_mpu_rw_thread 156
+#define REG_WR_ADDR_iop_mpu_rw_thread 156
+
+#define STRIDE_iop_mpu_rw_intr 4
+/* Register rw_intr, scope iop_mpu, type rw */
+typedef struct {
+  unsigned int addr : 12;
+  unsigned int dummy1 : 20;
+} reg_iop_mpu_rw_intr;
+#define REG_RD_ADDR_iop_mpu_rw_intr 196
+#define REG_WR_ADDR_iop_mpu_rw_intr 196
+
+
+/* Constants */
+enum {
+  regk_iop_mpu_no                          = 0x00000000,
+  regk_iop_mpu_r_pc_default                = 0x00000000,
+  regk_iop_mpu_rw_ctrl_default             = 0x00000000,
+  regk_iop_mpu_rw_intr_size                = 0x00000010,
+  regk_iop_mpu_rw_r_size                   = 0x00000010,
+  regk_iop_mpu_rw_thread_default           = 0x00000000,
+  regk_iop_mpu_rw_thread_size              = 0x00000004,
+  regk_iop_mpu_yes                         = 0x00000001
+};
+#endif /* __iop_mpu_defs_h */
diff --git a/include/asm-cris/arch-v32/hwregs/iop/iop_mpu_macros.h b/include/asm-cris/arch-v32/hwregs/iop/iop_mpu_macros.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/iop/iop_mpu_macros.h
@@ -0,0 +1,764 @@
+/* ************************************************************************* */
+/* This file is autogenerated by IOPASM Version 1.2                          */
+/* DO NOT EDIT THIS FILE - All changes will be lost!                         */
+/* ************************************************************************* */
+
+
+
+#ifndef __IOP_MPU_MACROS_H__
+#define __IOP_MPU_MACROS_H__
+
+
+/* ************************************************************************* */
+/*                           REGISTER DEFINITIONS                            */
+/* ************************************************************************* */
+#define MPU_R0 (0x0)
+#define MPU_R1 (0x1)
+#define MPU_R2 (0x2)
+#define MPU_R3 (0x3)
+#define MPU_R4 (0x4)
+#define MPU_R5 (0x5)
+#define MPU_R6 (0x6)
+#define MPU_R7 (0x7)
+#define MPU_R8 (0x8)
+#define MPU_R9 (0x9)
+#define MPU_R10 (0xa)
+#define MPU_R11 (0xb)
+#define MPU_R12 (0xc)
+#define MPU_R13 (0xd)
+#define MPU_R14 (0xe)
+#define MPU_R15 (0xf)
+#define MPU_PC (0x2)
+#define MPU_WSTS (0x3)
+#define MPU_JADDR (0x4)
+#define MPU_IRP (0x5)
+#define MPU_SRP (0x6)
+#define MPU_T0 (0x8)
+#define MPU_T1 (0x9)
+#define MPU_T2 (0xa)
+#define MPU_T3 (0xb)
+#define MPU_I0 (0x10)
+#define MPU_I1 (0x11)
+#define MPU_I2 (0x12)
+#define MPU_I3 (0x13)
+#define MPU_I4 (0x14)
+#define MPU_I5 (0x15)
+#define MPU_I6 (0x16)
+#define MPU_I7 (0x17)
+#define MPU_I8 (0x18)
+#define MPU_I9 (0x19)
+#define MPU_I10 (0x1a)
+#define MPU_I11 (0x1b)
+#define MPU_I12 (0x1c)
+#define MPU_I13 (0x1d)
+#define MPU_I14 (0x1e)
+#define MPU_I15 (0x1f)
+#define MPU_P2 (0x2)
+#define MPU_P3 (0x3)
+#define MPU_P5 (0x5)
+#define MPU_P6 (0x6)
+#define MPU_P8 (0x8)
+#define MPU_P9 (0x9)
+#define MPU_P10 (0xa)
+#define MPU_P11 (0xb)
+#define MPU_P16 (0x10)
+#define MPU_P17 (0x12)
+#define MPU_P18 (0x12)
+#define MPU_P19 (0x13)
+#define MPU_P20 (0x14)
+#define MPU_P21 (0x15)
+#define MPU_P22 (0x16)
+#define MPU_P23 (0x17)
+#define MPU_P24 (0x18)
+#define MPU_P25 (0x19)
+#define MPU_P26 (0x1a)
+#define MPU_P27 (0x1b)
+#define MPU_P28 (0x1c)
+#define MPU_P29 (0x1d)
+#define MPU_P30 (0x1e)
+#define MPU_P31 (0x1f)
+#define MPU_P1 (0x1)
+#define MPU_REGA (0x1)
+
+
+
+/* ************************************************************************* */
+/*                              ADDRESS MACROS                               */
+/* ************************************************************************* */
+#define MK_DWORD_ADDR(ADDR) (ADDR >> 2)
+#define MK_BYTE_ADDR(ADDR) (ADDR)
+
+
+
+/* ************************************************************************* */
+/*                            INSTRUCTION MACROS                             */
+/* ************************************************************************* */
+#define MPU_ADD_RRR(S,N,D) (0x4000008C | ((S & ((1 << 5) - 1)) << 16)\
+                                | ((N & ((1 << 5) - 1)) << 11)\
+                                | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_ADD_RRS(S,N,D) (0x4000048C | ((S & ((1 << 5) - 1)) << 16)\
+                                | ((N & ((1 << 5) - 1)) << 11)\
+                                | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_ADD_RSR(S,N,D) (0x4000018C | ((S & ((1 << 5) - 1)) << 16)\
+                                | ((N & ((1 << 5) - 1)) << 11)\
+                                | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_ADD_RSS(S,N,D) (0x4000058C | ((S & ((1 << 5) - 1)) << 16)\
+                                | ((N & ((1 << 5) - 1)) << 11)\
+                                | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_ADD_SRR(S,N,D) (0x4000028C | ((S & ((1 << 5) - 1)) << 16)\
+                                | ((N & ((1 << 5) - 1)) << 11)\
+                                | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_ADD_SRS(S,N,D) (0x4000068C | ((S & ((1 << 5) - 1)) << 16)\
+                                | ((N & ((1 << 5) - 1)) << 11)\
+                                | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_ADD_SSR(S,N,D) (0x4000038C | ((S & ((1 << 5) - 1)) << 16)\
+                                | ((N & ((1 << 5) - 1)) << 11)\
+                                | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_ADD_SSS(S,N,D) (0x4000078C | ((S & ((1 << 5) - 1)) << 16)\
+                                | ((N & ((1 << 5) - 1)) << 11)\
+                                | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_ADDQ_RIR(S,N,D) (0x10000000 | ((S & ((1 << 5) - 1)) << 16)\
+                                 | ((N & ((1 << 16) - 1)) << 0)\
+                                 | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_ADDQ_IRR(S,N,D) (0x10000000 | ((S & ((1 << 16) - 1)) << 0)\
+                                 | ((N & ((1 << 5) - 1)) << 16)\
+                                 | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_ADDX_IRR_INSTR(S,N,D) (0xC000008C | ((N & ((1 << 5) - 1)) << 16)\
+                                       | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_ADDX_IRR_IMM(S,N,D) (S & 0xFFFFFFFF)
+
+#define MPU_ADDX_RIR_INSTR(S,N,D) (0xC000008C | ((S & ((1 << 5) - 1)) << 16)\
+                                       | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_ADDX_RIR_IMM(S,N,D) (N & 0xFFFFFFFF)
+
+#define MPU_ADDX_ISR_INSTR(S,N,D) (0xC000028C | ((N & ((1 << 5) - 1)) << 16)\
+                                       | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_ADDX_ISR_IMM(S,N,D) (S & 0xFFFFFFFF)
+
+#define MPU_ADDX_SIR_INSTR(S,N,D) (0xC000028C | ((S & ((1 << 5) - 1)) << 16)\
+                                       | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_ADDX_SIR_IMM(S,N,D) (N & 0xFFFFFFFF)
+
+#define MPU_ADDX_IRS_INSTR(S,N,D) (0xC000048C | ((N & ((1 << 5) - 1)) << 16)\
+                                       | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_ADDX_IRS_IMM(S,N,D) (S & 0xFFFFFFFF)
+
+#define MPU_ADDX_RIS_INSTR(S,N,D) (0xC000048C | ((S & ((1 << 5) - 1)) << 16)\
+                                       | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_ADDX_RIS_IMM(S,N,D) (N & 0xFFFFFFFF)
+
+#define MPU_ADDX_ISS_INSTR(S,N,D) (0xC000068C | ((N & ((1 << 5) - 1)) << 16)\
+                                       | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_ADDX_ISS_IMM(S,N,D) (S & 0xFFFFFFFF)
+
+#define MPU_ADDX_SIS_INSTR(S,N,D) (0xC000068C | ((S & ((1 << 5) - 1)) << 16)\
+                                       | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_ADDX_SIS_IMM(S,N,D) (N & 0xFFFFFFFF)
+
+#define MPU_AND_RRR(S,N,D) (0x4000008A | ((S & ((1 << 5) - 1)) << 16)\
+                                | ((N & ((1 << 5) - 1)) << 11)\
+                                | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_AND_RRS(S,N,D) (0x4000048A | ((S & ((1 << 5) - 1)) << 16)\
+                                | ((N & ((1 << 5) - 1)) << 11)\
+                                | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_AND_RSR(S,N,D) (0x4000018A | ((S & ((1 << 5) - 1)) << 16)\
+                                | ((N & ((1 << 5) - 1)) << 11)\
+                                | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_AND_RSS(S,N,D) (0x4000058A | ((S & ((1 << 5) - 1)) << 16)\
+                                | ((N & ((1 << 5) - 1)) << 11)\
+                                | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_AND_SRR(S,N,D) (0x4000028A | ((S & ((1 << 5) - 1)) << 16)\
+                                | ((N & ((1 << 5) - 1)) << 11)\
+                                | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_AND_SRS(S,N,D) (0x4000068A | ((S & ((1 << 5) - 1)) << 16)\
+                                | ((N & ((1 << 5) - 1)) << 11)\
+                                | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_AND_SSR(S,N,D) (0x4000038A | ((S & ((1 << 5) - 1)) << 16)\
+                                | ((N & ((1 << 5) - 1)) << 11)\
+                                | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_AND_SSS(S,N,D) (0x4000078A | ((S & ((1 << 5) - 1)) << 16)\
+                                | ((N & ((1 << 5) - 1)) << 11)\
+                                | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_ANDQ_RIR(S,N,D) (0x08000000 | ((S & ((1 << 5) - 1)) << 16)\
+                                 | ((N & ((1 << 16) - 1)) << 0)\
+                                 | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_ANDQ_IRR(S,N,D) (0x08000000 | ((S & ((1 << 16) - 1)) << 0)\
+                                 | ((N & ((1 << 5) - 1)) << 16)\
+                                 | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_ANDX_RIR_INSTR(S,N,D) (0xC000008A | ((S & ((1 << 5) - 1)) << 16)\
+                                       | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_ANDX_RIR_IMM(S,N,D) (N & 0xFFFFFFFF)
+
+#define MPU_ANDX_IRR_INSTR(S,N,D) (0xC000008A | ((N & ((1 << 5) - 1)) << 16)\
+                                       | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_ANDX_IRR_IMM(S,N,D) (S & 0xFFFFFFFF)
+
+#define MPU_ANDX_ISR_INSTR(S,N,D) (0xC000028A | ((N & ((1 << 5) - 1)) << 16)\
+                                       | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_ANDX_ISR_IMM(S,N,D) (S & 0xFFFFFFFF)
+
+#define MPU_ANDX_SIR_INSTR(S,N,D) (0xC000028A | ((S & ((1 << 5) - 1)) << 16)\
+                                       | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_ANDX_SIR_IMM(S,N,D) (N & 0xFFFFFFFF)
+
+#define MPU_ANDX_IRS_INSTR(S,N,D) (0xC000048A | ((N & ((1 << 5) - 1)) << 16)\
+                                       | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_ANDX_IRS_IMM(S,N,D) (S & 0xFFFFFFFF)
+
+#define MPU_ANDX_ISS_INSTR(S,N,D) (0xC000068A | ((N & ((1 << 5) - 1)) << 16)\
+                                       | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_ANDX_ISS_IMM(S,N,D) (S & 0xFFFFFFFF)
+
+#define MPU_ANDX_RIS_INSTR(S,N,D) (0xC000048A | ((S & ((1 << 5) - 1)) << 16)\
+                                       | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_ANDX_RIS_IMM(S,N,D) (N & 0xFFFFFFFF)
+
+#define MPU_ANDX_SIS_INSTR(S,N,D) (0xC000068A | ((S & ((1 << 5) - 1)) << 16)\
+                                       | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_ANDX_SIS_IMM(S,N,D) (N & 0xFFFFFFFF)
+
+#define MPU_BA_I(S) (0x60000000 | ((S & ((1 << 16) - 1)) << 0))
+
+#define MPU_BAR_R(S) (0x62000000 | ((S & ((1 << 5) - 1)) << 11))
+
+#define MPU_BAR_S(S) (0x63000000 | ((S & ((1 << 5) - 1)) << 11))
+
+#define MPU_BBC_RII(S,N,D) (0x78000000 | ((S & ((1 << 5) - 1)) << 16)\
+                                | ((N & ((1 << 5) - 1)) << 21)\
+                                | ((D & ((1 << 16) - 1)) << 0))
+
+#define MPU_BBS_RII(S,N,D) (0x7C000000 | ((S & ((1 << 5) - 1)) << 16)\
+                                | ((N & ((1 << 5) - 1)) << 21)\
+                                | ((D & ((1 << 16) - 1)) << 0))
+
+#define MPU_BNZ_RI(S,D) (0x74400000 | ((S & ((1 << 5) - 1)) << 16)\
+                             | ((D & ((1 << 16) - 1)) << 0))
+
+#define MPU_BMI_RI(S,D) (0x7FE00000 | ((S & ((1 << 5) - 1)) << 16)\
+                             | ((D & ((1 << 16) - 1)) << 0))
+
+#define MPU_BPL_RI(S,D) (0x7BE00000 | ((S & ((1 << 5) - 1)) << 16)\
+                             | ((D & ((1 << 16) - 1)) << 0))
+
+#define MPU_BZ_RI(S,D) (0x74000000 | ((S & ((1 << 5) - 1)) << 16)\
+                            | ((D & ((1 << 16) - 1)) << 0))
+
+#define MPU_DI() (0x40000001)
+
+#define MPU_EI() (0x40000003)
+
+#define MPU_HALT() (0x40000002)
+
+#define MPU_JIR_I(S) (0x60200000 | ((S & ((1 << 16) - 1)) << 0))
+
+#define MPU_JIR_R(S) (0x62200000 | ((S & ((1 << 5) - 1)) << 11))
+
+#define MPU_JIR_S(S) (0x63200000 | ((S & ((1 << 5) - 1)) << 11))
+
+#define MPU_JNT() (0x61000000)
+
+#define MPU_JSR_I(S) (0x60400000 | ((S & ((1 << 16) - 1)) << 0))
+
+#define MPU_JSR_R(S) (0x62400000 | ((S & ((1 << 5) - 1)) << 11))
+
+#define MPU_JSR_S(S) (0x63400000 | ((S & ((1 << 5) - 1)) << 11))
+
+#define MPU_LSL_RRR(S,N,D) (0x4000008E | ((S & ((1 << 5) - 1)) << 16)\
+                                | ((N & ((1 << 5) - 1)) << 11)\
+                                | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_LSL_RRS(S,N,D) (0x4000048E | ((S & ((1 << 5) - 1)) << 16)\
+                                | ((N & ((1 << 5) - 1)) << 11)\
+                                | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_LSL_RSR(S,N,D) (0x4000018E | ((S & ((1 << 5) - 1)) << 16)\
+                                | ((N & ((1 << 5) - 1)) << 11)\
+                                | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_LSL_RSS(S,N,D) (0x4000058E | ((S & ((1 << 5) - 1)) << 16)\
+                                | ((N & ((1 << 5) - 1)) << 11)\
+                                | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_LSL_SRR(S,N,D) (0x4000028E | ((S & ((1 << 5) - 1)) << 16)\
+                                | ((N & ((1 << 5) - 1)) << 11)\
+                                | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_LSL_SRS(S,N,D) (0x4000068E | ((S & ((1 << 5) - 1)) << 16)\
+                                | ((N & ((1 << 5) - 1)) << 11)\
+                                | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_LSL_SSR(S,N,D) (0x4000038E | ((S & ((1 << 5) - 1)) << 16)\
+                                | ((N & ((1 << 5) - 1)) << 11)\
+                                | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_LSL_SSS(S,N,D) (0x4000078E | ((S & ((1 << 5) - 1)) << 16)\
+                                | ((N & ((1 << 5) - 1)) << 11)\
+                                | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_LSLQ_RIR(S,N,D) (0x18000000 | ((S & ((1 << 5) - 1)) << 16)\
+                                 | ((N & ((1 << 16) - 1)) << 0)\
+                                 | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_LSR_RRR(S,N,D) (0x4000008F | ((S & ((1 << 5) - 1)) << 16)\
+                                | ((N & ((1 << 5) - 1)) << 11)\
+                                | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_LSR_RRS(S,N,D) (0x4000048F | ((S & ((1 << 5) - 1)) << 16)\
+                                | ((N & ((1 << 5) - 1)) << 11)\
+                                | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_LSR_RSR(S,N,D) (0x4000018F | ((S & ((1 << 5) - 1)) << 16)\
+                                | ((N & ((1 << 5) - 1)) << 11)\
+                                | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_LSR_RSS(S,N,D) (0x4000058F | ((S & ((1 << 5) - 1)) << 16)\
+                                | ((N & ((1 << 5) - 1)) << 11)\
+                                | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_LSR_SRR(S,N,D) (0x4000028F | ((S & ((1 << 5) - 1)) << 16)\
+                                | ((N & ((1 << 5) - 1)) << 11)\
+                                | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_LSR_SRS(S,N,D) (0x4000068F | ((S & ((1 << 5) - 1)) << 16)\
+                                | ((N & ((1 << 5) - 1)) << 11)\
+                                | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_LSR_SSR(S,N,D) (0x4000038F | ((S & ((1 << 5) - 1)) << 16)\
+                                | ((N & ((1 << 5) - 1)) << 11)\
+                                | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_LSR_SSS(S,N,D) (0x4000078F | ((S & ((1 << 5) - 1)) << 16)\
+                                | ((N & ((1 << 5) - 1)) << 11)\
+                                | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_LSRQ_RIR(S,N,D) (0x1C000000 | ((S & ((1 << 5) - 1)) << 16)\
+                                 | ((N & ((1 << 16) - 1)) << 0)\
+                                 | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_LW_IR(S,D) (0x64400000 | ((S & ((1 << 16) - 1)) << 0)\
+                            | ((D & ((1 << 5) - 1)) << 16))
+
+#define MPU_LW_IS(S,D) (0x64600000 | ((S & ((1 << 16) - 1)) << 0)\
+                            | ((D & ((1 << 5) - 1)) << 16))
+
+#define MPU_LW_RR(S,D) (0x66400000 | ((S & ((1 << 5) - 1)) << 11)\
+                            | ((D & ((1 << 5) - 1)) << 16))
+
+#define MPU_LW_RS(S,D) (0x66600000 | ((S & ((1 << 5) - 1)) << 11)\
+                            | ((D & ((1 << 5) - 1)) << 16))
+
+#define MPU_LW_SR(S,D) (0x67400000 | ((S & ((1 << 5) - 1)) << 11)\
+                            | ((D & ((1 << 5) - 1)) << 16))
+
+#define MPU_LW_SS(S,D) (0x67600000 | ((S & ((1 << 5) - 1)) << 11)\
+                            | ((D & ((1 << 5) - 1)) << 16))
+
+#define MPU_LW_RIR(S,N,D) (0x66400000 | ((S & ((1 << 5) - 1)) << 11)\
+                               | ((N & ((1 << 8) - 1)) << 0)\
+                               | ((D & ((1 << 5) - 1)) << 16))
+
+#define MPU_LW_RIS(S,N,D) (0x66600000 | ((S & ((1 << 5) - 1)) << 11)\
+                               | ((N & ((1 << 8) - 1)) << 0)\
+                               | ((D & ((1 << 5) - 1)) << 16))
+
+#define MPU_LW_SIR(S,N,D) (0x67400000 | ((S & ((1 << 5) - 1)) << 11)\
+                               | ((N & ((1 << 8) - 1)) << 0)\
+                               | ((D & ((1 << 5) - 1)) << 16))
+
+#define MPU_LW_SIS(S,N,D) (0x67600000 | ((S & ((1 << 5) - 1)) << 11)\
+                               | ((N & ((1 << 8) - 1)) << 0)\
+                               | ((D & ((1 << 5) - 1)) << 16))
+
+#define MPU_MOVE_RR(S,D) (0x40000081 | ((S & ((1 << 5) - 1)) << 11)\
+                              | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_MOVE_RS(S,D) (0x40000481 | ((S & ((1 << 5) - 1)) << 11)\
+                              | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_MOVE_SR(S,D) (0x40000181 | ((S & ((1 << 5) - 1)) << 11)\
+                              | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_MOVE_SS(S,D) (0x40000581 | ((S & ((1 << 5) - 1)) << 11)\
+                              | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_MOVEQ_IR(S,D) (0x24000000 | ((S & ((1 << 16) - 1)) << 0)\
+                               | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_MOVEQ_IS(S,D) (0x2C000000 | ((S & ((1 << 16) - 1)) << 0)\
+                               | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_MOVEX_IR_INSTR(S,D) (0xC0000081 | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_MOVEX_IR_IMM(S,D) (S & 0xFFFFFFFF)
+
+#define MPU_MOVEX_IS_INSTR(S,D) (0xC0000481 | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_MOVEX_IS_IMM(S,D) (S & 0xFFFFFFFF)
+
+#define MPU_NOP() (0x40000000)
+
+#define MPU_NOT_RR(S,D) (0x40100081 | ((S & ((1 << 5) - 1)) << 11)\
+                             | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_NOT_RS(S,D) (0x40100481 | ((S & ((1 << 5) - 1)) << 11)\
+                             | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_NOT_SR(S,D) (0x40100181 | ((S & ((1 << 5) - 1)) << 11)\
+                             | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_NOT_SS(S,D) (0x40100581 | ((S & ((1 << 5) - 1)) << 11)\
+                             | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_OR_RRR(S,N,D) (0x4000008B | ((S & ((1 << 5) - 1)) << 16)\
+                               | ((N & ((1 << 5) - 1)) << 11)\
+                               | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_OR_RRS(S,N,D) (0x4000048B | ((S & ((1 << 5) - 1)) << 16)\
+                               | ((N & ((1 << 5) - 1)) << 11)\
+                               | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_OR_RSR(S,N,D) (0x4000018B | ((S & ((1 << 5) - 1)) << 16)\
+                               | ((N & ((1 << 5) - 1)) << 11)\
+                               | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_OR_RSS(S,N,D) (0x4000058B | ((S & ((1 << 5) - 1)) << 16)\
+                               | ((N & ((1 << 5) - 1)) << 11)\
+                               | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_OR_SRR(S,N,D) (0x4000028B | ((S & ((1 << 5) - 1)) << 16)\
+                               | ((N & ((1 << 5) - 1)) << 11)\
+                               | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_OR_SRS(S,N,D) (0x4000068B | ((S & ((1 << 5) - 1)) << 16)\
+                               | ((N & ((1 << 5) - 1)) << 11)\
+                               | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_OR_SSR(S,N,D) (0x4000038B | ((S & ((1 << 5) - 1)) << 16)\
+                               | ((N & ((1 << 5) - 1)) << 11)\
+                               | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_OR_SSS(S,N,D) (0x4000078B | ((S & ((1 << 5) - 1)) << 16)\
+                               | ((N & ((1 << 5) - 1)) << 11)\
+                               | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_ORQ_RIR(S,N,D) (0x0C000000 | ((S & ((1 << 5) - 1)) << 16)\
+                                | ((N & ((1 << 16) - 1)) << 0)\
+                                | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_ORQ_IRR(S,N,D) (0x0C000000 | ((S & ((1 << 16) - 1)) << 0)\
+                                | ((N & ((1 << 5) - 1)) << 16)\
+                                | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_ORX_RIR_INSTR(S,N,D) (0xC000008B | ((S & ((1 << 5) - 1)) << 16)\
+                                      | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_ORX_RIR_IMM(S,N,D) (N & 0xFFFFFFFF)
+
+#define MPU_ORX_IRR_INSTR(S,N,D) (0xC000008B | ((N & ((1 << 5) - 1)) << 16)\
+                                      | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_ORX_IRR_IMM(S,N,D) (S & 0xFFFFFFFF)
+
+#define MPU_ORX_SIR_INSTR(S,N,D) (0xC000028B | ((S & ((1 << 5) - 1)) << 16)\
+                                      | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_ORX_SIR_IMM(S,N,D) (N & 0xFFFFFFFF)
+
+#define MPU_ORX_ISR_INSTR(S,N,D) (0xC000028B | ((N & ((1 << 5) - 1)) << 16)\
+                                      | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_ORX_ISR_IMM(S,N,D) (S & 0xFFFFFFFF)
+
+#define MPU_ORX_RIS_INSTR(S,N,D) (0xC000048B | ((S & ((1 << 5) - 1)) << 16)\
+                                      | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_ORX_RIS_IMM(S,N,D) (N & 0xFFFFFFFF)
+
+#define MPU_ORX_IRS_INSTR(S,N,D) (0xC000048B | ((N & ((1 << 5) - 1)) << 16)\
+                                      | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_ORX_IRS_IMM(S,N,D) (S & 0xFFFFFFFF)
+
+#define MPU_ORX_SIS_INSTR(S,N,D) (0xC000068B | ((S & ((1 << 5) - 1)) << 16)\
+                                      | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_ORX_SIS_IMM(S,N,D) (N & 0xFFFFFFFF)
+
+#define MPU_ORX_ISS_INSTR(S,N,D) (0xC000068B | ((N & ((1 << 5) - 1)) << 16)\
+                                      | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_ORX_ISS_IMM(S,N,D) (S & 0xFFFFFFFF)
+
+#define MPU_RET() (0x63003000)
+
+#define MPU_RETI() (0x63602800)
+
+#define MPU_RR_IR(S,D) (0x50000000 | ((S & ((1 << 11) - 1)) << 0)\
+                            | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_RR_SR(S,D) (0x50008000 | ((S & ((1 << 5) - 1)) << 16)\
+                            | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_RW_RI(S,D) (0x56000000 | ((S & ((1 << 5) - 1)) << 11)\
+                            | ((D & ((1 << 11) - 1)) << 0))
+
+#define MPU_RW_RS(S,D) (0x57000000 | ((S & ((1 << 5) - 1)) << 11)\
+                            | ((D & ((1 << 5) - 1)) << 16))
+
+#define MPU_RWQ_II(S,D) (0x58000000 | ((S & ((1 << 16) - 1)) << 11)\
+                             | ((D & ((1 << 11) - 1)) << 0))
+
+#define MPU_RWQ_IS(S,D) (0x55000000 | ((S & ((1 << 16) - 1)) << 0)\
+                             | ((D & ((1 << 5) - 1)) << 16))
+
+#define MPU_RWX_II_INSTR(S,D) (0xD4000000 | ((D & ((1 << 11) - 1)) << 0))
+
+#define MPU_RWX_II_IMM(S,D) (S & 0xFFFFFFFF)
+
+#define MPU_RWX_IS_INSTR(S,D) (0xD5000000 | ((D & ((1 << 5) - 1)) << 16))
+
+#define MPU_RWX_IS_IMM(S,D) (S & 0xFFFFFFFF)
+
+#define MPU_SUB_RRR(S,N,D) (0x4000008D | ((S & ((1 << 5) - 1)) << 16)\
+                                | ((N & ((1 << 5) - 1)) << 11)\
+                                | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_SUB_RRS(S,N,D) (0x4000048D | ((S & ((1 << 5) - 1)) << 16)\
+                                | ((N & ((1 << 5) - 1)) << 11)\
+                                | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_SUB_RSR(S,N,D) (0x4000018D | ((S & ((1 << 5) - 1)) << 16)\
+                                | ((N & ((1 << 5) - 1)) << 11)\
+                                | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_SUB_RSS(S,N,D) (0x4000058D | ((S & ((1 << 5) - 1)) << 16)\
+                                | ((N & ((1 << 5) - 1)) << 11)\
+                                | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_SUB_SRR(S,N,D) (0x4000028D | ((S & ((1 << 5) - 1)) << 16)\
+                                | ((N & ((1 << 5) - 1)) << 11)\
+                                | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_SUB_SRS(S,N,D) (0x4000068D | ((S & ((1 << 5) - 1)) << 16)\
+                                | ((N & ((1 << 5) - 1)) << 11)\
+                                | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_SUB_SSR(S,N,D) (0x4000038D | ((S & ((1 << 5) - 1)) << 16)\
+                                | ((N & ((1 << 5) - 1)) << 11)\
+                                | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_SUB_SSS(S,N,D) (0x4000078D | ((S & ((1 << 5) - 1)) << 16)\
+                                | ((N & ((1 << 5) - 1)) << 11)\
+                                | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_SUBQ_RIR(S,N,D) (0x14000000 | ((S & ((1 << 5) - 1)) << 16)\
+                                 | ((N & ((1 << 16) - 1)) << 0)\
+                                 | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_SUBX_RIR_INSTR(S,N,D) (0xC000008D | ((S & ((1 << 5) - 1)) << 16)\
+                                       | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_SUBX_RIR_IMM(S,N,D) (N & 0xFFFFFFFF)
+
+#define MPU_SUBX_SIR_INSTR(S,N,D) (0xC000028D | ((S & ((1 << 5) - 1)) << 16)\
+                                       | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_SUBX_SIR_IMM(S,N,D) (N & 0xFFFFFFFF)
+
+#define MPU_SUBX_RIS_INSTR(S,N,D) (0xC000048D | ((S & ((1 << 5) - 1)) << 16)\
+                                       | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_SUBX_RIS_IMM(S,N,D) (N & 0xFFFFFFFF)
+
+#define MPU_SUBX_SIS_INSTR(S,N,D) (0xC000068D | ((S & ((1 << 5) - 1)) << 16)\
+                                       | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_SUBX_SIS_IMM(S,N,D) (N & 0xFFFFFFFF)
+
+#define MPU_SW_RI(S,D) (0x64000000 | ((S & ((1 << 5) - 1)) << 16)\
+                            | ((D & ((1 << 16) - 1)) << 0))
+
+#define MPU_SW_SI(S,D) (0x64200000 | ((S & ((1 << 5) - 1)) << 16)\
+                            | ((D & ((1 << 16) - 1)) << 0))
+
+#define MPU_SW_RR(S,D) (0x66000000 | ((S & ((1 << 5) - 1)) << 16)\
+                            | ((D & ((1 << 5) - 1)) << 11))
+
+#define MPU_SW_SR(S,D) (0x66200000 | ((S & ((1 << 5) - 1)) << 16)\
+                            | ((D & ((1 << 5) - 1)) << 11))
+
+#define MPU_SW_RS(S,D) (0x67000000 | ((S & ((1 << 5) - 1)) << 16)\
+                            | ((D & ((1 << 5) - 1)) << 11))
+
+#define MPU_SW_SS(S,D) (0x67200000 | ((S & ((1 << 5) - 1)) << 16)\
+                            | ((D & ((1 << 5) - 1)) << 11))
+
+#define MPU_SW_RIR(S,N,D) (0x66000000 | ((S & ((1 << 5) - 1)) << 16)\
+                               | ((N & ((1 << 8) - 1)) << 0)\
+                               | ((D & ((1 << 5) - 1)) << 11))
+
+#define MPU_SW_SIR(S,N,D) (0x66200000 | ((S & ((1 << 5) - 1)) << 16)\
+                               | ((N & ((1 << 8) - 1)) << 0)\
+                               | ((D & ((1 << 5) - 1)) << 11))
+
+#define MPU_SW_RIS(S,N,D) (0x67000000 | ((S & ((1 << 5) - 1)) << 16)\
+                               | ((N & ((1 << 8) - 1)) << 0)\
+                               | ((D & ((1 << 5) - 1)) << 11))
+
+#define MPU_SW_SIS(S,N,D) (0x67200000 | ((S & ((1 << 5) - 1)) << 16)\
+                               | ((N & ((1 << 8) - 1)) << 0)\
+                               | ((D & ((1 << 5) - 1)) << 11))
+
+#define MPU_SWX_II_INSTR(S,D) (0xE4000000 | ((D & ((1 << 16) - 1)) << 0))
+
+#define MPU_SWX_II_IMM(S,D) (S & 0xFFFFFFFF)
+
+#define MPU_SWX_IR_INSTR(S,D) (0xE6000000 | ((D & ((1 << 5) - 1)) << 11))
+
+#define MPU_SWX_IR_IMM(S,D) (S & 0xFFFFFFFF)
+
+#define MPU_SWX_IS_INSTR(S,D) (0xE7000000 | ((D & ((1 << 5) - 1)) << 11))
+
+#define MPU_SWX_IS_IMM(S,D) (S & 0xFFFFFFFF)
+
+#define MPU_SWX_IIR_INSTR(S,N,D) (0xE6000000 | ((N & ((1 << 8) - 1)) << 0)\
+                                      | ((D & ((1 << 5) - 1)) << 11))
+
+#define MPU_SWX_IIR_IMM(S,N,D) (S & 0xFFFFFFFF)
+
+#define MPU_SWX_IIS_INSTR(S,N,D) (0xE7000000 | ((N & ((1 << 8) - 1)) << 0)\
+                                      | ((D & ((1 << 5) - 1)) << 11))
+
+#define MPU_SWX_IIS_IMM(S,N,D) (S & 0xFFFFFFFF)
+
+#define MPU_XOR_RRR(S,N,D) (0x40000089 | ((S & ((1 << 5) - 1)) << 16)\
+                                | ((N & ((1 << 5) - 1)) << 11)\
+                                | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_XOR_RRS(S,N,D) (0x40000489 | ((S & ((1 << 5) - 1)) << 16)\
+                                | ((N & ((1 << 5) - 1)) << 11)\
+                                | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_XOR_RSR(S,N,D) (0x40000189 | ((S & ((1 << 5) - 1)) << 16)\
+                                | ((N & ((1 << 5) - 1)) << 11)\
+                                | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_XOR_RSS(S,N,D) (0x40000589 | ((S & ((1 << 5) - 1)) << 16)\
+                                | ((N & ((1 << 5) - 1)) << 11)\
+                                | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_XOR_SRR(S,N,D) (0x40000289 | ((S & ((1 << 5) - 1)) << 16)\
+                                | ((N & ((1 << 5) - 1)) << 11)\
+                                | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_XOR_SRS(S,N,D) (0x40000689 | ((S & ((1 << 5) - 1)) << 16)\
+                                | ((N & ((1 << 5) - 1)) << 11)\
+                                | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_XOR_SSR(S,N,D) (0x40000389 | ((S & ((1 << 5) - 1)) << 16)\
+                                | ((N & ((1 << 5) - 1)) << 11)\
+                                | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_XOR_SSS(S,N,D) (0x40000789 | ((S & ((1 << 5) - 1)) << 16)\
+                                | ((N & ((1 << 5) - 1)) << 11)\
+                                | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_XOR_RR(S,D) (0x40000088 | ((S & ((1 << 5) - 1)) << 11)\
+                             | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_XOR_RS(S,D) (0x40000488 | ((S & ((1 << 5) - 1)) << 11)\
+                             | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_XOR_SR(S,D) (0x40000188 | ((S & ((1 << 5) - 1)) << 11)\
+                             | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_XOR_SS(S,D) (0x40000588 | ((S & ((1 << 5) - 1)) << 11)\
+                             | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_XORQ_RIR(S,N,D) (0x04000000 | ((S & ((1 << 5) - 1)) << 16)\
+                                 | ((N & ((1 << 16) - 1)) << 0)\
+                                 | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_XORQ_IRR(S,N,D) (0x04000000 | ((S & ((1 << 16) - 1)) << 0)\
+                                 | ((N & ((1 << 5) - 1)) << 16)\
+                                 | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_XORX_RIR_INSTR(S,N,D) (0xC0000089 | ((S & ((1 << 5) - 1)) << 16)\
+                                       | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_XORX_RIR_IMM(S,N,D) (N & 0xFFFFFFFF)
+
+#define MPU_XORX_IRR_INSTR(S,N,D) (0xC0000089 | ((N & ((1 << 5) - 1)) << 16)\
+                                       | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_XORX_IRR_IMM(S,N,D) (S & 0xFFFFFFFF)
+
+#define MPU_XORX_SIR_INSTR(S,N,D) (0xC0000289 | ((S & ((1 << 5) - 1)) << 16)\
+                                       | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_XORX_SIR_IMM(S,N,D) (N & 0xFFFFFFFF)
+
+#define MPU_XORX_ISR_INSTR(S,N,D) (0xC0000289 | ((N & ((1 << 5) - 1)) << 16)\
+                                       | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_XORX_ISR_IMM(S,N,D) (S & 0xFFFFFFFF)
+
+#define MPU_XORX_RIS_INSTR(S,N,D) (0xC0000489 | ((S & ((1 << 5) - 1)) << 16)\
+                                       | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_XORX_RIS_IMM(S,N,D) (N & 0xFFFFFFFF)
+
+#define MPU_XORX_IRS_INSTR(S,N,D) (0xC0000489 | ((N & ((1 << 5) - 1)) << 16)\
+                                       | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_XORX_IRS_IMM(S,N,D) (S & 0xFFFFFFFF)
+
+#define MPU_XORX_SIS_INSTR(S,N,D) (0xC0000689 | ((S & ((1 << 5) - 1)) << 16)\
+                                       | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_XORX_SIS_IMM(S,N,D) (N & 0xFFFFFFFF)
+
+#define MPU_XORX_ISS_INSTR(S,N,D) (0xC0000689 | ((N & ((1 << 5) - 1)) << 16)\
+                                       | ((D & ((1 << 5) - 1)) << 21))
+
+#define MPU_XORX_ISS_IMM(S,N,D) (S & 0xFFFFFFFF)
+
+
+#endif /* end of __IOP_MPU_MACROS_H__ */
+/* End of iop_mpu_macros.h */
diff --git a/include/asm-cris/arch-v32/hwregs/iop/iop_reg_space.h b/include/asm-cris/arch-v32/hwregs/iop/iop_reg_space.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/iop/iop_reg_space.h
@@ -0,0 +1,44 @@
+/* Autogenerated Changes here will be lost!
+ * generated by ../gen_sw.pl Mon Apr 11 16:10:18 2005 iop_sw.cfg
+ */
+#define regi_iop_version (regi_iop + 0)
+#define regi_iop_fifo_in0_extra (regi_iop + 64)
+#define regi_iop_fifo_in1_extra (regi_iop + 128)
+#define regi_iop_fifo_out0_extra (regi_iop + 192)
+#define regi_iop_fifo_out1_extra (regi_iop + 256)
+#define regi_iop_trigger_grp0 (regi_iop + 320)
+#define regi_iop_trigger_grp1 (regi_iop + 384)
+#define regi_iop_trigger_grp2 (regi_iop + 448)
+#define regi_iop_trigger_grp3 (regi_iop + 512)
+#define regi_iop_trigger_grp4 (regi_iop + 576)
+#define regi_iop_trigger_grp5 (regi_iop + 640)
+#define regi_iop_trigger_grp6 (regi_iop + 704)
+#define regi_iop_trigger_grp7 (regi_iop + 768)
+#define regi_iop_crc_par0 (regi_iop + 896)
+#define regi_iop_crc_par1 (regi_iop + 1024)
+#define regi_iop_dmc_in0 (regi_iop + 1152)
+#define regi_iop_dmc_in1 (regi_iop + 1280)
+#define regi_iop_dmc_out0 (regi_iop + 1408)
+#define regi_iop_dmc_out1 (regi_iop + 1536)
+#define regi_iop_fifo_in0 (regi_iop + 1664)
+#define regi_iop_fifo_in1 (regi_iop + 1792)
+#define regi_iop_fifo_out0 (regi_iop + 1920)
+#define regi_iop_fifo_out1 (regi_iop + 2048)
+#define regi_iop_scrc_in0 (regi_iop + 2176)
+#define regi_iop_scrc_in1 (regi_iop + 2304)
+#define regi_iop_scrc_out0 (regi_iop + 2432)
+#define regi_iop_scrc_out1 (regi_iop + 2560)
+#define regi_iop_timer_grp0 (regi_iop + 2688)
+#define regi_iop_timer_grp1 (regi_iop + 2816)
+#define regi_iop_timer_grp2 (regi_iop + 2944)
+#define regi_iop_timer_grp3 (regi_iop + 3072)
+#define regi_iop_sap_in (regi_iop + 3328)
+#define regi_iop_sap_out (regi_iop + 3584)
+#define regi_iop_spu0 (regi_iop + 3840)
+#define regi_iop_spu1 (regi_iop + 4096)
+#define regi_iop_sw_cfg (regi_iop + 4352)
+#define regi_iop_sw_cpu (regi_iop + 4608)
+#define regi_iop_sw_mpu (regi_iop + 4864)
+#define regi_iop_sw_spu0 (regi_iop + 5120)
+#define regi_iop_sw_spu1 (regi_iop + 5376)
+#define regi_iop_mpu (regi_iop + 5632)
diff --git a/include/asm-cris/arch-v32/hwregs/iop/iop_sap_in_defs.h b/include/asm-cris/arch-v32/hwregs/iop/iop_sap_in_defs.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/iop/iop_sap_in_defs.h
@@ -0,0 +1,179 @@
+#ifndef __iop_sap_in_defs_h
+#define __iop_sap_in_defs_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/io_proc/rtl/iop_sap_in.r
+ *     id:           <not found>
+ *     last modfied: Mon Apr 11 16:08:45 2005
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c --outfile iop_sap_in_defs.h ../../inst/io_proc/rtl/iop_sap_in.r
+ *      id: $Id: iop_sap_in_defs.h,v 1.5 2005/04/24 18:31:05 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+/* Main access macros */
+#ifndef REG_RD
+#define REG_RD( scope, inst, reg ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR
+#define REG_WR( scope, inst, reg, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_VECT
+#define REG_RD_VECT( scope, inst, reg, index ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_VECT
+#define REG_WR_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT
+#define REG_RD_INT( scope, inst, reg ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT
+#define REG_WR_INT( scope, inst, reg, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT_VECT
+#define REG_RD_INT_VECT( scope, inst, reg, index ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT_VECT
+#define REG_WR_INT_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_TYPE_CONV
+#define REG_TYPE_CONV( type, orgtype, val ) \
+  ( { union { orgtype o; type n; } r; r.o = val; r.n; } )
+#endif
+
+#ifndef reg_page_size
+#define reg_page_size 8192
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg + \
+    (index) * STRIDE_##scope##_##reg )
+#endif
+
+/* C-code for register scope iop_sap_in */
+
+/* Register rw_bus0_sync, scope iop_sap_in, type rw */
+typedef struct {
+  unsigned int byte0_sel     : 2;
+  unsigned int byte0_ext_src : 3;
+  unsigned int byte0_edge    : 2;
+  unsigned int byte0_delay   : 1;
+  unsigned int byte1_sel     : 2;
+  unsigned int byte1_ext_src : 3;
+  unsigned int byte1_edge    : 2;
+  unsigned int byte1_delay   : 1;
+  unsigned int byte2_sel     : 2;
+  unsigned int byte2_ext_src : 3;
+  unsigned int byte2_edge    : 2;
+  unsigned int byte2_delay   : 1;
+  unsigned int byte3_sel     : 2;
+  unsigned int byte3_ext_src : 3;
+  unsigned int byte3_edge    : 2;
+  unsigned int byte3_delay   : 1;
+} reg_iop_sap_in_rw_bus0_sync;
+#define REG_RD_ADDR_iop_sap_in_rw_bus0_sync 0
+#define REG_WR_ADDR_iop_sap_in_rw_bus0_sync 0
+
+/* Register rw_bus1_sync, scope iop_sap_in, type rw */
+typedef struct {
+  unsigned int byte0_sel     : 2;
+  unsigned int byte0_ext_src : 3;
+  unsigned int byte0_edge    : 2;
+  unsigned int byte0_delay   : 1;
+  unsigned int byte1_sel     : 2;
+  unsigned int byte1_ext_src : 3;
+  unsigned int byte1_edge    : 2;
+  unsigned int byte1_delay   : 1;
+  unsigned int byte2_sel     : 2;
+  unsigned int byte2_ext_src : 3;
+  unsigned int byte2_edge    : 2;
+  unsigned int byte2_delay   : 1;
+  unsigned int byte3_sel     : 2;
+  unsigned int byte3_ext_src : 3;
+  unsigned int byte3_edge    : 2;
+  unsigned int byte3_delay   : 1;
+} reg_iop_sap_in_rw_bus1_sync;
+#define REG_RD_ADDR_iop_sap_in_rw_bus1_sync 4
+#define REG_WR_ADDR_iop_sap_in_rw_bus1_sync 4
+
+#define STRIDE_iop_sap_in_rw_gio 4
+/* Register rw_gio, scope iop_sap_in, type rw */
+typedef struct {
+  unsigned int sync_sel     : 2;
+  unsigned int sync_ext_src : 3;
+  unsigned int sync_edge    : 2;
+  unsigned int delay        : 1;
+  unsigned int logic        : 2;
+  unsigned int dummy1       : 22;
+} reg_iop_sap_in_rw_gio;
+#define REG_RD_ADDR_iop_sap_in_rw_gio 8
+#define REG_WR_ADDR_iop_sap_in_rw_gio 8
+
+
+/* Constants */
+enum {
+  regk_iop_sap_in_and                      = 0x00000002,
+  regk_iop_sap_in_ext_clk200               = 0x00000003,
+  regk_iop_sap_in_gio1                     = 0x00000000,
+  regk_iop_sap_in_gio13                    = 0x00000005,
+  regk_iop_sap_in_gio18                    = 0x00000003,
+  regk_iop_sap_in_gio19                    = 0x00000004,
+  regk_iop_sap_in_gio21                    = 0x00000006,
+  regk_iop_sap_in_gio23                    = 0x00000005,
+  regk_iop_sap_in_gio29                    = 0x00000007,
+  regk_iop_sap_in_gio5                     = 0x00000004,
+  regk_iop_sap_in_gio6                     = 0x00000001,
+  regk_iop_sap_in_gio7                     = 0x00000002,
+  regk_iop_sap_in_inv                      = 0x00000001,
+  regk_iop_sap_in_neg                      = 0x00000002,
+  regk_iop_sap_in_no                       = 0x00000000,
+  regk_iop_sap_in_no_del_ext_clk200        = 0x00000001,
+  regk_iop_sap_in_none                     = 0x00000000,
+  regk_iop_sap_in_or                       = 0x00000003,
+  regk_iop_sap_in_pos                      = 0x00000001,
+  regk_iop_sap_in_pos_neg                  = 0x00000003,
+  regk_iop_sap_in_rw_bus0_sync_default     = 0x02020202,
+  regk_iop_sap_in_rw_bus1_sync_default     = 0x02020202,
+  regk_iop_sap_in_rw_gio_default           = 0x00000002,
+  regk_iop_sap_in_rw_gio_size              = 0x00000020,
+  regk_iop_sap_in_timer_grp0_tmr3          = 0x00000006,
+  regk_iop_sap_in_timer_grp1_tmr3          = 0x00000004,
+  regk_iop_sap_in_timer_grp2_tmr3          = 0x00000005,
+  regk_iop_sap_in_timer_grp3_tmr3          = 0x00000007,
+  regk_iop_sap_in_tmr_clk200               = 0x00000000,
+  regk_iop_sap_in_two_clk200               = 0x00000002,
+  regk_iop_sap_in_yes                      = 0x00000001
+};
+#endif /* __iop_sap_in_defs_h */
diff --git a/include/asm-cris/arch-v32/hwregs/iop/iop_sap_out_defs.h b/include/asm-cris/arch-v32/hwregs/iop/iop_sap_out_defs.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/iop/iop_sap_out_defs.h
@@ -0,0 +1,306 @@
+#ifndef __iop_sap_out_defs_h
+#define __iop_sap_out_defs_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/io_proc/rtl/iop_sap_out.r
+ *     id:           <not found>
+ *     last modfied: Mon Apr 11 16:08:46 2005
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c --outfile iop_sap_out_defs.h ../../inst/io_proc/rtl/iop_sap_out.r
+ *      id: $Id: iop_sap_out_defs.h,v 1.5 2005/04/24 18:31:05 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+/* Main access macros */
+#ifndef REG_RD
+#define REG_RD( scope, inst, reg ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR
+#define REG_WR( scope, inst, reg, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_VECT
+#define REG_RD_VECT( scope, inst, reg, index ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_VECT
+#define REG_WR_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT
+#define REG_RD_INT( scope, inst, reg ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT
+#define REG_WR_INT( scope, inst, reg, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT_VECT
+#define REG_RD_INT_VECT( scope, inst, reg, index ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT_VECT
+#define REG_WR_INT_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_TYPE_CONV
+#define REG_TYPE_CONV( type, orgtype, val ) \
+  ( { union { orgtype o; type n; } r; r.o = val; r.n; } )
+#endif
+
+#ifndef reg_page_size
+#define reg_page_size 8192
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg + \
+    (index) * STRIDE_##scope##_##reg )
+#endif
+
+/* C-code for register scope iop_sap_out */
+
+/* Register rw_gen_gated, scope iop_sap_out, type rw */
+typedef struct {
+  unsigned int clk0_src       : 2;
+  unsigned int clk0_gate_src  : 2;
+  unsigned int clk0_force_src : 3;
+  unsigned int clk1_src       : 2;
+  unsigned int clk1_gate_src  : 2;
+  unsigned int clk1_force_src : 3;
+  unsigned int clk2_src       : 2;
+  unsigned int clk2_gate_src  : 2;
+  unsigned int clk2_force_src : 3;
+  unsigned int clk3_src       : 2;
+  unsigned int clk3_gate_src  : 2;
+  unsigned int clk3_force_src : 3;
+  unsigned int dummy1         : 4;
+} reg_iop_sap_out_rw_gen_gated;
+#define REG_RD_ADDR_iop_sap_out_rw_gen_gated 0
+#define REG_WR_ADDR_iop_sap_out_rw_gen_gated 0
+
+/* Register rw_bus0, scope iop_sap_out, type rw */
+typedef struct {
+  unsigned int byte0_clk_sel   : 3;
+  unsigned int byte0_gated_clk : 2;
+  unsigned int byte0_clk_inv   : 1;
+  unsigned int byte1_clk_sel   : 3;
+  unsigned int byte1_gated_clk : 2;
+  unsigned int byte1_clk_inv   : 1;
+  unsigned int byte2_clk_sel   : 3;
+  unsigned int byte2_gated_clk : 2;
+  unsigned int byte2_clk_inv   : 1;
+  unsigned int byte3_clk_sel   : 3;
+  unsigned int byte3_gated_clk : 2;
+  unsigned int byte3_clk_inv   : 1;
+  unsigned int dummy1          : 8;
+} reg_iop_sap_out_rw_bus0;
+#define REG_RD_ADDR_iop_sap_out_rw_bus0 4
+#define REG_WR_ADDR_iop_sap_out_rw_bus0 4
+
+/* Register rw_bus1, scope iop_sap_out, type rw */
+typedef struct {
+  unsigned int byte0_clk_sel   : 3;
+  unsigned int byte0_gated_clk : 2;
+  unsigned int byte0_clk_inv   : 1;
+  unsigned int byte1_clk_sel   : 3;
+  unsigned int byte1_gated_clk : 2;
+  unsigned int byte1_clk_inv   : 1;
+  unsigned int byte2_clk_sel   : 3;
+  unsigned int byte2_gated_clk : 2;
+  unsigned int byte2_clk_inv   : 1;
+  unsigned int byte3_clk_sel   : 3;
+  unsigned int byte3_gated_clk : 2;
+  unsigned int byte3_clk_inv   : 1;
+  unsigned int dummy1          : 8;
+} reg_iop_sap_out_rw_bus1;
+#define REG_RD_ADDR_iop_sap_out_rw_bus1 8
+#define REG_WR_ADDR_iop_sap_out_rw_bus1 8
+
+/* Register rw_bus0_lo_oe, scope iop_sap_out, type rw */
+typedef struct {
+  unsigned int byte0_clk_sel   : 3;
+  unsigned int byte0_clk_ext   : 3;
+  unsigned int byte0_gated_clk : 2;
+  unsigned int byte0_clk_inv   : 1;
+  unsigned int byte0_logic     : 2;
+  unsigned int byte1_clk_sel   : 3;
+  unsigned int byte1_clk_ext   : 3;
+  unsigned int byte1_gated_clk : 2;
+  unsigned int byte1_clk_inv   : 1;
+  unsigned int byte1_logic     : 2;
+  unsigned int dummy1          : 10;
+} reg_iop_sap_out_rw_bus0_lo_oe;
+#define REG_RD_ADDR_iop_sap_out_rw_bus0_lo_oe 12
+#define REG_WR_ADDR_iop_sap_out_rw_bus0_lo_oe 12
+
+/* Register rw_bus0_hi_oe, scope iop_sap_out, type rw */
+typedef struct {
+  unsigned int byte2_clk_sel   : 3;
+  unsigned int byte2_clk_ext   : 3;
+  unsigned int byte2_gated_clk : 2;
+  unsigned int byte2_clk_inv   : 1;
+  unsigned int byte2_logic     : 2;
+  unsigned int byte3_clk_sel   : 3;
+  unsigned int byte3_clk_ext   : 3;
+  unsigned int byte3_gated_clk : 2;
+  unsigned int byte3_clk_inv   : 1;
+  unsigned int byte3_logic     : 2;
+  unsigned int dummy1          : 10;
+} reg_iop_sap_out_rw_bus0_hi_oe;
+#define REG_RD_ADDR_iop_sap_out_rw_bus0_hi_oe 16
+#define REG_WR_ADDR_iop_sap_out_rw_bus0_hi_oe 16
+
+/* Register rw_bus1_lo_oe, scope iop_sap_out, type rw */
+typedef struct {
+  unsigned int byte0_clk_sel   : 3;
+  unsigned int byte0_clk_ext   : 3;
+  unsigned int byte0_gated_clk : 2;
+  unsigned int byte0_clk_inv   : 1;
+  unsigned int byte0_logic     : 2;
+  unsigned int byte1_clk_sel   : 3;
+  unsigned int byte1_clk_ext   : 3;
+  unsigned int byte1_gated_clk : 2;
+  unsigned int byte1_clk_inv   : 1;
+  unsigned int byte1_logic     : 2;
+  unsigned int dummy1          : 10;
+} reg_iop_sap_out_rw_bus1_lo_oe;
+#define REG_RD_ADDR_iop_sap_out_rw_bus1_lo_oe 20
+#define REG_WR_ADDR_iop_sap_out_rw_bus1_lo_oe 20
+
+/* Register rw_bus1_hi_oe, scope iop_sap_out, type rw */
+typedef struct {
+  unsigned int byte2_clk_sel   : 3;
+  unsigned int byte2_clk_ext   : 3;
+  unsigned int byte2_gated_clk : 2;
+  unsigned int byte2_clk_inv   : 1;
+  unsigned int byte2_logic     : 2;
+  unsigned int byte3_clk_sel   : 3;
+  unsigned int byte3_clk_ext   : 3;
+  unsigned int byte3_gated_clk : 2;
+  unsigned int byte3_clk_inv   : 1;
+  unsigned int byte3_logic     : 2;
+  unsigned int dummy1          : 10;
+} reg_iop_sap_out_rw_bus1_hi_oe;
+#define REG_RD_ADDR_iop_sap_out_rw_bus1_hi_oe 24
+#define REG_WR_ADDR_iop_sap_out_rw_bus1_hi_oe 24
+
+#define STRIDE_iop_sap_out_rw_gio 4
+/* Register rw_gio, scope iop_sap_out, type rw */
+typedef struct {
+  unsigned int out_clk_sel   : 3;
+  unsigned int out_clk_ext   : 4;
+  unsigned int out_gated_clk : 2;
+  unsigned int out_clk_inv   : 1;
+  unsigned int out_logic     : 1;
+  unsigned int oe_clk_sel    : 3;
+  unsigned int oe_clk_ext    : 3;
+  unsigned int oe_gated_clk  : 2;
+  unsigned int oe_clk_inv    : 1;
+  unsigned int oe_logic      : 2;
+  unsigned int dummy1        : 10;
+} reg_iop_sap_out_rw_gio;
+#define REG_RD_ADDR_iop_sap_out_rw_gio 28
+#define REG_WR_ADDR_iop_sap_out_rw_gio 28
+
+
+/* Constants */
+enum {
+  regk_iop_sap_out_and                     = 0x00000002,
+  regk_iop_sap_out_clk0                    = 0x00000000,
+  regk_iop_sap_out_clk1                    = 0x00000001,
+  regk_iop_sap_out_clk12                   = 0x00000002,
+  regk_iop_sap_out_clk2                    = 0x00000002,
+  regk_iop_sap_out_clk200                  = 0x00000001,
+  regk_iop_sap_out_clk3                    = 0x00000003,
+  regk_iop_sap_out_ext                     = 0x00000003,
+  regk_iop_sap_out_gated                   = 0x00000004,
+  regk_iop_sap_out_gio1                    = 0x00000000,
+  regk_iop_sap_out_gio13                   = 0x00000002,
+  regk_iop_sap_out_gio13_clk               = 0x0000000c,
+  regk_iop_sap_out_gio15                   = 0x00000001,
+  regk_iop_sap_out_gio18                   = 0x00000003,
+  regk_iop_sap_out_gio18_clk               = 0x0000000d,
+  regk_iop_sap_out_gio1_clk                = 0x00000008,
+  regk_iop_sap_out_gio21_clk               = 0x0000000e,
+  regk_iop_sap_out_gio23                   = 0x00000002,
+  regk_iop_sap_out_gio29_clk               = 0x0000000f,
+  regk_iop_sap_out_gio31                   = 0x00000003,
+  regk_iop_sap_out_gio5                    = 0x00000001,
+  regk_iop_sap_out_gio5_clk                = 0x00000009,
+  regk_iop_sap_out_gio6_clk                = 0x0000000a,
+  regk_iop_sap_out_gio7                    = 0x00000000,
+  regk_iop_sap_out_gio7_clk                = 0x0000000b,
+  regk_iop_sap_out_gio_in13                = 0x00000001,
+  regk_iop_sap_out_gio_in21                = 0x00000002,
+  regk_iop_sap_out_gio_in29                = 0x00000003,
+  regk_iop_sap_out_gio_in5                 = 0x00000000,
+  regk_iop_sap_out_inv                     = 0x00000001,
+  regk_iop_sap_out_nand                    = 0x00000003,
+  regk_iop_sap_out_no                      = 0x00000000,
+  regk_iop_sap_out_none                    = 0x00000000,
+  regk_iop_sap_out_rw_bus0_default         = 0x00000000,
+  regk_iop_sap_out_rw_bus0_hi_oe_default   = 0x00000000,
+  regk_iop_sap_out_rw_bus0_lo_oe_default   = 0x00000000,
+  regk_iop_sap_out_rw_bus1_default         = 0x00000000,
+  regk_iop_sap_out_rw_bus1_hi_oe_default   = 0x00000000,
+  regk_iop_sap_out_rw_bus1_lo_oe_default   = 0x00000000,
+  regk_iop_sap_out_rw_gen_gated_default    = 0x00000000,
+  regk_iop_sap_out_rw_gio_default          = 0x00000000,
+  regk_iop_sap_out_rw_gio_size             = 0x00000020,
+  regk_iop_sap_out_spu0_gio0               = 0x00000002,
+  regk_iop_sap_out_spu0_gio1               = 0x00000003,
+  regk_iop_sap_out_spu0_gio12              = 0x00000004,
+  regk_iop_sap_out_spu0_gio13              = 0x00000004,
+  regk_iop_sap_out_spu0_gio14              = 0x00000004,
+  regk_iop_sap_out_spu0_gio15              = 0x00000004,
+  regk_iop_sap_out_spu0_gio2               = 0x00000002,
+  regk_iop_sap_out_spu0_gio3               = 0x00000003,
+  regk_iop_sap_out_spu0_gio4               = 0x00000002,
+  regk_iop_sap_out_spu0_gio5               = 0x00000003,
+  regk_iop_sap_out_spu0_gio6               = 0x00000002,
+  regk_iop_sap_out_spu0_gio7               = 0x00000003,
+  regk_iop_sap_out_spu1_gio0               = 0x00000005,
+  regk_iop_sap_out_spu1_gio1               = 0x00000006,
+  regk_iop_sap_out_spu1_gio12              = 0x00000007,
+  regk_iop_sap_out_spu1_gio13              = 0x00000007,
+  regk_iop_sap_out_spu1_gio14              = 0x00000007,
+  regk_iop_sap_out_spu1_gio15              = 0x00000007,
+  regk_iop_sap_out_spu1_gio2               = 0x00000005,
+  regk_iop_sap_out_spu1_gio3               = 0x00000006,
+  regk_iop_sap_out_spu1_gio4               = 0x00000005,
+  regk_iop_sap_out_spu1_gio5               = 0x00000006,
+  regk_iop_sap_out_spu1_gio6               = 0x00000005,
+  regk_iop_sap_out_spu1_gio7               = 0x00000006,
+  regk_iop_sap_out_timer_grp0_tmr2         = 0x00000004,
+  regk_iop_sap_out_timer_grp1_tmr2         = 0x00000005,
+  regk_iop_sap_out_timer_grp2_tmr2         = 0x00000006,
+  regk_iop_sap_out_timer_grp3_tmr2         = 0x00000007,
+  regk_iop_sap_out_tmr                     = 0x00000005,
+  regk_iop_sap_out_yes                     = 0x00000001
+};
+#endif /* __iop_sap_out_defs_h */
diff --git a/include/asm-cris/arch-v32/hwregs/iop/iop_scrc_in_defs.h b/include/asm-cris/arch-v32/hwregs/iop/iop_scrc_in_defs.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/iop/iop_scrc_in_defs.h
@@ -0,0 +1,160 @@
+#ifndef __iop_scrc_in_defs_h
+#define __iop_scrc_in_defs_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/io_proc/rtl/iop_scrc_in.r
+ *     id:           iop_scrc_in.r,v 1.10 2005/02/16 09:13:58 niklaspa Exp
+ *     last modfied: Mon Apr 11 16:08:46 2005
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c --outfile iop_scrc_in_defs.h ../../inst/io_proc/rtl/iop_scrc_in.r
+ *      id: $Id: iop_scrc_in_defs.h,v 1.4 2005/04/24 18:31:05 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+/* Main access macros */
+#ifndef REG_RD
+#define REG_RD( scope, inst, reg ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR
+#define REG_WR( scope, inst, reg, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_VECT
+#define REG_RD_VECT( scope, inst, reg, index ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_VECT
+#define REG_WR_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT
+#define REG_RD_INT( scope, inst, reg ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT
+#define REG_WR_INT( scope, inst, reg, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT_VECT
+#define REG_RD_INT_VECT( scope, inst, reg, index ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT_VECT
+#define REG_WR_INT_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_TYPE_CONV
+#define REG_TYPE_CONV( type, orgtype, val ) \
+  ( { union { orgtype o; type n; } r; r.o = val; r.n; } )
+#endif
+
+#ifndef reg_page_size
+#define reg_page_size 8192
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg + \
+    (index) * STRIDE_##scope##_##reg )
+#endif
+
+/* C-code for register scope iop_scrc_in */
+
+/* Register rw_cfg, scope iop_scrc_in, type rw */
+typedef struct {
+  unsigned int trig : 2;
+  unsigned int dummy1 : 30;
+} reg_iop_scrc_in_rw_cfg;
+#define REG_RD_ADDR_iop_scrc_in_rw_cfg 0
+#define REG_WR_ADDR_iop_scrc_in_rw_cfg 0
+
+/* Register rw_ctrl, scope iop_scrc_in, type rw */
+typedef struct {
+  unsigned int dif_in_en : 1;
+  unsigned int dummy1    : 31;
+} reg_iop_scrc_in_rw_ctrl;
+#define REG_RD_ADDR_iop_scrc_in_rw_ctrl 4
+#define REG_WR_ADDR_iop_scrc_in_rw_ctrl 4
+
+/* Register r_stat, scope iop_scrc_in, type r */
+typedef struct {
+  unsigned int err : 1;
+  unsigned int dummy1 : 31;
+} reg_iop_scrc_in_r_stat;
+#define REG_RD_ADDR_iop_scrc_in_r_stat 8
+
+/* Register rw_init_crc, scope iop_scrc_in, type rw */
+typedef unsigned int reg_iop_scrc_in_rw_init_crc;
+#define REG_RD_ADDR_iop_scrc_in_rw_init_crc 12
+#define REG_WR_ADDR_iop_scrc_in_rw_init_crc 12
+
+/* Register rs_computed_crc, scope iop_scrc_in, type rs */
+typedef unsigned int reg_iop_scrc_in_rs_computed_crc;
+#define REG_RD_ADDR_iop_scrc_in_rs_computed_crc 16
+
+/* Register r_computed_crc, scope iop_scrc_in, type r */
+typedef unsigned int reg_iop_scrc_in_r_computed_crc;
+#define REG_RD_ADDR_iop_scrc_in_r_computed_crc 20
+
+/* Register rw_crc, scope iop_scrc_in, type rw */
+typedef unsigned int reg_iop_scrc_in_rw_crc;
+#define REG_RD_ADDR_iop_scrc_in_rw_crc 24
+#define REG_WR_ADDR_iop_scrc_in_rw_crc 24
+
+/* Register rw_correct_crc, scope iop_scrc_in, type rw */
+typedef unsigned int reg_iop_scrc_in_rw_correct_crc;
+#define REG_RD_ADDR_iop_scrc_in_rw_correct_crc 28
+#define REG_WR_ADDR_iop_scrc_in_rw_correct_crc 28
+
+/* Register rw_wr1bit, scope iop_scrc_in, type rw */
+typedef struct {
+  unsigned int data : 2;
+  unsigned int last : 2;
+  unsigned int dummy1 : 28;
+} reg_iop_scrc_in_rw_wr1bit;
+#define REG_RD_ADDR_iop_scrc_in_rw_wr1bit 32
+#define REG_WR_ADDR_iop_scrc_in_rw_wr1bit 32
+
+
+/* Constants */
+enum {
+  regk_iop_scrc_in_dif_in                  = 0x00000002,
+  regk_iop_scrc_in_hi                      = 0x00000000,
+  regk_iop_scrc_in_neg                     = 0x00000002,
+  regk_iop_scrc_in_no                      = 0x00000000,
+  regk_iop_scrc_in_pos                     = 0x00000001,
+  regk_iop_scrc_in_pos_neg                 = 0x00000003,
+  regk_iop_scrc_in_r_computed_crc_default  = 0x00000000,
+  regk_iop_scrc_in_rs_computed_crc_default = 0x00000000,
+  regk_iop_scrc_in_rw_cfg_default          = 0x00000000,
+  regk_iop_scrc_in_rw_ctrl_default         = 0x00000000,
+  regk_iop_scrc_in_rw_init_crc_default     = 0x00000000,
+  regk_iop_scrc_in_set0                    = 0x00000000,
+  regk_iop_scrc_in_set1                    = 0x00000001,
+  regk_iop_scrc_in_yes                     = 0x00000001
+};
+#endif /* __iop_scrc_in_defs_h */
diff --git a/include/asm-cris/arch-v32/hwregs/iop/iop_scrc_out_defs.h b/include/asm-cris/arch-v32/hwregs/iop/iop_scrc_out_defs.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/iop/iop_scrc_out_defs.h
@@ -0,0 +1,146 @@
+#ifndef __iop_scrc_out_defs_h
+#define __iop_scrc_out_defs_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/io_proc/rtl/iop_scrc_out.r
+ *     id:           iop_scrc_out.r,v 1.11 2005/02/16 09:13:38 niklaspa Exp
+ *     last modfied: Mon Apr 11 16:08:46 2005
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c --outfile iop_scrc_out_defs.h ../../inst/io_proc/rtl/iop_scrc_out.r
+ *      id: $Id: iop_scrc_out_defs.h,v 1.4 2005/04/24 18:31:05 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+/* Main access macros */
+#ifndef REG_RD
+#define REG_RD( scope, inst, reg ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR
+#define REG_WR( scope, inst, reg, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_VECT
+#define REG_RD_VECT( scope, inst, reg, index ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_VECT
+#define REG_WR_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT
+#define REG_RD_INT( scope, inst, reg ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT
+#define REG_WR_INT( scope, inst, reg, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT_VECT
+#define REG_RD_INT_VECT( scope, inst, reg, index ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT_VECT
+#define REG_WR_INT_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_TYPE_CONV
+#define REG_TYPE_CONV( type, orgtype, val ) \
+  ( { union { orgtype o; type n; } r; r.o = val; r.n; } )
+#endif
+
+#ifndef reg_page_size
+#define reg_page_size 8192
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg + \
+    (index) * STRIDE_##scope##_##reg )
+#endif
+
+/* C-code for register scope iop_scrc_out */
+
+/* Register rw_cfg, scope iop_scrc_out, type rw */
+typedef struct {
+  unsigned int trig    : 2;
+  unsigned int inv_crc : 1;
+  unsigned int dummy1  : 29;
+} reg_iop_scrc_out_rw_cfg;
+#define REG_RD_ADDR_iop_scrc_out_rw_cfg 0
+#define REG_WR_ADDR_iop_scrc_out_rw_cfg 0
+
+/* Register rw_ctrl, scope iop_scrc_out, type rw */
+typedef struct {
+  unsigned int strb_src : 1;
+  unsigned int out_src  : 1;
+  unsigned int dummy1   : 30;
+} reg_iop_scrc_out_rw_ctrl;
+#define REG_RD_ADDR_iop_scrc_out_rw_ctrl 4
+#define REG_WR_ADDR_iop_scrc_out_rw_ctrl 4
+
+/* Register rw_init_crc, scope iop_scrc_out, type rw */
+typedef unsigned int reg_iop_scrc_out_rw_init_crc;
+#define REG_RD_ADDR_iop_scrc_out_rw_init_crc 8
+#define REG_WR_ADDR_iop_scrc_out_rw_init_crc 8
+
+/* Register rw_crc, scope iop_scrc_out, type rw */
+typedef unsigned int reg_iop_scrc_out_rw_crc;
+#define REG_RD_ADDR_iop_scrc_out_rw_crc 12
+#define REG_WR_ADDR_iop_scrc_out_rw_crc 12
+
+/* Register rw_data, scope iop_scrc_out, type rw */
+typedef struct {
+  unsigned int val : 1;
+  unsigned int dummy1 : 31;
+} reg_iop_scrc_out_rw_data;
+#define REG_RD_ADDR_iop_scrc_out_rw_data 16
+#define REG_WR_ADDR_iop_scrc_out_rw_data 16
+
+/* Register r_computed_crc, scope iop_scrc_out, type r */
+typedef unsigned int reg_iop_scrc_out_r_computed_crc;
+#define REG_RD_ADDR_iop_scrc_out_r_computed_crc 20
+
+
+/* Constants */
+enum {
+  regk_iop_scrc_out_crc                    = 0x00000001,
+  regk_iop_scrc_out_data                   = 0x00000000,
+  regk_iop_scrc_out_dif                    = 0x00000001,
+  regk_iop_scrc_out_hi                     = 0x00000000,
+  regk_iop_scrc_out_neg                    = 0x00000002,
+  regk_iop_scrc_out_no                     = 0x00000000,
+  regk_iop_scrc_out_pos                    = 0x00000001,
+  regk_iop_scrc_out_pos_neg                = 0x00000003,
+  regk_iop_scrc_out_reg                    = 0x00000000,
+  regk_iop_scrc_out_rw_cfg_default         = 0x00000000,
+  regk_iop_scrc_out_rw_crc_default         = 0x00000000,
+  regk_iop_scrc_out_rw_ctrl_default        = 0x00000000,
+  regk_iop_scrc_out_rw_data_default        = 0x00000000,
+  regk_iop_scrc_out_rw_init_crc_default    = 0x00000000,
+  regk_iop_scrc_out_yes                    = 0x00000001
+};
+#endif /* __iop_scrc_out_defs_h */
diff --git a/include/asm-cris/arch-v32/hwregs/iop/iop_spu_defs.h b/include/asm-cris/arch-v32/hwregs/iop/iop_spu_defs.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/iop/iop_spu_defs.h
@@ -0,0 +1,453 @@
+#ifndef __iop_spu_defs_h
+#define __iop_spu_defs_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/io_proc/rtl/iop_spu.r
+ *     id:           <not found>
+ *     last modfied: Mon Apr 11 16:08:46 2005
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c --outfile iop_spu_defs.h ../../inst/io_proc/rtl/iop_spu.r
+ *      id: $Id: iop_spu_defs.h,v 1.5 2005/04/24 18:31:05 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+/* Main access macros */
+#ifndef REG_RD
+#define REG_RD( scope, inst, reg ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR
+#define REG_WR( scope, inst, reg, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_VECT
+#define REG_RD_VECT( scope, inst, reg, index ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_VECT
+#define REG_WR_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT
+#define REG_RD_INT( scope, inst, reg ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT
+#define REG_WR_INT( scope, inst, reg, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT_VECT
+#define REG_RD_INT_VECT( scope, inst, reg, index ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT_VECT
+#define REG_WR_INT_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_TYPE_CONV
+#define REG_TYPE_CONV( type, orgtype, val ) \
+  ( { union { orgtype o; type n; } r; r.o = val; r.n; } )
+#endif
+
+#ifndef reg_page_size
+#define reg_page_size 8192
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg + \
+    (index) * STRIDE_##scope##_##reg )
+#endif
+
+/* C-code for register scope iop_spu */
+
+#define STRIDE_iop_spu_rw_r 4
+/* Register rw_r, scope iop_spu, type rw */
+typedef unsigned int reg_iop_spu_rw_r;
+#define REG_RD_ADDR_iop_spu_rw_r 0
+#define REG_WR_ADDR_iop_spu_rw_r 0
+
+/* Register rw_seq_pc, scope iop_spu, type rw */
+typedef struct {
+  unsigned int addr : 12;
+  unsigned int dummy1 : 20;
+} reg_iop_spu_rw_seq_pc;
+#define REG_RD_ADDR_iop_spu_rw_seq_pc 64
+#define REG_WR_ADDR_iop_spu_rw_seq_pc 64
+
+/* Register rw_fsm_pc, scope iop_spu, type rw */
+typedef struct {
+  unsigned int addr : 12;
+  unsigned int dummy1 : 20;
+} reg_iop_spu_rw_fsm_pc;
+#define REG_RD_ADDR_iop_spu_rw_fsm_pc 68
+#define REG_WR_ADDR_iop_spu_rw_fsm_pc 68
+
+/* Register rw_ctrl, scope iop_spu, type rw */
+typedef struct {
+  unsigned int fsm : 1;
+  unsigned int en  : 1;
+  unsigned int dummy1 : 30;
+} reg_iop_spu_rw_ctrl;
+#define REG_RD_ADDR_iop_spu_rw_ctrl 72
+#define REG_WR_ADDR_iop_spu_rw_ctrl 72
+
+/* Register rw_fsm_inputs3_0, scope iop_spu, type rw */
+typedef struct {
+  unsigned int val0 : 5;
+  unsigned int src0 : 3;
+  unsigned int val1 : 5;
+  unsigned int src1 : 3;
+  unsigned int val2 : 5;
+  unsigned int src2 : 3;
+  unsigned int val3 : 5;
+  unsigned int src3 : 3;
+} reg_iop_spu_rw_fsm_inputs3_0;
+#define REG_RD_ADDR_iop_spu_rw_fsm_inputs3_0 76
+#define REG_WR_ADDR_iop_spu_rw_fsm_inputs3_0 76
+
+/* Register rw_fsm_inputs7_4, scope iop_spu, type rw */
+typedef struct {
+  unsigned int val4 : 5;
+  unsigned int src4 : 3;
+  unsigned int val5 : 5;
+  unsigned int src5 : 3;
+  unsigned int val6 : 5;
+  unsigned int src6 : 3;
+  unsigned int val7 : 5;
+  unsigned int src7 : 3;
+} reg_iop_spu_rw_fsm_inputs7_4;
+#define REG_RD_ADDR_iop_spu_rw_fsm_inputs7_4 80
+#define REG_WR_ADDR_iop_spu_rw_fsm_inputs7_4 80
+
+/* Register rw_gio_out, scope iop_spu, type rw */
+typedef unsigned int reg_iop_spu_rw_gio_out;
+#define REG_RD_ADDR_iop_spu_rw_gio_out 84
+#define REG_WR_ADDR_iop_spu_rw_gio_out 84
+
+/* Register rw_bus0_out, scope iop_spu, type rw */
+typedef unsigned int reg_iop_spu_rw_bus0_out;
+#define REG_RD_ADDR_iop_spu_rw_bus0_out 88
+#define REG_WR_ADDR_iop_spu_rw_bus0_out 88
+
+/* Register rw_bus1_out, scope iop_spu, type rw */
+typedef unsigned int reg_iop_spu_rw_bus1_out;
+#define REG_RD_ADDR_iop_spu_rw_bus1_out 92
+#define REG_WR_ADDR_iop_spu_rw_bus1_out 92
+
+/* Register r_gio_in, scope iop_spu, type r */
+typedef unsigned int reg_iop_spu_r_gio_in;
+#define REG_RD_ADDR_iop_spu_r_gio_in 96
+
+/* Register r_bus0_in, scope iop_spu, type r */
+typedef unsigned int reg_iop_spu_r_bus0_in;
+#define REG_RD_ADDR_iop_spu_r_bus0_in 100
+
+/* Register r_bus1_in, scope iop_spu, type r */
+typedef unsigned int reg_iop_spu_r_bus1_in;
+#define REG_RD_ADDR_iop_spu_r_bus1_in 104
+
+/* Register rw_gio_out_set, scope iop_spu, type rw */
+typedef unsigned int reg_iop_spu_rw_gio_out_set;
+#define REG_RD_ADDR_iop_spu_rw_gio_out_set 108
+#define REG_WR_ADDR_iop_spu_rw_gio_out_set 108
+
+/* Register rw_gio_out_clr, scope iop_spu, type rw */
+typedef unsigned int reg_iop_spu_rw_gio_out_clr;
+#define REG_RD_ADDR_iop_spu_rw_gio_out_clr 112
+#define REG_WR_ADDR_iop_spu_rw_gio_out_clr 112
+
+/* Register rs_wr_stat, scope iop_spu, type rs */
+typedef struct {
+  unsigned int r0  : 1;
+  unsigned int r1  : 1;
+  unsigned int r2  : 1;
+  unsigned int r3  : 1;
+  unsigned int r4  : 1;
+  unsigned int r5  : 1;
+  unsigned int r6  : 1;
+  unsigned int r7  : 1;
+  unsigned int r8  : 1;
+  unsigned int r9  : 1;
+  unsigned int r10 : 1;
+  unsigned int r11 : 1;
+  unsigned int r12 : 1;
+  unsigned int r13 : 1;
+  unsigned int r14 : 1;
+  unsigned int r15 : 1;
+  unsigned int dummy1 : 16;
+} reg_iop_spu_rs_wr_stat;
+#define REG_RD_ADDR_iop_spu_rs_wr_stat 116
+
+/* Register r_wr_stat, scope iop_spu, type r */
+typedef struct {
+  unsigned int r0  : 1;
+  unsigned int r1  : 1;
+  unsigned int r2  : 1;
+  unsigned int r3  : 1;
+  unsigned int r4  : 1;
+  unsigned int r5  : 1;
+  unsigned int r6  : 1;
+  unsigned int r7  : 1;
+  unsigned int r8  : 1;
+  unsigned int r9  : 1;
+  unsigned int r10 : 1;
+  unsigned int r11 : 1;
+  unsigned int r12 : 1;
+  unsigned int r13 : 1;
+  unsigned int r14 : 1;
+  unsigned int r15 : 1;
+  unsigned int dummy1 : 16;
+} reg_iop_spu_r_wr_stat;
+#define REG_RD_ADDR_iop_spu_r_wr_stat 120
+
+/* Register r_reg_indexed_by_bus0_in, scope iop_spu, type r */
+typedef unsigned int reg_iop_spu_r_reg_indexed_by_bus0_in;
+#define REG_RD_ADDR_iop_spu_r_reg_indexed_by_bus0_in 124
+
+/* Register r_stat_in, scope iop_spu, type r */
+typedef struct {
+  unsigned int timer_grp_lo    : 4;
+  unsigned int fifo_out_last   : 1;
+  unsigned int fifo_out_rdy    : 1;
+  unsigned int fifo_out_all    : 1;
+  unsigned int fifo_in_rdy     : 1;
+  unsigned int dmc_out_all     : 1;
+  unsigned int dmc_out_dth     : 1;
+  unsigned int dmc_out_eop     : 1;
+  unsigned int dmc_out_dv      : 1;
+  unsigned int dmc_out_last    : 1;
+  unsigned int dmc_out_cmd_rq  : 1;
+  unsigned int dmc_out_cmd_rdy : 1;
+  unsigned int pcrc_correct    : 1;
+  unsigned int timer_grp_hi    : 4;
+  unsigned int dmc_in_sth      : 1;
+  unsigned int dmc_in_full     : 1;
+  unsigned int dmc_in_cmd_rdy  : 1;
+  unsigned int spu_gio_out     : 4;
+  unsigned int sync_clk12      : 1;
+  unsigned int scrc_out_data   : 1;
+  unsigned int scrc_in_err     : 1;
+  unsigned int mc_busy         : 1;
+  unsigned int mc_owned        : 1;
+} reg_iop_spu_r_stat_in;
+#define REG_RD_ADDR_iop_spu_r_stat_in 128
+
+/* Register r_trigger_in, scope iop_spu, type r */
+typedef unsigned int reg_iop_spu_r_trigger_in;
+#define REG_RD_ADDR_iop_spu_r_trigger_in 132
+
+/* Register r_special_stat, scope iop_spu, type r */
+typedef struct {
+  unsigned int c_flag         : 1;
+  unsigned int v_flag         : 1;
+  unsigned int z_flag         : 1;
+  unsigned int n_flag         : 1;
+  unsigned int xor_bus0_r2_0  : 1;
+  unsigned int xor_bus1_r3_0  : 1;
+  unsigned int xor_bus0m_r2_0 : 1;
+  unsigned int xor_bus1m_r3_0 : 1;
+  unsigned int fsm_in0        : 1;
+  unsigned int fsm_in1        : 1;
+  unsigned int fsm_in2        : 1;
+  unsigned int fsm_in3        : 1;
+  unsigned int fsm_in4        : 1;
+  unsigned int fsm_in5        : 1;
+  unsigned int fsm_in6        : 1;
+  unsigned int fsm_in7        : 1;
+  unsigned int event0         : 1;
+  unsigned int event1         : 1;
+  unsigned int event2         : 1;
+  unsigned int event3         : 1;
+  unsigned int dummy1         : 12;
+} reg_iop_spu_r_special_stat;
+#define REG_RD_ADDR_iop_spu_r_special_stat 136
+
+/* Register rw_reg_access, scope iop_spu, type rw */
+typedef struct {
+  unsigned int addr   : 13;
+  unsigned int dummy1 : 3;
+  unsigned int imm_hi : 16;
+} reg_iop_spu_rw_reg_access;
+#define REG_RD_ADDR_iop_spu_rw_reg_access 140
+#define REG_WR_ADDR_iop_spu_rw_reg_access 140
+
+#define STRIDE_iop_spu_rw_event_cfg 4
+/* Register rw_event_cfg, scope iop_spu, type rw */
+typedef struct {
+  unsigned int addr   : 12;
+  unsigned int src    : 2;
+  unsigned int eq_en  : 1;
+  unsigned int eq_inv : 1;
+  unsigned int gt_en  : 1;
+  unsigned int gt_inv : 1;
+  unsigned int dummy1 : 14;
+} reg_iop_spu_rw_event_cfg;
+#define REG_RD_ADDR_iop_spu_rw_event_cfg 144
+#define REG_WR_ADDR_iop_spu_rw_event_cfg 144
+
+#define STRIDE_iop_spu_rw_event_mask 4
+/* Register rw_event_mask, scope iop_spu, type rw */
+typedef unsigned int reg_iop_spu_rw_event_mask;
+#define REG_RD_ADDR_iop_spu_rw_event_mask 160
+#define REG_WR_ADDR_iop_spu_rw_event_mask 160
+
+#define STRIDE_iop_spu_rw_event_val 4
+/* Register rw_event_val, scope iop_spu, type rw */
+typedef unsigned int reg_iop_spu_rw_event_val;
+#define REG_RD_ADDR_iop_spu_rw_event_val 176
+#define REG_WR_ADDR_iop_spu_rw_event_val 176
+
+/* Register rw_event_ret, scope iop_spu, type rw */
+typedef struct {
+  unsigned int addr : 12;
+  unsigned int dummy1 : 20;
+} reg_iop_spu_rw_event_ret;
+#define REG_RD_ADDR_iop_spu_rw_event_ret 192
+#define REG_WR_ADDR_iop_spu_rw_event_ret 192
+
+/* Register r_trace, scope iop_spu, type r */
+typedef struct {
+  unsigned int fsm      : 1;
+  unsigned int en       : 1;
+  unsigned int c_flag   : 1;
+  unsigned int v_flag   : 1;
+  unsigned int z_flag   : 1;
+  unsigned int n_flag   : 1;
+  unsigned int seq_addr : 12;
+  unsigned int dummy1   : 2;
+  unsigned int fsm_addr : 12;
+} reg_iop_spu_r_trace;
+#define REG_RD_ADDR_iop_spu_r_trace 196
+
+/* Register r_fsm_trace, scope iop_spu, type r */
+typedef struct {
+  unsigned int fsm      : 1;
+  unsigned int en       : 1;
+  unsigned int tmr_done : 1;
+  unsigned int inp0     : 1;
+  unsigned int inp1     : 1;
+  unsigned int inp2     : 1;
+  unsigned int inp3     : 1;
+  unsigned int event0   : 1;
+  unsigned int event1   : 1;
+  unsigned int event2   : 1;
+  unsigned int event3   : 1;
+  unsigned int gio_out  : 8;
+  unsigned int dummy1   : 1;
+  unsigned int fsm_addr : 12;
+} reg_iop_spu_r_fsm_trace;
+#define REG_RD_ADDR_iop_spu_r_fsm_trace 200
+
+#define STRIDE_iop_spu_rw_brp 4
+/* Register rw_brp, scope iop_spu, type rw */
+typedef struct {
+  unsigned int addr : 12;
+  unsigned int fsm  : 1;
+  unsigned int en   : 1;
+  unsigned int dummy1 : 18;
+} reg_iop_spu_rw_brp;
+#define REG_RD_ADDR_iop_spu_rw_brp 204
+#define REG_WR_ADDR_iop_spu_rw_brp 204
+
+
+/* Constants */
+enum {
+  regk_iop_spu_attn_hi                     = 0x00000005,
+  regk_iop_spu_attn_lo                     = 0x00000005,
+  regk_iop_spu_attn_r0                     = 0x00000000,
+  regk_iop_spu_attn_r1                     = 0x00000001,
+  regk_iop_spu_attn_r10                    = 0x00000002,
+  regk_iop_spu_attn_r11                    = 0x00000003,
+  regk_iop_spu_attn_r12                    = 0x00000004,
+  regk_iop_spu_attn_r13                    = 0x00000005,
+  regk_iop_spu_attn_r14                    = 0x00000006,
+  regk_iop_spu_attn_r15                    = 0x00000007,
+  regk_iop_spu_attn_r2                     = 0x00000002,
+  regk_iop_spu_attn_r3                     = 0x00000003,
+  regk_iop_spu_attn_r4                     = 0x00000004,
+  regk_iop_spu_attn_r5                     = 0x00000005,
+  regk_iop_spu_attn_r6                     = 0x00000006,
+  regk_iop_spu_attn_r7                     = 0x00000007,
+  regk_iop_spu_attn_r8                     = 0x00000000,
+  regk_iop_spu_attn_r9                     = 0x00000001,
+  regk_iop_spu_c                           = 0x00000000,
+  regk_iop_spu_flag                        = 0x00000002,
+  regk_iop_spu_gio_in                      = 0x00000000,
+  regk_iop_spu_gio_out                     = 0x00000005,
+  regk_iop_spu_gio_out0                    = 0x00000008,
+  regk_iop_spu_gio_out1                    = 0x00000009,
+  regk_iop_spu_gio_out2                    = 0x0000000a,
+  regk_iop_spu_gio_out3                    = 0x0000000b,
+  regk_iop_spu_gio_out4                    = 0x0000000c,
+  regk_iop_spu_gio_out5                    = 0x0000000d,
+  regk_iop_spu_gio_out6                    = 0x0000000e,
+  regk_iop_spu_gio_out7                    = 0x0000000f,
+  regk_iop_spu_n                           = 0x00000003,
+  regk_iop_spu_no                          = 0x00000000,
+  regk_iop_spu_r0                          = 0x00000008,
+  regk_iop_spu_r1                          = 0x00000009,
+  regk_iop_spu_r10                         = 0x0000000a,
+  regk_iop_spu_r11                         = 0x0000000b,
+  regk_iop_spu_r12                         = 0x0000000c,
+  regk_iop_spu_r13                         = 0x0000000d,
+  regk_iop_spu_r14                         = 0x0000000e,
+  regk_iop_spu_r15                         = 0x0000000f,
+  regk_iop_spu_r2                          = 0x0000000a,
+  regk_iop_spu_r3                          = 0x0000000b,
+  regk_iop_spu_r4                          = 0x0000000c,
+  regk_iop_spu_r5                          = 0x0000000d,
+  regk_iop_spu_r6                          = 0x0000000e,
+  regk_iop_spu_r7                          = 0x0000000f,
+  regk_iop_spu_r8                          = 0x00000008,
+  regk_iop_spu_r9                          = 0x00000009,
+  regk_iop_spu_reg_hi                      = 0x00000002,
+  regk_iop_spu_reg_lo                      = 0x00000002,
+  regk_iop_spu_rw_brp_default              = 0x00000000,
+  regk_iop_spu_rw_brp_size                 = 0x00000004,
+  regk_iop_spu_rw_ctrl_default             = 0x00000000,
+  regk_iop_spu_rw_event_cfg_size           = 0x00000004,
+  regk_iop_spu_rw_event_mask_size          = 0x00000004,
+  regk_iop_spu_rw_event_val_size           = 0x00000004,
+  regk_iop_spu_rw_gio_out_default          = 0x00000000,
+  regk_iop_spu_rw_r_size                   = 0x00000010,
+  regk_iop_spu_rw_reg_access_default       = 0x00000000,
+  regk_iop_spu_stat_in                     = 0x00000002,
+  regk_iop_spu_statin_hi                   = 0x00000004,
+  regk_iop_spu_statin_lo                   = 0x00000004,
+  regk_iop_spu_trig                        = 0x00000003,
+  regk_iop_spu_trigger                     = 0x00000006,
+  regk_iop_spu_v                           = 0x00000001,
+  regk_iop_spu_wsts_gioout_spec            = 0x00000001,
+  regk_iop_spu_xor                         = 0x00000003,
+  regk_iop_spu_xor_bus0_r2_0               = 0x00000000,
+  regk_iop_spu_xor_bus0m_r2_0              = 0x00000002,
+  regk_iop_spu_xor_bus1_r3_0               = 0x00000001,
+  regk_iop_spu_xor_bus1m_r3_0              = 0x00000003,
+  regk_iop_spu_yes                         = 0x00000001,
+  regk_iop_spu_z                           = 0x00000002
+};
+#endif /* __iop_spu_defs_h */
diff --git a/include/asm-cris/arch-v32/hwregs/iop/iop_sw_cfg_defs.h b/include/asm-cris/arch-v32/hwregs/iop/iop_sw_cfg_defs.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/iop/iop_sw_cfg_defs.h
@@ -0,0 +1,1042 @@
+#ifndef __iop_sw_cfg_defs_h
+#define __iop_sw_cfg_defs_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/io_proc/rtl/guinness/iop_sw_cfg.r
+ *     id:           <not found>
+ *     last modfied: Mon Apr 11 16:10:19 2005
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c --outfile iop_sw_cfg_defs.h ../../inst/io_proc/rtl/guinness/iop_sw_cfg.r
+ *      id: $Id: iop_sw_cfg_defs.h,v 1.4 2005/04/24 18:31:05 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+/* Main access macros */
+#ifndef REG_RD
+#define REG_RD( scope, inst, reg ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR
+#define REG_WR( scope, inst, reg, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_VECT
+#define REG_RD_VECT( scope, inst, reg, index ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_VECT
+#define REG_WR_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT
+#define REG_RD_INT( scope, inst, reg ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT
+#define REG_WR_INT( scope, inst, reg, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT_VECT
+#define REG_RD_INT_VECT( scope, inst, reg, index ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT_VECT
+#define REG_WR_INT_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_TYPE_CONV
+#define REG_TYPE_CONV( type, orgtype, val ) \
+  ( { union { orgtype o; type n; } r; r.o = val; r.n; } )
+#endif
+
+#ifndef reg_page_size
+#define reg_page_size 8192
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg + \
+    (index) * STRIDE_##scope##_##reg )
+#endif
+
+/* C-code for register scope iop_sw_cfg */
+
+/* Register rw_crc_par0_owner, scope iop_sw_cfg, type rw */
+typedef struct {
+  unsigned int cfg : 2;
+  unsigned int dummy1 : 30;
+} reg_iop_sw_cfg_rw_crc_par0_owner;
+#define REG_RD_ADDR_iop_sw_cfg_rw_crc_par0_owner 0
+#define REG_WR_ADDR_iop_sw_cfg_rw_crc_par0_owner 0
+
+/* Register rw_crc_par1_owner, scope iop_sw_cfg, type rw */
+typedef struct {
+  unsigned int cfg : 2;
+  unsigned int dummy1 : 30;
+} reg_iop_sw_cfg_rw_crc_par1_owner;
+#define REG_RD_ADDR_iop_sw_cfg_rw_crc_par1_owner 4
+#define REG_WR_ADDR_iop_sw_cfg_rw_crc_par1_owner 4
+
+/* Register rw_dmc_in0_owner, scope iop_sw_cfg, type rw */
+typedef struct {
+  unsigned int cfg : 2;
+  unsigned int dummy1 : 30;
+} reg_iop_sw_cfg_rw_dmc_in0_owner;
+#define REG_RD_ADDR_iop_sw_cfg_rw_dmc_in0_owner 8
+#define REG_WR_ADDR_iop_sw_cfg_rw_dmc_in0_owner 8
+
+/* Register rw_dmc_in1_owner, scope iop_sw_cfg, type rw */
+typedef struct {
+  unsigned int cfg : 2;
+  unsigned int dummy1 : 30;
+} reg_iop_sw_cfg_rw_dmc_in1_owner;
+#define REG_RD_ADDR_iop_sw_cfg_rw_dmc_in1_owner 12
+#define REG_WR_ADDR_iop_sw_cfg_rw_dmc_in1_owner 12
+
+/* Register rw_dmc_out0_owner, scope iop_sw_cfg, type rw */
+typedef struct {
+  unsigned int cfg : 2;
+  unsigned int dummy1 : 30;
+} reg_iop_sw_cfg_rw_dmc_out0_owner;
+#define REG_RD_ADDR_iop_sw_cfg_rw_dmc_out0_owner 16
+#define REG_WR_ADDR_iop_sw_cfg_rw_dmc_out0_owner 16
+
+/* Register rw_dmc_out1_owner, scope iop_sw_cfg, type rw */
+typedef struct {
+  unsigned int cfg : 2;
+  unsigned int dummy1 : 30;
+} reg_iop_sw_cfg_rw_dmc_out1_owner;
+#define REG_RD_ADDR_iop_sw_cfg_rw_dmc_out1_owner 20
+#define REG_WR_ADDR_iop_sw_cfg_rw_dmc_out1_owner 20
+
+/* Register rw_fifo_in0_owner, scope iop_sw_cfg, type rw */
+typedef struct {
+  unsigned int cfg : 2;
+  unsigned int dummy1 : 30;
+} reg_iop_sw_cfg_rw_fifo_in0_owner;
+#define REG_RD_ADDR_iop_sw_cfg_rw_fifo_in0_owner 24
+#define REG_WR_ADDR_iop_sw_cfg_rw_fifo_in0_owner 24
+
+/* Register rw_fifo_in0_extra_owner, scope iop_sw_cfg, type rw */
+typedef struct {
+  unsigned int cfg : 2;
+  unsigned int dummy1 : 30;
+} reg_iop_sw_cfg_rw_fifo_in0_extra_owner;
+#define REG_RD_ADDR_iop_sw_cfg_rw_fifo_in0_extra_owner 28
+#define REG_WR_ADDR_iop_sw_cfg_rw_fifo_in0_extra_owner 28
+
+/* Register rw_fifo_in1_owner, scope iop_sw_cfg, type rw */
+typedef struct {
+  unsigned int cfg : 2;
+  unsigned int dummy1 : 30;
+} reg_iop_sw_cfg_rw_fifo_in1_owner;
+#define REG_RD_ADDR_iop_sw_cfg_rw_fifo_in1_owner 32
+#define REG_WR_ADDR_iop_sw_cfg_rw_fifo_in1_owner 32
+
+/* Register rw_fifo_in1_extra_owner, scope iop_sw_cfg, type rw */
+typedef struct {
+  unsigned int cfg : 2;
+  unsigned int dummy1 : 30;
+} reg_iop_sw_cfg_rw_fifo_in1_extra_owner;
+#define REG_RD_ADDR_iop_sw_cfg_rw_fifo_in1_extra_owner 36
+#define REG_WR_ADDR_iop_sw_cfg_rw_fifo_in1_extra_owner 36
+
+/* Register rw_fifo_out0_owner, scope iop_sw_cfg, type rw */
+typedef struct {
+  unsigned int cfg : 2;
+  unsigned int dummy1 : 30;
+} reg_iop_sw_cfg_rw_fifo_out0_owner;
+#define REG_RD_ADDR_iop_sw_cfg_rw_fifo_out0_owner 40
+#define REG_WR_ADDR_iop_sw_cfg_rw_fifo_out0_owner 40
+
+/* Register rw_fifo_out0_extra_owner, scope iop_sw_cfg, type rw */
+typedef struct {
+  unsigned int cfg : 2;
+  unsigned int dummy1 : 30;
+} reg_iop_sw_cfg_rw_fifo_out0_extra_owner;
+#define REG_RD_ADDR_iop_sw_cfg_rw_fifo_out0_extra_owner 44
+#define REG_WR_ADDR_iop_sw_cfg_rw_fifo_out0_extra_owner 44
+
+/* Register rw_fifo_out1_owner, scope iop_sw_cfg, type rw */
+typedef struct {
+  unsigned int cfg : 2;
+  unsigned int dummy1 : 30;
+} reg_iop_sw_cfg_rw_fifo_out1_owner;
+#define REG_RD_ADDR_iop_sw_cfg_rw_fifo_out1_owner 48
+#define REG_WR_ADDR_iop_sw_cfg_rw_fifo_out1_owner 48
+
+/* Register rw_fifo_out1_extra_owner, scope iop_sw_cfg, type rw */
+typedef struct {
+  unsigned int cfg : 2;
+  unsigned int dummy1 : 30;
+} reg_iop_sw_cfg_rw_fifo_out1_extra_owner;
+#define REG_RD_ADDR_iop_sw_cfg_rw_fifo_out1_extra_owner 52
+#define REG_WR_ADDR_iop_sw_cfg_rw_fifo_out1_extra_owner 52
+
+/* Register rw_sap_in_owner, scope iop_sw_cfg, type rw */
+typedef struct {
+  unsigned int cfg : 2;
+  unsigned int dummy1 : 30;
+} reg_iop_sw_cfg_rw_sap_in_owner;
+#define REG_RD_ADDR_iop_sw_cfg_rw_sap_in_owner 56
+#define REG_WR_ADDR_iop_sw_cfg_rw_sap_in_owner 56
+
+/* Register rw_sap_out_owner, scope iop_sw_cfg, type rw */
+typedef struct {
+  unsigned int cfg : 2;
+  unsigned int dummy1 : 30;
+} reg_iop_sw_cfg_rw_sap_out_owner;
+#define REG_RD_ADDR_iop_sw_cfg_rw_sap_out_owner 60
+#define REG_WR_ADDR_iop_sw_cfg_rw_sap_out_owner 60
+
+/* Register rw_scrc_in0_owner, scope iop_sw_cfg, type rw */
+typedef struct {
+  unsigned int cfg : 2;
+  unsigned int dummy1 : 30;
+} reg_iop_sw_cfg_rw_scrc_in0_owner;
+#define REG_RD_ADDR_iop_sw_cfg_rw_scrc_in0_owner 64
+#define REG_WR_ADDR_iop_sw_cfg_rw_scrc_in0_owner 64
+
+/* Register rw_scrc_in1_owner, scope iop_sw_cfg, type rw */
+typedef struct {
+  unsigned int cfg : 2;
+  unsigned int dummy1 : 30;
+} reg_iop_sw_cfg_rw_scrc_in1_owner;
+#define REG_RD_ADDR_iop_sw_cfg_rw_scrc_in1_owner 68
+#define REG_WR_ADDR_iop_sw_cfg_rw_scrc_in1_owner 68
+
+/* Register rw_scrc_out0_owner, scope iop_sw_cfg, type rw */
+typedef struct {
+  unsigned int cfg : 2;
+  unsigned int dummy1 : 30;
+} reg_iop_sw_cfg_rw_scrc_out0_owner;
+#define REG_RD_ADDR_iop_sw_cfg_rw_scrc_out0_owner 72
+#define REG_WR_ADDR_iop_sw_cfg_rw_scrc_out0_owner 72
+
+/* Register rw_scrc_out1_owner, scope iop_sw_cfg, type rw */
+typedef struct {
+  unsigned int cfg : 2;
+  unsigned int dummy1 : 30;
+} reg_iop_sw_cfg_rw_scrc_out1_owner;
+#define REG_RD_ADDR_iop_sw_cfg_rw_scrc_out1_owner 76
+#define REG_WR_ADDR_iop_sw_cfg_rw_scrc_out1_owner 76
+
+/* Register rw_spu0_owner, scope iop_sw_cfg, type rw */
+typedef struct {
+  unsigned int cfg : 2;
+  unsigned int dummy1 : 30;
+} reg_iop_sw_cfg_rw_spu0_owner;
+#define REG_RD_ADDR_iop_sw_cfg_rw_spu0_owner 80
+#define REG_WR_ADDR_iop_sw_cfg_rw_spu0_owner 80
+
+/* Register rw_spu1_owner, scope iop_sw_cfg, type rw */
+typedef struct {
+  unsigned int cfg : 2;
+  unsigned int dummy1 : 30;
+} reg_iop_sw_cfg_rw_spu1_owner;
+#define REG_RD_ADDR_iop_sw_cfg_rw_spu1_owner 84
+#define REG_WR_ADDR_iop_sw_cfg_rw_spu1_owner 84
+
+/* Register rw_timer_grp0_owner, scope iop_sw_cfg, type rw */
+typedef struct {
+  unsigned int cfg : 2;
+  unsigned int dummy1 : 30;
+} reg_iop_sw_cfg_rw_timer_grp0_owner;
+#define REG_RD_ADDR_iop_sw_cfg_rw_timer_grp0_owner 88
+#define REG_WR_ADDR_iop_sw_cfg_rw_timer_grp0_owner 88
+
+/* Register rw_timer_grp1_owner, scope iop_sw_cfg, type rw */
+typedef struct {
+  unsigned int cfg : 2;
+  unsigned int dummy1 : 30;
+} reg_iop_sw_cfg_rw_timer_grp1_owner;
+#define REG_RD_ADDR_iop_sw_cfg_rw_timer_grp1_owner 92
+#define REG_WR_ADDR_iop_sw_cfg_rw_timer_grp1_owner 92
+
+/* Register rw_timer_grp2_owner, scope iop_sw_cfg, type rw */
+typedef struct {
+  unsigned int cfg : 2;
+  unsigned int dummy1 : 30;
+} reg_iop_sw_cfg_rw_timer_grp2_owner;
+#define REG_RD_ADDR_iop_sw_cfg_rw_timer_grp2_owner 96
+#define REG_WR_ADDR_iop_sw_cfg_rw_timer_grp2_owner 96
+
+/* Register rw_timer_grp3_owner, scope iop_sw_cfg, type rw */
+typedef struct {
+  unsigned int cfg : 2;
+  unsigned int dummy1 : 30;
+} reg_iop_sw_cfg_rw_timer_grp3_owner;
+#define REG_RD_ADDR_iop_sw_cfg_rw_timer_grp3_owner 100
+#define REG_WR_ADDR_iop_sw_cfg_rw_timer_grp3_owner 100
+
+/* Register rw_trigger_grp0_owner, scope iop_sw_cfg, type rw */
+typedef struct {
+  unsigned int cfg : 2;
+  unsigned int dummy1 : 30;
+} reg_iop_sw_cfg_rw_trigger_grp0_owner;
+#define REG_RD_ADDR_iop_sw_cfg_rw_trigger_grp0_owner 104
+#define REG_WR_ADDR_iop_sw_cfg_rw_trigger_grp0_owner 104
+
+/* Register rw_trigger_grp1_owner, scope iop_sw_cfg, type rw */
+typedef struct {
+  unsigned int cfg : 2;
+  unsigned int dummy1 : 30;
+} reg_iop_sw_cfg_rw_trigger_grp1_owner;
+#define REG_RD_ADDR_iop_sw_cfg_rw_trigger_grp1_owner 108
+#define REG_WR_ADDR_iop_sw_cfg_rw_trigger_grp1_owner 108
+
+/* Register rw_trigger_grp2_owner, scope iop_sw_cfg, type rw */
+typedef struct {
+  unsigned int cfg : 2;
+  unsigned int dummy1 : 30;
+} reg_iop_sw_cfg_rw_trigger_grp2_owner;
+#define REG_RD_ADDR_iop_sw_cfg_rw_trigger_grp2_owner 112
+#define REG_WR_ADDR_iop_sw_cfg_rw_trigger_grp2_owner 112
+
+/* Register rw_trigger_grp3_owner, scope iop_sw_cfg, type rw */
+typedef struct {
+  unsigned int cfg : 2;
+  unsigned int dummy1 : 30;
+} reg_iop_sw_cfg_rw_trigger_grp3_owner;
+#define REG_RD_ADDR_iop_sw_cfg_rw_trigger_grp3_owner 116
+#define REG_WR_ADDR_iop_sw_cfg_rw_trigger_grp3_owner 116
+
+/* Register rw_trigger_grp4_owner, scope iop_sw_cfg, type rw */
+typedef struct {
+  unsigned int cfg : 2;
+  unsigned int dummy1 : 30;
+} reg_iop_sw_cfg_rw_trigger_grp4_owner;
+#define REG_RD_ADDR_iop_sw_cfg_rw_trigger_grp4_owner 120
+#define REG_WR_ADDR_iop_sw_cfg_rw_trigger_grp4_owner 120
+
+/* Register rw_trigger_grp5_owner, scope iop_sw_cfg, type rw */
+typedef struct {
+  unsigned int cfg : 2;
+  unsigned int dummy1 : 30;
+} reg_iop_sw_cfg_rw_trigger_grp5_owner;
+#define REG_RD_ADDR_iop_sw_cfg_rw_trigger_grp5_owner 124
+#define REG_WR_ADDR_iop_sw_cfg_rw_trigger_grp5_owner 124
+
+/* Register rw_trigger_grp6_owner, scope iop_sw_cfg, type rw */
+typedef struct {
+  unsigned int cfg : 2;
+  unsigned int dummy1 : 30;
+} reg_iop_sw_cfg_rw_trigger_grp6_owner;
+#define REG_RD_ADDR_iop_sw_cfg_rw_trigger_grp6_owner 128
+#define REG_WR_ADDR_iop_sw_cfg_rw_trigger_grp6_owner 128
+
+/* Register rw_trigger_grp7_owner, scope iop_sw_cfg, type rw */
+typedef struct {
+  unsigned int cfg : 2;
+  unsigned int dummy1 : 30;
+} reg_iop_sw_cfg_rw_trigger_grp7_owner;
+#define REG_RD_ADDR_iop_sw_cfg_rw_trigger_grp7_owner 132
+#define REG_WR_ADDR_iop_sw_cfg_rw_trigger_grp7_owner 132
+
+/* Register rw_bus0_mask, scope iop_sw_cfg, type rw */
+typedef struct {
+  unsigned int byte0 : 8;
+  unsigned int byte1 : 8;
+  unsigned int byte2 : 8;
+  unsigned int byte3 : 8;
+} reg_iop_sw_cfg_rw_bus0_mask;
+#define REG_RD_ADDR_iop_sw_cfg_rw_bus0_mask 136
+#define REG_WR_ADDR_iop_sw_cfg_rw_bus0_mask 136
+
+/* Register rw_bus0_oe_mask, scope iop_sw_cfg, type rw */
+typedef struct {
+  unsigned int byte0 : 1;
+  unsigned int byte1 : 1;
+  unsigned int byte2 : 1;
+  unsigned int byte3 : 1;
+  unsigned int dummy1 : 28;
+} reg_iop_sw_cfg_rw_bus0_oe_mask;
+#define REG_RD_ADDR_iop_sw_cfg_rw_bus0_oe_mask 140
+#define REG_WR_ADDR_iop_sw_cfg_rw_bus0_oe_mask 140
+
+/* Register rw_bus1_mask, scope iop_sw_cfg, type rw */
+typedef struct {
+  unsigned int byte0 : 8;
+  unsigned int byte1 : 8;
+  unsigned int byte2 : 8;
+  unsigned int byte3 : 8;
+} reg_iop_sw_cfg_rw_bus1_mask;
+#define REG_RD_ADDR_iop_sw_cfg_rw_bus1_mask 144
+#define REG_WR_ADDR_iop_sw_cfg_rw_bus1_mask 144
+
+/* Register rw_bus1_oe_mask, scope iop_sw_cfg, type rw */
+typedef struct {
+  unsigned int byte0 : 1;
+  unsigned int byte1 : 1;
+  unsigned int byte2 : 1;
+  unsigned int byte3 : 1;
+  unsigned int dummy1 : 28;
+} reg_iop_sw_cfg_rw_bus1_oe_mask;
+#define REG_RD_ADDR_iop_sw_cfg_rw_bus1_oe_mask 148
+#define REG_WR_ADDR_iop_sw_cfg_rw_bus1_oe_mask 148
+
+/* Register rw_gio_mask, scope iop_sw_cfg, type rw */
+typedef struct {
+  unsigned int val : 32;
+} reg_iop_sw_cfg_rw_gio_mask;
+#define REG_RD_ADDR_iop_sw_cfg_rw_gio_mask 152
+#define REG_WR_ADDR_iop_sw_cfg_rw_gio_mask 152
+
+/* Register rw_gio_oe_mask, scope iop_sw_cfg, type rw */
+typedef struct {
+  unsigned int val : 32;
+} reg_iop_sw_cfg_rw_gio_oe_mask;
+#define REG_RD_ADDR_iop_sw_cfg_rw_gio_oe_mask 156
+#define REG_WR_ADDR_iop_sw_cfg_rw_gio_oe_mask 156
+
+/* Register rw_pinmapping, scope iop_sw_cfg, type rw */
+typedef struct {
+  unsigned int bus0_byte0 : 2;
+  unsigned int bus0_byte1 : 2;
+  unsigned int bus0_byte2 : 2;
+  unsigned int bus0_byte3 : 2;
+  unsigned int bus1_byte0 : 2;
+  unsigned int bus1_byte1 : 2;
+  unsigned int bus1_byte2 : 2;
+  unsigned int bus1_byte3 : 2;
+  unsigned int gio3_0     : 2;
+  unsigned int gio7_4     : 2;
+  unsigned int gio11_8    : 2;
+  unsigned int gio15_12   : 2;
+  unsigned int gio19_16   : 2;
+  unsigned int gio23_20   : 2;
+  unsigned int gio27_24   : 2;
+  unsigned int gio31_28   : 2;
+} reg_iop_sw_cfg_rw_pinmapping;
+#define REG_RD_ADDR_iop_sw_cfg_rw_pinmapping 160
+#define REG_WR_ADDR_iop_sw_cfg_rw_pinmapping 160
+
+/* Register rw_bus_out_cfg, scope iop_sw_cfg, type rw */
+typedef struct {
+  unsigned int bus0_lo    : 3;
+  unsigned int bus0_hi    : 3;
+  unsigned int bus0_lo_oe : 3;
+  unsigned int bus0_hi_oe : 3;
+  unsigned int bus1_lo    : 3;
+  unsigned int bus1_hi    : 3;
+  unsigned int bus1_lo_oe : 3;
+  unsigned int bus1_hi_oe : 3;
+  unsigned int dummy1     : 8;
+} reg_iop_sw_cfg_rw_bus_out_cfg;
+#define REG_RD_ADDR_iop_sw_cfg_rw_bus_out_cfg 164
+#define REG_WR_ADDR_iop_sw_cfg_rw_bus_out_cfg 164
+
+/* Register rw_gio_out_grp0_cfg, scope iop_sw_cfg, type rw */
+typedef struct {
+  unsigned int gio0    : 4;
+  unsigned int gio0_oe : 2;
+  unsigned int gio1    : 4;
+  unsigned int gio1_oe : 2;
+  unsigned int gio2    : 4;
+  unsigned int gio2_oe : 2;
+  unsigned int gio3    : 4;
+  unsigned int gio3_oe : 2;
+  unsigned int dummy1  : 8;
+} reg_iop_sw_cfg_rw_gio_out_grp0_cfg;
+#define REG_RD_ADDR_iop_sw_cfg_rw_gio_out_grp0_cfg 168
+#define REG_WR_ADDR_iop_sw_cfg_rw_gio_out_grp0_cfg 168
+
+/* Register rw_gio_out_grp1_cfg, scope iop_sw_cfg, type rw */
+typedef struct {
+  unsigned int gio4    : 4;
+  unsigned int gio4_oe : 2;
+  unsigned int gio5    : 4;
+  unsigned int gio5_oe : 2;
+  unsigned int gio6    : 4;
+  unsigned int gio6_oe : 2;
+  unsigned int gio7    : 4;
+  unsigned int gio7_oe : 2;
+  unsigned int dummy1  : 8;
+} reg_iop_sw_cfg_rw_gio_out_grp1_cfg;
+#define REG_RD_ADDR_iop_sw_cfg_rw_gio_out_grp1_cfg 172
+#define REG_WR_ADDR_iop_sw_cfg_rw_gio_out_grp1_cfg 172
+
+/* Register rw_gio_out_grp2_cfg, scope iop_sw_cfg, type rw */
+typedef struct {
+  unsigned int gio8     : 4;
+  unsigned int gio8_oe  : 2;
+  unsigned int gio9     : 4;
+  unsigned int gio9_oe  : 2;
+  unsigned int gio10    : 4;
+  unsigned int gio10_oe : 2;
+  unsigned int gio11    : 4;
+  unsigned int gio11_oe : 2;
+  unsigned int dummy1   : 8;
+} reg_iop_sw_cfg_rw_gio_out_grp2_cfg;
+#define REG_RD_ADDR_iop_sw_cfg_rw_gio_out_grp2_cfg 176
+#define REG_WR_ADDR_iop_sw_cfg_rw_gio_out_grp2_cfg 176
+
+/* Register rw_gio_out_grp3_cfg, scope iop_sw_cfg, type rw */
+typedef struct {
+  unsigned int gio12    : 4;
+  unsigned int gio12_oe : 2;
+  unsigned int gio13    : 4;
+  unsigned int gio13_oe : 2;
+  unsigned int gio14    : 4;
+  unsigned int gio14_oe : 2;
+  unsigned int gio15    : 4;
+  unsigned int gio15_oe : 2;
+  unsigned int dummy1   : 8;
+} reg_iop_sw_cfg_rw_gio_out_grp3_cfg;
+#define REG_RD_ADDR_iop_sw_cfg_rw_gio_out_grp3_cfg 180
+#define REG_WR_ADDR_iop_sw_cfg_rw_gio_out_grp3_cfg 180
+
+/* Register rw_gio_out_grp4_cfg, scope iop_sw_cfg, type rw */
+typedef struct {
+  unsigned int gio16    : 4;
+  unsigned int gio16_oe : 2;
+  unsigned int gio17    : 4;
+  unsigned int gio17_oe : 2;
+  unsigned int gio18    : 4;
+  unsigned int gio18_oe : 2;
+  unsigned int gio19    : 4;
+  unsigned int gio19_oe : 2;
+  unsigned int dummy1   : 8;
+} reg_iop_sw_cfg_rw_gio_out_grp4_cfg;
+#define REG_RD_ADDR_iop_sw_cfg_rw_gio_out_grp4_cfg 184
+#define REG_WR_ADDR_iop_sw_cfg_rw_gio_out_grp4_cfg 184
+
+/* Register rw_gio_out_grp5_cfg, scope iop_sw_cfg, type rw */
+typedef struct {
+  unsigned int gio20    : 4;
+  unsigned int gio20_oe : 2;
+  unsigned int gio21    : 4;
+  unsigned int gio21_oe : 2;
+  unsigned int gio22    : 4;
+  unsigned int gio22_oe : 2;
+  unsigned int gio23    : 4;
+  unsigned int gio23_oe : 2;
+  unsigned int dummy1   : 8;
+} reg_iop_sw_cfg_rw_gio_out_grp5_cfg;
+#define REG_RD_ADDR_iop_sw_cfg_rw_gio_out_grp5_cfg 188
+#define REG_WR_ADDR_iop_sw_cfg_rw_gio_out_grp5_cfg 188
+
+/* Register rw_gio_out_grp6_cfg, scope iop_sw_cfg, type rw */
+typedef struct {
+  unsigned int gio24    : 4;
+  unsigned int gio24_oe : 2;
+  unsigned int gio25    : 4;
+  unsigned int gio25_oe : 2;
+  unsigned int gio26    : 4;
+  unsigned int gio26_oe : 2;
+  unsigned int gio27    : 4;
+  unsigned int gio27_oe : 2;
+  unsigned int dummy1   : 8;
+} reg_iop_sw_cfg_rw_gio_out_grp6_cfg;
+#define REG_RD_ADDR_iop_sw_cfg_rw_gio_out_grp6_cfg 192
+#define REG_WR_ADDR_iop_sw_cfg_rw_gio_out_grp6_cfg 192
+
+/* Register rw_gio_out_grp7_cfg, scope iop_sw_cfg, type rw */
+typedef struct {
+  unsigned int gio28    : 4;
+  unsigned int gio28_oe : 2;
+  unsigned int gio29    : 4;
+  unsigned int gio29_oe : 2;
+  unsigned int gio30    : 4;
+  unsigned int gio30_oe : 2;
+  unsigned int gio31    : 4;
+  unsigned int gio31_oe : 2;
+  unsigned int dummy1   : 8;
+} reg_iop_sw_cfg_rw_gio_out_grp7_cfg;
+#define REG_RD_ADDR_iop_sw_cfg_rw_gio_out_grp7_cfg 196
+#define REG_WR_ADDR_iop_sw_cfg_rw_gio_out_grp7_cfg 196
+
+/* Register rw_spu0_cfg, scope iop_sw_cfg, type rw */
+typedef struct {
+  unsigned int bus0_in : 2;
+  unsigned int bus1_in : 2;
+  unsigned int dummy1  : 28;
+} reg_iop_sw_cfg_rw_spu0_cfg;
+#define REG_RD_ADDR_iop_sw_cfg_rw_spu0_cfg 200
+#define REG_WR_ADDR_iop_sw_cfg_rw_spu0_cfg 200
+
+/* Register rw_spu1_cfg, scope iop_sw_cfg, type rw */
+typedef struct {
+  unsigned int bus0_in : 2;
+  unsigned int bus1_in : 2;
+  unsigned int dummy1  : 28;
+} reg_iop_sw_cfg_rw_spu1_cfg;
+#define REG_RD_ADDR_iop_sw_cfg_rw_spu1_cfg 204
+#define REG_WR_ADDR_iop_sw_cfg_rw_spu1_cfg 204
+
+/* Register rw_timer_grp0_cfg, scope iop_sw_cfg, type rw */
+typedef struct {
+  unsigned int ext_clk  : 3;
+  unsigned int tmr0_en  : 1;
+  unsigned int tmr1_en  : 1;
+  unsigned int tmr2_en  : 1;
+  unsigned int tmr3_en  : 1;
+  unsigned int tmr0_dis : 1;
+  unsigned int tmr1_dis : 1;
+  unsigned int tmr2_dis : 1;
+  unsigned int tmr3_dis : 1;
+  unsigned int dummy1   : 21;
+} reg_iop_sw_cfg_rw_timer_grp0_cfg;
+#define REG_RD_ADDR_iop_sw_cfg_rw_timer_grp0_cfg 208
+#define REG_WR_ADDR_iop_sw_cfg_rw_timer_grp0_cfg 208
+
+/* Register rw_timer_grp1_cfg, scope iop_sw_cfg, type rw */
+typedef struct {
+  unsigned int ext_clk  : 3;
+  unsigned int tmr0_en  : 1;
+  unsigned int tmr1_en  : 1;
+  unsigned int tmr2_en  : 1;
+  unsigned int tmr3_en  : 1;
+  unsigned int tmr0_dis : 1;
+  unsigned int tmr1_dis : 1;
+  unsigned int tmr2_dis : 1;
+  unsigned int tmr3_dis : 1;
+  unsigned int dummy1   : 21;
+} reg_iop_sw_cfg_rw_timer_grp1_cfg;
+#define REG_RD_ADDR_iop_sw_cfg_rw_timer_grp1_cfg 212
+#define REG_WR_ADDR_iop_sw_cfg_rw_timer_grp1_cfg 212
+
+/* Register rw_timer_grp2_cfg, scope iop_sw_cfg, type rw */
+typedef struct {
+  unsigned int ext_clk  : 3;
+  unsigned int tmr0_en  : 1;
+  unsigned int tmr1_en  : 1;
+  unsigned int tmr2_en  : 1;
+  unsigned int tmr3_en  : 1;
+  unsigned int tmr0_dis : 1;
+  unsigned int tmr1_dis : 1;
+  unsigned int tmr2_dis : 1;
+  unsigned int tmr3_dis : 1;
+  unsigned int dummy1   : 21;
+} reg_iop_sw_cfg_rw_timer_grp2_cfg;
+#define REG_RD_ADDR_iop_sw_cfg_rw_timer_grp2_cfg 216
+#define REG_WR_ADDR_iop_sw_cfg_rw_timer_grp2_cfg 216
+
+/* Register rw_timer_grp3_cfg, scope iop_sw_cfg, type rw */
+typedef struct {
+  unsigned int ext_clk  : 3;
+  unsigned int tmr0_en  : 1;
+  unsigned int tmr1_en  : 1;
+  unsigned int tmr2_en  : 1;
+  unsigned int tmr3_en  : 1;
+  unsigned int tmr0_dis : 1;
+  unsigned int tmr1_dis : 1;
+  unsigned int tmr2_dis : 1;
+  unsigned int tmr3_dis : 1;
+  unsigned int dummy1   : 21;
+} reg_iop_sw_cfg_rw_timer_grp3_cfg;
+#define REG_RD_ADDR_iop_sw_cfg_rw_timer_grp3_cfg 220
+#define REG_WR_ADDR_iop_sw_cfg_rw_timer_grp3_cfg 220
+
+/* Register rw_trigger_grps_cfg, scope iop_sw_cfg, type rw */
+typedef struct {
+  unsigned int grp0_dis : 1;
+  unsigned int grp0_en  : 1;
+  unsigned int grp1_dis : 1;
+  unsigned int grp1_en  : 1;
+  unsigned int grp2_dis : 1;
+  unsigned int grp2_en  : 1;
+  unsigned int grp3_dis : 1;
+  unsigned int grp3_en  : 1;
+  unsigned int grp4_dis : 1;
+  unsigned int grp4_en  : 1;
+  unsigned int grp5_dis : 1;
+  unsigned int grp5_en  : 1;
+  unsigned int grp6_dis : 1;
+  unsigned int grp6_en  : 1;
+  unsigned int grp7_dis : 1;
+  unsigned int grp7_en  : 1;
+  unsigned int dummy1   : 16;
+} reg_iop_sw_cfg_rw_trigger_grps_cfg;
+#define REG_RD_ADDR_iop_sw_cfg_rw_trigger_grps_cfg 224
+#define REG_WR_ADDR_iop_sw_cfg_rw_trigger_grps_cfg 224
+
+/* Register rw_pdp0_cfg, scope iop_sw_cfg, type rw */
+typedef struct {
+  unsigned int dmc0_usr : 1;
+  unsigned int out_strb : 5;
+  unsigned int in_src   : 3;
+  unsigned int in_size  : 3;
+  unsigned int in_last  : 2;
+  unsigned int in_strb  : 4;
+  unsigned int out_src  : 1;
+  unsigned int dummy1   : 13;
+} reg_iop_sw_cfg_rw_pdp0_cfg;
+#define REG_RD_ADDR_iop_sw_cfg_rw_pdp0_cfg 228
+#define REG_WR_ADDR_iop_sw_cfg_rw_pdp0_cfg 228
+
+/* Register rw_pdp1_cfg, scope iop_sw_cfg, type rw */
+typedef struct {
+  unsigned int dmc1_usr : 1;
+  unsigned int out_strb : 5;
+  unsigned int in_src   : 3;
+  unsigned int in_size  : 3;
+  unsigned int in_last  : 2;
+  unsigned int in_strb  : 4;
+  unsigned int out_src  : 1;
+  unsigned int dummy1   : 13;
+} reg_iop_sw_cfg_rw_pdp1_cfg;
+#define REG_RD_ADDR_iop_sw_cfg_rw_pdp1_cfg 232
+#define REG_WR_ADDR_iop_sw_cfg_rw_pdp1_cfg 232
+
+/* Register rw_sdp_cfg, scope iop_sw_cfg, type rw */
+typedef struct {
+  unsigned int sdp_out0_strb : 3;
+  unsigned int sdp_out1_strb : 3;
+  unsigned int sdp_in0_data  : 3;
+  unsigned int sdp_in0_last  : 2;
+  unsigned int sdp_in0_strb  : 3;
+  unsigned int sdp_in1_data  : 3;
+  unsigned int sdp_in1_last  : 2;
+  unsigned int sdp_in1_strb  : 3;
+  unsigned int dummy1        : 10;
+} reg_iop_sw_cfg_rw_sdp_cfg;
+#define REG_RD_ADDR_iop_sw_cfg_rw_sdp_cfg 236
+#define REG_WR_ADDR_iop_sw_cfg_rw_sdp_cfg 236
+
+
+/* Constants */
+enum {
+  regk_iop_sw_cfg_a                        = 0x00000001,
+  regk_iop_sw_cfg_b                        = 0x00000002,
+  regk_iop_sw_cfg_bus0                     = 0x00000000,
+  regk_iop_sw_cfg_bus0_rot16               = 0x00000004,
+  regk_iop_sw_cfg_bus0_rot24               = 0x00000006,
+  regk_iop_sw_cfg_bus0_rot8                = 0x00000002,
+  regk_iop_sw_cfg_bus1                     = 0x00000001,
+  regk_iop_sw_cfg_bus1_rot16               = 0x00000005,
+  regk_iop_sw_cfg_bus1_rot24               = 0x00000007,
+  regk_iop_sw_cfg_bus1_rot8                = 0x00000003,
+  regk_iop_sw_cfg_clk12                    = 0x00000000,
+  regk_iop_sw_cfg_cpu                      = 0x00000000,
+  regk_iop_sw_cfg_dmc0                     = 0x00000000,
+  regk_iop_sw_cfg_dmc1                     = 0x00000001,
+  regk_iop_sw_cfg_gated_clk0               = 0x00000010,
+  regk_iop_sw_cfg_gated_clk1               = 0x00000011,
+  regk_iop_sw_cfg_gated_clk2               = 0x00000012,
+  regk_iop_sw_cfg_gated_clk3               = 0x00000013,
+  regk_iop_sw_cfg_gio0                     = 0x00000004,
+  regk_iop_sw_cfg_gio1                     = 0x00000001,
+  regk_iop_sw_cfg_gio2                     = 0x00000005,
+  regk_iop_sw_cfg_gio3                     = 0x00000002,
+  regk_iop_sw_cfg_gio4                     = 0x00000006,
+  regk_iop_sw_cfg_gio5                     = 0x00000003,
+  regk_iop_sw_cfg_gio6                     = 0x00000007,
+  regk_iop_sw_cfg_gio7                     = 0x00000004,
+  regk_iop_sw_cfg_gio_in0                  = 0x00000000,
+  regk_iop_sw_cfg_gio_in1                  = 0x00000001,
+  regk_iop_sw_cfg_gio_in10                 = 0x00000002,
+  regk_iop_sw_cfg_gio_in11                 = 0x00000003,
+  regk_iop_sw_cfg_gio_in14                 = 0x00000004,
+  regk_iop_sw_cfg_gio_in15                 = 0x00000005,
+  regk_iop_sw_cfg_gio_in18                 = 0x00000002,
+  regk_iop_sw_cfg_gio_in19                 = 0x00000003,
+  regk_iop_sw_cfg_gio_in20                 = 0x00000004,
+  regk_iop_sw_cfg_gio_in21                 = 0x00000005,
+  regk_iop_sw_cfg_gio_in26                 = 0x00000006,
+  regk_iop_sw_cfg_gio_in27                 = 0x00000007,
+  regk_iop_sw_cfg_gio_in28                 = 0x00000006,
+  regk_iop_sw_cfg_gio_in29                 = 0x00000007,
+  regk_iop_sw_cfg_gio_in4                  = 0x00000000,
+  regk_iop_sw_cfg_gio_in5                  = 0x00000001,
+  regk_iop_sw_cfg_last_timer_grp0_tmr2     = 0x00000001,
+  regk_iop_sw_cfg_last_timer_grp1_tmr2     = 0x00000001,
+  regk_iop_sw_cfg_last_timer_grp2_tmr2     = 0x00000002,
+  regk_iop_sw_cfg_last_timer_grp2_tmr3     = 0x00000003,
+  regk_iop_sw_cfg_last_timer_grp3_tmr2     = 0x00000002,
+  regk_iop_sw_cfg_last_timer_grp3_tmr3     = 0x00000003,
+  regk_iop_sw_cfg_mpu                      = 0x00000001,
+  regk_iop_sw_cfg_none                     = 0x00000000,
+  regk_iop_sw_cfg_par0                     = 0x00000000,
+  regk_iop_sw_cfg_par1                     = 0x00000001,
+  regk_iop_sw_cfg_pdp_out0                 = 0x00000002,
+  regk_iop_sw_cfg_pdp_out0_hi              = 0x00000001,
+  regk_iop_sw_cfg_pdp_out0_hi_rot8         = 0x00000005,
+  regk_iop_sw_cfg_pdp_out0_lo              = 0x00000000,
+  regk_iop_sw_cfg_pdp_out0_lo_rot8         = 0x00000004,
+  regk_iop_sw_cfg_pdp_out1                 = 0x00000003,
+  regk_iop_sw_cfg_pdp_out1_hi              = 0x00000003,
+  regk_iop_sw_cfg_pdp_out1_hi_rot8         = 0x00000005,
+  regk_iop_sw_cfg_pdp_out1_lo              = 0x00000002,
+  regk_iop_sw_cfg_pdp_out1_lo_rot8         = 0x00000004,
+  regk_iop_sw_cfg_rw_bus0_mask_default     = 0x00000000,
+  regk_iop_sw_cfg_rw_bus0_oe_mask_default  = 0x00000000,
+  regk_iop_sw_cfg_rw_bus1_mask_default     = 0x00000000,
+  regk_iop_sw_cfg_rw_bus1_oe_mask_default  = 0x00000000,
+  regk_iop_sw_cfg_rw_bus_out_cfg_default   = 0x00000000,
+  regk_iop_sw_cfg_rw_crc_par0_owner_default = 0x00000000,
+  regk_iop_sw_cfg_rw_crc_par1_owner_default = 0x00000000,
+  regk_iop_sw_cfg_rw_dmc_in0_owner_default = 0x00000000,
+  regk_iop_sw_cfg_rw_dmc_in1_owner_default = 0x00000000,
+  regk_iop_sw_cfg_rw_dmc_out0_owner_default = 0x00000000,
+  regk_iop_sw_cfg_rw_dmc_out1_owner_default = 0x00000000,
+  regk_iop_sw_cfg_rw_fifo_in0_extra_owner_default = 0x00000000,
+  regk_iop_sw_cfg_rw_fifo_in0_owner_default = 0x00000000,
+  regk_iop_sw_cfg_rw_fifo_in1_extra_owner_default = 0x00000000,
+  regk_iop_sw_cfg_rw_fifo_in1_owner_default = 0x00000000,
+  regk_iop_sw_cfg_rw_fifo_out0_extra_owner_default = 0x00000000,
+  regk_iop_sw_cfg_rw_fifo_out0_owner_default = 0x00000000,
+  regk_iop_sw_cfg_rw_fifo_out1_extra_owner_default = 0x00000000,
+  regk_iop_sw_cfg_rw_fifo_out1_owner_default = 0x00000000,
+  regk_iop_sw_cfg_rw_gio_mask_default      = 0x00000000,
+  regk_iop_sw_cfg_rw_gio_oe_mask_default   = 0x00000000,
+  regk_iop_sw_cfg_rw_gio_out_grp0_cfg_default = 0x00000000,
+  regk_iop_sw_cfg_rw_gio_out_grp1_cfg_default = 0x00000000,
+  regk_iop_sw_cfg_rw_gio_out_grp2_cfg_default = 0x00000000,
+  regk_iop_sw_cfg_rw_gio_out_grp3_cfg_default = 0x00000000,
+  regk_iop_sw_cfg_rw_gio_out_grp4_cfg_default = 0x00000000,
+  regk_iop_sw_cfg_rw_gio_out_grp5_cfg_default = 0x00000000,
+  regk_iop_sw_cfg_rw_gio_out_grp6_cfg_default = 0x00000000,
+  regk_iop_sw_cfg_rw_gio_out_grp7_cfg_default = 0x00000000,
+  regk_iop_sw_cfg_rw_pdp0_cfg_default      = 0x00000000,
+  regk_iop_sw_cfg_rw_pdp1_cfg_default      = 0x00000000,
+  regk_iop_sw_cfg_rw_pinmapping_default    = 0x55555555,
+  regk_iop_sw_cfg_rw_sap_in_owner_default  = 0x00000000,
+  regk_iop_sw_cfg_rw_sap_out_owner_default = 0x00000000,
+  regk_iop_sw_cfg_rw_scrc_in0_owner_default = 0x00000000,
+  regk_iop_sw_cfg_rw_scrc_in1_owner_default = 0x00000000,
+  regk_iop_sw_cfg_rw_scrc_out0_owner_default = 0x00000000,
+  regk_iop_sw_cfg_rw_scrc_out1_owner_default = 0x00000000,
+  regk_iop_sw_cfg_rw_sdp_cfg_default       = 0x00000000,
+  regk_iop_sw_cfg_rw_spu0_cfg_default      = 0x00000000,
+  regk_iop_sw_cfg_rw_spu0_owner_default    = 0x00000000,
+  regk_iop_sw_cfg_rw_spu1_cfg_default      = 0x00000000,
+  regk_iop_sw_cfg_rw_spu1_owner_default    = 0x00000000,
+  regk_iop_sw_cfg_rw_timer_grp0_cfg_default = 0x00000000,
+  regk_iop_sw_cfg_rw_timer_grp0_owner_default = 0x00000000,
+  regk_iop_sw_cfg_rw_timer_grp1_cfg_default = 0x00000000,
+  regk_iop_sw_cfg_rw_timer_grp1_owner_default = 0x00000000,
+  regk_iop_sw_cfg_rw_timer_grp2_cfg_default = 0x00000000,
+  regk_iop_sw_cfg_rw_timer_grp2_owner_default = 0x00000000,
+  regk_iop_sw_cfg_rw_timer_grp3_cfg_default = 0x00000000,
+  regk_iop_sw_cfg_rw_timer_grp3_owner_default = 0x00000000,
+  regk_iop_sw_cfg_rw_trigger_grp0_owner_default = 0x00000000,
+  regk_iop_sw_cfg_rw_trigger_grp1_owner_default = 0x00000000,
+  regk_iop_sw_cfg_rw_trigger_grp2_owner_default = 0x00000000,
+  regk_iop_sw_cfg_rw_trigger_grp3_owner_default = 0x00000000,
+  regk_iop_sw_cfg_rw_trigger_grp4_owner_default = 0x00000000,
+  regk_iop_sw_cfg_rw_trigger_grp5_owner_default = 0x00000000,
+  regk_iop_sw_cfg_rw_trigger_grp6_owner_default = 0x00000000,
+  regk_iop_sw_cfg_rw_trigger_grp7_owner_default = 0x00000000,
+  regk_iop_sw_cfg_rw_trigger_grps_cfg_default = 0x00000000,
+  regk_iop_sw_cfg_sdp_out0                 = 0x00000008,
+  regk_iop_sw_cfg_sdp_out1                 = 0x00000009,
+  regk_iop_sw_cfg_size16                   = 0x00000002,
+  regk_iop_sw_cfg_size24                   = 0x00000003,
+  regk_iop_sw_cfg_size32                   = 0x00000004,
+  regk_iop_sw_cfg_size8                    = 0x00000001,
+  regk_iop_sw_cfg_spu0                     = 0x00000002,
+  regk_iop_sw_cfg_spu0_bus_out0_hi         = 0x00000006,
+  regk_iop_sw_cfg_spu0_bus_out0_lo         = 0x00000006,
+  regk_iop_sw_cfg_spu0_bus_out1_hi         = 0x00000007,
+  regk_iop_sw_cfg_spu0_bus_out1_lo         = 0x00000007,
+  regk_iop_sw_cfg_spu0_g0                  = 0x0000000e,
+  regk_iop_sw_cfg_spu0_g1                  = 0x0000000e,
+  regk_iop_sw_cfg_spu0_g2                  = 0x0000000e,
+  regk_iop_sw_cfg_spu0_g3                  = 0x0000000e,
+  regk_iop_sw_cfg_spu0_g4                  = 0x0000000e,
+  regk_iop_sw_cfg_spu0_g5                  = 0x0000000e,
+  regk_iop_sw_cfg_spu0_g6                  = 0x0000000e,
+  regk_iop_sw_cfg_spu0_g7                  = 0x0000000e,
+  regk_iop_sw_cfg_spu0_gio0                = 0x00000000,
+  regk_iop_sw_cfg_spu0_gio1                = 0x00000001,
+  regk_iop_sw_cfg_spu0_gio2                = 0x00000000,
+  regk_iop_sw_cfg_spu0_gio5                = 0x00000005,
+  regk_iop_sw_cfg_spu0_gio6                = 0x00000006,
+  regk_iop_sw_cfg_spu0_gio7                = 0x00000007,
+  regk_iop_sw_cfg_spu0_gio_out0            = 0x00000008,
+  regk_iop_sw_cfg_spu0_gio_out1            = 0x00000009,
+  regk_iop_sw_cfg_spu0_gio_out2            = 0x0000000a,
+  regk_iop_sw_cfg_spu0_gio_out3            = 0x0000000b,
+  regk_iop_sw_cfg_spu0_gio_out4            = 0x0000000c,
+  regk_iop_sw_cfg_spu0_gio_out5            = 0x0000000d,
+  regk_iop_sw_cfg_spu0_gio_out6            = 0x0000000e,
+  regk_iop_sw_cfg_spu0_gio_out7            = 0x0000000f,
+  regk_iop_sw_cfg_spu0_gioout0             = 0x00000000,
+  regk_iop_sw_cfg_spu0_gioout1             = 0x00000000,
+  regk_iop_sw_cfg_spu0_gioout10            = 0x0000000e,
+  regk_iop_sw_cfg_spu0_gioout11            = 0x0000000e,
+  regk_iop_sw_cfg_spu0_gioout12            = 0x0000000e,
+  regk_iop_sw_cfg_spu0_gioout13            = 0x0000000e,
+  regk_iop_sw_cfg_spu0_gioout14            = 0x0000000e,
+  regk_iop_sw_cfg_spu0_gioout15            = 0x0000000e,
+  regk_iop_sw_cfg_spu0_gioout16            = 0x0000000e,
+  regk_iop_sw_cfg_spu0_gioout17            = 0x0000000e,
+  regk_iop_sw_cfg_spu0_gioout18            = 0x0000000e,
+  regk_iop_sw_cfg_spu0_gioout19            = 0x0000000e,
+  regk_iop_sw_cfg_spu0_gioout2             = 0x00000002,
+  regk_iop_sw_cfg_spu0_gioout20            = 0x0000000e,
+  regk_iop_sw_cfg_spu0_gioout21            = 0x0000000e,
+  regk_iop_sw_cfg_spu0_gioout22            = 0x0000000e,
+  regk_iop_sw_cfg_spu0_gioout23            = 0x0000000e,
+  regk_iop_sw_cfg_spu0_gioout24            = 0x0000000e,
+  regk_iop_sw_cfg_spu0_gioout25            = 0x0000000e,
+  regk_iop_sw_cfg_spu0_gioout26            = 0x0000000e,
+  regk_iop_sw_cfg_spu0_gioout27            = 0x0000000e,
+  regk_iop_sw_cfg_spu0_gioout28            = 0x0000000e,
+  regk_iop_sw_cfg_spu0_gioout29            = 0x0000000e,
+  regk_iop_sw_cfg_spu0_gioout3             = 0x00000002,
+  regk_iop_sw_cfg_spu0_gioout30            = 0x0000000e,
+  regk_iop_sw_cfg_spu0_gioout31            = 0x0000000e,
+  regk_iop_sw_cfg_spu0_gioout4             = 0x00000004,
+  regk_iop_sw_cfg_spu0_gioout5             = 0x00000004,
+  regk_iop_sw_cfg_spu0_gioout6             = 0x00000006,
+  regk_iop_sw_cfg_spu0_gioout7             = 0x00000006,
+  regk_iop_sw_cfg_spu0_gioout8             = 0x0000000e,
+  regk_iop_sw_cfg_spu0_gioout9             = 0x0000000e,
+  regk_iop_sw_cfg_spu1                     = 0x00000003,
+  regk_iop_sw_cfg_spu1_bus_out0_hi         = 0x00000006,
+  regk_iop_sw_cfg_spu1_bus_out0_lo         = 0x00000006,
+  regk_iop_sw_cfg_spu1_bus_out1_hi         = 0x00000007,
+  regk_iop_sw_cfg_spu1_bus_out1_lo         = 0x00000007,
+  regk_iop_sw_cfg_spu1_g0                  = 0x0000000f,
+  regk_iop_sw_cfg_spu1_g1                  = 0x0000000f,
+  regk_iop_sw_cfg_spu1_g2                  = 0x0000000f,
+  regk_iop_sw_cfg_spu1_g3                  = 0x0000000f,
+  regk_iop_sw_cfg_spu1_g4                  = 0x0000000f,
+  regk_iop_sw_cfg_spu1_g5                  = 0x0000000f,
+  regk_iop_sw_cfg_spu1_g6                  = 0x0000000f,
+  regk_iop_sw_cfg_spu1_g7                  = 0x0000000f,
+  regk_iop_sw_cfg_spu1_gio0                = 0x00000002,
+  regk_iop_sw_cfg_spu1_gio1                = 0x00000003,
+  regk_iop_sw_cfg_spu1_gio2                = 0x00000002,
+  regk_iop_sw_cfg_spu1_gio5                = 0x00000005,
+  regk_iop_sw_cfg_spu1_gio6                = 0x00000006,
+  regk_iop_sw_cfg_spu1_gio7                = 0x00000007,
+  regk_iop_sw_cfg_spu1_gio_out0            = 0x00000008,
+  regk_iop_sw_cfg_spu1_gio_out1            = 0x00000009,
+  regk_iop_sw_cfg_spu1_gio_out2            = 0x0000000a,
+  regk_iop_sw_cfg_spu1_gio_out3            = 0x0000000b,
+  regk_iop_sw_cfg_spu1_gio_out4            = 0x0000000c,
+  regk_iop_sw_cfg_spu1_gio_out5            = 0x0000000d,
+  regk_iop_sw_cfg_spu1_gio_out6            = 0x0000000e,
+  regk_iop_sw_cfg_spu1_gio_out7            = 0x0000000f,
+  regk_iop_sw_cfg_spu1_gioout0             = 0x00000001,
+  regk_iop_sw_cfg_spu1_gioout1             = 0x00000001,
+  regk_iop_sw_cfg_spu1_gioout10            = 0x0000000f,
+  regk_iop_sw_cfg_spu1_gioout11            = 0x0000000f,
+  regk_iop_sw_cfg_spu1_gioout12            = 0x0000000f,
+  regk_iop_sw_cfg_spu1_gioout13            = 0x0000000f,
+  regk_iop_sw_cfg_spu1_gioout14            = 0x0000000f,
+  regk_iop_sw_cfg_spu1_gioout15            = 0x0000000f,
+  regk_iop_sw_cfg_spu1_gioout16            = 0x0000000f,
+  regk_iop_sw_cfg_spu1_gioout17            = 0x0000000f,
+  regk_iop_sw_cfg_spu1_gioout18            = 0x0000000f,
+  regk_iop_sw_cfg_spu1_gioout19            = 0x0000000f,
+  regk_iop_sw_cfg_spu1_gioout2             = 0x00000003,
+  regk_iop_sw_cfg_spu1_gioout20            = 0x0000000f,
+  regk_iop_sw_cfg_spu1_gioout21            = 0x0000000f,
+  regk_iop_sw_cfg_spu1_gioout22            = 0x0000000f,
+  regk_iop_sw_cfg_spu1_gioout23            = 0x0000000f,
+  regk_iop_sw_cfg_spu1_gioout24            = 0x0000000f,
+  regk_iop_sw_cfg_spu1_gioout25            = 0x0000000f,
+  regk_iop_sw_cfg_spu1_gioout26            = 0x0000000f,
+  regk_iop_sw_cfg_spu1_gioout27            = 0x0000000f,
+  regk_iop_sw_cfg_spu1_gioout28            = 0x0000000f,
+  regk_iop_sw_cfg_spu1_gioout29            = 0x0000000f,
+  regk_iop_sw_cfg_spu1_gioout3             = 0x00000003,
+  regk_iop_sw_cfg_spu1_gioout30            = 0x0000000f,
+  regk_iop_sw_cfg_spu1_gioout31            = 0x0000000f,
+  regk_iop_sw_cfg_spu1_gioout4             = 0x00000005,
+  regk_iop_sw_cfg_spu1_gioout5             = 0x00000005,
+  regk_iop_sw_cfg_spu1_gioout6             = 0x00000007,
+  regk_iop_sw_cfg_spu1_gioout7             = 0x00000007,
+  regk_iop_sw_cfg_spu1_gioout8             = 0x0000000f,
+  regk_iop_sw_cfg_spu1_gioout9             = 0x0000000f,
+  regk_iop_sw_cfg_strb_timer_grp0_tmr0     = 0x00000001,
+  regk_iop_sw_cfg_strb_timer_grp0_tmr1     = 0x00000002,
+  regk_iop_sw_cfg_strb_timer_grp1_tmr0     = 0x00000001,
+  regk_iop_sw_cfg_strb_timer_grp1_tmr1     = 0x00000002,
+  regk_iop_sw_cfg_strb_timer_grp2_tmr0     = 0x00000003,
+  regk_iop_sw_cfg_strb_timer_grp2_tmr1     = 0x00000002,
+  regk_iop_sw_cfg_strb_timer_grp3_tmr0     = 0x00000003,
+  regk_iop_sw_cfg_strb_timer_grp3_tmr1     = 0x00000002,
+  regk_iop_sw_cfg_timer_grp0               = 0x00000000,
+  regk_iop_sw_cfg_timer_grp0_rot           = 0x00000001,
+  regk_iop_sw_cfg_timer_grp0_strb0         = 0x0000000a,
+  regk_iop_sw_cfg_timer_grp0_strb1         = 0x0000000a,
+  regk_iop_sw_cfg_timer_grp0_strb2         = 0x0000000a,
+  regk_iop_sw_cfg_timer_grp0_strb3         = 0x0000000a,
+  regk_iop_sw_cfg_timer_grp0_tmr0          = 0x00000004,
+  regk_iop_sw_cfg_timer_grp0_tmr1          = 0x00000004,
+  regk_iop_sw_cfg_timer_grp1               = 0x00000000,
+  regk_iop_sw_cfg_timer_grp1_rot           = 0x00000001,
+  regk_iop_sw_cfg_timer_grp1_strb0         = 0x0000000b,
+  regk_iop_sw_cfg_timer_grp1_strb1         = 0x0000000b,
+  regk_iop_sw_cfg_timer_grp1_strb2         = 0x0000000b,
+  regk_iop_sw_cfg_timer_grp1_strb3         = 0x0000000b,
+  regk_iop_sw_cfg_timer_grp1_tmr0          = 0x00000005,
+  regk_iop_sw_cfg_timer_grp1_tmr1          = 0x00000005,
+  regk_iop_sw_cfg_timer_grp2               = 0x00000000,
+  regk_iop_sw_cfg_timer_grp2_rot           = 0x00000001,
+  regk_iop_sw_cfg_timer_grp2_strb0         = 0x0000000c,
+  regk_iop_sw_cfg_timer_grp2_strb1         = 0x0000000c,
+  regk_iop_sw_cfg_timer_grp2_strb2         = 0x0000000c,
+  regk_iop_sw_cfg_timer_grp2_strb3         = 0x0000000c,
+  regk_iop_sw_cfg_timer_grp2_tmr0          = 0x00000006,
+  regk_iop_sw_cfg_timer_grp2_tmr1          = 0x00000006,
+  regk_iop_sw_cfg_timer_grp3               = 0x00000000,
+  regk_iop_sw_cfg_timer_grp3_rot           = 0x00000001,
+  regk_iop_sw_cfg_timer_grp3_strb0         = 0x0000000d,
+  regk_iop_sw_cfg_timer_grp3_strb1         = 0x0000000d,
+  regk_iop_sw_cfg_timer_grp3_strb2         = 0x0000000d,
+  regk_iop_sw_cfg_timer_grp3_strb3         = 0x0000000d,
+  regk_iop_sw_cfg_timer_grp3_tmr0          = 0x00000007,
+  regk_iop_sw_cfg_timer_grp3_tmr1          = 0x00000007,
+  regk_iop_sw_cfg_trig0_0                  = 0x00000000,
+  regk_iop_sw_cfg_trig0_1                  = 0x00000000,
+  regk_iop_sw_cfg_trig0_2                  = 0x00000000,
+  regk_iop_sw_cfg_trig0_3                  = 0x00000000,
+  regk_iop_sw_cfg_trig1_0                  = 0x00000000,
+  regk_iop_sw_cfg_trig1_1                  = 0x00000000,
+  regk_iop_sw_cfg_trig1_2                  = 0x00000000,
+  regk_iop_sw_cfg_trig1_3                  = 0x00000000,
+  regk_iop_sw_cfg_trig2_0                  = 0x00000000,
+  regk_iop_sw_cfg_trig2_1                  = 0x00000000,
+  regk_iop_sw_cfg_trig2_2                  = 0x00000000,
+  regk_iop_sw_cfg_trig2_3                  = 0x00000000,
+  regk_iop_sw_cfg_trig3_0                  = 0x00000000,
+  regk_iop_sw_cfg_trig3_1                  = 0x00000000,
+  regk_iop_sw_cfg_trig3_2                  = 0x00000000,
+  regk_iop_sw_cfg_trig3_3                  = 0x00000000,
+  regk_iop_sw_cfg_trig4_0                  = 0x00000001,
+  regk_iop_sw_cfg_trig4_1                  = 0x00000001,
+  regk_iop_sw_cfg_trig4_2                  = 0x00000001,
+  regk_iop_sw_cfg_trig4_3                  = 0x00000001,
+  regk_iop_sw_cfg_trig5_0                  = 0x00000001,
+  regk_iop_sw_cfg_trig5_1                  = 0x00000001,
+  regk_iop_sw_cfg_trig5_2                  = 0x00000001,
+  regk_iop_sw_cfg_trig5_3                  = 0x00000001,
+  regk_iop_sw_cfg_trig6_0                  = 0x00000001,
+  regk_iop_sw_cfg_trig6_1                  = 0x00000001,
+  regk_iop_sw_cfg_trig6_2                  = 0x00000001,
+  regk_iop_sw_cfg_trig6_3                  = 0x00000001,
+  regk_iop_sw_cfg_trig7_0                  = 0x00000001,
+  regk_iop_sw_cfg_trig7_1                  = 0x00000001,
+  regk_iop_sw_cfg_trig7_2                  = 0x00000001,
+  regk_iop_sw_cfg_trig7_3                  = 0x00000001
+};
+#endif /* __iop_sw_cfg_defs_h */
diff --git a/include/asm-cris/arch-v32/hwregs/iop/iop_sw_cpu_defs.h b/include/asm-cris/arch-v32/hwregs/iop/iop_sw_cpu_defs.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/iop/iop_sw_cpu_defs.h
@@ -0,0 +1,853 @@
+#ifndef __iop_sw_cpu_defs_h
+#define __iop_sw_cpu_defs_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/io_proc/rtl/guinness/iop_sw_cpu.r
+ *     id:           <not found>
+ *     last modfied: Mon Apr 11 16:10:19 2005
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c --outfile iop_sw_cpu_defs.h ../../inst/io_proc/rtl/guinness/iop_sw_cpu.r
+ *      id: $Id: iop_sw_cpu_defs.h,v 1.4 2005/04/24 18:31:05 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+/* Main access macros */
+#ifndef REG_RD
+#define REG_RD( scope, inst, reg ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR
+#define REG_WR( scope, inst, reg, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_VECT
+#define REG_RD_VECT( scope, inst, reg, index ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_VECT
+#define REG_WR_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT
+#define REG_RD_INT( scope, inst, reg ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT
+#define REG_WR_INT( scope, inst, reg, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT_VECT
+#define REG_RD_INT_VECT( scope, inst, reg, index ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT_VECT
+#define REG_WR_INT_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_TYPE_CONV
+#define REG_TYPE_CONV( type, orgtype, val ) \
+  ( { union { orgtype o; type n; } r; r.o = val; r.n; } )
+#endif
+
+#ifndef reg_page_size
+#define reg_page_size 8192
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg + \
+    (index) * STRIDE_##scope##_##reg )
+#endif
+
+/* C-code for register scope iop_sw_cpu */
+
+/* Register rw_mc_ctrl, scope iop_sw_cpu, type rw */
+typedef struct {
+  unsigned int keep_owner  : 1;
+  unsigned int cmd         : 2;
+  unsigned int size        : 3;
+  unsigned int wr_spu0_mem : 1;
+  unsigned int wr_spu1_mem : 1;
+  unsigned int dummy1      : 24;
+} reg_iop_sw_cpu_rw_mc_ctrl;
+#define REG_RD_ADDR_iop_sw_cpu_rw_mc_ctrl 0
+#define REG_WR_ADDR_iop_sw_cpu_rw_mc_ctrl 0
+
+/* Register rw_mc_data, scope iop_sw_cpu, type rw */
+typedef struct {
+  unsigned int val : 32;
+} reg_iop_sw_cpu_rw_mc_data;
+#define REG_RD_ADDR_iop_sw_cpu_rw_mc_data 4
+#define REG_WR_ADDR_iop_sw_cpu_rw_mc_data 4
+
+/* Register rw_mc_addr, scope iop_sw_cpu, type rw */
+typedef unsigned int reg_iop_sw_cpu_rw_mc_addr;
+#define REG_RD_ADDR_iop_sw_cpu_rw_mc_addr 8
+#define REG_WR_ADDR_iop_sw_cpu_rw_mc_addr 8
+
+/* Register rs_mc_data, scope iop_sw_cpu, type rs */
+typedef unsigned int reg_iop_sw_cpu_rs_mc_data;
+#define REG_RD_ADDR_iop_sw_cpu_rs_mc_data 12
+
+/* Register r_mc_data, scope iop_sw_cpu, type r */
+typedef unsigned int reg_iop_sw_cpu_r_mc_data;
+#define REG_RD_ADDR_iop_sw_cpu_r_mc_data 16
+
+/* Register r_mc_stat, scope iop_sw_cpu, type r */
+typedef struct {
+  unsigned int busy_cpu      : 1;
+  unsigned int busy_mpu      : 1;
+  unsigned int busy_spu0     : 1;
+  unsigned int busy_spu1     : 1;
+  unsigned int owned_by_cpu  : 1;
+  unsigned int owned_by_mpu  : 1;
+  unsigned int owned_by_spu0 : 1;
+  unsigned int owned_by_spu1 : 1;
+  unsigned int dummy1        : 24;
+} reg_iop_sw_cpu_r_mc_stat;
+#define REG_RD_ADDR_iop_sw_cpu_r_mc_stat 20
+
+/* Register rw_bus0_clr_mask, scope iop_sw_cpu, type rw */
+typedef struct {
+  unsigned int byte0 : 8;
+  unsigned int byte1 : 8;
+  unsigned int byte2 : 8;
+  unsigned int byte3 : 8;
+} reg_iop_sw_cpu_rw_bus0_clr_mask;
+#define REG_RD_ADDR_iop_sw_cpu_rw_bus0_clr_mask 24
+#define REG_WR_ADDR_iop_sw_cpu_rw_bus0_clr_mask 24
+
+/* Register rw_bus0_set_mask, scope iop_sw_cpu, type rw */
+typedef struct {
+  unsigned int byte0 : 8;
+  unsigned int byte1 : 8;
+  unsigned int byte2 : 8;
+  unsigned int byte3 : 8;
+} reg_iop_sw_cpu_rw_bus0_set_mask;
+#define REG_RD_ADDR_iop_sw_cpu_rw_bus0_set_mask 28
+#define REG_WR_ADDR_iop_sw_cpu_rw_bus0_set_mask 28
+
+/* Register rw_bus0_oe_clr_mask, scope iop_sw_cpu, type rw */
+typedef struct {
+  unsigned int byte0 : 1;
+  unsigned int byte1 : 1;
+  unsigned int byte2 : 1;
+  unsigned int byte3 : 1;
+  unsigned int dummy1 : 28;
+} reg_iop_sw_cpu_rw_bus0_oe_clr_mask;
+#define REG_RD_ADDR_iop_sw_cpu_rw_bus0_oe_clr_mask 32
+#define REG_WR_ADDR_iop_sw_cpu_rw_bus0_oe_clr_mask 32
+
+/* Register rw_bus0_oe_set_mask, scope iop_sw_cpu, type rw */
+typedef struct {
+  unsigned int byte0 : 1;
+  unsigned int byte1 : 1;
+  unsigned int byte2 : 1;
+  unsigned int byte3 : 1;
+  unsigned int dummy1 : 28;
+} reg_iop_sw_cpu_rw_bus0_oe_set_mask;
+#define REG_RD_ADDR_iop_sw_cpu_rw_bus0_oe_set_mask 36
+#define REG_WR_ADDR_iop_sw_cpu_rw_bus0_oe_set_mask 36
+
+/* Register r_bus0_in, scope iop_sw_cpu, type r */
+typedef unsigned int reg_iop_sw_cpu_r_bus0_in;
+#define REG_RD_ADDR_iop_sw_cpu_r_bus0_in 40
+
+/* Register rw_bus1_clr_mask, scope iop_sw_cpu, type rw */
+typedef struct {
+  unsigned int byte0 : 8;
+  unsigned int byte1 : 8;
+  unsigned int byte2 : 8;
+  unsigned int byte3 : 8;
+} reg_iop_sw_cpu_rw_bus1_clr_mask;
+#define REG_RD_ADDR_iop_sw_cpu_rw_bus1_clr_mask 44
+#define REG_WR_ADDR_iop_sw_cpu_rw_bus1_clr_mask 44
+
+/* Register rw_bus1_set_mask, scope iop_sw_cpu, type rw */
+typedef struct {
+  unsigned int byte0 : 8;
+  unsigned int byte1 : 8;
+  unsigned int byte2 : 8;
+  unsigned int byte3 : 8;
+} reg_iop_sw_cpu_rw_bus1_set_mask;
+#define REG_RD_ADDR_iop_sw_cpu_rw_bus1_set_mask 48
+#define REG_WR_ADDR_iop_sw_cpu_rw_bus1_set_mask 48
+
+/* Register rw_bus1_oe_clr_mask, scope iop_sw_cpu, type rw */
+typedef struct {
+  unsigned int byte0 : 1;
+  unsigned int byte1 : 1;
+  unsigned int byte2 : 1;
+  unsigned int byte3 : 1;
+  unsigned int dummy1 : 28;
+} reg_iop_sw_cpu_rw_bus1_oe_clr_mask;
+#define REG_RD_ADDR_iop_sw_cpu_rw_bus1_oe_clr_mask 52
+#define REG_WR_ADDR_iop_sw_cpu_rw_bus1_oe_clr_mask 52
+
+/* Register rw_bus1_oe_set_mask, scope iop_sw_cpu, type rw */
+typedef struct {
+  unsigned int byte0 : 1;
+  unsigned int byte1 : 1;
+  unsigned int byte2 : 1;
+  unsigned int byte3 : 1;
+  unsigned int dummy1 : 28;
+} reg_iop_sw_cpu_rw_bus1_oe_set_mask;
+#define REG_RD_ADDR_iop_sw_cpu_rw_bus1_oe_set_mask 56
+#define REG_WR_ADDR_iop_sw_cpu_rw_bus1_oe_set_mask 56
+
+/* Register r_bus1_in, scope iop_sw_cpu, type r */
+typedef unsigned int reg_iop_sw_cpu_r_bus1_in;
+#define REG_RD_ADDR_iop_sw_cpu_r_bus1_in 60
+
+/* Register rw_gio_clr_mask, scope iop_sw_cpu, type rw */
+typedef struct {
+  unsigned int val : 32;
+} reg_iop_sw_cpu_rw_gio_clr_mask;
+#define REG_RD_ADDR_iop_sw_cpu_rw_gio_clr_mask 64
+#define REG_WR_ADDR_iop_sw_cpu_rw_gio_clr_mask 64
+
+/* Register rw_gio_set_mask, scope iop_sw_cpu, type rw */
+typedef struct {
+  unsigned int val : 32;
+} reg_iop_sw_cpu_rw_gio_set_mask;
+#define REG_RD_ADDR_iop_sw_cpu_rw_gio_set_mask 68
+#define REG_WR_ADDR_iop_sw_cpu_rw_gio_set_mask 68
+
+/* Register rw_gio_oe_clr_mask, scope iop_sw_cpu, type rw */
+typedef struct {
+  unsigned int val : 32;
+} reg_iop_sw_cpu_rw_gio_oe_clr_mask;
+#define REG_RD_ADDR_iop_sw_cpu_rw_gio_oe_clr_mask 72
+#define REG_WR_ADDR_iop_sw_cpu_rw_gio_oe_clr_mask 72
+
+/* Register rw_gio_oe_set_mask, scope iop_sw_cpu, type rw */
+typedef struct {
+  unsigned int val : 32;
+} reg_iop_sw_cpu_rw_gio_oe_set_mask;
+#define REG_RD_ADDR_iop_sw_cpu_rw_gio_oe_set_mask 76
+#define REG_WR_ADDR_iop_sw_cpu_rw_gio_oe_set_mask 76
+
+/* Register r_gio_in, scope iop_sw_cpu, type r */
+typedef unsigned int reg_iop_sw_cpu_r_gio_in;
+#define REG_RD_ADDR_iop_sw_cpu_r_gio_in 80
+
+/* Register rw_intr0_mask, scope iop_sw_cpu, type rw */
+typedef struct {
+  unsigned int mpu_0   : 1;
+  unsigned int mpu_1   : 1;
+  unsigned int mpu_2   : 1;
+  unsigned int mpu_3   : 1;
+  unsigned int mpu_4   : 1;
+  unsigned int mpu_5   : 1;
+  unsigned int mpu_6   : 1;
+  unsigned int mpu_7   : 1;
+  unsigned int mpu_8   : 1;
+  unsigned int mpu_9   : 1;
+  unsigned int mpu_10  : 1;
+  unsigned int mpu_11  : 1;
+  unsigned int mpu_12  : 1;
+  unsigned int mpu_13  : 1;
+  unsigned int mpu_14  : 1;
+  unsigned int mpu_15  : 1;
+  unsigned int spu0_0  : 1;
+  unsigned int spu0_1  : 1;
+  unsigned int spu0_2  : 1;
+  unsigned int spu0_3  : 1;
+  unsigned int spu0_4  : 1;
+  unsigned int spu0_5  : 1;
+  unsigned int spu0_6  : 1;
+  unsigned int spu0_7  : 1;
+  unsigned int spu1_8  : 1;
+  unsigned int spu1_9  : 1;
+  unsigned int spu1_10 : 1;
+  unsigned int spu1_11 : 1;
+  unsigned int spu1_12 : 1;
+  unsigned int spu1_13 : 1;
+  unsigned int spu1_14 : 1;
+  unsigned int spu1_15 : 1;
+} reg_iop_sw_cpu_rw_intr0_mask;
+#define REG_RD_ADDR_iop_sw_cpu_rw_intr0_mask 84
+#define REG_WR_ADDR_iop_sw_cpu_rw_intr0_mask 84
+
+/* Register rw_ack_intr0, scope iop_sw_cpu, type rw */
+typedef struct {
+  unsigned int mpu_0   : 1;
+  unsigned int mpu_1   : 1;
+  unsigned int mpu_2   : 1;
+  unsigned int mpu_3   : 1;
+  unsigned int mpu_4   : 1;
+  unsigned int mpu_5   : 1;
+  unsigned int mpu_6   : 1;
+  unsigned int mpu_7   : 1;
+  unsigned int mpu_8   : 1;
+  unsigned int mpu_9   : 1;
+  unsigned int mpu_10  : 1;
+  unsigned int mpu_11  : 1;
+  unsigned int mpu_12  : 1;
+  unsigned int mpu_13  : 1;
+  unsigned int mpu_14  : 1;
+  unsigned int mpu_15  : 1;
+  unsigned int spu0_0  : 1;
+  unsigned int spu0_1  : 1;
+  unsigned int spu0_2  : 1;
+  unsigned int spu0_3  : 1;
+  unsigned int spu0_4  : 1;
+  unsigned int spu0_5  : 1;
+  unsigned int spu0_6  : 1;
+  unsigned int spu0_7  : 1;
+  unsigned int spu1_8  : 1;
+  unsigned int spu1_9  : 1;
+  unsigned int spu1_10 : 1;
+  unsigned int spu1_11 : 1;
+  unsigned int spu1_12 : 1;
+  unsigned int spu1_13 : 1;
+  unsigned int spu1_14 : 1;
+  unsigned int spu1_15 : 1;
+} reg_iop_sw_cpu_rw_ack_intr0;
+#define REG_RD_ADDR_iop_sw_cpu_rw_ack_intr0 88
+#define REG_WR_ADDR_iop_sw_cpu_rw_ack_intr0 88
+
+/* Register r_intr0, scope iop_sw_cpu, type r */
+typedef struct {
+  unsigned int mpu_0   : 1;
+  unsigned int mpu_1   : 1;
+  unsigned int mpu_2   : 1;
+  unsigned int mpu_3   : 1;
+  unsigned int mpu_4   : 1;
+  unsigned int mpu_5   : 1;
+  unsigned int mpu_6   : 1;
+  unsigned int mpu_7   : 1;
+  unsigned int mpu_8   : 1;
+  unsigned int mpu_9   : 1;
+  unsigned int mpu_10  : 1;
+  unsigned int mpu_11  : 1;
+  unsigned int mpu_12  : 1;
+  unsigned int mpu_13  : 1;
+  unsigned int mpu_14  : 1;
+  unsigned int mpu_15  : 1;
+  unsigned int spu0_0  : 1;
+  unsigned int spu0_1  : 1;
+  unsigned int spu0_2  : 1;
+  unsigned int spu0_3  : 1;
+  unsigned int spu0_4  : 1;
+  unsigned int spu0_5  : 1;
+  unsigned int spu0_6  : 1;
+  unsigned int spu0_7  : 1;
+  unsigned int spu1_8  : 1;
+  unsigned int spu1_9  : 1;
+  unsigned int spu1_10 : 1;
+  unsigned int spu1_11 : 1;
+  unsigned int spu1_12 : 1;
+  unsigned int spu1_13 : 1;
+  unsigned int spu1_14 : 1;
+  unsigned int spu1_15 : 1;
+} reg_iop_sw_cpu_r_intr0;
+#define REG_RD_ADDR_iop_sw_cpu_r_intr0 92
+
+/* Register r_masked_intr0, scope iop_sw_cpu, type r */
+typedef struct {
+  unsigned int mpu_0   : 1;
+  unsigned int mpu_1   : 1;
+  unsigned int mpu_2   : 1;
+  unsigned int mpu_3   : 1;
+  unsigned int mpu_4   : 1;
+  unsigned int mpu_5   : 1;
+  unsigned int mpu_6   : 1;
+  unsigned int mpu_7   : 1;
+  unsigned int mpu_8   : 1;
+  unsigned int mpu_9   : 1;
+  unsigned int mpu_10  : 1;
+  unsigned int mpu_11  : 1;
+  unsigned int mpu_12  : 1;
+  unsigned int mpu_13  : 1;
+  unsigned int mpu_14  : 1;
+  unsigned int mpu_15  : 1;
+  unsigned int spu0_0  : 1;
+  unsigned int spu0_1  : 1;
+  unsigned int spu0_2  : 1;
+  unsigned int spu0_3  : 1;
+  unsigned int spu0_4  : 1;
+  unsigned int spu0_5  : 1;
+  unsigned int spu0_6  : 1;
+  unsigned int spu0_7  : 1;
+  unsigned int spu1_8  : 1;
+  unsigned int spu1_9  : 1;
+  unsigned int spu1_10 : 1;
+  unsigned int spu1_11 : 1;
+  unsigned int spu1_12 : 1;
+  unsigned int spu1_13 : 1;
+  unsigned int spu1_14 : 1;
+  unsigned int spu1_15 : 1;
+} reg_iop_sw_cpu_r_masked_intr0;
+#define REG_RD_ADDR_iop_sw_cpu_r_masked_intr0 96
+
+/* Register rw_intr1_mask, scope iop_sw_cpu, type rw */
+typedef struct {
+  unsigned int mpu_16  : 1;
+  unsigned int mpu_17  : 1;
+  unsigned int mpu_18  : 1;
+  unsigned int mpu_19  : 1;
+  unsigned int mpu_20  : 1;
+  unsigned int mpu_21  : 1;
+  unsigned int mpu_22  : 1;
+  unsigned int mpu_23  : 1;
+  unsigned int mpu_24  : 1;
+  unsigned int mpu_25  : 1;
+  unsigned int mpu_26  : 1;
+  unsigned int mpu_27  : 1;
+  unsigned int mpu_28  : 1;
+  unsigned int mpu_29  : 1;
+  unsigned int mpu_30  : 1;
+  unsigned int mpu_31  : 1;
+  unsigned int spu0_8  : 1;
+  unsigned int spu0_9  : 1;
+  unsigned int spu0_10 : 1;
+  unsigned int spu0_11 : 1;
+  unsigned int spu0_12 : 1;
+  unsigned int spu0_13 : 1;
+  unsigned int spu0_14 : 1;
+  unsigned int spu0_15 : 1;
+  unsigned int spu1_0  : 1;
+  unsigned int spu1_1  : 1;
+  unsigned int spu1_2  : 1;
+  unsigned int spu1_3  : 1;
+  unsigned int spu1_4  : 1;
+  unsigned int spu1_5  : 1;
+  unsigned int spu1_6  : 1;
+  unsigned int spu1_7  : 1;
+} reg_iop_sw_cpu_rw_intr1_mask;
+#define REG_RD_ADDR_iop_sw_cpu_rw_intr1_mask 100
+#define REG_WR_ADDR_iop_sw_cpu_rw_intr1_mask 100
+
+/* Register rw_ack_intr1, scope iop_sw_cpu, type rw */
+typedef struct {
+  unsigned int mpu_16  : 1;
+  unsigned int mpu_17  : 1;
+  unsigned int mpu_18  : 1;
+  unsigned int mpu_19  : 1;
+  unsigned int mpu_20  : 1;
+  unsigned int mpu_21  : 1;
+  unsigned int mpu_22  : 1;
+  unsigned int mpu_23  : 1;
+  unsigned int mpu_24  : 1;
+  unsigned int mpu_25  : 1;
+  unsigned int mpu_26  : 1;
+  unsigned int mpu_27  : 1;
+  unsigned int mpu_28  : 1;
+  unsigned int mpu_29  : 1;
+  unsigned int mpu_30  : 1;
+  unsigned int mpu_31  : 1;
+  unsigned int spu0_8  : 1;
+  unsigned int spu0_9  : 1;
+  unsigned int spu0_10 : 1;
+  unsigned int spu0_11 : 1;
+  unsigned int spu0_12 : 1;
+  unsigned int spu0_13 : 1;
+  unsigned int spu0_14 : 1;
+  unsigned int spu0_15 : 1;
+  unsigned int spu1_0  : 1;
+  unsigned int spu1_1  : 1;
+  unsigned int spu1_2  : 1;
+  unsigned int spu1_3  : 1;
+  unsigned int spu1_4  : 1;
+  unsigned int spu1_5  : 1;
+  unsigned int spu1_6  : 1;
+  unsigned int spu1_7  : 1;
+} reg_iop_sw_cpu_rw_ack_intr1;
+#define REG_RD_ADDR_iop_sw_cpu_rw_ack_intr1 104
+#define REG_WR_ADDR_iop_sw_cpu_rw_ack_intr1 104
+
+/* Register r_intr1, scope iop_sw_cpu, type r */
+typedef struct {
+  unsigned int mpu_16  : 1;
+  unsigned int mpu_17  : 1;
+  unsigned int mpu_18  : 1;
+  unsigned int mpu_19  : 1;
+  unsigned int mpu_20  : 1;
+  unsigned int mpu_21  : 1;
+  unsigned int mpu_22  : 1;
+  unsigned int mpu_23  : 1;
+  unsigned int mpu_24  : 1;
+  unsigned int mpu_25  : 1;
+  unsigned int mpu_26  : 1;
+  unsigned int mpu_27  : 1;
+  unsigned int mpu_28  : 1;
+  unsigned int mpu_29  : 1;
+  unsigned int mpu_30  : 1;
+  unsigned int mpu_31  : 1;
+  unsigned int spu0_8  : 1;
+  unsigned int spu0_9  : 1;
+  unsigned int spu0_10 : 1;
+  unsigned int spu0_11 : 1;
+  unsigned int spu0_12 : 1;
+  unsigned int spu0_13 : 1;
+  unsigned int spu0_14 : 1;
+  unsigned int spu0_15 : 1;
+  unsigned int spu1_0  : 1;
+  unsigned int spu1_1  : 1;
+  unsigned int spu1_2  : 1;
+  unsigned int spu1_3  : 1;
+  unsigned int spu1_4  : 1;
+  unsigned int spu1_5  : 1;
+  unsigned int spu1_6  : 1;
+  unsigned int spu1_7  : 1;
+} reg_iop_sw_cpu_r_intr1;
+#define REG_RD_ADDR_iop_sw_cpu_r_intr1 108
+
+/* Register r_masked_intr1, scope iop_sw_cpu, type r */
+typedef struct {
+  unsigned int mpu_16  : 1;
+  unsigned int mpu_17  : 1;
+  unsigned int mpu_18  : 1;
+  unsigned int mpu_19  : 1;
+  unsigned int mpu_20  : 1;
+  unsigned int mpu_21  : 1;
+  unsigned int mpu_22  : 1;
+  unsigned int mpu_23  : 1;
+  unsigned int mpu_24  : 1;
+  unsigned int mpu_25  : 1;
+  unsigned int mpu_26  : 1;
+  unsigned int mpu_27  : 1;
+  unsigned int mpu_28  : 1;
+  unsigned int mpu_29  : 1;
+  unsigned int mpu_30  : 1;
+  unsigned int mpu_31  : 1;
+  unsigned int spu0_8  : 1;
+  unsigned int spu0_9  : 1;
+  unsigned int spu0_10 : 1;
+  unsigned int spu0_11 : 1;
+  unsigned int spu0_12 : 1;
+  unsigned int spu0_13 : 1;
+  unsigned int spu0_14 : 1;
+  unsigned int spu0_15 : 1;
+  unsigned int spu1_0  : 1;
+  unsigned int spu1_1  : 1;
+  unsigned int spu1_2  : 1;
+  unsigned int spu1_3  : 1;
+  unsigned int spu1_4  : 1;
+  unsigned int spu1_5  : 1;
+  unsigned int spu1_6  : 1;
+  unsigned int spu1_7  : 1;
+} reg_iop_sw_cpu_r_masked_intr1;
+#define REG_RD_ADDR_iop_sw_cpu_r_masked_intr1 112
+
+/* Register rw_intr2_mask, scope iop_sw_cpu, type rw */
+typedef struct {
+  unsigned int mpu_0           : 1;
+  unsigned int mpu_1           : 1;
+  unsigned int mpu_2           : 1;
+  unsigned int mpu_3           : 1;
+  unsigned int mpu_4           : 1;
+  unsigned int mpu_5           : 1;
+  unsigned int mpu_6           : 1;
+  unsigned int mpu_7           : 1;
+  unsigned int spu0_0          : 1;
+  unsigned int spu0_1          : 1;
+  unsigned int spu0_2          : 1;
+  unsigned int spu0_3          : 1;
+  unsigned int spu0_4          : 1;
+  unsigned int spu0_5          : 1;
+  unsigned int spu0_6          : 1;
+  unsigned int spu0_7          : 1;
+  unsigned int dmc_in0         : 1;
+  unsigned int dmc_out0        : 1;
+  unsigned int fifo_in0        : 1;
+  unsigned int fifo_out0       : 1;
+  unsigned int fifo_in0_extra  : 1;
+  unsigned int fifo_out0_extra : 1;
+  unsigned int trigger_grp0    : 1;
+  unsigned int trigger_grp1    : 1;
+  unsigned int trigger_grp2    : 1;
+  unsigned int trigger_grp3    : 1;
+  unsigned int trigger_grp4    : 1;
+  unsigned int trigger_grp5    : 1;
+  unsigned int trigger_grp6    : 1;
+  unsigned int trigger_grp7    : 1;
+  unsigned int timer_grp0      : 1;
+  unsigned int timer_grp1      : 1;
+} reg_iop_sw_cpu_rw_intr2_mask;
+#define REG_RD_ADDR_iop_sw_cpu_rw_intr2_mask 116
+#define REG_WR_ADDR_iop_sw_cpu_rw_intr2_mask 116
+
+/* Register rw_ack_intr2, scope iop_sw_cpu, type rw */
+typedef struct {
+  unsigned int mpu_0  : 1;
+  unsigned int mpu_1  : 1;
+  unsigned int mpu_2  : 1;
+  unsigned int mpu_3  : 1;
+  unsigned int mpu_4  : 1;
+  unsigned int mpu_5  : 1;
+  unsigned int mpu_6  : 1;
+  unsigned int mpu_7  : 1;
+  unsigned int spu0_0 : 1;
+  unsigned int spu0_1 : 1;
+  unsigned int spu0_2 : 1;
+  unsigned int spu0_3 : 1;
+  unsigned int spu0_4 : 1;
+  unsigned int spu0_5 : 1;
+  unsigned int spu0_6 : 1;
+  unsigned int spu0_7 : 1;
+  unsigned int dummy1 : 16;
+} reg_iop_sw_cpu_rw_ack_intr2;
+#define REG_RD_ADDR_iop_sw_cpu_rw_ack_intr2 120
+#define REG_WR_ADDR_iop_sw_cpu_rw_ack_intr2 120
+
+/* Register r_intr2, scope iop_sw_cpu, type r */
+typedef struct {
+  unsigned int mpu_0           : 1;
+  unsigned int mpu_1           : 1;
+  unsigned int mpu_2           : 1;
+  unsigned int mpu_3           : 1;
+  unsigned int mpu_4           : 1;
+  unsigned int mpu_5           : 1;
+  unsigned int mpu_6           : 1;
+  unsigned int mpu_7           : 1;
+  unsigned int spu0_0          : 1;
+  unsigned int spu0_1          : 1;
+  unsigned int spu0_2          : 1;
+  unsigned int spu0_3          : 1;
+  unsigned int spu0_4          : 1;
+  unsigned int spu0_5          : 1;
+  unsigned int spu0_6          : 1;
+  unsigned int spu0_7          : 1;
+  unsigned int dmc_in0         : 1;
+  unsigned int dmc_out0        : 1;
+  unsigned int fifo_in0        : 1;
+  unsigned int fifo_out0       : 1;
+  unsigned int fifo_in0_extra  : 1;
+  unsigned int fifo_out0_extra : 1;
+  unsigned int trigger_grp0    : 1;
+  unsigned int trigger_grp1    : 1;
+  unsigned int trigger_grp2    : 1;
+  unsigned int trigger_grp3    : 1;
+  unsigned int trigger_grp4    : 1;
+  unsigned int trigger_grp5    : 1;
+  unsigned int trigger_grp6    : 1;
+  unsigned int trigger_grp7    : 1;
+  unsigned int timer_grp0      : 1;
+  unsigned int timer_grp1      : 1;
+} reg_iop_sw_cpu_r_intr2;
+#define REG_RD_ADDR_iop_sw_cpu_r_intr2 124
+
+/* Register r_masked_intr2, scope iop_sw_cpu, type r */
+typedef struct {
+  unsigned int mpu_0           : 1;
+  unsigned int mpu_1           : 1;
+  unsigned int mpu_2           : 1;
+  unsigned int mpu_3           : 1;
+  unsigned int mpu_4           : 1;
+  unsigned int mpu_5           : 1;
+  unsigned int mpu_6           : 1;
+  unsigned int mpu_7           : 1;
+  unsigned int spu0_0          : 1;
+  unsigned int spu0_1          : 1;
+  unsigned int spu0_2          : 1;
+  unsigned int spu0_3          : 1;
+  unsigned int spu0_4          : 1;
+  unsigned int spu0_5          : 1;
+  unsigned int spu0_6          : 1;
+  unsigned int spu0_7          : 1;
+  unsigned int dmc_in0         : 1;
+  unsigned int dmc_out0        : 1;
+  unsigned int fifo_in0        : 1;
+  unsigned int fifo_out0       : 1;
+  unsigned int fifo_in0_extra  : 1;
+  unsigned int fifo_out0_extra : 1;
+  unsigned int trigger_grp0    : 1;
+  unsigned int trigger_grp1    : 1;
+  unsigned int trigger_grp2    : 1;
+  unsigned int trigger_grp3    : 1;
+  unsigned int trigger_grp4    : 1;
+  unsigned int trigger_grp5    : 1;
+  unsigned int trigger_grp6    : 1;
+  unsigned int trigger_grp7    : 1;
+  unsigned int timer_grp0      : 1;
+  unsigned int timer_grp1      : 1;
+} reg_iop_sw_cpu_r_masked_intr2;
+#define REG_RD_ADDR_iop_sw_cpu_r_masked_intr2 128
+
+/* Register rw_intr3_mask, scope iop_sw_cpu, type rw */
+typedef struct {
+  unsigned int mpu_16          : 1;
+  unsigned int mpu_17          : 1;
+  unsigned int mpu_18          : 1;
+  unsigned int mpu_19          : 1;
+  unsigned int mpu_20          : 1;
+  unsigned int mpu_21          : 1;
+  unsigned int mpu_22          : 1;
+  unsigned int mpu_23          : 1;
+  unsigned int spu1_0          : 1;
+  unsigned int spu1_1          : 1;
+  unsigned int spu1_2          : 1;
+  unsigned int spu1_3          : 1;
+  unsigned int spu1_4          : 1;
+  unsigned int spu1_5          : 1;
+  unsigned int spu1_6          : 1;
+  unsigned int spu1_7          : 1;
+  unsigned int dmc_in1         : 1;
+  unsigned int dmc_out1        : 1;
+  unsigned int fifo_in1        : 1;
+  unsigned int fifo_out1       : 1;
+  unsigned int fifo_in1_extra  : 1;
+  unsigned int fifo_out1_extra : 1;
+  unsigned int trigger_grp0    : 1;
+  unsigned int trigger_grp1    : 1;
+  unsigned int trigger_grp2    : 1;
+  unsigned int trigger_grp3    : 1;
+  unsigned int trigger_grp4    : 1;
+  unsigned int trigger_grp5    : 1;
+  unsigned int trigger_grp6    : 1;
+  unsigned int trigger_grp7    : 1;
+  unsigned int timer_grp2      : 1;
+  unsigned int timer_grp3      : 1;
+} reg_iop_sw_cpu_rw_intr3_mask;
+#define REG_RD_ADDR_iop_sw_cpu_rw_intr3_mask 132
+#define REG_WR_ADDR_iop_sw_cpu_rw_intr3_mask 132
+
+/* Register rw_ack_intr3, scope iop_sw_cpu, type rw */
+typedef struct {
+  unsigned int mpu_16 : 1;
+  unsigned int mpu_17 : 1;
+  unsigned int mpu_18 : 1;
+  unsigned int mpu_19 : 1;
+  unsigned int mpu_20 : 1;
+  unsigned int mpu_21 : 1;
+  unsigned int mpu_22 : 1;
+  unsigned int mpu_23 : 1;
+  unsigned int spu1_0 : 1;
+  unsigned int spu1_1 : 1;
+  unsigned int spu1_2 : 1;
+  unsigned int spu1_3 : 1;
+  unsigned int spu1_4 : 1;
+  unsigned int spu1_5 : 1;
+  unsigned int spu1_6 : 1;
+  unsigned int spu1_7 : 1;
+  unsigned int dummy1 : 16;
+} reg_iop_sw_cpu_rw_ack_intr3;
+#define REG_RD_ADDR_iop_sw_cpu_rw_ack_intr3 136
+#define REG_WR_ADDR_iop_sw_cpu_rw_ack_intr3 136
+
+/* Register r_intr3, scope iop_sw_cpu, type r */
+typedef struct {
+  unsigned int mpu_16          : 1;
+  unsigned int mpu_17          : 1;
+  unsigned int mpu_18          : 1;
+  unsigned int mpu_19          : 1;
+  unsigned int mpu_20          : 1;
+  unsigned int mpu_21          : 1;
+  unsigned int mpu_22          : 1;
+  unsigned int mpu_23          : 1;
+  unsigned int spu1_0          : 1;
+  unsigned int spu1_1          : 1;
+  unsigned int spu1_2          : 1;
+  unsigned int spu1_3          : 1;
+  unsigned int spu1_4          : 1;
+  unsigned int spu1_5          : 1;
+  unsigned int spu1_6          : 1;
+  unsigned int spu1_7          : 1;
+  unsigned int dmc_in1         : 1;
+  unsigned int dmc_out1        : 1;
+  unsigned int fifo_in1        : 1;
+  unsigned int fifo_out1       : 1;
+  unsigned int fifo_in1_extra  : 1;
+  unsigned int fifo_out1_extra : 1;
+  unsigned int trigger_grp0    : 1;
+  unsigned int trigger_grp1    : 1;
+  unsigned int trigger_grp2    : 1;
+  unsigned int trigger_grp3    : 1;
+  unsigned int trigger_grp4    : 1;
+  unsigned int trigger_grp5    : 1;
+  unsigned int trigger_grp6    : 1;
+  unsigned int trigger_grp7    : 1;
+  unsigned int timer_grp2      : 1;
+  unsigned int timer_grp3      : 1;
+} reg_iop_sw_cpu_r_intr3;
+#define REG_RD_ADDR_iop_sw_cpu_r_intr3 140
+
+/* Register r_masked_intr3, scope iop_sw_cpu, type r */
+typedef struct {
+  unsigned int mpu_16          : 1;
+  unsigned int mpu_17          : 1;
+  unsigned int mpu_18          : 1;
+  unsigned int mpu_19          : 1;
+  unsigned int mpu_20          : 1;
+  unsigned int mpu_21          : 1;
+  unsigned int mpu_22          : 1;
+  unsigned int mpu_23          : 1;
+  unsigned int spu1_0          : 1;
+  unsigned int spu1_1          : 1;
+  unsigned int spu1_2          : 1;
+  unsigned int spu1_3          : 1;
+  unsigned int spu1_4          : 1;
+  unsigned int spu1_5          : 1;
+  unsigned int spu1_6          : 1;
+  unsigned int spu1_7          : 1;
+  unsigned int dmc_in1         : 1;
+  unsigned int dmc_out1        : 1;
+  unsigned int fifo_in1        : 1;
+  unsigned int fifo_out1       : 1;
+  unsigned int fifo_in1_extra  : 1;
+  unsigned int fifo_out1_extra : 1;
+  unsigned int trigger_grp0    : 1;
+  unsigned int trigger_grp1    : 1;
+  unsigned int trigger_grp2    : 1;
+  unsigned int trigger_grp3    : 1;
+  unsigned int trigger_grp4    : 1;
+  unsigned int trigger_grp5    : 1;
+  unsigned int trigger_grp6    : 1;
+  unsigned int trigger_grp7    : 1;
+  unsigned int timer_grp2      : 1;
+  unsigned int timer_grp3      : 1;
+} reg_iop_sw_cpu_r_masked_intr3;
+#define REG_RD_ADDR_iop_sw_cpu_r_masked_intr3 144
+
+
+/* Constants */
+enum {
+  regk_iop_sw_cpu_copy                     = 0x00000000,
+  regk_iop_sw_cpu_no                       = 0x00000000,
+  regk_iop_sw_cpu_rd                       = 0x00000002,
+  regk_iop_sw_cpu_reg_copy                 = 0x00000001,
+  regk_iop_sw_cpu_rw_bus0_clr_mask_default = 0x00000000,
+  regk_iop_sw_cpu_rw_bus0_oe_clr_mask_default = 0x00000000,
+  regk_iop_sw_cpu_rw_bus0_oe_set_mask_default = 0x00000000,
+  regk_iop_sw_cpu_rw_bus0_set_mask_default = 0x00000000,
+  regk_iop_sw_cpu_rw_bus1_clr_mask_default = 0x00000000,
+  regk_iop_sw_cpu_rw_bus1_oe_clr_mask_default = 0x00000000,
+  regk_iop_sw_cpu_rw_bus1_oe_set_mask_default = 0x00000000,
+  regk_iop_sw_cpu_rw_bus1_set_mask_default = 0x00000000,
+  regk_iop_sw_cpu_rw_gio_clr_mask_default  = 0x00000000,
+  regk_iop_sw_cpu_rw_gio_oe_clr_mask_default = 0x00000000,
+  regk_iop_sw_cpu_rw_gio_oe_set_mask_default = 0x00000000,
+  regk_iop_sw_cpu_rw_gio_set_mask_default  = 0x00000000,
+  regk_iop_sw_cpu_rw_intr0_mask_default    = 0x00000000,
+  regk_iop_sw_cpu_rw_intr1_mask_default    = 0x00000000,
+  regk_iop_sw_cpu_rw_intr2_mask_default    = 0x00000000,
+  regk_iop_sw_cpu_rw_intr3_mask_default    = 0x00000000,
+  regk_iop_sw_cpu_wr                       = 0x00000003,
+  regk_iop_sw_cpu_yes                      = 0x00000001
+};
+#endif /* __iop_sw_cpu_defs_h */
diff --git a/include/asm-cris/arch-v32/hwregs/iop/iop_sw_mpu_defs.h b/include/asm-cris/arch-v32/hwregs/iop/iop_sw_mpu_defs.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/iop/iop_sw_mpu_defs.h
@@ -0,0 +1,893 @@
+#ifndef __iop_sw_mpu_defs_h
+#define __iop_sw_mpu_defs_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/io_proc/rtl/guinness/iop_sw_mpu.r
+ *     id:           <not found>
+ *     last modfied: Mon Apr 11 16:10:19 2005
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c --outfile iop_sw_mpu_defs.h ../../inst/io_proc/rtl/guinness/iop_sw_mpu.r
+ *      id: $Id: iop_sw_mpu_defs.h,v 1.4 2005/04/24 18:31:05 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+/* Main access macros */
+#ifndef REG_RD
+#define REG_RD( scope, inst, reg ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR
+#define REG_WR( scope, inst, reg, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_VECT
+#define REG_RD_VECT( scope, inst, reg, index ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_VECT
+#define REG_WR_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT
+#define REG_RD_INT( scope, inst, reg ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT
+#define REG_WR_INT( scope, inst, reg, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT_VECT
+#define REG_RD_INT_VECT( scope, inst, reg, index ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT_VECT
+#define REG_WR_INT_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_TYPE_CONV
+#define REG_TYPE_CONV( type, orgtype, val ) \
+  ( { union { orgtype o; type n; } r; r.o = val; r.n; } )
+#endif
+
+#ifndef reg_page_size
+#define reg_page_size 8192
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg + \
+    (index) * STRIDE_##scope##_##reg )
+#endif
+
+/* C-code for register scope iop_sw_mpu */
+
+/* Register rw_sw_cfg_owner, scope iop_sw_mpu, type rw */
+typedef struct {
+  unsigned int cfg : 2;
+  unsigned int dummy1 : 30;
+} reg_iop_sw_mpu_rw_sw_cfg_owner;
+#define REG_RD_ADDR_iop_sw_mpu_rw_sw_cfg_owner 0
+#define REG_WR_ADDR_iop_sw_mpu_rw_sw_cfg_owner 0
+
+/* Register rw_mc_ctrl, scope iop_sw_mpu, type rw */
+typedef struct {
+  unsigned int keep_owner  : 1;
+  unsigned int cmd         : 2;
+  unsigned int size        : 3;
+  unsigned int wr_spu0_mem : 1;
+  unsigned int wr_spu1_mem : 1;
+  unsigned int dummy1      : 24;
+} reg_iop_sw_mpu_rw_mc_ctrl;
+#define REG_RD_ADDR_iop_sw_mpu_rw_mc_ctrl 4
+#define REG_WR_ADDR_iop_sw_mpu_rw_mc_ctrl 4
+
+/* Register rw_mc_data, scope iop_sw_mpu, type rw */
+typedef struct {
+  unsigned int val : 32;
+} reg_iop_sw_mpu_rw_mc_data;
+#define REG_RD_ADDR_iop_sw_mpu_rw_mc_data 8
+#define REG_WR_ADDR_iop_sw_mpu_rw_mc_data 8
+
+/* Register rw_mc_addr, scope iop_sw_mpu, type rw */
+typedef unsigned int reg_iop_sw_mpu_rw_mc_addr;
+#define REG_RD_ADDR_iop_sw_mpu_rw_mc_addr 12
+#define REG_WR_ADDR_iop_sw_mpu_rw_mc_addr 12
+
+/* Register rs_mc_data, scope iop_sw_mpu, type rs */
+typedef unsigned int reg_iop_sw_mpu_rs_mc_data;
+#define REG_RD_ADDR_iop_sw_mpu_rs_mc_data 16
+
+/* Register r_mc_data, scope iop_sw_mpu, type r */
+typedef unsigned int reg_iop_sw_mpu_r_mc_data;
+#define REG_RD_ADDR_iop_sw_mpu_r_mc_data 20
+
+/* Register r_mc_stat, scope iop_sw_mpu, type r */
+typedef struct {
+  unsigned int busy_cpu      : 1;
+  unsigned int busy_mpu      : 1;
+  unsigned int busy_spu0     : 1;
+  unsigned int busy_spu1     : 1;
+  unsigned int owned_by_cpu  : 1;
+  unsigned int owned_by_mpu  : 1;
+  unsigned int owned_by_spu0 : 1;
+  unsigned int owned_by_spu1 : 1;
+  unsigned int dummy1        : 24;
+} reg_iop_sw_mpu_r_mc_stat;
+#define REG_RD_ADDR_iop_sw_mpu_r_mc_stat 24
+
+/* Register rw_bus0_clr_mask, scope iop_sw_mpu, type rw */
+typedef struct {
+  unsigned int byte0 : 8;
+  unsigned int byte1 : 8;
+  unsigned int byte2 : 8;
+  unsigned int byte3 : 8;
+} reg_iop_sw_mpu_rw_bus0_clr_mask;
+#define REG_RD_ADDR_iop_sw_mpu_rw_bus0_clr_mask 28
+#define REG_WR_ADDR_iop_sw_mpu_rw_bus0_clr_mask 28
+
+/* Register rw_bus0_set_mask, scope iop_sw_mpu, type rw */
+typedef struct {
+  unsigned int byte0 : 8;
+  unsigned int byte1 : 8;
+  unsigned int byte2 : 8;
+  unsigned int byte3 : 8;
+} reg_iop_sw_mpu_rw_bus0_set_mask;
+#define REG_RD_ADDR_iop_sw_mpu_rw_bus0_set_mask 32
+#define REG_WR_ADDR_iop_sw_mpu_rw_bus0_set_mask 32
+
+/* Register rw_bus0_oe_clr_mask, scope iop_sw_mpu, type rw */
+typedef struct {
+  unsigned int byte0 : 1;
+  unsigned int byte1 : 1;
+  unsigned int byte2 : 1;
+  unsigned int byte3 : 1;
+  unsigned int dummy1 : 28;
+} reg_iop_sw_mpu_rw_bus0_oe_clr_mask;
+#define REG_RD_ADDR_iop_sw_mpu_rw_bus0_oe_clr_mask 36
+#define REG_WR_ADDR_iop_sw_mpu_rw_bus0_oe_clr_mask 36
+
+/* Register rw_bus0_oe_set_mask, scope iop_sw_mpu, type rw */
+typedef struct {
+  unsigned int byte0 : 1;
+  unsigned int byte1 : 1;
+  unsigned int byte2 : 1;
+  unsigned int byte3 : 1;
+  unsigned int dummy1 : 28;
+} reg_iop_sw_mpu_rw_bus0_oe_set_mask;
+#define REG_RD_ADDR_iop_sw_mpu_rw_bus0_oe_set_mask 40
+#define REG_WR_ADDR_iop_sw_mpu_rw_bus0_oe_set_mask 40
+
+/* Register r_bus0_in, scope iop_sw_mpu, type r */
+typedef unsigned int reg_iop_sw_mpu_r_bus0_in;
+#define REG_RD_ADDR_iop_sw_mpu_r_bus0_in 44
+
+/* Register rw_bus1_clr_mask, scope iop_sw_mpu, type rw */
+typedef struct {
+  unsigned int byte0 : 8;
+  unsigned int byte1 : 8;
+  unsigned int byte2 : 8;
+  unsigned int byte3 : 8;
+} reg_iop_sw_mpu_rw_bus1_clr_mask;
+#define REG_RD_ADDR_iop_sw_mpu_rw_bus1_clr_mask 48
+#define REG_WR_ADDR_iop_sw_mpu_rw_bus1_clr_mask 48
+
+/* Register rw_bus1_set_mask, scope iop_sw_mpu, type rw */
+typedef struct {
+  unsigned int byte0 : 8;
+  unsigned int byte1 : 8;
+  unsigned int byte2 : 8;
+  unsigned int byte3 : 8;
+} reg_iop_sw_mpu_rw_bus1_set_mask;
+#define REG_RD_ADDR_iop_sw_mpu_rw_bus1_set_mask 52
+#define REG_WR_ADDR_iop_sw_mpu_rw_bus1_set_mask 52
+
+/* Register rw_bus1_oe_clr_mask, scope iop_sw_mpu, type rw */
+typedef struct {
+  unsigned int byte0 : 1;
+  unsigned int byte1 : 1;
+  unsigned int byte2 : 1;
+  unsigned int byte3 : 1;
+  unsigned int dummy1 : 28;
+} reg_iop_sw_mpu_rw_bus1_oe_clr_mask;
+#define REG_RD_ADDR_iop_sw_mpu_rw_bus1_oe_clr_mask 56
+#define REG_WR_ADDR_iop_sw_mpu_rw_bus1_oe_clr_mask 56
+
+/* Register rw_bus1_oe_set_mask, scope iop_sw_mpu, type rw */
+typedef struct {
+  unsigned int byte0 : 1;
+  unsigned int byte1 : 1;
+  unsigned int byte2 : 1;
+  unsigned int byte3 : 1;
+  unsigned int dummy1 : 28;
+} reg_iop_sw_mpu_rw_bus1_oe_set_mask;
+#define REG_RD_ADDR_iop_sw_mpu_rw_bus1_oe_set_mask 60
+#define REG_WR_ADDR_iop_sw_mpu_rw_bus1_oe_set_mask 60
+
+/* Register r_bus1_in, scope iop_sw_mpu, type r */
+typedef unsigned int reg_iop_sw_mpu_r_bus1_in;
+#define REG_RD_ADDR_iop_sw_mpu_r_bus1_in 64
+
+/* Register rw_gio_clr_mask, scope iop_sw_mpu, type rw */
+typedef struct {
+  unsigned int val : 32;
+} reg_iop_sw_mpu_rw_gio_clr_mask;
+#define REG_RD_ADDR_iop_sw_mpu_rw_gio_clr_mask 68
+#define REG_WR_ADDR_iop_sw_mpu_rw_gio_clr_mask 68
+
+/* Register rw_gio_set_mask, scope iop_sw_mpu, type rw */
+typedef struct {
+  unsigned int val : 32;
+} reg_iop_sw_mpu_rw_gio_set_mask;
+#define REG_RD_ADDR_iop_sw_mpu_rw_gio_set_mask 72
+#define REG_WR_ADDR_iop_sw_mpu_rw_gio_set_mask 72
+
+/* Register rw_gio_oe_clr_mask, scope iop_sw_mpu, type rw */
+typedef struct {
+  unsigned int val : 32;
+} reg_iop_sw_mpu_rw_gio_oe_clr_mask;
+#define REG_RD_ADDR_iop_sw_mpu_rw_gio_oe_clr_mask 76
+#define REG_WR_ADDR_iop_sw_mpu_rw_gio_oe_clr_mask 76
+
+/* Register rw_gio_oe_set_mask, scope iop_sw_mpu, type rw */
+typedef struct {
+  unsigned int val : 32;
+} reg_iop_sw_mpu_rw_gio_oe_set_mask;
+#define REG_RD_ADDR_iop_sw_mpu_rw_gio_oe_set_mask 80
+#define REG_WR_ADDR_iop_sw_mpu_rw_gio_oe_set_mask 80
+
+/* Register r_gio_in, scope iop_sw_mpu, type r */
+typedef unsigned int reg_iop_sw_mpu_r_gio_in;
+#define REG_RD_ADDR_iop_sw_mpu_r_gio_in 84
+
+/* Register rw_cpu_intr, scope iop_sw_mpu, type rw */
+typedef struct {
+  unsigned int intr0  : 1;
+  unsigned int intr1  : 1;
+  unsigned int intr2  : 1;
+  unsigned int intr3  : 1;
+  unsigned int intr4  : 1;
+  unsigned int intr5  : 1;
+  unsigned int intr6  : 1;
+  unsigned int intr7  : 1;
+  unsigned int intr8  : 1;
+  unsigned int intr9  : 1;
+  unsigned int intr10 : 1;
+  unsigned int intr11 : 1;
+  unsigned int intr12 : 1;
+  unsigned int intr13 : 1;
+  unsigned int intr14 : 1;
+  unsigned int intr15 : 1;
+  unsigned int intr16 : 1;
+  unsigned int intr17 : 1;
+  unsigned int intr18 : 1;
+  unsigned int intr19 : 1;
+  unsigned int intr20 : 1;
+  unsigned int intr21 : 1;
+  unsigned int intr22 : 1;
+  unsigned int intr23 : 1;
+  unsigned int intr24 : 1;
+  unsigned int intr25 : 1;
+  unsigned int intr26 : 1;
+  unsigned int intr27 : 1;
+  unsigned int intr28 : 1;
+  unsigned int intr29 : 1;
+  unsigned int intr30 : 1;
+  unsigned int intr31 : 1;
+} reg_iop_sw_mpu_rw_cpu_intr;
+#define REG_RD_ADDR_iop_sw_mpu_rw_cpu_intr 88
+#define REG_WR_ADDR_iop_sw_mpu_rw_cpu_intr 88
+
+/* Register r_cpu_intr, scope iop_sw_mpu, type r */
+typedef struct {
+  unsigned int intr0  : 1;
+  unsigned int intr1  : 1;
+  unsigned int intr2  : 1;
+  unsigned int intr3  : 1;
+  unsigned int intr4  : 1;
+  unsigned int intr5  : 1;
+  unsigned int intr6  : 1;
+  unsigned int intr7  : 1;
+  unsigned int intr8  : 1;
+  unsigned int intr9  : 1;
+  unsigned int intr10 : 1;
+  unsigned int intr11 : 1;
+  unsigned int intr12 : 1;
+  unsigned int intr13 : 1;
+  unsigned int intr14 : 1;
+  unsigned int intr15 : 1;
+  unsigned int intr16 : 1;
+  unsigned int intr17 : 1;
+  unsigned int intr18 : 1;
+  unsigned int intr19 : 1;
+  unsigned int intr20 : 1;
+  unsigned int intr21 : 1;
+  unsigned int intr22 : 1;
+  unsigned int intr23 : 1;
+  unsigned int intr24 : 1;
+  unsigned int intr25 : 1;
+  unsigned int intr26 : 1;
+  unsigned int intr27 : 1;
+  unsigned int intr28 : 1;
+  unsigned int intr29 : 1;
+  unsigned int intr30 : 1;
+  unsigned int intr31 : 1;
+} reg_iop_sw_mpu_r_cpu_intr;
+#define REG_RD_ADDR_iop_sw_mpu_r_cpu_intr 92
+
+/* Register rw_intr_grp0_mask, scope iop_sw_mpu, type rw */
+typedef struct {
+  unsigned int spu0_intr0      : 1;
+  unsigned int spu1_intr0      : 1;
+  unsigned int trigger_grp0    : 1;
+  unsigned int trigger_grp4    : 1;
+  unsigned int timer_grp0      : 1;
+  unsigned int fifo_out0       : 1;
+  unsigned int fifo_out0_extra : 1;
+  unsigned int dmc_out0        : 1;
+  unsigned int spu0_intr1      : 1;
+  unsigned int spu1_intr1      : 1;
+  unsigned int trigger_grp1    : 1;
+  unsigned int trigger_grp5    : 1;
+  unsigned int timer_grp1      : 1;
+  unsigned int fifo_in0        : 1;
+  unsigned int fifo_in0_extra  : 1;
+  unsigned int dmc_in0         : 1;
+  unsigned int spu0_intr2      : 1;
+  unsigned int spu1_intr2      : 1;
+  unsigned int trigger_grp2    : 1;
+  unsigned int trigger_grp6    : 1;
+  unsigned int timer_grp2      : 1;
+  unsigned int fifo_out1       : 1;
+  unsigned int fifo_out1_extra : 1;
+  unsigned int dmc_out1        : 1;
+  unsigned int spu0_intr3      : 1;
+  unsigned int spu1_intr3      : 1;
+  unsigned int trigger_grp3    : 1;
+  unsigned int trigger_grp7    : 1;
+  unsigned int timer_grp3      : 1;
+  unsigned int fifo_in1        : 1;
+  unsigned int fifo_in1_extra  : 1;
+  unsigned int dmc_in1         : 1;
+} reg_iop_sw_mpu_rw_intr_grp0_mask;
+#define REG_RD_ADDR_iop_sw_mpu_rw_intr_grp0_mask 96
+#define REG_WR_ADDR_iop_sw_mpu_rw_intr_grp0_mask 96
+
+/* Register rw_ack_intr_grp0, scope iop_sw_mpu, type rw */
+typedef struct {
+  unsigned int spu0_intr0 : 1;
+  unsigned int spu1_intr0 : 1;
+  unsigned int dummy1     : 6;
+  unsigned int spu0_intr1 : 1;
+  unsigned int spu1_intr1 : 1;
+  unsigned int dummy2     : 6;
+  unsigned int spu0_intr2 : 1;
+  unsigned int spu1_intr2 : 1;
+  unsigned int dummy3     : 6;
+  unsigned int spu0_intr3 : 1;
+  unsigned int spu1_intr3 : 1;
+  unsigned int dummy4     : 6;
+} reg_iop_sw_mpu_rw_ack_intr_grp0;
+#define REG_RD_ADDR_iop_sw_mpu_rw_ack_intr_grp0 100
+#define REG_WR_ADDR_iop_sw_mpu_rw_ack_intr_grp0 100
+
+/* Register r_intr_grp0, scope iop_sw_mpu, type r */
+typedef struct {
+  unsigned int spu0_intr0      : 1;
+  unsigned int spu1_intr0      : 1;
+  unsigned int trigger_grp0    : 1;
+  unsigned int trigger_grp4    : 1;
+  unsigned int timer_grp0      : 1;
+  unsigned int fifo_out0       : 1;
+  unsigned int fifo_out0_extra : 1;
+  unsigned int dmc_out0        : 1;
+  unsigned int spu0_intr1      : 1;
+  unsigned int spu1_intr1      : 1;
+  unsigned int trigger_grp1    : 1;
+  unsigned int trigger_grp5    : 1;
+  unsigned int timer_grp1      : 1;
+  unsigned int fifo_in0        : 1;
+  unsigned int fifo_in0_extra  : 1;
+  unsigned int dmc_in0         : 1;
+  unsigned int spu0_intr2      : 1;
+  unsigned int spu1_intr2      : 1;
+  unsigned int trigger_grp2    : 1;
+  unsigned int trigger_grp6    : 1;
+  unsigned int timer_grp2      : 1;
+  unsigned int fifo_out1       : 1;
+  unsigned int fifo_out1_extra : 1;
+  unsigned int dmc_out1        : 1;
+  unsigned int spu0_intr3      : 1;
+  unsigned int spu1_intr3      : 1;
+  unsigned int trigger_grp3    : 1;
+  unsigned int trigger_grp7    : 1;
+  unsigned int timer_grp3      : 1;
+  unsigned int fifo_in1        : 1;
+  unsigned int fifo_in1_extra  : 1;
+  unsigned int dmc_in1         : 1;
+} reg_iop_sw_mpu_r_intr_grp0;
+#define REG_RD_ADDR_iop_sw_mpu_r_intr_grp0 104
+
+/* Register r_masked_intr_grp0, scope iop_sw_mpu, type r */
+typedef struct {
+  unsigned int spu0_intr0      : 1;
+  unsigned int spu1_intr0      : 1;
+  unsigned int trigger_grp0    : 1;
+  unsigned int trigger_grp4    : 1;
+  unsigned int timer_grp0      : 1;
+  unsigned int fifo_out0       : 1;
+  unsigned int fifo_out0_extra : 1;
+  unsigned int dmc_out0        : 1;
+  unsigned int spu0_intr1      : 1;
+  unsigned int spu1_intr1      : 1;
+  unsigned int trigger_grp1    : 1;
+  unsigned int trigger_grp5    : 1;
+  unsigned int timer_grp1      : 1;
+  unsigned int fifo_in0        : 1;
+  unsigned int fifo_in0_extra  : 1;
+  unsigned int dmc_in0         : 1;
+  unsigned int spu0_intr2      : 1;
+  unsigned int spu1_intr2      : 1;
+  unsigned int trigger_grp2    : 1;
+  unsigned int trigger_grp6    : 1;
+  unsigned int timer_grp2      : 1;
+  unsigned int fifo_out1       : 1;
+  unsigned int fifo_out1_extra : 1;
+  unsigned int dmc_out1        : 1;
+  unsigned int spu0_intr3      : 1;
+  unsigned int spu1_intr3      : 1;
+  unsigned int trigger_grp3    : 1;
+  unsigned int trigger_grp7    : 1;
+  unsigned int timer_grp3      : 1;
+  unsigned int fifo_in1        : 1;
+  unsigned int fifo_in1_extra  : 1;
+  unsigned int dmc_in1         : 1;
+} reg_iop_sw_mpu_r_masked_intr_grp0;
+#define REG_RD_ADDR_iop_sw_mpu_r_masked_intr_grp0 108
+
+/* Register rw_intr_grp1_mask, scope iop_sw_mpu, type rw */
+typedef struct {
+  unsigned int spu0_intr4      : 1;
+  unsigned int spu1_intr4      : 1;
+  unsigned int trigger_grp0    : 1;
+  unsigned int trigger_grp5    : 1;
+  unsigned int timer_grp0      : 1;
+  unsigned int fifo_in0        : 1;
+  unsigned int fifo_in0_extra  : 1;
+  unsigned int dmc_out0        : 1;
+  unsigned int spu0_intr5      : 1;
+  unsigned int spu1_intr5      : 1;
+  unsigned int trigger_grp1    : 1;
+  unsigned int trigger_grp6    : 1;
+  unsigned int timer_grp1      : 1;
+  unsigned int fifo_out1       : 1;
+  unsigned int fifo_out0_extra : 1;
+  unsigned int dmc_in0         : 1;
+  unsigned int spu0_intr6      : 1;
+  unsigned int spu1_intr6      : 1;
+  unsigned int trigger_grp2    : 1;
+  unsigned int trigger_grp7    : 1;
+  unsigned int timer_grp2      : 1;
+  unsigned int fifo_in1        : 1;
+  unsigned int fifo_in1_extra  : 1;
+  unsigned int dmc_out1        : 1;
+  unsigned int spu0_intr7      : 1;
+  unsigned int spu1_intr7      : 1;
+  unsigned int trigger_grp3    : 1;
+  unsigned int trigger_grp4    : 1;
+  unsigned int timer_grp3      : 1;
+  unsigned int fifo_out0       : 1;
+  unsigned int fifo_out1_extra : 1;
+  unsigned int dmc_in1         : 1;
+} reg_iop_sw_mpu_rw_intr_grp1_mask;
+#define REG_RD_ADDR_iop_sw_mpu_rw_intr_grp1_mask 112
+#define REG_WR_ADDR_iop_sw_mpu_rw_intr_grp1_mask 112
+
+/* Register rw_ack_intr_grp1, scope iop_sw_mpu, type rw */
+typedef struct {
+  unsigned int spu0_intr4 : 1;
+  unsigned int spu1_intr4 : 1;
+  unsigned int dummy1     : 6;
+  unsigned int spu0_intr5 : 1;
+  unsigned int spu1_intr5 : 1;
+  unsigned int dummy2     : 6;
+  unsigned int spu0_intr6 : 1;
+  unsigned int spu1_intr6 : 1;
+  unsigned int dummy3     : 6;
+  unsigned int spu0_intr7 : 1;
+  unsigned int spu1_intr7 : 1;
+  unsigned int dummy4     : 6;
+} reg_iop_sw_mpu_rw_ack_intr_grp1;
+#define REG_RD_ADDR_iop_sw_mpu_rw_ack_intr_grp1 116
+#define REG_WR_ADDR_iop_sw_mpu_rw_ack_intr_grp1 116
+
+/* Register r_intr_grp1, scope iop_sw_mpu, type r */
+typedef struct {
+  unsigned int spu0_intr4      : 1;
+  unsigned int spu1_intr4      : 1;
+  unsigned int trigger_grp0    : 1;
+  unsigned int trigger_grp5    : 1;
+  unsigned int timer_grp0      : 1;
+  unsigned int fifo_in0        : 1;
+  unsigned int fifo_in0_extra  : 1;
+  unsigned int dmc_out0        : 1;
+  unsigned int spu0_intr5      : 1;
+  unsigned int spu1_intr5      : 1;
+  unsigned int trigger_grp1    : 1;
+  unsigned int trigger_grp6    : 1;
+  unsigned int timer_grp1      : 1;
+  unsigned int fifo_out1       : 1;
+  unsigned int fifo_out0_extra : 1;
+  unsigned int dmc_in0         : 1;
+  unsigned int spu0_intr6      : 1;
+  unsigned int spu1_intr6      : 1;
+  unsigned int trigger_grp2    : 1;
+  unsigned int trigger_grp7    : 1;
+  unsigned int timer_grp2      : 1;
+  unsigned int fifo_in1        : 1;
+  unsigned int fifo_in1_extra  : 1;
+  unsigned int dmc_out1        : 1;
+  unsigned int spu0_intr7      : 1;
+  unsigned int spu1_intr7      : 1;
+  unsigned int trigger_grp3    : 1;
+  unsigned int trigger_grp4    : 1;
+  unsigned int timer_grp3      : 1;
+  unsigned int fifo_out0       : 1;
+  unsigned int fifo_out1_extra : 1;
+  unsigned int dmc_in1         : 1;
+} reg_iop_sw_mpu_r_intr_grp1;
+#define REG_RD_ADDR_iop_sw_mpu_r_intr_grp1 120
+
+/* Register r_masked_intr_grp1, scope iop_sw_mpu, type r */
+typedef struct {
+  unsigned int spu0_intr4      : 1;
+  unsigned int spu1_intr4      : 1;
+  unsigned int trigger_grp0    : 1;
+  unsigned int trigger_grp5    : 1;
+  unsigned int timer_grp0      : 1;
+  unsigned int fifo_in0        : 1;
+  unsigned int fifo_in0_extra  : 1;
+  unsigned int dmc_out0        : 1;
+  unsigned int spu0_intr5      : 1;
+  unsigned int spu1_intr5      : 1;
+  unsigned int trigger_grp1    : 1;
+  unsigned int trigger_grp6    : 1;
+  unsigned int timer_grp1      : 1;
+  unsigned int fifo_out1       : 1;
+  unsigned int fifo_out0_extra : 1;
+  unsigned int dmc_in0         : 1;
+  unsigned int spu0_intr6      : 1;
+  unsigned int spu1_intr6      : 1;
+  unsigned int trigger_grp2    : 1;
+  unsigned int trigger_grp7    : 1;
+  unsigned int timer_grp2      : 1;
+  unsigned int fifo_in1        : 1;
+  unsigned int fifo_in1_extra  : 1;
+  unsigned int dmc_out1        : 1;
+  unsigned int spu0_intr7      : 1;
+  unsigned int spu1_intr7      : 1;
+  unsigned int trigger_grp3    : 1;
+  unsigned int trigger_grp4    : 1;
+  unsigned int timer_grp3      : 1;
+  unsigned int fifo_out0       : 1;
+  unsigned int fifo_out1_extra : 1;
+  unsigned int dmc_in1         : 1;
+} reg_iop_sw_mpu_r_masked_intr_grp1;
+#define REG_RD_ADDR_iop_sw_mpu_r_masked_intr_grp1 124
+
+/* Register rw_intr_grp2_mask, scope iop_sw_mpu, type rw */
+typedef struct {
+  unsigned int spu0_intr8      : 1;
+  unsigned int spu1_intr8      : 1;
+  unsigned int trigger_grp0    : 1;
+  unsigned int trigger_grp6    : 1;
+  unsigned int timer_grp0      : 1;
+  unsigned int fifo_out1       : 1;
+  unsigned int fifo_out1_extra : 1;
+  unsigned int dmc_out0        : 1;
+  unsigned int spu0_intr9      : 1;
+  unsigned int spu1_intr9      : 1;
+  unsigned int trigger_grp1    : 1;
+  unsigned int trigger_grp7    : 1;
+  unsigned int timer_grp1      : 1;
+  unsigned int fifo_in1        : 1;
+  unsigned int fifo_in1_extra  : 1;
+  unsigned int dmc_in0         : 1;
+  unsigned int spu0_intr10     : 1;
+  unsigned int spu1_intr10     : 1;
+  unsigned int trigger_grp2    : 1;
+  unsigned int trigger_grp4    : 1;
+  unsigned int timer_grp2      : 1;
+  unsigned int fifo_out0       : 1;
+  unsigned int fifo_out0_extra : 1;
+  unsigned int dmc_out1        : 1;
+  unsigned int spu0_intr11     : 1;
+  unsigned int spu1_intr11     : 1;
+  unsigned int trigger_grp3    : 1;
+  unsigned int trigger_grp5    : 1;
+  unsigned int timer_grp3      : 1;
+  unsigned int fifo_in0        : 1;
+  unsigned int fifo_in0_extra  : 1;
+  unsigned int dmc_in1         : 1;
+} reg_iop_sw_mpu_rw_intr_grp2_mask;
+#define REG_RD_ADDR_iop_sw_mpu_rw_intr_grp2_mask 128
+#define REG_WR_ADDR_iop_sw_mpu_rw_intr_grp2_mask 128
+
+/* Register rw_ack_intr_grp2, scope iop_sw_mpu, type rw */
+typedef struct {
+  unsigned int spu0_intr8  : 1;
+  unsigned int spu1_intr8  : 1;
+  unsigned int dummy1      : 6;
+  unsigned int spu0_intr9  : 1;
+  unsigned int spu1_intr9  : 1;
+  unsigned int dummy2      : 6;
+  unsigned int spu0_intr10 : 1;
+  unsigned int spu1_intr10 : 1;
+  unsigned int dummy3      : 6;
+  unsigned int spu0_intr11 : 1;
+  unsigned int spu1_intr11 : 1;
+  unsigned int dummy4      : 6;
+} reg_iop_sw_mpu_rw_ack_intr_grp2;
+#define REG_RD_ADDR_iop_sw_mpu_rw_ack_intr_grp2 132
+#define REG_WR_ADDR_iop_sw_mpu_rw_ack_intr_grp2 132
+
+/* Register r_intr_grp2, scope iop_sw_mpu, type r */
+typedef struct {
+  unsigned int spu0_intr8      : 1;
+  unsigned int spu1_intr8      : 1;
+  unsigned int trigger_grp0    : 1;
+  unsigned int trigger_grp6    : 1;
+  unsigned int timer_grp0      : 1;
+  unsigned int fifo_out1       : 1;
+  unsigned int fifo_out1_extra : 1;
+  unsigned int dmc_out0        : 1;
+  unsigned int spu0_intr9      : 1;
+  unsigned int spu1_intr9      : 1;
+  unsigned int trigger_grp1    : 1;
+  unsigned int trigger_grp7    : 1;
+  unsigned int timer_grp1      : 1;
+  unsigned int fifo_in1        : 1;
+  unsigned int fifo_in1_extra  : 1;
+  unsigned int dmc_in0         : 1;
+  unsigned int spu0_intr10     : 1;
+  unsigned int spu1_intr10     : 1;
+  unsigned int trigger_grp2    : 1;
+  unsigned int trigger_grp4    : 1;
+  unsigned int timer_grp2      : 1;
+  unsigned int fifo_out0       : 1;
+  unsigned int fifo_out0_extra : 1;
+  unsigned int dmc_out1        : 1;
+  unsigned int spu0_intr11     : 1;
+  unsigned int spu1_intr11     : 1;
+  unsigned int trigger_grp3    : 1;
+  unsigned int trigger_grp5    : 1;
+  unsigned int timer_grp3      : 1;
+  unsigned int fifo_in0        : 1;
+  unsigned int fifo_in0_extra  : 1;
+  unsigned int dmc_in1         : 1;
+} reg_iop_sw_mpu_r_intr_grp2;
+#define REG_RD_ADDR_iop_sw_mpu_r_intr_grp2 136
+
+/* Register r_masked_intr_grp2, scope iop_sw_mpu, type r */
+typedef struct {
+  unsigned int spu0_intr8      : 1;
+  unsigned int spu1_intr8      : 1;
+  unsigned int trigger_grp0    : 1;
+  unsigned int trigger_grp6    : 1;
+  unsigned int timer_grp0      : 1;
+  unsigned int fifo_out1       : 1;
+  unsigned int fifo_out1_extra : 1;
+  unsigned int dmc_out0        : 1;
+  unsigned int spu0_intr9      : 1;
+  unsigned int spu1_intr9      : 1;
+  unsigned int trigger_grp1    : 1;
+  unsigned int trigger_grp7    : 1;
+  unsigned int timer_grp1      : 1;
+  unsigned int fifo_in1        : 1;
+  unsigned int fifo_in1_extra  : 1;
+  unsigned int dmc_in0         : 1;
+  unsigned int spu0_intr10     : 1;
+  unsigned int spu1_intr10     : 1;
+  unsigned int trigger_grp2    : 1;
+  unsigned int trigger_grp4    : 1;
+  unsigned int timer_grp2      : 1;
+  unsigned int fifo_out0       : 1;
+  unsigned int fifo_out0_extra : 1;
+  unsigned int dmc_out1        : 1;
+  unsigned int spu0_intr11     : 1;
+  unsigned int spu1_intr11     : 1;
+  unsigned int trigger_grp3    : 1;
+  unsigned int trigger_grp5    : 1;
+  unsigned int timer_grp3      : 1;
+  unsigned int fifo_in0        : 1;
+  unsigned int fifo_in0_extra  : 1;
+  unsigned int dmc_in1         : 1;
+} reg_iop_sw_mpu_r_masked_intr_grp2;
+#define REG_RD_ADDR_iop_sw_mpu_r_masked_intr_grp2 140
+
+/* Register rw_intr_grp3_mask, scope iop_sw_mpu, type rw */
+typedef struct {
+  unsigned int spu0_intr12     : 1;
+  unsigned int spu1_intr12     : 1;
+  unsigned int trigger_grp0    : 1;
+  unsigned int trigger_grp7    : 1;
+  unsigned int timer_grp0      : 1;
+  unsigned int fifo_in1        : 1;
+  unsigned int fifo_in1_extra  : 1;
+  unsigned int dmc_out0        : 1;
+  unsigned int spu0_intr13     : 1;
+  unsigned int spu1_intr13     : 1;
+  unsigned int trigger_grp1    : 1;
+  unsigned int trigger_grp4    : 1;
+  unsigned int timer_grp1      : 1;
+  unsigned int fifo_out0       : 1;
+  unsigned int fifo_out0_extra : 1;
+  unsigned int dmc_in0         : 1;
+  unsigned int spu0_intr14     : 1;
+  unsigned int spu1_intr14     : 1;
+  unsigned int trigger_grp2    : 1;
+  unsigned int trigger_grp5    : 1;
+  unsigned int timer_grp2      : 1;
+  unsigned int fifo_in0        : 1;
+  unsigned int fifo_in0_extra  : 1;
+  unsigned int dmc_out1        : 1;
+  unsigned int spu0_intr15     : 1;
+  unsigned int spu1_intr15     : 1;
+  unsigned int trigger_grp3    : 1;
+  unsigned int trigger_grp6    : 1;
+  unsigned int timer_grp3      : 1;
+  unsigned int fifo_out1       : 1;
+  unsigned int fifo_out1_extra : 1;
+  unsigned int dmc_in1         : 1;
+} reg_iop_sw_mpu_rw_intr_grp3_mask;
+#define REG_RD_ADDR_iop_sw_mpu_rw_intr_grp3_mask 144
+#define REG_WR_ADDR_iop_sw_mpu_rw_intr_grp3_mask 144
+
+/* Register rw_ack_intr_grp3, scope iop_sw_mpu, type rw */
+typedef struct {
+  unsigned int spu0_intr12 : 1;
+  unsigned int spu1_intr12 : 1;
+  unsigned int dummy1      : 6;
+  unsigned int spu0_intr13 : 1;
+  unsigned int spu1_intr13 : 1;
+  unsigned int dummy2      : 6;
+  unsigned int spu0_intr14 : 1;
+  unsigned int spu1_intr14 : 1;
+  unsigned int dummy3      : 6;
+  unsigned int spu0_intr15 : 1;
+  unsigned int spu1_intr15 : 1;
+  unsigned int dummy4      : 6;
+} reg_iop_sw_mpu_rw_ack_intr_grp3;
+#define REG_RD_ADDR_iop_sw_mpu_rw_ack_intr_grp3 148
+#define REG_WR_ADDR_iop_sw_mpu_rw_ack_intr_grp3 148
+
+/* Register r_intr_grp3, scope iop_sw_mpu, type r */
+typedef struct {
+  unsigned int spu0_intr12     : 1;
+  unsigned int spu1_intr12     : 1;
+  unsigned int trigger_grp0    : 1;
+  unsigned int trigger_grp7    : 1;
+  unsigned int timer_grp0      : 1;
+  unsigned int fifo_in1        : 1;
+  unsigned int fifo_in1_extra  : 1;
+  unsigned int dmc_out0        : 1;
+  unsigned int spu0_intr13     : 1;
+  unsigned int spu1_intr13     : 1;
+  unsigned int trigger_grp1    : 1;
+  unsigned int trigger_grp4    : 1;
+  unsigned int timer_grp1      : 1;
+  unsigned int fifo_out0       : 1;
+  unsigned int fifo_out0_extra : 1;
+  unsigned int dmc_in0         : 1;
+  unsigned int spu0_intr14     : 1;
+  unsigned int spu1_intr14     : 1;
+  unsigned int trigger_grp2    : 1;
+  unsigned int trigger_grp5    : 1;
+  unsigned int timer_grp2      : 1;
+  unsigned int fifo_in0        : 1;
+  unsigned int fifo_in0_extra  : 1;
+  unsigned int dmc_out1        : 1;
+  unsigned int spu0_intr15     : 1;
+  unsigned int spu1_intr15     : 1;
+  unsigned int trigger_grp3    : 1;
+  unsigned int trigger_grp6    : 1;
+  unsigned int timer_grp3      : 1;
+  unsigned int fifo_out1       : 1;
+  unsigned int fifo_out1_extra : 1;
+  unsigned int dmc_in1         : 1;
+} reg_iop_sw_mpu_r_intr_grp3;
+#define REG_RD_ADDR_iop_sw_mpu_r_intr_grp3 152
+
+/* Register r_masked_intr_grp3, scope iop_sw_mpu, type r */
+typedef struct {
+  unsigned int spu0_intr12     : 1;
+  unsigned int spu1_intr12     : 1;
+  unsigned int trigger_grp0    : 1;
+  unsigned int trigger_grp7    : 1;
+  unsigned int timer_grp0      : 1;
+  unsigned int fifo_in1        : 1;
+  unsigned int fifo_in1_extra  : 1;
+  unsigned int dmc_out0        : 1;
+  unsigned int spu0_intr13     : 1;
+  unsigned int spu1_intr13     : 1;
+  unsigned int trigger_grp1    : 1;
+  unsigned int trigger_grp4    : 1;
+  unsigned int timer_grp1      : 1;
+  unsigned int fifo_out0       : 1;
+  unsigned int fifo_out0_extra : 1;
+  unsigned int dmc_in0         : 1;
+  unsigned int spu0_intr14     : 1;
+  unsigned int spu1_intr14     : 1;
+  unsigned int trigger_grp2    : 1;
+  unsigned int trigger_grp5    : 1;
+  unsigned int timer_grp2      : 1;
+  unsigned int fifo_in0        : 1;
+  unsigned int fifo_in0_extra  : 1;
+  unsigned int dmc_out1        : 1;
+  unsigned int spu0_intr15     : 1;
+  unsigned int spu1_intr15     : 1;
+  unsigned int trigger_grp3    : 1;
+  unsigned int trigger_grp6    : 1;
+  unsigned int timer_grp3      : 1;
+  unsigned int fifo_out1       : 1;
+  unsigned int fifo_out1_extra : 1;
+  unsigned int dmc_in1         : 1;
+} reg_iop_sw_mpu_r_masked_intr_grp3;
+#define REG_RD_ADDR_iop_sw_mpu_r_masked_intr_grp3 156
+
+
+/* Constants */
+enum {
+  regk_iop_sw_mpu_copy                     = 0x00000000,
+  regk_iop_sw_mpu_cpu                      = 0x00000000,
+  regk_iop_sw_mpu_mpu                      = 0x00000001,
+  regk_iop_sw_mpu_no                       = 0x00000000,
+  regk_iop_sw_mpu_nop                      = 0x00000000,
+  regk_iop_sw_mpu_rd                       = 0x00000002,
+  regk_iop_sw_mpu_reg_copy                 = 0x00000001,
+  regk_iop_sw_mpu_rw_bus0_clr_mask_default = 0x00000000,
+  regk_iop_sw_mpu_rw_bus0_oe_clr_mask_default = 0x00000000,
+  regk_iop_sw_mpu_rw_bus0_oe_set_mask_default = 0x00000000,
+  regk_iop_sw_mpu_rw_bus0_set_mask_default = 0x00000000,
+  regk_iop_sw_mpu_rw_bus1_clr_mask_default = 0x00000000,
+  regk_iop_sw_mpu_rw_bus1_oe_clr_mask_default = 0x00000000,
+  regk_iop_sw_mpu_rw_bus1_oe_set_mask_default = 0x00000000,
+  regk_iop_sw_mpu_rw_bus1_set_mask_default = 0x00000000,
+  regk_iop_sw_mpu_rw_gio_clr_mask_default  = 0x00000000,
+  regk_iop_sw_mpu_rw_gio_oe_clr_mask_default = 0x00000000,
+  regk_iop_sw_mpu_rw_gio_oe_set_mask_default = 0x00000000,
+  regk_iop_sw_mpu_rw_gio_set_mask_default  = 0x00000000,
+  regk_iop_sw_mpu_rw_intr_grp0_mask_default = 0x00000000,
+  regk_iop_sw_mpu_rw_intr_grp1_mask_default = 0x00000000,
+  regk_iop_sw_mpu_rw_intr_grp2_mask_default = 0x00000000,
+  regk_iop_sw_mpu_rw_intr_grp3_mask_default = 0x00000000,
+  regk_iop_sw_mpu_rw_sw_cfg_owner_default  = 0x00000000,
+  regk_iop_sw_mpu_set                      = 0x00000001,
+  regk_iop_sw_mpu_spu0                     = 0x00000002,
+  regk_iop_sw_mpu_spu1                     = 0x00000003,
+  regk_iop_sw_mpu_wr                       = 0x00000003,
+  regk_iop_sw_mpu_yes                      = 0x00000001
+};
+#endif /* __iop_sw_mpu_defs_h */
diff --git a/include/asm-cris/arch-v32/hwregs/iop/iop_sw_spu_defs.h b/include/asm-cris/arch-v32/hwregs/iop/iop_sw_spu_defs.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/iop/iop_sw_spu_defs.h
@@ -0,0 +1,552 @@
+#ifndef __iop_sw_spu_defs_h
+#define __iop_sw_spu_defs_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/io_proc/rtl/guinness/iop_sw_spu.r
+ *     id:           <not found>
+ *     last modfied: Mon Apr 11 16:10:19 2005
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c --outfile iop_sw_spu_defs.h ../../inst/io_proc/rtl/guinness/iop_sw_spu.r
+ *      id: $Id: iop_sw_spu_defs.h,v 1.4 2005/04/24 18:31:05 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+/* Main access macros */
+#ifndef REG_RD
+#define REG_RD( scope, inst, reg ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR
+#define REG_WR( scope, inst, reg, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_VECT
+#define REG_RD_VECT( scope, inst, reg, index ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_VECT
+#define REG_WR_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT
+#define REG_RD_INT( scope, inst, reg ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT
+#define REG_WR_INT( scope, inst, reg, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT_VECT
+#define REG_RD_INT_VECT( scope, inst, reg, index ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT_VECT
+#define REG_WR_INT_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_TYPE_CONV
+#define REG_TYPE_CONV( type, orgtype, val ) \
+  ( { union { orgtype o; type n; } r; r.o = val; r.n; } )
+#endif
+
+#ifndef reg_page_size
+#define reg_page_size 8192
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg + \
+    (index) * STRIDE_##scope##_##reg )
+#endif
+
+/* C-code for register scope iop_sw_spu */
+
+/* Register rw_mc_ctrl, scope iop_sw_spu, type rw */
+typedef struct {
+  unsigned int keep_owner  : 1;
+  unsigned int cmd         : 2;
+  unsigned int size        : 3;
+  unsigned int wr_spu0_mem : 1;
+  unsigned int wr_spu1_mem : 1;
+  unsigned int dummy1      : 24;
+} reg_iop_sw_spu_rw_mc_ctrl;
+#define REG_RD_ADDR_iop_sw_spu_rw_mc_ctrl 0
+#define REG_WR_ADDR_iop_sw_spu_rw_mc_ctrl 0
+
+/* Register rw_mc_data, scope iop_sw_spu, type rw */
+typedef struct {
+  unsigned int val : 32;
+} reg_iop_sw_spu_rw_mc_data;
+#define REG_RD_ADDR_iop_sw_spu_rw_mc_data 4
+#define REG_WR_ADDR_iop_sw_spu_rw_mc_data 4
+
+/* Register rw_mc_addr, scope iop_sw_spu, type rw */
+typedef unsigned int reg_iop_sw_spu_rw_mc_addr;
+#define REG_RD_ADDR_iop_sw_spu_rw_mc_addr 8
+#define REG_WR_ADDR_iop_sw_spu_rw_mc_addr 8
+
+/* Register rs_mc_data, scope iop_sw_spu, type rs */
+typedef unsigned int reg_iop_sw_spu_rs_mc_data;
+#define REG_RD_ADDR_iop_sw_spu_rs_mc_data 12
+
+/* Register r_mc_data, scope iop_sw_spu, type r */
+typedef unsigned int reg_iop_sw_spu_r_mc_data;
+#define REG_RD_ADDR_iop_sw_spu_r_mc_data 16
+
+/* Register r_mc_stat, scope iop_sw_spu, type r */
+typedef struct {
+  unsigned int busy_cpu      : 1;
+  unsigned int busy_mpu      : 1;
+  unsigned int busy_spu0     : 1;
+  unsigned int busy_spu1     : 1;
+  unsigned int owned_by_cpu  : 1;
+  unsigned int owned_by_mpu  : 1;
+  unsigned int owned_by_spu0 : 1;
+  unsigned int owned_by_spu1 : 1;
+  unsigned int dummy1        : 24;
+} reg_iop_sw_spu_r_mc_stat;
+#define REG_RD_ADDR_iop_sw_spu_r_mc_stat 20
+
+/* Register rw_bus0_clr_mask, scope iop_sw_spu, type rw */
+typedef struct {
+  unsigned int byte0 : 8;
+  unsigned int byte1 : 8;
+  unsigned int byte2 : 8;
+  unsigned int byte3 : 8;
+} reg_iop_sw_spu_rw_bus0_clr_mask;
+#define REG_RD_ADDR_iop_sw_spu_rw_bus0_clr_mask 24
+#define REG_WR_ADDR_iop_sw_spu_rw_bus0_clr_mask 24
+
+/* Register rw_bus0_set_mask, scope iop_sw_spu, type rw */
+typedef struct {
+  unsigned int byte0 : 8;
+  unsigned int byte1 : 8;
+  unsigned int byte2 : 8;
+  unsigned int byte3 : 8;
+} reg_iop_sw_spu_rw_bus0_set_mask;
+#define REG_RD_ADDR_iop_sw_spu_rw_bus0_set_mask 28
+#define REG_WR_ADDR_iop_sw_spu_rw_bus0_set_mask 28
+
+/* Register rw_bus0_oe_clr_mask, scope iop_sw_spu, type rw */
+typedef struct {
+  unsigned int byte0 : 1;
+  unsigned int byte1 : 1;
+  unsigned int byte2 : 1;
+  unsigned int byte3 : 1;
+  unsigned int dummy1 : 28;
+} reg_iop_sw_spu_rw_bus0_oe_clr_mask;
+#define REG_RD_ADDR_iop_sw_spu_rw_bus0_oe_clr_mask 32
+#define REG_WR_ADDR_iop_sw_spu_rw_bus0_oe_clr_mask 32
+
+/* Register rw_bus0_oe_set_mask, scope iop_sw_spu, type rw */
+typedef struct {
+  unsigned int byte0 : 1;
+  unsigned int byte1 : 1;
+  unsigned int byte2 : 1;
+  unsigned int byte3 : 1;
+  unsigned int dummy1 : 28;
+} reg_iop_sw_spu_rw_bus0_oe_set_mask;
+#define REG_RD_ADDR_iop_sw_spu_rw_bus0_oe_set_mask 36
+#define REG_WR_ADDR_iop_sw_spu_rw_bus0_oe_set_mask 36
+
+/* Register r_bus0_in, scope iop_sw_spu, type r */
+typedef unsigned int reg_iop_sw_spu_r_bus0_in;
+#define REG_RD_ADDR_iop_sw_spu_r_bus0_in 40
+
+/* Register rw_bus1_clr_mask, scope iop_sw_spu, type rw */
+typedef struct {
+  unsigned int byte0 : 8;
+  unsigned int byte1 : 8;
+  unsigned int byte2 : 8;
+  unsigned int byte3 : 8;
+} reg_iop_sw_spu_rw_bus1_clr_mask;
+#define REG_RD_ADDR_iop_sw_spu_rw_bus1_clr_mask 44
+#define REG_WR_ADDR_iop_sw_spu_rw_bus1_clr_mask 44
+
+/* Register rw_bus1_set_mask, scope iop_sw_spu, type rw */
+typedef struct {
+  unsigned int byte0 : 8;
+  unsigned int byte1 : 8;
+  unsigned int byte2 : 8;
+  unsigned int byte3 : 8;
+} reg_iop_sw_spu_rw_bus1_set_mask;
+#define REG_RD_ADDR_iop_sw_spu_rw_bus1_set_mask 48
+#define REG_WR_ADDR_iop_sw_spu_rw_bus1_set_mask 48
+
+/* Register rw_bus1_oe_clr_mask, scope iop_sw_spu, type rw */
+typedef struct {
+  unsigned int byte0 : 1;
+  unsigned int byte1 : 1;
+  unsigned int byte2 : 1;
+  unsigned int byte3 : 1;
+  unsigned int dummy1 : 28;
+} reg_iop_sw_spu_rw_bus1_oe_clr_mask;
+#define REG_RD_ADDR_iop_sw_spu_rw_bus1_oe_clr_mask 52
+#define REG_WR_ADDR_iop_sw_spu_rw_bus1_oe_clr_mask 52
+
+/* Register rw_bus1_oe_set_mask, scope iop_sw_spu, type rw */
+typedef struct {
+  unsigned int byte0 : 1;
+  unsigned int byte1 : 1;
+  unsigned int byte2 : 1;
+  unsigned int byte3 : 1;
+  unsigned int dummy1 : 28;
+} reg_iop_sw_spu_rw_bus1_oe_set_mask;
+#define REG_RD_ADDR_iop_sw_spu_rw_bus1_oe_set_mask 56
+#define REG_WR_ADDR_iop_sw_spu_rw_bus1_oe_set_mask 56
+
+/* Register r_bus1_in, scope iop_sw_spu, type r */
+typedef unsigned int reg_iop_sw_spu_r_bus1_in;
+#define REG_RD_ADDR_iop_sw_spu_r_bus1_in 60
+
+/* Register rw_gio_clr_mask, scope iop_sw_spu, type rw */
+typedef struct {
+  unsigned int val : 32;
+} reg_iop_sw_spu_rw_gio_clr_mask;
+#define REG_RD_ADDR_iop_sw_spu_rw_gio_clr_mask 64
+#define REG_WR_ADDR_iop_sw_spu_rw_gio_clr_mask 64
+
+/* Register rw_gio_set_mask, scope iop_sw_spu, type rw */
+typedef struct {
+  unsigned int val : 32;
+} reg_iop_sw_spu_rw_gio_set_mask;
+#define REG_RD_ADDR_iop_sw_spu_rw_gio_set_mask 68
+#define REG_WR_ADDR_iop_sw_spu_rw_gio_set_mask 68
+
+/* Register rw_gio_oe_clr_mask, scope iop_sw_spu, type rw */
+typedef struct {
+  unsigned int val : 32;
+} reg_iop_sw_spu_rw_gio_oe_clr_mask;
+#define REG_RD_ADDR_iop_sw_spu_rw_gio_oe_clr_mask 72
+#define REG_WR_ADDR_iop_sw_spu_rw_gio_oe_clr_mask 72
+
+/* Register rw_gio_oe_set_mask, scope iop_sw_spu, type rw */
+typedef struct {
+  unsigned int val : 32;
+} reg_iop_sw_spu_rw_gio_oe_set_mask;
+#define REG_RD_ADDR_iop_sw_spu_rw_gio_oe_set_mask 76
+#define REG_WR_ADDR_iop_sw_spu_rw_gio_oe_set_mask 76
+
+/* Register r_gio_in, scope iop_sw_spu, type r */
+typedef unsigned int reg_iop_sw_spu_r_gio_in;
+#define REG_RD_ADDR_iop_sw_spu_r_gio_in 80
+
+/* Register rw_bus0_clr_mask_lo, scope iop_sw_spu, type rw */
+typedef struct {
+  unsigned int byte0 : 8;
+  unsigned int byte1 : 8;
+  unsigned int dummy1 : 16;
+} reg_iop_sw_spu_rw_bus0_clr_mask_lo;
+#define REG_RD_ADDR_iop_sw_spu_rw_bus0_clr_mask_lo 84
+#define REG_WR_ADDR_iop_sw_spu_rw_bus0_clr_mask_lo 84
+
+/* Register rw_bus0_clr_mask_hi, scope iop_sw_spu, type rw */
+typedef struct {
+  unsigned int byte2 : 8;
+  unsigned int byte3 : 8;
+  unsigned int dummy1 : 16;
+} reg_iop_sw_spu_rw_bus0_clr_mask_hi;
+#define REG_RD_ADDR_iop_sw_spu_rw_bus0_clr_mask_hi 88
+#define REG_WR_ADDR_iop_sw_spu_rw_bus0_clr_mask_hi 88
+
+/* Register rw_bus0_set_mask_lo, scope iop_sw_spu, type rw */
+typedef struct {
+  unsigned int byte0 : 8;
+  unsigned int byte1 : 8;
+  unsigned int dummy1 : 16;
+} reg_iop_sw_spu_rw_bus0_set_mask_lo;
+#define REG_RD_ADDR_iop_sw_spu_rw_bus0_set_mask_lo 92
+#define REG_WR_ADDR_iop_sw_spu_rw_bus0_set_mask_lo 92
+
+/* Register rw_bus0_set_mask_hi, scope iop_sw_spu, type rw */
+typedef struct {
+  unsigned int byte2 : 8;
+  unsigned int byte3 : 8;
+  unsigned int dummy1 : 16;
+} reg_iop_sw_spu_rw_bus0_set_mask_hi;
+#define REG_RD_ADDR_iop_sw_spu_rw_bus0_set_mask_hi 96
+#define REG_WR_ADDR_iop_sw_spu_rw_bus0_set_mask_hi 96
+
+/* Register rw_bus1_clr_mask_lo, scope iop_sw_spu, type rw */
+typedef struct {
+  unsigned int byte0 : 8;
+  unsigned int byte1 : 8;
+  unsigned int dummy1 : 16;
+} reg_iop_sw_spu_rw_bus1_clr_mask_lo;
+#define REG_RD_ADDR_iop_sw_spu_rw_bus1_clr_mask_lo 100
+#define REG_WR_ADDR_iop_sw_spu_rw_bus1_clr_mask_lo 100
+
+/* Register rw_bus1_clr_mask_hi, scope iop_sw_spu, type rw */
+typedef struct {
+  unsigned int byte2 : 8;
+  unsigned int byte3 : 8;
+  unsigned int dummy1 : 16;
+} reg_iop_sw_spu_rw_bus1_clr_mask_hi;
+#define REG_RD_ADDR_iop_sw_spu_rw_bus1_clr_mask_hi 104
+#define REG_WR_ADDR_iop_sw_spu_rw_bus1_clr_mask_hi 104
+
+/* Register rw_bus1_set_mask_lo, scope iop_sw_spu, type rw */
+typedef struct {
+  unsigned int byte0 : 8;
+  unsigned int byte1 : 8;
+  unsigned int dummy1 : 16;
+} reg_iop_sw_spu_rw_bus1_set_mask_lo;
+#define REG_RD_ADDR_iop_sw_spu_rw_bus1_set_mask_lo 108
+#define REG_WR_ADDR_iop_sw_spu_rw_bus1_set_mask_lo 108
+
+/* Register rw_bus1_set_mask_hi, scope iop_sw_spu, type rw */
+typedef struct {
+  unsigned int byte2 : 8;
+  unsigned int byte3 : 8;
+  unsigned int dummy1 : 16;
+} reg_iop_sw_spu_rw_bus1_set_mask_hi;
+#define REG_RD_ADDR_iop_sw_spu_rw_bus1_set_mask_hi 112
+#define REG_WR_ADDR_iop_sw_spu_rw_bus1_set_mask_hi 112
+
+/* Register rw_gio_clr_mask_lo, scope iop_sw_spu, type rw */
+typedef struct {
+  unsigned int val : 16;
+  unsigned int dummy1 : 16;
+} reg_iop_sw_spu_rw_gio_clr_mask_lo;
+#define REG_RD_ADDR_iop_sw_spu_rw_gio_clr_mask_lo 116
+#define REG_WR_ADDR_iop_sw_spu_rw_gio_clr_mask_lo 116
+
+/* Register rw_gio_clr_mask_hi, scope iop_sw_spu, type rw */
+typedef struct {
+  unsigned int val : 16;
+  unsigned int dummy1 : 16;
+} reg_iop_sw_spu_rw_gio_clr_mask_hi;
+#define REG_RD_ADDR_iop_sw_spu_rw_gio_clr_mask_hi 120
+#define REG_WR_ADDR_iop_sw_spu_rw_gio_clr_mask_hi 120
+
+/* Register rw_gio_set_mask_lo, scope iop_sw_spu, type rw */
+typedef struct {
+  unsigned int val : 16;
+  unsigned int dummy1 : 16;
+} reg_iop_sw_spu_rw_gio_set_mask_lo;
+#define REG_RD_ADDR_iop_sw_spu_rw_gio_set_mask_lo 124
+#define REG_WR_ADDR_iop_sw_spu_rw_gio_set_mask_lo 124
+
+/* Register rw_gio_set_mask_hi, scope iop_sw_spu, type rw */
+typedef struct {
+  unsigned int val : 16;
+  unsigned int dummy1 : 16;
+} reg_iop_sw_spu_rw_gio_set_mask_hi;
+#define REG_RD_ADDR_iop_sw_spu_rw_gio_set_mask_hi 128
+#define REG_WR_ADDR_iop_sw_spu_rw_gio_set_mask_hi 128
+
+/* Register rw_gio_oe_clr_mask_lo, scope iop_sw_spu, type rw */
+typedef struct {
+  unsigned int val : 16;
+  unsigned int dummy1 : 16;
+} reg_iop_sw_spu_rw_gio_oe_clr_mask_lo;
+#define REG_RD_ADDR_iop_sw_spu_rw_gio_oe_clr_mask_lo 132
+#define REG_WR_ADDR_iop_sw_spu_rw_gio_oe_clr_mask_lo 132
+
+/* Register rw_gio_oe_clr_mask_hi, scope iop_sw_spu, type rw */
+typedef struct {
+  unsigned int val : 16;
+  unsigned int dummy1 : 16;
+} reg_iop_sw_spu_rw_gio_oe_clr_mask_hi;
+#define REG_RD_ADDR_iop_sw_spu_rw_gio_oe_clr_mask_hi 136
+#define REG_WR_ADDR_iop_sw_spu_rw_gio_oe_clr_mask_hi 136
+
+/* Register rw_gio_oe_set_mask_lo, scope iop_sw_spu, type rw */
+typedef struct {
+  unsigned int val : 16;
+  unsigned int dummy1 : 16;
+} reg_iop_sw_spu_rw_gio_oe_set_mask_lo;
+#define REG_RD_ADDR_iop_sw_spu_rw_gio_oe_set_mask_lo 140
+#define REG_WR_ADDR_iop_sw_spu_rw_gio_oe_set_mask_lo 140
+
+/* Register rw_gio_oe_set_mask_hi, scope iop_sw_spu, type rw */
+typedef struct {
+  unsigned int val : 16;
+  unsigned int dummy1 : 16;
+} reg_iop_sw_spu_rw_gio_oe_set_mask_hi;
+#define REG_RD_ADDR_iop_sw_spu_rw_gio_oe_set_mask_hi 144
+#define REG_WR_ADDR_iop_sw_spu_rw_gio_oe_set_mask_hi 144
+
+/* Register rw_cpu_intr, scope iop_sw_spu, type rw */
+typedef struct {
+  unsigned int intr0  : 1;
+  unsigned int intr1  : 1;
+  unsigned int intr2  : 1;
+  unsigned int intr3  : 1;
+  unsigned int intr4  : 1;
+  unsigned int intr5  : 1;
+  unsigned int intr6  : 1;
+  unsigned int intr7  : 1;
+  unsigned int intr8  : 1;
+  unsigned int intr9  : 1;
+  unsigned int intr10 : 1;
+  unsigned int intr11 : 1;
+  unsigned int intr12 : 1;
+  unsigned int intr13 : 1;
+  unsigned int intr14 : 1;
+  unsigned int intr15 : 1;
+  unsigned int dummy1 : 16;
+} reg_iop_sw_spu_rw_cpu_intr;
+#define REG_RD_ADDR_iop_sw_spu_rw_cpu_intr 148
+#define REG_WR_ADDR_iop_sw_spu_rw_cpu_intr 148
+
+/* Register r_cpu_intr, scope iop_sw_spu, type r */
+typedef struct {
+  unsigned int intr0  : 1;
+  unsigned int intr1  : 1;
+  unsigned int intr2  : 1;
+  unsigned int intr3  : 1;
+  unsigned int intr4  : 1;
+  unsigned int intr5  : 1;
+  unsigned int intr6  : 1;
+  unsigned int intr7  : 1;
+  unsigned int intr8  : 1;
+  unsigned int intr9  : 1;
+  unsigned int intr10 : 1;
+  unsigned int intr11 : 1;
+  unsigned int intr12 : 1;
+  unsigned int intr13 : 1;
+  unsigned int intr14 : 1;
+  unsigned int intr15 : 1;
+  unsigned int dummy1 : 16;
+} reg_iop_sw_spu_r_cpu_intr;
+#define REG_RD_ADDR_iop_sw_spu_r_cpu_intr 152
+
+/* Register r_hw_intr, scope iop_sw_spu, type r */
+typedef struct {
+  unsigned int trigger_grp0    : 1;
+  unsigned int trigger_grp1    : 1;
+  unsigned int trigger_grp2    : 1;
+  unsigned int trigger_grp3    : 1;
+  unsigned int trigger_grp4    : 1;
+  unsigned int trigger_grp5    : 1;
+  unsigned int trigger_grp6    : 1;
+  unsigned int trigger_grp7    : 1;
+  unsigned int timer_grp0      : 1;
+  unsigned int timer_grp1      : 1;
+  unsigned int timer_grp2      : 1;
+  unsigned int timer_grp3      : 1;
+  unsigned int fifo_out0       : 1;
+  unsigned int fifo_out0_extra : 1;
+  unsigned int fifo_in0        : 1;
+  unsigned int fifo_in0_extra  : 1;
+  unsigned int fifo_out1       : 1;
+  unsigned int fifo_out1_extra : 1;
+  unsigned int fifo_in1        : 1;
+  unsigned int fifo_in1_extra  : 1;
+  unsigned int dmc_out0        : 1;
+  unsigned int dmc_in0         : 1;
+  unsigned int dmc_out1        : 1;
+  unsigned int dmc_in1         : 1;
+  unsigned int dummy1          : 8;
+} reg_iop_sw_spu_r_hw_intr;
+#define REG_RD_ADDR_iop_sw_spu_r_hw_intr 156
+
+/* Register rw_mpu_intr, scope iop_sw_spu, type rw */
+typedef struct {
+  unsigned int intr0  : 1;
+  unsigned int intr1  : 1;
+  unsigned int intr2  : 1;
+  unsigned int intr3  : 1;
+  unsigned int intr4  : 1;
+  unsigned int intr5  : 1;
+  unsigned int intr6  : 1;
+  unsigned int intr7  : 1;
+  unsigned int intr8  : 1;
+  unsigned int intr9  : 1;
+  unsigned int intr10 : 1;
+  unsigned int intr11 : 1;
+  unsigned int intr12 : 1;
+  unsigned int intr13 : 1;
+  unsigned int intr14 : 1;
+  unsigned int intr15 : 1;
+  unsigned int dummy1 : 16;
+} reg_iop_sw_spu_rw_mpu_intr;
+#define REG_RD_ADDR_iop_sw_spu_rw_mpu_intr 160
+#define REG_WR_ADDR_iop_sw_spu_rw_mpu_intr 160
+
+/* Register r_mpu_intr, scope iop_sw_spu, type r */
+typedef struct {
+  unsigned int intr0            : 1;
+  unsigned int intr1            : 1;
+  unsigned int intr2            : 1;
+  unsigned int intr3            : 1;
+  unsigned int intr4            : 1;
+  unsigned int intr5            : 1;
+  unsigned int intr6            : 1;
+  unsigned int intr7            : 1;
+  unsigned int intr8            : 1;
+  unsigned int intr9            : 1;
+  unsigned int intr10           : 1;
+  unsigned int intr11           : 1;
+  unsigned int intr12           : 1;
+  unsigned int intr13           : 1;
+  unsigned int intr14           : 1;
+  unsigned int intr15           : 1;
+  unsigned int other_spu_intr0  : 1;
+  unsigned int other_spu_intr1  : 1;
+  unsigned int other_spu_intr2  : 1;
+  unsigned int other_spu_intr3  : 1;
+  unsigned int other_spu_intr4  : 1;
+  unsigned int other_spu_intr5  : 1;
+  unsigned int other_spu_intr6  : 1;
+  unsigned int other_spu_intr7  : 1;
+  unsigned int other_spu_intr8  : 1;
+  unsigned int other_spu_intr9  : 1;
+  unsigned int other_spu_intr10 : 1;
+  unsigned int other_spu_intr11 : 1;
+  unsigned int other_spu_intr12 : 1;
+  unsigned int other_spu_intr13 : 1;
+  unsigned int other_spu_intr14 : 1;
+  unsigned int other_spu_intr15 : 1;
+} reg_iop_sw_spu_r_mpu_intr;
+#define REG_RD_ADDR_iop_sw_spu_r_mpu_intr 164
+
+
+/* Constants */
+enum {
+  regk_iop_sw_spu_copy                     = 0x00000000,
+  regk_iop_sw_spu_no                       = 0x00000000,
+  regk_iop_sw_spu_nop                      = 0x00000000,
+  regk_iop_sw_spu_rd                       = 0x00000002,
+  regk_iop_sw_spu_reg_copy                 = 0x00000001,
+  regk_iop_sw_spu_rw_bus0_clr_mask_default = 0x00000000,
+  regk_iop_sw_spu_rw_bus0_oe_clr_mask_default = 0x00000000,
+  regk_iop_sw_spu_rw_bus0_oe_set_mask_default = 0x00000000,
+  regk_iop_sw_spu_rw_bus0_set_mask_default = 0x00000000,
+  regk_iop_sw_spu_rw_bus1_clr_mask_default = 0x00000000,
+  regk_iop_sw_spu_rw_bus1_oe_clr_mask_default = 0x00000000,
+  regk_iop_sw_spu_rw_bus1_oe_set_mask_default = 0x00000000,
+  regk_iop_sw_spu_rw_bus1_set_mask_default = 0x00000000,
+  regk_iop_sw_spu_rw_gio_clr_mask_default  = 0x00000000,
+  regk_iop_sw_spu_rw_gio_oe_clr_mask_default = 0x00000000,
+  regk_iop_sw_spu_rw_gio_oe_set_mask_default = 0x00000000,
+  regk_iop_sw_spu_rw_gio_set_mask_default  = 0x00000000,
+  regk_iop_sw_spu_set                      = 0x00000001,
+  regk_iop_sw_spu_wr                       = 0x00000003,
+  regk_iop_sw_spu_yes                      = 0x00000001
+};
+#endif /* __iop_sw_spu_defs_h */
diff --git a/include/asm-cris/arch-v32/hwregs/iop/iop_timer_grp_defs.h b/include/asm-cris/arch-v32/hwregs/iop/iop_timer_grp_defs.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/iop/iop_timer_grp_defs.h
@@ -0,0 +1,249 @@
+#ifndef __iop_timer_grp_defs_h
+#define __iop_timer_grp_defs_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/io_proc/rtl/iop_timer_grp.r
+ *     id:           iop_timer_grp.r,v 1.29 2005/02/16 09:13:27 niklaspa Exp
+ *     last modfied: Mon Apr 11 16:08:46 2005
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c --outfile iop_timer_grp_defs.h ../../inst/io_proc/rtl/iop_timer_grp.r
+ *      id: $Id: iop_timer_grp_defs.h,v 1.5 2005/04/24 18:31:05 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+/* Main access macros */
+#ifndef REG_RD
+#define REG_RD( scope, inst, reg ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR
+#define REG_WR( scope, inst, reg, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_VECT
+#define REG_RD_VECT( scope, inst, reg, index ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_VECT
+#define REG_WR_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT
+#define REG_RD_INT( scope, inst, reg ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT
+#define REG_WR_INT( scope, inst, reg, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT_VECT
+#define REG_RD_INT_VECT( scope, inst, reg, index ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT_VECT
+#define REG_WR_INT_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_TYPE_CONV
+#define REG_TYPE_CONV( type, orgtype, val ) \
+  ( { union { orgtype o; type n; } r; r.o = val; r.n; } )
+#endif
+
+#ifndef reg_page_size
+#define reg_page_size 8192
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg + \
+    (index) * STRIDE_##scope##_##reg )
+#endif
+
+/* C-code for register scope iop_timer_grp */
+
+/* Register rw_cfg, scope iop_timer_grp, type rw */
+typedef struct {
+  unsigned int clk_src     : 1;
+  unsigned int trig        : 2;
+  unsigned int clk_gen_div : 8;
+  unsigned int clk_div     : 8;
+  unsigned int dummy1      : 13;
+} reg_iop_timer_grp_rw_cfg;
+#define REG_RD_ADDR_iop_timer_grp_rw_cfg 0
+#define REG_WR_ADDR_iop_timer_grp_rw_cfg 0
+
+/* Register rw_half_period, scope iop_timer_grp, type rw */
+typedef struct {
+  unsigned int quota_lo     : 15;
+  unsigned int quota_hi     : 15;
+  unsigned int quota_hi_sel : 1;
+  unsigned int dummy1       : 1;
+} reg_iop_timer_grp_rw_half_period;
+#define REG_RD_ADDR_iop_timer_grp_rw_half_period 4
+#define REG_WR_ADDR_iop_timer_grp_rw_half_period 4
+
+/* Register rw_half_period_len, scope iop_timer_grp, type rw */
+typedef unsigned int reg_iop_timer_grp_rw_half_period_len;
+#define REG_RD_ADDR_iop_timer_grp_rw_half_period_len 8
+#define REG_WR_ADDR_iop_timer_grp_rw_half_period_len 8
+
+#define STRIDE_iop_timer_grp_rw_tmr_cfg 4
+/* Register rw_tmr_cfg, scope iop_timer_grp, type rw */
+typedef struct {
+  unsigned int clk_src         : 3;
+  unsigned int strb            : 2;
+  unsigned int run_mode        : 2;
+  unsigned int out_mode        : 1;
+  unsigned int active_on_tmr   : 2;
+  unsigned int inv             : 1;
+  unsigned int en_by_tmr       : 2;
+  unsigned int dis_by_tmr      : 2;
+  unsigned int en_only_by_reg  : 1;
+  unsigned int dis_only_by_reg : 1;
+  unsigned int rst_at_en_strb  : 1;
+  unsigned int dummy1          : 14;
+} reg_iop_timer_grp_rw_tmr_cfg;
+#define REG_RD_ADDR_iop_timer_grp_rw_tmr_cfg 12
+#define REG_WR_ADDR_iop_timer_grp_rw_tmr_cfg 12
+
+#define STRIDE_iop_timer_grp_rw_tmr_len 4
+/* Register rw_tmr_len, scope iop_timer_grp, type rw */
+typedef struct {
+  unsigned int val : 16;
+  unsigned int dummy1 : 16;
+} reg_iop_timer_grp_rw_tmr_len;
+#define REG_RD_ADDR_iop_timer_grp_rw_tmr_len 44
+#define REG_WR_ADDR_iop_timer_grp_rw_tmr_len 44
+
+/* Register rw_cmd, scope iop_timer_grp, type rw */
+typedef struct {
+  unsigned int rst  : 4;
+  unsigned int en   : 4;
+  unsigned int dis  : 4;
+  unsigned int strb : 4;
+  unsigned int dummy1 : 16;
+} reg_iop_timer_grp_rw_cmd;
+#define REG_RD_ADDR_iop_timer_grp_rw_cmd 60
+#define REG_WR_ADDR_iop_timer_grp_rw_cmd 60
+
+/* Register r_clk_gen_cnt, scope iop_timer_grp, type r */
+typedef unsigned int reg_iop_timer_grp_r_clk_gen_cnt;
+#define REG_RD_ADDR_iop_timer_grp_r_clk_gen_cnt 64
+
+#define STRIDE_iop_timer_grp_rs_tmr_cnt 8
+/* Register rs_tmr_cnt, scope iop_timer_grp, type rs */
+typedef struct {
+  unsigned int val : 16;
+  unsigned int dummy1 : 16;
+} reg_iop_timer_grp_rs_tmr_cnt;
+#define REG_RD_ADDR_iop_timer_grp_rs_tmr_cnt 68
+
+#define STRIDE_iop_timer_grp_r_tmr_cnt 8
+/* Register r_tmr_cnt, scope iop_timer_grp, type r */
+typedef struct {
+  unsigned int val : 16;
+  unsigned int dummy1 : 16;
+} reg_iop_timer_grp_r_tmr_cnt;
+#define REG_RD_ADDR_iop_timer_grp_r_tmr_cnt 72
+
+/* Register rw_intr_mask, scope iop_timer_grp, type rw */
+typedef struct {
+  unsigned int tmr0 : 1;
+  unsigned int tmr1 : 1;
+  unsigned int tmr2 : 1;
+  unsigned int tmr3 : 1;
+  unsigned int dummy1 : 28;
+} reg_iop_timer_grp_rw_intr_mask;
+#define REG_RD_ADDR_iop_timer_grp_rw_intr_mask 100
+#define REG_WR_ADDR_iop_timer_grp_rw_intr_mask 100
+
+/* Register rw_ack_intr, scope iop_timer_grp, type rw */
+typedef struct {
+  unsigned int tmr0 : 1;
+  unsigned int tmr1 : 1;
+  unsigned int tmr2 : 1;
+  unsigned int tmr3 : 1;
+  unsigned int dummy1 : 28;
+} reg_iop_timer_grp_rw_ack_intr;
+#define REG_RD_ADDR_iop_timer_grp_rw_ack_intr 104
+#define REG_WR_ADDR_iop_timer_grp_rw_ack_intr 104
+
+/* Register r_intr, scope iop_timer_grp, type r */
+typedef struct {
+  unsigned int tmr0 : 1;
+  unsigned int tmr1 : 1;
+  unsigned int tmr2 : 1;
+  unsigned int tmr3 : 1;
+  unsigned int dummy1 : 28;
+} reg_iop_timer_grp_r_intr;
+#define REG_RD_ADDR_iop_timer_grp_r_intr 108
+
+/* Register r_masked_intr, scope iop_timer_grp, type r */
+typedef struct {
+  unsigned int tmr0 : 1;
+  unsigned int tmr1 : 1;
+  unsigned int tmr2 : 1;
+  unsigned int tmr3 : 1;
+  unsigned int dummy1 : 28;
+} reg_iop_timer_grp_r_masked_intr;
+#define REG_RD_ADDR_iop_timer_grp_r_masked_intr 112
+
+
+/* Constants */
+enum {
+  regk_iop_timer_grp_clk200                = 0x00000000,
+  regk_iop_timer_grp_clk_gen               = 0x00000002,
+  regk_iop_timer_grp_complete              = 0x00000002,
+  regk_iop_timer_grp_div_clk200            = 0x00000001,
+  regk_iop_timer_grp_div_clk_gen           = 0x00000003,
+  regk_iop_timer_grp_ext                   = 0x00000001,
+  regk_iop_timer_grp_hi                    = 0x00000000,
+  regk_iop_timer_grp_long_period           = 0x00000001,
+  regk_iop_timer_grp_neg                   = 0x00000002,
+  regk_iop_timer_grp_no                    = 0x00000000,
+  regk_iop_timer_grp_once                  = 0x00000003,
+  regk_iop_timer_grp_pause                 = 0x00000001,
+  regk_iop_timer_grp_pos                   = 0x00000001,
+  regk_iop_timer_grp_pos_neg               = 0x00000003,
+  regk_iop_timer_grp_pulse                 = 0x00000000,
+  regk_iop_timer_grp_r_tmr_cnt_size        = 0x00000004,
+  regk_iop_timer_grp_rs_tmr_cnt_size       = 0x00000004,
+  regk_iop_timer_grp_rw_cfg_default        = 0x00000002,
+  regk_iop_timer_grp_rw_intr_mask_default  = 0x00000000,
+  regk_iop_timer_grp_rw_tmr_cfg_default0   = 0x00018000,
+  regk_iop_timer_grp_rw_tmr_cfg_default1   = 0x0001a900,
+  regk_iop_timer_grp_rw_tmr_cfg_default2   = 0x0001d200,
+  regk_iop_timer_grp_rw_tmr_cfg_default3   = 0x0001fb00,
+  regk_iop_timer_grp_rw_tmr_cfg_size       = 0x00000004,
+  regk_iop_timer_grp_rw_tmr_len_default    = 0x00000000,
+  regk_iop_timer_grp_rw_tmr_len_size       = 0x00000004,
+  regk_iop_timer_grp_short_period          = 0x00000000,
+  regk_iop_timer_grp_stop                  = 0x00000000,
+  regk_iop_timer_grp_tmr                   = 0x00000004,
+  regk_iop_timer_grp_toggle                = 0x00000001,
+  regk_iop_timer_grp_yes                   = 0x00000001
+};
+#endif /* __iop_timer_grp_defs_h */
diff --git a/include/asm-cris/arch-v32/hwregs/iop/iop_trigger_grp_defs.h b/include/asm-cris/arch-v32/hwregs/iop/iop_trigger_grp_defs.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/iop/iop_trigger_grp_defs.h
@@ -0,0 +1,170 @@
+#ifndef __iop_trigger_grp_defs_h
+#define __iop_trigger_grp_defs_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/io_proc/rtl/iop_trigger_grp.r
+ *     id:           iop_trigger_grp.r,v 0.20 2005/02/16 09:13:20 niklaspa Exp
+ *     last modfied: Mon Apr 11 16:08:46 2005
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c --outfile iop_trigger_grp_defs.h ../../inst/io_proc/rtl/iop_trigger_grp.r
+ *      id: $Id: iop_trigger_grp_defs.h,v 1.5 2005/04/24 18:31:05 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+/* Main access macros */
+#ifndef REG_RD
+#define REG_RD( scope, inst, reg ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR
+#define REG_WR( scope, inst, reg, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_VECT
+#define REG_RD_VECT( scope, inst, reg, index ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_VECT
+#define REG_WR_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT
+#define REG_RD_INT( scope, inst, reg ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT
+#define REG_WR_INT( scope, inst, reg, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT_VECT
+#define REG_RD_INT_VECT( scope, inst, reg, index ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT_VECT
+#define REG_WR_INT_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_TYPE_CONV
+#define REG_TYPE_CONV( type, orgtype, val ) \
+  ( { union { orgtype o; type n; } r; r.o = val; r.n; } )
+#endif
+
+#ifndef reg_page_size
+#define reg_page_size 8192
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg + \
+    (index) * STRIDE_##scope##_##reg )
+#endif
+
+/* C-code for register scope iop_trigger_grp */
+
+#define STRIDE_iop_trigger_grp_rw_cfg 4
+/* Register rw_cfg, scope iop_trigger_grp, type rw */
+typedef struct {
+  unsigned int action          : 2;
+  unsigned int once            : 1;
+  unsigned int trig            : 3;
+  unsigned int en_only_by_reg  : 1;
+  unsigned int dis_only_by_reg : 1;
+  unsigned int dummy1          : 24;
+} reg_iop_trigger_grp_rw_cfg;
+#define REG_RD_ADDR_iop_trigger_grp_rw_cfg 0
+#define REG_WR_ADDR_iop_trigger_grp_rw_cfg 0
+
+/* Register rw_cmd, scope iop_trigger_grp, type rw */
+typedef struct {
+  unsigned int dis : 4;
+  unsigned int en  : 4;
+  unsigned int dummy1 : 24;
+} reg_iop_trigger_grp_rw_cmd;
+#define REG_RD_ADDR_iop_trigger_grp_rw_cmd 16
+#define REG_WR_ADDR_iop_trigger_grp_rw_cmd 16
+
+/* Register rw_intr_mask, scope iop_trigger_grp, type rw */
+typedef struct {
+  unsigned int trig0 : 1;
+  unsigned int trig1 : 1;
+  unsigned int trig2 : 1;
+  unsigned int trig3 : 1;
+  unsigned int dummy1 : 28;
+} reg_iop_trigger_grp_rw_intr_mask;
+#define REG_RD_ADDR_iop_trigger_grp_rw_intr_mask 20
+#define REG_WR_ADDR_iop_trigger_grp_rw_intr_mask 20
+
+/* Register rw_ack_intr, scope iop_trigger_grp, type rw */
+typedef struct {
+  unsigned int trig0 : 1;
+  unsigned int trig1 : 1;
+  unsigned int trig2 : 1;
+  unsigned int trig3 : 1;
+  unsigned int dummy1 : 28;
+} reg_iop_trigger_grp_rw_ack_intr;
+#define REG_RD_ADDR_iop_trigger_grp_rw_ack_intr 24
+#define REG_WR_ADDR_iop_trigger_grp_rw_ack_intr 24
+
+/* Register r_intr, scope iop_trigger_grp, type r */
+typedef struct {
+  unsigned int trig0 : 1;
+  unsigned int trig1 : 1;
+  unsigned int trig2 : 1;
+  unsigned int trig3 : 1;
+  unsigned int dummy1 : 28;
+} reg_iop_trigger_grp_r_intr;
+#define REG_RD_ADDR_iop_trigger_grp_r_intr 28
+
+/* Register r_masked_intr, scope iop_trigger_grp, type r */
+typedef struct {
+  unsigned int trig0 : 1;
+  unsigned int trig1 : 1;
+  unsigned int trig2 : 1;
+  unsigned int trig3 : 1;
+  unsigned int dummy1 : 28;
+} reg_iop_trigger_grp_r_masked_intr;
+#define REG_RD_ADDR_iop_trigger_grp_r_masked_intr 32
+
+
+/* Constants */
+enum {
+  regk_iop_trigger_grp_fall                = 0x00000002,
+  regk_iop_trigger_grp_fall_lo             = 0x00000006,
+  regk_iop_trigger_grp_no                  = 0x00000000,
+  regk_iop_trigger_grp_off                 = 0x00000000,
+  regk_iop_trigger_grp_pulse               = 0x00000000,
+  regk_iop_trigger_grp_rise                = 0x00000001,
+  regk_iop_trigger_grp_rise_fall           = 0x00000003,
+  regk_iop_trigger_grp_rise_fall_hi        = 0x00000007,
+  regk_iop_trigger_grp_rise_fall_lo        = 0x00000004,
+  regk_iop_trigger_grp_rise_hi             = 0x00000005,
+  regk_iop_trigger_grp_rw_cfg_default      = 0x000000c0,
+  regk_iop_trigger_grp_rw_cfg_size         = 0x00000004,
+  regk_iop_trigger_grp_rw_intr_mask_default = 0x00000000,
+  regk_iop_trigger_grp_toggle              = 0x00000003,
+  regk_iop_trigger_grp_yes                 = 0x00000001
+};
+#endif /* __iop_trigger_grp_defs_h */
diff --git a/include/asm-cris/arch-v32/hwregs/iop/iop_version_defs.h b/include/asm-cris/arch-v32/hwregs/iop/iop_version_defs.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/iop/iop_version_defs.h
@@ -0,0 +1,99 @@
+#ifndef __iop_version_defs_h
+#define __iop_version_defs_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/io_proc/rtl/guinness/iop_version.r
+ *     id:           iop_version.r,v 1.3 2004/04/22 12:37:54 jonaso Exp
+ *     last modfied: Mon Apr 11 16:08:44 2005
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c --outfile iop_version_defs.h ../../inst/io_proc/rtl/guinness/iop_version.r
+ *      id: $Id: iop_version_defs.h,v 1.4 2005/04/24 18:31:05 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+/* Main access macros */
+#ifndef REG_RD
+#define REG_RD( scope, inst, reg ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR
+#define REG_WR( scope, inst, reg, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_VECT
+#define REG_RD_VECT( scope, inst, reg, index ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_VECT
+#define REG_WR_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT
+#define REG_RD_INT( scope, inst, reg ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT
+#define REG_WR_INT( scope, inst, reg, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT_VECT
+#define REG_RD_INT_VECT( scope, inst, reg, index ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT_VECT
+#define REG_WR_INT_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_TYPE_CONV
+#define REG_TYPE_CONV( type, orgtype, val ) \
+  ( { union { orgtype o; type n; } r; r.o = val; r.n; } )
+#endif
+
+#ifndef reg_page_size
+#define reg_page_size 8192
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg + \
+    (index) * STRIDE_##scope##_##reg )
+#endif
+
+/* C-code for register scope iop_version */
+
+/* Register r_version, scope iop_version, type r */
+typedef struct {
+  unsigned int nr : 8;
+  unsigned int dummy1 : 24;
+} reg_iop_version_r_version;
+#define REG_RD_ADDR_iop_version_r_version 0
+
+
+/* Constants */
+enum {
+  regk_iop_version_v1_0                    = 0x00000001
+};
+#endif /* __iop_version_defs_h */
diff --git a/include/asm-cris/arch-v32/hwregs/irq_nmi_defs.h b/include/asm-cris/arch-v32/hwregs/irq_nmi_defs.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/irq_nmi_defs.h
@@ -0,0 +1,104 @@
+#ifndef __irq_nmi_defs_h
+#define __irq_nmi_defs_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../mod/irq_nmi.r
+ *     id:           <not found>
+ *     last modfied: Thu Jan 22 09:22:43 2004
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c --outfile irq_nmi_defs.h ../../mod/irq_nmi.r
+ *      id: $Id: irq_nmi_defs.h,v 1.1 2005/04/24 18:30:58 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+/* Main access macros */
+#ifndef REG_RD
+#define REG_RD( scope, inst, reg ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR
+#define REG_WR( scope, inst, reg, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_VECT
+#define REG_RD_VECT( scope, inst, reg, index ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_VECT
+#define REG_WR_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT
+#define REG_RD_INT( scope, inst, reg ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT
+#define REG_WR_INT( scope, inst, reg, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT_VECT
+#define REG_RD_INT_VECT( scope, inst, reg, index ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT_VECT
+#define REG_WR_INT_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_TYPE_CONV
+#define REG_TYPE_CONV( type, orgtype, val ) \
+  ( { union { orgtype o; type n; } r; r.o = val; r.n; } )
+#endif
+
+#ifndef reg_page_size
+#define reg_page_size 8192
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg + \
+    (index) * STRIDE_##scope##_##reg )
+#endif
+
+/* C-code for register scope irq_nmi */
+
+/* Register rw_cmd, scope irq_nmi, type rw */
+typedef struct {
+  unsigned int delay : 16;
+  unsigned int op    : 2;
+  unsigned int dummy1 : 14;
+} reg_irq_nmi_rw_cmd;
+#define REG_RD_ADDR_irq_nmi_rw_cmd 0
+#define REG_WR_ADDR_irq_nmi_rw_cmd 0
+
+
+/* Constants */
+enum {
+  regk_irq_nmi_ack_irq                     = 0x00000002,
+  regk_irq_nmi_ack_nmi                     = 0x00000003,
+  regk_irq_nmi_irq                         = 0x00000000,
+  regk_irq_nmi_nmi                         = 0x00000001
+};
+#endif /* __irq_nmi_defs_h */
diff --git a/include/asm-cris/arch-v32/hwregs/marb_bp_defs.h b/include/asm-cris/arch-v32/hwregs/marb_bp_defs.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/marb_bp_defs.h
@@ -0,0 +1,205 @@
+#ifndef __marb_bp_defs_h
+#define __marb_bp_defs_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/memarb/rtl/guinness/marb_top.r
+ *     id:           <not found>
+ *     last modfied: Fri Nov  7 15:36:04 2003
+ *
+ *   by /n/asic/projects/guinness/design/top/inst/rdesc/rdes2c ../../rtl/global.rmap ../../mod/modreg.rmap -base 0xb0000000 ../../inst/memarb/rtl/guinness/marb_top.r
+ *      id: $Id: marb_bp_defs.h,v 1.2 2004/06/04 07:15:33 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+/* Main access macros */
+#ifndef REG_RD
+#define REG_RD( scope, inst, reg ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR
+#define REG_WR( scope, inst, reg, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_VECT
+#define REG_RD_VECT( scope, inst, reg, index ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_VECT
+#define REG_WR_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT
+#define REG_RD_INT( scope, inst, reg ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT
+#define REG_WR_INT( scope, inst, reg, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT_VECT
+#define REG_RD_INT_VECT( scope, inst, reg, index ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT_VECT
+#define REG_WR_INT_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_TYPE_CONV
+#define REG_TYPE_CONV( type, orgtype, val ) \
+  ( { union { orgtype o; type n; } r; r.o = val; r.n; } )
+#endif
+
+#ifndef reg_page_size
+#define reg_page_size 8192
+#endif
+
+/* C-code for register scope marb_bp */
+
+/* Register rw_first_addr, scope marb_bp, type rw */
+typedef unsigned int reg_marb_bp_rw_first_addr;
+#define REG_RD_ADDR_marb_bp_rw_first_addr 0
+#define REG_WR_ADDR_marb_bp_rw_first_addr 0
+
+/* Register rw_last_addr, scope marb_bp, type rw */
+typedef unsigned int reg_marb_bp_rw_last_addr;
+#define REG_RD_ADDR_marb_bp_rw_last_addr 4
+#define REG_WR_ADDR_marb_bp_rw_last_addr 4
+
+/* Register rw_op, scope marb_bp, type rw */
+typedef struct {
+  unsigned int read         : 1;
+  unsigned int write        : 1;
+  unsigned int read_excl    : 1;
+  unsigned int pri_write    : 1;
+  unsigned int us_read      : 1;
+  unsigned int us_write     : 1;
+  unsigned int us_read_excl : 1;
+  unsigned int us_pri_write : 1;
+  unsigned int dummy1       : 24;
+} reg_marb_bp_rw_op;
+#define REG_RD_ADDR_marb_bp_rw_op 8
+#define REG_WR_ADDR_marb_bp_rw_op 8
+
+/* Register rw_clients, scope marb_bp, type rw */
+typedef struct {
+  unsigned int dma0  : 1;
+  unsigned int dma1  : 1;
+  unsigned int dma2  : 1;
+  unsigned int dma3  : 1;
+  unsigned int dma4  : 1;
+  unsigned int dma5  : 1;
+  unsigned int dma6  : 1;
+  unsigned int dma7  : 1;
+  unsigned int dma8  : 1;
+  unsigned int dma9  : 1;
+  unsigned int cpui  : 1;
+  unsigned int cpud  : 1;
+  unsigned int iop   : 1;
+  unsigned int slave : 1;
+  unsigned int dummy1 : 18;
+} reg_marb_bp_rw_clients;
+#define REG_RD_ADDR_marb_bp_rw_clients 12
+#define REG_WR_ADDR_marb_bp_rw_clients 12
+
+/* Register rw_options, scope marb_bp, type rw */
+typedef struct {
+  unsigned int wrap : 1;
+  unsigned int dummy1 : 31;
+} reg_marb_bp_rw_options;
+#define REG_RD_ADDR_marb_bp_rw_options 16
+#define REG_WR_ADDR_marb_bp_rw_options 16
+
+/* Register r_break_addr, scope marb_bp, type r */
+typedef unsigned int reg_marb_bp_r_break_addr;
+#define REG_RD_ADDR_marb_bp_r_break_addr 20
+
+/* Register r_break_op, scope marb_bp, type r */
+typedef struct {
+  unsigned int read         : 1;
+  unsigned int write        : 1;
+  unsigned int read_excl    : 1;
+  unsigned int pri_write    : 1;
+  unsigned int us_read      : 1;
+  unsigned int us_write     : 1;
+  unsigned int us_read_excl : 1;
+  unsigned int us_pri_write : 1;
+  unsigned int dummy1       : 24;
+} reg_marb_bp_r_break_op;
+#define REG_RD_ADDR_marb_bp_r_break_op 24
+
+/* Register r_break_clients, scope marb_bp, type r */
+typedef struct {
+  unsigned int dma0  : 1;
+  unsigned int dma1  : 1;
+  unsigned int dma2  : 1;
+  unsigned int dma3  : 1;
+  unsigned int dma4  : 1;
+  unsigned int dma5  : 1;
+  unsigned int dma6  : 1;
+  unsigned int dma7  : 1;
+  unsigned int dma8  : 1;
+  unsigned int dma9  : 1;
+  unsigned int cpui  : 1;
+  unsigned int cpud  : 1;
+  unsigned int iop   : 1;
+  unsigned int slave : 1;
+  unsigned int dummy1 : 18;
+} reg_marb_bp_r_break_clients;
+#define REG_RD_ADDR_marb_bp_r_break_clients 28
+
+/* Register r_break_first_client, scope marb_bp, type r */
+typedef struct {
+  unsigned int dma0  : 1;
+  unsigned int dma1  : 1;
+  unsigned int dma2  : 1;
+  unsigned int dma3  : 1;
+  unsigned int dma4  : 1;
+  unsigned int dma5  : 1;
+  unsigned int dma6  : 1;
+  unsigned int dma7  : 1;
+  unsigned int dma8  : 1;
+  unsigned int dma9  : 1;
+  unsigned int cpui  : 1;
+  unsigned int cpud  : 1;
+  unsigned int iop   : 1;
+  unsigned int slave : 1;
+  unsigned int dummy1 : 18;
+} reg_marb_bp_r_break_first_client;
+#define REG_RD_ADDR_marb_bp_r_break_first_client 32
+
+/* Register r_break_size, scope marb_bp, type r */
+typedef unsigned int reg_marb_bp_r_break_size;
+#define REG_RD_ADDR_marb_bp_r_break_size 36
+
+/* Register rw_ack, scope marb_bp, type rw */
+typedef unsigned int reg_marb_bp_rw_ack;
+#define REG_RD_ADDR_marb_bp_rw_ack 40
+#define REG_WR_ADDR_marb_bp_rw_ack 40
+
+
+/* Constants */
+enum {
+  regk_marb_bp_no                          = 0x00000000,
+  regk_marb_bp_rw_op_default               = 0x00000000,
+  regk_marb_bp_rw_options_default          = 0x00000000,
+  regk_marb_bp_yes                         = 0x00000001
+};
+#endif /* __marb_bp_defs_h */
diff --git a/include/asm-cris/arch-v32/hwregs/marb_defs.h b/include/asm-cris/arch-v32/hwregs/marb_defs.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/marb_defs.h
@@ -0,0 +1,475 @@
+#ifndef __marb_defs_h
+#define __marb_defs_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/memarb/rtl/guinness/marb_top.r
+ *     id:           <not found>
+ *     last modfied: Mon Apr 11 16:12:16 2005
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c --outfile marb_defs.h ../../inst/memarb/rtl/guinness/marb_top.r
+ *      id: $Id: marb_defs.h,v 1.3 2005/04/24 18:30:58 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+/* Main access macros */
+#ifndef REG_RD
+#define REG_RD( scope, inst, reg ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR
+#define REG_WR( scope, inst, reg, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_VECT
+#define REG_RD_VECT( scope, inst, reg, index ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_VECT
+#define REG_WR_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT
+#define REG_RD_INT( scope, inst, reg ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT
+#define REG_WR_INT( scope, inst, reg, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT_VECT
+#define REG_RD_INT_VECT( scope, inst, reg, index ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT_VECT
+#define REG_WR_INT_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_TYPE_CONV
+#define REG_TYPE_CONV( type, orgtype, val ) \
+  ( { union { orgtype o; type n; } r; r.o = val; r.n; } )
+#endif
+
+#ifndef reg_page_size
+#define reg_page_size 8192
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg + \
+    (index) * STRIDE_##scope##_##reg )
+#endif
+
+/* C-code for register scope marb */
+
+#define STRIDE_marb_rw_int_slots 4
+/* Register rw_int_slots, scope marb, type rw */
+typedef struct {
+  unsigned int owner : 4;
+  unsigned int dummy1 : 28;
+} reg_marb_rw_int_slots;
+#define REG_RD_ADDR_marb_rw_int_slots 0
+#define REG_WR_ADDR_marb_rw_int_slots 0
+
+#define STRIDE_marb_rw_ext_slots 4
+/* Register rw_ext_slots, scope marb, type rw */
+typedef struct {
+  unsigned int owner : 4;
+  unsigned int dummy1 : 28;
+} reg_marb_rw_ext_slots;
+#define REG_RD_ADDR_marb_rw_ext_slots 256
+#define REG_WR_ADDR_marb_rw_ext_slots 256
+
+#define STRIDE_marb_rw_regs_slots 4
+/* Register rw_regs_slots, scope marb, type rw */
+typedef struct {
+  unsigned int owner : 4;
+  unsigned int dummy1 : 28;
+} reg_marb_rw_regs_slots;
+#define REG_RD_ADDR_marb_rw_regs_slots 512
+#define REG_WR_ADDR_marb_rw_regs_slots 512
+
+/* Register rw_intr_mask, scope marb, type rw */
+typedef struct {
+  unsigned int bp0 : 1;
+  unsigned int bp1 : 1;
+  unsigned int bp2 : 1;
+  unsigned int bp3 : 1;
+  unsigned int dummy1 : 28;
+} reg_marb_rw_intr_mask;
+#define REG_RD_ADDR_marb_rw_intr_mask 528
+#define REG_WR_ADDR_marb_rw_intr_mask 528
+
+/* Register rw_ack_intr, scope marb, type rw */
+typedef struct {
+  unsigned int bp0 : 1;
+  unsigned int bp1 : 1;
+  unsigned int bp2 : 1;
+  unsigned int bp3 : 1;
+  unsigned int dummy1 : 28;
+} reg_marb_rw_ack_intr;
+#define REG_RD_ADDR_marb_rw_ack_intr 532
+#define REG_WR_ADDR_marb_rw_ack_intr 532
+
+/* Register r_intr, scope marb, type r */
+typedef struct {
+  unsigned int bp0 : 1;
+  unsigned int bp1 : 1;
+  unsigned int bp2 : 1;
+  unsigned int bp3 : 1;
+  unsigned int dummy1 : 28;
+} reg_marb_r_intr;
+#define REG_RD_ADDR_marb_r_intr 536
+
+/* Register r_masked_intr, scope marb, type r */
+typedef struct {
+  unsigned int bp0 : 1;
+  unsigned int bp1 : 1;
+  unsigned int bp2 : 1;
+  unsigned int bp3 : 1;
+  unsigned int dummy1 : 28;
+} reg_marb_r_masked_intr;
+#define REG_RD_ADDR_marb_r_masked_intr 540
+
+/* Register rw_stop_mask, scope marb, type rw */
+typedef struct {
+  unsigned int dma0  : 1;
+  unsigned int dma1  : 1;
+  unsigned int dma2  : 1;
+  unsigned int dma3  : 1;
+  unsigned int dma4  : 1;
+  unsigned int dma5  : 1;
+  unsigned int dma6  : 1;
+  unsigned int dma7  : 1;
+  unsigned int dma8  : 1;
+  unsigned int dma9  : 1;
+  unsigned int cpui  : 1;
+  unsigned int cpud  : 1;
+  unsigned int iop   : 1;
+  unsigned int slave : 1;
+  unsigned int dummy1 : 18;
+} reg_marb_rw_stop_mask;
+#define REG_RD_ADDR_marb_rw_stop_mask 544
+#define REG_WR_ADDR_marb_rw_stop_mask 544
+
+/* Register r_stopped, scope marb, type r */
+typedef struct {
+  unsigned int dma0  : 1;
+  unsigned int dma1  : 1;
+  unsigned int dma2  : 1;
+  unsigned int dma3  : 1;
+  unsigned int dma4  : 1;
+  unsigned int dma5  : 1;
+  unsigned int dma6  : 1;
+  unsigned int dma7  : 1;
+  unsigned int dma8  : 1;
+  unsigned int dma9  : 1;
+  unsigned int cpui  : 1;
+  unsigned int cpud  : 1;
+  unsigned int iop   : 1;
+  unsigned int slave : 1;
+  unsigned int dummy1 : 18;
+} reg_marb_r_stopped;
+#define REG_RD_ADDR_marb_r_stopped 548
+
+/* Register rw_no_snoop, scope marb, type rw */
+typedef struct {
+  unsigned int dma0  : 1;
+  unsigned int dma1  : 1;
+  unsigned int dma2  : 1;
+  unsigned int dma3  : 1;
+  unsigned int dma4  : 1;
+  unsigned int dma5  : 1;
+  unsigned int dma6  : 1;
+  unsigned int dma7  : 1;
+  unsigned int dma8  : 1;
+  unsigned int dma9  : 1;
+  unsigned int cpui  : 1;
+  unsigned int cpud  : 1;
+  unsigned int iop   : 1;
+  unsigned int slave : 1;
+  unsigned int dummy1 : 18;
+} reg_marb_rw_no_snoop;
+#define REG_RD_ADDR_marb_rw_no_snoop 832
+#define REG_WR_ADDR_marb_rw_no_snoop 832
+
+/* Register rw_no_snoop_rq, scope marb, type rw */
+typedef struct {
+  unsigned int dummy1 : 10;
+  unsigned int cpui : 1;
+  unsigned int cpud : 1;
+  unsigned int dummy2 : 20;
+} reg_marb_rw_no_snoop_rq;
+#define REG_RD_ADDR_marb_rw_no_snoop_rq 836
+#define REG_WR_ADDR_marb_rw_no_snoop_rq 836
+
+
+/* Constants */
+enum {
+  regk_marb_cpud                           = 0x0000000b,
+  regk_marb_cpui                           = 0x0000000a,
+  regk_marb_dma0                           = 0x00000000,
+  regk_marb_dma1                           = 0x00000001,
+  regk_marb_dma2                           = 0x00000002,
+  regk_marb_dma3                           = 0x00000003,
+  regk_marb_dma4                           = 0x00000004,
+  regk_marb_dma5                           = 0x00000005,
+  regk_marb_dma6                           = 0x00000006,
+  regk_marb_dma7                           = 0x00000007,
+  regk_marb_dma8                           = 0x00000008,
+  regk_marb_dma9                           = 0x00000009,
+  regk_marb_iop                            = 0x0000000c,
+  regk_marb_no                             = 0x00000000,
+  regk_marb_r_stopped_default              = 0x00000000,
+  regk_marb_rw_ext_slots_default           = 0x00000000,
+  regk_marb_rw_ext_slots_size              = 0x00000040,
+  regk_marb_rw_int_slots_default           = 0x00000000,
+  regk_marb_rw_int_slots_size              = 0x00000040,
+  regk_marb_rw_intr_mask_default           = 0x00000000,
+  regk_marb_rw_no_snoop_default            = 0x00000000,
+  regk_marb_rw_no_snoop_rq_default         = 0x00000000,
+  regk_marb_rw_regs_slots_default          = 0x00000000,
+  regk_marb_rw_regs_slots_size             = 0x00000004,
+  regk_marb_rw_stop_mask_default           = 0x00000000,
+  regk_marb_slave                          = 0x0000000d,
+  regk_marb_yes                            = 0x00000001
+};
+#endif /* __marb_defs_h */
+#ifndef __marb_bp_defs_h
+#define __marb_bp_defs_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/memarb/rtl/guinness/marb_top.r
+ *     id:           <not found>
+ *     last modfied: Mon Apr 11 16:12:16 2005
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c --outfile marb_defs.h ../../inst/memarb/rtl/guinness/marb_top.r
+ *      id: $Id: marb_defs.h,v 1.3 2005/04/24 18:30:58 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+/* Main access macros */
+#ifndef REG_RD
+#define REG_RD( scope, inst, reg ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR
+#define REG_WR( scope, inst, reg, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_VECT
+#define REG_RD_VECT( scope, inst, reg, index ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_VECT
+#define REG_WR_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT
+#define REG_RD_INT( scope, inst, reg ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT
+#define REG_WR_INT( scope, inst, reg, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT_VECT
+#define REG_RD_INT_VECT( scope, inst, reg, index ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT_VECT
+#define REG_WR_INT_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_TYPE_CONV
+#define REG_TYPE_CONV( type, orgtype, val ) \
+  ( { union { orgtype o; type n; } r; r.o = val; r.n; } )
+#endif
+
+#ifndef reg_page_size
+#define reg_page_size 8192
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg + \
+    (index) * STRIDE_##scope##_##reg )
+#endif
+
+/* C-code for register scope marb_bp */
+
+/* Register rw_first_addr, scope marb_bp, type rw */
+typedef unsigned int reg_marb_bp_rw_first_addr;
+#define REG_RD_ADDR_marb_bp_rw_first_addr 0
+#define REG_WR_ADDR_marb_bp_rw_first_addr 0
+
+/* Register rw_last_addr, scope marb_bp, type rw */
+typedef unsigned int reg_marb_bp_rw_last_addr;
+#define REG_RD_ADDR_marb_bp_rw_last_addr 4
+#define REG_WR_ADDR_marb_bp_rw_last_addr 4
+
+/* Register rw_op, scope marb_bp, type rw */
+typedef struct {
+  unsigned int rd         : 1;
+  unsigned int wr         : 1;
+  unsigned int rd_excl    : 1;
+  unsigned int pri_wr     : 1;
+  unsigned int us_rd      : 1;
+  unsigned int us_wr      : 1;
+  unsigned int us_rd_excl : 1;
+  unsigned int us_pri_wr  : 1;
+  unsigned int dummy1     : 24;
+} reg_marb_bp_rw_op;
+#define REG_RD_ADDR_marb_bp_rw_op 8
+#define REG_WR_ADDR_marb_bp_rw_op 8
+
+/* Register rw_clients, scope marb_bp, type rw */
+typedef struct {
+  unsigned int dma0  : 1;
+  unsigned int dma1  : 1;
+  unsigned int dma2  : 1;
+  unsigned int dma3  : 1;
+  unsigned int dma4  : 1;
+  unsigned int dma5  : 1;
+  unsigned int dma6  : 1;
+  unsigned int dma7  : 1;
+  unsigned int dma8  : 1;
+  unsigned int dma9  : 1;
+  unsigned int cpui  : 1;
+  unsigned int cpud  : 1;
+  unsigned int iop   : 1;
+  unsigned int slave : 1;
+  unsigned int dummy1 : 18;
+} reg_marb_bp_rw_clients;
+#define REG_RD_ADDR_marb_bp_rw_clients 12
+#define REG_WR_ADDR_marb_bp_rw_clients 12
+
+/* Register rw_options, scope marb_bp, type rw */
+typedef struct {
+  unsigned int wrap : 1;
+  unsigned int dummy1 : 31;
+} reg_marb_bp_rw_options;
+#define REG_RD_ADDR_marb_bp_rw_options 16
+#define REG_WR_ADDR_marb_bp_rw_options 16
+
+/* Register r_brk_addr, scope marb_bp, type r */
+typedef unsigned int reg_marb_bp_r_brk_addr;
+#define REG_RD_ADDR_marb_bp_r_brk_addr 20
+
+/* Register r_brk_op, scope marb_bp, type r */
+typedef struct {
+  unsigned int rd         : 1;
+  unsigned int wr         : 1;
+  unsigned int rd_excl    : 1;
+  unsigned int pri_wr     : 1;
+  unsigned int us_rd      : 1;
+  unsigned int us_wr      : 1;
+  unsigned int us_rd_excl : 1;
+  unsigned int us_pri_wr  : 1;
+  unsigned int dummy1     : 24;
+} reg_marb_bp_r_brk_op;
+#define REG_RD_ADDR_marb_bp_r_brk_op 24
+
+/* Register r_brk_clients, scope marb_bp, type r */
+typedef struct {
+  unsigned int dma0  : 1;
+  unsigned int dma1  : 1;
+  unsigned int dma2  : 1;
+  unsigned int dma3  : 1;
+  unsigned int dma4  : 1;
+  unsigned int dma5  : 1;
+  unsigned int dma6  : 1;
+  unsigned int dma7  : 1;
+  unsigned int dma8  : 1;
+  unsigned int dma9  : 1;
+  unsigned int cpui  : 1;
+  unsigned int cpud  : 1;
+  unsigned int iop   : 1;
+  unsigned int slave : 1;
+  unsigned int dummy1 : 18;
+} reg_marb_bp_r_brk_clients;
+#define REG_RD_ADDR_marb_bp_r_brk_clients 28
+
+/* Register r_brk_first_client, scope marb_bp, type r */
+typedef struct {
+  unsigned int dma0  : 1;
+  unsigned int dma1  : 1;
+  unsigned int dma2  : 1;
+  unsigned int dma3  : 1;
+  unsigned int dma4  : 1;
+  unsigned int dma5  : 1;
+  unsigned int dma6  : 1;
+  unsigned int dma7  : 1;
+  unsigned int dma8  : 1;
+  unsigned int dma9  : 1;
+  unsigned int cpui  : 1;
+  unsigned int cpud  : 1;
+  unsigned int iop   : 1;
+  unsigned int slave : 1;
+  unsigned int dummy1 : 18;
+} reg_marb_bp_r_brk_first_client;
+#define REG_RD_ADDR_marb_bp_r_brk_first_client 32
+
+/* Register r_brk_size, scope marb_bp, type r */
+typedef unsigned int reg_marb_bp_r_brk_size;
+#define REG_RD_ADDR_marb_bp_r_brk_size 36
+
+/* Register rw_ack, scope marb_bp, type rw */
+typedef unsigned int reg_marb_bp_rw_ack;
+#define REG_RD_ADDR_marb_bp_rw_ack 40
+#define REG_WR_ADDR_marb_bp_rw_ack 40
+
+
+/* Constants */
+enum {
+  regk_marb_bp_no                          = 0x00000000,
+  regk_marb_bp_rw_op_default               = 0x00000000,
+  regk_marb_bp_rw_options_default          = 0x00000000,
+  regk_marb_bp_yes                         = 0x00000001
+};
+#endif /* __marb_bp_defs_h */
diff --git a/include/asm-cris/arch-v32/hwregs/pinmux_defs.h b/include/asm-cris/arch-v32/hwregs/pinmux_defs.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/pinmux_defs.h
@@ -0,0 +1,357 @@
+#ifndef __pinmux_defs_h
+#define __pinmux_defs_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/pinmux/rtl/guinness/pinmux_regs.r
+ *     id:           pinmux_regs.r,v 1.40 2005/02/09 16:22:59 perz Exp
+ *     last modfied: Mon Apr 11 16:09:11 2005
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c --outfile pinmux_defs.h ../../inst/pinmux/rtl/guinness/pinmux_regs.r
+ *      id: $Id: pinmux_defs.h,v 1.3 2005/04/24 18:30:58 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+/* Main access macros */
+#ifndef REG_RD
+#define REG_RD( scope, inst, reg ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR
+#define REG_WR( scope, inst, reg, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_VECT
+#define REG_RD_VECT( scope, inst, reg, index ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_VECT
+#define REG_WR_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT
+#define REG_RD_INT( scope, inst, reg ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT
+#define REG_WR_INT( scope, inst, reg, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT_VECT
+#define REG_RD_INT_VECT( scope, inst, reg, index ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT_VECT
+#define REG_WR_INT_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_TYPE_CONV
+#define REG_TYPE_CONV( type, orgtype, val ) \
+  ( { union { orgtype o; type n; } r; r.o = val; r.n; } )
+#endif
+
+#ifndef reg_page_size
+#define reg_page_size 8192
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg + \
+    (index) * STRIDE_##scope##_##reg )
+#endif
+
+/* C-code for register scope pinmux */
+
+/* Register rw_pa, scope pinmux, type rw */
+typedef struct {
+  unsigned int pa0    : 1;
+  unsigned int pa1    : 1;
+  unsigned int pa2    : 1;
+  unsigned int pa3    : 1;
+  unsigned int pa4    : 1;
+  unsigned int pa5    : 1;
+  unsigned int pa6    : 1;
+  unsigned int pa7    : 1;
+  unsigned int csp2_n : 1;
+  unsigned int csp3_n : 1;
+  unsigned int csp5_n : 1;
+  unsigned int csp6_n : 1;
+  unsigned int hsh4   : 1;
+  unsigned int hsh5   : 1;
+  unsigned int hsh6   : 1;
+  unsigned int hsh7   : 1;
+  unsigned int dummy1 : 16;
+} reg_pinmux_rw_pa;
+#define REG_RD_ADDR_pinmux_rw_pa 0
+#define REG_WR_ADDR_pinmux_rw_pa 0
+
+/* Register rw_hwprot, scope pinmux, type rw */
+typedef struct {
+  unsigned int ser1     : 1;
+  unsigned int ser2     : 1;
+  unsigned int ser3     : 1;
+  unsigned int sser0    : 1;
+  unsigned int sser1    : 1;
+  unsigned int ata0     : 1;
+  unsigned int ata1     : 1;
+  unsigned int ata2     : 1;
+  unsigned int ata3     : 1;
+  unsigned int ata      : 1;
+  unsigned int eth1     : 1;
+  unsigned int eth1_mgm : 1;
+  unsigned int timer    : 1;
+  unsigned int p21      : 1;
+  unsigned int dummy1   : 18;
+} reg_pinmux_rw_hwprot;
+#define REG_RD_ADDR_pinmux_rw_hwprot 4
+#define REG_WR_ADDR_pinmux_rw_hwprot 4
+
+/* Register rw_pb_gio, scope pinmux, type rw */
+typedef struct {
+  unsigned int pb0  : 1;
+  unsigned int pb1  : 1;
+  unsigned int pb2  : 1;
+  unsigned int pb3  : 1;
+  unsigned int pb4  : 1;
+  unsigned int pb5  : 1;
+  unsigned int pb6  : 1;
+  unsigned int pb7  : 1;
+  unsigned int pb8  : 1;
+  unsigned int pb9  : 1;
+  unsigned int pb10 : 1;
+  unsigned int pb11 : 1;
+  unsigned int pb12 : 1;
+  unsigned int pb13 : 1;
+  unsigned int pb14 : 1;
+  unsigned int pb15 : 1;
+  unsigned int pb16 : 1;
+  unsigned int pb17 : 1;
+  unsigned int dummy1 : 14;
+} reg_pinmux_rw_pb_gio;
+#define REG_RD_ADDR_pinmux_rw_pb_gio 8
+#define REG_WR_ADDR_pinmux_rw_pb_gio 8
+
+/* Register rw_pb_iop, scope pinmux, type rw */
+typedef struct {
+  unsigned int pb0  : 1;
+  unsigned int pb1  : 1;
+  unsigned int pb2  : 1;
+  unsigned int pb3  : 1;
+  unsigned int pb4  : 1;
+  unsigned int pb5  : 1;
+  unsigned int pb6  : 1;
+  unsigned int pb7  : 1;
+  unsigned int pb8  : 1;
+  unsigned int pb9  : 1;
+  unsigned int pb10 : 1;
+  unsigned int pb11 : 1;
+  unsigned int pb12 : 1;
+  unsigned int pb13 : 1;
+  unsigned int pb14 : 1;
+  unsigned int pb15 : 1;
+  unsigned int pb16 : 1;
+  unsigned int pb17 : 1;
+  unsigned int dummy1 : 14;
+} reg_pinmux_rw_pb_iop;
+#define REG_RD_ADDR_pinmux_rw_pb_iop 12
+#define REG_WR_ADDR_pinmux_rw_pb_iop 12
+
+/* Register rw_pc_gio, scope pinmux, type rw */
+typedef struct {
+  unsigned int pc0  : 1;
+  unsigned int pc1  : 1;
+  unsigned int pc2  : 1;
+  unsigned int pc3  : 1;
+  unsigned int pc4  : 1;
+  unsigned int pc5  : 1;
+  unsigned int pc6  : 1;
+  unsigned int pc7  : 1;
+  unsigned int pc8  : 1;
+  unsigned int pc9  : 1;
+  unsigned int pc10 : 1;
+  unsigned int pc11 : 1;
+  unsigned int pc12 : 1;
+  unsigned int pc13 : 1;
+  unsigned int pc14 : 1;
+  unsigned int pc15 : 1;
+  unsigned int pc16 : 1;
+  unsigned int pc17 : 1;
+  unsigned int dummy1 : 14;
+} reg_pinmux_rw_pc_gio;
+#define REG_RD_ADDR_pinmux_rw_pc_gio 16
+#define REG_WR_ADDR_pinmux_rw_pc_gio 16
+
+/* Register rw_pc_iop, scope pinmux, type rw */
+typedef struct {
+  unsigned int pc0  : 1;
+  unsigned int pc1  : 1;
+  unsigned int pc2  : 1;
+  unsigned int pc3  : 1;
+  unsigned int pc4  : 1;
+  unsigned int pc5  : 1;
+  unsigned int pc6  : 1;
+  unsigned int pc7  : 1;
+  unsigned int pc8  : 1;
+  unsigned int pc9  : 1;
+  unsigned int pc10 : 1;
+  unsigned int pc11 : 1;
+  unsigned int pc12 : 1;
+  unsigned int pc13 : 1;
+  unsigned int pc14 : 1;
+  unsigned int pc15 : 1;
+  unsigned int pc16 : 1;
+  unsigned int pc17 : 1;
+  unsigned int dummy1 : 14;
+} reg_pinmux_rw_pc_iop;
+#define REG_RD_ADDR_pinmux_rw_pc_iop 20
+#define REG_WR_ADDR_pinmux_rw_pc_iop 20
+
+/* Register rw_pd_gio, scope pinmux, type rw */
+typedef struct {
+  unsigned int pd0  : 1;
+  unsigned int pd1  : 1;
+  unsigned int pd2  : 1;
+  unsigned int pd3  : 1;
+  unsigned int pd4  : 1;
+  unsigned int pd5  : 1;
+  unsigned int pd6  : 1;
+  unsigned int pd7  : 1;
+  unsigned int pd8  : 1;
+  unsigned int pd9  : 1;
+  unsigned int pd10 : 1;
+  unsigned int pd11 : 1;
+  unsigned int pd12 : 1;
+  unsigned int pd13 : 1;
+  unsigned int pd14 : 1;
+  unsigned int pd15 : 1;
+  unsigned int pd16 : 1;
+  unsigned int pd17 : 1;
+  unsigned int dummy1 : 14;
+} reg_pinmux_rw_pd_gio;
+#define REG_RD_ADDR_pinmux_rw_pd_gio 24
+#define REG_WR_ADDR_pinmux_rw_pd_gio 24
+
+/* Register rw_pd_iop, scope pinmux, type rw */
+typedef struct {
+  unsigned int pd0  : 1;
+  unsigned int pd1  : 1;
+  unsigned int pd2  : 1;
+  unsigned int pd3  : 1;
+  unsigned int pd4  : 1;
+  unsigned int pd5  : 1;
+  unsigned int pd6  : 1;
+  unsigned int pd7  : 1;
+  unsigned int pd8  : 1;
+  unsigned int pd9  : 1;
+  unsigned int pd10 : 1;
+  unsigned int pd11 : 1;
+  unsigned int pd12 : 1;
+  unsigned int pd13 : 1;
+  unsigned int pd14 : 1;
+  unsigned int pd15 : 1;
+  unsigned int pd16 : 1;
+  unsigned int pd17 : 1;
+  unsigned int dummy1 : 14;
+} reg_pinmux_rw_pd_iop;
+#define REG_RD_ADDR_pinmux_rw_pd_iop 28
+#define REG_WR_ADDR_pinmux_rw_pd_iop 28
+
+/* Register rw_pe_gio, scope pinmux, type rw */
+typedef struct {
+  unsigned int pe0  : 1;
+  unsigned int pe1  : 1;
+  unsigned int pe2  : 1;
+  unsigned int pe3  : 1;
+  unsigned int pe4  : 1;
+  unsigned int pe5  : 1;
+  unsigned int pe6  : 1;
+  unsigned int pe7  : 1;
+  unsigned int pe8  : 1;
+  unsigned int pe9  : 1;
+  unsigned int pe10 : 1;
+  unsigned int pe11 : 1;
+  unsigned int pe12 : 1;
+  unsigned int pe13 : 1;
+  unsigned int pe14 : 1;
+  unsigned int pe15 : 1;
+  unsigned int pe16 : 1;
+  unsigned int pe17 : 1;
+  unsigned int dummy1 : 14;
+} reg_pinmux_rw_pe_gio;
+#define REG_RD_ADDR_pinmux_rw_pe_gio 32
+#define REG_WR_ADDR_pinmux_rw_pe_gio 32
+
+/* Register rw_pe_iop, scope pinmux, type rw */
+typedef struct {
+  unsigned int pe0  : 1;
+  unsigned int pe1  : 1;
+  unsigned int pe2  : 1;
+  unsigned int pe3  : 1;
+  unsigned int pe4  : 1;
+  unsigned int pe5  : 1;
+  unsigned int pe6  : 1;
+  unsigned int pe7  : 1;
+  unsigned int pe8  : 1;
+  unsigned int pe9  : 1;
+  unsigned int pe10 : 1;
+  unsigned int pe11 : 1;
+  unsigned int pe12 : 1;
+  unsigned int pe13 : 1;
+  unsigned int pe14 : 1;
+  unsigned int pe15 : 1;
+  unsigned int pe16 : 1;
+  unsigned int pe17 : 1;
+  unsigned int dummy1 : 14;
+} reg_pinmux_rw_pe_iop;
+#define REG_RD_ADDR_pinmux_rw_pe_iop 36
+#define REG_WR_ADDR_pinmux_rw_pe_iop 36
+
+/* Register rw_usb_phy, scope pinmux, type rw */
+typedef struct {
+  unsigned int en_usb0 : 1;
+  unsigned int en_usb1 : 1;
+  unsigned int dummy1  : 30;
+} reg_pinmux_rw_usb_phy;
+#define REG_RD_ADDR_pinmux_rw_usb_phy 40
+#define REG_WR_ADDR_pinmux_rw_usb_phy 40
+
+
+/* Constants */
+enum {
+  regk_pinmux_no                           = 0x00000000,
+  regk_pinmux_rw_hwprot_default            = 0x00000000,
+  regk_pinmux_rw_pa_default                = 0x00000000,
+  regk_pinmux_rw_pb_gio_default            = 0x00000000,
+  regk_pinmux_rw_pb_iop_default            = 0x00000000,
+  regk_pinmux_rw_pc_gio_default            = 0x00000000,
+  regk_pinmux_rw_pc_iop_default            = 0x00000000,
+  regk_pinmux_rw_pd_gio_default            = 0x00000000,
+  regk_pinmux_rw_pd_iop_default            = 0x00000000,
+  regk_pinmux_rw_pe_gio_default            = 0x00000000,
+  regk_pinmux_rw_pe_iop_default            = 0x00000000,
+  regk_pinmux_rw_usb_phy_default           = 0x00000000,
+  regk_pinmux_yes                          = 0x00000001
+};
+#endif /* __pinmux_defs_h */
diff --git a/include/asm-cris/arch-v32/hwregs/reg_map.h b/include/asm-cris/arch-v32/hwregs/reg_map.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/reg_map.h
@@ -0,0 +1,103 @@
+#ifndef __reg_map_h
+#define __reg_map_h
+
+/*
+ * This file is autogenerated from
+ *   file:            ../../mod/fakereg.rmap
+ *     id:            fakereg.rmap,v 1.3 2004/02/11 19:53:22 ronny Exp
+ *     last modified: Wed Feb 11 20:53:25 2004
+ *   file:            ../../rtl/global.rmap
+ *     id:            global.rmap,v 1.3 2003/08/18 15:08:23 mikaeln Exp
+ *     last modified: Mon Aug 18 17:08:23 2003
+ *   file:            ../../mod/modreg.rmap
+ *     id:            modreg.rmap,v 1.31 2004/02/20 15:40:04 stefans Exp
+ *     last modified: Fri Feb 20 16:40:04 2004
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c -map -base 0xb0000000 ../../rtl/global.rmap ../../mod/modreg.rmap ../../inst/io_proc/rtl/guinness/iop_top.r ../../inst/memarb/rtl/guinness/marb_top.r ../../mod/fakereg.rmap
+ *      id: $Id: reg_map.h,v 1.7 2005/04/24 18:30:58 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+typedef enum {
+  regi_ata                                 = 0xb0032000,
+  regi_bif_core                            = 0xb0014000,
+  regi_bif_dma                             = 0xb0016000,
+  regi_bif_slave                           = 0xb0018000,
+  regi_config                              = 0xb003c000,
+  regi_dma0                                = 0xb0000000,
+  regi_dma1                                = 0xb0002000,
+  regi_dma2                                = 0xb0004000,
+  regi_dma3                                = 0xb0006000,
+  regi_dma4                                = 0xb0008000,
+  regi_dma5                                = 0xb000a000,
+  regi_dma6                                = 0xb000c000,
+  regi_dma7                                = 0xb000e000,
+  regi_dma8                                = 0xb0010000,
+  regi_dma9                                = 0xb0012000,
+  regi_eth0                                = 0xb0034000,
+  regi_eth1                                = 0xb0036000,
+  regi_gio                                 = 0xb001a000,
+  regi_iop                                 = 0xb0020000,
+  regi_iop_version                         = 0xb0020000,
+  regi_iop_fifo_in0_extra                  = 0xb0020040,
+  regi_iop_fifo_in1_extra                  = 0xb0020080,
+  regi_iop_fifo_out0_extra                 = 0xb00200c0,
+  regi_iop_fifo_out1_extra                 = 0xb0020100,
+  regi_iop_trigger_grp0                    = 0xb0020140,
+  regi_iop_trigger_grp1                    = 0xb0020180,
+  regi_iop_trigger_grp2                    = 0xb00201c0,
+  regi_iop_trigger_grp3                    = 0xb0020200,
+  regi_iop_trigger_grp4                    = 0xb0020240,
+  regi_iop_trigger_grp5                    = 0xb0020280,
+  regi_iop_trigger_grp6                    = 0xb00202c0,
+  regi_iop_trigger_grp7                    = 0xb0020300,
+  regi_iop_crc_par0                        = 0xb0020380,
+  regi_iop_crc_par1                        = 0xb0020400,
+  regi_iop_dmc_in0                         = 0xb0020480,
+  regi_iop_dmc_in1                         = 0xb0020500,
+  regi_iop_dmc_out0                        = 0xb0020580,
+  regi_iop_dmc_out1                        = 0xb0020600,
+  regi_iop_fifo_in0                        = 0xb0020680,
+  regi_iop_fifo_in1                        = 0xb0020700,
+  regi_iop_fifo_out0                       = 0xb0020780,
+  regi_iop_fifo_out1                       = 0xb0020800,
+  regi_iop_scrc_in0                        = 0xb0020880,
+  regi_iop_scrc_in1                        = 0xb0020900,
+  regi_iop_scrc_out0                       = 0xb0020980,
+  regi_iop_scrc_out1                       = 0xb0020a00,
+  regi_iop_timer_grp0                      = 0xb0020a80,
+  regi_iop_timer_grp1                      = 0xb0020b00,
+  regi_iop_timer_grp2                      = 0xb0020b80,
+  regi_iop_timer_grp3                      = 0xb0020c00,
+  regi_iop_sap_in                          = 0xb0020d00,
+  regi_iop_sap_out                         = 0xb0020e00,
+  regi_iop_spu0                            = 0xb0020f00,
+  regi_iop_spu1                            = 0xb0021000,
+  regi_iop_sw_cfg                          = 0xb0021100,
+  regi_iop_sw_cpu                          = 0xb0021200,
+  regi_iop_sw_mpu                          = 0xb0021300,
+  regi_iop_sw_spu0                         = 0xb0021400,
+  regi_iop_sw_spu1                         = 0xb0021500,
+  regi_iop_mpu                             = 0xb0021600,
+  regi_irq                                 = 0xb001c000,
+  regi_irq2                                = 0xb005c000,
+  regi_marb                                = 0xb003e000,
+  regi_marb_bp0                            = 0xb003e240,
+  regi_marb_bp1                            = 0xb003e280,
+  regi_marb_bp2                            = 0xb003e2c0,
+  regi_marb_bp3                            = 0xb003e300,
+  regi_pinmux                              = 0xb0038000,
+  regi_ser0                                = 0xb0026000,
+  regi_ser1                                = 0xb0028000,
+  regi_ser2                                = 0xb002a000,
+  regi_ser3                                = 0xb002c000,
+  regi_sser0                               = 0xb0022000,
+  regi_sser1                               = 0xb0024000,
+  regi_strcop                              = 0xb0030000,
+  regi_strmux                              = 0xb003a000,
+  regi_timer                               = 0xb001e000,
+  regi_timer2                              = 0xb005e000,
+  regi_trace                               = 0xb0040000,
+} reg_scope_instances;
+#endif /* __reg_map_h */
diff --git a/include/asm-cris/arch-v32/hwregs/reg_rdwr.h b/include/asm-cris/arch-v32/hwregs/reg_rdwr.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/reg_rdwr.h
@@ -0,0 +1,15 @@
+/* $Id: reg_rdwr.h,v 1.6 2005/04/24 18:30:58 starvik Exp $
+ *
+ * Read/write register macros used by *_defs.h
+ */
+
+#ifndef reg_rdwr_h
+#define reg_rdwr_h
+
+
+#define REG_READ(type, addr) *((volatile type *) (addr))
+
+#define REG_WRITE(type, addr, val) \
+   do { *((volatile type *) (addr)) = (val); } while(0)
+
+#endif
diff --git a/include/asm-cris/arch-v32/hwregs/rt_trace_defs.h b/include/asm-cris/arch-v32/hwregs/rt_trace_defs.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/rt_trace_defs.h
@@ -0,0 +1,173 @@
+#ifndef __rt_trace_defs_h
+#define __rt_trace_defs_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/rt_trace/rtl/rt_regs.r
+ *     id:           rt_regs.r,v 1.18 2005/02/08 15:45:00 stefans Exp
+ *     last modfied: Mon Apr 11 16:09:14 2005
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c --outfile rt_trace_defs.h ../../inst/rt_trace/rtl/rt_regs.r
+ *      id: $Id: rt_trace_defs.h,v 1.1 2005/04/24 18:30:58 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+/* Main access macros */
+#ifndef REG_RD
+#define REG_RD( scope, inst, reg ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR
+#define REG_WR( scope, inst, reg, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_VECT
+#define REG_RD_VECT( scope, inst, reg, index ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_VECT
+#define REG_WR_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT
+#define REG_RD_INT( scope, inst, reg ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT
+#define REG_WR_INT( scope, inst, reg, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT_VECT
+#define REG_RD_INT_VECT( scope, inst, reg, index ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT_VECT
+#define REG_WR_INT_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_TYPE_CONV
+#define REG_TYPE_CONV( type, orgtype, val ) \
+  ( { union { orgtype o; type n; } r; r.o = val; r.n; } )
+#endif
+
+#ifndef reg_page_size
+#define reg_page_size 8192
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg + \
+    (index) * STRIDE_##scope##_##reg )
+#endif
+
+/* C-code for register scope rt_trace */
+
+/* Register rw_cfg, scope rt_trace, type rw */
+typedef struct {
+  unsigned int en       : 1;
+  unsigned int mode     : 1;
+  unsigned int owner    : 1;
+  unsigned int wp       : 1;
+  unsigned int stall    : 1;
+  unsigned int dummy1   : 3;
+  unsigned int wp_start : 7;
+  unsigned int dummy2   : 1;
+  unsigned int wp_stop  : 7;
+  unsigned int dummy3   : 9;
+} reg_rt_trace_rw_cfg;
+#define REG_RD_ADDR_rt_trace_rw_cfg 0
+#define REG_WR_ADDR_rt_trace_rw_cfg 0
+
+/* Register rw_tap_ctrl, scope rt_trace, type rw */
+typedef struct {
+  unsigned int ack_data : 1;
+  unsigned int ack_guru : 1;
+  unsigned int dummy1   : 30;
+} reg_rt_trace_rw_tap_ctrl;
+#define REG_RD_ADDR_rt_trace_rw_tap_ctrl 4
+#define REG_WR_ADDR_rt_trace_rw_tap_ctrl 4
+
+/* Register r_tap_stat, scope rt_trace, type r */
+typedef struct {
+  unsigned int dav   : 1;
+  unsigned int empty : 1;
+  unsigned int dummy1 : 30;
+} reg_rt_trace_r_tap_stat;
+#define REG_RD_ADDR_rt_trace_r_tap_stat 8
+
+/* Register rw_tap_data, scope rt_trace, type rw */
+typedef unsigned int reg_rt_trace_rw_tap_data;
+#define REG_RD_ADDR_rt_trace_rw_tap_data 12
+#define REG_WR_ADDR_rt_trace_rw_tap_data 12
+
+/* Register rw_tap_hdata, scope rt_trace, type rw */
+typedef struct {
+  unsigned int op     : 4;
+  unsigned int sub_op : 4;
+  unsigned int dummy1 : 24;
+} reg_rt_trace_rw_tap_hdata;
+#define REG_RD_ADDR_rt_trace_rw_tap_hdata 16
+#define REG_WR_ADDR_rt_trace_rw_tap_hdata 16
+
+/* Register r_redir, scope rt_trace, type r */
+typedef unsigned int reg_rt_trace_r_redir;
+#define REG_RD_ADDR_rt_trace_r_redir 20
+
+
+/* Constants */
+enum {
+  regk_rt_trace_brk                        = 0x0000000c,
+  regk_rt_trace_dbg                        = 0x00000003,
+  regk_rt_trace_dbgdi                      = 0x00000004,
+  regk_rt_trace_dbgdo                      = 0x00000005,
+  regk_rt_trace_gmode                      = 0x00000000,
+  regk_rt_trace_no                         = 0x00000000,
+  regk_rt_trace_nop                        = 0x00000000,
+  regk_rt_trace_normal                     = 0x00000000,
+  regk_rt_trace_rdmem                      = 0x00000007,
+  regk_rt_trace_rdmemb                     = 0x00000009,
+  regk_rt_trace_rdpreg                     = 0x00000002,
+  regk_rt_trace_rdreg                      = 0x00000001,
+  regk_rt_trace_rdsreg                     = 0x00000003,
+  regk_rt_trace_redir                      = 0x00000006,
+  regk_rt_trace_ret                        = 0x0000000b,
+  regk_rt_trace_rw_cfg_default             = 0x00000000,
+  regk_rt_trace_trcfg                      = 0x00000001,
+  regk_rt_trace_wp                         = 0x00000001,
+  regk_rt_trace_wp0                        = 0x00000001,
+  regk_rt_trace_wp1                        = 0x00000002,
+  regk_rt_trace_wp2                        = 0x00000004,
+  regk_rt_trace_wp3                        = 0x00000008,
+  regk_rt_trace_wp4                        = 0x00000010,
+  regk_rt_trace_wp5                        = 0x00000020,
+  regk_rt_trace_wp6                        = 0x00000040,
+  regk_rt_trace_wrmem                      = 0x00000008,
+  regk_rt_trace_wrmemb                     = 0x0000000a,
+  regk_rt_trace_wrpreg                     = 0x00000005,
+  regk_rt_trace_wrreg                      = 0x00000004,
+  regk_rt_trace_wrsreg                     = 0x00000006,
+  regk_rt_trace_yes                        = 0x00000001
+};
+#endif /* __rt_trace_defs_h */
diff --git a/include/asm-cris/arch-v32/hwregs/ser_defs.h b/include/asm-cris/arch-v32/hwregs/ser_defs.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/ser_defs.h
@@ -0,0 +1,308 @@
+#ifndef __ser_defs_h
+#define __ser_defs_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/ser/rtl/ser_regs.r
+ *     id:           ser_regs.r,v 1.23 2005/02/08 13:58:35 perz Exp
+ *     last modfied: Mon Apr 11 16:09:21 2005
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c --outfile ser_defs.h ../../inst/ser/rtl/ser_regs.r
+ *      id: $Id: ser_defs.h,v 1.10 2005/04/24 18:30:58 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+/* Main access macros */
+#ifndef REG_RD
+#define REG_RD( scope, inst, reg ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR
+#define REG_WR( scope, inst, reg, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_VECT
+#define REG_RD_VECT( scope, inst, reg, index ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_VECT
+#define REG_WR_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT
+#define REG_RD_INT( scope, inst, reg ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT
+#define REG_WR_INT( scope, inst, reg, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT_VECT
+#define REG_RD_INT_VECT( scope, inst, reg, index ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT_VECT
+#define REG_WR_INT_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_TYPE_CONV
+#define REG_TYPE_CONV( type, orgtype, val ) \
+  ( { union { orgtype o; type n; } r; r.o = val; r.n; } )
+#endif
+
+#ifndef reg_page_size
+#define reg_page_size 8192
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg + \
+    (index) * STRIDE_##scope##_##reg )
+#endif
+
+/* C-code for register scope ser */
+
+/* Register rw_tr_ctrl, scope ser, type rw */
+typedef struct {
+  unsigned int base_freq : 3;
+  unsigned int en        : 1;
+  unsigned int par       : 2;
+  unsigned int par_en    : 1;
+  unsigned int data_bits : 1;
+  unsigned int stop_bits : 1;
+  unsigned int stop      : 1;
+  unsigned int rts_delay : 3;
+  unsigned int rts_setup : 1;
+  unsigned int auto_rts  : 1;
+  unsigned int txd       : 1;
+  unsigned int auto_cts  : 1;
+  unsigned int dummy1    : 15;
+} reg_ser_rw_tr_ctrl;
+#define REG_RD_ADDR_ser_rw_tr_ctrl 0
+#define REG_WR_ADDR_ser_rw_tr_ctrl 0
+
+/* Register rw_tr_dma_en, scope ser, type rw */
+typedef struct {
+  unsigned int en : 1;
+  unsigned int dummy1 : 31;
+} reg_ser_rw_tr_dma_en;
+#define REG_RD_ADDR_ser_rw_tr_dma_en 4
+#define REG_WR_ADDR_ser_rw_tr_dma_en 4
+
+/* Register rw_rec_ctrl, scope ser, type rw */
+typedef struct {
+  unsigned int base_freq   : 3;
+  unsigned int en          : 1;
+  unsigned int par         : 2;
+  unsigned int par_en      : 1;
+  unsigned int data_bits   : 1;
+  unsigned int dma_mode    : 1;
+  unsigned int dma_err     : 1;
+  unsigned int sampling    : 1;
+  unsigned int timeout     : 3;
+  unsigned int auto_eop    : 1;
+  unsigned int half_duplex : 1;
+  unsigned int rts_n       : 1;
+  unsigned int loopback    : 1;
+  unsigned int dummy1      : 14;
+} reg_ser_rw_rec_ctrl;
+#define REG_RD_ADDR_ser_rw_rec_ctrl 8
+#define REG_WR_ADDR_ser_rw_rec_ctrl 8
+
+/* Register rw_tr_baud_div, scope ser, type rw */
+typedef struct {
+  unsigned int div : 16;
+  unsigned int dummy1 : 16;
+} reg_ser_rw_tr_baud_div;
+#define REG_RD_ADDR_ser_rw_tr_baud_div 12
+#define REG_WR_ADDR_ser_rw_tr_baud_div 12
+
+/* Register rw_rec_baud_div, scope ser, type rw */
+typedef struct {
+  unsigned int div : 16;
+  unsigned int dummy1 : 16;
+} reg_ser_rw_rec_baud_div;
+#define REG_RD_ADDR_ser_rw_rec_baud_div 16
+#define REG_WR_ADDR_ser_rw_rec_baud_div 16
+
+/* Register rw_xoff, scope ser, type rw */
+typedef struct {
+  unsigned int chr       : 8;
+  unsigned int automatic : 1;
+  unsigned int dummy1    : 23;
+} reg_ser_rw_xoff;
+#define REG_RD_ADDR_ser_rw_xoff 20
+#define REG_WR_ADDR_ser_rw_xoff 20
+
+/* Register rw_xoff_clr, scope ser, type rw */
+typedef struct {
+  unsigned int clr : 1;
+  unsigned int dummy1 : 31;
+} reg_ser_rw_xoff_clr;
+#define REG_RD_ADDR_ser_rw_xoff_clr 24
+#define REG_WR_ADDR_ser_rw_xoff_clr 24
+
+/* Register rw_dout, scope ser, type rw */
+typedef struct {
+  unsigned int data : 8;
+  unsigned int dummy1 : 24;
+} reg_ser_rw_dout;
+#define REG_RD_ADDR_ser_rw_dout 28
+#define REG_WR_ADDR_ser_rw_dout 28
+
+/* Register rs_stat_din, scope ser, type rs */
+typedef struct {
+  unsigned int data        : 8;
+  unsigned int dummy1      : 8;
+  unsigned int dav         : 1;
+  unsigned int framing_err : 1;
+  unsigned int par_err     : 1;
+  unsigned int orun        : 1;
+  unsigned int rec_err     : 1;
+  unsigned int rxd         : 1;
+  unsigned int tr_idle     : 1;
+  unsigned int tr_empty    : 1;
+  unsigned int tr_rdy      : 1;
+  unsigned int cts_n       : 1;
+  unsigned int xoff_detect : 1;
+  unsigned int rts_n       : 1;
+  unsigned int txd         : 1;
+  unsigned int dummy2      : 3;
+} reg_ser_rs_stat_din;
+#define REG_RD_ADDR_ser_rs_stat_din 32
+
+/* Register r_stat_din, scope ser, type r */
+typedef struct {
+  unsigned int data        : 8;
+  unsigned int dummy1      : 8;
+  unsigned int dav         : 1;
+  unsigned int framing_err : 1;
+  unsigned int par_err     : 1;
+  unsigned int orun        : 1;
+  unsigned int rec_err     : 1;
+  unsigned int rxd         : 1;
+  unsigned int tr_idle     : 1;
+  unsigned int tr_empty    : 1;
+  unsigned int tr_rdy      : 1;
+  unsigned int cts_n       : 1;
+  unsigned int xoff_detect : 1;
+  unsigned int rts_n       : 1;
+  unsigned int txd         : 1;
+  unsigned int dummy2      : 3;
+} reg_ser_r_stat_din;
+#define REG_RD_ADDR_ser_r_stat_din 36
+
+/* Register rw_rec_eop, scope ser, type rw */
+typedef struct {
+  unsigned int set : 1;
+  unsigned int dummy1 : 31;
+} reg_ser_rw_rec_eop;
+#define REG_RD_ADDR_ser_rw_rec_eop 40
+#define REG_WR_ADDR_ser_rw_rec_eop 40
+
+/* Register rw_intr_mask, scope ser, type rw */
+typedef struct {
+  unsigned int tr_rdy   : 1;
+  unsigned int tr_empty : 1;
+  unsigned int tr_idle  : 1;
+  unsigned int dav      : 1;
+  unsigned int dummy1   : 28;
+} reg_ser_rw_intr_mask;
+#define REG_RD_ADDR_ser_rw_intr_mask 44
+#define REG_WR_ADDR_ser_rw_intr_mask 44
+
+/* Register rw_ack_intr, scope ser, type rw */
+typedef struct {
+  unsigned int tr_rdy   : 1;
+  unsigned int tr_empty : 1;
+  unsigned int tr_idle  : 1;
+  unsigned int dav      : 1;
+  unsigned int dummy1   : 28;
+} reg_ser_rw_ack_intr;
+#define REG_RD_ADDR_ser_rw_ack_intr 48
+#define REG_WR_ADDR_ser_rw_ack_intr 48
+
+/* Register r_intr, scope ser, type r */
+typedef struct {
+  unsigned int tr_rdy   : 1;
+  unsigned int tr_empty : 1;
+  unsigned int tr_idle  : 1;
+  unsigned int dav      : 1;
+  unsigned int dummy1   : 28;
+} reg_ser_r_intr;
+#define REG_RD_ADDR_ser_r_intr 52
+
+/* Register r_masked_intr, scope ser, type r */
+typedef struct {
+  unsigned int tr_rdy   : 1;
+  unsigned int tr_empty : 1;
+  unsigned int tr_idle  : 1;
+  unsigned int dav      : 1;
+  unsigned int dummy1   : 28;
+} reg_ser_r_masked_intr;
+#define REG_RD_ADDR_ser_r_masked_intr 56
+
+
+/* Constants */
+enum {
+  regk_ser_active                          = 0x00000000,
+  regk_ser_bits1                           = 0x00000000,
+  regk_ser_bits2                           = 0x00000001,
+  regk_ser_bits7                           = 0x00000001,
+  regk_ser_bits8                           = 0x00000000,
+  regk_ser_del0_5                          = 0x00000000,
+  regk_ser_del1                            = 0x00000001,
+  regk_ser_del1_5                          = 0x00000002,
+  regk_ser_del2                            = 0x00000003,
+  regk_ser_del2_5                          = 0x00000004,
+  regk_ser_del3                            = 0x00000005,
+  regk_ser_del3_5                          = 0x00000006,
+  regk_ser_del4                            = 0x00000007,
+  regk_ser_even                            = 0x00000000,
+  regk_ser_ext                             = 0x00000001,
+  regk_ser_f100                            = 0x00000007,
+  regk_ser_f29_493                         = 0x00000004,
+  regk_ser_f32                             = 0x00000005,
+  regk_ser_f32_768                         = 0x00000006,
+  regk_ser_ignore                          = 0x00000001,
+  regk_ser_inactive                        = 0x00000001,
+  regk_ser_majority                        = 0x00000001,
+  regk_ser_mark                            = 0x00000002,
+  regk_ser_middle                          = 0x00000000,
+  regk_ser_no                              = 0x00000000,
+  regk_ser_odd                             = 0x00000001,
+  regk_ser_off                             = 0x00000000,
+  regk_ser_rw_intr_mask_default            = 0x00000000,
+  regk_ser_rw_rec_baud_div_default         = 0x00000000,
+  regk_ser_rw_rec_ctrl_default             = 0x00010000,
+  regk_ser_rw_tr_baud_div_default          = 0x00000000,
+  regk_ser_rw_tr_ctrl_default              = 0x00008000,
+  regk_ser_rw_tr_dma_en_default            = 0x00000000,
+  regk_ser_rw_xoff_default                 = 0x00000000,
+  regk_ser_space                           = 0x00000003,
+  regk_ser_stop                            = 0x00000000,
+  regk_ser_yes                             = 0x00000001
+};
+#endif /* __ser_defs_h */
diff --git a/include/asm-cris/arch-v32/hwregs/sser_defs.h b/include/asm-cris/arch-v32/hwregs/sser_defs.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/sser_defs.h
@@ -0,0 +1,331 @@
+#ifndef __sser_defs_h
+#define __sser_defs_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/syncser/rtl/sser_regs.r
+ *     id:           sser_regs.r,v 1.24 2005/02/11 14:27:36 gunnard Exp
+ *     last modfied: Mon Apr 11 16:09:48 2005
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c --outfile sser_defs.h ../../inst/syncser/rtl/sser_regs.r
+ *      id: $Id: sser_defs.h,v 1.3 2005/04/24 18:30:58 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+/* Main access macros */
+#ifndef REG_RD
+#define REG_RD( scope, inst, reg ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR
+#define REG_WR( scope, inst, reg, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_VECT
+#define REG_RD_VECT( scope, inst, reg, index ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_VECT
+#define REG_WR_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT
+#define REG_RD_INT( scope, inst, reg ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT
+#define REG_WR_INT( scope, inst, reg, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT_VECT
+#define REG_RD_INT_VECT( scope, inst, reg, index ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT_VECT
+#define REG_WR_INT_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_TYPE_CONV
+#define REG_TYPE_CONV( type, orgtype, val ) \
+  ( { union { orgtype o; type n; } r; r.o = val; r.n; } )
+#endif
+
+#ifndef reg_page_size
+#define reg_page_size 8192
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg + \
+    (index) * STRIDE_##scope##_##reg )
+#endif
+
+/* C-code for register scope sser */
+
+/* Register rw_cfg, scope sser, type rw */
+typedef struct {
+  unsigned int clk_div      : 16;
+  unsigned int base_freq    : 3;
+  unsigned int gate_clk     : 1;
+  unsigned int clkgate_ctrl : 1;
+  unsigned int clkgate_in   : 1;
+  unsigned int clk_dir      : 1;
+  unsigned int clk_od_mode  : 1;
+  unsigned int out_clk_pol  : 1;
+  unsigned int out_clk_src  : 2;
+  unsigned int clk_in_sel   : 1;
+  unsigned int hold_pol     : 1;
+  unsigned int prepare      : 1;
+  unsigned int en           : 1;
+  unsigned int dummy1       : 1;
+} reg_sser_rw_cfg;
+#define REG_RD_ADDR_sser_rw_cfg 0
+#define REG_WR_ADDR_sser_rw_cfg 0
+
+/* Register rw_frm_cfg, scope sser, type rw */
+typedef struct {
+  unsigned int wordrate       : 10;
+  unsigned int rec_delay      : 3;
+  unsigned int tr_delay       : 3;
+  unsigned int early_wend     : 1;
+  unsigned int level          : 2;
+  unsigned int type           : 1;
+  unsigned int clk_pol        : 1;
+  unsigned int fr_in_rxclk    : 1;
+  unsigned int clk_src        : 1;
+  unsigned int out_off        : 1;
+  unsigned int out_on         : 1;
+  unsigned int frame_pin_dir  : 1;
+  unsigned int frame_pin_use  : 2;
+  unsigned int status_pin_dir : 1;
+  unsigned int status_pin_use : 2;
+  unsigned int dummy1         : 1;
+} reg_sser_rw_frm_cfg;
+#define REG_RD_ADDR_sser_rw_frm_cfg 4
+#define REG_WR_ADDR_sser_rw_frm_cfg 4
+
+/* Register rw_tr_cfg, scope sser, type rw */
+typedef struct {
+  unsigned int tr_en          : 1;
+  unsigned int stop           : 1;
+  unsigned int urun_stop      : 1;
+  unsigned int eop_stop       : 1;
+  unsigned int sample_size    : 6;
+  unsigned int sh_dir         : 1;
+  unsigned int clk_pol        : 1;
+  unsigned int clk_src        : 1;
+  unsigned int use_dma        : 1;
+  unsigned int mode           : 2;
+  unsigned int frm_src        : 1;
+  unsigned int use60958       : 1;
+  unsigned int iec60958_ckdiv : 2;
+  unsigned int rate_ctrl      : 1;
+  unsigned int use_md         : 1;
+  unsigned int dual_i2s       : 1;
+  unsigned int data_pin_use   : 2;
+  unsigned int od_mode        : 1;
+  unsigned int bulk_wspace    : 2;
+  unsigned int dummy1         : 4;
+} reg_sser_rw_tr_cfg;
+#define REG_RD_ADDR_sser_rw_tr_cfg 8
+#define REG_WR_ADDR_sser_rw_tr_cfg 8
+
+/* Register rw_rec_cfg, scope sser, type rw */
+typedef struct {
+  unsigned int rec_en          : 1;
+  unsigned int force_eop       : 1;
+  unsigned int stop            : 1;
+  unsigned int orun_stop       : 1;
+  unsigned int eop_stop        : 1;
+  unsigned int sample_size     : 6;
+  unsigned int sh_dir          : 1;
+  unsigned int clk_pol         : 1;
+  unsigned int clk_src         : 1;
+  unsigned int use_dma         : 1;
+  unsigned int mode            : 2;
+  unsigned int frm_src         : 2;
+  unsigned int use60958        : 1;
+  unsigned int iec60958_ui_len : 5;
+  unsigned int slave2_en       : 1;
+  unsigned int slave3_en       : 1;
+  unsigned int fifo_thr        : 2;
+  unsigned int dummy1          : 3;
+} reg_sser_rw_rec_cfg;
+#define REG_RD_ADDR_sser_rw_rec_cfg 12
+#define REG_WR_ADDR_sser_rw_rec_cfg 12
+
+/* Register rw_tr_data, scope sser, type rw */
+typedef struct {
+  unsigned int data : 16;
+  unsigned int md   : 1;
+  unsigned int dummy1 : 15;
+} reg_sser_rw_tr_data;
+#define REG_RD_ADDR_sser_rw_tr_data 16
+#define REG_WR_ADDR_sser_rw_tr_data 16
+
+/* Register r_rec_data, scope sser, type r */
+typedef struct {
+  unsigned int data      : 16;
+  unsigned int md        : 1;
+  unsigned int ext_clk   : 1;
+  unsigned int status_in : 1;
+  unsigned int frame_in  : 1;
+  unsigned int din       : 1;
+  unsigned int data_in   : 1;
+  unsigned int clk_in    : 1;
+  unsigned int dummy1    : 9;
+} reg_sser_r_rec_data;
+#define REG_RD_ADDR_sser_r_rec_data 20
+
+/* Register rw_extra, scope sser, type rw */
+typedef struct {
+  unsigned int clkoff_cycles : 20;
+  unsigned int clkoff_en     : 1;
+  unsigned int clkon_en      : 1;
+  unsigned int dout_delay    : 5;
+  unsigned int dummy1        : 5;
+} reg_sser_rw_extra;
+#define REG_RD_ADDR_sser_rw_extra 24
+#define REG_WR_ADDR_sser_rw_extra 24
+
+/* Register rw_intr_mask, scope sser, type rw */
+typedef struct {
+  unsigned int trdy    : 1;
+  unsigned int rdav    : 1;
+  unsigned int tidle   : 1;
+  unsigned int rstop   : 1;
+  unsigned int urun    : 1;
+  unsigned int orun    : 1;
+  unsigned int md_rec  : 1;
+  unsigned int md_sent : 1;
+  unsigned int r958err : 1;
+  unsigned int dummy1  : 23;
+} reg_sser_rw_intr_mask;
+#define REG_RD_ADDR_sser_rw_intr_mask 28
+#define REG_WR_ADDR_sser_rw_intr_mask 28
+
+/* Register rw_ack_intr, scope sser, type rw */
+typedef struct {
+  unsigned int trdy    : 1;
+  unsigned int rdav    : 1;
+  unsigned int tidle   : 1;
+  unsigned int rstop   : 1;
+  unsigned int urun    : 1;
+  unsigned int orun    : 1;
+  unsigned int md_rec  : 1;
+  unsigned int md_sent : 1;
+  unsigned int r958err : 1;
+  unsigned int dummy1  : 23;
+} reg_sser_rw_ack_intr;
+#define REG_RD_ADDR_sser_rw_ack_intr 32
+#define REG_WR_ADDR_sser_rw_ack_intr 32
+
+/* Register r_intr, scope sser, type r */
+typedef struct {
+  unsigned int trdy    : 1;
+  unsigned int rdav    : 1;
+  unsigned int tidle   : 1;
+  unsigned int rstop   : 1;
+  unsigned int urun    : 1;
+  unsigned int orun    : 1;
+  unsigned int md_rec  : 1;
+  unsigned int md_sent : 1;
+  unsigned int r958err : 1;
+  unsigned int dummy1  : 23;
+} reg_sser_r_intr;
+#define REG_RD_ADDR_sser_r_intr 36
+
+/* Register r_masked_intr, scope sser, type r */
+typedef struct {
+  unsigned int trdy    : 1;
+  unsigned int rdav    : 1;
+  unsigned int tidle   : 1;
+  unsigned int rstop   : 1;
+  unsigned int urun    : 1;
+  unsigned int orun    : 1;
+  unsigned int md_rec  : 1;
+  unsigned int md_sent : 1;
+  unsigned int r958err : 1;
+  unsigned int dummy1  : 23;
+} reg_sser_r_masked_intr;
+#define REG_RD_ADDR_sser_r_masked_intr 40
+
+
+/* Constants */
+enum {
+  regk_sser_both                           = 0x00000002,
+  regk_sser_bulk                           = 0x00000001,
+  regk_sser_clk100                         = 0x00000000,
+  regk_sser_clk_in                         = 0x00000000,
+  regk_sser_const0                         = 0x00000003,
+  regk_sser_dout                           = 0x00000002,
+  regk_sser_edge                           = 0x00000000,
+  regk_sser_ext                            = 0x00000001,
+  regk_sser_ext_clk                        = 0x00000001,
+  regk_sser_f100                           = 0x00000000,
+  regk_sser_f29_493                        = 0x00000004,
+  regk_sser_f32                            = 0x00000005,
+  regk_sser_f32_768                        = 0x00000006,
+  regk_sser_frm                            = 0x00000003,
+  regk_sser_gio0                           = 0x00000000,
+  regk_sser_gio1                           = 0x00000001,
+  regk_sser_hispeed                        = 0x00000001,
+  regk_sser_hold                           = 0x00000002,
+  regk_sser_in                             = 0x00000000,
+  regk_sser_inf                            = 0x00000003,
+  regk_sser_intern                         = 0x00000000,
+  regk_sser_intern_clk                     = 0x00000001,
+  regk_sser_intern_tb                      = 0x00000000,
+  regk_sser_iso                            = 0x00000000,
+  regk_sser_level                          = 0x00000001,
+  regk_sser_lospeed                        = 0x00000000,
+  regk_sser_lsbfirst                       = 0x00000000,
+  regk_sser_msbfirst                       = 0x00000001,
+  regk_sser_neg                            = 0x00000001,
+  regk_sser_neg_lo                         = 0x00000000,
+  regk_sser_no                             = 0x00000000,
+  regk_sser_no_clk                         = 0x00000007,
+  regk_sser_nojitter                       = 0x00000002,
+  regk_sser_out                            = 0x00000001,
+  regk_sser_pos                            = 0x00000000,
+  regk_sser_pos_hi                         = 0x00000001,
+  regk_sser_rec                            = 0x00000000,
+  regk_sser_rw_cfg_default                 = 0x00000000,
+  regk_sser_rw_extra_default               = 0x00000000,
+  regk_sser_rw_frm_cfg_default             = 0x00000000,
+  regk_sser_rw_intr_mask_default           = 0x00000000,
+  regk_sser_rw_rec_cfg_default             = 0x00000000,
+  regk_sser_rw_tr_cfg_default              = 0x01800000,
+  regk_sser_rw_tr_data_default             = 0x00000000,
+  regk_sser_thr16                          = 0x00000001,
+  regk_sser_thr32                          = 0x00000002,
+  regk_sser_thr8                           = 0x00000000,
+  regk_sser_tr                             = 0x00000001,
+  regk_sser_ts_out                         = 0x00000003,
+  regk_sser_tx_bulk                        = 0x00000002,
+  regk_sser_wiresave                       = 0x00000002,
+  regk_sser_yes                            = 0x00000001
+};
+#endif /* __sser_defs_h */
diff --git a/include/asm-cris/arch-v32/hwregs/strcop.h b/include/asm-cris/arch-v32/hwregs/strcop.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/strcop.h
@@ -0,0 +1,57 @@
+// $Id: strcop.h,v 1.3 2003/10/22 13:27:12 henriken Exp $
+
+// Streamcop meta-data configuration structs
+
+struct strcop_meta_out {
+	unsigned char  csumsel  : 3;
+	unsigned char  ciphsel  : 3;
+	unsigned char  ciphconf : 2;
+	unsigned char  hashsel  : 3;
+	unsigned char  hashconf : 1;
+	unsigned char  hashmode : 1;
+	unsigned char  decrypt  : 1;
+	unsigned char  dlkey    : 1;
+	unsigned char  cbcmode  : 1;
+};
+
+struct strcop_meta_in {
+	unsigned char  dmasel     : 3;
+	unsigned char  sync       : 1;
+	unsigned char  res1       : 5;
+	unsigned char  res2;
+};
+
+// Source definitions
+
+enum {
+	src_none = 0,
+	src_dma  = 1,
+	src_des  = 2,
+	src_sha1 = 3,
+	src_csum = 4,
+	src_aes  = 5,
+	src_md5  = 6,
+	src_res  = 7
+};
+
+// Cipher definitions
+
+enum {
+	ciph_des = 0,
+	ciph_3des = 1,
+	ciph_aes = 2
+};
+
+// Hash definitions
+
+enum {
+	hash_sha1 = 0,
+	hash_md5 = 1
+};
+
+enum {
+	hash_noiv = 0,
+	hash_iv = 1
+};
+
+
diff --git a/include/asm-cris/arch-v32/hwregs/strcop_defs.h b/include/asm-cris/arch-v32/hwregs/strcop_defs.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/strcop_defs.h
@@ -0,0 +1,109 @@
+#ifndef __strcop_defs_h
+#define __strcop_defs_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/strcop/rtl/strcop_regs.r
+ *     id:           strcop_regs.r,v 1.5 2003/10/15 12:09:45 kriskn Exp
+ *     last modfied: Mon Apr 11 16:09:38 2005
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c --outfile strcop_defs.h ../../inst/strcop/rtl/strcop_regs.r
+ *      id: $Id: strcop_defs.h,v 1.7 2005/04/24 18:30:58 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+/* Main access macros */
+#ifndef REG_RD
+#define REG_RD( scope, inst, reg ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR
+#define REG_WR( scope, inst, reg, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_VECT
+#define REG_RD_VECT( scope, inst, reg, index ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_VECT
+#define REG_WR_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT
+#define REG_RD_INT( scope, inst, reg ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT
+#define REG_WR_INT( scope, inst, reg, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT_VECT
+#define REG_RD_INT_VECT( scope, inst, reg, index ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT_VECT
+#define REG_WR_INT_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_TYPE_CONV
+#define REG_TYPE_CONV( type, orgtype, val ) \
+  ( { union { orgtype o; type n; } r; r.o = val; r.n; } )
+#endif
+
+#ifndef reg_page_size
+#define reg_page_size 8192
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg + \
+    (index) * STRIDE_##scope##_##reg )
+#endif
+
+/* C-code for register scope strcop */
+
+/* Register rw_cfg, scope strcop, type rw */
+typedef struct {
+  unsigned int td3         : 1;
+  unsigned int td2         : 1;
+  unsigned int td1         : 1;
+  unsigned int ipend       : 1;
+  unsigned int ignore_sync : 1;
+  unsigned int en          : 1;
+  unsigned int dummy1      : 26;
+} reg_strcop_rw_cfg;
+#define REG_RD_ADDR_strcop_rw_cfg 0
+#define REG_WR_ADDR_strcop_rw_cfg 0
+
+
+/* Constants */
+enum {
+  regk_strcop_big                          = 0x00000001,
+  regk_strcop_d                            = 0x00000001,
+  regk_strcop_e                            = 0x00000000,
+  regk_strcop_little                       = 0x00000000,
+  regk_strcop_rw_cfg_default               = 0x00000002
+};
+#endif /* __strcop_defs_h */
diff --git a/include/asm-cris/arch-v32/hwregs/strmux_defs.h b/include/asm-cris/arch-v32/hwregs/strmux_defs.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/strmux_defs.h
@@ -0,0 +1,127 @@
+#ifndef __strmux_defs_h
+#define __strmux_defs_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/strmux/rtl/guinness/strmux_regs.r
+ *     id:           strmux_regs.r,v 1.10 2005/02/10 10:10:46 perz Exp
+ *     last modfied: Mon Apr 11 16:09:43 2005
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c --outfile strmux_defs.h ../../inst/strmux/rtl/guinness/strmux_regs.r
+ *      id: $Id: strmux_defs.h,v 1.5 2005/04/24 18:30:58 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+/* Main access macros */
+#ifndef REG_RD
+#define REG_RD( scope, inst, reg ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR
+#define REG_WR( scope, inst, reg, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_VECT
+#define REG_RD_VECT( scope, inst, reg, index ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_VECT
+#define REG_WR_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT
+#define REG_RD_INT( scope, inst, reg ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT
+#define REG_WR_INT( scope, inst, reg, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT_VECT
+#define REG_RD_INT_VECT( scope, inst, reg, index ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT_VECT
+#define REG_WR_INT_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_TYPE_CONV
+#define REG_TYPE_CONV( type, orgtype, val ) \
+  ( { union { orgtype o; type n; } r; r.o = val; r.n; } )
+#endif
+
+#ifndef reg_page_size
+#define reg_page_size 8192
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg + \
+    (index) * STRIDE_##scope##_##reg )
+#endif
+
+/* C-code for register scope strmux */
+
+/* Register rw_cfg, scope strmux, type rw */
+typedef struct {
+  unsigned int dma0 : 3;
+  unsigned int dma1 : 3;
+  unsigned int dma2 : 3;
+  unsigned int dma3 : 3;
+  unsigned int dma4 : 3;
+  unsigned int dma5 : 3;
+  unsigned int dma6 : 3;
+  unsigned int dma7 : 3;
+  unsigned int dma8 : 3;
+  unsigned int dma9 : 3;
+  unsigned int dummy1 : 2;
+} reg_strmux_rw_cfg;
+#define REG_RD_ADDR_strmux_rw_cfg 0
+#define REG_WR_ADDR_strmux_rw_cfg 0
+
+
+/* Constants */
+enum {
+  regk_strmux_ata                          = 0x00000003,
+  regk_strmux_eth0                         = 0x00000001,
+  regk_strmux_eth1                         = 0x00000004,
+  regk_strmux_ext0                         = 0x00000001,
+  regk_strmux_ext1                         = 0x00000001,
+  regk_strmux_ext2                         = 0x00000001,
+  regk_strmux_ext3                         = 0x00000001,
+  regk_strmux_iop0                         = 0x00000002,
+  regk_strmux_iop1                         = 0x00000001,
+  regk_strmux_off                          = 0x00000000,
+  regk_strmux_p21                          = 0x00000004,
+  regk_strmux_rw_cfg_default               = 0x00000000,
+  regk_strmux_ser0                         = 0x00000002,
+  regk_strmux_ser1                         = 0x00000002,
+  regk_strmux_ser2                         = 0x00000004,
+  regk_strmux_ser3                         = 0x00000003,
+  regk_strmux_sser0                        = 0x00000003,
+  regk_strmux_sser1                        = 0x00000003,
+  regk_strmux_strcop                       = 0x00000002
+};
+#endif /* __strmux_defs_h */
diff --git a/include/asm-cris/arch-v32/hwregs/supp_reg.h b/include/asm-cris/arch-v32/hwregs/supp_reg.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/supp_reg.h
@@ -0,0 +1,78 @@
+#ifndef __SUPP_REG_H__
+#define __SUPP_REG_H__
+
+/* Macros for reading and writing support/special registers. */
+
+#ifndef STRINGIFYFY
+#define STRINGIFYFY(i) #i
+#endif
+
+#ifndef STRINGIFY
+#define STRINGIFY(i) STRINGIFYFY(i)
+#endif
+
+#define SPEC_REG_BZ     "BZ"
+#define SPEC_REG_VR     "VR"
+#define SPEC_REG_PID    "PID"
+#define SPEC_REG_SRS    "SRS"
+#define SPEC_REG_WZ     "WZ"
+#define SPEC_REG_EXS    "EXS"
+#define SPEC_REG_EDA    "EDA"
+#define SPEC_REG_MOF    "MOF"
+#define SPEC_REG_DZ     "DZ"
+#define SPEC_REG_EBP    "EBP"
+#define SPEC_REG_ERP    "ERP"
+#define SPEC_REG_SRP    "SRP"
+#define SPEC_REG_NRP    "NRP"
+#define SPEC_REG_CCS    "CCS"
+#define SPEC_REG_USP    "USP"
+#define SPEC_REG_SPC    "SPC"
+
+#define RW_MM_CFG       0
+#define RW_MM_KBASE_LO  1
+#define RW_MM_KBASE_HI  2
+#define RW_MM_CAUSE     3
+#define RW_MM_TLB_SEL   4
+#define RW_MM_TLB_LO    5
+#define RW_MM_TLB_HI    6
+#define RW_MM_TLB_PGD   7
+
+#define BANK_GC		0
+#define BANK_IM		1
+#define BANK_DM		2
+#define BANK_BP		3
+
+#define RW_GC_CFG       0
+#define RW_GC_CCS       1
+#define RW_GC_SRS       2
+#define RW_GC_NRP       3
+#define RW_GC_EXS       4
+#define RW_GC_R0        8
+#define RW_GC_R1        9
+
+#define SPEC_REG_WR(r,v) \
+__asm__ __volatile__ ("move %0, $" r : : "r" (v));
+
+#define SPEC_REG_RD(r,v) \
+__asm__ __volatile__ ("move $" r ",%0" : "=r" (v));
+
+#define NOP() \
+	__asm__ __volatile__ ("nop");
+
+#define SUPP_BANK_SEL(b) 		\
+	SPEC_REG_WR(SPEC_REG_SRS,b);	\
+	NOP();				\
+	NOP();				\
+	NOP();
+
+#define SUPP_REG_WR(r,v) \
+__asm__ __volatile__ ("move %0, $S" STRINGIFYFY(r) "\n\t"	\
+		      "nop\n\t"					\
+		      "nop\n\t"					\
+		      "nop\n\t"					\
+		      : : "r" (v));
+
+#define SUPP_REG_RD(r,v) \
+__asm__ __volatile__ ("move $S" STRINGIFYFY(r) ",%0" : "=r" (v));
+
+#endif /* __SUPP_REG_H__ */
diff --git a/include/asm-cris/arch-v32/hwregs/timer_defs.h b/include/asm-cris/arch-v32/hwregs/timer_defs.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/hwregs/timer_defs.h
@@ -0,0 +1,266 @@
+#ifndef __timer_defs_h
+#define __timer_defs_h
+
+/*
+ * This file is autogenerated from
+ *   file:           ../../inst/timer/rtl/timer_regs.r
+ *     id:           timer_regs.r,v 1.7 2003/03/11 11:16:59 perz Exp
+ *     last modfied: Mon Apr 11 16:09:53 2005
+ *
+ *   by /n/asic/design/tools/rdesc/src/rdes2c --outfile timer_defs.h ../../inst/timer/rtl/timer_regs.r
+ *      id: $Id: timer_defs.h,v 1.6 2005/04/24 18:30:58 starvik Exp $
+ * Any changes here will be lost.
+ *
+ * -*- buffer-read-only: t -*-
+ */
+/* Main access macros */
+#ifndef REG_RD
+#define REG_RD( scope, inst, reg ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR
+#define REG_WR( scope, inst, reg, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_VECT
+#define REG_RD_VECT( scope, inst, reg, index ) \
+  REG_READ( reg_##scope##_##reg, \
+            (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_VECT
+#define REG_WR_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( reg_##scope##_##reg, \
+             (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT
+#define REG_RD_INT( scope, inst, reg ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT
+#define REG_WR_INT( scope, inst, reg, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_RD_INT_VECT
+#define REG_RD_INT_VECT( scope, inst, reg, index ) \
+  REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg + \
+	    (index) * STRIDE_##scope##_##reg )
+#endif
+
+#ifndef REG_WR_INT_VECT
+#define REG_WR_INT_VECT( scope, inst, reg, index, val ) \
+  REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg + \
+	     (index) * STRIDE_##scope##_##reg, (val) )
+#endif
+
+#ifndef REG_TYPE_CONV
+#define REG_TYPE_CONV( type, orgtype, val ) \
+  ( { union { orgtype o; type n; } r; r.o = val; r.n; } )
+#endif
+
+#ifndef reg_page_size
+#define reg_page_size 8192
+#endif
+
+#ifndef REG_ADDR
+#define REG_ADDR( scope, inst, reg ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg )
+#endif
+
+#ifndef REG_ADDR_VECT
+#define REG_ADDR_VECT( scope, inst, reg, index ) \
+  ( (inst) + REG_RD_ADDR_##scope##_##reg + \
+    (index) * STRIDE_##scope##_##reg )
+#endif
+
+/* C-code for register scope timer */
+
+/* Register rw_tmr0_div, scope timer, type rw */
+typedef unsigned int reg_timer_rw_tmr0_div;
+#define REG_RD_ADDR_timer_rw_tmr0_div 0
+#define REG_WR_ADDR_timer_rw_tmr0_div 0
+
+/* Register r_tmr0_data, scope timer, type r */
+typedef unsigned int reg_timer_r_tmr0_data;
+#define REG_RD_ADDR_timer_r_tmr0_data 4
+
+/* Register rw_tmr0_ctrl, scope timer, type rw */
+typedef struct {
+  unsigned int op   : 2;
+  unsigned int freq : 3;
+  unsigned int dummy1 : 27;
+} reg_timer_rw_tmr0_ctrl;
+#define REG_RD_ADDR_timer_rw_tmr0_ctrl 8
+#define REG_WR_ADDR_timer_rw_tmr0_ctrl 8
+
+/* Register rw_tmr1_div, scope timer, type rw */
+typedef unsigned int reg_timer_rw_tmr1_div;
+#define REG_RD_ADDR_timer_rw_tmr1_div 16
+#define REG_WR_ADDR_timer_rw_tmr1_div 16
+
+/* Register r_tmr1_data, scope timer, type r */
+typedef unsigned int reg_timer_r_tmr1_data;
+#define REG_RD_ADDR_timer_r_tmr1_data 20
+
+/* Register rw_tmr1_ctrl, scope timer, type rw */
+typedef struct {
+  unsigned int op   : 2;
+  unsigned int freq : 3;
+  unsigned int dummy1 : 27;
+} reg_timer_rw_tmr1_ctrl;
+#define REG_RD_ADDR_timer_rw_tmr1_ctrl 24
+#define REG_WR_ADDR_timer_rw_tmr1_ctrl 24
+
+/* Register rs_cnt_data, scope timer, type rs */
+typedef struct {
+  unsigned int tmr : 24;
+  unsigned int cnt : 8;
+} reg_timer_rs_cnt_data;
+#define REG_RD_ADDR_timer_rs_cnt_data 32
+
+/* Register r_cnt_data, scope timer, type r */
+typedef struct {
+  unsigned int tmr : 24;
+  unsigned int cnt : 8;
+} reg_timer_r_cnt_data;
+#define REG_RD_ADDR_timer_r_cnt_data 36
+
+/* Register rw_cnt_cfg, scope timer, type rw */
+typedef struct {
+  unsigned int clk : 2;
+  unsigned int dummy1 : 30;
+} reg_timer_rw_cnt_cfg;
+#define REG_RD_ADDR_timer_rw_cnt_cfg 40
+#define REG_WR_ADDR_timer_rw_cnt_cfg 40
+
+/* Register rw_trig, scope timer, type rw */
+typedef unsigned int reg_timer_rw_trig;
+#define REG_RD_ADDR_timer_rw_trig 48
+#define REG_WR_ADDR_timer_rw_trig 48
+
+/* Register rw_trig_cfg, scope timer, type rw */
+typedef struct {
+  unsigned int tmr : 2;
+  unsigned int dummy1 : 30;
+} reg_timer_rw_trig_cfg;
+#define REG_RD_ADDR_timer_rw_trig_cfg 52
+#define REG_WR_ADDR_timer_rw_trig_cfg 52
+
+/* Register r_time, scope timer, type r */
+typedef unsigned int reg_timer_r_time;
+#define REG_RD_ADDR_timer_r_time 56
+
+/* Register rw_out, scope timer, type rw */
+typedef struct {
+  unsigned int tmr : 2;
+  unsigned int dummy1 : 30;
+} reg_timer_rw_out;
+#define REG_RD_ADDR_timer_rw_out 60
+#define REG_WR_ADDR_timer_rw_out 60
+
+/* Register rw_wd_ctrl, scope timer, type rw */
+typedef struct {
+  unsigned int cnt : 8;
+  unsigned int cmd : 1;
+  unsigned int key : 7;
+  unsigned int dummy1 : 16;
+} reg_timer_rw_wd_ctrl;
+#define REG_RD_ADDR_timer_rw_wd_ctrl 64
+#define REG_WR_ADDR_timer_rw_wd_ctrl 64
+
+/* Register r_wd_stat, scope timer, type r */
+typedef struct {
+  unsigned int cnt : 8;
+  unsigned int cmd : 1;
+  unsigned int dummy1 : 23;
+} reg_timer_r_wd_stat;
+#define REG_RD_ADDR_timer_r_wd_stat 68
+
+/* Register rw_intr_mask, scope timer, type rw */
+typedef struct {
+  unsigned int tmr0 : 1;
+  unsigned int tmr1 : 1;
+  unsigned int cnt  : 1;
+  unsigned int trig : 1;
+  unsigned int dummy1 : 28;
+} reg_timer_rw_intr_mask;
+#define REG_RD_ADDR_timer_rw_intr_mask 72
+#define REG_WR_ADDR_timer_rw_intr_mask 72
+
+/* Register rw_ack_intr, scope timer, type rw */
+typedef struct {
+  unsigned int tmr0 : 1;
+  unsigned int tmr1 : 1;
+  unsigned int cnt  : 1;
+  unsigned int trig : 1;
+  unsigned int dummy1 : 28;
+} reg_timer_rw_ack_intr;
+#define REG_RD_ADDR_timer_rw_ack_intr 76
+#define REG_WR_ADDR_timer_rw_ack_intr 76
+
+/* Register r_intr, scope timer, type r */
+typedef struct {
+  unsigned int tmr0 : 1;
+  unsigned int tmr1 : 1;
+  unsigned int cnt  : 1;
+  unsigned int trig : 1;
+  unsigned int dummy1 : 28;
+} reg_timer_r_intr;
+#define REG_RD_ADDR_timer_r_intr 80
+
+/* Register r_masked_intr, scope timer, type r */
+typedef struct {
+  unsigned int tmr0 : 1;
+  unsigned int tmr1 : 1;
+  unsigned int cnt  : 1;
+  unsigned int trig : 1;
+  unsigned int dummy1 : 28;
+} reg_timer_r_masked_intr;
+#define REG_RD_ADDR_timer_r_masked_intr 84
+
+/* Register rw_test, scope timer, type rw */
+typedef struct {
+  unsigned int dis : 1;
+  unsigned int en  : 1;
+  unsigned int dummy1 : 30;
+} reg_timer_rw_test;
+#define REG_RD_ADDR_timer_rw_test 88
+#define REG_WR_ADDR_timer_rw_test 88
+
+
+/* Constants */
+enum {
+  regk_timer_ext                           = 0x00000001,
+  regk_timer_f100                          = 0x00000007,
+  regk_timer_f29_493                       = 0x00000004,
+  regk_timer_f32                           = 0x00000005,
+  regk_timer_f32_768                       = 0x00000006,
+  regk_timer_hold                          = 0x00000001,
+  regk_timer_ld                            = 0x00000000,
+  regk_timer_no                            = 0x00000000,
+  regk_timer_off                           = 0x00000000,
+  regk_timer_run                           = 0x00000002,
+  regk_timer_rw_cnt_cfg_default            = 0x00000000,
+  regk_timer_rw_intr_mask_default          = 0x00000000,
+  regk_timer_rw_out_default                = 0x00000000,
+  regk_timer_rw_test_default               = 0x00000000,
+  regk_timer_rw_tmr0_ctrl_default          = 0x00000000,
+  regk_timer_rw_tmr1_ctrl_default          = 0x00000000,
+  regk_timer_rw_trig_cfg_default           = 0x00000000,
+  regk_timer_start                         = 0x00000001,
+  regk_timer_stop                          = 0x00000000,
+  regk_timer_time                          = 0x00000001,
+  regk_timer_tmr0                          = 0x00000002,
+  regk_timer_tmr1                          = 0x00000003,
+  regk_timer_yes                           = 0x00000001
+};
+#endif /* __timer_defs_h */
diff --git a/include/asm-cris/arch-v32/ide.h b/include/asm-cris/arch-v32/ide.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/ide.h
@@ -0,0 +1,61 @@
+/*
+ *  linux/include/asm-cris/ide.h
+ *
+ *  Copyright (C) 2000-2004  Axis Communications AB
+ *
+ *  Authors:    Bjorn Wesen, Mikael Starvik
+ *
+ */
+
+/*
+ *  This file contains the ETRAX FS specific IDE code.
+ */
+
+#ifndef __ASMCRIS_IDE_H
+#define __ASMCRIS_IDE_H
+
+#ifdef __KERNEL__
+
+#include <asm/arch/hwregs/intr_vect.h>
+#include <asm/arch/hwregs/ata_defs.h>
+#include <asm/io.h>
+#include <asm-generic/ide_iops.h>
+
+
+/* ETRAX FS can support 4 IDE busses on the same pins (serialized) */
+
+#define MAX_HWIFS	4
+
+extern __inline__ int ide_default_irq(unsigned long base)
+{
+	/* all IDE busses share the same IRQ,
+	 * this has the side-effect that ide-probe.c will cluster our 4 interfaces
+	 * together in a hwgroup, and will serialize accesses. this is good, because
+	 * we can't access more than one interface at the same time on ETRAX100.
+	 */
+	return ATA_INTR_VECT;
+}
+
+extern __inline__ unsigned long ide_default_io_base(int index)
+{
+	reg_ata_rw_ctrl2 ctrl2 = {.sel = index};
+	/* we have no real I/O base address per interface, since all go through the
+	 * same register. but in a bitfield in that register, we have the i/f number.
+	 * so we can use the io_base to remember that bitfield.
+	 */
+        ctrl2.sel = index;
+
+	return REG_TYPE_CONV(unsigned long, reg_ata_rw_ctrl2, ctrl2);
+}
+
+/* some configuration options we don't need */
+
+#undef SUPPORT_VLB_SYNC
+#define SUPPORT_VLB_SYNC 0
+
+#define IDE_ARCH_ACK_INTR
+#define ide_ack_intr(hwif)	(hwif)->hw.ack_intr(hwif)
+
+#endif /* __KERNEL__ */
+
+#endif /* __ASMCRIS_IDE_H */
diff --git a/include/asm-cris/arch-v32/intmem.h b/include/asm-cris/arch-v32/intmem.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/intmem.h
@@ -0,0 +1,9 @@
+#ifndef _ASM_CRIS_INTMEM_H
+#define _ASM_CRIS_INTMEM_H
+
+void* crisv32_intmem_alloc(unsigned size, unsigned align);
+void crisv32_intmem_free(void* addr);
+void* crisv32_intmem_phys_to_virt(unsigned long addr);
+unsigned long crisv32_intmem_virt_to_phys(void *addr);
+
+#endif /* _ASM_CRIS_ARCH_INTMEM_H */
diff --git a/include/asm-cris/arch-v32/io.h b/include/asm-cris/arch-v32/io.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/io.h
@@ -0,0 +1,98 @@
+#ifndef _ASM_ARCH_CRIS_IO_H
+#define _ASM_ARCH_CRIS_IO_H
+
+#include <asm/arch/hwregs/reg_map.h>
+#include <asm/arch/hwregs/reg_rdwr.h>
+#include <asm/arch/hwregs/gio_defs.h>
+#include <linux/config.h>
+
+enum crisv32_io_dir
+{
+  crisv32_io_dir_in = 0,
+  crisv32_io_dir_out = 1
+};
+
+struct crisv32_ioport
+{
+  unsigned long* oe;
+  unsigned long* data;
+  unsigned long* data_in;
+  unsigned int pin_count;
+};
+
+struct crisv32_iopin
+{
+  struct crisv32_ioport* port;
+  int bit;
+};
+
+extern struct crisv32_ioport crisv32_ioports[];
+
+extern struct crisv32_iopin crisv32_led1_green;
+extern struct crisv32_iopin crisv32_led1_red;
+extern struct crisv32_iopin crisv32_led2_green;
+extern struct crisv32_iopin crisv32_led2_red;
+extern struct crisv32_iopin crisv32_led3_green;
+extern struct crisv32_iopin crisv32_led3_red;
+
+extern inline void crisv32_io_set(struct crisv32_iopin* iopin,
+			   int val)
+{
+	if (val)
+		*iopin->port->data |= iopin->bit;
+	else
+		*iopin->port->data &= ~iopin->bit;
+}
+
+extern inline void crisv32_io_set_dir(struct crisv32_iopin* iopin,
+			       enum crisv32_io_dir dir)
+{
+	if (dir == crisv32_io_dir_in)
+		*iopin->port->oe &= ~iopin->bit;
+	else
+		*iopin->port->oe |= iopin->bit;
+}
+
+extern inline int crisv32_io_rd(struct crisv32_iopin* iopin)
+{
+	return ((*iopin->port->data_in & iopin->bit) ? 1 : 0);
+}
+
+int crisv32_io_get(struct crisv32_iopin* iopin,
+                   unsigned int port, unsigned int pin);
+int crisv32_io_get_name(struct crisv32_iopin* iopin,
+                         char* name);
+
+#define LED_OFF    0x00
+#define LED_GREEN  0x01
+#define LED_RED    0x02
+#define LED_ORANGE (LED_GREEN | LED_RED)
+
+#define LED_NETWORK_SET(x)                          \
+	do {                                        \
+		LED_NETWORK_SET_G((x) & LED_GREEN); \
+		LED_NETWORK_SET_R((x) & LED_RED);   \
+	} while (0)
+#define LED_ACTIVE_SET(x)                           \
+	do {                                        \
+		LED_ACTIVE_SET_G((x) & LED_GREEN);  \
+		LED_ACTIVE_SET_R((x) & LED_RED);    \
+	} while (0)
+
+#define LED_NETWORK_SET_G(x) \
+	crisv32_io_set(&crisv32_led1_green, !(x));
+#define LED_NETWORK_SET_R(x) \
+	crisv32_io_set(&crisv32_led1_red, !(x));
+#define LED_ACTIVE_SET_G(x) \
+	crisv32_io_set(&crisv32_led2_green, !(x));
+#define LED_ACTIVE_SET_R(x) \
+	crisv32_io_set(&crisv32_led2_red, !(x));
+#define LED_DISK_WRITE(x) \
+         do{\
+		crisv32_io_set(&crisv32_led3_green, !(x)); \
+		crisv32_io_set(&crisv32_led3_red, !(x));   \
+        }while(0)
+#define LED_DISK_READ(x) \
+	crisv32_io_set(&crisv32_led3_green, !(x));
+
+#endif
diff --git a/include/asm-cris/arch-v32/irq.h b/include/asm-cris/arch-v32/irq.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/irq.h
@@ -0,0 +1,120 @@
+#ifndef _ASM_ARCH_IRQ_H
+#define _ASM_ARCH_IRQ_H
+
+#include <linux/config.h>
+#include "hwregs/intr_vect.h"
+
+/* Number of non-cpu interrupts. */
+#define NR_IRQS 0x50 /* Exceptions + IRQs */
+#define NR_REAL_IRQS 0x20 /* IRQs */
+#define FIRST_IRQ 0x31 /* Exception number for first IRQ */
+
+#ifndef __ASSEMBLY__
+/* Global IRQ vector. */
+typedef void (*irqvectptr)(void);
+
+struct etrax_interrupt_vector {
+	irqvectptr v[256];
+};
+
+extern struct etrax_interrupt_vector *etrax_irv;	/* head.S */
+
+void mask_irq(int irq);
+void unmask_irq(int irq);
+
+void set_exception_vector(int n, irqvectptr addr);
+
+/* Save registers so that they match pt_regs. */
+#define SAVE_ALL \
+	"subq 12,$sp\n\t"	\
+	"move $erp,[$sp]\n\t"	\
+	"subq 4,$sp\n\t"	\
+	"move $srp,[$sp]\n\t"	\
+	"subq 4,$sp\n\t"	\
+	"move $ccs,[$sp]\n\t"	\
+	"subq 4,$sp\n\t"	\
+	"move $spc,[$sp]\n\t"	\
+	"subq 4,$sp\n\t"	\
+	"move $mof,[$sp]\n\t"	\
+	"subq 4,$sp\n\t"	\
+	"move $srs,[$sp]\n\t"	\
+	"subq 4,$sp\n\t"	\
+	"move.d $acr,[$sp]\n\t"	\
+	"subq 14*4,$sp\n\t"	\
+	"movem $r13,[$sp]\n\t"	\
+	"subq 4,$sp\n\t"	\
+	"move.d $r10,[$sp]\n"
+
+#define STR2(x) #x
+#define STR(x) STR2(x)
+
+#define IRQ_NAME2(nr) nr##_interrupt(void)
+#define IRQ_NAME(nr) IRQ_NAME2(IRQ##nr)
+
+/*
+ * The reason for setting the S-bit when debugging the kernel is that we want
+ * hardware breakpoints to remain active while we are in an exception handler.
+ * Note that we cannot simply copy S1, since we may come here from user-space,
+ * or any context where the S-bit wasn't set.
+ */
+#ifdef CONFIG_ETRAX_KGDB
+#define KGDB_FIXUP \
+	"move $ccs, $r10\n\t"		\
+	"or.d (1<<9), $r10\n\t"		\
+	"move $r10, $ccs\n\t"
+#else
+#define KGDB_FIXUP ""
+#endif
+
+/*
+ * Make sure the causing IRQ is blocked, then call do_IRQ. After that, unblock
+ * and jump to ret_from_intr which is found in entry.S.
+ *
+ * The reason for blocking the IRQ is to allow an sti() before the handler,
+ * which will acknowledge the interrupt, is run. The actual blocking is made
+ * by crisv32_do_IRQ.
+ */
+#define BUILD_IRQ(nr, mask)		\
+void IRQ_NAME(nr);			\
+__asm__ (				\
+	".text\n\t"			\
+	"IRQ" #nr "_interrupt:\n\t" 	\
+	SAVE_ALL			\
+	KGDB_FIXUP                      \
+	"move.d "#nr",$r10\n\t"		\
+	"move.d $sp,$r12\n\t"		\
+	"jsr crisv32_do_IRQ\n\t"       	\
+	"moveq 1, $r11\n\t"		\
+	"jump ret_from_intr\n\t"	\
+	"nop\n\t");
+/*
+ * This is subtle. The timer interrupt is crucial and it should not be disabled
+ * for too long. However, if it had been a normal interrupt as per BUILD_IRQ, it
+ * would have been BLOCK'ed, and then softirq's are run before we return here to
+ * UNBLOCK. If the softirq's take too much time to run, the timer irq won't run
+ * and the watchdog will kill us.
+ *
+ * Furthermore, if a lot of other irq's occur before we return here, the
+ * multiple_irq handler is run and it prioritizes the timer interrupt. However
+ * if we had BLOCK'edit here, we would not get the multiple_irq at all.
+ *
+ * The non-blocking here is based on the knowledge that the timer interrupt is
+ * registred as a fast interrupt (SA_INTERRUPT) so that we _know_ there will not
+ * be an sti() before the timer irq handler is run to acknowledge the interrupt.
+ */
+#define BUILD_TIMER_IRQ(nr, mask) 	\
+void IRQ_NAME(nr);			\
+__asm__ (				\
+	".text\n\t"			\
+	"IRQ" #nr "_interrupt:\n\t"	\
+	SAVE_ALL			\
+        KGDB_FIXUP                      \
+	"move.d "#nr",$r10\n\t"		\
+	"move.d $sp,$r12\n\t"		\
+	"jsr crisv32_do_IRQ\n\t"	\
+	"moveq 0,$r11\n\t"		\
+	"jump ret_from_intr\n\t"	\
+	"nop\n\t");
+
+#endif /* __ASSEMBLY__ */
+#endif /* _ASM_ARCH_IRQ_H */
diff --git a/include/asm-cris/arch-v32/juliette.h b/include/asm-cris/arch-v32/juliette.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/juliette.h
@@ -0,0 +1,326 @@
+#ifndef _ASM_JULIETTE_H
+#define _ASM_JULIETTE_H
+
+/* juliette _IOC_TYPE, bits 8 to 15 in ioctl cmd */
+
+#define JULIOCTYPE 42
+
+/* supported ioctl _IOC_NR's */
+
+#define JULSTARTDMA      0x1        /* start a picture asynchronously */
+
+/* set parameters */
+
+#define SETDEFAULT        0x2 /* CCD/VIDEO/SS1M */
+#define SETPARAMETERS     0x3 /* CCD/VIDEO      */
+#define SETSIZE           0x4 /* CCD/VIDEO/SS1M */
+#define SETCOMPRESSION    0x5 /* CCD/VIDEO/SS1M */
+#define SETCOLORLEVEL     0x6 /* CCD/VIDEO      */
+#define SETBRIGHTNESS     0x7 /* CCD            */
+#define SETROTATION       0x8 /* CCD            */
+#define SETTEXT           0x9 /* CCD/VIDEO/SS1M */
+#define SETCLOCK          0xa /* CCD/VIDEO/SS1M */
+#define SETDATE           0xb /* CCD/VIDEO/SS1M */
+#define SETTIMEFORMAT     0xc /* CCD/VIDEO/SS1M */
+#define SETDATEFORMAT     0xd /*     VIDEO      */
+#define SETTEXTALIGNMENT  0xe /*     VIDEO      */
+#define SETFPS            0xf /* CCD/VIDEO/SS1M */
+#define SETVGA           0xff /*     VIDEO      */
+#define SETCOMMENT       0xfe /* CCD/VIDEO      */
+
+/* get parameters */
+
+#define GETDRIVERTYPE    0x10 /* CCD/VIDEO/SS1M */
+#define GETNBROFCAMERAS  0x11 /* CCD/VIDEO/SS1M */
+#define GETPARAMETERS    0x12 /* CCD/VIDEO/SS1M */
+#define GETBUFFERSIZE    0x13 /* CCD/VIDEO/SS1M */
+#define GETVIDEOTYPE     0x14 /*     VIDEO/SS1M */
+#define GETVIDEOSIGNAL   0x15 /*     VIDEO      */
+#define GETMODULATION    0x16 /*     VIDEO      */
+#define GETDCYVALUES     0xa0 /* CCD      /SS1M */
+#define GETDCYWIDTH      0xa1 /* CCD      /SS1M */
+#define GETDCYHEIGHT     0xa2 /* CCD      /SS1M */
+#define GETSIZE          0xa3 /* CCD/VIDEO      */
+#define GETCOMPRESSION   0xa4 /* CCD/VIDEO      */
+
+/* detect and get parameters */
+
+#define DETECTMODULATION  0x17 /*     VIDEO      */
+#define DETECTVIDEOTYPE   0x18 /*     VIDEO      */
+#define DETECTVIDEOSIGNAL 0x19 /*     VIDEO      */
+
+/* configure default parameters */
+
+#define CONFIGUREDEFAULT  0x20 /* CCD/VIDEO/SS1M */
+#define DEFSIZE           0x21 /* CCD/VIDEO/SS1M */
+#define DEFCOMPRESSION    0x22 /* CCD/VIDEO/SS1M */
+#define DEFCOLORLEVEL     0x23 /* CCD/VIDEO      */
+#define DEFBRIGHTNESS     0x24 /* CCD            */
+#define DEFROTATION       0x25 /* CCD            */
+#define DEFWHITEBALANCE   0x26 /* CCD            */
+#define DEFEXPOSURE       0x27 /* CCD            */
+#define DEFAUTOEXPWINDOW  0x28 /* CCD            */
+#define DEFTEXT           0x29 /* CCD/VIDEO/SS1M */
+#define DEFCLOCK          0x2a /* CCD/VIDEO/SS1M */
+#define DEFDATE           0x2b /* CCD/VIDEO/SS1M */
+#define DEFTIMEFORMAT     0x2c /* CCD/VIDEO/SS1M */
+#define DEFDATEFORMAT     0x2d /*     VIDEO      */
+#define DEFTEXTALIGNMENT  0x2e /*     VIDEO      */
+#define DEFFPS            0x2f /* CCD/VIDEO/SS1M */
+#define DEFTEXTSTRING     0x30 /* CCD/VIDEO/SS1M */
+#define DEFHEADERINFO     0x31 /* CCD/VIDEO/SS1M */
+#define DEFWEXAR          0x32 /* CCD            */
+#define DEFLINEDELAY      0x33 /* CCD            */
+#define DEFDISABLEDVIDEO  0x34 /*     VIDEO      */
+#define DEFVIDEOTYPE      0x35 /*     VIDEO      */
+#define DEFMODULATION     0x36 /*     VIDEO      */
+#define DEFXOFFSET        0x37 /*     VIDEO      */
+#define DEFYOFFSET        0x38 /*     VIDEO      */
+#define DEFYCMODE         0x39 /*     VIDEO      */
+#define DEFVCRMODE        0x3a /*     VIDEO      */
+#define DEFSTOREDCYVALUES 0x3b /* CCD/VIDEO/SS1M */
+#define DEFWCDS           0x3c /* CCD            */
+#define DEFVGA            0x3d /*     VIDEO      */
+#define DEFCOMMENT        0x3e /* CCD/VIDEO      */
+#define DEFCOMMENTSIZE    0x3f /* CCD/VIDEO      */
+#define DEFCOMMENTTEXT    0x50 /* CCD/VIDEO      */
+#define DEFSTOREDCYTEXT   0x51 /*     VIDEO      */
+
+
+#define JULABORTDMA       0x70 /* Abort current DMA transfer */
+
+/* juliette general i/o port */
+
+#define JIO_READBITS      0x40 /* read and return current port bits */
+#define JIO_SETBITS       0x41 /* set bits marked by 1 in the argument */
+#define JIO_CLRBITS       0x42 /* clr bits marked by 1 in the argument */
+#define JIO_READDIR       0x43 /* read direction, 0=input 1=output */
+#define JIO_SETINPUT      0x44 /* set direction, 0=unchanged 1=input
+                                  returns current dir */
+#define JIO_SETOUTPUT     0x45 /* set direction, 0=unchanged 1=output
+                                  returns current dir */
+
+/**** YumYum internal adresses ****/
+
+/* Juliette buffer addresses */
+
+#define BUFFER1_VIDEO   0x1100
+#define BUFFER2_VIDEO   0x2800
+#define ACDC_BUFF_VIDEO 0x0aaa
+#define BUFFER1         0x1700
+#define BUFFER2         0x2b01
+#define ACDC_BUFFER     0x1200
+#define BUFFER1_SS1M    0x1100
+#define BUFFER2_SS1M    0x2800
+#define ACDC_BUFF_SS1M  0x0900
+
+/* Juliette parameter memory addresses */
+
+#define PA_BUFFER_CNT     0x3f09 /* CCD/VIDEO */
+#define PA_CCD_BUFFER     0x3f10 /* CCD       */
+#define PA_VIDEO_BUFFER   0x3f10 /*     VIDEO */
+#define PA_DCT_BUFFER     0x3f11 /* CCD/VIDEO */
+#define PA_TEMP           0x3f12 /* CCD/VIDEO */
+#define PA_VIDEOLINE_RD   0x3f13 /*     VIDEO */
+#define PA_VIDEOLINE_WR   0x3f14 /*     VIDEO */
+#define PA_VI_HDELAY0     0x3f15 /*     VIDEO */
+#define PA_VI_VDELAY0     0x3f16 /*     VIDEO */
+#define PA_VI_HDELAY1     0x3f17 /*     VIDEO */
+#define PA_VI_VDELAY1     0x3f18 /*     VIDEO */
+#define PA_VI_HDELAY2     0x3f19 /*     VIDEO */
+#define PA_VI_VDELAY2     0x3f1a /*     VIDEO */
+#define PA_VI_HDELAY3     0x3f1b /*     VIDEO */
+#define PA_VI_VDELAY3     0x3f1c /*     VIDEO */
+#define PA_VI_CTRL        0x3f20 /*     VIDEO */
+#define PA_JPEG_CTRL      0x3f22 /* CCD/VIDEO */
+#define PA_BUFFER_SIZE    0x3f24 /* CCD/VIDEO */
+#define PA_PAL_NTSC       0x3f25 /*     VIDEO */
+#define PA_MACROBLOCKS    0x3f26 /* CCD/VIDEO */
+#define PA_COLOR          0x3f27 /*     VIDEO */
+#define PA_MEMCH1CNT2     0x3f28 /* CCD/VIDEO */
+#define PA_MEMCH1CNT3     0x3f29 /*     VIDEO */
+#define PA_MEMCH1STR2     0x3f2a /* CCD/VIDEO */
+#define PA_MEMCH1STR3     0x3f2b /*     VIDEO */
+#define PA_BUFFERS        0x3f2c /* CCD/VIDEO */
+#define PA_PROGRAM        0x3f2d /* CCD/VIDEO */
+#define PA_ROTATION       0x3f2e /* CCD       */
+#define PA_PC             0x3f30 /* CCD/VIDEO */
+#define PA_PC2            0x3f31 /*     VIDEO */
+#define PA_ODD_LINE       0x3f32 /*     VIDEO */
+#define PA_EXP_DELAY      0x3f34 /* CCD       */
+#define PA_MACROBLOCK_CNT 0x3f35 /* CCD/VIDEO */
+#define PA_DRAM_PTR1_L    0x3f36 /* CCD/VIDEO */
+#define PA_CLPOB_CNT      0x3f37 /* CCD       */
+#define PA_DRAM_PTR1_H    0x3f38 /* CCD/VIDEO */
+#define PA_DRAM_PTR2_L    0x3f3a /*     VIDEO */
+#define PA_DRAM_PTR2_H    0x3f3c /*     VIDEO */
+#define PA_CCD_LINE_CNT   0x3f3f /* CCD       */
+#define PA_VIDEO_LINE_CNT 0x3f3f /*     VIDEO */
+#define PA_TEXT           0x3f41 /* CCD/VIDEO */
+#define PA_CAMERA_CHANGED 0x3f42 /*     VIDEO */
+#define PA_TEXTALIGNMENT  0x3f43 /*     VIDEO */
+#define PA_DISABLED       0x3f44 /*     VIDEO */
+#define PA_MACROBLOCKTEXT 0x3f45 /*     VIDEO */
+#define PA_VGA            0x3f46 /*     VIDEO */
+#define PA_ZERO           0x3ffe /*     VIDEO */
+#define PA_NULL           0x3fff /* CCD/VIDEO */
+
+typedef enum {
+	jpeg  = 0,
+	dummy = 1
+} request_type;
+
+typedef enum {
+	hugesize  = 0,
+	fullsize  = 1,
+	halfsize  = 2,
+	fieldsize = 3
+} size_type;
+
+typedef enum {
+	min       = 0,
+	low       = 1,
+	medium    = 2,
+	high      = 3,
+	very_high = 4,
+	very_low  = 5,
+	q1        = 6,
+	q2        = 7,
+	q3        = 8,
+	q4        = 9,
+	q5        = 10,
+	q6        = 11
+} compr_type;
+
+typedef enum {
+	deg_0   = 0,
+	deg_180 = 1,
+	deg_90  = 2,
+	deg_270 = 3
+} rotation_type;
+
+typedef enum {
+	auto_white    = 0,
+	hold          = 1,
+	fixed_outdoor = 2,
+	fixed_indoor  = 3,
+	fixed_fluor   = 4
+} white_balance_type;
+
+typedef enum {
+	auto_exp  = 0,
+	fixed_exp = 1
+} exposure_type;
+
+typedef enum {
+	no_window = 0,
+	center    = 1,
+	top       = 2,
+	lower     = 3,
+	left      = 4,
+	right     = 5,
+	spot      = 6,
+	cw        = 7
+} exp_window_type;
+
+typedef enum {
+	h_24 = 0,
+	h_12 = 1,
+	h_24P = 2
+} hour_type;
+
+typedef enum {
+	standard = 0,
+	YYYY_MM_DD = 1,
+	Www_Mmm_DD_YYYY = 2,
+	Www_DD_MM_YYYY = 3
+} date_type;
+
+typedef enum {
+	left_align = 0,
+	center_align = 1,
+	right_align = 2
+} alignment_type;
+
+typedef enum {
+	off = 0,
+	on  = 1,
+	no  = 0,
+	yes = 1
+} enable_type;
+
+typedef enum {
+         disabled = 0,
+         enabled  = 1,
+         extended = 2
+} comment_type;
+
+typedef enum {
+	pal  = 0,
+	ntsc = 1
+} video_type;
+
+typedef enum {
+	pal_bghi_ntsc_m              = 0,
+	ntsc_4_43_50hz_pal_4_43_60hz = 1,
+	pal_n_ntsc_4_43_60hz         = 2,
+	ntsc_n_pal_m                 = 3,
+	secam_pal_4_43_60hz          = 4
+} modulation_type;
+
+typedef enum {
+	cam0 = 0,
+	cam1 = 1,
+	cam2 = 2,
+	cam3 = 3,
+	quad = 32
+} camera_type;
+
+typedef enum {
+	video_driver = 0,
+	ccd_driver   = 1
+} driver_type;
+
+struct jul_param {
+	request_type req_type;
+	size_type size;
+	compr_type compression;
+	rotation_type rotation;
+	int color_level;
+	int brightness;
+	white_balance_type white_balance;
+	exposure_type exposure;
+        exp_window_type auto_exp_window;
+	hour_type time_format;
+	date_type date_format;
+	alignment_type text_alignment;
+	enable_type text;
+	enable_type clock;
+	enable_type date;
+	enable_type fps;
+        enable_type vga;
+        enable_type comment;
+};
+
+struct video_param {
+	enable_type disabled;
+	modulation_type modulation;
+	video_type video;
+	enable_type signal;
+	enable_type vcr;
+	int xoffset;
+	int yoffset;
+};
+
+/* The juliette_request structure is used during the JULSTARTDMA asynchronous
+ * picture-taking ioctl call as an argument to specify a buffer which will get
+ * the final picture.
+ */
+
+struct juliette_request {
+	char *buf;              /* Pointer to the buffer to hold picture data */
+	unsigned int buflen;    /* Length of the above buffer */
+	unsigned int size;      /* Resulting length, 0 if the picture is not ready */
+};
+
+#endif
diff --git a/include/asm-cris/arch-v32/memmap.h b/include/asm-cris/arch-v32/memmap.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/memmap.h
@@ -0,0 +1,24 @@
+#ifndef _ASM_ARCH_MEMMAP_H
+#define _ASM_ARCH_MEMMAP_H
+
+#define MEM_CSE0_START (0x00000000)
+#define MEM_CSE0_SIZE (0x04000000)
+#define MEM_CSE1_START (0x04000000)
+#define MEM_CSE1_SIZE (0x04000000)
+#define MEM_CSR0_START (0x08000000)
+#define MEM_CSR1_START (0x0c000000)
+#define MEM_CSP0_START (0x10000000)
+#define MEM_CSP1_START (0x14000000)
+#define MEM_CSP2_START (0x18000000)
+#define MEM_CSP3_START (0x1c000000)
+#define MEM_CSP4_START (0x20000000)
+#define MEM_CSP5_START (0x24000000)
+#define MEM_CSP6_START (0x28000000)
+#define MEM_CSP7_START (0x2c000000)
+#define MEM_INTMEM_START (0x38000000)
+#define MEM_INTMEM_SIZE (0x00020000)
+#define MEM_DRAM_START (0x40000000)
+
+#define MEM_NON_CACHEABLE (0x80000000)
+
+#endif
diff --git a/include/asm-cris/arch-v32/mmu.h b/include/asm-cris/arch-v32/mmu.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/mmu.h
@@ -0,0 +1,111 @@
+#ifndef _ASM_CRIS_ARCH_MMU_H
+#define _ASM_CRIS_ARCH_MMU_H
+
+/* MMU context type. */
+typedef struct
+{
+  unsigned int page_id;
+} mm_context_t;
+
+/* Kernel memory segments. */
+#define KSEG_F 0xf0000000UL
+#define KSEG_E 0xe0000000UL
+#define KSEG_D 0xd0000000UL
+#define KSEG_C 0xc0000000UL
+#define KSEG_B 0xb0000000UL
+#define KSEG_A 0xa0000000UL
+#define KSEG_9 0x90000000UL
+#define KSEG_8 0x80000000UL
+#define KSEG_7 0x70000000UL
+#define KSEG_6 0x60000000UL
+#define KSEG_5 0x50000000UL
+#define KSEG_4 0x40000000UL
+#define KSEG_3 0x30000000UL
+#define KSEG_2 0x20000000UL
+#define KSEG_1 0x10000000UL
+#define KSEG_0 0x00000000UL
+
+/*
+ * CRISv32 PTE bits:
+ *
+ *  Bit:  31-13  12-5     4        3       2        1        0
+ *       +-----+------+--------+-------+--------+-------+---------+
+ *       | pfn | zero | global | valid | kernel | write | execute |
+ *       +-----+------+--------+-------+--------+-------+---------+
+ */
+
+/*
+ * Defines for accessing the bits. Also define some synonyms for use with
+ * the software-based defined bits below.
+ */
+#define _PAGE_EXECUTE       (1 << 0)	/* Execution bit. */
+#define _PAGE_WE            (1 << 1)	/* Write bit. */
+#define _PAGE_SILENT_WRITE  (1 << 1)	/* Same as above. */
+#define _PAGE_KERNEL        (1 << 2)	/* Kernel mode page. */
+#define _PAGE_VALID         (1 << 3)	/* Page is valid. */
+#define _PAGE_SILENT_READ   (1 << 3)	/* Same as above. */
+#define _PAGE_GLOBAL        (1 << 4)	/* Global page. */
+
+/*
+ * The hardware doesn't care about these bits, but the kernel uses them in
+ * software.
+ */
+#define _PAGE_PRESENT   (1 << 5)   /* Page is present in memory. */
+#define _PAGE_FILE      (1 << 6)   /* 1=pagecache, 0=swap (when !present) */
+#define _PAGE_ACCESSED  (1 << 6)   /* Simulated in software using valid bit. */
+#define _PAGE_MODIFIED  (1 << 7)   /* Simulated in software using we bit. */
+#define _PAGE_READ      (1 << 8)   /* Read enabled. */
+#define _PAGE_WRITE     (1 << 9)   /* Write enabled. */
+
+/* Define some higher level generic page attributes. */
+#define __READABLE      (_PAGE_READ | _PAGE_SILENT_READ | _PAGE_ACCESSED)
+#define __WRITEABLE     (_PAGE_WRITE | _PAGE_SILENT_WRITE | _PAGE_MODIFIED)
+
+#define _PAGE_TABLE	(_PAGE_PRESENT | __READABLE | __WRITEABLE)
+#define _PAGE_CHG_MASK  (PAGE_MASK | _PAGE_ACCESSED | _PAGE_MODIFIED)
+
+#define PAGE_NONE       __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED)
+#define PAGE_SHARED     __pgprot(_PAGE_PRESENT | __READABLE | _PAGE_WRITE | \
+                                 _PAGE_ACCESSED)
+#define PAGE_SHARED_EXEC __pgprot(_PAGE_PRESENT | __READABLE | _PAGE_WRITE | \
+                                  _PAGE_ACCESSED | _PAGE_EXECUTE)
+
+#define PAGE_READONLY   __pgprot(_PAGE_PRESENT | __READABLE)
+#define PAGE_READONLY_EXEC __pgprot(_PAGE_PRESENT | __READABLE | _PAGE_EXECUTE | _PAGE_ACCESSED)
+
+#define PAGE_COPY       __pgprot(_PAGE_PRESENT | __READABLE)
+#define PAGE_COPY_EXEC	__pgprot(_PAGE_PRESENT | __READABLE | _PAGE_EXECUTE)
+#define PAGE_KERNEL     __pgprot(_PAGE_GLOBAL | _PAGE_KERNEL | \
+                                 _PAGE_PRESENT | __READABLE | __WRITEABLE)
+#define PAGE_KERNEL_EXEC __pgprot(_PAGE_GLOBAL | _PAGE_KERNEL | _PAGE_EXECUTE | \
+                                 _PAGE_PRESENT | __READABLE | __WRITEABLE)
+#define PAGE_SIGNAL_TRAMPOLINE __pgprot(_PAGE_GLOBAL | _PAGE_EXECUTE | \
+                                       _PAGE_PRESENT | __READABLE)
+
+#define _KERNPG_TABLE   (_PAGE_TABLE | _PAGE_KERNEL)
+
+/* CRISv32 can do page protection for execute.
+ * Write permissions imply read permissions.
+ * Note that the numbers are in Execute-Write-Read order!
+ */
+#define __P000  PAGE_NONE
+#define __P001  PAGE_READONLY
+#define __P010  PAGE_COPY
+#define __P011  PAGE_COPY
+#define __P100  PAGE_READONLY_EXEC
+#define __P101  PAGE_READONLY_EXEC
+#define __P110  PAGE_COPY_EXEC
+#define __P111  PAGE_COPY_EXEC
+
+#define __S000  PAGE_NONE
+#define __S001  PAGE_READONLY
+#define __S010  PAGE_SHARED
+#define __S011  PAGE_SHARED
+#define __S100  PAGE_READONLY_EXEC
+#define __S101  PAGE_READONLY_EXEC
+#define __S110  PAGE_SHARED_EXEC
+#define __S111  PAGE_SHARED_EXEC
+
+#define PTE_FILE_MAX_BITS	25
+
+#endif /* _ASM_CRIS_ARCH_MMU_H */
diff --git a/include/asm-cris/arch-v32/offset.h b/include/asm-cris/arch-v32/offset.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/offset.h
@@ -0,0 +1,35 @@
+#ifndef __ASM_OFFSETS_H__
+#define __ASM_OFFSETS_H__
+/*
+ * DO NOT MODIFY.
+ *
+ * This file was generated by arch/cris/Makefile
+ *
+ */
+
+#define PT_orig_r10 0 /* offsetof(struct pt_regs, orig_r10) */
+#define PT_r13 56 /* offsetof(struct pt_regs, r13) */
+#define PT_r12 52 /* offsetof(struct pt_regs, r12) */
+#define PT_r11 48 /* offsetof(struct pt_regs, r11) */
+#define PT_r10 44 /* offsetof(struct pt_regs, r10) */
+#define PT_r9 40 /* offsetof(struct pt_regs, r9) */
+#define PT_acr 60 /* offsetof(struct pt_regs, acr) */
+#define PT_srs 64 /* offsetof(struct pt_regs, srs) */
+#define PT_mof 68 /* offsetof(struct pt_regs, mof) */
+#define PT_ccs 76 /* offsetof(struct pt_regs, ccs) */
+#define PT_srp 80 /* offsetof(struct pt_regs, srp) */
+
+#define TI_task 0 /* offsetof(struct thread_info, task) */
+#define TI_flags 8 /* offsetof(struct thread_info, flags) */
+#define TI_preempt_count 16 /* offsetof(struct thread_info, preempt_count) */
+
+#define THREAD_ksp 0 /* offsetof(struct thread_struct, ksp) */
+#define THREAD_usp 4 /* offsetof(struct thread_struct, usp) */
+#define THREAD_ccs 8 /* offsetof(struct thread_struct, ccs) */
+
+#define TASK_pid 149 /* offsetof(struct task_struct, pid) */
+
+#define LCLONE_VM 256 /* CLONE_VM */
+#define LCLONE_UNTRACED 8388608 /* CLONE_UNTRACED */
+
+#endif
diff --git a/include/asm-cris/arch-v32/page.h b/include/asm-cris/arch-v32/page.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/page.h
@@ -0,0 +1,28 @@
+#ifndef _ASM_CRIS_ARCH_PAGE_H
+#define _ASM_CRIS_ARCH_PAGE_H
+
+#include <linux/config.h>
+
+#ifdef __KERNEL__
+
+#define PAGE_OFFSET KSEG_C	/* kseg_c is mapped to physical ram. */
+
+/*
+ * Macros to convert between physical and virtual addresses. By stripiing a
+ * selected bit it's possible to convert between KSEG_x and 0x40000000 where the
+ * DRAM really resides. DRAM is virtually at 0xc.
+ */
+#ifndef CONFIG_ETRAXFS_SIM
+#define __pa(x) ((unsigned long)(x) & 0x7fffffff)
+#define __va(x) ((void *)((unsigned long)(x) | 0x80000000))
+#else
+#define __pa(x) ((unsigned long)(x) & 0x3fffffff)
+#define __va(x) ((void *)((unsigned long)(x) | 0xc0000000))
+#endif
+
+#define VM_STACK_DEFAULT_FLAGS	(VM_READ | VM_WRITE | \
+				 VM_MAYREAD | VM_MAYWRITE)
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_CRIS_ARCH_PAGE_H */
diff --git a/include/asm-cris/arch-v32/pgtable.h b/include/asm-cris/arch-v32/pgtable.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/pgtable.h
@@ -0,0 +1,9 @@
+#ifndef _ASM_CRIS_ARCH_PGTABLE_H
+#define _ASM_CRIS_ARCH_PGTABLE_H
+
+/* Define the kernels virtual memory area. */
+#define VMALLOC_START		KSEG_D
+#define VMALLOC_END		KSEG_E
+#define VMALLOC_VMADDR(x)	((unsigned long)(x))
+
+#endif /* _ASM_CRIS_ARCH_PGTABLE_H */
diff --git a/include/asm-cris/arch-v32/pinmux.h b/include/asm-cris/arch-v32/pinmux.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/pinmux.h
@@ -0,0 +1,39 @@
+#ifndef _ASM_CRIS_ARCH_PINMUX_H
+#define _ASM_CRIS_ARCH_PINMUX_H
+
+#define PORT_B 0
+#define PORT_C 1
+#define PORT_D 2
+#define PORT_E 3
+
+enum pin_mode
+{
+  pinmux_none = 0,
+  pinmux_fixed,
+  pinmux_gpio,
+  pinmux_iop
+};
+
+enum fixed_function
+{
+  pinmux_ser1,
+  pinmux_ser2,
+  pinmux_ser3,
+  pinmux_sser0,
+  pinmux_sser1,
+  pinmux_ata0,
+  pinmux_ata1,
+  pinmux_ata2,
+  pinmux_ata3,
+  pinmux_ata,
+  pinmux_eth1,
+  pinmux_timer
+};
+
+int crisv32_pinmux_init(void);
+int crisv32_pinmux_alloc(int port, int first_pin, int last_pin, enum pin_mode);
+int crisv32_pinmux_alloc_fixed(enum fixed_function function);
+int crisv32_pinmux_dealloc(int port, int first_pin, int last_pin);
+void crisv32_pinmux_dump(void);
+
+#endif
diff --git a/include/asm-cris/arch-v32/processor.h b/include/asm-cris/arch-v32/processor.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/processor.h
@@ -0,0 +1,60 @@
+#ifndef _ASM_CRIS_ARCH_PROCESSOR_H
+#define _ASM_CRIS_ARCH_PROCESSOR_H
+
+#include <linux/config.h>
+
+/* Return current instruction pointer. */
+#define current_text_addr() \
+	({void *pc; __asm__ __volatile__ ("lapcq .,%0" : "=rm" (pc)); pc;})
+
+/*
+ * Since CRIS doesn't do hardware task-switching this hasn't really anything to
+ * do with the proccessor itself, it's just here for legacy reasons. This is
+ * used when task-switching using _resume defined in entry.S. The offsets here
+ * are hardcoded into _resume, so if this struct is changed, entry.S needs to be
+ * changed as well.
+ */
+struct thread_struct {
+	unsigned long ksp;	/* Kernel stack pointer. */
+	unsigned long usp;	/* User stack pointer. */
+	unsigned long ccs;	/* Saved flags register. */
+};
+
+/*
+ * User-space process size. This is hardcoded into a few places, so don't
+ * changed it unless everything's clear!
+ */
+#ifndef CONFIG_ETRAXFS_SIM
+#define TASK_SIZE	(0xB0000000UL)
+#else
+#define TASK_SIZE	(0xA0000000UL)
+#endif
+
+/* CCS I=1, enable interrupts. */
+#define INIT_THREAD { 0, 0, (1 << I_CCS_BITNR) }
+
+#define KSTK_EIP(tsk)		\
+({				\
+	unsigned long eip = 0;	\
+	unsigned long regs = (unsigned long)user_regs(tsk); \
+	if (regs > PAGE_SIZE && virt_addr_valid(regs))	    \
+		eip = ((struct pt_regs *)regs)->erp;	    \
+	eip; \
+})
+
+/*
+ * Give the thread a program location, set user-mode and switch user
+ * stackpointer.
+ */
+#define start_thread(regs, ip, usp) \
+do { \
+	set_fs(USER_DS); \
+	regs->erp = ip; \
+	regs->ccs |= 1 << (U_CCS_BITNR + CCS_SHIFT); \
+	wrusp(usp); \
+} while(0)
+
+/* Nothing special to do for v32 when handling a kernel bus fault fixup. */
+#define arch_fixup(regs) {};
+
+#endif /* _ASM_CRIS_ARCH_PROCESSOR_H */
diff --git a/include/asm-cris/arch-v32/ptrace.h b/include/asm-cris/arch-v32/ptrace.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/ptrace.h
@@ -0,0 +1,114 @@
+#ifndef _CRIS_ARCH_PTRACE_H
+#define _CRIS_ARCH_PTRACE_H
+
+/* Register numbers in the ptrace system call interface */
+
+#define PT_ORIG_R10  0
+#define PT_R0        1
+#define PT_R1        2
+#define PT_R2        3
+#define PT_R3        4
+#define PT_R4        5
+#define PT_R5        6
+#define PT_R6        7
+#define PT_R7        8
+#define PT_R8        9
+#define PT_R9        10
+#define PT_R10       11
+#define PT_R11       12
+#define PT_R12       13
+#define PT_R13       14
+#define PT_ACR       15
+#define PT_SRS       16
+#define PT_MOF       17
+#define PT_SPC       18
+#define PT_CCS       19
+#define PT_SRP       20
+#define PT_ERP       21    /* This is actually the debugged process' PC */
+#define PT_EXS       22
+#define PT_EDA       23
+#define PT_USP       24    /* special case - USP is not in the pt_regs */
+#define PT_PPC       25    /* special case - pseudo PC */
+#define PT_BP        26    /* Base number for BP registers. */
+#define PT_BP_CTRL   26    /* BP control register. */
+#define PT_MAX       40
+
+/* Condition code bit numbers. */
+#define C_CCS_BITNR 0
+#define V_CCS_BITNR 1
+#define Z_CCS_BITNR 2
+#define N_CCS_BITNR 3
+#define X_CCS_BITNR 4
+#define I_CCS_BITNR 5
+#define U_CCS_BITNR 6
+#define P_CCS_BITNR 7
+#define R_CCS_BITNR 8
+#define S_CCS_BITNR 9
+#define M_CCS_BITNR 30
+#define Q_CCS_BITNR 31
+#define CCS_SHIFT   10 /* Shift count for each level in CCS */
+
+/* pt_regs not only specifices the format in the user-struct during
+ * ptrace but is also the frame format used in the kernel prologue/epilogues
+ * themselves
+ */
+
+struct pt_regs {
+	unsigned long orig_r10;
+	/* pushed by movem r13, [sp] in SAVE_ALL. */
+	unsigned long r0;
+	unsigned long r1;
+	unsigned long r2;
+	unsigned long r3;
+	unsigned long r4;
+	unsigned long r5;
+	unsigned long r6;
+	unsigned long r7;
+	unsigned long r8;
+	unsigned long r9;
+	unsigned long r10;
+	unsigned long r11;
+	unsigned long r12;
+	unsigned long r13;
+	unsigned long acr;
+	unsigned long srs;
+	unsigned long mof;
+	unsigned long spc;
+	unsigned long ccs;
+	unsigned long srp;
+	unsigned long erp; /* This is actually the debugged process' PC */
+	/* For debugging purposes; saved only when needed. */
+	unsigned long exs;
+	unsigned long eda;
+};
+
+/* switch_stack is the extra stuff pushed onto the stack in _resume (entry.S)
+ * when doing a context-switch. it is used (apart from in resume) when a new
+ * thread is made and we need to make _resume (which is starting it for the
+ * first time) realise what is going on.
+ *
+ * Actually, the use is very close to the thread struct (TSS) in that both the
+ * switch_stack and the TSS are used to keep thread stuff when switching in
+ * _resume.
+ */
+
+struct switch_stack {
+	unsigned long r0;
+	unsigned long r1;
+	unsigned long r2;
+	unsigned long r3;
+	unsigned long r4;
+	unsigned long r5;
+	unsigned long r6;
+	unsigned long r7;
+	unsigned long r8;
+	unsigned long r9;
+	unsigned long return_ip; /* ip that _resume will return to */
+};
+
+#define user_mode(regs) (((regs)->ccs & (1 << (U_CCS_BITNR + CCS_SHIFT))) != 0)
+#define instruction_pointer(regs) ((regs)->erp)
+extern void show_regs(struct pt_regs *);
+#define profile_pc(regs) instruction_pointer(regs)
+
+#endif
diff --git a/include/asm-cris/arch-v32/spinlock.h b/include/asm-cris/arch-v32/spinlock.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/spinlock.h
@@ -0,0 +1,163 @@
+#ifndef __ASM_ARCH_SPINLOCK_H
+#define __ASM_ARCH_SPINLOCK_H
+
+#include <asm/system.h>
+
+#define RW_LOCK_BIAS 0x01000000
+#define SPIN_LOCK_UNLOCKED (spinlock_t) { 1 }
+#define spin_lock_init(x)	do { *(x) = SPIN_LOCK_UNLOCKED; } while(0)
+
+#define spin_is_locked(x)	(*(volatile signed char *)(&(x)->lock) <= 0)
+#define spin_unlock_wait(x)	do { barrier(); } while(spin_is_locked(x))
+
+extern void cris_spin_unlock(void *l, int val);
+extern void cris_spin_lock(void *l);
+extern int cris_spin_trylock(void* l);
+
+static inline void _raw_spin_unlock(spinlock_t *lock)
+{
+	__asm__ volatile ("move.d %1,%0" \
+	                  : "=m" (lock->lock) \
+			  : "r" (1) \
+			  : "memory");
+}
+
+static inline int _raw_spin_trylock(spinlock_t *lock)
+{
+	return cris_spin_trylock((void*)&lock->lock);
+}
+
+static inline void _raw_spin_lock(spinlock_t *lock)
+{
+	cris_spin_lock((void*)&lock->lock);
+}
+
+static inline void _raw_spin_lock_flags (spinlock_t *lock, unsigned long flags)
+{
+  _raw_spin_lock(lock);
+}
+
+/*
+ * Read-write spinlocks, allowing multiple readers
+ * but only one writer.
+ *
+ * NOTE! it is quite common to have readers in interrupts
+ * but no interrupt writers. For those circumstances we
+ * can "mix" irq-safe locks - any writer needs to get a
+ * irq-safe write-lock, but readers can get non-irqsafe
+ * read-locks.
+ */
+typedef struct {
+	spinlock_t lock;
+	volatile int counter;
+#ifdef CONFIG_PREEMPT
+	unsigned int break_lock;
+#endif
+} rwlock_t;
+
+#define RW_LOCK_UNLOCKED (rwlock_t) { {1}, 0 }
+
+#define rwlock_init(lp)	do { *(lp) = RW_LOCK_UNLOCKED; } while (0)
+
+/**
+ * read_can_lock - would read_trylock() succeed?
+ * @lock: the rwlock in question.
+ */
+#define read_can_lock(x) ((int)(x)->counter >= 0)
+
+/**
+ * write_can_lock - would write_trylock() succeed?
+ * @lock: the rwlock in question.
+ */
+#define write_can_lock(x) ((x)->counter == 0)
+
+#define _raw_read_trylock(lock) generic_raw_read_trylock(lock)
+
+/* read_lock, read_unlock are pretty straightforward.  Of course it somehow
+ * sucks we end up saving/restoring flags twice for read_lock_irqsave aso. */
+
+static  __inline__ void _raw_read_lock(rwlock_t *rw)
+{
+	unsigned long flags;
+	local_irq_save(flags);
+	_raw_spin_lock(&rw->lock);
+
+	rw->counter++;
+
+	_raw_spin_unlock(&rw->lock);
+	local_irq_restore(flags);
+}
+
+static  __inline__ void _raw_read_unlock(rwlock_t *rw)
+{
+	unsigned long flags;
+	local_irq_save(flags);
+	_raw_spin_lock(&rw->lock);
+
+	rw->counter--;
+
+	_raw_spin_unlock(&rw->lock);
+	local_irq_restore(flags);
+}
+
+/* write_lock is less trivial.  We optimistically grab the lock and check
+ * if we surprised any readers.  If so we release the lock and wait till
+ * they're all gone before trying again
+ *
+ * Also note that we don't use the _irqsave / _irqrestore suffixes here.
+ * If we're called with interrupts enabled and we've got readers (or other
+ * writers) in interrupt handlers someone fucked up and we'd dead-lock
+ * sooner or later anyway.   prumpf */
+
+static  __inline__ void _raw_write_lock(rwlock_t *rw)
+{
+retry:
+	_raw_spin_lock(&rw->lock);
+
+	if(rw->counter != 0) {
+		/* this basically never happens */
+		_raw_spin_unlock(&rw->lock);
+
+		while(rw->counter != 0);
+
+		goto retry;
+	}
+
+	/* got it.  now leave without unlocking */
+	rw->counter = -1; /* remember we are locked */
+}
+
+/* write_unlock is absolutely trivial - we don't have to wait for anything */
+
+static  __inline__ void _raw_write_unlock(rwlock_t *rw)
+{
+	rw->counter = 0;
+	_raw_spin_unlock(&rw->lock);
+}
+
+static  __inline__ int _raw_write_trylock(rwlock_t *rw)
+{
+	_raw_spin_lock(&rw->lock);
+	if (rw->counter != 0) {
+		/* this basically never happens */
+		_raw_spin_unlock(&rw->lock);
+
+		return 0;
+	}
+
+	/* got it.  now leave without unlocking */
+	rw->counter = -1; /* remember we are locked */
+	return 1;
+}
+
+static __inline__ int is_read_locked(rwlock_t *rw)
+{
+	return rw->counter > 0;
+}
+
+static __inline__ int is_write_locked(rwlock_t *rw)
+{
+	return rw->counter < 0;
+}
+
+#endif /* __ASM_ARCH_SPINLOCK_H */
diff --git a/include/asm-cris/arch-v32/system.h b/include/asm-cris/arch-v32/system.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/system.h
@@ -0,0 +1,79 @@
+#ifndef _ASM_CRIS_ARCH_SYSTEM_H
+#define _ASM_CRIS_ARCH_SYSTEM_H
+
+#include <linux/config.h>
+
+/* Read the CPU version register. */
+extern inline unsigned long rdvr(void)
+{
+	unsigned char vr;
+
+	__asm__ __volatile__ ("move $vr, %0" : "=rm" (vr));
+	return vr;
+}
+
+#define cris_machine_name "crisv32"
+
+/* Read the user-mode stack pointer. */
+extern inline unsigned long rdusp(void)
+{
+	unsigned long usp;
+
+	__asm__ __volatile__ ("move $usp, %0" : "=rm" (usp));
+	return usp;
+}
+
+/* Read the current stack pointer. */
+extern inline unsigned long rdsp(void)
+{
+	unsigned long sp;
+
+	__asm__ __volatile__ ("move.d $sp, %0" : "=rm" (sp));
+	return sp;
+}
+
+/* Write the user-mode stack pointer. */
+#define wrusp(usp) __asm__ __volatile__ ("move %0, $usp" : : "rm" (usp))
+
+#define nop() __asm__ __volatile__ ("nop");
+
+#define xchg(ptr,x) \
+	((__typeof__(*(ptr)))__xchg((unsigned long) (x),(ptr),sizeof(*(ptr))))
+
+#define tas(ptr) (xchg((ptr),1))
+
+struct __xchg_dummy { unsigned long a[100]; };
+#define __xg(x) ((struct __xchg_dummy *)(x))
+
+/* Used for interrupt control. */
+#define local_save_flags(x) \
+	__asm__ __volatile__ ("move $ccs, %0" : "=rm" (x) : : "memory");
+
+#define local_irq_restore(x) \
+	__asm__ __volatile__ ("move %0, $ccs" : : "rm" (x) : "memory");
+
+#define local_irq_disable()  __asm__ __volatile__ ("di" : : : "memory");
+#define local_irq_enable()   __asm__ __volatile__ ("ei" : : : "memory");
+
+#define irqs_disabled()		\
+({				\
+	unsigned long flags;	\
+				\
+	local_save_flags(flags);\
+	!(flags & (1 << I_CCS_BITNR));	\
+})
+
+/* Used for spinlocks, etc. */
+#define local_irq_save(x) \
+	__asm__ __volatile__ ("move $ccs, %0\n\tdi" : "=rm" (x) : : "memory");
+
+#ifdef CONFIG_SMP
+typedef struct {
+	volatile unsigned int lock __attribute__ ((aligned(4)));
+#ifdef CONFIG_PREEMPT
+	unsigned int break_lock;
+#endif
+} spinlock_t;
+#endif
+
+#endif /* _ASM_CRIS_ARCH_SYSTEM_H */
diff --git a/include/asm-cris/arch-v32/thread_info.h b/include/asm-cris/arch-v32/thread_info.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/thread_info.h
@@ -0,0 +1,13 @@
+#ifndef _ASM_CRIS_ARCH_THREAD_INFO_H
+#define _ASM_CRIS_ARCH_THREAD_INFO_H
+
+/* Return a thread_info struct. */
+extern inline struct thread_info *current_thread_info(void)
+{
+	struct thread_info *ti;
+
+	__asm__ __volatile__ ("and.d $sp, %0" : "=r" (ti) : "0" (~8191UL));
+	return ti;
+}
+
+#endif /* _ASM_CRIS_ARCH_THREAD_INFO_H */
diff --git a/include/asm-cris/arch-v32/timex.h b/include/asm-cris/arch-v32/timex.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/timex.h
@@ -0,0 +1,31 @@
+#ifndef _ASM_CRIS_ARCH_TIMEX_H
+#define _ASM_CRIS_ARCH_TIMEX_H
+
+#include <asm/arch/hwregs/reg_map.h>
+#include <asm/arch/hwregs/reg_rdwr.h>
+#include <asm/arch/hwregs/timer_defs.h>
+
+/*
+ * The clock runs at 100MHz, we divide it by 1000000. If you change anything
+ * here you must check time.c as well.
+ */
+
+#define CLOCK_TICK_RATE 100000000	/* Underlying frequency of the HZ timer */
+
+/* The timer0 values gives 10 ns resolution but interrupts at HZ. */
+#define TIMER0_FREQ (CLOCK_TICK_RATE)
+#define TIMER0_DIV (TIMER0_FREQ/(HZ))
+
+/* Convert the value in step of 10 ns to 1us without overflow: */
+#define GET_JIFFIES_USEC() \
+  ( (TIMER0_DIV - REG_RD(timer, regi_timer, r_tmr0_data)) /100 )
+
+extern unsigned long get_ns_in_jiffie(void);
+
+extern inline unsigned long get_us_in_jiffie_highres(void)
+{
+	return get_ns_in_jiffie() / 1000;
+}
+
+#endif
+
diff --git a/include/asm-cris/arch-v32/tlb.h b/include/asm-cris/arch-v32/tlb.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/tlb.h
@@ -0,0 +1,14 @@
+#ifndef _CRIS_ARCH_TLB_H
+#define _CRIS_ARCH_TLB_H
+
+/*
+ * The TLB is a 64-entry cache. Each entry has a 8-bit page_id that is used
+ * to store the "process" it belongs to (=> fast mm context switch). The
+ * last page_id is never used so we can make TLB entries that never matches.
+ */
+#define NUM_TLB_ENTRIES 64
+#define NUM_PAGEID 256
+#define INVALID_PAGEID 255
+#define NO_CONTEXT -1
+
+#endif /* _CRIS_ARCH_TLB_H */
diff --git a/include/asm-cris/arch-v32/uaccess.h b/include/asm-cris/arch-v32/uaccess.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/uaccess.h
@@ -0,0 +1,748 @@
+/*
+ * Authors:    Hans-Peter Nilsson (hp@axis.com)
+ *
+ */
+#ifndef _CRIS_ARCH_UACCESS_H
+#define _CRIS_ARCH_UACCESS_H
+
+/*
+ * We don't tell gcc that we are accessing memory, but this is OK
+ * because we do not write to any memory gcc knows about, so there
+ * are no aliasing issues.
+ *
+ * Note that PC at a fault is the address *at* the faulting
+ * instruction for CRISv32.
+ */
+#define __put_user_asm(x, addr, err, op)			\
+	__asm__ __volatile__(					\
+		"2:	"op" %1,[%2]\n"				\
+		"4:\n"						\
+		"	.section .fixup,\"ax\"\n"		\
+		"3:	move.d %3,%0\n"				\
+		"	jump 4b\n"				\
+		"	nop\n"					\
+		"	.previous\n"				\
+		"	.section __ex_table,\"a\"\n"		\
+		"	.dword 2b,3b\n"				\
+		"	.previous\n"				\
+		: "=r" (err)					\
+		: "r" (x), "r" (addr), "g" (-EFAULT), "0" (err))
+
+#define __put_user_asm_64(x, addr, err) do {			\
+	int dummy_for_put_user_asm_64_;				\
+	__asm__ __volatile__(					\
+		"2:	move.d %M2,[%1+]\n"			\
+		"4:	move.d %H2,[%1]\n"			\
+		"5:\n"						\
+		"	.section .fixup,\"ax\"\n"		\
+		"3:	move.d %4,%0\n"				\
+		"	jump 5b\n"				\
+		"	.previous\n"				\
+		"	.section __ex_table,\"a\"\n"		\
+		"	.dword 2b,3b\n"				\
+		"	.dword 4b,3b\n"				\
+		"	.previous\n"				\
+		: "=r" (err), "=b" (dummy_for_put_user_asm_64_)	\
+		: "r" (x), "1" (addr), "g" (-EFAULT),		\
+		  "0" (err));					\
+	} while (0)
+
+/* See comment before __put_user_asm.  */
+
+#define __get_user_asm(x, addr, err, op)		\
+	__asm__ __volatile__(				\
+		"2:	"op" [%2],%1\n"			\
+		"4:\n"					\
+		"	.section .fixup,\"ax\"\n"	\
+		"3:	move.d %3,%0\n"			\
+		"	jump 4b\n"			\
+		"	moveq 0,%1\n"			\
+		"	.previous\n"			\
+		"	.section __ex_table,\"a\"\n"	\
+		"	.dword 2b,3b\n"			\
+		"	.previous\n"			\
+		: "=r" (err), "=r" (x)			\
+		: "r" (addr), "g" (-EFAULT), "0" (err))
+
+#define __get_user_asm_64(x, addr, err) do {		\
+	int dummy_for_get_user_asm_64_;			\
+	__asm__ __volatile__(				\
+		"2:	move.d [%2+],%M1\n"		\
+		"4:	move.d [%2],%H1\n"		\
+		"5:\n"					\
+		"	.section .fixup,\"ax\"\n"	\
+		"3:	move.d %4,%0\n"			\
+		"	jump 5b\n"			\
+		"	moveq 0,%1\n"			\
+		"	.previous\n"			\
+		"	.section __ex_table,\"a\"\n"	\
+		"	.dword 2b,3b\n"			\
+		"	.dword 4b,3b\n"			\
+		"	.previous\n"			\
+		: "=r" (err), "=r" (x),			\
+		  "=b" (dummy_for_get_user_asm_64_)	\
+		: "2" (addr), "g" (-EFAULT), "0" (err));\
+	} while (0)
+
+/*
+ * Copy a null terminated string from userspace.
+ *
+ * Must return:
+ * -EFAULT		for an exception
+ * count		if we hit the buffer limit
+ * bytes copied		if we hit a null byte
+ * (without the null byte)
+ */
+extern inline long
+__do_strncpy_from_user(char *dst, const char *src, long count)
+{
+	long res;
+
+	if (count == 0)
+		return 0;
+
+	/*
+	 * Currently, in 2.4.0-test9, most ports use a simple byte-copy loop.
+	 *  So do we.
+	 *
+	 *  This code is deduced from:
+	 *
+	 *	char tmp2;
+	 *	long tmp1, tmp3;
+	 *	tmp1 = count;
+	 *	while ((*dst++ = (tmp2 = *src++)) != 0
+	 *	       && --tmp1)
+	 *	  ;
+	 *
+	 *	res = count - tmp1;
+	 *
+	 *  with tweaks.
+	 */
+
+	__asm__ __volatile__ (
+		"	move.d %3,%0\n"
+		"5:	move.b [%2+],$acr\n"
+		"1:	beq 2f\n"
+		"	move.b $acr,[%1+]\n"
+
+		"	subq 1,%0\n"
+		"2:	bne 1b\n"
+		"	move.b [%2+],$acr\n"
+
+		"	sub.d %3,%0\n"
+		"	neg.d %0,%0\n"
+		"3:\n"
+		"	.section .fixup,\"ax\"\n"
+		"4:	move.d %7,%0\n"
+		"	jump 3b\n"
+		"	nop\n"
+
+		/* The address for a fault at the first move is trivial.
+		   The address for a fault at the second move is that of
+		   the preceding branch insn, since the move insn is in
+		   its delay-slot.  That address is also a branch
+		   target.  Just so you don't get confused...  */
+		"	.previous\n"
+		"	.section __ex_table,\"a\"\n"
+		"	.dword 5b,4b\n"
+		"	.dword 2b,4b\n"
+		"	.previous"
+		: "=r" (res), "=b" (dst), "=b" (src), "=r" (count)
+		: "3" (count), "1" (dst), "2" (src), "g" (-EFAULT)
+		: "acr");
+
+	return res;
+}
+
+/* A few copy asms to build up the more complex ones from.
+
+   Note again, a post-increment is performed regardless of whether a bus
+   fault occurred in that instruction, and PC for a faulted insn is the
+   address for the insn, or for the preceding branch when in a delay-slot.  */
+
+#define __asm_copy_user_cont(to, from, ret, COPY, FIXUP, TENTRY) \
+	__asm__ __volatile__ (				\
+			COPY				\
+		"1:\n"					\
+		"	.section .fixup,\"ax\"\n"	\
+			FIXUP				\
+		"	.previous\n"			\
+		"	.section __ex_table,\"a\"\n"	\
+			TENTRY				\
+		"	.previous\n"			\
+		: "=b" (to), "=b" (from), "=r" (ret)	\
+		: "0" (to), "1" (from), "2" (ret)	\
+		: "acr", "memory")
+
+#define __asm_copy_from_user_1(to, from, ret) \
+	__asm_copy_user_cont(to, from, ret,	\
+		"2:	move.b [%1+],$acr\n"	\
+		"	move.b $acr,[%0+]\n",	\
+		"3:	addq 1,%2\n"		\
+		"	jump 1b\n"		\
+		"	clear.b [%0+]\n",	\
+		"	.dword 2b,3b\n")
+
+#define __asm_copy_from_user_2x_cont(to, from, ret, COPY, FIXUP, TENTRY) \
+	__asm_copy_user_cont(to, from, ret,		\
+			COPY				\
+		"2:	move.w [%1+],$acr\n"		\
+		"	move.w $acr,[%0+]\n",		\
+			FIXUP				\
+		"3:	addq 2,%2\n"			\
+		"	jump 1b\n"			\
+		"	clear.w [%0+]\n",		\
+			TENTRY				\
+		"	.dword 2b,3b\n")
+
+#define __asm_copy_from_user_2(to, from, ret) \
+	__asm_copy_from_user_2x_cont(to, from, ret, "", "", "")
+
+#define __asm_copy_from_user_3(to, from, ret)		\
+	__asm_copy_from_user_2x_cont(to, from, ret,	\
+		"4:	move.b [%1+],$acr\n"		\
+		"	move.b $acr,[%0+]\n",		\
+		"5:	addq 1,%2\n"			\
+		"	clear.b [%0+]\n",		\
+		"	.dword 4b,5b\n")
+
+#define __asm_copy_from_user_4x_cont(to, from, ret, COPY, FIXUP, TENTRY) \
+	__asm_copy_user_cont(to, from, ret,		\
+			COPY				\
+		"2:	move.d [%1+],$acr\n"		\
+		"	move.d $acr,[%0+]\n",		\
+			FIXUP				\
+		"3:	addq 4,%2\n"			\
+		"	jump 1b\n"			\
+		"	clear.d [%0+]\n",		\
+			TENTRY				\
+		"	.dword 2b,3b\n")
+
+#define __asm_copy_from_user_4(to, from, ret) \
+	__asm_copy_from_user_4x_cont(to, from, ret, "", "", "")
+
+#define __asm_copy_from_user_5(to, from, ret) \
+	__asm_copy_from_user_4x_cont(to, from, ret,	\
+		"4:	move.b [%1+],$acr\n"		\
+		"	move.b $acr,[%0+]\n",		\
+		"5:	addq 1,%2\n"			\
+		"	clear.b [%0+]\n",		\
+		"	.dword 4b,5b\n")
+
+#define __asm_copy_from_user_6x_cont(to, from, ret, COPY, FIXUP, TENTRY) \
+	__asm_copy_from_user_4x_cont(to, from, ret,	\
+			COPY				\
+		"4:	move.w [%1+],$acr\n"		\
+		"	move.w $acr,[%0+]\n",		\
+			FIXUP				\
+		"5:	addq 2,%2\n"			\
+		"	clear.w [%0+]\n",		\
+			TENTRY				\
+		"	.dword 4b,5b\n")
+
+#define __asm_copy_from_user_6(to, from, ret) \
+	__asm_copy_from_user_6x_cont(to, from, ret, "", "", "")
+
+#define __asm_copy_from_user_7(to, from, ret) \
+	__asm_copy_from_user_6x_cont(to, from, ret,	\
+		"6:	move.b [%1+],$acr\n"		\
+		"	move.b $acr,[%0+]\n",		\
+		"7:	addq 1,%2\n"			\
+		"	clear.b [%0+]\n",		\
+		"	.dword 6b,7b\n")
+
+#define __asm_copy_from_user_8x_cont(to, from, ret, COPY, FIXUP, TENTRY) \
+	__asm_copy_from_user_4x_cont(to, from, ret,	\
+			COPY				\
+		"4:	move.d [%1+],$acr\n"		\
+		"	move.d $acr,[%0+]\n",		\
+			FIXUP				\
+		"5:	addq 4,%2\n"			\
+		"	clear.d [%0+]\n",		\
+			TENTRY				\
+		"	.dword 4b,5b\n")
+
+#define __asm_copy_from_user_8(to, from, ret) \
+	__asm_copy_from_user_8x_cont(to, from, ret, "", "", "")
+
+#define __asm_copy_from_user_9(to, from, ret) \
+	__asm_copy_from_user_8x_cont(to, from, ret,	\
+		"6:	move.b [%1+],$acr\n"		\
+		"	move.b $acr,[%0+]\n",		\
+		"7:	addq 1,%2\n"			\
+		"	clear.b [%0+]\n",		\
+		"	.dword 6b,7b\n")
+
+#define __asm_copy_from_user_10x_cont(to, from, ret, COPY, FIXUP, TENTRY) \
+	__asm_copy_from_user_8x_cont(to, from, ret,	\
+			COPY				\
+		"6:	move.w [%1+],$acr\n"		\
+		"	move.w $acr,[%0+]\n",		\
+			FIXUP				\
+		"7:	addq 2,%2\n"			\
+		"	clear.w [%0+]\n",		\
+			TENTRY				\
+		"	.dword 6b,7b\n")
+
+#define __asm_copy_from_user_10(to, from, ret) \
+	__asm_copy_from_user_10x_cont(to, from, ret, "", "", "")
+
+#define __asm_copy_from_user_11(to, from, ret)		\
+	__asm_copy_from_user_10x_cont(to, from, ret,	\
+		"8:	move.b [%1+],$acr\n"		\
+		"	move.b $acr,[%0+]\n",		\
+		"9:	addq 1,%2\n"			\
+		"	clear.b [%0+]\n",		\
+		"	.dword 8b,9b\n")
+
+#define __asm_copy_from_user_12x_cont(to, from, ret, COPY, FIXUP, TENTRY) \
+	__asm_copy_from_user_8x_cont(to, from, ret,	\
+			COPY				\
+		"6:	move.d [%1+],$acr\n"		\
+		"	move.d $acr,[%0+]\n",		\
+			FIXUP				\
+		"7:	addq 4,%2\n"			\
+		"	clear.d [%0+]\n",		\
+			TENTRY				\
+		"	.dword 6b,7b\n")
+
+#define __asm_copy_from_user_12(to, from, ret) \
+	__asm_copy_from_user_12x_cont(to, from, ret, "", "", "")
+
+#define __asm_copy_from_user_13(to, from, ret) \
+	__asm_copy_from_user_12x_cont(to, from, ret,	\
+		"8:	move.b [%1+],$acr\n"		\
+		"	move.b $acr,[%0+]\n",		\
+		"9:	addq 1,%2\n"			\
+		"	clear.b [%0+]\n",		\
+		"	.dword 8b,9b\n")
+
+#define __asm_copy_from_user_14x_cont(to, from, ret, COPY, FIXUP, TENTRY) \
+	__asm_copy_from_user_12x_cont(to, from, ret,	\
+			COPY				\
+		"8:	move.w [%1+],$acr\n"		\
+		"	move.w $acr,[%0+]\n",		\
+			FIXUP				\
+		"9:	addq 2,%2\n"			\
+		"	clear.w [%0+]\n",		\
+			TENTRY				\
+		"	.dword 8b,9b\n")
+
+#define __asm_copy_from_user_14(to, from, ret) \
+	__asm_copy_from_user_14x_cont(to, from, ret, "", "", "")
+
+#define __asm_copy_from_user_15(to, from, ret) \
+	__asm_copy_from_user_14x_cont(to, from, ret,	\
+		"10:	move.b [%1+],$acr\n"		\
+		"	move.b $acr,[%0+]\n",		\
+		"11:	addq 1,%2\n"			\
+		"	clear.b [%0+]\n",		\
+		"	.dword 10b,11b\n")
+
+#define __asm_copy_from_user_16x_cont(to, from, ret, COPY, FIXUP, TENTRY) \
+	__asm_copy_from_user_12x_cont(to, from, ret,	\
+			COPY				\
+		"8:	move.d [%1+],$acr\n"		\
+		"	move.d $acr,[%0+]\n",		\
+			FIXUP				\
+		"9:	addq 4,%2\n"			\
+		"	clear.d [%0+]\n",		\
+			TENTRY				\
+		"	.dword 8b,9b\n")
+
+#define __asm_copy_from_user_16(to, from, ret) \
+	__asm_copy_from_user_16x_cont(to, from, ret, "", "", "")
+
+#define __asm_copy_from_user_20x_cont(to, from, ret, COPY, FIXUP, TENTRY) \
+	__asm_copy_from_user_16x_cont(to, from, ret,	\
+			COPY				\
+		"10:	move.d [%1+],$acr\n"		\
+		"	move.d $acr,[%0+]\n",		\
+			FIXUP				\
+		"11:	addq 4,%2\n"			\
+		"	clear.d [%0+]\n",		\
+			TENTRY				\
+		"	.dword 10b,11b\n")
+
+#define __asm_copy_from_user_20(to, from, ret) \
+	__asm_copy_from_user_20x_cont(to, from, ret, "", "", "")
+
+#define __asm_copy_from_user_24x_cont(to, from, ret, COPY, FIXUP, TENTRY) \
+	__asm_copy_from_user_20x_cont(to, from, ret,	\
+			COPY				\
+		"12:	move.d [%1+],$acr\n"		\
+		"	move.d $acr,[%0+]\n",		\
+			FIXUP				\
+		"13:	addq 4,%2\n"			\
+		"	clear.d [%0+]\n",		\
+			TENTRY				\
+		"	.dword 12b,13b\n")
+
+#define __asm_copy_from_user_24(to, from, ret) \
+	__asm_copy_from_user_24x_cont(to, from, ret, "", "", "")
+
+/* And now, the to-user ones.  */
+
+#define __asm_copy_to_user_1(to, from, ret)	\
+	__asm_copy_user_cont(to, from, ret,	\
+		"	move.b [%1+],$acr\n"	\
+		"2:	move.b $acr,[%0+]\n",	\
+		"3:	jump 1b\n"		\
+		"	addq 1,%2\n",		\
+		"	.dword 2b,3b\n")
+
+#define __asm_copy_to_user_2x_cont(to, from, ret, COPY, FIXUP, TENTRY) \
+	__asm_copy_user_cont(to, from, ret,		\
+			COPY				\
+		"	move.w [%1+],$acr\n"		\
+		"2:	move.w $acr,[%0+]\n",		\
+			FIXUP				\
+		"3:	jump 1b\n"			\
+		"	addq 2,%2\n",			\
+			TENTRY				\
+		"	.dword 2b,3b\n")
+
+#define __asm_copy_to_user_2(to, from, ret) \
+	__asm_copy_to_user_2x_cont(to, from, ret, "", "", "")
+
+#define __asm_copy_to_user_3(to, from, ret) \
+	__asm_copy_to_user_2x_cont(to, from, ret,	\
+		"	move.b [%1+],$acr\n"		\
+		"4:	move.b $acr,[%0+]\n",		\
+		"5:	addq 1,%2\n",			\
+		"	.dword 4b,5b\n")
+
+#define __asm_copy_to_user_4x_cont(to, from, ret, COPY, FIXUP, TENTRY) \
+	__asm_copy_user_cont(to, from, ret,		\
+			COPY				\
+		"	move.d [%1+],$acr\n"		\
+		"2:	move.d $acr,[%0+]\n",		\
+			FIXUP				\
+		"3:	jump 1b\n"			\
+		"	addq 4,%2\n",			\
+			TENTRY				\
+		"	.dword 2b,3b\n")
+
+#define __asm_copy_to_user_4(to, from, ret) \
+	__asm_copy_to_user_4x_cont(to, from, ret, "", "", "")
+
+#define __asm_copy_to_user_5(to, from, ret) \
+	__asm_copy_to_user_4x_cont(to, from, ret,	\
+		"	move.b [%1+],$acr\n"		\
+		"4:	move.b $acr,[%0+]\n",		\
+		"5:	addq 1,%2\n",			\
+		"	.dword 4b,5b\n")
+
+#define __asm_copy_to_user_6x_cont(to, from, ret, COPY, FIXUP, TENTRY) \
+	__asm_copy_to_user_4x_cont(to, from, ret,	\
+			COPY				\
+		"	move.w [%1+],$acr\n"		\
+		"4:	move.w $acr,[%0+]\n",		\
+			FIXUP				\
+		"5:	addq 2,%2\n",			\
+			TENTRY				\
+		"	.dword 4b,5b\n")
+
+#define __asm_copy_to_user_6(to, from, ret) \
+	__asm_copy_to_user_6x_cont(to, from, ret, "", "", "")
+
+#define __asm_copy_to_user_7(to, from, ret) \
+	__asm_copy_to_user_6x_cont(to, from, ret,	\
+		"	move.b [%1+],$acr\n"		\
+		"6:	move.b $acr,[%0+]\n",		\
+		"7:	addq 1,%2\n",			\
+		"	.dword 6b,7b\n")
+
+#define __asm_copy_to_user_8x_cont(to, from, ret, COPY, FIXUP, TENTRY) \
+	__asm_copy_to_user_4x_cont(to, from, ret,	\
+			COPY				\
+		"	move.d [%1+],$acr\n"		\
+		"4:	move.d $acr,[%0+]\n",		\
+			FIXUP				\
+		"5:	addq 4,%2\n",			\
+			TENTRY				\
+		"	.dword 4b,5b\n")
+
+#define __asm_copy_to_user_8(to, from, ret) \
+	__asm_copy_to_user_8x_cont(to, from, ret, "", "", "")
+
+#define __asm_copy_to_user_9(to, from, ret) \
+	__asm_copy_to_user_8x_cont(to, from, ret,	\
+		"	move.b [%1+],$acr\n"		\
+		"6:	move.b $acr,[%0+]\n",		\
+		"7:	addq 1,%2\n",			\
+		"	.dword 6b,7b\n")
+
+#define __asm_copy_to_user_10x_cont(to, from, ret, COPY, FIXUP, TENTRY) \
+	__asm_copy_to_user_8x_cont(to, from, ret,	\
+			COPY				\
+		"	move.w [%1+],$acr\n"		\
+		"6:	move.w $acr,[%0+]\n",		\
+			FIXUP				\
+		"7:	addq 2,%2\n",			\
+			TENTRY				\
+		"	.dword 6b,7b\n")
+
+#define __asm_copy_to_user_10(to, from, ret) \
+	__asm_copy_to_user_10x_cont(to, from, ret, "", "", "")
+
+#define __asm_copy_to_user_11(to, from, ret) \
+	__asm_copy_to_user_10x_cont(to, from, ret,	\
+		"	move.b [%1+],$acr\n"		\
+		"8:	move.b $acr,[%0+]\n",		\
+		"9:	addq 1,%2\n",			\
+		"	.dword 8b,9b\n")
+
+#define __asm_copy_to_user_12x_cont(to, from, ret, COPY, FIXUP, TENTRY) \
+	__asm_copy_to_user_8x_cont(to, from, ret,	\
+			COPY				\
+		"	move.d [%1+],$acr\n"		\
+		"6:	move.d $acr,[%0+]\n",		\
+			FIXUP				\
+		"7:	addq 4,%2\n",			\
+			TENTRY				\
+		"	.dword 6b,7b\n")
+
+#define __asm_copy_to_user_12(to, from, ret) \
+	__asm_copy_to_user_12x_cont(to, from, ret, "", "", "")
+
+#define __asm_copy_to_user_13(to, from, ret) \
+	__asm_copy_to_user_12x_cont(to, from, ret,	\
+		"	move.b [%1+],$acr\n"		\
+		"8:	move.b $acr,[%0+]\n",		\
+		"9:	addq 1,%2\n",			\
+		"	.dword 8b,9b\n")
+
+#define __asm_copy_to_user_14x_cont(to, from, ret, COPY, FIXUP, TENTRY) \
+	__asm_copy_to_user_12x_cont(to, from, ret,	\
+			COPY				\
+		"	move.w [%1+],$acr\n"		\
+		"8:	move.w $acr,[%0+]\n",		\
+			FIXUP				\
+		"9:	addq 2,%2\n",			\
+			TENTRY				\
+		"	.dword 8b,9b\n")
+
+#define __asm_copy_to_user_14(to, from, ret)	\
+	__asm_copy_to_user_14x_cont(to, from, ret, "", "", "")
+
+#define __asm_copy_to_user_15(to, from, ret) \
+	__asm_copy_to_user_14x_cont(to, from, ret,	\
+		"	move.b [%1+],$acr\n"		\
+		"10:	move.b $acr,[%0+]\n",		\
+		"11:	addq 1,%2\n",			\
+		"	.dword 10b,11b\n")
+
+#define __asm_copy_to_user_16x_cont(to, from, ret, COPY, FIXUP, TENTRY) \
+	__asm_copy_to_user_12x_cont(to, from, ret,	\
+			COPY				\
+		"	move.d [%1+],$acr\n"		\
+		"8:	move.d $acr,[%0+]\n",		\
+			FIXUP				\
+		"9:	addq 4,%2\n",			\
+			TENTRY				\
+		"	.dword 8b,9b\n")
+
+#define __asm_copy_to_user_16(to, from, ret) \
+	__asm_copy_to_user_16x_cont(to, from, ret, "", "", "")
+
+#define __asm_copy_to_user_20x_cont(to, from, ret, COPY, FIXUP, TENTRY) \
+	__asm_copy_to_user_16x_cont(to, from, ret,	\
+			COPY				\
+		"	move.d [%1+],$acr\n"		\
+		"10:	move.d $acr,[%0+]\n",		\
+			FIXUP				\
+		"11:	addq 4,%2\n",			\
+			TENTRY				\
+		"	.dword 10b,11b\n")
+
+#define __asm_copy_to_user_20(to, from, ret) \
+	__asm_copy_to_user_20x_cont(to, from, ret, "", "", "")
+
+#define __asm_copy_to_user_24x_cont(to, from, ret, COPY, FIXUP, TENTRY)	\
+	__asm_copy_to_user_20x_cont(to, from, ret,	\
+			COPY				\
+		"	move.d [%1+],$acr\n"		\
+		"12:	move.d $acr,[%0+]\n",		\
+			FIXUP				\
+		"13:	addq 4,%2\n",			\
+			TENTRY				\
+		"	.dword 12b,13b\n")
+
+#define __asm_copy_to_user_24(to, from, ret)	\
+	__asm_copy_to_user_24x_cont(to, from, ret, "", "", "")
+
+/* Define a few clearing asms with exception handlers.  */
+
+/* This frame-asm is like the __asm_copy_user_cont one, but has one less
+   input.  */
+
+#define __asm_clear(to, ret, CLEAR, FIXUP, TENTRY) \
+	__asm__ __volatile__ (				\
+			CLEAR				\
+		"1:\n"					\
+		"	.section .fixup,\"ax\"\n"	\
+			FIXUP				\
+		"	.previous\n"			\
+		"	.section __ex_table,\"a\"\n"	\
+			TENTRY				\
+		"	.previous"			\
+		: "=b" (to), "=r" (ret)			\
+		: "0" (to), "1" (ret)			\
+		: "memory")
+
+#define __asm_clear_1(to, ret) \
+	__asm_clear(to, ret,			\
+		"2:	clear.b [%0+]\n",	\
+		"3:	jump 1b\n"		\
+		"	addq 1,%1\n",		\
+		"	.dword 2b,3b\n")
+
+#define __asm_clear_2(to, ret) \
+	__asm_clear(to, ret,			\
+		"2:	clear.w [%0+]\n",	\
+		"3:	jump 1b\n"		\
+		"	addq 2,%1\n",		\
+		"	.dword 2b,3b\n")
+
+#define __asm_clear_3(to, ret) \
+     __asm_clear(to, ret,			\
+		 "2:	clear.w [%0+]\n"	\
+		 "3:	clear.b [%0+]\n",	\
+		 "4:	addq 2,%1\n"		\
+		 "5:	jump 1b\n"		\
+		 "	addq 1,%1\n",		\
+		 "	.dword 2b,4b\n"		\
+		 "	.dword 3b,5b\n")
+
+#define __asm_clear_4x_cont(to, ret, CLEAR, FIXUP, TENTRY) \
+	__asm_clear(to, ret,				\
+			CLEAR				\
+		"2:	clear.d [%0+]\n",		\
+			FIXUP				\
+		"3:	jump 1b\n"			\
+		"	addq 4,%1\n",			\
+			TENTRY				\
+		"	.dword 2b,3b\n")
+
+#define __asm_clear_4(to, ret) \
+	__asm_clear_4x_cont(to, ret, "", "", "")
+
+#define __asm_clear_8x_cont(to, ret, CLEAR, FIXUP, TENTRY) \
+	__asm_clear_4x_cont(to, ret,			\
+			CLEAR				\
+		"4:	clear.d [%0+]\n",		\
+			FIXUP				\
+		"5:	addq 4,%1\n",			\
+			TENTRY				\
+		"	.dword 4b,5b\n")
+
+#define __asm_clear_8(to, ret) \
+	__asm_clear_8x_cont(to, ret, "", "", "")
+
+#define __asm_clear_12x_cont(to, ret, CLEAR, FIXUP, TENTRY) \
+	__asm_clear_8x_cont(to, ret,			\
+			CLEAR				\
+		"6:	clear.d [%0+]\n",		\
+			FIXUP				\
+		"7:	addq 4,%1\n",			\
+			TENTRY				\
+		"	.dword 6b,7b\n")
+
+#define __asm_clear_12(to, ret) \
+	__asm_clear_12x_cont(to, ret, "", "", "")
+
+#define __asm_clear_16x_cont(to, ret, CLEAR, FIXUP, TENTRY) \
+	__asm_clear_12x_cont(to, ret,			\
+			CLEAR				\
+		"8:	clear.d [%0+]\n",		\
+			FIXUP				\
+		"9:	addq 4,%1\n",			\
+			TENTRY				\
+		"	.dword 8b,9b\n")
+
+#define __asm_clear_16(to, ret) \
+	__asm_clear_16x_cont(to, ret, "", "", "")
+
+#define __asm_clear_20x_cont(to, ret, CLEAR, FIXUP, TENTRY) \
+	__asm_clear_16x_cont(to, ret,			\
+			CLEAR				\
+		"10:	clear.d [%0+]\n",		\
+			FIXUP				\
+		"11:	addq 4,%1\n",			\
+			TENTRY				\
+		"	.dword 10b,11b\n")
+
+#define __asm_clear_20(to, ret) \
+	__asm_clear_20x_cont(to, ret, "", "", "")
+
+#define __asm_clear_24x_cont(to, ret, CLEAR, FIXUP, TENTRY) \
+	__asm_clear_20x_cont(to, ret,			\
+			CLEAR				\
+		"12:	clear.d [%0+]\n",		\
+			FIXUP				\
+		"13:	addq 4,%1\n",			\
+			TENTRY				\
+		"	.dword 12b,13b\n")
+
+#define __asm_clear_24(to, ret) \
+	__asm_clear_24x_cont(to, ret, "", "", "")
+
+/*
+ * Return the size of a string (including the ending 0)
+ *
+ * Return length of string in userspace including terminating 0
+ * or 0 for error.  Return a value greater than N if too long.
+ */
+
+extern inline long
+strnlen_user(const char *s, long n)
+{
+	long res, tmp1;
+
+	if (!access_ok(VERIFY_READ, s, 0))
+		return 0;
+
+	/*
+	 * This code is deduced from:
+	 *
+	 *	tmp1 = n;
+	 *	while (tmp1-- > 0 && *s++)
+	 *	  ;
+	 *
+	 *	res = n - tmp1;
+	 *
+	 *  (with tweaks).
+	 */
+
+	__asm__ __volatile__ (
+		"	move.d %1,$acr\n"
+		"	cmpq 0,$acr\n"
+		"0:\n"
+		"	ble 1f\n"
+		"	subq 1,$acr\n"
+
+		"4:	test.b [%0+]\n"
+		"	bne 0b\n"
+		"	cmpq 0,$acr\n"
+		"1:\n"
+		"	move.d %1,%0\n"
+		"	sub.d $acr,%0\n"
+		"2:\n"
+		"	.section .fixup,\"ax\"\n"
+
+		"3:	jump 2b\n"
+		"	clear.d %0\n"
+
+		"	.previous\n"
+		"	.section __ex_table,\"a\"\n"
+		"	.dword 4b,3b\n"
+		"	.previous\n"
+		: "=r" (res), "=r" (tmp1)
+		: "0" (s), "1" (n)
+		: "acr");
+
+	return res;
+}
+
+#endif
diff --git a/include/asm-cris/arch-v32/unistd.h b/include/asm-cris/arch-v32/unistd.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/unistd.h
@@ -0,0 +1,148 @@
+#ifndef _ASM_CRIS_ARCH_UNISTD_H_
+#define _ASM_CRIS_ARCH_UNISTD_H_
+
+/* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */
+/*
+ * Don't remove the .ifnc tests; they are an insurance against
+ * any hard-to-spot gcc register allocation bugs.
+ */
+#define _syscall0(type,name) \
+type name(void) \
+{ \
+  register long __a __asm__ ("r10"); \
+  register long __n_ __asm__ ("r9") = (__NR_##name); \
+  __asm__ __volatile__ (".ifnc %0%1,$r10$r9\n\t" \
+			".err\n\t" \
+			".endif\n\t" \
+			"break 13" \
+			: "=r" (__a) \
+			: "r" (__n_)); \
+  if (__a >= 0) \
+     return (type) __a; \
+  errno = -__a; \
+  return (type) -1; \
+}
+
+#define _syscall1(type,name,type1,arg1) \
+type name(type1 arg1) \
+{ \
+  register long __a __asm__ ("r10") = (long) arg1; \
+  register long __n_ __asm__ ("r9") = (__NR_##name); \
+  __asm__ __volatile__ (".ifnc %0%1,$r10$r9\n\t" \
+			".err\n\t" \
+			".endif\n\t" \
+			"break 13" \
+			: "=r" (__a) \
+			: "r" (__n_), "0" (__a)); \
+  if (__a >= 0) \
+     return (type) __a; \
+  errno = -__a; \
+  return (type) -1; \
+}
+
+#define _syscall2(type,name,type1,arg1,type2,arg2) \
+type name(type1 arg1,type2 arg2) \
+{ \
+  register long __a __asm__ ("r10") = (long) arg1; \
+  register long __b __asm__ ("r11") = (long) arg2; \
+  register long __n_ __asm__ ("r9") = (__NR_##name); \
+  __asm__ __volatile__ (".ifnc %0%1%3,$r10$r9$r11\n\t" \
+			".err\n\t" \
+			".endif\n\t" \
+			"break 13" \
+			: "=r" (__a) \
+			: "r" (__n_), "0" (__a), "r" (__b)); \
+  if (__a >= 0) \
+     return (type) __a; \
+  errno = -__a; \
+  return (type) -1; \
+}
+
+#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
+type name(type1 arg1,type2 arg2,type3 arg3) \
+{ \
+  register long __a __asm__ ("r10") = (long) arg1; \
+  register long __b __asm__ ("r11") = (long) arg2; \
+  register long __c __asm__ ("r12") = (long) arg3; \
+  register long __n_ __asm__ ("r9") = (__NR_##name); \
+  __asm__ __volatile__ (".ifnc %0%1%3%4,$r10$r9$r11$r12\n\t" \
+			".err\n\t" \
+			".endif\n\t" \
+			"break 13" \
+			: "=r" (__a) \
+			: "r" (__n_), "0" (__a), "r" (__b), "r" (__c)); \
+  if (__a >= 0) \
+     return (type) __a; \
+  errno = -__a; \
+  return (type) -1; \
+}
+
+#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
+type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \
+{ \
+  register long __a __asm__ ("r10") = (long) arg1; \
+  register long __b __asm__ ("r11") = (long) arg2; \
+  register long __c __asm__ ("r12") = (long) arg3; \
+  register long __d __asm__ ("r13") = (long) arg4; \
+  register long __n_ __asm__ ("r9") = (__NR_##name); \
+  __asm__ __volatile__ (".ifnc %0%1%3%4%5,$r10$r9$r11$r12$r13\n\t" \
+			".err\n\t" \
+			".endif\n\t" \
+			"break 13" \
+			: "=r" (__a) \
+			: "r" (__n_), "0" (__a), "r" (__b), \
+			  "r" (__c), "r" (__d)); \
+  if (__a >= 0) \
+     return (type) __a; \
+  errno = -__a; \
+  return (type) -1; \
+}
+
+#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
+	  type5,arg5) \
+type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \
+{ \
+  register long __a __asm__ ("r10") = (long) arg1; \
+  register long __b __asm__ ("r11") = (long) arg2; \
+  register long __c __asm__ ("r12") = (long) arg3; \
+  register long __d __asm__ ("r13") = (long) arg4; \
+  register long __e __asm__ ("mof") = (long) arg5; \
+  register long __n_ __asm__ ("r9") = (__NR_##name); \
+  __asm__ __volatile__ (".ifnc %0%1%3%4%5%6,$r10$r9$r11$r12$r13$mof\n\t" \
+			".err\n\t" \
+			".endif\n\t" \
+			"break 13" \
+			: "=r" (__a) \
+			: "r" (__n_), "0" (__a), "r" (__b), \
+			  "r" (__c), "r" (__d), "h" (__e)); \
+  if (__a >= 0) \
+     return (type) __a; \
+  errno = -__a; \
+  return (type) -1; \
+}
+
+#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
+	  type5,arg5,type6,arg6) \
+type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,type6 arg6) \
+{ \
+  register long __a __asm__ ("r10") = (long) arg1; \
+  register long __b __asm__ ("r11") = (long) arg2; \
+  register long __c __asm__ ("r12") = (long) arg3; \
+  register long __d __asm__ ("r13") = (long) arg4; \
+  register long __e __asm__ ("mof") = (long) arg5; \
+  register long __f __asm__ ("srp") = (long) arg6; \
+  register long __n_ __asm__ ("r9") = (__NR_##name); \
+  __asm__ __volatile__ (".ifnc %0%1%3%4%5%6%7,$r10$r9$r11$r12$r13$mof$srp\n\t" \
+			".err\n\t" \
+			".endif\n\t" \
+			"break 13" \
+			: "=r" (__a) \
+			: "r" (__n_), "0" (__a), "r" (__b), \
+			  "r" (__c), "r" (__d), "h" (__e), "x" (__f)); \
+  if (__a >= 0) \
+     return (type) __a; \
+  errno = -__a; \
+  return (type) -1; \
+}
+
+#endif
diff --git a/include/asm-cris/arch-v32/user.h b/include/asm-cris/arch-v32/user.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/arch-v32/user.h
@@ -0,0 +1,41 @@
+#ifndef _ASM_CRIS_ARCH_USER_H
+#define _ASM_CRIS_ARCH_USER_H
+
+/* User-mode register used for core dumps. */
+
+struct user_regs_struct {
+	unsigned long r0;	/* General registers. */
+	unsigned long r1;
+	unsigned long r2;
+	unsigned long r3;
+	unsigned long r4;
+	unsigned long r5;
+	unsigned long r6;
+	unsigned long r7;
+	unsigned long r8;
+	unsigned long r9;
+	unsigned long r10;
+	unsigned long r11;
+	unsigned long r12;
+	unsigned long r13;
+	unsigned long sp;	/* R14, Stack pointer. */
+	unsigned long acr;	/* R15, Address calculation register. */
+	unsigned long bz;	/* P0, Constant zero (8-bits). */
+	unsigned long vr;	/* P1, Version register (8-bits). */
+	unsigned long pid;	/* P2, Process ID (8-bits). */
+	unsigned long srs;	/* P3, Support register select (8-bits). */
+	unsigned long wz;	/* P4, Constant zero (16-bits). */
+	unsigned long exs;	/* P5, Exception status. */
+	unsigned long eda;	/* P6, Exception data address. */
+	unsigned long mof;	/* P7, Multiply overflow regiter. */
+	unsigned long dz;	/* P8, Constant zero (32-bits). */
+	unsigned long ebp;	/* P9, Exception base pointer. */
+	unsigned long erp;	/* P10, Exception return pointer. */
+	unsigned long srp;	/* P11, Subroutine return pointer. */
+	unsigned long nrp;	/* P12, NMI return pointer. */
+	unsigned long ccs;	/* P13, Condition code stack. */
+	unsigned long usp;	/* P14, User mode stack pointer. */
+	unsigned long spc;	/* P15, Single step PC. */
+};
+
+#endif /* _ASM_CRIS_ARCH_USER_H */
diff --git a/include/asm-cris/atomic.h b/include/asm-cris/atomic.h
--- a/include/asm-cris/atomic.h
+++ b/include/asm-cris/atomic.h
@@ -4,21 +4,14 @@
 #define __ASM_CRIS_ATOMIC__
 
 #include <asm/system.h>
+#include <asm/arch/atomic.h>
 
 /*
  * Atomic operations that C can't guarantee us.  Useful for
  * resource counting etc..
  */
 
-/*
- * Make sure gcc doesn't try to be clever and move things around
- * on us. We need to use _exactly_ the address the user gave us,
- * not some alias that contains the same information.
- */
-
-#define __atomic_fool_gcc(x) (*(struct { int a[100]; } *)x)
-
-typedef struct { int counter; } atomic_t;
+typedef struct { volatile int counter; } atomic_t;
 
 #define ATOMIC_INIT(i)  { (i) }
 
@@ -30,29 +23,26 @@ typedef struct { int counter; } atomic_t
 extern __inline__ void atomic_add(int i, volatile atomic_t *v)
 {
 	unsigned long flags;
-	local_save_flags(flags);
-	local_irq_disable();
+	cris_atomic_save(v, flags);
 	v->counter += i;
-	local_irq_restore(flags);
+	cris_atomic_restore(v, flags);
 }
 
 extern __inline__ void atomic_sub(int i, volatile atomic_t *v)
 {
 	unsigned long flags;
-	local_save_flags(flags);
-	local_irq_disable();
+	cris_atomic_save(v, flags);
 	v->counter -= i;
-	local_irq_restore(flags);
+	cris_atomic_restore(v, flags);
 }
 
 extern __inline__ int atomic_add_return(int i, volatile atomic_t *v)
 {
 	unsigned long flags;
 	int retval;
-	local_save_flags(flags);
-	local_irq_disable();
+	cris_atomic_save(v, flags);
 	retval = (v->counter += i);
-	local_irq_restore(flags);
+	cris_atomic_restore(v, flags);
 	return retval;
 }
 
@@ -62,10 +52,9 @@ extern __inline__ int atomic_sub_return(
 {
 	unsigned long flags;
 	int retval;
-	local_save_flags(flags);
-	local_irq_disable();
+	cris_atomic_save(v, flags);
 	retval = (v->counter -= i);
-	local_irq_restore(flags);
+	cris_atomic_restore(v, flags);
 	return retval;
 }
 
@@ -73,39 +62,35 @@ extern __inline__ int atomic_sub_and_tes
 {
 	int retval;
 	unsigned long flags;
-	local_save_flags(flags);
-	local_irq_disable();
+	cris_atomic_save(v, flags);
 	retval = (v->counter -= i) == 0;
-	local_irq_restore(flags);
+	cris_atomic_restore(v, flags);
 	return retval;
 }
 
 extern __inline__ void atomic_inc(volatile atomic_t *v)
 {
 	unsigned long flags;
-	local_save_flags(flags);
-	local_irq_disable();
+	cris_atomic_save(v, flags);
 	(v->counter)++;
-	local_irq_restore(flags);
+	cris_atomic_restore(v, flags);
 }
 
 extern __inline__ void atomic_dec(volatile atomic_t *v)
 {
 	unsigned long flags;
-	local_save_flags(flags);
-	local_irq_disable();
+	cris_atomic_save(v, flags);
 	(v->counter)--;
-	local_irq_restore(flags);
+	cris_atomic_restore(v, flags);
 }
 
 extern __inline__ int atomic_inc_return(volatile atomic_t *v)
 {
 	unsigned long flags;
 	int retval;
-	local_save_flags(flags);
-	local_irq_disable();
+	cris_atomic_save(v, flags);
 	retval = (v->counter)++;
-	local_irq_restore(flags);
+	cris_atomic_restore(v, flags);
 	return retval;
 }
 
@@ -113,20 +98,18 @@ extern __inline__ int atomic_dec_return(
 {
 	unsigned long flags;
 	int retval;
-	local_save_flags(flags);
-	local_irq_disable();
+	cris_atomic_save(v, flags);
 	retval = (v->counter)--;
-	local_irq_restore(flags);
+	cris_atomic_restore(v, flags);
 	return retval;
 }
 extern __inline__ int atomic_dec_and_test(volatile atomic_t *v)
 {
 	int retval;
 	unsigned long flags;
-	local_save_flags(flags);
-	local_irq_disable();
+	cris_atomic_save(v, flags);
 	retval = --(v->counter) == 0;
-	local_irq_restore(flags);
+	cris_atomic_restore(v, flags);
 	return retval;
 }
 
@@ -134,10 +117,9 @@ extern __inline__ int atomic_inc_and_tes
 {
 	int retval;
 	unsigned long flags;
-	local_save_flags(flags);
-	local_irq_disable();
+	cris_atomic_save(v, flags);
 	retval = ++(v->counter) == 0;
-	local_irq_restore(flags);
+	cris_atomic_restore(v, flags);
 	return retval;
 }
 
diff --git a/include/asm-cris/axisflashmap.h b/include/asm-cris/axisflashmap.h
--- a/include/asm-cris/axisflashmap.h
+++ b/include/asm-cris/axisflashmap.h
@@ -40,4 +40,7 @@ struct partitiontable_entry {
 #define PARTITION_TYPE_KERNEL 0x0002
 #define PARTITION_TYPE_JFFS   0x0003
 
+/* The master mtd for the entire flash. */
+extern struct mtd_info* axisflash_mtd;
+
 #endif
diff --git a/include/asm-cris/bitops.h b/include/asm-cris/bitops.h
--- a/include/asm-cris/bitops.h
+++ b/include/asm-cris/bitops.h
@@ -16,6 +16,7 @@
 
 #include <asm/arch/bitops.h>
 #include <asm/system.h>
+#include <asm/atomic.h>
 #include <linux/compiler.h>
 
 /*
@@ -88,7 +89,7 @@ struct __dummy { unsigned long a[100]; }
  * It also implies a memory barrier.
  */
 
-extern inline int test_and_set_bit(int nr, void *addr)
+extern inline int test_and_set_bit(int nr, volatile unsigned long *addr)
 {
 	unsigned int mask, retval;
 	unsigned long flags;
@@ -96,15 +97,15 @@ extern inline int test_and_set_bit(int n
 	
 	adr += nr >> 5;
 	mask = 1 << (nr & 0x1f);
-	local_save_flags(flags);
-	local_irq_disable();
+	cris_atomic_save(addr, flags);
 	retval = (mask & *adr) != 0;
 	*adr |= mask;
+	cris_atomic_restore(addr, flags);
 	local_irq_restore(flags);
 	return retval;
 }
 
-extern inline int __test_and_set_bit(int nr, void *addr)
+extern inline int __test_and_set_bit(int nr, volatile unsigned long *addr)
 {
 	unsigned int mask, retval;
 	unsigned int *adr = (unsigned int *)addr;
@@ -131,7 +132,7 @@ extern inline int __test_and_set_bit(int
  * It also implies a memory barrier.
  */
 
-extern inline int test_and_clear_bit(int nr, void *addr)
+extern inline int test_and_clear_bit(int nr, volatile unsigned long *addr)
 {
 	unsigned int mask, retval;
 	unsigned long flags;
@@ -139,11 +140,10 @@ extern inline int test_and_clear_bit(int
 	
 	adr += nr >> 5;
 	mask = 1 << (nr & 0x1f);
-	local_save_flags(flags);
-	local_irq_disable();
+	cris_atomic_save(addr, flags);
 	retval = (mask & *adr) != 0;
 	*adr &= ~mask;
-	local_irq_restore(flags);
+	cris_atomic_restore(addr, flags);
 	return retval;
 }
 
@@ -157,7 +157,7 @@ extern inline int test_and_clear_bit(int
  * but actually fail.  You must protect multiple accesses with a lock.
  */
 
-extern inline int __test_and_clear_bit(int nr, void *addr)
+extern inline int __test_and_clear_bit(int nr, volatile unsigned long *addr)
 {
 	unsigned int mask, retval;
 	unsigned int *adr = (unsigned int *)addr;
@@ -177,24 +177,23 @@ extern inline int __test_and_clear_bit(i
  * It also implies a memory barrier.
  */
 
-extern inline int test_and_change_bit(int nr, void *addr)
+extern inline int test_and_change_bit(int nr, volatile unsigned long *addr)
 {
 	unsigned int mask, retval;
 	unsigned long flags;
 	unsigned int *adr = (unsigned int *)addr;
 	adr += nr >> 5;
 	mask = 1 << (nr & 0x1f);
-	local_save_flags(flags);
-	local_irq_disable();
+	cris_atomic_save(addr, flags);
 	retval = (mask & *adr) != 0;
 	*adr ^= mask;
-	local_irq_restore(flags);
+	cris_atomic_restore(addr, flags);
 	return retval;
 }
 
 /* WARNING: non atomic and it can be reordered! */
 
-extern inline int __test_and_change_bit(int nr, void *addr)
+extern inline int __test_and_change_bit(int nr, volatile unsigned long *addr)
 {
 	unsigned int mask, retval;
 	unsigned int *adr = (unsigned int *)addr;
@@ -215,7 +214,7 @@ extern inline int __test_and_change_bit(
  * This routine doesn't need to be atomic.
  */
 
-extern inline int test_bit(int nr, const void *addr)
+extern inline int test_bit(int nr, const volatile unsigned long *addr)
 {
 	unsigned int mask;
 	unsigned int *adr = (unsigned int *)addr;
@@ -259,7 +258,7 @@ extern inline int test_bit(int nr, const
  * @offset: The bitnumber to start searching at
  * @size: The maximum size to search
  */
-extern inline int find_next_zero_bit (void * addr, int size, int offset)
+extern inline int find_next_zero_bit (const unsigned long * addr, int size, int offset)
 {
 	unsigned long *p = ((unsigned long *) addr) + (offset >> 5);
 	unsigned long result = offset & ~31UL;
@@ -301,7 +300,7 @@ extern inline int find_next_zero_bit (vo
  * @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)
+static __inline__ int find_next_bit(const unsigned long *addr, int size, int offset)
 {
 	unsigned long *p = ((unsigned long *) addr) + (offset >> 5);
         unsigned long result = offset & ~31UL;
@@ -367,7 +366,7 @@ found_middle:
 #define minix_test_bit(nr,addr) test_bit(nr,addr)
 #define minix_find_first_zero_bit(addr,size) find_first_zero_bit(addr,size)
 
-extern inline int sched_find_first_bit(unsigned long *b)
+extern inline int sched_find_first_bit(const unsigned long *b)
 {
 	if (unlikely(b[0]))
 		return __ffs(b[0]);
diff --git a/include/asm-cris/dma-mapping.h b/include/asm-cris/dma-mapping.h
--- a/include/asm-cris/dma-mapping.h
+++ b/include/asm-cris/dma-mapping.h
@@ -1,125 +1,179 @@
+/* DMA mapping. Nothing tricky here, just virt_to_phys */
+
 #ifndef _ASM_CRIS_DMA_MAPPING_H
 #define _ASM_CRIS_DMA_MAPPING_H
 
-#include "scatterlist.h"
+#include <linux/mm.h>
+#include <linux/kernel.h>
 
-static inline int
-dma_supported(struct device *dev, u64 mask)
-{
-	BUG();
-	return 0;
-}
+#include <asm/cache.h>
+#include <asm/io.h>
+#include <asm/scatterlist.h>
 
-static inline int
-dma_set_mask(struct device *dev, u64 dma_mask)
-{
-	BUG();
-	return 1;
-}
+#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
+#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
 
+#ifdef CONFIG_PCI
+void *dma_alloc_coherent(struct device *dev, size_t size,
+			   dma_addr_t *dma_handle, int flag);
+
+void dma_free_coherent(struct device *dev, size_t size,
+			 void *vaddr, dma_addr_t dma_handle);
+#else
 static inline void *
 dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
-		   int flag)
+                   int flag)
 {
-	BUG();
-	return NULL;
+        BUG();
+        return NULL;
 }
 
 static inline void
 dma_free_coherent(struct device *dev, size_t size, void *cpu_addr,
-		    dma_addr_t dma_handle)
+                    dma_addr_t dma_handle)
 {
-	BUG();
+        BUG();
 }
-
+#endif
 static inline dma_addr_t
-dma_map_single(struct device *dev, void *cpu_addr, size_t size,
+dma_map_single(struct device *dev, void *ptr, size_t size,
 	       enum dma_data_direction direction)
 {
-	BUG();
-	return 0;
+	BUG_ON(direction == DMA_NONE);
+	return virt_to_phys(ptr);
 }
 
 static inline void
 dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
 		 enum dma_data_direction direction)
 {
-	BUG();
+	BUG_ON(direction == DMA_NONE);
+}
+
+static inline int
+dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
+	   enum dma_data_direction direction)
+{
+	printk("Map sg\n");
+	return nents;
 }
 
 static inline dma_addr_t
-dma_map_page(struct device *dev, struct page *page,
-	     unsigned long offset, size_t size,
-	     enum dma_data_direction direction)
+dma_map_page(struct device *dev, struct page *page, unsigned long offset,
+	     size_t size, enum dma_data_direction direction)
 {
-	BUG();
-	return 0;
+	BUG_ON(direction == DMA_NONE);
+	return page_to_phys(page) + offset;
 }
 
 static inline void
 dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
 	       enum dma_data_direction direction)
 {
-	BUG();
+	BUG_ON(direction == DMA_NONE);
 }
 
-static inline int
-dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
-	   enum dma_data_direction direction)
-{
-	BUG();
-	return 1;
-}
 
 static inline void
 dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
 	     enum dma_data_direction direction)
 {
-	BUG();
+	BUG_ON(direction == DMA_NONE);
 }
 
 static inline void
-dma_sync_single(struct device *dev, dma_addr_t dma_handle, size_t size,
-		enum dma_data_direction direction)
+dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size,
+			enum dma_data_direction direction)
 {
-	BUG();
 }
 
 static inline void
-dma_sync_sg(struct device *dev, struct scatterlist *sg, int nelems,
-	    enum dma_data_direction direction)
+dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, size_t size,
+			enum dma_data_direction direction)
 {
-	BUG();
 }
 
-/* Now for the API extensions over the pci_ one */
+static inline void
+dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t dma_handle,
+			      unsigned long offset, size_t size,
+			      enum dma_data_direction direction)
+{
+}
 
-#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
-#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
-#define dma_is_consistent(d)	(1)
+static inline void
+dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_handle,
+				 unsigned long offset, size_t size,
+				 enum dma_data_direction direction)
+{
+}
 
-static inline int
-dma_get_cache_alignment(void)
+static inline void
+dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
+		    enum dma_data_direction direction)
 {
-	/* no easy way to get cache size on all processors, so return
-	 * the maximum possible, to be safe */
-	return (1 << L1_CACHE_SHIFT_MAX);
 }
 
 static inline void
-dma_sync_single_range(struct device *dev, dma_addr_t dma_handle,
-		      unsigned long offset, size_t size,
-		      enum dma_data_direction direction)
+dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems,
+		    enum dma_data_direction direction)
+{
+}
+
+static inline int
+dma_mapping_error(dma_addr_t dma_addr)
 {
-	BUG();
+	return 0;
+}
+
+static inline int
+dma_supported(struct device *dev, u64 mask)
+{
+        /*
+         * we fall back to GFP_DMA when the mask isn't all 1s,
+         * so we can't guarantee allocations that must be
+         * within a tighter range than GFP_DMA..
+         */
+        if(mask < 0x00ffffff)
+                return 0;
+
+	return 1;
 }
 
+static inline int
+dma_set_mask(struct device *dev, u64 mask)
+{
+	if(!dev->dma_mask || !dma_supported(dev, mask))
+		return -EIO;
+
+	*dev->dma_mask = mask;
+
+	return 0;
+}
+
+static inline int
+dma_get_cache_alignment(void)
+{
+	return (1 << L1_CACHE_SHIFT_MAX);
+}
+
+#define dma_is_consistent(d)	(1)
+
 static inline void
 dma_cache_sync(void *vaddr, size_t size,
 	       enum dma_data_direction direction)
 {
-	BUG();
 }
 
-#endif
+#define ARCH_HAS_DMA_DECLARE_COHERENT_MEMORY
+extern int
+dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr,
+			    dma_addr_t device_addr, size_t size, int flags);
+
+extern void
+dma_release_declared_memory(struct device *dev);
+
+extern void *
+dma_mark_declared_memory_occupied(struct device *dev,
+				  dma_addr_t device_addr, size_t size);
 
+#endif
diff --git a/include/asm-cris/dma.h b/include/asm-cris/dma.h
--- a/include/asm-cris/dma.h
+++ b/include/asm-cris/dma.h
@@ -10,4 +10,12 @@
 
 #define MAX_DMA_ADDRESS PAGE_OFFSET
 
+/* From PCI */
+
+#ifdef CONFIG_PCI
+extern int isa_dma_bridge_buggy;
+#else
+#define isa_dma_bridge_buggy 	(0)
+#endif
+
 #endif /* _ASM_DMA_H */
diff --git a/include/asm-cris/elf.h b/include/asm-cris/elf.h
--- a/include/asm-cris/elf.h
+++ b/include/asm-cris/elf.h
@@ -8,6 +8,27 @@
 #include <asm/arch/elf.h>
 #include <asm/user.h>
 
+#define R_CRIS_NONE             0
+#define R_CRIS_8                1
+#define R_CRIS_16               2
+#define R_CRIS_32               3
+#define R_CRIS_8_PCREL          4
+#define R_CRIS_16_PCREL         5
+#define R_CRIS_32_PCREL         6
+#define R_CRIS_GNU_VTINHERIT    7
+#define R_CRIS_GNU_VTENTRY      8
+#define R_CRIS_COPY             9
+#define R_CRIS_GLOB_DAT         10
+#define R_CRIS_JUMP_SLOT        11
+#define R_CRIS_RELATIVE         12
+#define R_CRIS_16_GOT           13
+#define R_CRIS_32_GOT           14
+#define R_CRIS_16_GOTPLT        15
+#define R_CRIS_32_GOTPLT        16
+#define R_CRIS_32_GOTREL        17
+#define R_CRIS_32_PLT_GOTREL    18
+#define R_CRIS_32_PLT_PCREL     19
+
 typedef unsigned long elf_greg_t;
 
 /* Note that NGREG is defined to ELF_NGREG in include/linux/elfcore.h, and is
@@ -19,17 +40,29 @@ typedef elf_greg_t elf_gregset_t[ELF_NGR
 typedef unsigned long elf_fpregset_t;
 
 /*
- * This is used to ensure we don't load something for the wrong architecture.
- */
-#define elf_check_arch(x) ( (x)->e_machine == EM_CRIS )
-
-/*
  * These are used to set parameters in the core dumps.
  */
 #define ELF_CLASS	ELFCLASS32
-#define ELF_DATA	ELFDATA2LSB;
+#define ELF_DATA	ELFDATA2LSB
 #define ELF_ARCH	EM_CRIS
 
+/* The master for these definitions is {binutils}/include/elf/cris.h:  */
+/* User symbols in this file have a leading underscore.  */
+#define EF_CRIS_UNDERSCORE		0x00000001
+
+/* This is a mask for different incompatible machine variants.  */
+#define EF_CRIS_VARIANT_MASK		0x0000000e
+
+/* Variant 0; may contain v0..10 object.  */
+#define EF_CRIS_VARIANT_ANY_V0_V10	0x00000000
+
+/* Variant 1; contains v32 object.  */
+#define EF_CRIS_VARIANT_V32		0x00000002
+
+/* Variant 2; contains object compatible with v32 and v10.  */
+#define EF_CRIS_VARIANT_COMMON_V10_V32	0x00000004
+/* End of excerpt from {binutils}/include/elf/cris.h.  */
+
 #define USE_ELF_CORE_DUMP
 
 #define ELF_EXEC_PAGESIZE	8192
diff --git a/include/asm-cris/emergency-restart.h b/include/asm-cris/emergency-restart.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/emergency-restart.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_EMERGENCY_RESTART_H
+#define _ASM_EMERGENCY_RESTART_H
+
+#include <asm-generic/emergency-restart.h>
+
+#endif /* _ASM_EMERGENCY_RESTART_H */
diff --git a/include/asm-cris/etraxgpio.h b/include/asm-cris/etraxgpio.h
--- a/include/asm-cris/etraxgpio.h
+++ b/include/asm-cris/etraxgpio.h
@@ -13,7 +13,7 @@
          are enabled.
  *
  *
- * For ETRAX 200 (ARCH_V32):
+ * For ETRAX FS (ARCH_V32):
  * /dev/gpioa  minor 0,  8 bit GPIO, each bit can change direction
  * /dev/gpiob  minor 1, 18 bit GPIO, each bit can change direction
  * /dev/gpioc  minor 2, 18 bit GPIO, each bit can change direction
@@ -39,10 +39,10 @@
 #define ETRAXGPIO_IOCTYPE 43
 #define GPIO_MINOR_A 0
 #define GPIO_MINOR_B 1
-#define GPIO_MINOR_C 2
-#define GPIO_MINOR_D 3
-#define GPIO_MINOR_E 4
-#define GPIO_MINOR_LEDS 5
+#define GPIO_MINOR_LEDS 2
+#define GPIO_MINOR_C 3
+#define GPIO_MINOR_D 4
+#define GPIO_MINOR_E 5
 #define GPIO_MINOR_LAST 5
 #endif
 
diff --git a/include/asm-cris/hardirq.h b/include/asm-cris/hardirq.h
--- a/include/asm-cris/hardirq.h
+++ b/include/asm-cris/hardirq.h
@@ -1,18 +1,17 @@
 #ifndef __ASM_HARDIRQ_H
 #define __ASM_HARDIRQ_H
 
-/* only non-SMP supported */
-
 #include <linux/threads.h>
 #include <linux/cache.h>
 
-/* entry.S is sensitive to the offsets of these fields */
 typedef struct {
 	unsigned int __softirq_pending;
 } ____cacheline_aligned irq_cpustat_t;
 
 #include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
 
+void ack_bad_irq(unsigned int irq);
+
 #define HARDIRQ_BITS	8
 
 /*
diff --git a/include/asm-cris/hw_irq.h b/include/asm-cris/hw_irq.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/hw_irq.h
@@ -0,0 +1,7 @@
+#ifndef _ASM_HW_IRQ_H
+#define _ASM_HW_IRQ_H
+
+static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) {}
+
+#endif
+
diff --git a/include/asm-cris/ide.h b/include/asm-cris/ide.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/ide.h
@@ -0,0 +1 @@
+#include <asm/arch/ide.h>
diff --git a/include/asm-cris/io.h b/include/asm-cris/io.h
--- a/include/asm-cris/io.h
+++ b/include/asm-cris/io.h
@@ -3,6 +3,21 @@
 
 #include <asm/page.h>   /* for __va, __pa */
 #include <asm/arch/io.h>
+#include <linux/kernel.h>
+
+struct cris_io_operations
+{
+	u32 (*read_mem)(void *addr, int size);
+	void (*write_mem)(u32 val, int size, void *addr);
+	u32 (*read_io)(u32 port, void *addr, int size, int count);
+	void (*write_io)(u32 port, void *addr, int size, int count);
+};
+
+#ifdef CONFIG_PCI
+extern struct cris_io_operations *cris_iops;
+#else
+#define cris_iops ((struct cris_io_operations*)NULL)
+#endif
 
 /*
  * Change virtual addresses to physical addresses and vv.
@@ -18,14 +33,17 @@ extern inline void * phys_to_virt(unsign
 	return __va(address);
 }
 
-extern void * __ioremap(unsigned long offset, unsigned long size, unsigned long flags);
+extern void __iomem * __ioremap(unsigned long offset, unsigned long size, unsigned long flags);
+extern void __iomem * __ioremap_prot(unsigned long phys_addr, unsigned long size, pgprot_t prot);
 
-extern inline void * ioremap (unsigned long offset, unsigned long size)
+extern inline void __iomem * ioremap (unsigned long offset, unsigned long size)
 {
 	return __ioremap(offset, size, 0);
 }
 
-extern void iounmap(void *addr);
+extern void iounmap(volatile void * __iomem addr);
+
+extern void __iomem * ioremap_nocache(unsigned long offset, unsigned long size);
 
 /*
  * IO bus memory addresses are also 1:1 with the physical address
@@ -39,9 +57,32 @@ extern void iounmap(void *addr);
  * differently. On the CRIS architecture, we just read/write the
  * memory location directly.
  */
-#define readb(addr) (*(volatile unsigned char *) (addr))
-#define readw(addr) (*(volatile unsigned short *) (addr))
-#define readl(addr) (*(volatile unsigned int *) (addr))
+#ifdef CONFIG_PCI
+#define PCI_SPACE(x) ((((unsigned)(x)) & 0x10000000) == 0x10000000)
+#else
+#define PCI_SPACE(x) 0
+#endif
+static inline unsigned char readb(const volatile void __iomem *addr)
+{
+	if (PCI_SPACE(addr) && cris_iops)
+		return cris_iops->read_mem((void*)addr, 1);
+	else
+		return *(volatile unsigned char __force *) addr;
+}
+static inline unsigned short readw(const volatile void __iomem *addr)
+{
+	if (PCI_SPACE(addr) && cris_iops)
+		return cris_iops->read_mem((void*)addr, 2);
+	else
+		return *(volatile unsigned short __force *) addr;
+}
+static inline unsigned int readl(const volatile void __iomem *addr)
+{
+	if (PCI_SPACE(addr) && cris_iops)
+		return cris_iops->read_mem((void*)addr, 4);
+	else
+		return *(volatile unsigned int __force *) addr;
+}
 #define readb_relaxed(addr) readb(addr)
 #define readw_relaxed(addr) readw(addr)
 #define readl_relaxed(addr) readl(addr)
@@ -49,9 +90,27 @@ extern void iounmap(void *addr);
 #define __raw_readw readw
 #define __raw_readl readl
 
-#define writeb(b,addr) ((*(volatile unsigned char *) (addr)) = (b))
-#define writew(b,addr) ((*(volatile unsigned short *) (addr)) = (b))
-#define writel(b,addr) ((*(volatile unsigned int *) (addr)) = (b))
+static inline void writeb(unsigned char b, volatile void __iomem *addr)
+{
+	if (PCI_SPACE(addr) && cris_iops)
+		cris_iops->write_mem(b, 1, (void*)addr);
+	else
+		*(volatile unsigned char __force *) addr = b;
+}
+static inline void writew(unsigned short b, volatile void __iomem *addr)
+{
+	if (PCI_SPACE(addr) && cris_iops)
+		cris_iops->write_mem(b, 2, (void*)addr);
+	else
+		*(volatile unsigned short __force *) addr = b;
+}
+static inline void writel(unsigned int b, volatile void __iomem *addr)
+{
+	if (PCI_SPACE(addr) && cris_iops)
+		cris_iops->write_mem(b, 4, (void*)addr);
+	else
+		*(volatile unsigned int __force *) addr = b;
+}
 #define __raw_writeb writeb
 #define __raw_writew writew
 #define __raw_writel writel
@@ -66,25 +125,25 @@ extern void iounmap(void *addr);
  * Again, CRIS does not require mem IO specific function.
  */
 
-#define eth_io_copy_and_sum(a,b,c,d)	eth_copy_and_sum((a),(void *)(b),(c),(d))
+#define eth_io_copy_and_sum(a,b,c,d)	eth_copy_and_sum((a),(void __force *)(b),(c),(d))
 
 /* The following is junk needed for the arch-independent code but which
  * we never use in the CRIS port
  */
 
 #define IO_SPACE_LIMIT 0xffff
-#define inb(x) (0)
-#define inw(x) (0)
-#define inl(x) (0)
-#define outb(x,y)
-#define outw(x,y)
-#define outl(x,y)
-#define insb(x,y,z)
-#define insw(x,y,z)
-#define insl(x,y,z)
-#define outsb(x,y,z)
-#define outsw(x,y,z)
-#define outsl(x,y,z)
+#define inb(port) (cris_iops ? cris_iops->read_io(port,NULL,1,1) : 0)
+#define inw(port) (cris_iops ? cris_iops->read_io(port,NULL,2,1) : 0)
+#define inl(port) (cris_iops ? cris_iops->read_io(port,NULL,4,1) : 0)
+#define insb(port,addr,count) (cris_iops ? cris_iops->read_io(port,addr,1,count) : 0)
+#define insw(port,addr,count) (cris_iops ? cris_iops->read_io(port,addr,2,count) : 0)
+#define insl(port,addr,count) (cris_iops ? cris_iops->read_io(port,addr,4,count) : 0)
+#define outb(data,port) if (cris_iops) cris_iops->write_io(port,(void*)(unsigned)data,1,1)
+#define outw(data,port) if (cris_iops) cris_iops->write_io(port,(void*)(unsigned)data,2,1)
+#define outl(data,port) if (cris_iops) cris_iops->write_io(port,(void*)(unsigned)data,4,1)
+#define outsb(port,addr,count) if(cris_iops) cris_iops->write_io(port,(void*)addr,1,count)
+#define outsw(port,addr,count) if(cris_iops) cris_iops->write_io(port,(void*)addr,2,count)
+#define outsl(port,addr,count) if(cris_iops) cris_iops->write_io(port,(void*)addr,3,count)
 
 /*
  * Convert a physical pointer to a virtual kernel pointer for /dev/mem
diff --git a/include/asm-cris/irq.h b/include/asm-cris/irq.h
--- a/include/asm-cris/irq.h
+++ b/include/asm-cris/irq.h
@@ -8,16 +8,6 @@ extern __inline__ int irq_canonicalize(i
   return irq; 
 }
 
-extern void disable_irq(unsigned int);
-extern void enable_irq(unsigned int);
-
-#define disable_irq_nosync      disable_irq
-#define enable_irq_nosync       enable_irq
-
-struct irqaction;
-struct pt_regs;
-int handle_IRQ_event(unsigned int, struct pt_regs *, struct irqaction *);
-
 #endif  /* _ASM_IRQ_H */
 
 
diff --git a/include/asm-cris/kmap_types.h b/include/asm-cris/kmap_types.h
--- a/include/asm-cris/kmap_types.h
+++ b/include/asm-cris/kmap_types.h
@@ -17,8 +17,8 @@ enum km_type {
 	KM_PTE1,
 	KM_IRQ0,
 	KM_IRQ1,
-	KM_CRYPTO_USER,
-	KM_CRYPTO_SOFTIRQ,
+	KM_SOFTIRQ0,
+	KM_SOFTIRQ1,
 	KM_TYPE_NR
 };
 
diff --git a/include/asm-cris/mmu_context.h b/include/asm-cris/mmu_context.h
--- a/include/asm-cris/mmu_context.h
+++ b/include/asm-cris/mmu_context.h
@@ -15,7 +15,7 @@ extern void switch_mm(struct mm_struct *
  * registers like cr3 on the i386
  */
 
-extern volatile pgd_t *current_pgd;   /* defined in arch/cris/mm/fault.c */
+extern volatile DEFINE_PER_CPU(pgd_t *,current_pgd); /* defined in arch/cris/mm/fault.c */
 
 static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
 {
diff --git a/include/asm-cris/page.h b/include/asm-cris/page.h
--- a/include/asm-cris/page.h
+++ b/include/asm-cris/page.h
@@ -29,18 +29,15 @@
  */
 #ifndef __ASSEMBLY__
 typedef struct { unsigned long pte; } pte_t;
-typedef struct { unsigned long pmd; } pmd_t;
 typedef struct { unsigned long pgd; } pgd_t;
 typedef struct { unsigned long pgprot; } pgprot_t;
 #endif
 
 #define pte_val(x)	((x).pte)
-#define pmd_val(x)	((x).pmd)
 #define pgd_val(x)	((x).pgd)
 #define pgprot_val(x)	((x).pgprot)
 
 #define __pte(x)	((pte_t) { (x) } )
-#define __pmd(x)	((pmd_t) { (x) } )
 #define __pgd(x)	((pgd_t) { (x) } )
 #define __pgprot(x)	((pgprot_t) { (x) } )
 
@@ -73,10 +70,6 @@ typedef struct { unsigned long pgprot; }
 
 #ifndef __ASSEMBLY__
 
-#define BUG() do { \
-  printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
-} while (0)
-
 /* Pure 2^n version of get_order */
 static inline int get_order(unsigned long size)
 {
diff --git a/include/asm-cris/pci.h b/include/asm-cris/pci.h
--- a/include/asm-cris/pci.h
+++ b/include/asm-cris/pci.h
@@ -1,13 +1,105 @@
 #ifndef __ASM_CRIS_PCI_H
 #define __ASM_CRIS_PCI_H
 
+#include <linux/config.h>
+
+#ifdef __KERNEL__
+#include <linux/mm.h>		/* for struct page */
+
+/* Can be used to override the logic in pci_scan_bus for skipping
+   already-configured bus numbers - to be used for buggy BIOSes
+   or architectures with incomplete PCI setup by the loader */
+
+#define pcibios_assign_all_busses(void) 1
+
+extern unsigned long pci_mem_start;
+#define PCIBIOS_MIN_IO		0x1000
+#define PCIBIOS_MIN_MEM		0x10000000
+
+#define PCIBIOS_MIN_CARDBUS_IO	0x4000
+
+void pcibios_config_init(void);
+struct pci_bus * pcibios_scan_root(int bus);
+int pcibios_assign_resources(void);
+
+void pcibios_set_master(struct pci_dev *dev);
+void pcibios_penalize_isa_irq(int irq);
+struct irq_routing_table *pcibios_get_irq_routing_table(void);
+int pcibios_set_irq_routing(struct pci_dev *dev, int pin, int irq);
+
+/* Dynamic DMA mapping stuff.
+ * i386 has everything mapped statically.
+ */
+
+#include <linux/types.h>
+#include <linux/slab.h>
 #include <asm/scatterlist.h>
-#include <asm-generic/pci-dma-compat.h>
+#include <linux/string.h>
+#include <asm/io.h>
 
-/* ETRAX chips don't have a PCI bus. This file is just here because some stupid .c code
- * includes it even if CONFIG_PCI is not set.
+struct pci_dev;
+
+/* The PCI address space does equal the physical memory
+ * address space.  The networking and block device layers use
+ * this boolean for bounce buffer decisions.
  */
-#define PCI_DMA_BUS_IS_PHYS       (1)
+#define PCI_DMA_BUS_IS_PHYS	(1)
 
-#endif /* __ASM_CRIS_PCI_H */
+/* pci_unmap_{page,single} is a nop so... */
+#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)
+#define DECLARE_PCI_UNMAP_LEN(LEN_NAME)
+#define pci_unmap_addr(PTR, ADDR_NAME)		(0)
+#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL)	do { } while (0)
+#define pci_unmap_len(PTR, LEN_NAME)		(0)
+#define pci_unmap_len_set(PTR, LEN_NAME, VAL)	do { } while (0)
+
+/* This is always fine. */
+#define pci_dac_dma_supported(pci_dev, mask)	(1)
 
+static inline dma64_addr_t
+pci_dac_page_to_dma(struct pci_dev *pdev, struct page *page, unsigned long offset, int direction)
+{
+	return ((dma64_addr_t) page_to_phys(page) +
+		(dma64_addr_t) offset);
+}
+
+static inline struct page *
+pci_dac_dma_to_page(struct pci_dev *pdev, dma64_addr_t dma_addr)
+{
+	return pfn_to_page(dma_addr >> PAGE_SHIFT);
+}
+
+static inline unsigned long
+pci_dac_dma_to_offset(struct pci_dev *pdev, dma64_addr_t dma_addr)
+{
+	return (dma_addr & ~PAGE_MASK);
+}
+
+static inline void
+pci_dac_dma_sync_single_for_cpu(struct pci_dev *pdev, dma64_addr_t dma_addr, size_t len, int direction)
+{
+}
+
+static inline void
+pci_dac_dma_sync_single_for_device(struct pci_dev *pdev, dma64_addr_t dma_addr, size_t len, int direction)
+{
+}
+
+#define HAVE_PCI_MMAP
+extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
+			       enum pci_mmap_state mmap_state, int write_combine);
+
+
+static inline void pcibios_add_platform_entries(struct pci_dev *dev)
+{
+}
+
+#endif /* __KERNEL__ */
+
+/* implement the pci_ DMA API in terms of the generic device dma_ one */
+#include <asm-generic/pci-dma-compat.h>
+
+/* generic pci stuff */
+#include <asm-generic/pci.h>
+
+#endif /* __ASM_CRIS_PCI_H */
diff --git a/include/asm-cris/pgalloc.h b/include/asm-cris/pgalloc.h
--- a/include/asm-cris/pgalloc.h
+++ b/include/asm-cris/pgalloc.h
@@ -47,16 +47,6 @@ extern inline void pte_free(struct page 
 
 #define __pte_free_tlb(tlb,pte) tlb_remove_page((tlb),(pte))
 
-/*
- * We don't have any real pmd's, and this code never triggers because
- * the pgd will always be present..
- */
-
-#define pmd_alloc_one(mm, addr)    ({ BUG(); ((pmd_t *)2); })
-#define pmd_free(x)                do { } while (0)
-#define __pmd_free_tlb(tlb,x)      do { } while (0)
-#define pgd_populate(mm, pmd, pte) BUG()
-
 #define check_pgt_cache()          do { } while (0)
 
 #endif
diff --git a/include/asm-cris/pgtable.h b/include/asm-cris/pgtable.h
--- a/include/asm-cris/pgtable.h
+++ b/include/asm-cris/pgtable.h
@@ -5,7 +5,8 @@
 #ifndef _CRIS_PGTABLE_H
 #define _CRIS_PGTABLE_H
 
-#include <asm-generic/4level-fixup.h>
+#include <asm/page.h>
+#include <asm-generic/pgtable-nopmd.h>
 
 #ifndef __ASSEMBLY__
 #include <linux/config.h>
@@ -41,22 +42,14 @@ extern void paging_init(void);
  * but the define is needed for a generic inline function.)
  */
 #define set_pmd(pmdptr, pmdval) (*(pmdptr) = pmdval)
-#define set_pgd(pgdptr, pgdval) (*(pgdptr) = pgdval)
+#define set_pgu(pudptr, pudval) (*(pudptr) = pudval)
 
-/* PMD_SHIFT determines the size of the area a second-level page table can
+/* PGDIR_SHIFT determines the size of the area a second-level page table can
  * map. It is equal to the page size times the number of PTE's that fit in
  * a PMD page. A PTE is 4-bytes in CRIS. Hence the following number.
  */
 
-#define PMD_SHIFT	(PAGE_SHIFT + (PAGE_SHIFT-2))
-#define PMD_SIZE	(1UL << PMD_SHIFT)
-#define PMD_MASK	(~(PMD_SIZE-1))
-
-/* PGDIR_SHIFT determines what a third-level page table entry can map.
- * Since we fold into a two-level structure, this is the same as PMD_SHIFT.
- */
-
-#define PGDIR_SHIFT	PMD_SHIFT
+#define PGDIR_SHIFT	(PAGE_SHIFT + (PAGE_SHIFT-2))
 #define PGDIR_SIZE	(1UL << PGDIR_SHIFT)
 #define PGDIR_MASK	(~(PGDIR_SIZE-1))
 
@@ -67,7 +60,6 @@ extern void paging_init(void);
  * divide it by 4 (shift by 2).
  */
 #define PTRS_PER_PTE	(1UL << (PAGE_SHIFT-2))
-#define PTRS_PER_PMD	1
 #define PTRS_PER_PGD	(1UL << (PAGE_SHIFT-2))
 
 /* calculate how many PGD entries a user-level program can use
@@ -105,7 +97,7 @@ extern unsigned long empty_zero_page;
 #define pte_present(x)	(pte_val(x) & _PAGE_PRESENT)
 #define pte_clear(mm,addr,xp)	do { pte_val(*(xp)) = 0; } while (0)
 
-#define pmd_none(x)	(!pmd_val(x))
+#define pmd_none(x)     (!pmd_val(x))
 /* by removing the _PAGE_KERNEL bit from the comparision, the same pmd_bad
  * works for both _PAGE_TABLE and _KERNPG_TABLE pmd entries.
  */
@@ -116,16 +108,6 @@ extern unsigned long empty_zero_page;
 #ifndef __ASSEMBLY__
 
 /*
- * The "pgd_xxx()" functions here are trivial for a folded two-level
- * setup: the pgd is never bad, and a pmd always exists (as it's folded
- * into the pgd entry)
- */
-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)	{ }
-
-/*
  * The following only work if pte_present() is true.
  * Undefined behaviour if not..
  */
@@ -275,7 +257,7 @@ extern inline void pmd_set(pmd_t * pmdp,
 #define pmd_page_kernel(pmd)	((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
 
 /* to find an entry in a page-table-directory. */
-#define pgd_index(address) ((address >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
+#define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
 
 /* to find an entry in a page-table-directory */
 extern inline pgd_t * pgd_offset(struct mm_struct * mm, unsigned long address)
@@ -286,12 +268,6 @@ extern inline pgd_t * pgd_offset(struct 
 /* to find an entry in a kernel page-table-directory */
 #define pgd_offset_k(address) pgd_offset(&init_mm, address)
 
-/* Find an entry in the second-level page table.. */
-extern inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address)
-{
-	return (pmd_t *) dir;
-}
-
 /* Find an entry in the third-level page table.. */
 #define __pte_offset(address) \
 	(((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
@@ -308,8 +284,6 @@ extern inline pmd_t * pmd_offset(pgd_t *
 
 #define pte_ERROR(e) \
         printk("%s:%d: bad pte %p(%08lx).\n", __FILE__, __LINE__, &(e), pte_val(e))
-#define pmd_ERROR(e) \
-        printk("%s:%d: bad pmd %p(%08lx).\n", __FILE__, __LINE__, &(e), pmd_val(e))
 #define pgd_ERROR(e) \
         printk("%s:%d: bad pgd %p(%08lx).\n", __FILE__, __LINE__, &(e), pgd_val(e))
 
@@ -348,5 +322,7 @@ extern inline void update_mmu_cache(stru
 #define pte_to_pgoff(x)	(pte_val(x) >> 6)
 #define pgoff_to_pte(x)	__pte(((x) << 6) | _PAGE_FILE)
 
+typedef pte_t *pte_addr_t;
+
 #endif /* __ASSEMBLY__ */
 #endif /* _CRIS_PGTABLE_H */
diff --git a/include/asm-cris/processor.h b/include/asm-cris/processor.h
--- a/include/asm-cris/processor.h
+++ b/include/asm-cris/processor.h
@@ -55,15 +55,6 @@ unsigned long get_wchan(struct task_stru
 
 #define KSTK_ESP(tsk)   ((tsk) == current ? rdusp() : (tsk)->thread.usp)
 
-/*
- * Free current thread data structures etc..
- */
-
-extern inline void exit_thread(void)
-{
-        /* Nothing needs to be done.  */
-}
-
 extern unsigned long thread_saved_pc(struct task_struct *tsk);
 
 /* Free all resources held by a thread. */
diff --git a/include/asm-cris/ptrace.h b/include/asm-cris/ptrace.h
--- a/include/asm-cris/ptrace.h
+++ b/include/asm-cris/ptrace.h
@@ -9,4 +9,6 @@
 #define PTRACE_SETREGS            13
 #endif
 
+#define profile_pc(regs) instruction_pointer(regs)
+
 #endif /* _CRIS_PTRACE_H */
diff --git a/include/asm-cris/semaphore.h b/include/asm-cris/semaphore.h
--- a/include/asm-cris/semaphore.h
+++ b/include/asm-cris/semaphore.h
@@ -72,10 +72,9 @@ extern inline void down(struct semaphore
 	might_sleep();
 
 	/* atomically decrement the semaphores count, and if its negative, we wait */
-	local_save_flags(flags);
-	local_irq_disable();
+	cris_atomic_save(sem, flags);
 	failed = --(sem->count.counter) < 0;
-	local_irq_restore(flags);
+	cris_atomic_restore(sem, flags);
 	if(failed) {
 		__down(sem);
 	}
@@ -95,10 +94,9 @@ extern inline int down_interruptible(str
 	might_sleep();
 
 	/* atomically decrement the semaphores count, and if its negative, we wait */
-	local_save_flags(flags);
-	local_irq_disable();
+	cris_atomic_save(sem, flags);
 	failed = --(sem->count.counter) < 0;
-	local_irq_restore(flags);
+	cris_atomic_restore(sem, flags);
 	if(failed)
 		failed = __down_interruptible(sem);
 	return(failed);
@@ -109,13 +107,13 @@ extern inline int down_trylock(struct se
 	unsigned long flags;
 	int failed;
 
-	local_save_flags(flags);
-	local_irq_disable();
+	cris_atomic_save(sem, flags);
 	failed = --(sem->count.counter) < 0;
-	local_irq_restore(flags);
+	cris_atomic_restore(sem, flags);
 	if(failed)
 		failed = __down_trylock(sem);
 	return(failed);
+
 }
 
 /*
@@ -130,10 +128,9 @@ extern inline void up(struct semaphore *
 	int wakeup;
 
 	/* atomically increment the semaphores count, and if it was negative, we wake people */
-	local_save_flags(flags);
-	local_irq_disable();
+	cris_atomic_save(sem, flags);
 	wakeup = ++(sem->count.counter) <= 0;
-	local_irq_restore(flags);
+	cris_atomic_restore(sem, flags);
 	if(wakeup) {
 		__up(sem);
 	}
diff --git a/include/asm-cris/smp.h b/include/asm-cris/smp.h
--- a/include/asm-cris/smp.h
+++ b/include/asm-cris/smp.h
@@ -1,4 +1,11 @@
 #ifndef __ASM_SMP_H
 #define __ASM_SMP_H
 
+#include <linux/cpumask.h>
+
+extern cpumask_t phys_cpu_present_map;
+#define cpu_possible_map phys_cpu_present_map
+
+#define __smp_processor_id() (current_thread_info()->cpu)
+
 #endif
diff --git a/include/asm-cris/spinlock.h b/include/asm-cris/spinlock.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/spinlock.h
@@ -0,0 +1 @@
+#include <asm/arch/spinlock.h>
diff --git a/include/asm-cris/sync_serial.h b/include/asm-cris/sync_serial.h
new file mode 100644
--- /dev/null
+++ b/include/asm-cris/sync_serial.h
@@ -0,0 +1,106 @@
+/*
+ * ioctl defines for synchronous serial port driver
+ *
+ * Copyright (c) 2001-2003 Axis Communications AB
+ *
+ * Author: Mikael Starvik
+ *
+ */
+
+#ifndef SYNC_SERIAL_H
+#define SYNC_SERIAL_H
+
+#include <linux/ioctl.h>
+
+#define SSP_SPEED      _IOR('S', 0, unsigned int)
+#define SSP_MODE       _IOR('S', 1, unsigned int)
+#define SSP_FRAME_SYNC _IOR('S', 2, unsigned int)
+#define SSP_IPOLARITY  _IOR('S', 3, unsigned int)
+#define SSP_OPOLARITY  _IOR('S', 4, unsigned int)
+#define SSP_SPI        _IOR('S', 5, unsigned int)
+#define SSP_INBUFCHUNK _IOR('S', 6, unsigned int)
+
+/* Values for SSP_SPEED */
+#define SSP150        0
+#define SSP300        1
+#define SSP600        2
+#define SSP1200       3
+#define SSP2400       4
+#define SSP4800       5
+#define SSP9600       6
+#define SSP19200      7
+#define SSP28800      8
+#define SSP57600      9
+#define SSP115200    10
+#define SSP230400    11
+#define SSP460800    12
+#define SSP921600    13
+#define SSP3125000   14
+#define CODEC        15
+
+#define FREQ_4MHz   0
+#define FREQ_2MHz   1
+#define FREQ_1MHz   2
+#define FREQ_512kHz 3
+#define FREQ_256kHz 4
+#define FREQ_128kHz 5
+#define FREQ_64kHz  6
+#define FREQ_32kHz  7
+
+/* Used by application to set CODEC divider, word rate and frame rate */
+#define CODEC_VAL(freq, clk_per_sync, sync_per_frame) (CODEC | (freq << 8) | (clk_per_sync << 16) | (sync_per_frame << 28))
+
+/* Used by driver to extract speed */
+#define GET_SPEED(x) (x & 0xff)
+#define GET_FREQ(x) ((x & 0xff00) >> 8)
+#define GET_WORD_RATE(x) (((x & 0x0fff0000) >> 16) - 1)
+#define GET_FRAME_RATE(x) (((x & 0xf0000000) >> 28) - 1)
+
+/* Values for SSP_MODE */
+#define MASTER_OUTPUT 0
+#define SLAVE_OUTPUT  1
+#define MASTER_INPUT  2
+#define SLAVE_INPUT   3
+#define MASTER_BIDIR  4
+#define SLAVE_BIDIR   5
+
+/* Values for SSP_FRAME_SYNC */
+#define NORMAL_SYNC                1
+#define EARLY_SYNC                 2
+
+#define BIT_SYNC                   4
+#define WORD_SYNC                  8
+#define EXTENDED_SYNC           0x10
+
+#define SYNC_OFF                0x20
+#define SYNC_ON                 0x40
+#define WORD_SIZE_8             0x80
+#define WORD_SIZE_12           0x100
+#define WORD_SIZE_16           0x200
+#define WORD_SIZE_24           0x400
+#define WORD_SIZE_32           0x800
+#define BIT_ORDER_LSB         0x1000
+#define BIT_ORDER_MSB         0x2000
+#define FLOW_CONTROL_ENABLE   0x4000
+#define FLOW_CONTROL_DISABLE  0x8000
+#define CLOCK_GATED          0x10000
+#define CLOCK_NOT_GATED      0x20000
+
+/* Values for SSP_IPOLARITY and SSP_OPOLARITY */
+#define CLOCK_NORMAL         1
+#define CLOCK_INVERT         2
+#define CLOCK_INEGEDGE       CLOCK_NORMAL
+#define CLOCK_IPOSEDGE       CLOCK_INVERT
+#define FRAME_NORMAL         4
+#define FRAME_INVERT         8
+#define STATUS_NORMAL      0x10
+#define STATUS_INVERT      0x20
+
+/* Values for SSP_SPI */
+#define SPI_MASTER           0
+#define SPI_SLAVE            1
+
+/* Values for SSP_INBUFCHUNK */
+/* plain integer with the size of DMA chunks */
+
+#endif
diff --git a/include/asm-cris/termbits.h b/include/asm-cris/termbits.h
--- a/include/asm-cris/termbits.h
+++ b/include/asm-cris/termbits.h
@@ -152,7 +152,7 @@ struct termios {
 #define  B921600   0010005
 #define  B1843200  0010006
 #define  B6250000  0010007
-/* etrax 200 supports this as well */
+/* ETRAX FS supports this as well */
 #define  B12500000 0010010
 #define CIBAUD	  002003600000	/* input baud rate (used in v32) */
 /* The values for CIBAUD bits are the same as the values for CBAUD and CBAUDEX
diff --git a/include/asm-cris/thread_info.h b/include/asm-cris/thread_info.h
--- a/include/asm-cris/thread_info.h
+++ b/include/asm-cris/thread_info.h
@@ -31,7 +31,7 @@ struct thread_info {
 	struct exec_domain	*exec_domain;	/* execution domain */
 	unsigned long		flags;		/* low level flags */
 	__u32			cpu;		/* current CPU */
-	__s32			preempt_count; /* 0 => preemptable, <0 => BUG */
+	int			preempt_count;	/* 0 => preemptable, <0 => BUG */
 
 	mm_segment_t		addr_limit;	/* thread address space:
 					 	   0-0xBFFFFFFF for user-thead
@@ -43,7 +43,7 @@ struct thread_info {
 
 #endif
 
-#define PREEMPT_ACTIVE		0x4000000
+#define PREEMPT_ACTIVE		0x10000000
 
 /*
  * macros/functions for gaining access to the thread information structure
diff --git a/include/asm-cris/timex.h b/include/asm-cris/timex.h
--- a/include/asm-cris/timex.h
+++ b/include/asm-cris/timex.h
@@ -14,7 +14,7 @@
  * used so it does not matter.
  */
 
-typedef unsigned int cycles_t;
+typedef unsigned long long cycles_t;
 
 extern inline cycles_t get_cycles(void)
 {
diff --git a/include/asm-cris/tlbflush.h b/include/asm-cris/tlbflush.h
--- a/include/asm-cris/tlbflush.h
+++ b/include/asm-cris/tlbflush.h
@@ -18,13 +18,26 @@
  *
  */
 
+extern void __flush_tlb_all(void);
+extern void __flush_tlb_mm(struct mm_struct *mm);
+extern void __flush_tlb_page(struct vm_area_struct *vma,
+			   unsigned long addr);
+
+#ifdef CONFIG_SMP
 extern void flush_tlb_all(void);
 extern void flush_tlb_mm(struct mm_struct *mm);
 extern void flush_tlb_page(struct vm_area_struct *vma, 
 			   unsigned long addr);
-extern void flush_tlb_range(struct vm_area_struct *vma,
-			    unsigned long start,
-			    unsigned long end);
+#else
+#define flush_tlb_all __flush_tlb_all
+#define flush_tlb_mm __flush_tlb_mm
+#define flush_tlb_page __flush_tlb_page
+#endif
+
+static inline void flush_tlb_range(struct vm_area_struct * vma, unsigned long start, unsigned long end)
+{
+	flush_tlb_mm(vma->vm_mm);
+}
 
 extern inline void flush_tlb_pgtables(struct mm_struct *mm,
                                       unsigned long start, unsigned long end)
diff --git a/include/asm-cris/types.h b/include/asm-cris/types.h
--- a/include/asm-cris/types.h
+++ b/include/asm-cris/types.h
@@ -52,7 +52,7 @@ typedef unsigned long long u64;
 typedef u32 dma_addr_t;
 typedef u32 dma64_addr_t;
 
-typedef unsigned int kmem_bufctl_t;
+typedef unsigned short kmem_bufctl_t;
 
 #endif /* __ASSEMBLY__ */
 
diff --git a/include/asm-cris/unistd.h b/include/asm-cris/unistd.h
--- a/include/asm-cris/unistd.h
+++ b/include/asm-cris/unistd.h
@@ -288,8 +288,15 @@
 #define __NR_mq_timedreceive	(__NR_mq_open+3)
 #define __NR_mq_notify		(__NR_mq_open+4)
 #define __NR_mq_getsetattr	(__NR_mq_open+5)
- 
-#define NR_syscalls 283
+#define __NR_sys_kexec_load	283
+#define __NR_waitid		284
+/* #define __NR_sys_setaltroot	285 */
+#define __NR_add_key		286
+#define __NR_request_key	287
+#define __NR_keyctl		288
+
+#define NR_syscalls 289
+
 
 
 #ifdef __KERNEL__
diff --git a/include/asm-frv/emergency-restart.h b/include/asm-frv/emergency-restart.h
new file mode 100644
--- /dev/null
+++ b/include/asm-frv/emergency-restart.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_EMERGENCY_RESTART_H
+#define _ASM_EMERGENCY_RESTART_H
+
+#include <asm-generic/emergency-restart.h>
+
+#endif /* _ASM_EMERGENCY_RESTART_H */
diff --git a/include/asm-frv/pci.h b/include/asm-frv/pci.h
--- a/include/asm-frv/pci.h
+++ b/include/asm-frv/pci.h
@@ -57,6 +57,16 @@ extern void pci_free_consistent(struct p
  */
 #define PCI_DMA_BUS_IS_PHYS	(1)
 
+#ifdef CONFIG_PCI
+static inline void pci_dma_burst_advice(struct pci_dev *pdev,
+					enum pci_dma_burst_strategy *strat,
+					unsigned long *strategy_parameter)
+{
+	*strat = PCI_DMA_BURST_INFINITY;
+	*strategy_parameter = ~0UL;
+}
+#endif
+
 /*
  *	These are pretty much arbitary with the CoMEM implementation.
  *	We have the whole address space to ourselves.
diff --git a/include/asm-frv/thread_info.h b/include/asm-frv/thread_info.h
--- a/include/asm-frv/thread_info.h
+++ b/include/asm-frv/thread_info.h
@@ -33,7 +33,7 @@ struct thread_info {
 	unsigned long		flags;		/* low level flags */
 	unsigned long		status;		/* thread-synchronous flags */
 	__u32			cpu;		/* current CPU */
-	__s32			preempt_count;	/* 0 => preemptable, <0 => BUG */
+	int			preempt_count;	/* 0 => preemptable, <0 => BUG */
 
 	mm_segment_t		addr_limit;	/* thread address space:
 					 	   0-0xBFFFFFFF for user-thead
diff --git a/include/asm-generic/emergency-restart.h b/include/asm-generic/emergency-restart.h
new file mode 100644
--- /dev/null
+++ b/include/asm-generic/emergency-restart.h
@@ -0,0 +1,9 @@
+#ifndef _ASM_GENERIC_EMERGENCY_RESTART_H
+#define _ASM_GENERIC_EMERGENCY_RESTART_H
+
+static inline void machine_emergency_restart(void)
+{
+	machine_restart(NULL);
+}
+
+#endif /* _ASM_GENERIC_EMERGENCY_RESTART_H */
diff --git a/include/asm-generic/pci.h b/include/asm-generic/pci.h
--- a/include/asm-generic/pci.h
+++ b/include/asm-generic/pci.h
@@ -22,6 +22,14 @@ pcibios_resource_to_bus(struct pci_dev *
 	region->end = res->end;
 }
 
+static inline void
+pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
+			struct pci_bus_region *region)
+{
+	res->start = region->start;
+	res->end = region->end;
+}
+
 #define pcibios_scan_all_fns(a, b)	0
 
 #ifndef HAVE_ARCH_PCI_GET_LEGACY_IDE_IRQ
diff --git a/include/asm-generic/percpu.h b/include/asm-generic/percpu.h
--- a/include/asm-generic/percpu.h
+++ b/include/asm-generic/percpu.h
@@ -29,7 +29,7 @@ do {								\
 #define DEFINE_PER_CPU(type, name) \
     __typeof__(type) per_cpu__##name
 
-#define per_cpu(var, cpu)			(*((void)cpu, &per_cpu__##var))
+#define per_cpu(var, cpu)			(*((void)(cpu), &per_cpu__##var))
 #define __get_cpu_var(var)			per_cpu__##var
 
 #endif	/* SMP */
diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h
--- a/include/asm-generic/pgtable.h
+++ b/include/asm-generic/pgtable.h
@@ -125,6 +125,9 @@ static inline void ptep_set_wrprotect(st
 
 #ifndef __HAVE_ARCH_PAGE_TEST_AND_CLEAR_DIRTY
 #define page_test_and_clear_dirty(page) (0)
+#define pte_maybe_dirty(pte)		pte_dirty(pte)
+#else
+#define pte_maybe_dirty(pte)		(1)
 #endif
 
 #ifndef __HAVE_ARCH_PAGE_TEST_AND_CLEAR_YOUNG
diff --git a/include/asm-generic/sections.h b/include/asm-generic/sections.h
--- a/include/asm-generic/sections.h
+++ b/include/asm-generic/sections.h
@@ -11,5 +11,6 @@ extern char _sinittext[], _einittext[];
 extern char _sextratext[] __attribute__((weak));
 extern char _eextratext[] __attribute__((weak));
 extern char _end[];
+extern char __per_cpu_start[], __per_cpu_end[];
 
 #endif /* _ASM_GENERIC_SECTIONS_H_ */
diff --git a/include/asm-generic/topology.h b/include/asm-generic/topology.h
--- a/include/asm-generic/topology.h
+++ b/include/asm-generic/topology.h
@@ -41,8 +41,15 @@
 #ifndef node_to_first_cpu
 #define node_to_first_cpu(node)	(0)
 #endif
+#ifndef pcibus_to_node
+#define pcibus_to_node(node)	(-1)
+#endif
+
 #ifndef pcibus_to_cpumask
-#define pcibus_to_cpumask(bus)	(cpu_online_map)
+#define pcibus_to_cpumask(bus)	(pcibus_to_node(bus) == -1 ? \
+					CPU_MASK_ALL : \
+					node_to_cpumask(pcibus_to_node(bus)) \
+				)
 #endif
 
 #endif /* _ASM_GENERIC_TOPOLOGY_H */
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -73,7 +73,7 @@
 	}
 
 #define SECURITY_INIT							\
-	.security_initcall.init : {					\
+	.security_initcall.init : AT(ADDR(.security_initcall.init) - LOAD_OFFSET) { \
 		VMLINUX_SYMBOL(__security_initcall_start) = .;		\
 		*(.security_initcall.init) 				\
 		VMLINUX_SYMBOL(__security_initcall_end) = .;		\
diff --git a/include/asm-h8300/emergency-restart.h b/include/asm-h8300/emergency-restart.h
new file mode 100644
--- /dev/null
+++ b/include/asm-h8300/emergency-restart.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_EMERGENCY_RESTART_H
+#define _ASM_EMERGENCY_RESTART_H
+
+#include <asm-generic/emergency-restart.h>
+
+#endif /* _ASM_EMERGENCY_RESTART_H */
diff --git a/include/asm-h8300/pci.h b/include/asm-h8300/pci.h
--- a/include/asm-h8300/pci.h
+++ b/include/asm-h8300/pci.h
@@ -15,7 +15,7 @@ extern inline void pcibios_set_master(st
 	/* No special bus mastering setup handling */
 }
 
-extern inline void pcibios_penalize_isa_irq(int irq)
+extern inline void pcibios_penalize_isa_irq(int irq, int active)
 {
 	/* We don't do dynamic PCI IRQ allocation */
 }
diff --git a/include/asm-h8300/thread_info.h b/include/asm-h8300/thread_info.h
--- a/include/asm-h8300/thread_info.h
+++ b/include/asm-h8300/thread_info.h
@@ -23,7 +23,7 @@ struct thread_info {
 	struct exec_domain *exec_domain;	/* execution domain */
 	unsigned long	   flags;		/* low level flags */
 	int		   cpu;			/* cpu we're on */
-	int		   preempt_count;	/* 0 => preemptable, <0 => BUG*/
+	int		   preempt_count;	/* 0 => preemptable, <0 => BUG */
 	struct restart_block restart_block;
 };
 
diff --git a/include/asm-i386/acpi.h b/include/asm-i386/acpi.h
--- a/include/asm-i386/acpi.h
+++ b/include/asm-i386/acpi.h
@@ -28,6 +28,8 @@
 
 #ifdef __KERNEL__
 
+#include <acpi/pdc_intel.h>
+
 #include <asm/system.h>		/* defines cmpxchg */
 
 #define COMPILER_DEPENDENT_INT64   long long
@@ -101,12 +103,6 @@ __acpi_release_global_lock (unsigned int
         :"=r"(n_hi), "=r"(n_lo)     \
         :"0"(n_hi), "1"(n_lo))
 
-/*
- * Refer Intel ACPI _PDC support document for bit definitions
- */
-#define ACPI_PDC_EST_CAPABILITY_SMP 	0xa
-#define ACPI_PDC_EST_CAPABILITY_MSR	0x1
-
 #ifdef CONFIG_ACPI_BOOT 
 extern int acpi_lapic;
 extern int acpi_ioapic;
@@ -185,6 +181,8 @@ extern void acpi_reserve_bootmem(void);
 
 extern u8 x86_acpiid_to_apicid[];
 
+#define ARCH_HAS_POWER_PDC_INIT	1
+
 #endif /*__KERNEL__*/
 
 #endif /*_ASM_ACPI_H*/
diff --git a/include/asm-i386/apic.h b/include/asm-i386/apic.h
--- a/include/asm-i386/apic.h
+++ b/include/asm-i386/apic.h
@@ -5,6 +5,7 @@
 #include <linux/pm.h>
 #include <asm/fixmap.h>
 #include <asm/apicdef.h>
+#include <asm/processor.h>
 #include <asm/system.h>
 
 #define Dprintk(x...)
@@ -16,8 +17,20 @@
 #define APIC_VERBOSE 1
 #define APIC_DEBUG   2
 
+extern int enable_local_apic;
 extern int apic_verbosity;
 
+static inline void lapic_disable(void)
+{
+	enable_local_apic = -1;
+	clear_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability);
+}
+
+static inline void lapic_enable(void)
+{
+	enable_local_apic = 1;
+}
+
 /*
  * Define the default level of output to be very little
  * This can be turned up by using apic=verbose for more
@@ -87,7 +100,7 @@ extern void (*wait_timer_tick)(void);
 extern int get_maxlvt(void);
 extern void clear_local_APIC(void);
 extern void connect_bsp_APIC (void);
-extern void disconnect_bsp_APIC (void);
+extern void disconnect_bsp_APIC (int virt_wire_setup);
 extern void disable_local_APIC (void);
 extern void lapic_shutdown (void);
 extern int verify_local_APIC (void);
diff --git a/include/asm-i386/apicdef.h b/include/asm-i386/apicdef.h
--- a/include/asm-i386/apicdef.h
+++ b/include/asm-i386/apicdef.h
@@ -86,11 +86,12 @@
 #define			APIC_LVT_REMOTE_IRR		(1<<14)
 #define			APIC_INPUT_POLARITY		(1<<13)
 #define			APIC_SEND_PENDING		(1<<12)
+#define			APIC_MODE_MASK			0x700
 #define			GET_APIC_DELIVERY_MODE(x)	(((x)>>8)&0x7)
 #define			SET_APIC_DELIVERY_MODE(x,y)	(((x)&~0x700)|((y)<<8))
 #define				APIC_MODE_FIXED		0x0
 #define				APIC_MODE_NMI		0x4
-#define				APIC_MODE_EXINT		0x7
+#define				APIC_MODE_EXTINT	0x7
 #define 	APIC_LVT1	0x360
 #define		APIC_LVTERR	0x370
 #define		APIC_TMICT	0x380
@@ -108,11 +109,7 @@
 
 #define APIC_BASE (fix_to_virt(FIX_APIC_BASE))
 
-#ifdef CONFIG_NUMA
- #define MAX_IO_APICS 32
-#else
- #define MAX_IO_APICS 8
-#endif
+#define MAX_IO_APICS 64
 
 /*
  * the local APIC register structure, memory mapped. Not terribly well
diff --git a/include/asm-i386/bitops.h b/include/asm-i386/bitops.h
--- a/include/asm-i386/bitops.h
+++ b/include/asm-i386/bitops.h
@@ -311,6 +311,20 @@ static inline int find_first_zero_bit(co
 int find_next_zero_bit(const unsigned long *addr, int size, int offset);
 
 /**
+ * __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;
+}
+
+/**
  * 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
@@ -320,22 +334,15 @@ int find_next_zero_bit(const unsigned lo
  */
 static inline int find_first_bit(const unsigned long *addr, unsigned size)
 {
-	int d0, d1;
-	int res;
+	int x = 0;
 
-	/* 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) : "memory");
-	return res;
+	while (x < size) {
+		unsigned long val = *addr++;
+		if (val)
+			return __ffs(val) + x;
+		x += (sizeof(*addr)<<3);
+	}
+	return x;
 }
 
 /**
@@ -360,20 +367,6 @@ static inline unsigned long ffz(unsigned
 	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.
  */
diff --git a/include/asm-i386/checksum.h b/include/asm-i386/checksum.h
--- a/include/asm-i386/checksum.h
+++ b/include/asm-i386/checksum.h
@@ -3,6 +3,8 @@
 
 #include <linux/in6.h>
 
+#include <asm/uaccess.h>
+
 /*
  * computes the checksum of a memory block at buff, length len,
  * and adds in "sum" (32-bit)
diff --git a/include/asm-i386/cpu.h b/include/asm-i386/cpu.h
--- a/include/asm-i386/cpu.h
+++ b/include/asm-i386/cpu.h
@@ -5,6 +5,7 @@
 #include <linux/cpu.h>
 #include <linux/topology.h>
 #include <linux/nodemask.h>
+#include <linux/percpu.h>
 
 #include <asm/node.h>
 
@@ -16,4 +17,5 @@ extern int arch_register_cpu(int num);
 extern void arch_unregister_cpu(int);
 #endif
 
+DECLARE_PER_CPU(int, cpu_state);
 #endif /* _ASM_I386_CPU_H_ */
diff --git a/include/asm-i386/emergency-restart.h b/include/asm-i386/emergency-restart.h
new file mode 100644
--- /dev/null
+++ b/include/asm-i386/emergency-restart.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_EMERGENCY_RESTART_H
+#define _ASM_EMERGENCY_RESTART_H
+
+extern void machine_emergency_restart(void);
+
+#endif /* _ASM_EMERGENCY_RESTART_H */
diff --git a/include/asm-i386/genapic.h b/include/asm-i386/genapic.h
--- a/include/asm-i386/genapic.h
+++ b/include/asm-i386/genapic.h
@@ -78,7 +78,6 @@ struct genapic { 
 	.int_delivery_mode = INT_DELIVERY_MODE, \
 	.int_dest_mode = INT_DEST_MODE, \
 	.no_balance_irq = NO_BALANCE_IRQ, \
-	.no_ioapic_check = NO_IOAPIC_CHECK, \
 	.ESR_DISABLE = esr_disable, \
 	.apic_destination_logical = APIC_DEST_LOGICAL, \
 	APICFUNC(apic_id_registered), \
diff --git a/include/asm-i386/highmem.h b/include/asm-i386/highmem.h
--- a/include/asm-i386/highmem.h
+++ b/include/asm-i386/highmem.h
@@ -70,6 +70,7 @@ void *kmap(struct page *page);
 void kunmap(struct page *page);
 void *kmap_atomic(struct page *page, enum km_type type);
 void kunmap_atomic(void *kvaddr, enum km_type type);
+void *kmap_atomic_pfn(unsigned long pfn, enum km_type type);
 struct page *kmap_atomic_to_page(void *ptr);
 
 #define flush_cache_kmaps()	do { } while (0)
diff --git a/include/asm-i386/i387.h b/include/asm-i386/i387.h
--- a/include/asm-i386/i387.h
+++ b/include/asm-i386/i387.h
@@ -19,10 +19,21 @@
 
 extern void mxcsr_feature_mask_init(void);
 extern void init_fpu(struct task_struct *);
+
 /*
  * FPU lazy state save handling...
  */
-extern void restore_fpu( struct task_struct *tsk );
+
+/*
+ * The "nop" is needed to make the instructions the same
+ * length.
+ */
+#define restore_fpu(tsk)			\
+	alternative_input(			\
+		"nop ; frstor %1",		\
+		"fxrstor %1",			\
+		X86_FEATURE_FXSR,		\
+		"m" ((tsk)->thread.i387.fxsave))
 
 extern void kernel_fpu_begin(void);
 #define kernel_fpu_end() do { stts(); preempt_enable(); } while(0)
@@ -32,13 +43,12 @@ extern void kernel_fpu_begin(void);
  */
 static inline void __save_init_fpu( struct task_struct *tsk )
 {
-	if ( cpu_has_fxsr ) {
-		asm volatile( "fxsave %0 ; fnclex"
-			      : "=m" (tsk->thread.i387.fxsave) );
-	} else {
-		asm volatile( "fnsave %0 ; fwait"
-			      : "=m" (tsk->thread.i387.fsave) );
-	}
+	alternative_input(
+		"fnsave %1 ; fwait ;" GENERIC_NOP2,
+		"fxsave %1 ; fnclex",
+		X86_FEATURE_FXSR,
+		"m" (tsk->thread.i387.fxsave)
+		:"memory");
 	tsk->thread_info->status &= ~TS_USEDFPU;
 }
 
diff --git a/include/asm-i386/i8253.h b/include/asm-i386/i8253.h
new file mode 100644
--- /dev/null
+++ b/include/asm-i386/i8253.h
@@ -0,0 +1,6 @@
+#ifndef __ASM_I8253_H__
+#define __ASM_I8253_H__
+
+extern spinlock_t i8253_lock;
+
+#endif	/* __ASM_I8253_H__ */
diff --git a/include/asm-i386/ide.h b/include/asm-i386/ide.h
--- a/include/asm-i386/ide.h
+++ b/include/asm-i386/ide.h
@@ -41,13 +41,17 @@ static __inline__ int ide_default_irq(un
 
 static __inline__ unsigned long ide_default_io_base(int index)
 {
+	if (pci_find_device(PCI_ANY_ID, PCI_ANY_ID, NULL) == NULL) {
+		switch(index) {
+			case 2: return 0x1e8;
+			case 3: return 0x168;
+			case 4: return 0x1e0;
+			case 5: return 0x160;
+		}
+	}
 	switch (index) {
 		case 0:	return 0x1f0;
 		case 1:	return 0x170;
-		case 2: return 0x1e8;
-		case 3: return 0x168;
-		case 4: return 0x1e0;
-		case 5: return 0x160;
 		default:
 			return 0;
 	}
diff --git a/include/asm-i386/irq.h b/include/asm-i386/irq.h
--- a/include/asm-i386/irq.h
+++ b/include/asm-i386/irq.h
@@ -29,13 +29,19 @@ extern void release_vm86_irqs(struct tas
 
 #ifdef CONFIG_4KSTACKS
   extern void irq_ctx_init(int cpu);
+  extern void irq_ctx_exit(int cpu);
 # define __ARCH_HAS_DO_SOFTIRQ
 #else
 # define irq_ctx_init(cpu) do { } while (0)
+# define irq_ctx_exit(cpu) do { } while (0)
 #endif
 
 #ifdef CONFIG_IRQBALANCE
 extern int irqbalance_disable(char *str);
 #endif
 
+#ifdef CONFIG_HOTPLUG_CPU
+extern void fixup_irqs(cpumask_t map);
+#endif
+
 #endif /* _ASM_IRQ_H */
diff --git a/include/asm-i386/kdebug.h b/include/asm-i386/kdebug.h
--- a/include/asm-i386/kdebug.h
+++ b/include/asm-i386/kdebug.h
@@ -18,7 +18,7 @@ struct die_args {
 };
 
 /* Note - you should never unregister because that can race with NMIs.
-   If you really want to do it first unregister - then synchronize_kernel - then free.
+   If you really want to do it first unregister - then synchronize_sched - then free.
   */
 int register_die_notifier(struct notifier_block *nb);
 extern struct notifier_block *i386die_chain;
diff --git a/include/asm-i386/kexec.h b/include/asm-i386/kexec.h
new file mode 100644
--- /dev/null
+++ b/include/asm-i386/kexec.h
@@ -0,0 +1,33 @@
+#ifndef _I386_KEXEC_H
+#define _I386_KEXEC_H
+
+#include <asm/fixmap.h>
+
+/*
+ * KEXEC_SOURCE_MEMORY_LIMIT maximum page get_free_page can return.
+ * I.e. Maximum page that is mapped directly into kernel memory,
+ * and kmap is not required.
+ *
+ * Someone correct me if FIXADDR_START - PAGEOFFSET is not the correct
+ * calculation for the amount of memory directly mappable into the
+ * kernel memory space.
+ */
+
+/* Maximum physical address we can use pages from */
+#define KEXEC_SOURCE_MEMORY_LIMIT (-1UL)
+/* Maximum address we can reach in physical address mode */
+#define KEXEC_DESTINATION_MEMORY_LIMIT (-1UL)
+/* Maximum address we can use for the control code buffer */
+#define KEXEC_CONTROL_MEMORY_LIMIT TASK_SIZE
+
+#define KEXEC_CONTROL_CODE_SIZE	4096
+
+/* The native architecture */
+#define KEXEC_ARCH KEXEC_ARCH_386
+
+#define MAX_NOTE_BYTES 1024
+typedef u32 note_buf_t[MAX_NOTE_BYTES/4];
+
+extern note_buf_t crash_notes[];
+
+#endif /* _I386_KEXEC_H */
diff --git a/include/asm-i386/kprobes.h b/include/asm-i386/kprobes.h
--- a/include/asm-i386/kprobes.h
+++ b/include/asm-i386/kprobes.h
@@ -39,6 +39,9 @@ typedef u8 kprobe_opcode_t;
 	: (((unsigned long)current_thread_info()) + THREAD_SIZE - (ADDR)))
 
 #define JPROBE_ENTRY(pentry)	(kprobe_opcode_t *)pentry
+#define ARCH_SUPPORTS_KRETPROBES
+
+void kretprobe_trampoline(void);
 
 /* Architecture specific copy of original instruction*/
 struct arch_specific_insn {
diff --git a/include/asm-i386/mach-bigsmp/mach_apic.h b/include/asm-i386/mach-bigsmp/mach_apic.h
--- a/include/asm-i386/mach-bigsmp/mach_apic.h
+++ b/include/asm-i386/mach-bigsmp/mach_apic.h
@@ -14,8 +14,6 @@
 #define NO_BALANCE_IRQ (1)
 #define esr_disable (1)
 
-#define NO_IOAPIC_CHECK (0)
-
 static inline int apic_id_registered(void)
 {
 	return (1);
diff --git a/include/asm-i386/mach-default/do_timer.h b/include/asm-i386/mach-default/do_timer.h
--- a/include/asm-i386/mach-default/do_timer.h
+++ b/include/asm-i386/mach-default/do_timer.h
@@ -1,6 +1,7 @@
 /* defines for inline arch setup functions */
 
 #include <asm/apic.h>
+#include <asm/i8259.h>
 
 /**
  * do_timer_interrupt_hook - hook into timer tick
diff --git a/include/asm-i386/mach-default/mach_apic.h b/include/asm-i386/mach-default/mach_apic.h
--- a/include/asm-i386/mach-default/mach_apic.h
+++ b/include/asm-i386/mach-default/mach_apic.h
@@ -19,8 +19,6 @@ static inline cpumask_t target_cpus(void
 #define NO_BALANCE_IRQ (0)
 #define esr_disable (0)
 
-#define NO_IOAPIC_CHECK (0)
-
 #define INT_DELIVERY_MODE dest_LowestPrio
 #define INT_DEST_MODE 1     /* logical delivery broadcast to all procs */
 
diff --git a/include/asm-i386/mach-default/mach_ipi.h b/include/asm-i386/mach-default/mach_ipi.h
--- a/include/asm-i386/mach-default/mach_ipi.h
+++ b/include/asm-i386/mach-default/mach_ipi.h
@@ -4,11 +4,34 @@
 void send_IPI_mask_bitmask(cpumask_t mask, int vector);
 void __send_IPI_shortcut(unsigned int shortcut, int vector);
 
+extern int no_broadcast;
+
 static inline void send_IPI_mask(cpumask_t mask, int vector)
 {
 	send_IPI_mask_bitmask(mask, vector);
 }
 
+static inline void __local_send_IPI_allbutself(int vector)
+{
+	if (no_broadcast) {
+		cpumask_t mask = cpu_online_map;
+		int this_cpu = get_cpu();
+
+		cpu_clear(this_cpu, mask);
+		send_IPI_mask(mask, vector);
+		put_cpu();
+	} else
+		__send_IPI_shortcut(APIC_DEST_ALLBUT, vector);
+}
+
+static inline void __local_send_IPI_all(int vector)
+{
+	if (no_broadcast)
+		send_IPI_mask(cpu_online_map, vector);
+	else
+		__send_IPI_shortcut(APIC_DEST_ALLINC, vector);
+}
+
 static inline void send_IPI_allbutself(int vector)
 {
 	/*
@@ -18,13 +41,13 @@ static inline void send_IPI_allbutself(i
 	if (!(num_online_cpus() > 1))
 		return;
 
-	__send_IPI_shortcut(APIC_DEST_ALLBUT, vector);
+	__local_send_IPI_allbutself(vector);
 	return;
 }
 
 static inline void send_IPI_all(int vector)
 {
-	__send_IPI_shortcut(APIC_DEST_ALLINC, vector);
+	__local_send_IPI_all(vector);
 }
 
 #endif /* __ASM_MACH_IPI_H */
diff --git a/include/asm-i386/mach-es7000/mach_apic.h b/include/asm-i386/mach-es7000/mach_apic.h
--- a/include/asm-i386/mach-es7000/mach_apic.h
+++ b/include/asm-i386/mach-es7000/mach_apic.h
@@ -38,8 +38,6 @@ static inline cpumask_t target_cpus(void
 #define WAKE_SECONDARY_VIA_INIT
 #endif
 
-#define NO_IOAPIC_CHECK (1)
-
 static inline unsigned long check_apicid_used(physid_mask_t bitmap, int apicid)
 { 
 	return 0;
diff --git a/include/asm-i386/mach-generic/mach_apic.h b/include/asm-i386/mach-generic/mach_apic.h
--- a/include/asm-i386/mach-generic/mach_apic.h
+++ b/include/asm-i386/mach-generic/mach_apic.h
@@ -5,7 +5,6 @@
 
 #define esr_disable (genapic->ESR_DISABLE)
 #define NO_BALANCE_IRQ (genapic->no_balance_irq)
-#define NO_IOAPIC_CHECK	(genapic->no_ioapic_check)
 #define INT_DELIVERY_MODE (genapic->int_delivery_mode)
 #define INT_DEST_MODE (genapic->int_dest_mode)
 #undef APIC_DEST_LOGICAL
diff --git a/include/asm-i386/mach-numaq/mach_apic.h b/include/asm-i386/mach-numaq/mach_apic.h
--- a/include/asm-i386/mach-numaq/mach_apic.h
+++ b/include/asm-i386/mach-numaq/mach_apic.h
@@ -17,8 +17,6 @@ static inline cpumask_t target_cpus(void
 #define NO_BALANCE_IRQ (1)
 #define esr_disable (1)
 
-#define NO_IOAPIC_CHECK (0)
-
 #define INT_DELIVERY_MODE dest_LowestPrio
 #define INT_DEST_MODE 0     /* physical delivery on LOCAL quad */
  
diff --git a/include/asm-i386/mach-summit/mach_apic.h b/include/asm-i386/mach-summit/mach_apic.h
--- a/include/asm-i386/mach-summit/mach_apic.h
+++ b/include/asm-i386/mach-summit/mach_apic.h
@@ -7,8 +7,6 @@
 #define esr_disable (1)
 #define NO_BALANCE_IRQ (0)
 
-#define NO_IOAPIC_CHECK (1)	/* Don't check I/O APIC ID for xAPIC */
-
 /* In clustered mode, the high nibble of APIC ID is a cluster number.
  * The low nibble is a 4-bit bitmap. */
 #define XAPIC_DEST_CPUS_SHIFT	4
diff --git a/include/asm-i386/mach-visws/do_timer.h b/include/asm-i386/mach-visws/do_timer.h
--- a/include/asm-i386/mach-visws/do_timer.h
+++ b/include/asm-i386/mach-visws/do_timer.h
@@ -1,6 +1,7 @@
 /* defines for inline arch setup functions */
 
 #include <asm/fixmap.h>
+#include <asm/i8259.h>
 #include "cobalt.h"
 
 static inline void do_timer_interrupt_hook(struct pt_regs *regs)
diff --git a/include/asm-i386/mach-visws/mach_apic.h b/include/asm-i386/mach-visws/mach_apic.h
--- a/include/asm-i386/mach-visws/mach_apic.h
+++ b/include/asm-i386/mach-visws/mach_apic.h
@@ -9,8 +9,6 @@
 #define no_balance_irq (0)
 #define esr_disable (0)
 
-#define NO_IOAPIC_CHECK (0)
-
 #define INT_DELIVERY_MODE dest_LowestPrio
 #define INT_DEST_MODE 1     /* logical delivery broadcast to all procs */
 
diff --git a/include/asm-i386/mmzone.h b/include/asm-i386/mmzone.h
--- a/include/asm-i386/mmzone.h
+++ b/include/asm-i386/mmzone.h
@@ -8,21 +8,43 @@
 
 #include <asm/smp.h>
 
-#ifdef CONFIG_DISCONTIGMEM
-
 #ifdef CONFIG_NUMA
-	#ifdef CONFIG_X86_NUMAQ
-		#include <asm/numaq.h>
-	#else	/* summit or generic arch */
-		#include <asm/srat.h>
-	#endif
+extern struct pglist_data *node_data[];
+#define NODE_DATA(nid)	(node_data[nid])
+
+#ifdef CONFIG_X86_NUMAQ
+	#include <asm/numaq.h>
+#else	/* summit or generic arch */
+	#include <asm/srat.h>
+#endif
+
+extern int get_memcfg_numa_flat(void );
+/*
+ * This allows any one NUMA architecture to be compiled
+ * for, and still fall back to the flat function if it
+ * fails.
+ */
+static inline void get_memcfg_numa(void)
+{
+#ifdef CONFIG_X86_NUMAQ
+	if (get_memcfg_numaq())
+		return;
+#elif CONFIG_ACPI_SRAT
+	if (get_memcfg_from_srat())
+		return;
+#endif
+
+	get_memcfg_numa_flat();
+}
+
+extern int early_pfn_to_nid(unsigned long pfn);
+
 #else /* !CONFIG_NUMA */
-	#define get_memcfg_numa get_memcfg_numa_flat
-	#define get_zholes_size(n) (0)
+#define get_memcfg_numa get_memcfg_numa_flat
+#define get_zholes_size(n) (0)
 #endif /* CONFIG_NUMA */
 
-extern struct pglist_data *node_data[];
-#define NODE_DATA(nid)		(node_data[nid])
+#ifdef CONFIG_DISCONTIGMEM
 
 /*
  * generic node memory support, the following assumptions apply:
@@ -48,26 +70,6 @@ static inline int pfn_to_nid(unsigned lo
 #endif
 }
 
-/*
- * Following are macros that are specific to this numa platform.
- */
-#define reserve_bootmem(addr, size) \
-	reserve_bootmem_node(NODE_DATA(0), (addr), (size))
-#define alloc_bootmem(x) \
-	__alloc_bootmem_node(NODE_DATA(0), (x), SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS))
-#define alloc_bootmem_low(x) \
-	__alloc_bootmem_node(NODE_DATA(0), (x), SMP_CACHE_BYTES, 0)
-#define alloc_bootmem_pages(x) \
-	__alloc_bootmem_node(NODE_DATA(0), (x), PAGE_SIZE, __pa(MAX_DMA_ADDRESS))
-#define alloc_bootmem_low_pages(x) \
-	__alloc_bootmem_node(NODE_DATA(0), (x), PAGE_SIZE, 0)
-#define alloc_bootmem_node(ignore, x) \
-	__alloc_bootmem_node(NODE_DATA(0), (x), SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS))
-#define alloc_bootmem_pages_node(ignore, x) \
-	__alloc_bootmem_node(NODE_DATA(0), (x), PAGE_SIZE, __pa(MAX_DMA_ADDRESS))
-#define alloc_bootmem_low_pages_node(ignore, x) \
-	__alloc_bootmem_node(NODE_DATA(0), (x), PAGE_SIZE, 0)
-
 #define node_localnr(pfn, nid)		((pfn) - node_data[nid]->node_start_pfn)
 
 /*
@@ -79,7 +81,6 @@ static inline int pfn_to_nid(unsigned lo
  */
 #define kvaddr_to_nid(kaddr)	pfn_to_nid(__pa(kaddr) >> PAGE_SHIFT)
 
-#define node_mem_map(nid)	(NODE_DATA(nid)->node_mem_map)
 #define node_start_pfn(nid)	(NODE_DATA(nid)->node_start_pfn)
 #define node_end_pfn(nid)						\
 ({									\
@@ -100,7 +101,7 @@ static inline int pfn_to_nid(unsigned lo
 ({									\
 	unsigned long __pfn = pfn;					\
 	int __node  = pfn_to_nid(__pfn);				\
-	&node_mem_map(__node)[node_localnr(__pfn,__node)];		\
+	&NODE_DATA(__node)->node_mem_map[node_localnr(__pfn,__node)];	\
 })
 
 #define page_to_pfn(pg)							\
@@ -122,26 +123,32 @@ static inline int pfn_valid(int pfn)
 		return (pfn < node_end_pfn(nid));
 	return 0;
 }
-#endif
+#endif /* CONFIG_X86_NUMAQ */
+
+#endif /* CONFIG_DISCONTIGMEM */
+
+#ifdef CONFIG_NEED_MULTIPLE_NODES
 
-extern int get_memcfg_numa_flat(void );
 /*
- * This allows any one NUMA architecture to be compiled
- * for, and still fall back to the flat function if it
- * fails.
+ * Following are macros that are specific to this numa platform.
  */
-static inline void get_memcfg_numa(void)
-{
-#ifdef CONFIG_X86_NUMAQ
-	if (get_memcfg_numaq())
-		return;
-#elif CONFIG_ACPI_SRAT
-	if (get_memcfg_from_srat())
-		return;
-#endif
+#define reserve_bootmem(addr, size) \
+	reserve_bootmem_node(NODE_DATA(0), (addr), (size))
+#define alloc_bootmem(x) \
+	__alloc_bootmem_node(NODE_DATA(0), (x), SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS))
+#define alloc_bootmem_low(x) \
+	__alloc_bootmem_node(NODE_DATA(0), (x), SMP_CACHE_BYTES, 0)
+#define alloc_bootmem_pages(x) \
+	__alloc_bootmem_node(NODE_DATA(0), (x), PAGE_SIZE, __pa(MAX_DMA_ADDRESS))
+#define alloc_bootmem_low_pages(x) \
+	__alloc_bootmem_node(NODE_DATA(0), (x), PAGE_SIZE, 0)
+#define alloc_bootmem_node(ignore, x) \
+	__alloc_bootmem_node(NODE_DATA(0), (x), SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS))
+#define alloc_bootmem_pages_node(ignore, x) \
+	__alloc_bootmem_node(NODE_DATA(0), (x), PAGE_SIZE, __pa(MAX_DMA_ADDRESS))
+#define alloc_bootmem_low_pages_node(ignore, x) \
+	__alloc_bootmem_node(NODE_DATA(0), (x), PAGE_SIZE, 0)
 
-	get_memcfg_numa_flat();
-}
+#endif /* CONFIG_NEED_MULTIPLE_NODES */
 
-#endif /* CONFIG_DISCONTIGMEM */
 #endif /* _ASM_MMZONE_H_ */
diff --git a/include/asm-i386/page.h b/include/asm-i386/page.h
--- a/include/asm-i386/page.h
+++ b/include/asm-i386/page.h
@@ -68,6 +68,7 @@ typedef struct { unsigned long pgprot; }
 #define HPAGE_MASK	(~(HPAGE_SIZE - 1))
 #define HUGETLB_PAGE_ORDER	(HPAGE_SHIFT - PAGE_SHIFT)
 #define HAVE_ARCH_HUGETLB_UNMAPPED_AREA
+#define ARCH_HAS_HUGETLB_CLEAN_STALE_PGTABLE
 #endif
 
 #define pgd_val(x)	((x).pgd)
@@ -119,13 +120,18 @@ static __inline__ int get_order(unsigned
 
 extern int sysctl_legacy_va_layout;
 
+extern int page_is_ram(unsigned long pagenr);
+
 #endif /* __ASSEMBLY__ */
 
 #ifdef __ASSEMBLY__
 #define __PAGE_OFFSET		(0xC0000000)
+#define __PHYSICAL_START	CONFIG_PHYSICAL_START
 #else
 #define __PAGE_OFFSET		(0xC0000000UL)
+#define __PHYSICAL_START	((unsigned long)CONFIG_PHYSICAL_START)
 #endif
+#define __KERNEL_START		(__PAGE_OFFSET + __PHYSICAL_START)
 
 
 #define PAGE_OFFSET		((unsigned long)__PAGE_OFFSET)
@@ -134,11 +140,11 @@ extern int sysctl_legacy_va_layout;
 #define __pa(x)			((unsigned long)(x)-PAGE_OFFSET)
 #define __va(x)			((void *)((unsigned long)(x)+PAGE_OFFSET))
 #define pfn_to_kaddr(pfn)      __va((pfn) << PAGE_SHIFT)
-#ifndef CONFIG_DISCONTIGMEM
+#ifdef CONFIG_FLATMEM
 #define pfn_to_page(pfn)	(mem_map + (pfn))
 #define page_to_pfn(page)	((unsigned long)((page) - mem_map))
 #define pfn_valid(pfn)		((pfn) < max_mapnr)
-#endif /* !CONFIG_DISCONTIGMEM */
+#endif /* CONFIG_FLATMEM */
 #define virt_to_page(kaddr)	pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
 
 #define virt_addr_valid(kaddr)	pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
diff --git a/include/asm-i386/param.h b/include/asm-i386/param.h
--- a/include/asm-i386/param.h
+++ b/include/asm-i386/param.h
@@ -1,8 +1,10 @@
+#include <linux/config.h>
+
 #ifndef _ASMi386_PARAM_H
 #define _ASMi386_PARAM_H
 
 #ifdef __KERNEL__
-# define HZ		1000		/* Internal kernel timer frequency */
+# define HZ		CONFIG_HZ	/* Internal kernel timer frequency */
 # define USER_HZ	100		/* .. some user interfaces are in "ticks" */
 # define CLOCKS_PER_SEC		(USER_HZ)	/* like times() */
 #endif
diff --git a/include/asm-i386/pci.h b/include/asm-i386/pci.h
--- a/include/asm-i386/pci.h
+++ b/include/asm-i386/pci.h
@@ -27,7 +27,7 @@ void pcibios_config_init(void);
 struct pci_bus * pcibios_scan_root(int bus);
 
 void pcibios_set_master(struct pci_dev *dev);
-void pcibios_penalize_isa_irq(int irq);
+void pcibios_penalize_isa_irq(int irq, int active);
 struct irq_routing_table *pcibios_get_irq_routing_table(void);
 int pcibios_set_irq_routing(struct pci_dev *dev, int pin, int irq);
 
@@ -99,6 +99,16 @@ static inline void pcibios_add_platform_
 {
 }
 
+#ifdef CONFIG_PCI
+static inline void pci_dma_burst_advice(struct pci_dev *pdev,
+					enum pci_dma_burst_strategy *strat,
+					unsigned long *strategy_parameter)
+{
+	*strat = PCI_DMA_BURST_INFINITY;
+	*strategy_parameter = ~0UL;
+}
+#endif
+
 #endif /* __KERNEL__ */
 
 /* implement the pci_ DMA API in terms of the generic device dma_ one */
diff --git a/include/asm-i386/pgtable.h b/include/asm-i386/pgtable.h
--- a/include/asm-i386/pgtable.h
+++ b/include/asm-i386/pgtable.h
@@ -236,6 +236,7 @@ static inline pte_t pte_mkexec(pte_t pte
 static inline pte_t pte_mkdirty(pte_t pte)	{ (pte).pte_low |= _PAGE_DIRTY; return pte; }
 static inline pte_t pte_mkyoung(pte_t pte)	{ (pte).pte_low |= _PAGE_ACCESSED; return pte; }
 static inline pte_t pte_mkwrite(pte_t pte)	{ (pte).pte_low |= _PAGE_RW; return pte; }
+static inline pte_t pte_mkhuge(pte_t pte)	{ (pte).pte_low |= _PAGE_PRESENT | _PAGE_PSE; return pte; }
 
 #ifdef CONFIG_X86_PAE
 # include <asm/pgtable-3level.h>
@@ -275,7 +276,6 @@ static inline void ptep_set_wrprotect(st
  */
 
 #define mk_pte(page, pgprot)	pfn_pte(page_to_pfn(page), (pgprot))
-#define mk_pte_huge(entry) ((entry).pte_low |= _PAGE_PRESENT | _PAGE_PSE)
 
 static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
 {
@@ -398,9 +398,9 @@ extern void noexec_setup(const char *str
 
 #endif /* !__ASSEMBLY__ */
 
-#ifndef CONFIG_DISCONTIGMEM
+#ifdef CONFIG_FLATMEM
 #define kern_addr_valid(addr)	(1)
-#endif /* !CONFIG_DISCONTIGMEM */
+#endif /* CONFIG_FLATMEM */
 
 #define io_remap_page_range(vma, vaddr, paddr, size, prot)		\
 		remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot)
diff --git a/include/asm-i386/processor.h b/include/asm-i386/processor.h
--- a/include/asm-i386/processor.h
+++ b/include/asm-i386/processor.h
@@ -29,7 +29,7 @@ struct desc_struct {
 };
 
 #define desc_empty(desc) \
-		(!((desc)->a + (desc)->b))
+		(!((desc)->a | (desc)->b))
 
 #define desc_equal(desc1, desc2) \
 		(((desc1)->a == (desc2)->a) && ((desc1)->b == (desc2)->b))
@@ -501,12 +501,16 @@ static inline void load_esp0(struct tss_
 } while (0)
 
 /*
- * This special macro can be used to load a debugging register
+ * These special macros can be used to get or set a debugging register
  */
-#define loaddebug(thread,register) \
-               __asm__("movl %0,%%db" #register  \
-                       : /* no output */ \
-                       :"r" ((thread)->debugreg[register]))
+#define get_debugreg(var, register)				\
+		__asm__("movl %%db" #register ", %0"		\
+			:"=r" (var))
+#define set_debugreg(value, register)			\
+		__asm__("movl %0,%%db" #register		\
+			: /* no output */			\
+			:"r" (value))
+
 
 /* Forward declaration, a strange C thing */
 struct task_struct;
@@ -687,5 +691,15 @@ extern void select_idle_routine(const st
 #define cache_line_size() (boot_cpu_data.x86_cache_alignment)
 
 extern unsigned long boot_option_idle_override;
+extern void enable_sep_cpu(void);
+extern int sysenter_setup(void);
+
+#ifdef CONFIG_MTRR
+extern void mtrr_ap_init(void);
+extern void mtrr_bp_init(void);
+#else
+#define mtrr_ap_init() do {} while (0)
+#define mtrr_bp_init() do {} while (0)
+#endif
 
 #endif /* __ASM_I386_PROCESSOR_H */
diff --git a/include/asm-i386/ptrace.h b/include/asm-i386/ptrace.h
--- a/include/asm-i386/ptrace.h
+++ b/include/asm-i386/ptrace.h
@@ -55,15 +55,26 @@ struct pt_regs {
 #define PTRACE_SET_THREAD_AREA    26
 
 #ifdef __KERNEL__
+
+#include <asm/vm86.h>
+
 struct task_struct;
 extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code);
-#define user_mode(regs) ((VM_MASK & (regs)->eflags) || (3 & (regs)->xcs))
+
+static inline int user_mode(struct pt_regs *regs)
+{
+	return (regs->xcs & 3) != 0;
+}
+static inline int user_mode_vm(struct pt_regs *regs)
+{
+	return ((regs->xcs & 3) | (regs->eflags & VM_MASK)) != 0;
+}
 #define instruction_pointer(regs) ((regs)->eip)
 #if defined(CONFIG_SMP) && defined(CONFIG_FRAME_POINTER)
 extern unsigned long profile_pc(struct pt_regs *regs);
 #else
 #define profile_pc(regs) instruction_pointer(regs)
 #endif
-#endif
+#endif /* __KERNEL__ */
 
 #endif
diff --git a/include/asm-i386/serial.h b/include/asm-i386/serial.h
--- a/include/asm-i386/serial.h
+++ b/include/asm-i386/serial.h
@@ -22,109 +22,9 @@
 #define STD_COM4_FLAGS ASYNC_BOOT_AUTOCONF
 #endif
 
-#ifdef CONFIG_SERIAL_MANY_PORTS
-#define FOURPORT_FLAGS ASYNC_FOURPORT
-#define ACCENT_FLAGS 0
-#define BOCA_FLAGS 0
-#define HUB6_FLAGS 0
-#endif
-
-#define MCA_COM_FLAGS	(STD_COM_FLAGS|ASYNC_BOOT_ONLYMCA)
-
-/*
- * The following define the access methods for the HUB6 card. All
- * access is through two ports for all 24 possible chips. The card is
- * selected through the high 2 bits, the port on that card with the
- * "middle" 3 bits, and the register on that port with the bottom
- * 3 bits.
- *
- * While the access port and interrupt is configurable, the default
- * port locations are 0x302 for the port control register, and 0x303
- * for the data read/write register. Normally, the interrupt is at irq3
- * but can be anything from 3 to 7 inclusive. Note that using 3 will
- * require disabling com2.
- */
-
-#define C_P(card,port) (((card)<<6|(port)<<3) + 1)
-
-#define STD_SERIAL_PORT_DEFNS			\
+#define SERIAL_PORT_DFNS			\
 	/* UART CLK   PORT IRQ     FLAGS        */			\
 	{ 0, BASE_BAUD, 0x3F8, 4, STD_COM_FLAGS },	/* ttyS0 */	\
 	{ 0, BASE_BAUD, 0x2F8, 3, STD_COM_FLAGS },	/* ttyS1 */	\
 	{ 0, BASE_BAUD, 0x3E8, 4, STD_COM_FLAGS },	/* ttyS2 */	\
 	{ 0, BASE_BAUD, 0x2E8, 3, STD_COM4_FLAGS },	/* ttyS3 */
-
-
-#ifdef CONFIG_SERIAL_MANY_PORTS
-#define EXTRA_SERIAL_PORT_DEFNS			\
-	{ 0, BASE_BAUD, 0x1A0, 9, FOURPORT_FLAGS }, 	/* ttyS4 */	\
-	{ 0, BASE_BAUD, 0x1A8, 9, FOURPORT_FLAGS },	/* ttyS5 */	\
-	{ 0, BASE_BAUD, 0x1B0, 9, FOURPORT_FLAGS },	/* ttyS6 */	\
-	{ 0, BASE_BAUD, 0x1B8, 9, FOURPORT_FLAGS },	/* ttyS7 */	\
-	{ 0, BASE_BAUD, 0x2A0, 5, FOURPORT_FLAGS },	/* ttyS8 */	\
-	{ 0, BASE_BAUD, 0x2A8, 5, FOURPORT_FLAGS },	/* ttyS9 */	\
-	{ 0, BASE_BAUD, 0x2B0, 5, FOURPORT_FLAGS },	/* ttyS10 */	\
-	{ 0, BASE_BAUD, 0x2B8, 5, FOURPORT_FLAGS },	/* ttyS11 */	\
-	{ 0, BASE_BAUD, 0x330, 4, ACCENT_FLAGS },	/* ttyS12 */	\
-	{ 0, BASE_BAUD, 0x338, 4, ACCENT_FLAGS },	/* ttyS13 */	\
-	{ 0, BASE_BAUD, 0x000, 0, 0 },	/* ttyS14 (spare) */		\
-	{ 0, BASE_BAUD, 0x000, 0, 0 },	/* ttyS15 (spare) */		\
-	{ 0, BASE_BAUD, 0x100, 12, BOCA_FLAGS },	/* ttyS16 */	\
-	{ 0, BASE_BAUD, 0x108, 12, BOCA_FLAGS },	/* ttyS17 */	\
-	{ 0, BASE_BAUD, 0x110, 12, BOCA_FLAGS },	/* ttyS18 */	\
-	{ 0, BASE_BAUD, 0x118, 12, BOCA_FLAGS },	/* ttyS19 */	\
-	{ 0, BASE_BAUD, 0x120, 12, BOCA_FLAGS },	/* ttyS20 */	\
-	{ 0, BASE_BAUD, 0x128, 12, BOCA_FLAGS },	/* ttyS21 */	\
-	{ 0, BASE_BAUD, 0x130, 12, BOCA_FLAGS },	/* ttyS22 */	\
-	{ 0, BASE_BAUD, 0x138, 12, BOCA_FLAGS },	/* ttyS23 */	\
-	{ 0, BASE_BAUD, 0x140, 12, BOCA_FLAGS },	/* ttyS24 */	\
-	{ 0, BASE_BAUD, 0x148, 12, BOCA_FLAGS },	/* ttyS25 */	\
-	{ 0, BASE_BAUD, 0x150, 12, BOCA_FLAGS },	/* ttyS26 */	\
-	{ 0, BASE_BAUD, 0x158, 12, BOCA_FLAGS },	/* ttyS27 */	\
-	{ 0, BASE_BAUD, 0x160, 12, BOCA_FLAGS },	/* ttyS28 */	\
-	{ 0, BASE_BAUD, 0x168, 12, BOCA_FLAGS },	/* ttyS29 */	\
-	{ 0, BASE_BAUD, 0x170, 12, BOCA_FLAGS },	/* ttyS30 */	\
-	{ 0, BASE_BAUD, 0x178, 12, BOCA_FLAGS },	/* ttyS31 */
-#else
-#define EXTRA_SERIAL_PORT_DEFNS
-#endif
-
-/* You can have up to four HUB6's in the system, but I've only
- * included two cards here for a total of twelve ports.
- */
-#if (defined(CONFIG_HUB6) && defined(CONFIG_SERIAL_MANY_PORTS))
-#define HUB6_SERIAL_PORT_DFNS		\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,0) },  /* ttyS32 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,1) },  /* ttyS33 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,2) },  /* ttyS34 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,3) },  /* ttyS35 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,4) },  /* ttyS36 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,5) },  /* ttyS37 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,0) },  /* ttyS38 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,1) },  /* ttyS39 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,2) },  /* ttyS40 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,3) },  /* ttyS41 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,4) },  /* ttyS42 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,5) },  /* ttyS43 */
-#else
-#define HUB6_SERIAL_PORT_DFNS
-#endif
-
-#ifdef CONFIG_MCA
-#define MCA_SERIAL_PORT_DFNS			\
-	{ 0, BASE_BAUD, 0x3220, 3, MCA_COM_FLAGS },	\
-	{ 0, BASE_BAUD, 0x3228, 3, MCA_COM_FLAGS },	\
-	{ 0, BASE_BAUD, 0x4220, 3, MCA_COM_FLAGS },	\
-	{ 0, BASE_BAUD, 0x4228, 3, MCA_COM_FLAGS },	\
-	{ 0, BASE_BAUD, 0x5220, 3, MCA_COM_FLAGS },	\
-	{ 0, BASE_BAUD, 0x5228, 3, MCA_COM_FLAGS },
-#else
-#define MCA_SERIAL_PORT_DFNS
-#endif
-
-#define SERIAL_PORT_DFNS		\
-	STD_SERIAL_PORT_DEFNS		\
-	EXTRA_SERIAL_PORT_DEFNS		\
-	HUB6_SERIAL_PORT_DFNS		\
-	MCA_SERIAL_PORT_DFNS
-
diff --git a/include/asm-i386/smp.h b/include/asm-i386/smp.h
--- a/include/asm-i386/smp.h
+++ b/include/asm-i386/smp.h
@@ -37,21 +37,25 @@ extern int smp_num_siblings;
 extern cpumask_t cpu_sibling_map[];
 extern cpumask_t cpu_core_map[];
 
-extern void smp_flush_tlb(void);
-extern void smp_message_irq(int cpl, void *dev_id, struct pt_regs *regs);
-extern void smp_invalidate_rcv(void);		/* Process an NMI */
 extern void (*mtrr_hook) (void);
 extern void zap_low_mappings (void);
+extern void lock_ipi_call_lock(void);
+extern void unlock_ipi_call_lock(void);
 
 #define MAX_APICID 256
 extern u8 x86_cpu_to_apicid[];
 
+#ifdef CONFIG_HOTPLUG_CPU
+extern void cpu_exit_clear(void);
+extern void cpu_uninit(void);
+#endif
+
 /*
  * This function is needed by all SMP systems. It must _always_ be valid
  * from the initial startup. We map APIC_BASE very early in page_setup(),
  * so this is correct in the x86 case.
  */
-#define __smp_processor_id() (current_thread_info()->cpu)
+#define raw_smp_processor_id() (current_thread_info()->cpu)
 
 extern cpumask_t cpu_callout_map;
 extern cpumask_t cpu_callin_map;
@@ -83,6 +87,9 @@ static __inline int logical_smp_processo
 }
 
 #endif
+
+extern int __cpu_disable(void);
+extern void __cpu_die(unsigned int cpu);
 #endif /* !__ASSEMBLY__ */
 
 #define NO_PROC_ID		0xFF		/* No processor magic marker */
diff --git a/include/asm-i386/sparsemem.h b/include/asm-i386/sparsemem.h
new file mode 100644
--- /dev/null
+++ b/include/asm-i386/sparsemem.h
@@ -0,0 +1,31 @@
+#ifndef _I386_SPARSEMEM_H
+#define _I386_SPARSEMEM_H
+#ifdef CONFIG_SPARSEMEM
+
+/*
+ * generic non-linear memory support:
+ *
+ * 1) we will not split memory into more chunks than will fit into the
+ *    flags field of the struct page
+ */
+
+/*
+ * SECTION_SIZE_BITS		2^N: how big each section will be
+ * MAX_PHYSADDR_BITS		2^N: how much physical address space we have
+ * MAX_PHYSMEM_BITS		2^N: how much memory we can have in that space
+ */
+#ifdef CONFIG_X86_PAE
+#define SECTION_SIZE_BITS       30
+#define MAX_PHYSADDR_BITS       36
+#define MAX_PHYSMEM_BITS	36
+#else
+#define SECTION_SIZE_BITS       26
+#define MAX_PHYSADDR_BITS       32
+#define MAX_PHYSMEM_BITS	32
+#endif
+
+/* XXX: FIXME -- wli */
+#define kern_addr_valid(kaddr)  (0)
+
+#endif /* CONFIG_SPARSEMEM */
+#endif /* _I386_SPARSEMEM_H */
diff --git a/include/asm-i386/string.h b/include/asm-i386/string.h
--- a/include/asm-i386/string.h
+++ b/include/asm-i386/string.h
@@ -116,7 +116,8 @@ __asm__ __volatile__(
 	"orb $1,%%al\n"
 	"3:"
 	:"=a" (__res), "=&S" (d0), "=&D" (d1)
-		     :"1" (cs),"2" (ct));
+	:"1" (cs),"2" (ct)
+	:"memory");
 return __res;
 }
 
@@ -138,8 +139,9 @@ __asm__ __volatile__(
 	"3:\tsbbl %%eax,%%eax\n\t"
 	"orb $1,%%al\n"
 	"4:"
-		     :"=a" (__res), "=&S" (d0), "=&D" (d1), "=&c" (d2)
-		     :"1" (cs),"2" (ct),"3" (count));
+	:"=a" (__res), "=&S" (d0), "=&D" (d1), "=&c" (d2)
+	:"1" (cs),"2" (ct),"3" (count)
+	:"memory");
 return __res;
 }
 
@@ -158,7 +160,9 @@ __asm__ __volatile__(
 	"movl $1,%1\n"
 	"2:\tmovl %1,%0\n\t"
 	"decl %0"
-	:"=a" (__res), "=&S" (d0) : "1" (s),"0" (c));
+	:"=a" (__res), "=&S" (d0)
+	:"1" (s),"0" (c)
+	:"memory");
 return __res;
 }
 
@@ -175,7 +179,9 @@ __asm__ __volatile__(
 	"leal -1(%%esi),%0\n"
 	"2:\ttestb %%al,%%al\n\t"
 	"jne 1b"
-	:"=g" (__res), "=&S" (d0), "=&a" (d1) :"0" (0),"1" (s),"2" (c));
+	:"=g" (__res), "=&S" (d0), "=&a" (d1)
+	:"0" (0),"1" (s),"2" (c)
+	:"memory");
 return __res;
 }
 
@@ -189,7 +195,9 @@ __asm__ __volatile__(
 	"scasb\n\t"
 	"notl %0\n\t"
 	"decl %0"
-	:"=c" (__res), "=&D" (d0) :"1" (s),"a" (0), "0" (0xffffffffu));
+	:"=c" (__res), "=&D" (d0)
+	:"1" (s),"a" (0), "0" (0xffffffffu)
+	:"memory");
 return __res;
 }
 
@@ -333,7 +341,9 @@ __asm__ __volatile__(
 	"je 1f\n\t"
 	"movl $1,%0\n"
 	"1:\tdecl %0"
-	:"=D" (__res), "=&c" (d0) : "a" (c),"0" (cs),"1" (count));
+	:"=D" (__res), "=&c" (d0)
+	:"a" (c),"0" (cs),"1" (count)
+	:"memory");
 return __res;
 }
 
@@ -369,7 +379,7 @@ __asm__ __volatile__(
 	"je 2f\n\t"
 	"stosb\n"
 	"2:"
-	: "=&c" (d0), "=&D" (d1)
+	:"=&c" (d0), "=&D" (d1)
 	:"a" (c), "q" (count), "0" (count/4), "1" ((long) s)
 	:"memory");
 return (s);	
@@ -392,7 +402,8 @@ __asm__ __volatile__(
 	"jne 1b\n"
 	"3:\tsubl %2,%0"
 	:"=a" (__res), "=&d" (d0)
-	:"c" (s),"1" (count));
+	:"c" (s),"1" (count)
+	:"memory");
 return __res;
 }
 /* end of additional stuff */
@@ -473,7 +484,8 @@ static inline void * memscan(void * addr
 		"dec %%edi\n"
 		"1:"
 		: "=D" (addr), "=c" (size)
-		: "0" (addr), "1" (size), "a" (c));
+		: "0" (addr), "1" (size), "a" (c)
+		: "memory");
 	return addr;
 }
 
diff --git a/include/asm-i386/thread_info.h b/include/asm-i386/thread_info.h
--- a/include/asm-i386/thread_info.h
+++ b/include/asm-i386/thread_info.h
@@ -31,7 +31,7 @@ struct thread_info {
 	unsigned long		flags;		/* low level flags */
 	unsigned long		status;		/* thread-synchronous flags */
 	__u32			cpu;		/* current CPU */
-	__s32			preempt_count; /* 0 => preemptable, <0 => BUG */
+	int			preempt_count;	/* 0 => preemptable, <0 => BUG */
 
 
 	mm_segment_t		addr_limit;	/* thread address space:
diff --git a/include/asm-i386/timer.h b/include/asm-i386/timer.h
--- a/include/asm-i386/timer.h
+++ b/include/asm-i386/timer.h
@@ -22,6 +22,7 @@ struct timer_opts {
 	unsigned long (*get_offset)(void);
 	unsigned long long (*monotonic_clock)(void);
 	void (*delay)(unsigned long);
+	unsigned long (*read_timer)(void);
 };
 
 struct init_timer_opts {
@@ -52,6 +53,7 @@ extern struct init_timer_opts timer_cycl
 #endif
 
 extern unsigned long calibrate_tsc(void);
+extern unsigned long read_timer_tsc(void);
 extern void init_cpu_khz(void);
 extern int recalibrate_cpu_khz(void);
 #ifdef CONFIG_HPET_TIMER
diff --git a/include/asm-i386/timex.h b/include/asm-i386/timex.h
--- a/include/asm-i386/timex.h
+++ b/include/asm-i386/timex.h
@@ -47,6 +47,9 @@ static inline cycles_t get_cycles (void)
 	return ret;
 }
 
-extern unsigned long cpu_khz;
+extern unsigned int cpu_khz;
+
+extern int read_current_timer(unsigned long *timer_value);
+#define ARCH_HAS_READ_CURRENT_TIMER	1
 
 #endif
diff --git a/include/asm-i386/tlbflush.h b/include/asm-i386/tlbflush.h
--- a/include/asm-i386/tlbflush.h
+++ b/include/asm-i386/tlbflush.h
@@ -22,16 +22,18 @@
  */
 #define __flush_tlb_global()						\
 	do {								\
-		unsigned int tmpreg;					\
+		unsigned int tmpreg, cr4, cr4_orig;			\
 									\
 		__asm__ __volatile__(					\
-			"movl %1, %%cr4;  # turn off PGE     \n"	\
+			"movl %%cr4, %2;  # turn off PGE     \n"	\
+			"movl %2, %1;                        \n"	\
+			"andl %3, %1;                        \n"	\
+			"movl %1, %%cr4;                     \n"	\
 			"movl %%cr3, %0;                     \n"	\
 			"movl %0, %%cr3;  # flush TLB        \n"	\
 			"movl %2, %%cr4;  # turn PGE back on \n"	\
-			: "=&r" (tmpreg)				\
-			: "r" (mmu_cr4_features & ~X86_CR4_PGE),	\
-			  "r" (mmu_cr4_features)			\
+			: "=&r" (tmpreg), "=&r" (cr4), "=&r" (cr4_orig)	\
+			: "i" (~X86_CR4_PGE)				\
 			: "memory");					\
 	} while (0)
 
diff --git a/include/asm-i386/topology.h b/include/asm-i386/topology.h
--- a/include/asm-i386/topology.h
+++ b/include/asm-i386/topology.h
@@ -60,12 +60,8 @@ static inline int node_to_first_cpu(int 
 	return first_cpu(mask);
 }
 
-/* Returns the number of the node containing PCI bus number 'busnr' */
-static inline cpumask_t __pcibus_to_cpumask(int busnr)
-{
-	return node_to_cpumask(mp_bus_id_to_node[busnr]);
-}
-#define pcibus_to_cpumask(bus)	__pcibus_to_cpumask(bus->number)
+#define pcibus_to_node(bus) mp_bus_id_to_node[(bus)->number]
+#define pcibus_to_cpumask(bus) node_to_cpumask(pcibus_to_node(bus))
 
 /* sched_domains SD_NODE_INIT for NUMAQ machines */
 #define SD_NODE_INIT (struct sched_domain) {		\
@@ -78,11 +74,14 @@ static inline cpumask_t __pcibus_to_cpum
 	.imbalance_pct		= 125,			\
 	.cache_hot_time		= (10*1000000),		\
 	.cache_nice_tries	= 1,			\
+	.busy_idx		= 3,			\
+	.idle_idx		= 1,			\
+	.newidle_idx		= 2,			\
+	.wake_idx		= 1,			\
 	.per_cpu_gain		= 100,			\
 	.flags			= SD_LOAD_BALANCE	\
 				| SD_BALANCE_EXEC	\
-				| SD_BALANCE_NEWIDLE	\
-				| SD_WAKE_IDLE		\
+				| SD_BALANCE_FORK	\
 				| SD_WAKE_BALANCE,	\
 	.last_balance		= jiffies,		\
 	.balance_interval	= 1,			\
diff --git a/include/asm-i386/unistd.h b/include/asm-i386/unistd.h
--- a/include/asm-i386/unistd.h
+++ b/include/asm-i386/unistd.h
@@ -256,7 +256,7 @@
 #define __NR_io_submit		248
 #define __NR_io_cancel		249
 #define __NR_fadvise64		250
-
+#define __NR_set_zone_reclaim	251
 #define __NR_exit_group		252
 #define __NR_lookup_dcookie	253
 #define __NR_epoll_create	254
@@ -294,8 +294,13 @@
 #define __NR_add_key		286
 #define __NR_request_key	287
 #define __NR_keyctl		288
+#define __NR_ioprio_set		289
+#define __NR_ioprio_get		290
+#define __NR_inotify_init	291
+#define __NR_inotify_add_watch	292
+#define __NR_inotify_rm_watch	293
 
-#define NR_syscalls 289
+#define NR_syscalls 294
 
 /*
  * user-visible error numbers are in the range -1 - -128: see
diff --git a/include/asm-ia64/acpi.h b/include/asm-ia64/acpi.h
--- a/include/asm-ia64/acpi.h
+++ b/include/asm-ia64/acpi.h
@@ -98,6 +98,15 @@ const char *acpi_get_sysname (void);
 int acpi_request_vector (u32 int_type);
 int acpi_gsi_to_irq (u32 gsi, unsigned int *irq);
 
+/*
+ * Record the cpei override flag and current logical cpu. This is
+ * useful for CPU removal.
+ */
+extern unsigned int can_cpei_retarget(void);
+extern unsigned int is_cpu_cpei_target(unsigned int cpu);
+extern void set_cpei_target_cpu(unsigned int cpu);
+extern unsigned int get_cpei_target_cpu(void);
+
 #ifdef CONFIG_ACPI_NUMA
 /* Proximity bitmap length; _PXM is at most 255 (8 bit)*/
 #define MAX_PXM_DOMAINS (256)
diff --git a/include/asm-ia64/break.h b/include/asm-ia64/break.h
--- a/include/asm-ia64/break.h
+++ b/include/asm-ia64/break.h
@@ -12,6 +12,8 @@
  * OS-specific debug break numbers:
  */
 #define __IA64_BREAK_KDB		0x80100
+#define __IA64_BREAK_KPROBE		0x80200
+#define __IA64_BREAK_JPROBE		0x80300
 
 /*
  * OS-specific break numbers:
diff --git a/include/asm-ia64/compat.h b/include/asm-ia64/compat.h
--- a/include/asm-ia64/compat.h
+++ b/include/asm-ia64/compat.h
@@ -27,6 +27,7 @@ typedef u16		compat_ipc_pid_t;
 typedef s32		compat_daddr_t;
 typedef u32		compat_caddr_t;
 typedef __kernel_fsid_t	compat_fsid_t;
+typedef s32		compat_timer_t;
 
 typedef s32		compat_int_t;
 typedef s32		compat_long_t;
diff --git a/include/asm-ia64/emergency-restart.h b/include/asm-ia64/emergency-restart.h
new file mode 100644
--- /dev/null
+++ b/include/asm-ia64/emergency-restart.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_EMERGENCY_RESTART_H
+#define _ASM_EMERGENCY_RESTART_H
+
+#include <asm-generic/emergency-restart.h>
+
+#endif /* _ASM_EMERGENCY_RESTART_H */
diff --git a/include/asm-ia64/fcntl.h b/include/asm-ia64/fcntl.h
--- a/include/asm-ia64/fcntl.h
+++ b/include/asm-ia64/fcntl.h
@@ -81,4 +81,6 @@ struct flock {
 
 #define F_LINUX_SPECIFIC_BASE	1024
 
+#define force_o_largefile() ( ! (current->personality & PER_LINUX32) )
+
 #endif /* _ASM_IA64_FCNTL_H */
diff --git a/include/asm-ia64/hw_irq.h b/include/asm-ia64/hw_irq.h
--- a/include/asm-ia64/hw_irq.h
+++ b/include/asm-ia64/hw_irq.h
@@ -81,7 +81,6 @@ extern __u8 isa_irq_to_vector_map[16];
 
 extern struct hw_interrupt_type irq_type_ia64_lsapic;	/* CPU-internal interrupt controller */
 
-extern int assign_irq_vector_nopanic (int irq); /* allocate a free vector without panic */
 extern int assign_irq_vector (int irq);	/* allocate a free vector */
 extern void free_irq_vector (int vector);
 extern void ia64_send_ipi (int cpu, int vector, int delivery_mode, int redirect);
diff --git a/include/asm-ia64/io.h b/include/asm-ia64/io.h
--- a/include/asm-ia64/io.h
+++ b/include/asm-ia64/io.h
@@ -120,14 +120,6 @@ static inline void ___ia64_mmiowb(void)
 	ia64_mfa();
 }
 
-static inline const unsigned long
-__ia64_get_io_port_base (void)
-{
-	extern unsigned long ia64_iobase;
-
-	return ia64_iobase;
-}
-
 static inline void*
 __ia64_mk_io_addr (unsigned long port)
 {
diff --git a/include/asm-ia64/iosapic.h b/include/asm-ia64/iosapic.h
--- a/include/asm-ia64/iosapic.h
+++ b/include/asm-ia64/iosapic.h
@@ -71,8 +71,13 @@ static inline void iosapic_eoi(char __io
 }
 
 extern void __init iosapic_system_init (int pcat_compat);
-extern void __init iosapic_init (unsigned long address,
+extern int __devinit iosapic_init (unsigned long address,
 				    unsigned int gsi_base);
+#ifdef CONFIG_HOTPLUG
+extern int iosapic_remove (unsigned int gsi_base);
+#else
+#define iosapic_remove(gsi_base)				(-EINVAL)
+#endif /* CONFIG_HOTPLUG */
 extern int gsi_to_vector (unsigned int gsi);
 extern int gsi_to_irq (unsigned int gsi);
 extern void iosapic_enable_intr (unsigned int vector);
@@ -94,11 +99,12 @@ extern unsigned int iosapic_version (cha
 
 extern void iosapic_pci_fixup (int);
 #ifdef CONFIG_NUMA
-extern void __init map_iosapic_to_node (unsigned int, int);
+extern void __devinit map_iosapic_to_node (unsigned int, int);
 #endif
 #else
 #define iosapic_system_init(pcat_compat)			do { } while (0)
-#define iosapic_init(address,gsi_base)				do { } while (0)
+#define iosapic_init(address,gsi_base)				(-EINVAL)
+#define iosapic_remove(gsi_base)				(-ENODEV)
 #define iosapic_register_intr(gsi,polarity,trigger)		(gsi)
 #define iosapic_unregister_intr(irq)				do { } while (0)
 #define iosapic_override_isa_irq(isa_irq,gsi,polarity,trigger)	do { } while (0)
diff --git a/include/asm-ia64/kdebug.h b/include/asm-ia64/kdebug.h
new file mode 100644
--- /dev/null
+++ b/include/asm-ia64/kdebug.h
@@ -0,0 +1,61 @@
+#ifndef _IA64_KDEBUG_H
+#define _IA64_KDEBUG_H 1
+/*
+ * include/asm-ia64/kdebug.h
+ *
+ * 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.
+ *
+ * Copyright (C) Intel Corporation, 2005
+ *
+ * 2005-Apr     Rusty Lynch <rusty.lynch@intel.com> and Anil S Keshavamurthy
+ *              <anil.s.keshavamurthy@intel.com> adopted from
+ *              include/asm-x86_64/kdebug.h
+ */
+#include <linux/notifier.h>
+
+struct pt_regs;
+
+struct die_args {
+	struct pt_regs *regs;
+	const char *str;
+	long err;
+	int trapnr;
+	int signr;
+};
+
+int register_die_notifier(struct notifier_block *nb);
+extern struct notifier_block *ia64die_chain;
+
+enum die_val {
+	DIE_BREAK = 1,
+	DIE_SS,
+	DIE_PAGE_FAULT,
+};
+
+static inline int notify_die(enum die_val val, char *str, struct pt_regs *regs,
+			     long err, int trap, int sig)
+{
+	struct die_args args = {
+		.regs   = regs,
+		.str    = str,
+		.err    = err,
+		.trapnr = trap,
+		.signr  = sig
+	};
+
+	return notifier_call_chain(&ia64die_chain, val, &args);
+}
+
+#endif
diff --git a/include/asm-ia64/kprobes.h b/include/asm-ia64/kprobes.h
new file mode 100644
--- /dev/null
+++ b/include/asm-ia64/kprobes.h
@@ -0,0 +1,120 @@
+#ifndef _ASM_KPROBES_H
+#define _ASM_KPROBES_H
+/*
+ *  Kernel Probes (KProbes)
+ *  include/asm-ia64/kprobes.h
+ *
+ * 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.
+ *
+ * Copyright (C) IBM Corporation, 2002, 2004
+ * Copyright (C) Intel Corporation, 2005
+ *
+ * 2005-Apr     Rusty Lynch <rusty.lynch@intel.com> and Anil S Keshavamurthy
+ *              <anil.s.keshavamurthy@intel.com> adapted from i386
+ */
+#include <linux/types.h>
+#include <linux/ptrace.h>
+#include <asm/break.h>
+
+#define MAX_INSN_SIZE   16
+#define BREAK_INST	(long)(__IA64_BREAK_KPROBE << 6)
+
+typedef union cmp_inst {
+	struct {
+	unsigned long long qp : 6;
+	unsigned long long p1 : 6;
+	unsigned long long c  : 1;
+	unsigned long long r2 : 7;
+	unsigned long long r3 : 7;
+	unsigned long long p2 : 6;
+	unsigned long long ta : 1;
+	unsigned long long x2 : 2;
+	unsigned long long tb : 1;
+	unsigned long long opcode : 4;
+	unsigned long long reserved : 23;
+	}f;
+	unsigned long long l;
+} cmp_inst_t;
+
+struct kprobe;
+
+typedef struct _bundle {
+	struct {
+		unsigned long long template : 5;
+		unsigned long long slot0 : 41;
+		unsigned long long slot1_p0 : 64-46;
+	} quad0;
+	struct {
+		unsigned long long slot1_p1 : 41 - (64-46);
+		unsigned long long slot2 : 41;
+	} quad1;
+} __attribute__((__aligned__(16)))  bundle_t;
+
+#define JPROBE_ENTRY(pentry)	(kprobe_opcode_t *)pentry
+
+#define ARCH_SUPPORTS_KRETPROBES
+
+#define SLOT0_OPCODE_SHIFT	(37)
+#define SLOT1_p1_OPCODE_SHIFT	(37 - (64-46))
+#define SLOT2_OPCODE_SHIFT 	(37)
+
+#define INDIRECT_CALL_OPCODE		(1)
+#define IP_RELATIVE_CALL_OPCODE		(5)
+#define IP_RELATIVE_BRANCH_OPCODE	(4)
+#define IP_RELATIVE_PREDICT_OPCODE	(7)
+#define LONG_BRANCH_OPCODE		(0xC)
+#define LONG_CALL_OPCODE		(0xD)
+
+typedef struct kprobe_opcode {
+	bundle_t bundle;
+} kprobe_opcode_t;
+
+struct fnptr {
+	unsigned long ip;
+	unsigned long gp;
+};
+
+/* Architecture specific copy of original instruction*/
+struct arch_specific_insn {
+	/* copy of the instruction to be emulated */
+	kprobe_opcode_t insn;
+ #define INST_FLAG_FIX_RELATIVE_IP_ADDR		1
+ #define INST_FLAG_FIX_BRANCH_REG		2
+ 	unsigned long inst_flag;
+ 	unsigned short target_br_reg;
+};
+
+/* ia64 does not need this */
+static inline void arch_copy_kprobe(struct kprobe *p)
+{
+}
+
+#ifdef CONFIG_KPROBES
+extern int kprobe_exceptions_notify(struct notifier_block *self,
+				    unsigned long val, void *data);
+
+/* ia64 does not need this */
+static inline void jprobe_return(void)
+{
+}
+
+#else				/* !CONFIG_KPROBES */
+static inline int kprobe_exceptions_notify(struct notifier_block *self,
+					   unsigned long val, void *data)
+{
+	return 0;
+}
+#endif
+#endif				/* _ASM_KPROBES_H */
diff --git a/include/asm-ia64/mmu_context.h b/include/asm-ia64/mmu_context.h
--- a/include/asm-ia64/mmu_context.h
+++ b/include/asm-ia64/mmu_context.h
@@ -132,6 +132,9 @@ reload_context (mm_context_t context)
 	ia64_srlz_i();			/* srlz.i implies srlz.d */
 }
 
+/*
+ * Must be called with preemption off
+ */
 static inline void
 activate_context (struct mm_struct *mm)
 {
diff --git a/include/asm-ia64/mmzone.h b/include/asm-ia64/mmzone.h
--- a/include/asm-ia64/mmzone.h
+++ b/include/asm-ia64/mmzone.h
@@ -17,6 +17,20 @@
 
 #ifdef CONFIG_DISCONTIGMEM
 
+static inline int pfn_to_nid(unsigned long pfn)
+{
+#ifdef CONFIG_NUMA
+	extern int paddr_to_nid(unsigned long);
+	int nid = paddr_to_nid(pfn << PAGE_SHIFT);
+	if (nid < 0)
+		return 0;
+	else
+		return nid;
+#else
+	return 0;
+#endif
+}
+
 #ifdef CONFIG_IA64_DIG /* DIG systems are small */
 # define MAX_PHYSNODE_ID	8
 # define NR_NODE_MEMBLKS	(MAX_NUMNODES * 8)
diff --git a/include/asm-ia64/param.h b/include/asm-ia64/param.h
--- a/include/asm-ia64/param.h
+++ b/include/asm-ia64/param.h
@@ -27,7 +27,7 @@
    */
 #  define HZ	  32
 # else
-#  define HZ	1024
+#  define HZ	CONFIG_HZ
 # endif
 # define USER_HZ	HZ
 # define CLOCKS_PER_SEC	HZ	/* frequency at which times() counts */
diff --git a/include/asm-ia64/pci.h b/include/asm-ia64/pci.h
--- a/include/asm-ia64/pci.h
+++ b/include/asm-ia64/pci.h
@@ -47,7 +47,7 @@ pcibios_set_master (struct pci_dev *dev)
 }
 
 static inline void
-pcibios_penalize_isa_irq (int irq)
+pcibios_penalize_isa_irq (int irq, int active)
 {
 	/* We don't do dynamic PCI IRQ allocation */
 }
@@ -82,6 +82,25 @@ extern int pcibios_prep_mwi (struct pci_
 #define sg_dma_len(sg)		((sg)->dma_length)
 #define sg_dma_address(sg)	((sg)->dma_address)
 
+#ifdef CONFIG_PCI
+static inline void pci_dma_burst_advice(struct pci_dev *pdev,
+					enum pci_dma_burst_strategy *strat,
+					unsigned long *strategy_parameter)
+{
+	unsigned long cacheline_size;
+	u8 byte;
+
+	pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &byte);
+	if (byte == 0)
+		cacheline_size = 1024;
+	else
+		cacheline_size = (int) byte * 4;
+
+	*strat = PCI_DMA_BURST_MULTIPLE;
+	*strategy_parameter = cacheline_size;
+}
+#endif
+
 #define HAVE_PCI_MMAP
 extern int pci_mmap_page_range (struct pci_dev *dev, struct vm_area_struct *vma,
 				enum pci_mmap_state mmap_state, int write_combine);
@@ -109,6 +128,7 @@ struct pci_controller {
 	void *acpi_handle;
 	void *iommu;
 	int segment;
+	int node;		/* nearest node with memory or -1 for global allocation */
 
 	unsigned int windows;
 	struct pci_window *window;
diff --git a/include/asm-ia64/percpu.h b/include/asm-ia64/percpu.h
--- a/include/asm-ia64/percpu.h
+++ b/include/asm-ia64/percpu.h
@@ -50,7 +50,7 @@ extern void *per_cpu_init(void);
 
 #else /* ! SMP */
 
-#define per_cpu(var, cpu)			(*((void)cpu, &per_cpu__##var))
+#define per_cpu(var, cpu)			(*((void)(cpu), &per_cpu__##var))
 #define __get_cpu_var(var)			per_cpu__##var
 #define per_cpu_init()				(__phys_per_cpu_start)
 
diff --git a/include/asm-ia64/pgtable.h b/include/asm-ia64/pgtable.h
--- a/include/asm-ia64/pgtable.h
+++ b/include/asm-ia64/pgtable.h
@@ -283,6 +283,7 @@ ia64_phys_addr_valid (unsigned long addr
 #define pte_mkyoung(pte)	(__pte(pte_val(pte) | _PAGE_A))
 #define pte_mkclean(pte)	(__pte(pte_val(pte) & ~_PAGE_D))
 #define pte_mkdirty(pte)	(__pte(pte_val(pte) | _PAGE_D))
+#define pte_mkhuge(pte)		(__pte(pte_val(pte) | _PAGE_P))
 
 /*
  * Macro to a page protection value as "uncacheable".  Note that "protection" is really a
diff --git a/include/asm-ia64/sections.h b/include/asm-ia64/sections.h
--- a/include/asm-ia64/sections.h
+++ b/include/asm-ia64/sections.h
@@ -17,6 +17,7 @@ extern char __start_gate_vtop_patchlist[
 extern char __start_gate_fsyscall_patchlist[], __end_gate_fsyscall_patchlist[];
 extern char __start_gate_brl_fsys_bubble_down_patchlist[], __end_gate_brl_fsys_bubble_down_patchlist[];
 extern char __start_unwind[], __end_unwind[];
+extern char __start_ivt_text[], __end_ivt_text[];
 
 #endif /* _ASM_IA64_SECTIONS_H */
 
diff --git a/include/asm-ia64/smp.h b/include/asm-ia64/smp.h
--- a/include/asm-ia64/smp.h
+++ b/include/asm-ia64/smp.h
@@ -46,7 +46,7 @@ ia64_get_lid (void)
 #define SMP_IRQ_REDIRECTION	(1 << 0)
 #define SMP_IPI_REDIRECTION	(1 << 1)
 
-#define smp_processor_id()	(current_thread_info()->cpu)
+#define raw_smp_processor_id() (current_thread_info()->cpu)
 
 extern struct smp_boot_data {
 	int cpu_count;
diff --git a/include/asm-ia64/sn/addrs.h b/include/asm-ia64/sn/addrs.h
--- a/include/asm-ia64/sn/addrs.h
+++ b/include/asm-ia64/sn/addrs.h
@@ -216,6 +216,10 @@
 #define TIO_SWIN_WIDGETNUM(x)		(((x)  >> TIO_SWIN_SIZE_BITS) & TIO_SWIN_WIDGET_MASK)
 
 
+#define TIO_IOSPACE_ADDR(n,x)					\
+	/* Move in the Chiplet ID for TIO Local Block MMR */	\
+	(REMOTE_ADDR(n,x) | 1UL << (NASID_SHIFT - 2))
+
 /*
  * The following macros produce the correct base virtual address for
  * the hub registers. The REMOTE_HUB_* macro produce
@@ -233,13 +237,16 @@
 #define REMOTE_HUB_ADDR(n,x)						\
 	((n & 1) ?							\
 	/* TIO: */							\
-	((volatile u64 *)(GLOBAL_MMR_ADDR(n,x)))			\
-	: /* SHUB: */							\
-	(((x) & BWIN_TOP) ? ((volatile u64 *)(GLOBAL_MMR_ADDR(n,x)))\
+	(is_shub2() ?							\
+	/* TIO on Shub2 */						\
+	(volatile u64 *)(TIO_IOSPACE_ADDR(n,x))				\
+	: /* TIO on shub1 */						\
+	(volatile u64 *)(GLOBAL_MMR_ADDR(n,x)))				\
+									\
+	: /* SHUB1 and SHUB2 MMRs: */					\
+	(((x) & BWIN_TOP) ? ((volatile u64 *)(GLOBAL_MMR_ADDR(n,x)))	\
 	: ((volatile u64 *)(NODE_SWIN_BASE(n,1) + 0x800000 + (x)))))
 
-
-
 #define HUB_L(x)			(*((volatile typeof(*x) *)x))
 #define	HUB_S(x,d)			(*((volatile typeof(*x) *)x) = (d))
 
diff --git a/include/asm-ia64/sn/arch.h b/include/asm-ia64/sn/arch.h
--- a/include/asm-ia64/sn/arch.h
+++ b/include/asm-ia64/sn/arch.h
@@ -11,6 +11,7 @@
 #ifndef _ASM_IA64_SN_ARCH_H
 #define _ASM_IA64_SN_ARCH_H
 
+#include <linux/numa.h>
 #include <asm/types.h>
 #include <asm/percpu.h>
 #include <asm/sn/types.h>
diff --git a/include/asm-ia64/sn/intr.h b/include/asm-ia64/sn/intr.h
--- a/include/asm-ia64/sn/intr.h
+++ b/include/asm-ia64/sn/intr.h
@@ -9,6 +9,8 @@
 #ifndef _ASM_IA64_SN_INTR_H
 #define _ASM_IA64_SN_INTR_H
 
+#include <linux/rcupdate.h>
+
 #define SGI_UART_VECTOR		(0xe9)
 #define SGI_PCIBR_ERROR		(0x33)
 
@@ -33,7 +35,7 @@
 
 // The SN PROM irq struct
 struct sn_irq_info {
-	struct sn_irq_info *irq_next;	/* sharing irq list	     */
+	struct sn_irq_info *irq_next;	/* deprecated DO NOT USE     */
 	short		irq_nasid;	/* Nasid IRQ is assigned to  */
 	int		irq_slice;	/* slice IRQ is assigned to  */
 	int		irq_cpuid;	/* kernel logical cpuid	     */
@@ -47,6 +49,8 @@ struct sn_irq_info {
 	int		irq_cookie;	/* unique cookie 	     */
 	int		irq_flags;	/* flags */
 	int		irq_share_cnt;	/* num devices sharing IRQ   */
+	struct list_head	list;	/* list of sn_irq_info structs */
+	struct rcu_head		rcu;	/* rcu callback list */
 };
 
 extern void sn_send_IPI_phys(int, long, int, int);
diff --git a/include/asm-ia64/sn/l1.h b/include/asm-ia64/sn/l1.h
--- a/include/asm-ia64/sn/l1.h
+++ b/include/asm-ia64/sn/l1.h
@@ -33,5 +33,6 @@
 #define L1_BRICKTYPE_PA		0x6a            /* j */
 #define L1_BRICKTYPE_IA		0x6b            /* k */
 #define L1_BRICKTYPE_ATHENA	0x2b            /* + */
+#define L1_BRICKTYPE_DAYTONA	0x7a            /* z */
 
 #endif /* _ASM_IA64_SN_L1_H */
diff --git a/include/asm-ia64/sn/mspec.h b/include/asm-ia64/sn/mspec.h
new file mode 100644
--- /dev/null
+++ b/include/asm-ia64/sn/mspec.h
@@ -0,0 +1,59 @@
+/*
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 2001-2004 Silicon Graphics, Inc.  All rights reserved.
+ */
+
+#ifndef _ASM_IA64_SN_MSPEC_H
+#define _ASM_IA64_SN_MSPEC_H
+
+#define FETCHOP_VAR_SIZE 64 /* 64 byte per fetchop variable */
+
+#define FETCHOP_LOAD		0
+#define FETCHOP_INCREMENT	8
+#define FETCHOP_DECREMENT	16
+#define FETCHOP_CLEAR		24
+
+#define FETCHOP_STORE		0
+#define FETCHOP_AND		24
+#define FETCHOP_OR		32
+
+#define FETCHOP_CLEAR_CACHE	56
+
+#define FETCHOP_LOAD_OP(addr, op) ( \
+         *(volatile long *)((char*) (addr) + (op)))
+
+#define FETCHOP_STORE_OP(addr, op, x) ( \
+         *(volatile long *)((char*) (addr) + (op)) = (long) (x))
+
+#ifdef __KERNEL__
+
+/*
+ * Each Atomic Memory Operation (AMO formerly known as fetchop)
+ * variable is 64 bytes long.  The first 8 bytes are used.  The
+ * remaining 56 bytes are unaddressable due to the operation taking
+ * that portion of the address.
+ *
+ * NOTE: The AMO_t _MUST_ be placed in either the first or second half
+ * of the cache line.  The cache line _MUST NOT_ be used for anything
+ * other than additional AMO_t entries.  This is because there are two
+ * addresses which reference the same physical cache line.  One will
+ * be a cached entry with the memory type bits all set.  This address
+ * may be loaded into processor cache.  The AMO_t will be referenced
+ * uncached via the memory special memory type.  If any portion of the
+ * cached cache-line is modified, when that line is flushed, it will
+ * overwrite the uncached value in physical memory and lead to
+ * inconsistency.
+ */
+typedef struct {
+        u64 variable;
+        u64 unused[7];
+} AMO_t;
+
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_IA64_SN_MSPEC_H */
diff --git a/include/asm-ia64/sn/pcibr_provider.h b/include/asm-ia64/sn/pcibr_provider.h
new file mode 100644
--- /dev/null
+++ b/include/asm-ia64/sn/pcibr_provider.h
@@ -0,0 +1,159 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1992-1997,2000-2004 Silicon Graphics, Inc. All rights reserved.
+ */
+#ifndef _ASM_IA64_SN_PCI_PCIBR_PROVIDER_H
+#define _ASM_IA64_SN_PCI_PCIBR_PROVIDER_H
+
+#include <asm/sn/intr.h>
+#include <asm/sn/pcibus_provider_defs.h>
+
+/* Workarounds */
+#define PV907516 (1 << 1) /* TIOCP: Don't write the write buffer flush reg */
+
+#define BUSTYPE_MASK                    0x1
+
+/* Macros given a pcibus structure */
+#define IS_PCIX(ps)     ((ps)->pbi_bridge_mode & BUSTYPE_MASK)
+#define IS_PCI_BRIDGE_ASIC(asic) (asic == PCIIO_ASIC_TYPE_PIC || \
+                asic == PCIIO_ASIC_TYPE_TIOCP)
+#define IS_PIC_SOFT(ps)     (ps->pbi_bridge_type == PCIBR_BRIDGETYPE_PIC)
+
+
+/*
+ * The different PCI Bridge types supported on the SGI Altix platforms
+ */
+#define PCIBR_BRIDGETYPE_UNKNOWN       -1
+#define PCIBR_BRIDGETYPE_PIC            2
+#define PCIBR_BRIDGETYPE_TIOCP          3
+
+/*
+ * Bridge 64bit Direct Map Attributes
+ */
+#define PCI64_ATTR_PREF                 (1ull << 59)
+#define PCI64_ATTR_PREC                 (1ull << 58)
+#define PCI64_ATTR_VIRTUAL              (1ull << 57)
+#define PCI64_ATTR_BAR                  (1ull << 56)
+#define PCI64_ATTR_SWAP                 (1ull << 55)
+#define PCI64_ATTR_VIRTUAL1             (1ull << 54)
+
+#define PCI32_LOCAL_BASE                0
+#define PCI32_MAPPED_BASE               0x40000000
+#define PCI32_DIRECT_BASE               0x80000000
+
+#define IS_PCI32_MAPPED(x)              ((uint64_t)(x) < PCI32_DIRECT_BASE && \
+                                         (uint64_t)(x) >= PCI32_MAPPED_BASE)
+#define IS_PCI32_DIRECT(x)              ((uint64_t)(x) >= PCI32_MAPPED_BASE)
+
+
+/*
+ * Bridge PMU Address Transaltion Entry Attibutes
+ */
+#define PCI32_ATE_V                     (0x1 << 0)
+#define PCI32_ATE_CO                    (0x1 << 1)
+#define PCI32_ATE_PREC                  (0x1 << 2)
+#define PCI32_ATE_PREF                  (0x1 << 3)
+#define PCI32_ATE_BAR                   (0x1 << 4)
+#define PCI32_ATE_ADDR_SHFT             12
+
+#define MINIMAL_ATES_REQUIRED(addr, size) \
+	(IOPG(IOPGOFF(addr) + (size) - 1) == IOPG((size) - 1))
+
+#define MINIMAL_ATE_FLAG(addr, size) \
+	(MINIMAL_ATES_REQUIRED((uint64_t)addr, size) ? 1 : 0)
+
+/* bit 29 of the pci address is the SWAP bit */
+#define ATE_SWAPSHIFT                   29
+#define ATE_SWAP_ON(x)                  ((x) |= (1 << ATE_SWAPSHIFT))
+#define ATE_SWAP_OFF(x)                 ((x) &= ~(1 << ATE_SWAPSHIFT))
+
+/*
+ * I/O page size
+ */
+#if PAGE_SIZE < 16384
+#define IOPFNSHIFT                      12      /* 4K per mapped page */
+#else
+#define IOPFNSHIFT                      14      /* 16K per mapped page */
+#endif
+
+#define IOPGSIZE                        (1 << IOPFNSHIFT)
+#define IOPG(x)                         ((x) >> IOPFNSHIFT)
+#define IOPGOFF(x)                      ((x) & (IOPGSIZE-1))
+
+#define PCIBR_DEV_SWAP_DIR              (1ull << 19)
+#define PCIBR_CTRL_PAGE_SIZE            (0x1 << 21)
+
+/*
+ * PMU resources.
+ */
+struct ate_resource{
+	uint64_t *ate;
+	uint64_t num_ate;
+	uint64_t lowest_free_index;
+};
+
+struct pcibus_info {
+	struct pcibus_bussoft	pbi_buscommon;   /* common header */
+	uint32_t                pbi_moduleid;
+	short                   pbi_bridge_type;
+	short                   pbi_bridge_mode;
+
+	struct ate_resource     pbi_int_ate_resource;
+	uint64_t                pbi_int_ate_size;
+
+	uint64_t                pbi_dir_xbase;
+	char                    pbi_hub_xid;
+
+	uint64_t                pbi_devreg[8];
+
+	uint32_t		pbi_valid_devices;
+	uint32_t		pbi_enabled_devices;
+
+	spinlock_t              pbi_lock;
+};
+
+/*
+ * pcibus_info structure locking macros
+ */
+inline static unsigned long
+pcibr_lock(struct pcibus_info *pcibus_info)
+{
+	unsigned long flag;
+	spin_lock_irqsave(&pcibus_info->pbi_lock, flag);
+	return(flag);
+}
+#define pcibr_unlock(pcibus_info, flag)  spin_unlock_irqrestore(&pcibus_info->pbi_lock, flag)
+
+extern int  pcibr_init_provider(void);
+extern void *pcibr_bus_fixup(struct pcibus_bussoft *, struct pci_controller *);
+extern dma_addr_t pcibr_dma_map(struct pci_dev *, unsigned long, size_t);
+extern dma_addr_t pcibr_dma_map_consistent(struct pci_dev *, unsigned long, size_t);
+extern void pcibr_dma_unmap(struct pci_dev *, dma_addr_t, int);
+
+/*
+ * prototypes for the bridge asic register access routines in pcibr_reg.c
+ */
+extern void             pcireg_control_bit_clr(struct pcibus_info *, uint64_t);
+extern void             pcireg_control_bit_set(struct pcibus_info *, uint64_t);
+extern uint64_t         pcireg_tflush_get(struct pcibus_info *);
+extern uint64_t         pcireg_intr_status_get(struct pcibus_info *);
+extern void             pcireg_intr_enable_bit_clr(struct pcibus_info *, uint64_t);
+extern void             pcireg_intr_enable_bit_set(struct pcibus_info *, uint64_t);
+extern void             pcireg_intr_addr_addr_set(struct pcibus_info *, int, uint64_t);
+extern void             pcireg_force_intr_set(struct pcibus_info *, int);
+extern uint64_t         pcireg_wrb_flush_get(struct pcibus_info *, int);
+extern void             pcireg_int_ate_set(struct pcibus_info *, int, uint64_t);
+extern uint64_t *	pcireg_int_ate_addr(struct pcibus_info *, int);
+extern void 		pcibr_force_interrupt(struct sn_irq_info *sn_irq_info);
+extern void 		pcibr_change_devices_irq(struct sn_irq_info *sn_irq_info);
+extern int 		pcibr_ate_alloc(struct pcibus_info *, int);
+extern void 		pcibr_ate_free(struct pcibus_info *, int);
+extern void 		ate_write(struct pcibus_info *, int, int, uint64_t);
+extern int sal_pcibr_slot_enable(struct pcibus_info *soft, int device,
+				 void *resp);
+extern int sal_pcibr_slot_disable(struct pcibus_info *soft, int device,
+				  int action, void *resp);
+#endif
diff --git a/include/asm-ia64/sn/pcibus_provider_defs.h b/include/asm-ia64/sn/pcibus_provider_defs.h
--- a/include/asm-ia64/sn/pcibus_provider_defs.h
+++ b/include/asm-ia64/sn/pcibus_provider_defs.h
@@ -37,6 +37,7 @@ struct pcibus_bussoft {
 	struct xwidget_info	*bs_xwidget_info;
 };
 
+struct pci_controller;
 /*
  * SN pci bus indirection
  */
@@ -45,7 +46,7 @@ struct sn_pcibus_provider {
 	dma_addr_t	(*dma_map)(struct pci_dev *, unsigned long, size_t);
 	dma_addr_t	(*dma_map_consistent)(struct pci_dev *, unsigned long, size_t);
 	void		(*dma_unmap)(struct pci_dev *, dma_addr_t, int);
-	void *		(*bus_fixup)(struct pcibus_bussoft *);
+	void *		(*bus_fixup)(struct pcibus_bussoft *, struct pci_controller *);
 };
 
 extern struct sn_pcibus_provider *sn_pci_provider[];
diff --git a/include/asm-ia64/sn/pcidev.h b/include/asm-ia64/sn/pcidev.h
--- a/include/asm-ia64/sn/pcidev.h
+++ b/include/asm-ia64/sn/pcidev.h
@@ -10,11 +10,11 @@
 
 #include <linux/pci.h>
 
-extern struct sn_irq_info **sn_irq;
-
 #define SN_PCIDEV_INFO(pci_dev) \
         ((struct pcidev_info *)(pci_dev)->sysdata)
 
+#define SN_PCIBUS_BUSSOFT_INFO(pci_bus) \
+	(struct pcibus_info *)((struct pcibus_bussoft *)(PCI_CONTROLLER((pci_bus))->platform_data))
 /*
  * Given a pci_bus, return the sn pcibus_bussoft struct.  Note that
  * this only works for root busses, not for busses represented by PPB's.
@@ -23,6 +23,8 @@ extern struct sn_irq_info **sn_irq;
 #define SN_PCIBUS_BUSSOFT(pci_bus) \
         ((struct pcibus_bussoft *)(PCI_CONTROLLER((pci_bus))->platform_data))
 
+#define SN_PCIBUS_BUSSOFT_INFO(pci_bus) \
+	(struct pcibus_info *)((struct pcibus_bussoft *)(PCI_CONTROLLER((pci_bus))->platform_data))
 /*
  * Given a struct pci_dev, return the sn pcibus_bussoft struct.  Note
  * that this is not equivalent to SN_PCIBUS_BUSSOFT(pci_dev->bus) due
@@ -50,9 +52,17 @@ struct pcidev_info {
 
 	struct sn_irq_info	*pdi_sn_irq_info;
 	struct sn_pcibus_provider *pdi_provider;	/* sn pci ops */
+	struct pci_dev 		*host_pci_dev;		/* host bus link */
 };
 
 extern void sn_irq_fixup(struct pci_dev *pci_dev,
 			 struct sn_irq_info *sn_irq_info);
-
+extern void sn_irq_unfixup(struct pci_dev *pci_dev);
+extern void sn_pci_controller_fixup(int segment, int busnum,
+ 				    struct pci_bus *bus);
+extern void sn_bus_store_sysdata(struct pci_dev *dev);
+extern void sn_bus_free_sysdata(void);
+extern void sn_pci_fixup_slot(struct pci_dev *dev);
+extern void sn_pci_unfixup_slot(struct pci_dev *dev);
+extern void sn_irq_lh_init(void);
 #endif				/* _ASM_IA64_SN_PCI_PCIDEV_H */
diff --git a/include/asm-ia64/sn/pic.h b/include/asm-ia64/sn/pic.h
new file mode 100644
--- /dev/null
+++ b/include/asm-ia64/sn/pic.h
@@ -0,0 +1,261 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
+ */
+#ifndef _ASM_IA64_SN_PCI_PIC_H
+#define _ASM_IA64_SN_PCI_PIC_H
+
+/*
+ * PIC AS DEVICE ZERO
+ * ------------------
+ *
+ * PIC handles PCI/X busses.  PCI/X requires that the 'bridge' (i.e. PIC)
+ * be designated as 'device 0'.   That is a departure from earlier SGI
+ * PCI bridges.  Because of that we use config space 1 to access the
+ * config space of the first actual PCI device on the bus.
+ * Here's what the PIC manual says:
+ *
+ *     The current PCI-X bus specification now defines that the parent
+ *     hosts bus bridge (PIC for example) must be device 0 on bus 0. PIC
+ *     reduced the total number of devices from 8 to 4 and removed the
+ *     device registers and windows, now only supporting devices 0,1,2, and
+ *     3. PIC did leave all 8 configuration space windows. The reason was
+ *     there was nothing to gain by removing them. Here in lies the problem.
+ *     The device numbering we do using 0 through 3 is unrelated to the device
+ *     numbering which PCI-X requires in configuration space. In the past we
+ *     correlated Configs pace and our device space 0 <-> 0, 1 <-> 1, etc.
+ *     PCI-X requires we start a 1, not 0 and currently the PX brick
+ *     does associate our:
+ *
+ *         device 0 with configuration space window 1,
+ *         device 1 with configuration space window 2,
+ *         device 2 with configuration space window 3,
+ *         device 3 with configuration space window 4.
+ *
+ * The net effect is that all config space access are off-by-one with
+ * relation to other per-slot accesses on the PIC.
+ * Here is a table that shows some of that:
+ *
+ *                               Internal Slot#
+ *           |
+ *           |     0         1        2         3
+ * ----------|---------------------------------------
+ * config    |  0x21000   0x22000  0x23000   0x24000
+ *           |
+ * even rrb  |  0[0]      n/a      1[0]      n/a	[] == implied even/odd
+ *           |
+ * odd rrb   |  n/a       0[1]     n/a       1[1]
+ *           |
+ * int dev   |  00       01        10        11
+ *           |
+ * ext slot# |  1        2         3         4
+ * ----------|---------------------------------------
+ */
+
+#define PIC_ATE_TARGETID_SHFT           8
+#define PIC_HOST_INTR_ADDR              0x0000FFFFFFFFFFFFUL
+#define PIC_PCI64_ATTR_TARG_SHFT        60
+
+
+/*****************************************************************************
+ *********************** PIC MMR structure mapping ***************************
+ *****************************************************************************/
+
+/* NOTE: PIC WAR. PV#854697.  PIC does not allow writes just to [31:0]
+ * of a 64-bit register.  When writing PIC registers, always write the
+ * entire 64 bits.
+ */
+
+struct pic {
+
+    /* 0x000000-0x00FFFF -- Local Registers */
+
+    /* 0x000000-0x000057 -- Standard Widget Configuration */
+    uint64_t		p_wid_id;			/* 0x000000 */
+    uint64_t		p_wid_stat;			/* 0x000008 */
+    uint64_t		p_wid_err_upper;		/* 0x000010 */
+    uint64_t		p_wid_err_lower;		/* 0x000018 */
+    #define p_wid_err p_wid_err_lower
+    uint64_t		p_wid_control;			/* 0x000020 */
+    uint64_t		p_wid_req_timeout;		/* 0x000028 */
+    uint64_t		p_wid_int_upper;		/* 0x000030 */
+    uint64_t		p_wid_int_lower;		/* 0x000038 */
+    #define p_wid_int p_wid_int_lower
+    uint64_t		p_wid_err_cmdword;		/* 0x000040 */
+    uint64_t		p_wid_llp;			/* 0x000048 */
+    uint64_t		p_wid_tflush;			/* 0x000050 */
+
+    /* 0x000058-0x00007F -- Bridge-specific Widget Configuration */
+    uint64_t		p_wid_aux_err;			/* 0x000058 */
+    uint64_t		p_wid_resp_upper;		/* 0x000060 */
+    uint64_t		p_wid_resp_lower;		/* 0x000068 */
+    #define p_wid_resp p_wid_resp_lower
+    uint64_t		p_wid_tst_pin_ctrl;		/* 0x000070 */
+    uint64_t		p_wid_addr_lkerr;		/* 0x000078 */
+
+    /* 0x000080-0x00008F -- PMU & MAP */
+    uint64_t		p_dir_map;			/* 0x000080 */
+    uint64_t		_pad_000088;			/* 0x000088 */
+
+    /* 0x000090-0x00009F -- SSRAM */
+    uint64_t		p_map_fault;			/* 0x000090 */
+    uint64_t		_pad_000098;			/* 0x000098 */
+
+    /* 0x0000A0-0x0000AF -- Arbitration */
+    uint64_t		p_arb;				/* 0x0000A0 */
+    uint64_t		_pad_0000A8;			/* 0x0000A8 */
+
+    /* 0x0000B0-0x0000BF -- Number In A Can or ATE Parity Error */
+    uint64_t		p_ate_parity_err;		/* 0x0000B0 */
+    uint64_t		_pad_0000B8;			/* 0x0000B8 */
+
+    /* 0x0000C0-0x0000FF -- PCI/GIO */
+    uint64_t		p_bus_timeout;			/* 0x0000C0 */
+    uint64_t		p_pci_cfg;			/* 0x0000C8 */
+    uint64_t		p_pci_err_upper;		/* 0x0000D0 */
+    uint64_t		p_pci_err_lower;		/* 0x0000D8 */
+    #define p_pci_err p_pci_err_lower
+    uint64_t		_pad_0000E0[4];			/* 0x0000{E0..F8} */
+
+    /* 0x000100-0x0001FF -- Interrupt */
+    uint64_t		p_int_status;			/* 0x000100 */
+    uint64_t		p_int_enable;			/* 0x000108 */
+    uint64_t		p_int_rst_stat;			/* 0x000110 */
+    uint64_t		p_int_mode;			/* 0x000118 */
+    uint64_t		p_int_device;			/* 0x000120 */
+    uint64_t		p_int_host_err;			/* 0x000128 */
+    uint64_t		p_int_addr[8];			/* 0x0001{30,,,68} */
+    uint64_t		p_err_int_view;			/* 0x000170 */
+    uint64_t		p_mult_int;			/* 0x000178 */
+    uint64_t		p_force_always[8];		/* 0x0001{80,,,B8} */
+    uint64_t		p_force_pin[8];			/* 0x0001{C0,,,F8} */
+
+    /* 0x000200-0x000298 -- Device */
+    uint64_t		p_device[4];			/* 0x0002{00,,,18} */
+    uint64_t		_pad_000220[4];			/* 0x0002{20,,,38} */
+    uint64_t		p_wr_req_buf[4];		/* 0x0002{40,,,58} */
+    uint64_t		_pad_000260[4];			/* 0x0002{60,,,78} */
+    uint64_t		p_rrb_map[2];			/* 0x0002{80,,,88} */
+    #define p_even_resp p_rrb_map[0]			/* 0x000280 */
+    #define p_odd_resp  p_rrb_map[1]			/* 0x000288 */
+    uint64_t		p_resp_status;			/* 0x000290 */
+    uint64_t		p_resp_clear;			/* 0x000298 */
+
+    uint64_t		_pad_0002A0[12];		/* 0x0002{A0..F8} */
+
+    /* 0x000300-0x0003F8 -- Buffer Address Match Registers */
+    struct {
+	uint64_t	upper;				/* 0x0003{00,,,F0} */
+	uint64_t	lower;				/* 0x0003{08,,,F8} */
+    } p_buf_addr_match[16];
+
+    /* 0x000400-0x0005FF -- Performance Monitor Registers (even only) */
+    struct {
+	uint64_t	flush_w_touch;			/* 0x000{400,,,5C0} */
+	uint64_t	flush_wo_touch;			/* 0x000{408,,,5C8} */
+	uint64_t	inflight;			/* 0x000{410,,,5D0} */
+	uint64_t	prefetch;			/* 0x000{418,,,5D8} */
+	uint64_t	total_pci_retry;		/* 0x000{420,,,5E0} */
+	uint64_t	max_pci_retry;			/* 0x000{428,,,5E8} */
+	uint64_t	max_latency;			/* 0x000{430,,,5F0} */
+	uint64_t	clear_all;			/* 0x000{438,,,5F8} */
+    } p_buf_count[8];
+
+
+    /* 0x000600-0x0009FF -- PCI/X registers */
+    uint64_t		p_pcix_bus_err_addr;		/* 0x000600 */
+    uint64_t		p_pcix_bus_err_attr;		/* 0x000608 */
+    uint64_t		p_pcix_bus_err_data;		/* 0x000610 */
+    uint64_t		p_pcix_pio_split_addr;		/* 0x000618 */
+    uint64_t		p_pcix_pio_split_attr;		/* 0x000620 */
+    uint64_t		p_pcix_dma_req_err_attr;	/* 0x000628 */
+    uint64_t		p_pcix_dma_req_err_addr;	/* 0x000630 */
+    uint64_t		p_pcix_timeout;			/* 0x000638 */
+
+    uint64_t		_pad_000640[120];		/* 0x000{640,,,9F8} */
+
+    /* 0x000A00-0x000BFF -- PCI/X Read&Write Buffer */
+    struct {
+	uint64_t	p_buf_addr;			/* 0x000{A00,,,AF0} */
+	uint64_t	p_buf_attr;			/* 0X000{A08,,,AF8} */
+    } p_pcix_read_buf_64[16];
+
+    struct {
+	uint64_t	p_buf_addr;			/* 0x000{B00,,,BE0} */
+	uint64_t	p_buf_attr;			/* 0x000{B08,,,BE8} */
+	uint64_t	p_buf_valid;			/* 0x000{B10,,,BF0} */
+	uint64_t	__pad1;				/* 0x000{B18,,,BF8} */
+    } p_pcix_write_buf_64[8];
+
+    /* End of Local Registers -- Start of Address Map space */
+
+    char		_pad_000c00[0x010000 - 0x000c00];
+
+    /* 0x010000-0x011fff -- Internal ATE RAM (Auto Parity Generation) */
+    uint64_t		p_int_ate_ram[1024];		/* 0x010000-0x011fff */
+
+    /* 0x012000-0x013fff -- Internal ATE RAM (Manual Parity Generation) */
+    uint64_t		p_int_ate_ram_mp[1024];		/* 0x012000-0x013fff */
+
+    char		_pad_014000[0x18000 - 0x014000];
+
+    /* 0x18000-0x197F8 -- PIC Write Request Ram */
+    uint64_t		p_wr_req_lower[256];		/* 0x18000 - 0x187F8 */
+    uint64_t		p_wr_req_upper[256];		/* 0x18800 - 0x18FF8 */
+    uint64_t		p_wr_req_parity[256];		/* 0x19000 - 0x197F8 */
+
+    char		_pad_019800[0x20000 - 0x019800];
+
+    /* 0x020000-0x027FFF -- PCI Device Configuration Spaces */
+    union {
+	uint8_t		c[0x1000 / 1];			/* 0x02{0000,,,7FFF} */
+	uint16_t	s[0x1000 / 2];			/* 0x02{0000,,,7FFF} */
+	uint32_t	l[0x1000 / 4];			/* 0x02{0000,,,7FFF} */
+	uint64_t	d[0x1000 / 8];			/* 0x02{0000,,,7FFF} */
+	union {
+	    uint8_t	c[0x100 / 1];
+	    uint16_t	s[0x100 / 2];
+	    uint32_t	l[0x100 / 4];
+	    uint64_t	d[0x100 / 8];
+	} f[8];
+    } p_type0_cfg_dev[8];				/* 0x02{0000,,,7FFF} */
+
+    /* 0x028000-0x028FFF -- PCI Type 1 Configuration Space */
+    union {
+	uint8_t		c[0x1000 / 1];			/* 0x028000-0x029000 */
+	uint16_t	s[0x1000 / 2];			/* 0x028000-0x029000 */
+	uint32_t	l[0x1000 / 4];			/* 0x028000-0x029000 */
+	uint64_t	d[0x1000 / 8];			/* 0x028000-0x029000 */
+	union {
+	    uint8_t	c[0x100 / 1];
+	    uint16_t	s[0x100 / 2];
+	    uint32_t	l[0x100 / 4];
+	    uint64_t	d[0x100 / 8];
+	} f[8];
+    } p_type1_cfg;					/* 0x028000-0x029000 */
+
+    char		_pad_029000[0x030000-0x029000];
+
+    /* 0x030000-0x030007 -- PCI Interrupt Acknowledge Cycle */
+    union {
+	uint8_t		c[8 / 1];
+	uint16_t	s[8 / 2];
+	uint32_t	l[8 / 4];
+	uint64_t	d[8 / 8];
+    } p_pci_iack;					/* 0x030000-0x030007 */
+
+    char		_pad_030007[0x040000-0x030008];
+
+    /* 0x040000-0x030007 -- PCIX Special Cycle */
+    union {
+	uint8_t		c[8 / 1];
+	uint16_t	s[8 / 2];
+	uint32_t	l[8 / 4];
+	uint64_t	d[8 / 8];
+    } p_pcix_cycle;					/* 0x040000-0x040007 */
+};
+
+#endif                          /* _ASM_IA64_SN_PCI_PIC_H */
diff --git a/include/asm-ia64/sn/shub_mmr.h b/include/asm-ia64/sn/shub_mmr.h
--- a/include/asm-ia64/sn/shub_mmr.h
+++ b/include/asm-ia64/sn/shub_mmr.h
@@ -14,96 +14,98 @@
 /*                        Register "SH_IPI_INT"                         */
 /*               SHub Inter-Processor Interrupt Registers               */
 /* ==================================================================== */
-#define SH1_IPI_INT                               0x0000000110000380
-#define SH2_IPI_INT                               0x0000000010000380
+#define SH1_IPI_INT			__IA64_UL_CONST(0x0000000110000380)
+#define SH2_IPI_INT			__IA64_UL_CONST(0x0000000010000380)
 
 /*   SH_IPI_INT_TYPE                                                    */
 /*   Description:  Type of Interrupt: 0=INT, 2=PMI, 4=NMI, 5=INIT       */
-#define SH_IPI_INT_TYPE_SHFT                     0
-#define SH_IPI_INT_TYPE_MASK                     0x0000000000000007
+#define SH_IPI_INT_TYPE_SHFT				0
+#define SH_IPI_INT_TYPE_MASK		__IA64_UL_CONST(0x0000000000000007)
 
 /*   SH_IPI_INT_AGT                                                     */
 /*   Description:  Agent, must be 0 for SHub                            */
-#define SH_IPI_INT_AGT_SHFT                      3
-#define SH_IPI_INT_AGT_MASK                      0x0000000000000008
+#define SH_IPI_INT_AGT_SHFT				3
+#define SH_IPI_INT_AGT_MASK		__IA64_UL_CONST(0x0000000000000008)
 
 /*   SH_IPI_INT_PID                                                     */
 /*   Description:  Processor ID, same setting as on targeted McKinley  */
-#define SH_IPI_INT_PID_SHFT                      4
-#define SH_IPI_INT_PID_MASK                      0x00000000000ffff0
+#define SH_IPI_INT_PID_SHFT                      	4
+#define SH_IPI_INT_PID_MASK		__IA64_UL_CONST(0x00000000000ffff0)
 
 /*   SH_IPI_INT_BASE                                                    */
 /*   Description:  Optional interrupt vector area, 2MB aligned          */
-#define SH_IPI_INT_BASE_SHFT                     21
-#define SH_IPI_INT_BASE_MASK                     0x0003ffffffe00000
+#define SH_IPI_INT_BASE_SHFT				21
+#define SH_IPI_INT_BASE_MASK 		__IA64_UL_CONST(0x0003ffffffe00000)
 
 /*   SH_IPI_INT_IDX                                                     */
 /*   Description:  Targeted McKinley interrupt vector                   */
-#define SH_IPI_INT_IDX_SHFT                      52
-#define SH_IPI_INT_IDX_MASK                      0x0ff0000000000000
+#define SH_IPI_INT_IDX_SHFT				52
+#define SH_IPI_INT_IDX_MASK		__IA64_UL_CONST(0x0ff0000000000000)
 
 /*   SH_IPI_INT_SEND                                                    */
 /*   Description:  Send Interrupt Message to PI, This generates a puls  */
-#define SH_IPI_INT_SEND_SHFT                     63
-#define SH_IPI_INT_SEND_MASK                     0x8000000000000000
+#define SH_IPI_INT_SEND_SHFT				63
+#define SH_IPI_INT_SEND_MASK		__IA64_UL_CONST(0x8000000000000000)
 
 /* ==================================================================== */
 /*                     Register "SH_EVENT_OCCURRED"                     */
 /*                    SHub Interrupt Event Occurred                     */
 /* ==================================================================== */
-#define SH1_EVENT_OCCURRED                        0x0000000110010000
-#define SH1_EVENT_OCCURRED_ALIAS                  0x0000000110010008
-#define SH2_EVENT_OCCURRED                        0x0000000010010000
-#define SH2_EVENT_OCCURRED_ALIAS                  0x0000000010010008
+#define SH1_EVENT_OCCURRED		__IA64_UL_CONST(0x0000000110010000)
+#define SH1_EVENT_OCCURRED_ALIAS	__IA64_UL_CONST(0x0000000110010008)
+#define SH2_EVENT_OCCURRED		__IA64_UL_CONST(0x0000000010010000)
+#define SH2_EVENT_OCCURRED_ALIAS 	__IA64_UL_CONST(0x0000000010010008)
 
 /* ==================================================================== */
 /*                     Register "SH_PI_CAM_CONTROL"                     */
 /*                      CRB CAM MMR Access Control                      */
 /* ==================================================================== */
-#define SH1_PI_CAM_CONTROL                        0x0000000120050300
+#define SH1_PI_CAM_CONTROL		__IA64_UL_CONST(0x0000000120050300)
 
 /* ==================================================================== */
 /*                        Register "SH_SHUB_ID"                         */
 /*                            SHub ID Number                            */
 /* ==================================================================== */
-#define SH1_SHUB_ID                               0x0000000110060580
-#define SH1_SHUB_ID_REVISION_SHFT                 28
-#define SH1_SHUB_ID_REVISION_MASK                 0x00000000f0000000
+#define SH1_SHUB_ID			__IA64_UL_CONST(0x0000000110060580)
+#define SH1_SHUB_ID_REVISION_SHFT			28
+#define SH1_SHUB_ID_REVISION_MASK	__IA64_UL_CONST(0x00000000f0000000)
 
 /* ==================================================================== */
 /*                          Register "SH_RTC"                           */
 /*                           Real-time Clock                            */
 /* ==================================================================== */
-#define SH1_RTC                                   0x00000001101c0000
-#define SH2_RTC					  0x00000002101c0000
-#define SH_RTC_MASK                               0x007fffffffffffff
+#define SH1_RTC				__IA64_UL_CONST(0x00000001101c0000)
+#define SH2_RTC				__IA64_UL_CONST(0x00000002101c0000)
+#define SH_RTC_MASK			__IA64_UL_CONST(0x007fffffffffffff)
 
 /* ==================================================================== */
 /*                   Register "SH_PIO_WRITE_STATUS_0|1"                 */
 /*                      PIO Write Status for CPU 0 & 1                  */
 /* ==================================================================== */
-#define SH1_PIO_WRITE_STATUS_0                    0x0000000120070200
-#define SH1_PIO_WRITE_STATUS_1                    0x0000000120070280
-#define SH2_PIO_WRITE_STATUS_0                    0x0000000020070200
-#define SH2_PIO_WRITE_STATUS_1                    0x0000000020070280
-#define SH2_PIO_WRITE_STATUS_2                    0x0000000020070300
-#define SH2_PIO_WRITE_STATUS_3                    0x0000000020070380
+#define SH1_PIO_WRITE_STATUS_0		__IA64_UL_CONST(0x0000000120070200)
+#define SH1_PIO_WRITE_STATUS_1		__IA64_UL_CONST(0x0000000120070280)
+#define SH2_PIO_WRITE_STATUS_0		__IA64_UL_CONST(0x0000000020070200)
+#define SH2_PIO_WRITE_STATUS_1		__IA64_UL_CONST(0x0000000020070280)
+#define SH2_PIO_WRITE_STATUS_2		__IA64_UL_CONST(0x0000000020070300)
+#define SH2_PIO_WRITE_STATUS_3		__IA64_UL_CONST(0x0000000020070380)
 
 /*   SH_PIO_WRITE_STATUS_0_WRITE_DEADLOCK                               */
 /*   Description:  Deadlock response detected                           */
-#define SH_PIO_WRITE_STATUS_WRITE_DEADLOCK_SHFT 1
-#define SH_PIO_WRITE_STATUS_WRITE_DEADLOCK_MASK 0x0000000000000002
+#define SH_PIO_WRITE_STATUS_WRITE_DEADLOCK_SHFT		1
+#define SH_PIO_WRITE_STATUS_WRITE_DEADLOCK_MASK \
+					__IA64_UL_CONST(0x0000000000000002)
 
 /*   SH_PIO_WRITE_STATUS_0_PENDING_WRITE_COUNT                          */
 /*   Description:  Count of currently pending PIO writes                */
-#define SH_PIO_WRITE_STATUS_PENDING_WRITE_COUNT_SHFT 56
-#define SH_PIO_WRITE_STATUS_PENDING_WRITE_COUNT_MASK 0x3f00000000000000
+#define SH_PIO_WRITE_STATUS_PENDING_WRITE_COUNT_SHFT	56
+#define SH_PIO_WRITE_STATUS_PENDING_WRITE_COUNT_MASK \
+					__IA64_UL_CONST(0x3f00000000000000)
 
 /* ==================================================================== */
 /*                Register "SH_PIO_WRITE_STATUS_0_ALIAS"                */
 /* ==================================================================== */
-#define SH1_PIO_WRITE_STATUS_0_ALIAS              0x0000000120070208
-#define SH2_PIO_WRITE_STATUS_0_ALIAS              0x0000000020070208
+#define SH1_PIO_WRITE_STATUS_0_ALIAS	__IA64_UL_CONST(0x0000000120070208)
+#define SH2_PIO_WRITE_STATUS_0_ALIAS	__IA64_UL_CONST(0x0000000020070208)
 
 /* ==================================================================== */
 /*                     Register "SH_EVENT_OCCURRED"                     */
@@ -111,33 +113,33 @@
 /* ==================================================================== */
 /*   SH_EVENT_OCCURRED_UART_INT                                         */
 /*   Description:  Pending Junk Bus UART Interrupt                      */
-#define SH_EVENT_OCCURRED_UART_INT_SHFT          20
-#define SH_EVENT_OCCURRED_UART_INT_MASK          0x0000000000100000
+#define SH_EVENT_OCCURRED_UART_INT_SHFT			20
+#define SH_EVENT_OCCURRED_UART_INT_MASK	__IA64_UL_CONST(0x0000000000100000)
 
 /*   SH_EVENT_OCCURRED_IPI_INT                                          */
 /*   Description:  Pending IPI Interrupt                                */
-#define SH_EVENT_OCCURRED_IPI_INT_SHFT           28
-#define SH_EVENT_OCCURRED_IPI_INT_MASK           0x0000000010000000
+#define SH_EVENT_OCCURRED_IPI_INT_SHFT			28
+#define SH_EVENT_OCCURRED_IPI_INT_MASK	__IA64_UL_CONST(0x0000000010000000)
 
 /*   SH_EVENT_OCCURRED_II_INT0                                          */
 /*   Description:  Pending II 0 Interrupt                               */
-#define SH_EVENT_OCCURRED_II_INT0_SHFT           29
-#define SH_EVENT_OCCURRED_II_INT0_MASK           0x0000000020000000
+#define SH_EVENT_OCCURRED_II_INT0_SHFT			29
+#define SH_EVENT_OCCURRED_II_INT0_MASK	__IA64_UL_CONST(0x0000000020000000)
 
 /*   SH_EVENT_OCCURRED_II_INT1                                          */
 /*   Description:  Pending II 1 Interrupt                               */
-#define SH_EVENT_OCCURRED_II_INT1_SHFT           30
-#define SH_EVENT_OCCURRED_II_INT1_MASK           0x0000000040000000
+#define SH_EVENT_OCCURRED_II_INT1_SHFT			30
+#define SH_EVENT_OCCURRED_II_INT1_MASK	__IA64_UL_CONST(0x0000000040000000)
 
 /*   SH2_EVENT_OCCURRED_EXTIO_INT2                                      */
 /*   Description:  Pending SHUB 2 EXT IO INT2                           */
-#define SH2_EVENT_OCCURRED_EXTIO_INT2_SHFT       33
-#define SH2_EVENT_OCCURRED_EXTIO_INT2_MASK       0x0000000200000000
+#define SH2_EVENT_OCCURRED_EXTIO_INT2_SHFT		33
+#define SH2_EVENT_OCCURRED_EXTIO_INT2_MASK __IA64_UL_CONST(0x0000000200000000)
 
 /*   SH2_EVENT_OCCURRED_EXTIO_INT3                                      */
 /*   Description:  Pending SHUB 2 EXT IO INT3                           */
-#define SH2_EVENT_OCCURRED_EXTIO_INT3_SHFT       34
-#define SH2_EVENT_OCCURRED_EXTIO_INT3_MASK       0x0000000400000000
+#define SH2_EVENT_OCCURRED_EXTIO_INT3_SHFT		34
+#define SH2_EVENT_OCCURRED_EXTIO_INT3_MASK __IA64_UL_CONST(0x0000000400000000)
 
 #define SH_ALL_INT_MASK \
 	(SH_EVENT_OCCURRED_UART_INT_MASK | SH_EVENT_OCCURRED_IPI_INT_MASK | \
@@ -149,310 +151,310 @@
 /* ==================================================================== */
 /*                         LEDS                                         */
 /* ==================================================================== */
-#define SH1_REAL_JUNK_BUS_LED0			 0x7fed00000UL
-#define SH1_REAL_JUNK_BUS_LED1			 0x7fed10000UL
-#define SH1_REAL_JUNK_BUS_LED2			 0x7fed20000UL
-#define SH1_REAL_JUNK_BUS_LED3			 0x7fed30000UL
-
-#define SH2_REAL_JUNK_BUS_LED0			 0xf0000000UL
-#define SH2_REAL_JUNK_BUS_LED1			 0xf0010000UL
-#define SH2_REAL_JUNK_BUS_LED2			 0xf0020000UL
-#define SH2_REAL_JUNK_BUS_LED3			 0xf0030000UL
+#define SH1_REAL_JUNK_BUS_LED0			0x7fed00000UL
+#define SH1_REAL_JUNK_BUS_LED1			0x7fed10000UL
+#define SH1_REAL_JUNK_BUS_LED2			0x7fed20000UL
+#define SH1_REAL_JUNK_BUS_LED3			0x7fed30000UL
+
+#define SH2_REAL_JUNK_BUS_LED0			0xf0000000UL
+#define SH2_REAL_JUNK_BUS_LED1			0xf0010000UL
+#define SH2_REAL_JUNK_BUS_LED2			0xf0020000UL
+#define SH2_REAL_JUNK_BUS_LED3			0xf0030000UL
 
 /* ==================================================================== */
 /*                         Register "SH1_PTC_0"                         */
 /*       Puge Translation Cache Message Configuration Information       */
 /* ==================================================================== */
-#define SH1_PTC_0                                 0x00000001101a0000
+#define SH1_PTC_0			__IA64_UL_CONST(0x00000001101a0000)
 
 /*   SH1_PTC_0_A                                                        */
 /*   Description:  Type                                                 */
-#define SH1_PTC_0_A_SHFT                          0
+#define SH1_PTC_0_A_SHFT				0
 
 /*   SH1_PTC_0_PS                                                       */
 /*   Description:  Page Size                                            */
-#define SH1_PTC_0_PS_SHFT                         2
+#define SH1_PTC_0_PS_SHFT				2
 
 /*   SH1_PTC_0_RID                                                      */
 /*   Description:  Region ID                                            */
-#define SH1_PTC_0_RID_SHFT                        8
+#define SH1_PTC_0_RID_SHFT				8
 
 /*   SH1_PTC_0_START                                                    */
 /*   Description:  Start                                                */
-#define SH1_PTC_0_START_SHFT                      63
+#define SH1_PTC_0_START_SHFT				63
 
 /* ==================================================================== */
 /*                         Register "SH1_PTC_1"                         */
 /*       Puge Translation Cache Message Configuration Information       */
 /* ==================================================================== */
-#define SH1_PTC_1                                 0x00000001101a0080
+#define SH1_PTC_1			__IA64_UL_CONST(0x00000001101a0080)
 
 /*   SH1_PTC_1_START                                                    */
 /*   Description:  PTC_1 Start                                          */
-#define SH1_PTC_1_START_SHFT                      63
-
+#define SH1_PTC_1_START_SHFT				63
 
 /* ==================================================================== */
 /*                         Register "SH2_PTC"                           */
 /*       Puge Translation Cache Message Configuration Information       */
 /* ==================================================================== */
-#define SH2_PTC                                   0x0000000170000000
+#define SH2_PTC				__IA64_UL_CONST(0x0000000170000000)
 
 /*   SH2_PTC_A                                                          */
 /*   Description:  Type                                                 */
-#define SH2_PTC_A_SHFT                            0
+#define SH2_PTC_A_SHFT					0
 
 /*   SH2_PTC_PS                                                         */
 /*   Description:  Page Size                                            */
-#define SH2_PTC_PS_SHFT                           2
+#define SH2_PTC_PS_SHFT					2
 
 /*   SH2_PTC_RID                                                      */
 /*   Description:  Region ID                                            */
-#define SH2_PTC_RID_SHFT                          4
+#define SH2_PTC_RID_SHFT				4
 
 /*   SH2_PTC_START                                                      */
 /*   Description:  Start                                                */
-#define SH2_PTC_START_SHFT                        63
+#define SH2_PTC_START_SHFT				63
 
 /*   SH2_PTC_ADDR_RID                                                   */
 /*   Description:  Region ID                                            */
-#define SH2_PTC_ADDR_SHFT                         4
-#define SH2_PTC_ADDR_MASK                         0x1ffffffffffff000
+#define SH2_PTC_ADDR_SHFT				4
+#define SH2_PTC_ADDR_MASK		__IA64_UL_CONST(0x1ffffffffffff000)
 
 /* ==================================================================== */
 /*                    Register "SH_RTC1_INT_CONFIG"                     */
 /*                SHub RTC 1 Interrupt Config Registers                 */
 /* ==================================================================== */
 
-#define SH1_RTC1_INT_CONFIG                      0x0000000110001480
-#define SH2_RTC1_INT_CONFIG                      0x0000000010001480
-#define SH_RTC1_INT_CONFIG_MASK                  0x0ff3ffffffefffff
-#define SH_RTC1_INT_CONFIG_INIT                  0x0000000000000000
+#define SH1_RTC1_INT_CONFIG		__IA64_UL_CONST(0x0000000110001480)
+#define SH2_RTC1_INT_CONFIG		__IA64_UL_CONST(0x0000000010001480)
+#define SH_RTC1_INT_CONFIG_MASK		__IA64_UL_CONST(0x0ff3ffffffefffff)
+#define SH_RTC1_INT_CONFIG_INIT		__IA64_UL_CONST(0x0000000000000000)
 
 /*   SH_RTC1_INT_CONFIG_TYPE                                            */
 /*   Description:  Type of Interrupt: 0=INT, 2=PMI, 4=NMI, 5=INIT       */
-#define SH_RTC1_INT_CONFIG_TYPE_SHFT             0
-#define SH_RTC1_INT_CONFIG_TYPE_MASK             0x0000000000000007
+#define SH_RTC1_INT_CONFIG_TYPE_SHFT			0
+#define SH_RTC1_INT_CONFIG_TYPE_MASK	__IA64_UL_CONST(0x0000000000000007)
 
 /*   SH_RTC1_INT_CONFIG_AGT                                             */
 /*   Description:  Agent, must be 0 for SHub                            */
-#define SH_RTC1_INT_CONFIG_AGT_SHFT              3
-#define SH_RTC1_INT_CONFIG_AGT_MASK              0x0000000000000008
+#define SH_RTC1_INT_CONFIG_AGT_SHFT			3
+#define SH_RTC1_INT_CONFIG_AGT_MASK	__IA64_UL_CONST(0x0000000000000008)
 
 /*   SH_RTC1_INT_CONFIG_PID                                             */
 /*   Description:  Processor ID, same setting as on targeted McKinley  */
-#define SH_RTC1_INT_CONFIG_PID_SHFT              4
-#define SH_RTC1_INT_CONFIG_PID_MASK              0x00000000000ffff0
+#define SH_RTC1_INT_CONFIG_PID_SHFT			4
+#define SH_RTC1_INT_CONFIG_PID_MASK	__IA64_UL_CONST(0x00000000000ffff0)
 
 /*   SH_RTC1_INT_CONFIG_BASE                                            */
 /*   Description:  Optional interrupt vector area, 2MB aligned          */
-#define SH_RTC1_INT_CONFIG_BASE_SHFT             21
-#define SH_RTC1_INT_CONFIG_BASE_MASK             0x0003ffffffe00000
+#define SH_RTC1_INT_CONFIG_BASE_SHFT			21
+#define SH_RTC1_INT_CONFIG_BASE_MASK	__IA64_UL_CONST(0x0003ffffffe00000)
 
 /*   SH_RTC1_INT_CONFIG_IDX                                             */
 /*   Description:  Targeted McKinley interrupt vector                   */
-#define SH_RTC1_INT_CONFIG_IDX_SHFT              52
-#define SH_RTC1_INT_CONFIG_IDX_MASK              0x0ff0000000000000
+#define SH_RTC1_INT_CONFIG_IDX_SHFT			52
+#define SH_RTC1_INT_CONFIG_IDX_MASK	__IA64_UL_CONST(0x0ff0000000000000)
 
 /* ==================================================================== */
 /*                    Register "SH_RTC1_INT_ENABLE"                     */
 /*                SHub RTC 1 Interrupt Enable Registers                 */
 /* ==================================================================== */
 
-#define SH1_RTC1_INT_ENABLE                      0x0000000110001500
-#define SH2_RTC1_INT_ENABLE                      0x0000000010001500
-#define SH_RTC1_INT_ENABLE_MASK                  0x0000000000000001
-#define SH_RTC1_INT_ENABLE_INIT                  0x0000000000000000
+#define SH1_RTC1_INT_ENABLE		__IA64_UL_CONST(0x0000000110001500)
+#define SH2_RTC1_INT_ENABLE		__IA64_UL_CONST(0x0000000010001500)
+#define SH_RTC1_INT_ENABLE_MASK		__IA64_UL_CONST(0x0000000000000001)
+#define SH_RTC1_INT_ENABLE_INIT		__IA64_UL_CONST(0x0000000000000000)
 
 /*   SH_RTC1_INT_ENABLE_RTC1_ENABLE                                     */
 /*   Description:  Enable RTC 1 Interrupt                               */
-#define SH_RTC1_INT_ENABLE_RTC1_ENABLE_SHFT      0
-#define SH_RTC1_INT_ENABLE_RTC1_ENABLE_MASK      0x0000000000000001
+#define SH_RTC1_INT_ENABLE_RTC1_ENABLE_SHFT		0
+#define SH_RTC1_INT_ENABLE_RTC1_ENABLE_MASK \
+					__IA64_UL_CONST(0x0000000000000001)
 
 /* ==================================================================== */
 /*                    Register "SH_RTC2_INT_CONFIG"                     */
 /*                SHub RTC 2 Interrupt Config Registers                 */
 /* ==================================================================== */
 
-#define SH1_RTC2_INT_CONFIG                      0x0000000110001580
-#define SH2_RTC2_INT_CONFIG                      0x0000000010001580
-#define SH_RTC2_INT_CONFIG_MASK                  0x0ff3ffffffefffff
-#define SH_RTC2_INT_CONFIG_INIT                  0x0000000000000000
+#define SH1_RTC2_INT_CONFIG		__IA64_UL_CONST(0x0000000110001580)
+#define SH2_RTC2_INT_CONFIG		__IA64_UL_CONST(0x0000000010001580)
+#define SH_RTC2_INT_CONFIG_MASK		__IA64_UL_CONST(0x0ff3ffffffefffff)
+#define SH_RTC2_INT_CONFIG_INIT		__IA64_UL_CONST(0x0000000000000000)
 
 /*   SH_RTC2_INT_CONFIG_TYPE                                            */
 /*   Description:  Type of Interrupt: 0=INT, 2=PMI, 4=NMI, 5=INIT       */
-#define SH_RTC2_INT_CONFIG_TYPE_SHFT             0
-#define SH_RTC2_INT_CONFIG_TYPE_MASK             0x0000000000000007
+#define SH_RTC2_INT_CONFIG_TYPE_SHFT			0
+#define SH_RTC2_INT_CONFIG_TYPE_MASK	__IA64_UL_CONST(0x0000000000000007)
 
 /*   SH_RTC2_INT_CONFIG_AGT                                             */
 /*   Description:  Agent, must be 0 for SHub                            */
-#define SH_RTC2_INT_CONFIG_AGT_SHFT              3
-#define SH_RTC2_INT_CONFIG_AGT_MASK              0x0000000000000008
+#define SH_RTC2_INT_CONFIG_AGT_SHFT			3
+#define SH_RTC2_INT_CONFIG_AGT_MASK	__IA64_UL_CONST(0x0000000000000008)
 
 /*   SH_RTC2_INT_CONFIG_PID                                             */
 /*   Description:  Processor ID, same setting as on targeted McKinley  */
-#define SH_RTC2_INT_CONFIG_PID_SHFT              4
-#define SH_RTC2_INT_CONFIG_PID_MASK              0x00000000000ffff0
+#define SH_RTC2_INT_CONFIG_PID_SHFT			4
+#define SH_RTC2_INT_CONFIG_PID_MASK	__IA64_UL_CONST(0x00000000000ffff0)
 
 /*   SH_RTC2_INT_CONFIG_BASE                                            */
 /*   Description:  Optional interrupt vector area, 2MB aligned          */
-#define SH_RTC2_INT_CONFIG_BASE_SHFT             21
-#define SH_RTC2_INT_CONFIG_BASE_MASK             0x0003ffffffe00000
+#define SH_RTC2_INT_CONFIG_BASE_SHFT			21
+#define SH_RTC2_INT_CONFIG_BASE_MASK	__IA64_UL_CONST(0x0003ffffffe00000)
 
 /*   SH_RTC2_INT_CONFIG_IDX                                             */
 /*   Description:  Targeted McKinley interrupt vector                   */
-#define SH_RTC2_INT_CONFIG_IDX_SHFT              52
-#define SH_RTC2_INT_CONFIG_IDX_MASK              0x0ff0000000000000
+#define SH_RTC2_INT_CONFIG_IDX_SHFT			52
+#define SH_RTC2_INT_CONFIG_IDX_MASK	__IA64_UL_CONST(0x0ff0000000000000)
 
 /* ==================================================================== */
 /*                    Register "SH_RTC2_INT_ENABLE"                     */
 /*                SHub RTC 2 Interrupt Enable Registers                 */
 /* ==================================================================== */
 
-#define SH1_RTC2_INT_ENABLE                      0x0000000110001600
-#define SH2_RTC2_INT_ENABLE                      0x0000000010001600
-#define SH_RTC2_INT_ENABLE_MASK                  0x0000000000000001
-#define SH_RTC2_INT_ENABLE_INIT                  0x0000000000000000
+#define SH1_RTC2_INT_ENABLE		__IA64_UL_CONST(0x0000000110001600)
+#define SH2_RTC2_INT_ENABLE		__IA64_UL_CONST(0x0000000010001600)
+#define SH_RTC2_INT_ENABLE_MASK		__IA64_UL_CONST(0x0000000000000001)
+#define SH_RTC2_INT_ENABLE_INIT		__IA64_UL_CONST(0x0000000000000000)
 
 /*   SH_RTC2_INT_ENABLE_RTC2_ENABLE                                     */
 /*   Description:  Enable RTC 2 Interrupt                               */
-#define SH_RTC2_INT_ENABLE_RTC2_ENABLE_SHFT      0
-#define SH_RTC2_INT_ENABLE_RTC2_ENABLE_MASK      0x0000000000000001
+#define SH_RTC2_INT_ENABLE_RTC2_ENABLE_SHFT		0
+#define SH_RTC2_INT_ENABLE_RTC2_ENABLE_MASK \
+					__IA64_UL_CONST(0x0000000000000001)
 
 /* ==================================================================== */
 /*                    Register "SH_RTC3_INT_CONFIG"                     */
 /*                SHub RTC 3 Interrupt Config Registers                 */
 /* ==================================================================== */
 
-#define SH1_RTC3_INT_CONFIG                      0x0000000110001680
-#define SH2_RTC3_INT_CONFIG                      0x0000000010001680
-#define SH_RTC3_INT_CONFIG_MASK                  0x0ff3ffffffefffff
-#define SH_RTC3_INT_CONFIG_INIT                  0x0000000000000000
+#define SH1_RTC3_INT_CONFIG		__IA64_UL_CONST(0x0000000110001680)
+#define SH2_RTC3_INT_CONFIG		__IA64_UL_CONST(0x0000000010001680)
+#define SH_RTC3_INT_CONFIG_MASK		__IA64_UL_CONST(0x0ff3ffffffefffff)
+#define SH_RTC3_INT_CONFIG_INIT		__IA64_UL_CONST(0x0000000000000000)
 
 /*   SH_RTC3_INT_CONFIG_TYPE                                            */
 /*   Description:  Type of Interrupt: 0=INT, 2=PMI, 4=NMI, 5=INIT       */
-#define SH_RTC3_INT_CONFIG_TYPE_SHFT             0
-#define SH_RTC3_INT_CONFIG_TYPE_MASK             0x0000000000000007
+#define SH_RTC3_INT_CONFIG_TYPE_SHFT			0
+#define SH_RTC3_INT_CONFIG_TYPE_MASK	__IA64_UL_CONST(0x0000000000000007)
 
 /*   SH_RTC3_INT_CONFIG_AGT                                             */
 /*   Description:  Agent, must be 0 for SHub                            */
-#define SH_RTC3_INT_CONFIG_AGT_SHFT              3
-#define SH_RTC3_INT_CONFIG_AGT_MASK              0x0000000000000008
+#define SH_RTC3_INT_CONFIG_AGT_SHFT			3
+#define SH_RTC3_INT_CONFIG_AGT_MASK	__IA64_UL_CONST(0x0000000000000008)
 
 /*   SH_RTC3_INT_CONFIG_PID                                             */
 /*   Description:  Processor ID, same setting as on targeted McKinley  */
-#define SH_RTC3_INT_CONFIG_PID_SHFT              4
-#define SH_RTC3_INT_CONFIG_PID_MASK              0x00000000000ffff0
+#define SH_RTC3_INT_CONFIG_PID_SHFT			4
+#define SH_RTC3_INT_CONFIG_PID_MASK	__IA64_UL_CONST(0x00000000000ffff0)
 
 /*   SH_RTC3_INT_CONFIG_BASE                                            */
 /*   Description:  Optional interrupt vector area, 2MB aligned          */
-#define SH_RTC3_INT_CONFIG_BASE_SHFT             21
-#define SH_RTC3_INT_CONFIG_BASE_MASK             0x0003ffffffe00000
+#define SH_RTC3_INT_CONFIG_BASE_SHFT			21
+#define SH_RTC3_INT_CONFIG_BASE_MASK	__IA64_UL_CONST(0x0003ffffffe00000)
 
 /*   SH_RTC3_INT_CONFIG_IDX                                             */
 /*   Description:  Targeted McKinley interrupt vector                   */
-#define SH_RTC3_INT_CONFIG_IDX_SHFT              52
-#define SH_RTC3_INT_CONFIG_IDX_MASK              0x0ff0000000000000
+#define SH_RTC3_INT_CONFIG_IDX_SHFT			52
+#define SH_RTC3_INT_CONFIG_IDX_MASK	__IA64_UL_CONST(0x0ff0000000000000)
 
 /* ==================================================================== */
 /*                    Register "SH_RTC3_INT_ENABLE"                     */
 /*                SHub RTC 3 Interrupt Enable Registers                 */
 /* ==================================================================== */
 
-#define SH1_RTC3_INT_ENABLE                      0x0000000110001700
-#define SH2_RTC3_INT_ENABLE                      0x0000000010001700
-#define SH_RTC3_INT_ENABLE_MASK                  0x0000000000000001
-#define SH_RTC3_INT_ENABLE_INIT                  0x0000000000000000
+#define SH1_RTC3_INT_ENABLE		__IA64_UL_CONST(0x0000000110001700)
+#define SH2_RTC3_INT_ENABLE		__IA64_UL_CONST(0x0000000010001700)
+#define SH_RTC3_INT_ENABLE_MASK		__IA64_UL_CONST(0x0000000000000001)
+#define SH_RTC3_INT_ENABLE_INIT		__IA64_UL_CONST(0x0000000000000000)
 
 /*   SH_RTC3_INT_ENABLE_RTC3_ENABLE                                     */
 /*   Description:  Enable RTC 3 Interrupt                               */
-#define SH_RTC3_INT_ENABLE_RTC3_ENABLE_SHFT      0
-#define SH_RTC3_INT_ENABLE_RTC3_ENABLE_MASK      0x0000000000000001
+#define SH_RTC3_INT_ENABLE_RTC3_ENABLE_SHFT		0
+#define SH_RTC3_INT_ENABLE_RTC3_ENABLE_MASK \
+					__IA64_UL_CONST(0x0000000000000001)
 
 /*   SH_EVENT_OCCURRED_RTC1_INT                                         */
 /*   Description:  Pending RTC 1 Interrupt                              */
-#define SH_EVENT_OCCURRED_RTC1_INT_SHFT          24
-#define SH_EVENT_OCCURRED_RTC1_INT_MASK          0x0000000001000000
+#define SH_EVENT_OCCURRED_RTC1_INT_SHFT			24
+#define SH_EVENT_OCCURRED_RTC1_INT_MASK	__IA64_UL_CONST(0x0000000001000000)
 
 /*   SH_EVENT_OCCURRED_RTC2_INT                                         */
 /*   Description:  Pending RTC 2 Interrupt                              */
-#define SH_EVENT_OCCURRED_RTC2_INT_SHFT          25
-#define SH_EVENT_OCCURRED_RTC2_INT_MASK          0x0000000002000000
+#define SH_EVENT_OCCURRED_RTC2_INT_SHFT			25
+#define SH_EVENT_OCCURRED_RTC2_INT_MASK	__IA64_UL_CONST(0x0000000002000000)
 
 /*   SH_EVENT_OCCURRED_RTC3_INT                                         */
 /*   Description:  Pending RTC 3 Interrupt                              */
-#define SH_EVENT_OCCURRED_RTC3_INT_SHFT          26
-#define SH_EVENT_OCCURRED_RTC3_INT_MASK          0x0000000004000000
+#define SH_EVENT_OCCURRED_RTC3_INT_SHFT			26
+#define SH_EVENT_OCCURRED_RTC3_INT_MASK	__IA64_UL_CONST(0x0000000004000000)
 
 /* ==================================================================== */
 /*                       Register "SH_IPI_ACCESS"                       */
 /*                 CPU interrupt Access Permission Bits                 */
 /* ==================================================================== */
 
-#define SH1_IPI_ACCESS                           0x0000000110060480
-#define SH2_IPI_ACCESS0                          0x0000000010060c00
-#define SH2_IPI_ACCESS1                          0x0000000010060c80
-#define SH2_IPI_ACCESS2                          0x0000000010060d00
-#define SH2_IPI_ACCESS3                          0x0000000010060d80
+#define SH1_IPI_ACCESS			__IA64_UL_CONST(0x0000000110060480)
+#define SH2_IPI_ACCESS0			__IA64_UL_CONST(0x0000000010060c00)
+#define SH2_IPI_ACCESS1			__IA64_UL_CONST(0x0000000010060c80)
+#define SH2_IPI_ACCESS2			__IA64_UL_CONST(0x0000000010060d00)
+#define SH2_IPI_ACCESS3			__IA64_UL_CONST(0x0000000010060d80)
 
 /* ==================================================================== */
 /*                        Register "SH_INT_CMPB"                        */
 /*                  RTC Compare Value for Processor B                   */
 /* ==================================================================== */
 
-#define SH1_INT_CMPB                             0x00000001101b0080
-#define SH2_INT_CMPB                             0x00000000101b0080
-#define SH_INT_CMPB_MASK                         0x007fffffffffffff
-#define SH_INT_CMPB_INIT                         0x0000000000000000
+#define SH1_INT_CMPB			__IA64_UL_CONST(0x00000001101b0080)
+#define SH2_INT_CMPB			__IA64_UL_CONST(0x00000000101b0080)
+#define SH_INT_CMPB_MASK		__IA64_UL_CONST(0x007fffffffffffff)
+#define SH_INT_CMPB_INIT		__IA64_UL_CONST(0x0000000000000000)
 
 /*   SH_INT_CMPB_REAL_TIME_CMPB                                         */
 /*   Description:  Real Time Clock Compare                              */
-#define SH_INT_CMPB_REAL_TIME_CMPB_SHFT          0
-#define SH_INT_CMPB_REAL_TIME_CMPB_MASK          0x007fffffffffffff
+#define SH_INT_CMPB_REAL_TIME_CMPB_SHFT			0
+#define SH_INT_CMPB_REAL_TIME_CMPB_MASK	__IA64_UL_CONST(0x007fffffffffffff)
 
 /* ==================================================================== */
 /*                        Register "SH_INT_CMPC"                        */
 /*                  RTC Compare Value for Processor C                   */
 /* ==================================================================== */
 
-#define SH1_INT_CMPC                             0x00000001101b0100
-#define SH2_INT_CMPC                             0x00000000101b0100
-#define SH_INT_CMPC_MASK                         0x007fffffffffffff
-#define SH_INT_CMPC_INIT                         0x0000000000000000
+#define SH1_INT_CMPC			__IA64_UL_CONST(0x00000001101b0100)
+#define SH2_INT_CMPC			__IA64_UL_CONST(0x00000000101b0100)
+#define SH_INT_CMPC_MASK		__IA64_UL_CONST(0x007fffffffffffff)
+#define SH_INT_CMPC_INIT		__IA64_UL_CONST(0x0000000000000000)
 
 /*   SH_INT_CMPC_REAL_TIME_CMPC                                         */
 /*   Description:  Real Time Clock Compare                              */
-#define SH_INT_CMPC_REAL_TIME_CMPC_SHFT          0
-#define SH_INT_CMPC_REAL_TIME_CMPC_MASK          0x007fffffffffffff
+#define SH_INT_CMPC_REAL_TIME_CMPC_SHFT			0
+#define SH_INT_CMPC_REAL_TIME_CMPC_MASK	__IA64_UL_CONST(0x007fffffffffffff)
 
 /* ==================================================================== */
 /*                        Register "SH_INT_CMPD"                        */
 /*                  RTC Compare Value for Processor D                   */
 /* ==================================================================== */
 
-#define SH1_INT_CMPD                             0x00000001101b0180
-#define SH2_INT_CMPD                             0x00000000101b0180
-#define SH_INT_CMPD_MASK                         0x007fffffffffffff
-#define SH_INT_CMPD_INIT                         0x0000000000000000
+#define SH1_INT_CMPD			__IA64_UL_CONST(0x00000001101b0180)
+#define SH2_INT_CMPD			__IA64_UL_CONST(0x00000000101b0180)
+#define SH_INT_CMPD_MASK		__IA64_UL_CONST(0x007fffffffffffff)
+#define SH_INT_CMPD_INIT		__IA64_UL_CONST(0x0000000000000000)
 
 /*   SH_INT_CMPD_REAL_TIME_CMPD                                         */
 /*   Description:  Real Time Clock Compare                              */
-#define SH_INT_CMPD_REAL_TIME_CMPD_SHFT          0
-#define SH_INT_CMPD_REAL_TIME_CMPD_MASK          0x007fffffffffffff
+#define SH_INT_CMPD_REAL_TIME_CMPD_SHFT			0
+#define SH_INT_CMPD_REAL_TIME_CMPD_MASK	__IA64_UL_CONST(0x007fffffffffffff)
 
 /* ==================================================================== */
 /*                Register "SH_MD_DQLP_MMR_DIR_PRIVEC0"                 */
 /*                      privilege vector for acc=0                      */
 /* ==================================================================== */
-
-#define SH1_MD_DQLP_MMR_DIR_PRIVEC0              0x0000000100030300
+#define SH1_MD_DQLP_MMR_DIR_PRIVEC0	__IA64_UL_CONST(0x0000000100030300)
 
 /* ==================================================================== */
 /*                Register "SH_MD_DQRP_MMR_DIR_PRIVEC0"                 */
 /*                      privilege vector for acc=0                      */
 /* ==================================================================== */
-
-#define SH1_MD_DQRP_MMR_DIR_PRIVEC0              0x0000000100050300
+#define SH1_MD_DQRP_MMR_DIR_PRIVEC0	__IA64_UL_CONST(0x0000000100050300)
 
 /* ==================================================================== */
 /* Some MMRs are functionally identical (or close enough) on both SHUB1 */
@@ -484,17 +486,17 @@
 /*                    Engine 0 Control and Status Register                    */
 /* ========================================================================== */
 
-#define SH2_BT_ENG_CSR_0                         0x0000000030040000
-#define SH2_BT_ENG_SRC_ADDR_0                    0x0000000030040080
-#define SH2_BT_ENG_DEST_ADDR_0                   0x0000000030040100
-#define SH2_BT_ENG_NOTIF_ADDR_0                  0x0000000030040180
+#define SH2_BT_ENG_CSR_0		__IA64_UL_CONST(0x0000000030040000)
+#define SH2_BT_ENG_SRC_ADDR_0		__IA64_UL_CONST(0x0000000030040080)
+#define SH2_BT_ENG_DEST_ADDR_0		__IA64_UL_CONST(0x0000000030040100)
+#define SH2_BT_ENG_NOTIF_ADDR_0		__IA64_UL_CONST(0x0000000030040180)
 
 /* ========================================================================== */
 /*                       BTE interfaces 1-3                                   */
 /* ========================================================================== */
 
-#define SH2_BT_ENG_CSR_1                         0x0000000030050000
-#define SH2_BT_ENG_CSR_2                         0x0000000030060000
-#define SH2_BT_ENG_CSR_3                         0x0000000030070000
+#define SH2_BT_ENG_CSR_1		__IA64_UL_CONST(0x0000000030050000)
+#define SH2_BT_ENG_CSR_2		__IA64_UL_CONST(0x0000000030060000)
+#define SH2_BT_ENG_CSR_3		__IA64_UL_CONST(0x0000000030070000)
 
 #endif /* _ASM_IA64_SN_SHUB_MMR_H */
diff --git a/include/asm-ia64/sn/simulator.h b/include/asm-ia64/sn/simulator.h
--- a/include/asm-ia64/sn/simulator.h
+++ b/include/asm-ia64/sn/simulator.h
@@ -10,18 +10,12 @@
 
 #include <linux/config.h>
 
-#ifdef CONFIG_IA64_SGI_SN_SIM
-
 #define SNMAGIC 0xaeeeeeee8badbeefL
-#define IS_RUNNING_ON_SIMULATOR() ({long sn; asm("mov %0=cpuid[%1]" : "=r"(sn) : "r"(2)); sn == SNMAGIC;})
-
-#define SIMULATOR_SLEEP()	asm("nop.i 0x8beef")
-
-#else
-
-#define IS_RUNNING_ON_SIMULATOR()	(0)
-#define SIMULATOR_SLEEP()
+#define IS_MEDUSA()			({long sn; asm("mov %0=cpuid[%1]" : "=r"(sn) : "r"(2)); sn == SNMAGIC;})
 
-#endif
+#define SIMULATOR_SLEEP()		asm("nop.i 0x8beef")
+#define IS_RUNNING_ON_SIMULATOR()	(sn_prom_type)
+#define IS_RUNNING_ON_FAKE_PROM()	(sn_prom_type == 2)
+extern int sn_prom_type;		/* 0=hardware, 1=medusa/realprom, 2=medusa/fakeprom */
 
 #endif /* _ASM_IA64_SN_SIMULATOR_H */
diff --git a/include/asm-ia64/sn/sn2/sn_hwperf.h b/include/asm-ia64/sn/sn2/sn_hwperf.h
--- a/include/asm-ia64/sn/sn2/sn_hwperf.h
+++ b/include/asm-ia64/sn/sn2/sn_hwperf.h
@@ -223,4 +223,6 @@ struct sn_hwperf_ioctl_args {
 #define SN_HWPERF_OP_RECONFIGURE	253
 #define SN_HWPERF_OP_INVAL		254
 
+int sn_topology_open(struct inode *inode, struct file *file);
+int sn_topology_release(struct inode *inode, struct file *file);
 #endif				/* SN_HWPERF_H */
diff --git a/include/asm-ia64/sn/sn_cpuid.h b/include/asm-ia64/sn/sn_cpuid.h
--- a/include/asm-ia64/sn/sn_cpuid.h
+++ b/include/asm-ia64/sn/sn_cpuid.h
@@ -81,11 +81,6 @@
  *
  */
 
-#ifndef CONFIG_SMP
-#define cpu_physical_id(cpuid)			((ia64_getreg(_IA64_REG_CR_LID) >> 16) & 0xffff)
-#endif
-
-
 #define get_node_number(addr)			NASID_GET(addr)
 
 /*
diff --git a/include/asm-ia64/sn/sn_sal.h b/include/asm-ia64/sn/sn_sal.h
--- a/include/asm-ia64/sn/sn_sal.h
+++ b/include/asm-ia64/sn/sn_sal.h
@@ -132,43 +132,30 @@
 #define SALRET_INVALID_ARG	(-2)
 #define SALRET_ERROR		(-3)
 
+#define SN_SAL_FAKE_PROM			   0x02009999
 
 /**
- * sn_sal_rev_major - get the major SGI SAL revision number
- *
- * The SGI PROM stores its version in sal_[ab]_rev_(major|minor).
- * This routine simply extracts the major value from the
- * @ia64_sal_systab structure constructed by ia64_sal_init().
- */
-static inline int
-sn_sal_rev_major(void)
+  * sn_sal_revision - get the SGI SAL revision number
+  *
+  * The SGI PROM stores its version in the sal_[ab]_rev_(major|minor).
+  * This routine simply extracts the major and minor values and
+  * presents them in a u32 format.
+  *
+  * For example, version 4.05 would be represented at 0x0405.
+  */
+static inline u32
+sn_sal_rev(void)
 {
 	struct ia64_sal_systab *systab = efi.sal_systab;
 
-	return (int)systab->sal_b_rev_major;
-}
-
-/**
- * sn_sal_rev_minor - get the minor SGI SAL revision number
- *
- * The SGI PROM stores its version in sal_[ab]_rev_(major|minor).
- * This routine simply extracts the minor value from the
- * @ia64_sal_systab structure constructed by ia64_sal_init().
- */
-static inline int
-sn_sal_rev_minor(void)
-{
-	struct ia64_sal_systab *systab = efi.sal_systab;
-	
-	return (int)systab->sal_b_rev_minor;
+	return (u32)(systab->sal_b_rev_major << 8 | systab->sal_b_rev_minor);
 }
 
 /*
  * Specify the minimum PROM revsion required for this kernel.
  * Note that they're stored in hex format...
  */
-#define SN_SAL_MIN_MAJOR	0x4  /* SN2 kernels need at least PROM 4.0 */
-#define SN_SAL_MIN_MINOR	0x0
+#define SN_SAL_MIN_VERSION	0x0404
 
 /*
  * Returns the master console nasid, if the call fails, return an illegal
@@ -1105,4 +1092,12 @@ ia64_sn_bte_recovery(nasid_t nasid)
 	return (int) rv.status;
 }
 
+static inline int
+ia64_sn_is_fake_prom(void)
+{
+	struct ia64_sal_retval rv;
+	SAL_CALL_NOLOCK(rv, SN_SAL_FAKE_PROM, 0, 0, 0, 0, 0, 0, 0);
+	return (rv.status == 0);
+}
+
 #endif /* _ASM_IA64_SN_SN_SAL_H */
diff --git a/include/asm-ia64/sn/tioca_provider.h b/include/asm-ia64/sn/tioca_provider.h
--- a/include/asm-ia64/sn/tioca_provider.h
+++ b/include/asm-ia64/sn/tioca_provider.h
@@ -201,6 +201,7 @@ tioca_tlbflush(struct tioca_kernel *tioc
 }
 
 extern uint32_t	tioca_gart_found;
+extern struct list_head tioca_list;
 extern int tioca_init_provider(void);
 extern void tioca_fastwrite_enable(struct tioca_kernel *tioca_kern);
 #endif /* _ASM_IA64_SN_TIO_CA_AGP_PROVIDER_H */
diff --git a/include/asm-ia64/sn/tiocp.h b/include/asm-ia64/sn/tiocp.h
new file mode 100644
--- /dev/null
+++ b/include/asm-ia64/sn/tiocp.h
@@ -0,0 +1,256 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2003-2004 Silicon Graphics, Inc. All rights reserved.
+ */
+#ifndef _ASM_IA64_SN_PCI_TIOCP_H
+#define _ASM_IA64_SN_PCI_TIOCP_H
+
+#define TIOCP_HOST_INTR_ADDR            0x003FFFFFFFFFFFFFUL
+#define TIOCP_PCI64_CMDTYPE_MEM         (0x1ull << 60)
+
+
+/*****************************************************************************
+ *********************** TIOCP MMR structure mapping ***************************
+ *****************************************************************************/
+
+struct tiocp{
+
+    /* 0x000000-0x00FFFF -- Local Registers */
+
+    /* 0x000000-0x000057 -- (Legacy Widget Space) Configuration */
+    uint64_t		cp_id;				/* 0x000000 */
+    uint64_t		cp_stat;			/* 0x000008 */
+    uint64_t		cp_err_upper;			/* 0x000010 */
+    uint64_t		cp_err_lower;			/* 0x000018 */
+    #define cp_err cp_err_lower
+    uint64_t		cp_control;			/* 0x000020 */
+    uint64_t		cp_req_timeout;			/* 0x000028 */
+    uint64_t		cp_intr_upper;			/* 0x000030 */
+    uint64_t		cp_intr_lower;			/* 0x000038 */
+    #define cp_intr cp_intr_lower
+    uint64_t		cp_err_cmdword;			/* 0x000040 */
+    uint64_t		_pad_000048;			/* 0x000048 */
+    uint64_t		cp_tflush;			/* 0x000050 */
+
+    /* 0x000058-0x00007F -- Bridge-specific Configuration */
+    uint64_t		cp_aux_err;			/* 0x000058 */
+    uint64_t		cp_resp_upper;			/* 0x000060 */
+    uint64_t		cp_resp_lower;			/* 0x000068 */
+    #define cp_resp cp_resp_lower
+    uint64_t		cp_tst_pin_ctrl;		/* 0x000070 */
+    uint64_t		cp_addr_lkerr;			/* 0x000078 */
+
+    /* 0x000080-0x00008F -- PMU & MAP */
+    uint64_t		cp_dir_map;			/* 0x000080 */
+    uint64_t		_pad_000088;			/* 0x000088 */
+
+    /* 0x000090-0x00009F -- SSRAM */
+    uint64_t		cp_map_fault;			/* 0x000090 */
+    uint64_t		_pad_000098;			/* 0x000098 */
+
+    /* 0x0000A0-0x0000AF -- Arbitration */
+    uint64_t		cp_arb;				/* 0x0000A0 */
+    uint64_t		_pad_0000A8;			/* 0x0000A8 */
+
+    /* 0x0000B0-0x0000BF -- Number In A Can or ATE Parity Error */
+    uint64_t		cp_ate_parity_err;		/* 0x0000B0 */
+    uint64_t		_pad_0000B8;			/* 0x0000B8 */
+
+    /* 0x0000C0-0x0000FF -- PCI/GIO */
+    uint64_t		cp_bus_timeout;			/* 0x0000C0 */
+    uint64_t		cp_pci_cfg;			/* 0x0000C8 */
+    uint64_t		cp_pci_err_upper;		/* 0x0000D0 */
+    uint64_t		cp_pci_err_lower;		/* 0x0000D8 */
+    #define cp_pci_err cp_pci_err_lower
+    uint64_t		_pad_0000E0[4];			/* 0x0000{E0..F8} */
+
+    /* 0x000100-0x0001FF -- Interrupt */
+    uint64_t		cp_int_status;			/* 0x000100 */
+    uint64_t		cp_int_enable;			/* 0x000108 */
+    uint64_t		cp_int_rst_stat;		/* 0x000110 */
+    uint64_t		cp_int_mode;			/* 0x000118 */
+    uint64_t		cp_int_device;			/* 0x000120 */
+    uint64_t		cp_int_host_err;		/* 0x000128 */
+    uint64_t		cp_int_addr[8];			/* 0x0001{30,,,68} */
+    uint64_t		cp_err_int_view;		/* 0x000170 */
+    uint64_t		cp_mult_int;			/* 0x000178 */
+    uint64_t		cp_force_always[8];		/* 0x0001{80,,,B8} */
+    uint64_t		cp_force_pin[8];		/* 0x0001{C0,,,F8} */
+
+    /* 0x000200-0x000298 -- Device */
+    uint64_t		cp_device[4];			/* 0x0002{00,,,18} */
+    uint64_t		_pad_000220[4];			/* 0x0002{20,,,38} */
+    uint64_t		cp_wr_req_buf[4];		/* 0x0002{40,,,58} */
+    uint64_t		_pad_000260[4];			/* 0x0002{60,,,78} */
+    uint64_t		cp_rrb_map[2];			/* 0x0002{80,,,88} */
+    #define cp_even_resp cp_rrb_map[0]			/* 0x000280 */
+    #define cp_odd_resp  cp_rrb_map[1]			/* 0x000288 */
+    uint64_t		cp_resp_status;			/* 0x000290 */
+    uint64_t		cp_resp_clear;			/* 0x000298 */
+
+    uint64_t		_pad_0002A0[12];		/* 0x0002{A0..F8} */
+
+    /* 0x000300-0x0003F8 -- Buffer Address Match Registers */
+    struct {
+	uint64_t	upper;				/* 0x0003{00,,,F0} */
+	uint64_t	lower;				/* 0x0003{08,,,F8} */
+    } cp_buf_addr_match[16];
+
+    /* 0x000400-0x0005FF -- Performance Monitor Registers (even only) */
+    struct {
+	uint64_t	flush_w_touch;			/* 0x000{400,,,5C0} */
+	uint64_t	flush_wo_touch;			/* 0x000{408,,,5C8} */
+	uint64_t	inflight;			/* 0x000{410,,,5D0} */
+	uint64_t	prefetch;			/* 0x000{418,,,5D8} */
+	uint64_t	total_pci_retry;		/* 0x000{420,,,5E0} */
+	uint64_t	max_pci_retry;			/* 0x000{428,,,5E8} */
+	uint64_t	max_latency;			/* 0x000{430,,,5F0} */
+	uint64_t	clear_all;			/* 0x000{438,,,5F8} */
+    } cp_buf_count[8];
+
+
+    /* 0x000600-0x0009FF -- PCI/X registers */
+    uint64_t		cp_pcix_bus_err_addr;		/* 0x000600 */
+    uint64_t		cp_pcix_bus_err_attr;		/* 0x000608 */
+    uint64_t		cp_pcix_bus_err_data;		/* 0x000610 */
+    uint64_t		cp_pcix_pio_split_addr;		/* 0x000618 */
+    uint64_t		cp_pcix_pio_split_attr;		/* 0x000620 */
+    uint64_t		cp_pcix_dma_req_err_attr;	/* 0x000628 */
+    uint64_t		cp_pcix_dma_req_err_addr;	/* 0x000630 */
+    uint64_t		cp_pcix_timeout;		/* 0x000638 */
+
+    uint64_t		_pad_000640[24];		/* 0x000{640,,,6F8} */
+
+    /* 0x000700-0x000737 -- Debug Registers */
+    uint64_t		cp_ct_debug_ctl;		/* 0x000700 */
+    uint64_t		cp_br_debug_ctl;		/* 0x000708 */
+    uint64_t		cp_mux3_debug_ctl;		/* 0x000710 */
+    uint64_t		cp_mux4_debug_ctl;		/* 0x000718 */
+    uint64_t		cp_mux5_debug_ctl;		/* 0x000720 */
+    uint64_t		cp_mux6_debug_ctl;		/* 0x000728 */
+    uint64_t		cp_mux7_debug_ctl;		/* 0x000730 */
+
+    uint64_t		_pad_000738[89];		/* 0x000{738,,,9F8} */
+
+    /* 0x000A00-0x000BFF -- PCI/X Read&Write Buffer */
+    struct {
+	uint64_t	cp_buf_addr;			/* 0x000{A00,,,AF0} */
+	uint64_t	cp_buf_attr;			/* 0X000{A08,,,AF8} */
+    } cp_pcix_read_buf_64[16];
+
+    struct {
+	uint64_t	cp_buf_addr;			/* 0x000{B00,,,BE0} */
+	uint64_t	cp_buf_attr;			/* 0x000{B08,,,BE8} */
+	uint64_t	cp_buf_valid;			/* 0x000{B10,,,BF0} */
+	uint64_t	__pad1;				/* 0x000{B18,,,BF8} */
+    } cp_pcix_write_buf_64[8];
+
+    /* End of Local Registers -- Start of Address Map space */
+
+    char		_pad_000c00[0x010000 - 0x000c00];
+
+    /* 0x010000-0x011FF8 -- Internal ATE RAM (Auto Parity Generation) */
+    uint64_t		cp_int_ate_ram[1024];		/* 0x010000-0x011FF8 */
+
+    char		_pad_012000[0x14000 - 0x012000];
+
+    /* 0x014000-0x015FF8 -- Internal ATE RAM (Manual Parity Generation) */
+    uint64_t		cp_int_ate_ram_mp[1024];	/* 0x014000-0x015FF8 */
+
+    char		_pad_016000[0x18000 - 0x016000];
+
+    /* 0x18000-0x197F8 -- TIOCP Write Request Ram */
+    uint64_t		cp_wr_req_lower[256];		/* 0x18000 - 0x187F8 */
+    uint64_t		cp_wr_req_upper[256];		/* 0x18800 - 0x18FF8 */
+    uint64_t		cp_wr_req_parity[256];		/* 0x19000 - 0x197F8 */
+
+    char		_pad_019800[0x1C000 - 0x019800];
+
+    /* 0x1C000-0x1EFF8 -- TIOCP Read Response Ram */
+    uint64_t		cp_rd_resp_lower[512];		/* 0x1C000 - 0x1CFF8 */
+    uint64_t		cp_rd_resp_upper[512];		/* 0x1D000 - 0x1DFF8 */
+    uint64_t		cp_rd_resp_parity[512];		/* 0x1E000 - 0x1EFF8 */
+
+    char		_pad_01F000[0x20000 - 0x01F000];
+
+    /* 0x020000-0x021FFF -- Host Device (CP) Configuration Space (not used)  */
+    char		_pad_020000[0x021000 - 0x20000];
+
+    /* 0x021000-0x027FFF -- PCI Device Configuration Spaces */
+    union {
+	uint8_t		c[0x1000 / 1];			/* 0x02{0000,,,7FFF} */
+	uint16_t	s[0x1000 / 2];			/* 0x02{0000,,,7FFF} */
+	uint32_t	l[0x1000 / 4];			/* 0x02{0000,,,7FFF} */
+	uint64_t	d[0x1000 / 8];			/* 0x02{0000,,,7FFF} */
+	union {
+	    uint8_t	c[0x100 / 1];
+	    uint16_t	s[0x100 / 2];
+	    uint32_t	l[0x100 / 4];
+	    uint64_t	d[0x100 / 8];
+	} f[8];
+    } cp_type0_cfg_dev[7];				/* 0x02{1000,,,7FFF} */
+
+    /* 0x028000-0x028FFF -- PCI Type 1 Configuration Space */
+    union {
+	uint8_t		c[0x1000 / 1];			/* 0x028000-0x029000 */
+	uint16_t	s[0x1000 / 2];			/* 0x028000-0x029000 */
+	uint32_t	l[0x1000 / 4];			/* 0x028000-0x029000 */
+	uint64_t	d[0x1000 / 8];			/* 0x028000-0x029000 */
+	union {
+	    uint8_t	c[0x100 / 1];
+	    uint16_t	s[0x100 / 2];
+	    uint32_t	l[0x100 / 4];
+	    uint64_t	d[0x100 / 8];
+	} f[8];
+    } cp_type1_cfg;					/* 0x028000-0x029000 */
+
+    char		_pad_029000[0x030000-0x029000];
+
+    /* 0x030000-0x030007 -- PCI Interrupt Acknowledge Cycle */
+    union {
+	uint8_t		c[8 / 1];
+	uint16_t	s[8 / 2];
+	uint32_t	l[8 / 4];
+	uint64_t	d[8 / 8];
+    } cp_pci_iack;					/* 0x030000-0x030007 */
+
+    char		_pad_030007[0x040000-0x030008];
+
+    /* 0x040000-0x040007 -- PCIX Special Cycle */
+    union {
+	uint8_t		c[8 / 1];
+	uint16_t	s[8 / 2];
+	uint32_t	l[8 / 4];
+	uint64_t	d[8 / 8];
+    } cp_pcix_cycle;					/* 0x040000-0x040007 */
+
+    char		_pad_040007[0x200000-0x040008];
+
+    /* 0x200000-0x7FFFFF -- PCI/GIO Device Spaces */
+    union {
+	uint8_t		c[0x100000 / 1];
+	uint16_t	s[0x100000 / 2];
+	uint32_t	l[0x100000 / 4];
+	uint64_t	d[0x100000 / 8];
+    } cp_devio_raw[6];					/* 0x200000-0x7FFFFF */
+
+    #define cp_devio(n)  cp_devio_raw[((n)<2)?(n*2):(n+2)]
+
+    char		_pad_800000[0xA00000-0x800000];
+
+    /* 0xA00000-0xBFFFFF -- PCI/GIO Device Spaces w/flush  */
+    union {
+	uint8_t		c[0x100000 / 1];
+	uint16_t	s[0x100000 / 2];
+	uint32_t	l[0x100000 / 4];
+	uint64_t	d[0x100000 / 8];
+    } cp_devio_raw_flush[6];				/* 0xA00000-0xBFFFFF */
+
+    #define cp_devio_flush(n)  cp_devio_raw_flush[((n)<2)?(n*2):(n+2)]
+
+};
+
+#endif 	/* _ASM_IA64_SN_PCI_TIOCP_H */
diff --git a/include/asm-ia64/sn/xp.h b/include/asm-ia64/sn/xp.h
--- a/include/asm-ia64/sn/xp.h
+++ b/include/asm-ia64/sn/xp.h
@@ -16,7 +16,6 @@
 #define _ASM_IA64_SN_XP_H
 
 
-#include <linux/version.h>
 #include <linux/cache.h>
 #include <linux/hardirq.h>
 #include <asm/sn/types.h>
diff --git a/include/asm-ia64/system.h b/include/asm-ia64/system.h
--- a/include/asm-ia64/system.h
+++ b/include/asm-ia64/system.h
@@ -183,8 +183,6 @@ do {								\
 
 #ifdef __KERNEL__
 
-#define prepare_to_switch()    do { } while(0)
-
 #ifdef CONFIG_IA32_SUPPORT
 # define IS_IA32_PROCESS(regs)	(ia64_psr(regs)->is != 0)
 #else
@@ -274,13 +272,7 @@ extern void ia64_load_extra (struct task
  * of that CPU which will not be released, because there we wait for the
  * tasklist_lock to become available.
  */
-#define prepare_arch_switch(rq, next)		\
-do {						\
-	spin_lock(&(next)->switch_lock);	\
-	spin_unlock(&(rq)->lock);		\
-} while (0)
-#define finish_arch_switch(rq, prev)	spin_unlock_irq(&(prev)->switch_lock)
-#define task_running(rq, p) 		((rq)->curr == (p) || spin_is_locked(&(p)->switch_lock))
+#define __ARCH_WANT_UNLOCKED_CTXSW
 
 #define ia64_platform_is(x) (strcmp(x, platform_name) == 0)
 
diff --git a/include/asm-ia64/thread_info.h b/include/asm-ia64/thread_info.h
--- a/include/asm-ia64/thread_info.h
+++ b/include/asm-ia64/thread_info.h
@@ -25,7 +25,7 @@ struct thread_info {
 	__u32 flags;			/* thread_info flags (see TIF_*) */
 	__u32 cpu;			/* current CPU */
 	mm_segment_t addr_limit;	/* user-level address space limit */
-	__s32 preempt_count;		/* 0=premptable, <0=BUG; will also serve as bh-counter */
+	int preempt_count;		/* 0=premptable, <0=BUG; will also serve as bh-counter */
 	struct restart_block restart_block;
 	struct {
 		int signo;
diff --git a/include/asm-ia64/topology.h b/include/asm-ia64/topology.h
--- a/include/asm-ia64/topology.h
+++ b/include/asm-ia64/topology.h
@@ -40,27 +40,61 @@
  */
 #define node_to_first_cpu(node) (__ffs(node_to_cpumask(node)))
 
+/*
+ * Determines the node for a given pci bus
+ */
+#define pcibus_to_node(bus) PCI_CONTROLLER(bus)->node
+
 void build_cpu_to_node_map(void);
 
+#define SD_CPU_INIT (struct sched_domain) {		\
+	.span			= CPU_MASK_NONE,	\
+	.parent			= NULL,			\
+	.groups			= NULL,			\
+	.min_interval		= 1,			\
+	.max_interval		= 4,			\
+	.busy_factor		= 64,			\
+	.imbalance_pct		= 125,			\
+	.cache_hot_time		= (10*1000000),		\
+	.per_cpu_gain		= 100,			\
+	.cache_nice_tries	= 2,			\
+	.busy_idx		= 2,			\
+	.idle_idx		= 1,			\
+	.newidle_idx		= 2,			\
+	.wake_idx		= 1,			\
+	.forkexec_idx		= 1,			\
+	.flags			= SD_LOAD_BALANCE	\
+				| SD_BALANCE_NEWIDLE	\
+				| SD_BALANCE_EXEC	\
+				| SD_WAKE_AFFINE,	\
+	.last_balance		= jiffies,		\
+	.balance_interval	= 1,			\
+	.nr_balance_failed	= 0,			\
+}
+
 /* sched_domains SD_NODE_INIT for IA64 NUMA machines */
 #define SD_NODE_INIT (struct sched_domain) {		\
 	.span			= CPU_MASK_NONE,	\
 	.parent			= NULL,			\
 	.groups			= NULL,			\
-	.min_interval		= 80,			\
-	.max_interval		= 320,			\
-	.busy_factor		= 320,			\
+	.min_interval		= 8,			\
+	.max_interval		= 8*(min(num_online_cpus(), 32)), \
+	.busy_factor		= 64,			\
 	.imbalance_pct		= 125,			\
 	.cache_hot_time		= (10*1000000),		\
-	.cache_nice_tries	= 1,			\
+	.cache_nice_tries	= 2,			\
+	.busy_idx		= 3,			\
+	.idle_idx		= 2,			\
+	.newidle_idx		= 0, /* unused */	\
+	.wake_idx		= 1,			\
+	.forkexec_idx		= 1,			\
 	.per_cpu_gain		= 100,			\
 	.flags			= SD_LOAD_BALANCE	\
 				| SD_BALANCE_EXEC	\
-				| SD_BALANCE_NEWIDLE	\
-				| SD_WAKE_IDLE		\
+				| SD_BALANCE_FORK	\
 				| SD_WAKE_BALANCE,	\
 	.last_balance		= jiffies,		\
-	.balance_interval	= 1,			\
+	.balance_interval	= 64,			\
 	.nr_balance_failed	= 0,			\
 }
 
@@ -69,17 +103,21 @@ void build_cpu_to_node_map(void);
 	.span			= CPU_MASK_NONE,	\
 	.parent			= NULL,			\
 	.groups			= NULL,			\
-	.min_interval		= 80,			\
-	.max_interval		= 320,			\
-	.busy_factor		= 320,			\
-	.imbalance_pct		= 125,			\
+	.min_interval		= 64,			\
+	.max_interval		= 64*num_online_cpus(),	\
+	.busy_factor		= 128,			\
+	.imbalance_pct		= 133,			\
 	.cache_hot_time		= (10*1000000),		\
 	.cache_nice_tries	= 1,			\
+	.busy_idx		= 3,			\
+	.idle_idx		= 3,			\
+	.newidle_idx		= 0, /* unused */	\
+	.wake_idx		= 0, /* unused */	\
+	.forkexec_idx		= 0, /* unused */	\
 	.per_cpu_gain		= 100,			\
-	.flags			= SD_LOAD_BALANCE	\
-				| SD_BALANCE_EXEC,	\
+	.flags			= SD_LOAD_BALANCE,	\
 	.last_balance		= jiffies,		\
-	.balance_interval	= 100*(63+num_online_cpus())/64,   \
+	.balance_interval	= 64,			\
 	.nr_balance_failed	= 0,			\
 }
 
diff --git a/include/asm-ia64/uncached.h b/include/asm-ia64/uncached.h
new file mode 100644
--- /dev/null
+++ b/include/asm-ia64/uncached.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (C) 2001-2005 Silicon Graphics, Inc.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ *
+ * Prototypes for the uncached page allocator
+ */
+
+extern unsigned long uncached_alloc_page(int nid);
+extern void uncached_free_page(unsigned long);
diff --git a/include/asm-ia64/unistd.h b/include/asm-ia64/unistd.h
--- a/include/asm-ia64/unistd.h
+++ b/include/asm-ia64/unistd.h
@@ -263,6 +263,12 @@
 #define __NR_add_key			1271
 #define __NR_request_key		1272
 #define __NR_keyctl			1273
+#define __NR_ioprio_set			1274
+#define __NR_ioprio_get			1275
+#define __NR_set_zone_reclaim		1276
+#define __NR_inotify_init		1277
+#define __NR_inotify_add_watch		1278
+#define __NR_inotify_rm_watch		1279
 
 #ifdef __KERNEL__
 
diff --git a/include/asm-ia64/vga.h b/include/asm-ia64/vga.h
--- a/include/asm-ia64/vga.h
+++ b/include/asm-ia64/vga.h
@@ -14,7 +14,10 @@
  * videoram directly without any black magic.
  */
 
-#define VGA_MAP_MEM(x)	((unsigned long) ioremap((x), 0))
+extern unsigned long vga_console_iobase;
+extern unsigned long vga_console_membase;
+
+#define VGA_MAP_MEM(x)	((unsigned long) ioremap(vga_console_membase + (x), 0))
 
 #define vga_readb(x)	(*(x))
 #define vga_writeb(x,y)	(*(y) = (x))
diff --git a/include/asm-m32r/div64.h b/include/asm-m32r/div64.h
--- a/include/asm-m32r/div64.h
+++ b/include/asm-m32r/div64.h
@@ -1,38 +1 @@
-#ifndef _ASM_M32R_DIV64
-#define _ASM_M32R_DIV64
-
-/* $Id$ */
-
-/* unsigned long long division.
- * Input:
- *  unsigned long long  n
- *  unsigned long  base
- * Output:
- *  n = n / base;
- *  return value = n % base;
- */
-#define do_div(n, base)						\
-({								\
-	unsigned long _res, _high, _mid, _low;			\
-								\
-	_low = (n) & 0xffffffffUL;				\
-	_high = (n) >> 32;					\
-	if (_high) {						\
-		_mid = (_high % (unsigned long)(base)) << 16;	\
-		_high = _high / (unsigned long)(base);		\
-		_mid += _low >> 16;				\
-		_low &= 0x0000ffffUL;				\
-		_low += (_mid % (unsigned long)(base)) << 16;	\
-		_mid = _mid / (unsigned long)(base);		\
-		_res = _low % (unsigned long)(base);		\
-		_low = _low / (unsigned long)(base);		\
-		n = _low + ((long long)_mid << 16) +		\
-			((long long)_high << 32);		\
-	} else {						\
-		_res = _low % (unsigned long)(base);		\
-		n = (_low / (unsigned long)(base));		\
-	}							\
-	_res;							\
-})
-
-#endif  /* _ASM_M32R_DIV64 */
+#include <asm-generic/div64.h>
diff --git a/include/asm-m32r/emergency-restart.h b/include/asm-m32r/emergency-restart.h
new file mode 100644
--- /dev/null
+++ b/include/asm-m32r/emergency-restart.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_EMERGENCY_RESTART_H
+#define _ASM_EMERGENCY_RESTART_H
+
+#include <asm-generic/emergency-restart.h>
+
+#endif /* _ASM_EMERGENCY_RESTART_H */
diff --git a/include/asm-m32r/ide.h b/include/asm-m32r/ide.h
--- a/include/asm-m32r/ide.h
+++ b/include/asm-m32r/ide.h
@@ -35,7 +35,7 @@
 static __inline__ int ide_default_irq(unsigned long base)
 {
 	switch (base) {
-#if defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_MAPPI2)
+#if defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_MAPPI2) || defined(CONFIG_PLAT_MAPPI3)
 		case 0x1f0: return PLD_IRQ_CFIREQ;
 		default:
 			return 0;
diff --git a/include/asm-m32r/m32102.h b/include/asm-m32r/m32102.h
--- a/include/asm-m32r/m32102.h
+++ b/include/asm-m32r/m32102.h
@@ -175,6 +175,7 @@
 #define M32R_ICU_CR5_PORTL    (0x210+M32R_ICU_OFFSET)  /* INT4 */
 #define M32R_ICU_CR6_PORTL    (0x214+M32R_ICU_OFFSET)  /* INT5 */
 #define M32R_ICU_CR7_PORTL    (0x218+M32R_ICU_OFFSET)  /* INT6 */
+#define M32R_ICU_CR8_PORTL    (0x219+M32R_ICU_OFFSET)  /* INT7 */
 #define M32R_ICU_CR16_PORTL   (0x23C+M32R_ICU_OFFSET)  /* MFT0 */
 #define M32R_ICU_CR17_PORTL   (0x240+M32R_ICU_OFFSET)  /* MFT1 */
 #define M32R_ICU_CR18_PORTL   (0x244+M32R_ICU_OFFSET)  /* MFT2 */
diff --git a/include/asm-m32r/m32102peri.h b/include/asm-m32r/m32102peri.h
deleted file mode 100644
--- a/include/asm-m32r/m32102peri.h
+++ /dev/null
@@ -1,468 +0,0 @@
-/* $Id$
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2000,2001 by Hiroyuki Kondo
- */
-
-#ifndef __ASSEMBLY__
-
-typedef	void	V;
-typedef	char	B;
-typedef	short	S;
-typedef	int		W;
-typedef	long	L;
-typedef	float	F;
-typedef	double	D;
-typedef	unsigned char	UB;
-typedef	unsigned short	US;
-typedef	unsigned int	UW;
-typedef	unsigned long	UL;
-typedef	const unsigned int	CUW;
-
-/*********************************
-
-M32102 ICU
-
-*********************************/
-#define		ICUISTS		(UW *)0xa0EFF004
-#define		ICUIREQ0	(UW *)0xa0EFF008
-#define		ICUIREQ1	(UW *)0xa0EFF00C
-
-#define		ICUSBICR	(UW *)0xa0EFF018
-#define		ICUIMASK	(UW *)0xa0EFF01C
-
-#define		ICUCR1		(UW *)0xa0EFF200	/* INT0 */
-#define		ICUCR2		(UW *)0xa0EFF204	/* INT1 */
-#define		ICUCR3		(UW *)0xa0EFF208	/* INT2 */
-#define		ICUCR4		(UW *)0xa0EFF20C	/* INT3 */
-#define		ICUCR5		(UW *)0xa0EFF210	/* INT4 */
-#define		ICUCR6		(UW *)0xa0EFF214	/* INT5 */
-#define		ICUCR7		(UW *)0xa0EFF218	/* INT6 */
-
-#define		ICUCR16		(UW *)0xa0EFF23C	/* MFT0 */
-#define		ICUCR17		(UW *)0xa0EFF240	/* MFT1 */
-#define		ICUCR18		(UW *)0xa0EFF244	/* MFT2 */
-#define		ICUCR19		(UW *)0xa0EFF248	/* MFT3 */
-#define		ICUCR20		(UW *)0xa0EFF24C	/* MFT4 */
-#define		ICUCR21		(UW *)0xa0EFF250	/* MFT5 */
-
-#define		ICUCR32		(UW *)0xa0EFF27C	/* DMA0 */
-#define		ICUCR33		(UW *)0xa0EFF280	/* DMA1 */
-
-#define		ICUCR48		(UW *)0xa0EFF2BC	/* SIO0R */
-#define		ICUCR49		(UW *)0xa0EFF2C0	/* SIO0S */
-#define		ICUCR50		(UW *)0xa0EFF2C4	/* SIO1R */
-#define		ICUCR51		(UW *)0xa0EFF2C8	/* SIO1S */
-#define		ICUCR52		(UW *)0xa0EFF2CC	/* SIO2R */
-#define		ICUCR53		(UW *)0xa0EFF2D0	/* SIO2S */
-#define		ICUCR54		(UW *)0xa0EFF2D4	/* SIO3R */
-#define		ICUCR55		(UW *)0xa0EFF2D8	/* SIO3S */
-#define		ICUCR56		(UW *)0xa0EFF2DC	/* SIO4R */
-#define		ICUCR57		(UW *)0xa0EFF2E0	/* SIO4S */
-
-/*********************************
-
-M32102 MFT
-
-*********************************/
-#define		MFTCR		(US *)0xa0EFC002
-#define		MFTRPR		(UB *)0xa0EFC006
-
-#define		MFT0MOD		(US *)0xa0EFC102
-#define		MFT0BOS		(US *)0xa0EFC106
-#define		MFT0CUT		(US *)0xa0EFC10A
-#define		MFT0RLD		(US *)0xa0EFC10E
-#define		MFT0CRLD	(US *)0xa0EFC112
-
-#define		MFT1MOD		(US *)0xa0EFC202
-#define		MFT1BOS		(US *)0xa0EFC206
-#define		MFT1CUT		(US *)0xa0EFC20A
-#define		MFT1RLD		(US *)0xa0EFC20E
-#define		MFT1CRLD	(US *)0xa0EFC212
-
-#define		MFT2MOD		(US *)0xa0EFC302
-#define		MFT2BOS		(US *)0xa0EFC306
-#define		MFT2CUT		(US *)0xa0EFC30A
-#define		MFT2RLD		(US *)0xa0EFC30E
-#define		MFT2CRLD	(US *)0xa0EFC312
-
-#define		MFT3MOD		(US *)0xa0EFC402
-#define		MFT3CUT		(US *)0xa0EFC40A
-#define		MFT3RLD		(US *)0xa0EFC40E
-#define		MFT3CRLD	(US *)0xa0EFC412
-
-#define		MFT4MOD		(US *)0xa0EFC502
-#define		MFT4CUT		(US *)0xa0EFC50A
-#define		MFT4RLD		(US *)0xa0EFC50E
-#define		MFT4CRLD	(US *)0xa0EFC512
-
-#define		MFT5MOD		(US *)0xa0EFC602
-#define		MFT5CUT		(US *)0xa0EFC60A
-#define		MFT5RLD		(US *)0xa0EFC60E
-#define		MFT5CRLD	(US *)0xa0EFC612
-
-/*********************************
-
-M32102 SIO
-
-*********************************/
-
-#define SIO0CR     (volatile int *)0xa0efd000
-#define SIO0MOD0   (volatile int *)0xa0efd004
-#define SIO0MOD1   (volatile int *)0xa0efd008
-#define SIO0STS    (volatile int *)0xa0efd00c
-#define SIO0IMASK  (volatile int *)0xa0efd010
-#define SIO0BAUR   (volatile int *)0xa0efd014
-#define SIO0RBAUR  (volatile int *)0xa0efd018
-#define SIO0TXB    (volatile int *)0xa0efd01c
-#define SIO0RXB    (volatile int *)0xa0efd020
-
-#define SIO1CR     (volatile int *)0xa0efd100
-#define SIO1MOD0   (volatile int *)0xa0efd104
-#define SIO1MOD1   (volatile int *)0xa0efd108
-#define SIO1STS    (volatile int *)0xa0efd10c
-#define SIO1IMASK  (volatile int *)0xa0efd110
-#define SIO1BAUR   (volatile int *)0xa0efd114
-#define SIO1RBAUR  (volatile int *)0xa0efd118
-#define SIO1TXB    (volatile int *)0xa0efd11c
-#define SIO1RXB    (volatile int *)0xa0efd120
-/*********************************
-
-M32102 PORT
-
-*********************************/
-#define		PIEN		(UB *)0xa0EF1003	/* input enable */
-
-#define		P0DATA		(UB *)0xa0EF1020	/* data */
-#define		P1DATA		(UB *)0xa0EF1021
-#define		P2DATA		(UB *)0xa0EF1022
-#define		P3DATA		(UB *)0xa0EF1023
-#define		P4DATA		(UB *)0xa0EF1024
-#define		P5DATA		(UB *)0xa0EF1025
-#define		P6DATA		(UB *)0xa0EF1026
-#define		P7DATA		(UB *)0xa0EF1027
-
-#define		P0DIR		(UB *)0xa0EF1040	/* direction */
-#define		P1DIR		(UB *)0xa0EF1041
-#define		P2DIR		(UB *)0xa0EF1042
-#define		P3DIR		(UB *)0xa0EF1043
-#define		P4DIR		(UB *)0xa0EF1044
-#define		P5DIR		(UB *)0xa0EF1045
-#define		P6DIR		(UB *)0xa0EF1046
-#define		P7DIR		(UB *)0xa0EF1047
-
-#define		P0MOD		(US *)0xa0EF1060	/* mode control */
-#define		P1MOD		(US *)0xa0EF1062
-#define		P2MOD		(US *)0xa0EF1064
-#define		P3MOD		(US *)0xa0EF1066
-#define		P4MOD		(US *)0xa0EF1068
-#define		P5MOD		(US *)0xa0EF106A
-#define		P6MOD		(US *)0xa0EF106C
-#define		P7MOD		(US *)0xa0EF106E
-
-#define		P0ODCR		(UB *)0xa0EF1080	/* open-drain control */
-#define		P1ODCR		(UB *)0xa0EF1081
-#define		P2ODCR		(UB *)0xa0EF1082
-#define		P3ODCR		(UB *)0xa0EF1083
-#define		P4ODCR		(UB *)0xa0EF1084
-#define		P5ODCR		(UB *)0xa0EF1085
-#define		P6ODCR		(UB *)0xa0EF1086
-#define		P7ODCR		(UB *)0xa0EF1087
-
-/*********************************
-
-M32102 Cache
-
-********************************/
-
-#define		MCCR	(US *)0xFFFFFFFE
-
-
-#else  /* __ASSEMBLY__ */
-
-;;
-;; PIO     0x80ef1000
-;;
-
-#define PIEN          0xa0ef1000
-
-#define P0DATA        0xa0ef1020
-#define P1DATA        0xa0ef1021
-#define P2DATA        0xa0ef1022
-#define P3DATA        0xa0ef1023
-#define P4DATA        0xa0ef1024
-#define P5DATA        0xa0ef1025
-#define P6DATA        0xa0ef1026
-#define P7DATA        0xa0ef1027
-
-#define P0DIR         0xa0ef1040
-#define P1DIR         0xa0ef1041
-#define P2DIR         0xa0ef1042
-#define P3DIR         0xa0ef1043
-#define P4DIR         0xa0ef1044
-#define P5DIR         0xa0ef1045
-#define P6DIR         0xa0ef1046
-#define P7DIR         0xa0ef1047
-
-#define P0MOD         0xa0ef1060
-#define P1MOD         0xa0ef1062
-#define P2MOD         0xa0ef1064
-#define P3MOD         0xa0ef1066
-#define P4MOD         0xa0ef1068
-#define P5MOD         0xa0ef106a
-#define P6MOD         0xa0ef106c
-#define P7MOD         0xa0ef106e
-;
-#define P0ODCR        0xa0ef1080
-#define P1ODCR        0xa0ef1081
-#define P2ODCR        0xa0ef1082
-#define P3ODCR        0xa0ef1083
-#define P4ODCR        0xa0ef1084
-#define P5ODCR        0xa0ef1085
-#define P6ODCR        0xa0ef1086
-#define P7ODCR        0xa0ef1087
-
-;;
-;; WDT     0xa0ef2000
-;;
-
-#define WDTCR         0xa0ef2000
-
-
-;;
-;; CLK     0xa0ef4000
-;;
-
-#define CPUCLKCR      0xa0ef4000
-#define CLKMOD        0xa0ef4004
-#define PLLCR         0xa0ef4008
-
-
-;;
-;; BSEL    0xa0ef5000
-;;
-
-#define BSEL0CR       0xa0ef5000
-#define BSEL1CR       0xa0ef5004
-#define BSEL2CR       0xa0ef5008
-#define BSEL3CR       0xa0ef500c
-#define BSEL4CR       0xa0ef5010
-#define BSEL5CR       0xa0ef5014
-
-
-;;
-;; SDRAMC  0xa0ef6000
-;;
-
-#define SDRF0         0xa0ef6000
-#define SDRF1         0xa0ef6004
-#define SDIR0         0xa0ef6008
-#define SDIR1         0xa0ef600c
-#define SDBR          0xa0ef6010
-
-;; CH0
-#define SD0ADR        0xa0ef6020
-#define SD0SZ         0xa0ef6022
-#define SD0ER         0xa0ef6024
-#define SD0TR         0xa0ef6028
-#define SD0MOD        0xa0ef602c
-
-;; CH1
-#define SD1ADR        0xa0ef6040
-#define SD1SZ         0xa0ef6042
-#define SD1ER         0xa0ef6044
-#define SD1TR         0xa0ef6048
-#define SD1MOD        0xa0ef604c
-
-
-;;
-;; DMAC    0xa0ef8000
-;;
-
-#define DMAEN         0xa0ef8000
-#define DMAISTS       0xa0ef8004
-#define DMAEDET       0xa0ef8008
-#define DMAASTS       0xa0ef800c
-
-;; CH0
-#define DMA0CR0       0xa0ef8100
-#define DMA0CR1       0xa0ef8104
-#define DMA0CSA       0xa0ef8108
-#define DMA0RSA       0xa0ef810c
-#define DMA0CDA       0xa0ef8110
-#define DMA0RDA       0xa0ef8114
-#define DMA0CBCUT     0xa0ef8118
-#define DMA0RBCUT     0xa0ef811c
-
-;; CH1
-#define DMA1CR0       0xa0ef8200
-#define DMA1CR1       0xa0ef8204
-#define DMA1CSA       0xa0ef8208
-#define DMA1RSA       0xa0ef820c
-#define DMA1CDA       0xa0ef8210
-#define DMA1RDA       0xa0ef8214
-#define DMA1CBCUT     0xa0ef8218
-#define DMA1RBCUT     0xa0ef821c
-
-
-;;
-;; MFT     0xa0efc000
-;;
-
-#define MFTCR        0xa0efc000
-#define MFTRPR       0xa0efc004
-
-;; CH0
-#define MFT0MOD      0xa0efc100
-#define MFT0BOS      0xa0efc104
-#define MFT0CUT      0xa0efc108
-#define MFT0RLD      0xa0efc10c
-#define MFT0CMPRLD   0xa0efc110
-
-;; CH1
-#define MFT1MOD      0xa0efc200
-#define MFT1BOS      0xa0efc204
-#define MFT1CUT      0xa0efc208
-#define MFT1RLD      0xa0efc20c
-#define MFT1CMPRLD   0xa0efc210
-
-;; CH2
-#define MFT2MOD      0xa0efc300
-#define MFT2BOS      0xa0efc304
-#define MFT2CUT      0xa0efc308
-#define MFT2RLD      0xa0efc30c
-#define MFT2CMPRLD   0xa0efc310
-
-;; CH3
-#define MFT3MOD      0xa0efc400
-#define MFT3BOS      0xa0efc404
-#define MFT3CUT      0xa0efc408
-#define MFT3RLD      0xa0efc40c
-#define MFT3CMPRLD   0xa0efc410
-
-;; CH4
-#define MFT4MOD      0xa0efc500
-#define MFT4BOS      0xa0efc504
-#define MFT4CUT      0xa0efc508
-#define MFT4RLD      0xa0efc50c
-#define MFT4CMPRLD   0xa0efc510
-
-;; CH5
-#define MFT5MOD      0xa0efc600
-#define MFT5BOS      0xa0efc604
-#define MFT5CUT      0xa0efc608
-#define MFT5RLD      0xa0efc60c
-#define MFT5CMPRLD   0xa0efc610
-
-
-;;
-;; SIO     0xa0efd000
-;;
-
-;; CH0
-#define SIO0CR        0xa0efd000
-#define SIO0MOD0      0xa0efd004
-#define SIO0MOD1      0xa0efd008
-#define SIO0STS       0xa0efd00c
-#define SIO0IMASK     0xa0efd010
-#define SIO0BAUR      0xa0efd014
-#define SIO0RBAUR     0xa0efd018
-#define SIO0TXB       0xa0efd01c
-#define SIO0RXB       0xa0efd020
-
-;; CH1
-#define SIO1CR        0xa0efd100
-#define SIO1MOD0      0xa0efd104
-#define SIO1MOD1      0xa0efd108
-#define SIO1STS       0xa0efd10c
-#define SIO1IMASK     0xa0efd110
-#define SIO1BAUR      0xa0efd114
-#define SIO1RBAUR     0xa0efd118
-#define SIO1TXB       0xa0efd11c
-#define SIO1RXB       0xa0efd120
-
-;; CH2
-#define SIO2CR        0xa0efd200
-#define SIO2MOD0      0xa0efd204
-#define SIO2MOD1      0xa0efd208
-#define SIO2STS       0xa0efd20c
-#define SIO2IMASK     0xa0efd210
-#define SIO2BAUR      0xa0efd214
-#define SIO2RBAUR     0xa0efd218
-#define SIO2TXB       0xa0efd21c
-#define SIO2RXB       0xa0efd220
-
-;; CH3
-#define SIO3CR        0xa0efd300
-#define SIO3MOD0      0xa0efd304
-#define SIO3MOD1      0xa0efd308
-#define SIO3STS       0xa0efd30c
-#define SIO3IMASK     0xa0efd310
-#define SIO3BAUR      0xa0efd314
-#define SIO3RBAUR     0xa0efd318
-#define SIO3TXB       0xa0efd31c
-#define SIO3RXB       0xa0efd320
-
-;; CH4
-#define SIO4CR        0xa0efd400
-#define SIO4MOD0      0xa0efd404
-#define SIO4MOD1      0xa0efd408
-#define SIO4STS       0xa0efd40c
-#define SIO4IMASK     0xa0efd410
-#define SIO4BAUR      0xa0efd414
-#define SIO4RBAUR     0xa0efd418
-#define SIO4TXB       0xa0efd41c
-#define SIO4RXB       0xa0efd420
-
-
-;;
-;; ICU     0xa0eff000
-;;
-
-#define ICUISTS       0xa0eff004
-#define ICUIREQ0      0xa0eff008
-#define ICUIREQ1      0xa0eff00c
-
-#define ICUSBICR      0xa0eff018
-#define ICUIMASK      0xa0eff01c
-
-#define ICUCR1        0xa0eff200
-#define ICUCR2        0xa0eff204
-#define ICUCR3        0xa0eff208
-#define ICUCR4        0xa0eff20c
-#define ICUCR5        0xa0eff210
-#define ICUCR6        0xa0eff214
-#define ICUCR7        0xa0eff218
-
-#define ICUCR16       0xa0eff23c
-#define ICUCR17       0xa0eff240
-#define ICUCR18       0xa0eff244
-#define ICUCR19       0xa0eff248
-#define ICUCR20       0xa0eff24c
-#define ICUCR21       0xa0eff250
-
-#define ICUCR32       0xa0eff27c
-#define ICUCR33       0xa0eff280
-
-#define ICUCR48       0xa0eff2bc
-#define ICUCR49       0xa0eff2c0
-#define ICUCR50       0xa0eff2c4
-#define ICUCR51       0xa0eff2c8
-#define ICUCR52       0xa0eff2cc
-#define ICUCR53       0xa0eff2d0
-#define ICUCR54       0xa0eff2d4
-#define ICUCR55       0xa0eff2d8
-#define ICUCR56       0xa0eff2dc
-#define ICUCR57       0xa0eff2e0
-
-;;
-;; CACHE
-;;
-
-#define MCCR		  0xfffffffc
-
-
-#endif  /* __ASSEMBLY__ */
diff --git a/include/asm-m32r/m32r.h b/include/asm-m32r/m32r.h
--- a/include/asm-m32r/m32r.h
+++ b/include/asm-m32r/m32r.h
@@ -16,7 +16,6 @@
 	|| defined(CONFIG_CHIP_M32700) || defined(CONFIG_CHIP_M32102) \
         || defined(CONFIG_CHIP_OPSP)
 #include <asm/m32102.h>
-#include <asm/m32102peri.h>
 #endif
 
 /* Platform type */
@@ -36,6 +35,10 @@
 #include <asm/mappi2/mappi2_pld.h>
 #endif	/* CONFIG_PLAT_MAPPI2 */
 
+#if defined(CONFIG_PLAT_MAPPI3)
+#include <asm/mappi3/mappi3_pld.h>
+#endif	/* CONFIG_PLAT_MAPPI3 */
+
 #if defined(CONFIG_PLAT_USRV)
 #include <asm/m32700ut/m32700ut_pld.h>
 #endif
diff --git a/include/asm-m32r/mappi3/mappi3_pld.h b/include/asm-m32r/mappi3/mappi3_pld.h
new file mode 100644
--- /dev/null
+++ b/include/asm-m32r/mappi3/mappi3_pld.h
@@ -0,0 +1,143 @@
+/*
+ * include/asm/mappi3/mappi3_pld.h
+ *
+ * Definitions for Extended IO Logic on MAPPI3 board.
+ *  based on m32700ut_pld.h
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file "COPYING" in the main directory of
+ * this archive for more details.
+ *
+ */
+
+#ifndef _MAPPI3_PLD_H
+#define _MAPPI3_PLD_H
+
+#ifndef __ASSEMBLY__
+/* FIXME:
+ * Some C functions use non-cache address, so can't define non-cache address.
+ */
+#define PLD_BASE		(0x1c000000 /* + NONCACHE_OFFSET */)
+#define __reg8			(volatile unsigned char *)
+#define __reg16			(volatile unsigned short *)
+#define __reg32			(volatile unsigned int *)
+#else
+#define PLD_BASE		(0x1c000000 + NONCACHE_OFFSET)
+#define __reg8
+#define __reg16
+#define __reg32
+#endif	/* __ASSEMBLY__ */
+
+/* CFC */
+#define	PLD_CFRSTCR		__reg16(PLD_BASE + 0x0000)
+#define PLD_CFSTS		__reg16(PLD_BASE + 0x0002)
+#define PLD_CFIMASK		__reg16(PLD_BASE + 0x0004)
+#define PLD_CFBUFCR		__reg16(PLD_BASE + 0x0006)
+#define PLD_CFCR0		__reg16(PLD_BASE + 0x000a)
+#define PLD_CFCR1		__reg16(PLD_BASE + 0x000c)
+
+/* MMC */
+#define PLD_MMCCR		__reg16(PLD_BASE + 0x4000)
+#define PLD_MMCMOD		__reg16(PLD_BASE + 0x4002)
+#define PLD_MMCSTS		__reg16(PLD_BASE + 0x4006)
+#define PLD_MMCBAUR		__reg16(PLD_BASE + 0x400a)
+#define PLD_MMCCMDBCUT		__reg16(PLD_BASE + 0x400c)
+#define PLD_MMCCDTBCUT		__reg16(PLD_BASE + 0x400e)
+#define PLD_MMCDET		__reg16(PLD_BASE + 0x4010)
+#define PLD_MMCWP		__reg16(PLD_BASE + 0x4012)
+#define PLD_MMCWDATA		__reg16(PLD_BASE + 0x5000)
+#define PLD_MMCRDATA		__reg16(PLD_BASE + 0x6000)
+#define PLD_MMCCMDDATA		__reg16(PLD_BASE + 0x7000)
+#define PLD_MMCRSPDATA		__reg16(PLD_BASE + 0x7006)
+
+/* Power Control of MMC and CF */
+#define PLD_CPCR		__reg16(PLD_BASE + 0x14000)
+
+
+/*==== ICU ====*/
+#define  M32R_IRQ_PC104        (5)   /* INT4(PC/104) */
+#define  M32R_IRQ_I2C          (28)  /* I2C-BUS     */
+#define  PLD_IRQ_CFIREQ       (6)  /* INT5 CFC Card Interrupt */
+#define  PLD_IRQ_CFC_INSERT   (7)  /* INT6 CFC Card Insert */
+#define  PLD_IRQ_CFC_EJECT    (8)  /* INT7 CFC Card Eject */
+#define  PLD_IRQ_MMCCARD      (43)  /* MMC Card Insert */
+#define  PLD_IRQ_MMCIRQ       (44)  /* MMC Transfer Done */
+
+
+#if 0
+/* LED Control
+ *
+ * 1: DIP swich side
+ * 2: Reset switch side
+ */
+#define PLD_IOLEDCR		__reg16(PLD_BASE + 0x14002)
+#define PLD_IOLED_1_ON		0x001
+#define PLD_IOLED_1_OFF		0x000
+#define PLD_IOLED_2_ON		0x002
+#define PLD_IOLED_2_OFF		0x000
+
+/* DIP Switch
+ *  0: Write-protect of Flash Memory (0:protected, 1:non-protected)
+ *  1: -
+ *  2: -
+ *  3: -
+ */
+#define PLD_IOSWSTS		__reg16(PLD_BASE + 0x14004)
+#define	PLD_IOSWSTS_IOSW2	0x0200
+#define	PLD_IOSWSTS_IOSW1	0x0100
+#define	PLD_IOSWSTS_IOWP0	0x0001
+
+#endif
+
+/* CRC */
+#define PLD_CRC7DATA		__reg16(PLD_BASE + 0x18000)
+#define PLD_CRC7INDATA		__reg16(PLD_BASE + 0x18002)
+#define PLD_CRC16DATA		__reg16(PLD_BASE + 0x18004)
+#define PLD_CRC16INDATA		__reg16(PLD_BASE + 0x18006)
+#define PLD_CRC16ADATA		__reg16(PLD_BASE + 0x18008)
+#define PLD_CRC16AINDATA	__reg16(PLD_BASE + 0x1800a)
+
+
+#if 0
+/* RTC */
+#define PLD_RTCCR		__reg16(PLD_BASE + 0x1c000)
+#define PLD_RTCBAUR		__reg16(PLD_BASE + 0x1c002)
+#define PLD_RTCWRDATA		__reg16(PLD_BASE + 0x1c004)
+#define PLD_RTCRDDATA		__reg16(PLD_BASE + 0x1c006)
+#define PLD_RTCRSTODT		__reg16(PLD_BASE + 0x1c008)
+
+/* SIO0 */
+#define PLD_ESIO0CR		__reg16(PLD_BASE + 0x20000)
+#define	PLD_ESIO0CR_TXEN	0x0001
+#define	PLD_ESIO0CR_RXEN	0x0002
+#define PLD_ESIO0MOD0		__reg16(PLD_BASE + 0x20002)
+#define	PLD_ESIO0MOD0_CTSS	0x0040
+#define	PLD_ESIO0MOD0_RTSS	0x0080
+#define PLD_ESIO0MOD1		__reg16(PLD_BASE + 0x20004)
+#define	PLD_ESIO0MOD1_LMFS	0x0010
+#define PLD_ESIO0STS		__reg16(PLD_BASE + 0x20006)
+#define	PLD_ESIO0STS_TEMP	0x0001
+#define	PLD_ESIO0STS_TXCP	0x0002
+#define	PLD_ESIO0STS_RXCP	0x0004
+#define	PLD_ESIO0STS_TXSC	0x0100
+#define	PLD_ESIO0STS_RXSC	0x0200
+#define PLD_ESIO0STS_TXREADY	(PLD_ESIO0STS_TXCP | PLD_ESIO0STS_TEMP)
+#define PLD_ESIO0INTCR		__reg16(PLD_BASE + 0x20008)
+#define	PLD_ESIO0INTCR_TXIEN	0x0002
+#define	PLD_ESIO0INTCR_RXCEN	0x0004
+#define PLD_ESIO0BAUR		__reg16(PLD_BASE + 0x2000a)
+#define PLD_ESIO0TXB		__reg16(PLD_BASE + 0x2000c)
+#define PLD_ESIO0RXB		__reg16(PLD_BASE + 0x2000e)
+
+/* SIM Card */
+#define PLD_SCCR		__reg16(PLD_BASE + 0x38000)
+#define PLD_SCMOD		__reg16(PLD_BASE + 0x38004)
+#define PLD_SCSTS		__reg16(PLD_BASE + 0x38006)
+#define PLD_SCINTCR		__reg16(PLD_BASE + 0x38008)
+#define PLD_SCBAUR		__reg16(PLD_BASE + 0x3800a)
+#define PLD_SCTXB		__reg16(PLD_BASE + 0x3800c)
+#define PLD_SCRXB		__reg16(PLD_BASE + 0x3800e)
+
+#endif
+
+#endif	/* _MAPPI3_PLD.H */
diff --git a/include/asm-m32r/mmzone.h b/include/asm-m32r/mmzone.h
--- a/include/asm-m32r/mmzone.h
+++ b/include/asm-m32r/mmzone.h
@@ -14,7 +14,6 @@ extern struct pglist_data *node_data[];
 #define NODE_DATA(nid)		(node_data[nid])
 
 #define node_localnr(pfn, nid)	((pfn) - NODE_DATA(nid)->node_start_pfn)
-#define node_mem_map(nid)	(NODE_DATA(nid)->node_mem_map)
 #define node_start_pfn(nid)	(NODE_DATA(nid)->node_start_pfn)
 #define node_end_pfn(nid)						\
 ({									\
@@ -32,7 +31,7 @@ extern struct pglist_data *node_data[];
 ({									\
 	unsigned long __pfn = pfn;					\
 	int __node  = pfn_to_nid(__pfn);				\
-	&node_mem_map(__node)[node_localnr(__pfn,__node)];		\
+	&NODE_DATA(__node)->node_mem_map[node_localnr(__pfn,__node)];	\
 })
 
 #define page_to_pfn(pg)							\
diff --git a/include/asm-m32r/s1d13806.h b/include/asm-m32r/s1d13806.h
new file mode 100644
--- /dev/null
+++ b/include/asm-m32r/s1d13806.h
@@ -0,0 +1,199 @@
+//----------------------------------------------------------------------------
+//
+//  File generated by S1D13806CFG.EXE
+//
+//  Copyright (c) 2000,2001 Epson Research and Development, Inc.
+//  All rights reserved.
+//
+//----------------------------------------------------------------------------
+
+// Panel:  (active)  640x480 77Hz STN Single 8-bit (PCLK=CLKI=25.175MHz)
+// Memory: Embedded SDRAM (MCLK=CLKI3=50.000MHz) (BUSCLK=33.333MHz)
+
+#define SWIVEL_VIEW		0	/* 0:none, 1:90 not completed */
+
+static struct s1d13xxxfb_regval s1d13xxxfb_initregs[] = {
+
+    {0x0001,0x00},   // Miscellaneous Register
+    {0x01FC,0x00},   // Display Mode Register
+#if defined(CONFIG_PLAT_MAPPI)
+    {0x0004,0x00},   // General IO Pins Configuration Register 0
+    {0x0005,0x00},   // General IO Pins Configuration Register 1
+    {0x0008,0x00},   // General IO Pins Control Register 0
+    {0x0009,0x00},   // General IO Pins Control Register 1
+    {0x0010,0x00},   // Memory Clock Configuration Register
+    {0x0014,0x00},   // LCD Pixel Clock Configuration Register
+    {0x0018,0x00},   // CRT/TV Pixel Clock Configuration Register
+    {0x001C,0x00},   // MediaPlug Clock Configuration Register
+/*
+ * .. 10MHz: 0x00
+ * .. 30MHz: 0x01
+ * 30MHz ..: 0x02
+ */
+    {0x001E,0x02},   // CPU To Memory Wait State Select Register
+    {0x0021,0x02},   // DRAM Refresh Rate Register
+    {0x002A,0x11},   // DRAM Timings Control Register 0
+    {0x002B,0x13},   // DRAM Timings Control Register 1
+    {0x0020,0x80},   // Memory Configuration Register
+    {0x0030,0x25},   // Panel Type Register
+    {0x0031,0x00},   // MOD Rate Register
+    {0x0032,0x4F},   // LCD Horizontal Display Width Register
+    {0x0034,0x12},   // LCD Horizontal Non-Display Period Register
+    {0x0035,0x01},   // TFT FPLINE Start Position Register
+    {0x0036,0x0B},   // TFT FPLINE Pulse Width Register
+    {0x0038,0xDF},   // LCD Vertical Display Height Register 0
+    {0x0039,0x01},   // LCD Vertical Display Height Register 1
+    {0x003A,0x2C},   // LCD Vertical Non-Display Period Register
+    {0x003B,0x0A},   // TFT FPFRAME Start Position Register
+    {0x003C,0x01},   // TFT FPFRAME Pulse Width Register
+
+    {0x0041,0x00},   // LCD Miscellaneous Register
+    {0x0042,0x00},   // LCD Display Start Address Register 0
+    {0x0043,0x00},   // LCD Display Start Address Register 1
+    {0x0044,0x00},   // LCD Display Start Address Register 2
+
+#elif defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_OPSPUT) || defined(CONFIG_PLAT_MAPPI3)
+    {0x0004,0x07},   // GPIO[0:7] direction
+    {0x0005,0x00},   // GPIO[8:12] direction
+    {0x0008,0x00},   // GPIO[0:7] data
+    {0x0009,0x00},   // GPIO[8:12] data
+    {0x0008,0x04},   // LCD panel Vcc on
+    {0x0008,0x05},   // LCD panel reset
+    {0x0010,0x01},   // Memory Clock Configuration Register
+    {0x0014,0x30},   // LCD Pixel Clock Configuration Register (CLKI 22MHz/4)
+    {0x0018,0x00},   // CRT/TV Pixel Clock Configuration Register
+    {0x001C,0x00},   // MediaPlug Clock Configuration Register(10MHz)
+    {0x001E,0x00},   // CPU To Memory Wait State Select Register
+    {0x0020,0x80},   // Memory Configuration Register
+    {0x0021,0x03},   // DRAM Refresh Rate Register
+    {0x002A,0x00},   // DRAM Timings Control Register 0
+    {0x002B,0x01},   // DRAM Timings Control Register 1
+    {0x0030,0x25},   // Panel Type Register
+    {0x0031,0x00},   // MOD Rate Register
+    {0x0032,0x1d},   // LCD Horizontal Display Width Register
+    {0x0034,0x05},   // LCD Horizontal Non-Display Period Register
+    {0x0035,0x01},   // TFT FPLINE Start Position Register
+    {0x0036,0x01},   // TFT FPLINE Pulse Width Register
+    {0x0038,0x3F},   // LCD Vertical Display Height Register 0
+    {0x0039,0x01},   // LCD Vertical Display Height Register 1
+    {0x003A,0x0b},   // LCD Vertical Non-Display Period Register
+    {0x003B,0x07},   // TFT FPFRAME Start Position Register
+    {0x003C,0x02},   // TFT FPFRAME Pulse Width Register
+
+    {0x0041,0x00},   // LCD Miscellaneous Register
+#if (SWIVEL_VIEW == 0)
+    {0x0042,0x00},   // LCD Display Start Address Register 0
+    {0x0043,0x00},   // LCD Display Start Address Register 1
+    {0x0044,0x00},   // LCD Display Start Address Register 2
+
+#elif (SWIVEL_VIEW == 1)
+    // 1024 - W(320) = 0x2C0
+    {0x0042,0xC0},   // LCD Display Start Address Register 0
+    {0x0043,0x02},   // LCD Display Start Address Register 1
+    {0x0044,0x00},   // LCD Display Start Address Register 2
+    // 1024
+    {0x0046,0x00},   // LCD Memory Address Offset Register 0
+    {0x0047,0x02},   // LCD Memory Address Offset Register 1
+#else
+#error unsupported SWIVEL_VIEW mode
+#endif
+#else
+#error no platform configuration
+#endif  /* CONFIG_PLAT_XXX */
+
+    {0x0048,0x00},   // LCD Pixel Panning Register
+    {0x004A,0x00},   // LCD Display FIFO High Threshold Control Register
+    {0x004B,0x00},   // LCD Display FIFO Low Threshold Control Register
+    {0x0050,0x4F},   // CRT/TV Horizontal Display Width Register
+    {0x0052,0x13},   // CRT/TV Horizontal Non-Display Period Register
+    {0x0053,0x01},   // CRT/TV HRTC Start Position Register
+    {0x0054,0x0B},   // CRT/TV HRTC Pulse Width Register
+    {0x0056,0xDF},   // CRT/TV Vertical Display Height Register 0
+    {0x0057,0x01},   // CRT/TV Vertical Display Height Register 1
+    {0x0058,0x2B},   // CRT/TV Vertical Non-Display Period Register
+    {0x0059,0x09},   // CRT/TV VRTC Start Position Register
+    {0x005A,0x01},   // CRT/TV VRTC Pulse Width Register
+    {0x005B,0x10},   // TV Output Control Register
+
+    {0x0062,0x00},   // CRT/TV Display Start Address Register 0
+    {0x0063,0x00},   // CRT/TV Display Start Address Register 1
+    {0x0064,0x00},   // CRT/TV Display Start Address Register 2
+
+    {0x0068,0x00},   // CRT/TV Pixel Panning Register
+    {0x006A,0x00},   // CRT/TV Display FIFO High Threshold Control Register
+    {0x006B,0x00},   // CRT/TV Display FIFO Low Threshold Control Register
+    {0x0070,0x00},   // LCD Ink/Cursor Control Register
+    {0x0071,0x01},   // LCD Ink/Cursor Start Address Register
+    {0x0072,0x00},   // LCD Cursor X Position Register 0
+    {0x0073,0x00},   // LCD Cursor X Position Register 1
+    {0x0074,0x00},   // LCD Cursor Y Position Register 0
+    {0x0075,0x00},   // LCD Cursor Y Position Register 1
+    {0x0076,0x00},   // LCD Ink/Cursor Blue Color 0 Register
+    {0x0077,0x00},   // LCD Ink/Cursor Green Color 0 Register
+    {0x0078,0x00},   // LCD Ink/Cursor Red Color 0 Register
+    {0x007A,0x1F},   // LCD Ink/Cursor Blue Color 1 Register
+    {0x007B,0x3F},   // LCD Ink/Cursor Green Color 1 Register
+    {0x007C,0x1F},   // LCD Ink/Cursor Red Color 1 Register
+    {0x007E,0x00},   // LCD Ink/Cursor FIFO Threshold Register
+    {0x0080,0x00},   // CRT/TV Ink/Cursor Control Register
+    {0x0081,0x01},   // CRT/TV Ink/Cursor Start Address Register
+    {0x0082,0x00},   // CRT/TV Cursor X Position Register 0
+    {0x0083,0x00},   // CRT/TV Cursor X Position Register 1
+    {0x0084,0x00},   // CRT/TV Cursor Y Position Register 0
+    {0x0085,0x00},   // CRT/TV Cursor Y Position Register 1
+    {0x0086,0x00},   // CRT/TV Ink/Cursor Blue Color 0 Register
+    {0x0087,0x00},   // CRT/TV Ink/Cursor Green Color 0 Register
+    {0x0088,0x00},   // CRT/TV Ink/Cursor Red Color 0 Register
+    {0x008A,0x1F},   // CRT/TV Ink/Cursor Blue Color 1 Register
+    {0x008B,0x3F},   // CRT/TV Ink/Cursor Green Color 1 Register
+    {0x008C,0x1F},   // CRT/TV Ink/Cursor Red Color 1 Register
+    {0x008E,0x00},   // CRT/TV Ink/Cursor FIFO Threshold Register
+    {0x0100,0x00},   // BitBlt Control Register 0
+    {0x0101,0x00},   // BitBlt Control Register 1
+    {0x0102,0x00},   // BitBlt ROP Code/Color Expansion Register
+    {0x0103,0x00},   // BitBlt Operation Register
+    {0x0104,0x00},   // BitBlt Source Start Address Register 0
+    {0x0105,0x00},   // BitBlt Source Start Address Register 1
+    {0x0106,0x00},   // BitBlt Source Start Address Register 2
+    {0x0108,0x00},   // BitBlt Destination Start Address Register 0
+    {0x0109,0x00},   // BitBlt Destination Start Address Register 1
+    {0x010A,0x00},   // BitBlt Destination Start Address Register 2
+    {0x010C,0x00},   // BitBlt Memory Address Offset Register 0
+    {0x010D,0x00},   // BitBlt Memory Address Offset Register 1
+    {0x0110,0x00},   // BitBlt Width Register 0
+    {0x0111,0x00},   // BitBlt Width Register 1
+    {0x0112,0x00},   // BitBlt Height Register 0
+    {0x0113,0x00},   // BitBlt Height Register 1
+    {0x0114,0x00},   // BitBlt Background Color Register 0
+    {0x0115,0x00},   // BitBlt Background Color Register 1
+    {0x0118,0x00},   // BitBlt Foreground Color Register 0
+    {0x0119,0x00},   // BitBlt Foreground Color Register 1
+    {0x01E0,0x00},   // Look-Up Table Mode Register
+    {0x01E2,0x00},   // Look-Up Table Address Register
+    {0x01F0,0x10},   // Power Save Configuration Register
+    {0x01F1,0x00},   // Power Save Status Register
+    {0x01F4,0x00},   // CPU-to-Memory Access Watchdog Timer Register
+#if (SWIVEL_VIEW == 0)
+    {0x01FC,0x01},   // Display Mode Register(0x01:LCD, 0x02:CRT, 0x03:LCD&CRT)
+#elif (SWIVEL_VIEW == 1)
+    {0x01FC,0x41},   // Display Mode Register(0x01:LCD, 0x02:CRT, 0x03:LCD&CRT)
+#else
+#error unsupported SWIVEL_VIEW mode
+#endif  /* SWIVEL_VIEW */
+
+#if defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_OPSPUT) || defined(CONFIG_PLAT_MAPPI3)
+    {0x0008,0x07},   // LCD panel Vdd & Vg on
+#endif
+
+    {0x0040,0x05},   // LCD Display Mode Register (2:4bpp,3:8bpp,5:16bpp)
+#if defined(CONFIG_PLAT_MAPPI)
+    {0x0046,0x80},   // LCD Memory Address Offset Register 0
+    {0x0047,0x02},   // LCD Memory Address Offset Register 1
+#elif defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_OPSPUT) || defined(CONFIG_PLAT_MAPPI3)
+    {0x0046,0xf0},   // LCD Memory Address Offset Register 0
+    {0x0047,0x00},   // LCD Memory Address Offset Register 1
+#endif
+    {0x0060,0x05},   // CRT/TV Display Mode Register (2:4bpp,3:8bpp,5:16bpp)
+    {0x0066,0x80},   // CRT/TV Memory Address Offset Register 0	// takeo
+    {0x0067,0x02},   // CRT/TV Memory Address Offset Register 1
+};
diff --git a/include/asm-m32r/smp.h b/include/asm-m32r/smp.h
--- a/include/asm-m32r/smp.h
+++ b/include/asm-m32r/smp.h
@@ -61,12 +61,10 @@ extern physid_mask_t phys_cpu_present_ma
  * Some lowlevel functions might want to know about
  * the real CPU ID <-> CPU # mapping.
  */
-extern volatile int physid_2_cpu[NR_CPUS];
 extern volatile int cpu_2_physid[NR_CPUS];
-#define physid_to_cpu(physid)	physid_2_cpu[physid]
 #define cpu_to_physid(cpu_id)	cpu_2_physid[cpu_id]
 
-#define smp_processor_id()	(current_thread_info()->cpu)
+#define raw_smp_processor_id()	(current_thread_info()->cpu)
 
 extern cpumask_t cpu_callout_map;
 #define cpu_possible_map cpu_callout_map
diff --git a/include/asm-m32r/thread_info.h b/include/asm-m32r/thread_info.h
--- a/include/asm-m32r/thread_info.h
+++ b/include/asm-m32r/thread_info.h
@@ -28,7 +28,7 @@ struct thread_info {
 	unsigned long		flags;		/* low level flags */
 	unsigned long		status;		/* thread-synchronous flags */
 	__u32			cpu;		/* current CPU */
-	__s32			preempt_count; /* 0 => preemptable, <0 => BUG */
+	int			preempt_count;	/* 0 => preemptable, <0 => BUG */
 
 	mm_segment_t		addr_limit;	/* thread address space:
 					 	   0-0xBFFFFFFF for user-thread
diff --git a/include/asm-m32r/topology.h b/include/asm-m32r/topology.h
--- a/include/asm-m32r/topology.h
+++ b/include/asm-m32r/topology.h
@@ -1,48 +1,6 @@
-/*
- * linux/include/asm-generic/topology.h
- *
- * Written by: Matthew Dobson, IBM Corporation
- *
- * Copyright (C) 2002, IBM Corp.
- *
- * 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, GOOD TITLE or
- * NON INFRINGEMENT.  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.
- *
- * Send feedback to <colpatch@us.ibm.com>
- */
 #ifndef _ASM_M32R_TOPOLOGY_H
 #define _ASM_M32R_TOPOLOGY_H
 
-/* Other architectures wishing to use this simple topology API should fill
-   in the below functions as appropriate in their own <asm/topology.h> file. */
-
-#define cpu_to_node(cpu)	(0)
-
-#ifndef parent_node
-#define parent_node(node)	(0)
-#endif
-#ifndef node_to_cpumask
-#define node_to_cpumask(node)	(cpu_online_map)
-#endif
-#ifndef node_to_first_cpu
-#define node_to_first_cpu(node)	(0)
-#endif
-#ifndef pcibus_to_cpumask
-#define pcibus_to_cpumask(bus)	(cpu_online_map)
-#endif
+#include <asm-generic/topology.h>
 
 #endif /* _ASM_M32R_TOPOLOGY_H */
diff --git a/include/asm-m68k/emergency-restart.h b/include/asm-m68k/emergency-restart.h
new file mode 100644
--- /dev/null
+++ b/include/asm-m68k/emergency-restart.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_EMERGENCY_RESTART_H
+#define _ASM_EMERGENCY_RESTART_H
+
+#include <asm-generic/emergency-restart.h>
+
+#endif /* _ASM_EMERGENCY_RESTART_H */
diff --git a/include/asm-m68k/page.h b/include/asm-m68k/page.h
--- a/include/asm-m68k/page.h
+++ b/include/asm-m68k/page.h
@@ -138,13 +138,13 @@ extern unsigned long m68k_memoffset;
 #define __pa(vaddr)		((unsigned long)(vaddr)+m68k_memoffset)
 #define __va(paddr)		((void *)((unsigned long)(paddr)-m68k_memoffset))
 #else
-#define __pa(vaddr)		virt_to_phys((void *)vaddr)
-#define __va(paddr)		phys_to_virt((unsigned long)paddr)
+#define __pa(vaddr)		virt_to_phys((void *)(vaddr))
+#define __va(paddr)		phys_to_virt((unsigned long)(paddr))
 #endif
 
 #else	/* !CONFIG_SUN3 */
 /* This #define is a horrible hack to suppress lots of warnings. --m */
-#define __pa(x) ___pa((unsigned long)x)
+#define __pa(x) ___pa((unsigned long)(x))
 static inline unsigned long ___pa(unsigned long x)
 {
      if(x == 0)
diff --git a/include/asm-m68k/pci.h b/include/asm-m68k/pci.h
--- a/include/asm-m68k/pci.h
+++ b/include/asm-m68k/pci.h
@@ -43,7 +43,7 @@ static inline void pcibios_set_master(st
 	/* No special bus mastering setup handling */
 }
 
-static inline void pcibios_penalize_isa_irq(int irq)
+static inline void pcibios_penalize_isa_irq(int irq, int active)
 {
 	/* We don't do dynamic PCI IRQ allocation */
 }
diff --git a/include/asm-m68k/serial.h b/include/asm-m68k/serial.h
--- a/include/asm-m68k/serial.h
+++ b/include/asm-m68k/serial.h
@@ -26,54 +26,9 @@
 #define STD_COM4_FLAGS ASYNC_BOOT_AUTOCONF
 #endif
 
-#ifdef CONFIG_SERIAL_MANY_PORTS
-#define FOURPORT_FLAGS ASYNC_FOURPORT
-#define ACCENT_FLAGS 0
-#define BOCA_FLAGS 0
-#endif
-
-#define STD_SERIAL_PORT_DEFNS			\
+#define SERIAL_PORT_DFNS			\
 	/* UART CLK   PORT IRQ     FLAGS        */			\
 	{ 0, BASE_BAUD, 0x3F8, 4, STD_COM_FLAGS },	/* ttyS0 */	\
 	{ 0, BASE_BAUD, 0x2F8, 3, STD_COM_FLAGS },	/* ttyS1 */	\
 	{ 0, BASE_BAUD, 0x3E8, 4, STD_COM_FLAGS },	/* ttyS2 */	\
 	{ 0, BASE_BAUD, 0x2E8, 3, STD_COM4_FLAGS },	/* ttyS3 */
-
-
-#ifdef CONFIG_SERIAL_MANY_PORTS
-#define EXTRA_SERIAL_PORT_DEFNS			\
-	{ 0, BASE_BAUD, 0x1A0, 9, FOURPORT_FLAGS },	/* ttyS4 */	\
-	{ 0, BASE_BAUD, 0x1A8, 9, FOURPORT_FLAGS },	/* ttyS5 */	\
-	{ 0, BASE_BAUD, 0x1B0, 9, FOURPORT_FLAGS },	/* ttyS6 */	\
-	{ 0, BASE_BAUD, 0x1B8, 9, FOURPORT_FLAGS },	/* ttyS7 */	\
-	{ 0, BASE_BAUD, 0x2A0, 5, FOURPORT_FLAGS },	/* ttyS8 */	\
-	{ 0, BASE_BAUD, 0x2A8, 5, FOURPORT_FLAGS },	/* ttyS9 */	\
-	{ 0, BASE_BAUD, 0x2B0, 5, FOURPORT_FLAGS },	/* ttyS10 */	\
-	{ 0, BASE_BAUD, 0x2B8, 5, FOURPORT_FLAGS },	/* ttyS11 */	\
-	{ 0, BASE_BAUD, 0x330, 4, ACCENT_FLAGS },	/* ttyS12 */	\
-	{ 0, BASE_BAUD, 0x338, 4, ACCENT_FLAGS },	/* ttyS13 */	\
-	{ 0, BASE_BAUD, 0x000, 0, 0 },	/* ttyS14 (spare) */		\
-	{ 0, BASE_BAUD, 0x000, 0, 0 },	/* ttyS15 (spare) */		\
-	{ 0, BASE_BAUD, 0x100, 12, BOCA_FLAGS },	/* ttyS16 */	\
-	{ 0, BASE_BAUD, 0x108, 12, BOCA_FLAGS },	/* ttyS17 */	\
-	{ 0, BASE_BAUD, 0x110, 12, BOCA_FLAGS },	/* ttyS18 */	\
-	{ 0, BASE_BAUD, 0x118, 12, BOCA_FLAGS },	/* ttyS19 */	\
-	{ 0, BASE_BAUD, 0x120, 12, BOCA_FLAGS },	/* ttyS20 */	\
-	{ 0, BASE_BAUD, 0x128, 12, BOCA_FLAGS },	/* ttyS21 */	\
-	{ 0, BASE_BAUD, 0x130, 12, BOCA_FLAGS },	/* ttyS22 */	\
-	{ 0, BASE_BAUD, 0x138, 12, BOCA_FLAGS },	/* ttyS23 */	\
-	{ 0, BASE_BAUD, 0x140, 12, BOCA_FLAGS },	/* ttyS24 */	\
-	{ 0, BASE_BAUD, 0x148, 12, BOCA_FLAGS },	/* ttyS25 */	\
-	{ 0, BASE_BAUD, 0x150, 12, BOCA_FLAGS },	/* ttyS26 */	\
-	{ 0, BASE_BAUD, 0x158, 12, BOCA_FLAGS },	/* ttyS27 */	\
-	{ 0, BASE_BAUD, 0x160, 12, BOCA_FLAGS },	/* ttyS28 */	\
-	{ 0, BASE_BAUD, 0x168, 12, BOCA_FLAGS },	/* ttyS29 */	\
-	{ 0, BASE_BAUD, 0x170, 12, BOCA_FLAGS },	/* ttyS30 */	\
-	{ 0, BASE_BAUD, 0x178, 12, BOCA_FLAGS },	/* ttyS31 */
-#else
-#define EXTRA_SERIAL_PORT_DEFNS
-#endif
-
-#define SERIAL_PORT_DFNS		\
-	STD_SERIAL_PORT_DEFNS		\
-	EXTRA_SERIAL_PORT_DEFNS
diff --git a/include/asm-m68k/thread_info.h b/include/asm-m68k/thread_info.h
--- a/include/asm-m68k/thread_info.h
+++ b/include/asm-m68k/thread_info.h
@@ -8,7 +8,7 @@
 struct thread_info {
 	struct task_struct	*task;		/* main task structure */
 	struct exec_domain	*exec_domain;	/* execution domain */
-	__s32			preempt_count; /* 0 => preemptable, <0 => BUG */
+	int			preempt_count;	/* 0 => preemptable, <0 => BUG */
 	__u32 cpu; /* should always be 0 on m68k */
 	struct restart_block    restart_block;
 
diff --git a/include/asm-m68knommu/emergency-restart.h b/include/asm-m68knommu/emergency-restart.h
new file mode 100644
--- /dev/null
+++ b/include/asm-m68knommu/emergency-restart.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_EMERGENCY_RESTART_H
+#define _ASM_EMERGENCY_RESTART_H
+
+#include <asm-generic/emergency-restart.h>
+
+#endif /* _ASM_EMERGENCY_RESTART_H */
diff --git a/include/asm-m68knommu/thread_info.h b/include/asm-m68knommu/thread_info.h
--- a/include/asm-m68knommu/thread_info.h
+++ b/include/asm-m68knommu/thread_info.h
@@ -36,7 +36,7 @@ struct thread_info {
 	struct exec_domain *exec_domain;	/* execution domain */
 	unsigned long	   flags;		/* low level flags */
 	int		   cpu;			/* cpu we're on */
-	int		   preempt_count;	/* 0 => preemptable, <0 => BUG*/
+	int		   preempt_count;	/* 0 => preemptable, <0 => BUG */
 	struct restart_block restart_block;
 };
 
diff --git a/include/asm-mips/compat.h b/include/asm-mips/compat.h
--- a/include/asm-mips/compat.h
+++ b/include/asm-mips/compat.h
@@ -29,6 +29,7 @@ typedef s32		compat_caddr_t;
 typedef struct {
 	s32	val[2];
 } compat_fsid_t;
+typedef s32		compat_timer_t;
 
 typedef s32		compat_int_t;
 typedef s32		compat_long_t;
diff --git a/include/asm-mips/emergency-restart.h b/include/asm-mips/emergency-restart.h
new file mode 100644
--- /dev/null
+++ b/include/asm-mips/emergency-restart.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_EMERGENCY_RESTART_H
+#define _ASM_EMERGENCY_RESTART_H
+
+#include <asm-generic/emergency-restart.h>
+
+#endif /* _ASM_EMERGENCY_RESTART_H */
diff --git a/include/asm-mips/mmzone.h b/include/asm-mips/mmzone.h
--- a/include/asm-mips/mmzone.h
+++ b/include/asm-mips/mmzone.h
@@ -8,6 +8,8 @@
 #include <asm/page.h>
 #include <mmzone.h>
 
+#ifdef CONFIG_DISCONTIGMEM
+
 #define kvaddr_to_nid(kvaddr)	pa_to_nid(__pa(kvaddr))
 #define pfn_to_nid(pfn)		pa_to_nid((pfn) << PAGE_SHIFT)
 
@@ -36,4 +38,6 @@
 /* XXX: FIXME -- wli */
 #define kern_addr_valid(addr)	(0)
 
+#endif /* CONFIG_DISCONTIGMEM */
+
 #endif /* _ASM_MMZONE_H_ */
diff --git a/include/asm-mips/page.h b/include/asm-mips/page.h
--- a/include/asm-mips/page.h
+++ b/include/asm-mips/page.h
@@ -127,7 +127,7 @@ static __inline__ int get_order(unsigned
 
 #define pfn_to_kaddr(pfn)	__va((pfn) << PAGE_SHIFT)
 
-#ifndef CONFIG_DISCONTIGMEM
+#ifndef CONFIG_NEED_MULTIPLE_NODES
 #define pfn_to_page(pfn)	(mem_map + (pfn))
 #define page_to_pfn(page)	((unsigned long)((page) - mem_map))
 #define pfn_valid(pfn)		((pfn) < max_mapnr)
diff --git a/include/asm-mips/pci.h b/include/asm-mips/pci.h
--- a/include/asm-mips/pci.h
+++ b/include/asm-mips/pci.h
@@ -69,7 +69,7 @@ extern unsigned long PCIBIOS_MIN_MEM;
 
 extern void pcibios_set_master(struct pci_dev *dev);
 
-static inline void pcibios_penalize_isa_irq(int irq)
+static inline void pcibios_penalize_isa_irq(int irq, int active)
 {
 	/* We don't do dynamic PCI IRQ allocation */
 }
@@ -130,6 +130,16 @@ extern void pci_dac_dma_sync_single_for_
 extern void pci_dac_dma_sync_single_for_device(struct pci_dev *pdev,
 	dma64_addr_t dma_addr, size_t len, int direction);
 
+#ifdef CONFIG_PCI
+static inline void pci_dma_burst_advice(struct pci_dev *pdev,
+					enum pci_dma_burst_strategy *strat,
+					unsigned long *strategy_parameter)
+{
+	*strat = PCI_DMA_BURST_INFINITY;
+	*strategy_parameter = ~0UL;
+}
+#endif
+
 extern void pcibios_resource_to_bus(struct pci_dev *dev,
 	struct pci_bus_region *region, struct resource *res);
 
diff --git a/include/asm-mips/pgtable.h b/include/asm-mips/pgtable.h
--- a/include/asm-mips/pgtable.h
+++ b/include/asm-mips/pgtable.h
@@ -350,7 +350,7 @@ static inline void update_mmu_cache(stru
 	__update_cache(vma, address, pte);
 }
 
-#ifndef CONFIG_DISCONTIGMEM
+#ifndef CONFIG_NEED_MULTIPLE_NODES
 #define kern_addr_valid(addr)	(1)
 #endif
 
diff --git a/include/asm-mips/serial.h b/include/asm-mips/serial.h
--- a/include/asm-mips/serial.h
+++ b/include/asm-mips/serial.h
@@ -29,32 +29,6 @@
 #define STD_COM4_FLAGS ASYNC_BOOT_AUTOCONF
 #endif
 
-#ifdef CONFIG_SERIAL_MANY_PORTS
-#define FOURPORT_FLAGS ASYNC_FOURPORT
-#define ACCENT_FLAGS 0
-#define BOCA_FLAGS 0
-#define HUB6_FLAGS 0
-#define RS_TABLE_SIZE	64
-#else
-#define RS_TABLE_SIZE
-#endif
-
-/*
- * The following define the access methods for the HUB6 card. All
- * access is through two ports for all 24 possible chips. The card is
- * selected through the high 2 bits, the port on that card with the
- * "middle" 3 bits, and the register on that port with the bottom
- * 3 bits.
- *
- * While the access port and interrupt is configurable, the default
- * port locations are 0x302 for the port control register, and 0x303
- * for the data read/write register. Normally, the interrupt is at irq3
- * but can be anything from 3 to 7 inclusive. Note that using 3 will
- * require disabling com2.
- */
-
-#define C_P(card,port) (((card)<<6|(port)<<3) + 1)
-
 #ifdef CONFIG_MACH_JAZZ
 #include <asm/jazz.h>
 
@@ -240,66 +214,10 @@
 	{ 0, BASE_BAUD, 0x3E8, 4, STD_COM_FLAGS },	/* ttyS2 */	\
 	{ 0, BASE_BAUD, 0x2E8, 3, STD_COM4_FLAGS },	/* ttyS3 */
 
-#ifdef CONFIG_SERIAL_MANY_PORTS
-#define EXTRA_SERIAL_PORT_DEFNS			\
-	{ 0, BASE_BAUD, 0x1A0, 9, FOURPORT_FLAGS }, 	/* ttyS4 */	\
-	{ 0, BASE_BAUD, 0x1A8, 9, FOURPORT_FLAGS },	/* ttyS5 */	\
-	{ 0, BASE_BAUD, 0x1B0, 9, FOURPORT_FLAGS },	/* ttyS6 */	\
-	{ 0, BASE_BAUD, 0x1B8, 9, FOURPORT_FLAGS },	/* ttyS7 */	\
-	{ 0, BASE_BAUD, 0x2A0, 5, FOURPORT_FLAGS },	/* ttyS8 */	\
-	{ 0, BASE_BAUD, 0x2A8, 5, FOURPORT_FLAGS },	/* ttyS9 */	\
-	{ 0, BASE_BAUD, 0x2B0, 5, FOURPORT_FLAGS },	/* ttyS10 */	\
-	{ 0, BASE_BAUD, 0x2B8, 5, FOURPORT_FLAGS },	/* ttyS11 */	\
-	{ 0, BASE_BAUD, 0x330, 4, ACCENT_FLAGS },	/* ttyS12 */	\
-	{ 0, BASE_BAUD, 0x338, 4, ACCENT_FLAGS },	/* ttyS13 */	\
-	{ 0, BASE_BAUD, 0x000, 0, 0 },			/* ttyS14 (spare) */ \
-	{ 0, BASE_BAUD, 0x000, 0, 0 },			/* ttyS15 (spare) */ \
-	{ 0, BASE_BAUD, 0x100, 12, BOCA_FLAGS },	/* ttyS16 */	\
-	{ 0, BASE_BAUD, 0x108, 12, BOCA_FLAGS },	/* ttyS17 */	\
-	{ 0, BASE_BAUD, 0x110, 12, BOCA_FLAGS },	/* ttyS18 */	\
-	{ 0, BASE_BAUD, 0x118, 12, BOCA_FLAGS },	/* ttyS19 */	\
-	{ 0, BASE_BAUD, 0x120, 12, BOCA_FLAGS },	/* ttyS20 */	\
-	{ 0, BASE_BAUD, 0x128, 12, BOCA_FLAGS },	/* ttyS21 */	\
-	{ 0, BASE_BAUD, 0x130, 12, BOCA_FLAGS },	/* ttyS22 */	\
-	{ 0, BASE_BAUD, 0x138, 12, BOCA_FLAGS },	/* ttyS23 */	\
-	{ 0, BASE_BAUD, 0x140, 12, BOCA_FLAGS },	/* ttyS24 */	\
-	{ 0, BASE_BAUD, 0x148, 12, BOCA_FLAGS },	/* ttyS25 */	\
-	{ 0, BASE_BAUD, 0x150, 12, BOCA_FLAGS },	/* ttyS26 */	\
-	{ 0, BASE_BAUD, 0x158, 12, BOCA_FLAGS },	/* ttyS27 */	\
-	{ 0, BASE_BAUD, 0x160, 12, BOCA_FLAGS },	/* ttyS28 */	\
-	{ 0, BASE_BAUD, 0x168, 12, BOCA_FLAGS },	/* ttyS29 */	\
-	{ 0, BASE_BAUD, 0x170, 12, BOCA_FLAGS },	/* ttyS30 */	\
-	{ 0, BASE_BAUD, 0x178, 12, BOCA_FLAGS },	/* ttyS31 */
-#else /* CONFIG_SERIAL_MANY_PORTS */
-#define EXTRA_SERIAL_PORT_DEFNS
-#endif /* CONFIG_SERIAL_MANY_PORTS */
-
 #else /* CONFIG_HAVE_STD_PC_SERIAL_PORTS */
 #define STD_SERIAL_PORT_DEFNS
-#define EXTRA_SERIAL_PORT_DEFNS
 #endif /* CONFIG_HAVE_STD_PC_SERIAL_PORTS */
 
-/* You can have up to four HUB6's in the system, but I've only
- * included two cards here for a total of twelve ports.
- */
-#if (defined(CONFIG_HUB6) && defined(CONFIG_SERIAL_MANY_PORTS))
-#define HUB6_SERIAL_PORT_DFNS		\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,0) },  /* ttyS32 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,1) },  /* ttyS33 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,2) },  /* ttyS34 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,3) },  /* ttyS35 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,4) },  /* ttyS36 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,5) },  /* ttyS37 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,0) },  /* ttyS38 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,1) },  /* ttyS39 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,2) },  /* ttyS40 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,3) },  /* ttyS41 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,4) },  /* ttyS42 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,5) },  /* ttyS43 */
-#else
-#define HUB6_SERIAL_PORT_DFNS
-#endif
-
 #ifdef CONFIG_MOMENCO_JAGUAR_ATX
 /* Ordinary NS16552 duart with a 20MHz crystal.  */
 #define JAGUAR_ATX_UART_CLK	20000000
@@ -427,8 +345,6 @@
 	COBALT_SERIAL_PORT_DEFNS			\
 	DDB5477_SERIAL_PORT_DEFNS			\
 	EV96100_SERIAL_PORT_DEFNS			\
-	EXTRA_SERIAL_PORT_DEFNS				\
-	HUB6_SERIAL_PORT_DFNS				\
 	IP32_SERIAL_PORT_DEFNS                          \
 	ITE_SERIAL_PORT_DEFNS           		\
 	IVR_SERIAL_PORT_DEFNS           		\
diff --git a/include/asm-mips/smp.h b/include/asm-mips/smp.h
--- a/include/asm-mips/smp.h
+++ b/include/asm-mips/smp.h
@@ -21,7 +21,7 @@
 #include <linux/cpumask.h>
 #include <asm/atomic.h>
 
-#define smp_processor_id()	(current_thread_info()->cpu)
+#define raw_smp_processor_id() (current_thread_info()->cpu)
 
 /* Map from cpu id to sequential logical cpu number.  This will only
    not be idempotent when cpus failed to come on-line.  */
diff --git a/include/asm-mips/system.h b/include/asm-mips/system.h
--- a/include/asm-mips/system.h
+++ b/include/asm-mips/system.h
@@ -422,16 +422,10 @@ extern void __die_if_kernel(const char *
 extern int stop_a_enabled;
 
 /*
- * Taken from include/asm-ia64/system.h; prevents deadlock on SMP
+ * See include/asm-ia64/system.h; prevents deadlock on SMP
  * systems.
  */
-#define prepare_arch_switch(rq, next)		\
-do {						\
-	spin_lock(&(next)->switch_lock);	\
-	spin_unlock(&(rq)->lock);		\
-} while (0)
-#define finish_arch_switch(rq, prev)	spin_unlock_irq(&(prev)->switch_lock)
-#define task_running(rq, p) 		((rq)->curr == (p) || spin_is_locked(&(p)->switch_lock))
+#define __ARCH_WANT_UNLOCKED_CTXSW
 
 #define arch_align_stack(x) (x)
 
diff --git a/include/asm-mips/thread_info.h b/include/asm-mips/thread_info.h
--- a/include/asm-mips/thread_info.h
+++ b/include/asm-mips/thread_info.h
@@ -27,7 +27,7 @@ struct thread_info {
 	struct exec_domain	*exec_domain;	/* execution domain */
 	unsigned long		flags;		/* low level flags */
 	__u32			cpu;		/* current CPU */
-	__s32			preempt_count; /* 0 => preemptable, <0 => BUG */
+	int			preempt_count;	/* 0 => preemptable, <0 => BUG */
 
 	mm_segment_t		addr_limit;	/* thread address space:
 					 	   0-0xBFFFFFFF for user-thead
diff --git a/include/asm-mips/vr41xx/giu.h b/include/asm-mips/vr41xx/giu.h
new file mode 100644
--- /dev/null
+++ b/include/asm-mips/vr41xx/giu.h
@@ -0,0 +1,69 @@
+/*
+ *  Include file for NEC VR4100 series General-purpose I/O Unit.
+ *
+ *  Copyright (C) 2005  Yoichi Yuasa <yuasa@hh.iij4u.or.jp>
+ *
+ *  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 __NEC_VR41XX_GIU_H
+#define __NEC_VR41XX_GIU_H
+
+typedef enum {
+	IRQ_TRIGGER_LEVEL,
+	IRQ_TRIGGER_EDGE,
+	IRQ_TRIGGER_EDGE_FALLING,
+	IRQ_TRIGGER_EDGE_RISING,
+} irq_trigger_t;
+
+typedef enum {
+	IRQ_SIGNAL_THROUGH,
+	IRQ_SIGNAL_HOLD,
+} irq_signal_t;
+
+extern void vr41xx_set_irq_trigger(unsigned int pin, irq_trigger_t trigger, irq_signal_t signal);
+
+typedef enum {
+	IRQ_LEVEL_LOW,
+	IRQ_LEVEL_HIGH,
+} irq_level_t;
+
+extern void vr41xx_set_irq_level(unsigned int pin, irq_level_t level);
+
+typedef enum {
+	GPIO_DATA_LOW,
+	GPIO_DATA_HIGH,
+	GPIO_DATA_INVAL,
+} gpio_data_t;
+
+extern gpio_data_t vr41xx_gpio_get_pin(unsigned int pin);
+extern int vr41xx_gpio_set_pin(unsigned int pin, gpio_data_t data);
+
+typedef enum {
+	GPIO_INPUT,
+	GPIO_OUTPUT,
+	GPIO_OUTPUT_DISABLE,
+} gpio_direction_t;
+
+extern int vr41xx_gpio_set_direction(unsigned int pin, gpio_direction_t dir);
+
+typedef enum {
+	GPIO_PULL_DOWN,
+	GPIO_PULL_UP,
+	GPIO_PULL_DISABLE,
+} gpio_pull_t;
+
+extern int vr41xx_gpio_pullupdown(unsigned int pin, gpio_pull_t pull);
+
+#endif /* __NEC_VR41XX_GIU_H */
diff --git a/include/asm-mips/vr41xx/vr41xx.h b/include/asm-mips/vr41xx/vr41xx.h
--- a/include/asm-mips/vr41xx/vr41xx.h
+++ b/include/asm-mips/vr41xx/vr41xx.h
@@ -126,7 +126,6 @@ extern void vr41xx_mask_clock(vr41xx_clo
 #define GIU_IRQ_BASE		40
 #define GIU_IRQ(x)		(GIU_IRQ_BASE + (x))	/* IRQ 40-71 */
 #define GIU_IRQ_LAST		GIU_IRQ(31)
-#define GIU_IRQ_TO_PIN(x)	((x) - GIU_IRQ_BASE)	/* Pin 0-31 */
 
 extern int vr41xx_set_intassign(unsigned int irq, unsigned char intassign);
 extern int vr41xx_cascade_irq(unsigned int irq, int (*get_irq_number)(int irq));
@@ -197,38 +196,4 @@ extern void vr41xx_disable_csiint(uint16
 extern void vr41xx_enable_bcuint(void);
 extern void vr41xx_disable_bcuint(void);
 
-/*
- * General-Purpose I/O Unit
- */
-enum {
-	TRIGGER_LEVEL,
-	TRIGGER_EDGE,
-	TRIGGER_EDGE_FALLING,
-	TRIGGER_EDGE_RISING
-};
-
-enum {
-	SIGNAL_THROUGH,
-	SIGNAL_HOLD
-};
-
-extern void vr41xx_set_irq_trigger(int pin, int trigger, int hold);
-
-enum {
-	LEVEL_LOW,
-	LEVEL_HIGH
-};
-
-extern void vr41xx_set_irq_level(int pin, int level);
-
-enum {
-	PIO_INPUT,
-	PIO_OUTPUT
-};
-
-enum {
-	DATA_LOW,
-	DATA_HIGH
-};
-
 #endif /* __NEC_VR41XX_H */
diff --git a/include/asm-parisc/compat.h b/include/asm-parisc/compat.h
--- a/include/asm-parisc/compat.h
+++ b/include/asm-parisc/compat.h
@@ -24,7 +24,7 @@ typedef u16	compat_nlink_t;
 typedef u16	compat_ipc_pid_t;
 typedef s32	compat_daddr_t;
 typedef u32	compat_caddr_t;
-typedef u32	compat_timer_t;
+typedef s32	compat_timer_t;
 
 typedef s32	compat_int_t;
 typedef s32	compat_long_t;
diff --git a/include/asm-parisc/emergency-restart.h b/include/asm-parisc/emergency-restart.h
new file mode 100644
--- /dev/null
+++ b/include/asm-parisc/emergency-restart.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_EMERGENCY_RESTART_H
+#define _ASM_EMERGENCY_RESTART_H
+
+#include <asm-generic/emergency-restart.h>
+
+#endif /* _ASM_EMERGENCY_RESTART_H */
diff --git a/include/asm-parisc/mmzone.h b/include/asm-parisc/mmzone.h
--- a/include/asm-parisc/mmzone.h
+++ b/include/asm-parisc/mmzone.h
@@ -19,7 +19,6 @@ extern struct node_map_data node_data[];
  */
 #define kvaddr_to_nid(kaddr)	pfn_to_nid(__pa(kaddr) >> PAGE_SHIFT)
 
-#define node_mem_map(nid)	(NODE_DATA(nid)->node_mem_map)
 #define node_start_pfn(nid)	(NODE_DATA(nid)->node_start_pfn)
 #define node_end_pfn(nid)						\
 ({									\
@@ -38,7 +37,7 @@ extern struct node_map_data node_data[];
 ({									\
 	unsigned long __pfn = (pfn);					\
 	int __node  = pfn_to_nid(__pfn);				\
-	&node_mem_map(__node)[node_localnr(__pfn,__node)];		\
+	&NODE_DATA(__node)->node_mem_map[node_localnr(__pfn,__node)];	\
 })
 
 #define page_to_pfn(pg)							\
diff --git a/include/asm-parisc/pci.h b/include/asm-parisc/pci.h
--- a/include/asm-parisc/pci.h
+++ b/include/asm-parisc/pci.h
@@ -230,10 +230,33 @@ extern inline void pcibios_register_hba(
 /* export the pci_ DMA API in terms of the dma_ one */
 #include <asm-generic/pci-dma-compat.h>
 
+#ifdef CONFIG_PCI
+static inline void pci_dma_burst_advice(struct pci_dev *pdev,
+					enum pci_dma_burst_strategy *strat,
+					unsigned long *strategy_parameter)
+{
+	unsigned long cacheline_size;
+	u8 byte;
+
+	pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &byte);
+	if (byte == 0)
+		cacheline_size = 1024;
+	else
+		cacheline_size = (int) byte * 4;
+
+	*strat = PCI_DMA_BURST_MULTIPLE;
+	*strategy_parameter = cacheline_size;
+}
+#endif
+
 extern void
 pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
 			 struct resource *res);
 
+extern void
+pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
+			struct pci_bus_region *region);
+
 static inline void pcibios_add_platform_entries(struct pci_dev *dev)
 {
 }
diff --git a/include/asm-parisc/serial.h b/include/asm-parisc/serial.h
--- a/include/asm-parisc/serial.h
+++ b/include/asm-parisc/serial.h
@@ -19,18 +19,4 @@
  * A500 w/ PCI serial cards: 5 + 4 * card ~= 17
  */
  
-#define STD_SERIAL_PORT_DEFNS			\
-	{ 0, },		/* ttyS0 */	\
-	{ 0, },		/* ttyS1 */	\
-	{ 0, },		/* ttyS2 */	\
-	{ 0, },		/* ttyS3 */	\
-	{ 0, },		/* ttyS4 */	\
-	{ 0, },		/* ttyS5 */	\
-	{ 0, },		/* ttyS6 */	\
-	{ 0, },		/* ttyS7 */	\
-	{ 0, },		/* ttyS8 */
-
-
-#define SERIAL_PORT_DFNS		\
-	STD_SERIAL_PORT_DEFNS
-
+#define SERIAL_PORT_DFNS
diff --git a/include/asm-parisc/smp.h b/include/asm-parisc/smp.h
--- a/include/asm-parisc/smp.h
+++ b/include/asm-parisc/smp.h
@@ -51,7 +51,7 @@ extern void smp_send_reschedule(int cpu)
 
 extern unsigned long cpu_present_mask;
 
-#define smp_processor_id()	(current_thread_info()->cpu)
+#define raw_smp_processor_id()	(current_thread_info()->cpu)
 
 #endif /* CONFIG_SMP */
 
diff --git a/include/asm-parisc/thread_info.h b/include/asm-parisc/thread_info.h
--- a/include/asm-parisc/thread_info.h
+++ b/include/asm-parisc/thread_info.h
@@ -12,7 +12,7 @@ struct thread_info {
 	unsigned long flags;		/* thread_info flags (see TIF_*) */
 	mm_segment_t addr_limit;	/* user-level address space limit */
 	__u32 cpu;			/* current CPU */
-	__s32 preempt_count;		/* 0=premptable, <0=BUG; will also serve as bh-counter */
+	int preempt_count;		/* 0=premptable, <0=BUG; will also serve as bh-counter */
 	struct restart_block restart_block;
 };
 
diff --git a/include/asm-ppc/cpm2.h b/include/asm-ppc/cpm2.h
--- a/include/asm-ppc/cpm2.h
+++ b/include/asm-ppc/cpm2.h
@@ -109,6 +109,7 @@ static inline long IS_DPERR(const uint o
  * and dual port ram.
  */
 extern		cpm_cpm2_t	*cpmp;	 /* Pointer to comm processor */
+
 extern uint cpm_dpalloc(uint size, uint align);
 extern int cpm_dpfree(uint offset);
 extern uint cpm_dpalloc_fixed(uint offset, uint size, uint align);
@@ -116,6 +117,8 @@ extern void cpm_dpdump(void);
 extern void *cpm_dpram_addr(uint offset);
 extern void cpm_setbrg(uint brg, uint rate);
 extern void cpm2_fastbrg(uint brg, uint rate, int div16);
+extern void cpm2_reset(void);
+
 
 /* Buffer descriptors used by many of the CPM protocols.
 */
@@ -1087,5 +1090,3 @@ typedef struct im_idma {
 
 #endif /* __CPM2__ */
 #endif /* __KERNEL__ */
-
-
diff --git a/include/asm-ppc/dma-mapping.h b/include/asm-ppc/dma-mapping.h
--- a/include/asm-ppc/dma-mapping.h
+++ b/include/asm-ppc/dma-mapping.h
@@ -117,7 +117,7 @@ dma_map_page(struct device *dev, struct 
 
 	__dma_sync_page(page, offset, size, direction);
 
-	return (page - mem_map) * PAGE_SIZE + PCI_DRAM_OFFSET + offset;
+	return page_to_bus(page) + offset;
 }
 
 /* We do nothing. */
diff --git a/include/asm-ppc/emergency-restart.h b/include/asm-ppc/emergency-restart.h
new file mode 100644
--- /dev/null
+++ b/include/asm-ppc/emergency-restart.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_EMERGENCY_RESTART_H
+#define _ASM_EMERGENCY_RESTART_H
+
+#include <asm-generic/emergency-restart.h>
+
+#endif /* _ASM_EMERGENCY_RESTART_H */
diff --git a/include/asm-ppc/fsl_ocp.h b/include/asm-ppc/fsl_ocp.h
deleted file mode 100644
--- a/include/asm-ppc/fsl_ocp.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * include/asm-ppc/fsl_ocp.h
- *
- * Definitions for the on-chip peripherals on Freescale PPC processors
- *
- * Maintainer: Kumar Gala (kumar.gala@freescale.com)
- *
- * Copyright 2004 Freescale Semiconductor, 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.
- */
-
-#ifdef __KERNEL__
-#ifndef __ASM_FS_OCP_H__
-#define __ASM_FS_OCP_H__
-
-/* A table of information for supporting the Gianfar Ethernet Controller
- * This helps identify which enet controller we are dealing with,
- * and what type of enet controller it is
- */
-struct ocp_gfar_data {
-	uint interruptTransmit;
-	uint interruptError;
-	uint interruptReceive;
-	uint interruptPHY;
-	uint flags;
-	uint phyid;
-	uint phyregidx;
-	unsigned char mac_addr[6];
-};
-
-/* Flags in the flags field */
-#define GFAR_HAS_COALESCE		0x20
-#define GFAR_HAS_RMON			0x10
-#define GFAR_HAS_MULTI_INTR		0x08
-#define GFAR_FIRM_SET_MACADDR		0x04
-#define GFAR_HAS_PHY_INTR		0x02	/* if not set use a timer */
-#define GFAR_HAS_GIGABIT		0x01
-
-/* Data structure for I2C support.  Just contains a couple flags
- * to distinguish various I2C implementations*/
-struct ocp_fs_i2c_data {
-	uint flags;
-};
-
-/* Flags for I2C */
-#define FS_I2C_SEPARATE_DFSRR	0x02
-#define FS_I2C_CLOCK_5200	0x01
-
-#endif	/* __ASM_FS_OCP_H__ */
-#endif	/* __KERNEL__ */
diff --git a/include/asm-ppc/ibm44x.h b/include/asm-ppc/ibm44x.h
--- a/include/asm-ppc/ibm44x.h
+++ b/include/asm-ppc/ibm44x.h
@@ -35,8 +35,10 @@
 #define PPC44x_LOW_SLOT		63
 
 /* LS 32-bits of UART0 physical address location for early serial text debug */
-#ifdef CONFIG_440SP
+#if defined(CONFIG_440SP)
 #define UART0_PHYS_IO_BASE	0xf0000200
+#elif defined(CONFIG_440EP)
+#define UART0_PHYS_IO_BASE	0xe0000000
 #else
 #define UART0_PHYS_IO_BASE	0x40000200
 #endif
@@ -49,11 +51,16 @@
 /*
  * Standard 4GB "page" definitions
  */
-#ifdef CONFIG_440SP
+#if defined(CONFIG_440SP)
 #define	PPC44x_IO_PAGE		0x0000000100000000ULL
 #define	PPC44x_PCICFG_PAGE	0x0000000900000000ULL
 #define	PPC44x_PCIIO_PAGE	PPC44x_PCICFG_PAGE
 #define	PPC44x_PCIMEM_PAGE	0x0000000a00000000ULL
+#elif defined(CONFIG_440EP)
+#define PPC44x_IO_PAGE		0x0000000000000000ULL
+#define PPC44x_PCICFG_PAGE	0x0000000000000000ULL
+#define PPC44x_PCIIO_PAGE	PPC44x_PCICFG_PAGE
+#define PPC44x_PCIMEM_PAGE	0x0000000000000000ULL
 #else
 #define	PPC44x_IO_PAGE		0x0000000100000000ULL
 #define	PPC44x_PCICFG_PAGE	0x0000000200000000ULL
@@ -64,7 +71,7 @@
 /*
  * 36-bit trap ranges
  */
-#ifdef CONFIG_440SP
+#if defined(CONFIG_440SP)
 #define PPC44x_IO_LO		0xf0000000UL
 #define PPC44x_IO_HI		0xf0000fffUL
 #define PPC44x_PCI0CFG_LO	0x0ec00000UL
@@ -75,6 +82,13 @@
 #define PPC44x_PCI2CFG_HI	0x2ec00007UL
 #define PPC44x_PCIMEM_LO	0x80000000UL
 #define PPC44x_PCIMEM_HI	0xdfffffffUL
+#elif defined(CONFIG_440EP)
+#define PPC44x_IO_LO		0xef500000UL
+#define PPC44x_IO_HI		0xefffffffUL
+#define PPC44x_PCI0CFG_LO	0xeec00000UL
+#define PPC44x_PCI0CFG_HI	0xeecfffffUL
+#define PPC44x_PCIMEM_LO	0xa0000000UL
+#define PPC44x_PCIMEM_HI	0xdfffffffUL
 #else
 #define PPC44x_IO_LO		0x40000000UL
 #define PPC44x_IO_HI		0x40000fffUL
@@ -152,6 +166,12 @@
 #define DCRN_SDR_UART0		0x0120
 #define DCRN_SDR_UART1		0x0121
 
+#ifdef CONFIG_440EP
+#define DCRN_SDR_UART2		0x0122
+#define DCRN_SDR_UART3		0x0123
+#define DCRN_SDR_CUST0		0x4000
+#endif
+
 /* SDR read/write helper macros */
 #define SDR_READ(offset) ({\
 	mtdcr(DCRN_SDR_CONFIG_ADDR, offset); \
@@ -169,6 +189,14 @@
 #define DCRNCAP_DMA_SG		1	/* have DMA scatter/gather capability */
 #define DCRN_MAL_BASE		0x180
 
+#ifdef CONFIG_440EP
+#define DCRN_DMA2P40_BASE	0x300
+#define DCRN_DMA2P41_BASE	0x308
+#define DCRN_DMA2P42_BASE	0x310
+#define DCRN_DMA2P43_BASE	0x318
+#define DCRN_DMA2P4SR_BASE	0x320
+#endif
+
 /* UIC */
 #define DCRN_UIC0_BASE	0xc0
 #define DCRN_UIC1_BASE	0xd0
@@ -395,11 +423,7 @@
 #define MQ0_CONFIG_SIZE_2G		0x0000c000
 
 /* Internal SRAM Controller 440GX/440SP */
-#ifdef CONFIG_440SP
-#define DCRN_SRAM0_BASE		0x100
-#else /* 440GX */
 #define DCRN_SRAM0_BASE		0x000
-#endif
 
 #define DCRN_SRAM0_SB0CR	(DCRN_SRAM0_BASE + 0x020)
 #define DCRN_SRAM0_SB1CR	(DCRN_SRAM0_BASE + 0x021)
diff --git a/include/asm-ppc/ibm4xx.h b/include/asm-ppc/ibm4xx.h
--- a/include/asm-ppc/ibm4xx.h
+++ b/include/asm-ppc/ibm4xx.h
@@ -97,6 +97,10 @@ void ppc4xx_init(unsigned long r3, unsig
 
 #elif CONFIG_44x
 
+#if defined(CONFIG_BAMBOO)
+#include <platforms/4xx/bamboo.h>
+#endif
+
 #if defined(CONFIG_EBONY)
 #include <platforms/4xx/ebony.h>
 #endif
diff --git a/include/asm-ppc/ibm_ocp.h b/include/asm-ppc/ibm_ocp.h
--- a/include/asm-ppc/ibm_ocp.h
+++ b/include/asm-ppc/ibm_ocp.h
@@ -71,6 +71,8 @@ struct ocp_func_emac_data {
 
 /* Sysfs support */
 #define OCP_SYSFS_EMAC_DATA()						\
+OCP_SYSFS_ADDTL(struct ocp_func_emac_data, "%d\n", emac, rgmii_idx)	\
+OCP_SYSFS_ADDTL(struct ocp_func_emac_data, "%d\n", emac, rgmii_mux)	\
 OCP_SYSFS_ADDTL(struct ocp_func_emac_data, "%d\n", emac, zmii_idx)	\
 OCP_SYSFS_ADDTL(struct ocp_func_emac_data, "%d\n", emac, zmii_mux)	\
 OCP_SYSFS_ADDTL(struct ocp_func_emac_data, "%d\n", emac, mal_idx)	\
@@ -78,9 +80,14 @@ OCP_SYSFS_ADDTL(struct ocp_func_emac_dat
 OCP_SYSFS_ADDTL(struct ocp_func_emac_data, "%d\n", emac, mal_tx_chan)	\
 OCP_SYSFS_ADDTL(struct ocp_func_emac_data, "%d\n", emac, wol_irq)	\
 OCP_SYSFS_ADDTL(struct ocp_func_emac_data, "%d\n", emac, mdio_idx)	\
+OCP_SYSFS_ADDTL(struct ocp_func_emac_data, "%d\n", emac, tah_idx)	\
+OCP_SYSFS_ADDTL(struct ocp_func_emac_data, "%d\n", emac, phy_mode)	\
+OCP_SYSFS_ADDTL(struct ocp_func_emac_data, "0x%08x\n", emac, phy_map)	\
 									\
 void ocp_show_emac_data(struct device *dev)				\
 {									\
+	device_create_file(dev, &dev_attr_emac_rgmii_idx);		\
+	device_create_file(dev, &dev_attr_emac_rgmii_mux);		\
 	device_create_file(dev, &dev_attr_emac_zmii_idx);		\
 	device_create_file(dev, &dev_attr_emac_zmii_mux);		\
 	device_create_file(dev, &dev_attr_emac_mal_idx);		\
@@ -88,6 +95,9 @@ void ocp_show_emac_data(struct device *d
 	device_create_file(dev, &dev_attr_emac_mal_tx_chan);		\
 	device_create_file(dev, &dev_attr_emac_wol_irq);		\
 	device_create_file(dev, &dev_attr_emac_mdio_idx);		\
+	device_create_file(dev, &dev_attr_emac_tah_idx);		\
+	device_create_file(dev, &dev_attr_emac_phy_mode);		\
+	device_create_file(dev, &dev_attr_emac_phy_map);		\
 }
 
 #ifdef CONFIG_40x
@@ -157,7 +167,7 @@ OCP_SYSFS_ADDTL(struct ocp_func_iic_data
 									\
 void ocp_show_iic_data(struct device *dev)				\
 {									\
-	device_create_file(dev, &dev_attr_iic_fast_mode);			\
+	device_create_file(dev, &dev_attr_iic_fast_mode);		\
 }
 #endif /* __IBM_OCP_H__ */
 #endif /* __KERNEL__ */
diff --git a/include/asm-ppc/irq.h b/include/asm-ppc/irq.h
--- a/include/asm-ppc/irq.h
+++ b/include/asm-ppc/irq.h
@@ -176,7 +176,7 @@ static __inline__ int irq_canonicalize(i
 */
 #include <asm/mpc85xx.h>
 
-/* The MPC8560 openpic has  32 internal interrupts and 12 external
+/* The MPC8548 openpic has 48 internal interrupts and 12 external
  * interrupts.
  *
  * We are "flattening" the interrupt vectors of the cascaded CPM
@@ -184,7 +184,7 @@ static __inline__ int irq_canonicalize(i
  * single integer.
  */
 #define NR_CPM_INTS	64
-#define NR_EPIC_INTS	44
+#define NR_EPIC_INTS	60
 #ifndef NR_8259_INTS
 #define NR_8259_INTS	0
 #endif
@@ -223,9 +223,15 @@ static __inline__ int irq_canonicalize(i
 #define MPC85xx_IRQ_RIO_RX	(12 + MPC85xx_OPENPIC_IRQ_OFFSET)
 #define MPC85xx_IRQ_TSEC1_TX	(13 + MPC85xx_OPENPIC_IRQ_OFFSET)
 #define MPC85xx_IRQ_TSEC1_RX	(14 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_TSEC3_TX	(15 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_TSEC3_RX	(16 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_TSEC3_ERROR	(17 + MPC85xx_OPENPIC_IRQ_OFFSET)
 #define MPC85xx_IRQ_TSEC1_ERROR	(18 + MPC85xx_OPENPIC_IRQ_OFFSET)
 #define MPC85xx_IRQ_TSEC2_TX	(19 + MPC85xx_OPENPIC_IRQ_OFFSET)
 #define MPC85xx_IRQ_TSEC2_RX	(20 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_TSEC4_TX	(21 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_TSEC4_RX	(22 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_TSEC4_ERROR	(23 + MPC85xx_OPENPIC_IRQ_OFFSET)
 #define MPC85xx_IRQ_TSEC2_ERROR	(24 + MPC85xx_OPENPIC_IRQ_OFFSET)
 #define MPC85xx_IRQ_FEC		(25 + MPC85xx_OPENPIC_IRQ_OFFSET)
 #define MPC85xx_IRQ_DUART	(26 + MPC85xx_OPENPIC_IRQ_OFFSET)
@@ -235,18 +241,18 @@ static __inline__ int irq_canonicalize(i
 #define MPC85xx_IRQ_CPM		(30 + MPC85xx_OPENPIC_IRQ_OFFSET)
 
 /* The 12 external interrupt lines */
-#define MPC85xx_IRQ_EXT0        (32 + MPC85xx_OPENPIC_IRQ_OFFSET)
-#define MPC85xx_IRQ_EXT1        (33 + MPC85xx_OPENPIC_IRQ_OFFSET)
-#define MPC85xx_IRQ_EXT2        (34 + MPC85xx_OPENPIC_IRQ_OFFSET)
-#define MPC85xx_IRQ_EXT3        (35 + MPC85xx_OPENPIC_IRQ_OFFSET)
-#define MPC85xx_IRQ_EXT4        (36 + MPC85xx_OPENPIC_IRQ_OFFSET)
-#define MPC85xx_IRQ_EXT5        (37 + MPC85xx_OPENPIC_IRQ_OFFSET)
-#define MPC85xx_IRQ_EXT6        (38 + MPC85xx_OPENPIC_IRQ_OFFSET)
-#define MPC85xx_IRQ_EXT7        (39 + MPC85xx_OPENPIC_IRQ_OFFSET)
-#define MPC85xx_IRQ_EXT8        (40 + MPC85xx_OPENPIC_IRQ_OFFSET)
-#define MPC85xx_IRQ_EXT9        (41 + MPC85xx_OPENPIC_IRQ_OFFSET)
-#define MPC85xx_IRQ_EXT10       (42 + MPC85xx_OPENPIC_IRQ_OFFSET)
-#define MPC85xx_IRQ_EXT11       (43 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_EXT0        (48 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_EXT1        (49 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_EXT2        (50 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_EXT3        (51 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_EXT4        (52 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_EXT5        (53 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_EXT6        (54 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_EXT7        (55 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_EXT8        (56 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_EXT9        (57 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_EXT10       (58 + MPC85xx_OPENPIC_IRQ_OFFSET)
+#define MPC85xx_IRQ_EXT11       (59 + MPC85xx_OPENPIC_IRQ_OFFSET)
 
 /* CPM related interrupts */
 #define	SIU_INT_ERROR		((uint)0x00+CPM_IRQ_OFFSET)
diff --git a/include/asm-ppc/kexec.h b/include/asm-ppc/kexec.h
new file mode 100644
--- /dev/null
+++ b/include/asm-ppc/kexec.h
@@ -0,0 +1,40 @@
+#ifndef _PPC_KEXEC_H
+#define _PPC_KEXEC_H
+
+#ifdef CONFIG_KEXEC
+
+/*
+ * KEXEC_SOURCE_MEMORY_LIMIT maximum page get_free_page can return.
+ * I.e. Maximum page that is mapped directly into kernel memory,
+ * and kmap is not required.
+ *
+ * Someone correct me if FIXADDR_START - PAGEOFFSET is not the correct
+ * calculation for the amount of memory directly mappable into the
+ * kernel memory space.
+ */
+
+/* Maximum physical address we can use pages from */
+#define KEXEC_SOURCE_MEMORY_LIMIT (-1UL)
+/* Maximum address we can reach in physical address mode */
+#define KEXEC_DESTINATION_MEMORY_LIMIT (-1UL)
+/* Maximum address we can use for the control code buffer */
+#define KEXEC_CONTROL_MEMORY_LIMIT TASK_SIZE
+
+#define KEXEC_CONTROL_CODE_SIZE	4096
+
+/* The native architecture */
+#define KEXEC_ARCH KEXEC_ARCH_PPC
+
+#ifndef __ASSEMBLY__
+
+extern void *crash_notes;
+
+struct kimage;
+
+extern void machine_kexec_simple(struct kimage *image);
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* CONFIG_KEXEC */
+
+#endif /* _PPC_KEXEC_H */
diff --git a/include/asm-ppc/machdep.h b/include/asm-ppc/machdep.h
--- a/include/asm-ppc/machdep.h
+++ b/include/asm-ppc/machdep.h
@@ -4,6 +4,7 @@
 
 #include <linux/config.h>
 #include <linux/init.h>
+#include <linux/kexec.h>
 
 #include <asm/setup.h>
 #include <asm/page.h>
@@ -114,6 +115,36 @@ struct machdep_calls {
 	/* functions for dealing with other cpus */
 	struct smp_ops_t *smp_ops;
 #endif /* CONFIG_SMP */
+
+#ifdef CONFIG_KEXEC
+	/* Called to shutdown machine specific hardware not already controlled
+	 * by other drivers.
+	 * XXX Should we move this one out of kexec scope?
+	 */
+	void (*machine_shutdown)(void);
+
+	/* Called to do the minimal shutdown needed to run a kexec'd kernel
+	 * to run successfully.
+	 * XXX Should we move this one out of kexec scope?
+	 */
+	void (*machine_crash_shutdown)(void);
+
+	/* Called to do what every setup is needed on image and the
+	 * reboot code buffer. Returns 0 on success.
+	 * Provide your own (maybe dummy) implementation if your platform
+	 * claims to support kexec.
+	 */
+	int (*machine_kexec_prepare)(struct kimage *image);
+
+	/* Called to handle any machine specific cleanup on image */
+	void (*machine_kexec_cleanup)(struct kimage *image);
+
+	/* Called to perform the _real_ kexec.
+	 * Do NOT allocate memory or fail here. We are past the point of
+	 * no return.
+	 */
+	void (*machine_kexec)(struct kimage *image);
+#endif /* CONFIG_KEXEC */
 };
 
 extern struct machdep_calls ppc_md;
diff --git a/include/asm-ppc/macio.h b/include/asm-ppc/macio.h
--- a/include/asm-ppc/macio.h
+++ b/include/asm-ppc/macio.h
@@ -1,6 +1,7 @@
 #ifndef __MACIO_ASIC_H__
 #define __MACIO_ASIC_H__
 
+#include <linux/mod_devicetable.h>
 #include <asm/of_device.h>
 
 extern struct bus_type macio_bus_type;
@@ -120,10 +121,10 @@ static inline struct pci_dev *macio_get_
 struct macio_driver
 {
 	char			*name;
-	struct of_match		*match_table;
+	struct of_device_id	*match_table;
 	struct module		*owner;
 
-	int	(*probe)(struct macio_dev* dev, const struct of_match *match);
+	int	(*probe)(struct macio_dev* dev, const struct of_device_id *match);
 	int	(*remove)(struct macio_dev* dev);
 
 	int	(*suspend)(struct macio_dev* dev, pm_message_t state);
diff --git a/include/asm-ppc/mmu.h b/include/asm-ppc/mmu.h
--- a/include/asm-ppc/mmu.h
+++ b/include/asm-ppc/mmu.h
@@ -405,7 +405,7 @@ typedef struct _P601_BAT {
 
 #define MAS0_TLBSEL(x)	((x << 28) & 0x30000000)
 #define MAS0_ESEL(x)	((x << 16) & 0x0FFF0000)
-#define MAS0_NV		0x00000FFF
+#define MAS0_NV(x)	((x) & 0x00000FFF)
 
 #define MAS1_VALID 	0x80000000
 #define MAS1_IPROT	0x40000000
diff --git a/include/asm-ppc/mmu_context.h b/include/asm-ppc/mmu_context.h
--- a/include/asm-ppc/mmu_context.h
+++ b/include/asm-ppc/mmu_context.h
@@ -63,7 +63,7 @@ static inline void enter_lazy_tlb(struct
 #define LAST_CONTEXT    	255
 #define FIRST_CONTEXT    	1
 
-#elif defined(CONFIG_E500)
+#elif defined(CONFIG_E200) || defined(CONFIG_E500)
 #define NO_CONTEXT      	256
 #define LAST_CONTEXT    	255
 #define FIRST_CONTEXT    	1
@@ -149,6 +149,7 @@ static inline void get_mmu_context(struc
  */
 static inline void destroy_context(struct mm_struct *mm)
 {
+	preempt_disable();
 	if (mm->context != NO_CONTEXT) {
 		clear_bit(mm->context, context_map);
 		mm->context = NO_CONTEXT;
@@ -156,6 +157,7 @@ static inline void destroy_context(struc
 		atomic_inc(&nr_free_contexts);
 #endif
 	}
+	preempt_enable();
 }
 
 static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
diff --git a/include/asm-ppc/mpc10x.h b/include/asm-ppc/mpc10x.h
--- a/include/asm-ppc/mpc10x.h
+++ b/include/asm-ppc/mpc10x.h
@@ -159,6 +159,13 @@ extern unsigned long			ioremap_base;
 #define	MPC10X_MAPA_EUMB_BASE		(ioremap_base - MPC10X_EUMB_SIZE)
 #define	MPC10X_MAPB_EUMB_BASE		MPC10X_MAPA_EUMB_BASE
 
+enum ppc_sys_devices {
+	MPC10X_IIC1,
+	MPC10X_DMA0,
+	MPC10X_DMA1,
+	MPC10X_UART0,
+	MPC10X_UART1,
+};
 
 int mpc10x_bridge_init(struct pci_controller *hose,
 		       uint current_map,
diff --git a/include/asm-ppc/mpc85xx.h b/include/asm-ppc/mpc85xx.h
--- a/include/asm-ppc/mpc85xx.h
+++ b/include/asm-ppc/mpc85xx.h
@@ -25,7 +25,7 @@
 #ifdef CONFIG_MPC8540_ADS
 #include <platforms/85xx/mpc8540_ads.h>
 #endif
-#ifdef CONFIG_MPC8555_CDS
+#if defined(CONFIG_MPC8555_CDS) || defined(CONFIG_MPC8548_CDS)
 #include <platforms/85xx/mpc8555_cds.h>
 #endif
 #ifdef CONFIG_MPC8560_ADS
@@ -74,7 +74,7 @@ extern unsigned char __res[];
 #define MPC85xx_GUTS_OFFSET	(0xe0000)
 #define MPC85xx_GUTS_SIZE	(0x01000)
 #define MPC85xx_IIC1_OFFSET	(0x03000)
-#define MPC85xx_IIC1_SIZE	(0x01000)
+#define MPC85xx_IIC1_SIZE	(0x00100)
 #define MPC85xx_OPENPIC_OFFSET	(0x40000)
 #define MPC85xx_OPENPIC_SIZE	(0x40000)
 #define MPC85xx_PCI1_OFFSET	(0x08000)
@@ -127,8 +127,64 @@ enum ppc_sys_devices {
 	MPC85xx_CPM_MCC2,
 	MPC85xx_CPM_SMC1,
 	MPC85xx_CPM_SMC2,
+	MPC85xx_eTSEC1,
+	MPC85xx_eTSEC2,
+	MPC85xx_eTSEC3,
+	MPC85xx_eTSEC4,
+	MPC85xx_IIC2,
 };
 
+/* Internal interrupts are all Level Sensitive, and Positive Polarity */
+#define MPC85XX_INTERNAL_IRQ_SENSES \
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal  0 */	\
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal  1 */	\
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal  2 */	\
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal  3 */	\
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal  4 */	\
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal  5 */	\
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal  6 */	\
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal  7 */	\
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal  8 */	\
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal  9 */	\
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 10 */	\
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 11 */	\
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 12 */	\
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 13 */	\
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 14 */	\
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 15 */	\
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 16 */	\
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 17 */	\
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 18 */	\
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 19 */	\
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 20 */	\
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 21 */	\
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 22 */	\
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 23 */	\
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 24 */	\
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 25 */	\
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 26 */	\
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 27 */	\
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 28 */	\
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 29 */	\
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 30 */	\
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 31 */	\
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 32 */	\
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 33 */	\
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 34 */	\
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 35 */	\
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 36 */	\
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 37 */	\
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 38 */	\
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 39 */	\
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 40 */	\
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 41 */	\
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 42 */	\
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 43 */	\
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 44 */	\
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 45 */	\
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),	/* Internal 46 */	\
+	(IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE)	/* Internal 47 */
+
 #endif /* CONFIG_85xx */
 #endif /* __ASM_MPC85xx_H__ */
 #endif /* __KERNEL__ */
diff --git a/include/asm-ppc/mpc8xx.h b/include/asm-ppc/mpc8xx.h
--- a/include/asm-ppc/mpc8xx.h
+++ b/include/asm-ppc/mpc8xx.h
@@ -68,6 +68,10 @@
 #include <platforms/lantec.h>
 #endif
 
+#if defined(CONFIG_MPC885ADS)
+#include <platforms/mpc885ads.h>
+#endif
+
 /* Currently, all 8xx boards that support a processor to PCI/ISA bridge
  * use the same memory map.
  */
diff --git a/include/asm-ppc/ocp.h b/include/asm-ppc/ocp.h
--- a/include/asm-ppc/ocp.h
+++ b/include/asm-ppc/ocp.h
@@ -189,7 +189,7 @@ extern void ocp_for_each_device(void(*ca
 /* Sysfs support */
 #define OCP_SYSFS_ADDTL(type, format, name, field)			\
 static ssize_t								\
-show_##name##_##field(struct device *dev, char *buf)			\
+show_##name##_##field(struct device *dev, struct device_attribute *attr, char *buf)			\
 {									\
 	struct ocp_device *odev = to_ocp_dev(dev);			\
 	type *add = odev->def->additions;				\
@@ -202,10 +202,6 @@ static DEVICE_ATTR(name##_##field, S_IRU
 #include <asm/ibm_ocp.h>
 #endif
 
-#ifdef CONFIG_FSL_OCP
-#include <asm/fsl_ocp.h>
-#endif
-
 #endif				/* CONFIG_PPC_OCP */
 #endif				/* __OCP_H__ */
 #endif				/* __KERNEL__ */
diff --git a/include/asm-ppc/of_device.h b/include/asm-ppc/of_device.h
--- a/include/asm-ppc/of_device.h
+++ b/include/asm-ppc/of_device.h
@@ -24,20 +24,8 @@ struct of_device
 };
 #define	to_of_device(d) container_of(d, struct of_device, dev)
 
-/*
- * Struct used for matching a device
- */
-struct of_match
-{
-	char	*name;
-	char	*type;
-	char	*compatible;
-	void	*data;
-};
-#define OF_ANY_MATCH		((char *)-1L)
-
-extern const struct of_match *of_match_device(
-	const struct of_match *matches, const struct of_device *dev);
+extern const struct of_device_id *of_match_device(
+	const struct of_device_id *matches, const struct of_device *dev);
 
 extern struct of_device *of_dev_get(struct of_device *dev);
 extern void of_dev_put(struct of_device *dev);
@@ -49,10 +37,10 @@ extern void of_dev_put(struct of_device 
 struct of_platform_driver
 {
 	char			*name;
-	struct of_match		*match_table;
+	struct of_device_id	*match_table;
 	struct module		*owner;
 
-	int	(*probe)(struct of_device* dev, const struct of_match *match);
+	int	(*probe)(struct of_device* dev, const struct of_device_id *match);
 	int	(*remove)(struct of_device* dev);
 
 	int	(*suspend)(struct of_device* dev, pm_message_t state);
diff --git a/include/asm-ppc/open_pic.h b/include/asm-ppc/open_pic.h
--- a/include/asm-ppc/open_pic.h
+++ b/include/asm-ppc/open_pic.h
@@ -25,6 +25,11 @@
 #define OPENPIC_VEC_IPI		118	/* and up */
 #define OPENPIC_VEC_SPURIOUS	255
 
+/* Priorities */
+#define OPENPIC_PRIORITY_IPI_BASE	10
+#define OPENPIC_PRIORITY_DEFAULT	4
+#define OPENPIC_PRIORITY_NMI		9
+
 /* OpenPIC IRQ controller structure */
 extern struct hw_interrupt_type open_pic;
 
@@ -42,6 +47,7 @@ extern int epic_serial_mode;
 extern void openpic_set_sources(int first_irq, int num_irqs, void __iomem *isr);
 extern void openpic_init(int linux_irq_offset);
 extern void openpic_init_nmi_irq(u_int irq);
+extern void openpic_set_irq_priority(u_int irq, u_int pri);
 extern void openpic_hookup_cascade(u_int irq, char *name,
 				   int (*cascade_fn)(struct pt_regs *));
 extern u_int openpic_irq(void);
diff --git a/include/asm-ppc/pc_serial.h b/include/asm-ppc/pc_serial.h
--- a/include/asm-ppc/pc_serial.h
+++ b/include/asm-ppc/pc_serial.h
@@ -35,93 +35,9 @@
 #define STD_COM4_FLAGS ASYNC_BOOT_AUTOCONF
 #endif
 
-#ifdef CONFIG_SERIAL_MANY_PORTS
-#define FOURPORT_FLAGS ASYNC_FOURPORT
-#define ACCENT_FLAGS 0
-#define BOCA_FLAGS 0
-#define HUB6_FLAGS 0
-#endif
-	
-/*
- * The following define the access methods for the HUB6 card. All
- * access is through two ports for all 24 possible chips. The card is
- * selected through the high 2 bits, the port on that card with the
- * "middle" 3 bits, and the register on that port with the bottom
- * 3 bits.
- *
- * While the access port and interrupt is configurable, the default
- * port locations are 0x302 for the port control register, and 0x303
- * for the data read/write register. Normally, the interrupt is at irq3
- * but can be anything from 3 to 7 inclusive. Note that using 3 will
- * require disabling com2.
- */
-
-#define C_P(card,port) (((card)<<6|(port)<<3) + 1)
-
-#define STD_SERIAL_PORT_DEFNS			\
+#define SERIAL_PORT_DFNS			\
 	/* UART CLK   PORT IRQ     FLAGS        */			\
 	{ 0, BASE_BAUD, 0x3F8, 4, STD_COM_FLAGS },	/* ttyS0 */	\
 	{ 0, BASE_BAUD, 0x2F8, 3, STD_COM_FLAGS },	/* ttyS1 */	\
 	{ 0, BASE_BAUD, 0x3E8, 4, STD_COM_FLAGS },	/* ttyS2 */	\
 	{ 0, BASE_BAUD, 0x2E8, 3, STD_COM4_FLAGS },	/* ttyS3 */
-
-
-#ifdef CONFIG_SERIAL_MANY_PORTS
-#define EXTRA_SERIAL_PORT_DEFNS			\
-	{ 0, BASE_BAUD, 0x1A0, 9, FOURPORT_FLAGS }, 	/* ttyS4 */	\
-	{ 0, BASE_BAUD, 0x1A8, 9, FOURPORT_FLAGS },	/* ttyS5 */	\
-	{ 0, BASE_BAUD, 0x1B0, 9, FOURPORT_FLAGS },	/* ttyS6 */	\
-	{ 0, BASE_BAUD, 0x1B8, 9, FOURPORT_FLAGS },	/* ttyS7 */	\
-	{ 0, BASE_BAUD, 0x2A0, 5, FOURPORT_FLAGS },	/* ttyS8 */	\
-	{ 0, BASE_BAUD, 0x2A8, 5, FOURPORT_FLAGS },	/* ttyS9 */	\
-	{ 0, BASE_BAUD, 0x2B0, 5, FOURPORT_FLAGS },	/* ttyS10 */	\
-	{ 0, BASE_BAUD, 0x2B8, 5, FOURPORT_FLAGS },	/* ttyS11 */	\
-	{ 0, BASE_BAUD, 0x330, 4, ACCENT_FLAGS },	/* ttyS12 */	\
-	{ 0, BASE_BAUD, 0x338, 4, ACCENT_FLAGS },	/* ttyS13 */	\
-	{ 0, BASE_BAUD, 0x000, 0, 0 },	/* ttyS14 (spare) */		\
-	{ 0, BASE_BAUD, 0x000, 0, 0 },	/* ttyS15 (spare) */		\
-	{ 0, BASE_BAUD, 0x100, 12, BOCA_FLAGS },	/* ttyS16 */	\
-	{ 0, BASE_BAUD, 0x108, 12, BOCA_FLAGS },	/* ttyS17 */	\
-	{ 0, BASE_BAUD, 0x110, 12, BOCA_FLAGS },	/* ttyS18 */	\
-	{ 0, BASE_BAUD, 0x118, 12, BOCA_FLAGS },	/* ttyS19 */	\
-	{ 0, BASE_BAUD, 0x120, 12, BOCA_FLAGS },	/* ttyS20 */	\
-	{ 0, BASE_BAUD, 0x128, 12, BOCA_FLAGS },	/* ttyS21 */	\
-	{ 0, BASE_BAUD, 0x130, 12, BOCA_FLAGS },	/* ttyS22 */	\
-	{ 0, BASE_BAUD, 0x138, 12, BOCA_FLAGS },	/* ttyS23 */	\
-	{ 0, BASE_BAUD, 0x140, 12, BOCA_FLAGS },	/* ttyS24 */	\
-	{ 0, BASE_BAUD, 0x148, 12, BOCA_FLAGS },	/* ttyS25 */	\
-	{ 0, BASE_BAUD, 0x150, 12, BOCA_FLAGS },	/* ttyS26 */	\
-	{ 0, BASE_BAUD, 0x158, 12, BOCA_FLAGS },	/* ttyS27 */	\
-	{ 0, BASE_BAUD, 0x160, 12, BOCA_FLAGS },	/* ttyS28 */	\
-	{ 0, BASE_BAUD, 0x168, 12, BOCA_FLAGS },	/* ttyS29 */	\
-	{ 0, BASE_BAUD, 0x170, 12, BOCA_FLAGS },	/* ttyS30 */	\
-	{ 0, BASE_BAUD, 0x178, 12, BOCA_FLAGS },	/* ttyS31 */
-#else
-#define EXTRA_SERIAL_PORT_DEFNS
-#endif
-
-/* You can have up to four HUB6's in the system, but I've only
- * included two cards here for a total of twelve ports.
- */
-#if (defined(CONFIG_HUB6) && defined(CONFIG_SERIAL_MANY_PORTS))
-#define HUB6_SERIAL_PORT_DFNS		\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,0) },  /* ttyS32 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,1) },  /* ttyS33 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,2) },  /* ttyS34 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,3) },  /* ttyS35 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,4) },  /* ttyS36 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,5) },  /* ttyS37 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,0) },  /* ttyS38 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,1) },  /* ttyS39 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,2) },  /* ttyS40 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,3) },  /* ttyS41 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,4) },  /* ttyS42 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,5) },  /* ttyS43 */
-#else
-#define HUB6_SERIAL_PORT_DFNS
-#endif
-
-#define SERIAL_PORT_DFNS		\
-	STD_SERIAL_PORT_DEFNS		\
-	EXTRA_SERIAL_PORT_DEFNS		\
-	HUB6_SERIAL_PORT_DFNS
diff --git a/include/asm-ppc/pci.h b/include/asm-ppc/pci.h
--- a/include/asm-ppc/pci.h
+++ b/include/asm-ppc/pci.h
@@ -37,7 +37,7 @@ extern inline void pcibios_set_master(st
 	/* No special bus mastering setup handling */
 }
 
-extern inline void pcibios_penalize_isa_irq(int irq)
+extern inline void pcibios_penalize_isa_irq(int irq, int active)
 {
 	/* We don't do dynamic PCI IRQ allocation */
 }
@@ -69,6 +69,16 @@ extern unsigned long pci_bus_to_phys(uns
 #define pci_unmap_len(PTR, LEN_NAME)		(0)
 #define pci_unmap_len_set(PTR, LEN_NAME, VAL)	do { } while (0)
 
+#ifdef CONFIG_PCI
+static inline void pci_dma_burst_advice(struct pci_dev *pdev,
+					enum pci_dma_burst_strategy *strat,
+					unsigned long *strategy_parameter)
+{
+	*strat = PCI_DMA_BURST_INFINITY;
+	*strategy_parameter = ~0UL;
+}
+#endif
+
 /*
  * At present there are very few 32-bit PPC machines that can have
  * memory above the 4GB point, and we don't support that.
@@ -95,6 +105,10 @@ extern void
 pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
 			struct resource *res);
 
+extern void
+pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
+			struct pci_bus_region *region);
+
 extern void pcibios_add_platform_entries(struct pci_dev *dev);
 
 struct file;
@@ -103,6 +117,12 @@ extern pgprot_t	pci_phys_mem_access_prot
 					 unsigned long size,
 					 pgprot_t prot);
 
+#define HAVE_ARCH_PCI_RESOURCE_TO_USER
+extern void pci_resource_to_user(const struct pci_dev *dev, int bar,
+				 const struct resource *rsrc,
+				 u64 *start, u64 *end);
+
+
 #endif	/* __KERNEL__ */
 
 #endif /* __PPC_PCI_H */
diff --git a/include/asm-ppc/pgtable.h b/include/asm-ppc/pgtable.h
--- a/include/asm-ppc/pgtable.h
+++ b/include/asm-ppc/pgtable.h
@@ -202,18 +202,64 @@ extern unsigned long ioremap_bot, iorema
  *
  * Note that these bits preclude future use of a page size
  * less than 4KB.
+ *
+ *
+ * PPC 440 core has following TLB attribute fields;
+ *
+ *   TLB1:
+ *   0  1  2  3  4  ... 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
+ *   RPN.................................  -  -  -  -  -  - ERPN.......
+ *
+ *   TLB2:
+ *   0  1  2  3  4  ... 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
+ *   -  -  -  -  -    - U0 U1 U2 U3 W  I  M  G  E   - UX UW UR SX SW SR
+ *
+ * There are some constrains and options, to decide mapping software bits
+ * into TLB entry.
+ *
+ *   - PRESENT *must* be in the bottom three bits because swap cache
+ *     entries use the top 29 bits for TLB2.
+ *
+ *   - FILE *must* be in the bottom three bits because swap cache
+ *     entries use the top 29 bits for TLB2.
+ *
+ *   - CACHE COHERENT bit (M) has no effect on PPC440 core, because it
+ *     doesn't support SMP. So we can use this as software bit, like
+ *     DIRTY.
+ *
+ * With the PPC 44x Linux implementation, the 0-11th LSBs of the PTE are used
+ * for memory protection related functions (see PTE structure in
+ * include/asm-ppc/mmu.h).  The _PAGE_XXX definitions in this file map to the
+ * above bits.  Note that the bit values are CPU specific, not architecture
+ * specific.
+ *
+ * The kernel PTE entry holds an arch-dependent swp_entry structure under
+ * certain situations. In other words, in such situations some portion of
+ * the PTE bits are used as a swp_entry. In the PPC implementation, the
+ * 3-24th LSB are shared with swp_entry, however the 0-2nd three LSB still
+ * hold protection values. That means the three protection bits are
+ * reserved for both PTE and SWAP entry at the most significant three
+ * LSBs.
+ *
+ * There are three protection bits available for SWAP entry:
+ *	_PAGE_PRESENT
+ *	_PAGE_FILE
+ *	_PAGE_HASHPTE (if HW has)
+ *
+ * So those three bits have to be inside of 0-2nd LSB of PTE.
+ *
  */
+
 #define _PAGE_PRESENT	0x00000001		/* S: PTE valid */
 #define	_PAGE_RW	0x00000002		/* S: Write permission */
-#define	_PAGE_DIRTY	0x00000004		/* S: Page dirty */
+#define _PAGE_FILE	0x00000004		/* S: nonlinear file mapping */
 #define _PAGE_ACCESSED	0x00000008		/* S: Page referenced */
 #define _PAGE_HWWRITE	0x00000010		/* H: Dirty & RW */
 #define _PAGE_HWEXEC	0x00000020		/* H: Execute permission */
 #define	_PAGE_USER	0x00000040		/* S: User page */
 #define	_PAGE_ENDIAN	0x00000080		/* H: E bit */
 #define	_PAGE_GUARDED	0x00000100		/* H: G bit */
-#define	_PAGE_COHERENT	0x00000200		/* H: M bit */
-#define _PAGE_FILE	0x00000400		/* S: nonlinear file mapping */
+#define	_PAGE_DIRTY	0x00000200		/* S: Page dirty */
 #define	_PAGE_NO_CACHE	0x00000400		/* H: I bit */
 #define	_PAGE_WRITETHRU	0x00000800		/* H: W bit */
 
@@ -267,8 +313,6 @@ extern unsigned long ioremap_bot, iorema
 #define _PMD_PRESENT_MASK (PAGE_MASK)
 #define _PMD_BAD	(~PAGE_MASK)
 
-#define NUM_TLBCAMS	(16)
-
 #elif defined(CONFIG_8xx)
 /* Definitions for 8xx embedded chips. */
 #define _PAGE_PRESENT	0x0001	/* Page is valid */
diff --git a/include/asm-ppc/ppc4xx_dma.h b/include/asm-ppc/ppc4xx_dma.h
--- a/include/asm-ppc/ppc4xx_dma.h
+++ b/include/asm-ppc/ppc4xx_dma.h
@@ -285,7 +285,7 @@ typedef uint32_t sgl_handle_t;
 
 #define GET_DMA_POLARITY(chan) (DMAReq_ActiveLow(chan) | DMAAck_ActiveLow(chan) | EOT_ActiveLow(chan))
 
-#elif defined(CONFIG_STBXXX_DMA)		/* stb03xxx */
+#elif defined(CONFIG_STB03xxx)		/* stb03xxx */
 
 #define DMA_PPC4xx_SIZE	4096
 
diff --git a/include/asm-ppc/ppc_asm.h b/include/asm-ppc/ppc_asm.h
--- a/include/asm-ppc/ppc_asm.h
+++ b/include/asm-ppc/ppc_asm.h
@@ -174,6 +174,8 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601)
 #define CLR_TOP32(r)
 #endif /* CONFIG_PPC64BRIDGE */
 
+#define RFCI		.long 0x4c000066	/* rfci instruction */
+#define RFDI		.long 0x4c00004e	/* rfdi instruction */
 #define RFMCI		.long 0x4c00004c	/* rfmci instruction */
 
 #ifdef CONFIG_IBM405_ERR77
@@ -184,6 +186,12 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601)
 #define PPC405_ERR77_SYNC
 #endif
 
+#ifdef CONFIG_IBM440EP_ERR42
+#define PPC440EP_ERR42 isync
+#else
+#define PPC440EP_ERR42
+#endif
+
 /* The boring bits... */
 
 /* Condition Register Bit Fields */
diff --git a/include/asm-ppc/ppc_sys.h b/include/asm-ppc/ppc_sys.h
--- a/include/asm-ppc/ppc_sys.h
+++ b/include/asm-ppc/ppc_sys.h
@@ -27,6 +27,8 @@
 #include <asm/mpc85xx.h>
 #elif defined(CONFIG_PPC_MPC52xx)
 #include <asm/mpc52xx.h>
+#elif defined(CONFIG_MPC10X_BRIDGE)
+#include <asm/mpc10x.h>
 #else
 #error "need definition of ppc_sys_devices"
 #endif
diff --git a/include/asm-ppc/reg.h b/include/asm-ppc/reg.h
--- a/include/asm-ppc/reg.h
+++ b/include/asm-ppc/reg.h
@@ -160,6 +160,7 @@
 #define HID0_ICFI	(1<<11)		/* Instr. Cache Flash Invalidate */
 #define HID0_DCI	(1<<10)		/* Data Cache Invalidate */
 #define HID0_SPD	(1<<9)		/* Speculative disable */
+#define HID0_DAPUEN	(1<<8)		/* Debug APU enable */
 #define HID0_SGE	(1<<7)		/* Store Gathering Enable */
 #define HID0_SIED	(1<<7)		/* Serial Instr. Execution [Disable] */
 #define HID0_DFCA	(1<<6)		/* Data Cache Flush Assist */
diff --git a/include/asm-ppc/reg_booke.h b/include/asm-ppc/reg_booke.h
--- a/include/asm-ppc/reg_booke.h
+++ b/include/asm-ppc/reg_booke.h
@@ -165,6 +165,8 @@ do {						\
 #define SPRN_MCSRR1	0x23B	/* Machine Check Save and Restore Register 1 */
 #define SPRN_MCSR	0x23C	/* Machine Check Status Register */
 #define SPRN_MCAR	0x23D	/* Machine Check Address Register */
+#define SPRN_DSRR0	0x23E	/* Debug Save and Restore Register 0 */
+#define SPRN_DSRR1	0x23F	/* Debug Save and Restore Register 1 */
 #define SPRN_MAS0	0x270	/* MMU Assist Register 0 */
 #define SPRN_MAS1	0x271	/* MMU Assist Register 1 */
 #define SPRN_MAS2	0x272	/* MMU Assist Register 2 */
@@ -264,6 +266,17 @@ do {						\
 #define MCSR_BUS_IPERR 	0x00000002UL /* Instruction parity Error */
 #define MCSR_BUS_RPERR 	0x00000001UL /* Read parity Error */
 #endif
+#ifdef CONFIG_E200
+#define MCSR_MCP 	0x80000000UL /* Machine Check Input Pin */
+#define MCSR_CP_PERR 	0x20000000UL /* Cache Push Parity Error */
+#define MCSR_CPERR 	0x10000000UL /* Cache Parity Error */
+#define MCSR_EXCP_ERR 	0x08000000UL /* ISI, ITLB, or Bus Error on 1st insn
+					fetch for an exception handler */
+#define MCSR_BUS_IRERR 	0x00000010UL /* Read Bus Error on instruction fetch*/
+#define MCSR_BUS_DRERR 	0x00000008UL /* Read Bus Error on data load */
+#define MCSR_BUS_WRERR 	0x00000004UL /* Write Bus Error on buffered
+					store or cache line push */
+#endif
 
 /* Bit definitions for the DBSR. */
 /*
@@ -311,6 +324,7 @@ do {						\
 #define ESR_ST		0x00800000	/* Store Operation */
 #define ESR_DLK		0x00200000	/* Data Cache Locking */
 #define ESR_ILK		0x00100000	/* Instr. Cache Locking */
+#define ESR_PUO		0x00040000	/* Unimplemented Operation exception */
 #define ESR_BO		0x00020000	/* Byte Ordering */
 
 /* Bit definitions related to the DBCR0. */
@@ -387,10 +401,12 @@ do {						\
 #define ICCR_CACHE	1		/* Cacheable */
 
 /* Bit definitions for L1CSR0. */
+#define L1CSR0_CLFC	0x00000100	/* Cache Lock Bits Flash Clear */
 #define L1CSR0_DCFI	0x00000002	/* Data Cache Flash Invalidate */
+#define L1CSR0_CFI	0x00000002	/* Cache Flash Invalidate */
 #define L1CSR0_DCE	0x00000001	/* Data Cache Enable */
 
-/* Bit definitions for L1CSR0. */
+/* Bit definitions for L1CSR1. */
 #define L1CSR1_ICLFR	0x00000100	/* Instr Cache Lock Bits Flash Reset */
 #define L1CSR1_ICFI	0x00000002	/* Instr Cache Flash Invalidate */
 #define L1CSR1_ICE	0x00000001	/* Instr Cache Enable */
diff --git a/include/asm-ppc/seccomp.h b/include/asm-ppc/seccomp.h
new file mode 100644
--- /dev/null
+++ b/include/asm-ppc/seccomp.h
@@ -0,0 +1,10 @@
+#ifndef _ASM_SECCOMP_H
+
+#include <linux/unistd.h>
+
+#define __NR_seccomp_read __NR_read
+#define __NR_seccomp_write __NR_write
+#define __NR_seccomp_exit __NR_exit
+#define __NR_seccomp_sigreturn __NR_rt_sigreturn
+
+#endif /* _ASM_SECCOMP_H */
diff --git a/include/asm-ppc/smp.h b/include/asm-ppc/smp.h
--- a/include/asm-ppc/smp.h
+++ b/include/asm-ppc/smp.h
@@ -44,7 +44,7 @@ extern void smp_message_recv(int, struct
 #define NO_PROC_ID		0xFF            /* No processor magic marker */
 #define PROC_CHANGE_PENALTY	20
 
-#define smp_processor_id() (current_thread_info()->cpu)
+#define raw_smp_processor_id()	(current_thread_info()->cpu)
 
 extern int __cpu_up(unsigned int cpu);
 
diff --git a/include/asm-ppc/thread_info.h b/include/asm-ppc/thread_info.h
--- a/include/asm-ppc/thread_info.h
+++ b/include/asm-ppc/thread_info.h
@@ -20,7 +20,8 @@ struct thread_info {
 	unsigned long		flags;		/* low level flags */
 	unsigned long		local_flags;	/* non-racy flags */
 	int			cpu;		/* cpu we're on */
-	int			preempt_count;
+	int			preempt_count;	/* 0 => preemptable,
+						   <0 => BUG */
 	struct restart_block	restart_block;
 };
 
@@ -77,12 +78,19 @@ static inline struct thread_info *curren
 #define TIF_POLLING_NRFLAG	4	/* true if poll_idle() is polling
 					   TIF_NEED_RESCHED */
 #define TIF_MEMDIE		5
+#define TIF_SYSCALL_AUDIT       6       /* syscall auditing active */
+#define TIF_SECCOMP             7      /* secure computing */
+
 /* as above, but as bit values */
 #define _TIF_SYSCALL_TRACE	(1<<TIF_SYSCALL_TRACE)
 #define _TIF_NOTIFY_RESUME	(1<<TIF_NOTIFY_RESUME)
 #define _TIF_SIGPENDING		(1<<TIF_SIGPENDING)
 #define _TIF_NEED_RESCHED	(1<<TIF_NEED_RESCHED)
 #define _TIF_POLLING_NRFLAG	(1<<TIF_POLLING_NRFLAG)
+#define _TIF_SYSCALL_AUDIT      (1<<TIF_SYSCALL_AUDIT)
+#define _TIF_SECCOMP            (1<<TIF_SECCOMP)
+
+#define _TIF_SYSCALL_T_OR_A     (_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP)
 
 /*
  * Non racy (local) flags bit numbers
diff --git a/include/asm-ppc/time.h b/include/asm-ppc/time.h
--- a/include/asm-ppc/time.h
+++ b/include/asm-ppc/time.h
@@ -58,7 +58,7 @@ static __inline__ void set_dec(unsigned 
 /* Accessor functions for the timebase (RTC on 601) registers. */
 /* If one day CONFIG_POWER is added just define __USE_RTC as 1 */
 #ifdef CONFIG_6xx
-extern __inline__ int const __USE_RTC(void) {
+extern __inline__ int __attribute_pure__ __USE_RTC(void) {
 	return (mfspr(SPRN_PVR)>>16) == 1;
 }
 #else
diff --git a/include/asm-ppc/unistd.h b/include/asm-ppc/unistd.h
--- a/include/asm-ppc/unistd.h
+++ b/include/asm-ppc/unistd.h
@@ -262,7 +262,7 @@
 #define __NR_rtas		255
 #define __NR_sys_debug_setcontext 256
 /* Number 257 is reserved for vserver */
-/* Number 258 is reserved for new sys_remap_file_pages */
+/* 258 currently unused */
 /* Number 259 is reserved for new sys_mbind */
 /* Number 260 is reserved for new sys_get_mempolicy */
 /* Number 261 is reserved for new sys_set_mempolicy */
@@ -277,8 +277,13 @@
 #define __NR_request_key	270
 #define __NR_keyctl		271
 #define __NR_waitid		272
+#define __NR_ioprio_set		273
+#define __NR_ioprio_get		274
+#define __NR_inotify_init	275
+#define __NR_inotify_add_watch	276
+#define __NR_inotify_rm_watch	277
 
-#define __NR_syscalls		273
+#define __NR_syscalls		278
 
 #define __NR(n)	#n
 
diff --git a/include/asm-ppc64/bug.h b/include/asm-ppc64/bug.h
--- a/include/asm-ppc64/bug.h
+++ b/include/asm-ppc64/bug.h
@@ -43,8 +43,8 @@ struct bug_entry *find_bug(unsigned long
 		".section __bug_table,\"a\"\n\t"		\
 		"	.llong 1b,%1,%2,%3\n"			\
 		".previous"					\
-		: : "r" (x), "i" (__LINE__), "i" (__FILE__),	\
-		    "i" (__FUNCTION__));			\
+		: : "r" ((long long)(x)), "i" (__LINE__),	\
+		    "i" (__FILE__), "i" (__FUNCTION__));	\
 } while (0)
 
 #define WARN_ON(x) do {						\
@@ -53,7 +53,8 @@ struct bug_entry *find_bug(unsigned long
 		".section __bug_table,\"a\"\n\t"		\
 		"	.llong 1b,%1,%2,%3\n"			\
 		".previous"					\
-		: : "r" (x), "i" (__LINE__ + BUG_WARNING_TRAP),	\
+		: : "r" ((long long)(x)),			\
+		    "i" (__LINE__ + BUG_WARNING_TRAP),		\
 		    "i" (__FILE__), "i" (__FUNCTION__));	\
 } while (0)
 
diff --git a/include/asm-ppc64/byteorder.h b/include/asm-ppc64/byteorder.h
--- a/include/asm-ppc64/byteorder.h
+++ b/include/asm-ppc64/byteorder.h
@@ -40,7 +40,6 @@ static __inline__ void st_le32(volatile 
 	__asm__ __volatile__ ("stwbrx %1,0,%2" : "=m" (*addr) : "r" (val), "r" (addr));
 }
 
-#if 0
 static __inline__ __attribute_const__ __u16 ___arch__swab16(__u16 value)
 {
 	__u16 result;
@@ -63,17 +62,8 @@ static __inline__ __attribute_const__ __
 	return result;
 }
 
-static __inline__ __attribute_const__ __u64 ___arch__swab64(__u64 value)
-{
-	__u64 result;
-#error implement me
-}
-
 #define __arch__swab16(x) ___arch__swab16(x)
 #define __arch__swab32(x) ___arch__swab32(x)
-#define __arch__swab64(x) ___arch__swab64(x)
-
-#endif
 
 /* The same, but returns converted value from the location pointer by addr. */
 #define __arch__swab16p(addr) ld_le16(addr)
diff --git a/include/asm-ppc64/compat.h b/include/asm-ppc64/compat.h
--- a/include/asm-ppc64/compat.h
+++ b/include/asm-ppc64/compat.h
@@ -26,6 +26,7 @@ typedef s32		compat_daddr_t;
 typedef u32		compat_caddr_t;
 typedef __kernel_fsid_t	compat_fsid_t;
 typedef s32		compat_key_t;
+typedef s32		compat_timer_t;
 
 typedef s32		compat_int_t;
 typedef s32		compat_long_t;
diff --git a/include/asm-ppc64/cputable.h b/include/asm-ppc64/cputable.h
--- a/include/asm-ppc64/cputable.h
+++ b/include/asm-ppc64/cputable.h
@@ -138,6 +138,7 @@ extern firmware_feature_t firmware_featu
 #define CPU_FTR_COHERENT_ICACHE  	ASM_CONST(0x0000020000000000)
 #define CPU_FTR_LOCKLESS_TLBIE		ASM_CONST(0x0000040000000000)
 #define CPU_FTR_MMCRA_SIHV		ASM_CONST(0x0000080000000000)
+#define CPU_FTR_CTRL			ASM_CONST(0x0000100000000000)
 
 /* Platform firmware features */
 #define FW_FTR_				ASM_CONST(0x0000000000000001)
@@ -148,7 +149,7 @@ extern firmware_feature_t firmware_featu
 
 #define CPU_FTR_PPCAS_ARCH_V2_BASE (CPU_FTR_SLB | \
                                  CPU_FTR_TLBIEL | CPU_FTR_NOEXECUTE | \
-                                 CPU_FTR_NODSISRALIGN)
+                                 CPU_FTR_NODSISRALIGN | CPU_FTR_CTRL)
 
 /* iSeries doesn't support large pages */
 #ifdef CONFIG_PPC_ISERIES
diff --git a/include/asm-ppc64/dma.h b/include/asm-ppc64/dma.h
--- a/include/asm-ppc64/dma.h
+++ b/include/asm-ppc64/dma.h
@@ -27,6 +27,8 @@
 /* Doesn't really apply... */
 #define MAX_DMA_ADDRESS  (~0UL)
 
+#if !defined(CONFIG_PPC_ISERIES) || defined(CONFIG_PCI)
+
 #define dma_outb	outb
 #define dma_inb		inb
 
@@ -323,4 +325,5 @@ extern int isa_dma_bridge_buggy;        
 #else                                                         
 #define isa_dma_bridge_buggy   (0)
 #endif
+#endif	/* !defined(CONFIG_PPC_ISERIES) || defined(CONFIG_PCI) */
 #endif /* _ASM_DMA_H */
diff --git a/include/asm-ppc64/emergency-restart.h b/include/asm-ppc64/emergency-restart.h
new file mode 100644
--- /dev/null
+++ b/include/asm-ppc64/emergency-restart.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_EMERGENCY_RESTART_H
+#define _ASM_EMERGENCY_RESTART_H
+
+#include <asm-generic/emergency-restart.h>
+
+#endif /* _ASM_EMERGENCY_RESTART_H */
diff --git a/include/asm-ppc64/hvconsole.h b/include/asm-ppc64/hvconsole.h
--- a/include/asm-ppc64/hvconsole.h
+++ b/include/asm-ppc64/hvconsole.h
@@ -29,12 +29,21 @@
  */
 #define MAX_NR_HVC_CONSOLES	16
 
+/* implemented by a low level driver */
+struct hv_ops {
+	int (*get_chars)(uint32_t vtermno, char *buf, int count);
+	int (*put_chars)(uint32_t vtermno, const char *buf, int count);
+};
 extern int hvc_get_chars(uint32_t vtermno, char *buf, int count);
 extern int hvc_put_chars(uint32_t vtermno, const char *buf, int count);
 
-/* Early discovery of console adapters. */
-extern int hvc_find_vtys(void);
+struct hvc_struct;
 
-/* Implemented by a console driver */
-extern int hvc_instantiate(uint32_t vtermno, int index);
+/* Register a vterm and a slot index for use as a console (console_init) */
+extern int hvc_instantiate(uint32_t vtermno, int index, struct hv_ops *ops);
+/* register a vterm for hvc tty operation (module_init or hotplug add) */
+extern struct hvc_struct * __devinit hvc_alloc(uint32_t vtermno, int irq,
+						 struct hv_ops *ops);
+/* remove a vterm from hvc tty operation (modele_exit or hotplug remove) */
+extern int __devexit hvc_remove(struct hvc_struct *hp);
 #endif /* _PPC64_HVCONSOLE_H */
diff --git a/include/asm-ppc64/iSeries/HvCall.h b/include/asm-ppc64/iSeries/HvCall.h
--- a/include/asm-ppc64/iSeries/HvCall.h
+++ b/include/asm-ppc64/iSeries/HvCall.h
@@ -1,84 +1,36 @@
 /*
  * HvCall.h
  * Copyright (C) 2001  Mike Corrigan IBM Corporation
- * 
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  */
-
-//===========================================================================
-//
-//	This file contains the "hypervisor call" interface which is used to
-//	drive the hypervisor from the OS.
-//
-//===========================================================================
+/*
+ * This file contains the "hypervisor call" interface which is used to
+ * drive the hypervisor from the OS.
+ */
 #ifndef _HVCALL_H
 #define _HVCALL_H
 
-//-------------------------------------------------------------------
-// Standard Includes
-//-------------------------------------------------------------------
 #include <asm/iSeries/HvCallSc.h>
 #include <asm/iSeries/HvTypes.h>
 #include <asm/paca.h>
 
-/*
-enum HvCall_ReturnCode
-{
-	HvCall_Good		= 0,
-	HvCall_Partial		= 1,
-	HvCall_NotOwned		= 2,
-	HvCall_NotFreed		= 3,
-	HvCall_UnspecifiedError	= 4
-};
-
-enum HvCall_TypeOfSIT
-{
-	HvCall_ReduceOnly	= 0,
-	HvCall_Unconditional	= 1
-};
-
-enum HvCall_TypeOfYield
-{
-	HvCall_YieldTimed	= 0,	// Yield until specified time
-	HvCall_YieldToActive	= 1,	// Yield until all active procs have run
-	HvCall_YieldToProc	= 2	// Yield until the specified processor has run
-};
-
-enum HvCall_InterruptMasks
-{
-	HvCall_MaskIPI		= 0x00000001,
-	HvCall_MaskLpEvent	= 0x00000002,
-	HvCall_MaskLpProd	= 0x00000004,
-	HvCall_MaskTimeout	= 0x00000008
-};
-
-enum HvCall_VaryOffChunkRc
-{
-	HvCall_VaryOffSucceeded		= 0,
-	HvCall_VaryOffWithdrawn		= 1,
-	HvCall_ChunkInLoadArea		= 2,
-	HvCall_ChunkInHPT		= 3,
-	HvCall_ChunkNotAccessible	= 4,
-	HvCall_ChunkInUse		= 5
-};
-*/
-
 /* Type of yield for HvCallBaseYieldProcessor */
-#define HvCall_YieldTimed 	0	// Yield until specified time (tb)
-#define HvCall_YieldToActive	1	// Yield until all active procs have run
-#define HvCall_YieldToProc	2	// Yield until the specified processor has run
+#define HvCall_YieldTimed	0	/* Yield until specified time (tb) */
+#define HvCall_YieldToActive	1	/* Yield until all active procs have run */
+#define HvCall_YieldToProc	2	/* Yield until the specified processor has run */
 
 /* interrupt masks for setEnabledInterrupts */
 #define HvCall_MaskIPI		0x00000001
@@ -86,7 +38,7 @@ enum HvCall_VaryOffChunkRc
 #define HvCall_MaskLpProd	0x00000004
 #define HvCall_MaskTimeout	0x00000008
 
-/* Log buffer formats                       */
+/* Log buffer formats */
 #define HvCall_LogBuffer_ASCII          0
 #define HvCall_LogBuffer_EBCDIC         1
 
@@ -95,7 +47,7 @@ enum HvCall_VaryOffChunkRc
 #define HvCallBaseGetHwPatch				HvCallBase +  2
 #define HvCallBaseReIplSpAttn				HvCallBase +  3
 #define HvCallBaseSetASR				HvCallBase +  4
-#define HvCallBaseSetASRAndRfi				HvCallBase +  5 
+#define HvCallBaseSetASRAndRfi				HvCallBase +  5
 #define HvCallBaseSetIMR				HvCallBase +  6
 #define HvCallBaseSendIPI				HvCallBase +  7
 #define HvCallBaseTerminateMachine			HvCallBase +  8
@@ -115,91 +67,47 @@ enum HvCall_VaryOffChunkRc
 #define HvCallBaseGetLogBufferCodePage			HvCallBase + 22
 #define HvCallBaseGetLogBufferFormat			HvCallBase + 23
 #define HvCallBaseGetLogBufferLength			HvCallBase + 24
-#define HvCallBaseReadLogBuffer 			HvCallBase + 25
+#define HvCallBaseReadLogBuffer				HvCallBase + 25
 #define HvCallBaseSetLogBufferFormatAndCodePage		HvCallBase + 26
-#define HvCallBaseWriteLogBuffer               		HvCallBase + 27
+#define HvCallBaseWriteLogBuffer			HvCallBase + 27
 #define HvCallBaseRouter28				HvCallBase + 28
 #define HvCallBaseRouter29				HvCallBase + 29
 #define HvCallBaseRouter30				HvCallBase + 30
-#define HvCallBaseSetDebugBus 				HvCallBase + 31
+#define HvCallBaseSetDebugBus				HvCallBase + 31
 
-#define HvCallCcSetDABR  				HvCallCc + 7
+#define HvCallCcSetDABR					HvCallCc + 7
 
-//=====================================================================================
-static inline void		HvCall_setVirtualDecr(void)
+static inline void HvCall_setVirtualDecr(void)
 {
-	/* Ignore any error return codes - most likely means that the target value for the
-	 * LP has been increased and this vary off would bring us below the new target. */
+	/*
+	 * Ignore any error return codes - most likely means that the
+	 * target value for the LP has been increased and this vary off
+	 * would bring us below the new target.
+	 */
 	HvCall0(HvCallBaseSetVirtualDecr);
 }
-//=====================================================================
-static inline void		HvCall_yieldProcessor(unsigned typeOfYield, u64 yieldParm)
-{
-	HvCall2( HvCallBaseYieldProcessor, typeOfYield, yieldParm );
-}
-//=====================================================================
-static inline void		HvCall_setEnabledInterrupts(u64 enabledInterrupts)
-{
-	HvCall1(HvCallBaseSetEnabledInterrupts,enabledInterrupts);
-}
-
-//=====================================================================
-static inline void		HvCall_clearLogBuffer(HvLpIndex lpindex)
-{
-	HvCall1(HvCallBaseClearLogBuffer,lpindex);
-}
-
-//=====================================================================
-static inline u32  		HvCall_getLogBufferCodePage(HvLpIndex lpindex)
-{
-	u32 retVal = HvCall1(HvCallBaseGetLogBufferCodePage,lpindex);
-	return retVal;
-}
-
-//=====================================================================
-static inline int  		HvCall_getLogBufferFormat(HvLpIndex lpindex)
-{
-	int retVal = HvCall1(HvCallBaseGetLogBufferFormat,lpindex);
-	return retVal;
-}
-
-//=====================================================================
-static inline u32  		HvCall_getLogBufferLength(HvLpIndex lpindex)
-{
-	u32 retVal = HvCall1(HvCallBaseGetLogBufferLength,lpindex);
-	return retVal;
-}
 
-//=====================================================================
-static inline void  		HvCall_setLogBufferFormatAndCodepage(int format, u32 codePage)
+static inline void HvCall_yieldProcessor(unsigned typeOfYield, u64 yieldParm)
 {
-	HvCall2(HvCallBaseSetLogBufferFormatAndCodePage,format, codePage);
+	HvCall2(HvCallBaseYieldProcessor, typeOfYield, yieldParm);
 }
 
-//=====================================================================
-int HvCall_readLogBuffer(HvLpIndex lpindex, void *buffer, u64 bufLen);
-void HvCall_writeLogBuffer(const void *buffer, u64 bufLen);
-
-//=====================================================================
-static inline void		HvCall_sendIPI(struct paca_struct * targetPaca)
+static inline void HvCall_setEnabledInterrupts(u64 enabledInterrupts)
 {
-	HvCall1( HvCallBaseSendIPI, targetPaca->paca_index );
+	HvCall1(HvCallBaseSetEnabledInterrupts, enabledInterrupts);
 }
 
-//=====================================================================
-static inline void		HvCall_terminateMachineSrc(void)
+static inline void HvCall_setLogBufferFormatAndCodepage(int format,
+		u32 codePage)
 {
-	HvCall0( HvCallBaseTerminateMachineSrc );
+	HvCall2(HvCallBaseSetLogBufferFormatAndCodePage, format, codePage);
 }
 
-static inline void HvCall_setDABR(unsigned long val)
-{
-	HvCall1(HvCallCcSetDABR, val);
-}
+extern void HvCall_writeLogBuffer(const void *buffer, u64 bufLen);
 
-static inline void HvCall_setDebugBus(unsigned long val)
+static inline void HvCall_sendIPI(struct paca_struct *targetPaca)
 {
-	HvCall1(HvCallBaseSetDebugBus, val);
+	HvCall1(HvCallBaseSendIPI, targetPaca->paca_index);
 }
 
 #endif /* _HVCALL_H */
diff --git a/include/asm-ppc64/iSeries/HvCallCfg.h b/include/asm-ppc64/iSeries/HvCallCfg.h
deleted file mode 100644
--- a/include/asm-ppc64/iSeries/HvCallCfg.h
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- * HvCallCfg.h
- * Copyright (C) 2001  Mike Corrigan IBM Corporation
- * 
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- */
-
-//=====================================================================================
-//
-//	This file contains the "hypervisor call" interface which is used to
-//	drive the hypervisor from the OS.
-//
-//=====================================================================================
-#ifndef _HVCALLCFG_H
-#define _HVCALLCFG_H
-
-//-------------------------------------------------------------------
-// Standard Includes
-//-------------------------------------------------------------------
-#include <asm/iSeries/HvCallSc.h>
-#include <asm/iSeries/HvTypes.h>
-
-//-------------------------------------------------------------------------------------
-// Constants
-//-------------------------------------------------------------------------------------
-
-enum HvCallCfg_ReqQual
-{
-	HvCallCfg_Cur	= 0,
-	HvCallCfg_Init	= 1,
-	HvCallCfg_Max	= 2,
-	HvCallCfg_Min	= 3
-};
-
-#define HvCallCfgGetLps					HvCallCfg +  0
-#define HvCallCfgGetActiveLpMap				HvCallCfg +  1
-#define HvCallCfgGetLpVrmIndex				HvCallCfg +  2
-#define HvCallCfgGetLpMinSupportedPlicVrmIndex		HvCallCfg +  3
-#define HvCallCfgGetLpMinCompatablePlicVrmIndex		HvCallCfg +  4
-#define HvCallCfgGetLpVrmName				HvCallCfg +  5 
-#define HvCallCfgGetSystemPhysicalProcessors		HvCallCfg +  6
-#define HvCallCfgGetPhysicalProcessors			HvCallCfg +  7
-#define HvCallCfgGetSystemMsChunks			HvCallCfg +  8
-#define HvCallCfgGetMsChunks				HvCallCfg +  9
-#define HvCallCfgGetInteractivePercentage		HvCallCfg + 10
-#define HvCallCfgIsBusDedicated				HvCallCfg + 11
-#define HvCallCfgGetBusOwner				HvCallCfg + 12
-#define HvCallCfgGetBusAllocation			HvCallCfg + 13
-#define HvCallCfgGetBusUnitOwner			HvCallCfg + 14
-#define HvCallCfgGetBusUnitAllocation			HvCallCfg + 15
-#define HvCallCfgGetVirtualBusPool			HvCallCfg + 16
-#define HvCallCfgGetBusUnitInterruptProc		HvCallCfg + 17
-#define HvCallCfgGetConfiguredBusUnitsForIntProc	HvCallCfg + 18
-#define HvCallCfgGetRioSanBusPool			HvCallCfg + 19
-#define HvCallCfgGetSharedPoolIndex			HvCallCfg + 20
-#define HvCallCfgGetSharedProcUnits			HvCallCfg + 21
-#define HvCallCfgGetNumProcsInSharedPool		HvCallCfg + 22
-#define HvCallCfgRouter23				HvCallCfg + 23
-#define HvCallCfgRouter24				HvCallCfg + 24
-#define HvCallCfgRouter25				HvCallCfg + 25
-#define HvCallCfgRouter26				HvCallCfg + 26
-#define HvCallCfgRouter27				HvCallCfg + 27
-#define HvCallCfgGetMinRuntimeMsChunks			HvCallCfg + 28
-#define HvCallCfgSetMinRuntimeMsChunks			HvCallCfg + 29
-#define HvCallCfgGetVirtualLanIndexMap			HvCallCfg + 30
-#define HvCallCfgGetLpExecutionMode			HvCallCfg + 31
-#define HvCallCfgGetHostingLpIndex 			HvCallCfg + 32
-
-//====================================================================
-static inline HvLpIndex	HvCallCfg_getLps(void)
-{
-	HvLpIndex retVal = HvCall0(HvCallCfgGetLps);
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
-	return retVal;
-}
-//====================================================================
-static inline int		HvCallCfg_isBusDedicated(u64 busIndex)
-{
-	int retVal = HvCall1(HvCallCfgIsBusDedicated,busIndex);
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
-	return retVal;
-}
-//====================================================================
-static inline HvLpIndex	HvCallCfg_getBusOwner(u64 busIndex)
-{
-	HvLpIndex retVal = HvCall1(HvCallCfgGetBusOwner,busIndex);
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
-	return retVal;
-}
-//====================================================================
-static inline HvLpIndexMap	HvCallCfg_getBusAllocation(u64 busIndex)
-{
-	HvLpIndexMap retVal = HvCall1(HvCallCfgGetBusAllocation,busIndex);
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
-	return retVal;
-}
-//====================================================================
-static inline HvLpIndexMap	HvCallCfg_getActiveLpMap(void)
-{
-	HvLpIndexMap retVal = HvCall0(HvCallCfgGetActiveLpMap);
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
-	return retVal;
-}
-//====================================================================
-static inline HvLpVirtualLanIndexMap	HvCallCfg_getVirtualLanIndexMap(HvLpIndex lp)
-{
-	// This is a new function in V5R1 so calls to this on older 
-	// hypervisors will return -1
-	u64 retVal = HvCall1(HvCallCfgGetVirtualLanIndexMap, lp);
-	if(retVal == -1)
-		retVal = 0;
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
-	return retVal;
-}
-//===================================================================
-static inline u64		HvCallCfg_getSystemMsChunks(void)
-{
-	u64 retVal = HvCall0(HvCallCfgGetSystemMsChunks);
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
-	return retVal;
-}
-//===================================================================
-static inline u64		HvCallCfg_getMsChunks(HvLpIndex lp,enum HvCallCfg_ReqQual qual)
-{
-	u64 retVal = HvCall2(HvCallCfgGetMsChunks,lp,qual);
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
-	return retVal;
-}
-//===================================================================
-static inline u64		HvCallCfg_getMinRuntimeMsChunks(HvLpIndex lp)
-{
-	// NOTE: This function was added in v5r1 so older hypervisors will return a -1 value
-	u64 retVal = HvCall1(HvCallCfgGetMinRuntimeMsChunks,lp);
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
-	return retVal;
-}
-//===================================================================
-static inline u64		HvCallCfg_setMinRuntimeMsChunks(u64 chunks)
-{
-	u64 retVal = HvCall1(HvCallCfgSetMinRuntimeMsChunks,chunks);
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
-	return retVal;
-}
-//===================================================================
-static inline u64		HvCallCfg_getSystemPhysicalProcessors(void)
-{
-	u64 retVal = HvCall0(HvCallCfgGetSystemPhysicalProcessors);
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
-	return retVal;
-}
-//===================================================================
-static inline u64		HvCallCfg_getPhysicalProcessors(HvLpIndex lp,enum HvCallCfg_ReqQual qual)
-{
-	u64 retVal = HvCall2(HvCallCfgGetPhysicalProcessors,lp,qual);
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
-	return retVal;
-}
-//===================================================================
-static inline u64		HvCallCfg_getConfiguredBusUnitsForInterruptProc(HvLpIndex lp,
-										u16 hvLogicalProcIndex)
-{
-	u64 retVal = HvCall2(HvCallCfgGetConfiguredBusUnitsForIntProc,lp,hvLogicalProcIndex);
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
-	return retVal;
-
-}
-//==================================================================
-static inline HvLpSharedPoolIndex	HvCallCfg_getSharedPoolIndex(HvLpIndex lp)
-{
-	HvLpSharedPoolIndex retVal =
-		HvCall1(HvCallCfgGetSharedPoolIndex,lp);
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
-	return retVal;
-
-}
-//==================================================================
-static inline u64	HvCallCfg_getSharedProcUnits(HvLpIndex lp,enum HvCallCfg_ReqQual qual)
-{
-	u64 retVal = HvCall2(HvCallCfgGetSharedProcUnits,lp,qual);
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
-	return retVal;
-
-}
-//==================================================================
-static inline u64	HvCallCfg_getNumProcsInSharedPool(HvLpSharedPoolIndex sPI)
-{
-	u16 retVal = HvCall1(HvCallCfgGetNumProcsInSharedPool,sPI);
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
-	return retVal;
-
-}
-//==================================================================
-static inline HvLpIndex	HvCallCfg_getHostingLpIndex(HvLpIndex lp)
-{
-	u64 retVal = HvCall1(HvCallCfgGetHostingLpIndex,lp);
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
-	return retVal;
-
-}
-
-#endif /* _HVCALLCFG_H */
diff --git a/include/asm-ppc64/iSeries/HvCallEvent.h b/include/asm-ppc64/iSeries/HvCallEvent.h
--- a/include/asm-ppc64/iSeries/HvCallEvent.h
+++ b/include/asm-ppc64/iSeries/HvCallEvent.h
@@ -1,32 +1,28 @@
 /*
  * HvCallEvent.h
  * Copyright (C) 2001  Mike Corrigan IBM Corporation
- * 
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  */
-
 /*
- *	This file contains the "hypervisor call" interface which is used to
- *	drive the hypervisor from the OS.
+ * This file contains the "hypervisor call" interface which is used to
+ * drive the hypervisor from the OS.
  */
 #ifndef _HVCALLEVENT_H
 #define _HVCALLEVENT_H
 
-/*
- * Standard Includes
- */
 #include <asm/iSeries/HvCallSc.h>
 #include <asm/iSeries/HvTypes.h>
 #include <asm/abs_addr.h>
@@ -71,7 +67,7 @@ typedef u64 HvLpDma_Rc;
 #define HvCallEventCloseLpEventPath			HvCallEvent +  2
 #define HvCallEventDmaBufList				HvCallEvent +  3
 #define HvCallEventDmaSingle				HvCallEvent +  4
-#define HvCallEventDmaToSp				HvCallEvent +  5 
+#define HvCallEventDmaToSp				HvCallEvent +  5
 #define HvCallEventGetOverflowLpEvents			HvCallEvent +  6
 #define HvCallEventGetSourceLpInstanceId		HvCallEvent +  7
 #define HvCallEventGetTargetLpInstanceId		HvCallEvent +  8
@@ -85,14 +81,12 @@ typedef u64 HvLpDma_Rc;
 
 static inline void HvCallEvent_getOverflowLpEvents(u8 queueIndex)
 {
-	HvCall1(HvCallEventGetOverflowLpEvents,queueIndex);
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+	HvCall1(HvCallEventGetOverflowLpEvents, queueIndex);
 }
 
 static inline void HvCallEvent_setInterLpQueueIndex(u8 queueIndex)
 {
-	HvCall1(HvCallEventSetInterLpQueueIndex,queueIndex);
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+	HvCall1(HvCallEventSetInterLpQueueIndex, queueIndex);
 }
 
 static inline void HvCallEvent_setLpEventStack(u8 queueIndex,
@@ -103,7 +97,6 @@ static inline void HvCallEvent_setLpEven
 	abs_addr = virt_to_abs(eventStackAddr);
 	HvCall3(HvCallEventSetLpEventStack, queueIndex, abs_addr,
 			eventStackSize);
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
 }
 
 static inline void HvCallEvent_setLpEventQueueInterruptProc(u8 queueIndex,
@@ -111,22 +104,18 @@ static inline void HvCallEvent_setLpEven
 {
 	HvCall2(HvCallEventSetLpEventQueueInterruptProc, queueIndex,
 			lpLogicalProcIndex);
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
 }
 
 static inline HvLpEvent_Rc HvCallEvent_signalLpEvent(struct HvLpEvent *event)
 {
 	u64 abs_addr;
-	HvLpEvent_Rc retVal;
 
 #ifdef DEBUG_SENDEVENT
 	printk("HvCallEvent_signalLpEvent: *event = %016lx\n ",
 			(unsigned long)event);
 #endif
 	abs_addr = virt_to_abs(event);
-	retVal = (HvLpEvent_Rc)HvCall1(HvCallEventSignalLpEvent, abs_addr);
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
-	return retVal;
+	return HvCall1(HvCallEventSignalLpEvent, abs_addr);
 }
 
 static inline HvLpEvent_Rc HvCallEvent_signalLpEventFast(HvLpIndex targetLp,
@@ -136,9 +125,7 @@ static inline HvLpEvent_Rc HvCallEvent_s
 		u64 eventData1, u64 eventData2, u64 eventData3,
 		u64 eventData4, u64 eventData5)
 {
-	HvLpEvent_Rc retVal;
-
-	// Pack the misc bits into a single Dword to pass to PLIC
+	/* Pack the misc bits into a single Dword to pass to PLIC */
 	union {
 		struct HvCallEvent_PackedParms	parms;
 		u64		dword;
@@ -152,67 +139,49 @@ static inline HvLpEvent_Rc HvCallEvent_s
 	packed.parms.xSourceInstId	= sourceInstanceId;
 	packed.parms.xTargetInstId	= targetInstanceId;
 
-	retVal = (HvLpEvent_Rc)HvCall7(HvCallEventSignalLpEventParms,
-			packed.dword, correlationToken, eventData1,eventData2,
-			eventData3,eventData4, eventData5);
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
-	return retVal;
+	return HvCall7(HvCallEventSignalLpEventParms, packed.dword,
+			correlationToken, eventData1, eventData2,
+			eventData3, eventData4, eventData5);
 }
 
 static inline HvLpEvent_Rc HvCallEvent_ackLpEvent(struct HvLpEvent *event)
 {
 	u64 abs_addr;
-	HvLpEvent_Rc retVal;
 
 	abs_addr = virt_to_abs(event);
-	retVal = (HvLpEvent_Rc)HvCall1(HvCallEventAckLpEvent, abs_addr);
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
-	return retVal;
+	return HvCall1(HvCallEventAckLpEvent, abs_addr);
 }
 
 static inline HvLpEvent_Rc HvCallEvent_cancelLpEvent(struct HvLpEvent *event)
 {
 	u64 abs_addr;
-	HvLpEvent_Rc retVal;
 
 	abs_addr = virt_to_abs(event);
-	retVal = (HvLpEvent_Rc)HvCall1(HvCallEventCancelLpEvent, abs_addr);
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
-	return retVal;
+	return HvCall1(HvCallEventCancelLpEvent, abs_addr);
 }
 
 static inline HvLpInstanceId HvCallEvent_getSourceLpInstanceId(
 		HvLpIndex targetLp, HvLpEvent_Type type)
 {
-	HvLpInstanceId retVal;	
-
-	retVal = HvCall2(HvCallEventGetSourceLpInstanceId, targetLp, type);
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
-	return retVal;
+	return HvCall2(HvCallEventGetSourceLpInstanceId, targetLp, type);
 }
 
 static inline HvLpInstanceId HvCallEvent_getTargetLpInstanceId(
 		HvLpIndex targetLp, HvLpEvent_Type type)
 {
-	HvLpInstanceId retVal;	
-
-	retVal = HvCall2(HvCallEventGetTargetLpInstanceId, targetLp, type);
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
-	return retVal;
+	return HvCall2(HvCallEventGetTargetLpInstanceId, targetLp, type);
 }
 
 static inline void HvCallEvent_openLpEventPath(HvLpIndex targetLp,
 		HvLpEvent_Type type)
 {
 	HvCall2(HvCallEventOpenLpEventPath, targetLp, type);
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
 }
 
 static inline void HvCallEvent_closeLpEventPath(HvLpIndex targetLp,
 		HvLpEvent_Type type)
 {
 	HvCall2(HvCallEventCloseLpEventPath, targetLp, type);
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
 }
 
 static inline HvLpDma_Rc HvCallEvent_dmaBufList(HvLpEvent_Type type,
@@ -224,8 +193,7 @@ static inline HvLpDma_Rc HvCallEvent_dma
 		/* Do these need to be converted to absolute addresses? */
 		u64 localBufList, u64 remoteBufList, u32 transferLength)
 {
-	HvLpDma_Rc retVal;
-	// Pack the misc bits into a single Dword to pass to PLIC
+	/* Pack the misc bits into a single Dword to pass to PLIC */
 	union {
 		struct HvCallEvent_PackedDmaParms	parms;
 		u64		dword;
@@ -241,11 +209,8 @@ static inline HvLpDma_Rc HvCallEvent_dma
 	packed.parms.xLocalInstId	= localInstanceId;
 	packed.parms.xRemoteInstId	= remoteInstanceId;
 
-	retVal = (HvLpDma_Rc)HvCall4(HvCallEventDmaBufList,
-			packed.dword, localBufList, remoteBufList,
-			transferLength);
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
-	return retVal;
+	return HvCall4(HvCallEventDmaBufList, packed.dword, localBufList,
+			remoteBufList, transferLength);
 }
 
 static inline HvLpDma_Rc HvCallEvent_dmaSingle(HvLpEvent_Type type,
@@ -256,8 +221,7 @@ static inline HvLpDma_Rc HvCallEvent_dma
 		HvLpDma_AddressType remoteAddressType,
 		u64 localAddrOrTce, u64 remoteAddrOrTce, u32 transferLength)
 {
-	HvLpDma_Rc retVal;
-	// Pack the misc bits into a single Dword to pass to PLIC
+	/* Pack the misc bits into a single Dword to pass to PLIC */
 	union {
 		struct HvCallEvent_PackedDmaParms	parms;
 		u64		dword;
@@ -273,25 +237,17 @@ static inline HvLpDma_Rc HvCallEvent_dma
 	packed.parms.xLocalInstId	= localInstanceId;
 	packed.parms.xRemoteInstId	= remoteInstanceId;
 
-	retVal = (HvLpDma_Rc)HvCall4(HvCallEventDmaSingle,
-			packed.dword, localAddrOrTce, remoteAddrOrTce,
-			transferLength);
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
-	return retVal;
+	return (HvLpDma_Rc)HvCall4(HvCallEventDmaSingle, packed.dword,
+			localAddrOrTce, remoteAddrOrTce, transferLength);
 }
 
-static inline HvLpDma_Rc HvCallEvent_dmaToSp(void* local, u32 remote,
+static inline HvLpDma_Rc HvCallEvent_dmaToSp(void *local, u32 remote,
 		u32 length, HvLpDma_Direction dir)
 {
 	u64 abs_addr;
-	HvLpDma_Rc retVal;
 
 	abs_addr = virt_to_abs(local);
-	retVal = (HvLpDma_Rc)HvCall4(HvCallEventDmaToSp, abs_addr, remote,
-			length, dir);
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
-	return retVal;
+	return HvCall4(HvCallEventDmaToSp, abs_addr, remote, length, dir);
 }
 
-
 #endif /* _HVCALLEVENT_H */
diff --git a/include/asm-ppc64/iSeries/HvCallHpt.h b/include/asm-ppc64/iSeries/HvCallHpt.h
--- a/include/asm-ppc64/iSeries/HvCallHpt.h
+++ b/include/asm-ppc64/iSeries/HvCallHpt.h
@@ -1,17 +1,17 @@
 /*
  * HvCallHpt.h
  * Copyright (C) 2001  Mike Corrigan IBM Corporation
- * 
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
@@ -19,21 +19,15 @@
 #ifndef _HVCALLHPT_H
 #define _HVCALLHPT_H
 
-//============================================================================
-//
-//	This file contains the "hypervisor call" interface which is used to
-//	drive the hypervisor from the OS.
-//
-//============================================================================
+/*
+ * This file contains the "hypervisor call" interface which is used to
+ * drive the hypervisor from the OS.
+ */
 
 #include <asm/iSeries/HvCallSc.h>
 #include <asm/iSeries/HvTypes.h>
 #include <asm/mmu.h>
 
-//-----------------------------------------------------------------------------
-// Constants
-//-----------------------------------------------------------------------------
-
 #define HvCallHptGetHptAddress		HvCallHpt +  0
 #define HvCallHptGetHptPages		HvCallHpt +  1
 #define HvCallHptSetPp			HvCallHpt +  5
@@ -47,81 +41,62 @@
 #define HvCallHptInvalidateSetSwBitsGet HvCallHpt + 18
 
 
-//============================================================================
-static inline u64		HvCallHpt_getHptAddress(void)
+static inline u64 HvCallHpt_getHptAddress(void)
 {
-	u64 retval = HvCall0(HvCallHptGetHptAddress);
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
-	return retval;
-}
-//============================================================================
-static inline u64		HvCallHpt_getHptPages(void)
-{	
-	u64 retval = HvCall0(HvCallHptGetHptPages);
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
-	return retval;
-}
-//=============================================================================
-static inline void		HvCallHpt_setPp(u32 hpteIndex, u8 value)
-{
-	HvCall2( HvCallHptSetPp, hpteIndex, value );
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
-}
-//=============================================================================
-static inline void		HvCallHpt_setSwBits(u32 hpteIndex, u8 bitson, u8 bitsoff )
-{
-	HvCall3( HvCallHptSetSwBits, hpteIndex, bitson, bitsoff );
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
-}
-//=============================================================================
-static inline void		HvCallHpt_invalidateNoSyncICache(u32 hpteIndex)
-						
-{
-	HvCall1( HvCallHptInvalidateNoSyncICache, hpteIndex );
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
-}
-//=============================================================================
-static inline u64		HvCallHpt_invalidateSetSwBitsGet(u32 hpteIndex, u8 bitson, u8 bitsoff )
-						
+	return HvCall0(HvCallHptGetHptAddress);
+}
+
+static inline u64 HvCallHpt_getHptPages(void)
 {
-	u64 compressedStatus;
-	compressedStatus = HvCall4( HvCallHptInvalidateSetSwBitsGet, hpteIndex, bitson, bitsoff, 1 );
-	HvCall1( HvCallHptInvalidateNoSyncICache, hpteIndex );
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
-	return compressedStatus;
+	return HvCall0(HvCallHptGetHptPages);
+}
+
+static inline void HvCallHpt_setPp(u32 hpteIndex, u8 value)
+{
+	HvCall2(HvCallHptSetPp, hpteIndex, value);
+}
+
+static inline void HvCallHpt_setSwBits(u32 hpteIndex, u8 bitson, u8 bitsoff)
+{
+	HvCall3(HvCallHptSetSwBits, hpteIndex, bitson, bitsoff);
 }
-//=============================================================================
-static inline u64		HvCallHpt_findValid( HPTE *hpte, u64 vpn )
+
+static inline void HvCallHpt_invalidateNoSyncICache(u32 hpteIndex)
 {
-	u64 retIndex = HvCall3Ret16( HvCallHptFindValid, hpte, vpn, 0, 0 );
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
-	return retIndex;
+	HvCall1(HvCallHptInvalidateNoSyncICache, hpteIndex);
 }
-//=============================================================================
-static inline u64		HvCallHpt_findNextValid( HPTE *hpte, u32 hpteIndex, u8 bitson, u8 bitsoff )
+
+static inline u64 HvCallHpt_invalidateSetSwBitsGet(u32 hpteIndex, u8 bitson,
+		u8 bitsoff)
 {
-	u64 retIndex = HvCall3Ret16( HvCallHptFindNextValid, hpte, hpteIndex, bitson, bitsoff );
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
-	return retIndex;
+	u64 compressedStatus;
+
+	compressedStatus = HvCall4(HvCallHptInvalidateSetSwBitsGet,
+			hpteIndex, bitson, bitsoff, 1);
+	HvCall1(HvCallHptInvalidateNoSyncICache, hpteIndex);
+	return compressedStatus;
 }
-//=============================================================================
-static inline void		HvCallHpt_get( HPTE *hpte, u32 hpteIndex )
+
+static inline u64 HvCallHpt_findValid(hpte_t *hpte, u64 vpn)
 {
-	HvCall2Ret16( HvCallHptGet, hpte, hpteIndex, 0 );
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+	return HvCall3Ret16(HvCallHptFindValid, hpte, vpn, 0, 0);
 }
-//============================================================================
-static inline void		HvCallHpt_addValidate( u32 hpteIndex,
-						       u32 hBit,
-						       HPTE *hpte )
-						
+
+static inline u64 HvCallHpt_findNextValid(hpte_t *hpte, u32 hpteIndex,
+		u8 bitson, u8 bitsoff)
 {
-	HvCall4( HvCallHptAddValidate, hpteIndex,
-		 hBit, (*((u64 *)hpte)), (*(((u64 *)hpte)+1)) );
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+	return HvCall3Ret16(HvCallHptFindNextValid, hpte, hpteIndex,
+			bitson, bitsoff);
 }
 
+static inline void HvCallHpt_get(hpte_t *hpte, u32 hpteIndex)
+{
+	HvCall2Ret16(HvCallHptGet, hpte, hpteIndex, 0);
+}
 
-//=============================================================================
+static inline void HvCallHpt_addValidate(u32 hpteIndex, u32 hBit, hpte_t *hpte)
+{
+	HvCall4(HvCallHptAddValidate, hpteIndex, hBit, hpte->v, hpte->r);
+}
 
 #endif /* _HVCALLHPT_H */
diff --git a/include/asm-ppc64/iSeries/HvCallPci.h b/include/asm-ppc64/iSeries/HvCallPci.h
--- a/include/asm-ppc64/iSeries/HvCallPci.h
+++ b/include/asm-ppc64/iSeries/HvCallPci.h
@@ -1,26 +1,26 @@
-/************************************************************************/
-/* Provides the Hypervisor PCI calls for iSeries Linux Parition.        */
-/* Copyright (C) 2001  <Wayne G Holm> <IBM Corporation>                 */
-/*                                                                      */
-/* This program is free software; you can redistribute it and/or modify */
-/* it under the terms of the GNU General Public License as published by */
-/* the Free Software Foundation; either version 2 of the License, or    */
-/* (at your option) any later version.                                  */
-/*                                                                      */
-/* This program is distributed in the hope that it will be useful,      */ 
-/* but WITHOUT ANY WARRANTY; without even the implied warranty of       */
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        */
-/* GNU General Public License for more details.                         */
-/*                                                                      */
-/* You should have received a copy of the GNU General Public License    */ 
-/* along with this program; if not, write to the:                       */
-/* Free Software Foundation, Inc.,                                      */ 
-/* 59 Temple Place, Suite 330,                                          */ 
-/* Boston, MA  02111-1307  USA                                          */
-/************************************************************************/
-/* Change Activity:                                                     */
-/*   Created, Jan 9, 2001                                               */
-/************************************************************************/
+/*
+ * Provides the Hypervisor PCI calls for iSeries Linux Parition.
+ * Copyright (C) 2001  <Wayne G Holm> <IBM Corporation>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the:
+ * Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330,
+ * Boston, MA  02111-1307  USA
+ *
+ * Change Activity:
+ *   Created, Jan 9, 2001
+ */
 
 #ifndef _HVCALLPCI_H
 #define _HVCALLPCI_H
@@ -34,8 +34,8 @@
  */
 struct HvCallPci_DsaAddr {
 	u16		busNumber;		/* PHB index? */
-	u8		subBusNumber; 		/* PCI bus number? */
-	u8		deviceId;     		/* device and function? */
+	u8		subBusNumber;		/* PCI bus number? */
+	u8		deviceId;		/* device and function? */
 	u8		barNumber;
 	u8		reserved[3];
 };
@@ -52,34 +52,37 @@ struct HvCallPci_LoadReturn {
 
 enum HvCallPci_DeviceType {
 	HvCallPci_NodeDevice	= 1,
-	HvCallPci_SpDevice	= 2,	
-	HvCallPci_IopDevice     = 3,	
-	HvCallPci_BridgeDevice	= 4,	
-	HvCallPci_MultiFunctionDevice = 5,	
-	HvCallPci_IoaDevice	= 6	
+	HvCallPci_SpDevice	= 2,
+	HvCallPci_IopDevice     = 3,
+	HvCallPci_BridgeDevice	= 4,
+	HvCallPci_MultiFunctionDevice = 5,
+	HvCallPci_IoaDevice	= 6
 };
 
 
 struct HvCallPci_DeviceInfo {
-	u32	deviceType;		// See DeviceType enum for values
+	u32	deviceType;		/* See DeviceType enum for values */
 };
-    
+
 struct HvCallPci_BusUnitInfo {
-	u32	sizeReturned;		// length of data returned
-	u32	deviceType;		// see DeviceType enum for values
+	u32	sizeReturned;		/* length of data returned */
+	u32	deviceType;		/* see DeviceType enum for values */
 };
 
 struct HvCallPci_BridgeInfo {
-	struct HvCallPci_BusUnitInfo busUnitInfo;  // Generic bus unit info
-	u8		subBusNumber;		// Bus number of secondary bus
-	u8		maxAgents;		// Max idsels on secondary bus
-        u8              maxSubBusNumber;        // Max Sub Bus
-	u8		logicalSlotNumber;	// Logical Slot Number for IOA 
+	struct HvCallPci_BusUnitInfo busUnitInfo;  /* Generic bus unit info */
+	u8		subBusNumber;	/* Bus number of secondary bus */
+	u8		maxAgents;	/* Max idsels on secondary bus */
+        u8              maxSubBusNumber; /* Max Sub Bus */
+	u8		logicalSlotNumber; /* Logical Slot Number for IOA */
 };
-    
 
-//  Maximum BusUnitInfo buffer size.  Provided for clients so they can allocate
-//  a buffer big enough for any type of bus unit.  Increase as needed.
+
+/*
+ * Maximum BusUnitInfo buffer size.  Provided for clients so
+ * they can allocate a buffer big enough for any type of bus
+ * unit.  Increase as needed.
+ */
 enum {HvCallPci_MaxBusUnitInfoSize = 128};
 
 struct HvCallPci_BarParms {
@@ -89,12 +92,12 @@ struct HvCallPci_BarParms {
 	u64		protectStart;
 	u64		protectEnd;
 	u64		relocationOffset;
-	u64		pciAddress;		
+	u64		pciAddress;
 	u64		reserved[3];
-};					
+};
 
 enum HvCallPci_VpdType {
-	HvCallPci_BusVpd		= 1,
+	HvCallPci_BusVpd	= 1,
 	HvCallPci_BusAdapterVpd	= 2
 };
 
@@ -123,15 +126,13 @@ enum HvCallPci_VpdType {
 #define HvCallPciUnmaskInterrupts	HvCallPci + 49
 #define HvCallPciGetBusUnitInfo		HvCallPci + 50
 
-//============================================================================
 static inline u64 HvCallPci_configLoad8(u16 busNumber, u8 subBusNumber,
-					u8 deviceId, u32 offset,
-					u8 *value)
+		u8 deviceId, u32 offset, u8 *value)
 {
 	struct HvCallPci_DsaAddr dsa;
 	struct HvCallPci_LoadReturn retVal;
 
-	*((u64*)&dsa) = 0;				
+	*((u64*)&dsa) = 0;
 
 	dsa.busNumber = busNumber;
 	dsa.subBusNumber = subBusNumber;
@@ -139,21 +140,18 @@ static inline u64 HvCallPci_configLoad8(
 
 	HvCall3Ret16(HvCallPciConfigLoad8, &retVal, *(u64 *)&dsa, offset, 0);
 
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
-
 	*value = retVal.value;
 
 	return retVal.rc;
 }
-//============================================================================
+
 static inline u64 HvCallPci_configLoad16(u16 busNumber, u8 subBusNumber,
-					 u8 deviceId, u32 offset,
-					 u16 *value)
+		u8 deviceId, u32 offset, u16 *value)
 {
 	struct HvCallPci_DsaAddr dsa;
 	struct HvCallPci_LoadReturn retVal;
 
-	*((u64*)&dsa) = 0;				
+	*((u64*)&dsa) = 0;
 
 	dsa.busNumber = busNumber;
 	dsa.subBusNumber = subBusNumber;
@@ -161,21 +159,18 @@ static inline u64 HvCallPci_configLoad16
 
 	HvCall3Ret16(HvCallPciConfigLoad16, &retVal, *(u64 *)&dsa, offset, 0);
 
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
-
 	*value = retVal.value;
 
 	return retVal.rc;
 }
-//============================================================================
-static inline u64	HvCallPci_configLoad32(u16 busNumber, u8 subBusNumber,
-					      u8 deviceId, u32 offset,
-					      u32 *value)
+
+static inline u64 HvCallPci_configLoad32(u16 busNumber, u8 subBusNumber,
+		u8 deviceId, u32 offset, u32 *value)
 {
 	struct HvCallPci_DsaAddr dsa;
 	struct HvCallPci_LoadReturn retVal;
 
-	*((u64*)&dsa) = 0;				
+	*((u64*)&dsa) = 0;
 
 	dsa.busNumber = busNumber;
 	dsa.subBusNumber = subBusNumber;
@@ -183,84 +178,61 @@ static inline u64	HvCallPci_configLoad32
 
 	HvCall3Ret16(HvCallPciConfigLoad32, &retVal, *(u64 *)&dsa, offset, 0);
 
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
-
 	*value = retVal.value;
 
 	return retVal.rc;
 }
-//============================================================================
-static inline u64	HvCallPci_configStore8(u16 busNumber, u8 subBusNumber,
-					      u8 deviceId, u32 offset,
-					      u8  value)
+
+static inline u64 HvCallPci_configStore8(u16 busNumber, u8 subBusNumber,
+		u8 deviceId, u32 offset, u8 value)
 {
 	struct HvCallPci_DsaAddr dsa;
-	u64 retVal;
 
-	*((u64*)&dsa) = 0;				
+	*((u64*)&dsa) = 0;
 
 	dsa.busNumber = busNumber;
 	dsa.subBusNumber = subBusNumber;
 	dsa.deviceId = deviceId;
 
-	retVal = HvCall4(HvCallPciConfigStore8, *(u64 *)&dsa, offset, value, 0);
-
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
-
-	return retVal;
+	return HvCall4(HvCallPciConfigStore8, *(u64 *)&dsa, offset, value, 0);
 }
-//============================================================================
-static inline u64	HvCallPci_configStore16(u16 busNumber, u8 subBusNumber,
-					      u8 deviceId, u32 offset,
-					      u16  value)
+
+static inline u64 HvCallPci_configStore16(u16 busNumber, u8 subBusNumber,
+		u8 deviceId, u32 offset, u16 value)
 {
 	struct HvCallPci_DsaAddr dsa;
-	u64 retVal;
 
-	*((u64*)&dsa) = 0;				
+	*((u64*)&dsa) = 0;
 
 	dsa.busNumber = busNumber;
 	dsa.subBusNumber = subBusNumber;
 	dsa.deviceId = deviceId;
 
-	retVal = HvCall4(HvCallPciConfigStore16, *(u64 *)&dsa, offset, value, 0);
-
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
-
-	return retVal;
+	return HvCall4(HvCallPciConfigStore16, *(u64 *)&dsa, offset, value, 0);
 }
-//============================================================================
-static inline u64	HvCallPci_configStore32(u16 busNumber, u8 subBusNumber,
-					      u8 deviceId, u32 offset,
-					      u32  value)
+
+static inline u64 HvCallPci_configStore32(u16 busNumber, u8 subBusNumber,
+		u8 deviceId, u32 offset, u32 value)
 {
 	struct HvCallPci_DsaAddr dsa;
-	u64 retVal;
 
-	*((u64*)&dsa) = 0;				
+	*((u64*)&dsa) = 0;
 
 	dsa.busNumber = busNumber;
 	dsa.subBusNumber = subBusNumber;
 	dsa.deviceId = deviceId;
 
-	retVal = HvCall4(HvCallPciConfigStore32, *(u64 *)&dsa, offset, value, 0);
-
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
-
-	return retVal;
+	return HvCall4(HvCallPciConfigStore32, *(u64 *)&dsa, offset, value, 0);
 }
-//============================================================================
-static inline u64	HvCallPci_barLoad8(u16	busNumberParm,
-					   u8		subBusParm,
-					   u8		deviceIdParm,
-					   u8		barNumberParm,
-					   u64		offsetParm,
-					   u8*		valueParm)
+
+static inline u64 HvCallPci_barLoad8(u16 busNumberParm, u8 subBusParm,
+		u8 deviceIdParm, u8 barNumberParm, u64 offsetParm,
+		u8 *valueParm)
 {
 	struct HvCallPci_DsaAddr dsa;
 	struct HvCallPci_LoadReturn retVal;
 
-	*((u64*)&dsa) = 0;				
+	*((u64*)&dsa) = 0;
 
 	dsa.busNumber = busNumberParm;
 	dsa.subBusNumber = subBusParm;
@@ -269,24 +241,19 @@ static inline u64	HvCallPci_barLoad8(u16
 
 	HvCall3Ret16(HvCallPciBarLoad8, &retVal, *(u64 *)&dsa, offsetParm, 0);
 
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
-
 	*valueParm = retVal.value;
 
 	return retVal.rc;
 }
-//============================================================================
-static inline u64	HvCallPci_barLoad16(u16	busNumberParm,
-					   u8		subBusParm,
-					   u8		deviceIdParm,
-					   u8		barNumberParm,
-					   u64		offsetParm,
-					   u16*		valueParm)
+
+static inline u64 HvCallPci_barLoad16(u16 busNumberParm, u8 subBusParm,
+		u8 deviceIdParm, u8 barNumberParm, u64 offsetParm,
+		u16 *valueParm)
 {
 	struct HvCallPci_DsaAddr dsa;
 	struct HvCallPci_LoadReturn retVal;
 
-	*((u64*)&dsa) = 0;				
+	*((u64*)&dsa) = 0;
 
 	dsa.busNumber = busNumberParm;
 	dsa.subBusNumber = subBusParm;
@@ -295,24 +262,19 @@ static inline u64	HvCallPci_barLoad16(u1
 
 	HvCall3Ret16(HvCallPciBarLoad16, &retVal, *(u64 *)&dsa, offsetParm, 0);
 
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
-
 	*valueParm = retVal.value;
 
 	return retVal.rc;
 }
-//============================================================================
-static inline u64	HvCallPci_barLoad32(u16	busNumberParm,
-					   u8		subBusParm,
-					   u8		deviceIdParm,
-					   u8		barNumberParm,
-					   u64		offsetParm,
-					   u32*		valueParm)
+
+static inline u64 HvCallPci_barLoad32(u16 busNumberParm, u8 subBusParm,
+		u8 deviceIdParm, u8 barNumberParm, u64 offsetParm,
+		u32 *valueParm)
 {
 	struct HvCallPci_DsaAddr dsa;
 	struct HvCallPci_LoadReturn retVal;
 
-	*((u64*)&dsa) = 0;				
+	*((u64*)&dsa) = 0;
 
 	dsa.busNumber = busNumberParm;
 	dsa.subBusNumber = subBusParm;
@@ -321,24 +283,19 @@ static inline u64	HvCallPci_barLoad32(u1
 
 	HvCall3Ret16(HvCallPciBarLoad32, &retVal, *(u64 *)&dsa, offsetParm, 0);
 
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
-
 	*valueParm = retVal.value;
 
 	return retVal.rc;
 }
-//============================================================================
-static inline u64	HvCallPci_barLoad64(u16	busNumberParm,
-					   u8		subBusParm,
-					   u8		deviceIdParm,
-					   u8		barNumberParm,
-					   u64		offsetParm,
-					   u64*		valueParm)
+
+static inline u64 HvCallPci_barLoad64(u16 busNumberParm, u8 subBusParm,
+		u8 deviceIdParm, u8 barNumberParm, u64 offsetParm,
+		u64 *valueParm)
 {
 	struct HvCallPci_DsaAddr dsa;
 	struct HvCallPci_LoadReturn retVal;
 
-	*((u64*)&dsa) = 0;				
+	*((u64*)&dsa) = 0;
 
 	dsa.busNumber = busNumberParm;
 	dsa.subBusNumber = subBusParm;
@@ -347,112 +304,81 @@ static inline u64	HvCallPci_barLoad64(u1
 
 	HvCall3Ret16(HvCallPciBarLoad64, &retVal, *(u64 *)&dsa, offsetParm, 0);
 
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
-
 	*valueParm = retVal.value;
 
 	return retVal.rc;
 }
-//============================================================================
-static inline u64	HvCallPci_barStore8(u16	busNumberParm,
-					    u8		subBusParm,
-					    u8		deviceIdParm,
-					    u8		barNumberParm,
-					    u64		offsetParm,
-					    u8		valueParm)
+
+static inline u64 HvCallPci_barStore8(u16 busNumberParm, u8 subBusParm,
+		u8 deviceIdParm, u8 barNumberParm, u64 offsetParm,
+		u8 valueParm)
 {
 	struct HvCallPci_DsaAddr dsa;
-	u64 retVal;
 
 	*((u64*)&dsa) = 0;
-				
+
 	dsa.busNumber = busNumberParm;
 	dsa.subBusNumber = subBusParm;
 	dsa.deviceId = deviceIdParm;
 	dsa.barNumber = barNumberParm;
 
-	retVal = HvCall4(HvCallPciBarStore8, *(u64 *)&dsa, offsetParm, valueParm, 0);
-
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
-
-	return retVal;
+	return HvCall4(HvCallPciBarStore8, *(u64 *)&dsa, offsetParm,
+			valueParm, 0);
 }
-//============================================================================
-static inline u64	HvCallPci_barStore16(u16	busNumberParm,
-					     u8		subBusParm,
-					     u8		deviceIdParm,
-					     u8		barNumberParm,
-					     u64	offsetParm,
-					     u16	valueParm)
+
+static inline u64 HvCallPci_barStore16(u16 busNumberParm, u8 subBusParm,
+		u8 deviceIdParm, u8 barNumberParm, u64 offsetParm,
+		u16 valueParm)
 {
 	struct HvCallPci_DsaAddr dsa;
-	u64 retVal;
 
 	*((u64*)&dsa) = 0;
-				
+
 	dsa.busNumber = busNumberParm;
 	dsa.subBusNumber = subBusParm;
 	dsa.deviceId = deviceIdParm;
 	dsa.barNumber = barNumberParm;
 
-	retVal = HvCall4(HvCallPciBarStore16, *(u64 *)&dsa, offsetParm, valueParm, 0);
-
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
-
-	return retVal;
+	return HvCall4(HvCallPciBarStore16, *(u64 *)&dsa, offsetParm,
+			valueParm, 0);
 }
-//============================================================================
-static inline u64	HvCallPci_barStore32(u16	busNumberParm,
-					     u8		subBusParm,
-					     u8		deviceIdParm,
-					     u8		barNumberParm,
-					     u64	offsetParm,
-					     u32	valueParm)
+
+static inline u64 HvCallPci_barStore32(u16 busNumberParm, u8 subBusParm,
+		u8 deviceIdParm, u8 barNumberParm, u64 offsetParm,
+		u32 valueParm)
 {
 	struct HvCallPci_DsaAddr dsa;
-	u64 retVal;
 
 	*((u64*)&dsa) = 0;
-				
+
 	dsa.busNumber = busNumberParm;
 	dsa.subBusNumber = subBusParm;
 	dsa.deviceId = deviceIdParm;
 	dsa.barNumber = barNumberParm;
 
-	retVal = HvCall4(HvCallPciBarStore32, *(u64 *)&dsa, offsetParm, valueParm, 0);
-
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
-
-	return retVal;
+	return HvCall4(HvCallPciBarStore32, *(u64 *)&dsa, offsetParm,
+			valueParm, 0);
 }
-//============================================================================
-static inline u64	HvCallPci_barStore64(u16	busNumberParm,
-					     u8		subBusParm,
-					     u8		deviceIdParm,
-					     u8		barNumberParm,
-					     u64	offsetParm,
-					     u64	valueParm)
+
+static inline u64 HvCallPci_barStore64(u16 busNumberParm, u8 subBusParm,
+		u8 deviceIdParm, u8 barNumberParm, u64 offsetParm,
+		u64 valueParm)
 {
 	struct HvCallPci_DsaAddr dsa;
-	u64 retVal;
 
 	*((u64*)&dsa) = 0;
-				
+
 	dsa.busNumber = busNumberParm;
 	dsa.subBusNumber = subBusParm;
 	dsa.deviceId = deviceIdParm;
 	dsa.barNumber = barNumberParm;
 
-	retVal = HvCall4(HvCallPciBarStore64, *(u64 *)&dsa, offsetParm, valueParm, 0);
-
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
-
-	return retVal;
+	return HvCall4(HvCallPciBarStore64, *(u64 *)&dsa, offsetParm,
+			valueParm, 0);
 }
-//============================================================================
-static inline u64	HvCallPci_eoi(u16	busNumberParm,
-				      u8	subBusParm,  
-				      u8	deviceIdParm)
+
+static inline u64 HvCallPci_eoi(u16 busNumberParm, u8 subBusParm,
+		u8 deviceIdParm)
 {
 	struct HvCallPci_DsaAddr dsa;
 	struct HvCallPci_LoadReturn retVal;
@@ -465,20 +391,13 @@ static inline u64	HvCallPci_eoi(u16	busN
 
 	HvCall1Ret16(HvCallPciEoi, &retVal, *(u64*)&dsa);
 
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
-
 	return retVal.rc;
 }
-//============================================================================
-static inline u64	HvCallPci_getBarParms(u16	busNumberParm,
-					      u8	subBusParm,  
-					      u8	deviceIdParm,
-					      u8	barNumberParm,
-					      u64	parms,
-					      u32	sizeofParms)
+
+static inline u64 HvCallPci_getBarParms(u16 busNumberParm, u8 subBusParm,
+		u8 deviceIdParm, u8 barNumberParm, u64 parms, u32 sizeofParms)
 {
 	struct HvCallPci_DsaAddr dsa;
-	u64 retVal;
 
 	*((u64*)&dsa) = 0;
 
@@ -487,62 +406,41 @@ static inline u64	HvCallPci_getBarParms(
 	dsa.deviceId = deviceIdParm;
 	dsa.barNumber = barNumberParm;
 
-	retVal = HvCall3(HvCallPciGetBarParms, *(u64*)&dsa, parms, sizeofParms);
-
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
-
-	return retVal;
+	return HvCall3(HvCallPciGetBarParms, *(u64*)&dsa, parms, sizeofParms);
 }
-//============================================================================
-static inline u64	HvCallPci_maskFisr(u16	busNumberParm,
-					   u8	subBusParm,  
-					   u8	deviceIdParm,
-					   u64	fisrMask)
+
+static inline u64 HvCallPci_maskFisr(u16 busNumberParm, u8 subBusParm,
+		u8 deviceIdParm, u64 fisrMask)
 {
 	struct HvCallPci_DsaAddr dsa;
-	u64 retVal;
 
-	*((u64*)&dsa) = 0;		
+	*((u64*)&dsa) = 0;
 
 	dsa.busNumber = busNumberParm;
 	dsa.subBusNumber = subBusParm;
 	dsa.deviceId = deviceIdParm;
 
-	retVal = HvCall2(HvCallPciMaskFisr, *(u64*)&dsa, fisrMask);
-
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
-
-	return retVal;
+	return HvCall2(HvCallPciMaskFisr, *(u64*)&dsa, fisrMask);
 }
-//============================================================================
-static inline u64	HvCallPci_unmaskFisr(u16	busNumberParm,
-					     u8		subBusParm,  
-					     u8		deviceIdParm,
-					     u64	fisrMask)
+
+static inline u64 HvCallPci_unmaskFisr(u16 busNumberParm, u8 subBusParm,
+		u8 deviceIdParm, u64 fisrMask)
 {
 	struct HvCallPci_DsaAddr dsa;
-	u64 retVal;
 
-	*((u64*)&dsa) = 0;		
+	*((u64*)&dsa) = 0;
 
 	dsa.busNumber = busNumberParm;
 	dsa.subBusNumber = subBusParm;
 	dsa.deviceId = deviceIdParm;
 
-	retVal = HvCall2(HvCallPciUnmaskFisr, *(u64*)&dsa, fisrMask);
-
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
-
-	return retVal;
+	return HvCall2(HvCallPciUnmaskFisr, *(u64*)&dsa, fisrMask);
 }
-//============================================================================
-static inline u64	HvCallPci_setSlotReset(u16		busNumberParm,
-					       u8		subBusParm,
-					       u8		deviceIdParm,
-					       u64		onNotOff)
+
+static inline u64 HvCallPci_setSlotReset(u16 busNumberParm, u8 subBusParm,
+		u8 deviceIdParm, u64 onNotOff)
 {
 	struct HvCallPci_DsaAddr dsa;
-	u64 retVal;
 
 	*((u64*)&dsa) = 0;
 
@@ -550,21 +448,13 @@ static inline u64	HvCallPci_setSlotReset
 	dsa.subBusNumber = subBusParm;
 	dsa.deviceId = deviceIdParm;
 
-	retVal = HvCall2(HvCallPciSetSlotReset, *(u64*)&dsa, onNotOff);
-
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
-
-	return retVal;
+	return HvCall2(HvCallPciSetSlotReset, *(u64*)&dsa, onNotOff);
 }
-//============================================================================
-static inline u64	HvCallPci_getDeviceInfo(u16	busNumberParm,
-						u8	subBusParm,  
-						u8	deviceNumberParm,
-						u64     parms,
-						u32	sizeofParms)
+
+static inline u64 HvCallPci_getDeviceInfo(u16 busNumberParm, u8 subBusParm,
+		u8 deviceNumberParm, u64 parms, u32 sizeofParms)
 {
 	struct HvCallPci_DsaAddr dsa;
-	u64 retVal;
 
 	*((u64*)&dsa) = 0;
 
@@ -572,102 +462,72 @@ static inline u64	HvCallPci_getDeviceInf
 	dsa.subBusNumber = subBusParm;
 	dsa.deviceId = deviceNumberParm << 4;
 
-	retVal = HvCall3(HvCallPciGetDeviceInfo, *(u64*)&dsa, parms, sizeofParms);
-
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
-
-	return retVal;
+	return HvCall3(HvCallPciGetDeviceInfo, *(u64*)&dsa, parms, sizeofParms);
 }
-//============================================================================
-static inline u64	HvCallPci_maskInterrupts(u16	busNumberParm,
-						 u8	subBusParm,  
-						 u8	deviceIdParm,
-						 u64	interruptMask)
+
+static inline u64 HvCallPci_maskInterrupts(u16 busNumberParm, u8 subBusParm,
+		u8 deviceIdParm, u64 interruptMask)
 {
 	struct HvCallPci_DsaAddr dsa;
-	u64 retVal;
 
-	*((u64*)&dsa) = 0;		
+	*((u64*)&dsa) = 0;
 
 	dsa.busNumber = busNumberParm;
 	dsa.subBusNumber = subBusParm;
 	dsa.deviceId = deviceIdParm;
 
-	retVal = HvCall2(HvCallPciMaskInterrupts, *(u64*)&dsa, interruptMask);
-
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
-
-	return retVal;
+	return HvCall2(HvCallPciMaskInterrupts, *(u64*)&dsa, interruptMask);
 }
-//============================================================================
-static inline u64	HvCallPci_unmaskInterrupts(u16	busNumberParm,
-						 u8		subBusParm,  
-						 u8		deviceIdParm,
-						 u64		interruptMask)
+
+static inline u64 HvCallPci_unmaskInterrupts(u16 busNumberParm, u8 subBusParm,
+		u8 deviceIdParm, u64 interruptMask)
 {
 	struct HvCallPci_DsaAddr dsa;
-	u64 retVal;
 
-	*((u64*)&dsa) = 0;		
+	*((u64*)&dsa) = 0;
 
 	dsa.busNumber = busNumberParm;
 	dsa.subBusNumber = subBusParm;
 	dsa.deviceId = deviceIdParm;
 
-	retVal = HvCall2(HvCallPciUnmaskInterrupts, *(u64*)&dsa, interruptMask);
-
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
-
-	return retVal;
+	return HvCall2(HvCallPciUnmaskInterrupts, *(u64*)&dsa, interruptMask);
 }
-//============================================================================
 
-static inline u64	HvCallPci_getBusUnitInfo(u16		busNumberParm,
-						 u8		subBusParm,  
-						 u8		deviceIdParm,
-						 u64            parms,
-						 u32		sizeofParms)
+static inline u64 HvCallPci_getBusUnitInfo(u16 busNumberParm, u8 subBusParm,
+		u8 deviceIdParm, u64 parms, u32 sizeofParms)
 {
 	struct HvCallPci_DsaAddr dsa;
-	u64 retVal;
 
-	*((u64*)&dsa) = 0;		
+	*((u64*)&dsa) = 0;
 
 	dsa.busNumber = busNumberParm;
 	dsa.subBusNumber = subBusParm;
 	dsa.deviceId = deviceIdParm;
 
-	retVal = HvCall3(HvCallPciGetBusUnitInfo, *(u64*)&dsa, parms, sizeofParms);
-
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
-
-	return retVal;
+	return HvCall3(HvCallPciGetBusUnitInfo, *(u64*)&dsa, parms,
+			sizeofParms);
 }
-//============================================================================
 
-static inline int HvCallPci_getBusVpd(u16 busNumParm, u64 destParm, u16 sizeParm)
+static inline int HvCallPci_getBusVpd(u16 busNumParm, u64 destParm,
+		u16 sizeParm)
 {
-	int xRetSize;
-	u64 xRc = HvCall4(HvCallPciGetCardVpd, busNumParm, destParm, sizeParm, HvCallPci_BusVpd);
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+	u64 xRc = HvCall4(HvCallPciGetCardVpd, busNumParm, destParm,
+			sizeParm, HvCallPci_BusVpd);
 	if (xRc == -1)
-		xRetSize = -1;
+		return -1;
 	else
-		xRetSize = xRc & 0xFFFF;
-	return xRetSize;
+		return xRc & 0xFFFF;
 }
-//============================================================================
 
-static inline int HvCallPci_getBusAdapterVpd(u16 busNumParm, u64 destParm, u16 sizeParm)
+static inline int HvCallPci_getBusAdapterVpd(u16 busNumParm, u64 destParm,
+		u16 sizeParm)
 {
-	int xRetSize;
-	u64 xRc = HvCall4(HvCallPciGetCardVpd, busNumParm, destParm, sizeParm, HvCallPci_BusAdapterVpd);
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
+	u64 xRc = HvCall4(HvCallPciGetCardVpd, busNumParm, destParm,
+			sizeParm, HvCallPci_BusAdapterVpd);
 	if (xRc == -1)
-		xRetSize = -1;
+		return -1;
 	else
-		xRetSize = xRc & 0xFFFF;
-	return xRetSize;
+		return xRc & 0xFFFF;
 }
-//============================================================================
+
 #endif /* _HVCALLPCI_H */
diff --git a/include/asm-ppc64/iSeries/HvCallSc.h b/include/asm-ppc64/iSeries/HvCallSc.h
--- a/include/asm-ppc64/iSeries/HvCallSc.h
+++ b/include/asm-ppc64/iSeries/HvCallSc.h
@@ -1,17 +1,17 @@
 /*
  * HvCallSc.h
  * Copyright (C) 2001  Mike Corrigan IBM Corporation
- * 
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
@@ -19,7 +19,7 @@
 #ifndef _HVCALLSC_H
 #define _HVCALLSC_H
 
-#include <asm/iSeries/HvTypes.h>
+#include <linux/types.h>
 
 #define HvCallBase		0x8000000000000000ul
 #define HvCallCc		0x8001000000000000ul
@@ -30,22 +30,22 @@
 #define HvCallSm		0x8007000000000000ul
 #define HvCallXm		0x8009000000000000ul
 
-u64 HvCall0( u64 );
-u64 HvCall1( u64, u64 );
-u64 HvCall2( u64, u64, u64 );
-u64 HvCall3( u64, u64, u64, u64 );
-u64 HvCall4( u64, u64, u64, u64, u64 );
-u64 HvCall5( u64, u64, u64, u64, u64, u64 );
-u64 HvCall6( u64, u64, u64, u64, u64, u64, u64 );
-u64 HvCall7( u64, u64, u64, u64, u64, u64, u64, u64 );
+extern u64 HvCall0(u64);
+extern u64 HvCall1(u64, u64);
+extern u64 HvCall2(u64, u64, u64);
+extern u64 HvCall3(u64, u64, u64, u64);
+extern u64 HvCall4(u64, u64, u64, u64, u64);
+extern u64 HvCall5(u64, u64, u64, u64, u64, u64);
+extern u64 HvCall6(u64, u64, u64, u64, u64, u64, u64);
+extern u64 HvCall7(u64, u64, u64, u64, u64, u64, u64, u64);
 
-u64 HvCall0Ret16( u64, void * );
-u64 HvCall1Ret16( u64, void *, u64 );
-u64 HvCall2Ret16( u64, void *, u64, u64 );
-u64 HvCall3Ret16( u64, void *, u64, u64, u64 );
-u64 HvCall4Ret16( u64, void *, u64, u64, u64, u64 );
-u64 HvCall5Ret16( u64, void *, u64, u64, u64, u64, u64 );
-u64 HvCall6Ret16( u64, void *, u64, u64, u64, u64, u64, u64 );
-u64 HvCall7Ret16( u64, void *, u64, u64 ,u64 ,u64 ,u64 ,u64 ,u64 );
+extern u64 HvCall0Ret16(u64, void *);
+extern u64 HvCall1Ret16(u64, void *, u64);
+extern u64 HvCall2Ret16(u64, void *, u64, u64);
+extern u64 HvCall3Ret16(u64, void *, u64, u64, u64);
+extern u64 HvCall4Ret16(u64, void *, u64, u64, u64, u64);
+extern u64 HvCall5Ret16(u64, void *, u64, u64, u64, u64, u64);
+extern u64 HvCall6Ret16(u64, void *, u64, u64, u64, u64, u64, u64);
+extern u64 HvCall7Ret16(u64, void *, u64, u64 ,u64 ,u64 ,u64 ,u64 ,u64);
 
 #endif /* _HVCALLSC_H */
diff --git a/include/asm-ppc64/iSeries/HvCallSm.h b/include/asm-ppc64/iSeries/HvCallSm.h
--- a/include/asm-ppc64/iSeries/HvCallSm.h
+++ b/include/asm-ppc64/iSeries/HvCallSm.h
@@ -1,17 +1,17 @@
 /*
  * HvCallSm.h
  * Copyright (C) 2001  Mike Corrigan IBM Corporation
- * 
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
@@ -19,34 +19,20 @@
 #ifndef _HVCALLSM_H
 #define _HVCALLSM_H
 
-//============================================================================
-//
-//	This file contains the "hypervisor call" interface which is used to
-//	drive the hypervisor from the OS.
-//
-//============================================================================
+/*
+ * This file contains the "hypervisor call" interface which is used to
+ * drive the hypervisor from the OS.
+ */
 
-//-------------------------------------------------------------------
-// Standard Includes
-//-------------------------------------------------------------------
 #include <asm/iSeries/HvCallSc.h>
 #include <asm/iSeries/HvTypes.h>
 
-//-----------------------------------------------------------------------------
-// Constants
-//-----------------------------------------------------------------------------
-
 #define HvCallSmGet64BitsOfAccessMap	HvCallSm  + 11
 
-
-//============================================================================
-static inline u64		HvCallSm_get64BitsOfAccessMap(
-					HvLpIndex lpIndex, u64 indexIntoBitMap )
+static inline u64 HvCallSm_get64BitsOfAccessMap(HvLpIndex lpIndex,
+		u64 indexIntoBitMap)
 {
-	u64 retval = HvCall2(HvCallSmGet64BitsOfAccessMap, lpIndex,
-			     indexIntoBitMap );
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
-	return retval;
+	return HvCall2(HvCallSmGet64BitsOfAccessMap, lpIndex, indexIntoBitMap);
 }
-//============================================================================
+
 #endif /* _HVCALLSM_H */
diff --git a/include/asm-ppc64/iSeries/HvCallXm.h b/include/asm-ppc64/iSeries/HvCallXm.h
--- a/include/asm-ppc64/iSeries/HvCallXm.h
+++ b/include/asm-ppc64/iSeries/HvCallXm.h
@@ -1,30 +1,13 @@
-//============================================================================
-//							 Header File Id
-// Name______________:	HvCallXm.H
-//
-// Description_______:
-//
-//	This file contains the "hypervisor call" interface which is used to
-//	drive the hypervisor from SLIC.
-//
-//============================================================================
+/*
+ * This file contains the "hypervisor call" interface which is used to
+ * drive the hypervisor from SLIC.
+ */
 #ifndef _HVCALLXM_H
 #define _HVCALLXM_H
 
-//-------------------------------------------------------------------
-// Forward declarations 
-//-------------------------------------------------------------------
-
-//-------------------------------------------------------------------
-// Standard Includes
-//-------------------------------------------------------------------
 #include <asm/iSeries/HvCallSc.h>
 #include <asm/iSeries/HvTypes.h>
 
-//-----------------------------------------------------------------------------
-// Constants
-//-----------------------------------------------------------------------------
-
 #define HvCallXmGetTceTableParms	HvCallXm +  0
 #define HvCallXmTestBus			HvCallXm +  1
 #define HvCallXmConnectBusUnit		HvCallXm +  2
@@ -33,63 +16,63 @@
 #define HvCallXmSetTce			HvCallXm + 11
 #define HvCallXmSetTces			HvCallXm + 13
 
+/*
+ * Structure passed to HvCallXm_getTceTableParms
+ */
+struct iommu_table_cb {
+	unsigned long	itc_busno;	/* Bus number for this tce table */
+	unsigned long	itc_start;	/* Will be NULL for secondary */
+	unsigned long	itc_totalsize;	/* Size (in pages) of whole table */
+	unsigned long	itc_offset;	/* Index into real tce table of the
+					   start of our section */
+	unsigned long	itc_size;	/* Size (in pages) of our section */
+	unsigned long	itc_index;	/* Index of this tce table */
+	unsigned short	itc_maxtables;	/* Max num of tables for partition */
+	unsigned char	itc_virtbus;	/* Flag to indicate virtual bus */
+	unsigned char	itc_slotno;	/* IOA Tce Slot Index */
+	unsigned char	itc_rsvd[4];
+};
 
-
-//============================================================================
-static inline void		HvCallXm_getTceTableParms(u64 cb)
+static inline void HvCallXm_getTceTableParms(u64 cb)
 {
 	HvCall1(HvCallXmGetTceTableParms, cb);
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
 }
-//============================================================================
-static inline u64		HvCallXm_setTce(u64 tceTableToken, u64 tceOffset, u64 tce)
-{	
-	u64 retval = HvCall3(HvCallXmSetTce, tceTableToken, tceOffset, tce );
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
-	return retval;
-}
-//============================================================================
-static inline u64		HvCallXm_setTces(u64 tceTableToken, u64 tceOffset, u64 numTces, u64 tce1, u64 tce2, u64 tce3, u64 tce4)
-{	
-	u64 retval = HvCall7(HvCallXmSetTces, tceTableToken, tceOffset, numTces,
-			     tce1, tce2, tce3, tce4 );
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
-	return retval;
-}
-//=============================================================================
-static inline u64	HvCallXm_testBus(u16 busNumber)
-{
-	u64 retVal = HvCall1(HvCallXmTestBus, busNumber);
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
-	return retVal;
-}
-//=====================================================================================
-static inline u64	HvCallXm_testBusUnit(u16 busNumber, u8 subBusNumber, u8 deviceId)
-{
-	u64 busUnitNumber = (subBusNumber << 8) | deviceId;
-	u64 retVal = HvCall2(HvCallXmTestBusUnit, busNumber, busUnitNumber);
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
-	return retVal;
-}
-//=====================================================================================
-static inline u64	HvCallXm_connectBusUnit(u16 busNumber, u8 subBusNumber, u8 deviceId,
-						u64 interruptToken)
-{
-	u64 busUnitNumber = (subBusNumber << 8) | deviceId;
-	u64 queueIndex = 0; // HvLpConfig::mapDsaToQueueIndex(HvLpDSA(busNumber, xBoard, xCard));  
-
-	u64 retVal = HvCall5(HvCallXmConnectBusUnit, busNumber, busUnitNumber,
-			     interruptToken, 0, queueIndex);
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
-	return retVal;
-}
-//=====================================================================================
-static inline u64	HvCallXm_loadTod(void)
-{
-	u64 retVal = HvCall0(HvCallXmLoadTod);
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
-	return retVal;
+
+static inline u64 HvCallXm_setTce(u64 tceTableToken, u64 tceOffset, u64 tce)
+{
+	return HvCall3(HvCallXmSetTce, tceTableToken, tceOffset, tce);
+}
+
+static inline u64 HvCallXm_setTces(u64 tceTableToken, u64 tceOffset,
+		u64 numTces, u64 tce1, u64 tce2, u64 tce3, u64 tce4)
+{
+	return HvCall7(HvCallXmSetTces, tceTableToken, tceOffset, numTces,
+			     tce1, tce2, tce3, tce4);
+}
+
+static inline u64 HvCallXm_testBus(u16 busNumber)
+{
+	return HvCall1(HvCallXmTestBus, busNumber);
+}
+
+static inline u64 HvCallXm_testBusUnit(u16 busNumber, u8 subBusNumber,
+		u8 deviceId)
+{
+	return HvCall2(HvCallXmTestBusUnit, busNumber,
+			(subBusNumber << 8) | deviceId);
+}
+
+static inline u64 HvCallXm_connectBusUnit(u16 busNumber, u8 subBusNumber,
+		u8 deviceId, u64 interruptToken)
+{
+	return HvCall5(HvCallXmConnectBusUnit, busNumber,
+			(subBusNumber << 8) | deviceId, interruptToken, 0,
+			0 /* HvLpConfig::mapDsaToQueueIndex(HvLpDSA(busNumber, xBoard, xCard)) */);
+}
+
+static inline u64 HvCallXm_loadTod(void)
+{
+	return HvCall0(HvCallXmLoadTod);
 }
-//=====================================================================================
 
 #endif /* _HVCALLXM_H */
diff --git a/include/asm-ppc64/iSeries/HvLpConfig.h b/include/asm-ppc64/iSeries/HvLpConfig.h
--- a/include/asm-ppc64/iSeries/HvLpConfig.h
+++ b/include/asm-ppc64/iSeries/HvLpConfig.h
@@ -1,17 +1,17 @@
 /*
  * HvLpConfig.h
  * Copyright (C) 2001  Mike Corrigan IBM Corporation
- * 
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
@@ -19,262 +19,120 @@
 #ifndef _HVLPCONFIG_H
 #define _HVLPCONFIG_H
 
-//===========================================================================
-//
-//      This file contains the interface to the LPAR configuration data
-//  to determine which resources should be allocated to each partition.
-//
-//===========================================================================
+/*
+ * This file contains the interface to the LPAR configuration data
+ * to determine which resources should be allocated to each partition.
+ */
 
-#include <asm/iSeries/HvCallCfg.h>
+#include <asm/iSeries/HvCallSc.h>
 #include <asm/iSeries/HvTypes.h>
 #include <asm/iSeries/ItLpNaca.h>
-#include <asm/iSeries/LparData.h>
 
-//-------------------------------------------------------------------
-// Constants
-//-------------------------------------------------------------------
+enum {
+	HvCallCfg_Cur	= 0,
+	HvCallCfg_Init	= 1,
+	HvCallCfg_Max	= 2,
+	HvCallCfg_Min	= 3
+};
+
+#define HvCallCfgGetSystemPhysicalProcessors		HvCallCfg +  6
+#define HvCallCfgGetPhysicalProcessors			HvCallCfg +  7
+#define HvCallCfgGetMsChunks				HvCallCfg +  9
+#define HvCallCfgGetSharedPoolIndex			HvCallCfg + 20
+#define HvCallCfgGetSharedProcUnits			HvCallCfg + 21
+#define HvCallCfgGetNumProcsInSharedPool		HvCallCfg + 22
+#define HvCallCfgGetVirtualLanIndexMap			HvCallCfg + 30
+#define HvCallCfgGetHostingLpIndex			HvCallCfg + 32
 
 extern HvLpIndex HvLpConfig_getLpIndex_outline(void);
 
-//===================================================================
 static inline HvLpIndex	HvLpConfig_getLpIndex(void)
 {
 	return itLpNaca.xLpIndex;
 }
-//===================================================================
+
 static inline HvLpIndex	HvLpConfig_getPrimaryLpIndex(void)
 {
 	return itLpNaca.xPrimaryLpIndex;
 }
-//=================================================================
-static inline HvLpIndex	HvLpConfig_getLps(void)
-{
-	return HvCallCfg_getLps();
-}
-//=================================================================
-static inline HvLpIndexMap	HvLpConfig_getActiveLpMap(void)
-{
-	return HvCallCfg_getActiveLpMap();
-}
-//=================================================================
-static inline u64		HvLpConfig_getSystemMsMegs(void)
-{
-	return HvCallCfg_getSystemMsChunks() / HVCHUNKSPERMEG;
-}
-//=================================================================
-static inline u64		HvLpConfig_getSystemMsChunks(void)
-{
-	return HvCallCfg_getSystemMsChunks();
-}
-//=================================================================
-static inline u64		HvLpConfig_getSystemMsPages(void)
-{
-	return HvCallCfg_getSystemMsChunks() * HVPAGESPERCHUNK;
-}
-//================================================================
-static inline u64		HvLpConfig_getMsMegs(void)
-{
-	return HvCallCfg_getMsChunks(HvLpConfig_getLpIndex(),HvCallCfg_Cur) / HVCHUNKSPERMEG;
-}
-//================================================================
-static inline u64		HvLpConfig_getMsChunks(void)
-{
-	return HvCallCfg_getMsChunks(HvLpConfig_getLpIndex(),HvCallCfg_Cur);
-}
-//================================================================
-static inline u64		HvLpConfig_getMsPages(void)
-{
-	return HvCallCfg_getMsChunks(HvLpConfig_getLpIndex(),HvCallCfg_Cur) * HVPAGESPERCHUNK;
-}
-//================================================================
-static inline u64		HvLpConfig_getMinMsMegs(void)
-{
-	return HvCallCfg_getMsChunks(HvLpConfig_getLpIndex(),HvCallCfg_Min) / HVCHUNKSPERMEG;
-}
-//================================================================
-static inline u64		HvLpConfig_getMinMsChunks(void)
-{
-	return HvCallCfg_getMsChunks(HvLpConfig_getLpIndex(),HvCallCfg_Min);
-}
-//================================================================
-static inline u64		HvLpConfig_getMinMsPages(void)
-{
-	return HvCallCfg_getMsChunks(HvLpConfig_getLpIndex(),HvCallCfg_Min) * HVPAGESPERCHUNK;
-}
-//================================================================
-static inline u64		HvLpConfig_getMinRuntimeMsMegs(void)
-{
-	return HvCallCfg_getMinRuntimeMsChunks(HvLpConfig_getLpIndex()) / HVCHUNKSPERMEG;
-}
-//===============================================================
-static inline u64		HvLpConfig_getMinRuntimeMsChunks(void)
-{
-	return HvCallCfg_getMinRuntimeMsChunks(HvLpConfig_getLpIndex());
-}
-//===============================================================
-static inline u64		HvLpConfig_getMinRuntimeMsPages(void)
-{
-	return HvCallCfg_getMinRuntimeMsChunks(HvLpConfig_getLpIndex()) * HVPAGESPERCHUNK;
-}
-//===============================================================
-static inline u64		HvLpConfig_getMaxMsMegs(void)
-{
-	return HvCallCfg_getMsChunks(HvLpConfig_getLpIndex(),HvCallCfg_Max) / HVCHUNKSPERMEG;
-}
-//===============================================================
-static inline u64		HvLpConfig_getMaxMsChunks(void)
-{
-	return HvCallCfg_getMsChunks(HvLpConfig_getLpIndex(),HvCallCfg_Max);
-}
-//===============================================================
-static inline u64		HvLpConfig_getMaxMsPages(void)
-{
-	return HvCallCfg_getMsChunks(HvLpConfig_getLpIndex(),HvCallCfg_Max) * HVPAGESPERCHUNK;
-}
-//===============================================================
-static inline u64		HvLpConfig_getInitMsMegs(void)
-{
-	return HvCallCfg_getMsChunks(HvLpConfig_getLpIndex(),HvCallCfg_Init) / HVCHUNKSPERMEG;
-}
-//===============================================================
-static inline u64		HvLpConfig_getInitMsChunks(void)
-{
-	return HvCallCfg_getMsChunks(HvLpConfig_getLpIndex(),HvCallCfg_Init);
-}
-//===============================================================
-static inline u64		HvLpConfig_getInitMsPages(void)
-{    return HvCallCfg_getMsChunks(HvLpConfig_getLpIndex(),HvCallCfg_Init) * HVPAGESPERCHUNK;
-}
-//===============================================================
-static inline u64		HvLpConfig_getSystemPhysicalProcessors(void)
-{
-	return HvCallCfg_getSystemPhysicalProcessors();
-}
-//===============================================================
-static inline u64		HvLpConfig_getSystemLogicalProcessors(void)
-{
-	return HvCallCfg_getSystemPhysicalProcessors() * (/*getPaca()->getSecondaryThreadCount() +*/ 1);
-}
-//===============================================================
-static inline u64		HvLpConfig_getNumProcsInSharedPool(HvLpSharedPoolIndex sPI)
-{
-	return HvCallCfg_getNumProcsInSharedPool(sPI);
-}
-//===============================================================
-static inline u64		HvLpConfig_getPhysicalProcessors(void)
-{
-	return HvCallCfg_getPhysicalProcessors(HvLpConfig_getLpIndex(),HvCallCfg_Cur);
-}
-//===============================================================
-static inline u64		HvLpConfig_getLogicalProcessors(void)
-{
-	return HvCallCfg_getPhysicalProcessors(HvLpConfig_getLpIndex(),HvCallCfg_Cur) * (/*getPaca()->getSecondaryThreadCount() +*/ 1);
-}
-//===============================================================
-static inline HvLpSharedPoolIndex	HvLpConfig_getSharedPoolIndex(void)
-{
-	return HvCallCfg_getSharedPoolIndex(HvLpConfig_getLpIndex());
-}
-//===============================================================
-static inline u64		HvLpConfig_getSharedProcUnits(void)
-{
-	return HvCallCfg_getSharedProcUnits(HvLpConfig_getLpIndex(),HvCallCfg_Cur);
-}
-//===============================================================
-static inline u64		HvLpConfig_getMinSharedProcUnits(void)
-{
-	return HvCallCfg_getSharedProcUnits(HvLpConfig_getLpIndex(),HvCallCfg_Min);
-}
-//===============================================================
-static inline u64		HvLpConfig_getMaxSharedProcUnits(void)
-{
-	return HvCallCfg_getSharedProcUnits(HvLpConfig_getLpIndex(),HvCallCfg_Max);
-}
-//===============================================================
-static inline u64		HvLpConfig_getMinPhysicalProcessors(void)
-{
-	return HvCallCfg_getPhysicalProcessors(HvLpConfig_getLpIndex(),HvCallCfg_Min);
-}
-//===============================================================
-static inline u64		HvLpConfig_getMinLogicalProcessors(void)
-{
-	return HvCallCfg_getPhysicalProcessors(HvLpConfig_getLpIndex(),HvCallCfg_Min) * (/*getPaca()->getSecondaryThreadCount() +*/ 1);
-}
-//===============================================================
-static inline u64		HvLpConfig_getMaxPhysicalProcessors(void)
-{
-	return HvCallCfg_getPhysicalProcessors(HvLpConfig_getLpIndex(),HvCallCfg_Max);
-}
-//===============================================================
-static inline u64		HvLpConfig_getMaxLogicalProcessors(void)
-{
-	return HvCallCfg_getPhysicalProcessors(HvLpConfig_getLpIndex(),HvCallCfg_Max) * (/*getPaca()->getSecondaryThreadCount() +*/ 1);
-}
-//===============================================================
-static inline u64		HvLpConfig_getInitPhysicalProcessors(void)
+
+static inline u64 HvLpConfig_getMsChunks(void)
 {
-	return HvCallCfg_getPhysicalProcessors(HvLpConfig_getLpIndex(),HvCallCfg_Init);
+	return HvCall2(HvCallCfgGetMsChunks, HvLpConfig_getLpIndex(),
+			HvCallCfg_Cur);
 }
-//===============================================================
-static inline u64		HvLpConfig_getInitLogicalProcessors(void)
+
+static inline u64 HvLpConfig_getSystemPhysicalProcessors(void)
 {
-	return HvCallCfg_getPhysicalProcessors(HvLpConfig_getLpIndex(),HvCallCfg_Init) * (/*getPaca()->getSecondaryThreadCount() +*/ 1);
+	return HvCall0(HvCallCfgGetSystemPhysicalProcessors);
 }
-//================================================================
-static inline HvLpVirtualLanIndexMap	HvLpConfig_getVirtualLanIndexMap(void)
+
+static inline u64 HvLpConfig_getNumProcsInSharedPool(HvLpSharedPoolIndex sPI)
 {
-	return HvCallCfg_getVirtualLanIndexMap(HvLpConfig_getLpIndex_outline());
+	return (u16)HvCall1(HvCallCfgGetNumProcsInSharedPool, sPI);
 }
-//===============================================================
-static inline HvLpVirtualLanIndexMap	HvLpConfig_getVirtualLanIndexMapForLp(HvLpIndex lp)
+
+static inline u64 HvLpConfig_getPhysicalProcessors(void)
 {
-	return HvCallCfg_getVirtualLanIndexMap(lp);
+	return HvCall2(HvCallCfgGetPhysicalProcessors, HvLpConfig_getLpIndex(),
+			HvCallCfg_Cur);
 }
-//================================================================
-static inline HvLpIndex	HvLpConfig_getBusOwner(HvBusNumber busNumber)
+
+static inline HvLpSharedPoolIndex HvLpConfig_getSharedPoolIndex(void)
 {
-	return HvCallCfg_getBusOwner(busNumber);
+	return HvCall1(HvCallCfgGetSharedPoolIndex, HvLpConfig_getLpIndex());
 }
-//===============================================================
-static inline int		HvLpConfig_isBusDedicated(HvBusNumber busNumber)
+
+static inline u64 HvLpConfig_getSharedProcUnits(void)
 {
-	return HvCallCfg_isBusDedicated(busNumber);
+	return HvCall2(HvCallCfgGetSharedProcUnits, HvLpConfig_getLpIndex(),
+			HvCallCfg_Cur);
 }
-//================================================================
-static inline HvLpIndexMap	HvLpConfig_getBusAllocation(HvBusNumber busNumber)
+
+static inline u64 HvLpConfig_getMaxSharedProcUnits(void)
 {
-	return HvCallCfg_getBusAllocation(busNumber);
+	return HvCall2(HvCallCfgGetSharedProcUnits, HvLpConfig_getLpIndex(),
+			HvCallCfg_Max);
 }
-//================================================================
-// returns the absolute real address of the load area
-static inline u64		HvLpConfig_getLoadAddress(void)
+
+static inline u64 HvLpConfig_getMaxPhysicalProcessors(void)
 {
-	return itLpNaca.xLoadAreaAddr & 0x7fffffffffffffff;
+	return HvCall2(HvCallCfgGetPhysicalProcessors, HvLpConfig_getLpIndex(),
+			HvCallCfg_Max);
 }
-//================================================================
-static inline u64		HvLpConfig_getLoadPages(void)
+
+static inline HvLpVirtualLanIndexMap HvLpConfig_getVirtualLanIndexMapForLp(
+		HvLpIndex lp)
 {
-	return itLpNaca.xLoadAreaChunks * HVPAGESPERCHUNK;
+	/*
+	 * This is a new function in V5R1 so calls to this on older
+	 * hypervisors will return -1
+	 */
+	u64 retVal = HvCall1(HvCallCfgGetVirtualLanIndexMap, lp);
+	if (retVal == -1)
+		retVal = 0;
+	return retVal;
 }
-//================================================================
-static inline int		HvLpConfig_isBusOwnedByThisLp(HvBusNumber busNumber)
+
+static inline HvLpVirtualLanIndexMap HvLpConfig_getVirtualLanIndexMap(void)
 {
-	HvLpIndex busOwner = HvLpConfig_getBusOwner(busNumber);
-	return (busOwner == HvLpConfig_getLpIndex());
+	return HvLpConfig_getVirtualLanIndexMapForLp(
+			HvLpConfig_getLpIndex_outline());
 }
-//================================================================
-static inline int         HvLpConfig_doLpsCommunicateOnVirtualLan(HvLpIndex lp1, HvLpIndex lp2)
+
+static inline int HvLpConfig_doLpsCommunicateOnVirtualLan(HvLpIndex lp1,
+		HvLpIndex lp2)
 {
-	HvLpVirtualLanIndexMap virtualLanIndexMap1 = HvCallCfg_getVirtualLanIndexMap( lp1 );
-	HvLpVirtualLanIndexMap virtualLanIndexMap2 = HvCallCfg_getVirtualLanIndexMap( lp2 );
+	HvLpVirtualLanIndexMap virtualLanIndexMap1 =
+		HvLpConfig_getVirtualLanIndexMapForLp(lp1);
+	HvLpVirtualLanIndexMap virtualLanIndexMap2 =
+		HvLpConfig_getVirtualLanIndexMapForLp(lp2);
 	return ((virtualLanIndexMap1 & virtualLanIndexMap2) != 0);
 }
-//================================================================
-static inline HvLpIndex		HvLpConfig_getHostingLpIndex(HvLpIndex lp)
+
+static inline HvLpIndex HvLpConfig_getHostingLpIndex(HvLpIndex lp)
 {
-	return HvCallCfg_getHostingLpIndex(lp);
+	return HvCall1(HvCallCfgGetHostingLpIndex, lp);
 }
-//================================================================
 
 #endif /* _HVLPCONFIG_H */
diff --git a/include/asm-ppc64/iSeries/HvLpEvent.h b/include/asm-ppc64/iSeries/HvLpEvent.h
--- a/include/asm-ppc64/iSeries/HvLpEvent.h
+++ b/include/asm-ppc64/iSeries/HvLpEvent.h
@@ -1,27 +1,24 @@
 /*
  * HvLpEvent.h
  * Copyright (C) 2001  Mike Corrigan IBM Corporation
- * 
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  */
 
-//======================================================================
-//
-//	This file contains the class for HV events in the system.
-//
-//=====================================================================
+/* This file contains the class for HV events in the system. */
+
 #ifndef _HVLPEVENT_H
 #define _HVLPEVENT_H
 
@@ -30,69 +27,70 @@
 #include <asm/iSeries/HvTypes.h>
 #include <asm/iSeries/HvCallEvent.h>
 
-//=====================================================================
-//
-// HvLpEvent is the structure for Lp Event messages passed between
-// partitions through PLIC. 
-//
-//=====================================================================
-
-struct HvEventFlags
-{
-	u8	xValid:1;		// Indicates a valid request	x00-x00
-	u8	xRsvd1:4;		// Reserved			...
-	u8	xAckType:1;		// Immediate or deferred	...
-	u8	xAckInd:1;		// Indicates if ACK required	...
-	u8	xFunction:1;		// Interrupt or Acknowledge	...
+/*
+ * HvLpEvent is the structure for Lp Event messages passed between
+ * partitions through PLIC.
+ */
+
+struct HvEventFlags {
+	u8	xValid:1;	/* Indicates a valid request	x00-x00 */
+	u8	xRsvd1:4;	/* Reserved			... */
+	u8	xAckType:1;	/* Immediate or deferred	... */
+	u8	xAckInd:1;	/* Indicates if ACK required	... */
+	u8	xFunction:1;	/* Interrupt or Acknowledge	... */
 };
 
 
-struct HvLpEvent
-{
-	struct HvEventFlags xFlags;	// Event flags			x00-x00
-	u8	xType;			// Type of message		x01-x01
-	u16	xSubtype;		// Subtype for event		x02-x03
-	u8	xSourceLp;		// Source LP			x04-x04
-	u8	xTargetLp;		// Target LP			x05-x05
-	u8	xSizeMinus1;		// Size of Derived class - 1	x06-x06
-	u8	xRc;			// RC for Ack flows		x07-x07
-	u16	xSourceInstanceId;	// Source sides instance id	x08-x09
-	u16	xTargetInstanceId;	// Target sides instance id	x0A-x0B
+struct HvLpEvent {
+	struct HvEventFlags xFlags;	/* Event flags		      x00-x00 */
+	u8	xType;			/* Type of message	      x01-x01 */
+	u16	xSubtype;		/* Subtype for event	      x02-x03 */
+	u8	xSourceLp;		/* Source LP		      x04-x04 */
+	u8	xTargetLp;		/* Target LP		      x05-x05 */
+	u8	xSizeMinus1;		/* Size of Derived class - 1  x06-x06 */
+	u8	xRc;			/* RC for Ack flows	      x07-x07 */
+	u16	xSourceInstanceId;	/* Source sides instance id   x08-x09 */
+	u16	xTargetInstanceId;	/* Target sides instance id   x0A-x0B */
 	union {
-		u32	xSubtypeData;	// Data usable by the subtype	x0C-x0F
-		u16	xSubtypeDataShort[2];	// Data as 2 shorts
-		u8	xSubtypeDataChar[4];	// Data as 4 chars
+		u32	xSubtypeData;	/* Data usable by the subtype x0C-x0F */
+		u16	xSubtypeDataShort[2];	/* Data as 2 shorts */
+		u8	xSubtypeDataChar[4];	/* Data as 4 chars */
 	} x;
 
-	u64	xCorrelationToken;	// Unique value for source/type x10-x17
+	u64	xCorrelationToken;	/* Unique value for source/type x10-x17 */
 };
 
-// Lp Event handler function
 typedef void (*LpEventHandler)(struct HvLpEvent *, struct pt_regs *);
 
-// Register a handler for an event type
-//  returns 0 on success
-extern int HvLpEvent_registerHandler( HvLpEvent_Type eventType, LpEventHandler hdlr);
-
-// Unregister a handler for an event type
-//  This call will sleep until the handler being removed is guaranteed to
-//  be no longer executing on any CPU. Do not call with locks held.
-//
-//  returns 0 on success
-//  Unregister will fail if there are any paths open for the type
-extern int HvLpEvent_unregisterHandler( HvLpEvent_Type eventType );
-
-// Open an Lp Event Path for an event type
-//  returns 0 on success
-//  openPath will fail if there is no handler registered for the event type.
-//  The lpIndex specified is the partition index for the target partition
-//  (for VirtualIo, VirtualLan and SessionMgr) other types specify zero) 
-extern int HvLpEvent_openPath( HvLpEvent_Type eventType, HvLpIndex lpIndex );
-
-
-// Close an Lp Event Path for a type and partition
-//  returns 0 on sucess
-extern int HvLpEvent_closePath( HvLpEvent_Type eventType, HvLpIndex lpIndex );
+/* Register a handler for an event type - returns 0 on success */
+extern int HvLpEvent_registerHandler(HvLpEvent_Type eventType,
+		LpEventHandler hdlr);
+
+/*
+ * Unregister a handler for an event type
+ *
+ * This call will sleep until the handler being removed is guaranteed to
+ * be no longer executing on any CPU. Do not call with locks held.
+ *
+ *  returns 0 on success
+ *  Unregister will fail if there are any paths open for the type
+ */
+extern int HvLpEvent_unregisterHandler(HvLpEvent_Type eventType);
+
+/*
+ * Open an Lp Event Path for an event type
+ * returns 0 on success
+ * openPath will fail if there is no handler registered for the event type.
+ * The lpIndex specified is the partition index for the target partition
+ * (for VirtualIo, VirtualLan and SessionMgr) other types specify zero)
+ */
+extern int HvLpEvent_openPath(HvLpEvent_Type eventType, HvLpIndex lpIndex);
+
+/*
+ * Close an Lp Event Path for a type and partition
+ * returns 0 on sucess
+ */
+extern int HvLpEvent_closePath(HvLpEvent_Type eventType, HvLpIndex lpIndex);
 
 #define HvLpEvent_Type_Hypervisor 0
 #define HvLpEvent_Type_MachineFac 1
@@ -141,4 +139,4 @@ extern int HvLpEvent_closePath( HvLpEven
 #define HvLpDma_Rc_InvalidAddress 4
 #define HvLpDma_Rc_InvalidLength 5
 
-#endif // _HVLPEVENT_H
+#endif /* _HVLPEVENT_H */
diff --git a/include/asm-ppc64/iSeries/HvReleaseData.h b/include/asm-ppc64/iSeries/HvReleaseData.h
--- a/include/asm-ppc64/iSeries/HvReleaseData.h
+++ b/include/asm-ppc64/iSeries/HvReleaseData.h
@@ -1,17 +1,17 @@
 /*
  * HvReleaseData.h
  * Copyright (C) 2001  Mike Corrigan IBM Corporation
- * 
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
@@ -19,47 +19,46 @@
 #ifndef _HVRELEASEDATA_H
 #define _HVRELEASEDATA_H
 
-//=============================================================================
-//
-//   This control block contains the critical information about the 
-//   release so that it can be changed in the future (ie, the virtual 
-//   address of the OS's NACA).
-//
+/*
+ * This control block contains the critical information about the
+ * release so that it can be changed in the future (ie, the virtual
+ * address of the OS's NACA).
+ */
 #include <asm/types.h>
 #include <asm/naca.h>
 
-//=============================================================================
-//
-//	When we IPL a secondary partition, we will check if if the 
-//	secondary xMinPlicVrmIndex > the primary xVrmIndex.  
-//	If it is then this tells PLIC that this secondary is not 
-//	supported running on this "old" of a level of PLIC.
-//
-//	Likewise, we will compare the primary xMinSlicVrmIndex to 
-//	the secondary xVrmIndex. 
-//	If the primary xMinSlicVrmDelta > secondary xVrmDelta then we 
-//	know that this PLIC does not support running an OS "that old".
-//
-//=============================================================================
-
-struct	HvReleaseData
-{
-	u32	xDesc;			// Descriptor	"HvRD" ebcdic	x00-x03
-	u16	xSize;			// Size of this control block	x04-x05
-	u16	xVpdAreasPtrOffset;	// Offset in NACA of ItVpdAreas	x06-x07
-	struct  naca_struct * xSlicNacaAddr; // Virt addr of SLIC NACA  x08-x0F
-	u32	xMsNucDataOffset;	// Offset of Linux Mapping Data x10-x13
-	u32	xRsvd1;			// Reserved			x14-x17
-	u16	xTagsMode:1;		// 0 == tags active, 1 == tags inactive
-	u16	xAddressSize:1;		// 0 == 64-bit, 1 == 32-bit
-	u16	xNoSharedProcs:1;	// 0 == shared procs, 1 == no shared
-	u16	xNoHMT:1;		// 0 == allow HMT, 1 == no HMT
-	u16	xRsvd2:12;		// Reserved			x18-x19
-	u16	xVrmIndex;		// VRM Index of OS image	x1A-x1B
-	u16	xMinSupportedPlicVrmIndex;// Min PLIC level  (soft)	x1C-x1D
-	u16	xMinCompatablePlicVrmIndex;// Min PLIC levelP (hard)	x1E-x1F
-	char	xVrmName[12];		// Displayable name  		x20-x2B
-	char	xRsvd3[20];		// Reserved			x2C-x3F
+/*
+ * When we IPL a secondary partition, we will check if if the
+ * secondary xMinPlicVrmIndex > the primary xVrmIndex.
+ * If it is then this tells PLIC that this secondary is not
+ * supported running on this "old" of a level of PLIC.
+ *
+ * Likewise, we will compare the primary xMinSlicVrmIndex to
+ * the secondary xVrmIndex.
+ * If the primary xMinSlicVrmDelta > secondary xVrmDelta then we
+ * know that this PLIC does not support running an OS "that old".
+ */
+
+#define	HVREL_TAGSINACTIVE	0x8000
+#define HVREL_32BIT		0x4000
+#define HVREL_NOSHAREDPROCS	0x2000
+#define HVREL_NOHMT		0x1000
+
+struct HvReleaseData {
+	u32	xDesc;		/* Descriptor "HvRD" ebcdic	x00-x03 */
+	u16	xSize;		/* Size of this control block	x04-x05 */
+	u16	xVpdAreasPtrOffset; /* Offset in NACA of ItVpdAreas x06-x07 */
+	struct  naca_struct	*xSlicNacaAddr; /* Virt addr of SLIC NACA x08-x0F */
+	u32	xMsNucDataOffset; /* Offset of Linux Mapping Data x10-x13 */
+	u32	xRsvd1;		/* Reserved			x14-x17 */
+	u16	xFlags;
+	u16	xVrmIndex;	/* VRM Index of OS image	x1A-x1B */
+	u16	xMinSupportedPlicVrmIndex; /* Min PLIC level  (soft) x1C-x1D */
+	u16	xMinCompatablePlicVrmIndex; /* Min PLIC levelP (hard) x1E-x1F */
+	char	xVrmName[12];	/* Displayable name		x20-x2B */
+	char	xRsvd3[20];	/* Reserved			x2C-x3F */
 };
 
+extern struct HvReleaseData	hvReleaseData;
+
 #endif /* _HVRELEASEDATA_H */
diff --git a/include/asm-ppc64/iSeries/HvTypes.h b/include/asm-ppc64/iSeries/HvTypes.h
--- a/include/asm-ppc64/iSeries/HvTypes.h
+++ b/include/asm-ppc64/iSeries/HvTypes.h
@@ -1,17 +1,17 @@
 /*
  * HvTypes.h
  * Copyright (C) 2001  Mike Corrigan IBM Corporation
- * 
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
@@ -19,74 +19,60 @@
 #ifndef _HVTYPES_H
 #define _HVTYPES_H
 
-//===========================================================================
-//                                                             Header File Id
-// Name______________:  HvTypes.H
-//
-// Description_______:
-//
-//	General typedefs for the hypervisor.
-//
-// Declared Class(es):
-//
-//===========================================================================
+/*
+ * General typedefs for the hypervisor.
+ */
 
 #include <asm/types.h>
 
-//-------------------------------------------------------------------
-// Typedefs
-//-------------------------------------------------------------------
 typedef u8	HvLpIndex;
 typedef u16	HvLpInstanceId;
-typedef u64     HvLpTOD;
-typedef u64     HvLpSystemSerialNum;
-typedef u8      HvLpDeviceSerialNum[12];
-typedef u16     HvLpSanHwSet;
-typedef u16     HvLpBus;
-typedef u16     HvLpBoard;
-typedef u16     HvLpCard;
-typedef u8      HvLpDeviceType[4];
-typedef u8      HvLpDeviceModel[3];
-typedef u64     HvIoToken;
-typedef u8      HvLpName[8];
+typedef u64	HvLpTOD;
+typedef u64	HvLpSystemSerialNum;
+typedef u8	HvLpDeviceSerialNum[12];
+typedef u16	HvLpSanHwSet;
+typedef u16	HvLpBus;
+typedef u16	HvLpBoard;
+typedef u16	HvLpCard;
+typedef u8	HvLpDeviceType[4];
+typedef u8	HvLpDeviceModel[3];
+typedef u64	HvIoToken;
+typedef u8	HvLpName[8];
 typedef u32	HvIoId;
 typedef u64	HvRealMemoryIndex;
-typedef u32     HvLpIndexMap;		// Must hold HvMaxArchitectedLps bits!!!
+typedef u32	HvLpIndexMap;	/* Must hold HVMAXARCHITECTEDLPS bits!!! */
 typedef u16	HvLpVrmIndex;
 typedef u32	HvXmGenerationId;
-typedef u8	HvLpBusPool;			
-typedef u8	HvLpSharedPoolIndex;		
+typedef u8	HvLpBusPool;
+typedef u8	HvLpSharedPoolIndex;
 typedef u16	HvLpSharedProcUnitsX100;
 typedef u8	HvLpVirtualLanIndex;
-typedef u16	HvLpVirtualLanIndexMap;	// Must hold HvMaxArchitectedVirtualLans bits!!!
-typedef u16	HvBusNumber;		// Hypervisor Bus Number
-typedef u8	HvSubBusNumber;		// Hypervisor SubBus Number
-typedef u8	HvAgentId;		// Hypervisor DevFn
-
-
-#define HVMAXARCHITECTEDLPS 32
-#define HVMAXARCHITECTEDVIRTUALLANS 16
-#define HVMAXARCHITECTEDVIRTUALDISKS 32
-#define HVMAXARCHITECTEDVIRTUALCDROMS 8
-#define HVMAXARCHITECTEDVIRTUALTAPES 8
-#define HVCHUNKSIZE 256 * 1024
-#define HVPAGESIZE 4 * 1024
-#define HVLPMINMEGSPRIMARY 256
-#define HVLPMINMEGSSECONDARY 64
-#define HVCHUNKSPERMEG 4
-#define HVPAGESPERMEG 256
-#define HVPAGESPERCHUNK 64
- 
-#define HvMaxArchitectedLps 		((HvLpIndex)HVMAXARCHITECTEDLPS)
-#define HvMaxArchitectedVirtualLans	((HvLpVirtualLanIndex)16)
+typedef u16	HvLpVirtualLanIndexMap;	/* Must hold HVMAXARCHITECTEDVIRTUALLANS bits!!! */
+typedef u16	HvBusNumber;	/* Hypervisor Bus Number */
+typedef u8	HvSubBusNumber;	/* Hypervisor SubBus Number */
+typedef u8	HvAgentId;	/* Hypervisor DevFn */
+
+
+#define HVMAXARCHITECTEDLPS		32
+#define HVMAXARCHITECTEDVIRTUALLANS	16
+#define HVMAXARCHITECTEDVIRTUALDISKS	32
+#define HVMAXARCHITECTEDVIRTUALCDROMS	8
+#define HVMAXARCHITECTEDVIRTUALTAPES	8
+#define HVCHUNKSIZE			(256 * 1024)
+#define HVPAGESIZE			(4 * 1024)
+#define HVLPMINMEGSPRIMARY		256
+#define HVLPMINMEGSSECONDARY		64
+#define HVCHUNKSPERMEG			4
+#define HVPAGESPERMEG			256
+#define HVPAGESPERCHUNK			64
+
 #define HvLpIndexInvalid		((HvLpIndex)0xff)
 
-//--------------------------------------------------------------------
-// Enums for the sub-components under PLIC
-// Used in HvCall  and HvPrimaryCall
-//--------------------------------------------------------------------
-enum   HvCallCompIds
-{
+/*
+ * Enums for the sub-components under PLIC
+ * Used in HvCall  and HvPrimaryCall
+ */
+enum {
 	HvCallCompId = 0,
 	HvCallCpuCtlsCompId = 1,
 	HvCallCfgCompId = 2,
@@ -97,18 +83,18 @@ enum   HvCallCompIds
 	HvCallSmCompId = 7,
 	HvCallSpdCompId = 8,
 	HvCallXmCompId = 9,
-	HvCallRioCompId = 10, 
+	HvCallRioCompId = 10,
 	HvCallRsvd3CompId = 11,
 	HvCallRsvd2CompId = 12,
 	HvCallRsvd1CompId = 13,
 	HvCallMaxCompId = 14,
-	HvPrimaryCallCompId = 0,    
+	HvPrimaryCallCompId = 0,
 	HvPrimaryCallCfgCompId = 1,
-	HvPrimaryCallPciCompId = 2,    
+	HvPrimaryCallPciCompId = 2,
 	HvPrimaryCallSmCompId = 3,
 	HvPrimaryCallSpdCompId = 4,
 	HvPrimaryCallXmCompId = 5,
-	HvPrimaryCallRioCompId = 6, 
+	HvPrimaryCallRioCompId = 6,
 	HvPrimaryCallRsvd7CompId = 7,
 	HvPrimaryCallRsvd6CompId = 8,
 	HvPrimaryCallRsvd5CompId = 9,
@@ -116,7 +102,7 @@ enum   HvCallCompIds
 	HvPrimaryCallRsvd3CompId = 11,
 	HvPrimaryCallRsvd2CompId = 12,
 	HvPrimaryCallRsvd1CompId = 13,
-	HvPrimaryCallMaxCompId = HvCallMaxCompId     
+	HvPrimaryCallMaxCompId = HvCallMaxCompId
 };
 
 struct HvLpBufferList {
diff --git a/include/asm-ppc64/iSeries/IoHriMainStore.h b/include/asm-ppc64/iSeries/IoHriMainStore.h
--- a/include/asm-ppc64/iSeries/IoHriMainStore.h
+++ b/include/asm-ppc64/iSeries/IoHriMainStore.h
@@ -1,17 +1,17 @@
 /*
  * IoHriMainStore.h
  * Copyright (C) 2001  Mike Corrigan IBM Corporation
- * 
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
@@ -21,7 +21,7 @@
 #define _IOHRIMAINSTORE_H
 
 /* Main Store Vpd for Condor,iStar,sStar */
-struct IoHriMainStoreSegment4 {    
+struct IoHriMainStoreSegment4 {
 	u8	msArea0Exists:1;
 	u8	msArea1Exists:1;
 	u8	msArea2Exists:1;
@@ -51,7 +51,7 @@ struct IoHriMainStoreSegment4 {    
 	u8	msArea1HasRiserVpd:1;
 	u8	msArea2HasRiserVpd:1;
 	u8	msArea3HasRiserVpd:1;
-	u8	reserved5:4;	
+	u8	reserved5:4;
 	u8	reserved6;
 	u16	reserved7;
 
@@ -82,8 +82,8 @@ struct IoHriMainStoreVpdFruData {
 };
 
 struct IoHriMainStoreAdrRangeBlock {
-	void *	blockStart      __attribute((packed));
-	void *	blockEnd        __attribute((packed));
+	void	*blockStart      __attribute((packed));
+	void	*blockEnd        __attribute((packed));
 	u32	blockProcChipId __attribute((packed));
 };
 
@@ -102,7 +102,7 @@ struct IoHriMainStoreArea4 {
 	u32	procNodeId			__attribute((packed));
 
 	u32	numAdrRangeBlocks		__attribute((packed));
-	struct IoHriMainStoreAdrRangeBlock xAdrRangeBlock[MaxAreaAdrRangeBlocks] __attribute((packed));
+	struct IoHriMainStoreAdrRangeBlock xAdrRangeBlock[MaxAreaAdrRangeBlocks]	__attribute((packed));
 
 	struct IoHriMainStoreChipInfo1	chipInfo0	__attribute((packed));
 	struct IoHriMainStoreChipInfo1	chipInfo1	__attribute((packed));
@@ -113,17 +113,17 @@ struct IoHriMainStoreArea4 {
 	struct IoHriMainStoreChipInfo1	chipInfo6	__attribute((packed));
 	struct IoHriMainStoreChipInfo1	chipInfo7	__attribute((packed));
 
-	void *   msRamAreaArray			__attribute((packed));
+	void	*msRamAreaArray			__attribute((packed));
 	u32	msRamAreaArrayNumEntries	__attribute((packed));
 	u32	msRamAreaArrayEntrySize		__attribute((packed));
 
 	u32	numaDimmExists			__attribute((packed));
 	u32	numaDimmFunctional		__attribute((packed));
-	void *	numaDimmArray			__attribute((packed));
+	void	*numaDimmArray			__attribute((packed));
 	u32	numaDimmArrayNumEntries		__attribute((packed));
 	u32	numaDimmArrayEntrySize		__attribute((packed));
 
-	struct IoHriMainStoreVpdIdData  idData	__attribute((packed));
+	struct IoHriMainStoreVpdIdData idData	__attribute((packed));
 
 	u64	powerData			__attribute((packed));
 	u64	cardAssemblyPartNum		__attribute((packed));
@@ -143,7 +143,7 @@ struct IoHriMainStoreArea4 {
 };
 
 
-struct IoHriMainStoreSegment5 {    
+struct IoHriMainStoreSegment5 {
 	u16	reserved1;
 	u8	reserved2;
 	u8	msVpdFormat;
@@ -151,17 +151,16 @@ struct IoHriMainStoreSegment5 {    
 	u32	totalMainStore;
 	u64	maxConfiguredMsAdr;
 
-	struct IoHriMainStoreArea4*	msAreaArray;
+	struct IoHriMainStoreArea4	*msAreaArray;
 	u32	msAreaArrayNumEntries;
 	u32	msAreaArrayEntrySize;
 
-	u32	msAreaExists;    
+	u32	msAreaExists;
 	u32	msAreaFunctional;
 
 	u64	reserved3;
 };
 
+extern u64	xMsVpd[];
 
-
-#endif // _IOHRIMAINSTORE_H
-
+#endif	/* _IOHRIMAINSTORE_H */
diff --git a/include/asm-ppc64/iSeries/IoHriProcessorVpd.h b/include/asm-ppc64/iSeries/IoHriProcessorVpd.h
--- a/include/asm-ppc64/iSeries/IoHriProcessorVpd.h
+++ b/include/asm-ppc64/iSeries/IoHriProcessorVpd.h
@@ -1,17 +1,17 @@
 /*
  * IoHriProcessorVpd.h
  * Copyright (C) 2001  Mike Corrigan IBM Corporation
- * 
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
@@ -19,16 +19,12 @@
 #ifndef _IOHRIPROCESSORVPD_H
 #define _IOHRIPROCESSORVPD_H
 
-//===================================================================
-//
-//	This struct maps Processor Vpd that is DMAd to SLIC by CSP 
-//
-
 #include <asm/types.h>
 
-struct IoHriProcessorVpd
-{
-
+/*
+ * This struct maps Processor Vpd that is DMAd to SLIC by CSP
+ */
+struct IoHriProcessorVpd {
 	u8	xFormat;		// VPD format indicator		x00-x00
 	u8	xProcStatus:8;		// Processor State		x01-x01
 	u8	xSecondaryThreadCount;	// Secondary thread cnt		x02-x02
@@ -40,12 +36,12 @@ struct IoHriProcessorVpd
 	u16	xRsvd2;			// Reserved			x06-x07
 	u32	xHwNodeId;		// Hardware node id		x08-x0B
 	u32	xHwProcId;		// Hardware processor id	x0C-x0F
-	
+
 	u32	xTypeNum;		// Card Type/CCIN number	x10-x13
 	u32	xModelNum;		// Model/Feature number		x14-x17
 	u64	xSerialNum;		// Serial number		x18-x1F
-	char xPartNum[12];		// Book Part or FPU number	x20-x2B
-	char xMfgID[4];			// Manufacturing ID		x2C-x2F
+	char	xPartNum[12];		// Book Part or FPU number	x20-x2B
+	char	xMfgID[4];		// Manufacturing ID		x2C-x2F
 
 	u32	xProcFreq;		// Processor Frequency		x30-x33
 	u32	xTimeBaseFreq;		// Time Base Frequency		x34-x37
@@ -71,7 +67,7 @@ struct IoHriProcessorVpd
 	u32	xDataL3CacheSizeKB;	// L3 data cache size in KB	x80-x83
 	u32	xDataL3CacheLineSize;	// L3 data cache block size	x84-x87
 	u64	xRsvd6;			// Reserved			x88-x8F
-   
+
 	u64	xFruLabel;		// Card Location Label		x90-x97
 	u8	xSlotsOnCard;		// Slots on card (0=no slots)	x98-x98
 	u8	xPartLocFlag;		// Location flag (0-pluggable 1-imbedded) x99-x99
@@ -79,10 +75,12 @@ struct IoHriProcessorVpd
 	u8	xSmartCardPortNo;	// Smart card port number	x9C-x9C
 	u8	xRsvd7;			// Reserved			x9D-x9D
 	u16	xFrameIdAndRackUnit;	// Frame ID and rack unit adr	x9E-x9F
-    
+
 	u8	xRsvd8[24];		// Reserved			xA0-xB7
 
-	char xProcSrc[72];		// CSP format SRC		xB8-xFF
+	char	xProcSrc[72];		// CSP format SRC		xB8-xFF
 };
 
+extern struct IoHriProcessorVpd	xIoHriProcessorVpd[];
+
 #endif /* _IOHRIPROCESSORVPD_H */
diff --git a/include/asm-ppc64/iSeries/ItExtVpdPanel.h b/include/asm-ppc64/iSeries/ItExtVpdPanel.h
--- a/include/asm-ppc64/iSeries/ItExtVpdPanel.h
+++ b/include/asm-ppc64/iSeries/ItExtVpdPanel.h
@@ -1,17 +1,17 @@
 /*
  * ItExtVpdPanel.h
  * Copyright (C) 2002  Dave Boutcher IBM Corporation
- * 
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
@@ -20,39 +20,33 @@
 #define _ITEXTVPDPANEL_H
 
 /*
- *
- *	This struct maps the panel information 
+ *	This struct maps the panel information
  *
  * Warning:
  *	This data must match the architecture for the panel information
- *
  */
 
-
-/*-------------------------------------------------------------------
- * Standard Includes
- *------------------------------------------------------------------- 
-*/
 #include <asm/types.h>
 
-struct ItExtVpdPanel
-{
-  // Definition of the Extended Vpd On Panel Data Area
-  char                      systemSerial[8];
-  char                      mfgID[4];
-  char                      reserved1[24];
-  char                      machineType[4];
-  char                      systemID[6];
-  char                      somUniqueCnt[4];
-  char                      serialNumberCount;
-  char                      reserved2[7];
-  u16                       bbu3;
-  u16                       bbu2;
-  u16                       bbu1;
-  char                      xLocationLabel[8];
-  u8                        xRsvd1[6];
-  u16                       xFrameId;
-  u8                        xRsvd2[48];
+struct ItExtVpdPanel {
+	/* Definition of the Extended Vpd On Panel Data Area */
+	char	systemSerial[8];
+	char	mfgID[4];
+	char	reserved1[24];
+	char	machineType[4];
+	char	systemID[6];
+	char	somUniqueCnt[4];
+	char	serialNumberCount;
+	char	reserved2[7];
+	u16	bbu3;
+	u16	bbu2;
+	u16	bbu1;
+	char	xLocationLabel[8];
+	u8	xRsvd1[6];
+	u16	xFrameId;
+	u8	xRsvd2[48];
 };
 
-#endif /* _ITEXTVPDPANEL_H  */
+extern struct ItExtVpdPanel	xItExtVpdPanel;
+
+#endif /* _ITEXTVPDPANEL_H */
diff --git a/include/asm-ppc64/iSeries/ItIplParmsReal.h b/include/asm-ppc64/iSeries/ItIplParmsReal.h
--- a/include/asm-ppc64/iSeries/ItIplParmsReal.h
+++ b/include/asm-ppc64/iSeries/ItIplParmsReal.h
@@ -1,17 +1,17 @@
 /*
  * ItIplParmsReal.h
  * Copyright (C) 2001  Mike Corrigan IBM Corporation
- * 
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
@@ -19,58 +19,53 @@
 #ifndef _ITIPLPARMSREAL_H
 #define _ITIPLPARMSREAL_H
 
-//==============================================================================
-//
-//	This struct maps the IPL Parameters DMA'd from the SP.                  
-//
-// Warning:
-//	This data must map in exactly 64 bytes and match the architecture for
-//	the IPL parms
-//
-//=============================================================================
-
+/*
+ *	This struct maps the IPL Parameters DMA'd from the SP.
+ *
+ * Warning:
+ *	This data must map in exactly 64 bytes and match the architecture for
+ *	the IPL parms
+ */
 
-//-------------------------------------------------------------------
-// Standard Includes
-//-------------------------------------------------------------------
 #include <asm/types.h>
 
-struct ItIplParmsReal
-{
-	u8	xFormat;		// Defines format of IplParms		x00-x00
-	u8	xRsvd01:6;		// Reserved				x01-x01
-	u8	xAlternateSearch:1;	// Alternate search indicator		...
-	u8	xUaSupplied:1;		// UA Supplied on programmed IPL	...
-	u8	xLsUaFormat;		// Format byte for UA			x02-x02
-	u8	xRsvd02;		// Reserved				x03-x03
-	u32	xLsUa;			// LS UA				x04-x07
-	u32	xUnusedLsLid;		// First OS LID to load			x08-x0B
-	u16	xLsBusNumber;		// LS Bus Number			x0C-x0D
-	u8	xLsCardAdr;		// LS Card Address			x0E-x0E
-	u8	xLsBoardAdr;		// LS Board Address			x0F-x0F
-	u32	xRsvd03;		// Reserved				x10-x13
-	u8	xSpcnPresent:1;		// SPCN present				x14-x14
-	u8	xCpmPresent:1;		// CPM present				...
-	u8	xRsvd04:6;		// Reserved				...
-	u8	xRsvd05:4;		// Reserved				x15-x15
-	u8	xKeyLock:4;		// Keylock setting			...
-	u8	xRsvd06:6;		// Reserved				x16-x16
-	u8	xIplMode:2;		// Ipl mode (A|B|C|D)			...
-	u8	xHwIplType;		// Fast v slow v slow EC HW IPL		x17-x17
-	u16	xCpmEnabledIpl:1;	// CPM in effect when IPL initiated	x18-x19
-	u16	xPowerOnResetIpl:1;	// Indicate POR condition		...
-	u16	xMainStorePreserved:1;	// Main Storage is preserved		...
-	u16	xRsvd07:13;		// Reserved				...
-	u16	xIplSource:16;		// Ipl source				x1A-x1B
-	u8	xIplReason:8;		// Reason for this IPL			x1C-x1C
-	u8	xRsvd08;		// Reserved				x1D-x1D
-	u16	xRsvd09;		// Reserved				x1E-x1F
-	u16	xSysBoxType;		// System Box Type			x20-x21
-	u16	xSysProcType;		// System Processor Type		x22-x23
-	u32	xRsvd10;		// Reserved				x24-x27
-	u64	xRsvd11;		// Reserved				x28-x2F
-	u64	xRsvd12;		// Reserved				x30-x37
-	u64	xRsvd13;		// Reserved				x38-x3F
+struct ItIplParmsReal {
+	u8	xFormat;		// Defines format of IplParms	x00-x00
+	u8	xRsvd01:6;		// Reserved			x01-x01
+	u8	xAlternateSearch:1;	// Alternate search indicator	...
+	u8	xUaSupplied:1;		// UA Supplied on programmed IPL...
+	u8	xLsUaFormat;		// Format byte for UA		x02-x02
+	u8	xRsvd02;		// Reserved			x03-x03
+	u32	xLsUa;			// LS UA			x04-x07
+	u32	xUnusedLsLid;		// First OS LID to load		x08-x0B
+	u16	xLsBusNumber;		// LS Bus Number		x0C-x0D
+	u8	xLsCardAdr;		// LS Card Address		x0E-x0E
+	u8	xLsBoardAdr;		// LS Board Address		x0F-x0F
+	u32	xRsvd03;		// Reserved			x10-x13
+	u8	xSpcnPresent:1;		// SPCN present			x14-x14
+	u8	xCpmPresent:1;		// CPM present			...
+	u8	xRsvd04:6;		// Reserved			...
+	u8	xRsvd05:4;		// Reserved			x15-x15
+	u8	xKeyLock:4;		// Keylock setting		...
+	u8	xRsvd06:6;		// Reserved			x16-x16
+	u8	xIplMode:2;		// Ipl mode (A|B|C|D)		...
+	u8	xHwIplType;		// Fast v slow v slow EC HW IPL	x17-x17
+	u16	xCpmEnabledIpl:1;	// CPM in effect when IPL initiatedx18-x19
+	u16	xPowerOnResetIpl:1;	// Indicate POR condition	...
+	u16	xMainStorePreserved:1;	// Main Storage is preserved	...
+	u16	xRsvd07:13;		// Reserved			...
+	u16	xIplSource:16;		// Ipl source			x1A-x1B
+	u8	xIplReason:8;		// Reason for this IPL		x1C-x1C
+	u8	xRsvd08;		// Reserved			x1D-x1D
+	u16	xRsvd09;		// Reserved			x1E-x1F
+	u16	xSysBoxType;		// System Box Type		x20-x21
+	u16	xSysProcType;		// System Processor Type	x22-x23
+	u32	xRsvd10;		// Reserved			x24-x27
+	u64	xRsvd11;		// Reserved			x28-x2F
+	u64	xRsvd12;		// Reserved			x30-x37
+	u64	xRsvd13;		// Reserved			x38-x3F
 };
 
+extern struct ItIplParmsReal	xItIplParmsReal;
+
 #endif /* _ITIPLPARMSREAL_H */
diff --git a/include/asm-ppc64/iSeries/ItLpNaca.h b/include/asm-ppc64/iSeries/ItLpNaca.h
--- a/include/asm-ppc64/iSeries/ItLpNaca.h
+++ b/include/asm-ppc64/iSeries/ItLpNaca.h
@@ -1,17 +1,17 @@
 /*
  * ItLpNaca.h
  * Copyright (C) 2001  Mike Corrigan IBM Corporation
- * 
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
@@ -19,18 +19,15 @@
 #ifndef _ITLPNACA_H
 #define _ITLPNACA_H
 
-//=============================================================================
-//
-//	This control block contains the data that is shared between the
-//	hypervisor (PLIC) and the OS.
-//
-//=============================================================================
-
-struct ItLpNaca
-{
-//=============================================================================
+#include <linux/types.h>
+
+/*
+ *	This control block contains the data that is shared between the
+ *	hypervisor (PLIC) and the OS.
+ */
+
+struct ItLpNaca {
 // CACHE_LINE_1 0x0000 - 0x007F Contains read-only data
-//=============================================================================
 	u32	xDesc;			// Eye catcher			x00-x03
 	u16	xSize;			// Size of this class		x04-x05
 	u16	xIntHdlrOffset;		// Offset to IntHdlr array	x06-x07
@@ -59,30 +56,25 @@ struct ItLpNaca
 	u64	xLoadAreaAddr;		// ER address of load area	x28-x2F
 	u32	xLoadAreaChunks;	// Chunks for the load area	x30-x33
 	u32	xPaseSysCallCRMask;	// Mask used to test CR before  x34-x37
-	// doing an ASR switch on PASE
-	// system call.
-	u64	xSlicSegmentTablePtr;   // Pointer to Slic seg table.   x38-x3f
-	u8	xRsvd1_4[64];		//         			x40-x7F 
-   
-//=============================================================================
+					// doing an ASR switch on PASE
+					// system call.
+	u64	xSlicSegmentTablePtr;	// Pointer to Slic seg table.   x38-x3f
+	u8	xRsvd1_4[64];		//				x40-x7F
+
 // CACHE_LINE_2 0x0080 - 0x00FF Contains local read-write data
-//=============================================================================
 	u8	xRsvd2_0[128];		// Reserved			x00-x7F
 
-//=============================================================================
 // CACHE_LINE_3-6 0x0100 - 0x02FF Contains LP Queue indicators
-// NB: Padding required to keep xInterrruptHdlr at x300 which is required 
+// NB: Padding required to keep xInterrruptHdlr at x300 which is required
 // for v4r4 PLIC.
-//=============================================================================
 	u8	xOldLpQueue[128];	// LP Queue needed for v4r4	100-17F
 	u8	xRsvd3_0[384];		// Reserved			180-2FF
-//=============================================================================
+
 // CACHE_LINE_7-8 0x0300 - 0x03FF Contains the address of the OS interrupt
 //  handlers
-//=============================================================================
 	u64	xInterruptHdlr[32];	// Interrupt handlers		300-x3FF
 };
 
-//=============================================================================
+extern struct ItLpNaca		itLpNaca;
 
 #endif /* _ITLPNACA_H */
diff --git a/include/asm-ppc64/iSeries/ItLpQueue.h b/include/asm-ppc64/iSeries/ItLpQueue.h
--- a/include/asm-ppc64/iSeries/ItLpQueue.h
+++ b/include/asm-ppc64/iSeries/ItLpQueue.h
@@ -1,17 +1,17 @@
 /*
  * ItLpQueue.h
  * Copyright (C) 2001  Mike Corrigan IBM Corporation
- * 
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
@@ -19,74 +19,63 @@
 #ifndef _ITLPQUEUE_H
 #define _ITLPQUEUE_H
 
-//=============================================================================
-//
-//	This control block defines the simple LP queue structure that is 
-//	shared between the hypervisor (PLIC) and the OS in order to send 
-//	events to an LP.  
-//    
+/*
+ *	This control block defines the simple LP queue structure that is
+ *	shared between the hypervisor (PLIC) and the OS in order to send
+ *	events to an LP.
+ */
 
 #include <asm/types.h>
 #include <asm/ptrace.h>
 
 struct HvLpEvent;
 
-#define ITMaxLpQueues 8
+#define ITMaxLpQueues	8
 
 #define NotUsed		0	// Queue will not be used by PLIC
 #define DedicatedIo	1	// Queue dedicated to IO processor specified
 #define DedicatedLp	2	// Queue dedicated to LP specified
 #define Shared		3	// Queue shared for both IO and LP
 
-#define LpEventStackSize 4096
-#define LpEventMaxSize   256
-#define LpEventAlign	 64
-
-struct ItLpQueue
-{
-//
-//  The xSlicCurEventPtr is the pointer to the next event stack entry that will
-//  become valid.  The OS must peek at this entry to determine if it is valid.
-//  PLIC will set the valid indicator as the very last store into that entry.
-//
-//  When the OS has completed processing of the event then it will mark the event
-//  as invalid so that PLIC knows it can store into that event location again.
-//
-// If the event stack fills and there are overflow events, then PLIC will set 
-// the xPlicOverflowIntPending flag in which case the OS will have to fetch the 
-// additional LP events once they have drained the event stack.
-//
-// The first 16-bytes are known by both the OS and PLIC.  The remainder of the
-// cache line is for use by the OS.
-//
-//=============================================================================
+#define LpEventStackSize	4096
+#define LpEventMaxSize		256
+#define LpEventAlign		64
+
+struct hvlpevent_queue {
+/*
+ * The xSlicCurEventPtr is the pointer to the next event stack entry
+ * that will become valid.  The OS must peek at this entry to determine
+ * if it is valid.  PLIC will set the valid indicator as the very last
+ * store into that entry.
+ *
+ * When the OS has completed processing of the event then it will mark
+ * the event as invalid so that PLIC knows it can store into that event
+ * location again.
+ *
+ * If the event stack fills and there are overflow events, then PLIC
+ * will set the xPlicOverflowIntPending flag in which case the OS will
+ * have to fetch the additional LP events once they have drained the
+ * event stack.
+ *
+ * The first 16-bytes are known by both the OS and PLIC.  The remainder
+ * of the cache line is for use by the OS.
+ */
 	u8	xPlicOverflowIntPending;// 0x00 Overflow events are pending
 	u8	xPlicStatus;		// 0x01 DedicatedIo or DedicatedLp or NotUsed
 	u16	xSlicLogicalProcIndex;	// 0x02 Logical Proc Index for correlation
 	u8	xPlicRsvd[12];		// 0x04
-	char*	xSlicCurEventPtr;	// 0x10
-	char*	xSlicLastValidEventPtr;	// 0x18
-	char*	xSlicEventStackPtr;	// 0x20
+	char	*xSlicCurEventPtr;	// 0x10
+	char	*xSlicLastValidEventPtr; // 0x18
+	char	*xSlicEventStackPtr;	// 0x20
 	u8	xIndex;			// 0x28 unique sequential index.
 	u8	xSlicRsvd[3];		// 0x29-2b
-	u32	xInUseWord;		// 0x2C
-	u64	xLpIntCount;		// 0x30 Total Lp Int msgs processed
-	u64	xLpIntCountByType[9];	// 0x38-0x7F Event counts by type
+	spinlock_t	lock;
 };
 
-extern struct ItLpQueue xItLpQueue;
+extern struct hvlpevent_queue hvlpevent_queue;
 
-extern struct HvLpEvent * ItLpQueue_getNextLpEvent( struct ItLpQueue * );
-extern int ItLpQueue_isLpIntPending( struct ItLpQueue * ); 
-extern unsigned ItLpQueue_process( struct ItLpQueue *, struct pt_regs * );
-extern void ItLpQueue_clearValid( struct HvLpEvent * );
-
-static __inline__ void process_iSeries_events( void )
-{
-	__asm__ __volatile__ (
-	"	li	0,0x5555	\n\
-		sc"
-	: : : "r0", "r3" );	
-}
+extern int hvlpevent_is_pending(void);
+extern void process_hvlpevents(struct pt_regs *);
+extern void setup_hvlpevent_queue(void);
 
 #endif /* _ITLPQUEUE_H */
diff --git a/include/asm-ppc64/iSeries/ItLpRegSave.h b/include/asm-ppc64/iSeries/ItLpRegSave.h
--- a/include/asm-ppc64/iSeries/ItLpRegSave.h
+++ b/include/asm-ppc64/iSeries/ItLpRegSave.h
@@ -1,17 +1,17 @@
 /*
  * ItLpRegSave.h
  * Copyright (C) 2001  Mike Corrigan IBM Corporation
- * 
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
@@ -19,33 +19,30 @@
 #ifndef _ITLPREGSAVE_H
 #define _ITLPREGSAVE_H
 
-//=====================================================================================
-//
-//	This control block contains the data that is shared between PLIC
-//	and the OS
-//    
-//
+/*
+ * This control block contains the data that is shared between PLIC
+ * and the OS
+ */
 
-struct ItLpRegSave
-{
+struct ItLpRegSave {
 	u32	xDesc;		// Eye catcher  "LpRS" ebcdic	000-003
 	u16	xSize;		// Size of this class		004-005
 	u8	xInUse;         // Area is live                 006-007
-	u8	xRsvd1[9]; 	// Reserved			007-00F
+	u8	xRsvd1[9];	// Reserved			007-00F
 
-	u8      xFixedRegSave[352]; // Fixed Register Save Area 010-16F 
+	u8      xFixedRegSave[352]; // Fixed Register Save Area 010-16F
 	u32	xCTRL;		// Control Register		170-173
-	u32	xDEC;		// Decrementer			174-177    
+	u32	xDEC;		// Decrementer			174-177
 	u32	xFPSCR;		// FP Status and Control Reg	178-17B
 	u32	xPVR;		// Processor Version Number	17C-17F
-    
+
 	u64	xMMCR0;		// Monitor Mode Control Reg 0	180-187
 	u32	xPMC1;		// Perf Monitor Counter 1	188-18B
 	u32	xPMC2;		// Perf Monitor Counter 2	18C-18F
 	u32	xPMC3;		// Perf Monitor Counter 3	190-193
 	u32	xPMC4;		// Perf Monitor Counter 4	194-197
 	u32	xPIR;		// Processor ID Reg		198-19B
-    
+
 	u32	xMMCR1;		// Monitor Mode Control Reg 1	19C-19F
 	u32	xMMCRA;		// Monitor Mode Control Reg A	1A0-1A3
 	u32	xPMC5;		// Perf Monitor Counter 5	1A4-1A7
@@ -57,17 +54,17 @@ struct ItLpRegSave
 	u32	xRsvd;          // Reserved                     1BC-1BF
 
 	u64	xACCR;		// Address Compare Control Reg	1C0-1C7
-	u64	xIMR;		// Instruction Match Register	1C8-1CF    
-	u64	xSDR1;		// Storage Description Reg 1	1D0-1D7    
+	u64	xIMR;		// Instruction Match Register	1C8-1CF
+	u64	xSDR1;		// Storage Description Reg 1	1D0-1D7
 	u64	xSPRG0;		// Special Purpose Reg General0	1D8-1DF
 	u64	xSPRG1;		// Special Purpose Reg General1	1E0-1E7
 	u64	xSPRG2;		// Special Purpose Reg General2	1E8-1EF
 	u64	xSPRG3;		// Special Purpose Reg General3	1F0-1F7
 	u64	xTB;		// Time Base Register		1F8-1FF
-   
+
 	u64	xFPR[32];	// Floating Point Registers	200-2FF
 
-	u64	xMSR;		// Machine State Register  	300-307
+	u64	xMSR;		// Machine State Register	300-307
 	u64	xNIA;		// Next Instruction Address	308-30F
 
 	u64	xDABR;		// Data Address Breakpoint Reg	310-317
@@ -76,8 +73,8 @@ struct ItLpRegSave
 	u64	xHID0;		// HW Implementation Dependent0	320-327
 
 	u64	xHID4;		// HW Implementation Dependent4	328-32F
-	u64	xSCOMd;		// SCON Data Reg (SPRG4)       	330-337
-	u64	xSCOMc;		// SCON Command Reg (SPRG5)    	338-33F
+	u64	xSCOMd;		// SCON Data Reg (SPRG4)	330-337
+	u64	xSCOMc;		// SCON Command Reg (SPRG5)	338-33F
 	u64	xSDAR;		// Sample Data Address Register	340-347
 	u64	xSIAR;		// Sample Inst Address Register	348-34F
 
diff --git a/include/asm-ppc64/iSeries/ItSpCommArea.h b/include/asm-ppc64/iSeries/ItSpCommArea.h
--- a/include/asm-ppc64/iSeries/ItSpCommArea.h
+++ b/include/asm-ppc64/iSeries/ItSpCommArea.h
@@ -1,29 +1,27 @@
 /*
  * ItSpCommArea.h
  * Copyright (C) 2001  Mike Corrigan IBM Corporation
- * 
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  */
 
-
 #ifndef _ITSPCOMMAREA_H
 #define _ITSPCOMMAREA_H
 
 
-struct SpCommArea
-{
+struct SpCommArea {
 	u32	xDesc;			// Descriptor (only in new formats)	000-003
 	u8	xFormat;		// Format (only in new formats)		004-004
 	u8	xRsvd1[11];		// Reserved				005-00F
diff --git a/include/asm-ppc64/iSeries/ItVpdAreas.h b/include/asm-ppc64/iSeries/ItVpdAreas.h
--- a/include/asm-ppc64/iSeries/ItVpdAreas.h
+++ b/include/asm-ppc64/iSeries/ItVpdAreas.h
@@ -1,17 +1,17 @@
 /*
  * ItVpdAreas.h
  * Copyright (C) 2001  Mike Corrigan IBM Corporation
- * 
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
@@ -19,78 +19,71 @@
 #ifndef _ITVPDAREAS_H
 #define _ITVPDAREAS_H
 
-//=====================================================================================
-//
-//      This file defines the address and length of all of the VPD area passed to
-//	the OS from PLIC (most of which start from the SP).
-//
+/*
+ * This file defines the address and length of all of the VPD area passed to
+ * the OS from PLIC (most of which start from the SP).
+ */
 
 #include <asm/types.h>
 
-// VPD Entry index is carved in stone - cannot be changed (easily).
-#define ItVpdCecVpd				   0
-#define ItVpdDynamicSpace			   1
-#define ItVpdExtVpd				   2
-#define ItVpdExtVpdOnPanel			   3
-#define ItVpdFirstPaca				   4
-#define ItVpdIoVpd				   5
-#define ItVpdIplParms				   6
-#define ItVpdMsVpd				   7
-#define ItVpdPanelVpd				   8
-#define ItVpdLpNaca				   9
-#define ItVpdBackplaneAndMaybeClockCardVpd        10 
-#define ItVpdRecoveryLogBuffer		          11
-#define ItVpdSpCommArea				  12
-#define ItVpdSpLogBuffer			  13
-#define ItVpdSpLogBufferSave			  14
-#define ItVpdSpCardVpd				  15
-#define ItVpdFirstProcVpd			  16	
-#define ItVpdApModelVpd				  17
-#define ItVpdClockCardVpd			  18
-#define ItVpdBusExtCardVpd			  19
-#define ItVpdProcCapacityVpd			  20
-#define ItVpdInteractiveCapacityVpd		  21
-#define ItVpdFirstSlotLabel			  22
-#define ItVpdFirstLpQueue			  23
-#define ItVpdFirstL3CacheVpd			  24	
-#define ItVpdFirstProcFruVpd			  25
-
-#define ItVpdMaxEntries				  26
-
-
-#define ItDmaMaxEntries				  10
-
-#define ItVpdAreasMaxSlotLabels		 192 
-
-
-struct SlicVpdAdrs {
-	u32	pad1;
-	void *  vpdAddr;
+/* VPD Entry index is carved in stone - cannot be changed (easily). */
+#define ItVpdCecVpd				0
+#define ItVpdDynamicSpace			1
+#define ItVpdExtVpd				2
+#define ItVpdExtVpdOnPanel			3
+#define ItVpdFirstPaca				4
+#define ItVpdIoVpd				5
+#define ItVpdIplParms				6
+#define ItVpdMsVpd				7
+#define ItVpdPanelVpd				8
+#define ItVpdLpNaca				9
+#define ItVpdBackplaneAndMaybeClockCardVpd	10
+#define ItVpdRecoveryLogBuffer			11
+#define ItVpdSpCommArea				12
+#define ItVpdSpLogBuffer			13
+#define ItVpdSpLogBufferSave			14
+#define ItVpdSpCardVpd				15
+#define ItVpdFirstProcVpd			16
+#define ItVpdApModelVpd				17
+#define ItVpdClockCardVpd			18
+#define ItVpdBusExtCardVpd			19
+#define ItVpdProcCapacityVpd			20
+#define ItVpdInteractiveCapacityVpd		21
+#define ItVpdFirstSlotLabel			22
+#define ItVpdFirstLpQueue			23
+#define ItVpdFirstL3CacheVpd			24
+#define ItVpdFirstProcFruVpd			25
+
+#define ItVpdMaxEntries				26
+
+#define ItDmaMaxEntries				10
+
+#define ItVpdAreasMaxSlotLabels			192
+
+
+struct ItVpdAreas {
+	u32	xSlicDesc;		// Descriptor			000-003
+	u16	xSlicSize;		// Size of this control block	004-005
+	u16	xPlicAdjustVpdLens:1;	// Flag to indicate new interface006-007
+	u16	xRsvd1:15;		// Reserved bits		...
+	u16	xSlicVpdEntries;	// Number of VPD entries	008-009
+	u16	xSlicDmaEntries;	// Number of DMA entries	00A-00B
+	u16	xSlicMaxLogicalProcs;	// Maximum logical processors	00C-00D
+	u16	xSlicMaxPhysicalProcs;	// Maximum physical processors	00E-00F
+	u16	xSlicDmaToksOffset;	// Offset into this of array	010-011
+	u16	xSlicVpdAdrsOffset;	// Offset into this of array	012-013
+	u16	xSlicDmaLensOffset;	// Offset into this of array	014-015
+	u16	xSlicVpdLensOffset;	// Offset into this of array	016-017
+	u16	xSlicMaxSlotLabels;	// Maximum number of slot labels018-019
+	u16	xSlicMaxLpQueues;	// Maximum number of LP Queues	01A-01B
+	u8	xRsvd2[4];		// Reserved			01C-01F
+	u64	xRsvd3[12];		// Reserved			020-07F
+	u32	xPlicDmaLens[ItDmaMaxEntries];// Array of DMA lengths	080-0A7
+	u32	xPlicDmaToks[ItDmaMaxEntries];// Array of DMA tokens	0A8-0CF
+	u32	xSlicVpdLens[ItVpdMaxEntries];// Array of VPD lengths	0D0-12F
+	void	*xSlicVpdAdrs[ItVpdMaxEntries];// Array of VPD buffers	130-1EF
 };
 
-
-struct	ItVpdAreas
-{
-	u32	xSlicDesc;		// Descriptor				000-003
-	u16	xSlicSize;		// Size of this control block		004-005
-	u16	xPlicAdjustVpdLens:1;	// Flag to indicate new interface 	006-007
-	u16	xRsvd1:15;		// Reserved bits			...
-	u16	xSlicVpdEntries;	// Number of VPD entries		008-009
-	u16	xSlicDmaEntries;	// Number of DMA entries		00A-00B
-	u16	xSlicMaxLogicalProcs;	// Maximum logical processors		00C-00D
-	u16	xSlicMaxPhysicalProcs;	// Maximum physical processors		00E-00F
-	u16	xSlicDmaToksOffset;	// Offset into this of array		010-011
-	u16	xSlicVpdAdrsOffset;	// Offset into this of array		012-013
-	u16	xSlicDmaLensOffset;	// Offset into this of array		014-015
-	u16	xSlicVpdLensOffset;	// Offset into this of array		016-017
-	u16	xSlicMaxSlotLabels;	// Maximum number of slot labels	018-019
-	u16	xSlicMaxLpQueues;	// Maximum number of LP Queues		01A-01B
-	u8	xRsvd2[4];		// Reserved				01C-01F
-	u64	xRsvd3[12];		// Reserved				020-07F
-	u32	xPlicDmaLens[ItDmaMaxEntries];// Array of DMA lengths		080-0A7
-	u32	xPlicDmaToks[ItDmaMaxEntries];// Array of DMA tokens		0A8-0CF
-	u32	xSlicVpdLens[ItVpdMaxEntries];// Array of VPD lengths		0D0-12F
-	void * xSlicVpdAdrs[ItVpdMaxEntries];// Array of VPD buffers	130-1EF
-};
+extern struct ItVpdAreas	itVpdAreas;
 
 #endif /* _ITVPDAREAS_H */
diff --git a/include/asm-ppc64/iSeries/LparData.h b/include/asm-ppc64/iSeries/LparData.h
deleted file mode 100644
--- a/include/asm-ppc64/iSeries/LparData.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * LparData.h
- * Copyright (C) 2001  Mike Corrigan IBM Corporation
- * 
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- */
-
-#ifndef _LPARDATA_H
-#define _LPARDATA_H
-
-#include <asm/types.h>
-#include <asm/page.h>
-#include <asm/abs_addr.h>
-
-#include <asm/iSeries/ItLpNaca.h>
-#include <asm/iSeries/ItLpRegSave.h>
-#include <asm/iSeries/HvReleaseData.h>
-#include <asm/iSeries/LparMap.h>
-#include <asm/iSeries/ItVpdAreas.h>
-#include <asm/iSeries/ItIplParmsReal.h>
-#include <asm/iSeries/ItExtVpdPanel.h>
-#include <asm/iSeries/ItLpQueue.h>
-#include <asm/iSeries/IoHriProcessorVpd.h>
-
-extern struct LparMap	xLparMap;
-extern struct HvReleaseData hvReleaseData;
-extern struct ItLpNaca	itLpNaca;
-extern struct ItIplParmsReal xItIplParmsReal;
-extern struct ItExtVpdPanel xItExtVpdPanel;
-extern struct IoHriProcessorVpd xIoHriProcessorVpd[];
-extern struct ItLpQueue xItLpQueue;
-extern struct ItVpdAreas itVpdAreas;
-extern u64    xMsVpd[];
-extern struct msChunks msChunks;
-
-
-#endif /* _LPARDATA_H */
diff --git a/include/asm-ppc64/iSeries/LparMap.h b/include/asm-ppc64/iSeries/LparMap.h
--- a/include/asm-ppc64/iSeries/LparMap.h
+++ b/include/asm-ppc64/iSeries/LparMap.h
@@ -1,17 +1,17 @@
 /*
  * LparMap.h
  * Copyright (C) 2001  Mike Corrigan IBM Corporation
- * 
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
@@ -19,15 +19,18 @@
 #ifndef _LPARMAP_H
 #define _LPARMAP_H
 
+#ifndef __ASSEMBLY__
+
 #include <asm/types.h>
 
-/* The iSeries hypervisor will set up mapping for one or more 
+/*
+ * The iSeries hypervisor will set up mapping for one or more
  * ESID/VSID pairs (in SLB/segment registers) and will set up
  * mappings of one or more ranges of pages to VAs.
  * We will have the hypervisor set up the ESID->VSID mapping
  * for the four kernel segments (C-F).  With shared processors,
  * the hypervisor will clear all segment registers and reload
- * these four whenever the processor is switched from one 
+ * these four whenever the processor is switched from one
  * partition to another.
  */
 
@@ -38,30 +41,43 @@
  * need to be located within the load area (if the total partition size
  * is 64 MB), but cannot be mapped.  Typically, this should specify
  * to map half (32 MB) of the load area.
- * 
- * The hypervisor will set up page table entries for the number of 
+ *
+ * The hypervisor will set up page table entries for the number of
  * pages specified.
  *
  * In 32-bit mode, the hypervisor will load all four of the
- * segment registers (identified by the low-order four bits of the 
+ * segment registers (identified by the low-order four bits of the
  * Esid field.  In 64-bit mode, the hypervisor will load one SLB
  * entry to map the Esid to the Vsid.
 */
 
-// Hypervisor initially maps 32MB of the load area 
-#define HvPagesToMap 8192
+#define HvEsidsToMap	2
+#define HvRangesToMap	1
+
+/* Hypervisor initially maps 32MB of the load area */
+#define HvPagesToMap	8192
 
-struct LparMap
-{
-	u64	  xNumberEsids;		// Number of ESID/VSID pairs (1)
-	u64	  xNumberRanges;	// Number of VA ranges to map (1)
-	u64	  xSegmentTableOffs;	// Page number within load area of seg table (0)
-	u64	  xRsvd[5];		// Reserved (0)
-	u64	  xKernelEsid;  	// Esid used to map kernel load (0x0C00000000)	
-	u64	  xKernelVsid;		// Vsid used to map kernel load (0x0C00000000)
-	u64	  xPages;		// Number of pages to be mapped	(8192)
-	u64	  xOffset;		// Offset from start of load area (0)
-	u64	  xVPN;			// Virtual Page Number (0x000C000000000000)
+struct LparMap {
+	u64	xNumberEsids;	// Number of ESID/VSID pairs
+	u64	xNumberRanges;	// Number of VA ranges to map
+	u64	xSegmentTableOffs; // Page number within load area of seg table
+	u64	xRsvd[5];
+	struct {
+		u64	xKernelEsid;	// Esid used to map kernel load
+		u64	xKernelVsid;	// Vsid used to map kernel load
+	} xEsids[HvEsidsToMap];
+	struct {
+		u64	xPages;		// Number of pages to be mapped
+		u64	xOffset;	// Offset from start of load area
+		u64	xVPN;		// Virtual Page Number
+	} xRanges[HvRangesToMap];
 };
 
+extern const struct LparMap	xLparMap;
+
+#endif /* __ASSEMBLY__ */
+
+/* the fixed address where the LparMap exists */
+#define LPARMAP_PHYS		0x7000
+
 #endif /* _LPARMAP_H */
diff --git a/include/asm-ppc64/iSeries/XmPciLpEvent.h b/include/asm-ppc64/iSeries/XmPciLpEvent.h
deleted file mode 100644
--- a/include/asm-ppc64/iSeries/XmPciLpEvent.h
+++ /dev/null
@@ -1,18 +0,0 @@
-
-#ifndef	__XMPCILPEVENT_H__
-#define	__XMPCILPEVENT_H__
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-int XmPciLpEvent_init(void);
-void ppc_irq_dispatch_handler(struct pt_regs *regs, int irq);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __XMPCILPEVENT_H__ */
diff --git a/include/asm-ppc64/iSeries/iSeries_io.h b/include/asm-ppc64/iSeries/iSeries_io.h
--- a/include/asm-ppc64/iSeries/iSeries_io.h
+++ b/include/asm-ppc64/iSeries/iSeries_io.h
@@ -5,32 +5,33 @@
 
 #ifdef CONFIG_PPC_ISERIES
 #include <linux/types.h>
-/************************************************************************/
-/* File iSeries_io.h created by Allan Trautman on Thu Dec 28 2000.      */
-/************************************************************************/
-/* Remaps the io.h for the iSeries Io                                   */
-/* Copyright (C) 20yy  Allan H Trautman, IBM Corporation                */
-/*                                                                      */
-/* This program is free software; you can redistribute it and/or modify */
-/* it under the terms of the GNU General Public License as published by */
-/* the Free Software Foundation; either version 2 of the License, or    */
-/* (at your option) any later version.                                  */
-/*                                                                      */
-/* This program is distributed in the hope that it will be useful,      */ 
-/* but WITHOUT ANY WARRANTY; without even the implied warranty of       */
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        */
-/* GNU General Public License for more details.                         */
-/*                                                                      */
-/* You should have received a copy of the GNU General Public License    */ 
-/* along with this program; if not, write to the:                       */
-/* Free Software Foundation, Inc.,                                      */ 
-/* 59 Temple Place, Suite 330,                                          */ 
-/* Boston, MA  02111-1307  USA                                          */
-/************************************************************************/
-/* Change Activity:                                                     */
-/*   Created December 28, 2000                                          */
-/* End Change Activity                                                  */
-/************************************************************************/
+/*
+ * File iSeries_io.h created by Allan Trautman on Thu Dec 28 2000.
+ *
+ * Remaps the io.h for the iSeries Io
+ * Copyright (C) 2000  Allan H Trautman, IBM Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the:
+ * Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330,
+ * Boston, MA  02111-1307  USA
+ *
+ * Change Activity:
+ *   Created December 28, 2000
+ * End Change Activity
+ */
+
 extern u8   iSeries_Read_Byte(const volatile void __iomem * IoAddress);
 extern u16  iSeries_Read_Word(const volatile void __iomem * IoAddress);
 extern u32  iSeries_Read_Long(const volatile void __iomem * IoAddress);
@@ -39,8 +40,10 @@ extern void iSeries_Write_Word(u16 IoDat
 extern void iSeries_Write_Long(u32 IoData, volatile void __iomem * IoAddress);
 
 extern void iSeries_memset_io(volatile void __iomem *dest, char x, size_t n);
-extern void iSeries_memcpy_toio(volatile void __iomem *dest, void *source, size_t n);
-extern void iSeries_memcpy_fromio(void *dest, const volatile void __iomem *source, size_t n);
+extern void iSeries_memcpy_toio(volatile void __iomem *dest, void *source,
+		size_t n);
+extern void iSeries_memcpy_fromio(void *dest,
+		const volatile void __iomem *source, size_t n);
 
 #endif /* CONFIG_PPC_ISERIES */
 #endif /* _ISERIES_IO_H */
diff --git a/include/asm-ppc64/iSeries/iSeries_irq.h b/include/asm-ppc64/iSeries/iSeries_irq.h
--- a/include/asm-ppc64/iSeries/iSeries_irq.h
+++ b/include/asm-ppc64/iSeries/iSeries_irq.h
@@ -1,19 +1,8 @@
 #ifndef	__ISERIES_IRQ_H__
 #define	__ISERIES_IRQ_H__
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-void iSeries_init_IRQ(void);
-int  iSeries_allocate_IRQ(HvBusNumber, HvSubBusNumber, HvAgentId);
-int  iSeries_assign_IRQ(int, HvBusNumber, HvSubBusNumber, HvAgentId);
-void iSeries_activate_IRQs(void);
-
-int XmPciLpEvent_init(void);
-
-#ifdef __cplusplus
-}
-#endif
+extern void iSeries_init_IRQ(void);
+extern int  iSeries_allocate_IRQ(HvBusNumber, HvSubBusNumber, HvAgentId);
+extern void iSeries_activate_IRQs(void);
 
 #endif /* __ISERIES_IRQ_H__ */
diff --git a/include/asm-ppc64/iSeries/iSeries_pci.h b/include/asm-ppc64/iSeries/iSeries_pci.h
--- a/include/asm-ppc64/iSeries/iSeries_pci.h
+++ b/include/asm-ppc64/iSeries/iSeries_pci.h
@@ -1,112 +1,88 @@
 #ifndef _ISERIES_64_PCI_H
 #define _ISERIES_64_PCI_H
 
-/************************************************************************/
-/* File iSeries_pci.h created by Allan Trautman on Tue Feb 20, 2001.    */
-/************************************************************************/
-/* Define some useful macros for the iSeries pci routines.              */
-/* Copyright (C) 2001  Allan H Trautman, IBM Corporation                */
-/*                                                                      */
-/* This program is free software; you can redistribute it and/or modify */
-/* it under the terms of the GNU General Public License as published by */
-/* the Free Software Foundation; either version 2 of the License, or    */
-/* (at your option) any later version.                                  */
-/*                                                                      */
-/* This program is distributed in the hope that it will be useful,      */ 
-/* but WITHOUT ANY WARRANTY; without even the implied warranty of       */
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        */
-/* GNU General Public License for more details.                         */
-/*                                                                      */
-/* You should have received a copy of the GNU General Public License    */ 
-/* along with this program; if not, write to the:                       */
-/* Free Software Foundation, Inc.,                                      */ 
-/* 59 Temple Place, Suite 330,                                          */ 
-/* Boston, MA  02111-1307  USA                                          */
-/************************************************************************/
-/* Change Activity:                                                     */
-/*   Created Feb 20, 2001                                               */
-/*   Added device reset, March 22, 2001                                 */
-/*   Ported to ppc64, May 25, 2001                                      */
-/* End Change Activity                                                  */
-/************************************************************************/
+/*
+ * File iSeries_pci.h created by Allan Trautman on Tue Feb 20, 2001.
+ *
+ * Define some useful macros for the iSeries pci routines.
+ * Copyright (C) 2001  Allan H Trautman, IBM Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the:
+ * Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330,
+ * Boston, MA  02111-1307  USA
+ *
+ * Change Activity:
+ *   Created Feb 20, 2001
+ *   Added device reset, March 22, 2001
+ *   Ported to ppc64, May 25, 2001
+ * End Change Activity
+ */
 
 #include <asm/iSeries/HvCallPci.h>
 #include <asm/abs_addr.h>
 
-struct pci_dev;				/* For Forward Reference        */
+struct pci_dev;				/* For Forward Reference */
 struct iSeries_Device_Node;
 
-/************************************************************************/
-/* Gets iSeries Bus, SubBus, DevFn using iSeries_Device_Node structure */
-/************************************************************************/
+/*
+ * Gets iSeries Bus, SubBus, DevFn using iSeries_Device_Node structure
+ */
 
 #define ISERIES_BUS(DevPtr)	DevPtr->DsaAddr.Dsa.busNumber
 #define ISERIES_SUBBUS(DevPtr)	DevPtr->DsaAddr.Dsa.subBusNumber
 #define ISERIES_DEVICE(DevPtr)	DevPtr->DsaAddr.Dsa.deviceId
 #define ISERIES_DSA(DevPtr)	DevPtr->DsaAddr.DsaAddr
-#define ISERIES_DEVFUN(DevPtr)	DevPtr->DevFn
-#define ISERIES_DEVNODE(PciDev) ((struct iSeries_Device_Node*)PciDev->sysdata)
+#define ISERIES_DEVNODE(PciDev)	((struct iSeries_Device_Node *)PciDev->sysdata)
 
 #define EADsMaxAgents 7
 
-/************************************************************************/
-/* Decodes Linux DevFn to iSeries DevFn, bridge device, or function.    */
-/* For Linux, see PCI_SLOT and PCI_FUNC in include/linux/pci.h          */
-/************************************************************************/
+/*
+ * Decodes Linux DevFn to iSeries DevFn, bridge device, or function.
+ * For Linux, see PCI_SLOT and PCI_FUNC in include/linux/pci.h
+ */
 
-#define ISERIES_PCI_AGENTID(idsel,func)	((idsel & 0x0F) << 4) | (func  & 0x07)
-#define ISERIES_ENCODE_DEVICE(agentid)	((0x10) | ((agentid&0x20)>>2) | (agentid&07))
+#define ISERIES_PCI_AGENTID(idsel, func)	\
+	(((idsel & 0x0F) << 4) | (func & 0x07))
+#define ISERIES_ENCODE_DEVICE(agentid)		\
+	((0x10) | ((agentid & 0x20) >> 2) | (agentid & 0x07))
 
-#define ISERIES_GET_DEVICE_FROM_SUBBUS(subbus)   ((subbus >> 5) & 0x7)
-#define ISERIES_GET_FUNCTION_FROM_SUBBUS(subbus) ((subbus >> 2) & 0x7)
+#define ISERIES_GET_DEVICE_FROM_SUBBUS(subbus)		((subbus >> 5) & 0x7)
+#define ISERIES_GET_FUNCTION_FROM_SUBBUS(subbus)	((subbus >> 2) & 0x7)
 
 /*
- * N.B. the ISERIES_DECODE_* macros are not used anywhere, and I think
- * the 0x71 (at least) must be wrong - 0x78 maybe?  -- paulus.
+ * Converts Virtual Address to Real Address for Hypervisor calls
  */
-#define ISERIES_DECODE_DEVFN(linuxdevfn)  (((linuxdevfn & 0x71) << 1) | (linuxdevfn & 0x07))
-#define ISERIES_DECODE_DEVICE(linuxdevfn) (((linuxdevfn & 0x38) >> 3) |(((linuxdevfn & 0x40) >> 2) + 0x10))
-#define ISERIES_DECODE_FUNCTION(linuxdevfn) (linuxdevfn & 0x07)
-
-/************************************************************************/
-/* Converts Virtual Address to Real Address for Hypervisor calls        */
-/************************************************************************/
-
-#define ISERIES_HV_ADDR(virtaddr)  (0x8000000000000000 | virt_to_abs(virtaddr))
-
-/************************************************************************/
-/* iSeries Device Information                                           */
-/************************************************************************/
+#define ISERIES_HV_ADDR(virtaddr)	\
+	(0x8000000000000000 | virt_to_abs(virtaddr))
 
+/*
+ * iSeries Device Information
+ */
 struct iSeries_Device_Node {
 	struct list_head Device_List;
-	struct pci_dev* PciDev;         /* Pointer to pci_dev structure*/
-        union HvDsaMap	DsaAddr;	/* Direct Select Address       */
-                                        /* busNumber,subBusNumber,     */ 
-	                                /* deviceId, barNumber         */
-	HvAgentId       AgentId;	/* Hypervisor DevFn            */
-	int             DevFn;          /* Linux devfn                 */
-	int             BarOffset;
-	int             Irq;            /* Assigned IRQ                */
-	int             ReturnCode;	/* Return Code Holder          */
-	int             IoRetry;        /* Current Retry Count         */
-	int             Flags;          /* Possible flags(disable/bist)*/
-	u16             Vendor;         /* Vendor ID                   */
-	u8              LogicalSlot;    /* Hv Slot Index for Tces      */
-	struct iommu_table* iommu_table;/* Device TCE Table            */ 
-	u8              PhbId;          /* Phb Card is on.             */
-	u16             Board;          /* Board Number                */
-	u8              FrameId;	/* iSeries spcn Frame Id       */
-	char            CardLocation[4];/* Char format of planar vpd   */
-	char            Location[20];   /* Frame  1, Card C10          */
+	struct pci_dev	*PciDev;
+	union HvDsaMap	DsaAddr;	/* Direct Select Address */
+					/* busNumber, subBusNumber, */
+					/* deviceId, barNumber */
+	int		DevFn;		/* Linux devfn */
+	int		Irq;		/* Assigned IRQ */
+	int		Flags;		/* Possible flags(disable/bist)*/
+	u8		LogicalSlot;	/* Hv Slot Index for Tces */
+	struct iommu_table *iommu_table;/* Device TCE Table */
 };
 
-/************************************************************************/
-/* Functions                                                            */
-/************************************************************************/
-
-extern int           iSeries_Device_Information(struct pci_dev*,char*, int);
-extern void          iSeries_Get_Location_Code(struct iSeries_Device_Node*);
-extern int           iSeries_Device_ToggleReset(struct pci_dev* PciDev, int AssertTime, int DelayTime);
+extern void	iSeries_Device_Information(struct pci_dev*, int);
 
 #endif /* _ISERIES_64_PCI_H */
diff --git a/include/asm-ppc64/iSeries/iSeries_proc.h b/include/asm-ppc64/iSeries/iSeries_proc.h
deleted file mode 100644
--- a/include/asm-ppc64/iSeries/iSeries_proc.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * iSeries_proc.h
- * Copyright (C) 2001  Kyle A. Lucke IBM Corporation
- * 
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- */
-#ifndef _ISERIES_PROC_H
-#define _ISERIES_PROC_H
-
-extern void iSeries_proc_early_init(void);
-
-#endif /* _iSeries_PROC_H */
diff --git a/include/asm-ppc64/iSeries/mf.h b/include/asm-ppc64/iSeries/mf.h
--- a/include/asm-ppc64/iSeries/mf.h
+++ b/include/asm-ppc64/iSeries/mf.h
@@ -9,17 +9,16 @@
  * all partitions in the iSeries.  It also provides miscellaneous low-level
  * machine facility type operations.
  *
- * 
  * 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
diff --git a/include/asm-ppc64/iSeries/vio.h b/include/asm-ppc64/iSeries/vio.h
--- a/include/asm-ppc64/iSeries/vio.h
+++ b/include/asm-ppc64/iSeries/vio.h
@@ -8,32 +8,32 @@
  *           Colin Devilbiss <devilbis@us.ibm.com>
  *
  * (C) Copyright 2000 IBM Corporation
- * 
+ *
  * This header file is used by the iSeries virtual I/O device
  * drivers.  It defines the interfaces to the common functions
  * (implemented in drivers/char/viopath.h) as well as defining
- * common functions and structures.  Currently (at the time I 
+ * common functions and structures.  Currently (at the time I
  * wrote this comment) the iSeries virtual I/O device drivers
- * that use this are 
- *   drivers/block/viodasd.c 
+ * that use this are
+ *   drivers/block/viodasd.c
  *   drivers/char/viocons.c
  *   drivers/char/viotape.c
  *   drivers/cdrom/viocd.c
  *
  * The iSeries virtual ethernet support (veth.c) uses a whole
  * different set of functions.
- * 
+ *
  * 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) anyu later version.
  *
  * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of 
+ * 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.  
+ * General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License 
+ * 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
  *
@@ -44,39 +44,41 @@
 #include <asm/iSeries/HvTypes.h>
 #include <asm/iSeries/HvLpEvent.h>
 
-/* iSeries virtual I/O events use the subtype field in
+/*
+ * iSeries virtual I/O events use the subtype field in
  * HvLpEvent to figure out what kind of vio event is coming
  * in.  We use a table to route these, and this defines
  * the maximum number of distinct subtypes
  */
 #define VIO_MAX_SUBTYPES 8
 
-/* Each subtype can register a handler to process their events.
+/*
+ * Each subtype can register a handler to process their events.
  * The handler must have this interface.
  */
 typedef void (vio_event_handler_t) (struct HvLpEvent * event);
 
-int viopath_open(HvLpIndex remoteLp, int subtype, int numReq);
-int viopath_close(HvLpIndex remoteLp, int subtype, int numReq);
-int vio_setHandler(int subtype, vio_event_handler_t * beh);
-int vio_clearHandler(int subtype);
-int viopath_isactive(HvLpIndex lp);
-HvLpInstanceId viopath_sourceinst(HvLpIndex lp);
-HvLpInstanceId viopath_targetinst(HvLpIndex lp);
-void vio_set_hostlp(void);
-void *vio_get_event_buffer(int subtype);
-void vio_free_event_buffer(int subtype, void *buffer);
+extern int viopath_open(HvLpIndex remoteLp, int subtype, int numReq);
+extern int viopath_close(HvLpIndex remoteLp, int subtype, int numReq);
+extern int vio_setHandler(int subtype, vio_event_handler_t * beh);
+extern int vio_clearHandler(int subtype);
+extern int viopath_isactive(HvLpIndex lp);
+extern HvLpInstanceId viopath_sourceinst(HvLpIndex lp);
+extern HvLpInstanceId viopath_targetinst(HvLpIndex lp);
+extern void vio_set_hostlp(void);
+extern void *vio_get_event_buffer(int subtype);
+extern void vio_free_event_buffer(int subtype, void *buffer);
 
 extern HvLpIndex viopath_hostLp;
 extern HvLpIndex viopath_ourLp;
 
-#define VIOCHAR_MAX_DATA 200
+#define VIOCHAR_MAX_DATA	200
 
-#define VIOMAJOR_SUBTYPE_MASK 0xff00
-#define VIOMINOR_SUBTYPE_MASK 0x00ff
-#define VIOMAJOR_SUBTYPE_SHIFT 8
+#define VIOMAJOR_SUBTYPE_MASK	0xff00
+#define VIOMINOR_SUBTYPE_MASK	0x00ff
+#define VIOMAJOR_SUBTYPE_SHIFT	8
 
-#define VIOVERSION            0x0101
+#define VIOVERSION		0x0101
 
 /*
  * This is the general structure for VIO errors; each module should have
@@ -89,8 +91,8 @@ struct vio_error_entry {
 	int errno;
 	const char *msg;
 };
-const struct vio_error_entry *vio_lookup_rc(const struct vio_error_entry
-					    *local_table, u16 rc);
+extern const struct vio_error_entry *vio_lookup_rc(
+		const struct vio_error_entry *local_table, u16 rc);
 
 enum viosubtypes {
 	viomajorsubtype_monitor = 0x0100,
@@ -102,7 +104,6 @@ enum viosubtypes {
 	viomajorsubtype_scsi = 0x0700
 };
 
-
 enum vioconfigsubtype {
 	vioconfigget = 0x0001,
 };
diff --git a/include/asm-ppc64/imalloc.h b/include/asm-ppc64/imalloc.h
--- a/include/asm-ppc64/imalloc.h
+++ b/include/asm-ppc64/imalloc.h
@@ -4,9 +4,9 @@
 /*
  * Define the address range of the imalloc VM area.
  */
-#define PHBS_IO_BASE  	  IOREGIONBASE
-#define IMALLOC_BASE      (IOREGIONBASE + 0x80000000ul)	/* Reserve 2 gigs for PHBs */
-#define IMALLOC_END       (IOREGIONBASE + EADDR_MASK)
+#define PHBS_IO_BASE  	  VMALLOC_END
+#define IMALLOC_BASE      (PHBS_IO_BASE + 0x80000000ul)	/* Reserve 2 gigs for PHBs */
+#define IMALLOC_END       (VMALLOC_START + EADDR_MASK)
 
 
 /* imalloc region types */
@@ -18,7 +18,9 @@
 
 extern struct vm_struct * im_get_free_area(unsigned long size);
 extern struct vm_struct * im_get_area(unsigned long v_addr, unsigned long size,
-			int region_type);
-unsigned long im_free(void *addr);
+				      int region_type);
+extern void im_free(void *addr);
+
+extern unsigned long ioremap_bot;
 
 #endif /* _PPC64_IMALLOC_H */
diff --git a/include/asm-ppc64/iommu.h b/include/asm-ppc64/iommu.h
--- a/include/asm-ppc64/iommu.h
+++ b/include/asm-ppc64/iommu.h
@@ -82,24 +82,6 @@ struct iommu_table {
 	unsigned long *it_map;       /* A simple allocation bitmap for now */
 };
 
-#ifdef CONFIG_PPC_ISERIES
-struct iommu_table_cb {
-	unsigned long	itc_busno;	/* Bus number for this tce table */
-	unsigned long	itc_start;	/* Will be NULL for secondary */
-	unsigned long	itc_totalsize;	/* Size (in pages) of whole table */
-	unsigned long	itc_offset;	/* Index into real tce table of the
-					   start of our section */
-	unsigned long	itc_size;	/* Size (in pages) of our section */
-	unsigned long	itc_index;	/* Index of this tce table */
-	unsigned short	itc_maxtables;	/* Max num of tables for partition */
-	unsigned char	itc_virtbus;	/* Flag to indicate virtual bus */
- 	unsigned char	itc_slotno;	/* IOA Tce Slot Index */
- 	unsigned char	itc_rsvd[4];
-};
-
-extern struct iommu_table vio_tce_table;      /* Tce table for virtual bus */
-#endif /* CONFIG_PPC_ISERIES */
-
 struct scatterlist;
 
 #ifdef CONFIG_PPC_MULTIPLATFORM
@@ -122,9 +104,6 @@ extern void iommu_devnode_init_pSeries(s
 
 #ifdef CONFIG_PPC_ISERIES
 
-/* Walks all buses and creates iommu tables */
-extern void iommu_setup_iSeries(void);
-
 /* Initializes tables for bio buses */
 extern void __init iommu_vio_init(void);
 
@@ -158,8 +137,12 @@ extern void iommu_init_early_pSeries(voi
 extern void iommu_init_early_iSeries(void);
 extern void iommu_init_early_u3(void);
 
+#ifdef CONFIG_PCI
 extern void pci_iommu_init(void);
 extern void pci_direct_iommu_init(void);
+#else
+static inline void pci_iommu_init(void) { }
+#endif
 
 extern void alloc_u3_dart_table(void);
 
diff --git a/include/asm-ppc64/kdebug.h b/include/asm-ppc64/kdebug.h
--- a/include/asm-ppc64/kdebug.h
+++ b/include/asm-ppc64/kdebug.h
@@ -17,7 +17,7 @@ struct die_args {
 
 /*
    Note - you should never unregister because that can race with NMIs.
-   If you really want to do it first unregister - then synchronize_kernel -
+   If you really want to do it first unregister - then synchronize_sched -
    then free.
  */
 int register_die_notifier(struct notifier_block *nb);
diff --git a/include/asm-ppc64/kexec.h b/include/asm-ppc64/kexec.h
new file mode 100644
--- /dev/null
+++ b/include/asm-ppc64/kexec.h
@@ -0,0 +1,41 @@
+#ifndef _PPC64_KEXEC_H
+#define _PPC64_KEXEC_H
+
+/*
+ * KEXEC_SOURCE_MEMORY_LIMIT maximum page get_free_page can return.
+ * I.e. Maximum page that is mapped directly into kernel memory,
+ * and kmap is not required.
+ */
+
+/* Maximum physical address we can use pages from */
+/* XXX: since we copy virt we can use any page we allocate */
+#define KEXEC_SOURCE_MEMORY_LIMIT (-1UL)
+
+/* Maximum address we can reach in physical address mode */
+/* XXX: I want to allow initrd in highmem.  otherwise set to rmo on lpar */
+#define KEXEC_DESTINATION_MEMORY_LIMIT (-1UL)
+
+/* Maximum address we can use for the control code buffer */
+/* XXX: unused today, ppc32 uses TASK_SIZE, probably left over from use_mm  */
+#define KEXEC_CONTROL_MEMORY_LIMIT (-1UL)
+
+/* XXX: today we don't use this at all, althogh we have a static stack */
+#define KEXEC_CONTROL_CODE_SIZE 4096
+
+/* The native architecture */
+#define KEXEC_ARCH KEXEC_ARCH_PPC64
+
+#define MAX_NOTE_BYTES 1024
+
+#ifndef __ASSEMBLY__
+
+typedef u32 note_buf_t[MAX_NOTE_BYTES/4];
+
+extern note_buf_t crash_notes[];
+
+extern void kexec_smp_wait(void);	/* get and clear naca physid, wait for
+					  master to copy new code to 0 */
+
+#endif /* __ASSEMBLY__ */
+#endif /* _PPC_KEXEC_H */
+
diff --git a/include/asm-ppc64/kprobes.h b/include/asm-ppc64/kprobes.h
--- a/include/asm-ppc64/kprobes.h
+++ b/include/asm-ppc64/kprobes.h
@@ -42,10 +42,13 @@ typedef unsigned int kprobe_opcode_t;
 
 #define JPROBE_ENTRY(pentry)	(kprobe_opcode_t *)((func_descr_t *)pentry)
 
+#define ARCH_SUPPORTS_KRETPROBES
+void kretprobe_trampoline(void);
+
 /* Architecture specific copy of original instruction */
 struct arch_specific_insn {
 	/* copy of original instruction */
-	kprobe_opcode_t insn[MAX_INSN_SIZE];
+	kprobe_opcode_t *insn;
 };
 
 #ifdef CONFIG_KPROBES
diff --git a/include/asm-ppc64/machdep.h b/include/asm-ppc64/machdep.h
--- a/include/asm-ppc64/machdep.h
+++ b/include/asm-ppc64/machdep.h
@@ -53,10 +53,8 @@ struct machdep_calls {
 	long		(*hpte_insert)(unsigned long hpte_group,
 				       unsigned long va,
 				       unsigned long prpn,
-				       int secondary, 
-				       unsigned long hpteflags, 
-				       int bolted,
-				       int large);
+				       unsigned long vflags,
+				       unsigned long rflags);
 	long		(*hpte_remove)(unsigned long hpte_group);
 	void		(*flush_hash_range)(unsigned long context,
 					    unsigned long number,
@@ -76,6 +74,7 @@ struct machdep_calls {
 	void		(*tce_flush)(struct iommu_table *tbl);
 	void		(*iommu_dev_setup)(struct pci_dev *dev);
 	void		(*iommu_bus_setup)(struct pci_bus *bus);
+	void		(*irq_bus_setup)(struct pci_bus *bus);
 
 	int		(*probe)(int platform);
 	void		(*setup_arch)(void);
@@ -85,6 +84,7 @@ struct machdep_calls {
 
 	void		(*init_IRQ)(void);
 	int		(*get_irq)(struct pt_regs *);
+	void		(*cpu_irq_down)(int secondary);
 
 	/* PCI stuff */
 	void		(*pcibios_fixup)(void);
@@ -138,8 +138,13 @@ struct machdep_calls {
 						unsigned long size,
 						pgprot_t vma_prot);
 
+	/* Idle loop for this platform, leave empty for default idle loop */
+	int		(*idle_loop)(void);
 };
 
+extern int default_idle(void);
+extern int native_idle(void);
+
 extern struct machdep_calls ppc_md;
 extern char cmd_line[COMMAND_LINE_SIZE];
 
diff --git a/include/asm-ppc64/mmu.h b/include/asm-ppc64/mmu.h
--- a/include/asm-ppc64/mmu.h
+++ b/include/asm-ppc64/mmu.h
@@ -47,9 +47,10 @@
 #define SLB_VSID_KS		ASM_CONST(0x0000000000000800)
 #define SLB_VSID_KP		ASM_CONST(0x0000000000000400)
 #define SLB_VSID_N		ASM_CONST(0x0000000000000200) /* no-execute */
-#define SLB_VSID_L		ASM_CONST(0x0000000000000100) /* largepage 16M */
+#define SLB_VSID_L		ASM_CONST(0x0000000000000100) /* largepage */
 #define SLB_VSID_C		ASM_CONST(0x0000000000000080) /* class */
-
+#define SLB_VSID_LS		ASM_CONST(0x0000000000000070) /* size of largepage */
+ 
 #define SLB_VSID_KERNEL		(SLB_VSID_KP|SLB_VSID_C)
 #define SLB_VSID_USER		(SLB_VSID_KP|SLB_VSID_KS)
 
@@ -59,6 +60,22 @@
 
 #define HPTES_PER_GROUP 8
 
+#define HPTE_V_AVPN_SHIFT	7
+#define HPTE_V_AVPN		ASM_CONST(0xffffffffffffff80)
+#define HPTE_V_AVPN_VAL(x)	(((x) & HPTE_V_AVPN) >> HPTE_V_AVPN_SHIFT)
+#define HPTE_V_BOLTED		ASM_CONST(0x0000000000000010)
+#define HPTE_V_LOCK		ASM_CONST(0x0000000000000008)
+#define HPTE_V_LARGE		ASM_CONST(0x0000000000000004)
+#define HPTE_V_SECONDARY	ASM_CONST(0x0000000000000002)
+#define HPTE_V_VALID		ASM_CONST(0x0000000000000001)
+
+#define HPTE_R_PP0		ASM_CONST(0x8000000000000000)
+#define HPTE_R_TS		ASM_CONST(0x4000000000000000)
+#define HPTE_R_RPN_SHIFT	12
+#define HPTE_R_RPN		ASM_CONST(0x3ffffffffffff000)
+#define HPTE_R_FLAGS		ASM_CONST(0x00000000000003ff)
+#define HPTE_R_PP		ASM_CONST(0x0000000000000003)
+
 /* Values for PP (assumes Ks=0, Kp=1) */
 /* pp0 will always be 0 for linux     */
 #define PP_RWXX	0	/* Supervisor read/write, User none */
@@ -68,54 +85,13 @@
 
 #ifndef __ASSEMBLY__
 
-/* Hardware Page Table Entry */
-typedef struct {
-	unsigned long avpn:57; /* vsid | api == avpn  */
-	unsigned long :     2; /* Software use */
-	unsigned long bolted: 1; /* HPTE is "bolted" */
-	unsigned long lock: 1; /* lock on pSeries SMP */
-	unsigned long l:    1; /* Virtual page is large (L=1) or 4 KB (L=0) */
-	unsigned long h:    1; /* Hash function identifier */
-	unsigned long v:    1; /* Valid (v=1) or invalid (v=0) */
-} Hpte_dword0;
-
-typedef struct {
-	unsigned long pp0:  1; /* Page protection bit 0 */
-	unsigned long ts:   1; /* Tag set bit */
-	unsigned long rpn: 50; /* Real page number */
-	unsigned long :     2; /* Reserved */
-	unsigned long ac:   1; /* Address compare */ 
-	unsigned long r:    1; /* Referenced */
-	unsigned long c:    1; /* Changed */
-	unsigned long w:    1; /* Write-thru cache mode */
-	unsigned long i:    1; /* Cache inhibited */
-	unsigned long m:    1; /* Memory coherence required */
-	unsigned long g:    1; /* Guarded */
-	unsigned long n:    1; /* No-execute */
-	unsigned long pp:   2; /* Page protection bits 1:2 */
-} Hpte_dword1;
-
-typedef struct {
-	char padding[6];	   	/* padding */
-	unsigned long :       6;	/* padding */ 
-	unsigned long flags: 10;	/* HPTE flags */
-} Hpte_dword1_flags;
-
 typedef struct {
-	union {
-		unsigned long dword0;
-		Hpte_dword0   dw0;
-	} dw0;
-
-	union {
-		unsigned long dword1;
-		Hpte_dword1 dw1;
-		Hpte_dword1_flags flags;
-	} dw1;
-} HPTE; 
+	unsigned long v;
+	unsigned long r;
+} hpte_t;
 
-extern HPTE *		htab_address;
-extern unsigned long	htab_hash_mask;
+extern hpte_t *htab_address;
+extern unsigned long htab_hash_mask;
 
 static inline unsigned long hpt_hash(unsigned long vpn, int large)
 {
@@ -180,6 +156,28 @@ static inline void tlbiel(unsigned long 
 	asm volatile("ptesync": : :"memory");
 }
 
+static inline unsigned long slot2va(unsigned long hpte_v, unsigned long slot)
+{
+	unsigned long avpn = HPTE_V_AVPN_VAL(hpte_v);
+	unsigned long va;
+
+	va = avpn << 23;
+
+	if (! (hpte_v & HPTE_V_LARGE)) {
+		unsigned long vpi, pteg;
+
+		pteg = slot / HPTES_PER_GROUP;
+		if (hpte_v & HPTE_V_SECONDARY)
+			pteg = ~pteg;
+
+		vpi = ((va >> 28) ^ pteg) & htab_hash_mask;
+
+		va |= vpi << PAGE_SHIFT;
+	}
+
+	return va;
+}
+
 /*
  * Handle a fault by adding an HPTE. If the address can't be determined
  * to be valid via Linux page tables, return 1. If handled return 0
@@ -196,11 +194,13 @@ extern void hpte_init_iSeries(void);
 
 extern long pSeries_lpar_hpte_insert(unsigned long hpte_group,
 				     unsigned long va, unsigned long prpn,
-				     int secondary, unsigned long hpteflags,
-				     int bolted, int large);
+				     unsigned long vflags,
+				     unsigned long rflags);
 extern long native_hpte_insert(unsigned long hpte_group, unsigned long va,
-			       unsigned long prpn, int secondary,
-			       unsigned long hpteflags, int bolted, int large);
+			       unsigned long prpn,
+			       unsigned long vflags, unsigned long rflags);
+
+extern void stabs_alloc(void);
 
 #endif /* __ASSEMBLY__ */
 
@@ -338,6 +338,9 @@ static inline unsigned long get_vsid(uns
 			     | (ea >> SID_SHIFT));
 }
 
+#define VSID_SCRAMBLE(pvsid)	(((pvsid) * VSID_MULTIPLIER) % VSID_MODULUS)
+#define KERNEL_VSID(ea)		VSID_SCRAMBLE(GET_ESID(ea))
+
 #endif /* __ASSEMBLY */
 
 #endif /* _PPC64_MMU_H_ */
diff --git a/include/asm-ppc64/mmzone.h b/include/asm-ppc64/mmzone.h
--- a/include/asm-ppc64/mmzone.h
+++ b/include/asm-ppc64/mmzone.h
@@ -10,9 +10,20 @@
 #include <linux/config.h>
 #include <asm/smp.h>
 
-#ifdef CONFIG_DISCONTIGMEM
+/* generic non-linear memory support:
+ *
+ * 1) we will not split memory into more chunks than will fit into the
+ *    flags field of the struct page
+ */
+
+
+#ifdef CONFIG_NEED_MULTIPLE_NODES
 
 extern struct pglist_data *node_data[];
+/*
+ * Return a pointer to the node data for node n.
+ */
+#define NODE_DATA(nid)		(node_data[nid])
 
 /*
  * Following are specific to this numa platform.
@@ -47,36 +58,32 @@ static inline int pa_to_nid(unsigned lon
 	return nid;
 }
 
-#define pfn_to_nid(pfn)		pa_to_nid((pfn) << PAGE_SHIFT)
-
-/*
- * Return a pointer to the node data for node n.
- */
-#define NODE_DATA(nid)		(node_data[nid])
-
 #define node_localnr(pfn, nid)	((pfn) - NODE_DATA(nid)->node_start_pfn)
 
 /*
  * Following are macros that each numa implmentation must define.
  */
 
-/*
- * Given a kernel address, find the home node of the underlying memory.
- */
-#define kvaddr_to_nid(kaddr)	pa_to_nid(__pa(kaddr))
-
-#define node_mem_map(nid)	(NODE_DATA(nid)->node_mem_map)
 #define node_start_pfn(nid)	(NODE_DATA(nid)->node_start_pfn)
 #define node_end_pfn(nid)	(NODE_DATA(nid)->node_end_pfn)
 
 #define local_mapnr(kvaddr) \
 	( (__pa(kvaddr) >> PAGE_SHIFT) - node_start_pfn(kvaddr_to_nid(kvaddr)) 
 
+#ifdef CONFIG_DISCONTIGMEM
+
+/*
+ * Given a kernel address, find the home node of the underlying memory.
+ */
+#define kvaddr_to_nid(kaddr)	pa_to_nid(__pa(kaddr))
+
+#define pfn_to_nid(pfn)		pa_to_nid((unsigned long)(pfn) << PAGE_SHIFT)
+
 /* Written this way to avoid evaluating arguments twice */
 #define discontigmem_pfn_to_page(pfn) \
 ({ \
 	unsigned long __tmp = pfn; \
-	(node_mem_map(pfn_to_nid(__tmp)) + \
+	(NODE_DATA(pfn_to_nid(__tmp))->node_mem_map + \
 	 node_localnr(__tmp, pfn_to_nid(__tmp))); \
 })
 
@@ -91,4 +98,11 @@ static inline int pa_to_nid(unsigned lon
 #define discontigmem_pfn_valid(pfn)		((pfn) < num_physpages)
 
 #endif /* CONFIG_DISCONTIGMEM */
+
+#endif /* CONFIG_NEED_MULTIPLE_NODES */
+
+#ifdef CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID
+#define early_pfn_to_nid(pfn)  pa_to_nid(((unsigned long)pfn) << PAGE_SHIFT)
+#endif
+
 #endif /* _ASM_MMZONE_H_ */
diff --git a/include/asm-ppc64/nvram.h b/include/asm-ppc64/nvram.h
--- a/include/asm-ppc64/nvram.h
+++ b/include/asm-ppc64/nvram.h
@@ -70,6 +70,7 @@ extern struct nvram_partition *nvram_fin
 
 extern int pSeries_nvram_init(void);
 extern int pmac_nvram_init(void);
+extern int bpa_nvram_init(void);
 
 /* PowerMac specific nvram stuffs */
 
diff --git a/include/asm-ppc64/paca.h b/include/asm-ppc64/paca.h
--- a/include/asm-ppc64/paca.h
+++ b/include/asm-ppc64/paca.h
@@ -26,7 +26,6 @@ register struct paca_struct *local_paca 
 #define get_paca()	local_paca
 
 struct task_struct;
-struct ItLpQueue;
 
 /*
  * Defines the layout of the paca.
@@ -62,7 +61,6 @@ struct paca_struct {
 	u16 paca_index;			/* Logical processor number */
 
 	u32 default_decr;		/* Default decrementer value */
-	struct ItLpQueue *lpqueue_ptr;	/* LpQueue handled by this CPU */
 	u64 kernel_toc;			/* Kernel TOC address */
 	u64 stab_real;			/* Absolute address of segment table */
 	u64 stab_addr;			/* Virtual address of segment table */
@@ -91,7 +89,6 @@ struct paca_struct {
 	u64 next_jiffy_update_tb;	/* TB value for next jiffy update */
 	u64 saved_r1;			/* r1 save for RTAS calls */
 	u64 saved_msr;			/* MSR saved here by enter_rtas */
-	u32 lpevent_count;		/* lpevents processed  */
 	u8 proc_enabled;		/* irq soft-enable flag */
 
 	/* not yet used */
diff --git a/include/asm-ppc64/page.h b/include/asm-ppc64/page.h
--- a/include/asm-ppc64/page.h
+++ b/include/asm-ppc64/page.h
@@ -202,9 +202,7 @@ extern u64 ppc64_pft_size;		/* Log 2 of 
 #define PAGE_OFFSET     ASM_CONST(0xC000000000000000)
 #define KERNELBASE      PAGE_OFFSET
 #define VMALLOCBASE     ASM_CONST(0xD000000000000000)
-#define IOREGIONBASE    ASM_CONST(0xE000000000000000)
 
-#define IO_REGION_ID       (IOREGIONBASE >> REGION_SHIFT)
 #define VMALLOC_REGION_ID  (VMALLOCBASE >> REGION_SHIFT)
 #define KERNEL_REGION_ID   (KERNELBASE >> REGION_SHIFT)
 #define USER_REGION_ID     (0UL)
@@ -219,7 +217,8 @@ extern u64 ppc64_pft_size;		/* Log 2 of 
 #define page_to_pfn(page)	discontigmem_page_to_pfn(page)
 #define pfn_to_page(pfn)	discontigmem_pfn_to_page(pfn)
 #define pfn_valid(pfn)		discontigmem_pfn_valid(pfn)
-#else
+#endif
+#ifdef CONFIG_FLATMEM
 #define pfn_to_page(pfn)	(mem_map + (pfn))
 #define page_to_pfn(page)	((unsigned long)((page) - mem_map))
 #define pfn_valid(pfn)		((pfn) < max_mapnr)
diff --git a/include/asm-ppc64/pci.h b/include/asm-ppc64/pci.h
--- a/include/asm-ppc64/pci.h
+++ b/include/asm-ppc64/pci.h
@@ -37,7 +37,7 @@ static inline void pcibios_set_master(st
 	/* No special bus mastering setup handling */
 }
 
-static inline void pcibios_penalize_isa_irq(int irq)
+static inline void pcibios_penalize_isa_irq(int irq, int active)
 {
 	/* We don't do dynamic PCI IRQ allocation */
 }
@@ -78,6 +78,25 @@ static inline int pci_dac_dma_supported(
 	return 0;
 }
 
+#ifdef CONFIG_PCI
+static inline void pci_dma_burst_advice(struct pci_dev *pdev,
+					enum pci_dma_burst_strategy *strat,
+					unsigned long *strategy_parameter)
+{
+	unsigned long cacheline_size;
+	u8 byte;
+
+	pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &byte);
+	if (byte == 0)
+		cacheline_size = 1024;
+	else
+		cacheline_size = (int) byte * 4;
+
+	*strat = PCI_DMA_BURST_MULTIPLE;
+	*strategy_parameter = cacheline_size;
+}
+#endif
+
 extern int pci_domain_nr(struct pci_bus *bus);
 
 /* Decide whether to display the domain number in /proc */
@@ -115,6 +134,10 @@ extern void
 pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
 			struct resource *res);
 
+extern void
+pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
+			struct pci_bus_region *region);
+
 extern int
 unmap_bus_range(struct pci_bus *bus);
 
@@ -136,6 +159,13 @@ extern pgprot_t	pci_phys_mem_access_prot
 					 unsigned long size,
 					 pgprot_t prot);
 
+#ifdef CONFIG_PPC_MULTIPLATFORM
+#define HAVE_ARCH_PCI_RESOURCE_TO_USER
+extern void pci_resource_to_user(const struct pci_dev *dev, int bar,
+				 const struct resource *rsrc,
+				 u64 *start, u64 *end);
+#endif /* CONFIG_PPC_MULTIPLATFORM */
+
 
 #endif	/* __KERNEL__ */
 
diff --git a/include/asm-ppc64/pgtable.h b/include/asm-ppc64/pgtable.h
--- a/include/asm-ppc64/pgtable.h
+++ b/include/asm-ppc64/pgtable.h
@@ -53,7 +53,8 @@
  * Define the address range of the vmalloc VM area.
  */
 #define VMALLOC_START (0xD000000000000000ul)
-#define VMALLOC_END   (VMALLOC_START + EADDR_MASK)
+#define VMALLOC_SIZE  (0x10000000000UL)
+#define VMALLOC_END   (VMALLOC_START + VMALLOC_SIZE)
 
 /*
  * Bits in a linux-style PTE.  These match the bits in the
@@ -239,9 +240,6 @@ static inline pte_t pfn_pte(unsigned lon
 /* This now only contains the vmalloc pages */
 #define pgd_offset_k(address) pgd_offset(&init_mm, address)
 
-/* to find an entry in the ioremap page-table-directory */
-#define pgd_offset_i(address) (ioremap_pgd + pgd_index(address))
-
 /*
  * The following only work if pte_present() is true.
  * Undefined behaviour if not..
@@ -459,15 +457,12 @@ extern pgprot_t phys_mem_access_prot(str
 #define __HAVE_ARCH_PTE_SAME
 #define pte_same(A,B)	(((pte_val(A) ^ pte_val(B)) & ~_PAGE_HPTEFLAGS) == 0)
 
-extern unsigned long ioremap_bot, ioremap_base;
-
 #define pmd_ERROR(e) \
 	printk("%s:%d: bad pmd %08x.\n", __FILE__, __LINE__, pmd_val(e))
 #define pgd_ERROR(e) \
 	printk("%s:%d: bad pgd %08x.\n", __FILE__, __LINE__, pgd_val(e))
 
 extern pgd_t swapper_pg_dir[];
-extern pgd_t ioremap_dir[];
 
 extern void paging_init(void);
 
diff --git a/include/asm-ppc64/ppc32.h b/include/asm-ppc64/ppc32.h
--- a/include/asm-ppc64/ppc32.h
+++ b/include/asm-ppc64/ppc32.h
@@ -32,7 +32,7 @@ typedef struct compat_siginfo {
 
 		/* POSIX.1b timers */
 		struct {
-			timer_t _tid;			/* timer id */
+			compat_timer_t _tid;			/* timer id */
 			int _overrun;			/* overrun count */
 			compat_sigval_t _sigval;		/* same as below */
 			int _sys_private;		/* not to be passed to user */
diff --git a/include/asm-ppc64/processor.h b/include/asm-ppc64/processor.h
--- a/include/asm-ppc64/processor.h
+++ b/include/asm-ppc64/processor.h
@@ -20,6 +20,7 @@
 #include <asm/ptrace.h>
 #include <asm/types.h>
 #include <asm/systemcfg.h>
+#include <asm/cputable.h>
 
 /* Machine State Register (MSR) Fields */
 #define MSR_SF_LG	63              /* Enable 64 bit mode */
@@ -138,8 +139,16 @@
 #define	SPRN_NIADORM	0x3F3	/* Hardware Implementation Register 2 */
 #define SPRN_HID4	0x3F4	/* 970 HID4 */
 #define SPRN_HID5	0x3F6	/* 970 HID5 */
-#define	SPRN_TSC 	0x3FD	/* Thread switch control */
-#define	SPRN_TST 	0x3FC	/* Thread switch timeout */
+#define	SPRN_HID6	0x3F9	/* BE HID 6 */
+#define	  HID6_LB	(0x0F<<12) /* Concurrent Large Page Modes */
+#define	  HID6_DLP	(1<<20)	/* Disable all large page modes (4K only) */
+#define	SPRN_TSCR	0x399   /* Thread switch control on BE */
+#define	SPRN_TTR	0x39A   /* Thread switch timeout on BE */
+#define	  TSCR_DEC_ENABLE	0x200000 /* Decrementer Interrupt */
+#define	  TSCR_EE_ENABLE	0x100000 /* External Interrupt */
+#define	  TSCR_EE_BOOST		0x080000 /* External Interrupt Boost */
+#define	SPRN_TSC 	0x3FD	/* Thread switch control on others */
+#define	SPRN_TST 	0x3FC	/* Thread switch timeout on others */
 #define	SPRN_L2CR	0x3F9	/* Level 2 Cache Control Regsiter */
 #define	SPRN_LR		0x008	/* Link Register */
 #define	SPRN_PIR	0x3FF	/* Processor Identification Register */
@@ -259,6 +268,7 @@
 #define PV_970FX	0x003C
 #define	PV_630        	0x0040
 #define	PV_630p	        0x0041
+#define	PV_BE		0x0070
 
 /* Platforms supported by PPC64 */
 #define PLATFORM_PSERIES      0x0100
@@ -267,6 +277,7 @@
 #define PLATFORM_LPAR         0x0001
 #define PLATFORM_POWERMAC     0x0400
 #define PLATFORM_MAPLE        0x0500
+#define PLATFORM_BPA          0x1000
 
 /* Compatibility with drivers coming from PPC32 world */
 #define _machine	(systemcfg->platform)
@@ -278,6 +289,7 @@
 #define IC_INVALID    0
 #define IC_OPEN_PIC   1
 #define IC_PPC_XIC    2
+#define IC_BPA_IIC    3
 
 #define XGLUE(a,b) a##b
 #define GLUE(a,b) XGLUE(a,b)
@@ -430,16 +442,6 @@ struct thread_struct {
 }
 
 /*
- * Note: the vm_start and vm_end fields here should *not*
- * be in kernel space.  (Could vm_end == vm_start perhaps?)
- */
-#define IOREMAP_MMAP { &ioremap_mm, 0, 0x1000, NULL, \
-		    PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC, \
-		    1, NULL, NULL }
-
-extern struct mm_struct ioremap_mm;
-
-/*
  * Return saved PC of a blocked thread. For now, this is the "user" PC
  */
 #define thread_saved_pc(tsk)    \
@@ -500,24 +502,37 @@ static inline void ppc64_runlatch_on(voi
 {
 	unsigned long ctrl;
 
-	ctrl = mfspr(SPRN_CTRLF);
-	ctrl |= CTRL_RUNLATCH;
-	mtspr(SPRN_CTRLT, ctrl);
+	if (cpu_has_feature(CPU_FTR_CTRL)) {
+		ctrl = mfspr(SPRN_CTRLF);
+		ctrl |= CTRL_RUNLATCH;
+		mtspr(SPRN_CTRLT, ctrl);
+	}
 }
 
 static inline void ppc64_runlatch_off(void)
 {
 	unsigned long ctrl;
 
-	ctrl = mfspr(SPRN_CTRLF);
-	ctrl &= ~CTRL_RUNLATCH;
-	mtspr(SPRN_CTRLT, ctrl);
+	if (cpu_has_feature(CPU_FTR_CTRL)) {
+		ctrl = mfspr(SPRN_CTRLF);
+		ctrl &= ~CTRL_RUNLATCH;
+		mtspr(SPRN_CTRLT, ctrl);
+	}
 }
 
 #endif /* __KERNEL__ */
 
 #endif /* __ASSEMBLY__ */
 
+#ifdef __KERNEL__
+#define RUNLATCH_ON(REG)			\
+BEGIN_FTR_SECTION				\
+	mfspr	(REG),SPRN_CTRLF;		\
+	ori	(REG),(REG),CTRL_RUNLATCH;	\
+	mtspr	SPRN_CTRLT,(REG);		\
+END_FTR_SECTION_IFSET(CPU_FTR_CTRL)
+#endif
+
 /*
  * Number of entries in the SLB. If this ever changes we should handle
  * it with a use a cpu feature fixup.
diff --git a/include/asm-ppc64/rtas.h b/include/asm-ppc64/rtas.h
--- a/include/asm-ppc64/rtas.h
+++ b/include/asm-ppc64/rtas.h
@@ -186,8 +186,14 @@ extern int rtas_get_sensor(int sensor, i
 extern int rtas_get_power_level(int powerdomain, int *level);
 extern int rtas_set_power_level(int powerdomain, int level, int *setlevel);
 extern int rtas_set_indicator(int indicator, int index, int new_value);
+extern void rtas_progress(char *s, unsigned short hex);
 extern void rtas_initialize(void);
 
+struct rtc_time;
+extern void rtas_get_boot_time(struct rtc_time *rtc_time);
+extern void rtas_get_rtc_time(struct rtc_time *rtc_time);
+extern int rtas_set_rtc_time(struct rtc_time *rtc_time);
+
 /* Given an RTAS status code of 9900..9905 compute the hinted delay */
 unsigned int rtas_extended_busy_delay_time(int status);
 static inline int rtas_is_extended_busy(int status)
diff --git a/include/asm-ppc64/smp.h b/include/asm-ppc64/smp.h
--- a/include/asm-ppc64/smp.h
+++ b/include/asm-ppc64/smp.h
@@ -45,7 +45,7 @@ void generic_cpu_die(unsigned int cpu);
 void generic_mach_cpu_die(void);
 #endif
 
-#define __smp_processor_id() (get_paca()->paca_index)
+#define raw_smp_processor_id()	(get_paca()->paca_index)
 #define hard_smp_processor_id() (get_paca()->hw_cpu_id)
 
 extern cpumask_t cpu_sibling_map[NR_CPUS];
@@ -85,6 +85,14 @@ extern void smp_generic_take_timebase(vo
 
 extern struct smp_ops_t *smp_ops;
 
+#ifdef CONFIG_PPC_PSERIES
+void vpa_init(int cpu);
+#else
+static inline void vpa_init(int cpu)
+{
+}
+#endif /* CONFIG_PPC_PSERIES */
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* !(_PPC64_SMP_H) */
diff --git a/include/asm-ppc64/sparsemem.h b/include/asm-ppc64/sparsemem.h
new file mode 100644
--- /dev/null
+++ b/include/asm-ppc64/sparsemem.h
@@ -0,0 +1,16 @@
+#ifndef _ASM_PPC64_SPARSEMEM_H
+#define _ASM_PPC64_SPARSEMEM_H 1
+
+#ifdef CONFIG_SPARSEMEM
+/*
+ * SECTION_SIZE_BITS		2^N: how big each section will be
+ * MAX_PHYSADDR_BITS		2^N: how much physical address space we have
+ * MAX_PHYSMEM_BITS		2^N: how much memory we can have in that space
+ */
+#define SECTION_SIZE_BITS       24
+#define MAX_PHYSADDR_BITS       38
+#define MAX_PHYSMEM_BITS        36
+
+#endif /* CONFIG_SPARSEMEM */
+
+#endif /* _ASM_PPC64_SPARSEMEM_H */
diff --git a/include/asm-ppc64/thread_info.h b/include/asm-ppc64/thread_info.h
--- a/include/asm-ppc64/thread_info.h
+++ b/include/asm-ppc64/thread_info.h
@@ -24,7 +24,7 @@ struct thread_info {
 	struct task_struct *task;		/* main task structure */
 	struct exec_domain *exec_domain;	/* execution domain */
 	int		cpu;			/* cpu we're on */
-	int		preempt_count;
+	int		preempt_count;		/* 0 => preemptable, <0 => BUG */
 	struct restart_block restart_block;
 	/* set by force_successful_syscall_return */
 	unsigned char	syscall_noerror;
diff --git a/include/asm-ppc64/time.h b/include/asm-ppc64/time.h
--- a/include/asm-ppc64/time.h
+++ b/include/asm-ppc64/time.h
@@ -34,6 +34,15 @@ struct rtc_time;
 extern void to_tm(int tim, struct rtc_time * tm);
 extern time_t last_rtc_update;
 
+void generic_calibrate_decr(void);
+void setup_default_decr(void);
+
+/* Some sane defaults: 125 MHz timebase, 1GHz processor */
+extern unsigned long ppc_proc_freq;
+#define DEFAULT_PROC_FREQ	(DEFAULT_TB_FREQ * 8)
+extern unsigned long ppc_tb_freq;
+#define DEFAULT_TB_FREQ		125000000UL
+
 /*
  * By putting all of this stuff into a single struct we 
  * reduce the number of cache lines touched by do_gettimeofday.
diff --git a/include/asm-ppc64/topology.h b/include/asm-ppc64/topology.h
--- a/include/asm-ppc64/topology.h
+++ b/include/asm-ppc64/topology.h
@@ -33,6 +33,7 @@ static inline int node_to_first_cpu(int 
 	return first_cpu(tmp);
 }
 
+#define pcibus_to_node(node)    (-1)
 #define pcibus_to_cpumask(bus)	(cpu_online_map)
 
 #define nr_cpus_node(node)	(nr_cpus_in_node[node])
@@ -59,7 +60,7 @@ static inline int node_to_first_cpu(int 
 	.nr_balance_failed	= 0,			\
 }
 
-#else /* !CONFIG_NUMA */
+#else
 
 #include <asm-generic/topology.h>
 
diff --git a/include/asm-ppc64/unistd.h b/include/asm-ppc64/unistd.h
--- a/include/asm-ppc64/unistd.h
+++ b/include/asm-ppc64/unistd.h
@@ -268,7 +268,7 @@
 #define __NR_rtas		255
 /* Number 256 is reserved for sys_debug_setcontext */
 /* Number 257 is reserved for vserver */
-/* Number 258 is reserved for new sys_remap_file_pages */
+/* 258 currently unused */
 #define __NR_mbind		259
 #define __NR_get_mempolicy	260
 #define __NR_set_mempolicy	261
@@ -283,8 +283,13 @@
 #define __NR_request_key	270
 #define __NR_keyctl		271
 #define __NR_waitid		272
+#define __NR_ioprio_set		273
+#define __NR_ioprio_get		274
+#define __NR_inotify_init	275
+#define __NR_inotify_add_watch	276
+#define __NR_inotify_rm_watch	277
 
-#define __NR_syscalls		273
+#define __NR_syscalls		278
 #ifdef __KERNEL__
 #define NR_syscalls	__NR_syscalls
 #endif
diff --git a/include/asm-ppc64/xics.h b/include/asm-ppc64/xics.h
--- a/include/asm-ppc64/xics.h
+++ b/include/asm-ppc64/xics.h
@@ -17,6 +17,7 @@
 void xics_init_IRQ(void);
 int xics_get_irq(struct pt_regs *);
 void xics_setup_cpu(void);
+void xics_teardown_cpu(int secondary);
 void xics_cause_IPI(int cpu);
 void xics_request_IPIs(void);
 void xics_migrate_irqs_away(void);
diff --git a/include/asm-s390/atomic.h b/include/asm-s390/atomic.h
--- a/include/asm-s390/atomic.h
+++ b/include/asm-s390/atomic.h
@@ -123,19 +123,19 @@ typedef struct {
 #define atomic64_read(v)          ((v)->counter)
 #define atomic64_set(v,i)         (((v)->counter) = (i))
 
-static __inline__ void atomic64_add(int i, atomic64_t * v)
+static __inline__ void atomic64_add(long long i, atomic64_t * v)
 {
 	       __CSG_LOOP(v, i, "agr");
 }
-static __inline__ long long atomic64_add_return(int i, atomic64_t * v)
+static __inline__ long long atomic64_add_return(long long i, atomic64_t * v)
 {
 	return __CSG_LOOP(v, i, "agr");
 }
-static __inline__ long long atomic64_add_negative(int i, atomic64_t * v)
+static __inline__ long long atomic64_add_negative(long long i, atomic64_t * v)
 {
 	return __CSG_LOOP(v, i, "agr") < 0;
 }
-static __inline__ void atomic64_sub(int i, atomic64_t * v)
+static __inline__ void atomic64_sub(long long i, atomic64_t * v)
 {
 	       __CSG_LOOP(v, i, "sgr");
 }
diff --git a/include/asm-s390/bitops.h b/include/asm-s390/bitops.h
--- a/include/asm-s390/bitops.h
+++ b/include/asm-s390/bitops.h
@@ -527,13 +527,64 @@ __constant_test_bit(unsigned long nr, co
  __constant_test_bit((nr),(addr)) : \
  __test_bit((nr),(addr)) )
 
-#ifndef __s390x__
+/*
+ * ffz = Find First Zero in word. Undefined if no zero exists,
+ * so code should check against ~0UL first..
+ */
+static inline unsigned long ffz(unsigned long word)
+{
+        unsigned long bit = 0;
+
+#ifdef __s390x__
+	if (likely((word & 0xffffffff) == 0xffffffff)) {
+		word >>= 32;
+		bit += 32;
+	}
+#endif
+	if (likely((word & 0xffff) == 0xffff)) {
+		word >>= 16;
+		bit += 16;
+	}
+	if (likely((word & 0xff) == 0xff)) {
+		word >>= 8;
+		bit += 8;
+	}
+	return bit + _zb_findmap[word & 0xff];
+}
+
+/*
+ * __ffs = find first bit in word. Undefined if no bit exists,
+ * so code should check against 0UL first..
+ */
+static inline unsigned long __ffs (unsigned long word)
+{
+	unsigned long bit = 0;
+
+#ifdef __s390x__
+	if (likely((word & 0xffffffff) == 0)) {
+		word >>= 32;
+		bit += 32;
+	}
+#endif
+	if (likely((word & 0xffff) == 0)) {
+		word >>= 16;
+		bit += 16;
+	}
+	if (likely((word & 0xff) == 0)) {
+		word >>= 8;
+		bit += 8;
+	}
+	return bit + _sb_findmap[word & 0xff];
+}
 
 /*
  * Find-bit routines..
  */
+
+#ifndef __s390x__
+
 static inline int
-find_first_zero_bit(const unsigned long * addr, unsigned int size)
+find_first_zero_bit(const unsigned long * addr, unsigned long size)
 {
 	typedef struct { long _[__BITOPS_WORDS(size)]; } addrtype;
 	unsigned long cmp, count;
@@ -548,7 +599,7 @@ find_first_zero_bit(const unsigned long 
                 "   srl  %2,5\n"
                 "0: c    %1,0(%0,%4)\n"
                 "   jne  1f\n"
-                "   ahi  %0,4\n"
+                "   la   %0,4(%0)\n"
                 "   brct %2,0b\n"
                 "   lr   %0,%3\n"
                 "   j    4f\n"
@@ -574,7 +625,7 @@ find_first_zero_bit(const unsigned long 
 }
 
 static inline int
-find_first_bit(const unsigned long * addr, unsigned int size)
+find_first_bit(const unsigned long * addr, unsigned long size)
 {
 	typedef struct { long _[__BITOPS_WORDS(size)]; } addrtype;
 	unsigned long cmp, count;
@@ -589,7 +640,7 @@ find_first_bit(const unsigned long * add
                 "   srl  %2,5\n"
                 "0: c    %1,0(%0,%4)\n"
                 "   jne  1f\n"
-                "   ahi  %0,4\n"
+                "   la   %0,4(%0)\n"
                 "   brct %2,0b\n"
                 "   lr   %0,%3\n"
                 "   j    4f\n"
@@ -614,89 +665,8 @@ find_first_bit(const unsigned long * add
         return (res < size) ? res : size;
 }
 
-static inline int
-find_next_zero_bit (const unsigned long * addr, int size, int offset)
-{
-        unsigned long * p = ((unsigned long *) addr) + (offset >> 5);
-        unsigned long bitvec, reg;
-        int set, bit = offset & 31, res;
-
-        if (bit) {
-                /*
-                 * Look for zero in first word
-                 */
-                bitvec = (*p) >> bit;
-                __asm__("   slr  %0,%0\n"
-                        "   lhi  %2,0xff\n"
-                        "   tml  %1,0xffff\n"
-                        "   jno  0f\n"
-                        "   ahi  %0,16\n"
-                        "   srl  %1,16\n"
-                        "0: tml  %1,0x00ff\n"
-                        "   jno  1f\n"
-                        "   ahi  %0,8\n"
-                        "   srl  %1,8\n"
-                        "1: nr   %1,%2\n"
-                        "   ic   %1,0(%1,%3)\n"
-                        "   alr  %0,%1"
-                        : "=&d" (set), "+a" (bitvec), "=&d" (reg)
-                        : "a" (&_zb_findmap) : "cc" );
-                if (set < (32 - bit))
-                        return set + offset;
-                offset += 32 - bit;
-                p++;
-        }
-        /*
-         * No zero yet, search remaining full words for a zero
-         */
-        res = find_first_zero_bit (p, size - 32 * (p - (unsigned long *) addr));
-        return (offset + res);
-}
-
-static inline int
-find_next_bit (const unsigned long * addr, int size, int offset)
-{
-        unsigned long * p = ((unsigned long *) addr) + (offset >> 5);
-        unsigned long bitvec, reg;
-        int set, bit = offset & 31, res;
-
-        if (bit) {
-                /*
-                 * Look for set bit in first word
-                 */
-                bitvec = (*p) >> bit;
-                __asm__("   slr  %0,%0\n"
-                        "   lhi  %2,0xff\n"
-                        "   tml  %1,0xffff\n"
-                        "   jnz  0f\n"
-                        "   ahi  %0,16\n"
-                        "   srl  %1,16\n"
-                        "0: tml  %1,0x00ff\n"
-                        "   jnz  1f\n"
-                        "   ahi  %0,8\n"
-                        "   srl  %1,8\n"
-                        "1: nr   %1,%2\n"
-                        "   ic   %1,0(%1,%3)\n"
-                        "   alr  %0,%1"
-                        : "=&d" (set), "+a" (bitvec), "=&d" (reg)
-                        : "a" (&_sb_findmap) : "cc" );
-                if (set < (32 - bit))
-                        return set + offset;
-                offset += 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 + res);
-}
-
 #else /* __s390x__ */
 
-/*
- * Find-bit routines..
- */
 static inline unsigned long
 find_first_zero_bit(const unsigned long * addr, unsigned long size)
 {
@@ -712,7 +682,7 @@ find_first_zero_bit(const unsigned long 
                 "   srlg  %2,%2,6\n"
                 "0: cg    %1,0(%0,%4)\n"
                 "   jne   1f\n"
-                "   aghi  %0,8\n"
+                "   la    %0,8(%0)\n"
                 "   brct  %2,0b\n"
                 "   lgr   %0,%3\n"
                 "   j     5f\n"
@@ -785,143 +755,66 @@ find_first_bit(const unsigned long * add
         return (res < size) ? res : size;
 }
 
-static inline unsigned long
-find_next_zero_bit (const unsigned long * addr, unsigned long size, unsigned long offset)
-{
-        unsigned long * p = ((unsigned long *) addr) + (offset >> 6);
-        unsigned long bitvec, reg;
-        unsigned long set, bit = offset & 63, res;
-
-        if (bit) {
-                /*
-                 * Look for zero in first word
-                 */
-                bitvec = (*p) >> bit;
-                __asm__("   lhi  %2,-1\n"
-                        "   slgr %0,%0\n"
-                        "   clr  %1,%2\n"
-                        "   jne  0f\n"
-                        "   aghi %0,32\n"
-                        "   srlg %1,%1,32\n"
-			"0: lghi %2,0xff\n"
-                        "   tmll %1,0xffff\n"
-                        "   jno  1f\n"
-                        "   aghi %0,16\n"
-                        "   srlg %1,%1,16\n"
-                        "1: tmll %1,0x00ff\n"
-                        "   jno  2f\n"
-                        "   aghi %0,8\n"
-                        "   srlg %1,%1,8\n"
-                        "2: ngr  %1,%2\n"
-                        "   ic   %1,0(%1,%3)\n"
-                        "   algr %0,%1"
-                        : "=&d" (set), "+a" (bitvec), "=&d" (reg)
-                        : "a" (&_zb_findmap) : "cc" );
-                if (set < (64 - bit))
-                        return set + offset;
-                offset += 64 - bit;
-                p++;
-        }
-        /*
-         * No zero yet, search remaining full words for a zero
-         */
-        res = find_first_zero_bit (p, size - 64 * (p - (unsigned long *) addr));
-        return (offset + res);
-}
-
-static inline unsigned long
-find_next_bit (const unsigned long * addr, unsigned long size, unsigned long offset)
-{
-        unsigned long * p = ((unsigned long *) addr) + (offset >> 6);
-        unsigned long bitvec, reg;
-        unsigned long set, bit = offset & 63, res;
-
-        if (bit) {
-                /*
-                 * Look for zero in first word
-                 */
-                bitvec = (*p) >> bit;
-                __asm__("   slgr %0,%0\n"
-                        "   ltr  %1,%1\n"
-                        "   jnz  0f\n"
-                        "   aghi %0,32\n"
-                        "   srlg %1,%1,32\n"
-			"0: lghi %2,0xff\n"
-                        "   tmll %1,0xffff\n"
-                        "   jnz  1f\n"
-                        "   aghi %0,16\n"
-                        "   srlg %1,%1,16\n"
-                        "1: tmll %1,0x00ff\n"
-                        "   jnz  2f\n"
-                        "   aghi %0,8\n"
-                        "   srlg %1,%1,8\n"
-                        "2: ngr  %1,%2\n"
-                        "   ic   %1,0(%1,%3)\n"
-                        "   algr %0,%1"
-                        : "=&d" (set), "+a" (bitvec), "=&d" (reg)
-                        : "a" (&_sb_findmap) : "cc" );
-                if (set < (64 - bit))
-                        return set + offset;
-                offset += 64 - bit;
-                p++;
-        }
-        /*
-         * No set bit yet, search remaining full words for a bit
-         */
-        res = find_first_bit (p, size - 64 * (p - (unsigned long *) addr));
-        return (offset + res);
-}
-
 #endif /* __s390x__ */
 
-/*
- * ffz = Find First Zero in word. Undefined if no zero exists,
- * so code should check against ~0UL first..
- */
-static inline unsigned long ffz(unsigned long word)
+static inline int
+find_next_zero_bit (const unsigned long * addr, unsigned long size,
+		    unsigned long offset)
 {
-        unsigned long bit = 0;
+        const unsigned long *p;
+	unsigned long bit, set;
 
-#ifdef __s390x__
-	if (likely((word & 0xffffffff) == 0xffffffff)) {
-		word >>= 32;
-		bit += 32;
+	if (offset >= size)
+		return size;
+	bit = offset & (__BITOPS_WORDSIZE - 1);
+	offset -= bit;
+	size -= offset;
+	p = addr + offset / __BITOPS_WORDSIZE;
+	if (bit) {
+		/*
+		 * s390 version of ffz returns __BITOPS_WORDSIZE
+		 * if no zero bit is present in the word.
+		 */
+		set = ffz(*p >> bit) + bit;
+		if (set >= size)
+			return size + offset;
+		if (set < __BITOPS_WORDSIZE)
+			return set + offset;
+		offset += __BITOPS_WORDSIZE;
+		size -= __BITOPS_WORDSIZE;
+		p++;
 	}
-#endif
-	if (likely((word & 0xffff) == 0xffff)) {
-		word >>= 16;
-		bit += 16;
-	}
-	if (likely((word & 0xff) == 0xff)) {
-		word >>= 8;
-		bit += 8;
-	}
-	return bit + _zb_findmap[word & 0xff];
+	return offset + find_first_zero_bit(p, size);
 }
 
-/*
- * __ffs = find first bit in word. Undefined if no bit exists,
- * so code should check against 0UL first..
- */
-static inline unsigned long __ffs (unsigned long word)
+static inline int
+find_next_bit (const unsigned long * addr, unsigned long size,
+	       unsigned long offset)
 {
-	unsigned long bit = 0;
+        const unsigned long *p;
+	unsigned long bit, set;
 
-#ifdef __s390x__
-	if (likely((word & 0xffffffff) == 0)) {
-		word >>= 32;
-		bit += 32;
+	if (offset >= size)
+		return size;
+	bit = offset & (__BITOPS_WORDSIZE - 1);
+	offset -= bit;
+	size -= offset;
+	p = addr + offset / __BITOPS_WORDSIZE;
+	if (bit) {
+		/*
+		 * s390 version of __ffs returns __BITOPS_WORDSIZE
+		 * if no one bit is present in the word.
+		 */
+		set = __ffs(*p & (~0UL << bit));
+		if (set >= size)
+			return size + offset;
+		if (set < __BITOPS_WORDSIZE)
+			return set + offset;
+		offset += __BITOPS_WORDSIZE;
+		size -= __BITOPS_WORDSIZE;
+		p++;
 	}
-#endif
-	if (likely((word & 0xffff) == 0)) {
-		word >>= 16;
-		bit += 16;
-	}
-	if (likely((word & 0xff) == 0)) {
-		word >>= 8;
-		bit += 8;
-	}
-	return bit + _sb_findmap[word & 0xff];
+	return offset + find_first_bit(p, size);
 }
 
 /*
@@ -1031,49 +924,6 @@ ext2_find_first_zero_bit(void *vaddr, un
         return (res < size) ? res : size;
 }
 
-static inline int 
-ext2_find_next_zero_bit(void *vaddr, unsigned int size, unsigned offset)
-{
-        unsigned long *addr = vaddr;
-        unsigned long *p = addr + (offset >> 5);
-        unsigned long word, reg;
-        unsigned int bit = offset & 31UL, res;
-
-        if (offset >= size)
-                return size;
-
-        if (bit) {
-                __asm__("   ic   %0,0(%1)\n"
-                        "   icm  %0,2,1(%1)\n"
-                        "   icm  %0,4,2(%1)\n"
-                        "   icm  %0,8,3(%1)"
-                        : "=&a" (word) : "a" (p) : "cc" );
-		word >>= bit;
-                res = bit;
-                /* Look for zero in first longword */
-                __asm__("   lhi  %2,0xff\n"
-                        "   tml  %1,0xffff\n"
-                	"   jno  0f\n"
-                	"   ahi  %0,16\n"
-                	"   srl  %1,16\n"
-                	"0: tml  %1,0x00ff\n"
-                	"   jno  1f\n"
-                	"   ahi  %0,8\n"
-                	"   srl  %1,8\n"
-                	"1: nr   %1,%2\n"
-                	"   ic   %1,0(%1,%3)\n"
-                	"   alr  %0,%1"
-                	: "+&d" (res), "+&a" (word), "=&d" (reg)
-                  	: "a" (&_zb_findmap) : "cc" );
-                if (res < 32)
-			return (p - addr)*32 + res;
-                p++;
-        }
-        /* No zero yet, search remaining full bytes for a zero */
-        res = ext2_find_first_zero_bit (p, size - 32 * (p - addr));
-        return (p - addr) * 32 + res;
-}
-
 #else /* __s390x__ */
 
 static inline unsigned long
@@ -1120,56 +970,46 @@ ext2_find_first_zero_bit(void *vaddr, un
         return (res < size) ? res : size;
 }
 
-static inline unsigned long
+#endif /* __s390x__ */
+
+static inline int
 ext2_find_next_zero_bit(void *vaddr, unsigned long size, unsigned long offset)
 {
-        unsigned long *addr = vaddr;
-        unsigned long *p = addr + (offset >> 6);
-        unsigned long word, reg;
-        unsigned long bit = offset & 63UL, res;
+        unsigned long *addr = vaddr, *p;
+	unsigned long word, bit, set;
 
         if (offset >= size)
                 return size;
-
+	bit = offset & (__BITOPS_WORDSIZE - 1);
+	offset -= bit;
+	size -= offset;
+	p = addr + offset / __BITOPS_WORDSIZE;
         if (bit) {
-                __asm__("   lrvg %0,%1" /* load reversed, neat instruction */
-                        : "=a" (word) : "m" (*p) );
-                word >>= bit;
-                res = bit;
-                /* Look for zero in first 8 byte word */
-                __asm__("   lghi %2,0xff\n"
-			"   tmll %1,0xffff\n"
-			"   jno  2f\n"
-			"   ahi  %0,16\n"
-			"   srlg %1,%1,16\n"
-                	"0: tmll %1,0xffff\n"
-                        "   jno  2f\n"
-                        "   ahi  %0,16\n"
-                        "   srlg %1,%1,16\n"
-                        "1: tmll %1,0xffff\n"
-                        "   jno  2f\n"
-                        "   ahi  %0,16\n"
-                        "   srl  %1,16\n"
-                        "2: tmll %1,0x00ff\n"
-                	"   jno  3f\n"
-                	"   ahi  %0,8\n"
-                	"   srl  %1,8\n"
-                	"3: ngr  %1,%2\n"
-                	"   ic   %1,0(%1,%3)\n"
-                	"   alr  %0,%1"
-                	: "+&d" (res), "+a" (word), "=&d" (reg)
-                  	: "a" (&_zb_findmap) : "cc" );
-                if (res < 64)
-			return (p - addr)*64 + res;
-                p++;
+#ifndef __s390x__
+                asm("   ic   %0,0(%1)\n"
+		    "   icm  %0,2,1(%1)\n"
+		    "   icm  %0,4,2(%1)\n"
+		    "   icm  %0,8,3(%1)"
+		    : "=&a" (word) : "a" (p), "m" (*p) : "cc" );
+#else
+                asm("   lrvg %0,%1" : "=a" (word) : "m" (*p) );
+#endif
+		/*
+		 * s390 version of ffz returns __BITOPS_WORDSIZE
+		 * if no zero bit is present in the word.
+		 */
+		set = ffz(word >> bit) + bit;
+		if (set >= size)
+			return size + offset;
+		if (set < __BITOPS_WORDSIZE)
+			return set + offset;
+		offset += __BITOPS_WORDSIZE;
+		size -= __BITOPS_WORDSIZE;
+		p++;
         }
-        /* No zero yet, search remaining full bytes for a zero */
-        res = ext2_find_first_zero_bit (p, size - 64 * (p - addr));
-        return (p - addr) * 64 + res;
+	return offset + ext2_find_first_zero_bit(p, size);
 }
 
-#endif /* __s390x__ */
-
 /* Bitmap functions for the minix filesystem.  */
 /* FIXME !!! */
 #define minix_test_and_set_bit(nr,addr) \
diff --git a/include/asm-s390/cpcmd.h b/include/asm-s390/cpcmd.h
--- a/include/asm-s390/cpcmd.h
+++ b/include/asm-s390/cpcmd.h
@@ -11,14 +11,28 @@
 #define __CPCMD__
 
 /*
+ * the lowlevel function for cpcmd
  * the caller of __cpcmd has to ensure that the response buffer is below 2 GB
  */
-extern void __cpcmd(char *cmd, char *response, int rlen);
+extern int __cpcmd(const char *cmd, char *response, int rlen, int *response_code);
 
 #ifndef __s390x__
 #define cpcmd __cpcmd
 #else
-extern void cpcmd(char *cmd, char *response, int rlen);
+/*
+ * cpcmd is the in-kernel interface for issuing CP commands
+ *
+ * cmd:		null-terminated command string, max 240 characters
+ * response:	response buffer for VM's textual response
+ * rlen:	size of the response buffer, cpcmd will not exceed this size
+ *		but will cap the output, if its too large. Everything that
+ *		did not fit into the buffer will be silently dropped
+ * response_code: return pointer for VM's error code
+ * return value: the size of the response. The caller can check if the buffer
+ *		was large enough by comparing the return value and rlen
+ * NOTE: If the response buffer is not below 2 GB, cpcmd can sleep
+ */
+extern int cpcmd(const char *cmd, char *response, int rlen, int *response_code);
 #endif /*__s390x__*/
 
 #endif
diff --git a/include/asm-s390/debug.h b/include/asm-s390/debug.h
--- a/include/asm-s390/debug.h
+++ b/include/asm-s390/debug.h
@@ -9,6 +9,8 @@
 #ifndef DEBUG_H
 #define DEBUG_H
 
+#include <linux/config.h>
+#include <linux/fs.h>
 #include <linux/string.h>
 
 /* Note:
@@ -31,19 +33,18 @@ struct __debug_entry{
 } __attribute__((packed));
 
 
-#define __DEBUG_FEATURE_VERSION      1  /* version of debug feature */
+#define __DEBUG_FEATURE_VERSION      2  /* version of debug feature */
 
 #ifdef __KERNEL__
 #include <linux/spinlock.h>
 #include <linux/kernel.h>
 #include <linux/time.h>
-#include <linux/proc_fs.h>
 
 #define DEBUG_MAX_LEVEL            6  /* debug levels range from 0 to 6 */
 #define DEBUG_OFF_LEVEL            -1 /* level where debug is switched off */
 #define DEBUG_FLUSH_ALL            -1 /* parameter to flush all areas */
 #define DEBUG_MAX_VIEWS            10 /* max number of views in proc fs */
-#define DEBUG_MAX_PROCF_LEN        64 /* max length for a proc file name */
+#define DEBUG_MAX_NAME_LEN         64 /* max length for a debugfs file name */
 #define DEBUG_DEFAULT_LEVEL        3  /* initial debug level */
 
 #define DEBUG_DIR_ROOT "s390dbf" /* name of debug root directory in proc fs */
@@ -64,16 +65,17 @@ typedef struct debug_info {	
 	spinlock_t lock;			
 	int level;
 	int nr_areas;
-	int page_order;
+	int pages_per_area;
 	int buf_size;
 	int entry_size;	
-	debug_entry_t** areas;
+	debug_entry_t*** areas;
 	int active_area;
-	int *active_entry;
-	struct proc_dir_entry* proc_root_entry;
-	struct proc_dir_entry* proc_entries[DEBUG_MAX_VIEWS];
+	int *active_pages;
+	int *active_entries;
+	struct dentry* debugfs_root_entry;
+	struct dentry* debugfs_entries[DEBUG_MAX_VIEWS];
 	struct debug_view* views[DEBUG_MAX_VIEWS];	
-	char name[DEBUG_MAX_PROCF_LEN];
+	char name[DEBUG_MAX_NAME_LEN];
 } debug_info_t;
 
 typedef int (debug_header_proc_t) (debug_info_t* id,
@@ -98,7 +100,7 @@ int debug_dflt_header_fn(debug_info_t* i
 		         int area, debug_entry_t* entry, char* out_buf);						
 				
 struct debug_view {
-	char name[DEBUG_MAX_PROCF_LEN];
+	char name[DEBUG_MAX_NAME_LEN];
 	debug_prolog_proc_t* prolog_proc;
 	debug_header_proc_t* header_proc;
 	debug_format_proc_t* format_proc;
@@ -120,7 +122,7 @@ debug_entry_t* debug_exception_common(de
 
 /* Debug Feature API: */
 
-debug_info_t* debug_register(char* name, int pages_index, int nr_areas,
+debug_info_t* debug_register(char* name, int pages, int nr_areas,
                              int buf_size);
 
 void debug_unregister(debug_info_t* id);
@@ -132,7 +134,8 @@ void debug_stop_all(void);
 extern inline debug_entry_t* 
 debug_event(debug_info_t* id, int level, void* data, int length)
 {
-	if ((!id) || (level > id->level)) return NULL;
+	if ((!id) || (level > id->level) || (id->pages_per_area == 0))
+		return NULL;
         return debug_event_common(id,level,data,length);
 }
 
@@ -140,7 +143,8 @@ extern inline debug_entry_t* 
 debug_int_event(debug_info_t* id, int level, unsigned int tag)
 {
         unsigned int t=tag;
-	if ((!id) || (level > id->level)) return NULL;
+	if ((!id) || (level > id->level) || (id->pages_per_area == 0))
+		return NULL;
         return debug_event_common(id,level,&t,sizeof(unsigned int));
 }
 
@@ -148,14 +152,16 @@ extern inline debug_entry_t *
 debug_long_event (debug_info_t* id, int level, unsigned long tag)
 {
         unsigned long t=tag;
-	if ((!id) || (level > id->level)) return NULL;
+	if ((!id) || (level > id->level) || (id->pages_per_area == 0))
+		return NULL;
         return debug_event_common(id,level,&t,sizeof(unsigned long));
 }
 
 extern inline debug_entry_t* 
 debug_text_event(debug_info_t* id, int level, const char* txt)
 {
-	if ((!id) || (level > id->level)) return NULL;
+	if ((!id) || (level > id->level) || (id->pages_per_area == 0))
+		return NULL;
         return debug_event_common(id,level,txt,strlen(txt));
 }
 
@@ -167,7 +173,8 @@ debug_sprintf_event(debug_info_t* id,int
 extern inline debug_entry_t* 
 debug_exception(debug_info_t* id, int level, void* data, int length)
 {
-	if ((!id) || (level > id->level)) return NULL;
+	if ((!id) || (level > id->level) || (id->pages_per_area == 0))
+		return NULL;
         return debug_exception_common(id,level,data,length);
 }
 
@@ -175,7 +182,8 @@ extern inline debug_entry_t* 
 debug_int_exception(debug_info_t* id, int level, unsigned int tag)
 {
         unsigned int t=tag;
-	if ((!id) || (level > id->level)) return NULL;
+	if ((!id) || (level > id->level) || (id->pages_per_area == 0))
+		return NULL;
         return debug_exception_common(id,level,&t,sizeof(unsigned int));
 }
 
@@ -183,14 +191,16 @@ extern inline debug_entry_t * 
 debug_long_exception (debug_info_t* id, int level, unsigned long tag)
 {
         unsigned long t=tag;
-	if ((!id) || (level > id->level)) return NULL;
+	if ((!id) || (level > id->level) || (id->pages_per_area == 0))
+		return NULL;
         return debug_exception_common(id,level,&t,sizeof(unsigned long));
 }
 
 extern inline debug_entry_t* 
 debug_text_exception(debug_info_t* id, int level, const char* txt)
 {
-	if ((!id) || (level > id->level)) return NULL;
+	if ((!id) || (level > id->level) || (id->pages_per_area == 0))
+		return NULL;
         return debug_exception_common(id,level,txt,strlen(txt));
 }
 
diff --git a/include/asm-s390/emergency-restart.h b/include/asm-s390/emergency-restart.h
new file mode 100644
--- /dev/null
+++ b/include/asm-s390/emergency-restart.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_EMERGENCY_RESTART_H
+#define _ASM_EMERGENCY_RESTART_H
+
+#include <asm-generic/emergency-restart.h>
+
+#endif /* _ASM_EMERGENCY_RESTART_H */
diff --git a/include/asm-s390/kexec.h b/include/asm-s390/kexec.h
new file mode 100644
--- /dev/null
+++ b/include/asm-s390/kexec.h
@@ -0,0 +1,42 @@
+/*
+ * include/asm-s390/kexec.h
+ *
+ * (C) Copyright IBM Corp. 2005
+ *
+ * Author(s): Rolf Adelsberger <adelsberger@de.ibm.com>
+ *
+ */
+
+#ifndef _S390_KEXEC_H
+#define _S390_KEXEC_H
+
+#include <asm/page.h>
+#include <asm/processor.h>
+/*
+ * KEXEC_SOURCE_MEMORY_LIMIT maximum page get_free_page can return.
+ * I.e. Maximum page that is mapped directly into kernel memory,
+ * and kmap is not required.
+ */
+
+/* Maximum physical address we can use pages from */
+#define KEXEC_SOURCE_MEMORY_LIMIT (-1UL)
+
+/* Maximum address we can reach in physical address mode */
+#define KEXEC_DESTINATION_MEMORY_LIMIT (-1UL)
+
+/* Maximum address we can use for the control pages */
+/* Not more than 2GB */
+#define KEXEC_CONTROL_MEMORY_LIMIT (1<<31)
+
+/* Allocate one page for the pdp and the second for the code */
+#define KEXEC_CONTROL_CODE_SIZE 4096
+
+/* The native architecture */
+#define KEXEC_ARCH KEXEC_ARCH_S390
+
+#define MAX_NOTE_BYTES 1024
+typedef u32 note_buf_t[MAX_NOTE_BYTES/4];
+
+extern note_buf_t crash_notes[];
+
+#endif /*_S390_KEXEC_H */
diff --git a/include/asm-s390/lowcore.h b/include/asm-s390/lowcore.h
--- a/include/asm-s390/lowcore.h
+++ b/include/asm-s390/lowcore.h
@@ -90,7 +90,6 @@
 #define __LC_SYSTEM_TIMER		0x278
 #define __LC_LAST_UPDATE_CLOCK		0x280
 #define __LC_STEAL_CLOCK		0x288
-#define __LC_DIAG44_OPCODE		0x290
 #define __LC_KERNEL_STACK               0xD40
 #define __LC_THREAD_INFO		0xD48
 #define __LC_ASYNC_STACK                0xD50
@@ -109,10 +108,14 @@
 
 #ifndef __s390x__
 #define __LC_PFAULT_INTPARM             0x080
+#define __LC_CPU_TIMER_SAVE_AREA        0x0D8
 #define __LC_AREGS_SAVE_AREA            0x120
+#define __LC_GPREGS_SAVE_AREA           0x180
 #define __LC_CREGS_SAVE_AREA            0x1C0
 #else /* __s390x__ */
 #define __LC_PFAULT_INTPARM             0x11B8
+#define __LC_GPREGS_SAVE_AREA           0x1280
+#define __LC_CPU_TIMER_SAVE_AREA        0x1328
 #define __LC_AREGS_SAVE_AREA            0x1340
 #define __LC_CREGS_SAVE_AREA            0x1380
 #endif /* __s390x__ */
@@ -167,7 +170,8 @@ struct _lowcore
 	__u16        subchannel_nr;            /* 0x0ba */
 	__u32        io_int_parm;              /* 0x0bc */
 	__u32        io_int_word;              /* 0x0c0 */
-        __u8         pad3[0xD8-0xC4];          /* 0x0c4 */
+        __u8         pad3[0xD4-0xC4];          /* 0x0c4 */
+	__u32        extended_save_area_addr;  /* 0x0d4 */
 	__u32        cpu_timer_save_area[2];   /* 0x0d8 */
 	__u32        clock_comp_save_area[2];  /* 0x0e0 */
 	__u32        mcck_interruption_code[2]; /* 0x0e8 */
@@ -281,8 +285,7 @@ struct _lowcore
 	__u64        system_timer;             /* 0x278 */
 	__u64        last_update_clock;        /* 0x280 */
 	__u64        steal_clock;              /* 0x288 */
-	__u32        diag44_opcode;            /* 0x290 */
-        __u8         pad8[0xc00-0x294];        /* 0x294 */
+        __u8         pad8[0xc00-0x290];        /* 0x290 */
         /* System info area */
 	__u64        save_area[16];            /* 0xc00 */
         __u8         pad9[0xd40-0xc80];        /* 0xc80 */
diff --git a/include/asm-s390/processor.h b/include/asm-s390/processor.h
--- a/include/asm-s390/processor.h
+++ b/include/asm-s390/processor.h
@@ -203,10 +203,25 @@ unsigned long get_wchan(struct task_stru
 # define cpu_relax()	asm volatile ("diag 0,0,68" : : : "memory")
 #else /* __s390x__ */
 # define cpu_relax() \
-	asm volatile ("ex 0,%0" : : "i" (__LC_DIAG44_OPCODE) : "memory")
+	do { \
+		if (MACHINE_HAS_DIAG44) \
+			asm volatile ("diag 0,0,68" : : : "memory"); \
+	} while (0)
 #endif /* __s390x__ */
 
 /*
+ * Set PSW to specified value.
+ */
+static inline void __load_psw(psw_t psw)
+{
+#ifndef __s390x__
+	asm volatile ("lpsw  0(%0)" : : "a" (&psw), "m" (psw) : "cc" );
+#else
+	asm volatile ("lpswe 0(%0)" : : "a" (&psw), "m" (psw) : "cc" );
+#endif
+}
+
+/*
  * Set PSW mask to specified value, while leaving the
  * PSW addr pointing to the next instruction.
  */
@@ -214,8 +229,8 @@ unsigned long get_wchan(struct task_stru
 static inline void __load_psw_mask (unsigned long mask)
 {
 	unsigned long addr;
-
 	psw_t psw;
+
 	psw.mask = mask;
 
 #ifndef __s390x__
@@ -241,30 +256,8 @@ static inline void __load_psw_mask (unsi
  */
 static inline void enabled_wait(void)
 {
-	unsigned long reg;
-	psw_t wait_psw;
-
-	wait_psw.mask = PSW_BASE_BITS | PSW_MASK_IO | PSW_MASK_EXT |
-		PSW_MASK_MCHECK | PSW_MASK_WAIT | PSW_DEFAULT_KEY;
-#ifndef __s390x__
-	asm volatile (
-		"    basr %0,0\n"
-		"0:  la   %0,1f-0b(%0)\n"
-		"    st   %0,4(%1)\n"
-		"    oi   4(%1),0x80\n"
-		"    lpsw 0(%1)\n"
-		"1:"
-		: "=&a" (reg) : "a" (&wait_psw), "m" (wait_psw)
-		: "memory", "cc" );
-#else /* __s390x__ */
-	asm volatile (
-		"    larl  %0,0f\n"
-		"    stg   %0,8(%1)\n"
-		"    lpswe 0(%1)\n"
-		"0:"
-		: "=&a" (reg) : "a" (&wait_psw), "m" (wait_psw)
-		: "memory", "cc" );
-#endif /* __s390x__ */
+	__load_psw_mask(PSW_BASE_BITS | PSW_MASK_IO | PSW_MASK_EXT |
+			PSW_MASK_MCHECK | PSW_MASK_WAIT | PSW_DEFAULT_KEY);
 }
 
 /*
@@ -273,13 +266,11 @@ static inline void enabled_wait(void)
 
 static inline void disabled_wait(unsigned long code)
 {
-        char psw_buffer[2*sizeof(psw_t)];
         unsigned long ctl_buf;
-        psw_t *dw_psw = (psw_t *)(((unsigned long) &psw_buffer+sizeof(psw_t)-1)
-                                  & -sizeof(psw_t));
+        psw_t dw_psw;
 
-        dw_psw->mask = PSW_BASE_BITS | PSW_MASK_WAIT;
-        dw_psw->addr = code;
+        dw_psw.mask = PSW_BASE_BITS | PSW_MASK_WAIT;
+        dw_psw.addr = code;
         /* 
          * Store status and then load disabled wait psw,
          * the processor is dead afterwards
@@ -301,7 +292,7 @@ static inline void disabled_wait(unsigne
                       "    oi    0x1c0,0x10\n" /* fake protection bit */
                       "    lpsw 0(%1)"
                       : "=m" (ctl_buf)
-		      : "a" (dw_psw), "a" (&ctl_buf), "m" (dw_psw) : "cc" );
+		      : "a" (&dw_psw), "a" (&ctl_buf), "m" (dw_psw) : "cc" );
 #else /* __s390x__ */
         asm volatile ("    stctg 0,0,0(%2)\n"
                       "    ni    4(%2),0xef\n" /* switch off protection */
@@ -333,7 +324,7 @@ static inline void disabled_wait(unsigne
                       "    oi    0x384(1),0x10\n" /* fake protection bit */
                       "    lpswe 0(%1)"
                       : "=m" (ctl_buf)
-		      : "a" (dw_psw), "a" (&ctl_buf),
+		      : "a" (&dw_psw), "a" (&ctl_buf),
 		        "m" (dw_psw) : "cc", "0", "1");
 #endif /* __s390x__ */
 }
diff --git a/include/asm-s390/ptrace.h b/include/asm-s390/ptrace.h
--- a/include/asm-s390/ptrace.h
+++ b/include/asm-s390/ptrace.h
@@ -276,7 +276,7 @@ typedef struct 
 #endif /* __s390x__ */
 
 #define PSW_KERNEL_BITS	(PSW_BASE_BITS | PSW_MASK_DAT | PSW_ASC_PRIMARY | \
-			 PSW_DEFAULT_KEY)
+			 PSW_MASK_MCHECK | PSW_DEFAULT_KEY)
 #define PSW_USER_BITS	(PSW_BASE_BITS | PSW_MASK_DAT | PSW_ASC_HOME | \
 			 PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK | \
 			 PSW_MASK_PSTATE | PSW_DEFAULT_KEY)
diff --git a/include/asm-s390/smp.h b/include/asm-s390/smp.h
--- a/include/asm-s390/smp.h
+++ b/include/asm-s390/smp.h
@@ -47,7 +47,7 @@ extern int smp_call_function_on(void (*f
  
 #define PROC_CHANGE_PENALTY	20		/* Schedule penalty */
 
-#define smp_processor_id() (S390_lowcore.cpu_data.cpu_nr)
+#define raw_smp_processor_id()	(S390_lowcore.cpu_data.cpu_nr)
 
 extern int smp_get_cpu(cpumask_t cpu_map);
 extern void smp_put_cpu(int cpu);
diff --git a/include/asm-s390/spinlock.h b/include/asm-s390/spinlock.h
--- a/include/asm-s390/spinlock.h
+++ b/include/asm-s390/spinlock.h
@@ -11,21 +11,16 @@
 #ifndef __ASM_SPINLOCK_H
 #define __ASM_SPINLOCK_H
 
-#ifdef __s390x__
-/*
- * Grmph, take care of %&#! user space programs that include
- * asm/spinlock.h. The diagnose is only available in kernel
- * context.
- */
-#ifdef __KERNEL__
-#include <asm/lowcore.h>
-#define __DIAG44_INSN "ex"
-#define __DIAG44_OPERAND __LC_DIAG44_OPCODE
-#else
-#define __DIAG44_INSN "#"
-#define __DIAG44_OPERAND 0
-#endif
-#endif /* __s390x__ */
+static inline int
+_raw_compare_and_swap(volatile unsigned int *lock,
+		      unsigned int old, unsigned int new)
+{
+	asm volatile ("cs %0,%3,0(%4)"
+		      : "=d" (old), "=m" (*lock)
+		      : "0" (old), "d" (new), "a" (lock), "m" (*lock)
+		      : "cc", "memory" );
+	return old;
+}
 
 /*
  * Simple spin lock operations.  There are two variants, one clears IRQ's
@@ -41,58 +36,35 @@ typedef struct {
 #endif
 } __attribute__ ((aligned (4))) spinlock_t;
 
-#define SPIN_LOCK_UNLOCKED (spinlock_t) { 0 }
-#define spin_lock_init(lp) do { (lp)->lock = 0; } while(0)
+#define SPIN_LOCK_UNLOCKED	(spinlock_t) { 0 }
+#define spin_lock_init(lp)	do { (lp)->lock = 0; } while(0)
 #define spin_unlock_wait(lp)	do { barrier(); } while(((volatile spinlock_t *)(lp))->lock)
-#define spin_is_locked(x) ((x)->lock != 0)
+#define spin_is_locked(x)	((x)->lock != 0)
 #define _raw_spin_lock_flags(lock, flags) _raw_spin_lock(lock)
 
-extern inline void _raw_spin_lock(spinlock_t *lp)
+extern void _raw_spin_lock_wait(spinlock_t *lp, unsigned int pc);
+extern int _raw_spin_trylock_retry(spinlock_t *lp, unsigned int pc);
+
+static inline void _raw_spin_lock(spinlock_t *lp)
 {
-#ifndef __s390x__
-	unsigned int reg1, reg2;
-        __asm__ __volatile__("    bras  %0,1f\n"
-                           "0:  diag  0,0,68\n"
-                           "1:  slr   %1,%1\n"
-                           "    cs    %1,%0,0(%3)\n"
-                           "    jl    0b\n"
-                           : "=&d" (reg1), "=&d" (reg2), "=m" (lp->lock)
-			   : "a" (&lp->lock), "m" (lp->lock)
-			   : "cc", "memory" );
-#else /* __s390x__ */
-	unsigned long reg1, reg2;
-        __asm__ __volatile__("    bras  %1,1f\n"
-                           "0:  " __DIAG44_INSN " 0,%4\n"
-                           "1:  slr   %0,%0\n"
-                           "    cs    %0,%1,0(%3)\n"
-                           "    jl    0b\n"
-                           : "=&d" (reg1), "=&d" (reg2), "=m" (lp->lock)
-			   : "a" (&lp->lock), "i" (__DIAG44_OPERAND),
-			     "m" (lp->lock) : "cc", "memory" );
-#endif /* __s390x__ */
-}
-
-extern inline int _raw_spin_trylock(spinlock_t *lp)
-{
-	unsigned long reg;
-	unsigned int result;
-
-	__asm__ __volatile__("    basr  %1,0\n"
-			   "0:  cs    %0,%1,0(%3)"
-			   : "=d" (result), "=&d" (reg), "=m" (lp->lock)
-			   : "a" (&lp->lock), "m" (lp->lock), "0" (0)
-			   : "cc", "memory" );
-	return !result;
+	unsigned long pc = (unsigned long) __builtin_return_address(0);
+
+	if (unlikely(_raw_compare_and_swap(&lp->lock, 0, pc) != 0))
+		_raw_spin_lock_wait(lp, pc);
 }
 
-extern inline void _raw_spin_unlock(spinlock_t *lp)
+static inline int _raw_spin_trylock(spinlock_t *lp)
 {
-	unsigned int old;
+	unsigned long pc = (unsigned long) __builtin_return_address(0);
 
-	__asm__ __volatile__("cs %0,%3,0(%4)"
-			   : "=d" (old), "=m" (lp->lock)
-			   : "0" (lp->lock), "d" (0), "a" (lp)
-			   : "cc", "memory" );
+	if (likely(_raw_compare_and_swap(&lp->lock, 0, pc) == 0))
+		return 1;
+	return _raw_spin_trylock_retry(lp, pc);
+}
+
+static inline void _raw_spin_unlock(spinlock_t *lp)
+{
+	_raw_compare_and_swap(&lp->lock, lp->lock, 0);
 }
 		
 /*
@@ -106,7 +78,7 @@ extern inline void _raw_spin_unlock(spin
  * read-locks.
  */
 typedef struct {
-	volatile unsigned long lock;
+	volatile unsigned int lock;
 	volatile unsigned long owner_pc;
 #ifdef CONFIG_PREEMPT
 	unsigned int break_lock;
@@ -129,123 +101,55 @@ typedef struct {
  */
 #define write_can_lock(x) ((x)->lock == 0)
 
-#ifndef __s390x__
-#define _raw_read_lock(rw)   \
-        asm volatile("   l     2,0(%1)\n"   \
-                     "   j     1f\n"     \
-                     "0: diag  0,0,68\n" \
-                     "1: la    2,0(2)\n"     /* clear high (=write) bit */ \
-                     "   la    3,1(2)\n"     /* one more reader */ \
-                     "   cs    2,3,0(%1)\n"  /* try to write new value */ \
-                     "   jl    0b"       \
-                     : "=m" ((rw)->lock) : "a" (&(rw)->lock), \
-		       "m" ((rw)->lock) : "2", "3", "cc", "memory" )
-#else /* __s390x__ */
-#define _raw_read_lock(rw)   \
-        asm volatile("   lg    2,0(%1)\n"   \
-                     "   j     1f\n"     \
-                     "0: " __DIAG44_INSN " 0,%2\n" \
-                     "1: nihh  2,0x7fff\n" /* clear high (=write) bit */ \
-                     "   la    3,1(2)\n"   /* one more reader */  \
-                     "   csg   2,3,0(%1)\n" /* try to write new value */ \
-                     "   jl    0b"       \
-                     : "=m" ((rw)->lock) \
-		     : "a" (&(rw)->lock), "i" (__DIAG44_OPERAND), \
-		       "m" ((rw)->lock) : "2", "3", "cc", "memory" )
-#endif /* __s390x__ */
-
-#ifndef __s390x__
-#define _raw_read_unlock(rw) \
-        asm volatile("   l     2,0(%1)\n"   \
-                     "   j     1f\n"     \
-                     "0: diag  0,0,68\n" \
-                     "1: lr    3,2\n"    \
-                     "   ahi   3,-1\n"    /* one less reader */ \
-                     "   cs    2,3,0(%1)\n" \
-                     "   jl    0b"       \
-                     : "=m" ((rw)->lock) : "a" (&(rw)->lock), \
-		       "m" ((rw)->lock) : "2", "3", "cc", "memory" )
-#else /* __s390x__ */
-#define _raw_read_unlock(rw) \
-        asm volatile("   lg    2,0(%1)\n"   \
-                     "   j     1f\n"     \
-                     "0: " __DIAG44_INSN " 0,%2\n" \
-                     "1: lgr   3,2\n"    \
-                     "   bctgr 3,0\n"    /* one less reader */ \
-                     "   csg   2,3,0(%1)\n" \
-                     "   jl    0b"       \
-                     : "=m" ((rw)->lock) \
-		     : "a" (&(rw)->lock), "i" (__DIAG44_OPERAND), \
-		       "m" ((rw)->lock) : "2", "3", "cc", "memory" )
-#endif /* __s390x__ */
-
-#ifndef __s390x__
-#define _raw_write_lock(rw) \
-        asm volatile("   lhi   3,1\n"    \
-                     "   sll   3,31\n"    /* new lock value = 0x80000000 */ \
-                     "   j     1f\n"     \
-                     "0: diag  0,0,68\n" \
-                     "1: slr   2,2\n"     /* old lock value must be 0 */ \
-                     "   cs    2,3,0(%1)\n" \
-                     "   jl    0b"       \
-                     : "=m" ((rw)->lock) : "a" (&(rw)->lock), \
-		       "m" ((rw)->lock) : "2", "3", "cc", "memory" )
-#else /* __s390x__ */
-#define _raw_write_lock(rw) \
-        asm volatile("   llihh 3,0x8000\n" /* new lock value = 0x80...0 */ \
-                     "   j     1f\n"       \
-                     "0: " __DIAG44_INSN " 0,%2\n"   \
-                     "1: slgr  2,2\n"      /* old lock value must be 0 */ \
-                     "   csg   2,3,0(%1)\n" \
-                     "   jl    0b"         \
-                     : "=m" ((rw)->lock) \
-		     : "a" (&(rw)->lock), "i" (__DIAG44_OPERAND), \
-		       "m" ((rw)->lock) : "2", "3", "cc", "memory" )
-#endif /* __s390x__ */
-
-#ifndef __s390x__
-#define _raw_write_unlock(rw) \
-        asm volatile("   slr   3,3\n"     /* new lock value = 0 */ \
-                     "   j     1f\n"     \
-                     "0: diag  0,0,68\n" \
-                     "1: lhi   2,1\n"    \
-                     "   sll   2,31\n"    /* old lock value must be 0x80000000 */ \
-                     "   cs    2,3,0(%1)\n" \
-                     "   jl    0b"       \
-                     : "=m" ((rw)->lock) : "a" (&(rw)->lock), \
-		       "m" ((rw)->lock) : "2", "3", "cc", "memory" )
-#else /* __s390x__ */
-#define _raw_write_unlock(rw) \
-        asm volatile("   slgr  3,3\n"      /* new lock value = 0 */ \
-                     "   j     1f\n"       \
-                     "0: " __DIAG44_INSN " 0,%2\n"   \
-                     "1: llihh 2,0x8000\n" /* old lock value must be 0x8..0 */\
-                     "   csg   2,3,0(%1)\n"   \
-                     "   jl    0b"         \
-                     : "=m" ((rw)->lock) \
-		     : "a" (&(rw)->lock), "i" (__DIAG44_OPERAND), \
-		       "m" ((rw)->lock) : "2", "3", "cc", "memory" )
-#endif /* __s390x__ */
-
-#define _raw_read_trylock(lock) generic_raw_read_trylock(lock)
-
-extern inline int _raw_write_trylock(rwlock_t *rw)
-{
-	unsigned long result, reg;
-	
-	__asm__ __volatile__(
-#ifndef __s390x__
-			     "   lhi  %1,1\n"
-			     "   sll  %1,31\n"
-			     "   cs   %0,%1,0(%3)"
-#else /* __s390x__ */
-			     "   llihh %1,0x8000\n"
-			     "0: csg %0,%1,0(%3)\n"
-#endif /* __s390x__ */
-			     : "=d" (result), "=&d" (reg), "=m" (rw->lock)
-			     : "a" (&rw->lock), "m" (rw->lock), "0" (0UL)
-			     : "cc", "memory" );
-	return result == 0;
+extern void _raw_read_lock_wait(rwlock_t *lp);
+extern int _raw_read_trylock_retry(rwlock_t *lp);
+extern void _raw_write_lock_wait(rwlock_t *lp);
+extern int _raw_write_trylock_retry(rwlock_t *lp);
+
+static inline void _raw_read_lock(rwlock_t *rw)
+{
+	unsigned int old;
+	old = rw->lock & 0x7fffffffU;
+	if (_raw_compare_and_swap(&rw->lock, old, old + 1) != old)
+		_raw_read_lock_wait(rw);
+}
+
+static inline void _raw_read_unlock(rwlock_t *rw)
+{
+	unsigned int old, cmp;
+
+	old = rw->lock;
+	do {
+		cmp = old;
+		old = _raw_compare_and_swap(&rw->lock, old, old - 1);
+	} while (cmp != old);
+}
+
+static inline void _raw_write_lock(rwlock_t *rw)
+{
+	if (unlikely(_raw_compare_and_swap(&rw->lock, 0, 0x80000000) != 0))
+		_raw_write_lock_wait(rw);
+}
+
+static inline void _raw_write_unlock(rwlock_t *rw)
+{
+	_raw_compare_and_swap(&rw->lock, 0x80000000, 0);
+}
+
+static inline int _raw_read_trylock(rwlock_t *rw)
+{
+	unsigned int old;
+	old = rw->lock & 0x7fffffffU;
+	if (likely(_raw_compare_and_swap(&rw->lock, old, old + 1) == old))
+		return 1;
+	return _raw_read_trylock_retry(rw);
+}
+
+static inline int _raw_write_trylock(rwlock_t *rw)
+{
+	if (likely(_raw_compare_and_swap(&rw->lock, 0, 0x80000000) == 0))
+		return 1;
+	return _raw_write_trylock_retry(rw);
 }
 
 #endif /* __ASM_SPINLOCK_H */
diff --git a/include/asm-s390/system.h b/include/asm-s390/system.h
--- a/include/asm-s390/system.h
+++ b/include/asm-s390/system.h
@@ -16,6 +16,7 @@
 #include <asm/types.h>
 #include <asm/ptrace.h>
 #include <asm/setup.h>
+#include <asm/processor.h>
 
 #ifdef __KERNEL__
 
@@ -103,29 +104,16 @@ static inline void restore_access_regs(u
 	prev = __switch_to(prev,next);					     \
 } while (0)
 
-#define prepare_arch_switch(rq, next)	do { } while(0)
-#define task_running(rq, p)		((rq)->curr == (p))
-
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
 extern void account_user_vtime(struct task_struct *);
 extern void account_system_vtime(struct task_struct *);
+#endif
 
-#define finish_arch_switch(rq, prev) do {				     \
+#define finish_arch_switch(prev) do {					     \
 	set_fs(current->thread.mm_segment);				     \
-	spin_unlock(&(rq)->lock);					     \
 	account_system_vtime(prev);					     \
-	local_irq_enable();						     \
 } while (0)
 
-#else
-
-#define finish_arch_switch(rq, prev) do {				     \
-	set_fs(current->thread.mm_segment);				     \
-	spin_unlock_irq(&(rq)->lock);					     \
-} while (0)
-
-#endif
-
 #define nop() __asm__ __volatile__ ("nop")
 
 #define xchg(ptr,x) \
@@ -331,9 +319,6 @@ __cmpxchg(volatile void *ptr, unsigned l
 
 #ifdef __s390x__
 
-#define __load_psw(psw) \
-        __asm__ __volatile__("lpswe 0(%0)" : : "a" (&psw), "m" (psw) : "cc" );
-
 #define __ctl_load(array, low, high) ({ \
 	typedef struct { char _[sizeof(array)]; } addrtype; \
 	__asm__ __volatile__ ( \
@@ -390,9 +375,6 @@ __cmpxchg(volatile void *ptr, unsigned l
 
 #else /* __s390x__ */
 
-#define __load_psw(psw) \
-	__asm__ __volatile__("lpsw 0(%0)" : : "a" (&psw) : "cc" );
-
 #define __ctl_load(array, low, high) ({ \
 	typedef struct { char _[sizeof(array)]; } addrtype; \
 	__asm__ __volatile__ ( \
@@ -451,6 +433,20 @@ __cmpxchg(volatile void *ptr, unsigned l
 /* For spinlocks etc */
 #define local_irq_save(x)	((x) = local_irq_disable())
 
+/*
+ * Use to set psw mask except for the first byte which
+ * won't be changed by this function.
+ */
+static inline void
+__set_psw_mask(unsigned long mask)
+{
+	local_save_flags(mask);
+	__load_psw_mask(mask);
+}
+
+#define local_mcck_enable()  __set_psw_mask(PSW_KERNEL_BITS)
+#define local_mcck_disable() __set_psw_mask(PSW_KERNEL_BITS & ~PSW_MASK_MCHECK)
+
 #ifdef CONFIG_SMP
 
 extern void smp_ctl_set_bit(int cr, int bit);
diff --git a/include/asm-s390/thread_info.h b/include/asm-s390/thread_info.h
--- a/include/asm-s390/thread_info.h
+++ b/include/asm-s390/thread_info.h
@@ -50,7 +50,7 @@ struct thread_info {
 	struct exec_domain	*exec_domain;	/* execution domain */
 	unsigned long		flags;		/* low level flags */
 	unsigned int		cpu;		/* current CPU */
-	unsigned int		preempt_count; /* 0 => preemptable */
+	int			preempt_count;	/* 0 => preemptable, <0 => BUG */
 	struct restart_block	restart_block;
 };
 
@@ -96,6 +96,7 @@ static inline struct thread_info *curren
 #define TIF_RESTART_SVC		4	/* restart svc with new svc number */
 #define TIF_SYSCALL_AUDIT	5	/* syscall auditing active */
 #define TIF_SINGLE_STEP		6	/* deliver sigtrap on return to user */
+#define TIF_MCCK_PENDING	7	/* machine check handling is pending */
 #define TIF_USEDFPU		16	/* FPU was used by this task this quantum (SMP) */
 #define TIF_POLLING_NRFLAG	17	/* true if poll_idle() is polling 
 					   TIF_NEED_RESCHED */
@@ -109,6 +110,7 @@ static inline struct thread_info *curren
 #define _TIF_RESTART_SVC	(1<<TIF_RESTART_SVC)
 #define _TIF_SYSCALL_AUDIT	(1<<TIF_SYSCALL_AUDIT)
 #define _TIF_SINGLE_STEP	(1<<TIF_SINGLE_STEP)
+#define _TIF_MCCK_PENDING	(1<<TIF_MCCK_PENDING)
 #define _TIF_USEDFPU		(1<<TIF_USEDFPU)
 #define _TIF_POLLING_NRFLAG	(1<<TIF_POLLING_NRFLAG)
 #define _TIF_31BIT		(1<<TIF_31BIT)
diff --git a/include/asm-s390/uaccess.h b/include/asm-s390/uaccess.h
--- a/include/asm-s390/uaccess.h
+++ b/include/asm-s390/uaccess.h
@@ -149,11 +149,11 @@ struct exception_table_entry
 })
 #endif
 
-#ifndef __CHECKER__
 #define __put_user(x, ptr) \
 ({								\
 	__typeof__(*(ptr)) __x = (x);				\
 	int __pu_err;						\
+        __chk_user_ptr(ptr);                                    \
 	switch (sizeof (*(ptr))) {				\
 	case 1:							\
 	case 2:							\
@@ -167,14 +167,6 @@ struct exception_table_entry
 	 }							\
 	__pu_err;						\
 })
-#else
-#define __put_user(x, ptr)			\
-({						\
-	void __user *p;				\
-	p = (ptr);				\
-	0;					\
-})
-#endif
 
 #define put_user(x, ptr)					\
 ({								\
@@ -213,11 +205,11 @@ extern int __put_user_bad(void) __attrib
 })
 #endif
 
-#ifndef __CHECKER__
 #define __get_user(x, ptr)					\
 ({								\
 	__typeof__(*(ptr)) __x;					\
 	int __gu_err;						\
+        __chk_user_ptr(ptr);                                    \
 	switch (sizeof(*(ptr))) {				\
 	case 1:							\
 	case 2:							\
@@ -232,15 +224,6 @@ extern int __put_user_bad(void) __attrib
 	(x) = __x;						\
 	__gu_err;						\
 })
-#else
-#define __get_user(x, ptr)			\
-({						\
-	void __user *p;				\
-	p = (ptr);				\
-	0;					\
-})
-#endif
-
 
 #define get_user(x, ptr)					\
 ({								\
diff --git a/include/asm-s390/unistd.h b/include/asm-s390/unistd.h
--- a/include/asm-s390/unistd.h
+++ b/include/asm-s390/unistd.h
@@ -269,13 +269,18 @@
 #define __NR_mq_timedreceive	274
 #define __NR_mq_notify		275
 #define __NR_mq_getsetattr	276
-/* Number 277 is reserved for new sys_kexec_load */
+#define __NR_kexec_load		277
 #define __NR_add_key		278
 #define __NR_request_key	279
 #define __NR_keyctl		280
 #define __NR_waitid		281
+#define __NR_ioprio_set		282
+#define __NR_ioprio_get		283
+#define __NR_inotify_init	284
+#define __NR_inotify_add_watch	285
+#define __NR_inotify_rm_watch	286
 
-#define NR_syscalls 282
+#define NR_syscalls 287
 
 /* 
  * There are some system calls that are not present on 64 bit, some
diff --git a/include/asm-sh/bigsur/serial.h b/include/asm-sh/bigsur/serial.h
--- a/include/asm-sh/bigsur/serial.h
+++ b/include/asm-sh/bigsur/serial.h
@@ -14,13 +14,10 @@
 #define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
 
 
-#define STD_SERIAL_PORT_DEFNS                   \
+#define SERIAL_PORT_DFNS                   \
         /* UART CLK   PORT IRQ     FLAGS        */                      \
         { 0, BASE_BAUD, 0x3F8, HD64465_IRQ_UART, STD_COM_FLAGS } /* ttyS0 */ 
 
-
-#define SERIAL_PORT_DFNS STD_SERIAL_PORT_DEFNS
-
 /* XXX: This should be moved ino irq.h */
 #define irq_cannonicalize(x) (x)
 
diff --git a/include/asm-sh/ec3104/serial.h b/include/asm-sh/ec3104/serial.h
--- a/include/asm-sh/ec3104/serial.h
+++ b/include/asm-sh/ec3104/serial.h
@@ -10,13 +10,11 @@
  * it's got the keyboard controller behind it so we can't really use it
  * (without moving the keyboard driver to userspace, which doesn't sound
  * like a very good idea) */
-#define STD_SERIAL_PORT_DEFNS			\
+#define SERIAL_PORT_DFNS			\
 	/* UART CLK   PORT IRQ     FLAGS        */			\
 	{ 0, BASE_BAUD, 0x11C00, EC3104_IRQBASE+7, STD_COM_FLAGS }, /* ttyS0 */	\
 	{ 0, BASE_BAUD, 0x12000, EC3104_IRQBASE+8, STD_COM_FLAGS }, /* ttyS1 */	\
 	{ 0, BASE_BAUD, 0x12400, EC3104_IRQBASE+9, STD_COM_FLAGS }, /* ttyS2 */
 
-#define SERIAL_PORT_DFNS STD_SERIAL_PORT_DEFNS
-
 /* XXX: This should be moved ino irq.h */
 #define irq_cannonicalize(x) (x)
diff --git a/include/asm-sh/emergency-restart.h b/include/asm-sh/emergency-restart.h
new file mode 100644
--- /dev/null
+++ b/include/asm-sh/emergency-restart.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_EMERGENCY_RESTART_H
+#define _ASM_EMERGENCY_RESTART_H
+
+#include <asm-generic/emergency-restart.h>
+
+#endif /* _ASM_EMERGENCY_RESTART_H */
diff --git a/include/asm-sh/page.h b/include/asm-sh/page.h
--- a/include/asm-sh/page.h
+++ b/include/asm-sh/page.h
@@ -31,6 +31,7 @@
 #define HPAGE_SIZE		(1UL << HPAGE_SHIFT)
 #define HPAGE_MASK		(~(HPAGE_SIZE-1))
 #define HUGETLB_PAGE_ORDER	(HPAGE_SHIFT-PAGE_SHIFT)
+#define ARCH_HAS_SETCLEAR_HUGE_PTE
 #endif
 
 #ifdef __KERNEL__
diff --git a/include/asm-sh/pci.h b/include/asm-sh/pci.h
--- a/include/asm-sh/pci.h
+++ b/include/asm-sh/pci.h
@@ -36,7 +36,7 @@ struct pci_dev;
 
 extern void pcibios_set_master(struct pci_dev *dev);
 
-static inline void pcibios_penalize_isa_irq(int irq)
+static inline void pcibios_penalize_isa_irq(int irq, int active)
 {
 	/* We don't do dynamic PCI IRQ allocation */
 }
@@ -96,6 +96,16 @@ static inline void pcibios_penalize_isa_
 #define sg_dma_address(sg)	(virt_to_bus((sg)->dma_address))
 #define sg_dma_len(sg)		((sg)->length)
 
+#ifdef CONFIG_PCI
+static inline void pci_dma_burst_advice(struct pci_dev *pdev,
+					enum pci_dma_burst_strategy *strat,
+					unsigned long *strategy_parameter)
+{
+	*strat = PCI_DMA_BURST_INFINITY;
+	*strategy_parameter = ~0UL;
+}
+#endif
+
 /* Board-specific fixup routines. */
 extern void pcibios_fixup(void);
 extern void pcibios_fixup_irqs(void);
diff --git a/include/asm-sh/pgtable.h b/include/asm-sh/pgtable.h
--- a/include/asm-sh/pgtable.h
+++ b/include/asm-sh/pgtable.h
@@ -196,6 +196,7 @@ static inline pte_t pte_mkexec(pte_t pte
 static inline pte_t pte_mkdirty(pte_t pte)	{ set_pte(&pte, __pte(pte_val(pte) | _PAGE_DIRTY)); return pte; }
 static inline pte_t pte_mkyoung(pte_t pte)	{ set_pte(&pte, __pte(pte_val(pte) | _PAGE_ACCESSED)); return pte; }
 static inline pte_t pte_mkwrite(pte_t pte)	{ set_pte(&pte, __pte(pte_val(pte) | _PAGE_RW)); return pte; }
+static inline pte_t pte_mkhuge(pte_t pte)	{ set_pte(&pte, __pte(pte_val(pte) | _PAGE_SZHUGE)); return pte; }
 
 /*
  * Macro and implementation to make a page protection as uncachable.
diff --git a/include/asm-sh/serial.h b/include/asm-sh/serial.h
--- a/include/asm-sh/serial.h
+++ b/include/asm-sh/serial.h
@@ -29,20 +29,18 @@
 #ifdef CONFIG_HD64465
 #include <asm/hd64465.h>
 
-#define STD_SERIAL_PORT_DEFNS                   \
+#define SERIAL_PORT_DFNS                   \
         /* UART CLK   PORT IRQ     FLAGS        */                      \
         { 0, BASE_BAUD, 0x3F8, HD64465_IRQ_UART, STD_COM_FLAGS }  /* ttyS0 */
 
 #else
 
-#define STD_SERIAL_PORT_DEFNS			\
+#define SERIAL_PORT_DFNS			\
 	/* UART CLK   PORT IRQ     FLAGS        */			\
 	{ 0, BASE_BAUD, 0x3F8, 4, STD_COM_FLAGS },	/* ttyS0 */	\
 	{ 0, BASE_BAUD, 0x2F8, 3, STD_COM_FLAGS }	/* ttyS1 */
 
 #endif
 
-#define SERIAL_PORT_DFNS STD_SERIAL_PORT_DEFNS
-
 #endif
 #endif /* _ASM_SERIAL_H */
diff --git a/include/asm-sh/smp.h b/include/asm-sh/smp.h
--- a/include/asm-sh/smp.h
+++ b/include/asm-sh/smp.h
@@ -25,7 +25,7 @@ extern cpumask_t cpu_possible_map;
 
 #define cpu_online(cpu)		cpu_isset(cpu, cpu_online_map)
 
-#define smp_processor_id()	(current_thread_info()->cpu)
+#define raw_smp_processor_id()	(current_thread_info()->cpu)
 
 /* I've no idea what the real meaning of this is */
 #define PROC_CHANGE_PENALTY	20
diff --git a/include/asm-sh/thread_info.h b/include/asm-sh/thread_info.h
--- a/include/asm-sh/thread_info.h
+++ b/include/asm-sh/thread_info.h
@@ -20,7 +20,7 @@ struct thread_info {
 	struct exec_domain	*exec_domain;	/* execution domain */
 	__u32			flags;		/* low level flags */
 	__u32			cpu;
-	__s32			preempt_count; /* 0 => preemptable, <0 => BUG */
+	int			preempt_count; /* 0 => preemptable, <0 => BUG */
 	struct restart_block	restart_block;
 	__u8			supervisor_stack[0];
 };
diff --git a/include/asm-sh/unistd.h b/include/asm-sh/unistd.h
--- a/include/asm-sh/unistd.h
+++ b/include/asm-sh/unistd.h
@@ -295,8 +295,14 @@
 #define __NR_add_key		285
 #define __NR_request_key	286
 #define __NR_keyctl		287
+#define __NR_ioprio_set		288
+#define __NR_ioprio_get		289
+#define __NR_inotify_init	290
+#define __NR_inotify_add_watch	291
+#define __NR_inotify_rm_watch	292
 
-#define NR_syscalls 288
+
+#define NR_syscalls 293
 
 /* user-visible error numbers are in the range -1 - -124: see <asm-sh/errno.h> */
 
@@ -406,7 +412,7 @@ register long __sc6 __asm__ ("r6") = (lo
 register long __sc7 __asm__ ("r7") = (long) arg4; \
 register long __sc0 __asm__ ("r0") = (long) arg5; \
 register long __sc1 __asm__ ("r1") = (long) arg6; \
-__asm__ __volatile__ ("trapa	#0x15" \
+__asm__ __volatile__ ("trapa	#0x16" \
 	: "=z" (__sc0) \
 	: "0" (__sc0), "r" (__sc4), "r" (__sc5), "r" (__sc6), "r" (__sc7),  \
 	  "r" (__sc3), "r" (__sc1) \
diff --git a/include/asm-sh64/emergency-restart.h b/include/asm-sh64/emergency-restart.h
new file mode 100644
--- /dev/null
+++ b/include/asm-sh64/emergency-restart.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_EMERGENCY_RESTART_H
+#define _ASM_EMERGENCY_RESTART_H
+
+#include <asm-generic/emergency-restart.h>
+
+#endif /* _ASM_EMERGENCY_RESTART_H */
diff --git a/include/asm-sh64/page.h b/include/asm-sh64/page.h
--- a/include/asm-sh64/page.h
+++ b/include/asm-sh64/page.h
@@ -41,6 +41,7 @@
 #define HPAGE_SIZE		(1UL << HPAGE_SHIFT)
 #define HPAGE_MASK		(~(HPAGE_SIZE-1))
 #define HUGETLB_PAGE_ORDER	(HPAGE_SHIFT-PAGE_SHIFT)
+#define ARCH_HAS_SETCLEAR_HUGE_PTE
 #endif
 
 #ifdef __KERNEL__
diff --git a/include/asm-sh64/pci.h b/include/asm-sh64/pci.h
--- a/include/asm-sh64/pci.h
+++ b/include/asm-sh64/pci.h
@@ -26,7 +26,7 @@ extern void pcibios_set_master(struct pc
 /*
  * Set penalize isa irq function
  */
-static inline void pcibios_penalize_isa_irq(int irq)
+static inline void pcibios_penalize_isa_irq(int irq, int active)
 {
 	/* We don't do dynamic PCI IRQ allocation */
 }
@@ -86,6 +86,16 @@ static inline void pcibios_penalize_isa_
 #define sg_dma_address(sg)	((sg)->dma_address)
 #define sg_dma_len(sg)		((sg)->length)
 
+#ifdef CONFIG_PCI
+static inline void pci_dma_burst_advice(struct pci_dev *pdev,
+					enum pci_dma_burst_strategy *strat,
+					unsigned long *strategy_parameter)
+{
+	*strat = PCI_DMA_BURST_INFINITY;
+	*strategy_parameter = ~0UL;
+}
+#endif
+
 /* Board-specific fixup routines. */
 extern void pcibios_fixup(void);
 extern void pcibios_fixup_irqs(void);
diff --git a/include/asm-sh64/pgtable.h b/include/asm-sh64/pgtable.h
--- a/include/asm-sh64/pgtable.h
+++ b/include/asm-sh64/pgtable.h
@@ -430,6 +430,8 @@ extern inline pte_t pte_mkwrite(pte_t pt
 extern inline pte_t pte_mkexec(pte_t pte)	{ set_pte(&pte, __pte(pte_val(pte) | _PAGE_EXECUTE)); return pte; }
 extern inline pte_t pte_mkdirty(pte_t pte)	{ set_pte(&pte, __pte(pte_val(pte) | _PAGE_DIRTY)); return pte; }
 extern inline pte_t pte_mkyoung(pte_t pte)	{ set_pte(&pte, __pte(pte_val(pte) | _PAGE_ACCESSED)); return pte; }
+extern inline pte_t pte_mkhuge(pte_t pte)	{ set_pte(&pte, __pte(pte_val(pte) | _PAGE_SZHUGE)); return pte; }
+
 
 /*
  * Conversion functions: convert a page and protection to a page entry.
diff --git a/include/asm-sh64/serial.h b/include/asm-sh64/serial.h
--- a/include/asm-sh64/serial.h
+++ b/include/asm-sh64/serial.h
@@ -20,13 +20,11 @@
 
 #define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
 
-#define STD_SERIAL_PORT_DEFNS			\
+#define SERIAL_PORT_DFNS			\
 	/* UART CLK   PORT IRQ     FLAGS        */			\
 	{ 0, BASE_BAUD, 0x3F8, 4, STD_COM_FLAGS },	/* ttyS0 */	\
 	{ 0, BASE_BAUD, 0x2F8, 3, STD_COM_FLAGS }	/* ttyS1 */
 
-#define SERIAL_PORT_DFNS STD_SERIAL_PORT_DEFNS
-
 /* XXX: This should be moved ino irq.h */
 #define irq_cannonicalize(x) (x)
 
diff --git a/include/asm-sh64/thread_info.h b/include/asm-sh64/thread_info.h
--- a/include/asm-sh64/thread_info.h
+++ b/include/asm-sh64/thread_info.h
@@ -22,7 +22,7 @@ struct thread_info {
 	struct exec_domain	*exec_domain;	/* execution domain */
 	unsigned long		flags;		/* low level flags */
 	/* Put the 4 32-bit fields together to make asm offsetting easier. */
-	__s32			preempt_count; /* 0 => preemptable, <0 => BUG */
+	int			preempt_count;	/* 0 => preemptable, <0 => BUG */
 	__u16			cpu;
 
 	mm_segment_t		addr_limit;
diff --git a/include/asm-sh64/unistd.h b/include/asm-sh64/unistd.h
--- a/include/asm-sh64/unistd.h
+++ b/include/asm-sh64/unistd.h
@@ -338,8 +338,13 @@
 #define __NR_add_key		313
 #define __NR_request_key	314
 #define __NR_keyctl		315
+#define __NR_ioprio_set		316
+#define __NR_ioprio_get		317
+#define __NR_inotify_init	318
+#define __NR_inotify_add_watch	319
+#define __NR_inotify_rm_watch	320
 
-#define NR_syscalls 316
+#define NR_syscalls 321
 
 /* user-visible error numbers are in the range -1 - -125: see <asm-sh64/errno.h> */
 
diff --git a/include/asm-sparc/emergency-restart.h b/include/asm-sparc/emergency-restart.h
new file mode 100644
--- /dev/null
+++ b/include/asm-sparc/emergency-restart.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_EMERGENCY_RESTART_H
+#define _ASM_EMERGENCY_RESTART_H
+
+#include <asm-generic/emergency-restart.h>
+
+#endif /* _ASM_EMERGENCY_RESTART_H */
diff --git a/include/asm-sparc/pci.h b/include/asm-sparc/pci.h
--- a/include/asm-sparc/pci.h
+++ b/include/asm-sparc/pci.h
@@ -20,7 +20,7 @@ extern inline void pcibios_set_master(st
 	/* No special bus mastering setup handling */
 }
 
-extern inline void pcibios_penalize_isa_irq(int irq)
+extern inline void pcibios_penalize_isa_irq(int irq, int active)
 {
 	/* We don't do dynamic PCI IRQ allocation */
 }
@@ -144,6 +144,16 @@ extern inline int pci_dma_supported(stru
 
 #define pci_dac_dma_supported(dev, mask)	(0)
 
+#ifdef CONFIG_PCI
+static inline void pci_dma_burst_advice(struct pci_dev *pdev,
+					enum pci_dma_burst_strategy *strat,
+					unsigned long *strategy_parameter)
+{
+	*strat = PCI_DMA_BURST_INFINITY;
+	*strategy_parameter = ~0UL;
+}
+#endif
+
 static inline void pcibios_add_platform_entries(struct pci_dev *dev)
 {
 }
diff --git a/include/asm-sparc/smp.h b/include/asm-sparc/smp.h
--- a/include/asm-sparc/smp.h
+++ b/include/asm-sparc/smp.h
@@ -148,7 +148,7 @@ extern __inline__ int hard_smp_processor
 }
 #endif
 
-#define smp_processor_id()	(current_thread_info()->cpu)
+#define raw_smp_processor_id()		(current_thread_info()->cpu)
 
 #define prof_multiplier(__cpu)		cpu_data(__cpu).multiplier
 #define prof_counter(__cpu)		cpu_data(__cpu).counter
diff --git a/include/asm-sparc/system.h b/include/asm-sparc/system.h
--- a/include/asm-sparc/system.h
+++ b/include/asm-sparc/system.h
@@ -101,7 +101,7 @@ extern void fpsave(unsigned long *fpregs
  * SWITCH_ENTER and SWITH_DO_LAZY_FPU do not work yet (e.g. SMP does not work)
  * XXX WTF is the above comment? Found in late teen 2.4.x.
  */
-#define prepare_arch_switch(rq, next) do { \
+#define prepare_arch_switch(next) do { \
 	__asm__ __volatile__( \
 	".globl\tflush_patch_switch\nflush_patch_switch:\n\t" \
 	"save %sp, -0x40, %sp; save %sp, -0x40, %sp; save %sp, -0x40, %sp\n\t" \
@@ -109,8 +109,6 @@ extern void fpsave(unsigned long *fpregs
 	"save %sp, -0x40, %sp\n\t" \
 	"restore; restore; restore; restore; restore; restore; restore"); \
 } while(0)
-#define finish_arch_switch(rq, next)	spin_unlock_irq(&(rq)->lock)
-#define task_running(rq, p)		((rq)->curr == (p))
 
 	/* Much care has gone into this code, do not touch it.
 	 *
diff --git a/include/asm-sparc/thread_info.h b/include/asm-sparc/thread_info.h
--- a/include/asm-sparc/thread_info.h
+++ b/include/asm-sparc/thread_info.h
@@ -30,9 +30,9 @@ struct thread_info {
 	struct task_struct	*task;		/* main task structure */
 	struct exec_domain	*exec_domain;	/* execution domain */
 	unsigned long		flags;		/* low level flags */
-
 	int			cpu;		/* cpu we're on */
-	int			preempt_count;
+	int			preempt_count;	/* 0 => preemptable,
+						   <0 => BUG */
 	int			softirq_count;
 	int			hardirq_count;
 
diff --git a/include/asm-sparc/unistd.h b/include/asm-sparc/unistd.h
--- a/include/asm-sparc/unistd.h
+++ b/include/asm-sparc/unistd.h
@@ -167,12 +167,12 @@
 #define __NR_pciconfig_read	148 /* ENOSYS under SunOS                          */
 #define __NR_pciconfig_write	149 /* ENOSYS under SunOS                          */
 #define __NR_getsockname        150 /* Common                                      */
-/* #define __NR_getmsg          151    SunOS Specific                              */
-/* #define __NR_putmsg          152    SunOS Specific                              */
+#define __NR_inotify_init       151 /* Linux specific                              */
+#define __NR_inotify_add_watch  152 /* Linux specific                              */
 #define __NR_poll               153 /* Common                                      */
 #define __NR_getdents64		154 /* Linux specific				   */
 #define __NR_fcntl64		155 /* Linux sparc32 Specific                      */
-/* #define __NR_getdirentires 	156    SunOS Specific                              */
+#define __NR_inotify_rm_watch   156 /* Linux specific				   */
 #define __NR_statfs             157 /* Common                                      */
 #define __NR_fstatfs            158 /* Common                                      */
 #define __NR_umount             159 /* Common                                      */
@@ -212,7 +212,7 @@
 #define __NR_epoll_create       193 /* Linux Specific                              */
 #define __NR_epoll_ctl          194 /* Linux Specific                              */
 #define __NR_epoll_wait         195 /* Linux Specific                              */
-/* #define __NR_ulimit          196    Linux Specific                              */
+#define __NR_ioprio_set         196 /* Linux Specific                              */
 #define __NR_getppid            197 /* Linux Specific                              */
 #define __NR_sigaction          198 /* Linux Specific                              */
 #define __NR_sgetmask           199 /* Linux Specific                              */
@@ -234,7 +234,7 @@
 #define __NR_ipc                215 /* Linux Specific                              */
 #define __NR_sigreturn          216 /* Linux Specific                              */
 #define __NR_clone              217 /* Linux Specific                              */
-/* #define __NR_modify_ldt      218    Linux Specific - i386 specific, unused      */
+#define __NR_ioprio_get         218 /* Linux Specific                              */
 #define __NR_adjtimex           219 /* Linux Specific                              */
 #define __NR_sigprocmask        220 /* Linux Specific                              */
 #define __NR_create_module      221 /* Linux Specific                              */
diff --git a/include/asm-sparc64/auxio.h b/include/asm-sparc64/auxio.h
--- a/include/asm-sparc64/auxio.h
+++ b/include/asm-sparc64/auxio.h
@@ -75,6 +75,8 @@
 
 #ifndef __ASSEMBLY__
 
+extern void __iomem *auxio_register;
+
 #define AUXIO_LTE_ON	1
 #define AUXIO_LTE_OFF	0
 
diff --git a/include/asm-sparc64/bitops.h b/include/asm-sparc64/bitops.h
--- a/include/asm-sparc64/bitops.h
+++ b/include/asm-sparc64/bitops.h
@@ -20,52 +20,52 @@ extern void change_bit(unsigned long nr,
 
 /* "non-atomic" versions... */
 
-static __inline__ void __set_bit(int nr, volatile unsigned long *addr)
+static inline void __set_bit(int nr, volatile unsigned long *addr)
 {
-	volatile unsigned long *m = addr + (nr >> 6);
+	unsigned long *m = ((unsigned long *)addr) + (nr >> 6);
 
 	*m |= (1UL << (nr & 63));
 }
 
-static __inline__ void __clear_bit(int nr, volatile unsigned long *addr)
+static inline void __clear_bit(int nr, volatile unsigned long *addr)
 {
-	volatile unsigned long *m = addr + (nr >> 6);
+	unsigned long *m = ((unsigned long *)addr) + (nr >> 6);
 
 	*m &= ~(1UL << (nr & 63));
 }
 
-static __inline__ void __change_bit(int nr, volatile unsigned long *addr)
+static inline void __change_bit(int nr, volatile unsigned long *addr)
 {
-	volatile unsigned long *m = addr + (nr >> 6);
+	unsigned long *m = ((unsigned long *)addr) + (nr >> 6);
 
 	*m ^= (1UL << (nr & 63));
 }
 
-static __inline__ int __test_and_set_bit(int nr, volatile unsigned long *addr)
+static inline int __test_and_set_bit(int nr, volatile unsigned long *addr)
 {
-	volatile unsigned long *m = addr + (nr >> 6);
-	long old = *m;
-	long mask = (1UL << (nr & 63));
+	unsigned long *m = ((unsigned long *)addr) + (nr >> 6);
+	unsigned long old = *m;
+	unsigned long mask = (1UL << (nr & 63));
 
 	*m = (old | mask);
 	return ((old & mask) != 0);
 }
 
-static __inline__ int __test_and_clear_bit(int nr, volatile unsigned long *addr)
+static inline int __test_and_clear_bit(int nr, volatile unsigned long *addr)
 {
-	volatile unsigned long *m = addr + (nr >> 6);
-	long old = *m;
-	long mask = (1UL << (nr & 63));
+	unsigned long *m = ((unsigned long *)addr) + (nr >> 6);
+	unsigned long old = *m;
+	unsigned long mask = (1UL << (nr & 63));
 
 	*m = (old & ~mask);
 	return ((old & mask) != 0);
 }
 
-static __inline__ int __test_and_change_bit(int nr, volatile unsigned long *addr)
+static inline int __test_and_change_bit(int nr, volatile unsigned long *addr)
 {
-	volatile unsigned long *m = addr + (nr >> 6);
-	long old = *m;
-	long mask = (1UL << (nr & 63));
+	unsigned long *m = ((unsigned long *)addr) + (nr >> 6);
+	unsigned long old = *m;
+	unsigned long mask = (1UL << (nr & 63));
 
 	*m = (old ^ mask);
 	return ((old & mask) != 0);
@@ -79,13 +79,13 @@ static __inline__ int __test_and_change_
 #define smp_mb__after_clear_bit()	barrier()
 #endif
 
-static __inline__ int test_bit(int nr, __const__ volatile unsigned long *addr)
+static inline int test_bit(int nr, __const__ volatile unsigned long *addr)
 {
-	return (1UL & ((addr)[nr >> 6] >> (nr & 63))) != 0UL;
+	return (1UL & (addr[nr >> 6] >> (nr & 63))) != 0UL;
 }
 
 /* The easy/cheese version for now. */
-static __inline__ unsigned long ffz(unsigned long word)
+static inline unsigned long ffz(unsigned long word)
 {
 	unsigned long result;
 
@@ -103,7 +103,7 @@ static __inline__ unsigned long ffz(unsi
  *
  * Undefined if no bit exists, so code should check against 0 first.
  */
-static __inline__ unsigned long __ffs(unsigned long word)
+static inline unsigned long __ffs(unsigned long word)
 {
 	unsigned long result = 0;
 
@@ -144,7 +144,7 @@ static inline int sched_find_first_bit(u
  * the libc and compiler builtin ffs routines, therefore
  * differs in spirit from the above ffz (man ffs).
  */
-static __inline__ int ffs(int x)
+static inline int ffs(int x)
 {
 	if (!x)
 		return 0;
@@ -158,7 +158,7 @@ static __inline__ int ffs(int x)
 
 #ifdef ULTRA_HAS_POPULATION_COUNT
 
-static __inline__ unsigned int hweight64(unsigned long w)
+static inline unsigned int hweight64(unsigned long w)
 {
 	unsigned int res;
 
@@ -166,7 +166,7 @@ static __inline__ unsigned int hweight64
 	return res;
 }
 
-static __inline__ unsigned int hweight32(unsigned int w)
+static inline unsigned int hweight32(unsigned int w)
 {
 	unsigned int res;
 
@@ -174,7 +174,7 @@ static __inline__ unsigned int hweight32
 	return res;
 }
 
-static __inline__ unsigned int hweight16(unsigned int w)
+static inline unsigned int hweight16(unsigned int w)
 {
 	unsigned int res;
 
@@ -182,7 +182,7 @@ static __inline__ unsigned int hweight16
 	return res;
 }
 
-static __inline__ unsigned int hweight8(unsigned int w)
+static inline unsigned int hweight8(unsigned int w)
 {
 	unsigned int res;
 
@@ -236,7 +236,7 @@ extern unsigned long find_next_zero_bit(
 #define test_and_clear_le_bit(nr,addr)	\
 	test_and_clear_bit((nr) ^ 0x38, (addr))
 
-static __inline__ int test_le_bit(int nr, __const__ unsigned long * addr)
+static inline int test_le_bit(int nr, __const__ unsigned long * addr)
 {
 	int			mask;
 	__const__ unsigned char	*ADDR = (__const__ unsigned char *) addr;
diff --git a/include/asm-sparc64/compat.h b/include/asm-sparc64/compat.h
--- a/include/asm-sparc64/compat.h
+++ b/include/asm-sparc64/compat.h
@@ -25,6 +25,7 @@ typedef s32		compat_daddr_t;
 typedef u32		compat_caddr_t;
 typedef __kernel_fsid_t	compat_fsid_t;
 typedef s32		compat_key_t;
+typedef s32		compat_timer_t;
 
 typedef s32		compat_int_t;
 typedef s32		compat_long_t;
diff --git a/include/asm-sparc64/emergency-restart.h b/include/asm-sparc64/emergency-restart.h
new file mode 100644
--- /dev/null
+++ b/include/asm-sparc64/emergency-restart.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_EMERGENCY_RESTART_H
+#define _ASM_EMERGENCY_RESTART_H
+
+#include <asm-generic/emergency-restart.h>
+
+#endif /* _ASM_EMERGENCY_RESTART_H */
diff --git a/include/asm-sparc64/floppy.h b/include/asm-sparc64/floppy.h
--- a/include/asm-sparc64/floppy.h
+++ b/include/asm-sparc64/floppy.h
@@ -159,7 +159,7 @@ static void sun_82077_fd_outb(unsigned c
  * underruns.  If non-zero, doing_pdma encodes the direction of
  * the transfer for debugging.  1=read 2=write
  */
-char *pdma_vaddr;
+unsigned char *pdma_vaddr;
 unsigned long pdma_size;
 volatile int doing_pdma = 0;
 
@@ -209,8 +209,7 @@ static void sun_fd_enable_dma(void)
 	pdma_areasize = pdma_size;
 }
 
-/* Our low-level entry point in arch/sparc/kernel/entry.S */
-extern irqreturn_t floppy_hardint(int irq, void *unused, struct pt_regs *regs);
+extern irqreturn_t sparc_floppy_irq(int, void *, struct pt_regs *);
 
 static int sun_fd_request_irq(void)
 {
@@ -220,8 +219,8 @@ static int sun_fd_request_irq(void)
 	if(!once) {
 		once = 1;
 
-		error = request_fast_irq(FLOPPY_IRQ, floppy_hardint, 
-					 SA_INTERRUPT, "floppy", NULL);
+		error = request_irq(FLOPPY_IRQ, sparc_floppy_irq, 
+				    SA_INTERRUPT, "floppy", NULL);
 
 		return ((error == 0) ? 0 : -1);
 	}
@@ -615,7 +614,7 @@ static unsigned long __init sun_floppy_i
 		struct linux_ebus *ebus;
 		struct linux_ebus_device *edev = NULL;
 		unsigned long config = 0;
-		unsigned long auxio_reg;
+		void __iomem *auxio_reg;
 
 		for_each_ebus(ebus) {
 			for_each_ebusdev(edev, ebus) {
@@ -642,7 +641,7 @@ static unsigned long __init sun_floppy_i
 		/* Make sure the high density bit is set, some systems
 		 * (most notably Ultra5/Ultra10) come up with it clear.
 		 */
-		auxio_reg = edev->resource[2].start;
+		auxio_reg = (void __iomem *) edev->resource[2].start;
 		writel(readl(auxio_reg)|0x2, auxio_reg);
 
 		sun_pci_ebus_dev = ebus->self;
@@ -650,7 +649,8 @@ static unsigned long __init sun_floppy_i
 		spin_lock_init(&sun_pci_fd_ebus_dma.lock);
 
 		/* XXX ioremap */
-		sun_pci_fd_ebus_dma.regs = edev->resource[1].start;
+		sun_pci_fd_ebus_dma.regs = (void __iomem *)
+			edev->resource[1].start;
 		if (!sun_pci_fd_ebus_dma.regs)
 			return 0;
 
diff --git a/include/asm-sparc64/irq.h b/include/asm-sparc64/irq.h
--- a/include/asm-sparc64/irq.h
+++ b/include/asm-sparc64/irq.h
@@ -16,10 +16,22 @@
 #include <asm/pil.h>
 #include <asm/ptrace.h>
 
+struct ino_bucket;
+
+#define MAX_IRQ_DESC_ACTION	4
+
+struct irq_desc {
+	void			(*pre_handler)(struct ino_bucket *, void *, void *);
+	void			*pre_handler_arg1;
+	void			*pre_handler_arg2;
+	u32			action_active_mask;
+	struct irqaction	action[MAX_IRQ_DESC_ACTION];
+};
+
 /* You should not mess with this directly. That's the job of irq.c.
  *
  * If you make changes here, please update hand coded assembler of
- * SBUS/floppy interrupt handler in entry.S -DaveM
+ * the vectored interrupt trap handler in entry.S -DaveM
  *
  * This is currently one DCACHE line, two buckets per L2 cache
  * line.  Keep this in mind please.
@@ -42,24 +54,11 @@ struct ino_bucket {
 	/* Miscellaneous flags. */
 /*0x06*/unsigned char flags;
 
-	/* This is used to deal with IBF_DMA_SYNC on
-	 * Sabre systems.
-	 */
-/*0x07*/unsigned char synctab_ent;
+	/* Currently unused.  */
+/*0x07*/unsigned char __pad;
 
-	/* Reference to handler for this IRQ.  If this is
-	 * non-NULL this means it is active and should be
-	 * serviced.  Else the pending member is set to one
-	 * and later registry of the interrupt checks for
-	 * this condition.
-	 *
-	 * Normally this is just an irq_action structure.
-	 * But, on PCI, if multiple interrupt sources behind
-	 * a bridge have multiple interrupt sources that share
-	 * the same INO bucket, this points to an array of
-	 * pointers to four IRQ action structures.
-	 */
-/*0x08*/void *irq_info;
+	/* Reference to IRQ descriptor for this bucket. */
+/*0x08*/struct irq_desc *irq_info;
 
 	/* Sun5 Interrupt Clear Register. */
 /*0x10*/unsigned long iclr;
@@ -69,12 +68,6 @@ struct ino_bucket {
 
 };
 
-#ifdef CONFIG_PCI
-extern unsigned long pci_dma_wsync;
-extern unsigned long dma_sync_reg_table[256];
-extern unsigned char dma_sync_reg_table_entry;
-#endif
-
 /* IMAP/ICLR register defines */
 #define IMAP_VALID		0x80000000	/* IRQ Enabled		*/
 #define IMAP_TID_UPA		0x7c000000	/* UPA TargetID		*/
@@ -90,11 +83,9 @@ extern unsigned char dma_sync_reg_table_
 #define ICLR_PENDING		0x00000003	/* Pending state	*/
 
 /* Only 8-bits are available, be careful.  -DaveM */
-#define IBF_DMA_SYNC	0x01	/* DMA synchronization behind PCI bridge needed. */
-#define IBF_PCI		0x02	/* Indicates PSYCHO/SABRE/SCHIZO PCI interrupt.	 */
-#define IBF_ACTIVE	0x04	/* This interrupt is active and has a handler.	 */
-#define IBF_MULTI	0x08	/* On PCI, indicates shared bucket.		 */
-#define IBF_INPROGRESS	0x10	/* IRQ is being serviced.			 */
+#define IBF_PCI		0x02	/* PSYCHO/SABRE/SCHIZO PCI interrupt.	 */
+#define IBF_ACTIVE	0x04	/* Interrupt is active and has a handler.*/
+#define IBF_INPROGRESS	0x10	/* IRQ is being serviced.		 */
 
 #define NUM_IVECS	(IMAP_INR + 1)
 extern struct ino_bucket ivector_table[NUM_IVECS];
@@ -122,11 +113,6 @@ extern void enable_irq(unsigned int);
 extern unsigned int build_irq(int pil, int inofixup, unsigned long iclr, unsigned long imap);
 extern unsigned int sbus_build_irq(void *sbus, unsigned int ino);
 
-extern int request_fast_irq(unsigned int irq,
-			    irqreturn_t (*handler)(int, void *, struct pt_regs *),
-			    unsigned long flags, __const__ char *devname,
-			    void *dev_id);
-
 static __inline__ void set_softint(unsigned long bits)
 {
 	__asm__ __volatile__("wr	%0, 0x0, %%set_softint"
diff --git a/include/asm-sparc64/kdebug.h b/include/asm-sparc64/kdebug.h
--- a/include/asm-sparc64/kdebug.h
+++ b/include/asm-sparc64/kdebug.h
@@ -16,7 +16,7 @@ struct die_args {
 };
 
 /* Note - you should never unregister because that can race with NMIs.
- * If you really want to do it first unregister - then synchronize_kernel
+ * If you really want to do it first unregister - then synchronize_sched
  * - then free.
  */
 int register_die_notifier(struct notifier_block *nb);
diff --git a/include/asm-sparc64/page.h b/include/asm-sparc64/page.h
--- a/include/asm-sparc64/page.h
+++ b/include/asm-sparc64/page.h
@@ -95,6 +95,8 @@ typedef unsigned long pgprot_t;
 #define HPAGE_SIZE		(_AC(1,UL) << HPAGE_SHIFT)
 #define HPAGE_MASK		(~(HPAGE_SIZE - 1UL))
 #define HUGETLB_PAGE_ORDER	(HPAGE_SHIFT - PAGE_SHIFT)
+#define ARCH_HAS_SETCLEAR_HUGE_PTE
+#define ARCH_HAS_HUGETLB_PREFAULT_HOOK
 #endif
 
 #define TASK_UNMAPPED_BASE	(test_thread_flag(TIF_32BIT) ? \
diff --git a/include/asm-sparc64/param.h b/include/asm-sparc64/param.h
--- a/include/asm-sparc64/param.h
+++ b/include/asm-sparc64/param.h
@@ -1,9 +1,10 @@
-/* $Id: param.h,v 1.2 2000/10/30 21:01:41 davem Exp $ */
 #ifndef _ASMSPARC64_PARAM_H
 #define _ASMSPARC64_PARAM_H
 
+#include <linux/config.h>
+
 #ifdef __KERNEL__
-# define HZ		1000	/* Internal kernel timer frequency */
+# define HZ		CONFIG_HZ	/* Internal kernel timer frequency */
 # define USER_HZ	100	/* .. some user interfaces are in "ticks" */
 # define CLOCKS_PER_SEC (USER_HZ)
 #endif
diff --git a/include/asm-sparc64/parport.h b/include/asm-sparc64/parport.h
--- a/include/asm-sparc64/parport.h
+++ b/include/asm-sparc64/parport.h
@@ -27,12 +27,12 @@ static struct sparc_ebus_info {
 
 static __inline__ void enable_dma(unsigned int dmanr)
 {
+	ebus_dma_enable(&sparc_ebus_dmas[dmanr].info, 1);
+
 	if (ebus_dma_request(&sparc_ebus_dmas[dmanr].info,
 			     sparc_ebus_dmas[dmanr].addr,
 			     sparc_ebus_dmas[dmanr].count))
 		BUG();
-
-	ebus_dma_enable(&sparc_ebus_dmas[dmanr].info, 1);
 }
 
 static __inline__ void disable_dma(unsigned int dmanr)
diff --git a/include/asm-sparc64/pbm.h b/include/asm-sparc64/pbm.h
--- a/include/asm-sparc64/pbm.h
+++ b/include/asm-sparc64/pbm.h
@@ -145,6 +145,9 @@ struct pci_pbm_info {
 	/* Physical address base of PBM registers. */
 	unsigned long			pbm_regs;
 
+	/* Physical address of DMA sync register, if any.  */
+	unsigned long			sync_reg;
+
 	/* Opaque 32-bit system bus Port ID. */
 	u32				portid;
 
diff --git a/include/asm-sparc64/pci.h b/include/asm-sparc64/pci.h
--- a/include/asm-sparc64/pci.h
+++ b/include/asm-sparc64/pci.h
@@ -23,7 +23,7 @@ static inline void pcibios_set_master(st
 	/* No special bus mastering setup handling */
 }
 
-static inline void pcibios_penalize_isa_irq(int irq)
+static inline void pcibios_penalize_isa_irq(int irq, int active)
 {
 	/* We don't do dynamic PCI IRQ allocation */
 }
@@ -220,6 +220,25 @@ static inline int pci_dma_mapping_error(
 	return (dma_addr == PCI_DMA_ERROR_CODE);
 }
 
+#ifdef CONFIG_PCI
+static inline void pci_dma_burst_advice(struct pci_dev *pdev,
+					enum pci_dma_burst_strategy *strat,
+					unsigned long *strategy_parameter)
+{
+	unsigned long cacheline_size;
+	u8 byte;
+
+	pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &byte);
+	if (byte == 0)
+		cacheline_size = 1024;
+	else
+		cacheline_size = (int) byte * 4;
+
+	*strat = PCI_DMA_BURST_BOUNDARY;
+	*strategy_parameter = cacheline_size;
+}
+#endif
+
 /* Return the index of the PCI controller for device PDEV. */
 
 extern int pci_domain_nr(struct pci_bus *bus);
diff --git a/include/asm-sparc64/pgtable.h b/include/asm-sparc64/pgtable.h
--- a/include/asm-sparc64/pgtable.h
+++ b/include/asm-sparc64/pgtable.h
@@ -286,6 +286,7 @@ static inline pte_t pte_modify(pte_t ori
 #define pte_mkyoung(pte)	(__pte(pte_val(pte) | _PAGE_ACCESSED | _PAGE_R))
 #define pte_mkwrite(pte)	(__pte(pte_val(pte) | _PAGE_WRITE))
 #define pte_mkdirty(pte)	(__pte(pte_val(pte) | _PAGE_MODIFIED | _PAGE_W))
+#define pte_mkhuge(pte)		(__pte(pte_val(pte) | _PAGE_SZHUGE))
 
 /* to find an entry in a page-table-directory. */
 #define pgd_index(address)	(((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1))
diff --git a/include/asm-sparc64/processor.h b/include/asm-sparc64/processor.h
--- a/include/asm-sparc64/processor.h
+++ b/include/asm-sparc64/processor.h
@@ -192,6 +192,40 @@ extern unsigned long get_wchan(struct ta
 
 #define cpu_relax()	barrier()
 
+/* Prefetch support.  This is tuned for UltraSPARC-III and later.
+ * UltraSPARC-I will treat these as nops, and UltraSPARC-II has
+ * a shallower prefetch queue than later chips.
+ */
+#define ARCH_HAS_PREFETCH
+#define ARCH_HAS_PREFETCHW
+#define ARCH_HAS_SPINLOCK_PREFETCH
+
+static inline void prefetch(const void *x)
+{
+	/* We do not use the read prefetch mnemonic because that
+	 * prefetches into the prefetch-cache which only is accessible
+	 * by floating point operations in UltraSPARC-III and later.
+	 * By contrast, "#one_write" prefetches into the L2 cache
+	 * in shared state.
+	 */
+	__asm__ __volatile__("prefetch [%0], #one_write"
+			     : /* no outputs */
+			     : "r" (x));
+}
+
+static inline void prefetchw(const void *x)
+{
+	/* The most optimal prefetch to use for writes is
+	 * "#n_writes".  This brings the cacheline into the
+	 * L2 cache in "owned" state.
+	 */
+	__asm__ __volatile__("prefetch [%0], #n_writes"
+			     : /* no outputs */
+			     : "r" (x));
+}
+
+#define spin_lock_prefetch(x)	prefetchw(x)
+
 #endif /* !(__ASSEMBLY__) */
 
 #endif /* !(__ASM_SPARC64_PROCESSOR_H) */
diff --git a/include/asm-sparc64/ptrace.h b/include/asm-sparc64/ptrace.h
--- a/include/asm-sparc64/ptrace.h
+++ b/include/asm-sparc64/ptrace.h
@@ -94,8 +94,9 @@ struct sparc_trapf {
 #define STACKFRAME32_SZ	sizeof(struct sparc_stackf32)
 
 #ifdef __KERNEL__
-#define force_successful_syscall_return()	\
-	set_thread_flag(TIF_SYSCALL_SUCCESS)
+#define force_successful_syscall_return()	    \
+do {	current_thread_info()->syscall_noerror = 1; \
+} while (0)
 #define user_mode(regs) (!((regs)->tstate & TSTATE_PRIV))
 #define instruction_pointer(regs) ((regs)->tpc)
 #ifdef CONFIG_SMP
diff --git a/include/asm-sparc64/rwsem.h b/include/asm-sparc64/rwsem.h
--- a/include/asm-sparc64/rwsem.h
+++ b/include/asm-sparc64/rwsem.h
@@ -46,53 +46,14 @@ extern void __up_read(struct rw_semaphor
 extern void __up_write(struct rw_semaphore *sem);
 extern void __downgrade_write(struct rw_semaphore *sem);
 
-static __inline__ int rwsem_atomic_update(int delta, struct rw_semaphore *sem)
+static inline int rwsem_atomic_update(int delta, struct rw_semaphore *sem)
 {
-	int tmp = delta;
-
-	__asm__ __volatile__(
-		"1:\tlduw	[%2], %%g1\n\t"
-		"add		%%g1, %1, %%g7\n\t"
-		"cas		[%2], %%g1, %%g7\n\t"
-		"cmp		%%g1, %%g7\n\t"
-		"bne,pn		%%icc, 1b\n\t"
-		" membar	#StoreLoad | #StoreStore\n\t"
-		"mov		%%g7, %0\n\t"
-		: "=&r" (tmp)
-		: "0" (tmp), "r" (sem)
-		: "g1", "g7", "memory", "cc");
-
-	return tmp + delta;
-}
-
-#define rwsem_atomic_add rwsem_atomic_update
-
-static __inline__ __u16 rwsem_cmpxchgw(struct rw_semaphore *sem, __u16 __old, __u16 __new)
-{
-	u32 old = (sem->count & 0xffff0000) | (u32) __old;
-	u32 new = (old & 0xffff0000) | (u32) __new;
-	u32 prev;
-
-again:
-	__asm__ __volatile__("cas	[%2], %3, %0\n\t"
-			     "membar	#StoreLoad | #StoreStore"
-			     : "=&r" (prev)
-			     : "0" (new), "r" (sem), "r" (old)
-			     : "memory");
-
-	/* To give the same semantics as x86 cmpxchgw, keep trying
-	 * if only the upper 16-bits changed.
-	 */
-	if (prev != old &&
-	    ((prev & 0xffff) == (old & 0xffff)))
-		goto again;
-
-	return prev & 0xffff;
+	return atomic_add_return(delta, (atomic_t *)(&sem->count));
 }
 
-static __inline__ signed long rwsem_cmpxchg(struct rw_semaphore *sem, signed long old, signed long new)
+static inline void rwsem_atomic_add(int delta, struct rw_semaphore *sem)
 {
-	return cmpxchg(&sem->count,old,new);
+	atomic_add(delta, (atomic_t *)(&sem->count));
 }
 
 #endif /* __KERNEL__ */
diff --git a/include/asm-sparc64/seccomp.h b/include/asm-sparc64/seccomp.h
new file mode 100644
--- /dev/null
+++ b/include/asm-sparc64/seccomp.h
@@ -0,0 +1,21 @@
+#ifndef _ASM_SECCOMP_H
+
+#include <linux/thread_info.h> /* already defines TIF_32BIT */
+
+#ifndef TIF_32BIT
+#error "unexpected TIF_32BIT on sparc64"
+#endif
+
+#include <linux/unistd.h>
+
+#define __NR_seccomp_read __NR_read
+#define __NR_seccomp_write __NR_write
+#define __NR_seccomp_exit __NR_exit
+#define __NR_seccomp_sigreturn __NR_rt_sigreturn
+
+#define __NR_seccomp_read_32 __NR_read
+#define __NR_seccomp_write_32 __NR_write
+#define __NR_seccomp_exit_32 __NR_exit
+#define __NR_seccomp_sigreturn_32 __NR_sigreturn
+
+#endif /* _ASM_SECCOMP_H */
diff --git a/include/asm-sparc64/signal.h b/include/asm-sparc64/signal.h
--- a/include/asm-sparc64/signal.h
+++ b/include/asm-sparc64/signal.h
@@ -162,21 +162,6 @@ struct sigstack {
 #define MINSIGSTKSZ	4096
 #define SIGSTKSZ	16384
 
-#ifdef __KERNEL__
-/*
- * DJHR
- * SA_STATIC_ALLOC is used for the SPARC system to indicate that this
- * interrupt handler's irq structure should be statically allocated
- * by the request_irq routine.
- * The alternative is that arch/sparc/kernel/irq.c has carnal knowledge
- * of interrupt usage and that sucks. Also without a flag like this
- * it may be possible for the free_irq routine to attempt to free
- * statically allocated data.. which is NOT GOOD.
- *
- */
-#define SA_STATIC_ALLOC		0x80
-#endif
-
 #include <asm-generic/signal.h>
 
 struct __new_sigaction {
diff --git a/include/asm-sparc64/smp.h b/include/asm-sparc64/smp.h
--- a/include/asm-sparc64/smp.h
+++ b/include/asm-sparc64/smp.h
@@ -64,7 +64,7 @@ static __inline__ int hard_smp_processor
 	}
 }
 
-#define smp_processor_id() (current_thread_info()->cpu)
+#define raw_smp_processor_id() (current_thread_info()->cpu)
 
 #endif /* !(__ASSEMBLY__) */
 
diff --git a/include/asm-sparc64/spinlock.h b/include/asm-sparc64/spinlock.h
--- a/include/asm-sparc64/spinlock.h
+++ b/include/asm-sparc64/spinlock.h
@@ -52,12 +52,14 @@ static inline void _raw_spin_lock(spinlo
 
 	__asm__ __volatile__(
 "1:	ldstub		[%1], %0\n"
+"	membar		#StoreLoad | #StoreStore\n"
 "	brnz,pn		%0, 2f\n"
-"	 membar		#StoreLoad | #StoreStore\n"
+"	 nop\n"
 "	.subsection	2\n"
 "2:	ldub		[%1], %0\n"
+"	membar		#LoadLoad\n"
 "	brnz,pt		%0, 2b\n"
-"	 membar		#LoadLoad\n"
+"	 nop\n"
 "	ba,a,pt		%%xcc, 1b\n"
 "	.previous"
 	: "=&r" (tmp)
@@ -95,16 +97,18 @@ static inline void _raw_spin_lock_flags(
 
 	__asm__ __volatile__(
 "1:	ldstub		[%2], %0\n"
-"	brnz,pn		%0, 2f\n"
 "	membar		#StoreLoad | #StoreStore\n"
+"	brnz,pn		%0, 2f\n"
+"	 nop\n"
 "	.subsection	2\n"
 "2:	rdpr		%%pil, %1\n"
 "	wrpr		%3, %%pil\n"
 "3:	ldub		[%2], %0\n"
-"	brnz,pt		%0, 3b\n"
 "	membar		#LoadLoad\n"
+"	brnz,pt		%0, 3b\n"
+"	 nop\n"
 "	ba,pt		%%xcc, 1b\n"
-"	wrpr		%1, %%pil\n"
+"	 wrpr		%1, %%pil\n"
 "	.previous"
 	: "=&r" (tmp1), "=&r" (tmp2)
 	: "r"(lock), "r"(flags)
@@ -162,12 +166,14 @@ static void inline __read_lock(rwlock_t 
 "4:	 add		%0, 1, %1\n"
 "	cas		[%2], %0, %1\n"
 "	cmp		%0, %1\n"
+"	membar		#StoreLoad | #StoreStore\n"
 "	bne,pn		%%icc, 1b\n"
-"	 membar		#StoreLoad | #StoreStore\n"
+"	 nop\n"
 "	.subsection	2\n"
 "2:	ldsw		[%2], %0\n"
+"	membar		#LoadLoad\n"
 "	brlz,pt		%0, 2b\n"
-"	 membar		#LoadLoad\n"
+"	 nop\n"
 "	ba,a,pt		%%xcc, 4b\n"
 "	.previous"
 	: "=&r" (tmp1), "=&r" (tmp2)
@@ -204,12 +210,14 @@ static void inline __write_lock(rwlock_t
 "4:	 or		%0, %3, %1\n"
 "	cas		[%2], %0, %1\n"
 "	cmp		%0, %1\n"
+"	membar		#StoreLoad | #StoreStore\n"
 "	bne,pn		%%icc, 1b\n"
-"	 membar		#StoreLoad | #StoreStore\n"
+"	 nop\n"
 "	.subsection	2\n"
 "2:	lduw		[%2], %0\n"
+"	membar		#LoadLoad\n"
 "	brnz,pt		%0, 2b\n"
-"	 membar		#LoadLoad\n"
+"	 nop\n"
 "	ba,a,pt		%%xcc, 4b\n"
 "	.previous"
 	: "=&r" (tmp1), "=&r" (tmp2)
@@ -240,8 +248,9 @@ static int inline __write_trylock(rwlock
 "	 or		%0, %4, %1\n"
 "	cas		[%3], %0, %1\n"
 "	cmp		%0, %1\n"
+"	membar		#StoreLoad | #StoreStore\n"
 "	bne,pn		%%icc, 1b\n"
-"	 membar		#StoreLoad | #StoreStore\n"
+"	 nop\n"
 "	mov		1, %2\n"
 "2:"
 	: "=&r" (tmp1), "=&r" (tmp2), "=&r" (result)
diff --git a/include/asm-sparc64/spitfire.h b/include/asm-sparc64/spitfire.h
--- a/include/asm-sparc64/spitfire.h
+++ b/include/asm-sparc64/spitfire.h
@@ -56,52 +56,6 @@ extern void cheetah_enable_pcache(void);
 	 SPITFIRE_HIGHEST_LOCKED_TLBENT : \
 	 CHEETAH_HIGHEST_LOCKED_TLBENT)
 
-static __inline__ unsigned long spitfire_get_isfsr(void)
-{
-	unsigned long ret;
-
-	__asm__ __volatile__("ldxa	[%1] %2, %0"
-			     : "=r" (ret)
-			     : "r" (TLB_SFSR), "i" (ASI_IMMU));
-	return ret;
-}
-
-static __inline__ unsigned long spitfire_get_dsfsr(void)
-{
-	unsigned long ret;
-
-	__asm__ __volatile__("ldxa	[%1] %2, %0"
-			     : "=r" (ret)
-			     : "r" (TLB_SFSR), "i" (ASI_DMMU));
-	return ret;
-}
-
-static __inline__ unsigned long spitfire_get_sfar(void)
-{
-	unsigned long ret;
-
-	__asm__ __volatile__("ldxa	[%1] %2, %0"
-			     : "=r" (ret)
-			     : "r" (DMMU_SFAR), "i" (ASI_DMMU));
-	return ret;
-}
-
-static __inline__ void spitfire_put_isfsr(unsigned long sfsr)
-{
-	__asm__ __volatile__("stxa	%0, [%1] %2\n\t"
-			     "membar	#Sync"
-			     : /* no outputs */
-			     : "r" (sfsr), "r" (TLB_SFSR), "i" (ASI_IMMU));
-}
-
-static __inline__ void spitfire_put_dsfsr(unsigned long sfsr)
-{
-	__asm__ __volatile__("stxa	%0, [%1] %2\n\t"
-			     "membar	#Sync"
-			     : /* no outputs */
-			     : "r" (sfsr), "r" (TLB_SFSR), "i" (ASI_DMMU));
-}
-
 /* The data cache is write through, so this just invalidates the
  * specified line.
  */
@@ -111,7 +65,6 @@ static __inline__ void spitfire_put_dcac
 			     "membar	#Sync"
 			     : /* No outputs */
 			     : "r" (tag), "r" (addr), "i" (ASI_DCACHE_TAG));
-	__asm__ __volatile__ ("membar #Sync" : : : "memory");
 }
 
 /* The instruction cache lines are flushed with this, but note that
@@ -194,90 +147,6 @@ static __inline__ void spitfire_put_itlb
 			       "i" (ASI_ITLB_DATA_ACCESS));
 }
 
-/* Spitfire hardware assisted TLB flushes. */
-
-/* Context level flushes. */
-static __inline__ void spitfire_flush_dtlb_primary_context(void)
-{
-	__asm__ __volatile__("stxa	%%g0, [%0] %1\n\t"
-			     "membar	#Sync"
-			     : /* No outputs */
-			     : "r" (0x40), "i" (ASI_DMMU_DEMAP));
-}
-
-static __inline__ void spitfire_flush_itlb_primary_context(void)
-{
-	__asm__ __volatile__("stxa	%%g0, [%0] %1\n\t"
-			     "membar	#Sync"
-			     : /* No outputs */
-			     : "r" (0x40), "i" (ASI_IMMU_DEMAP));
-}
-
-static __inline__ void spitfire_flush_dtlb_secondary_context(void)
-{
-	__asm__ __volatile__("stxa	%%g0, [%0] %1\n\t"
-			     "membar	#Sync"
-			     : /* No outputs */
-			     : "r" (0x50), "i" (ASI_DMMU_DEMAP));
-}
-
-static __inline__ void spitfire_flush_itlb_secondary_context(void)
-{
-	__asm__ __volatile__("stxa	%%g0, [%0] %1\n\t"
-			     "membar	#Sync"
-			     : /* No outputs */
-			     : "r" (0x50), "i" (ASI_IMMU_DEMAP));
-}
-
-static __inline__ void spitfire_flush_dtlb_nucleus_context(void)
-{
-	__asm__ __volatile__("stxa	%%g0, [%0] %1\n\t"
-			     "membar	#Sync"
-			     : /* No outputs */
-			     : "r" (0x60), "i" (ASI_DMMU_DEMAP));
-}
-
-static __inline__ void spitfire_flush_itlb_nucleus_context(void)
-{
-	__asm__ __volatile__("stxa	%%g0, [%0] %1\n\t"
-			     "membar	#Sync"
-			     : /* No outputs */
-			     : "r" (0x60), "i" (ASI_IMMU_DEMAP));
-}
-
-/* Page level flushes. */
-static __inline__ void spitfire_flush_dtlb_primary_page(unsigned long page)
-{
-	__asm__ __volatile__("stxa	%%g0, [%0] %1\n\t"
-			     "membar	#Sync"
-			     : /* No outputs */
-			     : "r" (page), "i" (ASI_DMMU_DEMAP));
-}
-
-static __inline__ void spitfire_flush_itlb_primary_page(unsigned long page)
-{
-	__asm__ __volatile__("stxa	%%g0, [%0] %1\n\t"
-			     "membar	#Sync"
-			     : /* No outputs */
-			     : "r" (page), "i" (ASI_IMMU_DEMAP));
-}
-
-static __inline__ void spitfire_flush_dtlb_secondary_page(unsigned long page)
-{
-	__asm__ __volatile__("stxa	%%g0, [%0] %1\n\t"
-			     "membar	#Sync"
-			     : /* No outputs */
-			     : "r" (page | 0x10), "i" (ASI_DMMU_DEMAP));
-}
-
-static __inline__ void spitfire_flush_itlb_secondary_page(unsigned long page)
-{
-	__asm__ __volatile__("stxa	%%g0, [%0] %1\n\t"
-			     "membar	#Sync"
-			     : /* No outputs */
-			     : "r" (page | 0x10), "i" (ASI_IMMU_DEMAP));
-}
-
 static __inline__ void spitfire_flush_dtlb_nucleus_page(unsigned long page)
 {
 	__asm__ __volatile__("stxa	%%g0, [%0] %1\n\t"
diff --git a/include/asm-sparc64/system.h b/include/asm-sparc64/system.h
--- a/include/asm-sparc64/system.h
+++ b/include/asm-sparc64/system.h
@@ -139,19 +139,13 @@ extern void __flushw_user(void);
 #define flush_user_windows flushw_user
 #define flush_register_windows flushw_all
 
-#define prepare_arch_switch(rq, next)		\
-do {	spin_lock(&(next)->switch_lock);	\
-	spin_unlock(&(rq)->lock);		\
+/* Don't hold the runqueue lock over context switch */
+#define __ARCH_WANT_UNLOCKED_CTXSW
+#define prepare_arch_switch(next)		\
+do {						\
 	flushw_all();				\
 } while (0)
 
-#define finish_arch_switch(rq, prev)		\
-do {	spin_unlock_irq(&(prev)->switch_lock);	\
-} while (0)
-
-#define task_running(rq, p) \
-	((rq)->curr == (p) || spin_is_locked(&(p)->switch_lock))
-
 	/* See what happens when you design the chip correctly?
 	 *
 	 * We tell gcc we clobber all non-fixed-usage registers except
@@ -196,24 +190,23 @@ do {	if (test_thread_flag(TIF_PERFCTR)) 
 	"wrpr	%%g1, %%cwp\n\t"					\
 	"ldx	[%%g6 + %3], %%o6\n\t"					\
 	"ldub	[%%g6 + %2], %%o5\n\t"					\
-	"ldx	[%%g6 + %4], %%o7\n\t"					\
+	"ldub	[%%g6 + %4], %%o7\n\t"					\
 	"mov	%%g6, %%l2\n\t"						\
 	"wrpr	%%o5, 0x0, %%wstate\n\t"				\
 	"ldx	[%%sp + 2047 + 0x70], %%i6\n\t"				\
 	"ldx	[%%sp + 2047 + 0x78], %%i7\n\t"				\
 	"wrpr	%%g0, 0x94, %%pstate\n\t"				\
 	"mov	%%l2, %%g6\n\t"						\
-	"ldx	[%%g6 + %7], %%g4\n\t"					\
+	"ldx	[%%g6 + %6], %%g4\n\t"					\
 	"wrpr	%%g0, 0x96, %%pstate\n\t"				\
-	"andcc	%%o7, %6, %%g0\n\t"					\
-	"beq,pt %%icc, 1f\n\t"						\
+	"brz,pt %%o7, 1f\n\t"						\
 	" mov	%%g7, %0\n\t"						\
 	"b,a ret_from_syscall\n\t"					\
 	"1:\n\t"							\
 	: "=&r" (last)							\
 	: "0" (next->thread_info),					\
-	  "i" (TI_WSTATE), "i" (TI_KSP), "i" (TI_FLAGS), "i" (TI_CWP),	\
-	  "i" (_TIF_NEWCHILD), "i" (TI_TASK)				\
+	  "i" (TI_WSTATE), "i" (TI_KSP), "i" (TI_NEW_CHILD),            \
+	  "i" (TI_CWP), "i" (TI_TASK)					\
 	: "cc",								\
 	        "g1", "g2", "g3",                   "g7",		\
 	              "l2", "l3", "l4", "l5", "l6", "l7",		\
diff --git a/include/asm-sparc64/termios.h b/include/asm-sparc64/termios.h
--- a/include/asm-sparc64/termios.h
+++ b/include/asm-sparc64/termios.h
@@ -100,16 +100,17 @@ struct winsize {
 #define user_termio_to_kernel_termios(termios, termio) \
 ({ \
 	unsigned short tmp; \
-	get_user(tmp, &(termio)->c_iflag); \
+	int err; \
+	err = get_user(tmp, &(termio)->c_iflag); \
 	(termios)->c_iflag = (0xffff0000 & ((termios)->c_iflag)) | tmp; \
-	get_user(tmp, &(termio)->c_oflag); \
+	err |= get_user(tmp, &(termio)->c_oflag); \
 	(termios)->c_oflag = (0xffff0000 & ((termios)->c_oflag)) | tmp; \
-	get_user(tmp, &(termio)->c_cflag); \
+	err |= get_user(tmp, &(termio)->c_cflag); \
 	(termios)->c_cflag = (0xffff0000 & ((termios)->c_cflag)) | tmp; \
-	get_user(tmp, &(termio)->c_lflag); \
+	err |= get_user(tmp, &(termio)->c_lflag); \
 	(termios)->c_lflag = (0xffff0000 & ((termios)->c_lflag)) | tmp; \
-	copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \
-	0; \
+	err |= copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \
+	err; \
 })
 
 /*
@@ -119,53 +120,56 @@ struct winsize {
  */
 #define kernel_termios_to_user_termio(termio, termios) \
 ({ \
-	put_user((termios)->c_iflag, &(termio)->c_iflag); \
-	put_user((termios)->c_oflag, &(termio)->c_oflag); \
-	put_user((termios)->c_cflag, &(termio)->c_cflag); \
-	put_user((termios)->c_lflag, &(termio)->c_lflag); \
-	put_user((termios)->c_line,  &(termio)->c_line); \
-	copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \
+	int err; \
+	err  = put_user((termios)->c_iflag, &(termio)->c_iflag); \
+	err |= put_user((termios)->c_oflag, &(termio)->c_oflag); \
+	err |= put_user((termios)->c_cflag, &(termio)->c_cflag); \
+	err |= put_user((termios)->c_lflag, &(termio)->c_lflag); \
+	err |= put_user((termios)->c_line,  &(termio)->c_line); \
+	err |= copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \
 	if (!((termios)->c_lflag & ICANON)) { \
-		put_user((termios)->c_cc[VMIN], &(termio)->c_cc[_VMIN]); \
-		put_user((termios)->c_cc[VTIME], &(termio)->c_cc[_VTIME]); \
+		err |= put_user((termios)->c_cc[VMIN], &(termio)->c_cc[_VMIN]); \
+		err |= put_user((termios)->c_cc[VTIME], &(termio)->c_cc[_VTIME]); \
 	} \
-	0; \
+	err; \
 })
 
 #define user_termios_to_kernel_termios(k, u) \
 ({ \
-	get_user((k)->c_iflag, &(u)->c_iflag); \
-	get_user((k)->c_oflag, &(u)->c_oflag); \
-	get_user((k)->c_cflag, &(u)->c_cflag); \
-	get_user((k)->c_lflag, &(u)->c_lflag); \
-	get_user((k)->c_line,  &(u)->c_line); \
-	copy_from_user((k)->c_cc, (u)->c_cc, NCCS); \
+	int err; \
+	err  = get_user((k)->c_iflag, &(u)->c_iflag); \
+	err |= get_user((k)->c_oflag, &(u)->c_oflag); \
+	err |= get_user((k)->c_cflag, &(u)->c_cflag); \
+	err |= get_user((k)->c_lflag, &(u)->c_lflag); \
+	err |= get_user((k)->c_line,  &(u)->c_line); \
+	err |= copy_from_user((k)->c_cc, (u)->c_cc, NCCS); \
 	if((k)->c_lflag & ICANON) { \
-		get_user((k)->c_cc[VEOF], &(u)->c_cc[VEOF]); \
-		get_user((k)->c_cc[VEOL], &(u)->c_cc[VEOL]); \
+		err |= get_user((k)->c_cc[VEOF], &(u)->c_cc[VEOF]); \
+		err |= get_user((k)->c_cc[VEOL], &(u)->c_cc[VEOL]); \
 	} else { \
-		get_user((k)->c_cc[VMIN],  &(u)->c_cc[_VMIN]); \
-		get_user((k)->c_cc[VTIME], &(u)->c_cc[_VTIME]); \
+		err |= get_user((k)->c_cc[VMIN],  &(u)->c_cc[_VMIN]); \
+		err |= get_user((k)->c_cc[VTIME], &(u)->c_cc[_VTIME]); \
 	} \
-	0; \
+	err; \
 })
 
 #define kernel_termios_to_user_termios(u, k) \
 ({ \
-	put_user((k)->c_iflag, &(u)->c_iflag); \
-	put_user((k)->c_oflag, &(u)->c_oflag); \
-	put_user((k)->c_cflag, &(u)->c_cflag); \
-	put_user((k)->c_lflag, &(u)->c_lflag); \
-	put_user((k)->c_line, &(u)->c_line); \
-	copy_to_user((u)->c_cc, (k)->c_cc, NCCS); \
+	int err; \
+	err  = put_user((k)->c_iflag, &(u)->c_iflag); \
+	err |= put_user((k)->c_oflag, &(u)->c_oflag); \
+	err |= put_user((k)->c_cflag, &(u)->c_cflag); \
+	err |= put_user((k)->c_lflag, &(u)->c_lflag); \
+	err |= put_user((k)->c_line, &(u)->c_line); \
+	err |= copy_to_user((u)->c_cc, (k)->c_cc, NCCS); \
 	if(!((k)->c_lflag & ICANON)) { \
-		put_user((k)->c_cc[VMIN],  &(u)->c_cc[_VMIN]); \
-		put_user((k)->c_cc[VTIME], &(u)->c_cc[_VTIME]); \
+		err |= put_user((k)->c_cc[VMIN],  &(u)->c_cc[_VMIN]); \
+		err |= put_user((k)->c_cc[VTIME], &(u)->c_cc[_VTIME]); \
 	} else { \
-		put_user((k)->c_cc[VEOF], &(u)->c_cc[VEOF]); \
-		put_user((k)->c_cc[VEOL], &(u)->c_cc[VEOL]); \
+		err |= put_user((k)->c_cc[VEOF], &(u)->c_cc[VEOF]); \
+		err |= put_user((k)->c_cc[VEOL], &(u)->c_cc[VEOL]); \
 	} \
-	0; \
+	err; \
 })
 
 #endif	/* __KERNEL__ */
diff --git a/include/asm-sparc64/thread_info.h b/include/asm-sparc64/thread_info.h
--- a/include/asm-sparc64/thread_info.h
+++ b/include/asm-sparc64/thread_info.h
@@ -46,8 +46,10 @@ struct thread_info {
 	unsigned long		fault_address;
 	struct pt_regs		*kregs;
 	struct exec_domain	*exec_domain;
-	int			preempt_count;
-	int			__pad;
+	int			preempt_count;	/* 0 => preemptable, <0 => BUG */
+	__u8			new_child;
+	__u8			syscall_noerror;
+	__u16			__pad;
 
 	unsigned long		*utraps;
 
@@ -66,6 +68,9 @@ struct thread_info {
 
 	struct restart_block	restart_block;
 
+	struct pt_regs		*kern_una_regs;
+	unsigned int		kern_una_insn;
+
 	unsigned long		fpregs[0] __attribute__ ((aligned(64)));
 };
 
@@ -87,6 +92,8 @@ struct thread_info {
 #define TI_KREGS	0x00000028
 #define TI_EXEC_DOMAIN	0x00000030
 #define TI_PRE_COUNT	0x00000038
+#define TI_NEW_CHILD	0x0000003c
+#define TI_SYS_NOERROR	0x0000003d
 #define TI_UTRAPS	0x00000040
 #define TI_REG_WINDOW	0x00000048
 #define TI_RWIN_SPTRS	0x000003c8	
@@ -99,6 +106,8 @@ struct thread_info {
 #define TI_PCR		0x00000490
 #define TI_CEE_STUFF	0x00000498
 #define TI_RESTART_BLOCK 0x000004a0
+#define TI_KUNA_REGS	0x000004c8
+#define TI_KUNA_INSN	0x000004d0
 #define TI_FPREGS	0x00000500
 
 /* We embed this in the uppermost byte of thread_info->flags */
@@ -219,16 +228,17 @@ register struct thread_info *current_thr
 #define TIF_UNALIGNED		5	/* allowed to do unaligned accesses */
 #define TIF_NEWSIGNALS		6	/* wants new-style signals */
 #define TIF_32BIT		7	/* 32-bit binary */
-#define TIF_NEWCHILD		8	/* just-spawned child process */
-/* TIF_* value 9 is available */
-#define TIF_POLLING_NRFLAG	10
-#define TIF_SYSCALL_SUCCESS	11
+/* flag bit 8 is available */
+#define TIF_SECCOMP		9	/* secure computing */
+#define TIF_SYSCALL_AUDIT	10	/* syscall auditing active */
+/* flag bit 11 is available */
 /* NOTE: Thread flags >= 12 should be ones we have no interest
  *       in using in assembly, else we can't use the mask as
  *       an immediate value in instructions such as andcc.
  */
 #define TIF_ABI_PENDING		12
 #define TIF_MEMDIE		13
+#define TIF_POLLING_NRFLAG	14
 
 #define _TIF_SYSCALL_TRACE	(1<<TIF_SYSCALL_TRACE)
 #define _TIF_NOTIFY_RESUME	(1<<TIF_NOTIFY_RESUME)
@@ -238,10 +248,10 @@ register struct thread_info *current_thr
 #define _TIF_UNALIGNED		(1<<TIF_UNALIGNED)
 #define _TIF_NEWSIGNALS		(1<<TIF_NEWSIGNALS)
 #define _TIF_32BIT		(1<<TIF_32BIT)
-#define _TIF_NEWCHILD		(1<<TIF_NEWCHILD)
-#define _TIF_POLLING_NRFLAG	(1<<TIF_POLLING_NRFLAG)
+#define _TIF_SECCOMP		(1<<TIF_SECCOMP)
+#define _TIF_SYSCALL_AUDIT	(1<<TIF_SYSCALL_AUDIT)
 #define _TIF_ABI_PENDING	(1<<TIF_ABI_PENDING)
-#define _TIF_SYSCALL_SUCCESS	(1<<TIF_SYSCALL_SUCCESS)
+#define _TIF_POLLING_NRFLAG	(1<<TIF_POLLING_NRFLAG)
 
 #define _TIF_USER_WORK_MASK	((0xff << TI_FLAG_WSAVED_SHIFT) | \
 				 (_TIF_NOTIFY_RESUME | _TIF_SIGPENDING | \
diff --git a/include/asm-sparc64/timer.h b/include/asm-sparc64/timer.h
--- a/include/asm-sparc64/timer.h
+++ b/include/asm-sparc64/timer.h
@@ -9,49 +9,8 @@
 
 #include <linux/types.h>
 
-/* How timers work:
- *
- * On uniprocessors we just use counter zero for the system wide
- * ticker, this performs thread scheduling, clock book keeping,
- * and runs timer based events.  Previously we used the Ultra
- * %tick interrupt for this purpose.
- *
- * On multiprocessors we pick one cpu as the master level 10 tick
- * processor.  Here this counter zero tick handles clock book
- * keeping and timer events only.  Each Ultra has it's level
- * 14 %tick interrupt set to fire off as well, even the master
- * tick cpu runs this locally.  This ticker performs thread
- * scheduling, system/user tick counting for the current thread,
- * and also profiling if enabled.
- */
-
 #include <linux/config.h>
 
-/* Two timers, traditionally steered to PIL's 10 and 14 respectively.
- * But since INO packets are used on sun5, we could use any PIL level
- * we like, however for now we use the normal ones.
- *
- * The 'reg' and 'interrupts' properties for these live in nodes named
- * 'counter-timer'.  The first of three 'reg' properties describe where
- * the sun5_timer registers are.  The other two I have no idea. (XXX)
- */
-struct sun5_timer {
-	u64	count0;
-	u64	limit0;
-	u64	count1;
-	u64	limit1;
-};
-
-#define SUN5_LIMIT_ENABLE	0x80000000
-#define SUN5_LIMIT_TOZERO	0x40000000
-#define SUN5_LIMIT_ZRESTART	0x20000000
-#define SUN5_LIMIT_CMASK	0x1fffffff
-
-/* Given a HZ value, set the limit register to so that the timer IRQ
- * gets delivered that often.
- */
-#define SUN5_HZ_TO_LIMIT(__hz)  (1000000/(__hz))
-
 struct sparc64_tick_ops {
 	void (*init_tick)(unsigned long);
 	unsigned long (*get_tick)(void);
diff --git a/include/asm-sparc64/unistd.h b/include/asm-sparc64/unistd.h
--- a/include/asm-sparc64/unistd.h
+++ b/include/asm-sparc64/unistd.h
@@ -167,12 +167,12 @@
 #define __NR_pciconfig_read	148 /* ENOSYS under SunOS                          */
 #define __NR_pciconfig_write	149 /* ENOSYS under SunOS                          */
 #define __NR_getsockname        150 /* Common                                      */
-/* #define __NR_getmsg          151    SunOS Specific                              */
-/* #define __NR_putmsg          152    SunOS Specific                              */
+#define __NR_inotify_init       151 /* Linux specific                              */
+#define __NR_inotify_add_watch  152 /* Linux specific                              */
 #define __NR_poll               153 /* Common                                      */
 #define __NR_getdents64		154 /* Linux specific				   */
 /* #define __NR_fcntl64         155    Linux sparc32 Specific                      */
-/* #define __NR_getdirentries   156    SunOS Specific                              */
+#define __NR_inotify_rm_watch   156 /* Linux specific				   */
 #define __NR_statfs             157 /* Common                                      */
 #define __NR_fstatfs            158 /* Common                                      */
 #define __NR_umount             159 /* Common                                      */
@@ -212,7 +212,7 @@
 #define __NR_epoll_create       193 /* Linux Specific                              */
 #define __NR_epoll_ctl          194 /* Linux Specific                              */
 #define __NR_epoll_wait         195 /* Linux Specific                              */
-/* #define __NR_ulimit          196    Linux Specific                              */
+#define __NR_ioprio_set         196 /* Linux Specific                              */
 #define __NR_getppid            197 /* Linux Specific                              */
 #define __NR_sigaction          198 /* Linux Specific                              */
 #define __NR_sgetmask           199 /* Linux Specific                              */
@@ -234,7 +234,7 @@
 #define __NR_ipc                215 /* Linux Specific                              */
 #define __NR_sigreturn          216 /* Linux Specific                              */
 #define __NR_clone              217 /* Linux Specific                              */
-/* #define __NR_modify_ldt      218    Linux Specific - i386 specific, unused      */
+#define __NR_ioprio_get         218 /* Linux Specific                              */
 #define __NR_adjtimex           219 /* Linux Specific                              */
 #define __NR_sigprocmask        220 /* Linux Specific                              */
 #define __NR_create_module      221 /* Linux Specific                              */
diff --git a/include/asm-um/emergency-restart.h b/include/asm-um/emergency-restart.h
new file mode 100644
--- /dev/null
+++ b/include/asm-um/emergency-restart.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_EMERGENCY_RESTART_H
+#define _ASM_EMERGENCY_RESTART_H
+
+#include <asm-generic/emergency-restart.h>
+
+#endif /* _ASM_EMERGENCY_RESTART_H */
diff --git a/include/asm-um/ldt.h b/include/asm-um/ldt.h
new file mode 100644
--- /dev/null
+++ b/include/asm-um/ldt.h
@@ -0,0 +1,5 @@
+#ifndef __UM_LDT_H
+#define __UM_LDT_H
+
+#include "asm/arch/ldt.h"
+#endif
diff --git a/include/asm-um/mmu_context.h b/include/asm-um/mmu_context.h
--- a/include/asm-um/mmu_context.h
+++ b/include/asm-um/mmu_context.h
@@ -7,19 +7,23 @@
 #define __UM_MMU_CONTEXT_H
 
 #include "linux/sched.h"
+#include "linux/config.h"
 #include "choose-mode.h"
+#include "um_mmu.h"
 
 #define get_mmu_context(task) do ; while(0)
 #define activate_context(tsk) do ; while(0)
 
 #define deactivate_mm(tsk,mm)	do { } while (0)
 
+extern void force_flush_all(void);
+
 static inline void activate_mm(struct mm_struct *old, struct mm_struct *new)
 {
+	if (old != new)
+		force_flush_all();
 }
 
-extern void switch_mm_skas(int mm_fd);
-
 static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, 
 			     struct task_struct *tsk)
 {
@@ -30,7 +34,7 @@ static inline void switch_mm(struct mm_s
 		cpu_set(cpu, next->cpu_vm_mask);
 		if(next != &init_mm)
 			CHOOSE_MODE((void) 0, 
-				    switch_mm_skas(next->context.skas.mm_fd));
+				    switch_mm_skas(&next->context.skas.id));
 	}
 }
 
diff --git a/include/asm-um/page.h b/include/asm-um/page.h
--- a/include/asm-um/page.h
+++ b/include/asm-um/page.h
@@ -104,8 +104,8 @@ extern void *to_virt(unsigned long phys)
  * casting is the right thing, but 32-bit UML can't have 64-bit virtual
  * addresses
  */
-#define __pa(virt) to_phys((void *) (unsigned long) virt)
-#define __va(phys) to_virt((unsigned long) phys)
+#define __pa(virt) to_phys((void *) (unsigned long) (virt))
+#define __va(phys) to_virt((unsigned long) (phys))
 
 #define page_to_pfn(page) ((page) - mem_map)
 #define pfn_to_page(pfn) (mem_map + (pfn))
diff --git a/include/asm-um/ptrace-i386.h b/include/asm-um/ptrace-i386.h
--- a/include/asm-um/ptrace-i386.h
+++ b/include/asm-um/ptrace-i386.h
@@ -32,6 +32,10 @@
 #define PT_REGS_SYSCALL_RET(r) PT_REGS_EAX(r)
 #define PT_FIX_EXEC_STACK(sp) do ; while(0)
 
+/* Cope with a conditional i386 definition. */
+#undef profile_pc
+#define profile_pc(regs) PT_REGS_IP(regs)
+
 #define user_mode(r) UPT_IS_USER(&(r)->regs)
 
 #endif
diff --git a/include/asm-um/smp.h b/include/asm-um/smp.h
--- a/include/asm-um/smp.h
+++ b/include/asm-um/smp.h
@@ -8,7 +8,8 @@
 #include "asm/current.h"
 #include "linux/cpumask.h"
 
-#define smp_processor_id() (current_thread->cpu)
+#define raw_smp_processor_id() (current_thread->cpu)
+
 #define cpu_logical_map(n) (n)
 #define cpu_number_map(n) (n)
 #define PROC_CHANGE_PENALTY	15 /* Pick a number, any number */
diff --git a/include/asm-um/thread_info.h b/include/asm-um/thread_info.h
--- a/include/asm-um/thread_info.h
+++ b/include/asm-um/thread_info.h
@@ -17,7 +17,7 @@ struct thread_info {
 	struct exec_domain	*exec_domain;	/* execution domain */
 	unsigned long		flags;		/* low level flags */
 	__u32			cpu;		/* current CPU */
-	__s32			preempt_count;  /* 0 => preemptable, 
+	int			preempt_count;  /* 0 => preemptable,
 						   <0 => BUG */
 	mm_segment_t		addr_limit;	/* thread address space:
 					 	   0-0xBFFFFFFF for user
diff --git a/include/asm-um/vm86.h b/include/asm-um/vm86.h
new file mode 100644
--- /dev/null
+++ b/include/asm-um/vm86.h
@@ -0,0 +1,6 @@
+#ifndef __UM_VM86_H
+#define __UM_VM86_H
+
+#include "asm/arch/vm86.h"
+
+#endif
diff --git a/include/asm-v850/bitops.h b/include/asm-v850/bitops.h
--- a/include/asm-v850/bitops.h
+++ b/include/asm-v850/bitops.h
@@ -1,8 +1,8 @@
 /*
  * include/asm-v850/bitops.h -- Bit operations
  *
- *  Copyright (C) 2001,02,03,04  NEC Electronics Corporation
- *  Copyright (C) 2001,02,03,04  Miles Bader <miles@gnu.org>
+ *  Copyright (C) 2001,02,03,04,05  NEC Electronics Corporation
+ *  Copyright (C) 2001,02,03,04,05  Miles Bader <miles@gnu.org>
  *  Copyright (C) 1992  Linus Torvalds.
  *
  * This file is subject to the terms and conditions of the GNU General
@@ -157,7 +157,7 @@ extern __inline__ int __test_bit (int nr
 #define find_first_zero_bit(addr, size) \
   find_next_zero_bit ((addr), (size), 0)
 
-extern __inline__ int find_next_zero_bit (void *addr, int size, int offset)
+extern __inline__ int find_next_zero_bit(const void *addr, int size, int offset)
 {
 	unsigned long *p = ((unsigned long *) addr) + (offset >> 5);
 	unsigned long result = offset & ~31UL;
diff --git a/include/asm-v850/cache.h b/include/asm-v850/cache.h
--- a/include/asm-v850/cache.h
+++ b/include/asm-v850/cache.h
@@ -1,8 +1,8 @@
 /*
  * include/asm-v850/cache.h -- Cache operations
  *
- *  Copyright (C) 2001  NEC Corporation
- *  Copyright (C) 2001  Miles Bader <miles@gnu.org>
+ *  Copyright (C) 2001,05  NEC Corporation
+ *  Copyright (C) 2001,05  Miles Bader <miles@gnu.org>
  *
  * This file is subject to the terms and conditions of the GNU General
  * Public License.  See the file COPYING in the main directory of this
@@ -20,6 +20,9 @@
 #ifndef L1_CACHE_BYTES
 /* This processor has no cache, so just choose an arbitrary value.  */
 #define L1_CACHE_BYTES		16
+#define L1_CACHE_SHIFT		4
 #endif
 
+#define L1_CACHE_SHIFT_MAX	L1_CACHE_SHIFT
+
 #endif /* __V850_CACHE_H__ */
diff --git a/include/asm-v850/checksum.h b/include/asm-v850/checksum.h
--- a/include/asm-v850/checksum.h
+++ b/include/asm-v850/checksum.h
@@ -1,8 +1,8 @@
 /*
  * include/asm-v850/checksum.h -- Checksum ops
  *
- *  Copyright (C) 2001  NEC Corporation
- *  Copyright (C) 2001  Miles Bader <miles@gnu.org>
+ *  Copyright (C) 2001,2005  NEC Corporation
+ *  Copyright (C) 2001,2005  Miles Bader <miles@gnu.org>
  *
  * This file is subject to the terms and conditions of the GNU General
  * Public License.  See the file COPYING in the main directory of this
@@ -36,8 +36,8 @@ extern unsigned int csum_partial (const 
  * here even more important to align src and dst on a 32-bit (or even
  * better 64-bit) boundary
  */
-extern unsigned csum_partial_copy (const char *src, char *dst, int len,
-				   unsigned sum);
+extern unsigned csum_partial_copy (const unsigned char *src,
+				   unsigned char *dst, int len, unsigned sum);
 
 
 /*
@@ -46,7 +46,8 @@ extern unsigned csum_partial_copy (const
  * here even more important to align src and dst on a 32-bit (or even
  * better 64-bit) boundary
  */
-extern unsigned csum_partial_copy_from_user (const char *src, char *dst,
+extern unsigned csum_partial_copy_from_user (const unsigned char *src,
+					     unsigned char *dst,
 					     int len, unsigned sum,
 					     int *csum_err);
 
diff --git a/include/asm-v850/emergency-restart.h b/include/asm-v850/emergency-restart.h
new file mode 100644
--- /dev/null
+++ b/include/asm-v850/emergency-restart.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_EMERGENCY_RESTART_H
+#define _ASM_EMERGENCY_RESTART_H
+
+#include <asm-generic/emergency-restart.h>
+
+#endif /* _ASM_EMERGENCY_RESTART_H */
diff --git a/include/asm-v850/io.h b/include/asm-v850/io.h
--- a/include/asm-v850/io.h
+++ b/include/asm-v850/io.h
@@ -1,8 +1,8 @@
 /*
  * include/asm-v850/io.h -- Misc I/O operations
  *
- *  Copyright (C) 2001,02,03,04  NEC Electronics Corporation
- *  Copyright (C) 2001,02,03,04  Miles Bader <miles@gnu.org>
+ *  Copyright (C) 2001,02,03,04,05  NEC Electronics Corporation
+ *  Copyright (C) 2001,02,03,04,05  Miles Bader <miles@gnu.org>
  *
  * This file is subject to the terms and conditions of the GNU General
  * Public License.  See the file COPYING in the main directory of this
@@ -27,12 +27,12 @@
 #define readw_relaxed(a) readw(a)
 #define readl_relaxed(a) readl(a)
 
-#define writeb(b, addr) \
-  (void)((*(volatile unsigned char *) (addr)) = (b))
-#define writew(b, addr) \
-  (void)((*(volatile unsigned short *) (addr)) = (b))
-#define writel(b, addr) \
-  (void)((*(volatile unsigned int *) (addr)) = (b))
+#define writeb(val, addr) \
+  (void)((*(volatile unsigned char *) (addr)) = (val))
+#define writew(val, addr) \
+  (void)((*(volatile unsigned short *) (addr)) = (val))
+#define writel(val, addr) \
+  (void)((*(volatile unsigned int *) (addr)) = (val))
 
 #define __raw_readb readb
 #define __raw_readw readw
@@ -96,11 +96,22 @@ outsl (unsigned long port, const void *s
 		outl (*p++, port);
 }
 
-#define iounmap(addr)				((void)0)
-#define ioremap(physaddr, size)			(physaddr)
-#define ioremap_nocache(physaddr, size)		(physaddr)
-#define ioremap_writethrough(physaddr, size)	(physaddr)
-#define ioremap_fullcache(physaddr, size)	(physaddr)
+
+/* Some places try to pass in an loff_t for PHYSADDR (?!), so we cast it to
+   long before casting it to a pointer to avoid compiler warnings.  */
+#define ioremap(physaddr, size)	((void __iomem *)(unsigned long)(physaddr))
+#define iounmap(addr)		((void)0)
+
+#define ioremap_nocache(physaddr, size)		ioremap (physaddr, size)
+#define ioremap_writethrough(physaddr, size)	ioremap (physaddr, size)
+#define ioremap_fullcache(physaddr, size)	ioremap (physaddr, size)
+
+#define ioread8(addr)		readb (addr)
+#define ioread16(addr)		readw (addr)
+#define ioread32(addr)		readl (addr)
+#define iowrite8(val, addr)	writeb (val, addr)
+#define iowrite16(val, addr)	writew (val, addr)
+#define iowrite32(val, addr)	writel (val, addr)
 
 #define mmiowb()
 
diff --git a/include/asm-v850/mmu.h b/include/asm-v850/mmu.h
--- a/include/asm-v850/mmu.h
+++ b/include/asm-v850/mmu.h
@@ -1,22 +1,11 @@
-/* Copyright (C) 2002, David McCullough <davidm@snapgear.com> */
+/* Copyright (C) 2002, 2005, David McCullough <davidm@snapgear.com> */
 
 #ifndef __V850_MMU_H__
 #define __V850_MMU_H__
 
-struct mm_rblock_struct {
-	int		size;
-	int		refcount;
-	void	*kblock;
-};
-
-struct mm_tblock_struct {
-	struct mm_rblock_struct	*rblock;
-	struct mm_tblock_struct	*next;
-};
-
 typedef struct {
-	struct mm_tblock_struct	tblock;
-	unsigned long			end_brk;
+	struct vm_list_struct	*vmlist;
+	unsigned long		end_brk;
 } mm_context_t;
 
 #endif /* __V850_MMU_H__ */
diff --git a/include/asm-v850/page.h b/include/asm-v850/page.h
--- a/include/asm-v850/page.h
+++ b/include/asm-v850/page.h
@@ -1,8 +1,8 @@
 /*
  * include/asm-v850/page.h -- VM ops
  *
- *  Copyright (C) 2001,02,03  NEC Electronics Corporation
- *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
+ *  Copyright (C) 2001,02,03,05  NEC Electronics Corporation
+ *  Copyright (C) 2001,02,03,05  Miles Bader <miles@gnu.org>
  *
  * This file is subject to the terms and conditions of the GNU General
  * Public License.  See the file COPYING in the main directory of this
@@ -132,6 +132,7 @@ extern __inline__ int get_order (unsigne
 
 #define pfn_to_page(pfn)	virt_to_page (pfn_to_virt (pfn))
 #define page_to_pfn(page)	virt_to_pfn (page_to_virt (page))
+#define pfn_valid(pfn)	        ((pfn) < max_mapnr)
 
 #define	virt_addr_valid(kaddr)						\
   (((void *)(kaddr) >= (void *)PAGE_OFFSET) && MAP_NR (kaddr) < max_mapnr)
diff --git a/include/asm-v850/pci.h b/include/asm-v850/pci.h
--- a/include/asm-v850/pci.h
+++ b/include/asm-v850/pci.h
@@ -1,8 +1,8 @@
 /*
  * include/asm-v850/pci.h -- PCI support
  *
- *  Copyright (C) 2001,02  NEC Corporation
- *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *  Copyright (C) 2001,02,05  NEC Corporation
+ *  Copyright (C) 2001,02,05  Miles Bader <miles@gnu.org>
  *
  * This file is subject to the terms and conditions of the GNU General
  * Public License.  See the file COPYING in the main directory of this
@@ -48,12 +48,12 @@ pci_unmap_single (struct pci_dev *pdev, 
    perform a pci_dma_sync_for_device, and then the device again owns
    the buffer.  */
 extern void
-pci_dma_sync_single_for_cpu (struct pci_dev *dev, dma_addr_t dma_addr, size_t size,
-		     int dir);
+pci_dma_sync_single_for_cpu (struct pci_dev *dev, dma_addr_t dma_addr,
+			     size_t size, int dir);
 
 extern void
-pci_dma_sync_single_for_device (struct pci_dev *dev, dma_addr_t dma_addr, size_t size,
-		     int dir);
+pci_dma_sync_single_for_device (struct pci_dev *dev, dma_addr_t dma_addr,
+				size_t size, int dir);
 
 
 /* Do multiple DMA mappings at once.  */
@@ -65,6 +65,28 @@ extern void
 pci_unmap_sg (struct pci_dev *pdev, struct scatterlist *sg, int sg_len,
 	      int dir);
 
+/* SG-list versions of pci_dma_sync functions.  */
+extern void
+pci_dma_sync_sg_for_cpu (struct pci_dev *dev,
+			 struct scatterlist *sg, int sg_len,
+			 int dir);
+extern void
+pci_dma_sync_sg_for_device (struct pci_dev *dev,
+			    struct scatterlist *sg, int sg_len,
+			    int dir);
+
+#define pci_map_page(dev, page, offs, size, dir) \
+  pci_map_single(dev, (page_address(page) + (offs)), size, dir)
+#define pci_unmap_page(dev,addr,sz,dir) \
+  pci_unmap_single(dev, addr, sz, dir)
+
+/* Test for pci_map_single or pci_map_page having generated an error.  */
+static inline int
+pci_dma_mapping_error (dma_addr_t dma_addr)
+{
+	return dma_addr == 0;
+}
+
 /* Allocate and map kernel buffer using consistent mode DMA for PCI
    device.  Returns non-NULL cpu-view pointer to the buffer if
    successful and sets *DMA_ADDR to the pci side dma address as well,
@@ -81,6 +103,19 @@ extern void
 pci_free_consistent (struct pci_dev *pdev, size_t size, void *cpu_addr,
 		     dma_addr_t dma_addr);
 
+#ifdef CONFIG_PCI
+static inline void pci_dma_burst_advice(struct pci_dev *pdev,
+					enum pci_dma_burst_strategy *strat,
+					unsigned long *strategy_parameter)
+{
+	*strat = PCI_DMA_BURST_INFINITY;
+	*strategy_parameter = ~0UL;
+}
+#endif
+
+extern void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max);
+extern void pci_iounmap (struct pci_dev *dev, void __iomem *addr);
+
 static inline void pcibios_add_platform_entries(struct pci_dev *dev)
 {
 }
diff --git a/include/asm-v850/pgtable.h b/include/asm-v850/pgtable.h
--- a/include/asm-v850/pgtable.h
+++ b/include/asm-v850/pgtable.h
@@ -23,6 +23,8 @@
 #define __pte_to_swp_entry(pte)	((swp_entry_t) { pte_val(pte) })
 #define __swp_entry_to_pte(x)	((pte_t) { (x).val })
 
+static inline int pte_file (pte_t pte) { return 0; }
+
 
 /* These mean nothing to !CONFIG_MMU.  */
 #define PAGE_NONE		__pgprot(0)
diff --git a/include/asm-v850/thread_info.h b/include/asm-v850/thread_info.h
--- a/include/asm-v850/thread_info.h
+++ b/include/asm-v850/thread_info.h
@@ -30,7 +30,8 @@ struct thread_info {
 	struct exec_domain	*exec_domain;	/* execution domain */
 	unsigned long		flags;		/* low level flags */
 	int			cpu;		/* cpu we're on */
-	int			preempt_count;
+	int			preempt_count;	/* 0 => preemptable,
+						   <0 => BUG */
 	struct restart_block	restart_block;
 };
 
diff --git a/include/asm-v850/v850e2_cache.h b/include/asm-v850/v850e2_cache.h
--- a/include/asm-v850/v850e2_cache.h
+++ b/include/asm-v850/v850e2_cache.h
@@ -2,8 +2,8 @@
  * include/asm-v850/v850e2_cache_cache.h -- Cache control for V850E2
  * 	cache memories
  *
- *  Copyright (C) 2003  NEC Electronics Corporation
- *  Copyright (C) 2003  Miles Bader <miles@gnu.org>
+ *  Copyright (C) 2003,05  NEC Electronics Corporation
+ *  Copyright (C) 2003,05  Miles Bader <miles@gnu.org>
  *
  * This file is subject to the terms and conditions of the GNU General
  * Public License.  See the file COPYING in the main directory of this
@@ -69,6 +69,7 @@
 
 /* For <asm/cache.h> */
 #define L1_CACHE_BYTES			V850E2_CACHE_LINE_SIZE
+#define L1_CACHE_SHIFT			V850E2_CACHE_LINE_SIZE_BITS
 
 
 #endif /* __V850_V850E2_CACHE_H__ */
diff --git a/include/asm-x86_64/a.out.h b/include/asm-x86_64/a.out.h
--- a/include/asm-x86_64/a.out.h
+++ b/include/asm-x86_64/a.out.h
@@ -21,7 +21,7 @@ struct exec
 
 #ifdef __KERNEL__
 #include <linux/thread_info.h>
-#define STACK_TOP (test_thread_flag(TIF_IA32) ? IA32_PAGE_OFFSET : TASK_SIZE)
+#define STACK_TOP TASK_SIZE
 #endif
 
 #endif /* __A_OUT_GNU_H__ */
diff --git a/include/asm-x86_64/acpi.h b/include/asm-x86_64/acpi.h
--- a/include/asm-x86_64/acpi.h
+++ b/include/asm-x86_64/acpi.h
@@ -28,6 +28,8 @@
 
 #ifdef __KERNEL__
 
+#include <acpi/pdc_intel.h>
+
 #define COMPILER_DEPENDENT_INT64   long long
 #define COMPILER_DEPENDENT_UINT64  unsigned long long
 
@@ -99,12 +101,6 @@ __acpi_release_global_lock (unsigned int
         :"=r"(n_hi), "=r"(n_lo)     \
         :"0"(n_hi), "1"(n_lo))
 
-/*
- * Refer Intel ACPI _PDC support document for bit definitions
- */
-#define ACPI_PDC_EST_CAPABILITY_SMP 	0xa
-#define ACPI_PDC_EST_CAPABILITY_MSR	0x1
-
 #ifdef CONFIG_ACPI_BOOT
 extern int acpi_lapic;
 extern int acpi_ioapic;
diff --git a/include/asm-x86_64/apic.h b/include/asm-x86_64/apic.h
--- a/include/asm-x86_64/apic.h
+++ b/include/asm-x86_64/apic.h
@@ -77,7 +77,7 @@ static inline void ack_APIC_irq(void)
 extern int get_maxlvt (void);
 extern void clear_local_APIC (void);
 extern void connect_bsp_APIC (void);
-extern void disconnect_bsp_APIC (void);
+extern void disconnect_bsp_APIC (int virt_wire_setup);
 extern void disable_local_APIC (void);
 extern int verify_local_APIC (void);
 extern void cache_APIC_registers (void);
diff --git a/include/asm-x86_64/apicdef.h b/include/asm-x86_64/apicdef.h
--- a/include/asm-x86_64/apicdef.h
+++ b/include/asm-x86_64/apicdef.h
@@ -94,7 +94,7 @@
 #define			SET_APIC_DELIVERY_MODE(x,y)	(((x)&~0x700)|((y)<<8))
 #define				APIC_MODE_FIXED		0x0
 #define				APIC_MODE_NMI		0x4
-#define				APIC_MODE_EXINT		0x7
+#define				APIC_MODE_EXTINT	0x7
 #define 	APIC_LVT1	0x360
 #define		APIC_LVTERR	0x370
 #define		APIC_TMICT	0x380
diff --git a/include/asm-x86_64/bitops.h b/include/asm-x86_64/bitops.h
--- a/include/asm-x86_64/bitops.h
+++ b/include/asm-x86_64/bitops.h
@@ -348,8 +348,7 @@ static inline int sched_find_first_bit(c
 		return __ffs(b[0]);
 	if (b[1])
 		return __ffs(b[1]) + 64;
-	if (b[2])
-		return __ffs(b[2]) + 128;
+	return __ffs(b[2]) + 128;
 }
 
 /**
@@ -411,8 +410,6 @@ static __inline__ int ffs(int x)
 /* find last set bit */
 #define fls(x) generic_fls(x)
 
-#define ARCH_HAS_ATOMIC_UNSIGNED 1
-
 #endif /* __KERNEL__ */
 
 #endif /* _X86_64_BITOPS_H */
diff --git a/include/asm-x86_64/bug.h b/include/asm-x86_64/bug.h
--- a/include/asm-x86_64/bug.h
+++ b/include/asm-x86_64/bug.h
@@ -8,17 +8,24 @@
  * this frame.
  */
 struct bug_frame {
-       unsigned char ud2[2];
+	unsigned char ud2[2];
+	unsigned char mov;
 	/* should use 32bit offset instead, but the assembler doesn't 
 	   like it */
 	char *filename;
+	unsigned char ret;
 	unsigned short line;
 } __attribute__((packed));
 
 #ifdef CONFIG_BUG
 #define HAVE_ARCH_BUG
-#define BUG() \
-	asm volatile("ud2 ; .quad %c1 ; .short %c0" :: \
+/* We turn the bug frame into valid instructions to not confuse
+   the disassembler. Thanks to Jan Beulich & Suresh Siddha
+   for nice instruction selection.
+   The magic numbers generate mov $64bitimm,%eax ; ret $offset. */
+#define BUG() 								\
+	asm volatile(							\
+	"ud2 ; .byte 0xa3 ; .quad %c1 ; .byte 0xc2 ; .short %c0" :: 	\
 		     "i"(__LINE__), "i" (__stringify(__FILE__)))
 void out_of_line_bug(void);
 #else
diff --git a/include/asm-x86_64/desc.h b/include/asm-x86_64/desc.h
--- a/include/asm-x86_64/desc.h
+++ b/include/asm-x86_64/desc.h
@@ -75,6 +75,7 @@ struct desc_ptr {
  */
 extern struct desc_struct default_ldt[];
 extern struct gate_struct idt_table[]; 
+extern struct desc_ptr cpu_gdt_descr[];
 
 static inline void _set_gate(void *adr, unsigned type, unsigned long func, unsigned dpl, unsigned ist)  
 {
diff --git a/include/asm-x86_64/e820.h b/include/asm-x86_64/e820.h
--- a/include/asm-x86_64/e820.h
+++ b/include/asm-x86_64/e820.h
@@ -51,6 +51,8 @@ extern int e820_mapped(unsigned long sta
 
 extern void e820_bootmem_free(pg_data_t *pgdat, unsigned long start,unsigned long end);
 extern void e820_setup_gap(void);
+extern unsigned long e820_hole_size(unsigned long start_pfn,
+				    unsigned long end_pfn);
 
 extern void __init parse_memopt(char *p, char **end);
 
diff --git a/include/asm-x86_64/emergency-restart.h b/include/asm-x86_64/emergency-restart.h
new file mode 100644
--- /dev/null
+++ b/include/asm-x86_64/emergency-restart.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_EMERGENCY_RESTART_H
+#define _ASM_EMERGENCY_RESTART_H
+
+extern void machine_emergency_restart(void);
+
+#endif /* _ASM_EMERGENCY_RESTART_H */
diff --git a/include/asm-x86_64/ia32.h b/include/asm-x86_64/ia32.h
--- a/include/asm-x86_64/ia32.h
+++ b/include/asm-x86_64/ia32.h
@@ -94,7 +94,7 @@ typedef struct compat_siginfo{
 
 		/* POSIX.1b timers */
 		struct {
-			int _tid;		/* timer id */
+			compat_timer_t _tid;	/* timer id */
 			int _overrun;		/* overrun count */
 			compat_sigval_t _sigval;	/* same as below */
 			int _sys_private;	/* not to be passed to user */
diff --git a/include/asm-x86_64/ia32_unistd.h b/include/asm-x86_64/ia32_unistd.h
--- a/include/asm-x86_64/ia32_unistd.h
+++ b/include/asm-x86_64/ia32_unistd.h
@@ -294,7 +294,12 @@
 #define __NR_ia32_add_key		286
 #define __NR_ia32_request_key	287
 #define __NR_ia32_keyctl		288
+#define __NR_ia32_ioprio_set		289
+#define __NR_ia32_ioprio_get		290
+#define __NR_ia32_inotify_init		291
+#define __NR_ia32_inotify_add_watch	292
+#define __NR_ia32_inotify_rm_watch	293
 
-#define IA32_NR_syscalls 290	/* must be > than biggest syscall! */
+#define IA32_NR_syscalls 294	/* must be > than biggest syscall! */
 
 #endif /* _ASM_X86_64_IA32_UNISTD_H_ */
diff --git a/include/asm-x86_64/io.h b/include/asm-x86_64/io.h
--- a/include/asm-x86_64/io.h
+++ b/include/asm-x86_64/io.h
@@ -124,12 +124,7 @@ extern inline void * phys_to_virt(unsign
 /*
  * Change "struct page" to physical address.
  */
-#ifdef CONFIG_DISCONTIGMEM
-#include <asm/mmzone.h>
 #define page_to_phys(page)    ((dma_addr_t)page_to_pfn(page) << PAGE_SHIFT)
-#else
-#define page_to_phys(page)	((page - mem_map) << PAGE_SHIFT)
-#endif
 
 #include <asm-generic/iomap.h>
 
diff --git a/include/asm-x86_64/io_apic.h b/include/asm-x86_64/io_apic.h
--- a/include/asm-x86_64/io_apic.h
+++ b/include/asm-x86_64/io_apic.h
@@ -217,4 +217,6 @@ extern int assign_irq_vector(int irq);
 
 void enable_NMI_through_LVT0 (void * dummy);
 
+extern spinlock_t i8259A_lock;
+
 #endif
diff --git a/include/asm-x86_64/ipi.h b/include/asm-x86_64/ipi.h
--- a/include/asm-x86_64/ipi.h
+++ b/include/asm-x86_64/ipi.h
@@ -82,30 +82,27 @@ static inline void send_IPI_mask_sequenc
 	 */
 	local_irq_save(flags);
 
-	for (query_cpu = 0; query_cpu < NR_CPUS; ++query_cpu) {
-		if (cpu_isset(query_cpu, mask)) {
-
-			/*
-			 * Wait for idle.
-			 */
-			apic_wait_icr_idle();
-
-			/*
-			 * prepare target chip field
-			 */
-			cfg = __prepare_ICR2(x86_cpu_to_apicid[query_cpu]);
-			apic_write_around(APIC_ICR2, cfg);
-
-			/*
-			 * program the ICR
-			 */
-			cfg = __prepare_ICR(0, vector, APIC_DEST_PHYSICAL);
-
-			/*
-			 * Send the IPI. The write to APIC_ICR fires this off.
-			 */
-			apic_write_around(APIC_ICR, cfg);
-		}
+	for_each_cpu_mask(query_cpu, mask) {
+		/*
+		 * Wait for idle.
+		 */
+		apic_wait_icr_idle();
+
+		/*
+		 * prepare target chip field
+		 */
+		cfg = __prepare_ICR2(x86_cpu_to_apicid[query_cpu]);
+		apic_write_around(APIC_ICR2, cfg);
+
+		/*
+		 * program the ICR
+		 */
+		cfg = __prepare_ICR(0, vector, APIC_DEST_PHYSICAL);
+
+		/*
+		 * Send the IPI. The write to APIC_ICR fires this off.
+		 */
+		apic_write_around(APIC_ICR, cfg);
 	}
 	local_irq_restore(flags);
 }
diff --git a/include/asm-x86_64/irq.h b/include/asm-x86_64/irq.h
--- a/include/asm-x86_64/irq.h
+++ b/include/asm-x86_64/irq.h
@@ -52,4 +52,11 @@ struct irqaction;
 struct pt_regs;
 int handle_IRQ_event(unsigned int, struct pt_regs *, struct irqaction *);
 
+#ifdef CONFIG_HOTPLUG_CPU
+#include <linux/cpumask.h>
+extern void fixup_irqs(cpumask_t map);
+#endif
+
+#define __ARCH_HAS_DO_SOFTIRQ 1
+
 #endif /* _ASM_IRQ_H */
diff --git a/include/asm-x86_64/kdebug.h b/include/asm-x86_64/kdebug.h
--- a/include/asm-x86_64/kdebug.h
+++ b/include/asm-x86_64/kdebug.h
@@ -14,7 +14,7 @@ struct die_args { 
 }; 
 
 /* Note - you should never unregister because that can race with NMIs.
-   If you really want to do it first unregister - then synchronize_kernel - then free. 
+   If you really want to do it first unregister - then synchronize_sched - then free.
   */
 int register_die_notifier(struct notifier_block *nb);
 extern struct notifier_block *die_chain;
diff --git a/include/asm-x86_64/kexec.h b/include/asm-x86_64/kexec.h
new file mode 100644
--- /dev/null
+++ b/include/asm-x86_64/kexec.h
@@ -0,0 +1,33 @@
+#ifndef _X86_64_KEXEC_H
+#define _X86_64_KEXEC_H
+
+#include <asm/page.h>
+#include <asm/proto.h>
+
+/*
+ * KEXEC_SOURCE_MEMORY_LIMIT maximum page get_free_page can return.
+ * I.e. Maximum page that is mapped directly into kernel memory,
+ * and kmap is not required.
+ *
+ * So far x86_64 is limited to 40 physical address bits.
+ */
+
+/* Maximum physical address we can use pages from */
+#define KEXEC_SOURCE_MEMORY_LIMIT      (0xFFFFFFFFFFUL)
+/* Maximum address we can reach in physical address mode */
+#define KEXEC_DESTINATION_MEMORY_LIMIT (0xFFFFFFFFFFUL)
+/* Maximum address we can use for the control pages */
+#define KEXEC_CONTROL_MEMORY_LIMIT     (0xFFFFFFFFFFUL)
+
+/* Allocate one page for the pdp and the second for the code */
+#define KEXEC_CONTROL_CODE_SIZE  (4096UL + 4096UL)
+
+/* The native architecture */
+#define KEXEC_ARCH KEXEC_ARCH_X86_64
+
+#define MAX_NOTE_BYTES 1024
+typedef u32 note_buf_t[MAX_NOTE_BYTES/4];
+
+extern note_buf_t crash_notes[];
+
+#endif /* _X86_64_KEXEC_H */
diff --git a/include/asm-x86_64/kprobes.h b/include/asm-x86_64/kprobes.h
--- a/include/asm-x86_64/kprobes.h
+++ b/include/asm-x86_64/kprobes.h
@@ -38,6 +38,9 @@ typedef u8 kprobe_opcode_t;
 	: (((unsigned long)current_thread_info()) + THREAD_SIZE - (ADDR)))
 
 #define JPROBE_ENTRY(pentry)	(kprobe_opcode_t *)pentry
+#define ARCH_SUPPORTS_KRETPROBES
+
+void kretprobe_trampoline(void);
 
 /* Architecture specific copy of original instruction*/
 struct arch_specific_insn {
diff --git a/include/asm-x86_64/mmzone.h b/include/asm-x86_64/mmzone.h
--- a/include/asm-x86_64/mmzone.h
+++ b/include/asm-x86_64/mmzone.h
@@ -6,7 +6,7 @@
 
 #include <linux/config.h>
 
-#ifdef CONFIG_DISCONTIGMEM
+#ifdef CONFIG_NUMA
 
 #define VIRTUAL_BUG_ON(x) 
 
@@ -30,27 +30,23 @@ static inline __attribute__((pure)) int 
 	return nid; 
 } 
 
-#define pfn_to_nid(pfn) phys_to_nid((unsigned long)(pfn) << PAGE_SHIFT)
-
-#define kvaddr_to_nid(kaddr)	phys_to_nid(__pa(kaddr))
 #define NODE_DATA(nid)		(node_data[nid])
 
-#define node_mem_map(nid)	(NODE_DATA(nid)->node_mem_map)
-
-#define node_mem_map(nid)	(NODE_DATA(nid)->node_mem_map)
 #define node_start_pfn(nid)	(NODE_DATA(nid)->node_start_pfn)
 #define node_end_pfn(nid)       (NODE_DATA(nid)->node_start_pfn + \
 				 NODE_DATA(nid)->node_spanned_pages)
 
-#define local_mapnr(kvaddr) \
-	( (__pa(kvaddr) >> PAGE_SHIFT) - node_start_pfn(kvaddr_to_nid(kvaddr)) )
+#ifdef CONFIG_DISCONTIGMEM
+
+#define pfn_to_nid(pfn) phys_to_nid((unsigned long)(pfn) << PAGE_SHIFT)
+#define kvaddr_to_nid(kaddr)	phys_to_nid(__pa(kaddr))
 
 /* AK: this currently doesn't deal with invalid addresses. We'll see 
    if the 2.5 kernel doesn't pass them
    (2.4 used to). */
 #define pfn_to_page(pfn) ({ \
 	int nid = phys_to_nid(((unsigned long)(pfn)) << PAGE_SHIFT); 	\
-	((pfn) - node_start_pfn(nid)) + node_mem_map(nid);		\
+	((pfn) - node_start_pfn(nid)) + NODE_DATA(nid)->node_mem_map;	\
 })
 
 #define page_to_pfn(page) \
@@ -60,4 +56,8 @@ static inline __attribute__((pure)) int 
 			({ u8 nid__ = pfn_to_nid(pfn); \
 			   nid__ != 0xff && (pfn) >= node_start_pfn(nid__) && (pfn) <= node_end_pfn(nid__); }))
 #endif
+
+#define local_mapnr(kvaddr) \
+	( (__pa(kvaddr) >> PAGE_SHIFT) - node_start_pfn(kvaddr_to_nid(kvaddr)) )
+#endif
 #endif
diff --git a/include/asm-x86_64/msr.h b/include/asm-x86_64/msr.h
--- a/include/asm-x86_64/msr.h
+++ b/include/asm-x86_64/msr.h
@@ -57,11 +57,6 @@
      (val) = ((unsigned long)__a) | (((unsigned long)__d)<<32); \
 } while(0)
 
-#define rdpmc(counter,low,high) \
-     __asm__ __volatile__("rdpmc" \
-			  : "=a" (low), "=d" (high) \
-			  : "c" (counter))
-
 #define write_tsc(val1,val2) wrmsr(0x10, val1, val2)
 
 #define rdpmc(counter,low,high) \
@@ -223,7 +218,7 @@ extern inline unsigned int cpuid_edx(uns
 #define MSR_K7_PERFCTR3            0xC0010007
 #define MSR_K8_TOP_MEM1		   0xC001001A
 #define MSR_K8_TOP_MEM2		   0xC001001D
-#define MSR_K8_SYSCFG		   0xC0000010	
+#define MSR_K8_SYSCFG		   0xC0010010
 
 /* K6 MSRs */
 #define MSR_K6_EFER			0xC0000080
diff --git a/include/asm-x86_64/page.h b/include/asm-x86_64/page.h
--- a/include/asm-x86_64/page.h
+++ b/include/asm-x86_64/page.h
@@ -28,6 +28,7 @@
 #define HPAGE_SIZE	((1UL) << HPAGE_SHIFT)
 #define HPAGE_MASK	(~(HPAGE_SIZE - 1))
 #define HUGETLB_PAGE_ORDER	(HPAGE_SHIFT - PAGE_SHIFT)
+#define ARCH_HAS_HUGETLB_CLEAN_STALE_PGTABLE
 
 #ifdef __KERNEL__
 #ifndef __ASSEMBLY__
@@ -63,12 +64,14 @@ typedef struct { unsigned long pgprot; }
 #define __pgd(x) ((pgd_t) { (x) } )
 #define __pgprot(x)	((pgprot_t) { (x) } )
 
-#define __START_KERNEL		0xffffffff80100000UL
+#define __PHYSICAL_START	((unsigned long)CONFIG_PHYSICAL_START)
+#define __START_KERNEL		(__START_KERNEL_map + __PHYSICAL_START)
 #define __START_KERNEL_map	0xffffffff80000000UL
 #define __PAGE_OFFSET           0xffff810000000000UL
 
 #else
-#define __START_KERNEL		0xffffffff80100000
+#define __PHYSICAL_START	CONFIG_PHYSICAL_START
+#define __START_KERNEL		(__START_KERNEL_map + __PHYSICAL_START)
 #define __START_KERNEL_map	0xffffffff80000000
 #define __PAGE_OFFSET           0xffff810000000000
 #endif /* !__ASSEMBLY__ */
@@ -118,7 +121,9 @@ extern __inline__ int get_order(unsigned
 	  __pa(v); })
 
 #define __va(x)			((void *)((unsigned long)(x)+PAGE_OFFSET))
-#ifndef CONFIG_DISCONTIGMEM
+#define __boot_va(x)		__va(x)
+#define __boot_pa(x)		__pa(x)
+#ifdef CONFIG_FLATMEM
 #define pfn_to_page(pfn)	(mem_map + (pfn))
 #define page_to_pfn(page)	((unsigned long)((page) - mem_map))
 #define pfn_valid(pfn)		((pfn) < max_mapnr)
diff --git a/include/asm-x86_64/param.h b/include/asm-x86_64/param.h
--- a/include/asm-x86_64/param.h
+++ b/include/asm-x86_64/param.h
@@ -1,9 +1,11 @@
+#include <linux/config.h>
+
 #ifndef _ASMx86_64_PARAM_H
 #define _ASMx86_64_PARAM_H
 
 #ifdef __KERNEL__
-# define HZ            1000            /* Internal kernel timer frequency */
-# define USER_HZ       100          /* .. some user interfaces are in "ticks */
+# define HZ            CONFIG_HZ	/* Internal kernel timer frequency */
+# define USER_HZ       100		/* .. some user interfaces are in "ticks */
 #define CLOCKS_PER_SEC        (USER_HZ)       /* like times() */
 #endif
 
diff --git a/include/asm-x86_64/pci.h b/include/asm-x86_64/pci.h
--- a/include/asm-x86_64/pci.h
+++ b/include/asm-x86_64/pci.h
@@ -33,7 +33,7 @@ extern int (*pci_config_read)(int seg, i
 extern int (*pci_config_write)(int seg, int bus, int dev, int fn, int reg, int len, u32 value);
 
 void pcibios_set_master(struct pci_dev *dev);
-void pcibios_penalize_isa_irq(int irq);
+void pcibios_penalize_isa_irq(int irq, int active);
 struct irq_routing_table *pcibios_get_irq_routing_table(void);
 int pcibios_set_irq_routing(struct pci_dev *dev, int pin, int irq);
 
@@ -123,6 +123,16 @@ pci_dac_dma_sync_single_for_device(struc
 	flush_write_buffers();
 }
 
+#ifdef CONFIG_PCI
+static inline void pci_dma_burst_advice(struct pci_dev *pdev,
+					enum pci_dma_burst_strategy *strat,
+					unsigned long *strategy_parameter)
+{
+	*strat = PCI_DMA_BURST_INFINITY;
+	*strategy_parameter = ~0UL;
+}
+#endif
+
 #define HAVE_PCI_MMAP
 extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
 			       enum pci_mmap_state mmap_state, int write_combine);
diff --git a/include/asm-x86_64/percpu.h b/include/asm-x86_64/percpu.h
--- a/include/asm-x86_64/percpu.h
+++ b/include/asm-x86_64/percpu.h
@@ -39,7 +39,7 @@ extern void setup_per_cpu_areas(void);
 #define DEFINE_PER_CPU(type, name) \
     __typeof__(type) per_cpu__##name
 
-#define per_cpu(var, cpu)			(*((void)cpu, &per_cpu__##var))
+#define per_cpu(var, cpu)			(*((void)(cpu), &per_cpu__##var))
 #define __get_cpu_var(var)			per_cpu__##var
 
 #endif	/* SMP */
diff --git a/include/asm-x86_64/pgtable.h b/include/asm-x86_64/pgtable.h
--- a/include/asm-x86_64/pgtable.h
+++ b/include/asm-x86_64/pgtable.h
@@ -176,6 +176,8 @@ extern inline void pgd_clear (pgd_t * pg
 	(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_PCD)
 #define __PAGE_KERNEL_LARGE \
 	(__PAGE_KERNEL | _PAGE_PSE)
+#define __PAGE_KERNEL_LARGE_EXEC \
+	(__PAGE_KERNEL_EXEC | _PAGE_PSE)
 
 #define MAKE_GLOBAL(x) __pgprot((x) | _PAGE_GLOBAL)
 
@@ -253,6 +255,7 @@ extern inline int pte_young(pte_t pte)		
 extern inline int pte_write(pte_t pte)		{ return pte_val(pte) & _PAGE_RW; }
 static inline int pte_file(pte_t pte)		{ return pte_val(pte) & _PAGE_FILE; }
 
+#define __LARGE_PTE (_PAGE_PSE|_PAGE_PRESENT)
 extern inline pte_t pte_rdprotect(pte_t pte)	{ set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_USER)); return pte; }
 extern inline pte_t pte_exprotect(pte_t pte)	{ set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_USER)); return pte; }
 extern inline pte_t pte_mkclean(pte_t pte)	{ set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_DIRTY)); return pte; }
@@ -263,6 +266,7 @@ extern inline pte_t pte_mkexec(pte_t pte
 extern inline pte_t pte_mkdirty(pte_t pte)	{ set_pte(&pte, __pte(pte_val(pte) | _PAGE_DIRTY)); return pte; }
 extern inline pte_t pte_mkyoung(pte_t pte)	{ set_pte(&pte, __pte(pte_val(pte) | _PAGE_ACCESSED)); return pte; }
 extern inline pte_t pte_mkwrite(pte_t pte)	{ set_pte(&pte, __pte(pte_val(pte) | _PAGE_RW)); return pte; }
+extern inline pte_t pte_mkhuge(pte_t pte)	{ set_pte(&pte, __pte(pte_val(pte) | __LARGE_PTE)); return pte; }
 
 struct vm_area_struct;
 
@@ -290,7 +294,6 @@ static inline void ptep_set_wrprotect(st
  */
 #define pgprot_noncached(prot)	(__pgprot(pgprot_val(prot) | _PAGE_PCD | _PAGE_PWT))
 
-#define __LARGE_PTE (_PAGE_PSE|_PAGE_PRESENT) 
 static inline int pmd_large(pmd_t pte) { 
 	return (pmd_val(pte) & __LARGE_PTE) == __LARGE_PTE; 
 } 	
diff --git a/include/asm-x86_64/processor.h b/include/asm-x86_64/processor.h
--- a/include/asm-x86_64/processor.h
+++ b/include/asm-x86_64/processor.h
@@ -32,7 +32,7 @@
 #define ID_MASK		0x00200000
 
 #define desc_empty(desc) \
-               (!((desc)->a + (desc)->b))
+               (!((desc)->a | (desc)->b))
 
 #define desc_equal(desc1, desc2) \
                (((desc1)->a == (desc2)->a) && ((desc1)->b == (desc2)->b))
@@ -160,16 +160,17 @@ static inline void clear_in_cr4 (unsigne
 /*
  * User space process size. 47bits minus one guard page.
  */
-#define TASK_SIZE	(0x800000000000UL - 4096)
+#define TASK_SIZE64	(0x800000000000UL - 4096)
 
 /* This decides where the kernel will search for a free chunk of vm
  * space during mmap's.
  */
 #define IA32_PAGE_OFFSET ((current->personality & ADDR_LIMIT_3GB) ? 0xc0000000 : 0xFFFFe000)
-#define TASK_UNMAPPED_32 PAGE_ALIGN(IA32_PAGE_OFFSET/3)
-#define TASK_UNMAPPED_64 PAGE_ALIGN(TASK_SIZE/3) 
-#define TASK_UNMAPPED_BASE	\
-	(test_thread_flag(TIF_IA32) ? TASK_UNMAPPED_32 : TASK_UNMAPPED_64)  
+
+#define TASK_SIZE 		(test_thread_flag(TIF_IA32) ? IA32_PAGE_OFFSET : TASK_SIZE64)
+#define TASK_SIZE_OF(child) 	((test_tsk_thread_flag(child, TIF_IA32)) ? IA32_PAGE_OFFSET : TASK_SIZE64)
+
+#define TASK_UNMAPPED_BASE	PAGE_ALIGN(TASK_SIZE/3)
 
 /*
  * Size of io_bitmap.
@@ -279,6 +280,14 @@ struct thread_struct {
 	set_fs(USER_DS);							 \
 } while(0) 
 
+#define get_debugreg(var, register)				\
+		__asm__("movq %%db" #register ", %0"		\
+			:"=r" (var))
+#define set_debugreg(value, register)			\
+		__asm__("movq %0,%%db" #register		\
+			: /* no output */			\
+			:"r" (value))
+
 struct task_struct;
 struct mm_struct;
 
diff --git a/include/asm-x86_64/proto.h b/include/asm-x86_64/proto.h
--- a/include/asm-x86_64/proto.h
+++ b/include/asm-x86_64/proto.h
@@ -15,6 +15,13 @@ extern void pda_init(int); 
 extern void early_idt_handler(void);
 
 extern void mcheck_init(struct cpuinfo_x86 *c);
+#ifdef CONFIG_MTRR
+extern void mtrr_ap_init(void);
+extern void mtrr_bp_init(void);
+#else
+#define mtrr_ap_init() do {} while (0)
+#define mtrr_bp_init() do {} while (0)
+#endif
 extern void init_memory_mapping(unsigned long start, unsigned long end);
 
 extern void system_call(void); 
diff --git a/include/asm-x86_64/ptrace.h b/include/asm-x86_64/ptrace.h
--- a/include/asm-x86_64/ptrace.h
+++ b/include/asm-x86_64/ptrace.h
@@ -82,6 +82,7 @@ struct pt_regs {
 
 #if defined(__KERNEL__) && !defined(__ASSEMBLY__) 
 #define user_mode(regs) (!!((regs)->cs & 3))
+#define user_mode_vm(regs) user_mode(regs)
 #define instruction_pointer(regs) ((regs)->rip)
 extern unsigned long profile_pc(struct pt_regs *regs);
 void signal_fault(struct pt_regs *regs, void __user *frame, char *where);
diff --git a/include/asm-x86_64/serial.h b/include/asm-x86_64/serial.h
--- a/include/asm-x86_64/serial.h
+++ b/include/asm-x86_64/serial.h
@@ -22,109 +22,9 @@
 #define STD_COM4_FLAGS ASYNC_BOOT_AUTOCONF
 #endif
 
-#ifdef CONFIG_SERIAL_MANY_PORTS
-#define FOURPORT_FLAGS ASYNC_FOURPORT
-#define ACCENT_FLAGS 0
-#define BOCA_FLAGS 0
-#define HUB6_FLAGS 0
-#endif
-
-#define MCA_COM_FLAGS	(STD_COM_FLAGS|ASYNC_BOOT_ONLYMCA)
-
-/*
- * The following define the access methods for the HUB6 card. All
- * access is through two ports for all 24 possible chips. The card is
- * selected through the high 2 bits, the port on that card with the
- * "middle" 3 bits, and the register on that port with the bottom
- * 3 bits.
- *
- * While the access port and interrupt is configurable, the default
- * port locations are 0x302 for the port control register, and 0x303
- * for the data read/write register. Normally, the interrupt is at irq3
- * but can be anything from 3 to 7 inclusive. Note that using 3 will
- * require disabling com2.
- */
-
-#define C_P(card,port) (((card)<<6|(port)<<3) + 1)
-
-#define STD_SERIAL_PORT_DEFNS			\
+#define SERIAL_PORT_DFNS			\
 	/* UART CLK   PORT IRQ     FLAGS        */			\
 	{ 0, BASE_BAUD, 0x3F8, 4, STD_COM_FLAGS },	/* ttyS0 */	\
 	{ 0, BASE_BAUD, 0x2F8, 3, STD_COM_FLAGS },	/* ttyS1 */	\
 	{ 0, BASE_BAUD, 0x3E8, 4, STD_COM_FLAGS },	/* ttyS2 */	\
 	{ 0, BASE_BAUD, 0x2E8, 3, STD_COM4_FLAGS },	/* ttyS3 */
-
-
-#ifdef CONFIG_SERIAL_MANY_PORTS
-#define EXTRA_SERIAL_PORT_DEFNS			\
-	{ 0, BASE_BAUD, 0x1A0, 9, FOURPORT_FLAGS }, 	/* ttyS4 */	\
-	{ 0, BASE_BAUD, 0x1A8, 9, FOURPORT_FLAGS },	/* ttyS5 */	\
-	{ 0, BASE_BAUD, 0x1B0, 9, FOURPORT_FLAGS },	/* ttyS6 */	\
-	{ 0, BASE_BAUD, 0x1B8, 9, FOURPORT_FLAGS },	/* ttyS7 */	\
-	{ 0, BASE_BAUD, 0x2A0, 5, FOURPORT_FLAGS },	/* ttyS8 */	\
-	{ 0, BASE_BAUD, 0x2A8, 5, FOURPORT_FLAGS },	/* ttyS9 */	\
-	{ 0, BASE_BAUD, 0x2B0, 5, FOURPORT_FLAGS },	/* ttyS10 */	\
-	{ 0, BASE_BAUD, 0x2B8, 5, FOURPORT_FLAGS },	/* ttyS11 */	\
-	{ 0, BASE_BAUD, 0x330, 4, ACCENT_FLAGS },	/* ttyS12 */	\
-	{ 0, BASE_BAUD, 0x338, 4, ACCENT_FLAGS },	/* ttyS13 */	\
-	{ 0, BASE_BAUD, 0x000, 0, 0 },	/* ttyS14 (spare) */		\
-	{ 0, BASE_BAUD, 0x000, 0, 0 },	/* ttyS15 (spare) */		\
-	{ 0, BASE_BAUD, 0x100, 12, BOCA_FLAGS },	/* ttyS16 */	\
-	{ 0, BASE_BAUD, 0x108, 12, BOCA_FLAGS },	/* ttyS17 */	\
-	{ 0, BASE_BAUD, 0x110, 12, BOCA_FLAGS },	/* ttyS18 */	\
-	{ 0, BASE_BAUD, 0x118, 12, BOCA_FLAGS },	/* ttyS19 */	\
-	{ 0, BASE_BAUD, 0x120, 12, BOCA_FLAGS },	/* ttyS20 */	\
-	{ 0, BASE_BAUD, 0x128, 12, BOCA_FLAGS },	/* ttyS21 */	\
-	{ 0, BASE_BAUD, 0x130, 12, BOCA_FLAGS },	/* ttyS22 */	\
-	{ 0, BASE_BAUD, 0x138, 12, BOCA_FLAGS },	/* ttyS23 */	\
-	{ 0, BASE_BAUD, 0x140, 12, BOCA_FLAGS },	/* ttyS24 */	\
-	{ 0, BASE_BAUD, 0x148, 12, BOCA_FLAGS },	/* ttyS25 */	\
-	{ 0, BASE_BAUD, 0x150, 12, BOCA_FLAGS },	/* ttyS26 */	\
-	{ 0, BASE_BAUD, 0x158, 12, BOCA_FLAGS },	/* ttyS27 */	\
-	{ 0, BASE_BAUD, 0x160, 12, BOCA_FLAGS },	/* ttyS28 */	\
-	{ 0, BASE_BAUD, 0x168, 12, BOCA_FLAGS },	/* ttyS29 */	\
-	{ 0, BASE_BAUD, 0x170, 12, BOCA_FLAGS },	/* ttyS30 */	\
-	{ 0, BASE_BAUD, 0x178, 12, BOCA_FLAGS },	/* ttyS31 */
-#else
-#define EXTRA_SERIAL_PORT_DEFNS
-#endif
-
-/* You can have up to four HUB6's in the system, but I've only
- * included two cards here for a total of twelve ports.
- */
-#if (defined(CONFIG_HUB6) && defined(CONFIG_SERIAL_MANY_PORTS))
-#define HUB6_SERIAL_PORT_DFNS		\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,0) },  /* ttyS32 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,1) },  /* ttyS33 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,2) },  /* ttyS34 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,3) },  /* ttyS35 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,4) },  /* ttyS36 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,5) },  /* ttyS37 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,0) },  /* ttyS38 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,1) },  /* ttyS39 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,2) },  /* ttyS40 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,3) },  /* ttyS41 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,4) },  /* ttyS42 */	\
-	{ 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,5) },  /* ttyS43 */
-#else
-#define HUB6_SERIAL_PORT_DFNS
-#endif
-
-#ifdef CONFIG_MCA
-#define MCA_SERIAL_PORT_DFNS			\
-	{ 0, BASE_BAUD, 0x3220, 3, MCA_COM_FLAGS },	\
-	{ 0, BASE_BAUD, 0x3228, 3, MCA_COM_FLAGS },	\
-	{ 0, BASE_BAUD, 0x4220, 3, MCA_COM_FLAGS },	\
-	{ 0, BASE_BAUD, 0x4228, 3, MCA_COM_FLAGS },	\
-	{ 0, BASE_BAUD, 0x5220, 3, MCA_COM_FLAGS },	\
-	{ 0, BASE_BAUD, 0x5228, 3, MCA_COM_FLAGS },
-#else
-#define MCA_SERIAL_PORT_DFNS
-#endif
-
-#define SERIAL_PORT_DFNS		\
-	STD_SERIAL_PORT_DEFNS		\
-	EXTRA_SERIAL_PORT_DEFNS		\
-	HUB6_SERIAL_PORT_DFNS		\
-	MCA_SERIAL_PORT_DFNS
-
diff --git a/include/asm-x86_64/smp.h b/include/asm-x86_64/smp.h
--- a/include/asm-x86_64/smp.h
+++ b/include/asm-x86_64/smp.h
@@ -43,13 +43,15 @@ extern cpumask_t cpu_callout_map;
 extern void smp_alloc_memory(void);
 extern volatile unsigned long smp_invalidate_needed;
 extern int pic_mode;
+extern void lock_ipi_call_lock(void);
+extern void unlock_ipi_call_lock(void);
 extern int smp_num_siblings;
-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_invalidate_rcv(void);		/* Process an NMI */
 extern void zap_low_mappings(void);
 void smp_stop_cpu(void);
+extern int smp_call_function_single(int cpuid, void (*func) (void *info),
+				void *info, int retry, int wait);
+
 extern cpumask_t cpu_sibling_map[NR_CPUS];
 extern cpumask_t cpu_core_map[NR_CPUS];
 extern u8 phys_proc_id[NR_CPUS];
@@ -68,7 +70,7 @@ static inline int num_booting_cpus(void)
 	return cpus_weight(cpu_callout_map);
 }
 
-#define __smp_processor_id() read_pda(cpunumber)
+#define raw_smp_processor_id() read_pda(cpunumber)
 
 extern __inline int hard_smp_processor_id(void)
 {
@@ -77,6 +79,8 @@ extern __inline int hard_smp_processor_i
 }
 
 extern int safe_smp_processor_id(void);
+extern int __cpu_disable(void);
+extern void __cpu_die(unsigned int cpu);
 
 #endif /* !ASSEMBLY */
 
diff --git a/include/asm-x86_64/sparsemem.h b/include/asm-x86_64/sparsemem.h
new file mode 100644
--- /dev/null
+++ b/include/asm-x86_64/sparsemem.h
@@ -0,0 +1,26 @@
+#ifndef _ASM_X86_64_SPARSEMEM_H
+#define _ASM_X86_64_SPARSEMEM_H 1
+
+#ifdef CONFIG_SPARSEMEM
+
+/*
+ * generic non-linear memory support:
+ *
+ * 1) we will not split memory into more chunks than will fit into the flags
+ *    field of the struct page
+ *
+ * SECTION_SIZE_BITS		2^n: size of each section
+ * MAX_PHYSADDR_BITS		2^n: max size of physical address space
+ * MAX_PHYSMEM_BITS		2^n: how much memory we can have in that space
+ *
+ */
+
+#define SECTION_SIZE_BITS	27 /* matt - 128 is convenient right now */
+#define MAX_PHYSADDR_BITS	40
+#define MAX_PHYSMEM_BITS	40
+
+extern int early_pfn_to_nid(unsigned long pfn);
+
+#endif /* CONFIG_SPARSEMEM */
+
+#endif /* _ASM_X86_64_SPARSEMEM_H */
diff --git a/include/asm-x86_64/suspend.h b/include/asm-x86_64/suspend.h
--- a/include/asm-x86_64/suspend.h
+++ b/include/asm-x86_64/suspend.h
@@ -16,7 +16,7 @@ arch_prepare_suspend(void)
 struct saved_context {
   	u16 ds, es, fs, gs, ss;
 	unsigned long gs_base, gs_kernel_base, fs_base;
-	unsigned long cr0, cr2, cr3, cr4;
+	unsigned long cr0, cr2, cr3, cr4, cr8;
 	u16 gdt_pad;
 	u16 gdt_limit;
 	unsigned long gdt_base;
diff --git a/include/asm-x86_64/system.h b/include/asm-x86_64/system.h
--- a/include/asm-x86_64/system.h
+++ b/include/asm-x86_64/system.h
@@ -116,12 +116,12 @@ struct alt_instr { 
 /*
  * Alternative inline assembly with input.
  * 
- * Pecularities:
+ * Peculiarities:
  * No memory clobber here. 
  * Argument numbers start with 1.
  * Best is to use constraints that are fixed size (like (%1) ... "r")
  * If you use variable sized constraints like "m" or "g" in the 
- * replacement maake sure to pad to the worst case length.
+ * replacement make sure to pad to the worst case length.
  */
 #define alternative_input(oldinstr, newinstr, feature, input...)	\
 	asm volatile ("661:\n\t" oldinstr "\n662:\n"			\
@@ -335,9 +335,6 @@ void cpu_idle_wait(void);
 void disable_hlt(void);
 void enable_hlt(void);
 
-#define HAVE_EAT_KEY
-void eat_key(void);
-
 extern unsigned long arch_align_stack(unsigned long sp);
 
 #endif
diff --git a/include/asm-x86_64/thread_info.h b/include/asm-x86_64/thread_info.h
--- a/include/asm-x86_64/thread_info.h
+++ b/include/asm-x86_64/thread_info.h
@@ -29,7 +29,7 @@ struct thread_info {
 	__u32			flags;		/* low level flags */
 	__u32			status;		/* thread synchronous flags */
 	__u32			cpu;		/* current CPU */
-	int 			preempt_count;
+	int 			preempt_count;	/* 0 => preemptable, <0 => BUG */
 
 	mm_segment_t		addr_limit;	
 	struct restart_block    restart_block;
diff --git a/include/asm-x86_64/timex.h b/include/asm-x86_64/timex.h
--- a/include/asm-x86_64/timex.h
+++ b/include/asm-x86_64/timex.h
@@ -26,6 +26,9 @@ static inline cycles_t get_cycles (void)
 
 extern unsigned int cpu_khz;
 
+extern int read_current_timer(unsigned long *timer_value);
+#define ARCH_HAS_READ_CURRENT_TIMER	1
+
 extern struct vxtime_data vxtime;
 
 #endif
diff --git a/include/asm-x86_64/tlbflush.h b/include/asm-x86_64/tlbflush.h
--- a/include/asm-x86_64/tlbflush.h
+++ b/include/asm-x86_64/tlbflush.h
@@ -22,16 +22,18 @@
  */
 #define __flush_tlb_global()						\
 	do {								\
-		unsigned long tmpreg;					\
+		unsigned long tmpreg, cr4, cr4_orig;			\
 									\
 		__asm__ __volatile__(					\
-			"movq %1, %%cr4;  # turn off PGE     \n"	\
+			"movq %%cr4, %2;  # turn off PGE     \n"	\
+			"movq %2, %1;                        \n"	\
+			"andq %3, %1;                        \n"	\
+			"movq %1, %%cr4;                     \n"	\
 			"movq %%cr3, %0;  # flush TLB        \n"	\
 			"movq %0, %%cr3;                     \n"	\
 			"movq %2, %%cr4;  # turn PGE back on \n"	\
-			: "=&r" (tmpreg)				\
-			: "r" (mmu_cr4_features & ~X86_CR4_PGE),	\
-			  "r" (mmu_cr4_features)			\
+			: "=&r" (tmpreg), "=&r" (cr4), "=&r" (cr4_orig)	\
+			: "i" (~X86_CR4_PGE)				\
 			: "memory");					\
 	} while (0)
 
@@ -54,8 +56,9 @@ extern unsigned long pgkern_mask;
  *  - flush_tlb_kernel_range(start, end) flushes a range of kernel pages
  *  - flush_tlb_pgtables(mm, start, end) flushes a range of page tables
  *
- * ..but the x86_64 has somewhat limited tlb flushing capabilities,
- * and page-granular flushes are available only on i486 and up.
+ * x86-64 can only flush individual pages or full VMs. For a range flush
+ * we always do the full VM. Might be worth trying if for a small
+ * range a few INVLPGs in a row are a win.
  */
 
 #ifndef CONFIG_SMP
@@ -113,7 +116,9 @@ static inline void flush_tlb_range(struc
 static inline void flush_tlb_pgtables(struct mm_struct *mm,
 				      unsigned long start, unsigned long end)
 {
-	/* x86_64 does not keep any page table caches in TLB */
+	/* x86_64 does not keep any page table caches in a software TLB.
+	   The CPUs do in their hardware TLBs, but they are handled
+	   by the normal TLB flushing algorithms. */
 }
 
 #endif /* _X8664_TLBFLUSH_H */
diff --git a/include/asm-x86_64/topology.h b/include/asm-x86_64/topology.h
--- a/include/asm-x86_64/topology.h
+++ b/include/asm-x86_64/topology.h
@@ -3,7 +3,7 @@
 
 #include <linux/config.h>
 
-#ifdef CONFIG_DISCONTIGMEM
+#ifdef CONFIG_NUMA
 
 #include <asm/mpspec.h>
 #include <asm/bitops.h>
@@ -13,8 +13,8 @@
 extern cpumask_t cpu_online_map;
 
 extern unsigned char cpu_to_node[];
+extern unsigned char pci_bus_to_node[];
 extern cpumask_t     node_to_cpumask[];
-extern cpumask_t pci_bus_to_cpumask[];
 
 #ifdef CONFIG_ACPI_NUMA
 extern int __node_distance(int, int);
@@ -26,18 +26,9 @@ extern int __node_distance(int, int);
 #define parent_node(node)		(node)
 #define node_to_first_cpu(node) 	(__ffs(node_to_cpumask[node]))
 #define node_to_cpumask(node)		(node_to_cpumask[node])
+#define pcibus_to_node(bus)		pci_bus_to_node[(bus)->number]
+#define pcibus_to_cpumask(bus)		node_to_cpumask(pcibus_to_node(bus));
 
-static inline cpumask_t __pcibus_to_cpumask(int bus)
-{
-	cpumask_t busmask = pci_bus_to_cpumask[bus];
-	cpumask_t online = cpu_online_map;
-	cpumask_t res;
-	cpus_and(res, busmask, online);
-	return res;
-}
-#define pcibus_to_cpumask(bus) __pcibus_to_cpumask(bus->number)
-
-#ifdef CONFIG_NUMA
 /* sched_domains SD_NODE_INIT for x86_64 machines */
 #define SD_NODE_INIT (struct sched_domain) {		\
 	.span			= CPU_MASK_NONE,	\
@@ -48,18 +39,21 @@ static inline cpumask_t __pcibus_to_cpum
 	.busy_factor		= 32,			\
 	.imbalance_pct		= 125,			\
 	.cache_hot_time		= (10*1000000),		\
-	.cache_nice_tries	= 1,			\
+	.cache_nice_tries	= 2,			\
+	.busy_idx		= 3,			\
+	.idle_idx		= 2,			\
+	.newidle_idx		= 0, 			\
+	.wake_idx		= 1,			\
+	.forkexec_idx		= 1,			\
 	.per_cpu_gain		= 100,			\
 	.flags			= SD_LOAD_BALANCE	\
-				| SD_BALANCE_NEWIDLE	\
+				| SD_BALANCE_FORK	\
 				| SD_BALANCE_EXEC	\
-				| SD_WAKE_IDLE		\
 				| SD_WAKE_BALANCE,	\
 	.last_balance		= jiffies,		\
 	.balance_interval	= 1,			\
 	.nr_balance_failed	= 0,			\
 }
-#endif
 
 #endif
 
diff --git a/include/asm-x86_64/unistd.h b/include/asm-x86_64/unistd.h
--- a/include/asm-x86_64/unistd.h
+++ b/include/asm-x86_64/unistd.h
@@ -552,7 +552,7 @@ __SYSCALL(__NR_mq_notify, sys_mq_notify)
 #define __NR_mq_getsetattr 	245
 __SYSCALL(__NR_mq_getsetattr, sys_mq_getsetattr)
 #define __NR_kexec_load 	246
-__SYSCALL(__NR_kexec_load, sys_ni_syscall)
+__SYSCALL(__NR_kexec_load, sys_kexec_load)
 #define __NR_waitid		247
 __SYSCALL(__NR_waitid, sys_waitid)
 #define __NR_add_key		248
@@ -561,8 +561,18 @@ __SYSCALL(__NR_add_key, sys_add_key)
 __SYSCALL(__NR_request_key, sys_request_key)
 #define __NR_keyctl		250
 __SYSCALL(__NR_keyctl, sys_keyctl)
+#define __NR_ioprio_set		251
+__SYSCALL(__NR_ioprio_set, sys_ioprio_set)
+#define __NR_ioprio_get		252
+__SYSCALL(__NR_ioprio_get, sys_ioprio_get)
+#define __NR_inotify_init	253
+__SYSCALL(__NR_inotify_init, sys_inotify_init)
+#define __NR_inotify_add_watch	254
+__SYSCALL(__NR_inotify_add_watch, sys_inotify_add_watch)
+#define __NR_inotify_rm_watch	255
+__SYSCALL(__NR_inotify_rm_watch, sys_inotify_rm_watch)
 
-#define __NR_syscall_max __NR_keyctl
+#define __NR_syscall_max __NR_inotify_rm_watch
 #ifndef __NO_STUBS
 
 /* user-visible error numbers are in the range -1 - -4095 */
diff --git a/include/asm-xtensa/a.out.h b/include/asm-xtensa/a.out.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/a.out.h
@@ -0,0 +1,33 @@
+/*
+ * include/asm-xtensa/addrspace.h
+ *
+ * Dummy a.out file. Xtensa does not support the a.out format, but the kernel
+ * seems to depend on it.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_A_OUT_H
+#define _XTENSA_A_OUT_H
+
+/* Note: the kernel needs the a.out definitions, even if only ELF is used. */
+
+#define STACK_TOP	TASK_SIZE
+
+struct exec
+{
+  unsigned long a_info;
+  unsigned a_text;
+  unsigned a_data;
+  unsigned a_bss;
+  unsigned a_syms;
+  unsigned a_entry;
+  unsigned a_trsize;
+  unsigned a_drsize;
+};
+
+#endif /* _XTENSA_A_OUT_H */
diff --git a/include/asm-xtensa/atomic.h b/include/asm-xtensa/atomic.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/atomic.h
@@ -0,0 +1,272 @@
+/*
+ * include/asm-xtensa/atomic.h
+ *
+ * Atomic operations that C can't guarantee us.  Useful for resource counting..
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_ATOMIC_H
+#define _XTENSA_ATOMIC_H
+
+#include <linux/config.h>
+#include <linux/stringify.h>
+
+typedef struct { volatile int counter; } atomic_t;
+
+#ifdef __KERNEL__
+#include <asm/processor.h>
+#include <asm/system.h>
+
+#define ATOMIC_INIT(i)	( (atomic_t) { (i) } )
+
+/*
+ * This Xtensa implementation assumes that the right mechanism
+ * for exclusion is for locking interrupts to level 1.
+ *
+ * Locking interrupts looks like this:
+ *
+ *    rsil a15, 1
+ *    <code>
+ *    wsr  a15, PS
+ *    rsync
+ *
+ * Note that a15 is used here because the register allocation
+ * done by the compiler is not guaranteed and a window overflow
+ * may not occur between the rsil and wsr instructions. By using
+ * a15 in the rsil, the machine is guaranteed to be in a state
+ * where no register reference will cause an overflow.
+ */
+
+/**
+ * atomic_read - read atomic variable
+ * @v: pointer of type atomic_t
+ *
+ * Atomically reads the value of @v.
+ */
+#define atomic_read(v)		((v)->counter)
+
+/**
+ * atomic_set - set atomic variable
+ * @v: pointer of type atomic_t
+ * @i: required value
+ *
+ * Atomically sets the value of @v to @i.
+ */
+#define atomic_set(v,i)		((v)->counter = (i))
+
+/**
+ * atomic_add - add integer to atomic variable
+ * @i: integer value to add
+ * @v: pointer of type atomic_t
+ *
+ * Atomically adds @i to @v.
+ */
+extern __inline__ void atomic_add(int i, atomic_t * v)
+{
+    unsigned int vval;
+
+    __asm__ __volatile__(
+	"rsil    a15, "__stringify(LOCKLEVEL)"\n\t"
+	"l32i    %0, %2, 0              \n\t"
+	"add     %0, %0, %1             \n\t"
+	"s32i    %0, %2, 0              \n\t"
+	"wsr     a15, "__stringify(PS)"       \n\t"
+	"rsync                          \n"
+	: "=&a" (vval)
+	: "a" (i), "a" (v)
+	: "a15", "memory"
+	);
+}
+
+/**
+ * atomic_sub - subtract the atomic variable
+ * @i: integer value to subtract
+ * @v: pointer of type atomic_t
+ *
+ * Atomically subtracts @i from @v.
+ */
+extern __inline__ void atomic_sub(int i, atomic_t *v)
+{
+    unsigned int vval;
+
+    __asm__ __volatile__(
+	"rsil    a15, "__stringify(LOCKLEVEL)"\n\t"
+	"l32i    %0, %2, 0              \n\t"
+	"sub     %0, %0, %1             \n\t"
+	"s32i    %0, %2, 0              \n\t"
+	"wsr     a15, "__stringify(PS)"       \n\t"
+	"rsync                          \n"
+	: "=&a" (vval)
+	: "a" (i), "a" (v)
+	: "a15", "memory"
+	);
+}
+
+/*
+ * We use atomic_{add|sub}_return to define other functions.
+ */
+
+extern __inline__ int atomic_add_return(int i, atomic_t * v)
+{
+     unsigned int vval;
+
+    __asm__ __volatile__(
+	"rsil    a15,"__stringify(LOCKLEVEL)"\n\t"
+	"l32i    %0, %2, 0             \n\t"
+	"add     %0, %0, %1            \n\t"
+	"s32i    %0, %2, 0             \n\t"
+	"wsr     a15, "__stringify(PS)"      \n\t"
+	"rsync                         \n"
+	: "=&a" (vval)
+	: "a" (i), "a" (v)
+	: "a15", "memory"
+	);
+
+    return vval;
+}
+
+extern __inline__ int atomic_sub_return(int i, atomic_t * v)
+{
+    unsigned int vval;
+
+    __asm__ __volatile__(
+	"rsil    a15,"__stringify(LOCKLEVEL)"\n\t"
+	"l32i    %0, %2, 0             \n\t"
+	"sub     %0, %0, %1            \n\t"
+	"s32i    %0, %2, 0             \n\t"
+	"wsr     a15, "__stringify(PS)"       \n\t"
+	"rsync                         \n"
+	: "=&a" (vval)
+	: "a" (i), "a" (v)
+	: "a15", "memory"
+	);
+
+    return vval;
+}
+
+/**
+ * atomic_sub_and_test - subtract value from variable and test result
+ * @i: integer value to subtract
+ * @v: pointer of type atomic_t
+ *
+ * Atomically subtracts @i from @v and returns
+ * true if the result is zero, or false for all
+ * other cases.
+ */
+#define atomic_sub_and_test(i,v) (atomic_sub_return((i),(v)) == 0)
+
+/**
+ * atomic_inc - increment atomic variable
+ * @v: pointer of type atomic_t
+ *
+ * Atomically increments @v by 1.
+ */
+#define atomic_inc(v) atomic_add(1,(v))
+
+/**
+ * atomic_inc - increment atomic variable
+ * @v: pointer of type atomic_t
+ *
+ * Atomically increments @v by 1.
+ */
+#define atomic_inc_return(v) atomic_add_return(1,(v))
+
+/**
+ * atomic_dec - decrement atomic variable
+ * @v: pointer of type atomic_t
+ *
+ * Atomically decrements @v by 1.
+ */
+#define atomic_dec(v) atomic_sub(1,(v))
+
+/**
+ * atomic_dec_return - decrement atomic variable
+ * @v: pointer of type atomic_t
+ *
+ * Atomically decrements @v by 1.
+ */
+#define atomic_dec_return(v) atomic_sub_return(1,(v))
+
+/**
+ * atomic_dec_and_test - decrement and test
+ * @v: pointer of type atomic_t
+ *
+ * Atomically decrements @v by 1 and
+ * returns true if the result is 0, or false for all other
+ * cases.
+ */
+#define atomic_dec_and_test(v) (atomic_sub_return(1,(v)) == 0)
+
+/**
+ * atomic_inc_and_test - increment and test
+ * @v: pointer of type atomic_t
+ *
+ * Atomically increments @v by 1
+ * and returns true if the result is zero, or false for all
+ * other cases.
+ */
+#define atomic_inc_and_test(v) (atomic_add_return(1,(v)) == 0)
+
+/**
+ * atomic_add_negative - add and test if negative
+ * @v: pointer of type atomic_t
+ * @i: integer value to add
+ *
+ * Atomically adds @i to @v and returns true
+ * if the result is negative, or false when
+ * result is greater than or equal to zero.
+ */
+#define atomic_add_negative(i,v) (atomic_add_return((i),(v)) < 0)
+
+
+extern __inline__ void atomic_clear_mask(unsigned int mask, atomic_t *v)
+{
+    unsigned int all_f = -1;
+    unsigned int vval;
+
+    __asm__ __volatile__(
+	"rsil    a15,"__stringify(LOCKLEVEL)"\n\t"
+	"l32i    %0, %2, 0             \n\t"
+	"xor     %1, %4, %3            \n\t"
+	"and     %0, %0, %4            \n\t"
+	"s32i    %0, %2, 0             \n\t"
+	"wsr     a15, "__stringify(PS)"      \n\t"
+	"rsync                         \n"
+	: "=&a" (vval), "=a" (mask)
+	: "a" (v), "a" (all_f), "1" (mask)
+	: "a15", "memory"
+	);
+}
+
+extern __inline__ void atomic_set_mask(unsigned int mask, atomic_t *v)
+{
+    unsigned int vval;
+
+    __asm__ __volatile__(
+	"rsil    a15,"__stringify(LOCKLEVEL)"\n\t"
+	"l32i    %0, %2, 0             \n\t"
+	"or      %0, %0, %1            \n\t"
+	"s32i    %0, %2, 0             \n\t"
+	"wsr     a15, "__stringify(PS)"       \n\t"
+	"rsync                         \n"
+	: "=&a" (vval)
+	: "a" (mask), "a" (v)
+	: "a15", "memory"
+	);
+}
+
+/* Atomic operations are already serializing */
+#define smp_mb__before_atomic_dec()	barrier()
+#define smp_mb__after_atomic_dec()	barrier()
+#define smp_mb__before_atomic_inc()	barrier()
+#define smp_mb__after_atomic_inc()	barrier()
+
+#endif /* __KERNEL__ */
+
+#endif /* _XTENSA_ATOMIC_H */
+
diff --git a/include/asm-xtensa/bitops.h b/include/asm-xtensa/bitops.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/bitops.h
@@ -0,0 +1,446 @@
+/*
+ * include/asm-xtensa/bitops.h
+ *
+ * Atomic operations that C can't guarantee us.Useful for resource counting etc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_BITOPS_H
+#define _XTENSA_BITOPS_H
+
+#ifdef __KERNEL__
+
+#include <asm/processor.h>
+#include <asm/byteorder.h>
+#include <asm/system.h>
+
+#ifdef CONFIG_SMP
+# error SMP not supported on this architecture
+#endif
+
+static __inline__ void set_bit(int nr, volatile void * addr)
+{
+	unsigned long mask = 1 << (nr & 0x1f);
+	unsigned long *a = ((unsigned long *)addr) + (nr >> 5);
+	unsigned long flags;
+
+	local_irq_save(flags);
+	*a |= mask;
+	local_irq_restore(flags);
+}
+
+static __inline__ void __set_bit(int nr, volatile unsigned long * addr)
+{
+	unsigned long mask = 1 << (nr & 0x1f);
+	unsigned long *a = ((unsigned long *)addr) + (nr >> 5);
+
+	*a |= mask;
+}
+
+static __inline__ void clear_bit(int nr, volatile void * addr)
+{
+	unsigned long mask = 1 << (nr & 0x1f);
+	unsigned long *a = ((unsigned long *)addr) + (nr >> 5);
+	unsigned long flags;
+
+	local_irq_save(flags);
+	*a &= ~mask;
+	local_irq_restore(flags);
+}
+
+static __inline__ void __clear_bit(int nr, volatile unsigned long *addr)
+{
+	unsigned long mask = 1 << (nr & 0x1f);
+	unsigned long *a = ((unsigned long *)addr) + (nr >> 5);
+
+	*a &= ~mask;
+}
+
+/*
+ * clear_bit() doesn't provide any barrier for the compiler.
+ */
+
+#define smp_mb__before_clear_bit()	barrier()
+#define smp_mb__after_clear_bit()	barrier()
+
+static __inline__ void change_bit(int nr, volatile void * addr)
+{
+	unsigned long mask = 1 << (nr & 0x1f);
+	unsigned long *a = ((unsigned long *)addr) + (nr >> 5);
+	unsigned long flags;
+
+	local_irq_save(flags);
+	*a ^= mask;
+	local_irq_restore(flags);
+}
+
+static __inline__ void __change_bit(int nr, volatile void * addr)
+{
+	unsigned long mask = 1 << (nr & 0x1f);
+	unsigned long *a = ((unsigned long *)addr) + (nr >> 5);
+
+	*a ^= mask;
+}
+
+static __inline__ int test_and_set_bit(int nr, volatile void * addr)
+{
+  	unsigned long retval;
+	unsigned long mask = 1 << (nr & 0x1f);
+	unsigned long *a = ((unsigned long *)addr) + (nr >> 5);
+	unsigned long flags;
+
+	local_irq_save(flags);
+	retval = (mask & *a) != 0;
+	*a |= mask;
+	local_irq_restore(flags);
+
+	return retval;
+}
+
+static __inline__ int __test_and_set_bit(int nr, volatile void * addr)
+{
+  	unsigned long retval;
+	unsigned long mask = 1 << (nr & 0x1f);
+	unsigned long *a = ((unsigned long *)addr) + (nr >> 5);
+
+	retval = (mask & *a) != 0;
+	*a |= mask;
+
+	return retval;
+}
+
+static __inline__ int test_and_clear_bit(int nr, volatile void * addr)
+{
+  	unsigned long retval;
+	unsigned long mask = 1 << (nr & 0x1f);
+	unsigned long *a = ((unsigned long *)addr) + (nr >> 5);
+	unsigned long flags;
+
+	local_irq_save(flags);
+	retval = (mask & *a) != 0;
+	*a &= ~mask;
+	local_irq_restore(flags);
+
+	return retval;
+}
+
+static __inline__ int __test_and_clear_bit(int nr, volatile void * addr)
+{
+	unsigned long mask = 1 << (nr & 0x1f);
+	unsigned long *a = ((unsigned long *)addr) + (nr >> 5);
+  	unsigned long old = *a;
+
+	*a = old & ~mask;
+	return (old & mask) != 0;
+}
+
+static __inline__ int test_and_change_bit(int nr, volatile void * addr)
+{
+  	unsigned long retval;
+	unsigned long mask = 1 << (nr & 0x1f);
+	unsigned long *a = ((unsigned long *)addr) + (nr >> 5);
+	unsigned long flags;
+
+	local_irq_save(flags);
+
+	retval = (mask & *a) != 0;
+	*a ^= mask;
+	local_irq_restore(flags);
+
+	return retval;
+}
+
+/*
+ * non-atomic version; can be reordered
+ */
+
+static __inline__ int __test_and_change_bit(int nr, volatile void *addr)
+{
+	unsigned long mask = 1 << (nr & 0x1f);
+	unsigned long *a = ((unsigned long *)addr) + (nr >> 5);
+	unsigned long old = *a;
+
+	*a = old ^ mask;
+	return (old & mask) != 0;
+}
+
+static __inline__ int test_bit(int nr, const volatile void *addr)
+{
+	return 1UL & (((const volatile unsigned int *)addr)[nr>>5] >> (nr&31));
+}
+
+#if XCHAL_HAVE_NSAU
+
+static __inline__ int __cntlz (unsigned long x)
+{
+	int lz;
+	asm ("nsau %0, %1" : "=r" (lz) : "r" (x));
+	return 31 - lz;
+}
+
+#else
+
+static __inline__ int __cntlz (unsigned long x)
+{
+	unsigned long sum, x1, x2, x4, x8, x16;
+	x1  = x & 0xAAAAAAAA;
+	x2  = x & 0xCCCCCCCC;
+	x4  = x & 0xF0F0F0F0;
+	x8  = x & 0xFF00FF00;
+	x16 = x & 0xFFFF0000;
+	sum = x2 ? 2 : 0;
+	sum += (x16 != 0) * 16;
+	sum += (x8 != 0) * 8;
+	sum += (x4 != 0) * 4;
+	sum += (x1 != 0);
+
+	return sum;
+}
+
+#endif
+
+/*
+ * ffz: Find first zero in word. Undefined if no zero exists.
+ * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1).
+ */
+
+static __inline__ int ffz(unsigned long x)
+{
+	if ((x = ~x) == 0)
+		return 32;
+	return __cntlz(x & -x);
+}
+
+/*
+ * __ffs: Find first bit set in word. Return 0 for bit 0
+ */
+
+static __inline__ int __ffs(unsigned long x)
+{
+	return __cntlz(x & -x);
+}
+
+/*
+ * ffs: Find first bit set in word. This is defined the same way as
+ * the libc and compiler builtin ffs routines, therefore
+ * differs in spirit from the above ffz (man ffs).
+ */
+
+static __inline__ int ffs(unsigned long x)
+{
+	return __cntlz(x & -x) + 1;
+}
+
+/*
+ * fls: Find last (most-significant) bit set in word.
+ * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
+ */
+
+static __inline__ int fls (unsigned int x)
+{
+	return __cntlz(x);
+}
+
+static __inline__ int
+find_next_bit(const unsigned long *addr, int size, int offset)
+{
+	const unsigned long *p = addr + (offset >> 5);
+	unsigned long result = offset & ~31UL;
+	unsigned long tmp;
+
+	if (offset >= size)
+		return size;
+	size -= result;
+	offset &= 31UL;
+	if (offset) {
+		tmp = *p++;
+		tmp &= ~0UL << offset;
+		if (size < 32)
+			goto found_first;
+		if (tmp)
+			goto found_middle;
+		size -= 32;
+		result += 32;
+	}
+	while (size >= 32) {
+		if ((tmp = *p++) != 0)
+			goto found_middle;
+		result += 32;
+		size -= 32;
+	}
+	if (!size)
+		return result;
+	tmp = *p;
+
+found_first:
+	tmp &= ~0UL >> (32 - size);
+	if (tmp == 0UL)	/* Are any bits set? */
+		return result + size;	/* Nope. */
+found_middle:
+	return result + __ffs(tmp);
+}
+
+/**
+ * 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.
+ */
+
+#define find_first_bit(addr, size) \
+        find_next_bit((addr), (size), 0)
+
+static __inline__ int
+find_next_zero_bit(const unsigned long *addr, int size, int offset)
+{
+	const unsigned long *p = addr + (offset >> 5);
+	unsigned long result = offset & ~31UL;
+	unsigned long tmp;
+
+	if (offset >= size)
+		return size;
+	size -= result;
+	offset &= 31UL;
+	if (offset) {
+		tmp = *p++;
+		tmp |= ~0UL >> (32-offset);
+		if (size < 32)
+			goto found_first;
+		if (~tmp)
+			goto found_middle;
+		size -= 32;
+		result += 32;
+	}
+	while (size & ~31UL) {
+		if (~(tmp = *p++))
+			goto found_middle;
+		result += 32;
+		size -= 32;
+	}
+	if (!size)
+		return result;
+	tmp = *p;
+
+found_first:
+	tmp |= ~0UL << size;
+found_middle:
+	return result + ffz(tmp);
+}
+
+#define find_first_zero_bit(addr, size) \
+        find_next_zero_bit((addr), (size), 0)
+
+#ifdef __XTENSA_EL__
+# define ext2_set_bit(nr,addr) __test_and_set_bit((nr), (addr))
+# define ext2_set_bit_atomic(lock,nr,addr) test_and_set_bit((nr),(addr))
+# define ext2_clear_bit(nr,addr) __test_and_clear_bit((nr), (addr))
+# define ext2_clear_bit_atomic(lock,nr,addr) test_and_clear_bit((nr),(addr))
+# define ext2_test_bit(nr,addr) test_bit((nr), (addr))
+# define ext2_find_first_zero_bit(addr, size) find_first_zero_bit((addr),(size))
+# define ext2_find_next_zero_bit(addr, size, offset) \
+                find_next_zero_bit((addr), (size), (offset))
+#elif defined(__XTENSA_EB__)
+# define ext2_set_bit(nr,addr) __test_and_set_bit((nr) ^ 0x18, (addr))
+# define ext2_set_bit_atomic(lock,nr,addr) test_and_set_bit((nr) ^ 0x18, (addr))
+# define ext2_clear_bit(nr,addr) __test_and_clear_bit((nr) ^ 18, (addr))
+# define ext2_clear_bit_atomic(lock,nr,addr) test_and_clear_bit((nr)^0x18,(addr))
+# define ext2_test_bit(nr,addr) test_bit((nr) ^ 0x18, (addr))
+# define ext2_find_first_zero_bit(addr, size) \
+        ext2_find_next_zero_bit((addr), (size), 0)
+
+static __inline__ unsigned long ext2_find_next_zero_bit(void *addr, unsigned long size, unsigned long offset)
+{
+	unsigned long *p = ((unsigned long *) addr) + (offset >> 5);
+	unsigned long result = offset & ~31UL;
+	unsigned long tmp;
+
+	if (offset >= size)
+		return size;
+	size -= result;
+	offset &= 31UL;
+	if(offset) {
+		/* We hold the little endian value in tmp, but then the
+		 * shift is illegal. So we could keep a big endian value
+		 * in tmp, like this:
+		 *
+		 * tmp = __swab32(*(p++));
+		 * tmp |= ~0UL >> (32-offset);
+		 *
+		 * but this would decrease preformance, so we change the
+		 * shift:
+		 */
+		tmp = *(p++);
+		tmp |= __swab32(~0UL >> (32-offset));
+		if(size < 32)
+			goto found_first;
+		if(~tmp)
+			goto found_middle;
+		size -= 32;
+		result += 32;
+	}
+	while(size & ~31UL) {
+		if(~(tmp = *(p++)))
+			goto found_middle;
+		result += 32;
+		size -= 32;
+	}
+	if(!size)
+		return result;
+	tmp = *p;
+
+found_first:
+	/* tmp is little endian, so we would have to swab the shift,
+	 * see above. But then we have to swab tmp below for ffz, so
+	 * we might as well do this here.
+	 */
+	return result + ffz(__swab32(tmp) | (~0UL << size));
+found_middle:
+	return result + ffz(__swab32(tmp));
+}
+
+#else
+# error processor byte order undefined!
+#endif
+
+
+#define hweight32(x)	generic_hweight32(x)
+#define hweight16(x)	generic_hweight16(x)
+#define hweight8(x)	generic_hweight8(x)
+
+/*
+ * Find the first bit set in a 140-bit bitmap.
+ * The first 100 bits are unlikely to be set.
+ */
+
+static inline int sched_find_first_bit(const 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;
+}
+
+
+/* Bitmap functions for the minix filesystem.  */
+
+#define minix_test_and_set_bit(nr,addr) test_and_set_bit(nr,addr)
+#define minix_set_bit(nr,addr) set_bit(nr,addr)
+#define minix_test_and_clear_bit(nr,addr) test_and_clear_bit(nr,addr)
+#define minix_test_bit(nr,addr) test_bit(nr,addr)
+#define minix_find_first_zero_bit(addr,size) find_first_zero_bit(addr,size)
+
+#endif	/* __KERNEL__ */
+
+#endif	/* _XTENSA_BITOPS_H */
diff --git a/include/asm-xtensa/bootparam.h b/include/asm-xtensa/bootparam.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/bootparam.h
@@ -0,0 +1,61 @@
+/*
+ * include/asm-xtensa/bootparam.h
+ *
+ * Definition of the Linux/Xtensa boot parameter structure
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005  Tensilica Inc.
+ *
+ * (Concept borrowed from the 68K port)
+ */
+
+#ifndef _XTENSA_BOOTPARAM_H
+#define _XTENSA_BOOTPARAM_H
+
+#define BP_VERSION 0x0001
+
+#define BP_TAG_COMMAND_LINE	0x1001	/* command line (0-terminated string)*/
+#define BP_TAG_INITRD		0x1002	/* ramdisk addr and size (bp_meminfo) */
+#define BP_TAG_MEMORY		0x1003	/* memory addr and size (bp_meminfo) */
+#define BP_TAG_SERIAL_BAUSRATE	0x1004	/* baud rate of current console. */
+#define BP_TAG_SERIAL_PORT	0x1005	/* serial device of current console */
+
+#define BP_TAG_FIRST		0x7B0B  /* first tag with a version number */
+#define BP_TAG_LAST 		0x7E0B	/* last tag */
+
+#ifndef __ASSEMBLY__
+
+/* All records are aligned to 4 bytes */
+
+typedef struct bp_tag {
+  unsigned short id;		/* tag id */
+  unsigned short size;		/* size of this record excluding the structure*/
+  unsigned long data[0];	/* data */
+} bp_tag_t;
+
+typedef struct meminfo {
+  unsigned long type;
+  unsigned long start;
+  unsigned long end;
+} meminfo_t;
+
+#define SYSMEM_BANKS_MAX 5
+
+#define MEMORY_TYPE_CONVENTIONAL	0x1000
+#define MEMORY_TYPE_NONE		0x2000
+
+typedef struct sysmem_info {
+  int nr_banks;
+  meminfo_t bank[SYSMEM_BANKS_MAX];
+} sysmem_info_t;
+
+extern sysmem_info_t sysmem;
+
+#endif
+#endif
+
+
+
diff --git a/include/asm-xtensa/bug.h b/include/asm-xtensa/bug.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/bug.h
@@ -0,0 +1,41 @@
+/*
+ * include/asm-xtensa/bug.h
+ *
+ * Macros to cause a 'bug' message.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_BUG_H
+#define _XTENSA_BUG_H
+
+#include <linux/stringify.h>
+
+#define ILL	__asm__ __volatile__ (".byte 0,0,0\n")
+
+#ifdef CONFIG_KALLSYMS
+# define BUG() do {							\
+	printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__);		\
+	ILL;								\
+} while (0)
+#else
+# define BUG() do {							\
+	printk("kernel BUG!\n");					\
+      	ILL;								\
+} while (0)
+#endif
+
+#define BUG_ON(condition) do { if (unlikely((condition)!=0)) BUG(); } while(0)
+#define PAGE_BUG(page) do {  BUG(); } while (0)
+#define WARN_ON(condition) do {						   \
+  if (unlikely((condition)!=0)) {					   \
+    printk ("Warning in %s at %s:%d\n", __FUNCTION__, __FILE__, __LINE__); \
+      dump_stack();							   \
+  }									   \
+} while (0)
+
+#endif	/* _XTENSA_BUG_H */
diff --git a/include/asm-xtensa/bugs.h b/include/asm-xtensa/bugs.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/bugs.h
@@ -0,0 +1,22 @@
+/*
+ * include/asm-xtensa/bugs.h
+ *
+ * This is included by init/main.c to check for architecture-dependent bugs.
+ *
+ * Xtensa processors don't have any bugs.  :)
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file "COPYING" in the main directory of
+ * this archive for more details.
+ */
+
+#ifndef _XTENSA_BUGS_H
+#define _XTENSA_BUGS_H
+
+#include <asm/processor.h>
+
+static void __init check_bugs(void)
+{
+}
+
+#endif /* _XTENSA_BUGS_H */
diff --git a/include/asm-xtensa/byteorder.h b/include/asm-xtensa/byteorder.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/byteorder.h
@@ -0,0 +1,82 @@
+/*
+ * include/asm-xtensa/byteorder.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_BYTEORDER_H
+#define _XTENSA_BYTEORDER_H
+
+#include <asm/processor.h>
+#include <asm/types.h>
+
+static __inline__ __const__ __u32 ___arch__swab32(__u32 x)
+{
+    __u32 res;
+    /* instruction sequence from Xtensa ISA release 2/2000 */
+    __asm__("ssai     8           \n\t"
+	    "srli     %0, %1, 16  \n\t"
+	    "src      %0, %0, %1  \n\t"
+	    "src      %0, %0, %0  \n\t"
+	    "src      %0, %1, %0  \n"
+	    : "=&a" (res)
+	    : "a" (x)
+	    );
+    return res;
+}
+
+static __inline__ __const__ __u16 ___arch__swab16(__u16 x)
+{
+    /* Given that 'short' values are signed (i.e., can be negative),
+     * we cannot assume that the upper 16-bits of the register are
+     * zero.  We are careful to mask values after shifting.
+     */
+
+    /* There exists an anomaly between xt-gcc and xt-xcc.  xt-gcc
+     * inserts an extui instruction after putting this function inline
+     * to ensure that it uses only the least-significant 16 bits of
+     * the result.  xt-xcc doesn't use an extui, but assumes the
+     * __asm__ macro follows convention that the upper 16 bits of an
+     * 'unsigned short' result are still zero.  This macro doesn't
+     * follow convention; indeed, it leaves garbage in the upport 16
+     * bits of the register.
+
+     * Declaring the temporary variables 'res' and 'tmp' to be 32-bit
+     * types while the return type of the function is a 16-bit type
+     * forces both compilers to insert exactly one extui instruction
+     * (or equivalent) to mask off the upper 16 bits. */
+
+    __u32 res;
+    __u32 tmp;
+
+    __asm__("extui    %1, %2, 8, 8\n\t"
+	    "slli     %0, %2, 8   \n\t"
+	    "or       %0, %0, %1  \n"
+	    : "=&a" (res), "=&a" (tmp)
+	    : "a" (x)
+	    );
+
+    return res;
+}
+
+#define __arch__swab32(x) ___arch__swab32(x)
+#define __arch__swab16(x) ___arch__swab16(x)
+
+#if !defined(__STRICT_ANSI__) || defined(__KERNEL__)
+#  define __BYTEORDER_HAS_U64__
+#  define __SWAB_64_THRU_32__
+#endif
+
+#ifdef __XTENSA_EL__
+# include <linux/byteorder/little_endian.h>
+#elif defined(__XTENSA_EB__)
+# include <linux/byteorder/big_endian.h>
+#else
+# error processor byte order undefined!
+#endif
+
+#endif /* __ASM_XTENSA_BYTEORDER_H */
diff --git a/include/asm-xtensa/cache.h b/include/asm-xtensa/cache.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/cache.h
@@ -0,0 +1,32 @@
+/*
+ * include/asm-xtensa/cacheflush.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ * 2 of the License, or (at your option) any later version.
+ *
+ * (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_CACHE_H
+#define _XTENSA_CACHE_H
+
+#include <xtensa/config/core.h>
+
+#if XCHAL_ICACHE_SIZE > 0
+# if (XCHAL_ICACHE_SIZE % (XCHAL_ICACHE_LINESIZE*XCHAL_ICACHE_WAYS*4)) != 0
+#  error cache configuration outside expected/supported range!
+# endif
+#endif
+
+#if XCHAL_DCACHE_SIZE > 0
+# if (XCHAL_DCACHE_SIZE % (XCHAL_DCACHE_LINESIZE*XCHAL_DCACHE_WAYS*4)) != 0
+#  error cache configuration outside expected/supported range!
+# endif
+#endif
+
+#define L1_CACHE_SHIFT		XCHAL_CACHE_LINEWIDTH_MAX
+#define L1_CACHE_BYTES		XCHAL_CACHE_LINESIZE_MAX
+
+#endif	/* _XTENSA_CACHE_H */
diff --git a/include/asm-xtensa/cacheflush.h b/include/asm-xtensa/cacheflush.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/cacheflush.h
@@ -0,0 +1,122 @@
+/*
+ * include/asm-xtensa/cacheflush.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_CACHEFLUSH_H
+#define _XTENSA_CACHEFLUSH_H
+
+#ifdef __KERNEL__
+
+#include <linux/mm.h>
+#include <asm/processor.h>
+#include <asm/page.h>
+
+/*
+ * flush and invalidate data cache, invalidate instruction cache:
+ *
+ * __flush_invalidate_cache_all()
+ * __flush_invalidate_cache_range(from,sze)
+ *
+ * invalidate data or instruction cache:
+ *
+ * __invalidate_icache_all()
+ * __invalidate_icache_page(adr)
+ * __invalidate_dcache_page(adr)
+ * __invalidate_icache_range(from,size)
+ * __invalidate_dcache_range(from,size)
+ *
+ * flush data cache:
+ *
+ * __flush_dcache_page(adr)
+ *
+ * flush and invalidate data cache:
+ *
+ * __flush_invalidate_dcache_all()
+ * __flush_invalidate_dcache_page(adr)
+ * __flush_invalidate_dcache_range(from,size)
+ */
+
+extern void __flush_invalidate_cache_all(void);
+extern void __flush_invalidate_cache_range(unsigned long, unsigned long);
+extern void __flush_invalidate_dcache_all(void);
+extern void __invalidate_icache_all(void);
+
+extern void __invalidate_dcache_page(unsigned long);
+extern void __invalidate_icache_page(unsigned long);
+extern void __invalidate_icache_range(unsigned long, unsigned long);
+extern void __invalidate_dcache_range(unsigned long, unsigned long);
+
+#if XCHAL_DCACHE_IS_WRITEBACK
+extern void __flush_dcache_page(unsigned long);
+extern void __flush_invalidate_dcache_page(unsigned long);
+extern void __flush_invalidate_dcache_range(unsigned long, unsigned long);
+#else
+# define __flush_dcache_page(p)				do { } while(0)
+# define __flush_invalidate_dcache_page(p) 		do { } while(0)
+# define __flush_invalidate_dcache_range(p,s)		do { } while(0)
+#endif
+
+/*
+ * We have physically tagged caches - nothing to do here -
+ * unless we have cache aliasing.
+ *
+ * Pages can get remapped. Because this might change the 'color' of that page,
+ * we have to flush the cache before the PTE is changed.
+ * (see also Documentation/cachetlb.txt)
+ */
+
+#if (DCACHE_WAY_SIZE > PAGE_SIZE) && XCHAL_DCACHE_IS_WRITEBACK
+
+#define flush_cache_all()		__flush_invalidate_cache_all();
+#define flush_cache_mm(mm)		__flush_invalidate_cache_all();
+
+#define flush_cache_vmap(start,end)	__flush_invalidate_cache_all();
+#define flush_cache_vunmap(start,end)	__flush_invalidate_cache_all();
+
+extern void flush_dcache_page(struct page*);
+
+extern void flush_cache_range(struct vm_area_struct*, ulong, ulong);
+extern void flush_cache_page(struct vm_area_struct*, unsigned long, unsigned long);
+
+#else
+
+#define flush_cache_all()				do { } while (0)
+#define flush_cache_mm(mm)				do { } while (0)
+
+#define flush_cache_vmap(start,end)			do { } while (0)
+#define flush_cache_vunmap(start,end)			do { } while (0)
+
+#define flush_dcache_page(page)				do { } while (0)
+
+#define flush_cache_page(vma,addr,pfn)			do { } while (0)
+#define flush_cache_range(vma,start,end)		do { } while (0)
+
+#endif
+
+#define flush_icache_range(start,end) 					\
+	__invalidate_icache_range(start,(end)-(start))
+
+/* This is not required, see Documentation/cachetlb.txt */
+
+#define	flush_icache_page(vma,page)			do { } while(0)
+
+#define flush_dcache_mmap_lock(mapping)			do { } while (0)
+#define flush_dcache_mmap_unlock(mapping)		do { } while (0)
+
+
+#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
+	memcpy(dst, src, len)
+
+#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
+	memcpy(dst, src, len)
+
+#endif /* __KERNEL__ */
+
+#endif /* _XTENSA_CACHEFLUSH_H */
+
diff --git a/include/asm-xtensa/checksum.h b/include/asm-xtensa/checksum.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/checksum.h
@@ -0,0 +1,264 @@
+/*
+ * include/asm-xtensa/checksum.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_CHECKSUM_H
+#define _XTENSA_CHECKSUM_H
+
+#include <linux/config.h>
+#include <linux/in6.h>
+#include <xtensa/config/core.h>
+
+/*
+ * computes the checksum of a memory block at buff, length len,
+ * and adds in "sum" (32-bit)
+ *
+ * returns a 32-bit number suitable for feeding into itself
+ * or csum_tcpudp_magic
+ *
+ * this function must be called with even lengths, except
+ * for the last fragment, which may be odd
+ *
+ * it's best to have buff aligned on a 32-bit boundary
+ */
+asmlinkage unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum);
+
+/*
+ * the same as csum_partial, but copies from src while it
+ * checksums, and handles user-space pointer exceptions correctly, when needed.
+ *
+ * here even more important to align src and dst on a 32-bit (or even
+ * better 64-bit) boundary
+ */
+
+asmlinkage unsigned int csum_partial_copy_generic( const char *src, char *dst, int len, int sum,
+						   int *src_err_ptr, int *dst_err_ptr);
+
+/*
+ *	Note: when you get a NULL pointer exception here this means someone
+ *	passed in an incorrect kernel address to one of these functions.
+ *
+ *	If you use these functions directly please don't forget the
+ *	verify_area().
+ */
+extern __inline__
+unsigned int csum_partial_copy_nocheck ( const char *src, char *dst,
+					int len, int sum)
+{
+	return csum_partial_copy_generic ( src, dst, len, sum, NULL, NULL);
+}
+
+extern __inline__
+unsigned int csum_partial_copy_from_user ( const char *src, char *dst,
+						int len, int sum, int *err_ptr)
+{
+	return csum_partial_copy_generic ( src, dst, len, sum, err_ptr, NULL);
+}
+
+/*
+ * These are the old (and unsafe) way of doing checksums, a warning message will be
+ * printed if they are used and an exeption occurs.
+ *
+ * these functions should go away after some time.
+ */
+
+#define csum_partial_copy_fromuser csum_partial_copy
+unsigned int csum_partial_copy( const char *src, char *dst, int len, int sum);
+
+/*
+ *	Fold a partial checksum
+ */
+
+static __inline__ unsigned int csum_fold(unsigned int sum)
+{
+	unsigned int __dummy;
+	__asm__("extui	%1, %0, 16, 16\n\t"
+		"extui	%0 ,%0, 0, 16\n\t"
+		"add	%0, %0, %1\n\t"
+		"slli	%1, %0, 16\n\t"
+		"add	%0, %0, %1\n\t"
+		"extui	%0, %0, 16, 16\n\t"
+		"neg	%0, %0\n\t"
+		"addi	%0, %0, -1\n\t"
+		"extui	%0, %0, 0, 16\n\t"
+		: "=r" (sum), "=&r" (__dummy)
+		: "0" (sum));
+	return sum;
+}
+
+/*
+ *	This is a version of ip_compute_csum() optimized for IP headers,
+ *	which always checksum on 4 octet boundaries.
+ */
+static __inline__ unsigned short ip_fast_csum(unsigned char * iph, unsigned int ihl)
+{
+	unsigned int sum, tmp, endaddr;
+
+	__asm__ __volatile__(
+		"sub		%0, %0, %0\n\t"
+#if XCHAL_HAVE_LOOPS
+		"loopgtz	%2, 2f\n\t"
+#else
+		"beqz		%2, 2f\n\t"
+		"slli		%4, %2, 2\n\t"
+		"add		%4, %4, %1\n\t"
+		"0:\t"
+#endif
+		"l32i		%3, %1, 0\n\t"
+		"add		%0, %0, %3\n\t"
+		"bgeu		%0, %3, 1f\n\t"
+		"addi		%0, %0, 1\n\t"
+		"1:\t"
+		"addi		%1, %1, 4\n\t"
+#if !XCHAL_HAVE_LOOPS
+		"blt		%1, %4, 0b\n\t"
+#endif
+		"2:\t"
+	/* Since the input registers which are loaded with iph and ihl
+	   are modified, we must also specify them as outputs, or gcc
+	   will assume they contain their original values. */
+		: "=r" (sum), "=r" (iph), "=r" (ihl), "=&r" (tmp), "=&r" (endaddr)
+		: "1" (iph), "2" (ihl));
+
+	return	csum_fold(sum);
+}
+
+static __inline__ unsigned long csum_tcpudp_nofold(unsigned long saddr,
+						   unsigned long daddr,
+						   unsigned short len,
+						   unsigned short proto,
+						   unsigned int sum)
+{
+
+#ifdef __XTENSA_EL__
+	unsigned long len_proto = (ntohs(len)<<16)+proto*256;
+#elif defined(__XTENSA_EB__)
+	unsigned long len_proto = (proto<<16)+len;
+#else
+# error processor byte order undefined!
+#endif
+	__asm__("add	%0, %0, %1\n\t"
+		"bgeu	%0, %1, 1f\n\t"
+		"addi	%0, %0, 1\n\t"
+		"1:\t"
+		"add	%0, %0, %2\n\t"
+		"bgeu	%0, %2, 1f\n\t"
+		"addi	%0, %0, 1\n\t"
+		"1:\t"
+		"add	%0, %0, %3\n\t"
+		"bgeu	%0, %3, 1f\n\t"
+		"addi	%0, %0, 1\n\t"
+		"1:\t"
+		: "=r" (sum), "=r" (len_proto)
+		: "r" (daddr), "r" (saddr), "1" (len_proto), "0" (sum));
+	return sum;
+}
+
+/*
+ * computes the checksum of the TCP/UDP pseudo-header
+ * returns a 16-bit checksum, already complemented
+ */
+static __inline__ unsigned short int csum_tcpudp_magic(unsigned long saddr,
+						       unsigned long daddr,
+						       unsigned short len,
+						       unsigned short proto,
+						       unsigned int sum)
+{
+	return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
+}
+
+/*
+ * this routine is used for miscellaneous IP-like checksums, mainly
+ * in icmp.c
+ */
+
+static __inline__ unsigned short ip_compute_csum(unsigned char * buff, int len)
+{
+    return csum_fold (csum_partial(buff, len, 0));
+}
+
+#define _HAVE_ARCH_IPV6_CSUM
+static __inline__ unsigned short int csum_ipv6_magic(struct in6_addr *saddr,
+						     struct in6_addr *daddr,
+						     __u32 len,
+						     unsigned short proto,
+						     unsigned int sum)
+{
+	unsigned int __dummy;
+	__asm__("l32i	%1, %2, 0\n\t"
+		"add	%0, %0, %1\n\t"
+		"bgeu	%0, %1, 1f\n\t"
+		"addi	%0, %0, 1\n\t"
+		"1:\t"
+		"l32i	%1, %2, 4\n\t"
+		"add	%0, %0, %1\n\t"
+		"bgeu	%0, %1, 1f\n\t"
+		"addi	%0, %0, 1\n\t"
+		"1:\t"
+		"l32i	%1, %2, 8\n\t"
+		"add	%0, %0, %1\n\t"
+		"bgeu	%0, %1, 1f\n\t"
+		"addi	%0, %0, 1\n\t"
+		"1:\t"
+		"l32i	%1, %2, 12\n\t"
+		"add	%0, %0, %1\n\t"
+		"bgeu	%0, %1, 1f\n\t"
+		"addi	%0, %0, 1\n\t"
+		"1:\t"
+		"l32i	%1, %3, 0\n\t"
+		"add	%0, %0, %1\n\t"
+		"bgeu	%0, %1, 1f\n\t"
+		"addi	%0, %0, 1\n\t"
+		"1:\t"
+		"l32i	%1, %3, 4\n\t"
+		"add	%0, %0, %1\n\t"
+		"bgeu	%0, %1, 1f\n\t"
+		"addi	%0, %0, 1\n\t"
+		"1:\t"
+		"l32i	%1, %3, 8\n\t"
+		"add	%0, %0, %1\n\t"
+		"bgeu	%0, %1, 1f\n\t"
+		"addi	%0, %0, 1\n\t"
+		"1:\t"
+		"l32i	%1, %3, 12\n\t"
+		"add	%0, %0, %1\n\t"
+		"bgeu	%0, %1, 1f\n\t"
+		"addi	%0, %0, 1\n\t"
+		"1:\t"
+		"add	%0, %0, %4\n\t"
+		"bgeu	%0, %4, 1f\n\t"
+		"addi	%0, %0, 1\n\t"
+		"1:\t"
+		"add	%0, %0, %5\n\t"
+		"bgeu	%0, %5, 1f\n\t"
+		"addi	%0, %0, 1\n\t"
+		"1:\t"
+		: "=r" (sum), "=&r" (__dummy)
+		: "r" (saddr), "r" (daddr),
+		  "r" (htonl(len)), "r" (htonl(proto)), "0" (sum));
+
+	return csum_fold(sum);
+}
+
+/*
+ *	Copy and checksum to user
+ */
+#define HAVE_CSUM_COPY_USER
+static __inline__ unsigned int csum_and_copy_to_user (const char *src, char *dst,
+				    int len, int sum, int *err_ptr)
+{
+	if (access_ok(VERIFY_WRITE, dst, len))
+		return csum_partial_copy_generic(src, dst, len, sum, NULL, err_ptr);
+
+	if (len)
+		*err_ptr = -EFAULT;
+
+	return -1; /* invalid checksum */
+}
+#endif
diff --git a/include/asm-xtensa/coprocessor.h b/include/asm-xtensa/coprocessor.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/coprocessor.h
@@ -0,0 +1,70 @@
+/*
+ * include/asm-xtensa/cpextra.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2003 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_COPROCESSOR_H
+#define _XTENSA_COPROCESSOR_H
+
+#include <xtensa/config/core.h>
+
+#define XTOFS(last_start,last_size,align) \
+	((last_start+last_size+align-1) & -align)
+
+#define XTENSA_CP_EXTRA_OFFSET	0
+#define XTENSA_CP_EXTRA_ALIGN	XCHAL_EXTRA_SA_ALIGN
+
+#define XTENSA_CPE_CP0_OFFSET	\
+	XTOFS(XTENSA_CP_EXTRA_OFFSET, XCHAL_EXTRA_SA_SIZE, XCHAL_CP0_SA_ALIGN)
+#define XTENSA_CPE_CP1_OFFSET	\
+	XTOFS(XTENSA_CPE_CP0_OFFSET, XCHAL_CP0_SA_SIZE, XCHAL_CP1_SA_ALIGN)
+#define XTENSA_CPE_CP2_OFFSET	\
+	XTOFS(XTENSA_CPE_CP1_OFFSET, XCHAL_CP1_SA_SIZE, XCHAL_CP2_SA_ALIGN)
+#define XTENSA_CPE_CP3_OFFSET	\
+	XTOFS(XTENSA_CPE_CP2_OFFSET, XCHAL_CP2_SA_SIZE, XCHAL_CP3_SA_ALIGN)
+#define XTENSA_CPE_CP4_OFFSET	\
+	XTOFS(XTENSA_CPE_CP3_OFFSET, XCHAL_CP3_SA_SIZE, XCHAL_CP4_SA_ALIGN)
+#define XTENSA_CPE_CP5_OFFSET	\
+	XTOFS(XTENSA_CPE_CP4_OFFSET, XCHAL_CP4_SA_SIZE, XCHAL_CP5_SA_ALIGN)
+#define XTENSA_CPE_CP6_OFFSET	\
+	XTOFS(XTENSA_CPE_CP5_OFFSET, XCHAL_CP5_SA_SIZE, XCHAL_CP6_SA_ALIGN)
+#define XTENSA_CPE_CP7_OFFSET	\
+	XTOFS(XTENSA_CPE_CP6_OFFSET, XCHAL_CP6_SA_SIZE, XCHAL_CP7_SA_ALIGN)
+#define XTENSA_CP_EXTRA_SIZE	\
+	XTOFS(XTENSA_CPE_CP7_OFFSET, XCHAL_CP7_SA_SIZE, 16)
+
+#if XCHAL_CP_NUM > 0
+# ifndef __ASSEMBLY__
+/*
+ * Tasks that own contents of (last user) each coprocessor.
+ * Entries are 0 for not-owned or non-existent coprocessors.
+ * Note: The size of this structure is fixed to 8 bytes in entry.S
+ */
+typedef struct {
+	struct task_struct *owner;	/* owner */
+	int offset;			/* offset in cpextra space. */
+} coprocessor_info_t;
+# else
+#  define COPROCESSOR_INFO_OWNER 0
+#  define COPROCESSOR_INFO_OFFSET 4
+#  define COPROCESSOR_INFO_SIZE 8
+# endif
+#endif
+
+
+#ifndef __ASSEMBLY__
+# if XCHAL_CP_NUM > 0
+struct task_struct;
+extern void release_coprocessors (struct task_struct*);
+extern void save_coprocessor_registers(void*, int);
+# else
+#  define release_coprocessors(task)
+# endif
+#endif
+
+#endif	/* _XTENSA_COPROCESSOR_H */
diff --git a/include/asm-xtensa/cpumask.h b/include/asm-xtensa/cpumask.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/cpumask.h
@@ -0,0 +1,16 @@
+/*
+ * include/asm-xtensa/cpumask.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_CPUMASK_H
+#define _XTENSA_CPUMASK_H
+
+#include <asm-generic/cpumask.h>
+
+#endif /* _XTENSA_CPUMASK_H */
diff --git a/include/asm-xtensa/cputime.h b/include/asm-xtensa/cputime.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/cputime.h
@@ -0,0 +1,6 @@
+#ifndef _XTENSA_CPUTIME_H
+#define _XTENSA_CPUTIME_H
+
+#include <asm-generic/cputime.h>
+
+#endif /* _XTENSA_CPUTIME_H */
diff --git a/include/asm-xtensa/current.h b/include/asm-xtensa/current.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/current.h
@@ -0,0 +1,38 @@
+/*
+ * include/asm-xtensa/current.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_CURRENT_H
+#define _XTENSA_CURRENT_H
+
+#ifndef __ASSEMBLY__
+
+#include <linux/thread_info.h>
+
+struct task_struct;
+
+static inline struct task_struct *get_current(void)
+{
+	return current_thread_info()->task;
+}
+
+#define current get_current()
+
+#else
+
+#define CURRENT_SHIFT 13
+
+#define GET_CURRENT(reg,sp)		\
+	GET_THREAD_INFO(reg,sp);	\
+  	l32i reg, reg, TI_TASK		\
+
+#endif
+
+
+#endif /* XTENSA_CURRENT_H */
diff --git a/include/asm-xtensa/delay.h b/include/asm-xtensa/delay.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/delay.h
@@ -0,0 +1,50 @@
+/*
+ * include/asm-xtensa/delay.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ *
+ */
+
+#ifndef _XTENSA_DELAY_H
+#define _XTENSA_DELAY_H
+
+#include <linux/config.h>
+#include <asm/processor.h>
+#include <asm/param.h>
+
+extern unsigned long loops_per_jiffy;
+
+extern __inline__ void __delay(unsigned long loops)
+{
+  /* 2 cycles per loop. */
+  __asm__ __volatile__ ("1: addi %0, %0, -2; bgeui %0, 2, 1b"
+			: "=r" (loops) : "0" (loops));
+}
+
+static __inline__ u32 xtensa_get_ccount(void)
+{
+	u32 ccount;
+	asm volatile ("rsr %0, 234; # CCOUNT\n" : "=r" (ccount));
+	return ccount;
+}
+
+/* For SMP/NUMA systems, change boot_cpu_data to something like
+ * local_cpu_data->... where local_cpu_data points to the current
+ * cpu. */
+
+static __inline__ void udelay (unsigned long usecs)
+{
+	unsigned long start = xtensa_get_ccount();
+	unsigned long cycles = usecs * (loops_per_jiffy / (1000000UL / HZ));
+
+	/* Note: all variables are unsigned (can wrap around)! */
+	while (((unsigned long)xtensa_get_ccount()) - start < cycles)
+		;
+}
+
+#endif
+
diff --git a/include/asm-xtensa/div64.h b/include/asm-xtensa/div64.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/div64.h
@@ -0,0 +1,19 @@
+/*
+ * include/asm-xtensa/div64.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_DIV64_H
+#define _XTENSA_DIV64_H
+
+#define do_div(n,base) ({ \
+	int __res = n % ((unsigned int) base); \
+	n /= (unsigned int) base; \
+	__res; })
+
+#endif
diff --git a/include/asm-xtensa/dma-mapping.h b/include/asm-xtensa/dma-mapping.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/dma-mapping.h
@@ -0,0 +1,182 @@
+/*
+ * include/asm-xtensa/dma_mapping.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2003 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_DMA_MAPPING_H
+#define _XTENSA_DMA_MAPPING_H
+
+#include <asm/scatterlist.h>
+#include <asm/cache.h>
+#include <asm/io.h>
+#include <linux/mm.h>
+
+/*
+ * DMA-consistent mapping functions.
+ */
+
+extern void *consistent_alloc(int, size_t, dma_addr_t, unsigned long);
+extern void consistent_free(void*, size_t, dma_addr_t);
+extern void consistent_sync(void*, size_t, int);
+
+#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
+#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
+
+void *dma_alloc_coherent(struct device *dev, size_t size,
+			   dma_addr_t *dma_handle, int flag);
+
+void dma_free_coherent(struct device *dev, size_t size,
+			 void *vaddr, dma_addr_t dma_handle);
+
+static inline dma_addr_t
+dma_map_single(struct device *dev, void *ptr, size_t size,
+	       enum dma_data_direction direction)
+{
+	BUG_ON(direction == DMA_NONE);
+	consistent_sync(ptr, size, direction);
+	return virt_to_phys(ptr);
+}
+
+static inline void
+dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
+		 enum dma_data_direction direction)
+{
+	BUG_ON(direction == DMA_NONE);
+}
+
+static inline int
+dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
+	   enum dma_data_direction direction)
+{
+	int i;
+
+	BUG_ON(direction == DMA_NONE);
+
+	for (i = 0; i < nents; i++, sg++ ) {
+		BUG_ON(!sg->page);
+
+		sg->dma_address = page_to_phys(sg->page) + sg->offset;
+		consistent_sync(page_address(sg->page) + sg->offset,
+				sg->length, direction);
+	}
+
+	return nents;
+}
+
+static inline dma_addr_t
+dma_map_page(struct device *dev, struct page *page, unsigned long offset,
+	     size_t size, enum dma_data_direction direction)
+{
+	BUG_ON(direction == DMA_NONE);
+	return (dma_addr_t)(page_to_pfn(page)) * PAGE_SIZE + offset;
+}
+
+static inline void
+dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
+	       enum dma_data_direction direction)
+{
+	BUG_ON(direction == DMA_NONE);
+}
+
+
+static inline void
+dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
+	     enum dma_data_direction direction)
+{
+	BUG_ON(direction == DMA_NONE);
+}
+
+static inline void
+dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size,
+		enum dma_data_direction direction)
+{
+	consistent_sync((void *)bus_to_virt(dma_handle), size, direction);
+}
+
+static inline void
+dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, size_t size,
+		enum dma_data_direction direction)
+{
+	consistent_sync((void *)bus_to_virt(dma_handle), size, direction);
+}
+
+static inline void
+dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t dma_handle,
+		      unsigned long offset, size_t size,
+		      enum dma_data_direction direction)
+{
+
+	consistent_sync((void *)bus_to_virt(dma_handle)+offset,size,direction);
+}
+
+static inline void
+dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_handle,
+		      unsigned long offset, size_t size,
+		      enum dma_data_direction direction)
+{
+
+	consistent_sync((void *)bus_to_virt(dma_handle)+offset,size,direction);
+}
+static inline void
+dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
+		 enum dma_data_direction dir)
+{
+	int i;
+	for (i = 0; i < nelems; i++, sg++)
+		consistent_sync(page_address(sg->page) + sg->offset,
+				sg->length, dir);
+}
+
+static inline void
+dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems,
+		 enum dma_data_direction dir)
+{
+	int i;
+	for (i = 0; i < nelems; i++, sg++)
+		consistent_sync(page_address(sg->page) + sg->offset,
+				sg->length, dir);
+}
+static inline int
+dma_mapping_error(dma_addr_t dma_addr)
+{
+	return 0;
+}
+
+static inline int
+dma_supported(struct device *dev, u64 mask)
+{
+	return 1;
+}
+
+static inline int
+dma_set_mask(struct device *dev, u64 mask)
+{
+	if(!dev->dma_mask || !dma_supported(dev, mask))
+		return -EIO;
+
+	*dev->dma_mask = mask;
+
+	return 0;
+}
+
+static inline int
+dma_get_cache_alignment(void)
+{
+	return L1_CACHE_BYTES;
+}
+
+#define dma_is_consistent(d)	(1)
+
+static inline void
+dma_cache_sync(void *vaddr, size_t size,
+	       enum dma_data_direction direction)
+{
+	consistent_sync(vaddr, size, direction);
+}
+
+#endif	/* _XTENSA_DMA_MAPPING_H */
diff --git a/include/asm-xtensa/dma.h b/include/asm-xtensa/dma.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/dma.h
@@ -0,0 +1,61 @@
+/*
+ * include/asm-xtensa/dma.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2003 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_DMA_H
+#define _XTENSA_DMA_H
+
+#include <linux/config.h>
+#include <asm/io.h>		/* need byte IO */
+#include <xtensa/config/core.h>
+
+/*
+ * This is only to be defined if we have PC-like DMA.
+ * By default this is not true on an Xtensa processor,
+ * however on boards with a PCI bus, such functionality
+ * might be emulated externally.
+ *
+ * NOTE:  there still exists driver code that assumes
+ * this is defined, eg. drivers/sound/soundcard.c (as of 2.4).
+ */
+#define MAX_DMA_CHANNELS	8
+
+/*
+ * The maximum virtual address to which DMA transfers
+ * can be performed on this platform.
+ *
+ * NOTE: This is board (platform) specific, not processor-specific!
+ *
+ * NOTE: This assumes DMA transfers can only be performed on
+ *	the section of physical memory contiguously mapped in virtual
+ *	space for the kernel.  For the Xtensa architecture, this
+ *	means the maximum possible size of this DMA area is
+ *	the size of the statically mapped kernel segment
+ *	(XCHAL_KSEG_{CACHED,BYPASS}_SIZE), ie. 128 MB.
+ *
+ * NOTE: When the entire KSEG area is DMA capable, we substract
+ *	one from the max address so that the virt_to_phys() macro
+ *	works correctly on the address (otherwise the address
+ *	enters another area, and virt_to_phys() may not return
+ *	the value desired).
+ */
+#define MAX_DMA_ADDRESS		(PAGE_OFFSET + XCHAL_KSEG_CACHED_SIZE - 1)
+
+/* Reserve and release a DMA channel */
+extern int request_dma(unsigned int dmanr, const char * device_id);
+extern void free_dma(unsigned int dmanr);
+
+#ifdef CONFIG_PCI
+extern int isa_dma_bridge_buggy;
+#else
+#define isa_dma_bridge_buggy 	(0)
+#endif
+
+
+#endif
diff --git a/include/asm-xtensa/elf.h b/include/asm-xtensa/elf.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/elf.h
@@ -0,0 +1,222 @@
+/*
+ * include/asm-xtensa/elf.h
+ *
+ * ELF register definitions
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_ELF_H
+#define _XTENSA_ELF_H
+
+#include <asm/ptrace.h>
+#include <asm/coprocessor.h>
+#include <xtensa/config/core.h>
+
+/* Xtensa processor ELF architecture-magic number */
+
+#define EM_XTENSA	94
+#define EM_XTENSA_OLD	0xABC7
+
+/* ELF register definitions. This is needed for core dump support.  */
+
+/*
+ * elf_gregset_t contains the application-level state in the following order:
+ * Processor info: 	config_version, cpuxy
+ * Processor state:	pc, ps, exccause, excvaddr, wb, ws,
+ *			lbeg, lend, lcount, sar
+ * GP regs:		ar0 - arXX
+ */
+
+typedef unsigned long elf_greg_t;
+
+typedef struct {
+	elf_greg_t xchal_config_id0;
+	elf_greg_t xchal_config_id1;
+	elf_greg_t cpux;
+	elf_greg_t cpuy;
+	elf_greg_t pc;
+	elf_greg_t ps;
+	elf_greg_t exccause;
+	elf_greg_t excvaddr;
+	elf_greg_t windowbase;
+	elf_greg_t windowstart;
+	elf_greg_t lbeg;
+	elf_greg_t lend;
+	elf_greg_t lcount;
+	elf_greg_t sar;
+	elf_greg_t syscall;
+	elf_greg_t ar[XCHAL_NUM_AREGS];
+} xtensa_gregset_t;
+
+#define ELF_NGREG	(sizeof(xtensa_gregset_t) / sizeof(elf_greg_t))
+
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+
+/*
+ *  Compute the size of the coprocessor and extra state layout (register info)
+ *  table (in bytes).
+ *  This is actually the maximum size of the table, as opposed to the size,
+ *  which is available from the _xtensa_reginfo_table_size global variable.
+ *
+ *  (See also arch/xtensa/kernel/coprocessor.S)
+ *
+ */
+
+#ifndef XCHAL_EXTRA_SA_CONTENTS_LIBDB_NUM
+# define XTENSA_CPE_LTABLE_SIZE		0
+#else
+# define XTENSA_CPE_SEGMENT(num)	(num ? (1+num) : 0)
+# define XTENSA_CPE_LTABLE_ENTRIES	\
+		( XTENSA_CPE_SEGMENT(XCHAL_EXTRA_SA_CONTENTS_LIBDB_NUM)	\
+		+ XTENSA_CPE_SEGMENT(XCHAL_CP0_SA_CONTENTS_LIBDB_NUM)	\
+		+ XTENSA_CPE_SEGMENT(XCHAL_CP1_SA_CONTENTS_LIBDB_NUM)	\
+		+ XTENSA_CPE_SEGMENT(XCHAL_CP2_SA_CONTENTS_LIBDB_NUM)	\
+		+ XTENSA_CPE_SEGMENT(XCHAL_CP3_SA_CONTENTS_LIBDB_NUM)	\
+		+ XTENSA_CPE_SEGMENT(XCHAL_CP4_SA_CONTENTS_LIBDB_NUM)	\
+		+ XTENSA_CPE_SEGMENT(XCHAL_CP5_SA_CONTENTS_LIBDB_NUM)	\
+		+ XTENSA_CPE_SEGMENT(XCHAL_CP6_SA_CONTENTS_LIBDB_NUM)	\
+		+ XTENSA_CPE_SEGMENT(XCHAL_CP7_SA_CONTENTS_LIBDB_NUM)	\
+		+ 1		/* final entry */			\
+		)
+# define XTENSA_CPE_LTABLE_SIZE		(XTENSA_CPE_LTABLE_ENTRIES * 8)
+#endif
+
+
+/*
+ * Instantiations of the elf_fpregset_t type contain, in most
+ * architectures, the floating point (FPU) register set.
+ * For Xtensa, this type is extended to contain all custom state,
+ * ie. coprocessor and "extra" (non-coprocessor) state (including,
+ * for example, TIE-defined states and register files; as well
+ * as other optional processor state).
+ * This includes FPU state if a floating-point coprocessor happens
+ * to have been configured within the Xtensa processor.
+ *
+ * TOTAL_FPREGS_SIZE is the required size (without rounding)
+ * of elf_fpregset_t.  It provides space for the following:
+ *
+ *  a)	32-bit mask of active coprocessors for this task (similar
+ *	to CPENABLE in single-threaded Xtensa processor systems)
+ *
+ *  b)	table describing the layout of custom states (ie. of
+ *      individual registers, etc) within the save areas
+ *
+ *  c)  save areas for each coprocessor and for non-coprocessor
+ *      ("extra") state
+ *
+ * Note that save areas may require up to 16-byte alignment when
+ * accessed by save/restore sequences.  We do not need to ensure
+ * such alignment in an elf_fpregset_t structure because custom
+ * state is not directly loaded/stored into it; rather, save area
+ * contents are copied to elf_fpregset_t from the active save areas
+ * (see 'struct task_struct' definition in processor.h for that)
+ * using memcpy().  But we do allow space for such alignment,
+ * to allow optimizations of layout and copying.
+ */
+
+#define TOTAL_FPREGS_SIZE						\
+  	(4 + XTENSA_CPE_LTABLE_SIZE + XTENSA_CP_EXTRA_SIZE)
+#define ELF_NFPREG							\
+	((TOTAL_FPREGS_SIZE + sizeof(elf_fpreg_t) - 1) / sizeof(elf_fpreg_t))
+
+typedef unsigned int elf_fpreg_t;
+typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
+
+#define ELF_CORE_COPY_REGS(_eregs, _pregs) 				\
+	xtensa_elf_core_copy_regs (&_eregs, _pregs);
+
+extern void xtensa_elf_core_copy_regs (xtensa_gregset_t *, struct pt_regs *);
+
+/*
+ * This is used to ensure we don't load something for the wrong architecture.
+ */
+
+#define elf_check_arch(x) ( ( (x)->e_machine == EM_XTENSA )  || \
+			    ( (x)->e_machine == EM_XTENSA_OLD ) )
+
+/*
+ * These are used to set parameters in the core dumps.
+ */
+
+#ifdef __XTENSA_EL__
+# define ELF_DATA	ELFDATA2LSB
+#elif defined(__XTENSA_EB__)
+# define ELF_DATA	ELFDATA2MSB
+#else
+# error processor byte order undefined!
+#endif
+
+#define ELF_CLASS	ELFCLASS32
+#define ELF_ARCH	EM_XTENSA
+
+#define USE_ELF_CORE_DUMP
+#define ELF_EXEC_PAGESIZE	PAGE_SIZE
+
+/*
+ * This is the location that an ET_DYN program is loaded if exec'ed.  Typical
+ * use of this is to invoke "./ld.so someprog" to test out a new version of
+ * the loader.  We need to make sure that it is out of the way of the program
+ * that it will "exec", and that there is sufficient room for the brk.
+ */
+
+#define ELF_ET_DYN_BASE         (2 * TASK_SIZE / 3)
+
+/*
+ * This yields a mask that user programs can use to figure out what
+ * instruction set this CPU supports.  This could be done in user space,
+ * but it's not easy, and we've already done it here.
+ */
+
+#define ELF_HWCAP	(0)
+
+/*
+ * This yields a string that ld.so will use to load implementation
+ * specific libraries for optimization.  This is more specific in
+ * intent than poking at uname or /proc/cpuinfo.
+ * For the moment, we have only optimizations for the Intel generations,
+ * but that could change...
+ */
+
+#define ELF_PLATFORM  (NULL)
+
+/*
+ * The Xtensa processor ABI says that when the program starts, a2
+ * contains a pointer to a function which might be registered using
+ * `atexit'.  This provides a mean for the dynamic linker to call
+ * DT_FINI functions for shared libraries that have been loaded before
+ * the code runs.
+ *
+ * A value of 0 tells we have no such handler.
+ *
+ * We might as well make sure everything else is cleared too (except
+ * for the stack pointer in a1), just to make things more
+ * deterministic.  Also, clearing a0 terminates debugger backtraces.
+ */
+
+#define ELF_PLAT_INIT(_r, load_addr) \
+  do { _r->areg[0]=0; /*_r->areg[1]=0;*/ _r->areg[2]=0;  _r->areg[3]=0;  \
+       _r->areg[4]=0;  _r->areg[5]=0;    _r->areg[6]=0;  _r->areg[7]=0;  \
+       _r->areg[8]=0;  _r->areg[9]=0;    _r->areg[10]=0; _r->areg[11]=0; \
+       _r->areg[12]=0; _r->areg[13]=0;   _r->areg[14]=0; _r->areg[15]=0; \
+  } while (0)
+
+#ifdef __KERNEL__
+
+#define SET_PERSONALITY(ex, ibcs2) set_personality(PER_LINUX_32BIT)
+
+extern void do_copy_regs (xtensa_gregset_t*, struct pt_regs*,
+			  struct task_struct*);
+extern void do_restore_regs (xtensa_gregset_t*, struct pt_regs*,
+			     struct task_struct*);
+extern void do_save_fpregs (elf_fpregset_t*, struct pt_regs*,
+			    struct task_struct*);
+extern int do_restore_fpregs (elf_fpregset_t*, struct pt_regs*,
+			      struct task_struct*);
+
+#endif	/* __KERNEL__ */
+#endif	/* _XTENSA_ELF_H */
diff --git a/include/asm-xtensa/emergency-restart.h b/include/asm-xtensa/emergency-restart.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/emergency-restart.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_EMERGENCY_RESTART_H
+#define _ASM_EMERGENCY_RESTART_H
+
+#include <asm-generic/emergency-restart.h>
+
+#endif /* _ASM_EMERGENCY_RESTART_H */
diff --git a/include/asm-xtensa/errno.h b/include/asm-xtensa/errno.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/errno.h
@@ -0,0 +1,16 @@
+/*
+ * include/asm-xtensa/errno.h
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file "COPYING" in the main directory of
+ * this archive for more details.
+ *
+ * Copyright (C) 2002 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_ERRNO_H
+#define _XTENSA_ERRNO_H
+
+#include <asm-generic/errno.h>
+
+#endif	/* _XTENSA_ERRNO_H */
diff --git a/include/asm-xtensa/fcntl.h b/include/asm-xtensa/fcntl.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/fcntl.h
@@ -0,0 +1,101 @@
+/*
+ * include/asm-xtensa/fcntl.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995, 1996, 1997, 1998 by Ralf Baechle
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_FCNTL_H
+#define _XTENSA_FCNTL_H
+
+/* open/fcntl - O_SYNC is only implemented on blocks devices and on files
+   located on an ext2 file system */
+#define O_ACCMODE	0x0003
+#define O_RDONLY	0x0000
+#define O_WRONLY	0x0001
+#define O_RDWR		0x0002
+#define O_APPEND	0x0008
+#define O_SYNC		0x0010
+#define O_NONBLOCK	0x0080
+#define O_CREAT         0x0100	/* not fcntl */
+#define O_TRUNC		0x0200	/* not fcntl */
+#define O_EXCL		0x0400	/* not fcntl */
+#define O_NOCTTY	0x0800	/* not fcntl */
+#define FASYNC		0x1000	/* fcntl, for BSD compatibility */
+#define O_LARGEFILE	0x2000	/* allow large file opens - currently ignored */
+#define O_DIRECT	0x8000	/* direct disk access hint - currently ignored*/
+#define O_DIRECTORY	0x10000	/* must be a directory */
+#define O_NOFOLLOW	0x20000	/* don't follow links */
+#define O_NOATIME	0x100000
+
+#define O_NDELAY	O_NONBLOCK
+
+#define F_DUPFD		0	/* dup */
+#define F_GETFD		1	/* get close_on_exec */
+#define F_SETFD		2	/* set/clear close_on_exec */
+#define F_GETFL		3	/* get file->f_flags */
+#define F_SETFL		4	/* set file->f_flags */
+#define F_GETLK		14
+#define F_GETLK64       15
+#define F_SETLK		6
+#define F_SETLKW	7
+#define F_SETLK64       16
+#define F_SETLKW64      17
+
+#define F_SETOWN	24	/*  for sockets. */
+#define F_GETOWN	23	/*  for sockets. */
+#define F_SETSIG	10	/*  for sockets. */
+#define F_GETSIG	11	/*  for sockets. */
+
+/* for F_[GET|SET]FL */
+#define FD_CLOEXEC	1	/* actually anything with low bit set goes */
+
+/* for posix fcntl() and lockf() */
+#define F_RDLCK		0
+#define F_WRLCK		1
+#define F_UNLCK		2
+
+/* for old implementation of bsd flock () */
+#define F_EXLCK		4	/* or 3 */
+#define F_SHLCK		8	/* or 4 */
+
+/* for leases */
+#define F_INPROGRESS	16
+
+/* operations for bsd flock(), also used by the kernel implementation */
+#define LOCK_SH		1	/* shared lock */
+#define LOCK_EX		2	/* exclusive lock */
+#define LOCK_NB		4	/* or'd with one of the above to prevent
+				   blocking */
+#define LOCK_UN		8	/* remove lock */
+
+#define LOCK_MAND	32	/* This is a mandatory flock ... */
+#define LOCK_READ	64	/*  which allows concurrent read operations */
+#define LOCK_WRITE	128	/*  which allows concurrent write operations */
+#define LOCK_RW		192	/*  which allows concurrent read & write ops */
+
+typedef struct flock {
+	short l_type;
+	short l_whence;
+	__kernel_off_t l_start;
+	__kernel_off_t l_len;
+	long  l_sysid;
+	__kernel_pid_t l_pid;
+	long  pad[4];
+} flock_t;
+
+struct flock64 {
+	short  l_type;
+	short  l_whence;
+	__kernel_off_t l_start;
+	__kernel_off_t l_len;
+	pid_t  l_pid;
+};
+
+#define F_LINUX_SPECIFIC_BASE	1024
+
+#endif /* _XTENSA_FCNTL_H */
diff --git a/include/asm-xtensa/fixmap.h b/include/asm-xtensa/fixmap.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/fixmap.h
@@ -0,0 +1,252 @@
+/*
+ * include/asm-xtensa/fixmap.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_FIXMAP_H
+#define _XTENSA_FIXMAP_H
+
+#include <asm/processor.h>
+
+#ifdef CONFIG_MMU
+
+/*
+ * Here we define all the compile-time virtual addresses.
+ */
+
+#if XCHAL_SEG_MAPPABLE_VADDR != 0
+# error "Current port requires virtual user space starting at 0"
+#endif
+#if XCHAL_SEG_MAPPABLE_SIZE < 0x80000000
+# error "Current port requires at least 0x8000000 bytes for user space"
+#endif
+
+/* Verify instruction/data ram/rom and xlmi don't overlay vmalloc space. */
+
+#define __IN_VMALLOC(addr)						\
+	(((addr) >= VMALLOC_START) && ((addr) < VMALLOC_END))
+#define __SPAN_VMALLOC(start,end)					\
+	(((start) < VMALLOC_START) && ((end) >= VMALLOC_END))
+#define INSIDE_VMALLOC(start,end) 					\
+	(__IN_VMALLOC((start)) || __IN_VMALLOC(end) || __SPAN_VMALLOC((start),(end)))
+
+#if XCHAL_NUM_INSTROM
+# if XCHAL_NUM_INSTROM == 1
+#  if INSIDE_VMALLOC(XCHAL_INSTROM0_VADDR,XCHAL_INSTROM0_VADDR+XCHAL_INSTROM0_SIZE)
+#   error vmalloc range conflicts with instrom0
+#  endif
+# endif
+# if XCHAL_NUM_INSTROM == 2
+#  if INSIDE_VMALLOC(XCHAL_INSTROM1_VADDR,XCHAL_INSTROM1_VADDR+XCHAL_INSTROM1_SIZE)
+#   error vmalloc range conflicts with instrom1
+#  endif
+# endif
+#endif
+
+#if XCHAL_NUM_INSTRAM
+# if XCHAL_NUM_INSTRAM == 1
+#  if INSIDE_VMALLOC(XCHAL_INSTRAM0_VADDR,XCHAL_INSTRAM0_VADDR+XCHAL_INSTRAM0_SIZE)
+#   error vmalloc range conflicts with instram0
+#  endif
+# endif
+# if XCHAL_NUM_INSTRAM == 2
+#  if INSIDE_VMALLOC(XCHAL_INSTRAM1_VADDR,XCHAL_INSTRAM1_VADDR+XCHAL_INSTRAM1_SIZE)
+#   error vmalloc range conflicts with instram1
+#  endif
+# endif
+#endif
+
+#if XCHAL_NUM_DATAROM
+# if XCHAL_NUM_DATAROM == 1
+#  if INSIDE_VMALLOC(XCHAL_DATAROM0_VADDR,XCHAL_DATAROM0_VADDR+XCHAL_DATAROM0_SIZE)
+#   error vmalloc range conflicts with datarom0
+#  endif
+# endif
+# if XCHAL_NUM_DATAROM == 2
+#  if INSIDE_VMALLOC(XCHAL_DATAROM1_VADDR,XCHAL_DATAROM1_VADDR+XCHAL_DATAROM1_SIZE)
+#   error vmalloc range conflicts with datarom1
+#  endif
+# endif
+#endif
+
+#if XCHAL_NUM_DATARAM
+# if XCHAL_NUM_DATARAM == 1
+#  if INSIDE_VMALLOC(XCHAL_DATARAM0_VADDR,XCHAL_DATARAM0_VADDR+XCHAL_DATARAM0_SIZE)
+#   error vmalloc range conflicts with dataram0
+#  endif
+# endif
+# if XCHAL_NUM_DATARAM == 2
+#  if INSIDE_VMALLOC(XCHAL_DATARAM1_VADDR,XCHAL_DATARAM1_VADDR+XCHAL_DATARAM1_SIZE)
+#   error vmalloc range conflicts with dataram1
+#  endif
+# endif
+#endif
+
+#if XCHAL_NUM_XLMI
+# if XCHAL_NUM_XLMI == 1
+#  if INSIDE_VMALLOC(XCHAL_XLMI0_VADDR,XCHAL_XLMI0_VADDR+XCHAL_XLMI0_SIZE)
+#   error vmalloc range conflicts with xlmi0
+#  endif
+# endif
+# if XCHAL_NUM_XLMI == 2
+#  if INSIDE_VMALLOC(XCHAL_XLMI1_VADDR,XCHAL_XLMI1_VADDR+XCHAL_XLMI1_SIZE)
+#   error vmalloc range conflicts with xlmi1
+#  endif
+# endif
+#endif
+
+#if (XCHAL_NUM_INSTROM > 2) || \
+    (XCHAL_NUM_INSTRAM > 2) || \
+    (XCHAL_NUM_DATARAM > 2) || \
+    (XCHAL_NUM_DATAROM > 2) || \
+    (XCHAL_NUM_XLMI    > 2)
+# error Insufficient checks on vmalloc above for more than 2 devices
+#endif
+
+/*
+ * USER_VM_SIZE does not necessarily equal TASK_SIZE.  We bumped
+ * TASK_SIZE down to 0x4000000 to simplify the handling of windowed
+ * call instructions (currently limited to a range of 1 GByte).  User
+ * tasks may very well reclaim the VM space from 0x40000000 to
+ * 0x7fffffff in the future, so we do not want the kernel becoming
+ * accustomed to having any of its stuff (e.g., page tables) in this
+ * region.  This VM region is no-man's land for now.
+ */
+
+#define USER_VM_START		XCHAL_SEG_MAPPABLE_VADDR
+#define USER_VM_SIZE		0x80000000
+
+/*  Size of page table:  */
+
+#define PGTABLE_SIZE_BITS	(32 - XCHAL_MMU_MIN_PTE_PAGE_SIZE + 2)
+#define PGTABLE_SIZE		(1L << PGTABLE_SIZE_BITS)
+
+/*  All kernel-mappable space:  */
+
+#define KERNEL_ALLMAP_START	(USER_VM_START + USER_VM_SIZE)
+#define KERNEL_ALLMAP_SIZE	(XCHAL_SEG_MAPPABLE_SIZE - KERNEL_ALLMAP_START)
+
+/*  Carve out page table at start of kernel-mappable area:  */
+
+#if KERNEL_ALLMAP_SIZE < PGTABLE_SIZE
+#error "Gimme some space for page table!"
+#endif
+#define PGTABLE_START		KERNEL_ALLMAP_START
+
+/*  Remaining kernel-mappable space:  */
+
+#define KERNEL_MAPPED_START	(KERNEL_ALLMAP_START + PGTABLE_SIZE)
+#define KERNEL_MAPPED_SIZE	(KERNEL_ALLMAP_SIZE - PGTABLE_SIZE)
+
+#if KERNEL_MAPPED_SIZE < 0x01000000	/* 16 MB is arbitrary for now */
+# error "Shouldn't the kernel have at least *some* mappable space?"
+#endif
+
+#define MAX_LOW_MEMORY		XCHAL_KSEG_CACHED_SIZE
+
+#endif
+
+/*
+ *  Some constants used elsewhere, but perhaps only in Xtensa header
+ *  files, so maybe we can get rid of some and access compile-time HAL
+ *  directly...
+ *
+ *  Note:  We assume that system RAM is located at the very start of the
+ *  	   kernel segments !!
+ */
+#define KERNEL_VM_LOW           XCHAL_KSEG_CACHED_VADDR
+#define KERNEL_VM_HIGH          XCHAL_KSEG_BYPASS_VADDR
+#define KERNEL_SPACE            XCHAL_KSEG_CACHED_VADDR
+
+/*
+ * Returns the physical/virtual addresses of the kernel space
+ * (works with the cached kernel segment only, which is the
+ *  one normally used for kernel operation).
+ */
+
+/*			PHYSICAL	BYPASS		CACHED
+ *
+ *  bypass vaddr	bypass paddr	*		cached vaddr
+ *  cached vaddr	cached paddr	bypass vaddr	*
+ *  bypass paddr	*		bypass vaddr	cached vaddr
+ *  cached paddr	*		bypass vaddr	cached vaddr
+ *  other		*		*		*
+ */
+
+#define PHYSADDR(a)							      \
+(((unsigned)(a) >= XCHAL_KSEG_BYPASS_VADDR				      \
+  && (unsigned)(a) < XCHAL_KSEG_BYPASS_VADDR + XCHAL_KSEG_BYPASS_SIZE) ?      \
+    (unsigned)(a) - XCHAL_KSEG_BYPASS_VADDR + XCHAL_KSEG_BYPASS_PADDR :       \
+    ((unsigned)(a) >= XCHAL_KSEG_CACHED_VADDR				      \
+     && (unsigned)(a) < XCHAL_KSEG_CACHED_VADDR + XCHAL_KSEG_CACHED_SIZE) ?   \
+        (unsigned)(a) - XCHAL_KSEG_CACHED_VADDR + XCHAL_KSEG_CACHED_PADDR :   \
+	(unsigned)(a))
+
+#define BYPASS_ADDR(a)							      \
+(((unsigned)(a) >= XCHAL_KSEG_BYPASS_PADDR				      \
+  && (unsigned)(a) < XCHAL_KSEG_BYPASS_PADDR + XCHAL_KSEG_BYPASS_SIZE) ?      \
+    (unsigned)(a) - XCHAL_KSEG_BYPASS_PADDR + XCHAL_KSEG_BYPASS_VADDR :       \
+    ((unsigned)(a) >= XCHAL_KSEG_CACHED_PADDR				      \
+     && (unsigned)(a) < XCHAL_KSEG_CACHED_PADDR + XCHAL_KSEG_CACHED_SIZE) ?   \
+        (unsigned)(a) - XCHAL_KSEG_CACHED_PADDR + XCHAL_KSEG_BYPASS_VADDR :   \
+        ((unsigned)(a) >= XCHAL_KSEG_CACHED_VADDR			      \
+         && (unsigned)(a) < XCHAL_KSEG_CACHED_VADDR+XCHAL_KSEG_CACHED_SIZE)?  \
+            (unsigned)(a) - XCHAL_KSEG_CACHED_VADDR+XCHAL_KSEG_BYPASS_VADDR:  \
+	    (unsigned)(a))
+
+#define CACHED_ADDR(a)							      \
+(((unsigned)(a) >= XCHAL_KSEG_BYPASS_PADDR				      \
+  && (unsigned)(a) < XCHAL_KSEG_BYPASS_PADDR + XCHAL_KSEG_BYPASS_SIZE) ?      \
+    (unsigned)(a) - XCHAL_KSEG_BYPASS_PADDR + XCHAL_KSEG_CACHED_VADDR :       \
+    ((unsigned)(a) >= XCHAL_KSEG_CACHED_PADDR			              \
+     && (unsigned)(a) < XCHAL_KSEG_CACHED_PADDR + XCHAL_KSEG_CACHED_SIZE) ?   \
+        (unsigned)(a) - XCHAL_KSEG_CACHED_PADDR + XCHAL_KSEG_CACHED_VADDR :   \
+        ((unsigned)(a) >= XCHAL_KSEG_BYPASS_VADDR			      \
+         && (unsigned)(a) < XCHAL_KSEG_BYPASS_VADDR+XCHAL_KSEG_BYPASS_SIZE) ? \
+            (unsigned)(a) - XCHAL_KSEG_BYPASS_VADDR+XCHAL_KSEG_CACHED_VADDR : \
+	    (unsigned)(a))
+
+#define PHYSADDR_IO(a)							      \
+(((unsigned)(a) >= XCHAL_KIO_BYPASS_VADDR				      \
+  && (unsigned)(a) < XCHAL_KIO_BYPASS_VADDR + XCHAL_KIO_BYPASS_SIZE) ?	      \
+    (unsigned)(a) - XCHAL_KIO_BYPASS_VADDR + XCHAL_KIO_BYPASS_PADDR :	      \
+    ((unsigned)(a) >= XCHAL_KIO_CACHED_VADDR				      \
+     && (unsigned)(a) < XCHAL_KIO_CACHED_VADDR + XCHAL_KIO_CACHED_SIZE) ?     \
+        (unsigned)(a) - XCHAL_KIO_CACHED_VADDR + XCHAL_KIO_CACHED_PADDR :     \
+	(unsigned)(a))
+
+#define BYPASS_ADDR_IO(a)						      \
+(((unsigned)(a) >= XCHAL_KIO_BYPASS_PADDR				      \
+  && (unsigned)(a) < XCHAL_KIO_BYPASS_PADDR + XCHAL_KIO_BYPASS_SIZE) ?	      \
+    (unsigned)(a) - XCHAL_KIO_BYPASS_PADDR + XCHAL_KIO_BYPASS_VADDR :	      \
+    ((unsigned)(a) >= XCHAL_KIO_CACHED_PADDR				      \
+     && (unsigned)(a) < XCHAL_KIO_CACHED_PADDR + XCHAL_KIO_CACHED_SIZE) ?     \
+        (unsigned)(a) - XCHAL_KIO_CACHED_PADDR + XCHAL_KIO_BYPASS_VADDR :     \
+        ((unsigned)(a) >= XCHAL_KIO_CACHED_VADDR			      \
+         && (unsigned)(a) < XCHAL_KIO_CACHED_VADDR + XCHAL_KIO_CACHED_SIZE) ? \
+            (unsigned)(a) - XCHAL_KIO_CACHED_VADDR + XCHAL_KIO_BYPASS_VADDR : \
+	    (unsigned)(a))
+
+#define CACHED_ADDR_IO(a)						      \
+(((unsigned)(a) >= XCHAL_KIO_BYPASS_PADDR				      \
+  && (unsigned)(a) < XCHAL_KIO_BYPASS_PADDR + XCHAL_KIO_BYPASS_SIZE) ?	      \
+    (unsigned)(a) - XCHAL_KIO_BYPASS_PADDR + XCHAL_KIO_CACHED_VADDR :	      \
+    ((unsigned)(a) >= XCHAL_KIO_CACHED_PADDR				      \
+     && (unsigned)(a) < XCHAL_KIO_CACHED_PADDR + XCHAL_KIO_CACHED_SIZE) ?     \
+        (unsigned)(a) - XCHAL_KIO_CACHED_PADDR + XCHAL_KIO_CACHED_VADDR :     \
+        ((unsigned)(a) >= XCHAL_KIO_BYPASS_VADDR			      \
+         && (unsigned)(a) < XCHAL_KIO_BYPASS_VADDR + XCHAL_KIO_BYPASS_SIZE) ? \
+            (unsigned)(a) - XCHAL_KIO_BYPASS_VADDR + XCHAL_KIO_CACHED_VADDR : \
+	    (unsigned)(a))
+
+#endif /* _XTENSA_ADDRSPACE_H */
+
+
+
+
+
diff --git a/include/asm-xtensa/hardirq.h b/include/asm-xtensa/hardirq.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/hardirq.h
@@ -0,0 +1,28 @@
+/*
+ * include/asm-xtensa/hardirq.h
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file "COPYING" in the main directory of
+ * this archive for more details.
+ *
+ * Copyright (C) 2002 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_HARDIRQ_H
+#define _XTENSA_HARDIRQ_H
+
+#include <linux/config.h>
+#include <linux/cache.h>
+#include <asm/irq.h>
+
+/* headers.S is sensitive to the offsets of these fields */
+typedef struct {
+	unsigned int __softirq_pending;
+	unsigned int __syscall_count;
+	struct task_struct * __ksoftirqd_task; /* waitqueue is too large */
+	unsigned int __nmi_count;	       /* arch dependent */
+} ____cacheline_aligned irq_cpustat_t;
+
+#include <linux/irq_cpustat.h>	/* Standard mappings for irq_cpustat_t above */
+
+#endif	/* _XTENSA_HARDIRQ_H */
diff --git a/include/asm-xtensa/hdreg.h b/include/asm-xtensa/hdreg.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/hdreg.h
@@ -0,0 +1,17 @@
+/*
+ * include/asm-xtensa/hdreg.h
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file "COPYING" in the main directory of
+ * this archive for more details.
+ *
+ * Copyright (C) 2002 - 2005 Tensilica Inc.
+ * Copyright (C) 1994-1996  Linus Torvalds & authors
+ */
+
+#ifndef _XTENSA_HDREG_H
+#define _XTENSA_HDREG_H
+
+typedef unsigned int ide_ioreg_t;
+
+#endif
diff --git a/include/asm-xtensa/highmem.h b/include/asm-xtensa/highmem.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/highmem.h
@@ -0,0 +1,17 @@
+/*
+ * include/asm-xtensa/highmem.h
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file "COPYING" in the main directory of
+ * this archive for more details.
+ *
+ * Copyright (C) 2003 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_HIGHMEM_H
+#define _XTENSA_HIGHMEM_H
+
+extern void flush_cache_kmaps(void);
+
+#endif
+
diff --git a/include/asm-xtensa/hw_irq.h b/include/asm-xtensa/hw_irq.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/hw_irq.h
@@ -0,0 +1,18 @@
+/*
+ * include/asm-xtensa/hw_irq.h
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file "COPYING" in the main directory of
+ * this archive for more details.
+ *
+ * Copyright (C) 2002 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_HW_IRQ_H
+#define _XTENSA_HW_IRQ_H
+
+static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i)
+{
+}
+
+#endif
diff --git a/include/asm-xtensa/ide.h b/include/asm-xtensa/ide.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/ide.h
@@ -0,0 +1,36 @@
+/*
+ * include/asm-xtensa/ide.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994 - 1996  Linus Torvalds & authors
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_IDE_H
+#define _XTENSA_IDE_H
+
+#ifdef __KERNEL__
+
+#include <linux/config.h>
+
+#ifndef MAX_HWIFS
+# define MAX_HWIFS	1
+#endif
+
+static __inline__ int ide_default_irq(unsigned long base)
+{
+	/* Unsupported! */
+  	return 0;
+}
+
+static __inline__ unsigned long ide_default_io_base(int index)
+{
+	/* Unsupported! */
+  	return 0;
+}
+
+#endif	/* __KERNEL__ */
+#endif	/* _XTENSA_IDE_H */
diff --git a/include/asm-xtensa/io.h b/include/asm-xtensa/io.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/io.h
@@ -0,0 +1,197 @@
+/*
+ * linux/include/asm-xtensa/io.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_IO_H
+#define _XTENSA_IO_H
+
+#ifdef __KERNEL__
+#include <linux/config.h>
+#include <asm/byteorder.h>
+
+#include <linux/types.h>
+#include <asm/fixmap.h>
+
+#define _IO_BASE 0
+
+
+/*
+ * swap functions to change byte order from little-endian to big-endian and
+ * vice versa.
+ */
+
+static inline unsigned short _swapw (unsigned short v)
+{
+	return (v << 8) | (v >> 8);
+}
+
+static inline unsigned int _swapl (unsigned int v)
+{
+	return (v << 24) | ((v & 0xff00) << 8) | ((v >> 8) & 0xff00) | (v >> 24);
+}
+
+/*
+ * Change virtual addresses to physical addresses and vv.
+ * These are trivial on the 1:1 Linux/Xtensa mapping
+ */
+
+extern inline unsigned long virt_to_phys(volatile void * address)
+{
+	return PHYSADDR((unsigned long)address);
+}
+
+extern inline void * phys_to_virt(unsigned long address)
+{
+	return (void*) CACHED_ADDR(address);
+}
+
+/*
+ * IO bus memory addresses are also 1:1 with the physical address
+ */
+
+extern inline unsigned long virt_to_bus(volatile void * address)
+{
+	return PHYSADDR((unsigned long)address);
+}
+
+extern inline void * bus_to_virt (unsigned long address)
+{
+	return (void *) CACHED_ADDR(address);
+}
+
+/*
+ * Change "struct page" to physical address.
+ */
+
+extern inline void *ioremap(unsigned long offset, unsigned long size)
+{
+        return (void *) CACHED_ADDR_IO(offset);
+}
+
+extern inline void *ioremap_nocache(unsigned long offset, unsigned long size)
+{
+        return (void *) BYPASS_ADDR_IO(offset);
+}
+
+extern inline void iounmap(void *addr)
+{
+}
+
+/*
+ * Generic I/O
+ */
+
+#define readb(addr) \
+	({ unsigned char __v = (*(volatile unsigned char *)(addr)); __v; })
+#define readw(addr) \
+	({ unsigned short __v = (*(volatile unsigned short *)(addr)); __v; })
+#define readl(addr) \
+	({ unsigned int __v = (*(volatile unsigned int *)(addr)); __v; })
+#define writeb(b, addr) (void)((*(volatile unsigned char *)(addr)) = (b))
+#define writew(b, addr) (void)((*(volatile unsigned short *)(addr)) = (b))
+#define writel(b, addr) (void)((*(volatile unsigned int *)(addr)) = (b))
+
+static inline __u8 __raw_readb(const volatile void __iomem *addr)
+{
+          return *(__force volatile __u8 *)(addr);
+}
+static inline __u16 __raw_readw(const volatile void __iomem *addr)
+{
+          return *(__force volatile __u16 *)(addr);
+}
+static inline __u32 __raw_readl(const volatile void __iomem *addr)
+{
+          return *(__force volatile __u32 *)(addr);
+}
+static inline void __raw_writeb(__u8 b, volatile void __iomem *addr)
+{
+          *(__force volatile __u8 *)(addr) = b;
+}
+static inline void __raw_writew(__u16 b, volatile void __iomem *addr)
+{
+          *(__force volatile __u16 *)(addr) = b;
+}
+static inline void __raw_writel(__u32 b, volatile void __iomem *addr)
+{
+          *(__force volatile __u32 *)(addr) = b;
+}
+
+
+
+
+/* These are the definitions for the x86 IO instructions
+ * inb/inw/inl/outb/outw/outl, the "string" versions
+ * insb/insw/insl/outsb/outsw/outsl, and the "pausing" versions
+ * inb_p/inw_p/...
+ * The macros don't do byte-swapping.
+ */
+
+#define inb(port)		readb((u8 *)((port)+_IO_BASE))
+#define outb(val, port)		writeb((val),(u8 *)((unsigned long)(port)+_IO_BASE))
+#define inw(port)		readw((u16 *)((port)+_IO_BASE))
+#define outw(val, port)		writew((val),(u16 *)((unsigned long)(port)+_IO_BASE))
+#define inl(port)		readl((u32 *)((port)+_IO_BASE))
+#define outl(val, port)		writel((val),(u32 *)((unsigned long)(port)))
+
+#define inb_p(port)		inb((port))
+#define outb_p(val, port)	outb((val), (port))
+#define inw_p(port)		inw((port))
+#define outw_p(val, port)	outw((val), (port))
+#define inl_p(port)		inl((port))
+#define outl_p(val, port)	outl((val), (port))
+
+extern void insb (unsigned long port, void *dst, unsigned long count);
+extern void insw (unsigned long port, void *dst, unsigned long count);
+extern void insl (unsigned long port, void *dst, unsigned long count);
+extern void outsb (unsigned long port, const void *src, unsigned long count);
+extern void outsw (unsigned long port, const void *src, unsigned long count);
+extern void outsl (unsigned long port, const void *src, unsigned long count);
+
+#define IO_SPACE_LIMIT ~0
+
+#define memset_io(a,b,c)       memset((void *)(a),(b),(c))
+#define memcpy_fromio(a,b,c)   memcpy((a),(void *)(b),(c))
+#define memcpy_toio(a,b,c)      memcpy((void *)(a),(b),(c))
+
+/* At this point the Xtensa doesn't provide byte swap instructions */
+
+#ifdef __XTENSA_EB__
+# define in_8(addr) (*(u8*)(addr))
+# define in_le16(addr) _swapw(*(u16*)(addr))
+# define in_le32(addr) _swapl(*(u32*)(addr))
+# define out_8(b, addr) *(u8*)(addr) = (b)
+# define out_le16(b, addr) *(u16*)(addr) = _swapw(b)
+# define out_le32(b, addr) *(u32*)(addr) = _swapl(b)
+#elif defined(__XTENSA_EL__)
+# define in_8(addr)  (*(u8*)(addr))
+# define in_le16(addr) (*(u16*)(addr))
+# define in_le32(addr) (*(u32*)(addr))
+# define out_8(b, addr) *(u8*)(addr) = (b)
+# define out_le16(b, addr) *(u16*)(addr) = (b)
+# define out_le32(b, addr) *(u32*)(addr) = (b)
+#else
+# error processor byte order undefined!
+#endif
+
+
+/*
+ *  * Convert a physical pointer to a virtual kernel pointer for /dev/mem
+ *   * access
+ *    */
+#define xlate_dev_mem_ptr(p)    __va(p)
+
+/*
+ *  * Convert a virtual cached pointer to an uncached pointer
+ *   */
+#define xlate_dev_kmem_ptr(p)   p
+
+
+#endif	/* __KERNEL__ */
+
+#endif	/* _XTENSA_IO_H */
diff --git a/include/asm-xtensa/ioctl.h b/include/asm-xtensa/ioctl.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/ioctl.h
@@ -0,0 +1,83 @@
+/*
+ * include/asm-xtensa/ioctl.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2003 - 2005 Tensilica Inc.
+ *
+ * Derived from "include/asm-i386/ioctl.h"
+ */
+
+#ifndef _XTENSA_IOCTL_H
+#define _XTENSA_IOCTL_H
+
+
+/* ioctl command encoding: 32 bits total, command in lower 16 bits,
+ * size of the parameter structure in the lower 14 bits of the
+ * upper 16 bits.
+ * Encoding the size of the parameter structure in the ioctl request
+ * is useful for catching programs compiled with old versions
+ * and to avoid overwriting user space outside the user buffer area.
+ * The highest 2 bits are reserved for indicating the ``access mode''.
+ * NOTE: This limits the max parameter size to 16kB -1 !
+ */
+
+/*
+ * The following is for compatibility across the various Linux
+ * platforms.  The i386 ioctl numbering scheme doesn't really enforce
+ * a type field.  De facto, however, the top 8 bits of the lower 16
+ * bits are indeed used as a type field, so we might just as well make
+ * this explicit here.  Please be sure to use the decoding macros
+ * below from now on.
+ */
+#define _IOC_NRBITS	8
+#define _IOC_TYPEBITS	8
+#define _IOC_SIZEBITS	14
+#define _IOC_DIRBITS	2
+
+#define _IOC_NRMASK	((1 << _IOC_NRBITS)-1)
+#define _IOC_TYPEMASK	((1 << _IOC_TYPEBITS)-1)
+#define _IOC_SIZEMASK	((1 << _IOC_SIZEBITS)-1)
+#define _IOC_DIRMASK	((1 << _IOC_DIRBITS)-1)
+
+#define _IOC_NRSHIFT	0
+#define _IOC_TYPESHIFT	(_IOC_NRSHIFT+_IOC_NRBITS)
+#define _IOC_SIZESHIFT	(_IOC_TYPESHIFT+_IOC_TYPEBITS)
+#define _IOC_DIRSHIFT	(_IOC_SIZESHIFT+_IOC_SIZEBITS)
+
+/*
+ * Direction bits.
+ */
+#define _IOC_NONE	0U
+#define _IOC_WRITE	1U
+#define _IOC_READ	2U
+
+#define _IOC(dir,type,nr,size) \
+	(((dir)  << _IOC_DIRSHIFT) | \
+	 ((type) << _IOC_TYPESHIFT) | \
+	 ((nr)   << _IOC_NRSHIFT) | \
+	 ((size) << _IOC_SIZESHIFT))
+
+/* used to create numbers */
+#define _IO(type,nr)		_IOC(_IOC_NONE,(type),(nr),0)
+#define _IOR(type,nr,size)	_IOC(_IOC_READ,(type),(nr),sizeof(size))
+#define _IOW(type,nr,size)	_IOC(_IOC_WRITE,(type),(nr),sizeof(size))
+#define _IOWR(type,nr,size)	_IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
+
+/* used to decode ioctl numbers.. */
+#define _IOC_DIR(nr)		(((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)
+#define _IOC_TYPE(nr)		(((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK)
+#define _IOC_NR(nr)		(((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK)
+#define _IOC_SIZE(nr)		(((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK)
+
+/* ...and for the drivers/sound files... */
+
+#define IOC_IN		(_IOC_WRITE << _IOC_DIRSHIFT)
+#define IOC_OUT		(_IOC_READ << _IOC_DIRSHIFT)
+#define IOC_INOUT	((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT)
+#define IOCSIZE_MASK	(_IOC_SIZEMASK << _IOC_SIZESHIFT)
+#define IOCSIZE_SHIFT	(_IOC_SIZESHIFT)
+
+#endif
diff --git a/include/asm-xtensa/ioctls.h b/include/asm-xtensa/ioctls.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/ioctls.h
@@ -0,0 +1,112 @@
+/*
+ * include/asm-xtensa/ioctl.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2003 - 2005 Tensilica Inc.
+ *
+ * Derived from "include/asm-i386/ioctls.h"
+ */
+
+#ifndef _XTENSA_IOCTLS_H
+#define _XTENSA_IOCTLS_H
+
+#include <asm/ioctl.h>
+
+#define FIOCLEX		_IO('f', 1)
+#define FIONCLEX	_IO('f', 2)
+#define FIOASYNC	_IOW('f', 125, int)
+#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
+#define TCSETSW		0x5403
+#define TCSETSF		0x5404
+
+#define TCGETA		_IOR('t', 23, struct termio)
+#define TCSETA		_IOW('t', 24, struct termio)
+#define TCSETAW		_IOW('t', 25, struct termio)
+#define TCSETAF		_IOW('t', 28, struct termio)
+
+#define TCSBRK		_IO('t', 29)
+#define TCXONC		_IO('t', 30)
+#define TCFLSH		_IO('t', 31)
+
+#define TIOCSWINSZ	_IOW('t', 103, struct winsize)
+#define TIOCGWINSZ	_IOR('t', 104, struct winsize)
+#define	TIOCSTART	_IO('t', 110)		/* start output, like ^Q */
+#define	TIOCSTOP	_IO('t', 111)		/* stop output, like ^S */
+#define TIOCOUTQ        _IOR('t', 115, int)     /* output queue size */
+
+#define TIOCSPGRP	_IOW('t', 118, int)
+#define TIOCGPGRP	_IOR('t', 119, int)
+
+#define TIOCEXCL	_IO('T', 12)
+#define TIOCNXCL	_IO('T', 13)
+#define TIOCSCTTY	_IO('T', 14)
+
+#define TIOCSTI		_IOW('T', 18, char)
+#define TIOCMGET	_IOR('T', 21, unsigned int)
+#define TIOCMBIS	_IOW('T', 22, unsigned int)
+#define TIOCMBIC	_IOW('T', 23, unsigned int)
+#define TIOCMSET	_IOW('T', 24, unsigned int)
+# define TIOCM_LE	0x001
+# define TIOCM_DTR	0x002
+# define TIOCM_RTS	0x004
+# define TIOCM_ST	0x008
+# define TIOCM_SR	0x010
+# define TIOCM_CTS	0x020
+# define TIOCM_CAR	0x040
+# define TIOCM_RNG	0x080
+# define TIOCM_DSR	0x100
+# define TIOCM_CD	TIOCM_CAR
+# define TIOCM_RI	TIOCM_RNG
+
+#define TIOCGSOFTCAR	_IOR('T', 25, unsigned int)
+#define TIOCSSOFTCAR	_IOW('T', 26, unsigned int)
+#define TIOCLINUX	_IOW('T', 28, char)
+#define TIOCCONS	_IO('T', 29)
+#define TIOCGSERIAL	_IOR('T', 30, struct serial_struct)
+#define TIOCSSERIAL	_IOW('T', 31, struct serial_struct)
+#define TIOCPKT		_IOW('T', 32, int)
+# define TIOCPKT_DATA		 0
+# define TIOCPKT_FLUSHREAD	 1
+# define TIOCPKT_FLUSHWRITE	 2
+# define TIOCPKT_STOP		 4
+# define TIOCPKT_START		 8
+# define TIOCPKT_NOSTOP		16
+# define TIOCPKT_DOSTOP		32
+
+
+#define TIOCNOTTY	_IO('T', 34)
+#define TIOCSETD	_IOW('T', 35, int)
+#define TIOCGETD	_IOR('T', 36, int)
+#define TCSBRKP		_IOW('T', 37, int)   /* Needed for POSIX tcsendbreak()*/
+#define TIOCTTYGSTRUCT	_IOR('T', 38, struct tty_struct) /* For debugging only*/
+#define TIOCSBRK	_IO('T', 39) 	     /* BSD compatibility */
+#define TIOCCBRK	_IO('T', 40)	     /* BSD compatibility */
+#define TIOCGSID	_IOR('T', 41, pid_t) /* Return the session ID of FD*/
+#define TIOCGPTN	_IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */
+#define TIOCSPTLCK	_IOW('T',0x31, int)  /* Lock/unlock Pty */
+
+#define TIOCSERCONFIG	_IO('T', 83)
+#define TIOCSERGWILD	_IOR('T', 84,  int)
+#define TIOCSERSWILD	_IOW('T', 85,  int)
+#define TIOCGLCKTRMIOS	0x5456
+#define TIOCSLCKTRMIOS	0x5457
+#define TIOCSERGSTRUCT	0x5458		     /* For debugging only */
+#define TIOCSERGETLSR   _IOR('T', 89, unsigned int) /* Get line status reg. */
+  /* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
+# define TIOCSER_TEMT    0x01		     /* Transmitter physically empty */
+#define TIOCSERGETMULTI _IOR('T', 90, struct serial_multiport_struct) /* Get multiport config  */
+#define TIOCSERSETMULTI _IOW('T', 91, struct serial_multiport_struct) /* Set multiport config */
+
+#define TIOCMIWAIT	_IO('T', 92) /* wait for a change on serial input line(s) */
+#define TIOCGICOUNT	_IOR('T', 93, struct async_icount) /* read serial port inline interrupt counts */
+
+#endif /* _XTENSA_IOCTLS_H */
diff --git a/include/asm-xtensa/ipcbuf.h b/include/asm-xtensa/ipcbuf.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/ipcbuf.h
@@ -0,0 +1,37 @@
+/*
+ * include/asm-xtensa/ipcbuf.h
+ *
+ * The ipc64_perm structure for the Xtensa architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_IPCBUF_H
+#define _XTENSA_IPCBUF_H
+
+/*
+ * Pad space is left for:
+ * - 32-bit mode_t and seq
+ * - 2 miscellaneous 32-bit values
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file "COPYING" in the main directory of
+ * this archive for more details.
+ */
+
+struct ipc64_perm
+{
+	__kernel_key_t		key;
+	__kernel_uid32_t	uid;
+	__kernel_gid32_t	gid;
+	__kernel_uid32_t	cuid;
+	__kernel_gid32_t	cgid;
+	__kernel_mode_t		mode;
+	unsigned long		seq;
+	unsigned long		__unused1;
+	unsigned long		__unused2;
+};
+
+#endif /* _XTENSA_IPCBUF_H */
diff --git a/include/asm-xtensa/irq.h b/include/asm-xtensa/irq.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/irq.h
@@ -0,0 +1,37 @@
+/*
+ * include/asm-xtensa/irq.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_IRQ_H
+#define _XTENSA_IRQ_H
+
+#include <linux/config.h>
+#include <asm/platform/hardware.h>
+
+#include <xtensa/config/core.h>
+
+#ifndef PLATFORM_NR_IRQS
+# define PLATFORM_NR_IRQS 0
+#endif
+#define XTENSA_NR_IRQS XCHAL_NUM_INTERRUPTS
+#define NR_IRQS (XTENSA_NR_IRQS + PLATFORM_NR_IRQS)
+
+static __inline__ int irq_canonicalize(int irq)
+{
+	return (irq);
+}
+
+struct irqaction;
+#if 0 // FIXME
+extern void disable_irq_nosync(unsigned int);
+extern void disable_irq(unsigned int);
+extern void enable_irq(unsigned int);
+#endif
+
+#endif	/* _XTENSA_IRQ_H */
diff --git a/include/asm-xtensa/kmap_types.h b/include/asm-xtensa/kmap_types.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/kmap_types.h
@@ -0,0 +1,31 @@
+/*
+ * include/asm-xtensa/kmap_types.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_KMAP_TYPES_H
+#define _XTENSA_KMAP_TYPES_H
+
+enum km_type {
+  KM_BOUNCE_READ,
+  KM_SKB_SUNRPC_DATA,
+  KM_SKB_DATA_SOFTIRQ,
+  KM_USER0,
+  KM_USER1,
+  KM_BIO_SRC_IRQ,
+  KM_BIO_DST_IRQ,
+  KM_PTE0,
+  KM_PTE1,
+  KM_IRQ0,
+  KM_IRQ1,
+  KM_SOFTIRQ0,
+  KM_SOFTIRQ1,
+  KM_TYPE_NR
+};
+
+#endif	/* _XTENSA_KMAP_TYPES_H */
diff --git a/include/asm-xtensa/linkage.h b/include/asm-xtensa/linkage.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/linkage.h
@@ -0,0 +1,16 @@
+/*
+ * include/asm-xtensa/linkage.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_LINKAGE_H
+#define _XTENSA_LINKAGE_H
+
+/* Nothing to do here ... */
+
+#endif	/* _XTENSA_LINKAGE_H */
diff --git a/include/asm-xtensa/local.h b/include/asm-xtensa/local.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/local.h
@@ -0,0 +1,16 @@
+/*
+ * include/asm-xtensa/local.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_LOCAL_H
+#define _XTENSA_LOCAL_H
+
+#include <asm-generic/local.h>
+
+#endif /* _XTENSA_LOCAL_H */
diff --git a/include/asm-xtensa/mman.h b/include/asm-xtensa/mman.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/mman.h
@@ -0,0 +1,80 @@
+/*
+ * include/asm-xtensa/mman.h
+ *
+ * Xtensa Processor memory-manager definitions
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995 by Ralf Baechle
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_MMAN_H
+#define _XTENSA_MMAN_H
+
+/*
+ * Protections are chosen from these bits, OR'd together.  The
+ * implementation does not necessarily support PROT_EXEC or PROT_WRITE
+ * without PROT_READ.  The only guarantees are that no writing will be
+ * allowed without PROT_WRITE and no access will be allowed for PROT_NONE.
+ */
+
+#define PROT_NONE	0x0		/* page can not be accessed */
+#define PROT_READ	0x1		/* page can be read */
+#define PROT_WRITE	0x2		/* page can be written */
+#define PROT_EXEC	0x4		/* page can be executed */
+
+#define PROT_SEM	0x10		/* page may be used for atomic ops */
+#define PROT_GROWSDOWN	0x01000000	/* mprotect flag: extend change to start of growsdown vma */
+#define PROT_GROWSUP	0x02000000	/* mprotect flag: extend change to end fo growsup vma */
+
+/*
+ * Flags for mmap
+ */
+#define MAP_SHARED	0x001		/* Share changes */
+#define MAP_PRIVATE	0x002		/* Changes are private */
+#define MAP_TYPE	0x00f		/* Mask for type of mapping */
+#define MAP_FIXED	0x010		/* Interpret addr exactly */
+
+/* not used by linux, but here to make sure we don't clash with ABI defines */
+#define MAP_RENAME	0x020		/* Assign page to file */
+#define MAP_AUTOGROW	0x040		/* File may grow by writing */
+#define MAP_LOCAL	0x080		/* Copy on fork/sproc */
+#define MAP_AUTORSRV	0x100		/* Logical swap reserved on demand */
+
+/* These are linux-specific */
+#define MAP_NORESERVE	0x0400		/* don't check for reservations */
+#define MAP_ANONYMOUS	0x0800		/* don't use a file */
+#define MAP_GROWSDOWN	0x1000		/* stack-like segment */
+#define MAP_DENYWRITE	0x2000		/* ETXTBSY */
+#define MAP_EXECUTABLE	0x4000		/* mark it as an executable */
+#define MAP_LOCKED	0x8000		/* pages are locked */
+#define MAP_POPULATE	0x10000		/* populate (prefault) pagetables */
+#define MAP_NONBLOCK	0x20000		/* do not block on IO */
+
+/*
+ * Flags for msync
+ */
+#define MS_ASYNC	0x0001		/* sync memory asynchronously */
+#define MS_INVALIDATE	0x0002		/* invalidate mappings & caches */
+#define MS_SYNC		0x0004		/* synchronous memory sync */
+
+/*
+ * Flags for mlockall
+ */
+#define MCL_CURRENT	1		/* lock all current mappings */
+#define MCL_FUTURE	2		/* lock all future mappings */
+
+#define MADV_NORMAL	0x0		/* default page-in behavior */
+#define MADV_RANDOM	0x1		/* page-in minimum required */
+#define MADV_SEQUENTIAL	0x2		/* read-ahead aggressively */
+#define MADV_WILLNEED	0x3		/* pre-fault pages */
+#define MADV_DONTNEED	0x4		/* discard these pages */
+
+/* compatibility flags */
+#define MAP_ANON       MAP_ANONYMOUS
+#define MAP_FILE       0
+
+#endif /* _XTENSA_MMAN_H */
diff --git a/include/asm-xtensa/mmu.h b/include/asm-xtensa/mmu.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/mmu.h
@@ -0,0 +1,17 @@
+/*
+ * include/asm-xtensa/mmu.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_MMU_H
+#define _XTENSA_MMU_H
+
+/* Default "unsigned long" context */
+typedef unsigned long mm_context_t;
+
+#endif	/* _XTENSA_MMU_H */
diff --git a/include/asm-xtensa/mmu_context.h b/include/asm-xtensa/mmu_context.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/mmu_context.h
@@ -0,0 +1,330 @@
+/*
+ * include/asm-xtensa/mmu_context.h
+ *
+ * Switch an MMU context.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_MMU_CONTEXT_H
+#define _XTENSA_MMU_CONTEXT_H
+
+#include <linux/config.h>
+#include <linux/stringify.h>
+
+#include <asm/pgtable.h>
+#include <asm/mmu_context.h>
+#include <asm/cacheflush.h>
+#include <asm/tlbflush.h>
+
+/*
+ * Linux was ported to Xtensa assuming all auto-refill ways in set 0
+ * had the same properties (a very likely assumption).  Multiple sets
+ * of auto-refill ways will still work properly, but not as optimally
+ * as the Xtensa designer may have assumed.
+ *
+ * We make this case a hard #error, killing the kernel build, to alert
+ * the developer to this condition (which is more likely an error).
+ * You super-duper clever developers can change it to a warning or
+ * remove it altogether if you think you know what you're doing.  :)
+ */
+
+#if (XCHAL_HAVE_TLBS != 1)
+# error "Linux must have an MMU!"
+#endif
+
+#if ((XCHAL_ITLB_ARF_WAYS == 0) || (XCHAL_DTLB_ARF_WAYS == 0))
+# error "MMU must have auto-refill ways"
+#endif
+
+#if ((XCHAL_ITLB_ARF_SETS != 1) || (XCHAL_DTLB_ARF_SETS != 1))
+# error Linux may not use all auto-refill ways as efficiently as you think
+#endif
+
+#if (XCHAL_MMU_MAX_PTE_PAGE_SIZE != XCHAL_MMU_MIN_PTE_PAGE_SIZE)
+# error Only one page size allowed!
+#endif
+
+extern unsigned long asid_cache;
+extern pgd_t *current_pgd;
+
+/*
+ * Define the number of entries per auto-refill way in set 0 of both I and D
+ * TLBs.  We deal only with set 0 here (an assumption further explained in
+ * assertions.h).  Also, define the total number of ARF entries in both TLBs.
+ */
+
+#define ITLB_ENTRIES_PER_ARF_WAY  (XCHAL_ITLB_SET(XCHAL_ITLB_ARF_SET0,ENTRIES))
+#define DTLB_ENTRIES_PER_ARF_WAY  (XCHAL_DTLB_SET(XCHAL_DTLB_ARF_SET0,ENTRIES))
+
+#define ITLB_ENTRIES							\
+ 	(ITLB_ENTRIES_PER_ARF_WAY * (XCHAL_ITLB_SET(XCHAL_ITLB_ARF_SET0,WAYS)))
+#define DTLB_ENTRIES							\
+	(DTLB_ENTRIES_PER_ARF_WAY * (XCHAL_DTLB_SET(XCHAL_DTLB_ARF_SET0,WAYS)))
+
+
+/*
+ * SMALLEST_NTLB_ENTRIES is the smaller of ITLB_ENTRIES and DTLB_ENTRIES.
+ * In practice, they are probably equal.  This macro simplifies function
+ * flush_tlb_range().
+ */
+
+#if (DTLB_ENTRIES < ITLB_ENTRIES)
+# define SMALLEST_NTLB_ENTRIES  DTLB_ENTRIES
+#else
+# define SMALLEST_NTLB_ENTRIES  ITLB_ENTRIES
+#endif
+
+
+/*
+ * asid_cache tracks only the ASID[USER_RING] field of the RASID special
+ * register, which is the current user-task asid allocation value.
+ * mm->context has the same meaning.  When it comes time to write the
+ * asid_cache or mm->context values to the RASID special register, we first
+ * shift the value left by 8, then insert the value.
+ * ASID[0] always contains the kernel's asid value, and we reserve three
+ * other asid values that we never assign to user tasks.
+ */
+
+#define ASID_INC	0x1
+#define ASID_MASK	((1 << XCHAL_MMU_ASID_BITS) - 1)
+
+/*
+ * XCHAL_MMU_ASID_INVALID is a configurable Xtensa processor constant
+ * indicating invalid address space.  XCHAL_MMU_ASID_KERNEL is a configurable
+ * Xtensa processor constant indicating the kernel address space.  They can
+ * be arbitrary values.
+ *
+ * We identify three more unique, reserved ASID values to use in the unused
+ * ring positions.  No other user process will be assigned these reserved
+ * ASID values.
+ *
+ * For example, given that
+ *
+ *	XCHAL_MMU_ASID_INVALID == 0
+ *	XCHAL_MMU_ASID_KERNEL  == 1
+ *
+ * the following maze of #if statements would generate
+ *
+ *	ASID_RESERVED_1        == 2
+ *	ASID_RESERVED_2        == 3
+ *	ASID_RESERVED_3        == 4
+ *	ASID_FIRST_NONRESERVED == 5
+ */
+
+#if (XCHAL_MMU_ASID_INVALID != XCHAL_MMU_ASID_KERNEL + 1)
+# define ASID_RESERVED_1         ((XCHAL_MMU_ASID_KERNEL + 1) & ASID_MASK)
+#else
+# define ASID_RESERVED_1         ((XCHAL_MMU_ASID_KERNEL + 2) & ASID_MASK)
+#endif
+
+#if (XCHAL_MMU_ASID_INVALID != ASID_RESERVED_1 + 1)
+# define ASID_RESERVED_2         ((ASID_RESERVED_1 + 1) & ASID_MASK)
+#else
+# define ASID_RESERVED_2         ((ASID_RESERVED_1 + 2) & ASID_MASK)
+#endif
+
+#if (XCHAL_MMU_ASID_INVALID != ASID_RESERVED_2 + 1)
+# define ASID_RESERVED_3         ((ASID_RESERVED_2 + 1) & ASID_MASK)
+#else
+# define ASID_RESERVED_3         ((ASID_RESERVED_2 + 2) & ASID_MASK)
+#endif
+
+#if (XCHAL_MMU_ASID_INVALID != ASID_RESERVED_3 + 1)
+# define ASID_FIRST_NONRESERVED  ((ASID_RESERVED_3 + 1) & ASID_MASK)
+#else
+# define ASID_FIRST_NONRESERVED  ((ASID_RESERVED_3 + 2) & ASID_MASK)
+#endif
+
+#define ASID_ALL_RESERVED ( ((ASID_RESERVED_1) << 24) + \
+                            ((ASID_RESERVED_2) << 16) + \
+                            ((ASID_RESERVED_3) <<  8) + \
+                            ((XCHAL_MMU_ASID_KERNEL))   )
+
+
+/*
+ * NO_CONTEXT is the invalid ASID value that we don't ever assign to
+ * any user or kernel context.  NO_CONTEXT is a better mnemonic than
+ * XCHAL_MMU_ASID_INVALID, so we use it in code instead.
+ */
+
+#define NO_CONTEXT   XCHAL_MMU_ASID_INVALID
+
+#if (KERNEL_RING != 0)
+# error The KERNEL_RING really should be zero.
+#endif
+
+#if (USER_RING >= XCHAL_MMU_RINGS)
+# error USER_RING cannot be greater than the highest numbered ring.
+#endif
+
+#if (USER_RING == KERNEL_RING)
+# error The user and kernel rings really should not be equal.
+#endif
+
+#if (USER_RING == 1)
+#define ASID_INSERT(x) ( ((ASID_RESERVED_1)   << 24) + \
+                         ((ASID_RESERVED_2)   << 16) + \
+                         (((x) & (ASID_MASK)) <<  8) + \
+                         ((XCHAL_MMU_ASID_KERNEL))   )
+
+#elif (USER_RING == 2)
+#define ASID_INSERT(x) ( ((ASID_RESERVED_1)   << 24) + \
+                         (((x) & (ASID_MASK)) << 16) + \
+                         ((ASID_RESERVED_2)   <<  8) + \
+                         ((XCHAL_MMU_ASID_KERNEL))   )
+
+#elif (USER_RING == 3)
+#define ASID_INSERT(x) ( (((x) & (ASID_MASK)) << 24) + \
+			 ((ASID_RESERVED_1)   << 16) + \
+                         ((ASID_RESERVED_2)   <<  8) + \
+                         ((XCHAL_MMU_ASID_KERNEL))   )
+
+#else
+#error Goofy value for USER_RING
+
+#endif /* USER_RING == 1 */
+
+
+/*
+ *  All unused by hardware upper bits will be considered
+ *  as a software asid extension.
+ */
+
+#define ASID_VERSION_MASK  ((unsigned long)~(ASID_MASK|(ASID_MASK-1)))
+#define ASID_FIRST_VERSION						\
+	((unsigned long)(~ASID_VERSION_MASK) + 1 + ASID_FIRST_NONRESERVED)
+
+extern inline void set_rasid_register (unsigned long val)
+{
+	__asm__ __volatile__ (" wsr %0, "__stringify(RASID)"\n\t"
+			      " isync\n" : : "a" (val));
+}
+
+extern inline unsigned long get_rasid_register (void)
+{
+	unsigned long tmp;
+	__asm__ __volatile__ (" rsr %0, "__stringify(RASID)"\n\t" : "=a" (tmp));
+	return tmp;
+}
+
+
+#if ((XCHAL_MMU_ASID_INVALID == 0) && (XCHAL_MMU_ASID_KERNEL == 1))
+
+extern inline void
+get_new_mmu_context(struct mm_struct *mm, unsigned long asid)
+{
+	extern void flush_tlb_all(void);
+	if (! ((asid += ASID_INC) & ASID_MASK) ) {
+		flush_tlb_all(); /* start new asid cycle */
+		if (!asid)      /* fix version if needed */
+			asid = ASID_FIRST_VERSION - ASID_FIRST_NONRESERVED;
+		asid += ASID_FIRST_NONRESERVED;
+	}
+	mm->context = asid_cache = asid;
+}
+
+#else
+#warning ASID_{INVALID,KERNEL} values impose non-optimal get_new_mmu_context implementation
+
+/* XCHAL_MMU_ASID_INVALID == 0 and XCHAL_MMU_ASID_KERNEL ==1 are
+   really the best, but if you insist... */
+
+extern inline int validate_asid (unsigned long asid)
+{
+	switch (asid) {
+	case XCHAL_MMU_ASID_INVALID:
+	case XCHAL_MMU_ASID_KERNEL:
+	case ASID_RESERVED_1:
+	case ASID_RESERVED_2:
+	case ASID_RESERVED_3:
+		return 0; /* can't use these values as ASIDs */
+	}
+	return 1; /* valid */
+}
+
+extern inline void
+get_new_mmu_context(struct mm_struct *mm, unsigned long asid)
+{
+	extern void flush_tlb_all(void);
+	while (1) {
+		asid += ASID_INC;
+		if ( ! (asid & ASID_MASK) ) {
+			flush_tlb_all(); /* start new asid cycle */
+			if (!asid)      /* fix version if needed */
+				asid = ASID_FIRST_VERSION - ASID_FIRST_NONRESERVED;
+			asid += ASID_FIRST_NONRESERVED;
+			break; /* no need to validate here */
+		}
+		if (validate_asid (asid & ASID_MASK))
+			break;
+	}
+	mm->context = asid_cache = asid;
+}
+
+#endif
+
+
+/*
+ * Initialize the context related info for a new mm_struct
+ * instance.
+ */
+
+extern inline int
+init_new_context(struct task_struct *tsk, struct mm_struct *mm)
+{
+	mm->context = NO_CONTEXT;
+	return 0;
+}
+
+extern inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
+                             struct task_struct *tsk)
+{
+	unsigned long asid = asid_cache;
+
+	/* Check if our ASID is of an older version and thus invalid */
+
+	if ((next->context ^ asid) & ASID_VERSION_MASK)
+		get_new_mmu_context(next, asid);
+
+	set_rasid_register (ASID_INSERT(next->context));
+	invalidate_page_directory();
+}
+
+#define deactivate_mm(tsk, mm)	do { } while(0)
+
+/*
+ * Destroy context related info for an mm_struct that is about
+ * to be put to rest.
+ */
+extern inline void destroy_context(struct mm_struct *mm)
+{
+	/* Nothing to do. */
+}
+
+/*
+ * After we have set current->mm to a new value, this activates
+ * the context for the new mm so we see the new mappings.
+ */
+extern inline void
+activate_mm(struct mm_struct *prev, struct mm_struct *next)
+{
+	/* Unconditionally get a new ASID.  */
+
+	get_new_mmu_context(next, asid_cache);
+	set_rasid_register (ASID_INSERT(next->context));
+	invalidate_page_directory();
+}
+
+
+static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
+{
+	/* Nothing to do. */
+
+}
+
+#endif /* _XTENSA_MMU_CONTEXT_H */
diff --git a/include/asm-xtensa/module.h b/include/asm-xtensa/module.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/module.h
@@ -0,0 +1,25 @@
+/*
+ * include/asm-xtensa/module.h
+ *
+ * This file contains the module code specific to the Xtensa architecture.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_MODULE_H
+#define _XTENSA_MODULE_H
+
+struct mod_arch_specific
+{
+	/* Module support is not completely implemented. */
+};
+
+#define Elf_Shdr Elf32_Shdr
+#define Elf_Sym Elf32_Sym
+#define Elf_Ehdr Elf32_Ehdr
+
+#endif	/* _XTENSA_MODULE_H */
diff --git a/include/asm-xtensa/msgbuf.h b/include/asm-xtensa/msgbuf.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/msgbuf.h
@@ -0,0 +1,48 @@
+/*
+ * include/asm-xtensa/msgbuf.h
+ *
+ * The msqid64_ds structure for the Xtensa architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 64-bit time_t to solve y2038 problem
+ * - 2 miscellaneous 32-bit values
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file "COPYING" in the main directory of
+ * this archive for more details.
+ */
+
+#ifndef _XTENSA_MSGBUF_H
+#define _XTENSA_MSGBUF_H
+
+struct msqid64_ds {
+	struct ipc64_perm msg_perm;
+#ifdef __XTENSA_EB__
+	unsigned int	__unused1;
+	__kernel_time_t msg_stime;	/* last msgsnd time */
+	unsigned int	__unused2;
+	__kernel_time_t msg_rtime;	/* last msgrcv time */
+	unsigned int	__unused3;
+	__kernel_time_t msg_ctime;	/* last change time */
+#elif defined(__XTENSA_EL__)
+	__kernel_time_t msg_stime;	/* last msgsnd time */
+	unsigned int	__unused1;
+	__kernel_time_t msg_rtime;	/* last msgrcv time */
+	unsigned int	__unused2;
+	__kernel_time_t msg_ctime;	/* last change time */
+	unsigned int	__unused3;
+#else
+# error processor byte order undefined!
+#endif
+	unsigned long  msg_cbytes;	/* current number of bytes on queue */
+	unsigned long  msg_qnum;	/* number of messages in queue */
+	unsigned long  msg_qbytes;	/* max number of bytes on queue */
+	__kernel_pid_t msg_lspid;	/* pid of last msgsnd */
+	__kernel_pid_t msg_lrpid;	/* last receive pid */
+	unsigned long  __unused4;
+	unsigned long  __unused5;
+};
+
+#endif	/* _XTENSA_MSGBUF_H */
diff --git a/include/asm-xtensa/namei.h b/include/asm-xtensa/namei.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/namei.h
@@ -0,0 +1,26 @@
+/*
+ * include/asm-xtensa/namei.h
+ *
+ * Included from linux/fs/namei.c
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_NAMEI_H
+#define _XTENSA_NAMEI_H
+
+#ifdef __KERNEL__
+
+/* This dummy routine maybe changed to something useful
+ * for /usr/gnemul/ emulation stuff.
+ * Look at asm-sparc/namei.h for details.
+ */
+
+#define __emul_prefix() NULL
+
+#endif	/* __KERNEL__ */
+#endif	/* _XTENSA_NAMEI_H */
diff --git a/include/asm-xtensa/page.h b/include/asm-xtensa/page.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/page.h
@@ -0,0 +1,133 @@
+/*
+ * linux/include/asm-xtensa/page.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version2 as
+ * published by the Free Software Foundation.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_PAGE_H
+#define _XTENSA_PAGE_H
+
+#ifdef __KERNEL__
+
+#include <asm/processor.h>
+#include <linux/config.h>
+
+/*
+ * PAGE_SHIFT determines the page size
+ * PAGE_ALIGN(x) aligns the pointer to the (next) page boundary
+ */
+
+#define PAGE_SHIFT		XCHAL_MMU_MIN_PTE_PAGE_SIZE
+#define PAGE_SIZE		(1 << PAGE_SHIFT)
+#define PAGE_MASK		(~(PAGE_SIZE-1))
+#define PAGE_ALIGN(addr)	(((addr)+PAGE_SIZE - 1) & PAGE_MASK)
+
+#define DCACHE_WAY_SIZE		(XCHAL_DCACHE_SIZE / XCHAL_DCACHE_WAYS)
+#define PAGE_OFFSET		XCHAL_KSEG_CACHED_VADDR
+
+#ifdef __ASSEMBLY__
+
+#define __pgprot(x)	(x)
+
+#else
+
+/*
+ * These are used to make use of C type-checking..
+ */
+
+typedef struct { unsigned long pte; } pte_t;		/* page table entry */
+typedef struct { unsigned long pgd; } pgd_t;		/* PGD table entry */
+typedef struct { unsigned long pgprot; } pgprot_t;
+
+#define pte_val(x)	((x).pte)
+#define pgd_val(x)	((x).pgd)
+#define pgprot_val(x)	((x).pgprot)
+
+#define __pte(x)	((pte_t) { (x) } )
+#define __pgd(x)	((pgd_t) { (x) } )
+#define __pgprot(x)	((pgprot_t) { (x) } )
+
+/*
+ * Pure 2^n version of get_order
+ */
+
+extern __inline__ int get_order(unsigned long size)
+{
+	int order;
+#ifndef XCHAL_HAVE_NSU
+	unsigned long x1, x2, x4, x8, x16;
+
+	size = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
+	x1  = size & 0xAAAAAAAA;
+	x2  = size & 0xCCCCCCCC;
+	x4  = size & 0xF0F0F0F0;
+	x8  = size & 0xFF00FF00;
+	x16 = size & 0xFFFF0000;
+	order = x2 ? 2 : 0;
+	order += (x16 != 0) * 16;
+	order += (x8 != 0) * 8;
+	order += (x4 != 0) * 4;
+	order += (x1 != 0);
+
+	return order;
+#else
+	size = (size - 1) >> PAGE_SHIFT;
+	asm ("nsau %0, %1" : "=r" (order) : "r" (size));
+	return 32 - order;
+#endif
+}
+
+
+struct page;
+extern void clear_page(void *page);
+extern void copy_page(void *to, void *from);
+
+/*
+ * If we have cache aliasing and writeback caches, we might have to do
+ * some extra work
+ */
+
+#if (DCACHE_WAY_SIZE > PAGE_SIZE)
+void clear_user_page(void *addr, unsigned long vaddr, struct page* page);
+void copy_user_page(void *to,void* from,unsigned long vaddr,struct page* page);
+#else
+# define clear_user_page(page,vaddr,pg)		clear_page(page)
+# define copy_user_page(to, from, vaddr, pg)	copy_page(to, from)
+#endif
+
+/*
+ * This handles the memory map.  We handle pages at
+ * XCHAL_KSEG_CACHED_VADDR for kernels with 32 bit address space.
+ * These macros are for conversion of kernel address, not user
+ * addresses.
+ */
+
+#define __pa(x)			((unsigned long) (x) - PAGE_OFFSET)
+#define __va(x)			((void *)((unsigned long) (x) + PAGE_OFFSET))
+#define pfn_valid(pfn)		((unsigned long)pfn < max_mapnr)
+#ifndef CONFIG_DISCONTIGMEM
+# define pfn_to_page(pfn)	(mem_map + (pfn))
+# define page_to_pfn(page)	((unsigned long)((page) - mem_map))
+#else
+# error CONFIG_DISCONTIGMEM not supported
+#endif
+
+#define virt_to_page(kaddr)	pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
+#define page_to_virt(page)	__va(page_to_pfn(page) << PAGE_SHIFT)
+#define virt_addr_valid(kaddr)	pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
+#define page_to_phys(page)	(page_to_pfn(page) << PAGE_SHIFT)
+
+#define WANT_PAGE_VIRTUAL
+
+
+#endif /* __ASSEMBLY__ */
+
+#define VM_DATA_DEFAULT_FLAGS	(VM_READ | VM_WRITE | VM_EXEC | \
+				 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
+
+#endif /* __KERNEL__ */
+#endif /* _XTENSA_PAGE_H */
diff --git a/include/asm-xtensa/page.h.n b/include/asm-xtensa/page.h.n
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/page.h.n
@@ -0,0 +1,135 @@
+/*
+ * linux/include/asm-xtensa/page.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version2 as
+ * published by the Free Software Foundation.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_PAGE_H
+#define _XTENSA_PAGE_H
+
+#ifdef __KERNEL__
+
+#include <asm/processor.h>
+#include <linux/config.h>
+
+/*
+ * PAGE_SHIFT determines the page size
+ * PAGE_ALIGN(x) aligns the pointer to the (next) page boundary
+ */
+#define PAGE_SHIFT		XCHAL_MMU_MIN_PTE_PAGE_SIZE
+#define PAGE_SIZE		(1 << PAGE_SHIFT)
+#define PAGE_MASK		(~(PAGE_SIZE-1))
+#define PAGE_ALIGN(addr)	(((addr)+PAGE_SIZE - 1) & PAGE_MASK)
+
+#define DCACHE_WAY_SIZE		(XCHAL_DCACHE_SIZE / XCHAL_DCACHE_WAYS)
+#define PAGE_OFFSET		XCHAL_KSEG_CACHED_VADDR
+
+#ifdef __ASSEMBLY__
+
+#define __pgprot(x)	(x)
+
+#else
+
+
+/*
+ * These are used to make use of C type-checking..
+ */
+typedef struct { unsigned long pte; } pte_t;		/* page table entry */
+typedef struct { unsigned long pmd; } pmd_t;		/* PMD table entry */
+typedef struct { unsigned long pgd; } pgd_t;		/* PGD table entry */
+typedef struct { unsigned long pgprot; } pgprot_t;
+
+#define pte_val(x)	((x).pte)
+#define pmd_val(x)	((x).pmd)
+#define pgd_val(x)	((x).pgd)
+#define pgprot_val(x)	((x).pgprot)
+
+#define __pte(x)	((pte_t) { (x) } )
+#define __pmd(x)	((pmd_t) { (x) } )
+#define __pgd(x)	((pgd_t) { (x) } )
+#define __pgprot(x)	((pgprot_t) { (x) } )
+
+/*
+ * Pure 2^n version of get_order
+ */
+extern __inline__ int get_order(unsigned long size)
+{
+	int order;
+#ifndef XCHAL_HAVE_NSU
+	unsigned long x1, x2, x4, x8, x16;
+
+	size = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
+	x1  = size & 0xAAAAAAAA;
+	x2  = size & 0xCCCCCCCC;
+	x4  = size & 0xF0F0F0F0;
+	x8  = size & 0xFF00FF00;
+	x16 = size & 0xFFFF0000;
+	order = x2 ? 2 : 0;
+	order += (x16 != 0) * 16;
+	order += (x8 != 0) * 8;
+	order += (x4 != 0) * 4;
+	order += (x1 != 0);
+
+	return order;
+#else
+	size = (size - 1) >> PAGE_SHIFT;
+	asm ("nsau %0, %1" : "=r" (order) : "r" (size));
+	return 32 - order;
+#endif
+}
+
+
+struct page;
+extern void clear_page(void *page);
+extern void copy_page(void *to, void *from);
+
+/*
+ * If we have cache aliasing and writeback caches, we might have to do
+ * some extra work
+ */
+
+#if (DCACHE_WAY_SIZE > PAGE_SIZE) && XCHAL_DCACHE_IS_WRITEBACK
+void clear_user_page(void *addr, unsigned long vaddr, struct page* page);
+void copy_user_page(void *to, void* from, unsigned long vaddr, struct page* page);
+#else
+# define clear_user_page(page,vaddr,pg)		clear_page(page)
+# define copy_user_page(to, from, vaddr, pg)	copy_page(to, from)
+#endif
+
+
+/*
+ * This handles the memory map.  We handle pages at
+ * XCHAL_KSEG_CACHED_VADDR for kernels with 32 bit address space.
+ * These macros are for conversion of kernel address, not user
+ * addresses.
+ */
+
+#define __pa(x)			((unsigned long) (x) - PAGE_OFFSET)
+#define __va(x)			((void *)((unsigned long) (x) + PAGE_OFFSET))
+#define pfn_valid(pfn)		((unsigned long)pfn < max_mapnr)
+#ifndef CONFIG_DISCONTIGMEM
+# define pfn_to_page(pfn)	(mem_map + (pfn))
+# define page_to_pfn(page)	((unsigned long)((page) - mem_map))
+#else
+# error CONFIG_DISCONTIGMEM not supported
+#endif
+
+#define virt_to_page(kaddr)	pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
+#define page_to_virt(page)	__va(page_to_pfn(page) << PAGE_SHIFT)
+#define virt_addr_valid(kaddr)	pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
+#define page_to_phys(page)	(page_to_pfn(page) << PAGE_SHIFT)
+
+#define WANT_PAGE_VIRTUAL
+
+
+#endif /* __ASSEMBLY__ */
+
+#define VM_DATA_DEFAULT_FLAGS	(VM_READ | VM_WRITE | VM_EXEC | \
+				 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
+
+#endif /* __KERNEL__ */
+#endif /* _XTENSA_PAGE_H */
diff --git a/include/asm-xtensa/param.h b/include/asm-xtensa/param.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/param.h
@@ -0,0 +1,34 @@
+/*
+ * include/asm-xtensa/param.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_PARAM_H
+#define _XTENSA_PARAM_H
+
+#include <xtensa/config/core.h>
+
+#ifdef __KERNEL__
+# define HZ		100		/* internal timer frequency */
+# define USER_HZ	100		/* for user interfaces in "ticks" */
+# define CLOCKS_PER_SEC (USER_HZ)	/* frequnzy at which times() counts */
+#endif
+
+#define EXEC_PAGESIZE	(1 << XCHAL_MMU_MIN_PTE_PAGE_SIZE)
+
+#ifndef NGROUPS
+#define NGROUPS		32
+#endif
+
+#ifndef NOGROUP
+#define NOGROUP		(-1)
+#endif
+
+#define MAXHOSTNAMELEN	64	/* max length of hostname */
+
+#endif /* _XTENSA_PARAM_H */
diff --git a/include/asm-xtensa/pci-bridge.h b/include/asm-xtensa/pci-bridge.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/pci-bridge.h
@@ -0,0 +1,88 @@
+/*
+ * include/asm-xtensa/pci-bridge.h
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file "COPYING" in the main directory of
+ * this archive for more details.
+ *
+ * Copyright (C) 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_PCI_BRIDGE_H
+#define _XTENSA_PCI_BRIDGE_H
+
+#ifdef __KERNEL__
+
+struct device_node;
+struct pci_controller;
+
+/*
+ * pciauto_bus_scan() enumerates the pci space.
+ */
+
+extern int pciauto_bus_scan(struct pci_controller *, int);
+
+struct pci_space {
+	unsigned long start;
+	unsigned long end;
+	unsigned long base;
+};
+
+/*
+ * Structure of a PCI controller (host bridge)
+ */
+
+struct pci_controller {
+	int index;			/* used for pci_controller_num */
+	struct pci_controller *next;
+        struct pci_bus *bus;
+	void *arch_data;
+
+	int first_busno;
+	int last_busno;
+
+	struct pci_ops *ops;
+	volatile unsigned int *cfg_addr;
+	volatile unsigned char *cfg_data;
+
+	/* Currently, we limit ourselves to 1 IO range and 3 mem
+	 * ranges since the common pci_bus structure can't handle more
+	 */
+	struct resource	io_resource;
+	struct resource mem_resources[3];
+	int mem_resource_count;
+
+	/* Host bridge I/O and Memory space
+	 * Used for BAR placement algorithms
+	 */
+	struct pci_space io_space;
+	struct pci_space mem_space;
+
+	/* Return the interrupt number fo a device. */
+	int (*map_irq)(struct pci_dev*, u8, u8);
+
+};
+
+static inline void pcibios_init_resource(struct resource *res,
+		unsigned long start, unsigned long end, int flags, char *name)
+{
+	res->start = start;
+	res->end = end;
+	res->flags = flags;
+	res->name = name;
+	res->parent = NULL;
+	res->sibling = NULL;
+	res->child = NULL;
+}
+
+
+/* These are used for config access before all the PCI probing has been done. */
+int early_read_config_byte(struct pci_controller*, int, int, int, u8*);
+int early_read_config_word(struct pci_controller*, int, int, int, u16*);
+int early_read_config_dword(struct pci_controller*, int, int, int, u32*);
+int early_write_config_byte(struct pci_controller*, int, int, int, u8);
+int early_write_config_word(struct pci_controller*, int, int, int, u16);
+int early_write_config_dword(struct pci_controller*, int, int, int, u32);
+
+#endif	/* __KERNEL__ */
+#endif	/* _XTENSA_PCI_BRIDGE_H */
diff --git a/include/asm-xtensa/pci.h b/include/asm-xtensa/pci.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/pci.h
@@ -0,0 +1,89 @@
+/*
+ * linux/include/asm-xtensa/pci.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_PCI_H
+#define _XTENSA_PCI_H
+
+#ifdef __KERNEL__
+
+/* Can be used to override the logic in pci_scan_bus for skipping
+ * already-configured bus numbers - to be used for buggy BIOSes
+ * or architectures with incomplete PCI setup by the loader
+ */
+
+#define pcibios_assign_all_busses()	0
+
+extern struct pci_controller* pcibios_alloc_controller(void);
+
+extern inline void pcibios_set_master(struct pci_dev *dev)
+{
+	/* No special bus mastering setup handling */
+}
+
+extern inline void pcibios_penalize_isa_irq(int irq)
+{
+	/* We don't do dynamic PCI IRQ allocation */
+}
+
+/* Assume some values. (We should revise them, if necessary) */
+
+#define PCIBIOS_MIN_IO		0x2000
+#define PCIBIOS_MIN_MEM		0x10000000
+
+/* Dynamic DMA mapping stuff.
+ * Xtensa has everything mapped statically like x86.
+ */
+
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <asm/scatterlist.h>
+#include <linux/string.h>
+#include <asm/io.h>
+
+struct pci_dev;
+
+/* The PCI address space does equal the physical memory address space.
+ * The networking and block device layers use this boolean for bounce buffer
+ * decisions.
+ */
+
+#define PCI_DMA_BUS_IS_PHYS	(1)
+
+/* pci_unmap_{page,single} is a no-op, so */
+#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)
+#define DECLARE_PCI_UNMAP_LEN(LEN_NAME)
+#define pci_unmap_addr(PTR, ADDR_NAME)		(0)
+#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL)	do { } while (0)
+#define pci_ubnmap_len(PTR, LEN_NAME)		(0)
+#define pci_unmap_len_set(PTR, LEN_NAME, VAL)	do { } while (0)
+
+/* We cannot access memory above 4GB */
+#define pci_dac_dma_supported(pci_dev, mask)	(0)
+
+/* Map a range of PCI memory or I/O space for a device into user space */
+int pci_mmap_page_range(struct pci_dev *pdev, struct vm_area_struct *vma,
+                        enum pci_mmap_state mmap_state, int write_combine);
+
+/* Tell drivers/pci/proc.c that we have pci_mmap_page_range() */
+#define HAVE_PCI_MMAP	1
+
+static inline void pcibios_add_platform_entries(struct pci_dev *dev)
+{
+}
+
+#endif /* __KERNEL__ */
+
+/* Implement the pci_ DMA API in terms of the generic device dma_ one */
+#include <asm-generic/pci-dma-compat.h>
+
+/* Generic PCI */
+#include <asm-generic/pci.h>
+
+#endif	/* _XTENSA_PCI_H */
diff --git a/include/asm-xtensa/percpu.h b/include/asm-xtensa/percpu.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/percpu.h
@@ -0,0 +1,16 @@
+/*
+ * linux/include/asm-xtensa/percpu.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_PERCPU__
+#define _XTENSA_PERCPU__
+
+#include <asm-generic/percpu.h>
+
+#endif /* _XTENSA_PERCPU__ */
diff --git a/include/asm-xtensa/pgalloc.h b/include/asm-xtensa/pgalloc.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/pgalloc.h
@@ -0,0 +1,116 @@
+/*
+ * linux/include/asm-xtensa/pgalloc.h
+ *
+ * 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.
+ *
+ * Copyright (C) 2001-2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_PGALLOC_H
+#define _XTENSA_PGALLOC_H
+
+#ifdef __KERNEL__
+
+#include <linux/config.h>
+#include <linux/threads.h>
+#include <linux/highmem.h>
+#include <asm/processor.h>
+#include <asm/cacheflush.h>
+
+
+/* Cache aliasing:
+ *
+ * If the cache size for one way is greater than the page size, we have to
+ * deal with cache aliasing. The cache index is wider than the page size:
+ *
+ *      |cache |
+ * |pgnum |page|	virtual address
+ * |xxxxxX|zzzz|
+ * |      |    |
+ *   \  / |    |
+ *  trans.|    |
+ *   /  \ |    |
+ * |yyyyyY|zzzz|	physical address
+ *
+ * When the page number is translated to the physical page address, the lowest
+ * bit(s) (X) that are also part of the cache index are also translated (Y).
+ * If this translation changes this bit (X), the cache index is also afected,
+ * thus resulting in a different cache line than before.
+ * The kernel does not provide a mechanism to ensure that the page color
+ * (represented by this bit) remains the same when allocated or when pages
+ * are remapped. When user pages are mapped into kernel space, the color of
+ * the page might also change.
+ *
+ * We use the address space VMALLOC_END ... VMALLOC_END + DCACHE_WAY_SIZE * 2
+ * to temporarily map a patch so we can match the color.
+ */
+
+#if (DCACHE_WAY_SIZE > PAGE_SIZE)
+# define PAGE_COLOR_MASK	(PAGE_MASK & (DCACHE_WAY_SIZE-1))
+# define PAGE_COLOR(a)		\
+	(((unsigned long)(a)&PAGE_COLOR_MASK) >> PAGE_SHIFT)
+# define PAGE_COLOR_EQ(a,b)	\
+	((((unsigned long)(a) ^ (unsigned long)(b)) & PAGE_COLOR_MASK) == 0)
+# define PAGE_COLOR_MAP0(v)	\
+	(VMALLOC_END + ((unsigned long)(v) & PAGE_COLOR_MASK))
+# define PAGE_COLOR_MAP1(v)	\
+	(VMALLOC_END + ((unsigned long)(v) & PAGE_COLOR_MASK) + DCACHE_WAY_SIZE)
+#endif
+
+/*
+ * Allocating and freeing a pmd is trivial: the 1-entry pmd is
+ * inside the pgd, so has no extra memory associated with it.
+ */
+
+#define pgd_free(pgd)	free_page((unsigned long)(pgd))
+
+#if (DCACHE_WAY_SIZE > PAGE_SIZE) && XCHAL_DCACHE_IS_WRITEBACK
+
+static inline void
+pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmdp, pte_t *pte)
+{
+	pmd_val(*(pmdp)) = (unsigned long)(pte);
+	__asm__ __volatile__ ("memw; dhwb %0, 0; dsync" :: "a" (pmdp));
+}
+
+static inline void
+pmd_populate(struct mm_struct *mm, pmd_t *pmdp, struct page *page)
+{
+	pmd_val(*(pmdp)) = (unsigned long)page_to_virt(page);
+	__asm__ __volatile__ ("memw; dhwb %0, 0; dsync" :: "a" (pmdp));
+}
+
+
+
+#else
+
+# define pmd_populate_kernel(mm, pmdp, pte)				     \
+	(pmd_val(*(pmdp)) = (unsigned long)(pte))
+# define pmd_populate(mm, pmdp, page)					     \
+	(pmd_val(*(pmdp)) = (unsigned long)page_to_virt(page))
+
+#endif
+
+static inline pgd_t*
+pgd_alloc(struct mm_struct *mm)
+{
+	pgd_t *pgd;
+
+	pgd = (pgd_t *)__get_free_pages(GFP_KERNEL|__GFP_ZERO, PGD_ORDER);
+
+	if (likely(pgd != NULL))
+		__flush_dcache_page((unsigned long)pgd);
+
+	return pgd;
+}
+
+extern pte_t* pte_alloc_one_kernel(struct mm_struct* mm, unsigned long addr);
+extern struct page* pte_alloc_one(struct mm_struct* mm, unsigned long addr);
+
+#define pte_free_kernel(pte) free_page((unsigned long)pte)
+#define pte_free(pte) __free_page(pte)
+
+#endif /* __KERNEL__ */
+#endif /* _XTENSA_PGALLOC_H */
diff --git a/include/asm-xtensa/pgtable.h b/include/asm-xtensa/pgtable.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/pgtable.h
@@ -0,0 +1,468 @@
+/*
+ * linux/include/asm-xtensa/page.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version2 as
+ * published by the Free Software Foundation.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_PGTABLE_H
+#define _XTENSA_PGTABLE_H
+
+#include <asm-generic/pgtable-nopmd.h>
+#include <asm/page.h>
+
+/* Assertions. */
+
+#ifdef CONFIG_MMU
+
+
+#if (XCHAL_MMU_RINGS < 2)
+# error Linux build assumes at least 2 ring levels.
+#endif
+
+#if (XCHAL_MMU_CA_BITS != 4)
+# error We assume exactly four bits for CA.
+#endif
+
+#if (XCHAL_MMU_SR_BITS != 0)
+# error We have no room for SR bits.
+#endif
+
+/*
+ * Use the first min-wired way for mapping page-table pages.
+ * Page coloring requires a second min-wired way.
+ */
+
+#if (XCHAL_DTLB_MINWIRED_SETS == 0)
+# error Need a min-wired way for mapping page-table pages
+#endif
+
+#define DTLB_WAY_PGTABLE XCHAL_DTLB_SET(XCHAL_DTLB_MINWIRED_SET0, WAY)
+
+#if (DCACHE_WAY_SIZE > PAGE_SIZE) && XCHAL_DCACHE_IS_WRITEBACK
+# if XCHAL_DTLB_SET(XCHAL_DTLB_MINWIRED_SET0, WAYS) >= 2
+#  define DTLB_WAY_DCACHE_ALIAS0 (DTLB_WAY_PGTABLE + 1)
+#  define DTLB_WAY_DCACHE_ALIAS1 (DTLB_WAY_PGTABLE + 2)
+# else
+#  error Page coloring requires its own wired dtlb way!
+# endif
+#endif
+
+#endif /* CONFIG_MMU */
+
+/*
+ * We only use two ring levels, user and kernel space.
+ */
+
+#define USER_RING		1	/* user ring level */
+#define KERNEL_RING		0	/* kernel ring level */
+
+/*
+ * The Xtensa architecture port of Linux has a two-level page table system,
+ * i.e. the logical three-level Linux page table layout are folded.
+ * Each task has the following memory page tables:
+ *
+ *   PGD table (page directory), ie. 3rd-level page table:
+ *	One page (4 kB) of 1024 (PTRS_PER_PGD) pointers to PTE tables
+ *	(Architectures that don't have the PMD folded point to the PMD tables)
+ *
+ *	The pointer to the PGD table for a given task can be retrieved from
+ *	the task structure (struct task_struct*) t, e.g. current():
+ *	  (t->mm ? t->mm : t->active_mm)->pgd
+ *
+ *   PMD tables (page middle-directory), ie. 2nd-level page tables:
+ *	Absent for the Xtensa architecture (folded, PTRS_PER_PMD == 1).
+ *
+ *   PTE tables (page table entry), ie. 1st-level page tables:
+ *	One page (4 kB) of 1024 (PTRS_PER_PTE) PTEs with a special PTE
+ *	invalid_pte_table for absent mappings.
+ *
+ * The individual pages are 4 kB big with special pages for the empty_zero_page.
+ */
+#define PGDIR_SHIFT	22
+#define PGDIR_SIZE	(1UL << PGDIR_SHIFT)
+#define PGDIR_MASK	(~(PGDIR_SIZE-1))
+
+/*
+ * Entries per page directory level: we use two-level, so
+ * we don't really have any PMD directory physically.
+ */
+#define PTRS_PER_PTE		1024
+#define PTRS_PER_PTE_SHIFT	10
+#define PTRS_PER_PMD		1
+#define PTRS_PER_PGD		1024
+#define PGD_ORDER		0
+#define PMD_ORDER		0
+#define USER_PTRS_PER_PGD	(TASK_SIZE/PGDIR_SIZE)
+#define FIRST_USER_ADDRESS      XCHAL_SEG_MAPPABLE_VADDR
+#define FIRST_USER_PGD_NR	(FIRST_USER_ADDRESS >> PGDIR_SHIFT)
+
+/* virtual memory area. We keep a distance to other memory regions to be
+ * on the safe side. We also use this area for cache aliasing.
+ */
+
+// FIXME: virtual memory area must be configuration-dependent
+
+#define VMALLOC_START		0xC0000000
+#define VMALLOC_END		0xC7FF0000
+
+/* Xtensa Linux config PTE layout (when present):
+ *	31-12:	PPN
+ *	11-6:	Software
+ *	5-4:	RING
+ *	3-0:	CA
+ *
+ * Similar to the Alpha and MIPS ports, we need to keep track of the ref
+ * and mod bits in software.  We have a software "you can read
+ * from this page" bit, and a hardware one which actually lets the
+ * process read from the page.  On the same token we have a software
+ * writable bit and the real hardware one which actually lets the
+ * process write to the page.
+ *
+ * See further below for PTE layout for swapped-out pages.
+ */
+
+#define _PAGE_VALID		(1<<0)	/* hardware: page is accessible */
+#define _PAGE_WRENABLE		(1<<1)	/* hardware: page is writable */
+
+/* None of these cache modes include MP coherency:  */
+#define _PAGE_NO_CACHE		(0<<2)	/* bypass, non-speculative */
+#if XCHAL_DCACHE_IS_WRITEBACK
+# define _PAGE_WRITEBACK	(1<<2)	/* write back */
+# define _PAGE_WRITETHRU	(2<<2)	/* write through */
+#else
+# define _PAGE_WRITEBACK	(1<<2)	/* assume write through */
+# define _PAGE_WRITETHRU	(1<<2)
+#endif
+#define _PAGE_NOALLOC		(3<<2)	/* don't allocate cache,if not cached */
+#define _CACHE_MASK		(3<<2)
+
+#define _PAGE_USER		(1<<4)	/* user access (ring=1) */
+#define _PAGE_KERNEL		(0<<4)	/* kernel access (ring=0) */
+
+/* Software */
+#define _PAGE_RW		(1<<6)	/* software: page writable */
+#define _PAGE_DIRTY		(1<<7)	/* software: page dirty */
+#define _PAGE_ACCESSED		(1<<8)	/* software: page accessed (read) */
+#define _PAGE_FILE		(1<<9)	/* nonlinear file mapping*/
+
+#define _PAGE_CHG_MASK	(PAGE_MASK | _PAGE_ACCESSED | _CACHE_MASK | _PAGE_DIRTY)
+#define _PAGE_PRESENT	( _PAGE_VALID | _PAGE_WRITEBACK | _PAGE_ACCESSED)
+
+#ifdef CONFIG_MMU
+
+# define PAGE_NONE	__pgprot(_PAGE_PRESENT)
+# define PAGE_SHARED	__pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_RW)
+# define PAGE_COPY	__pgprot(_PAGE_PRESENT | _PAGE_USER)
+# define PAGE_READONLY	__pgprot(_PAGE_PRESENT | _PAGE_USER)
+# define PAGE_KERNEL	__pgprot(_PAGE_PRESENT | _PAGE_KERNEL | _PAGE_WRENABLE)
+# define PAGE_INVALID	__pgprot(_PAGE_USER)
+
+# if (DCACHE_WAY_SIZE > PAGE_SIZE)
+#  define PAGE_DIRECTORY  __pgprot(_PAGE_VALID | _PAGE_ACCESSED | _PAGE_KERNEL)
+# else
+#  define PAGE_DIRECTORY  __pgprot(_PAGE_PRESENT | _PAGE_KERNEL)
+# endif
+
+#else /* no mmu */
+
+# define PAGE_NONE       __pgprot(0)
+# define PAGE_SHARED     __pgprot(0)
+# define PAGE_COPY       __pgprot(0)
+# define PAGE_READONLY   __pgprot(0)
+# define PAGE_KERNEL     __pgprot(0)
+
+#endif
+
+/*
+ * On certain configurations of Xtensa MMUs (eg. the initial Linux config),
+ * the MMU can't do page protection for execute, and considers that the same as
+ * read.  Also, write permissions may imply read permissions.
+ * What follows is the closest we can get by reasonable means..
+ * See linux/mm/mmap.c for protection_map[] array that uses these definitions.
+ */
+#define __P000	PAGE_NONE	/* private --- */
+#define __P001	PAGE_READONLY	/* private --r */
+#define __P010	PAGE_COPY	/* private -w- */
+#define __P011	PAGE_COPY	/* private -wr */
+#define __P100	PAGE_READONLY	/* private x-- */
+#define __P101	PAGE_READONLY	/* private x-r */
+#define __P110	PAGE_COPY	/* private xw- */
+#define __P111	PAGE_COPY	/* private xwr */
+
+#define __S000	PAGE_NONE	/* shared  --- */
+#define __S001	PAGE_READONLY	/* shared  --r */
+#define __S010	PAGE_SHARED	/* shared  -w- */
+#define __S011	PAGE_SHARED	/* shared  -wr */
+#define __S100	PAGE_READONLY	/* shared  x-- */
+#define __S101	PAGE_READONLY	/* shared  x-r */
+#define __S110	PAGE_SHARED	/* shared  xw- */
+#define __S111	PAGE_SHARED	/* shared  xwr */
+
+#ifndef __ASSEMBLY__
+
+#define pte_ERROR(e) \
+	printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e))
+#define pgd_ERROR(e) \
+	printk("%s:%d: bad pgd entry %08lx.\n", __FILE__, __LINE__, pgd_val(e))
+
+extern unsigned long empty_zero_page[1024];
+
+#define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
+
+extern pgd_t swapper_pg_dir[PAGE_SIZE/sizeof(pgd_t)];
+
+/*
+ * The pmd contains the kernel virtual address of the pte page.
+ */
+#define pmd_page_kernel(pmd) ((unsigned long)(pmd_val(pmd) & PAGE_MASK))
+#define pmd_page(pmd) virt_to_page(pmd_val(pmd))
+
+/*
+ * The following only work if pte_present() is true.
+ */
+#define pte_none(pte)	 (!(pte_val(pte) ^ _PAGE_USER))
+#define pte_present(pte) (pte_val(pte) & _PAGE_VALID)
+#define pte_clear(mm,addr,ptep)						\
+	do { update_pte(ptep, __pte(_PAGE_USER)); } while(0)
+
+#define pmd_none(pmd)	 (!pmd_val(pmd))
+#define pmd_present(pmd) (pmd_val(pmd) & PAGE_MASK)
+#define pmd_clear(pmdp)	 do { set_pmd(pmdp, __pmd(0)); } while (0)
+#define pmd_bad(pmd)	 (pmd_val(pmd) & ~PAGE_MASK)
+
+/* Note: We use the _PAGE_USER bit to indicate write-protect kernel memory */
+
+static inline int pte_read(pte_t pte)  { return pte_val(pte) & _PAGE_USER; }
+static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_RW; }
+static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; }
+static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; }
+static inline int pte_file(pte_t pte)  { return pte_val(pte) & _PAGE_FILE; }
+static inline pte_t pte_wrprotect(pte_t pte)	{ pte_val(pte) &= ~(_PAGE_RW | _PAGE_WRENABLE); return pte; }
+static inline pte_t pte_rdprotect(pte_t pte)	{ pte_val(pte) &= ~_PAGE_USER; return pte; }
+static inline pte_t pte_mkclean(pte_t pte)	{ pte_val(pte) &= ~_PAGE_DIRTY; return pte; }
+static inline pte_t pte_mkold(pte_t pte)	{ pte_val(pte) &= ~_PAGE_ACCESSED; return pte; }
+static inline pte_t pte_mkread(pte_t pte)	{ pte_val(pte) |= _PAGE_USER; return pte; }
+static inline pte_t pte_mkdirty(pte_t pte)	{ pte_val(pte) |= _PAGE_DIRTY; return pte; }
+static inline pte_t pte_mkyoung(pte_t pte)	{ pte_val(pte) |= _PAGE_ACCESSED; return pte; }
+static inline pte_t pte_mkwrite(pte_t pte)	{ pte_val(pte) |= _PAGE_RW; return pte; }
+
+/*
+ * Conversion functions: convert a page and protection to a page entry,
+ * and a page entry and page directory to the page they refer to.
+ */
+#define pte_pfn(pte)		(pte_val(pte) >> PAGE_SHIFT)
+#define pte_same(a,b)		(pte_val(a) == pte_val(b))
+#define pte_page(x)		pfn_to_page(pte_pfn(x))
+#define pfn_pte(pfn, prot)	__pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
+#define mk_pte(page, prot)	pfn_pte(page_to_pfn(page), prot)
+
+extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
+{
+	return __pte((pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot));
+}
+
+/*
+ * Certain architectures need to do special things when pte's
+ * within a page table are directly modified.  Thus, the following
+ * hook is made available.
+ */
+static inline void update_pte(pte_t *ptep, pte_t pteval)
+{
+	*ptep = pteval;
+#if (DCACHE_WAY_SIZE > PAGE_SIZE) && XCHAL_DCACHE_IS_WRITEBACK
+	__asm__ __volatile__ ("memw; dhwb %0, 0; dsync" :: "a" (ptep));
+#endif
+}
+
+extern inline void
+set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pteval)
+{
+	update_pte(ptep, pteval);
+}
+
+
+extern inline void
+set_pmd(pmd_t *pmdp, pmd_t pmdval)
+{
+	*pmdp = pmdval;
+#if (DCACHE_WAY_SIZE > PAGE_SIZE) && XCHAL_DCACHE_IS_WRITEBACK
+	__asm__ __volatile__ ("memw; dhwb %0, 0; dsync" :: "a" (pmdp));
+#endif
+}
+
+
+static inline int
+ptep_test_and_clear_young(struct vm_area_struct *vma, unsigned long addr,
+    			  pte_t *ptep)
+{
+	pte_t pte = *ptep;
+	if (!pte_young(pte))
+		return 0;
+	update_pte(ptep, pte_mkold(pte));
+	return 1;
+}
+
+static inline int
+ptep_test_and_clear_dirty(struct vm_area_struct *vma, unsigned long addr,
+   			  pte_t *ptep)
+{
+	pte_t pte = *ptep;
+	if (!pte_dirty(pte))
+		return 0;
+	update_pte(ptep, pte_mkclean(pte));
+	return 1;
+}
+
+static inline pte_t
+ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
+{
+	pte_t pte = *ptep;
+	pte_clear(mm, addr, ptep);
+	return pte;
+}
+
+static inline void
+ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
+{
+  	pte_t pte = *ptep;
+  	update_pte(ptep, pte_wrprotect(pte));
+}
+
+/* to find an entry in a kernel page-table-directory */
+#define pgd_offset_k(address)	pgd_offset(&init_mm, address)
+
+/* to find an entry in a page-table-directory */
+#define pgd_offset(mm,address)	((mm)->pgd + pgd_index(address))
+
+#define pgd_index(address)	((address) >> PGDIR_SHIFT)
+
+/* Find an entry in the second-level page table.. */
+#define pmd_offset(dir,address) ((pmd_t*)(dir))
+
+/* Find an entry in the third-level page table.. */
+#define pte_index(address)	(((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
+#define pte_offset_kernel(dir,addr) 					\
+	((pte_t*) pmd_page_kernel(*(dir)) + pte_index(addr))
+#define pte_offset_map(dir,addr)	pte_offset_kernel((dir),(addr))
+#define pte_offset_map_nested(dir,addr)	pte_offset_kernel((dir),(addr))
+
+#define pte_unmap(pte)		do { } while (0)
+#define pte_unmap_nested(pte)	do { } while (0)
+
+
+/*
+ * Encode and decode a swap entry.
+ * Each PTE in a process VM's page table is either:
+ *   "present" -- valid and not swapped out, protection bits are meaningful;
+ *   "not present" -- which further subdivides in these two cases:
+ *      "none" -- no mapping at all; identified by pte_none(), set by pte_clear(
+ *      "swapped out" -- the page is swapped out, and the SWP macros below
+ *                      are used to store swap file info in the PTE itself.
+ *
+ * In the Xtensa processor MMU, any PTE entries in user space (or anywhere
+ * in virtual memory that can map differently across address spaces)
+ * must have a correct ring value that represents the RASID field that
+ * is changed when switching address spaces.  Eg. such PTE entries cannot
+ * be set to ring zero, because that can cause a (global) kernel ASID
+ * entry to be created in the TLBs (even with invalid cache attribute),
+ * potentially causing a multihit exception when going back to another
+ * address space that mapped the same virtual address at another ring.
+ *
+ * SO: we avoid using ring bits (_PAGE_RING_MASK) in "not present" PTEs.
+ * We also avoid using the _PAGE_VALID bit which must be zero for non-present
+ * pages.
+ *
+ * We end up with the following available bits:  1..3 and 7..31.
+ * We don't bother with 1..3 for now (we can use them later if needed),
+ * and chose to allocate 6 bits for SWP_TYPE and the remaining 19 bits
+ * for SWP_OFFSET.  At least 5 bits are needed for SWP_TYPE, because it
+ * is currently implemented as an index into swap_info[MAX_SWAPFILES]
+ * and MAX_SWAPFILES is currently defined as 32 in <linux/swap.h>.
+ * However, for some reason all other architectures in the 2.4 kernel
+ * reserve either 6, 7, or 8 bits so I'll not detract from that for now.  :)
+ * SWP_OFFSET is an offset into the swap file in page-size units, so
+ * with 4 kB pages, 19 bits supports a maximum swap file size of 2 GB.
+ *
+ * FIXME:  2 GB isn't very big.  Other bits can be used to allow
+ * larger swap sizes.  In the meantime, it appears relatively easy to get
+ * around the 2 GB limitation by simply using multiple swap files.
+ */
+
+#define __swp_type(entry)	(((entry).val >> 7) & 0x3f)
+#define __swp_offset(entry)	((entry).val >> 13)
+#define __swp_entry(type,offs)	((swp_entry_t) {((type) << 7) | ((offs) << 13)})
+#define __pte_to_swp_entry(pte)	((swp_entry_t) { pte_val(pte) })
+#define __swp_entry_to_pte(x)	((pte_t) { (x).val })
+
+#define PTE_FILE_MAX_BITS	29
+#define pte_to_pgoff(pte)	(pte_val(pte) >> 3)
+#define pgoff_to_pte(off)	((pte_t) { ((off) << 3) | _PAGE_FILE })
+
+
+#endif /*  !defined (__ASSEMBLY__) */
+
+
+#ifdef __ASSEMBLY__
+
+/* Assembly macro _PGD_INDEX is the same as C pgd_index(unsigned long),
+ *                _PGD_OFFSET as C pgd_offset(struct mm_struct*, unsigned long),
+ *                _PMD_OFFSET as C pmd_offset(pgd_t*, unsigned long)
+ *                _PTE_OFFSET as C pte_offset(pmd_t*, unsigned long)
+ *
+ * Note: We require an additional temporary register which can be the same as
+ *       the register that holds the address.
+ *
+ * ((pte_t*) ((unsigned long)(pmd_val(*pmd) & PAGE_MASK)) + pte_index(addr))
+ *
+ */
+#define _PGD_INDEX(rt,rs)	extui	rt, rs, PGDIR_SHIFT, 32-PGDIR_SHIFT
+#define _PTE_INDEX(rt,rs)	extui	rt, rs, PAGE_SHIFT, PTRS_PER_PTE_SHIFT
+
+#define _PGD_OFFSET(mm,adr,tmp)		l32i	mm, mm, MM_PGD;		\
+					_PGD_INDEX(tmp, adr);		\
+					addx4	mm, tmp, mm
+
+#define _PTE_OFFSET(pmd,adr,tmp)	_PTE_INDEX(tmp, adr);		\
+					srli	pmd, pmd, PAGE_SHIFT;	\
+					slli	pmd, pmd, PAGE_SHIFT;	\
+					addx4	pmd, tmp, pmd
+
+#else
+
+extern void paging_init(void);
+
+#define kern_addr_valid(addr)	(1)
+
+extern  void update_mmu_cache(struct vm_area_struct * vma,
+			      unsigned long address, pte_t pte);
+
+/*
+ * remap a physical address `phys' of size `size' with page protection `prot'
+ * into virtual address `from'
+ */
+#define io_remap_page_range(vma,from,phys,size,prot) \
+                remap_pfn_range(vma, from, (phys) >> PAGE_SHIFT, size, prot)
+
+
+/* No page table caches to init */
+
+#define pgtable_cache_init()	do { } while (0)
+
+typedef pte_t *pte_addr_t;
+
+#endif /* !defined (__ASSEMBLY__) */
+
+#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
+#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_DIRTY
+#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
+#define __HAVE_ARCH_PTEP_SET_WRPROTECT
+#define __HAVE_ARCH_PTEP_MKDIRTY
+#define __HAVE_ARCH_PTE_SAME
+
+#include <asm-generic/pgtable.h>
+
+#endif /* _XTENSA_PGTABLE_H */
diff --git a/include/asm-xtensa/platform-iss/hardware.h b/include/asm-xtensa/platform-iss/hardware.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/platform-iss/hardware.h
@@ -0,0 +1,29 @@
+/*
+ * include/asm-xtensa/platform-iss/hardware.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 Tensilica Inc.
+ */
+
+/*
+ * This file contains the default configuration of ISS.
+ */
+
+#ifndef __ASM_XTENSA_ISS_HARDWARE
+#define __ASM_XTENSA_ISS_HARDWARE
+
+/*
+ * Memory configuration.
+ */
+
+#define PLATFORM_DEFAULT_MEM_START XSHAL_RAM_PADDR
+#define PLATFORM_DEFAULT_MEM_SIZE XSHAL_RAM_VSIZE
+
+/*
+ * Interrupt configuration.
+ */
+
+#endif /* __ASM_XTENSA_ISS_HARDWARE */
diff --git a/include/asm-xtensa/platform.h b/include/asm-xtensa/platform.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/platform.h
@@ -0,0 +1,92 @@
+/*
+ * include/asm-xtensa/platform.h
+ *
+ * Platform specific functions
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file "COPYING" in the main directory of
+ * this archive for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_PLATFORM_H
+#define _XTENSA_PLATFORM_H
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+
+#include <asm/bootparam.h>
+
+/*
+ * platform_init is called before the mmu is initialized to give the
+ * platform a early hook-up. bp_tag_t is a list of configuration tags
+ * passed from the boot-loader.
+ */
+extern void platform_init(bp_tag_t*);
+
+/*
+ * platform_setup is called from setup_arch with a pointer to the command-line
+ * string.
+ */
+extern void platform_setup (char **);
+
+/*
+ * platform_init_irq is called from init_IRQ.
+ */
+extern void platform_init_irq (void);
+
+/*
+ * platform_restart is called to restart the system.
+ */
+extern void platform_restart (void);
+
+/*
+ * platform_halt is called to stop the system and halt.
+ */
+extern void platform_halt (void);
+
+/*
+ * platform_power_off is called to stop the system and power it off.
+ */
+extern void platform_power_off (void);
+
+/*
+ * platform_idle is called from the idle function.
+ */
+extern void platform_idle (void);
+
+/*
+ * platform_heartbeat is called every HZ
+ */
+extern void platform_heartbeat (void);
+
+/*
+ * platform_pcibios_init is called to allow the platform to setup the pci bus.
+ */
+extern void platform_pcibios_init (void);
+
+/*
+ * platform_pcibios_fixup allows to modify the PCI configuration.
+ */
+extern int platform_pcibios_fixup (void);
+
+/*
+ * platform_calibrate_ccount calibrates cpu clock freq (CONFIG_XTENSA_CALIBRATE)
+ */
+extern void platform_calibrate_ccount (void);
+
+/*
+ * platform_get_rtc_time returns RTC seconds (returns 0 for no error)
+ */
+extern int platform_get_rtc_time(time_t*);
+
+/*
+ * platform_set_rtc_time set RTC seconds (returns 0 for no error)
+ */
+extern int platform_set_rtc_time(time_t);
+
+
+#endif	/* _XTENSA_PLATFORM_H */
+
diff --git a/include/asm-xtensa/poll.h b/include/asm-xtensa/poll.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/poll.h
@@ -0,0 +1,37 @@
+/*
+ * include/asm-xtensa/poll.h
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file "COPYING" in the main directory of
+ * this archive for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_POLL_H
+#define _XTENSA_POLL_H
+
+
+#define POLLIN		0x0001
+#define POLLPRI		0x0002
+#define POLLOUT		0x0004
+
+#define POLLERR		0x0008
+#define POLLHUP		0x0010
+#define POLLNVAL	0x0020
+
+#define POLLRDNORM	0x0040
+#define POLLRDBAND	0x0080
+#define POLLWRNORM	POLLOUT
+#define POLLWRBAND	0x0100
+
+#define POLLMSG		0x0400
+#define POLLREMOVE	0x0800
+
+struct pollfd {
+	int fd;
+	short events;
+	short revents;
+};
+
+#endif /* _XTENSA_POLL_H */
diff --git a/include/asm-xtensa/posix_types.h b/include/asm-xtensa/posix_types.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/posix_types.h
@@ -0,0 +1,123 @@
+/*
+ * include/asm-xtensa/posix_types.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Largely copied from include/asm-ppc/posix_types.h
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_POSIX_TYPES_H
+#define _XTENSA_POSIX_TYPES_H
+
+/*
+ * This file is generally used by user-level software, so you need to
+ * be a little careful about namespace pollution etc.  Also, we cannot
+ * assume GCC is being used.
+ */
+
+typedef unsigned long	__kernel_ino_t;
+typedef unsigned int	__kernel_mode_t;
+typedef unsigned short	__kernel_nlink_t;
+typedef long		__kernel_off_t;
+typedef int		__kernel_pid_t;
+typedef unsigned short	__kernel_ipc_pid_t;
+typedef unsigned int	__kernel_uid_t;
+typedef unsigned int	__kernel_gid_t;
+typedef unsigned int	__kernel_size_t;
+typedef int		__kernel_ssize_t;
+typedef long		__kernel_ptrdiff_t;
+typedef long		__kernel_time_t;
+typedef long		__kernel_suseconds_t;
+typedef long		__kernel_clock_t;
+typedef int		__kernel_timer_t;
+typedef int		__kernel_clockid_t;
+typedef int		__kernel_daddr_t;
+typedef char *		__kernel_caddr_t;
+typedef unsigned short	__kernel_uid16_t;
+typedef unsigned short	__kernel_gid16_t;
+typedef unsigned int	__kernel_uid32_t;
+typedef unsigned int	__kernel_gid32_t;
+
+typedef unsigned short	__kernel_old_uid_t;
+typedef unsigned short	__kernel_old_gid_t;
+typedef unsigned short	__kernel_old_dev_t;
+
+#ifdef __GNUC__
+typedef long long	__kernel_loff_t;
+#endif
+
+typedef struct {
+	int	val[2];
+} __kernel_fsid_t;
+
+#ifndef __GNUC__
+
+#define	__FD_SET(d, set)	((set)->fds_bits[__FDELT(d)] |= __FDMASK(d))
+#define	__FD_CLR(d, set)	((set)->fds_bits[__FDELT(d)] &= ~__FDMASK(d))
+#define	__FD_ISSET(d, set)	((set)->fds_bits[__FDELT(d)] & __FDMASK(d))
+#define	__FD_ZERO(set)	\
+  ((void) memset ((__ptr_t) (set), 0, sizeof (__kernel_fd_set)))
+
+#else /* __GNUC__ */
+
+#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) \
+    || (__GLIBC__ == 2 && __GLIBC_MINOR__ == 0)
+/* With GNU C, use inline functions instead so args are evaluated only once: */
+
+#undef __FD_SET
+static __inline__ void __FD_SET(unsigned long fd, __kernel_fd_set *fdsetp)
+{
+	unsigned long _tmp = fd / __NFDBITS;
+	unsigned long _rem = fd % __NFDBITS;
+	fdsetp->fds_bits[_tmp] |= (1UL<<_rem);
+}
+
+#undef __FD_CLR
+static __inline__ void __FD_CLR(unsigned long fd, __kernel_fd_set *fdsetp)
+{
+	unsigned long _tmp = fd / __NFDBITS;
+	unsigned long _rem = fd % __NFDBITS;
+	fdsetp->fds_bits[_tmp] &= ~(1UL<<_rem);
+}
+
+#undef __FD_ISSET
+static __inline__ int __FD_ISSET(unsigned long fd, __kernel_fd_set *p)
+{
+	unsigned long _tmp = fd / __NFDBITS;
+	unsigned long _rem = fd % __NFDBITS;
+	return (p->fds_bits[_tmp] & (1UL<<_rem)) != 0;
+}
+
+/*
+ * This will unroll the loop for the normal constant case (8 ints,
+ * for a 256-bit fd_set)
+ */
+#undef __FD_ZERO
+static __inline__ void __FD_ZERO(__kernel_fd_set *p)
+{
+	unsigned int *tmp = (unsigned int *)p->fds_bits;
+	int i;
+
+	if (__builtin_constant_p(__FDSET_LONGS)) {
+		switch (__FDSET_LONGS) {
+			case 8:
+				tmp[0] = 0; tmp[1] = 0; tmp[2] = 0; tmp[3] = 0;
+				tmp[4] = 0; tmp[5] = 0; tmp[6] = 0; tmp[7] = 0;
+				return;
+		}
+	}
+	i = __FDSET_LONGS;
+	while (i) {
+		i--;
+		*tmp = 0;
+		tmp++;
+	}
+}
+
+#endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */
+#endif /* __GNUC__ */
+#endif /* _XTENSA_POSIX_TYPES_H */
diff --git a/include/asm-xtensa/processor.h b/include/asm-xtensa/processor.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/processor.h
@@ -0,0 +1,205 @@
+/*
+ * include/asm-xtensa/processor.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_PROCESSOR_H
+#define _XTENSA_PROCESSOR_H
+
+#ifdef __ASSEMBLY__
+#define _ASMLANGUAGE
+#endif
+
+#include <xtensa/config/core.h>
+#include <xtensa/config/specreg.h>
+#include <xtensa/config/tie.h>
+#include <xtensa/config/system.h>
+
+#include <asm/ptrace.h>
+#include <asm/types.h>
+#include <asm/coprocessor.h>
+
+/* Assertions. */
+
+#if (XCHAL_HAVE_WINDOWED != 1)
+#error Linux requires the Xtensa Windowed Registers Option.
+#endif
+
+/*
+ * User space process size: 1 GB.
+ * Windowed call ABI requires caller and callee to be located within the same
+ * 1 GB region. The C compiler places trampoline code on the stack for sources
+ * that take the address of a nested C function (a feature used by glibc), so
+ * the 1 GB requirement applies to the stack as well.
+ */
+
+#define TASK_SIZE	0x40000000
+
+/*
+ * General exception cause assigned to debug exceptions. Debug exceptions go
+ * to their own vector, rather than the general exception vectors (user,
+ * kernel, double); and their specific causes are reported via DEBUGCAUSE
+ * rather than EXCCAUSE.  However it is sometimes convenient to redirect debug
+ * exceptions to the general exception mechanism.  To do this, an otherwise
+ * unused EXCCAUSE value was assigned to debug exceptions for this purpose.
+ */
+
+#define EXCCAUSE_MAPPED_DEBUG	63
+
+/*
+ * We use DEPC also as a flag to distinguish between double and regular
+ * exceptions. For performance reasons, DEPC might contain the value of
+ * EXCCAUSE for regular exceptions, so we use this definition to mark a
+ * valid double exception address.
+ * (Note: We use it in bgeui, so it should be 64, 128, or 256)
+ */
+
+#define VALID_DOUBLE_EXCEPTION_ADDRESS	64
+
+/* LOCKLEVEL defines the interrupt level that masks all
+ * general-purpose interrupts.
+ */
+#define LOCKLEVEL 1
+
+/* WSBITS and WBBITS are the width of the WINDOWSTART and WINDOWBASE
+ * registers
+ */
+#define WSBITS  (XCHAL_NUM_AREGS / 4)      /* width of WINDOWSTART in bits */
+#define WBBITS  (XCHAL_NUM_AREGS_LOG2 - 2) /* width of WINDOWBASE in bits */
+
+#ifndef __ASSEMBLY__
+
+/* Build a valid return address for the specified call winsize.
+ * winsize must be 1 (call4), 2 (call8), or 3 (call12)
+ */
+#define MAKE_RA_FOR_CALL(ra,ws)   (((ra) & 0x3fffffff) | (ws) << 30)
+
+/* Convert return address to a valid pc
+ * Note: We assume that the stack pointer is in the same 1GB ranges as the ra
+ */
+#define MAKE_PC_FROM_RA(ra,sp)    (((ra) & 0x3fffffff) | ((sp) & 0xc0000000))
+
+typedef struct {
+    unsigned long seg;
+} mm_segment_t;
+
+struct thread_struct {
+
+	/* kernel's return address and stack pointer for context switching */
+	unsigned long ra; /* kernel's a0: return address and window call size */
+	unsigned long sp; /* kernel's a1: stack pointer */
+
+	mm_segment_t current_ds;    /* see uaccess.h for example uses */
+
+	/* struct xtensa_cpuinfo info; */
+
+	unsigned long bad_vaddr; /* last user fault */
+	unsigned long bad_uaddr; /* last kernel fault accessing user space */
+	unsigned long error_code;
+
+	unsigned long ibreak[XCHAL_NUM_IBREAK];
+	unsigned long dbreaka[XCHAL_NUM_DBREAK];
+	unsigned long dbreakc[XCHAL_NUM_DBREAK];
+
+	/* Allocate storage for extra state and coprocessor state. */
+	unsigned char cp_save[XTENSA_CP_EXTRA_SIZE]
+		__attribute__ ((aligned(XTENSA_CP_EXTRA_ALIGN)));
+
+	/* Make structure 16 bytes aligned. */
+	int align[0] __attribute__ ((aligned(16)));
+};
+
+
+/*
+ * Default implementation of macro that returns current
+ * instruction pointer ("program counter").
+ */
+#define current_text_addr()  ({ __label__ _l; _l: &&_l;})
+
+
+/* This decides where the kernel will search for a free chunk of vm
+ * space during mmap's.
+ */
+#define TASK_UNMAPPED_BASE	(TASK_SIZE / 2)
+
+#define INIT_THREAD  \
+{									\
+	ra:		0, 						\
+	sp:		sizeof(init_stack) + (long) &init_stack,	\
+	current_ds:	{0},						\
+	/*info:		{0}, */						\
+	bad_vaddr:	0,						\
+	bad_uaddr:	0,						\
+	error_code:	0,						\
+}
+
+
+/*
+ * Do necessary setup to start up a newly executed thread.
+ * Note: We set-up ps as if we did a call4 to the new pc.
+ *       set_thread_state in signal.c depends on it.
+ */
+#define USER_PS_VALUE ( (1 << XCHAL_PS_WOE_SHIFT) + \
+                        (1 << XCHAL_PS_CALLINC_SHIFT) + \
+                        (USER_RING << XCHAL_PS_RING_SHIFT) + \
+                        (1 << XCHAL_PS_PROGSTACK_SHIFT) + \
+                        (1 << XCHAL_PS_EXCM_SHIFT) )
+
+/* Clearing a0 terminates the backtrace. */
+#define start_thread(regs, new_pc, new_sp) \
+	regs->pc = new_pc; \
+	regs->ps = USER_PS_VALUE; \
+	regs->areg[1] = new_sp; \
+	regs->areg[0] = 0; \
+	regs->wmask = 1; \
+	regs->depc = 0; \
+	regs->windowbase = 0; \
+	regs->windowstart = 1;
+
+/* Forward declaration */
+struct task_struct;
+struct mm_struct;
+
+// FIXME: do we need release_thread for CP??
+/* Free all resources held by a thread. */
+#define release_thread(thread) do { } while(0)
+
+// FIXME: do we need prepare_to_copy (lazy status) for CP??
+/* Prepare to copy thread state - unlazy all lazy status */
+#define prepare_to_copy(tsk)	do { } while (0)
+
+/*
+ * create a kernel thread without removing it from tasklists
+ */
+extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
+
+/* Copy and release all segment info associated with a VM */
+
+#define copy_segments(p, mm)	do { } while(0)
+#define release_segments(mm)	do { } while(0)
+#define forget_segments()	do { } while (0)
+
+#define thread_saved_pc(tsk)	(xtensa_pt_regs(tsk)->pc)
+
+extern unsigned long get_wchan(struct task_struct *p);
+
+#define KSTK_EIP(tsk)		(xtensa_pt_regs(tsk)->pc)
+#define KSTK_ESP(tsk)		(xtensa_pt_regs(tsk)->areg[1])
+
+#define cpu_relax()  do { } while (0)
+
+/* Special register access. */
+
+#define WSR(v,sr) __asm__ __volatile__ ("wsr %0,"__stringify(sr) :: "a"(v));
+#define RSR(v,sr) __asm__ __volatile__ ("rsr %0,"__stringify(sr) : "=a"(v));
+
+#define set_sr(x,sr) ({unsigned int v=(unsigned int)x; WSR(v,sr);})
+#define get_sr(sr) ({unsigned int v; RSR(v,sr); v; })
+
+#endif	/* __ASSEMBLY__ */
+#endif	/* _XTENSA_PROCESSOR_H */
diff --git a/include/asm-xtensa/ptrace.h b/include/asm-xtensa/ptrace.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/ptrace.h
@@ -0,0 +1,135 @@
+/*
+ * include/asm-xtensa/ptrace.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_PTRACE_H
+#define _XTENSA_PTRACE_H
+
+#include <xtensa/config/core.h>
+
+/*
+ * Kernel stack
+ *
+ * 		+-----------------------+  -------- STACK_SIZE
+ * 		|     register file     |  |
+ * 		+-----------------------+  |
+ * 		|    struct pt_regs     |  |
+ * 		+-----------------------+  | ------ PT_REGS_OFFSET
+ * double 	:  16 bytes spill area  :  |  ^
+ * excetion 	:- - - - - - - - - - - -:  |  |
+ * frame	:    struct pt_regs     :  |  |
+ * 		:- - - - - - - - - - - -:  |  |
+ * 		|                       |  |  |
+ * 		|     memory stack      |  |  |
+ * 		|                       |  |  |
+ * 		~                       ~  ~  ~
+ * 		~                       ~  ~  ~
+ * 		|                       |  |  |
+ * 		|                       |  |  |
+ * 		+-----------------------+  |  | --- STACK_BIAS
+ * 		|  struct task_struct   |  |  |  ^
+ *  current --> +-----------------------+  |  |  |
+ * 		|  struct thread_info   |  |  |  |
+ *		+-----------------------+ --------
+ */
+
+#define KERNEL_STACK_SIZE (2 * PAGE_SIZE)
+
+/*  Offsets for exception_handlers[] (3 x 64-entries x 4-byte tables). */
+
+#define EXC_TABLE_KSTK		0x004	/* Kernel Stack */
+#define EXC_TABLE_DOUBLE_SAVE	0x008	/* Double exception save area for a0 */
+#define EXC_TABLE_FIXUP		0x00c	/* Fixup handler */
+#define EXC_TABLE_PARAM		0x010	/* For passing a parameter to fixup */
+#define EXC_TABLE_SYSCALL_SAVE	0x014	/* For fast syscall handler */
+#define EXC_TABLE_FAST_USER	0x100	/* Fast user exception handler */
+#define EXC_TABLE_FAST_KERNEL	0x200	/* Fast kernel exception handler */
+#define EXC_TABLE_DEFAULT	0x300	/* Default C-Handler */
+#define EXC_TABLE_SIZE		0x400
+
+/* Registers used by strace */
+
+#define REG_A_BASE	0xfc000000
+#define REG_AR_BASE	0x04000000
+#define REG_PC		0x14000000
+#define REG_PS		0x080000e6
+#define REG_WB		0x08000048
+#define REG_WS		0x08000049
+#define REG_LBEG	0x08000000
+#define REG_LEND	0x08000001
+#define REG_LCOUNT	0x08000002
+#define REG_SAR		0x08000003
+#define REG_DEPC	0x080000c0
+#define	REG_EXCCAUSE	0x080000e8
+#define REG_EXCVADDR	0x080000ee
+#define SYSCALL_NR	0x1
+
+#define AR_REGNO_TO_A_REGNO(ar, wb) (ar - wb*4) & ~(XCHAL_NUM_AREGS - 1)
+
+/* Other PTRACE_ values defined in <linux/ptrace.h> using values 0-9,16,17,24 */
+
+#define PTRACE_GETREGS            12
+#define PTRACE_SETREGS            13
+#define PTRACE_GETFPREGS          14
+#define PTRACE_SETFPREGS          15
+#define PTRACE_GETFPREGSIZE       18
+
+#ifndef __ASSEMBLY__
+
+/*
+ * This struct defines the way the registers are stored on the
+ * kernel stack during a system call or other kernel entry.
+ */
+struct pt_regs {
+	unsigned long pc;		/*   4 */
+	unsigned long ps;		/*   8 */
+	unsigned long depc;		/*  12 */
+	unsigned long exccause;		/*  16 */
+	unsigned long excvaddr;		/*  20 */
+	unsigned long debugcause;	/*  24 */
+	unsigned long wmask;		/*  28 */
+	unsigned long lbeg;		/*  32 */
+	unsigned long lend;		/*  36 */
+	unsigned long lcount;		/*  40 */
+	unsigned long sar;		/*  44 */
+	unsigned long windowbase;	/*  48 */
+	unsigned long windowstart;	/*  52 */
+	unsigned long syscall;		/*  56 */
+	int reserved[2];		/*  64 */
+
+	/* Make sure the areg field is 16 bytes aligned. */
+	int align[0] __attribute__ ((aligned(16)));
+
+	/* current register frame.
+	 * Note: The ESF for kernel exceptions ends after 16 registers!
+	 */
+	unsigned long areg[16];		/* 128 (64) */
+};
+
+#ifdef __KERNEL__
+# define xtensa_pt_regs(tsk) ((struct pt_regs*) \
+  (((long)(tsk)->thread_info + KERNEL_STACK_SIZE - (XCHAL_NUM_AREGS-16)*4)) - 1)
+# define user_mode(regs) (((regs)->ps & 0x00000020)!=0)
+# define instruction_pointer(regs) ((regs)->pc)
+extern void show_regs(struct pt_regs *);
+
+# ifndef CONFIG_SMP
+#  define profile_pc(regs) instruction_pointer(regs)
+# endif
+#endif /* __KERNEL__ */
+
+#else	/* __ASSEMBLY__ */
+
+#ifdef __KERNEL__
+# include <asm/offsets.h>
+#define PT_REGS_OFFSET	  (KERNEL_STACK_SIZE - PT_USER_SIZE)
+#endif
+
+#endif	/* !__ASSEMBLY__ */
+#endif	/* _XTENSA_PTRACE_H */
diff --git a/include/asm-xtensa/resource.h b/include/asm-xtensa/resource.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/resource.h
@@ -0,0 +1,16 @@
+/*
+ * include/asm-xtensa/resource.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_RESOURCE_H
+#define _XTENSA_RESOURCE_H
+
+#include <asm-generic/resource.h>
+
+#endif	/* _XTENSA_RESOURCE_H */
diff --git a/include/asm-xtensa/rmap.h b/include/asm-xtensa/rmap.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/rmap.h
@@ -0,0 +1,16 @@
+/*
+ * include/asm-xtensa/rmap.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_RMAP_H
+#define _XTENSA_RMAP_H
+
+#include <asm-generic/rmap.h>
+
+#endif
diff --git a/include/asm-xtensa/rwsem.h b/include/asm-xtensa/rwsem.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/rwsem.h
@@ -0,0 +1,175 @@
+/*
+ * include/asm-xtensa/rwsem.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Largely copied from include/asm-ppc/rwsem.h
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_RWSEM_H
+#define _XTENSA_RWSEM_H
+
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#include <asm/atomic.h>
+#include <asm/system.h>
+
+/*
+ * the semaphore definition
+ */
+struct rw_semaphore {
+	signed long		count;
+#define RWSEM_UNLOCKED_VALUE		0x00000000
+#define RWSEM_ACTIVE_BIAS		0x00000001
+#define RWSEM_ACTIVE_MASK		0x0000ffff
+#define RWSEM_WAITING_BIAS		(-0x00010000)
+#define RWSEM_ACTIVE_READ_BIAS		RWSEM_ACTIVE_BIAS
+#define RWSEM_ACTIVE_WRITE_BIAS		(RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS)
+	spinlock_t		wait_lock;
+	struct list_head	wait_list;
+#if RWSEM_DEBUG
+	int			debug;
+#endif
+};
+
+/*
+ * initialisation
+ */
+#if RWSEM_DEBUG
+#define __RWSEM_DEBUG_INIT      , 0
+#else
+#define __RWSEM_DEBUG_INIT	/* */
+#endif
+
+#define __RWSEM_INITIALIZER(name) \
+	{ RWSEM_UNLOCKED_VALUE, SPIN_LOCK_UNLOCKED, \
+	  LIST_HEAD_INIT((name).wait_list) \
+	  __RWSEM_DEBUG_INIT }
+
+#define DECLARE_RWSEM(name)		\
+	struct rw_semaphore name = __RWSEM_INITIALIZER(name)
+
+extern struct rw_semaphore *rwsem_down_read_failed(struct rw_semaphore *sem);
+extern struct rw_semaphore *rwsem_down_write_failed(struct rw_semaphore *sem);
+extern struct rw_semaphore *rwsem_wake(struct rw_semaphore *sem);
+extern struct rw_semaphore *rwsem_downgrade_wake(struct rw_semaphore *sem);
+
+static inline void init_rwsem(struct rw_semaphore *sem)
+{
+	sem->count = RWSEM_UNLOCKED_VALUE;
+	spin_lock_init(&sem->wait_lock);
+	INIT_LIST_HEAD(&sem->wait_list);
+#if RWSEM_DEBUG
+	sem->debug = 0;
+#endif
+}
+
+/*
+ * lock for reading
+ */
+static inline void __down_read(struct rw_semaphore *sem)
+{
+	if (atomic_add_return(1,(atomic_t *)(&sem->count)) > 0)
+		smp_wmb();
+	else
+		rwsem_down_read_failed(sem);
+}
+
+static inline int __down_read_trylock(struct rw_semaphore *sem)
+{
+	int tmp;
+
+	while ((tmp = sem->count) >= 0) {
+		if (tmp == cmpxchg(&sem->count, tmp,
+				   tmp + RWSEM_ACTIVE_READ_BIAS)) {
+			smp_wmb();
+			return 1;
+		}
+	}
+	return 0;
+}
+
+/*
+ * lock for writing
+ */
+static inline void __down_write(struct rw_semaphore *sem)
+{
+	int tmp;
+
+	tmp = atomic_add_return(RWSEM_ACTIVE_WRITE_BIAS,
+				(atomic_t *)(&sem->count));
+	if (tmp == RWSEM_ACTIVE_WRITE_BIAS)
+		smp_wmb();
+	else
+		rwsem_down_write_failed(sem);
+}
+
+static inline int __down_write_trylock(struct rw_semaphore *sem)
+{
+	int tmp;
+
+	tmp = cmpxchg(&sem->count, RWSEM_UNLOCKED_VALUE,
+		      RWSEM_ACTIVE_WRITE_BIAS);
+	smp_wmb();
+	return tmp == RWSEM_UNLOCKED_VALUE;
+}
+
+/*
+ * unlock after reading
+ */
+static inline void __up_read(struct rw_semaphore *sem)
+{
+	int tmp;
+
+	smp_wmb();
+	tmp = atomic_sub_return(1,(atomic_t *)(&sem->count));
+	if (tmp < -1 && (tmp & RWSEM_ACTIVE_MASK) == 0)
+		rwsem_wake(sem);
+}
+
+/*
+ * unlock after writing
+ */
+static inline void __up_write(struct rw_semaphore *sem)
+{
+	smp_wmb();
+	if (atomic_sub_return(RWSEM_ACTIVE_WRITE_BIAS,
+			      (atomic_t *)(&sem->count)) < 0)
+		rwsem_wake(sem);
+}
+
+/*
+ * implement atomic add functionality
+ */
+static inline void rwsem_atomic_add(int delta, struct rw_semaphore *sem)
+{
+	atomic_add(delta, (atomic_t *)(&sem->count));
+}
+
+/*
+ * downgrade write lock to read lock
+ */
+static inline void __downgrade_write(struct rw_semaphore *sem)
+{
+	int tmp;
+
+	smp_wmb();
+	tmp = atomic_add_return(-RWSEM_WAITING_BIAS, (atomic_t *)(&sem->count));
+	if (tmp < 0)
+		rwsem_downgrade_wake(sem);
+}
+
+/*
+ * implement exchange and add functionality
+ */
+static inline int rwsem_atomic_update(int delta, struct rw_semaphore *sem)
+{
+	smp_mb();
+	return atomic_add_return(delta, (atomic_t *)(&sem->count));
+}
+
+#endif	/* _XTENSA_RWSEM_XADD_H */
diff --git a/include/asm-xtensa/scatterlist.h b/include/asm-xtensa/scatterlist.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/scatterlist.h
@@ -0,0 +1,34 @@
+/*
+ * include/asm-xtensa/scatterlist.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_SCATTERLIST_H
+#define _XTENSA_SCATTERLIST_H
+
+struct scatterlist {
+	struct page 	*page;
+	unsigned int	offset;
+	dma_addr_t	dma_address;
+	unsigned int	length;
+};
+
+/*
+ * These macros should be used after a pci_map_sg call has been done
+ * to get bus addresses of each of the SG entries and their lengths.
+ * You should only work with the number of sg entries pci_map_sg
+ * returns, or alternatively stop on the first sg_dma_len(sg) which
+ * is 0.
+ */
+#define sg_dma_address(sg)      ((sg)->dma_address)
+#define sg_dma_len(sg)          ((sg)->length)
+
+
+#define ISA_DMA_THRESHOLD (~0UL)
+
+#endif	/* _XTENSA_SCATTERLIST_H */
diff --git a/include/asm-xtensa/sections.h b/include/asm-xtensa/sections.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/sections.h
@@ -0,0 +1,16 @@
+/*
+ * include/asm-xtensa/sections.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_SECTIONS_H
+#define _XTENSA_SECTIONS_H
+
+#include <asm-generic/sections.h>
+
+#endif	/* _XTENSA_SECTIONS_H */
diff --git a/include/asm-xtensa/segment.h b/include/asm-xtensa/segment.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/segment.h
@@ -0,0 +1,16 @@
+/*
+ * include/asm-xtensa/segment.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_SEGMENT_H
+#define _XTENSA_SEGMENT_H
+
+#include <asm/uaccess.h>
+
+#endif	/* _XTENSA_SEGEMENT_H */
diff --git a/include/asm-xtensa/semaphore.h b/include/asm-xtensa/semaphore.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/semaphore.h
@@ -0,0 +1,129 @@
+/*
+ * linux/include/asm-xtensa/semaphore.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_SEMAPHORE_H
+#define _XTENSA_SEMAPHORE_H
+
+#include <asm/atomic.h>
+#include <asm/system.h>
+#include <linux/wait.h>
+#include <linux/rwsem.h>
+
+struct semaphore {
+	atomic_t count;
+	int sleepers;
+	wait_queue_head_t wait;
+#if WAITQUEUE_DEBUG
+	long __magic;
+#endif
+};
+
+#if WAITQUEUE_DEBUG
+# define __SEM_DEBUG_INIT(name) \
+		, (int)&(name).__magic
+#else
+# define __SEM_DEBUG_INIT(name)
+#endif
+
+#define __SEMAPHORE_INITIALIZER(name,count)			\
+	{ ATOMIC_INIT(count), 					\
+	  0,							\
+	  __WAIT_QUEUE_HEAD_INITIALIZER((name).wait)		\
+	__SEM_DEBUG_INIT(name) }
+
+#define __MUTEX_INITIALIZER(name) \
+	__SEMAPHORE_INITIALIZER(name, 1)
+
+#define __DECLARE_SEMAPHORE_GENERIC(name,count) \
+	struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
+
+#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1)
+#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0)
+
+extern inline void sema_init (struct semaphore *sem, int val)
+{
+/*
+ *	*sem = (struct semaphore)__SEMAPHORE_INITIALIZER((*sem),val);
+ *
+ * i'd rather use the more flexible initialization above, but sadly
+ * GCC 2.7.2.3 emits a bogus warning. EGCS doesnt. Oh well.
+ */
+	atomic_set(&sem->count, val);
+	init_waitqueue_head(&sem->wait);
+#if WAITQUEUE_DEBUG
+	sem->__magic = (int)&sem->__magic;
+#endif
+}
+
+static inline void init_MUTEX (struct semaphore *sem)
+{
+	sema_init(sem, 1);
+}
+
+static inline void init_MUTEX_LOCKED (struct semaphore *sem)
+{
+	sema_init(sem, 0);
+}
+
+asmlinkage void __down(struct semaphore * sem);
+asmlinkage int  __down_interruptible(struct semaphore * sem);
+asmlinkage int  __down_trylock(struct semaphore * sem);
+asmlinkage void __up(struct semaphore * sem);
+
+extern spinlock_t semaphore_wake_lock;
+
+extern __inline__ void down(struct semaphore * sem)
+{
+#if WAITQUEUE_DEBUG
+	CHECK_MAGIC(sem->__magic);
+#endif
+
+	if (atomic_sub_return(1, &sem->count) < 0)
+		__down(sem);
+}
+
+extern __inline__ int down_interruptible(struct semaphore * sem)
+{
+	int ret = 0;
+#if WAITQUEUE_DEBUG
+	CHECK_MAGIC(sem->__magic);
+#endif
+
+	if (atomic_sub_return(1, &sem->count) < 0)
+		ret = __down_interruptible(sem);
+	return ret;
+}
+
+extern __inline__ int down_trylock(struct semaphore * sem)
+{
+	int ret = 0;
+#if WAITQUEUE_DEBUG
+	CHECK_MAGIC(sem->__magic);
+#endif
+
+	if (atomic_sub_return(1, &sem->count) < 0)
+		ret = __down_trylock(sem);
+	return ret;
+}
+
+/*
+ * Note! This is subtle. We jump to wake people up only if
+ * the semaphore was negative (== somebody was waiting on it).
+ */
+extern __inline__ void up(struct semaphore * sem)
+{
+#if WAITQUEUE_DEBUG
+	CHECK_MAGIC(sem->__magic);
+#endif
+	if (atomic_add_return(1, &sem->count) <= 0)
+		__up(sem);
+}
+
+#endif /* _XTENSA_SEMAPHORE_H */
diff --git a/include/asm-xtensa/sembuf.h b/include/asm-xtensa/sembuf.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/sembuf.h
@@ -0,0 +1,44 @@
+/*
+ * include/asm-xtensa/sembuf.h
+ *
+ * The semid64_ds structure for Xtensa architecture.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ *
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 64-bit time_t to solve y2038 problem
+ * - 2 miscellaneous 32-bit values
+ *
+ */
+
+#ifndef _XTENSA_SEMBUF_H
+#define _XTENSA_SEMBUF_H
+
+#include <asm/byteorder.h>
+
+struct semid64_ds {
+	struct ipc64_perm sem_perm;		/* permissions .. see ipc.h */
+#if XCHAL_HAVE_LE
+	__kernel_time_t	sem_otime;		/* last semop time */
+	unsigned long	__unused1;
+	__kernel_time_t	sem_ctime;		/* last change time */
+	unsigned long	__unused2;
+#else
+	unsigned long	__unused1;
+	__kernel_time_t	sem_otime;		/* last semop time */
+	unsigned long	__unused2;
+	__kernel_time_t	sem_ctime;		/* last change time */
+#endif
+	unsigned long	sem_nsems;		/* no. of semaphores in array */
+	unsigned long	__unused3;
+	unsigned long	__unused4;
+};
+
+#endif /* __ASM_XTENSA_SEMBUF_H */
diff --git a/include/asm-xtensa/serial.h b/include/asm-xtensa/serial.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/serial.h
@@ -0,0 +1,18 @@
+/*
+ * include/asm-xtensa/serial.h
+ *
+ * Configuration details for 8250, 16450, 16550, etc. serial ports
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_SERIAL_H
+#define _XTENSA_SERIAL_H
+
+#include <asm/platform/serial.h>
+
+#endif	/* _XTENSA_SERIAL_H */
diff --git a/include/asm-xtensa/setup.h b/include/asm-xtensa/setup.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/setup.h
@@ -0,0 +1,16 @@
+/*
+ * include/asm-xtensa/setup.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_SETUP_H
+#define _XTENSA_SETUP_H
+
+#define COMMAND_LINE_SIZE	256
+
+#endif
diff --git a/include/asm-xtensa/shmbuf.h b/include/asm-xtensa/shmbuf.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/shmbuf.h
@@ -0,0 +1,50 @@
+/*
+ * include/asm-xtensa/shmbuf.h
+ *
+ * The shmid64_ds structure for Xtensa architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 64-bit time_t to solve y2038 problem
+ * - 2 miscellaneous 32-bit values
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_SHMBUF_H
+#define _XTENSA_SHMBUF_H
+
+struct shmid64_ds {
+	struct ipc64_perm	shm_perm;	/* operation perms */
+	size_t			shm_segsz;	/* size of segment (bytes) */
+	__kernel_time_t		shm_atime;	/* last attach time */
+	unsigned long		__unused1;
+	__kernel_time_t		shm_dtime;	/* last detach time */
+	unsigned long		__unused2;
+	__kernel_time_t		shm_ctime;	/* last change time */
+	unsigned long		__unused3;
+	__kernel_pid_t		shm_cpid;	/* pid of creator */
+	__kernel_pid_t		shm_lpid;	/* pid of last operator */
+	unsigned long		shm_nattch;	/* no. of current attaches */
+	unsigned long		__unused4;
+	unsigned long		__unused5;
+};
+
+struct shminfo64 {
+	unsigned long	shmmax;
+	unsigned long	shmmin;
+	unsigned long	shmmni;
+	unsigned long	shmseg;
+	unsigned long	shmall;
+	unsigned long	__unused1;
+	unsigned long	__unused2;
+	unsigned long	__unused3;
+	unsigned long	__unused4;
+};
+
+#endif	/* _XTENSA_SHMBUF_H */
diff --git a/include/asm-xtensa/shmparam.h b/include/asm-xtensa/shmparam.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/shmparam.h
@@ -0,0 +1,23 @@
+/*
+ * include/asm-xtensa/shmparam.h
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file "COPYING" in the main directory of
+ * this archive for more details.
+ */
+
+#ifndef _XTENSA_SHMPARAM_H
+#define _XTENSA_SHMPARAM_H
+
+#include <asm/processor.h>
+
+/*
+ * Xtensa can have variable size caches, and if
+ * the size of single way is larger than the page size,
+ * then we have to start worrying about cache aliasing
+ * problems.
+ */
+
+#define SHMLBA	((PAGE_SIZE > DCACHE_WAY_SIZE)? PAGE_SIZE : DCACHE_WAY_SIZE)
+
+#endif /* _XTENSA_SHMPARAM_H */
diff --git a/include/asm-xtensa/sigcontext.h b/include/asm-xtensa/sigcontext.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/sigcontext.h
@@ -0,0 +1,44 @@
+/*
+ * include/asm-xtensa/sigcontext.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2003 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_SIGCONTEXT_H
+#define _XTENSA_SIGCONTEXT_H
+
+#define _ASMLANGUAGE
+#include <asm/processor.h>
+#include <asm/coprocessor.h>
+
+
+struct _cpstate {
+	unsigned char _cpstate[XTENSA_CP_EXTRA_SIZE];
+} __attribute__ ((aligned (XTENSA_CP_EXTRA_ALIGN)));
+
+
+struct sigcontext {
+	unsigned long	oldmask;
+
+	/* CPU registers */
+	unsigned long sc_pc;
+	unsigned long sc_ps;
+	unsigned long sc_wmask;
+	unsigned long sc_windowbase;
+	unsigned long sc_windowstart;
+	unsigned long sc_lbeg;
+	unsigned long sc_lend;
+	unsigned long sc_lcount;
+	unsigned long sc_sar;
+	unsigned long sc_depc;
+	unsigned long sc_dareg0;
+	unsigned long sc_treg[4];
+	unsigned long sc_areg[XCHAL_NUM_AREGS];
+	struct _cpstate *sc_cpstate;
+};
+
+#endif /* __ASM_XTENSA_SIGCONTEXT_H */
diff --git a/include/asm-xtensa/siginfo.h b/include/asm-xtensa/siginfo.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/siginfo.h
@@ -0,0 +1,16 @@
+/*
+ * include/asm-xtensa/processor.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_SIGINFO_H
+#define _XTENSA_SIGINFO_H
+
+#include <asm-generic/siginfo.h>
+
+#endif	/* _XTENSA_SIGINFO_H */
diff --git a/include/asm-xtensa/signal.h b/include/asm-xtensa/signal.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/signal.h
@@ -0,0 +1,187 @@
+/*
+ * include/asm-xtensa/signal.h
+ *
+ * Swiped from SH.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_SIGNAL_H
+#define _XTENSA_SIGNAL_H
+
+
+#define _NSIG		64
+#define _NSIG_BPW	32
+#define _NSIG_WORDS	(_NSIG / _NSIG_BPW)
+
+#ifndef __ASSEMBLY__
+
+#include <linux/types.h>
+
+/* Avoid too many header ordering problems.  */
+struct siginfo;
+typedef unsigned long old_sigset_t;		/* at least 32 bits */
+typedef struct {
+	unsigned long sig[_NSIG_WORDS];
+} sigset_t;
+
+#endif
+
+#define SIGHUP		 1
+#define SIGINT		 2
+#define SIGQUIT		 3
+#define SIGILL		 4
+#define SIGTRAP		 5
+#define SIGABRT		 6
+#define SIGIOT		 6
+#define SIGBUS		 7
+#define SIGFPE		 8
+#define SIGKILL		 9
+#define SIGUSR1		10
+#define SIGSEGV		11
+#define SIGUSR2		12
+#define SIGPIPE		13
+#define SIGALRM		14
+#define SIGTERM		15
+#define SIGSTKFLT	16
+#define SIGCHLD		17
+#define SIGCONT		18
+#define SIGSTOP		19
+#define SIGTSTP		20
+#define SIGTTIN		21
+#define SIGTTOU		22
+#define SIGURG		23
+#define SIGXCPU		24
+#define SIGXFSZ		25
+#define SIGVTALRM	26
+#define SIGPROF		27
+#define SIGWINCH	28
+#define SIGIO		29
+#define SIGPOLL		SIGIO
+/* #define SIGLOST		29 */
+#define SIGPWR		30
+#define SIGSYS		31
+#define	SIGUNUSED	31
+
+/* These should not be considered constants from userland.  */
+#define SIGRTMIN	32
+#define SIGRTMAX	(_NSIG-1)
+
+/*
+ * SA_FLAGS values:
+ *
+ * SA_ONSTACK indicates that a registered stack_t will be used.
+ * SA_INTERRUPT is a no-op, but left due to historical reasons. Use the
+ * SA_RESTART flag to get restarting signals (which were the default long ago)
+ * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
+ * SA_RESETHAND clears the handler when the signal is delivered.
+ * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies.
+ * SA_NODEFER prevents the current signal from being masked in the handler.
+ *
+ * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
+ * Unix names RESETHAND and NODEFER respectively.
+ */
+#define SA_NOCLDSTOP	0x00000001
+#define SA_NOCLDWAIT	0x00000002 /* not supported yet */
+#define SA_SIGINFO	0x00000004
+#define SA_ONSTACK	0x08000000
+#define SA_RESTART	0x10000000
+#define SA_NODEFER	0x40000000
+#define SA_RESETHAND	0x80000000
+
+#define SA_NOMASK	SA_NODEFER
+#define SA_ONESHOT	SA_RESETHAND
+#define SA_INTERRUPT	0x20000000 /* dummy -- ignored */
+
+#define SA_RESTORER	0x04000000
+
+/*
+ * sigaltstack controls
+ */
+#define SS_ONSTACK	1
+#define SS_DISABLE	2
+
+#define MINSIGSTKSZ	2048
+#define SIGSTKSZ	8192
+
+#ifndef __ASSEMBLY__
+#ifdef __KERNEL__
+
+/*
+ * These values of sa_flags are used only by the kernel as part of the
+ * irq handling routines.
+ *
+ * SA_INTERRUPT is also used by the irq handling routines.
+ * SA_SHIRQ is for shared interrupt support on PCI and EISA.
+ */
+#define SA_PROBE		SA_ONESHOT
+#define SA_SAMPLE_RANDOM	SA_RESTART
+#define SA_SHIRQ		0x04000000
+#endif
+
+#define SIG_BLOCK          0	/* for blocking signals */
+#define SIG_UNBLOCK        1	/* for unblocking signals */
+#define SIG_SETMASK        2	/* for setting the signal mask */
+
+/* Type of a signal handler.  */
+typedef void (*__sighandler_t)(int);
+
+#define SIG_DFL	((__sighandler_t)0)	/* default signal handling */
+#define SIG_IGN	((__sighandler_t)1)	/* ignore signal */
+#define SIG_ERR	((__sighandler_t)-1)	/* error return from signal */
+
+#ifdef __KERNEL__
+struct old_sigaction {
+	__sighandler_t sa_handler;
+	old_sigset_t sa_mask;
+	unsigned long sa_flags;
+	void (*sa_restorer)(void);
+};
+
+struct sigaction {
+	__sighandler_t sa_handler;
+	unsigned long sa_flags;
+	void (*sa_restorer)(void);
+	sigset_t sa_mask;		/* mask last for extensibility */
+};
+
+struct k_sigaction {
+	struct sigaction sa;
+};
+
+#else
+
+/* Here we must cater to libcs that poke about in kernel headers.  */
+
+struct sigaction {
+	union {
+	  __sighandler_t _sa_handler;
+	  void (*_sa_sigaction)(int, struct siginfo *, void *);
+	} _u;
+	sigset_t sa_mask;
+	unsigned long sa_flags;
+	void (*sa_restorer)(void);
+};
+
+#define sa_handler	_u._sa_handler
+#define sa_sigaction	_u._sa_sigaction
+
+#endif /* __KERNEL__ */
+
+typedef struct sigaltstack {
+	void *ss_sp;
+	int ss_flags;
+	size_t ss_size;
+} stack_t;
+
+#ifdef __KERNEL__
+#include <asm/sigcontext.h>
+#define ptrace_signal_deliver(regs, cookie) do { } while (0)
+
+#endif	/* __KERNEL__ */
+#endif	/* __ASSEMBLY__ */
+#endif	/* _XTENSA_SIGNAL_H */
diff --git a/include/asm-xtensa/smp.h b/include/asm-xtensa/smp.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/smp.h
@@ -0,0 +1,27 @@
+/*
+ * include/asm-xtensa/smp.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_SMP_H
+#define _XTENSA_SMP_H
+
+extern struct xtensa_cpuinfo boot_cpu_data;
+
+#define cpu_data (&boot_cpu_data)
+#define current_cpu_data boot_cpu_data
+
+struct xtensa_cpuinfo {
+	unsigned long	*pgd_cache;
+	unsigned long	*pte_cache;
+	unsigned long	pgtable_cache_sz;
+};
+
+#define cpu_logical_map(cpu)	(cpu)
+
+#endif	/* _XTENSA_SMP_H */
diff --git a/include/asm-xtensa/socket.h b/include/asm-xtensa/socket.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/socket.h
@@ -0,0 +1,61 @@
+/*
+ * include/asm-xtensa/socket.h
+ *
+ * Copied from i386.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef _XTENSA_SOCKET_H
+#define _XTENSA_SOCKET_H
+
+#include <asm/sockios.h>
+
+/* For setsockoptions(2) */
+#define SOL_SOCKET	1
+
+#define SO_DEBUG	1
+#define SO_REUSEADDR	2
+#define SO_TYPE		3
+#define SO_ERROR	4
+#define SO_DONTROUTE	5
+#define SO_BROADCAST	6
+#define SO_SNDBUF	7
+#define SO_RCVBUF	8
+#define SO_KEEPALIVE	9
+#define SO_OOBINLINE	10
+#define SO_NO_CHECK	11
+#define SO_PRIORITY	12
+#define SO_LINGER	13
+#define SO_BSDCOMPAT	14
+/* To add :#define SO_REUSEPORT 15 */
+#define SO_PASSCRED	16
+#define SO_PEERCRED	17
+#define SO_RCVLOWAT	18
+#define SO_SNDLOWAT	19
+#define SO_RCVTIMEO	20
+#define SO_SNDTIMEO	21
+
+/* Security levels - as per NRL IPv6 - don't actually do anything */
+
+#define SO_SECURITY_AUTHENTICATION		22
+#define SO_SECURITY_ENCRYPTION_TRANSPORT	23
+#define SO_SECURITY_ENCRYPTION_NETWORK		24
+
+#define SO_BINDTODEVICE	25
+
+/* Socket filtering */
+
+#define SO_ATTACH_FILTER        26
+#define SO_DETACH_FILTER        27
+
+#define SO_PEERNAME		28
+#define SO_TIMESTAMP		29
+#define SCM_TIMESTAMP		SO_TIMESTAMP
+
+#define SO_ACCEPTCONN		30
+#define SO_PEERSEC		31
+
+#endif	/* _XTENSA_SOCKET_H */
diff --git a/include/asm-xtensa/sockios.h b/include/asm-xtensa/sockios.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/sockios.h
@@ -0,0 +1,30 @@
+/*
+ * include/asm-xtensa/sockios.h
+ *
+ * Socket-level I/O control calls.  Copied from MIPS.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995 by Ralf Baechle
+ * Copyright (C) 2001 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_SOCKIOS_H
+#define _XTENSA_SOCKIOS_H
+
+#include <asm/ioctl.h>
+
+/* Socket-level I/O control calls. */
+
+#define FIOGETOWN	_IOR('f', 123, int)
+#define FIOSETOWN 	_IOW('f', 124, int)
+
+#define SIOCATMARK	_IOR('s', 7, int)
+#define SIOCSPGRP	_IOW('s', 8, pid_t)
+#define SIOCGPGRP	_IOR('s', 9, pid_t)
+
+#define SIOCGSTAMP	0x8906		/* Get stamp - linux-specific */
+
+#endif	/* _XTENSA_SOCKIOS_H */
diff --git a/include/asm-xtensa/spinlock.h b/include/asm-xtensa/spinlock.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/spinlock.h
@@ -0,0 +1,16 @@
+/*
+ * include/asm-xtensa/spinlock.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_SPINLOCK_H
+#define _XTENSA_SPINLOCK_H
+
+#include <linux/spinlock.h>
+
+#endif	/* _XTENSA_SPINLOCK_H */
diff --git a/include/asm-xtensa/stat.h b/include/asm-xtensa/stat.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/stat.h
@@ -0,0 +1,105 @@
+/*
+ * include/asm-xtensa/stat.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_STAT_H
+#define _XTENSA_STAT_H
+
+#include <linux/types.h>
+
+struct __old_kernel_stat {
+	unsigned short st_dev;
+	unsigned short st_ino;
+	unsigned short st_mode;
+	unsigned short st_nlink;
+	unsigned short st_uid;
+	unsigned short st_gid;
+	unsigned short st_rdev;
+	unsigned long  st_size;
+	unsigned long  st_atime;
+	unsigned long  st_mtime;
+	unsigned long  st_ctime;
+};
+
+#define STAT_HAVE_NSEC 1
+
+struct stat {
+	unsigned short st_dev;
+	unsigned short __pad1;
+	unsigned long st_ino;
+	unsigned short st_mode;
+	unsigned short st_nlink;
+	unsigned short st_uid;
+	unsigned short st_gid;
+	unsigned short st_rdev;
+	unsigned short __pad2;
+	unsigned long  st_size;
+	unsigned long  st_blksize;
+	unsigned long  st_blocks;
+	unsigned long  st_atime;
+	unsigned long  st_atime_nsec;
+	unsigned long  st_mtime;
+	unsigned long  st_mtime_nsec;
+	unsigned long  st_ctime;
+	unsigned long  st_ctime_nsec;
+	unsigned long  __unused4;
+	unsigned long  __unused5;
+};
+
+/* This matches struct stat64 in glibc-2.2.3. */
+
+struct stat64  {
+#ifdef __XTENSA_EL__
+	unsigned short	st_dev;		/* Device */
+	unsigned char	__pad0[10];
+#else
+	unsigned char	__pad0[6];
+	unsigned short	st_dev;
+	unsigned char	__pad1[2];
+#endif
+
+#define STAT64_HAS_BROKEN_ST_INO	1
+	unsigned long __st_ino;		/* 32bit file serial number. */
+
+	unsigned int  st_mode;		/* File mode. */
+	unsigned int  st_nlink;		/* Link count. */
+	unsigned int  st_uid;		/* User ID of the file's owner. */
+	unsigned int  st_gid;		/* Group ID of the file's group. */
+
+#ifdef __XTENSA_EL__
+	unsigned short	st_rdev;	/* Device number, if device. */
+	unsigned char	__pad3[10];
+#else
+	unsigned char	__pad2[6];
+	unsigned short	st_rdev;
+	unsigned char	__pad3[2];
+#endif
+
+	long long int  st_size;		/* Size of file, in bytes. */
+	long int st_blksize;		/* Optimal block size for I/O. */
+
+#ifdef __XTENSA_EL__
+	unsigned long  st_blocks;	/* Number 512-byte blocks allocated. */
+	unsigned long  __pad4;
+#else
+	unsigned long  __pad4;
+	unsigned long  st_blocks;
+#endif
+
+	unsigned long  __pad5;
+	long int st_atime;		/* Time of last access. */
+	unsigned long  st_atime_nsec;
+	long int st_mtime;		/* Time of last modification. */
+	unsigned long  st_mtime_nsec;
+	long int  st_ctime;		/* Time of last status change. */
+	unsigned long  st_ctime_nsec;
+	unsigned long long int st_ino;	/* File serial number. */
+};
+
+#endif	/* _XTENSA_STAT_H */
diff --git a/include/asm-xtensa/statfs.h b/include/asm-xtensa/statfs.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/statfs.h
@@ -0,0 +1,17 @@
+/*
+ * include/asm-xtensa/statfs.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_STATFS_H
+#define _XTENSA_STATFS_H
+
+#include <asm-generic/statfs.h>
+
+#endif	/* _XTENSA_STATFS_H */
+
diff --git a/include/asm-xtensa/string.h b/include/asm-xtensa/string.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/string.h
@@ -0,0 +1,124 @@
+/*
+ * include/asm-xtensa/string.h
+ *
+ * These trivial string functions are considered part of the public domain.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+/* We should optimize these. See arch/xtensa/lib/strncpy_user.S */
+
+#ifndef _XTENSA_STRING_H
+#define _XTENSA_STRING_H
+
+#define __HAVE_ARCH_STRCPY
+extern __inline__ char *strcpy(char *__dest, const char *__src)
+{
+	register char *__xdest = __dest;
+	unsigned long __dummy;
+
+	__asm__ __volatile__("1:\n\t"
+		"l8ui	%2, %1, 0\n\t"
+		"s8i	%2, %0, 0\n\t"
+		"addi	%1, %1, 1\n\t"
+		"addi	%0, %0, 1\n\t"
+		"bnez	%2, 1b\n\t"
+		: "=r" (__dest), "=r" (__src), "=&r" (__dummy)
+		: "0" (__dest), "1" (__src)
+		: "memory");
+
+	return __xdest;
+}
+
+#define __HAVE_ARCH_STRNCPY
+extern __inline__ char *strncpy(char *__dest, const char *__src, size_t __n)
+{
+	register char *__xdest = __dest;
+	unsigned long __dummy;
+
+	if (__n == 0)
+		return __xdest;
+
+	__asm__ __volatile__(
+		"1:\n\t"
+		"l8ui	%2, %1, 0\n\t"
+		"s8i	%2, %0, 0\n\t"
+		"addi	%1, %1, 1\n\t"
+		"addi	%0, %0, 1\n\t"
+		"beqz	%2, 2f\n\t"
+		"bne	%1, %5, 1b\n"
+		"2:"
+		: "=r" (__dest), "=r" (__src), "=&r" (__dummy)
+		: "0" (__dest), "1" (__src), "r" (__src+__n)
+		: "memory");
+
+	return __xdest;
+}
+
+#define __HAVE_ARCH_STRCMP
+extern __inline__ int strcmp(const char *__cs, const char *__ct)
+{
+	register int __res;
+	unsigned long __dummy;
+
+	__asm__ __volatile__(
+		"1:\n\t"
+		"l8ui	%3, %1, 0\n\t"
+		"addi	%1, %1, 1\n\t"
+		"l8ui	%2, %0, 0\n\t"
+		"addi	%0, %0, 1\n\t"
+		"beqz	%2, 2f\n\t"
+		"beq	%2, %3, 1b\n"
+		"2:\n\t"
+		"sub	%2, %3, %2"
+		: "=r" (__cs), "=r" (__ct), "=&r" (__res), "=&r" (__dummy)
+		: "0" (__cs), "1" (__ct));
+
+	return __res;
+}
+
+#define __HAVE_ARCH_STRNCMP
+extern __inline__ int strncmp(const char *__cs, const char *__ct, size_t __n)
+{
+	register int __res;
+	unsigned long __dummy;
+
+	__asm__ __volatile__(
+		"mov	%2, %3\n"
+		"1:\n\t"
+		"beq	%0, %6, 2f\n\t"
+		"l8ui	%3, %1, 0\n\t"
+		"addi	%1, %1, 1\n\t"
+		"l8ui	%2, %0, 0\n\t"
+		"addi	%0, %0, 1\n\t"
+		"beqz	%2, 2f\n\t"
+		"beqz	%3, 2f\n\t"
+		"beq	%2, %3, 1b\n"
+		"2:\n\t"
+		"sub	%2, %3, %2"
+		: "=r" (__cs), "=r" (__ct), "=&r" (__res), "=&r" (__dummy)
+		: "0" (__cs), "1" (__ct), "r" (__cs+__n));
+
+	return __res;
+}
+
+#define __HAVE_ARCH_MEMSET
+extern void *memset(void *__s, int __c, size_t __count);
+
+#define __HAVE_ARCH_MEMCPY
+extern void *memcpy(void *__to, __const__ void *__from, size_t __n);
+
+#define __HAVE_ARCH_MEMMOVE
+extern void *memmove(void *__dest, __const__ void *__src, size_t __n);
+
+/* Don't build bcopy at all ...  */
+#define __HAVE_ARCH_BCOPY
+
+#define __HAVE_ARCH_MEMSCAN
+#define memscan memchr
+
+#endif	/* _XTENSA_STRING_H */
diff --git a/include/asm-xtensa/system.h b/include/asm-xtensa/system.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/system.h
@@ -0,0 +1,252 @@
+/*
+ * include/asm-xtensa/system.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_SYSTEM_H
+#define _XTENSA_SYSTEM_H
+
+#include <linux/config.h>
+#include <linux/stringify.h>
+
+#include <asm/processor.h>
+
+/* interrupt control */
+
+#define local_save_flags(x)						\
+	__asm__ __volatile__ ("rsr %0,"__stringify(PS) : "=a" (x));
+#define local_irq_restore(x)	do {					\
+	__asm__ __volatile__ ("wsr %0, "__stringify(PS)" ; rsync" 	\
+	    		      :: "a" (x) : "memory"); } while(0);
+#define local_irq_save(x)	do {					\
+	__asm__ __volatile__ ("rsil %0, "__stringify(LOCKLEVEL) 	\
+	    		      : "=a" (x) :: "memory");} while(0);
+
+static inline void local_irq_disable(void)
+{
+	unsigned long flags;
+	__asm__ __volatile__ ("rsil %0, "__stringify(LOCKLEVEL)
+	    		      : "=a" (flags) :: "memory");
+}
+static inline void local_irq_enable(void)
+{
+	unsigned long flags;
+	__asm__ __volatile__ ("rsil %0, 0" : "=a" (flags) :: "memory");
+
+}
+
+static inline int irqs_disabled(void)
+{
+	unsigned long flags;
+	local_save_flags(flags);
+	return flags & 0xf;
+}
+
+#define RSR_CPENABLE(x)	do {						  \
+	__asm__ __volatile__("rsr %0," __stringify(CPENABLE) : "=a" (x)); \
+	} while(0);
+#define WSR_CPENABLE(x)	do {						  \
+  	__asm__ __volatile__("wsr %0," __stringify(CPENABLE)";rsync" 	  \
+	    		     :: "a" (x));} while(0);
+
+#define clear_cpenable() __clear_cpenable()
+
+extern __inline__ void __clear_cpenable(void)
+{
+#if XCHAL_HAVE_CP
+	unsigned long i = 0;
+	WSR_CPENABLE(i);
+#endif
+}
+
+extern __inline__ void enable_coprocessor(int i)
+{
+#if XCHAL_HAVE_CP
+	int cp;
+	RSR_CPENABLE(cp);
+	cp |= 1 << i;
+	WSR_CPENABLE(cp);
+#endif
+}
+
+extern __inline__ void disable_coprocessor(int i)
+{
+#if XCHAL_HAVE_CP
+	int cp;
+	RSR_CPENABLE(cp);
+	cp &= ~(1 << i);
+	WSR_CPENABLE(cp);
+#endif
+}
+
+#define smp_read_barrier_depends() do { } while(0)
+#define read_barrier_depends() do { } while(0)
+
+#define mb()  barrier()
+#define rmb() mb()
+#define wmb() mb()
+
+#ifdef CONFIG_SMP
+#error smp_* not defined
+#else
+#define smp_mb()	barrier()
+#define smp_rmb()	barrier()
+#define smp_wmb()	barrier()
+#endif
+
+#define set_mb(var, value)	do { var = value; mb(); } while (0)
+#define set_wmb(var, value)	do { var = value; wmb(); } while (0)
+
+#if !defined (__ASSEMBLY__)
+
+/* * switch_to(n) should switch tasks to task nr n, first
+ * checking that n isn't the current task, in which case it does nothing.
+ */
+extern void *_switch_to(void *last, void *next);
+
+#endif	/* __ASSEMBLY__ */
+
+#define prepare_to_switch()	do { } while(0)
+
+#define switch_to(prev,next,last)		\
+do {						\
+	clear_cpenable();			\
+	(last) = _switch_to(prev, next);	\
+} while(0)
+
+/*
+ * cmpxchg
+ */
+
+extern __inline__ unsigned long
+__cmpxchg_u32(volatile int *p, int old, int new)
+{
+  __asm__ __volatile__("rsil    a15, "__stringify(LOCKLEVEL)"\n\t"
+		       "l32i    %0, %1, 0              \n\t"
+		       "bne	%0, %2, 1f             \n\t"
+		       "s32i    %3, %1, 0              \n\t"
+		       "1:                             \n\t"
+		       "wsr     a15, "__stringify(PS)" \n\t"
+		       "rsync                          \n\t"
+		       : "=&a" (old)
+		       : "a" (p), "a" (old), "r" (new)
+		       : "a15", "memory");
+  return old;
+}
+/* This function doesn't exist, so you'll get a linker error
+ * if something tries to do an invalid cmpxchg(). */
+
+extern void __cmpxchg_called_with_bad_pointer(void);
+
+static __inline__ unsigned long
+__cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
+{
+	switch (size) {
+	case 4:  return __cmpxchg_u32(ptr, old, new);
+	default: __cmpxchg_called_with_bad_pointer();
+		 return old;
+	}
+}
+
+#define cmpxchg(ptr,o,n)						      \
+	({ __typeof__(*(ptr)) _o_ = (o);				      \
+	   __typeof__(*(ptr)) _n_ = (n);				      \
+	   (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_,	      \
+	   			        (unsigned long)_n_, sizeof (*(ptr))); \
+	})
+
+
+
+
+/*
+ * xchg_u32
+ *
+ * Note that a15 is used here because the register allocation
+ * done by the compiler is not guaranteed and a window overflow
+ * may not occur between the rsil and wsr instructions. By using
+ * a15 in the rsil, the machine is guaranteed to be in a state
+ * where no register reference will cause an overflow.
+ */
+
+extern __inline__ unsigned long xchg_u32(volatile int * m, unsigned long val)
+{
+  unsigned long tmp;
+  __asm__ __volatile__("rsil    a15, "__stringify(LOCKLEVEL)"\n\t"
+		       "l32i    %0, %1, 0              \n\t"
+		       "s32i    %2, %1, 0              \n\t"
+		       "wsr     a15, "__stringify(PS)" \n\t"
+		       "rsync                          \n\t"
+		       : "=&a" (tmp)
+		       : "a" (m), "a" (val)
+		       : "a15", "memory");
+  return tmp;
+}
+
+#define tas(ptr) (xchg((ptr),1))
+
+#if ( __XCC__ == 1 )
+
+/* xt-xcc processes __inline__ differently than xt-gcc and decides to
+ * insert an out-of-line copy of function __xchg.  This presents the
+ * unresolved symbol at link time of __xchg_called_with_bad_pointer,
+ * even though such a function would never be called at run-time.
+ * xt-gcc always inlines __xchg, and optimizes away the undefined
+ * bad_pointer function.
+ */
+
+#define xchg(ptr,x) xchg_u32(ptr,x)
+
+#else  /* assume xt-gcc */
+
+#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
+
+/*
+ * This only works if the compiler isn't horribly bad at optimizing.
+ * gcc-2.5.8 reportedly can't handle this, but I define that one to
+ * be dead anyway.
+ */
+
+extern void __xchg_called_with_bad_pointer(void);
+
+static __inline__ unsigned long
+__xchg(unsigned long x, volatile void * ptr, int size)
+{
+	switch (size) {
+		case 4:
+			return xchg_u32(ptr, x);
+	}
+	__xchg_called_with_bad_pointer();
+	return x;
+}
+
+#endif
+
+extern void set_except_vector(int n, void *addr);
+
+static inline void spill_registers(void)
+{
+	unsigned int a0, ps;
+
+	__asm__ __volatile__ (
+		"movi	a14," __stringify (PS_EXCM_MASK) " | 1\n\t"
+		"mov	a12, a0\n\t"
+		"rsr	a13," __stringify(SAR) "\n\t"
+		"xsr	a14," __stringify(PS) "\n\t"
+		"movi	a0, _spill_registers\n\t"
+		"rsync\n\t"
+		"callx0 a0\n\t"
+		"mov	a0, a12\n\t"
+		"wsr	a13," __stringify(SAR) "\n\t"
+		"wsr	a14," __stringify(PS) "\n\t"
+		:: "a" (&a0), "a" (&ps)
+		: "a2", "a3", "a12", "a13", "a14", "a15", "memory");
+}
+
+#define arch_align_stack(x) (x)
+
+#endif	/* _XTENSA_SYSTEM_H */
diff --git a/include/asm-xtensa/termbits.h b/include/asm-xtensa/termbits.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/termbits.h
@@ -0,0 +1,194 @@
+/*
+ * include/asm-xtensa/termbits.h
+ *
+ * Copied from SH.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_TERMBITS_H
+#define _XTENSA_TERMBITS_H
+
+
+#include <linux/posix_types.h>
+
+typedef unsigned char	cc_t;
+typedef unsigned int	speed_t;
+typedef unsigned int	tcflag_t;
+
+#define NCCS 19
+struct termios {
+	tcflag_t c_iflag;		/* input mode flags */
+	tcflag_t c_oflag;		/* output mode flags */
+	tcflag_t c_cflag;		/* control mode flags */
+	tcflag_t c_lflag;		/* local mode flags */
+	cc_t c_line;			/* line discipline */
+	cc_t c_cc[NCCS];		/* control characters */
+};
+
+/* c_cc characters */
+
+#define VINTR 0
+#define VQUIT 1
+#define VERASE 2
+#define VKILL 3
+#define VEOF 4
+#define VTIME 5
+#define VMIN 6
+#define VSWTC 7
+#define VSTART 8
+#define VSTOP 9
+#define VSUSP 10
+#define VEOL 11
+#define VREPRINT 12
+#define VDISCARD 13
+#define VWERASE 14
+#define VLNEXT 15
+#define VEOL2 16
+
+/* c_iflag bits */
+
+#define IGNBRK	0000001
+#define BRKINT	0000002
+#define IGNPAR	0000004
+#define PARMRK	0000010
+#define INPCK	0000020
+#define ISTRIP	0000040
+#define INLCR	0000100
+#define IGNCR	0000200
+#define ICRNL	0000400
+#define IUCLC	0001000
+#define IXON	0002000
+#define IXANY	0004000
+#define IXOFF	0010000
+#define IMAXBEL	0020000
+#define IUTF8	0040000
+
+/* c_oflag bits */
+
+#define OPOST	0000001
+#define OLCUC	0000002
+#define ONLCR	0000004
+#define OCRNL	0000010
+#define ONOCR	0000020
+#define ONLRET	0000040
+#define OFILL	0000100
+#define OFDEL	0000200
+#define NLDLY	0000400
+#define   NL0	0000000
+#define   NL1	0000400
+#define CRDLY	0003000
+#define   CR0	0000000
+#define   CR1	0001000
+#define   CR2	0002000
+#define   CR3	0003000
+#define TABDLY	0014000
+#define   TAB0	0000000
+#define   TAB1	0004000
+#define   TAB2	0010000
+#define   TAB3	0014000
+#define   XTABS	0014000
+#define BSDLY	0020000
+#define   BS0	0000000
+#define   BS1	0020000
+#define VTDLY	0040000
+#define   VT0	0000000
+#define   VT1	0040000
+#define FFDLY	0100000
+#define   FF0	0000000
+#define   FF1	0100000
+
+/* c_cflag bit meaning */
+
+#define CBAUD	0010017
+#define  B0	0000000		/* hang up */
+#define  B50	0000001
+#define  B75	0000002
+#define  B110	0000003
+#define  B134	0000004
+#define  B150	0000005
+#define  B200	0000006
+#define  B300	0000007
+#define  B600	0000010
+#define  B1200	0000011
+#define  B1800	0000012
+#define  B2400	0000013
+#define  B4800	0000014
+#define  B9600	0000015
+#define  B19200	0000016
+#define  B38400	0000017
+#define EXTA B19200
+#define EXTB B38400
+#define CSIZE	0000060
+#define   CS5	0000000
+#define   CS6	0000020
+#define   CS7	0000040
+#define   CS8	0000060
+#define CSTOPB	0000100
+#define CREAD	0000200
+#define PARENB	0000400
+#define PARODD	0001000
+#define HUPCL	0002000
+#define CLOCAL	0004000
+#define CBAUDEX 0010000
+#define    B57600 0010001
+#define   B115200 0010002
+#define   B230400 0010003
+#define   B460800 0010004
+#define   B500000 0010005
+#define   B576000 0010006
+#define   B921600 0010007
+#define  B1000000 0010010
+#define  B1152000 0010011
+#define  B1500000 0010012
+#define  B2000000 0010013
+#define  B2500000 0010014
+#define  B3000000 0010015
+#define  B3500000 0010016
+#define  B4000000 0010017
+#define CIBAUD	  002003600000	/* input baud rate (not used) */
+#define CMSPAR	  010000000000		/* mark or space (stick) parity */
+#define CRTSCTS	  020000000000		/* flow control */
+
+/* c_lflag bits */
+
+#define ISIG	0000001
+#define ICANON	0000002
+#define XCASE	0000004
+#define ECHO	0000010
+#define ECHOE	0000020
+#define ECHOK	0000040
+#define ECHONL	0000100
+#define NOFLSH	0000200
+#define TOSTOP	0000400
+#define ECHOCTL	0001000
+#define ECHOPRT	0002000
+#define ECHOKE	0004000
+#define FLUSHO	0010000
+#define PENDIN	0040000
+#define IEXTEN	0100000
+
+/* tcflow() and TCXONC use these */
+
+#define	TCOOFF		0
+#define	TCOON		1
+#define	TCIOFF		2
+#define	TCION		3
+
+/* tcflush() and TCFLSH use these */
+
+#define	TCIFLUSH	0
+#define	TCOFLUSH	1
+#define	TCIOFLUSH	2
+
+/* tcsetattr uses these */
+
+#define	TCSANOW		0
+#define	TCSADRAIN	1
+#define	TCSAFLUSH	2
+
+#endif	/* _XTENSA_TERMBITS_H */
diff --git a/include/asm-xtensa/termios.h b/include/asm-xtensa/termios.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/termios.h
@@ -0,0 +1,122 @@
+/*
+ * include/asm-xtensa/termios.h
+ *
+ * Copied from SH.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_TERMIOS_H
+#define _XTENSA_TERMIOS_H
+
+#include <asm/termbits.h>
+#include <asm/ioctls.h>
+
+struct winsize {
+	unsigned short ws_row;
+	unsigned short ws_col;
+	unsigned short ws_xpixel;
+	unsigned short ws_ypixel;
+};
+
+#define NCC 8
+struct termio {
+	unsigned short c_iflag;		/* input mode flags */
+	unsigned short c_oflag;		/* output mode flags */
+	unsigned short c_cflag;		/* control mode flags */
+	unsigned short c_lflag;		/* local mode flags */
+	unsigned char c_line;		/* line discipline */
+	unsigned char c_cc[NCC];	/* control characters */
+};
+
+/* Modem lines */
+
+#define TIOCM_LE	0x001
+#define TIOCM_DTR	0x002
+#define TIOCM_RTS	0x004
+#define TIOCM_ST	0x008
+#define TIOCM_SR	0x010
+#define TIOCM_CTS	0x020
+#define TIOCM_CAR	0x040
+#define TIOCM_RNG	0x080
+#define TIOCM_DSR	0x100
+#define TIOCM_CD	TIOCM_CAR
+#define TIOCM_RI	TIOCM_RNG
+#define TIOCM_OUT1	0x2000
+#define TIOCM_OUT2	0x4000
+#define TIOCM_LOOP	0x8000
+
+/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
+
+/* Line disciplines */
+
+#define N_TTY		0
+#define N_SLIP		1
+#define N_MOUSE		2
+#define N_PPP		3
+#define N_STRIP		4
+#define N_AX25		5
+#define N_X25		6	/* X.25 async */
+#define N_6PACK		7
+#define N_MASC		8	/* Reserved for Mobitex module <kaz@cafe.net> */
+#define N_R3964		9	/* Reserved for Simatic R3964 module */
+#define N_PROFIBUS_FDL	10	/* Reserved for Profibus <Dave@mvhi.com> */
+#define N_IRDA		11	/* Linux IR - http://irda.sourceforge.net/ */
+#define N_SMSBLOCK	12	/* SMS block mode - for talking to GSM data cards about SMS messages */
+#define N_HDLC		13	/* synchronous HDLC */
+#define N_SYNC_PPP	14
+#define N_HCI		15      /* Bluetooth HCI UART */
+
+#ifdef __KERNEL__
+
+/*	intr=^C		quit=^\		erase=del	kill=^U
+	eof=^D		vtime=\0	vmin=\1		sxtc=\0
+	start=^Q	stop=^S		susp=^Z		eol=\0
+	reprint=^R	discard=^U	werase=^W	lnext=^V
+	eol2=\0
+*/
+#define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0"
+
+/*
+ * Translate a "termio" structure into a "termios". Ugh.
+ */
+
+#define SET_LOW_TERMIOS_BITS(termios, termio, x) { \
+	unsigned short __tmp; \
+	get_user(__tmp,&(termio)->x); \
+	*(unsigned short *) &(termios)->x = __tmp; \
+}
+
+#define user_termio_to_kernel_termios(termios, termio) \
+({ \
+	SET_LOW_TERMIOS_BITS(termios, termio, c_iflag); \
+	SET_LOW_TERMIOS_BITS(termios, termio, c_oflag); \
+	SET_LOW_TERMIOS_BITS(termios, termio, c_cflag); \
+	SET_LOW_TERMIOS_BITS(termios, termio, c_lflag); \
+	copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \
+})
+
+/*
+ * Translate a "termios" structure into a "termio". Ugh.
+ */
+
+#define kernel_termios_to_user_termio(termio, termios) \
+({ \
+	put_user((termios)->c_iflag, &(termio)->c_iflag); \
+	put_user((termios)->c_oflag, &(termio)->c_oflag); \
+	put_user((termios)->c_cflag, &(termio)->c_cflag); \
+	put_user((termios)->c_lflag, &(termio)->c_lflag); \
+	put_user((termios)->c_line,  &(termio)->c_line); \
+	copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \
+})
+
+#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios))
+#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios))
+
+#endif	/* __KERNEL__ */
+
+#endif	/* _XTENSA_TERMIOS_H */
diff --git a/include/asm-xtensa/thread_info.h b/include/asm-xtensa/thread_info.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/thread_info.h
@@ -0,0 +1,146 @@
+/*
+ * include/asm-xtensa/thread_info.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_THREAD_INFO_H
+#define _XTENSA_THREAD_INFO_H
+
+#ifdef __KERNEL__
+
+#ifndef __ASSEMBLY__
+# include <asm/processor.h>
+#endif
+
+/*
+ * low level task data that entry.S needs immediate access to
+ * - this struct should fit entirely inside of one cache line
+ * - this struct shares the supervisor stack pages
+ * - if the contents of this structure are changed, the assembly constants
+ *   must also be changed
+ */
+
+#ifndef __ASSEMBLY__
+
+struct thread_info {
+	struct task_struct	*task;		/* main task structure */
+	struct exec_domain	*exec_domain;	/* execution domain */
+	unsigned long		flags;		/* low level flags */
+	unsigned long		status;		/* thread-synchronous flags */
+	__u32			cpu;		/* current CPU */
+	__s32			preempt_count;	/* 0 => preemptable,< 0 => BUG*/
+
+	mm_segment_t		addr_limit;	/* thread address space */
+	struct restart_block    restart_block;
+
+
+};
+
+#else /* !__ASSEMBLY__ */
+
+/* offsets into the thread_info struct for assembly code access */
+#define TI_TASK		 0x00000000
+#define TI_EXEC_DOMAIN	 0x00000004
+#define TI_FLAGS	 0x00000008
+#define TI_STATUS	 0x0000000C
+#define TI_CPU		 0x00000010
+#define TI_PRE_COUNT	 0x00000014
+#define TI_ADDR_LIMIT	 0x00000018
+#define TI_RESTART_BLOCK 0x000001C
+
+#endif
+
+#define PREEMPT_ACTIVE		0x10000000
+
+/*
+ * macros/functions for gaining access to the thread information structure
+ *
+ * preempt_count needs to be 1 initially, until the scheduler is functional.
+ */
+
+#ifndef __ASSEMBLY__
+
+#define INIT_THREAD_INFO(tsk)			\
+{						\
+	.task		= &tsk,			\
+	.exec_domain	= &default_exec_domain,	\
+	.flags		= 0,			\
+	.cpu		= 0,			\
+	.preempt_count	= 1,			\
+	.addr_limit	= KERNEL_DS,		\
+	.restart_block = {			\
+		.fn = do_no_restart_syscall,	\
+	},					\
+}
+
+#define init_thread_info	(init_thread_union.thread_info)
+#define init_stack		(init_thread_union.stack)
+
+/* how to get the thread information struct from C */
+static inline struct thread_info *current_thread_info(void)
+{
+	struct thread_info *ti;
+	 __asm__("extui %0,a1,0,13\n\t"
+	         "xor %0, a1, %0" : "=&r" (ti) : );
+	return ti;
+}
+
+/* thread information allocation */
+#define alloc_thread_info(tsk) ((struct thread_info *) __get_free_pages(GFP_KERNEL,1))
+#define free_thread_info(ti) free_pages((unsigned long) (ti), 1)
+#define get_thread_info(ti) get_task_struct((ti)->task)
+#define put_thread_info(ti) put_task_struct((ti)->task)
+
+#else /* !__ASSEMBLY__ */
+
+/* how to get the thread information struct from ASM */
+#define GET_THREAD_INFO(reg,sp) \
+	extui reg, sp, 0, 13; \
+	xor   reg, sp, reg
+#endif
+
+
+/*
+ * thread information flags
+ * - these are process state flags that various assembly files may need to access
+ * - pending work-to-be-done flags are in LSW
+ * - other flags in MSW
+ */
+#define TIF_SYSCALL_TRACE	0	/* syscall trace active */
+#define TIF_NOTIFY_RESUME	1	/* resumption notification requested */
+#define TIF_SIGPENDING		2	/* signal pending */
+#define TIF_NEED_RESCHED	3	/* rescheduling necessary */
+#define TIF_SINGLESTEP		4	/* restore singlestep on return to user mode */
+#define TIF_IRET		5	/* return with iret */
+#define TIF_MEMDIE		6
+#define TIF_POLLING_NRFLAG	16	/* true if poll_idle() is polling TIF_NEED_RESCHED */
+
+#define _TIF_SYSCALL_TRACE	(1<<TIF_SYSCALL_TRACE)
+#define _TIF_NOTIFY_RESUME	(1<<TIF_NOTIFY_RESUME)
+#define _TIF_SIGPENDING		(1<<TIF_SIGPENDING)
+#define _TIF_NEED_RESCHED	(1<<TIF_NEED_RESCHED)
+#define _TIF_SINGLESTEP		(1<<TIF_SINGLESTEP)
+#define _TIF_IRET		(1<<TIF_IRET)
+#define _TIF_POLLING_NRFLAG	(1<<TIF_POLLING_NRFLAG)
+
+#define _TIF_WORK_MASK		0x0000FFFE	/* work to do on interrupt/exception return */
+#define _TIF_ALLWORK_MASK	0x0000FFFF	/* work to do on any return to u-space */
+
+/*
+ * Thread-synchronous status.
+ *
+ * This is different from the flags in that nobody else
+ * ever touches our thread-synchronous status, so we don't
+ * have to worry about atomic accesses.
+ */
+#define TS_USEDFPU		0x0001	/* FPU was used by this task this quantum (SMP) */
+
+#define THREAD_SIZE 8192	//(2*PAGE_SIZE)
+
+#endif	/* __KERNEL__ */
+#endif	/* _XTENSA_THREAD_INFO */
diff --git a/include/asm-xtensa/timex.h b/include/asm-xtensa/timex.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/timex.h
@@ -0,0 +1,94 @@
+/*
+ * include/asm-xtensa/timex.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_TIMEX_H
+#define _XTENSA_TIMEX_H
+
+#ifdef __KERNEL__
+
+#include <asm/processor.h>
+#include <linux/stringify.h>
+
+#if XCHAL_INT_LEVEL(XCHAL_TIMER0_INTERRUPT) == 1
+# define LINUX_TIMER     0
+#elif XCHAL_INT_LEVEL(XCHAL_TIMER1_INTERRUPT) == 1
+# define LINUX_TIMER     1
+#elif XCHAL_INT_LEVEL(XCHAL_TIMER2_INTERRUPT) == 1
+# define LINUX_TIMER     2
+#else
+# error "Bad timer number for Linux configurations!"
+#endif
+
+#define LINUX_TIMER_INT         XCHAL_TIMER_INTERRUPT(LINUX_TIMER)
+#define LINUX_TIMER_MASK        (1L << LINUX_TIMER_INT)
+
+#define CLOCK_TICK_RATE 	1193180	/* (everyone is using this value) */
+#define CLOCK_TICK_FACTOR       20 /* Factor of both 10^6 and CLOCK_TICK_RATE */
+#define FINETUNE ((((((long)LATCH * HZ - CLOCK_TICK_RATE) << SHIFT_HZ) * \
+	(1000000/CLOCK_TICK_FACTOR) / (CLOCK_TICK_RATE/CLOCK_TICK_FACTOR)) \
+		<< (SHIFT_SCALE-SHIFT_HZ)) / HZ)
+
+#ifdef CONFIG_XTENSA_CALIBRATE_CCOUNT
+extern unsigned long ccount_per_jiffy;
+extern unsigned long ccount_nsec;
+#define CCOUNT_PER_JIFFY ccount_per_jiffy
+#define CCOUNT_NSEC ccount_nsec
+#else
+#define CCOUNT_PER_JIFFY (CONFIG_XTENSA_CPU_CLOCK*(1000000UL/HZ))
+#define CCOUNT_NSEC (1000000000UL / CONFIG_XTENSA_CPU_CLOCK)
+#endif
+
+
+typedef unsigned long long cycles_t;
+
+/*
+ * Only used for SMP.
+ */
+
+extern cycles_t cacheflush_time;
+
+#define get_cycles()	(0)
+
+
+/*
+ * Register access.
+ */
+
+#define WSR_CCOUNT(r)	  __asm__("wsr %0,"__stringify(CCOUNT) :: "a" (r))
+#define RSR_CCOUNT(r)	  __asm__("rsr %0,"__stringify(CCOUNT) : "=a" (r))
+#define WSR_CCOMPARE(x,r) __asm__("wsr %0,"__stringify(CCOMPARE_0)"+"__stringify(x) :: "a"(r))
+#define RSR_CCOMPARE(x,r) __asm__("rsr %0,"__stringify(CCOMPARE_0)"+"__stringify(x) : "=a"(r))
+
+static inline unsigned long get_ccount (void)
+{
+	unsigned long ccount;
+	RSR_CCOUNT(ccount);
+	return ccount;
+}
+
+static inline void set_ccount (unsigned long ccount)
+{
+	WSR_CCOUNT(ccount);
+}
+
+static inline unsigned long get_linux_timer (void)
+{
+	unsigned ccompare;
+	RSR_CCOMPARE(LINUX_TIMER, ccompare);
+	return ccompare;
+}
+
+static inline void set_linux_timer (unsigned long ccompare)
+{
+	WSR_CCOMPARE(LINUX_TIMER, ccompare);
+}
+
+#endif	/* __KERNEL__ */
+#endif	/* _XTENSA_TIMEX_H */
diff --git a/include/asm-xtensa/tlb.h b/include/asm-xtensa/tlb.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/tlb.h
@@ -0,0 +1,25 @@
+/*
+ * include/asm-xtensa/tlb.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_TLB_H
+#define _XTENSA_TLB_H
+
+#define tlb_start_vma(tlb,vma)			do { } while (0)
+#define tlb_end_vma(tlb,vma)			do { } while (0)
+#define __tlb_remove_tlb_entry(tlb,pte,addr)	do { } while (0)
+
+#define tlb_flush(tlb)				flush_tlb_mm((tlb)->mm)
+
+#include <asm-generic/tlb.h>
+#include <asm/page.h>
+
+#define __pte_free_tlb(tlb,pte)			pte_free(pte)
+
+#endif	/* _XTENSA_TLB_H */
diff --git a/include/asm-xtensa/tlbflush.h b/include/asm-xtensa/tlbflush.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/tlbflush.h
@@ -0,0 +1,200 @@
+/*
+ * include/asm-xtensa/tlbflush.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_TLBFLUSH_H
+#define _XTENSA_TLBFLUSH_H
+
+#define DEBUG_TLB
+
+#ifdef __KERNEL__
+
+#include <asm/processor.h>
+#include <linux/stringify.h>
+
+/* TLB flushing:
+ *
+ *  - flush_tlb_all() flushes all processes TLB entries
+ *  - flush_tlb_mm(mm) flushes the specified mm context TLB entries
+ *  - flush_tlb_page(mm, vmaddr) flushes a single page
+ *  - flush_tlb_range(mm, start, end) flushes a range of pages
+ */
+
+extern void flush_tlb_all(void);
+extern void flush_tlb_mm(struct mm_struct*);
+extern void flush_tlb_page(struct vm_area_struct*,unsigned long);
+extern void flush_tlb_range(struct vm_area_struct*,unsigned long,unsigned long);
+
+#define flush_tlb_kernel_range(start,end) flush_tlb_all()
+
+
+/* This is calld in munmap when we have freed up some page-table pages.
+ * We don't need to do anything here, there's nothing special about our
+ * page-table pages.
+ */
+
+extern inline void flush_tlb_pgtables(struct mm_struct *mm,
+                                      unsigned long start, unsigned long end)
+{
+}
+
+/* TLB operations. */
+
+#define ITLB_WAYS_LOG2      XCHAL_ITLB_WAY_BITS
+#define DTLB_WAYS_LOG2      XCHAL_DTLB_WAY_BITS
+#define ITLB_PROBE_SUCCESS  (1 << ITLB_WAYS_LOG2)
+#define DTLB_PROBE_SUCCESS  (1 << DTLB_WAYS_LOG2)
+
+extern inline unsigned long itlb_probe(unsigned long addr)
+{
+	unsigned long tmp;
+	__asm__ __volatile__("pitlb  %0, %1\n\t" : "=a" (tmp) : "a" (addr));
+	return tmp;
+}
+
+extern inline unsigned long dtlb_probe(unsigned long addr)
+{
+	unsigned long tmp;
+	__asm__ __volatile__("pdtlb  %0, %1\n\t" : "=a" (tmp) : "a" (addr));
+	return tmp;
+}
+
+extern inline void invalidate_itlb_entry (unsigned long probe)
+{
+	__asm__ __volatile__("iitlb  %0; isync\n\t" : : "a" (probe));
+}
+
+extern inline void invalidate_dtlb_entry (unsigned long probe)
+{
+	__asm__ __volatile__("idtlb  %0; dsync\n\t" : : "a" (probe));
+}
+
+/* Use the .._no_isync functions with caution.  Generally, these are
+ * handy for bulk invalidates followed by a single 'isync'.  The
+ * caller must follow up with an 'isync', which can be relatively
+ * expensive on some Xtensa implementations.
+ */
+extern inline void invalidate_itlb_entry_no_isync (unsigned entry)
+{
+	/* Caller must follow up with 'isync'. */
+	__asm__ __volatile__ ("iitlb  %0\n" : : "a" (entry) );
+}
+
+extern inline void invalidate_dtlb_entry_no_isync (unsigned entry)
+{
+	/* Caller must follow up with 'isync'. */
+	__asm__ __volatile__ ("idtlb  %0\n" : : "a" (entry) );
+}
+
+extern inline void set_itlbcfg_register (unsigned long val)
+{
+	__asm__ __volatile__("wsr  %0, "__stringify(ITLBCFG)"\n\t" "isync\n\t"
+			     : : "a" (val));
+}
+
+extern inline void set_dtlbcfg_register (unsigned long val)
+{
+	__asm__ __volatile__("wsr  %0, "__stringify(DTLBCFG)"; dsync\n\t"
+	    		     : : "a" (val));
+}
+
+extern inline void set_ptevaddr_register (unsigned long val)
+{
+	__asm__ __volatile__(" wsr  %0, "__stringify(PTEVADDR)"; isync\n"
+			     : : "a" (val));
+}
+
+extern inline unsigned long read_ptevaddr_register (void)
+{
+	unsigned long tmp;
+	__asm__ __volatile__("rsr  %0, "__stringify(PTEVADDR)"\n\t" : "=a" (tmp));
+	return tmp;
+}
+
+extern inline void write_dtlb_entry (pte_t entry, int way)
+{
+	__asm__ __volatile__("wdtlb  %1, %0; dsync\n\t"
+			     : : "r" (way), "r" (entry) );
+}
+
+extern inline void write_itlb_entry (pte_t entry, int way)
+{
+	__asm__ __volatile__("witlb  %1, %0; isync\n\t"
+	                     : : "r" (way), "r" (entry) );
+}
+
+extern inline void invalidate_page_directory (void)
+{
+	invalidate_dtlb_entry (DTLB_WAY_PGTABLE);
+}
+
+extern inline void invalidate_itlb_mapping (unsigned address)
+{
+	unsigned long tlb_entry;
+	while ((tlb_entry = itlb_probe (address)) & ITLB_PROBE_SUCCESS)
+		invalidate_itlb_entry (tlb_entry);
+}
+
+extern inline void invalidate_dtlb_mapping (unsigned address)
+{
+	unsigned long tlb_entry;
+	while ((tlb_entry = dtlb_probe (address)) & DTLB_PROBE_SUCCESS)
+		invalidate_dtlb_entry (tlb_entry);
+}
+
+#define check_pgt_cache()	do { } while (0)
+
+
+#ifdef DEBUG_TLB
+
+/* DO NOT USE THESE FUNCTIONS.  These instructions aren't part of the Xtensa
+ * ISA and exist only for test purposes..
+ * You may find it helpful for MMU debugging, however.
+ *
+ * 'at' is the unmodified input register
+ * 'as' is the output register, as follows (specific to the Linux config):
+ *
+ *      as[31..12] contain the virtual address
+ *      as[11..08] are meaningless
+ *      as[07..00] contain the asid
+ */
+
+extern inline unsigned long read_dtlb_virtual (int way)
+{
+	unsigned long tmp;
+	__asm__ __volatile__("rdtlb0  %0, %1\n\t" : "=a" (tmp), "+a" (way));
+	return tmp;
+}
+
+extern inline unsigned long read_dtlb_translation (int way)
+{
+	unsigned long tmp;
+	__asm__ __volatile__("rdtlb1  %0, %1\n\t" : "=a" (tmp), "+a" (way));
+	return tmp;
+}
+
+extern inline unsigned long read_itlb_virtual (int way)
+{
+	unsigned long tmp;
+	__asm__ __volatile__("ritlb0  %0, %1\n\t" : "=a" (tmp), "+a" (way));
+	return tmp;
+}
+
+extern inline unsigned long read_itlb_translation (int way)
+{
+	unsigned long tmp;
+	__asm__ __volatile__("ritlb1  %0, %1\n\t" : "=a" (tmp), "+a" (way));
+	return tmp;
+}
+
+#endif	/* DEBUG_TLB */
+
+
+#endif	/* __KERNEL__ */
+#endif	/* _XTENSA_PGALLOC_H */
diff --git a/include/asm-xtensa/topology.h b/include/asm-xtensa/topology.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/topology.h
@@ -0,0 +1,16 @@
+/*
+ * include/asm-xtensa/topology.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_TOPOLOGY_H
+#define _XTENSA_TOPOLOGY_H
+
+#include <asm-generic/topology.h>
+
+#endif	/* _XTENSA_TOPOLOGY_H */
diff --git a/include/asm-xtensa/types.h b/include/asm-xtensa/types.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/types.h
@@ -0,0 +1,66 @@
+/*
+ * include/asm-xtensa/types.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_TYPES_H
+#define _XTENSA_TYPES_H
+
+#ifndef __ASSEMBLY__
+
+typedef unsigned short umode_t;
+
+/*
+ * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
+ * header files exported to user space
+ */
+
+typedef __signed__ char __s8;
+typedef unsigned char __u8;
+
+typedef __signed__ short __s16;
+typedef unsigned short __u16;
+
+typedef __signed__ int __s32;
+typedef unsigned int __u32;
+
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
+typedef __signed__ long long __s64;
+typedef unsigned long long __u64;
+#endif
+
+/*
+ * These aren't exported outside the kernel to avoid name space clashes
+ */
+#ifdef __KERNEL__
+
+typedef __signed__ char s8;
+typedef unsigned char u8;
+
+typedef __signed__ short s16;
+typedef unsigned short u16;
+
+typedef __signed__ int s32;
+typedef unsigned int u32;
+
+typedef __signed__ long long s64;
+typedef unsigned long long u64;
+
+
+#define BITS_PER_LONG 32
+
+/* Dma addresses are 32-bits wide.  */
+
+typedef u32 dma_addr_t;
+
+typedef unsigned int kmem_bufctl_t;
+
+#endif	/* __KERNEL__ */
+#endif
+
+#endif	/* _XTENSA_TYPES_H */
diff --git a/include/asm-xtensa/uaccess.h b/include/asm-xtensa/uaccess.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/uaccess.h
@@ -0,0 +1,532 @@
+/*
+ * include/asm-xtensa/uaccess.h
+ *
+ * User space memory access functions
+ *
+ * These routines provide basic accessing functions to the user memory
+ * space for the kernel. This header file provides fuctions such as:
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_UACCESS_H
+#define _XTENSA_UACCESS_H
+
+#include <linux/errno.h>
+
+#define VERIFY_READ    0
+#define VERIFY_WRITE   1
+
+#ifdef __ASSEMBLY__
+
+#define _ASMLANGUAGE
+#include <asm/current.h>
+#include <asm/offsets.h>
+#include <asm/processor.h>
+
+/*
+ * These assembly macros mirror the C macros that follow below.  They
+ * should always have identical functionality.  See
+ * arch/xtensa/kernel/sys.S for usage.
+ */
+
+#define KERNEL_DS	0
+#define USER_DS		1
+
+#define get_ds		(KERNEL_DS)
+
+/*
+ * get_fs reads current->thread.current_ds into a register.
+ * On Entry:
+ * 	<ad>	anything
+ * 	<sp>	stack
+ * On Exit:
+ * 	<ad>	contains current->thread.current_ds
+ */
+	.macro	get_fs	ad, sp
+	GET_CURRENT(\ad,\sp)
+	l32i	\ad, \ad, THREAD_CURRENT_DS
+	.endm
+
+/*
+ * set_fs sets current->thread.current_ds to some value.
+ * On Entry:
+ *	<at>	anything (temp register)
+ *	<av>	value to write
+ *	<sp>	stack
+ * On Exit:
+ *	<at>	destroyed (actually, current)
+ *	<av>	preserved, value to write
+ */
+	.macro	set_fs	at, av, sp
+	GET_CURRENT(\at,\sp)
+	s32i	\av, \at, THREAD_CURRENT_DS
+	.endm
+
+/*
+ * kernel_ok determines whether we should bypass addr/size checking.
+ * See the equivalent C-macro version below for clarity.
+ * On success, kernel_ok branches to a label indicated by parameter
+ * <success>.  This implies that the macro falls through to the next
+ * insruction on an error.
+ *
+ * Note that while this macro can be used independently, we designed
+ * in for optimal use in the access_ok macro below (i.e., we fall
+ * through on error).
+ *
+ * On Entry:
+ * 	<at>		anything (temp register)
+ * 	<success>	label to branch to on success; implies
+ * 			fall-through macro on error
+ * 	<sp>		stack pointer
+ * On Exit:
+ * 	<at>		destroyed (actually, current->thread.current_ds)
+ */
+
+#if ((KERNEL_DS != 0) || (USER_DS == 0))
+# error Assembly macro kernel_ok fails
+#endif
+	.macro	kernel_ok  at, sp, success
+	get_fs	\at, \sp
+	beqz	\at, \success
+	.endm
+
+/*
+ * user_ok determines whether the access to user-space memory is allowed.
+ * See the equivalent C-macro version below for clarity.
+ *
+ * On error, user_ok branches to a label indicated by parameter
+ * <error>.  This implies that the macro falls through to the next
+ * instruction on success.
+ *
+ * Note that while this macro can be used independently, we designed
+ * in for optimal use in the access_ok macro below (i.e., we fall
+ * through on success).
+ *
+ * On Entry:
+ * 	<aa>	register containing memory address
+ * 	<as>	register containing memory size
+ * 	<at>	temp register
+ * 	<error>	label to branch to on error; implies fall-through
+ * 		macro on success
+ * On Exit:
+ * 	<aa>	preserved
+ * 	<as>	preserved
+ * 	<at>	destroyed (actually, (TASK_SIZE + 1 - size))
+ */
+	.macro	user_ok	aa, as, at, error
+	movi	\at, (TASK_SIZE+1)
+	bgeu	\as, \at, \error
+	sub	\at, \at, \as
+	bgeu	\aa, \at, \error
+	.endm
+
+/*
+ * access_ok determines whether a memory access is allowed.  See the
+ * equivalent C-macro version below for clarity.
+ *
+ * On error, access_ok branches to a label indicated by parameter
+ * <error>.  This implies that the macro falls through to the next
+ * instruction on success.
+ *
+ * Note that we assume success is the common case, and we optimize the
+ * branch fall-through case on success.
+ *
+ * On Entry:
+ * 	<aa>	register containing memory address
+ * 	<as>	register containing memory size
+ * 	<at>	temp register
+ * 	<sp>
+ * 	<error>	label to branch to on error; implies fall-through
+ * 		macro on success
+ * On Exit:
+ * 	<aa>	preserved
+ * 	<as>	preserved
+ * 	<at>	destroyed
+ */
+	.macro	access_ok  aa, as, at, sp, error
+	kernel_ok  \at, \sp, .Laccess_ok_\@
+	user_ok    \aa, \as, \at, \error
+.Laccess_ok_\@:
+	.endm
+
+/*
+ * verify_area determines whether a memory access is allowed.  It's
+ * mostly an unnecessary wrapper for access_ok, but we provide it as a
+ * duplicate of the verify_area() C inline function below.  See the
+ * equivalent C version below for clarity.
+ *
+ * On error, verify_area branches to a label indicated by parameter
+ * <error>.  This implies that the macro falls through to the next
+ * instruction on success.
+ *
+ * Note that we assume success is the common case, and we optimize the
+ * branch fall-through case on success.
+ *
+ * On Entry:
+ * 	<aa>	register containing memory address
+ * 	<as>	register containing memory size
+ * 	<at>	temp register
+ * 	<error>	label to branch to on error; implies fall-through
+ * 		macro on success
+ * On Exit:
+ * 	<aa>	preserved
+ * 	<as>	preserved
+ * 	<at>	destroyed
+ */
+	.macro	verify_area	aa, as, at, sp, error
+	access_ok  \at, \aa, \as, \sp, \error
+	.endm
+
+
+#else /* __ASSEMBLY__ not defined */
+
+#include <linux/sched.h>
+#include <asm/types.h>
+
+/*
+ * The fs value determines whether argument validity checking should
+ * be performed or not.  If get_fs() == USER_DS, checking is
+ * performed, with get_fs() == KERNEL_DS, checking is bypassed.
+ *
+ * For historical reasons (Data Segment Register?), these macros are
+ * grossly misnamed.
+ */
+
+#define KERNEL_DS	((mm_segment_t) { 0 })
+#define USER_DS		((mm_segment_t) { 1 })
+
+#define get_ds()	(KERNEL_DS)
+#define get_fs()	(current->thread.current_ds)
+#define set_fs(val)	(current->thread.current_ds = (val))
+
+#define segment_eq(a,b)	((a).seg == (b).seg)
+
+#define __kernel_ok (segment_eq(get_fs(), KERNEL_DS))
+#define __user_ok(addr,size) (((size) <= TASK_SIZE)&&((addr) <= TASK_SIZE-(size)))
+#define __access_ok(addr,size) (__kernel_ok || __user_ok((addr),(size)))
+#define access_ok(type,addr,size) __access_ok((unsigned long)(addr),(size))
+
+extern inline int verify_area(int type, const void * addr, unsigned long size)
+{
+	return access_ok(type,addr,size) ? 0 : -EFAULT;
+}
+
+/*
+ * These are the main single-value transfer routines.  They
+ * automatically use the right size if we just have the right pointer
+ * type.
+ *
+ * This gets kind of ugly. We want to return _two_ values in
+ * "get_user()" and yet we don't want to do any pointers, because that
+ * is too much of a performance impact. Thus we have a few rather ugly
+ * macros here, and hide all the uglyness from the user.
+ *
+ * Careful to not
+ * (a) re-use the arguments for side effects (sizeof is ok)
+ * (b) require any knowledge of processes at this stage
+ */
+#define put_user(x,ptr)	__put_user_check((x),(ptr),sizeof(*(ptr)))
+#define get_user(x,ptr) __get_user_check((x),(ptr),sizeof(*(ptr)))
+
+/*
+ * The "__xxx" versions of the user access functions are versions that
+ * do not verify the address space, that must have been done previously
+ * with a separate "access_ok()" call (this is used when we do multiple
+ * accesses to the same area of user memory).
+ */
+#define __put_user(x,ptr) __put_user_nocheck((x),(ptr),sizeof(*(ptr)))
+#define __get_user(x,ptr) __get_user_nocheck((x),(ptr),sizeof(*(ptr)))
+
+
+extern long __put_user_bad(void);
+
+#define __put_user_nocheck(x,ptr,size)			\
+({							\
+	long __pu_err;					\
+	__put_user_size((x),(ptr),(size),__pu_err);	\
+	__pu_err;					\
+})
+
+#define __put_user_check(x,ptr,size)				\
+({								\
+	long __pu_err = -EFAULT;				\
+	__typeof__(*(ptr)) *__pu_addr = (ptr);			\
+	if (access_ok(VERIFY_WRITE,__pu_addr,size))		\
+		__put_user_size((x),__pu_addr,(size),__pu_err);	\
+	__pu_err;						\
+})
+
+#define __put_user_size(x,ptr,size,retval)			\
+do {								\
+	retval = 0;						\
+	switch (size) {						\
+        case 1: __put_user_asm(x,ptr,retval,1,"s8i");  break;	\
+        case 2: __put_user_asm(x,ptr,retval,2,"s16i"); break;   \
+        case 4: __put_user_asm(x,ptr,retval,4,"s32i"); break;   \
+        case 8: {						\
+		     __typeof__(*ptr) __v64 = x;		\
+		     retval = __copy_to_user(ptr,&__v64,8);	\
+		     break;					\
+	        }						\
+	default: __put_user_bad();				\
+	}							\
+} while (0)
+
+
+/*
+ * Consider a case of a user single load/store would cause both an
+ * unaligned exception and an MMU-related exception (unaligned
+ * exceptions happen first):
+ *
+ * User code passes a bad variable ptr to a system call.
+ * Kernel tries to access the variable.
+ * Unaligned exception occurs.
+ * Unaligned exception handler tries to make aligned accesses.
+ * Double exception occurs for MMU-related cause (e.g., page not mapped).
+ * do_page_fault() thinks the fault address belongs to the kernel, not the
+ * user, and panics.
+ *
+ * The kernel currently prohibits user unaligned accesses.  We use the
+ * __check_align_* macros to check for unaligned addresses before
+ * accessing user space so we don't crash the kernel.  Both
+ * __put_user_asm and __get_user_asm use these alignment macros, so
+ * macro-specific labels such as 0f, 1f, %0, %2, and %3 must stay in
+ * sync.
+ */
+
+#define __check_align_1  ""
+
+#define __check_align_2				\
+	"   _bbci.l %2,  0, 1f		\n"	\
+	"   movi    %0, %3		\n"	\
+	"   _j      2f			\n"
+
+#define __check_align_4				\
+	"   _bbsi.l %2,  0, 0f		\n"	\
+	"   _bbci.l %2,  1, 1f		\n"	\
+	"0: movi    %0, %3		\n"	\
+	"   _j      2f			\n"
+
+
+/*
+ * We don't tell gcc that we are accessing memory, but this is OK
+ * because we do not write to any memory gcc knows about, so there
+ * are no aliasing issues.
+ *
+ * WARNING: If you modify this macro at all, verify that the
+ * __check_align_* macros still work.
+ */
+#define __put_user_asm(x, addr, err, align, insn) \
+   __asm__ __volatile__(			\
+	__check_align_##align			\
+	"1: "insn"  %1, %2, 0		\n"	\
+	"2:				\n"	\
+	"   .section  .fixup,\"ax\"	\n"	\
+	"   .align 4			\n"	\
+	"4:				\n"	\
+	"   .long  2b			\n"	\
+	"5:				\n"	\
+	"   l32r   %2, 4b		\n"	\
+        "   movi   %0, %3		\n"	\
+        "   jx     %2			\n"	\
+	"   .previous			\n"	\
+	"   .section  __ex_table,\"a\"	\n"	\
+	"   .long	1b, 5b		\n"	\
+	"   .previous"				\
+	:"=r" (err)				\
+	:"r" ((int)(x)), "r" (addr), "i" (-EFAULT), "0" (err))
+
+#define __get_user_nocheck(x,ptr,size)				\
+({								\
+	long __gu_err, __gu_val;				\
+	__get_user_size(__gu_val,(ptr),(size),__gu_err);	\
+	(x) = (__typeof__(*(ptr)))__gu_val;			\
+	__gu_err;						\
+})
+
+#define __get_user_check(x,ptr,size)					\
+({									\
+	long __gu_err = -EFAULT, __gu_val = 0;				\
+	const __typeof__(*(ptr)) *__gu_addr = (ptr);			\
+	if (access_ok(VERIFY_READ,__gu_addr,size))			\
+		__get_user_size(__gu_val,__gu_addr,(size),__gu_err);	\
+	(x) = (__typeof__(*(ptr)))__gu_val;				\
+	__gu_err;							\
+})
+
+extern long __get_user_bad(void);
+
+#define __get_user_size(x,ptr,size,retval)				\
+do {									\
+	retval = 0;							\
+        switch (size) {							\
+          case 1: __get_user_asm(x,ptr,retval,1,"l8ui");  break;	\
+          case 2: __get_user_asm(x,ptr,retval,2,"l16ui"); break;	\
+          case 4: __get_user_asm(x,ptr,retval,4,"l32i");  break;	\
+          case 8: retval = __copy_from_user(&x,ptr,8);    break;	\
+          default: (x) = __get_user_bad();				\
+        }								\
+} while (0)
+
+
+/*
+ * WARNING: If you modify this macro at all, verify that the
+ * __check_align_* macros still work.
+ */
+#define __get_user_asm(x, addr, err, align, insn) \
+   __asm__ __volatile__(			\
+	__check_align_##align			\
+	"1: "insn"  %1, %2, 0		\n"	\
+	"2:				\n"	\
+	"   .section  .fixup,\"ax\"	\n"	\
+	"   .align 4			\n"	\
+	"4:				\n"	\
+	"   .long  2b			\n"	\
+	"5:				\n"	\
+	"   l32r   %2, 4b		\n"	\
+	"   movi   %1, 0		\n"	\
+        "   movi   %0, %3		\n"	\
+        "   jx     %2			\n"	\
+	"   .previous			\n"	\
+	"   .section  __ex_table,\"a\"	\n"	\
+	"   .long	1b, 5b		\n"	\
+	"   .previous"				\
+	:"=r" (err), "=r" (x)			\
+	:"r" (addr), "i" (-EFAULT), "0" (err))
+
+
+/*
+ * Copy to/from user space
+ */
+
+/*
+ * We use a generic, arbitrary-sized copy subroutine.  The Xtensa
+ * architecture would cause heavy code bloat if we tried to inline
+ * these functions and provide __constant_copy_* equivalents like the
+ * i386 versions.  __xtensa_copy_user is quite efficient.  See the
+ * .fixup section of __xtensa_copy_user for a discussion on the
+ * X_zeroing equivalents for Xtensa.
+ */
+
+extern unsigned __xtensa_copy_user(void *to, const void *from, unsigned n);
+#define __copy_user(to,from,size) __xtensa_copy_user(to,from,size)
+
+
+static inline unsigned long
+__generic_copy_from_user_nocheck(void *to, const void *from, unsigned long n)
+{
+	return __copy_user(to,from,n);
+}
+
+static inline unsigned long
+__generic_copy_to_user_nocheck(void *to, const void *from, unsigned long n)
+{
+	return __copy_user(to,from,n);
+}
+
+static inline unsigned long
+__generic_copy_to_user(void *to, const void *from, unsigned long n)
+{
+	prefetch(from);
+	if (access_ok(VERIFY_WRITE, to, n))
+		return __copy_user(to,from,n);
+	return n;
+}
+
+static inline unsigned long
+__generic_copy_from_user(void *to, const void *from, unsigned long n)
+{
+	prefetchw(to);
+	if (access_ok(VERIFY_READ, from, n))
+		return __copy_user(to,from,n);
+	else
+		memset(to, 0, n);
+	return n;
+}
+
+#define copy_to_user(to,from,n) __generic_copy_to_user((to),(from),(n))
+#define copy_from_user(to,from,n) __generic_copy_from_user((to),(from),(n))
+#define __copy_to_user(to,from,n) __generic_copy_to_user_nocheck((to),(from),(n))
+#define __copy_from_user(to,from,n) __generic_copy_from_user_nocheck((to),(from),(n))
+#define __copy_to_user_inatomic __copy_to_user
+#define __copy_from_user_inatomic __copy_from_user
+
+
+/*
+ * We need to return the number of bytes not cleared.  Our memset()
+ * returns zero if a problem occurs while accessing user-space memory.
+ * In that event, return no memory cleared.  Otherwise, zero for
+ * success.
+ */
+
+extern inline unsigned long
+__xtensa_clear_user(void *addr, unsigned long size)
+{
+	if ( ! memset(addr, 0, size) )
+		return size;
+	return 0;
+}
+
+extern inline unsigned long
+clear_user(void *addr, unsigned long size)
+{
+	if (access_ok(VERIFY_WRITE, addr, size))
+		return __xtensa_clear_user(addr, size);
+	return size ? -EFAULT : 0;
+}
+
+#define __clear_user  __xtensa_clear_user
+
+
+extern long __strncpy_user(char *, const char *, long);
+#define __strncpy_from_user __strncpy_user
+
+extern inline long
+strncpy_from_user(char *dst, const char *src, long count)
+{
+	if (access_ok(VERIFY_READ, src, 1))
+		return __strncpy_from_user(dst, src, count);
+	return -EFAULT;
+}
+
+
+#define strlen_user(str) strnlen_user((str), TASK_SIZE - 1)
+
+/*
+ * Return the size of a string (including the ending 0!)
+ */
+extern long __strnlen_user(const char *, long);
+
+extern inline long strnlen_user(const char *str, long len)
+{
+	unsigned long top = __kernel_ok ? ~0UL : TASK_SIZE - 1;
+
+	if ((unsigned long)str > top)
+		return 0;
+	return __strnlen_user(str, len);
+}
+
+
+struct exception_table_entry
+{
+	unsigned long insn, fixup;
+};
+
+/* Returns 0 if exception not found and fixup.unit otherwise.  */
+
+extern unsigned long search_exception_table(unsigned long addr);
+extern void sort_exception_table(void);
+
+/* Returns the new pc */
+#define fixup_exception(map_reg, fixup_unit, pc)                \
+({                                                              \
+	fixup_unit;                                             \
+})
+
+#endif	/* __ASSEMBLY__ */
+#endif	/* _XTENSA_UACCESS_H */
diff --git a/include/asm-xtensa/ucontext.h b/include/asm-xtensa/ucontext.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/ucontext.h
@@ -0,0 +1,22 @@
+/*
+ * include/asm-xtensa/ucontext.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_UCONTEXT_H
+#define _XTENSA_UCONTEXT_H
+
+struct ucontext {
+	unsigned long	  uc_flags;
+	struct ucontext  *uc_link;
+	stack_t		  uc_stack;
+	struct sigcontext uc_mcontext;
+	sigset_t	  uc_sigmask;	/* mask last for extensibility */
+};
+
+#endif /* _XTENSA_UCONTEXT_H */
diff --git a/include/asm-xtensa/unaligned.h b/include/asm-xtensa/unaligned.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/unaligned.h
@@ -0,0 +1,28 @@
+/*
+ * include/asm-xtensa/unaligned.h
+ *
+ * Xtensa doesn't handle unaligned accesses efficiently.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_UNALIGNED_H
+#define _XTENSA_UNALIGNED_H
+
+#include <linux/string.h>
+
+/* Use memmove here, so gcc does not insert a __builtin_memcpy. */
+
+#define get_unaligned(ptr) \
+  ({ __typeof__(*(ptr)) __tmp; memmove(&__tmp, (ptr), sizeof(*(ptr))); __tmp; })
+
+#define put_unaligned(val, ptr)				\
+  ({ __typeof__(*(ptr)) __tmp = (val);			\
+     memmove((ptr), &__tmp, sizeof(*(ptr)));		\
+     (void)0; })
+
+#endif	/* _XTENSA_UNALIGNED_H */
diff --git a/include/asm-xtensa/unistd.h b/include/asm-xtensa/unistd.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/unistd.h
@@ -0,0 +1,439 @@
+/*
+ * include/asm-xtensa/unistd.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_UNISTD_H
+#define _XTENSA_UNISTD_H
+
+#include <linux/linkage.h>
+
+#define __NR_spill		  0
+#define __NR_exit		  1
+#define __NR_read		  3
+#define __NR_write		  4
+#define __NR_open		  5
+#define __NR_close		  6
+#define __NR_creat		  8
+#define __NR_link		  9
+#define __NR_unlink		 10
+#define __NR_execve		 11
+#define __NR_chdir		 12
+#define __NR_mknod		 14
+#define __NR_chmod		 15
+#define __NR_lchown		 16
+#define __NR_break		 17
+#define __NR_lseek		 19
+#define __NR_getpid		 20
+#define __NR_mount		 21
+#define __NR_setuid		 23
+#define __NR_getuid		 24
+#define __NR_ptrace		 26
+#define __NR_utime		 30
+#define __NR_stty		 31
+#define __NR_gtty		 32
+#define __NR_access		 33
+#define __NR_ftime		 35
+#define __NR_sync		 36
+#define __NR_kill		 37
+#define __NR_rename		 38
+#define __NR_mkdir		 39
+#define __NR_rmdir		 40
+#define __NR_dup		 41
+#define __NR_pipe		 42
+#define __NR_times		 43
+#define __NR_prof		 44
+#define __NR_brk		 45
+#define __NR_setgid		 46
+#define __NR_getgid		 47
+#define __NR_signal		 48
+#define __NR_geteuid		 49
+#define __NR_getegid		 50
+#define __NR_acct		 51
+#define __NR_lock		 53
+#define __NR_ioctl		 54
+#define __NR_fcntl		 55
+#define __NR_setpgid		 57
+#define __NR_ulimit		 58
+#define __NR_umask		 60
+#define __NR_chroot		 61
+#define __NR_ustat		 62
+#define __NR_dup2		 63
+#define __NR_getppid		 64
+#define __NR_setsid		 66
+#define __NR_sigaction		 67
+#define __NR_setreuid		 70
+#define __NR_setregid		 71
+#define __NR_sigsuspend		 72
+#define __NR_sigpending		 73
+#define __NR_sethostname	 74
+#define __NR_setrlimit		 75
+#define __NR_getrlimit	 	 76	/* Back compatible 2Gig limited rlimit */
+#define __NR_getrusage		 77
+#define __NR_gettimeofday	 78
+#define __NR_settimeofday	 79
+#define __NR_getgroups		 80
+#define __NR_setgroups		 81
+#define __NR_select		 82
+#define __NR_symlink		 83
+#define __NR_readlink		 85
+#define __NR_uselib		 86
+#define __NR_swapon		 87
+#define __NR_reboot		 88
+#define __NR_munmap		 91
+#define __NR_truncate		 92
+#define __NR_ftruncate		 93
+#define __NR_fchmod		 94
+#define __NR_fchown		 95
+#define __NR_getpriority	 96
+#define __NR_setpriority	 97
+#define __NR_profil		 98
+#define __NR_statfs		 99
+#define __NR_fstatfs		100
+#define __NR_ioperm		101
+#define __NR_syslog		103
+#define __NR_setitimer		104
+#define __NR_getitimer		105
+#define __NR_stat		106
+#define __NR_lstat		107
+#define __NR_fstat		108
+#define __NR_iopl		110
+#define __NR_vhangup		111
+#define __NR_idle		112
+#define __NR_wait4		114
+#define __NR_swapoff		115
+#define __NR_sysinfo		116
+#define __NR_fsync		118
+#define __NR_sigreturn		119
+#define __NR_clone		120
+#define __NR_setdomainname	121
+#define __NR_uname		122
+#define __NR_modify_ldt		123
+#define __NR_adjtimex		124
+#define __NR_mprotect		125
+#define __NR_create_module	127
+#define __NR_init_module	128
+#define __NR_delete_module	129
+#define __NR_quotactl		131
+#define __NR_getpgid		132
+#define __NR_fchdir		133
+#define __NR_bdflush		134
+#define __NR_sysfs		135
+#define __NR_personality	136
+#define __NR_setfsuid		138
+#define __NR_setfsgid		139
+#define __NR__llseek		140
+#define __NR_getdents		141
+#define __NR__newselect		142
+#define __NR_flock		143
+#define __NR_msync		144
+#define __NR_readv		145
+#define __NR_writev		146
+#define __NR_cacheflush         147
+#define __NR_cachectl           148
+#define __NR_sysxtensa          149
+#define __NR_sysdummy           150
+#define __NR_getsid		151
+#define __NR_fdatasync		152
+#define __NR__sysctl		153
+#define __NR_mlock		154
+#define __NR_munlock		155
+#define __NR_mlockall		156
+#define __NR_munlockall		157
+#define __NR_sched_setparam		158
+#define __NR_sched_getparam		159
+#define __NR_sched_setscheduler		160
+#define __NR_sched_getscheduler		161
+#define __NR_sched_yield		162
+#define __NR_sched_get_priority_max	163
+#define __NR_sched_get_priority_min	164
+#define __NR_sched_rr_get_interval	165
+#define __NR_nanosleep		166
+#define __NR_mremap		167
+#define __NR_accept             168
+#define __NR_bind               169
+#define __NR_connect            170
+#define __NR_getpeername        171
+#define __NR_getsockname        172
+#define __NR_getsockopt         173
+#define __NR_listen             174
+#define __NR_recv               175
+#define __NR_recvfrom           176
+#define __NR_recvmsg            177
+#define __NR_send               178
+#define __NR_sendmsg            179
+#define __NR_sendto             180
+#define __NR_setsockopt         181
+#define __NR_shutdown           182
+#define __NR_socket             183
+#define __NR_socketpair         184
+#define __NR_setresuid		185
+#define __NR_getresuid		186
+#define __NR_query_module	187
+#define __NR_poll		188
+#define __NR_nfsservctl		189
+#define __NR_setresgid		190
+#define __NR_getresgid		191
+#define __NR_prctl              192
+#define __NR_rt_sigreturn	193
+#define __NR_rt_sigaction	194
+#define __NR_rt_sigprocmask	195
+#define __NR_rt_sigpending	196
+#define __NR_rt_sigtimedwait	197
+#define __NR_rt_sigqueueinfo	198
+#define __NR_rt_sigsuspend	199
+#define __NR_pread		200
+#define __NR_pwrite		201
+#define __NR_chown		202
+#define __NR_getcwd		203
+#define __NR_capget		204
+#define __NR_capset		205
+#define __NR_sigaltstack	206
+#define __NR_sendfile		207
+#define __NR_mmap2		210
+#define __NR_truncate64		211
+#define __NR_ftruncate64	212
+#define __NR_stat64		213
+#define __NR_lstat64		214
+#define __NR_fstat64		215
+#define __NR_pivot_root		216
+#define __NR_mincore		217
+#define __NR_madvise		218
+#define __NR_getdents64		219
+
+/* Keep this last; should always equal the last valid call number. */
+#define __NR_Linux_syscalls     220
+
+/* user-visible error numbers are in the range -1 - -125: see
+ * <asm-xtensa/errno.h> */
+
+#define SYSXTENSA_RESERVED	   0	/* don't use this */
+#define SYSXTENSA_ATOMIC_SET	   1	/* set variable */
+#define SYSXTENSA_ATOMIC_EXG_ADD   2	/* exchange memory and add */
+#define SYSXTENSA_ATOMIC_ADD	   3	/* add to memory */
+#define SYSXTENSA_ATOMIC_CMP_SWP   4	/* compare and swap */
+
+#define SYSXTENSA_COUNT		   5	/* count of syscall0 functions*/
+
+#ifdef __KERNEL__
+#define __syscall_return(type, res) return ((type)(res))
+#else
+#define __syscall_return(type, res) \
+do { \
+	if ((unsigned long)(res) >= (unsigned long)(-125)) { \
+	/* Avoid using "res" which is declared to be in register r2; \
+	 * errno might expand to a function call and clobber it.  */ \
+		int __err = -(res); \
+		errno = __err; \
+		res = -1; \
+	} \
+	return (type) (res); \
+} while (0)
+#endif
+
+
+/* Tensilica's xt-xcc compiler is much more agressive at code
+ * optimization than gcc.  Multiple __asm__ statements are
+ * insufficient for xt-xcc because subsequent optimization passes
+ * (beyond the front-end that knows of __asm__ statements and other
+ * such GNU Extensions to C) can modify the register selection for
+ * containment of C variables.
+ *
+ * xt-xcc cannot modify the contents of a single __asm__ statement, so
+ * we create single-asm versions of the syscall macros that are
+ * suitable and optimal for both xt-xcc and gcc.
+ *
+ * Linux takes system-call arguments in registers.  The following
+ * design is optimized for user-land apps (e.g., glibc) which
+ * typically have a function wrapper around the "syscall" assembly
+ * instruction.  It satisfies the Xtensa ABI while minizing argument
+ * shifting.
+ *
+ * The Xtensa ABI and software conventions require the system-call
+ * number in a2.  If an argument exists in a2, we move it to the next
+ * available register.  Note that for improved efficiency, we do NOT
+ * shift all parameters down one register to maintain the original
+ * order.
+ *
+ * At best case (zero arguments), we just write the syscall number to
+ * a2.  At worst case (1 to 6 arguments), we move the argument in a2
+ * to the next available register, then write the syscall number to
+ * a2.
+ *
+ * For clarity, the following truth table enumerates all possibilities.
+ *
+ * arguments	syscall number	arg0, arg1, arg2, arg3, arg4, arg5
+ * ---------	--------------	----------------------------------
+ *	0	      a2
+ *	1	      a2	a3
+ *	2	      a2	a4,   a3
+ *	3	      a2	a5,   a3,   a4
+ *	4	      a2	a6,   a3,   a4,   a5
+ *	5	      a2	a7,   a3,   a4,   a5,   a6
+ *	6	      a2	a8,   a3,   a4,   a5,   a6,   a7
+ */
+
+#define _syscall0(type,name) \
+type name(void) \
+{ \
+long __res; \
+__asm__ __volatile__ ( \
+	"  movi  a2, %1 \n" \
+	"  syscall      \n" \
+	"  mov   %0, a2 \n" \
+	: "=a" (__res) \
+	: "i" (__NR_##name) \
+	: "a2" \
+	); \
+__syscall_return(type,__res); \
+}
+
+#define _syscall1(type,name,type0,arg0) \
+type name(type0 arg0) \
+{ \
+long __res; \
+__asm__ __volatile__ ( \
+	"  mov   a3, %2 \n" \
+	"  movi  a2, %1 \n" \
+	"  syscall      \n" \
+	"  mov   %0, a2 \n" \
+	: "=a" (__res) \
+	: "i" (__NR_##name), "a" (arg0) \
+	: "a2", "a3" \
+	); \
+__syscall_return(type,__res); \
+}
+
+#define _syscall2(type,name,type0,arg0,type1,arg1) \
+type name(type0 arg0,type1 arg1) \
+{ \
+long __res; \
+__asm__ __volatile__ ( \
+	"  mov   a4, %2 \n" \
+	"  mov   a3, %3 \n" \
+	"  movi  a2, %1 \n" \
+	"  syscall      \n" \
+	"  mov   %0, a2 \n" \
+	: "=a" (__res) \
+	: "i" (__NR_##name), "a" (arg0), "a" (arg1) \
+	: "a2", "a3", "a4" \
+	); \
+__syscall_return(type,__res); \
+}
+
+#define _syscall3(type,name,type0,arg0,type1,arg1,type2,arg2) \
+type name(type0 arg0,type1 arg1,type2 arg2) \
+{ \
+long __res; \
+__asm__ __volatile__ ( \
+	"  mov   a5, %2 \n" \
+	"  mov   a4, %4 \n" \
+	"  mov   a3, %3 \n" \
+	"  movi  a2, %1 \n" \
+	"  syscall      \n" \
+	"  mov   %0, a2 \n" \
+	: "=a" (__res) \
+	: "i" (__NR_##name), "a" (arg0), "a" (arg1), "a" (arg2) \
+	: "a2", "a3", "a4", "a5" \
+	); \
+__syscall_return(type,__res); \
+}
+
+#define _syscall4(type,name,type0,arg0,type1,arg1,type2,arg2,type3,arg3) \
+type name(type0 arg0,type1 arg1,type2 arg2,type3 arg3) \
+{ \
+long __res; \
+__asm__ __volatile__ ( \
+	"  mov   a6, %2 \n" \
+	"  mov   a5, %5 \n" \
+	"  mov   a4, %4 \n" \
+	"  mov   a3, %3 \n" \
+	"  movi  a2, %1 \n" \
+	"  syscall      \n" \
+	"  mov   %0, a2 \n" \
+	: "=a" (__res) \
+	: "i" (__NR_##name), "a" (arg0), "a" (arg1), "a" (arg2), "a" (arg3) \
+	: "a2", "a3", "a4", "a5", "a6" \
+	); \
+__syscall_return(type,__res); \
+}
+
+/* Note that we save and restore the a7 frame pointer.
+ * Including a7 in the clobber list doesn't do what you'd expect.
+ */
+#define _syscall5(type,name,type0,arg0,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
+type name(type0 arg0,type1 arg1,type2 arg2,type3 arg3,type4 arg4) \
+{ \
+long __res; \
+__asm__ __volatile__ ( \
+	"  mov   a9, a7 \n" \
+	"  mov   a7, %2 \n" \
+	"  mov   a6, %6 \n" \
+	"  mov   a5, %5 \n" \
+	"  mov   a4, %4 \n" \
+	"  mov   a3, %3 \n" \
+	"  movi  a2, %1 \n" \
+	"  syscall      \n" \
+	"  mov   a7, a9 \n" \
+	"  mov   %0, a2 \n" \
+	: "=a" (__res) \
+	: "i" (__NR_##name), "a" (arg0), "a" (arg1), "a" (arg2), \
+                             "a" (arg3), "a" (arg4) \
+	: "a2", "a3", "a4", "a5", "a6", "a9" \
+	); \
+__syscall_return(type,__res); \
+}
+
+/* Note that we save and restore the a7 frame pointer.
+ * Including a7 in the clobber list doesn't do what you'd expect.
+ */
+#define _syscall6(type,name,type0,arg0,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \
+type name(type0 arg0,type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \
+{ \
+long __res; \
+__asm__ __volatile__ ( \
+	"  mov   a9, a7 \n" \
+	"  mov   a8, %2 \n" \
+	"  mov   a7, %7 \n" \
+	"  mov   a6, %6 \n" \
+	"  mov   a5, %5 \n" \
+	"  mov   a4, %4 \n" \
+	"  mov   a3, %3 \n" \
+	"  movi  a2, %1 \n" \
+	"  syscall      \n" \
+	"  mov   a7, a9 \n" \
+	"  mov   %0, a2 \n" \
+	: "=a" (__res) \
+	: "i" (__NR_##name), "a" (arg0), "a" (arg1), "a" (arg2), \
+                             "a" (arg3), "a" (arg4), "a" (arg5)  \
+	: "a2", "a3", "a4", "a5", "a6", "a8", "a9" \
+	); \
+__syscall_return(type,__res); \
+}
+
+
+#ifdef __KERNEL_SYSCALLS__
+static __inline__ _syscall3(int,execve,const char*,file,char**,argv,char**,envp)
+#endif
+
+/*
+ * "Conditional" syscalls
+ *
+ * What we want is __attribute__((weak,alias("sys_ni_syscall"))),
+ * but it doesn't work on all toolchains, so we just do it by hand
+ */
+#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall");
+
+#ifdef __KERNEL__
+#define __ARCH_WANT_STAT64
+#define __ARCH_WANT_SYS_UTIME
+#define __ARCH_WANT_SYS_LLSEEK
+#define __ARCH_WANT_SYS_RT_SIGACTION
+#endif
+
+#endif	/* _XTENSA_UNISTD_H */
diff --git a/include/asm-xtensa/user.h b/include/asm-xtensa/user.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/user.h
@@ -0,0 +1,20 @@
+/*
+ * include/asm-xtensa/user.h
+ *
+ * Xtensa Processor version.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_USER_H
+#define _XTENSA_USER_H
+
+/* This file usually defines a 'struct user' structure. However, it it only
+ * used for a.out file, which are not supported on Xtensa.
+ */
+
+#endif	/* _XTENSA_USER_H */
diff --git a/include/asm-xtensa/vga.h b/include/asm-xtensa/vga.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/vga.h
@@ -0,0 +1,19 @@
+/*
+ * include/asm-xtensa/vga.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_VGA_H
+#define _XTENSA_VGA_H
+
+#define VGA_MAP_MEM(x) (unsigned long)phys_to_virt(x)
+
+#define vga_readb(x)	(*(x))
+#define vga_writeb(x,y)	(*(y) = (x))
+
+#endif
diff --git a/include/asm-xtensa/xor.h b/include/asm-xtensa/xor.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/xor.h
@@ -0,0 +1,16 @@
+/*
+ * include/asm-xtensa/xor.h
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 - 2005 Tensilica Inc.
+ */
+
+#ifndef _XTENSA_XOR_H
+#define _XTENSA_XOR_H
+
+#include <asm-generic/xor.h>
+
+#endif
diff --git a/include/asm-xtensa/xtensa/cacheasm.h b/include/asm-xtensa/xtensa/cacheasm.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/xtensa/cacheasm.h
@@ -0,0 +1,708 @@
+#ifndef XTENSA_CACHEASM_H
+#define XTENSA_CACHEASM_H
+
+/*
+ * THIS FILE IS GENERATED -- DO NOT MODIFY BY HAND
+ *
+ * include/asm-xtensa/xtensa/cacheasm.h -- assembler-specific cache
+ * related definitions that depend on CORE configuration.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2002 Tensilica Inc.
+ */
+
+
+#include <xtensa/coreasm.h>
+
+
+/*
+ *  This header file defines assembler macros of the form:
+ *	<x>cache_<func>
+ *  where <x> is 'i' or 'd' for instruction and data caches,
+ *  and <func> indicates the function of the macro.
+ *
+ *  The following functions <func> are defined,
+ *  and apply only to the specified cache (I or D):
+ *
+ *  reset
+ *	Resets the cache.
+ *
+ *  sync
+ *	Makes sure any previous cache instructions have been completed;
+ *	ie. makes sure any previous cache control operations
+ *	have had full effect and been synchronized to memory.
+ *	Eg. any invalidate completed [so as not to generate a hit],
+ *	any writebacks or other pipelined writes written to memory, etc.
+ *
+ *  invalidate_line		(single cache line)
+ *  invalidate_region		(specified memory range)
+ *  invalidate_all		(entire cache)
+ *	Invalidates all cache entries that cache
+ *	data from the specified memory range.
+ *	NOTE: locked entries are not invalidated.
+ *
+ *  writeback_line		(single cache line)
+ *  writeback_region		(specified memory range)
+ *  writeback_all		(entire cache)
+ *	Writes back to memory all dirty cache entries
+ *	that cache data from the specified memory range,
+ *	and marks these entries as clean.
+ *	NOTE: on some future implementations, this might
+ *		also invalidate.
+ *	NOTE: locked entries are written back, but never invalidated.
+ *	NOTE: instruction caches never implement writeback.
+ *
+ *  writeback_inv_line		(single cache line)
+ *  writeback_inv_region	(specified memory range)
+ *  writeback_inv_all		(entire cache)
+ *	Writes back to memory all dirty cache entries
+ *	that cache data from the specified memory range,
+ *	and invalidates these entries (including all clean
+ *	cache entries that cache data from that range).
+ *	NOTE: locked entries are written back but not invalidated.
+ *	NOTE: instruction caches never implement writeback.
+ *
+ *  lock_line			(single cache line)
+ *  lock_region			(specified memory range)
+ *	Prefetch and lock the specified memory range into cache.
+ *	NOTE:  if any part of the specified memory range cannot
+ *	be locked, a ??? exception occurs.  These macros don't
+ *	do anything special (yet anyway) to handle this situation.
+ *
+ *  unlock_line			(single cache line)
+ *  unlock_region		(specified memory range)
+ *  unlock_all			(entire cache)
+ *	Unlock cache entries that cache the specified memory range.
+ *	Entries not already locked are unaffected.
+ */
+
+
+
+/***************************   GENERIC -- ALL CACHES   ***************************/
+
+
+/*
+ *  The following macros assume the following cache size/parameter limits
+ *  in the current Xtensa core implementation:
+ *	cache size:	1024 bytes minimum
+ *	line size:	16 - 64 bytes
+ *	way count:	1 - 4
+ *
+ *  Minimum entries per way (ie. per associativity) = 1024 / 64 / 4 = 4
+ *  Hence the assumption that each loop can execute four cache instructions.
+ *
+ *  Correspondingly, the offset range of instructions is assumed able to cover
+ *  four lines, ie. offsets {0,1,2,3} * line_size are assumed valid for
+ *  both hit and indexed cache instructions.  Ie. these offsets are all
+ *  valid:  0, 16, 32, 48, 64, 96, 128, 192 (for line sizes 16, 32, 64).
+ *  This is true of all original cache instructions
+ *  (dhi, ihi, dhwb, dhwbi, dii, iii) which have offsets
+ *  of 0 to 1020 in multiples of 4 (ie. 8 bits shifted by 2).
+ *  This is also true of subsequent cache instructions
+ *  (dhu, ihu, diu, iiu, diwb, diwbi, dpfl, ipfl) which have offsets
+ *  of 0 to 240 in multiples of 16 (ie. 4 bits shifted by 4).
+ *
+ *  (Maximum cache size, currently 32k, doesn't affect the following macros.
+ *  Cache ways > MMU min page size cause aliasing but that's another matter.)
+ */
+
+
+
+/*
+ *  Macro to apply an 'indexed' cache instruction to the entire cache.
+ *
+ *  Parameters:
+ *	cainst		instruction/ that takes an address register parameter
+ *			and an offset parameter (in range 0 .. 3*linesize).
+ *	size		size of cache in bytes
+ *	linesize	size of cache line in bytes
+ *	assoc_or1	number of associativities (ways/sets) in cache
+ *			if all sets affected by cainst,
+ *			or 1 if only one set (or not all sets) of the cache
+ *			is affected by cainst (eg. DIWB or DIWBI [not yet ISA defined]).
+ *	aa, ab		unique address registers (temporaries)
+ */
+
+	.macro	cache_index_all		cainst, size, linesize, assoc_or1, aa, ab
+
+	//  Sanity-check on cache parameters:
+	.ifne	(\size % (\linesize * \assoc_or1 * 4))
+	.err	//  cache configuration outside expected/supported range!
+	.endif
+
+	//  \size byte cache, \linesize byte lines, \assoc_or1 way(s) affected by each \cainst.
+	movi	\aa, (\size / (\linesize * \assoc_or1 * 4))
+	// Possible improvement: need only loop if \aa > 1 ;
+	// however that particular condition is highly unlikely.
+	movi	\ab, 0		// to iterate over cache
+	floop		\aa, cachex\@
+	\cainst		\ab, 0*\linesize
+	\cainst		\ab, 1*\linesize
+	\cainst		\ab, 2*\linesize
+	\cainst		\ab, 3*\linesize
+	addi		\ab, \ab, 4*\linesize	// move to next line
+	floopend	\aa, cachex\@
+
+	.endm
+
+
+/*
+ *  Macro to apply a 'hit' cache instruction to a memory region,
+ *  ie. to any cache entries that cache a specified portion (region) of memory.
+ *  Takes care of the unaligned cases, ie. may apply to one
+ *  more cache line than $asize / lineSize if $aaddr is not aligned.
+ *
+ *
+ *  Parameters are:
+ *	cainst	instruction/macro that takes an address register parameter
+ *		and an offset parameter (currently always zero)
+ *		and generates a cache instruction (eg. "dhi", "dhwb", "ihi", etc.)
+ *	linesize_log2	log2(size of cache line in bytes)
+ *	addr	register containing start address of region (clobbered)
+ *	asize	register containing size of the region in bytes (clobbered)
+ *	askew	unique register used as temporary
+ *
+ * !?!?! 2DO: optimization: iterate max(cache_size and \asize) / linesize
+ */
+
+	.macro	cache_hit_region	cainst, linesize_log2, addr, asize, askew
+
+	//  Make \asize the number of iterations:
+	extui	\askew, \addr, 0, \linesize_log2	// get unalignment amount of \addr
+	add	\asize, \asize, \askew			// ... and add it to \asize
+	addi	\asize, \asize, (1 << \linesize_log2) - 1	// round up!
+	srli	\asize, \asize, \linesize_log2
+
+	//  Iterate over region:
+	floopnez	\asize, cacheh\@
+	\cainst		\addr, 0
+	addi		\addr, \addr, (1 << \linesize_log2)	// move to next line
+	floopend	\asize, cacheh\@
+
+	.endm
+
+
+
+
+
+/***************************   INSTRUCTION CACHE   ***************************/
+
+
+/*
+ *  Reset/initialize the instruction cache by simply invalidating it:
+ *  (need to unlock first also, if cache locking implemented):
+ *
+ *  Parameters:
+ *	aa, ab		unique address registers (temporaries)
+ */
+	.macro	icache_reset	aa, ab
+	icache_unlock_all	\aa, \ab
+	icache_invalidate_all	\aa, \ab
+	.endm
+
+
+/*
+ * Synchronize after an instruction cache operation,
+ * to be sure everything is in sync with memory as to be
+ * expected following any previous instruction cache control operations.
+ *
+ * Parameters are:
+ *	ar	an address register (temporary) (currently unused, but may be used in future)
+ */
+	.macro	icache_sync	ar
+#if XCHAL_ICACHE_SIZE > 0
+	isync
+#endif
+	.endm
+
+
+
+/*
+ *  Invalidate a single line of the instruction cache.
+ *  Parameters are:
+ *	ar	address register that contains (virtual) address to invalidate
+ *		(may get clobbered in a future implementation, but not currently)
+ *	offset	(optional) offset to add to \ar to compute effective address to invalidate
+ *		(note: some number of lsbits are ignored)
+ */
+	.macro	icache_invalidate_line	ar, offset
+#if XCHAL_ICACHE_SIZE > 0
+	ihi	\ar, \offset		// invalidate icache line
+	/*
+	 *  NOTE:  in some version of the silicon [!!!SHOULD HAVE BEEN DOCUMENTED!!!]
+	 *  'ihi' doesn't work, so it had been replaced with 'iii'
+	 *  (which would just invalidate more than it should,
+	 *  which should be okay other than the performance hit
+	 *  because cache locking did not exist in that version,
+	 *  unless user somehow relies on something being cached).
+	 *  [WHAT VERSION IS IT!!?!?
+	 *  IS THERE ANY WAY TO TEST FOR THAT HERE, TO OUTPUT 'III' ONLY IF NEEDED!?!?].
+	 *
+	 *	iii	\ar, \offset
+	 */
+	icache_sync	\ar
+#endif
+	.endm
+
+
+
+
+/*
+ *  Invalidate instruction  cache entries that cache a specified portion of memory.
+ *  Parameters are:
+ *	astart	start address (register gets clobbered)
+ *	asize	size of the region in bytes (register gets clobbered)
+ *	ac	unique register used as temporary
+ */
+	.macro	icache_invalidate_region	astart, asize, ac
+#if XCHAL_ICACHE_SIZE > 0
+	//  Instruction cache region invalidation:
+	cache_hit_region	ihi, XCHAL_ICACHE_LINEWIDTH, \astart, \asize, \ac
+	icache_sync	\ac
+	//  End of instruction cache region invalidation
+#endif
+	.endm
+
+
+
+/*
+ *  Invalidate entire instruction cache.
+ *
+ *  Parameters:
+ *	aa, ab		unique address registers (temporaries)
+ */
+	.macro	icache_invalidate_all	aa, ab
+#if XCHAL_ICACHE_SIZE > 0
+	//  Instruction cache invalidation:
+	cache_index_all		iii, XCHAL_ICACHE_SIZE, XCHAL_ICACHE_LINESIZE, XCHAL_ICACHE_WAYS, \aa, \ab
+	icache_sync	\aa
+	//  End of instruction cache invalidation
+#endif
+	.endm
+
+
+
+/*
+ *  Lock (prefetch & lock) a single line of the instruction cache.
+ *
+ *  Parameters are:
+ *	ar	address register that contains (virtual) address to lock
+ *		(may get clobbered in a future implementation, but not currently)
+ *	offset	offset to add to \ar to compute effective address to lock
+ *		(note: some number of lsbits are ignored)
+ */
+	.macro	icache_lock_line	ar, offset
+#if XCHAL_ICACHE_SIZE > 0 && XCHAL_ICACHE_LINE_LOCKABLE
+	ipfl	\ar, \offset	/* prefetch and lock icache line */
+	icache_sync	\ar
+#endif
+	.endm
+
+
+
+/*
+ *  Lock (prefetch & lock) a specified portion of memory into the instruction cache.
+ *  Parameters are:
+ *	astart	start address (register gets clobbered)
+ *	asize	size of the region in bytes (register gets clobbered)
+ *	ac	unique register used as temporary
+ */
+	.macro	icache_lock_region	astart, asize, ac
+#if XCHAL_ICACHE_SIZE > 0 && XCHAL_ICACHE_LINE_LOCKABLE
+	//  Instruction cache region lock:
+	cache_hit_region	ipfl, XCHAL_ICACHE_LINEWIDTH, \astart, \asize, \ac
+	icache_sync	\ac
+	//  End of instruction cache region lock
+#endif
+	.endm
+
+
+
+/*
+ *  Unlock a single line of the instruction cache.
+ *
+ *  Parameters are:
+ *	ar	address register that contains (virtual) address to unlock
+ *		(may get clobbered in a future implementation, but not currently)
+ *	offset	offset to add to \ar to compute effective address to unlock
+ *		(note: some number of lsbits are ignored)
+ */
+	.macro	icache_unlock_line	ar, offset
+#if XCHAL_ICACHE_SIZE > 0 && XCHAL_ICACHE_LINE_LOCKABLE
+	ihu	\ar, \offset	/* unlock icache line */
+	icache_sync	\ar
+#endif
+	.endm
+
+
+
+/*
+ *  Unlock a specified portion of memory from the instruction cache.
+ *  Parameters are:
+ *	astart	start address (register gets clobbered)
+ *	asize	size of the region in bytes (register gets clobbered)
+ *	ac	unique register used as temporary
+ */
+	.macro	icache_unlock_region	astart, asize, ac
+#if XCHAL_ICACHE_SIZE > 0 && XCHAL_ICACHE_LINE_LOCKABLE
+	//  Instruction cache region unlock:
+	cache_hit_region	ihu, XCHAL_ICACHE_LINEWIDTH, \astart, \asize, \ac
+	icache_sync	\ac
+	//  End of instruction cache region unlock
+#endif
+	.endm
+
+
+
+/*
+ *  Unlock entire instruction cache.
+ *
+ *  Parameters:
+ *	aa, ab		unique address registers (temporaries)
+ */
+	.macro	icache_unlock_all	aa, ab
+#if XCHAL_ICACHE_SIZE > 0 && XCHAL_ICACHE_LINE_LOCKABLE
+	//  Instruction cache unlock:
+	cache_index_all		iiu, XCHAL_ICACHE_SIZE, XCHAL_ICACHE_LINESIZE, 1, \aa, \ab
+	icache_sync	\aa
+	//  End of instruction cache unlock
+#endif
+	.endm
+
+
+
+
+
+/***************************   DATA CACHE   ***************************/
+
+
+
+/*
+ *  Reset/initialize the data cache by simply invalidating it
+ *  (need to unlock first also, if cache locking implemented):
+ *
+ *  Parameters:
+ *	aa, ab		unique address registers (temporaries)
+ */
+	.macro	dcache_reset	aa, ab
+	dcache_unlock_all	\aa, \ab
+	dcache_invalidate_all	\aa, \ab
+	.endm
+
+
+
+
+/*
+ * Synchronize after a data cache operation,
+ * to be sure everything is in sync with memory as to be
+ * expected following any previous data cache control operations.
+ *
+ * Parameters are:
+ *	ar	an address register (temporary) (currently unused, but may be used in future)
+ */
+	.macro	dcache_sync	ar
+#if XCHAL_DCACHE_SIZE > 0
+	//  This previous sequence errs on the conservative side (too much so); a DSYNC should be sufficient:
+	//memw		// synchronize data cache changes relative to subsequent memory accesses
+	//isync		// be conservative and ISYNC as well (just to be sure)
+
+	dsync
+#endif
+	.endm
+
+
+
+/*
+ * Synchronize after a data store operation,
+ * to be sure the stored data is completely off the processor
+ * (and assuming there is no buffering outside the processor,
+ *  that the data is in memory).  This may be required to
+ * ensure that the processor's write buffers are emptied.
+ * A MEMW followed by a read guarantees this, by definition.
+ * We also try to make sure the read itself completes.
+ *
+ * Parameters are:
+ *	ar	an address register (temporary)
+ */
+	.macro	write_sync	ar
+	memw			// ensure previous memory accesses are complete prior to subsequent memory accesses
+	l32i	\ar, sp, 0	// completing this read ensures any previous write has completed, because of MEMW
+	//slot
+	add	\ar, \ar, \ar	// use the result of the read to help ensure the read completes (in future architectures)
+	.endm
+
+
+/*
+ *  Invalidate a single line of the data cache.
+ *  Parameters are:
+ *	ar	address register that contains (virtual) address to invalidate
+ *		(may get clobbered in a future implementation, but not currently)
+ *	offset	(optional) offset to add to \ar to compute effective address to invalidate
+ *		(note: some number of lsbits are ignored)
+ */
+	.macro	dcache_invalidate_line	ar, offset
+#if XCHAL_DCACHE_SIZE > 0
+	dhi	\ar, \offset
+	dcache_sync	\ar
+#endif
+	.endm
+
+
+
+
+
+/*
+ *  Invalidate data cache entries that cache a specified portion of memory.
+ *  Parameters are:
+ *	astart	start address (register gets clobbered)
+ *	asize	size of the region in bytes (register gets clobbered)
+ *	ac	unique register used as temporary
+ */
+	.macro	dcache_invalidate_region	astart, asize, ac
+#if XCHAL_DCACHE_SIZE > 0
+	//  Data cache region invalidation:
+	cache_hit_region	dhi, XCHAL_DCACHE_LINEWIDTH, \astart, \asize, \ac
+	dcache_sync	\ac
+	//  End of data cache region invalidation
+#endif
+	.endm
+
+
+
+#if 0
+/*
+ *  This is a work-around for a bug in SiChip1 (???).
+ *  There should be a proper mechanism for not outputting
+ *  these instructions when not needed.
+ *  To enable work-around, uncomment this and replace 'dii'
+ *  with 'dii_s1' everywhere, eg. in dcache_invalidate_all
+ *  macro below.
+ */
+	.macro	dii_s1	ar, offset
+	dii	\ar, \offset
+	or	\ar, \ar, \ar
+	or	\ar, \ar, \ar
+	or	\ar, \ar, \ar
+	or	\ar, \ar, \ar
+	.endm
+#endif
+
+
+/*
+ *  Invalidate entire data cache.
+ *
+ *  Parameters:
+ *	aa, ab		unique address registers (temporaries)
+ */
+	.macro	dcache_invalidate_all	aa, ab
+#if XCHAL_DCACHE_SIZE > 0
+	//  Data cache invalidation:
+	cache_index_all		dii, XCHAL_DCACHE_SIZE, XCHAL_DCACHE_LINESIZE, XCHAL_DCACHE_WAYS, \aa, \ab
+	dcache_sync	\aa
+	//  End of data cache invalidation
+#endif
+	.endm
+
+
+
+/*
+ *  Writeback a single line of the data cache.
+ *  Parameters are:
+ *	ar	address register that contains (virtual) address to writeback
+ *		(may get clobbered in a future implementation, but not currently)
+ *	offset	offset to add to \ar to compute effective address to writeback
+ *		(note: some number of lsbits are ignored)
+ */
+	.macro	dcache_writeback_line	ar, offset
+#if XCHAL_DCACHE_SIZE > 0 && XCHAL_DCACHE_IS_WRITEBACK
+	dhwb	\ar, \offset
+	dcache_sync	\ar
+#endif
+	.endm
+
+
+
+/*
+ *  Writeback dirty data cache entries that cache a specified portion of memory.
+ *  Parameters are:
+ *	astart	start address (register gets clobbered)
+ *	asize	size of the region in bytes (register gets clobbered)
+ *	ac	unique register used as temporary
+ */
+	.macro	dcache_writeback_region		astart, asize, ac
+#if XCHAL_DCACHE_SIZE > 0 && XCHAL_DCACHE_IS_WRITEBACK
+	//  Data cache region writeback:
+	cache_hit_region	dhwb, XCHAL_DCACHE_LINEWIDTH, \astart, \asize, \ac
+	dcache_sync	\ac
+	//  End of data cache region writeback
+#endif
+	.endm
+
+
+
+/*
+ *  Writeback entire data cache.
+ *  Parameters:
+ *	aa, ab		unique address registers (temporaries)
+ */
+	.macro	dcache_writeback_all	aa, ab
+#if XCHAL_DCACHE_SIZE > 0 && XCHAL_DCACHE_IS_WRITEBACK
+	//  Data cache writeback:
+	cache_index_all		diwb, XCHAL_DCACHE_SIZE, XCHAL_DCACHE_LINESIZE, 1, \aa, \ab
+	dcache_sync	\aa
+	//  End of data cache writeback
+#endif
+	.endm
+
+
+
+/*
+ *  Writeback and invalidate a single line of the data cache.
+ *  Parameters are:
+ *	ar	address register that contains (virtual) address to writeback and invalidate
+ *		(may get clobbered in a future implementation, but not currently)
+ *	offset	offset to add to \ar to compute effective address to writeback and invalidate
+ *		(note: some number of lsbits are ignored)
+ */
+	.macro	dcache_writeback_inv_line	ar, offset
+#if XCHAL_DCACHE_SIZE > 0
+	dhwbi	\ar, \offset	/* writeback and invalidate dcache line */
+	dcache_sync	\ar
+#endif
+	.endm
+
+
+
+/*
+ *  Writeback and invalidate data cache entries that cache a specified portion of memory.
+ *  Parameters are:
+ *	astart	start address (register gets clobbered)
+ *	asize	size of the region in bytes (register gets clobbered)
+ *	ac	unique register used as temporary
+ */
+	.macro	dcache_writeback_inv_region	astart, asize, ac
+#if XCHAL_DCACHE_SIZE > 0
+	//  Data cache region writeback and invalidate:
+	cache_hit_region	dhwbi, XCHAL_DCACHE_LINEWIDTH, \astart, \asize, \ac
+	dcache_sync	\ac
+	//  End of data cache region writeback and invalidate
+#endif
+	.endm
+
+
+
+/*
+ *  Writeback and invalidate entire data cache.
+ *  Parameters:
+ *	aa, ab		unique address registers (temporaries)
+ */
+	.macro	dcache_writeback_inv_all	aa, ab
+#if XCHAL_DCACHE_SIZE > 0
+	//  Data cache writeback and invalidate:
+#if XCHAL_DCACHE_IS_WRITEBACK
+	cache_index_all		diwbi, XCHAL_DCACHE_SIZE, XCHAL_DCACHE_LINESIZE, 1, \aa, \ab
+	dcache_sync	\aa
+#else /*writeback*/
+	//  Data cache does not support writeback, so just invalidate: */
+	dcache_invalidate_all	\aa, \ab
+#endif /*writeback*/
+	//  End of data cache writeback and invalidate
+#endif
+	.endm
+
+
+
+
+/*
+ *  Lock (prefetch & lock) a single line of the data cache.
+ *
+ *  Parameters are:
+ *	ar	address register that contains (virtual) address to lock
+ *		(may get clobbered in a future implementation, but not currently)
+ *	offset	offset to add to \ar to compute effective address to lock
+ *		(note: some number of lsbits are ignored)
+ */
+	.macro	dcache_lock_line	ar, offset
+#if XCHAL_DCACHE_SIZE > 0 && XCHAL_DCACHE_LINE_LOCKABLE
+	dpfl	\ar, \offset	/* prefetch and lock dcache line */
+	dcache_sync	\ar
+#endif
+	.endm
+
+
+
+/*
+ *  Lock (prefetch & lock) a specified portion of memory into the data cache.
+ *  Parameters are:
+ *	astart	start address (register gets clobbered)
+ *	asize	size of the region in bytes (register gets clobbered)
+ *	ac	unique register used as temporary
+ */
+	.macro	dcache_lock_region	astart, asize, ac
+#if XCHAL_DCACHE_SIZE > 0 && XCHAL_DCACHE_LINE_LOCKABLE
+	//  Data cache region lock:
+	cache_hit_region	dpfl, XCHAL_DCACHE_LINEWIDTH, \astart, \asize, \ac
+	dcache_sync	\ac
+	//  End of data cache region lock
+#endif
+	.endm
+
+
+
+/*
+ *  Unlock a single line of the data cache.
+ *
+ *  Parameters are:
+ *	ar	address register that contains (virtual) address to unlock
+ *		(may get clobbered in a future implementation, but not currently)
+ *	offset	offset to add to \ar to compute effective address to unlock
+ *		(note: some number of lsbits are ignored)
+ */
+	.macro	dcache_unlock_line	ar, offset
+#if XCHAL_DCACHE_SIZE > 0 && XCHAL_DCACHE_LINE_LOCKABLE
+	dhu	\ar, \offset	/* unlock dcache line */
+	dcache_sync	\ar
+#endif
+	.endm
+
+
+
+/*
+ *  Unlock a specified portion of memory from the data cache.
+ *  Parameters are:
+ *	astart	start address (register gets clobbered)
+ *	asize	size of the region in bytes (register gets clobbered)
+ *	ac	unique register used as temporary
+ */
+	.macro	dcache_unlock_region	astart, asize, ac
+#if XCHAL_DCACHE_SIZE > 0 && XCHAL_DCACHE_LINE_LOCKABLE
+	//  Data cache region unlock:
+	cache_hit_region	dhu, XCHAL_DCACHE_LINEWIDTH, \astart, \asize, \ac
+	dcache_sync	\ac
+	//  End of data cache region unlock
+#endif
+	.endm
+
+
+
+/*
+ *  Unlock entire data cache.
+ *
+ *  Parameters:
+ *	aa, ab		unique address registers (temporaries)
+ */
+	.macro	dcache_unlock_all	aa, ab
+#if XCHAL_DCACHE_SIZE > 0 && XCHAL_DCACHE_LINE_LOCKABLE
+	//  Data cache unlock:
+	cache_index_all		diu, XCHAL_DCACHE_SIZE, XCHAL_DCACHE_LINESIZE, 1, \aa, \ab
+	dcache_sync	\aa
+	//  End of data cache unlock
+#endif
+	.endm
+
+
+#endif /*XTENSA_CACHEASM_H*/
+
diff --git a/include/asm-xtensa/xtensa/cacheattrasm.h b/include/asm-xtensa/xtensa/cacheattrasm.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/xtensa/cacheattrasm.h
@@ -0,0 +1,432 @@
+#ifndef XTENSA_CACHEATTRASM_H
+#define XTENSA_CACHEATTRASM_H
+
+/*
+ * THIS FILE IS GENERATED -- DO NOT MODIFY BY HAND
+ *
+ * include/asm-xtensa/xtensa/cacheattrasm.h -- assembler-specific
+ * CACHEATTR register related definitions that depend on CORE
+ * configuration.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2002 Tensilica Inc.
+ */
+
+
+#include <xtensa/coreasm.h>
+
+
+/*
+ *  This header file defines assembler macros of the form:
+ *	<x>cacheattr_<func>
+ *  where:
+ *	<x> is 'i', 'd' or absent for instruction, data
+ *		or both caches; and
+ *	<func> indicates the function of the macro.
+ *
+ *  The following functions are defined:
+ *
+ *  icacheattr_get
+ *	Reads I-cache CACHEATTR into a2 (clobbers a3-a5).
+ *
+ *  dcacheattr_get
+ *	Reads D-cache CACHEATTR into a2 (clobbers a3-a5).
+ *	(Note:  for configs with a real CACHEATTR register, the
+ *	 above two macros are identical.)
+ *
+ *  cacheattr_set
+ *	Writes both I-cache and D-cache CACHEATTRs from a2 (a3-a8 clobbered).
+ *	Works even when changing one's own code's attributes.
+ *
+ *  icacheattr_is_enabled  label
+ *	Branches to \label if I-cache appears to have been enabled
+ *	(eg. if CACHEATTR contains a cache-enabled attribute).
+ *	(clobbers a2-a5,SAR)
+ *
+ *  dcacheattr_is_enabled  label
+ *	Branches to \label if D-cache appears to have been enabled
+ *	(eg. if CACHEATTR contains a cache-enabled attribute).
+ *	(clobbers a2-a5,SAR)
+ *
+ *  cacheattr_is_enabled  label
+ *	Branches to \label if either I-cache or D-cache appears to have been enabled
+ *	(eg. if CACHEATTR contains a cache-enabled attribute).
+ *	(clobbers a2-a5,SAR)
+ *
+ *  The following macros are only defined under certain conditions:
+ *
+ *  icacheattr_set	(if XCHAL_HAVE_MIMIC_CACHEATTR || XCHAL_HAVE_XLT_CACHEATTR)
+ *	Writes I-cache CACHEATTR from a2 (a3-a8 clobbered).
+ *
+ *  dcacheattr_set	(if XCHAL_HAVE_MIMIC_CACHEATTR || XCHAL_HAVE_XLT_CACHEATTR)
+ *	Writes D-cache CACHEATTR from a2 (a3-a8 clobbered).
+ */
+
+
+
+/***************************   GENERIC -- ALL CACHES   ***************************/
+
+/*
+ *  _cacheattr_get
+ *
+ *  (Internal macro.)
+ *  Returns value of CACHEATTR register (or closest equivalent) in a2.
+ *
+ *  Entry:
+ *	(none)
+ *  Exit:
+ *	a2	value read from CACHEATTR
+ *	a3-a5	clobbered (temporaries)
+ */
+	.macro	_cacheattr_get	tlb
+#if XCHAL_HAVE_CACHEATTR
+	rsr	a2, CACHEATTR
+#elif XCHAL_HAVE_MIMIC_CACHEATTR || XCHAL_HAVE_XLT_CACHEATTR
+	//  We have a config that "mimics" CACHEATTR using a simplified
+	//  "MMU" composed of a single statically-mapped way.
+	//  DTLB and ITLB are independent, so there's no single
+	//  cache attribute that can describe both.  So for now
+	//  just return the DTLB state.
+	movi	a5, 0xE0000000
+	movi	a2, 0
+	movi	a3, 0
+1:	add	a3, a3, a5	// next segment
+	r&tlb&1	a4, a3		// get PPN+CA of segment at 0xE0000000, 0xC0000000, ..., 0
+	dsync	// interlock???
+	slli	a2, a2, 4
+	extui	a4, a4, 0, 4	// extract CA
+	or	a2, a2, a4
+	bnez	a3, 1b
+#else
+	//  This macro isn't applicable to arbitrary MMU configurations.
+	//  Just return zero.
+	movi	a2, 0
+#endif
+	.endm
+
+	.macro	icacheattr_get
+	_cacheattr_get	itlb
+	.endm
+
+	.macro	dcacheattr_get
+	_cacheattr_get	dtlb
+	.endm
+
+
+#define XCHAL_CACHEATTR_ALL_BYPASS	0x22222222	/* default (powerup/reset) value of CACHEATTR, all BYPASS
+							   mode (ie. disabled/bypassed caches) */
+
+#if XCHAL_HAVE_CACHEATTR || XCHAL_HAVE_MIMIC_CACHEATTR || XCHAL_HAVE_XLT_CACHEATTR
+
+#define XCHAL_FCA_ENAMASK	0x001A	/* bitmap of fetch attributes that require enabled icache */
+#define XCHAL_LCA_ENAMASK	0x0003	/* bitmap of load  attributes that require enabled dcache */
+#define XCHAL_SCA_ENAMASK	0x0003	/* bitmap of store attributes that require enabled dcache */
+#define XCHAL_LSCA_ENAMASK	(XCHAL_LCA_ENAMASK|XCHAL_SCA_ENAMASK)	/* l/s attrs requiring enabled dcache */
+#define XCHAL_ALLCA_ENAMASK	(XCHAL_FCA_ENAMASK|XCHAL_LSCA_ENAMASK)	/* all attrs requiring enabled caches */
+
+/*
+ *  _cacheattr_is_enabled
+ *
+ *  (Internal macro.)
+ *  Branches to \label if CACHEATTR in a2 indicates an enabled
+ *  cache, using mask in a3.
+ *
+ *  Parameters:
+ *	label	where to branch to if cache is enabled
+ *  Entry:
+ *	a2	contains CACHEATTR value used to determine whether
+ *		caches are enabled
+ *	a3	16-bit constant where each bit correspond to
+ *		one of the 16 possible CA values (in a CACHEATTR mask);
+ *		CA values that indicate the cache is enabled
+ *		have their corresponding bit set in this mask
+ *		(eg. use XCHAL_xCA_ENAMASK , above)
+ *  Exit:
+ *	a2,a4,a5	clobbered
+ *	SAR		clobbered
+ */
+	.macro	_cacheattr_is_enabled	label
+	movi	a4, 8		// loop 8 times
+.Lcaife\@:
+	extui	a5, a2, 0, 4	// get CA nibble
+	ssr	a5		// index into mask according to CA...
+	srl	a5, a3		// ...and get CA's mask bit in a5 bit 0
+	bbsi.l	a5, 0, \label	// if CA indicates cache enabled, jump to label
+	srli	a2, a2, 4	// next nibble
+	addi	a4, a4, -1
+	bnez	a4, .Lcaife\@	// loop for each nibble
+	.endm
+
+#else /* XCHAL_HAVE_CACHEATTR || XCHAL_HAVE_MIMIC_CACHEATTR || XCHAL_HAVE_XLT_CACHEATTR */
+	.macro	_cacheattr_is_enabled	label
+	j	\label		// macro not applicable, assume caches always enabled
+	.endm
+#endif /* XCHAL_HAVE_CACHEATTR || XCHAL_HAVE_MIMIC_CACHEATTR || XCHAL_HAVE_XLT_CACHEATTR */
+
+
+
+/*
+ *  icacheattr_is_enabled
+ *
+ *  Branches to \label if I-cache is enabled.
+ *
+ *  Parameters:
+ *	label	where to branch to if icache is enabled
+ *  Entry:
+ *	(none)
+ *  Exit:
+ *	a2-a5, SAR	clobbered (temporaries)
+ */
+	.macro	icacheattr_is_enabled	label
+#if XCHAL_HAVE_CACHEATTR || XCHAL_HAVE_MIMIC_CACHEATTR || XCHAL_HAVE_XLT_CACHEATTR
+	icacheattr_get
+	movi	a3, XCHAL_FCA_ENAMASK
+#endif
+	_cacheattr_is_enabled	\label
+	.endm
+
+/*
+ *  dcacheattr_is_enabled
+ *
+ *  Branches to \label if D-cache is enabled.
+ *
+ *  Parameters:
+ *	label	where to branch to if dcache is enabled
+ *  Entry:
+ *	(none)
+ *  Exit:
+ *	a2-a5, SAR	clobbered (temporaries)
+ */
+	.macro	dcacheattr_is_enabled	label
+#if XCHAL_HAVE_CACHEATTR || XCHAL_HAVE_MIMIC_CACHEATTR || XCHAL_HAVE_XLT_CACHEATTR
+	dcacheattr_get
+	movi	a3, XCHAL_LSCA_ENAMASK
+#endif
+	_cacheattr_is_enabled	\label
+	.endm
+
+/*
+ *  cacheattr_is_enabled
+ *
+ *  Branches to \label if either I-cache or D-cache is enabled.
+ *
+ *  Parameters:
+ *	label	where to branch to if a cache is enabled
+ *  Entry:
+ *	(none)
+ *  Exit:
+ *	a2-a5, SAR	clobbered (temporaries)
+ */
+	.macro	cacheattr_is_enabled	label
+#if XCHAL_HAVE_CACHEATTR
+	rsr	a2, CACHEATTR
+	movi	a3, XCHAL_ALLCA_ENAMASK
+#elif XCHAL_HAVE_MIMIC_CACHEATTR || XCHAL_HAVE_XLT_CACHEATTR
+	icacheattr_get
+	movi	a3, XCHAL_FCA_ENAMASK
+	_cacheattr_is_enabled	\label
+	dcacheattr_get
+	movi	a3, XCHAL_LSCA_ENAMASK
+#endif
+	_cacheattr_is_enabled	\label
+	.endm
+
+
+
+/*
+ *  The ISA does not have a defined way to change the
+ *  instruction cache attributes of the running code,
+ *  ie. of the memory area that encloses the current PC.
+ *  However, each micro-architecture (or class of
+ *  configurations within a micro-architecture)
+ *  provides a way to deal with this issue.
+ *
+ *  Here are a few macros used to implement the relevant
+ *  approach taken.
+ */
+
+#if XCHAL_HAVE_MIMIC_CACHEATTR || XCHAL_HAVE_XLT_CACHEATTR
+	//  We have a config that "mimics" CACHEATTR using a simplified
+	//  "MMU" composed of a single statically-mapped way.
+
+/*
+ *  icacheattr_set
+ *
+ *  Entry:
+ *	a2		cacheattr value to set
+ *  Exit:
+ *	a2		unchanged
+ *	a3-a8		clobbered (temporaries)
+ */
+	.macro	icacheattr_set
+
+	movi	a5, 0xE0000000	// mask of upper 3 bits
+	movi	a6, 3f		// PC where ITLB is set
+	movi	a3, 0		// start at region 0 (0 .. 7)
+	and	a6, a6, a5	// upper 3 bits of local PC area
+	mov	a7, a2		// copy a2 so it doesn't get clobbered
+	j	3f
+
+# if XCHAL_HAVE_XLT_CACHEATTR
+	//  Can do translations, use generic method:
+1:	sub	a6, a3, a5	// address of some other segment
+	ritlb1	a8, a6		// save its PPN+CA
+	dsync	// interlock??
+	witlb	a4, a6		// make it translate to this code area
+	movi	a6, 5f		// where to jump into it
+	isync
+	sub	a6, a6, a5	// adjust jump address within that other segment
+	jx	a6
+
+	//  Note that in the following code snippet, which runs at a different virtual
+	//  address than it is assembled for, we avoid using literals (eg. via movi/l32r)
+	//  just in case literals end up in a different 512 MB segment, and we avoid
+	//  instructions that rely on the current PC being what is expected.
+	//
+	.align	4
+	_j	6f		// this is at label '5' minus 4 bytes
+	.align	4
+5:	witlb	a4, a3		// we're in other segment, now can write previous segment's CA
+	isync
+	add	a6, a6, a5	// back to previous segment
+	addi	a6, a6, -4	// next jump label
+	jx	a6
+
+6:	sub	a6, a3, a5	// address of some other segment
+	witlb	a8, a6		// restore PPN+CA of other segment
+	mov	a6, a3		// restore a6
+	isync
+# else /* XCHAL_HAVE_XLT_CACHEATTR */
+	//  Use micro-architecture specific method.
+	//  The following 4-instruction sequence is aligned such that
+	//  it all fits within a single I-cache line.  Sixteen byte
+	//  alignment is sufficient for this (using XCHAL_ICACHE_LINESIZE
+	//  actually causes problems because that can be greater than
+	//  the alignment of the reset vector, where this macro is often
+	//  invoked, which would cause the linker to align the reset
+	//  vector code away from the reset vector!!).
+	.align	16 /*XCHAL_ICACHE_LINESIZE*/
+1:	_witlb	a4, a3		// write wired PTE (CA, no PPN) of 512MB segment to ITLB
+	_isync
+	nop
+	nop
+# endif /* XCHAL_HAVE_XLT_CACHEATTR */
+	beq	a3, a5, 4f	// done?
+
+	//  Note that in the WITLB loop, we don't do any load/stores
+	//  (may not be an issue here, but it is important in the DTLB case).
+2:	srli	a7, a7, 4	// next CA
+	sub	a3, a3, a5	// next segment (add 0x20000000)
+3:
+# if XCHAL_HAVE_XLT_CACHEATTR	/* if have translation, preserve it */
+	ritlb1	a8, a3		// get current PPN+CA of segment
+	dsync	// interlock???
+	extui	a4, a7, 0, 4	// extract CA to set
+	srli	a8, a8, 4	// clear CA but keep PPN ...
+	slli	a8, a8, 4	// ...
+	add	a4, a4, a8	// combine new CA with PPN to preserve
+# else
+	extui	a4, a7, 0, 4	// extract CA
+# endif
+	beq	a3, a6, 1b	// current PC's region? if so, do it in a safe way
+	witlb	a4, a3		// write wired PTE (CA [+PPN]) of 512MB segment to ITLB
+	bne	a3, a5, 2b
+	isync			// make sure all ifetch changes take effect
+4:
+	.endm	// icacheattr_set
+
+
+/*
+ *  dcacheattr_set
+ *
+ *  Entry:
+ *	a2		cacheattr value to set
+ *  Exit:
+ *	a2		unchanged
+ *	a3-a8		clobbered (temporaries)
+ */
+
+	.macro	dcacheattr_set
+
+	movi	a5, 0xE0000000	// mask of upper 3 bits
+	movi	a3, 0		// start at region 0 (0 .. 7)
+	mov	a7, a2		// copy a2 so it doesn't get clobbered
+	j	3f
+	//  Note that in the WDTLB loop, we don't do any load/stores
+	//  (including implicit l32r via movi) because it isn't safe.
+2:	srli	a7, a7, 4	// next CA
+	sub	a3, a3, a5	// next segment (add 0x20000000)
+3:
+# if XCHAL_HAVE_XLT_CACHEATTR	/* if have translation, preserve it */
+	rdtlb1	a8, a3		// get current PPN+CA of segment
+	dsync	// interlock???
+	extui	a4, a7, 0, 4	// extract CA to set
+	srli	a8, a8, 4	// clear CA but keep PPN ...
+	slli	a8, a8, 4	// ...
+	add	a4, a4, a8	// combine new CA with PPN to preserve
+# else
+	extui	a4, a7, 0, 4	// extract CA to set
+# endif
+	wdtlb	a4, a3		// write wired PTE (CA [+PPN]) of 512MB segment to DTLB
+	bne	a3, a5, 2b
+	dsync			// make sure all data path changes take effect
+	.endm	// dcacheattr_set
+
+#endif /* XCHAL_HAVE_MIMIC_CACHEATTR || XCHAL_HAVE_XLT_CACHEATTR */
+
+
+
+/*
+ *  cacheattr_set
+ *
+ *  Macro that sets the current CACHEATTR safely
+ *  (both i and d) according to the current contents of a2.
+ *  It works even when changing the cache attributes of
+ *  the currently running code.
+ *
+ *  Entry:
+ *	a2		cacheattr value to set
+ *  Exit:
+ *	a2		unchanged
+ *	a3-a8		clobbered (temporaries)
+ */
+	.macro	cacheattr_set
+
+#if XCHAL_HAVE_CACHEATTR
+# if XCHAL_ICACHE_LINESIZE < 4
+	//  No i-cache, so can always safely write to CACHEATTR:
+	wsr	a2, CACHEATTR
+# else
+	//  The Athens micro-architecture, when using the old
+	//  exception architecture option (ie. with the CACHEATTR register)
+	//  allows changing the cache attributes of the running code
+	//  using the following exact sequence aligned to be within
+	//  an instruction cache line.  (NOTE: using XCHAL_ICACHE_LINESIZE
+	//  alignment actually causes problems because that can be greater
+	//  than the alignment of the reset vector, where this macro is often
+	//  invoked, which would cause the linker to align the reset
+	//  vector code away from the reset vector!!).
+	j	1f
+	.align	16 /*XCHAL_ICACHE_LINESIZE*/	// align to within an I-cache line
+1:	_wsr	a2, CACHEATTR
+	_isync
+	nop
+	nop
+# endif
+#elif XCHAL_HAVE_MIMIC_CACHEATTR || XCHAL_HAVE_XLT_CACHEATTR
+	//  DTLB and ITLB are independent, but to keep semantics
+	//  of this macro we simply write to both.
+	icacheattr_set
+	dcacheattr_set
+#else
+	//  This macro isn't applicable to arbitrary MMU configurations.
+	//  Do nothing in this case.
+#endif
+	.endm
+
+
+#endif /*XTENSA_CACHEATTRASM_H*/
+
diff --git a/include/asm-xtensa/xtensa/config-linux_be/core.h b/include/asm-xtensa/xtensa/config-linux_be/core.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/xtensa/config-linux_be/core.h
@@ -0,0 +1,1270 @@
+/*
+ * xtensa/config/core.h -- HAL definitions that are dependent on CORE configuration
+ *
+ *  This header file is sometimes referred to as the "compile-time HAL" or CHAL.
+ *  It was generated for a specific Xtensa processor configuration.
+ *
+ *  Source for configuration-independent binaries (which link in a
+ *  configuration-specific HAL library) must NEVER include this file.
+ *  It is perfectly normal, however, for the HAL source itself to include this file.
+ */
+
+/*
+ * Copyright (c) 2003 Tensilica, Inc.  All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2.1 of the GNU Lesser General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like.  Any license provided herein, whether implied or
+ * otherwise, applies only to this software file.  Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307,
+ * USA.
+ */
+
+
+#ifndef XTENSA_CONFIG_CORE_H
+#define XTENSA_CONFIG_CORE_H
+
+#include <xtensa/hal.h>
+
+
+/*----------------------------------------------------------------------
+				GENERAL
+  ----------------------------------------------------------------------*/
+
+/*
+ *  Separators for macros that expand into arrays.
+ *  These can be predefined by files that #include this one,
+ *  when different separators are required.
+ */
+/*  Element separator for macros that expand into 1-dimensional arrays:  */
+#ifndef XCHAL_SEP
+#define XCHAL_SEP			,
+#endif
+/*  Array separator for macros that expand into 2-dimensional arrays:  */
+#ifndef XCHAL_SEP2
+#define XCHAL_SEP2			},{
+#endif
+
+
+/*----------------------------------------------------------------------
+				ENDIANNESS
+  ----------------------------------------------------------------------*/
+
+#define XCHAL_HAVE_BE			1
+#define XCHAL_HAVE_LE			0
+#define XCHAL_MEMORY_ORDER		XTHAL_BIGENDIAN
+
+
+/*----------------------------------------------------------------------
+				REGISTER WINDOWS
+  ----------------------------------------------------------------------*/
+
+#define XCHAL_HAVE_WINDOWED		1	/* 1 if windowed registers option configured, 0 otherwise */
+#define XCHAL_NUM_AREGS			64	/* number of physical address regs */
+#define XCHAL_NUM_AREGS_LOG2		6	/* log2(XCHAL_NUM_AREGS) */
+
+
+/*----------------------------------------------------------------------
+				ADDRESS ALIGNMENT
+  ----------------------------------------------------------------------*/
+
+/*  These apply to a selected set of core load and store instructions only (see ISA):  */
+#define XCHAL_UNALIGNED_LOAD_EXCEPTION	1	/* 1 if unaligned loads cause an exception, 0 otherwise */
+#define XCHAL_UNALIGNED_STORE_EXCEPTION	1	/* 1 if unaligned stores cause an exception, 0 otherwise */
+
+
+/*----------------------------------------------------------------------
+				INTERRUPTS
+  ----------------------------------------------------------------------*/
+
+#define XCHAL_HAVE_INTERRUPTS		1	/* 1 if interrupt option configured, 0 otherwise */
+#define XCHAL_HAVE_HIGHPRI_INTERRUPTS	1	/* 1 if high-priority interrupt option configured, 0 otherwise */
+#define XCHAL_HAVE_HIGHLEVEL_INTERRUPTS	XCHAL_HAVE_HIGHPRI_INTERRUPTS
+#define XCHAL_HAVE_NMI			0	/* 1 if NMI option configured, 0 otherwise */
+#define XCHAL_NUM_INTERRUPTS		17	/* number of interrupts */
+#define XCHAL_NUM_INTERRUPTS_LOG2	5	/* number of bits to hold an interrupt number: roundup(log2(number of interrupts)) */
+#define XCHAL_NUM_EXTINTERRUPTS		10	/* number of external interrupts */
+#define XCHAL_NUM_INTLEVELS		4	/* number of interrupt levels (not including level zero!) */
+#define XCHAL_NUM_LOWPRI_LEVELS		1			/* number of low-priority interrupt levels (always 1) */
+#define XCHAL_FIRST_HIGHPRI_LEVEL	(XCHAL_NUM_LOWPRI_LEVELS+1)	/* level of first high-priority interrupt (always 2) */
+#define XCHAL_EXCM_LEVEL		1			/* level of interrupts masked by PS.EXCM (XEA2 only; always 1 in T10xx);
+								   for XEA1, where there is no PS.EXCM, this is always 1;
+								   interrupts at levels FIRST_HIGHPRI <= n <= EXCM_LEVEL, if any,
+								   are termed "medium priority" interrupts (post T10xx only) */
+/*  Note:  1 <= LOWPRI_LEVELS <= EXCM_LEVEL < DEBUGLEVEL <= NUM_INTLEVELS < NMILEVEL <= 15  */
+
+/*  Masks of interrupts at each interrupt level:  */
+#define XCHAL_INTLEVEL0_MASK		0x00000000
+#define XCHAL_INTLEVEL1_MASK		0x000064F9
+#define XCHAL_INTLEVEL2_MASK		0x00008902
+#define XCHAL_INTLEVEL3_MASK		0x00011204
+#define XCHAL_INTLEVEL4_MASK		0x00000000
+#define XCHAL_INTLEVEL5_MASK		0x00000000
+#define XCHAL_INTLEVEL6_MASK		0x00000000
+#define XCHAL_INTLEVEL7_MASK		0x00000000
+#define XCHAL_INTLEVEL8_MASK		0x00000000
+#define XCHAL_INTLEVEL9_MASK		0x00000000
+#define XCHAL_INTLEVEL10_MASK		0x00000000
+#define XCHAL_INTLEVEL11_MASK		0x00000000
+#define XCHAL_INTLEVEL12_MASK		0x00000000
+#define XCHAL_INTLEVEL13_MASK		0x00000000
+#define XCHAL_INTLEVEL14_MASK		0x00000000
+#define XCHAL_INTLEVEL15_MASK		0x00000000
+/*  As an array of entries (eg. for C constant arrays):  */
+#define XCHAL_INTLEVEL_MASKS		0x00000000	XCHAL_SEP \
+					0x000064F9	XCHAL_SEP \
+					0x00008902	XCHAL_SEP \
+					0x00011204	XCHAL_SEP \
+					0x00000000	XCHAL_SEP \
+					0x00000000	XCHAL_SEP \
+					0x00000000	XCHAL_SEP \
+					0x00000000	XCHAL_SEP \
+					0x00000000	XCHAL_SEP \
+					0x00000000	XCHAL_SEP \
+					0x00000000	XCHAL_SEP \
+					0x00000000	XCHAL_SEP \
+					0x00000000	XCHAL_SEP \
+					0x00000000	XCHAL_SEP \
+					0x00000000	XCHAL_SEP \
+					0x00000000
+
+/*  Masks of interrupts at each range 1..n of interrupt levels:  */
+#define XCHAL_INTLEVEL0_ANDBELOW_MASK	0x00000000
+#define XCHAL_INTLEVEL1_ANDBELOW_MASK	0x000064F9
+#define XCHAL_INTLEVEL2_ANDBELOW_MASK	0x0000EDFB
+#define XCHAL_INTLEVEL3_ANDBELOW_MASK	0x0001FFFF
+#define XCHAL_INTLEVEL4_ANDBELOW_MASK	0x0001FFFF
+#define XCHAL_INTLEVEL5_ANDBELOW_MASK	0x0001FFFF
+#define XCHAL_INTLEVEL6_ANDBELOW_MASK	0x0001FFFF
+#define XCHAL_INTLEVEL7_ANDBELOW_MASK	0x0001FFFF
+#define XCHAL_INTLEVEL8_ANDBELOW_MASK	0x0001FFFF
+#define XCHAL_INTLEVEL9_ANDBELOW_MASK	0x0001FFFF
+#define XCHAL_INTLEVEL10_ANDBELOW_MASK	0x0001FFFF
+#define XCHAL_INTLEVEL11_ANDBELOW_MASK	0x0001FFFF
+#define XCHAL_INTLEVEL12_ANDBELOW_MASK	0x0001FFFF
+#define XCHAL_INTLEVEL13_ANDBELOW_MASK	0x0001FFFF
+#define XCHAL_INTLEVEL14_ANDBELOW_MASK	0x0001FFFF
+#define XCHAL_INTLEVEL15_ANDBELOW_MASK	0x0001FFFF
+#define XCHAL_LOWPRI_MASK		XCHAL_INTLEVEL1_ANDBELOW_MASK	/* mask of all low-priority interrupts */
+#define XCHAL_EXCM_MASK			XCHAL_INTLEVEL1_ANDBELOW_MASK	/* mask of all interrupts masked by PS.EXCM (or CEXCM) */
+/*  As an array of entries (eg. for C constant arrays):  */
+#define XCHAL_INTLEVEL_ANDBELOW_MASKS	0x00000000	XCHAL_SEP \
+					0x000064F9	XCHAL_SEP \
+					0x0000EDFB	XCHAL_SEP \
+					0x0001FFFF	XCHAL_SEP \
+					0x0001FFFF	XCHAL_SEP \
+					0x0001FFFF	XCHAL_SEP \
+					0x0001FFFF	XCHAL_SEP \
+					0x0001FFFF	XCHAL_SEP \
+					0x0001FFFF	XCHAL_SEP \
+					0x0001FFFF	XCHAL_SEP \
+					0x0001FFFF	XCHAL_SEP \
+					0x0001FFFF	XCHAL_SEP \
+					0x0001FFFF	XCHAL_SEP \
+					0x0001FFFF	XCHAL_SEP \
+					0x0001FFFF	XCHAL_SEP \
+					0x0001FFFF
+
+/*  Interrupt numbers for each interrupt level at which only one interrupt was configured:  */
+/*#define XCHAL_INTLEVEL1_NUM		...more than one interrupt at this level...*/
+/*#define XCHAL_INTLEVEL2_NUM		...more than one interrupt at this level...*/
+/*#define XCHAL_INTLEVEL3_NUM		...more than one interrupt at this level...*/
+
+/*  Level of each interrupt:  */
+#define XCHAL_INT0_LEVEL		1
+#define XCHAL_INT1_LEVEL		2
+#define XCHAL_INT2_LEVEL		3
+#define XCHAL_INT3_LEVEL		1
+#define XCHAL_INT4_LEVEL		1
+#define XCHAL_INT5_LEVEL		1
+#define XCHAL_INT6_LEVEL		1
+#define XCHAL_INT7_LEVEL		1
+#define XCHAL_INT8_LEVEL		2
+#define XCHAL_INT9_LEVEL		3
+#define XCHAL_INT10_LEVEL		1
+#define XCHAL_INT11_LEVEL		2
+#define XCHAL_INT12_LEVEL		3
+#define XCHAL_INT13_LEVEL		1
+#define XCHAL_INT14_LEVEL		1
+#define XCHAL_INT15_LEVEL		2
+#define XCHAL_INT16_LEVEL		3
+#define XCHAL_INT17_LEVEL		0
+#define XCHAL_INT18_LEVEL		0
+#define XCHAL_INT19_LEVEL		0
+#define XCHAL_INT20_LEVEL		0
+#define XCHAL_INT21_LEVEL		0
+#define XCHAL_INT22_LEVEL		0
+#define XCHAL_INT23_LEVEL		0
+#define XCHAL_INT24_LEVEL		0
+#define XCHAL_INT25_LEVEL		0
+#define XCHAL_INT26_LEVEL		0
+#define XCHAL_INT27_LEVEL		0
+#define XCHAL_INT28_LEVEL		0
+#define XCHAL_INT29_LEVEL		0
+#define XCHAL_INT30_LEVEL		0
+#define XCHAL_INT31_LEVEL		0
+/*  As an array of entries (eg. for C constant arrays):  */
+#define XCHAL_INT_LEVELS		1	XCHAL_SEP \
+					2	XCHAL_SEP \
+					3	XCHAL_SEP \
+					1	XCHAL_SEP \
+					1	XCHAL_SEP \
+					1	XCHAL_SEP \
+					1	XCHAL_SEP \
+					1	XCHAL_SEP \
+					2	XCHAL_SEP \
+					3	XCHAL_SEP \
+					1	XCHAL_SEP \
+					2	XCHAL_SEP \
+					3	XCHAL_SEP \
+					1	XCHAL_SEP \
+					1	XCHAL_SEP \
+					2	XCHAL_SEP \
+					3	XCHAL_SEP \
+					0	XCHAL_SEP \
+					0	XCHAL_SEP \
+					0	XCHAL_SEP \
+					0	XCHAL_SEP \
+					0	XCHAL_SEP \
+					0	XCHAL_SEP \
+					0	XCHAL_SEP \
+					0	XCHAL_SEP \
+					0	XCHAL_SEP \
+					0	XCHAL_SEP \
+					0	XCHAL_SEP \
+					0	XCHAL_SEP \
+					0	XCHAL_SEP \
+					0	XCHAL_SEP \
+					0
+
+/*  Type of each interrupt:  */
+#define XCHAL_INT0_TYPE 	XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT1_TYPE 	XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT2_TYPE 	XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT3_TYPE 	XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT4_TYPE 	XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT5_TYPE 	XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT6_TYPE 	XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT7_TYPE 	XTHAL_INTTYPE_EXTERN_EDGE
+#define XCHAL_INT8_TYPE 	XTHAL_INTTYPE_EXTERN_EDGE
+#define XCHAL_INT9_TYPE 	XTHAL_INTTYPE_EXTERN_EDGE
+#define XCHAL_INT10_TYPE 	XTHAL_INTTYPE_TIMER
+#define XCHAL_INT11_TYPE 	XTHAL_INTTYPE_TIMER
+#define XCHAL_INT12_TYPE 	XTHAL_INTTYPE_TIMER
+#define XCHAL_INT13_TYPE 	XTHAL_INTTYPE_SOFTWARE
+#define XCHAL_INT14_TYPE 	XTHAL_INTTYPE_SOFTWARE
+#define XCHAL_INT15_TYPE 	XTHAL_INTTYPE_SOFTWARE
+#define XCHAL_INT16_TYPE 	XTHAL_INTTYPE_SOFTWARE
+#define XCHAL_INT17_TYPE 	XTHAL_INTTYPE_UNCONFIGURED
+#define XCHAL_INT18_TYPE 	XTHAL_INTTYPE_UNCONFIGURED
+#define XCHAL_INT19_TYPE 	XTHAL_INTTYPE_UNCONFIGURED
+#define XCHAL_INT20_TYPE 	XTHAL_INTTYPE_UNCONFIGURED
+#define XCHAL_INT21_TYPE 	XTHAL_INTTYPE_UNCONFIGURED
+#define XCHAL_INT22_TYPE 	XTHAL_INTTYPE_UNCONFIGURED
+#define XCHAL_INT23_TYPE 	XTHAL_INTTYPE_UNCONFIGURED
+#define XCHAL_INT24_TYPE 	XTHAL_INTTYPE_UNCONFIGURED
+#define XCHAL_INT25_TYPE 	XTHAL_INTTYPE_UNCONFIGURED
+#define XCHAL_INT26_TYPE 	XTHAL_INTTYPE_UNCONFIGURED
+#define XCHAL_INT27_TYPE 	XTHAL_INTTYPE_UNCONFIGURED
+#define XCHAL_INT28_TYPE 	XTHAL_INTTYPE_UNCONFIGURED
+#define XCHAL_INT29_TYPE 	XTHAL_INTTYPE_UNCONFIGURED
+#define XCHAL_INT30_TYPE 	XTHAL_INTTYPE_UNCONFIGURED
+#define XCHAL_INT31_TYPE 	XTHAL_INTTYPE_UNCONFIGURED
+/*  As an array of entries (eg. for C constant arrays):  */
+#define XCHAL_INT_TYPES		XTHAL_INTTYPE_EXTERN_LEVEL     	XCHAL_SEP \
+				XTHAL_INTTYPE_EXTERN_LEVEL     	XCHAL_SEP \
+				XTHAL_INTTYPE_EXTERN_LEVEL     	XCHAL_SEP \
+				XTHAL_INTTYPE_EXTERN_LEVEL     	XCHAL_SEP \
+				XTHAL_INTTYPE_EXTERN_LEVEL     	XCHAL_SEP \
+				XTHAL_INTTYPE_EXTERN_LEVEL     	XCHAL_SEP \
+				XTHAL_INTTYPE_EXTERN_LEVEL     	XCHAL_SEP \
+				XTHAL_INTTYPE_EXTERN_EDGE     	XCHAL_SEP \
+				XTHAL_INTTYPE_EXTERN_EDGE     	XCHAL_SEP \
+				XTHAL_INTTYPE_EXTERN_EDGE     	XCHAL_SEP \
+				XTHAL_INTTYPE_TIMER     	XCHAL_SEP \
+				XTHAL_INTTYPE_TIMER     	XCHAL_SEP \
+				XTHAL_INTTYPE_TIMER     	XCHAL_SEP \
+				XTHAL_INTTYPE_SOFTWARE     	XCHAL_SEP \
+				XTHAL_INTTYPE_SOFTWARE     	XCHAL_SEP \
+				XTHAL_INTTYPE_SOFTWARE     	XCHAL_SEP \
+				XTHAL_INTTYPE_SOFTWARE     	XCHAL_SEP \
+				XTHAL_INTTYPE_UNCONFIGURED     	XCHAL_SEP \
+				XTHAL_INTTYPE_UNCONFIGURED     	XCHAL_SEP \
+				XTHAL_INTTYPE_UNCONFIGURED     	XCHAL_SEP \
+				XTHAL_INTTYPE_UNCONFIGURED     	XCHAL_SEP \
+				XTHAL_INTTYPE_UNCONFIGURED     	XCHAL_SEP \
+				XTHAL_INTTYPE_UNCONFIGURED     	XCHAL_SEP \
+				XTHAL_INTTYPE_UNCONFIGURED     	XCHAL_SEP \
+				XTHAL_INTTYPE_UNCONFIGURED     	XCHAL_SEP \
+				XTHAL_INTTYPE_UNCONFIGURED     	XCHAL_SEP \
+				XTHAL_INTTYPE_UNCONFIGURED     	XCHAL_SEP \
+				XTHAL_INTTYPE_UNCONFIGURED     	XCHAL_SEP \
+				XTHAL_INTTYPE_UNCONFIGURED     	XCHAL_SEP \
+				XTHAL_INTTYPE_UNCONFIGURED     	XCHAL_SEP \
+				XTHAL_INTTYPE_UNCONFIGURED     	XCHAL_SEP \
+				XTHAL_INTTYPE_UNCONFIGURED
+
+/*  Masks of interrupts for each type of interrupt:  */
+#define XCHAL_INTTYPE_MASK_UNCONFIGURED	0xFFFE0000
+#define XCHAL_INTTYPE_MASK_SOFTWARE	0x0001E000
+#define XCHAL_INTTYPE_MASK_EXTERN_EDGE	0x00000380
+#define XCHAL_INTTYPE_MASK_EXTERN_LEVEL	0x0000007F
+#define XCHAL_INTTYPE_MASK_TIMER	0x00001C00
+#define XCHAL_INTTYPE_MASK_NMI		0x00000000
+/*  As an array of entries (eg. for C constant arrays):  */
+#define XCHAL_INTTYPE_MASKS		0xFFFE0000	XCHAL_SEP \
+					0x0001E000	XCHAL_SEP \
+					0x00000380	XCHAL_SEP \
+					0x0000007F	XCHAL_SEP \
+					0x00001C00	XCHAL_SEP \
+					0x00000000
+
+/*  Interrupts assigned to each timer (CCOMPARE0 to CCOMPARE3), -1 if unassigned  */
+#define XCHAL_TIMER0_INTERRUPT	10
+#define XCHAL_TIMER1_INTERRUPT	11
+#define XCHAL_TIMER2_INTERRUPT	12
+#define XCHAL_TIMER3_INTERRUPT	XTHAL_TIMER_UNCONFIGURED
+/*  As an array of entries (eg. for C constant arrays):  */
+#define XCHAL_TIMER_INTERRUPTS	10	XCHAL_SEP \
+				11	XCHAL_SEP \
+				12	XCHAL_SEP \
+				XTHAL_TIMER_UNCONFIGURED
+
+/*  Indexing macros:  */
+#define _XCHAL_INTLEVEL_MASK(n)		XCHAL_INTLEVEL ## n ## _MASK
+#define XCHAL_INTLEVEL_MASK(n)		_XCHAL_INTLEVEL_MASK(n)		/* n = 0 .. 15 */
+#define _XCHAL_INTLEVEL_ANDBELOWMASK(n)	XCHAL_INTLEVEL ## n ## _ANDBELOW_MASK
+#define XCHAL_INTLEVEL_ANDBELOW_MASK(n)	_XCHAL_INTLEVEL_ANDBELOWMASK(n)	/* n = 0 .. 15 */
+#define _XCHAL_INT_LEVEL(n)		XCHAL_INT ## n ## _LEVEL
+#define XCHAL_INT_LEVEL(n)		_XCHAL_INT_LEVEL(n)		/* n = 0 .. 31 */
+#define _XCHAL_INT_TYPE(n)		XCHAL_INT ## n ## _TYPE
+#define XCHAL_INT_TYPE(n)		_XCHAL_INT_TYPE(n)		/* n = 0 .. 31 */
+#define _XCHAL_TIMER_INTERRUPT(n)	XCHAL_TIMER ## n ## _INTERRUPT
+#define XCHAL_TIMER_INTERRUPT(n)	_XCHAL_TIMER_INTERRUPT(n)	/* n = 0 .. 3 */
+
+
+
+/*
+ *  External interrupt vectors/levels.
+ *  These macros describe how Xtensa processor interrupt numbers
+ *  (as numbered internally, eg. in INTERRUPT and INTENABLE registers)
+ *  map to external BInterrupt<n> pins, for those interrupts
+ *  configured as external (level-triggered, edge-triggered, or NMI).
+ *  See the Xtensa processor databook for more details.
+ */
+
+/*  Core interrupt numbers mapped to each EXTERNAL interrupt number:  */
+#define XCHAL_EXTINT0_NUM		0	/* (intlevel 1) */
+#define XCHAL_EXTINT1_NUM		1	/* (intlevel 2) */
+#define XCHAL_EXTINT2_NUM		2	/* (intlevel 3) */
+#define XCHAL_EXTINT3_NUM		3	/* (intlevel 1) */
+#define XCHAL_EXTINT4_NUM		4	/* (intlevel 1) */
+#define XCHAL_EXTINT5_NUM		5	/* (intlevel 1) */
+#define XCHAL_EXTINT6_NUM		6	/* (intlevel 1) */
+#define XCHAL_EXTINT7_NUM		7	/* (intlevel 1) */
+#define XCHAL_EXTINT8_NUM		8	/* (intlevel 2) */
+#define XCHAL_EXTINT9_NUM		9	/* (intlevel 3) */
+
+/*  Corresponding interrupt masks:  */
+#define XCHAL_EXTINT0_MASK		0x00000001
+#define XCHAL_EXTINT1_MASK		0x00000002
+#define XCHAL_EXTINT2_MASK		0x00000004
+#define XCHAL_EXTINT3_MASK		0x00000008
+#define XCHAL_EXTINT4_MASK		0x00000010
+#define XCHAL_EXTINT5_MASK		0x00000020
+#define XCHAL_EXTINT6_MASK		0x00000040
+#define XCHAL_EXTINT7_MASK		0x00000080
+#define XCHAL_EXTINT8_MASK		0x00000100
+#define XCHAL_EXTINT9_MASK		0x00000200
+
+/*  Core config interrupt levels mapped to each external interrupt:  */
+#define XCHAL_EXTINT0_LEVEL		1	/* (int number 0) */
+#define XCHAL_EXTINT1_LEVEL		2	/* (int number 1) */
+#define XCHAL_EXTINT2_LEVEL		3	/* (int number 2) */
+#define XCHAL_EXTINT3_LEVEL		1	/* (int number 3) */
+#define XCHAL_EXTINT4_LEVEL		1	/* (int number 4) */
+#define XCHAL_EXTINT5_LEVEL		1	/* (int number 5) */
+#define XCHAL_EXTINT6_LEVEL		1	/* (int number 6) */
+#define XCHAL_EXTINT7_LEVEL		1	/* (int number 7) */
+#define XCHAL_EXTINT8_LEVEL		2	/* (int number 8) */
+#define XCHAL_EXTINT9_LEVEL		3	/* (int number 9) */
+
+
+/*----------------------------------------------------------------------
+			EXCEPTIONS and VECTORS
+  ----------------------------------------------------------------------*/
+
+#define XCHAL_HAVE_EXCEPTIONS		1	/* 1 if exception option configured, 0 otherwise */
+
+#define XCHAL_XEA_VERSION		2	/* Xtensa Exception Architecture number: 1 for XEA1 (old), 2 for XEA2 (new) */
+#define XCHAL_HAVE_XEA1			0	/* 1 if XEA1, 0 otherwise */
+#define XCHAL_HAVE_XEA2			1	/* 1 if XEA2, 0 otherwise */
+/*  For backward compatibility ONLY -- DO NOT USE (will be removed in future release):  */
+#define XCHAL_HAVE_OLD_EXC_ARCH		XCHAL_HAVE_XEA1	/* (DEPRECATED) 1 if old exception architecture (XEA1), 0 otherwise (eg. XEA2) */
+#define XCHAL_HAVE_EXCM			XCHAL_HAVE_XEA2	/* (DEPRECATED) 1 if PS.EXCM bit exists (currently equals XCHAL_HAVE_TLBS) */
+
+#define XCHAL_RESET_VECTOR_VADDR	0xFE000020
+#define XCHAL_RESET_VECTOR_PADDR	0xFE000020
+#define XCHAL_USER_VECTOR_VADDR		0xD0000220
+#define XCHAL_PROGRAMEXC_VECTOR_VADDR	XCHAL_USER_VECTOR_VADDR		/* for backward compatibility */
+#define XCHAL_USEREXC_VECTOR_VADDR	XCHAL_USER_VECTOR_VADDR		/* for backward compatibility */
+#define XCHAL_USER_VECTOR_PADDR		0x00000220
+#define XCHAL_PROGRAMEXC_VECTOR_PADDR	XCHAL_USER_VECTOR_PADDR		/* for backward compatibility */
+#define XCHAL_USEREXC_VECTOR_PADDR	XCHAL_USER_VECTOR_PADDR		/* for backward compatibility */
+#define XCHAL_KERNEL_VECTOR_VADDR	0xD0000200
+#define XCHAL_STACKEDEXC_VECTOR_VADDR	XCHAL_KERNEL_VECTOR_VADDR	/* for backward compatibility */
+#define XCHAL_KERNELEXC_VECTOR_VADDR	XCHAL_KERNEL_VECTOR_VADDR	/* for backward compatibility */
+#define XCHAL_KERNEL_VECTOR_PADDR	0x00000200
+#define XCHAL_STACKEDEXC_VECTOR_PADDR	XCHAL_KERNEL_VECTOR_PADDR	/* for backward compatibility */
+#define XCHAL_KERNELEXC_VECTOR_PADDR	XCHAL_KERNEL_VECTOR_PADDR	/* for backward compatibility */
+#define XCHAL_DOUBLEEXC_VECTOR_VADDR	0xD0000290
+#define XCHAL_DOUBLEEXC_VECTOR_PADDR	0x00000290
+#define XCHAL_WINDOW_VECTORS_VADDR	0xD0000000
+#define XCHAL_WINDOW_VECTORS_PADDR	0x00000000
+#define XCHAL_INTLEVEL2_VECTOR_VADDR	0xD0000240
+#define XCHAL_INTLEVEL2_VECTOR_PADDR	0x00000240
+#define XCHAL_INTLEVEL3_VECTOR_VADDR	0xD0000250
+#define XCHAL_INTLEVEL3_VECTOR_PADDR	0x00000250
+#define XCHAL_INTLEVEL4_VECTOR_VADDR	0xFE000520
+#define XCHAL_INTLEVEL4_VECTOR_PADDR	0xFE000520
+#define XCHAL_DEBUG_VECTOR_VADDR	XCHAL_INTLEVEL4_VECTOR_VADDR
+#define XCHAL_DEBUG_VECTOR_PADDR	XCHAL_INTLEVEL4_VECTOR_PADDR
+
+/*  Indexing macros:  */
+#define _XCHAL_INTLEVEL_VECTOR_VADDR(n)		XCHAL_INTLEVEL ## n ## _VECTOR_VADDR
+#define XCHAL_INTLEVEL_VECTOR_VADDR(n)		_XCHAL_INTLEVEL_VECTOR_VADDR(n)		/* n = 0 .. 15 */
+
+/*
+ *  General Exception Causes
+ *  (values of EXCCAUSE special register set by general exceptions,
+ *   which vector to the user, kernel, or double-exception vectors):
+ */
+#define XCHAL_EXCCAUSE_ILLEGAL_INSTRUCTION		0	/* Illegal Instruction (IllegalInstruction) */
+#define XCHAL_EXCCAUSE_SYSTEM_CALL			1	/* System Call (SystemCall) */
+#define XCHAL_EXCCAUSE_INSTRUCTION_FETCH_ERROR		2	/* Instruction Fetch Error (InstructionFetchError) */
+#define XCHAL_EXCCAUSE_LOAD_STORE_ERROR			3	/* Load Store Error (LoadStoreError) */
+#define XCHAL_EXCCAUSE_LEVEL1_INTERRUPT			4	/* Level 1 Interrupt (Level1Interrupt) */
+#define XCHAL_EXCCAUSE_ALLOCA				5	/* Stack Extension Assist (Alloca) */
+#define XCHAL_EXCCAUSE_INTEGER_DIVIDE_BY_ZERO		6	/* Integer Divide by Zero (IntegerDivideByZero) */
+#define XCHAL_EXCCAUSE_SPECULATION			7	/* Speculation (Speculation) */
+#define XCHAL_EXCCAUSE_PRIVILEGED			8	/* Privileged Instruction (Privileged) */
+#define XCHAL_EXCCAUSE_UNALIGNED			9	/* Unaligned Load Store (Unaligned) */
+#define XCHAL_EXCCAUSE_ITLB_MISS			16	/* ITlb Miss Exception (ITlbMiss) */
+#define XCHAL_EXCCAUSE_ITLB_MULTIHIT			17	/* ITlb Mutltihit Exception (ITlbMultihit) */
+#define XCHAL_EXCCAUSE_ITLB_PRIVILEGE			18	/* ITlb Privilege Exception (ITlbPrivilege) */
+#define XCHAL_EXCCAUSE_ITLB_SIZE_RESTRICTION		19	/* ITlb Size Restriction Exception (ITlbSizeRestriction) */
+#define XCHAL_EXCCAUSE_FETCH_CACHE_ATTRIBUTE		20	/* Fetch Cache Attribute Exception (FetchCacheAttribute) */
+#define XCHAL_EXCCAUSE_DTLB_MISS			24	/* DTlb Miss Exception (DTlbMiss) */
+#define XCHAL_EXCCAUSE_DTLB_MULTIHIT			25	/* DTlb Multihit Exception (DTlbMultihit) */
+#define XCHAL_EXCCAUSE_DTLB_PRIVILEGE			26	/* DTlb Privilege Exception (DTlbPrivilege) */
+#define XCHAL_EXCCAUSE_DTLB_SIZE_RESTRICTION		27	/* DTlb Size Restriction Exception (DTlbSizeRestriction) */
+#define XCHAL_EXCCAUSE_LOAD_CACHE_ATTRIBUTE		28	/* Load Cache Attribute Exception (LoadCacheAttribute) */
+#define XCHAL_EXCCAUSE_STORE_CACHE_ATTRIBUTE		29	/* Store Cache Attribute Exception (StoreCacheAttribute) */
+#define XCHAL_EXCCAUSE_FLOATING_POINT			40	/* Floating Point Exception (FloatingPoint) */
+
+
+
+/*----------------------------------------------------------------------
+				TIMERS
+  ----------------------------------------------------------------------*/
+
+#define XCHAL_HAVE_CCOUNT		1	/* 1 if have CCOUNT, 0 otherwise */
+/*#define XCHAL_HAVE_TIMERS		XCHAL_HAVE_CCOUNT*/
+#define XCHAL_NUM_TIMERS		3	/* number of CCOMPAREn regs */
+
+
+
+/*----------------------------------------------------------------------
+				DEBUG
+  ----------------------------------------------------------------------*/
+
+#define XCHAL_HAVE_DEBUG		1	/* 1 if debug option configured, 0 otherwise */
+#define XCHAL_HAVE_OCD			1	/* 1 if OnChipDebug option configured, 0 otherwise */
+#define XCHAL_NUM_IBREAK		2	/* number of IBREAKn regs */
+#define XCHAL_NUM_DBREAK		2	/* number of DBREAKn regs */
+#define XCHAL_DEBUGLEVEL		4	/* debug interrupt level */
+/*DebugExternalInterrupt		0		0|1*/
+/*DebugUseDIRArray			0		0|1*/
+
+
+
+
+/*----------------------------------------------------------------------
+			COPROCESSORS and EXTRA STATE
+  ----------------------------------------------------------------------*/
+
+#define XCHAL_HAVE_CP			0	/* 1 if coprocessor option configured (CPENABLE present) */
+#define XCHAL_CP_MAXCFG			0	/* max allowed cp id plus one (per cfg) */
+
+#include <xtensa/config/tie.h>
+
+
+
+
+/*----------------------------------------------------------------------
+			INTERNAL I/D RAM/ROMs and XLMI
+  ----------------------------------------------------------------------*/
+
+#define XCHAL_NUM_INSTROM		0	/* number of core instruction ROMs configured */
+#define XCHAL_NUM_INSTRAM		0	/* number of core instruction RAMs configured */
+#define XCHAL_NUM_DATAROM		0	/* number of core data ROMs configured */
+#define XCHAL_NUM_DATARAM		0	/* number of core data RAMs configured */
+#define XCHAL_NUM_XLMI			0	/* number of core XLMI ports configured */
+#define  XCHAL_NUM_IROM			XCHAL_NUM_INSTROM	/* (DEPRECATED) */
+#define  XCHAL_NUM_IRAM			XCHAL_NUM_INSTRAM	/* (DEPRECATED) */
+#define  XCHAL_NUM_DROM			XCHAL_NUM_DATAROM	/* (DEPRECATED) */
+#define  XCHAL_NUM_DRAM			XCHAL_NUM_DATARAM	/* (DEPRECATED) */
+
+
+
+/*----------------------------------------------------------------------
+				CACHE
+  ----------------------------------------------------------------------*/
+
+/*  Size of the cache lines in log2(bytes):  */
+#define XCHAL_ICACHE_LINEWIDTH		4
+#define XCHAL_DCACHE_LINEWIDTH		4
+/*  Size of the cache lines in bytes:  */
+#define XCHAL_ICACHE_LINESIZE		16
+#define XCHAL_DCACHE_LINESIZE		16
+/*  Max for both I-cache and D-cache (used for general alignment):  */
+#define XCHAL_CACHE_LINEWIDTH_MAX	4
+#define XCHAL_CACHE_LINESIZE_MAX	16
+
+/*  Number of cache sets in log2(lines per way):  */
+#define XCHAL_ICACHE_SETWIDTH		8
+#define XCHAL_DCACHE_SETWIDTH		8
+/*  Max for both I-cache and D-cache (used for general cache-coherency page alignment):  */
+#define XCHAL_CACHE_SETWIDTH_MAX	8
+#define XCHAL_CACHE_SETSIZE_MAX		256
+
+/*  Cache set associativity (number of ways):  */
+#define XCHAL_ICACHE_WAYS		2
+#define XCHAL_DCACHE_WAYS		2
+
+/*  Size of the caches in bytes (ways * 2^(linewidth + setwidth)):  */
+#define XCHAL_ICACHE_SIZE		8192
+#define XCHAL_DCACHE_SIZE		8192
+
+/*  Cache features:  */
+#define XCHAL_DCACHE_IS_WRITEBACK	0
+/*  Whether cache locking feature is available:  */
+#define XCHAL_ICACHE_LINE_LOCKABLE	0
+#define XCHAL_DCACHE_LINE_LOCKABLE	0
+
+/*  Number of (encoded) cache attribute bits:  */
+#define XCHAL_CA_BITS			4	/* number of bits needed to hold cache attribute encoding */
+/*  (The number of access mode bits (decoded cache attribute bits) is defined by the architecture; see xtensa/hal.h?)  */
+
+
+/*  Cache Attribute encodings -- lists of access modes for each cache attribute:  */
+#define XCHAL_FCA_LIST		XTHAL_FAM_EXCEPTION	XCHAL_SEP \
+				XTHAL_FAM_BYPASS	XCHAL_SEP \
+				XTHAL_FAM_EXCEPTION	XCHAL_SEP \
+				XTHAL_FAM_BYPASS	XCHAL_SEP \
+				XTHAL_FAM_EXCEPTION	XCHAL_SEP \
+				XTHAL_FAM_CACHED	XCHAL_SEP \
+				XTHAL_FAM_EXCEPTION	XCHAL_SEP \
+				XTHAL_FAM_CACHED	XCHAL_SEP \
+				XTHAL_FAM_EXCEPTION	XCHAL_SEP \
+				XTHAL_FAM_CACHED	XCHAL_SEP \
+				XTHAL_FAM_EXCEPTION	XCHAL_SEP \
+				XTHAL_FAM_CACHED	XCHAL_SEP \
+				XTHAL_FAM_EXCEPTION	XCHAL_SEP \
+				XTHAL_FAM_EXCEPTION	XCHAL_SEP \
+				XTHAL_FAM_EXCEPTION	XCHAL_SEP \
+				XTHAL_FAM_EXCEPTION
+#define XCHAL_LCA_LIST		XTHAL_LAM_EXCEPTION	XCHAL_SEP \
+				XTHAL_LAM_BYPASSG	XCHAL_SEP \
+				XTHAL_LAM_EXCEPTION	XCHAL_SEP \
+				XTHAL_LAM_BYPASSG	XCHAL_SEP \
+				XTHAL_LAM_EXCEPTION	XCHAL_SEP \
+				XTHAL_LAM_CACHED	XCHAL_SEP \
+				XTHAL_LAM_EXCEPTION	XCHAL_SEP \
+				XTHAL_LAM_CACHED	XCHAL_SEP \
+				XTHAL_LAM_EXCEPTION	XCHAL_SEP \
+				XTHAL_LAM_NACACHED	XCHAL_SEP \
+				XTHAL_LAM_EXCEPTION	XCHAL_SEP \
+				XTHAL_LAM_NACACHED	XCHAL_SEP \
+				XTHAL_LAM_EXCEPTION	XCHAL_SEP \
+				XTHAL_LAM_ISOLATE	XCHAL_SEP \
+				XTHAL_LAM_EXCEPTION	XCHAL_SEP \
+				XTHAL_LAM_CACHED
+#define XCHAL_SCA_LIST		XTHAL_SAM_EXCEPTION	XCHAL_SEP \
+				XTHAL_SAM_EXCEPTION	XCHAL_SEP \
+				XTHAL_SAM_EXCEPTION	XCHAL_SEP \
+				XTHAL_SAM_BYPASS	XCHAL_SEP \
+				XTHAL_SAM_EXCEPTION	XCHAL_SEP \
+				XTHAL_SAM_EXCEPTION	XCHAL_SEP \
+				XTHAL_SAM_EXCEPTION	XCHAL_SEP \
+				XTHAL_SAM_WRITETHRU	XCHAL_SEP \
+				XTHAL_SAM_EXCEPTION	XCHAL_SEP \
+				XTHAL_SAM_EXCEPTION	XCHAL_SEP \
+				XTHAL_SAM_EXCEPTION	XCHAL_SEP \
+				XTHAL_SAM_WRITETHRU	XCHAL_SEP \
+				XTHAL_SAM_EXCEPTION	XCHAL_SEP \
+				XTHAL_SAM_ISOLATE	XCHAL_SEP \
+				XTHAL_SAM_EXCEPTION	XCHAL_SEP \
+				XTHAL_SAM_WRITETHRU
+
+/*  Test:
+	read/only: 0 + 1 + 2 + 4 + 5 + 6 + 8 + 9 + 10 + 12 + 14
+	read/only: 0 + 1 + 2 + 4 + 5 + 6 + 8 + 9 + 10 + 12 + 14
+	all:       0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15
+	fault:     0 + 2 + 4 + 6 + 8 + 10 + 12 + 14
+	r/w/x cached:
+	r/w/x dcached:
+	I-bypass:  1 + 3
+
+	load guard bit set: 1 + 3
+	load guard bit clr: 0 + 2 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15
+	hit-cache r/w/x: 7 + 11
+
+	fams: 5
+	fams: 0 / 6 / 18 / 1 / 2
+	fams: Bypass / Isolate / Cached / Exception / NACached
+
+        MMU okay:  yes
+*/
+
+
+/*----------------------------------------------------------------------
+				MMU
+  ----------------------------------------------------------------------*/
+
+/*
+ *  General notes on MMU parameters.
+ *
+ *  Terminology:
+ *	ASID = address-space ID (acts as an "extension" of virtual addresses)
+ *	VPN  = virtual page number
+ *	PPN  = physical page number
+ *	CA   = encoded cache attribute (access modes)
+ *	TLB  = translation look-aside buffer (term is stretched somewhat here)
+ *	I    = instruction (fetch accesses)
+ *	D    = data (load and store accesses)
+ *	way  = each TLB (ITLB and DTLB) consists of a number of "ways"
+ *		that simultaneously match the virtual address of an access;
+ *		a TLB successfully translates a virtual address if exactly
+ *		one way matches the vaddr; if none match, it is a miss;
+ *		if multiple match, one gets a "multihit" exception;
+ *		each way can be independently configured in terms of number of
+ *		entries, page sizes, which fields are writable or constant, etc.
+ *	set  = group of contiguous ways with exactly identical parameters
+ *	ARF  = auto-refill; hardware services a 1st-level miss by loading a PTE
+ *		from the page table and storing it in one of the auto-refill ways;
+ *		if this PTE load also misses, a miss exception is posted for s/w.
+ *	min-wired = a "min-wired" way can be used to map a single (minimum-sized)
+ * 		page arbitrarily under program control; it has a single entry,
+ *		is non-auto-refill (some other way(s) must be auto-refill),
+ *		all its fields (VPN, PPN, ASID, CA) are all writable, and it
+ *		supports the XCHAL_MMU_MIN_PTE_PAGE_SIZE page size (a current
+ *		restriction is that this be the only page size it supports).
+ *
+ *  TLB way entries are virtually indexed.
+ *  TLB ways that support multiple page sizes:
+ *	- must have all writable VPN and PPN fields;
+ *	- can only use one page size at any given time (eg. setup at startup),
+ *	  selected by the respective ITLBCFG or DTLBCFG special register,
+ *	  whose bits n*4+3 .. n*4 index the list of page sizes for way n
+ *	  (XCHAL_xTLB_SETm_PAGESZ_LOG2_LIST for set m corresponding to way n);
+ *	  this list may be sparse for auto-refill ways because auto-refill
+ *	  ways have independent lists of supported page sizes sharing a
+ *	  common encoding with PTE entries; the encoding is the index into
+ *	  this list; unsupported sizes for a given way are zero in the list;
+ *	  selecting unsupported sizes results in undefined hardware behaviour;
+ *	- is only possible for ways 0 thru 7 (due to ITLBCFG/DTLBCFG definition).
+ */
+
+#define XCHAL_HAVE_CACHEATTR		0	/* 1 if CACHEATTR register present, 0 if TLBs present instead */
+#define XCHAL_HAVE_TLBS			1	/* 1 if TLBs present, 0 if CACHEATTR present instead */
+#define XCHAL_HAVE_MMU			XCHAL_HAVE_TLBS	/* (DEPRECATED; use XCHAL_HAVE_TLBS instead; will be removed in future release) */
+#define XCHAL_HAVE_SPANNING_WAY		0	/* 1 if single way maps entire virtual address space in I+D */
+#define XCHAL_HAVE_IDENTITY_MAP		0	/* 1 if virtual addr == physical addr always, 0 otherwise */
+#define XCHAL_HAVE_MIMIC_CACHEATTR	0	/* 1 if have MMU that mimics a CACHEATTR config (CaMMU) */
+#define XCHAL_HAVE_XLT_CACHEATTR	0	/* 1 if have MMU that mimics a CACHEATTR config, but with translation (CaXltMMU) */
+
+#define XCHAL_MMU_ASID_BITS		8	/* number of bits in ASIDs (address space IDs) */
+#define XCHAL_MMU_ASID_INVALID		0	/* ASID value indicating invalid address space */
+#define XCHAL_MMU_ASID_KERNEL		1	/* ASID value indicating kernel (ring 0) address space */
+#define XCHAL_MMU_RINGS			4	/* number of rings supported (1..4) */
+#define XCHAL_MMU_RING_BITS		2	/* number of bits needed to hold ring number */
+#define XCHAL_MMU_SR_BITS		0	/* number of size-restriction bits supported */
+#define XCHAL_MMU_CA_BITS		4	/* number of bits needed to hold cache attribute encoding */
+#define XCHAL_MMU_MAX_PTE_PAGE_SIZE	12	/* max page size in a PTE structure (log2) */
+#define XCHAL_MMU_MIN_PTE_PAGE_SIZE	12	/* min page size in a PTE structure (log2) */
+
+
+/***  Instruction TLB:  ***/
+
+#define XCHAL_ITLB_WAY_BITS		3	/* number of bits holding the ways */
+#define XCHAL_ITLB_WAYS			7	/* number of ways (n-way set-associative TLB) */
+#define XCHAL_ITLB_ARF_WAYS		4	/* number of auto-refill ways */
+#define XCHAL_ITLB_SETS			4	/* number of sets (groups of ways with identical settings) */
+
+/*  Way set to which each way belongs:  */
+#define XCHAL_ITLB_WAY0_SET		0
+#define XCHAL_ITLB_WAY1_SET		0
+#define XCHAL_ITLB_WAY2_SET		0
+#define XCHAL_ITLB_WAY3_SET		0
+#define XCHAL_ITLB_WAY4_SET		1
+#define XCHAL_ITLB_WAY5_SET		2
+#define XCHAL_ITLB_WAY6_SET		3
+
+/*  Ways sets that are used by hardware auto-refill (ARF):  */
+#define XCHAL_ITLB_ARF_SETS		1	/* number of auto-refill sets */
+#define XCHAL_ITLB_ARF_SET0		0	/* index of n'th auto-refill set */
+
+/*  Way sets that are "min-wired" (see terminology comment above):  */
+#define XCHAL_ITLB_MINWIRED_SETS	0	/* number of "min-wired" sets */
+
+
+/*  ITLB way set 0 (group of ways 0 thru 3):  */
+#define XCHAL_ITLB_SET0_WAY			0	/* index of first way in this way set */
+#define XCHAL_ITLB_SET0_WAYS			4	/* number of (contiguous) ways in this way set */
+#define XCHAL_ITLB_SET0_ENTRIES_LOG2		2	/* log2(number of entries in this way) */
+#define XCHAL_ITLB_SET0_ENTRIES			4	/* number of entries in this way (always a power of 2) */
+#define XCHAL_ITLB_SET0_ARF			1	/* 1=autorefill by h/w, 0=non-autorefill (wired/constant/static) */
+#define XCHAL_ITLB_SET0_PAGESIZES		1	/* number of supported page sizes in this way */
+#define XCHAL_ITLB_SET0_PAGESZ_BITS		0	/* number of bits to encode the page size */
+#define XCHAL_ITLB_SET0_PAGESZ_LOG2_MIN		12	/* log2(minimum supported page size) */
+#define XCHAL_ITLB_SET0_PAGESZ_LOG2_MAX		12	/* log2(maximum supported page size) */
+#define XCHAL_ITLB_SET0_PAGESZ_LOG2_LIST	12	/* list of log2(page size)s, separated by XCHAL_SEP;
+							   2^PAGESZ_BITS entries in list, unsupported entries are zero */
+#define XCHAL_ITLB_SET0_ASID_CONSTMASK		0	/* constant ASID bits; 0 if all writable */
+#define XCHAL_ITLB_SET0_VPN_CONSTMASK		0	/* constant VPN bits, not including entry index bits; 0 if all writable */
+#define XCHAL_ITLB_SET0_PPN_CONSTMASK		0	/* constant PPN bits, including entry index bits; 0 if all writable */
+#define XCHAL_ITLB_SET0_CA_CONSTMASK		0	/* constant CA bits; 0 if all writable */
+#define XCHAL_ITLB_SET0_ASID_RESET		0	/* 1 if ASID reset values defined (and all writable); 0 otherwise */
+#define XCHAL_ITLB_SET0_VPN_RESET		0	/* 1 if VPN reset values defined (and all writable); 0 otherwise */
+#define XCHAL_ITLB_SET0_PPN_RESET		0	/* 1 if PPN reset values defined (and all writable); 0 otherwise */
+#define XCHAL_ITLB_SET0_CA_RESET		0	/* 1 if CA reset values defined (and all writable); 0 otherwise */
+
+/*  ITLB way set 1 (group of ways 4 thru 4):  */
+#define XCHAL_ITLB_SET1_WAY			4	/* index of first way in this way set */
+#define XCHAL_ITLB_SET1_WAYS			1	/* number of (contiguous) ways in this way set */
+#define XCHAL_ITLB_SET1_ENTRIES_LOG2		2	/* log2(number of entries in this way) */
+#define XCHAL_ITLB_SET1_ENTRIES			4	/* number of entries in this way (always a power of 2) */
+#define XCHAL_ITLB_SET1_ARF			0	/* 1=autorefill by h/w, 0=non-autorefill (wired/constant/static) */
+#define XCHAL_ITLB_SET1_PAGESIZES		4	/* number of supported page sizes in this way */
+#define XCHAL_ITLB_SET1_PAGESZ_BITS		2	/* number of bits to encode the page size */
+#define XCHAL_ITLB_SET1_PAGESZ_LOG2_MIN		20	/* log2(minimum supported page size) */
+#define XCHAL_ITLB_SET1_PAGESZ_LOG2_MAX		26	/* log2(maximum supported page size) */
+#define XCHAL_ITLB_SET1_PAGESZ_LOG2_LIST	20 XCHAL_SEP 22 XCHAL_SEP 24 XCHAL_SEP 26	/* list of log2(page size)s, separated by XCHAL_SEP;
+							   2^PAGESZ_BITS entries in list, unsupported entries are zero */
+#define XCHAL_ITLB_SET1_ASID_CONSTMASK		0	/* constant ASID bits; 0 if all writable */
+#define XCHAL_ITLB_SET1_VPN_CONSTMASK		0	/* constant VPN bits, not including entry index bits; 0 if all writable */
+#define XCHAL_ITLB_SET1_PPN_CONSTMASK		0	/* constant PPN bits, including entry index bits; 0 if all writable */
+#define XCHAL_ITLB_SET1_CA_CONSTMASK		0	/* constant CA bits; 0 if all writable */
+#define XCHAL_ITLB_SET1_ASID_RESET		0	/* 1 if ASID reset values defined (and all writable); 0 otherwise */
+#define XCHAL_ITLB_SET1_VPN_RESET		0	/* 1 if VPN reset values defined (and all writable); 0 otherwise */
+#define XCHAL_ITLB_SET1_PPN_RESET		0	/* 1 if PPN reset values defined (and all writable); 0 otherwise */
+#define XCHAL_ITLB_SET1_CA_RESET		0	/* 1 if CA reset values defined (and all writable); 0 otherwise */
+
+/*  ITLB way set 2 (group of ways 5 thru 5):  */
+#define XCHAL_ITLB_SET2_WAY			5	/* index of first way in this way set */
+#define XCHAL_ITLB_SET2_WAYS			1	/* number of (contiguous) ways in this way set */
+#define XCHAL_ITLB_SET2_ENTRIES_LOG2		1	/* log2(number of entries in this way) */
+#define XCHAL_ITLB_SET2_ENTRIES			2	/* number of entries in this way (always a power of 2) */
+#define XCHAL_ITLB_SET2_ARF			0	/* 1=autorefill by h/w, 0=non-autorefill (wired/constant/static) */
+#define XCHAL_ITLB_SET2_PAGESIZES		1	/* number of supported page sizes in this way */
+#define XCHAL_ITLB_SET2_PAGESZ_BITS		0	/* number of bits to encode the page size */
+#define XCHAL_ITLB_SET2_PAGESZ_LOG2_MIN		27	/* log2(minimum supported page size) */
+#define XCHAL_ITLB_SET2_PAGESZ_LOG2_MAX		27	/* log2(maximum supported page size) */
+#define XCHAL_ITLB_SET2_PAGESZ_LOG2_LIST	27	/* list of log2(page size)s, separated by XCHAL_SEP;
+							   2^PAGESZ_BITS entries in list, unsupported entries are zero */
+#define XCHAL_ITLB_SET2_ASID_CONSTMASK		0xFF	/* constant ASID bits; 0 if all writable */
+#define XCHAL_ITLB_SET2_VPN_CONSTMASK		0xF0000000	/* constant VPN bits, not including entry index bits; 0 if all writable */
+#define XCHAL_ITLB_SET2_PPN_CONSTMASK		0xF8000000	/* constant PPN bits, including entry index bits; 0 if all writable */
+#define XCHAL_ITLB_SET2_CA_CONSTMASK		0x0000000F	/* constant CA bits; 0 if all writable */
+#define XCHAL_ITLB_SET2_ASID_RESET		0	/* 1 if ASID reset values defined (and all writable); 0 otherwise */
+#define XCHAL_ITLB_SET2_VPN_RESET		0	/* 1 if VPN reset values defined (and all writable); 0 otherwise */
+#define XCHAL_ITLB_SET2_PPN_RESET		0	/* 1 if PPN reset values defined (and all writable); 0 otherwise */
+#define XCHAL_ITLB_SET2_CA_RESET		0	/* 1 if CA reset values defined (and all writable); 0 otherwise */
+/*  Constant ASID values for each entry of ITLB way set 2 (because ASID_CONSTMASK is non-zero):  */
+#define XCHAL_ITLB_SET2_E0_ASID_CONST		0x01
+#define XCHAL_ITLB_SET2_E1_ASID_CONST		0x01
+/*  Constant VPN values for each entry of ITLB way set 2 (because VPN_CONSTMASK is non-zero):  */
+#define XCHAL_ITLB_SET2_E0_VPN_CONST		0xD0000000
+#define XCHAL_ITLB_SET2_E1_VPN_CONST		0xD8000000
+/*  Constant PPN values for each entry of ITLB way set 2 (because PPN_CONSTMASK is non-zero):  */
+#define XCHAL_ITLB_SET2_E0_PPN_CONST		0x00000000
+#define XCHAL_ITLB_SET2_E1_PPN_CONST		0x00000000
+/*  Constant CA values for each entry of ITLB way set 2 (because CA_CONSTMASK is non-zero):  */
+#define XCHAL_ITLB_SET2_E0_CA_CONST		0x07
+#define XCHAL_ITLB_SET2_E1_CA_CONST		0x03
+
+/*  ITLB way set 3 (group of ways 6 thru 6):  */
+#define XCHAL_ITLB_SET3_WAY			6	/* index of first way in this way set */
+#define XCHAL_ITLB_SET3_WAYS			1	/* number of (contiguous) ways in this way set */
+#define XCHAL_ITLB_SET3_ENTRIES_LOG2		1	/* log2(number of entries in this way) */
+#define XCHAL_ITLB_SET3_ENTRIES			2	/* number of entries in this way (always a power of 2) */
+#define XCHAL_ITLB_SET3_ARF			0	/* 1=autorefill by h/w, 0=non-autorefill (wired/constant/static) */
+#define XCHAL_ITLB_SET3_PAGESIZES		1	/* number of supported page sizes in this way */
+#define XCHAL_ITLB_SET3_PAGESZ_BITS		0	/* number of bits to encode the page size */
+#define XCHAL_ITLB_SET3_PAGESZ_LOG2_MIN		28	/* log2(minimum supported page size) */
+#define XCHAL_ITLB_SET3_PAGESZ_LOG2_MAX		28	/* log2(maximum supported page size) */
+#define XCHAL_ITLB_SET3_PAGESZ_LOG2_LIST	28	/* list of log2(page size)s, separated by XCHAL_SEP;
+							   2^PAGESZ_BITS entries in list, unsupported entries are zero */
+#define XCHAL_ITLB_SET3_ASID_CONSTMASK		0xFF	/* constant ASID bits; 0 if all writable */
+#define XCHAL_ITLB_SET3_VPN_CONSTMASK		0xE0000000	/* constant VPN bits, not including entry index bits; 0 if all writable */
+#define XCHAL_ITLB_SET3_PPN_CONSTMASK		0xF0000000	/* constant PPN bits, including entry index bits; 0 if all writable */
+#define XCHAL_ITLB_SET3_CA_CONSTMASK		0x0000000F	/* constant CA bits; 0 if all writable */
+#define XCHAL_ITLB_SET3_ASID_RESET		0	/* 1 if ASID reset values defined (and all writable); 0 otherwise */
+#define XCHAL_ITLB_SET3_VPN_RESET		0	/* 1 if VPN reset values defined (and all writable); 0 otherwise */
+#define XCHAL_ITLB_SET3_PPN_RESET		0	/* 1 if PPN reset values defined (and all writable); 0 otherwise */
+#define XCHAL_ITLB_SET3_CA_RESET		0	/* 1 if CA reset values defined (and all writable); 0 otherwise */
+/*  Constant ASID values for each entry of ITLB way set 3 (because ASID_CONSTMASK is non-zero):  */
+#define XCHAL_ITLB_SET3_E0_ASID_CONST		0x01
+#define XCHAL_ITLB_SET3_E1_ASID_CONST		0x01
+/*  Constant VPN values for each entry of ITLB way set 3 (because VPN_CONSTMASK is non-zero):  */
+#define XCHAL_ITLB_SET3_E0_VPN_CONST		0xE0000000
+#define XCHAL_ITLB_SET3_E1_VPN_CONST		0xF0000000
+/*  Constant PPN values for each entry of ITLB way set 3 (because PPN_CONSTMASK is non-zero):  */
+#define XCHAL_ITLB_SET3_E0_PPN_CONST		0xF0000000
+#define XCHAL_ITLB_SET3_E1_PPN_CONST		0xF0000000
+/*  Constant CA values for each entry of ITLB way set 3 (because CA_CONSTMASK is non-zero):  */
+#define XCHAL_ITLB_SET3_E0_CA_CONST		0x07
+#define XCHAL_ITLB_SET3_E1_CA_CONST		0x03
+
+/*  Indexing macros:  */
+#define _XCHAL_ITLB_SET(n,_what)	XCHAL_ITLB_SET ## n ## _what
+#define XCHAL_ITLB_SET(n,what)		_XCHAL_ITLB_SET(n, _ ## what )
+#define _XCHAL_ITLB_SET_E(n,i,_what)	XCHAL_ITLB_SET ## n ## _E ## i ## _what
+#define XCHAL_ITLB_SET_E(n,i,what)	_XCHAL_ITLB_SET_E(n,i, _ ## what )
+/*
+ *  Example use:  XCHAL_ITLB_SET(XCHAL_ITLB_ARF_SET0,ENTRIES)
+ *	to get the value of XCHAL_ITLB_SET<n>_ENTRIES where <n> is the first auto-refill set.
+ */
+
+
+/***  Data TLB:  ***/
+
+#define XCHAL_DTLB_WAY_BITS		4	/* number of bits holding the ways */
+#define XCHAL_DTLB_WAYS			10	/* number of ways (n-way set-associative TLB) */
+#define XCHAL_DTLB_ARF_WAYS		4	/* number of auto-refill ways */
+#define XCHAL_DTLB_SETS			5	/* number of sets (groups of ways with identical settings) */
+
+/*  Way set to which each way belongs:  */
+#define XCHAL_DTLB_WAY0_SET		0
+#define XCHAL_DTLB_WAY1_SET		0
+#define XCHAL_DTLB_WAY2_SET		0
+#define XCHAL_DTLB_WAY3_SET		0
+#define XCHAL_DTLB_WAY4_SET		1
+#define XCHAL_DTLB_WAY5_SET		2
+#define XCHAL_DTLB_WAY6_SET		3
+#define XCHAL_DTLB_WAY7_SET		4
+#define XCHAL_DTLB_WAY8_SET		4
+#define XCHAL_DTLB_WAY9_SET		4
+
+/*  Ways sets that are used by hardware auto-refill (ARF):  */
+#define XCHAL_DTLB_ARF_SETS		1	/* number of auto-refill sets */
+#define XCHAL_DTLB_ARF_SET0		0	/* index of n'th auto-refill set */
+
+/*  Way sets that are "min-wired" (see terminology comment above):  */
+#define XCHAL_DTLB_MINWIRED_SETS	1	/* number of "min-wired" sets */
+#define XCHAL_DTLB_MINWIRED_SET0	4	/* index of n'th "min-wired" set */
+
+
+/*  DTLB way set 0 (group of ways 0 thru 3):  */
+#define XCHAL_DTLB_SET0_WAY			0	/* index of first way in this way set */
+#define XCHAL_DTLB_SET0_WAYS			4	/* number of (contiguous) ways in this way set */
+#define XCHAL_DTLB_SET0_ENTRIES_LOG2		2	/* log2(number of entries in this way) */
+#define XCHAL_DTLB_SET0_ENTRIES			4	/* number of entries in this way (always a power of 2) */
+#define XCHAL_DTLB_SET0_ARF			1	/* 1=autorefill by h/w, 0=non-autorefill (wired/constant/static) */
+#define XCHAL_DTLB_SET0_PAGESIZES		1	/* number of supported page sizes in this way */
+#define XCHAL_DTLB_SET0_PAGESZ_BITS		0	/* number of bits to encode the page size */
+#define XCHAL_DTLB_SET0_PAGESZ_LOG2_MIN		12	/* log2(minimum supported page size) */
+#define XCHAL_DTLB_SET0_PAGESZ_LOG2_MAX		12	/* log2(maximum supported page size) */
+#define XCHAL_DTLB_SET0_PAGESZ_LOG2_LIST	12	/* list of log2(page size)s, separated by XCHAL_SEP;
+							   2^PAGESZ_BITS entries in list, unsupported entries are zero */
+#define XCHAL_DTLB_SET0_ASID_CONSTMASK		0	/* constant ASID bits; 0 if all writable */
+#define XCHAL_DTLB_SET0_VPN_CONSTMASK		0	/* constant VPN bits, not including entry index bits; 0 if all writable */
+#define XCHAL_DTLB_SET0_PPN_CONSTMASK		0	/* constant PPN bits, including entry index bits; 0 if all writable */
+#define XCHAL_DTLB_SET0_CA_CONSTMASK		0	/* constant CA bits; 0 if all writable */
+#define XCHAL_DTLB_SET0_ASID_RESET		0	/* 1 if ASID reset values defined (and all writable); 0 otherwise */
+#define XCHAL_DTLB_SET0_VPN_RESET		0	/* 1 if VPN reset values defined (and all writable); 0 otherwise */
+#define XCHAL_DTLB_SET0_PPN_RESET		0	/* 1 if PPN reset values defined (and all writable); 0 otherwise */
+#define XCHAL_DTLB_SET0_CA_RESET		0	/* 1 if CA reset values defined (and all writable); 0 otherwise */
+
+/*  DTLB way set 1 (group of ways 4 thru 4):  */
+#define XCHAL_DTLB_SET1_WAY			4	/* index of first way in this way set */
+#define XCHAL_DTLB_SET1_WAYS			1	/* number of (contiguous) ways in this way set */
+#define XCHAL_DTLB_SET1_ENTRIES_LOG2		2	/* log2(number of entries in this way) */
+#define XCHAL_DTLB_SET1_ENTRIES			4	/* number of entries in this way (always a power of 2) */
+#define XCHAL_DTLB_SET1_ARF			0	/* 1=autorefill by h/w, 0=non-autorefill (wired/constant/static) */
+#define XCHAL_DTLB_SET1_PAGESIZES		4	/* number of supported page sizes in this way */
+#define XCHAL_DTLB_SET1_PAGESZ_BITS		2	/* number of bits to encode the page size */
+#define XCHAL_DTLB_SET1_PAGESZ_LOG2_MIN		20	/* log2(minimum supported page size) */
+#define XCHAL_DTLB_SET1_PAGESZ_LOG2_MAX		26	/* log2(maximum supported page size) */
+#define XCHAL_DTLB_SET1_PAGESZ_LOG2_LIST	20 XCHAL_SEP 22 XCHAL_SEP 24 XCHAL_SEP 26	/* list of log2(page size)s, separated by XCHAL_SEP;
+							   2^PAGESZ_BITS entries in list, unsupported entries are zero */
+#define XCHAL_DTLB_SET1_ASID_CONSTMASK		0	/* constant ASID bits; 0 if all writable */
+#define XCHAL_DTLB_SET1_VPN_CONSTMASK		0	/* constant VPN bits, not including entry index bits; 0 if all writable */
+#define XCHAL_DTLB_SET1_PPN_CONSTMASK		0	/* constant PPN bits, including entry index bits; 0 if all writable */
+#define XCHAL_DTLB_SET1_CA_CONSTMASK		0	/* constant CA bits; 0 if all writable */
+#define XCHAL_DTLB_SET1_ASID_RESET		0	/* 1 if ASID reset values defined (and all writable); 0 otherwise */
+#define XCHAL_DTLB_SET1_VPN_RESET		0	/* 1 if VPN reset values defined (and all writable); 0 otherwise */
+#define XCHAL_DTLB_SET1_PPN_RESET		0	/* 1 if PPN reset values defined (and all writable); 0 otherwise */
+#define XCHAL_DTLB_SET1_CA_RESET		0	/* 1 if CA reset values defined (and all writable); 0 otherwise */
+
+/*  DTLB way set 2 (group of ways 5 thru 5):  */
+#define XCHAL_DTLB_SET2_WAY			5	/* index of first way in this way set */
+#define XCHAL_DTLB_SET2_WAYS			1	/* number of (contiguous) ways in this way set */
+#define XCHAL_DTLB_SET2_ENTRIES_LOG2		1	/* log2(number of entries in this way) */
+#define XCHAL_DTLB_SET2_ENTRIES			2	/* number of entries in this way (always a power of 2) */
+#define XCHAL_DTLB_SET2_ARF			0	/* 1=autorefill by h/w, 0=non-autorefill (wired/constant/static) */
+#define XCHAL_DTLB_SET2_PAGESIZES		1	/* number of supported page sizes in this way */
+#define XCHAL_DTLB_SET2_PAGESZ_BITS		0	/* number of bits to encode the page size */
+#define XCHAL_DTLB_SET2_PAGESZ_LOG2_MIN		27	/* log2(minimum supported page size) */
+#define XCHAL_DTLB_SET2_PAGESZ_LOG2_MAX		27	/* log2(maximum supported page size) */
+#define XCHAL_DTLB_SET2_PAGESZ_LOG2_LIST	27	/* list of log2(page size)s, separated by XCHAL_SEP;
+							   2^PAGESZ_BITS entries in list, unsupported entries are zero */
+#define XCHAL_DTLB_SET2_ASID_CONSTMASK		0xFF	/* constant ASID bits; 0 if all writable */
+#define XCHAL_DTLB_SET2_VPN_CONSTMASK		0xF0000000	/* constant VPN bits, not including entry index bits; 0 if all writable */
+#define XCHAL_DTLB_SET2_PPN_CONSTMASK		0xF8000000	/* constant PPN bits, including entry index bits; 0 if all writable */
+#define XCHAL_DTLB_SET2_CA_CONSTMASK		0x0000000F	/* constant CA bits; 0 if all writable */
+#define XCHAL_DTLB_SET2_ASID_RESET		0	/* 1 if ASID reset values defined (and all writable); 0 otherwise */
+#define XCHAL_DTLB_SET2_VPN_RESET		0	/* 1 if VPN reset values defined (and all writable); 0 otherwise */
+#define XCHAL_DTLB_SET2_PPN_RESET		0	/* 1 if PPN reset values defined (and all writable); 0 otherwise */
+#define XCHAL_DTLB_SET2_CA_RESET		0	/* 1 if CA reset values defined (and all writable); 0 otherwise */
+/*  Constant ASID values for each entry of DTLB way set 2 (because ASID_CONSTMASK is non-zero):  */
+#define XCHAL_DTLB_SET2_E0_ASID_CONST		0x01
+#define XCHAL_DTLB_SET2_E1_ASID_CONST		0x01
+/*  Constant VPN values for each entry of DTLB way set 2 (because VPN_CONSTMASK is non-zero):  */
+#define XCHAL_DTLB_SET2_E0_VPN_CONST		0xD0000000
+#define XCHAL_DTLB_SET2_E1_VPN_CONST		0xD8000000
+/*  Constant PPN values for each entry of DTLB way set 2 (because PPN_CONSTMASK is non-zero):  */
+#define XCHAL_DTLB_SET2_E0_PPN_CONST		0x00000000
+#define XCHAL_DTLB_SET2_E1_PPN_CONST		0x00000000
+/*  Constant CA values for each entry of DTLB way set 2 (because CA_CONSTMASK is non-zero):  */
+#define XCHAL_DTLB_SET2_E0_CA_CONST		0x07
+#define XCHAL_DTLB_SET2_E1_CA_CONST		0x03
+
+/*  DTLB way set 3 (group of ways 6 thru 6):  */
+#define XCHAL_DTLB_SET3_WAY			6	/* index of first way in this way set */
+#define XCHAL_DTLB_SET3_WAYS			1	/* number of (contiguous) ways in this way set */
+#define XCHAL_DTLB_SET3_ENTRIES_LOG2		1	/* log2(number of entries in this way) */
+#define XCHAL_DTLB_SET3_ENTRIES			2	/* number of entries in this way (always a power of 2) */
+#define XCHAL_DTLB_SET3_ARF			0	/* 1=autorefill by h/w, 0=non-autorefill (wired/constant/static) */
+#define XCHAL_DTLB_SET3_PAGESIZES		1	/* number of supported page sizes in this way */
+#define XCHAL_DTLB_SET3_PAGESZ_BITS		0	/* number of bits to encode the page size */
+#define XCHAL_DTLB_SET3_PAGESZ_LOG2_MIN		28	/* log2(minimum supported page size) */
+#define XCHAL_DTLB_SET3_PAGESZ_LOG2_MAX		28	/* log2(maximum supported page size) */
+#define XCHAL_DTLB_SET3_PAGESZ_LOG2_LIST	28	/* list of log2(page size)s, separated by XCHAL_SEP;
+							   2^PAGESZ_BITS entries in list, unsupported entries are zero */
+#define XCHAL_DTLB_SET3_ASID_CONSTMASK		0xFF	/* constant ASID bits; 0 if all writable */
+#define XCHAL_DTLB_SET3_VPN_CONSTMASK		0xE0000000	/* constant VPN bits, not including entry index bits; 0 if all writable */
+#define XCHAL_DTLB_SET3_PPN_CONSTMASK		0xF0000000	/* constant PPN bits, including entry index bits; 0 if all writable */
+#define XCHAL_DTLB_SET3_CA_CONSTMASK		0x0000000F	/* constant CA bits; 0 if all writable */
+#define XCHAL_DTLB_SET3_ASID_RESET		0	/* 1 if ASID reset values defined (and all writable); 0 otherwise */
+#define XCHAL_DTLB_SET3_VPN_RESET		0	/* 1 if VPN reset values defined (and all writable); 0 otherwise */
+#define XCHAL_DTLB_SET3_PPN_RESET		0	/* 1 if PPN reset values defined (and all writable); 0 otherwise */
+#define XCHAL_DTLB_SET3_CA_RESET		0	/* 1 if CA reset values defined (and all writable); 0 otherwise */
+/*  Constant ASID values for each entry of DTLB way set 3 (because ASID_CONSTMASK is non-zero):  */
+#define XCHAL_DTLB_SET3_E0_ASID_CONST		0x01
+#define XCHAL_DTLB_SET3_E1_ASID_CONST		0x01
+/*  Constant VPN values for each entry of DTLB way set 3 (because VPN_CONSTMASK is non-zero):  */
+#define XCHAL_DTLB_SET3_E0_VPN_CONST		0xE0000000
+#define XCHAL_DTLB_SET3_E1_VPN_CONST		0xF0000000
+/*  Constant PPN values for each entry of DTLB way set 3 (because PPN_CONSTMASK is non-zero):  */
+#define XCHAL_DTLB_SET3_E0_PPN_CONST		0xF0000000
+#define XCHAL_DTLB_SET3_E1_PPN_CONST		0xF0000000
+/*  Constant CA values for each entry of DTLB way set 3 (because CA_CONSTMASK is non-zero):  */
+#define XCHAL_DTLB_SET3_E0_CA_CONST		0x07
+#define XCHAL_DTLB_SET3_E1_CA_CONST		0x03
+
+/*  DTLB way set 4 (group of ways 7 thru 9):  */
+#define XCHAL_DTLB_SET4_WAY			7	/* index of first way in this way set */
+#define XCHAL_DTLB_SET4_WAYS			3	/* number of (contiguous) ways in this way set */
+#define XCHAL_DTLB_SET4_ENTRIES_LOG2		0	/* log2(number of entries in this way) */
+#define XCHAL_DTLB_SET4_ENTRIES			1	/* number of entries in this way (always a power of 2) */
+#define XCHAL_DTLB_SET4_ARF			0	/* 1=autorefill by h/w, 0=non-autorefill (wired/constant/static) */
+#define XCHAL_DTLB_SET4_PAGESIZES		1	/* number of supported page sizes in this way */
+#define XCHAL_DTLB_SET4_PAGESZ_BITS		0	/* number of bits to encode the page size */
+#define XCHAL_DTLB_SET4_PAGESZ_LOG2_MIN		12	/* log2(minimum supported page size) */
+#define XCHAL_DTLB_SET4_PAGESZ_LOG2_MAX		12	/* log2(maximum supported page size) */
+#define XCHAL_DTLB_SET4_PAGESZ_LOG2_LIST	12	/* list of log2(page size)s, separated by XCHAL_SEP;
+							   2^PAGESZ_BITS entries in list, unsupported entries are zero */
+#define XCHAL_DTLB_SET4_ASID_CONSTMASK		0	/* constant ASID bits; 0 if all writable */
+#define XCHAL_DTLB_SET4_VPN_CONSTMASK		0	/* constant VPN bits, not including entry index bits; 0 if all writable */
+#define XCHAL_DTLB_SET4_PPN_CONSTMASK		0	/* constant PPN bits, including entry index bits; 0 if all writable */
+#define XCHAL_DTLB_SET4_CA_CONSTMASK		0	/* constant CA bits; 0 if all writable */
+#define XCHAL_DTLB_SET4_ASID_RESET		0	/* 1 if ASID reset values defined (and all writable); 0 otherwise */
+#define XCHAL_DTLB_SET4_VPN_RESET		0	/* 1 if VPN reset values defined (and all writable); 0 otherwise */
+#define XCHAL_DTLB_SET4_PPN_RESET		0	/* 1 if PPN reset values defined (and all writable); 0 otherwise */
+#define XCHAL_DTLB_SET4_CA_RESET		0	/* 1 if CA reset values defined (and all writable); 0 otherwise */
+
+/*  Indexing macros:  */
+#define _XCHAL_DTLB_SET(n,_what)	XCHAL_DTLB_SET ## n ## _what
+#define XCHAL_DTLB_SET(n,what)		_XCHAL_DTLB_SET(n, _ ## what )
+#define _XCHAL_DTLB_SET_E(n,i,_what)	XCHAL_DTLB_SET ## n ## _E ## i ## _what
+#define XCHAL_DTLB_SET_E(n,i,what)	_XCHAL_DTLB_SET_E(n,i, _ ## what )
+/*
+ *  Example use:  XCHAL_DTLB_SET(XCHAL_DTLB_ARF_SET0,ENTRIES)
+ *	to get the value of XCHAL_DTLB_SET<n>_ENTRIES where <n> is the first auto-refill set.
+ */
+
+
+/*
+ *  Determine whether we have a full MMU (with Page Table and Protection)
+ *  usable for an MMU-based OS:
+ */
+#if XCHAL_HAVE_TLBS && !XCHAL_HAVE_SPANNING_WAY && XCHAL_ITLB_ARF_WAYS > 0 && XCHAL_DTLB_ARF_WAYS > 0 && XCHAL_MMU_RINGS >= 2
+# define XCHAL_HAVE_PTP_MMU		1	/* have full MMU (with page table [autorefill] and protection) */
+#else
+# define XCHAL_HAVE_PTP_MMU		0	/* don't have full MMU */
+#endif
+
+/*
+ *  For full MMUs, report kernel RAM segment and kernel I/O segment static page mappings:
+ */
+#if XCHAL_HAVE_PTP_MMU
+#define XCHAL_KSEG_CACHED_VADDR		0xD0000000	/* virt.addr of kernel RAM cached static map */
+#define XCHAL_KSEG_CACHED_PADDR		0x00000000	/* phys.addr of kseg_cached */
+#define XCHAL_KSEG_CACHED_SIZE		0x08000000	/* size in bytes of kseg_cached (assumed power of 2!!!) */
+#define XCHAL_KSEG_BYPASS_VADDR		0xD8000000	/* virt.addr of kernel RAM bypass (uncached) static map */
+#define XCHAL_KSEG_BYPASS_PADDR		0x00000000	/* phys.addr of kseg_bypass */
+#define XCHAL_KSEG_BYPASS_SIZE		0x08000000	/* size in bytes of kseg_bypass (assumed power of 2!!!) */
+
+#define XCHAL_KIO_CACHED_VADDR		0xE0000000	/* virt.addr of kernel I/O cached static map */
+#define XCHAL_KIO_CACHED_PADDR		0xF0000000	/* phys.addr of kio_cached */
+#define XCHAL_KIO_CACHED_SIZE		0x10000000	/* size in bytes of kio_cached (assumed power of 2!!!) */
+#define XCHAL_KIO_BYPASS_VADDR		0xF0000000	/* virt.addr of kernel I/O bypass (uncached) static map */
+#define XCHAL_KIO_BYPASS_PADDR		0xF0000000	/* phys.addr of kio_bypass */
+#define XCHAL_KIO_BYPASS_SIZE		0x10000000	/* size in bytes of kio_bypass (assumed power of 2!!!) */
+
+#define XCHAL_SEG_MAPPABLE_VADDR	0x00000000	/* start of largest non-static-mapped virtual addr area */
+#define XCHAL_SEG_MAPPABLE_SIZE		0xD0000000	/* size in bytes of  "  */
+/* define XCHAL_SEG_MAPPABLE2_xxx if more areas present, sorted in order of descending size.  */
+#endif
+
+
+/*----------------------------------------------------------------------
+				MISC
+  ----------------------------------------------------------------------*/
+
+#define XCHAL_NUM_WRITEBUFFER_ENTRIES	4	/* number of write buffer entries */
+
+#define XCHAL_CORE_ID			"linux_be"	/* configuration's alphanumeric core identifier
+							   (CoreID) set in the Xtensa Processor Generator */
+
+#define XCHAL_BUILD_UNIQUE_ID		0x00003256	/* software build-unique ID (22-bit) */
+
+/*  These definitions describe the hardware targeted by this software:  */
+#define XCHAL_HW_CONFIGID0		0xC103D1FF	/* config ID reg 0 value (upper 32 of 64 bits) */
+#define XCHAL_HW_CONFIGID1		0x00803256	/* config ID reg 1 value (lower 32 of 64 bits) */
+#define XCHAL_CONFIGID0			XCHAL_HW_CONFIGID0	/* for backward compatibility only -- don't use! */
+#define XCHAL_CONFIGID1			XCHAL_HW_CONFIGID1	/* for backward compatibility only -- don't use! */
+#define XCHAL_HW_RELEASE_MAJOR		1050	/* major release of targeted hardware */
+#define XCHAL_HW_RELEASE_MINOR		1	/* minor release of targeted hardware */
+#define XCHAL_HW_RELEASE_NAME		"T1050.1"	/* full release name of targeted hardware */
+#define XTHAL_HW_REL_T1050	1
+#define XTHAL_HW_REL_T1050_1	1
+#define XCHAL_HW_CONFIGID_RELIABLE	1
+
+
+/*
+ *  Miscellaneous special register fields:
+ */
+
+
+/*  DBREAKC (special register number 160):  */
+#define XCHAL_DBREAKC_VALIDMASK	0xC000003F	/* bits of DBREAKC that are defined */
+/*  MASK field:  */
+#define XCHAL_DBREAKC_MASK_BITS 	6		/* number of bits in MASK field */
+#define XCHAL_DBREAKC_MASK_NUM  	64		/* max number of possible causes (2^bits) */
+#define XCHAL_DBREAKC_MASK_SHIFT	0		/* position of MASK bits in DBREAKC, starting from lsbit */
+#define XCHAL_DBREAKC_MASK_MASK 	0x0000003F	/* mask of bits in MASK field of DBREAKC */
+/*  LOADBREAK field:  */
+#define XCHAL_DBREAKC_LOADBREAK_BITS 	1		/* number of bits in LOADBREAK field */
+#define XCHAL_DBREAKC_LOADBREAK_NUM  	2		/* max number of possible causes (2^bits) */
+#define XCHAL_DBREAKC_LOADBREAK_SHIFT	30		/* position of LOADBREAK bits in DBREAKC, starting from lsbit */
+#define XCHAL_DBREAKC_LOADBREAK_MASK 	0x40000000	/* mask of bits in LOADBREAK field of DBREAKC */
+/*  STOREBREAK field:  */
+#define XCHAL_DBREAKC_STOREBREAK_BITS 	1		/* number of bits in STOREBREAK field */
+#define XCHAL_DBREAKC_STOREBREAK_NUM  	2		/* max number of possible causes (2^bits) */
+#define XCHAL_DBREAKC_STOREBREAK_SHIFT	31		/* position of STOREBREAK bits in DBREAKC, starting from lsbit */
+#define XCHAL_DBREAKC_STOREBREAK_MASK 	0x80000000	/* mask of bits in STOREBREAK field of DBREAKC */
+
+/*  PS (special register number 230):  */
+#define XCHAL_PS_VALIDMASK	0x00070FFF	/* bits of PS that are defined */
+/*  INTLEVEL field:  */
+#define XCHAL_PS_INTLEVEL_BITS 	4		/* number of bits in INTLEVEL field */
+#define XCHAL_PS_INTLEVEL_NUM  	16		/* max number of possible causes (2^bits) */
+#define XCHAL_PS_INTLEVEL_SHIFT	0		/* position of INTLEVEL bits in PS, starting from lsbit */
+#define XCHAL_PS_INTLEVEL_MASK 	0x0000000F	/* mask of bits in INTLEVEL field of PS */
+/*  EXCM field:  */
+#define XCHAL_PS_EXCM_BITS 	1		/* number of bits in EXCM field */
+#define XCHAL_PS_EXCM_NUM  	2		/* max number of possible causes (2^bits) */
+#define XCHAL_PS_EXCM_SHIFT	4		/* position of EXCM bits in PS, starting from lsbit */
+#define XCHAL_PS_EXCM_MASK 	0x00000010	/* mask of bits in EXCM field of PS */
+/*  PROGSTACK field:  */
+#define XCHAL_PS_PROGSTACK_BITS 	1		/* number of bits in PROGSTACK field */
+#define XCHAL_PS_PROGSTACK_NUM  	2		/* max number of possible causes (2^bits) */
+#define XCHAL_PS_PROGSTACK_SHIFT	5		/* position of PROGSTACK bits in PS, starting from lsbit */
+#define XCHAL_PS_PROGSTACK_MASK 	0x00000020	/* mask of bits in PROGSTACK field of PS */
+/*  RING field:  */
+#define XCHAL_PS_RING_BITS 	2		/* number of bits in RING field */
+#define XCHAL_PS_RING_NUM  	4		/* max number of possible causes (2^bits) */
+#define XCHAL_PS_RING_SHIFT	6		/* position of RING bits in PS, starting from lsbit */
+#define XCHAL_PS_RING_MASK 	0x000000C0	/* mask of bits in RING field of PS */
+/*  OWB field:  */
+#define XCHAL_PS_OWB_BITS 	4		/* number of bits in OWB field */
+#define XCHAL_PS_OWB_NUM  	16		/* max number of possible causes (2^bits) */
+#define XCHAL_PS_OWB_SHIFT	8		/* position of OWB bits in PS, starting from lsbit */
+#define XCHAL_PS_OWB_MASK 	0x00000F00	/* mask of bits in OWB field of PS */
+/*  CALLINC field:  */
+#define XCHAL_PS_CALLINC_BITS 	2		/* number of bits in CALLINC field */
+#define XCHAL_PS_CALLINC_NUM  	4		/* max number of possible causes (2^bits) */
+#define XCHAL_PS_CALLINC_SHIFT	16		/* position of CALLINC bits in PS, starting from lsbit */
+#define XCHAL_PS_CALLINC_MASK 	0x00030000	/* mask of bits in CALLINC field of PS */
+/*  WOE field:  */
+#define XCHAL_PS_WOE_BITS 	1		/* number of bits in WOE field */
+#define XCHAL_PS_WOE_NUM  	2		/* max number of possible causes (2^bits) */
+#define XCHAL_PS_WOE_SHIFT	18		/* position of WOE bits in PS, starting from lsbit */
+#define XCHAL_PS_WOE_MASK 	0x00040000	/* mask of bits in WOE field of PS */
+
+/*  EXCCAUSE (special register number 232):  */
+#define XCHAL_EXCCAUSE_VALIDMASK	0x0000003F	/* bits of EXCCAUSE that are defined */
+/*  EXCCAUSE field:  */
+#define XCHAL_EXCCAUSE_BITS 		6		/* number of bits in EXCCAUSE register */
+#define XCHAL_EXCCAUSE_NUM  		64		/* max number of possible causes (2^bits) */
+#define XCHAL_EXCCAUSE_SHIFT		0		/* position of EXCCAUSE bits in register, starting from lsbit */
+#define XCHAL_EXCCAUSE_MASK 		0x0000003F	/* mask of bits in EXCCAUSE register */
+
+/*  DEBUGCAUSE (special register number 233):  */
+#define XCHAL_DEBUGCAUSE_VALIDMASK	0x0000003F	/* bits of DEBUGCAUSE that are defined */
+/*  ICOUNT field:  */
+#define XCHAL_DEBUGCAUSE_ICOUNT_BITS 	1		/* number of bits in ICOUNT field */
+#define XCHAL_DEBUGCAUSE_ICOUNT_NUM  	2		/* max number of possible causes (2^bits) */
+#define XCHAL_DEBUGCAUSE_ICOUNT_SHIFT	0		/* position of ICOUNT bits in DEBUGCAUSE, starting from lsbit */
+#define XCHAL_DEBUGCAUSE_ICOUNT_MASK 	0x00000001	/* mask of bits in ICOUNT field of DEBUGCAUSE */
+/*  IBREAK field:  */
+#define XCHAL_DEBUGCAUSE_IBREAK_BITS 	1		/* number of bits in IBREAK field */
+#define XCHAL_DEBUGCAUSE_IBREAK_NUM  	2		/* max number of possible causes (2^bits) */
+#define XCHAL_DEBUGCAUSE_IBREAK_SHIFT	1		/* position of IBREAK bits in DEBUGCAUSE, starting from lsbit */
+#define XCHAL_DEBUGCAUSE_IBREAK_MASK 	0x00000002	/* mask of bits in IBREAK field of DEBUGCAUSE */
+/*  DBREAK field:  */
+#define XCHAL_DEBUGCAUSE_DBREAK_BITS 	1		/* number of bits in DBREAK field */
+#define XCHAL_DEBUGCAUSE_DBREAK_NUM  	2		/* max number of possible causes (2^bits) */
+#define XCHAL_DEBUGCAUSE_DBREAK_SHIFT	2		/* position of DBREAK bits in DEBUGCAUSE, starting from lsbit */
+#define XCHAL_DEBUGCAUSE_DBREAK_MASK 	0x00000004	/* mask of bits in DBREAK field of DEBUGCAUSE */
+/*  BREAK field:  */
+#define XCHAL_DEBUGCAUSE_BREAK_BITS 	1		/* number of bits in BREAK field */
+#define XCHAL_DEBUGCAUSE_BREAK_NUM  	2		/* max number of possible causes (2^bits) */
+#define XCHAL_DEBUGCAUSE_BREAK_SHIFT	3		/* position of BREAK bits in DEBUGCAUSE, starting from lsbit */
+#define XCHAL_DEBUGCAUSE_BREAK_MASK 	0x00000008	/* mask of bits in BREAK field of DEBUGCAUSE */
+/*  BREAKN field:  */
+#define XCHAL_DEBUGCAUSE_BREAKN_BITS 	1		/* number of bits in BREAKN field */
+#define XCHAL_DEBUGCAUSE_BREAKN_NUM  	2		/* max number of possible causes (2^bits) */
+#define XCHAL_DEBUGCAUSE_BREAKN_SHIFT	4		/* position of BREAKN bits in DEBUGCAUSE, starting from lsbit */
+#define XCHAL_DEBUGCAUSE_BREAKN_MASK 	0x00000010	/* mask of bits in BREAKN field of DEBUGCAUSE */
+/*  DEBUGINT field:  */
+#define XCHAL_DEBUGCAUSE_DEBUGINT_BITS 	1		/* number of bits in DEBUGINT field */
+#define XCHAL_DEBUGCAUSE_DEBUGINT_NUM  	2		/* max number of possible causes (2^bits) */
+#define XCHAL_DEBUGCAUSE_DEBUGINT_SHIFT	5		/* position of DEBUGINT bits in DEBUGCAUSE, starting from lsbit */
+#define XCHAL_DEBUGCAUSE_DEBUGINT_MASK 	0x00000020	/* mask of bits in DEBUGINT field of DEBUGCAUSE */
+
+
+
+/*----------------------------------------------------------------------
+				ISA
+  ----------------------------------------------------------------------*/
+
+#define XCHAL_HAVE_DENSITY		1	/* 1 if density option configured, 0 otherwise */
+#define XCHAL_HAVE_LOOPS		1	/* 1 if zero-overhead loops option configured, 0 otherwise */
+/*  Misc instructions:  */
+#define XCHAL_HAVE_NSA			0	/* 1 if NSA/NSAU instructions option configured, 0 otherwise */
+#define XCHAL_HAVE_MINMAX		0	/* 1 if MIN/MAX instructions option configured, 0 otherwise */
+#define XCHAL_HAVE_SEXT			0	/* 1 if sign-extend instruction option configured, 0 otherwise */
+#define XCHAL_HAVE_CLAMPS		0	/* 1 if CLAMPS instruction option configured, 0 otherwise */
+#define XCHAL_HAVE_MAC16		0	/* 1 if MAC16 option configured, 0 otherwise */
+#define XCHAL_HAVE_MUL16		0	/* 1 if 16-bit integer multiply option configured, 0 otherwise */
+/*#define XCHAL_HAVE_POPC		0*/	/* 1 if CRC instruction option configured, 0 otherwise */
+/*#define XCHAL_HAVE_CRC		0*/	/* 1 if POPC instruction option configured, 0 otherwise */
+
+#define XCHAL_HAVE_SPECULATION		0	/* 1 if speculation option configured, 0 otherwise */
+/*#define XCHAL_HAVE_MP_SYNC		0*/	/* 1 if multiprocessor sync. option configured, 0 otherwise */
+#define XCHAL_HAVE_PRID			0	/* 1 if processor ID register configured, 0 otherwise */
+
+#define XCHAL_NUM_MISC_REGS		2	/* number of miscellaneous registers (0..4) */
+
+/*  These relate a bit more to TIE:  */
+#define XCHAL_HAVE_BOOLEANS		0	/* 1 if booleans option configured, 0 otherwise */
+#define XCHAL_HAVE_MUL32		0	/* 1 if 32-bit integer multiply option configured, 0 otherwise */
+#define XCHAL_HAVE_MUL32_HIGH		0	/* 1 if MUL32 option includes MULUH and MULSH, 0 otherwise */
+#define XCHAL_HAVE_FP			0	/* 1 if floating point option configured, 0 otherwise */
+
+
+/*----------------------------------------------------------------------
+				DERIVED
+  ----------------------------------------------------------------------*/
+
+#if XCHAL_HAVE_BE
+#define XCHAL_INST_ILLN			0xD60F		/* 2-byte illegal instruction, msb-first */
+#define XCHAL_INST_ILLN_BYTE0		0xD6		/* 2-byte illegal instruction, 1st byte */
+#define XCHAL_INST_ILLN_BYTE1		0x0F		/* 2-byte illegal instruction, 2nd byte */
+#else
+#define XCHAL_INST_ILLN			0xF06D		/* 2-byte illegal instruction, lsb-first */
+#define XCHAL_INST_ILLN_BYTE0		0x6D		/* 2-byte illegal instruction, 1st byte */
+#define XCHAL_INST_ILLN_BYTE1		0xF0		/* 2-byte illegal instruction, 2nd byte */
+#endif
+/*  Belongs in xtensa/hal.h:  */
+#define XTHAL_INST_ILL			0x000000	/* 3-byte illegal instruction */
+
+
+/*
+ *  Because information as to exactly which hardware release is targeted
+ *  by a given software build is not always available, compile-time HAL
+ *  Hardware-Release "_AT" macros are fuzzy (return 0, 1, or XCHAL_MAYBE):
+ */
+#ifndef XCHAL_HW_RELEASE_MAJOR
+# define XCHAL_HW_CONFIGID_RELIABLE	0
+#endif
+#if XCHAL_HW_CONFIGID_RELIABLE
+# define XCHAL_HW_RELEASE_AT_OR_BELOW(major,minor)	(XTHAL_REL_LE( XCHAL_HW_RELEASE_MAJOR,XCHAL_HW_RELEASE_MINOR, major,minor ) ? 1 : 0)
+# define XCHAL_HW_RELEASE_AT_OR_ABOVE(major,minor)	(XTHAL_REL_GE( XCHAL_HW_RELEASE_MAJOR,XCHAL_HW_RELEASE_MINOR, major,minor ) ? 1 : 0)
+# define XCHAL_HW_RELEASE_AT(major,minor)		(XTHAL_REL_EQ( XCHAL_HW_RELEASE_MAJOR,XCHAL_HW_RELEASE_MINOR, major,minor ) ? 1 : 0)
+# define XCHAL_HW_RELEASE_MAJOR_AT(major)		((XCHAL_HW_RELEASE_MAJOR == (major)) ? 1 : 0)
+#else
+# define XCHAL_HW_RELEASE_AT_OR_BELOW(major,minor)	( ((major) < 1040 && XCHAL_HAVE_XEA2) ? 0 \
+							: ((major) > 1050 && XCHAL_HAVE_XEA1) ? 1 \
+							: XTHAL_MAYBE )
+# define XCHAL_HW_RELEASE_AT_OR_ABOVE(major,minor)	( ((major) >= 2000 && XCHAL_HAVE_XEA1) ? 0 \
+							: (XTHAL_REL_LE(major,minor, 1040,0) && XCHAL_HAVE_XEA2) ? 1 \
+							: XTHAL_MAYBE )
+# define XCHAL_HW_RELEASE_AT(major,minor)		( (((major) < 1040 && XCHAL_HAVE_XEA2) || \
+							   ((major) >= 2000 && XCHAL_HAVE_XEA1)) ? 0 : XTHAL_MAYBE)
+# define XCHAL_HW_RELEASE_MAJOR_AT(major)		XCHAL_HW_RELEASE_AT(major,0)
+#endif
+
+/*
+ *  Specific errata:
+ */
+
+/*
+ *  Erratum T1020.H13, T1030.H7, T1040.H10, T1050.H4 (fixed in T1040.3 and T1050.1;
+ *  relevant only in XEA1, kernel-vector mode, level-one interrupts and overflows enabled):
+ */
+#define XCHAL_MAYHAVE_ERRATUM_XEA1KWIN	(XCHAL_HAVE_XEA1 && \
+					 (XCHAL_HW_RELEASE_AT_OR_BELOW(1040,2) != 0 \
+					  || XCHAL_HW_RELEASE_AT(1050,0)))
+
+
+
+#endif /*XTENSA_CONFIG_CORE_H*/
+
diff --git a/include/asm-xtensa/xtensa/config-linux_be/defs.h b/include/asm-xtensa/xtensa/config-linux_be/defs.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/xtensa/config-linux_be/defs.h
@@ -0,0 +1,270 @@
+/* Definitions for Xtensa instructions, types, and protos. */
+
+/*
+ * Copyright (c) 2003 Tensilica, Inc.  All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2.1 of the GNU Lesser General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like.  Any license provided herein, whether implied or
+ * otherwise, applies only to this software file.  Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307,
+ * USA.
+ */
+
+/* Do not modify. This is automatically generated.*/
+
+#ifndef _XTENSA_BASE_HEADER
+#define _XTENSA_BASE_HEADER
+
+#ifdef __XTENSA__
+#if defined(__GNUC__) && !defined(__XCC__)
+
+#define L8UI_ASM(arr, ars, imm) { \
+  __asm__ volatile("l8ui %0, %1, %2" : "=a" (arr) : "a" (ars) , "i" (imm)); \
+}
+
+#define XT_L8UI(ars, imm) \
+({ \
+  unsigned char _arr; \
+  const unsigned char *_ars = ars; \
+  L8UI_ASM(_arr, _ars, imm); \
+  _arr; \
+})
+
+#define L16UI_ASM(arr, ars, imm) { \
+  __asm__ volatile("l16ui %0, %1, %2" : "=a" (arr) : "a" (ars) , "i" (imm)); \
+}
+
+#define XT_L16UI(ars, imm) \
+({ \
+  unsigned short _arr; \
+  const unsigned short *_ars = ars; \
+  L16UI_ASM(_arr, _ars, imm); \
+  _arr; \
+})
+
+#define L16SI_ASM(arr, ars, imm) {\
+  __asm__ volatile("l16si %0, %1, %2" : "=a" (arr) : "a" (ars) , "i" (imm)); \
+}
+
+#define XT_L16SI(ars, imm) \
+({ \
+  signed short _arr; \
+  const signed short *_ars = ars; \
+  L16SI_ASM(_arr, _ars, imm); \
+  _arr; \
+})
+
+#define L32I_ASM(arr, ars, imm) { \
+  __asm__ volatile("l32i %0, %1, %2" : "=a" (arr) : "a" (ars) , "i" (imm)); \
+}
+
+#define XT_L32I(ars, imm) \
+({ \
+  unsigned _arr; \
+  const unsigned *_ars = ars; \
+  L32I_ASM(_arr, _ars, imm); \
+  _arr; \
+})
+
+#define S8I_ASM(arr, ars, imm) {\
+  __asm__ volatile("s8i %0, %1, %2" : : "a" (arr), "a" (ars) , "i" (imm) : "memory" ); \
+}
+
+#define XT_S8I(arr, ars, imm) \
+({ \
+  signed char _arr = arr; \
+  const signed char *_ars = ars; \
+  S8I_ASM(_arr, _ars, imm); \
+})
+
+#define S16I_ASM(arr, ars, imm) {\
+  __asm__ volatile("s16i %0, %1, %2" : : "a" (arr), "a" (ars) , "i" (imm) : "memory" ); \
+}
+
+#define XT_S16I(arr, ars, imm) \
+({ \
+  signed short _arr = arr; \
+  const signed short *_ars = ars; \
+  S16I_ASM(_arr, _ars, imm); \
+})
+
+#define S32I_ASM(arr, ars, imm) { \
+  __asm__ volatile("s32i %0, %1, %2" : : "a" (arr), "a" (ars) , "i" (imm) : "memory" ); \
+}
+
+#define XT_S32I(arr, ars, imm) \
+({ \
+  signed int _arr = arr; \
+  const signed int *_ars = ars; \
+  S32I_ASM(_arr, _ars, imm); \
+})
+
+#define ADDI_ASM(art, ars, imm) {\
+   __asm__ ("addi %0, %1, %2" : "=a" (art) : "a" (ars), "i" (imm)); \
+}
+
+#define XT_ADDI(ars, imm) \
+({ \
+   unsigned _art; \
+   unsigned _ars = ars; \
+   ADDI_ASM(_art, _ars, imm); \
+   _art; \
+})
+
+#define ABS_ASM(arr, art) {\
+   __asm__ ("abs %0, %1" : "=a" (arr) : "a" (art)); \
+}
+
+#define XT_ABS(art) \
+({ \
+   unsigned _arr; \
+   signed _art = art; \
+   ABS_ASM(_arr, _art); \
+   _arr; \
+})
+
+/* Note: In the following macros that reference SAR, the magic "state"
+   register is used to capture the dependency on SAR.  This is because
+   SAR is a 5-bit register and thus there are no C types that can be
+   used to represent it.  It doesn't appear that the SAR register is
+   even relevant to GCC, but it is marked as "clobbered" just in
+   case.  */
+
+#define SRC_ASM(arr, ars, art) {\
+   register int _xt_sar __asm__ ("state"); \
+   __asm__ ("src %0, %1, %2" \
+	    : "=a" (arr) : "a" (ars), "a" (art), "t" (_xt_sar)); \
+}
+
+#define XT_SRC(ars, art) \
+({ \
+   unsigned _arr; \
+   unsigned _ars = ars; \
+   unsigned _art = art; \
+   SRC_ASM(_arr, _ars, _art); \
+   _arr; \
+})
+
+#define SSR_ASM(ars) {\
+   register int _xt_sar __asm__ ("state"); \
+   __asm__ ("ssr %1" : "=t" (_xt_sar) : "a" (ars) : "sar"); \
+}
+
+#define XT_SSR(ars) \
+({ \
+   unsigned _ars = ars; \
+   SSR_ASM(_ars); \
+})
+
+#define SSL_ASM(ars) {\
+   register int _xt_sar __asm__ ("state"); \
+   __asm__ ("ssl %1" : "=t" (_xt_sar) : "a" (ars) : "sar"); \
+}
+
+#define XT_SSL(ars) \
+({ \
+   unsigned _ars = ars; \
+   SSL_ASM(_ars); \
+})
+
+#define SSA8B_ASM(ars) {\
+   register int _xt_sar __asm__ ("state"); \
+   __asm__ ("ssa8b %1" : "=t" (_xt_sar) : "a" (ars) : "sar"); \
+}
+
+#define XT_SSA8B(ars) \
+({ \
+   unsigned _ars = ars; \
+   SSA8B_ASM(_ars); \
+})
+
+#define SSA8L_ASM(ars) {\
+   register int _xt_sar __asm__ ("state"); \
+   __asm__ ("ssa8l %1" : "=t" (_xt_sar) : "a" (ars) : "sar"); \
+}
+
+#define XT_SSA8L(ars) \
+({ \
+   unsigned _ars = ars; \
+   SSA8L_ASM(_ars); \
+})
+
+#define SSAI_ASM(imm) {\
+   register int _xt_sar __asm__ ("state"); \
+   __asm__ ("ssai %1" : "=t" (_xt_sar) : "i" (imm) : "sar"); \
+}
+
+#define XT_SSAI(imm) \
+({ \
+   SSAI_ASM(imm); \
+})
+
+
+
+
+
+
+
+
+#endif /* __GNUC__ && !__XCC__ */
+
+#ifdef __XCC__
+
+/* Core load/store instructions */
+extern unsigned char _TIE_L8UI(const unsigned char * ars, immediate imm);
+extern unsigned short _TIE_L16UI(const unsigned short * ars, immediate imm);
+extern signed short _TIE_L16SI(const signed short * ars, immediate imm);
+extern unsigned _TIE_L32I(const unsigned * ars, immediate imm);
+extern void _TIE_S8I(unsigned char arr, unsigned char * ars, immediate imm);
+extern void _TIE_S16I(unsigned short arr, unsigned short * ars, immediate imm);
+extern void _TIE_S32I(unsigned arr, unsigned * ars, immediate imm);
+
+#define XT_L8UI  _TIE_L8UI
+#define XT_L16UI _TIE_L16UI
+#define XT_L16SI _TIE_L16SI
+#define XT_L32I  _TIE_L32I
+#define XT_S8I   _TIE_S8I
+#define XT_S16I  _TIE_S16I
+#define XT_S32I  _TIE_S32I
+
+/* Add-immediate instruction */
+extern unsigned _TIE_ADDI(unsigned ars, immediate imm);
+#define XT_ADDI  _TIE_ADDI
+
+/* Absolute value instruction */
+extern unsigned _TIE_ABS(int art);
+#define XT_ABS _TIE_ABS
+
+/* funnel shift instructions */
+extern unsigned _TIE_SRC(unsigned ars, unsigned art);
+#define XT_SRC _TIE_SRC
+extern void _TIE_SSR(unsigned ars);
+#define XT_SSR _TIE_SSR
+extern void _TIE_SSL(unsigned ars);
+#define XT_SSL _TIE_SSL
+extern void _TIE_SSA8B(unsigned ars);
+#define XT_SSA8B _TIE_SSA8B
+extern void _TIE_SSA8L(unsigned ars);
+#define XT_SSA8L _TIE_SSA8L
+extern void _TIE_SSAI(immediate imm);
+#define XT_SSAI _TIE_SSAI
+
+
+#endif /* __XCC__ */
+
+#endif /* __XTENSA__ */
+#endif /* !_XTENSA_BASE_HEADER */
diff --git a/include/asm-xtensa/xtensa/config-linux_be/specreg.h b/include/asm-xtensa/xtensa/config-linux_be/specreg.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/xtensa/config-linux_be/specreg.h
@@ -0,0 +1,99 @@
+/*
+ * Xtensa Special Register symbolic names
+ */
+
+/* $Id: specreg.h,v 1.2 2003/03/07 19:15:18 joetaylor Exp $ */
+
+/*
+ * Copyright (c) 2003 Tensilica, Inc.  All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2.1 of the GNU Lesser General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like.  Any license provided herein, whether implied or
+ * otherwise, applies only to this software file.  Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307,
+ * USA.
+ */
+
+#ifndef XTENSA_SPECREG_H
+#define XTENSA_SPECREG_H
+
+/*  Include these special register bitfield definitions, for historical reasons:  */
+#include <xtensa/corebits.h>
+
+
+/*  Special registers:  */
+#define LBEG		0
+#define LEND		1
+#define LCOUNT		2
+#define SAR		3
+#define WINDOWBASE	72
+#define WINDOWSTART	73
+#define PTEVADDR	83
+#define RASID		90
+#define ITLBCFG		91
+#define DTLBCFG		92
+#define IBREAKENABLE	96
+#define DDR		104
+#define IBREAKA_0	128
+#define IBREAKA_1	129
+#define DBREAKA_0	144
+#define DBREAKA_1	145
+#define DBREAKC_0	160
+#define DBREAKC_1	161
+#define EPC_1		177
+#define EPC_2		178
+#define EPC_3		179
+#define EPC_4		180
+#define DEPC		192
+#define EPS_2		194
+#define EPS_3		195
+#define EPS_4		196
+#define EXCSAVE_1	209
+#define EXCSAVE_2	210
+#define EXCSAVE_3	211
+#define EXCSAVE_4	212
+#define INTERRUPT	226
+#define INTENABLE	228
+#define PS		230
+#define EXCCAUSE	232
+#define DEBUGCAUSE	233
+#define CCOUNT		234
+#define ICOUNT		236
+#define ICOUNTLEVEL	237
+#define EXCVADDR	238
+#define CCOMPARE_0	240
+#define CCOMPARE_1	241
+#define CCOMPARE_2	242
+#define MISC_REG_0	244
+#define MISC_REG_1	245
+
+/*  Special cases (bases of special register series):  */
+#define IBREAKA		128
+#define DBREAKA		144
+#define DBREAKC		160
+#define EPC		176
+#define EPS		192
+#define EXCSAVE		208
+#define CCOMPARE	240
+
+/*  Special names for read-only and write-only interrupt registers:  */
+#define INTREAD		226
+#define INTSET		226
+#define INTCLEAR	227
+
+#endif /* XTENSA_SPECREG_H */
+
diff --git a/include/asm-xtensa/xtensa/config-linux_be/system.h b/include/asm-xtensa/xtensa/config-linux_be/system.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/xtensa/config-linux_be/system.h
@@ -0,0 +1,198 @@
+/*
+ * xtensa/config/system.h -- HAL definitions that are dependent on SYSTEM configuration
+ *
+ *  NOTE: The location and contents of this file are highly subject to change.
+ *
+ *  Source for configuration-independent binaries (which link in a
+ *  configuration-specific HAL library) must NEVER include this file.
+ *  The HAL itself has historically included this file in some instances,
+ *  but this is not appropriate either, because the HAL is meant to be
+ *  core-specific but system independent.
+ */
+
+/*
+ * Copyright (c) 2003 Tensilica, Inc.  All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2.1 of the GNU Lesser General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like.  Any license provided herein, whether implied or
+ * otherwise, applies only to this software file.  Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307,
+ * USA.
+ */
+
+
+#ifndef XTENSA_CONFIG_SYSTEM_H
+#define XTENSA_CONFIG_SYSTEM_H
+
+/*#include <xtensa/hal.h>*/
+
+
+
+/*----------------------------------------------------------------------
+				DEVICE ADDRESSES
+  ----------------------------------------------------------------------*/
+
+/*
+ *  Strange place to find these, but the configuration GUI
+ *  allows moving these around to account for various core
+ *  configurations.  Specific boards (and their BSP software)
+ *  will have specific meanings for these components.
+ */
+
+/*  I/O Block areas:  */
+#define XSHAL_IOBLOCK_CACHED_VADDR	0xE0000000
+#define XSHAL_IOBLOCK_CACHED_PADDR	0xF0000000
+#define XSHAL_IOBLOCK_CACHED_SIZE	0x0E000000
+
+#define XSHAL_IOBLOCK_BYPASS_VADDR	0xF0000000
+#define XSHAL_IOBLOCK_BYPASS_PADDR	0xF0000000
+#define XSHAL_IOBLOCK_BYPASS_SIZE	0x0E000000
+
+/*  System ROM:  */
+#define XSHAL_ROM_VADDR		0xEE000000
+#define XSHAL_ROM_PADDR		0xFE000000
+#define XSHAL_ROM_SIZE		0x00400000
+/*  Largest available area (free of vectors):  */
+#define XSHAL_ROM_AVAIL_VADDR	0xEE00052C
+#define XSHAL_ROM_AVAIL_VSIZE	0x003FFAD4
+
+/*  System RAM:  */
+#define XSHAL_RAM_VADDR		0xD0000000
+#define XSHAL_RAM_PADDR		0x00000000
+#define XSHAL_RAM_VSIZE		0x08000000
+#define XSHAL_RAM_PSIZE		0x10000000
+#define XSHAL_RAM_SIZE		XSHAL_RAM_PSIZE
+/*  Largest available area (free of vectors):  */
+#define XSHAL_RAM_AVAIL_VADDR	0xD0000370
+#define XSHAL_RAM_AVAIL_VSIZE	0x07FFFC90
+
+/*
+ *  Shadow system RAM (same device as system RAM, at different address).
+ *  (Emulation boards need this for the SONIC Ethernet driver
+ *   when data caches are configured for writeback mode.)
+ *  NOTE: on full MMU configs, this points to the BYPASS virtual address
+ *  of system RAM, ie. is the same as XSHAL_RAM_* except that virtual
+ *  addresses are viewed through the BYPASS static map rather than
+ *  the CACHED static map.
+ */
+#define XSHAL_RAM_BYPASS_VADDR		0xD8000000
+#define XSHAL_RAM_BYPASS_PADDR		0x00000000
+#define XSHAL_RAM_BYPASS_PSIZE		0x08000000
+
+/*  Alternate system RAM (different device than system RAM):  */
+#define XSHAL_ALTRAM_VADDR		0xCEE00000
+#define XSHAL_ALTRAM_PADDR		0xC0000000
+#define XSHAL_ALTRAM_SIZE		0x00200000
+
+
+/*----------------------------------------------------------------------
+ *			DEVICE-ADDRESS DEPENDENT...
+ *
+ *  Values written to CACHEATTR special register (or its equivalent)
+ *  to enable and disable caches in various modes.
+ *----------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------
+			BACKWARD COMPATIBILITY ...
+  ----------------------------------------------------------------------*/
+
+/*
+ *  NOTE:  the following two macros are DEPRECATED.  Use the latter
+ *  board-specific macros instead, which are specially tuned for the
+ *  particular target environments' memory maps.
+ */
+#define XSHAL_CACHEATTR_BYPASS		XSHAL_XT2000_CACHEATTR_BYPASS	/* disable caches in bypass mode */
+#define XSHAL_CACHEATTR_DEFAULT		XSHAL_XT2000_CACHEATTR_DEFAULT	/* default setting to enable caches (no writeback!) */
+
+/*----------------------------------------------------------------------
+			ISS (Instruction Set Simulator) SPECIFIC ...
+  ----------------------------------------------------------------------*/
+
+#define XSHAL_ISS_CACHEATTR_WRITEBACK	0x1122222F	/* enable caches in write-back mode */
+#define XSHAL_ISS_CACHEATTR_WRITEALLOC	0x1122222F	/* enable caches in write-allocate mode */
+#define XSHAL_ISS_CACHEATTR_WRITETHRU	0x1122222F	/* enable caches in write-through mode */
+#define XSHAL_ISS_CACHEATTR_BYPASS	0x2222222F	/* disable caches in bypass mode */
+#define XSHAL_ISS_CACHEATTR_DEFAULT	XSHAL_ISS_CACHEATTR_WRITEBACK	/* default setting to enable caches */
+
+/*  For Coware only:  */
+#define XSHAL_COWARE_CACHEATTR_WRITEBACK	0x11222222	/* enable caches in write-back mode */
+#define XSHAL_COWARE_CACHEATTR_WRITEALLOC	0x11222222	/* enable caches in write-allocate mode */
+#define XSHAL_COWARE_CACHEATTR_WRITETHRU	0x11222222	/* enable caches in write-through mode */
+#define XSHAL_COWARE_CACHEATTR_BYPASS		0x22222222	/* disable caches in bypass mode */
+#define XSHAL_COWARE_CACHEATTR_DEFAULT		XSHAL_COWARE_CACHEATTR_WRITEBACK	/* default setting to enable caches */
+
+/*  For BFM and other purposes:  */
+#define XSHAL_ALLVALID_CACHEATTR_WRITEBACK	0x11222222	/* enable caches without any invalid regions */
+#define XSHAL_ALLVALID_CACHEATTR_DEFAULT	XSHAL_ALLVALID_CACHEATTR_WRITEBACK	/* default setting for caches without any invalid regions */
+
+#define XSHAL_ISS_PIPE_REGIONS	0
+#define XSHAL_ISS_SDRAM_REGIONS	0
+
+
+/*----------------------------------------------------------------------
+			XT2000 BOARD SPECIFIC ...
+  ----------------------------------------------------------------------*/
+
+#define XSHAL_XT2000_CACHEATTR_WRITEBACK	0x22FFFFFF	/* enable caches in write-back mode */
+#define XSHAL_XT2000_CACHEATTR_WRITEALLOC	0x22FFFFFF	/* enable caches in write-allocate mode */
+#define XSHAL_XT2000_CACHEATTR_WRITETHRU	0x22FFFFFF	/* enable caches in write-through mode */
+#define XSHAL_XT2000_CACHEATTR_BYPASS		0x22FFFFFF	/* disable caches in bypass mode */
+#define XSHAL_XT2000_CACHEATTR_DEFAULT		XSHAL_XT2000_CACHEATTR_WRITEBACK	/* default setting to enable caches */
+
+#define XSHAL_XT2000_PIPE_REGIONS	0x00001000	/* BusInt pipeline regions */
+#define XSHAL_XT2000_SDRAM_REGIONS	0x00000005	/* BusInt SDRAM regions */
+
+
+/*----------------------------------------------------------------------
+				VECTOR SIZES
+  ----------------------------------------------------------------------*/
+
+/*
+ *  Sizes allocated to vectors by the system (memory map) configuration.
+ *  These sizes are constrained by core configuration (eg. one vector's
+ *  code cannot overflow into another vector) but are dependent on the
+ *  system or board (or LSP) memory map configuration.
+ *
+ *  Whether or not each vector happens to be in a system ROM is also
+ *  a system configuration matter, sometimes useful, included here also:
+ */
+#define XSHAL_RESET_VECTOR_SIZE	0x000004E0
+#define XSHAL_RESET_VECTOR_ISROM	1
+#define XSHAL_USER_VECTOR_SIZE	0x0000001C
+#define XSHAL_USER_VECTOR_ISROM	0
+#define XSHAL_PROGRAMEXC_VECTOR_SIZE	XSHAL_USER_VECTOR_SIZE	/* for backward compatibility */
+#define XSHAL_USEREXC_VECTOR_SIZE	XSHAL_USER_VECTOR_SIZE	/* for backward compatibility */
+#define XSHAL_KERNEL_VECTOR_SIZE	0x0000001C
+#define XSHAL_KERNEL_VECTOR_ISROM	0
+#define XSHAL_STACKEDEXC_VECTOR_SIZE	XSHAL_KERNEL_VECTOR_SIZE	/* for backward compatibility */
+#define XSHAL_KERNELEXC_VECTOR_SIZE	XSHAL_KERNEL_VECTOR_SIZE	/* for backward compatibility */
+#define XSHAL_DOUBLEEXC_VECTOR_SIZE	0x000000E0
+#define XSHAL_DOUBLEEXC_VECTOR_ISROM	0
+#define XSHAL_WINDOW_VECTORS_SIZE	0x00000180
+#define XSHAL_WINDOW_VECTORS_ISROM	0
+#define XSHAL_INTLEVEL2_VECTOR_SIZE	0x0000000C
+#define XSHAL_INTLEVEL2_VECTOR_ISROM	0
+#define XSHAL_INTLEVEL3_VECTOR_SIZE	0x0000000C
+#define XSHAL_INTLEVEL3_VECTOR_ISROM	0
+#define XSHAL_INTLEVEL4_VECTOR_SIZE	0x0000000C
+#define XSHAL_INTLEVEL4_VECTOR_ISROM	1
+#define XSHAL_DEBUG_VECTOR_SIZE		XSHAL_INTLEVEL4_VECTOR_SIZE
+#define XSHAL_DEBUG_VECTOR_ISROM	XSHAL_INTLEVEL4_VECTOR_ISROM
+
+
+#endif /*XTENSA_CONFIG_SYSTEM_H*/
+
diff --git a/include/asm-xtensa/xtensa/config-linux_be/tie.h b/include/asm-xtensa/xtensa/config-linux_be/tie.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/xtensa/config-linux_be/tie.h
@@ -0,0 +1,275 @@
+/*
+ * xtensa/config/tie.h -- HAL definitions that are dependent on CORE and TIE configuration
+ *
+ *  This header file is sometimes referred to as the "compile-time HAL" or CHAL.
+ *  It was generated for a specific Xtensa processor configuration,
+ *  and furthermore for a specific set of TIE source files that extend
+ *  basic core functionality.
+ *
+ *  Source for configuration-independent binaries (which link in a
+ *  configuration-specific HAL library) must NEVER include this file.
+ *  It is perfectly normal, however, for the HAL source itself to include this file.
+ */
+
+/*
+ * Copyright (c) 2003 Tensilica, Inc.  All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2.1 of the GNU Lesser General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like.  Any license provided herein, whether implied or
+ * otherwise, applies only to this software file.  Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307,
+ * USA.
+ */
+
+
+#ifndef XTENSA_CONFIG_TIE_H
+#define XTENSA_CONFIG_TIE_H
+
+#include <xtensa/hal.h>
+
+
+/*----------------------------------------------------------------------
+				GENERAL
+  ----------------------------------------------------------------------*/
+
+/*
+ *  Separators for macros that expand into arrays.
+ *  These can be predefined by files that #include this one,
+ *  when different separators are required.
+ */
+/*  Element separator for macros that expand into 1-dimensional arrays:  */
+#ifndef XCHAL_SEP
+#define XCHAL_SEP			,
+#endif
+/*  Array separator for macros that expand into 2-dimensional arrays:  */
+#ifndef XCHAL_SEP2
+#define XCHAL_SEP2			},{
+#endif
+
+
+
+
+
+
+/*----------------------------------------------------------------------
+			COPROCESSORS and EXTRA STATE
+  ----------------------------------------------------------------------*/
+
+#define XCHAL_CP_NUM			0	/* number of coprocessors */
+#define XCHAL_CP_MAX			0	/* max coprocessor id plus one (0 if none) */
+#define XCHAL_CP_MASK			0x00	/* bitmask of coprocessors by id */
+
+/*  Space for coprocessors' state save areas:  */
+#define XCHAL_CP0_SA_SIZE		0
+#define XCHAL_CP1_SA_SIZE		0
+#define XCHAL_CP2_SA_SIZE		0
+#define XCHAL_CP3_SA_SIZE		0
+#define XCHAL_CP4_SA_SIZE		0
+#define XCHAL_CP5_SA_SIZE		0
+#define XCHAL_CP6_SA_SIZE		0
+#define XCHAL_CP7_SA_SIZE		0
+/*  Minimum required alignments of CP state save areas:  */
+#define XCHAL_CP0_SA_ALIGN		1
+#define XCHAL_CP1_SA_ALIGN		1
+#define XCHAL_CP2_SA_ALIGN		1
+#define XCHAL_CP3_SA_ALIGN		1
+#define XCHAL_CP4_SA_ALIGN		1
+#define XCHAL_CP5_SA_ALIGN		1
+#define XCHAL_CP6_SA_ALIGN		1
+#define XCHAL_CP7_SA_ALIGN		1
+
+/*  Indexing macros:  */
+#define _XCHAL_CP_SA_SIZE(n)		XCHAL_CP ## n ## _SA_SIZE
+#define XCHAL_CP_SA_SIZE(n)		_XCHAL_CP_SA_SIZE(n)	/* n = 0 .. 7 */
+#define _XCHAL_CP_SA_ALIGN(n)		XCHAL_CP ## n ## _SA_ALIGN
+#define XCHAL_CP_SA_ALIGN(n)		_XCHAL_CP_SA_ALIGN(n)	/* n = 0 .. 7 */
+
+
+/*  Space for "extra" state (user special registers and non-cp TIE) save area:  */
+#define XCHAL_EXTRA_SA_SIZE		0
+#define XCHAL_EXTRA_SA_ALIGN		1
+
+/*  Total save area size (extra + all coprocessors)  */
+/*  (not useful until xthal_{save,restore}_all_extra() is implemented,  */
+/*   but included for Tor2 beta; doesn't account for alignment!):  */
+#define XCHAL_CPEXTRA_SA_SIZE_TOR2	0	/* Tor2Beta temporary definition -- do not use */
+
+/*  Combined required alignment for all CP and EXTRA state save areas  */
+/*  (does not include required alignment for any base config registers):  */
+#define XCHAL_CPEXTRA_SA_ALIGN		1
+
+/* ... */
+
+
+#ifdef _ASMLANGUAGE
+/*
+ *  Assembly-language specific definitions (assembly macros, etc.).
+ */
+#include <xtensa/config/specreg.h>
+
+/********************
+ *  Macros to save and restore the non-coprocessor TIE portion of EXTRA state.
+ */
+
+/* (none) */
+
+
+/********************
+ *  Macros to create functions that save and restore all EXTRA (non-coprocessor) state
+ *  (does not include zero-overhead loop registers and non-optional registers).
+ */
+
+	/*
+	 *  Macro that expands to the body of a function that
+	 *  stores the extra (non-coprocessor) optional/custom state.
+	 *	Entry:	a2 = ptr to save area in which to save extra state
+	 *	Exit:	any register a2-a15 (?) may have been clobbered.
+	 */
+	.macro	xchal_extra_store_funcbody
+	.endm
+
+
+	/*
+	 *  Macro that expands to the body of a function that
+	 *  loads the extra (non-coprocessor) optional/custom state.
+	 *	Entry:	a2 = ptr to save area from which to restore extra state
+	 *	Exit:	any register a2-a15 (?) may have been clobbered.
+	 */
+	.macro	xchal_extra_load_funcbody
+	.endm
+
+
+/********************
+ *  Macros to save and restore the state of each TIE coprocessor.
+ */
+
+
+
+/********************
+ *  Macros to create functions that save and restore the state of *any* TIE coprocessor.
+ */
+
+	/*
+	 *  Macro that expands to the body of a function
+	 *  that stores the selected coprocessor's state (registers etc).
+	 *	Entry:	a2 = ptr to save area in which to save cp state
+	 *		a3 = coprocessor number
+	 *	Exit:	any register a2-a15 (?) may have been clobbered.
+	 */
+	.macro	xchal_cpi_store_funcbody
+	.endm
+
+
+	/*
+	 *  Macro that expands to the body of a function
+	 *  that loads the selected coprocessor's state (registers etc).
+	 *	Entry:	a2 = ptr to save area from which to restore cp state
+	 *		a3 = coprocessor number
+	 *	Exit:	any register a2-a15 (?) may have been clobbered.
+	 */
+	.macro	xchal_cpi_load_funcbody
+	.endm
+
+#endif /*_ASMLANGUAGE*/
+
+
+/*
+ *  Contents of save areas in terms of libdb register numbers.
+ *  NOTE:  CONTENTS_LIBDB_{UREG,REGF} macros are not defined in this file;
+ *  it is up to the user of this header file to define these macros
+ *  usefully before each expansion of the CONTENTS_LIBDB macros.
+ *  (Fields rsv[123] are reserved for future additions; they are currently
+ *   set to zero but may be set to some useful values in the future.)
+ *
+ *	CONTENTS_LIBDB_SREG(libdbnum, offset, size, align, rsv1, name, sregnum, bitmask, rsv2, rsv3)
+ *	CONTENTS_LIBDB_UREG(libdbnum, offset, size, align, rsv1, name, uregnum, bitmask, rsv2, rsv3)
+ *	CONTENTS_LIBDB_REGF(libdbnum, offset, size, align, rsv1, name, index, numentries, contentsize, regname_base, regfile_name, rsv2, rsv3)
+ */
+
+#define XCHAL_EXTRA_SA_CONTENTS_LIBDB_NUM	0
+#define XCHAL_EXTRA_SA_CONTENTS_LIBDB	/* empty */
+
+#define XCHAL_CP0_SA_CONTENTS_LIBDB_NUM	0
+#define XCHAL_CP0_SA_CONTENTS_LIBDB	/* empty */
+
+#define XCHAL_CP1_SA_CONTENTS_LIBDB_NUM	0
+#define XCHAL_CP1_SA_CONTENTS_LIBDB	/* empty */
+
+#define XCHAL_CP2_SA_CONTENTS_LIBDB_NUM	0
+#define XCHAL_CP2_SA_CONTENTS_LIBDB	/* empty */
+
+#define XCHAL_CP3_SA_CONTENTS_LIBDB_NUM	0
+#define XCHAL_CP3_SA_CONTENTS_LIBDB	/* empty */
+
+#define XCHAL_CP4_SA_CONTENTS_LIBDB_NUM	0
+#define XCHAL_CP4_SA_CONTENTS_LIBDB	/* empty */
+
+#define XCHAL_CP5_SA_CONTENTS_LIBDB_NUM	0
+#define XCHAL_CP5_SA_CONTENTS_LIBDB	/* empty */
+
+#define XCHAL_CP6_SA_CONTENTS_LIBDB_NUM	0
+#define XCHAL_CP6_SA_CONTENTS_LIBDB	/* empty */
+
+#define XCHAL_CP7_SA_CONTENTS_LIBDB_NUM	0
+#define XCHAL_CP7_SA_CONTENTS_LIBDB	/* empty */
+
+
+
+
+
+
+/*----------------------------------------------------------------------
+				MISC
+  ----------------------------------------------------------------------*/
+
+#if 0	/* is there something equivalent for user TIE? */
+#define XCHAL_CORE_ID			"linux_be"	/* configuration's alphanumeric core identifier
+							   (CoreID) set in the Xtensa Processor Generator */
+
+#define XCHAL_BUILD_UNIQUE_ID		0x00003256	/* software build-unique ID (22-bit) */
+
+/*  These definitions describe the hardware targeted by this software:  */
+#define XCHAL_HW_CONFIGID0		0xC103D1FF	/* config ID reg 0 value (upper 32 of 64 bits) */
+#define XCHAL_HW_CONFIGID1		0x00803256	/* config ID reg 1 value (lower 32 of 64 bits) */
+#define XCHAL_CONFIGID0			XCHAL_HW_CONFIGID0	/* for backward compatibility only -- don't use! */
+#define XCHAL_CONFIGID1			XCHAL_HW_CONFIGID1	/* for backward compatibility only -- don't use! */
+#define XCHAL_HW_RELEASE_MAJOR		1050	/* major release of targeted hardware */
+#define XCHAL_HW_RELEASE_MINOR		1	/* minor release of targeted hardware */
+#define XCHAL_HW_RELEASE_NAME		"T1050.1"	/* full release name of targeted hardware */
+#define XTHAL_HW_REL_T1050	1
+#define XTHAL_HW_REL_T1050_1	1
+#define XCHAL_HW_CONFIGID_RELIABLE	1
+#endif /*0*/
+
+
+
+/*----------------------------------------------------------------------
+				ISA
+  ----------------------------------------------------------------------*/
+
+#if 0	/* these probably don't belong here, but are related to or implemented using TIE */
+#define XCHAL_HAVE_BOOLEANS		0	/* 1 if booleans option configured, 0 otherwise */
+/*  Misc instructions:  */
+#define XCHAL_HAVE_MUL32		0	/* 1 if 32-bit integer multiply option configured, 0 otherwise */
+#define XCHAL_HAVE_MUL32_HIGH		0	/* 1 if MUL32 option includes MULUH and MULSH, 0 otherwise */
+
+#define XCHAL_HAVE_FP			0	/* 1 if floating point option configured, 0 otherwise */
+#endif /*0*/
+
+
+#endif /*XTENSA_CONFIG_TIE_H*/
+
diff --git a/include/asm-xtensa/xtensa/coreasm.h b/include/asm-xtensa/xtensa/coreasm.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/xtensa/coreasm.h
@@ -0,0 +1,526 @@
+#ifndef XTENSA_COREASM_H
+#define XTENSA_COREASM_H
+
+/*
+ * THIS FILE IS GENERATED -- DO NOT MODIFY BY HAND
+ *
+ * include/asm-xtensa/xtensa/coreasm.h -- assembler-specific
+ * definitions that depend on CORE configuration.
+ *
+ * Source for configuration-independent binaries (which link in a
+ * configuration-specific HAL library) must NEVER include this file.
+ * It is perfectly normal, however, for the HAL itself to include this
+ * file.
+ *
+ * This file must NOT include xtensa/config/system.h.  Any assembler
+ * header file that depends on system information should likely go in
+ * a new systemasm.h (or sysasm.h) header file.
+ *
+ *  NOTE: macro beqi32 is NOT configuration-dependent, and is placed
+ *        here til we will have configuration-independent header file.
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file "COPYING" in the main directory of
+ * this archive for more details.
+ *
+ * Copyright (C) 2002 Tensilica Inc.
+ */
+
+
+#include <xtensa/config/core.h>
+#include <xtensa/config/specreg.h>
+
+/*
+ *  Assembly-language specific definitions (assembly macros, etc.).
+ */
+
+/*----------------------------------------------------------------------
+ *  find_ms_setbit
+ *
+ *  This macro finds the most significant bit that is set in <as>
+ *  and return its index + <base> in <ad>, or <base> - 1 if <as> is zero.
+ *  The index counts starting at zero for the lsbit, so the return
+ *  value ranges from <base>-1 (no bit set) to <base>+31 (msbit set).
+ *
+ *  Parameters:
+ *	<ad>	destination address register (any register)
+ *	<as>	source address register
+ *	<at>	temporary address register (must be different than <as>)
+ *	<base>	constant value added to result (usually 0 or 1)
+ *  On entry:
+ *	<ad> = undefined if different than <as>
+ *	<as> = value whose most significant set bit is to be found
+ *	<at> = undefined
+ *	no other registers are used by this macro.
+ *  On exit:
+ *	<ad> = <base> + index of msbit set in original <as>,
+ *	     = <base> - 1 if original <as> was zero.
+ *	<as> clobbered (if not <ad>)
+ *	<at> clobbered (if not <ad>)
+ *  Example:
+ *	find_ms_setbit a0, a4, a0, 0		-- return in a0 index of msbit set in a4
+ */
+
+	.macro	find_ms_setbit ad, as, at, base
+#if XCHAL_HAVE_NSA
+	movi	\at, 31+\base
+	nsau	\as, \as	// get index of \as, numbered from msbit (32 if absent)
+	sub	\ad, \at, \as	// get numbering from lsbit (0..31, -1 if absent)
+#else /* XCHAL_HAVE_NSA */
+	movi	\at, \base	// start with result of 0 (point to lsbit of 32)
+
+	beqz	\as, 2f		// special case for zero argument: return -1
+	bltui	\as, 0x10000, 1f	// is it one of the 16 lsbits? (if so, check lower 16 bits)
+	addi	\at, \at, 16	// no, increment result to upper 16 bits (of 32)
+	//srli	\as, \as, 16	// check upper half (shift right 16 bits)
+	extui	\as, \as, 16, 16	// check upper half (shift right 16 bits)
+1:	bltui	\as, 0x100, 1f	// is it one of the 8 lsbits? (if so, check lower 8 bits)
+	addi	\at, \at, 8	// no, increment result to upper 8 bits (of 16)
+	srli	\as, \as, 8	// shift right to check upper 8 bits
+1:	bltui	\as, 0x10, 1f	// is it one of the 4 lsbits? (if so, check lower 4 bits)
+	addi	\at, \at, 4	// no, increment result to upper 4 bits (of 8)
+	srli	\as, \as, 4	// shift right 4 bits to check upper half
+1:	bltui	\as, 0x4, 1f	// is it one of the 2 lsbits? (if so, check lower 2 bits)
+	addi	\at, \at, 2	// no, increment result to upper 2 bits (of 4)
+	srli	\as, \as, 2	// shift right 2 bits to check upper half
+1:	bltui	\as, 0x2, 1f	// is it the lsbit?
+	addi	\at, \at, 2	// no, increment result to upper bit (of 2)
+2:	addi	\at, \at, -1	// (from just above: add 1;  from beqz: return -1)
+	//srli	\as, \as, 1
+1:				// done! \at contains index of msbit set (or -1 if none set)
+	.if	0x\ad - 0x\at	// destination different than \at ? (works because regs are a0-a15)
+	mov	\ad, \at	// then move result to \ad
+	.endif
+#endif /* XCHAL_HAVE_NSA */
+	.endm	// find_ms_setbit
+
+/*----------------------------------------------------------------------
+ *  find_ls_setbit
+ *
+ *  This macro finds the least significant bit that is set in <as>,
+ *  and return its index in <ad>.
+ *  Usage is the same as for the find_ms_setbit macro.
+ *  Example:
+ *	find_ls_setbit a0, a4, a0, 0	-- return in a0 index of lsbit set in a4
+ */
+
+	.macro	find_ls_setbit ad, as, at, base
+	neg	\at, \as	// keep only the least-significant bit that is set...
+	and	\as, \at, \as	// ... in \as
+	find_ms_setbit	\ad, \as, \at, \base
+	.endm	// find_ls_setbit
+
+/*----------------------------------------------------------------------
+ *  find_ls_one
+ *
+ *  Same as find_ls_setbit with base zero.
+ *  Source (as) and destination (ad) registers must be different.
+ *  Provided for backward compatibility.
+ */
+
+	.macro	find_ls_one ad, as
+	find_ls_setbit	\ad, \as, \ad, 0
+	.endm	// find_ls_one
+
+/*----------------------------------------------------------------------
+ *  floop, floopnez, floopgtz, floopend
+ *
+ *  These macros are used for fast inner loops that
+ *  work whether or not the Loops options is configured.
+ *  If the Loops option is configured, they simply use
+ *  the zero-overhead LOOP instructions; otherwise
+ *  they use explicit decrement and branch instructions.
+ *
+ *  They are used in pairs, with floop, floopnez or floopgtz
+ *  at the beginning of the loop, and floopend at the end.
+ *
+ *  Each pair of loop macro calls must be given the loop count
+ *  address register and a unique label for that loop.
+ *
+ *  Example:
+ *
+ *	movi	 a3, 16     // loop 16 times
+ *	floop    a3, myloop1
+ *	:
+ *	bnez     a7, end1	// exit loop if a7 != 0
+ *	:
+ *	floopend a3, myloop1
+ *  end1:
+ *
+ *  Like the LOOP instructions, these macros cannot be
+ *  nested, must include at least one instruction,
+ *  cannot call functions inside the loop, etc.
+ *  The loop can be exited by jumping to the instruction
+ *  following floopend (or elsewhere outside the loop),
+ *  or continued by jumping to a NOP instruction placed
+ *  immediately before floopend.
+ *
+ *  Unlike LOOP instructions, the register passed to floop*
+ *  cannot be used inside the loop, because it is used as
+ *  the loop counter if the Loops option is not configured.
+ *  And its value is undefined after exiting the loop.
+ *  And because the loop counter register is active inside
+ *  the loop, you can't easily use this construct to loop
+ *  across a register file using ROTW as you might with LOOP
+ *  instructions, unless you copy the loop register along.
+ */
+
+	/*  Named label version of the macros:  */
+
+	.macro	floop		ar, endlabel
+	floop_		\ar, .Lfloopstart_\endlabel, .Lfloopend_\endlabel
+	.endm
+
+	.macro	floopnez	ar, endlabel
+	floopnez_	\ar, .Lfloopstart_\endlabel, .Lfloopend_\endlabel
+	.endm
+
+	.macro	floopgtz	ar, endlabel
+	floopgtz_	\ar, .Lfloopstart_\endlabel, .Lfloopend_\endlabel
+	.endm
+
+	.macro	floopend	ar, endlabel
+	floopend_	\ar, .Lfloopstart_\endlabel, .Lfloopend_\endlabel
+	.endm
+
+	/*  Numbered local label version of the macros:  */
+#if 0 /*UNTESTED*/
+	.macro	floop89		ar
+	floop_		\ar, 8, 9f
+	.endm
+
+	.macro	floopnez89	ar
+	floopnez_	\ar, 8, 9f
+	.endm
+
+	.macro	floopgtz89	ar
+	floopgtz_	\ar, 8, 9f
+	.endm
+
+	.macro	floopend89	ar
+	floopend_	\ar, 8b, 9
+	.endm
+#endif /*0*/
+
+	/*  Underlying version of the macros:  */
+
+	.macro	floop_	ar, startlabel, endlabelref
+	.ifdef	_infloop_
+	.if	_infloop_
+	.err	// Error: floop cannot be nested
+	.endif
+	.endif
+	.set	_infloop_, 1
+#if XCHAL_HAVE_LOOPS
+	loop	\ar, \endlabelref
+#else /* XCHAL_HAVE_LOOPS */
+\startlabel:
+	addi	\ar, \ar, -1
+#endif /* XCHAL_HAVE_LOOPS */
+	.endm	// floop_
+
+	.macro	floopnez_	ar, startlabel, endlabelref
+	.ifdef	_infloop_
+	.if	_infloop_
+	.err	// Error: floopnez cannot be nested
+	.endif
+	.endif
+	.set	_infloop_, 1
+#if XCHAL_HAVE_LOOPS
+	loopnez	\ar, \endlabelref
+#else /* XCHAL_HAVE_LOOPS */
+	beqz	\ar, \endlabelref
+\startlabel:
+	addi	\ar, \ar, -1
+#endif /* XCHAL_HAVE_LOOPS */
+	.endm	// floopnez_
+
+	.macro	floopgtz_	ar, startlabel, endlabelref
+	.ifdef	_infloop_
+	.if	_infloop_
+	.err	// Error: floopgtz cannot be nested
+	.endif
+	.endif
+	.set	_infloop_, 1
+#if XCHAL_HAVE_LOOPS
+	loopgtz	\ar, \endlabelref
+#else /* XCHAL_HAVE_LOOPS */
+	bltz	\ar, \endlabelref
+	beqz	\ar, \endlabelref
+\startlabel:
+	addi	\ar, \ar, -1
+#endif /* XCHAL_HAVE_LOOPS */
+	.endm	// floopgtz_
+
+
+	.macro	floopend_	ar, startlabelref, endlabel
+	.ifndef	_infloop_
+	.err	// Error: floopend without matching floopXXX
+	.endif
+	.ifeq	_infloop_
+	.err	// Error: floopend without matching floopXXX
+	.endif
+	.set	_infloop_, 0
+#if ! XCHAL_HAVE_LOOPS
+	bnez	\ar, \startlabelref
+#endif /* XCHAL_HAVE_LOOPS */
+\endlabel:
+	.endm	// floopend_
+
+/*----------------------------------------------------------------------
+ *  crsil  --  conditional RSIL (read/set interrupt level)
+ *
+ *  Executes the RSIL instruction if it exists, else just reads PS.
+ *  The RSIL instruction does not exist in the new exception architecture
+ *  if the interrupt option is not selected.
+ */
+
+	.macro	crsil	ar, newlevel
+#if XCHAL_HAVE_OLD_EXC_ARCH || XCHAL_HAVE_INTERRUPTS
+	rsil	\ar, \newlevel
+#else
+	rsr	\ar, PS
+#endif
+	.endm	// crsil
+
+/*----------------------------------------------------------------------
+ *  window_spill{4,8,12}
+ *
+ *  These macros spill callers' register windows to the stack.
+ *  They work for both privileged and non-privileged tasks.
+ *  Must be called from a windowed ABI context, eg. within
+ *  a windowed ABI function (ie. valid stack frame, window
+ *  exceptions enabled, not in exception mode, etc).
+ *
+ *  This macro requires a single invocation of the window_spill_common
+ *  macro in the same assembly unit and section.
+ *
+ *  Note that using window_spill{4,8,12} macros is more efficient
+ *  than calling a function implemented using window_spill_function,
+ *  because the latter needs extra code to figure out the size of
+ *  the call to the spilling function.
+ *
+ *  Example usage:
+ *
+ *		.text
+ *		.align	4
+ *		.global	some_function
+ *		.type	some_function,@function
+ *	some_function:
+ *		entry	a1, 16
+ *		:
+ *		:
+ *
+ *		window_spill4	// spill windows of some_function's callers; preserves a0..a3 only;
+ *				// to use window_spill{8,12} in this example function we'd have
+ *				// to increase space allocated by the entry instruction, because
+ *				// 16 bytes only allows call4; 32 or 48 bytes (+locals) are needed
+ *				// for call8/window_spill8 or call12/window_spill12 respectively.
+ *		:
+ *
+ *		retw
+ *
+ *		window_spill_common	// instantiates code used by window_spill4
+ *
+ *
+ *  On entry:
+ *	none (if window_spill4)
+ *	stack frame has enough space allocated for call8 (if window_spill8)
+ *	stack frame has enough space allocated for call12 (if window_spill12)
+ *  On exit:
+ *	 a4..a15 clobbered (if window_spill4)
+ *	 a8..a15 clobbered (if window_spill8)
+ *	a12..a15 clobbered (if window_spill12)
+ *	no caller windows are in live registers
+ */
+
+	.macro	window_spill4
+#if XCHAL_HAVE_WINDOWED
+# if XCHAL_NUM_AREGS == 16
+	movi	a15, 0			// for 16-register files, no need to call to reach the end
+# elif XCHAL_NUM_AREGS == 32
+	call4	.L__wdwspill_assist28	// call deep enough to clear out any live callers
+# elif XCHAL_NUM_AREGS == 64
+	call4	.L__wdwspill_assist60	// call deep enough to clear out any live callers
+# endif
+#endif
+	.endm	// window_spill4
+
+	.macro	window_spill8
+#if XCHAL_HAVE_WINDOWED
+# if XCHAL_NUM_AREGS == 16
+	movi	a15, 0			// for 16-register files, no need to call to reach the end
+# elif XCHAL_NUM_AREGS == 32
+	call8	.L__wdwspill_assist24	// call deep enough to clear out any live callers
+# elif XCHAL_NUM_AREGS == 64
+	call8	.L__wdwspill_assist56	// call deep enough to clear out any live callers
+# endif
+#endif
+	.endm	// window_spill8
+
+	.macro	window_spill12
+#if XCHAL_HAVE_WINDOWED
+# if XCHAL_NUM_AREGS == 16
+	movi	a15, 0			// for 16-register files, no need to call to reach the end
+# elif XCHAL_NUM_AREGS == 32
+	call12	.L__wdwspill_assist20	// call deep enough to clear out any live callers
+# elif XCHAL_NUM_AREGS == 64
+	call12	.L__wdwspill_assist52	// call deep enough to clear out any live callers
+# endif
+#endif
+	.endm	// window_spill12
+
+/*----------------------------------------------------------------------
+ *  window_spill_function
+ *
+ *  This macro outputs a function that will spill its caller's callers'
+ *  register windows to the stack.  Eg. it could be used to implement
+ *  a version of xthal_window_spill() that works in non-privileged tasks.
+ *  This works for both privileged and non-privileged tasks.
+ *
+ *  Typical usage:
+ *
+ *		.text
+ *		.align	4
+ *		.global	my_spill_function
+ *		.type	my_spill_function,@function
+ *	my_spill_function:
+ *		window_spill_function
+ *
+ *  On entry to resulting function:
+ *	none
+ *  On exit from resulting function:
+ *	none (no caller windows are in live registers)
+ */
+
+	.macro	window_spill_function
+#if XCHAL_HAVE_WINDOWED
+# if XCHAL_NUM_AREGS == 32
+	entry	sp, 48
+	bbci.l	a0, 31, 1f		// branch if called with call4
+	bbsi.l	a0, 30, 2f		// branch if called with call12
+	call8	.L__wdwspill_assist16	// called with call8, only need another 8
+	retw
+1:	call12	.L__wdwspill_assist16	// called with call4, only need another 12
+	retw
+2:	call4	.L__wdwspill_assist16	// called with call12, only need another 4
+	retw
+# elif XCHAL_NUM_AREGS == 64
+	entry	sp, 48
+	bbci.l	a0, 31, 1f		// branch if called with call4
+	bbsi.l	a0, 30, 2f		// branch if called with call12
+	call4	.L__wdwspill_assist52	// called with call8, only need a call4
+	retw
+1:	call8	.L__wdwspill_assist52	// called with call4, only need a call8
+	retw
+2:	call12	.L__wdwspill_assist40	// called with call12, can skip a call12
+	retw
+# elif XCHAL_NUM_AREGS == 16
+	entry	sp, 16
+	bbci.l	a0, 31, 1f	// branch if called with call4
+	bbsi.l	a0, 30, 2f	// branch if called with call12
+	movi	a7, 0		// called with call8
+	retw
+1:	movi	a11, 0		// called with call4
+2:	retw			// if called with call12, everything already spilled
+
+//	movi	a15, 0		// trick to spill all but the direct caller
+//	j	1f
+//	//  The entry instruction is magical in the assembler (gets auto-aligned)
+//	//  so we have to jump to it to avoid falling through the padding.
+//	//  We need entry/retw to know where to return.
+//1:	entry	sp, 16
+//	retw
+# else
+#  error "unrecognized address register file size"
+# endif
+#endif /* XCHAL_HAVE_WINDOWED */
+	window_spill_common
+	.endm	// window_spill_function
+
+/*----------------------------------------------------------------------
+ *  window_spill_common
+ *
+ *  Common code used by any number of invocations of the window_spill##
+ *  and window_spill_function macros.
+ *
+ *  Must be instantiated exactly once within a given assembly unit,
+ *  within call/j range of and same section as window_spill##
+ *  macro invocations for that assembly unit.
+ *  (Is automatically instantiated by the window_spill_function macro.)
+ */
+
+	.macro	window_spill_common
+#if XCHAL_HAVE_WINDOWED && (XCHAL_NUM_AREGS == 32 || XCHAL_NUM_AREGS == 64)
+	.ifndef	.L__wdwspill_defined
+# if XCHAL_NUM_AREGS >= 64
+.L__wdwspill_assist60:
+	entry	sp, 32
+	call8	.L__wdwspill_assist52
+	retw
+.L__wdwspill_assist56:
+	entry	sp, 16
+	call4	.L__wdwspill_assist52
+	retw
+.L__wdwspill_assist52:
+	entry	sp, 48
+	call12	.L__wdwspill_assist40
+	retw
+.L__wdwspill_assist40:
+	entry	sp, 48
+	call12	.L__wdwspill_assist28
+	retw
+# endif
+.L__wdwspill_assist28:
+	entry	sp, 48
+	call12	.L__wdwspill_assist16
+	retw
+.L__wdwspill_assist24:
+	entry	sp, 32
+	call8	.L__wdwspill_assist16
+	retw
+.L__wdwspill_assist20:
+	entry	sp, 16
+	call4	.L__wdwspill_assist16
+	retw
+.L__wdwspill_assist16:
+	entry	sp, 16
+	movi	a15, 0
+	retw
+	.set	.L__wdwspill_defined, 1
+	.endif
+#endif /* XCHAL_HAVE_WINDOWED with 32 or 64 aregs */
+	.endm	// window_spill_common
+
+/*----------------------------------------------------------------------
+ *  beqi32
+ *
+ *  macro implements version of beqi for arbitrary 32-bit immidiate value
+ *
+ *     beqi32 ax, ay, imm32, label
+ *
+ *  Compares value in register ax with imm32 value and jumps to label if
+ *  equal. Clobberes register ay if needed
+ *
+ */
+   .macro beqi32	ax, ay, imm, label
+    .ifeq ((\imm-1) & ~7)	// 1..8 ?
+		beqi	\ax, \imm, \label
+    .else
+      .ifeq (\imm+1)		// -1 ?
+		beqi	\ax, \imm, \label
+      .else
+        .ifeq (\imm)		// 0 ?
+		beqz	\ax, \label
+        .else
+		//  We could also handle immediates 10,12,16,32,64,128,256
+		//  but it would be a long macro...
+		movi	\ay, \imm
+		beq	\ax, \ay, \label
+        .endif
+      .endif
+    .endif
+   .endm // beqi32
+
+#endif /*XTENSA_COREASM_H*/
+
diff --git a/include/asm-xtensa/xtensa/corebits.h b/include/asm-xtensa/xtensa/corebits.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/xtensa/corebits.h
@@ -0,0 +1,77 @@
+#ifndef XTENSA_COREBITS_H
+#define XTENSA_COREBITS_H
+
+/*
+ * THIS FILE IS GENERATED -- DO NOT MODIFY BY HAND
+ *
+ * xtensa/corebits.h - Xtensa Special Register field positions and masks.
+ *
+ * (In previous releases, these were defined in specreg.h, a generated file.
+ *  This file is not generated, i.e. it is processor configuration independent.)
+ */
+
+
+/*  EXCCAUSE register fields:  */
+#define EXCCAUSE_EXCCAUSE_SHIFT	0
+#define EXCCAUSE_EXCCAUSE_MASK	0x3F
+/*  Exception causes (mostly incomplete!):  */
+#define EXCCAUSE_ILLEGAL		0
+#define EXCCAUSE_SYSCALL		1
+#define EXCCAUSE_IFETCHERROR		2
+#define EXCCAUSE_LOADSTOREERROR		3
+#define EXCCAUSE_LEVEL1INTERRUPT	4
+#define EXCCAUSE_ALLOCA			5
+
+/*  PS register fields:  */
+#define PS_WOE_SHIFT		18
+#define PS_WOE_MASK		0x00040000
+#define PS_WOE			PS_WOE_MASK
+#define PS_CALLINC_SHIFT	16
+#define PS_CALLINC_MASK		0x00030000
+#define PS_CALLINC(n)		(((n)&3)<<PS_CALLINC_SHIFT)	/* n = 0..3 */
+#define PS_OWB_SHIFT		8
+#define PS_OWB_MASK		0x00000F00
+#define PS_OWB(n)		(((n)&15)<<PS_OWB_SHIFT)	/* n = 0..15 (or 0..7) */
+#define PS_RING_SHIFT		6
+#define PS_RING_MASK		0x000000C0
+#define PS_RING(n)		(((n)&3)<<PS_RING_SHIFT)	/* n = 0..3 */
+#define PS_UM_SHIFT		5
+#define PS_UM_MASK		0x00000020
+#define PS_UM			PS_UM_MASK
+#define PS_EXCM_SHIFT		4
+#define PS_EXCM_MASK		0x00000010
+#define PS_EXCM			PS_EXCM_MASK
+#define PS_INTLEVEL_SHIFT	0
+#define PS_INTLEVEL_MASK	0x0000000F
+#define PS_INTLEVEL(n)		((n)&PS_INTLEVEL_MASK)		/* n = 0..15 */
+/*  Backward compatibility (deprecated):  */
+#define PS_PROGSTACK_SHIFT	PS_UM_SHIFT
+#define PS_PROGSTACK_MASK	PS_UM_MASK
+#define PS_PROG_SHIFT		PS_UM_SHIFT
+#define PS_PROG_MASK		PS_UM_MASK
+#define PS_PROG			PS_UM
+
+/*  DBREAKCn register fields:  */
+#define DBREAKC_MASK_SHIFT		0
+#define DBREAKC_MASK_MASK		0x0000003F
+#define DBREAKC_LOADBREAK_SHIFT		30
+#define DBREAKC_LOADBREAK_MASK		0x40000000
+#define DBREAKC_STOREBREAK_SHIFT	31
+#define DBREAKC_STOREBREAK_MASK		0x80000000
+
+/*  DEBUGCAUSE register fields:  */
+#define DEBUGCAUSE_DEBUGINT_SHIFT	5
+#define DEBUGCAUSE_DEBUGINT_MASK	0x20	/* debug interrupt */
+#define DEBUGCAUSE_BREAKN_SHIFT		4
+#define DEBUGCAUSE_BREAKN_MASK		0x10	/* BREAK.N instruction */
+#define DEBUGCAUSE_BREAK_SHIFT		3
+#define DEBUGCAUSE_BREAK_MASK		0x08	/* BREAK instruction */
+#define DEBUGCAUSE_DBREAK_SHIFT		2
+#define DEBUGCAUSE_DBREAK_MASK		0x04	/* DBREAK match */
+#define DEBUGCAUSE_IBREAK_SHIFT		1
+#define DEBUGCAUSE_IBREAK_MASK		0x02	/* IBREAK match */
+#define DEBUGCAUSE_ICOUNT_SHIFT		0
+#define DEBUGCAUSE_ICOUNT_MASK		0x01	/* ICOUNT would increment to zero */
+
+#endif /*XTENSA_COREBITS_H*/
+
diff --git a/include/asm-xtensa/xtensa/hal.h b/include/asm-xtensa/xtensa/hal.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/xtensa/hal.h
@@ -0,0 +1,822 @@
+#ifndef XTENSA_HAL_H
+#define XTENSA_HAL_H
+
+/*
+ * THIS FILE IS GENERATED -- DO NOT MODIFY BY HAND
+ *
+ * include/asm-xtensa/xtensa/hal.h -- contains a definition of the
+ * Core HAL interface.
+ *
+ * All definitions in this header file are independent of any specific
+ * Xtensa processor configuration.  Thus an OS or other software can
+ * include this header file and be compiled into configuration-
+ * independent objects that can be distributed and eventually linked
+ * to the HAL library (libhal.a) to create a configuration-specific
+ * final executable.
+ *
+ * Certain definitions, however, are release-specific -- such as the
+ * XTHAL_RELEASE_xxx macros (or additions made in later releases).
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2002 Tensilica Inc.
+ */
+
+
+/*----------------------------------------------------------------------
+  			 Constant Definitions
+			(shared with assembly)
+  ----------------------------------------------------------------------*/
+
+/*  Software release information (not configuration-specific!):  */
+#define XTHAL_RELEASE_MAJOR	1050
+#define XTHAL_RELEASE_MINOR	0
+#define XTHAL_RELEASE_NAME	"T1050.0-2002-08-06-eng0"
+#define XTHAL_RELEASE_INTERNAL	"2002-08-06-eng0"
+#define XTHAL_REL_T1050	1
+#define XTHAL_REL_T1050_0	1
+#define XTHAL_REL_T1050_0_2002	1
+#define XTHAL_REL_T1050_0_2002_08	1
+#define XTHAL_REL_T1050_0_2002_08_06	1
+#define XTHAL_REL_T1050_0_2002_08_06_ENG0	1
+
+/*  HAL version numbers (these names are for backward compatibility):  */
+#define XTHAL_MAJOR_REV		XTHAL_RELEASE_MAJOR
+#define XTHAL_MINOR_REV		XTHAL_RELEASE_MINOR
+/*
+ *  A bit of software release history on values of XTHAL_{MAJOR,MINOR}_REV:
+ *
+ *	Release		MAJOR	MINOR		Comment
+ *	=======		=====	=====		=======
+ *	T1015.n		n/a	n/a		(HAL not yet available)
+ *	T1020.{0,1,2}	0	1		(HAL beta)
+ *	T1020.{3,4}	0	2		First release.
+ *	T1020.n (n>4)	0	2 or >3		(TBD)
+ *	T1030.0		0	1		(HAL beta)
+ *	T1030.{1,2}	0	3		Equivalent to first release.
+ *	T1030.n (n>=3)	0	>= 3		(TBD)
+ *	T1040.n		1040	n		Full CHAL available from T1040.2
+ *	T1050.n		1050	n		Current release.
+ *
+ *
+ *  Note:  there is a distinction between the software release with
+ *  which something is compiled (accessible using XTHAL_RELEASE_* macros)
+ *  and the software release with which the HAL library was compiled
+ *  (accessible using Xthal_release_* global variables).  This
+ *  distinction is particularly relevant for vendors that distribute
+ *  configuration-independent binaries (eg. an OS), where their customer
+ *  might link it with a HAL of a different Xtensa software release.
+ *  In this case, it may be appropriate for the OS to verify at run-time
+ *  whether XTHAL_RELEASE_* and Xthal_release_* are compatible.
+ *  [Guidelines as to which release is compatible with which are not
+ *  currently provided explicitly, but might be inferred from reading
+ *  OSKit documentation for all releases -- compatibility is also highly
+ *  dependent on which HAL features are used.  Each release is usually
+ *  backward compatible, with very few exceptions if any.]
+ *
+ *  Notes:
+ *	Tornado 2.0 supported in T1020.3+, T1030.1+, and T1040.{0,1} only.
+ *	Tornado 2.0.2 supported in T1040.2+, and T1050.
+ *	Compile-time HAL port of NucleusPlus supported by T1040.2+ and T1050.
+ */
+
+
+/*
+ *  Architectural limits, independent of configuration.
+ *  Note that these are ISA-defined limits, not micro-architecture implementation
+ *  limits enforced by the Xtensa Processor Generator (which may be stricter than
+ *  these below).
+ */
+#define XTHAL_MAX_CPS		8	/* max number of coprocessors (0..7) */
+#define XTHAL_MAX_INTERRUPTS	32	/* max number of interrupts (0..31) */
+#define XTHAL_MAX_INTLEVELS	16	/* max number of interrupt levels (0..15) */
+					/* (as of T1040, implementation limit is 7: 0..6) */
+#define XTHAL_MAX_TIMERS	4	/* max number of timers (CCOMPARE0..CCOMPARE3) */
+					/* (as of T1040, implementation limit is 3: 0..2) */
+
+/*  Misc:  */
+#define XTHAL_LITTLEENDIAN		0
+#define XTHAL_BIGENDIAN			1
+
+
+/*  Interrupt types:  */
+#define XTHAL_INTTYPE_UNCONFIGURED	0
+#define XTHAL_INTTYPE_SOFTWARE		1
+#define XTHAL_INTTYPE_EXTERN_EDGE	2
+#define XTHAL_INTTYPE_EXTERN_LEVEL	3
+#define XTHAL_INTTYPE_TIMER		4
+#define XTHAL_INTTYPE_NMI		5
+#define XTHAL_MAX_INTTYPES		6	/* number of interrupt types */
+
+/*  Timer related:  */
+#define XTHAL_TIMER_UNCONFIGURED	-1	/* Xthal_timer_interrupt[] value for non-existent timers */
+#define XTHAL_TIMER_UNASSIGNED	XTHAL_TIMER_UNCONFIGURED	/* (for backwards compatibility only) */
+
+
+/*  Access Mode bits (tentative):  */	/* bit abbr unit short_name       PPC equ - Description */
+#define XTHAL_AMB_EXCEPTION	0	/* 001 E EX fls: EXception        none    - generate exception on any access (aka "illegal") */
+#define XTHAL_AMB_HITCACHE	1	/* 002 C CH fls: use Cache on Hit ~(I CI) - use cache on hit -- way from tag match [or H HC, or U UC] (ISA: same, except for Isolate case) */
+#define XTHAL_AMB_ALLOCATE	2	/* 004 A AL fl?: ALlocate         none    - refill cache on miss -- way from LRU [or F FI fill] (ISA: Read/Write Miss Refill) */
+#define XTHAL_AMB_WRITETHRU	3	/* 008 W WT --s: WriteThrough     W WT    - store immediately to memory (ISA: same) */
+#define XTHAL_AMB_ISOLATE	4	/* 010 I IS fls: ISolate          none    - use cache regardless of hit-vs-miss -- way from vaddr (ISA: use-cache-on-miss+hit) */
+#define XTHAL_AMB_GUARD		5	/* 020 G GU ?l?: GUard            G *     - non-speculative; spec/replay refs not permitted */
+#if 0
+#define XTHAL_AMB_ORDERED	x	/* 000 O OR fls: ORdered          G *     - mem accesses cannot be out of order */
+#define XTHAL_AMB_FUSEWRITES	x	/* 000 F FW --s: FuseWrites       none    - allow combining/merging multiple writes (to same datapath data unit) into one (implied by writeback) */
+#define XTHAL_AMB_COHERENT	x	/* 000 M MC fl?: Mem/MP Coherent  M       - on reads, other CPUs/bus-masters may need to supply data */
+#define XTHAL_AMB_TRUSTED	x	/* 000 T TR ?l?: TRusted          none    - memory will not bus error (if it does, handle as fatal imprecise interrupt) */
+#define XTHAL_AMB_PREFETCH	x	/* 000 P PR fl?: PRefetch         none    - on refill, read line+1 into prefetch buffers */
+#define XTHAL_AMB_STREAM	x	/* 000 S ST ???: STreaming        none    - access one of N stream buffers */
+#endif /*0*/
+
+#define XTHAL_AM_EXCEPTION	(1<<XTHAL_AMB_EXCEPTION)
+#define XTHAL_AM_HITCACHE	(1<<XTHAL_AMB_HITCACHE)
+#define XTHAL_AM_ALLOCATE	(1<<XTHAL_AMB_ALLOCATE)
+#define XTHAL_AM_WRITETHRU	(1<<XTHAL_AMB_WRITETHRU)
+#define XTHAL_AM_ISOLATE	(1<<XTHAL_AMB_ISOLATE)
+#define XTHAL_AM_GUARD		(1<<XTHAL_AMB_GUARD)
+#if 0
+#define XTHAL_AM_ORDERED	(1<<XTHAL_AMB_ORDERED)
+#define XTHAL_AM_FUSEWRITES	(1<<XTHAL_AMB_FUSEWRITES)
+#define XTHAL_AM_COHERENT	(1<<XTHAL_AMB_COHERENT)
+#define XTHAL_AM_TRUSTED	(1<<XTHAL_AMB_TRUSTED)
+#define XTHAL_AM_PREFETCH	(1<<XTHAL_AMB_PREFETCH)
+#define XTHAL_AM_STREAM		(1<<XTHAL_AMB_STREAM)
+#endif /*0*/
+
+/*
+ *  Allowed Access Modes (bit combinations).
+ *
+ *  Columns are:
+ *  "FOGIWACE"
+ *	Access mode bits (see XTHAL_AMB_xxx above).
+ *	<letter> = bit is set
+ *	'-'      = bit is clear
+ *	'.'      = bit is irrelevant / don't care, as follows:
+ *			E=1 makes all others irrelevant
+ *			W,F relevant only for stores
+ *  "2345"
+ *	Indicates which Xtensa releases support the corresponding
+ *	access mode.  Releases for each character column are:
+ *		2 = prior to T1020.2:   T1015 (V1.5), T1020.0, T1020.1
+ *		3 = T1020.2 and later:  T1020.2+, T1030
+ *		4 = T1040
+ *		5 = T1050 (maybe)
+ *	And the character column contents are:
+ *		<number> = support by release(s)
+ *		"." = unsupported by release(s)
+ *		"?" = support unknown
+ */
+					/* FOGIWACE 2345 */
+/*  For instruction fetch:  */
+#define XTHAL_FAM_EXCEPTION	0x001	/* .......E 2345 exception */
+#define XTHAL_FAM_ISOLATE	0x012	/* .--I.-C- .... isolate */
+#define XTHAL_FAM_BYPASS	0x000	/* .---.--- 2345 bypass */
+#define XTHAL_FAM_NACACHED	0x002	/* .---.-C- .... cached no-allocate (frozen) */
+#define XTHAL_FAM_CACHED	0x006	/* .---.AC- 2345 cached */
+/*  For data load:  */
+#define XTHAL_LAM_EXCEPTION	0x001	/* .......E 2345 exception */
+#define XTHAL_LAM_ISOLATE	0x012	/* .--I.-C- 2345 isolate */
+#define XTHAL_LAM_BYPASS	0x000	/* .O--.--- 2... bypass speculative */
+#define XTHAL_LAM_BYPASSG	0x020	/* .OG-.--- .345 bypass guarded */
+#define XTHAL_LAM_NACACHED	0x002	/* .O--.-C- 2... cached no-allocate speculative */
+#define XTHAL_LAM_NACACHEDG	0x022	/* .OG-.-C- .345 cached no-allocate guarded */
+#define XTHAL_LAM_CACHED	0x006	/* .---.AC- 2345 cached speculative */
+#define XTHAL_LAM_CACHEDG	0x026	/* .?G-.AC- .... cached guarded */
+/*  For data store:  */
+#define XTHAL_SAM_EXCEPTION	0x001	/* .......E 2345 exception */
+#define XTHAL_SAM_ISOLATE	0x032	/* .-GI--C- 2345 isolate */
+#define XTHAL_SAM_BYPASS	0x028	/* -OG-W--- 2345 bypass */
+/*efine XTHAL_SAM_BYPASSF	0x028*/	/* F-G-W--- ...? bypass write-combined */
+#define XTHAL_SAM_WRITETHRU	0x02A	/* -OG-W-C- 234? writethrough */
+/*efine XTHAL_SAM_WRITETHRUF	0x02A*/	/* F-G-W-C- ...5 writethrough write-combined */
+#define XTHAL_SAM_WRITEALLOC	0x02E	/* -OG-WAC- ...? writethrough-allocate */
+/*efine XTHAL_SAM_WRITEALLOCF	0x02E*/	/* F-G-WAC- ...? writethrough-allocate write-combined */
+#define XTHAL_SAM_WRITEBACK	0x026	/* F-G--AC- ...5 writeback */
+
+#if 0
+/*
+    Cache attribute encoding for CACHEATTR (per ISA):
+    (Note:  if this differs from ISA Ref Manual, ISA has precedence)
+
+	Inst-fetches	Loads		Stores
+	-------------	------------	-------------
+0x0	FCA_EXCEPTION  ?LCA_NACACHED_G*	SCA_WRITETHRU	"uncached"
+0x1	FCA_CACHED	LCA_CACHED	SCA_WRITETHRU	cached
+0x2	FCA_BYPASS	LCA_BYPASS_G*	SCA_BYPASS	bypass
+0x3	FCA_CACHED	LCA_CACHED	SCA_WRITEALLOCF	write-allocate
+		     or LCA_EXCEPTION	SCA_EXCEPTION	(if unimplemented)
+0x4	FCA_CACHED	LCA_CACHED	SCA_WRITEBACK	write-back
+		     or LCA_EXCEPTION	SCA_EXCEPTION	(if unimplemented)
+0x5..D	FCA_EXCEPTION	LCA_EXCEPTION	SCA_EXCEPTION	(reserved)
+0xE	FCA_EXCEPTION	LCA_ISOLATE	SCA_ISOLATE	isolate
+0xF	FCA_EXCEPTION	LCA_EXCEPTION	SCA_EXCEPTION	illegal
+     *  Prior to T1020.2?, guard feature not supported, this defaulted to speculative (no _G)
+*/
+#endif /*0*/
+
+
+#if !defined(__ASSEMBLY__) && !defined(_NOCLANGUAGE)
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*----------------------------------------------------------------------
+  			     HAL
+  ----------------------------------------------------------------------*/
+
+/* Constant to be checked in build = (XTHAL_MAJOR_REV<<16)|XTHAL_MINOR_REV */
+extern const unsigned int Xthal_rev_no;
+
+
+/*----------------------------------------------------------------------
+  			Processor State
+  ----------------------------------------------------------------------*/
+/* save & restore the extra processor state */
+extern void xthal_save_extra(void *base);
+extern void xthal_restore_extra(void *base);
+
+extern void xthal_save_cpregs(void *base, int);
+extern void xthal_restore_cpregs(void *base, int);
+
+/*extern void xthal_save_all_extra(void *base);*/
+/*extern void xthal_restore_all_extra(void *base);*/
+
+/* space for processor state */
+extern const unsigned int Xthal_extra_size;
+extern const unsigned int Xthal_extra_align;
+/* space for TIE register files */
+extern const unsigned int Xthal_cpregs_size[XTHAL_MAX_CPS];
+extern const unsigned int Xthal_cpregs_align[XTHAL_MAX_CPS];
+
+/* total of space for the processor state (for Tor2) */
+extern const unsigned int Xthal_all_extra_size;
+extern const unsigned int Xthal_all_extra_align;
+
+/* initialize the extra processor */
+/*extern void xthal_init_extra(void);*/
+/* initialize the TIE coprocessor */
+/*extern void xthal_init_cp(int);*/
+
+/* initialize the extra processor */
+extern void xthal_init_mem_extra(void *);
+/* initialize the TIE coprocessor */
+extern void xthal_init_mem_cp(void *, int);
+
+/* validate & invalidate the TIE register file */
+extern void xthal_validate_cp(int);
+extern void xthal_invalidate_cp(int);
+
+/* the number of TIE coprocessors contiguous from zero (for Tor2) */
+extern const unsigned int Xthal_num_coprocessors;
+
+/* actual number of coprocessors */
+extern const unsigned char Xthal_cp_num;
+/* index of highest numbered coprocessor, plus one */
+extern const unsigned char Xthal_cp_max;
+/* index of highest allowed coprocessor number, per cfg, plus one */
+/*extern const unsigned char Xthal_cp_maxcfg;*/
+/* bitmask of which coprocessors are present */
+extern const unsigned int  Xthal_cp_mask;
+
+/* read and write cpenable register */
+extern void xthal_set_cpenable(unsigned);
+extern unsigned xthal_get_cpenable(void);
+
+/* read & write extra state register */
+/*extern int xthal_read_extra(void *base, unsigned reg, unsigned *value);*/
+/*extern int xthal_write_extra(void *base, unsigned reg, unsigned value);*/
+
+/* read & write a TIE coprocessor register */
+/*extern int xthal_read_cpreg(void *base, int cp, unsigned reg, unsigned *value);*/
+/*extern int xthal_write_cpreg(void *base, int cp, unsigned reg, unsigned value);*/
+
+/* return coprocessor number based on register */
+/*extern int xthal_which_cp(unsigned reg);*/
+
+/*----------------------------------------------------------------------
+   				Interrupts
+  ----------------------------------------------------------------------*/
+
+/* the number of interrupt levels */
+extern const unsigned char Xthal_num_intlevels;
+/* the number of interrupts */
+extern const unsigned char Xthal_num_interrupts;
+
+/* mask for level of interrupts */
+extern const unsigned int Xthal_intlevel_mask[XTHAL_MAX_INTLEVELS];
+/* mask for level 0 to N interrupts */
+extern const unsigned int Xthal_intlevel_andbelow_mask[XTHAL_MAX_INTLEVELS];
+
+/* level of each interrupt */
+extern const unsigned char Xthal_intlevel[XTHAL_MAX_INTERRUPTS];
+
+/* type per interrupt */
+extern const unsigned char Xthal_inttype[XTHAL_MAX_INTERRUPTS];
+
+/* masks of each type of interrupt */
+extern const unsigned int Xthal_inttype_mask[XTHAL_MAX_INTTYPES];
+
+/* interrupt numbers assigned to each timer interrupt */
+extern const int Xthal_timer_interrupt[XTHAL_MAX_TIMERS];
+
+/***  Virtual interrupt prioritization:  ***/
+
+/*  Convert between interrupt levels (as per PS.INTLEVEL) and virtual interrupt priorities:  */
+extern unsigned	xthal_vpri_to_intlevel(unsigned vpri);
+extern unsigned	xthal_intlevel_to_vpri(unsigned intlevel);
+
+/*  Enables/disables given set (mask) of interrupts; returns previous enabled-mask of all ints:  */
+extern unsigned	xthal_int_enable(unsigned);
+extern unsigned	xthal_int_disable(unsigned);
+
+/*  Set/get virtual priority of an interrupt:  */
+extern int	xthal_set_int_vpri(int intnum, int vpri);
+extern int	xthal_get_int_vpri(int intnum);
+
+/*  Set/get interrupt lockout level for exclusive access to virtual priority data structures:  */
+extern void	xthal_set_vpri_locklevel(unsigned intlevel);
+extern unsigned	xthal_get_vpri_locklevel(void);
+
+/*  Set/get current virtual interrupt priority:  */
+extern unsigned	xthal_set_vpri(unsigned vpri);
+extern unsigned	xthal_get_vpri(unsigned vpri);
+extern unsigned	xthal_set_vpri_intlevel(unsigned intlevel);
+extern unsigned	xthal_set_vpri_lock(void);
+
+
+
+/*----------------------------------------------------------------------
+   			Generic Interrupt Trampolining Support
+  ----------------------------------------------------------------------*/
+
+typedef void (XtHalVoidFunc)(void);
+
+/*
+ *  Bitmask of interrupts currently trampolining down:
+ */
+extern unsigned Xthal_tram_pending;
+
+/*
+ *  Bitmask of which interrupts currently trampolining down
+ *  synchronously are actually enabled; this bitmask is necessary
+ *  because INTENABLE cannot hold that state (sync-trampolining
+ *  interrupts must be kept disabled while trampolining);
+ *  in the current implementation, any bit set here is not set
+ *  in INTENABLE, and vice-versa; once a sync-trampoline is
+ *  handled (at level one), its enable bit must be moved from
+ *  here to INTENABLE:
+ */
+extern unsigned Xthal_tram_enabled;
+
+/*
+ *  Bitmask of interrupts configured for sync trampolining:
+ */
+extern unsigned Xthal_tram_sync;
+
+
+/*  Trampoline support functions:  */
+extern unsigned  xthal_tram_pending_to_service( void );
+extern void      xthal_tram_done( unsigned serviced_mask );
+extern int       xthal_tram_set_sync( int intnum, int sync );
+extern XtHalVoidFunc* xthal_set_tram_trigger_func( XtHalVoidFunc *trigger_fn );
+
+/*  INTENABLE,INTREAD,INTSET,INTCLEAR register access functions:  */
+extern unsigned  xthal_get_intenable( void );
+extern void      xthal_set_intenable( unsigned );
+extern unsigned  xthal_get_intread( void );
+extern void      xthal_set_intset( unsigned );
+extern void      xthal_set_intclear( unsigned );
+
+
+/*----------------------------------------------------------------------
+   				Register Windows
+  ----------------------------------------------------------------------*/
+
+/* number of registers in register window */
+extern const unsigned int  Xthal_num_aregs;
+extern const unsigned char Xthal_num_aregs_log2;
+
+/*  This spill any live register windows (other than the caller's):  */
+extern void      xthal_window_spill( void );
+
+
+/*----------------------------------------------------------------------
+   				Cache
+  ----------------------------------------------------------------------*/
+
+/* size of the cache lines in log2(bytes) */
+extern const unsigned char Xthal_icache_linewidth;
+extern const unsigned char Xthal_dcache_linewidth;
+/* size of the cache lines in bytes */
+extern const unsigned short Xthal_icache_linesize;
+extern const unsigned short Xthal_dcache_linesize;
+/* number of cache sets in log2(lines per way) */
+extern const unsigned char Xthal_icache_setwidth;
+extern const unsigned char Xthal_dcache_setwidth;
+/* cache set associativity (number of ways) */
+extern const unsigned int  Xthal_icache_ways;
+extern const unsigned int  Xthal_dcache_ways;
+/* size of the caches in bytes (ways * 2^(linewidth + setwidth)) */
+extern const unsigned int  Xthal_icache_size;
+extern const unsigned int  Xthal_dcache_size;
+/* cache features */
+extern const unsigned char Xthal_dcache_is_writeback;
+extern const unsigned char Xthal_icache_line_lockable;
+extern const unsigned char Xthal_dcache_line_lockable;
+
+/* cache attribute register control (used by other HAL routines) */
+extern unsigned xthal_get_cacheattr( void );
+extern unsigned xthal_get_icacheattr( void );
+extern unsigned xthal_get_dcacheattr( void );
+extern void     xthal_set_cacheattr( unsigned );
+extern void     xthal_set_icacheattr( unsigned );
+extern void     xthal_set_dcacheattr( unsigned );
+
+/* initialize cache support (must be called once at startup, before all other cache calls) */
+/*extern void xthal_cache_startinit( void );*/
+/* reset caches */
+/*extern void xthal_icache_reset( void );*/
+/*extern void xthal_dcache_reset( void );*/
+/* enable caches */
+extern void xthal_icache_enable( void );	/* DEPRECATED */
+extern void xthal_dcache_enable( void );	/* DEPRECATED */
+/* disable caches */
+extern void xthal_icache_disable( void );	/* DEPRECATED */
+extern void xthal_dcache_disable( void );	/* DEPRECATED */
+
+/* invalidate the caches */
+extern void xthal_icache_all_invalidate( void );
+extern void xthal_dcache_all_invalidate( void );
+extern void xthal_icache_region_invalidate( void *addr, unsigned size );
+extern void xthal_dcache_region_invalidate( void *addr, unsigned size );
+extern void xthal_icache_line_invalidate(void *addr);
+extern void xthal_dcache_line_invalidate(void *addr);
+/* write dirty data back */
+extern void xthal_dcache_all_writeback( void );
+extern void xthal_dcache_region_writeback( void *addr, unsigned size );
+extern void xthal_dcache_line_writeback(void *addr);
+/* write dirty data back and invalidate */
+extern void xthal_dcache_all_writeback_inv( void );
+extern void xthal_dcache_region_writeback_inv( void *addr, unsigned size );
+extern void xthal_dcache_line_writeback_inv(void *addr);
+/* prefetch and lock specified memory range into cache */
+extern void xthal_icache_region_lock( void *addr, unsigned size );
+extern void xthal_dcache_region_lock( void *addr, unsigned size );
+extern void xthal_icache_line_lock(void *addr);
+extern void xthal_dcache_line_lock(void *addr);
+/* unlock from cache */
+extern void xthal_icache_all_unlock( void );
+extern void xthal_dcache_all_unlock( void );
+extern void xthal_icache_region_unlock( void *addr, unsigned size );
+extern void xthal_dcache_region_unlock( void *addr, unsigned size );
+extern void xthal_icache_line_unlock(void *addr);
+extern void xthal_dcache_line_unlock(void *addr);
+
+
+/* sync icache and memory */
+extern void xthal_icache_sync( void );
+/* sync dcache and memory */
+extern void xthal_dcache_sync( void );
+
+/*----------------------------------------------------------------------
+   				Debug
+  ----------------------------------------------------------------------*/
+
+/*  1 if debug option configured, 0 if not:  */
+extern const int Xthal_debug_configured;
+
+/*  Number of instruction and data break registers:  */
+extern const int Xthal_num_ibreak;
+extern const int Xthal_num_dbreak;
+
+/*  Set (plant) and remove software breakpoint, both synchronizing cache:  */
+extern unsigned int xthal_set_soft_break(void *addr);
+extern void         xthal_remove_soft_break(void *addr, unsigned int);
+
+
+/*----------------------------------------------------------------------
+   				Disassembler
+  ----------------------------------------------------------------------*/
+
+/*  Max expected size of the return buffer for a disassembled instruction (hint only):  */
+#define XTHAL_DISASM_BUFSIZE	80
+
+/*  Disassembly option bits for selecting what to return:  */
+#define XTHAL_DISASM_OPT_ADDR	0x0001	/* display address */
+#define XTHAL_DISASM_OPT_OPHEX	0x0002	/* display opcode bytes in hex */
+#define XTHAL_DISASM_OPT_OPCODE	0x0004	/* display opcode name (mnemonic) */
+#define XTHAL_DISASM_OPT_PARMS	0x0008	/* display parameters */
+#define XTHAL_DISASM_OPT_ALL	0x0FFF	/* display everything */
+
+/* routine to get a string for the disassembled instruction */
+extern int xthal_disassemble( unsigned char *instr_buf, void *tgt_addr,
+		       char *buffer, unsigned buflen, unsigned options );
+
+/* routine to get the size of the next instruction. Returns 0 for
+   illegal instruction */
+extern int xthal_disassemble_size( unsigned char *instr_buf );
+
+
+/*----------------------------------------------------------------------
+   				Core Counter
+  ----------------------------------------------------------------------*/
+
+/* counter info */
+extern const unsigned char Xthal_have_ccount;	/* set if CCOUNT register present */
+extern const unsigned char Xthal_num_ccompare;	/* number of CCOMPAREn registers */
+
+/* get CCOUNT register (if not present return 0) */
+extern unsigned xthal_get_ccount(void);
+
+/* set and get CCOMPAREn registers (if not present, get returns 0) */
+extern void     xthal_set_ccompare(int, unsigned);
+extern unsigned xthal_get_ccompare(int);
+
+
+/*----------------------------------------------------------------------
+			Instruction/Data RAM/ROM Access
+  ----------------------------------------------------------------------*/
+
+extern void* xthal_memcpy(void *dst, const void *src, unsigned len);
+extern void* xthal_bcopy(const void *src, void *dst, unsigned len);
+
+/*----------------------------------------------------------------------
+                           MP Synchronization
+  ----------------------------------------------------------------------*/
+extern int      xthal_compare_and_set( int *addr, int test_val, int compare_val );
+extern unsigned xthal_get_prid( void );
+
+/*extern const char  Xthal_have_s32c1i;*/
+extern const unsigned char Xthal_have_prid;
+
+
+/*----------------------------------------------------------------------
+                             Miscellaneous
+  ----------------------------------------------------------------------*/
+
+extern const unsigned int  Xthal_release_major;
+extern const unsigned int  Xthal_release_minor;
+extern const char * const  Xthal_release_name;
+extern const char * const  Xthal_release_internal;
+
+extern const unsigned char Xthal_memory_order;
+extern const unsigned char Xthal_have_windowed;
+extern const unsigned char Xthal_have_density;
+extern const unsigned char Xthal_have_booleans;
+extern const unsigned char Xthal_have_loops;
+extern const unsigned char Xthal_have_nsa;
+extern const unsigned char Xthal_have_minmax;
+extern const unsigned char Xthal_have_sext;
+extern const unsigned char Xthal_have_clamps;
+extern const unsigned char Xthal_have_mac16;
+extern const unsigned char Xthal_have_mul16;
+extern const unsigned char Xthal_have_fp;
+extern const unsigned char Xthal_have_speculation;
+extern const unsigned char Xthal_have_exceptions;
+extern const unsigned char Xthal_xea_version;
+extern const unsigned char Xthal_have_interrupts;
+extern const unsigned char Xthal_have_highlevel_interrupts;
+extern const unsigned char Xthal_have_nmi;
+
+extern const unsigned short Xthal_num_writebuffer_entries;
+
+extern const unsigned int  Xthal_build_unique_id;
+/*  Release info for hardware targeted by software upgrades:  */
+extern const unsigned int  Xthal_hw_configid0;
+extern const unsigned int  Xthal_hw_configid1;
+extern const unsigned int  Xthal_hw_release_major;
+extern const unsigned int  Xthal_hw_release_minor;
+extern const char * const  Xthal_hw_release_name;
+extern const char * const  Xthal_hw_release_internal;
+
+
+/*  Internal memories...  */
+
+extern const unsigned char Xthal_num_instrom;
+extern const unsigned char Xthal_num_instram;
+extern const unsigned char Xthal_num_datarom;
+extern const unsigned char Xthal_num_dataram;
+extern const unsigned char Xthal_num_xlmi;
+extern const unsigned int  Xthal_instrom_vaddr[1];
+extern const unsigned int  Xthal_instrom_paddr[1];
+extern const unsigned int  Xthal_instrom_size [1];
+extern const unsigned int  Xthal_instram_vaddr[1];
+extern const unsigned int  Xthal_instram_paddr[1];
+extern const unsigned int  Xthal_instram_size [1];
+extern const unsigned int  Xthal_datarom_vaddr[1];
+extern const unsigned int  Xthal_datarom_paddr[1];
+extern const unsigned int  Xthal_datarom_size [1];
+extern const unsigned int  Xthal_dataram_vaddr[1];
+extern const unsigned int  Xthal_dataram_paddr[1];
+extern const unsigned int  Xthal_dataram_size [1];
+extern const unsigned int  Xthal_xlmi_vaddr[1];
+extern const unsigned int  Xthal_xlmi_paddr[1];
+extern const unsigned int  Xthal_xlmi_size [1];
+
+
+
+/*----------------------------------------------------------------------
+                         Memory Management Unit
+  ----------------------------------------------------------------------*/
+
+extern const unsigned char Xthal_have_spanning_way;
+extern const unsigned char Xthal_have_identity_map;
+extern const unsigned char Xthal_have_mimic_cacheattr;
+extern const unsigned char Xthal_have_xlt_cacheattr;
+extern const unsigned char Xthal_have_cacheattr;
+extern const unsigned char Xthal_have_tlbs;
+
+extern const unsigned char Xthal_mmu_asid_bits;		/* 0 .. 8 */
+extern const unsigned char Xthal_mmu_asid_kernel;
+extern const unsigned char Xthal_mmu_rings;		/* 1 .. 4 (perhaps 0 if no MMU and/or no protection?) */
+extern const unsigned char Xthal_mmu_ring_bits;
+extern const unsigned char Xthal_mmu_sr_bits;
+extern const unsigned char Xthal_mmu_ca_bits;
+extern const unsigned int  Xthal_mmu_max_pte_page_size;
+extern const unsigned int  Xthal_mmu_min_pte_page_size;
+
+extern const unsigned char Xthal_itlb_way_bits;
+extern const unsigned char Xthal_itlb_ways;
+extern const unsigned char Xthal_itlb_arf_ways;
+extern const unsigned char Xthal_dtlb_way_bits;
+extern const unsigned char Xthal_dtlb_ways;
+extern const unsigned char Xthal_dtlb_arf_ways;
+
+/*  Convert between virtual and physical addresses (through static maps only):  */
+/*** WARNING: these two functions may go away in a future release; don't depend on them! ***/
+extern int  xthal_static_v2p( unsigned vaddr, unsigned *paddrp );
+extern int  xthal_static_p2v( unsigned paddr, unsigned *vaddrp, unsigned cached );
+
+#if 0
+/*******************   EXPERIMENTAL AND TENTATIVE ONLY   ********************/
+
+#define XTHAL_MMU_PAGESZ_COUNT_MAX	8	/* maximum number of different page sizes */
+extern const char	Xthal_mmu_pagesz_count;		/* 0 .. 8		number of different page sizes configured */
+
+/*  Note:  the following table doesn't necessarily have page sizes in increasing order: */
+extern const char	Xthal_mmu_pagesz_log2[XTHAL_MMU_PAGESZ_COUNT_MAX];	/* 10 .. 28 (0 past count) */
+
+/*  Sorted (increasing) table of page sizes, that indexes into the above table: */
+extern const char	Xthal_mmu_pagesz_sorted[XTHAL_MMU_PAGESZ_COUNT_MAX];	/* 0 .. 7 (0 past count) */
+
+/*u32	Xthal_virtual_exceptions;*/	/* bitmask of which exceptions execute in virtual mode... */
+
+extern const char	Xthal_mmu_pte_pagesz_log2_min;	/* ?? minimum page size in PTEs */
+extern const char	Xthal_mmu_pte_pagesz_log2_max;	/* ?? maximum page size in PTEs */
+
+/*  Cache Attribute Bits Implemented by the Cache (part of the cache abstraction) */
+extern const char	Xthal_icache_fca_bits_implemented;	/* ITLB/UTLB only! */
+extern const char	Xthal_dcache_lca_bits_implemented;	/* DTLB/UTLB only! */
+extern const char	Xthal_dcache_sca_bits_implemented; 	/* DTLB/UTLB only! */
+
+/*  Per TLB Parameters (Instruction, Data, Unified)  */
+struct XtHalMmuTlb	Xthal_itlb;	/* description of MMU I-TLB generic features */
+struct XtHalMmuTlb	Xthal_dtlb;	/* description of MMU D-TLB generic features */
+struct XtHalMmuTlb	Xthal_utlb;	/* description of MMU U-TLB generic features */
+
+#define XTHAL_MMU_WAYS_MAX	8	/* maximum number of ways (associativities) for each TLB */
+
+/*  Structure for common information described for each possible TLB (instruction, data and unified): */
+typedef struct XtHalMmuTlb {
+    u8  	va_bits;		/* 32		(number of virtual address bits) */
+    u8  	pa_bits;		/* 32		(number of physical address bits) */
+    bool	tlb_va_indexed;		/* 1	(set if TLB is indexed by virtual address) */
+    bool	tlb_va_tagged;		/* 0	(set if TLB is tagged by virtual address) */
+    bool	cache_va_indexed;	/* 1	(set if cache is indexed by virtual address) */
+    bool	cache_va_tagged;	/* 0	(set if cache is tagged by virtual address) */
+    /*bool	(whether page tables are traversed in vaddr sorted order, paddr sorted order, ...) */
+    /*u8	(set of available page attribute bits, other than cache attribute bits defined above) */
+    /*u32	(various masks for pages, MMU table/TLB entries, etc.) */
+    u8  	way_count;		/* 0 .. 8	(number of ways, a.k.a. associativities, for this TLB) */
+    XtHalMmuTlbWay *	ways[XTHAL_MMU_WAYS_MAX];	/* pointers to per-way parms for each way */
+} XtHalMmuTlb;
+
+/*  Per TLB Way (Per Associativity) Parameters  */
+typedef struct XtHalMmuTlbWay {
+     u32	index_count_log2;	/* 0 .. 4 */
+     u32	pagesz_mask;		/* 0 .. 2^pagesz_count - 1	(each bit corresponds to a size */
+					/*		defined in the Xthal_mmu_pagesz_log2[] table) */
+     u32	vpn_const_mask;
+     u32	vpn_const_value;
+     u64	ppn_const_mask;		/* future may support pa_bits > 32 */
+     u64	ppn_const_value;
+     u32	ppn_id_mask;		/* paddr bits taken directly from vaddr */
+     bool	backgnd_match;		/* 0 or 1 */
+     /*  These are defined in terms of the XTHAL_CACHE_xxx bits: */
+     u8 	fca_const_mask;		/* ITLB/UTLB only! */
+     u8 	fca_const_value;	/* ITLB/UTLB only! */
+     u8 	lca_const_mask;		/* DTLB/UTLB only! */
+     u8 	lca_const_value; 	/* DTLB/UTLB only! */
+     u8 	sca_const_mask; 	/* DTLB/UTLB only! */
+     u8 	sca_const_value; 	/* DTLB/UTLB only! */
+     /*  These define an encoding that map 5 bits in TLB and PTE entries to */
+     /*  8 bits (FCA, ITLB), 16 bits (LCA+SCA, DTLB) or 24 bits (FCA+LCA+SCA, UTLB): */
+     /*  (they may be moved to struct XtHalMmuTlb) */
+     u8		ca_bits;		/* number of bits in TLB/PTE entries for cache attributes */
+     u32 *	ca_map;			/* pointer to array of 2^ca_bits entries of FCA+LCA+SCA bits */
+} XtHalMmuTlbWay;
+
+/*
+ *  The way to determine whether protection support is present in core
+ *  is to [look at Xthal_mmu_rings ???].
+ *  Give info on memory requirements for MMU tables and other in-memory
+ *  data structures (globally, per task, base and per page, etc.) - whatever bounds can be calculated.
+ */
+
+
+/*  Default vectors:  */
+xthal_immu_fetch_miss_vector
+xthal_dmmu_load_miss_vector
+xthal_dmmu_store_miss_vector
+
+/*  Functions called when a fault is detected:  */
+typedef void (XtHalMmuFaultFunc)( unsigned vaddr, ...context... );
+/*  Or, */
+/*	a? = vaddr */
+/*	a? = context... */
+/*	PS.xxx = xxx */
+XtHalMMuFaultFunc *Xthal_immu_fetch_fault_func;
+XtHalMMuFaultFunc *Xthal_dmmu_load_fault_func;
+XtHalMMuFaultFunc *Xthal_dmmu_store_fault_func;
+
+/*  Default Handlers:  */
+/*  The user and/or kernel exception handlers may jump to these handlers to handle the relevant exceptions,
+ *  according to the value of EXCCAUSE.  The exact register state on entry to these handlers is TBD.  */
+/*  When multiple TLB entries match (hit) on the same access:  */
+xthal_immu_fetch_multihit_handler
+xthal_dmmu_load_multihit_handler
+xthal_dmmu_store_multihit_handler
+/*  Protection violations according to cache attributes, and other cache attribute mismatches:  */
+xthal_immu_fetch_attr_handler
+xthal_dmmu_load_attr_handler
+xthal_dmmu_store_attr_handler
+/*  Protection violations due to insufficient ring level:  */
+xthal_immu_fetch_priv_handler
+xthal_dmmu_load_priv_handler
+xthal_dmmu_store_priv_handler
+/*  Alignment exception handlers (if supported by the particular Xtensa MMU configuration):  */
+xthal_dmmu_load_align_handler
+xthal_dmmu_store_align_handler
+
+/*  Or, alternatively, the OS user and/or kernel exception handlers may simply jump to the
+ *  following entry points which will handle any values of EXCCAUSE not handled by the OS:  */
+xthal_user_exc_default_handler
+xthal_kernel_exc_default_handler
+
+#endif /*0*/
+
+#ifdef INCLUDE_DEPRECATED_HAL_CODE
+extern const unsigned char Xthal_have_old_exc_arch;
+extern const unsigned char Xthal_have_mmu;
+extern const unsigned int  Xthal_num_regs;
+extern const unsigned char Xthal_num_iroms;
+extern const unsigned char Xthal_num_irams;
+extern const unsigned char Xthal_num_droms;
+extern const unsigned char Xthal_num_drams;
+extern const unsigned int  Xthal_configid0;
+extern const unsigned int  Xthal_configid1;
+#endif
+
+#ifdef INCLUDE_DEPRECATED_HAL_DEBUG_CODE
+#define XTHAL_24_BIT_BREAK		0x80000000
+#define XTHAL_16_BIT_BREAK		0x40000000
+extern const unsigned short	Xthal_ill_inst_16[16];
+#define XTHAL_DEST_REG		0xf0000000	/* Mask for destination register */
+#define XTHAL_DEST_REG_INST	0x08000000	/* Branch address is in register */
+#define XTHAL_DEST_REL_INST	0x04000000	/* Branch address is relative */
+#define XTHAL_RFW_INST		0x00000800
+#define XTHAL_RFUE_INST		0x00000400
+#define XTHAL_RFI_INST		0x00000200
+#define XTHAL_RFE_INST		0x00000100
+#define XTHAL_RET_INST		0x00000080
+#define XTHAL_BREAK_INST	0x00000040
+#define XTHAL_SYSCALL_INST	0x00000020
+#define XTHAL_LOOP_END		0x00000010	/* Not set by xthal_inst_type */
+#define XTHAL_JUMP_INST		0x00000008	/* Call or jump instruction */
+#define XTHAL_BRANCH_INST	0x00000004	/* Branch instruction */
+#define XTHAL_24_BIT_INST	0x00000002
+#define XTHAL_16_BIT_INST   0x00000001
+typedef struct xthal_state {
+    unsigned	pc;
+    unsigned	ar[16];
+    unsigned	lbeg;
+    unsigned	lend;
+    unsigned	lcount;
+    unsigned	extra_ptr;
+    unsigned	cpregs_ptr[XTHAL_MAX_CPS];
+} XTHAL_STATE;
+extern unsigned int xthal_inst_type(void *addr);
+extern unsigned int xthal_branch_addr(void *addr);
+extern unsigned int xthal_get_npc(XTHAL_STATE *user_state);
+#endif /* INCLUDE_DEPRECATED_HAL_DEBUG_CODE */
+
+#ifdef __cplusplus
+}
+#endif
+#endif /*!__ASSEMBLY__ */
+
+#endif /*XTENSA_HAL_H*/
+
diff --git a/include/asm-xtensa/xtensa/simcall.h b/include/asm-xtensa/xtensa/simcall.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/xtensa/simcall.h
@@ -0,0 +1,130 @@
+#ifndef SIMCALL_INCLUDED
+#define SIMCALL_INCLUDED
+
+/*
+ * THIS FILE IS GENERATED -- DO NOT MODIFY BY HAND
+ *
+ * include/asm-xtensa/xtensa/simcall.h  -  Simulator call numbers
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file "COPYING" in the main directory of
+ * this archive for more details.
+ *
+ * Copyright (C) 2002 Tensilica Inc.
+ */
+
+
+/*
+ *  System call like services offered by the simulator host.
+ *  These are modeled after the Linux 2.4 kernel system calls
+ *  for Xtensa processors.  However not all system calls and
+ *  not all functionality of a given system call are implemented,
+ *  or necessarily have well defined or equivalent semantics in
+ *  the context of a simulation (as opposed to a Unix kernel).
+ *
+ *  These services behave largely as if they had been invoked
+ *  as a task in the simulator host's operating system
+ *  (eg. files accessed are those of the simulator host).
+ *  However, these SIMCALLs model a virtual operating system
+ *  so that various definitions, bit assignments etc
+ *  (eg. open mode bits, errno values, etc) are independent
+ *  of the host operating system used to run the simulation.
+ *  Rather these definitions are specific to the Xtensa ISS.
+ *  This way Xtensa ISA code written to use these SIMCALLs
+ *  can (in principle) be simulated on any host.
+ *
+ *  Up to 6 parameters are passed in registers a3 to a8
+ *  (note the 6th parameter isn't passed on the stack,
+ *   unlike windowed function calling conventions).
+ *  The return value is in a2.  A negative value in the
+ *  range -4096 to -1 indicates a negated error code to be
+ *  reported in errno with a return value of -1, otherwise
+ *  the value in a2 is returned as is.
+ */
+
+/* These #defines need to match what's in Xtensa/OS/vxworks/xtiss/simcalls.c */
+
+#define SYS_nop		0	/* n/a - setup; used to flush register windows */
+#define SYS_exit	1	/*x*/
+#define SYS_fork	2
+#define SYS_read	3	/*x*/
+#define SYS_write	4	/*x*/
+#define SYS_open	5	/*x*/
+#define SYS_close	6	/*x*/
+#define SYS_rename	7	/*x 38 - waitpid */
+#define SYS_creat	8	/*x*/
+#define SYS_link	9	/*x (not implemented on WIN32) */
+#define SYS_unlink	10	/*x*/
+#define SYS_execv	11	/* n/a - execve */
+#define SYS_execve	12	/* 11 - chdir */
+#define SYS_pipe	13	/* 42 - time */
+#define SYS_stat	14	/* 106 - mknod */
+#define SYS_chmod	15
+#define SYS_chown	16	/* 202 - lchown */
+#define SYS_utime	17	/* 30 - break */
+#define SYS_wait	18	/* n/a - oldstat */
+#define SYS_lseek	19	/*x*/
+#define SYS_getpid	20
+#define SYS_isatty	21	/* n/a - mount */
+#define SYS_fstat	22	/* 108 - oldumount */
+#define SYS_time	23	/* 13 - setuid */
+#define SYS_gettimeofday 24	/*x 78 - getuid (not implemented on WIN32) */
+#define SYS_times	25	/*X 43 - stime (Xtensa-specific implementation) */
+#define SYS_socket      26
+#define SYS_sendto      27
+#define SYS_recvfrom    28
+#define SYS_select_one  29      /* not compitible select, one file descriptor at the time */
+#define SYS_bind        30
+#define SYS_ioctl	31
+
+/*
+ *  Other...
+ */
+#define SYS_iss_argc      1000	/* returns value of argc */
+#define SYS_iss_argv_size 1001	/* bytes needed for argv & arg strings */
+#define SYS_iss_set_argv  1002	/* saves argv & arg strings at given addr */
+
+/*
+ * SIMCALLs for the ferret memory debugger. All are invoked by
+ * libferret.a ...  ( Xtensa/Target-Libs/ferret )
+ */
+#define SYS_ferret           1010
+#define SYS_malloc           1011
+#define SYS_free             1012
+#define SYS_more_heap        1013
+#define SYS_no_heap          1014
+
+
+/*
+ *  Extra SIMCALLs for GDB:
+ */
+#define SYS_gdb_break         -1	/* invoked by XTOS on user exceptions if EPC points
+					   to a break.n/break, regardless of cause! */
+#define SYS_xmon_out          -2	/* invoked by XMON: ... */
+#define SYS_xmon_in           -3	/* invoked by XMON: ... */
+#define SYS_xmon_flush        -4	/* invoked by XMON: ... */
+#define SYS_gdb_abort         -5	/* invoked by XTOS in _xtos_panic() */
+#define SYS_gdb_illegal_inst  -6	/* invoked by XTOS for illegal instructions (too deeply) */
+#define SYS_xmon_init         -7	/* invoked by XMON: ... */
+#define SYS_gdb_enter_sktloop -8	/* invoked by XTOS on debug exceptions */
+
+/*
+ *  SIMCALLs for vxWorks xtiss BSP:
+ */
+#define SYS_setup_ppp_pipes   -83
+#define SYS_log_msg           -84
+
+/*
+ *  Test SIMCALLs:
+ */
+#define SYS_test_write_state  -100
+#define SYS_test_read_state   -101
+
+/*
+ * SYS_select_one specifiers
+ */
+#define  XTISS_SELECT_ONE_READ    1
+#define  XTISS_SELECT_ONE_WRITE   2
+#define  XTISS_SELECT_ONE_EXCEPT  3
+
+#endif /* !SIMCALL_INCLUDED */
diff --git a/include/asm-xtensa/xtensa/xt2000-uart.h b/include/asm-xtensa/xtensa/xt2000-uart.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/xtensa/xt2000-uart.h
@@ -0,0 +1,155 @@
+#ifndef _uart_h_included_
+#define _uart_h_included_
+
+/*
+ * THIS FILE IS GENERATED -- DO NOT MODIFY BY HAND
+ *
+ * include/asm-xtensa/xtensa/xt2000-uart.h -- NatSemi PC16552D DUART
+ * definitions
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2002 Tensilica Inc.
+ */
+
+
+#include <xtensa/xt2000.h>
+
+
+/* 16550 UART DEVICE REGISTERS
+   The XT2000 board aligns each register to a 32-bit word but the UART device only uses
+   one byte of the word, which is the least-significant byte regardless of the
+   endianness of the core (ie. byte offset 0 for little-endian and 3 for big-endian).
+   So if using word accesses then endianness doesn't matter.
+   The macros provided here do that.
+*/
+struct uart_dev_s {
+  union {
+    unsigned int rxb;	/* DLAB=0: receive buffer, read-only */
+    unsigned int txb;	/* DLAB=0: transmit buffer, write-only */
+    unsigned int dll;	/* DLAB=1: divisor, least-significant byte latch (was write-only?) */
+  } w0;
+  union {
+    unsigned int ier;	/* DLAB=0: interrupt-enable register (was write-only?) */
+    unsigned int dlm;	/* DLAB=1: divisor, most-significant byte latch (was write-only?) */
+  } w1;
+
+  union {
+    unsigned int isr;	/* DLAB=0: interrupt status register, read-only */
+    unsigned int fcr;	/* DLAB=0: FIFO control register, write-only */
+    unsigned int afr;	/* DLAB=1: alternate function register */
+  } w2;
+
+  unsigned int lcr;	/* line control-register, write-only */
+  unsigned int mcr;	/* modem control-regsiter, write-only */
+  unsigned int lsr;	/* line status register, read-only */
+  unsigned int msr;	/* modem status register, read-only */
+  unsigned int scr;	/* scratch regsiter, read/write */
+};
+
+#define _RXB(u) ((u)->w0.rxb)
+#define _TXB(u) ((u)->w0.txb)
+#define _DLL(u) ((u)->w0.dll)
+#define _IER(u) ((u)->w1.ier)
+#define _DLM(u) ((u)->w1.dlm)
+#define _ISR(u) ((u)->w2.isr)
+#define _FCR(u) ((u)->w2.fcr)
+#define _AFR(u) ((u)->w2.afr)
+#define _LCR(u) ((u)->lcr)
+#define _MCR(u) ((u)->mcr)
+#define _LSR(u) ((u)->lsr)
+#define _MSR(u) ((u)->msr)
+#define _SCR(u) ((u)->scr)
+
+typedef volatile struct uart_dev_s uart_dev_t;
+
+/* IER bits */
+#define RCVR_DATA_REG_INTENABLE 0x01
+#define XMIT_HOLD_REG_INTENABLE    0x02
+#define RCVR_STATUS_INTENABLE   0x04
+#define MODEM_STATUS_INTENABLE     0x08
+
+/* FCR bits */
+#define _FIFO_ENABLE      0x01
+#define RCVR_FIFO_RESET  0x02
+#define XMIT_FIFO_RESET  0x04
+#define DMA_MODE_SELECT  0x08
+#define RCVR_TRIGGER_LSB 0x40
+#define RCVR_TRIGGER_MSB 0x80
+
+/* AFR bits */
+#define AFR_CONC_WRITE	0x01
+#define AFR_BAUDOUT_SEL	0x02
+#define AFR_RXRDY_SEL	0x04
+
+/* ISR bits */
+#define INT_STATUS(r)   ((r)&1)
+#define INT_PRIORITY(r) (((r)>>1)&0x7)
+
+/* LCR bits */
+#define WORD_LENGTH(n)  (((n)-5)&0x3)
+#define STOP_BIT_ENABLE 0x04
+#define PARITY_ENABLE   0x08
+#define EVEN_PARITY     0x10
+#define FORCE_PARITY    0x20
+#define XMIT_BREAK      0x40
+#define DLAB_ENABLE     0x80
+
+/* MCR bits */
+#define _DTR 0x01
+#define _RTS 0x02
+#define _OP1 0x04
+#define _OP2 0x08
+#define LOOP_BACK 0x10
+
+/* LSR Bits */
+#define RCVR_DATA_READY 0x01
+#define OVERRUN_ERROR   0x02
+#define PARITY_ERROR    0x04
+#define FRAMING_ERROR   0x08
+#define BREAK_INTERRUPT 0x10
+#define XMIT_HOLD_EMPTY 0x20
+#define XMIT_EMPTY      0x40
+#define FIFO_ERROR      0x80
+#define RCVR_READY(u)   (_LSR(u)&RCVR_DATA_READY)
+#define XMIT_READY(u)   (_LSR(u)&XMIT_HOLD_EMPTY)
+
+/* MSR bits */
+#define _RDR       0x01
+#define DELTA_DSR 0x02
+#define DELTA_RI  0x04
+#define DELTA_CD  0x08
+#define _CTS       0x10
+#define _DSR       0x20
+#define _RI        0x40
+#define _CD        0x80
+
+/* prototypes */
+void uart_init( uart_dev_t *u, int bitrate );
+void uart_out( uart_dev_t *u, char c );
+void uart_puts( uart_dev_t *u, char *s );
+char uart_in( uart_dev_t *u );
+void uart_enable_rcvr_int( uart_dev_t *u );
+void uart_disable_rcvr_int( uart_dev_t *u );
+
+#ifdef DUART16552_1_VADDR
+/*  DUART present.  */
+#define DUART_1_BASE	(*(uart_dev_t*)DUART16552_1_VADDR)
+#define DUART_2_BASE	(*(uart_dev_t*)DUART16552_2_VADDR)
+#define UART1_PUTS(s)	uart_puts( &DUART_1_BASE, s )
+#define UART2_PUTS(s)	uart_puts( &DUART_2_BASE, s )
+#else
+/*  DUART not configured, use dummy placeholders to allow compiles to work.  */
+#define DUART_1_BASE	(*(uart_dev_t*)0)
+#define DUART_2_BASE	(*(uart_dev_t*)0)
+#define UART1_PUTS(s)
+#define UART2_PUTS(s)
+#endif
+
+/*  Compute 16-bit divisor for baudrate generator, with rounding:  */
+#define DUART_DIVISOR(crystal,speed)	(((crystal)/16 + (speed)/2)/(speed))
+
+#endif /*_uart_h_included_*/
+
diff --git a/include/asm-xtensa/xtensa/xt2000.h b/include/asm-xtensa/xtensa/xt2000.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/xtensa/xt2000.h
@@ -0,0 +1,408 @@
+#ifndef _INC_XT2000_H_
+#define _INC_XT2000_H_
+
+/*
+ * THIS FILE IS GENERATED -- DO NOT MODIFY BY HAND
+ *
+ * include/asm-xtensa/xtensa/xt2000.h - Definitions specific to the
+ * Tensilica XT2000 Emulation Board
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2002 Tensilica Inc.
+ */
+
+
+#include <xtensa/config/core.h>
+#include <xtensa/config/system.h>
+
+
+/*
+ *  Default assignment of XT2000 devices to external interrupts.
+ */
+
+/*  Ethernet interrupt:  */
+#ifdef XCHAL_EXTINT3_NUM
+#define SONIC83934_INTNUM	XCHAL_EXTINT3_NUM
+#define SONIC83934_INTLEVEL	XCHAL_EXTINT3_LEVEL
+#define SONIC83934_INTMASK	XCHAL_EXTINT3_MASK
+#else
+#define SONIC83934_INTMASK	0
+#endif
+
+/*  DUART channel 1 interrupt (P1 - console):  */
+#ifdef XCHAL_EXTINT4_NUM
+#define DUART16552_1_INTNUM	XCHAL_EXTINT4_NUM
+#define DUART16552_1_INTLEVEL	XCHAL_EXTINT4_LEVEL
+#define DUART16552_1_INTMASK	XCHAL_EXTINT4_MASK
+#else
+#define DUART16552_1_INTMASK	0
+#endif
+
+/*  DUART channel 2 interrupt (P2 - 2nd serial port):  */
+#ifdef XCHAL_EXTINT5_NUM
+#define DUART16552_2_INTNUM	XCHAL_EXTINT5_NUM
+#define DUART16552_2_INTLEVEL	XCHAL_EXTINT5_LEVEL
+#define DUART16552_2_INTMASK	XCHAL_EXTINT5_MASK
+#else
+#define DUART16552_2_INTMASK	0
+#endif
+
+/*  FPGA-combined PCI/etc interrupts:  */
+#ifdef XCHAL_EXTINT6_NUM
+#define XT2000_FPGAPCI_INTNUM	XCHAL_EXTINT6_NUM
+#define XT2000_FPGAPCI_INTLEVEL	XCHAL_EXTINT6_LEVEL
+#define XT2000_FPGAPCI_INTMASK	XCHAL_EXTINT6_MASK
+#else
+#define XT2000_FPGAPCI_INTMASK	0
+#endif
+
+
+
+/*
+ *  Device addresses.
+ *
+ *  Note:  for endianness-independence, use 32-bit loads and stores for all
+ *  register accesses to Ethernet, DUART and LED devices.  Undefined bits
+ *  may need to be masked out if needed when reading if the actual register
+ *  size is smaller than 32 bits.
+ *
+ *  Note:  XT2000 bus byte lanes are defined in terms of msbyte and lsbyte
+ *  relative to the processor.  So 32-bit registers are accessed consistently
+ *  from both big and little endian processors.  However, this means byte
+ *  sequences are not consistent between big and little endian processors.
+ *  This is fine for RAM, and for ROM if ROM is created for a specific
+ *  processor (and thus has correct byte sequences).  However this may be
+ *  unexpected for Flash, which might contain a file-system that one wants
+ *  to use for multiple processor configurations (eg. the Flash might contain
+ *  the Ethernet card's address, endianness-independent application data, etc).
+ *  That is, byte sequences written in Flash by a core of a given endianness
+ *  will be byte-swapped when seen by a core of the other endianness.
+ *  Someone implementing an endianness-independent Flash file system will
+ *  likely handle this byte-swapping issue in the Flash driver software.
+ */
+
+#define DUART16552_XTAL_FREQ	18432000	/* crystal frequency in Hz */
+#define XTBOARD_FLASH_MAXSIZE	0x4000000	/* 64 MB (max; depends on what is socketed!) */
+#define XTBOARD_EPROM_MAXSIZE	0x0400000	/* 4 MB (max; depends on what is socketed!) */
+#define XTBOARD_EEPROM_MAXSIZE	0x0080000	/* 512 kB (max; depends on what is socketed!) */
+#define XTBOARD_ASRAM_SIZE	0x0100000	/* 1 MB */
+#define XTBOARD_PCI_MEM_SIZE	0x8000000	/* 128 MB (allocated) */
+#define XTBOARD_PCI_IO_SIZE	0x1000000	/* 16 MB (allocated) */
+
+#ifdef XSHAL_IOBLOCK_BYPASS_PADDR
+/*  PCI memory space:  */
+# define XTBOARD_PCI_MEM_PADDR	(XSHAL_IOBLOCK_BYPASS_PADDR+0x0000000)
+/*  Socketed Flash (eg. 2 x 16-bit devices):  */
+# define XTBOARD_FLASH_PADDR	(XSHAL_IOBLOCK_BYPASS_PADDR+0x8000000)
+/*  PCI I/O space:  */
+# define XTBOARD_PCI_IO_PADDR	(XSHAL_IOBLOCK_BYPASS_PADDR+0xC000000)
+/*  V3 PCI interface chip register/config space:  */
+# define XTBOARD_V3PCI_PADDR	(XSHAL_IOBLOCK_BYPASS_PADDR+0xD000000)
+/*  Bus Interface registers:  */
+# define XTBOARD_BUSINT_PADDR	(XSHAL_IOBLOCK_BYPASS_PADDR+0xD010000)
+/*  FPGA registers:  */
+# define XT2000_FPGAREGS_PADDR	(XSHAL_IOBLOCK_BYPASS_PADDR+0xD020000)
+/*  SONIC SN83934 Ethernet controller/transceiver:  */
+# define SONIC83934_PADDR	(XSHAL_IOBLOCK_BYPASS_PADDR+0xD030000)
+/*  8-character bitmapped LED display:  */
+# define XTBOARD_LED_PADDR	(XSHAL_IOBLOCK_BYPASS_PADDR+0xD040000)
+/*  National-Semi PC16552D DUART:  */
+# define DUART16552_1_PADDR	(XSHAL_IOBLOCK_BYPASS_PADDR+0xD050020)	/* channel 1 (P1 - console) */
+# define DUART16552_2_PADDR	(XSHAL_IOBLOCK_BYPASS_PADDR+0xD050000)	/* channel 2 (P2) */
+/*  Asynchronous Static RAM:  */
+# define XTBOARD_ASRAM_PADDR	(XSHAL_IOBLOCK_BYPASS_PADDR+0xD400000)
+/*  8-bit EEPROM:  */
+# define XTBOARD_EEPROM_PADDR	(XSHAL_IOBLOCK_BYPASS_PADDR+0xD600000)
+/*  2 x 16-bit EPROMs:  */
+# define XTBOARD_EPROM_PADDR	(XSHAL_IOBLOCK_BYPASS_PADDR+0xD800000)
+#endif /* XSHAL_IOBLOCK_BYPASS_PADDR */
+
+/*  These devices might be accessed cached:  */
+#ifdef XSHAL_IOBLOCK_CACHED_PADDR
+# define XTBOARD_PCI_MEM_CACHED_PADDR	(XSHAL_IOBLOCK_CACHED_PADDR+0x0000000)
+# define XTBOARD_FLASH_CACHED_PADDR	(XSHAL_IOBLOCK_CACHED_PADDR+0x8000000)
+# define XTBOARD_ASRAM_CACHED_PADDR	(XSHAL_IOBLOCK_CACHED_PADDR+0xD400000)
+# define XTBOARD_EEPROM_CACHED_PADDR	(XSHAL_IOBLOCK_CACHED_PADDR+0xD600000)
+# define XTBOARD_EPROM_CACHED_PADDR	(XSHAL_IOBLOCK_CACHED_PADDR+0xD800000)
+#endif /* XSHAL_IOBLOCK_CACHED_PADDR */
+
+
+/***  Same thing over again, this time with virtual addresses:  ***/
+
+#ifdef XSHAL_IOBLOCK_BYPASS_VADDR
+/*  PCI memory space:  */
+# define XTBOARD_PCI_MEM_VADDR	(XSHAL_IOBLOCK_BYPASS_VADDR+0x0000000)
+/*  Socketed Flash (eg. 2 x 16-bit devices):  */
+# define XTBOARD_FLASH_VADDR	(XSHAL_IOBLOCK_BYPASS_VADDR+0x8000000)
+/*  PCI I/O space:  */
+# define XTBOARD_PCI_IO_VADDR	(XSHAL_IOBLOCK_BYPASS_VADDR+0xC000000)
+/*  V3 PCI interface chip register/config space:  */
+# define XTBOARD_V3PCI_VADDR	(XSHAL_IOBLOCK_BYPASS_VADDR+0xD000000)
+/*  Bus Interface registers:  */
+# define XTBOARD_BUSINT_VADDR	(XSHAL_IOBLOCK_BYPASS_VADDR+0xD010000)
+/*  FPGA registers:  */
+# define XT2000_FPGAREGS_VADDR	(XSHAL_IOBLOCK_BYPASS_VADDR+0xD020000)
+/*  SONIC SN83934 Ethernet controller/transceiver:  */
+# define SONIC83934_VADDR	(XSHAL_IOBLOCK_BYPASS_VADDR+0xD030000)
+/*  8-character bitmapped LED display:  */
+# define XTBOARD_LED_VADDR	(XSHAL_IOBLOCK_BYPASS_VADDR+0xD040000)
+/*  National-Semi PC16552D DUART:  */
+# define DUART16552_1_VADDR	(XSHAL_IOBLOCK_BYPASS_VADDR+0xD050020)	/* channel 1 (P1 - console) */
+# define DUART16552_2_VADDR	(XSHAL_IOBLOCK_BYPASS_VADDR+0xD050000)	/* channel 2 (P2) */
+/*  Asynchronous Static RAM:  */
+# define XTBOARD_ASRAM_VADDR	(XSHAL_IOBLOCK_BYPASS_VADDR+0xD400000)
+/*  8-bit EEPROM:  */
+# define XTBOARD_EEPROM_VADDR	(XSHAL_IOBLOCK_BYPASS_VADDR+0xD600000)
+/*  2 x 16-bit EPROMs:  */
+# define XTBOARD_EPROM_VADDR	(XSHAL_IOBLOCK_BYPASS_VADDR+0xD800000)
+#endif /* XSHAL_IOBLOCK_BYPASS_VADDR */
+
+/*  These devices might be accessed cached:  */
+#ifdef XSHAL_IOBLOCK_CACHED_VADDR
+# define XTBOARD_PCI_MEM_CACHED_VADDR	(XSHAL_IOBLOCK_CACHED_VADDR+0x0000000)
+# define XTBOARD_FLASH_CACHED_VADDR	(XSHAL_IOBLOCK_CACHED_VADDR+0x8000000)
+# define XTBOARD_ASRAM_CACHED_VADDR	(XSHAL_IOBLOCK_CACHED_VADDR+0xD400000)
+# define XTBOARD_EEPROM_CACHED_VADDR	(XSHAL_IOBLOCK_CACHED_VADDR+0xD600000)
+# define XTBOARD_EPROM_CACHED_VADDR	(XSHAL_IOBLOCK_CACHED_VADDR+0xD800000)
+#endif /* XSHAL_IOBLOCK_CACHED_VADDR */
+
+
+/*  System ROM:  */
+#define XTBOARD_ROM_SIZE		XSHAL_ROM_SIZE
+#ifdef XSHAL_ROM_VADDR
+#define XTBOARD_ROM_VADDR		XSHAL_ROM_VADDR
+#endif
+#ifdef XSHAL_ROM_PADDR
+#define XTBOARD_ROM_PADDR		XSHAL_ROM_PADDR
+#endif
+
+/*  System RAM:  */
+#define XTBOARD_RAM_SIZE		XSHAL_RAM_SIZE
+#ifdef XSHAL_RAM_VADDR
+#define XTBOARD_RAM_VADDR		XSHAL_RAM_VADDR
+#endif
+#ifdef XSHAL_RAM_PADDR
+#define XTBOARD_RAM_PADDR		XSHAL_RAM_PADDR
+#endif
+#define XTBOARD_RAM_BYPASS_VADDR	XSHAL_RAM_BYPASS_VADDR
+#define XTBOARD_RAM_BYPASS_PADDR	XSHAL_RAM_BYPASS_PADDR
+
+
+
+/*
+ *  Things that depend on device addresses.
+ */
+
+
+#define XTBOARD_CACHEATTR_WRITEBACK	XSHAL_XT2000_CACHEATTR_WRITEBACK
+#define XTBOARD_CACHEATTR_WRITEALLOC	XSHAL_XT2000_CACHEATTR_WRITEALLOC
+#define XTBOARD_CACHEATTR_WRITETHRU	XSHAL_XT2000_CACHEATTR_WRITETHRU
+#define XTBOARD_CACHEATTR_BYPASS	XSHAL_XT2000_CACHEATTR_BYPASS
+#define XTBOARD_CACHEATTR_DEFAULT	XSHAL_XT2000_CACHEATTR_DEFAULT
+
+#define XTBOARD_BUSINT_PIPE_REGIONS	XSHAL_XT2000_PIPE_REGIONS
+#define XTBOARD_BUSINT_SDRAM_REGIONS	XSHAL_XT2000_SDRAM_REGIONS
+
+
+
+/*
+ *  BusLogic (FPGA) registers.
+ *  All these registers are normally accessed using 32-bit loads/stores.
+ */
+
+/*  Register offsets:  */
+#define XT2000_DATECD_OFS	0x00	/* date code (read-only) */
+#define XT2000_STSREG_OFS	0x04	/* status (read-only) */
+#define XT2000_SYSLED_OFS	0x08	/* system LED */
+#define XT2000_WRPROT_OFS	0x0C	/* write protect */
+#define XT2000_SWRST_OFS	0x10	/* software reset */
+#define XT2000_SYSRST_OFS	0x14	/* system (peripherals) reset */
+#define XT2000_IMASK_OFS	0x18	/* interrupt mask */
+#define XT2000_ISTAT_OFS	0x1C	/* interrupt status */
+#define XT2000_V3CFG_OFS	0x20	/* V3 config (V320 PCI) */
+
+/*  Physical register addresses:  */
+#ifdef XT2000_FPGAREGS_PADDR
+#define XT2000_DATECD_PADDR	(XT2000_FPGAREGS_PADDR+XT2000_DATECD_OFS)
+#define XT2000_STSREG_PADDR	(XT2000_FPGAREGS_PADDR+XT2000_STSREG_OFS)
+#define XT2000_SYSLED_PADDR	(XT2000_FPGAREGS_PADDR+XT2000_SYSLED_OFS)
+#define XT2000_WRPROT_PADDR	(XT2000_FPGAREGS_PADDR+XT2000_WRPROT_OFS)
+#define XT2000_SWRST_PADDR	(XT2000_FPGAREGS_PADDR+XT2000_SWRST_OFS)
+#define XT2000_SYSRST_PADDR	(XT2000_FPGAREGS_PADDR+XT2000_SYSRST_OFS)
+#define XT2000_IMASK_PADDR	(XT2000_FPGAREGS_PADDR+XT2000_IMASK_OFS)
+#define XT2000_ISTAT_PADDR	(XT2000_FPGAREGS_PADDR+XT2000_ISTAT_OFS)
+#define XT2000_V3CFG_PADDR	(XT2000_FPGAREGS_PADDR+XT2000_V3CFG_OFS)
+#endif
+
+/*  Virtual register addresses:  */
+#ifdef XT2000_FPGAREGS_VADDR
+#define XT2000_DATECD_VADDR	(XT2000_FPGAREGS_VADDR+XT2000_DATECD_OFS)
+#define XT2000_STSREG_VADDR	(XT2000_FPGAREGS_VADDR+XT2000_STSREG_OFS)
+#define XT2000_SYSLED_VADDR	(XT2000_FPGAREGS_VADDR+XT2000_SYSLED_OFS)
+#define XT2000_WRPROT_VADDR	(XT2000_FPGAREGS_VADDR+XT2000_WRPROT_OFS)
+#define XT2000_SWRST_VADDR	(XT2000_FPGAREGS_VADDR+XT2000_SWRST_OFS)
+#define XT2000_SYSRST_VADDR	(XT2000_FPGAREGS_VADDR+XT2000_SYSRST_OFS)
+#define XT2000_IMASK_VADDR	(XT2000_FPGAREGS_VADDR+XT2000_IMASK_OFS)
+#define XT2000_ISTAT_VADDR	(XT2000_FPGAREGS_VADDR+XT2000_ISTAT_OFS)
+#define XT2000_V3CFG_VADDR	(XT2000_FPGAREGS_VADDR+XT2000_V3CFG_OFS)
+/*  Register access (for C code):  */
+#define XT2000_DATECD_REG	(*(volatile unsigned*) XT2000_DATECD_VADDR)
+#define XT2000_STSREG_REG	(*(volatile unsigned*) XT2000_STSREG_VADDR)
+#define XT2000_SYSLED_REG	(*(volatile unsigned*) XT2000_SYSLED_VADDR)
+#define XT2000_WRPROT_REG	(*(volatile unsigned*) XT2000_WRPROT_VADDR)
+#define XT2000_SWRST_REG	(*(volatile unsigned*) XT2000_SWRST_VADDR)
+#define XT2000_SYSRST_REG	(*(volatile unsigned*) XT2000_SYSRST_VADDR)
+#define XT2000_IMASK_REG	(*(volatile unsigned*) XT2000_IMASK_VADDR)
+#define XT2000_ISTAT_REG	(*(volatile unsigned*) XT2000_ISTAT_VADDR)
+#define XT2000_V3CFG_REG	(*(volatile unsigned*) XT2000_V3CFG_VADDR)
+#endif
+
+/*  DATECD (date code) bit fields:  */
+
+/*  BCD-coded month (01..12):  */
+#define XT2000_DATECD_MONTH_SHIFT	24
+#define XT2000_DATECD_MONTH_BITS	8
+#define XT2000_DATECD_MONTH_MASK	0xFF000000
+/*  BCD-coded day (01..31):  */
+#define XT2000_DATECD_DAY_SHIFT		16
+#define XT2000_DATECD_DAY_BITS		8
+#define XT2000_DATECD_DAY_MASK		0x00FF0000
+/*  BCD-coded year (2001..9999):  */
+#define XT2000_DATECD_YEAR_SHIFT	0
+#define XT2000_DATECD_YEAR_BITS		16
+#define XT2000_DATECD_YEAR_MASK		0x0000FFFF
+
+/*  STSREG (status) bit fields:  */
+
+/*  Switch SW3 setting bit fields (0=off/up, 1=on/down):  */
+#define XT2000_STSREG_SW3_SHIFT		0
+#define XT2000_STSREG_SW3_BITS		4
+#define XT2000_STSREG_SW3_MASK		0x0000000F
+/*  Boot-select bits of switch SW3:  */
+#define XT2000_STSREG_BOOTSEL_SHIFT	0
+#define XT2000_STSREG_BOOTSEL_BITS	2
+#define XT2000_STSREG_BOOTSEL_MASK	0x00000003
+/*  Boot-select values:  */
+#define XT2000_STSREG_BOOTSEL_FLASH	0
+#define XT2000_STSREG_BOOTSEL_EPROM16	1
+#define XT2000_STSREG_BOOTSEL_PROM8	2
+#define XT2000_STSREG_BOOTSEL_ASRAM	3
+/*  User-defined bits of switch SW3:  */
+#define XT2000_STSREG_SW3_2_SHIFT	2
+#define XT2000_STSREG_SW3_2_MASK	0x00000004
+#define XT2000_STSREG_SW3_3_SHIFT	3
+#define XT2000_STSREG_SW3_3_MASK	0x00000008
+
+/*  SYSLED (system LED) bit fields:  */
+
+/*  LED control bit (0=off, 1=on):  */
+#define XT2000_SYSLED_LEDON_SHIFT	0
+#define XT2000_SYSLED_LEDON_MASK	0x00000001
+
+/*  WRPROT (write protect) bit fields (0=writable, 1=write-protected [default]):  */
+
+/*  Flash write protect:  */
+#define XT2000_WRPROT_FLWP_SHIFT	0
+#define XT2000_WRPROT_FLWP_MASK		0x00000001
+/*  Reserved but present write protect bits:  */
+#define XT2000_WRPROT_WRP_SHIFT		1
+#define XT2000_WRPROT_WRP_BITS		7
+#define XT2000_WRPROT_WRP_MASK		0x000000FE
+
+/*  SWRST (software reset; allows s/w to generate power-on equivalent reset):  */
+
+/*  Software reset bits:  */
+#define XT2000_SWRST_SWR_SHIFT		0
+#define XT2000_SWRST_SWR_BITS		16
+#define XT2000_SWRST_SWR_MASK		0x0000FFFF
+/*  Software reset value -- writing this value resets the board:  */
+#define XT2000_SWRST_RESETVALUE		0x0000DEAD
+
+/*  SYSRST (system reset; controls reset of individual peripherals):  */
+
+/*  All-device reset:  */
+#define XT2000_SYSRST_ALL_SHIFT		0
+#define XT2000_SYSRST_ALL_BITS		4
+#define XT2000_SYSRST_ALL_MASK		0x0000000F
+/*  HDSP-2534 LED display reset (1=reset, 0=nothing):  */
+#define XT2000_SYSRST_LED_SHIFT		0
+#define XT2000_SYSRST_LED_MASK		0x00000001
+/*  Sonic DP83934 Ethernet controller reset (1=reset, 0=nothing):  */
+#define XT2000_SYSRST_SONIC_SHIFT	1
+#define XT2000_SYSRST_SONIC_MASK	0x00000002
+/*  DP16552 DUART reset (1=reset, 0=nothing):  */
+#define XT2000_SYSRST_DUART_SHIFT	2
+#define XT2000_SYSRST_DUART_MASK	0x00000004
+/*  V3 V320 PCI bridge controller reset (1=reset, 0=nothing):  */
+#define XT2000_SYSRST_V3_SHIFT		3
+#define XT2000_SYSRST_V3_MASK		0x00000008
+
+/*  IMASK (interrupt mask; 0=disable, 1=enable):  */
+/*  ISTAT (interrupt status; 0=inactive, 1=pending):  */
+
+/*  PCI INTP interrupt:  */
+#define XT2000_INTMUX_PCI_INTP_SHIFT	2
+#define XT2000_INTMUX_PCI_INTP_MASK	0x00000004
+/*  PCI INTS interrupt:  */
+#define XT2000_INTMUX_PCI_INTS_SHIFT	3
+#define XT2000_INTMUX_PCI_INTS_MASK	0x00000008
+/*  PCI INTD interrupt:  */
+#define XT2000_INTMUX_PCI_INTD_SHIFT	4
+#define XT2000_INTMUX_PCI_INTD_MASK	0x00000010
+/*  V320 PCI controller interrupt:  */
+#define XT2000_INTMUX_V3_SHIFT		5
+#define XT2000_INTMUX_V3_MASK		0x00000020
+/*  PCI ENUM interrupt:  */
+#define XT2000_INTMUX_PCI_ENUM_SHIFT	6
+#define XT2000_INTMUX_PCI_ENUM_MASK	0x00000040
+/*  PCI DEG interrupt:  */
+#define XT2000_INTMUX_PCI_DEG_SHIFT	7
+#define XT2000_INTMUX_PCI_DEG_MASK	0x00000080
+
+/*  V3CFG (V3 config, V320 PCI controller):  */
+
+/*  V3 address control (0=pass-thru, 1=V3 address bits 31:28 set to 4'b0001 [default]):  */
+#define XT2000_V3CFG_V3ADC_SHIFT	0
+#define XT2000_V3CFG_V3ADC_MASK		0x00000001
+
+/* I2C Devices */
+
+#define	XT2000_I2C_RTC_ID		0x68
+#define	XT2000_I2C_NVRAM0_ID		0x56	/* 1st 256 byte block */
+#define	XT2000_I2C_NVRAM1_ID		0x57	/* 2nd 256 byte block */
+
+/*  NVRAM Board Info structure:  */
+
+#define XT2000_NVRAM_SIZE		512
+
+#define XT2000_NVRAM_BINFO_START	0x100
+#define XT2000_NVRAM_BINFO_SIZE		0x20
+#define XT2000_NVRAM_BINFO_VERSION	0x10	/* version 1.0 */
+#if 0
+#define XT2000_NVRAM_BINFO_VERSION_OFFSET	0x00
+#define XT2000_NVRAM_BINFO_VERSION_SIZE			0x1
+#define XT2000_NVRAM_BINFO_ETH_ADDR_OFFSET	0x02
+#define XT2000_NVRAM_BINFO_ETH_ADDR_SIZE		0x6
+#define XT2000_NVRAM_BINFO_SN_OFFSET		0x10
+#define XT2000_NVRAM_BINFO_SN_SIZE			0xE
+#define	XT2000_NVRAM_BINFO_CRC_OFFSET		0x1E
+#define	XT2000_NVRAM_BINFO_CRC_SIZE			0x2
+#endif /*0*/
+
+#if !defined(__ASSEMBLY__) && !defined(_NOCLANGUAGE)
+typedef struct xt2000_nvram_binfo {
+    unsigned char	version;
+    unsigned char	reserved1;
+    unsigned char	eth_addr[6];
+    unsigned char	reserved8[8];
+    unsigned char	serialno[14];
+    unsigned char	crc[2];		/* 16-bit CRC */
+} xt2000_nvram_binfo;
+#endif /*!__ASSEMBLY__ && !_NOCLANGUAGE*/
+
+
+#endif /*_INC_XT2000_H_*/
+
diff --git a/include/asm-xtensa/xtensa/xtboard.h b/include/asm-xtensa/xtensa/xtboard.h
new file mode 100644
--- /dev/null
+++ b/include/asm-xtensa/xtensa/xtboard.h
@@ -0,0 +1,120 @@
+#ifndef _xtboard_h_included_
+#define _xtboard_h_included_
+
+/*
+ * THIS FILE IS GENERATED -- DO NOT MODIFY BY HAND
+ *
+ *  xtboard.h  --  Routines for getting useful information from the board.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2002 Tensilica Inc.
+ */
+
+
+#include <xtensa/xt2000.h>
+
+#define	XTBOARD_RTC_ERROR	-1
+#define	XTBOARD_RTC_STOPPED	-2
+
+
+/*  xt2000-i2cdev.c:  */
+typedef void XtboardDelayFunc( unsigned );
+extern XtboardDelayFunc* xtboard_set_nsdelay_func( XtboardDelayFunc *delay_fn );
+extern int xtboard_i2c_read (unsigned id, unsigned char *buf, unsigned addr, unsigned size);
+extern int xtboard_i2c_write(unsigned id, unsigned char *buf, unsigned addr, unsigned size);
+extern int xtboard_i2c_wait_nvram_ack(unsigned id, unsigned swtimer);
+
+/*  xtboard.c:  */
+extern int xtboard_nvram_read (unsigned addr, unsigned len, unsigned char *buf);
+extern int xtboard_nvram_write(unsigned addr, unsigned len, unsigned char *buf);
+extern int xtboard_nvram_binfo_read (xt2000_nvram_binfo *buf);
+extern int xtboard_nvram_binfo_write(xt2000_nvram_binfo *buf);
+extern int xtboard_nvram_binfo_valid(xt2000_nvram_binfo *buf);
+extern int xtboard_ethermac_get(unsigned char *buf);
+extern int xtboard_ethermac_set(unsigned char *buf);
+
+/*+*----------------------------------------------------------------------------
+/ Function: xtboard_get_rtc_time
+/
+/ Description:  Get time stored in real-time clock.
+/
+/ Returns: time in seconds stored in real-time clock.
+/-**----------------------------------------------------------------------------*/
+
+extern unsigned xtboard_get_rtc_time(void);
+
+/*+*----------------------------------------------------------------------------
+/ Function: xtboard_set_rtc_time
+/
+/ Description:  Set time stored in real-time clock.
+/
+/ Parameters: 	time -- time in seconds to store to real-time clock
+/
+/ Returns: 0 on success, xtboard_i2c_write() error code otherwise.
+/-**----------------------------------------------------------------------------*/
+
+extern int xtboard_set_rtc_time(unsigned time);
+
+
+/*  xtfreq.c:  */
+/*+*----------------------------------------------------------------------------
+/ Function: xtboard_measure_sys_clk
+/
+/ Description:  Get frequency of system clock.
+/
+/ Parameters:	none
+/
+/ Returns: frequency of system clock.
+/-**----------------------------------------------------------------------------*/
+
+extern unsigned xtboard_measure_sys_clk(void);
+
+
+#if 0	/* old stuff from xtboard.c: */
+
+/*+*----------------------------------------------------------------------------
+/ Function: xtboard_nvram valid
+/
+/ Description:  Determines if data in NVRAM is valid.
+/
+/ Parameters:	delay -- 10us delay function
+/
+/ Returns: 1 if NVRAM is valid, 0 otherwise
+/-**----------------------------------------------------------------------------*/
+
+extern unsigned xtboard_nvram_valid(void (*delay)( void ));
+
+/*+*----------------------------------------------------------------------------
+/ Function: xtboard_get_nvram_contents
+/
+/ Description:  Returns contents of NVRAM.
+/
+/ Parameters: 	buf -- buffer to NVRAM contents.
+/		delay -- 10us delay function
+/
+/ Returns: 1 if NVRAM is valid, 0 otherwise
+/-**----------------------------------------------------------------------------*/
+
+extern unsigned xtboard_get_nvram_contents(unsigned char *buf, void (*delay)( void ));
+
+/*+*----------------------------------------------------------------------------
+/ Function: xtboard_get_ether_addr
+/
+/ Description:  Returns ethernet address of board.
+/
+/ Parameters: 	buf -- buffer to store ethernet address
+/		delay -- 10us delay function
+/
+/ Returns: nothing.
+/-**----------------------------------------------------------------------------*/
+
+extern void xtboard_get_ether_addr(unsigned char *buf, void (*delay)( void ));
+
+#endif /*0*/
+
+
+#endif /*_xtboard_h_included_*/
+
diff --git a/include/linux/a.out.h b/include/linux/a.out.h
--- a/include/linux/a.out.h
+++ b/include/linux/a.out.h
@@ -138,7 +138,7 @@ enum machine_type {
 #endif
 #endif
 
-#define _N_SEGMENT_ROUND(x) (((x) + SEGMENT_SIZE - 1) & ~(SEGMENT_SIZE - 1))
+#define _N_SEGMENT_ROUND(x) ALIGN(x, SEGMENT_SIZE)
 
 #define _N_TXTENDADDR(x) (N_TXTADDR(x)+(x).a_text)
 
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -206,7 +206,10 @@ struct acpi_table_plat_int_src {
 	u8			eid;
 	u8			iosapic_vector;
 	u32			global_irq;
-	u32			reserved;
+	struct {
+		u32			cpei_override_flag:1;
+		u32			reserved:31;
+	}			plint_flags;
 } __attribute__ ((packed));
 
 enum acpi_interrupt_id {
@@ -342,11 +345,19 @@ struct acpi_table_ecdt {
 
 /* PCI MMCONFIG */
 
+/* Defined in PCI Firmware Specification 3.0 */
+struct acpi_table_mcfg_config {
+	u32				base_address;
+	u32				base_reserved;
+	u16				pci_segment_group_number;
+	u8				start_bus_number;
+	u8				end_bus_number;
+	u8				reserved[4];
+} __attribute__ ((packed));
 struct acpi_table_mcfg {
 	struct acpi_table_header	header;
 	u8				reserved[8];
-	u32				base_address;
-	u32				base_reserved;
+	struct acpi_table_mcfg_config	config[0];
 } __attribute__ ((packed));
 
 /* Table Handlers */
@@ -391,6 +402,7 @@ int acpi_table_parse (enum acpi_table_id
 int acpi_get_table_header_early (enum acpi_table_id id, struct acpi_table_header **header);
 int acpi_table_parse_madt (enum acpi_madt_entry_id id, acpi_madt_entry_handler handler, unsigned int max_entries);
 int acpi_table_parse_srat (enum acpi_srat_entry_id id, acpi_madt_entry_handler handler, unsigned int max_entries);
+int acpi_parse_mcfg (unsigned long phys_addr, unsigned long size);
 void acpi_table_print (struct acpi_table_header *header, unsigned long phys_addr);
 void acpi_table_print_madt_entry (acpi_table_entry_header *madt);
 void acpi_table_print_srat_entry (acpi_table_entry_header *srat);
@@ -407,9 +419,13 @@ int acpi_map_lsapic(acpi_handle handle, 
 int acpi_unmap_lsapic(int cpu);
 #endif /* CONFIG_ACPI_HOTPLUG_CPU */
 
+int acpi_register_ioapic(acpi_handle handle, u64 phys_addr, u32 gsi_base);
+int acpi_unregister_ioapic(acpi_handle handle, u32 gsi_base);
+
 extern int acpi_mp_config;
 
-extern u32 pci_mmcfg_base_addr;
+extern struct acpi_table_mcfg_config *pci_mmcfg_config;
+extern int pci_mmcfg_config_num;
 
 extern int sbf_port ;
 
@@ -437,9 +453,7 @@ int acpi_gsi_to_irq (u32 gsi, unsigned i
  * If this matches the last registration, any IRQ resources for gsi
  * are freed.
  */
-#ifdef CONFIG_ACPI_DEALLOCATE_IRQ
 void acpi_unregister_gsi (u32 gsi);
-#endif
 
 #ifdef CONFIG_ACPI_PCI
 
@@ -462,11 +476,9 @@ struct acpi_prt_list {
 struct pci_dev;
 
 int acpi_pci_irq_enable (struct pci_dev *dev);
-void acpi_penalize_isa_irq(int irq);
+void acpi_penalize_isa_irq(int irq, int active);
 
-#ifdef CONFIG_ACPI_DEALLOCATE_IRQ
 void acpi_pci_irq_disable (struct pci_dev *dev);
-#endif
 
 struct acpi_pci_driver {
 	struct acpi_pci_driver *next;
diff --git a/include/linux/arcfb.h b/include/linux/arcfb.h
new file mode 100644
--- /dev/null
+++ b/include/linux/arcfb.h
@@ -0,0 +1,8 @@
+#ifndef __LINUX_ARCFB_H__
+#define __LINUX_ARCFB_H__
+
+#define FBIO_WAITEVENT		_IO('F', 0x88)
+#define FBIO_GETCONTROL2	_IOR('F', 0x89, size_t)
+
+#endif
+
diff --git a/include/linux/ata.h b/include/linux/ata.h
--- a/include/linux/ata.h
+++ b/include/linux/ata.h
@@ -224,6 +224,7 @@ struct ata_taskfile {
 };
 
 #define ata_id_is_ata(id)	(((id)[0] & (1 << 15)) == 0)
+#define ata_id_is_sata(id)	((id)[93] == 0)
 #define ata_id_rahead_enabled(id) ((id)[85] & (1 << 6))
 #define ata_id_wcache_enabled(id) ((id)[85] & (1 << 5))
 #define ata_id_has_flush(id) ((id)[83] & (1 << 12))
diff --git a/include/linux/atalk.h b/include/linux/atalk.h
--- a/include/linux/atalk.h
+++ b/include/linux/atalk.h
@@ -1,6 +1,8 @@
 #ifndef __LINUX_ATALK_H__
 #define __LINUX_ATALK_H__
 
+#include <asm/byteorder.h>
+
 /*
  * AppleTalk networking structures
  *
@@ -20,7 +22,7 @@
 #define SIOCATALKDIFADDR       (SIOCPROTOPRIVATE + 0)
 
 struct atalk_addr {
-	__u16	s_net;
+	__be16	s_net;
 	__u8	s_node;
 };
 
@@ -33,8 +35,8 @@ struct sockaddr_at {
 
 struct atalk_netrange {
 	__u8	nr_phase;
-	__u16	nr_firstnet;
-	__u16	nr_lastnet;
+	__be16	nr_firstnet;
+	__be16	nr_lastnet;
 };
 
 #ifdef __KERNEL__
@@ -70,8 +72,8 @@ struct atalk_iface {
 struct atalk_sock {
 	/* struct sock has to be the first member of atalk_sock */
 	struct sock	sk;
-	unsigned short	dest_net;
-	unsigned short	src_net;
+	__be16		dest_net;
+	__be16		src_net;
 	unsigned char	dest_node;
 	unsigned char	src_node;
 	unsigned char	dest_port;
@@ -95,9 +97,9 @@ struct ddpehdr {
 		deh_hops:4,
 		deh_len:10;
 #endif
-	__u16	deh_sum;
-	__u16	deh_dnet;
-	__u16	deh_snet;
+	__be16	deh_sum;
+	__be16	deh_dnet;
+	__be16	deh_snet;
 	__u8	deh_dnode;
 	__u8	deh_snode;
 	__u8	deh_dport;
@@ -142,24 +144,24 @@ struct ddpshdr {
 
 /* AppleTalk AARP headers */
 struct elapaarp {
-	__u16	hw_type;
+	__be16	hw_type;
 #define AARP_HW_TYPE_ETHERNET		1
 #define AARP_HW_TYPE_TOKENRING		2
-	__u16	pa_type;
+	__be16	pa_type;
 	__u8	hw_len;
 	__u8	pa_len;
 #define AARP_PA_ALEN			4
-	__u16	function;
+	__be16	function;
 #define AARP_REQUEST			1
 #define AARP_REPLY			2
 #define AARP_PROBE			3
 	__u8	hw_src[ETH_ALEN]	__attribute__ ((packed));
 	__u8	pa_src_zero		__attribute__ ((packed));
-	__u16	pa_src_net		__attribute__ ((packed));
+	__be16	pa_src_net		__attribute__ ((packed));
 	__u8	pa_src_node		__attribute__ ((packed));
 	__u8	hw_dst[ETH_ALEN]	__attribute__ ((packed));
 	__u8	pa_dst_zero		__attribute__ ((packed));
-	__u16	pa_dst_net		__attribute__ ((packed));
+	__be16	pa_dst_net		__attribute__ ((packed));
 	__u8	pa_dst_node		__attribute__ ((packed));	
 };
 
diff --git a/include/linux/audit.h b/include/linux/audit.h
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -27,15 +27,52 @@
 #include <linux/sched.h>
 #include <linux/elf.h>
 
-/* Request and reply types */
-#define AUDIT_GET      1000	/* Get status */
-#define AUDIT_SET      1001	/* Set status (enable/disable/auditd) */
-#define AUDIT_LIST     1002	/* List filtering rules */
-#define AUDIT_ADD      1003	/* Add filtering rule */
-#define AUDIT_DEL      1004	/* Delete filtering rule */
-#define AUDIT_USER     1005	/* Send a message from user-space */
-#define AUDIT_LOGIN    1006     /* Define the login id and informaiton */
-#define AUDIT_KERNEL   2000	/* Asynchronous audit record. NOT A REQUEST. */
+/* The netlink messages for the audit system is divided into blocks:
+ * 1000 - 1099 are for commanding the audit system
+ * 1100 - 1199 user space trusted application messages
+ * 1200 - 1299 messages internal to the audit daemon
+ * 1300 - 1399 audit event messages
+ * 1400 - 1499 SE Linux use
+ * 1500 - 1999 future use
+ * 2000 is for otherwise unclassified kernel audit messages
+ *
+ * Messages from 1000-1199 are bi-directional. 1200-1299 are exclusively user
+ * space. Anything over that is kernel --> user space communication.
+ */
+#define AUDIT_GET		1000	/* Get status */
+#define AUDIT_SET		1001	/* Set status (enable/disable/auditd) */
+#define AUDIT_LIST		1002	/* List syscall filtering rules */
+#define AUDIT_ADD		1003	/* Add syscall filtering rule */
+#define AUDIT_DEL		1004	/* Delete syscall filtering rule */
+#define AUDIT_USER		1005	/* Message from userspace -- deprecated */
+#define AUDIT_LOGIN		1006	/* Define the login id and information */
+#define AUDIT_WATCH_INS		1007	/* Insert file/dir watch entry */
+#define AUDIT_WATCH_REM		1008	/* Remove file/dir watch entry */
+#define AUDIT_WATCH_LIST	1009	/* List all file/dir watches */
+#define AUDIT_SIGNAL_INFO	1010	/* Get info about sender of signal to auditd */
+
+#define AUDIT_FIRST_USER_MSG	1100	/* Userspace messages uninteresting to kernel */
+#define AUDIT_LAST_USER_MSG	1199
+ 
+#define AUDIT_DAEMON_START      1200    /* Daemon startup record */
+#define AUDIT_DAEMON_END        1201    /* Daemon normal stop record */
+#define AUDIT_DAEMON_ABORT      1202    /* Daemon error stop record */
+#define AUDIT_DAEMON_CONFIG     1203    /* Daemon config change */
+
+#define AUDIT_SYSCALL		1300	/* Syscall event */
+#define AUDIT_FS_WATCH		1301	/* Filesystem watch event */
+#define AUDIT_PATH		1302	/* Filename path information */
+#define AUDIT_IPC		1303	/* IPC record */
+#define AUDIT_SOCKETCALL	1304	/* sys_socketcall arguments */
+#define AUDIT_CONFIG_CHANGE	1305	/* Audit system configuration change */
+#define AUDIT_SOCKADDR		1306	/* sockaddr copied as syscall arg */
+#define AUDIT_CWD		1307	/* Current working directory */
+
+#define AUDIT_AVC		1400	/* SE Linux avc denial or grant */
+#define AUDIT_SELINUX_ERR	1401	/* Internal SE Linux Errors */
+#define AUDIT_AVC_PATH		1402	/* dentry, vfsmount pair from avc */
+
+#define AUDIT_KERNEL		2000	/* Asynchronous audit record. NOT A REQUEST. */
 
 /* Rule flags */
 #define AUDIT_PER_TASK 0x01	/* Apply rule at task creation (not syscall) */
@@ -128,20 +165,13 @@
 #define AUDIT_ARCH_SH64		(EM_SH|__AUDIT_ARCH_64BIT)
 #define AUDIT_ARCH_SHEL64	(EM_SH|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
 #define AUDIT_ARCH_SPARC	(EM_SPARC)
-#define AUDIT_ARCH_SPARC64	(EM_SPARC64|__AUDIT_ARCH_64BIT)
+#define AUDIT_ARCH_SPARC64	(EM_SPARCV9|__AUDIT_ARCH_64BIT)
 #define AUDIT_ARCH_V850		(EM_V850|__AUDIT_ARCH_LE)
 #define AUDIT_ARCH_X86_64	(EM_X86_64|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
 
-#ifndef __KERNEL__
-struct audit_message {
-	struct nlmsghdr nlh;
-	char		data[1200];
-};
-#endif
-
 struct audit_status {
 	__u32		mask;		/* Bit mask for valid entries */
-	__u32		enabled;	/* 1 = enabled, 0 = disbaled */
+	__u32		enabled;	/* 1 = enabled, 0 = disabled */
 	__u32		failure;	/* Failure-to-log action */
 	__u32		pid;		/* pid of auditd process */
 	__u32		rate_limit;	/* messages rate limit (per second) */
@@ -161,6 +191,11 @@ struct audit_rule {		/* for AUDIT_LIST, 
 
 #ifdef __KERNEL__
 
+struct audit_sig_info {
+	uid_t		uid;
+	pid_t		pid;
+};
+
 struct audit_buffer;
 struct audit_context;
 struct inode;
@@ -185,11 +220,16 @@ extern void audit_inode(const char *name
 				/* Private API (for audit.c only) */
 extern int  audit_receive_filter(int type, int pid, int uid, int seq,
 				 void *data, uid_t loginuid);
-extern void audit_get_stamp(struct audit_context *ctx,
-			    struct timespec *t, unsigned int *serial);
+extern unsigned int audit_serial(void);
+extern void auditsc_get_stamp(struct audit_context *ctx,
+			      struct timespec *t, unsigned int *serial);
 extern int  audit_set_loginuid(struct task_struct *task, uid_t loginuid);
 extern uid_t audit_get_loginuid(struct audit_context *ctx);
 extern int audit_ipc_perms(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode);
+extern int audit_socketcall(int nargs, unsigned long *args);
+extern int audit_sockaddr(int len, void *addr);
+extern int audit_avc_path(struct dentry *dentry, struct vfsmount *mnt);
+extern void audit_signal_info(int sig, struct task_struct *t);
 #else
 #define audit_alloc(t) ({ 0; })
 #define audit_free(t) do { ; } while (0)
@@ -198,18 +238,24 @@ extern int audit_ipc_perms(unsigned long
 #define audit_getname(n) do { ; } while (0)
 #define audit_putname(n) do { ; } while (0)
 #define audit_inode(n,i) do { ; } while (0)
+#define audit_receive_filter(t,p,u,s,d,l) ({ -EOPNOTSUPP; })
+#define auditsc_get_stamp(c,t,s) do { BUG(); } while (0)
 #define audit_get_loginuid(c) ({ -1; })
 #define audit_ipc_perms(q,u,g,m) ({ 0; })
+#define audit_socketcall(n,a) ({ 0; })
+#define audit_sockaddr(len, addr) ({ 0; })
+#define audit_avc_path(dentry, mnt) ({ 0; })
+#define audit_signal_info(s,t) do { ; } while (0)
 #endif
 
 #ifdef CONFIG_AUDIT
 /* These are defined in audit.c */
 				/* Public API */
-extern void		    audit_log(struct audit_context *ctx,
+extern void		    audit_log(struct audit_context *ctx, int type,
 				      const char *fmt, ...)
-			    __attribute__((format(printf,2,3)));
+			    __attribute__((format(printf,3,4)));
 
-extern struct audit_buffer *audit_log_start(struct audit_context *ctx);
+extern struct audit_buffer *audit_log_start(struct audit_context *ctx,int type);
 extern void		    audit_log_format(struct audit_buffer *ab,
 					     const char *fmt, ...)
 			    __attribute__((format(printf,2,3)));
@@ -229,8 +275,8 @@ extern void		    audit_send_reply(int pi
 					     void *payload, int size);
 extern void		    audit_log_lost(const char *message);
 #else
-#define audit_log(t,f,...) do { ; } while (0)
-#define audit_log_start(t) ({ NULL; })
+#define audit_log(c,t,f,...) do { ; } while (0)
+#define audit_log_start(c,t) ({ NULL; })
 #define audit_log_vformat(b,f,a) do { ; } while (0)
 #define audit_log_format(b,f,...) do { ; } while (0)
 #define audit_log_end(b) do { ; } while (0)
diff --git a/include/linux/auto_fs4.h b/include/linux/auto_fs4.h
--- a/include/linux/auto_fs4.h
+++ b/include/linux/auto_fs4.h
@@ -23,7 +23,7 @@
 #define AUTOFS_MIN_PROTO_VERSION	3
 #define AUTOFS_MAX_PROTO_VERSION	4
 
-#define AUTOFS_PROTO_SUBVERSION		6
+#define AUTOFS_PROTO_SUBVERSION		7
 
 /* Mask for expire behaviour */
 #define AUTOFS_EXP_IMMEDIATE		1
diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h
--- a/include/linux/binfmts.h
+++ b/include/linux/binfmts.h
@@ -69,6 +69,11 @@ extern void remove_arg_zero(struct linux
 extern int search_binary_handler(struct linux_binprm *,struct pt_regs *);
 extern int flush_old_exec(struct linux_binprm * bprm);
 
+extern int suid_dumpable;
+#define SUID_DUMP_DISABLE	0	/* No setuid dumping */
+#define SUID_DUMP_USER		1	/* Dump as user of process */
+#define SUID_DUMP_ROOT		2	/* Dump as root */
+
 /* Stack area protections */
 #define EXSTACK_DEFAULT   0	/* Whatever the arch defaults to */
 #define EXSTACK_DISABLE_X 1	/* Disable executable stacks */
diff --git a/include/linux/bio.h b/include/linux/bio.h
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -22,6 +22,7 @@
 
 #include <linux/highmem.h>
 #include <linux/mempool.h>
+#include <linux/ioprio.h>
 
 /* Platforms may set this to teach the BIO layer about IOMMU hardware. */
 #include <asm/io.h>
@@ -150,6 +151,19 @@ struct bio {
 #define BIO_RW_SYNC	4
 
 /*
+ * upper 16 bits of bi_rw define the io priority of this bio
+ */
+#define BIO_PRIO_SHIFT	(8 * sizeof(unsigned long) - IOPRIO_BITS)
+#define bio_prio(bio)	((bio)->bi_rw >> BIO_PRIO_SHIFT)
+#define bio_prio_valid(bio)	ioprio_valid(bio_prio(bio))
+
+#define bio_set_prio(bio, prio)		do {			\
+	WARN_ON(prio >= (1 << IOPRIO_BITS));			\
+	(bio)->bi_rw &= ((1UL << BIO_PRIO_SHIFT) - 1);		\
+	(bio)->bi_rw |= ((unsigned long) (prio) << BIO_PRIO_SHIFT);	\
+} while (0)
+
+/*
  * various member access, note that bio_data should of course not be used
  * on highmem page vectors
  */
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -54,16 +54,23 @@ struct as_io_context {
 
 struct cfq_queue;
 struct cfq_io_context {
-	void (*dtor)(struct cfq_io_context *);
-	void (*exit)(struct cfq_io_context *);
-
-	struct io_context *ioc;
-
 	/*
 	 * circular list of cfq_io_contexts belonging to a process io context
 	 */
 	struct list_head list;
 	struct cfq_queue *cfqq;
+	void *key;
+
+	struct io_context *ioc;
+
+	unsigned long last_end_request;
+	unsigned long last_queue;
+	unsigned long ttime_total;
+	unsigned long ttime_samples;
+	unsigned long ttime_mean;
+
+	void (*dtor)(struct cfq_io_context *);
+	void (*exit)(struct cfq_io_context *);
 };
 
 /*
@@ -73,7 +80,9 @@ struct cfq_io_context {
  */
 struct io_context {
 	atomic_t refcount;
-	pid_t pid;
+	struct task_struct *task;
+
+	int (*set_ioprio)(struct io_context *, unsigned int);
 
 	/*
 	 * For request batching
@@ -81,14 +90,13 @@ struct io_context {
 	unsigned long last_waited; /* Time last woken after wait for request */
 	int nr_batch_requests;     /* Number of requests left in the batch */
 
-	spinlock_t lock;
-
 	struct as_io_context *aic;
 	struct cfq_io_context *cic;
 };
 
 void put_io_context(struct io_context *ioc);
 void exit_io_context(void);
+struct io_context *current_io_context(int gfp_flags);
 struct io_context *get_io_context(int gfp_flags);
 void copy_io_context(struct io_context **pdst, struct io_context **psrc);
 void swap_io_context(struct io_context **ioc1, struct io_context **ioc2);
@@ -134,6 +142,8 @@ struct request {
 
 	void *elevator_private;
 
+	unsigned short ioprio;
+
 	int rq_status;	/* should split this into a few status bits */
 	struct gendisk *rq_disk;
 	int errors;
@@ -285,9 +295,6 @@ enum blk_queue_state {
 	Queue_up,
 };
 
-#define BLK_TAGS_PER_LONG	(sizeof(unsigned long) * 8)
-#define BLK_TAGS_MASK		(BLK_TAGS_PER_LONG - 1)
-
 struct blk_queue_tag {
 	struct request **tag_index;	/* map of busy tags */
 	unsigned long *tag_map;		/* bit map of free/busy tags */
@@ -396,6 +403,7 @@ struct request_queue
 	 */
 	unsigned int		sg_timeout;
 	unsigned int		sg_reserved_size;
+	int			node;
 
 	struct list_head	drain_list;
 
@@ -542,15 +550,12 @@ extern void generic_make_request(struct 
 extern void blk_put_request(struct request *);
 extern void blk_end_sync_rq(struct request *rq);
 extern void blk_attempt_remerge(request_queue_t *, struct request *);
-extern void __blk_attempt_remerge(request_queue_t *, struct request *);
 extern struct request *blk_get_request(request_queue_t *, int, int);
-extern void blk_insert_request(request_queue_t *, struct request *, int, void *, int);
+extern void blk_insert_request(request_queue_t *, struct request *, int, void *);
 extern void blk_requeue_request(request_queue_t *, struct request *);
 extern void blk_plug_device(request_queue_t *);
 extern int blk_remove_plug(request_queue_t *);
 extern void blk_recount_segments(request_queue_t *, struct bio *);
-extern int blk_phys_contig_segment(request_queue_t *q, struct bio *, struct bio *);
-extern int blk_hw_contig_segment(request_queue_t *q, struct bio *, struct bio *);
 extern int scsi_cmd_ioctl(struct file *, struct gendisk *, unsigned int, void __user *);
 extern void blk_start_queue(request_queue_t *q);
 extern void blk_stop_queue(request_queue_t *q);
@@ -615,6 +620,8 @@ static inline void blkdev_dequeue_reques
 /*
  * Access functions for manipulating queue properties
  */
+extern request_queue_t *blk_init_queue_node(request_fn_proc *rfn,
+					spinlock_t *lock, int node_id);
 extern request_queue_t *blk_init_queue(request_fn_proc *, spinlock_t *);
 extern void blk_cleanup_queue(request_queue_t *);
 extern void blk_queue_make_request(request_queue_t *, make_request_fn *);
@@ -632,7 +639,6 @@ extern void blk_queue_dma_alignment(requ
 extern struct backing_dev_info *blk_get_backing_dev_info(struct block_device *bdev);
 extern void blk_queue_ordered(request_queue_t *, int);
 extern void blk_queue_issue_flush_fn(request_queue_t *, issue_flush_fn *);
-extern int blkdev_scsi_issue_flush_fn(request_queue_t *, struct gendisk *, sector_t *);
 extern struct request *blk_start_pre_flush(request_queue_t *,struct request *);
 extern int blk_complete_barrier_rq(request_queue_t *, struct request *, int);
 extern int blk_complete_barrier_rq_locked(request_queue_t *, struct request *, int);
@@ -646,7 +652,8 @@ extern void blk_wait_queue_drained(reque
 extern void blk_finish_queue_drain(request_queue_t *);
 
 int blk_get_queue(request_queue_t *);
-request_queue_t *blk_alloc_queue(int);
+request_queue_t *blk_alloc_queue(int gfp_mask);
+request_queue_t *blk_alloc_queue_node(int,int);
 #define blk_put_queue(q) blk_cleanup_queue((q))
 
 /*
@@ -675,8 +682,6 @@ extern int blkdev_issue_flush(struct blo
 
 #define blkdev_entry_to_request(entry) list_entry((entry), struct request, queuelist)
 
-extern void drive_stat_acct(struct request *, int, int);
-
 static inline int queue_hardsect_size(request_queue_t *q)
 {
 	int retval = 512;
diff --git a/include/linux/bootmem.h b/include/linux/bootmem.h
--- a/include/linux/bootmem.h
+++ b/include/linux/bootmem.h
@@ -22,6 +22,10 @@ extern unsigned long min_low_pfn;
  */
 extern unsigned long max_pfn;
 
+#ifdef CONFIG_CRASH_DUMP
+extern unsigned long saved_max_pfn;
+#endif
+
 /*
  * node_bootmem_map is a map pointer - the bits represent all physical 
  * memory pages (including holes) on the node.
@@ -67,6 +71,15 @@ extern void * __init __alloc_bootmem_nod
 	__alloc_bootmem_node((pgdat), (x), PAGE_SIZE, 0)
 #endif /* !CONFIG_HAVE_ARCH_BOOTMEM_NODE */
 
+#ifdef CONFIG_HAVE_ARCH_ALLOC_REMAP
+extern void *alloc_remap(int nid, unsigned long size);
+#else
+static inline void *alloc_remap(int nid, unsigned long size)
+{
+	return NULL;
+}
+#endif
+
 extern unsigned long __initdata nr_kernel_pages;
 extern unsigned long __initdata nr_all_pages;
 
diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h
--- a/include/linux/buffer_head.h
+++ b/include/linux/buffer_head.h
@@ -19,6 +19,9 @@ enum bh_state_bits {
 	BH_Dirty,	/* Is dirty */
 	BH_Lock,	/* Is locked */
 	BH_Req,		/* Has been submitted for I/O */
+	BH_Uptodate_Lock,/* Used by the first bh in a page, to serialise
+			  * IO completion of other buffers in the page
+			  */
 
 	BH_Mapped,	/* Has a disk mapping */
 	BH_New,		/* Disk mapping was newly created by get_block */
diff --git a/include/linux/byteorder/swabb.h b/include/linux/byteorder/swabb.h
--- a/include/linux/byteorder/swabb.h
+++ b/include/linux/byteorder/swabb.h
@@ -92,29 +92,32 @@
 #endif /* OPTIMIZE */
 
 
-static __inline__ __const__ __u32 __fswahw32(__u32 x)
+static inline __u32 __fswahw32(__u32 x)
 {
 	return __arch__swahw32(x);
 }
-static __inline__ __u32 __swahw32p(__u32 *x)
+
+static inline __u32 __swahw32p(__u32 *x)
 {
 	return __arch__swahw32p(x);
 }
-static __inline__ void __swahw32s(__u32 *addr)
+
+static inline void __swahw32s(__u32 *addr)
 {
 	__arch__swahw32s(addr);
 }
 
-
-static __inline__ __const__ __u32 __fswahb32(__u32 x)
+static inline __u32 __fswahb32(__u32 x)
 {
 	return __arch__swahb32(x);
 }
-static __inline__ __u32 __swahb32p(__u32 *x)
+
+static inline __u32 __swahb32p(__u32 *x)
 {
 	return __arch__swahb32p(x);
 }
-static __inline__ void __swahb32s(__u32 *addr)
+
+static inline void __swahb32s(__u32 *addr)
 {
 	__arch__swahb32s(addr);
 }
diff --git a/include/linux/cache.h b/include/linux/cache.h
--- a/include/linux/cache.h
+++ b/include/linux/cache.h
@@ -13,6 +13,12 @@
 #define SMP_CACHE_BYTES L1_CACHE_BYTES
 #endif
 
+#if defined(CONFIG_X86) || defined(CONFIG_SPARC64)
+#define __read_mostly __attribute__((__section__(".data.read_mostly")))
+#else
+#define __read_mostly
+#endif
+
 #ifndef ____cacheline_aligned
 #define ____cacheline_aligned __attribute__((__aligned__(SMP_CACHE_BYTES)))
 #endif
diff --git a/include/linux/cciss_ioctl.h b/include/linux/cciss_ioctl.h
--- a/include/linux/cciss_ioctl.h
+++ b/include/linux/cciss_ioctl.h
@@ -10,6 +10,7 @@
 typedef struct _cciss_pci_info_struct
 {
 	unsigned char 	bus;
+	unsigned short	domain;
 	unsigned char 	dev_fn;
 	__u32 		board_id;
 } cciss_pci_info_struct; 
diff --git a/include/linux/chio.h b/include/linux/chio.h
new file mode 100644
--- /dev/null
+++ b/include/linux/chio.h
@@ -0,0 +1,168 @@
+/*
+ * ioctl interface for the scsi media changer driver
+ */
+
+/* changer element types */
+#define CHET_MT   0	/* media transport element (robot) */
+#define CHET_ST   1	/* storage element (media slots) */
+#define CHET_IE   2	/* import/export element */
+#define CHET_DT   3	/* data transfer element (tape/cdrom/whatever) */
+#define CHET_V1   4	/* vendor specific #1 */
+#define CHET_V2   5	/* vendor specific #2 */
+#define CHET_V3   6	/* vendor specific #3 */
+#define CHET_V4   7	/* vendor specific #4 */
+
+
+/*
+ * CHIOGPARAMS
+ *    query changer properties
+ *
+ * CHIOVGPARAMS
+ *    query vendor-specific element types
+ *
+ *    accessing elements works by specifing type and unit of the element.
+ *    for eample, storage elements are addressed with type = CHET_ST and
+ *    unit = 0 .. cp_nslots-1
+ *
+ */
+struct changer_params {
+	int cp_curpicker;  /* current transport element */
+	int cp_npickers;   /* number of transport elements      (CHET_MT) */
+	int cp_nslots;     /* number of storage elements        (CHET_ST) */
+	int cp_nportals;   /* number of import/export elements  (CHET_IE) */
+	int cp_ndrives;    /* number of data transfer elements  (CHET_DT) */
+};
+struct changer_vendor_params {
+	int  cvp_n1;       /* number of vendor specific elems   (CHET_V1) */
+	char cvp_label1[16];
+	int  cvp_n2;       /* number of vendor specific elems   (CHET_V2) */
+	char cvp_label2[16];
+	int  cvp_n3;       /* number of vendor specific elems   (CHET_V3) */
+	char cvp_label3[16];
+	int  cvp_n4;       /* number of vendor specific elems   (CHET_V4) */
+	char cvp_label4[16];
+	int  reserved[8];
+};
+
+
+/*
+ * CHIOMOVE
+ *    move a medium from one element to another
+ */
+struct changer_move {
+	int cm_fromtype;	/* type/unit of source element */
+	int cm_fromunit;	
+	int cm_totype;	/* type/unit of destination element */
+	int cm_tounit;
+	int cm_flags;
+};
+#define CM_INVERT   1   /* flag: rotate media (for double-sided like MOD) */
+
+
+/*
+ * CHIOEXCHANGE
+ *    move one medium from element #1 to element #2,
+ *    and another one from element #2 to element #3.
+ *    element #1 and #3 are allowed to be identical.
+ */
+struct changer_exchange {
+	int ce_srctype;	    /* type/unit of element #1 */
+	int ce_srcunit;
+	int ce_fdsttype;    /* type/unit of element #2 */
+	int ce_fdstunit;
+	int ce_sdsttype;    /* type/unit of element #3 */
+	int ce_sdstunit;
+	int ce_flags;
+};
+#define CE_INVERT1   1
+#define CE_INVERT2   2
+
+
+/*
+ * CHIOPOSITION
+ *    move the transport element (robot arm) to a specific element.
+ */
+struct changer_position {
+	int cp_type;
+	int cp_unit;
+	int cp_flags;
+};
+#define CP_INVERT   1
+
+
+/*
+ * CHIOGSTATUS
+ *    get element status for all elements of a specific type
+ */
+struct changer_element_status {
+	int             ces_type;
+	unsigned char   *ces_data;
+};
+#define CESTATUS_FULL     0x01 /* full */
+#define CESTATUS_IMPEXP   0x02	/* media was imported (inserted by sysop) */
+#define CESTATUS_EXCEPT   0x04	/* error condition */
+#define CESTATUS_ACCESS   0x08	/* access allowed */
+#define CESTATUS_EXENAB   0x10	/* element can export media */
+#define CESTATUS_INENAB   0x20	/* element can import media */
+
+
+/*
+ * CHIOGELEM
+ *    get more detailed status informtion for a single element
+ */
+struct changer_get_element {
+	int	cge_type;	 /* type/unit */
+	int	cge_unit;
+	int	cge_status;      /* status */
+	int     cge_errno;       /* errno */
+	int     cge_srctype;     /* source element of the last move/exchange */
+	int     cge_srcunit;
+	int     cge_id;          /* scsi id  (for data transfer elements) */
+	int     cge_lun;         /* scsi lun (for data transfer elements) */
+	char    cge_pvoltag[36]; /* primary volume tag */
+	char    cge_avoltag[36]; /* alternate volume tag */
+	int     cge_flags;
+};
+/* flags */
+#define CGE_ERRNO     0x01       /* errno available       */
+#define CGE_INVERT    0x02       /* media inverted        */
+#define CGE_SRC       0x04       /* media src available   */
+#define CGE_IDLUN     0x08       /* ID+LUN available      */
+#define CGE_PVOLTAG   0x10       /* primary volume tag available */
+#define CGE_AVOLTAG   0x20       /* alternate volume tag available */
+
+
+/*
+ * CHIOSVOLTAG
+ *    set volume tag
+ */
+struct changer_set_voltag {
+	int	csv_type;	 /* type/unit */
+	int	csv_unit;
+	char    csv_voltag[36];  /* volume tag */
+	int     csv_flags;
+};
+#define CSV_PVOLTAG   0x01       /* primary volume tag */
+#define CSV_AVOLTAG   0x02       /* alternate volume tag */
+#define CSV_CLEARTAG  0x04       /* clear volume tag */
+
+/* ioctls */
+#define CHIOMOVE       _IOW('c', 1,struct changer_move)
+#define CHIOEXCHANGE   _IOW('c', 2,struct changer_exchange)
+#define CHIOPOSITION   _IOW('c', 3,struct changer_position)
+#define CHIOGPICKER    _IOR('c', 4,int)                        /* not impl. */
+#define CHIOSPICKER    _IOW('c', 5,int)                        /* not impl. */
+#define CHIOGPARAMS    _IOR('c', 6,struct changer_params)
+#define CHIOGSTATUS    _IOW('c', 8,struct changer_element_status)
+#define CHIOGELEM      _IOW('c',16,struct changer_get_element)
+#define CHIOINITELEM   _IO('c',17)
+#define CHIOSVOLTAG    _IOW('c',18,struct changer_set_voltag)
+#define CHIOGVPARAMS   _IOR('c',19,struct changer_vendor_params)
+
+/* ---------------------------------------------------------------------- */
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/include/linux/compat_ioctl.h b/include/linux/compat_ioctl.h
--- a/include/linux/compat_ioctl.h
+++ b/include/linux/compat_ioctl.h
@@ -346,10 +346,27 @@ COMPATIBLE_IOCTL(PPPOEIOCDFWD)
 /* LP */
 COMPATIBLE_IOCTL(LPGETSTATUS)
 /* ppdev */
+COMPATIBLE_IOCTL(PPSETMODE)
+COMPATIBLE_IOCTL(PPRSTATUS)
+COMPATIBLE_IOCTL(PPRCONTROL)
+COMPATIBLE_IOCTL(PPWCONTROL)
+COMPATIBLE_IOCTL(PPFCONTROL)
+COMPATIBLE_IOCTL(PPRDATA)
+COMPATIBLE_IOCTL(PPWDATA)
 COMPATIBLE_IOCTL(PPCLAIM)
 COMPATIBLE_IOCTL(PPRELEASE)
-COMPATIBLE_IOCTL(PPEXCL)
 COMPATIBLE_IOCTL(PPYIELD)
+COMPATIBLE_IOCTL(PPEXCL)
+COMPATIBLE_IOCTL(PPDATADIR)
+COMPATIBLE_IOCTL(PPNEGOT)
+COMPATIBLE_IOCTL(PPWCTLONIRQ)
+COMPATIBLE_IOCTL(PPCLRIRQ)
+COMPATIBLE_IOCTL(PPSETPHASE)
+COMPATIBLE_IOCTL(PPGETMODES)
+COMPATIBLE_IOCTL(PPGETMODE)
+COMPATIBLE_IOCTL(PPGETPHASE)
+COMPATIBLE_IOCTL(PPGETFLAGS)
+COMPATIBLE_IOCTL(PPSETFLAGS)
 /* CDROM stuff */
 COMPATIBLE_IOCTL(CDROMPAUSE)
 COMPATIBLE_IOCTL(CDROMRESUME)
diff --git a/include/linux/cpu.h b/include/linux/cpu.h
--- a/include/linux/cpu.h
+++ b/include/linux/cpu.h
@@ -69,6 +69,7 @@ extern struct semaphore cpucontrol;
 	register_cpu_notifier(&fn##_nb);			\
 }
 int cpu_down(unsigned int cpu);
+extern int __attribute__((weak)) smp_prepare_cpu(int cpu);
 #define cpu_is_offline(cpu) unlikely(!cpu_online(cpu))
 #else
 #define lock_cpu_hotplug()	do { } while (0)
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
--- a/include/linux/cpufreq.h
+++ b/include/linux/cpufreq.h
@@ -201,7 +201,7 @@ struct cpufreq_driver {
 
 	/* optional */
 	int	(*exit)		(struct cpufreq_policy *policy);
-	int	(*suspend)	(struct cpufreq_policy *policy, u32 state);
+	int	(*suspend)	(struct cpufreq_policy *policy, pm_message_t pmsg);
 	int	(*resume)	(struct cpufreq_policy *policy);
 	struct freq_attr	**attr;
 };
diff --git a/include/linux/crash_dump.h b/include/linux/crash_dump.h
new file mode 100644
--- /dev/null
+++ b/include/linux/crash_dump.h
@@ -0,0 +1,18 @@
+#ifndef LINUX_CRASH_DUMP_H
+#define LINUX_CRASH_DUMP_H
+
+#ifdef CONFIG_CRASH_DUMP
+#include <linux/kexec.h>
+#include <linux/smp_lock.h>
+#include <linux/device.h>
+#include <linux/proc_fs.h>
+
+#define ELFCORE_ADDR_MAX	(-1ULL)
+extern unsigned long long elfcorehdr_addr;
+extern ssize_t copy_oldmem_page(unsigned long, char *, size_t,
+						unsigned long, int);
+extern struct file_operations proc_vmcore_operations;
+extern struct proc_dir_entry *proc_vmcore;
+
+#endif /* CONFIG_CRASH_DUMP */
+#endif /* LINUX_CRASHDUMP_H */
diff --git a/include/linux/crypto.h b/include/linux/crypto.h
--- a/include/linux/crypto.h
+++ b/include/linux/crypto.h
@@ -61,6 +61,15 @@
 #define CRYPTO_DIR_DECRYPT		0
 
 struct scatterlist;
+struct crypto_tfm;
+
+struct cipher_desc {
+	struct crypto_tfm *tfm;
+	void (*crfn)(void *ctx, u8 *dst, const u8 *src);
+	unsigned int (*prfn)(const struct cipher_desc *desc, u8 *dst,
+			     const u8 *src, unsigned int nbytes);
+	void *info;
+};
 
 /*
  * Algorithms: modular crypto algorithm implementations, managed
@@ -73,6 +82,19 @@ struct cipher_alg {
 	                  unsigned int keylen, u32 *flags);
 	void (*cia_encrypt)(void *ctx, u8 *dst, const u8 *src);
 	void (*cia_decrypt)(void *ctx, u8 *dst, const u8 *src);
+
+	unsigned int (*cia_encrypt_ecb)(const struct cipher_desc *desc,
+					u8 *dst, const u8 *src,
+					unsigned int nbytes);
+	unsigned int (*cia_decrypt_ecb)(const struct cipher_desc *desc,
+					u8 *dst, const u8 *src,
+					unsigned int nbytes);
+	unsigned int (*cia_encrypt_cbc)(const struct cipher_desc *desc,
+					u8 *dst, const u8 *src,
+					unsigned int nbytes);
+	unsigned int (*cia_decrypt_cbc)(const struct cipher_desc *desc,
+					u8 *dst, const u8 *src,
+					unsigned int nbytes);
 };
 
 struct digest_alg {
@@ -102,6 +124,7 @@ struct crypto_alg {
 	u32 cra_flags;
 	unsigned int cra_blocksize;
 	unsigned int cra_ctxsize;
+	unsigned int cra_alignmask;
 	const char cra_name[CRYPTO_MAX_ALG_NAME];
 
 	union {
@@ -136,7 +159,6 @@ static inline int crypto_alg_available(c
  * and core processing logic.  Managed via crypto_alloc_tfm() and
  * crypto_free_tfm(), as well as the various helpers below.
  */
-struct crypto_tfm;
 
 struct cipher_tfm {
 	void *cit_iv;
@@ -266,6 +288,16 @@ static inline unsigned int crypto_tfm_al
 	return tfm->__crt_alg->cra_digest.dia_digestsize;
 }
 
+static inline unsigned int crypto_tfm_alg_alignmask(struct crypto_tfm *tfm)
+{
+	return tfm->__crt_alg->cra_alignmask;
+}
+
+static inline void *crypto_tfm_ctx(struct crypto_tfm *tfm)
+{
+	return (void *)&tfm[1];
+}
+
 /*
  * API wrappers.
  */
diff --git a/include/linux/dcookies.h b/include/linux/dcookies.h
--- a/include/linux/dcookies.h
+++ b/include/linux/dcookies.h
@@ -48,12 +48,12 @@ int get_dcookie(struct dentry * dentry, 
 
 #else
 
-struct dcookie_user * dcookie_register(void)
+static inline struct dcookie_user * dcookie_register(void)
 {
 	return NULL;
 }
 
-void dcookie_unregister(struct dcookie_user * user)
+static inline void dcookie_unregister(struct dcookie_user * user)
 {
 	return;
 }
diff --git a/include/linux/device.h b/include/linux/device.h
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -14,6 +14,7 @@
 #include <linux/config.h>
 #include <linux/ioport.h>
 #include <linux/kobject.h>
+#include <linux/klist.h>
 #include <linux/list.h>
 #include <linux/types.h>
 #include <linux/module.h>
@@ -44,14 +45,15 @@ struct device;
 struct device_driver;
 struct class;
 struct class_device;
-struct class_simple;
 
 struct bus_type {
-	char			* name;
+	const char		* name;
 
 	struct subsystem	subsys;
 	struct kset		drivers;
 	struct kset		devices;
+	struct klist		klist_devices;
+	struct klist		klist_drivers;
 
 	struct bus_attribute	* bus_attrs;
 	struct device_attribute	* dev_attrs;
@@ -67,7 +69,7 @@ struct bus_type {
 extern int bus_register(struct bus_type * bus);
 extern void bus_unregister(struct bus_type * bus);
 
-extern int bus_rescan_devices(struct bus_type * bus);
+extern void bus_rescan_devices(struct bus_type * bus);
 
 extern struct bus_type * get_bus(struct bus_type * bus);
 extern void put_bus(struct bus_type * bus);
@@ -78,6 +80,8 @@ extern struct bus_type * find_bus(char *
 
 int bus_for_each_dev(struct bus_type * bus, struct device * start, void * data,
 		     int (*fn)(struct device *, void *));
+struct device * bus_find_device(struct bus_type *bus, struct device *start,
+				void *data, int (*match)(struct device *, void *));
 
 int bus_for_each_drv(struct bus_type * bus, struct device_driver * start, 
 		     void * data, int (*fn)(struct device_driver *, void *));
@@ -98,17 +102,18 @@ extern int bus_create_file(struct bus_ty
 extern void bus_remove_file(struct bus_type *, struct bus_attribute *);
 
 struct device_driver {
-	char			* name;
+	const char		* name;
 	struct bus_type		* bus;
 
 	struct completion	unloaded;
 	struct kobject		kobj;
-	struct list_head	devices;
+	struct klist		klist_devices;
+	struct klist_node	knode_bus;
 
-	struct module 		* owner;
+	struct module		* owner;
 
 	int	(*probe)	(struct device * dev);
-	int 	(*remove)	(struct device * dev);
+	int	(*remove)	(struct device * dev);
 	void	(*shutdown)	(struct device * dev);
 	int	(*suspend)	(struct device * dev, pm_message_t state, u32 level);
 	int	(*resume)	(struct device * dev, u32 level);
@@ -137,12 +142,19 @@ struct driver_attribute driver_attr_##_n
 extern int driver_create_file(struct device_driver *, struct driver_attribute *);
 extern void driver_remove_file(struct device_driver *, struct driver_attribute *);
 
+extern int driver_for_each_device(struct device_driver * drv, struct device * start,
+				  void * data, int (*fn)(struct device *, void *));
+struct device * driver_find_device(struct device_driver *drv,
+				   struct device *start, void *data,
+				   int (*match)(struct device *, void *));
+
 
 /*
  * device classes
  */
 struct class {
-	char			* name;
+	const char		* name;
+	struct module		* owner;
 
 	struct subsystem	subsys;
 	struct list_head	children;
@@ -185,6 +197,7 @@ struct class_device {
 	struct kobject		kobj;
 	struct class		* class;	/* required */
 	dev_t			devt;		/* dev_t, creates the sysfs "dev" */
+	struct class_device_attribute *devt_attr;
 	struct device		* dev;		/* not necessary, but nice to have */
 	void			* class_data;	/* class-specific data */
 
@@ -245,32 +258,36 @@ struct class_interface {
 extern int class_interface_register(struct class_interface *);
 extern void class_interface_unregister(struct class_interface *);
 
-/* interface for class simple stuff */
-extern struct class_simple *class_simple_create(struct module *owner, char *name);
-extern void class_simple_destroy(struct class_simple *cs);
-extern struct class_device *class_simple_device_add(struct class_simple *cs, dev_t dev, struct device *device, const char *fmt, ...)
-	__attribute__((format(printf,4,5)));
-extern int class_simple_set_hotplug(struct class_simple *, 
-	int (*hotplug)(struct class_device *dev, char **envp, int num_envp, char *buffer, int buffer_size));
-extern void class_simple_device_remove(dev_t dev);
+extern struct class *class_create(struct module *owner, char *name);
+extern void class_destroy(struct class *cls);
+extern struct class_device *class_device_create(struct class *cls, dev_t devt,
+						struct device *device, char *fmt, ...)
+					__attribute__((format(printf,4,5)));
+extern void class_device_destroy(struct class *cls, dev_t devt);
 
 
 struct device {
-	struct list_head node;		/* node in sibling list */
-	struct list_head bus_list;	/* node in bus's list */
-	struct list_head driver_list;
-	struct list_head children;
+	struct klist		klist_children;
+	struct klist_node	knode_parent;		/* node in sibling list */
+	struct klist_node	knode_driver;
+	struct klist_node	knode_bus;
 	struct device 	* parent;
 
 	struct kobject kobj;
 	char	bus_id[BUS_ID_SIZE];	/* position on parent bus */
 
+	struct semaphore	sem;	/* semaphore to synchronize calls to
+					 * its driver.
+					 */
+
 	struct bus_type	* bus;		/* type of bus device is on */
 	struct device_driver *driver;	/* which driver has allocated this
 					   device */
 	void		*driver_data;	/* data private to the driver */
-	void		*platform_data;	/* Platform specific data (e.g. ACPI,
-					   BIOS data relevant to device) */
+	void		*platform_data;	/* Platform specific data, device
+					   core doesn't touch it */
+	void		*firmware_data; /* Firmware specific data (e.g. ACPI,
+					   BIOS data),reserved for device core*/
 	struct dev_pm_info	power;
 
 	u64		*dma_mask;	/* dma mask (if dma'able device) */
@@ -288,12 +305,6 @@ struct device {
 	void	(*release)(struct device * dev);
 };
 
-static inline struct device *
-list_to_dev(struct list_head *node)
-{
-	return list_entry(node, struct device, node);
-}
-
 static inline void *
 dev_get_drvdata (struct device *dev)
 {
@@ -321,7 +332,6 @@ extern int device_for_each_child(struct 
  * Manual binding of a device to driver. See drivers/base/bus.c
  * for information on use.
  */
-extern int  driver_probe_device(struct device_driver * drv, struct device * dev);
 extern void device_bind_driver(struct device * dev);
 extern void device_release_driver(struct device * dev);
 extern int  device_attach(struct device * dev);
@@ -332,8 +342,10 @@ extern void driver_attach(struct device_
 
 struct device_attribute {
 	struct attribute	attr;
-	ssize_t (*show)(struct device * dev, char * buf);
-	ssize_t (*store)(struct device * dev, const char * buf, size_t count);
+	ssize_t (*show)(struct device *dev, struct device_attribute *attr,
+			char *buf);
+	ssize_t (*store)(struct device *dev, struct device_attribute *attr,
+			 const char *buf, size_t count);
 };
 
 #define DEVICE_ATTR(_name,_mode,_show,_store) \
@@ -360,13 +372,12 @@ extern int (*platform_notify_remove)(str
  */
 extern struct device * get_device(struct device * dev);
 extern void put_device(struct device * dev);
-extern struct device *device_find(const char *name, struct bus_type *bus);
 
 
 /* drivers/base/platform.c */
 
 struct platform_device {
-	char		* name;
+	const char	* name;
 	u32		id;
 	struct device	dev;
 	u32		num_resources;
diff --git a/include/linux/dm9000.h b/include/linux/dm9000.h
new file mode 100644
--- /dev/null
+++ b/include/linux/dm9000.h
@@ -0,0 +1,36 @@
+/* include/linux/dm9000.h
+ *
+ * Copyright (c) 2004 Simtec Electronics
+ *   Ben Dooks <ben@simtec.co.uk>
+ *
+ * Header file for dm9000 platform data
+ *
+ * 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.
+ *
+*/
+
+#ifndef __DM9000_PLATFORM_DATA
+#define __DM9000_PLATFORM_DATA __FILE__
+
+/* IO control flags */
+
+#define DM9000_PLATF_8BITONLY	(0x0001)
+#define DM9000_PLATF_16BITONLY	(0x0002)
+#define DM9000_PLATF_32BITONLY	(0x0004)
+
+/* platfrom data for platfrom device structure's platfrom_data field */
+
+struct dm9000_plat_data {
+	unsigned int	flags;
+
+	/* allow replacement IO routines */
+
+	void	(*inblk)(void __iomem *reg, void *data, int len);
+	void	(*outblk)(void __iomem *reg, void *data, int len);
+	void	(*dumpblk)(void __iomem *reg, int len);
+};
+
+#endif /* __DM9000_PLATFORM_DATA */
+
diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
--- a/include/linux/dma-mapping.h
+++ b/include/linux/dma-mapping.h
@@ -14,7 +14,12 @@ enum dma_data_direction {
 };
 
 #define DMA_64BIT_MASK	0xffffffffffffffffULL
+#define DMA_40BIT_MASK	0x000000ffffffffffULL
+#define DMA_39BIT_MASK	0x0000007fffffffffULL
 #define DMA_32BIT_MASK	0x00000000ffffffffULL
+#define DMA_31BIT_MASK	0x000000007fffffffULL
+#define DMA_30BIT_MASK	0x000000003fffffffULL
+#define DMA_29BIT_MASK	0x000000001fffffffULL
 
 #include <asm/dma-mapping.h>
 
diff --git a/include/linux/dmi.h b/include/linux/dmi.h
--- a/include/linux/dmi.h
+++ b/include/linux/dmi.h
@@ -9,6 +9,7 @@ enum dmi_field {
 	DMI_SYS_VENDOR,
 	DMI_PRODUCT_NAME,
 	DMI_PRODUCT_VERSION,
+	DMI_PRODUCT_SERIAL,
 	DMI_BOARD_VENDOR,
 	DMI_BOARD_NAME,
 	DMI_BOARD_VERSION,
diff --git a/include/linux/dqblk_v1.h b/include/linux/dqblk_v1.h
--- a/include/linux/dqblk_v1.h
+++ b/include/linux/dqblk_v1.h
@@ -11,6 +11,12 @@
 /* Root squash turned on */
 #define V1_DQF_RSQUASH 1
 
+/* Numbers of blocks needed for updates */
+#define V1_INIT_ALLOC 1
+#define V1_INIT_REWRITE 1
+#define V1_DEL_ALLOC 0
+#define V1_DEL_REWRITE 2
+
 /* Special information about quotafile */
 struct v1_mem_dqinfo {
 };
diff --git a/include/linux/dqblk_v2.h b/include/linux/dqblk_v2.h
--- a/include/linux/dqblk_v2.h
+++ b/include/linux/dqblk_v2.h
@@ -10,6 +10,12 @@
 /* id numbers of quota format */
 #define QFMT_VFS_V0 2
 
+/* Numbers of blocks needed for updates */
+#define V2_INIT_ALLOC 4
+#define V2_INIT_REWRITE 2
+#define V2_DEL_ALLOC 0
+#define V2_DEL_REWRITE 6
+
 /* Inmemory copy of version specific information */
 struct v2_mem_dqinfo {
 	unsigned int dqi_blocks;
diff --git a/include/linux/efi.h b/include/linux/efi.h
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -315,7 +315,7 @@ extern struct efi_memory_map memmap;
  */
 static inline int efi_range_is_wc(unsigned long start, unsigned long len)
 {
-	int i;
+	unsigned long i;
 
 	for (i = 0; i < len; i += (1UL << EFI_PAGE_SHIFT)) {
 		unsigned long paddr = __pa(start + i);
diff --git a/include/linux/elevator.h b/include/linux/elevator.h
--- a/include/linux/elevator.h
+++ b/include/linux/elevator.h
@@ -16,9 +16,9 @@ typedef void (elevator_remove_req_fn) (r
 typedef void (elevator_requeue_req_fn) (request_queue_t *, struct request *);
 typedef struct request *(elevator_request_list_fn) (request_queue_t *, struct request *);
 typedef void (elevator_completed_req_fn) (request_queue_t *, struct request *);
-typedef int (elevator_may_queue_fn) (request_queue_t *, int);
+typedef int (elevator_may_queue_fn) (request_queue_t *, int, struct bio *);
 
-typedef int (elevator_set_req_fn) (request_queue_t *, struct request *, int);
+typedef int (elevator_set_req_fn) (request_queue_t *, struct request *, struct bio *, int);
 typedef void (elevator_put_req_fn) (request_queue_t *, struct request *);
 typedef void (elevator_deactivate_req_fn) (request_queue_t *, struct request *);
 
@@ -96,9 +96,9 @@ extern struct request *elv_former_reques
 extern struct request *elv_latter_request(request_queue_t *, struct request *);
 extern int elv_register_queue(request_queue_t *q);
 extern void elv_unregister_queue(request_queue_t *q);
-extern int elv_may_queue(request_queue_t *, int);
+extern int elv_may_queue(request_queue_t *, int, struct bio *);
 extern void elv_completed_request(request_queue_t *, struct request *);
-extern int elv_set_request(request_queue_t *, struct request *, int);
+extern int elv_set_request(request_queue_t *, struct request *, struct bio *, int);
 extern void elv_put_request(request_queue_t *, struct request *);
 
 /*
diff --git a/include/linux/etherdevice.h b/include/linux/etherdevice.h
--- a/include/linux/etherdevice.h
+++ b/include/linux/etherdevice.h
@@ -25,6 +25,7 @@
 #define _LINUX_ETHERDEVICE_H
 
 #include <linux/if_ether.h>
+#include <linux/netdevice.h>
 #include <linux/random.h>
 
 #ifdef __KERNEL__
@@ -32,7 +33,7 @@ extern int		eth_header(struct sk_buff *s
 				   unsigned short type, void *daddr,
 				   void *saddr, unsigned len);
 extern int		eth_rebuild_header(struct sk_buff *skb);
-extern unsigned short	eth_type_trans(struct sk_buff *skb, struct net_device *dev);
+extern __be16		eth_type_trans(struct sk_buff *skb, struct net_device *dev);
 extern void		eth_header_cache_update(struct hh_cache *hh, struct net_device *dev,
 						unsigned char * haddr);
 extern int		eth_header_cache(struct neighbour *neigh,
@@ -65,7 +66,7 @@ static inline int is_zero_ether_addr(con
  */
 static inline int is_multicast_ether_addr(const u8 *addr)
 {
-	return addr[0] & 0x01;
+	return ((addr[0] != 0xff) && (0x01 & addr[0]));
 }
 
 /**
diff --git a/include/linux/ext2_fs.h b/include/linux/ext2_fs.h
--- a/include/linux/ext2_fs.h
+++ b/include/linux/ext2_fs.h
@@ -300,18 +300,19 @@ struct ext2_inode {
 /*
  * Mount flags
  */
-#define EXT2_MOUNT_CHECK		0x0001	/* Do mount-time checks */
-#define EXT2_MOUNT_OLDALLOC		0x0002  /* Don't use the new Orlov allocator */
-#define EXT2_MOUNT_GRPID		0x0004	/* Create files with directory's group */
-#define EXT2_MOUNT_DEBUG		0x0008	/* Some debugging messages */
-#define EXT2_MOUNT_ERRORS_CONT		0x0010	/* Continue on errors */
-#define EXT2_MOUNT_ERRORS_RO		0x0020	/* Remount fs ro on errors */
-#define EXT2_MOUNT_ERRORS_PANIC		0x0040	/* Panic on errors */
-#define EXT2_MOUNT_MINIX_DF		0x0080	/* Mimics the Minix statfs */
-#define EXT2_MOUNT_NOBH			0x0100	/* No buffer_heads */
-#define EXT2_MOUNT_NO_UID32		0x0200  /* Disable 32-bit UIDs */
-#define EXT2_MOUNT_XATTR_USER		0x4000	/* Extended user attributes */
-#define EXT2_MOUNT_POSIX_ACL		0x8000	/* POSIX Access Control Lists */
+#define EXT2_MOUNT_CHECK		0x000001  /* Do mount-time checks */
+#define EXT2_MOUNT_OLDALLOC		0x000002  /* Don't use the new Orlov allocator */
+#define EXT2_MOUNT_GRPID		0x000004  /* Create files with directory's group */
+#define EXT2_MOUNT_DEBUG		0x000008  /* Some debugging messages */
+#define EXT2_MOUNT_ERRORS_CONT		0x000010  /* Continue on errors */
+#define EXT2_MOUNT_ERRORS_RO		0x000020  /* Remount fs ro on errors */
+#define EXT2_MOUNT_ERRORS_PANIC		0x000040  /* Panic on errors */
+#define EXT2_MOUNT_MINIX_DF		0x000080  /* Mimics the Minix statfs */
+#define EXT2_MOUNT_NOBH			0x000100  /* No buffer_heads */
+#define EXT2_MOUNT_NO_UID32		0x000200  /* Disable 32-bit UIDs */
+#define EXT2_MOUNT_XATTR_USER		0x004000  /* Extended user attributes */
+#define EXT2_MOUNT_POSIX_ACL		0x008000  /* POSIX Access Control Lists */
+#define EXT2_MOUNT_XIP			0x010000  /* Execute in place */
 
 #define clear_opt(o, opt)		o &= ~EXT2_MOUNT_##opt
 #define set_opt(o, opt)			o |= EXT2_MOUNT_##opt
diff --git a/include/linux/ext3_fs.h b/include/linux/ext3_fs.h
--- a/include/linux/ext3_fs.h
+++ b/include/linux/ext3_fs.h
@@ -239,6 +239,20 @@ struct ext3_new_group_data {
 #define EXT3_IOC_SETRSVSZ		_IOW('f', 6, long)
 
 /*
+ *  Mount options
+ */
+struct ext3_mount_options {
+	unsigned long s_mount_opt;
+	uid_t s_resuid;
+	gid_t s_resgid;
+	unsigned long s_commit_interval;
+#ifdef CONFIG_QUOTA
+	int s_jquota_fmt;
+	char *s_qf_names[MAXQUOTAS];
+#endif
+};
+
+/*
  * Structure of an inode on the disk
  */
 struct ext3_inode {
@@ -358,6 +372,7 @@ struct ext3_inode {
 #define EXT3_MOUNT_RESERVATION		0x10000	/* Preallocation */
 #define EXT3_MOUNT_BARRIER		0x20000 /* Use block barriers */
 #define EXT3_MOUNT_NOBH			0x40000 /* No bufferheads */
+#define EXT3_MOUNT_QUOTA		0x80000 /* Some quota option set */
 
 /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */
 #ifndef _LINUX_EXT2_FS_H
diff --git a/include/linux/ext3_jbd.h b/include/linux/ext3_jbd.h
--- a/include/linux/ext3_jbd.h
+++ b/include/linux/ext3_jbd.h
@@ -42,15 +42,15 @@
  * superblock only gets updated once, of course, so don't bother
  * counting that again for the quota updates. */
 
-#define EXT3_DATA_TRANS_BLOCKS		(EXT3_SINGLEDATA_TRANS_BLOCKS + \
+#define EXT3_DATA_TRANS_BLOCKS(sb)	(EXT3_SINGLEDATA_TRANS_BLOCKS + \
 					 EXT3_XATTR_TRANS_BLOCKS - 2 + \
-					 2*EXT3_QUOTA_TRANS_BLOCKS)
+					 2*EXT3_QUOTA_TRANS_BLOCKS(sb))
 
 /* Delete operations potentially hit one directory's namespace plus an
  * entire inode, plus arbitrary amounts of bitmap/indirection data.  Be
  * generous.  We can grow the delete transaction later if necessary. */
 
-#define EXT3_DELETE_TRANS_BLOCKS	(2 * EXT3_DATA_TRANS_BLOCKS + 64)
+#define EXT3_DELETE_TRANS_BLOCKS(sb)	(2 * EXT3_DATA_TRANS_BLOCKS(sb) + 64)
 
 /* Define an arbitrary limit for the amount of data we will anticipate
  * writing to any given transaction.  For unbounded transactions such as
@@ -74,14 +74,17 @@
 #ifdef CONFIG_QUOTA
 /* Amount of blocks needed for quota update - we know that the structure was
  * allocated so we need to update only inode+data */
-#define EXT3_QUOTA_TRANS_BLOCKS 2
+#define EXT3_QUOTA_TRANS_BLOCKS(sb) (test_opt(sb, QUOTA) ? 2 : 0)
 /* Amount of blocks needed for quota insert/delete - we do some block writes
  * but inode, sb and group updates are done only once */
-#define EXT3_QUOTA_INIT_BLOCKS (DQUOT_MAX_WRITES*\
-				(EXT3_SINGLEDATA_TRANS_BLOCKS-3)+3)
+#define EXT3_QUOTA_INIT_BLOCKS(sb) (test_opt(sb, QUOTA) ? (DQUOT_INIT_ALLOC*\
+		(EXT3_SINGLEDATA_TRANS_BLOCKS-3)+3+DQUOT_INIT_REWRITE) : 0)
+#define EXT3_QUOTA_DEL_BLOCKS(sb) (test_opt(sb, QUOTA) ? (DQUOT_DEL_ALLOC*\
+		(EXT3_SINGLEDATA_TRANS_BLOCKS-3)+3+DQUOT_DEL_REWRITE) : 0)
 #else
-#define EXT3_QUOTA_TRANS_BLOCKS 0
-#define EXT3_QUOTA_INIT_BLOCKS 0
+#define EXT3_QUOTA_TRANS_BLOCKS(sb) 0
+#define EXT3_QUOTA_INIT_BLOCKS(sb) 0
+#define EXT3_QUOTA_DEL_BLOCKS(sb) 0
 #endif
 
 int
diff --git a/include/linux/fadvise.h b/include/linux/fadvise.h
--- a/include/linux/fadvise.h
+++ b/include/linux/fadvise.h
@@ -5,7 +5,17 @@
 #define POSIX_FADV_RANDOM	1 /* Expect random page references.  */
 #define POSIX_FADV_SEQUENTIAL	2 /* Expect sequential page references.  */
 #define POSIX_FADV_WILLNEED	3 /* Will need these pages.  */
+
+/*
+ * The advise values for POSIX_FADV_DONTNEED and POSIX_ADV_NOREUSE
+ * for s390-64 differ from the values for the rest of the world.
+ */
+#if defined(__s390x__)
+#define POSIX_FADV_DONTNEED	6 /* Don't need these pages.  */
+#define POSIX_FADV_NOREUSE	7 /* Data will be accessed once.  */
+#else
 #define POSIX_FADV_DONTNEED	4 /* Don't need these pages.  */
 #define POSIX_FADV_NOREUSE	5 /* Data will be accessed once.  */
+#endif
 
 #endif	/* FADVISE_H_INCLUDED */
diff --git a/include/linux/fb.h b/include/linux/fb.h
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -524,11 +524,11 @@ struct fb_pixmap {
 	u32 offset;		/* current offset to buffer		*/
 	u32 buf_align;		/* byte alignment of each bitmap	*/
 	u32 scan_align;		/* alignment per scanline		*/
-	u32 access_align;	/* alignment per read/write		*/
+	u32 access_align;	/* alignment per read/write (bits)	*/
 	u32 flags;		/* see FB_PIXMAP_*			*/
 	/* access methods */
-	void (*outbuf)(struct fb_info *info, u8 *addr, u8 *src, unsigned int size);
-	u8   (*inbuf) (struct fb_info *info, u8 *addr);
+	void (*writeio)(struct fb_info *info, void __iomem *dst, void *src, unsigned int size);
+	void (*readio) (struct fb_info *info, void *dst, void __iomem *src, unsigned int size);
 };
 
 
@@ -816,18 +816,9 @@ extern int unregister_framebuffer(struct
 extern int fb_prepare_logo(struct fb_info *fb_info);
 extern int fb_show_logo(struct fb_info *fb_info);
 extern char* fb_get_buffer_offset(struct fb_info *info, struct fb_pixmap *buf, u32 size);
-extern void fb_iomove_buf_unaligned(struct fb_info *info, struct fb_pixmap *buf,
-				u8 *dst, u32 d_pitch, u8 *src, u32 idx,
+extern void fb_pad_unaligned_buffer(u8 *dst, u32 d_pitch, u8 *src, u32 idx,
 				u32 height, u32 shift_high, u32 shift_low, u32 mod);
-extern void fb_iomove_buf_aligned(struct fb_info *info, struct fb_pixmap *buf,
-				u8 *dst, u32 d_pitch, u8 *src, u32 s_pitch,
-				u32 height);
-extern void fb_sysmove_buf_unaligned(struct fb_info *info, struct fb_pixmap *buf,
-				u8 *dst, u32 d_pitch, u8 *src, u32 idx,
-				u32 height, u32 shift_high, u32 shift_low, u32 mod);
-extern void fb_sysmove_buf_aligned(struct fb_info *info, struct fb_pixmap *buf,
-				u8 *dst, u32 d_pitch, u8 *src, u32 s_pitch,
-				u32 height);
+extern void fb_pad_aligned_buffer(u8 *dst, u32 d_pitch, u8 *src, u32 s_pitch, u32 height);
 extern void fb_set_suspend(struct fb_info *info, int state);
 extern int fb_get_color_depth(struct fb_var_screeninfo *var);
 extern int fb_get_options(char *name, char **option);
diff --git a/include/linux/fcntl.h b/include/linux/fcntl.h
--- a/include/linux/fcntl.h
+++ b/include/linux/fcntl.h
@@ -25,6 +25,10 @@
 
 #ifdef __KERNEL__
 
+#ifndef force_o_largefile
+#define force_o_largefile() (BITS_PER_LONG != 32)
+#endif
+
 #if BITS_PER_LONG == 32
 #define IS_GETLK32(cmd)		((cmd) == F_GETLK)
 #define IS_SETLK32(cmd)		((cmd) == F_SETLK)
diff --git a/include/linux/fddidevice.h b/include/linux/fddidevice.h
--- a/include/linux/fddidevice.h
+++ b/include/linux/fddidevice.h
@@ -25,7 +25,7 @@
 #include <linux/if_fddi.h>
 
 #ifdef __KERNEL__
-extern unsigned short	fddi_type_trans(struct sk_buff *skb,
+extern __be16	fddi_type_trans(struct sk_buff *skb,
 				struct net_device *dev);
 extern struct net_device *alloc_fddidev(int sizeof_priv);
 #endif
diff --git a/include/linux/font.h b/include/linux/font.h
--- a/include/linux/font.h
+++ b/include/linux/font.h
@@ -25,19 +25,23 @@ struct font_desc {
 #define VGA8x16_IDX	1
 #define PEARL8x8_IDX	2
 #define VGA6x11_IDX	3
-#define SUN8x16_IDX	4
-#define SUN12x22_IDX	5
-#define ACORN8x8_IDX	6
-#define	MINI4x6_IDX	7
+#define FONT7x14_IDX	4
+#define	FONT10x18_IDX	5
+#define SUN8x16_IDX	6
+#define SUN12x22_IDX	7
+#define ACORN8x8_IDX	8
+#define	MINI4x6_IDX	9
 
 extern struct font_desc	font_vga_8x8,
-				font_vga_8x16,
-				font_pearl_8x8,
-				font_vga_6x11,
-				font_sun_8x16,
-				font_sun_12x22,
-				font_acorn_8x8,
-				font_mini_4x6;
+			font_vga_8x16,
+			font_pearl_8x8,
+			font_vga_6x11,
+			font_7x14,
+			font_10x18,
+			font_sun_8x16,
+			font_sun_12x22,
+			font_acorn_8x8,
+			font_mini_4x6;
 
 /* Find a font with a specific name */
 
diff --git a/include/linux/fs.h b/include/linux/fs.h
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -213,6 +213,7 @@ extern int dir_notify_enable;
 #include <linux/radix-tree.h>
 #include <linux/prio_tree.h>
 #include <linux/init.h>
+#include <linux/sched.h>
 
 #include <asm/atomic.h>
 #include <asm/semaphore.h>
@@ -220,6 +221,7 @@ extern int dir_notify_enable;
 
 struct iovec;
 struct nameidata;
+struct kiocb;
 struct pipe_inode_info;
 struct poll_table_struct;
 struct kstatfs;
@@ -240,7 +242,7 @@ typedef int (get_block_t)(struct inode *
 typedef int (get_blocks_t)(struct inode *inode, sector_t iblock,
 			unsigned long max_blocks,
 			struct buffer_head *bh_result, int create);
-typedef void (dio_iodone_t)(struct inode *inode, loff_t offset,
+typedef void (dio_iodone_t)(struct kiocb *iocb, loff_t offset,
 			ssize_t bytes, void *private);
 
 /*
@@ -302,7 +304,6 @@ struct iattr {
 struct page;
 struct address_space;
 struct writeback_control;
-struct kiocb;
 
 struct address_space_operations {
 	int (*writepage)(struct page *page, struct writeback_control *wbc);
@@ -330,6 +331,8 @@ struct address_space_operations {
 	int (*releasepage) (struct page *, int);
 	ssize_t (*direct_IO)(int, struct kiocb *, const struct iovec *iov,
 			loff_t offset, unsigned long nr_segs);
+	struct page* (*get_xip_page)(struct address_space *, sector_t,
+			int);
 };
 
 struct backing_dev_info;
@@ -471,6 +474,11 @@ struct inode {
 	struct dnotify_struct	*i_dnotify; /* for directory notifications */
 #endif
 
+#ifdef CONFIG_INOTIFY
+	struct list_head	inotify_watches; /* watches on this inode */
+	struct semaphore	inotify_sem;	/* protects the watches list */
+#endif
+
 	unsigned long		i_state;
 	unsigned long		dirtied_when;	/* jiffies of first dirtying */
 
@@ -581,7 +589,6 @@ struct file {
 	atomic_t		f_count;
 	unsigned int 		f_flags;
 	mode_t			f_mode;
-	int			f_error;
 	loff_t			f_pos;
 	struct fown_struct	f_owner;
 	unsigned int		f_uid, f_gid;
@@ -674,6 +681,7 @@ struct file_lock {
 	struct lock_manager_operations *fl_lmops;	/* Callbacks for lockmanagers */
 	union {
 		struct nfs_lock_info	nfs_fl;
+		struct nfs4_lock_info	nfs4_fl;
 	} fl_u;
 };
 
@@ -689,11 +697,13 @@ extern struct list_head file_lock_list;
 #include <linux/fcntl.h>
 
 extern int fcntl_getlk(struct file *, struct flock __user *);
-extern int fcntl_setlk(struct file *, unsigned int, struct flock __user *);
+extern int fcntl_setlk(unsigned int, struct file *, unsigned int,
+			struct flock __user *);
 
 #if BITS_PER_LONG == 32
 extern int fcntl_getlk64(struct file *, struct flock64 __user *);
-extern int fcntl_setlk64(struct file *, unsigned int, struct flock64 __user *);
+extern int fcntl_setlk64(unsigned int, struct file *, unsigned int,
+			struct flock64 __user *);
 #endif
 
 extern void send_sigio(struct fown_struct *fown, int fd, int band);
@@ -820,16 +830,34 @@ enum {
 #define vfs_check_frozen(sb, level) \
 	wait_event((sb)->s_wait_unfrozen, ((sb)->s_frozen < (level)))
 
+static inline void get_fs_excl(void)
+{
+	atomic_inc(&current->fs_excl);
+}
+
+static inline void put_fs_excl(void)
+{
+	atomic_dec(&current->fs_excl);
+}
+
+static inline int has_fs_excl(void)
+{
+	return atomic_read(&current->fs_excl);
+}
+
+
 /*
  * Superblock locking.
  */
 static inline void lock_super(struct super_block * sb)
 {
+	get_fs_excl();
 	down(&sb->s_lock);
 }
 
 static inline void unlock_super(struct super_block * sb)
 {
+	put_fs_excl();
 	up(&sb->s_lock);
 }
 
@@ -883,7 +911,9 @@ struct block_device_operations {
 	int (*open) (struct inode *, struct file *);
 	int (*release) (struct inode *, struct file *);
 	int (*ioctl) (struct inode *, struct file *, unsigned, unsigned long);
+	long (*unlocked_ioctl) (struct file *, unsigned, unsigned long);
 	long (*compat_ioctl) (struct file *, unsigned, unsigned long);
+	int (*direct_access) (struct block_device *, sector_t, unsigned long *);
 	int (*media_changed) (struct gendisk *);
 	int (*revalidate_disk) (struct gendisk *);
 	struct module *owner;
@@ -963,8 +993,8 @@ struct inode_operations {
 	int (*rename) (struct inode *, struct dentry *,
 			struct inode *, struct dentry *);
 	int (*readlink) (struct dentry *, char __user *,int);
-	int (*follow_link) (struct dentry *, struct nameidata *);
-	void (*put_link) (struct dentry *, struct nameidata *);
+	void * (*follow_link) (struct dentry *, struct nameidata *);
+	void (*put_link) (struct dentry *, struct nameidata *, void *);
 	void (*truncate) (struct inode *);
 	int (*permission) (struct inode *, int, struct nameidata *);
 	int (*setattr) (struct dentry *, struct iattr *);
@@ -1024,6 +1054,7 @@ struct super_operations {
 #define I_FREEING		16
 #define I_CLEAR			32
 #define I_NEW			64
+#define I_WILL_FREE		128
 
 #define I_DIRTY (I_DIRTY_SYNC | I_DIRTY_DATASYNC | I_DIRTY_PAGES)
 
@@ -1369,7 +1400,6 @@ extern void emergency_remount(void);
 extern int do_remount_sb(struct super_block *sb, int flags,
 			 void *data, int force);
 extern sector_t bmap(struct inode *, sector_t);
-extern int setattr_mask(unsigned int);
 extern int notify_change(struct dentry *, struct iattr *);
 extern int permission(struct inode *, int, struct nameidata *);
 extern int generic_permission(struct inode *, int,
@@ -1411,7 +1441,11 @@ extern struct inode * igrab(struct inode
 extern ino_t iunique(struct super_block *, ino_t);
 extern int inode_needs_sync(struct inode *inode);
 extern void generic_delete_inode(struct inode *inode);
+extern void generic_drop_inode(struct inode *inode);
 
+extern struct inode *ilookup5_nowait(struct super_block *sb,
+		unsigned long hashval, int (*test)(struct inode *, void *),
+		void *data);
 extern struct inode *ilookup5(struct super_block *sb, unsigned long hashval,
 		int (*test)(struct inode *, void *), void *data);
 extern struct inode *ilookup(struct super_block *sb, unsigned long ino);
@@ -1494,6 +1528,23 @@ extern loff_t remote_llseek(struct file 
 extern int generic_file_open(struct inode * inode, struct file * filp);
 extern int nonseekable_open(struct inode * inode, struct file * filp);
 
+#ifdef CONFIG_FS_XIP
+extern ssize_t xip_file_read(struct file *filp, char __user *buf, size_t len,
+			     loff_t *ppos);
+extern ssize_t xip_file_sendfile(struct file *in_file, loff_t *ppos,
+				 size_t count, read_actor_t actor,
+				 void *target);
+extern int xip_file_mmap(struct file * file, struct vm_area_struct * vma);
+extern ssize_t xip_file_write(struct file *filp, const char __user *buf,
+			      size_t len, loff_t *ppos);
+extern int xip_truncate_page(struct address_space *mapping, loff_t from);
+#else
+static inline int xip_truncate_page(struct address_space *mapping, loff_t from)
+{
+	return 0;
+}
+#endif
+
 static inline void do_generic_file_read(struct file * filp, loff_t *ppos,
 					read_descriptor_t * desc,
 					read_actor_t actor)
@@ -1551,8 +1602,8 @@ extern struct file_operations generic_ro
 extern int vfs_readlink(struct dentry *, char __user *, int, const char *);
 extern int vfs_follow_link(struct nameidata *, const char *);
 extern int page_readlink(struct dentry *, char __user *, int);
-extern int page_follow_link_light(struct dentry *, struct nameidata *);
-extern void page_put_link(struct dentry *, struct nameidata *);
+extern void *page_follow_link_light(struct dentry *, struct nameidata *);
+extern void page_put_link(struct dentry *, struct nameidata *, void *);
 extern int page_symlink(struct inode *inode, const char *symname, int len);
 extern struct inode_operations page_symlink_inode_operations;
 extern int generic_readlink(struct dentry *, char __user *, int);
@@ -1657,6 +1708,52 @@ static inline void simple_transaction_se
 	ar->size = n;
 }
 
+/*
+ * simple attribute files
+ *
+ * These attributes behave similar to those in sysfs:
+ *
+ * Writing to an attribute immediately sets a value, an open file can be
+ * written to multiple times.
+ *
+ * Reading from an attribute creates a buffer from the value that might get
+ * read with multiple read calls. When the attribute has been read
+ * completely, no further read calls are possible until the file is opened
+ * again.
+ *
+ * All attributes contain a text representation of a numeric value
+ * that are accessed with the get() and set() functions.
+ */
+#define DEFINE_SIMPLE_ATTRIBUTE(__fops, __get, __set, __fmt)		\
+static int __fops ## _open(struct inode *inode, struct file *file)	\
+{									\
+	__simple_attr_check_format(__fmt, 0ull);			\
+	return simple_attr_open(inode, file, __get, __set, __fmt);	\
+}									\
+static struct file_operations __fops = {				\
+	.owner	 = THIS_MODULE,						\
+	.open	 = __fops ## _open,					\
+	.release = simple_attr_close,					\
+	.read	 = simple_attr_read,					\
+	.write	 = simple_attr_write,					\
+};
+
+static inline void __attribute__((format(printf, 1, 2)))
+__simple_attr_check_format(const char *fmt, ...)
+{
+	/* don't do anything, just let the compiler check the arguments; */
+}
+
+int simple_attr_open(struct inode *inode, struct file *file,
+		     u64 (*get)(void *), void (*set)(void *, u64),
+		     const char *fmt);
+int simple_attr_close(struct inode *inode, struct file *file);
+ssize_t simple_attr_read(struct file *file, char __user *buf,
+			 size_t len, loff_t *ppos);
+ssize_t simple_attr_write(struct file *file, const char __user *buf,
+			  size_t len, loff_t *ppos);
+
+
 #ifdef CONFIG_SECURITY
 static inline char *alloc_secdata(void)
 {
diff --git a/include/linux/fsl_devices.h b/include/linux/fsl_devices.h
--- a/include/linux/fsl_devices.h
+++ b/include/linux/fsl_devices.h
@@ -51,6 +51,7 @@ struct gianfar_platform_data {
 
 	/* board specific information */
 	u32 board_flags;
+	u32 phy_flags;
 	u32 phyid;
 	u32 interruptPHY;
 	u8 mac_addr[6];
@@ -61,9 +62,14 @@ struct gianfar_platform_data {
 #define FSL_GIANFAR_DEV_HAS_COALESCE		0x00000002
 #define FSL_GIANFAR_DEV_HAS_RMON		0x00000004
 #define FSL_GIANFAR_DEV_HAS_MULTI_INTR		0x00000008
+#define FSL_GIANFAR_DEV_HAS_CSUM		0x00000010
+#define FSL_GIANFAR_DEV_HAS_VLAN		0x00000020
+#define FSL_GIANFAR_DEV_HAS_EXTENDED_HASH	0x00000040
+#define FSL_GIANFAR_DEV_HAS_PADDING		0x00000080
 
 /* Flags in gianfar_platform_data */
-#define FSL_GIANFAR_BRD_HAS_PHY_INTR	0x00000001	/* if not set use a timer */
+#define FSL_GIANFAR_BRD_HAS_PHY_INTR	0x00000001 /* set or use a timer */
+#define FSL_GIANFAR_BRD_IS_REDUCED	0x00000002 /* Set if RGMII, RMII */
 
 struct fsl_i2c_platform_data {
 	/* device specific information */
diff --git a/include/linux/fsnotify.h b/include/linux/fsnotify.h
new file mode 100644
--- /dev/null
+++ b/include/linux/fsnotify.h
@@ -0,0 +1,251 @@
+#ifndef _LINUX_FS_NOTIFY_H
+#define _LINUX_FS_NOTIFY_H
+
+/*
+ * include/linux/fsnotify.h - generic hooks for filesystem notification, to
+ * reduce in-source duplication from both dnotify and inotify.
+ *
+ * We don't compile any of this away in some complicated menagerie of ifdefs.
+ * Instead, we rely on the code inside to optimize away as needed.
+ *
+ * (C) Copyright 2005 Robert Love
+ */
+
+#ifdef __KERNEL__
+
+#include <linux/dnotify.h>
+#include <linux/inotify.h>
+
+/*
+ * fsnotify_move - file old_name at old_dir was moved to new_name at new_dir
+ */
+static inline void fsnotify_move(struct inode *old_dir, struct inode *new_dir,
+				 const char *old_name, const char *new_name,
+				 int isdir, struct inode *target, struct inode *source)
+{
+	u32 cookie = inotify_get_cookie();
+
+	if (old_dir == new_dir)
+		inode_dir_notify(old_dir, DN_RENAME);
+	else {
+		inode_dir_notify(old_dir, DN_DELETE);
+		inode_dir_notify(new_dir, DN_CREATE);
+	}
+
+	if (isdir)
+		isdir = IN_ISDIR;
+	inotify_inode_queue_event(old_dir, IN_MOVED_FROM|isdir,cookie,old_name);
+	inotify_inode_queue_event(new_dir, IN_MOVED_TO|isdir, cookie, new_name);
+
+	if (target) {
+		inotify_inode_queue_event(target, IN_DELETE_SELF, 0, NULL);
+		inotify_inode_is_dead(target);
+	}
+
+	if (source) {
+		inotify_inode_queue_event(source, IN_MOVE_SELF, 0, NULL);
+	}
+}
+
+/*
+ * fsnotify_nameremove - a filename was removed from a directory
+ */
+static inline void fsnotify_nameremove(struct dentry *dentry, int isdir)
+{
+	if (isdir)
+		isdir = IN_ISDIR;
+	dnotify_parent(dentry, DN_DELETE);
+	inotify_dentry_parent_queue_event(dentry, IN_DELETE|isdir, 0, dentry->d_name.name);
+}
+
+/*
+ * fsnotify_inoderemove - an inode is going away
+ */
+static inline void fsnotify_inoderemove(struct inode *inode)
+{
+	inotify_inode_queue_event(inode, IN_DELETE_SELF, 0, NULL);
+	inotify_inode_is_dead(inode);
+}
+
+/*
+ * fsnotify_create - 'name' was linked in
+ */
+static inline void fsnotify_create(struct inode *inode, const char *name)
+{
+	inode_dir_notify(inode, DN_CREATE);
+	inotify_inode_queue_event(inode, IN_CREATE, 0, name);
+}
+
+/*
+ * fsnotify_mkdir - directory 'name' was created
+ */
+static inline void fsnotify_mkdir(struct inode *inode, const char *name)
+{
+	inode_dir_notify(inode, DN_CREATE);
+	inotify_inode_queue_event(inode, IN_CREATE | IN_ISDIR, 0, name);
+}
+
+/*
+ * fsnotify_access - file was read
+ */
+static inline void fsnotify_access(struct dentry *dentry)
+{
+	struct inode *inode = dentry->d_inode;
+	u32 mask = IN_ACCESS;
+
+	if (S_ISDIR(inode->i_mode))
+		mask |= IN_ISDIR;
+
+	dnotify_parent(dentry, DN_ACCESS);
+	inotify_dentry_parent_queue_event(dentry, mask, 0, dentry->d_name.name);
+	inotify_inode_queue_event(inode, mask, 0, NULL);
+}
+
+/*
+ * fsnotify_modify - file was modified
+ */
+static inline void fsnotify_modify(struct dentry *dentry)
+{
+	struct inode *inode = dentry->d_inode;
+	u32 mask = IN_MODIFY;
+
+	if (S_ISDIR(inode->i_mode))
+		mask |= IN_ISDIR;
+
+	dnotify_parent(dentry, DN_MODIFY);
+	inotify_dentry_parent_queue_event(dentry, mask, 0, dentry->d_name.name);
+	inotify_inode_queue_event(inode, mask, 0, NULL);
+}
+
+/*
+ * fsnotify_open - file was opened
+ */
+static inline void fsnotify_open(struct dentry *dentry)
+{
+	struct inode *inode = dentry->d_inode;
+	u32 mask = IN_OPEN;
+
+	if (S_ISDIR(inode->i_mode))
+		mask |= IN_ISDIR;
+
+	inotify_dentry_parent_queue_event(dentry, mask, 0, dentry->d_name.name);
+	inotify_inode_queue_event(inode, mask, 0, NULL);	
+}
+
+/*
+ * fsnotify_close - file was closed
+ */
+static inline void fsnotify_close(struct file *file)
+{
+	struct dentry *dentry = file->f_dentry;
+	struct inode *inode = dentry->d_inode;
+	const char *name = dentry->d_name.name;
+	mode_t mode = file->f_mode;
+	u32 mask = (mode & FMODE_WRITE) ? IN_CLOSE_WRITE : IN_CLOSE_NOWRITE;
+
+	if (S_ISDIR(inode->i_mode))
+		mask |= IN_ISDIR;
+
+	inotify_dentry_parent_queue_event(dentry, mask, 0, name);
+	inotify_inode_queue_event(inode, mask, 0, NULL);
+}
+
+/*
+ * fsnotify_xattr - extended attributes were changed
+ */
+static inline void fsnotify_xattr(struct dentry *dentry)
+{
+	struct inode *inode = dentry->d_inode;
+	u32 mask = IN_ATTRIB;
+
+	if (S_ISDIR(inode->i_mode))
+		mask |= IN_ISDIR;
+
+	inotify_dentry_parent_queue_event(dentry, mask, 0, dentry->d_name.name);
+	inotify_inode_queue_event(inode, mask, 0, NULL);
+}
+
+/*
+ * fsnotify_change - notify_change event.  file was modified and/or metadata
+ * was changed.
+ */
+static inline void fsnotify_change(struct dentry *dentry, unsigned int ia_valid)
+{
+	struct inode *inode = dentry->d_inode;
+	int dn_mask = 0;
+	u32 in_mask = 0;
+
+	if (ia_valid & ATTR_UID) {
+		in_mask |= IN_ATTRIB;
+		dn_mask |= DN_ATTRIB;
+	}
+	if (ia_valid & ATTR_GID) {
+		in_mask |= IN_ATTRIB;
+		dn_mask |= DN_ATTRIB;
+	}
+	if (ia_valid & ATTR_SIZE) {
+		in_mask |= IN_MODIFY;
+		dn_mask |= DN_MODIFY;
+	}
+	/* both times implies a utime(s) call */
+	if ((ia_valid & (ATTR_ATIME | ATTR_MTIME)) == (ATTR_ATIME | ATTR_MTIME))
+	{
+		in_mask |= IN_ATTRIB;
+		dn_mask |= DN_ATTRIB;
+	} else if (ia_valid & ATTR_ATIME) {
+		in_mask |= IN_ACCESS;
+		dn_mask |= DN_ACCESS;
+	} else if (ia_valid & ATTR_MTIME) {
+		in_mask |= IN_MODIFY;
+		dn_mask |= DN_MODIFY;
+	}
+	if (ia_valid & ATTR_MODE) {
+		in_mask |= IN_ATTRIB;
+		dn_mask |= DN_ATTRIB;
+	}
+
+	if (dn_mask)
+		dnotify_parent(dentry, dn_mask);
+	if (in_mask) {
+		if (S_ISDIR(inode->i_mode))
+			in_mask |= IN_ISDIR;
+		inotify_inode_queue_event(inode, in_mask, 0, NULL);
+		inotify_dentry_parent_queue_event(dentry, in_mask, 0,
+						  dentry->d_name.name);
+	}
+}
+
+#ifdef CONFIG_INOTIFY	/* inotify helpers */
+
+/*
+ * fsnotify_oldname_init - save off the old filename before we change it
+ */
+static inline const char *fsnotify_oldname_init(const char *name)
+{
+	return kstrdup(name, GFP_KERNEL);
+}
+
+/*
+ * fsnotify_oldname_free - free the name we got from fsnotify_oldname_init
+ */
+static inline void fsnotify_oldname_free(const char *old_name)
+{
+	kfree(old_name);
+}
+
+#else	/* CONFIG_INOTIFY */
+
+static inline const char *fsnotify_oldname_init(const char *name)
+{
+	return NULL;
+}
+
+static inline void fsnotify_oldname_free(const char *old_name)
+{
+}
+
+#endif	/* ! CONFIG_INOTIFY */
+
+#endif	/* __KERNEL__ */
+
+#endif	/* _LINUX_FS_NOTIFY_H */
diff --git a/include/linux/ftape.h b/include/linux/ftape.h
--- a/include/linux/ftape.h
+++ b/include/linux/ftape.h
@@ -165,7 +165,7 @@ typedef union {
 #  undef  CONFIG_FT_FDC_DMA
 #  define CONFIG_FT_FDC_DMA 2
 # endif
-#elif CONFIG_FT_ALT_FDC == 1  /* CONFIG_FT_MACH2 */
+#elif defined(CONFIG_FT_ALT_FDC)  /* CONFIG_FT_MACH2 */
 # if CONFIG_FT_FDC_BASE == 0
 #  undef  CONFIG_FT_FDC_BASE
 #  define CONFIG_FT_FDC_BASE 0x370
diff --git a/include/linux/genalloc.h b/include/linux/genalloc.h
new file mode 100644
--- /dev/null
+++ b/include/linux/genalloc.h
@@ -0,0 +1,40 @@
+/*
+ * Basic general purpose allocator for managing special purpose memory
+ * not managed by the regular kmalloc/kfree interface.
+ * Uses for this includes on-device special memory, uncached memory
+ * etc.
+ *
+ * This code is based on the buddy allocator found in the sym53c8xx_2
+ * driver, adapted for general purpose use.
+ *
+ * This source code is licensed under the GNU General Public License,
+ * Version 2.  See the file COPYING for more details.
+ */
+
+#include <linux/spinlock.h>
+
+#define ALLOC_MIN_SHIFT		5 /* 32 bytes minimum */
+/*
+ *  Link between free memory chunks of a given size.
+ */
+struct gen_pool_link {
+	struct gen_pool_link *next;
+};
+
+/*
+ *  Memory pool descriptor.
+ */
+struct gen_pool {
+	spinlock_t lock;
+	unsigned long (*get_new_chunk)(struct gen_pool *);
+	struct gen_pool *next;
+	struct gen_pool_link *h;
+	unsigned long private;
+	int max_chunk_shift;
+};
+
+unsigned long gen_pool_alloc(struct gen_pool *poolp, int size);
+void gen_pool_free(struct gen_pool *mp, unsigned long ptr, int size);
+struct gen_pool *gen_pool_create(int nr_chunks, int max_chunk_shift,
+				 unsigned long (*fp)(struct gen_pool *),
+				 unsigned long data);
diff --git a/include/linux/genhd.h b/include/linux/genhd.h
--- a/include/linux/genhd.h
+++ b/include/linux/genhd.h
@@ -224,7 +224,7 @@ static inline void free_disk_stats(struc
 extern void disk_round_stats(struct gendisk *disk);
 
 /* drivers/block/genhd.c */
-extern int get_blkdev_list(char *);
+extern int get_blkdev_list(char *, int);
 extern void add_disk(struct gendisk *disk);
 extern void del_gendisk(struct gendisk *gp);
 extern void unlink_gendisk(struct gendisk *gp);
@@ -403,6 +403,7 @@ extern int rescan_partitions(struct gend
 extern void add_partition(struct gendisk *, int, sector_t, sector_t);
 extern void delete_partition(struct gendisk *, int);
 
+extern struct gendisk *alloc_disk_node(int minors, int node_id);
 extern struct gendisk *alloc_disk(int minors);
 extern struct kobject *get_disk(struct gendisk *disk);
 extern void put_disk(struct gendisk *disk);
diff --git a/include/linux/gfp.h b/include/linux/gfp.h
--- a/include/linux/gfp.h
+++ b/include/linux/gfp.h
@@ -12,8 +12,8 @@ struct vm_area_struct;
  * GFP bitmasks..
  */
 /* Zone modifiers in GFP_ZONEMASK (see linux/mmzone.h - low two bits) */
-#define __GFP_DMA	0x01
-#define __GFP_HIGHMEM	0x02
+#define __GFP_DMA	0x01u
+#define __GFP_HIGHMEM	0x02u
 
 /*
  * Action modifiers - doesn't change the zoning
@@ -39,6 +39,7 @@ struct vm_area_struct;
 #define __GFP_COMP	0x4000u	/* Add compound page metadata */
 #define __GFP_ZERO	0x8000u	/* Return zeroed page on success */
 #define __GFP_NOMEMALLOC 0x10000u /* Don't use emergency reserves */
+#define __GFP_NORECLAIM  0x20000u /* No realy zone reclaim during allocation */
 
 #define __GFP_BITS_SHIFT 20	/* Room for 20 __GFP_FOO bits */
 #define __GFP_BITS_MASK ((1 << __GFP_BITS_SHIFT) - 1)
@@ -47,7 +48,7 @@ struct vm_area_struct;
 #define GFP_LEVEL_MASK (__GFP_WAIT|__GFP_HIGH|__GFP_IO|__GFP_FS| \
 			__GFP_COLD|__GFP_NOWARN|__GFP_REPEAT| \
 			__GFP_NOFAIL|__GFP_NORETRY|__GFP_NO_GROW|__GFP_COMP| \
-			__GFP_NOMEMALLOC)
+			__GFP_NOMEMALLOC|__GFP_NORECLAIM)
 
 #define GFP_ATOMIC	(__GFP_HIGH)
 #define GFP_NOIO	(__GFP_WAIT)
@@ -132,5 +133,10 @@ extern void FASTCALL(free_cold_page(stru
 #define free_page(addr) free_pages((addr),0)
 
 void page_alloc_init(void);
+#ifdef CONFIG_NUMA
+void drain_remote_pages(void);
+#else
+static inline void drain_remote_pages(void) { };
+#endif
 
 #endif /* __LINUX_GFP_H */
diff --git a/include/linux/hardirq.h b/include/linux/hardirq.h
--- a/include/linux/hardirq.h
+++ b/include/linux/hardirq.h
@@ -2,6 +2,7 @@
 #define LINUX_HARDIRQ_H
 
 #include <linux/config.h>
+#include <linux/preempt.h>
 #include <linux/smp_lock.h>
 #include <asm/hardirq.h>
 #include <asm/system.h>
diff --git a/include/linux/hdlc.h b/include/linux/hdlc.h
--- a/include/linux/hdlc.h
+++ b/include/linux/hdlc.h
@@ -1,7 +1,7 @@
 /*
  * Generic HDLC support routines for Linux
  *
- * Copyright (C) 1999-2003 Krzysztof Halasa <khc@pm.waw.pl>
+ * Copyright (C) 1999-2005 Krzysztof Halasa <khc@pm.waw.pl>
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License
@@ -41,6 +41,7 @@
 #define LMI_NONE		1 /* No LMI, all PVCs are static */
 #define LMI_ANSI		2 /* ANSI Annex D */
 #define LMI_CCITT		3 /* ITU-T Annex A */
+#define LMI_CISCO		4 /* The "original" LMI, aka Gang of Four */
 
 #define HDLC_MAX_MTU 1500	/* Ethernet 1500 bytes */
 #define HDLC_MAX_MRU (HDLC_MAX_MTU + 10 + 14 + 4) /* for ETH+VLAN over FR */
@@ -89,6 +90,7 @@ typedef struct pvc_device_struct {
 		unsigned int deleted: 1;
 		unsigned int fecn: 1;
 		unsigned int becn: 1;
+		unsigned int bandwidth;	/* Cisco LMI reporting only */
 	}state;
 }pvc_device;
 
@@ -240,8 +242,8 @@ static __inline__ struct net_device_stat
 }
 
 
-static __inline__ unsigned short hdlc_type_trans(struct sk_buff *skb,
-						 struct net_device *dev)
+static __inline__ __be16 hdlc_type_trans(struct sk_buff *skb,
+					 struct net_device *dev)
 {
 	hdlc_device *hdlc = dev_to_hdlc(dev);
 
diff --git a/include/linux/highmem.h b/include/linux/highmem.h
--- a/include/linux/highmem.h
+++ b/include/linux/highmem.h
@@ -28,6 +28,7 @@ static inline void *kmap(struct page *pa
 
 #define kmap_atomic(page, idx)		page_address(page)
 #define kunmap_atomic(addr, idx)	do { } while (0)
+#define kmap_atomic_pfn(pfn, idx)	page_address(pfn_to_page(pfn))
 #define kmap_atomic_to_page(ptr)	virt_to_page(ptr)
 
 #endif /* CONFIG_HIGHMEM */
diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
--- a/include/linux/hugetlb.h
+++ b/include/linux/hugetlb.h
@@ -4,6 +4,7 @@
 #ifdef CONFIG_HUGETLB_PAGE
 
 #include <linux/mempolicy.h>
+#include <asm/tlbflush.h>
 
 struct ctl_table;
 
@@ -22,12 +23,6 @@ int hugetlb_report_meminfo(char *);
 int hugetlb_report_node_meminfo(int, char *);
 int is_hugepage_mem_enough(size_t);
 unsigned long hugetlb_total_pages(void);
-struct page *follow_huge_addr(struct mm_struct *mm, unsigned long address,
-			      int write);
-struct page *follow_huge_pmd(struct mm_struct *mm, unsigned long address,
-				pmd_t *pmd, int write);
-int is_aligned_hugepage_range(unsigned long addr, unsigned long len);
-int pmd_huge(pmd_t pmd);
 struct page *alloc_huge_page(void);
 void free_huge_page(struct page *);
 
@@ -35,6 +30,17 @@ extern unsigned long max_huge_pages;
 extern const unsigned long hugetlb_zero, hugetlb_infinity;
 extern int sysctl_hugetlb_shm_group;
 
+/* arch callbacks */
+
+pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr);
+pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr);
+struct page *follow_huge_addr(struct mm_struct *mm, unsigned long address,
+			      int write);
+struct page *follow_huge_pmd(struct mm_struct *mm, unsigned long address,
+				pmd_t *pmd, int write);
+int is_aligned_hugepage_range(unsigned long addr, unsigned long len);
+int pmd_huge(pmd_t pmd);
+
 #ifndef ARCH_HAS_HUGEPAGE_ONLY_RANGE
 #define is_hugepage_only_range(mm, addr, len)	0
 #define hugetlb_free_pgd_range(tlb, addr, end, floor, ceiling) \
@@ -48,6 +54,28 @@ extern int sysctl_hugetlb_shm_group;
 int prepare_hugepage_range(unsigned long addr, unsigned long len);
 #endif
 
+#ifndef ARCH_HAS_SETCLEAR_HUGE_PTE
+#define set_huge_pte_at(mm, addr, ptep, pte)	set_pte_at(mm, addr, ptep, pte)
+#define huge_ptep_get_and_clear(mm, addr, ptep) ptep_get_and_clear(mm, addr, ptep)
+#else
+void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
+		     pte_t *ptep, pte_t pte);
+pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
+			      pte_t *ptep);
+#endif
+
+#ifndef ARCH_HAS_HUGETLB_PREFAULT_HOOK
+#define hugetlb_prefault_arch_hook(mm)		do { } while (0)
+#else
+void hugetlb_prefault_arch_hook(struct mm_struct *mm);
+#endif
+
+#ifndef ARCH_HAS_HUGETLB_CLEAN_STALE_PGTABLE
+#define hugetlb_clean_stale_pgtable(pte)	BUG()
+#else
+void hugetlb_clean_stale_pgtable(pte_t *pte);
+#endif
+
 #else /* !CONFIG_HUGETLB_PAGE */
 
 static inline int is_vm_hugetlb_page(struct vm_area_struct *vma)
diff --git a/include/linux/hwmon-sysfs.h b/include/linux/hwmon-sysfs.h
new file mode 100644
--- /dev/null
+++ b/include/linux/hwmon-sysfs.h
@@ -0,0 +1,36 @@
+/*
+ *  hwmon-sysfs.h - hardware monitoring chip driver sysfs defines
+ *
+ *  Copyright (C) 2005 Yani Ioannou <yani.ioannou@gmail.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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef _LINUX_HWMON_SYSFS_H
+#define _LINUX_HWMON_SYSFS_H
+
+struct sensor_device_attribute{
+	struct device_attribute dev_attr;
+	int index;
+};
+#define to_sensor_dev_attr(_dev_attr) \
+	container_of(_dev_attr, struct sensor_device_attribute, dev_attr)
+
+#define SENSOR_DEVICE_ATTR(_name,_mode,_show,_store,_index)	\
+struct sensor_device_attribute sensor_dev_attr_##_name = {	\
+	.dev_attr =	__ATTR(_name,_mode,_show,_store),	\
+	.index =	_index,					\
+}
+
+#endif /* _LINUX_HWMON_SYSFS_H */
diff --git a/include/linux/i2c-dev.h b/include/linux/i2c-dev.h
--- a/include/linux/i2c-dev.h
+++ b/include/linux/i2c-dev.h
@@ -25,6 +25,7 @@
 #define _LINUX_I2C_DEV_H
 
 #include <linux/types.h>
+#include <linux/compiler.h>
 
 /* Some IOCTL commands are defined in <linux/i2c.h> */
 /* Note: 10-bit addresses are NOT supported! */
diff --git a/include/linux/i2c-id.h b/include/linux/i2c-id.h
--- a/include/linux/i2c-id.h
+++ b/include/linux/i2c-id.h
@@ -108,6 +108,7 @@
 #define I2C_DRIVERID_TDA7313	62	/* TDA7313 audio processor	*/
 #define I2C_DRIVERID_MAX6900	63	/* MAX6900 real-time clock	*/
 #define I2C_DRIVERID_SAA7114H	64	/* video decoder		*/
+#define I2C_DRIVERID_DS1374	65	/* DS1374 real time clock	*/
 
 
 #define I2C_DRIVERID_EXP0	0xF0	/* experimental use id's	*/
diff --git a/include/linux/i2c-vid.h b/include/linux/i2c-vid.h
--- a/include/linux/i2c-vid.h
+++ b/include/linux/i2c-vid.h
@@ -97,3 +97,15 @@ static inline int vid_from_reg(int val, 
 		                     2050 - (val) * 50);
 	}
 }
+
+static inline int vid_to_reg(int val, int vrm)
+{
+	switch (vrm) {
+	case 91:		/* VRM 9.1 */
+	case 90:		/* VRM 9.0 */
+		return ((val >= 1100) && (val <= 1850) ?
+			((18499 - val * 10) / 25 + 5) / 10 : -1);
+	default:
+		return -1;
+	}
+}
diff --git a/include/linux/i2c.h b/include/linux/i2c.h
--- a/include/linux/i2c.h
+++ b/include/linux/i2c.h
@@ -290,11 +290,8 @@ static inline void i2c_set_adapdata (str
  */
 struct i2c_client_address_data {
 	unsigned short *normal_i2c;
-	unsigned short *normal_i2c_range;
 	unsigned short *probe;
-	unsigned short *probe_range;
 	unsigned short *ignore;
-	unsigned short *ignore_range;
 	unsigned short *force;
 };
 
@@ -563,24 +560,15 @@ union i2c_smbus_data {
 #define I2C_CLIENT_INSMOD \
   I2C_CLIENT_MODULE_PARM(probe, \
                       "List of adapter,address pairs to scan additionally"); \
-  I2C_CLIENT_MODULE_PARM(probe_range, \
-                      "List of adapter,start-addr,end-addr triples to scan " \
-                      "additionally"); \
   I2C_CLIENT_MODULE_PARM(ignore, \
                       "List of adapter,address pairs not to scan"); \
-  I2C_CLIENT_MODULE_PARM(ignore_range, \
-                      "List of adapter,start-addr,end-addr triples not to " \
-                      "scan"); \
   I2C_CLIENT_MODULE_PARM(force, \
                       "List of adapter,address pairs to boldly assume " \
                       "to be present"); \
 	static struct i2c_client_address_data addr_data = {		\
 			.normal_i2c = 		normal_i2c,		\
-			.normal_i2c_range =	normal_i2c_range,	\
 			.probe =		probe,			\
-			.probe_range =		probe_range,		\
 			.ignore =		ignore,			\
-			.ignore_range =		ignore_range,		\
 			.force =		force,			\
 		}
 
diff --git a/include/linux/i2o-dev.h b/include/linux/i2o-dev.h
--- a/include/linux/i2o-dev.h
+++ b/include/linux/i2o-dev.h
@@ -24,6 +24,13 @@
 #define MAX_I2O_CONTROLLERS	32
 
 //#include <linux/ioctl.h>
+#ifndef __KERNEL__
+
+typedef unsigned char u8;
+typedef unsigned short u16;
+typedef unsigned int u32;
+
+#endif				/* __KERNEL__ */
 
 /*
  * I2O Control IOCTLs and structures
@@ -113,6 +120,10 @@ struct i2o_evt_get {
 	int lost;
 };
 
+typedef struct i2o_sg_io_hdr {
+	unsigned int flags;	/* see I2O_DPT_SG_IO_FLAGS */
+} i2o_sg_io_hdr_t;
+
 /**************************************************************************
  * HRT related constants and structures
  **************************************************************************/
@@ -126,14 +137,6 @@ struct i2o_evt_get {
 #define I2O_BUS_CARDBUS 7
 #define I2O_BUS_UNKNOWN 0x80
 
-#ifndef __KERNEL__
-
-typedef unsigned char u8;
-typedef unsigned short u16;
-typedef unsigned int u32;
-
-#endif				/* __KERNEL__ */
-
 typedef struct _i2o_pci_bus {
 	u8 PciFunctionNumber;
 	u8 PciDeviceNumber;
@@ -333,7 +336,7 @@ typedef struct _i2o_status_block {
 #define I2O_CLASS_ATE_PERIPHERAL		0x061
 #define I2O_CLASS_FLOPPY_CONTROLLER		0x070
 #define I2O_CLASS_FLOPPY_DEVICE 		0x071
-#define I2O_CLASS_BUS_ADAPTER_PORT		0x080
+#define I2O_CLASS_BUS_ADAPTER			0x080
 #define I2O_CLASS_PEER_TRANSPORT_AGENT		0x090
 #define I2O_CLASS_PEER_TRANSPORT		0x091
 #define	I2O_CLASS_END				0xfff
@@ -399,4 +402,26 @@ typedef struct _i2o_status_block {
 #define ADAPTER_STATE_FAILED			0x10
 #define ADAPTER_STATE_FAULTED			0x11
 
+/*
+ *	Software module types
+ */
+#define I2O_SOFTWARE_MODULE_IRTOS		0x11
+#define I2O_SOFTWARE_MODULE_IOP_PRIVATE		0x22
+#define I2O_SOFTWARE_MODULE_IOP_CONFIG		0x23
+
+/*
+ *	Vendors
+ */
+#define I2O_VENDOR_DPT				0x001b
+
+/*
+ * DPT / Adaptec specific values for i2o_sg_io_hdr flags.
+ */
+#define I2O_DPT_SG_FLAG_INTERPRET		0x00010000
+#define I2O_DPT_SG_FLAG_PHYSICAL		0x00020000
+
+#define I2O_DPT_FLASH_FRAG_SIZE			0x10000
+#define I2O_DPT_FLASH_READ			0x0101
+#define I2O_DPT_FLASH_WRITE			0x0102
+
 #endif				/* _I2O_DEV_H */
diff --git a/include/linux/i2o.h b/include/linux/i2o.h
--- a/include/linux/i2o.h
+++ b/include/linux/i2o.h
@@ -119,12 +119,21 @@ struct i2o_driver {
 };
 
 /*
- *	Contains all information which are necessary for DMA operations
+ *	Contains DMA mapped address information
  */
 struct i2o_dma {
 	void *virt;
 	dma_addr_t phys;
-	u32 len;
+	size_t len;
+};
+
+/*
+ *	Contains IO mapped address information
+ */
+struct i2o_io {
+	void __iomem *virt;
+	unsigned long phys;
+	unsigned long len;
 };
 
 /*
@@ -147,28 +156,25 @@ struct i2o_controller {
 
 	struct pci_dev *pdev;	/* PCI device */
 
-	unsigned int short_req:1;	/* use small block sizes */
+	unsigned int promise:1;	/* Promise controller */
+	unsigned int adaptec:1;	/* DPT / Adaptec controller */
+	unsigned int raptor:1;	/* split bar */
 	unsigned int no_quiesce:1;	/* dont quiesce before reset */
-	unsigned int raptor:1;		/* split bar */
-	unsigned int promise:1;		/* Promise controller */
-
-#ifdef CONFIG_MTRR
-	int mtrr_reg0;
-	int mtrr_reg1;
-#endif
+	unsigned int short_req:1;	/* use small block sizes */
+	unsigned int limit_sectors:1;	/* limit number of sectors / request */
+	unsigned int pae_support:1;	/* controller has 64-bit SGL support */
 
 	struct list_head devices;	/* list of I2O devices */
-
-	struct notifier_block *event_notifer;	/* Events */
-	atomic_t users;
 	struct list_head list;	/* Controller list */
-	void __iomem *post_port;	/* Inbout port address */
-	void __iomem *reply_port;	/* Outbound port address */
-	void __iomem *irq_mask;		/* Interrupt register address */
+
+	void __iomem *in_port;	/* Inbout port address */
+	void __iomem *out_port;	/* Outbound port address */
+	void __iomem *irq_status;	/* Interrupt status register address */
+	void __iomem *irq_mask;	/* Interrupt mask register address */
 
 	/* Dynamic LCT related data */
 
-	struct i2o_dma status;	/* status of IOP */
+	struct i2o_dma status;	/* IOP status block */
 
 	struct i2o_dma hrt;	/* HW Resource Table */
 	i2o_lct *lct;		/* Logical Config Table */
@@ -176,21 +182,19 @@ struct i2o_controller {
 	struct semaphore lct_lock;	/* Lock for LCT updates */
 	struct i2o_dma status_block;	/* IOP status block */
 
-	struct i2o_dma base;	/* controller messaging unit */
-	struct i2o_dma in_queue;	/* inbound message queue Host->IOP */
+	struct i2o_io base;	/* controller messaging unit */
+	struct i2o_io in_queue;	/* inbound message queue Host->IOP */
 	struct i2o_dma out_queue;	/* outbound message queue IOP->Host */
 
-	unsigned int battery:1;		/* Has a battery backup */
+	unsigned int battery:1;	/* Has a battery backup */
 	unsigned int io_alloc:1;	/* An I/O resource was allocated */
 	unsigned int mem_alloc:1;	/* A memory resource was allocated */
 
 	struct resource io_resource;	/* I/O resource allocated to the IOP */
 	struct resource mem_resource;	/* Mem resource allocated to the IOP */
 
-	struct proc_dir_entry *proc_entry;	/* /proc dir */
-
-	struct list_head bus_list;	/* list of busses on IOP */
 	struct device device;
+	struct class_device classdev;	/* I2O controller class */
 	struct i2o_device *exec;	/* Executive */
 #if BITS_PER_LONG == 64
 	spinlock_t context_list_lock;	/* lock for context_list */
@@ -241,9 +245,10 @@ struct i2o_sys_tbl {
 extern struct list_head i2o_controllers;
 
 /* Message functions */
-static inline u32 i2o_msg_get(struct i2o_controller *, struct i2o_message __iomem **);
-extern u32 i2o_msg_get_wait(struct i2o_controller *, struct i2o_message __iomem **,
-			    int);
+static inline u32 i2o_msg_get(struct i2o_controller *,
+			      struct i2o_message __iomem **);
+extern u32 i2o_msg_get_wait(struct i2o_controller *,
+			    struct i2o_message __iomem **, int);
 static inline void i2o_msg_post(struct i2o_controller *, u32);
 static inline int i2o_msg_post_wait(struct i2o_controller *, u32,
 				    unsigned long);
@@ -252,15 +257,6 @@ extern int i2o_msg_post_wait_mem(struct 
 extern void i2o_msg_nop(struct i2o_controller *, u32);
 static inline void i2o_flush_reply(struct i2o_controller *, u32);
 
-/* DMA handling functions */
-static inline int i2o_dma_alloc(struct device *, struct i2o_dma *, size_t,
-				unsigned int);
-static inline void i2o_dma_free(struct device *, struct i2o_dma *);
-int i2o_dma_realloc(struct device *, struct i2o_dma *, size_t, unsigned int);
-
-static inline int i2o_dma_map(struct device *, struct i2o_dma *);
-static inline void i2o_dma_unmap(struct device *, struct i2o_dma *);
-
 /* IOP functions */
 extern int i2o_status_get(struct i2o_controller *);
 
@@ -285,6 +281,16 @@ static inline u32 i2o_ptr_high(void *ptr
 {
 	return (u32) ((u64) ptr >> 32);
 };
+
+static inline u32 i2o_dma_low(dma_addr_t dma_addr)
+{
+	return (u32) (u64) dma_addr;
+};
+
+static inline u32 i2o_dma_high(dma_addr_t dma_addr)
+{
+	return (u32) ((u64) dma_addr >> 32);
+};
 #else
 static inline u32 i2o_cntxt_list_add(struct i2o_controller *c, void *ptr)
 {
@@ -315,7 +321,245 @@ static inline u32 i2o_ptr_high(void *ptr
 {
 	return 0;
 };
+
+static inline u32 i2o_dma_low(dma_addr_t dma_addr)
+{
+	return (u32) dma_addr;
+};
+
+static inline u32 i2o_dma_high(dma_addr_t dma_addr)
+{
+	return 0;
+};
+#endif
+
+/**
+ *	i2o_sg_tablesize - Calculate the maximum number of elements in a SGL
+ *	@c: I2O controller for which the calculation should be done
+ *	@body_size: maximum body size used for message in 32-bit words.
+ *
+ *	Return the maximum number of SG elements in a SG list.
+ */
+static inline u16 i2o_sg_tablesize(struct i2o_controller *c, u16 body_size)
+{
+	i2o_status_block *sb = c->status_block.virt;
+	u16 sg_count =
+	    (sb->inbound_frame_size - sizeof(struct i2o_message) / 4) -
+	    body_size;
+
+	if (c->pae_support) {
+		/*
+		 * for 64-bit a SG attribute element must be added and each
+		 * SG element needs 12 bytes instead of 8.
+		 */
+		sg_count -= 2;
+		sg_count /= 3;
+	} else
+		sg_count /= 2;
+
+	if (c->short_req && (sg_count > 8))
+		sg_count = 8;
+
+	return sg_count;
+};
+
+/**
+ *	i2o_dma_map_single - Map pointer to controller and fill in I2O message.
+ *	@c: I2O controller
+ *	@ptr: pointer to the data which should be mapped
+ *	@size: size of data in bytes
+ *	@direction: DMA_TO_DEVICE / DMA_FROM_DEVICE
+ *	@sg_ptr: pointer to the SG list inside the I2O message
+ *
+ *	This function does all necessary DMA handling and also writes the I2O
+ *	SGL elements into the I2O message. For details on DMA handling see also
+ *	dma_map_single(). The pointer sg_ptr will only be set to the end of the
+ *	SG list if the allocation was successful.
+ *
+ *	Returns DMA address which must be checked for failures using
+ *	dma_mapping_error().
+ */
+static inline dma_addr_t i2o_dma_map_single(struct i2o_controller *c, void *ptr,
+					    size_t size,
+					    enum dma_data_direction direction,
+					    u32 __iomem ** sg_ptr)
+{
+	u32 sg_flags;
+	u32 __iomem *mptr = *sg_ptr;
+	dma_addr_t dma_addr;
+
+	switch (direction) {
+	case DMA_TO_DEVICE:
+		sg_flags = 0xd4000000;
+		break;
+	case DMA_FROM_DEVICE:
+		sg_flags = 0xd0000000;
+		break;
+	default:
+		return 0;
+	}
+
+	dma_addr = dma_map_single(&c->pdev->dev, ptr, size, direction);
+	if (!dma_mapping_error(dma_addr)) {
+#ifdef CONFIG_I2O_EXT_ADAPTEC_DMA64
+		if ((sizeof(dma_addr_t) > 4) && c->pae_support) {
+			writel(0x7C020002, mptr++);
+			writel(PAGE_SIZE, mptr++);
+		}
+#endif
+
+		writel(sg_flags | size, mptr++);
+		writel(i2o_dma_low(dma_addr), mptr++);
+#ifdef CONFIG_I2O_EXT_ADAPTEC_DMA64
+		if ((sizeof(dma_addr_t) > 4) && c->pae_support)
+			writel(i2o_dma_high(dma_addr), mptr++);
+#endif
+		*sg_ptr = mptr;
+	}
+	return dma_addr;
+};
+
+/**
+ *	i2o_dma_map_sg - Map a SG List to controller and fill in I2O message.
+ *	@c: I2O controller
+ *	@sg: SG list to be mapped
+ *	@sg_count: number of elements in the SG list
+ *	@direction: DMA_TO_DEVICE / DMA_FROM_DEVICE
+ *	@sg_ptr: pointer to the SG list inside the I2O message
+ *
+ *	This function does all necessary DMA handling and also writes the I2O
+ *	SGL elements into the I2O message. For details on DMA handling see also
+ *	dma_map_sg(). The pointer sg_ptr will only be set to the end of the SG
+ *	list if the allocation was successful.
+ *
+ *	Returns 0 on failure or 1 on success.
+ */
+static inline int i2o_dma_map_sg(struct i2o_controller *c,
+				 struct scatterlist *sg, int sg_count,
+				 enum dma_data_direction direction,
+				 u32 __iomem ** sg_ptr)
+{
+	u32 sg_flags;
+	u32 __iomem *mptr = *sg_ptr;
+
+	switch (direction) {
+	case DMA_TO_DEVICE:
+		sg_flags = 0x14000000;
+		break;
+	case DMA_FROM_DEVICE:
+		sg_flags = 0x10000000;
+		break;
+	default:
+		return 0;
+	}
+
+	sg_count = dma_map_sg(&c->pdev->dev, sg, sg_count, direction);
+	if (!sg_count)
+		return 0;
+
+#ifdef CONFIG_I2O_EXT_ADAPTEC_DMA64
+	if ((sizeof(dma_addr_t) > 4) && c->pae_support) {
+		writel(0x7C020002, mptr++);
+		writel(PAGE_SIZE, mptr++);
+	}
+#endif
+
+	while (sg_count-- > 0) {
+		if (!sg_count)
+			sg_flags |= 0xC0000000;
+		writel(sg_flags | sg_dma_len(sg), mptr++);
+		writel(i2o_dma_low(sg_dma_address(sg)), mptr++);
+#ifdef CONFIG_I2O_EXT_ADAPTEC_DMA64
+		if ((sizeof(dma_addr_t) > 4) && c->pae_support)
+			writel(i2o_dma_high(sg_dma_address(sg)), mptr++);
 #endif
+		sg++;
+	}
+	*sg_ptr = mptr;
+
+	return 1;
+};
+
+/**
+ *	i2o_dma_alloc - Allocate DMA memory
+ *	@dev: struct device pointer to the PCI device of the I2O controller
+ *	@addr: i2o_dma struct which should get the DMA buffer
+ *	@len: length of the new DMA memory
+ *	@gfp_mask: GFP mask
+ *
+ *	Allocate a coherent DMA memory and write the pointers into addr.
+ *
+ *	Returns 0 on success or -ENOMEM on failure.
+ */
+static inline int i2o_dma_alloc(struct device *dev, struct i2o_dma *addr,
+				size_t len, unsigned int gfp_mask)
+{
+	struct pci_dev *pdev = to_pci_dev(dev);
+	int dma_64 = 0;
+
+	if ((sizeof(dma_addr_t) > 4) && (pdev->dma_mask == DMA_64BIT_MASK)) {
+		dma_64 = 1;
+		if (pci_set_dma_mask(pdev, DMA_32BIT_MASK))
+			return -ENOMEM;
+	}
+
+	addr->virt = dma_alloc_coherent(dev, len, &addr->phys, gfp_mask);
+
+	if ((sizeof(dma_addr_t) > 4) && dma_64)
+		if (pci_set_dma_mask(pdev, DMA_64BIT_MASK))
+			printk(KERN_WARNING "i2o: unable to set 64-bit DMA");
+
+	if (!addr->virt)
+		return -ENOMEM;
+
+	memset(addr->virt, 0, len);
+	addr->len = len;
+
+	return 0;
+};
+
+/**
+ *	i2o_dma_free - Free DMA memory
+ *	@dev: struct device pointer to the PCI device of the I2O controller
+ *	@addr: i2o_dma struct which contains the DMA buffer
+ *
+ *	Free a coherent DMA memory and set virtual address of addr to NULL.
+ */
+static inline void i2o_dma_free(struct device *dev, struct i2o_dma *addr)
+{
+	if (addr->virt) {
+		if (addr->phys)
+			dma_free_coherent(dev, addr->len, addr->virt,
+					  addr->phys);
+		else
+			kfree(addr->virt);
+		addr->virt = NULL;
+	}
+};
+
+/**
+ *	i2o_dma_realloc - Realloc DMA memory
+ *	@dev: struct device pointer to the PCI device of the I2O controller
+ *	@addr: pointer to a i2o_dma struct DMA buffer
+ *	@len: new length of memory
+ *	@gfp_mask: GFP mask
+ *
+ *	If there was something allocated in the addr, free it first. If len > 0
+ *	than try to allocate it and write the addresses back to the addr
+ *	structure. If len == 0 set the virtual address to NULL.
+ *
+ *	Returns the 0 on success or negative error code on failure.
+ */
+static inline int i2o_dma_realloc(struct device *dev, struct i2o_dma *addr,
+				  size_t len, unsigned int gfp_mask)
+{
+	i2o_dma_free(dev, addr);
+
+	if (len)
+		return i2o_dma_alloc(dev, addr, len, gfp_mask);
+
+	return 0;
+};
 
 /* I2O driver (OSM) functions */
 extern int i2o_driver_register(struct i2o_driver *);
@@ -385,49 +629,11 @@ extern int i2o_device_claim_release(stru
 /* Exec OSM functions */
 extern int i2o_exec_lct_get(struct i2o_controller *);
 
-/* device to i2o_device and driver to i2o_driver convertion functions */
+/* device / driver / kobject conversion functions */
 #define to_i2o_driver(drv) container_of(drv,struct i2o_driver, driver)
 #define to_i2o_device(dev) container_of(dev, struct i2o_device, device)
-
-/*
- *	Messenger inlines
- */
-static inline u32 I2O_POST_READ32(struct i2o_controller *c)
-{
-	rmb();
-	return readl(c->post_port);
-};
-
-static inline void I2O_POST_WRITE32(struct i2o_controller *c, u32 val)
-{
-	wmb();
-	writel(val, c->post_port);
-};
-
-static inline u32 I2O_REPLY_READ32(struct i2o_controller *c)
-{
-	rmb();
-	return readl(c->reply_port);
-};
-
-static inline void I2O_REPLY_WRITE32(struct i2o_controller *c, u32 val)
-{
-	wmb();
-	writel(val, c->reply_port);
-};
-
-static inline u32 I2O_IRQ_READ32(struct i2o_controller *c)
-{
-	rmb();
-	return readl(c->irq_mask);
-};
-
-static inline void I2O_IRQ_WRITE32(struct i2o_controller *c, u32 val)
-{
-	wmb();
-	writel(val, c->irq_mask);
-	wmb();
-};
+#define to_i2o_controller(dev) container_of(dev, struct i2o_controller, device)
+#define kobj_to_i2o_device(kobj) to_i2o_device(container_of(kobj, struct device, kobj))
 
 /**
  *	i2o_msg_get - obtain an I2O message from the IOP
@@ -443,11 +649,11 @@ static inline void I2O_IRQ_WRITE32(struc
  *	available returns I2O_QUEUE_EMPTY and msg is leaved untouched.
  */
 static inline u32 i2o_msg_get(struct i2o_controller *c,
-			      struct i2o_message __iomem **msg)
+			      struct i2o_message __iomem ** msg)
 {
-	u32 m;
+	u32 m = readl(c->in_port);
 
-	if ((m = I2O_POST_READ32(c)) != I2O_QUEUE_EMPTY)
+	if (m != I2O_QUEUE_EMPTY)
 		*msg = c->in_queue.virt + m;
 
 	return m;
@@ -462,7 +668,7 @@ static inline u32 i2o_msg_get(struct i2o
  */
 static inline void i2o_msg_post(struct i2o_controller *c, u32 m)
 {
-	I2O_POST_WRITE32(c, m);
+	writel(m, c->in_port);
 };
 
 /**
@@ -491,12 +697,10 @@ static inline int i2o_msg_post_wait(stru
  *	The I2O controller must be informed that the reply message is not needed
  *	anymore. If you forget to flush the reply, the message frame can't be
  *	used by the controller anymore and is therefore lost.
- *
- *	FIXME: is there a timeout after which the controller reuse the message?
  */
 static inline void i2o_flush_reply(struct i2o_controller *c, u32 m)
 {
-	I2O_REPLY_WRITE32(c, m);
+	writel(m, c->out_port);
 };
 
 /**
@@ -530,97 +734,13 @@ static inline struct i2o_message *i2o_ms
  *	work for receive side messages as they are kmalloc objects
  *	in a different pool.
  */
-static inline struct i2o_message __iomem *i2o_msg_in_to_virt(struct i2o_controller *c,
-						     u32 m)
+static inline struct i2o_message __iomem *i2o_msg_in_to_virt(struct
+							     i2o_controller *c,
+							     u32 m)
 {
 	return c->in_queue.virt + m;
 };
 
-/**
- *	i2o_dma_alloc - Allocate DMA memory
- *	@dev: struct device pointer to the PCI device of the I2O controller
- *	@addr: i2o_dma struct which should get the DMA buffer
- *	@len: length of the new DMA memory
- *	@gfp_mask: GFP mask
- *
- *	Allocate a coherent DMA memory and write the pointers into addr.
- *
- *	Returns 0 on success or -ENOMEM on failure.
- */
-static inline int i2o_dma_alloc(struct device *dev, struct i2o_dma *addr,
-				size_t len, unsigned int gfp_mask)
-{
-	addr->virt = dma_alloc_coherent(dev, len, &addr->phys, gfp_mask);
-	if (!addr->virt)
-		return -ENOMEM;
-
-	memset(addr->virt, 0, len);
-	addr->len = len;
-
-	return 0;
-};
-
-/**
- *	i2o_dma_free - Free DMA memory
- *	@dev: struct device pointer to the PCI device of the I2O controller
- *	@addr: i2o_dma struct which contains the DMA buffer
- *
- *	Free a coherent DMA memory and set virtual address of addr to NULL.
- */
-static inline void i2o_dma_free(struct device *dev, struct i2o_dma *addr)
-{
-	if (addr->virt) {
-		if (addr->phys)
-			dma_free_coherent(dev, addr->len, addr->virt,
-					  addr->phys);
-		else
-			kfree(addr->virt);
-		addr->virt = NULL;
-	}
-};
-
-/**
- *	i2o_dma_map - Map the memory to DMA
- *	@dev: struct device pointer to the PCI device of the I2O controller
- *	@addr: i2o_dma struct which should be mapped
- *
- *	Map the memory in addr->virt to coherent DMA memory and write the
- *	physical address into addr->phys.
- *
- *	Returns 0 on success or -ENOMEM on failure.
- */
-static inline int i2o_dma_map(struct device *dev, struct i2o_dma *addr)
-{
-	if (!addr->virt)
-		return -EFAULT;
-
-	if (!addr->phys)
-		addr->phys = dma_map_single(dev, addr->virt, addr->len,
-					    DMA_BIDIRECTIONAL);
-	if (!addr->phys)
-		return -ENOMEM;
-
-	return 0;
-};
-
-/**
- *	i2o_dma_unmap - Unmap the DMA memory
- *	@dev: struct device pointer to the PCI device of the I2O controller
- *	@addr: i2o_dma struct which should be unmapped
- *
- *	Unmap the memory in addr->virt from DMA memory.
- */
-static inline void i2o_dma_unmap(struct device *dev, struct i2o_dma *addr)
-{
-	if (!addr->virt)
-		return;
-
-	if (addr->phys) {
-		dma_unmap_single(dev, addr->phys, addr->len, DMA_BIDIRECTIONAL);
-		addr->phys = 0;
-	}
-};
-
 /*
  *	Endian handling wrapped into the macro - keeps the core code
  *	cleaner.
@@ -773,6 +893,14 @@ extern void i2o_debug_state(struct i2o_c
 #define I2O_CMD_SCSI_BUSRESET		0x27
 
 /*
+ * Bus Adapter Class
+ */
+#define I2O_CMD_BUS_ADAPTER_RESET	0x85
+#define I2O_CMD_BUS_RESET		0x87
+#define I2O_CMD_BUS_SCAN		0x89
+#define I2O_CMD_BUS_QUIESCE		0x8b
+
+/*
  * Random Block Storage Class
  */
 #define I2O_CMD_BLOCK_READ		0x30
@@ -784,7 +912,7 @@ extern void i2o_debug_state(struct i2o_c
 #define I2O_CMD_BLOCK_MEJECT		0x43
 #define I2O_CMD_BLOCK_POWER		0x70
 
-#define I2O_PRIVATE_MSG			0xFF
+#define I2O_CMD_PRIVATE			0xFF
 
 /* Command status values  */
 
@@ -922,7 +1050,7 @@ extern void i2o_debug_state(struct i2o_c
 #define I2OVER15	0x0001
 #define I2OVER20	0x0002
 
-/* Default is 1.5, FIXME: Need support for both 1.5 and 2.0 */
+/* Default is 1.5 */
 #define I2OVERSION	I2OVER15
 
 #define SGL_OFFSET_0    I2OVERSION
@@ -933,9 +1061,9 @@ extern void i2o_debug_state(struct i2o_c
 #define SGL_OFFSET_8    (0x0080 | I2OVERSION)
 #define SGL_OFFSET_9    (0x0090 | I2OVERSION)
 #define SGL_OFFSET_10   (0x00A0 | I2OVERSION)
-
-#define TRL_OFFSET_5    (0x0050 | I2OVERSION)
-#define TRL_OFFSET_6    (0x0060 | I2OVERSION)
+#define SGL_OFFSET_11   (0x00B0 | I2OVERSION)
+#define SGL_OFFSET_12   (0x00C0 | I2OVERSION)
+#define SGL_OFFSET(x)   (((x)<<4) | I2OVERSION)
 
 /* Transaction Reply Lists (TRL) Control Word structure */
 #define TRL_SINGLE_FIXED_LENGTH		0x00
@@ -962,17 +1090,13 @@ extern void i2o_debug_state(struct i2o_c
 #define ELEVEN_WORD_MSG_SIZE	0x000B0000
 #define I2O_MESSAGE_SIZE(x)	((x)<<16)
 
-/* Special TID Assignments */
-
+/* special TID assignments */
 #define ADAPTER_TID		0
 #define HOST_TID		1
 
-#define MSG_FRAME_SIZE		128	/* i2o_scsi assumes >= 32 */
-#define REPLY_FRAME_SIZE	17
-#define SG_TABLESIZE		30
-#define NMBR_MSG_FRAMES		128
-
-#define MSG_POOL_SIZE		(MSG_FRAME_SIZE*NMBR_MSG_FRAMES*sizeof(u32))
+/* outbound queue defines */
+#define I2O_MAX_OUTBOUND_MSG_FRAMES	128
+#define I2O_OUTBOUND_MSG_FRAME_SIZE	128	/* in 32-bit words */
 
 #define I2O_POST_WAIT_OK	0
 #define I2O_POST_WAIT_TIMEOUT	-ETIMEDOUT
@@ -993,11 +1117,10 @@ extern void i2o_debug_state(struct i2o_c
 #define I2O_HRT_GET_TRIES		3
 #define I2O_LCT_GET_TRIES		3
 
-/* request queue sizes */
+/* defines for max_sectors and max_phys_segments */
 #define I2O_MAX_SECTORS			1024
-#define I2O_MAX_SEGMENTS		128
-
-#define I2O_REQ_MEMPOOL_SIZE		32
+#define I2O_MAX_SECTORS_LIMITED		256
+#define I2O_MAX_PHYS_SEGMENTS		MAX_PHYS_SEGMENTS
 
 #endif				/* __KERNEL__ */
 #endif				/* _I2O_H */
diff --git a/include/linux/ide.h b/include/linux/ide.h
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -917,7 +917,7 @@ typedef struct hwif_s {
 	unsigned dma;
 
 	void (*led_act)(void *data, int rw);
-} ide_hwif_t;
+} ____cacheline_maxaligned_in_smp ide_hwif_t;
 
 /*
  *  internal ide interrupt handler type
@@ -1501,4 +1501,10 @@ extern struct bus_type ide_bus_type;
 #define ide_id_has_flush_cache_ext(id)	\
 	(((id)->cfs_enable_2 & 0x2400) == 0x2400)
 
+static inline int hwif_to_node(ide_hwif_t *hwif)
+{
+	struct pci_dev *dev = hwif->pci_dev;
+	return dev ? pcibus_to_node(dev->bus) : -1;
+}
+
 #endif /* _IDE_H */
diff --git a/include/linux/if.h b/include/linux/if.h
--- a/include/linux/if.h
+++ b/include/linux/if.h
@@ -33,7 +33,7 @@
 #define	IFF_LOOPBACK	0x8		/* is a loopback net		*/
 #define	IFF_POINTOPOINT	0x10		/* interface is has p-p link	*/
 #define	IFF_NOTRAILERS	0x20		/* avoid use of trailers	*/
-#define	IFF_RUNNING	0x40		/* resources allocated		*/
+#define	IFF_RUNNING	0x40		/* interface running and carrier ok */
 #define	IFF_NOARP	0x80		/* no ARP protocol		*/
 #define	IFF_PROMISC	0x100		/* receive all packets		*/
 #define	IFF_ALLMULTI	0x200		/* receive all multicast packets*/
diff --git a/include/linux/if_bonding.h b/include/linux/if_bonding.h
--- a/include/linux/if_bonding.h
+++ b/include/linux/if_bonding.h
@@ -35,6 +35,9 @@
  *
  * 2003/12/01 - Shmulik Hen <shmulik.hen at intel dot com>
  *	- Code cleanup and style changes
+ *
+ * 2005/05/05 - Jason Gabler <jygabler at lbl dot gov>
+ *      - added definitions for various XOR hashing policies
  */
 
 #ifndef _LINUX_IF_BONDING_H
@@ -80,6 +83,10 @@
 
 #define BOND_DEFAULT_MAX_BONDS  1   /* Default maximum number of devices to support */
 
+/* hashing types */
+#define BOND_XMIT_POLICY_LAYER2		0 /* layer 2 (MAC only), default */
+#define BOND_XMIT_POLICY_LAYER34	1 /* layer 3+4 (IP ^ MAC) */
+
 typedef struct ifbond {
 	__s32 bond_mode;
 	__s32 num_slaves;
diff --git a/include/linux/if_shaper.h b/include/linux/if_shaper.h
--- a/include/linux/if_shaper.h
+++ b/include/linux/if_shaper.h
@@ -23,7 +23,7 @@ struct shaper
 	__u32 shapeclock;
 	unsigned long recovery;	/* Time we can next clock a packet out on
 				   an empty queue */
-	struct semaphore sem;
+	spinlock_t lock;
         struct net_device_stats stats;
 	struct net_device *dev;
 	int  (*hard_start_xmit) (struct sk_buff *skb,
diff --git a/include/linux/igmp.h b/include/linux/igmp.h
--- a/include/linux/igmp.h
+++ b/include/linux/igmp.h
@@ -148,7 +148,6 @@ struct ip_sf_socklist
 struct ip_mc_socklist
 {
 	struct ip_mc_socklist	*next;
-	int			count;
 	struct ip_mreqn		multi;
 	unsigned int		sfmode;		/* MCAST_{INCLUDE,EXCLUDE} */
 	struct ip_sf_socklist	*sflist;
diff --git a/include/linux/in6.h b/include/linux/in6.h
--- a/include/linux/in6.h
+++ b/include/linux/in6.h
@@ -156,7 +156,7 @@ struct in6_flowlabel_req
 #define IPV6_CHECKSUM		7
 #define IPV6_HOPLIMIT		8
 #define IPV6_NEXTHOP		9
-#define IPV6_AUTHHDR		10
+#define IPV6_AUTHHDR		10	/* obsolete */
 #define IPV6_FLOWINFO		11
 
 #define IPV6_UNICAST_HOPS	16
diff --git a/include/linux/init.h b/include/linux/init.h
--- a/include/linux/init.h
+++ b/include/linux/init.h
@@ -229,6 +229,18 @@ void __init parse_early_param(void);
 #define __devexitdata __exitdata
 #endif
 
+#ifdef CONFIG_HOTPLUG_CPU
+#define __cpuinit
+#define __cpuinitdata
+#define __cpuexit
+#define __cpuexitdata
+#else
+#define __cpuinit	__init
+#define __cpuinitdata __initdata
+#define __cpuexit __exit
+#define __cpuexitdata	__exitdata
+#endif
+
 /* Functions marked as __devexit may be discarded at kernel link time, depending
    on config options.  Newer versions of binutils detect references from
    retained sections to discarded sections and flag an error.  Pointers to
diff --git a/include/linux/init_task.h b/include/linux/init_task.h
--- a/include/linux/init_task.h
+++ b/include/linux/init_task.h
@@ -81,6 +81,7 @@ extern struct group_info init_groups;
 	.mm		= NULL,						\
 	.active_mm	= &init_mm,					\
 	.run_list	= LIST_HEAD_INIT(tsk.run_list),			\
+	.ioprio		= 0,						\
 	.time_slice	= HZ,						\
 	.tasks		= LIST_HEAD_INIT(tsk.tasks),			\
 	.ptrace_children= LIST_HEAD_INIT(tsk.ptrace_children),		\
@@ -108,9 +109,9 @@ extern struct group_info init_groups;
 	.blocked	= {{0}},					\
 	.alloc_lock	= SPIN_LOCK_UNLOCKED,				\
 	.proc_lock	= SPIN_LOCK_UNLOCKED,				\
-	.switch_lock	= SPIN_LOCK_UNLOCKED,				\
 	.journal_info	= NULL,						\
 	.cpu_timers	= INIT_CPU_TIMERS(tsk.cpu_timers),		\
+	.fs_excl	= ATOMIC_INIT(0),				\
 }
 
 
diff --git a/include/linux/inotify.h b/include/linux/inotify.h
new file mode 100644
--- /dev/null
+++ b/include/linux/inotify.h
@@ -0,0 +1,110 @@
+/*
+ * Inode based directory notification for Linux
+ *
+ * Copyright (C) 2005 John McCutchan
+ */
+
+#ifndef _LINUX_INOTIFY_H
+#define _LINUX_INOTIFY_H
+
+#include <linux/types.h>
+
+/*
+ * struct inotify_event - structure read from the inotify device for each event
+ *
+ * When you are watching a directory, you will receive the filename for events
+ * such as IN_CREATE, IN_DELETE, IN_OPEN, IN_CLOSE, ..., relative to the wd.
+ */
+struct inotify_event {
+	__s32		wd;		/* watch descriptor */
+	__u32		mask;		/* watch mask */
+	__u32		cookie;		/* cookie to synchronize two events */
+	__u32		len;		/* length (including nulls) of name */
+	char		name[0];	/* stub for possible name */
+};
+
+/* the following are legal, implemented events that user-space can watch for */
+#define IN_ACCESS		0x00000001	/* File was accessed */
+#define IN_MODIFY		0x00000002	/* File was modified */
+#define IN_ATTRIB		0x00000004	/* Metadata changed */
+#define IN_CLOSE_WRITE		0x00000008	/* Writtable file was closed */
+#define IN_CLOSE_NOWRITE	0x00000010	/* Unwrittable file closed */
+#define IN_OPEN			0x00000020	/* File was opened */
+#define IN_MOVED_FROM		0x00000040	/* File was moved from X */
+#define IN_MOVED_TO		0x00000080	/* File was moved to Y */
+#define IN_CREATE		0x00000100	/* Subfile was created */
+#define IN_DELETE		0x00000200	/* Subfile was deleted */
+#define IN_DELETE_SELF		0x00000400	/* Self was deleted */
+#define IN_MOVE_SELF		0x00000800	/* Self was moved */
+
+/* the following are legal events.  they are sent as needed to any watch */
+#define IN_UNMOUNT		0x00002000	/* Backing fs was unmounted */
+#define IN_Q_OVERFLOW		0x00004000	/* Event queued overflowed */
+#define IN_IGNORED		0x00008000	/* File was ignored */
+
+/* helper events */
+#define IN_CLOSE		(IN_CLOSE_WRITE | IN_CLOSE_NOWRITE) /* close */
+#define IN_MOVE			(IN_MOVED_FROM | IN_MOVED_TO) /* moves */
+
+/* special flags */
+#define IN_ISDIR		0x40000000	/* event occurred against dir */
+#define IN_ONESHOT		0x80000000	/* only send event once */
+
+/*
+ * All of the events - we build the list by hand so that we can add flags in
+ * the future and not break backward compatibility.  Apps will get only the
+ * events that they originally wanted.  Be sure to add new events here!
+ */
+#define IN_ALL_EVENTS	(IN_ACCESS | IN_MODIFY | IN_ATTRIB | IN_CLOSE_WRITE | \
+			 IN_CLOSE_NOWRITE | IN_OPEN | IN_MOVED_FROM | \
+			 IN_MOVED_TO | IN_DELETE | IN_CREATE | IN_DELETE_SELF | \
+			 IN_MOVE_SELF)
+
+#ifdef __KERNEL__
+
+#include <linux/dcache.h>
+#include <linux/fs.h>
+#include <linux/config.h>
+
+#ifdef CONFIG_INOTIFY
+
+extern void inotify_inode_queue_event(struct inode *, __u32, __u32,
+				      const char *);
+extern void inotify_dentry_parent_queue_event(struct dentry *, __u32, __u32,
+					      const char *);
+extern void inotify_unmount_inodes(struct list_head *);
+extern void inotify_inode_is_dead(struct inode *);
+extern u32 inotify_get_cookie(void);
+
+#else
+
+static inline void inotify_inode_queue_event(struct inode *inode,
+					     __u32 mask, __u32 cookie,
+					     const char *filename)
+{
+}
+
+static inline void inotify_dentry_parent_queue_event(struct dentry *dentry,
+						     __u32 mask, __u32 cookie,
+						     const char *filename)
+{
+}
+
+static inline void inotify_unmount_inodes(struct list_head *list)
+{
+}
+
+static inline void inotify_inode_is_dead(struct inode *inode)
+{
+}
+
+static inline u32 inotify_get_cookie(void)
+{
+	return 0;
+}
+
+#endif	/* CONFIG_INOTIFY */
+
+#endif	/* __KERNEL __ */
+
+#endif	/* _LINUX_INOTIFY_H */
diff --git a/include/linux/input.h b/include/linux/input.h
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -811,9 +811,9 @@ struct input_dev {
 
 	void *private;
 
-	char *name;
-	char *phys;
-	char *uniq;
+	const char *name;
+	const char *phys;
+	const char *uniq;
 	struct input_id id;
 
 	unsigned long evbit[NBITS(EV_MAX)];
@@ -859,6 +859,10 @@ struct input_dev {
 	int (*erase_effect)(struct input_dev *dev, int effect_id);
 
 	struct input_handle *grab;
+
+	struct semaphore sem;	/* serializes open and close operations */
+	unsigned int users;
+
 	struct device *dev;
 
 	struct list_head	h_list;
@@ -1015,7 +1019,7 @@ static inline void input_set_abs_params(
 	dev->absbit[LONG(axis)] |= BIT(axis);
 }
 
-extern struct class_simple *input_class;
+extern struct class *input_class;
 
 #endif
 #endif
diff --git a/include/linux/ioc4.h b/include/linux/ioc4.h
new file mode 100644
--- /dev/null
+++ b/include/linux/ioc4.h
@@ -0,0 +1,179 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 2005 Silicon Graphics, Inc.  All Rights Reserved.
+ */
+
+#ifndef _LINUX_IOC4_H
+#define _LINUX_IOC4_H
+
+#include <linux/interrupt.h>
+
+/***************
+ * Definitions *
+ ***************/
+
+/* Miscellaneous values inherent to hardware */
+
+#define IOC4_EXTINT_COUNT_DIVISOR 520	/* PCI clocks per COUNT tick */
+
+/***********************************
+ * Structures needed by subdrivers *
+ ***********************************/
+
+/* This structure fully describes the IOC4 miscellaneous registers which
+ * appear at bar[0]+0x00000 through bar[0]+0x0005c.  The corresponding
+ * PCI resource is managed by the main IOC4 driver because it contains
+ * registers of interest to many different IOC4 subdrivers.
+ */
+struct ioc4_misc_regs {
+	/* Miscellaneous IOC4 registers */
+	union ioc4_pci_err_addr_l {
+		uint32_t raw;
+		struct {
+			uint32_t valid:1;	/* Address captured */
+			uint32_t master_id:4;	/* Unit causing error
+						 * 0/1: Serial port 0 TX/RX
+						 * 2/3: Serial port 1 TX/RX
+						 * 4/5: Serial port 2 TX/RX
+						 * 6/7: Serial port 3 TX/RX
+						 * 8: ATA/ATAPI
+						 * 9-15: Undefined
+						 */
+			uint32_t mul_err:1;	/* Multiple errors occurred */
+			uint32_t addr:26;	/* Bits 31-6 of error addr */
+		} fields;
+	} pci_err_addr_l;
+	uint32_t pci_err_addr_h;	/* Bits 63-32 of error addr */
+	union ioc4_sio_int {
+		uint32_t raw;
+		struct {
+			uint8_t tx_mt:1;	/* TX ring buffer empty */
+			uint8_t rx_full:1;	/* RX ring buffer full */
+			uint8_t rx_high:1;	/* RX high-water exceeded */
+			uint8_t rx_timer:1;	/* RX timer has triggered */
+			uint8_t delta_dcd:1;	/* DELTA_DCD seen */
+			uint8_t delta_cts:1;	/* DELTA_CTS seen */
+			uint8_t intr_pass:1;	/* Interrupt pass-through */
+			uint8_t tx_explicit:1;	/* TX, MCW, or delay complete */
+		} fields[4];
+	} sio_ir;		/* Serial interrupt state */
+	union ioc4_other_int {
+		uint32_t raw;
+		struct {
+			uint32_t ata_int:1;	/* ATA port passthru */
+			uint32_t ata_memerr:1;	/* ATA halted by mem error */
+			uint32_t memerr:4;	/* Serial halted by mem err */
+			uint32_t kbd_int:1;	/* kbd/mouse intr asserted */
+			uint32_t reserved:16;	/* zero */
+			uint32_t rt_int:1;	/* INT_OUT section latch */
+			uint32_t gen_int:8;	/* Intr. from generic pins */
+		} fields;
+	} other_ir;		/* Other interrupt state */
+	union ioc4_sio_int sio_ies;	/* Serial interrupt enable set */
+	union ioc4_other_int other_ies;	/* Other interrupt enable set */
+	union ioc4_sio_int sio_iec;	/* Serial interrupt enable clear */
+	union ioc4_other_int other_iec;	/* Other interrupt enable clear */
+	union ioc4_sio_cr {
+		uint32_t raw;
+		struct {
+			uint32_t cmd_pulse:4;	/* Bytebus strobe width */
+			uint32_t arb_diag:3;	/* PCI bus requester */
+			uint32_t sio_diag_idle:1;	/* Active ser req? */
+			uint32_t ata_diag_idle:1;	/* Active ATA req? */
+			uint32_t ata_diag_active:1;	/* ATA req is winner */
+			uint32_t reserved:22;	/* zero */
+		} fields;
+	} sio_cr;
+	uint32_t unused1;
+	union ioc4_int_out {
+		uint32_t raw;
+		struct {
+			uint32_t count:16;	/* Period control */
+			uint32_t mode:3;	/* Output signal shape */
+			uint32_t reserved:11;	/* zero */
+			uint32_t diag:1;	/* Timebase control */
+			uint32_t int_out:1;	/* Current value */
+		} fields;
+	} int_out;		/* External interrupt output control */
+	uint32_t unused2;
+	union ioc4_gpcr {
+		uint32_t raw;
+		struct {
+			uint32_t dir:8;	/* Pin direction */
+			uint32_t edge:8;	/* Edge/level mode */
+			uint32_t reserved1:4;	/* zero */
+			uint32_t int_out_en:1;	/* INT_OUT enable */
+			uint32_t reserved2:11;	/* zero */
+		} fields;
+	} gpcr_s;		/* Generic PIO control set */
+	union ioc4_gpcr gpcr_c;	/* Generic PIO control clear */
+	union ioc4_gpdr {
+		uint32_t raw;
+		struct {
+			uint32_t gen_pin:8;	/* State of pins */
+			uint32_t reserved:24;
+		} fields;
+	} gpdr;			/* Generic PIO data */
+	uint32_t unused3;
+	union ioc4_gppr {
+		uint32_t raw;
+		struct {
+			uint32_t gen_pin:1;	/* Single pin state */
+			uint32_t reserved:31;
+		} fields;
+	} gppr[8];		/* Generic PIO pins */
+};
+
+/* Masks for GPCR DIR pins */
+#define IOC4_GPCR_DIR_0 0x01	/* External interrupt output */
+#define IOC4_GPCR_DIR_1 0x02	/* External interrupt input */
+#define IOC4_GPCR_DIR_2 0x04
+#define IOC4_GPCR_DIR_3 0x08	/* Keyboard/mouse presence */
+#define IOC4_GPCR_DIR_4 0x10	/* Ser. port 0 xcvr select (0=232, 1=422) */
+#define IOC4_GPCR_DIR_5 0x20	/* Ser. port 1 xcvr select (0=232, 1=422) */
+#define IOC4_GPCR_DIR_6 0x40	/* Ser. port 2 xcvr select (0=232, 1=422) */
+#define IOC4_GPCR_DIR_7 0x80	/* Ser. port 3 xcvr select (0=232, 1=422) */
+
+/* Masks for GPCR EDGE pins */
+#define IOC4_GPCR_EDGE_0 0x01
+#define IOC4_GPCR_EDGE_1 0x02	/* External interrupt input */
+#define IOC4_GPCR_EDGE_2 0x04
+#define IOC4_GPCR_EDGE_3 0x08
+#define IOC4_GPCR_EDGE_4 0x10
+#define IOC4_GPCR_EDGE_5 0x20
+#define IOC4_GPCR_EDGE_6 0x40
+#define IOC4_GPCR_EDGE_7 0x80
+
+/* One of these per IOC4 */
+struct ioc4_driver_data {
+	struct list_head idd_list;
+	unsigned long idd_bar0;
+	struct pci_dev *idd_pdev;
+	const struct pci_device_id *idd_pci_id;
+	struct __iomem ioc4_misc_regs *idd_misc_regs;
+	unsigned long count_period;
+	void *idd_serial_data;
+};
+
+/* One per submodule */
+struct ioc4_submodule {
+	struct list_head is_list;
+	char *is_name;
+	struct module *is_owner;
+	int (*is_probe) (struct ioc4_driver_data *);
+	int (*is_remove) (struct ioc4_driver_data *);
+};
+
+#define IOC4_NUM_CARDS		8	/* max cards per partition */
+
+/**********************************
+ * Functions needed by submodules *
+ **********************************/
+
+extern int ioc4_register_submodule(struct ioc4_submodule *);
+extern void ioc4_unregister_submodule(struct ioc4_submodule *);
+
+#endif				/* _LINUX_IOC4_H */
diff --git a/include/linux/ioc4_common.h b/include/linux/ioc4_common.h
deleted file mode 100644
--- a/include/linux/ioc4_common.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (c) 2005 Silicon Graphics, Inc.  All Rights Reserved.
- */
-
-#ifndef _LINUX_IOC4_COMMON_H
-#define _LINUX_IOC4_COMMON_H
-
-/* prototypes */
-
-int ioc4_serial_init(void);
-
-int ioc4_serial_attach_one(struct pci_dev *pdev, const struct
-				pci_device_id *pci_id);
-int ioc4_ide_attach_one(struct pci_dev *pdev, const struct
-				pci_device_id *pci_id);
-
-#endif	/* _LINUX_IOC4_COMMON_H */
diff --git a/include/linux/ioprio.h b/include/linux/ioprio.h
new file mode 100644
--- /dev/null
+++ b/include/linux/ioprio.h
@@ -0,0 +1,85 @@
+#ifndef IOPRIO_H
+#define IOPRIO_H
+
+#include <linux/sched.h>
+
+/*
+ * Gives us 8 prio classes with 13-bits of data for each class
+ */
+#define IOPRIO_BITS		(16)
+#define IOPRIO_CLASS_SHIFT	(13)
+#define IOPRIO_PRIO_MASK	((1UL << IOPRIO_CLASS_SHIFT) - 1)
+
+#define IOPRIO_PRIO_CLASS(mask)	((mask) >> IOPRIO_CLASS_SHIFT)
+#define IOPRIO_PRIO_DATA(mask)	((mask) & IOPRIO_PRIO_MASK)
+#define IOPRIO_PRIO_VALUE(class, data)	(((class) << IOPRIO_CLASS_SHIFT) | data)
+
+#define ioprio_valid(mask)	(IOPRIO_PRIO_CLASS((mask)) != IOPRIO_CLASS_NONE)
+
+/*
+ * These are the io priority groups as implemented by CFQ. RT is the realtime
+ * class, it always gets premium service. BE is the best-effort scheduling
+ * class, the default for any process. IDLE is the idle scheduling class, it
+ * is only served when no one else is using the disk.
+ */
+enum {
+	IOPRIO_CLASS_NONE,
+	IOPRIO_CLASS_RT,
+	IOPRIO_CLASS_BE,
+	IOPRIO_CLASS_IDLE,
+};
+
+/*
+ * 8 best effort priority levels are supported
+ */
+#define IOPRIO_BE_NR	(8)
+
+enum {
+	IOPRIO_WHO_PROCESS = 1,
+	IOPRIO_WHO_PGRP,
+	IOPRIO_WHO_USER,
+};
+
+/*
+ * if process has set io priority explicitly, use that. if not, convert
+ * the cpu scheduler nice value to an io priority
+ */
+#define IOPRIO_NORM	(4)
+static inline int task_ioprio(struct task_struct *task)
+{
+	WARN_ON(!ioprio_valid(task->ioprio));
+	return IOPRIO_PRIO_DATA(task->ioprio);
+}
+
+static inline int task_nice_ioprio(struct task_struct *task)
+{
+	return (task_nice(task) + 20) / 5;
+}
+
+/*
+ * For inheritance, return the highest of the two given priorities
+ */
+static inline int ioprio_best(unsigned short aprio, unsigned short bprio)
+{
+	unsigned short aclass = IOPRIO_PRIO_CLASS(aprio);
+	unsigned short bclass = IOPRIO_PRIO_CLASS(bprio);
+
+	if (!ioprio_valid(aprio))
+		return bprio;
+	if (!ioprio_valid(bprio))
+		return aprio;
+
+	if (aclass == IOPRIO_CLASS_NONE)
+		aclass = IOPRIO_CLASS_BE;
+	if (bclass == IOPRIO_CLASS_NONE)
+		bclass = IOPRIO_CLASS_BE;
+
+	if (aclass == bclass)
+		return min(aprio, bprio);
+	if (aclass > bclass)
+		return bprio;
+	else
+		return aprio;
+}
+
+#endif
diff --git a/include/linux/ip.h b/include/linux/ip.h
--- a/include/linux/ip.h
+++ b/include/linux/ip.h
@@ -81,6 +81,7 @@
 #ifdef __KERNEL__
 #include <linux/config.h>
 #include <linux/types.h>
+#include <net/request_sock.h>
 #include <net/sock.h>
 #include <linux/igmp.h>
 #include <net/flow.h>
@@ -107,6 +108,26 @@ struct ip_options {
 
 #define optlength(opt) (sizeof(struct ip_options) + opt->optlen)
 
+struct inet_request_sock {
+	struct request_sock	req;
+	u32			loc_addr;
+	u32			rmt_addr;
+	u16			rmt_port;
+	u16			snd_wscale : 4, 
+				rcv_wscale : 4, 
+				tstamp_ok  : 1,
+				sack_ok	   : 1,
+				wscale_ok  : 1,
+				ecn_ok	   : 1,
+				acked	   : 1;
+	struct ip_options	*opt;
+};
+
+static inline struct inet_request_sock *inet_rsk(const struct request_sock *sk)
+{
+	return (struct inet_request_sock *)sk;
+}
+
 struct ipv6_pinfo;
 
 struct inet_sock {
diff --git a/include/linux/ipmi.h b/include/linux/ipmi.h
--- a/include/linux/ipmi.h
+++ b/include/linux/ipmi.h
@@ -209,6 +209,11 @@ struct kernel_ipmi_msg
 #include <linux/list.h>
 #include <linux/module.h>
 
+#ifdef CONFIG_PROC_FS
+#include <linux/proc_fs.h>
+extern struct proc_dir_entry *proc_ipmi_root;
+#endif /* CONFIG_PROC_FS */
+
 /* Opaque type for a IPMI message user.  One of these is needed to
    send and receive messages. */
 typedef struct ipmi_user *ipmi_user_t;
diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h
--- a/include/linux/ipv6.h
+++ b/include/linux/ipv6.h
@@ -193,6 +193,19 @@ struct inet6_skb_parm {
 
 #define IP6CB(skb)	((struct inet6_skb_parm*)((skb)->cb))
 
+struct tcp6_request_sock {
+	struct tcp_request_sock	req;
+	struct in6_addr		loc_addr;
+	struct in6_addr		rmt_addr;
+	struct sk_buff		*pktopts;
+	int			iif;
+};
+
+static inline struct tcp6_request_sock *tcp6_rsk(const struct request_sock *sk)
+{
+	return (struct tcp6_request_sock *)sk;
+}
+
 /**
  * struct ipv6_pinfo - ipv6 private area
  *
diff --git a/include/linux/irq.h b/include/linux/irq.h
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -47,6 +47,10 @@ struct hw_interrupt_type {
 	void (*ack)(unsigned int irq);
 	void (*end)(unsigned int irq);
 	void (*set_affinity)(unsigned int irq, cpumask_t dest);
+	/* Currently used only by UML, might disappear one day.*/
+#ifdef CONFIG_IRQ_RELEASE_METHOD
+	void (*release)(unsigned int irq, void *dev_id);
+#endif
 };
 
 typedef struct hw_interrupt_type  hw_irq_controller;
@@ -81,10 +85,10 @@ extern int no_irq_affinity;
 extern int noirqdebug_setup(char *str);
 
 extern fastcall int handle_IRQ_event(unsigned int irq, struct pt_regs *regs,
-				       struct irqaction *action);
+					struct irqaction *action);
 extern fastcall unsigned int __do_IRQ(unsigned int irq, struct pt_regs *regs);
-extern void note_interrupt(unsigned int irq, irq_desc_t *desc, int action_ret);
-extern void report_bad_irq(unsigned int irq, irq_desc_t *desc, int action_ret);
+extern void note_interrupt(unsigned int irq, irq_desc_t *desc,
+					int action_ret, struct pt_regs *regs);
 extern int can_request_irq(unsigned int irq, unsigned long irqflags);
 
 extern void init_irq_proc(void);
diff --git a/include/linux/jffs2_fs_sb.h b/include/linux/jffs2_fs_sb.h
--- a/include/linux/jffs2_fs_sb.h
+++ b/include/linux/jffs2_fs_sb.h
@@ -1,4 +1,4 @@
-/* $Id: jffs2_fs_sb.h,v 1.48 2004/11/20 10:41:12 dwmw2 Exp $ */
+/* $Id: jffs2_fs_sb.h,v 1.52 2005/05/19 16:12:17 gleixner Exp $ */
 
 #ifndef _JFFS2_FS_SB
 #define _JFFS2_FS_SB
@@ -14,7 +14,8 @@
 #include <linux/rwsem.h>
 
 #define JFFS2_SB_FLAG_RO 1
-#define JFFS2_SB_FLAG_MOUNTING 2
+#define JFFS2_SB_FLAG_SCANNING 2 /* Flash scanning is in progress */
+#define JFFS2_SB_FLAG_BUILDING 4 /* File system building is in progress */
 
 struct jffs2_inodirty;
 
@@ -31,7 +32,7 @@ struct jffs2_sb_info {
 	unsigned int flags;
 
 	struct task_struct *gc_task;	/* GC task struct */
-	struct semaphore gc_thread_start; /* GC thread start mutex */
+	struct completion gc_thread_start; /* GC thread start completion */
 	struct completion gc_thread_exit; /* GC thread exit completion port */
 
 	struct semaphore alloc_sem;	/* Used to protect all the following 
@@ -94,7 +95,7 @@ struct jffs2_sb_info {
 	   to an obsoleted node. I don't like this. Alternatives welcomed. */
 	struct semaphore erase_free_sem;
 
-#if defined CONFIG_JFFS2_FS_NAND || defined CONFIG_JFFS2_FS_NOR_ECC
+#ifdef CONFIG_JFFS2_FS_WRITEBUFFER
 	/* Write-behind buffer for NAND flash */
 	unsigned char *wbuf;
 	uint32_t wbuf_ofs;
diff --git a/include/linux/joystick.h b/include/linux/joystick.h
--- a/include/linux/joystick.h
+++ b/include/linux/joystick.h
@@ -111,18 +111,35 @@ struct js_corr {
 #define JS_SET_ALL		8
 
 struct JS_DATA_TYPE {
-	int buttons;
-	int x;
-	int y;
+	__s32 buttons;
+	__s32 x;
+	__s32 y;
 };
 
-struct JS_DATA_SAVE_TYPE {
-	int JS_TIMEOUT;
-	int BUSY;
-	long JS_EXPIRETIME;
-	long JS_TIMELIMIT;
+struct JS_DATA_SAVE_TYPE_32 {
+	__s32 JS_TIMEOUT;
+	__s32 BUSY;
+	__s32 JS_EXPIRETIME;
+	__s32 JS_TIMELIMIT;
 	struct JS_DATA_TYPE JS_SAVE;
 	struct JS_DATA_TYPE JS_CORR;
 };
 
+struct JS_DATA_SAVE_TYPE_64 {
+	__s32 JS_TIMEOUT;
+	__s32 BUSY;
+	__s64 JS_EXPIRETIME;
+	__s64 JS_TIMELIMIT;
+	struct JS_DATA_TYPE JS_SAVE;
+	struct JS_DATA_TYPE JS_CORR;
+};
+
+#if BITS_PER_LONG == 64
+#define JS_DATA_SAVE_TYPE JS_DATA_SAVE_TYPE_64
+#elif BITS_PER_LONG == 32
+#define JS_DATA_SAVE_TYPE JS_DATA_SAVE_TYPE_32
+#else
+#error Unexpected BITS_PER_LONG
+#endif
+
 #endif /* _LINUX_JOYSTICK_H */
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -58,15 +58,23 @@ struct completion;
  * be biten later when the calling function happens to sleep when it is not
  * supposed to.
  */
+#ifdef CONFIG_PREEMPT_VOLUNTARY
+extern int cond_resched(void);
+# define might_resched() cond_resched()
+#else
+# define might_resched() do { } while (0)
+#endif
+
 #ifdef CONFIG_DEBUG_SPINLOCK_SLEEP
-#define might_sleep() __might_sleep(__FILE__, __LINE__)
-#define might_sleep_if(cond) do { if (unlikely(cond)) might_sleep(); } while (0)
-void __might_sleep(char *file, int line);
+  void __might_sleep(char *file, int line);
+# define might_sleep() \
+	do { __might_sleep(__FILE__, __LINE__); might_resched(); } while (0)
 #else
-#define might_sleep() do {} while(0)
-#define might_sleep_if(cond) do {} while (0)
+# define might_sleep() do { might_resched(); } while (0)
 #endif
 
+#define might_sleep_if(cond) do { if (unlikely(cond)) might_sleep(); } while (0)
+
 #define abs(x) ({				\
 		int __x = (x);			\
 		(__x < 0) ? -__x : __x;		\
diff --git a/include/linux/kexec.h b/include/linux/kexec.h
new file mode 100644
--- /dev/null
+++ b/include/linux/kexec.h
@@ -0,0 +1,135 @@
+#ifndef LINUX_KEXEC_H
+#define LINUX_KEXEC_H
+
+#ifdef CONFIG_KEXEC
+#include <linux/types.h>
+#include <linux/list.h>
+#include <linux/linkage.h>
+#include <linux/compat.h>
+#include <asm/kexec.h>
+
+/* Verify architecture specific macros are defined */
+
+#ifndef KEXEC_SOURCE_MEMORY_LIMIT
+#error KEXEC_SOURCE_MEMORY_LIMIT not defined
+#endif
+
+#ifndef KEXEC_DESTINATION_MEMORY_LIMIT
+#error KEXEC_DESTINATION_MEMORY_LIMIT not defined
+#endif
+
+#ifndef KEXEC_CONTROL_MEMORY_LIMIT
+#error KEXEC_CONTROL_MEMORY_LIMIT not defined
+#endif
+
+#ifndef KEXEC_CONTROL_CODE_SIZE
+#error KEXEC_CONTROL_CODE_SIZE not defined
+#endif
+
+#ifndef KEXEC_ARCH
+#error KEXEC_ARCH not defined
+#endif
+
+/*
+ * This structure is used to hold the arguments that are used when loading
+ * kernel binaries.
+ */
+
+typedef unsigned long kimage_entry_t;
+#define IND_DESTINATION  0x1
+#define IND_INDIRECTION  0x2
+#define IND_DONE         0x4
+#define IND_SOURCE       0x8
+
+#define KEXEC_SEGMENT_MAX 8
+struct kexec_segment {
+	void __user *buf;
+	size_t bufsz;
+	unsigned long mem;	/* User space sees this as a (void *) ... */
+	size_t memsz;
+};
+
+#ifdef CONFIG_COMPAT
+struct compat_kexec_segment {
+	compat_uptr_t buf;
+	compat_size_t bufsz;
+	compat_ulong_t mem;	/* User space sees this as a (void *) ... */
+	compat_size_t memsz;
+};
+#endif
+
+struct kimage {
+	kimage_entry_t head;
+	kimage_entry_t *entry;
+	kimage_entry_t *last_entry;
+
+	unsigned long destination;
+
+	unsigned long start;
+	struct page *control_code_page;
+
+	unsigned long nr_segments;
+	struct kexec_segment segment[KEXEC_SEGMENT_MAX];
+
+	struct list_head control_pages;
+	struct list_head dest_pages;
+	struct list_head unuseable_pages;
+
+	/* Address of next control page to allocate for crash kernels. */
+	unsigned long control_page;
+
+	/* Flags to indicate special processing */
+	unsigned int type : 1;
+#define KEXEC_TYPE_DEFAULT 0
+#define KEXEC_TYPE_CRASH   1
+};
+
+
+
+/* kexec interface functions */
+extern NORET_TYPE void machine_kexec(struct kimage *image) ATTRIB_NORET;
+extern int machine_kexec_prepare(struct kimage *image);
+extern void machine_kexec_cleanup(struct kimage *image);
+extern asmlinkage long sys_kexec_load(unsigned long entry,
+					unsigned long nr_segments,
+					struct kexec_segment __user *segments,
+					unsigned long flags);
+#ifdef CONFIG_COMPAT
+extern asmlinkage long compat_sys_kexec_load(unsigned long entry,
+				unsigned long nr_segments,
+				struct compat_kexec_segment __user *segments,
+				unsigned long flags);
+#endif
+extern struct page *kimage_alloc_control_pages(struct kimage *image,
+						unsigned int order);
+extern void crash_kexec(struct pt_regs *);
+int kexec_should_crash(struct task_struct *);
+extern struct kimage *kexec_image;
+
+#define KEXEC_ON_CRASH  0x00000001
+#define KEXEC_ARCH_MASK 0xffff0000
+
+/* These values match the ELF architecture values.
+ * Unless there is a good reason that should continue to be the case.
+ */
+#define KEXEC_ARCH_DEFAULT ( 0 << 16)
+#define KEXEC_ARCH_386     ( 3 << 16)
+#define KEXEC_ARCH_X86_64  (62 << 16)
+#define KEXEC_ARCH_PPC     (20 << 16)
+#define KEXEC_ARCH_PPC64   (21 << 16)
+#define KEXEC_ARCH_IA_64   (50 << 16)
+#define KEXEC_ARCH_S390    (22 << 16)
+
+#define KEXEC_FLAGS    (KEXEC_ON_CRASH)  /* List of defined/legal kexec flags */
+
+/* Location of a reserved region to hold the crash kernel.
+ */
+extern struct resource crashk_res;
+
+#else /* !CONFIG_KEXEC */
+struct pt_regs;
+struct task_struct;
+static inline void crash_kexec(struct pt_regs *regs) { }
+static inline int kexec_should_crash(struct task_struct *p) { return 0; }
+#endif /* CONFIG_KEXEC */
+#endif /* LINUX_KEXEC_H */
diff --git a/include/linux/key-ui.h b/include/linux/key-ui.h
--- a/include/linux/key-ui.h
+++ b/include/linux/key-ui.h
@@ -1,4 +1,4 @@
-/* key-ui.h: key userspace interface stuff for use by keyfs
+/* key-ui.h: key userspace interface stuff
  *
  * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
  * Written by David Howells (dhowells@redhat.com)
@@ -31,8 +31,10 @@ extern spinlock_t key_serial_lock;
  * subscribed
  */
 struct keyring_list {
-	unsigned	maxkeys;	/* max keys this list can hold */
-	unsigned	nkeys;		/* number of keys currently held */
+	struct rcu_head	rcu;		/* RCU deletion hook */
+	unsigned short	maxkeys;	/* max keys this list can hold */
+	unsigned short	nkeys;		/* number of keys currently held */
+	unsigned short	delkey;		/* key to be unlinked by RCU */
 	struct key	*keys[0];
 };
 
@@ -82,8 +84,45 @@ static inline int key_any_permission(con
 	return kperm != 0;
 }
 
+static inline int key_task_groups_search(struct task_struct *tsk, gid_t gid)
+{
+	int ret;
+
+	task_lock(tsk);
+	ret = groups_search(tsk->group_info, gid);
+	task_unlock(tsk);
+	return ret;
+}
+
+static inline int key_task_permission(const struct key *key,
+				      struct task_struct *context,
+				      key_perm_t perm)
+{
+	key_perm_t kperm;
+
+	if (key->uid == context->fsuid) {
+		kperm = key->perm >> 16;
+	}
+	else if (key->gid != -1 &&
+		 key->perm & KEY_GRP_ALL && (
+			 key->gid == context->fsgid ||
+			 key_task_groups_search(context, key->gid)
+			 )
+		 ) {
+		kperm = key->perm >> 8;
+	}
+	else {
+		kperm = key->perm;
+	}
+
+	kperm = kperm & perm & KEY_ALL;
+
+	return kperm == perm;
+
+}
 
-extern struct key *lookup_user_key(key_serial_t id, int create, int part,
+extern struct key *lookup_user_key(struct task_struct *context,
+				   key_serial_t id, int create, int partial,
 				   key_perm_t perm);
 
 extern long join_session_keyring(const char *name);
diff --git a/include/linux/key.h b/include/linux/key.h
--- a/include/linux/key.h
+++ b/include/linux/key.h
@@ -18,7 +18,7 @@
 #include <linux/types.h>
 #include <linux/list.h>
 #include <linux/rbtree.h>
-#include <linux/spinlock.h>
+#include <linux/rcupdate.h>
 #include <asm/atomic.h>
 
 #ifdef __KERNEL__
@@ -78,7 +78,6 @@ struct key {
 	key_serial_t		serial;		/* key serial number */
 	struct rb_node		serial_node;
 	struct key_type		*type;		/* type of key */
-	rwlock_t		lock;		/* examination vs change lock */
 	struct rw_semaphore	sem;		/* change vs change sem */
 	struct key_user		*user;		/* owner of this key */
 	time_t			expiry;		/* time at which key expires (or 0) */
@@ -86,14 +85,10 @@ struct key {
 	gid_t			gid;
 	key_perm_t		perm;		/* access permissions */
 	unsigned short		quotalen;	/* length added to quota */
-	unsigned short		datalen;	/* payload data length */
-	unsigned short		flags;		/* status flags (change with lock writelocked) */
-#define KEY_FLAG_INSTANTIATED	0x00000001	/* set if key has been instantiated */
-#define KEY_FLAG_DEAD		0x00000002	/* set if key type has been deleted */
-#define KEY_FLAG_REVOKED	0x00000004	/* set if key had been revoked */
-#define KEY_FLAG_IN_QUOTA	0x00000008	/* set if key consumes quota */
-#define KEY_FLAG_USER_CONSTRUCT	0x00000010	/* set if key is being constructed in userspace */
-#define KEY_FLAG_NEGATIVE	0x00000020	/* set if key is negative */
+	unsigned short		datalen;	/* payload data length
+						 * - may not match RCU dereferenced payload
+						 * - payload should contain own length
+						 */
 
 #ifdef KEY_DEBUGGING
 	unsigned		magic;
@@ -101,6 +96,14 @@ struct key {
 #define KEY_DEBUG_MAGIC_X	0xf8e9dacbu
 #endif
 
+	unsigned long		flags;		/* status flags (change with bitops) */
+#define KEY_FLAG_INSTANTIATED	0	/* set if key has been instantiated */
+#define KEY_FLAG_DEAD		1	/* set if key type has been deleted */
+#define KEY_FLAG_REVOKED	2	/* set if key had been revoked */
+#define KEY_FLAG_IN_QUOTA	3	/* set if key consumes quota */
+#define KEY_FLAG_USER_CONSTRUCT	4	/* set if key is being constructed in userspace */
+#define KEY_FLAG_NEGATIVE	5	/* set if key is negative */
+
 	/* the description string
 	 * - this is used to match a key against search criteria
 	 * - this should be a printable string
@@ -196,10 +199,12 @@ extern int key_payload_reserve(struct ke
 extern int key_instantiate_and_link(struct key *key,
 				    const void *data,
 				    size_t datalen,
-				    struct key *keyring);
+				    struct key *keyring,
+				    struct key *instkey);
 extern int key_negate_and_link(struct key *key,
 			       unsigned timeout,
-			       struct key *keyring);
+			       struct key *keyring,
+			       struct key *instkey);
 extern void key_revoke(struct key *key);
 extern void key_put(struct key *key);
 
@@ -242,14 +247,13 @@ extern struct key *keyring_search(struct
 				  struct key_type *type,
 				  const char *description);
 
-extern struct key *search_process_keyrings(struct key_type *type,
-					   const char *description);
-
 extern int keyring_add_key(struct key *keyring,
 			   struct key *key);
 
 extern struct key *key_lookup(key_serial_t id);
 
+extern void keyring_replace_payload(struct key *key, void *replacement);
+
 #define key_serial(key) ((key) ? (key)->serial : 0)
 
 /*
@@ -268,14 +272,22 @@ extern void key_fsuid_changed(struct tas
 extern void key_fsgid_changed(struct task_struct *tsk);
 extern void key_init(void);
 
+#define __install_session_keyring(tsk, keyring)			\
+({								\
+	struct key *old_session = tsk->signal->session_keyring;	\
+	tsk->signal->session_keyring = keyring;			\
+	old_session;						\
+})
+
 #else /* CONFIG_KEYS */
 
 #define key_validate(k)			0
 #define key_serial(k)			0
-#define key_get(k) 			NULL
+#define key_get(k) 			({ NULL; })
 #define key_put(k)			do { } while(0)
 #define alloc_uid_keyring(u)		0
 #define switch_uid_keyring(u)		do { } while(0)
+#define __install_session_keyring(t, k)	({ NULL; })
 #define copy_keys(f,t)			0
 #define copy_thread_group_keys(t)	0
 #define exit_keys(t)			do { } while(0)
diff --git a/include/linux/keyctl.h b/include/linux/keyctl.h
--- a/include/linux/keyctl.h
+++ b/include/linux/keyctl.h
@@ -20,6 +20,16 @@
 #define KEY_SPEC_USER_SESSION_KEYRING	-5	/* - key ID for UID-session keyring */
 #define KEY_SPEC_GROUP_KEYRING		-6	/* - key ID for GID-specific keyring */
 
+/* request-key default keyrings */
+#define KEY_REQKEY_DEFL_NO_CHANGE		-1
+#define KEY_REQKEY_DEFL_DEFAULT			0
+#define KEY_REQKEY_DEFL_THREAD_KEYRING		1
+#define KEY_REQKEY_DEFL_PROCESS_KEYRING		2
+#define KEY_REQKEY_DEFL_SESSION_KEYRING		3
+#define KEY_REQKEY_DEFL_USER_KEYRING		4
+#define KEY_REQKEY_DEFL_USER_SESSION_KEYRING	5
+#define KEY_REQKEY_DEFL_GROUP_KEYRING		6
+
 /* keyctl commands */
 #define KEYCTL_GET_KEYRING_ID		0	/* ask for a keyring's ID */
 #define KEYCTL_JOIN_SESSION_KEYRING	1	/* join or start named session keyring */
@@ -35,5 +45,6 @@
 #define KEYCTL_READ			11	/* read a key or keyring's contents */
 #define KEYCTL_INSTANTIATE		12	/* instantiate a partially constructed key */
 #define KEYCTL_NEGATE			13	/* negate a partially constructed key */
+#define KEYCTL_SET_REQKEY_KEYRING	14	/* set default request-key keyring */
 
 #endif /*  _LINUX_KEYCTL_H */
diff --git a/include/linux/klist.h b/include/linux/klist.h
new file mode 100644
--- /dev/null
+++ b/include/linux/klist.h
@@ -0,0 +1,55 @@
+/*
+ *	klist.h - Some generic list helpers, extending struct list_head a bit.
+ *
+ *	Implementations are found in lib/klist.c
+ *
+ *
+ *	Copyright (C) 2005 Patrick Mochel
+ *
+ *	This file is rleased under the GPL v2.
+ */
+
+#include <linux/spinlock.h>
+#include <linux/completion.h>
+#include <linux/kref.h>
+#include <linux/list.h>
+
+
+struct klist {
+	spinlock_t		k_lock;
+	struct list_head	k_list;
+};
+
+
+extern void klist_init(struct klist * k);
+
+
+struct klist_node {
+	struct klist		* n_klist;
+	struct list_head	n_node;
+	struct kref		n_ref;
+	struct completion	n_removed;
+};
+
+extern void klist_add_tail(struct klist * k, struct klist_node * n);
+extern void klist_add_head(struct klist * k, struct klist_node * n);
+
+extern void klist_del(struct klist_node * n);
+extern void klist_remove(struct klist_node * n);
+
+extern int klist_node_attached(struct klist_node * n);
+
+
+struct klist_iter {
+	struct klist		* i_klist;
+	struct list_head	* i_head;
+	struct klist_node	* i_cur;
+};
+
+
+extern void klist_iter_init(struct klist * k, struct klist_iter * i);
+extern void klist_iter_init_node(struct klist * k, struct klist_iter * i, 
+				 struct klist_node * n);
+extern void klist_iter_exit(struct klist_iter * i);
+extern struct klist_node * klist_next(struct klist_iter * i);
+
diff --git a/include/linux/kmod.h b/include/linux/kmod.h
--- a/include/linux/kmod.h
+++ b/include/linux/kmod.h
@@ -19,6 +19,7 @@
  *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#include <linux/stddef.h>
 #include <linux/config.h>
 #include <linux/errno.h>
 #include <linux/compiler.h>
@@ -34,7 +35,17 @@ static inline int request_module(const c
 #endif
 
 #define try_then_request_module(x, mod...) ((x) ?: (request_module(mod), (x)))
-extern int call_usermodehelper(char *path, char *argv[], char *envp[], int wait);
+
+struct key;
+extern int call_usermodehelper_keys(char *path, char *argv[], char *envp[],
+				    struct key *session_keyring, int wait);
+
+static inline int
+call_usermodehelper(char *path, char **argv, char **envp, int wait)
+{
+	return call_usermodehelper_keys(path, argv, envp, NULL, wait);
+}
+
 extern void usermodehelper_init(void);
 
 #endif /* __LINUX_KMOD_H__ */
diff --git a/include/linux/kobject.h b/include/linux/kobject.h
--- a/include/linux/kobject.h
+++ b/include/linux/kobject.h
@@ -33,7 +33,7 @@
 extern u64 hotplug_seqnum;
 
 struct kobject {
-	char			* k_name;
+	const char		* k_name;
 	char			name[KOBJ_NAME_LEN];
 	struct kref		kref;
 	struct list_head	entry;
@@ -46,7 +46,7 @@ struct kobject {
 extern int kobject_set_name(struct kobject *, const char *, ...)
 	__attribute__((format(printf,2,3)));
 
-static inline char * kobject_name(struct kobject * kobj)
+static inline const char * kobject_name(const struct kobject * kobj)
 {
 	return kobj->k_name;
 }
@@ -57,7 +57,7 @@ extern void kobject_cleanup(struct kobje
 extern int kobject_add(struct kobject *);
 extern void kobject_del(struct kobject *);
 
-extern int kobject_rename(struct kobject *, char *new_name);
+extern int kobject_rename(struct kobject *, const char *new_name);
 
 extern int kobject_register(struct kobject *);
 extern void kobject_unregister(struct kobject *);
@@ -94,7 +94,7 @@ struct kobj_type {
  */
 struct kset_hotplug_ops {
 	int (*filter)(struct kset *kset, struct kobject *kobj);
-	char *(*name)(struct kset *kset, struct kobject *kobj);
+	const char *(*name)(struct kset *kset, struct kobject *kobj);
 	int (*hotplug)(struct kset *kset, struct kobject *kobj, char **envp,
 			int num_envp, char *buffer, int buffer_size);
 };
diff --git a/include/linux/kprobes.h b/include/linux/kprobes.h
--- a/include/linux/kprobes.h
+++ b/include/linux/kprobes.h
@@ -25,27 +25,45 @@
  *		Rusty Russell).
  * 2004-July	Suparna Bhattacharya <suparna@in.ibm.com> added jumper probes
  *		interface to access function arguments.
+ * 2005-May	Hien Nguyen <hien@us.ibm.com> and Jim Keniston
+ *		<jkenisto@us.ibm.com>  and Prasanna S Panchamukhi
+ *		<prasanna@in.ibm.com> added function-return probes.
  */
 #include <linux/config.h>
 #include <linux/list.h>
 #include <linux/notifier.h>
 #include <linux/smp.h>
+
 #include <asm/kprobes.h>
 
+/* kprobe_status settings */
+#define KPROBE_HIT_ACTIVE	0x00000001
+#define KPROBE_HIT_SS		0x00000002
+#define KPROBE_REENTER		0x00000004
+#define KPROBE_HIT_SSDONE	0x00000008
+
 struct kprobe;
 struct pt_regs;
+struct kretprobe;
+struct kretprobe_instance;
 typedef int (*kprobe_pre_handler_t) (struct kprobe *, struct pt_regs *);
 typedef int (*kprobe_break_handler_t) (struct kprobe *, struct pt_regs *);
 typedef void (*kprobe_post_handler_t) (struct kprobe *, struct pt_regs *,
 				       unsigned long flags);
 typedef int (*kprobe_fault_handler_t) (struct kprobe *, struct pt_regs *,
 				       int trapnr);
+typedef int (*kretprobe_handler_t) (struct kretprobe_instance *,
+				    struct pt_regs *);
+
 struct kprobe {
 	struct hlist_node hlist;
 
 	/* list of kprobes for multi-handler support */
 	struct list_head list;
 
+	/*count the number of times this probe was temporarily disarmed */
+	unsigned long nmissed;
+
 	/* location of the probe point */
 	kprobe_opcode_t *addr;
 
@@ -85,6 +103,41 @@ struct jprobe {
 	kprobe_opcode_t *entry;	/* probe handling code to jump to */
 };
 
+#ifdef ARCH_SUPPORTS_KRETPROBES
+extern void arch_prepare_kretprobe(struct kretprobe *rp, struct pt_regs *regs);
+#else /* ARCH_SUPPORTS_KRETPROBES */
+static inline void arch_prepare_kretprobe(struct kretprobe *rp,
+					struct pt_regs *regs)
+{
+}
+#endif /* ARCH_SUPPORTS_KRETPROBES */
+/*
+ * Function-return probe -
+ * Note:
+ * User needs to provide a handler function, and initialize maxactive.
+ * maxactive - The maximum number of instances of the probed function that
+ * can be active concurrently.
+ * nmissed - tracks the number of times the probed function's return was
+ * ignored, due to maxactive being too low.
+ *
+ */
+struct kretprobe {
+	struct kprobe kp;
+	kretprobe_handler_t handler;
+	int maxactive;
+	int nmissed;
+	struct hlist_head free_instances;
+	struct hlist_head used_instances;
+};
+
+struct kretprobe_instance {
+	struct hlist_node uflist; /* either on free list or used list */
+	struct hlist_node hlist;
+	struct kretprobe *rp;
+	kprobe_opcode_t *ret_addr;
+	struct task_struct *task;
+};
+
 #ifdef CONFIG_KPROBES
 /* Locks kprobe: irq must be disabled */
 void lock_kprobes(void);
@@ -99,11 +152,17 @@ static inline int kprobe_running(void)
 
 extern int arch_prepare_kprobe(struct kprobe *p);
 extern void arch_copy_kprobe(struct kprobe *p);
+extern void arch_arm_kprobe(struct kprobe *p);
+extern void arch_disarm_kprobe(struct kprobe *p);
 extern void arch_remove_kprobe(struct kprobe *p);
+extern int arch_init_kprobes(void);
 extern void show_registers(struct pt_regs *regs);
+extern kprobe_opcode_t *get_insn_slot(void);
+extern void free_insn_slot(kprobe_opcode_t *slot);
 
 /* Get the kprobe at this addr (if any).  Must have called lock_kprobes */
 struct kprobe *get_kprobe(void *addr);
+struct hlist_head * kretprobe_inst_table_head(struct task_struct *tsk);
 
 int register_kprobe(struct kprobe *p);
 void unregister_kprobe(struct kprobe *p);
@@ -113,7 +172,14 @@ int register_jprobe(struct jprobe *p);
 void unregister_jprobe(struct jprobe *p);
 void jprobe_return(void);
 
-#else
+int register_kretprobe(struct kretprobe *rp);
+void unregister_kretprobe(struct kretprobe *rp);
+
+struct kretprobe_instance *get_free_rp_inst(struct kretprobe *rp);
+void add_rp_inst(struct kretprobe_instance *ri);
+void kprobe_flush_task(struct task_struct *tk);
+void recycle_rp_inst(struct kretprobe_instance *ri);
+#else /* CONFIG_KPROBES */
 static inline int kprobe_running(void)
 {
 	return 0;
@@ -135,5 +201,15 @@ static inline void unregister_jprobe(str
 static inline void jprobe_return(void)
 {
 }
-#endif
+static inline int register_kretprobe(struct kretprobe *rp)
+{
+	return -ENOSYS;
+}
+static inline void unregister_kretprobe(struct kretprobe *rp)
+{
+}
+static inline void kprobe_flush_task(struct task_struct *tk)
+{
+}
+#endif				/* CONFIG_KPROBES */
 #endif				/* _LINUX_KPROBES_H */
diff --git a/include/linux/libata.h b/include/linux/libata.h
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -421,6 +421,7 @@ extern void ata_sg_init(struct ata_queue
 extern unsigned int ata_dev_classify(struct ata_taskfile *tf);
 extern void ata_dev_id_string(u16 *id, unsigned char *s,
 			      unsigned int ofs, unsigned int len);
+extern void ata_dev_config(struct ata_port *ap, unsigned int i);
 extern void ata_bmdma_setup (struct ata_queued_cmd *qc);
 extern void ata_bmdma_start (struct ata_queued_cmd *qc);
 extern void ata_bmdma_stop(struct ata_port *ap);
diff --git a/include/linux/libps2.h b/include/linux/libps2.h
--- a/include/linux/libps2.h
+++ b/include/linux/libps2.h
@@ -41,6 +41,7 @@ struct ps2dev {
 
 void ps2_init(struct ps2dev *ps2dev, struct serio *serio);
 int ps2_sendbyte(struct ps2dev *ps2dev, unsigned char byte, int timeout);
+void ps2_drain(struct ps2dev *ps2dev, int maxbytes, int timeout);
 int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command);
 int ps2_schedule_command(struct ps2dev *ps2dev, unsigned char *param, int command);
 int ps2_handle_ack(struct ps2dev *ps2dev, unsigned char data);
diff --git a/include/linux/list.h b/include/linux/list.h
--- a/include/linux/list.h
+++ b/include/linux/list.h
@@ -185,7 +185,7 @@ static inline void list_del(struct list_
  * list_for_each_entry_rcu().
  *
  * Note that the caller is not permitted to immediately free
- * the newly deleted entry.  Instead, either synchronize_kernel()
+ * the newly deleted entry.  Instead, either synchronize_rcu()
  * or call_rcu() must be used to defer freeing until an RCU
  * grace period has elapsed.
  */
diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h
--- a/include/linux/lockd/lockd.h
+++ b/include/linux/lockd/lockd.h
@@ -72,6 +72,8 @@ struct nlm_lockowner {
 	uint32_t pid;
 };
 
+struct nlm_wait;
+
 /*
  * Memory chunk for NLM client RPC request.
  */
@@ -81,6 +83,7 @@ struct nlm_rqst {
 	struct nlm_host *	a_host;		/* host handle */
 	struct nlm_args		a_args;		/* arguments */
 	struct nlm_res		a_res;		/* result */
+	struct nlm_wait *	a_block;
 	char			a_owner[NLMCLNT_OHSIZE];
 };
 
@@ -142,7 +145,9 @@ extern unsigned long		nlmsvc_timeout;
  * Lockd client functions
  */
 struct nlm_rqst * nlmclnt_alloc_call(void);
-int		  nlmclnt_block(struct nlm_host *, struct file_lock *, u32 *);
+int		  nlmclnt_prepare_block(struct nlm_rqst *req, struct nlm_host *host, struct file_lock *fl);
+void		  nlmclnt_finish_block(struct nlm_rqst *req);
+long		  nlmclnt_block(struct nlm_rqst *req, long timeout);
 int		  nlmclnt_cancel(struct nlm_host *, struct file_lock *);
 u32		  nlmclnt_grant(struct nlm_lock *);
 void		  nlmclnt_recovery(struct nlm_host *, u32);
diff --git a/include/linux/loop.h b/include/linux/loop.h
--- a/include/linux/loop.h
+++ b/include/linux/loop.h
@@ -61,7 +61,7 @@ struct loop_device {
 	struct semaphore	lo_sem;
 	struct semaphore	lo_ctl_mutex;
 	struct semaphore	lo_bh_mutex;
-	atomic_t		lo_pending;
+	int			lo_pending;
 
 	request_queue_t		*lo_queue;
 };
diff --git a/include/linux/major.h b/include/linux/major.h
--- a/include/linux/major.h
+++ b/include/linux/major.h
@@ -100,6 +100,7 @@
 #define I2O_MAJOR		80	/* 80->87 */
 
 #define SHMIQ_MAJOR		85   /* Linux/mips, SGI /dev/shmiq */
+#define SCSI_CHANGER_MAJOR      86
 
 #define IDE6_MAJOR		88
 #define IDE7_MAJOR		89
diff --git a/include/linux/mbcache.h b/include/linux/mbcache.h
--- a/include/linux/mbcache.h
+++ b/include/linux/mbcache.h
@@ -29,7 +29,7 @@ struct mb_cache_op {
 
 struct mb_cache * mb_cache_create(const char *, struct mb_cache_op *, size_t,
 				  int, int);
-void mb_cache_shrink(struct mb_cache *, struct block_device *);
+void mb_cache_shrink(struct block_device *);
 void mb_cache_destroy(struct mb_cache *);
 
 /* Functions on cache entries */
diff --git a/include/linux/mempool.h b/include/linux/mempool.h
--- a/include/linux/mempool.h
+++ b/include/linux/mempool.h
@@ -20,9 +20,14 @@ typedef struct mempool_s {
 	mempool_free_t *free;
 	wait_queue_head_t wait;
 } mempool_t;
-extern mempool_t * mempool_create(int min_nr, mempool_alloc_t *alloc_fn,
-				 mempool_free_t *free_fn, void *pool_data);
-extern int mempool_resize(mempool_t *pool, int new_min_nr, unsigned int __nocast gfp_mask);
+
+extern mempool_t *mempool_create(int min_nr, mempool_alloc_t *alloc_fn,
+			mempool_free_t *free_fn, void *pool_data);
+extern mempool_t *mempool_create_node(int min_nr, mempool_alloc_t *alloc_fn,
+			mempool_free_t *free_fn, void *pool_data, int nid);
+
+extern int mempool_resize(mempool_t *pool, int new_min_nr,
+			unsigned int __nocast gfp_mask);
 extern void mempool_destroy(mempool_t *pool);
 extern void * mempool_alloc(mempool_t *pool, unsigned int __nocast gfp_mask);
 extern void mempool_free(void *element, mempool_t *pool);
diff --git a/include/linux/mm.h b/include/linux/mm.h
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -395,19 +395,81 @@ static inline void put_page(struct page 
 /*
  * The zone field is never updated after free_area_init_core()
  * sets it, so none of the operations on it need to be atomic.
- * We'll have up to (MAX_NUMNODES * MAX_NR_ZONES) zones total,
- * so we use (MAX_NODES_SHIFT + MAX_ZONES_SHIFT) here to get enough bits.
  */
-#define NODEZONE_SHIFT (sizeof(page_flags_t)*8 - MAX_NODES_SHIFT - MAX_ZONES_SHIFT)
-#define NODEZONE(node, zone)	((node << ZONES_SHIFT) | zone)
+
+
+/*
+ * page->flags layout:
+ *
+ * There are three possibilities for how page->flags get
+ * laid out.  The first is for the normal case, without
+ * sparsemem.  The second is for sparsemem when there is
+ * plenty of space for node and section.  The last is when
+ * we have run out of space and have to fall back to an
+ * alternate (slower) way of determining the node.
+ *
+ *        No sparsemem: |       NODE     | ZONE | ... | FLAGS |
+ * with space for node: | SECTION | NODE | ZONE | ... | FLAGS |
+ *   no space for node: | SECTION |     ZONE    | ... | FLAGS |
+ */
+#ifdef CONFIG_SPARSEMEM
+#define SECTIONS_WIDTH		SECTIONS_SHIFT
+#else
+#define SECTIONS_WIDTH		0
+#endif
+
+#define ZONES_WIDTH		ZONES_SHIFT
+
+#if SECTIONS_WIDTH+ZONES_WIDTH+NODES_SHIFT <= FLAGS_RESERVED
+#define NODES_WIDTH		NODES_SHIFT
+#else
+#define NODES_WIDTH		0
+#endif
+
+/* Page flags: | [SECTION] | [NODE] | ZONE | ... | FLAGS | */
+#define SECTIONS_PGOFF		((sizeof(page_flags_t)*8) - SECTIONS_WIDTH)
+#define NODES_PGOFF		(SECTIONS_PGOFF - NODES_WIDTH)
+#define ZONES_PGOFF		(NODES_PGOFF - ZONES_WIDTH)
+
+/*
+ * We are going to use the flags for the page to node mapping if its in
+ * there.  This includes the case where there is no node, so it is implicit.
+ */
+#define FLAGS_HAS_NODE		(NODES_WIDTH > 0 || NODES_SHIFT == 0)
+
+#ifndef PFN_SECTION_SHIFT
+#define PFN_SECTION_SHIFT 0
+#endif
+
+/*
+ * Define the bit shifts to access each section.  For non-existant
+ * sections we define the shift as 0; that plus a 0 mask ensures
+ * the compiler will optimise away reference to them.
+ */
+#define SECTIONS_PGSHIFT	(SECTIONS_PGOFF * (SECTIONS_WIDTH != 0))
+#define NODES_PGSHIFT		(NODES_PGOFF * (NODES_WIDTH != 0))
+#define ZONES_PGSHIFT		(ZONES_PGOFF * (ZONES_WIDTH != 0))
+
+/* NODE:ZONE or SECTION:ZONE is used to lookup the zone from a page. */
+#if FLAGS_HAS_NODE
+#define ZONETABLE_SHIFT		(NODES_SHIFT + ZONES_SHIFT)
+#else
+#define ZONETABLE_SHIFT		(SECTIONS_SHIFT + ZONES_SHIFT)
+#endif
+#define ZONETABLE_PGSHIFT	ZONES_PGSHIFT
+
+#if SECTIONS_WIDTH+NODES_WIDTH+ZONES_WIDTH > FLAGS_RESERVED
+#error SECTIONS_WIDTH+NODES_WIDTH+ZONES_WIDTH > FLAGS_RESERVED
+#endif
+
+#define ZONES_MASK		((1UL << ZONES_WIDTH) - 1)
+#define NODES_MASK		((1UL << NODES_WIDTH) - 1)
+#define SECTIONS_MASK		((1UL << SECTIONS_WIDTH) - 1)
+#define ZONETABLE_MASK		((1UL << ZONETABLE_SHIFT) - 1)
 
 static inline unsigned long page_zonenum(struct page *page)
 {
-	return (page->flags >> NODEZONE_SHIFT) & (~(~0UL << ZONES_SHIFT));
-}
-static inline unsigned long page_to_nid(struct page *page)
-{
-	return (page->flags >> (NODEZONE_SHIFT + ZONES_SHIFT));
+	return (page->flags >> ZONES_PGSHIFT) & ZONES_MASK;
 }
 
 struct zone;
@@ -415,13 +477,44 @@ extern struct zone *zone_table[];
 
 static inline struct zone *page_zone(struct page *page)
 {
-	return zone_table[page->flags >> NODEZONE_SHIFT];
+	return zone_table[(page->flags >> ZONETABLE_PGSHIFT) &
+			ZONETABLE_MASK];
+}
+
+static inline unsigned long page_to_nid(struct page *page)
+{
+	if (FLAGS_HAS_NODE)
+		return (page->flags >> NODES_PGSHIFT) & NODES_MASK;
+	else
+		return page_zone(page)->zone_pgdat->node_id;
+}
+static inline unsigned long page_to_section(struct page *page)
+{
+	return (page->flags >> SECTIONS_PGSHIFT) & SECTIONS_MASK;
+}
+
+static inline void set_page_zone(struct page *page, unsigned long zone)
+{
+	page->flags &= ~(ZONES_MASK << ZONES_PGSHIFT);
+	page->flags |= (zone & ZONES_MASK) << ZONES_PGSHIFT;
+}
+static inline void set_page_node(struct page *page, unsigned long node)
+{
+	page->flags &= ~(NODES_MASK << NODES_PGSHIFT);
+	page->flags |= (node & NODES_MASK) << NODES_PGSHIFT;
+}
+static inline void set_page_section(struct page *page, unsigned long section)
+{
+	page->flags &= ~(SECTIONS_MASK << SECTIONS_PGSHIFT);
+	page->flags |= (section & SECTIONS_MASK) << SECTIONS_PGSHIFT;
 }
 
-static inline void set_page_zone(struct page *page, unsigned long nodezone_num)
+static inline void set_page_links(struct page *page, unsigned long zone,
+	unsigned long node, unsigned long pfn)
 {
-	page->flags &= ~(~0UL << NODEZONE_SHIFT);
-	page->flags |= nodezone_num << NODEZONE_SHIFT;
+	set_page_zone(page, zone);
+	set_page_node(page, node);
+	set_page_section(page, pfn_to_section_nr(pfn));
 }
 
 #ifndef CONFIG_DISCONTIGMEM
@@ -532,10 +625,16 @@ static inline int page_mapped(struct pag
  * Used to decide whether a process gets delivered SIGBUS or
  * just gets major/minor fault counters bumped up.
  */
-#define VM_FAULT_OOM	(-1)
-#define VM_FAULT_SIGBUS	0
-#define VM_FAULT_MINOR	1
-#define VM_FAULT_MAJOR	2
+#define VM_FAULT_OOM	0x00
+#define VM_FAULT_SIGBUS	0x01
+#define VM_FAULT_MINOR	0x02
+#define VM_FAULT_MAJOR	0x03
+
+/* 
+ * Special case for get_user_pages.
+ * Must be in a distinct bit from the above VM_FAULT_ flags.
+ */
+#define VM_FAULT_WRITE	0x10
 
 #define offset_in_page(p)	((unsigned long)(p) & ~PAGE_MASK)
 
@@ -611,7 +710,13 @@ extern pte_t *FASTCALL(pte_alloc_kernel(
 extern pte_t *FASTCALL(pte_alloc_map(struct mm_struct *mm, pmd_t *pmd, unsigned long address));
 extern int install_page(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long addr, struct page *page, pgprot_t prot);
 extern int install_file_pte(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long addr, unsigned long pgoff, pgprot_t prot);
-extern int handle_mm_fault(struct mm_struct *mm,struct vm_area_struct *vma, unsigned long address, int write_access);
+extern int __handle_mm_fault(struct mm_struct *mm,struct vm_area_struct *vma, unsigned long address, int write_access);
+
+static inline int handle_mm_fault(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long address, int write_access)
+{
+	return __handle_mm_fault(mm, vma, address, write_access) & (~VM_FAULT_WRITE);
+}
+
 extern int make_pages_present(unsigned long addr, unsigned long end);
 extern int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write);
 void install_arg_page(struct vm_area_struct *, struct page *, unsigned long);
@@ -691,6 +796,12 @@ extern void show_mem(void);
 extern void si_meminfo(struct sysinfo * val);
 extern void si_meminfo_node(struct sysinfo *val, int nid);
 
+#ifdef CONFIG_NUMA
+extern void setup_per_cpu_pageset(void);
+#else
+static inline void setup_per_cpu_pageset(void) {}
+#endif
+
 /* prio_tree.c */
 void vma_prio_tree_add(struct vm_area_struct *, struct vm_area_struct *old);
 void vma_prio_tree_insert(struct vm_area_struct *, struct prio_tree_root *);
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -63,6 +63,12 @@ struct per_cpu_pageset {
 #endif
 } ____cacheline_aligned_in_smp;
 
+#ifdef CONFIG_NUMA
+#define zone_pcp(__z, __cpu) ((__z)->pageset[(__cpu)])
+#else
+#define zone_pcp(__z, __cpu) (&(__z)->pageset[(__cpu)])
+#endif
+
 #define ZONE_DMA		0
 #define ZONE_NORMAL		1
 #define ZONE_HIGHMEM		2
@@ -122,8 +128,11 @@ struct zone {
 	 */
 	unsigned long		lowmem_reserve[MAX_NR_ZONES];
 
+#ifdef CONFIG_NUMA
+	struct per_cpu_pageset	*pageset[NR_CPUS];
+#else
 	struct per_cpu_pageset	pageset[NR_CPUS];
-
+#endif
 	/*
 	 * free areas of different sizes
 	 */
@@ -145,6 +154,14 @@ struct zone {
 	int			all_unreclaimable; /* All pages pinned */
 
 	/*
+	 * Does the allocator try to reclaim pages from the zone as soon
+	 * as it fails a watermark_ok() in __alloc_pages?
+	 */
+	int			reclaim_pages;
+	/* A count of how many reclaimers are scanning this zone */
+	atomic_t		reclaim_in_progress;
+
+	/*
 	 * prev_priority holds the scanning priority for this zone.  It is
 	 * defined as the scanning priority at which we achieved our reclaim
 	 * target at the previous try_to_free_pages() or balance_pgdat()
@@ -252,7 +269,9 @@ typedef struct pglist_data {
 	struct zone node_zones[MAX_NR_ZONES];
 	struct zonelist node_zonelists[GFP_ZONETYPES];
 	int nr_zones;
+#ifdef CONFIG_FLAT_NODE_MEM_MAP
 	struct page *node_mem_map;
+#endif
 	struct bootmem_data *bdata;
 	unsigned long node_start_pfn;
 	unsigned long node_present_pages; /* total number of physical pages */
@@ -267,6 +286,12 @@ typedef struct pglist_data {
 
 #define node_present_pages(nid)	(NODE_DATA(nid)->node_present_pages)
 #define node_spanned_pages(nid)	(NODE_DATA(nid)->node_spanned_pages)
+#ifdef CONFIG_FLAT_NODE_MEM_MAP
+#define pgdat_page_nr(pgdat, pagenr)	((pgdat)->node_mem_map + (pagenr))
+#else
+#define pgdat_page_nr(pgdat, pagenr)	pfn_to_page((pgdat)->node_start_pfn + (pagenr))
+#endif
+#define nid_page_nr(nid, pagenr) 	pgdat_page_nr(NODE_DATA(nid),(pagenr))
 
 extern struct pglist_data *pgdat_list;
 
@@ -381,9 +406,9 @@ int lowmem_reserve_ratio_sysctl_handler(
 
 #include <linux/topology.h>
 /* Returns the number of the current Node. */
-#define numa_node_id()		(cpu_to_node(_smp_processor_id()))
+#define numa_node_id()		(cpu_to_node(raw_smp_processor_id()))
 
-#ifndef CONFIG_DISCONTIGMEM
+#ifndef CONFIG_NEED_MULTIPLE_NODES
 
 extern struct pglist_data contig_page_data;
 #define NODE_DATA(nid)		(&contig_page_data)
@@ -391,36 +416,177 @@ extern struct pglist_data contig_page_da
 #define MAX_NODES_SHIFT		1
 #define pfn_to_nid(pfn)		(0)
 
-#else /* CONFIG_DISCONTIGMEM */
+#else /* CONFIG_NEED_MULTIPLE_NODES */
 
 #include <asm/mmzone.h>
 
+#endif /* !CONFIG_NEED_MULTIPLE_NODES */
+
+#ifdef CONFIG_SPARSEMEM
+#include <asm/sparsemem.h>
+#endif
+
 #if BITS_PER_LONG == 32 || defined(ARCH_HAS_ATOMIC_UNSIGNED)
 /*
  * with 32 bit page->flags field, we reserve 8 bits for node/zone info.
  * there are 3 zones (2 bits) and this leaves 8-2=6 bits for nodes.
  */
-#define MAX_NODES_SHIFT		6
+#define FLAGS_RESERVED		8
+
 #elif BITS_PER_LONG == 64
 /*
  * with 64 bit flags field, there's plenty of room.
  */
-#define MAX_NODES_SHIFT		10
+#define FLAGS_RESERVED		32
+
+#else
+
+#error BITS_PER_LONG not defined
+
+#endif
+
+#ifndef CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID
+#define early_pfn_to_nid(nid)  (0UL)
 #endif
 
-#endif /* !CONFIG_DISCONTIGMEM */
+#define pfn_to_section_nr(pfn) ((pfn) >> PFN_SECTION_SHIFT)
+#define section_nr_to_pfn(sec) ((sec) << PFN_SECTION_SHIFT)
+
+#ifdef CONFIG_SPARSEMEM
+
+/*
+ * SECTION_SHIFT    		#bits space required to store a section #
+ *
+ * PA_SECTION_SHIFT		physical address to/from section number
+ * PFN_SECTION_SHIFT		pfn to/from section number
+ */
+#define SECTIONS_SHIFT		(MAX_PHYSMEM_BITS - SECTION_SIZE_BITS)
+
+#define PA_SECTION_SHIFT	(SECTION_SIZE_BITS)
+#define PFN_SECTION_SHIFT	(SECTION_SIZE_BITS - PAGE_SHIFT)
+
+#define NR_MEM_SECTIONS		(1UL << SECTIONS_SHIFT)
 
-#if NODES_SHIFT > MAX_NODES_SHIFT
-#error NODES_SHIFT > MAX_NODES_SHIFT
+#define PAGES_PER_SECTION       (1UL << PFN_SECTION_SHIFT)
+#define PAGE_SECTION_MASK	(~(PAGES_PER_SECTION-1))
+
+#if (MAX_ORDER - 1 + PAGE_SHIFT) > SECTION_SIZE_BITS
+#error Allocator MAX_ORDER exceeds SECTION_SIZE
 #endif
 
-/* There are currently 3 zones: DMA, Normal & Highmem, thus we need 2 bits */
-#define MAX_ZONES_SHIFT		2
+struct page;
+struct mem_section {
+	/*
+	 * This is, logically, a pointer to an array of struct
+	 * pages.  However, it is stored with some other magic.
+	 * (see sparse.c::sparse_init_one_section())
+	 *
+	 * Making it a UL at least makes someone do a cast
+	 * before using it wrong.
+	 */
+	unsigned long section_mem_map;
+};
+
+extern struct mem_section mem_section[NR_MEM_SECTIONS];
+
+static inline struct mem_section *__nr_to_section(unsigned long nr)
+{
+	return &mem_section[nr];
+}
 
-#if ZONES_SHIFT > MAX_ZONES_SHIFT
-#error ZONES_SHIFT > MAX_ZONES_SHIFT
+/*
+ * We use the lower bits of the mem_map pointer to store
+ * a little bit of information.  There should be at least
+ * 3 bits here due to 32-bit alignment.
+ */
+#define	SECTION_MARKED_PRESENT	(1UL<<0)
+#define SECTION_HAS_MEM_MAP	(1UL<<1)
+#define SECTION_MAP_LAST_BIT	(1UL<<2)
+#define SECTION_MAP_MASK	(~(SECTION_MAP_LAST_BIT-1))
+
+static inline struct page *__section_mem_map_addr(struct mem_section *section)
+{
+	unsigned long map = section->section_mem_map;
+	map &= SECTION_MAP_MASK;
+	return (struct page *)map;
+}
+
+static inline int valid_section(struct mem_section *section)
+{
+	return (section->section_mem_map & SECTION_MARKED_PRESENT);
+}
+
+static inline int section_has_mem_map(struct mem_section *section)
+{
+	return (section->section_mem_map & SECTION_HAS_MEM_MAP);
+}
+
+static inline int valid_section_nr(unsigned long nr)
+{
+	return valid_section(__nr_to_section(nr));
+}
+
+/*
+ * Given a kernel address, find the home node of the underlying memory.
+ */
+#define kvaddr_to_nid(kaddr)	pfn_to_nid(__pa(kaddr) >> PAGE_SHIFT)
+
+static inline struct mem_section *__pfn_to_section(unsigned long pfn)
+{
+	return __nr_to_section(pfn_to_section_nr(pfn));
+}
+
+#define pfn_to_page(pfn) 						\
+({ 									\
+	unsigned long __pfn = (pfn);					\
+	__section_mem_map_addr(__pfn_to_section(__pfn)) + __pfn;	\
+})
+#define page_to_pfn(page)						\
+({									\
+	page - __section_mem_map_addr(__nr_to_section(			\
+		page_to_section(page)));				\
+})
+
+static inline int pfn_valid(unsigned long pfn)
+{
+	if (pfn_to_section_nr(pfn) >= NR_MEM_SECTIONS)
+		return 0;
+	return valid_section(__nr_to_section(pfn_to_section_nr(pfn)));
+}
+
+/*
+ * These are _only_ used during initialisation, therefore they
+ * can use __initdata ...  They could have names to indicate
+ * this restriction.
+ */
+#ifdef CONFIG_NUMA
+#define pfn_to_nid		early_pfn_to_nid
+#endif
+
+#define pfn_to_pgdat(pfn)						\
+({									\
+	NODE_DATA(pfn_to_nid(pfn));					\
+})
+
+#define early_pfn_valid(pfn)	pfn_valid(pfn)
+void sparse_init(void);
+#else
+#define sparse_init()	do {} while (0)
+#endif /* CONFIG_SPARSEMEM */
+
+#ifdef CONFIG_NODES_SPAN_OTHER_NODES
+#define early_pfn_in_nid(pfn, nid)	(early_pfn_to_nid(pfn) == (nid))
+#else
+#define early_pfn_in_nid(pfn, nid)	(1)
 #endif
 
+#ifndef early_pfn_valid
+#define early_pfn_valid(pfn)	(1)
+#endif
+
+void memory_present(int nid, unsigned long start, unsigned long end);
+unsigned long __init node_memmap_size_bytes(int, unsigned long, unsigned long);
+
 #endif /* !__ASSEMBLY__ */
 #endif /* __KERNEL__ */
 #endif /* _LINUX_MMZONE_H */
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
--- a/include/linux/mod_devicetable.h
+++ b/include/linux/mod_devicetable.h
@@ -174,5 +174,62 @@ struct serio_device_id {
 	__u8 proto;
 };
 
+/*
+ * Struct used for matching a device
+ */
+struct of_device_id
+{
+	char	name[32];
+	char	type[32];
+	char	compatible[128];
+	void	*data;
+};
+
+
+/* PCMCIA */
+
+struct pcmcia_device_id {
+	__u16		match_flags;
+
+	__u16		manf_id;
+	__u16 		card_id;
+
+	__u8  		func_id;
+
+	/* for real multi-function devices */
+	__u8  		function;
+
+	/* for pseude multi-function devices */
+	__u8  		device_no;
+
+	__u32 		prod_id_hash[4];
+
+	/* not matched against in kernelspace*/
+#ifdef __KERNEL__
+	const char *	prod_id[4];
+#else
+	kernel_ulong_t	prod_id[4];
+#endif
+
+	/* not matched against */
+	kernel_ulong_t	driver_info;
+#ifdef __KERNEL__
+	char *		cisfile;
+#else
+	kernel_ulong_t	cisfile;
+#endif
+};
+
+#define PCMCIA_DEV_ID_MATCH_MANF_ID	0x0001
+#define PCMCIA_DEV_ID_MATCH_CARD_ID	0x0002
+#define PCMCIA_DEV_ID_MATCH_FUNC_ID	0x0004
+#define PCMCIA_DEV_ID_MATCH_FUNCTION	0x0008
+#define PCMCIA_DEV_ID_MATCH_PROD_ID1	0x0010
+#define PCMCIA_DEV_ID_MATCH_PROD_ID2	0x0020
+#define PCMCIA_DEV_ID_MATCH_PROD_ID3	0x0040
+#define PCMCIA_DEV_ID_MATCH_PROD_ID4	0x0080
+#define PCMCIA_DEV_ID_MATCH_DEVICE_NO	0x0100
+#define PCMCIA_DEV_ID_MATCH_FAKE_CIS	0x0200
+#define PCMCIA_DEV_ID_MATCH_ANONYMOUS	0x0400
 
 #endif /* LINUX_MOD_DEVICETABLE_H */
diff --git a/include/linux/module.h b/include/linux/module.h
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -51,6 +51,9 @@ struct module_attribute {
         ssize_t (*show)(struct module_attribute *, struct module *, char *);
         ssize_t (*store)(struct module_attribute *, struct module *,
 			 const char *, size_t count);
+	void (*setup)(struct module *, const char *);
+	int (*test)(struct module *);
+	void (*free)(struct module *);
 };
 
 struct module_kobject
@@ -239,6 +242,8 @@ struct module
 	/* Sysfs stuff. */
 	struct module_kobject mkobj;
 	struct module_param_attrs *param_attrs;
+	const char *version;
+	const char *srcversion;
 
 	/* Exported symbols */
 	const struct kernel_symbol *syms;
diff --git a/include/linux/mount.h b/include/linux/mount.h
--- a/include/linux/mount.h
+++ b/include/linux/mount.h
@@ -12,6 +12,7 @@
 #define _LINUX_MOUNT_H
 #ifdef __KERNEL__
 
+#include <linux/types.h>
 #include <linux/list.h>
 #include <linux/spinlock.h>
 #include <asm/atomic.h>
@@ -34,7 +35,7 @@ struct vfsmount
 	int mnt_expiry_mark;		/* true if marked for expiry */
 	char *mnt_devname;		/* Name of device e.g. /dev/dsk/hda1 */
 	struct list_head mnt_list;
-	struct list_head mnt_fslink;	/* link in fs-specific expiry list */
+	struct list_head mnt_expire;	/* link in fs-specific expiry list */
 	struct namespace *mnt_namespace; /* containing namespace */
 };
 
@@ -47,7 +48,7 @@ static inline struct vfsmount *mntget(st
 
 extern void __mntput(struct vfsmount *mnt);
 
-static inline void _mntput(struct vfsmount *mnt)
+static inline void mntput_no_expire(struct vfsmount *mnt)
 {
 	if (mnt) {
 		if (atomic_dec_and_test(&mnt->mnt_count))
@@ -59,7 +60,7 @@ static inline void mntput(struct vfsmoun
 {
 	if (mnt) {
 		mnt->mnt_expiry_mark = 0;
-		_mntput(mnt);
+		mntput_no_expire(mnt);
 	}
 }
 
@@ -76,6 +77,7 @@ extern int do_add_mount(struct vfsmount 
 extern void mark_mounts_for_expiry(struct list_head *mounts);
 
 extern spinlock_t vfsmount_lock;
+extern dev_t name_to_dev_t(char *name);
 
 #endif
 #endif /* _LINUX_MOUNT_H */
diff --git a/include/linux/mtd/cfi.h b/include/linux/mtd/cfi.h
--- a/include/linux/mtd/cfi.h
+++ b/include/linux/mtd/cfi.h
@@ -1,7 +1,7 @@
 
 /* Common Flash Interface structures 
  * See http://support.intel.com/design/flash/technote/index.htm
- * $Id: cfi.h,v 1.50 2004/11/20 12:46:51 dwmw2 Exp $
+ * $Id: cfi.h,v 1.54 2005/06/06 23:04:36 tpoynor Exp $
  */
 
 #ifndef __MTD_CFI_H__
@@ -148,6 +148,14 @@ struct cfi_pri_intelext {
 	uint8_t  extra[0];
 } __attribute__((packed));
 
+struct cfi_intelext_otpinfo {
+	uint32_t ProtRegAddr;
+	uint16_t FactGroups;
+	uint8_t  FactProtRegSize;
+	uint16_t UserGroups;
+	uint8_t  UserProtRegSize;
+} __attribute__((packed));
+
 struct cfi_intelext_blockinfo {
 	uint16_t NumIdentBlocks;
 	uint16_t BlockSize;
@@ -244,7 +252,7 @@ static inline uint32_t cfi_build_cmd_add
  * It looks too long to be inline, but in the common case it should almost all
  * get optimised away. 
  */
-static inline map_word cfi_build_cmd(u_char cmd, struct map_info *map, struct cfi_private *cfi)
+static inline map_word cfi_build_cmd(u_long cmd, struct map_info *map, struct cfi_private *cfi)
 {
 	map_word val = { {0} };
 	int wordwidth, words_per_bus, chip_mode, chips_per_word;
@@ -307,6 +315,69 @@ static inline map_word cfi_build_cmd(u_c
 }
 #define CMD(x)  cfi_build_cmd((x), map, cfi)
 
+
+static inline unsigned char cfi_merge_status(map_word val, struct map_info *map, 
+					   struct cfi_private *cfi)
+{
+	int wordwidth, words_per_bus, chip_mode, chips_per_word;
+	unsigned long onestat, res = 0;
+	int i;
+
+	/* We do it this way to give the compiler a fighting chance 
+	   of optimising away all the crap for 'bankwidth' larger than
+	   an unsigned long, in the common case where that support is
+	   disabled */
+	if (map_bankwidth_is_large(map)) {
+		wordwidth = sizeof(unsigned long);
+		words_per_bus = (map_bankwidth(map)) / wordwidth; // i.e. normally 1
+	} else {
+		wordwidth = map_bankwidth(map);
+		words_per_bus = 1;
+	}
+	
+	chip_mode = map_bankwidth(map) / cfi_interleave(cfi);
+	chips_per_word = wordwidth * cfi_interleave(cfi) / map_bankwidth(map);
+
+	onestat = val.x[0];
+	/* Or all status words together */
+	for (i=1; i < words_per_bus; i++) {
+		onestat |= val.x[i];
+	}
+
+	res = onestat;
+	switch(chips_per_word) {
+	default: BUG();
+#if BITS_PER_LONG >= 64
+	case 8:
+		res |= (onestat >> (chip_mode * 32));
+#endif
+	case 4:
+		res |= (onestat >> (chip_mode * 16));
+	case 2:
+		res |= (onestat >> (chip_mode * 8));
+	case 1:
+		;
+	}
+
+	/* Last, determine what the bit-pattern should be for a single
+	   device, according to chip mode and endianness... */
+	switch (chip_mode) {
+	case 1:
+		break;
+	case 2:
+		res = cfi16_to_cpu(res);
+		break;
+	case 4:
+		res = cfi32_to_cpu(res);
+		break;
+	default: BUG();
+	}
+	return res;
+}
+
+#define MERGESTATUS(x) cfi_merge_status((x), map, cfi)
+
+
 /*
  * Sends a CFI command to a bank of flash for the given geometry.
  *
@@ -357,16 +428,6 @@ static inline void cfi_udelay(int us)
 	}
 }
 
-static inline void cfi_spin_lock(spinlock_t *mutex)
-{
-	spin_lock_bh(mutex);
-}
-
-static inline void cfi_spin_unlock(spinlock_t *mutex)
-{
-	spin_unlock_bh(mutex);
-}
-
 struct cfi_extquery *cfi_read_pri(struct map_info *map, uint16_t adr, uint16_t size,
 			     const char* name);
 struct cfi_fixup {
diff --git a/include/linux/mtd/flashchip.h b/include/linux/mtd/flashchip.h
--- a/include/linux/mtd/flashchip.h
+++ b/include/linux/mtd/flashchip.h
@@ -6,7 +6,7 @@
  *
  * (C) 2000 Red Hat. GPLd.
  *
- * $Id: flashchip.h,v 1.15 2004/11/05 22:41:06 nico Exp $
+ * $Id: flashchip.h,v 1.17 2005/03/14 18:27:15 bjd Exp $
  *
  */
 
@@ -29,6 +29,7 @@ typedef enum { 
 	FL_ERASE_SUSPENDED,
 	FL_WRITING,
 	FL_WRITING_TO_BUFFER,
+	FL_OTP_WRITE,
 	FL_WRITE_SUSPENDING,
 	FL_WRITE_SUSPENDED,
 	FL_PM_SUSPENDED,
@@ -62,8 +63,8 @@ struct flchip {
 	flstate_t state;
 	flstate_t oldstate;
 
-	int write_suspended:1;
-	int erase_suspended:1;
+	unsigned int write_suspended:1;
+	unsigned int erase_suspended:1;
 	unsigned long in_progress_block_addr;
 
 	spinlock_t *mutex;
diff --git a/include/linux/mtd/inftl.h b/include/linux/mtd/inftl.h
--- a/include/linux/mtd/inftl.h
+++ b/include/linux/mtd/inftl.h
@@ -3,7 +3,7 @@
  *
  *	(C) Copyright 2002, Greg Ungerer (gerg@snapgear.com)
  *
- *	$Id: inftl.h,v 1.6 2004/06/30 14:49:00 dbrown Exp $
+ *	$Id: inftl.h,v 1.7 2005/06/13 13:08:45 sean Exp $
  */
 
 #ifndef __MTD_INFTL_H__
@@ -20,7 +20,7 @@
 #include <mtd/inftl-user.h>
 
 #ifndef INFTL_MAJOR
-#define INFTL_MAJOR 94
+#define INFTL_MAJOR 96
 #endif
 #define INFTL_PARTN_BITS 4
 
diff --git a/include/linux/mtd/map.h b/include/linux/mtd/map.h
--- a/include/linux/mtd/map.h
+++ b/include/linux/mtd/map.h
@@ -1,6 +1,6 @@
 
 /* Overhauled routines for dealing with different mmap regions of flash */
-/* $Id: map.h,v 1.46 2005/01/05 17:09:44 dwmw2 Exp $ */
+/* $Id: map.h,v 1.52 2005/05/25 10:29:41 gleixner Exp $ */
 
 #ifndef __LINUX_MTD_MAP_H__
 #define __LINUX_MTD_MAP_H__
@@ -263,6 +263,17 @@ static inline map_word map_word_and(stru
 	return r;
 }
 
+static inline map_word map_word_clr(struct map_info *map, map_word val1, map_word val2)
+{
+	map_word r;
+	int i;
+
+	for (i=0; i<map_words(map); i++) {
+		r.x[i] = val1.x[i] & ~val2.x[i];
+	}
+	return r;
+}
+
 static inline map_word map_word_or(struct map_info *map, map_word val1, map_word val2)
 {
 	map_word r;
@@ -273,6 +284,7 @@ static inline map_word map_word_or(struc
 	}
 	return r;
 }
+
 #define map_word_andequal(m, a, b, z) map_word_equal(m, z, map_word_and(m, a, b))
 
 static inline int map_word_bitsset(struct map_info *map, map_word val1, map_word val2)
@@ -328,16 +340,27 @@ static inline map_word map_word_load_par
 	return orig;
 }
 
+#if BITS_PER_LONG < 64
+#define MAP_FF_LIMIT 4
+#else
+#define MAP_FF_LIMIT 8
+#endif
+
 static inline map_word map_word_ff(struct map_info *map)
 {
 	map_word r;
 	int i;
-
-	for (i=0; i<map_words(map); i++) {
-		r.x[i] = ~0UL;
+	
+	if (map_bankwidth(map) < MAP_FF_LIMIT) {
+		int bw = 8 * map_bankwidth(map);
+		r.x[0] = (1 << bw) - 1;
+	} else {
+		for (i=0; i<map_words(map); i++)
+			r.x[i] = ~0UL;
 	}
 	return r;
 }
+
 static inline map_word inline_map_read(struct map_info *map, unsigned long ofs)
 {
 	map_word r;
@@ -405,7 +428,7 @@ extern void simple_map_init(struct map_i
 
 
 #define simple_map_init(map) BUG_ON(!map_bankwidth_supported((map)->bankwidth))
-#define map_is_linear(map) (1)
+#define map_is_linear(map) ({ (void)(map); 1; })
 
 #endif /* !CONFIG_MTD_COMPLEX_MAPPINGS */
 
diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
--- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h
@@ -1,5 +1,5 @@
 /* 
- * $Id: mtd.h,v 1.56 2004/08/09 18:46:04 dmarlin Exp $
+ * $Id: mtd.h,v 1.59 2005/04/11 10:19:02 gleixner Exp $
  *
  * Copyright (C) 1999-2003 David Woodhouse <dwmw2@infradead.org> et al.
  *
@@ -18,6 +18,7 @@
 #include <linux/types.h>
 #include <linux/module.h>
 #include <linux/uio.h>
+#include <linux/notifier.h>
 
 #include <linux/mtd/compatmac.h>
 #include <mtd/mtd-abi.h>
@@ -69,7 +70,6 @@ struct mtd_info {
 
 	u_int32_t oobblock;  // Size of OOB blocks (e.g. 512)
 	u_int32_t oobsize;   // Amount of OOB data per block (e.g. 16)
-	u_int32_t oobavail;  // Number of bytes in OOB area available for fs 
 	u_int32_t ecctype;
 	u_int32_t eccsize;
 	
@@ -80,6 +80,7 @@ struct mtd_info {
 
 	// oobinfo is a nand_oobinfo structure, which can be set by iotcl (MEMSETOOBINFO)
 	struct nand_oobinfo oobinfo;
+	u_int32_t oobavail;  // Number of bytes in OOB area available for fs 
 
 	/* Data for variable erase regions. If numeraseregions is zero,
 	 * it means that the whole device has erasesize as given above. 
@@ -113,12 +114,12 @@ struct mtd_info {
 	 * flash devices. The user data is one time programmable but the
 	 * factory data is read only. 
 	 */
-	int (*read_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
-
+	int (*get_fact_prot_info) (struct mtd_info *mtd, struct otp_info *buf, size_t len);
 	int (*read_fact_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
-
-	/* This function is not yet implemented */
+	int (*get_user_prot_info) (struct mtd_info *mtd, struct otp_info *buf, size_t len);
+	int (*read_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
 	int (*write_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
+	int (*lock_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len);
 
 	/* kvec-based read/write methods. We need these especially for NAND flash,
 	   with its limited number of write cycles per erase.
@@ -147,6 +148,8 @@ struct mtd_info {
 	int (*block_isbad) (struct mtd_info *mtd, loff_t ofs);
 	int (*block_markbad) (struct mtd_info *mtd, loff_t ofs);
 
+	struct notifier_block reboot_notifier;  /* default mode before reboot */
+
 	void *priv;
 
 	struct module *owner;
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -5,7 +5,7 @@
  *                     Steven J. Hill <sjhill@realitydiluted.com>
  *		       Thomas Gleixner <tglx@linutronix.de>
  *
- * $Id: nand.h,v 1.68 2004/11/12 10:40:37 gleixner Exp $
+ * $Id: nand.h,v 1.73 2005/05/31 19:39:17 gleixner Exp $
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -48,6 +48,10 @@
  *  02-08-2004 tglx 	added option field to nand structure for chip anomalities
  *  05-25-2004 tglx 	added bad block table support, ST-MICRO manufacturer id
  *			update of nand_chip structure description
+ *  01-17-2005 dmarlin	added extended commands for AG-AND device and added option 
+ * 			for BBT_AUTO_REFRESH.
+ *  01-20-2005 dmarlin	added optional pointer to hardware specific callback for 
+ *			extra error status checks.
  */
 #ifndef __LINUX_MTD_NAND_H
 #define __LINUX_MTD_NAND_H
@@ -115,6 +119,25 @@ extern int nand_read_raw (struct mtd_inf
 #define NAND_CMD_READSTART	0x30
 #define NAND_CMD_CACHEDPROG	0x15
 
+/* Extended commands for AG-AND device */
+/* 
+ * Note: the command for NAND_CMD_DEPLETE1 is really 0x00 but 
+ *       there is no way to distinguish that from NAND_CMD_READ0
+ *       until the remaining sequence of commands has been completed
+ *       so add a high order bit and mask it off in the command.
+ */
+#define NAND_CMD_DEPLETE1	0x100
+#define NAND_CMD_DEPLETE2	0x38
+#define NAND_CMD_STATUS_MULTI	0x71
+#define NAND_CMD_STATUS_ERROR	0x72
+/* multi-bank error status (banks 0-3) */
+#define NAND_CMD_STATUS_ERROR0	0x73
+#define NAND_CMD_STATUS_ERROR1	0x74
+#define NAND_CMD_STATUS_ERROR2	0x75
+#define NAND_CMD_STATUS_ERROR3	0x76
+#define NAND_CMD_STATUS_RESET	0x7f
+#define NAND_CMD_STATUS_CLEAR	0xff
+
 /* Status bits */
 #define NAND_STATUS_FAIL	0x01
 #define NAND_STATUS_FAIL_N1	0x02
@@ -143,7 +166,7 @@ extern int nand_read_raw (struct mtd_inf
 
 /*
  * Constants for Hardware ECC
-*/
+ */
 /* Reset Hardware ECC for read */
 #define NAND_ECC_READ		0
 /* Reset Hardware ECC for write */
@@ -151,6 +174,10 @@ extern int nand_read_raw (struct mtd_inf
 /* Enable Hardware ECC before syndrom is read back from flash */
 #define NAND_ECC_READSYN	2
 
+/* Bit mask for flags passed to do_nand_read_ecc */
+#define NAND_GET_DEVICE		0x80
+
+
 /* Option constants for bizarre disfunctionality and real
 *  features
 */
@@ -170,6 +197,10 @@ extern int nand_read_raw (struct mtd_inf
 /* Chip has a array of 4 pages which can be read without
  * additional ready /busy waits */
 #define NAND_4PAGE_ARRAY	0x00000040 
+/* Chip requires that BBT is periodically rewritten to prevent
+ * bits from adjacent blocks from 'leaking' in altering data.
+ * This happens with the Renesas AG-AND chips, possibly others.  */
+#define BBT_AUTO_REFRESH	0x00000080
 
 /* Options valid for Samsung large page devices */
 #define NAND_SAMSUNG_LP_OPTIONS \
@@ -192,7 +223,8 @@ extern int nand_read_raw (struct mtd_inf
  * This can only work if we have the ecc bytes directly behind the 
  * data bytes. Applies for DOC and AG-AND Renesas HW Reed Solomon generators */
 #define NAND_HWECC_SYNDROME	0x00020000
-
+/* This option skips the bbt scan during initialization. */
+#define NAND_SKIP_BBTSCAN	0x00040000
 
 /* Options set by nand scan */
 /* Nand scan has allocated oob_buf */
@@ -221,10 +253,13 @@ struct nand_chip;
  * struct nand_hw_control - Control structure for hardware controller (e.g ECC generator) shared among independend devices
  * @lock:               protection lock  
  * @active:		the mtd device which holds the controller currently
+ * @wq:			wait queue to sleep on if a NAND operation is in progress
+ *                      used instead of the per chip wait queue when a hw controller is available
  */
 struct nand_hw_control {
 	spinlock_t	 lock;
 	struct nand_chip *active;
+	wait_queue_head_t wq;
 };
 
 /**
@@ -283,6 +318,8 @@ struct nand_hw_control {
  * @badblock_pattern:	[REPLACEABLE] bad block scan pattern used for initial bad block scan 
  * @controller:		[OPTIONAL] a pointer to a hardware controller structure which is shared among multiple independend devices
  * @priv:		[OPTIONAL] pointer to private chip date
+ * @errstat:		[OPTIONAL] hardware specific function to perform additional error status checks 
+ *			(determine if errors are correctable)
  */
  
 struct nand_chip {
@@ -338,6 +375,7 @@ struct nand_chip {
 	struct nand_bbt_descr	*badblock_pattern;
 	struct nand_hw_control  *controller;
 	void		*priv;
+	int		(*errstat)(struct mtd_info *mtd, struct nand_chip *this, int state, int status, int page);
 };
 
 /*
@@ -349,6 +387,7 @@ struct nand_chip {
 #define NAND_MFR_NATIONAL	0x8f
 #define NAND_MFR_RENESAS	0x07
 #define NAND_MFR_STMICRO	0x20
+#define NAND_MFR_HYNIX          0xad
 
 /**
  * struct nand_flash_dev - NAND Flash Device ID Structure
@@ -459,6 +498,9 @@ extern int nand_update_bbt (struct mtd_i
 extern int nand_default_bbt (struct mtd_info *mtd);
 extern int nand_isbad_bbt (struct mtd_info *mtd, loff_t offs, int allowbbt);
 extern int nand_erase_nand (struct mtd_info *mtd, struct erase_info *instr, int allowbbt);
+extern int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
+                             size_t * retlen, u_char * buf, u_char * oob_buf,
+                             struct nand_oobinfo *oobsel, int flags);
 
 /*
 * Constants for oob configuration
diff --git a/include/linux/mtd/plat-ram.h b/include/linux/mtd/plat-ram.h
new file mode 100644
--- /dev/null
+++ b/include/linux/mtd/plat-ram.h
@@ -0,0 +1,35 @@
+/* linux/include/mtd/plat-ram.h
+ *
+ * (c) 2004 Simtec Electronics
+ *	http://www.simtec.co.uk/products/SWLINUX/
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * Generic platform device based RAM map
+ *
+ * $Id: plat-ram.h,v 1.2 2005/01/24 00:37:40 bjd Exp $
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef __LINUX_MTD_PLATRAM_H
+#define __LINUX_MTD_PLATRAM_H __FILE__
+
+#define PLATRAM_RO (0)
+#define PLATRAM_RW (1)
+
+struct platdata_mtd_ram {
+	char			*mapname;
+	char		       **probes;
+	struct mtd_partition	*partitions;
+	int			 nr_partitions;
+	int			 bankwidth;
+
+	/* control callbacks */
+
+	void	(*set_rw)(struct device *dev, int to);
+};
+
+#endif /* __LINUX_MTD_PLATRAM_H */
diff --git a/include/linux/mtd/xip.h b/include/linux/mtd/xip.h
--- a/include/linux/mtd/xip.h
+++ b/include/linux/mtd/xip.h
@@ -58,22 +58,16 @@
  * 		returned value is <= the real elapsed time.
  * 	note 2: this should be able to cope with a few seconds without
  * 		overflowing.
+ *
+ * xip_iprefetch()
+ *  
+ *      Macro to fill instruction prefetch
+ *	e.g. a series of nops:  asm volatile (".rep 8; nop; .endr"); 
  */
 
-#if defined(CONFIG_ARCH_SA1100) || defined(CONFIG_ARCH_PXA)
+#include <asm/mtd-xip.h>
 
-#include <asm/hardware.h>
-#ifdef CONFIG_ARCH_PXA
-#include <asm/arch/pxa-regs.h>
-#endif
-
-#define xip_irqpending()	(ICIP & ICMR)
-
-/* we sample OSCR and convert desired delta to usec (1/4 ~= 1000000/3686400) */
-#define xip_currtime()		(OSCR)
-#define xip_elapsed_since(x)	(signed)((OSCR - (x)) / 4)
-
-#else
+#ifndef xip_irqpending
 
 #warning "missing IRQ and timer primitives for XIP MTD support"
 #warning "some of the XIP MTD support code will be disabled"
@@ -85,16 +79,17 @@
 
 #endif
 
+#ifndef xip_iprefetch
+#define xip_iprefetch()		do { } while (0)
+#endif
+
 /*
  * xip_cpu_idle() is used when waiting for a delay equal or larger than
  * the system timer tick period.  This should put the CPU into idle mode
  * to save power and to be woken up only when some interrupts are pending.
- * As above, this should not rely upon standard kernel code.
+ * This should not rely upon standard kernel code.
  */
-
-#if defined(CONFIG_CPU_XSCALE)
-#define xip_cpu_idle()  asm volatile ("mcr p14, 0, %0, c7, c0, 0" :: "r" (1))
-#else
+#ifndef xip_cpu_idle
 #define xip_cpu_idle()  do { } while (0)
 #endif
 
diff --git a/include/linux/namespace.h b/include/linux/namespace.h
--- a/include/linux/namespace.h
+++ b/include/linux/namespace.h
@@ -12,13 +12,13 @@ struct namespace {
 	struct rw_semaphore	sem;
 };
 
-extern void umount_tree(struct vfsmount *);
 extern int copy_namespace(int, struct task_struct *);
 extern void __put_namespace(struct namespace *namespace);
 
 static inline void put_namespace(struct namespace *namespace)
 {
-	if (atomic_dec_and_test(&namespace->count))
+	if (atomic_dec_and_lock(&namespace->count, &vfsmount_lock))
+		/* releases vfsmount_lock */
 		__put_namespace(namespace);
 }
 
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -41,7 +41,7 @@
 struct divert_blk;
 struct vlan_group;
 struct ethtool_ops;
-struct netpoll;
+struct netpoll_info;
 					/* source back-compat hooks */
 #define SET_ETHTOOL_OPS(netdev,ops) \
 	( (netdev)->ethtool_ops = (ops) )
@@ -164,12 +164,6 @@ struct netif_rx_stats
 	unsigned total;
 	unsigned dropped;
 	unsigned time_squeeze;
-	unsigned throttled;
-	unsigned fastroute_hit;
-	unsigned fastroute_success;
-	unsigned fastroute_defer;
-	unsigned fastroute_deferred_out;
-	unsigned fastroute_latency_reduction;
 	unsigned cpu_collision;
 };
 
@@ -468,7 +462,7 @@ struct net_device
 						     unsigned char *haddr);
 	int			(*neigh_setup)(struct net_device *dev, struct neigh_parms *);
 #ifdef CONFIG_NETPOLL
-	struct netpoll		*np;
+	struct netpoll_info	*npinfo;
 #endif
 #ifdef CONFIG_NET_POLL_CONTROLLER
 	void                    (*poll_controller)(struct net_device *dev);
@@ -562,12 +556,9 @@ static inline int unregister_gifconf(uns
 
 struct softnet_data
 {
-	int			throttle;
-	int			cng_level;
-	int			avg_blog;
+	struct net_device	*output_queue;
 	struct sk_buff_head	input_pkt_queue;
 	struct list_head	poll_list;
-	struct net_device	*output_queue;
 	struct sk_buff		*completion_queue;
 
 	struct net_device	backlog_dev;	/* Sorry. 8) */
@@ -925,10 +916,6 @@ extern int skb_checksum_help(struct sk_b
 extern void		net_enable_timestamp(void);
 extern void		net_disable_timestamp(void);
 
-#ifdef CONFIG_SYSCTL
-extern char *net_sysctl_strdup(const char *s);
-#endif
-
 #endif /* __KERNEL__ */
 
 #endif	/* _LINUX_DEV_H */
diff --git a/include/linux/netfilter_ipv4.h b/include/linux/netfilter_ipv4.h
--- a/include/linux/netfilter_ipv4.h
+++ b/include/linux/netfilter_ipv4.h
@@ -75,12 +75,6 @@ enum nf_ip_hook_priorities {
 #define SO_ORIGINAL_DST 80
 
 #ifdef __KERNEL__
-#ifdef CONFIG_NETFILTER_DEBUG
-void nf_debug_ip_local_deliver(struct sk_buff *skb);
-void nf_debug_ip_loopback_xmit(struct sk_buff *newskb);
-void nf_debug_ip_finish_output2(struct sk_buff *skb);
-#endif /*CONFIG_NETFILTER_DEBUG*/
-
 extern int ip_route_me_harder(struct sk_buff **pskb);
 
 /* Call this before modifying an existing IP packet: ensures it is
diff --git a/include/linux/netfilter_ipv4/ip_conntrack.h b/include/linux/netfilter_ipv4/ip_conntrack.h
--- a/include/linux/netfilter_ipv4/ip_conntrack.h
+++ b/include/linux/netfilter_ipv4/ip_conntrack.h
@@ -197,6 +197,9 @@ struct ip_conntrack_expect
 	/* Timer function; deletes the expectation. */
 	struct timer_list timeout;
 
+	/* Usage count. */
+	atomic_t use;
+
 #ifdef CONFIG_IP_NF_NAT_NEEDED
 	/* This is the original per-proto part, used to map the
 	 * expected connection the way the recipient expects. */
@@ -236,7 +239,7 @@ ip_conntrack_get(const struct sk_buff *s
 }
 
 /* decrement reference count on a conntrack */
-extern inline void ip_conntrack_put(struct ip_conntrack *ct);
+extern void ip_conntrack_put(struct ip_conntrack *ct);
 
 /* call to create an explicit dependency on ip_conntrack. */
 extern void need_ip_conntrack(void);
diff --git a/include/linux/netfilter_ipv4/ip_conntrack_core.h b/include/linux/netfilter_ipv4/ip_conntrack_core.h
--- a/include/linux/netfilter_ipv4/ip_conntrack_core.h
+++ b/include/linux/netfilter_ipv4/ip_conntrack_core.h
@@ -1,7 +1,6 @@
 #ifndef _IP_CONNTRACK_CORE_H
 #define _IP_CONNTRACK_CORE_H
 #include <linux/netfilter.h>
-#include <linux/netfilter_ipv4/lockhelp.h>
 
 /* This header is used to share core functionality between the
    standalone connection tracking module, and the compatibility layer's use
@@ -47,6 +46,6 @@ static inline int ip_conntrack_confirm(s
 
 extern struct list_head *ip_conntrack_hash;
 extern struct list_head ip_conntrack_expect_list;
-DECLARE_RWLOCK_EXTERN(ip_conntrack_lock);
+extern rwlock_t ip_conntrack_lock;
 #endif /* _IP_CONNTRACK_CORE_H */
 
diff --git a/include/linux/netfilter_ipv4/ip_conntrack_helper.h b/include/linux/netfilter_ipv4/ip_conntrack_helper.h
--- a/include/linux/netfilter_ipv4/ip_conntrack_helper.h
+++ b/include/linux/netfilter_ipv4/ip_conntrack_helper.h
@@ -30,9 +30,10 @@ extern int ip_conntrack_helper_register(
 extern void ip_conntrack_helper_unregister(struct ip_conntrack_helper *);
 
 /* Allocate space for an expectation: this is mandatory before calling 
-   ip_conntrack_expect_related. */
-extern struct ip_conntrack_expect *ip_conntrack_expect_alloc(void);
-extern void ip_conntrack_expect_free(struct ip_conntrack_expect *exp);
+   ip_conntrack_expect_related.  You will have to call put afterwards. */
+extern struct ip_conntrack_expect *
+ip_conntrack_expect_alloc(struct ip_conntrack *master);
+extern void ip_conntrack_expect_put(struct ip_conntrack_expect *exp);
 
 /* Add an expected connection: can have more than one per connection */
 extern int ip_conntrack_expect_related(struct ip_conntrack_expect *exp);
diff --git a/include/linux/netfilter_ipv4/ip_nat.h b/include/linux/netfilter_ipv4/ip_nat.h
--- a/include/linux/netfilter_ipv4/ip_nat.h
+++ b/include/linux/netfilter_ipv4/ip_nat.h
@@ -50,10 +50,9 @@ struct ip_nat_multi_range_compat
 
 #ifdef __KERNEL__
 #include <linux/list.h>
-#include <linux/netfilter_ipv4/lockhelp.h>
 
 /* Protects NAT hash tables, and NAT-private part of conntracks. */
-DECLARE_RWLOCK_EXTERN(ip_nat_lock);
+extern rwlock_t ip_nat_lock;
 
 /* The structure embedded in the conntrack structure. */
 struct ip_nat_info
diff --git a/include/linux/netfilter_ipv4/ipt_CLUSTERIP.h b/include/linux/netfilter_ipv4/ipt_CLUSTERIP.h
--- a/include/linux/netfilter_ipv4/ipt_CLUSTERIP.h
+++ b/include/linux/netfilter_ipv4/ipt_CLUSTERIP.h
@@ -18,7 +18,6 @@ struct clusterip_config;
 struct ipt_clusterip_tgt_info {
 
 	u_int32_t flags;
-	struct clusterip_config *config;
 	
 	/* only relevant for new ones */
 	u_int8_t clustermac[6];
@@ -27,6 +26,8 @@ struct ipt_clusterip_tgt_info {
 	u_int16_t local_nodes[CLUSTERIP_MAX_NODES];
 	enum clusterip_hashmode hash_mode;
 	u_int32_t hash_initval;
+
+	struct clusterip_config *config;
 };
 
 #endif /*_IPT_CLUSTERIP_H_target*/
diff --git a/include/linux/netfilter_ipv4/listhelp.h b/include/linux/netfilter_ipv4/listhelp.h
--- a/include/linux/netfilter_ipv4/listhelp.h
+++ b/include/linux/netfilter_ipv4/listhelp.h
@@ -2,7 +2,6 @@
 #define _LISTHELP_H
 #include <linux/config.h>
 #include <linux/list.h>
-#include <linux/netfilter_ipv4/lockhelp.h>
 
 /* Header to do more comprehensive job than linux/list.h; assume list
    is first entry in structure. */
diff --git a/include/linux/netfilter_ipv4/lockhelp.h b/include/linux/netfilter_ipv4/lockhelp.h
deleted file mode 100644
--- a/include/linux/netfilter_ipv4/lockhelp.h
+++ /dev/null
@@ -1,129 +0,0 @@
-#ifndef _LOCKHELP_H
-#define _LOCKHELP_H
-#include <linux/config.h>
-
-#include <linux/spinlock.h>
-#include <asm/atomic.h>
-#include <linux/interrupt.h>
-#include <linux/smp.h>
-
-/* Header to do help in lock debugging. */
-
-#ifdef CONFIG_NETFILTER_DEBUG
-struct spinlock_debug
-{
-	spinlock_t l;
-	atomic_t locked_by;
-};
-
-struct rwlock_debug
-{
-	rwlock_t l;
-	long read_locked_map;
-	long write_locked_map;
-};
-
-#define DECLARE_LOCK(l) 						\
-struct spinlock_debug l = { SPIN_LOCK_UNLOCKED, ATOMIC_INIT(-1) }
-#define DECLARE_LOCK_EXTERN(l) 			\
-extern struct spinlock_debug l
-#define DECLARE_RWLOCK(l)				\
-struct rwlock_debug l = { RW_LOCK_UNLOCKED, 0, 0 }
-#define DECLARE_RWLOCK_EXTERN(l)		\
-extern struct rwlock_debug l
-
-#define MUST_BE_LOCKED(l)						\
-do { if (atomic_read(&(l)->locked_by) != smp_processor_id())		\
-	printk("ASSERT %s:%u %s unlocked\n", __FILE__, __LINE__, #l);	\
-} while(0)
-
-#define MUST_BE_UNLOCKED(l)						\
-do { if (atomic_read(&(l)->locked_by) == smp_processor_id())		\
-	printk("ASSERT %s:%u %s locked\n", __FILE__, __LINE__, #l);	\
-} while(0)
-
-/* Write locked OK as well. */
-#define MUST_BE_READ_LOCKED(l)						    \
-do { if (!((l)->read_locked_map & (1UL << smp_processor_id()))		    \
-	 && !((l)->write_locked_map & (1UL << smp_processor_id())))	    \
-	printk("ASSERT %s:%u %s not readlocked\n", __FILE__, __LINE__, #l); \
-} while(0)
-
-#define MUST_BE_WRITE_LOCKED(l)						     \
-do { if (!((l)->write_locked_map & (1UL << smp_processor_id())))	     \
-	printk("ASSERT %s:%u %s not writelocked\n", __FILE__, __LINE__, #l); \
-} while(0)
-
-#define MUST_BE_READ_WRITE_UNLOCKED(l)					  \
-do { if ((l)->read_locked_map & (1UL << smp_processor_id()))		  \
-	printk("ASSERT %s:%u %s readlocked\n", __FILE__, __LINE__, #l);	  \
- else if ((l)->write_locked_map & (1UL << smp_processor_id()))		  \
-	 printk("ASSERT %s:%u %s writelocked\n", __FILE__, __LINE__, #l); \
-} while(0)
-
-#define LOCK_BH(lk)						\
-do {								\
-	MUST_BE_UNLOCKED(lk);					\
-	spin_lock_bh(&(lk)->l);					\
-	atomic_set(&(lk)->locked_by, smp_processor_id());	\
-} while(0)
-
-#define UNLOCK_BH(lk)				\
-do {						\
-	MUST_BE_LOCKED(lk);			\
-	atomic_set(&(lk)->locked_by, -1);	\
-	spin_unlock_bh(&(lk)->l);		\
-} while(0)
-
-#define READ_LOCK(lk) 						\
-do {								\
-	MUST_BE_READ_WRITE_UNLOCKED(lk);			\
-	read_lock_bh(&(lk)->l);					\
-	set_bit(smp_processor_id(), &(lk)->read_locked_map);	\
-} while(0)
-
-#define WRITE_LOCK(lk)							  \
-do {									  \
-	MUST_BE_READ_WRITE_UNLOCKED(lk);				  \
-	write_lock_bh(&(lk)->l);					  \
-	set_bit(smp_processor_id(), &(lk)->write_locked_map);		  \
-} while(0)
-
-#define READ_UNLOCK(lk)							\
-do {									\
-	if (!((lk)->read_locked_map & (1UL << smp_processor_id())))	\
-		printk("ASSERT: %s:%u %s not readlocked\n", 		\
-		       __FILE__, __LINE__, #lk);			\
-	clear_bit(smp_processor_id(), &(lk)->read_locked_map);		\
-	read_unlock_bh(&(lk)->l);					\
-} while(0)
-
-#define WRITE_UNLOCK(lk)					\
-do {								\
-	MUST_BE_WRITE_LOCKED(lk);				\
-	clear_bit(smp_processor_id(), &(lk)->write_locked_map);	\
-	write_unlock_bh(&(lk)->l);				\
-} while(0)
-
-#else
-#define DECLARE_LOCK(l) spinlock_t l = SPIN_LOCK_UNLOCKED
-#define DECLARE_LOCK_EXTERN(l) extern spinlock_t l
-#define DECLARE_RWLOCK(l) rwlock_t l = RW_LOCK_UNLOCKED
-#define DECLARE_RWLOCK_EXTERN(l) extern rwlock_t l
-
-#define MUST_BE_LOCKED(l)
-#define MUST_BE_UNLOCKED(l)
-#define MUST_BE_READ_LOCKED(l)
-#define MUST_BE_WRITE_LOCKED(l)
-#define MUST_BE_READ_WRITE_UNLOCKED(l)
-
-#define LOCK_BH(l) spin_lock_bh(l)
-#define UNLOCK_BH(l) spin_unlock_bh(l)
-
-#define READ_LOCK(l) read_lock_bh(l)
-#define WRITE_LOCK(l) write_lock_bh(l)
-#define READ_UNLOCK(l) read_unlock_bh(l)
-#define WRITE_UNLOCK(l) write_unlock_bh(l)
-#endif /*CONFIG_NETFILTER_DEBUG*/
-
-#endif /* _LOCKHELP_H */
diff --git a/include/linux/netlink.h b/include/linux/netlink.h
--- a/include/linux/netlink.h
+++ b/include/linux/netlink.h
@@ -5,20 +5,20 @@
 #include <linux/types.h>
 
 #define NETLINK_ROUTE		0	/* Routing/device hook				*/
-#define NETLINK_SKIP		1	/* Reserved for ENskip  			*/
+#define NETLINK_W1		1	/* 1-wire subsystem				*/
 #define NETLINK_USERSOCK	2	/* Reserved for user mode socket protocols 	*/
 #define NETLINK_FIREWALL	3	/* Firewalling hook				*/
 #define NETLINK_TCPDIAG		4	/* TCP socket monitoring			*/
 #define NETLINK_NFLOG		5	/* netfilter/iptables ULOG */
 #define NETLINK_XFRM		6	/* ipsec */
 #define NETLINK_SELINUX		7	/* SELinux event notifications */
-#define NETLINK_ARPD		8
+#define NETLINK_ISCSI		8	/* Open-iSCSI */
 #define NETLINK_AUDIT		9	/* auditing */
-#define NETLINK_ROUTE6		11	/* af_inet6 route comm channel */
+#define NETLINK_FIB_LOOKUP	10	
+#define NETLINK_NETFILTER	12	/* netfilter subsystem */
 #define NETLINK_IP6_FW		13
 #define NETLINK_DNRTMSG		14	/* DECnet routing messages */
 #define NETLINK_KOBJECT_UEVENT	15	/* Kernel messages to userspace */
-#define NETLINK_TAPBASE		16	/* 16 to 31 are ethertap */
 
 #define MAX_LINKS 32		
 
@@ -146,7 +146,7 @@ struct netlink_callback
 	int		(*dump)(struct sk_buff * skb, struct netlink_callback *cb);
 	int		(*done)(struct netlink_callback *cb);
 	int		family;
-	long		args[4];
+	long		args[5];
 };
 
 struct netlink_notify
@@ -156,7 +156,7 @@ struct netlink_notify
 };
 
 static __inline__ struct nlmsghdr *
-__nlmsg_put(struct sk_buff *skb, u32 pid, u32 seq, int type, int len)
+__nlmsg_put(struct sk_buff *skb, u32 pid, u32 seq, int type, int len, int flags)
 {
 	struct nlmsghdr *nlh;
 	int size = NLMSG_LENGTH(len);
@@ -164,15 +164,32 @@ __nlmsg_put(struct sk_buff *skb, u32 pid
 	nlh = (struct nlmsghdr*)skb_put(skb, NLMSG_ALIGN(size));
 	nlh->nlmsg_type = type;
 	nlh->nlmsg_len = size;
-	nlh->nlmsg_flags = 0;
+	nlh->nlmsg_flags = flags;
 	nlh->nlmsg_pid = pid;
 	nlh->nlmsg_seq = seq;
+	memset(NLMSG_DATA(nlh) + len, 0, NLMSG_ALIGN(size) - size);
 	return nlh;
 }
 
+#define NLMSG_NEW(skb, pid, seq, type, len, flags) \
+({	if (skb_tailroom(skb) < (int)NLMSG_SPACE(len)) \
+		goto nlmsg_failure; \
+	__nlmsg_put(skb, pid, seq, type, len, flags); })
+
 #define NLMSG_PUT(skb, pid, seq, type, len) \
-({ if (skb_tailroom(skb) < (int)NLMSG_SPACE(len)) goto nlmsg_failure; \
-   __nlmsg_put(skb, pid, seq, type, len); })
+	NLMSG_NEW(skb, pid, seq, type, len, 0)
+
+#define NLMSG_NEW_ANSWER(skb, cb, type, len, flags) \
+	NLMSG_NEW(skb, NETLINK_CB((cb)->skb).pid, \
+		  (cb)->nlh->nlmsg_seq, type, len, flags)
+
+#define NLMSG_END(skb, nlh) \
+({	(nlh)->nlmsg_len = (skb)->tail - (unsigned char *) (nlh); \
+	(skb)->len; })
+
+#define NLMSG_CANCEL(skb, nlh) \
+({	skb_trim(skb, (unsigned char *) (nlh) - (skb)->data); \
+	-1; })
 
 extern int netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
 			      struct nlmsghdr *nlh,
diff --git a/include/linux/netpoll.h b/include/linux/netpoll.h
--- a/include/linux/netpoll.h
+++ b/include/linux/netpoll.h
@@ -9,6 +9,7 @@
 
 #include <linux/netdevice.h>
 #include <linux/interrupt.h>
+#include <linux/rcupdate.h>
 #include <linux/list.h>
 
 struct netpoll;
@@ -16,14 +17,20 @@ struct netpoll;
 struct netpoll {
 	struct net_device *dev;
 	char dev_name[16], *name;
-	int rx_flags;
 	void (*rx_hook)(struct netpoll *, int, char *, int);
 	void (*drop)(struct sk_buff *skb);
 	u32 local_ip, remote_ip;
 	u16 local_port, remote_port;
 	unsigned char local_mac[6], remote_mac[6];
+};
+
+struct netpoll_info {
 	spinlock_t poll_lock;
 	int poll_owner;
+	int tries;
+	int rx_flags;
+	spinlock_t rx_lock;
+	struct netpoll *rx_np; /* netpoll that registered an rx_hook */
 };
 
 void netpoll_poll(struct netpoll *np);
@@ -39,28 +46,47 @@ void netpoll_queue(struct sk_buff *skb);
 #ifdef CONFIG_NETPOLL
 static inline int netpoll_rx(struct sk_buff *skb)
 {
-	return skb->dev->np && skb->dev->np->rx_flags && __netpoll_rx(skb);
+	struct netpoll_info *npinfo = skb->dev->npinfo;
+	unsigned long flags;
+	int ret = 0;
+
+	if (!npinfo || (!npinfo->rx_np && !npinfo->rx_flags))
+		return 0;
+
+	spin_lock_irqsave(&npinfo->rx_lock, flags);
+	/* check rx_flags again with the lock held */
+	if (npinfo->rx_flags && __netpoll_rx(skb))
+		ret = 1;
+	spin_unlock_irqrestore(&npinfo->rx_lock, flags);
+
+	return ret;
 }
 
-static inline void netpoll_poll_lock(struct net_device *dev)
+static inline void *netpoll_poll_lock(struct net_device *dev)
 {
-	if (dev->np) {
-		spin_lock(&dev->np->poll_lock);
-		dev->np->poll_owner = smp_processor_id();
+	rcu_read_lock(); /* deal with race on ->npinfo */
+	if (dev->npinfo) {
+		spin_lock(&dev->npinfo->poll_lock);
+		dev->npinfo->poll_owner = smp_processor_id();
+		return dev->npinfo;
 	}
+	return NULL;
 }
 
-static inline void netpoll_poll_unlock(struct net_device *dev)
+static inline void netpoll_poll_unlock(void *have)
 {
-	if (dev->np) {
-		spin_unlock(&dev->np->poll_lock);
-		dev->np->poll_owner = -1;
+	struct netpoll_info *npi = have;
+
+	if (npi) {
+		npi->poll_owner = -1;
+		spin_unlock(&npi->poll_lock);
 	}
+	rcu_read_unlock();
 }
 
 #else
 #define netpoll_rx(a) 0
-#define netpoll_poll_lock(a)
+#define netpoll_poll_lock(a) 0
 #define netpoll_poll_unlock(a)
 #endif
 
diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h
--- a/include/linux/nfs4.h
+++ b/include/linux/nfs4.h
@@ -28,7 +28,7 @@
 #define NFS4_ACCESS_DELETE      0x0010
 #define NFS4_ACCESS_EXECUTE     0x0020
 
-#define NFS4_FH_PERISTENT		0x0000
+#define NFS4_FH_PERSISTENT		0x0000
 #define NFS4_FH_NOEXPIRE_WITH_OPEN	0x0001
 #define NFS4_FH_VOLATILE_ANY		0x0002
 #define NFS4_FH_VOL_MIGRATION		0x0004
@@ -382,6 +382,8 @@ enum {
 	NFSPROC4_CLNT_READDIR,
 	NFSPROC4_CLNT_SERVER_CAPS,
 	NFSPROC4_CLNT_DELEGRETURN,
+	NFSPROC4_CLNT_GETACL,
+	NFSPROC4_CLNT_SETACL,
 };
 
 #endif
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
--- a/include/linux/nfs_fs.h
+++ b/include/linux/nfs_fs.h
@@ -15,7 +15,6 @@
 #include <linux/pagemap.h>
 #include <linux/rwsem.h>
 #include <linux/wait.h>
-#include <linux/uio.h>
 
 #include <linux/nfs_fs_sb.h>
 
@@ -29,7 +28,6 @@
 #include <linux/nfs4.h>
 #include <linux/nfs_xdr.h>
 #include <linux/rwsem.h>
-#include <linux/workqueue.h>
 #include <linux/mempool.h>
 
 /*
@@ -44,13 +42,6 @@
 #define NFS_DEF_FILE_IO_BUFFER_SIZE	4096
 
 /*
- * The upper limit on timeouts for the exponential backoff algorithm.
- */
-#define NFS_WRITEBACK_DELAY		(5*HZ)
-#define NFS_WRITEBACK_LOCKDELAY		(60*HZ)
-#define NFS_COMMIT_DELAY		(5*HZ)
-
-/*
  * superblock magic number for NFS
  */
 #define NFS_SUPER_MAGIC			0x6969
@@ -60,9 +51,6 @@
  */
 #define NFS_RPC_SWAPFLAGS		(RPC_TASK_SWAPPER|RPC_TASK_ROOTCREDS)
 
-#define NFS_RW_SYNC		0x0001	/* O_SYNC handling */
-#define NFS_RW_SWAP		0x0002	/* This is a swap request */
-
 /*
  * When flushing a cluster of dirty pages, there can be different
  * strategies:
@@ -96,7 +84,8 @@ struct nfs_open_context {
 	int error;
 
 	struct list_head list;
-	wait_queue_head_t waitq;
+
+	__u64 dir_cookie;
 };
 
 /*
@@ -104,6 +93,8 @@ struct nfs_open_context {
  */
 struct nfs_delegation;
 
+struct posix_acl;
+
 /*
  * nfs fs inode data in memory
  */
@@ -121,7 +112,8 @@ struct nfs_inode {
 	/*
 	 * Various flags
 	 */
-	unsigned int		flags;
+	unsigned long		flags;			/* atomic bit ops */
+	unsigned long		cache_validity;		/* bit mask */
 
 	/*
 	 * read_cache_jiffies is when we started read-caching this inode,
@@ -140,7 +132,6 @@ struct nfs_inode {
 	 *
 	 *	mtime != read_cache_mtime
 	 */
-	unsigned long		readdir_timestamp;
 	unsigned long		read_cache_jiffies;
 	unsigned long		attrtimeo;
 	unsigned long		attrtimeo_timestamp;
@@ -158,6 +149,10 @@ struct nfs_inode {
 	atomic_t		data_updates;
 
 	struct nfs_access_entry	cache_access;
+#ifdef CONFIG_NFS_V3_ACL
+	struct posix_acl	*acl_access;
+	struct posix_acl	*acl_default;
+#endif
 
 	/*
 	 * This is the cookie verifier used for NFSv3 readdir
@@ -180,29 +175,33 @@ struct nfs_inode {
 	/* Open contexts for shared mmap writes */
 	struct list_head	open_files;
 
-	wait_queue_head_t	nfs_i_wait;
-
 #ifdef CONFIG_NFS_V4
+	struct nfs4_cached_acl	*nfs4_acl;
         /* NFSv4 state */
 	struct list_head	open_states;
 	struct nfs_delegation	*delegation;
 	int			 delegation_state;
 	struct rw_semaphore	rwsem;
 #endif /* CONFIG_NFS_V4*/
-
 	struct inode		vfs_inode;
 };
 
 /*
- * Legal inode flag values
+ * Cache validity bit flags
+ */
+#define NFS_INO_INVALID_ATTR	0x0001		/* cached attrs are invalid */
+#define NFS_INO_INVALID_DATA	0x0002		/* cached data is invalid */
+#define NFS_INO_INVALID_ATIME	0x0004		/* cached atime is invalid */
+#define NFS_INO_INVALID_ACCESS	0x0008		/* cached access cred invalid */
+#define NFS_INO_INVALID_ACL	0x0010		/* cached acls are invalid */
+#define NFS_INO_REVAL_PAGECACHE	0x0020		/* must revalidate pagecache */
+
+/*
+ * Bit offsets in flags field
  */
-#define NFS_INO_STALE		0x0001		/* possible stale inode */
-#define NFS_INO_ADVISE_RDPLUS   0x0002          /* advise readdirplus */
-#define NFS_INO_REVALIDATING	0x0004		/* revalidating attrs */
-#define NFS_INO_INVALID_ATTR	0x0008		/* cached attrs are invalid */
-#define NFS_INO_INVALID_DATA	0x0010		/* cached data is invalid */
-#define NFS_INO_INVALID_ATIME	0x0020		/* cached atime is invalid */
-#define NFS_INO_INVALID_ACCESS	0x0040		/* cached access cred invalid */
+#define NFS_INO_REVALIDATING	(0)		/* revalidating attrs */
+#define NFS_INO_ADVISE_RDPLUS	(1)		/* advise readdirplus */
+#define NFS_INO_STALE		(2)		/* possible stale inode */
 
 static inline struct nfs_inode *NFS_I(struct inode *inode)
 {
@@ -228,8 +227,7 @@ static inline struct nfs_inode *NFS_I(st
 #define NFS_ATTRTIMEO_UPDATE(inode)	(NFS_I(inode)->attrtimeo_timestamp)
 
 #define NFS_FLAGS(inode)		(NFS_I(inode)->flags)
-#define NFS_REVALIDATING(inode)		(NFS_FLAGS(inode) & NFS_INO_REVALIDATING)
-#define NFS_STALE(inode)		(NFS_FLAGS(inode) & NFS_INO_STALE)
+#define NFS_STALE(inode)		(test_bit(NFS_INO_STALE, &NFS_FLAGS(inode)))
 
 #define NFS_FILEID(inode)		(NFS_I(inode)->fileid)
 
@@ -240,8 +238,11 @@ static inline int nfs_caches_unstable(st
 
 static inline void NFS_CACHEINV(struct inode *inode)
 {
-	if (!nfs_caches_unstable(inode))
-		NFS_FLAGS(inode) |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS;
+	if (!nfs_caches_unstable(inode)) {
+		spin_lock(&inode->i_lock);
+		NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS;
+		spin_unlock(&inode->i_lock);
+	}
 }
 
 static inline int nfs_server_capable(struct inode *inode, int cap)
@@ -251,7 +252,7 @@ static inline int nfs_server_capable(str
 
 static inline int NFS_USE_READDIRPLUS(struct inode *inode)
 {
-	return NFS_FLAGS(inode) & NFS_INO_ADVISE_RDPLUS;
+	return test_bit(NFS_INO_ADVISE_RDPLUS, &NFS_FLAGS(inode));
 }
 
 /**
@@ -294,12 +295,13 @@ extern int nfs_release(struct inode *, s
 extern int nfs_attribute_timeout(struct inode *inode);
 extern int nfs_revalidate_inode(struct nfs_server *server, struct inode *inode);
 extern int __nfs_revalidate_inode(struct nfs_server *, struct inode *);
+extern void nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping);
 extern int nfs_setattr(struct dentry *, struct iattr *);
+extern void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr);
 extern void nfs_begin_attr_update(struct inode *);
 extern void nfs_end_attr_update(struct inode *);
 extern void nfs_begin_data_update(struct inode *);
 extern void nfs_end_data_update(struct inode *);
-extern void nfs_end_data_update_defer(struct inode *);
 extern struct nfs_open_context *alloc_nfs_open_context(struct dentry *dentry, struct rpc_cred *cred);
 extern struct nfs_open_context *get_nfs_open_context(struct nfs_open_context *ctx);
 extern void put_nfs_open_context(struct nfs_open_context *ctx);
@@ -314,6 +316,9 @@ extern u32 root_nfs_parse_addr(char *nam
  * linux/fs/nfs/file.c
  */
 extern struct inode_operations nfs_file_inode_operations;
+#ifdef CONFIG_NFS_V3
+extern struct inode_operations nfs3_file_inode_operations;
+#endif /* CONFIG_NFS_V3 */
 extern struct file_operations nfs_file_operations;
 extern struct address_space_operations nfs_file_aops;
 
@@ -329,6 +334,22 @@ static inline struct rpc_cred *nfs_file_
 }
 
 /*
+ * linux/fs/nfs/xattr.c
+ */
+#ifdef CONFIG_NFS_V3_ACL
+extern ssize_t nfs3_listxattr(struct dentry *, char *, size_t);
+extern ssize_t nfs3_getxattr(struct dentry *, const char *, void *, size_t);
+extern int nfs3_setxattr(struct dentry *, const char *,
+			const void *, size_t, int);
+extern int nfs3_removexattr (struct dentry *, const char *name);
+#else
+# define nfs3_listxattr NULL
+# define nfs3_getxattr NULL
+# define nfs3_setxattr NULL
+# define nfs3_removexattr NULL
+#endif
+
+/*
  * linux/fs/nfs/direct.c
  */
 extern ssize_t nfs_direct_IO(int, struct kiocb *, const struct iovec *, loff_t,
@@ -342,6 +363,9 @@ extern ssize_t nfs_file_direct_write(str
  * linux/fs/nfs/dir.c
  */
 extern struct inode_operations nfs_dir_inode_operations;
+#ifdef CONFIG_NFS_V3
+extern struct inode_operations nfs3_dir_inode_operations;
+#endif /* CONFIG_NFS_V3 */
 extern struct file_operations nfs_dir_operations;
 extern struct dentry_operations nfs_dentry_operations;
 
@@ -377,10 +401,10 @@ extern void nfs_commit_done(struct rpc_t
  */
 extern int  nfs_sync_inode(struct inode *, unsigned long, unsigned int, int);
 #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
-extern int  nfs_commit_inode(struct inode *, unsigned long, unsigned int, int);
+extern int  nfs_commit_inode(struct inode *, int);
 #else
 static inline int
-nfs_commit_inode(struct inode *inode, unsigned long idx_start, unsigned int npages, int how)
+nfs_commit_inode(struct inode *inode, int how)
 {
 	return 0;
 }
@@ -434,11 +458,6 @@ static inline void nfs_writedata_free(st
 	mempool_free(p, nfs_wdata_mempool);
 }
 
-/* Hack for future NFS swap support */
-#ifndef IS_SWAPFILE
-# define IS_SWAPFILE(inode)	(0)
-#endif
-
 /*
  * linux/fs/nfs/read.c
  */
@@ -468,6 +487,29 @@ static inline void nfs_readdata_free(str
 extern void  nfs_readdata_release(struct rpc_task *task);
 
 /*
+ * linux/fs/nfs3proc.c
+ */
+#ifdef CONFIG_NFS_V3_ACL
+extern struct posix_acl *nfs3_proc_getacl(struct inode *inode, int type);
+extern int nfs3_proc_setacl(struct inode *inode, int type,
+			    struct posix_acl *acl);
+extern int nfs3_proc_set_default_acl(struct inode *dir, struct inode *inode,
+		mode_t mode);
+extern void nfs3_forget_cached_acls(struct inode *inode);
+#else
+static inline int nfs3_proc_set_default_acl(struct inode *dir,
+					    struct inode *inode,
+					    mode_t mode)
+{
+	return 0;
+}
+
+static inline void nfs3_forget_cached_acls(struct inode *inode)
+{
+}
+#endif /* CONFIG_NFS_V3_ACL */
+
+/*
  * linux/fs/mount_clnt.c
  * (Used only by nfsroot module)
  */
@@ -515,230 +557,6 @@ extern void * nfs_root_data(void);
 
 #define NFS_JUKEBOX_RETRY_TIME (5 * HZ)
 
-#ifdef CONFIG_NFS_V4
-
-struct idmap;
-
-/*
- * In a seqid-mutating op, this macro controls which error return
- * values trigger incrementation of the seqid.
- *
- * from rfc 3010:
- * The client MUST monotonically increment the sequence number for the
- * CLOSE, LOCK, LOCKU, OPEN, OPEN_CONFIRM, and OPEN_DOWNGRADE
- * operations.  This is true even in the event that the previous
- * operation that used the sequence number received an error.  The only
- * exception to this rule is if the previous operation received one of
- * the following errors: NFSERR_STALE_CLIENTID, NFSERR_STALE_STATEID,
- * NFSERR_BAD_STATEID, NFSERR_BAD_SEQID, NFSERR_BADXDR,
- * NFSERR_RESOURCE, NFSERR_NOFILEHANDLE.
- *
- */
-#define seqid_mutating_err(err)       \
-(((err) != NFSERR_STALE_CLIENTID) &&  \
- ((err) != NFSERR_STALE_STATEID)  &&  \
- ((err) != NFSERR_BAD_STATEID)    &&  \
- ((err) != NFSERR_BAD_SEQID)      &&  \
- ((err) != NFSERR_BAD_XDR)        &&  \
- ((err) != NFSERR_RESOURCE)       &&  \
- ((err) != NFSERR_NOFILEHANDLE))
-
-enum nfs4_client_state {
-	NFS4CLNT_OK  = 0,
-};
-
-/*
- * The nfs4_client identifies our client state to the server.
- */
-struct nfs4_client {
-	struct list_head	cl_servers;	/* Global list of servers */
-	struct in_addr		cl_addr;	/* Server identifier */
-	u64			cl_clientid;	/* constant */
-	nfs4_verifier		cl_confirm;
-	unsigned long		cl_state;
-
-	u32			cl_lockowner_id;
-
-	/*
-	 * The following rwsem ensures exclusive access to the server
-	 * while we recover the state following a lease expiration.
-	 */
-	struct rw_semaphore	cl_sem;
-
-	struct list_head	cl_delegations;
-	struct list_head	cl_state_owners;
-	struct list_head	cl_unused;
-	int			cl_nunused;
-	spinlock_t		cl_lock;
-	atomic_t		cl_count;
-
-	struct rpc_clnt *	cl_rpcclient;
-	struct rpc_cred *	cl_cred;
-
-	struct list_head	cl_superblocks;	/* List of nfs_server structs */
-
-	unsigned long		cl_lease_time;
-	unsigned long		cl_last_renewal;
-	struct work_struct	cl_renewd;
-	struct work_struct	cl_recoverd;
-
-	wait_queue_head_t	cl_waitq;
-	struct rpc_wait_queue	cl_rpcwaitq;
-
-	/* used for the setclientid verifier */
-	struct timespec		cl_boot_time;
-
-	/* idmapper */
-	struct idmap *		cl_idmap;
-
-	/* Our own IP address, as a null-terminated string.
-	 * This is used to generate the clientid, and the callback address.
-	 */
-	char			cl_ipaddr[16];
-	unsigned char		cl_id_uniquifier;
-};
-
-/*
- * NFS4 state_owners and lock_owners are simply labels for ordered
- * sequences of RPC calls. Their sole purpose is to provide once-only
- * semantics by allowing the server to identify replayed requests.
- *
- * The ->so_sema is held during all state_owner seqid-mutating operations:
- * OPEN, OPEN_DOWNGRADE, and CLOSE. Its purpose is to properly serialize
- * so_seqid.
- */
-struct nfs4_state_owner {
-	struct list_head     so_list;	 /* per-clientid list of state_owners */
-	struct nfs4_client   *so_client;
-	u32                  so_id;      /* 32-bit identifier, unique */
-	struct semaphore     so_sema;
-	u32                  so_seqid;   /* protected by so_sema */
-	atomic_t	     so_count;
-
-	struct rpc_cred	     *so_cred;	 /* Associated cred */
-	struct list_head     so_states;
-	struct list_head     so_delegations;
-};
-
-/*
- * struct nfs4_state maintains the client-side state for a given
- * (state_owner,inode) tuple (OPEN) or state_owner (LOCK).
- *
- * OPEN:
- * In order to know when to OPEN_DOWNGRADE or CLOSE the state on the server,
- * we need to know how many files are open for reading or writing on a
- * given inode. This information too is stored here.
- *
- * LOCK: one nfs4_state (LOCK) to hold the lock stateid nfs4_state(OPEN)
- */
-
-struct nfs4_lock_state {
-	struct list_head	ls_locks;	/* Other lock stateids */
-	fl_owner_t		ls_owner;	/* POSIX lock owner */
-#define NFS_LOCK_INITIALIZED 1
-	int			ls_flags;
-	u32			ls_seqid;
-	u32			ls_id;
-	nfs4_stateid		ls_stateid;
-	atomic_t		ls_count;
-};
-
-/* bits for nfs4_state->flags */
-enum {
-	LK_STATE_IN_USE,
-	NFS_DELEGATED_STATE,
-};
-
-struct nfs4_state {
-	struct list_head open_states;	/* List of states for the same state_owner */
-	struct list_head inode_states;	/* List of states for the same inode */
-	struct list_head lock_states;	/* List of subservient lock stateids */
-
-	struct nfs4_state_owner *owner;	/* Pointer to the open owner */
-	struct inode *inode;		/* Pointer to the inode */
-
-	unsigned long flags;		/* Do we hold any locks? */
-	struct semaphore lock_sema;	/* Serializes file locking operations */
-	rwlock_t state_lock;		/* Protects the lock_states list */
-
-	nfs4_stateid stateid;
-
-	unsigned int nreaders;
-	unsigned int nwriters;
-	int state;			/* State on the server (R,W, or RW) */
-	atomic_t count;
-};
-
-
-struct nfs4_exception {
-	long timeout;
-	int retry;
-};
-
-struct nfs4_state_recovery_ops {
-	int (*recover_open)(struct nfs4_state_owner *, struct nfs4_state *);
-	int (*recover_lock)(struct nfs4_state *, struct file_lock *);
-};
-
-extern struct dentry_operations nfs4_dentry_operations;
-extern struct inode_operations nfs4_dir_inode_operations;
-
-/* nfs4proc.c */
-extern int nfs4_map_errors(int err);
-extern int nfs4_proc_setclientid(struct nfs4_client *, u32, unsigned short);
-extern int nfs4_proc_setclientid_confirm(struct nfs4_client *);
-extern int nfs4_proc_async_renew(struct nfs4_client *);
-extern int nfs4_proc_renew(struct nfs4_client *);
-extern int nfs4_do_close(struct inode *inode, struct nfs4_state *state, mode_t mode);
-extern struct inode *nfs4_atomic_open(struct inode *, struct dentry *, struct nameidata *);
-extern int nfs4_open_revalidate(struct inode *, struct dentry *, int);
-
-extern struct nfs4_state_recovery_ops nfs4_reboot_recovery_ops;
-extern struct nfs4_state_recovery_ops nfs4_network_partition_recovery_ops;
-
-/* nfs4renewd.c */
-extern void nfs4_schedule_state_renewal(struct nfs4_client *);
-extern void nfs4_renewd_prepare_shutdown(struct nfs_server *);
-extern void nfs4_kill_renewd(struct nfs4_client *);
-
-/* nfs4state.c */
-extern void init_nfsv4_state(struct nfs_server *);
-extern void destroy_nfsv4_state(struct nfs_server *);
-extern struct nfs4_client *nfs4_get_client(struct in_addr *);
-extern void nfs4_put_client(struct nfs4_client *clp);
-extern int nfs4_init_client(struct nfs4_client *clp);
-extern struct nfs4_client *nfs4_find_client(struct in_addr *);
-extern u32 nfs4_alloc_lockowner_id(struct nfs4_client *);
-
-extern struct nfs4_state_owner * nfs4_get_state_owner(struct nfs_server *, struct rpc_cred *);
-extern void nfs4_put_state_owner(struct nfs4_state_owner *);
-extern void nfs4_drop_state_owner(struct nfs4_state_owner *);
-extern struct nfs4_state * nfs4_get_open_state(struct inode *, struct nfs4_state_owner *);
-extern void nfs4_put_open_state(struct nfs4_state *);
-extern void nfs4_close_state(struct nfs4_state *, mode_t);
-extern struct nfs4_state *nfs4_find_state(struct inode *, struct rpc_cred *, mode_t mode);
-extern void nfs4_increment_seqid(int status, struct nfs4_state_owner *sp);
-extern void nfs4_schedule_state_recovery(struct nfs4_client *);
-extern struct nfs4_lock_state *nfs4_find_lock_state(struct nfs4_state *state, fl_owner_t);
-extern struct nfs4_lock_state *nfs4_get_lock_state(struct nfs4_state *state, fl_owner_t);
-extern void nfs4_put_lock_state(struct nfs4_lock_state *state);
-extern void nfs4_increment_lock_seqid(int status, struct nfs4_lock_state *ls);
-extern void nfs4_notify_setlk(struct nfs4_state *, struct file_lock *, struct nfs4_lock_state *);
-extern void nfs4_notify_unlck(struct nfs4_state *, struct file_lock *, struct nfs4_lock_state *);
-extern void nfs4_copy_stateid(nfs4_stateid *, struct nfs4_state *, fl_owner_t);
-
-
-
-struct nfs4_mount_data;
-#else
-#define init_nfsv4_state(server)  do { } while (0)
-#define destroy_nfsv4_state(server)       do { } while (0)
-#define nfs4_put_state_owner(inode, owner) do { } while (0)
-#define nfs4_put_open_state(state) do { } while (0)
-#define nfs4_close_state(a, b) do { } while (0)
-#define nfs4_renewd_prepare_shutdown(server) do { } while (0)
-#endif
-
 #endif /* __KERNEL__ */
 
 /*
diff --git a/include/linux/nfs_fs_i.h b/include/linux/nfs_fs_i.h
--- a/include/linux/nfs_fs_i.h
+++ b/include/linux/nfs_fs_i.h
@@ -16,6 +16,11 @@ struct nfs_lock_info {
 	struct nlm_lockowner *owner;
 };
 
+struct nfs4_lock_state;
+struct nfs4_lock_info {
+	struct nfs4_lock_state *owner;
+};
+
 /*
  * Lock flag values
  */
diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
--- a/include/linux/nfs_fs_sb.h
+++ b/include/linux/nfs_fs_sb.h
@@ -10,6 +10,7 @@
 struct nfs_server {
 	struct rpc_clnt *	client;		/* RPC client handle */
 	struct rpc_clnt *	client_sys;	/* 2nd handle for FSINFO */
+	struct rpc_clnt *	client_acl;	/* ACL RPC client handle */
 	struct nfs_rpc_ops *	rpc_ops;	/* NFS protocol vector */
 	struct backing_dev_info	backing_dev_info;
 	int			flags;		/* various flags */
diff --git a/include/linux/nfs_mount.h b/include/linux/nfs_mount.h
--- a/include/linux/nfs_mount.h
+++ b/include/linux/nfs_mount.h
@@ -58,6 +58,7 @@ struct nfs_mount_data {
 #define NFS_MOUNT_KERBEROS	0x0100	/* 3 */
 #define NFS_MOUNT_NONLM		0x0200	/* 3 */
 #define NFS_MOUNT_BROKEN_SUID	0x0400	/* 4 */
+#define NFS_MOUNT_NOACL		0x0800	/* 4 */
 #define NFS_MOUNT_STRICTLOCK	0x1000	/* reserved for NFSv4 */
 #define NFS_MOUNT_SECFLAVOUR	0x2000	/* 5 */
 #define NFS_MOUNT_FLAGMASK	0xFFFF
diff --git a/include/linux/nfs_page.h b/include/linux/nfs_page.h
--- a/include/linux/nfs_page.h
+++ b/include/linux/nfs_page.h
@@ -20,12 +20,19 @@
 #include <asm/atomic.h>
 
 /*
+ * Valid flags for the radix tree
+ */
+#define NFS_PAGE_TAG_DIRTY	0
+#define NFS_PAGE_TAG_WRITEBACK	1
+
+/*
  * Valid flags for a dirty buffer
  */
 #define PG_BUSY			0
 #define PG_NEED_COMMIT		1
 #define PG_NEED_RESCHED		2
 
+struct nfs_inode;
 struct nfs_page {
 	struct list_head	wb_list,	/* Defines state of page: */
 				*wb_list_head;	/*      read/write/commit */
@@ -54,14 +61,17 @@ extern	void nfs_clear_request(struct nfs
 extern	void nfs_release_request(struct nfs_page *req);
 
 
-extern	void nfs_list_add_request(struct nfs_page *, struct list_head *);
-
+extern  int nfs_scan_lock_dirty(struct nfs_inode *nfsi, struct list_head *dst,
+				unsigned long idx_start, unsigned int npages);
 extern	int nfs_scan_list(struct list_head *, struct list_head *,
 			  unsigned long, unsigned int);
 extern	int nfs_coalesce_requests(struct list_head *, struct list_head *,
 				  unsigned int);
 extern  int nfs_wait_on_request(struct nfs_page *);
 extern	void nfs_unlock_request(struct nfs_page *req);
+extern  int nfs_set_page_writeback_locked(struct nfs_page *req);
+extern  void nfs_clear_page_writeback(struct nfs_page *req);
+
 
 /*
  * Lock the page of an asynchronous request without incrementing the wb_count
@@ -86,6 +96,18 @@ nfs_lock_request(struct nfs_page *req)
 	return 1;
 }
 
+/**
+ * nfs_list_add_request - Insert a request into a list
+ * @req: request
+ * @head: head of list into which to insert the request.
+ */
+static inline void
+nfs_list_add_request(struct nfs_page *req, struct list_head *head)
+{
+	list_add_tail(&req->wb_list, head);
+	req->wb_list_head = head;
+}
+
 
 /**
  * nfs_list_remove_request - Remove a request from its wb_list
@@ -96,10 +118,6 @@ nfs_list_remove_request(struct nfs_page 
 {
 	if (list_empty(&req->wb_list))
 		return;
-	if (!NFS_WBACK_BUSY(req)) {
-		printk(KERN_ERR "NFS: unlocked request attempted removed from list!\n");
-		BUG();
-	}
 	list_del_init(&req->wb_list);
 	req->wb_list_head = NULL;
 }
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -2,6 +2,7 @@
 #define _LINUX_NFS_XDR_H
 
 #include <linux/sunrpc/xprt.h>
+#include <linux/nfsacl.h>
 
 struct nfs4_fsid {
 	__u64 major;
@@ -326,6 +327,20 @@ struct nfs_setattrargs {
 	const u32 *			bitmask;
 };
 
+struct nfs_setaclargs {
+	struct nfs_fh *			fh;
+	size_t				acl_len;
+	unsigned int			acl_pgbase;
+	struct page **			acl_pages;
+};
+
+struct nfs_getaclargs {
+	struct nfs_fh *			fh;
+	size_t				acl_len;
+	unsigned int			acl_pgbase;
+	struct page **			acl_pages;
+};
+
 struct nfs_setattrres {
 	struct nfs_fattr *              fattr;
 	const struct nfs_server *	server;
@@ -354,6 +369,20 @@ struct nfs_readdirargs {
 	struct page **		pages;
 };
 
+struct nfs3_getaclargs {
+	struct nfs_fh *		fh;
+	int			mask;
+	struct page **		pages;
+};
+
+struct nfs3_setaclargs {
+	struct inode *		inode;
+	int			mask;
+	struct posix_acl *	acl_access;
+	struct posix_acl *	acl_default;
+	struct page **		pages;
+};
+
 struct nfs_diropok {
 	struct nfs_fh *		fh;
 	struct nfs_fattr *	fattr;
@@ -477,6 +506,15 @@ struct nfs3_readdirres {
 	int			plus;
 };
 
+struct nfs3_getaclres {
+	struct nfs_fattr *	fattr;
+	int			mask;
+	unsigned int		acl_access_count;
+	unsigned int		acl_default_count;
+	struct posix_acl *	acl_access;
+	struct posix_acl *	acl_default;
+};
+
 #ifdef CONFIG_NFS_V4
 
 typedef u64 clientid4;
@@ -667,6 +705,7 @@ struct nfs_rpc_ops {
 	int	version;		/* Protocol version */
 	struct dentry_operations *dentry_ops;
 	struct inode_operations *dir_inode_ops;
+	struct inode_operations *file_inode_ops;
 
 	int	(*getroot) (struct nfs_server *, struct nfs_fh *,
 			    struct nfs_fsinfo *);
@@ -713,6 +752,7 @@ struct nfs_rpc_ops {
 	int	(*file_open)   (struct inode *, struct file *);
 	int	(*file_release) (struct inode *, struct file *);
 	int	(*lock)(struct file *, int, struct file_lock *);
+	void	(*clear_acl_cache)(struct inode *);
 };
 
 /*
@@ -732,4 +772,7 @@ extern struct rpc_version	nfs_version2;
 extern struct rpc_version	nfs_version3;
 extern struct rpc_version	nfs_version4;
 
+extern struct rpc_version	nfsacl_version3;
+extern struct rpc_program	nfsacl_program;
+
 #endif
diff --git a/include/linux/nfsacl.h b/include/linux/nfsacl.h
new file mode 100644
--- /dev/null
+++ b/include/linux/nfsacl.h
@@ -0,0 +1,58 @@
+/*
+ * File: linux/nfsacl.h
+ *
+ * (C) 2003 Andreas Gruenbacher <agruen@suse.de>
+ */
+#ifndef __LINUX_NFSACL_H
+#define __LINUX_NFSACL_H
+
+#define NFS_ACL_PROGRAM	100227
+
+#define ACLPROC2_GETACL		1
+#define ACLPROC2_SETACL		2
+#define ACLPROC2_GETATTR	3
+#define ACLPROC2_ACCESS		4
+
+#define ACLPROC3_GETACL		1
+#define ACLPROC3_SETACL		2
+
+
+/* Flags for the getacl/setacl mode */
+#define NFS_ACL			0x0001
+#define NFS_ACLCNT		0x0002
+#define NFS_DFACL		0x0004
+#define NFS_DFACLCNT		0x0008
+
+/* Flag for Default ACL entries */
+#define NFS_ACL_DEFAULT		0x1000
+
+#ifdef __KERNEL__
+
+#include <linux/posix_acl.h>
+
+/* Maximum number of ACL entries over NFS */
+#define NFS_ACL_MAX_ENTRIES	1024
+
+#define NFSACL_MAXWORDS		(2*(2+3*NFS_ACL_MAX_ENTRIES))
+#define NFSACL_MAXPAGES		((2*(8+12*NFS_ACL_MAX_ENTRIES) + PAGE_SIZE-1) \
+				 >> PAGE_SHIFT)
+
+static inline unsigned int
+nfsacl_size(struct posix_acl *acl_access, struct posix_acl *acl_default)
+{
+	unsigned int w = 16;
+	w += max(acl_access ? (int)acl_access->a_count : 3, 4) * 12;
+	if (acl_default)
+		w += max((int)acl_default->a_count, 4) * 12;
+	return w;
+}
+
+extern unsigned int
+nfsacl_encode(struct xdr_buf *buf, unsigned int base, struct inode *inode,
+	      struct posix_acl *acl, int encode_entries, int typeflag);
+extern unsigned int
+nfsacl_decode(struct xdr_buf *buf, unsigned int base, unsigned int *aclcnt,
+	      struct posix_acl **pacl);
+
+#endif /* __KERNEL__ */
+#endif  /* __LINUX_NFSACL_H */
diff --git a/include/linux/nfsd/nfsd.h b/include/linux/nfsd/nfsd.h
--- a/include/linux/nfsd/nfsd.h
+++ b/include/linux/nfsd/nfsd.h
@@ -15,6 +15,7 @@
 #include <linux/unistd.h>
 #include <linux/dirent.h>
 #include <linux/fs.h>
+#include <linux/posix_acl.h>
 #include <linux/mount.h>
 
 #include <linux/nfsd/debug.h>
@@ -123,21 +124,41 @@ int		nfsd_statfs(struct svc_rqst *, stru
 
 int		nfsd_notify_change(struct inode *, struct iattr *);
 int		nfsd_permission(struct svc_export *, struct dentry *, int);
+void		nfsd_sync_dir(struct dentry *dp);
+
+#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
+#ifdef CONFIG_NFSD_V2_ACL
+extern struct svc_version nfsd_acl_version2;
+#else
+#define nfsd_acl_version2 NULL
+#endif
+#ifdef CONFIG_NFSD_V3_ACL
+extern struct svc_version nfsd_acl_version3;
+#else
+#define nfsd_acl_version3 NULL
+#endif
+struct posix_acl *nfsd_get_posix_acl(struct svc_fh *, int);
+int nfsd_set_posix_acl(struct svc_fh *, int, struct posix_acl *);
+#endif
 
 
 /* 
  * NFSv4 State
  */
 #ifdef CONFIG_NFSD_V4
-int nfs4_state_init(void);
+void nfs4_state_init(void);
+int nfs4_state_start(void);
 void nfs4_state_shutdown(void);
 time_t nfs4_lease_time(void);
 void nfs4_reset_lease(time_t leasetime);
+int nfs4_reset_recoverydir(char *recdir);
 #else
-static inline int nfs4_state_init(void){return 0;}
+static inline void nfs4_state_init(void){};
+static inline int nfs4_state_start(void){return 0;}
 static inline void nfs4_state_shutdown(void){}
 static inline time_t nfs4_lease_time(void){return 0;}
 static inline void nfs4_reset_lease(time_t leasetime){}
+static inline int nfs4_reset_recoverydir(char *recdir) {return 0;}
 #endif
 
 /*
@@ -210,6 +231,7 @@ void		nfsd_lockd_shutdown(void);
 #define	nfserr_reclaim_bad	__constant_htonl(NFSERR_RECLAIM_BAD)
 #define	nfserr_badname		__constant_htonl(NFSERR_BADNAME)
 #define	nfserr_cb_path_down	__constant_htonl(NFSERR_CB_PATH_DOWN)
+#define	nfserr_locked		__constant_htonl(NFSERR_LOCKED)
 
 /* error codes for internal use */
 /* if a request fails due to kmalloc failure, it gets dropped.
diff --git a/include/linux/nfsd/state.h b/include/linux/nfsd/state.h
--- a/include/linux/nfsd/state.h
+++ b/include/linux/nfsd/state.h
@@ -61,11 +61,6 @@ typedef struct {
 #define si_stateownerid   si_opaque.so_stateownerid
 #define si_fileid         si_opaque.so_fileid
 
-extern stateid_t zerostateid;
-extern stateid_t onestateid;
-
-#define ZERO_STATEID(stateid)       (!memcmp((stateid), &zerostateid, sizeof(stateid_t)))
-#define ONE_STATEID(stateid)        (!memcmp((stateid), &onestateid, sizeof(stateid_t)))
 
 struct nfs4_cb_recall {
 	u32			cbr_ident;
@@ -77,8 +72,8 @@ struct nfs4_cb_recall {
 };
 
 struct nfs4_delegation {
-	struct list_head	dl_del_perfile; /* nfs4_file->fi_del_perfile */
-	struct list_head	dl_del_perclnt; /* nfs4_client->cl_del_perclnt*/
+	struct list_head	dl_perfile;
+	struct list_head	dl_perclnt;
 	struct list_head	dl_recall_lru;  /* delegation recalled */
 	atomic_t		dl_count;       /* ref count */
 	struct nfs4_client	*dl_client;
@@ -97,7 +92,6 @@ struct nfs4_delegation {
 /* client delegation callback info */
 struct nfs4_callback {
 	/* SETCLIENTID info */
-	u32			cb_parsed;  /* addr parsed */
 	u32                     cb_addr;
 	unsigned short          cb_port;
 	u32                     cb_prog;
@@ -109,6 +103,8 @@ struct nfs4_callback {
 	struct rpc_clnt *       cb_client;
 };
 
+#define HEXDIR_LEN     33 /* hex version of 16 byte md5 of cl_name plus '\0' */
+
 /*
  * struct nfs4_client - one per client.  Clientids live here.
  * 	o Each nfs4_client is hashed by clientid.
@@ -122,10 +118,11 @@ struct nfs4_callback {
 struct nfs4_client {
 	struct list_head	cl_idhash; 	/* hash by cl_clientid.id */
 	struct list_head	cl_strhash; 	/* hash by cl_name */
-	struct list_head	cl_perclient; 	/* list: stateowners */
-	struct list_head	cl_del_perclnt; /* list: delegations */
+	struct list_head	cl_openowners;
+	struct list_head	cl_delegations;
 	struct list_head        cl_lru;         /* tail queue */
 	struct xdr_netobj	cl_name; 	/* id generated by client */
+	char                    cl_recdir[HEXDIR_LEN]; /* recovery dir */
 	nfs4_verifier		cl_verifier; 	/* generated by client */
 	time_t                  cl_time;        /* time of last lease renewal */
 	u32			cl_addr; 	/* client ipaddress */
@@ -134,6 +131,7 @@ struct nfs4_client {
 	nfs4_verifier		cl_confirm;	/* generated by server */
 	struct nfs4_callback	cl_callback;    /* callback info */
 	atomic_t		cl_count;	/* ref count */
+	u32			cl_firststate;	/* recovery dir creation */
 };
 
 /* struct nfs4_client_reset
@@ -143,7 +141,7 @@ struct nfs4_client {
  */
 struct nfs4_client_reclaim {
 	struct list_head	cr_strhash;	/* hash by cr_name */
-	struct xdr_netobj 	cr_name; 	/* id generated by client */
+	char			cr_recdir[HEXDIR_LEN]; /* recover dir */
 };
 
 static inline void
@@ -197,15 +195,17 @@ struct nfs4_stateowner {
 	struct kref		so_ref;
 	struct list_head        so_idhash;   /* hash by so_id */
 	struct list_head        so_strhash;   /* hash by op_name */
-	struct list_head        so_perclient; /* nfs4_client->cl_perclient */
-	struct list_head        so_perfilestate; /* list: nfs4_stateid */
-	struct list_head        so_perlockowner; /* nfs4_stateid->st_perlockowner */
+	struct list_head        so_perclient;
+	struct list_head        so_stateids;
+	struct list_head        so_perstateid; /* for lockowners only */
 	struct list_head	so_close_lru; /* tail queue */
 	time_t			so_time; /* time of placement on so_close_lru */
 	int			so_is_open_owner; /* 1=openowner,0=lockowner */
 	u32                     so_id;
 	struct nfs4_client *    so_client;
-	u32                     so_seqid;    
+	/* after increment in ENCODE_SEQID_OP_TAIL, represents the next
+	 * sequence id expected from the client: */
+	u32                     so_seqid;
 	struct xdr_netobj       so_owner;     /* open owner name */
 	int                     so_confirmed; /* successful OPEN_CONFIRM? */
 	struct nfs4_replay	so_replay;
@@ -217,9 +217,10 @@ struct nfs4_stateowner {
 *      share_acces, share_deny on the file.
 */
 struct nfs4_file {
+	struct kref		fi_ref;
 	struct list_head        fi_hash;    /* hash by "struct inode *" */
-	struct list_head        fi_perfile; /* list: nfs4_stateid */
-	struct list_head	fi_del_perfile; /* list: nfs4_delegation */
+	struct list_head        fi_stateids;
+	struct list_head	fi_delegations;
 	struct inode		*fi_inode;
 	u32                     fi_id;      /* used with stateowner->so_id 
 					     * for stateid_hashtbl hash */
@@ -236,19 +237,24 @@ struct nfs4_file {
 *       st_perlockowner: (open stateid) list of lock nfs4_stateowners
 * 	st_access_bmap: used only for open stateid
 * 	st_deny_bmap: used only for open stateid
+*	st_openstp: open stateid lock stateid was derived from
+*
+* XXX: open stateids and lock stateids have diverged sufficiently that
+* we should consider defining separate structs for the two cases.
 */
 
 struct nfs4_stateid {
 	struct list_head              st_hash; 
 	struct list_head              st_perfile;
-	struct list_head              st_perfilestate; 
-	struct list_head              st_perlockowner;
+	struct list_head              st_perstateowner;
+	struct list_head              st_lockowners;
 	struct nfs4_stateowner      * st_stateowner;
 	struct nfs4_file            * st_file;
 	stateid_t                     st_stateid;
 	struct file                 * st_vfs_file;
 	unsigned long                 st_access_bmap;
 	unsigned long                 st_deny_bmap;
+	struct nfs4_stateid         * st_openstp;
 };
 
 /* flags for preprocess_seqid_op() */
@@ -267,12 +273,9 @@ struct nfs4_stateid {
 	((err) != nfserr_stale_stateid) &&      \
 	((err) != nfserr_bad_stateid))
 
-extern time_t nfs4_laundromat(void);
 extern int nfsd4_renew(clientid_t *clid);
 extern int nfs4_preprocess_stateid_op(struct svc_fh *current_fh, 
 		stateid_t *stateid, int flags, struct file **filp);
-extern int nfs4_share_conflict(struct svc_fh *current_fh, 
-		unsigned int deny_type);
 extern void nfs4_lock_state(void);
 extern void nfs4_unlock_state(void);
 extern int nfs4_in_grace(void);
@@ -282,6 +285,15 @@ extern void nfs4_free_stateowner(struct 
 extern void nfsd4_probe_callback(struct nfs4_client *clp);
 extern void nfsd4_cb_recall(struct nfs4_delegation *dp);
 extern void nfs4_put_delegation(struct nfs4_delegation *dp);
+extern int nfs4_make_rec_clidname(char *clidname, struct xdr_netobj *clname);
+extern void nfsd4_init_recdir(char *recdir_name);
+extern int nfsd4_recdir_load(void);
+extern void nfsd4_shutdown_recdir(void);
+extern int nfs4_client_to_reclaim(const char *name);
+extern int nfs4_has_reclaimed_state(const char *name);
+extern void nfsd4_recdir_purge_old(void);
+extern int nfsd4_create_clid_dir(struct nfs4_client *clp);
+extern void nfsd4_remove_clid_dir(struct nfs4_client *clp);
 
 static inline void
 nfs4_put_stateowner(struct nfs4_stateowner *so)
diff --git a/include/linux/nfsd/xdr.h b/include/linux/nfsd/xdr.h
--- a/include/linux/nfsd/xdr.h
+++ b/include/linux/nfsd/xdr.h
@@ -169,4 +169,8 @@ int nfssvc_encode_entry(struct readdir_c
 
 int nfssvc_release_fhandle(struct svc_rqst *, u32 *, struct nfsd_fhandle *);
 
+/* Helper functions for NFSv2 ACL code */
+u32 *nfs2svc_encode_fattr(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp);
+u32 *nfs2svc_decode_fh(u32 *p, struct svc_fh *fhp);
+
 #endif /* LINUX_NFSD_H */
diff --git a/include/linux/nfsd/xdr3.h b/include/linux/nfsd/xdr3.h
--- a/include/linux/nfsd/xdr3.h
+++ b/include/linux/nfsd/xdr3.h
@@ -110,6 +110,19 @@ struct nfsd3_commitargs {
 	__u32			count;
 };
 
+struct nfsd3_getaclargs {
+	struct svc_fh		fh;
+	int			mask;
+};
+
+struct posix_acl;
+struct nfsd3_setaclargs {
+	struct svc_fh		fh;
+	int			mask;
+	struct posix_acl	*acl_access;
+	struct posix_acl	*acl_default;
+};
+
 struct nfsd3_attrstat {
 	__u32			status;
 	struct svc_fh		fh;
@@ -209,6 +222,14 @@ struct nfsd3_commitres {
 	struct svc_fh		fh;
 };
 
+struct nfsd3_getaclres {
+	__u32			status;
+	struct svc_fh		fh;
+	int			mask;
+	struct posix_acl	*acl_access;
+	struct posix_acl	*acl_default;
+};
+
 /* dummy type for release */
 struct nfsd3_fhandle_pair {
 	__u32			dummy;
@@ -241,6 +262,7 @@ union nfsd3_xdrstore {
 	struct nfsd3_fsinfores		fsinfores;
 	struct nfsd3_pathconfres	pathconfres;
 	struct nfsd3_commitres		commitres;
+	struct nfsd3_getaclres		getaclres;
 };
 
 #define NFS3_SVC_XDRSIZE		sizeof(union nfsd3_xdrstore)
@@ -316,6 +338,10 @@ int nfs3svc_encode_entry(struct readdir_
 int nfs3svc_encode_entry_plus(struct readdir_cd *, const char *name,
 				int namlen, loff_t offset, ino_t ino,
 				unsigned int);
+/* Helper functions for NFSv3 ACL code */
+u32 *nfs3svc_encode_post_op_attr(struct svc_rqst *rqstp, u32 *p,
+				struct svc_fh *fhp);
+u32 *nfs3svc_decode_fh(u32 *p, struct svc_fh *fhp);
 
 
 #endif /* _LINUX_NFSD_XDR3_H */
diff --git a/include/linux/nfsd/xdr4.h b/include/linux/nfsd/xdr4.h
--- a/include/linux/nfsd/xdr4.h
+++ b/include/linux/nfsd/xdr4.h
@@ -210,6 +210,7 @@ struct nfsd4_open {
 	u32		op_share_access;    /* request */
 	u32		op_share_deny;      /* request */
 	stateid_t	op_stateid;         /* response */
+	u32		op_recall;          /* recall */
 	struct nfsd4_change_info  op_cinfo; /* response */
 	u32		op_rflags;          /* response */
 	int		op_truncate;        /* used during processing */
diff --git a/include/linux/nfsd_idmap.h b/include/linux/nfsd_idmap.h
--- a/include/linux/nfsd_idmap.h
+++ b/include/linux/nfsd_idmap.h
@@ -43,8 +43,13 @@
 /* XXX from linux/nfs_idmap.h */
 #define IDMAP_NAMESZ 128
 
+#ifdef CONFIG_NFSD_V4
 void nfsd_idmap_init(void);
 void nfsd_idmap_shutdown(void);
+#else
+static inline void nfsd_idmap_init(void) {};
+static inline void nfsd_idmap_shutdown(void) {};
+#endif
 
 int nfsd_map_name_to_uid(struct svc_rqst *, const char *, size_t, __u32 *);
 int nfsd_map_name_to_gid(struct svc_rqst *, const char *, size_t, __u32 *);
diff --git a/include/linux/node.h b/include/linux/node.h
--- a/include/linux/node.h
+++ b/include/linux/node.h
@@ -27,6 +27,7 @@ struct node {
 };
 
 extern int register_node(struct node *, int, struct node *);
+extern void unregister_node(struct node *node);
 
 #define to_node(sys_device) container_of(sys_device, struct node, sysdev)
 
diff --git a/include/linux/numa.h b/include/linux/numa.h
--- a/include/linux/numa.h
+++ b/include/linux/numa.h
@@ -3,7 +3,7 @@
 
 #include <linux/config.h>
 
-#ifdef CONFIG_DISCONTIGMEM
+#ifndef CONFIG_FLATMEM
 #include <asm/numnodes.h>
 #endif
 
diff --git a/include/linux/nvram.h b/include/linux/nvram.h
--- a/include/linux/nvram.h
+++ b/include/linux/nvram.h
@@ -20,8 +20,6 @@ extern void __nvram_write_byte(unsigned 
 extern void nvram_write_byte(unsigned char c, int i);
 extern int __nvram_check_checksum(void);
 extern int nvram_check_checksum(void);
-extern void __nvram_set_checksum(void);
-extern void nvram_set_checksum(void);
 #endif
 
 #endif  /* _LINUX_NVRAM_H */
diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h
--- a/include/linux/page-flags.h
+++ b/include/linux/page-flags.h
@@ -61,21 +61,20 @@
 #define PG_active		 6
 #define PG_slab			 7	/* slab debug (Suparna wants this) */
 
-#define PG_highmem		 8
-#define PG_checked		 9	/* kill me in 2.5.<early>. */
-#define PG_arch_1		10
-#define PG_reserved		11
-
-#define PG_private		12	/* Has something at ->private */
-#define PG_writeback		13	/* Page is under writeback */
-#define PG_nosave		14	/* Used for system suspend/resume */
-#define PG_compound		15	/* Part of a compound page */
-
-#define PG_swapcache		16	/* Swap page: swp_entry_t in private */
-#define PG_mappedtodisk		17	/* Has blocks allocated on-disk */
-#define PG_reclaim		18	/* To be reclaimed asap */
-#define PG_nosave_free		19	/* Free, should not be written */
-#define PG_uncached		20	/* Page has been mapped as uncached */
+#define PG_checked		 8	/* kill me in 2.5.<early>. */
+#define PG_arch_1		 9
+#define PG_reserved		10
+#define PG_private		11	/* Has something at ->private */
+
+#define PG_writeback		12	/* Page is under writeback */
+#define PG_nosave		13	/* Used for system suspend/resume */
+#define PG_compound		14	/* Part of a compound page */
+#define PG_swapcache		15	/* Swap page: swp_entry_t in private */
+
+#define PG_mappedtodisk		16	/* Has blocks allocated on-disk */
+#define PG_reclaim		17	/* To be reclaimed asap */
+#define PG_nosave_free		18	/* Free, should not be written */
+#define PG_uncached		19	/* Page has been mapped as uncached */
 
 /*
  * Global page accounting.  One instance per CPU.  Only unsigned longs are
@@ -136,8 +135,8 @@ struct page_state {
 
 extern void get_page_state(struct page_state *ret);
 extern void get_full_page_state(struct page_state *ret);
-extern unsigned long __read_page_state(unsigned offset);
-extern void __mod_page_state(unsigned offset, unsigned long delta);
+extern unsigned long __read_page_state(unsigned long offset);
+extern void __mod_page_state(unsigned long offset, unsigned long delta);
 
 #define read_page_state(member) \
 	__read_page_state(offsetof(struct page_state, member))
@@ -215,7 +214,7 @@ extern void __mod_page_state(unsigned of
 #define TestSetPageSlab(page)	test_and_set_bit(PG_slab, &(page)->flags)
 
 #ifdef CONFIG_HIGHMEM
-#define PageHighMem(page)	test_bit(PG_highmem, &(page)->flags)
+#define PageHighMem(page)	is_highmem(page_zone(page))
 #else
 #define PageHighMem(page)	0 /* needed to optimize away at compile time */
 #endif
diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
--- a/include/linux/pagemap.h
+++ b/include/linux/pagemap.h
@@ -52,12 +52,12 @@ void release_pages(struct page **pages, 
 
 static inline struct page *page_cache_alloc(struct address_space *x)
 {
-	return alloc_pages(mapping_gfp_mask(x), 0);
+	return alloc_pages(mapping_gfp_mask(x)|__GFP_NORECLAIM, 0);
 }
 
 static inline struct page *page_cache_alloc_cold(struct address_space *x)
 {
-	return alloc_pages(mapping_gfp_mask(x)|__GFP_COLD, 0);
+	return alloc_pages(mapping_gfp_mask(x)|__GFP_COLD|__GFP_NORECLAIM, 0);
 }
 
 typedef int filler_t(void *, struct page *);
diff --git a/include/linux/pci-dynids.h b/include/linux/pci-dynids.h
deleted file mode 100644
--- a/include/linux/pci-dynids.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- *	PCI defines and function prototypes
- *	Copyright 2003 Dell Inc.
- *        by Matt Domsch <Matt_Domsch@dell.com>
- */
-
-#ifndef LINUX_PCI_DYNIDS_H
-#define LINUX_PCI_DYNIDS_H
-
-#include <linux/list.h>
-#include <linux/mod_devicetable.h>
-
-struct dynid {
-	struct list_head        node;
-	struct pci_device_id    id;
-};
-
-#endif
diff --git a/include/linux/pci.h b/include/linux/pci.h
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -556,7 +556,8 @@ struct pci_dev {
 	/* keep track of device state */
 	unsigned int	is_enabled:1;	/* pci_enable_device has been called */
 	unsigned int	is_busmaster:1; /* device is busmaster */
-	
+	unsigned int	no_msi:1;	/* device may not use msi */
+
 	u32		saved_config_space[16]; /* config space saved at suspend time */
 	struct bin_attribute *rom_attr; /* attribute descriptor for sysfs ROM entry */
 	int rom_attr_enabled;		/* has display of the rom attribute been enabled? */
@@ -586,7 +587,7 @@ struct pci_dev {
 #define PCI_NUM_RESOURCES 11
 
 #ifndef PCI_BUS_NUM_RESOURCES
-#define PCI_BUS_NUM_RESOURCES 4
+#define PCI_BUS_NUM_RESOURCES 8
 #endif
   
 #define PCI_REGION_FLAG_MASK 0x0fU	/* These bits of resource flags tell us the PCI region flags */
@@ -734,16 +735,20 @@ void pcibios_update_irq(struct pci_dev *
 /* Generic PCI functions used internally */
 
 extern struct pci_bus *pci_find_bus(int domain, int busnr);
+void pci_bus_add_devices(struct pci_bus *bus);
 struct pci_bus *pci_scan_bus_parented(struct device *parent, int bus, struct pci_ops *ops, void *sysdata);
 static inline struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops, void *sysdata)
 {
-	return pci_scan_bus_parented(NULL, bus, ops, sysdata);
+	struct pci_bus *root_bus;
+	root_bus = pci_scan_bus_parented(NULL, bus, ops, sysdata);
+	if (root_bus)
+		pci_bus_add_devices(root_bus);
+	return root_bus;
 }
 int pci_scan_slot(struct pci_bus *bus, int devfn);
 struct pci_dev * pci_scan_single_device(struct pci_bus *bus, int devfn);
 unsigned int pci_scan_child_bus(struct pci_bus *bus);
 void pci_bus_add_device(struct pci_dev *dev);
-void pci_bus_add_devices(struct pci_bus *bus);
 void pci_name_device(struct pci_dev *dev);
 char *pci_class_name(u32 class);
 void pci_read_bridge_bases(struct pci_bus *child);
@@ -856,7 +861,8 @@ int pci_register_driver(struct pci_drive
 void pci_unregister_driver(struct pci_driver *);
 void pci_remove_behind_bridge(struct pci_dev *);
 struct pci_driver *pci_dev_driver(const struct pci_dev *);
-const struct pci_device_id *pci_match_device(const struct pci_device_id *ids, const struct pci_dev *dev);
+const struct pci_device_id *pci_match_device(struct pci_driver *drv, struct pci_dev *dev);
+const struct pci_device_id *pci_match_id(const struct pci_device_id *ids, struct pci_dev *dev);
 int pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max, int pass);
 
 /* kmem_cache style wrapper around pci_alloc_consistent() */
@@ -870,6 +876,15 @@ int pci_scan_bridge(struct pci_bus *bus,
 #define	pci_pool_alloc(pool, flags, handle) dma_pool_alloc(pool, flags, handle)
 #define	pci_pool_free(pool, vaddr, addr) dma_pool_free(pool, vaddr, addr)
 
+enum pci_dma_burst_strategy {
+	PCI_DMA_BURST_INFINITY,	/* make bursts as large as possible,
+				   strategy_parameter is N/A */
+	PCI_DMA_BURST_BOUNDARY, /* disconnect at every strategy_parameter
+				   byte boundaries */
+	PCI_DMA_BURST_MULTIPLE, /* disconnect at some multiple of
+				   strategy_parameter byte boundaries */
+};
+
 #if defined(CONFIG_ISA) || defined(CONFIG_EISA)
 extern struct pci_dev *isa_bridge;
 #endif
@@ -957,6 +972,8 @@ static inline int pci_enable_wake(struct
 
 #define	isa_bridge	((struct pci_dev *)NULL)
 
+#define pci_dma_burst_advice(pdev, strat, strategy_parameter) do { } while (0)
+
 #else
 
 /*
@@ -971,7 +988,6 @@ static inline int pci_proc_domain(struct
 	return 0;
 }
 #endif
-
 #endif /* !CONFIG_PCI */
 
 /* these helpers provide future and backwards compatibility
@@ -1016,6 +1032,20 @@ static inline char *pci_name(struct pci_
 #define pci_pretty_name(dev) ""
 #endif
 
+
+/* Some archs don't want to expose struct resource to userland as-is
+ * in sysfs and /proc
+ */
+#ifndef HAVE_ARCH_PCI_RESOURCE_TO_USER
+static inline void pci_resource_to_user(const struct pci_dev *dev, int bar,
+                const struct resource *rsrc, u64 *start, u64 *end)
+{
+	*start = rsrc->start;
+	*end = rsrc->end;
+}
+#endif /* HAVE_ARCH_PCI_RESOURCE_TO_USER */
+
+
 /*
  *  The world is not perfect and supplies us with broken PCI devices.
  *  For at least a part of these bugs we need a work-around, so both
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -62,6 +62,8 @@
 
 #define PCI_BASE_CLASS_SYSTEM		0x08
 #define PCI_CLASS_SYSTEM_PIC		0x0800
+#define PCI_CLASS_SYSTEM_PIC_IOAPIC	0x080010
+#define PCI_CLASS_SYSTEM_PIC_IOXAPIC	0x080020
 #define PCI_CLASS_SYSTEM_DMA		0x0801
 #define PCI_CLASS_SYSTEM_TIMER		0x0802
 #define PCI_CLASS_SYSTEM_RTC		0x0803
@@ -575,6 +577,7 @@
 #define PCI_DEVICE_ID_CT_65550		0x00e0
 #define PCI_DEVICE_ID_CT_65554		0x00e4
 #define PCI_DEVICE_ID_CT_65555		0x00e5
+#define PCI_DEVICE_ID_CT_69000		0x00c0
 
 #define PCI_VENDOR_ID_MIRO		0x1031
 #define PCI_DEVICE_ID_MIRO_36050	0x5601
@@ -711,8 +714,9 @@
 #define PCI_DEVICE_ID_HP_DIVA_AUX	0x1290
 #define PCI_DEVICE_ID_HP_DIVA_RMP3	0x1301
 #define PCI_DEVICE_ID_HP_CISSA		0x3220
-#define PCI_DEVICE_ID_HP_CISSB		0x3230
+#define PCI_DEVICE_ID_HP_CISSB		0x3222
 #define PCI_DEVICE_ID_HP_ZX2_IOC	0x4031
+#define PCI_DEVICE_ID_HP_CISSC		0x3230
 
 #define PCI_VENDOR_ID_PCTECH		0x1042
 #define PCI_DEVICE_ID_PCTECH_RZ1000	0x1000
@@ -877,7 +881,7 @@
 #define PCI_DEVICE_ID_APPLE_UNI_N_PCI15	0x002e
 #define PCI_DEVICE_ID_APPLE_UNI_N_FW2	0x0030
 #define PCI_DEVICE_ID_APPLE_UNI_N_GMAC2	0x0032
-#define PCI_DEVIEC_ID_APPLE_UNI_N_ATA	0x0033
+#define PCI_DEVICE_ID_APPLE_UNI_N_ATA	0x0033
 #define PCI_DEVICE_ID_APPLE_UNI_N_AGP2	0x0034
 #define PCI_DEVICE_ID_APPLE_IPID_ATA100	0x003b
 #define PCI_DEVICE_ID_APPLE_KEYLARGO_I	0x003e
@@ -907,6 +911,15 @@
 #define PCI_DEVICE_ID_QLOGIC_ISP1022	0x1022
 #define PCI_DEVICE_ID_QLOGIC_ISP2100	0x2100
 #define PCI_DEVICE_ID_QLOGIC_ISP2200	0x2200
+#define PCI_DEVICE_ID_QLOGIC_ISP2300	0x2300
+#define PCI_DEVICE_ID_QLOGIC_ISP2312	0x2312
+#define PCI_DEVICE_ID_QLOGIC_ISP2322	0x2322
+#define PCI_DEVICE_ID_QLOGIC_ISP6312	0x6312
+#define PCI_DEVICE_ID_QLOGIC_ISP6322	0x6322
+#define PCI_DEVICE_ID_QLOGIC_ISP2422	0x2422
+#define PCI_DEVICE_ID_QLOGIC_ISP2432	0x2432
+#define PCI_DEVICE_ID_QLOGIC_ISP2512	0x2512
+#define PCI_DEVICE_ID_QLOGIC_ISP2522	0x2522
 
 #define PCI_VENDOR_ID_CYRIX		0x1078
 #define PCI_DEVICE_ID_CYRIX_5510	0x0000
@@ -1007,6 +1020,7 @@
 #define PCI_DEVICE_ID_PLX_SPCOM200	0x1103
 #define PCI_DEVICE_ID_PLX_DJINN_ITOO	0x1151
 #define PCI_DEVICE_ID_PLX_R753		0x1152
+#define PCI_DEVICE_ID_PLX_OLITEC	0x1187
 #define PCI_DEVICE_ID_PLX_9030		0x9030
 #define PCI_DEVICE_ID_PLX_9050		0x9050
 #define PCI_DEVICE_ID_PLX_9060		0x9060
@@ -1234,6 +1248,7 @@
 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE	0x0265
 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA	0x0266
 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA2	0x0267
+#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE	0x036E
 #define PCI_DEVICE_ID_NVIDIA_NVENET_12		0x0268
 #define PCI_DEVICE_ID_NVIDIA_NVENET_13		0x0269
 #define PCI_DEVICE_ID_NVIDIA_MCP51_AUDIO	0x026B
@@ -1283,6 +1298,8 @@
 #define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO5700_2    0x0348
 #define PCI_DEVICE_ID_NVIDIA_QUADRO_FX_GO1000       0x034C
 #define PCI_DEVICE_ID_NVIDIA_QUADRO_FX_1100         0x034E
+#define PCI_DEVICE_ID_NVIDIA_NVENET_14              0x0372
+#define PCI_DEVICE_ID_NVIDIA_NVENET_15              0x0373
 
 #define PCI_VENDOR_ID_IMS		0x10e0
 #define PCI_DEVICE_ID_IMS_8849		0x8849
@@ -1563,10 +1580,12 @@
 #define PCI_DEVICE_ID_SERVERWORKS_OSB4IDE 0x0211
 #define PCI_DEVICE_ID_SERVERWORKS_CSB5IDE 0x0212
 #define PCI_DEVICE_ID_SERVERWORKS_CSB6IDE 0x0213
+#define PCI_DEVICE_ID_SERVERWORKS_HT1000IDE 0x0214
 #define PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2 0x0217
 #define PCI_DEVICE_ID_SERVERWORKS_OSB4USB 0x0220
 #define PCI_DEVICE_ID_SERVERWORKS_CSB5USB PCI_DEVICE_ID_SERVERWORKS_OSB4USB
 #define PCI_DEVICE_ID_SERVERWORKS_CSB6USB 0x0221
+#define PCI_DEVICE_ID_SERVERWORKS_CSB6LPC 0x0227
 #define PCI_DEVICE_ID_SERVERWORKS_GCLE    0x0225
 #define PCI_DEVICE_ID_SERVERWORKS_GCLE2   0x0227
 #define PCI_DEVICE_ID_SERVERWORKS_CSB5ISA 0x0230
@@ -1810,6 +1829,8 @@
 #define PCI_VENDOR_ID_ITE		0x1283
 #define PCI_DEVICE_ID_ITE_IT8172G	0x8172
 #define PCI_DEVICE_ID_ITE_IT8172G_AUDIO 0x0801
+#define PCI_DEVICE_ID_ITE_8211		0x8211
+#define PCI_DEVICE_ID_ITE_8212		0x8212
 #define PCI_DEVICE_ID_ITE_8872		0x8872
 #define PCI_DEVICE_ID_ITE_IT8330G_0	0xe886
 
@@ -1862,6 +1883,7 @@
 #define PCI_DEVICE_ID_CBOARDS_DAS1602_16 0x0001
 
 #define PCI_VENDOR_ID_SIIG		0x131f
+#define PCI_SUBVENDOR_ID_SIIG		0x131f
 #define PCI_DEVICE_ID_SIIG_1S_10x_550	0x1000
 #define PCI_DEVICE_ID_SIIG_1S_10x_650	0x1001
 #define PCI_DEVICE_ID_SIIG_1S_10x_850	0x1002
@@ -1899,6 +1921,7 @@
 #define PCI_DEVICE_ID_SIIG_2S1P_20x_550	0x2060
 #define PCI_DEVICE_ID_SIIG_2S1P_20x_650	0x2061
 #define PCI_DEVICE_ID_SIIG_2S1P_20x_850	0x2062
+#define PCI_SUBDEVICE_ID_SIIG_QUARTET_SERIAL	0x2050
 
 #define PCI_VENDOR_ID_RADISYS		0x1331
 #define PCI_DEVICE_ID_RADISYS_ENP2611	0x0030
@@ -2086,6 +2109,8 @@
 #define PCI_DEVICE_ID_TIGON3_5721	0x1659
 #define PCI_DEVICE_ID_TIGON3_5705M	0x165d
 #define PCI_DEVICE_ID_TIGON3_5705M_2	0x165e
+#define PCI_DEVICE_ID_TIGON3_5780	0x166a
+#define PCI_DEVICE_ID_TIGON3_5780S	0x166b
 #define PCI_DEVICE_ID_TIGON3_5705F	0x166e
 #define PCI_DEVICE_ID_TIGON3_5750	0x1676
 #define PCI_DEVICE_ID_TIGON3_5751	0x1677
@@ -2160,6 +2185,9 @@
 #define PCI_VENDOR_ID_SIBYTE		0x166d
 #define PCI_DEVICE_ID_BCM1250_HT	0x0002
 
+#define PCI_VENDOR_ID_NETCELL		0x169c
+#define PCI_DEVICE_ID_REVOLUTION	0x0044
+
 #define PCI_VENDOR_ID_LINKSYS		0x1737
 #define PCI_DEVICE_ID_LINKSYS_EG1032	0x1032
 #define PCI_DEVICE_ID_LINKSYS_EG1064	0x1064
@@ -2257,6 +2285,11 @@
 #define PCI_VENDOR_ID_INTEL		0x8086
 #define PCI_DEVICE_ID_INTEL_EESSC	0x0008
 #define PCI_DEVICE_ID_INTEL_21145	0x0039
+#define PCI_DEVICE_ID_INTEL_PXHD_0	0x0320
+#define PCI_DEVICE_ID_INTEL_PXHD_1	0x0321
+#define PCI_DEVICE_ID_INTEL_PXH_0	0x0329
+#define PCI_DEVICE_ID_INTEL_PXH_1	0x032A
+#define PCI_DEVICE_ID_INTEL_PXHV	0x032C
 #define PCI_DEVICE_ID_INTEL_82375	0x0482
 #define PCI_DEVICE_ID_INTEL_82424	0x0483
 #define PCI_DEVICE_ID_INTEL_82378	0x0484
diff --git a/include/linux/pfkeyv2.h b/include/linux/pfkeyv2.h
--- a/include/linux/pfkeyv2.h
+++ b/include/linux/pfkeyv2.h
@@ -245,6 +245,7 @@ struct sadb_x_nat_t_port {
 
 /* Security Association flags */
 #define SADB_SAFLAGS_PFS	1
+#define SADB_SAFLAGS_NOPMTUDISC	0x20000000
 #define SADB_SAFLAGS_DECAP_DSCP	0x40000000
 #define SADB_SAFLAGS_NOECN	0x80000000
 
diff --git a/include/linux/pkt_cls.h b/include/linux/pkt_cls.h
--- a/include/linux/pkt_cls.h
+++ b/include/linux/pkt_cls.h
@@ -276,6 +276,7 @@ struct tc_rsvp_pinfo
 	__u8	protocol;
 	__u8	tunnelid;
 	__u8	tunnelhdr;
+	__u8	pad;
 };
 
 /* ROUTE filter */
@@ -408,6 +409,7 @@ enum
 	TCF_EM_NBYTE,
 	TCF_EM_U32,
 	TCF_EM_META,
+	TCF_EM_TEXT,
 	__TCF_EM_MAX
 };
 
diff --git a/include/linux/pkt_sched.h b/include/linux/pkt_sched.h
--- a/include/linux/pkt_sched.h
+++ b/include/linux/pkt_sched.h
@@ -221,9 +221,11 @@ struct tc_gred_qopt
 /* gred setup */
 struct tc_gred_sopt
 {
-       __u32           DPs;
-       __u32           def_DP;
-       __u8            grio;
+       __u32		DPs;
+       __u32		def_DP;
+       __u8		grio;
+       __u8		pad1;
+       __u16		pad2;
 };
 
 /* HTB section */
@@ -351,6 +353,7 @@ struct tc_cbq_ovl
 #define	TC_CBQ_OVL_DROP		3
 #define	TC_CBQ_OVL_RCLASSIC	4
 	unsigned char	priority2;
+	__u16		pad;
 	__u32		penalty;
 };
 
diff --git a/include/linux/pktcdvd.h b/include/linux/pktcdvd.h
--- a/include/linux/pktcdvd.h
+++ b/include/linux/pktcdvd.h
@@ -159,7 +159,7 @@ struct packet_iosched
 	struct bio		*read_queue_tail;
 	struct bio		*write_queue;
 	struct bio		*write_queue_tail;
-	int			high_prio_read;	/* An important read request has been queued */
+	sector_t		last_write;	/* The sector where the last write ended */
 	int			successive_reads;
 };
 
diff --git a/include/linux/pm.h b/include/linux/pm.h
--- a/include/linux/pm.h
+++ b/include/linux/pm.h
@@ -103,7 +103,8 @@ extern int pm_active;
 /*
  * Register a device with power management
  */
-struct pm_dev __deprecated *pm_register(pm_dev_t type, unsigned long id, pm_callback callback);
+struct pm_dev __deprecated *
+pm_register(pm_dev_t type, unsigned long id, pm_callback callback);
 
 /*
  * Unregister a device with power management
@@ -175,7 +176,7 @@ struct pm_ops {
 };
 
 extern void pm_set_ops(struct pm_ops *);
-
+extern struct pm_ops *pm_ops;
 extern int pm_suspend(suspend_state_t state);
 
 
@@ -190,17 +191,18 @@ typedef u32 __bitwise pm_message_t;
 /*
  * There are 4 important states driver can be in:
  * ON     -- driver is working
- * FREEZE -- stop operations and apply whatever policy is applicable to a suspended driver
- *           of that class, freeze queues for block like IDE does, drop packets for
- *           ethernet, etc... stop DMA engine too etc... so a consistent image can be
- *           saved; but do not power any hardware down.
- * SUSPEND - like FREEZE, but hardware is doing as much powersaving as possible. Roughly
- *           pci D3.
+ * FREEZE -- stop operations and apply whatever policy is applicable to a
+ *           suspended driver of that class, freeze queues for block like IDE
+ *           does, drop packets for ethernet, etc... stop DMA engine too etc...
+ *           so a consistent image can be saved; but do not power any hardware
+ *           down.
+ * SUSPEND - like FREEZE, but hardware is doing as much powersaving as
+ *           possible. Roughly pci D3.
  *
- * Unfortunately, current drivers only recognize numeric values 0 (ON) and 3 (SUSPEND).
- * We'll need to fix the drivers. So yes, putting 3 to all diferent defines is intentional,
- * and will go away as soon as drivers are fixed. Also note that typedef is neccessary,
- * we'll probably want to switch to
+ * Unfortunately, current drivers only recognize numeric values 0 (ON) and 3
+ * (SUSPEND).  We'll need to fix the drivers. So yes, putting 3 to all different
+ * defines is intentional, and will go away as soon as drivers are fixed.  Also
+ * note that typedef is neccessary, we'll probably want to switch to
  *   typedef struct pm_message_t { int event; int flags; } pm_message_t
  * or something similar soon.
  */
@@ -222,11 +224,18 @@ struct dev_pm_info {
 
 extern void device_pm_set_parent(struct device * dev, struct device * parent);
 
-extern int device_suspend(pm_message_t state);
 extern int device_power_down(pm_message_t state);
 extern void device_power_up(void);
 extern void device_resume(void);
 
+#ifdef CONFIG_PM
+extern int device_suspend(pm_message_t state);
+#else
+static inline int device_suspend(pm_message_t state)
+{
+	return 0;
+}
+#endif
 
 #endif /* __KERNEL__ */
 
diff --git a/include/linux/pmu.h b/include/linux/pmu.h
--- a/include/linux/pmu.h
+++ b/include/linux/pmu.h
@@ -166,7 +166,7 @@ extern int pmu_i2c_simple_read(int bus, 
 extern int pmu_i2c_simple_write(int bus, int addr,  u8* data, int len);
 
 
-#ifdef CONFIG_PMAC_PBOOK
+#ifdef CONFIG_PM
 /*
  * Stuff for putting the powerbook to sleep and waking it again.
  *
@@ -208,6 +208,8 @@ struct pmu_sleep_notifier
 int pmu_register_sleep_notifier(struct pmu_sleep_notifier* notifier);
 int pmu_unregister_sleep_notifier(struct pmu_sleep_notifier* notifier);
 
+#endif /* CONFIG_PM */
+
 #define PMU_MAX_BATTERIES	2
 
 /* values for pmu_power_flags */
@@ -235,6 +237,4 @@ extern int pmu_battery_count;
 extern struct pmu_battery_info pmu_batteries[PMU_MAX_BATTERIES];
 extern unsigned int pmu_power_flags;
 
-#endif /* CONFIG_PMAC_PBOOK */
-
 #endif	/* __KERNEL__ */
diff --git a/include/linux/posix_acl_xattr.h b/include/linux/posix_acl_xattr.h
--- a/include/linux/posix_acl_xattr.h
+++ b/include/linux/posix_acl_xattr.h
@@ -23,13 +23,13 @@
 #define ACL_UNDEFINED_ID	(-1)
 
 typedef struct {
-	__u16			e_tag;
-	__u16			e_perm;
-	__u32			e_id;
+	__le16			e_tag;
+	__le16			e_perm;
+	__le32			e_id;
 } posix_acl_xattr_entry;
 
 typedef struct {
-	__u32			a_version;
+	__le32			a_version;
 	posix_acl_xattr_entry	a_entries[0];
 } posix_acl_xattr_header;
 
@@ -52,4 +52,7 @@ posix_acl_xattr_count(size_t size)
 	return size / sizeof(posix_acl_xattr_entry);
 }
 
+struct posix_acl *posix_acl_from_xattr(const void *value, size_t size);
+int posix_acl_to_xattr(const struct posix_acl *acl, void *buffer, size_t size);
+
 #endif	/* _POSIX_ACL_XATTR_H */
diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h
--- a/include/linux/proc_fs.h
+++ b/include/linux/proc_fs.h
@@ -74,6 +74,13 @@ struct kcore_list {
 	size_t size;
 };
 
+struct vmcore {
+	struct list_head list;
+	unsigned long long paddr;
+	unsigned long size;
+	loff_t offset;
+};
+
 #ifdef CONFIG_PROC_FS
 
 extern struct proc_dir_entry proc_root;
diff --git a/include/linux/qnx4_fs.h b/include/linux/qnx4_fs.h
--- a/include/linux/qnx4_fs.h
+++ b/include/linux/qnx4_fs.h
@@ -46,11 +46,11 @@ struct qnx4_inode_entry {
 	char		di_fname[QNX4_SHORT_NAME_MAX];
 	qnx4_off_t	di_size;
 	qnx4_xtnt_t	di_first_xtnt;
-	__u32		di_xblk;
-	__s32		di_ftime;
-	__s32		di_mtime;
-	__s32		di_atime;
-	__s32		di_ctime;
+	__le32		di_xblk;
+	__le32		di_ftime;
+	__le32		di_mtime;
+	__le32		di_atime;
+	__le32		di_ctime;
 	qnx4_nxtnt_t	di_num_xtnts;
 	qnx4_mode_t	di_mode;
 	qnx4_muid_t	di_uid;
@@ -63,18 +63,18 @@ struct qnx4_inode_entry {
 
 struct qnx4_link_info {
 	char		dl_fname[QNX4_NAME_MAX];
-	__u32		dl_inode_blk;
+	__le32		dl_inode_blk;
 	__u8		dl_inode_ndx;
 	__u8		dl_spare[10];
 	__u8		dl_status;
 };
 
 struct qnx4_xblk {
-	__u32		xblk_next_xblk;
-	__u32		xblk_prev_xblk;
+	__le32		xblk_next_xblk;
+	__le32		xblk_prev_xblk;
 	__u8		xblk_num_xtnts;
 	__u8		xblk_spare[3];
-	__s32		xblk_num_blocks;
+	__le32		xblk_num_blocks;
 	qnx4_xtnt_t	xblk_xtnts[QNX4_MAX_XTNTS_PER_XBLK];
 	char		xblk_signature[8];
 	qnx4_xtnt_t	xblk_first_xtnt;
diff --git a/include/linux/qnxtypes.h b/include/linux/qnxtypes.h
--- a/include/linux/qnxtypes.h
+++ b/include/linux/qnxtypes.h
@@ -12,18 +12,18 @@
 #ifndef _QNX4TYPES_H
 #define _QNX4TYPES_H
 
-typedef __u16 qnx4_nxtnt_t;
+typedef __le16 qnx4_nxtnt_t;
 typedef __u8  qnx4_ftype_t;
 
 typedef struct {
-	__u32 xtnt_blk;
-	__u32 xtnt_size;
+	__le32 xtnt_blk;
+	__le32 xtnt_size;
 } qnx4_xtnt_t;
 
-typedef __u16 qnx4_mode_t;
-typedef __u16 qnx4_muid_t;
-typedef __u16 qnx4_mgid_t;
-typedef __u32 qnx4_off_t;
-typedef __u16 qnx4_nlink_t;
+typedef __le16 qnx4_mode_t;
+typedef __le16 qnx4_muid_t;
+typedef __le16 qnx4_mgid_t;
+typedef __le32 qnx4_off_t;
+typedef __le16 qnx4_nlink_t;
 
 #endif
diff --git a/include/linux/quota.h b/include/linux/quota.h
--- a/include/linux/quota.h
+++ b/include/linux/quota.h
@@ -138,8 +138,11 @@ struct if_dqinfo {
 #include <linux/dqblk_v2.h>
 
 /* Maximal numbers of writes for quota operation (insert/delete/update)
- * (over all formats) - info block, 4 pointer blocks, data block */
-#define DQUOT_MAX_WRITES	6
+ * (over VFS all formats) */
+#define DQUOT_INIT_ALLOC max(V1_INIT_ALLOC, V2_INIT_ALLOC)
+#define DQUOT_INIT_REWRITE max(V1_INIT_REWRITE, V2_INIT_REWRITE)
+#define DQUOT_DEL_ALLOC max(V1_DEL_ALLOC, V2_DEL_ALLOC)
+#define DQUOT_DEL_REWRITE max(V1_DEL_REWRITE, V2_DEL_REWRITE)
 
 /*
  * Data for one user/group kept in memory
diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h
--- a/include/linux/quotaops.h
+++ b/include/linux/quotaops.h
@@ -39,7 +39,8 @@ extern int dquot_commit_info(struct supe
 extern int dquot_mark_dquot_dirty(struct dquot *dquot);
 
 extern int vfs_quota_on(struct super_block *sb, int type, int format_id, char *path);
-extern int vfs_quota_on_mount(int type, int format_id, struct dentry *dentry);
+extern int vfs_quota_on_mount(struct super_block *sb, char *qf_name,
+		int format_id, int type);
 extern int vfs_quota_off(struct super_block *sb, int type);
 #define vfs_quota_off_mount(sb, type) vfs_quota_off(sb, type)
 extern int vfs_quota_sync(struct super_block *sb, int type);
diff --git a/include/linux/raid/bitmap.h b/include/linux/raid/bitmap.h
new file mode 100644
--- /dev/null
+++ b/include/linux/raid/bitmap.h
@@ -0,0 +1,274 @@
+/*
+ * bitmap.h: Copyright (C) Peter T. Breuer (ptb@ot.uc3m.es) 2003
+ *
+ * additions: Copyright (C) 2003-2004, Paul Clements, SteelEye Technology, Inc.
+ */
+#ifndef BITMAP_H
+#define BITMAP_H 1
+
+#define BITMAP_MAJOR 3
+#define BITMAP_MINOR 38
+
+/*
+ * in-memory bitmap:
+ *
+ * Use 16 bit block counters to track pending writes to each "chunk".
+ * The 2 high order bits are special-purpose, the first is a flag indicating
+ * whether a resync is needed.  The second is a flag indicating whether a
+ * resync is active.
+ * This means that the counter is actually 14 bits:
+ *
+ * +--------+--------+------------------------------------------------+
+ * | resync | resync |               counter                          |
+ * | needed | active |                                                |
+ * |  (0-1) |  (0-1) |              (0-16383)                         |
+ * +--------+--------+------------------------------------------------+
+ *
+ * The "resync needed" bit is set when:
+ *    a '1' bit is read from storage at startup.
+ *    a write request fails on some drives
+ *    a resync is aborted on a chunk with 'resync active' set
+ * It is cleared (and resync-active set) when a resync starts across all drives
+ * of the chunk.
+ *
+ *
+ * The "resync active" bit is set when:
+ *    a resync is started on all drives, and resync_needed is set.
+ *       resync_needed will be cleared (as long as resync_active wasn't already set).
+ * It is cleared when a resync completes.
+ *
+ * The counter counts pending write requests, plus the on-disk bit.
+ * When the counter is '1' and the resync bits are clear, the on-disk
+ * bit can be cleared aswell, thus setting the counter to 0.
+ * When we set a bit, or in the counter (to start a write), if the fields is
+ * 0, we first set the disk bit and set the counter to 1.
+ *
+ * If the counter is 0, the on-disk bit is clear and the stipe is clean
+ * Anything that dirties the stipe pushes the counter to 2 (at least)
+ * and sets the on-disk bit (lazily).
+ * If a periodic sweep find the counter at 2, it is decremented to 1.
+ * If the sweep find the counter at 1, the on-disk bit is cleared and the
+ * counter goes to zero.
+ *
+ * Also, we'll hijack the "map" pointer itself and use it as two 16 bit block
+ * counters as a fallback when "page" memory cannot be allocated:
+ *
+ * Normal case (page memory allocated):
+ *
+ *     page pointer (32-bit)
+ *
+ *     [ ] ------+
+ *               |
+ *               +-------> [   ][   ]..[   ] (4096 byte page == 2048 counters)
+ *                          c1   c2    c2048
+ *
+ * Hijacked case (page memory allocation failed):
+ *
+ *     hijacked page pointer (32-bit)
+ *
+ *     [		  ][		  ] (no page memory allocated)
+ *      counter #1 (16-bit) counter #2 (16-bit)
+ *
+ */
+
+#ifdef __KERNEL__
+
+#define PAGE_BITS (PAGE_SIZE << 3)
+#define PAGE_BIT_SHIFT (PAGE_SHIFT + 3)
+
+typedef __u16 bitmap_counter_t;
+#define COUNTER_BITS 16
+#define COUNTER_BIT_SHIFT 4
+#define COUNTER_BYTE_RATIO (COUNTER_BITS / 8)
+#define COUNTER_BYTE_SHIFT (COUNTER_BIT_SHIFT - 3)
+
+#define NEEDED_MASK ((bitmap_counter_t) (1 << (COUNTER_BITS - 1)))
+#define RESYNC_MASK ((bitmap_counter_t) (1 << (COUNTER_BITS - 2)))
+#define COUNTER_MAX ((bitmap_counter_t) RESYNC_MASK - 1)
+#define NEEDED(x) (((bitmap_counter_t) x) & NEEDED_MASK)
+#define RESYNC(x) (((bitmap_counter_t) x) & RESYNC_MASK)
+#define COUNTER(x) (((bitmap_counter_t) x) & COUNTER_MAX)
+
+/* how many counters per page? */
+#define PAGE_COUNTER_RATIO (PAGE_BITS / COUNTER_BITS)
+/* same, except a shift value for more efficient bitops */
+#define PAGE_COUNTER_SHIFT (PAGE_BIT_SHIFT - COUNTER_BIT_SHIFT)
+/* same, except a mask value for more efficient bitops */
+#define PAGE_COUNTER_MASK  (PAGE_COUNTER_RATIO - 1)
+
+#define BITMAP_BLOCK_SIZE 512
+#define BITMAP_BLOCK_SHIFT 9
+
+/* how many blocks per chunk? (this is variable) */
+#define CHUNK_BLOCK_RATIO(bitmap) ((bitmap)->chunksize >> BITMAP_BLOCK_SHIFT)
+#define CHUNK_BLOCK_SHIFT(bitmap) ((bitmap)->chunkshift - BITMAP_BLOCK_SHIFT)
+#define CHUNK_BLOCK_MASK(bitmap) (CHUNK_BLOCK_RATIO(bitmap) - 1)
+
+/* when hijacked, the counters and bits represent even larger "chunks" */
+/* there will be 1024 chunks represented by each counter in the page pointers */
+#define PAGEPTR_BLOCK_RATIO(bitmap) \
+			(CHUNK_BLOCK_RATIO(bitmap) << PAGE_COUNTER_SHIFT >> 1)
+#define PAGEPTR_BLOCK_SHIFT(bitmap) \
+			(CHUNK_BLOCK_SHIFT(bitmap) + PAGE_COUNTER_SHIFT - 1)
+#define PAGEPTR_BLOCK_MASK(bitmap) (PAGEPTR_BLOCK_RATIO(bitmap) - 1)
+
+/*
+ * on-disk bitmap:
+ *
+ * Use one bit per "chunk" (block set). We do the disk I/O on the bitmap
+ * file a page at a time. There's a superblock at the start of the file.
+ */
+
+/* map chunks (bits) to file pages - offset by the size of the superblock */
+#define CHUNK_BIT_OFFSET(chunk) ((chunk) + (sizeof(bitmap_super_t) << 3))
+
+#endif
+
+/*
+ * bitmap structures:
+ */
+
+#define BITMAP_MAGIC 0x6d746962
+
+/* use these for bitmap->flags and bitmap->sb->state bit-fields */
+enum bitmap_state {
+	BITMAP_ACTIVE = 0x001, /* the bitmap is in use */
+	BITMAP_STALE  = 0x002  /* the bitmap file is out of date or had -EIO */
+};
+
+/* the superblock at the front of the bitmap file -- little endian */
+typedef struct bitmap_super_s {
+	__u32 magic;        /*  0  BITMAP_MAGIC */
+	__u32 version;      /*  4  the bitmap major for now, could change... */
+	__u8  uuid[16];     /*  8  128 bit uuid - must match md device uuid */
+	__u64 events;       /* 24  event counter for the bitmap (1)*/
+	__u64 events_cleared;/*32  event counter when last bit cleared (2) */
+	__u64 sync_size;    /* 40  the size of the md device's sync range(3) */
+	__u32 state;        /* 48  bitmap state information */
+	__u32 chunksize;    /* 52  the bitmap chunk size in bytes */
+	__u32 daemon_sleep; /* 56  seconds between disk flushes */
+
+	__u8  pad[256 - 60]; /* set to zero */
+} bitmap_super_t;
+
+/* notes:
+ * (1) This event counter is updated before the eventcounter in the md superblock
+ *    When a bitmap is loaded, it is only accepted if this event counter is equal
+ *    to, or one greater than, the event counter in the superblock.
+ * (2) This event counter is updated when the other one is *if*and*only*if* the
+ *    array is not degraded.  As bits are not cleared when the array is degraded,
+ *    this represents the last time that any bits were cleared.
+ *    If a device is being added that has an event count with this value or
+ *    higher, it is accepted as conforming to the bitmap.
+ * (3)This is the number of sectors represented by the bitmap, and is the range that
+ *    resync happens across.  For raid1 and raid5/6 it is the size of individual
+ *    devices.  For raid10 it is the size of the array.
+ */
+
+#ifdef __KERNEL__
+
+/* the in-memory bitmap is represented by bitmap_pages */
+struct bitmap_page {
+	/*
+	 * map points to the actual memory page
+	 */
+	char *map;
+	/*
+	 * in emergencies (when map cannot be alloced), hijack the map
+	 * pointer and use it as two counters itself
+	 */
+	unsigned int hijacked:1;
+	/*
+	 * count of dirty bits on the page
+	 */
+	unsigned int  count:31;
+};
+
+/* keep track of bitmap file pages that have pending writes on them */
+struct page_list {
+	struct list_head list;
+	struct page *page;
+};
+
+/* the main bitmap structure - one per mddev */
+struct bitmap {
+	struct bitmap_page *bp;
+	unsigned long pages; /* total number of pages in the bitmap */
+	unsigned long missing_pages; /* number of pages not yet allocated */
+
+	mddev_t *mddev; /* the md device that the bitmap is for */
+
+	int counter_bits; /* how many bits per block counter */
+
+	/* bitmap chunksize -- how much data does each bit represent? */
+	unsigned long chunksize;
+	unsigned long chunkshift; /* chunksize = 2^chunkshift (for bitops) */
+	unsigned long chunks; /* total number of data chunks for the array */
+
+	/* We hold a count on the chunk currently being synced, and drop
+	 * it when the last block is started.  If the resync is aborted
+	 * midway, we need to be able to drop that count, so we remember
+	 * the counted chunk..
+	 */
+	unsigned long syncchunk;
+
+	__u64	events_cleared;
+
+	/* bitmap spinlock */
+	spinlock_t lock;
+
+	long offset; /* offset from superblock if file is NULL */
+	struct file *file; /* backing disk file */
+	struct page *sb_page; /* cached copy of the bitmap file superblock */
+	struct page **filemap; /* list of cache pages for the file */
+	unsigned long *filemap_attr; /* attributes associated w/ filemap pages */
+	unsigned long file_pages; /* number of pages in the file */
+
+	unsigned long flags;
+
+	/*
+	 * the bitmap daemon - periodically wakes up and sweeps the bitmap
+	 * file, cleaning up bits and flushing out pages to disk as necessary
+	 */
+	unsigned long daemon_lastrun; /* jiffies of last run */
+	unsigned long daemon_sleep; /* how many seconds between updates? */
+
+	/*
+	 * bitmap_writeback_daemon waits for file-pages that have been written,
+	 * as there is no way to get a call-back when a page write completes.
+	 */
+	mdk_thread_t *writeback_daemon;
+	spinlock_t write_lock;
+	wait_queue_head_t write_wait;
+	struct list_head complete_pages;
+	mempool_t *write_pool;
+};
+
+/* the bitmap API */
+
+/* these are used only by md/bitmap */
+int  bitmap_create(mddev_t *mddev);
+void bitmap_flush(mddev_t *mddev);
+void bitmap_destroy(mddev_t *mddev);
+int  bitmap_active(struct bitmap *bitmap);
+
+char *file_path(struct file *file, char *buf, int count);
+void bitmap_print_sb(struct bitmap *bitmap);
+int bitmap_update_sb(struct bitmap *bitmap);
+
+int  bitmap_setallbits(struct bitmap *bitmap);
+void bitmap_write_all(struct bitmap *bitmap);
+
+/* these are exported */
+int bitmap_startwrite(struct bitmap *bitmap, sector_t offset, unsigned long sectors);
+void bitmap_endwrite(struct bitmap *bitmap, sector_t offset, unsigned long sectors,
+		     int success);
+int bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *blocks, int degraded);
+void bitmap_end_sync(struct bitmap *bitmap, sector_t offset, int *blocks, int aborted);
+void bitmap_close_sync(struct bitmap *bitmap);
+
+int bitmap_unplug(struct bitmap *bitmap);
+int bitmap_daemon_work(struct bitmap *bitmap);
+#endif
+
+#endif
diff --git a/include/linux/raid/md.h b/include/linux/raid/md.h
--- a/include/linux/raid/md.h
+++ b/include/linux/raid/md.h
@@ -60,7 +60,14 @@
  */
 #define MD_MAJOR_VERSION                0
 #define MD_MINOR_VERSION                90
-#define MD_PATCHLEVEL_VERSION           1
+/*
+ * MD_PATCHLEVEL_VERSION indicates kernel functionality.
+ * >=1 means different superblock formats are selectable using SET_ARRAY_INFO
+ *     and major_version/minor_version accordingly
+ * >=2 means that Internal bitmaps are supported by setting MD_SB_BITMAP_PRESENT
+ *     in the super status byte
+ */
+#define MD_PATCHLEVEL_VERSION           2
 
 extern int register_md_personality (int p_num, mdk_personality_t *p);
 extern int unregister_md_personality (int p_num);
@@ -69,7 +76,7 @@ extern mdk_thread_t * md_register_thread
 extern void md_unregister_thread (mdk_thread_t *thread);
 extern void md_wakeup_thread(mdk_thread_t *thread);
 extern void md_check_recovery(mddev_t *mddev);
-extern void md_write_start(mddev_t *mddev);
+extern void md_write_start(mddev_t *mddev, struct bio *bi);
 extern void md_write_end(mddev_t *mddev);
 extern void md_handle_safemode(mddev_t *mddev);
 extern void md_done_sync(mddev_t *mddev, int blocks, int ok);
@@ -78,6 +85,12 @@ extern void md_unplug_mddev(mddev_t *mdd
 
 extern void md_print_devices (void);
 
+extern void md_super_write(mddev_t *mddev, mdk_rdev_t *rdev,
+			   sector_t sector, int size, struct page *page);
+extern int sync_page_io(struct block_device *bdev, sector_t sector, int size,
+			struct page *page, int rw);
+
+
 #define MD_BUG(x...) { printk("md: bug in file %s, line %d\n", __FILE__, __LINE__); md_print_devices(); }
 
 #endif 
diff --git a/include/linux/raid/md_k.h b/include/linux/raid/md_k.h
--- a/include/linux/raid/md_k.h
+++ b/include/linux/raid/md_k.h
@@ -15,6 +15,9 @@
 #ifndef _MD_K_H
 #define _MD_K_H
 
+/* and dm-bio-list.h is not under include/linux because.... ??? */
+#include "../../../drivers/md/dm-bio-list.h"
+
 #define MD_RESERVED       0UL
 #define LINEAR            1UL
 #define RAID0             2UL
@@ -180,6 +183,10 @@ struct mdk_rdev_s
 
 	int desc_nr;			/* descriptor index in the superblock */
 	int raid_disk;			/* role of device in array */
+	int saved_raid_disk;		/* role that device used to have in the
+					 * array and could again if we did a partial
+					 * resync from the bitmap
+					 */
 
 	atomic_t	nr_pending;	/* number of pending requests.
 					 * only maintained for arrays that
@@ -252,6 +259,11 @@ struct mddev_s
 	atomic_t			recovery_active; /* blocks scheduled, but not written */
 	wait_queue_head_t		recovery_wait;
 	sector_t			recovery_cp;
+
+	spinlock_t			write_lock;
+	wait_queue_head_t		sb_wait;	/* for waiting on superblock updates */
+	atomic_t			pending_writes;	/* number of active superblock writes */
+
 	unsigned int			safemode;	/* if set, update "clean" superblock
 							 * when no writes pending.
 							 */ 
@@ -260,6 +272,13 @@ struct mddev_s
 	atomic_t			writes_pending; 
 	request_queue_t			*queue;	/* for plugging ... */
 
+	struct bitmap                   *bitmap; /* the bitmap for the device */
+	struct file			*bitmap_file; /* the bitmap file */
+	long				bitmap_offset; /* offset from superblock of
+							* start of bitmap. May be
+							* negative, but not '0'
+							*/
+
 	struct list_head		all_mddevs;
 };
 
@@ -291,7 +310,7 @@ struct mdk_personality_s
 	int (*hot_add_disk) (mddev_t *mddev, mdk_rdev_t *rdev);
 	int (*hot_remove_disk) (mddev_t *mddev, int number);
 	int (*spare_active) (mddev_t *mddev);
-	int (*sync_request)(mddev_t *mddev, sector_t sector_nr, int go_faster);
+	sector_t (*sync_request)(mddev_t *mddev, sector_t sector_nr, int *skipped, int go_faster);
 	int (*resize) (mddev_t *mddev, sector_t sectors);
 	int (*reshape) (mddev_t *mddev, int raid_disks);
 	int (*reconfig) (mddev_t *mddev, int layout, int chunk_size);
@@ -334,6 +353,7 @@ typedef struct mdk_thread_s {
 	unsigned long           flags;
 	struct completion	*event;
 	struct task_struct	*tsk;
+	unsigned long		timeout;
 	const char		*name;
 } mdk_thread_t;
 
diff --git a/include/linux/raid/md_p.h b/include/linux/raid/md_p.h
--- a/include/linux/raid/md_p.h
+++ b/include/linux/raid/md_p.h
@@ -96,6 +96,7 @@ typedef struct mdp_device_descriptor_s {
 #define MD_SB_CLEAN		0
 #define MD_SB_ERRORS		1
 
+#define	MD_SB_BITMAP_PRESENT	8 /* bitmap may be present nearby */
 typedef struct mdp_superblock_s {
 	/*
 	 * Constant generic information
@@ -184,7 +185,7 @@ struct mdp_superblock_1 {
 	/* constant array information - 128 bytes */
 	__u32	magic;		/* MD_SB_MAGIC: 0xa92b4efc - little endian */
 	__u32	major_version;	/* 1 */
-	__u32	feature_map;	/* 0 for now */
+	__u32	feature_map;	/* bit 0 set if 'bitmap_offset' is meaningful */
 	__u32	pad0;		/* always set to 0 when writing */
 
 	__u8	set_uuid[16];	/* user-space generated. */
@@ -197,7 +198,11 @@ struct mdp_superblock_1 {
 
 	__u32	chunksize;	/* in 512byte sectors */
 	__u32	raid_disks;
-	__u8	pad1[128-96];	/* set to 0 when written */
+	__u32	bitmap_offset;	/* sectors after start of superblock that bitmap starts
+				 * NOTE: signed, so bitmap can be before superblock
+				 * only meaningful of feature_map[0] is set.
+				 */
+	__u8	pad1[128-100];	/* set to 0 when written */
 
 	/* constant this-device information - 64 bytes */
 	__u64	data_offset;	/* sector start of data, often 0 */
diff --git a/include/linux/raid/md_u.h b/include/linux/raid/md_u.h
--- a/include/linux/raid/md_u.h
+++ b/include/linux/raid/md_u.h
@@ -23,6 +23,7 @@
 #define GET_DISK_INFO		_IOR (MD_MAJOR, 0x12, mdu_disk_info_t)
 #define PRINT_RAID_DEBUG	_IO (MD_MAJOR, 0x13)
 #define RAID_AUTORUN		_IO (MD_MAJOR, 0x14)
+#define GET_BITMAP_FILE		_IOR (MD_MAJOR, 0x15, mdu_bitmap_file_t)
 
 /* configuration */
 #define CLEAR_ARRAY		_IO (MD_MAJOR, 0x20)
@@ -36,6 +37,7 @@
 #define HOT_ADD_DISK		_IO (MD_MAJOR, 0x28)
 #define SET_DISK_FAULTY		_IO (MD_MAJOR, 0x29)
 #define HOT_GENERATE_ERROR	_IO (MD_MAJOR, 0x2a)
+#define SET_BITMAP_FILE		_IOW (MD_MAJOR, 0x2b, int)
 
 /* usage */
 #define RUN_ARRAY		_IOW (MD_MAJOR, 0x30, mdu_param_t)
@@ -106,6 +108,11 @@ typedef struct mdu_start_info_s {
 
 } mdu_start_info_t;
 
+typedef struct mdu_bitmap_file_s
+{
+	char pathname[4096];
+} mdu_bitmap_file_t;
+
 typedef struct mdu_param_s
 {
 	int			personality;	/* 1,2,3,4 */
diff --git a/include/linux/raid/raid1.h b/include/linux/raid/raid1.h
--- a/include/linux/raid/raid1.h
+++ b/include/linux/raid/raid1.h
@@ -36,12 +36,21 @@ struct r1_private_data_s {
 	spinlock_t		device_lock;
 
 	struct list_head	retry_list;
+	/* queue pending writes and submit them on unplug */
+	struct bio_list		pending_bio_list;
+	/* queue of writes that have been unplugged */
+	struct bio_list		flushing_bio_list;
+
 	/* for use when syncing mirrors: */
 
 	spinlock_t		resync_lock;
-	int nr_pending;
-	int barrier;
+	int			nr_pending;
+	int			barrier;
 	sector_t		next_resync;
+	int			fullsync;  /* set to 1 if a full sync is needed,
+					    * (fresh device added).
+					    * Cleared when a sync completes.
+					    */
 
 	wait_queue_head_t	wait_idle;
 	wait_queue_head_t	wait_resume;
@@ -85,14 +94,17 @@ struct r1bio_s {
 	int			read_disk;
 
 	struct list_head	retry_list;
+	struct bitmap_update	*bitmap_update;
 	/*
 	 * if the IO is in WRITE direction, then multiple bios are used.
 	 * We choose the number when they are allocated.
 	 */
 	struct bio		*bios[0];
+	/* DO NOT PUT ANY NEW FIELDS HERE - bios array is contiguously alloced*/
 };
 
 /* bits for r1bio.state */
 #define	R1BIO_Uptodate	0
 #define	R1BIO_IsSync	1
+#define	R1BIO_Degraded	2
 #endif
diff --git a/include/linux/reboot.h b/include/linux/reboot.h
--- a/include/linux/reboot.h
+++ b/include/linux/reboot.h
@@ -51,6 +51,26 @@ extern void machine_restart(char *cmd);
 extern void machine_halt(void);
 extern void machine_power_off(void);
 
+extern void machine_shutdown(void);
+struct pt_regs;
+extern void machine_crash_shutdown(struct pt_regs *);
+
+/* 
+ * Architecture independent implemenations of sys_reboot commands.
+ */
+
+extern void kernel_restart(char *cmd);
+extern void kernel_halt(void);
+extern void kernel_power_off(void);
+extern void kernel_kexec(void);
+
+/*
+ * Emergency restart, callable from an interrupt handler.
+ */
+
+extern void emergency_restart(void);
+#include <asm/emergency-restart.h>
+
 #endif
 
 #endif /* _LINUX_REBOOT_H */
diff --git a/include/linux/reiserfs_acl.h b/include/linux/reiserfs_acl.h
--- a/include/linux/reiserfs_acl.h
+++ b/include/linux/reiserfs_acl.h
@@ -1,33 +1,32 @@
 #include <linux/init.h>
 #include <linux/posix_acl.h>
-#include <linux/xattr_acl.h>
 
 #define REISERFS_ACL_VERSION	0x0001
 
 typedef struct {
-	__le16		e_tag;
-	__le16		e_perm;
-	__le32		e_id;
+	__le16 e_tag;
+	__le16 e_perm;
+	__le32 e_id;
 } reiserfs_acl_entry;
 
 typedef struct {
-	__le16		e_tag;
-	__le16		e_perm;
+	__le16 e_tag;
+	__le16 e_perm;
 } reiserfs_acl_entry_short;
 
 typedef struct {
-	__le32		a_version;
+	__le32 a_version;
 } reiserfs_acl_header;
 
 static inline size_t reiserfs_acl_size(int count)
 {
 	if (count <= 4) {
 		return sizeof(reiserfs_acl_header) +
-		       count * sizeof(reiserfs_acl_entry_short);
+		    count * sizeof(reiserfs_acl_entry_short);
 	} else {
 		return sizeof(reiserfs_acl_header) +
-		       4 * sizeof(reiserfs_acl_entry_short) +
-		       (count - 4) * sizeof(reiserfs_acl_entry);
+		    4 * sizeof(reiserfs_acl_entry_short) +
+		    (count - 4) * sizeof(reiserfs_acl_entry);
 	}
 }
 
@@ -47,14 +46,14 @@ static inline int reiserfs_acl_count(siz
 	}
 }
 
-
 #ifdef CONFIG_REISERFS_FS_POSIX_ACL
-struct posix_acl * reiserfs_get_acl(struct inode *inode, int type);
-int reiserfs_acl_chmod (struct inode *inode);
-int reiserfs_inherit_default_acl (struct inode *dir, struct dentry *dentry, struct inode *inode);
-int reiserfs_cache_default_acl (struct inode *dir);
-extern int reiserfs_xattr_posix_acl_init (void) __init;
-extern int reiserfs_xattr_posix_acl_exit (void);
+struct posix_acl *reiserfs_get_acl(struct inode *inode, int type);
+int reiserfs_acl_chmod(struct inode *inode);
+int reiserfs_inherit_default_acl(struct inode *dir, struct dentry *dentry,
+				 struct inode *inode);
+int reiserfs_cache_default_acl(struct inode *dir);
+extern int reiserfs_xattr_posix_acl_init(void) __init;
+extern int reiserfs_xattr_posix_acl_exit(void);
 extern struct reiserfs_xattr_handler posix_acl_default_handler;
 extern struct reiserfs_xattr_handler posix_acl_access_handler;
 #else
@@ -62,28 +61,26 @@ extern struct reiserfs_xattr_handler pos
 #define reiserfs_get_acl NULL
 #define reiserfs_cache_default_acl(inode) 0
 
-static inline int
-reiserfs_xattr_posix_acl_init (void)
+static inline int reiserfs_xattr_posix_acl_init(void)
 {
-    return 0;
+	return 0;
 }
 
-static inline int
-reiserfs_xattr_posix_acl_exit (void)
+static inline int reiserfs_xattr_posix_acl_exit(void)
 {
-    return 0;
+	return 0;
 }
 
-static inline int
-reiserfs_acl_chmod (struct inode *inode)
+static inline int reiserfs_acl_chmod(struct inode *inode)
 {
-    return 0;
+	return 0;
 }
 
 static inline int
-reiserfs_inherit_default_acl (const struct inode *dir, struct dentry *dentry, struct inode *inode)
+reiserfs_inherit_default_acl(const struct inode *dir, struct dentry *dentry,
+			     struct inode *inode)
 {
-    return 0;
+	return 0;
 }
 
 #endif
diff --git a/include/linux/reiserfs_fs.h b/include/linux/reiserfs_fs.h
--- a/include/linux/reiserfs_fs.h
+++ b/include/linux/reiserfs_fs.h
@@ -3,11 +3,10 @@
  */
 
 				/* this file has an amazingly stupid
-                                   name, yura please fix it to be
-                                   reiserfs.h, and merge all the rest
-                                   of our .h files that are in this
-                                   directory into it.  */
-
+				   name, yura please fix it to be
+				   reiserfs.h, and merge all the rest
+				   of our .h files that are in this
+				   directory into it.  */
 
 #ifndef _LINUX_REISER_FS_H
 #define _LINUX_REISER_FS_H
@@ -74,9 +73,9 @@
 /* debug levels.  Right now, CONFIG_REISERFS_CHECK means print all debug
 ** messages.
 */
-#define REISERFS_DEBUG_CODE 5 /* extra messages to help find/debug errors */ 
+#define REISERFS_DEBUG_CODE 5	/* extra messages to help find/debug errors */
 
-void reiserfs_warning (struct super_block *s, const char * fmt, ...);
+void reiserfs_warning(struct super_block *s, const char *fmt, ...);
 /* assertions handling */
 
 /** always check a condition and panic if it's false. */
@@ -105,82 +104,78 @@ if( !( cond ) ) 								\
  * Structure of super block on disk, a version of which in RAM is often accessed as REISERFS_SB(s)->s_rs
  * the version in RAM is part of a larger structure containing fields never written to disk.
  */
-#define UNSET_HASH 0 // read_super will guess about, what hash names
-                     // in directories were sorted with
+#define UNSET_HASH 0		// read_super will guess about, what hash names
+		     // in directories were sorted with
 #define TEA_HASH  1
 #define YURA_HASH 2
 #define R5_HASH   3
 #define DEFAULT_HASH R5_HASH
 
-
 struct journal_params {
-    __le32 jp_journal_1st_block;	      /* where does journal start from on its
-				       * device */
-    __le32 jp_journal_dev;	      /* journal device st_rdev */
-    __le32 jp_journal_size;	      /* size of the journal */
-    __le32 jp_journal_trans_max;	      /* max number of blocks in a transaction. */
-    __le32 jp_journal_magic; 	      /* random value made on fs creation (this
-				       * was sb_journal_block_count) */
-    __le32 jp_journal_max_batch;	      /* max number of blocks to batch into a
-				       * trans */
-    __le32 jp_journal_max_commit_age;  /* in seconds, how old can an async
-				       * commit be */
-    __le32 jp_journal_max_trans_age;   /* in seconds, how old can a transaction
-				       * be */
+	__le32 jp_journal_1st_block;	/* where does journal start from on its
+					 * device */
+	__le32 jp_journal_dev;	/* journal device st_rdev */
+	__le32 jp_journal_size;	/* size of the journal */
+	__le32 jp_journal_trans_max;	/* max number of blocks in a transaction. */
+	__le32 jp_journal_magic;	/* random value made on fs creation (this
+					 * was sb_journal_block_count) */
+	__le32 jp_journal_max_batch;	/* max number of blocks to batch into a
+					 * trans */
+	__le32 jp_journal_max_commit_age;	/* in seconds, how old can an async
+						 * commit be */
+	__le32 jp_journal_max_trans_age;	/* in seconds, how old can a transaction
+						 * be */
 };
 
 /* this is the super from 3.5.X, where X >= 10 */
-struct reiserfs_super_block_v1
-{
-    __le32 s_block_count;	   /* blocks count         */
-    __le32 s_free_blocks;           /* free blocks count    */
-    __le32 s_root_block;            /* root block number    */
-    struct journal_params s_journal;
-    __le16 s_blocksize;             /* block size */
-    __le16 s_oid_maxsize;	   /* max size of object id array, see
-				    * get_objectid() commentary  */
-    __le16 s_oid_cursize;	   /* current size of object id array */
-    __le16 s_umount_state;          /* this is set to 1 when filesystem was
-				    * umounted, to 2 - when not */    
-    char s_magic[10];              /* reiserfs magic string indicates that
-				    * file system is reiserfs:
-				    * "ReIsErFs" or "ReIsEr2Fs" or "ReIsEr3Fs" */
-    __le16 s_fs_state;	           /* it is set to used by fsck to mark which
-				    * phase of rebuilding is done */
-    __le32 s_hash_function_code;    /* indicate, what hash function is being use
-				    * to sort names in a directory*/
-    __le16 s_tree_height;           /* height of disk tree */
-    __le16 s_bmap_nr;               /* amount of bitmap blocks needed to address
-				    * each block of file system */
-    __le16 s_version;               /* this field is only reliable on filesystem
-				    * with non-standard journal */
-    __le16 s_reserved_for_journal;  /* size in blocks of journal area on main
-				    * device, we need to keep after
-				    * making fs with non-standard journal */	
+struct reiserfs_super_block_v1 {
+	__le32 s_block_count;	/* blocks count         */
+	__le32 s_free_blocks;	/* free blocks count    */
+	__le32 s_root_block;	/* root block number    */
+	struct journal_params s_journal;
+	__le16 s_blocksize;	/* block size */
+	__le16 s_oid_maxsize;	/* max size of object id array, see
+				 * get_objectid() commentary  */
+	__le16 s_oid_cursize;	/* current size of object id array */
+	__le16 s_umount_state;	/* this is set to 1 when filesystem was
+				 * umounted, to 2 - when not */
+	char s_magic[10];	/* reiserfs magic string indicates that
+				 * file system is reiserfs:
+				 * "ReIsErFs" or "ReIsEr2Fs" or "ReIsEr3Fs" */
+	__le16 s_fs_state;	/* it is set to used by fsck to mark which
+				 * phase of rebuilding is done */
+	__le32 s_hash_function_code;	/* indicate, what hash function is being use
+					 * to sort names in a directory*/
+	__le16 s_tree_height;	/* height of disk tree */
+	__le16 s_bmap_nr;	/* amount of bitmap blocks needed to address
+				 * each block of file system */
+	__le16 s_version;	/* this field is only reliable on filesystem
+				 * with non-standard journal */
+	__le16 s_reserved_for_journal;	/* size in blocks of journal area on main
+					 * device, we need to keep after
+					 * making fs with non-standard journal */
 } __attribute__ ((__packed__));
 
 #define SB_SIZE_V1 (sizeof(struct reiserfs_super_block_v1))
 
 /* this is the on disk super block */
-struct reiserfs_super_block
-{
-    struct reiserfs_super_block_v1 s_v1;
-    __le32 s_inode_generation;
-    __le32 s_flags;                  /* Right now used only by inode-attributes, if enabled */
-    unsigned char s_uuid[16];       /* filesystem unique identifier */
-    unsigned char s_label[16];      /* filesystem volume label */
-    char s_unused[88] ;             /* zero filled by mkreiserfs and
-				     * reiserfs_convert_objectid_map_v1()
-				     * so any additions must be updated
-				     * there as well. */
-}  __attribute__ ((__packed__));
+struct reiserfs_super_block {
+	struct reiserfs_super_block_v1 s_v1;
+	__le32 s_inode_generation;
+	__le32 s_flags;		/* Right now used only by inode-attributes, if enabled */
+	unsigned char s_uuid[16];	/* filesystem unique identifier */
+	unsigned char s_label[16];	/* filesystem volume label */
+	char s_unused[88];	/* zero filled by mkreiserfs and
+				 * reiserfs_convert_objectid_map_v1()
+				 * so any additions must be updated
+				 * there as well. */
+} __attribute__ ((__packed__));
 
 #define SB_SIZE (sizeof(struct reiserfs_super_block))
 
 #define REISERFS_VERSION_1 0
 #define REISERFS_VERSION_2 2
 
-
 // on-disk super block fields converted to cpu form
 #define SB_DISK_SUPER_BLOCK(s) (REISERFS_SB(s)->s_rs)
 #define SB_V1_DISK_SUPER_BLOCK(s) (&(SB_DISK_SUPER_BLOCK(s)->s_v1))
@@ -210,13 +205,12 @@ struct reiserfs_super_block
 #define PUT_SB_TREE_HEIGHT(s, val) \
    do { SB_V1_DISK_SUPER_BLOCK(s)->s_tree_height = cpu_to_le16(val); } while (0)
 #define PUT_SB_REISERFS_STATE(s, val) \
-   do { SB_V1_DISK_SUPER_BLOCK(s)->s_umount_state = cpu_to_le16(val); } while (0) 
+   do { SB_V1_DISK_SUPER_BLOCK(s)->s_umount_state = cpu_to_le16(val); } while (0)
 #define PUT_SB_VERSION(s, val) \
    do { SB_V1_DISK_SUPER_BLOCK(s)->s_version = cpu_to_le16(val); } while (0)
 #define PUT_SB_BMAP_NR(s, val) \
    do { SB_V1_DISK_SUPER_BLOCK(s)->s_bmap_nr = cpu_to_le16 (val); } while (0)
 
-
 #define SB_ONDISK_JP(s) (&SB_V1_DISK_SUPER_BLOCK(s)->s_journal)
 #define SB_ONDISK_JOURNAL_SIZE(s) \
          le32_to_cpu ((SB_ONDISK_JP(s)->jp_journal_size))
@@ -231,21 +225,19 @@ struct reiserfs_super_block
          block >= SB_JOURNAL_1st_RESERVED_BLOCK(s) \
          && block < SB_JOURNAL_1st_RESERVED_BLOCK(s) +  \
          ((!is_reiserfs_jr(SB_DISK_SUPER_BLOCK(s)) ? \
-         SB_ONDISK_JOURNAL_SIZE(s) + 1 : SB_ONDISK_RESERVED_FOR_JOURNAL(s))) 
-
-
+         SB_ONDISK_JOURNAL_SIZE(s) + 1 : SB_ONDISK_RESERVED_FOR_JOURNAL(s)))
 
 				/* used by gcc */
 #define REISERFS_SUPER_MAGIC 0x52654973
 				/* used by file system utilities that
-                                   look at the superblock, etc. */
+				   look at the superblock, etc. */
 #define REISERFS_SUPER_MAGIC_STRING "ReIsErFs"
 #define REISER2FS_SUPER_MAGIC_STRING "ReIsEr2Fs"
 #define REISER2FS_JR_SUPER_MAGIC_STRING "ReIsEr3Fs"
 
-int is_reiserfs_3_5 (struct reiserfs_super_block * rs);
-int is_reiserfs_3_6 (struct reiserfs_super_block * rs);
-int is_reiserfs_jr (struct reiserfs_super_block * rs);
+int is_reiserfs_3_5(struct reiserfs_super_block *rs);
+int is_reiserfs_3_6(struct reiserfs_super_block *rs);
+int is_reiserfs_jr(struct reiserfs_super_block *rs);
 
 /* ReiserFS leaves the first 64k unused, so that partition labels have
    enough space.  If someone wants to write a fancy bootloader that
@@ -272,8 +264,8 @@ typedef __u32 b_blocknr_t;
 typedef __le32 unp_t;
 
 struct unfm_nodeinfo {
-    unp_t unfm_nodenum;
-    unsigned short unfm_freespace;
+	unp_t unfm_nodenum;
+	unsigned short unfm_freespace;
 };
 
 /* there are two formats of keys: 3.5 and 3.6
@@ -285,7 +277,6 @@ struct unfm_nodeinfo {
 #define STAT_DATA_V1 0
 #define STAT_DATA_V2 1
 
-
 static inline struct reiserfs_inode_info *REISERFS_I(const struct inode *inode)
 {
 	return container_of(inode, struct reiserfs_inode_info, vfs_inode);
@@ -343,15 +334,13 @@ static inline struct reiserfs_sb_info *R
    file would fit into one DIRECT item.
    Primary intention for this one is to increase performance by decreasing
    seeking.
-*/   
+*/
 #define STORE_TAIL_IN_UNFM_S2(n_file_size,n_tail_size,n_block_size) \
 (\
   (!(n_tail_size)) || \
   (((n_file_size) > MAX_DIRECT_ITEM_LEN(n_block_size)) ) \
 )
 
-
-
 /*
  * values for s_umount_state field
  */
@@ -364,9 +353,9 @@ static inline struct reiserfs_sb_info *R
 #define TYPE_STAT_DATA 0
 #define TYPE_INDIRECT 1
 #define TYPE_DIRECT 2
-#define TYPE_DIRENTRY 3 
-#define TYPE_MAXTYPE 3 
-#define TYPE_ANY 15 // FIXME: comment is required
+#define TYPE_DIRENTRY 3
+#define TYPE_MAXTYPE 3
+#define TYPE_ANY 15		// FIXME: comment is required
 
 /***************************************************************************/
 /*                       KEY & ITEM HEAD                                   */
@@ -376,60 +365,62 @@ static inline struct reiserfs_sb_info *R
 // directories use this key as well as old files
 //
 struct offset_v1 {
-    __le32 k_offset;
-    __le32 k_uniqueness;
+	__le32 k_offset;
+	__le32 k_uniqueness;
 } __attribute__ ((__packed__));
 
 struct offset_v2 {
 	__le64 v;
 } __attribute__ ((__packed__));
 
-static inline __u16 offset_v2_k_type( const struct offset_v2 *v2 )
+static inline __u16 offset_v2_k_type(const struct offset_v2 *v2)
 {
 	__u8 type = le64_to_cpu(v2->v) >> 60;
-	return (type <= TYPE_MAXTYPE)?type:TYPE_ANY;
+	return (type <= TYPE_MAXTYPE) ? type : TYPE_ANY;
 }
- 
-static inline void set_offset_v2_k_type( struct offset_v2 *v2, int type )
+
+static inline void set_offset_v2_k_type(struct offset_v2 *v2, int type)
 {
-	v2->v = (v2->v & cpu_to_le64(~0ULL>>4)) | cpu_to_le64((__u64)type<<60);
+	v2->v =
+	    (v2->v & cpu_to_le64(~0ULL >> 4)) | cpu_to_le64((__u64) type << 60);
 }
- 
-static inline loff_t offset_v2_k_offset( const struct offset_v2 *v2 )
+
+static inline loff_t offset_v2_k_offset(const struct offset_v2 *v2)
 {
-	return le64_to_cpu(v2->v) & (~0ULL>>4);
+	return le64_to_cpu(v2->v) & (~0ULL >> 4);
 }
 
-static inline void set_offset_v2_k_offset( struct offset_v2 *v2, loff_t offset ){
-	offset &= (~0ULL>>4);
-	v2->v = (v2->v & cpu_to_le64(15ULL<<60)) | cpu_to_le64(offset);
+static inline void set_offset_v2_k_offset(struct offset_v2 *v2, loff_t offset)
+{
+	offset &= (~0ULL >> 4);
+	v2->v = (v2->v & cpu_to_le64(15ULL << 60)) | cpu_to_le64(offset);
 }
 
 /* Key of an item determines its location in the S+tree, and
    is composed of 4 components */
 struct reiserfs_key {
-    __le32 k_dir_id;    /* packing locality: by default parent
-			  directory object id */
-    __le32 k_objectid;  /* object identifier */
-    union {
-	struct offset_v1 k_offset_v1;
-	struct offset_v2 k_offset_v2;
-    } __attribute__ ((__packed__)) u;
+	__le32 k_dir_id;	/* packing locality: by default parent
+				   directory object id */
+	__le32 k_objectid;	/* object identifier */
+	union {
+		struct offset_v1 k_offset_v1;
+		struct offset_v2 k_offset_v2;
+	} __attribute__ ((__packed__)) u;
 } __attribute__ ((__packed__));
 
 struct in_core_key {
-    __u32 k_dir_id;    /* packing locality: by default parent
-			  directory object id */
-    __u32 k_objectid;  /* object identifier */
-    __u64 k_offset;
-    __u8 k_type;
+	__u32 k_dir_id;		/* packing locality: by default parent
+				   directory object id */
+	__u32 k_objectid;	/* object identifier */
+	__u64 k_offset;
+	__u8 k_type;
 };
 
 struct cpu_key {
-    struct in_core_key on_disk_key;
-    int version;
-    int key_length; /* 3 in all cases but direct2indirect and
-		       indirect2direct conversion */
+	struct in_core_key on_disk_key;
+	int version;
+	int key_length;		/* 3 in all cases but direct2indirect and
+				   indirect2direct conversion */
 };
 
 /* Our function for comparing keys can compare keys of different
@@ -475,8 +466,7 @@ struct cpu_key {
     indirect items) and specifies the location of the item itself
     within the block.  */
 
-struct item_head
-{
+struct item_head {
 	/* Everything in the tree is found by searching for it based on
 	 * its key.*/
 	struct reiserfs_key ih_key;
@@ -492,13 +482,13 @@ struct item_head
 		   number of directory entries in the directory item. */
 		__le16 ih_entry_count;
 	} __attribute__ ((__packed__)) u;
-	__le16 ih_item_len;           /* total size of the item body */
-	__le16 ih_item_location;      /* an offset to the item body
-				      * within the block */
-	__le16 ih_version;	     /* 0 for all old items, 2 for new
-					ones. Highest bit is set by fsck
-					temporary, cleaned after all
-					done */
+	__le16 ih_item_len;	/* total size of the item body */
+	__le16 ih_item_location;	/* an offset to the item body
+					 * within the block */
+	__le16 ih_version;	/* 0 for all old items, 2 for new
+				   ones. Highest bit is set by fsck
+				   temporary, cleaned after all
+				   done */
 } __attribute__ ((__packed__));
 /* size of item header     */
 #define IH_SIZE (sizeof(struct item_head))
@@ -515,7 +505,6 @@ struct item_head
 #define put_ih_location(ih, val)     do { (ih)->ih_item_location = cpu_to_le16(val); } while (0)
 #define put_ih_item_len(ih, val)     do { (ih)->ih_item_len = cpu_to_le16(val); } while (0)
 
-
 #define unreachable_item(ih) (ih_version(ih) & (1 << 15))
 
 #define get_ih_free_space(ih) (ih_version (ih) == KEY_FORMAT_3_6 ? 0 : ih_free_space (ih))
@@ -537,40 +526,48 @@ struct item_head
 #define V1_INDIRECT_UNIQUENESS 0xfffffffe
 #define V1_DIRECT_UNIQUENESS 0xffffffff
 #define V1_DIRENTRY_UNIQUENESS 500
-#define V1_ANY_UNIQUENESS 555 // FIXME: comment is required
+#define V1_ANY_UNIQUENESS 555	// FIXME: comment is required
 
 //
 // here are conversion routines
 //
-static inline int uniqueness2type (__u32 uniqueness) CONSTF;
-static inline int uniqueness2type (__u32 uniqueness)
+static inline int uniqueness2type(__u32 uniqueness) CONSTF;
+static inline int uniqueness2type(__u32 uniqueness)
 {
-    switch ((int)uniqueness) {
-    case V1_SD_UNIQUENESS: return TYPE_STAT_DATA;
-    case V1_INDIRECT_UNIQUENESS: return TYPE_INDIRECT;
-    case V1_DIRECT_UNIQUENESS: return TYPE_DIRECT;
-    case V1_DIRENTRY_UNIQUENESS: return TYPE_DIRENTRY;
-    default:
-	    reiserfs_warning (NULL, "vs-500: unknown uniqueness %d",
-			      uniqueness);
+	switch ((int)uniqueness) {
+	case V1_SD_UNIQUENESS:
+		return TYPE_STAT_DATA;
+	case V1_INDIRECT_UNIQUENESS:
+		return TYPE_INDIRECT;
+	case V1_DIRECT_UNIQUENESS:
+		return TYPE_DIRECT;
+	case V1_DIRENTRY_UNIQUENESS:
+		return TYPE_DIRENTRY;
+	default:
+		reiserfs_warning(NULL, "vs-500: unknown uniqueness %d",
+				 uniqueness);
 	case V1_ANY_UNIQUENESS:
-	    return TYPE_ANY;
-    }
+		return TYPE_ANY;
+	}
 }
 
-static inline __u32 type2uniqueness (int type) CONSTF;
-static inline __u32 type2uniqueness (int type)
+static inline __u32 type2uniqueness(int type) CONSTF;
+static inline __u32 type2uniqueness(int type)
 {
-    switch (type) {
-    case TYPE_STAT_DATA: return V1_SD_UNIQUENESS;
-    case TYPE_INDIRECT: return V1_INDIRECT_UNIQUENESS;
-    case TYPE_DIRECT: return V1_DIRECT_UNIQUENESS;
-    case TYPE_DIRENTRY: return V1_DIRENTRY_UNIQUENESS;
-    default:
-	    reiserfs_warning (NULL, "vs-501: unknown type %d", type);
+	switch (type) {
+	case TYPE_STAT_DATA:
+		return V1_SD_UNIQUENESS;
+	case TYPE_INDIRECT:
+		return V1_INDIRECT_UNIQUENESS;
+	case TYPE_DIRECT:
+		return V1_DIRECT_UNIQUENESS;
+	case TYPE_DIRENTRY:
+		return V1_DIRENTRY_UNIQUENESS;
+	default:
+		reiserfs_warning(NULL, "vs-501: unknown type %d", type);
 	case TYPE_ANY:
-	    return V1_ANY_UNIQUENESS;
-    }
+		return V1_ANY_UNIQUENESS;
+	}
 }
 
 //
@@ -578,57 +575,56 @@ static inline __u32 type2uniqueness (int
 // there is no way to get version of object from key, so, provide
 // version to these defines
 //
-static inline loff_t le_key_k_offset (int version, const struct reiserfs_key * key)
+static inline loff_t le_key_k_offset(int version,
+				     const struct reiserfs_key *key)
 {
-    return (version == KEY_FORMAT_3_5) ?
-        le32_to_cpu( key->u.k_offset_v1.k_offset ) :
-	offset_v2_k_offset( &(key->u.k_offset_v2) );
+	return (version == KEY_FORMAT_3_5) ?
+	    le32_to_cpu(key->u.k_offset_v1.k_offset) :
+	    offset_v2_k_offset(&(key->u.k_offset_v2));
 }
 
-static inline loff_t le_ih_k_offset (const struct item_head * ih)
+static inline loff_t le_ih_k_offset(const struct item_head *ih)
 {
-    return le_key_k_offset (ih_version (ih), &(ih->ih_key));
+	return le_key_k_offset(ih_version(ih), &(ih->ih_key));
 }
 
-static inline loff_t le_key_k_type (int version, const struct reiserfs_key * key)
+static inline loff_t le_key_k_type(int version, const struct reiserfs_key *key)
 {
-    return (version == KEY_FORMAT_3_5) ?
-        uniqueness2type( le32_to_cpu( key->u.k_offset_v1.k_uniqueness)) :
-	offset_v2_k_type( &(key->u.k_offset_v2) );
+	return (version == KEY_FORMAT_3_5) ?
+	    uniqueness2type(le32_to_cpu(key->u.k_offset_v1.k_uniqueness)) :
+	    offset_v2_k_type(&(key->u.k_offset_v2));
 }
 
-static inline loff_t le_ih_k_type (const struct item_head * ih)
+static inline loff_t le_ih_k_type(const struct item_head *ih)
 {
-    return le_key_k_type (ih_version (ih), &(ih->ih_key));
+	return le_key_k_type(ih_version(ih), &(ih->ih_key));
 }
 
-
-static inline void set_le_key_k_offset (int version, struct reiserfs_key * key, loff_t offset)
+static inline void set_le_key_k_offset(int version, struct reiserfs_key *key,
+				       loff_t offset)
 {
-    (version == KEY_FORMAT_3_5) ?
-        (void)(key->u.k_offset_v1.k_offset = cpu_to_le32 (offset)) : /* jdm check */
-	(void)(set_offset_v2_k_offset( &(key->u.k_offset_v2), offset ));
+	(version == KEY_FORMAT_3_5) ? (void)(key->u.k_offset_v1.k_offset = cpu_to_le32(offset)) :	/* jdm check */
+	    (void)(set_offset_v2_k_offset(&(key->u.k_offset_v2), offset));
 }
 
-
-static inline void set_le_ih_k_offset (struct item_head * ih, loff_t offset)
+static inline void set_le_ih_k_offset(struct item_head *ih, loff_t offset)
 {
-    set_le_key_k_offset (ih_version (ih), &(ih->ih_key), offset);
+	set_le_key_k_offset(ih_version(ih), &(ih->ih_key), offset);
 }
 
-
-static inline void set_le_key_k_type (int version, struct reiserfs_key * key, int type)
+static inline void set_le_key_k_type(int version, struct reiserfs_key *key,
+				     int type)
 {
-    (version == KEY_FORMAT_3_5) ?
-        (void)(key->u.k_offset_v1.k_uniqueness = cpu_to_le32(type2uniqueness(type))):
-	(void)(set_offset_v2_k_type( &(key->u.k_offset_v2), type ));
+	(version == KEY_FORMAT_3_5) ?
+	    (void)(key->u.k_offset_v1.k_uniqueness =
+		   cpu_to_le32(type2uniqueness(type)))
+	    : (void)(set_offset_v2_k_type(&(key->u.k_offset_v2), type));
 }
-static inline void set_le_ih_k_type (struct item_head * ih, int type)
+static inline void set_le_ih_k_type(struct item_head *ih, int type)
 {
-    set_le_key_k_type (ih_version (ih), &(ih->ih_key), type);
+	set_le_key_k_type(ih_version(ih), &(ih->ih_key), type);
 }
 
-
 #define is_direntry_le_key(version,key) (le_key_k_type (version, key) == TYPE_DIRENTRY)
 #define is_direct_le_key(version,key) (le_key_k_type (version, key) == TYPE_DIRECT)
 #define is_indirect_le_key(version,key) (le_key_k_type (version, key) == TYPE_INDIRECT)
@@ -642,34 +638,32 @@ static inline void set_le_ih_k_type (str
 #define is_indirect_le_ih(ih) is_indirect_le_key (ih_version(ih), &((ih)->ih_key))
 #define is_statdata_le_ih(ih) is_statdata_le_key (ih_version (ih), &((ih)->ih_key))
 
-
-
 //
 // key is pointer to cpu key, result is cpu
 //
-static inline loff_t cpu_key_k_offset (const struct cpu_key * key)
+static inline loff_t cpu_key_k_offset(const struct cpu_key *key)
 {
-    return key->on_disk_key.k_offset;
+	return key->on_disk_key.k_offset;
 }
 
-static inline loff_t cpu_key_k_type (const struct cpu_key * key)
+static inline loff_t cpu_key_k_type(const struct cpu_key *key)
 {
-    return key->on_disk_key.k_type;
+	return key->on_disk_key.k_type;
 }
 
-static inline void set_cpu_key_k_offset (struct cpu_key * key, loff_t offset)
+static inline void set_cpu_key_k_offset(struct cpu_key *key, loff_t offset)
 {
 	key->on_disk_key.k_offset = offset;
 }
 
-static inline void set_cpu_key_k_type (struct cpu_key * key, int type)
+static inline void set_cpu_key_k_type(struct cpu_key *key, int type)
 {
 	key->on_disk_key.k_type = type;
 }
 
-static inline void cpu_key_k_offset_dec (struct cpu_key * key)
+static inline void cpu_key_k_offset_dec(struct cpu_key *key)
 {
-	key->on_disk_key.k_offset --;
+	key->on_disk_key.k_offset--;
 }
 
 #define is_direntry_cpu_key(key) (cpu_key_k_type (key) == TYPE_DIRENTRY)
@@ -677,34 +671,25 @@ static inline void cpu_key_k_offset_dec 
 #define is_indirect_cpu_key(key) (cpu_key_k_type (key) == TYPE_INDIRECT)
 #define is_statdata_cpu_key(key) (cpu_key_k_type (key) == TYPE_STAT_DATA)
 
-
 /* are these used ? */
 #define is_direntry_cpu_ih(ih) (is_direntry_cpu_key (&((ih)->ih_key)))
 #define is_direct_cpu_ih(ih) (is_direct_cpu_key (&((ih)->ih_key)))
 #define is_indirect_cpu_ih(ih) (is_indirect_cpu_key (&((ih)->ih_key)))
 #define is_statdata_cpu_ih(ih) (is_statdata_cpu_key (&((ih)->ih_key)))
 
-
-
-
-
 #define I_K_KEY_IN_ITEM(p_s_ih, p_s_key, n_blocksize) \
     ( ! COMP_SHORT_KEYS(p_s_ih, p_s_key) && \
           I_OFF_BYTE_IN_ITEM(p_s_ih, k_offset (p_s_key), n_blocksize) )
 
-/* maximal length of item */ 
+/* maximal length of item */
 #define MAX_ITEM_LEN(block_size) (block_size - BLKH_SIZE - IH_SIZE)
 #define MIN_ITEM_LEN 1
 
-
 /* object identifier for root dir */
 #define REISERFS_ROOT_OBJECTID 2
 #define REISERFS_ROOT_PARENT_OBJECTID 1
 extern struct reiserfs_key root_key;
 
-
-
-
 /* 
  * Picture represents a leaf of the S+tree
  *  ______________________________________________________
@@ -716,13 +701,13 @@ extern struct reiserfs_key root_key;
 
 /* Header of a disk block.  More precisely, header of a formatted leaf
    or internal node, and not the header of an unformatted node. */
-struct block_head {       
-  __le16 blk_level;        /* Level of a block in the tree. */
-  __le16 blk_nr_item;      /* Number of keys/items in a block. */
-  __le16 blk_free_space;   /* Block free space in bytes. */
-  __le16 blk_reserved;
-				/* dump this in v4/planA */
-  struct reiserfs_key  blk_right_delim_key; /* kept only for compatibility */
+struct block_head {
+	__le16 blk_level;	/* Level of a block in the tree. */
+	__le16 blk_nr_item;	/* Number of keys/items in a block. */
+	__le16 blk_free_space;	/* Block free space in bytes. */
+	__le16 blk_reserved;
+	/* dump this in v4/planA */
+	struct reiserfs_key blk_right_delim_key;	/* kept only for compatibility */
 };
 
 #define BLKH_SIZE                     (sizeof(struct block_head))
@@ -741,12 +726,12 @@ struct block_head {       
  * values for blk_level field of the struct block_head
  */
 
-#define FREE_LEVEL 0 /* when node gets removed from the tree its
-			blk_level is set to FREE_LEVEL. It is then
-			used to see whether the node is still in the
-			tree */
+#define FREE_LEVEL 0		/* when node gets removed from the tree its
+				   blk_level is set to FREE_LEVEL. It is then
+				   used to see whether the node is still in the
+				   tree */
 
-#define DISK_LEAF_NODE_LEVEL  1 /* Leaf node level.*/
+#define DISK_LEAF_NODE_LEVEL  1	/* Leaf node level. */
 
 /* Given the buffer head of a formatted node, resolve to the block head of that node. */
 #define B_BLK_HEAD(p_s_bh)            ((struct block_head *)((p_s_bh)->b_data))
@@ -759,7 +744,6 @@ struct block_head {       
 #define PUT_B_LEVEL(p_s_bh,val)       do { set_blkh_level(B_BLK_HEAD(p_s_bh),val); } while (0)
 #define PUT_B_FREE_SPACE(p_s_bh,val)  do { set_blkh_free_space(B_BLK_HEAD(p_s_bh),val); } while (0)
 
-
 /* Get right delimiting key. -- little endian */
 #define B_PRIGHT_DELIM_KEY(p_s_bh)   (&(blk_right_delim_key(B_BLK_HEAD(p_s_bh))
 
@@ -770,41 +754,36 @@ struct block_head {       
 #define B_IS_KEYS_LEVEL(p_s_bh)      (B_LEVEL(p_s_bh) > DISK_LEAF_NODE_LEVEL \
                                             && B_LEVEL(p_s_bh) <= MAX_HEIGHT)
 
-
-
-
 /***************************************************************************/
 /*                             STAT DATA                                   */
 /***************************************************************************/
 
-
 //
 // old stat data is 32 bytes long. We are going to distinguish new one by
 // different size
 //
-struct stat_data_v1
-{
-    __le16 sd_mode;	/* file type, permissions */
-    __le16 sd_nlink;	/* number of hard links */
-    __le16 sd_uid;		/* owner */
-    __le16 sd_gid;		/* group */
-    __le32 sd_size;	/* file size */
-    __le32 sd_atime;	/* time of last access */
-    __le32 sd_mtime;	/* time file was last modified  */
-    __le32 sd_ctime;	/* time inode (stat data) was last changed (except changes to sd_atime and sd_mtime) */
-    union {
-	__le32 sd_rdev;
-	__le32 sd_blocks;	/* number of blocks file uses */
-    } __attribute__ ((__packed__)) u;
-    __le32 sd_first_direct_byte; /* first byte of file which is stored
-				   in a direct item: except that if it
-				   equals 1 it is a symlink and if it
-				   equals ~(__u32)0 there is no
-				   direct item.  The existence of this
-				   field really grates on me. Let's
-				   replace it with a macro based on
-				   sd_size and our tail suppression
-				   policy.  Someday.  -Hans */
+struct stat_data_v1 {
+	__le16 sd_mode;		/* file type, permissions */
+	__le16 sd_nlink;	/* number of hard links */
+	__le16 sd_uid;		/* owner */
+	__le16 sd_gid;		/* group */
+	__le32 sd_size;		/* file size */
+	__le32 sd_atime;	/* time of last access */
+	__le32 sd_mtime;	/* time file was last modified  */
+	__le32 sd_ctime;	/* time inode (stat data) was last changed (except changes to sd_atime and sd_mtime) */
+	union {
+		__le32 sd_rdev;
+		__le32 sd_blocks;	/* number of blocks file uses */
+	} __attribute__ ((__packed__)) u;
+	__le32 sd_first_direct_byte;	/* first byte of file which is stored
+					   in a direct item: except that if it
+					   equals 1 it is a symlink and if it
+					   equals ~(__u32)0 there is no
+					   direct item.  The existence of this
+					   field really grates on me. Let's
+					   replace it with a macro based on
+					   sd_size and our tail suppression
+					   policy.  Someday.  -Hans */
 } __attribute__ ((__packed__));
 
 #define SD_V1_SIZE              (sizeof(struct stat_data_v1))
@@ -862,29 +841,29 @@ struct stat_data_v1
 /* Stat Data on disk (reiserfs version of UFS disk inode minus the
    address blocks) */
 struct stat_data {
-    __le16 sd_mode;	/* file type, permissions */
-    __le16 sd_attrs;     /* persistent inode flags */
-    __le32 sd_nlink;	/* number of hard links */
-    __le64 sd_size;	/* file size */
-    __le32 sd_uid;		/* owner */
-    __le32 sd_gid;		/* group */
-    __le32 sd_atime;	/* time of last access */
-    __le32 sd_mtime;	/* time file was last modified  */
-    __le32 sd_ctime;	/* time inode (stat data) was last changed (except changes to sd_atime and sd_mtime) */
-    __le32 sd_blocks;
-    union {
-	__le32 sd_rdev;
-	__le32 sd_generation;
-      //__le32 sd_first_direct_byte;
-      /* first byte of file which is stored in a
-				       direct item: except that if it equals 1
-				       it is a symlink and if it equals
-				       ~(__u32)0 there is no direct item.  The
-				       existence of this field really grates
-				       on me. Let's replace it with a macro
-				       based on sd_size and our tail
-				       suppression policy? */
-  } __attribute__ ((__packed__)) u;
+	__le16 sd_mode;		/* file type, permissions */
+	__le16 sd_attrs;	/* persistent inode flags */
+	__le32 sd_nlink;	/* number of hard links */
+	__le64 sd_size;		/* file size */
+	__le32 sd_uid;		/* owner */
+	__le32 sd_gid;		/* group */
+	__le32 sd_atime;	/* time of last access */
+	__le32 sd_mtime;	/* time file was last modified  */
+	__le32 sd_ctime;	/* time inode (stat data) was last changed (except changes to sd_atime and sd_mtime) */
+	__le32 sd_blocks;
+	union {
+		__le32 sd_rdev;
+		__le32 sd_generation;
+		//__le32 sd_first_direct_byte;
+		/* first byte of file which is stored in a
+		   direct item: except that if it equals 1
+		   it is a symlink and if it equals
+		   ~(__u32)0 there is no direct item.  The
+		   existence of this field really grates
+		   on me. Let's replace it with a macro
+		   based on sd_size and our tail
+		   suppression policy? */
+	} __attribute__ ((__packed__)) u;
 } __attribute__ ((__packed__));
 //
 // this is 44 bytes long
@@ -919,7 +898,6 @@ struct stat_data {
 #define sd_v2_attrs(sdp)         (le16_to_cpu((sdp)->sd_attrs))
 #define set_sd_v2_attrs(sdp,v)   ((sdp)->sd_attrs = cpu_to_le16(v))
 
-
 /***************************************************************************/
 /*                      DIRECTORY STRUCTURE                                */
 /***************************************************************************/
@@ -954,17 +932,14 @@ struct stat_data {
 /* NOT IMPLEMENTED:   
    Directory will someday contain stat data of object */
 
-
-
-struct reiserfs_de_head
-{
-  __le32 deh_offset;		/* third component of the directory entry key */
-  __le32 deh_dir_id;		/* objectid of the parent directory of the object, that is referenced
-					   by directory entry */
-  __le32 deh_objectid;		/* objectid of the object, that is referenced by directory entry */
-  __le16 deh_location;		/* offset of name in the whole item */
-  __le16 deh_state;		/* whether 1) entry contains stat data (for future), and 2) whether
-					   entry is hidden (unlinked) */
+struct reiserfs_de_head {
+	__le32 deh_offset;	/* third component of the directory entry key */
+	__le32 deh_dir_id;	/* objectid of the parent directory of the object, that is referenced
+				   by directory entry */
+	__le32 deh_objectid;	/* objectid of the object, that is referenced by directory entry */
+	__le16 deh_location;	/* offset of name in the whole item */
+	__le16 deh_state;	/* whether 1) entry contains stat data (for future), and 2) whether
+				   entry is hidden (unlinked) */
 } __attribute__ ((__packed__));
 #define DEH_SIZE                  sizeof(struct reiserfs_de_head)
 #define deh_offset(p_deh)         (le32_to_cpu((p_deh)->deh_offset))
@@ -986,7 +961,7 @@ struct reiserfs_de_head
 /* old format directories have this size when empty */
 #define EMPTY_DIR_SIZE_V1 (DEH_SIZE * 2 + 3)
 
-#define DEH_Statdata 0			/* not used now */
+#define DEH_Statdata 0		/* not used now */
 #define DEH_Visible 2
 
 /* 64 bit systems (and the S/390) need to be aligned explicitly -jdm */
@@ -1023,10 +998,10 @@ struct reiserfs_de_head
 #define de_visible(deh)	    	    test_bit_unaligned (DEH_Visible, &((deh)->deh_state))
 #define de_hidden(deh)	    	    !test_bit_unaligned (DEH_Visible, &((deh)->deh_state))
 
-extern void make_empty_dir_item_v1 (char * body, __le32 dirid, __le32 objid,
-				    __le32 par_dirid, __le32 par_objid);
-extern void make_empty_dir_item (char * body, __le32 dirid, __le32 objid,
-				 __le32 par_dirid, __le32 par_objid);
+extern void make_empty_dir_item_v1(char *body, __le32 dirid, __le32 objid,
+				   __le32 par_dirid, __le32 par_objid);
+extern void make_empty_dir_item(char *body, __le32 dirid, __le32 objid,
+				__le32 par_dirid, __le32 par_objid);
 
 /* array of the entry headers */
  /* get item body */
@@ -1043,53 +1018,48 @@ extern void make_empty_dir_item (char * 
 #define I_DEH_N_ENTRY_LENGTH(ih,deh,i) \
 ((i) ? (deh_location((deh)-1) - deh_location((deh))) : (ih_item_len((ih)) - deh_location((deh))))
 */
-static inline int entry_length (const struct buffer_head * bh, 
-								const struct item_head * ih, int pos_in_item)
+static inline int entry_length(const struct buffer_head *bh,
+			       const struct item_head *ih, int pos_in_item)
 {
-    struct reiserfs_de_head * deh;
+	struct reiserfs_de_head *deh;
 
-    deh = B_I_DEH (bh, ih) + pos_in_item;
-    if (pos_in_item)
-	return deh_location(deh-1) - deh_location(deh);
+	deh = B_I_DEH(bh, ih) + pos_in_item;
+	if (pos_in_item)
+		return deh_location(deh - 1) - deh_location(deh);
 
-    return ih_item_len(ih) - deh_location(deh);
+	return ih_item_len(ih) - deh_location(deh);
 }
 
-
-
 /* number of entries in the directory item, depends on ENTRY_COUNT being at the start of directory dynamic data. */
 #define I_ENTRY_COUNT(ih) (ih_entry_count((ih)))
 
-
 /* name by bh, ih and entry_num */
 #define B_I_E_NAME(bh,ih,entry_num) ((char *)(bh->b_data + ih_location(ih) + deh_location(B_I_DEH(bh,ih)+(entry_num))))
 
 // two entries per block (at least)
 #define REISERFS_MAX_NAME(block_size) 255
 
-
 /* this structure is used for operations on directory entries. It is
    not a disk structure. */
 /* When reiserfs_find_entry or search_by_entry_key find directory
    entry, they return filled reiserfs_dir_entry structure */
-struct reiserfs_dir_entry
-{
-  struct buffer_head * de_bh;
-  int de_item_num;
-  struct item_head * de_ih;
-  int de_entry_num;
-  struct reiserfs_de_head * de_deh;
-  int de_entrylen;
-  int de_namelen;
-  char * de_name;
-  char * de_gen_number_bit_string;
+struct reiserfs_dir_entry {
+	struct buffer_head *de_bh;
+	int de_item_num;
+	struct item_head *de_ih;
+	int de_entry_num;
+	struct reiserfs_de_head *de_deh;
+	int de_entrylen;
+	int de_namelen;
+	char *de_name;
+	char *de_gen_number_bit_string;
 
-  __u32 de_dir_id;
-  __u32 de_objectid;
+	__u32 de_dir_id;
+	__u32 de_objectid;
 
-  struct cpu_key de_entry_key;
+	struct cpu_key de_entry_key;
 };
-   
+
 /* these defines are useful when a particular member of a reiserfs_dir_entry is needed */
 
 /* pointer to file name, stored in entry */
@@ -1099,8 +1069,6 @@ struct reiserfs_dir_entry
 #define I_DEH_N_ENTRY_FILE_NAME_LENGTH(ih,deh,entry_num) \
 (I_DEH_N_ENTRY_LENGTH (ih, deh, entry_num) - (de_with_sd (deh) ? SD_SIZE : 0))
 
-
-
 /* hash value occupies bits from 7 up to 30 */
 #define GET_HASH_VALUE(offset) ((offset) & 0x7fffff80LL)
 /* generation number occupies 7 bits starting from 0 up to 6 */
@@ -1109,7 +1077,6 @@ struct reiserfs_dir_entry
 
 #define SET_GENERATION_NUMBER(offset,gen_number) (GET_HASH_VALUE(offset)|(gen_number))
 
-
 /*
  * Picture represents an internal node of the reiserfs tree
  *  ______________________________________________________
@@ -1125,9 +1092,9 @@ struct reiserfs_dir_entry
 /* Disk child pointer: The pointer from an internal node of the tree
    to a node that is on disk. */
 struct disk_child {
-  __le32       dc_block_number;              /* Disk child's block number. */
-  __le16       dc_size;		            /* Disk child's used space.   */
-  __le16       dc_reserved;
+	__le32 dc_block_number;	/* Disk child's block number. */
+	__le16 dc_size;		/* Disk child's used space.   */
+	__le16 dc_reserved;
 };
 
 #define DC_SIZE (sizeof(struct disk_child))
@@ -1144,7 +1111,7 @@ struct disk_child {
 #define B_N_CHILD_NUM(p_s_bh,n_pos) (dc_block_number(B_N_CHILD(p_s_bh,n_pos)))
 #define PUT_B_N_CHILD_NUM(p_s_bh,n_pos, val) (put_dc_block_number(B_N_CHILD(p_s_bh,n_pos), val ))
 
- /* maximal value of field child_size in structure disk_child */ 
+ /* maximal value of field child_size in structure disk_child */
  /* child size is the combined size of all items and their headers */
 #define MAX_CHILD_SIZE(bh) ((int)( (bh)->b_size - BLKH_SIZE ))
 
@@ -1159,7 +1126,6 @@ struct disk_child {
 /*                      PATH STRUCTURES AND DEFINES                        */
 /***************************************************************************/
 
-
 /* Search_by_key fills up the path from the root to the leaf as it descends the tree looking for the
    key.  It uses reiserfs_bread to try to find buffers in the cache given their block number.  If it
    does not find them in the cache it reads them from disk.  For each node search_by_key finds using
@@ -1168,20 +1134,18 @@ struct disk_child {
    is looking through a leaf node bin_search will find the position of the item which has key either
    equal to given key, or which is the maximal key less than the given key. */
 
-struct  path_element  {
-  struct buffer_head *	pe_buffer;    /* Pointer to the buffer at the path in the tree. */
-  int         		pe_position;  /* Position in the tree node which is placed in the */
-                                      /* buffer above.                                  */
+struct path_element {
+	struct buffer_head *pe_buffer;	/* Pointer to the buffer at the path in the tree. */
+	int pe_position;	/* Position in the tree node which is placed in the */
+	/* buffer above.                                  */
 };
 
-#define MAX_HEIGHT 5 /* maximal height of a tree. don't change this without changing JOURNAL_PER_BALANCE_CNT */
-#define EXTENDED_MAX_HEIGHT         7 /* Must be equals MAX_HEIGHT + FIRST_PATH_ELEMENT_OFFSET */
-#define FIRST_PATH_ELEMENT_OFFSET   2 /* Must be equal to at least 2. */
-
-#define ILLEGAL_PATH_ELEMENT_OFFSET 1 /* Must be equal to FIRST_PATH_ELEMENT_OFFSET - 1 */
-#define MAX_FEB_SIZE 6   /* this MUST be MAX_HEIGHT + 1. See about FEB below */
-
+#define MAX_HEIGHT 5		/* maximal height of a tree. don't change this without changing JOURNAL_PER_BALANCE_CNT */
+#define EXTENDED_MAX_HEIGHT         7	/* Must be equals MAX_HEIGHT + FIRST_PATH_ELEMENT_OFFSET */
+#define FIRST_PATH_ELEMENT_OFFSET   2	/* Must be equal to at least 2. */
 
+#define ILLEGAL_PATH_ELEMENT_OFFSET 1	/* Must be equal to FIRST_PATH_ELEMENT_OFFSET - 1 */
+#define MAX_FEB_SIZE 6		/* this MUST be MAX_HEIGHT + 1. See about FEB below */
 
 /* We need to keep track of who the ancestors of nodes are.  When we
    perform a search we record which nodes were visited while
@@ -1200,14 +1164,14 @@ excessive effort to avoid disturbing the
 gods only know how we are going to SMP the code that uses them.
 znodes are the way! */
 
-#define PATH_READA	0x1 /* do read ahead */
-#define PATH_READA_BACK 0x2 /* read backwards */
+#define PATH_READA	0x1	/* do read ahead */
+#define PATH_READA_BACK 0x2	/* read backwards */
 
-struct  path {
-  int                   path_length;                      	/* Length of the array above.   */
-  int			reada;
-  struct  path_element  path_elements[EXTENDED_MAX_HEIGHT];	/* Array of the path elements.  */
-  int			pos_in_item;
+struct path {
+	int path_length;	/* Length of the array above.   */
+	int reada;
+	struct path_element path_elements[EXTENDED_MAX_HEIGHT];	/* Array of the path elements.  */
+	int pos_in_item;
 };
 
 #define pos_in_item(path) ((path)->pos_in_item)
@@ -1224,25 +1188,23 @@ struct path var = {.path_length = ILLEGA
 /* Get position in the element at the path by path and path position. */
 #define PATH_OFFSET_POSITION(p_s_path,n_offset) (PATH_OFFSET_PELEMENT(p_s_path,n_offset)->pe_position)
 
-
 #define PATH_PLAST_BUFFER(p_s_path) (PATH_OFFSET_PBUFFER((p_s_path), (p_s_path)->path_length))
 				/* you know, to the person who didn't
-                                   write this the macro name does not
-                                   at first suggest what it does.
-                                   Maybe POSITION_FROM_PATH_END? Or
-                                   maybe we should just focus on
-                                   dumping paths... -Hans */
+				   write this the macro name does not
+				   at first suggest what it does.
+				   Maybe POSITION_FROM_PATH_END? Or
+				   maybe we should just focus on
+				   dumping paths... -Hans */
 #define PATH_LAST_POSITION(p_s_path) (PATH_OFFSET_POSITION((p_s_path), (p_s_path)->path_length))
 
-
 #define PATH_PITEM_HEAD(p_s_path)    B_N_PITEM_HEAD(PATH_PLAST_BUFFER(p_s_path),PATH_LAST_POSITION(p_s_path))
 
 /* in do_balance leaf has h == 0 in contrast with path structure,
    where root has level == 0. That is why we need these defines */
 #define PATH_H_PBUFFER(p_s_path, h) PATH_OFFSET_PBUFFER (p_s_path, p_s_path->path_length - (h))	/* tb->S[h] */
-#define PATH_H_PPARENT(path, h) PATH_H_PBUFFER (path, (h) + 1)			/* tb->F[h] or tb->S[0]->b_parent */
-#define PATH_H_POSITION(path, h) PATH_OFFSET_POSITION (path, path->path_length - (h))	
-#define PATH_H_B_ITEM_ORDER(path, h) PATH_H_POSITION(path, h + 1)		/* tb->S[h]->b_item_order */
+#define PATH_H_PPARENT(path, h) PATH_H_PBUFFER (path, (h) + 1)	/* tb->F[h] or tb->S[0]->b_parent */
+#define PATH_H_POSITION(path, h) PATH_OFFSET_POSITION (path, path->path_length - (h))
+#define PATH_H_B_ITEM_ORDER(path, h) PATH_H_POSITION(path, h + 1)	/* tb->S[h]->b_item_order */
 
 #define PATH_H_PATH_OFFSET(p_s_path, n_h) ((p_s_path)->path_length - (n_h))
 
@@ -1253,7 +1215,6 @@ struct path var = {.path_length = ILLEGA
 #define item_moved(ih,path) comp_items(ih, path)
 #define path_changed(ih,path) comp_items (ih, path)
 
-
 /***************************************************************************/
 /*                       MISC                                              */
 /***************************************************************************/
@@ -1272,30 +1233,26 @@ struct path var = {.path_length = ILLEGA
 // reiserfs version 2 has max offset 60 bits. Version 1 - 32 bit offset
 #define U32_MAX (~(__u32)0)
 
-static inline loff_t max_reiserfs_offset (struct inode * inode)
+static inline loff_t max_reiserfs_offset(struct inode *inode)
 {
-    if (get_inode_item_key_version(inode) == KEY_FORMAT_3_5)
-	return (loff_t)U32_MAX;
+	if (get_inode_item_key_version(inode) == KEY_FORMAT_3_5)
+		return (loff_t) U32_MAX;
 
-    return (loff_t)((~(__u64)0) >> 4);
+	return (loff_t) ((~(__u64) 0) >> 4);
 }
 
-
 /*#define MAX_KEY_UNIQUENESS	MAX_UL_INT*/
 #define MAX_KEY_OBJECTID	MAX_UL_INT
 
-
 #define MAX_B_NUM  MAX_UL_INT
 #define MAX_FC_NUM MAX_US_INT
 
-
 /* the purpose is to detect overflow of an unsigned short */
 #define REISERFS_LINK_MAX (MAX_US_INT - 1000)
 
-
 /* The following defines are used in reiserfs_insert_item and reiserfs_append_item  */
-#define REISERFS_KERNEL_MEM		0	/* reiserfs kernel memory mode	*/
-#define REISERFS_USER_MEM		1	/* reiserfs user memory mode		*/
+#define REISERFS_KERNEL_MEM		0	/* reiserfs kernel memory mode  */
+#define REISERFS_USER_MEM		1	/* reiserfs user memory mode            */
 
 #define fs_generation(s) (REISERFS_SB(s)->s_generation_counter)
 #define get_generation(s) atomic_read (&fs_generation(s))
@@ -1303,7 +1260,6 @@ static inline loff_t max_reiserfs_offset
 #define __fs_changed(gen,s) (gen != get_generation (s))
 #define fs_changed(gen,s) ({cond_resched(); __fs_changed(gen, s);})
 
-
 /***************************************************************************/
 /*                  FIXATE NODES                                           */
 /***************************************************************************/
@@ -1324,38 +1280,34 @@ static inline loff_t max_reiserfs_offset
    calculating what we can shift to neighbors and how many nodes we
    have to have if we do not any shiftings, if we shift to left/right
    neighbor or to both. */
-struct virtual_item
-{
-    int vi_index; // index in the array of item operations
-    unsigned short vi_type;	// left/right mergeability
-    unsigned short vi_item_len;           /* length of item that it will have after balancing */
-    struct item_head * vi_ih;
-    const char * vi_item;     // body of item (old or new)
-    const void * vi_new_data; // 0 always but paste mode
-    void * vi_uarea;    // item specific area
+struct virtual_item {
+	int vi_index;		// index in the array of item operations
+	unsigned short vi_type;	// left/right mergeability
+	unsigned short vi_item_len;	/* length of item that it will have after balancing */
+	struct item_head *vi_ih;
+	const char *vi_item;	// body of item (old or new)
+	const void *vi_new_data;	// 0 always but paste mode
+	void *vi_uarea;		// item specific area
 };
 
-
-struct virtual_node
-{
-  char * vn_free_ptr;		/* this is a pointer to the free space in the buffer */
-  unsigned short vn_nr_item;	/* number of items in virtual node */
-  short vn_size;        	/* size of node , that node would have if it has unlimited size and no balancing is performed */
-  short vn_mode;		/* mode of balancing (paste, insert, delete, cut) */
-  short vn_affected_item_num; 
-  short vn_pos_in_item;
-  struct item_head * vn_ins_ih;	/* item header of inserted item, 0 for other modes */
-  const void * vn_data;
-  struct virtual_item * vn_vi;	/* array of items (including a new one, excluding item to be deleted) */
+struct virtual_node {
+	char *vn_free_ptr;	/* this is a pointer to the free space in the buffer */
+	unsigned short vn_nr_item;	/* number of items in virtual node */
+	short vn_size;		/* size of node , that node would have if it has unlimited size and no balancing is performed */
+	short vn_mode;		/* mode of balancing (paste, insert, delete, cut) */
+	short vn_affected_item_num;
+	short vn_pos_in_item;
+	struct item_head *vn_ins_ih;	/* item header of inserted item, 0 for other modes */
+	const void *vn_data;
+	struct virtual_item *vn_vi;	/* array of items (including a new one, excluding item to be deleted) */
 };
 
 /* used by directory items when creating virtual nodes */
 struct direntry_uarea {
-    int flags;
-    __u16 entry_count;
-    __u16 entry_sizes[1];
-} __attribute__ ((__packed__)) ;
-
+	int flags;
+	__u16 entry_count;
+	__u16 entry_sizes[1];
+} __attribute__ ((__packed__));
 
 /***************************************************************************/
 /*                  TREE BALANCE                                           */
@@ -1378,73 +1330,72 @@ struct direntry_uarea {
 #define MAX_AMOUNT_NEEDED 2
 
 /* someday somebody will prefix every field in this struct with tb_ */
-struct tree_balance
-{
-  int tb_mode;
-  int need_balance_dirty;
-  struct super_block * tb_sb;
-  struct reiserfs_transaction_handle *transaction_handle ;
-  struct path * tb_path;
-  struct buffer_head * L[MAX_HEIGHT];        /* array of left neighbors of nodes in the path */
-  struct buffer_head * R[MAX_HEIGHT];        /* array of right neighbors of nodes in the path*/
-  struct buffer_head * FL[MAX_HEIGHT];       /* array of fathers of the left  neighbors      */
-  struct buffer_head * FR[MAX_HEIGHT];       /* array of fathers of the right neighbors      */
-  struct buffer_head * CFL[MAX_HEIGHT];      /* array of common parents of center node and its left neighbor  */
-  struct buffer_head * CFR[MAX_HEIGHT];      /* array of common parents of center node and its right neighbor */
-
-  struct buffer_head * FEB[MAX_FEB_SIZE]; /* array of empty buffers. Number of buffers in array equals
-					     cur_blknum. */
-  struct buffer_head * used[MAX_FEB_SIZE];
-  struct buffer_head * thrown[MAX_FEB_SIZE];
-  int lnum[MAX_HEIGHT];	/* array of number of items which must be
-			   shifted to the left in order to balance the
-			   current node; for leaves includes item that
-			   will be partially shifted; for internal
-			   nodes, it is the number of child pointers
-			   rather than items. It includes the new item
-			   being created. The code sometimes subtracts
-			   one to get the number of wholly shifted
-			   items for other purposes. */
-  int rnum[MAX_HEIGHT];	/* substitute right for left in comment above */
-  int lkey[MAX_HEIGHT];               /* array indexed by height h mapping the key delimiting L[h] and
-					       S[h] to its item number within the node CFL[h] */
-  int rkey[MAX_HEIGHT];               /* substitute r for l in comment above */
-  int insert_size[MAX_HEIGHT];        /* the number of bytes by we are trying to add or remove from
-					       S[h]. A negative value means removing.  */
-  int blknum[MAX_HEIGHT];             /* number of nodes that will replace node S[h] after
-					       balancing on the level h of the tree.  If 0 then S is
-					       being deleted, if 1 then S is remaining and no new nodes
-					       are being created, if 2 or 3 then 1 or 2 new nodes is
-					       being created */
-
-  /* fields that are used only for balancing leaves of the tree */
-  int cur_blknum;	/* number of empty blocks having been already allocated			*/
-  int s0num;             /* number of items that fall into left most  node when S[0] splits	*/
-  int s1num;             /* number of items that fall into first  new node when S[0] splits	*/
-  int s2num;             /* number of items that fall into second new node when S[0] splits	*/
-  int lbytes;            /* number of bytes which can flow to the left neighbor from the	left	*/
-  /* most liquid item that cannot be shifted from S[0] entirely		*/
-  /* if -1 then nothing will be partially shifted */
-  int rbytes;            /* number of bytes which will flow to the right neighbor from the right	*/
-  /* most liquid item that cannot be shifted from S[0] entirely		*/
-  /* if -1 then nothing will be partially shifted                           */
-  int s1bytes;		/* number of bytes which flow to the first  new node when S[0] splits	*/
-            			/* note: if S[0] splits into 3 nodes, then items do not need to be cut	*/
-  int s2bytes;
-  struct buffer_head * buf_to_free[MAX_FREE_BLOCK]; /* buffers which are to be freed after do_balance finishes by unfix_nodes */
-  char * vn_buf;		/* kmalloced memory. Used to create
+struct tree_balance {
+	int tb_mode;
+	int need_balance_dirty;
+	struct super_block *tb_sb;
+	struct reiserfs_transaction_handle *transaction_handle;
+	struct path *tb_path;
+	struct buffer_head *L[MAX_HEIGHT];	/* array of left neighbors of nodes in the path */
+	struct buffer_head *R[MAX_HEIGHT];	/* array of right neighbors of nodes in the path */
+	struct buffer_head *FL[MAX_HEIGHT];	/* array of fathers of the left  neighbors      */
+	struct buffer_head *FR[MAX_HEIGHT];	/* array of fathers of the right neighbors      */
+	struct buffer_head *CFL[MAX_HEIGHT];	/* array of common parents of center node and its left neighbor  */
+	struct buffer_head *CFR[MAX_HEIGHT];	/* array of common parents of center node and its right neighbor */
+
+	struct buffer_head *FEB[MAX_FEB_SIZE];	/* array of empty buffers. Number of buffers in array equals
+						   cur_blknum. */
+	struct buffer_head *used[MAX_FEB_SIZE];
+	struct buffer_head *thrown[MAX_FEB_SIZE];
+	int lnum[MAX_HEIGHT];	/* array of number of items which must be
+				   shifted to the left in order to balance the
+				   current node; for leaves includes item that
+				   will be partially shifted; for internal
+				   nodes, it is the number of child pointers
+				   rather than items. It includes the new item
+				   being created. The code sometimes subtracts
+				   one to get the number of wholly shifted
+				   items for other purposes. */
+	int rnum[MAX_HEIGHT];	/* substitute right for left in comment above */
+	int lkey[MAX_HEIGHT];	/* array indexed by height h mapping the key delimiting L[h] and
+				   S[h] to its item number within the node CFL[h] */
+	int rkey[MAX_HEIGHT];	/* substitute r for l in comment above */
+	int insert_size[MAX_HEIGHT];	/* the number of bytes by we are trying to add or remove from
+					   S[h]. A negative value means removing.  */
+	int blknum[MAX_HEIGHT];	/* number of nodes that will replace node S[h] after
+				   balancing on the level h of the tree.  If 0 then S is
+				   being deleted, if 1 then S is remaining and no new nodes
+				   are being created, if 2 or 3 then 1 or 2 new nodes is
+				   being created */
+
+	/* fields that are used only for balancing leaves of the tree */
+	int cur_blknum;		/* number of empty blocks having been already allocated                 */
+	int s0num;		/* number of items that fall into left most  node when S[0] splits     */
+	int s1num;		/* number of items that fall into first  new node when S[0] splits     */
+	int s2num;		/* number of items that fall into second new node when S[0] splits     */
+	int lbytes;		/* number of bytes which can flow to the left neighbor from the        left    */
+	/* most liquid item that cannot be shifted from S[0] entirely         */
+	/* if -1 then nothing will be partially shifted */
+	int rbytes;		/* number of bytes which will flow to the right neighbor from the right        */
+	/* most liquid item that cannot be shifted from S[0] entirely         */
+	/* if -1 then nothing will be partially shifted                           */
+	int s1bytes;		/* number of bytes which flow to the first  new node when S[0] splits   */
+	/* note: if S[0] splits into 3 nodes, then items do not need to be cut  */
+	int s2bytes;
+	struct buffer_head *buf_to_free[MAX_FREE_BLOCK];	/* buffers which are to be freed after do_balance finishes by unfix_nodes */
+	char *vn_buf;		/* kmalloced memory. Used to create
 				   virtual node and keep map of
 				   dirtied bitmap blocks */
-  int vn_buf_size;		/* size of the vn_buf */
-  struct virtual_node * tb_vn;	/* VN starts after bitmap of bitmap blocks */
+	int vn_buf_size;	/* size of the vn_buf */
+	struct virtual_node *tb_vn;	/* VN starts after bitmap of bitmap blocks */
 
-  int fs_gen;                  /* saved value of `reiserfs_generation' counter
-			          see FILESYSTEM_CHANGED() macro in reiserfs_fs.h */
+	int fs_gen;		/* saved value of `reiserfs_generation' counter
+				   see FILESYSTEM_CHANGED() macro in reiserfs_fs.h */
 #ifdef DISPLACE_NEW_PACKING_LOCALITIES
-  struct in_core_key  key;	      /* key pointer, to pass to block allocator or
-				 another low-level subsystem */
+	struct in_core_key key;	/* key pointer, to pass to block allocator or
+				   another low-level subsystem */
 #endif
-} ;
+};
 
 /* These are modes of balancing */
 
@@ -1479,13 +1430,12 @@ struct tree_balance
 /* used in do_balance for passing parent of node information that has
    been gotten from tb struct */
 struct buffer_info {
-    struct tree_balance * tb;
-    struct buffer_head * bi_bh;
-    struct buffer_head * bi_parent;
-    int bi_position;
+	struct tree_balance *tb;
+	struct buffer_head *bi_bh;
+	struct buffer_head *bi_parent;
+	int bi_position;
 };
 
-
 /* there are 4 types of items: stat data, directory item, indirect, direct.
 +-------------------+------------+--------------+------------+
 |	            |  k_offset  | k_uniqueness | mergeable? |
@@ -1503,24 +1453,24 @@ struct buffer_info {
 */
 
 struct item_operations {
-    int (*bytes_number) (struct item_head * ih, int block_size);
-    void (*decrement_key) (struct cpu_key *);
-    int (*is_left_mergeable) (struct reiserfs_key * ih, unsigned long bsize);
-    void (*print_item) (struct item_head *, char * item);
-    void (*check_item) (struct item_head *, char * item);
-
-    int (*create_vi) (struct virtual_node * vn, struct virtual_item * vi, 
-		      int is_affected, int insert_size);
-    int (*check_left) (struct virtual_item * vi, int free, 
-			    int start_skip, int end_skip);
-    int (*check_right) (struct virtual_item * vi, int free);
-    int (*part_size) (struct virtual_item * vi, int from, int to);
-    int (*unit_num) (struct virtual_item * vi);
-    void (*print_vi) (struct virtual_item * vi);
+	int (*bytes_number) (struct item_head * ih, int block_size);
+	void (*decrement_key) (struct cpu_key *);
+	int (*is_left_mergeable) (struct reiserfs_key * ih,
+				  unsigned long bsize);
+	void (*print_item) (struct item_head *, char *item);
+	void (*check_item) (struct item_head *, char *item);
+
+	int (*create_vi) (struct virtual_node * vn, struct virtual_item * vi,
+			  int is_affected, int insert_size);
+	int (*check_left) (struct virtual_item * vi, int free,
+			   int start_skip, int end_skip);
+	int (*check_right) (struct virtual_item * vi, int free);
+	int (*part_size) (struct virtual_item * vi, int from, int to);
+	int (*unit_num) (struct virtual_item * vi);
+	void (*print_vi) (struct virtual_item * vi);
 };
 
-
-extern struct item_operations * item_ops [TYPE_ANY + 1];
+extern struct item_operations *item_ops[TYPE_ANY + 1];
 
 #define op_bytes_number(ih,bsize)                    item_ops[le_ih_k_type (ih)]->bytes_number (ih, bsize)
 #define op_is_left_mergeable(key,bsize)              item_ops[le_key_k_type (le_key_version (key), key)]->is_left_mergeable (key, bsize)
@@ -1533,8 +1483,6 @@ extern struct item_operations * item_ops
 #define op_unit_num(vi)				     item_ops[(vi)->vi_index]->unit_num (vi)
 #define op_print_vi(vi)                              item_ops[(vi)->vi_index]->print_vi (vi)
 
-
-
 #define COMP_SHORT_KEYS comp_short_keys
 
 /* number of blocks pointed to by the indirect item */
@@ -1545,8 +1493,7 @@ extern struct item_operations * item_ops
 
 /* number of bytes contained by the direct item or the unformatted nodes the indirect item points to */
 
-
-/* get the item header */ 
+/* get the item header */
 #define B_N_PITEM_HEAD(bh,item_num) ( (struct item_head * )((bh)->b_data + BLKH_SIZE) + (item_num) )
 
 /* get key */
@@ -1577,9 +1524,9 @@ extern struct item_operations * item_ops
 #define PUT_B_I_POS_UNFM_POINTER(bh,ih,pos, val) do {*(((unp_t *)B_I_PITEM(bh,ih)) + (pos)) = cpu_to_le32(val); } while (0)
 
 struct reiserfs_iget_args {
-    __u32 objectid ;
-    __u32 dirid ;
-} ;
+	__u32 objectid;
+	__u32 dirid;
+};
 
 /***************************************************************************/
 /*                    FUNCTION DECLARATIONS                                */
@@ -1595,11 +1542,11 @@ struct reiserfs_iget_args {
 
 /* first block written in a commit.  */
 struct reiserfs_journal_desc {
-  __le32 j_trans_id ;			/* id of commit */
-  __le32 j_len ;			/* length of commit. len +1 is the commit block */
-  __le32 j_mount_id ;				/* mount id of this trans*/
-  __le32 j_realblock[1] ; /* real locations for each block */
-} ;
+	__le32 j_trans_id;	/* id of commit */
+	__le32 j_len;		/* length of commit. len +1 is the commit block */
+	__le32 j_mount_id;	/* mount id of this trans */
+	__le32 j_realblock[1];	/* real locations for each block */
+};
 
 #define get_desc_trans_id(d)   le32_to_cpu((d)->j_trans_id)
 #define get_desc_trans_len(d)  le32_to_cpu((d)->j_len)
@@ -1611,10 +1558,10 @@ struct reiserfs_journal_desc {
 
 /* last block written in a commit */
 struct reiserfs_journal_commit {
-  __le32 j_trans_id ;			/* must match j_trans_id from the desc block */
-  __le32 j_len ;			/* ditto */
-  __le32 j_realblock[1] ; /* real locations for each block */
-} ;
+	__le32 j_trans_id;	/* must match j_trans_id from the desc block */
+	__le32 j_len;		/* ditto */
+	__le32 j_realblock[1];	/* real locations for each block */
+};
 
 #define get_commit_trans_id(c) le32_to_cpu((c)->j_trans_id)
 #define get_commit_trans_len(c)        le32_to_cpu((c)->j_len)
@@ -1628,27 +1575,34 @@ struct reiserfs_journal_commit {
 ** and this transaction does not need to be replayed.
 */
 struct reiserfs_journal_header {
-  __le32 j_last_flush_trans_id ;		/* id of last fully flushed transaction */
-  __le32 j_first_unflushed_offset ;      /* offset in the log of where to start replay after a crash */
-  __le32 j_mount_id ;
-  /* 12 */ struct journal_params jh_journal;
-} ;
+	__le32 j_last_flush_trans_id;	/* id of last fully flushed transaction */
+	__le32 j_first_unflushed_offset;	/* offset in the log of where to start replay after a crash */
+	__le32 j_mount_id;
+	/* 12 */ struct journal_params jh_journal;
+};
 
 /* biggest tunable defines are right here */
-#define JOURNAL_BLOCK_COUNT 8192 /* number of blocks in the journal */
-#define JOURNAL_TRANS_MAX_DEFAULT 1024   /* biggest possible single transaction, don't change for now (8/3/99) */
+#define JOURNAL_BLOCK_COUNT 8192	/* number of blocks in the journal */
+#define JOURNAL_TRANS_MAX_DEFAULT 1024	/* biggest possible single transaction, don't change for now (8/3/99) */
 #define JOURNAL_TRANS_MIN_DEFAULT 256
-#define JOURNAL_MAX_BATCH_DEFAULT   900 /* max blocks to batch into one transaction, don't make this any bigger than 900 */
+#define JOURNAL_MAX_BATCH_DEFAULT   900	/* max blocks to batch into one transaction, don't make this any bigger than 900 */
 #define JOURNAL_MIN_RATIO 2
-#define JOURNAL_MAX_COMMIT_AGE 30 
+#define JOURNAL_MAX_COMMIT_AGE 30
 #define JOURNAL_MAX_TRANS_AGE 30
 #define JOURNAL_PER_BALANCE_CNT (3 * (MAX_HEIGHT-2) + 9)
 #ifdef CONFIG_QUOTA
-#define REISERFS_QUOTA_TRANS_BLOCKS 2	/* We need to update data and inode (atime) */
-#define REISERFS_QUOTA_INIT_BLOCKS (DQUOT_MAX_WRITES*(JOURNAL_PER_BALANCE_CNT+2)+1)	/* 1 balancing, 1 bitmap, 1 data per write + stat data update */
+/* We need to update data and inode (atime) */
+#define REISERFS_QUOTA_TRANS_BLOCKS(s) (REISERFS_SB(s)->s_mount_opt & (1<<REISERFS_QUOTA) ? 2 : 0)
+/* 1 balancing, 1 bitmap, 1 data per write + stat data update */
+#define REISERFS_QUOTA_INIT_BLOCKS(s) (REISERFS_SB(s)->s_mount_opt & (1<<REISERFS_QUOTA) ? \
+(DQUOT_INIT_ALLOC*(JOURNAL_PER_BALANCE_CNT+2)+DQUOT_INIT_REWRITE+1) : 0)
+/* same as with INIT */
+#define REISERFS_QUOTA_DEL_BLOCKS(s) (REISERFS_SB(s)->s_mount_opt & (1<<REISERFS_QUOTA) ? \
+(DQUOT_DEL_ALLOC*(JOURNAL_PER_BALANCE_CNT+2)+DQUOT_DEL_REWRITE+1) : 0)
 #else
-#define REISERFS_QUOTA_TRANS_BLOCKS 0
-#define REISERFS_QUOTA_INIT_BLOCKS 0
+#define REISERFS_QUOTA_TRANS_BLOCKS(s) 0
+#define REISERFS_QUOTA_INIT_BLOCKS(s) 0
+#define REISERFS_QUOTA_DEL_BLOCKS(s) 0
 #endif
 
 /* both of these can be as low as 1, or as high as you want.  The min is the
@@ -1657,10 +1611,10 @@ struct reiserfs_journal_header {
 ** the current number of nodes is > max, the node is freed, otherwise, 
 ** it is put on a free list for faster use later.
 */
-#define REISERFS_MIN_BITMAP_NODES 10 
-#define REISERFS_MAX_BITMAP_NODES 100 
+#define REISERFS_MIN_BITMAP_NODES 10
+#define REISERFS_MAX_BITMAP_NODES 100
 
-#define JBH_HASH_SHIFT 13 /* these are based on journal hash size of 8192 */
+#define JBH_HASH_SHIFT 13	/* these are based on journal hash size of 8192 */
 #define JBH_HASH_MASK 8191
 
 #define _jhashfn(sb,block)	\
@@ -1674,14 +1628,14 @@ struct reiserfs_journal_header {
 #define journal_bread(s, block) __bread(SB_JOURNAL(s)->j_dev_bd, block, s->s_blocksize)
 
 enum reiserfs_bh_state_bits {
-    BH_JDirty = BH_PrivateStart, /* buffer is in current transaction */
-    BH_JDirty_wait,
-    BH_JNew,                     /* disk block was taken off free list before
-                                  * being in a finished transaction, or
-                                  * written to disk. Can be reused immed. */
-    BH_JPrepared,
-    BH_JRestore_dirty,
-    BH_JTest, // debugging only will go away
+	BH_JDirty = BH_PrivateStart,	/* buffer is in current transaction */
+	BH_JDirty_wait,
+	BH_JNew,		/* disk block was taken off free list before
+				 * being in a finished transaction, or
+				 * written to disk. Can be reused immed. */
+	BH_JPrepared,
+	BH_JRestore_dirty,
+	BH_JTest,		// debugging only will go away
 };
 
 BUFFER_FNS(JDirty, journaled);
@@ -1701,175 +1655,192 @@ TAS_BUFFER_FNS(JTest, journal_test);
 ** transaction handle which is passed around for all journal calls
 */
 struct reiserfs_transaction_handle {
-  struct super_block *t_super ; /* super for this FS when journal_begin was
-				   called. saves calls to reiserfs_get_super
-				   also used by nested transactions to make
-				   sure they are nesting on the right FS
-				   _must_ be first in the handle
-				*/
-  int t_refcount;
-  int t_blocks_logged ;         /* number of blocks this writer has logged */
-  int t_blocks_allocated ;      /* number of blocks this writer allocated */
-  unsigned long t_trans_id ;    /* sanity check, equals the current trans id */
-  void *t_handle_save ;		/* save existing current->journal_info */
-  unsigned displace_new_blocks:1; /* if new block allocation occurres, that block
-				   should be displaced from others */
-  struct list_head t_list;
-} ;
+	struct super_block *t_super;	/* super for this FS when journal_begin was
+					   called. saves calls to reiserfs_get_super
+					   also used by nested transactions to make
+					   sure they are nesting on the right FS
+					   _must_ be first in the handle
+					 */
+	int t_refcount;
+	int t_blocks_logged;	/* number of blocks this writer has logged */
+	int t_blocks_allocated;	/* number of blocks this writer allocated */
+	unsigned long t_trans_id;	/* sanity check, equals the current trans id */
+	void *t_handle_save;	/* save existing current->journal_info */
+	unsigned displace_new_blocks:1;	/* if new block allocation occurres, that block
+					   should be displaced from others */
+	struct list_head t_list;
+};
 
 /* used to keep track of ordered and tail writes, attached to the buffer
  * head through b_journal_head.
  */
 struct reiserfs_jh {
-    struct reiserfs_journal_list *jl;
-    struct buffer_head *bh;
-    struct list_head list;
+	struct reiserfs_journal_list *jl;
+	struct buffer_head *bh;
+	struct list_head list;
 };
 
 void reiserfs_free_jh(struct buffer_head *bh);
 int reiserfs_add_tail_list(struct inode *inode, struct buffer_head *bh);
 int reiserfs_add_ordered_list(struct inode *inode, struct buffer_head *bh);
-int journal_mark_dirty(struct reiserfs_transaction_handle *, struct super_block *, struct buffer_head *bh) ;
+int journal_mark_dirty(struct reiserfs_transaction_handle *,
+		       struct super_block *, struct buffer_head *bh);
 
-static inline int
-reiserfs_file_data_log(struct inode *inode) {
-    if (reiserfs_data_log(inode->i_sb) ||
-       (REISERFS_I(inode)->i_flags & i_data_log))
-        return 1 ;
-    return 0 ;
-}
-
-static inline int reiserfs_transaction_running(struct super_block *s) {
-    struct reiserfs_transaction_handle *th = current->journal_info ;
-    if (th && th->t_super == s)
-        return 1 ;
-    if (th && th->t_super == NULL)
-        BUG();
-    return 0 ;
+static inline int reiserfs_file_data_log(struct inode *inode)
+{
+	if (reiserfs_data_log(inode->i_sb) ||
+	    (REISERFS_I(inode)->i_flags & i_data_log))
+		return 1;
+	return 0;
+}
+
+static inline int reiserfs_transaction_running(struct super_block *s)
+{
+	struct reiserfs_transaction_handle *th = current->journal_info;
+	if (th && th->t_super == s)
+		return 1;
+	if (th && th->t_super == NULL)
+		BUG();
+	return 0;
 }
 
 int reiserfs_async_progress_wait(struct super_block *s);
 
-struct reiserfs_transaction_handle *
-reiserfs_persistent_transaction(struct super_block *, int count);
+struct reiserfs_transaction_handle *reiserfs_persistent_transaction(struct
+								    super_block
+								    *,
+								    int count);
 int reiserfs_end_persistent_transaction(struct reiserfs_transaction_handle *);
 int reiserfs_commit_page(struct inode *inode, struct page *page,
-		unsigned from, unsigned to);
+			 unsigned from, unsigned to);
 int reiserfs_flush_old_commits(struct super_block *);
-int reiserfs_commit_for_inode(struct inode *) ;
-int  reiserfs_inode_needs_commit(struct inode *) ;
-void reiserfs_update_inode_transaction(struct inode *) ;
-void reiserfs_wait_on_write_block(struct super_block *s) ;
-void reiserfs_block_writes(struct reiserfs_transaction_handle *th) ;
-void reiserfs_allow_writes(struct super_block *s) ;
-void reiserfs_check_lock_depth(struct super_block *s, char *caller) ;
-int reiserfs_prepare_for_journal(struct super_block *, struct buffer_head *bh, int wait) ;
-void reiserfs_restore_prepared_buffer(struct super_block *, struct buffer_head *bh) ;
-int journal_init(struct super_block *, const char * j_dev_name, int old_format, unsigned int) ;
-int journal_release(struct reiserfs_transaction_handle*, struct super_block *) ;
-int journal_release_error(struct reiserfs_transaction_handle*, struct super_block *) ;
-int journal_end(struct reiserfs_transaction_handle *, struct super_block *, unsigned long) ;
-int journal_end_sync(struct reiserfs_transaction_handle *, struct super_block *, unsigned long) ;
-int journal_mark_freed(struct reiserfs_transaction_handle *, struct super_block *, b_blocknr_t blocknr) ;
-int journal_transaction_should_end(struct reiserfs_transaction_handle *, int) ;
-int reiserfs_in_journal(struct super_block *p_s_sb, int bmap_nr, int bit_nr, int searchall, b_blocknr_t *next) ;
-int journal_begin(struct reiserfs_transaction_handle *, struct super_block *p_s_sb, unsigned long) ;
-int journal_join_abort(struct reiserfs_transaction_handle *, struct super_block *p_s_sb, unsigned long) ;
-void reiserfs_journal_abort (struct super_block *sb, int errno);
-void reiserfs_abort (struct super_block *sb, int errno, const char *fmt, ...);
-int reiserfs_allocate_list_bitmaps(struct super_block *s, struct reiserfs_list_bitmap *, int) ;
-
-void add_save_link (struct reiserfs_transaction_handle * th,
-					struct inode * inode, int truncate);
-int remove_save_link (struct inode * inode, int truncate);
+int reiserfs_commit_for_inode(struct inode *);
+int reiserfs_inode_needs_commit(struct inode *);
+void reiserfs_update_inode_transaction(struct inode *);
+void reiserfs_wait_on_write_block(struct super_block *s);
+void reiserfs_block_writes(struct reiserfs_transaction_handle *th);
+void reiserfs_allow_writes(struct super_block *s);
+void reiserfs_check_lock_depth(struct super_block *s, char *caller);
+int reiserfs_prepare_for_journal(struct super_block *, struct buffer_head *bh,
+				 int wait);
+void reiserfs_restore_prepared_buffer(struct super_block *,
+				      struct buffer_head *bh);
+int journal_init(struct super_block *, const char *j_dev_name, int old_format,
+		 unsigned int);
+int journal_release(struct reiserfs_transaction_handle *, struct super_block *);
+int journal_release_error(struct reiserfs_transaction_handle *,
+			  struct super_block *);
+int journal_end(struct reiserfs_transaction_handle *, struct super_block *,
+		unsigned long);
+int journal_end_sync(struct reiserfs_transaction_handle *, struct super_block *,
+		     unsigned long);
+int journal_mark_freed(struct reiserfs_transaction_handle *,
+		       struct super_block *, b_blocknr_t blocknr);
+int journal_transaction_should_end(struct reiserfs_transaction_handle *, int);
+int reiserfs_in_journal(struct super_block *p_s_sb, int bmap_nr, int bit_nr,
+			int searchall, b_blocknr_t * next);
+int journal_begin(struct reiserfs_transaction_handle *,
+		  struct super_block *p_s_sb, unsigned long);
+int journal_join_abort(struct reiserfs_transaction_handle *,
+		       struct super_block *p_s_sb, unsigned long);
+void reiserfs_journal_abort(struct super_block *sb, int errno);
+void reiserfs_abort(struct super_block *sb, int errno, const char *fmt, ...);
+int reiserfs_allocate_list_bitmaps(struct super_block *s,
+				   struct reiserfs_list_bitmap *, int);
+
+void add_save_link(struct reiserfs_transaction_handle *th,
+		   struct inode *inode, int truncate);
+int remove_save_link(struct inode *inode, int truncate);
 
 /* objectid.c */
-__u32 reiserfs_get_unused_objectid (struct reiserfs_transaction_handle *th);
-void reiserfs_release_objectid (struct reiserfs_transaction_handle *th, __u32 objectid_to_release);
-int reiserfs_convert_objectid_map_v1(struct super_block *) ;
+__u32 reiserfs_get_unused_objectid(struct reiserfs_transaction_handle *th);
+void reiserfs_release_objectid(struct reiserfs_transaction_handle *th,
+			       __u32 objectid_to_release);
+int reiserfs_convert_objectid_map_v1(struct super_block *);
 
 /* stree.c */
 int B_IS_IN_TREE(const struct buffer_head *);
-extern void copy_item_head(struct item_head * p_v_to,
-								  const struct item_head * p_v_from);
+extern void copy_item_head(struct item_head *p_v_to,
+			   const struct item_head *p_v_from);
 
 // first key is in cpu form, second - le
-extern int  comp_short_keys (const struct reiserfs_key * le_key,
-				    const struct cpu_key * cpu_key);
-extern void le_key2cpu_key (struct cpu_key * to, const struct reiserfs_key * from);
+extern int comp_short_keys(const struct reiserfs_key *le_key,
+			   const struct cpu_key *cpu_key);
+extern void le_key2cpu_key(struct cpu_key *to, const struct reiserfs_key *from);
 
 // both are in le form
-extern int comp_le_keys (const struct reiserfs_key *, const struct reiserfs_key *);
-extern int comp_short_le_keys (const struct reiserfs_key *, const struct reiserfs_key *);
+extern int comp_le_keys(const struct reiserfs_key *,
+			const struct reiserfs_key *);
+extern int comp_short_le_keys(const struct reiserfs_key *,
+			      const struct reiserfs_key *);
 
 //
 // get key version from on disk key - kludge
 //
-static inline int le_key_version (const struct reiserfs_key * key)
+static inline int le_key_version(const struct reiserfs_key *key)
 {
-    int type;
-    
-    type = offset_v2_k_type( &(key->u.k_offset_v2));
-    if (type != TYPE_DIRECT && type != TYPE_INDIRECT && type != TYPE_DIRENTRY)
-	return KEY_FORMAT_3_5;
+	int type;
 
-    return KEY_FORMAT_3_6;
-	
-}
+	type = offset_v2_k_type(&(key->u.k_offset_v2));
+	if (type != TYPE_DIRECT && type != TYPE_INDIRECT
+	    && type != TYPE_DIRENTRY)
+		return KEY_FORMAT_3_5;
 
+	return KEY_FORMAT_3_6;
 
-static inline void copy_key (struct reiserfs_key *to, const struct reiserfs_key *from)
-{
-    memcpy (to, from, KEY_SIZE);
 }
 
+static inline void copy_key(struct reiserfs_key *to,
+			    const struct reiserfs_key *from)
+{
+	memcpy(to, from, KEY_SIZE);
+}
 
-int comp_items (const struct item_head * stored_ih, const struct path * p_s_path);
-const struct reiserfs_key * get_rkey (const struct path * p_s_chk_path,
-							 const struct super_block  * p_s_sb);
-int search_by_key (struct super_block *, const struct cpu_key *, 
-				   struct path *, int);
+int comp_items(const struct item_head *stored_ih, const struct path *p_s_path);
+const struct reiserfs_key *get_rkey(const struct path *p_s_chk_path,
+				    const struct super_block *p_s_sb);
+int search_by_key(struct super_block *, const struct cpu_key *,
+		  struct path *, int);
 #define search_item(s,key,path) search_by_key (s, key, path, DISK_LEAF_NODE_LEVEL)
-int search_for_position_by_key (struct super_block * p_s_sb, 
-								const struct cpu_key * p_s_cpu_key, 
-								struct path * p_s_search_path);
-extern void decrement_bcount (struct buffer_head * p_s_bh);
-void decrement_counters_in_path (struct path * p_s_search_path);
-void pathrelse (struct path * p_s_search_path);
-int reiserfs_check_path(struct path *p) ;
-void pathrelse_and_restore (struct super_block *s, struct path * p_s_search_path);
-
-int reiserfs_insert_item (struct reiserfs_transaction_handle *th, 
-			  struct path * path, 
-			  const struct cpu_key * key,
-			  struct item_head * ih,
-			  struct inode *inode, const char * body);
-
-int reiserfs_paste_into_item (struct reiserfs_transaction_handle *th,
-			      struct path * path,
-			      const struct cpu_key * key,
-			      struct inode *inode,
-			      const char * body, int paste_size);
-
-int reiserfs_cut_from_item (struct reiserfs_transaction_handle *th,
-			    struct path * path,
-			    struct cpu_key * key,
-			    struct inode * inode,
-			    struct page *page,
-			    loff_t new_file_size);
-
-int reiserfs_delete_item (struct reiserfs_transaction_handle *th,
-			  struct path * path, 
-			  const struct cpu_key * key,
-			  struct inode * inode, 
-			  struct buffer_head  * p_s_un_bh);
-
-void reiserfs_delete_solid_item (struct reiserfs_transaction_handle *th,
-			struct inode *inode, struct reiserfs_key * key);
-int reiserfs_delete_object (struct reiserfs_transaction_handle *th, struct inode * p_s_inode);
-int reiserfs_do_truncate (struct reiserfs_transaction_handle *th,
-			   struct  inode * p_s_inode, struct page *, 
-			   int update_timestamps);
+int search_for_position_by_key(struct super_block *p_s_sb,
+			       const struct cpu_key *p_s_cpu_key,
+			       struct path *p_s_search_path);
+extern void decrement_bcount(struct buffer_head *p_s_bh);
+void decrement_counters_in_path(struct path *p_s_search_path);
+void pathrelse(struct path *p_s_search_path);
+int reiserfs_check_path(struct path *p);
+void pathrelse_and_restore(struct super_block *s, struct path *p_s_search_path);
+
+int reiserfs_insert_item(struct reiserfs_transaction_handle *th,
+			 struct path *path,
+			 const struct cpu_key *key,
+			 struct item_head *ih,
+			 struct inode *inode, const char *body);
+
+int reiserfs_paste_into_item(struct reiserfs_transaction_handle *th,
+			     struct path *path,
+			     const struct cpu_key *key,
+			     struct inode *inode,
+			     const char *body, int paste_size);
+
+int reiserfs_cut_from_item(struct reiserfs_transaction_handle *th,
+			   struct path *path,
+			   struct cpu_key *key,
+			   struct inode *inode,
+			   struct page *page, loff_t new_file_size);
+
+int reiserfs_delete_item(struct reiserfs_transaction_handle *th,
+			 struct path *path,
+			 const struct cpu_key *key,
+			 struct inode *inode, struct buffer_head *p_s_un_bh);
+
+void reiserfs_delete_solid_item(struct reiserfs_transaction_handle *th,
+				struct inode *inode, struct reiserfs_key *key);
+int reiserfs_delete_object(struct reiserfs_transaction_handle *th,
+			   struct inode *p_s_inode);
+int reiserfs_do_truncate(struct reiserfs_transaction_handle *th,
+			 struct inode *p_s_inode, struct page *,
+			 int update_timestamps);
 
 #define i_block_size(inode) ((inode)->i_sb->s_blocksize)
 #define file_size(inode) ((inode)->i_size)
@@ -1878,66 +1849,67 @@ int reiserfs_do_truncate (struct reiserf
 #define tail_has_to_be_packed(inode) (have_large_tails ((inode)->i_sb)?\
 !STORE_TAIL_IN_UNFM_S1(file_size (inode), tail_size(inode), inode->i_sb->s_blocksize):have_small_tails ((inode)->i_sb)?!STORE_TAIL_IN_UNFM_S2(file_size (inode), tail_size(inode), inode->i_sb->s_blocksize):0 )
 
-void padd_item (char * item, int total_length, int length);
+void padd_item(char *item, int total_length, int length);
 
 /* inode.c */
 /* args for the create parameter of reiserfs_get_block */
-#define GET_BLOCK_NO_CREATE 0 /* don't create new blocks or convert tails */
-#define GET_BLOCK_CREATE 1    /* add anything you need to find block */
-#define GET_BLOCK_NO_HOLE 2   /* return -ENOENT for file holes */
-#define GET_BLOCK_READ_DIRECT 4  /* read the tail if indirect item not found */
-#define GET_BLOCK_NO_ISEM     8 /* i_sem is not held, don't preallocate */
-#define GET_BLOCK_NO_DANGLE   16 /* don't leave any transactions running */
-
-int restart_transaction(struct reiserfs_transaction_handle *th, struct inode *inode, struct path *path);
-void reiserfs_read_locked_inode(struct inode * inode, struct reiserfs_iget_args *args) ;
-int reiserfs_find_actor(struct inode * inode, void *p) ;
-int reiserfs_init_locked_inode(struct inode * inode, void *p) ;
-void reiserfs_delete_inode (struct inode * inode);
-int reiserfs_write_inode (struct inode * inode, int) ;
-int reiserfs_get_block (struct inode * inode, sector_t block, struct buffer_head * bh_result, int create);
-struct dentry *reiserfs_get_dentry(struct super_block *, void *) ;
-struct dentry *reiserfs_decode_fh(struct super_block *sb, __u32 *data,
-                                     int len, int fhtype,
-				  int (*acceptable)(void *contect, struct dentry *de),
-				  void *context) ;
-int reiserfs_encode_fh( struct dentry *dentry, __u32 *data, int *lenp, 
-						int connectable );
-
-int reiserfs_truncate_file(struct inode *, int update_timestamps) ;
-void make_cpu_key (struct cpu_key * cpu_key, struct inode * inode, loff_t offset,
-		   int type, int key_length);
-void make_le_item_head (struct item_head * ih, const struct cpu_key * key, 
-			int version,
-			loff_t offset, int type, int length, int entry_count);
-struct inode * reiserfs_iget (struct super_block * s, 
-			      const struct cpu_key * key);
-
-
-int reiserfs_new_inode (struct reiserfs_transaction_handle *th, 
-				   struct inode * dir, int mode, 
-				   const char * symname, loff_t i_size,
-				   struct dentry *dentry, struct inode *inode);
+#define GET_BLOCK_NO_CREATE 0	/* don't create new blocks or convert tails */
+#define GET_BLOCK_CREATE 1	/* add anything you need to find block */
+#define GET_BLOCK_NO_HOLE 2	/* return -ENOENT for file holes */
+#define GET_BLOCK_READ_DIRECT 4	/* read the tail if indirect item not found */
+#define GET_BLOCK_NO_ISEM     8	/* i_sem is not held, don't preallocate */
+#define GET_BLOCK_NO_DANGLE   16	/* don't leave any transactions running */
+
+int restart_transaction(struct reiserfs_transaction_handle *th,
+			struct inode *inode, struct path *path);
+void reiserfs_read_locked_inode(struct inode *inode,
+				struct reiserfs_iget_args *args);
+int reiserfs_find_actor(struct inode *inode, void *p);
+int reiserfs_init_locked_inode(struct inode *inode, void *p);
+void reiserfs_delete_inode(struct inode *inode);
+int reiserfs_write_inode(struct inode *inode, int);
+int reiserfs_get_block(struct inode *inode, sector_t block,
+		       struct buffer_head *bh_result, int create);
+struct dentry *reiserfs_get_dentry(struct super_block *, void *);
+struct dentry *reiserfs_decode_fh(struct super_block *sb, __u32 * data,
+				  int len, int fhtype,
+				  int (*acceptable) (void *contect,
+						     struct dentry * de),
+				  void *context);
+int reiserfs_encode_fh(struct dentry *dentry, __u32 * data, int *lenp,
+		       int connectable);
+
+int reiserfs_truncate_file(struct inode *, int update_timestamps);
+void make_cpu_key(struct cpu_key *cpu_key, struct inode *inode, loff_t offset,
+		  int type, int key_length);
+void make_le_item_head(struct item_head *ih, const struct cpu_key *key,
+		       int version,
+		       loff_t offset, int type, int length, int entry_count);
+struct inode *reiserfs_iget(struct super_block *s, const struct cpu_key *key);
+
+int reiserfs_new_inode(struct reiserfs_transaction_handle *th,
+		       struct inode *dir, int mode,
+		       const char *symname, loff_t i_size,
+		       struct dentry *dentry, struct inode *inode);
 
-void reiserfs_update_sd_size (struct reiserfs_transaction_handle *th,
-                              struct inode * inode, loff_t size);
+void reiserfs_update_sd_size(struct reiserfs_transaction_handle *th,
+			     struct inode *inode, loff_t size);
 
 static inline void reiserfs_update_sd(struct reiserfs_transaction_handle *th,
-                                      struct inode *inode)
+				      struct inode *inode)
 {
-    reiserfs_update_sd_size(th, inode, inode->i_size) ;
+	reiserfs_update_sd_size(th, inode, inode->i_size);
 }
 
-void sd_attrs_to_i_attrs( __u16 sd_attrs, struct inode *inode );
-void i_attrs_to_sd_attrs( struct inode *inode, __u16 *sd_attrs );
+void sd_attrs_to_i_attrs(__u16 sd_attrs, struct inode *inode);
+void i_attrs_to_sd_attrs(struct inode *inode, __u16 * sd_attrs);
 int reiserfs_setattr(struct dentry *dentry, struct iattr *attr);
 
 /* namei.c */
-void set_de_name_and_namelen (struct reiserfs_dir_entry * de);
-int search_by_entry_key (struct super_block * sb, const struct cpu_key * key, 
-			 struct path * path, 
-			 struct reiserfs_dir_entry * de);
-struct dentry *reiserfs_get_parent(struct dentry *) ;
+void set_de_name_and_namelen(struct reiserfs_dir_entry *de);
+int search_by_entry_key(struct super_block *sb, const struct cpu_key *key,
+			struct path *path, struct reiserfs_dir_entry *de);
+struct dentry *reiserfs_get_parent(struct dentry *);
 /* procfs.c */
 
 #if defined( CONFIG_PROC_FS ) && defined( CONFIG_REISERFS_PROC_INFO )
@@ -1946,15 +1918,15 @@ struct dentry *reiserfs_get_parent(struc
 #undef REISERFS_PROC_INFO
 #endif
 
-int reiserfs_proc_info_init( struct super_block *sb );
-int reiserfs_proc_info_done( struct super_block *sb );
-struct proc_dir_entry *reiserfs_proc_register_global( char *name, 
-													  read_proc_t *func );
-void reiserfs_proc_unregister_global( const char *name );
-int reiserfs_proc_info_global_init( void );
-int reiserfs_proc_info_global_done( void );
-int reiserfs_global_version_in_proc( char *buffer, char **start, off_t offset,
-									 int count, int *eof, void *data );
+int reiserfs_proc_info_init(struct super_block *sb);
+int reiserfs_proc_info_done(struct super_block *sb);
+struct proc_dir_entry *reiserfs_proc_register_global(char *name,
+						     read_proc_t * func);
+void reiserfs_proc_unregister_global(const char *name);
+int reiserfs_proc_info_global_init(void);
+int reiserfs_proc_info_global_done(void);
+int reiserfs_global_version_in_proc(char *buffer, char **start, off_t offset,
+				    int count, int *eof, void *data);
 
 #if defined( REISERFS_PROC_INFO )
 
@@ -1986,123 +1958,132 @@ extern struct inode_operations reiserfs_
 extern struct file_operations reiserfs_dir_operations;
 
 /* tail_conversion.c */
-int direct2indirect (struct reiserfs_transaction_handle *, struct inode *, struct path *, struct buffer_head *, loff_t);
-int indirect2direct (struct reiserfs_transaction_handle *, struct inode *, struct page *, struct path *, const struct cpu_key *, loff_t, char *);
-void reiserfs_unmap_buffer(struct buffer_head *) ;
-
+int direct2indirect(struct reiserfs_transaction_handle *, struct inode *,
+		    struct path *, struct buffer_head *, loff_t);
+int indirect2direct(struct reiserfs_transaction_handle *, struct inode *,
+		    struct page *, struct path *, const struct cpu_key *,
+		    loff_t, char *);
+void reiserfs_unmap_buffer(struct buffer_head *);
 
 /* file.c */
 extern struct inode_operations reiserfs_file_inode_operations;
 extern struct file_operations reiserfs_file_operations;
-extern struct address_space_operations reiserfs_address_space_operations ;
+extern struct address_space_operations reiserfs_address_space_operations;
 
 /* fix_nodes.c */
 #ifdef CONFIG_REISERFS_CHECK
-void * reiserfs_kmalloc (size_t size, int flags, struct super_block * s);
-void reiserfs_kfree (const void * vp, size_t size, struct super_block * s);
+void *reiserfs_kmalloc(size_t size, int flags, struct super_block *s);
+void reiserfs_kfree(const void *vp, size_t size, struct super_block *s);
 #else
 static inline void *reiserfs_kmalloc(size_t size, int flags,
-					struct super_block *s)
+				     struct super_block *s)
 {
 	return kmalloc(size, flags);
 }
 
 static inline void reiserfs_kfree(const void *vp, size_t size,
-					struct super_block *s)
+				  struct super_block *s)
 {
 	kfree(vp);
 }
 #endif
 
-int fix_nodes (int n_op_mode, struct tree_balance * p_s_tb, 
-	       struct item_head * p_s_ins_ih, const void *);
-void unfix_nodes (struct tree_balance *);
-
+int fix_nodes(int n_op_mode, struct tree_balance *p_s_tb,
+	      struct item_head *p_s_ins_ih, const void *);
+void unfix_nodes(struct tree_balance *);
 
 /* prints.c */
-void reiserfs_panic (struct super_block * s, const char * fmt, ...) __attribute__ ( ( noreturn ) );
-void reiserfs_info (struct super_block *s, const char * fmt, ...);
-void reiserfs_debug (struct super_block *s, int level, const char * fmt, ...);
-void print_indirect_item (struct buffer_head * bh, int item_num);
-void store_print_tb (struct tree_balance * tb);
-void print_cur_tb (char * mes);
-void print_de (struct reiserfs_dir_entry * de);
-void print_bi (struct buffer_info * bi, char * mes);
-#define PRINT_LEAF_ITEMS 1   /* print all items */
-#define PRINT_DIRECTORY_ITEMS 2 /* print directory items */
-#define PRINT_DIRECT_ITEMS 4 /* print contents of direct items */
-void print_block (struct buffer_head * bh, ...);
-void print_bmap (struct super_block * s, int silent);
-void print_bmap_block (int i, char * data, int size, int silent);
+void reiserfs_panic(struct super_block *s, const char *fmt, ...)
+    __attribute__ ((noreturn));
+void reiserfs_info(struct super_block *s, const char *fmt, ...);
+void reiserfs_debug(struct super_block *s, int level, const char *fmt, ...);
+void print_indirect_item(struct buffer_head *bh, int item_num);
+void store_print_tb(struct tree_balance *tb);
+void print_cur_tb(char *mes);
+void print_de(struct reiserfs_dir_entry *de);
+void print_bi(struct buffer_info *bi, char *mes);
+#define PRINT_LEAF_ITEMS 1	/* print all items */
+#define PRINT_DIRECTORY_ITEMS 2	/* print directory items */
+#define PRINT_DIRECT_ITEMS 4	/* print contents of direct items */
+void print_block(struct buffer_head *bh, ...);
+void print_bmap(struct super_block *s, int silent);
+void print_bmap_block(int i, char *data, int size, int silent);
 /*void print_super_block (struct super_block * s, char * mes);*/
-void print_objectid_map (struct super_block * s);
-void print_block_head (struct buffer_head * bh, char * mes);
-void check_leaf (struct buffer_head * bh);
-void check_internal (struct buffer_head * bh);
-void print_statistics (struct super_block * s);
-char * reiserfs_hashname(int code);
+void print_objectid_map(struct super_block *s);
+void print_block_head(struct buffer_head *bh, char *mes);
+void check_leaf(struct buffer_head *bh);
+void check_internal(struct buffer_head *bh);
+void print_statistics(struct super_block *s);
+char *reiserfs_hashname(int code);
 
 /* lbalance.c */
-int leaf_move_items (int shift_mode, struct tree_balance * tb, int mov_num, int mov_bytes, struct buffer_head * Snew);
-int leaf_shift_left (struct tree_balance * tb, int shift_num, int shift_bytes);
-int leaf_shift_right (struct tree_balance * tb, int shift_num, int shift_bytes);
-void leaf_delete_items (struct buffer_info * cur_bi, int last_first, int first, int del_num, int del_bytes);
-void leaf_insert_into_buf (struct buffer_info * bi, int before, 
-                           struct item_head * inserted_item_ih, const char * inserted_item_body, int zeros_number);
-void leaf_paste_in_buffer (struct buffer_info * bi, int pasted_item_num, 
-                           int pos_in_item, int paste_size, const char * body, int zeros_number);
-void leaf_cut_from_buffer (struct buffer_info * bi, int cut_item_num, int pos_in_item, 
-                           int cut_size);
-void leaf_paste_entries (struct buffer_head * bh, int item_num, int before, 
-                         int new_entry_count, struct reiserfs_de_head * new_dehs, const char * records, int paste_size);
+int leaf_move_items(int shift_mode, struct tree_balance *tb, int mov_num,
+		    int mov_bytes, struct buffer_head *Snew);
+int leaf_shift_left(struct tree_balance *tb, int shift_num, int shift_bytes);
+int leaf_shift_right(struct tree_balance *tb, int shift_num, int shift_bytes);
+void leaf_delete_items(struct buffer_info *cur_bi, int last_first, int first,
+		       int del_num, int del_bytes);
+void leaf_insert_into_buf(struct buffer_info *bi, int before,
+			  struct item_head *inserted_item_ih,
+			  const char *inserted_item_body, int zeros_number);
+void leaf_paste_in_buffer(struct buffer_info *bi, int pasted_item_num,
+			  int pos_in_item, int paste_size, const char *body,
+			  int zeros_number);
+void leaf_cut_from_buffer(struct buffer_info *bi, int cut_item_num,
+			  int pos_in_item, int cut_size);
+void leaf_paste_entries(struct buffer_head *bh, int item_num, int before,
+			int new_entry_count, struct reiserfs_de_head *new_dehs,
+			const char *records, int paste_size);
 /* ibalance.c */
-int balance_internal (struct tree_balance * , int, int, struct item_head * , 
-                      struct buffer_head **);
+int balance_internal(struct tree_balance *, int, int, struct item_head *,
+		     struct buffer_head **);
 
 /* do_balance.c */
-void do_balance_mark_leaf_dirty (struct tree_balance * tb,
-					struct buffer_head * bh, int flag);
+void do_balance_mark_leaf_dirty(struct tree_balance *tb,
+				struct buffer_head *bh, int flag);
 #define do_balance_mark_internal_dirty do_balance_mark_leaf_dirty
 #define do_balance_mark_sb_dirty do_balance_mark_leaf_dirty
 
-void do_balance (struct tree_balance * tb, struct item_head * ih, 
-                 const char * body, int flag);
-void reiserfs_invalidate_buffer (struct tree_balance * tb, struct buffer_head * bh);
-
-int get_left_neighbor_position (struct tree_balance * tb, int h);
-int get_right_neighbor_position (struct tree_balance * tb, int h);
-void replace_key (struct tree_balance * tb, struct buffer_head *, int, struct buffer_head *, int);
-void make_empty_node (struct buffer_info *);
-struct buffer_head * get_FEB (struct tree_balance *);
+void do_balance(struct tree_balance *tb, struct item_head *ih,
+		const char *body, int flag);
+void reiserfs_invalidate_buffer(struct tree_balance *tb,
+				struct buffer_head *bh);
+
+int get_left_neighbor_position(struct tree_balance *tb, int h);
+int get_right_neighbor_position(struct tree_balance *tb, int h);
+void replace_key(struct tree_balance *tb, struct buffer_head *, int,
+		 struct buffer_head *, int);
+void make_empty_node(struct buffer_info *);
+struct buffer_head *get_FEB(struct tree_balance *);
 
 /* bitmap.c */
 
 /* structure contains hints for block allocator, and it is a container for
  * arguments, such as node, search path, transaction_handle, etc. */
- struct __reiserfs_blocknr_hint {
-     struct inode * inode;		/* inode passed to allocator, if we allocate unf. nodes */
-     long block;			/* file offset, in blocks */
-     struct in_core_key key;
-     struct path * path;		/* search path, used by allocator to deternine search_start by
-					 * various ways */
-     struct reiserfs_transaction_handle * th; /* transaction handle is needed to log super blocks and
-					       * bitmap blocks changes  */
-     b_blocknr_t beg, end;
-     b_blocknr_t search_start;		/* a field used to transfer search start value (block number)
+struct __reiserfs_blocknr_hint {
+	struct inode *inode;	/* inode passed to allocator, if we allocate unf. nodes */
+	long block;		/* file offset, in blocks */
+	struct in_core_key key;
+	struct path *path;	/* search path, used by allocator to deternine search_start by
+				 * various ways */
+	struct reiserfs_transaction_handle *th;	/* transaction handle is needed to log super blocks and
+						 * bitmap blocks changes  */
+	b_blocknr_t beg, end;
+	b_blocknr_t search_start;	/* a field used to transfer search start value (block number)
 					 * between different block allocator procedures
 					 * (determine_search_start() and others) */
-    int prealloc_size;			/* is set in determine_prealloc_size() function, used by underlayed
-					 * function that do actual allocation */
+	int prealloc_size;	/* is set in determine_prealloc_size() function, used by underlayed
+				 * function that do actual allocation */
 
-    unsigned formatted_node:1;		/* the allocator uses different polices for getting disk space for
+	unsigned formatted_node:1;	/* the allocator uses different polices for getting disk space for
 					 * formatted/unformatted blocks with/without preallocation */
-    unsigned preallocate:1;
+	unsigned preallocate:1;
 };
 
 typedef struct __reiserfs_blocknr_hint reiserfs_blocknr_hint_t;
 
-int reiserfs_parse_alloc_options (struct super_block *, char *);
-void reiserfs_init_alloc_options (struct super_block *s);
+int reiserfs_parse_alloc_options(struct super_block *, char *);
+void reiserfs_init_alloc_options(struct super_block *s);
 
 /*
  * given a directory, this will tell you what packing locality
@@ -2111,68 +2092,72 @@ void reiserfs_init_alloc_options (struct
  */
 __le32 reiserfs_choose_packing(struct inode *dir);
 
-int is_reusable (struct super_block * s, b_blocknr_t block, int bit_value);
-void reiserfs_free_block (struct reiserfs_transaction_handle *th, struct inode *, b_blocknr_t, int for_unformatted);
-int reiserfs_allocate_blocknrs(reiserfs_blocknr_hint_t *, b_blocknr_t * , int, int);
-extern inline int reiserfs_new_form_blocknrs (struct tree_balance * tb,
-					      b_blocknr_t *new_blocknrs, int amount_needed)
-{
-    reiserfs_blocknr_hint_t hint = {
-	.th = tb->transaction_handle,
-	.path = tb->tb_path,
-	.inode = NULL,
-	.key = tb->key,
-	.block = 0,
-	.formatted_node = 1
-    };
-    return reiserfs_allocate_blocknrs(&hint, new_blocknrs, amount_needed, 0);
-}
-
-extern inline int reiserfs_new_unf_blocknrs (struct reiserfs_transaction_handle *th,
-					     struct inode *inode,
-					     b_blocknr_t *new_blocknrs,
-					     struct path * path, long block)
-{
-    reiserfs_blocknr_hint_t hint = {
-	.th = th,
-	.path = path,
-	.inode = inode,
-	.block = block,
-	.formatted_node = 0,
-	.preallocate = 0
-    };
-    return reiserfs_allocate_blocknrs(&hint, new_blocknrs, 1, 0);
+int is_reusable(struct super_block *s, b_blocknr_t block, int bit_value);
+void reiserfs_free_block(struct reiserfs_transaction_handle *th, struct inode *,
+			 b_blocknr_t, int for_unformatted);
+int reiserfs_allocate_blocknrs(reiserfs_blocknr_hint_t *, b_blocknr_t *, int,
+			       int);
+extern inline int reiserfs_new_form_blocknrs(struct tree_balance *tb,
+					     b_blocknr_t * new_blocknrs,
+					     int amount_needed)
+{
+	reiserfs_blocknr_hint_t hint = {
+		.th = tb->transaction_handle,
+		.path = tb->tb_path,
+		.inode = NULL,
+		.key = tb->key,
+		.block = 0,
+		.formatted_node = 1
+	};
+	return reiserfs_allocate_blocknrs(&hint, new_blocknrs, amount_needed,
+					  0);
+}
+
+extern inline int reiserfs_new_unf_blocknrs(struct reiserfs_transaction_handle
+					    *th, struct inode *inode,
+					    b_blocknr_t * new_blocknrs,
+					    struct path *path, long block)
+{
+	reiserfs_blocknr_hint_t hint = {
+		.th = th,
+		.path = path,
+		.inode = inode,
+		.block = block,
+		.formatted_node = 0,
+		.preallocate = 0
+	};
+	return reiserfs_allocate_blocknrs(&hint, new_blocknrs, 1, 0);
 }
 
 #ifdef REISERFS_PREALLOCATE
-extern inline int reiserfs_new_unf_blocknrs2(struct reiserfs_transaction_handle *th,
-					     struct inode * inode,
-					     b_blocknr_t *new_blocknrs,
-					     struct path * path, long block)
-{
-    reiserfs_blocknr_hint_t hint = {
-	.th = th,
-	.path = path,
-	.inode = inode,
-	.block = block,
-	.formatted_node = 0,
-	.preallocate = 1
-    };
-    return reiserfs_allocate_blocknrs(&hint, new_blocknrs, 1, 0);
-}
-
-void reiserfs_discard_prealloc (struct reiserfs_transaction_handle *th, 
-				struct inode * inode);
-void reiserfs_discard_all_prealloc (struct reiserfs_transaction_handle *th);
+extern inline int reiserfs_new_unf_blocknrs2(struct reiserfs_transaction_handle
+					     *th, struct inode *inode,
+					     b_blocknr_t * new_blocknrs,
+					     struct path *path, long block)
+{
+	reiserfs_blocknr_hint_t hint = {
+		.th = th,
+		.path = path,
+		.inode = inode,
+		.block = block,
+		.formatted_node = 0,
+		.preallocate = 1
+	};
+	return reiserfs_allocate_blocknrs(&hint, new_blocknrs, 1, 0);
+}
+
+void reiserfs_discard_prealloc(struct reiserfs_transaction_handle *th,
+			       struct inode *inode);
+void reiserfs_discard_all_prealloc(struct reiserfs_transaction_handle *th);
 #endif
-void reiserfs_claim_blocks_to_be_allocated( struct super_block *sb, int blocks);
-void reiserfs_release_claimed_blocks( struct super_block *sb, int blocks);
+void reiserfs_claim_blocks_to_be_allocated(struct super_block *sb, int blocks);
+void reiserfs_release_claimed_blocks(struct super_block *sb, int blocks);
 int reiserfs_can_fit_pages(struct super_block *sb);
 
 /* hashes.c */
-__u32 keyed_hash (const signed char *msg, int len);
-__u32 yura_hash (const signed char *msg, int len);
-__u32 r5_hash (const signed char *msg, int len);
+__u32 keyed_hash(const signed char *msg, int len);
+__u32 yura_hash(const signed char *msg, int len);
+__u32 r5_hash(const signed char *msg, int len);
 
 /* the ext2 bit routines adjust for big or little endian as
 ** appropriate for the arch, so in our laziness we use them rather
@@ -2192,11 +2177,10 @@ __u32 r5_hash (const signed char *msg, i
    absolutely safe */
 #define SPARE_SPACE 500
 
-
 /* prototypes from ioctl.c */
-int reiserfs_ioctl (struct inode * inode, struct file * filp, 
- 		    unsigned int cmd, unsigned long arg);
- 
+int reiserfs_ioctl(struct inode *inode, struct file *filp,
+		   unsigned int cmd, unsigned long arg);
+
 /* ioctl's command */
 #define REISERFS_IOC_UNPACK		_IOW(0xCD,1,long)
 /* define following flags to be the same as in ext2, so that chattr(1),
@@ -2211,10 +2195,8 @@ int reiserfs_ioctl (struct inode * inode
    would evolve into real per-fs locks */
 #define reiserfs_write_lock( sb ) lock_kernel()
 #define reiserfs_write_unlock( sb ) unlock_kernel()
- 			         
+
 /* xattr stuff */
 #define REISERFS_XATTR_DIR_SEM(s) (REISERFS_SB(s)->xattr_dir_sem)
 
-#endif /* _LINUX_REISER_FS_H */
-
-
+#endif				/* _LINUX_REISER_FS_H */
diff --git a/include/linux/reiserfs_fs_i.h b/include/linux/reiserfs_fs_i.h
--- a/include/linux/reiserfs_fs_i.h
+++ b/include/linux/reiserfs_fs_i.h
@@ -10,54 +10,53 @@ typedef enum {
     /** this says what format of key do all items (but stat data) of
       an object have.  If this is set, that format is 3.6 otherwise
       - 3.5 */
-    i_item_key_version_mask    =  0x0001,
+	i_item_key_version_mask = 0x0001,
     /** If this is unset, object has 3.5 stat data, otherwise, it has
       3.6 stat data with 64bit size, 32bit nlink etc. */
-    i_stat_data_version_mask   =  0x0002,
+	i_stat_data_version_mask = 0x0002,
     /** file might need tail packing on close */
-    i_pack_on_close_mask       =  0x0004,
+	i_pack_on_close_mask = 0x0004,
     /** don't pack tail of file */
-    i_nopack_mask              =  0x0008,
+	i_nopack_mask = 0x0008,
     /** If those is set, "safe link" was created for this file during
       truncate or unlink. Safe link is used to avoid leakage of disk
       space on crash with some files open, but unlinked. */
-    i_link_saved_unlink_mask   =  0x0010,
-    i_link_saved_truncate_mask =  0x0020,
-    i_has_xattr_dir            =  0x0040,
-    i_data_log	               =  0x0080,
+	i_link_saved_unlink_mask = 0x0010,
+	i_link_saved_truncate_mask = 0x0020,
+	i_has_xattr_dir = 0x0040,
+	i_data_log = 0x0080,
 } reiserfs_inode_flags;
 
-
 struct reiserfs_inode_info {
-    __u32 i_key [4];/* key is still 4 32 bit integers */
+	__u32 i_key[4];		/* key is still 4 32 bit integers */
     /** transient inode flags that are never stored on disk. Bitmasks
       for this field are defined above. */
-    __u32 i_flags;
+	__u32 i_flags;
 
-    __u32 i_first_direct_byte; // offset of first byte stored in direct item.
+	__u32 i_first_direct_byte;	// offset of first byte stored in direct item.
 
-    /* copy of persistent inode flags read from sd_attrs. */
-    __u32 i_attrs;
+	/* copy of persistent inode flags read from sd_attrs. */
+	__u32 i_attrs;
 
-    int i_prealloc_block; /* first unused block of a sequence of unused blocks */
-    int i_prealloc_count; /* length of that sequence */
-    struct list_head i_prealloc_list; /* per-transaction list of inodes which
-                                       * have preallocated blocks */
-
-    unsigned new_packing_locality:1;  /* new_packig_locality is created; new blocks
-				       * for the contents of this directory should be
-				       * displaced */
-
-    /* we use these for fsync or O_SYNC to decide which transaction
-    ** needs to be committed in order for this inode to be properly
-    ** flushed */
-    unsigned long i_trans_id ;
-    struct reiserfs_journal_list *i_jl;
-
-    struct posix_acl *i_acl_access;
-    struct posix_acl *i_acl_default;
-    struct rw_semaphore xattr_sem;
-    struct inode vfs_inode;
+	int i_prealloc_block;	/* first unused block of a sequence of unused blocks */
+	int i_prealloc_count;	/* length of that sequence */
+	struct list_head i_prealloc_list;	/* per-transaction list of inodes which
+						 * have preallocated blocks */
+
+	unsigned new_packing_locality:1;	/* new_packig_locality is created; new blocks
+						 * for the contents of this directory should be
+						 * displaced */
+
+	/* we use these for fsync or O_SYNC to decide which transaction
+	 ** needs to be committed in order for this inode to be properly
+	 ** flushed */
+	unsigned long i_trans_id;
+	struct reiserfs_journal_list *i_jl;
+
+	struct posix_acl *i_acl_access;
+	struct posix_acl *i_acl_default;
+	struct rw_semaphore xattr_sem;
+	struct inode vfs_inode;
 };
 
 #endif
diff --git a/include/linux/reiserfs_fs_sb.h b/include/linux/reiserfs_fs_sb.h
--- a/include/linux/reiserfs_fs_sb.h
+++ b/include/linux/reiserfs_fs_sb.h
@@ -10,7 +10,7 @@
 #endif
 
 typedef enum {
-  reiserfs_attrs_cleared	= 0x00000001,
+	reiserfs_attrs_cleared = 0x00000001,
 } reiserfs_super_block_flags;
 
 /* struct reiserfs_super_block accessors/mutators
@@ -61,7 +61,7 @@ typedef enum {
 #define sb_umount_state(sbp)       (le16_to_cpu((sbp)->s_v1.s_umount_state))
 #define set_sb_umount_state(sbp,v) ((sbp)->s_v1.s_umount_state = cpu_to_le16(v))
 #define sb_fs_state(sbp)           (le16_to_cpu((sbp)->s_v1.s_fs_state))
-#define set_sb_fs_state(sbp,v)     ((sbp)->s_v1.s_fs_state = cpu_to_le16(v)) 
+#define set_sb_fs_state(sbp,v)     ((sbp)->s_v1.s_fs_state = cpu_to_le16(v))
 #define sb_hash_function_code(sbp) \
               (le32_to_cpu((sbp)->s_v1.s_hash_function_code))
 #define set_sb_hash_function_code(sbp,v) \
@@ -103,10 +103,10 @@ typedef enum {
 
 /* don't mess with these for a while */
 				/* we have a node size define somewhere in reiserfs_fs.h. -Hans */
-#define JOURNAL_BLOCK_SIZE  4096 /* BUG gotta get rid of this */
-#define JOURNAL_MAX_CNODE   1500 /* max cnodes to allocate. */
-#define JOURNAL_HASH_SIZE 8192   
-#define JOURNAL_NUM_BITMAPS 5 /* number of copies of the bitmaps to have floating.  Must be >= 2 */
+#define JOURNAL_BLOCK_SIZE  4096	/* BUG gotta get rid of this */
+#define JOURNAL_MAX_CNODE   1500	/* max cnodes to allocate. */
+#define JOURNAL_HASH_SIZE 8192
+#define JOURNAL_NUM_BITMAPS 5	/* number of copies of the bitmaps to have floating.  Must be >= 2 */
 
 /* One of these for every block in every transaction
 ** Each one is in two hash tables.  First, a hash of the current transaction, and after journal_end, a
@@ -117,27 +117,27 @@ typedef enum {
 ** to a given transaction.
 */
 struct reiserfs_journal_cnode {
-  struct buffer_head *bh ;		 /* real buffer head */
-  struct super_block *sb ;		 /* dev of real buffer head */
-  __u32 blocknr ;		 /* block number of real buffer head, == 0 when buffer on disk */
-  long state ;
-  struct reiserfs_journal_list *jlist ;  /* journal list this cnode lives in */
-  struct reiserfs_journal_cnode *next ;  /* next in transaction list */
-  struct reiserfs_journal_cnode *prev ;  /* prev in transaction list */
-  struct reiserfs_journal_cnode *hprev ; /* prev in hash list */
-  struct reiserfs_journal_cnode *hnext ; /* next in hash list */
+	struct buffer_head *bh;	/* real buffer head */
+	struct super_block *sb;	/* dev of real buffer head */
+	__u32 blocknr;		/* block number of real buffer head, == 0 when buffer on disk */
+	long state;
+	struct reiserfs_journal_list *jlist;	/* journal list this cnode lives in */
+	struct reiserfs_journal_cnode *next;	/* next in transaction list */
+	struct reiserfs_journal_cnode *prev;	/* prev in transaction list */
+	struct reiserfs_journal_cnode *hprev;	/* prev in hash list */
+	struct reiserfs_journal_cnode *hnext;	/* next in hash list */
 };
 
 struct reiserfs_bitmap_node {
-  int id ;
-  char *data ;
-  struct list_head list ;
-} ;
+	int id;
+	char *data;
+	struct list_head list;
+};
 
 struct reiserfs_list_bitmap {
-  struct reiserfs_journal_list *journal_list ;
-  struct reiserfs_bitmap_node **bitmaps ;
-} ;
+	struct reiserfs_journal_list *journal_list;
+	struct reiserfs_bitmap_node **bitmaps;
+};
 
 /*
 ** one of these for each transaction.  The most important part here is the j_realblock.
@@ -146,273 +146,269 @@ struct reiserfs_list_bitmap {
 ** and to make sure every real block in a transaction is on disk before allowing the log area
 ** to be overwritten */
 struct reiserfs_journal_list {
-  unsigned long j_start ;
-  unsigned long j_state;
-  unsigned long j_len ;
-  atomic_t j_nonzerolen ;
-  atomic_t j_commit_left ;
-  atomic_t j_older_commits_done ;      /* all commits older than this on disk*/
-  struct semaphore j_commit_lock;
-  unsigned long j_trans_id ;
-  time_t j_timestamp ;
-  struct reiserfs_list_bitmap *j_list_bitmap ;
-  struct buffer_head *j_commit_bh ; /* commit buffer head */
-  struct reiserfs_journal_cnode *j_realblock  ;
-  struct reiserfs_journal_cnode *j_freedlist ; /* list of buffers that were freed during this trans.  free each of these on flush */
-  /* time ordered list of all active transactions */
-  struct list_head j_list;
-
-  /* time ordered list of all transactions we haven't tried to flush yet */
-  struct list_head j_working_list;
-
-  /* list of tail conversion targets in need of flush before commit */
-  struct list_head j_tail_bh_list;
-  /* list of data=ordered buffers in need of flush before commit */
-  struct list_head j_bh_list;
-  int j_refcount;
-} ;
+	unsigned long j_start;
+	unsigned long j_state;
+	unsigned long j_len;
+	atomic_t j_nonzerolen;
+	atomic_t j_commit_left;
+	atomic_t j_older_commits_done;	/* all commits older than this on disk */
+	struct semaphore j_commit_lock;
+	unsigned long j_trans_id;
+	time_t j_timestamp;
+	struct reiserfs_list_bitmap *j_list_bitmap;
+	struct buffer_head *j_commit_bh;	/* commit buffer head */
+	struct reiserfs_journal_cnode *j_realblock;
+	struct reiserfs_journal_cnode *j_freedlist;	/* list of buffers that were freed during this trans.  free each of these on flush */
+	/* time ordered list of all active transactions */
+	struct list_head j_list;
+
+	/* time ordered list of all transactions we haven't tried to flush yet */
+	struct list_head j_working_list;
+
+	/* list of tail conversion targets in need of flush before commit */
+	struct list_head j_tail_bh_list;
+	/* list of data=ordered buffers in need of flush before commit */
+	struct list_head j_bh_list;
+	int j_refcount;
+};
 
 struct reiserfs_journal {
-  struct buffer_head ** j_ap_blocks ; /* journal blocks on disk */
-  struct reiserfs_journal_cnode *j_last ; /* newest journal block */
-  struct reiserfs_journal_cnode *j_first ; /*  oldest journal block.  start here for traverse */
-
-  struct file         *j_dev_file;
-  struct block_device *j_dev_bd;  
-  int j_1st_reserved_block;     /* first block on s_dev of reserved area journal */        
-	
-  long j_state ;			
-  unsigned long j_trans_id ;
-  unsigned long j_mount_id ;
-  unsigned long j_start ;             /* start of current waiting commit (index into j_ap_blocks) */
-  unsigned long j_len ;               /* lenght of current waiting commit */
-  unsigned long j_len_alloc ;         /* number of buffers requested by journal_begin() */
-  atomic_t j_wcount ;            /* count of writers for current commit */
-  unsigned long j_bcount ;            /* batch count. allows turning X transactions into 1 */
-  unsigned long j_first_unflushed_offset ;  /* first unflushed transactions offset */
-  unsigned long j_last_flush_trans_id ;    /* last fully flushed journal timestamp */
-  struct buffer_head *j_header_bh ;   
-
-  time_t j_trans_start_time ;         /* time this transaction started */
-  struct semaphore j_lock;
-  struct semaphore j_flush_sem;
-  wait_queue_head_t j_join_wait ;    /* wait for current transaction to finish before starting new one */
-  atomic_t j_jlock ;                       /* lock for j_join_wait */
-  int j_list_bitmap_index ;	      /* number of next list bitmap to use */
-  int j_must_wait ;		       /* no more journal begins allowed. MUST sleep on j_join_wait */
-  int j_next_full_flush ;             /* next journal_end will flush all journal list */
-  int j_next_async_flush ;             /* next journal_end will flush all async commits */
-
-  int j_cnode_used ;	      /* number of cnodes on the used list */
-  int j_cnode_free ;          /* number of cnodes on the free list */
-
-  unsigned int j_trans_max ;           /* max number of blocks in a transaction.  */
-  unsigned int j_max_batch ;           /* max number of blocks to batch into a trans */
-  unsigned int j_max_commit_age ;      /* in seconds, how old can an async commit be */
-  unsigned int j_max_trans_age ;       /* in seconds, how old can a transaction be */
-  unsigned int j_default_max_commit_age ; /* the default for the max commit age */
-
-  struct reiserfs_journal_cnode *j_cnode_free_list ;
-  struct reiserfs_journal_cnode *j_cnode_free_orig ; /* orig pointer returned from vmalloc */
-
-  struct reiserfs_journal_list *j_current_jl;
-  int j_free_bitmap_nodes ;
-  int j_used_bitmap_nodes ;
-
-  int j_num_lists;      /* total number of active transactions */
-  int j_num_work_lists; /* number that need attention from kreiserfsd */
-
-  /* debugging to make sure things are flushed in order */
-  int j_last_flush_id;
-
-  /* debugging to make sure things are committed in order */
-  int j_last_commit_id;
-
-  struct list_head j_bitmap_nodes ;
-  struct list_head j_dirty_buffers ;
-  spinlock_t j_dirty_buffers_lock ; /* protects j_dirty_buffers */
-
-  /* list of all active transactions */
-  struct list_head j_journal_list;
-  /* lists that haven't been touched by writeback attempts */
-  struct list_head j_working_list;
-
-  struct reiserfs_list_bitmap j_list_bitmap[JOURNAL_NUM_BITMAPS] ;	/* array of bitmaps to record the deleted blocks */
-  struct reiserfs_journal_cnode *j_hash_table[JOURNAL_HASH_SIZE] ; 	    /* hash table for real buffer heads in current trans */ 
-  struct reiserfs_journal_cnode *j_list_hash_table[JOURNAL_HASH_SIZE] ; /* hash table for all the real buffer heads in all 
-  										the transactions */
-  struct list_head j_prealloc_list;     /* list of inodes which have preallocated blocks */
-  int j_persistent_trans;
-  unsigned long j_max_trans_size ;
-  unsigned long j_max_batch_size ;
-
-  int j_errno;
-
-  /* when flushing ordered buffers, throttle new ordered writers */
-  struct work_struct j_work;
-  atomic_t j_async_throttle;
+	struct buffer_head **j_ap_blocks;	/* journal blocks on disk */
+	struct reiserfs_journal_cnode *j_last;	/* newest journal block */
+	struct reiserfs_journal_cnode *j_first;	/*  oldest journal block.  start here for traverse */
+
+	struct file *j_dev_file;
+	struct block_device *j_dev_bd;
+	int j_1st_reserved_block;	/* first block on s_dev of reserved area journal */
+
+	long j_state;
+	unsigned long j_trans_id;
+	unsigned long j_mount_id;
+	unsigned long j_start;	/* start of current waiting commit (index into j_ap_blocks) */
+	unsigned long j_len;	/* lenght of current waiting commit */
+	unsigned long j_len_alloc;	/* number of buffers requested by journal_begin() */
+	atomic_t j_wcount;	/* count of writers for current commit */
+	unsigned long j_bcount;	/* batch count. allows turning X transactions into 1 */
+	unsigned long j_first_unflushed_offset;	/* first unflushed transactions offset */
+	unsigned long j_last_flush_trans_id;	/* last fully flushed journal timestamp */
+	struct buffer_head *j_header_bh;
+
+	time_t j_trans_start_time;	/* time this transaction started */
+	struct semaphore j_lock;
+	struct semaphore j_flush_sem;
+	wait_queue_head_t j_join_wait;	/* wait for current transaction to finish before starting new one */
+	atomic_t j_jlock;	/* lock for j_join_wait */
+	int j_list_bitmap_index;	/* number of next list bitmap to use */
+	int j_must_wait;	/* no more journal begins allowed. MUST sleep on j_join_wait */
+	int j_next_full_flush;	/* next journal_end will flush all journal list */
+	int j_next_async_flush;	/* next journal_end will flush all async commits */
+
+	int j_cnode_used;	/* number of cnodes on the used list */
+	int j_cnode_free;	/* number of cnodes on the free list */
+
+	unsigned int j_trans_max;	/* max number of blocks in a transaction.  */
+	unsigned int j_max_batch;	/* max number of blocks to batch into a trans */
+	unsigned int j_max_commit_age;	/* in seconds, how old can an async commit be */
+	unsigned int j_max_trans_age;	/* in seconds, how old can a transaction be */
+	unsigned int j_default_max_commit_age;	/* the default for the max commit age */
+
+	struct reiserfs_journal_cnode *j_cnode_free_list;
+	struct reiserfs_journal_cnode *j_cnode_free_orig;	/* orig pointer returned from vmalloc */
+
+	struct reiserfs_journal_list *j_current_jl;
+	int j_free_bitmap_nodes;
+	int j_used_bitmap_nodes;
+
+	int j_num_lists;	/* total number of active transactions */
+	int j_num_work_lists;	/* number that need attention from kreiserfsd */
+
+	/* debugging to make sure things are flushed in order */
+	int j_last_flush_id;
+
+	/* debugging to make sure things are committed in order */
+	int j_last_commit_id;
+
+	struct list_head j_bitmap_nodes;
+	struct list_head j_dirty_buffers;
+	spinlock_t j_dirty_buffers_lock;	/* protects j_dirty_buffers */
+
+	/* list of all active transactions */
+	struct list_head j_journal_list;
+	/* lists that haven't been touched by writeback attempts */
+	struct list_head j_working_list;
+
+	struct reiserfs_list_bitmap j_list_bitmap[JOURNAL_NUM_BITMAPS];	/* array of bitmaps to record the deleted blocks */
+	struct reiserfs_journal_cnode *j_hash_table[JOURNAL_HASH_SIZE];	/* hash table for real buffer heads in current trans */
+	struct reiserfs_journal_cnode *j_list_hash_table[JOURNAL_HASH_SIZE];	/* hash table for all the real buffer heads in all 
+										   the transactions */
+	struct list_head j_prealloc_list;	/* list of inodes which have preallocated blocks */
+	int j_persistent_trans;
+	unsigned long j_max_trans_size;
+	unsigned long j_max_batch_size;
+
+	int j_errno;
+
+	/* when flushing ordered buffers, throttle new ordered writers */
+	struct work_struct j_work;
+	atomic_t j_async_throttle;
 };
 
 enum journal_state_bits {
-    J_WRITERS_BLOCKED = 1,   /* set when new writers not allowed */
-    J_WRITERS_QUEUED,        /* set when log is full due to too many writers */
-    J_ABORTED,               /* set when log is aborted */
+	J_WRITERS_BLOCKED = 1,	/* set when new writers not allowed */
+	J_WRITERS_QUEUED,	/* set when log is full due to too many writers */
+	J_ABORTED,		/* set when log is aborted */
 };
 
+#define JOURNAL_DESC_MAGIC "ReIsErLB"	/* ick.  magic string to find desc blocks in the journal */
 
-#define JOURNAL_DESC_MAGIC "ReIsErLB" /* ick.  magic string to find desc blocks in the journal */
+typedef __u32(*hashf_t) (const signed char *, int);
 
-typedef __u32 (*hashf_t) (const signed char *, int);
-
-struct reiserfs_bitmap_info
-{
-    // FIXME: Won't work with block sizes > 8K
-    __u16  first_zero_hint;
-    __u16  free_count;
-    struct buffer_head *bh; /* the actual bitmap */
+struct reiserfs_bitmap_info {
+	// FIXME: Won't work with block sizes > 8K
+	__u16 first_zero_hint;
+	__u16 free_count;
+	struct buffer_head *bh;	/* the actual bitmap */
 };
 
 struct proc_dir_entry;
 
 #if defined( CONFIG_PROC_FS ) && defined( CONFIG_REISERFS_PROC_INFO )
 typedef unsigned long int stat_cnt_t;
-typedef struct reiserfs_proc_info_data
-{
-  spinlock_t lock;
-  int exiting;
-  int max_hash_collisions;
-
-  stat_cnt_t breads;
-  stat_cnt_t bread_miss;
-  stat_cnt_t search_by_key;
-  stat_cnt_t search_by_key_fs_changed;
-  stat_cnt_t search_by_key_restarted;
-
-  stat_cnt_t insert_item_restarted;
-  stat_cnt_t paste_into_item_restarted;
-  stat_cnt_t cut_from_item_restarted;
-  stat_cnt_t delete_solid_item_restarted;
-  stat_cnt_t delete_item_restarted;
-
-  stat_cnt_t leaked_oid;
-  stat_cnt_t leaves_removable;
-
-  /* balances per level. Use explicit 5 as MAX_HEIGHT is not visible yet. */
-  stat_cnt_t balance_at[ 5 ]; /* XXX */
-  /* sbk == search_by_key */
-  stat_cnt_t sbk_read_at[ 5 ]; /* XXX */
-  stat_cnt_t sbk_fs_changed[ 5 ];
-  stat_cnt_t sbk_restarted[ 5 ];
-  stat_cnt_t items_at[ 5 ]; /* XXX */
-  stat_cnt_t free_at[ 5 ]; /* XXX */
-  stat_cnt_t can_node_be_removed[ 5 ]; /* XXX */
-  long int lnum[ 5 ]; /* XXX */
-  long int rnum[ 5 ]; /* XXX */
-  long int lbytes[ 5 ]; /* XXX */
-  long int rbytes[ 5 ]; /* XXX */
-  stat_cnt_t get_neighbors[ 5 ];
-  stat_cnt_t get_neighbors_restart[ 5 ];
-  stat_cnt_t need_l_neighbor[ 5 ];
-  stat_cnt_t need_r_neighbor[ 5 ];
-
-  stat_cnt_t free_block;
-  struct __scan_bitmap_stats {
-	stat_cnt_t call;
-	stat_cnt_t wait;
-	stat_cnt_t bmap;
-	stat_cnt_t retry;
-	stat_cnt_t in_journal_hint;
-	stat_cnt_t in_journal_nohint;
-	stat_cnt_t stolen;
-  } scan_bitmap;
-  struct __journal_stats {
-	stat_cnt_t in_journal;
-	stat_cnt_t in_journal_bitmap;
-	stat_cnt_t in_journal_reusable;
-	stat_cnt_t lock_journal;
-	stat_cnt_t lock_journal_wait;
-	stat_cnt_t journal_being;
-	stat_cnt_t journal_relock_writers;
-	stat_cnt_t journal_relock_wcount;
-	stat_cnt_t mark_dirty;
-	stat_cnt_t mark_dirty_already;
-	stat_cnt_t mark_dirty_notjournal;
-	stat_cnt_t restore_prepared;
-	stat_cnt_t prepare;
-	stat_cnt_t prepare_retry;
-  } journal;
+typedef struct reiserfs_proc_info_data {
+	spinlock_t lock;
+	int exiting;
+	int max_hash_collisions;
+
+	stat_cnt_t breads;
+	stat_cnt_t bread_miss;
+	stat_cnt_t search_by_key;
+	stat_cnt_t search_by_key_fs_changed;
+	stat_cnt_t search_by_key_restarted;
+
+	stat_cnt_t insert_item_restarted;
+	stat_cnt_t paste_into_item_restarted;
+	stat_cnt_t cut_from_item_restarted;
+	stat_cnt_t delete_solid_item_restarted;
+	stat_cnt_t delete_item_restarted;
+
+	stat_cnt_t leaked_oid;
+	stat_cnt_t leaves_removable;
+
+	/* balances per level. Use explicit 5 as MAX_HEIGHT is not visible yet. */
+	stat_cnt_t balance_at[5];	/* XXX */
+	/* sbk == search_by_key */
+	stat_cnt_t sbk_read_at[5];	/* XXX */
+	stat_cnt_t sbk_fs_changed[5];
+	stat_cnt_t sbk_restarted[5];
+	stat_cnt_t items_at[5];	/* XXX */
+	stat_cnt_t free_at[5];	/* XXX */
+	stat_cnt_t can_node_be_removed[5];	/* XXX */
+	long int lnum[5];	/* XXX */
+	long int rnum[5];	/* XXX */
+	long int lbytes[5];	/* XXX */
+	long int rbytes[5];	/* XXX */
+	stat_cnt_t get_neighbors[5];
+	stat_cnt_t get_neighbors_restart[5];
+	stat_cnt_t need_l_neighbor[5];
+	stat_cnt_t need_r_neighbor[5];
+
+	stat_cnt_t free_block;
+	struct __scan_bitmap_stats {
+		stat_cnt_t call;
+		stat_cnt_t wait;
+		stat_cnt_t bmap;
+		stat_cnt_t retry;
+		stat_cnt_t in_journal_hint;
+		stat_cnt_t in_journal_nohint;
+		stat_cnt_t stolen;
+	} scan_bitmap;
+	struct __journal_stats {
+		stat_cnt_t in_journal;
+		stat_cnt_t in_journal_bitmap;
+		stat_cnt_t in_journal_reusable;
+		stat_cnt_t lock_journal;
+		stat_cnt_t lock_journal_wait;
+		stat_cnt_t journal_being;
+		stat_cnt_t journal_relock_writers;
+		stat_cnt_t journal_relock_wcount;
+		stat_cnt_t mark_dirty;
+		stat_cnt_t mark_dirty_already;
+		stat_cnt_t mark_dirty_notjournal;
+		stat_cnt_t restore_prepared;
+		stat_cnt_t prepare;
+		stat_cnt_t prepare_retry;
+	} journal;
 } reiserfs_proc_info_data_t;
 #else
-typedef struct reiserfs_proc_info_data
-{} reiserfs_proc_info_data_t;
+typedef struct reiserfs_proc_info_data {
+} reiserfs_proc_info_data_t;
 #endif
 
 /* reiserfs union of in-core super block data */
-struct reiserfs_sb_info
-{
-    struct buffer_head * s_sbh;                   /* Buffer containing the super block */
-				/* both the comment and the choice of
-                                   name are unclear for s_rs -Hans */
-    struct reiserfs_super_block * s_rs;           /* Pointer to the super block in the buffer */
-    struct reiserfs_bitmap_info * s_ap_bitmap;
-    struct reiserfs_journal *s_journal ;		/* pointer to journal information */
-    unsigned short s_mount_state;                 /* reiserfs state (valid, invalid) */
-  
-				/* Comment? -Hans */
-    void (*end_io_handler)(struct buffer_head *, int);
-    hashf_t s_hash_function;	/* pointer to function which is used
-                                   to sort names in directory. Set on
-                                   mount */
-    unsigned long s_mount_opt;	/* reiserfs's mount options are set
-                                   here (currently - NOTAIL, NOLOG,
-                                   REPLAYONLY) */
-
-    struct {			/* This is a structure that describes block allocator options */
-	unsigned long bits;	/* Bitfield for enable/disable kind of options */
-	unsigned long large_file_size; /* size started from which we consider file to be a large one(in blocks) */
-	int border;		/* percentage of disk, border takes */
-	int preallocmin;	/* Minimal file size (in blocks) starting from which we do preallocations */
-	int preallocsize;	/* Number of blocks we try to prealloc when file
-				   reaches preallocmin size (in blocks) or
-				   prealloc_list is empty. */
-    } s_alloc_options;
-
-				/* Comment? -Hans */
-    wait_queue_head_t s_wait;
-				/* To be obsoleted soon by per buffer seals.. -Hans */
-    atomic_t s_generation_counter; // increased by one every time the
-    // tree gets re-balanced
-    unsigned long s_properties;    /* File system properties. Currently holds
-				     on-disk FS format */
-    
-    /* session statistics */
-    int s_kmallocs;
-    int s_disk_reads;
-    int s_disk_writes;
-    int s_fix_nodes;
-    int s_do_balance;
-    int s_unneeded_left_neighbor;
-    int s_good_search_by_key_reada;
-    int s_bmaps;
-    int s_bmaps_without_search;
-    int s_direct2indirect;
-    int s_indirect2direct;
+struct reiserfs_sb_info {
+	struct buffer_head *s_sbh;	/* Buffer containing the super block */
+	/* both the comment and the choice of
+	   name are unclear for s_rs -Hans */
+	struct reiserfs_super_block *s_rs;	/* Pointer to the super block in the buffer */
+	struct reiserfs_bitmap_info *s_ap_bitmap;
+	struct reiserfs_journal *s_journal;	/* pointer to journal information */
+	unsigned short s_mount_state;	/* reiserfs state (valid, invalid) */
+
+	/* Comment? -Hans */
+	void (*end_io_handler) (struct buffer_head *, int);
+	hashf_t s_hash_function;	/* pointer to function which is used
+					   to sort names in directory. Set on
+					   mount */
+	unsigned long s_mount_opt;	/* reiserfs's mount options are set
+					   here (currently - NOTAIL, NOLOG,
+					   REPLAYONLY) */
+
+	struct {		/* This is a structure that describes block allocator options */
+		unsigned long bits;	/* Bitfield for enable/disable kind of options */
+		unsigned long large_file_size;	/* size started from which we consider file to be a large one(in blocks) */
+		int border;	/* percentage of disk, border takes */
+		int preallocmin;	/* Minimal file size (in blocks) starting from which we do preallocations */
+		int preallocsize;	/* Number of blocks we try to prealloc when file
+					   reaches preallocmin size (in blocks) or
+					   prealloc_list is empty. */
+	} s_alloc_options;
+
+	/* Comment? -Hans */
+	wait_queue_head_t s_wait;
+	/* To be obsoleted soon by per buffer seals.. -Hans */
+	atomic_t s_generation_counter;	// increased by one every time the
+	// tree gets re-balanced
+	unsigned long s_properties;	/* File system properties. Currently holds
+					   on-disk FS format */
+
+	/* session statistics */
+	int s_kmallocs;
+	int s_disk_reads;
+	int s_disk_writes;
+	int s_fix_nodes;
+	int s_do_balance;
+	int s_unneeded_left_neighbor;
+	int s_good_search_by_key_reada;
+	int s_bmaps;
+	int s_bmaps_without_search;
+	int s_direct2indirect;
+	int s_indirect2direct;
 	/* set up when it's ok for reiserfs_read_inode2() to read from
 	   disk inode with nlink==0. Currently this is only used during
 	   finish_unfinished() processing at mount time */
-    int s_is_unlinked_ok;
-    reiserfs_proc_info_data_t s_proc_info_data;
-    struct proc_dir_entry *procdir;
-    int reserved_blocks; /* amount of blocks reserved for further allocations */
-    spinlock_t bitmap_lock; /* this lock on now only used to protect reserved_blocks variable */
-    struct dentry *priv_root; /* root of /.reiserfs_priv */
-    struct dentry *xattr_root; /* root of /.reiserfs_priv/.xa */
-    struct rw_semaphore xattr_dir_sem;
+	int s_is_unlinked_ok;
+	reiserfs_proc_info_data_t s_proc_info_data;
+	struct proc_dir_entry *procdir;
+	int reserved_blocks;	/* amount of blocks reserved for further allocations */
+	spinlock_t bitmap_lock;	/* this lock on now only used to protect reserved_blocks variable */
+	struct dentry *priv_root;	/* root of /.reiserfs_priv */
+	struct dentry *xattr_root;	/* root of /.reiserfs_priv/.xa */
+	struct rw_semaphore xattr_dir_sem;
 
-    int j_errno;
+	int j_errno;
 #ifdef CONFIG_QUOTA
-    char *s_qf_names[MAXQUOTAS];
-    int s_jquota_fmt;
+	char *s_qf_names[MAXQUOTAS];
+	int s_jquota_fmt;
 #endif
 };
 
@@ -422,14 +418,14 @@ struct reiserfs_sb_info
 
 enum reiserfs_mount_options {
 /* Mount options */
-    REISERFS_LARGETAIL,  /* large tails will be created in a session */
-    REISERFS_SMALLTAIL,  /* small (for files less than block size) tails will be created in a session */
-    REPLAYONLY, /* replay journal and return 0. Use by fsck */
-    REISERFS_CONVERT,    /* -o conv: causes conversion of old
-                                 format super block to the new
-                                 format. If not specified - old
-                                 partition will be dealt with in a
-                                 manner of 3.5.x */
+	REISERFS_LARGETAIL,	/* large tails will be created in a session */
+	REISERFS_SMALLTAIL,	/* small (for files less than block size) tails will be created in a session */
+	REPLAYONLY,		/* replay journal and return 0. Use by fsck */
+	REISERFS_CONVERT,	/* -o conv: causes conversion of old
+				   format super block to the new
+				   format. If not specified - old
+				   partition will be dealt with in a
+				   manner of 3.5.x */
 
 /* -o hash={tea, rupasov, r5, detect} is meant for properly mounting 
 ** reiserfs disks from 3.5.19 or earlier.  99% of the time, this option
@@ -439,39 +435,41 @@ enum reiserfs_mount_options {
 ** the existing hash on the FS, so if you have a tea hash disk, and mount
 ** with -o hash=rupasov, the mount will fail.
 */
-    FORCE_TEA_HASH,      /* try to force tea hash on mount */
-    FORCE_RUPASOV_HASH,  /* try to force rupasov hash on mount */
-    FORCE_R5_HASH,       /* try to force rupasov hash on mount */
-    FORCE_HASH_DETECT,   /* try to detect hash function on mount */
-
-    REISERFS_DATA_LOG,
-    REISERFS_DATA_ORDERED,
-    REISERFS_DATA_WRITEBACK,
+	FORCE_TEA_HASH,		/* try to force tea hash on mount */
+	FORCE_RUPASOV_HASH,	/* try to force rupasov hash on mount */
+	FORCE_R5_HASH,		/* try to force rupasov hash on mount */
+	FORCE_HASH_DETECT,	/* try to detect hash function on mount */
+
+	REISERFS_DATA_LOG,
+	REISERFS_DATA_ORDERED,
+	REISERFS_DATA_WRITEBACK,
 
 /* used for testing experimental features, makes benchmarking new
    features with and without more convenient, should never be used by
    users in any code shipped to users (ideally) */
 
-    REISERFS_NO_BORDER,
-    REISERFS_NO_UNHASHED_RELOCATION,
-    REISERFS_HASHED_RELOCATION,
-    REISERFS_ATTRS,
-    REISERFS_XATTRS,
-    REISERFS_XATTRS_USER,
-    REISERFS_POSIXACL,
-    REISERFS_BARRIER_NONE,
-    REISERFS_BARRIER_FLUSH,
-
-    /* Actions on error */
-    REISERFS_ERROR_PANIC,
-    REISERFS_ERROR_RO,
-    REISERFS_ERROR_CONTINUE,
-
-    REISERFS_TEST1,
-    REISERFS_TEST2,
-    REISERFS_TEST3,
-    REISERFS_TEST4,
-    REISERFS_UNSUPPORTED_OPT,
+	REISERFS_NO_BORDER,
+	REISERFS_NO_UNHASHED_RELOCATION,
+	REISERFS_HASHED_RELOCATION,
+	REISERFS_ATTRS,
+	REISERFS_XATTRS,
+	REISERFS_XATTRS_USER,
+	REISERFS_POSIXACL,
+	REISERFS_BARRIER_NONE,
+	REISERFS_BARRIER_FLUSH,
+
+	/* Actions on error */
+	REISERFS_ERROR_PANIC,
+	REISERFS_ERROR_RO,
+	REISERFS_ERROR_CONTINUE,
+
+	REISERFS_QUOTA,		/* Some quota option specified */
+
+	REISERFS_TEST1,
+	REISERFS_TEST2,
+	REISERFS_TEST3,
+	REISERFS_TEST4,
+	REISERFS_UNSUPPORTED_OPT,
 };
 
 #define reiserfs_r5_hash(s) (REISERFS_SB(s)->s_mount_opt & (1 << FORCE_R5_HASH))
@@ -502,18 +500,17 @@ enum reiserfs_mount_options {
 #define reiserfs_error_panic(s) (REISERFS_SB(s)->s_mount_opt & (1 << REISERFS_ERROR_PANIC))
 #define reiserfs_error_ro(s) (REISERFS_SB(s)->s_mount_opt & (1 << REISERFS_ERROR_RO))
 
-void reiserfs_file_buffer (struct buffer_head * bh, int list);
+void reiserfs_file_buffer(struct buffer_head *bh, int list);
 extern struct file_system_type reiserfs_fs_type;
-int reiserfs_resize(struct super_block *, unsigned long) ;
+int reiserfs_resize(struct super_block *, unsigned long);
 
 #define CARRY_ON                0
 #define SCHEDULE_OCCURRED       1
 
-
 #define SB_BUFFER_WITH_SB(s) (REISERFS_SB(s)->s_sbh)
 #define SB_JOURNAL(s) (REISERFS_SB(s)->s_journal)
 #define SB_JOURNAL_1st_RESERVED_BLOCK(s) (SB_JOURNAL(s)->j_1st_reserved_block)
-#define SB_JOURNAL_LEN_FREE(s) (SB_JOURNAL(s)->j_journal_len_free) 
+#define SB_JOURNAL_LEN_FREE(s) (SB_JOURNAL(s)->j_journal_len_free)
 #define SB_AP_BITMAP(s) (REISERFS_SB(s)->s_ap_bitmap)
 
 #define SB_DISK_JOURNAL_HEAD(s) (SB_JOURNAL(s)->j_header_bh->)
@@ -523,13 +520,14 @@ int reiserfs_resize(struct super_block *
  */
 static inline char *reiserfs_bdevname(struct super_block *s)
 {
-        return (s == NULL) ? "Null superblock" : s -> s_id;
+	return (s == NULL) ? "Null superblock" : s->s_id;
 }
 
 #define reiserfs_is_journal_aborted(journal) (unlikely (__reiserfs_is_journal_aborted (journal)))
-static inline int __reiserfs_is_journal_aborted (struct reiserfs_journal *journal)
+static inline int __reiserfs_is_journal_aborted(struct reiserfs_journal
+						*journal)
 {
-    return test_bit (J_ABORTED, &journal->j_state);
+	return test_bit(J_ABORTED, &journal->j_state);
 }
 
-#endif	/* _LINUX_REISER_FS_SB */
+#endif				/* _LINUX_REISER_FS_SB */
diff --git a/include/linux/reiserfs_xattr.h b/include/linux/reiserfs_xattr.h
--- a/include/linux/reiserfs_xattr.h
+++ b/include/linux/reiserfs_xattr.h
@@ -7,48 +7,48 @@
 #include <linux/xattr.h>
 
 /* Magic value in header */
-#define REISERFS_XATTR_MAGIC 0x52465841 /* "RFXA" */
+#define REISERFS_XATTR_MAGIC 0x52465841	/* "RFXA" */
 
 struct reiserfs_xattr_header {
-    __le32 h_magic;              /* magic number for identification */
-    __le32 h_hash;               /* hash of the value */
+	__le32 h_magic;		/* magic number for identification */
+	__le32 h_hash;		/* hash of the value */
 };
 
 #ifdef __KERNEL__
 
 struct reiserfs_xattr_handler {
 	char *prefix;
-        int (*init)(void);
-        void (*exit)(void);
-	int (*get)(struct inode *inode, const char *name, void *buffer,
-		   size_t size);
-	int (*set)(struct inode *inode, const char *name, const void *buffer,
-		   size_t size, int flags);
-	int (*del)(struct inode *inode, const char *name);
-        int (*list)(struct inode *inode, const char *name, int namelen, char *out);
-        struct list_head handlers;
+	int (*init) (void);
+	void (*exit) (void);
+	int (*get) (struct inode * inode, const char *name, void *buffer,
+		    size_t size);
+	int (*set) (struct inode * inode, const char *name, const void *buffer,
+		    size_t size, int flags);
+	int (*del) (struct inode * inode, const char *name);
+	int (*list) (struct inode * inode, const char *name, int namelen,
+		     char *out);
+	struct list_head handlers;
 };
 
-
 #ifdef CONFIG_REISERFS_FS_XATTR
 #define is_reiserfs_priv_object(inode) IS_PRIVATE(inode)
 #define has_xattr_dir(inode) (REISERFS_I(inode)->i_flags & i_has_xattr_dir)
-ssize_t reiserfs_getxattr (struct dentry *dentry, const char *name,
-			   void *buffer, size_t size);
-int reiserfs_setxattr (struct dentry *dentry, const char *name,
-                       const void *value, size_t size, int flags);
-ssize_t reiserfs_listxattr (struct dentry *dentry, char *buffer, size_t size);
-int reiserfs_removexattr (struct dentry *dentry, const char *name);
-int reiserfs_delete_xattrs (struct inode *inode);
-int reiserfs_chown_xattrs (struct inode *inode, struct iattr *attrs);
-int reiserfs_xattr_init (struct super_block *sb, int mount_flags);
-int reiserfs_permission (struct inode *inode, int mask, struct nameidata *nd);
-int reiserfs_permission_locked (struct inode *inode, int mask, struct nameidata *nd);
-
-int reiserfs_xattr_del (struct inode *, const char *);
-int reiserfs_xattr_get (const struct inode *, const char *, void *, size_t);
-int reiserfs_xattr_set (struct inode *, const char *, const void *,
-                               size_t, int);
+ssize_t reiserfs_getxattr(struct dentry *dentry, const char *name,
+			  void *buffer, size_t size);
+int reiserfs_setxattr(struct dentry *dentry, const char *name,
+		      const void *value, size_t size, int flags);
+ssize_t reiserfs_listxattr(struct dentry *dentry, char *buffer, size_t size);
+int reiserfs_removexattr(struct dentry *dentry, const char *name);
+int reiserfs_delete_xattrs(struct inode *inode);
+int reiserfs_chown_xattrs(struct inode *inode, struct iattr *attrs);
+int reiserfs_xattr_init(struct super_block *sb, int mount_flags);
+int reiserfs_permission(struct inode *inode, int mask, struct nameidata *nd);
+int reiserfs_permission_locked(struct inode *inode, int mask,
+			       struct nameidata *nd);
+
+int reiserfs_xattr_del(struct inode *, const char *);
+int reiserfs_xattr_get(const struct inode *, const char *, void *, size_t);
+int reiserfs_xattr_set(struct inode *, const char *, const void *, size_t, int);
 
 extern struct reiserfs_xattr_handler user_handler;
 extern struct reiserfs_xattr_handler trusted_handler;
@@ -56,57 +56,48 @@ extern struct reiserfs_xattr_handler tru
 extern struct reiserfs_xattr_handler security_handler;
 #endif
 
-int reiserfs_xattr_register_handlers (void) __init;
-void reiserfs_xattr_unregister_handlers (void);
+int reiserfs_xattr_register_handlers(void) __init;
+void reiserfs_xattr_unregister_handlers(void);
 
-static inline void
-reiserfs_write_lock_xattrs(struct super_block *sb)
+static inline void reiserfs_write_lock_xattrs(struct super_block *sb)
 {
-    down_write (&REISERFS_XATTR_DIR_SEM(sb));
+	down_write(&REISERFS_XATTR_DIR_SEM(sb));
 }
-static inline void
-reiserfs_write_unlock_xattrs(struct super_block *sb)
+static inline void reiserfs_write_unlock_xattrs(struct super_block *sb)
 {
-    up_write (&REISERFS_XATTR_DIR_SEM(sb));
+	up_write(&REISERFS_XATTR_DIR_SEM(sb));
 }
-static inline void
-reiserfs_read_lock_xattrs(struct super_block *sb)
+static inline void reiserfs_read_lock_xattrs(struct super_block *sb)
 {
-    down_read (&REISERFS_XATTR_DIR_SEM(sb));
+	down_read(&REISERFS_XATTR_DIR_SEM(sb));
 }
 
-static inline void
-reiserfs_read_unlock_xattrs(struct super_block *sb)
+static inline void reiserfs_read_unlock_xattrs(struct super_block *sb)
 {
-    up_read (&REISERFS_XATTR_DIR_SEM(sb));
+	up_read(&REISERFS_XATTR_DIR_SEM(sb));
 }
 
-static inline void
-reiserfs_write_lock_xattr_i(struct inode *inode)
+static inline void reiserfs_write_lock_xattr_i(struct inode *inode)
 {
-    down_write (&REISERFS_I(inode)->xattr_sem);
+	down_write(&REISERFS_I(inode)->xattr_sem);
 }
-static inline void
-reiserfs_write_unlock_xattr_i(struct inode *inode)
+static inline void reiserfs_write_unlock_xattr_i(struct inode *inode)
 {
-    up_write (&REISERFS_I(inode)->xattr_sem);
+	up_write(&REISERFS_I(inode)->xattr_sem);
 }
-static inline void
-reiserfs_read_lock_xattr_i(struct inode *inode)
+static inline void reiserfs_read_lock_xattr_i(struct inode *inode)
 {
-    down_read (&REISERFS_I(inode)->xattr_sem);
+	down_read(&REISERFS_I(inode)->xattr_sem);
 }
 
-static inline void
-reiserfs_read_unlock_xattr_i(struct inode *inode)
+static inline void reiserfs_read_unlock_xattr_i(struct inode *inode)
 {
-    up_read (&REISERFS_I(inode)->xattr_sem);
+	up_read(&REISERFS_I(inode)->xattr_sem);
 }
 
-static inline void
-reiserfs_mark_inode_private(struct inode *inode)
+static inline void reiserfs_mark_inode_private(struct inode *inode)
 {
-    inode->i_flags |= S_PRIVATE;
+	inode->i_flags |= S_PRIVATE;
 }
 
 #else
@@ -127,13 +118,20 @@ reiserfs_mark_inode_private(struct inode
 #define reiserfs_xattr_register_handlers() 0
 #define reiserfs_xattr_unregister_handlers()
 
-static inline int reiserfs_delete_xattrs (struct inode *inode) { return 0; };
-static inline int reiserfs_chown_xattrs (struct inode *inode, struct iattr *attrs) { return 0; };
-static inline int reiserfs_xattr_init (struct super_block *sb, int mount_flags)
+static inline int reiserfs_delete_xattrs(struct inode *inode)
+{
+	return 0;
+};
+static inline int reiserfs_chown_xattrs(struct inode *inode,
+					struct iattr *attrs)
+{
+	return 0;
+};
+static inline int reiserfs_xattr_init(struct super_block *sb, int mount_flags)
 {
-    sb->s_flags = (sb->s_flags & ~MS_POSIXACL); /* to be sure */
-    return 0;
+	sb->s_flags = (sb->s_flags & ~MS_POSIXACL);	/* to be sure */
+	return 0;
 };
 #endif
 
-#endif  /* __KERNEL__ */
+#endif				/* __KERNEL__ */
diff --git a/include/linux/rmap.h b/include/linux/rmap.h
--- a/include/linux/rmap.h
+++ b/include/linux/rmap.h
@@ -93,6 +93,12 @@ int page_referenced(struct page *, int i
 int try_to_unmap(struct page *);
 
 /*
+ * Called from mm/filemap_xip.c to unmap empty zero page
+ */
+pte_t *page_check_address(struct page *, struct mm_struct *, unsigned long);
+
+
+/*
  * Used by swapoff to help locate where page is expected in vma.
  */
 unsigned long page_address_in_vma(struct page *, struct vm_area_struct *);
diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h
--- a/include/linux/rtnetlink.h
+++ b/include/linux/rtnetlink.h
@@ -89,6 +89,13 @@ enum {
 	RTM_GETANYCAST	= 62,
 #define RTM_GETANYCAST	RTM_GETANYCAST
 
+	RTM_NEWNEIGHTBL	= 64,
+#define RTM_NEWNEIGHTBL	RTM_NEWNEIGHTBL
+	RTM_GETNEIGHTBL	= 66,
+#define RTM_GETNEIGHTBL	RTM_GETNEIGHTBL
+	RTM_SETNEIGHTBL,
+#define RTM_SETNEIGHTBL	RTM_SETNEIGHTBL
+
 	__RTM_MAX,
 #define RTM_MAX		(((__RTM_MAX + 3) & ~3) - 1)
 };
@@ -356,6 +363,8 @@ enum
 struct rta_session
 {
 	__u8	proto;
+	__u8	pad1;
+	__u16	pad2;
 
 	union {
 		struct {
@@ -493,6 +502,106 @@ struct nda_cacheinfo
 	__u32		ndm_refcnt;
 };
 
+
+/*****************************************************************
+ *		Neighbour tables specific messages.
+ *
+ * To retrieve the neighbour tables send RTM_GETNEIGHTBL with the
+ * NLM_F_DUMP flag set. Every neighbour table configuration is
+ * spread over multiple messages to avoid running into message
+ * size limits on systems with many interfaces. The first message
+ * in the sequence transports all not device specific data such as
+ * statistics, configuration, and the default parameter set.
+ * This message is followed by 0..n messages carrying device
+ * specific parameter sets.
+ * Although the ordering should be sufficient, NDTA_NAME can be
+ * used to identify sequences. The initial message can be identified
+ * by checking for NDTA_CONFIG. The device specific messages do
+ * not contain this TLV but have NDTPA_IFINDEX set to the
+ * corresponding interface index.
+ *
+ * To change neighbour table attributes, send RTM_SETNEIGHTBL
+ * with NDTA_NAME set. Changeable attribute include NDTA_THRESH[1-3],
+ * NDTA_GC_INTERVAL, and all TLVs in NDTA_PARMS unless marked
+ * otherwise. Device specific parameter sets can be changed by
+ * setting NDTPA_IFINDEX to the interface index of the corresponding
+ * device.
+ ****/
+
+struct ndt_stats
+{
+	__u64		ndts_allocs;
+	__u64		ndts_destroys;
+	__u64		ndts_hash_grows;
+	__u64		ndts_res_failed;
+	__u64		ndts_lookups;
+	__u64		ndts_hits;
+	__u64		ndts_rcv_probes_mcast;
+	__u64		ndts_rcv_probes_ucast;
+	__u64		ndts_periodic_gc_runs;
+	__u64		ndts_forced_gc_runs;
+};
+
+enum {
+	NDTPA_UNSPEC,
+	NDTPA_IFINDEX,			/* u32, unchangeable */
+	NDTPA_REFCNT,			/* u32, read-only */
+	NDTPA_REACHABLE_TIME,		/* u64, read-only, msecs */
+	NDTPA_BASE_REACHABLE_TIME,	/* u64, msecs */
+	NDTPA_RETRANS_TIME,		/* u64, msecs */
+	NDTPA_GC_STALETIME,		/* u64, msecs */
+	NDTPA_DELAY_PROBE_TIME,		/* u64, msecs */
+	NDTPA_QUEUE_LEN,		/* u32 */
+	NDTPA_APP_PROBES,		/* u32 */
+	NDTPA_UCAST_PROBES,		/* u32 */
+	NDTPA_MCAST_PROBES,		/* u32 */
+	NDTPA_ANYCAST_DELAY,		/* u64, msecs */
+	NDTPA_PROXY_DELAY,		/* u64, msecs */
+	NDTPA_PROXY_QLEN,		/* u32 */
+	NDTPA_LOCKTIME,			/* u64, msecs */
+	__NDTPA_MAX
+};
+#define NDTPA_MAX (__NDTPA_MAX - 1)
+
+struct ndtmsg
+{
+	__u8		ndtm_family;
+	__u8		ndtm_pad1;
+	__u16		ndtm_pad2;
+};
+
+struct ndt_config
+{
+	__u16		ndtc_key_len;
+	__u16		ndtc_entry_size;
+	__u32		ndtc_entries;
+	__u32		ndtc_last_flush;	/* delta to now in msecs */
+	__u32		ndtc_last_rand;		/* delta to now in msecs */
+	__u32		ndtc_hash_rnd;
+	__u32		ndtc_hash_mask;
+	__u32		ndtc_hash_chain_gc;
+	__u32		ndtc_proxy_qlen;
+};
+
+enum {
+	NDTA_UNSPEC,
+	NDTA_NAME,			/* char *, unchangeable */
+	NDTA_THRESH1,			/* u32 */
+	NDTA_THRESH2,			/* u32 */
+	NDTA_THRESH3,			/* u32 */
+	NDTA_CONFIG,			/* struct ndt_config, read-only */
+	NDTA_PARMS,			/* nested TLV NDTPA_* */
+	NDTA_STATS,			/* struct ndt_stats, read-only */
+	NDTA_GC_INTERVAL,		/* u64, msecs */
+	__NDTA_MAX
+};
+#define NDTA_MAX (__NDTA_MAX - 1)
+
+#define NDTA_RTA(r) ((struct rtattr*)(((char*)(r)) + \
+		     NLMSG_ALIGN(sizeof(struct ndtmsg))))
+#define NDTA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ndtmsg))
+
+
 /****
  *		General form of address family dependent message.
  ****/
@@ -528,10 +637,13 @@ struct ifinfomsg
 struct prefixmsg
 {
 	unsigned char	prefix_family;
+	unsigned char	prefix_pad1;
+	unsigned short	prefix_pad2;
 	int		prefix_ifindex;
 	unsigned char	prefix_type;
 	unsigned char	prefix_len;
 	unsigned char	prefix_flags;
+	unsigned char	prefix_pad3;
 };
 
 enum 
@@ -785,10 +897,84 @@ extern void __rta_fill(struct sk_buff *s
 		 goto rtattr_failure; \
    	__rta_fill(skb, attrtype, attrlen, data); }) 
 
-#define RTA_PUT_NOHDR(skb, attrlen, data) \
+#define RTA_APPEND(skb, attrlen, data) \
 ({	if (unlikely(skb_tailroom(skb) < (int)(attrlen))) \
 		goto rtattr_failure; \
-	memcpy(skb_put(skb, RTA_ALIGN(attrlen)), data, attrlen); })
+	memcpy(skb_put(skb, attrlen), data, attrlen); })
+
+#define RTA_PUT_NOHDR(skb, attrlen, data) \
+({	RTA_APPEND(skb, RTA_ALIGN(attrlen), data); \
+	memset(skb->tail - (RTA_ALIGN(attrlen) - attrlen), 0, \
+	       RTA_ALIGN(attrlen) - attrlen); })
+
+#define RTA_PUT_U8(skb, attrtype, value) \
+({	u8 _tmp = (value); \
+	RTA_PUT(skb, attrtype, sizeof(u8), &_tmp); })
+
+#define RTA_PUT_U16(skb, attrtype, value) \
+({	u16 _tmp = (value); \
+	RTA_PUT(skb, attrtype, sizeof(u16), &_tmp); })
+
+#define RTA_PUT_U32(skb, attrtype, value) \
+({	u32 _tmp = (value); \
+	RTA_PUT(skb, attrtype, sizeof(u32), &_tmp); })
+
+#define RTA_PUT_U64(skb, attrtype, value) \
+({	u64 _tmp = (value); \
+	RTA_PUT(skb, attrtype, sizeof(u64), &_tmp); })
+
+#define RTA_PUT_SECS(skb, attrtype, value) \
+	RTA_PUT_U64(skb, attrtype, (value) / HZ)
+
+#define RTA_PUT_MSECS(skb, attrtype, value) \
+	RTA_PUT_U64(skb, attrtype, jiffies_to_msecs(value))
+
+#define RTA_PUT_STRING(skb, attrtype, value) \
+	RTA_PUT(skb, attrtype, strlen(value) + 1, value)
+
+#define RTA_PUT_FLAG(skb, attrtype) \
+	RTA_PUT(skb, attrtype, 0, NULL);
+
+#define RTA_NEST(skb, type) \
+({	struct rtattr *__start = (struct rtattr *) (skb)->tail; \
+	RTA_PUT(skb, type, 0, NULL); \
+	__start;  })
+
+#define RTA_NEST_END(skb, start) \
+({	(start)->rta_len = ((skb)->tail - (unsigned char *) (start)); \
+	(skb)->len; })
+
+#define RTA_NEST_CANCEL(skb, start) \
+({	if (start) \
+		skb_trim(skb, (unsigned char *) (start) - (skb)->data); \
+	-1; })
+
+#define RTA_GET_U8(rta) \
+({	if (!rta || RTA_PAYLOAD(rta) < sizeof(u8)) \
+		goto rtattr_failure; \
+	*(u8 *) RTA_DATA(rta); })
+
+#define RTA_GET_U16(rta) \
+({	if (!rta || RTA_PAYLOAD(rta) < sizeof(u16)) \
+		goto rtattr_failure; \
+	*(u16 *) RTA_DATA(rta); })
+
+#define RTA_GET_U32(rta) \
+({	if (!rta || RTA_PAYLOAD(rta) < sizeof(u32)) \
+		goto rtattr_failure; \
+	*(u32 *) RTA_DATA(rta); })
+
+#define RTA_GET_U64(rta) \
+({	u64 _tmp; \
+	if (!rta || RTA_PAYLOAD(rta) < sizeof(u64)) \
+		goto rtattr_failure; \
+	memcpy(&_tmp, RTA_DATA(rta), sizeof(_tmp)); \
+	_tmp; })
+
+#define RTA_GET_FLAG(rta) (!!(rta))
+
+#define RTA_GET_SECS(rta) ((unsigned long) RTA_GET_U64(rta) * HZ)
+#define RTA_GET_MSECS(rta) (msecs_to_jiffies((unsigned long) RTA_GET_U64(rta)))
 		
 static inline struct rtattr *
 __rta_reserve(struct sk_buff *skb, int attrtype, int attrlen)
@@ -799,6 +985,7 @@ __rta_reserve(struct sk_buff *skb, int a
 	rta = (struct rtattr*)skb_put(skb, RTA_ALIGN(size));
 	rta->rta_type = attrtype;
 	rta->rta_len = size;
+	memset(RTA_DATA(rta) + attrlen, 0, RTA_ALIGN(size) - size);
 	return rta;
 }
 
diff --git a/include/linux/sched.h b/include/linux/sched.h
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -201,8 +201,8 @@ extern unsigned long
 arch_get_unmapped_area_topdown(struct file *filp, unsigned long addr,
 			  unsigned long len, unsigned long pgoff,
 			  unsigned long flags);
-extern void arch_unmap_area(struct vm_area_struct *area);
-extern void arch_unmap_area_topdown(struct vm_area_struct *area);
+extern void arch_unmap_area(struct mm_struct *, unsigned long);
+extern void arch_unmap_area_topdown(struct mm_struct *, unsigned long);
 
 #define set_mm_counter(mm, member, value) (mm)->_##member = (value)
 #define get_mm_counter(mm, member) ((mm)->_##member)
@@ -218,9 +218,10 @@ struct mm_struct {
 	unsigned long (*get_unmapped_area) (struct file *filp,
 				unsigned long addr, unsigned long len,
 				unsigned long pgoff, unsigned long flags);
-	void (*unmap_area) (struct vm_area_struct *area);
-	unsigned long mmap_base;		/* base of mmap area */
-	unsigned long free_area_cache;		/* first hole */
+	void (*unmap_area) (struct mm_struct *mm, unsigned long addr);
+        unsigned long mmap_base;		/* base of mmap area */
+        unsigned long cached_hole_size;         /* if non-zero, the largest hole below free_area_cache */
+	unsigned long free_area_cache;		/* first hole of size cached_hole_size or larger */
 	pgd_t * pgd;
 	atomic_t mm_users;			/* How many users with user space? */
 	atomic_t mm_count;			/* How many references to "struct mm_struct" (users count as 1) */
@@ -245,7 +246,7 @@ struct mm_struct {
 
 	unsigned long saved_auxv[42]; /* for /proc/PID/auxv */
 
-	unsigned dumpable:1;
+	unsigned dumpable:2;
 	cpumask_t cpu_vm_mask;
 
 	/* Architecture-specific MM context */
@@ -367,6 +368,11 @@ struct signal_struct {
 #endif
 };
 
+/* Context switch must be unlocked if interrupts are to be enabled */
+#ifdef __ARCH_WANT_INTERRUPTS_ON_CTXSW
+# define __ARCH_WANT_UNLOCKED_CTXSW
+#endif
+
 /*
  * Bits in flags field of signal_struct.
  */
@@ -404,6 +410,10 @@ struct user_struct {
 	atomic_t processes;	/* How many processes does this user have? */
 	atomic_t files;		/* How many open files does this user have? */
 	atomic_t sigpending;	/* How many pending signals does this user have? */
+#ifdef CONFIG_INOTIFY
+	atomic_t inotify_watches; /* How many inotify watches does this user have? */
+	atomic_t inotify_devs;	/* How many inotify devs does this user have opened? */
+#endif
 	/* protected by mq_lock	*/
 	unsigned long mq_bytes;	/* How many bytes can be allocated to mqueue? */
 	unsigned long locked_shm; /* How many pages of mlocked shm ? */
@@ -459,10 +469,11 @@ enum idle_type
 #define SD_LOAD_BALANCE		1	/* Do load balancing on this domain. */
 #define SD_BALANCE_NEWIDLE	2	/* Balance when about to become idle */
 #define SD_BALANCE_EXEC		4	/* Balance on exec */
-#define SD_WAKE_IDLE		8	/* Wake to idle CPU on task wakeup */
-#define SD_WAKE_AFFINE		16	/* Wake task to waking CPU */
-#define SD_WAKE_BALANCE		32	/* Perform balancing at task wakeup */
-#define SD_SHARE_CPUPOWER	64	/* Domain members share cpu power */
+#define SD_BALANCE_FORK		8	/* Balance on fork, clone */
+#define SD_WAKE_IDLE		16	/* Wake to idle CPU on task wakeup */
+#define SD_WAKE_AFFINE		32	/* Wake task to waking CPU */
+#define SD_WAKE_BALANCE		64	/* Perform balancing at task wakeup */
+#define SD_SHARE_CPUPOWER	128	/* Domain members share cpu power */
 
 struct sched_group {
 	struct sched_group *next;	/* Must be a circular list */
@@ -487,6 +498,11 @@ struct sched_domain {
 	unsigned long long cache_hot_time; /* Task considered cache hot (ns) */
 	unsigned int cache_nice_tries;	/* Leave cache hot tasks for # tries */
 	unsigned int per_cpu_gain;	/* CPU % gained by adding domain cpus */
+	unsigned int busy_idx;
+	unsigned int idle_idx;
+	unsigned int newidle_idx;
+	unsigned int wake_idx;
+	unsigned int forkexec_idx;
 	int flags;			/* See SD_* */
 
 	/* Runtime fields. */
@@ -510,10 +526,16 @@ struct sched_domain {
 	unsigned long alb_failed;
 	unsigned long alb_pushed;
 
-	/* sched_balance_exec() stats */
-	unsigned long sbe_attempts;
+	/* SD_BALANCE_EXEC stats */
+	unsigned long sbe_cnt;
+	unsigned long sbe_balanced;
 	unsigned long sbe_pushed;
 
+	/* SD_BALANCE_FORK stats */
+	unsigned long sbf_cnt;
+	unsigned long sbf_balanced;
+	unsigned long sbf_pushed;
+
 	/* try_to_wake_up() stats */
 	unsigned long ttwu_wake_remote;
 	unsigned long ttwu_move_affine;
@@ -521,6 +543,8 @@ struct sched_domain {
 #endif
 };
 
+extern void partition_sched_domains(cpumask_t *partition1,
+				    cpumask_t *partition2);
 #ifdef ARCH_HAS_SCHED_DOMAIN
 /* Useful helpers that arch setup code may use. Defined in kernel/sched.c */
 extern cpumask_t cpu_isolated_map;
@@ -560,9 +584,10 @@ struct group_info {
 		groups_free(group_info); \
 } while (0)
 
-struct group_info *groups_alloc(int gidsetsize);
-void groups_free(struct group_info *group_info);
-int set_current_groups(struct group_info *group_info);
+extern struct group_info *groups_alloc(int gidsetsize);
+extern void groups_free(struct group_info *group_info);
+extern int set_current_groups(struct group_info *group_info);
+extern int groups_search(struct group_info *group_info, gid_t grp);
 /* access the groups "array" with this macro */
 #define GROUP_AT(gi, i) \
     ((gi)->blocks[(i)/NGROUPS_PER_BLOCK][(i)%NGROUPS_PER_BLOCK])
@@ -580,10 +605,15 @@ struct task_struct {
 
 	int lock_depth;		/* BKL lock depth */
 
+#if defined(CONFIG_SMP) && defined(__ARCH_WANT_UNLOCKED_CTXSW)
+	int oncpu;
+#endif
 	int prio, static_prio;
 	struct list_head run_list;
 	prio_array_t *array;
 
+	unsigned short ioprio;
+
 	unsigned long sleep_avg;
 	unsigned long long timestamp, last_ran;
 	unsigned long long sched_time; /* sched_clock time spent running */
@@ -659,6 +689,7 @@ struct task_struct {
 	struct user_struct *user;
 #ifdef CONFIG_KEYS
 	struct key *thread_keyring;	/* keyring private to this thread */
+	unsigned char jit_keyring;	/* default keyring to attach requested keys to */
 #endif
 	int oomkilladj; /* OOM kill score adjustment (bit shift). */
 	char comm[TASK_COMM_LEN]; /* executable name excluding path
@@ -701,8 +732,6 @@ struct task_struct {
 	spinlock_t alloc_lock;
 /* Protection of proc_dentry: nesting proc_lock, dcache_lock, write_lock_irq(&tasklist_lock); */
 	spinlock_t proc_lock;
-/* context-switch lock */
-	spinlock_t switch_lock;
 
 /* journalling filesystem info */
 	void *journal_info;
@@ -740,6 +769,7 @@ struct task_struct {
 	nodemask_t mems_allowed;
 	int cpuset_mems_generation;
 #endif
+	atomic_t fs_excl;	/* holding fs exclusive resources */
 };
 
 static inline pid_t process_group(struct task_struct *tsk)
@@ -909,7 +939,7 @@ extern void FASTCALL(wake_up_new_task(st
 #else
  static inline void kick_process(struct task_struct *tsk) { }
 #endif
-extern void FASTCALL(sched_fork(task_t * p));
+extern void FASTCALL(sched_fork(task_t * p, int clone_flags));
 extern void FASTCALL(sched_exit(task_t * p));
 
 extern int in_group_p(gid_t);
@@ -1089,7 +1119,8 @@ extern void unhash_process(struct task_s
 
 /*
  * Protects ->fs, ->files, ->mm, ->ptrace, ->group_info, ->comm, keyring
- * subscriptions and synchronises with wait4().  Also used in procfs.
+ * subscriptions and synchronises with wait4().  Also used in procfs.  Also
+ * pins the final release of task.io_context.
  *
  * Nests both inside and outside of read_lock(&tasklist_lock).
  * It must not be nested with write_lock_irq(&tasklist_lock),
@@ -1242,33 +1273,78 @@ extern void normalize_rt_tasks(void);
 
 #endif
 
-/* try_to_freeze
- *
- * Checks whether we need to enter the refrigerator
- * and returns 1 if we did so.
- */
 #ifdef CONFIG_PM
-extern void refrigerator(unsigned long);
+/*
+ * Check if a process has been frozen
+ */
+static inline int frozen(struct task_struct *p)
+{
+	return p->flags & PF_FROZEN;
+}
+
+/*
+ * Check if there is a request to freeze a process
+ */
+static inline int freezing(struct task_struct *p)
+{
+	return p->flags & PF_FREEZE;
+}
+
+/*
+ * Request that a process be frozen
+ * FIXME: SMP problem. We may not modify other process' flags!
+ */
+static inline void freeze(struct task_struct *p)
+{
+	p->flags |= PF_FREEZE;
+}
+
+/*
+ * Wake up a frozen process
+ */
+static inline int thaw_process(struct task_struct *p)
+{
+	if (frozen(p)) {
+		p->flags &= ~PF_FROZEN;
+		wake_up_process(p);
+		return 1;
+	}
+	return 0;
+}
+
+/*
+ * freezing is complete, mark process as frozen
+ */
+static inline void frozen_process(struct task_struct *p)
+{
+	p->flags = (p->flags & ~PF_FREEZE) | PF_FROZEN;
+}
+
+extern void refrigerator(void);
 extern int freeze_processes(void);
 extern void thaw_processes(void);
 
-static inline int try_to_freeze(unsigned long refrigerator_flags)
+static inline int try_to_freeze(void)
 {
-	if (unlikely(current->flags & PF_FREEZE)) {
-		refrigerator(refrigerator_flags);
+	if (freezing(current)) {
+		refrigerator();
 		return 1;
 	} else
 		return 0;
 }
 #else
-static inline void refrigerator(unsigned long flag) {}
+static inline int frozen(struct task_struct *p) { return 0; }
+static inline int freezing(struct task_struct *p) { return 0; }
+static inline void freeze(struct task_struct *p) { BUG(); }
+static inline int thaw_process(struct task_struct *p) { return 1; }
+static inline void frozen_process(struct task_struct *p) { BUG(); }
+
+static inline void refrigerator(void) {}
 static inline int freeze_processes(void) { BUG(); return 0; }
 static inline void thaw_processes(void) {}
 
-static inline int try_to_freeze(unsigned long refrigerator_flags)
-{
-	return 0;
-}
+static inline int try_to_freeze(void) { return 0; }
+
 #endif /* CONFIG_PM */
 #endif /* __KERNEL__ */
 
diff --git a/include/linux/seccomp.h b/include/linux/seccomp.h
--- a/include/linux/seccomp.h
+++ b/include/linux/seccomp.h
@@ -19,6 +19,11 @@ static inline void secure_computing(int 
 		__secure_computing(this_syscall);
 }
 
+static inline int has_secure_computing(struct thread_info *ti)
+{
+	return unlikely(test_ti_thread_flag(ti, TIF_SECCOMP));
+}
+
 #else /* CONFIG_SECCOMP */
 
 #if (__GNUC__ > 2)
@@ -28,6 +33,11 @@ static inline void secure_computing(int 
 #endif
 
 #define secure_computing(x) do { } while (0)
+/* static inline to preserve typechecking */
+static inline int has_secure_computing(struct thread_info *ti)
+{
+	return 0;
+}
 
 #endif /* CONFIG_SECCOMP */
 
diff --git a/include/linux/serial.h b/include/linux/serial.h
--- a/include/linux/serial.h
+++ b/include/linux/serial.h
@@ -174,9 +174,11 @@ struct serial_icounter_struct {
 
 
 #ifdef __KERNEL__
+#include <linux/compiler.h>
+
 /* Export to allow PCMCIA to use this - Dave Hinds */
-extern int register_serial(struct serial_struct *req);
-extern void unregister_serial(int line);
+extern int __deprecated register_serial(struct serial_struct *req);
+extern void __deprecated unregister_serial(int line);
 
 /* Allow architectures to override entries in serial8250_ports[] at run time: */
 struct uart_port;	/* forward declaration */
diff --git a/include/linux/serialP.h b/include/linux/serialP.h
--- a/include/linux/serialP.h
+++ b/include/linux/serialP.h
@@ -19,7 +19,6 @@
  * For definitions of the flags field, see tty.h
  */
 
-#include <linux/version.h>
 #include <linux/config.h>
 #include <linux/termios.h>
 #include <linux/workqueue.h>
diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h
--- a/include/linux/serial_8250.h
+++ b/include/linux/serial_8250.h
@@ -22,6 +22,7 @@ struct plat_serial8250_port {
 	unsigned int	uartclk;	/* UART clock rate */
 	unsigned char	regshift;	/* register shift */
 	unsigned char	iotype;		/* UPIO_* */
+	unsigned char	hub6;
 	unsigned int	flags;		/* UPF_* flags */
 };
 
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -104,7 +104,7 @@
 #define PORT_MPSC	63
 
 /* TXX9 type number */
-#define PORT_TXX9       64
+#define PORT_TXX9	64
 
 /* NEC VR4100 series SIU/DSIU */
 #define PORT_VR41XX_SIU		65
@@ -122,6 +122,7 @@
 #ifdef __KERNEL__
 
 #include <linux/config.h>
+#include <linux/compiler.h>
 #include <linux/interrupt.h>
 #include <linux/circ_buf.h>
 #include <linux/spinlock.h>
@@ -359,8 +360,8 @@ struct tty_driver *uart_console_device(s
  */
 int uart_register_driver(struct uart_driver *uart);
 void uart_unregister_driver(struct uart_driver *uart);
-void uart_unregister_port(struct uart_driver *reg, int line);
-int uart_register_port(struct uart_driver *reg, struct uart_port *port);
+void __deprecated uart_unregister_port(struct uart_driver *reg, int line);
+int __deprecated uart_register_port(struct uart_driver *reg, struct uart_port *port);
 int uart_add_one_port(struct uart_driver *reg, struct uart_port *port);
 int uart_remove_one_port(struct uart_driver *reg, struct uart_port *port);
 int uart_match_port(struct uart_port *port1, struct uart_port *port2);
diff --git a/include/linux/serio.h b/include/linux/serio.h
--- a/include/linux/serio.h
+++ b/include/linux/serio.h
@@ -83,6 +83,7 @@ static inline void serio_register_port(s
 }
 
 void serio_unregister_port(struct serio *serio);
+void serio_unregister_child_port(struct serio *serio);
 void __serio_unregister_port_delayed(struct serio *serio, struct module *owner);
 static inline void serio_unregister_port_delayed(struct serio *serio)
 {
@@ -153,6 +154,11 @@ static inline int serio_pin_driver(struc
 	return down_interruptible(&serio->drv_sem);
 }
 
+static inline void serio_pin_driver_uninterruptible(struct serio *serio)
+{
+	down(&serio->drv_sem);
+}
+
 static inline void serio_unpin_driver(struct serio *serio)
 {
 	up(&serio->drv_sem);
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -27,6 +27,7 @@
 #include <linux/highmem.h>
 #include <linux/poll.h>
 #include <linux/net.h>
+#include <linux/textsearch.h>
 #include <net/checksum.h>
 
 #define HAVE_ALLOC_SKB		/* For the drivers to know */
@@ -182,7 +183,6 @@ struct skb_shared_info {
  *	@priority: Packet queueing priority
  *	@users: User count - see {datagram,tcp}.c
  *	@protocol: Packet protocol from driver
- *	@security: Security level of packet
  *	@truesize: Buffer size 
  *	@head: Head of buffer
  *	@data: Data head pointer
@@ -193,7 +193,6 @@ struct skb_shared_info {
  *	@nfcache: Cache info
  *	@nfct: Associated connection, if any
  *	@nfctinfo: Relationship of this skb to the connection
- *	@nf_debug: Netfilter debugging
  *	@nf_bridge: Saved data about a bridged frame - see br_netfilter.c
  *      @private: Data which is private to the HIPPI implementation
  *	@tc_index: Traffic control index
@@ -249,24 +248,21 @@ struct sk_buff {
 				data_len,
 				mac_len,
 				csum;
-	unsigned char		local_df,
-				cloned:1,
-				nohdr:1,
-				pkt_type,
-				ip_summed;
 	__u32			priority;
-	unsigned short		protocol,
-				security;
+	__u8			local_df:1,
+				cloned:1,
+				ip_summed:2,
+				nohdr:1;
+				/* 3 bits spare */
+	__u8			pkt_type;
+	__be16			protocol;
 
 	void			(*destructor)(struct sk_buff *skb);
 #ifdef CONFIG_NETFILTER
-        unsigned long		nfmark;
+	unsigned long		nfmark;
 	__u32			nfcache;
 	__u32			nfctinfo;
 	struct nf_conntrack	*nfct;
-#ifdef CONFIG_NETFILTER_DEBUG
-        unsigned int		nf_debug;
-#endif
 #ifdef CONFIG_BRIDGE_NETFILTER
 	struct nf_bridge_info	*nf_bridge;
 #endif
@@ -304,20 +300,26 @@ struct sk_buff {
 #include <asm/system.h>
 
 extern void	       __kfree_skb(struct sk_buff *skb);
-extern struct sk_buff *alloc_skb(unsigned int size, int priority);
+extern struct sk_buff *alloc_skb(unsigned int size,
+				 unsigned int __nocast priority);
 extern struct sk_buff *alloc_skb_from_cache(kmem_cache_t *cp,
-					    unsigned int size, int priority);
+					    unsigned int size,
+					    unsigned int __nocast priority);
 extern void	       kfree_skbmem(struct sk_buff *skb);
-extern struct sk_buff *skb_clone(struct sk_buff *skb, int priority);
-extern struct sk_buff *skb_copy(const struct sk_buff *skb, int priority);
-extern struct sk_buff *pskb_copy(struct sk_buff *skb, int gfp_mask);
+extern struct sk_buff *skb_clone(struct sk_buff *skb,
+				 unsigned int __nocast priority);
+extern struct sk_buff *skb_copy(const struct sk_buff *skb,
+				unsigned int __nocast priority);
+extern struct sk_buff *pskb_copy(struct sk_buff *skb,
+				 unsigned int __nocast gfp_mask);
 extern int	       pskb_expand_head(struct sk_buff *skb,
-					int nhead, int ntail, int gfp_mask);
+					int nhead, int ntail,
+					unsigned int __nocast gfp_mask);
 extern struct sk_buff *skb_realloc_headroom(struct sk_buff *skb,
 					    unsigned int headroom);
 extern struct sk_buff *skb_copy_expand(const struct sk_buff *skb,
 				       int newheadroom, int newtailroom,
-				       int priority);
+				       unsigned int __nocast priority);
 extern struct sk_buff *		skb_pad(struct sk_buff *skb, int pad);
 #define dev_kfree_skb(a)	kfree_skb(a)
 extern void	      skb_over_panic(struct sk_buff *skb, int len,
@@ -325,6 +327,28 @@ extern void	      skb_over_panic(struct 
 extern void	      skb_under_panic(struct sk_buff *skb, int len,
 				      void *here);
 
+struct skb_seq_state
+{
+	__u32		lower_offset;
+	__u32		upper_offset;
+	__u32		frag_idx;
+	__u32		stepped_offset;
+	struct sk_buff	*root_skb;
+	struct sk_buff	*cur_skb;
+	__u8		*frag_data;
+};
+
+extern void	      skb_prepare_seq_read(struct sk_buff *skb,
+					   unsigned int from, unsigned int to,
+					   struct skb_seq_state *st);
+extern unsigned int   skb_seq_read(unsigned int consumed, const u8 **data,
+				   struct skb_seq_state *st);
+extern void	      skb_abort_seq_read(struct skb_seq_state *st);
+
+extern unsigned int   skb_find_text(struct sk_buff *skb, unsigned int from,
+				    unsigned int to, struct ts_config *config,
+				    struct ts_state *state);
+
 /* Internal */
 #define skb_shinfo(SKB)		((struct skb_shared_info *)((SKB)->end))
 
@@ -446,7 +470,8 @@ static inline int skb_shared(const struc
  *
  *	NULL is returned on a memory allocation failure.
  */
-static inline struct sk_buff *skb_share_check(struct sk_buff *skb, int pri)
+static inline struct sk_buff *skb_share_check(struct sk_buff *skb,
+					      unsigned int __nocast pri)
 {
 	might_sleep_if(pri & __GFP_WAIT);
 	if (skb_shared(skb)) {
@@ -477,7 +502,8 @@ static inline struct sk_buff *skb_share_
  *
  *	%NULL is returned on a memory allocation failure.
  */
-static inline struct sk_buff *skb_unshare(struct sk_buff *skb, int pri)
+static inline struct sk_buff *skb_unshare(struct sk_buff *skb,
+					  unsigned int __nocast pri)
 {
 	might_sleep_if(pri & __GFP_WAIT);
 	if (skb_cloned(skb)) {
@@ -983,7 +1009,7 @@ static inline void __skb_queue_purge(str
  *	%NULL is returned in there is no free memory.
  */
 static inline struct sk_buff *__dev_alloc_skb(unsigned int length,
-					      int gfp_mask)
+					      unsigned int __nocast gfp_mask)
 {
 	struct sk_buff *skb = alloc_skb(length + 16, gfp_mask);
 	if (likely(skb))
@@ -1096,8 +1122,8 @@ static inline int skb_can_coalesce(struc
  *	If there is no free memory -ENOMEM is returned, otherwise zero
  *	is returned and the old skb data released.
  */
-extern int __skb_linearize(struct sk_buff *skb, int gfp);
-static inline int skb_linearize(struct sk_buff *skb, int gfp)
+extern int __skb_linearize(struct sk_buff *skb, unsigned int __nocast gfp);
+static inline int skb_linearize(struct sk_buff *skb, unsigned int __nocast gfp)
 {
 	return __skb_linearize(skb, gfp);
 }
@@ -1192,7 +1218,7 @@ static inline void *skb_header_pointer(c
 {
 	int hlen = skb_headlen(skb);
 
-	if (offset + len <= hlen)
+	if (hlen - offset >= len)
 		return skb->data + offset;
 
 	if (skb_copy_bits(skb, offset, buffer, len) < 0)
@@ -1219,15 +1245,6 @@ static inline void nf_reset(struct sk_bu
 {
 	nf_conntrack_put(skb->nfct);
 	skb->nfct = NULL;
-#ifdef CONFIG_NETFILTER_DEBUG
-	skb->nf_debug = 0;
-#endif
-}
-static inline void nf_reset_debug(struct sk_buff *skb)
-{
-#ifdef CONFIG_NETFILTER_DEBUG
-	skb->nf_debug = 0;
-#endif
 }
 
 #ifdef CONFIG_BRIDGE_NETFILTER
diff --git a/include/linux/slab.h b/include/linux/slab.h
--- a/include/linux/slab.h
+++ b/include/linux/slab.h
@@ -64,7 +64,8 @@ extern int kmem_cache_shrink(kmem_cache_
 extern void *kmem_cache_alloc(kmem_cache_t *, unsigned int __nocast);
 extern void kmem_cache_free(kmem_cache_t *, void *);
 extern unsigned int kmem_cache_size(kmem_cache_t *);
-extern kmem_cache_t *kmem_find_general_cachep(size_t size, int gfpflags);
+extern const char *kmem_cache_name(kmem_cache_t *);
+extern kmem_cache_t *kmem_find_general_cachep(size_t size, unsigned int __nocast gfpflags);
 
 /* Size description struct for general caches. */
 struct cache_sizes {
@@ -104,13 +105,13 @@ extern unsigned int ksize(const void *);
 
 #ifdef CONFIG_NUMA
 extern void *kmem_cache_alloc_node(kmem_cache_t *, int flags, int node);
-extern void *kmalloc_node(size_t size, int flags, int node);
+extern void *kmalloc_node(size_t size, unsigned int __nocast flags, int node);
 #else
 static inline void *kmem_cache_alloc_node(kmem_cache_t *cachep, int flags, int node)
 {
 	return kmem_cache_alloc(cachep, flags);
 }
-static inline void *kmalloc_node(size_t size, int flags, int node)
+static inline void *kmalloc_node(size_t size, unsigned int __nocast flags, int node)
 {
 	return kmalloc(size, flags);
 }
diff --git a/include/linux/smp.h b/include/linux/smp.h
--- a/include/linux/smp.h
+++ b/include/linux/smp.h
@@ -92,10 +92,7 @@ void smp_prepare_boot_cpu(void);
 /*
  *	These macros fold the SMP functionality into a single CPU system
  */
-
-#if !defined(__smp_processor_id) || !defined(CONFIG_PREEMPT)
-# define smp_processor_id()			0
-#endif
+#define raw_smp_processor_id()			0
 #define hard_smp_processor_id()			0
 #define smp_call_function(func,info,retry,wait)	({ 0; })
 #define on_each_cpu(func,info,retry,wait)	({ func(info); 0; })
@@ -106,30 +103,25 @@ static inline void smp_send_reschedule(i
 #endif /* !SMP */
 
 /*
- * DEBUG_PREEMPT support: check whether smp_processor_id() is being
- * used in a preemption-safe way.
+ * smp_processor_id(): get the current CPU ID.
  *
- * An architecture has to enable this debugging code explicitly.
- * It can do so by renaming the smp_processor_id() macro to
- * __smp_processor_id().  This should only be done after some minimal
- * testing, because usually there are a number of false positives
- * that an architecture will trigger.
+ * if DEBUG_PREEMPT is enabled the we check whether it is
+ * used in a preemption-safe way. (smp_processor_id() is safe
+ * if it's used in a preemption-off critical section, or in
+ * a thread that is bound to the current CPU.)
  *
- * To fix a false positive (i.e. smp_processor_id() use that the
- * debugging code reports but which use for some reason is legal),
- * change the smp_processor_id() reference to _smp_processor_id(),
- * which is the nondebug variant.  NOTE: don't use this to hack around
- * real bugs.
+ * NOTE: raw_smp_processor_id() is for internal use only
+ * (smp_processor_id() is the preferred variant), but in rare
+ * instances it might also be used to turn off false positives
+ * (i.e. smp_processor_id() use that the debugging code reports but
+ * which use for some reason is legal). Don't use this to hack around
+ * the warning message, as your code might not work under PREEMPT.
  */
-#ifdef __smp_processor_id
-# if defined(CONFIG_PREEMPT) && defined(CONFIG_DEBUG_PREEMPT)
-   extern unsigned int smp_processor_id(void);
-# else
-#  define smp_processor_id() __smp_processor_id()
-# endif
-# define _smp_processor_id() __smp_processor_id()
+#ifdef CONFIG_DEBUG_PREEMPT
+  extern unsigned int debug_smp_processor_id(void);
+# define smp_processor_id() debug_smp_processor_id()
 #else
-# define _smp_processor_id() smp_processor_id()
+# define smp_processor_id() raw_smp_processor_id()
 #endif
 
 #define get_cpu()		({ preempt_disable(); smp_processor_id(); })
diff --git a/include/linux/string.h b/include/linux/string.h
--- a/include/linux/string.h
+++ b/include/linux/string.h
@@ -88,6 +88,8 @@ extern int memcmp(const void *,const voi
 extern void * memchr(const void *,int,__kernel_size_t);
 #endif
 
+extern char *kstrdup(const char *s, unsigned int __nocast gfp);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h
--- a/include/linux/sunrpc/clnt.h
+++ b/include/linux/sunrpc/clnt.h
@@ -111,6 +111,11 @@ struct rpc_procinfo {
 struct rpc_clnt *rpc_create_client(struct rpc_xprt *xprt, char *servname,
 				struct rpc_program *info,
 				u32 version, rpc_authflavor_t authflavor);
+struct rpc_clnt *rpc_new_client(struct rpc_xprt *xprt, char *servname,
+				struct rpc_program *info,
+				u32 version, rpc_authflavor_t authflavor);
+struct rpc_clnt	*rpc_bind_new_program(struct rpc_clnt *,
+				struct rpc_program *, int);
 struct rpc_clnt *rpc_clone_client(struct rpc_clnt *);
 int		rpc_shutdown_client(struct rpc_clnt *);
 int		rpc_destroy_client(struct rpc_clnt *);
@@ -129,6 +134,7 @@ void		rpc_clnt_sigmask(struct rpc_clnt *
 void		rpc_clnt_sigunmask(struct rpc_clnt *clnt, sigset_t *oldset);
 void		rpc_setbufsize(struct rpc_clnt *, unsigned int, unsigned int);
 size_t		rpc_max_payload(struct rpc_clnt *);
+int		rpc_ping(struct rpc_clnt *clnt, int flags);
 
 static __inline__
 int rpc_call(struct rpc_clnt *clnt, u32 proc, void *argp, void *resp, int flags)
diff --git a/include/linux/sunrpc/sched.h b/include/linux/sunrpc/sched.h
--- a/include/linux/sunrpc/sched.h
+++ b/include/linux/sunrpc/sched.h
@@ -31,7 +31,6 @@ struct rpc_wait_queue;
 struct rpc_wait {
 	struct list_head	list;		/* wait queue links */
 	struct list_head	links;		/* Links to related tasks */
-	wait_queue_head_t	waitq;		/* sync: sleep on this q */
 	struct rpc_wait_queue *	rpc_waitq;	/* RPC wait queue we're on */
 };
 
diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h
--- a/include/linux/sunrpc/svc.h
+++ b/include/linux/sunrpc/svc.h
@@ -185,6 +185,17 @@ xdr_ressize_check(struct svc_rqst *rqstp
 	return vec->iov_len <= PAGE_SIZE;
 }
 
+static inline struct page *
+svc_take_res_page(struct svc_rqst *rqstp)
+{
+	if (rqstp->rq_arghi <= rqstp->rq_argused)
+		return NULL;
+	rqstp->rq_arghi--;
+	rqstp->rq_respages[rqstp->rq_resused] =
+		rqstp->rq_argpages[rqstp->rq_arghi];
+	return rqstp->rq_respages[rqstp->rq_resused++];
+}
+
 static inline int svc_take_page(struct svc_rqst *rqstp)
 {
 	if (rqstp->rq_arghi <= rqstp->rq_argused)
@@ -240,9 +251,10 @@ struct svc_deferred_req {
 };
 
 /*
- * RPC program
+ * List of RPC programs on the same transport endpoint
  */
 struct svc_program {
+	struct svc_program *	pg_next;	/* other programs (same xprt) */
 	u32			pg_prog;	/* program number */
 	unsigned int		pg_lovers;	/* lowest version */
 	unsigned int		pg_hivers;	/* lowest version */
diff --git a/include/linux/sunrpc/xdr.h b/include/linux/sunrpc/xdr.h
--- a/include/linux/sunrpc/xdr.h
+++ b/include/linux/sunrpc/xdr.h
@@ -146,7 +146,8 @@ extern void xdr_shift_buf(struct xdr_buf
 extern void xdr_buf_from_iov(struct kvec *, struct xdr_buf *);
 extern int xdr_buf_subsegment(struct xdr_buf *, struct xdr_buf *, int, int);
 extern int xdr_buf_read_netobj(struct xdr_buf *, struct xdr_netobj *, int);
-extern int read_bytes_from_xdr_buf(struct xdr_buf *buf, int base, void *obj, int len);
+extern int read_bytes_from_xdr_buf(struct xdr_buf *, int, void *, int);
+extern int write_bytes_to_xdr_buf(struct xdr_buf *, int, void *, int);
 
 /*
  * Helper structure for copying from an sk_buff.
@@ -160,7 +161,7 @@ typedef struct {
 
 typedef size_t (*skb_read_actor_t)(skb_reader_t *desc, void *to, size_t len);
 
-extern void xdr_partial_copy_from_skb(struct xdr_buf *, unsigned int,
+extern ssize_t xdr_partial_copy_from_skb(struct xdr_buf *, unsigned int,
 		skb_reader_t *, skb_read_actor_t);
 
 struct socket;
@@ -168,6 +169,23 @@ struct sockaddr;
 extern int xdr_sendpages(struct socket *, struct sockaddr *, int,
 		struct xdr_buf *, unsigned int, int);
 
+extern int xdr_encode_word(struct xdr_buf *, int, u32);
+extern int xdr_decode_word(struct xdr_buf *, int, u32 *);
+
+struct xdr_array2_desc;
+typedef int (*xdr_xcode_elem_t)(struct xdr_array2_desc *desc, void *elem);
+struct xdr_array2_desc {
+	unsigned int elem_size;
+	unsigned int array_len;
+	unsigned int array_maxlen;
+	xdr_xcode_elem_t xcode;
+};
+
+extern int xdr_decode_array2(struct xdr_buf *buf, unsigned int base,
+                             struct xdr_array2_desc *desc);
+extern int xdr_encode_array2(struct xdr_buf *buf, unsigned int base,
+			     struct xdr_array2_desc *desc);
+
 /*
  * Provide some simple tools for XDR buffer overflow-checking etc.
  */
diff --git a/include/linux/suspend.h b/include/linux/suspend.h
--- a/include/linux/suspend.h
+++ b/include/linux/suspend.h
@@ -58,7 +58,7 @@ static inline int software_suspend(void)
 }
 #endif
 
-#ifdef CONFIG_SMP
+#ifdef CONFIG_SUSPEND_SMP
 extern void disable_nonboot_cpus(void);
 extern void enable_nonboot_cpus(void);
 #else
diff --git a/include/linux/swap.h b/include/linux/swap.h
--- a/include/linux/swap.h
+++ b/include/linux/swap.h
@@ -7,6 +7,7 @@
 #include <linux/mmzone.h>
 #include <linux/list.h>
 #include <linux/sched.h>
+
 #include <asm/atomic.h>
 #include <asm/page.h>
 
@@ -148,7 +149,7 @@ struct swap_list_t {
 #define vm_swap_full() (nr_swap_pages*2 < total_swap_pages)
 
 /* linux/mm/oom_kill.c */
-extern void out_of_memory(unsigned int __nocast gfp_mask);
+extern void out_of_memory(unsigned int __nocast gfp_mask, int order);
 
 /* linux/mm/memory.c */
 extern void swapin_readahead(swp_entry_t, unsigned long, struct vm_area_struct *);
@@ -172,7 +173,8 @@ extern int rotate_reclaimable_page(struc
 extern void swap_setup(void);
 
 /* linux/mm/vmscan.c */
-extern int try_to_free_pages(struct zone **, unsigned int, unsigned int);
+extern int try_to_free_pages(struct zone **, unsigned int);
+extern int zone_reclaim(struct zone *, unsigned int, unsigned int);
 extern int shrink_all_memory(int);
 extern int vm_swappiness;
 
@@ -252,6 +254,8 @@ static inline void put_swap_token(struct
 
 #define si_swapinfo(val) \
 	do { (val)->freeswap = (val)->totalswap = 0; } while (0)
+/* only sparc can not include linux/pagemap.h in this file
+ * so leave page_cache_release and release_pages undeclared... */
 #define free_page_and_swap_cache(page) \
 	page_cache_release(page)
 #define free_pages_and_swap_cache(pages, nr) \
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -159,8 +159,9 @@ asmlinkage long sys_shutdown(int, int);
 asmlinkage long sys_reboot(int magic1, int magic2, unsigned int cmd,
 				void __user *arg);
 asmlinkage long sys_restart_syscall(void);
-asmlinkage long sys_kexec_load(void *entry, unsigned long nr_segments,
-			struct kexec_segment *segments, unsigned long flags);
+asmlinkage long sys_kexec_load(unsigned long entry, unsigned long nr_segments,
+				struct kexec_segment __user *segments,
+				unsigned long flags);
 
 asmlinkage long sys_exit(int error_code);
 asmlinkage void sys_exit_group(int error_code);
@@ -505,4 +506,7 @@ asmlinkage long sys_request_key(const ch
 asmlinkage long sys_keyctl(int cmd, unsigned long arg2, unsigned long arg3,
 			   unsigned long arg4, unsigned long arg5);
 
+asmlinkage long sys_ioprio_set(int which, int who, int ioprio);
+asmlinkage long sys_ioprio_get(int which, int who);
+
 #endif
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -70,6 +70,14 @@ enum
 	CTL_BUS_ISA=1		/* ISA */
 };
 
+/* /proc/sys/fs/inotify/ */
+enum
+{
+	INOTIFY_MAX_USER_INSTANCES=1,	/* max instances per user */
+	INOTIFY_MAX_USER_WATCHES=2,	/* max watches per user */
+	INOTIFY_MAX_QUEUED_EVENTS=3	/* max queued events per instance */
+};
+
 /* CTL_KERN names: */
 enum
 {
@@ -136,6 +144,8 @@ enum
 	KERN_UNKNOWN_NMI_PANIC=66, /* int: unknown nmi panic flag */
 	KERN_BOOTLOADER_TYPE=67, /* int: boot loader type */
 	KERN_RANDOMIZE=68, /* int: randomize virtual address space */
+	KERN_SETUID_DUMPABLE=69, /* int: behaviour of dumps for setuid core */
+	KERN_SPIN_RETRY=70,	/* int: number of spinlock retries */
 };
 
 
@@ -242,6 +252,7 @@ enum
 	NET_CORE_MOD_CONG=16,
 	NET_CORE_DEV_WEIGHT=17,
 	NET_CORE_SOMAXCONN=18,
+	NET_CORE_BUDGET=19,
 };
 
 /* /proc/sys/net/ethernet */
@@ -332,21 +343,14 @@ enum
 	NET_TCP_FRTO=92,
 	NET_TCP_LOW_LATENCY=93,
 	NET_IPV4_IPFRAG_SECRET_INTERVAL=94,
-	NET_TCP_WESTWOOD=95,
 	NET_IPV4_IGMP_MAX_MSF=96,
 	NET_TCP_NO_METRICS_SAVE=97,
-	NET_TCP_VEGAS=98,
-	NET_TCP_VEGAS_ALPHA=99,
-	NET_TCP_VEGAS_BETA=100,
-	NET_TCP_VEGAS_GAMMA=101,
- 	NET_TCP_BIC=102,
- 	NET_TCP_BIC_FAST_CONVERGENCE=103,
-	NET_TCP_BIC_LOW_WINDOW=104,
 	NET_TCP_DEFAULT_WIN_SCALE=105,
 	NET_TCP_MODERATE_RCVBUF=106,
 	NET_TCP_TSO_WIN_DIVISOR=107,
 	NET_TCP_BIC_BETA=108,
 	NET_IPV4_ICMP_ERRORS_USE_INBOUND_IFADDR=109,
+	NET_TCP_CONG_CONTROL=110,
 };
 
 enum {
@@ -646,6 +650,7 @@ enum {
 	NET_SCTP_ADDIP_ENABLE		 = 13,
 	NET_SCTP_PRSCTP_ENABLE		 = 14,
 	NET_SCTP_SNDBUF_POLICY		 = 15,
+	NET_SCTP_SACK_TIMEOUT		 = 16,
 };
 
 /* /proc/sys/net/bridge */
@@ -680,6 +685,7 @@ enum
 	FS_XFS=17,	/* struct: control xfs parameters */
 	FS_AIO_NR=18,	/* current system-wide number of aio requests */
 	FS_AIO_MAX_NR=19,	/* system-wide maximum number of aio requests */
+	FS_INOTIFY=20,	/* inotify submenu */
 };
 
 /* /proc/sys/fs/quota/ */
diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h
--- a/include/linux/sysfs.h
+++ b/include/linux/sysfs.h
@@ -16,13 +16,13 @@ struct kobject;
 struct module;
 
 struct attribute {
-	char			* name;
+	const char		* name;
 	struct module 		* owner;
 	mode_t			mode;
 };
 
 struct attribute_group {
-	char			* name;
+	const char		* name;
 	struct attribute	** attrs;
 };
 
@@ -73,6 +73,7 @@ struct sysfs_dirent {
 	int			s_type;
 	umode_t			s_mode;
 	struct dentry		* s_dentry;
+	struct iattr		* s_iattr;
 };
 
 #define SYSFS_ROOT		0x0001
@@ -105,11 +106,11 @@ sysfs_chmod_file(struct kobject *kobj, s
 extern void
 sysfs_remove_file(struct kobject *, const struct attribute *);
 
-extern int 
-sysfs_create_link(struct kobject * kobj, struct kobject * target, char * name);
+extern int
+sysfs_create_link(struct kobject * kobj, struct kobject * target, const char * name);
 
 extern void
-sysfs_remove_link(struct kobject *, char * name);
+sysfs_remove_link(struct kobject *, const char * name);
 
 int sysfs_create_bin_file(struct kobject * kobj, struct bin_attribute * attr);
 int sysfs_remove_bin_file(struct kobject * kobj, struct bin_attribute * attr);
@@ -153,12 +154,12 @@ static inline void sysfs_remove_file(str
 	;
 }
 
-static inline int sysfs_create_link(struct kobject * k, struct kobject * t, char * n)
+static inline int sysfs_create_link(struct kobject * k, struct kobject * t, const char * n)
 {
 	return 0;
 }
 
-static inline void sysfs_remove_link(struct kobject * k, char * name)
+static inline void sysfs_remove_link(struct kobject * k, const char * name)
 {
 	;
 }
diff --git a/include/linux/tc_ematch/tc_em_meta.h b/include/linux/tc_ematch/tc_em_meta.h
--- a/include/linux/tc_ematch/tc_em_meta.h
+++ b/include/linux/tc_ematch/tc_em_meta.h
@@ -41,19 +41,14 @@ enum
 	TCF_META_ID_LOADAVG_1,
 	TCF_META_ID_LOADAVG_2,
 	TCF_META_ID_DEV,
-	TCF_META_ID_INDEV,
-	TCF_META_ID_REALDEV,
 	TCF_META_ID_PRIORITY,
 	TCF_META_ID_PROTOCOL,
-	TCF_META_ID_SECURITY,
 	TCF_META_ID_PKTTYPE,
 	TCF_META_ID_PKTLEN,
 	TCF_META_ID_DATALEN,
 	TCF_META_ID_MACLEN,
 	TCF_META_ID_NFMARK,
 	TCF_META_ID_TCINDEX,
-	TCF_META_ID_TCVERDICT,
-	TCF_META_ID_TCCLASSID,
 	TCF_META_ID_RTCLASSID,
 	TCF_META_ID_RTIIF,
 	TCF_META_ID_SK_FAMILY,
diff --git a/include/linux/tc_ematch/tc_em_text.h b/include/linux/tc_ematch/tc_em_text.h
new file mode 100644
--- /dev/null
+++ b/include/linux/tc_ematch/tc_em_text.h
@@ -0,0 +1,19 @@
+#ifndef __LINUX_TC_EM_TEXT_H
+#define __LINUX_TC_EM_TEXT_H
+
+#include <linux/pkt_cls.h>
+
+#define TC_EM_TEXT_ALGOSIZ	16
+
+struct tcf_em_text
+{
+	char		algo[TC_EM_TEXT_ALGOSIZ];
+	__u16		from_offset;
+	__u16		to_offset;
+	__u16		pattern_len;
+	__u8		from_layer:4;
+	__u8		to_layer:4;
+	__u8		pad;
+};
+
+#endif
diff --git a/include/linux/tcp.h b/include/linux/tcp.h
--- a/include/linux/tcp.h
+++ b/include/linux/tcp.h
@@ -127,6 +127,7 @@ enum { 
 #define TCP_WINDOW_CLAMP	10	/* Bound advertised window */
 #define TCP_INFO		11	/* Information about this connection. */
 #define TCP_QUICKACK		12	/* Block/reenable quick acks */
+#define TCP_CONGESTION		13	/* Congestion control algorithm */
 
 #define TCPI_OPT_TIMESTAMPS	1
 #define TCPI_OPT_SACK		2
@@ -203,13 +204,6 @@ struct tcp_sack_block {
 	__u32	end_seq;
 };
 
-enum tcp_congestion_algo {
-	TCP_RENO=0,
-	TCP_VEGAS,
-	TCP_WESTWOOD,
-	TCP_BIC,
-};
-
 struct tcp_options_received {
 /*	PAWS/RTTM data	*/
 	long	ts_recent_stamp;/* Time we stored ts_recent (for aging) */
@@ -230,6 +224,17 @@ struct tcp_options_received {
 	__u16	mss_clamp;	/* Maximal mss, negotiated at connection setup */
 };
 
+struct tcp_request_sock {
+	struct inet_request_sock req;
+	__u32			 rcv_isn;
+	__u32			 snt_isn;
+};
+
+static inline struct tcp_request_sock *tcp_rsk(const struct request_sock *req)
+{
+	return (struct tcp_request_sock *)req;
+}
+
 struct tcp_sock {
 	/* inet_sock has to be the first member of tcp_sock */
 	struct inet_sock	inet;
@@ -281,7 +286,7 @@ struct tcp_sock {
 	__u32	max_window;	/* Maximal window ever seen from peer	*/
 	__u32	pmtu_cookie;	/* Last pmtu seen by socket		*/
 	__u32	mss_cache;	/* Cached effective mss, not including SACKS */
-	__u16	mss_cache_std;	/* Like mss_cache, but without TSO */
+	__u16	xmit_size_goal;	/* Goal for segmenting output packets	*/
 	__u16	ext_header_len;	/* Network protocol overhead (IP/IPv6 options) */
 	__u8	ca_state;	/* State of fast-retransmit machine 	*/
 	__u8	retransmits;	/* Number of unrecovered RTO timeouts.	*/
@@ -294,7 +299,7 @@ struct tcp_sock {
 	__u8	reordering;	/* Packet reordering metric.		*/
 	__u8	frto_counter;	/* Number of new acks after RTO */
 
-	__u8	adv_cong;	/* Using Vegas, Westwood, or BIC */
+	__u8	unused;
 	__u8	defer_accept;	/* User waits for some data after accept() */
 
 /* RTT measurement */
@@ -368,22 +373,7 @@ struct tcp_sock {
 
 	__u32	total_retrans;	/* Total retransmits for entire connection */
 
-	/* The syn_wait_lock is necessary only to avoid proc interface having
-	 * to grab the main lock sock while browsing the listening hash
-	 * (otherwise it's deadlock prone).
-	 * This lock is acquired in read mode only from listening_get_next()
-	 * and it's acquired in write mode _only_ from code that is actively
-	 * changing the syn_wait_queue. All readers that are holding
-	 * the master sock lock don't need to grab this lock in read mode
-	 * too as the syn_wait_queue writes are always protected from
-	 * the main sock lock.
-	 */
-	rwlock_t		syn_wait_lock;
-	struct tcp_listen_opt	*listen_opt;
-
-	/* FIFO of established children */
-	struct open_request	*accept_queue;
-	struct open_request	*accept_queue_tail;
+	struct request_sock_queue accept_queue; /* FIFO of established children */
 
 	unsigned int		keepalive_time;	  /* time before keep alive takes place */
 	unsigned int		keepalive_intvl;  /* time interval between keep alive probes */
@@ -405,37 +395,10 @@ struct tcp_sock {
 		__u32	time;
 	} rcvq_space;
 
-/* TCP Westwood structure */
-        struct {
-                __u32    bw_ns_est;        /* first bandwidth estimation..not too smoothed 8) */
-                __u32    bw_est;           /* bandwidth estimate */
-                __u32    rtt_win_sx;       /* here starts a new evaluation... */
-                __u32    bk;
-                __u32    snd_una;          /* used for evaluating the number of acked bytes */
-                __u32    cumul_ack;
-                __u32    accounted;
-                __u32    rtt;
-                __u32    rtt_min;          /* minimum observed RTT */
-        } westwood;
-
-/* Vegas variables */
-	struct {
-		__u32	beg_snd_nxt;	/* right edge during last RTT */
-		__u32	beg_snd_una;	/* left edge  during last RTT */
-		__u32	beg_snd_cwnd;	/* saves the size of the cwnd */
-		__u8	doing_vegas_now;/* if true, do vegas for this RTT */
-		__u16	cntRTT;		/* # of RTTs measured within last RTT */
-		__u32	minRTT;		/* min of RTTs measured within last RTT (in usec) */
-		__u32	baseRTT;	/* the min of all Vegas RTT measurements seen (in usec) */
-	} vegas;
-
-	/* BI TCP Parameters */
-	struct {
-		__u32	cnt;		/* increase cwnd by 1 after this number of ACKs */
-		__u32 	last_max_cwnd;	/* last maximium snd_cwnd */
-		__u32	last_cwnd;	/* the last snd_cwnd */
-		__u32   last_stamp;     /* time when updated last_cwnd */
-	} bictcp;
+	/* Pluggable TCP congestion control hook */
+	struct tcp_congestion_ops *ca_ops;
+	u32	ca_priv[16];
+#define TCP_CA_PRIV_SIZE	(16*sizeof(u32))
 };
 
 static inline struct tcp_sock *tcp_sk(const struct sock *sk)
@@ -443,6 +406,11 @@ static inline struct tcp_sock *tcp_sk(co
 	return (struct tcp_sock *)sk;
 }
 
+static inline void *tcp_ca(const struct tcp_sock *tp)
+{
+	return (void *) tp->ca_priv;
+}
+
 #endif
 
 #endif	/* _LINUX_TCP_H */
diff --git a/include/linux/tcp_diag.h b/include/linux/tcp_diag.h
--- a/include/linux/tcp_diag.h
+++ b/include/linux/tcp_diag.h
@@ -99,9 +99,10 @@ enum
 	TCPDIAG_MEMINFO,
 	TCPDIAG_INFO,
 	TCPDIAG_VEGASINFO,
+	TCPDIAG_CONG,
 };
 
-#define TCPDIAG_MAX TCPDIAG_VEGASINFO
+#define TCPDIAG_MAX TCPDIAG_CONG
 
 
 /* TCPDIAG_MEM */
@@ -123,5 +124,4 @@ struct tcpvegas_info {
 	__u32	tcpv_minrtt;
 };
 
-
 #endif /* _TCP_DIAG_H_ */
diff --git a/include/linux/textsearch.h b/include/linux/textsearch.h
new file mode 100644
--- /dev/null
+++ b/include/linux/textsearch.h
@@ -0,0 +1,180 @@
+#ifndef __LINUX_TEXTSEARCH_H
+#define __LINUX_TEXTSEARCH_H
+
+#ifdef __KERNEL__
+
+#include <linux/types.h>
+#include <linux/list.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/err.h>
+
+struct ts_config;
+
+/**
+ * TS_AUTOLOAD - Automatically load textsearch modules when needed
+ */
+#define TS_AUTOLOAD	1
+
+/**
+ * struct ts_state - search state
+ * @offset: offset for next match
+ * @cb: control buffer, for persistant variables of get_next_block()
+ */
+struct ts_state
+{
+	unsigned int		offset;
+	char			cb[40];
+};
+
+/**
+ * struct ts_ops - search module operations
+ * @name: name of search algorithm
+ * @init: initialization function to prepare a search
+ * @find: find the next occurrence of the pattern
+ * @destroy: destroy algorithm specific parts of a search configuration
+ * @get_pattern: return head of pattern
+ * @get_pattern_len: return length of pattern
+ * @owner: module reference to algorithm
+ */
+struct ts_ops
+{
+	const char		*name;
+	struct ts_config *	(*init)(const void *, unsigned int, int);
+	unsigned int		(*find)(struct ts_config *,
+					struct ts_state *);
+	void			(*destroy)(struct ts_config *);
+	void *			(*get_pattern)(struct ts_config *);
+	unsigned int		(*get_pattern_len)(struct ts_config *);
+	struct module		*owner;
+	struct list_head	list;
+};
+
+/**
+ * struct ts_config - search configuration
+ * @ops: operations of chosen algorithm
+ * @get_next_block: callback to fetch the next block to search in
+ * @finish: callback to finalize a search
+ */
+struct ts_config
+{
+	struct ts_ops		*ops;
+
+	/**
+	 * get_next_block - fetch next block of data
+	 * @consumed: number of bytes consumed by the caller
+	 * @dst: destination buffer
+	 * @conf: search configuration
+	 * @state: search state
+	 *
+	 * Called repeatedly until 0 is returned. Must assign the
+	 * head of the next block of data to &*dst and return the length
+	 * of the block or 0 if at the end. consumed == 0 indicates
+	 * a new search. May store/read persistant values in state->cb.
+	 */
+	unsigned int		(*get_next_block)(unsigned int consumed,
+						  const u8 **dst,
+						  struct ts_config *conf,
+						  struct ts_state *state);
+
+	/**
+	 * finish - finalize/clean a series of get_next_block() calls
+	 * @conf: search configuration
+	 * @state: search state
+	 *
+	 * Called after the last use of get_next_block(), may be used
+	 * to cleanup any leftovers.
+	 */
+	void			(*finish)(struct ts_config *conf,
+					  struct ts_state *state);
+};
+
+/**
+ * textsearch_next - continue searching for a pattern
+ * @conf: search configuration
+ * @state: search state
+ *
+ * Continues a search looking for more occurrences of the pattern.
+ * textsearch_find() must be called to find the first occurrence
+ * in order to reset the state.
+ *
+ * Returns the position of the next occurrence of the pattern or
+ * UINT_MAX if not match was found.
+ */ 
+static inline unsigned int textsearch_next(struct ts_config *conf,
+					   struct ts_state *state)
+{
+	unsigned int ret = conf->ops->find(conf, state);
+
+	if (conf->finish)
+		conf->finish(conf, state);
+
+	return ret;
+}
+
+/**
+ * textsearch_find - start searching for a pattern
+ * @conf: search configuration
+ * @state: search state
+ *
+ * Returns the position of first occurrence of the pattern or
+ * UINT_MAX if no match was found.
+ */ 
+static inline unsigned int textsearch_find(struct ts_config *conf,
+					   struct ts_state *state)
+{
+	state->offset = 0;
+	return textsearch_next(conf, state);
+}
+
+/**
+ * textsearch_get_pattern - return head of the pattern
+ * @conf: search configuration
+ */
+static inline void *textsearch_get_pattern(struct ts_config *conf)
+{
+	return conf->ops->get_pattern(conf);
+}
+
+/**
+ * textsearch_get_pattern_len - return length of the pattern
+ * @conf: search configuration
+ */
+static inline unsigned int textsearch_get_pattern_len(struct ts_config *conf)
+{
+	return conf->ops->get_pattern_len(conf);
+}
+
+extern int textsearch_register(struct ts_ops *);
+extern int textsearch_unregister(struct ts_ops *);
+extern struct ts_config *textsearch_prepare(const char *, const void *,
+					    unsigned int, int, int);
+extern void textsearch_destroy(struct ts_config *conf);
+extern unsigned int textsearch_find_continuous(struct ts_config *,
+					       struct ts_state *,
+					       const void *, unsigned int);
+
+
+#define TS_PRIV_ALIGNTO	8
+#define TS_PRIV_ALIGN(len) (((len) + TS_PRIV_ALIGNTO-1) & ~(TS_PRIV_ALIGNTO-1))
+
+static inline struct ts_config *alloc_ts_config(size_t payload, int gfp_mask)
+{
+	struct ts_config *conf;
+
+	conf = kmalloc(TS_PRIV_ALIGN(sizeof(*conf)) + payload, gfp_mask);
+	if (conf == NULL)
+		return ERR_PTR(-ENOMEM);
+
+	memset(conf, 0, TS_PRIV_ALIGN(sizeof(*conf)) + payload);
+	return conf;
+}
+
+static inline void *ts_config_priv(struct ts_config *conf)
+{
+	return ((u8 *) conf + TS_PRIV_ALIGN(sizeof(struct ts_config)));
+}
+
+#endif /* __KERNEL__ */
+
+#endif
diff --git a/include/linux/textsearch_fsm.h b/include/linux/textsearch_fsm.h
new file mode 100644
--- /dev/null
+++ b/include/linux/textsearch_fsm.h
@@ -0,0 +1,48 @@
+#ifndef __LINUX_TEXTSEARCH_FSM_H
+#define __LINUX_TEXTSEARCH_FSM_H
+
+#include <linux/types.h>
+
+enum {
+	TS_FSM_SPECIFIC,	/* specific character */
+	TS_FSM_WILDCARD,	/* any character */
+	TS_FSM_DIGIT,		/* isdigit() */
+	TS_FSM_XDIGIT,		/* isxdigit() */
+	TS_FSM_PRINT,		/* isprint() */
+	TS_FSM_ALPHA,		/* isalpha() */
+	TS_FSM_ALNUM,		/* isalnum() */
+	TS_FSM_ASCII,		/* isascii() */
+	TS_FSM_CNTRL,		/* iscntrl() */
+	TS_FSM_GRAPH,		/* isgraph() */
+	TS_FSM_LOWER,		/* islower() */
+	TS_FSM_UPPER,		/* isupper() */
+	TS_FSM_PUNCT,		/* ispunct() */
+	TS_FSM_SPACE,		/* isspace() */
+	__TS_FSM_TYPE_MAX,
+};
+#define TS_FSM_TYPE_MAX (__TS_FSM_TYPE_MAX - 1)
+
+enum {
+	TS_FSM_SINGLE,		/* 1 occurrence */
+	TS_FSM_PERHAPS,		/* 1 or 0 occurrence */
+	TS_FSM_ANY,		/* 0..n occurrences */
+	TS_FSM_MULTI,		/* 1..n occurrences */
+	TS_FSM_HEAD_IGNORE,	/* 0..n ignored occurrences at head */
+	__TS_FSM_RECUR_MAX,
+};
+#define TS_FSM_RECUR_MAX (__TS_FSM_RECUR_MAX - 1)
+
+/**
+ * struct ts_fsm_token - state machine token (state)
+ * @type: type of token
+ * @recur: number of recurrences
+ * @value: character value for TS_FSM_SPECIFIC
+ */
+struct ts_fsm_token
+{
+	__u16		type;
+	__u8		recur;
+	__u8		value;
+};
+
+#endif
diff --git a/include/linux/timer.h b/include/linux/timer.h
--- a/include/linux/timer.h
+++ b/include/linux/timer.h
@@ -6,45 +6,33 @@
 #include <linux/spinlock.h>
 #include <linux/stddef.h>
 
-struct tvec_t_base_s;
+struct timer_base_s;
 
 struct timer_list {
 	struct list_head entry;
 	unsigned long expires;
 
-	spinlock_t lock;
 	unsigned long magic;
 
 	void (*function)(unsigned long);
 	unsigned long data;
 
-	struct tvec_t_base_s *base;
+	struct timer_base_s *base;
 };
 
 #define TIMER_MAGIC	0x4b87ad6e
 
+extern struct timer_base_s __init_timer_base;
+
 #define TIMER_INITIALIZER(_function, _expires, _data) {		\
 		.function = (_function),			\
 		.expires = (_expires),				\
 		.data = (_data),				\
-		.base = NULL,					\
+		.base = &__init_timer_base,			\
 		.magic = TIMER_MAGIC,				\
-		.lock = SPIN_LOCK_UNLOCKED,			\
 	}
 
-/***
- * init_timer - initialize a timer.
- * @timer: the timer to be initialized
- *
- * init_timer() must be done to a timer prior calling *any* of the
- * other timer functions.
- */
-static inline void init_timer(struct timer_list * timer)
-{
-	timer->base = NULL;
-	timer->magic = TIMER_MAGIC;
-	spin_lock_init(&timer->lock);
-}
+void fastcall init_timer(struct timer_list * timer);
 
 /***
  * timer_pending - is a timer pending?
@@ -58,7 +46,7 @@ static inline void init_timer(struct tim
  */
 static inline int timer_pending(const struct timer_list * timer)
 {
-	return timer->base != NULL;
+	return timer->entry.next != NULL;
 }
 
 extern void add_timer_on(struct timer_list *timer, int cpu);
@@ -88,13 +76,15 @@ static inline void add_timer(struct time
 }
 
 #ifdef CONFIG_SMP
+  extern int try_to_del_timer_sync(struct timer_list *timer);
   extern int del_timer_sync(struct timer_list *timer);
-  extern int del_singleshot_timer_sync(struct timer_list *timer);
 #else
-# define del_timer_sync(t) del_timer(t)
-# define del_singleshot_timer_sync(t) del_timer(t)
+# define try_to_del_timer_sync(t)	del_timer(t)
+# define del_timer_sync(t)		del_timer(t)
 #endif
 
+#define del_singleshot_timer_sync(t) del_timer_sync(t)
+
 extern void init_timers(void);
 extern void run_local_timers(void);
 extern void it_real_fn(unsigned long);
diff --git a/include/linux/topology.h b/include/linux/topology.h
--- a/include/linux/topology.h
+++ b/include/linux/topology.h
@@ -89,6 +89,11 @@
 	.cache_hot_time		= 0,			\
 	.cache_nice_tries	= 0,			\
 	.per_cpu_gain		= 25,			\
+	.busy_idx		= 0,			\
+	.idle_idx		= 0,			\
+	.newidle_idx		= 1,			\
+	.wake_idx		= 0,			\
+	.forkexec_idx		= 0,			\
 	.flags			= SD_LOAD_BALANCE	\
 				| SD_BALANCE_NEWIDLE	\
 				| SD_BALANCE_EXEC	\
@@ -115,12 +120,15 @@
 	.cache_hot_time		= (5*1000000/2),	\
 	.cache_nice_tries	= 1,			\
 	.per_cpu_gain		= 100,			\
+	.busy_idx		= 2,			\
+	.idle_idx		= 1,			\
+	.newidle_idx		= 2,			\
+	.wake_idx		= 1,			\
+	.forkexec_idx		= 1,			\
 	.flags			= SD_LOAD_BALANCE	\
 				| SD_BALANCE_NEWIDLE	\
 				| SD_BALANCE_EXEC	\
-				| SD_WAKE_AFFINE	\
-				| SD_WAKE_IDLE		\
-				| SD_WAKE_BALANCE,	\
+				| SD_WAKE_AFFINE,	\
 	.last_balance		= jiffies,		\
 	.balance_interval	= 1,			\
 	.nr_balance_failed	= 0,			\
diff --git a/include/linux/tty.h b/include/linux/tty.h
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -345,6 +345,7 @@ extern int tty_check_change(struct tty_s
 extern void stop_tty(struct tty_struct * tty);
 extern void start_tty(struct tty_struct * tty);
 extern int tty_register_ldisc(int disc, struct tty_ldisc *new_ldisc);
+extern int tty_unregister_ldisc(int disc);
 extern int tty_register_driver(struct tty_driver *driver);
 extern int tty_unregister_driver(struct tty_driver *driver);
 extern void tty_register_device(struct tty_driver *driver, unsigned index, struct device *dev);
diff --git a/include/linux/uinput.h b/include/linux/uinput.h
--- a/include/linux/uinput.h
+++ b/include/linux/uinput.h
@@ -42,8 +42,7 @@ struct uinput_request {
 	int			code;	/* UI_FF_UPLOAD, UI_FF_ERASE */
 
 	int			retval;
-	wait_queue_head_t	waitq;
-	int			completed;
+	struct completion	done;
 
 	union {
 		int		effect_id;
@@ -62,7 +61,7 @@ struct uinput_device {
 
 	struct uinput_request	*requests[UINPUT_NUM_REQUESTS];
 	wait_queue_head_t	requests_waitq;
-	struct semaphore	requests_sem;
+	spinlock_t		requests_lock;
 };
 #endif	/* __KERNEL__ */
 
diff --git a/include/linux/usb.h b/include/linux/usb.h
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -287,15 +287,14 @@ struct usb_bus {
 
 	struct dentry *usbfs_dentry;	/* usbfs dentry entry for the bus */
 
-	struct class_device class_dev;	/* class device for this bus */
+	struct class_device *class_dev;	/* class device for this bus */
+	struct kref kref;		/* handles reference counting this bus */
 	void (*release)(struct usb_bus *bus);	/* function to destroy this bus's memory */
-#if defined(CONFIG_USB_MON) || defined(CONFIG_USB_MON_MODULE)
+#if defined(CONFIG_USB_MON)
 	struct mon_bus *mon_bus;	/* non-null when associated */
 	int monitored;			/* non-zero when monitored */
 #endif
 };
-#define	to_usb_bus(d) container_of(d, struct usb_bus, class_dev)
-
 
 /* -------------------------------------------------------------------------- */
 
@@ -939,17 +938,17 @@ static inline void usb_fill_int_urb (str
 }
 
 extern void usb_init_urb(struct urb *urb);
-extern struct urb *usb_alloc_urb(int iso_packets, int mem_flags);
+extern struct urb *usb_alloc_urb(int iso_packets, unsigned mem_flags);
 extern void usb_free_urb(struct urb *urb);
 #define usb_put_urb usb_free_urb
 extern struct urb *usb_get_urb(struct urb *urb);
-extern int usb_submit_urb(struct urb *urb, int mem_flags);
+extern int usb_submit_urb(struct urb *urb, unsigned mem_flags);
 extern int usb_unlink_urb(struct urb *urb);
 extern void usb_kill_urb(struct urb *urb);
 
 #define HAVE_USB_BUFFERS
 void *usb_buffer_alloc (struct usb_device *dev, size_t size,
-	int mem_flags, dma_addr_t *dma);
+	unsigned mem_flags, dma_addr_t *dma);
 void usb_buffer_free (struct usb_device *dev, size_t size,
 	void *addr, dma_addr_t dma);
 
@@ -1056,7 +1055,7 @@ int usb_sg_init (
 	struct scatterlist	*sg,
 	int			nents,
 	size_t			length,
-	int			mem_flags
+	unsigned		mem_flags
 );
 void usb_sg_cancel (struct usb_sg_request *io);
 void usb_sg_wait (struct usb_sg_request *io);
diff --git a/include/linux/usb_cdc.h b/include/linux/usb_cdc.h
--- a/include/linux/usb_cdc.h
+++ b/include/linux/usb_cdc.h
@@ -34,6 +34,7 @@
 #define USB_CDC_ACM_TYPE		0x02		/* acm_descriptor */
 #define USB_CDC_UNION_TYPE		0x06		/* union_desc */
 #define USB_CDC_COUNTRY_TYPE		0x07
+#define USB_CDC_NETWORK_TERMINAL_TYPE	0x0a		/* network_terminal_desc */
 #define USB_CDC_ETHERNET_TYPE		0x0f		/* ether_desc */
 #define USB_CDC_WHCM_TYPE		0x11
 #define USB_CDC_MDLM_TYPE		0x12		/* mdlm_desc */
@@ -83,6 +84,18 @@ struct usb_cdc_union_desc {
 	/* ... and there could be other slave interfaces */
 } __attribute__ ((packed));
 
+/* "Network Channel Terminal Functional Descriptor" from CDC spec 5.2.3.11 */
+struct usb_cdc_network_terminal_desc {
+	__u8	bLength;
+	__u8	bDescriptorType;
+	__u8	bDescriptorSubType;
+
+	__u8	bEntityId;
+	__u8	iName;
+	__u8	bChannelIndex;
+	__u8	bPhysicalInterface;
+} __attribute__ ((packed));
+
 /* "Ethernet Networking Functional Descriptor" from CDC spec 5.2.3.16 */
 struct usb_cdc_ether_desc {
 	__u8	bLength;
diff --git a/include/linux/usb_ch9.h b/include/linux/usb_ch9.h
--- a/include/linux/usb_ch9.h
+++ b/include/linux/usb_ch9.h
@@ -6,17 +6,20 @@
  *
  * - the master/host side Linux-USB kernel driver API;
  * - the "usbfs" user space API; and
- * - (eventually) a Linux "gadget" slave/device side driver API.
+ * - the Linux "gadget" slave/device/peripheral side driver API.
  *
  * USB 2.0 adds an additional "On The Go" (OTG) mode, which lets systems
  * act either as a USB master/host or as a USB slave/device.  That means
- * the master and slave side APIs will benefit from working well together.
+ * the master and slave side APIs benefit from working well together.
+ *
+ * There's also "Wireless USB", using low power short range radios for
+ * peripheral interconnection but otherwise building on the USB framework.
  */
 
 #ifndef __LINUX_USB_CH9_H
 #define __LINUX_USB_CH9_H
 
-#include <asm/types.h>		/* __u8 etc */
+#include <linux/types.h>	/* __u8 etc */
 
 /*-------------------------------------------------------------------------*/
 
@@ -68,6 +71,18 @@
 #define USB_REQ_SET_INTERFACE		0x0B
 #define USB_REQ_SYNCH_FRAME		0x0C
 
+#define USB_REQ_SET_ENCRYPTION		0x0D	/* Wireless USB */
+#define USB_REQ_GET_ENCRYPTION		0x0E
+#define USB_REQ_SET_HANDSHAKE		0x0F
+#define USB_REQ_GET_HANDSHAKE		0x10
+#define USB_REQ_SET_CONNECTION		0x11
+#define USB_REQ_SET_SECURITY_DATA	0x12
+#define USB_REQ_GET_SECURITY_DATA	0x13
+#define USB_REQ_SET_WUSB_DATA		0x14
+#define USB_REQ_LOOPBACK_DATA_WRITE	0x15
+#define USB_REQ_LOOPBACK_DATA_READ	0x16
+#define USB_REQ_SET_INTERFACE_DS	0x17
+
 /*
  * USB feature flags are written using USB_REQ_{CLEAR,SET}_FEATURE, and
  * are read as a bit array returned by USB_REQ_GET_STATUS.  (So there
@@ -75,10 +90,12 @@
  */
 #define USB_DEVICE_SELF_POWERED		0	/* (read only) */
 #define USB_DEVICE_REMOTE_WAKEUP	1	/* dev may initiate wakeup */
-#define USB_DEVICE_TEST_MODE		2	/* (high speed only) */
-#define USB_DEVICE_B_HNP_ENABLE		3	/* dev may initiate HNP */
-#define USB_DEVICE_A_HNP_SUPPORT	4	/* RH port supports HNP */
-#define USB_DEVICE_A_ALT_HNP_SUPPORT	5	/* other RH port does */
+#define USB_DEVICE_TEST_MODE		2	/* (wired high speed only) */
+#define USB_DEVICE_BATTERY		2	/* (wireless) */
+#define USB_DEVICE_B_HNP_ENABLE		3	/* (otg) dev may initiate HNP */
+#define USB_DEVICE_WUSB_DEVICE		3	/* (wireless)*/
+#define USB_DEVICE_A_HNP_SUPPORT	4	/* (otg) RH port supports HNP */
+#define USB_DEVICE_A_ALT_HNP_SUPPORT	5	/* (otg) other RH port does */
 #define USB_DEVICE_DEBUG_MODE		6	/* (special devices only) */
 
 #define USB_ENDPOINT_HALT		0	/* IN/OUT will STALL */
@@ -135,6 +152,13 @@ struct usb_ctrlrequest {
 #define USB_DT_OTG			0x09
 #define USB_DT_DEBUG			0x0a
 #define USB_DT_INTERFACE_ASSOCIATION	0x0b
+/* these are from the Wireless USB spec */
+#define USB_DT_SECURITY			0x0c
+#define USB_DT_KEY			0x0d
+#define USB_DT_ENCRYPTION_TYPE		0x0e
+#define USB_DT_BOS			0x0f
+#define USB_DT_DEVICE_CAPABILITY	0x10
+#define USB_DT_WIRELESS_ENDPOINT_COMP	0x11
 
 /* conventional codes for class-specific descriptors */
 #define USB_DT_CS_DEVICE		0x21
@@ -192,6 +216,7 @@ struct usb_device_descriptor {
 #define USB_CLASS_CSCID			0x0b	/* chip+ smart card */
 #define USB_CLASS_CONTENT_SEC		0x0d	/* content security */
 #define USB_CLASS_VIDEO			0x0e
+#define USB_CLASS_WIRELESS_CONTROLLER	0xe0
 #define USB_CLASS_APP_SPEC		0xfe
 #define USB_CLASS_VENDOR_SPEC		0xff
 
@@ -223,6 +248,7 @@ struct usb_config_descriptor {
 #define USB_CONFIG_ATT_ONE		(1 << 7)	/* must be set */
 #define USB_CONFIG_ATT_SELFPOWER	(1 << 6)	/* self powered */
 #define USB_CONFIG_ATT_WAKEUP		(1 << 5)	/* can wakeup */
+#define USB_CONFIG_ATT_BATTERY		(1 << 4)	/* battery powered */
 
 /*-------------------------------------------------------------------------*/
 
@@ -268,8 +294,8 @@ struct usb_endpoint_descriptor {
 	__le16 wMaxPacketSize;
 	__u8  bInterval;
 
-	// NOTE:  these two are _only_ in audio endpoints.
-	// use USB_DT_ENDPOINT*_SIZE in bLength, not sizeof.
+	/* NOTE:  these two are _only_ in audio endpoints. */
+	/* use USB_DT_ENDPOINT*_SIZE in bLength, not sizeof. */
 	__u8  bRefresh;
 	__u8  bSynchAddress;
 } __attribute__ ((packed));
@@ -289,6 +315,7 @@ struct usb_endpoint_descriptor {
 #define USB_ENDPOINT_XFER_ISOC		1
 #define USB_ENDPOINT_XFER_BULK		2
 #define USB_ENDPOINT_XFER_INT		3
+#define USB_ENDPOINT_MAX_ADJUSTABLE	0x80
 
 
 /*-------------------------------------------------------------------------*/
@@ -352,12 +379,154 @@ struct usb_interface_assoc_descriptor {
 
 /*-------------------------------------------------------------------------*/
 
+/* USB_DT_SECURITY:  group of wireless security descriptors, including
+ * encryption types available for setting up a CC/association.
+ */
+struct usb_security_descriptor {
+	__u8  bLength;
+	__u8  bDescriptorType;
+
+	__le16 wTotalLength;
+	__u8  bNumEncryptionTypes;
+};
+
+/*-------------------------------------------------------------------------*/
+
+/* USB_DT_KEY:  used with {GET,SET}_SECURITY_DATA; only public keys
+ * may be retrieved.
+ */
+struct usb_key_descriptor {
+	__u8  bLength;
+	__u8  bDescriptorType;
+
+	__u8  tTKID[3];
+	__u8  bReserved;
+	__u8  bKeyData[0];
+};
+
+/*-------------------------------------------------------------------------*/
+
+/* USB_DT_ENCRYPTION_TYPE:  bundled in DT_SECURITY groups */
+struct usb_encryption_descriptor {
+	__u8  bLength;
+	__u8  bDescriptorType;
+
+	__u8  bEncryptionType;
+#define	USB_ENC_TYPE_UNSECURE		0
+#define	USB_ENC_TYPE_WIRED		1	/* non-wireless mode */
+#define	USB_ENC_TYPE_CCM_1		2	/* aes128/cbc session */
+#define	USB_ENC_TYPE_RSA_1		3	/* rsa3072/sha1 auth */
+	__u8  bEncryptionValue;		/* use in SET_ENCRYPTION */
+	__u8  bAuthKeyIndex;
+};
+
+
+/*-------------------------------------------------------------------------*/
+
+/* USB_DT_BOS:  group of wireless capabilities */
+struct usb_bos_descriptor {
+	__u8  bLength;
+	__u8  bDescriptorType;
+
+	__le16 wTotalLength;
+	__u8  bNumDeviceCaps;
+};
+
+/*-------------------------------------------------------------------------*/
+
+/* USB_DT_DEVICE_CAPABILITY:  grouped with BOS */
+struct usb_dev_cap_header {
+	__u8  bLength;
+	__u8  bDescriptorType;
+	__u8  bDevCapabilityType;
+};
+
+#define	USB_CAP_TYPE_WIRELESS_USB	1
+
+struct usb_wireless_cap_descriptor {	/* Ultra Wide Band */
+	__u8  bLength;
+	__u8  bDescriptorType;
+	__u8  bDevCapabilityType;
+
+	__u8  bmAttributes;
+#define	USB_WIRELESS_P2P_DRD		(1 << 1)
+#define	USB_WIRELESS_BEACON_MASK	(3 << 2)
+#define	USB_WIRELESS_BEACON_SELF	(1 << 2)
+#define	USB_WIRELESS_BEACON_DIRECTED	(2 << 2)
+#define	USB_WIRELESS_BEACON_NONE	(3 << 2)
+	__le16 wPHYRates;	/* bit rates, Mbps */
+#define	USB_WIRELESS_PHY_53		(1 << 0)	/* always set */
+#define	USB_WIRELESS_PHY_80		(1 << 1)
+#define	USB_WIRELESS_PHY_107		(1 << 2)	/* always set */
+#define	USB_WIRELESS_PHY_160		(1 << 3)
+#define	USB_WIRELESS_PHY_200		(1 << 4)	/* always set */
+#define	USB_WIRELESS_PHY_320		(1 << 5)
+#define	USB_WIRELESS_PHY_400		(1 << 6)
+#define	USB_WIRELESS_PHY_480		(1 << 7)
+	__u8  bmTFITXPowerInfo;	/* TFI power levels */
+	__u8  bmFFITXPowerInfo;	/* FFI power levels */
+	__le16 bmBandGroup;
+	__u8  bReserved;
+};
+
+/*-------------------------------------------------------------------------*/
+
+/* USB_DT_WIRELESS_ENDPOINT_COMP:  companion descriptor associated with
+ * each endpoint descriptor for a wireless device
+ */
+struct usb_wireless_ep_comp_descriptor {
+	__u8  bLength;
+	__u8  bDescriptorType;
+
+	__u8  bMaxBurst;
+	__u8  bMaxSequence;
+	__le16 wMaxStreamDelay;
+	__le16 wOverTheAirPacketSize;
+	__u8  bOverTheAirInterval;
+	__u8  bmCompAttributes;
+#define USB_ENDPOINT_SWITCH_MASK	0x03	/* in bmCompAttributes */
+#define USB_ENDPOINT_SWITCH_NO		0
+#define USB_ENDPOINT_SWITCH_SWITCH	1
+#define USB_ENDPOINT_SWITCH_SCALE	2
+};
+
+/*-------------------------------------------------------------------------*/
+
+/* USB_REQ_SET_HANDSHAKE is a four-way handshake used between a wireless
+ * host and a device for connection set up, mutual authentication, and
+ * exchanging short lived session keys.  The handshake depends on a CC.
+ */
+struct usb_handshake {
+	__u8 bMessageNumber;
+	__u8 bStatus;
+	__u8 tTKID[3];
+	__u8 bReserved;
+	__u8 CDID[16];
+	__u8 nonce[16];
+	__u8 MIC[8];
+};
+
+/*-------------------------------------------------------------------------*/
+
+/* USB_REQ_SET_CONNECTION modifies or revokes a connection context (CC).
+ * A CC may also be set up using non-wireless secure channels (including
+ * wired USB!), and some devices may support CCs with multiple hosts.
+ */
+struct usb_connection_context {
+	__u8 CHID[16];		/* persistent host id */
+	__u8 CDID[16];		/* device id (unique w/in host context) */
+	__u8 CK[16];		/* connection key */
+};
+
+/*-------------------------------------------------------------------------*/
+
 /* USB 2.0 defines three speeds, here's how Linux identifies them */
 
 enum usb_device_speed {
 	USB_SPEED_UNKNOWN = 0,			/* enumerating */
 	USB_SPEED_LOW, USB_SPEED_FULL,		/* usb 1.1 */
-	USB_SPEED_HIGH				/* usb 2.0 */
+	USB_SPEED_HIGH,				/* usb 2.0 */
+	USB_SPEED_VARIABLE,			/* wireless (usb 2.5) */
 };
 
 enum usb_device_state {
diff --git a/include/linux/usb_gadget.h b/include/linux/usb_gadget.h
--- a/include/linux/usb_gadget.h
+++ b/include/linux/usb_gadget.h
@@ -107,18 +107,18 @@ struct usb_ep_ops {
 	int (*disable) (struct usb_ep *ep);
 
 	struct usb_request *(*alloc_request) (struct usb_ep *ep,
-		int gfp_flags);
+		unsigned gfp_flags);
 	void (*free_request) (struct usb_ep *ep, struct usb_request *req);
 
 	void *(*alloc_buffer) (struct usb_ep *ep, unsigned bytes,
-		dma_addr_t *dma, int gfp_flags);
+		dma_addr_t *dma, unsigned gfp_flags);
 	void (*free_buffer) (struct usb_ep *ep, void *buf, dma_addr_t dma,
 		unsigned bytes);
 	// NOTE:  on 2.6, drivers may also use dma_map() and
 	// dma_sync_single_*() to directly manage dma overhead. 
 
 	int (*queue) (struct usb_ep *ep, struct usb_request *req,
-		int gfp_flags);
+		unsigned gfp_flags);
 	int (*dequeue) (struct usb_ep *ep, struct usb_request *req);
 
 	int (*set_halt) (struct usb_ep *ep, int value);
@@ -214,7 +214,7 @@ usb_ep_disable (struct usb_ep *ep)
  * Returns the request, or null if one could not be allocated.
  */
 static inline struct usb_request *
-usb_ep_alloc_request (struct usb_ep *ep, int gfp_flags)
+usb_ep_alloc_request (struct usb_ep *ep, unsigned gfp_flags)
 {
 	return ep->ops->alloc_request (ep, gfp_flags);
 }
@@ -254,7 +254,7 @@ usb_ep_free_request (struct usb_ep *ep, 
  */
 static inline void *
 usb_ep_alloc_buffer (struct usb_ep *ep, unsigned len, dma_addr_t *dma,
-	int gfp_flags)
+	unsigned gfp_flags)
 {
 	return ep->ops->alloc_buffer (ep, len, dma, gfp_flags);
 }
@@ -330,7 +330,7 @@ usb_ep_free_buffer (struct usb_ep *ep, v
  * reported when the usb peripheral is disconnected.
  */
 static inline int
-usb_ep_queue (struct usb_ep *ep, struct usb_request *req, int gfp_flags)
+usb_ep_queue (struct usb_ep *ep, struct usb_request *req, unsigned gfp_flags)
 {
 	return ep->ops->queue (ep, req, gfp_flags);
 }
@@ -711,7 +711,7 @@ usb_gadget_disconnect (struct usb_gadget
  * 	the hardware level driver. Most calls must be handled by
  * 	the gadget driver, including descriptor and configuration
  * 	management.  The 16 bit members of the setup data are in
- * 	cpu order. Called in_interrupt; this may not sleep.  Driver
+ * 	USB byte order. Called in_interrupt; this may not sleep.  Driver
  *	queues a response to ep0, or returns negative to stall.
  * @disconnect: Invoked after all transfers have been stopped,
  * 	when the host is disconnected.  May be called in_interrupt; this
diff --git a/include/linux/usb_input.h b/include/linux/usb_input.h
new file mode 100644
--- /dev/null
+++ b/include/linux/usb_input.h
@@ -0,0 +1,25 @@
+#ifndef __USB_INPUT_H
+#define __USB_INPUT_H
+
+/*
+ * Copyright (C) 2005 Dmitry Torokhov
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+
+#include <linux/usb.h>
+#include <linux/input.h>
+#include <asm/byteorder.h>
+
+static inline void
+usb_to_input_id(const struct usb_device *dev, struct input_id *id)
+{
+	id->bustype = BUS_USB;
+	id->vendor = le16_to_cpu(dev->descriptor.idVendor);
+	id->product = le16_to_cpu(dev->descriptor.idProduct);
+	id->version = le16_to_cpu(dev->descriptor.bcdDevice);
+}
+
+#endif
diff --git a/include/linux/usb_isp116x.h b/include/linux/usb_isp116x.h
new file mode 100644
--- /dev/null
+++ b/include/linux/usb_isp116x.h
@@ -0,0 +1,47 @@
+
+/*
+ * Board initialization code should put one of these into dev->platform_data
+ * and place the isp116x onto platform_bus.
+ */
+
+struct isp116x_platform_data {
+	/* Enable internal resistors on downstream ports */
+	unsigned sel15Kres:1;
+	/* Chip's internal clock won't be stopped in suspended state.
+	   Setting/unsetting this bit takes effect only if
+	   'remote_wakeup_enable' below is not set. */
+	unsigned clknotstop:1;
+	/* On-chip overcurrent protection */
+	unsigned oc_enable:1;
+	/* INT output polarity */
+	unsigned int_act_high:1;
+	/* INT edge or level triggered */
+	unsigned int_edge_triggered:1;
+	/* WAKEUP pin connected - NOT SUPPORTED  */
+	/* unsigned remote_wakeup_connected:1; */
+	/* Wakeup by devices on usb bus enabled */
+	unsigned remote_wakeup_enable:1;
+	/* Switch or not to switch (keep always powered) */
+	unsigned no_power_switching:1;
+	/* Ganged port power switching (0) or individual port
+	   power switching (1) */
+	unsigned power_switching_mode:1;
+	/* Given port_power, msec/2 after power on till power good */
+	u8 potpg;
+	/* Hardware reset set/clear. If implemented, this function must:
+	   if set == 0,   deassert chip's HW reset pin
+	   otherwise,     assert chip's HW reset pin       */
+	void (*reset) (struct device * dev, int set);
+	/* Hardware clock start/stop. If implemented, this function must:
+	   if start == 0,    stop the external clock
+	   otherwise,        start the external clock
+	 */
+	void (*clock) (struct device * dev, int start);
+	/* Inter-io delay (ns). The chip is picky about access timings; it
+	   expects at least:
+	   150ns delay between consecutive accesses to DATA_REG,
+	   300ns delay between access to ADDR_REG and DATA_REG
+	   OE, WE MUST NOT be changed during these intervals
+	 */
+	void (*delay) (struct device * dev, int delay);
+};
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -221,6 +221,8 @@ struct v4l2_pix_format
 /*  Vendor-specific formats   */
 #define V4L2_PIX_FMT_WNVA     v4l2_fourcc('W','N','V','A') /* Winnov hw compress */
 #define V4L2_PIX_FMT_SN9C10X  v4l2_fourcc('S','9','1','0') /* SN9C10x compression */
+#define V4L2_PIX_FMT_PWC1     v4l2_fourcc('P','W','C','1') /* pwc older webcam */
+#define V4L2_PIX_FMT_PWC2     v4l2_fourcc('P','W','C','2') /* pwc newer webcam */
 
 /*
  *	F O R M A T   E N U M E R A T I O N
diff --git a/include/linux/wait.h b/include/linux/wait.h
--- a/include/linux/wait.h
+++ b/include/linux/wait.h
@@ -33,7 +33,7 @@ int default_wake_function(wait_queue_t *
 struct __wait_queue {
 	unsigned int flags;
 #define WQ_FLAG_EXCLUSIVE	0x01
-	struct task_struct * task;
+	void *private;
 	wait_queue_func_t func;
 	struct list_head task_list;
 };
@@ -60,7 +60,7 @@ typedef struct __wait_queue_head wait_qu
  */
 
 #define __WAITQUEUE_INITIALIZER(name, tsk) {				\
-	.task		= tsk,						\
+	.private	= tsk,						\
 	.func		= default_wake_function,			\
 	.task_list	= { NULL, NULL } }
 
@@ -86,7 +86,7 @@ static inline void init_waitqueue_head(w
 static inline void init_waitqueue_entry(wait_queue_t *q, struct task_struct *p)
 {
 	q->flags = 0;
-	q->task = p;
+	q->private = p;
 	q->func = default_wake_function;
 }
 
@@ -94,7 +94,7 @@ static inline void init_waitqueue_func_e
 					wait_queue_func_t func)
 {
 	q->flags = 0;
-	q->task = NULL;
+	q->private = NULL;
 	q->func = func;
 }
 
@@ -110,7 +110,7 @@ static inline int waitqueue_active(wait_
  * aio specifies a wait queue entry with an async notification
  * callback routine, not associated with any task.
  */
-#define is_sync_wait(wait)	(!(wait) || ((wait)->task))
+#define is_sync_wait(wait)	(!(wait) || ((wait)->private))
 
 extern void FASTCALL(add_wait_queue(wait_queue_head_t *q, wait_queue_t * wait));
 extern void FASTCALL(add_wait_queue_exclusive(wait_queue_head_t *q, wait_queue_t * wait));
@@ -384,7 +384,7 @@ int wake_bit_function(wait_queue_t *wait
 
 #define DEFINE_WAIT(name)						\
 	wait_queue_t name = {						\
-		.task		= current,				\
+		.private	= current,				\
 		.func		= autoremove_wake_function,		\
 		.task_list	= LIST_HEAD_INIT((name).task_list),	\
 	}
@@ -393,7 +393,7 @@ int wake_bit_function(wait_queue_t *wait
 	struct wait_bit_queue name = {					\
 		.key = __WAIT_BIT_KEY_INITIALIZER(word, bit),		\
 		.wait	= {						\
-			.task		= current,			\
+			.private	= current,			\
 			.func		= wake_bit_function,		\
 			.task_list	=				\
 				LIST_HEAD_INIT((name).wait.task_list),	\
@@ -402,7 +402,7 @@ int wake_bit_function(wait_queue_t *wait
 
 #define init_wait(wait)							\
 	do {								\
-		(wait)->task = current;					\
+		(wait)->private = current;				\
 		(wait)->func = autoremove_wake_function;		\
 		INIT_LIST_HEAD(&(wait)->task_list);			\
 	} while (0)
diff --git a/include/linux/wanrouter.h b/include/linux/wanrouter.h
--- a/include/linux/wanrouter.h
+++ b/include/linux/wanrouter.h
@@ -516,8 +516,7 @@ struct wan_device {
 /* Public functions available for device drivers */
 extern int register_wan_device(struct wan_device *wandev);
 extern int unregister_wan_device(char *name);
-unsigned short wanrouter_type_trans(struct sk_buff *skb,
-				    struct net_device *dev);
+__be16 wanrouter_type_trans(struct sk_buff *skb, struct net_device *dev);
 int wanrouter_encapsulate(struct sk_buff *skb, struct net_device *dev,
 			  unsigned short type);
 
diff --git a/include/linux/watchdog.h b/include/linux/watchdog.h
--- a/include/linux/watchdog.h
+++ b/include/linux/watchdog.h
@@ -47,4 +47,14 @@ struct watchdog_info {
 #define	WDIOS_ENABLECARD	0x0002	/* Turn on the watchdog timer */
 #define	WDIOS_TEMPPANIC		0x0004	/* Kernel panic on temperature trip */
 
+#ifdef __KERNEL__
+
+#ifdef CONFIG_WATCHDOG_NOWAYOUT
+#define WATCHDOG_NOWAYOUT	1
+#else
+#define WATCHDOG_NOWAYOUT	0
+#endif
+
+#endif	/* __KERNEL__ */
+
 #endif  /* ifndef _LINUX_WATCHDOG_H */
diff --git a/include/linux/wireless.h b/include/linux/wireless.h
--- a/include/linux/wireless.h
+++ b/include/linux/wireless.h
@@ -1,10 +1,10 @@
 /*
  * This file define a set of standard wireless extensions
  *
- * Version :	17	21.6.04
+ * Version :	18	12.3.05
  *
  * Authors :	Jean Tourrilhes - HPL - <jt@hpl.hp.com>
- * Copyright (c) 1997-2004 Jean Tourrilhes, All Rights Reserved.
+ * Copyright (c) 1997-2005 Jean Tourrilhes, All Rights Reserved.
  */
 
 #ifndef _LINUX_WIRELESS_H
@@ -82,7 +82,7 @@
  * (there is some stuff that will be added in the future...)
  * I just plan to increment with each new version.
  */
-#define WIRELESS_EXT	17
+#define WIRELESS_EXT	18
 
 /*
  * Changes :
@@ -182,6 +182,21 @@
  *	- Document (struct iw_quality *)->updated, add new flags (INVALID)
  *	- Wireless Event capability in struct iw_range
  *	- Add support for relative TxPower (yick !)
+ *
+ * V17 to V18 (From Jouni Malinen <jkmaline@cc.hut.fi>)
+ * ----------
+ *	- Add support for WPA/WPA2
+ *	- Add extended encoding configuration (SIOCSIWENCODEEXT and
+ *	  SIOCGIWENCODEEXT)
+ *	- Add SIOCSIWGENIE/SIOCGIWGENIE
+ *	- Add SIOCSIWMLME
+ *	- Add SIOCSIWPMKSA
+ *	- Add struct iw_range bit field for supported encoding capabilities
+ *	- Add optional scan request parameters for SIOCSIWSCAN
+ *	- Add SIOCSIWAUTH/SIOCGIWAUTH for setting authentication and WPA
+ *	  related parameters (extensible up to 4096 parameter values)
+ *	- Add wireless events: IWEVGENIE, IWEVMICHAELMICFAILURE,
+ *	  IWEVASSOCREQIE, IWEVASSOCRESPIE, IWEVPMKIDCAND
  */
 
 /**************************** CONSTANTS ****************************/
@@ -256,6 +271,30 @@
 #define SIOCSIWPOWER	0x8B2C		/* set Power Management settings */
 #define SIOCGIWPOWER	0x8B2D		/* get Power Management settings */
 
+/* WPA : Generic IEEE 802.11 informatiom element (e.g., for WPA/RSN/WMM).
+ * This ioctl uses struct iw_point and data buffer that includes IE id and len
+ * fields. More than one IE may be included in the request. Setting the generic
+ * IE to empty buffer (len=0) removes the generic IE from the driver. Drivers
+ * are allowed to generate their own WPA/RSN IEs, but in these cases, drivers
+ * are required to report the used IE as a wireless event, e.g., when
+ * associating with an AP. */
+#define SIOCSIWGENIE	0x8B30		/* set generic IE */
+#define SIOCGIWGENIE	0x8B31		/* get generic IE */
+
+/* WPA : IEEE 802.11 MLME requests */
+#define SIOCSIWMLME	0x8B16		/* request MLME operation; uses
+					 * struct iw_mlme */
+/* WPA : Authentication mode parameters */
+#define SIOCSIWAUTH	0x8B32		/* set authentication mode params */
+#define SIOCGIWAUTH	0x8B33		/* get authentication mode params */
+
+/* WPA : Extended version of encoding configuration */
+#define SIOCSIWENCODEEXT 0x8B34		/* set encoding token & mode */
+#define SIOCGIWENCODEEXT 0x8B35		/* get encoding token & mode */
+
+/* WPA2 : PMKSA cache management */
+#define SIOCSIWPMKSA	0x8B36		/* PMKSA cache operation */
+
 /* -------------------- DEV PRIVATE IOCTL LIST -------------------- */
 
 /* These 32 ioctl are wireless device private, for 16 commands.
@@ -297,6 +336,34 @@
 #define IWEVCUSTOM	0x8C02		/* Driver specific ascii string */
 #define IWEVREGISTERED	0x8C03		/* Discovered a new node (AP mode) */
 #define IWEVEXPIRED	0x8C04		/* Expired a node (AP mode) */
+#define IWEVGENIE	0x8C05		/* Generic IE (WPA, RSN, WMM, ..)
+					 * (scan results); This includes id and
+					 * length fields. One IWEVGENIE may
+					 * contain more than one IE. Scan
+					 * results may contain one or more
+					 * IWEVGENIE events. */
+#define IWEVMICHAELMICFAILURE 0x8C06	/* Michael MIC failure
+					 * (struct iw_michaelmicfailure)
+					 */
+#define IWEVASSOCREQIE	0x8C07		/* IEs used in (Re)Association Request.
+					 * The data includes id and length
+					 * fields and may contain more than one
+					 * IE. This event is required in
+					 * Managed mode if the driver
+					 * generates its own WPA/RSN IE. This
+					 * should be sent just before
+					 * IWEVREGISTERED event for the
+					 * association. */
+#define IWEVASSOCRESPIE	0x8C08		/* IEs used in (Re)Association
+					 * Response. The data includes id and
+					 * length fields and may contain more
+					 * than one IE. This may be sent
+					 * between IWEVASSOCREQIE and
+					 * IWEVREGISTERED events for the
+					 * association. */
+#define IWEVPMKIDCAND	0x8C09		/* PMKID candidate for RSN
+					 * pre-authentication
+					 * (struct iw_pmkid_cand) */
 
 #define IWEVFIRST	0x8C00
 
@@ -432,12 +499,94 @@
 #define IW_SCAN_THIS_MODE	0x0020	/* Scan only this Mode */
 #define IW_SCAN_ALL_RATE	0x0040	/* Scan all Bit-Rates */
 #define IW_SCAN_THIS_RATE	0x0080	/* Scan only this Bit-Rate */
+/* struct iw_scan_req scan_type */
+#define IW_SCAN_TYPE_ACTIVE 0
+#define IW_SCAN_TYPE_PASSIVE 1
 /* Maximum size of returned data */
 #define IW_SCAN_MAX_DATA	4096	/* In bytes */
 
 /* Max number of char in custom event - use multiple of them if needed */
 #define IW_CUSTOM_MAX		256	/* In bytes */
 
+/* Generic information element */
+#define IW_GENERIC_IE_MAX	1024
+
+/* MLME requests (SIOCSIWMLME / struct iw_mlme) */
+#define IW_MLME_DEAUTH		0
+#define IW_MLME_DISASSOC	1
+
+/* SIOCSIWAUTH/SIOCGIWAUTH struct iw_param flags */
+#define IW_AUTH_INDEX		0x0FFF
+#define IW_AUTH_FLAGS		0xF000
+/* SIOCSIWAUTH/SIOCGIWAUTH parameters (0 .. 4095)
+ * (IW_AUTH_INDEX mask in struct iw_param flags; this is the index of the
+ * parameter that is being set/get to; value will be read/written to
+ * struct iw_param value field) */
+#define IW_AUTH_WPA_VERSION		0
+#define IW_AUTH_CIPHER_PAIRWISE		1
+#define IW_AUTH_CIPHER_GROUP		2
+#define IW_AUTH_KEY_MGMT		3
+#define IW_AUTH_TKIP_COUNTERMEASURES	4
+#define IW_AUTH_DROP_UNENCRYPTED	5
+#define IW_AUTH_80211_AUTH_ALG		6
+#define IW_AUTH_WPA_ENABLED		7
+#define IW_AUTH_RX_UNENCRYPTED_EAPOL	8
+#define IW_AUTH_ROAMING_CONTROL		9
+#define IW_AUTH_PRIVACY_INVOKED		10
+
+/* IW_AUTH_WPA_VERSION values (bit field) */
+#define IW_AUTH_WPA_VERSION_DISABLED	0x00000001
+#define IW_AUTH_WPA_VERSION_WPA		0x00000002
+#define IW_AUTH_WPA_VERSION_WPA2	0x00000004
+
+/* IW_AUTH_PAIRWISE_CIPHER and IW_AUTH_GROUP_CIPHER values (bit field) */
+#define IW_AUTH_CIPHER_NONE	0x00000001
+#define IW_AUTH_CIPHER_WEP40	0x00000002
+#define IW_AUTH_CIPHER_TKIP	0x00000004
+#define IW_AUTH_CIPHER_CCMP	0x00000008
+#define IW_AUTH_CIPHER_WEP104	0x00000010
+
+/* IW_AUTH_KEY_MGMT values (bit field) */
+#define IW_AUTH_KEY_MGMT_802_1X	1
+#define IW_AUTH_KEY_MGMT_PSK	2
+
+/* IW_AUTH_80211_AUTH_ALG values (bit field) */
+#define IW_AUTH_ALG_OPEN_SYSTEM	0x00000001
+#define IW_AUTH_ALG_SHARED_KEY	0x00000002
+#define IW_AUTH_ALG_LEAP	0x00000004
+
+/* IW_AUTH_ROAMING_CONTROL values */
+#define IW_AUTH_ROAMING_ENABLE	0	/* driver/firmware based roaming */
+#define IW_AUTH_ROAMING_DISABLE	1	/* user space program used for roaming
+					 * control */
+
+/* SIOCSIWENCODEEXT definitions */
+#define IW_ENCODE_SEQ_MAX_SIZE	8
+/* struct iw_encode_ext ->alg */
+#define IW_ENCODE_ALG_NONE	0
+#define IW_ENCODE_ALG_WEP	1
+#define IW_ENCODE_ALG_TKIP	2
+#define IW_ENCODE_ALG_CCMP	3
+/* struct iw_encode_ext ->ext_flags */
+#define IW_ENCODE_EXT_TX_SEQ_VALID	0x00000001
+#define IW_ENCODE_EXT_RX_SEQ_VALID	0x00000002
+#define IW_ENCODE_EXT_GROUP_KEY		0x00000004
+#define IW_ENCODE_EXT_SET_TX_KEY	0x00000008
+
+/* IWEVMICHAELMICFAILURE : struct iw_michaelmicfailure ->flags */
+#define IW_MICFAILURE_KEY_ID	0x00000003 /* Key ID 0..3 */
+#define IW_MICFAILURE_GROUP	0x00000004
+#define IW_MICFAILURE_PAIRWISE	0x00000008
+#define IW_MICFAILURE_STAKEY	0x00000010
+#define IW_MICFAILURE_COUNT	0x00000060 /* 1 or 2 (0 = count not supported)
+					    */
+
+/* Bit field values for enc_capa in struct iw_range */
+#define IW_ENC_CAPA_WPA		0x00000001
+#define IW_ENC_CAPA_WPA2	0x00000002
+#define IW_ENC_CAPA_CIPHER_TKIP	0x00000004
+#define IW_ENC_CAPA_CIPHER_CCMP	0x00000008
+
 /* Event capability macros - in (struct iw_range *)->event_capa
  * Because we have more than 32 possible events, we use an array of
  * 32 bit bitmasks. Note : 32 bits = 0x20 = 2^5. */
@@ -546,6 +695,132 @@ struct	iw_thrspy
 	struct iw_quality	high;		/* High threshold */
 };
 
+/*
+ *	Optional data for scan request
+ *
+ *	Note: these optional parameters are controlling parameters for the
+ *	scanning behavior, these do not apply to getting scan results
+ *	(SIOCGIWSCAN). Drivers are expected to keep a local BSS table and
+ *	provide a merged results with all BSSes even if the previous scan
+ *	request limited scanning to a subset, e.g., by specifying an SSID.
+ *	Especially, scan results are required to include an entry for the
+ *	current BSS if the driver is in Managed mode and associated with an AP.
+ */
+struct	iw_scan_req
+{
+	__u8		scan_type; /* IW_SCAN_TYPE_{ACTIVE,PASSIVE} */
+	__u8		essid_len;
+	__u8		num_channels; /* num entries in channel_list;
+				       * 0 = scan all allowed channels */
+	__u8		flags; /* reserved as padding; use zero, this may
+				* be used in the future for adding flags
+				* to request different scan behavior */
+	struct sockaddr	bssid; /* ff:ff:ff:ff:ff:ff for broadcast BSSID or
+				* individual address of a specific BSS */
+
+	/*
+	 * Use this ESSID if IW_SCAN_THIS_ESSID flag is used instead of using
+	 * the current ESSID. This allows scan requests for specific ESSID
+	 * without having to change the current ESSID and potentially breaking
+	 * the current association.
+	 */
+	__u8		essid[IW_ESSID_MAX_SIZE];
+
+	/*
+	 * Optional parameters for changing the default scanning behavior.
+	 * These are based on the MLME-SCAN.request from IEEE Std 802.11.
+	 * TU is 1.024 ms. If these are set to 0, driver is expected to use
+	 * reasonable default values. min_channel_time defines the time that
+	 * will be used to wait for the first reply on each channel. If no
+	 * replies are received, next channel will be scanned after this. If
+	 * replies are received, total time waited on the channel is defined by
+	 * max_channel_time.
+	 */
+	__u32		min_channel_time; /* in TU */
+	__u32		max_channel_time; /* in TU */
+
+	struct iw_freq	channel_list[IW_MAX_FREQUENCIES];
+};
+
+/* ------------------------- WPA SUPPORT ------------------------- */
+
+/*
+ *	Extended data structure for get/set encoding (this is used with
+ *	SIOCSIWENCODEEXT/SIOCGIWENCODEEXT. struct iw_point and IW_ENCODE_*
+ *	flags are used in the same way as with SIOCSIWENCODE/SIOCGIWENCODE and
+ *	only the data contents changes (key data -> this structure, including
+ *	key data).
+ *
+ *	If the new key is the first group key, it will be set as the default
+ *	TX key. Otherwise, default TX key index is only changed if
+ *	IW_ENCODE_EXT_SET_TX_KEY flag is set.
+ *
+ *	Key will be changed with SIOCSIWENCODEEXT in all cases except for
+ *	special "change TX key index" operation which is indicated by setting
+ *	key_len = 0 and ext_flags |= IW_ENCODE_EXT_SET_TX_KEY.
+ *
+ *	tx_seq/rx_seq are only used when respective
+ *	IW_ENCODE_EXT_{TX,RX}_SEQ_VALID flag is set in ext_flags. Normal
+ *	TKIP/CCMP operation is to set RX seq with SIOCSIWENCODEEXT and start
+ *	TX seq from zero whenever key is changed. SIOCGIWENCODEEXT is normally
+ *	used only by an Authenticator (AP or an IBSS station) to get the
+ *	current TX sequence number. Using TX_SEQ_VALID for SIOCSIWENCODEEXT and
+ *	RX_SEQ_VALID for SIOCGIWENCODEEXT are optional, but can be useful for
+ *	debugging/testing.
+ */
+struct	iw_encode_ext
+{
+	__u32		ext_flags; /* IW_ENCODE_EXT_* */
+	__u8		tx_seq[IW_ENCODE_SEQ_MAX_SIZE]; /* LSB first */
+	__u8		rx_seq[IW_ENCODE_SEQ_MAX_SIZE]; /* LSB first */
+	struct sockaddr	addr; /* ff:ff:ff:ff:ff:ff for broadcast/multicast
+			       * (group) keys or unicast address for
+			       * individual keys */
+	__u16		alg; /* IW_ENCODE_ALG_* */
+	__u16		key_len;
+	__u8		key[0];
+};
+
+/* SIOCSIWMLME data */
+struct	iw_mlme
+{
+	__u16		cmd; /* IW_MLME_* */
+	__u16		reason_code;
+	struct sockaddr	addr;
+};
+
+/* SIOCSIWPMKSA data */
+#define IW_PMKSA_ADD		1
+#define IW_PMKSA_REMOVE		2
+#define IW_PMKSA_FLUSH		3
+
+#define IW_PMKID_LEN	16
+
+struct	iw_pmksa
+{
+	__u32		cmd; /* IW_PMKSA_* */
+	struct sockaddr	bssid;
+	__u8		pmkid[IW_PMKID_LEN];
+};
+
+/* IWEVMICHAELMICFAILURE data */
+struct	iw_michaelmicfailure
+{
+	__u32		flags;
+	struct sockaddr	src_addr;
+	__u8		tsc[IW_ENCODE_SEQ_MAX_SIZE]; /* LSB first */
+};
+
+/* IWEVPMKIDCAND data */
+#define IW_PMKID_CAND_PREAUTH	0x00000001 /* RNS pre-authentication enabled */
+struct	iw_pmkid_cand
+{
+	__u32		flags; /* IW_PMKID_CAND_* */
+	__u32		index; /* the smaller the index, the higher the
+				* priority */
+	struct sockaddr	bssid;
+};
+
 /* ------------------------ WIRELESS STATS ------------------------ */
 /*
  * Wireless statistics (used for /proc/net/wireless)
@@ -725,6 +1000,8 @@ struct	iw_range
 	struct iw_freq	freq[IW_MAX_FREQUENCIES];	/* list */
 	/* Note : this frequency list doesn't need to fit channel numbers,
 	 * because each entry contain its channel index */
+
+	__u32		enc_capa; /* IW_ENC_CAPA_* bit field */
 };
 
 /*
diff --git a/include/linux/writeback.h b/include/linux/writeback.h
--- a/include/linux/writeback.h
+++ b/include/linux/writeback.h
@@ -14,11 +14,13 @@ extern struct list_head inode_unused;
  * Yes, writeback.h requires sched.h
  * No, sched.h is not included from here.
  */
-static inline int current_is_pdflush(void)
+static inline int task_is_pdflush(struct task_struct *task)
 {
-	return current->flags & PF_FLUSHER;
+	return task->flags & PF_FLUSHER;
 }
 
+#define current_is_pdflush()	task_is_pdflush(current)
+
 /*
  * fs/fs-writeback.c
  */
@@ -83,7 +85,7 @@ static inline void wait_on_inode(struct 
 /*
  * mm/page-writeback.c
  */
-int wakeup_bdflush(long nr_pages);
+int wakeup_pdflush(long nr_pages);
 void laptop_io_completion(void);
 void laptop_sync_completion(void);
 void throttle_vm_writeout(void);
diff --git a/include/linux/x25.h b/include/linux/x25.h
--- a/include/linux/x25.h
+++ b/include/linux/x25.h
@@ -4,6 +4,8 @@
  * 	History
  *	mar/20/00	Daniela Squassoni Disabling/enabling of facilities 
  *					  negotiation.
+ *	apr/02/05	Shaun Pereira Selective sub address matching with
+ *					call user data
  */
 
 #ifndef	X25_KERNEL_H
@@ -16,6 +18,9 @@
 #define	SIOCX25GCALLUSERDATA	(SIOCPROTOPRIVATE + 4)
 #define	SIOCX25SCALLUSERDATA	(SIOCPROTOPRIVATE + 5)
 #define	SIOCX25GCAUSEDIAG	(SIOCPROTOPRIVATE + 6)
+#define SIOCX25SCUDMATCHLEN	(SIOCPROTOPRIVATE + 7)
+#define SIOCX25CALLACCPTAPPRV   (SIOCPROTOPRIVATE + 8)
+#define SIOCX25SENDCALLACCPT    (SIOCPROTOPRIVATE + 9)
 
 /*
  *	Values for {get,set}sockopt.
@@ -109,4 +114,11 @@ struct x25_causediag {
 	unsigned char	diagnostic;
 };
 
+/*
+ *	Further optional call user data match length selection
+ */
+struct x25_subaddr {
+	unsigned int cudmatchlength;
+};
+
 #endif
diff --git a/include/linux/xattr_acl.h b/include/linux/xattr_acl.h
deleted file mode 100644
--- a/include/linux/xattr_acl.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
-  File: linux/xattr_acl.h
-
-  (extended attribute representation of access control lists)
-
-  (C) 2000 Andreas Gruenbacher, <a.gruenbacher@computer.org>
-*/
-
-#ifndef _LINUX_XATTR_ACL_H
-#define _LINUX_XATTR_ACL_H
-
-#include <linux/posix_acl.h>
-
-#define XATTR_NAME_ACL_ACCESS	"system.posix_acl_access"
-#define XATTR_NAME_ACL_DEFAULT	"system.posix_acl_default"
-
-#define XATTR_ACL_VERSION	0x0002
-
-typedef struct {
-	__u16		e_tag;
-	__u16		e_perm;
-	__u32		e_id;
-} xattr_acl_entry;
-
-typedef struct {
-	__u32		a_version;
-	xattr_acl_entry	a_entries[0];
-} xattr_acl_header;
-
-static inline size_t xattr_acl_size(int count)
-{
-	return sizeof(xattr_acl_header) + count * sizeof(xattr_acl_entry);
-}
-
-static inline int xattr_acl_count(size_t size)
-{
-	if (size < sizeof(xattr_acl_header))
-		return -1;
-	size -= sizeof(xattr_acl_header);
-	if (size % sizeof(xattr_acl_entry))
-		return -1;
-	return size / sizeof(xattr_acl_entry);
-}
-
-struct posix_acl * posix_acl_from_xattr(const void *value, size_t size);
-int posix_acl_to_xattr(const struct posix_acl *acl, void *buffer, size_t size);
-
-
-
-#endif /* _LINUX_XATTR_ACL_H */
diff --git a/include/linux/xfrm.h b/include/linux/xfrm.h
--- a/include/linux/xfrm.h
+++ b/include/linux/xfrm.h
@@ -174,6 +174,8 @@ enum xfrm_attr_type_t {
 	XFRMA_ALG_COMP,		/* struct xfrm_algo */
 	XFRMA_ENCAP,		/* struct xfrm_algo + struct xfrm_encap_tmpl */
 	XFRMA_TMPL,		/* 1 or more struct xfrm_user_tmpl */
+	XFRMA_SA,
+	XFRMA_POLICY,
 	__XFRMA_MAX
 
 #define XFRMA_MAX (__XFRMA_MAX - 1)
@@ -194,6 +196,7 @@ struct xfrm_usersa_info {
 	__u8				flags;
 #define XFRM_STATE_NOECN	1
 #define XFRM_STATE_DECAP_DSCP	2
+#define XFRM_STATE_NOPMTUDISC	4
 };
 
 struct xfrm_usersa_id {
@@ -257,5 +260,7 @@ struct xfrm_usersa_flush {
 
 #define XFRMGRP_ACQUIRE		1
 #define XFRMGRP_EXPIRE		2
+#define XFRMGRP_SA		4
+#define XFRMGRP_POLICY		8
 
 #endif /* _LINUX_XFRM_H */
diff --git a/include/linux/zlib.h b/include/linux/zlib.h
--- a/include/linux/zlib.h
+++ b/include/linux/zlib.h
@@ -506,6 +506,11 @@ extern int zlib_deflateReset (z_streamp 
    stream state was inconsistent (such as zalloc or state being NULL).
 */
 
+static inline unsigned long deflateBound(unsigned long s)
+{
+	return s + ((s + 7) >> 3) + ((s + 63) >> 6) + 11;
+}
+
 extern int zlib_deflateParams (z_streamp strm, int level, int strategy);
 /*
      Dynamically update the compression level and compression strategy.  The
diff --git a/include/media/audiochip.h b/include/media/audiochip.h
--- a/include/media/audiochip.h
+++ b/include/media/audiochip.h
@@ -1,3 +1,7 @@
+/*
+ * $Id: audiochip.h,v 1.5 2005/06/16 22:59:16 hhackmann Exp $
+ */
+
 #ifndef AUDIOCHIP_H
 #define AUDIOCHIP_H
 
@@ -31,5 +35,4 @@
 
 /* misc stuff to pass around config info to i2c chips */
 #define AUDC_CONFIG_PINNACLE  _IOW('m',32,int)
-
 #endif /* AUDIOCHIP_H */
diff --git a/include/media/id.h b/include/media/id.h
--- a/include/media/id.h
+++ b/include/media/id.h
@@ -1,3 +1,7 @@
+/*
+ * $Id: id.h,v 1.4 2005/06/12 04:19:19 mchehab Exp $
+ */
+
 /* FIXME: this temporarely, until these are included in linux/i2c-id.h */
 
 /* drivers */
diff --git a/include/media/ir-common.h b/include/media/ir-common.h
--- a/include/media/ir-common.h
+++ b/include/media/ir-common.h
@@ -1,5 +1,5 @@
 /*
- * $Id: ir-common.h,v 1.8 2005/02/22 12:28:40 kraxel Exp $
+ * $Id: ir-common.h,v 1.9 2005/05/15 19:01:26 mchehab Exp $
  *
  * some common structs and functions to handle infrared remotes via
  * input layer ...
@@ -50,6 +50,7 @@ extern IR_KEYTAB_TYPE ir_codes_rc5_tv[IR
 extern IR_KEYTAB_TYPE ir_codes_winfast[IR_KEYTAB_SIZE];
 extern IR_KEYTAB_TYPE ir_codes_empty[IR_KEYTAB_SIZE];
 extern IR_KEYTAB_TYPE ir_codes_hauppauge_new[IR_KEYTAB_SIZE];
+extern IR_KEYTAB_TYPE ir_codes_pixelview[IR_KEYTAB_SIZE];
 
 void ir_input_init(struct input_dev *dev, struct ir_input_state *ir,
 		   int ir_type, IR_KEYTAB_TYPE *ir_codes);
diff --git a/include/media/saa6752hs.h b/include/media/saa6752hs.h
--- a/include/media/saa6752hs.h
+++ b/include/media/saa6752hs.h
@@ -18,55 +18,6 @@
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
-#if 0 /* ndef _SAA6752HS_H */
-#define _SAA6752HS_H
-
-enum mpeg_video_bitrate_mode {
-	MPEG_VIDEO_BITRATE_MODE_VBR = 0, /* Variable bitrate */
-	MPEG_VIDEO_BITRATE_MODE_CBR = 1, /* Constant bitrate */
-
-	MPEG_VIDEO_BITRATE_MODE_MAX
-};
-
-enum mpeg_audio_bitrate {
-	MPEG_AUDIO_BITRATE_256 = 0, /* 256 kBit/sec */
-	MPEG_AUDIO_BITRATE_384 = 1, /* 384 kBit/sec */
-
-	MPEG_AUDIO_BITRATE_MAX
-};
-
-enum mpeg_video_format {
-	MPEG_VIDEO_FORMAT_D1 = 0,
-	MPEG_VIDEO_FORMAT_2_3_D1 = 1,
-	MPEG_VIDEO_FORMAT_1_2_D1 = 2,
-	MPEG_VIDEO_FORMAT_SIF = 3,
-
-	MPEG_VIDEO_FORMAT_MAX
-};
-
-#define MPEG_VIDEO_TARGET_BITRATE_MAX 27000
-#define MPEG_VIDEO_MAX_BITRATE_MAX 27000
-#define MPEG_TOTAL_BITRATE_MAX 27000
-#define MPEG_PID_MAX ((1 << 14) - 1)
-
-struct mpeg_params {
-	enum mpeg_video_bitrate_mode video_bitrate_mode;
-	unsigned int video_target_bitrate;
-	unsigned int video_max_bitrate; // only used for VBR
-	enum mpeg_audio_bitrate audio_bitrate;
-	unsigned int total_bitrate;
-
-   	unsigned int pmt_pid;
-	unsigned int video_pid;
-	unsigned int audio_pid;
-	unsigned int pcr_pid;
-
-	enum mpeg_video_format video_format;
-};
-
-#define MPEG_SETPARAMS             _IOW('6',100,struct mpeg_params)
-
-#endif // _SAA6752HS_H
 
 /*
  * Local variables:
diff --git a/include/media/tuner.h b/include/media/tuner.h
--- a/include/media/tuner.h
+++ b/include/media/tuner.h
@@ -1,5 +1,6 @@
 
-/*
+/* $Id: tuner.h,v 1.45 2005/07/28 18:41:21 mchehab Exp $
+ *
     tuner.h - definition for different tuners
 
     Copyright (C) 1997 Markus Schroeder (schroedm@uni-duesseldorf.de)
@@ -23,7 +24,9 @@
 #ifndef _TUNER_H
 #define _TUNER_H
 
-#include "id.h"
+#include <linux/videodev2.h>
+
+#define ADDR_UNSET (255)
 
 #define TUNER_TEMIC_PAL     0        /* 4002 FH5 (3X 7756, 9483) */
 #define TUNER_PHILIPS_PAL_I 1
@@ -86,7 +89,7 @@
 #define TUNER_LG_NTSC_TAPE       47
 
 #define TUNER_TNF_8831BGFF       48
-#define TUNER_MICROTUNE_4042FI5  49	/* FusionHDTV 3 Gold - 4042 FI5 (3X 8147) */
+#define TUNER_MICROTUNE_4042FI5  49	/* DViCO FusionHDTV 3 Gold-Q - 4042 FI5 (3X 8147) */
 #define TUNER_TCL_2002N          50
 #define TUNER_PHILIPS_FM1256_IH3   51
 
@@ -96,7 +99,17 @@
 #define TUNER_LG_PAL_TAPE        55    /* Hauppauge PVR-150 PAL */
 
 #define TUNER_PHILIPS_FQ1216AME_MK4 56 /* Hauppauge PVR-150 PAL */
-#define TUNER_PHILIPS_FQ1236A_MK4 57   /* Hauppauge PVR-500MCE NTSC */
+#define TUNER_PHILIPS_FQ1236A_MK4   57   /* Hauppauge PVR-500MCE NTSC */
+
+#define TUNER_YMEC_TVF_8531MF 58
+#define TUNER_YMEC_TVF_5533MF 59	/* Pixelview Pro Ultra NTSC */
+#define TUNER_THOMSON_DTT7611 60	/* DViCO FusionHDTV 3 Gold-T */
+#define TUNER_TENA_9533_DI    61
+
+#define TUNER_TEA5767         62	/* Only FM Radio Tuner */
+#define TUNER_PHILIPS_FMD1216ME_MK3 63
+#define TUNER_LG_TDVS_H062F   64	/* DViCO FusionHDTV 5 */
+#define TUNER_YMEC_TVF66T5_B_DFF 65	/* Acorp Y878F */
 
 #define NOTUNER 0
 #define PAL     1	/* PAL_BG */
@@ -104,6 +117,7 @@
 #define NTSC    3
 #define SECAM   4
 #define ATSC    5
+#define RADIO	6
 
 #define NoTuner 0
 #define Philips 1
@@ -119,10 +133,9 @@
 #define TCL     11
 #define THOMSON 12
 
-#define TUNER_SET_TYPE               _IOW('t',1,int)    /* set tuner type */
-#define TUNER_SET_TVFREQ             _IOW('t',2,int)    /* set tv freq */
+#define TUNER_SET_TYPE_ADDR          _IOW('T',3,int)
+#define TDA9887_SET_CONFIG           _IOW('t',5,int)
 
-#define  TDA9887_SET_CONFIG          _IOW('t',5,int)
 /* tv card specific */
 # define TDA9887_PRESENT             (1<<0)
 # define TDA9887_PORT1_INACTIVE      (1<<1)
@@ -143,19 +156,34 @@
 #define I2C_ADDR_TDA8290        0x4b
 #define I2C_ADDR_TDA8275        0x61
 
+enum tuner_mode {
+	T_UNINITIALIZED = 0,
+	T_RADIO		= 1 << V4L2_TUNER_RADIO,
+	T_ANALOG_TV     = 1 << V4L2_TUNER_ANALOG_TV,
+	T_DIGITAL_TV    = 1 << V4L2_TUNER_DIGITAL_TV,
+	T_STANDBY	= 1 << 31
+};
+
+struct tuner_setup {
+	unsigned short		addr;
+	unsigned int		type;
+	unsigned int		mode_mask;
+};
+
 struct tuner {
 	/* device */
 	struct i2c_client i2c;
 
-	/* state + config */
-	unsigned int initialized;
 	unsigned int type;            /* chip type */
+
+	unsigned int          mode;
+	unsigned int          mode_mask; /* Combination of allowable modes */
+
 	unsigned int freq;            /* keep track of the current settings */
+	unsigned int audmode;
 	v4l2_std_id  std;
-	int          using_v4l2;
 
-	enum v4l2_tuner_type mode;
-	unsigned int input;
+	int          using_v4l2;
 
 	/* used by MT2032 */
 	unsigned int xogc;
@@ -177,7 +205,9 @@ extern unsigned const int tuner_count;
 
 extern int microtune_init(struct i2c_client *c);
 extern int tda8290_init(struct i2c_client *c);
+extern int tea5767_tuner_init(struct i2c_client *c);
 extern int default_tuner_init(struct i2c_client *c);
+extern int tea5767_autodetection(struct i2c_client *c);
 
 #define tuner_warn(fmt, arg...) \
 	dev_printk(KERN_WARNING , &t->i2c.dev , fmt , ## arg)
diff --git a/include/media/tveeprom.h b/include/media/tveeprom.h
--- a/include/media/tveeprom.h
+++ b/include/media/tveeprom.h
@@ -1,3 +1,7 @@
+/*
+ * $Id: tveeprom.h,v 1.2 2005/06/12 04:19:19 mchehab Exp $
+ */
+
 struct tveeprom {
 	u32 has_radio;
 
@@ -20,4 +24,3 @@ void tveeprom_hauppauge_analog(struct tv
 			       unsigned char *eeprom_data);
 
 int tveeprom_read(struct i2c_client *c, unsigned char *eedata, int len);
-int tveeprom_dump(unsigned char *eedata, int len);
diff --git a/include/mtd/mtd-abi.h b/include/mtd/mtd-abi.h
--- a/include/mtd/mtd-abi.h
+++ b/include/mtd/mtd-abi.h
@@ -1,5 +1,5 @@
 /*
- * $Id: mtd-abi.h,v 1.7 2004/11/23 15:37:32 gleixner Exp $
+ * $Id: mtd-abi.h,v 1.11 2005/05/19 16:08:58 gleixner Exp $
  *
  * Portions of MTD ABI definition which are shared by kernel and user space 
  */
@@ -29,6 +29,7 @@ struct mtd_oob_buf {
 #define MTD_NORFLASH		3
 #define MTD_NANDFLASH		4
 #define MTD_PEROM		5
+#define MTD_DATAFLASH		6
 #define MTD_OTHER		14
 #define MTD_UNKNOWN		15
 
@@ -60,6 +61,12 @@ struct mtd_oob_buf {
 #define MTD_NANDECC_PLACE	1	// Use the given placement in the structure (YAFFS1 legacy mode)
 #define MTD_NANDECC_AUTOPLACE	2	// Use the default placement scheme
 #define MTD_NANDECC_PLACEONLY	3	// Use the given placement in the structure (Do not store ecc result on read)
+#define MTD_NANDECC_AUTOPL_USR 	4	// Use the given autoplacement scheme rather than using the default
+
+/* OTP mode selection */
+#define MTD_OTP_OFF		0
+#define MTD_OTP_FACTORY		1
+#define MTD_OTP_USER		2
 
 struct mtd_info_user {
 	uint8_t type;
@@ -80,6 +87,12 @@ struct region_info_user {
 	uint32_t regionindex;
 };
 
+struct otp_info {
+	uint32_t start;
+	uint32_t length;
+	uint32_t locked;
+};
+
 #define MEMGETINFO              _IOR('M', 1, struct mtd_info_user)
 #define MEMERASE                _IOW('M', 2, struct erase_info_user)
 #define MEMWRITEOOB             _IOWR('M', 3, struct mtd_oob_buf)
@@ -92,6 +105,10 @@ struct region_info_user {
 #define MEMGETOOBSEL		_IOR('M', 10, struct nand_oobinfo)
 #define MEMGETBADBLOCK		_IOW('M', 11, loff_t)
 #define MEMSETBADBLOCK		_IOW('M', 12, loff_t)
+#define OTPSELECT		_IOR('M', 13, int)
+#define OTPGETREGIONCOUNT	_IOW('M', 14, int)
+#define OTPGETREGIONINFO	_IOW('M', 15, struct otp_info)
+#define OTPLOCK		_IOR('M', 16, struct otp_info)
 
 struct nand_oobinfo {
 	uint32_t useecc;
diff --git a/include/net/ax25.h b/include/net/ax25.h
--- a/include/net/ax25.h
+++ b/include/net/ax25.h
@@ -139,11 +139,25 @@ enum {
 #define AX25_DEF_DS_TIMEOUT	(3 * 60 * HZ)		/* DAMA timeout 3 minutes */
 
 typedef struct ax25_uid_assoc {
-	struct ax25_uid_assoc	*next;
+	struct hlist_node	uid_node;
+	atomic_t		refcount;
 	uid_t			uid;
 	ax25_address		call;
 } ax25_uid_assoc;
 
+#define ax25_uid_for_each(__ax25, node, list) \
+	hlist_for_each_entry(__ax25, node, list, uid_node)
+
+#define ax25_uid_hold(ax25) \
+	atomic_inc(&((ax25)->refcount))
+
+static inline void ax25_uid_put(ax25_uid_assoc *assoc)
+{
+	if (atomic_dec_and_test(&assoc->refcount)) {
+		kfree(assoc);
+	}
+}
+
 typedef struct {
 	ax25_address		calls[AX25_MAX_DIGIS];
 	unsigned char		repeated[AX25_MAX_DIGIS];
@@ -220,7 +234,7 @@ static __inline__ void ax25_cb_put(ax25_
 	}
 }
 
-static inline unsigned short ax25_type_trans(struct sk_buff *skb, struct net_device *dev)
+static inline __be16 ax25_type_trans(struct sk_buff *skb, struct net_device *dev)
 {
 	skb->dev      = dev;
 	skb->pkt_type = PACKET_HOST;
@@ -376,7 +390,7 @@ extern unsigned long ax25_display_timer(
 
 /* ax25_uid.c */
 extern int  ax25_uid_policy;
-extern ax25_address *ax25_findbyuid(uid_t);
+extern ax25_uid_assoc *ax25_findbyuid(uid_t);
 extern int  ax25_uid_ioctl(int, struct sockaddr_ax25 *);
 extern struct file_operations ax25_uid_fops;
 extern void ax25_uid_free(void);
diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
--- a/include/net/bluetooth/bluetooth.h
+++ b/include/net/bluetooth/bluetooth.h
@@ -57,12 +57,6 @@
 #define BT_DBG(fmt, arg...)  printk(KERN_INFO "%s: " fmt "\n" , __FUNCTION__ , ## arg)
 #define BT_ERR(fmt, arg...)  printk(KERN_ERR  "%s: " fmt "\n" , __FUNCTION__ , ## arg)
 
-#ifdef HCI_DATA_DUMP
-#define BT_DMP(buf, len) bt_dump(__FUNCTION__, buf, len)
-#else
-#define BT_DMP(D...)
-#endif
-
 extern struct proc_dir_entry *proc_bt;
 
 /* Connection and socket states */
@@ -174,8 +168,6 @@ static inline int skb_frags_no(struct sk
 	return n;
 }
 
-void bt_dump(char *pref, __u8 *buf, int count);
-
 int bt_err(__u16 code);
 
 #endif /* __BLUETOOTH_H */
diff --git a/include/net/ieee80211.h b/include/net/ieee80211.h
new file mode 100644
--- /dev/null
+++ b/include/net/ieee80211.h
@@ -0,0 +1,856 @@
+/*
+ * Merged with mainline ieee80211.h in Aug 2004.  Original ieee802_11
+ * remains copyright by the original authors
+ *
+ * Portions of the merged code are based on Host AP (software wireless
+ * LAN access point) driver for Intersil Prism2/2.5/3.
+ *
+ * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
+ * <jkmaline@cc.hut.fi>
+ * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
+ *
+ * Adaption to a generic IEEE 802.11 stack by James Ketrenos
+ * <jketreno@linux.intel.com>
+ * Copyright (c) 2004, Intel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation. See README and COPYING for
+ * more details.
+ */
+#ifndef IEEE80211_H
+#define IEEE80211_H
+
+#include <linux/if_ether.h> /* ETH_ALEN */
+#include <linux/kernel.h>   /* ARRAY_SIZE */
+
+#if WIRELESS_EXT < 17
+#define IW_QUAL_QUAL_INVALID   0x10
+#define IW_QUAL_LEVEL_INVALID  0x20
+#define IW_QUAL_NOISE_INVALID  0x40
+#define IW_QUAL_QUAL_UPDATED   0x1
+#define IW_QUAL_LEVEL_UPDATED  0x2
+#define IW_QUAL_NOISE_UPDATED  0x4
+#endif
+
+#define IEEE80211_DATA_LEN		2304
+/* Maximum size for the MA-UNITDATA primitive, 802.11 standard section
+   6.2.1.1.2.
+
+   The figure in section 7.1.2 suggests a body size of up to 2312
+   bytes is allowed, which is a bit confusing, I suspect this
+   represents the 2304 bytes of real data, plus a possible 8 bytes of
+   WEP IV and ICV. (this interpretation suggested by Ramiro Barreiro) */
+
+
+#define IEEE80211_HLEN			30
+#define IEEE80211_FRAME_LEN		(IEEE80211_DATA_LEN + IEEE80211_HLEN)
+
+struct ieee80211_hdr {
+	u16 frame_ctl;
+	u16 duration_id;
+	u8 addr1[ETH_ALEN];
+	u8 addr2[ETH_ALEN];
+	u8 addr3[ETH_ALEN];
+	u16 seq_ctl;
+	u8 addr4[ETH_ALEN];
+} __attribute__ ((packed));
+
+struct ieee80211_hdr_3addr {
+	u16 frame_ctl;
+	u16 duration_id;
+	u8 addr1[ETH_ALEN];
+	u8 addr2[ETH_ALEN];
+	u8 addr3[ETH_ALEN];
+	u16 seq_ctl;
+} __attribute__ ((packed));
+
+enum eap_type {
+	EAP_PACKET = 0,
+	EAPOL_START,
+	EAPOL_LOGOFF,
+	EAPOL_KEY,
+	EAPOL_ENCAP_ASF_ALERT
+};
+
+static const char *eap_types[] = {
+	[EAP_PACKET]		= "EAP-Packet",
+	[EAPOL_START]		= "EAPOL-Start",
+	[EAPOL_LOGOFF]		= "EAPOL-Logoff",
+	[EAPOL_KEY]		= "EAPOL-Key",
+	[EAPOL_ENCAP_ASF_ALERT]	= "EAPOL-Encap-ASF-Alert"
+};
+
+static inline const char *eap_get_type(int type)
+{
+	return (type >= ARRAY_SIZE(eap_types)) ? "Unknown" : eap_types[type];
+}
+
+struct eapol {
+	u8 snap[6];
+	u16 ethertype;
+	u8 version;
+	u8 type;
+	u16 length;
+} __attribute__ ((packed));
+
+#define IEEE80211_1ADDR_LEN 10
+#define IEEE80211_2ADDR_LEN 16
+#define IEEE80211_3ADDR_LEN 24
+#define IEEE80211_4ADDR_LEN 30
+#define IEEE80211_FCS_LEN    4
+
+#define MIN_FRAG_THRESHOLD     256U
+#define	MAX_FRAG_THRESHOLD     2346U
+
+/* Frame control field constants */
+#define IEEE80211_FCTL_VERS		0x0002
+#define IEEE80211_FCTL_FTYPE		0x000c
+#define IEEE80211_FCTL_STYPE		0x00f0
+#define IEEE80211_FCTL_TODS		0x0100
+#define IEEE80211_FCTL_FROMDS		0x0200
+#define IEEE80211_FCTL_MOREFRAGS	0x0400
+#define IEEE80211_FCTL_RETRY		0x0800
+#define IEEE80211_FCTL_PM		0x1000
+#define IEEE80211_FCTL_MOREDATA	0x2000
+#define IEEE80211_FCTL_WEP		0x4000
+#define IEEE80211_FCTL_ORDER		0x8000
+
+#define IEEE80211_FTYPE_MGMT		0x0000
+#define IEEE80211_FTYPE_CTL		0x0004
+#define IEEE80211_FTYPE_DATA		0x0008
+
+/* management */
+#define IEEE80211_STYPE_ASSOC_REQ	0x0000
+#define IEEE80211_STYPE_ASSOC_RESP 	0x0010
+#define IEEE80211_STYPE_REASSOC_REQ	0x0020
+#define IEEE80211_STYPE_REASSOC_RESP	0x0030
+#define IEEE80211_STYPE_PROBE_REQ	0x0040
+#define IEEE80211_STYPE_PROBE_RESP	0x0050
+#define IEEE80211_STYPE_BEACON		0x0080
+#define IEEE80211_STYPE_ATIM		0x0090
+#define IEEE80211_STYPE_DISASSOC	0x00A0
+#define IEEE80211_STYPE_AUTH		0x00B0
+#define IEEE80211_STYPE_DEAUTH		0x00C0
+
+/* control */
+#define IEEE80211_STYPE_PSPOLL		0x00A0
+#define IEEE80211_STYPE_RTS		0x00B0
+#define IEEE80211_STYPE_CTS		0x00C0
+#define IEEE80211_STYPE_ACK		0x00D0
+#define IEEE80211_STYPE_CFEND		0x00E0
+#define IEEE80211_STYPE_CFENDACK	0x00F0
+
+/* data */
+#define IEEE80211_STYPE_DATA		0x0000
+#define IEEE80211_STYPE_DATA_CFACK	0x0010
+#define IEEE80211_STYPE_DATA_CFPOLL	0x0020
+#define IEEE80211_STYPE_DATA_CFACKPOLL	0x0030
+#define IEEE80211_STYPE_NULLFUNC	0x0040
+#define IEEE80211_STYPE_CFACK		0x0050
+#define IEEE80211_STYPE_CFPOLL		0x0060
+#define IEEE80211_STYPE_CFACKPOLL	0x0070
+
+#define IEEE80211_SCTL_FRAG		0x000F
+#define IEEE80211_SCTL_SEQ		0xFFF0
+
+
+/* debug macros */
+
+#ifdef CONFIG_IEEE80211_DEBUG
+extern u32 ieee80211_debug_level;
+#define IEEE80211_DEBUG(level, fmt, args...) \
+do { if (ieee80211_debug_level & (level)) \
+  printk(KERN_DEBUG "ieee80211: %c %s " fmt, \
+         in_interrupt() ? 'I' : 'U', __FUNCTION__ , ## args); } while (0)
+#else
+#define IEEE80211_DEBUG(level, fmt, args...) do {} while (0)
+#endif	/* CONFIG_IEEE80211_DEBUG */
+
+/*
+ * To use the debug system;
+ *
+ * If you are defining a new debug classification, simply add it to the #define
+ * list here in the form of:
+ *
+ * #define IEEE80211_DL_xxxx VALUE
+ *
+ * shifting value to the left one bit from the previous entry.  xxxx should be
+ * the name of the classification (for example, WEP)
+ *
+ * You then need to either add a IEEE80211_xxxx_DEBUG() macro definition for your
+ * classification, or use IEEE80211_DEBUG(IEEE80211_DL_xxxx, ...) whenever you want
+ * to send output to that classification.
+ *
+ * To add your debug level to the list of levels seen when you perform
+ *
+ * % cat /proc/net/ipw/debug_level
+ *
+ * you simply need to add your entry to the ipw_debug_levels array.
+ *
+ * If you do not see debug_level in /proc/net/ipw then you do not have
+ * CONFIG_IEEE80211_DEBUG defined in your kernel configuration
+ *
+ */
+
+#define IEEE80211_DL_INFO          (1<<0)
+#define IEEE80211_DL_WX            (1<<1)
+#define IEEE80211_DL_SCAN          (1<<2)
+#define IEEE80211_DL_STATE         (1<<3)
+#define IEEE80211_DL_MGMT          (1<<4)
+#define IEEE80211_DL_FRAG          (1<<5)
+#define IEEE80211_DL_EAP           (1<<6)
+#define IEEE80211_DL_DROP          (1<<7)
+
+#define IEEE80211_DL_TX            (1<<8)
+#define IEEE80211_DL_RX            (1<<9)
+
+#define IEEE80211_ERROR(f, a...) printk(KERN_ERR "ieee80211: " f, ## a)
+#define IEEE80211_WARNING(f, a...) printk(KERN_WARNING "ieee80211: " f, ## a)
+#define IEEE80211_DEBUG_INFO(f, a...)   IEEE80211_DEBUG(IEEE80211_DL_INFO, f, ## a)
+
+#define IEEE80211_DEBUG_WX(f, a...)     IEEE80211_DEBUG(IEEE80211_DL_WX, f, ## a)
+#define IEEE80211_DEBUG_SCAN(f, a...)   IEEE80211_DEBUG(IEEE80211_DL_SCAN, f, ## a)
+#define IEEE80211_DEBUG_STATE(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_STATE, f, ## a)
+#define IEEE80211_DEBUG_MGMT(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_MGMT, f, ## a)
+#define IEEE80211_DEBUG_FRAG(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_FRAG, f, ## a)
+#define IEEE80211_DEBUG_EAP(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_EAP, f, ## a)
+#define IEEE80211_DEBUG_DROP(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_DROP, f, ## a)
+#define IEEE80211_DEBUG_TX(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_TX, f, ## a)
+#define IEEE80211_DEBUG_RX(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_RX, f, ## a)
+#include <linux/netdevice.h>
+#include <linux/wireless.h>
+#include <linux/if_arp.h> /* ARPHRD_ETHER */
+
+#ifndef WIRELESS_SPY
+#define WIRELESS_SPY		// enable iwspy support
+#endif
+#include <net/iw_handler.h>	// new driver API
+
+#ifndef ETH_P_PAE
+#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */
+#endif /* ETH_P_PAE */
+
+#define ETH_P_PREAUTH 0x88C7 /* IEEE 802.11i pre-authentication */
+
+#ifndef ETH_P_80211_RAW
+#define ETH_P_80211_RAW (ETH_P_ECONET + 1)
+#endif
+
+/* IEEE 802.11 defines */
+
+#define P80211_OUI_LEN 3
+
+struct ieee80211_snap_hdr {
+
+        u8    dsap;   /* always 0xAA */
+        u8    ssap;   /* always 0xAA */
+        u8    ctrl;   /* always 0x03 */
+        u8    oui[P80211_OUI_LEN];    /* organizational universal id */
+
+} __attribute__ ((packed));
+
+#define SNAP_SIZE sizeof(struct ieee80211_snap_hdr)
+
+#define WLAN_FC_GET_TYPE(fc) ((fc) & IEEE80211_FCTL_FTYPE)
+#define WLAN_FC_GET_STYPE(fc) ((fc) & IEEE80211_FCTL_STYPE)
+
+#define WLAN_GET_SEQ_FRAG(seq) ((seq) & IEEE80211_SCTL_FRAG)
+#define WLAN_GET_SEQ_SEQ(seq)  ((seq) & IEEE80211_SCTL_SEQ)
+
+/* Authentication algorithms */
+#define WLAN_AUTH_OPEN 0
+#define WLAN_AUTH_SHARED_KEY 1
+
+#define WLAN_AUTH_CHALLENGE_LEN 128
+
+#define WLAN_CAPABILITY_BSS (1<<0)
+#define WLAN_CAPABILITY_IBSS (1<<1)
+#define WLAN_CAPABILITY_CF_POLLABLE (1<<2)
+#define WLAN_CAPABILITY_CF_POLL_REQUEST (1<<3)
+#define WLAN_CAPABILITY_PRIVACY (1<<4)
+#define WLAN_CAPABILITY_SHORT_PREAMBLE (1<<5)
+#define WLAN_CAPABILITY_PBCC (1<<6)
+#define WLAN_CAPABILITY_CHANNEL_AGILITY (1<<7)
+
+/* Status codes */
+#define WLAN_STATUS_SUCCESS 0
+#define WLAN_STATUS_UNSPECIFIED_FAILURE 1
+#define WLAN_STATUS_CAPS_UNSUPPORTED 10
+#define WLAN_STATUS_REASSOC_NO_ASSOC 11
+#define WLAN_STATUS_ASSOC_DENIED_UNSPEC 12
+#define WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG 13
+#define WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION 14
+#define WLAN_STATUS_CHALLENGE_FAIL 15
+#define WLAN_STATUS_AUTH_TIMEOUT 16
+#define WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA 17
+#define WLAN_STATUS_ASSOC_DENIED_RATES 18
+/* 802.11b */
+#define WLAN_STATUS_ASSOC_DENIED_NOSHORT 19
+#define WLAN_STATUS_ASSOC_DENIED_NOPBCC 20
+#define WLAN_STATUS_ASSOC_DENIED_NOAGILITY 21
+
+/* Reason codes */
+#define WLAN_REASON_UNSPECIFIED 1
+#define WLAN_REASON_PREV_AUTH_NOT_VALID 2
+#define WLAN_REASON_DEAUTH_LEAVING 3
+#define WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY 4
+#define WLAN_REASON_DISASSOC_AP_BUSY 5
+#define WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA 6
+#define WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA 7
+#define WLAN_REASON_DISASSOC_STA_HAS_LEFT 8
+#define WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH 9
+
+
+#define IEEE80211_STATMASK_SIGNAL (1<<0)
+#define IEEE80211_STATMASK_RSSI (1<<1)
+#define IEEE80211_STATMASK_NOISE (1<<2)
+#define IEEE80211_STATMASK_RATE (1<<3)
+#define IEEE80211_STATMASK_WEMASK 0x7
+
+
+#define IEEE80211_CCK_MODULATION    (1<<0)
+#define IEEE80211_OFDM_MODULATION   (1<<1)
+
+#define IEEE80211_24GHZ_BAND     (1<<0)
+#define IEEE80211_52GHZ_BAND     (1<<1)
+
+#define IEEE80211_CCK_RATE_1MB		        0x02
+#define IEEE80211_CCK_RATE_2MB		        0x04
+#define IEEE80211_CCK_RATE_5MB		        0x0B
+#define IEEE80211_CCK_RATE_11MB		        0x16
+#define IEEE80211_OFDM_RATE_6MB		        0x0C
+#define IEEE80211_OFDM_RATE_9MB		        0x12
+#define IEEE80211_OFDM_RATE_12MB		0x18
+#define IEEE80211_OFDM_RATE_18MB		0x24
+#define IEEE80211_OFDM_RATE_24MB		0x30
+#define IEEE80211_OFDM_RATE_36MB		0x48
+#define IEEE80211_OFDM_RATE_48MB		0x60
+#define IEEE80211_OFDM_RATE_54MB		0x6C
+#define IEEE80211_BASIC_RATE_MASK		0x80
+
+#define IEEE80211_CCK_RATE_1MB_MASK		(1<<0)
+#define IEEE80211_CCK_RATE_2MB_MASK		(1<<1)
+#define IEEE80211_CCK_RATE_5MB_MASK		(1<<2)
+#define IEEE80211_CCK_RATE_11MB_MASK		(1<<3)
+#define IEEE80211_OFDM_RATE_6MB_MASK		(1<<4)
+#define IEEE80211_OFDM_RATE_9MB_MASK		(1<<5)
+#define IEEE80211_OFDM_RATE_12MB_MASK		(1<<6)
+#define IEEE80211_OFDM_RATE_18MB_MASK		(1<<7)
+#define IEEE80211_OFDM_RATE_24MB_MASK		(1<<8)
+#define IEEE80211_OFDM_RATE_36MB_MASK		(1<<9)
+#define IEEE80211_OFDM_RATE_48MB_MASK		(1<<10)
+#define IEEE80211_OFDM_RATE_54MB_MASK		(1<<11)
+
+#define IEEE80211_CCK_RATES_MASK	        0x0000000F
+#define IEEE80211_CCK_BASIC_RATES_MASK	(IEEE80211_CCK_RATE_1MB_MASK | \
+	IEEE80211_CCK_RATE_2MB_MASK)
+#define IEEE80211_CCK_DEFAULT_RATES_MASK	(IEEE80211_CCK_BASIC_RATES_MASK | \
+        IEEE80211_CCK_RATE_5MB_MASK | \
+        IEEE80211_CCK_RATE_11MB_MASK)
+
+#define IEEE80211_OFDM_RATES_MASK		0x00000FF0
+#define IEEE80211_OFDM_BASIC_RATES_MASK	(IEEE80211_OFDM_RATE_6MB_MASK | \
+	IEEE80211_OFDM_RATE_12MB_MASK | \
+	IEEE80211_OFDM_RATE_24MB_MASK)
+#define IEEE80211_OFDM_DEFAULT_RATES_MASK	(IEEE80211_OFDM_BASIC_RATES_MASK | \
+	IEEE80211_OFDM_RATE_9MB_MASK  | \
+	IEEE80211_OFDM_RATE_18MB_MASK | \
+	IEEE80211_OFDM_RATE_36MB_MASK | \
+	IEEE80211_OFDM_RATE_48MB_MASK | \
+	IEEE80211_OFDM_RATE_54MB_MASK)
+#define IEEE80211_DEFAULT_RATES_MASK (IEEE80211_OFDM_DEFAULT_RATES_MASK | \
+                                IEEE80211_CCK_DEFAULT_RATES_MASK)
+
+#define IEEE80211_NUM_OFDM_RATES	    8
+#define IEEE80211_NUM_CCK_RATES	            4
+#define IEEE80211_OFDM_SHIFT_MASK_A         4
+
+
+
+
+/* NOTE: This data is for statistical purposes; not all hardware provides this
+ *       information for frames received.  Not setting these will not cause
+ *       any adverse affects. */
+struct ieee80211_rx_stats {
+	u32 mac_time;
+	s8 rssi;
+	u8 signal;
+	u8 noise;
+	u16 rate; /* in 100 kbps */
+	u8 received_channel;
+	u8 control;
+	u8 mask;
+	u8 freq;
+	u16 len;
+};
+
+/* IEEE 802.11 requires that STA supports concurrent reception of at least
+ * three fragmented frames. This define can be increased to support more
+ * concurrent frames, but it should be noted that each entry can consume about
+ * 2 kB of RAM and increasing cache size will slow down frame reassembly. */
+#define IEEE80211_FRAG_CACHE_LEN 4
+
+struct ieee80211_frag_entry {
+	unsigned long first_frag_time;
+	unsigned int seq;
+	unsigned int last_frag;
+	struct sk_buff *skb;
+	u8 src_addr[ETH_ALEN];
+	u8 dst_addr[ETH_ALEN];
+};
+
+struct ieee80211_stats {
+	unsigned int tx_unicast_frames;
+	unsigned int tx_multicast_frames;
+	unsigned int tx_fragments;
+	unsigned int tx_unicast_octets;
+	unsigned int tx_multicast_octets;
+	unsigned int tx_deferred_transmissions;
+	unsigned int tx_single_retry_frames;
+	unsigned int tx_multiple_retry_frames;
+	unsigned int tx_retry_limit_exceeded;
+	unsigned int tx_discards;
+	unsigned int rx_unicast_frames;
+	unsigned int rx_multicast_frames;
+	unsigned int rx_fragments;
+	unsigned int rx_unicast_octets;
+	unsigned int rx_multicast_octets;
+	unsigned int rx_fcs_errors;
+	unsigned int rx_discards_no_buffer;
+	unsigned int tx_discards_wrong_sa;
+	unsigned int rx_discards_undecryptable;
+	unsigned int rx_message_in_msg_fragments;
+	unsigned int rx_message_in_bad_msg_fragments;
+};
+
+struct ieee80211_device;
+
+#if 0 /* for later */
+#include "ieee80211_crypt.h"
+#endif
+
+#define SEC_KEY_1         (1<<0)
+#define SEC_KEY_2         (1<<1)
+#define SEC_KEY_3         (1<<2)
+#define SEC_KEY_4         (1<<3)
+#define SEC_ACTIVE_KEY    (1<<4)
+#define SEC_AUTH_MODE     (1<<5)
+#define SEC_UNICAST_GROUP (1<<6)
+#define SEC_LEVEL         (1<<7)
+#define SEC_ENABLED       (1<<8)
+
+#define SEC_LEVEL_0      0 /* None */
+#define SEC_LEVEL_1      1 /* WEP 40 and 104 bit */
+#define SEC_LEVEL_2      2 /* Level 1 + TKIP */
+#define SEC_LEVEL_2_CKIP 3 /* Level 1 + CKIP */
+#define SEC_LEVEL_3      4 /* Level 2 + CCMP */
+
+#define WEP_KEYS 4
+#define WEP_KEY_LEN 13
+
+struct ieee80211_security {
+	u16 active_key:2,
+            enabled:1,
+	    auth_mode:2,
+            auth_algo:4,
+            unicast_uses_group:1;
+	u8 key_sizes[WEP_KEYS];
+	u8 keys[WEP_KEYS][WEP_KEY_LEN];
+	u8 level;
+	u16 flags;
+} __attribute__ ((packed));
+
+
+/*
+
+ 802.11 data frame from AP
+
+      ,-------------------------------------------------------------------.
+Bytes |  2   |  2   |    6    |    6    |    6    |  2   | 0..2312 |   4  |
+      |------|------|---------|---------|---------|------|---------|------|
+Desc. | ctrl | dura |  DA/RA  |   TA    |    SA   | Sequ |  frame  |  fcs |
+      |      | tion | (BSSID) |         |         | ence |  data   |      |
+      `-------------------------------------------------------------------'
+
+Total: 28-2340 bytes
+
+*/
+
+#define BEACON_PROBE_SSID_ID_POSITION 12
+
+/* Management Frame Information Element Types */
+#define MFIE_TYPE_SSID       0
+#define MFIE_TYPE_RATES      1
+#define MFIE_TYPE_FH_SET     2
+#define MFIE_TYPE_DS_SET     3
+#define MFIE_TYPE_CF_SET     4
+#define MFIE_TYPE_TIM        5
+#define MFIE_TYPE_IBSS_SET   6
+#define MFIE_TYPE_CHALLENGE  16
+#define MFIE_TYPE_RSN	     48
+#define MFIE_TYPE_RATES_EX   50
+#define MFIE_TYPE_GENERIC    221
+
+struct ieee80211_info_element_hdr {
+	u8 id;
+	u8 len;
+} __attribute__ ((packed));
+
+struct ieee80211_info_element {
+	u8 id;
+	u8 len;
+	u8 data[0];
+} __attribute__ ((packed));
+
+/*
+ * These are the data types that can make up management packets
+ *
+	u16 auth_algorithm;
+	u16 auth_sequence;
+	u16 beacon_interval;
+	u16 capability;
+	u8 current_ap[ETH_ALEN];
+	u16 listen_interval;
+	struct {
+		u16 association_id:14, reserved:2;
+	} __attribute__ ((packed));
+	u32 time_stamp[2];
+	u16 reason;
+	u16 status;
+*/
+
+struct ieee80211_authentication {
+	struct ieee80211_hdr_3addr header;
+	u16 algorithm;
+	u16 transaction;
+	u16 status;
+	struct ieee80211_info_element info_element;
+} __attribute__ ((packed));
+
+
+struct ieee80211_probe_response {
+	struct ieee80211_hdr_3addr header;
+	u32 time_stamp[2];
+	u16 beacon_interval;
+	u16 capability;
+	struct ieee80211_info_element info_element;
+} __attribute__ ((packed));
+
+struct ieee80211_assoc_request_frame {
+	u16 capability;
+	u16 listen_interval;
+	u8 current_ap[ETH_ALEN];
+	struct ieee80211_info_element info_element;
+} __attribute__ ((packed));
+
+struct ieee80211_assoc_response_frame {
+	struct ieee80211_hdr_3addr header;
+	u16 capability;
+	u16 status;
+	u16 aid;
+	struct ieee80211_info_element info_element; /* supported rates */
+} __attribute__ ((packed));
+
+
+struct ieee80211_txb {
+	u8 nr_frags;
+	u8 encrypted;
+	u16 reserved;
+	u16 frag_size;
+	u16 payload_size;
+	struct sk_buff *fragments[0];
+};
+
+
+/* SWEEP TABLE ENTRIES NUMBER*/
+#define MAX_SWEEP_TAB_ENTRIES		  42
+#define MAX_SWEEP_TAB_ENTRIES_PER_PACKET  7
+/* MAX_RATES_LENGTH needs to be 12.  The spec says 8, and many APs
+ * only use 8, and then use extended rates for the remaining supported
+ * rates.  Other APs, however, stick all of their supported rates on the
+ * main rates information element... */
+#define MAX_RATES_LENGTH                  ((u8)12)
+#define MAX_RATES_EX_LENGTH               ((u8)16)
+#define MAX_NETWORK_COUNT                  128
+
+#define CRC_LENGTH                 4U
+
+#define MAX_WPA_IE_LEN 64
+
+#define NETWORK_EMPTY_ESSID (1<<0)
+#define NETWORK_HAS_OFDM    (1<<1)
+#define NETWORK_HAS_CCK     (1<<2)
+
+struct ieee80211_network {
+	/* These entries are used to identify a unique network */
+	u8 bssid[ETH_ALEN];
+	u8 channel;
+	/* Ensure null-terminated for any debug msgs */
+	u8 ssid[IW_ESSID_MAX_SIZE + 1];
+	u8 ssid_len;
+
+	/* These are network statistics */
+	struct ieee80211_rx_stats stats;
+	u16 capability;
+	u8 rates[MAX_RATES_LENGTH];
+	u8 rates_len;
+	u8 rates_ex[MAX_RATES_EX_LENGTH];
+	u8 rates_ex_len;
+	unsigned long last_scanned;
+	u8 mode;
+	u8 flags;
+	u32 last_associate;
+	u32 time_stamp[2];
+	u16 beacon_interval;
+	u16 listen_interval;
+	u16 atim_window;
+	u8 wpa_ie[MAX_WPA_IE_LEN];
+	size_t wpa_ie_len;
+	u8 rsn_ie[MAX_WPA_IE_LEN];
+	size_t rsn_ie_len;
+	struct list_head list;
+};
+
+enum ieee80211_state {
+	IEEE80211_UNINITIALIZED = 0,
+	IEEE80211_INITIALIZED,
+	IEEE80211_ASSOCIATING,
+	IEEE80211_ASSOCIATED,
+	IEEE80211_AUTHENTICATING,
+	IEEE80211_AUTHENTICATED,
+	IEEE80211_SHUTDOWN
+};
+
+#define DEFAULT_MAX_SCAN_AGE (15 * HZ)
+#define DEFAULT_FTS 2346
+#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
+#define MAC_ARG(x) ((u8*)(x))[0],((u8*)(x))[1],((u8*)(x))[2],((u8*)(x))[3],((u8*)(x))[4],((u8*)(x))[5]
+
+
+#define CFG_IEEE80211_RESERVE_FCS (1<<0)
+#define CFG_IEEE80211_COMPUTE_FCS (1<<1)
+
+struct ieee80211_device {
+	struct net_device *dev;
+
+	/* Bookkeeping structures */
+	struct net_device_stats stats;
+	struct ieee80211_stats ieee_stats;
+
+	/* Probe / Beacon management */
+	struct list_head network_free_list;
+	struct list_head network_list;
+	struct ieee80211_network *networks;
+	int scans;
+	int scan_age;
+
+	int iw_mode; /* operating mode (IW_MODE_*) */
+
+	spinlock_t lock;
+
+	int tx_headroom; /* Set to size of any additional room needed at front
+			  * of allocated Tx SKBs */
+	u32 config;
+
+	/* WEP and other encryption related settings at the device level */
+	int open_wep; /* Set to 1 to allow unencrypted frames */
+
+	int reset_on_keychange; /* Set to 1 if the HW needs to be reset on
+				 * WEP key changes */
+
+	/* If the host performs {en,de}cryption, then set to 1 */
+	int host_encrypt;
+	int host_decrypt;
+	int ieee802_1x; /* is IEEE 802.1X used */
+
+	/* WPA data */
+	int wpa_enabled;
+	int drop_unencrypted;
+	int tkip_countermeasures;
+	int privacy_invoked;
+	size_t wpa_ie_len;
+	u8 *wpa_ie;
+
+	struct list_head crypt_deinit_list;
+	struct ieee80211_crypt_data *crypt[WEP_KEYS];
+	int tx_keyidx; /* default TX key index (crypt[tx_keyidx]) */
+	struct timer_list crypt_deinit_timer;
+
+	int bcrx_sta_key; /* use individual keys to override default keys even
+			   * with RX of broad/multicast frames */
+
+	/* Fragmentation structures */
+	struct ieee80211_frag_entry frag_cache[IEEE80211_FRAG_CACHE_LEN];
+	unsigned int frag_next_idx;
+	u16 fts; /* Fragmentation Threshold */
+
+	/* Association info */
+	u8 bssid[ETH_ALEN];
+
+	enum ieee80211_state state;
+
+	int mode;       /* A, B, G */
+	int modulation; /* CCK, OFDM */
+	int freq_band;  /* 2.4Ghz, 5.2Ghz, Mixed */
+	int abg_ture;   /* ABG flag              */
+
+	/* Callback functions */
+	void (*set_security)(struct net_device *dev,
+			     struct ieee80211_security *sec);
+	int (*hard_start_xmit)(struct ieee80211_txb *txb,
+			       struct net_device *dev);
+	int (*reset_port)(struct net_device *dev);
+
+	/* This must be the last item so that it points to the data
+	 * allocated beyond this structure by alloc_ieee80211 */
+	u8 priv[0];
+};
+
+#define IEEE_A            (1<<0)
+#define IEEE_B            (1<<1)
+#define IEEE_G            (1<<2)
+#define IEEE_MODE_MASK    (IEEE_A|IEEE_B|IEEE_G)
+
+extern inline void *ieee80211_priv(struct net_device *dev)
+{
+	return ((struct ieee80211_device *)netdev_priv(dev))->priv;
+}
+
+extern inline int ieee80211_is_empty_essid(const char *essid, int essid_len)
+{
+	/* Single white space is for Linksys APs */
+	if (essid_len == 1 && essid[0] == ' ')
+		return 1;
+
+	/* Otherwise, if the entire essid is 0, we assume it is hidden */
+	while (essid_len) {
+		essid_len--;
+		if (essid[essid_len] != '\0')
+			return 0;
+	}
+
+	return 1;
+}
+
+extern inline int ieee80211_is_valid_mode(struct ieee80211_device *ieee, int mode)
+{
+	/*
+	 * It is possible for both access points and our device to support
+	 * combinations of modes, so as long as there is one valid combination
+	 * of ap/device supported modes, then return success
+	 *
+	 */
+	if ((mode & IEEE_A) &&
+	    (ieee->modulation & IEEE80211_OFDM_MODULATION) &&
+	    (ieee->freq_band & IEEE80211_52GHZ_BAND))
+		return 1;
+
+	if ((mode & IEEE_G) &&
+	    (ieee->modulation & IEEE80211_OFDM_MODULATION) &&
+	    (ieee->freq_band & IEEE80211_24GHZ_BAND))
+		return 1;
+
+	if ((mode & IEEE_B) &&
+	    (ieee->modulation & IEEE80211_CCK_MODULATION) &&
+	    (ieee->freq_band & IEEE80211_24GHZ_BAND))
+		return 1;
+
+	return 0;
+}
+
+extern inline int ieee80211_get_hdrlen(u16 fc)
+{
+	int hdrlen = IEEE80211_3ADDR_LEN;
+
+	switch (WLAN_FC_GET_TYPE(fc)) {
+	case IEEE80211_FTYPE_DATA:
+		if ((fc & IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS))
+			hdrlen = IEEE80211_4ADDR_LEN;
+		break;
+	case IEEE80211_FTYPE_CTL:
+		switch (WLAN_FC_GET_STYPE(fc)) {
+		case IEEE80211_STYPE_CTS:
+		case IEEE80211_STYPE_ACK:
+			hdrlen = IEEE80211_1ADDR_LEN;
+			break;
+		default:
+			hdrlen = IEEE80211_2ADDR_LEN;
+			break;
+		}
+		break;
+	}
+
+	return hdrlen;
+}
+
+
+
+/* ieee80211.c */
+extern void free_ieee80211(struct net_device *dev);
+extern struct net_device *alloc_ieee80211(int sizeof_priv);
+
+extern int ieee80211_set_encryption(struct ieee80211_device *ieee);
+
+/* ieee80211_tx.c */
+
+
+extern int ieee80211_xmit(struct sk_buff *skb,
+			  struct net_device *dev);
+extern void ieee80211_txb_free(struct ieee80211_txb *);
+
+
+/* ieee80211_rx.c */
+extern int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
+			struct ieee80211_rx_stats *rx_stats);
+extern void ieee80211_rx_mgt(struct ieee80211_device *ieee,
+			     struct ieee80211_hdr *header,
+			     struct ieee80211_rx_stats *stats);
+
+/* iee80211_wx.c */
+extern int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
+				 struct iw_request_info *info,
+				 union iwreq_data *wrqu, char *key);
+extern int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
+				   struct iw_request_info *info,
+				   union iwreq_data *wrqu, char *key);
+extern int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
+				   struct iw_request_info *info,
+				   union iwreq_data *wrqu, char *key);
+
+
+extern inline void ieee80211_increment_scans(struct ieee80211_device *ieee)
+{
+	ieee->scans++;
+}
+
+extern inline int ieee80211_get_scans(struct ieee80211_device *ieee)
+{
+	return ieee->scans;
+}
+
+static inline const char *escape_essid(const char *essid, u8 essid_len) {
+	static char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
+	const char *s = essid;
+	char *d = escaped;
+
+	if (ieee80211_is_empty_essid(essid, essid_len)) {
+		memcpy(escaped, "<hidden>", sizeof("<hidden>"));
+		return escaped;
+	}
+
+	essid_len = min(essid_len, (u8)IW_ESSID_MAX_SIZE);
+	while (essid_len--) {
+		if (*s == '\0') {
+			*d++ = '\\';
+			*d++ = '0';
+			s++;
+		} else {
+			*d++ = *s++;
+		}
+	}
+	*d = '\0';
+	return escaped;
+}
+
+#endif /* IEEE80211_H */
diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h
--- a/include/net/ip6_fib.h
+++ b/include/net/ip6_fib.h
@@ -167,14 +167,17 @@ extern int			fib6_walk_continue(struct f
 extern int			fib6_add(struct fib6_node *root,
 					 struct rt6_info *rt,
 					 struct nlmsghdr *nlh,
-					 void *rtattr);
+					 void *rtattr,
+					 struct netlink_skb_parms *req);
 
 extern int			fib6_del(struct rt6_info *rt,
 					 struct nlmsghdr *nlh,
-					 void *rtattr);
+					 void *rtattr,
+					 struct netlink_skb_parms *req);
 
 extern void			inet6_rt_notify(int event, struct rt6_info *rt,
-						struct nlmsghdr *nlh);
+						struct nlmsghdr *nlh,
+						struct netlink_skb_parms *req);
 
 extern void			fib6_run_gc(unsigned long dummy);
 
diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h
--- a/include/net/ip6_route.h
+++ b/include/net/ip6_route.h
@@ -41,13 +41,16 @@ extern int			ipv6_route_ioctl(unsigned i
 
 extern int			ip6_route_add(struct in6_rtmsg *rtmsg,
 					      struct nlmsghdr *,
-					      void *rtattr);
+					      void *rtattr,
+					      struct netlink_skb_parms *req);
 extern int			ip6_ins_rt(struct rt6_info *,
 					   struct nlmsghdr *,
-					   void *rtattr);
+					   void *rtattr,
+					   struct netlink_skb_parms *req);
 extern int			ip6_del_rt(struct rt6_info *,
 					   struct nlmsghdr *,
-					   void *rtattr);
+					   void *rtattr,
+					   struct netlink_skb_parms *req);
 
 extern int			ip6_rt_addr_add(struct in6_addr *addr,
 						struct net_device *dev,
diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h
--- a/include/net/ip_fib.h
+++ b/include/net/ip_fib.h
@@ -109,6 +109,20 @@ struct fib_result {
 #endif
 };
 
+struct fib_result_nl {
+	u32		fl_addr;   /* To be looked up*/ 
+	u32		fl_fwmark; 
+	unsigned char	fl_tos;
+	unsigned char   fl_scope;
+	unsigned char   tb_id_in;
+
+	unsigned char   tb_id;      /* Results */
+	unsigned char	prefixlen;
+	unsigned char	nh_sel;
+	unsigned char	type;
+	unsigned char	scope;
+	int             err;      
+};
 
 #ifdef CONFIG_IP_ROUTE_MULTIPATH
 
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -183,7 +183,6 @@ struct ipv6_txoptions
 	struct ipv6_opt_hdr	*hopopt;
 	struct ipv6_opt_hdr	*dst0opt;
 	struct ipv6_rt_hdr	*srcrt;	/* Routing Header */
-	struct ipv6_opt_hdr	*auth;
 	struct ipv6_opt_hdr	*dst1opt;
 
 	/* Option buffer, as read by IPV6_PKTOPTIONS, starts here. */
diff --git a/include/net/irda/irda_device.h b/include/net/irda/irda_device.h
--- a/include/net/irda/irda_device.h
+++ b/include/net/irda/irda_device.h
@@ -224,7 +224,7 @@ int  irda_device_is_receiving(struct net
 /* Interface for internal use */
 static inline int irda_device_txqueue_empty(const struct net_device *dev)
 {
-	return (skb_queue_len(&dev->qdisc->q) == 0);
+	return skb_queue_empty(&dev->qdisc->q);
 }
 int  irda_device_set_raw_mode(struct net_device* self, int status);
 struct net_device *alloc_irdadev(int sizeof_priv);
diff --git a/include/net/neighbour.h b/include/net/neighbour.h
--- a/include/net/neighbour.h
+++ b/include/net/neighbour.h
@@ -65,11 +65,10 @@ struct neighbour;
 
 struct neigh_parms
 {
+	struct net_device *dev;
 	struct neigh_parms *next;
 	int	(*neigh_setup)(struct neighbour *);
 	struct neigh_table *tbl;
-	int	entries;
-	void	*priv;
 
 	void	*sysctl_table;
 
@@ -192,7 +191,6 @@ struct neigh_table
 	atomic_t		entries;
 	rwlock_t		lock;
 	unsigned long		last_rand;
-	struct neigh_parms	*parms_list;
 	kmem_cache_t		*kmem_cachep;
 	struct neigh_statistics	*stats;
 	struct neighbour	**hash_buckets;
@@ -252,6 +250,9 @@ extern int neigh_add(struct sk_buff *skb
 extern int neigh_delete(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg);
 extern void neigh_app_ns(struct neighbour *n);
 
+extern int neightbl_dump_info(struct sk_buff *skb, struct netlink_callback *cb);
+extern int neightbl_set(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg);
+
 extern void neigh_for_each(struct neigh_table *tbl, void (*cb)(struct neighbour *, void *), void *cookie);
 extern void __neigh_for_each_release(struct neigh_table *tbl, int (*cb)(struct neighbour *));
 extern void pneigh_for_each(struct neigh_table *tbl, void (*cb)(struct pneigh_entry *));
diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h
--- a/include/net/pkt_sched.h
+++ b/include/net/pkt_sched.h
@@ -13,13 +13,12 @@ struct qdisc_walker
 
 extern rwlock_t qdisc_tree_lock;
 
-#define	QDISC_ALIGN		32
-#define	QDISC_ALIGN_CONST	(QDISC_ALIGN - 1)
+#define QDISC_ALIGNTO		32
+#define QDISC_ALIGN(len)	(((len) + QDISC_ALIGNTO-1) & ~(QDISC_ALIGNTO-1))
 
 static inline void *qdisc_priv(struct Qdisc *q)
 {
-	return (char *)q + ((sizeof(struct Qdisc) + QDISC_ALIGN_CONST)
-			      & ~QDISC_ALIGN_CONST);
+	return (char *) q + QDISC_ALIGN(sizeof(struct Qdisc));
 }
 
 /* 
@@ -207,8 +206,6 @@ psched_tod_diff(int delta_sec, int bound
 
 #endif /* !CONFIG_NET_SCH_CLK_GETTIMEOFDAY */
 
-extern struct Qdisc noop_qdisc;
-extern struct Qdisc_ops noop_qdisc_ops;
 extern struct Qdisc_ops pfifo_qdisc_ops;
 extern struct Qdisc_ops bfifo_qdisc_ops;
 
@@ -216,14 +213,6 @@ extern int register_qdisc(struct Qdisc_o
 extern int unregister_qdisc(struct Qdisc_ops *qops);
 extern struct Qdisc *qdisc_lookup(struct net_device *dev, u32 handle);
 extern struct Qdisc *qdisc_lookup_class(struct net_device *dev, u32 handle);
-extern void dev_init_scheduler(struct net_device *dev);
-extern void dev_shutdown(struct net_device *dev);
-extern void dev_activate(struct net_device *dev);
-extern void dev_deactivate(struct net_device *dev);
-extern void qdisc_reset(struct Qdisc *qdisc);
-extern void qdisc_destroy(struct Qdisc *qdisc);
-extern struct Qdisc * qdisc_create_dflt(struct net_device *dev,
-	struct Qdisc_ops *ops);
 extern struct qdisc_rate_table *qdisc_get_rtab(struct tc_ratespec *r,
 		struct rtattr *tab);
 extern void qdisc_put_rtab(struct qdisc_rate_table *tab);
diff --git a/include/net/request_sock.h b/include/net/request_sock.h
new file mode 100644
--- /dev/null
+++ b/include/net/request_sock.h
@@ -0,0 +1,255 @@
+/*
+ * NET		Generic infrastructure for Network protocols.
+ *
+ *		Definitions for request_sock 
+ *
+ * Authors:	Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ *
+ * 		From code originally in include/net/tcp.h
+ *
+ *		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 _REQUEST_SOCK_H
+#define _REQUEST_SOCK_H
+
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+
+#include <net/sock.h>
+
+struct request_sock;
+struct sk_buff;
+struct dst_entry;
+struct proto;
+
+struct request_sock_ops {
+	int		family;
+	kmem_cache_t	*slab;
+	int		obj_size;
+	int		(*rtx_syn_ack)(struct sock *sk,
+				       struct request_sock *req,
+				       struct dst_entry *dst);
+	void		(*send_ack)(struct sk_buff *skb,
+				    struct request_sock *req);
+	void		(*send_reset)(struct sk_buff *skb);
+	void		(*destructor)(struct request_sock *req);
+};
+
+/* struct request_sock - mini sock to represent a connection request
+ */
+struct request_sock {
+	struct request_sock		*dl_next; /* Must be first member! */
+	u16				mss;
+	u8				retrans;
+	u8				__pad;
+	/* The following two fields can be easily recomputed I think -AK */
+	u32				window_clamp; /* window clamp at creation time */
+	u32				rcv_wnd;	  /* rcv_wnd offered first time */
+	u32				ts_recent;
+	unsigned long			expires;
+	struct request_sock_ops		*rsk_ops;
+	struct sock			*sk;
+};
+
+static inline struct request_sock *reqsk_alloc(struct request_sock_ops *ops)
+{
+	struct request_sock *req = kmem_cache_alloc(ops->slab, SLAB_ATOMIC);
+
+	if (req != NULL)
+		req->rsk_ops = ops;
+
+	return req;
+}
+
+static inline void __reqsk_free(struct request_sock *req)
+{
+	kmem_cache_free(req->rsk_ops->slab, req);
+}
+
+static inline void reqsk_free(struct request_sock *req)
+{
+	req->rsk_ops->destructor(req);
+	__reqsk_free(req);
+}
+
+extern int sysctl_max_syn_backlog;
+
+/** struct listen_sock - listen state
+ *
+ * @max_qlen_log - log_2 of maximal queued SYNs/REQUESTs
+ */
+struct listen_sock {
+	u8			max_qlen_log;
+	/* 3 bytes hole, try to use */
+	int			qlen;
+	int			qlen_young;
+	int			clock_hand;
+	u32			hash_rnd;
+	struct request_sock	*syn_table[0];
+};
+
+/** struct request_sock_queue - queue of request_socks
+ *
+ * @rskq_accept_head - FIFO head of established children
+ * @rskq_accept_tail - FIFO tail of established children
+ * @syn_wait_lock - serializer
+ *
+ * %syn_wait_lock is necessary only to avoid proc interface having to grab the main
+ * lock sock while browsing the listening hash (otherwise it's deadlock prone).
+ *
+ * This lock is acquired in read mode only from listening_get_next() seq_file
+ * op and it's acquired in write mode _only_ from code that is actively
+ * changing rskq_accept_head. All readers that are holding the master sock lock
+ * don't need to grab this lock in read mode too as rskq_accept_head. writes
+ * are always protected from the main sock lock.
+ */
+struct request_sock_queue {
+	struct request_sock	*rskq_accept_head;
+	struct request_sock	*rskq_accept_tail;
+	rwlock_t		syn_wait_lock;
+	struct listen_sock	*listen_opt;
+};
+
+extern int reqsk_queue_alloc(struct request_sock_queue *queue,
+			     const int nr_table_entries);
+
+static inline struct listen_sock *reqsk_queue_yank_listen_sk(struct request_sock_queue *queue)
+{
+	struct listen_sock *lopt;
+
+	write_lock_bh(&queue->syn_wait_lock);
+	lopt = queue->listen_opt;
+	queue->listen_opt = NULL;
+	write_unlock_bh(&queue->syn_wait_lock);
+
+	return lopt;
+}
+
+static inline void reqsk_queue_destroy(struct request_sock_queue *queue)
+{
+	kfree(reqsk_queue_yank_listen_sk(queue));
+}
+
+static inline struct request_sock *
+	reqsk_queue_yank_acceptq(struct request_sock_queue *queue)
+{
+	struct request_sock *req = queue->rskq_accept_head;
+
+	queue->rskq_accept_head = queue->rskq_accept_head = NULL;
+	return req;
+}
+
+static inline int reqsk_queue_empty(struct request_sock_queue *queue)
+{
+	return queue->rskq_accept_head == NULL;
+}
+
+static inline void reqsk_queue_unlink(struct request_sock_queue *queue,
+				      struct request_sock *req,
+				      struct request_sock **prev_req)
+{
+	write_lock(&queue->syn_wait_lock);
+	*prev_req = req->dl_next;
+	write_unlock(&queue->syn_wait_lock);
+}
+
+static inline void reqsk_queue_add(struct request_sock_queue *queue,
+				   struct request_sock *req,
+				   struct sock *parent,
+				   struct sock *child)
+{
+	req->sk = child;
+	sk_acceptq_added(parent);
+
+	if (queue->rskq_accept_head == NULL)
+		queue->rskq_accept_head = req;
+	else
+		queue->rskq_accept_tail->dl_next = req;
+
+	queue->rskq_accept_tail = req;
+	req->dl_next = NULL;
+}
+
+static inline struct request_sock *reqsk_queue_remove(struct request_sock_queue *queue)
+{
+	struct request_sock *req = queue->rskq_accept_head;
+
+	BUG_TRAP(req != NULL);
+
+	queue->rskq_accept_head = req->dl_next;
+	if (queue->rskq_accept_head == NULL)
+		queue->rskq_accept_tail = NULL;
+
+	return req;
+}
+
+static inline struct sock *reqsk_queue_get_child(struct request_sock_queue *queue,
+						 struct sock *parent)
+{
+	struct request_sock *req = reqsk_queue_remove(queue);
+	struct sock *child = req->sk;
+
+	BUG_TRAP(child != NULL);
+
+	sk_acceptq_removed(parent);
+	__reqsk_free(req);
+	return child;
+}
+
+static inline int reqsk_queue_removed(struct request_sock_queue *queue,
+				      struct request_sock *req)
+{
+	struct listen_sock *lopt = queue->listen_opt;
+
+	if (req->retrans == 0)
+		--lopt->qlen_young;
+
+	return --lopt->qlen;
+}
+
+static inline int reqsk_queue_added(struct request_sock_queue *queue)
+{
+	struct listen_sock *lopt = queue->listen_opt;
+	const int prev_qlen = lopt->qlen;
+
+	lopt->qlen_young++;
+	lopt->qlen++;
+	return prev_qlen;
+}
+
+static inline int reqsk_queue_len(struct request_sock_queue *queue)
+{
+	return queue->listen_opt != NULL ? queue->listen_opt->qlen : 0;
+}
+
+static inline int reqsk_queue_len_young(struct request_sock_queue *queue)
+{
+	return queue->listen_opt->qlen_young;
+}
+
+static inline int reqsk_queue_is_full(struct request_sock_queue *queue)
+{
+	return queue->listen_opt->qlen >> queue->listen_opt->max_qlen_log;
+}
+
+static inline void reqsk_queue_hash_req(struct request_sock_queue *queue,
+					u32 hash, struct request_sock *req,
+					unsigned timeout)
+{
+	struct listen_sock *lopt = queue->listen_opt;
+
+	req->expires = jiffies + timeout;
+	req->retrans = 0;
+	req->sk = NULL;
+	req->dl_next = lopt->syn_table[hash];
+
+	write_lock(&queue->syn_wait_lock);
+	lopt->syn_table[hash] = req;
+	write_unlock(&queue->syn_wait_lock);
+}
+
+#endif /* _REQUEST_SOCK_H */
diff --git a/include/net/route.h b/include/net/route.h
--- a/include/net/route.h
+++ b/include/net/route.h
@@ -107,7 +107,7 @@ struct rt_cache_stat 
 
 extern struct rt_cache_stat *rt_cache_stat;
 #define RT_CACHE_STAT_INC(field)					  \
-		(per_cpu_ptr(rt_cache_stat, _smp_processor_id())->field++)
+		(per_cpu_ptr(rt_cache_stat, raw_smp_processor_id())->field++)
 
 extern struct ip_rt_acct *ip_rt_acct;
 
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -164,6 +164,19 @@ extern void qdisc_unlock_tree(struct net
 #define tcf_tree_lock(tp)	qdisc_lock_tree((tp)->q->dev)
 #define tcf_tree_unlock(tp)	qdisc_unlock_tree((tp)->q->dev)
 
+extern struct Qdisc noop_qdisc;
+extern struct Qdisc_ops noop_qdisc_ops;
+
+extern void dev_init_scheduler(struct net_device *dev);
+extern void dev_shutdown(struct net_device *dev);
+extern void dev_activate(struct net_device *dev);
+extern void dev_deactivate(struct net_device *dev);
+extern void qdisc_reset(struct Qdisc *qdisc);
+extern void qdisc_destroy(struct Qdisc *qdisc);
+extern struct Qdisc *qdisc_alloc(struct net_device *dev, struct Qdisc_ops *ops);
+extern struct Qdisc *qdisc_create_dflt(struct net_device *dev,
+				       struct Qdisc_ops *ops);
+
 static inline void
 tcf_destroy(struct tcf_proto *tp)
 {
@@ -172,4 +185,126 @@ tcf_destroy(struct tcf_proto *tp)
 	kfree(tp);
 }
 
+static inline int __qdisc_enqueue_tail(struct sk_buff *skb, struct Qdisc *sch,
+				       struct sk_buff_head *list)
+{
+	__skb_queue_tail(list, skb);
+	sch->qstats.backlog += skb->len;
+	sch->bstats.bytes += skb->len;
+	sch->bstats.packets++;
+
+	return NET_XMIT_SUCCESS;
+}
+
+static inline int qdisc_enqueue_tail(struct sk_buff *skb, struct Qdisc *sch)
+{
+	return __qdisc_enqueue_tail(skb, sch, &sch->q);
+}
+
+static inline struct sk_buff *__qdisc_dequeue_head(struct Qdisc *sch,
+						   struct sk_buff_head *list)
+{
+	struct sk_buff *skb = __skb_dequeue(list);
+
+	if (likely(skb != NULL))
+		sch->qstats.backlog -= skb->len;
+
+	return skb;
+}
+
+static inline struct sk_buff *qdisc_dequeue_head(struct Qdisc *sch)
+{
+	return __qdisc_dequeue_head(sch, &sch->q);
+}
+
+static inline struct sk_buff *__qdisc_dequeue_tail(struct Qdisc *sch,
+						   struct sk_buff_head *list)
+{
+	struct sk_buff *skb = __skb_dequeue_tail(list);
+
+	if (likely(skb != NULL))
+		sch->qstats.backlog -= skb->len;
+
+	return skb;
+}
+
+static inline struct sk_buff *qdisc_dequeue_tail(struct Qdisc *sch)
+{
+	return __qdisc_dequeue_tail(sch, &sch->q);
+}
+
+static inline int __qdisc_requeue(struct sk_buff *skb, struct Qdisc *sch,
+				  struct sk_buff_head *list)
+{
+	__skb_queue_head(list, skb);
+	sch->qstats.backlog += skb->len;
+	sch->qstats.requeues++;
+
+	return NET_XMIT_SUCCESS;
+}
+
+static inline int qdisc_requeue(struct sk_buff *skb, struct Qdisc *sch)
+{
+	return __qdisc_requeue(skb, sch, &sch->q);
+}
+
+static inline void __qdisc_reset_queue(struct Qdisc *sch,
+				       struct sk_buff_head *list)
+{
+	/*
+	 * We do not know the backlog in bytes of this list, it
+	 * is up to the caller to correct it
+	 */
+	skb_queue_purge(list);
+}
+
+static inline void qdisc_reset_queue(struct Qdisc *sch)
+{
+	__qdisc_reset_queue(sch, &sch->q);
+	sch->qstats.backlog = 0;
+}
+
+static inline unsigned int __qdisc_queue_drop(struct Qdisc *sch,
+					      struct sk_buff_head *list)
+{
+	struct sk_buff *skb = __qdisc_dequeue_tail(sch, list);
+
+	if (likely(skb != NULL)) {
+		unsigned int len = skb->len;
+		kfree_skb(skb);
+		return len;
+	}
+
+	return 0;
+}
+
+static inline unsigned int qdisc_queue_drop(struct Qdisc *sch)
+{
+	return __qdisc_queue_drop(sch, &sch->q);
+}
+
+static inline int qdisc_drop(struct sk_buff *skb, struct Qdisc *sch)
+{
+	kfree_skb(skb);
+	sch->qstats.drops++;
+
+	return NET_XMIT_DROP;
+}
+
+static inline int qdisc_reshape_fail(struct sk_buff *skb, struct Qdisc *sch)
+{
+	sch->qstats.drops++;
+
+#ifdef CONFIG_NET_CLS_POLICE
+	if (sch->reshape_fail == NULL || sch->reshape_fail(skb, sch))
+		goto drop;
+
+	return NET_XMIT_SUCCESS;
+
+drop:
+#endif
+	kfree_skb(skb);
+	return NET_XMIT_DROP;
+}
+
 #endif
diff --git a/include/net/sctp/command.h b/include/net/sctp/command.h
--- a/include/net/sctp/command.h
+++ b/include/net/sctp/command.h
@@ -65,9 +65,11 @@ typedef enum {
 	SCTP_CMD_TIMER_START,	/* Start a timer.  */
 	SCTP_CMD_TIMER_RESTART,	/* Restart a timer. */
 	SCTP_CMD_TIMER_STOP,	/* Stop a timer. */
-	SCTP_CMD_COUNTER_RESET, /* Reset a counter. */
-	SCTP_CMD_COUNTER_INC,   /* Increment a counter. */
+	SCTP_CMD_INIT_CHOOSE_TRANSPORT, /* Choose transport for an INIT. */
+	SCTP_CMD_INIT_COUNTER_RESET, /* Reset init counter. */
+	SCTP_CMD_INIT_COUNTER_INC,   /* Increment init counter. */
 	SCTP_CMD_INIT_RESTART,  /* High level, do init timer work. */
+	SCTP_CMD_COOKIEECHO_RESTART,  /* High level, do cookie-echo timer work. */
 	SCTP_CMD_INIT_FAILED,   /* High level, do init failure work. */
 	SCTP_CMD_REPORT_DUP,	/* Report a duplicate TSN.  */
 	SCTP_CMD_STRIKE,	/* Mark a strike against a transport.  */
@@ -118,7 +120,6 @@ typedef union {
 	int error;
 	sctp_state_t state;
 	sctp_event_timeout_t to;
-	sctp_counter_t counter;
 	void *ptr;
 	struct sctp_chunk *chunk;
 	struct sctp_association *asoc;
@@ -165,7 +166,6 @@ SCTP_ARG_CONSTRUCTOR(U16,	__u16, u16)
 SCTP_ARG_CONSTRUCTOR(U8,	__u8, u8)
 SCTP_ARG_CONSTRUCTOR(ERROR,     int, error)
 SCTP_ARG_CONSTRUCTOR(STATE,	sctp_state_t, state)
-SCTP_ARG_CONSTRUCTOR(COUNTER,	sctp_counter_t, counter)
 SCTP_ARG_CONSTRUCTOR(TO,	sctp_event_timeout_t, to)
 SCTP_ARG_CONSTRUCTOR(PTR,	void *, ptr)
 SCTP_ARG_CONSTRUCTOR(CHUNK,	struct sctp_chunk *, chunk)
diff --git a/include/net/sctp/constants.h b/include/net/sctp/constants.h
--- a/include/net/sctp/constants.h
+++ b/include/net/sctp/constants.h
@@ -263,30 +263,11 @@ enum { SCTP_MIN_PMTU = 576 };
 enum { SCTP_MAX_DUP_TSNS = 16 };
 enum { SCTP_MAX_GABS = 16 };
 
-typedef enum {
-	SCTP_COUNTER_INIT_ERROR,
-} sctp_counter_t;
-
-/* How many counters does an association need? */
-#define SCTP_NUMBER_COUNTERS	5
-
-/* Here we define the default timers.  */
-
-/* cookie timer def = ? seconds */
-#define SCTP_DEFAULT_TIMEOUT_T1_COOKIE	(3 * HZ)
-
-/* init timer def = 3 seconds  */
-#define SCTP_DEFAULT_TIMEOUT_T1_INIT	(3 * HZ)
-
-/* shutdown timer def = 300 ms */
-#define SCTP_DEFAULT_TIMEOUT_T2_SHUTDOWN ((300 * HZ) / 1000)
-
-/* 0 seconds + RTO */
-#define SCTP_DEFAULT_TIMEOUT_HEARTBEAT	(10 * HZ)
+/* Heartbeat interval - 30 secs */
+#define SCTP_DEFAULT_TIMEOUT_HEARTBEAT	(30 * HZ)
 
-/* recv timer def = 200ms (in usec) */
+/* Delayed sack timer - 200ms */
 #define SCTP_DEFAULT_TIMEOUT_SACK	((200 * HZ) / 1000)
-#define SCTP_DEFAULT_TIMEOUT_SACK_MAX	((500 * HZ) / 1000) /* 500 ms */
 
 /* RTO.Initial              - 3  seconds
  * RTO.Min                  - 1  second
diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
--- a/include/net/sctp/sctp.h
+++ b/include/net/sctp/sctp.h
@@ -125,7 +125,8 @@
  */
 extern struct sock *sctp_get_ctl_sock(void);
 extern int sctp_copy_local_addr_list(struct sctp_bind_addr *,
-				     sctp_scope_t, int gfp, int flags);
+				     sctp_scope_t, unsigned int __nocast gfp,
+				     int flags);
 extern struct sctp_pf *sctp_get_pf_specific(sa_family_t family);
 extern int sctp_register_pf(struct sctp_pf *, sa_family_t);
 
@@ -166,15 +167,12 @@ void sctp_unhash_established(struct sctp
 void sctp_hash_endpoint(struct sctp_endpoint *);
 void sctp_unhash_endpoint(struct sctp_endpoint *);
 struct sock *sctp_err_lookup(int family, struct sk_buff *,
-			     struct sctphdr *, struct sctp_endpoint **,
-			     struct sctp_association **,
+			     struct sctphdr *, struct sctp_association **,
 			     struct sctp_transport **);
-void sctp_err_finish(struct sock *, struct sctp_endpoint *,
-			    struct sctp_association *);
+void sctp_err_finish(struct sock *, struct sctp_association *);
 void sctp_icmp_frag_needed(struct sock *, struct sctp_association *,
 			   struct sctp_transport *t, __u32 pmtu);
 void sctp_icmp_proto_unreachable(struct sock *sk,
-				 struct sctp_endpoint *ep,
 				 struct sctp_association *asoc,
 				 struct sctp_transport *t);
 
@@ -223,6 +221,22 @@ DECLARE_SNMP_STAT(struct sctp_mib, sctp_
 extern int sctp_debug_flag;
 #define SCTP_DEBUG_PRINTK(whatever...) \
 	((void) (sctp_debug_flag && printk(KERN_DEBUG whatever)))
+#define SCTP_DEBUG_PRINTK_IPADDR(lead, trail, leadparm, saddr, otherparms...) \
+	if (sctp_debug_flag) { \
+		if (saddr->sa.sa_family == AF_INET6) { \
+			printk(KERN_DEBUG \
+			       lead "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x" trail, \
+			       leadparm, \
+			       NIP6(saddr->v6.sin6_addr), \
+			       otherparms); \
+		} else { \
+			printk(KERN_DEBUG \
+			       lead "%u.%u.%u.%u" trail, \
+			       leadparm, \
+			       NIPQUAD(saddr->v4.sin_addr.s_addr), \
+			       otherparms); \
+		} \
+	}
 #define SCTP_ENABLE_DEBUG { sctp_debug_flag = 1; }
 #define SCTP_DISABLE_DEBUG { sctp_debug_flag = 0; }
 
@@ -236,6 +250,7 @@ extern int sctp_debug_flag;
 #else	/* SCTP_DEBUG */
 
 #define SCTP_DEBUG_PRINTK(whatever...)
+#define SCTP_DEBUG_PRINTK_IPADDR(whatever...)
 #define SCTP_ENABLE_DEBUG
 #define SCTP_DISABLE_DEBUG
 #define SCTP_ASSERT(expr, str, func)
diff --git a/include/net/sctp/sm.h b/include/net/sctp/sm.h
--- a/include/net/sctp/sm.h
+++ b/include/net/sctp/sm.h
@@ -116,7 +116,8 @@ sctp_state_fn_t sctp_sf_eat_data_fast_4_
 sctp_state_fn_t sctp_sf_eat_sack_6_2;
 sctp_state_fn_t sctp_sf_tabort_8_4_8;
 sctp_state_fn_t sctp_sf_operr_notify;
-sctp_state_fn_t sctp_sf_t1_timer_expire;
+sctp_state_fn_t sctp_sf_t1_init_timer_expire;
+sctp_state_fn_t sctp_sf_t1_cookie_timer_expire;
 sctp_state_fn_t sctp_sf_t2_timer_expire;
 sctp_state_fn_t sctp_sf_t4_timer_expire;
 sctp_state_fn_t sctp_sf_t5_timer_expire;
@@ -130,7 +131,6 @@ sctp_state_fn_t sctp_sf_do_ecne;
 sctp_state_fn_t sctp_sf_ootb;
 sctp_state_fn_t sctp_sf_pdiscard;
 sctp_state_fn_t sctp_sf_violation;
-sctp_state_fn_t sctp_sf_violation_chunklen;
 sctp_state_fn_t sctp_sf_discard_chunk;
 sctp_state_fn_t sctp_sf_do_5_2_1_siminit;
 sctp_state_fn_t sctp_sf_do_5_2_2_dupinit;
@@ -181,17 +181,17 @@ const sctp_sm_table_entry_t *sctp_sm_loo
 int sctp_chunk_iif(const struct sctp_chunk *);
 struct sctp_association *sctp_make_temp_asoc(const struct sctp_endpoint *,
 					     struct sctp_chunk *,
-					     int gfp);
+					     unsigned int __nocast gfp);
 __u32 sctp_generate_verification_tag(void);
 void sctp_populate_tie_tags(__u8 *cookie, __u32 curTag, __u32 hisTag);
 
 /* Prototypes for chunk-building functions.  */
 struct sctp_chunk *sctp_make_init(const struct sctp_association *,
 			     const struct sctp_bind_addr *,
-			     int gfp, int vparam_len);
+			     unsigned int __nocast gfp, int vparam_len);
 struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *,
 				 const struct sctp_chunk *,
-				 const int gfp,
+				 const unsigned int __nocast gfp,
 				 const int unkparam_len);
 struct sctp_chunk *sctp_make_cookie_echo(const struct sctp_association *,
 				    const struct sctp_chunk *);
@@ -258,8 +258,6 @@ struct sctp_chunk *sctp_make_fwdtsn(cons
 void sctp_chunk_assign_tsn(struct sctp_chunk *);
 void sctp_chunk_assign_ssn(struct sctp_chunk *);
 
-void sctp_stop_t1_and_abort(sctp_cmd_seq_t *commands, __u16 error);
-
 /* Prototypes for statetable processing. */
 
 int sctp_do_sm(sctp_event_t event_type, sctp_subtype_t subtype,
@@ -267,7 +265,7 @@ int sctp_do_sm(sctp_event_t event_type, 
                struct sctp_endpoint *,
                struct sctp_association *asoc,
                void *event_arg,
-               int gfp);
+	       unsigned int __nocast gfp);
 
 /* 2nd level prototypes */
 void sctp_generate_t3_rtx_event(unsigned long peer);
@@ -277,7 +275,8 @@ void sctp_ootb_pkt_free(struct sctp_pack
 
 struct sctp_association *sctp_unpack_cookie(const struct sctp_endpoint *,
 				       const struct sctp_association *,
-				       struct sctp_chunk *, int gfp, int *err,
+				       struct sctp_chunk *,
+				       unsigned int __nocast gfp, int *err,
 				       struct sctp_chunk **err_chk_p);
 int sctp_addip_addr_config(struct sctp_association *, sctp_param_t,
 			   struct sockaddr_storage*, int);
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -161,6 +161,9 @@ extern struct sctp_globals {
 	 */
 	int sndbuf_policy;
 
+	/* Delayed SACK timeout  200ms default*/
+	int sack_timeout;
+
 	/* HB.interval		    - 30 seconds  */
 	int hb_interval;
 
@@ -217,6 +220,7 @@ extern struct sctp_globals {
 #define sctp_sndbuf_policy	 	(sctp_globals.sndbuf_policy)
 #define sctp_max_retrans_path		(sctp_globals.max_retrans_path)
 #define sctp_max_retrans_init		(sctp_globals.max_retrans_init)
+#define sctp_sack_timeout		(sctp_globals.sack_timeout)
 #define sctp_hb_interval		(sctp_globals.hb_interval)
 #define sctp_max_instreams		(sctp_globals.max_instreams)
 #define sctp_max_outstreams		(sctp_globals.max_outstreams)
@@ -441,7 +445,8 @@ struct sctp_ssnmap {
 	int malloced;
 };
 
-struct sctp_ssnmap *sctp_ssnmap_new(__u16 in, __u16 out, int gfp);
+struct sctp_ssnmap *sctp_ssnmap_new(__u16 in, __u16 out,
+				    unsigned int __nocast gfp);
 void sctp_ssnmap_free(struct sctp_ssnmap *map);
 void sctp_ssnmap_clear(struct sctp_ssnmap *map);
 
@@ -578,7 +583,6 @@ void sctp_datamsg_track(struct sctp_chun
 void sctp_chunk_fail(struct sctp_chunk *, int error);
 int sctp_chunk_abandoned(struct sctp_chunk *);
 
-
 /* RFC2960 1.4 Key Terms
  *
  * o Chunk: A unit of information within an SCTP packet, consisting of
@@ -588,13 +592,8 @@ int sctp_chunk_abandoned(struct sctp_chu
  * each chunk as well as a few other header pointers...
  */
 struct sctp_chunk {
-	/* These first three elements MUST PRECISELY match the first
-	 * three elements of struct sk_buff.  This allows us to reuse
-	 * all the skb_* queue management functions.
-	 */
-	struct sctp_chunk *next;
-	struct sctp_chunk *prev;
-	struct sk_buff_head *list;
+	struct list_head list;
+
 	atomic_t refcnt;
 
 	/* This is our link to the per-transport transmitted list.  */
@@ -713,7 +712,7 @@ struct sctp_packet {
 	__u32 vtag;
 
 	/* This contains the payload chunks.  */
-	struct sk_buff_head chunks;
+	struct list_head chunk_list;
 
 	/* This is the overhead of the sctp and ip headers. */
 	size_t overhead;
@@ -867,10 +866,13 @@ struct sctp_transport {
 	 */
 	unsigned long last_time_ecne_reduced;
 
-	/* active      : The current active state of this destination,
-	 *	       :  i.e. DOWN, UP, etc.
+	/* The number of times INIT has been sent on this transport. */
+	int init_sent_count;
+
+	/* state       : The current state of this destination,
+	 *             : i.e. SCTP_ACTIVE, SCTP_INACTIVE, SCTP_UNKOWN.
 	 */
-	int active;
+	int state;
 
 	/* hb_allowed  : The current heartbeat state of this destination,
 	 *	       :  i.e. ALLOW-HB, NO-HEARTBEAT, etc.
@@ -944,7 +946,8 @@ struct sctp_transport {
 	} cacc;
 };
 
-struct sctp_transport *sctp_transport_new(const union sctp_addr *, int);
+struct sctp_transport *sctp_transport_new(const union sctp_addr *,
+					  unsigned int __nocast);
 void sctp_transport_set_owner(struct sctp_transport *,
 			      struct sctp_association *);
 void sctp_transport_route(struct sctp_transport *, union sctp_addr *,
@@ -967,7 +970,7 @@ struct sctp_inq {
 	/* This is actually a queue of sctp_chunk each
 	 * containing a partially decoded packet.
 	 */
-	struct sk_buff_head in;
+	struct list_head in_chunk_list;
 	/* This is the packet which is currently off the in queue and is
 	 * being worked on through the inbound chunk processing.
 	 */
@@ -1010,7 +1013,7 @@ struct sctp_outq {
 	struct sctp_association *asoc;
 
 	/* Data pending that has never been transmitted.  */
-	struct sk_buff_head out;
+	struct list_head out_chunk_list;
 
 	unsigned out_qlen;	/* Total length of queued data chunks. */
 
@@ -1018,7 +1021,7 @@ struct sctp_outq {
 	unsigned error;
 
 	/* These are control chunks we want to send.  */
-	struct sk_buff_head control;
+	struct list_head control_chunk_list;
 
 	/* These are chunks that have been sacked but are above the
 	 * CTSN, or cumulative tsn ack point.
@@ -1092,9 +1095,10 @@ void sctp_bind_addr_init(struct sctp_bin
 void sctp_bind_addr_free(struct sctp_bind_addr *);
 int sctp_bind_addr_copy(struct sctp_bind_addr *dest,
 			const struct sctp_bind_addr *src,
-			sctp_scope_t scope, int gfp,int flags);
+			sctp_scope_t scope, unsigned int __nocast gfp,
+			int flags);
 int sctp_add_bind_addr(struct sctp_bind_addr *, union sctp_addr *,
-		       int gfp);
+		       unsigned int __nocast gfp);
 int sctp_del_bind_addr(struct sctp_bind_addr *, union sctp_addr *);
 int sctp_bind_addr_match(struct sctp_bind_addr *, const union sctp_addr *,
 			 struct sctp_sock *);
@@ -1103,9 +1107,10 @@ union sctp_addr *sctp_find_unmatch_addr(
 					int			addrcnt,
 					struct sctp_sock	*opt);
 union sctp_params sctp_bind_addrs_to_raw(const struct sctp_bind_addr *bp,
-					 int *addrs_len, int gfp);
+					 int *addrs_len,
+					 unsigned int __nocast gfp);
 int sctp_raw_to_bind_addrs(struct sctp_bind_addr *bp, __u8 *raw, int len,
-			   __u16 port, int gfp);
+			   __u16 port, unsigned int __nocast gfp);
 
 sctp_scope_t sctp_scope(const union sctp_addr *);
 int sctp_in_scope(const union sctp_addr *addr, const sctp_scope_t scope);
@@ -1222,9 +1227,6 @@ struct sctp_endpoint {
 
 	/* sendbuf acct. policy.	*/
 	__u32 sndbuf_policy;
-
-	/* Name for debugging output... */
-	char *debug_name;
 };
 
 /* Recover the outter endpoint structure. */
@@ -1237,7 +1239,7 @@ static inline struct sctp_endpoint *sctp
 }
 
 /* These are function signatures for manipulating endpoints.  */
-struct sctp_endpoint *sctp_endpoint_new(struct sock *, int);
+struct sctp_endpoint *sctp_endpoint_new(struct sock *, unsigned int __nocast);
 void sctp_endpoint_free(struct sctp_endpoint *);
 void sctp_endpoint_put(struct sctp_endpoint *);
 void sctp_endpoint_hold(struct sctp_endpoint *);
@@ -1258,7 +1260,7 @@ int sctp_verify_init(const struct sctp_a
 		     struct sctp_chunk **err_chunk);
 int sctp_process_init(struct sctp_association *, sctp_cid_t cid,
 		      const union sctp_addr *peer,
-		      sctp_init_chunk_t *init, int gfp);
+		      sctp_init_chunk_t *init, unsigned int __nocast gfp);
 __u32 sctp_generate_tag(const struct sctp_endpoint *);
 __u32 sctp_generate_tsn(const struct sctp_endpoint *);
 
@@ -1314,11 +1316,23 @@ struct sctp_association {
 		 *	       : association. Normally this information is
 		 *	       : hashed or keyed for quick lookup and access
 		 *	       : of the TCB.
+		 *	       : The list is also initialized with the list
+		 *	       : of addresses passed with the sctp_connectx()
+		 *	       : call.
 		 *
 		 * It is a list of SCTP_transport's.
 		 */
 		struct list_head transport_addr_list;
 
+		/* transport_count
+		 *
+		 * Peer        : A count of the number of peer addresses
+		 * Transport   : in the Peer Transport Address List.
+		 * Address     :
+		 * Count       :
+		 */
+		__u16 transport_count;
+
 		/* port
 		 *   The transport layer port number.
 		 */
@@ -1486,6 +1500,9 @@ struct sctp_association {
 	/* Transport to which SHUTDOWN chunk was last sent.  */
 	struct sctp_transport *shutdown_last_sent_to;
 
+	/* Transport to which INIT chunk was last sent.  */
+	struct sctp_transport *init_last_sent_to;
+
 	/* Next TSN    : The next TSN number to be assigned to a new
 	 *	       : DATA chunk.  This is sent in the INIT or INIT
 	 *	       : ACK chunk to the peer and incremented each
@@ -1549,8 +1566,11 @@ struct sctp_association {
 	/* The message size at which SCTP fragmentation will occur. */
 	__u32 frag_point;
 
-	/* Currently only one counter is used to count INIT errors. */
-	int counters[SCTP_NUMBER_COUNTERS];
+	/* Counter used to count INIT errors. */
+	int init_err_counter;
+
+	/* Count the number of INIT cycles (for doubling timeout). */
+	int init_cycle;
 
 	/* Default send parameters. */
 	__u16 default_stream;
@@ -1650,7 +1670,7 @@ struct sctp_association {
 	 *  which already resides in sctp_outq.	 Please move this
 	 *  queue and its supporting logic down there.	--piggy]
 	 */
-	struct sk_buff_head addip_chunks;
+	struct list_head addip_chunk_list;
 
 	/* ADDIP Section 4.1 ASCONF Chunk Procedures
 	 *
@@ -1703,11 +1723,13 @@ static inline struct sctp_association *s
 
 struct sctp_association *
 sctp_association_new(const struct sctp_endpoint *, const struct sock *,
-		     sctp_scope_t scope, int gfp);
+		     sctp_scope_t scope, unsigned int __nocast gfp);
 void sctp_association_free(struct sctp_association *);
 void sctp_association_put(struct sctp_association *);
 void sctp_association_hold(struct sctp_association *);
 
+struct sctp_transport *sctp_assoc_choose_init_transport(
+	struct sctp_association *);
 struct sctp_transport *sctp_assoc_choose_shutdown_transport(
 	struct sctp_association *);
 void sctp_assoc_update_retran_path(struct sctp_association *);
@@ -1717,9 +1739,12 @@ int sctp_assoc_lookup_laddr(struct sctp_
 			    const union sctp_addr *laddr);
 struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *,
 				     const union sctp_addr *address,
-				     const int gfp);
+				     const unsigned int __nocast gfp,
+				     const int peer_state);
 void sctp_assoc_del_peer(struct sctp_association *asoc,
 			 const union sctp_addr *addr);
+void sctp_assoc_rm_peer(struct sctp_association *asoc,
+			 struct sctp_transport *peer);
 void sctp_assoc_control_transport(struct sctp_association *,
 				  struct sctp_transport *,
 				  sctp_transport_cmd_t, sctp_sn_error_t);
@@ -1738,9 +1763,11 @@ void sctp_assoc_rwnd_increase(struct sct
 void sctp_assoc_rwnd_decrease(struct sctp_association *, unsigned);
 void sctp_assoc_set_primary(struct sctp_association *,
 			    struct sctp_transport *);
-int sctp_assoc_set_bind_addr_from_ep(struct sctp_association *, int);
+int sctp_assoc_set_bind_addr_from_ep(struct sctp_association *,
+				     unsigned int __nocast);
 int sctp_assoc_set_bind_addr_from_cookie(struct sctp_association *,
-					 struct sctp_cookie*, int gfp);
+					 struct sctp_cookie*,
+					 unsigned int __nocast gfp);
 
 int sctp_cmp_addr_exact(const union sctp_addr *ss1,
 			const union sctp_addr *ss2);
diff --git a/include/net/sctp/ulpevent.h b/include/net/sctp/ulpevent.h
--- a/include/net/sctp/ulpevent.h
+++ b/include/net/sctp/ulpevent.h
@@ -88,7 +88,7 @@ struct sctp_ulpevent *sctp_ulpevent_make
 	__u16 error,
 	__u16 outbound,
 	__u16 inbound,
-	int gfp);
+	unsigned int __nocast gfp);
 
 struct sctp_ulpevent *sctp_ulpevent_make_peer_addr_change(
 	const struct sctp_association *asoc,
@@ -96,35 +96,35 @@ struct sctp_ulpevent *sctp_ulpevent_make
 	int flags,
 	int state,
 	int error,
-	int gfp);
+	unsigned int __nocast gfp);
 
 struct sctp_ulpevent *sctp_ulpevent_make_remote_error(
 	const struct sctp_association *asoc,
 	struct sctp_chunk *chunk,
 	__u16 flags,
-	int gfp);
+	unsigned int __nocast gfp);
 struct sctp_ulpevent *sctp_ulpevent_make_send_failed(
 	const struct sctp_association *asoc,
 	struct sctp_chunk *chunk,
 	__u16 flags,
 	__u32 error,
-	int gfp);
+	unsigned int __nocast gfp);
 
 struct sctp_ulpevent *sctp_ulpevent_make_shutdown_event(
 	const struct sctp_association *asoc,
 	__u16 flags,
-	int gfp);
+	unsigned int __nocast gfp);
 
 struct sctp_ulpevent *sctp_ulpevent_make_pdapi(
 	const struct sctp_association *asoc,
-	__u32 indication, int gfp);
+	__u32 indication, unsigned int __nocast gfp);
 
 struct sctp_ulpevent *sctp_ulpevent_make_adaption_indication(
-	const struct sctp_association *asoc, int gfp);
+	const struct sctp_association *asoc, unsigned int __nocast gfp);
 
 struct sctp_ulpevent *sctp_ulpevent_make_rcvmsg(struct sctp_association *asoc,
 	struct sctp_chunk *chunk,
-	int gfp);
+	unsigned int __nocast gfp);
 
 void sctp_ulpevent_read_sndrcvinfo(const struct sctp_ulpevent *event,
 	struct msghdr *);
diff --git a/include/net/sctp/ulpqueue.h b/include/net/sctp/ulpqueue.h
--- a/include/net/sctp/ulpqueue.h
+++ b/include/net/sctp/ulpqueue.h
@@ -62,19 +62,22 @@ struct sctp_ulpq *sctp_ulpq_init(struct 
 void sctp_ulpq_free(struct sctp_ulpq *);
 
 /* Add a new DATA chunk for processing. */
-int sctp_ulpq_tail_data(struct sctp_ulpq *, struct sctp_chunk *, int);
+int sctp_ulpq_tail_data(struct sctp_ulpq *, struct sctp_chunk *,
+			unsigned int __nocast);
 
 /* Add a new event for propagation to the ULP. */
 int sctp_ulpq_tail_event(struct sctp_ulpq *, struct sctp_ulpevent *ev);
 
 /* Renege previously received chunks.  */
-void sctp_ulpq_renege(struct sctp_ulpq *, struct sctp_chunk *, int);
+void sctp_ulpq_renege(struct sctp_ulpq *, struct sctp_chunk *,
+		      unsigned int __nocast);
 
 /* Perform partial delivery. */
-void sctp_ulpq_partial_delivery(struct sctp_ulpq *, struct sctp_chunk *, int);
+void sctp_ulpq_partial_delivery(struct sctp_ulpq *, struct sctp_chunk *,
+				unsigned int __nocast);
 
 /* Abort the partial delivery. */
-void sctp_ulpq_abort_pd(struct sctp_ulpq *, int);
+void sctp_ulpq_abort_pd(struct sctp_ulpq *, unsigned int __nocast);
 
 /* Clear the partial data delivery condition on this socket. */
 int sctp_clear_pd(struct sock *sk);
diff --git a/include/net/sctp/user.h b/include/net/sctp/user.h
--- a/include/net/sctp/user.h
+++ b/include/net/sctp/user.h
@@ -111,6 +111,8 @@ enum sctp_optname {
 #define SCTP_GET_LOCAL_ADDRS_NUM	SCTP_GET_LOCAL_ADDRS_NUM
 	SCTP_GET_LOCAL_ADDRS, 	/* Get all local addresss. */
 #define SCTP_GET_LOCAL_ADDRS	SCTP_GET_LOCAL_ADDRS
+	SCTP_SOCKOPT_CONNECTX, /* CONNECTX requests. */
+#define SCTP_SOCKOPT_CONNECTX	SCTP_SOCKOPT_CONNECTX
 };
 
 /*
@@ -527,6 +529,7 @@ struct sctp_paddrinfo {
 enum sctp_spinfo_state {
 	SCTP_INACTIVE,
 	SCTP_ACTIVE,
+	SCTP_UNKNOWN = 0xffff  /* Value used for transport state unknown */
 };
 
 /*
diff --git a/include/net/slhc_vj.h b/include/net/slhc_vj.h
--- a/include/net/slhc_vj.h
+++ b/include/net/slhc_vj.h
@@ -170,19 +170,14 @@ struct slcompress {
 };
 #define NULLSLCOMPR	(struct slcompress *)0
 
-#define __ARGS(x) x
-
 /* In slhc.c: */
-struct slcompress *slhc_init __ARGS((int rslots, int tslots));
-void slhc_free __ARGS((struct slcompress *comp));
+struct slcompress *slhc_init(int rslots, int tslots);
+void slhc_free(struct slcompress *comp);
 
-int slhc_compress __ARGS((struct slcompress *comp, unsigned char *icp,
-			  int isize, unsigned char *ocp, unsigned char **cpp,
-			  int compress_cid));
-int slhc_uncompress __ARGS((struct slcompress *comp, unsigned char *icp,
-			    int isize));
-int slhc_remember __ARGS((struct slcompress *comp, unsigned char *icp,
-			  int isize));
-int slhc_toss __ARGS((struct slcompress *comp));
+int slhc_compress(struct slcompress *comp, unsigned char *icp, int isize,
+		  unsigned char *ocp, unsigned char **cpp, int compress_cid);
+int slhc_uncompress(struct slcompress *comp, unsigned char *icp, int isize);
+int slhc_remember(struct slcompress *comp, unsigned char *icp, int isize);
+int slhc_toss(struct slcompress *comp);
 
 #endif	/* _SLHC_H */
diff --git a/include/net/snmp.h b/include/net/snmp.h
--- a/include/net/snmp.h
+++ b/include/net/snmp.h
@@ -128,18 +128,18 @@ struct linux_mib {
 #define SNMP_STAT_USRPTR(name)	(name[1])
 
 #define SNMP_INC_STATS_BH(mib, field) 	\
-	(per_cpu_ptr(mib[0], _smp_processor_id())->mibs[field]++)
+	(per_cpu_ptr(mib[0], raw_smp_processor_id())->mibs[field]++)
 #define SNMP_INC_STATS_OFFSET_BH(mib, field, offset)	\
-	(per_cpu_ptr(mib[0], _smp_processor_id())->mibs[field + (offset)]++)
+	(per_cpu_ptr(mib[0], raw_smp_processor_id())->mibs[field + (offset)]++)
 #define SNMP_INC_STATS_USER(mib, field) \
-	(per_cpu_ptr(mib[1], _smp_processor_id())->mibs[field]++)
+	(per_cpu_ptr(mib[1], raw_smp_processor_id())->mibs[field]++)
 #define SNMP_INC_STATS(mib, field) 	\
-	(per_cpu_ptr(mib[!in_softirq()], _smp_processor_id())->mibs[field]++)
+	(per_cpu_ptr(mib[!in_softirq()], raw_smp_processor_id())->mibs[field]++)
 #define SNMP_DEC_STATS(mib, field) 	\
-	(per_cpu_ptr(mib[!in_softirq()], _smp_processor_id())->mibs[field]--)
+	(per_cpu_ptr(mib[!in_softirq()], raw_smp_processor_id())->mibs[field]--)
 #define SNMP_ADD_STATS_BH(mib, field, addend) 	\
-	(per_cpu_ptr(mib[0], _smp_processor_id())->mibs[field] += addend)
+	(per_cpu_ptr(mib[0], raw_smp_processor_id())->mibs[field] += addend)
 #define SNMP_ADD_STATS_USER(mib, field, addend) 	\
-	(per_cpu_ptr(mib[1], _smp_processor_id())->mibs[field] += addend)
+	(per_cpu_ptr(mib[1], raw_smp_processor_id())->mibs[field] += addend)
 
 #endif
diff --git a/include/net/sock.h b/include/net/sock.h
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -384,6 +384,11 @@ enum sock_flags {
 	SOCK_QUEUE_SHRUNK, /* write queue has been shrunk recently */
 };
 
+static inline void sock_copy_flags(struct sock *nsk, struct sock *osk)
+{
+	nsk->sk_flags = osk->sk_flags;
+}
+
 static inline void sock_set_flag(struct sock *sk, enum sock_flags flag)
 {
 	__set_bit(flag, &sk->sk_flags);
@@ -484,6 +489,8 @@ extern void sk_stream_kill_queues(struct
 
 extern int sk_wait_data(struct sock *sk, long *timeo);
 
+struct request_sock_ops;
+
 /* Networking protocol blocks we attach to sockets.
  * socket layer -> transport layer interface
  * transport -> network interface is defined by struct inet_proto
@@ -547,6 +554,8 @@ struct proto {
 	kmem_cache_t		*slab;
 	unsigned int		obj_size;
 
+	struct request_sock_ops	*rsk_prot;
+
 	struct module		*owner;
 
 	char			name[32];
@@ -680,16 +689,17 @@ extern void FASTCALL(release_sock(struct
 #define bh_lock_sock(__sk)	spin_lock(&((__sk)->sk_lock.slock))
 #define bh_unlock_sock(__sk)	spin_unlock(&((__sk)->sk_lock.slock))
 
-extern struct sock		*sk_alloc(int family, int priority,
+extern struct sock		*sk_alloc(int family,
+					  unsigned int __nocast priority,
 					  struct proto *prot, int zero_it);
 extern void			sk_free(struct sock *sk);
 
 extern struct sk_buff		*sock_wmalloc(struct sock *sk,
 					      unsigned long size, int force,
-					      int priority);
+					      unsigned int __nocast priority);
 extern struct sk_buff		*sock_rmalloc(struct sock *sk,
 					      unsigned long size, int force,
-					      int priority);
+					      unsigned int __nocast priority);
 extern void			sock_wfree(struct sk_buff *skb);
 extern void			sock_rfree(struct sk_buff *skb);
 
@@ -704,7 +714,8 @@ extern struct sk_buff 		*sock_alloc_send
 						     unsigned long size,
 						     int noblock,
 						     int *errcode);
-extern void *sock_kmalloc(struct sock *sk, int size, int priority);
+extern void *sock_kmalloc(struct sock *sk, int size,
+			  unsigned int __nocast priority);
 extern void sock_kfree_s(struct sock *sk, void *mem, int size);
 extern void sk_send_sigurg(struct sock *sk);
 
@@ -1128,15 +1139,19 @@ static inline void sk_stream_moderate_sn
 }
 
 static inline struct sk_buff *sk_stream_alloc_pskb(struct sock *sk,
-						   int size, int mem, int gfp)
+						   int size, int mem,
+						   unsigned int __nocast gfp)
 {
-	struct sk_buff *skb = alloc_skb(size + sk->sk_prot->max_header, gfp);
+	struct sk_buff *skb;
+	int hdr_len;
 
+	hdr_len = SKB_DATA_ALIGN(sk->sk_prot->max_header);
+	skb = alloc_skb(size + hdr_len, gfp);
 	if (skb) {
 		skb->truesize += mem;
 		if (sk->sk_forward_alloc >= (int)skb->truesize ||
 		    sk_stream_mem_schedule(sk, skb->truesize, 0)) {
-			skb_reserve(skb, sk->sk_prot->max_header);
+			skb_reserve(skb, hdr_len);
 			return skb;
 		}
 		__kfree_skb(skb);
@@ -1148,7 +1163,8 @@ static inline struct sk_buff *sk_stream_
 }
 
 static inline struct sk_buff *sk_stream_alloc_skb(struct sock *sk,
-						  int size, int gfp)
+						  int size,
+						  unsigned int __nocast gfp)
 {
 	return sk_stream_alloc_pskb(sk, size, 0, gfp);
 }
@@ -1181,7 +1197,7 @@ static inline int sock_writeable(const s
 	return atomic_read(&sk->sk_wmem_alloc) < (sk->sk_sndbuf / 2);
 }
 
-static inline int gfp_any(void)
+static inline unsigned int __nocast gfp_any(void)
 {
 	return in_softirq() ? GFP_ATOMIC : GFP_KERNEL;
 }
diff --git a/include/net/tcp.h b/include/net/tcp.h
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -31,6 +31,7 @@
 #include <linux/cache.h>
 #include <linux/percpu.h>
 #include <net/checksum.h>
+#include <net/request_sock.h>
 #include <net/sock.h>
 #include <net/snmp.h>
 #include <net/ip.h>
@@ -504,25 +505,6 @@ static __inline__ int tcp_sk_listen_hash
 #else
 # define TCP_TW_RECYCLE_TICK (12+2-TCP_TW_RECYCLE_SLOTS_LOG)
 #endif
-
-#define BICTCP_BETA_SCALE    1024	/* Scale factor beta calculation
-					 * max_cwnd = snd_cwnd * beta
-					 */
-#define BICTCP_MAX_INCREMENT 32		/*
-					 * Limit on the amount of
-					 * increment allowed during
-					 * binary search.
-					 */
-#define BICTCP_FUNC_OF_MIN_INCR 11	/*
-					 * log(B/Smin)/log(B/(B-1))+1,
-					 * Smin:min increment
-					 * B:log factor
-					 */
-#define BICTCP_B		4	 /*
-					  * In binary search,
-					  * go to point (max+min)/N
-					  */
-
 /*
  *	TCP option
  */
@@ -563,7 +545,6 @@ static __inline__ int tcp_sk_listen_hash
 #define TCP_NAGLE_PUSH		4	/* Cork is overriden for already queued data */
 
 /* sysctl variables for tcp */
-extern int sysctl_max_syn_backlog;
 extern int sysctl_tcp_timestamps;
 extern int sysctl_tcp_window_scaling;
 extern int sysctl_tcp_sack;
@@ -596,16 +577,7 @@ extern int sysctl_tcp_adv_win_scale;
 extern int sysctl_tcp_tw_reuse;
 extern int sysctl_tcp_frto;
 extern int sysctl_tcp_low_latency;
-extern int sysctl_tcp_westwood;
-extern int sysctl_tcp_vegas_cong_avoid;
-extern int sysctl_tcp_vegas_alpha;
-extern int sysctl_tcp_vegas_beta;
-extern int sysctl_tcp_vegas_gamma;
 extern int sysctl_tcp_nometrics_save;
-extern int sysctl_tcp_bic;
-extern int sysctl_tcp_bic_fast_convergence;
-extern int sysctl_tcp_bic_low_window;
-extern int sysctl_tcp_bic_beta;
 extern int sysctl_tcp_moderate_rcvbuf;
 extern int sysctl_tcp_tso_win_divisor;
 
@@ -613,74 +585,6 @@ extern atomic_t tcp_memory_allocated;
 extern atomic_t tcp_sockets_allocated;
 extern int tcp_memory_pressure;
 
-struct open_request;
-
-struct or_calltable {
-	int  family;
-	int  (*rtx_syn_ack)	(struct sock *sk, struct open_request *req, struct dst_entry*);
-	void (*send_ack)	(struct sk_buff *skb, struct open_request *req);
-	void (*destructor)	(struct open_request *req);
-	void (*send_reset)	(struct sk_buff *skb);
-};
-
-struct tcp_v4_open_req {
-	__u32			loc_addr;
-	__u32			rmt_addr;
-	struct ip_options	*opt;
-};
-
-#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
-struct tcp_v6_open_req {
-	struct in6_addr		loc_addr;
-	struct in6_addr		rmt_addr;
-	struct sk_buff		*pktopts;
-	int			iif;
-};
-#endif
-
-/* this structure is too big */
-struct open_request {
-	struct open_request	*dl_next; /* Must be first member! */
-	__u32			rcv_isn;
-	__u32			snt_isn;
-	__u16			rmt_port;
-	__u16			mss;
-	__u8			retrans;
-	__u8			__pad;
-	__u16	snd_wscale : 4, 
-		rcv_wscale : 4, 
-		tstamp_ok : 1,
-		sack_ok : 1,
-		wscale_ok : 1,
-		ecn_ok : 1,
-		acked : 1;
-	/* The following two fields can be easily recomputed I think -AK */
-	__u32			window_clamp;	/* window clamp at creation time */
-	__u32			rcv_wnd;	/* rcv_wnd offered first time */
-	__u32			ts_recent;
-	unsigned long		expires;
-	struct or_calltable	*class;
-	struct sock		*sk;
-	union {
-		struct tcp_v4_open_req v4_req;
-#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
-		struct tcp_v6_open_req v6_req;
-#endif
-	} af;
-};
-
-/* SLAB cache for open requests. */
-extern kmem_cache_t *tcp_openreq_cachep;
-
-#define tcp_openreq_alloc()		kmem_cache_alloc(tcp_openreq_cachep, SLAB_ATOMIC)
-#define tcp_openreq_fastfree(req)	kmem_cache_free(tcp_openreq_cachep, req)
-
-static inline void tcp_openreq_free(struct open_request *req)
-{
-	req->class->destructor(req);
-	tcp_openreq_fastfree(req);
-}
-
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 #define TCP_INET_FAMILY(fam) ((fam) == AF_INET)
 #else
@@ -708,7 +612,7 @@ struct tcp_func {
 
 	struct sock *		(*syn_recv_sock)	(struct sock *sk,
 							 struct sk_buff *skb,
-							 struct open_request *req,
+							 struct request_sock *req,
 							 struct dst_entry *dst);
     
 	int			(*remember_stamp)	(struct sock *sk);
@@ -817,11 +721,16 @@ static inline int tcp_ack_scheduled(stru
 	return tp->ack.pending&TCP_ACK_SCHED;
 }
 
-static __inline__ void tcp_dec_quickack_mode(struct tcp_sock *tp)
+static __inline__ void tcp_dec_quickack_mode(struct tcp_sock *tp, unsigned int pkts)
 {
-	if (tp->ack.quick && --tp->ack.quick == 0) {
-		/* Leaving quickack mode we deflate ATO. */
-		tp->ack.ato = TCP_ATO_MIN;
+	if (tp->ack.quick) {
+		if (pkts >= tp->ack.quick) {
+			tp->ack.quick = 0;
+
+			/* Leaving quickack mode we deflate ATO. */
+			tp->ack.ato = TCP_ATO_MIN;
+		} else
+			tp->ack.quick -= pkts;
 	}
 }
 
@@ -852,8 +761,8 @@ extern enum tcp_tw_status	tcp_timewait_s
 							   unsigned len);
 
 extern struct sock *		tcp_check_req(struct sock *sk,struct sk_buff *skb,
-					      struct open_request *req,
-					      struct open_request **prev);
+					      struct request_sock *req,
+					      struct request_sock **prev);
 extern int			tcp_child_process(struct sock *parent,
 						  struct sock *child,
 						  struct sk_buff *skb);
@@ -903,12 +812,12 @@ extern int			tcp_v4_conn_request(struct 
 						    struct sk_buff *skb);
 
 extern struct sock *		tcp_create_openreq_child(struct sock *sk,
-							 struct open_request *req,
+							 struct request_sock *req,
 							 struct sk_buff *skb);
 
 extern struct sock *		tcp_v4_syn_recv_sock(struct sock *sk,
 						     struct sk_buff *skb,
-						     struct open_request *req,
+						     struct request_sock *req,
 							struct dst_entry *dst);
 
 extern int			tcp_v4_do_rcv(struct sock *sk,
@@ -922,7 +831,7 @@ extern int			tcp_connect(struct sock *sk
 
 extern struct sk_buff *		tcp_make_synack(struct sock *sk,
 						struct dst_entry *dst,
-						struct open_request *req);
+						struct request_sock *req);
 
 extern int			tcp_disconnect(struct sock *sk, int flags);
 
@@ -939,7 +848,9 @@ extern __u32 cookie_v4_init_sequence(str
 
 /* tcp_output.c */
 
-extern int tcp_write_xmit(struct sock *, int nonagle);
+extern void __tcp_push_pending_frames(struct sock *sk, struct tcp_sock *tp,
+				      unsigned int cur_mss, int nonagle);
+extern int tcp_may_send_now(struct sock *sk, struct tcp_sock *tp);
 extern int tcp_retransmit_skb(struct sock *, struct sk_buff *);
 extern void tcp_xmit_retransmit_queue(struct sock *);
 extern void tcp_simple_retransmit(struct sock *);
@@ -949,12 +860,16 @@ extern void tcp_send_probe0(struct sock 
 extern void tcp_send_partial(struct sock *);
 extern int  tcp_write_wakeup(struct sock *);
 extern void tcp_send_fin(struct sock *sk);
-extern void tcp_send_active_reset(struct sock *sk, int priority);
+extern void tcp_send_active_reset(struct sock *sk,
+                                  unsigned int __nocast priority);
 extern int  tcp_send_synack(struct sock *);
-extern void tcp_push_one(struct sock *, unsigned mss_now);
+extern void tcp_push_one(struct sock *, unsigned int mss_now);
 extern void tcp_send_ack(struct sock *sk);
 extern void tcp_send_delayed_ack(struct sock *sk);
 
+/* tcp_input.c */
+extern void tcp_cwnd_application_limited(struct sock *sk);
+
 /* tcp_timer.c */
 extern void tcp_init_xmit_timers(struct sock *);
 extern void tcp_clear_xmit_timers(struct sock *);
@@ -1054,7 +969,7 @@ static inline void tcp_reset_xmit_timer(
 static inline void tcp_initialize_rcv_mss(struct sock *sk)
 {
 	struct tcp_sock *tp = tcp_sk(sk);
-	unsigned int hint = min(tp->advmss, tp->mss_cache_std);
+	unsigned int hint = min_t(unsigned int, tp->advmss, tp->mss_cache);
 
 	hint = min(hint, tp->rcv_wnd/2);
 	hint = min(hint, TCP_MIN_RCVMSS);
@@ -1077,7 +992,7 @@ static __inline__ void tcp_fast_path_on(
 
 static inline void tcp_fast_path_check(struct sock *sk, struct tcp_sock *tp)
 {
-	if (skb_queue_len(&tp->out_of_order_queue) == 0 &&
+	if (skb_queue_empty(&tp->out_of_order_queue) &&
 	    tp->rcv_wnd &&
 	    atomic_read(&sk->sk_rmem_alloc) < sk->sk_rcvbuf &&
 	    !tp->urg_data)
@@ -1204,6 +1119,82 @@ static inline void tcp_packets_out_dec(s
 	tp->packets_out -= tcp_skb_pcount(skb);
 }
 
+/* Events passed to congestion control interface */
+enum tcp_ca_event {
+	CA_EVENT_TX_START,	/* first transmit when no packets in flight */
+	CA_EVENT_CWND_RESTART,	/* congestion window restart */
+	CA_EVENT_COMPLETE_CWR,	/* end of congestion recovery */
+	CA_EVENT_FRTO,		/* fast recovery timeout */
+	CA_EVENT_LOSS,		/* loss timeout */
+	CA_EVENT_FAST_ACK,	/* in sequence ack */
+	CA_EVENT_SLOW_ACK,	/* other ack */
+};
+
+/*
+ * Interface for adding new TCP congestion control handlers
+ */
+#define TCP_CA_NAME_MAX	16
+struct tcp_congestion_ops {
+	struct list_head	list;
+
+	/* initialize private data (optional) */
+	void (*init)(struct tcp_sock *tp);
+	/* cleanup private data  (optional) */
+	void (*release)(struct tcp_sock *tp);
+
+	/* return slow start threshold (required) */
+	u32 (*ssthresh)(struct tcp_sock *tp);
+	/* lower bound for congestion window (optional) */
+	u32 (*min_cwnd)(struct tcp_sock *tp);
+	/* do new cwnd calculation (required) */
+	void (*cong_avoid)(struct tcp_sock *tp, u32 ack,
+			   u32 rtt, u32 in_flight, int good_ack);
+	/* round trip time sample per acked packet (optional) */
+	void (*rtt_sample)(struct tcp_sock *tp, u32 usrtt);
+	/* call before changing ca_state (optional) */
+	void (*set_state)(struct tcp_sock *tp, u8 new_state);
+	/* call when cwnd event occurs (optional) */
+	void (*cwnd_event)(struct tcp_sock *tp, enum tcp_ca_event ev);
+	/* new value of cwnd after loss (optional) */
+	u32  (*undo_cwnd)(struct tcp_sock *tp);
+	/* hook for packet ack accounting (optional) */
+	void (*pkts_acked)(struct tcp_sock *tp, u32 num_acked);
+	/* get info for tcp_diag (optional) */
+	void (*get_info)(struct tcp_sock *tp, u32 ext, struct sk_buff *skb);
+
+	char 		name[TCP_CA_NAME_MAX];
+	struct module 	*owner;
+};
+
+extern int tcp_register_congestion_control(struct tcp_congestion_ops *type);
+extern void tcp_unregister_congestion_control(struct tcp_congestion_ops *type);
+
+extern void tcp_init_congestion_control(struct tcp_sock *tp);
+extern void tcp_cleanup_congestion_control(struct tcp_sock *tp);
+extern int tcp_set_default_congestion_control(const char *name);
+extern void tcp_get_default_congestion_control(char *name);
+extern int tcp_set_congestion_control(struct tcp_sock *tp, const char *name);
+
+extern struct tcp_congestion_ops tcp_init_congestion_ops;
+extern u32 tcp_reno_ssthresh(struct tcp_sock *tp);
+extern void tcp_reno_cong_avoid(struct tcp_sock *tp, u32 ack,
+				u32 rtt, u32 in_flight, int flag);
+extern u32 tcp_reno_min_cwnd(struct tcp_sock *tp);
+extern struct tcp_congestion_ops tcp_reno;
+
+static inline void tcp_set_ca_state(struct tcp_sock *tp, u8 ca_state)
+{
+	if (tp->ca_ops->set_state)
+		tp->ca_ops->set_state(tp, ca_state);
+	tp->ca_state = ca_state;
+}
+
+static inline void tcp_ca_event(struct tcp_sock *tp, enum tcp_ca_event event)
+{
+	if (tp->ca_ops->cwnd_event)
+		tp->ca_ops->cwnd_event(tp, event);
+}
+
 /* This determines how many packets are "in the network" to the best
  * of our knowledge.  In many cases it is conservative, but where
  * detailed information is available from the receiver (via SACK
@@ -1223,91 +1214,6 @@ static __inline__ unsigned int tcp_packe
 	return (tp->packets_out - tp->left_out + tp->retrans_out);
 }
 
-/*
- * Which congestion algorithim is in use on the connection.
- */
-#define tcp_is_vegas(__tp)	((__tp)->adv_cong == TCP_VEGAS)
-#define tcp_is_westwood(__tp)	((__tp)->adv_cong == TCP_WESTWOOD)
-#define tcp_is_bic(__tp)	((__tp)->adv_cong == TCP_BIC)
-
-/* Recalculate snd_ssthresh, we want to set it to:
- *
- * Reno:
- * 	one half the current congestion window, but no
- *	less than two segments
- *
- * BIC:
- *	behave like Reno until low_window is reached,
- *	then increase congestion window slowly
- */
-static inline __u32 tcp_recalc_ssthresh(struct tcp_sock *tp)
-{
-	if (tcp_is_bic(tp)) {
-		if (sysctl_tcp_bic_fast_convergence &&
-		    tp->snd_cwnd < tp->bictcp.last_max_cwnd)
-			tp->bictcp.last_max_cwnd = (tp->snd_cwnd * 
-						    (BICTCP_BETA_SCALE
-						     + sysctl_tcp_bic_beta))
-				/ (2 * BICTCP_BETA_SCALE);
-		else
-			tp->bictcp.last_max_cwnd = tp->snd_cwnd;
-
-		if (tp->snd_cwnd > sysctl_tcp_bic_low_window)
-			return max((tp->snd_cwnd * sysctl_tcp_bic_beta)
-				   / BICTCP_BETA_SCALE, 2U);
-	}
-
-	return max(tp->snd_cwnd >> 1U, 2U);
-}
-
-/* Stop taking Vegas samples for now. */
-#define tcp_vegas_disable(__tp)	((__tp)->vegas.doing_vegas_now = 0)
-    
-static inline void tcp_vegas_enable(struct tcp_sock *tp)
-{
-	/* There are several situations when we must "re-start" Vegas:
-	 *
-	 *  o when a connection is established
-	 *  o after an RTO
-	 *  o after fast recovery
-	 *  o when we send a packet and there is no outstanding
-	 *    unacknowledged data (restarting an idle connection)
-	 *
-	 * In these circumstances we cannot do a Vegas calculation at the
-	 * end of the first RTT, because any calculation we do is using
-	 * stale info -- both the saved cwnd and congestion feedback are
-	 * stale.
-	 *
-	 * Instead we must wait until the completion of an RTT during
-	 * which we actually receive ACKs.
-	 */
-    
-	/* Begin taking Vegas samples next time we send something. */
-	tp->vegas.doing_vegas_now = 1;
-     
-	/* Set the beginning of the next send window. */
-	tp->vegas.beg_snd_nxt = tp->snd_nxt;
-
-	tp->vegas.cntRTT = 0;
-	tp->vegas.minRTT = 0x7fffffff;
-}
-
-/* Should we be taking Vegas samples right now? */
-#define tcp_vegas_enabled(__tp)	((__tp)->vegas.doing_vegas_now)
-
-extern void tcp_ca_init(struct tcp_sock *tp);
-
-static inline void tcp_set_ca_state(struct tcp_sock *tp, u8 ca_state)
-{
-	if (tcp_is_vegas(tp)) {
-		if (ca_state == TCP_CA_Open) 
-			tcp_vegas_enable(tp);
-		else
-			tcp_vegas_disable(tp);
-	}
-	tp->ca_state = ca_state;
-}
-
 /* If cwnd > ssthresh, we may raise ssthresh to be half-way to cwnd.
  * The exception is rate halving phase, when cwnd is decreasing towards
  * ssthresh.
@@ -1330,33 +1236,11 @@ static inline void tcp_sync_left_out(str
 	tp->left_out = tp->sacked_out + tp->lost_out;
 }
 
-extern void tcp_cwnd_application_limited(struct sock *sk);
-
-/* Congestion window validation. (RFC2861) */
-
-static inline void tcp_cwnd_validate(struct sock *sk, struct tcp_sock *tp)
-{
-	__u32 packets_out = tp->packets_out;
-
-	if (packets_out >= tp->snd_cwnd) {
-		/* Network is feed fully. */
-		tp->snd_cwnd_used = 0;
-		tp->snd_cwnd_stamp = tcp_time_stamp;
-	} else {
-		/* Network starves. */
-		if (tp->packets_out > tp->snd_cwnd_used)
-			tp->snd_cwnd_used = tp->packets_out;
-
-		if ((s32)(tcp_time_stamp - tp->snd_cwnd_stamp) >= tp->rto)
-			tcp_cwnd_application_limited(sk);
-	}
-}
-
-/* Set slow start threshould and cwnd not falling to slow start */
+/* Set slow start threshold and cwnd not falling to slow start */
 static inline void __tcp_enter_cwr(struct tcp_sock *tp)
 {
 	tp->undo_marker = 0;
-	tp->snd_ssthresh = tcp_recalc_ssthresh(tp);
+	tp->snd_ssthresh = tp->ca_ops->ssthresh(tp);
 	tp->snd_cwnd = min(tp->snd_cwnd,
 			   tcp_packets_in_flight(tp) + 1U);
 	tp->snd_cwnd_cnt = 0;
@@ -1384,12 +1268,6 @@ static __inline__ __u32 tcp_max_burst(co
 	return 3;
 }
 
-static __inline__ int tcp_minshall_check(const struct tcp_sock *tp)
-{
-	return after(tp->snd_sml,tp->snd_una) &&
-		!after(tp->snd_sml, tp->snd_nxt);
-}
-
 static __inline__ void tcp_minshall_update(struct tcp_sock *tp, int mss, 
 					   const struct sk_buff *skb)
 {
@@ -1397,122 +1275,18 @@ static __inline__ void tcp_minshall_upda
 		tp->snd_sml = TCP_SKB_CB(skb)->end_seq;
 }
 
-/* Return 0, if packet can be sent now without violation Nagle's rules:
-   1. It is full sized.
-   2. Or it contains FIN.
-   3. Or TCP_NODELAY was set.
-   4. Or TCP_CORK is not set, and all sent packets are ACKed.
-      With Minshall's modification: all sent small packets are ACKed.
- */
-
-static __inline__ int
-tcp_nagle_check(const struct tcp_sock *tp, const struct sk_buff *skb, 
-		unsigned mss_now, int nonagle)
-{
-	return (skb->len < mss_now &&
-		!(TCP_SKB_CB(skb)->flags & TCPCB_FLAG_FIN) &&
-		((nonagle&TCP_NAGLE_CORK) ||
-		 (!nonagle &&
-		  tp->packets_out &&
-		  tcp_minshall_check(tp))));
-}
-
-extern void tcp_set_skb_tso_segs(struct sock *, struct sk_buff *);
-
-/* This checks if the data bearing packet SKB (usually sk->sk_send_head)
- * should be put on the wire right now.
- */
-static __inline__ int tcp_snd_test(struct sock *sk,
-				   struct sk_buff *skb,
-				   unsigned cur_mss, int nonagle)
-{
-	struct tcp_sock *tp = tcp_sk(sk);
-	int pkts = tcp_skb_pcount(skb);
-
-	if (!pkts) {
-		tcp_set_skb_tso_segs(sk, skb);
-		pkts = tcp_skb_pcount(skb);
-	}
-
-	/*	RFC 1122 - section 4.2.3.4
-	 *
-	 *	We must queue if
-	 *
-	 *	a) The right edge of this frame exceeds the window
-	 *	b) There are packets in flight and we have a small segment
-	 *	   [SWS avoidance and Nagle algorithm]
-	 *	   (part of SWS is done on packetization)
-	 *	   Minshall version sounds: there are no _small_
-	 *	   segments in flight. (tcp_nagle_check)
-	 *	c) We have too many packets 'in flight'
-	 *
-	 * 	Don't use the nagle rule for urgent data (or
-	 *	for the final FIN -DaveM).
-	 *
-	 *	Also, Nagle rule does not apply to frames, which
-	 *	sit in the middle of queue (they have no chances
-	 *	to get new data) and if room at tail of skb is
-	 *	not enough to save something seriously (<32 for now).
-	 */
-
-	/* Don't be strict about the congestion window for the
-	 * final FIN frame.  -DaveM
-	 */
-	return (((nonagle&TCP_NAGLE_PUSH) || tp->urg_mode
-		 || !tcp_nagle_check(tp, skb, cur_mss, nonagle)) &&
-		(((tcp_packets_in_flight(tp) + (pkts-1)) < tp->snd_cwnd) ||
-		 (TCP_SKB_CB(skb)->flags & TCPCB_FLAG_FIN)) &&
-		!after(TCP_SKB_CB(skb)->end_seq, tp->snd_una + tp->snd_wnd));
-}
-
 static __inline__ void tcp_check_probe_timer(struct sock *sk, struct tcp_sock *tp)
 {
 	if (!tp->packets_out && !tp->pending)
 		tcp_reset_xmit_timer(sk, TCP_TIME_PROBE0, tp->rto);
 }
 
-static __inline__ int tcp_skb_is_last(const struct sock *sk, 
-				      const struct sk_buff *skb)
-{
-	return skb->next == (struct sk_buff *)&sk->sk_write_queue;
-}
-
-/* Push out any pending frames which were held back due to
- * TCP_CORK or attempt at coalescing tiny packets.
- * The socket must be locked by the caller.
- */
-static __inline__ void __tcp_push_pending_frames(struct sock *sk,
-						 struct tcp_sock *tp,
-						 unsigned cur_mss,
-						 int nonagle)
-{
-	struct sk_buff *skb = sk->sk_send_head;
-
-	if (skb) {
-		if (!tcp_skb_is_last(sk, skb))
-			nonagle = TCP_NAGLE_PUSH;
-		if (!tcp_snd_test(sk, skb, cur_mss, nonagle) ||
-		    tcp_write_xmit(sk, nonagle))
-			tcp_check_probe_timer(sk, tp);
-	}
-	tcp_cwnd_validate(sk, tp);
-}
-
 static __inline__ void tcp_push_pending_frames(struct sock *sk,
 					       struct tcp_sock *tp)
 {
 	__tcp_push_pending_frames(sk, tp, tcp_current_mss(sk, 1), tp->nonagle);
 }
 
-static __inline__ int tcp_may_send_now(struct sock *sk, struct tcp_sock *tp)
-{
-	struct sk_buff *skb = sk->sk_send_head;
-
-	return (skb &&
-		tcp_snd_test(sk, skb, tcp_current_mss(sk, 1),
-			     tcp_skb_is_last(sk, skb) ? TCP_NAGLE_PUSH : tp->nonagle));
-}
-
 static __inline__ void tcp_init_wl(struct tcp_sock *tp, u32 ack, u32 seq)
 {
 	tp->snd_wl1 = seq;
@@ -1750,99 +1524,71 @@ static inline int tcp_full_space(const s
 	return tcp_win_from_space(sk->sk_rcvbuf); 
 }
 
-static inline void tcp_acceptq_queue(struct sock *sk, struct open_request *req,
+static inline void tcp_acceptq_queue(struct sock *sk, struct request_sock *req,
 					 struct sock *child)
 {
-	struct tcp_sock *tp = tcp_sk(sk);
-
-	req->sk = child;
-	sk_acceptq_added(sk);
-
-	if (!tp->accept_queue_tail) {
-		tp->accept_queue = req;
-	} else {
-		tp->accept_queue_tail->dl_next = req;
-	}
-	tp->accept_queue_tail = req;
-	req->dl_next = NULL;
+	reqsk_queue_add(&tcp_sk(sk)->accept_queue, req, sk, child);
 }
 
-struct tcp_listen_opt
-{
-	u8			max_qlen_log;	/* log_2 of maximal queued SYNs */
-	int			qlen;
-	int			qlen_young;
-	int			clock_hand;
-	u32			hash_rnd;
-	struct open_request	*syn_table[TCP_SYNQ_HSIZE];
-};
-
 static inline void
-tcp_synq_removed(struct sock *sk, struct open_request *req)
+tcp_synq_removed(struct sock *sk, struct request_sock *req)
 {
-	struct tcp_listen_opt *lopt = tcp_sk(sk)->listen_opt;
-
-	if (--lopt->qlen == 0)
+	if (reqsk_queue_removed(&tcp_sk(sk)->accept_queue, req) == 0)
 		tcp_delete_keepalive_timer(sk);
-	if (req->retrans == 0)
-		lopt->qlen_young--;
 }
 
 static inline void tcp_synq_added(struct sock *sk)
 {
-	struct tcp_listen_opt *lopt = tcp_sk(sk)->listen_opt;
-
-	if (lopt->qlen++ == 0)
+	if (reqsk_queue_added(&tcp_sk(sk)->accept_queue) == 0)
 		tcp_reset_keepalive_timer(sk, TCP_TIMEOUT_INIT);
-	lopt->qlen_young++;
 }
 
 static inline int tcp_synq_len(struct sock *sk)
 {
-	return tcp_sk(sk)->listen_opt->qlen;
+	return reqsk_queue_len(&tcp_sk(sk)->accept_queue);
 }
 
 static inline int tcp_synq_young(struct sock *sk)
 {
-	return tcp_sk(sk)->listen_opt->qlen_young;
+	return reqsk_queue_len_young(&tcp_sk(sk)->accept_queue);
 }
 
 static inline int tcp_synq_is_full(struct sock *sk)
 {
-	return tcp_synq_len(sk) >> tcp_sk(sk)->listen_opt->max_qlen_log;
+	return reqsk_queue_is_full(&tcp_sk(sk)->accept_queue);
 }
 
-static inline void tcp_synq_unlink(struct tcp_sock *tp, struct open_request *req,
-				       struct open_request **prev)
+static inline void tcp_synq_unlink(struct tcp_sock *tp, struct request_sock *req,
+				   struct request_sock **prev)
 {
-	write_lock(&tp->syn_wait_lock);
-	*prev = req->dl_next;
-	write_unlock(&tp->syn_wait_lock);
+	reqsk_queue_unlink(&tp->accept_queue, req, prev);
 }
 
-static inline void tcp_synq_drop(struct sock *sk, struct open_request *req,
-				     struct open_request **prev)
+static inline void tcp_synq_drop(struct sock *sk, struct request_sock *req,
+				     struct request_sock **prev)
 {
 	tcp_synq_unlink(tcp_sk(sk), req, prev);
 	tcp_synq_removed(sk, req);
-	tcp_openreq_free(req);
+	reqsk_free(req);
 }
 
-static __inline__ void tcp_openreq_init(struct open_request *req,
+static __inline__ void tcp_openreq_init(struct request_sock *req,
 					struct tcp_options_received *rx_opt,
 					struct sk_buff *skb)
 {
+	struct inet_request_sock *ireq = inet_rsk(req);
+
 	req->rcv_wnd = 0;		/* So that tcp_send_synack() knows! */
-	req->rcv_isn = TCP_SKB_CB(skb)->seq;
+	tcp_rsk(req)->rcv_isn = TCP_SKB_CB(skb)->seq;
 	req->mss = rx_opt->mss_clamp;
 	req->ts_recent = rx_opt->saw_tstamp ? rx_opt->rcv_tsval : 0;
-	req->tstamp_ok = rx_opt->tstamp_ok;
-	req->sack_ok = rx_opt->sack_ok;
-	req->snd_wscale = rx_opt->snd_wscale;
-	req->wscale_ok = rx_opt->wscale_ok;
-	req->acked = 0;
-	req->ecn_ok = 0;
-	req->rmt_port = skb->h.th->source;
+	ireq->tstamp_ok = rx_opt->tstamp_ok;
+	ireq->sack_ok = rx_opt->sack_ok;
+	ireq->snd_wscale = rx_opt->snd_wscale;
+	ireq->wscale_ok = rx_opt->wscale_ok;
+	ireq->acked = 0;
+	ireq->ecn_ok = 0;
+	ireq->rmt_port = skb->h.th->source;
 }
 
 extern void tcp_enter_memory_pressure(void);
@@ -1972,52 +1718,4 @@ struct tcp_iter_state {
 extern int tcp_proc_register(struct tcp_seq_afinfo *afinfo);
 extern void tcp_proc_unregister(struct tcp_seq_afinfo *afinfo);
 
-/* TCP Westwood functions and constants */
-
-#define TCP_WESTWOOD_INIT_RTT  (20*HZ)           /* maybe too conservative?! */
-#define TCP_WESTWOOD_RTT_MIN   (HZ/20)           /* 50ms */
-
-static inline void tcp_westwood_update_rtt(struct tcp_sock *tp, __u32 rtt_seq)
-{
-        if (tcp_is_westwood(tp))
-                tp->westwood.rtt = rtt_seq;
-}
-
-static inline __u32 __tcp_westwood_bw_rttmin(const struct tcp_sock *tp)
-{
-        return max((tp->westwood.bw_est) * (tp->westwood.rtt_min) /
-		   (__u32) (tp->mss_cache_std),
-		   2U);
-}
-
-static inline __u32 tcp_westwood_bw_rttmin(const struct tcp_sock *tp)
-{
-	return tcp_is_westwood(tp) ? __tcp_westwood_bw_rttmin(tp) : 0;
-}
-
-static inline int tcp_westwood_ssthresh(struct tcp_sock *tp)
-{
-	__u32 ssthresh = 0;
-
-	if (tcp_is_westwood(tp)) {
-		ssthresh = __tcp_westwood_bw_rttmin(tp);
-		if (ssthresh)
-			tp->snd_ssthresh = ssthresh;  
-	}
-
-	return (ssthresh != 0);
-}
-
-static inline int tcp_westwood_cwnd(struct tcp_sock *tp)
-{
-	__u32 cwnd = 0;
-
-	if (tcp_is_westwood(tp)) {
-		cwnd = __tcp_westwood_bw_rttmin(tp);
-		if (cwnd)
-			tp->snd_cwnd = cwnd;
-	}
-
-	return (cwnd != 0);
-}
 #endif	/* _TCP_H */
diff --git a/include/net/tcp_ecn.h b/include/net/tcp_ecn.h
--- a/include/net/tcp_ecn.h
+++ b/include/net/tcp_ecn.h
@@ -2,6 +2,7 @@
 #define _NET_TCP_ECN_H_ 1
 
 #include <net/inet_ecn.h>
+#include <net/request_sock.h>
 
 #define TCP_HP_BITS (~(TCP_RESERVED_BITS|TCP_FLAG_PSH))
 
@@ -38,9 +39,9 @@ static inline void TCP_ECN_send_syn(stru
 }
 
 static __inline__ void
-TCP_ECN_make_synack(struct open_request *req, struct tcphdr *th)
+TCP_ECN_make_synack(struct request_sock *req, struct tcphdr *th)
 {
-	if (req->ecn_ok)
+	if (inet_rsk(req)->ecn_ok)
 		th->ece = 1;
 }
 
@@ -111,16 +112,16 @@ static inline int TCP_ECN_rcv_ecn_echo(s
 }
 
 static inline void TCP_ECN_openreq_child(struct tcp_sock *tp,
-					 struct open_request *req)
+					 struct request_sock *req)
 {
-	tp->ecn_flags = req->ecn_ok ? TCP_ECN_OK : 0;
+	tp->ecn_flags = inet_rsk(req)->ecn_ok ? TCP_ECN_OK : 0;
 }
 
 static __inline__ void
-TCP_ECN_create_request(struct open_request *req, struct tcphdr *th)
+TCP_ECN_create_request(struct request_sock *req, struct tcphdr *th)
 {
 	if (sysctl_tcp_ecn && th->ece && th->cwr)
-		req->ecn_ok = 1;
+		inet_rsk(req)->ecn_ok = 1;
 }
 
 #endif
diff --git a/include/net/x25.h b/include/net/x25.h
--- a/include/net/x25.h
+++ b/include/net/x25.h
@@ -79,6 +79,8 @@ enum {
 #define	X25_DEFAULT_PACKET_SIZE	X25_PS128		/* Default Packet Size */
 #define	X25_DEFAULT_THROUGHPUT	0x0A			/* Deafult Throughput */
 #define	X25_DEFAULT_REVERSE	0x00			/* Default Reverse Charging */
+#define X25_DENY_ACCPT_APPRV   0x01			/* Default value */
+#define X25_ALLOW_ACCPT_APPRV  0x00			/* Control enabled */
 
 #define X25_SMODULUS 		8
 #define	X25_EMODULUS		128
@@ -94,7 +96,7 @@ enum {
 #define	X25_FAC_CLASS_C		0x80
 #define	X25_FAC_CLASS_D		0xC0
 
-#define	X25_FAC_REVERSE		0x01
+#define	X25_FAC_REVERSE		0x01			/* also fast select */
 #define	X25_FAC_THROUGHPUT	0x02
 #define	X25_FAC_PACKET_SIZE	0x42
 #define	X25_FAC_WINDOW_SIZE	0x43
@@ -134,8 +136,8 @@ struct x25_sock {
 	struct sock		sk;
 	struct x25_address	source_addr, dest_addr;
 	struct x25_neigh	*neighbour;
-	unsigned int		lci;
-	unsigned char		state, condition, qbitincl, intflag;
+	unsigned int		lci, cudmatchlength;
+	unsigned char		state, condition, qbitincl, intflag, accptapprv;
 	unsigned short		vs, vr, va, vl;
 	unsigned long		t2, t21, t22, t23;
 	unsigned short		fraglen;
@@ -242,7 +244,6 @@ extern int  x25_validate_nr(struct sock 
 extern void x25_write_internal(struct sock *, int);
 extern int  x25_decode(struct sock *, struct sk_buff *, int *, int *, int *, int *, int *);
 extern void x25_disconnect(struct sock *, int, unsigned char, unsigned char);
-extern int x25_check_calluserdata(struct x25_calluserdata *,struct x25_calluserdata *);
 
 /* x25_timer.c */
 extern void x25_start_heartbeat(struct sock *);
diff --git a/include/net/x25device.h b/include/net/x25device.h
--- a/include/net/x25device.h
+++ b/include/net/x25device.h
@@ -5,8 +5,7 @@
 #include <linux/if_packet.h>
 #include <linux/skbuff.h>
 
-static inline unsigned short x25_type_trans(struct sk_buff *skb,
-					    struct net_device *dev)
+static inline __be16 x25_type_trans(struct sk_buff *skb, struct net_device *dev)
 {
 	skb->mac.raw = skb->data;
 	skb->input_dev = skb->dev = dev;
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -158,6 +158,20 @@ enum {
 	XFRM_STATE_DEAD
 };
 
+/* callback structure passed from either netlink or pfkey */
+struct km_event
+{
+	union {
+		u32 hard;
+		u32 proto;
+		u32 byid;
+	} data;
+
+	u32	seq;
+	u32	pid;
+	u32	event;
+};
+
 struct xfrm_type;
 struct xfrm_dst;
 struct xfrm_policy_afinfo {
@@ -179,6 +193,8 @@ struct xfrm_policy_afinfo {
 
 extern int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo);
 extern int xfrm_policy_unregister_afinfo(struct xfrm_policy_afinfo *afinfo);
+extern void km_policy_notify(struct xfrm_policy *xp, int dir, struct km_event *c);
+extern void km_state_notify(struct xfrm_state *x, struct km_event *c);
 
 #define XFRM_ACQ_EXPIRES	30
 
@@ -188,6 +204,7 @@ struct xfrm_state_afinfo {
 	rwlock_t		lock;
 	struct list_head	*state_bydst;
 	struct list_head	*state_byspi;
+	int			(*init_flags)(struct xfrm_state *x);
 	void			(*init_tempsel)(struct xfrm_state *x, struct flowi *fl,
 						struct xfrm_tmpl *tmpl,
 						xfrm_address_t *daddr, xfrm_address_t *saddr);
@@ -209,7 +226,7 @@ struct xfrm_type
 	struct module		*owner;
 	__u8			proto;
 
-	int			(*init_state)(struct xfrm_state *x, void *args);
+	int			(*init_state)(struct xfrm_state *x);
 	void			(*destructor)(struct xfrm_state *);
 	int			(*input)(struct xfrm_state *, struct xfrm_decap_state *, struct sk_buff *skb);
 	int			(*post_input)(struct xfrm_state *, struct xfrm_decap_state *, struct sk_buff *skb);
@@ -290,11 +307,11 @@ struct xfrm_mgr
 {
 	struct list_head	list;
 	char			*id;
-	int			(*notify)(struct xfrm_state *x, int event);
+	int			(*notify)(struct xfrm_state *x, struct km_event *c);
 	int			(*acquire)(struct xfrm_state *x, struct xfrm_tmpl *, struct xfrm_policy *xp, int dir);
 	struct xfrm_policy	*(*compile_policy)(u16 family, int opt, u8 *data, int len, int *dir);
 	int			(*new_mapping)(struct xfrm_state *x, xfrm_address_t *ipaddr, u16 sport);
-	int			(*notify_policy)(struct xfrm_policy *x, int dir, int event);
+	int			(*notify_policy)(struct xfrm_policy *x, int dir, struct km_event *c);
 };
 
 extern int xfrm_register_km(struct xfrm_mgr *km);
@@ -656,7 +673,7 @@ static inline int xfrm_sk_clone_policy(s
 	return 0;
 }
 
-extern void xfrm_policy_delete(struct xfrm_policy *pol, int dir);
+extern int xfrm_policy_delete(struct xfrm_policy *pol, int dir);
 
 static inline void xfrm_sk_free_policy(struct sock *sk)
 {
@@ -786,7 +803,7 @@ struct xfrm_algo_desc {
 /* XFRM tunnel handlers.  */
 struct xfrm_tunnel {
 	int (*handler)(struct sk_buff *skb);
-	void (*err_handler)(struct sk_buff *skb, void *info);
+	void (*err_handler)(struct sk_buff *skb, __u32 info);
 };
 
 struct xfrm6_tunnel {
@@ -817,12 +834,13 @@ extern int xfrm_state_add(struct xfrm_st
 extern int xfrm_state_update(struct xfrm_state *x);
 extern struct xfrm_state *xfrm_state_lookup(xfrm_address_t *daddr, u32 spi, u8 proto, unsigned short family);
 extern struct xfrm_state *xfrm_find_acq_byseq(u32 seq);
-extern void xfrm_state_delete(struct xfrm_state *x);
+extern int xfrm_state_delete(struct xfrm_state *x);
 extern void xfrm_state_flush(u8 proto);
 extern int xfrm_replay_check(struct xfrm_state *x, u32 seq);
 extern void xfrm_replay_advance(struct xfrm_state *x, u32 seq);
 extern int xfrm_state_check(struct xfrm_state *x, struct sk_buff *skb);
 extern int xfrm_state_mtu(struct xfrm_state *x, int mtu);
+extern int xfrm_init_state(struct xfrm_state *x);
 extern int xfrm4_rcv(struct sk_buff *skb);
 extern int xfrm4_output(struct sk_buff *skb);
 extern int xfrm4_tunnel_register(struct xfrm_tunnel *handler);
diff --git a/include/pcmcia/ciscode.h b/include/pcmcia/ciscode.h
--- a/include/pcmcia/ciscode.h
+++ b/include/pcmcia/ciscode.h
@@ -112,6 +112,8 @@
 
 #define MANFID_TDK			0x0105
 #define PRODID_TDK_CF010		0x0900
+#define PRODID_TDK_NP9610		0x0d0a
+#define PRODID_TDK_MN3200		0x0e0a
 #define PRODID_TDK_GN3410		0x4815
 
 #define MANFID_TOSHIBA			0x0098
diff --git a/include/pcmcia/cs.h b/include/pcmcia/cs.h
--- a/include/pcmcia/cs.h
+++ b/include/pcmcia/cs.h
@@ -68,21 +68,9 @@ typedef struct adjust_t {
 #define RES_ALLOCATED			0x20
 #define RES_REMOVED			0x40
 
-typedef struct servinfo_t {
-    char	Signature[2];
-    u_int	Count;
-    u_int	Revision;
-    u_int	CSLevel;
-    char	*VendorString;
-} servinfo_t;
-
 typedef struct event_callback_args_t {
-    client_handle_t client_handle;
-    void	*info;
-    void	*mtdrequest;
-    void	*buffer;
-    void	*misc;
-    void	*client_data;
+	struct pcmcia_device	*client_handle;
+	void			*client_data;
 } event_callback_args_t;
 
 /* for GetConfigurationInfo */
@@ -393,31 +381,29 @@ enum service {
 
 struct pcmcia_socket;
 
-int pcmcia_access_configuration_register(client_handle_t handle, conf_reg_t *reg);
-int pcmcia_deregister_client(client_handle_t handle);
-int pcmcia_get_configuration_info(client_handle_t handle, config_info_t *config);
-int pcmcia_get_card_services_info(servinfo_t *info);
+int pcmcia_access_configuration_register(struct pcmcia_device *p_dev, conf_reg_t *reg);
+int pcmcia_deregister_client(struct pcmcia_device *p_dev);
+int pcmcia_get_configuration_info(struct pcmcia_device *p_dev, config_info_t *config);
 int pcmcia_get_first_window(window_handle_t *win, win_req_t *req);
 int pcmcia_get_next_window(window_handle_t *win, win_req_t *req);
-int pcmcia_get_status(client_handle_t handle, cs_status_t *status);
+int pcmcia_get_status(struct pcmcia_device *p_dev, cs_status_t *status);
 int pcmcia_get_mem_page(window_handle_t win, memreq_t *req);
 int pcmcia_map_mem_page(window_handle_t win, memreq_t *req);
-int pcmcia_modify_configuration(client_handle_t handle, modconf_t *mod);
+int pcmcia_modify_configuration(struct pcmcia_device *p_dev, modconf_t *mod);
 int pcmcia_register_client(client_handle_t *handle, client_reg_t *req);
-int pcmcia_release_configuration(client_handle_t handle);
-int pcmcia_release_io(client_handle_t handle, io_req_t *req);
-int pcmcia_release_irq(client_handle_t handle, irq_req_t *req);
+int pcmcia_release_configuration(struct pcmcia_device *p_dev);
+int pcmcia_release_io(struct pcmcia_device *p_dev, io_req_t *req);
+int pcmcia_release_irq(struct pcmcia_device *p_dev, irq_req_t *req);
 int pcmcia_release_window(window_handle_t win);
-int pcmcia_request_configuration(client_handle_t handle, config_req_t *req);
-int pcmcia_request_io(client_handle_t handle, io_req_t *req);
-int pcmcia_request_irq(client_handle_t handle, irq_req_t *req);
-int pcmcia_request_window(client_handle_t *handle, win_req_t *req, window_handle_t *wh);
-int pcmcia_reset_card(client_handle_t handle, client_req_t *req);
+int pcmcia_request_configuration(struct pcmcia_device *p_dev, config_req_t *req);
+int pcmcia_request_io(struct pcmcia_device *p_dev, io_req_t *req);
+int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req);
+int pcmcia_request_window(struct pcmcia_device **p_dev, win_req_t *req, window_handle_t *wh);
+int pcmcia_reset_card(struct pcmcia_device *p_dev, client_req_t *req);
 int pcmcia_suspend_card(struct pcmcia_socket *skt);
 int pcmcia_resume_card(struct pcmcia_socket *skt);
 int pcmcia_eject_card(struct pcmcia_socket *skt);
 int pcmcia_insert_card(struct pcmcia_socket *skt);
-int pcmcia_report_error(client_handle_t handle, error_info_t *err);
 
 struct pcmcia_socket * pcmcia_get_socket(struct pcmcia_socket *skt);
 void pcmcia_put_socket(struct pcmcia_socket *skt);
diff --git a/include/pcmcia/cs_types.h b/include/pcmcia/cs_types.h
--- a/include/pcmcia/cs_types.h
+++ b/include/pcmcia/cs_types.h
@@ -34,8 +34,8 @@ typedef u_int	event_t;
 typedef u_char	cisdata_t;
 typedef u_short	page_t;
 
-struct client_t;
-typedef struct client_t *client_handle_t;
+struct pcmcia_device;
+typedef struct pcmcia_device *client_handle_t;
 
 struct window_t;
 typedef struct window_t *window_handle_t;
diff --git a/include/pcmcia/device_id.h b/include/pcmcia/device_id.h
new file mode 100644
--- /dev/null
+++ b/include/pcmcia/device_id.h
@@ -0,0 +1,249 @@
+/*
+ * Copyright (2003-2004) 	Dominik Brodowski <linux@brodo.de>
+ *				David Woodhouse
+ *
+ * License: GPL v2
+ */
+
+#define PCMCIA_DEVICE_MANF_CARD(manf, card) { \
+	.match_flags = PCMCIA_DEV_ID_MATCH_MANF_ID| \
+			PCMCIA_DEV_ID_MATCH_CARD_ID, \
+	.manf_id = (manf), \
+	.card_id = (card), }
+
+#define PCMCIA_DEVICE_FUNC_ID(func) { \
+	.match_flags = PCMCIA_DEV_ID_MATCH_FUNC_ID, \
+	.func_id = (func), }
+
+#define PCMCIA_DEVICE_PROD_ID1(v1, vh1) { \
+	.match_flags = PCMCIA_DEV_ID_MATCH_PROD_ID1, \
+	.prod_id = { (v1), NULL, NULL, NULL }, \
+	.prod_id_hash = { (vh1), 0, 0, 0 }, }
+
+#define PCMCIA_DEVICE_PROD_ID2(v2, vh2) { \
+	.match_flags = PCMCIA_DEV_ID_MATCH_PROD_ID2, \
+	.prod_id = { NULL, (v2), NULL, NULL },  \
+	.prod_id_hash = { 0, (vh2), 0, 0 }, }
+
+#define PCMCIA_DEVICE_PROD_ID12(v1, v2, vh1, vh2) { \
+	.match_flags = PCMCIA_DEV_ID_MATCH_PROD_ID1| \
+			PCMCIA_DEV_ID_MATCH_PROD_ID2, \
+	.prod_id = { (v1), (v2), NULL, NULL }, \
+	.prod_id_hash = { (vh1), (vh2), 0, 0 }, }
+
+#define PCMCIA_DEVICE_PROD_ID13(v1, v3, vh1, vh3) { \
+	.match_flags = PCMCIA_DEV_ID_MATCH_PROD_ID1| \
+			PCMCIA_DEV_ID_MATCH_PROD_ID3, \
+	.prod_id = { (v1), NULL, (v3), NULL }, \
+	.prod_id_hash = { (vh1), 0, (vh3), 0 }, }
+
+#define PCMCIA_DEVICE_PROD_ID14(v1, v4, vh1, vh4) { \
+	.match_flags = PCMCIA_DEV_ID_MATCH_PROD_ID1| \
+			PCMCIA_DEV_ID_MATCH_PROD_ID4, \
+	.prod_id = { (v1), NULL, NULL, (v4) }, \
+	.prod_id_hash = { (vh1), 0, 0, (vh4) }, }
+
+#define PCMCIA_DEVICE_PROD_ID123(v1, v2, v3, vh1, vh2, vh3) { \
+	.match_flags = PCMCIA_DEV_ID_MATCH_PROD_ID1| \
+			PCMCIA_DEV_ID_MATCH_PROD_ID2| \
+			PCMCIA_DEV_ID_MATCH_PROD_ID3, \
+	.prod_id = { (v1), (v2), (v3), NULL },\
+	.prod_id_hash = { (vh1), (vh2), (vh3), 0 }, }
+
+#define PCMCIA_DEVICE_PROD_ID124(v1, v2, v4, vh1, vh2, vh4) { \
+	.match_flags = PCMCIA_DEV_ID_MATCH_PROD_ID1| \
+			PCMCIA_DEV_ID_MATCH_PROD_ID2| \
+			PCMCIA_DEV_ID_MATCH_PROD_ID4, \
+	.prod_id = { (v1), (v2), NULL, (v4) }, \
+	.prod_id_hash = { (vh1), (vh2), 0, (vh4) }, }
+
+#define PCMCIA_DEVICE_PROD_ID134(v1, v3, v4, vh1, vh3, vh4) { \
+	.match_flags = PCMCIA_DEV_ID_MATCH_PROD_ID1| \
+			PCMCIA_DEV_ID_MATCH_PROD_ID3| \
+			PCMCIA_DEV_ID_MATCH_PROD_ID4, \
+	.prod_id = { (v1), NULL, (v3), (v4) }, \
+	.prod_id_hash = { (vh1), 0, (vh3), (vh4) }, }
+
+#define PCMCIA_DEVICE_PROD_ID1234(v1, v2, v3, v4, vh1, vh2, vh3, vh4) { \
+	.match_flags = PCMCIA_DEV_ID_MATCH_PROD_ID1| \
+			PCMCIA_DEV_ID_MATCH_PROD_ID2| \
+			PCMCIA_DEV_ID_MATCH_PROD_ID3| \
+			PCMCIA_DEV_ID_MATCH_PROD_ID4, \
+	.prod_id = { (v1), (v2), (v3), (v4) }, \
+	.prod_id_hash = { (vh1), (vh2), (vh3), (vh4) }, }
+
+
+/* multi-function devices */
+
+#define PCMCIA_MFC_DEVICE_MANF_CARD(mfc, manf, card) { \
+	.match_flags = PCMCIA_DEV_ID_MATCH_MANF_ID| \
+			PCMCIA_DEV_ID_MATCH_CARD_ID| \
+			PCMCIA_DEV_ID_MATCH_FUNCTION, \
+	.manf_id = (manf), \
+	.card_id = (card), \
+	.function = (mfc), }
+
+#define PCMCIA_MFC_DEVICE_PROD_ID1(mfc, v1, vh1) { \
+	.match_flags = PCMCIA_DEV_ID_MATCH_PROD_ID1| \
+			PCMCIA_DEV_ID_MATCH_FUNCTION, \
+	.prod_id = { (v1), NULL, NULL, NULL }, \
+	.prod_id_hash = { (vh1), 0, 0, 0 }, \
+	.function = (mfc), }
+
+#define PCMCIA_MFC_DEVICE_PROD_ID2(mfc, v2, vh2) { \
+	.match_flags = PCMCIA_DEV_ID_MATCH_PROD_ID2| \
+			PCMCIA_DEV_ID_MATCH_FUNCTION, \
+	.prod_id = { NULL, (v2), NULL, NULL },  \
+	.prod_id_hash = { 0, (vh2), 0, 0 }, \
+	.function = (mfc), }
+
+#define PCMCIA_MFC_DEVICE_PROD_ID12(mfc, v1, v2, vh1, vh2) { \
+	.match_flags = PCMCIA_DEV_ID_MATCH_PROD_ID1| \
+			PCMCIA_DEV_ID_MATCH_PROD_ID2| \
+			PCMCIA_DEV_ID_MATCH_FUNCTION, \
+	.prod_id = { (v1), (v2), NULL, NULL }, \
+	.prod_id_hash = { (vh1), (vh2), 0, 0 }, \
+	.function = (mfc), }
+
+#define PCMCIA_MFC_DEVICE_PROD_ID13(mfc, v1, v3, vh1, vh3) { \
+	.match_flags = PCMCIA_DEV_ID_MATCH_PROD_ID1| \
+			PCMCIA_DEV_ID_MATCH_PROD_ID3| \
+			PCMCIA_DEV_ID_MATCH_FUNCTION, \
+	.prod_id = { (v1), NULL, (v3), NULL }, \
+	.prod_id_hash = { (vh1), 0, (vh3), 0 }, \
+	.function = (mfc), }
+
+#define PCMCIA_MFC_DEVICE_PROD_ID123(mfc, v1, v2, v3, vh1, vh2, vh3) { \
+	.match_flags = PCMCIA_DEV_ID_MATCH_PROD_ID1| \
+			PCMCIA_DEV_ID_MATCH_PROD_ID2| \
+			PCMCIA_DEV_ID_MATCH_PROD_ID3| \
+			PCMCIA_DEV_ID_MATCH_FUNCTION, \
+	.prod_id = { (v1), (v2), (v3), NULL },\
+	.prod_id_hash = { (vh1), (vh2), (vh3), 0 }, \
+	.function = (mfc), }
+
+/* pseudo multi-function devices */
+
+#define PCMCIA_PFC_DEVICE_MANF_CARD(mfc, manf, card) { \
+	.match_flags = PCMCIA_DEV_ID_MATCH_MANF_ID| \
+			PCMCIA_DEV_ID_MATCH_CARD_ID| \
+			PCMCIA_DEV_ID_MATCH_DEVICE_NO, \
+	.manf_id = (manf), \
+	.card_id = (card), \
+	.device_no = (mfc), }
+
+#define PCMCIA_PFC_DEVICE_PROD_ID1(mfc, v1, vh1) { \
+	.match_flags = PCMCIA_DEV_ID_MATCH_PROD_ID1| \
+			PCMCIA_DEV_ID_MATCH_DEVICE_NO, \
+	.prod_id = { (v1), NULL, NULL, NULL }, \
+	.prod_id_hash = { (vh1), 0, 0, 0 }, \
+	.device_no = (mfc), }
+
+#define PCMCIA_PFC_DEVICE_PROD_ID2(mfc, v2, vh2) { \
+	.match_flags = PCMCIA_DEV_ID_MATCH_PROD_ID2| \
+			PCMCIA_DEV_ID_MATCH_DEVICE_NO, \
+	.prod_id = { NULL, (v2), NULL, NULL },  \
+	.prod_id_hash = { 0, (vh2), 0, 0 }, \
+	.device_no = (mfc), }
+
+#define PCMCIA_PFC_DEVICE_PROD_ID12(mfc, v1, v2, vh1, vh2) { \
+	.match_flags = PCMCIA_DEV_ID_MATCH_PROD_ID1| \
+			PCMCIA_DEV_ID_MATCH_PROD_ID2| \
+			PCMCIA_DEV_ID_MATCH_DEVICE_NO, \
+	.prod_id = { (v1), (v2), NULL, NULL }, \
+	.prod_id_hash = { (vh1), (vh2), 0, 0 }, \
+	.device_no = (mfc), }
+
+#define PCMCIA_PFC_DEVICE_PROD_ID13(mfc, v1, v3, vh1, vh3) { \
+	.match_flags = PCMCIA_DEV_ID_MATCH_PROD_ID1| \
+			PCMCIA_DEV_ID_MATCH_PROD_ID3| \
+			PCMCIA_DEV_ID_MATCH_DEVICE_NO, \
+	.prod_id = { (v1), NULL, (v3), NULL }, \
+	.prod_id_hash = { (vh1), 0, (vh3), 0 }, \
+	.device_no = (mfc), }
+
+#define PCMCIA_PFC_DEVICE_PROD_ID123(mfc, v1, v2, v3, vh1, vh2, vh3) { \
+	.match_flags = PCMCIA_DEV_ID_MATCH_PROD_ID1| \
+			PCMCIA_DEV_ID_MATCH_PROD_ID2| \
+			PCMCIA_DEV_ID_MATCH_PROD_ID3| \
+			PCMCIA_DEV_ID_MATCH_DEVICE_NO, \
+	.prod_id = { (v1), (v2), (v3), NULL },\
+	.prod_id_hash = { (vh1), (vh2), (vh3), 0 }, \
+	.device_no = (mfc), }
+
+/* cards needing a CIS override */
+
+#define PCMCIA_DEVICE_CIS_MANF_CARD(manf, card, _cisfile) { \
+	.match_flags = PCMCIA_DEV_ID_MATCH_FAKE_CIS | \
+			PCMCIA_DEV_ID_MATCH_MANF_ID| \
+			PCMCIA_DEV_ID_MATCH_CARD_ID, \
+	.manf_id = (manf), \
+	.card_id = (card), \
+	.cisfile = (_cisfile)}
+
+#define PCMCIA_DEVICE_CIS_PROD_ID12(v1, v2, vh1, vh2, _cisfile) { \
+	.match_flags = PCMCIA_DEV_ID_MATCH_FAKE_CIS | \
+			PCMCIA_DEV_ID_MATCH_PROD_ID1| \
+			PCMCIA_DEV_ID_MATCH_PROD_ID2, \
+	.prod_id = { (v1), (v2), NULL, NULL }, \
+	.prod_id_hash = { (vh1), (vh2), 0, 0 }, \
+	.cisfile = (_cisfile)}
+
+#define PCMCIA_DEVICE_CIS_PROD_ID123(v1, v2, v3, vh1, vh2, vh3, _cisfile) { \
+	.match_flags = PCMCIA_DEV_ID_MATCH_FAKE_CIS | \
+			PCMCIA_DEV_ID_MATCH_PROD_ID1| \
+			PCMCIA_DEV_ID_MATCH_PROD_ID2| \
+			PCMCIA_DEV_ID_MATCH_PROD_ID3, \
+	.prod_id = { (v1), (v2), (v3), NULL },\
+	.prod_id_hash = { (vh1), (vh2), (vh3), 0 }, \
+	.cisfile = (_cisfile)}
+
+
+#define PCMCIA_DEVICE_CIS_PROD_ID2(v2, vh2, _cisfile) { \
+	.match_flags =  PCMCIA_DEV_ID_MATCH_FAKE_CIS | \
+			PCMCIA_DEV_ID_MATCH_PROD_ID2, \
+	.prod_id = { NULL, (v2), NULL, NULL },  \
+	.prod_id_hash = { 0, (vh2), 0, 0 }, \
+	.cisfile = (_cisfile)}
+
+#define PCMCIA_PFC_DEVICE_CIS_PROD_ID12(mfc, v1, v2, vh1, vh2, _cisfile) { \
+	.match_flags =  PCMCIA_DEV_ID_MATCH_FAKE_CIS | \
+			PCMCIA_DEV_ID_MATCH_PROD_ID1| \
+			PCMCIA_DEV_ID_MATCH_PROD_ID2| \
+			PCMCIA_DEV_ID_MATCH_DEVICE_NO, \
+	.prod_id = { (v1), (v2), NULL, NULL }, \
+	.prod_id_hash = { (vh1), (vh2), 0, 0 },\
+	.device_no = (mfc), \
+	.cisfile = (_cisfile)}
+
+#define PCMCIA_MFC_DEVICE_CIS_MANF_CARD(mfc, manf, card, _cisfile) { \
+	.match_flags =  PCMCIA_DEV_ID_MATCH_FAKE_CIS | \
+			PCMCIA_DEV_ID_MATCH_MANF_ID| \
+			PCMCIA_DEV_ID_MATCH_CARD_ID| \
+			PCMCIA_DEV_ID_MATCH_FUNCTION, \
+	.manf_id = (manf), \
+	.card_id = (card), \
+	.function = (mfc), \
+	.cisfile = (_cisfile)}
+
+#define PCMCIA_MFC_DEVICE_CIS_PROD_ID12(mfc, v1, v2, vh1, vh2, _cisfile) { \
+	.match_flags =  PCMCIA_DEV_ID_MATCH_FAKE_CIS | \
+			PCMCIA_DEV_ID_MATCH_PROD_ID1| \
+			PCMCIA_DEV_ID_MATCH_PROD_ID2| \
+			PCMCIA_DEV_ID_MATCH_FUNCTION, \
+	.prod_id = { (v1), (v2), NULL, NULL }, \
+	.prod_id_hash = { (vh1), (vh2), 0, 0 }, \
+	.function = (mfc), \
+	.cisfile = (_cisfile)}
+
+#define PCMCIA_MFC_DEVICE_CIS_PROD_ID4(mfc, v4, vh4, _cisfile) { \
+	.match_flags =  PCMCIA_DEV_ID_MATCH_FAKE_CIS | \
+			PCMCIA_DEV_ID_MATCH_PROD_ID4| \
+			PCMCIA_DEV_ID_MATCH_FUNCTION, \
+	.prod_id = { NULL, NULL, NULL, (v4) }, \
+	.prod_id_hash = { 0, 0, 0, (vh4) }, \
+	.function = (mfc), \
+	.cisfile = (_cisfile)}
+
+
+#define PCMCIA_DEVICE_NULL { .match_flags = 0, }
diff --git a/include/pcmcia/ds.h b/include/pcmcia/ds.h
--- a/include/pcmcia/ds.h
+++ b/include/pcmcia/ds.h
@@ -16,8 +16,13 @@
 #ifndef _LINUX_DS_H
 #define _LINUX_DS_H
 
+#ifdef __KERNEL__
+#include <linux/mod_devicetable.h>
+#endif
+
 #include <pcmcia/bulkmem.h>
 #include <pcmcia/cs_types.h>
+#include <pcmcia/device_id.h>
 
 typedef struct tuple_parse_t {
     tuple_t		tuple;
@@ -47,7 +52,6 @@ typedef struct mtd_info_t {
 } mtd_info_t;
 
 typedef union ds_ioctl_arg_t {
-    servinfo_t		servinfo;
     adjust_t		adjust;
     config_info_t	config;
     tuple_t		tuple;
@@ -63,7 +67,6 @@ typedef union ds_ioctl_arg_t {
     cisdump_t		cisdump;
 } ds_ioctl_arg_t;
 
-#define DS_GET_CARD_SERVICES_INFO	_IOR ('d', 1, servinfo_t)
 #define DS_ADJUST_RESOURCE_INFO		_IOWR('d', 2, adjust_t)
 #define DS_GET_CONFIGURATION_INFO	_IOWR('d', 3, config_info_t)
 #define DS_GET_FIRST_TUPLE		_IOWR('d', 4, tuple_t)
@@ -129,12 +132,13 @@ typedef struct dev_link_t {
 
 struct pcmcia_socket;
 
-extern struct bus_type pcmcia_bus_type;
-
 struct pcmcia_driver {
 	dev_link_t		*(*attach)(void);
+	int (*event)		(event_t event, int priority,
+				 event_callback_args_t *);
 	void			(*detach)(dev_link_t *);
 	struct module		*owner;
+	struct pcmcia_device_id	*id_table;
 	struct device_driver	drv;
 };
 
@@ -158,22 +162,16 @@ struct pcmcia_device {
 	/* deprecated, a cleaned up version will be moved into this
 	   struct soon */
 	dev_link_t		*instance;
-	struct client_t {
-		u_short			client_magic;
-		struct pcmcia_socket	*Socket;
-		u_char			Function;
-		u_int			state;
-		event_t			EventMask;
-		int (*event_handler)	(event_t event, int priority,
-					 event_callback_args_t *);
-		event_callback_args_t 	event_callback_args;
-	}			client;
+	event_callback_args_t 	event_callback_args;
+	u_int			state;
 
 	/* information about this device */
 	u8			has_manf_id:1;
 	u8			has_card_id:1;
 	u8			has_func_id:1;
-	u8			reserved:5;
+
+	u8			allow_func_id_match:1;
+	u8			reserved:4;
 
 	u8			func_id;
 	u16			manf_id;
@@ -190,8 +188,8 @@ struct pcmcia_device {
 #define to_pcmcia_dev(n) container_of(n, struct pcmcia_device, dev)
 #define to_pcmcia_drv(n) container_of(n, struct pcmcia_driver, drv)
 
-#define handle_to_pdev(handle) container_of(handle, struct pcmcia_device, client);
-#define handle_to_dev(handle) ((container_of(handle, struct pcmcia_device, client))->dev)
+#define handle_to_pdev(handle) (handle)
+#define handle_to_dev(handle) (handle->dev)
 
 /* error reporting */
 void cs_error(client_handle_t handle, int func, int ret);
diff --git a/include/pcmcia/ss.h b/include/pcmcia/ss.h
--- a/include/pcmcia/ss.h
+++ b/include/pcmcia/ss.h
@@ -15,10 +15,12 @@
 #ifndef _LINUX_SS_H
 #define _LINUX_SS_H
 
+#include <linux/config.h>
+#include <linux/device.h>
+
 #include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/bulkmem.h>
-#include <linux/device.h>
 
 /* Definitions for card status flags for GetStatus */
 #define SS_WRPROT	0x0001
@@ -77,6 +79,11 @@ extern socket_state_t dead_socket;
 /* Use this just for bridge windows */
 #define MAP_IOSPACE	0x20
 
+/* power hook operations */
+#define HOOK_POWER_PRE	0x01
+#define HOOK_POWER_POST	0x02
+
+
 typedef struct pccard_io_map {
     u_char	map;
     u_char	flags;
@@ -166,7 +173,7 @@ typedef struct window_t {
 
 struct config_t;
 struct pcmcia_callback;
-
+struct user_info_t;
 
 struct pcmcia_socket {
 	struct module			*owner;
@@ -211,8 +218,9 @@ struct pcmcia_socket {
 
 	/* is set to one if resource setup is done using adjust_resource_info() */
 	u8				resource_setup_old:1;
+	u8				resource_setup_new:1;
 
-	u8				reserved:6;
+	u8				reserved:5;
 
 	/* socket operations */
 	struct pccard_operations *	ops;
@@ -222,6 +230,9 @@ struct pcmcia_socket {
 	/* Zoom video behaviour is so chip specific its not worth adding
 	   this to _ops */
 	void 				(*zoom_video)(struct pcmcia_socket *, int);
+
+	/* so is power hook */
+	int (*power_hook)(struct pcmcia_socket *sock, int operation);
                            
 	/* state thread */
 	struct semaphore		skt_sem;	/* protects socket h/w state */
@@ -233,9 +244,32 @@ struct pcmcia_socket {
 	unsigned int			thread_events;
 
 	/* pcmcia (16-bit) */
-	struct pcmcia_bus_socket	*pcmcia;
 	struct pcmcia_callback		*callback;
 
+#if defined(CONFIG_PCMCIA) || defined(CONFIG_PCMCIA_MODULE)
+	struct list_head		devices_list;	/*  PCMCIA devices */
+	u8				device_count;	/* the number of devices, used
+							 * only internally and subject
+							 * to incorrectness and change */
+
+	struct {
+		u8			present:1,	/* PCMCIA card is present in socket */
+					busy:1,		/* "master" ioctl is used */
+					dead:1,		/* pcmcia module is being unloaded */
+					device_add_pending:1, /* a pseudo-multifunction-device
+							       * add event is pending */
+					reserved:4;
+	} 				pcmcia_state;
+
+	struct work_struct		device_add;	/* for adding further pseudo-multifunction
+							 * devices */
+
+#ifdef CONFIG_PCMCIA_IOCTL
+	struct user_info_t		*user;
+	wait_queue_head_t		queue;
+#endif
+#endif
+
 	/* cardbus (32-bit) */
 #ifdef CONFIG_CARDBUS
 	struct resource *		cb_cis_res;
diff --git a/include/pcmcia/version.h b/include/pcmcia/version.h
--- a/include/pcmcia/version.h
+++ b/include/pcmcia/version.h
@@ -1,4 +1,3 @@
 /* version.h 1.94 2000/10/03 17:55:48 (David Hinds) */
 
-#define CS_RELEASE "3.1.22"
-#define CS_RELEASE_CODE 0x3116
+/* This file will be removed, please don't include it */
diff --git a/include/scsi/scsi.h b/include/scsi/scsi.h
--- a/include/scsi/scsi.h
+++ b/include/scsi/scsi.h
@@ -28,7 +28,7 @@ extern const unsigned char scsi_command_
  *	SCSI device types
  */
 
-#define MAX_SCSI_DEVICE_CODE 14
+#define MAX_SCSI_DEVICE_CODE 15
 extern const char *const scsi_device_types[MAX_SCSI_DEVICE_CODE];
 
 /*
@@ -41,6 +41,7 @@ extern const char *const scsi_device_typ
 #define FORMAT_UNIT           0x04
 #define READ_BLOCK_LIMITS     0x05
 #define REASSIGN_BLOCKS       0x07
+#define INITIALIZE_ELEMENT_STATUS 0x07
 #define READ_6                0x08
 #define WRITE_6               0x0a
 #define SEEK_6                0x0b
@@ -65,6 +66,7 @@ extern const char *const scsi_device_typ
 #define READ_10               0x28
 #define WRITE_10              0x2a
 #define SEEK_10               0x2b
+#define POSITION_TO_ELEMENT   0x2b
 #define WRITE_VERIFY          0x2e
 #define VERIFY                0x2f
 #define SEARCH_HIGH           0x30
@@ -97,6 +99,7 @@ extern const char *const scsi_device_typ
 #define PERSISTENT_RESERVE_OUT 0x5f
 #define REPORT_LUNS           0xa0
 #define MOVE_MEDIUM           0xa5
+#define EXCHANGE_MEDIUM       0xa6
 #define READ_12               0xa8
 #define WRITE_12              0xaa
 #define WRITE_VERIFY_12       0xae
@@ -208,8 +211,9 @@ static inline int scsi_status_is_good(in
 				     * - treated as TYPE_DISK */
 #define TYPE_MEDIUM_CHANGER 0x08
 #define TYPE_COMM           0x09    /* Communications device */
-#define TYPE_ENCLOSURE      0x0d    /* Enclosure Services Device */
 #define TYPE_RAID           0x0c
+#define TYPE_ENCLOSURE      0x0d    /* Enclosure Services Device */
+#define TYPE_RBC	    0x0e
 #define TYPE_NO_LUN         0x7f
 
 /*
diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h
--- a/include/scsi/scsi_cmnd.h
+++ b/include/scsi/scsi_cmnd.h
@@ -31,14 +31,11 @@ struct scsi_cmnd {
 	int     sc_magic;
 
 	struct scsi_device *device;
-	unsigned short state;
-	unsigned short owner;
 	struct scsi_request *sc_request;
 
 	struct list_head list;  /* scsi_cmnd participates in queue lists */
 
 	struct list_head eh_entry; /* entry for the host eh_cmd_q */
-	int eh_state;		/* Used for state tracking in error handlr */
 	int eh_eflags;		/* Used by error handlr */
 	void (*done) (struct scsi_cmnd *);	/* Mid-level done function */
 
@@ -80,8 +77,6 @@ struct scsi_cmnd {
 					 * sense info */
 	unsigned short use_sg;	/* Number of pieces of scatter-gather */
 	unsigned short sglist_len;	/* size of malloc'd scatter-gather list */
-	unsigned short abort_reason;	/* If the mid-level code requests an
-					 * abort, this is the reason. */
 	unsigned bufflen;	/* Size of data buffer */
 	void *buffer;		/* Data buffer */
 
diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
--- a/include/scsi/scsi_device.h
+++ b/include/scsi/scsi_device.h
@@ -9,7 +9,7 @@
 struct request_queue;
 struct scsi_cmnd;
 struct scsi_mode_data;
-
+struct scsi_lun;
 
 /*
  * sdev state: If you alter this, you also need to alter scsi_sysfs.c
@@ -154,7 +154,9 @@ struct scsi_target {
 	unsigned int		id; /* target id ... replace
 				     * scsi_device.id eventually */
 	unsigned long		create:1; /* signal that it needs to be added */
-	unsigned long		starget_data[0];
+	void 			*hostdata; /* available to low-level driver */
+	unsigned long		starget_data[0]; /* for the transport */
+	/* starget_data must be the last element!!!! */
 } __attribute__((aligned(sizeof(unsigned long))));
 
 #define to_scsi_target(d)	container_of(d, struct scsi_target, dev)
@@ -241,6 +243,7 @@ extern void scsi_target_reap(struct scsi
 extern void scsi_target_block(struct device *);
 extern void scsi_target_unblock(struct device *);
 extern void scsi_remove_target(struct device *);
+extern void int_to_scsilun(unsigned int, struct scsi_lun *);
 extern const char *scsi_device_state_name(enum scsi_device_state);
 extern int scsi_is_sdev_device(const struct device *);
 extern int scsi_is_target_device(const struct device *);
diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h
--- a/include/scsi/scsi_host.h
+++ b/include/scsi/scsi_host.h
@@ -10,6 +10,7 @@ struct block_device;
 struct module;
 struct scsi_cmnd;
 struct scsi_device;
+struct scsi_target;
 struct Scsi_Host;
 struct scsi_host_cmd_pool;
 struct scsi_transport_template;
@@ -228,6 +229,30 @@ struct scsi_host_template {
 	void (* slave_destroy)(struct scsi_device *);
 
 	/*
+	 * Before the mid layer attempts to scan for a new device attached
+	 * to a target where no target currently exists, it will call this
+	 * entry in your driver.  Should your driver need to allocate any
+	 * structs or perform any other init items in order to send commands
+	 * to a currently unused target, then this is where you can perform
+	 * those allocations.
+	 *
+	 * Return values: 0 on success, non-0 on failure
+	 *
+	 * Status: OPTIONAL
+	 */
+	int (* target_alloc)(struct scsi_target *);
+
+	/*
+	 * Immediately prior to deallocating the target structure, and
+	 * after all activity to attached scsi devices has ceased, the
+	 * midlayer calls this point so that the driver may deallocate
+	 * and terminate any references to the target.
+	 *
+	 * Status: OPTIONAL
+	 */
+	void (* target_destroy)(struct scsi_target *);
+
+	/*
 	 * fill in this function to allow the queue depth of this host
 	 * to be changeable (on a per device basis).  returns either
 	 * the current queue depth setting (may be different from what
@@ -616,12 +641,6 @@ static inline void scsi_assign_lock(stru
 	shost->host_lock = lock;
 }
 
-static inline void scsi_set_device(struct Scsi_Host *shost,
-                                   struct device *dev)
-{
-        shost->shost_gendev.parent = dev;
-}
-
 static inline struct device *scsi_get_device(struct Scsi_Host *shost)
 {
         return shost->shost_gendev.parent;
diff --git a/include/scsi/scsi_transport.h b/include/scsi/scsi_transport.h
--- a/include/scsi/scsi_transport.h
+++ b/include/scsi/scsi_transport.h
@@ -21,6 +21,7 @@
 #define SCSI_TRANSPORT_H
 
 #include <linux/transport_class.h>
+#include <scsi/scsi_host.h>
 
 struct scsi_transport_template {
 	/* the attribute containers */
@@ -28,12 +29,23 @@ struct scsi_transport_template {
 	struct transport_container target_attrs;
 	struct transport_container device_attrs;
 
+	/*
+	 * If set, call target_parent prior to allocating a scsi_target,
+	 * so we get the appropriate parent for the target. This function
+	 * is required for transports like FC and iSCSI that do not put the
+	 * scsi_target under scsi_host.
+	 */
+	struct device *(*target_parent)(struct Scsi_Host *, int, uint);
+
 	/* The size of the specific transport attribute structure (a
 	 * space of this size will be left at the end of the
 	 * scsi_* structure */
 	int	device_size;
+	int	device_private_offset;
 	int	target_size;
+	int	target_private_offset;
 	int	host_size;
+	/* no private offset for the host; there's an alternative mechanism */
 
 	/*
 	 * True if the transport wants to use a host-based work-queue
@@ -45,4 +57,38 @@ struct scsi_transport_template {
 	dev_to_shost((tc)->dev)
 
 
+/* Private area maintenance. The driver requested allocations come
+ * directly after the transport class allocations (if any).  The idea
+ * is that you *must* call these only once.  The code assumes that the
+ * initial values are the ones the transport specific code requires */
+static inline void
+scsi_transport_reserve_target(struct scsi_transport_template * t, int space)
+{
+	BUG_ON(t->target_private_offset != 0);
+	t->target_private_offset = ALIGN(t->target_size, sizeof(void *));
+	t->target_size = t->target_private_offset + space;
+}
+static inline void
+scsi_transport_reserve_device(struct scsi_transport_template * t, int space)
+{
+	BUG_ON(t->device_private_offset != 0);
+	t->device_private_offset = ALIGN(t->device_size, sizeof(void *));
+	t->device_size = t->device_private_offset + space;
+}
+static inline void *
+scsi_transport_target_data(struct scsi_target *starget)
+{
+	struct Scsi_Host *shost = dev_to_shost(&starget->dev);
+	return (u8 *)starget->starget_data
+		+ shost->transportt->target_private_offset;
+
+}
+static inline void *
+scsi_transport_device_data(struct scsi_device *sdev)
+{
+	struct Scsi_Host *shost = sdev->host;
+	return (u8 *)sdev->sdev_data
+		+ shost->transportt->device_private_offset;
+}
+
 #endif /* SCSI_TRANSPORT_H */
diff --git a/include/scsi/sg_request.h b/include/scsi/sg_request.h
new file mode 100644
--- /dev/null
+++ b/include/scsi/sg_request.h
@@ -0,0 +1,26 @@
+typedef struct scsi_request Scsi_Request;
+
+static Scsi_Request *dummy_cmdp;	/* only used for sizeof */
+
+typedef struct sg_scatter_hold { /* holding area for scsi scatter gather info */
+	unsigned short k_use_sg; /* Count of kernel scatter-gather pieces */
+	unsigned short sglist_len; /* size of malloc'd scatter-gather list ++ */
+	unsigned bufflen;	/* Size of (aggregate) data buffer */
+	unsigned b_malloc_len;	/* actual len malloc'ed in buffer */
+	void *buffer;		/* Data buffer or scatter list (k_use_sg>0) */
+	char dio_in_use;	/* 0->indirect IO (or mmap), 1->dio */
+	unsigned char cmd_opcode; /* first byte of command */
+} Sg_scatter_hold;
+
+typedef struct sg_request {	/* SG_MAX_QUEUE requests outstanding per file */
+	Scsi_Request *my_cmdp;	/* != 0  when request with lower levels */
+	struct sg_request *nextrp;	/* NULL -> tail request (slist) */
+	struct sg_fd *parentfp;	/* NULL -> not in use */
+	Sg_scatter_hold data;	/* hold buffer, perhaps scatter list */
+	sg_io_hdr_t header;	/* scsi command+info, see <scsi/sg.h> */
+	unsigned char sense_b[sizeof (dummy_cmdp->sr_sense_buffer)];
+	char res_used;		/* 1 -> using reserve buffer, 0 -> not ... */
+	char orphan;		/* 1 -> drop on sight, 0 -> normal */
+	char sg_io_owned;	/* 1 -> packet belongs to SG_IO */
+	volatile char done;	/* 0->before bh, 1->before read, 2->read */
+} Sg_request;
diff --git a/include/sound/ac97_codec.h b/include/sound/ac97_codec.h
--- a/include/sound/ac97_codec.h
+++ b/include/sound/ac97_codec.h
@@ -437,6 +437,7 @@ struct snd_ac97_build_ops {
 	void (*suspend) (ac97_t *ac97);
 	void (*resume) (ac97_t *ac97);
 #endif
+	void (*update_jacks) (ac97_t *ac97);	/* for jack-sharing */
 };
 
 struct _snd_ac97_bus_ops {
@@ -516,6 +517,9 @@ struct _snd_ac97 {
 		} ad18xx;
 		unsigned int dev_flags;		/* device specific */
 	} spec;
+	/* jack-sharing info */
+	unsigned char indep_surround;
+	unsigned char channel_mode;
 };
 
 /* conditions */
@@ -569,8 +573,8 @@ enum {
 };
 
 struct ac97_quirk {
-	unsigned short vendor;	/* PCI vendor id */
-	unsigned short device;	/* PCI device id */
+	unsigned short subvendor; /* PCI subsystem vendor id */
+	unsigned short subdevice; /* PCI sybsystem device id */
 	unsigned short mask;	/* device id bit mask, 0 = accept all */
 	unsigned int codec_id;	/* codec id (if any), 0 = accept all */
 	const char *name;	/* name shown as info */
diff --git a/include/sound/asound.h b/include/sound/asound.h
--- a/include/sound/asound.h
+++ b/include/sound/asound.h
@@ -113,9 +113,10 @@ enum sndrv_hwdep_iface {
 	SNDRV_HWDEP_IFACE_BLUETOOTH,	/* Bluetooth audio */
 	SNDRV_HWDEP_IFACE_USX2Y_PCM,	/* Tascam US122, US224 & US428 rawusb pcm */
 	SNDRV_HWDEP_IFACE_PCXHR,	/* Digigram PCXHR */
+	SNDRV_HWDEP_IFACE_SB_RC,	/* SB Extigy/Audigy2NX remote control */
 
 	/* Don't forget to change the following: */
-	SNDRV_HWDEP_IFACE_LAST = SNDRV_HWDEP_IFACE_PCXHR
+	SNDRV_HWDEP_IFACE_LAST = SNDRV_HWDEP_IFACE_SB_RC
 };
 
 struct sndrv_hwdep_info {
@@ -344,7 +345,7 @@ enum sndrv_pcm_hw_param {
 	SNDRV_PCM_HW_PARAM_LAST_INTERVAL = SNDRV_PCM_HW_PARAM_TICK_TIME
 };
 
-#define SNDRV_PCM_HW_PARAMS_RUNTIME		(1<<0)
+#define SNDRV_PCM_HW_PARAMS_NORESAMPLE		(1<<0)	/* avoid rate resampling */
 
 struct sndrv_interval {
 	unsigned int min, max;
@@ -559,7 +560,7 @@ enum {
  *  Timer section - /dev/snd/timer
  */
 
-#define SNDRV_TIMER_VERSION		SNDRV_PROTOCOL_VERSION(2, 0, 2)
+#define SNDRV_TIMER_VERSION		SNDRV_PROTOCOL_VERSION(2, 0, 4)
 
 enum sndrv_timer_class {
 	SNDRV_TIMER_CLASS_NONE = -1,
@@ -672,10 +673,11 @@ enum {
 	SNDRV_TIMER_IOCTL_INFO = _IOR('T', 0x11, struct sndrv_timer_info),
 	SNDRV_TIMER_IOCTL_PARAMS = _IOW('T', 0x12, struct sndrv_timer_params),
 	SNDRV_TIMER_IOCTL_STATUS = _IOR('T', 0x14, struct sndrv_timer_status),
-	SNDRV_TIMER_IOCTL_START = _IO('T', 0x20),
-	SNDRV_TIMER_IOCTL_STOP = _IO('T', 0x21),
-	SNDRV_TIMER_IOCTL_CONTINUE = _IO('T', 0x22),
-	SNDRV_TIMER_IOCTL_PAUSE = _IO('T', 0x23),
+	/* The following four ioctls are changed since 1.0.9 due to confliction */
+	SNDRV_TIMER_IOCTL_START = _IO('T', 0xa0),
+	SNDRV_TIMER_IOCTL_STOP = _IO('T', 0xa1),
+	SNDRV_TIMER_IOCTL_CONTINUE = _IO('T', 0xa2),
+	SNDRV_TIMER_IOCTL_PAUSE = _IO('T', 0xa3),
 };
 
 struct sndrv_timer_read {
diff --git a/include/sound/control.h b/include/sound/control.h
--- a/include/sound/control.h
+++ b/include/sound/control.h
@@ -106,7 +106,7 @@ typedef int (*snd_kctl_ioctl_func_t) (sn
 void snd_ctl_notify(snd_card_t * card, unsigned int mask, snd_ctl_elem_id_t * id);
 
 snd_kcontrol_t *snd_ctl_new(snd_kcontrol_t * kcontrol, unsigned int access);
-snd_kcontrol_t *snd_ctl_new1(snd_kcontrol_new_t * kcontrolnew, void * private_data);
+snd_kcontrol_t *snd_ctl_new1(const snd_kcontrol_new_t * kcontrolnew, void * private_data);
 void snd_ctl_free_one(snd_kcontrol_t * kcontrol);
 int snd_ctl_add(snd_card_t * card, snd_kcontrol_t * kcontrol);
 int snd_ctl_remove(snd_card_t * card, snd_kcontrol_t * kcontrol);
diff --git a/include/sound/core.h b/include/sound/core.h
--- a/include/sound/core.h
+++ b/include/sound/core.h
@@ -126,25 +126,26 @@ struct snd_monitor_file {
 	struct snd_monitor_file *next;
 };
 
-struct snd_shutdown_f_ops;	/* define it later */
+struct snd_shutdown_f_ops;	/* define it later in init.c */
 
 /* main structure for soundcard */
 
 struct _snd_card {
-	int number;			/* number of soundcard (index to snd_cards) */
+	int number;			/* number of soundcard (index to
+								snd_cards) */
 
 	char id[16];			/* id string of this card */
 	char driver[16];		/* driver name */
 	char shortname[32];		/* short name of this soundcard */
 	char longname[80];		/* name of this soundcard */
 	char mixername[80];		/* mixer name */
-	char components[80];		/* card components delimited with space */
-
+	char components[80];		/* card components delimited with
+								space */
 	struct module *module;		/* top-level module */
 
 	void *private_data;		/* private data for soundcard */
-	void (*private_free) (snd_card_t *card); /* callback for freeing of private data */
-
+	void (*private_free) (snd_card_t *card); /* callback for freeing of
+								private data */
 	struct list_head devices;	/* devices */
 
 	unsigned int last_numid;	/* last used numeric ID */
@@ -160,7 +161,8 @@ struct _snd_card {
 	struct proc_dir_entry *proc_root_link;	/* number link to real id */
 
 	struct snd_monitor_file *files; /* all files associated to this card */
-	struct snd_shutdown_f_ops *s_f_ops; /* file operations in the shutdown state */
+	struct snd_shutdown_f_ops *s_f_ops; /* file operations in the shutdown
+								state */
 	spinlock_t files_lock;		/* lock the files for this card */
 	int shutdown;			/* this card is going down */
 	wait_queue_head_t shutdown_sleep;
@@ -196,8 +198,6 @@ static inline void snd_power_unlock(snd_
 	up(&card->power_lock);
 }
 
-int snd_power_wait(snd_card_t *card, unsigned int power_state, struct file *file);
-
 static inline unsigned int snd_power_get_state(snd_card_t *card)
 {
 	return card->power_state;
@@ -208,6 +208,10 @@ static inline void snd_power_change_stat
 	card->power_state = state;
 	wake_up(&card->power_sleep);
 }
+
+/* init.c */
+int snd_power_wait(snd_card_t *card, unsigned int power_state, struct file *file);
+
 int snd_card_set_pm_callback(snd_card_t *card,
 			     int (*suspend)(snd_card_t *, pm_message_t),
 			     int (*resume)(snd_card_t *),
@@ -238,15 +242,14 @@ static inline int snd_power_wait(snd_car
 
 #endif /* CONFIG_PM */
 
-/* device.c */
-
 struct _snd_minor {
 	struct list_head list;		/* list of all minors per card */
 	int number;			/* minor number */
 	int device;			/* device number */
 	const char *comment;		/* for /proc/asound/devices */
 	struct file_operations *f_ops;	/* file operations */
-	char name[0];			/* device name (keep at the end of structure) */
+	char name[0];			/* device name (keep at the end of
+								structure) */
 };
 
 typedef struct _snd_minor snd_minor_t;
@@ -287,11 +290,12 @@ void snd_memory_init(void);
 void snd_memory_done(void);
 int snd_memory_info_init(void);
 int snd_memory_info_done(void);
-void *snd_hidden_kmalloc(size_t size, int flags);
-void *snd_hidden_kcalloc(size_t n, size_t size, int flags);
+void *snd_hidden_kmalloc(size_t size, unsigned int __nocast flags);
+void *snd_hidden_kcalloc(size_t n, size_t size, unsigned int __nocast flags);
 void snd_hidden_kfree(const void *obj);
 void *snd_hidden_vmalloc(unsigned long size);
 void snd_hidden_vfree(void *obj);
+char *snd_hidden_kstrdup(const char *s, unsigned int __nocast flags);
 #define kmalloc(size, flags) snd_hidden_kmalloc(size, flags)
 #define kcalloc(n, size, flags) snd_hidden_kcalloc(n, size, flags)
 #define kfree(obj) snd_hidden_kfree(obj)
@@ -301,6 +305,7 @@ void snd_hidden_vfree(void *obj);
 #define vmalloc_nocheck(size) snd_wrapper_vmalloc(size)
 #define kfree_nocheck(obj) snd_wrapper_kfree(obj)
 #define vfree_nocheck(obj) snd_wrapper_vfree(obj)
+#define kstrdup(s, flags)  snd_hidden_kstrdup(s, flags)
 #else
 #define snd_memory_init() /*NOP*/
 #define snd_memory_done() /*NOP*/
@@ -311,7 +316,6 @@ void snd_hidden_vfree(void *obj);
 #define kfree_nocheck(obj) kfree(obj)
 #define vfree_nocheck(obj) vfree(obj)
 #endif
-char *snd_kmalloc_strdup(const char *string, int flags);
 int copy_to_user_fromio(void __user *dst, const volatile void __iomem *src, size_t count);
 int copy_from_user_toio(volatile void __iomem *dst, const void __user *src, size_t count);
 
@@ -356,11 +360,13 @@ int snd_device_free_all(snd_card_t *card
 
 /* isadma.c */
 
+#ifdef CONFIG_ISA_DMA_API
 #define DMA_MODE_NO_ENABLE	0x0100
 
 void snd_dma_program(unsigned long dma, unsigned long addr, unsigned int size, unsigned short mode);
 void snd_dma_disable(unsigned long dma);
 unsigned int snd_dma_pointer(unsigned long dma, unsigned int size);
+#endif
 
 /* misc.c */
 
@@ -410,7 +416,7 @@ void snd_verbose_printd(const char *file
 	printk(fmt ,##args)
 #endif
 /**
- * snd_assert - run-time assersion macro
+ * snd_assert - run-time assertion macro
  * @expr: expression
  * @args...: the action
  *
@@ -426,7 +432,7 @@ void snd_verbose_printd(const char *file
 	}\
 } while (0)
 /**
- * snd_runtime_check - run-time assersion macro
+ * snd_runtime_check - run-time assertion macro
  * @expr: expression
  * @args...: the action
  *
diff --git a/include/sound/driver.h b/include/sound/driver.h
--- a/include/sound/driver.h
+++ b/include/sound/driver.h
@@ -51,7 +51,7 @@
 #ifdef CONFIG_SND_DEBUG_MEMORY
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
-void *snd_wrapper_kmalloc(size_t, int);
+void *snd_wrapper_kmalloc(size_t, unsigned int __nocast);
 #undef kmalloc
 void snd_wrapper_kfree(const void *);
 #undef kfree
diff --git a/include/sound/emu10k1.h b/include/sound/emu10k1.h
--- a/include/sound/emu10k1.h
+++ b/include/sound/emu10k1.h
@@ -83,7 +83,8 @@
 #define IPR			0x08		/* Global interrupt pending register		*/
 						/* Clear pending interrupts by writing a 1 to	*/
 						/* the relevant bits and zero to the other bits	*/
-
+#define IPR_P16V		0x80000000	/* Bit set when the CA0151 P16V chip wishes
+						   to interrupt */
 #define IPR_GPIOMSG		0x20000000	/* GPIO message interrupt (RE'd, still not sure 
 						   which INTE bits enable it)			*/
 
@@ -746,6 +747,7 @@
 						/* Assumes sample lock				*/
 
 /* These three bitfields apply to CDSRCS, GPSRCS, and (except as noted) ZVSRCS.			*/
+#define SRCS_SPDIFVALID		0x04000000	/* SPDIF stream valid				*/
 #define SRCS_SPDIFLOCKED	0x02000000	/* SPDIF stream locked				*/
 #define SRCS_RATELOCKED		0x01000000	/* Sample rate locked				*/
 #define SRCS_ESTSAMPLERATE	0x0007ffff	/* Do not modify this field.			*/
@@ -803,10 +805,26 @@
 #define A_FXWC2			0x75		/* Selects 0x9f-0x80 for FX recording           */
 
 #define A_SPDIF_SAMPLERATE	0x76		/* Set the sample rate of SPDIF output		*/
-#define A_SPDIF_RATE_MASK	0x000000c0
+#define A_SAMPLE_RATE		0x76		/* Various sample rate settings. */
+#define A_SAMPLE_RATE_NOT_USED  0x0ffc111e	/* Bits that are not used and cannot be set. 	*/
+#define A_SAMPLE_RATE_UNKNOWN	0xf0030001	/* Bits that can be set, but have unknown use. 	*/
+#define A_SPDIF_RATE_MASK	0x000000e0	/* Any other values for rates, just use 48000	*/
 #define A_SPDIF_48000		0x00000000
-#define A_SPDIF_44100		0x00000080
+#define A_SPDIF_192000		0x00000020
 #define A_SPDIF_96000		0x00000040
+#define A_SPDIF_44100		0x00000080
+
+#define A_I2S_CAPTURE_RATE_MASK	0x00000e00	/* This sets the capture PCM rate, but it is    */
+#define A_I2S_CAPTURE_48000	0x00000000	/* unclear if this sets the ADC rate as well.	*/
+#define A_I2S_CAPTURE_192000	0x00000200
+#define A_I2S_CAPTURE_96000	0x00000400
+#define A_I2S_CAPTURE_44100	0x00000800
+
+#define A_PCM_RATE_MASK		0x0000e000	/* This sets the playback PCM rate on the P16V	*/
+#define A_PCM_48000		0x00000000
+#define A_PCM_192000		0x00002000
+#define A_PCM_96000		0x00004000
+#define A_PCM_44100		0x00008000
 
 /* 0x77,0x78,0x79 "something i2s-related" - default to 0x01080000 on my audigy 2 ZS --rlrevell	*/
 /* 0x7a, 0x7b - lookup tables */
@@ -1039,28 +1057,28 @@ typedef struct {
 	u32 vendor;
 	u32 device;
 	u32 subsystem;
+	unsigned char revision;
 	unsigned char emu10k1_chip; /* Original SB Live. Not SB Live 24bit. */
 	unsigned char emu10k2_chip; /* Audigy 1 or Audigy 2. */
 	unsigned char ca0102_chip;  /* Audigy 1 or Audigy 2. Not SB Audigy 2 Value. */
 	unsigned char ca0108_chip;  /* Audigy 2 Value */
 	unsigned char ca0151_chip;  /* P16V */
 	unsigned char spk71;        /* Has 7.1 speakers */
+	unsigned char sblive51;	    /* SBLive! 5.1 - extout 0x11 -> center, 0x12 -> lfe */
 	unsigned char spdif_bug;    /* Has Spdif phasing bug */
 	unsigned char ac97_chip;    /* Has an AC97 chip */
 	unsigned char ecard;        /* APS EEPROM */
-	char * driver;
-	char * name;
+	const char *driver;
+	const char *name;
+	const char *id;		/* for backward compatibility - can be NULL if not needed */
 } emu_chip_details_t;
 
 struct _snd_emu10k1 {
 	int irq;
 
 	unsigned long port;			/* I/O port number */
-	unsigned int APS: 1,			/* APS flag */
-	    no_ac97: 1,				/* no AC'97 */
-	    tos_link: 1,			/* tos link detected */
-	    rear_ac97: 1,			/* rear channels are on AC'97 */
-	    spk71:1;				/* 7.1 configuration (Audigy 2 ZS) */
+	unsigned int tos_link: 1,		/* tos link detected */
+	    rear_ac97: 1;			/* rear channels are on AC'97 */
 	const emu_chip_details_t *card_capabilities;	/* Contains profile of card capabilities */
 	unsigned int audigy;			/* is Audigy? */
 	unsigned int revision;			/* chip revision */
@@ -1109,7 +1127,10 @@ struct _snd_emu10k1 {
 
 	emu10k1_voice_t voices[NUM_G];
 	emu10k1_voice_t p16v_voices[4];
+	emu10k1_voice_t p16v_capture_voice;
 	int p16v_device_offset;
+	u32 p16v_capture_source;
+	u32 p16v_capture_channel;
 	emu10k1_pcm_mixer_t pcm_mixer[32];
 	emu10k1_pcm_mixer_t efx_pcm_mixer[NUM_EFX_PLAYBACK];
 	snd_kcontrol_t *ctl_send_routing;
@@ -1146,6 +1167,7 @@ int snd_emu10k1_create(snd_card_t * card
 		       unsigned short extout_mask,
 		       long max_cache_bytes,
 		       int enable_ir,
+		       uint subsystem,
 		       emu10k1_t ** remu);
 
 int snd_emu10k1_pcm(emu10k1_t * emu, int device, snd_pcm_t ** rpcm);
@@ -1453,7 +1475,6 @@ int snd_emu10k1_fx8010_unregister_irq_ha
 #endif
 
 typedef struct {
-	unsigned int card;			/* card type */
 	unsigned int internal_tram_size;	/* in samples */
 	unsigned int external_tram_size;	/* in samples */
 	char fxbus_names[16][32];		/* names of FXBUSes */
diff --git a/include/sound/gus.h b/include/sound/gus.h
--- a/include/sound/gus.h
+++ b/include/sound/gus.h
@@ -526,9 +526,6 @@ extern void snd_gf1_adlib_write(snd_gus_
 extern void snd_gf1_dram_addr(snd_gus_card_t * gus, unsigned int addr);
 extern void snd_gf1_poke(snd_gus_card_t * gus, unsigned int addr, unsigned char data);
 extern unsigned char snd_gf1_peek(snd_gus_card_t * gus, unsigned int addr);
-extern void snd_gf1_pokew(snd_gus_card_t * gus, unsigned int addr, unsigned short data);
-extern unsigned short snd_gf1_peekw(snd_gus_card_t * gus, unsigned int addr);
-extern void snd_gf1_dram_setmem(snd_gus_card_t * gus, unsigned int addr, unsigned short value, unsigned int count);
 extern void snd_gf1_write_addr(snd_gus_card_t * gus, unsigned char reg, unsigned int addr, short w_16bit);
 extern unsigned int snd_gf1_read_addr(snd_gus_card_t * gus, unsigned char reg, short w_16bit);
 extern void snd_gf1_i_ctrl_stop(snd_gus_card_t * gus, unsigned char reg);
@@ -544,9 +541,6 @@ extern inline unsigned short snd_gf1_i_r
 {
 	return snd_gf1_i_look16(gus, reg | 0x80);
 }
-extern void snd_gf1_i_adlib_write(snd_gus_card_t * gus, unsigned char reg, unsigned char data);
-extern void snd_gf1_i_write_addr(snd_gus_card_t * gus, unsigned char reg, unsigned int addr, short w_16bit);
-extern unsigned int snd_gf1_i_read_addr(snd_gus_card_t * gus, unsigned char reg, short w_16bit);
 
 extern void snd_gf1_select_active_voices(snd_gus_card_t * gus);
 
@@ -580,10 +574,6 @@ extern void snd_gf1_lfo_command(snd_gus_
 
 void snd_gf1_mem_lock(snd_gf1_mem_t * alloc, int xup);
 int snd_gf1_mem_xfree(snd_gf1_mem_t * alloc, snd_gf1_mem_block_t * block);
-snd_gf1_mem_block_t *snd_gf1_mem_look(snd_gf1_mem_t * alloc,
-				      unsigned int address);
-snd_gf1_mem_block_t *snd_gf1_mem_share(snd_gf1_mem_t * alloc,
-				       unsigned int *share_id);
 snd_gf1_mem_block_t *snd_gf1_mem_alloc(snd_gf1_mem_t * alloc, int owner,
 				       char *name, int size, int w_16,
 				       int align, unsigned int *share_id);
@@ -608,23 +598,13 @@ int snd_gf1_dma_transfer_block(snd_gus_c
 /* gus_volume.c */
 
 unsigned short snd_gf1_lvol_to_gvol_raw(unsigned int vol);
-unsigned int snd_gf1_gvol_to_lvol_raw(unsigned short gf1_vol);
-unsigned int snd_gf1_calc_ramp_rate(snd_gus_card_t * gus,
-				    unsigned short start,
-				    unsigned short end,
-				    unsigned int us);
 unsigned short snd_gf1_translate_freq(snd_gus_card_t * gus, unsigned int freq2);
-unsigned short snd_gf1_compute_pitchbend(unsigned short pitchbend, unsigned short sens);
-unsigned short snd_gf1_compute_freq(unsigned int freq,
-				    unsigned int rate,
-				    unsigned short mix_rate);
 
 /* gus_reset.c */
 
 void snd_gf1_set_default_handlers(snd_gus_card_t * gus, unsigned int what);
 void snd_gf1_smart_stop_voice(snd_gus_card_t * gus, unsigned short voice);
 void snd_gf1_stop_voice(snd_gus_card_t * gus, unsigned short voice);
-void snd_gf1_clear_voices(snd_gus_card_t * gus, unsigned short v_min, unsigned short v_max);
 void snd_gf1_stop_voices(snd_gus_card_t * gus, unsigned short v_min, unsigned short v_max);
 snd_gus_voice_t *snd_gf1_alloc_voice(snd_gus_card_t * gus, int type, int client, int port);
 void snd_gf1_free_voice(snd_gus_card_t * gus, snd_gus_voice_t *voice);
@@ -641,9 +621,6 @@ int snd_gf1_pcm_new(snd_gus_card_t * gus
 
 #ifdef CONFIG_SND_DEBUG
 extern void snd_gf1_print_voice_registers(snd_gus_card_t * gus);
-extern void snd_gf1_print_global_registers(snd_gus_card_t * gus);
-extern void snd_gf1_print_setup_registers(snd_gus_card_t * gus);
-extern void snd_gf1_peek_print_block(snd_gus_card_t * gus, unsigned int addr, int count, int w_16bit);
 #endif
 
 /* gus.c */
diff --git a/include/sound/hdspm.h b/include/sound/hdspm.h
new file mode 100644
--- /dev/null
+++ b/include/sound/hdspm.h
@@ -0,0 +1,131 @@
+#ifndef __SOUND_HDSPM_H		/* -*- linux-c -*- */
+#define __SOUND_HDSPM_H
+/*
+ *   Copyright (C) 2003 Winfried Ritsch (IEM)
+ *   based on hdsp.h from Thomas Charbonnel (thomas@undata.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.
+ */
+
+/* Maximum channels is 64 even on 56Mode you have 64playbacks to matrix */
+#define HDSPM_MAX_CHANNELS      64
+
+/* -------------------- IOCTL Peak/RMS Meters -------------------- */
+
+typedef struct _snd_hdspm_peak_rms hdspm_peak_rms_t;
+
+/* peam rms level structure like we get from hardware 
+  
+   maybe in future we can memory map it so I just copy it
+   to user on ioctl call now an dont change anything
+   rms are made out of low and high values
+   where (long) ????_rms = (????_rms_l >> 8) + ((????_rms_h & 0xFFFFFF00)<<24)
+   (i asume so from the code)
+*/
+
+struct _snd_hdspm_peak_rms {
+
+	unsigned int level_offset[1024];
+
+	unsigned int input_peak[64];
+	unsigned int playback_peak[64];
+	unsigned int output_peak[64];
+	unsigned int xxx_peak[64];	/* not used */
+
+	unsigned int reserved[256];	/* not used */
+
+	unsigned int input_rms_l[64];
+	unsigned int playback_rms_l[64];
+	unsigned int output_rms_l[64];
+	unsigned int xxx_rms_l[64];	/* not used */
+
+	unsigned int input_rms_h[64];
+	unsigned int playback_rms_h[64];
+	unsigned int output_rms_h[64];
+	unsigned int xxx_rms_h[64];	/* not used */
+};
+
+struct sndrv_hdspm_peak_rms_ioctl {
+	hdspm_peak_rms_t *peak;
+};
+
+/* use indirect access due to the limit of ioctl bit size */
+#define SNDRV_HDSPM_IOCTL_GET_PEAK_RMS _IOR('H', 0x40, struct sndrv_hdspm_peak_rms_ioctl)
+
+/* ------------ CONFIG block IOCTL ---------------------- */
+
+typedef struct _snd_hdspm_config_info hdspm_config_info_t;
+
+struct _snd_hdspm_config_info {
+	unsigned char pref_sync_ref;
+	unsigned char wordclock_sync_check;
+	unsigned char madi_sync_check;
+	unsigned int system_sample_rate;
+	unsigned int autosync_sample_rate;
+	unsigned char system_clock_mode;
+	unsigned char clock_source;
+	unsigned char autosync_ref;
+	unsigned char line_out;
+	unsigned int passthru;
+	unsigned int analog_out;
+};
+
+#define SNDRV_HDSPM_IOCTL_GET_CONFIG_INFO _IOR('H', 0x41, hdspm_config_info_t)
+
+
+/* get Soundcard Version */
+
+typedef struct _snd_hdspm_version hdspm_version_t;
+
+struct _snd_hdspm_version {
+	unsigned short firmware_rev;
+};
+
+#define SNDRV_HDSPM_IOCTL_GET_VERSION _IOR('H', 0x43, hdspm_version_t)
+
+
+/* ------------- get Matrix Mixer IOCTL --------------- */
+
+/* MADI mixer: 64inputs+64playback in 64outputs = 8192 => *4Byte = 32768 Bytes */
+
+/* organisation is 64 channelfader in a continous memory block */
+/* equivalent to hardware definition, maybe for future feature of mmap of them */
+/* each of 64 outputs has 64 infader and 64 outfader: 
+   Ins to Outs mixer[out].in[in], Outstreams to Outs mixer[out].pb[pb] */
+
+#define HDSPM_MIXER_CHANNELS HDSPM_MAX_CHANNELS
+
+typedef struct _snd_hdspm_channelfader snd_hdspm_channelfader_t;
+
+struct _snd_hdspm_channelfader {
+	unsigned int in[HDSPM_MIXER_CHANNELS];
+	unsigned int pb[HDSPM_MIXER_CHANNELS];
+};
+
+typedef struct _snd_hdspm_mixer hdspm_mixer_t;
+
+struct _snd_hdspm_mixer {
+	snd_hdspm_channelfader_t ch[HDSPM_MIXER_CHANNELS];
+};
+
+struct sndrv_hdspm_mixer_ioctl {
+	hdspm_mixer_t *mixer;
+};
+
+/* use indirect access due to the limit of ioctl bit size */
+#define SNDRV_HDSPM_IOCTL_GET_MIXER _IOR('H', 0x44, struct sndrv_hdspm_mixer_ioctl)
+
+#endif				/* __SOUND_HDSPM_H */
diff --git a/include/sound/pcm.h b/include/sound/pcm.h
--- a/include/sound/pcm.h
+++ b/include/sound/pcm.h
@@ -848,23 +848,6 @@ int snd_interval_ratnum(snd_interval_t *
 
 void _snd_pcm_hw_params_any(snd_pcm_hw_params_t *params);
 void _snd_pcm_hw_param_setempty(snd_pcm_hw_params_t *params, snd_pcm_hw_param_t var);
-int snd_pcm_hw_param_min(snd_pcm_substream_t *substream, 
-			 snd_pcm_hw_params_t *params,
-			 snd_pcm_hw_param_t var,
-			 unsigned int val, int *dir);
-int snd_pcm_hw_param_max(snd_pcm_substream_t *substream, 
-			 snd_pcm_hw_params_t *params,
-			 snd_pcm_hw_param_t var,
-			 unsigned int val, int *dir);
-int snd_pcm_hw_param_setinteger(snd_pcm_substream_t *substream, 
-				snd_pcm_hw_params_t *params,
-				snd_pcm_hw_param_t var);
-int snd_pcm_hw_param_first(snd_pcm_substream_t *substream, 
-			   snd_pcm_hw_params_t *params,
-			   snd_pcm_hw_param_t var, int *dir);
-int snd_pcm_hw_param_last(snd_pcm_substream_t *substream, 
-			  snd_pcm_hw_params_t *params,
-			  snd_pcm_hw_param_t var, int *dir);
 int snd_pcm_hw_param_near(snd_pcm_substream_t *substream, 
 			  snd_pcm_hw_params_t *params,
 			  snd_pcm_hw_param_t var, 
@@ -876,7 +859,6 @@ int snd_pcm_hw_param_set(snd_pcm_substre
 int snd_pcm_hw_params_choose(snd_pcm_substream_t *substream, snd_pcm_hw_params_t *params);
 
 int snd_pcm_hw_refine(snd_pcm_substream_t *substream, snd_pcm_hw_params_t *params);
-int snd_pcm_hw_params(snd_pcm_substream_t *substream, snd_pcm_hw_params_t *params);
 
 int snd_pcm_hw_constraints_init(snd_pcm_substream_t *substream);
 int snd_pcm_hw_constraints_complete(snd_pcm_substream_t *substream);
@@ -922,8 +904,22 @@ int snd_pcm_format_unsigned(snd_pcm_form
 int snd_pcm_format_linear(snd_pcm_format_t format);
 int snd_pcm_format_little_endian(snd_pcm_format_t format);
 int snd_pcm_format_big_endian(snd_pcm_format_t format);
+/**
+ * snd_pcm_format_cpu_endian - Check the PCM format is CPU-endian
+ * @format: the format to check
+ *
+ * Returns 1 if the given PCM format is CPU-endian, 0 if
+ * opposite, or a negative error code if endian not specified.
+ */
+/* int snd_pcm_format_cpu_endian(snd_pcm_format_t format); */
+#ifdef SNDRV_LITTLE_ENDIAN
+#define snd_pcm_format_cpu_endian	snd_pcm_format_little_endian
+#else
+#define snd_pcm_format_cpu_endian	snd_pcm_format_big_endian
+#endif
 int snd_pcm_format_width(snd_pcm_format_t format);			/* in bits */
 int snd_pcm_format_physical_width(snd_pcm_format_t format);		/* in bits */
+ssize_t snd_pcm_format_size(snd_pcm_format_t format, size_t samples);
 const unsigned char *snd_pcm_format_silence_64(snd_pcm_format_t format);
 int snd_pcm_format_set_silence(snd_pcm_format_t format, void *buf, unsigned int frames);
 snd_pcm_format_t snd_pcm_build_linear_format(int width, int unsignd, int big_endian);
diff --git a/include/sound/seq_midi_event.h b/include/sound/seq_midi_event.h
--- a/include/sound/seq_midi_event.h
+++ b/include/sound/seq_midi_event.h
@@ -41,9 +41,7 @@ struct snd_midi_event_t {
 };
 
 int snd_midi_event_new(int bufsize, snd_midi_event_t **rdev);
-int snd_midi_event_resize_buffer(snd_midi_event_t *dev, int bufsize);
 void snd_midi_event_free(snd_midi_event_t *dev);
-void snd_midi_event_init(snd_midi_event_t *dev);
 void snd_midi_event_reset_encode(snd_midi_event_t *dev);
 void snd_midi_event_reset_decode(snd_midi_event_t *dev);
 void snd_midi_event_no_status(snd_midi_event_t *dev, int on);
diff --git a/include/sound/seq_virmidi.h b/include/sound/seq_virmidi.h
--- a/include/sound/seq_virmidi.h
+++ b/include/sound/seq_virmidi.h
@@ -79,6 +79,5 @@ struct _snd_virmidi_dev {
 #define SNDRV_VIRMIDI_SEQ_DISPATCH	2
 
 int snd_virmidi_new(snd_card_t *card, int device, snd_rawmidi_t **rrmidi);
-int snd_virmidi_receive(snd_rawmidi_t *rmidi, snd_seq_event_t *ev);
 
 #endif /* __SOUND_SEQ_VIRMIDI */
diff --git a/include/sound/timer.h b/include/sound/timer.h
--- a/include/sound/timer.h
+++ b/include/sound/timer.h
@@ -152,6 +152,4 @@ extern int snd_timer_pause(snd_timer_ins
 
 extern void snd_timer_interrupt(snd_timer_t * timer, unsigned long ticks_left);
 
-extern unsigned int snd_timer_system_resolution(void);
-
 #endif /* __SOUND_TIMER_H */
diff --git a/include/sound/version.h b/include/sound/version.h
--- a/include/sound/version.h
+++ b/include/sound/version.h
@@ -1,3 +1,3 @@
 /* include/version.h.  Generated by configure.  */
-#define CONFIG_SND_VERSION "1.0.9rc2"
-#define CONFIG_SND_DATE "  (Thu Mar 24 10:33:39 2005 UTC)"
+#define CONFIG_SND_VERSION "1.0.9b"
+#define CONFIG_SND_DATE " (Thu Jul 28 12:20:13 2005 UTC)"
diff --git a/include/sound/vx_core.h b/include/sound/vx_core.h
--- a/include/sound/vx_core.h
+++ b/include/sound/vx_core.h
@@ -233,37 +233,37 @@ irqreturn_t snd_vx_irq_handler(int irq, 
 /*
  * lowlevel functions
  */
-inline static int vx_test_and_ack(vx_core_t *chip)
+static inline int vx_test_and_ack(vx_core_t *chip)
 {
 	snd_assert(chip->ops->test_and_ack, return -ENXIO);
 	return chip->ops->test_and_ack(chip);
 }
 
-inline static void vx_validate_irq(vx_core_t *chip, int enable)
+static inline void vx_validate_irq(vx_core_t *chip, int enable)
 {
 	snd_assert(chip->ops->validate_irq, return);
 	chip->ops->validate_irq(chip, enable);
 }
 
-inline static unsigned char snd_vx_inb(vx_core_t *chip, int reg)
+static inline unsigned char snd_vx_inb(vx_core_t *chip, int reg)
 {
 	snd_assert(chip->ops->in8, return 0);
 	return chip->ops->in8(chip, reg);
 }
 
-inline static unsigned int snd_vx_inl(vx_core_t *chip, int reg)
+static inline unsigned int snd_vx_inl(vx_core_t *chip, int reg)
 {
 	snd_assert(chip->ops->in32, return 0);
 	return chip->ops->in32(chip, reg);
 }
 
-inline static void snd_vx_outb(vx_core_t *chip, int reg, unsigned char val)
+static inline void snd_vx_outb(vx_core_t *chip, int reg, unsigned char val)
 {
 	snd_assert(chip->ops->out8, return);
 	chip->ops->out8(chip, reg, val);
 }
 
-inline static void snd_vx_outl(vx_core_t *chip, int reg, unsigned int val)
+static inline void snd_vx_outl(vx_core_t *chip, int reg, unsigned int val)
 {
 	snd_assert(chip->ops->out32, return);
 	chip->ops->out32(chip, reg, val);
@@ -303,14 +303,14 @@ int snd_vx_check_reg_bit(vx_core_t *chip
 /*
  * pseudo-DMA transfer
  */
-inline static void vx_pseudo_dma_write(vx_core_t *chip, snd_pcm_runtime_t *runtime,
+static inline void vx_pseudo_dma_write(vx_core_t *chip, snd_pcm_runtime_t *runtime,
 				       vx_pipe_t *pipe, int count)
 {
 	snd_assert(chip->ops->dma_write, return);
 	chip->ops->dma_write(chip, runtime, pipe, count);
 }
 
-inline static void vx_pseudo_dma_read(vx_core_t *chip, snd_pcm_runtime_t *runtime,
+static inline void vx_pseudo_dma_read(vx_core_t *chip, snd_pcm_runtime_t *runtime,
 				      vx_pipe_t *pipe, int count)
 {
 	snd_assert(chip->ops->dma_read, return);
diff --git a/init/Kconfig b/init/Kconfig
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -164,6 +164,7 @@ config SYSCTL
 
 config AUDIT
 	bool "Auditing support"
+	depends on NET
 	default y if SECURITY_SELINUX
 	help
 	  Enable auditing infrastructure that can be used with another
@@ -173,7 +174,7 @@ config AUDIT
 
 config AUDITSYSCALL
 	bool "Enable system-call auditing support"
-	depends on AUDIT && (X86 || PPC64 || ARCH_S390 || IA64 || UML)
+	depends on AUDIT && (X86 || PPC || PPC64 || ARCH_S390 || IA64 || UML || SPARC64)
 	default y if SECURITY_SELINUX
 	help
 	  Enable low-overhead system-call auditing infrastructure that
@@ -230,7 +231,7 @@ config CPUSETS
 	bool "Cpuset support"
 	depends on SMP
 	help
-	  This options will let you create and manage CPUSET's which
+	  This option will let you create and manage CPUSETs which
 	  allow dynamically partitioning a system into sets of CPUs and
 	  Memory Nodes and assigning tasks to run only within those sets.
 	  This is primarily useful on large SMP or NUMA systems.
diff --git a/init/calibrate.c b/init/calibrate.c
--- a/init/calibrate.c
+++ b/init/calibrate.c
@@ -8,6 +8,8 @@
 #include <linux/delay.h>
 #include <linux/init.h>
 
+#include <asm/timex.h>
+
 static unsigned long preset_lpj;
 static int __init lpj_setup(char *str)
 {
@@ -17,6 +19,92 @@ static int __init lpj_setup(char *str)
 
 __setup("lpj=", lpj_setup);
 
+#ifdef ARCH_HAS_READ_CURRENT_TIMER
+
+/* This routine uses the read_current_timer() routine and gets the
+ * loops per jiffy directly, instead of guessing it using delay().
+ * Also, this code tries to handle non-maskable asynchronous events
+ * (like SMIs)
+ */
+#define DELAY_CALIBRATION_TICKS			((HZ < 100) ? 1 : (HZ/100))
+#define MAX_DIRECT_CALIBRATION_RETRIES		5
+
+static unsigned long __devinit calibrate_delay_direct(void)
+{
+	unsigned long pre_start, start, post_start;
+	unsigned long pre_end, end, post_end;
+	unsigned long start_jiffies;
+	unsigned long tsc_rate_min, tsc_rate_max;
+	unsigned long good_tsc_sum = 0;
+	unsigned long good_tsc_count = 0;
+	int i;
+
+	if (read_current_timer(&pre_start) < 0 )
+		return 0;
+
+	/*
+	 * A simple loop like
+	 *	while ( jiffies < start_jiffies+1)
+	 *		start = read_current_timer();
+	 * will not do. As we don't really know whether jiffy switch
+	 * happened first or timer_value was read first. And some asynchronous
+	 * event can happen between these two events introducing errors in lpj.
+	 *
+	 * So, we do
+	 * 1. pre_start <- When we are sure that jiffy switch hasn't happened
+	 * 2. check jiffy switch
+	 * 3. start <- timer value before or after jiffy switch
+	 * 4. post_start <- When we are sure that jiffy switch has happened
+	 *
+	 * Note, we don't know anything about order of 2 and 3.
+	 * Now, by looking at post_start and pre_start difference, we can
+	 * check whether any asynchronous event happened or not
+	 */
+
+	for (i = 0; i < MAX_DIRECT_CALIBRATION_RETRIES; i++) {
+		pre_start = 0;
+		read_current_timer(&start);
+		start_jiffies = jiffies;
+		while (jiffies <= (start_jiffies + 1)) {
+			pre_start = start;
+			read_current_timer(&start);
+		}
+		read_current_timer(&post_start);
+
+		pre_end = 0;
+		end = post_start;
+		while (jiffies <=
+		       (start_jiffies + 1 + DELAY_CALIBRATION_TICKS)) {
+			pre_end = end;
+			read_current_timer(&end);
+		}
+		read_current_timer(&post_end);
+
+		tsc_rate_max = (post_end - pre_start) / DELAY_CALIBRATION_TICKS;
+		tsc_rate_min = (pre_end - post_start) / DELAY_CALIBRATION_TICKS;
+
+		/*
+	 	 * If the upper limit and lower limit of the tsc_rate is
+		 * >= 12.5% apart, redo calibration.
+		 */
+		if (pre_start != 0 && pre_end != 0 &&
+		    (tsc_rate_max - tsc_rate_min) < (tsc_rate_max >> 3)) {
+			good_tsc_count++;
+			good_tsc_sum += tsc_rate_max;
+		}
+	}
+
+	if (good_tsc_count)
+		return (good_tsc_sum/good_tsc_count);
+
+	printk(KERN_WARNING "calibrate_delay_direct() failed to get a good "
+	       "estimate for loops_per_jiffy.\nProbably due to long platform interrupts. Consider using \"lpj=\" boot option.\n");
+	return 0;
+}
+#else
+static unsigned long __devinit calibrate_delay_direct(void) {return 0;}
+#endif
+
 /*
  * This is the number of bits of precision for the loops_per_jiffy.  Each
  * bit takes on average 1.5/HZ seconds.  This (like the original) is a little
@@ -35,6 +123,12 @@ void __devinit calibrate_delay(void)
 			"%lu.%02lu BogoMIPS preset\n",
 			loops_per_jiffy/(500000/HZ),
 			(loops_per_jiffy/(5000/HZ)) % 100);
+	} else if ((loops_per_jiffy = calibrate_delay_direct()) != 0) {
+		printk("Calibrating delay using timer specific routine.. ");
+		printk("%lu.%02lu BogoMIPS (lpj=%lu)\n",
+			loops_per_jiffy/(500000/HZ),
+			(loops_per_jiffy/(5000/HZ)) % 100,
+			loops_per_jiffy);
 	} else {
 		loops_per_jiffy = (1<<12);
 
diff --git a/init/do_mounts.c b/init/do_mounts.c
--- a/init/do_mounts.c
+++ b/init/do_mounts.c
@@ -7,6 +7,7 @@
 #include <linux/root_dev.h>
 #include <linux/security.h>
 #include <linux/delay.h>
+#include <linux/mount.h>
 
 #include <linux/nfs_fs.h>
 #include <linux/nfs_fs_sb.h>
@@ -25,8 +26,6 @@ static char __initdata saved_root_name[6
 /* this is initialized in init/main.c */
 dev_t ROOT_DEV;
 
-EXPORT_SYMBOL(ROOT_DEV);
-
 static int __init load_ramdisk(char *str)
 {
 	rd_doload = simple_strtol(str,NULL,0) & 3;
diff --git a/init/do_mounts.h b/init/do_mounts.h
--- a/init/do_mounts.h
+++ b/init/do_mounts.h
@@ -9,7 +9,6 @@
 #include <linux/major.h>
 #include <linux/root_dev.h>
 
-dev_t name_to_dev_t(char *name);
 void  change_floppy(char *fmt, ...);
 void  mount_block_root(char *name, int flags);
 void  mount_root(void);
diff --git a/init/do_mounts_initrd.c b/init/do_mounts_initrd.c
--- a/init/do_mounts_initrd.c
+++ b/init/do_mounts_initrd.c
@@ -41,7 +41,7 @@ static int __init do_linuxrc(void * shel
 static void __init handle_initrd(void)
 {
 	int error;
-	int i, pid;
+	int pid;
 
 	real_root_dev = new_encode_dev(ROOT_DEV);
 	create_dev("/dev/root.old", Root_RAM0, NULL);
@@ -58,7 +58,7 @@ static void __init handle_initrd(void)
 
 	pid = kernel_thread(do_linuxrc, "/linuxrc", SIGCHLD);
 	if (pid > 0) {
-		while (pid != sys_wait4(-1, &i, 0, NULL))
+		while (pid != sys_wait4(-1, NULL, 0, NULL))
 			yield();
 	}
 
@@ -86,7 +86,10 @@ static void __init handle_initrd(void)
 		printk("okay\n");
 	else {
 		int fd = sys_open("/dev/root.old", O_RDWR, 0);
-		printk("failed\n");
+		if (error == -ENOENT)
+			printk("/initrd does not exist. Ignored.\n");
+		else
+			printk("failed\n");
 		printk(KERN_NOTICE "Unmounting old root\n");
 		sys_umount("/old", MNT_DETACH);
 		printk(KERN_NOTICE "Trying to free ramdisk memory ... ");
diff --git a/init/main.c b/init/main.c
--- a/init/main.c
+++ b/init/main.c
@@ -51,6 +51,7 @@
 #include <asm/io.h>
 #include <asm/bugs.h>
 #include <asm/setup.h>
+#include <asm/sections.h>
 
 /*
  * This is one of the first .c files built. Error out early
@@ -323,8 +324,6 @@ static void __init setup_per_cpu_areas(v
 {
 	unsigned long size, i;
 	char *ptr;
-	/* Created by linker magic */
-	extern char __per_cpu_start[], __per_cpu_end[];
 
 	/* Copy section for each CPU (we discard the original) */
 	size = ALIGN(__per_cpu_end - __per_cpu_start, SMP_CACHE_BYTES);
@@ -383,6 +382,13 @@ static void noinline rest_init(void)
 	numa_default_policy();
 	unlock_kernel();
 	preempt_enable_no_resched();
+
+	/*
+	 * The boot idle thread must execute schedule()
+	 * at least one to get things moving:
+	 */
+	schedule();
+
 	cpu_idle();
 } 
 
@@ -490,6 +496,7 @@ asmlinkage void __init start_kernel(void
 	vfs_caches_init_early();
 	mem_init();
 	kmem_cache_init();
+	setup_per_cpu_pageset();
 	numa_policy_init();
 	if (late_time_init)
 		late_time_init();
diff --git a/ipc/compat.c b/ipc/compat.c
--- a/ipc/compat.c
+++ b/ipc/compat.c
@@ -572,6 +572,7 @@ static inline int put_compat_shminfo(str
 	err |= __put_user(smi->shmmni, &up->shmmni);
 	err |= __put_user(smi->shmseg, &up->shmseg);
 	err |= __put_user(smi->shmall, &up->shmall);
+	return err;
 }
 
 static inline int put_compat_shm_info(struct shm_info __user *ip,
diff --git a/ipc/sem.c b/ipc/sem.c
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -895,7 +895,7 @@ static inline void lock_semundo(void)
 	struct sem_undo_list *undo_list;
 
 	undo_list = current->sysvsem.undo_list;
-	if ((undo_list != NULL) && (atomic_read(&undo_list->refcnt) != 1))
+	if (undo_list)
 		spin_lock(&undo_list->lock);
 }
 
@@ -915,7 +915,7 @@ static inline void unlock_semundo(void)
 	struct sem_undo_list *undo_list;
 
 	undo_list = current->sysvsem.undo_list;
-	if ((undo_list != NULL) && (atomic_read(&undo_list->refcnt) != 1))
+	if (undo_list)
 		spin_unlock(&undo_list->lock);
 }
 
@@ -943,9 +943,7 @@ static inline int get_undo_list(struct s
 		if (undo_list == NULL)
 			return -ENOMEM;
 		memset(undo_list, 0, size);
-		/* don't initialize unodhd->lock here.  It's done
-		 * in copy_semundo() instead.
-		 */
+		spin_lock_init(&undo_list->lock);
 		atomic_set(&undo_list->refcnt, 1);
 		current->sysvsem.undo_list = undo_list;
 	}
@@ -1054,7 +1052,7 @@ asmlinkage long sys_semtimedop(int semid
 	struct sembuf fast_sops[SEMOPM_FAST];
 	struct sembuf* sops = fast_sops, *sop;
 	struct sem_undo *un;
-	int undos = 0, decrease = 0, alter = 0, max;
+	int undos = 0, alter = 0, max;
 	struct sem_queue queue;
 	unsigned long jiffies_left = 0;
 
@@ -1089,13 +1087,10 @@ asmlinkage long sys_semtimedop(int semid
 		if (sop->sem_num >= max)
 			max = sop->sem_num;
 		if (sop->sem_flg & SEM_UNDO)
-			undos++;
-		if (sop->sem_op < 0)
-			decrease = 1;
-		if (sop->sem_op > 0)
+			undos = 1;
+		if (sop->sem_op != 0)
 			alter = 1;
 	}
-	alter |= decrease;
 
 retry_undos:
 	if (undos) {
@@ -1234,8 +1229,6 @@ int copy_semundo(unsigned long clone_fla
 		error = get_undo_list(&undo_list);
 		if (error)
 			return error;
-		if (atomic_read(&undo_list->refcnt) == 1)
-			spin_lock_init(&undo_list->lock);
 		atomic_inc(&undo_list->refcnt);
 		tsk->sysvsem.undo_list = undo_list;
 	} else 
diff --git a/ipc/shm.c b/ipc/shm.c
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -170,7 +170,7 @@ static struct vm_operations_struct shm_v
 	.open	= shm_open,	/* callback for a new vm-area open */
 	.close	= shm_close,	/* callback for when the vm-area is released */
 	.nopage	= shmem_nopage,
-#ifdef CONFIG_NUMA
+#if defined(CONFIG_NUMA) && defined(CONFIG_SHMEM)
 	.set_policy = shmem_set_policy,
 	.get_policy = shmem_get_policy,
 #endif
diff --git a/ipc/util.h b/ipc/util.h
--- a/ipc/util.h
+++ b/ipc/util.h
@@ -67,7 +67,7 @@ int ipc_checkid(struct ipc_ids* ids, str
 void kernel_to_ipc64_perm(struct kern_ipc_perm *in, struct ipc64_perm *out);
 void ipc64_perm_to_ipc_perm(struct ipc64_perm *in, struct ipc_perm *out);
 
-#if defined(__ia64__) || defined(__x86_64__) || defined(__hppa__)
+#if defined(__ia64__) || defined(__x86_64__) || defined(__hppa__) || defined(__XTENSA__)
   /* On IA-64, we always use the "64-bit version" of the IPC structures.  */ 
 # define ipc_parse_version(cmd)	IPC_64
 #else
diff --git a/kernel/Kconfig.hz b/kernel/Kconfig.hz
new file mode 100644
--- /dev/null
+++ b/kernel/Kconfig.hz
@@ -0,0 +1,46 @@
+#
+# Timer Interrupt Frequency Configuration
+#
+
+choice
+	prompt "Timer frequency"
+	default HZ_250
+	help
+	 Allows the configuration of the timer frequency. It is customary
+	 to have the timer interrupt run at 1000 HZ but 100 HZ may be more
+	 beneficial for servers and NUMA systems that do not need to have
+	 a fast response for user interaction and that may experience bus
+	 contention and cacheline bounces as a result of timer interrupts.
+	 Note that the timer interrupt occurs on each processor in an SMP
+	 environment leading to NR_CPUS * HZ number of timer interrupts
+	 per second.
+
+
+	config HZ_100
+		bool "100 HZ"
+	help
+	  100 HZ is a typical choice for servers, SMP and NUMA systems
+	  with lots of processors that may show reduced performance if
+	  too many timer interrupts are occurring.
+
+	config HZ_250
+		bool "250 HZ"
+	help
+	 250 HZ is a good compromise choice allowing server performance
+	 while also showing good interactive responsiveness even
+	 on SMP and NUMA systems.
+
+	config HZ_1000
+		bool "1000 HZ"
+	help
+	 1000 HZ is the preferred choice for desktop systems and other
+	 systems requiring fast interactive responses to events.
+
+endchoice
+
+config HZ
+	int
+	default 100 if HZ_100
+	default 250 if HZ_250
+	default 1000 if HZ_1000
+
diff --git a/kernel/Kconfig.preempt b/kernel/Kconfig.preempt
new file mode 100644
--- /dev/null
+++ b/kernel/Kconfig.preempt
@@ -0,0 +1,65 @@
+
+choice
+	prompt "Preemption Model"
+	default PREEMPT_NONE
+
+config PREEMPT_NONE
+	bool "No Forced Preemption (Server)"
+	help
+	  This is the traditional Linux preemption model, geared towards
+	  throughput. It will still provide good latencies most of the
+	  time, but there are no guarantees and occasional longer delays
+	  are possible.
+
+	  Select this option if you are building a kernel for a server or
+	  scientific/computation system, or if you want to maximize the
+	  raw processing power of the kernel, irrespective of scheduling
+	  latencies.
+
+config PREEMPT_VOLUNTARY
+	bool "Voluntary Kernel Preemption (Desktop)"
+	help
+	  This option reduces the latency of the kernel by adding more
+	  "explicit preemption points" to the kernel code. These new
+	  preemption points have been selected to reduce the maximum
+	  latency of rescheduling, providing faster application reactions,
+	  at the cost of slighly lower throughput.
+
+	  This allows reaction to interactive events by allowing a
+	  low priority process to voluntarily preempt itself even if it
+	  is in kernel mode executing a system call. This allows
+	  applications to run more 'smoothly' even when the system is
+	  under load.
+
+	  Select this if you are building a kernel for a desktop system.
+
+config PREEMPT
+	bool "Preemptible Kernel (Low-Latency Desktop)"
+	help
+	  This option reduces the latency of the kernel by making
+	  all kernel code (that is not executing in a critical section)
+	  preemptible.  This allows reaction to interactive events by
+	  permitting a low priority process to be preempted involuntarily
+	  even if it is in kernel mode executing a system call and would
+	  otherwise not be about to reach a natural preemption point.
+	  This allows applications to run more 'smoothly' even when the
+	  system is under load, at the cost of slighly lower throughput
+	  and a slight runtime overhead to kernel code.
+
+	  Select this if you are building a kernel for a desktop or
+	  embedded system with latency requirements in the milliseconds
+	  range.
+
+endchoice
+
+config PREEMPT_BKL
+	bool "Preempt The Big Kernel Lock"
+	depends on SMP || PREEMPT
+	default y
+	help
+	  This option reduces the latency of the kernel by making the
+	  big kernel lock preemptible.
+
+	  Say Y here if you are building a kernel for a desktop system.
+	  Say N if you are unsure.
+
diff --git a/kernel/Makefile b/kernel/Makefile
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -17,6 +17,7 @@ obj-$(CONFIG_MODULES) += module.o
 obj-$(CONFIG_KALLSYMS) += kallsyms.o
 obj-$(CONFIG_PM) += power/
 obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o
+obj-$(CONFIG_KEXEC) += kexec.o
 obj-$(CONFIG_COMPAT) += compat.o
 obj-$(CONFIG_CPUSETS) += cpuset.o
 obj-$(CONFIG_IKCONFIG) += configs.o
@@ -27,6 +28,7 @@ obj-$(CONFIG_AUDITSYSCALL) += auditsc.o
 obj-$(CONFIG_KPROBES) += kprobes.o
 obj-$(CONFIG_SYSFS) += ksysfs.o
 obj-$(CONFIG_GENERIC_HARDIRQS) += irq/
+obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
 obj-$(CONFIG_SECCOMP) += seccomp.o
 
 ifneq ($(CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER),y)
diff --git a/kernel/audit.c b/kernel/audit.c
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -46,6 +46,8 @@
 #include <asm/types.h>
 #include <linux/mm.h>
 #include <linux/module.h>
+#include <linux/err.h>
+#include <linux/kthread.h>
 
 #include <linux/audit.h>
 
@@ -68,7 +70,7 @@ static int	audit_failure = AUDIT_FAIL_PR
 
 /* If audit records are to be written to the netlink socket, audit_pid
  * contains the (non-zero) pid. */
-static int	audit_pid;
+int		audit_pid;
 
 /* If audit_limit is non-zero, limit the rate of sending audit records
  * to that number per second.  This prevents DoS attacks, but results in
@@ -77,7 +79,10 @@ static int	audit_rate_limit;
 
 /* Number of outstanding audit_buffers allowed. */
 static int	audit_backlog_limit = 64;
-static atomic_t	audit_backlog	    = ATOMIC_INIT(0);
+
+/* The identity of the user shutting down the audit system. */
+uid_t		audit_sig_uid = -1;
+pid_t		audit_sig_pid = -1;
 
 /* Records can be lost in several ways:
    0) [suppressed in audit_alloc]
@@ -91,19 +96,17 @@ static atomic_t    audit_lost = ATOMIC_I
 /* The netlink socket. */
 static struct sock *audit_sock;
 
-/* There are two lists of audit buffers.  The txlist contains audit
- * buffers that cannot be sent immediately to the netlink device because
- * we are in an irq context (these are sent later in a tasklet).
- *
- * The second list is a list of pre-allocated audit buffers (if more
+/* The audit_freelist is a list of pre-allocated audit buffers (if more
  * than AUDIT_MAXFREE are in use, the audit buffer is freed instead of
  * being placed on the freelist). */
-static DEFINE_SPINLOCK(audit_txlist_lock);
 static DEFINE_SPINLOCK(audit_freelist_lock);
 static int	   audit_freelist_count = 0;
-static LIST_HEAD(audit_txlist);
 static LIST_HEAD(audit_freelist);
 
+static struct sk_buff_head audit_skb_queue;
+static struct task_struct *kauditd_task;
+static DECLARE_WAIT_QUEUE_HEAD(kauditd_wait);
+
 /* There are three lists of rules -- one to search at task creation
  * time, one to search at syscall entry time, and another to search at
  * syscall exit time. */
@@ -112,7 +115,7 @@ static LIST_HEAD(audit_entlist);
 static LIST_HEAD(audit_extlist);
 
 /* The netlink socket is only to be read by 1 CPU, which lets us assume
- * that list additions and deletions never happen simultaneiously in
+ * that list additions and deletions never happen simultaneously in
  * auditsc.c */
 static DECLARE_MUTEX(audit_netlink_sem);
 
@@ -132,21 +135,14 @@ static DECLARE_MUTEX(audit_netlink_sem);
  * use simultaneously. */
 struct audit_buffer {
 	struct list_head     list;
-	struct sk_buff_head  sklist;	/* formatted skbs ready to send */
+	struct sk_buff       *skb;	/* formatted skb ready to send */
 	struct audit_context *ctx;	/* NULL or associated context */
-	int		     len;	/* used area of tmp */
-	char		     tmp[AUDIT_BUFSIZ];
-
-				/* Pointer to header and contents */
-	struct nlmsghdr      *nlh;
-	int		     total;
-	int		     type;
-	int		     pid;
 };
 
-void audit_set_type(struct audit_buffer *ab, int type)
+static void audit_set_pid(struct audit_buffer *ab, pid_t pid)
 {
-	ab->type = type;
+	struct nlmsghdr *nlh = (struct nlmsghdr *)ab->skb->data;
+	nlh->nlmsg_pid = pid;
 }
 
 struct audit_entry {
@@ -154,9 +150,6 @@ struct audit_entry {
 	struct audit_rule rule;
 };
 
-static void audit_log_end_irq(struct audit_buffer *ab);
-static void audit_log_end_fast(struct audit_buffer *ab);
-
 static void audit_panic(const char *message)
 {
 	switch (audit_failure)
@@ -227,10 +220,8 @@ void audit_log_lost(const char *message)
 
 	if (print) {
 		printk(KERN_WARNING
-		       "audit: audit_lost=%d audit_backlog=%d"
-		       " audit_rate_limit=%d audit_backlog_limit=%d\n",
+		       "audit: audit_lost=%d audit_rate_limit=%d audit_backlog_limit=%d\n",
 		       atomic_read(&audit_lost),
-		       atomic_read(&audit_backlog),
 		       audit_rate_limit,
 		       audit_backlog_limit);
 		audit_panic(message);
@@ -242,7 +233,8 @@ static int audit_set_rate_limit(int limi
 {
 	int old		 = audit_rate_limit;
 	audit_rate_limit = limit;
-	audit_log(NULL, "audit_rate_limit=%d old=%d by auid %u",
+	audit_log(NULL, AUDIT_CONFIG_CHANGE, 
+			"audit_rate_limit=%d old=%d by auid=%u",
 			audit_rate_limit, old, loginuid);
 	return old;
 }
@@ -251,7 +243,8 @@ static int audit_set_backlog_limit(int l
 {
 	int old		 = audit_backlog_limit;
 	audit_backlog_limit = limit;
-	audit_log(NULL, "audit_backlog_limit=%d old=%d by auid %u",
+	audit_log(NULL, AUDIT_CONFIG_CHANGE,
+			"audit_backlog_limit=%d old=%d by auid=%u",
 			audit_backlog_limit, old, loginuid);
 	return old;
 }
@@ -262,8 +255,9 @@ static int audit_set_enabled(int state, 
 	if (state != 0 && state != 1)
 		return -EINVAL;
 	audit_enabled = state;
-	audit_log(NULL, "audit_enabled=%d old=%d by auid %u",
-		  audit_enabled, old, loginuid);
+	audit_log(NULL, AUDIT_CONFIG_CHANGE,
+			"audit_enabled=%d old=%d by auid=%u",
+			audit_enabled, old, loginuid);
 	return old;
 }
 
@@ -275,12 +269,44 @@ static int audit_set_failure(int state, 
 	    && state != AUDIT_FAIL_PANIC)
 		return -EINVAL;
 	audit_failure = state;
-	audit_log(NULL, "audit_failure=%d old=%d by auid %u",
-		  audit_failure, old, loginuid);
+	audit_log(NULL, AUDIT_CONFIG_CHANGE,
+			"audit_failure=%d old=%d by auid=%u",
+			audit_failure, old, loginuid);
 	return old;
 }
 
-#ifdef CONFIG_NET
+int kauditd_thread(void *dummy)
+{
+	struct sk_buff *skb;
+
+	while (1) {
+		skb = skb_dequeue(&audit_skb_queue);
+		if (skb) {
+			if (audit_pid) {
+				int err = netlink_unicast(audit_sock, skb, audit_pid, 0);
+				if (err < 0) {
+					BUG_ON(err != -ECONNREFUSED); /* Shoudn't happen */
+					printk(KERN_ERR "audit: *NO* daemon at audit_pid=%d\n", audit_pid);
+					audit_pid = 0;
+				}
+			} else {
+				printk(KERN_ERR "%s\n", skb->data + NLMSG_SPACE(0));
+				kfree_skb(skb);
+			}
+		} else {
+			DECLARE_WAITQUEUE(wait, current);
+			set_current_state(TASK_INTERRUPTIBLE);
+			add_wait_queue(&kauditd_wait, &wait);
+
+			if (!skb_queue_len(&audit_skb_queue))
+				schedule();
+
+			__set_current_state(TASK_RUNNING);
+			remove_wait_queue(&kauditd_wait, &wait);
+		}
+	}
+}
+
 void audit_send_reply(int pid, int seq, int type, int done, int multi,
 		      void *payload, int size)
 {
@@ -293,13 +319,16 @@ void audit_send_reply(int pid, int seq, 
 
 	skb = alloc_skb(len, GFP_KERNEL);
 	if (!skb)
-		goto nlmsg_failure;
+		return;
 
-	nlh		 = NLMSG_PUT(skb, pid, seq, t, len - sizeof(*nlh));
+	nlh		 = NLMSG_PUT(skb, pid, seq, t, size);
 	nlh->nlmsg_flags = flags;
 	data		 = NLMSG_DATA(nlh);
 	memcpy(data, payload, size);
-	netlink_unicast(audit_sock, skb, pid, MSG_DONTWAIT);
+
+	/* Ignore failure. It'll only happen if the sender goes away,
+	   because our timeout is set to infinite. */
+	netlink_unicast(audit_sock, skb, pid, 0);
 	return;
 
 nlmsg_failure:			/* Used by NLMSG_PUT */
@@ -321,10 +350,12 @@ static int audit_netlink_ok(kernel_cap_t
 	case AUDIT_SET:
 	case AUDIT_ADD:
 	case AUDIT_DEL:
+	case AUDIT_SIGNAL_INFO:
 		if (!cap_raised(eff_cap, CAP_AUDIT_CONTROL))
 			err = -EPERM;
 		break;
 	case AUDIT_USER:
+	case AUDIT_FIRST_USER_MSG...AUDIT_LAST_USER_MSG:
 		if (!cap_raised(eff_cap, CAP_AUDIT_WRITE))
 			err = -EPERM;
 		break;
@@ -344,11 +375,21 @@ static int audit_receive_msg(struct sk_b
 	struct audit_buffer	*ab;
 	u16			msg_type = nlh->nlmsg_type;
 	uid_t			loginuid; /* loginuid of sender */
+	struct audit_sig_info   sig_data;
 
 	err = audit_netlink_ok(NETLINK_CB(skb).eff_cap, msg_type);
 	if (err)
 		return err;
 
+	/* As soon as there's any sign of userspace auditd, start kauditd to talk to it */
+	if (!kauditd_task)
+		kauditd_task = kthread_run(kauditd_thread, NULL, "kauditd");
+	if (IS_ERR(kauditd_task)) {
+		err = PTR_ERR(kauditd_task);
+		kauditd_task = NULL;
+		return err;
+	}
+
 	pid  = NETLINK_CREDS(skb)->pid;
 	uid  = NETLINK_CREDS(skb)->uid;
 	loginuid = NETLINK_CB(skb).loginuid;
@@ -363,7 +404,7 @@ static int audit_receive_msg(struct sk_b
 		status_set.rate_limit	 = audit_rate_limit;
 		status_set.backlog_limit = audit_backlog_limit;
 		status_set.lost		 = atomic_read(&audit_lost);
-		status_set.backlog	 = atomic_read(&audit_backlog);
+		status_set.backlog	 = skb_queue_len(&audit_skb_queue);
 		audit_send_reply(NETLINK_CB(skb).pid, seq, AUDIT_GET, 0, 0,
 				 &status_set, sizeof(status_set));
 		break;
@@ -382,7 +423,8 @@ static int audit_receive_msg(struct sk_b
 		if (status_get->mask & AUDIT_STATUS_PID) {
 			int old   = audit_pid;
 			audit_pid = status_get->pid;
-			audit_log(NULL, "audit_pid=%d old=%d by auid %u",
+			audit_log(NULL, AUDIT_CONFIG_CHANGE,
+				"audit_pid=%d old=%d by auid=%u",
 				  audit_pid, old, loginuid);
 		}
 		if (status_get->mask & AUDIT_STATUS_RATE_LIMIT)
@@ -392,18 +434,15 @@ static int audit_receive_msg(struct sk_b
 							loginuid);
 		break;
 	case AUDIT_USER:
-		ab = audit_log_start(NULL);
+	case AUDIT_FIRST_USER_MSG...AUDIT_LAST_USER_MSG:
+		ab = audit_log_start(NULL, msg_type);
 		if (!ab)
 			break;	/* audit_panic has been called */
 		audit_log_format(ab,
-				 "user pid=%d uid=%d length=%d loginuid=%u"
+				 "user pid=%d uid=%u auid=%u"
 				 " msg='%.1024s'",
-				 pid, uid,
-				 (int)(nlh->nlmsg_len
-				       - ((char *)data - (char *)nlh)),
-				 loginuid, (char *)data);
-		ab->type = AUDIT_USER;
-		ab->pid  = pid;
+				 pid, uid, loginuid, (char *)data);
+		audit_set_pid(ab, pid);
 		audit_log_end(ab);
 		break;
 	case AUDIT_ADD:
@@ -412,12 +451,14 @@ static int audit_receive_msg(struct sk_b
 			return -EINVAL;
 		/* fallthrough */
 	case AUDIT_LIST:
-#ifdef CONFIG_AUDITSYSCALL
 		err = audit_receive_filter(nlh->nlmsg_type, NETLINK_CB(skb).pid,
 					   uid, seq, data, loginuid);
-#else
-		err = -EOPNOTSUPP;
-#endif
+		break;
+	case AUDIT_SIGNAL_INFO:
+		sig_data.uid = audit_sig_uid;
+		sig_data.pid = audit_sig_pid;
+		audit_send_reply(NETLINK_CB(skb).pid, seq, AUDIT_SIGNAL_INFO, 
+				0, 0, &sig_data, sizeof(sig_data));
 		break;
 	default:
 		err = -EINVAL;
@@ -467,87 +508,6 @@ static void audit_receive(struct sock *s
 	up(&audit_netlink_sem);
 }
 
-/* Move data from tmp buffer into an skb.  This is an extra copy, and
- * that is unfortunate.  However, the copy will only occur when a record
- * is being written to user space, which is already a high-overhead
- * operation.  (Elimination of the copy is possible, for example, by
- * writing directly into a pre-allocated skb, at the cost of wasting
- * memory. */
-static void audit_log_move(struct audit_buffer *ab)
-{
-	struct sk_buff	*skb;
-	char		*start;
-	int		extra = ab->nlh ? 0 : NLMSG_SPACE(0);
-
-	/* possible resubmission */
-	if (ab->len == 0)
-		return;
-
-	skb = skb_peek_tail(&ab->sklist);
-	if (!skb || skb_tailroom(skb) <= ab->len + extra) {
-		skb = alloc_skb(2 * ab->len + extra, GFP_ATOMIC);
-		if (!skb) {
-			ab->len = 0; /* Lose information in ab->tmp */
-			audit_log_lost("out of memory in audit_log_move");
-			return;
-		}
-		__skb_queue_tail(&ab->sklist, skb);
-		if (!ab->nlh)
-			ab->nlh = (struct nlmsghdr *)skb_put(skb,
-							     NLMSG_SPACE(0));
-	}
-	start = skb_put(skb, ab->len);
-	memcpy(start, ab->tmp, ab->len);
-	ab->len = 0;
-}
-
-/* Iterate over the skbuff in the audit_buffer, sending their contents
- * to user space. */
-static inline int audit_log_drain(struct audit_buffer *ab)
-{
-	struct sk_buff *skb;
-
-	while ((skb = skb_dequeue(&ab->sklist))) {
-		int retval = 0;
-
-		if (audit_pid) {
-			if (ab->nlh) {
-				ab->nlh->nlmsg_len   = ab->total;
-				ab->nlh->nlmsg_type  = ab->type;
-				ab->nlh->nlmsg_flags = 0;
-				ab->nlh->nlmsg_seq   = 0;
-				ab->nlh->nlmsg_pid   = ab->pid;
-			}
-			skb_get(skb); /* because netlink_* frees */
-			retval = netlink_unicast(audit_sock, skb, audit_pid,
-						 MSG_DONTWAIT);
-		}
-		if (retval == -EAGAIN &&
-		    (atomic_read(&audit_backlog)) < audit_backlog_limit) {
-			skb_queue_head(&ab->sklist, skb);
-			audit_log_end_irq(ab);
-			return 1;
-		}
-		if (retval < 0) {
-			if (retval == -ECONNREFUSED) {
-				printk(KERN_ERR
-				       "audit: *NO* daemon at audit_pid=%d\n",
-				       audit_pid);
-				audit_pid = 0;
-			} else
-				audit_log_lost("netlink socket too busy");
-		}
-		if (!audit_pid) { /* No daemon */
-			int offset = ab->nlh ? NLMSG_SPACE(0) : 0;
-			int len    = skb->len - offset;
-			skb->data[offset + len] = '\0';
-			printk(KERN_ERR "%s\n", skb->data + offset);
-		}
-		kfree_skb(skb);
-		ab->nlh = NULL;
-	}
-	return 0;
-}
 
 /* Initialize audit support at boot time. */
 static int __init audit_init(void)
@@ -558,40 +518,13 @@ static int __init audit_init(void)
 	if (!audit_sock)
 		audit_panic("cannot initialize netlink socket");
 
+	audit_sock->sk_sndtimeo = MAX_SCHEDULE_TIMEOUT;
+	skb_queue_head_init(&audit_skb_queue);
 	audit_initialized = 1;
 	audit_enabled = audit_default;
-	audit_log(NULL, "initialized");
+	audit_log(NULL, AUDIT_KERNEL, "initialized");
 	return 0;
 }
-
-#else
-/* Without CONFIG_NET, we have no skbuffs.  For now, print what we have
- * in the buffer. */
-static void audit_log_move(struct audit_buffer *ab)
-{
-	printk(KERN_ERR "%*.*s\n", ab->len, ab->len, ab->tmp);
-	ab->len = 0;
-}
-
-static inline int audit_log_drain(struct audit_buffer *ab)
-{
-	return 0;
-}
-
-/* Initialize audit support at boot time. */
-int __init audit_init(void)
-{
-	printk(KERN_INFO "audit: initializing WITHOUT netlink support\n");
-	audit_sock = NULL;
-	audit_pid  = 0;
-
-	audit_initialized = 1;
-	audit_enabled = audit_default;
-	audit_log(NULL, "initialized");
-	return 0;
-}
-#endif
-
 __initcall(audit_init);
 
 /* Process kernel command-line parameter at boot time.  audit=0 or audit=1. */
@@ -608,6 +541,102 @@ static int __init audit_enable(char *str
 
 __setup("audit=", audit_enable);
 
+static void audit_buffer_free(struct audit_buffer *ab)
+{
+	unsigned long flags;
+
+	if (!ab)
+		return;
+
+	if (ab->skb)
+		kfree_skb(ab->skb);
+
+	spin_lock_irqsave(&audit_freelist_lock, flags);
+	if (++audit_freelist_count > AUDIT_MAXFREE)
+		kfree(ab);
+	else
+		list_add(&ab->list, &audit_freelist);
+	spin_unlock_irqrestore(&audit_freelist_lock, flags);
+}
+
+static struct audit_buffer * audit_buffer_alloc(struct audit_context *ctx,
+						int gfp_mask, int type)
+{
+	unsigned long flags;
+	struct audit_buffer *ab = NULL;
+	struct nlmsghdr *nlh;
+
+	spin_lock_irqsave(&audit_freelist_lock, flags);
+	if (!list_empty(&audit_freelist)) {
+		ab = list_entry(audit_freelist.next,
+				struct audit_buffer, list);
+		list_del(&ab->list);
+		--audit_freelist_count;
+	}
+	spin_unlock_irqrestore(&audit_freelist_lock, flags);
+
+	if (!ab) {
+		ab = kmalloc(sizeof(*ab), gfp_mask);
+		if (!ab)
+			goto err;
+	}
+
+	ab->skb = alloc_skb(AUDIT_BUFSIZ, gfp_mask);
+	if (!ab->skb)
+		goto err;
+
+	ab->ctx = ctx;
+	nlh = (struct nlmsghdr *)skb_put(ab->skb, NLMSG_SPACE(0));
+	nlh->nlmsg_type = type;
+	nlh->nlmsg_flags = 0;
+	nlh->nlmsg_pid = 0;
+	nlh->nlmsg_seq = 0;
+	return ab;
+err:
+	audit_buffer_free(ab);
+	return NULL;
+}
+
+/* Compute a serial number for the audit record.  Audit records are
+ * written to user-space as soon as they are generated, so a complete
+ * audit record may be written in several pieces.  The timestamp of the
+ * record and this serial number are used by the user-space tools to
+ * determine which pieces belong to the same audit record.  The
+ * (timestamp,serial) tuple is unique for each syscall and is live from
+ * syscall entry to syscall exit.
+ *
+ * Atomic values are only guaranteed to be 24-bit, so we count down.
+ *
+ * NOTE: Another possibility is to store the formatted records off the
+ * audit context (for those records that have a context), and emit them
+ * all at syscall exit.  However, this could delay the reporting of
+ * significant errors until syscall exit (or never, if the system
+ * halts). */
+unsigned int audit_serial(void)
+{
+	static atomic_t serial = ATOMIC_INIT(0xffffff);
+	unsigned int a, b;
+
+	do {
+		a = atomic_read(&serial);
+		if (atomic_dec_and_test(&serial))
+			atomic_set(&serial, 0xffffff);
+		b = atomic_read(&serial);
+	} while (b != a - 1);
+
+	return 0xffffff - b;
+}
+
+static inline void audit_get_stamp(struct audit_context *ctx, 
+				   struct timespec *t, unsigned int *serial)
+{
+	if (ctx)
+		auditsc_get_stamp(ctx, t, serial);
+	else {
+		*t = CURRENT_TIME;
+		*serial = audit_serial();
+	}
+}
 
 /* Obtain an audit buffer.  This routine does locking to obtain the
  * audit buffer, but then no locking is required for calls to
@@ -615,10 +644,9 @@ __setup("audit=", audit_enable);
  * syscall, then the syscall is marked as auditable and an audit record
  * will be written at syscall exit.  If there is no associated task, tsk
  * should be NULL. */
-struct audit_buffer *audit_log_start(struct audit_context *ctx)
+struct audit_buffer *audit_log_start(struct audit_context *ctx, int type)
 {
 	struct audit_buffer	*ab	= NULL;
-	unsigned long		flags;
 	struct timespec		t;
 	unsigned int		serial;
 
@@ -626,57 +654,48 @@ struct audit_buffer *audit_log_start(str
 		return NULL;
 
 	if (audit_backlog_limit
-	    && atomic_read(&audit_backlog) > audit_backlog_limit) {
+	    && skb_queue_len(&audit_skb_queue) > audit_backlog_limit) {
 		if (audit_rate_check())
 			printk(KERN_WARNING
 			       "audit: audit_backlog=%d > "
 			       "audit_backlog_limit=%d\n",
-			       atomic_read(&audit_backlog),
+			       skb_queue_len(&audit_skb_queue),
 			       audit_backlog_limit);
 		audit_log_lost("backlog limit exceeded");
 		return NULL;
 	}
 
-	spin_lock_irqsave(&audit_freelist_lock, flags);
-	if (!list_empty(&audit_freelist)) {
-		ab = list_entry(audit_freelist.next,
-				struct audit_buffer, list);
-		list_del(&ab->list);
-		--audit_freelist_count;
-	}
-	spin_unlock_irqrestore(&audit_freelist_lock, flags);
-
-	if (!ab)
-		ab = kmalloc(sizeof(*ab), GFP_ATOMIC);
+	ab = audit_buffer_alloc(ctx, GFP_ATOMIC, type);
 	if (!ab) {
 		audit_log_lost("out of memory in audit_log_start");
 		return NULL;
 	}
 
-	atomic_inc(&audit_backlog);
-	skb_queue_head_init(&ab->sklist);
+	audit_get_stamp(ab->ctx, &t, &serial);
 
-	ab->ctx   = ctx;
-	ab->len   = 0;
-	ab->nlh   = NULL;
-	ab->total = 0;
-	ab->type  = AUDIT_KERNEL;
-	ab->pid   = 0;
-
-#ifdef CONFIG_AUDITSYSCALL
-	if (ab->ctx)
-		audit_get_stamp(ab->ctx, &t, &serial);
-	else
-#endif
-	{
-		t = CURRENT_TIME;
-		serial = 0;
-	}
 	audit_log_format(ab, "audit(%lu.%03lu:%u): ",
 			 t.tv_sec, t.tv_nsec/1000000, serial);
 	return ab;
 }
 
+/**
+ * audit_expand - expand skb in the audit buffer
+ * @ab: audit_buffer
+ *
+ * Returns 0 (no space) on failed expansion, or available space if
+ * successful.
+ */
+static inline int audit_expand(struct audit_buffer *ab, int extra)
+{
+	struct sk_buff *skb = ab->skb;
+	int ret = pskb_expand_head(skb, skb_headroom(skb), extra,
+				   GFP_ATOMIC);
+	if (ret < 0) {
+		audit_log_lost("out of memory in audit_expand");
+		return 0;
+	}
+	return skb_tailroom(skb);
+}
 
 /* Format an audit message into the audit buffer.  If there isn't enough
  * room in the audit buffer, more room will be allocated and vsnprint
@@ -686,26 +705,35 @@ static void audit_log_vformat(struct aud
 			      va_list args)
 {
 	int len, avail;
+	struct sk_buff *skb;
+	va_list args2;
 
 	if (!ab)
 		return;
 
-	avail = sizeof(ab->tmp) - ab->len;
-	if (avail <= 0) {
-		audit_log_move(ab);
-		avail = sizeof(ab->tmp) - ab->len;
+	BUG_ON(!ab->skb);
+	skb = ab->skb;
+	avail = skb_tailroom(skb);
+	if (avail == 0) {
+		avail = audit_expand(ab, AUDIT_BUFSIZ);
+		if (!avail)
+			goto out;
 	}
-	len   = vsnprintf(ab->tmp + ab->len, avail, fmt, args);
+	va_copy(args2, args);
+	len = vsnprintf(skb->tail, avail, fmt, args);
 	if (len >= avail) {
 		/* The printk buffer is 1024 bytes long, so if we get
 		 * here and AUDIT_BUFSIZ is at least 1024, then we can
 		 * log everything that printk could have logged. */
-		audit_log_move(ab);
-		avail = sizeof(ab->tmp) - ab->len;
-		len   = vsnprintf(ab->tmp + ab->len, avail, fmt, args);
-	}
-	ab->len   += (len < avail) ? len : avail;
-	ab->total += (len < avail) ? len : avail;
+		avail = audit_expand(ab, max_t(unsigned, AUDIT_BUFSIZ, 1+len-avail));
+		if (!avail)
+			goto out;
+		len = vsnprintf(skb->tail, avail, fmt, args2);
+	}
+	if (len > 0)
+		skb_put(skb, len);
+out:
+	return;
 }
 
 /* Format a message into the audit buffer.  All the work is done in
@@ -721,20 +749,47 @@ void audit_log_format(struct audit_buffe
 	va_end(args);
 }
 
-void audit_log_hex(struct audit_buffer *ab, const unsigned char *buf, size_t len)
+/* This function will take the passed buf and convert it into a string of
+ * ascii hex digits. The new string is placed onto the skb. */
+void audit_log_hex(struct audit_buffer *ab, const unsigned char *buf, 
+		size_t len)
 {
-	int i;
+	int i, avail, new_len;
+	unsigned char *ptr;
+	struct sk_buff *skb;
+	static const unsigned char *hex = "0123456789ABCDEF";
+
+	BUG_ON(!ab->skb);
+	skb = ab->skb;
+	avail = skb_tailroom(skb);
+	new_len = len<<1;
+	if (new_len >= avail) {
+		/* Round the buffer request up to the next multiple */
+		new_len = AUDIT_BUFSIZ*(((new_len-avail)/AUDIT_BUFSIZ) + 1);
+		avail = audit_expand(ab, new_len);
+		if (!avail)
+			return;
+	}
 
-	for (i=0; i<len; i++)
-		audit_log_format(ab, "%02x", buf[i]);
+	ptr = skb->tail;
+	for (i=0; i<len; i++) {
+		*ptr++ = hex[(buf[i] & 0xF0)>>4]; /* Upper nibble */
+		*ptr++ = hex[buf[i] & 0x0F];	  /* Lower nibble */
+	}
+	*ptr = 0;
+	skb_put(skb, len << 1); /* new string is twice the old string */
 }
 
+/* This code will escape a string that is passed to it if the string
+ * contains a control character, unprintable character, double quote mark, 
+ * or a space. Unescaped strings will start and end with a double quote mark.
+ * Strings that are escaped are printed in hex (2 digits per char). */
 void audit_log_untrustedstring(struct audit_buffer *ab, const char *string)
 {
 	const unsigned char *p = string;
 
 	while (*p) {
-		if (*p == '"' || *p == ' ' || *p < 0x20 || *p > 0x7f) {
+		if (*p == '"' || *p < 0x21 || *p > 0x7f) {
 			audit_log_hex(ab, string, strlen(string));
 			return;
 		}
@@ -743,117 +798,63 @@ void audit_log_untrustedstring(struct au
 	audit_log_format(ab, "\"%s\"", string);
 }
 
-
-/* This is a helper-function to print the d_path without using a static
- * buffer or allocating another buffer in addition to the one in
- * audit_buffer. */
+/* This is a helper-function to print the escaped d_path */
 void audit_log_d_path(struct audit_buffer *ab, const char *prefix,
 		      struct dentry *dentry, struct vfsmount *vfsmnt)
 {
-	char *p;
-	int  len, avail;
-
-	if (prefix) audit_log_format(ab, " %s", prefix);
-
-	if (ab->len > 128)
-		audit_log_move(ab);
-	avail = sizeof(ab->tmp) - ab->len;
-	p = d_path(dentry, vfsmnt, ab->tmp + ab->len, avail);
-	if (IS_ERR(p)) {
-		/* FIXME: can we save some information here? */
-		audit_log_format(ab, "<toolong>");
-	} else {
-				/* path isn't at start of buffer */
-		len	   = (ab->tmp + sizeof(ab->tmp) - 1) - p;
-		memmove(ab->tmp + ab->len, p, len);
-		ab->len   += len;
-		ab->total += len;
-	}
-}
-
-/* Remove queued messages from the audit_txlist and send them to userspace. */
-static void audit_tasklet_handler(unsigned long arg)
-{
-	LIST_HEAD(list);
-	struct audit_buffer *ab;
-	unsigned long	    flags;
+	char *p, *path;
 
-	spin_lock_irqsave(&audit_txlist_lock, flags);
-	list_splice_init(&audit_txlist, &list);
-	spin_unlock_irqrestore(&audit_txlist_lock, flags);
+	if (prefix)
+		audit_log_format(ab, " %s", prefix);
 
-	while (!list_empty(&list)) {
-		ab = list_entry(list.next, struct audit_buffer, list);
-		list_del(&ab->list);
-		audit_log_end_fast(ab);
+	/* We will allow 11 spaces for ' (deleted)' to be appended */
+	path = kmalloc(PATH_MAX+11, GFP_KERNEL);
+	if (!path) {
+		audit_log_format(ab, "<no memory>");
+		return;
 	}
+	p = d_path(dentry, vfsmnt, path, PATH_MAX+11);
+	if (IS_ERR(p)) { /* Should never happen since we send PATH_MAX */
+		/* FIXME: can we save some information here? */
+		audit_log_format(ab, "<too long>");
+	} else 
+		audit_log_untrustedstring(ab, p);
+	kfree(path);
 }
 
-static DECLARE_TASKLET(audit_tasklet, audit_tasklet_handler, 0);
-
 /* The netlink_* functions cannot be called inside an irq context, so
  * the audit buffer is places on a queue and a tasklet is scheduled to
  * remove them from the queue outside the irq context.  May be called in
  * any context. */
-static void audit_log_end_irq(struct audit_buffer *ab)
-{
-	unsigned long flags;
-
-	if (!ab)
-		return;
-	spin_lock_irqsave(&audit_txlist_lock, flags);
-	list_add_tail(&ab->list, &audit_txlist);
-	spin_unlock_irqrestore(&audit_txlist_lock, flags);
-
-	tasklet_schedule(&audit_tasklet);
-}
-
-/* Send the message in the audit buffer directly to user space.  May not
- * be called in an irq context. */
-static void audit_log_end_fast(struct audit_buffer *ab)
+void audit_log_end(struct audit_buffer *ab)
 {
-	unsigned long flags;
-
-	BUG_ON(in_irq());
 	if (!ab)
 		return;
 	if (!audit_rate_check()) {
 		audit_log_lost("rate limit exceeded");
 	} else {
-		audit_log_move(ab);
-		if (audit_log_drain(ab))
-			return;
+		if (audit_pid) {
+			struct nlmsghdr *nlh = (struct nlmsghdr *)ab->skb->data;
+			nlh->nlmsg_len = ab->skb->len - NLMSG_SPACE(0);
+			skb_queue_tail(&audit_skb_queue, ab->skb);
+			ab->skb = NULL;
+			wake_up_interruptible(&kauditd_wait);
+		} else {
+			printk("%s\n", ab->skb->data + NLMSG_SPACE(0));
+		}
 	}
-
-	atomic_dec(&audit_backlog);
-	spin_lock_irqsave(&audit_freelist_lock, flags);
-	if (++audit_freelist_count > AUDIT_MAXFREE)
-		kfree(ab);
-	else
-		list_add(&ab->list, &audit_freelist);
-	spin_unlock_irqrestore(&audit_freelist_lock, flags);
-}
-
-/* Send or queue the message in the audit buffer, depending on the
- * current context.  (A convenience function that may be called in any
- * context.) */
-void audit_log_end(struct audit_buffer *ab)
-{
-	if (in_irq())
-		audit_log_end_irq(ab);
-	else
-		audit_log_end_fast(ab);
+	audit_buffer_free(ab);
 }
 
 /* Log an audit record.  This is a convenience function that calls
  * audit_log_start, audit_log_vformat, and audit_log_end.  It may be
  * called in any context. */
-void audit_log(struct audit_context *ctx, const char *fmt, ...)
+void audit_log(struct audit_context *ctx, int type, const char *fmt, ...)
 {
 	struct audit_buffer *ab;
 	va_list args;
 
-	ab = audit_log_start(ctx);
+	ab = audit_log_start(ctx, type);
 	if (ab) {
 		va_start(args, fmt);
 		audit_log_vformat(ab, fmt, args);
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -34,7 +34,8 @@
 #include <asm/types.h>
 #include <linux/mm.h>
 #include <linux/module.h>
-
+#include <linux/mount.h>
+#include <linux/socket.h>
 #include <linux/audit.h>
 #include <linux/personality.h>
 #include <linux/time.h>
@@ -112,6 +113,23 @@ struct audit_aux_data_ipcctl {
 	mode_t			mode;
 };
 
+struct audit_aux_data_socketcall {
+	struct audit_aux_data	d;
+	int			nargs;
+	unsigned long		args[0];
+};
+
+struct audit_aux_data_sockaddr {
+	struct audit_aux_data	d;
+	int			len;
+	char			a[0];
+};
+
+struct audit_aux_data_path {
+	struct audit_aux_data	d;
+	struct dentry		*dentry;
+	struct vfsmount		*mnt;
+};
 
 /* The per-task audit context. */
 struct audit_context {
@@ -127,6 +145,8 @@ struct audit_context {
 	int		    auditable;  /* 1 if record should be written */
 	int		    name_count;
 	struct audit_names  names[AUDIT_NAMES];
+	struct dentry *	    pwd;
+	struct vfsmount *   pwdmnt;
 	struct audit_context *previous; /* For nested syscalls */
 	struct audit_aux_data *aux;
 
@@ -157,6 +177,8 @@ struct audit_entry {
 	struct audit_rule rule;
 };
 
+extern int audit_pid;
+
 /* Check to see if two rules are identical.  It is called from
  * audit_del_rule during AUDIT_DEL. */
 static int audit_compare_rule(struct audit_rule *a, struct audit_rule *b)
@@ -226,7 +248,6 @@ static inline int audit_del_rule(struct 
 	return -EFAULT;		/* No matching rule */
 }
 
-#ifdef CONFIG_NET
 /* Copy rule from user-space to kernel-space.  Called during
  * AUDIT_ADD. */
 static int audit_copy_rule(struct audit_rule *d, struct audit_rule *s)
@@ -287,7 +308,8 @@ int audit_receive_filter(int type, int p
 			err = audit_add_rule(entry, &audit_entlist);
 		if (!err && (flags & AUDIT_AT_EXIT))
 			err = audit_add_rule(entry, &audit_extlist);
-		audit_log(NULL, "auid %u added an audit rule\n", loginuid);
+		audit_log(NULL, AUDIT_CONFIG_CHANGE, 
+				"auid=%u added an audit rule\n", loginuid);
 		break;
 	case AUDIT_DEL:
 		flags =((struct audit_rule *)data)->flags;
@@ -297,7 +319,8 @@ int audit_receive_filter(int type, int p
 			err = audit_del_rule(data, &audit_entlist);
 		if (!err && (flags & AUDIT_AT_EXIT))
 			err = audit_del_rule(data, &audit_extlist);
-		audit_log(NULL, "auid %u removed an audit rule\n", loginuid);
+		audit_log(NULL, AUDIT_CONFIG_CHANGE,
+				"auid=%u removed an audit rule\n", loginuid);
 		break;
 	default:
 		return -EINVAL;
@@ -305,7 +328,6 @@ int audit_receive_filter(int type, int p
 
 	return err;
 }
-#endif
 
 /* Compare a task_struct with an audit_rule.  Return 1 on match, 0
  * otherwise. */
@@ -444,7 +466,7 @@ static enum audit_state audit_filter_tas
 
 /* At syscall entry and exit time, this filter is called if the
  * audit_state is not low enough that auditing cannot take place, but is
- * also not high enough that we already know we have to write and audit
+ * also not high enough that we already know we have to write an audit
  * record (i.e., the state is AUDIT_SETUP_CONTEXT or  AUDIT_BUILD_CONTEXT).
  */
 static enum audit_state audit_filter_syscall(struct task_struct *tsk,
@@ -532,6 +554,12 @@ static inline void audit_free_names(stru
 		if (context->names[i].name)
 			__putname(context->names[i].name);
 	context->name_count = 0;
+	if (context->pwd)
+		dput(context->pwd);
+	if (context->pwdmnt)
+		mntput(context->pwdmnt);
+	context->pwd = NULL;
+	context->pwdmnt = NULL;
 }
 
 static inline void audit_free_aux(struct audit_context *context)
@@ -539,6 +567,11 @@ static inline void audit_free_aux(struct
 	struct audit_aux_data *aux;
 
 	while ((aux = context->aux)) {
+		if (aux->type == AUDIT_AVC_PATH) {
+			struct audit_aux_data_path *axi = (void *)aux;
+			dput(axi->dentry);
+			mntput(axi->mnt);
+		}
 		context->aux = aux->next;
 		kfree(aux);
 	}
@@ -625,7 +658,8 @@ static void audit_log_task_info(struct a
 	struct vm_area_struct *vma;
 
 	get_task_comm(name, current);
-	audit_log_format(ab, " comm=%s", name);
+	audit_log_format(ab, " comm=");
+	audit_log_untrustedstring(ab, name);
 
 	if (!mm)
 		return;
@@ -649,23 +683,24 @@ static void audit_log_exit(struct audit_
 {
 	int i;
 	struct audit_buffer *ab;
+	struct audit_aux_data *aux;
 
-	ab = audit_log_start(context);
+	ab = audit_log_start(context, AUDIT_SYSCALL);
 	if (!ab)
 		return;		/* audit_panic has been called */
-	audit_log_format(ab, "syscall=%d", context->major);
+	audit_log_format(ab, "arch=%x syscall=%d",
+			 context->arch, context->major);
 	if (context->personality != PER_LINUX)
 		audit_log_format(ab, " per=%lx", context->personality);
-	audit_log_format(ab, " arch=%x", context->arch);
 	if (context->return_valid)
 		audit_log_format(ab, " success=%s exit=%ld", 
 				 (context->return_valid==AUDITSC_SUCCESS)?"yes":"no",
 				 context->return_code);
 	audit_log_format(ab,
 		  " a0=%lx a1=%lx a2=%lx a3=%lx items=%d"
-		  " pid=%d loginuid=%d uid=%d gid=%d"
-		  " euid=%d suid=%d fsuid=%d"
-		  " egid=%d sgid=%d fsgid=%d",
+		  " pid=%d auid=%u uid=%u gid=%u"
+		  " euid=%u suid=%u fsuid=%u"
+		  " egid=%u sgid=%u fsgid=%u",
 		  context->argv[0],
 		  context->argv[1],
 		  context->argv[2],
@@ -679,33 +714,57 @@ static void audit_log_exit(struct audit_
 		  context->egid, context->sgid, context->fsgid);
 	audit_log_task_info(ab);
 	audit_log_end(ab);
-	while (context->aux) {
-		struct audit_aux_data *aux;
 
-		ab = audit_log_start(context);
+	for (aux = context->aux; aux; aux = aux->next) {
+
+		ab = audit_log_start(context, aux->type);
 		if (!ab)
 			continue; /* audit_panic has been called */
 
-		aux = context->aux;
-		context->aux = aux->next;
-
-		audit_log_format(ab, "auxitem=%d", aux->type);
 		switch (aux->type) {
-		case AUDIT_AUX_IPCPERM: {
+		case AUDIT_IPC: {
 			struct audit_aux_data_ipcctl *axi = (void *)aux;
 			audit_log_format(ab, 
-					 " qbytes=%lx uid=%d gid=%d mode=%x",
+					 " qbytes=%lx iuid=%u igid=%u mode=%x",
 					 axi->qbytes, axi->uid, axi->gid, axi->mode);
-			}
+			break; }
+
+		case AUDIT_SOCKETCALL: {
+			int i;
+			struct audit_aux_data_socketcall *axs = (void *)aux;
+			audit_log_format(ab, "nargs=%d", axs->nargs);
+			for (i=0; i<axs->nargs; i++)
+				audit_log_format(ab, " a%d=%lx", i, axs->args[i]);
+			break; }
+
+		case AUDIT_SOCKADDR: {
+			struct audit_aux_data_sockaddr *axs = (void *)aux;
+
+			audit_log_format(ab, "saddr=");
+			audit_log_hex(ab, axs->a, axs->len);
+			break; }
+
+		case AUDIT_AVC_PATH: {
+			struct audit_aux_data_path *axi = (void *)aux;
+			audit_log_d_path(ab, "path=", axi->dentry, axi->mnt);
+			break; }
+
 		}
 		audit_log_end(ab);
-		kfree(aux);
 	}
 
+	if (context->pwd && context->pwdmnt) {
+		ab = audit_log_start(context, AUDIT_CWD);
+		if (ab) {
+			audit_log_d_path(ab, "cwd=", context->pwd, context->pwdmnt);
+			audit_log_end(ab);
+		}
+	}
 	for (i = 0; i < context->name_count; i++) {
-		ab = audit_log_start(context);
+		ab = audit_log_start(context, AUDIT_PATH);
 		if (!ab)
 			continue; /* audit_panic has been called */
+
 		audit_log_format(ab, "item=%d", i);
 		if (context->names[i].name) {
 			audit_log_format(ab, " name=");
@@ -713,7 +772,7 @@ static void audit_log_exit(struct audit_
 		}
 		if (context->names[i].ino != (unsigned long)-1)
 			audit_log_format(ab, " inode=%lu dev=%02x:%02x mode=%#o"
-					     " uid=%d gid=%d rdev=%02x:%02x",
+					     " ouid=%u ogid=%u rdev=%02x:%02x",
 					 context->names[i].ino,
 					 MAJOR(context->names[i].dev),
 					 MINOR(context->names[i].dev),
@@ -741,42 +800,12 @@ void audit_free(struct task_struct *tsk)
 
 	/* Check for system calls that do not go through the exit
 	 * function (e.g., exit_group), then free context block. */
-	if (context->in_syscall && context->auditable)
+	if (context->in_syscall && context->auditable && context->pid != audit_pid)
 		audit_log_exit(context);
 
 	audit_free_context(context);
 }
 
-/* Compute a serial number for the audit record.  Audit records are
- * written to user-space as soon as they are generated, so a complete
- * audit record may be written in several pieces.  The timestamp of the
- * record and this serial number are used by the user-space daemon to
- * determine which pieces belong to the same audit record.  The
- * (timestamp,serial) tuple is unique for each syscall and is live from
- * syscall entry to syscall exit.
- *
- * Atomic values are only guaranteed to be 24-bit, so we count down.
- *
- * NOTE: Another possibility is to store the formatted records off the
- * audit context (for those records that have a context), and emit them
- * all at syscall exit.  However, this could delay the reporting of
- * significant errors until syscall exit (or never, if the system
- * halts). */
-static inline unsigned int audit_serial(void)
-{
-	static atomic_t serial = ATOMIC_INIT(0xffffff);
-	unsigned int a, b;
-
-	do {
-		a = atomic_read(&serial);
-		if (atomic_dec_and_test(&serial))
-			atomic_set(&serial, 0xffffff);
-		b = atomic_read(&serial);
-	} while (b != a - 1);
-
-	return 0xffffff - b;
-}
-
 /* Fill in audit context at syscall entry.  This only happens if the
  * audit context was created when the task was created and the state or
  * filters demand the audit context be built.  If the state from the
@@ -876,7 +905,7 @@ void audit_syscall_exit(struct task_stru
 	if (likely(!context))
 		return;
 
-	if (context->in_syscall && context->auditable)
+	if (context->in_syscall && context->auditable && context->pid != audit_pid)
 		audit_log_exit(context);
 
 	context->in_syscall = 0;
@@ -916,6 +945,13 @@ void audit_getname(const char *name)
 	context->names[context->name_count].name = name;
 	context->names[context->name_count].ino  = (unsigned long)-1;
 	++context->name_count;
+	if (!context->pwd) {
+		read_lock(&current->fs->lock);
+		context->pwd = dget(current->fs->pwd);
+		context->pwdmnt = mntget(current->fs->pwdmnt);
+		read_unlock(&current->fs->lock);
+	}
+		
 }
 
 /* Intercept a putname request.  Called from
@@ -994,34 +1030,26 @@ void audit_inode(const char *name, const
 	context->names[idx].rdev = inode->i_rdev;
 }
 
-void audit_get_stamp(struct audit_context *ctx,
-		     struct timespec *t, unsigned int *serial)
+void auditsc_get_stamp(struct audit_context *ctx,
+		       struct timespec *t, unsigned int *serial)
 {
-	if (ctx) {
-		t->tv_sec  = ctx->ctime.tv_sec;
-		t->tv_nsec = ctx->ctime.tv_nsec;
-		*serial    = ctx->serial;
-		ctx->auditable = 1;
-	} else {
-		*t      = CURRENT_TIME;
-		*serial = 0;
-	}
+	t->tv_sec  = ctx->ctime.tv_sec;
+	t->tv_nsec = ctx->ctime.tv_nsec;
+	*serial    = ctx->serial;
+	ctx->auditable = 1;
 }
 
-extern int audit_set_type(struct audit_buffer *ab, int type);
-
 int audit_set_loginuid(struct task_struct *task, uid_t loginuid)
 {
 	if (task->audit_context) {
 		struct audit_buffer *ab;
 
-		ab = audit_log_start(NULL);
+		ab = audit_log_start(NULL, AUDIT_LOGIN);
 		if (ab) {
 			audit_log_format(ab, "login pid=%d uid=%u "
-				"old loginuid=%u new loginuid=%u",
+				"old auid=%u new auid=%u",
 				task->pid, task->uid, 
 				task->audit_context->loginuid, loginuid);
-			audit_set_type(ab, AUDIT_LOGIN);
 			audit_log_end(ab);
 		}
 		task->audit_context->loginuid = loginuid;
@@ -1051,8 +1079,89 @@ int audit_ipc_perms(unsigned long qbytes
 	ax->gid = gid;
 	ax->mode = mode;
 
-	ax->d.type = AUDIT_AUX_IPCPERM;
+	ax->d.type = AUDIT_IPC;
 	ax->d.next = context->aux;
 	context->aux = (void *)ax;
 	return 0;
 }
+
+int audit_socketcall(int nargs, unsigned long *args)
+{
+	struct audit_aux_data_socketcall *ax;
+	struct audit_context *context = current->audit_context;
+
+	if (likely(!context))
+		return 0;
+
+	ax = kmalloc(sizeof(*ax) + nargs * sizeof(unsigned long), GFP_KERNEL);
+	if (!ax)
+		return -ENOMEM;
+
+	ax->nargs = nargs;
+	memcpy(ax->args, args, nargs * sizeof(unsigned long));
+
+	ax->d.type = AUDIT_SOCKETCALL;
+	ax->d.next = context->aux;
+	context->aux = (void *)ax;
+	return 0;
+}
+
+int audit_sockaddr(int len, void *a)
+{
+	struct audit_aux_data_sockaddr *ax;
+	struct audit_context *context = current->audit_context;
+
+	if (likely(!context))
+		return 0;
+
+	ax = kmalloc(sizeof(*ax) + len, GFP_KERNEL);
+	if (!ax)
+		return -ENOMEM;
+
+	ax->len = len;
+	memcpy(ax->a, a, len);
+
+	ax->d.type = AUDIT_SOCKADDR;
+	ax->d.next = context->aux;
+	context->aux = (void *)ax;
+	return 0;
+}
+
+int audit_avc_path(struct dentry *dentry, struct vfsmount *mnt)
+{
+	struct audit_aux_data_path *ax;
+	struct audit_context *context = current->audit_context;
+
+	if (likely(!context))
+		return 0;
+
+	ax = kmalloc(sizeof(*ax), GFP_ATOMIC);
+	if (!ax)
+		return -ENOMEM;
+
+	ax->dentry = dget(dentry);
+	ax->mnt = mntget(mnt);
+
+	ax->d.type = AUDIT_AVC_PATH;
+	ax->d.next = context->aux;
+	context->aux = (void *)ax;
+	return 0;
+}
+
+void audit_signal_info(int sig, struct task_struct *t)
+{
+	extern pid_t audit_sig_pid;
+	extern uid_t audit_sig_uid;
+
+	if (unlikely(audit_pid && t->pid == audit_pid)) {
+		if (sig == SIGTERM || sig == SIGHUP) {
+			struct audit_context *ctx = current->audit_context;
+			audit_sig_pid = current->pid;
+			if (ctx)
+				audit_sig_uid = ctx->loginuid;
+			else
+				audit_sig_uid = current->uid;
+		}
+	}
+}
+
diff --git a/kernel/capability.c b/kernel/capability.c
--- a/kernel/capability.c
+++ b/kernel/capability.c
@@ -31,8 +31,14 @@ static DEFINE_SPINLOCK(task_capability_l
  * uninteresting and/or not to be changed.
  */
 
-/*
+/**
  * sys_capget - get the capabilities of a given process.
+ * @header: pointer to struct that contains capability version and
+ *	target pid data
+ * @dataptr: pointer to struct that contains the effective, permitted,
+ *	and inheritable capabilities that are returned
+ *
+ * Returns 0 on success and < 0 on error.
  */
 asmlinkage long sys_capget(cap_user_header_t header, cap_user_data_t dataptr)
 {
@@ -141,8 +147,14 @@ static inline int cap_set_all(kernel_cap
      return ret;
 }
 
-/*
- * sys_capset - set capabilities for a given process, all processes, or all
+/**
+ * sys_capset - set capabilities for a process or a group of processes
+ * @header: pointer to struct that contains capability version and
+ *	target pid data
+ * @data: pointer to struct that contains the effective, permitted,
+ *	and inheritable capabilities
+ *
+ * Set capabilities for a given process, all processes, or all
  * processes in a given process group.
  *
  * The restrictions on setting capabilities are specified as:
@@ -152,6 +164,8 @@ static inline int cap_set_all(kernel_cap
  * I: any raised capabilities must be a subset of the (old current) permitted
  * P: any raised capabilities must be a subset of the (old current) permitted
  * E: must be set to a subset of (new target) permitted
+ *
+ * Returns 0 on success and < 0 on error.
  */
 asmlinkage long sys_capset(cap_user_header_t header, const cap_user_data_t data)
 {
diff --git a/kernel/cpu.c b/kernel/cpu.c
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -63,19 +63,15 @@ static int take_cpu_down(void *unused)
 {
 	int err;
 
-	/* Take offline: makes arch_cpu_down somewhat easier. */
-	cpu_clear(smp_processor_id(), cpu_online_map);
-
 	/* Ensure this CPU doesn't handle any more interrupts. */
 	err = __cpu_disable();
 	if (err < 0)
-		cpu_set(smp_processor_id(), cpu_online_map);
-	else
-		/* Force idle task to run as soon as we yield: it should
-		   immediately notice cpu is offline and die quickly. */
-		sched_idle_next();
+		return err;
 
-	return err;
+	/* Force idle task to run as soon as we yield: it should
+	   immediately notice cpu is offline and die quickly. */
+	sched_idle_next();
+	return 0;
 }
 
 int cpu_down(unsigned int cpu)
diff --git a/kernel/cpuset.c b/kernel/cpuset.c
--- a/kernel/cpuset.c
+++ b/kernel/cpuset.c
@@ -228,13 +228,7 @@ static struct dentry_operations cpuset_d
 
 static struct dentry *cpuset_get_dentry(struct dentry *parent, const char *name)
 {
-	struct qstr qstr;
-	struct dentry *d;
-
-	qstr.name = name;
-	qstr.len = strlen(name);
-	qstr.hash = full_name_hash(name, qstr.len);
-	d = lookup_hash(&qstr, parent);
+	struct dentry *d = lookup_one_len(name, parent, strlen(name));
 	if (!IS_ERR(d))
 		d->d_op = &cpuset_dops;
 	return d;
@@ -404,21 +398,31 @@ static int cpuset_path(const struct cpus
  * to continue to serve a useful existence.  Next time it's released,
  * we will get notified again, if it still has 'notify_on_release' set.
  *
- * Note final arg to call_usermodehelper() is 0 - that means
- * don't wait.  Since we are holding the global cpuset_sem here,
- * and we are asking another thread (started from keventd) to rmdir a
- * cpuset, we can't wait - or we'd deadlock with the removing thread
- * on cpuset_sem.
+ * The final arg to call_usermodehelper() is 0, which means don't
+ * wait.  The separate /sbin/cpuset_release_agent task is forked by
+ * call_usermodehelper(), then control in this thread returns here,
+ * without waiting for the release agent task.  We don't bother to
+ * wait because the caller of this routine has no use for the exit
+ * status of the /sbin/cpuset_release_agent task, so no sense holding
+ * our caller up for that.
+ *
+ * The simple act of forking that task might require more memory,
+ * which might need cpuset_sem.  So this routine must be called while
+ * cpuset_sem is not held, to avoid a possible deadlock.  See also
+ * comments for check_for_release(), below.
  */
 
-static int cpuset_release_agent(char *cpuset_str)
+static void cpuset_release_agent(const char *pathbuf)
 {
 	char *argv[3], *envp[3];
 	int i;
 
+	if (!pathbuf)
+		return;
+
 	i = 0;
 	argv[i++] = "/sbin/cpuset_release_agent";
-	argv[i++] = cpuset_str;
+	argv[i++] = (char *)pathbuf;
 	argv[i] = NULL;
 
 	i = 0;
@@ -427,17 +431,29 @@ static int cpuset_release_agent(char *cp
 	envp[i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
 	envp[i] = NULL;
 
-	return call_usermodehelper(argv[0], argv, envp, 0);
+	call_usermodehelper(argv[0], argv, envp, 0);
+	kfree(pathbuf);
 }
 
 /*
  * Either cs->count of using tasks transitioned to zero, or the
  * cs->children list of child cpusets just became empty.  If this
  * cs is notify_on_release() and now both the user count is zero and
- * the list of children is empty, send notice to user land.
+ * the list of children is empty, prepare cpuset path in a kmalloc'd
+ * buffer, to be returned via ppathbuf, so that the caller can invoke
+ * cpuset_release_agent() with it later on, once cpuset_sem is dropped.
+ * Call here with cpuset_sem held.
+ *
+ * This check_for_release() routine is responsible for kmalloc'ing
+ * pathbuf.  The above cpuset_release_agent() is responsible for
+ * kfree'ing pathbuf.  The caller of these routines is responsible
+ * for providing a pathbuf pointer, initialized to NULL, then
+ * calling check_for_release() with cpuset_sem held and the address
+ * of the pathbuf pointer, then dropping cpuset_sem, then calling
+ * cpuset_release_agent() with pathbuf, as set by check_for_release().
  */
 
-static void check_for_release(struct cpuset *cs)
+static void check_for_release(struct cpuset *cs, char **ppathbuf)
 {
 	if (notify_on_release(cs) && atomic_read(&cs->count) == 0 &&
 	    list_empty(&cs->children)) {
@@ -447,10 +463,9 @@ static void check_for_release(struct cpu
 		if (!buf)
 			return;
 		if (cpuset_path(cs, buf, PAGE_SIZE) < 0)
-			goto out;
-		cpuset_release_agent(buf);
-out:
-		kfree(buf);
+			kfree(buf);
+		else
+			*ppathbuf = buf;
 	}
 }
 
@@ -601,10 +616,75 @@ static int validate_change(const struct 
 	return 0;
 }
 
+/*
+ * For a given cpuset cur, partition the system as follows
+ * a. All cpus in the parent cpuset's cpus_allowed that are not part of any
+ *    exclusive child cpusets
+ * b. All cpus in the current cpuset's cpus_allowed that are not part of any
+ *    exclusive child cpusets
+ * Build these two partitions by calling partition_sched_domains
+ *
+ * Call with cpuset_sem held.  May nest a call to the
+ * lock_cpu_hotplug()/unlock_cpu_hotplug() pair.
+ */
+
+/*
+ * Hack to avoid 2.6.13 partial node dynamic sched domain bug.
+ * Disable letting 'cpu_exclusive' cpusets define dynamic sched
+ * domains, until the sched domain can handle partial nodes.
+ * Remove this #if hackery when sched domains fixed.
+ */
+#if 0
+static void update_cpu_domains(struct cpuset *cur)
+{
+	struct cpuset *c, *par = cur->parent;
+	cpumask_t pspan, cspan;
+
+	if (par == NULL || cpus_empty(cur->cpus_allowed))
+		return;
+
+	/*
+	 * Get all cpus from parent's cpus_allowed not part of exclusive
+	 * children
+	 */
+	pspan = par->cpus_allowed;
+	list_for_each_entry(c, &par->children, sibling) {
+		if (is_cpu_exclusive(c))
+			cpus_andnot(pspan, pspan, c->cpus_allowed);
+	}
+	if (is_removed(cur) || !is_cpu_exclusive(cur)) {
+		cpus_or(pspan, pspan, cur->cpus_allowed);
+		if (cpus_equal(pspan, cur->cpus_allowed))
+			return;
+		cspan = CPU_MASK_NONE;
+	} else {
+		if (cpus_empty(pspan))
+			return;
+		cspan = cur->cpus_allowed;
+		/*
+		 * Get all cpus from current cpuset's cpus_allowed not part
+		 * of exclusive children
+		 */
+		list_for_each_entry(c, &cur->children, sibling) {
+			if (is_cpu_exclusive(c))
+				cpus_andnot(cspan, cspan, c->cpus_allowed);
+		}
+	}
+
+	lock_cpu_hotplug();
+	partition_sched_domains(&pspan, &cspan);
+	unlock_cpu_hotplug();
+}
+#else
+static void update_cpu_domains(struct cpuset *cur)
+{
+}
+#endif
+
 static int update_cpumask(struct cpuset *cs, char *buf)
 {
 	struct cpuset trialcs;
-	int retval;
+	int retval, cpus_unchanged;
 
 	trialcs = *cs;
 	retval = cpulist_parse(buf, trialcs.cpus_allowed);
@@ -614,9 +694,13 @@ static int update_cpumask(struct cpuset 
 	if (cpus_empty(trialcs.cpus_allowed))
 		return -ENOSPC;
 	retval = validate_change(cs, &trialcs);
-	if (retval == 0)
-		cs->cpus_allowed = trialcs.cpus_allowed;
-	return retval;
+	if (retval < 0)
+		return retval;
+	cpus_unchanged = cpus_equal(cs->cpus_allowed, trialcs.cpus_allowed);
+	cs->cpus_allowed = trialcs.cpus_allowed;
+	if (is_cpu_exclusive(cs) && !cpus_unchanged)
+		update_cpu_domains(cs);
+	return 0;
 }
 
 static int update_nodemask(struct cpuset *cs, char *buf)
@@ -652,7 +736,7 @@ static int update_flag(cpuset_flagbits_t
 {
 	int turning_on;
 	struct cpuset trialcs;
-	int err;
+	int err, cpu_exclusive_changed;
 
 	turning_on = (simple_strtoul(buf, NULL, 10) != 0);
 
@@ -663,23 +747,28 @@ static int update_flag(cpuset_flagbits_t
 		clear_bit(bit, &trialcs.flags);
 
 	err = validate_change(cs, &trialcs);
-	if (err == 0) {
-		if (turning_on)
-			set_bit(bit, &cs->flags);
-		else
-			clear_bit(bit, &cs->flags);
-	}
-	return err;
+	if (err < 0)
+		return err;
+	cpu_exclusive_changed =
+		(is_cpu_exclusive(cs) != is_cpu_exclusive(&trialcs));
+	if (turning_on)
+		set_bit(bit, &cs->flags);
+	else
+		clear_bit(bit, &cs->flags);
+
+	if (cpu_exclusive_changed)
+                update_cpu_domains(cs);
+	return 0;
 }
 
-static int attach_task(struct cpuset *cs, char *buf)
+static int attach_task(struct cpuset *cs, char *pidbuf, char **ppathbuf)
 {
 	pid_t pid;
 	struct task_struct *tsk;
 	struct cpuset *oldcs;
 	cpumask_t cpus;
 
-	if (sscanf(buf, "%d", &pid) != 1)
+	if (sscanf(pidbuf, "%d", &pid) != 1)
 		return -EIO;
 	if (cpus_empty(cs->cpus_allowed) || nodes_empty(cs->mems_allowed))
 		return -ENOSPC;
@@ -722,7 +811,7 @@ static int attach_task(struct cpuset *cs
 
 	put_task_struct(tsk);
 	if (atomic_dec_and_test(&oldcs->count))
-		check_for_release(oldcs);
+		check_for_release(oldcs, ppathbuf);
 	return 0;
 }
 
@@ -746,6 +835,7 @@ static ssize_t cpuset_common_file_write(
 	struct cftype *cft = __d_cft(file->f_dentry);
 	cpuset_filetype_t type = cft->private;
 	char *buffer;
+	char *pathbuf = NULL;
 	int retval = 0;
 
 	/* Crude upper limit on largest legitimate cpulist user might write. */
@@ -786,7 +876,7 @@ static ssize_t cpuset_common_file_write(
 		retval = update_flag(CS_NOTIFY_ON_RELEASE, cs, buffer);
 		break;
 	case FILE_TASKLIST:
-		retval = attach_task(cs, buffer);
+		retval = attach_task(cs, buffer, &pathbuf);
 		break;
 	default:
 		retval = -EINVAL;
@@ -797,6 +887,7 @@ static ssize_t cpuset_common_file_write(
 		retval = nbytes;
 out2:
 	up(&cpuset_sem);
+	cpuset_release_agent(pathbuf);
 out1:
 	kfree(buffer);
 	return retval;
@@ -1302,6 +1393,7 @@ static int cpuset_rmdir(struct inode *un
 	struct cpuset *cs = dentry->d_fsdata;
 	struct dentry *d;
 	struct cpuset *parent;
+	char *pathbuf = NULL;
 
 	/* the vfs holds both inode->i_sem already */
 
@@ -1315,18 +1407,21 @@ static int cpuset_rmdir(struct inode *un
 		up(&cpuset_sem);
 		return -EBUSY;
 	}
-	spin_lock(&cs->dentry->d_lock);
 	parent = cs->parent;
 	set_bit(CS_REMOVED, &cs->flags);
+	if (is_cpu_exclusive(cs))
+		update_cpu_domains(cs);
 	list_del(&cs->sibling);	/* delete my sibling from parent->children */
 	if (list_empty(&parent->children))
-		check_for_release(parent);
+		check_for_release(parent, &pathbuf);
+	spin_lock(&cs->dentry->d_lock);
 	d = dget(cs->dentry);
 	cs->dentry = NULL;
 	spin_unlock(&d->d_lock);
 	cpuset_d_remove_dir(d);
 	dput(d);
 	up(&cpuset_sem);
+	cpuset_release_agent(pathbuf);
 	return 0;
 }
 
@@ -1383,10 +1478,10 @@ void __init cpuset_init_smp(void)
 
 /**
  * cpuset_fork - attach newly forked task to its parents cpuset.
- * @p: pointer to task_struct of forking parent process.
+ * @tsk: pointer to task_struct of forking parent process.
  *
  * Description: By default, on fork, a task inherits its
- * parents cpuset.  The pointer to the shared cpuset is
+ * parent's cpuset.  The pointer to the shared cpuset is
  * automatically copied in fork.c by dup_task_struct().
  * This cpuset_fork() routine need only increment the usage
  * counter in that cpuset.
@@ -1414,7 +1509,6 @@ void cpuset_fork(struct task_struct *tsk
  * by the cpuset_sem semaphore.  If you don't hold cpuset_sem,
  * then a zero cpuset use count is a license to any other task to
  * nuke the cpuset immediately.
- *
  **/
 
 void cpuset_exit(struct task_struct *tsk)
@@ -1427,10 +1521,13 @@ void cpuset_exit(struct task_struct *tsk
 	task_unlock(tsk);
 
 	if (notify_on_release(cs)) {
+		char *pathbuf = NULL;
+
 		down(&cpuset_sem);
 		if (atomic_dec_and_test(&cs->count))
-			check_for_release(cs);
+			check_for_release(cs, &pathbuf);
 		up(&cpuset_sem);
+		cpuset_release_agent(pathbuf);
 	} else {
 		atomic_dec(&cs->count);
 	}
@@ -1464,7 +1561,9 @@ void cpuset_init_current_mems_allowed(vo
 	current->mems_allowed = NODE_MASK_ALL;
 }
 
-/*
+/**
+ * cpuset_update_current_mems_allowed - update mems parameters to new values
+ *
  * If the current tasks cpusets mems_allowed changed behind our backs,
  * update current->mems_allowed and mems_generation to the new value.
  * Do not call this routine if in_interrupt().
@@ -1483,13 +1582,20 @@ void cpuset_update_current_mems_allowed(
 	}
 }
 
+/**
+ * cpuset_restrict_to_mems_allowed - limit nodes to current mems_allowed
+ * @nodes: pointer to a node bitmap that is and-ed with mems_allowed
+ */
 void cpuset_restrict_to_mems_allowed(unsigned long *nodes)
 {
 	bitmap_and(nodes, nodes, nodes_addr(current->mems_allowed),
 							MAX_NUMNODES);
 }
 
-/*
+/**
+ * cpuset_zonelist_valid_mems_allowed - check zonelist vs. curremt mems_allowed
+ * @zl: the zonelist to be checked
+ *
  * Are any of the nodes on zonelist zl allowed in current->mems_allowed?
  */
 int cpuset_zonelist_valid_mems_allowed(struct zonelist *zl)
@@ -1505,8 +1611,12 @@ int cpuset_zonelist_valid_mems_allowed(s
 	return 0;
 }
 
-/*
- * Is 'current' valid, and is zone z allowed in current->mems_allowed?
+/**
+ * cpuset_zone_allowed - is zone z allowed in current->mems_allowed
+ * @z: zone in question
+ *
+ * Is zone z allowed in current->mems_allowed, or is
+ * the CPU in interrupt context? (zone is always allowed in this case)
  */
 int cpuset_zone_allowed(struct zone *z)
 {
diff --git a/kernel/crash_dump.c b/kernel/crash_dump.c
new file mode 100644
--- /dev/null
+++ b/kernel/crash_dump.c
@@ -0,0 +1,61 @@
+/*
+ *	kernel/crash_dump.c - Memory preserving reboot related code.
+ *
+ *	Created by: Hariprasad Nellitheertha (hari@in.ibm.com)
+ *	Copyright (C) IBM Corporation, 2004. All rights reserved
+ */
+
+#include <linux/smp_lock.h>
+#include <linux/errno.h>
+#include <linux/proc_fs.h>
+#include <linux/bootmem.h>
+#include <linux/highmem.h>
+#include <linux/crash_dump.h>
+
+#include <asm/io.h>
+#include <asm/uaccess.h>
+
+/* Stores the physical address of elf header of crash image. */
+unsigned long long elfcorehdr_addr = ELFCORE_ADDR_MAX;
+
+/**
+ * copy_oldmem_page - copy one page from "oldmem"
+ * @pfn: page frame number to be copied
+ * @buf: target memory address for the copy; this can be in kernel address
+ *	space or user address space (see @userbuf)
+ * @csize: number of bytes to copy
+ * @offset: offset in bytes into the page (based on pfn) to begin the copy
+ * @userbuf: if set, @buf is in user address space, use copy_to_user(),
+ *	otherwise @buf is in kernel address space, use memcpy().
+ *
+ * Copy a page from "oldmem". For this page, there is no pte mapped
+ * in the current kernel. We stitch up a pte, similar to kmap_atomic.
+ */
+ssize_t copy_oldmem_page(unsigned long pfn, char *buf,
+				size_t csize, unsigned long offset, int userbuf)
+{
+	void *page, *vaddr;
+
+	if (!csize)
+		return 0;
+
+	page = kmalloc(PAGE_SIZE, GFP_KERNEL);
+	if (!page)
+		return -ENOMEM;
+
+	vaddr = kmap_atomic_pfn(pfn, KM_PTE0);
+	copy_page(page, vaddr);
+	kunmap_atomic(vaddr, KM_PTE0);
+
+	if (userbuf) {
+		if (copy_to_user(buf, (page + offset), csize)) {
+			kfree(page);
+			return -EFAULT;
+		}
+	} else {
+		memcpy(buf, (page + offset), csize);
+	}
+
+	kfree(page);
+	return csize;
+}
diff --git a/kernel/exit.c b/kernel/exit.c
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -72,6 +72,11 @@ repeat: 
 	BUG_ON(!list_empty(&p->ptrace_list) || !list_empty(&p->ptrace_children));
 	__exit_signal(p);
 	__exit_sighand(p);
+	/*
+	 * Note that the fastpath in sys_times depends on __exit_signal having
+	 * updated the counters before a task is removed from the tasklist of
+	 * the process by __unhash_process.
+	 */
 	__unhash_process(p);
 
 	/*
@@ -779,6 +784,8 @@ fastcall NORET_TYPE void do_exit(long co
 
 	profile_task_exit(tsk);
 
+	WARN_ON(atomic_read(&tsk->fs_excl));
+
 	if (unlikely(in_interrupt()))
 		panic("Aiee, killing interrupt handler!");
 	if (unlikely(!tsk->pid))
@@ -793,6 +800,17 @@ fastcall NORET_TYPE void do_exit(long co
 		ptrace_notify((PTRACE_EVENT_EXIT << 8) | SIGTRAP);
 	}
 
+	/*
+	 * We're taking recursive faults here in do_exit. Safest is to just
+	 * leave this task alone and wait for reboot.
+	 */
+	if (unlikely(tsk->flags & PF_EXITING)) {
+		printk(KERN_ALERT
+			"Fixing recursive fault but reboot is needed!\n");
+		set_current_state(TASK_UNINTERRUPTIBLE);
+		schedule();
+	}
+
 	tsk->flags |= PF_EXITING;
 
 	/*
@@ -811,8 +829,10 @@ fastcall NORET_TYPE void do_exit(long co
 	acct_update_integrals(tsk);
 	update_mem_hiwater(tsk);
 	group_dead = atomic_dec_and_test(&tsk->signal->live);
-	if (group_dead)
+	if (group_dead) {
+ 		del_timer_sync(&tsk->signal->real_timer);
 		acct_process(code);
+	}
 	exit_mm(tsk);
 
 	exit_sem(tsk);
diff --git a/kernel/fork.c b/kernel/fork.c
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -194,6 +194,7 @@ static inline int dup_mmap(struct mm_str
 	mm->mmap = NULL;
 	mm->mmap_cache = NULL;
 	mm->free_area_cache = oldmm->mmap_base;
+	mm->cached_hole_size = ~0UL;
 	mm->map_count = 0;
 	set_mm_counter(mm, rss, 0);
 	set_mm_counter(mm, anon_rss, 0);
@@ -207,8 +208,10 @@ static inline int dup_mmap(struct mm_str
 		struct file *file;
 
 		if (mpnt->vm_flags & VM_DONTCOPY) {
+			long pages = vma_pages(mpnt);
+			mm->total_vm -= pages;
 			__vm_stat_account(mm, mpnt->vm_flags, mpnt->vm_file,
-							-vma_pages(mpnt));
+								-pages);
 			continue;
 		}
 		charge = 0;
@@ -249,8 +252,9 @@ static inline int dup_mmap(struct mm_str
 
 		/*
 		 * Link in the new vma and copy the page table entries:
-		 * link in first so that swapoff can see swap entries,
-		 * and try_to_unmap_one's find_vma find the new vma.
+		 * link in first so that swapoff can see swap entries.
+		 * Note that, exceptionally, here the vma is inserted
+		 * without holding mm->mmap_sem.
 		 */
 		spin_lock(&mm->page_table_lock);
 		*pprev = tmp;
@@ -322,6 +326,7 @@ static struct mm_struct * mm_init(struct
 	mm->ioctx_list = NULL;
 	mm->default_kioctx = (struct kioctx)INIT_KIOCTX(mm->default_kioctx, *mm);
 	mm->free_area_cache = TASK_UNMAPPED_BASE;
+	mm->cached_hole_size = ~0UL;
 
 	if (likely(!mm_alloc_pgd(mm))) {
 		mm->def_flags = 0;
@@ -1000,9 +1005,6 @@ static task_t *copy_process(unsigned lon
 	p->pdeath_signal = 0;
 	p->exit_state = 0;
 
-	/* Perform scheduler related setup */
-	sched_fork(p);
-
 	/*
 	 * Ok, make it visible to the rest of the system.
 	 * We dont wake it up yet.
@@ -1011,18 +1013,24 @@ static task_t *copy_process(unsigned lon
 	INIT_LIST_HEAD(&p->ptrace_children);
 	INIT_LIST_HEAD(&p->ptrace_list);
 
+	/* Perform scheduler related setup. Assign this task to a CPU. */
+	sched_fork(p, clone_flags);
+
 	/* Need tasklist lock for parent etc handling! */
 	write_lock_irq(&tasklist_lock);
 
 	/*
-	 * The task hasn't been attached yet, so cpus_allowed mask cannot
-	 * have changed. The cpus_allowed mask of the parent may have
-	 * changed after it was copied first time, and it may then move to
-	 * another CPU - so we re-copy it here and set the child's CPU to
-	 * the parent's CPU. This avoids alot of nasty races.
+	 * The task hasn't been attached yet, so its cpus_allowed mask will
+	 * not be changed, nor will its assigned CPU.
+	 *
+	 * The cpus_allowed mask of the parent may have changed after it was
+	 * copied first time - so re-copy it here, then check the child's CPU
+	 * to ensure it is on a valid CPU (and if not, just force it back to
+	 * parent's CPU). This avoids alot of nasty races.
 	 */
 	p->cpus_allowed = current->cpus_allowed;
-	set_task_cpu(p, smp_processor_id());
+	if (unlikely(!cpu_isset(task_cpu(p), p->cpus_allowed)))
+		set_task_cpu(p, smp_processor_id());
 
 	/*
 	 * Check for pending SIGKILL! The new thread should not be allowed
@@ -1084,6 +1092,11 @@ static task_t *copy_process(unsigned lon
 		spin_unlock(&current->sighand->siglock);
 	}
 
+	/*
+	 * inherit ioprio
+	 */
+	p->ioprio = current->ioprio;
+
 	SET_LINKS(p);
 	if (unlikely(p->ptrace & PT_PTRACED))
 		__ptrace_link(p, current->parent);
diff --git a/kernel/irq/autoprobe.c b/kernel/irq/autoprobe.c
--- a/kernel/irq/autoprobe.c
+++ b/kernel/irq/autoprobe.c
@@ -9,6 +9,7 @@
 #include <linux/irq.h>
 #include <linux/module.h>
 #include <linux/interrupt.h>
+#include <linux/delay.h>
 
 /*
  * Autodetection depends on the fact that any interrupt that
@@ -26,7 +27,7 @@ static DECLARE_MUTEX(probe_sem);
  */
 unsigned long probe_irq_on(void)
 {
-	unsigned long val, delay;
+	unsigned long val;
 	irq_desc_t *desc;
 	unsigned int i;
 
@@ -45,8 +46,7 @@ unsigned long probe_irq_on(void)
 	}
 
 	/* Wait for longstanding interrupts to trigger. */
-	for (delay = jiffies + HZ/50; time_after(delay, jiffies); )
-		/* about 20ms delay */ barrier();
+	msleep(20);
 
 	/*
 	 * enable any unassigned irqs
@@ -68,8 +68,7 @@ unsigned long probe_irq_on(void)
 	/*
 	 * Wait for spurious interrupts to trigger
 	 */
-	for (delay = jiffies + HZ/10; time_after(delay, jiffies); )
-		/* about 100ms delay */ barrier();
+	msleep(100);
 
 	/*
 	 * Now filter out any obviously spurious interrupts
diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c
--- a/kernel/irq/handle.c
+++ b/kernel/irq/handle.c
@@ -172,7 +172,7 @@ fastcall unsigned int __do_IRQ(unsigned 
 
 		spin_lock(&desc->lock);
 		if (!noirqdebug)
-			note_interrupt(irq, desc, action_ret);
+			note_interrupt(irq, desc, action_ret, regs);
 		if (likely(!(desc->status & IRQ_PENDING)))
 			break;
 		desc->status &= ~IRQ_PENDING;
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -6,6 +6,7 @@
  * This file contains driver APIs to the irq subsystem.
  */
 
+#include <linux/config.h>
 #include <linux/irq.h>
 #include <linux/module.h>
 #include <linux/random.h>
@@ -255,6 +256,13 @@ void free_irq(unsigned int irq, void *de
 
 			/* Found it - now remove it from the list of entries */
 			*pp = action->next;
+
+			/* Currently used only by UML, might disappear one day.*/
+#ifdef CONFIG_IRQ_RELEASE_METHOD
+			if (desc->handler->release)
+				desc->handler->release(irq, dev_id);
+#endif
+
 			if (!desc->action) {
 				desc->status |= IRQ_DISABLED;
 				if (desc->handler->shutdown)
diff --git a/kernel/irq/spurious.c b/kernel/irq/spurious.c
--- a/kernel/irq/spurious.c
+++ b/kernel/irq/spurious.c
@@ -11,6 +11,83 @@
 #include <linux/kallsyms.h>
 #include <linux/interrupt.h>
 
+static int irqfixup;
+
+/*
+ * Recovery handler for misrouted interrupts.
+ */
+
+static int misrouted_irq(int irq, struct pt_regs *regs)
+{
+	int i;
+	irq_desc_t *desc;
+	int ok = 0;
+	int work = 0;	/* Did we do work for a real IRQ */
+
+	for(i = 1; i < NR_IRQS; i++) {
+		struct irqaction *action;
+
+		if (i == irq)	/* Already tried */
+			continue;
+		desc = &irq_desc[i];
+		spin_lock(&desc->lock);
+		action = desc->action;
+		/* Already running on another processor */
+		if (desc->status & IRQ_INPROGRESS) {
+			/*
+			 * Already running: If it is shared get the other
+			 * CPU to go looking for our mystery interrupt too
+			 */
+			if (desc->action && (desc->action->flags & SA_SHIRQ))
+				desc->status |= IRQ_PENDING;
+			spin_unlock(&desc->lock);
+			continue;
+		}
+		/* Honour the normal IRQ locking */
+		desc->status |= IRQ_INPROGRESS;
+		spin_unlock(&desc->lock);
+		while (action) {
+			/* Only shared IRQ handlers are safe to call */
+			if (action->flags & SA_SHIRQ) {
+				if (action->handler(i, action->dev_id, regs) ==
+						IRQ_HANDLED)
+					ok = 1;
+			}
+			action = action->next;
+		}
+		local_irq_disable();
+		/* Now clean up the flags */
+		spin_lock(&desc->lock);
+		action = desc->action;
+
+		/*
+		 * While we were looking for a fixup someone queued a real
+		 * IRQ clashing with our walk
+		 */
+
+		while ((desc->status & IRQ_PENDING) && action) {
+			/*
+			 * Perform real IRQ processing for the IRQ we deferred
+			 */
+			work = 1;
+			spin_unlock(&desc->lock);
+			handle_IRQ_event(i, regs, action);
+			spin_lock(&desc->lock);
+			desc->status &= ~IRQ_PENDING;
+		}
+		desc->status &= ~IRQ_INPROGRESS;
+		/*
+		 * If we did actual work for the real IRQ line we must let the
+		 * IRQ controller clean up too
+		 */
+		if(work)
+			desc->handler->end(i);
+		spin_unlock(&desc->lock);
+	}
+	/* So the caller can adjust the irq error counts */
+	return ok;
+}
+
 /*
  * If 99,900 of the previous 100,000 interrupts have not been handled
  * then assume that the IRQ is stuck in some manner. Drop a diagnostic
@@ -31,7 +108,8 @@ __report_bad_irq(unsigned int irq, irq_d
 		printk(KERN_ERR "irq event %d: bogus return value %x\n",
 				irq, action_ret);
 	} else {
-		printk(KERN_ERR "irq %d: nobody cared!\n", irq);
+		printk(KERN_ERR "irq %d: nobody cared (try booting with "
+				"the \"irqpoll\" option)\n", irq);
 	}
 	dump_stack();
 	printk(KERN_ERR "handlers:\n");
@@ -45,7 +123,7 @@ __report_bad_irq(unsigned int irq, irq_d
 	}
 }
 
-void report_bad_irq(unsigned int irq, irq_desc_t *desc, irqreturn_t action_ret)
+static void report_bad_irq(unsigned int irq, irq_desc_t *desc, irqreturn_t action_ret)
 {
 	static int count = 100;
 
@@ -55,7 +133,8 @@ void report_bad_irq(unsigned int irq, ir
 	}
 }
 
-void note_interrupt(unsigned int irq, irq_desc_t *desc, irqreturn_t action_ret)
+void note_interrupt(unsigned int irq, irq_desc_t *desc, irqreturn_t action_ret,
+			struct pt_regs *regs)
 {
 	if (action_ret != IRQ_HANDLED) {
 		desc->irqs_unhandled++;
@@ -63,6 +142,15 @@ void note_interrupt(unsigned int irq, ir
 			report_bad_irq(irq, desc, action_ret);
 	}
 
+	if (unlikely(irqfixup)) {
+		/* Don't punish working computers */
+		if ((irqfixup == 2 && irq == 0) || action_ret == IRQ_NONE) {
+			int ok = misrouted_irq(irq, regs);
+			if (action_ret == IRQ_NONE)
+				desc->irqs_unhandled -= ok;
+		}
+	}
+
 	desc->irq_count++;
 	if (desc->irq_count < 100000)
 		return;
@@ -94,3 +182,24 @@ int __init noirqdebug_setup(char *str)
 
 __setup("noirqdebug", noirqdebug_setup);
 
+static int __init irqfixup_setup(char *str)
+{
+	irqfixup = 1;
+	printk(KERN_WARNING "Misrouted IRQ fixup support enabled.\n");
+	printk(KERN_WARNING "This may impact system performance.\n");
+	return 1;
+}
+
+__setup("irqfixup", irqfixup_setup);
+
+static int __init irqpoll_setup(char *str)
+{
+	irqfixup = 2;
+	printk(KERN_WARNING "Misrouted IRQ fixup and polling support "
+				"enabled\n");
+	printk(KERN_WARNING "This may significantly impact system "
+				"performance\n");
+	return 1;
+}
+
+__setup("irqpoll", irqpoll_setup);
diff --git a/kernel/itimer.c b/kernel/itimer.c
--- a/kernel/itimer.c
+++ b/kernel/itimer.c
@@ -112,28 +112,11 @@ asmlinkage long sys_getitimer(int which,
 	return error;
 }
 
-/*
- * Called with P->sighand->siglock held and P->signal->real_timer inactive.
- * If interval is nonzero, arm the timer for interval ticks from now.
- */
-static inline void it_real_arm(struct task_struct *p, unsigned long interval)
-{
-	p->signal->it_real_value = interval; /* XXX unnecessary field?? */
-	if (interval == 0)
-		return;
-	if (interval > (unsigned long) LONG_MAX)
-		interval = LONG_MAX;
-	/* the "+ 1" below makes sure that the timer doesn't go off before
-	 * the interval requested. This could happen if
-	 * time requested % (usecs per jiffy) is more than the usecs left
-	 * in the current jiffy */
-	p->signal->real_timer.expires = jiffies + interval + 1;
-	add_timer(&p->signal->real_timer);
-}
 
 void it_real_fn(unsigned long __data)
 {
 	struct task_struct * p = (struct task_struct *) __data;
+	unsigned long inc = p->signal->it_real_incr;
 
 	send_group_sig_info(SIGALRM, SEND_SIG_PRIV, p);
 
@@ -141,26 +124,42 @@ void it_real_fn(unsigned long __data)
 	 * Now restart the timer if necessary.  We don't need any locking
 	 * here because do_setitimer makes sure we have finished running
 	 * before it touches anything.
+	 * Note, we KNOW we are (or should be) at a jiffie edge here so
+	 * we don't need the +1 stuff.  Also, we want to use the prior
+	 * expire value so as to not "slip" a jiffie if we are late.
+	 * Deal with requesting a time prior to "now" here rather than
+	 * in add_timer.
 	 */
-	it_real_arm(p, p->signal->it_real_incr);
+	if (!inc)
+		return;
+	while (time_before_eq(p->signal->real_timer.expires, jiffies))
+		p->signal->real_timer.expires += inc;
+	add_timer(&p->signal->real_timer);
 }
 
 int do_setitimer(int which, struct itimerval *value, struct itimerval *ovalue)
 {
 	struct task_struct *tsk = current;
- 	unsigned long val, interval;
+ 	unsigned long val, interval, expires;
 	cputime_t cval, cinterval, nval, ninterval;
 
 	switch (which) {
 	case ITIMER_REAL:
+again:
 		spin_lock_irq(&tsk->sighand->siglock);
 		interval = tsk->signal->it_real_incr;
 		val = it_real_value(tsk->signal);
-		if (val)
-			del_timer_sync(&tsk->signal->real_timer);
+		/* We are sharing ->siglock with it_real_fn() */
+		if (try_to_del_timer_sync(&tsk->signal->real_timer) < 0) {
+			spin_unlock_irq(&tsk->sighand->siglock);
+			goto again;
+		}
 		tsk->signal->it_real_incr =
 			timeval_to_jiffies(&value->it_interval);
-		it_real_arm(tsk, timeval_to_jiffies(&value->it_value));
+		expires = timeval_to_jiffies(&value->it_value);
+		if (expires)
+			mod_timer(&tsk->signal->real_timer,
+				  jiffies + 1 + expires);
 		spin_unlock_irq(&tsk->sighand->siglock);
 		if (ovalue) {
 			jiffies_to_timeval(val, &ovalue->it_value);
diff --git a/kernel/kexec.c b/kernel/kexec.c
new file mode 100644
--- /dev/null
+++ b/kernel/kexec.c
@@ -0,0 +1,1063 @@
+/*
+ * kexec.c - kexec system call
+ * Copyright (C) 2002-2004 Eric Biederman  <ebiederm@xmission.com>
+ *
+ * This source code is licensed under the GNU General Public License,
+ * Version 2.  See the file COPYING for more details.
+ */
+
+#include <linux/mm.h>
+#include <linux/file.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/kexec.h>
+#include <linux/spinlock.h>
+#include <linux/list.h>
+#include <linux/highmem.h>
+#include <linux/syscalls.h>
+#include <linux/reboot.h>
+#include <linux/syscalls.h>
+#include <linux/ioport.h>
+#include <linux/hardirq.h>
+
+#include <asm/page.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/semaphore.h>
+
+/* Location of the reserved area for the crash kernel */
+struct resource crashk_res = {
+	.name  = "Crash kernel",
+	.start = 0,
+	.end   = 0,
+	.flags = IORESOURCE_BUSY | IORESOURCE_MEM
+};
+
+int kexec_should_crash(struct task_struct *p)
+{
+	if (in_interrupt() || !p->pid || p->pid == 1 || panic_on_oops)
+		return 1;
+	return 0;
+}
+
+/*
+ * When kexec transitions to the new kernel there is a one-to-one
+ * mapping between physical and virtual addresses.  On processors
+ * where you can disable the MMU this is trivial, and easy.  For
+ * others it is still a simple predictable page table to setup.
+ *
+ * In that environment kexec copies the new kernel to its final
+ * resting place.  This means I can only support memory whose
+ * physical address can fit in an unsigned long.  In particular
+ * addresses where (pfn << PAGE_SHIFT) > ULONG_MAX cannot be handled.
+ * If the assembly stub has more restrictive requirements
+ * KEXEC_SOURCE_MEMORY_LIMIT and KEXEC_DEST_MEMORY_LIMIT can be
+ * defined more restrictively in <asm/kexec.h>.
+ *
+ * The code for the transition from the current kernel to the
+ * the new kernel is placed in the control_code_buffer, whose size
+ * is given by KEXEC_CONTROL_CODE_SIZE.  In the best case only a single
+ * page of memory is necessary, but some architectures require more.
+ * Because this memory must be identity mapped in the transition from
+ * virtual to physical addresses it must live in the range
+ * 0 - TASK_SIZE, as only the user space mappings are arbitrarily
+ * modifiable.
+ *
+ * The assembly stub in the control code buffer is passed a linked list
+ * of descriptor pages detailing the source pages of the new kernel,
+ * and the destination addresses of those source pages.  As this data
+ * structure is not used in the context of the current OS, it must
+ * be self-contained.
+ *
+ * The code has been made to work with highmem pages and will use a
+ * destination page in its final resting place (if it happens
+ * to allocate it).  The end product of this is that most of the
+ * physical address space, and most of RAM can be used.
+ *
+ * Future directions include:
+ *  - allocating a page table with the control code buffer identity
+ *    mapped, to simplify machine_kexec and make kexec_on_panic more
+ *    reliable.
+ */
+
+/*
+ * KIMAGE_NO_DEST is an impossible destination address..., for
+ * allocating pages whose destination address we do not care about.
+ */
+#define KIMAGE_NO_DEST (-1UL)
+
+static int kimage_is_destination_range(struct kimage *image,
+				       unsigned long start, unsigned long end);
+static struct page *kimage_alloc_page(struct kimage *image,
+				       unsigned int gfp_mask,
+				       unsigned long dest);
+
+static int do_kimage_alloc(struct kimage **rimage, unsigned long entry,
+	                    unsigned long nr_segments,
+                            struct kexec_segment __user *segments)
+{
+	size_t segment_bytes;
+	struct kimage *image;
+	unsigned long i;
+	int result;
+
+	/* Allocate a controlling structure */
+	result = -ENOMEM;
+	image = kmalloc(sizeof(*image), GFP_KERNEL);
+	if (!image)
+		goto out;
+
+	memset(image, 0, sizeof(*image));
+	image->head = 0;
+	image->entry = &image->head;
+	image->last_entry = &image->head;
+	image->control_page = ~0; /* By default this does not apply */
+	image->start = entry;
+	image->type = KEXEC_TYPE_DEFAULT;
+
+	/* Initialize the list of control pages */
+	INIT_LIST_HEAD(&image->control_pages);
+
+	/* Initialize the list of destination pages */
+	INIT_LIST_HEAD(&image->dest_pages);
+
+	/* Initialize the list of unuseable pages */
+	INIT_LIST_HEAD(&image->unuseable_pages);
+
+	/* Read in the segments */
+	image->nr_segments = nr_segments;
+	segment_bytes = nr_segments * sizeof(*segments);
+	result = copy_from_user(image->segment, segments, segment_bytes);
+	if (result)
+		goto out;
+
+	/*
+	 * Verify we have good destination addresses.  The caller is
+	 * responsible for making certain we don't attempt to load
+	 * the new image into invalid or reserved areas of RAM.  This
+	 * just verifies it is an address we can use.
+	 *
+	 * Since the kernel does everything in page size chunks ensure
+	 * the destination addreses are page aligned.  Too many
+	 * special cases crop of when we don't do this.  The most
+	 * insidious is getting overlapping destination addresses
+	 * simply because addresses are changed to page size
+	 * granularity.
+	 */
+	result = -EADDRNOTAVAIL;
+	for (i = 0; i < nr_segments; i++) {
+		unsigned long mstart, mend;
+
+		mstart = image->segment[i].mem;
+		mend   = mstart + image->segment[i].memsz;
+		if ((mstart & ~PAGE_MASK) || (mend & ~PAGE_MASK))
+			goto out;
+		if (mend >= KEXEC_DESTINATION_MEMORY_LIMIT)
+			goto out;
+	}
+
+	/* Verify our destination addresses do not overlap.
+	 * If we alloed overlapping destination addresses
+	 * through very weird things can happen with no
+	 * easy explanation as one segment stops on another.
+	 */
+	result = -EINVAL;
+	for (i = 0; i < nr_segments; i++) {
+		unsigned long mstart, mend;
+		unsigned long j;
+
+		mstart = image->segment[i].mem;
+		mend   = mstart + image->segment[i].memsz;
+		for (j = 0; j < i; j++) {
+			unsigned long pstart, pend;
+			pstart = image->segment[j].mem;
+			pend   = pstart + image->segment[j].memsz;
+			/* Do the segments overlap ? */
+			if ((mend > pstart) && (mstart < pend))
+				goto out;
+		}
+	}
+
+	/* Ensure our buffer sizes are strictly less than
+	 * our memory sizes.  This should always be the case,
+	 * and it is easier to check up front than to be surprised
+	 * later on.
+	 */
+	result = -EINVAL;
+	for (i = 0; i < nr_segments; i++) {
+		if (image->segment[i].bufsz > image->segment[i].memsz)
+			goto out;
+	}
+
+	result = 0;
+out:
+	if (result == 0)
+		*rimage = image;
+	else
+		kfree(image);
+
+	return result;
+
+}
+
+static int kimage_normal_alloc(struct kimage **rimage, unsigned long entry,
+				unsigned long nr_segments,
+				struct kexec_segment __user *segments)
+{
+	int result;
+	struct kimage *image;
+
+	/* Allocate and initialize a controlling structure */
+	image = NULL;
+	result = do_kimage_alloc(&image, entry, nr_segments, segments);
+	if (result)
+		goto out;
+
+	*rimage = image;
+
+	/*
+	 * Find a location for the control code buffer, and add it
+	 * the vector of segments so that it's pages will also be
+	 * counted as destination pages.
+	 */
+	result = -ENOMEM;
+	image->control_code_page = kimage_alloc_control_pages(image,
+					   get_order(KEXEC_CONTROL_CODE_SIZE));
+	if (!image->control_code_page) {
+		printk(KERN_ERR "Could not allocate control_code_buffer\n");
+		goto out;
+	}
+
+	result = 0;
+ out:
+	if (result == 0)
+		*rimage = image;
+	else
+		kfree(image);
+
+	return result;
+}
+
+static int kimage_crash_alloc(struct kimage **rimage, unsigned long entry,
+				unsigned long nr_segments,
+				struct kexec_segment __user *segments)
+{
+	int result;
+	struct kimage *image;
+	unsigned long i;
+
+	image = NULL;
+	/* Verify we have a valid entry point */
+	if ((entry < crashk_res.start) || (entry > crashk_res.end)) {
+		result = -EADDRNOTAVAIL;
+		goto out;
+	}
+
+	/* Allocate and initialize a controlling structure */
+	result = do_kimage_alloc(&image, entry, nr_segments, segments);
+	if (result)
+		goto out;
+
+	/* Enable the special crash kernel control page
+	 * allocation policy.
+	 */
+	image->control_page = crashk_res.start;
+	image->type = KEXEC_TYPE_CRASH;
+
+	/*
+	 * Verify we have good destination addresses.  Normally
+	 * the caller is responsible for making certain we don't
+	 * attempt to load the new image into invalid or reserved
+	 * areas of RAM.  But crash kernels are preloaded into a
+	 * reserved area of ram.  We must ensure the addresses
+	 * are in the reserved area otherwise preloading the
+	 * kernel could corrupt things.
+	 */
+	result = -EADDRNOTAVAIL;
+	for (i = 0; i < nr_segments; i++) {
+		unsigned long mstart, mend;
+
+		mstart = image->segment[i].mem;
+		mend = mstart + image->segment[i].memsz - 1;
+		/* Ensure we are within the crash kernel limits */
+		if ((mstart < crashk_res.start) || (mend > crashk_res.end))
+			goto out;
+	}
+
+	/*
+	 * Find a location for the control code buffer, and add
+	 * the vector of segments so that it's pages will also be
+	 * counted as destination pages.
+	 */
+	result = -ENOMEM;
+	image->control_code_page = kimage_alloc_control_pages(image,
+					   get_order(KEXEC_CONTROL_CODE_SIZE));
+	if (!image->control_code_page) {
+		printk(KERN_ERR "Could not allocate control_code_buffer\n");
+		goto out;
+	}
+
+	result = 0;
+out:
+	if (result == 0)
+		*rimage = image;
+	else
+		kfree(image);
+
+	return result;
+}
+
+static int kimage_is_destination_range(struct kimage *image,
+					unsigned long start,
+					unsigned long end)
+{
+	unsigned long i;
+
+	for (i = 0; i < image->nr_segments; i++) {
+		unsigned long mstart, mend;
+
+		mstart = image->segment[i].mem;
+		mend = mstart + image->segment[i].memsz;
+		if ((end > mstart) && (start < mend))
+			return 1;
+	}
+
+	return 0;
+}
+
+static struct page *kimage_alloc_pages(unsigned int gfp_mask,
+					unsigned int order)
+{
+	struct page *pages;
+
+	pages = alloc_pages(gfp_mask, order);
+	if (pages) {
+		unsigned int count, i;
+		pages->mapping = NULL;
+		pages->private = order;
+		count = 1 << order;
+		for (i = 0; i < count; i++)
+			SetPageReserved(pages + i);
+	}
+
+	return pages;
+}
+
+static void kimage_free_pages(struct page *page)
+{
+	unsigned int order, count, i;
+
+	order = page->private;
+	count = 1 << order;
+	for (i = 0; i < count; i++)
+		ClearPageReserved(page + i);
+	__free_pages(page, order);
+}
+
+static void kimage_free_page_list(struct list_head *list)
+{
+	struct list_head *pos, *next;
+
+	list_for_each_safe(pos, next, list) {
+		struct page *page;
+
+		page = list_entry(pos, struct page, lru);
+		list_del(&page->lru);
+		kimage_free_pages(page);
+	}
+}
+
+static struct page *kimage_alloc_normal_control_pages(struct kimage *image,
+							unsigned int order)
+{
+	/* Control pages are special, they are the intermediaries
+	 * that are needed while we copy the rest of the pages
+	 * to their final resting place.  As such they must
+	 * not conflict with either the destination addresses
+	 * or memory the kernel is already using.
+	 *
+	 * The only case where we really need more than one of
+	 * these are for architectures where we cannot disable
+	 * the MMU and must instead generate an identity mapped
+	 * page table for all of the memory.
+	 *
+	 * At worst this runs in O(N) of the image size.
+	 */
+	struct list_head extra_pages;
+	struct page *pages;
+	unsigned int count;
+
+	count = 1 << order;
+	INIT_LIST_HEAD(&extra_pages);
+
+	/* Loop while I can allocate a page and the page allocated
+	 * is a destination page.
+	 */
+	do {
+		unsigned long pfn, epfn, addr, eaddr;
+
+		pages = kimage_alloc_pages(GFP_KERNEL, order);
+		if (!pages)
+			break;
+		pfn   = page_to_pfn(pages);
+		epfn  = pfn + count;
+		addr  = pfn << PAGE_SHIFT;
+		eaddr = epfn << PAGE_SHIFT;
+		if ((epfn >= (KEXEC_CONTROL_MEMORY_LIMIT >> PAGE_SHIFT)) ||
+			      kimage_is_destination_range(image, addr, eaddr)) {
+			list_add(&pages->lru, &extra_pages);
+			pages = NULL;
+		}
+	} while (!pages);
+
+	if (pages) {
+		/* Remember the allocated page... */
+		list_add(&pages->lru, &image->control_pages);
+
+		/* Because the page is already in it's destination
+		 * location we will never allocate another page at
+		 * that address.  Therefore kimage_alloc_pages
+		 * will not return it (again) and we don't need
+		 * to give it an entry in image->segment[].
+		 */
+	}
+	/* Deal with the destination pages I have inadvertently allocated.
+	 *
+	 * Ideally I would convert multi-page allocations into single
+	 * page allocations, and add everyting to image->dest_pages.
+	 *
+	 * For now it is simpler to just free the pages.
+	 */
+	kimage_free_page_list(&extra_pages);
+
+	return pages;
+}
+
+static struct page *kimage_alloc_crash_control_pages(struct kimage *image,
+						      unsigned int order)
+{
+	/* Control pages are special, they are the intermediaries
+	 * that are needed while we copy the rest of the pages
+	 * to their final resting place.  As such they must
+	 * not conflict with either the destination addresses
+	 * or memory the kernel is already using.
+	 *
+	 * Control pages are also the only pags we must allocate
+	 * when loading a crash kernel.  All of the other pages
+	 * are specified by the segments and we just memcpy
+	 * into them directly.
+	 *
+	 * The only case where we really need more than one of
+	 * these are for architectures where we cannot disable
+	 * the MMU and must instead generate an identity mapped
+	 * page table for all of the memory.
+	 *
+	 * Given the low demand this implements a very simple
+	 * allocator that finds the first hole of the appropriate
+	 * size in the reserved memory region, and allocates all
+	 * of the memory up to and including the hole.
+	 */
+	unsigned long hole_start, hole_end, size;
+	struct page *pages;
+
+	pages = NULL;
+	size = (1 << order) << PAGE_SHIFT;
+	hole_start = (image->control_page + (size - 1)) & ~(size - 1);
+	hole_end   = hole_start + size - 1;
+	while (hole_end <= crashk_res.end) {
+		unsigned long i;
+
+		if (hole_end > KEXEC_CONTROL_MEMORY_LIMIT)
+			break;
+		if (hole_end > crashk_res.end)
+			break;
+		/* See if I overlap any of the segments */
+		for (i = 0; i < image->nr_segments; i++) {
+			unsigned long mstart, mend;
+
+			mstart = image->segment[i].mem;
+			mend   = mstart + image->segment[i].memsz - 1;
+			if ((hole_end >= mstart) && (hole_start <= mend)) {
+				/* Advance the hole to the end of the segment */
+				hole_start = (mend + (size - 1)) & ~(size - 1);
+				hole_end   = hole_start + size - 1;
+				break;
+			}
+		}
+		/* If I don't overlap any segments I have found my hole! */
+		if (i == image->nr_segments) {
+			pages = pfn_to_page(hole_start >> PAGE_SHIFT);
+			break;
+		}
+	}
+	if (pages)
+		image->control_page = hole_end;
+
+	return pages;
+}
+
+
+struct page *kimage_alloc_control_pages(struct kimage *image,
+					 unsigned int order)
+{
+	struct page *pages = NULL;
+
+	switch (image->type) {
+	case KEXEC_TYPE_DEFAULT:
+		pages = kimage_alloc_normal_control_pages(image, order);
+		break;
+	case KEXEC_TYPE_CRASH:
+		pages = kimage_alloc_crash_control_pages(image, order);
+		break;
+	}
+
+	return pages;
+}
+
+static int kimage_add_entry(struct kimage *image, kimage_entry_t entry)
+{
+	if (*image->entry != 0)
+		image->entry++;
+
+	if (image->entry == image->last_entry) {
+		kimage_entry_t *ind_page;
+		struct page *page;
+
+		page = kimage_alloc_page(image, GFP_KERNEL, KIMAGE_NO_DEST);
+		if (!page)
+			return -ENOMEM;
+
+		ind_page = page_address(page);
+		*image->entry = virt_to_phys(ind_page) | IND_INDIRECTION;
+		image->entry = ind_page;
+		image->last_entry = ind_page +
+				      ((PAGE_SIZE/sizeof(kimage_entry_t)) - 1);
+	}
+	*image->entry = entry;
+	image->entry++;
+	*image->entry = 0;
+
+	return 0;
+}
+
+static int kimage_set_destination(struct kimage *image,
+				   unsigned long destination)
+{
+	int result;
+
+	destination &= PAGE_MASK;
+	result = kimage_add_entry(image, destination | IND_DESTINATION);
+	if (result == 0)
+		image->destination = destination;
+
+	return result;
+}
+
+
+static int kimage_add_page(struct kimage *image, unsigned long page)
+{
+	int result;
+
+	page &= PAGE_MASK;
+	result = kimage_add_entry(image, page | IND_SOURCE);
+	if (result == 0)
+		image->destination += PAGE_SIZE;
+
+	return result;
+}
+
+
+static void kimage_free_extra_pages(struct kimage *image)
+{
+	/* Walk through and free any extra destination pages I may have */
+	kimage_free_page_list(&image->dest_pages);
+
+	/* Walk through and free any unuseable pages I have cached */
+	kimage_free_page_list(&image->unuseable_pages);
+
+}
+static int kimage_terminate(struct kimage *image)
+{
+	if (*image->entry != 0)
+		image->entry++;
+
+	*image->entry = IND_DONE;
+
+	return 0;
+}
+
+#define for_each_kimage_entry(image, ptr, entry) \
+	for (ptr = &image->head; (entry = *ptr) && !(entry & IND_DONE); \
+		ptr = (entry & IND_INDIRECTION)? \
+			phys_to_virt((entry & PAGE_MASK)): ptr +1)
+
+static void kimage_free_entry(kimage_entry_t entry)
+{
+	struct page *page;
+
+	page = pfn_to_page(entry >> PAGE_SHIFT);
+	kimage_free_pages(page);
+}
+
+static void kimage_free(struct kimage *image)
+{
+	kimage_entry_t *ptr, entry;
+	kimage_entry_t ind = 0;
+
+	if (!image)
+		return;
+
+	kimage_free_extra_pages(image);
+	for_each_kimage_entry(image, ptr, entry) {
+		if (entry & IND_INDIRECTION) {
+			/* Free the previous indirection page */
+			if (ind & IND_INDIRECTION)
+				kimage_free_entry(ind);
+			/* Save this indirection page until we are
+			 * done with it.
+			 */
+			ind = entry;
+		}
+		else if (entry & IND_SOURCE)
+			kimage_free_entry(entry);
+	}
+	/* Free the final indirection page */
+	if (ind & IND_INDIRECTION)
+		kimage_free_entry(ind);
+
+	/* Handle any machine specific cleanup */
+	machine_kexec_cleanup(image);
+
+	/* Free the kexec control pages... */
+	kimage_free_page_list(&image->control_pages);
+	kfree(image);
+}
+
+static kimage_entry_t *kimage_dst_used(struct kimage *image,
+					unsigned long page)
+{
+	kimage_entry_t *ptr, entry;
+	unsigned long destination = 0;
+
+	for_each_kimage_entry(image, ptr, entry) {
+		if (entry & IND_DESTINATION)
+			destination = entry & PAGE_MASK;
+		else if (entry & IND_SOURCE) {
+			if (page == destination)
+				return ptr;
+			destination += PAGE_SIZE;
+		}
+	}
+
+	return NULL;
+}
+
+static struct page *kimage_alloc_page(struct kimage *image,
+					unsigned int gfp_mask,
+					unsigned long destination)
+{
+	/*
+	 * Here we implement safeguards to ensure that a source page
+	 * is not copied to its destination page before the data on
+	 * the destination page is no longer useful.
+	 *
+	 * To do this we maintain the invariant that a source page is
+	 * either its own destination page, or it is not a
+	 * destination page at all.
+	 *
+	 * That is slightly stronger than required, but the proof
+	 * that no problems will not occur is trivial, and the
+	 * implementation is simply to verify.
+	 *
+	 * When allocating all pages normally this algorithm will run
+	 * in O(N) time, but in the worst case it will run in O(N^2)
+	 * time.   If the runtime is a problem the data structures can
+	 * be fixed.
+	 */
+	struct page *page;
+	unsigned long addr;
+
+	/*
+	 * Walk through the list of destination pages, and see if I
+	 * have a match.
+	 */
+	list_for_each_entry(page, &image->dest_pages, lru) {
+		addr = page_to_pfn(page) << PAGE_SHIFT;
+		if (addr == destination) {
+			list_del(&page->lru);
+			return page;
+		}
+	}
+	page = NULL;
+	while (1) {
+		kimage_entry_t *old;
+
+		/* Allocate a page, if we run out of memory give up */
+		page = kimage_alloc_pages(gfp_mask, 0);
+		if (!page)
+			return NULL;
+		/* If the page cannot be used file it away */
+		if (page_to_pfn(page) >
+				(KEXEC_SOURCE_MEMORY_LIMIT >> PAGE_SHIFT)) {
+			list_add(&page->lru, &image->unuseable_pages);
+			continue;
+		}
+		addr = page_to_pfn(page) << PAGE_SHIFT;
+
+		/* If it is the destination page we want use it */
+		if (addr == destination)
+			break;
+
+		/* If the page is not a destination page use it */
+		if (!kimage_is_destination_range(image, addr,
+						  addr + PAGE_SIZE))
+			break;
+
+		/*
+		 * I know that the page is someones destination page.
+		 * See if there is already a source page for this
+		 * destination page.  And if so swap the source pages.
+		 */
+		old = kimage_dst_used(image, addr);
+		if (old) {
+			/* If so move it */
+			unsigned long old_addr;
+			struct page *old_page;
+
+			old_addr = *old & PAGE_MASK;
+			old_page = pfn_to_page(old_addr >> PAGE_SHIFT);
+			copy_highpage(page, old_page);
+			*old = addr | (*old & ~PAGE_MASK);
+
+			/* The old page I have found cannot be a
+			 * destination page, so return it.
+			 */
+			addr = old_addr;
+			page = old_page;
+			break;
+		}
+		else {
+			/* Place the page on the destination list I
+			 * will use it later.
+			 */
+			list_add(&page->lru, &image->dest_pages);
+		}
+	}
+
+	return page;
+}
+
+static int kimage_load_normal_segment(struct kimage *image,
+					 struct kexec_segment *segment)
+{
+	unsigned long maddr;
+	unsigned long ubytes, mbytes;
+	int result;
+	unsigned char __user *buf;
+
+	result = 0;
+	buf = segment->buf;
+	ubytes = segment->bufsz;
+	mbytes = segment->memsz;
+	maddr = segment->mem;
+
+	result = kimage_set_destination(image, maddr);
+	if (result < 0)
+		goto out;
+
+	while (mbytes) {
+		struct page *page;
+		char *ptr;
+		size_t uchunk, mchunk;
+
+		page = kimage_alloc_page(image, GFP_HIGHUSER, maddr);
+		if (page == 0) {
+			result  = -ENOMEM;
+			goto out;
+		}
+		result = kimage_add_page(image, page_to_pfn(page)
+								<< PAGE_SHIFT);
+		if (result < 0)
+			goto out;
+
+		ptr = kmap(page);
+		/* Start with a clear page */
+		memset(ptr, 0, PAGE_SIZE);
+		ptr += maddr & ~PAGE_MASK;
+		mchunk = PAGE_SIZE - (maddr & ~PAGE_MASK);
+		if (mchunk > mbytes)
+			mchunk = mbytes;
+
+		uchunk = mchunk;
+		if (uchunk > ubytes)
+			uchunk = ubytes;
+
+		result = copy_from_user(ptr, buf, uchunk);
+		kunmap(page);
+		if (result) {
+			result = (result < 0) ? result : -EIO;
+			goto out;
+		}
+		ubytes -= uchunk;
+		maddr  += mchunk;
+		buf    += mchunk;
+		mbytes -= mchunk;
+	}
+out:
+	return result;
+}
+
+static int kimage_load_crash_segment(struct kimage *image,
+					struct kexec_segment *segment)
+{
+	/* For crash dumps kernels we simply copy the data from
+	 * user space to it's destination.
+	 * We do things a page at a time for the sake of kmap.
+	 */
+	unsigned long maddr;
+	unsigned long ubytes, mbytes;
+	int result;
+	unsigned char __user *buf;
+
+	result = 0;
+	buf = segment->buf;
+	ubytes = segment->bufsz;
+	mbytes = segment->memsz;
+	maddr = segment->mem;
+	while (mbytes) {
+		struct page *page;
+		char *ptr;
+		size_t uchunk, mchunk;
+
+		page = pfn_to_page(maddr >> PAGE_SHIFT);
+		if (page == 0) {
+			result  = -ENOMEM;
+			goto out;
+		}
+		ptr = kmap(page);
+		ptr += maddr & ~PAGE_MASK;
+		mchunk = PAGE_SIZE - (maddr & ~PAGE_MASK);
+		if (mchunk > mbytes)
+			mchunk = mbytes;
+
+		uchunk = mchunk;
+		if (uchunk > ubytes) {
+			uchunk = ubytes;
+			/* Zero the trailing part of the page */
+			memset(ptr + uchunk, 0, mchunk - uchunk);
+		}
+		result = copy_from_user(ptr, buf, uchunk);
+		kunmap(page);
+		if (result) {
+			result = (result < 0) ? result : -EIO;
+			goto out;
+		}
+		ubytes -= uchunk;
+		maddr  += mchunk;
+		buf    += mchunk;
+		mbytes -= mchunk;
+	}
+out:
+	return result;
+}
+
+static int kimage_load_segment(struct kimage *image,
+				struct kexec_segment *segment)
+{
+	int result = -ENOMEM;
+
+	switch (image->type) {
+	case KEXEC_TYPE_DEFAULT:
+		result = kimage_load_normal_segment(image, segment);
+		break;
+	case KEXEC_TYPE_CRASH:
+		result = kimage_load_crash_segment(image, segment);
+		break;
+	}
+
+	return result;
+}
+
+/*
+ * Exec Kernel system call: for obvious reasons only root may call it.
+ *
+ * This call breaks up into three pieces.
+ * - A generic part which loads the new kernel from the current
+ *   address space, and very carefully places the data in the
+ *   allocated pages.
+ *
+ * - A generic part that interacts with the kernel and tells all of
+ *   the devices to shut down.  Preventing on-going dmas, and placing
+ *   the devices in a consistent state so a later kernel can
+ *   reinitialize them.
+ *
+ * - A machine specific part that includes the syscall number
+ *   and the copies the image to it's final destination.  And
+ *   jumps into the image at entry.
+ *
+ * kexec does not sync, or unmount filesystems so if you need
+ * that to happen you need to do that yourself.
+ */
+struct kimage *kexec_image = NULL;
+static struct kimage *kexec_crash_image = NULL;
+/*
+ * A home grown binary mutex.
+ * Nothing can wait so this mutex is safe to use
+ * in interrupt context :)
+ */
+static int kexec_lock = 0;
+
+asmlinkage long sys_kexec_load(unsigned long entry, unsigned long nr_segments,
+				struct kexec_segment __user *segments,
+				unsigned long flags)
+{
+	struct kimage **dest_image, *image;
+	int locked;
+	int result;
+
+	/* We only trust the superuser with rebooting the system. */
+	if (!capable(CAP_SYS_BOOT))
+		return -EPERM;
+
+	/*
+	 * Verify we have a legal set of flags
+	 * This leaves us room for future extensions.
+	 */
+	if ((flags & KEXEC_FLAGS) != (flags & ~KEXEC_ARCH_MASK))
+		return -EINVAL;
+
+	/* Verify we are on the appropriate architecture */
+	if (((flags & KEXEC_ARCH_MASK) != KEXEC_ARCH) &&
+		((flags & KEXEC_ARCH_MASK) != KEXEC_ARCH_DEFAULT))
+		return -EINVAL;
+
+	/* Put an artificial cap on the number
+	 * of segments passed to kexec_load.
+	 */
+	if (nr_segments > KEXEC_SEGMENT_MAX)
+		return -EINVAL;
+
+	image = NULL;
+	result = 0;
+
+	/* Because we write directly to the reserved memory
+	 * region when loading crash kernels we need a mutex here to
+	 * prevent multiple crash  kernels from attempting to load
+	 * simultaneously, and to prevent a crash kernel from loading
+	 * over the top of a in use crash kernel.
+	 *
+	 * KISS: always take the mutex.
+	 */
+	locked = xchg(&kexec_lock, 1);
+	if (locked)
+		return -EBUSY;
+
+	dest_image = &kexec_image;
+	if (flags & KEXEC_ON_CRASH)
+		dest_image = &kexec_crash_image;
+	if (nr_segments > 0) {
+		unsigned long i;
+
+		/* Loading another kernel to reboot into */
+		if ((flags & KEXEC_ON_CRASH) == 0)
+			result = kimage_normal_alloc(&image, entry,
+							nr_segments, segments);
+		/* Loading another kernel to switch to if this one crashes */
+		else if (flags & KEXEC_ON_CRASH) {
+			/* Free any current crash dump kernel before
+			 * we corrupt it.
+			 */
+			kimage_free(xchg(&kexec_crash_image, NULL));
+			result = kimage_crash_alloc(&image, entry,
+						     nr_segments, segments);
+		}
+		if (result)
+			goto out;
+
+		result = machine_kexec_prepare(image);
+		if (result)
+			goto out;
+
+		for (i = 0; i < nr_segments; i++) {
+			result = kimage_load_segment(image, &image->segment[i]);
+			if (result)
+				goto out;
+		}
+		result = kimage_terminate(image);
+		if (result)
+			goto out;
+	}
+	/* Install the new kernel, and  Uninstall the old */
+	image = xchg(dest_image, image);
+
+out:
+	xchg(&kexec_lock, 0); /* Release the mutex */
+	kimage_free(image);
+
+	return result;
+}
+
+#ifdef CONFIG_COMPAT
+asmlinkage long compat_sys_kexec_load(unsigned long entry,
+				unsigned long nr_segments,
+				struct compat_kexec_segment __user *segments,
+				unsigned long flags)
+{
+	struct compat_kexec_segment in;
+	struct kexec_segment out, __user *ksegments;
+	unsigned long i, result;
+
+	/* Don't allow clients that don't understand the native
+	 * architecture to do anything.
+	 */
+	if ((flags & KEXEC_ARCH_MASK) == KEXEC_ARCH_DEFAULT)
+		return -EINVAL;
+
+	if (nr_segments > KEXEC_SEGMENT_MAX)
+		return -EINVAL;
+
+	ksegments = compat_alloc_user_space(nr_segments * sizeof(out));
+	for (i=0; i < nr_segments; i++) {
+		result = copy_from_user(&in, &segments[i], sizeof(in));
+		if (result)
+			return -EFAULT;
+
+		out.buf   = compat_ptr(in.buf);
+		out.bufsz = in.bufsz;
+		out.mem   = in.mem;
+		out.memsz = in.memsz;
+
+		result = copy_to_user(&ksegments[i], &out, sizeof(out));
+		if (result)
+			return -EFAULT;
+	}
+
+	return sys_kexec_load(entry, nr_segments, ksegments, flags);
+}
+#endif
+
+void crash_kexec(struct pt_regs *regs)
+{
+	struct kimage *image;
+	int locked;
+
+
+	/* Take the kexec_lock here to prevent sys_kexec_load
+	 * running on one cpu from replacing the crash kernel
+	 * we are using after a panic on a different cpu.
+	 *
+	 * If the crash kernel was not located in a fixed area
+	 * of memory the xchg(&kexec_crash_image) would be
+	 * sufficient.  But since I reuse the memory...
+	 */
+	locked = xchg(&kexec_lock, 1);
+	if (!locked) {
+		image = xchg(&kexec_crash_image, NULL);
+		if (image) {
+			machine_crash_shutdown(regs);
+			machine_kexec(image);
+		}
+		xchg(&kexec_lock, 0);
+	}
+}
diff --git a/kernel/kmod.c b/kernel/kmod.c
--- a/kernel/kmod.c
+++ b/kernel/kmod.c
@@ -120,6 +120,7 @@ struct subprocess_info {
 	char *path;
 	char **argv;
 	char **envp;
+	struct key *ring;
 	int wait;
 	int retval;
 };
@@ -130,16 +131,21 @@ struct subprocess_info {
 static int ____call_usermodehelper(void *data)
 {
 	struct subprocess_info *sub_info = data;
+	struct key *old_session;
 	int retval;
 
-	/* Unblock all signals. */
+	/* Unblock all signals and set the session keyring. */
+	key_get(sub_info->ring);
 	flush_signals(current);
 	spin_lock_irq(&current->sighand->siglock);
+	old_session = __install_session_keyring(current, sub_info->ring);
 	flush_signal_handlers(current, 1);
 	sigemptyset(&current->blocked);
 	recalc_sigpending();
 	spin_unlock_irq(&current->sighand->siglock);
 
+	key_put(old_session);
+
 	/* We can run anywhere, unlike our parent keventd(). */
 	set_cpus_allowed(current, CPU_MASK_ALL);
 
@@ -211,10 +217,11 @@ static void __call_usermodehelper(void *
 }
 
 /**
- * call_usermodehelper - start a usermode application
+ * call_usermodehelper_keys - start a usermode application
  * @path: pathname for the application
  * @argv: null-terminated argument list
  * @envp: null-terminated environment list
+ * @session_keyring: session keyring for process (NULL for an empty keyring)
  * @wait: wait for the application to finish and return status.
  *
  * Runs a user-space application.  The application is started
@@ -224,7 +231,8 @@ static void __call_usermodehelper(void *
  * Must be called from process context.  Returns a negative error code
  * if program was not execed successfully, or 0.
  */
-int call_usermodehelper(char *path, char **argv, char **envp, int wait)
+int call_usermodehelper_keys(char *path, char **argv, char **envp,
+			     struct key *session_keyring, int wait)
 {
 	DECLARE_COMPLETION(done);
 	struct subprocess_info sub_info = {
@@ -232,6 +240,7 @@ int call_usermodehelper(char *path, char
 		.path		= path,
 		.argv		= argv,
 		.envp		= envp,
+		.ring		= session_keyring,
 		.wait		= wait,
 		.retval		= 0,
 	};
@@ -247,7 +256,7 @@ int call_usermodehelper(char *path, char
 	wait_for_completion(&done);
 	return sub_info.retval;
 }
-EXPORT_SYMBOL(call_usermodehelper);
+EXPORT_SYMBOL(call_usermodehelper_keys);
 
 void __init usermodehelper_init(void)
 {
diff --git a/kernel/kprobes.c b/kernel/kprobes.c
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -27,12 +27,16 @@
  *		interface to access function arguments.
  * 2004-Sep	Prasanna S Panchamukhi <prasanna@in.ibm.com> Changed Kprobes
  *		exceptions notifier to be first on the priority list.
+ * 2005-May	Hien Nguyen <hien@us.ibm.com>, Jim Keniston
+ *		<jkenisto@us.ibm.com> and Prasanna S Panchamukhi
+ *		<prasanna@in.ibm.com> added function-return probes.
  */
 #include <linux/kprobes.h>
 #include <linux/spinlock.h>
 #include <linux/hash.h>
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/moduleloader.h>
 #include <asm/cacheflush.h>
 #include <asm/errno.h>
 #include <asm/kdebug.h>
@@ -41,11 +45,112 @@
 #define KPROBE_TABLE_SIZE (1 << KPROBE_HASH_BITS)
 
 static struct hlist_head kprobe_table[KPROBE_TABLE_SIZE];
+static struct hlist_head kretprobe_inst_table[KPROBE_TABLE_SIZE];
 
 unsigned int kprobe_cpu = NR_CPUS;
 static DEFINE_SPINLOCK(kprobe_lock);
 static struct kprobe *curr_kprobe;
 
+/*
+ * kprobe->ainsn.insn points to the copy of the instruction to be
+ * single-stepped. x86_64, POWER4 and above have no-exec support and
+ * stepping on the instruction on a vmalloced/kmalloced/data page
+ * is a recipe for disaster
+ */
+#define INSNS_PER_PAGE	(PAGE_SIZE/(MAX_INSN_SIZE * sizeof(kprobe_opcode_t)))
+
+struct kprobe_insn_page {
+	struct hlist_node hlist;
+	kprobe_opcode_t *insns;		/* Page of instruction slots */
+	char slot_used[INSNS_PER_PAGE];
+	int nused;
+};
+
+static struct hlist_head kprobe_insn_pages;
+
+/**
+ * get_insn_slot() - Find a slot on an executable page for an instruction.
+ * We allocate an executable page if there's no room on existing ones.
+ */
+kprobe_opcode_t *get_insn_slot(void)
+{
+	struct kprobe_insn_page *kip;
+	struct hlist_node *pos;
+
+	hlist_for_each(pos, &kprobe_insn_pages) {
+		kip = hlist_entry(pos, struct kprobe_insn_page, hlist);
+		if (kip->nused < INSNS_PER_PAGE) {
+			int i;
+			for (i = 0; i < INSNS_PER_PAGE; i++) {
+				if (!kip->slot_used[i]) {
+					kip->slot_used[i] = 1;
+					kip->nused++;
+					return kip->insns + (i * MAX_INSN_SIZE);
+				}
+			}
+			/* Surprise!  No unused slots.  Fix kip->nused. */
+			kip->nused = INSNS_PER_PAGE;
+		}
+	}
+
+	/* All out of space.  Need to allocate a new page. Use slot 0.*/
+	kip = kmalloc(sizeof(struct kprobe_insn_page), GFP_KERNEL);
+	if (!kip) {
+		return NULL;
+	}
+
+	/*
+	 * Use module_alloc so this page is within +/- 2GB of where the
+	 * kernel image and loaded module images reside. This is required
+	 * so x86_64 can correctly handle the %rip-relative fixups.
+	 */
+	kip->insns = module_alloc(PAGE_SIZE);
+	if (!kip->insns) {
+		kfree(kip);
+		return NULL;
+	}
+	INIT_HLIST_NODE(&kip->hlist);
+	hlist_add_head(&kip->hlist, &kprobe_insn_pages);
+	memset(kip->slot_used, 0, INSNS_PER_PAGE);
+	kip->slot_used[0] = 1;
+	kip->nused = 1;
+	return kip->insns;
+}
+
+void free_insn_slot(kprobe_opcode_t *slot)
+{
+	struct kprobe_insn_page *kip;
+	struct hlist_node *pos;
+
+	hlist_for_each(pos, &kprobe_insn_pages) {
+		kip = hlist_entry(pos, struct kprobe_insn_page, hlist);
+		if (kip->insns <= slot &&
+		    slot < kip->insns + (INSNS_PER_PAGE * MAX_INSN_SIZE)) {
+			int i = (slot - kip->insns) / MAX_INSN_SIZE;
+			kip->slot_used[i] = 0;
+			kip->nused--;
+			if (kip->nused == 0) {
+				/*
+				 * Page is no longer in use.  Free it unless
+				 * it's the last one.  We keep the last one
+				 * so as not to have to set it up again the
+				 * next time somebody inserts a probe.
+				 */
+				hlist_del(&kip->hlist);
+				if (hlist_empty(&kprobe_insn_pages)) {
+					INIT_HLIST_NODE(&kip->hlist);
+					hlist_add_head(&kip->hlist,
+						&kprobe_insn_pages);
+				} else {
+					module_free(NULL, kip->insns);
+					kfree(kip);
+				}
+			}
+			return;
+		}
+	}
+}
+
 /* Locks kprobe: irqs must be disabled */
 void lock_kprobes(void)
 {
@@ -78,22 +183,23 @@ struct kprobe *get_kprobe(void *addr)
  * Aggregate handlers for multiple kprobes support - these handlers
  * take care of invoking the individual kprobe handlers on p->list
  */
-int aggr_pre_handler(struct kprobe *p, struct pt_regs *regs)
+static int aggr_pre_handler(struct kprobe *p, struct pt_regs *regs)
 {
 	struct kprobe *kp;
 
 	list_for_each_entry(kp, &p->list, list) {
 		if (kp->pre_handler) {
 			curr_kprobe = kp;
-			kp->pre_handler(kp, regs);
-			curr_kprobe = NULL;
+			if (kp->pre_handler(kp, regs))
+				return 1;
 		}
+		curr_kprobe = NULL;
 	}
 	return 0;
 }
 
-void aggr_post_handler(struct kprobe *p, struct pt_regs *regs,
-		unsigned long flags)
+static void aggr_post_handler(struct kprobe *p, struct pt_regs *regs,
+			      unsigned long flags)
 {
 	struct kprobe *kp;
 
@@ -107,7 +213,8 @@ void aggr_post_handler(struct kprobe *p,
 	return;
 }
 
-int aggr_fault_handler(struct kprobe *p, struct pt_regs *regs, int trapnr)
+static int aggr_fault_handler(struct kprobe *p, struct pt_regs *regs,
+			      int trapnr)
 {
 	/*
 	 * if we faulted "during" the execution of a user specified
@@ -120,19 +227,159 @@ int aggr_fault_handler(struct kprobe *p,
 	return 0;
 }
 
+static int aggr_break_handler(struct kprobe *p, struct pt_regs *regs)
+{
+	struct kprobe *kp = curr_kprobe;
+	if (curr_kprobe && kp->break_handler) {
+		if (kp->break_handler(kp, regs)) {
+			curr_kprobe = NULL;
+			return 1;
+		}
+	}
+	curr_kprobe = NULL;
+	return 0;
+}
+
+struct kretprobe_instance *get_free_rp_inst(struct kretprobe *rp)
+{
+	struct hlist_node *node;
+	struct kretprobe_instance *ri;
+	hlist_for_each_entry(ri, node, &rp->free_instances, uflist)
+		return ri;
+	return NULL;
+}
+
+static struct kretprobe_instance *get_used_rp_inst(struct kretprobe *rp)
+{
+	struct hlist_node *node;
+	struct kretprobe_instance *ri;
+	hlist_for_each_entry(ri, node, &rp->used_instances, uflist)
+		return ri;
+	return NULL;
+}
+
+void add_rp_inst(struct kretprobe_instance *ri)
+{
+	/*
+	 * Remove rp inst off the free list -
+	 * Add it back when probed function returns
+	 */
+	hlist_del(&ri->uflist);
+
+	/* Add rp inst onto table */
+	INIT_HLIST_NODE(&ri->hlist);
+	hlist_add_head(&ri->hlist,
+			&kretprobe_inst_table[hash_ptr(ri->task, KPROBE_HASH_BITS)]);
+
+	/* Also add this rp inst to the used list. */
+	INIT_HLIST_NODE(&ri->uflist);
+	hlist_add_head(&ri->uflist, &ri->rp->used_instances);
+}
+
+void recycle_rp_inst(struct kretprobe_instance *ri)
+{
+	/* remove rp inst off the rprobe_inst_table */
+	hlist_del(&ri->hlist);
+	if (ri->rp) {
+		/* remove rp inst off the used list */
+		hlist_del(&ri->uflist);
+		/* put rp inst back onto the free list */
+		INIT_HLIST_NODE(&ri->uflist);
+		hlist_add_head(&ri->uflist, &ri->rp->free_instances);
+	} else
+		/* Unregistering */
+		kfree(ri);
+}
+
+struct hlist_head * kretprobe_inst_table_head(struct task_struct *tsk)
+{
+	return &kretprobe_inst_table[hash_ptr(tsk, KPROBE_HASH_BITS)];
+}
+
+/*
+ * This function is called from exit_thread or flush_thread when task tk's
+ * stack is being recycled so that we can recycle any function-return probe
+ * instances associated with this task. These left over instances represent
+ * probed functions that have been called but will never return.
+ */
+void kprobe_flush_task(struct task_struct *tk)
+{
+        struct kretprobe_instance *ri;
+        struct hlist_head *head;
+	struct hlist_node *node, *tmp;
+	unsigned long flags = 0;
+
+	spin_lock_irqsave(&kprobe_lock, flags);
+        head = kretprobe_inst_table_head(current);
+        hlist_for_each_entry_safe(ri, node, tmp, head, hlist) {
+                if (ri->task == tk)
+                        recycle_rp_inst(ri);
+        }
+	spin_unlock_irqrestore(&kprobe_lock, flags);
+}
+
+/*
+ * This kprobe pre_handler is registered with every kretprobe. When probe
+ * hits it will set up the return probe.
+ */
+static int pre_handler_kretprobe(struct kprobe *p, struct pt_regs *regs)
+{
+	struct kretprobe *rp = container_of(p, struct kretprobe, kp);
+
+	/*TODO: consider to only swap the RA after the last pre_handler fired */
+	arch_prepare_kretprobe(rp, regs);
+	return 0;
+}
+
+static inline void free_rp_inst(struct kretprobe *rp)
+{
+	struct kretprobe_instance *ri;
+	while ((ri = get_free_rp_inst(rp)) != NULL) {
+		hlist_del(&ri->uflist);
+		kfree(ri);
+	}
+}
+
+/*
+ * Keep all fields in the kprobe consistent
+ */
+static inline void copy_kprobe(struct kprobe *old_p, struct kprobe *p)
+{
+	memcpy(&p->opcode, &old_p->opcode, sizeof(kprobe_opcode_t));
+	memcpy(&p->ainsn, &old_p->ainsn, sizeof(struct arch_specific_insn));
+}
+
+/*
+* Add the new probe to old_p->list. Fail if this is the
+* second jprobe at the address - two jprobes can't coexist
+*/
+static int add_new_kprobe(struct kprobe *old_p, struct kprobe *p)
+{
+        struct kprobe *kp;
+
+	if (p->break_handler) {
+		list_for_each_entry(kp, &old_p->list, list) {
+			if (kp->break_handler)
+				return -EEXIST;
+		}
+		list_add_tail(&p->list, &old_p->list);
+	} else
+		list_add(&p->list, &old_p->list);
+	return 0;
+}
+
 /*
  * Fill in the required fields of the "manager kprobe". Replace the
  * earlier kprobe in the hlist with the manager kprobe
  */
 static inline void add_aggr_kprobe(struct kprobe *ap, struct kprobe *p)
 {
+	copy_kprobe(p, ap);
 	ap->addr = p->addr;
-	ap->opcode = p->opcode;
-	memcpy(&ap->ainsn, &p->ainsn, sizeof(struct arch_specific_insn));
-
 	ap->pre_handler = aggr_pre_handler;
 	ap->post_handler = aggr_post_handler;
 	ap->fault_handler = aggr_fault_handler;
+	ap->break_handler = aggr_break_handler;
 
 	INIT_LIST_HEAD(&ap->list);
 	list_add(&p->list, &ap->list);
@@ -153,16 +400,16 @@ static int register_aggr_kprobe(struct k
 	int ret = 0;
 	struct kprobe *ap;
 
-	if (old_p->break_handler || p->break_handler) {
-		ret = -EEXIST;	/* kprobe and jprobe can't (yet) coexist */
-	} else if (old_p->pre_handler == aggr_pre_handler) {
-		list_add(&p->list, &old_p->list);
+	if (old_p->pre_handler == aggr_pre_handler) {
+		copy_kprobe(old_p, p);
+		ret = add_new_kprobe(old_p, p);
 	} else {
 		ap = kcalloc(1, sizeof(struct kprobe), GFP_ATOMIC);
 		if (!ap)
 			return -ENOMEM;
 		add_aggr_kprobe(ap, old_p);
-		list_add(&p->list, &ap->list);
+		copy_kprobe(ap, p);
+		ret = add_new_kprobe(ap, p);
 	}
 	return ret;
 }
@@ -170,10 +417,8 @@ static int register_aggr_kprobe(struct k
 /* kprobe removal house-keeping routines */
 static inline void cleanup_kprobe(struct kprobe *p, unsigned long flags)
 {
-	*p->addr = p->opcode;
+	arch_disarm_kprobe(p);
 	hlist_del(&p->hlist);
-	flush_icache_range((unsigned long) p->addr,
-		   (unsigned long) p->addr + sizeof(kprobe_opcode_t));
 	spin_unlock_irqrestore(&kprobe_lock, flags);
 	arch_remove_kprobe(p);
 }
@@ -200,6 +445,7 @@ int register_kprobe(struct kprobe *p)
 	}
 	spin_lock_irqsave(&kprobe_lock, flags);
 	old_p = get_kprobe(p->addr);
+	p->nmissed = 0;
 	if (old_p) {
 		ret = register_aggr_kprobe(old_p, p);
 		goto out;
@@ -210,10 +456,8 @@ int register_kprobe(struct kprobe *p)
 	hlist_add_head(&p->hlist,
 		       &kprobe_table[hash_ptr(p->addr, KPROBE_HASH_BITS)]);
 
-	p->opcode = *p->addr;
-	*p->addr = BREAKPOINT_INSTRUCTION;
-	flush_icache_range((unsigned long) p->addr,
-			   (unsigned long) p->addr + sizeof(kprobe_opcode_t));
+  	arch_arm_kprobe(p);
+
 out:
 	spin_unlock_irqrestore(&kprobe_lock, flags);
 rm_kprobe:
@@ -257,16 +501,83 @@ void unregister_jprobe(struct jprobe *jp
 	unregister_kprobe(&jp->kp);
 }
 
+#ifdef ARCH_SUPPORTS_KRETPROBES
+
+int register_kretprobe(struct kretprobe *rp)
+{
+	int ret = 0;
+	struct kretprobe_instance *inst;
+	int i;
+
+	rp->kp.pre_handler = pre_handler_kretprobe;
+
+	/* Pre-allocate memory for max kretprobe instances */
+	if (rp->maxactive <= 0) {
+#ifdef CONFIG_PREEMPT
+		rp->maxactive = max(10, 2 * NR_CPUS);
+#else
+		rp->maxactive = NR_CPUS;
+#endif
+	}
+	INIT_HLIST_HEAD(&rp->used_instances);
+	INIT_HLIST_HEAD(&rp->free_instances);
+	for (i = 0; i < rp->maxactive; i++) {
+		inst = kmalloc(sizeof(struct kretprobe_instance), GFP_KERNEL);
+		if (inst == NULL) {
+			free_rp_inst(rp);
+			return -ENOMEM;
+		}
+		INIT_HLIST_NODE(&inst->uflist);
+		hlist_add_head(&inst->uflist, &rp->free_instances);
+	}
+
+	rp->nmissed = 0;
+	/* Establish function entry probe point */
+	if ((ret = register_kprobe(&rp->kp)) != 0)
+		free_rp_inst(rp);
+	return ret;
+}
+
+#else /* ARCH_SUPPORTS_KRETPROBES */
+
+int register_kretprobe(struct kretprobe *rp)
+{
+	return -ENOSYS;
+}
+
+#endif /* ARCH_SUPPORTS_KRETPROBES */
+
+void unregister_kretprobe(struct kretprobe *rp)
+{
+	unsigned long flags;
+	struct kretprobe_instance *ri;
+
+	unregister_kprobe(&rp->kp);
+	/* No race here */
+	spin_lock_irqsave(&kprobe_lock, flags);
+	free_rp_inst(rp);
+	while ((ri = get_used_rp_inst(rp)) != NULL) {
+		ri->rp = NULL;
+		hlist_del(&ri->uflist);
+	}
+	spin_unlock_irqrestore(&kprobe_lock, flags);
+}
+
 static int __init init_kprobes(void)
 {
 	int i, err = 0;
 
 	/* FIXME allocate the probe table, currently defined statically */
 	/* initialize all list heads */
-	for (i = 0; i < KPROBE_TABLE_SIZE; i++)
+	for (i = 0; i < KPROBE_TABLE_SIZE; i++) {
 		INIT_HLIST_HEAD(&kprobe_table[i]);
+		INIT_HLIST_HEAD(&kretprobe_inst_table[i]);
+	}
+
+	err = arch_init_kprobes();
+	if (!err)
+		err = register_die_notifier(&kprobe_exceptions_nb);
 
-	err = register_die_notifier(&kprobe_exceptions_nb);
 	return err;
 }
 
@@ -277,3 +588,6 @@ EXPORT_SYMBOL_GPL(unregister_kprobe);
 EXPORT_SYMBOL_GPL(register_jprobe);
 EXPORT_SYMBOL_GPL(unregister_jprobe);
 EXPORT_SYMBOL_GPL(jprobe_return);
+EXPORT_SYMBOL_GPL(register_kretprobe);
+EXPORT_SYMBOL_GPL(unregister_kretprobe);
+
diff --git a/kernel/ksysfs.c b/kernel/ksysfs.c
--- a/kernel/ksysfs.c
+++ b/kernel/ksysfs.c
@@ -30,6 +30,16 @@ static ssize_t hotplug_seqnum_show(struc
 KERNEL_ATTR_RO(hotplug_seqnum);
 #endif
 
+#ifdef CONFIG_KEXEC
+#include <asm/kexec.h>
+
+static ssize_t crash_notes_show(struct subsystem *subsys, char *page)
+{
+	return sprintf(page, "%p\n", (void *)crash_notes);
+}
+KERNEL_ATTR_RO(crash_notes);
+#endif
+
 decl_subsys(kernel, NULL, NULL);
 EXPORT_SYMBOL_GPL(kernel_subsys);
 
@@ -37,6 +47,9 @@ static struct attribute * kernel_attrs[]
 #ifdef CONFIG_HOTPLUG
 	&hotplug_seqnum_attr.attr,
 #endif
+#ifdef CONFIG_KEXEC
+	&crash_notes_attr.attr,
+#endif
 	NULL
 };
 
diff --git a/kernel/module.c b/kernel/module.c
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -35,6 +35,7 @@
 #include <linux/notifier.h>
 #include <linux/stop_machine.h>
 #include <linux/device.h>
+#include <linux/string.h>
 #include <asm/uaccess.h>
 #include <asm/semaphore.h>
 #include <asm/cacheflush.h>
@@ -249,13 +250,18 @@ static inline unsigned int block_size(in
 /* Created by linker magic */
 extern char __per_cpu_start[], __per_cpu_end[];
 
-static void *percpu_modalloc(unsigned long size, unsigned long align)
+static void *percpu_modalloc(unsigned long size, unsigned long align,
+			     const char *name)
 {
 	unsigned long extra;
 	unsigned int i;
 	void *ptr;
 
-	BUG_ON(align > SMP_CACHE_BYTES);
+	if (align > SMP_CACHE_BYTES) {
+		printk(KERN_WARNING "%s: per-cpu alignment %li > %i\n",
+		       name, align, SMP_CACHE_BYTES);
+		align = SMP_CACHE_BYTES;
+	}
 
 	ptr = __per_cpu_start;
 	for (i = 0; i < pcpu_num_used; ptr += block_size(pcpu_size[i]), i++) {
@@ -347,7 +353,8 @@ static int percpu_modinit(void)
 }	
 __initcall(percpu_modinit);
 #else /* ... !CONFIG_SMP */
-static inline void *percpu_modalloc(unsigned long size, unsigned long align)
+static inline void *percpu_modalloc(unsigned long size, unsigned long align,
+				    const char *name)
 {
 	return NULL;
 }
@@ -370,6 +377,43 @@ static inline void percpu_modcopy(void *
 #endif /* CONFIG_SMP */
 
 #ifdef CONFIG_MODULE_UNLOAD
+#define MODINFO_ATTR(field)	\
+static void setup_modinfo_##field(struct module *mod, const char *s)  \
+{                                                                     \
+	mod->field = kstrdup(s, GFP_KERNEL);                          \
+}                                                                     \
+static ssize_t show_modinfo_##field(struct module_attribute *mattr,   \
+	                struct module *mod, char *buffer)             \
+{                                                                     \
+	return sprintf(buffer, "%s\n", mod->field);                   \
+}                                                                     \
+static int modinfo_##field##_exists(struct module *mod)               \
+{                                                                     \
+	return mod->field != NULL;                                    \
+}                                                                     \
+static void free_modinfo_##field(struct module *mod)                  \
+{                                                                     \
+        kfree(mod->field);                                            \
+        mod->field = NULL;                                            \
+}                                                                     \
+static struct module_attribute modinfo_##field = {                    \
+	.attr = { .name = __stringify(field), .mode = 0444,           \
+		  .owner = THIS_MODULE },                             \
+	.show = show_modinfo_##field,                                 \
+	.setup = setup_modinfo_##field,                               \
+	.test = modinfo_##field##_exists,                             \
+	.free = free_modinfo_##field,                                 \
+};
+
+MODINFO_ATTR(version);
+MODINFO_ATTR(srcversion);
+
+static struct module_attribute *modinfo_attrs[] = {
+	&modinfo_version,
+	&modinfo_srcversion,
+	NULL,
+};
+
 /* Init the unload section of the module. */
 static void module_unload_init(struct module *mod)
 {
@@ -379,7 +423,7 @@ static void module_unload_init(struct mo
 	for (i = 0; i < NR_CPUS; i++)
 		local_set(&mod->ref[i].count, 0);
 	/* Hold reference count during initialization. */
-	local_set(&mod->ref[_smp_processor_id()].count, 1);
+	local_set(&mod->ref[raw_smp_processor_id()].count, 1);
 	/* Backwards compatibility macros put refcount during init. */
 	mod->waiter = current;
 }
@@ -692,7 +736,7 @@ static int obsparm_copy_string(const cha
 	return 0;
 }
 
-int set_obsolete(const char *val, struct kernel_param *kp)
+static int set_obsolete(const char *val, struct kernel_param *kp)
 {
 	unsigned int min, max;
 	unsigned int size, maxsize;
@@ -1031,6 +1075,32 @@ static void module_remove_refcnt_attr(st
 }
 #endif
 
+#ifdef CONFIG_MODULE_UNLOAD
+static int module_add_modinfo_attrs(struct module *mod)
+{
+	struct module_attribute *attr;
+	int error = 0;
+	int i;
+
+	for (i = 0; (attr = modinfo_attrs[i]) && !error; i++) {
+		if (!attr->test ||
+		    (attr->test && attr->test(mod)))
+			error = sysfs_create_file(&mod->mkobj.kobj,&attr->attr);
+	}
+	return error;
+}
+
+static void module_remove_modinfo_attrs(struct module *mod)
+{
+	struct module_attribute *attr;
+	int i;
+
+	for (i = 0; (attr = modinfo_attrs[i]); i++) {
+		sysfs_remove_file(&mod->mkobj.kobj,&attr->attr);
+		attr->free(mod);
+	}
+}
+#endif
 
 static int mod_sysfs_setup(struct module *mod,
 			   struct kernel_param *kparam,
@@ -1056,6 +1126,12 @@ static int mod_sysfs_setup(struct module
 	if (err)
 		goto out_unreg;
 
+#ifdef CONFIG_MODULE_UNLOAD
+	err = module_add_modinfo_attrs(mod);
+	if (err)
+		goto out_unreg;
+#endif
+
 	return 0;
 
 out_unreg:
@@ -1066,6 +1142,9 @@ out:
 
 static void mod_kobject_remove(struct module *mod)
 {
+#ifdef CONFIG_MODULE_UNLOAD
+	module_remove_modinfo_attrs(mod);
+#endif
 	module_remove_refcnt_attr(mod);
 	module_param_sysfs_remove(mod);
 
@@ -1311,6 +1390,23 @@ static char *get_modinfo(Elf_Shdr *sechd
 	return NULL;
 }
 
+#ifdef CONFIG_MODULE_UNLOAD
+static void setup_modinfo(struct module *mod, Elf_Shdr *sechdrs,
+			  unsigned int infoindex)
+{
+	struct module_attribute *attr;
+	int i;
+
+	for (i = 0; (attr = modinfo_attrs[i]); i++) {
+		if (attr->setup)
+			attr->setup(mod,
+				    get_modinfo(sechdrs,
+						infoindex,
+						attr->attr.name));
+	}
+}
+#endif
+
 #ifdef CONFIG_KALLSYMS
 int is_exported(const char *name, const struct module *mod)
 {
@@ -1554,7 +1650,8 @@ static struct module *load_module(void _
 	if (pcpuindex) {
 		/* We have a special allocation for this section. */
 		percpu = percpu_modalloc(sechdrs[pcpuindex].sh_size,
-					 sechdrs[pcpuindex].sh_addralign);
+					 sechdrs[pcpuindex].sh_addralign,
+					 mod->name);
 		if (!percpu) {
 			err = -ENOMEM;
 			goto free_mod;
@@ -1615,6 +1712,11 @@ static struct module *load_module(void _
 	/* Set up license info based on the info section */
 	set_license(mod, get_modinfo(sechdrs, infoindex, "license"));
 
+#ifdef CONFIG_MODULE_UNLOAD
+	/* Set up MODINFO_ATTR fields */
+	setup_modinfo(mod, sechdrs, infoindex);
+#endif
+
 	/* Fix up syms, so that st_value is a pointer to location. */
 	err = simplify_symbols(sechdrs, symindex, strtab, versindex, pcpuindex,
 			       mod);
diff --git a/kernel/panic.c b/kernel/panic.c
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -18,6 +18,7 @@
 #include <linux/sysrq.h>
 #include <linux/interrupt.h>
 #include <linux/nmi.h>
+#include <linux/kexec.h>
 
 int panic_timeout;
 int panic_on_oops;
@@ -63,6 +64,13 @@ NORET_TYPE void panic(const char * fmt, 
         unsigned long caller = (unsigned long) __builtin_return_address(0);
 #endif
 
+	/*
+	 * It's possible to come here directly from a panic-assertion and not
+	 * have preempt disabled. Some functions called from here want
+	 * preempt to be disabled. No point enabling it later though...
+	 */
+	preempt_disable();
+
 	bust_spinlocks(1);
 	va_start(args, fmt);
 	vsnprintf(buf, sizeof(buf), fmt, args);
@@ -70,7 +78,19 @@ NORET_TYPE void panic(const char * fmt, 
 	printk(KERN_EMERG "Kernel panic - not syncing: %s\n",buf);
 	bust_spinlocks(0);
 
+	/*
+	 * If we have crashed and we have a crash kernel loaded let it handle
+	 * everything else.
+	 * Do we want to call this before we try to display a message?
+	 */
+	crash_kexec(NULL);
+
 #ifdef CONFIG_SMP
+	/*
+	 * Note smp_send_stop is the usual smp shutdown function, which
+	 * unfortunately means it may not be hardened to work in a panic
+	 * situation.
+	 */
 	smp_send_stop();
 #endif
 
@@ -79,8 +99,7 @@ NORET_TYPE void panic(const char * fmt, 
 	if (!panic_blink)
 		panic_blink = no_blink;
 
-	if (panic_timeout > 0)
-	{
+	if (panic_timeout > 0) {
 		/*
 	 	 * Delay timeout seconds before rebooting the machine. 
 		 * We can't use the "normal" timers since we just panicked..
@@ -92,12 +111,11 @@ NORET_TYPE void panic(const char * fmt, 
 			mdelay(1);
 			i++;
 		}
-		/*
-		 *	Should we run the reboot notifier. For the moment Im
-		 *	choosing not too. It might crash, be corrupt or do
-		 *	more harm than good for other reasons.
+		/*	This will not be a clean reboot, with everything
+		 *	shutting down.  But if there is a chance of
+		 *	rebooting the system it will be rebooted.
 		 */
-		machine_restart(NULL);
+		emergency_restart();
 	}
 #ifdef __sparc__
 	{
diff --git a/kernel/params.c b/kernel/params.c
--- a/kernel/params.c
+++ b/kernel/params.c
@@ -629,7 +629,7 @@ static ssize_t module_attr_show(struct k
 	mk = to_module_kobject(kobj);
 
 	if (!attribute->show)
-		return -EPERM;
+		return -EIO;
 
 	if (!try_module_get(mk->mod))
 		return -ENODEV;
@@ -653,7 +653,7 @@ static ssize_t module_attr_store(struct 
 	mk = to_module_kobject(kobj);
 
 	if (!attribute->store)
-		return -EPERM;
+		return -EIO;
 
 	if (!try_module_get(mk->mod))
 		return -ENODEV;
diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c
--- a/kernel/posix-timers.c
+++ b/kernel/posix-timers.c
@@ -89,23 +89,6 @@ static struct idr posix_timers_id;
 static DEFINE_SPINLOCK(idr_lock);
 
 /*
- * Just because the timer is not in the timer list does NOT mean it is
- * inactive.  It could be in the "fire" routine getting a new expire time.
- */
-#define TIMER_INACTIVE 1
-
-#ifdef CONFIG_SMP
-# define timer_active(tmr) \
-		((tmr)->it.real.timer.entry.prev != (void *)TIMER_INACTIVE)
-# define set_timer_inactive(tmr) \
-		do { \
-			(tmr)->it.real.timer.entry.prev = (void *)TIMER_INACTIVE; \
-		} while (0)
-#else
-# define timer_active(tmr) BARFY	// error to use outside of SMP
-# define set_timer_inactive(tmr) do { } while (0)
-#endif
-/*
  * we assume that the new SIGEV_THREAD_ID shares no bits with the other
  * SIGEV values.  Here we put out an error if this assumption fails.
  */
@@ -226,7 +209,6 @@ static inline int common_timer_create(st
 	init_timer(&new_timer->it.real.timer);
 	new_timer->it.real.timer.data = (unsigned long) new_timer;
 	new_timer->it.real.timer.function = posix_timer_fn;
-	set_timer_inactive(new_timer);
 	return 0;
 }
 
@@ -480,7 +462,6 @@ static void posix_timer_fn(unsigned long
 	int do_notify = 1;
 
 	spin_lock_irqsave(&timr->it_lock, flags);
- 	set_timer_inactive(timr);
 	if (!list_empty(&timr->it.real.abs_timer_entry)) {
 		spin_lock(&abs_list.lock);
 		do {
@@ -915,21 +896,10 @@ static int adjust_abs_time(struct k_cloc
 			jiffies_64_f = get_jiffies_64();
 		}
 		/*
-		 * Take away now to get delta
-		 */
-		oc.tv_sec -= now.tv_sec;
-		oc.tv_nsec -= now.tv_nsec;
-		/*
-		 * Normalize...
+		 * Take away now to get delta and normalize
 		 */
-		while ((oc.tv_nsec - NSEC_PER_SEC) >= 0) {
-			oc.tv_nsec -= NSEC_PER_SEC;
-			oc.tv_sec++;
-		}
-		while ((oc.tv_nsec) < 0) {
-			oc.tv_nsec += NSEC_PER_SEC;
-			oc.tv_sec--;
-		}
+		set_normalized_timespec(&oc, oc.tv_sec - now.tv_sec,
+					oc.tv_nsec - now.tv_nsec);
 	}else{
 		jiffies_64_f = get_jiffies_64();
 	}
@@ -983,8 +953,8 @@ common_timer_set(struct k_itimer *timr, 
 	 * careful here.  If smp we could be in the "fire" routine which will
 	 * be spinning as we hold the lock.  But this is ONLY an SMP issue.
 	 */
+	if (try_to_del_timer_sync(&timr->it.real.timer) < 0) {
 #ifdef CONFIG_SMP
-	if (timer_active(timr) && !del_timer(&timr->it.real.timer))
 		/*
 		 * It can only be active if on an other cpu.  Since
 		 * we have cleared the interval stuff above, it should
@@ -994,11 +964,9 @@ common_timer_set(struct k_itimer *timr, 
 		 * a "retry" exit status.
 		 */
 		return TIMER_RETRY;
-
-	set_timer_inactive(timr);
-#else
-	del_timer(&timr->it.real.timer);
 #endif
+	}
+
 	remove_from_abslist(timr);
 
 	timr->it_requeue_pending = (timr->it_requeue_pending + 2) & 
@@ -1083,8 +1051,9 @@ retry:
 static inline int common_timer_del(struct k_itimer *timer)
 {
 	timer->it.real.incr = 0;
+
+	if (try_to_del_timer_sync(&timer->it.real.timer) < 0) {
 #ifdef CONFIG_SMP
-	if (timer_active(timer) && !del_timer(&timer->it.real.timer))
 		/*
 		 * It can only be active if on an other cpu.  Since
 		 * we have cleared the interval stuff above, it should
@@ -1094,9 +1063,9 @@ static inline int common_timer_del(struc
 		 * a "retry" exit status.
 		 */
 		return TIMER_RETRY;
-#else
-	del_timer(&timer->it.real.timer);
 #endif
+	}
+
 	remove_from_abslist(timer);
 
 	return 0;
@@ -1197,7 +1166,6 @@ void exit_itimers(struct signal_struct *
 		tmr = list_entry(sig->posix_timers.next, struct k_itimer, list);
 		itimer_delete(tmr);
 	}
-	del_timer_sync(&sig->real_timer);
 }
 
 /*
diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig
--- a/kernel/power/Kconfig
+++ b/kernel/power/Kconfig
@@ -27,8 +27,8 @@ config PM_DEBUG
 	like suspend support.
 
 config SOFTWARE_SUSPEND
-	bool "Software Suspend (EXPERIMENTAL)"
-	depends on EXPERIMENTAL && PM && SWAP
+	bool "Software Suspend"
+	depends on EXPERIMENTAL && PM && SWAP && ((X86 && SMP) || ((FVR || PPC32 || X86) && !SMP))
 	---help---
 	  Enable the possibility of suspending the machine.
 	  It doesn't need APM.
@@ -72,3 +72,7 @@ config PM_STD_PARTITION
 	  suspended image to. It will simply pick the first available swap 
 	  device.
 
+config SUSPEND_SMP
+	bool
+	depends on HOTPLUG_CPU && X86 && PM
+	default y
diff --git a/kernel/power/Makefile b/kernel/power/Makefile
--- a/kernel/power/Makefile
+++ b/kernel/power/Makefile
@@ -3,9 +3,9 @@ ifeq ($(CONFIG_PM_DEBUG),y)
 EXTRA_CFLAGS	+=	-DDEBUG
 endif
 
-swsusp-smp-$(CONFIG_SMP)	+= smp.o
-
 obj-y				:= main.o process.o console.o pm.o
-obj-$(CONFIG_SOFTWARE_SUSPEND)	+= swsusp.o $(swsusp-smp-y) disk.o
+obj-$(CONFIG_SOFTWARE_SUSPEND)	+= swsusp.o disk.o
+
+obj-$(CONFIG_SUSPEND_SMP)	+= smp.o
 
 obj-$(CONFIG_MAGIC_SYSRQ)	+= poweroff.o
diff --git a/kernel/power/disk.c b/kernel/power/disk.c
--- a/kernel/power/disk.c
+++ b/kernel/power/disk.c
@@ -16,6 +16,8 @@
 #include <linux/device.h>
 #include <linux/delay.h>
 #include <linux/fs.h>
+#include <linux/mount.h>
+
 #include "power.h"
 
 
@@ -57,16 +59,13 @@ static void power_down(suspend_disk_meth
 		error = pm_ops->enter(PM_SUSPEND_DISK);
 		break;
 	case PM_DISK_SHUTDOWN:
-		printk("Powering off system\n");
-		device_shutdown();
-		machine_power_off();
+		kernel_power_off();
 		break;
 	case PM_DISK_REBOOT:
-		device_shutdown();
-		machine_restart(NULL);
+		kernel_restart(NULL);
 		break;
 	}
-	machine_halt();
+	kernel_halt();
 	/* Valid image is on the disk, if we continue we risk serious data corruption
 	   after resume. */
 	printk(KERN_CRIT "Please power me down manually\n");
@@ -117,8 +116,8 @@ static void finish(void)
 {
 	device_resume();
 	platform_finish();
-	enable_nonboot_cpus();
 	thaw_processes();
+	enable_nonboot_cpus();
 	pm_restore_console();
 }
 
@@ -131,28 +130,35 @@ static int prepare_processes(void)
 
 	sys_sync();
 
+	disable_nonboot_cpus();
+
 	if (freeze_processes()) {
 		error = -EBUSY;
-		return error;
+		goto thaw;
 	}
 
 	if (pm_disk_mode == PM_DISK_PLATFORM) {
 		if (pm_ops && pm_ops->prepare) {
 			if ((error = pm_ops->prepare(PM_SUSPEND_DISK)))
-				return error;
+				goto thaw;
 		}
 	}
 
 	/* Free memory before shutting down devices. */
 	free_some_memory();
-
 	return 0;
+thaw:
+	thaw_processes();
+	enable_nonboot_cpus();
+	pm_restore_console();
+	return error;
 }
 
 static void unprepare_processes(void)
 {
-	enable_nonboot_cpus();
+	platform_finish();
 	thaw_processes();
+	enable_nonboot_cpus();
 	pm_restore_console();
 }
 
@@ -160,15 +166,9 @@ static int prepare_devices(void)
 {
 	int error;
 
-	disable_nonboot_cpus();
-	if ((error = device_suspend(PMSG_FREEZE))) {
+	if ((error = device_suspend(PMSG_FREEZE)))
 		printk("Some devices failed to suspend\n");
-		platform_finish();
-		enable_nonboot_cpus();
-		return error;
-	}
-
-	return 0;
+	return error;
 }
 
 /**
@@ -185,9 +185,9 @@ int pm_suspend_disk(void)
 	int error;
 
 	error = prepare_processes();
-	if (!error) {
-		error = prepare_devices();
-	}
+	if (error)
+		return error;
+	error = prepare_devices();
 
 	if (error) {
 		unprepare_processes();
@@ -233,6 +233,16 @@ static int software_resume(void)
 {
 	int error;
 
+	if (!swsusp_resume_device) {
+		if (!strlen(resume_file))
+			return -ENOENT;
+		swsusp_resume_device = name_to_dev_t(resume_file);
+		pr_debug("swsusp: Resume From Partition %s\n", resume_file);
+	} else {
+		pr_debug("swsusp: Resume From Partition %d:%d\n",
+			 MAJOR(swsusp_resume_device), MINOR(swsusp_resume_device));
+	}
+
 	if (noresume) {
 		/**
 		 * FIXME: If noresume is specified, we need to find the partition
@@ -250,7 +260,7 @@ static int software_resume(void)
 
 	if ((error = prepare_processes())) {
 		swsusp_close();
-		goto Cleanup;
+		goto Done;
 	}
 
 	pr_debug("PM: Reading swsusp image.\n");
diff --git a/kernel/power/main.c b/kernel/power/main.c
--- a/kernel/power/main.c
+++ b/kernel/power/main.c
@@ -19,6 +19,9 @@
 
 #include "power.h"
 
+/*This is just an arbitrary number */
+#define FREE_PAGE_NUMBER (100)
+
 DECLARE_MUTEX(pm_sem);
 
 struct pm_ops * pm_ops = NULL;
@@ -49,17 +52,35 @@ void pm_set_ops(struct pm_ops * ops)
 static int suspend_prepare(suspend_state_t state)
 {
 	int error = 0;
+	unsigned int free_pages;
 
 	if (!pm_ops || !pm_ops->enter)
 		return -EPERM;
 
 	pm_prepare_console();
 
+	disable_nonboot_cpus();
+
+	if (num_online_cpus() != 1) {
+		error = -EPERM;
+		goto Enable_cpu;
+	}
+
 	if (freeze_processes()) {
 		error = -EAGAIN;
 		goto Thaw;
 	}
 
+	if ((free_pages = nr_free_pages()) < FREE_PAGE_NUMBER) {
+		pr_debug("PM: free some memory\n");
+		shrink_all_memory(FREE_PAGE_NUMBER - free_pages);
+		if (nr_free_pages() < FREE_PAGE_NUMBER) {
+			error = -ENOMEM;
+			printk(KERN_ERR "PM: No enough memory\n");
+			goto Thaw;
+		}
+	}
+
 	if (pm_ops->prepare) {
 		if ((error = pm_ops->prepare(state)))
 			goto Thaw;
@@ -75,6 +96,8 @@ static int suspend_prepare(suspend_state
 		pm_ops->finish(state);
  Thaw:
 	thaw_processes();
+ Enable_cpu:
+	enable_nonboot_cpus();
 	pm_restore_console();
 	return error;
 }
@@ -113,6 +136,7 @@ static void suspend_finish(suspend_state
 	if (pm_ops && pm_ops->finish)
 		pm_ops->finish(state);
 	thaw_processes();
+	enable_nonboot_cpus();
 	pm_restore_console();
 }
 
@@ -150,12 +174,6 @@ static int enter_state(suspend_state_t s
 		goto Unlock;
 	}
 
-	/* Suspend is hard to get right on SMP. */
-	if (num_online_cpus() != 1) {
-		error = -EPERM;
-		goto Unlock;
-	}
-
 	pr_debug("PM: Preparing system for %s sleep\n", pm_states[state]);
 	if ((error = suspend_prepare(state)))
 		goto Unlock;
@@ -190,7 +208,7 @@ int software_suspend(void)
 
 int pm_suspend(suspend_state_t state)
 {
-	if (state > PM_SUSPEND_ON && state < PM_SUSPEND_MAX)
+	if (state > PM_SUSPEND_ON && state <= PM_SUSPEND_MAX)
 		return enter_state(state);
 	return -EINVAL;
 }
diff --git a/kernel/power/poweroff.c b/kernel/power/poweroff.c
--- a/kernel/power/poweroff.c
+++ b/kernel/power/poweroff.c
@@ -9,6 +9,7 @@
 #include <linux/init.h>
 #include <linux/pm.h>
 #include <linux/workqueue.h>
+#include <linux/reboot.h>
 
 /*
  * When the user hits Sys-Rq o to power down the machine this is the
@@ -17,8 +18,7 @@
 
 static void do_poweroff(void *dummy)
 {
-	if (pm_power_off)
-		pm_power_off();
+	kernel_power_off();
 }
 
 static DECLARE_WORK(poweroff_work, do_poweroff, NULL);
diff --git a/kernel/power/process.c b/kernel/power/process.c
--- a/kernel/power/process.c
+++ b/kernel/power/process.c
@@ -32,7 +32,7 @@ static inline int freezeable(struct task
 }
 
 /* Refrigerator is place where frozen processes are stored :-). */
-void refrigerator(unsigned long flag)
+void refrigerator(void)
 {
 	/* Hmm, should we be allowed to suspend when there are realtime
 	   processes around? */
@@ -41,14 +41,13 @@ void refrigerator(unsigned long flag)
 	current->state = TASK_UNINTERRUPTIBLE;
 	pr_debug("%s entered refrigerator\n", current->comm);
 	printk("=");
-	current->flags &= ~PF_FREEZE;
 
+	frozen_process(current);
 	spin_lock_irq(&current->sighand->siglock);
 	recalc_sigpending(); /* We sent fake signal, clean it up */
 	spin_unlock_irq(&current->sighand->siglock);
 
-	current->flags |= PF_FROZEN;
-	while (current->flags & PF_FROZEN)
+	while (frozen(current))
 		schedule();
 	pr_debug("%s left refrigerator\n", current->comm);
 	current->state = save;
@@ -57,27 +56,23 @@ void refrigerator(unsigned long flag)
 /* 0 = success, else # of processes that we failed to stop */
 int freeze_processes(void)
 {
-       int todo;
-       unsigned long start_time;
+	int todo;
+	unsigned long start_time;
 	struct task_struct *g, *p;
-	
+	unsigned long flags;
+
 	printk( "Stopping tasks: " );
 	start_time = jiffies;
 	do {
 		todo = 0;
 		read_lock(&tasklist_lock);
 		do_each_thread(g, p) {
-			unsigned long flags;
 			if (!freezeable(p))
 				continue;
-			if ((p->flags & PF_FROZEN) ||
-			    (p->state == TASK_TRACED) ||
-			    (p->state == TASK_STOPPED))
+			if (frozen(p))
 				continue;
 
-			/* FIXME: smp problem here: we may not access other process' flags
-			   without locking */
-			p->flags |= PF_FREEZE;
+			freeze(p);
 			spin_lock_irqsave(&p->sighand->siglock, flags);
 			signal_wake_up(p, 0);
 			spin_unlock_irqrestore(&p->sighand->siglock, flags);
@@ -91,7 +86,7 @@ int freeze_processes(void)
 			return todo;
 		}
 	} while(todo);
-	
+
 	printk( "|\n" );
 	BUG_ON(in_atomic());
 	return 0;
@@ -106,10 +101,7 @@ void thaw_processes(void)
 	do_each_thread(g, p) {
 		if (!freezeable(p))
 			continue;
-		if (p->flags & PF_FROZEN) {
-			p->flags &= ~PF_FROZEN;
-			wake_up_process(p);
-		} else
+		if (!thaw_process(p))
 			printk(KERN_INFO " Strange, %s not stopped\n", p->comm );
 	} while_each_thread(g, p);
 
diff --git a/kernel/power/smp.c b/kernel/power/smp.c
--- a/kernel/power/smp.c
+++ b/kernel/power/smp.c
@@ -13,73 +13,52 @@
 #include <linux/interrupt.h>
 #include <linux/suspend.h>
 #include <linux/module.h>
+#include <linux/cpu.h>
 #include <asm/atomic.h>
 #include <asm/tlbflush.h>
 
-static atomic_t cpu_counter, freeze;
-
-
-static void smp_pause(void * data)
-{
-	struct saved_context ctxt;
-	__save_processor_state(&ctxt);
-	printk("Sleeping in:\n");
-	dump_stack();
-	atomic_inc(&cpu_counter);
-	while (atomic_read(&freeze)) {
-		/* FIXME: restore takes place at random piece inside this.
-		   This should probably be written in assembly, and
-		   preserve general-purpose registers, too
-
-		   What about stack? We may need to move to new stack here.
-
-		   This should better be ran with interrupts disabled.
-		 */
-		cpu_relax();
-		barrier();
-	}
-	atomic_dec(&cpu_counter);
-	__restore_processor_state(&ctxt);
-}
-
-static cpumask_t oldmask;
+/* This is protected by pm_sem semaphore */
+static cpumask_t frozen_cpus;
 
 void disable_nonboot_cpus(void)
 {
-	oldmask = current->cpus_allowed;
-	set_cpus_allowed(current, cpumask_of_cpu(0));
-	printk("Freezing CPUs (at %d)", _smp_processor_id());
-	current->state = TASK_INTERRUPTIBLE;
-	schedule_timeout(HZ);
-	printk("...");
-	BUG_ON(_smp_processor_id() != 0);
-
-	/* FIXME: for this to work, all the CPUs must be running
-	 * "idle" thread (or we deadlock). Is that guaranteed? */
-
-	atomic_set(&cpu_counter, 0);
-	atomic_set(&freeze, 1);
-	smp_call_function(smp_pause, NULL, 0, 0);
-	while (atomic_read(&cpu_counter) < (num_online_cpus() - 1)) {
-		cpu_relax();
-		barrier();
+	int cpu, error;
+
+	error = 0;
+	cpus_clear(frozen_cpus);
+	printk("Freezing cpus ...\n");
+	for_each_online_cpu(cpu) {
+		if (cpu == 0)
+			continue;
+		error = cpu_down(cpu);
+		if (!error) {
+			cpu_set(cpu, frozen_cpus);
+			printk("CPU%d is down\n", cpu);
+			continue;
+		}
+		printk("Error taking cpu %d down: %d\n", cpu, error);
 	}
-	printk("ok\n");
+	BUG_ON(raw_smp_processor_id() != 0);
+	if (error)
+		panic("cpus not sleeping");
 }
 
 void enable_nonboot_cpus(void)
 {
-	printk("Restarting CPUs");
-	atomic_set(&freeze, 0);
-	while (atomic_read(&cpu_counter)) {
-		cpu_relax();
-		barrier();
-	}
-	printk("...");
-	set_cpus_allowed(current, oldmask);
-	schedule();
-	printk("ok\n");
+	int cpu, error;
 
+	printk("Thawing cpus ...\n");
+	for_each_cpu_mask(cpu, frozen_cpus) {
+		error = smp_prepare_cpu(cpu);
+		if (!error)
+			error = cpu_up(cpu);
+		if (!error) {
+			printk("CPU%d is up\n", cpu);
+			continue;
+		}
+		printk("Error taking cpu %d up: %d\n", cpu, error);
+		panic("Not enough cpus");
+	}
+	cpus_clear(frozen_cpus);
 }
 
-
diff --git a/kernel/power/swsusp.c b/kernel/power/swsusp.c
--- a/kernel/power/swsusp.c
+++ b/kernel/power/swsusp.c
@@ -10,12 +10,12 @@
  * This file is released under the GPLv2.
  *
  * 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. Port to 2.4.18-ac and 2.5.17.
  *
- * Steve Doddi <dirk@loth.demon.co.uk>: 
+ * Steve Doddi <dirk@loth.demon.co.uk>:
  * Support the possibility of hardware state restoring.
  *
  * Raph <grey.havens@earthling.net>:
@@ -63,6 +63,7 @@
 #include <linux/console.h>
 #include <linux/highmem.h>
 #include <linux/bio.h>
+#include <linux/mount.h>
 
 #include <asm/uaccess.h>
 #include <asm/mmu_context.h>
@@ -81,14 +82,14 @@ static int nr_copy_pages_check;
 extern char resume_file[];
 
 /* Local variables that should not be affected by save */
-unsigned int nr_copy_pages __nosavedata = 0;
+static unsigned int nr_copy_pages __nosavedata = 0;
 
 /* Suspend pagedir is allocated before final copy, therefore it
-   must be freed after resume 
+   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", 
+   time of suspend, that must be freed. Second is "pagedir_nosave",
    allocated at time of resume, that travels through memory not to
    collide with anything.
 
@@ -132,7 +133,7 @@ static int mark_swapfiles(swp_entry_t pr
 {
 	int error;
 
-	rw_swap_page_sync(READ, 
+	rw_swap_page_sync(READ,
 			  swp_entry(root_swap, 0),
 			  virt_to_page((unsigned long)&swsusp_header));
 	if (!memcmp("SWAP-SPACE",swsusp_header.sig, 10) ||
@@ -140,7 +141,7 @@ static int mark_swapfiles(swp_entry_t pr
 		memcpy(swsusp_header.orig_sig,swsusp_header.sig, 10);
 		memcpy(swsusp_header.sig,SWSUSP_SIG, 10);
 		swsusp_header.swsusp_info = prev;
-		error = rw_swap_page_sync(WRITE, 
+		error = rw_swap_page_sync(WRITE,
 					  swp_entry(root_swap, 0),
 					  virt_to_page((unsigned long)
 						       &swsusp_header));
@@ -174,22 +175,22 @@ static int is_resume_device(const struct
 static int swsusp_swap_check(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++) {
+	for (i=0; i<MAX_SWAPFILES; i++) {
 		if (swap_info[i].flags == 0) {
 			swapfile_used[i]=SWAPFILE_UNUSED;
 		} else {
-			if(!len) {
+			if (!len) {
 	    			printk(KERN_WARNING "resume= option should be used to set suspend device" );
-				if(root_swap == 0xFFFF) {
+				if (root_swap == 0xFFFF) {
 					swapfile_used[i] = SWAPFILE_SUSPEND;
 					root_swap = i;
 				} else
-					swapfile_used[i] = SWAPFILE_IGNORED;				  
+					swapfile_used[i] = SWAPFILE_IGNORED;
 			} else {
 	  			/* we ignore all swap devices that are not the resume_file */
 				if (is_resume_device(&swap_info[i])) {
@@ -209,15 +210,15 @@ static int swsusp_swap_check(void) /* Th
  * This is called after saving image so modification
  * will be lost after resume... and that's what we want.
  * we make the device unusable. A new call to
- * lock_swapdevices can unlock the devices. 
+ * lock_swapdevices can unlock the devices.
  */
 static void lock_swapdevices(void)
 {
 	int i;
 
 	swap_list_lock();
-	for(i = 0; i< MAX_SWAPFILES; i++)
-		if(swapfile_used[i] == SWAPFILE_IGNORED) {
+	for (i = 0; i< MAX_SWAPFILES; i++)
+		if (swapfile_used[i] == SWAPFILE_IGNORED) {
 			swap_info[i].flags ^= 0xFF;
 		}
 	swap_list_unlock();
@@ -229,7 +230,7 @@ static void lock_swapdevices(void)
  *	@loc:	Place to store the entry we used.
  *
  *	Allocate a new swap entry and 'sync' it. Note we discard -EIO
- *	errors. That is an artifact left over from swsusp. It did not 
+ *	errors. That is an artifact left over from swsusp. It did not
  *	check the return of rw_swap_page_sync() at all, since most pages
  *	written back to swap would return -EIO.
  *	This is a partial improvement, since we will at least return other
@@ -241,7 +242,7 @@ static int write_page(unsigned long addr
 	int error = 0;
 
 	entry = get_swap_page();
-	if (swp_offset(entry) && 
+	if (swp_offset(entry) &&
 	    swapfile_used[swp_type(entry)] == SWAPFILE_SUSPEND) {
 		error = rw_swap_page_sync(WRITE, entry,
 					  virt_to_page(addr));
@@ -257,7 +258,7 @@ static int write_page(unsigned long addr
 /**
  *	data_free - Free the swap entries used by the saved image.
  *
- *	Walk the list of used swap entries and free each one. 
+ *	Walk the list of used swap entries and free each one.
  *	This is only used for cleanup when suspend fails.
  */
 static void data_free(void)
@@ -290,7 +291,7 @@ static int data_write(void)
 		mod = 1;
 
 	printk( "Writing data to swap (%d pages)...     ", nr_copy_pages );
-	for_each_pbe(p, pagedir_nosave) {
+	for_each_pbe (p, pagedir_nosave) {
 		if (!(i%mod))
 			printk( "\b\b\b\b%3d%%", i / mod );
 		if ((error = write_page(p->address, &(p->swap_address))))
@@ -335,7 +336,7 @@ static int close_swap(void)
 
 	dump_info();
 	error = write_page((unsigned long)&swsusp_info, &entry);
-	if (!error) { 
+	if (!error) {
 		printk( "S" );
 		error = mark_swapfiles(entry);
 		printk( "|\n" );
@@ -370,7 +371,7 @@ static int write_pagedir(void)
 	struct pbe * pbe;
 
 	printk( "Writing pagedir...");
-	for_each_pb_page(pbe, pagedir_nosave) {
+	for_each_pb_page (pbe, pagedir_nosave) {
 		if ((error = write_page((unsigned long)pbe, &swsusp_info.pagedir[n++])))
 			return error;
 	}
@@ -472,7 +473,7 @@ static int save_highmem(void)
 	int res = 0;
 
 	pr_debug("swsusp: Saving Highmem\n");
-	for_each_zone(zone) {
+	for_each_zone (zone) {
 		if (is_highmem(zone))
 			res = save_highmem_zone(zone);
 		if (res)
@@ -547,7 +548,7 @@ static void count_data_pages(void)
 
 	nr_copy_pages = 0;
 
-	for_each_zone(zone) {
+	for_each_zone (zone) {
 		if (is_highmem(zone))
 			continue;
 		mark_free_pages(zone);
@@ -562,9 +563,9 @@ static void copy_data_pages(void)
 	struct zone *zone;
 	unsigned long zone_pfn;
 	struct pbe * pbe = pagedir_nosave;
-	
+
 	pr_debug("copy_data_pages(): pages to copy: %d\n", nr_copy_pages);
-	for_each_zone(zone) {
+	for_each_zone (zone) {
 		if (is_highmem(zone))
 			continue;
 		mark_free_pages(zone);
@@ -702,7 +703,7 @@ static void free_image_pages(void)
 {
 	struct pbe * p;
 
-	for_each_pbe(p, pagedir_save) {
+	for_each_pbe (p, pagedir_save) {
 		if (p->address) {
 			ClearPageNosave(virt_to_page(p->address));
 			free_page(p->address);
@@ -719,7 +720,7 @@ static int alloc_image_pages(void)
 {
 	struct pbe * p;
 
-	for_each_pbe(p, pagedir_save) {
+	for_each_pbe (p, pagedir_save) {
 		p->address = get_zeroed_page(GFP_ATOMIC | __GFP_COLD);
 		if (!p->address)
 			return -ENOMEM;
@@ -740,7 +741,7 @@ void swsusp_free(void)
 /**
  *	enough_free_mem - Make sure we enough free memory to snapshot.
  *
- *	Returns TRUE or FALSE after checking the number of available 
+ *	Returns TRUE or FALSE after checking the number of available
  *	free pages.
  */
 
@@ -758,11 +759,11 @@ static int enough_free_mem(void)
 /**
  *	enough_swap - Make sure we have enough swap to save the image.
  *
- *	Returns TRUE or FALSE after checking the total amount of swap 
+ *	Returns TRUE or FALSE after checking the total amount of swap
  *	space avaiable.
  *
  *	FIXME: si_swapinfo(&i) returns all swap devices information.
- *	We should only consider resume_device. 
+ *	We should only consider resume_device.
  */
 
 static int enough_swap(void)
@@ -781,18 +782,18 @@ static int swsusp_alloc(void)
 {
 	int error;
 
+	pagedir_nosave = NULL;
+	nr_copy_pages = calc_nr(nr_copy_pages);
+
 	pr_debug("suspend: (pages needed: %d + %d free: %d)\n",
 		 nr_copy_pages, PAGES_FOR_IO, nr_free_pages());
 
-	pagedir_nosave = NULL;
 	if (!enough_free_mem())
 		return -ENOMEM;
 
 	if (!enough_swap())
 		return -ENOSPC;
 
-	nr_copy_pages = calc_nr(nr_copy_pages);
-
 	if (!(pagedir_save = alloc_pagedir(nr_copy_pages))) {
 		printk(KERN_ERR "suspend: Allocating pagedir failed.\n");
 		return -ENOMEM;
@@ -827,8 +828,8 @@ static int suspend_prepare_image(void)
 	error = swsusp_alloc();
 	if (error)
 		return error;
-	
-	/* During allocating of suspend pagedir, new cold pages may appear. 
+
+	/* During allocating of suspend pagedir, new cold pages may appear.
 	 * Kill them.
 	 */
 	drain_local_pages();
@@ -869,13 +870,6 @@ extern asmlinkage int swsusp_arch_resume
 
 asmlinkage int swsusp_save(void)
 {
-	int error = 0;
-
-	if ((error = swsusp_swap_check())) {
-		printk(KERN_ERR "swsusp: FATAL: cannot find swap device, try "
-				"swapon -a!\n");
-		return error;
-	}
 	return suspend_prepare_image();
 }
 
@@ -892,14 +886,20 @@ int swsusp_suspend(void)
 	 * at resume time, and evil weirdness ensues.
 	 */
 	if ((error = device_power_down(PMSG_FREEZE))) {
-		printk(KERN_ERR "Some devices failed to power down, aborting suspend\n");
 		local_irq_enable();
-		swsusp_free();
 		return error;
 	}
+
+	if ((error = swsusp_swap_check())) {
+		printk(KERN_ERR "swsusp: FATAL: cannot find swap device, try "
+				"swapon -a!\n");
+		local_irq_enable();
+		return error;
+	}
+
 	save_processor_state();
 	if ((error = swsusp_arch_suspend()))
-		swsusp_free();
+		printk("Error %d suspending\n", error);
 	/* Restore control flow magically appears here */
 	restore_processor_state();
 	BUG_ON (nr_copy_pages_check != nr_copy_pages);
@@ -929,21 +929,6 @@ int swsusp_resume(void)
 	return error;
 }
 
-/* More restore stuff */
-
-/*
- * Returns true if given address/order collides with any orig_address 
- */
-static int does_collide_order(unsigned long addr, int order)
-{
-	int i;
-	
-	for (i=0; i < (1<<order); i++)
-		if (!PageNosaveFree(virt_to_page(addr + i * PAGE_SIZE)))
-			return 1;
-	return 0;
-}
-
 /**
  *	On resume, for storing the PBE list and the image,
  *	we can only use memory pages that do not conflict with the pages
@@ -973,7 +958,7 @@ static unsigned long get_usable_page(uns
 	unsigned long m;
 
 	m = get_zeroed_page(gfp_mask);
-	while (does_collide_order(m, 0)) {
+	while (!PageNosaveFree(virt_to_page(m))) {
 		eat_page((void *)m);
 		m = get_zeroed_page(gfp_mask);
 		if (!m)
@@ -1045,7 +1030,7 @@ static struct pbe * swsusp_pagedir_reloc
 
 	/* Set page flags */
 
-	for_each_zone(zone) {
+	for_each_zone (zone) {
         	for (zone_pfn = 0; zone_pfn < zone->spanned_pages; ++zone_pfn)
                 	SetPageNosaveFree(pfn_to_page(zone_pfn +
 					zone->zone_start_pfn));
@@ -1061,7 +1046,7 @@ static struct pbe * swsusp_pagedir_reloc
 	/* Relocate colliding pages */
 
 	for_each_pb_page (pbpage, pblist) {
-		if (does_collide_order((unsigned long)pbpage, 0)) {
+		if (!PageNosaveFree(virt_to_page((unsigned long)pbpage))) {
 			m = (void *)get_usable_page(GFP_ATOMIC | __GFP_COLD);
 			if (!m) {
 				error = -ENOMEM;
@@ -1181,9 +1166,9 @@ static int bio_write_page(pgoff_t page_o
 static const char * sanity_check(void)
 {
 	dump_info();
-	if(swsusp_info.version_code != LINUX_VERSION_CODE)
+	if (swsusp_info.version_code != LINUX_VERSION_CODE)
 		return "kernel version";
-	if(swsusp_info.num_physpages != num_physpages)
+	if (swsusp_info.num_physpages != num_physpages)
 		return "memory size";
 	if (strcmp(swsusp_info.uts.sysname,system_utsname.sysname))
 		return "system type";
@@ -1193,8 +1178,10 @@ static const char * sanity_check(void)
 		return "version";
 	if (strcmp(swsusp_info.uts.machine,system_utsname.machine))
 		return "machine";
+#if 0
 	if(swsusp_info.cpus != num_online_cpus())
 		return "number of cpus";
+#endif
 	return NULL;
 }
 
@@ -1274,8 +1261,6 @@ static int data_read(struct pbe *pblist)
 	return error;
 }
 
-extern dev_t name_to_dev_t(const char *line);
-
 /**
  *	read_pagedir - Read page backup list pages from swap
  */
@@ -1369,16 +1354,6 @@ int swsusp_check(void)
 {
 	int error;
 
-	if (!swsusp_resume_device) {
-		if (!strlen(resume_file))
-			return -ENOENT;
-		swsusp_resume_device = name_to_dev_t(resume_file);
-		pr_debug("swsusp: Resume From Partition %s\n", resume_file);
-	} else {
-		pr_debug("swsusp: Resume From Partition %d:%d\n",
-			 MAJOR(swsusp_resume_device), MINOR(swsusp_resume_device));
-	}
-
 	resume_bdev = open_by_devnum(swsusp_resume_device, FMODE_READ);
 	if (!IS_ERR(resume_bdev)) {
 		set_blocksize(resume_bdev, PAGE_SIZE);
diff --git a/kernel/printk.c b/kernel/printk.c
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -588,8 +588,7 @@ asmlinkage int vprintk(const char *fmt, 
 			log_level_unknown = 1;
 	}
 
-	if (!cpu_online(smp_processor_id()) &&
-	    system_state != SYSTEM_RUNNING) {
+	if (!cpu_online(smp_processor_id())) {
 		/*
 		 * Some console drivers may assume that per-cpu resources have
 		 * been allocated.  So don't allow them to be called by this
@@ -876,8 +875,10 @@ void register_console(struct console * c
 			break;
 		console->flags |= CON_ENABLED;
 		console->index = console_cmdline[i].index;
-		if (i == preferred_console)
+		if (i == selected_console) {
 			console->flags |= CON_CONSDEV;
+			preferred_console = selected_console;
+		}
 		break;
 	}
 
@@ -897,6 +898,8 @@ void register_console(struct console * c
 	if ((console->flags & CON_CONSDEV) || console_drivers == NULL) {
 		console->next = console_drivers;
 		console_drivers = console;
+		if (console->next)
+			console->next->flags &= ~CON_CONSDEV;
 	} else {
 		console->next = console_drivers->next;
 		console_drivers->next = console;
@@ -937,10 +940,14 @@ int unregister_console(struct console * 
 	/* If last console is removed, we re-enable picking the first
 	 * one that gets registered. Without that, pmac early boot console
 	 * would prevent fbcon from taking over.
+	 *
+	 * If this isn't the last console and it has CON_CONSDEV set, we
+	 * need to set it on the next preferred console.
 	 */
 	if (console_drivers == NULL)
 		preferred_console = selected_console;
-		
+	else if (console->flags & CON_CONSDEV)
+		console_drivers->flags |= CON_CONSDEV;
 
 	release_console_sem();
 	return res;
diff --git a/kernel/profile.c b/kernel/profile.c
--- a/kernel/profile.c
+++ b/kernel/profile.c
@@ -35,11 +35,11 @@ struct profile_hit {
 #define NR_PROFILE_GRP		(NR_PROFILE_HIT/PROFILE_GRPSZ)
 
 /* Oprofile timer tick hook */
-int (*timer_hook)(struct pt_regs *);
+int (*timer_hook)(struct pt_regs *) __read_mostly;
 
 static atomic_t *prof_buffer;
 static unsigned long prof_len, prof_shift;
-static int prof_on;
+static int prof_on __read_mostly;
 static cpumask_t prof_cpu_mask = CPU_MASK_ALL;
 #ifdef CONFIG_SMP
 static DEFINE_PER_CPU(struct profile_hit *[2], cpu_profile_hits);
diff --git a/kernel/resource.c b/kernel/resource.c
--- a/kernel/resource.c
+++ b/kernel/resource.c
@@ -263,7 +263,7 @@ static int find_resource(struct resource
 			new->start = min;
 		if (new->end > max)
 			new->end = max;
-		new->start = (new->start + align - 1) & ~(align - 1);
+		new->start = ALIGN(new->start, align);
 		if (alignf)
 			alignf(alignf_data, new, size, align);
 		if (new->start < new->end && new->end - new->start >= size - 1) {
diff --git a/kernel/sched.c b/kernel/sched.c
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -166,7 +166,7 @@
 #define SCALE_PRIO(x, prio) \
 	max(x * (MAX_PRIO - prio) / (MAX_USER_PRIO/2), MIN_TIMESLICE)
 
-static inline unsigned int task_timeslice(task_t *p)
+static unsigned int task_timeslice(task_t *p)
 {
 	if (p->static_prio < NICE_TO_PRIO(0))
 		return SCALE_PRIO(DEF_TIMESLICE*4, p->static_prio);
@@ -206,7 +206,7 @@ struct runqueue {
 	 */
 	unsigned long nr_running;
 #ifdef CONFIG_SMP
-	unsigned long cpu_load;
+	unsigned long cpu_load[3];
 #endif
 	unsigned long long nr_switches;
 
@@ -260,23 +260,87 @@ struct runqueue {
 
 static DEFINE_PER_CPU(struct runqueue, runqueues);
 
+/*
+ * The domain tree (rq->sd) is protected by RCU's quiescent state transition.
+ * See detach_destroy_domains: synchronize_sched for details.
+ *
+ * The domain tree of any CPU may only be accessed from within
+ * preempt-disabled sections.
+ */
 #define for_each_domain(cpu, domain) \
-	for (domain = cpu_rq(cpu)->sd; domain; domain = domain->parent)
+for (domain = rcu_dereference(cpu_rq(cpu)->sd); domain; domain = domain->parent)
 
 #define cpu_rq(cpu)		(&per_cpu(runqueues, (cpu)))
 #define this_rq()		(&__get_cpu_var(runqueues))
 #define task_rq(p)		cpu_rq(task_cpu(p))
 #define cpu_curr(cpu)		(cpu_rq(cpu)->curr)
 
-/*
- * Default context-switch locking:
- */
 #ifndef prepare_arch_switch
-# define prepare_arch_switch(rq, next)	do { } while (0)
-# define finish_arch_switch(rq, next)	spin_unlock_irq(&(rq)->lock)
-# define task_running(rq, p)		((rq)->curr == (p))
+# define prepare_arch_switch(next)	do { } while (0)
+#endif
+#ifndef finish_arch_switch
+# define finish_arch_switch(prev)	do { } while (0)
 #endif
 
+#ifndef __ARCH_WANT_UNLOCKED_CTXSW
+static inline int task_running(runqueue_t *rq, task_t *p)
+{
+	return rq->curr == p;
+}
+
+static inline void prepare_lock_switch(runqueue_t *rq, task_t *next)
+{
+}
+
+static inline void finish_lock_switch(runqueue_t *rq, task_t *prev)
+{
+	spin_unlock_irq(&rq->lock);
+}
+
+#else /* __ARCH_WANT_UNLOCKED_CTXSW */
+static inline int task_running(runqueue_t *rq, task_t *p)
+{
+#ifdef CONFIG_SMP
+	return p->oncpu;
+#else
+	return rq->curr == p;
+#endif
+}
+
+static inline void prepare_lock_switch(runqueue_t *rq, task_t *next)
+{
+#ifdef CONFIG_SMP
+	/*
+	 * We can optimise this out completely for !SMP, because the
+	 * SMP rebalancing from interrupt is the only thing that cares
+	 * here.
+	 */
+	next->oncpu = 1;
+#endif
+#ifdef __ARCH_WANT_INTERRUPTS_ON_CTXSW
+	spin_unlock_irq(&rq->lock);
+#else
+	spin_unlock(&rq->lock);
+#endif
+}
+
+static inline void finish_lock_switch(runqueue_t *rq, task_t *prev)
+{
+#ifdef CONFIG_SMP
+	/*
+	 * After ->oncpu is cleared, the task can be moved to a different CPU.
+	 * We must ensure this doesn't happen until the switch is completely
+	 * finished.
+	 */
+	smp_wmb();
+	prev->oncpu = 0;
+#endif
+#ifndef __ARCH_WANT_INTERRUPTS_ON_CTXSW
+	local_irq_enable();
+#endif
+}
+#endif /* __ARCH_WANT_UNLOCKED_CTXSW */
+
 /*
  * task_rq_lock - lock the runqueue a given task resides on and disable
  * interrupts.  Note the ordering: we can safely lookup the task_rq without
@@ -309,7 +373,7 @@ static inline void task_rq_unlock(runque
  * bump this up when changing the output format or the meaning of an existing
  * format, so that tools can adapt (or abort)
  */
-#define SCHEDSTAT_VERSION 11
+#define SCHEDSTAT_VERSION 12
 
 static int show_schedstat(struct seq_file *seq, void *v)
 {
@@ -338,6 +402,7 @@ static int show_schedstat(struct seq_fil
 
 #ifdef CONFIG_SMP
 		/* domain-specific stats */
+		preempt_disable();
 		for_each_domain(cpu, sd) {
 			enum idle_type itype;
 			char mask_str[NR_CPUS];
@@ -356,11 +421,13 @@ static int show_schedstat(struct seq_fil
 				    sd->lb_nobusyq[itype],
 				    sd->lb_nobusyg[itype]);
 			}
-			seq_printf(seq, " %lu %lu %lu %lu %lu %lu %lu %lu\n",
+			seq_printf(seq, " %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu\n",
 			    sd->alb_cnt, sd->alb_failed, sd->alb_pushed,
-			    sd->sbe_pushed, sd->sbe_attempts,
+			    sd->sbe_cnt, sd->sbe_balanced, sd->sbe_pushed,
+			    sd->sbf_cnt, sd->sbf_balanced, sd->sbf_pushed,
 			    sd->ttwu_wake_remote, sd->ttwu_move_affine, sd->ttwu_move_balance);
 		}
+		preempt_enable();
 #endif
 	}
 	return 0;
@@ -414,22 +481,6 @@ static inline runqueue_t *this_rq_lock(v
 	return rq;
 }
 
-#ifdef CONFIG_SCHED_SMT
-static int cpu_and_siblings_are_idle(int cpu)
-{
-	int sib;
-	for_each_cpu_mask(sib, cpu_sibling_map[cpu]) {
-		if (idle_cpu(sib))
-			continue;
-		return 0;
-	}
-
-	return 1;
-}
-#else
-#define cpu_and_siblings_are_idle(A) idle_cpu(A)
-#endif
-
 #ifdef CONFIG_SCHEDSTATS
 /*
  * Called when a process is dequeued from the active array and given
@@ -622,7 +673,7 @@ static inline void __activate_idle_task(
 	rq->nr_running++;
 }
 
-static void recalc_task_prio(task_t *p, unsigned long long now)
+static int recalc_task_prio(task_t *p, unsigned long long now)
 {
 	/* Caller must always ensure 'now >= p->timestamp' */
 	unsigned long long __sleep_time = now - p->timestamp;
@@ -681,7 +732,7 @@ static void recalc_task_prio(task_t *p, 
 		}
 	}
 
-	p->prio = effective_prio(p);
+	return effective_prio(p);
 }
 
 /*
@@ -704,7 +755,7 @@ static void activate_task(task_t *p, run
 	}
 #endif
 
-	recalc_task_prio(p, now);
+	p->prio = recalc_task_prio(p, now);
 
 	/*
 	 * This checks to make sure it's not an uninterruptible task
@@ -782,22 +833,12 @@ inline int task_curr(const task_t *p)
 }
 
 #ifdef CONFIG_SMP
-enum request_type {
-	REQ_MOVE_TASK,
-	REQ_SET_DOMAIN,
-};
-
 typedef struct {
 	struct list_head list;
-	enum request_type type;
 
-	/* For REQ_MOVE_TASK */
 	task_t *task;
 	int dest_cpu;
 
-	/* For REQ_SET_DOMAIN */
-	struct sched_domain *sd;
-
 	struct completion done;
 } migration_req_t;
 
@@ -819,7 +860,6 @@ static int migrate_task(task_t *p, int d
 	}
 
 	init_completion(&req->done);
-	req->type = REQ_MOVE_TASK;
 	req->task = p;
 	req->dest_cpu = dest_cpu;
 	list_add(&req->list, &rq->migration_queue);
@@ -886,26 +926,154 @@ void kick_process(task_t *p)
  * We want to under-estimate the load of migration sources, to
  * balance conservatively.
  */
-static inline unsigned long source_load(int cpu)
+static inline unsigned long source_load(int cpu, int type)
 {
 	runqueue_t *rq = cpu_rq(cpu);
 	unsigned long load_now = rq->nr_running * SCHED_LOAD_SCALE;
+	if (type == 0)
+		return load_now;
 
-	return min(rq->cpu_load, load_now);
+	return min(rq->cpu_load[type-1], load_now);
 }
 
 /*
  * Return a high guess at the load of a migration-target cpu
  */
-static inline unsigned long target_load(int cpu)
+static inline unsigned long target_load(int cpu, int type)
 {
 	runqueue_t *rq = cpu_rq(cpu);
 	unsigned long load_now = rq->nr_running * SCHED_LOAD_SCALE;
+	if (type == 0)
+		return load_now;
 
-	return max(rq->cpu_load, load_now);
+	return max(rq->cpu_load[type-1], load_now);
 }
 
-#endif
+/*
+ * find_idlest_group finds and returns the least busy CPU group within the
+ * domain.
+ */
+static struct sched_group *
+find_idlest_group(struct sched_domain *sd, struct task_struct *p, int this_cpu)
+{
+	struct sched_group *idlest = NULL, *this = NULL, *group = sd->groups;
+	unsigned long min_load = ULONG_MAX, this_load = 0;
+	int load_idx = sd->forkexec_idx;
+	int imbalance = 100 + (sd->imbalance_pct-100)/2;
+
+	do {
+		unsigned long load, avg_load;
+		int local_group;
+		int i;
+
+		local_group = cpu_isset(this_cpu, group->cpumask);
+		/* XXX: put a cpus allowed check */
+
+		/* Tally up the load of all CPUs in the group */
+		avg_load = 0;
+
+		for_each_cpu_mask(i, group->cpumask) {
+			/* Bias balancing toward cpus of our domain */
+			if (local_group)
+				load = source_load(i, load_idx);
+			else
+				load = target_load(i, load_idx);
+
+			avg_load += load;
+		}
+
+		/* Adjust by relative CPU power of the group */
+		avg_load = (avg_load * SCHED_LOAD_SCALE) / group->cpu_power;
+
+		if (local_group) {
+			this_load = avg_load;
+			this = group;
+		} else if (avg_load < min_load) {
+			min_load = avg_load;
+			idlest = group;
+		}
+		group = group->next;
+	} while (group != sd->groups);
+
+	if (!idlest || 100*this_load < imbalance*min_load)
+		return NULL;
+	return idlest;
+}
+
+/*
+ * find_idlest_queue - find the idlest runqueue among the cpus in group.
+ */
+static int find_idlest_cpu(struct sched_group *group, int this_cpu)
+{
+	unsigned long load, min_load = ULONG_MAX;
+	int idlest = -1;
+	int i;
+
+	for_each_cpu_mask(i, group->cpumask) {
+		load = source_load(i, 0);
+
+		if (load < min_load || (load == min_load && i == this_cpu)) {
+			min_load = load;
+			idlest = i;
+		}
+	}
+
+	return idlest;
+}
+
+/*
+ * sched_balance_self: balance the current task (running on cpu) in domains
+ * that have the 'flag' flag set. In practice, this is SD_BALANCE_FORK and
+ * SD_BALANCE_EXEC.
+ *
+ * Balance, ie. select the least loaded group.
+ *
+ * Returns the target CPU number, or the same CPU if no balancing is needed.
+ *
+ * preempt must be disabled.
+ */
+static int sched_balance_self(int cpu, int flag)
+{
+	struct task_struct *t = current;
+	struct sched_domain *tmp, *sd = NULL;
+
+	for_each_domain(cpu, tmp)
+		if (tmp->flags & flag)
+			sd = tmp;
+
+	while (sd) {
+		cpumask_t span;
+		struct sched_group *group;
+		int new_cpu;
+		int weight;
+
+		span = sd->span;
+		group = find_idlest_group(sd, t, cpu);
+		if (!group)
+			goto nextlevel;
+
+		new_cpu = find_idlest_cpu(group, cpu);
+		if (new_cpu == -1 || new_cpu == cpu)
+			goto nextlevel;
+
+		/* Now try balancing at a lower domain level */
+		cpu = new_cpu;
+nextlevel:
+		sd = NULL;
+		weight = cpus_weight(span);
+		for_each_domain(cpu, tmp) {
+			if (weight <= cpus_weight(tmp->span))
+				break;
+			if (tmp->flags & flag)
+				sd = tmp;
+		}
+		/* while loop will break here if sd == NULL */
+	}
+
+	return cpu;
+}
+
+#endif /* CONFIG_SMP */
 
 /*
  * wake_idle() will wake a task on an idle cpu if task->cpu is
@@ -927,14 +1095,14 @@ static int wake_idle(int cpu, task_t *p)
 
 	for_each_domain(cpu, sd) {
 		if (sd->flags & SD_WAKE_IDLE) {
-			cpus_and(tmp, sd->span, cpu_online_map);
-			cpus_and(tmp, tmp, p->cpus_allowed);
+			cpus_and(tmp, sd->span, p->cpus_allowed);
 			for_each_cpu_mask(i, tmp) {
 				if (idle_cpu(i))
 					return i;
 			}
 		}
-		else break;
+		else
+			break;
 	}
 	return cpu;
 }
@@ -967,7 +1135,7 @@ static int try_to_wake_up(task_t * p, un
 	runqueue_t *rq;
 #ifdef CONFIG_SMP
 	unsigned long load, this_load;
-	struct sched_domain *sd;
+	struct sched_domain *sd, *this_sd = NULL;
 	int new_cpu;
 #endif
 
@@ -986,70 +1154,69 @@ static int try_to_wake_up(task_t * p, un
 	if (unlikely(task_running(rq, p)))
 		goto out_activate;
 
-#ifdef CONFIG_SCHEDSTATS
+	new_cpu = cpu;
+
 	schedstat_inc(rq, ttwu_cnt);
 	if (cpu == this_cpu) {
 		schedstat_inc(rq, ttwu_local);
-	} else {
-		for_each_domain(this_cpu, sd) {
-			if (cpu_isset(cpu, sd->span)) {
-				schedstat_inc(sd, ttwu_wake_remote);
-				break;
-			}
+		goto out_set_cpu;
+	}
+
+	for_each_domain(this_cpu, sd) {
+		if (cpu_isset(cpu, sd->span)) {
+			schedstat_inc(sd, ttwu_wake_remote);
+			this_sd = sd;
+			break;
 		}
 	}
-#endif
 
-	new_cpu = cpu;
-	if (cpu == this_cpu || unlikely(!cpu_isset(this_cpu, p->cpus_allowed)))
+	if (unlikely(!cpu_isset(this_cpu, p->cpus_allowed)))
 		goto out_set_cpu;
 
-	load = source_load(cpu);
-	this_load = target_load(this_cpu);
-
 	/*
-	 * If sync wakeup then subtract the (maximum possible) effect of
-	 * the currently running task from the load of the current CPU:
+	 * Check for affine wakeup and passive balancing possibilities.
 	 */
-	if (sync)
-		this_load -= SCHED_LOAD_SCALE;
+	if (this_sd) {
+		int idx = this_sd->wake_idx;
+		unsigned int imbalance;
 
-	/* Don't pull the task off an idle CPU to a busy one */
-	if (load < SCHED_LOAD_SCALE/2 && this_load > SCHED_LOAD_SCALE/2)
-		goto out_set_cpu;
+		imbalance = 100 + (this_sd->imbalance_pct - 100) / 2;
 
-	new_cpu = this_cpu; /* Wake to this CPU if we can */
+		load = source_load(cpu, idx);
+		this_load = target_load(this_cpu, idx);
 
-	/*
-	 * Scan domains for affine wakeup and passive balancing
-	 * possibilities.
-	 */
-	for_each_domain(this_cpu, sd) {
-		unsigned int imbalance;
-		/*
-		 * Start passive balancing when half the imbalance_pct
-		 * limit is reached.
-		 */
-		imbalance = sd->imbalance_pct + (sd->imbalance_pct - 100) / 2;
+		new_cpu = this_cpu; /* Wake to this CPU if we can */
 
-		if ((sd->flags & SD_WAKE_AFFINE) &&
-				!task_hot(p, rq->timestamp_last_tick, sd)) {
+		if (this_sd->flags & SD_WAKE_AFFINE) {
+			unsigned long tl = this_load;
 			/*
-			 * This domain has SD_WAKE_AFFINE and p is cache cold
-			 * in this domain.
+			 * If sync wakeup then subtract the (maximum possible)
+			 * effect of the currently running task from the load
+			 * of the current CPU:
 			 */
-			if (cpu_isset(cpu, sd->span)) {
-				schedstat_inc(sd, ttwu_move_affine);
+			if (sync)
+				tl -= SCHED_LOAD_SCALE;
+
+			if ((tl <= load &&
+				tl + target_load(cpu, idx) <= SCHED_LOAD_SCALE) ||
+				100*(tl + SCHED_LOAD_SCALE) <= imbalance*load) {
+				/*
+				 * This domain has SD_WAKE_AFFINE and
+				 * p is cache cold in this domain, and
+				 * there is no bad imbalance.
+				 */
+				schedstat_inc(this_sd, ttwu_move_affine);
 				goto out_set_cpu;
 			}
-		} else if ((sd->flags & SD_WAKE_BALANCE) &&
-				imbalance*this_load <= 100*load) {
-			/*
-			 * This domain has SD_WAKE_BALANCE and there is
-			 * an imbalance.
-			 */
-			if (cpu_isset(cpu, sd->span)) {
-				schedstat_inc(sd, ttwu_move_balance);
+		}
+
+		/*
+		 * Start passive balancing when half the imbalance_pct
+		 * limit is reached.
+		 */
+		if (this_sd->flags & SD_WAKE_BALANCE) {
+			if (imbalance*this_load <= 100*load) {
+				schedstat_inc(this_sd, ttwu_move_balance);
 				goto out_set_cpu;
 			}
 		}
@@ -1120,17 +1287,19 @@ int fastcall wake_up_state(task_t *p, un
 	return try_to_wake_up(p, state, 0);
 }
 
-#ifdef CONFIG_SMP
-static int find_idlest_cpu(struct task_struct *p, int this_cpu,
-			   struct sched_domain *sd);
-#endif
-
 /*
  * Perform scheduler related setup for a newly forked process p.
  * p is forked by current.
  */
-void fastcall sched_fork(task_t *p)
+void fastcall sched_fork(task_t *p, int clone_flags)
 {
+	int cpu = get_cpu();
+
+#ifdef CONFIG_SMP
+	cpu = sched_balance_self(cpu, SD_BALANCE_FORK);
+#endif
+	set_task_cpu(p, cpu);
+
 	/*
 	 * We mark the process as running here, but have not actually
 	 * inserted it onto the runqueue yet. This guarantees that
@@ -1140,17 +1309,14 @@ void fastcall sched_fork(task_t *p)
 	p->state = TASK_RUNNING;
 	INIT_LIST_HEAD(&p->run_list);
 	p->array = NULL;
-	spin_lock_init(&p->switch_lock);
 #ifdef CONFIG_SCHEDSTATS
 	memset(&p->sched_info, 0, sizeof(p->sched_info));
 #endif
+#if defined(CONFIG_SMP) && defined(__ARCH_WANT_UNLOCKED_CTXSW)
+	p->oncpu = 0;
+#endif
 #ifdef CONFIG_PREEMPT
-	/*
-	 * During context-switch we hold precisely one spinlock, which
-	 * schedule_tail drops. (in the common case it's this_rq()->lock,
-	 * but it also can be p->switch_lock.) So we compensate with a count
-	 * of 1. Also, we want to start with kernel preemption disabled.
-	 */
+	/* Want to start with kernel preemption disabled. */
 	p->thread_info->preempt_count = 1;
 #endif
 	/*
@@ -1174,12 +1340,10 @@ void fastcall sched_fork(task_t *p)
 		 * runqueue lock is not a problem.
 		 */
 		current->time_slice = 1;
-		preempt_disable();
 		scheduler_tick();
-		local_irq_enable();
-		preempt_enable();
-	} else
-		local_irq_enable();
+	}
+	local_irq_enable();
+	put_cpu();
 }
 
 /*
@@ -1196,10 +1360,9 @@ void fastcall wake_up_new_task(task_t * 
 	runqueue_t *rq, *this_rq;
 
 	rq = task_rq_lock(p, &flags);
-	cpu = task_cpu(p);
-	this_cpu = smp_processor_id();
-
 	BUG_ON(p->state != TASK_RUNNING);
+	this_cpu = smp_processor_id();
+	cpu = task_cpu(p);
 
 	/*
 	 * We decrease the sleep average of forking parents
@@ -1296,22 +1459,40 @@ void fastcall sched_exit(task_t * p)
 }
 
 /**
+ * prepare_task_switch - prepare to switch tasks
+ * @rq: the runqueue preparing to switch
+ * @next: the task we are going to switch to.
+ *
+ * This is called with the rq lock held and interrupts off. It must
+ * be paired with a subsequent finish_task_switch after the context
+ * switch.
+ *
+ * prepare_task_switch sets up locking and calls architecture specific
+ * hooks.
+ */
+static inline void prepare_task_switch(runqueue_t *rq, task_t *next)
+{
+	prepare_lock_switch(rq, next);
+	prepare_arch_switch(next);
+}
+
+/**
  * finish_task_switch - clean up after a task-switch
  * @prev: the thread we just switched away from.
  *
- * We enter this with the runqueue still locked, and finish_arch_switch()
- * will unlock it along with doing any other architecture-specific cleanup
- * actions.
+ * finish_task_switch must be called after the context switch, paired
+ * with a prepare_task_switch call before the context switch.
+ * finish_task_switch will reconcile locking set up by prepare_task_switch,
+ * and do any other architecture-specific cleanup actions.
  *
  * Note that we may have delayed dropping an mm in context_switch(). If
  * so, we finish that here outside of the runqueue lock.  (Doing it
  * with the lock held can cause deadlocks; see schedule() for
  * details.)
  */
-static inline void finish_task_switch(task_t *prev)
+static inline void finish_task_switch(runqueue_t *rq, task_t *prev)
 	__releases(rq->lock)
 {
-	runqueue_t *rq = this_rq();
 	struct mm_struct *mm = rq->prev_mm;
 	unsigned long prev_task_flags;
 
@@ -1329,7 +1510,8 @@ static inline void finish_task_switch(ta
 	 *		Manfred Spraul <manfred@colorfullife.com>
 	 */
 	prev_task_flags = prev->flags;
-	finish_arch_switch(rq, prev);
+	finish_arch_switch(prev);
+	finish_lock_switch(rq, prev);
 	if (mm)
 		mmdrop(mm);
 	if (unlikely(prev_task_flags & PF_DEAD))
@@ -1343,8 +1525,12 @@ static inline void finish_task_switch(ta
 asmlinkage void schedule_tail(task_t *prev)
 	__releases(rq->lock)
 {
-	finish_task_switch(prev);
-
+	runqueue_t *rq = this_rq();
+	finish_task_switch(rq, prev);
+#ifdef __ARCH_WANT_UNLOCKED_CTXSW
+	/* In this case, finish_task_switch does not reenable preemption */
+	preempt_enable();
+#endif
 	if (current->set_child_tid)
 		put_user(current->pid, current->set_child_tid);
 }
@@ -1494,51 +1680,6 @@ static void double_lock_balance(runqueue
 }
 
 /*
- * find_idlest_cpu - find the least busy runqueue.
- */
-static int find_idlest_cpu(struct task_struct *p, int this_cpu,
-			   struct sched_domain *sd)
-{
-	unsigned long load, min_load, this_load;
-	int i, min_cpu;
-	cpumask_t mask;
-
-	min_cpu = UINT_MAX;
-	min_load = ULONG_MAX;
-
-	cpus_and(mask, sd->span, p->cpus_allowed);
-
-	for_each_cpu_mask(i, mask) {
-		load = target_load(i);
-
-		if (load < min_load) {
-			min_cpu = i;
-			min_load = load;
-
-			/* break out early on an idle CPU: */
-			if (!min_load)
-				break;
-		}
-	}
-
-	/* add +1 to account for the new task */
-	this_load = source_load(this_cpu) + SCHED_LOAD_SCALE;
-
-	/*
-	 * Would with the addition of the new task to the
-	 * current CPU there be an imbalance between this
-	 * CPU and the idlest CPU?
-	 *
-	 * Use half of the balancing threshold - new-context is
-	 * a good opportunity to balance.
-	 */
-	if (min_load*(100 + (sd->imbalance_pct-100)/2) < this_load*100)
-		return min_cpu;
-
-	return this_cpu;
-}
-
-/*
  * If dest_cpu is allowed for this process, migrate the task to it.
  * This is accomplished by forcing the cpu_allowed mask to only
  * allow dest_cpu, which will force the cpu onto dest_cpu.  Then
@@ -1571,37 +1712,16 @@ out:
 }
 
 /*
- * sched_exec(): find the highest-level, exec-balance-capable
- * domain and try to migrate the task to the least loaded CPU.
- *
- * execve() is a valuable balancing opportunity, because at this point
- * the task has the smallest effective memory and cache footprint.
+ * sched_exec - execve() is a valuable balancing opportunity, because at
+ * this point the task has the smallest effective memory and cache footprint.
  */
 void sched_exec(void)
 {
-	struct sched_domain *tmp, *sd = NULL;
 	int new_cpu, this_cpu = get_cpu();
-
-	/* Prefer the current CPU if there's only this task running */
-	if (this_rq()->nr_running <= 1)
-		goto out;
-
-	for_each_domain(this_cpu, tmp)
-		if (tmp->flags & SD_BALANCE_EXEC)
-			sd = tmp;
-
-	if (sd) {
-		schedstat_inc(sd, sbe_attempts);
-		new_cpu = find_idlest_cpu(current, this_cpu, sd);
-		if (new_cpu != this_cpu) {
-			schedstat_inc(sd, sbe_pushed);
-			put_cpu();
-			sched_migrate_task(current, new_cpu);
-			return;
-		}
-	}
-out:
+	new_cpu = sched_balance_self(this_cpu, SD_BALANCE_EXEC);
 	put_cpu();
+	if (new_cpu != this_cpu)
+		sched_migrate_task(current, new_cpu);
 }
 
 /*
@@ -1632,7 +1752,7 @@ void pull_task(runqueue_t *src_rq, prio_
  */
 static inline
 int can_migrate_task(task_t *p, runqueue_t *rq, int this_cpu,
-		     struct sched_domain *sd, enum idle_type idle)
+	     struct sched_domain *sd, enum idle_type idle, int *all_pinned)
 {
 	/*
 	 * We do not migrate tasks that are:
@@ -1640,23 +1760,24 @@ int can_migrate_task(task_t *p, runqueue
 	 * 2) cannot be migrated to this CPU due to cpus_allowed, or
 	 * 3) are cache-hot on their current CPU.
 	 */
-	if (task_running(rq, p))
-		return 0;
 	if (!cpu_isset(this_cpu, p->cpus_allowed))
 		return 0;
+	*all_pinned = 0;
+
+	if (task_running(rq, p))
+		return 0;
 
 	/*
 	 * Aggressive migration if:
-	 * 1) the [whole] cpu is idle, or
+	 * 1) task is cache cold, or
 	 * 2) too many balance attempts have failed.
 	 */
 
-	if (cpu_and_siblings_are_idle(this_cpu) || \
-			sd->nr_balance_failed > sd->cache_nice_tries)
+	if (sd->nr_balance_failed > sd->cache_nice_tries)
 		return 1;
 
 	if (task_hot(p, rq->timestamp_last_tick, sd))
-			return 0;
+		return 0;
 	return 1;
 }
 
@@ -1669,16 +1790,18 @@ int can_migrate_task(task_t *p, runqueue
  */
 static int move_tasks(runqueue_t *this_rq, int this_cpu, runqueue_t *busiest,
 		      unsigned long max_nr_move, struct sched_domain *sd,
-		      enum idle_type idle)
+		      enum idle_type idle, int *all_pinned)
 {
 	prio_array_t *array, *dst_array;
 	struct list_head *head, *curr;
-	int idx, pulled = 0;
+	int idx, pulled = 0, pinned = 0;
 	task_t *tmp;
 
-	if (max_nr_move <= 0 || busiest->nr_running <= 1)
+	if (max_nr_move == 0)
 		goto out;
 
+	pinned = 1;
+
 	/*
 	 * We first consider expired tasks. Those will likely not be
 	 * executed in the near future, and they are most likely to
@@ -1717,7 +1840,7 @@ skip_queue:
 
 	curr = curr->prev;
 
-	if (!can_migrate_task(tmp, busiest, this_cpu, sd, idle)) {
+	if (!can_migrate_task(tmp, busiest, this_cpu, sd, idle, &pinned)) {
 		if (curr != head)
 			goto skip_queue;
 		idx++;
@@ -1746,6 +1869,9 @@ out:
 	 * inside pull_task().
 	 */
 	schedstat_add(sd, lb_gained[idle], pulled);
+
+	if (all_pinned)
+		*all_pinned = pinned;
 	return pulled;
 }
 
@@ -1760,8 +1886,15 @@ find_busiest_group(struct sched_domain *
 {
 	struct sched_group *busiest = NULL, *this = NULL, *group = sd->groups;
 	unsigned long max_load, avg_load, total_load, this_load, total_pwr;
+	int load_idx;
 
 	max_load = this_load = total_load = total_pwr = 0;
+	if (idle == NOT_IDLE)
+		load_idx = sd->busy_idx;
+	else if (idle == NEWLY_IDLE)
+		load_idx = sd->newidle_idx;
+	else
+		load_idx = sd->idle_idx;
 
 	do {
 		unsigned long load;
@@ -1776,9 +1909,9 @@ find_busiest_group(struct sched_domain *
 		for_each_cpu_mask(i, group->cpumask) {
 			/* Bias balancing toward cpus of our domain */
 			if (local_group)
-				load = target_load(i);
+				load = target_load(i, load_idx);
 			else
-				load = source_load(i);
+				load = source_load(i, load_idx);
 
 			avg_load += load;
 		}
@@ -1792,12 +1925,10 @@ find_busiest_group(struct sched_domain *
 		if (local_group) {
 			this_load = avg_load;
 			this = group;
-			goto nextgroup;
 		} else if (avg_load > max_load) {
 			max_load = avg_load;
 			busiest = group;
 		}
-nextgroup:
 		group = group->next;
 	} while (group != sd->groups);
 
@@ -1870,15 +2001,9 @@ nextgroup:
 
 	/* Get rid of the scaling factor, rounding down as we divide */
 	*imbalance = *imbalance / SCHED_LOAD_SCALE;
-
 	return busiest;
 
 out_balanced:
-	if (busiest && (idle == NEWLY_IDLE ||
-			(idle == SCHED_IDLE && max_load > SCHED_LOAD_SCALE)) ) {
-		*imbalance = 1;
-		return busiest;
-	}
 
 	*imbalance = 0;
 	return NULL;
@@ -1894,7 +2019,7 @@ static runqueue_t *find_busiest_queue(st
 	int i;
 
 	for_each_cpu_mask(i, group->cpumask) {
-		load = source_load(i);
+		load = source_load(i, 0);
 
 		if (load > max_load) {
 			max_load = load;
@@ -1906,6 +2031,12 @@ static runqueue_t *find_busiest_queue(st
 }
 
 /*
+ * Max backoff if we encounter pinned tasks. Pretty arbitrary value, but
+ * so long as it is large enough.
+ */
+#define MAX_PINNED_INTERVAL	512
+
+/*
  * Check this_cpu to ensure it is balanced within domain. Attempt to move
  * tasks if there is an imbalance.
  *
@@ -1917,7 +2048,8 @@ static int load_balance(int this_cpu, ru
 	struct sched_group *group;
 	runqueue_t *busiest;
 	unsigned long imbalance;
-	int nr_moved;
+	int nr_moved, all_pinned = 0;
+	int active_balance = 0;
 
 	spin_lock(&this_rq->lock);
 	schedstat_inc(sd, lb_cnt[idle]);
@@ -1934,15 +2066,7 @@ static int load_balance(int this_cpu, ru
 		goto out_balanced;
 	}
 
-	/*
-	 * This should be "impossible", but since load
-	 * balancing is inherently racy and statistical,
-	 * it could happen in theory.
-	 */
-	if (unlikely(busiest == this_rq)) {
-		WARN_ON(1);
-		goto out_balanced;
-	}
+	BUG_ON(busiest == this_rq);
 
 	schedstat_add(sd, lb_imbalance[idle], imbalance);
 
@@ -1956,9 +2080,15 @@ static int load_balance(int this_cpu, ru
 		 */
 		double_lock_balance(this_rq, busiest);
 		nr_moved = move_tasks(this_rq, this_cpu, busiest,
-						imbalance, sd, idle);
+						imbalance, sd, idle,
+						&all_pinned);
 		spin_unlock(&busiest->lock);
+
+		/* All tasks on this runqueue were pinned by CPU affinity */
+		if (unlikely(all_pinned))
+			goto out_balanced;
 	}
+
 	spin_unlock(&this_rq->lock);
 
 	if (!nr_moved) {
@@ -1966,36 +2096,38 @@ static int load_balance(int this_cpu, ru
 		sd->nr_balance_failed++;
 
 		if (unlikely(sd->nr_balance_failed > sd->cache_nice_tries+2)) {
-			int wake = 0;
 
 			spin_lock(&busiest->lock);
 			if (!busiest->active_balance) {
 				busiest->active_balance = 1;
 				busiest->push_cpu = this_cpu;
-				wake = 1;
+				active_balance = 1;
 			}
 			spin_unlock(&busiest->lock);
-			if (wake)
+			if (active_balance)
 				wake_up_process(busiest->migration_thread);
 
 			/*
 			 * We've kicked active balancing, reset the failure
 			 * counter.
 			 */
-			sd->nr_balance_failed = sd->cache_nice_tries;
+			sd->nr_balance_failed = sd->cache_nice_tries+1;
 		}
-
-		/*
-		 * We were unbalanced, but unsuccessful in move_tasks(),
-		 * so bump the balance_interval to lessen the lock contention.
-		 */
-		if (sd->balance_interval < sd->max_interval)
-			sd->balance_interval++;
-	} else {
+	} else
 		sd->nr_balance_failed = 0;
 
+	if (likely(!active_balance)) {
 		/* We were unbalanced, so reset the balancing interval */
 		sd->balance_interval = sd->min_interval;
+	} else {
+		/*
+		 * If we've begun active balancing, start to back off. This
+		 * case may not be covered by the all_pinned logic if there
+		 * is only 1 task on the busy runqueue (because we don't call
+		 * move_tasks).
+		 */
+		if (sd->balance_interval < sd->max_interval)
+			sd->balance_interval *= 2;
 	}
 
 	return nr_moved;
@@ -2005,8 +2137,10 @@ out_balanced:
 
 	schedstat_inc(sd, lb_balanced[idle]);
 
+	sd->nr_balance_failed = 0;
 	/* tune up the balancing interval */
-	if (sd->balance_interval < sd->max_interval)
+	if ((all_pinned && sd->balance_interval < MAX_PINNED_INTERVAL) ||
+			(sd->balance_interval < sd->max_interval))
 		sd->balance_interval *= 2;
 
 	return 0;
@@ -2030,31 +2164,36 @@ static int load_balance_newidle(int this
 	schedstat_inc(sd, lb_cnt[NEWLY_IDLE]);
 	group = find_busiest_group(sd, this_cpu, &imbalance, NEWLY_IDLE);
 	if (!group) {
-		schedstat_inc(sd, lb_balanced[NEWLY_IDLE]);
 		schedstat_inc(sd, lb_nobusyg[NEWLY_IDLE]);
-		goto out;
+		goto out_balanced;
 	}
 
 	busiest = find_busiest_queue(group);
-	if (!busiest || busiest == this_rq) {
-		schedstat_inc(sd, lb_balanced[NEWLY_IDLE]);
+	if (!busiest) {
 		schedstat_inc(sd, lb_nobusyq[NEWLY_IDLE]);
-		goto out;
+		goto out_balanced;
 	}
 
+	BUG_ON(busiest == this_rq);
+
 	/* Attempt to move tasks */
 	double_lock_balance(this_rq, busiest);
 
 	schedstat_add(sd, lb_imbalance[NEWLY_IDLE], imbalance);
 	nr_moved = move_tasks(this_rq, this_cpu, busiest,
-					imbalance, sd, NEWLY_IDLE);
+					imbalance, sd, NEWLY_IDLE, NULL);
 	if (!nr_moved)
 		schedstat_inc(sd, lb_failed[NEWLY_IDLE]);
+	else
+		sd->nr_balance_failed = 0;
 
 	spin_unlock(&busiest->lock);
-
-out:
 	return nr_moved;
+
+out_balanced:
+	schedstat_inc(sd, lb_balanced[NEWLY_IDLE]);
+	sd->nr_balance_failed = 0;
+	return 0;
 }
 
 /*
@@ -2086,56 +2225,42 @@ static inline void idle_balance(int this
 static void active_load_balance(runqueue_t *busiest_rq, int busiest_cpu)
 {
 	struct sched_domain *sd;
-	struct sched_group *cpu_group;
 	runqueue_t *target_rq;
-	cpumask_t visited_cpus;
-	int cpu;
+	int target_cpu = busiest_rq->push_cpu;
+
+	if (busiest_rq->nr_running <= 1)
+		/* no task to move */
+		return;
+
+	target_rq = cpu_rq(target_cpu);
 
 	/*
-	 * Search for suitable CPUs to push tasks to in successively higher
-	 * domains with SD_LOAD_BALANCE set.
+	 * This condition is "impossible", if it occurs
+	 * we need to fix it.  Originally reported by
+	 * Bjorn Helgaas on a 128-cpu setup.
 	 */
-	visited_cpus = CPU_MASK_NONE;
-	for_each_domain(busiest_cpu, sd) {
-		if (!(sd->flags & SD_LOAD_BALANCE))
-			/* no more domains to search */
-			break;
+	BUG_ON(busiest_rq == target_rq);
 
-		schedstat_inc(sd, alb_cnt);
+	/* move a task from busiest_rq to target_rq */
+	double_lock_balance(busiest_rq, target_rq);
 
-		cpu_group = sd->groups;
-		do {
-			for_each_cpu_mask(cpu, cpu_group->cpumask) {
-				if (busiest_rq->nr_running <= 1)
-					/* no more tasks left to move */
-					return;
-				if (cpu_isset(cpu, visited_cpus))
-					continue;
-				cpu_set(cpu, visited_cpus);
-				if (!cpu_and_siblings_are_idle(cpu) || cpu == busiest_cpu)
-					continue;
+	/* Search for an sd spanning us and the target CPU. */
+	for_each_domain(target_cpu, sd)
+		if ((sd->flags & SD_LOAD_BALANCE) &&
+			cpu_isset(busiest_cpu, sd->span))
+				break;
 
-				target_rq = cpu_rq(cpu);
-				/*
-				 * This condition is "impossible", if it occurs
-				 * we need to fix it.  Originally reported by
-				 * Bjorn Helgaas on a 128-cpu setup.
-				 */
-				BUG_ON(busiest_rq == target_rq);
+	if (unlikely(sd == NULL))
+		goto out;
 
-				/* move a task from busiest_rq to target_rq */
-				double_lock_balance(busiest_rq, target_rq);
-				if (move_tasks(target_rq, cpu, busiest_rq,
-						1, sd, SCHED_IDLE)) {
-					schedstat_inc(sd, alb_pushed);
-				} else {
-					schedstat_inc(sd, alb_failed);
-				}
-				spin_unlock(&target_rq->lock);
-			}
-			cpu_group = cpu_group->next;
-		} while (cpu_group != sd->groups);
-	}
+	schedstat_inc(sd, alb_cnt);
+
+	if (move_tasks(target_rq, target_cpu, busiest_rq, 1, sd, SCHED_IDLE, NULL))
+		schedstat_inc(sd, alb_pushed);
+	else
+		schedstat_inc(sd, alb_failed);
+out:
+	spin_unlock(&target_rq->lock);
 }
 
 /*
@@ -2156,18 +2281,23 @@ static void rebalance_tick(int this_cpu,
 	unsigned long old_load, this_load;
 	unsigned long j = jiffies + CPU_OFFSET(this_cpu);
 	struct sched_domain *sd;
+	int i;
 
-	/* Update our load */
-	old_load = this_rq->cpu_load;
 	this_load = this_rq->nr_running * SCHED_LOAD_SCALE;
-	/*
-	 * Round up the averaging division if load is increasing. This
-	 * prevents us from getting stuck on 9 if the load is 10, for
-	 * example.
-	 */
-	if (this_load > old_load)
-		old_load++;
-	this_rq->cpu_load = (old_load + this_load) / 2;
+	/* Update our load */
+	for (i = 0; i < 3; i++) {
+		unsigned long new_load = this_load;
+		int scale = 1 << i;
+		old_load = this_rq->cpu_load[i];
+		/*
+		 * Round up the averaging division if load is increasing. This
+		 * prevents us from getting stuck on 9 if the load is 10, for
+		 * example.
+		 */
+		if (new_load > old_load)
+			new_load += scale-1;
+		this_rq->cpu_load[i] = (old_load*(scale-1) + new_load) / scale;
+	}
 
 	for_each_domain(this_cpu, sd) {
 		unsigned long interval;
@@ -2447,11 +2577,15 @@ out:
 #ifdef CONFIG_SCHED_SMT
 static inline void wake_sleeping_dependent(int this_cpu, runqueue_t *this_rq)
 {
-	struct sched_domain *sd = this_rq->sd;
+	struct sched_domain *tmp, *sd = NULL;
 	cpumask_t sibling_map;
 	int i;
 
-	if (!(sd->flags & SD_SHARE_CPUPOWER))
+	for_each_domain(this_cpu, tmp)
+		if (tmp->flags & SD_SHARE_CPUPOWER)
+			sd = tmp;
+
+	if (!sd)
 		return;
 
 	/*
@@ -2492,13 +2626,17 @@ static inline void wake_sleeping_depende
 
 static inline int dependent_sleeper(int this_cpu, runqueue_t *this_rq)
 {
-	struct sched_domain *sd = this_rq->sd;
+	struct sched_domain *tmp, *sd = NULL;
 	cpumask_t sibling_map;
 	prio_array_t *array;
 	int ret = 0, i;
 	task_t *p;
 
-	if (!(sd->flags & SD_SHARE_CPUPOWER))
+	for_each_domain(this_cpu, tmp)
+		if (tmp->flags & SD_SHARE_CPUPOWER)
+			sd = tmp;
+
+	if (!sd)
 		return 0;
 
 	/*
@@ -2576,7 +2714,7 @@ void fastcall add_preempt_count(int val)
 	/*
 	 * Underflow?
 	 */
-	BUG_ON(((int)preempt_count() < 0));
+	BUG_ON((preempt_count() < 0));
 	preempt_count() += val;
 	/*
 	 * Spinlock count overflowing soon?
@@ -2613,7 +2751,7 @@ asmlinkage void __sched schedule(void)
 	struct list_head *queue;
 	unsigned long long now;
 	unsigned long run_time;
-	int cpu, idx;
+	int cpu, idx, new_prio;
 
 	/*
 	 * Test if we are atomic.  Since do_exit() needs to call into
@@ -2735,9 +2873,14 @@ go_idle:
 			delta = delta * (ON_RUNQUEUE_WEIGHT * 128 / 100) / 128;
 
 		array = next->array;
-		dequeue_task(next, array);
-		recalc_task_prio(next, next->timestamp + delta);
-		enqueue_task(next, array);
+		new_prio = recalc_task_prio(next, next->timestamp + delta);
+
+		if (unlikely(next->prio != new_prio)) {
+			dequeue_task(next, array);
+			next->prio = new_prio;
+			enqueue_task(next, array);
+		} else
+			requeue_task(next, array);
 	}
 	next->activated = 0;
 switch_tasks:
@@ -2761,11 +2904,15 @@ switch_tasks:
 		rq->curr = next;
 		++*switch_count;
 
-		prepare_arch_switch(rq, next);
+		prepare_task_switch(rq, next);
 		prev = context_switch(rq, prev, next);
 		barrier();
-
-		finish_task_switch(prev);
+		/*
+		 * this_rq must be evaluated again because prev may have moved
+		 * CPUs since it called schedule(), thus the 'rq' on its stack
+		 * frame will be invalid.
+		 */
+		finish_task_switch(this_rq(), prev);
 	} else
 		spin_unlock_irq(&rq->lock);
 
@@ -2869,7 +3016,7 @@ need_resched:
 
 int default_wake_function(wait_queue_t *curr, unsigned mode, int sync, void *key)
 {
-	task_t *p = curr->task;
+	task_t *p = curr->private;
 	return try_to_wake_up(p, mode, sync);
 }
 
@@ -3231,8 +3378,8 @@ EXPORT_SYMBOL(set_user_nice);
  */
 int can_nice(const task_t *p, const int nice)
 {
-	/* convert nice value [19,-20] to rlimit style value [0,39] */
-	int nice_rlim = 19 - nice;
+	/* convert nice value [19,-20] to rlimit style value [1,40] */
+	int nice_rlim = 20 - nice;
 	return (nice_rlim <= p->signal->rlim[RLIMIT_NICE].rlim_cur ||
 		capable(CAP_SYS_NICE));
 }
@@ -3301,15 +3448,7 @@ int task_nice(const task_t *p)
 {
 	return TASK_NICE(p);
 }
-
-/*
- * The only users of task_nice are binfmt_elf and binfmt_elf32.
- * binfmt_elf is no longer modular, but binfmt_elf32 still is.
- * Therefore, task_nice is needed if there is a compat_mode.
- */
-#ifdef CONFIG_COMPAT
 EXPORT_SYMBOL_GPL(task_nice);
-#endif
 
 /**
  * idle_cpu - is a given cpu idle currently?
@@ -3347,7 +3486,7 @@ static void __setscheduler(struct task_s
 	p->policy = policy;
 	p->rt_priority = prio;
 	if (policy != SCHED_NORMAL)
-		p->prio = MAX_USER_RT_PRIO-1 - p->rt_priority;
+		p->prio = MAX_RT_PRIO-1 - p->rt_priority;
 	else
 		p->prio = p->static_prio;
 }
@@ -3379,18 +3518,31 @@ recheck:
 	 * 1..MAX_USER_RT_PRIO-1, valid priority for SCHED_NORMAL is 0.
 	 */
 	if (param->sched_priority < 0 ||
-	    param->sched_priority > MAX_USER_RT_PRIO-1)
+	    (p->mm &&  param->sched_priority > MAX_USER_RT_PRIO-1) ||
+	    (!p->mm && param->sched_priority > MAX_RT_PRIO-1))
 		return -EINVAL;
 	if ((policy == SCHED_NORMAL) != (param->sched_priority == 0))
 		return -EINVAL;
 
-	if ((policy == SCHED_FIFO || policy == SCHED_RR) &&
-	    param->sched_priority > p->signal->rlim[RLIMIT_RTPRIO].rlim_cur &&
-	    !capable(CAP_SYS_NICE))
-		return -EPERM;
-	if ((current->euid != p->euid) && (current->euid != p->uid) &&
-	    !capable(CAP_SYS_NICE))
-		return -EPERM;
+	/*
+	 * Allow unprivileged RT tasks to decrease priority:
+	 */
+	if (!capable(CAP_SYS_NICE)) {
+		/* can't change policy */
+		if (policy != p->policy &&
+			!p->signal->rlim[RLIMIT_RTPRIO].rlim_cur)
+			return -EPERM;
+		/* can't increase priority */
+		if (policy != SCHED_NORMAL &&
+		    param->sched_priority > p->rt_priority &&
+		    param->sched_priority >
+				p->signal->rlim[RLIMIT_RTPRIO].rlim_cur)
+			return -EPERM;
+		/* can't change other user's priorities */
+		if ((current->euid != p->euid) &&
+		    (current->euid != p->uid))
+			return -EPERM;
+	}
 
 	retval = security_task_setscheduler(p, policy, param);
 	if (retval)
@@ -3727,6 +3879,13 @@ asmlinkage long sys_sched_yield(void)
 
 static inline void __cond_resched(void)
 {
+	/*
+	 * The BKS might be reacquired before we have dropped
+	 * PREEMPT_ACTIVE, which could trigger a second
+	 * cond_resched() call.
+	 */
+	if (unlikely(preempt_count()))
+		return;
 	do {
 		add_preempt_count(PREEMPT_ACTIVE);
 		schedule();
@@ -3814,7 +3973,7 @@ EXPORT_SYMBOL(yield);
  */
 void __sched io_schedule(void)
 {
-	struct runqueue *rq = &per_cpu(runqueues, _smp_processor_id());
+	struct runqueue *rq = &per_cpu(runqueues, raw_smp_processor_id());
 
 	atomic_inc(&rq->nr_iowait);
 	schedule();
@@ -3825,7 +3984,7 @@ EXPORT_SYMBOL(io_schedule);
 
 long __sched io_schedule_timeout(long timeout)
 {
-	struct runqueue *rq = &per_cpu(runqueues, _smp_processor_id());
+	struct runqueue *rq = &per_cpu(runqueues, raw_smp_processor_id());
 	long ret;
 
 	atomic_inc(&rq->nr_iowait);
@@ -4016,6 +4175,14 @@ void show_state(void)
 	read_unlock(&tasklist_lock);
 }
 
+/**
+ * init_idle - set up an idle thread for a given CPU
+ * @idle: task in question
+ * @cpu: cpu the idle task belongs to
+ *
+ * NOTE: this function does not set the idle thread's NEED_RESCHED
+ * flag, to make booting more robust.
+ */
 void __devinit init_idle(task_t *idle, int cpu)
 {
 	runqueue_t *rq = cpu_rq(cpu);
@@ -4030,7 +4197,9 @@ void __devinit init_idle(task_t *idle, i
 
 	spin_lock_irqsave(&rq->lock, flags);
 	rq->curr = rq->idle = idle;
-	set_tsk_need_resched(idle);
+#if defined(CONFIG_SMP) && defined(__ARCH_WANT_UNLOCKED_CTXSW)
+	idle->oncpu = 1;
+#endif
 	spin_unlock_irqrestore(&rq->lock, flags);
 
 	/* Set the preempt count _outside_ the spinlocks! */
@@ -4174,8 +4343,7 @@ static int migration_thread(void * data)
 		struct list_head *head;
 		migration_req_t *req;
 
-		if (current->flags & PF_FREEZE)
-			refrigerator(PF_FREEZE);
+		try_to_freeze();
 
 		spin_lock_irq(&rq->lock);
 
@@ -4200,17 +4368,9 @@ static int migration_thread(void * data)
 		req = list_entry(head->next, migration_req_t, list);
 		list_del_init(head->next);
 
-		if (req->type == REQ_MOVE_TASK) {
-			spin_unlock(&rq->lock);
-			__migrate_task(req->task, cpu, req->dest_cpu);
-			local_irq_enable();
-		} else if (req->type == REQ_SET_DOMAIN) {
-			rq->sd = req->sd;
-			spin_unlock_irq(&rq->lock);
-		} else {
-			spin_unlock_irq(&rq->lock);
-			WARN_ON(1);
-		}
+		spin_unlock(&rq->lock);
+		__migrate_task(req->task, cpu, req->dest_cpu);
+		local_irq_enable();
 
 		complete(&req->done);
 	}
@@ -4441,7 +4601,6 @@ static int migration_call(struct notifie
 			migration_req_t *req;
 			req = list_entry(rq->migration_queue.next,
 					 migration_req_t, list);
-			BUG_ON(req->type != REQ_MOVE_TASK);
 			list_del_init(&req->list);
 			complete(&req->done);
 		}
@@ -4472,12 +4631,17 @@ int __init migration_init(void)
 #endif
 
 #ifdef CONFIG_SMP
-#define SCHED_DOMAIN_DEBUG
+#undef SCHED_DOMAIN_DEBUG
 #ifdef SCHED_DOMAIN_DEBUG
 static void sched_domain_debug(struct sched_domain *sd, int cpu)
 {
 	int level = 0;
 
+	if (!sd) {
+		printk(KERN_DEBUG "CPU%d attaching NULL sched-domain.\n", cpu);
+		return;
+	}
+
 	printk(KERN_DEBUG "CPU%d attaching sched-domain:\n", cpu);
 
 	do {
@@ -4560,37 +4724,81 @@ static void sched_domain_debug(struct sc
 #define sched_domain_debug(sd, cpu) {}
 #endif
 
+static int sd_degenerate(struct sched_domain *sd)
+{
+	if (cpus_weight(sd->span) == 1)
+		return 1;
+
+	/* Following flags need at least 2 groups */
+	if (sd->flags & (SD_LOAD_BALANCE |
+			 SD_BALANCE_NEWIDLE |
+			 SD_BALANCE_FORK |
+			 SD_BALANCE_EXEC)) {
+		if (sd->groups != sd->groups->next)
+			return 0;
+	}
+
+	/* Following flags don't use groups */
+	if (sd->flags & (SD_WAKE_IDLE |
+			 SD_WAKE_AFFINE |
+			 SD_WAKE_BALANCE))
+		return 0;
+
+	return 1;
+}
+
+static int sd_parent_degenerate(struct sched_domain *sd,
+						struct sched_domain *parent)
+{
+	unsigned long cflags = sd->flags, pflags = parent->flags;
+
+	if (sd_degenerate(parent))
+		return 1;
+
+	if (!cpus_equal(sd->span, parent->span))
+		return 0;
+
+	/* Does parent contain flags not in child? */
+	/* WAKE_BALANCE is a subset of WAKE_AFFINE */
+	if (cflags & SD_WAKE_AFFINE)
+		pflags &= ~SD_WAKE_BALANCE;
+	/* Flags needing groups don't count if only 1 group in parent */
+	if (parent->groups == parent->groups->next) {
+		pflags &= ~(SD_LOAD_BALANCE |
+				SD_BALANCE_NEWIDLE |
+				SD_BALANCE_FORK |
+				SD_BALANCE_EXEC);
+	}
+	if (~cflags & pflags)
+		return 0;
+
+	return 1;
+}
+
 /*
  * Attach the domain 'sd' to 'cpu' as its base domain.  Callers must
  * hold the hotplug lock.
  */
-void __devinit cpu_attach_domain(struct sched_domain *sd, int cpu)
+void cpu_attach_domain(struct sched_domain *sd, int cpu)
 {
-	migration_req_t req;
-	unsigned long flags;
 	runqueue_t *rq = cpu_rq(cpu);
-	int local = 1;
-
-	sched_domain_debug(sd, cpu);
-
-	spin_lock_irqsave(&rq->lock, flags);
+	struct sched_domain *tmp;
 
-	if (cpu == smp_processor_id() || !cpu_online(cpu)) {
-		rq->sd = sd;
-	} else {
-		init_completion(&req.done);
-		req.type = REQ_SET_DOMAIN;
-		req.sd = sd;
-		list_add(&req.list, &rq->migration_queue);
-		local = 0;
+	/* Remove the sched domains which do not contribute to scheduling. */
+	for (tmp = sd; tmp; tmp = tmp->parent) {
+		struct sched_domain *parent = tmp->parent;
+		if (!parent)
+			break;
+		if (sd_parent_degenerate(tmp, parent))
+			tmp->parent = parent->parent;
 	}
 
-	spin_unlock_irqrestore(&rq->lock, flags);
+	if (sd && sd_degenerate(sd))
+		sd = sd->parent;
 
-	if (!local) {
-		wake_up_process(rq->migration_thread);
-		wait_for_completion(&req.done);
-	}
+	sched_domain_debug(sd, cpu);
+
+	rcu_assign_pointer(rq->sd, sd);
 }
 
 /* cpus with isolated domains */
@@ -4622,7 +4830,7 @@ __setup ("isolcpus=", isolated_cpu_setup
  * covered by the given span, and will set each group's ->cpumask correctly,
  * and ->cpu_power to 0.
  */
-void __devinit init_sched_build_groups(struct sched_group groups[],
+void init_sched_build_groups(struct sched_group groups[],
 			cpumask_t span, int (*group_fn)(int cpu))
 {
 	struct sched_group *first = NULL, *last = NULL;
@@ -4658,13 +4866,14 @@ void __devinit init_sched_build_groups(s
 
 
 #ifdef ARCH_HAS_SCHED_DOMAIN
-extern void __devinit arch_init_sched_domains(void);
-extern void __devinit arch_destroy_sched_domains(void);
+extern void build_sched_domains(const cpumask_t *cpu_map);
+extern void arch_init_sched_domains(const cpumask_t *cpu_map);
+extern void arch_destroy_sched_domains(const cpumask_t *cpu_map);
 #else
 #ifdef CONFIG_SCHED_SMT
 static DEFINE_PER_CPU(struct sched_domain, cpu_domains);
 static struct sched_group sched_group_cpus[NR_CPUS];
-static int __devinit cpu_to_cpu_group(int cpu)
+static int cpu_to_cpu_group(int cpu)
 {
 	return cpu;
 }
@@ -4672,7 +4881,7 @@ static int __devinit cpu_to_cpu_group(in
 
 static DEFINE_PER_CPU(struct sched_domain, phys_domains);
 static struct sched_group sched_group_phys[NR_CPUS];
-static int __devinit cpu_to_phys_group(int cpu)
+static int cpu_to_phys_group(int cpu)
 {
 #ifdef CONFIG_SCHED_SMT
 	return first_cpu(cpu_sibling_map[cpu]);
@@ -4685,7 +4894,7 @@ static int __devinit cpu_to_phys_group(i
 
 static DEFINE_PER_CPU(struct sched_domain, node_domains);
 static struct sched_group sched_group_nodes[MAX_NUMNODES];
-static int __devinit cpu_to_node_group(int cpu)
+static int cpu_to_node_group(int cpu)
 {
 	return cpu_to_node(cpu);
 }
@@ -4716,39 +4925,28 @@ static void check_sibling_maps(void)
 #endif
 
 /*
- * Set up scheduler domains and groups.  Callers must hold the hotplug lock.
+ * Build sched domains for a given set of cpus and attach the sched domains
+ * to the individual cpus
  */
-static void __devinit arch_init_sched_domains(void)
+static void build_sched_domains(const cpumask_t *cpu_map)
 {
 	int i;
-	cpumask_t cpu_default_map;
 
-#if defined(CONFIG_SCHED_SMT) && defined(CONFIG_NUMA)
-	check_sibling_maps();
-#endif
 	/*
-	 * Setup mask for cpus without special case scheduling requirements.
-	 * For now this just excludes isolated cpus, but could be used to
-	 * exclude other special cases in the future.
-	 */
-	cpus_complement(cpu_default_map, cpu_isolated_map);
-	cpus_and(cpu_default_map, cpu_default_map, cpu_online_map);
-
-	/*
-	 * Set up domains. Isolated domains just stay on the dummy domain.
+	 * Set up domains for cpus specified by the cpu_map.
 	 */
-	for_each_cpu_mask(i, cpu_default_map) {
+	for_each_cpu_mask(i, *cpu_map) {
 		int group;
 		struct sched_domain *sd = NULL, *p;
 		cpumask_t nodemask = node_to_cpumask(cpu_to_node(i));
 
-		cpus_and(nodemask, nodemask, cpu_default_map);
+		cpus_and(nodemask, nodemask, *cpu_map);
 
 #ifdef CONFIG_NUMA
 		sd = &per_cpu(node_domains, i);
 		group = cpu_to_node_group(i);
 		*sd = SD_NODE_INIT;
-		sd->span = cpu_default_map;
+		sd->span = *cpu_map;
 		sd->groups = &sched_group_nodes[group];
 #endif
 
@@ -4766,7 +4964,7 @@ static void __devinit arch_init_sched_do
 		group = cpu_to_cpu_group(i);
 		*sd = SD_SIBLING_INIT;
 		sd->span = cpu_sibling_map[i];
-		cpus_and(sd->span, sd->span, cpu_default_map);
+		cpus_and(sd->span, sd->span, *cpu_map);
 		sd->parent = p;
 		sd->groups = &sched_group_cpus[group];
 #endif
@@ -4776,7 +4974,7 @@ static void __devinit arch_init_sched_do
 	/* Set up CPU (sibling) groups */
 	for_each_online_cpu(i) {
 		cpumask_t this_sibling_map = cpu_sibling_map[i];
-		cpus_and(this_sibling_map, this_sibling_map, cpu_default_map);
+		cpus_and(this_sibling_map, this_sibling_map, *cpu_map);
 		if (i != first_cpu(this_sibling_map))
 			continue;
 
@@ -4789,7 +4987,7 @@ static void __devinit arch_init_sched_do
 	for (i = 0; i < MAX_NUMNODES; i++) {
 		cpumask_t nodemask = node_to_cpumask(i);
 
-		cpus_and(nodemask, nodemask, cpu_default_map);
+		cpus_and(nodemask, nodemask, *cpu_map);
 		if (cpus_empty(nodemask))
 			continue;
 
@@ -4799,12 +4997,12 @@ static void __devinit arch_init_sched_do
 
 #ifdef CONFIG_NUMA
 	/* Set up node groups */
-	init_sched_build_groups(sched_group_nodes, cpu_default_map,
+	init_sched_build_groups(sched_group_nodes, *cpu_map,
 					&cpu_to_node_group);
 #endif
 
 	/* Calculate CPU power for physical packages and nodes */
-	for_each_cpu_mask(i, cpu_default_map) {
+	for_each_cpu_mask(i, *cpu_map) {
 		int power;
 		struct sched_domain *sd;
 #ifdef CONFIG_SCHED_SMT
@@ -4828,7 +5026,7 @@ static void __devinit arch_init_sched_do
 	}
 
 	/* Attach the domains */
-	for_each_online_cpu(i) {
+	for_each_cpu_mask(i, *cpu_map) {
 		struct sched_domain *sd;
 #ifdef CONFIG_SCHED_SMT
 		sd = &per_cpu(cpu_domains, i);
@@ -4838,41 +5036,85 @@ static void __devinit arch_init_sched_do
 		cpu_attach_domain(sd, i);
 	}
 }
+/*
+ * Set up scheduler domains and groups.  Callers must hold the hotplug lock.
+ */
+static void arch_init_sched_domains(cpumask_t *cpu_map)
+{
+	cpumask_t cpu_default_map;
+
+#if defined(CONFIG_SCHED_SMT) && defined(CONFIG_NUMA)
+	check_sibling_maps();
+#endif
+	/*
+	 * Setup mask for cpus without special case scheduling requirements.
+	 * For now this just excludes isolated cpus, but could be used to
+	 * exclude other special cases in the future.
+	 */
+	cpus_andnot(cpu_default_map, *cpu_map, cpu_isolated_map);
+
+	build_sched_domains(&cpu_default_map);
+}
 
-#ifdef CONFIG_HOTPLUG_CPU
-static void __devinit arch_destroy_sched_domains(void)
+static void arch_destroy_sched_domains(const cpumask_t *cpu_map)
 {
 	/* Do nothing: everything is statically allocated. */
 }
-#endif
 
 #endif /* ARCH_HAS_SCHED_DOMAIN */
 
 /*
- * Initial dummy domain for early boot and for hotplug cpu. Being static,
- * it is initialized to zero, so all balancing flags are cleared which is
- * what we want.
+ * Detach sched domains from a group of cpus specified in cpu_map
+ * These cpus will now be attached to the NULL domain
  */
-static struct sched_domain sched_domain_dummy;
+static inline void detach_destroy_domains(const cpumask_t *cpu_map)
+{
+	int i;
+
+	for_each_cpu_mask(i, *cpu_map)
+		cpu_attach_domain(NULL, i);
+	synchronize_sched();
+	arch_destroy_sched_domains(cpu_map);
+}
+
+/*
+ * Partition sched domains as specified by the cpumasks below.
+ * This attaches all cpus from the cpumasks to the NULL domain,
+ * waits for a RCU quiescent period, recalculates sched
+ * domain information and then attaches them back to the
+ * correct sched domains
+ * Call with hotplug lock held
+ */
+void partition_sched_domains(cpumask_t *partition1, cpumask_t *partition2)
+{
+	cpumask_t change_map;
+
+	cpus_and(*partition1, *partition1, cpu_online_map);
+	cpus_and(*partition2, *partition2, cpu_online_map);
+	cpus_or(change_map, *partition1, *partition2);
+
+	/* Detach sched domains from all of the affected cpus */
+	detach_destroy_domains(&change_map);
+	if (!cpus_empty(*partition1))
+		build_sched_domains(partition1);
+	if (!cpus_empty(*partition2))
+		build_sched_domains(partition2);
+}
 
 #ifdef CONFIG_HOTPLUG_CPU
 /*
  * Force a reinitialization of the sched domains hierarchy.  The domains
  * and groups cannot be updated in place without racing with the balancing
- * code, so we temporarily attach all running cpus to a "dummy" domain
+ * code, so we temporarily attach all running cpus to the NULL domain
  * which will prevent rebalancing while the sched domains are recalculated.
  */
 static int update_sched_domains(struct notifier_block *nfb,
 				unsigned long action, void *hcpu)
 {
-	int i;
-
 	switch (action) {
 	case CPU_UP_PREPARE:
 	case CPU_DOWN_PREPARE:
-		for_each_online_cpu(i)
-			cpu_attach_domain(&sched_domain_dummy, i);
-		arch_destroy_sched_domains();
+		detach_destroy_domains(&cpu_online_map);
 		return NOTIFY_OK;
 
 	case CPU_UP_CANCELED:
@@ -4888,7 +5130,7 @@ static int update_sched_domains(struct n
 	}
 
 	/* The hotplug lock is already held by cpu_up/cpu_down */
-	arch_init_sched_domains();
+	arch_init_sched_domains(&cpu_online_map);
 
 	return NOTIFY_OK;
 }
@@ -4897,7 +5139,7 @@ static int update_sched_domains(struct n
 void __init sched_init_smp(void)
 {
 	lock_cpu_hotplug();
-	arch_init_sched_domains();
+	arch_init_sched_domains(&cpu_online_map);
 	unlock_cpu_hotplug();
 	/* XXX: Theoretical race here - CPU may be hotplugged now */
 	hotcpu_notifier(update_sched_domains, 0);
@@ -4927,13 +5169,15 @@ void __init sched_init(void)
 
 		rq = cpu_rq(i);
 		spin_lock_init(&rq->lock);
+		rq->nr_running = 0;
 		rq->active = rq->arrays;
 		rq->expired = rq->arrays + 1;
 		rq->best_expired_prio = MAX_PRIO;
 
 #ifdef CONFIG_SMP
-		rq->sd = &sched_domain_dummy;
-		rq->cpu_load = 0;
+		rq->sd = NULL;
+		for (j = 1; j < 3; j++)
+			rq->cpu_load[j] = 0;
 		rq->active_balance = 0;
 		rq->push_cpu = 0;
 		rq->migration_thread = NULL;
diff --git a/kernel/signal.c b/kernel/signal.c
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -24,6 +24,7 @@
 #include <linux/ptrace.h>
 #include <linux/posix-timers.h>
 #include <linux/signal.h>
+#include <linux/audit.h>
 #include <asm/param.h>
 #include <asm/uaccess.h>
 #include <asm/unistd.h>
@@ -212,6 +213,7 @@ static inline int has_pending_signals(si
 fastcall void recalc_sigpending_tsk(struct task_struct *t)
 {
 	if (t->signal->group_stop_count > 0 ||
+	    (freezing(t)) ||
 	    PENDING(&t->pending, &t->blocked) ||
 	    PENDING(&t->signal->shared_pending, &t->blocked))
 		set_tsk_thread_flag(t, TIF_SIGPENDING);
@@ -667,7 +669,11 @@ static int check_kill_permission(int sig
 	    && (current->uid ^ t->suid) && (current->uid ^ t->uid)
 	    && !capable(CAP_KILL))
 		return error;
-	return security_task_kill(t, info, sig);
+
+	error = security_task_kill(t, info, sig);
+	if (!error)
+		audit_signal_info(sig, t); /* Let audit system see the signal */
+	return error;
 }
 
 /* forward decl */
@@ -686,7 +692,7 @@ static void handle_stop_signal(int sig, 
 {
 	struct task_struct *t;
 
-	if (p->flags & SIGNAL_GROUP_EXIT)
+	if (p->signal->flags & SIGNAL_GROUP_EXIT)
 		/*
 		 * The process is in the middle of dying already.
 		 */
@@ -2225,8 +2231,7 @@ sys_rt_sigtimedwait(const sigset_t __use
 			current->state = TASK_INTERRUPTIBLE;
 			timeout = schedule_timeout(timeout);
 
-			if (current->flags & PF_FREEZE)
-				refrigerator(PF_FREEZE);
+			try_to_freeze();
 			spin_lock_irq(&current->sighand->siglock);
 			sig = dequeue_signal(current, &these, &info);
 			current->blocked = current->real_blocked;
diff --git a/kernel/stop_machine.c b/kernel/stop_machine.c
--- a/kernel/stop_machine.c
+++ b/kernel/stop_machine.c
@@ -100,7 +100,7 @@ static int stop_machine(void)
 	stopmachine_state = STOPMACHINE_WAIT;
 
 	for_each_online_cpu(i) {
-		if (i == _smp_processor_id())
+		if (i == raw_smp_processor_id())
 			continue;
 		ret = kernel_thread(stopmachine, (void *)(long)i,CLONE_KERNEL);
 		if (ret < 0)
@@ -182,7 +182,7 @@ struct task_struct *__stop_machine_run(i
 
 	/* If they don't care which CPU fn runs on, bind to any online one. */
 	if (cpu == NR_CPUS)
-		cpu = _smp_processor_id();
+		cpu = raw_smp_processor_id();
 
 	p = kthread_create(do_stop, &smdata, "kstopmachine");
 	if (!IS_ERR(p)) {
diff --git a/kernel/sys.c b/kernel/sys.c
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -16,6 +16,8 @@
 #include <linux/init.h>
 #include <linux/highuid.h>
 #include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/kexec.h>
 #include <linux/workqueue.h>
 #include <linux/device.h>
 #include <linux/key.h>
@@ -359,6 +361,64 @@ out_unlock:
 	return retval;
 }
 
+void emergency_restart(void)
+{
+	machine_emergency_restart();
+}
+EXPORT_SYMBOL_GPL(emergency_restart);
+
+void kernel_restart(char *cmd)
+{
+	notifier_call_chain(&reboot_notifier_list, SYS_RESTART, cmd);
+	system_state = SYSTEM_RESTART;
+	device_shutdown();
+	if (!cmd) {
+		printk(KERN_EMERG "Restarting system.\n");
+	} else {
+		printk(KERN_EMERG "Restarting system with command '%s'.\n", cmd);
+	}
+	printk(".\n");
+	machine_restart(cmd);
+}
+EXPORT_SYMBOL_GPL(kernel_restart);
+
+void kernel_kexec(void)
+{
+#ifdef CONFIG_KEXEC
+	struct kimage *image;
+	image = xchg(&kexec_image, 0);
+	if (!image) {
+		return;
+	}
+	notifier_call_chain(&reboot_notifier_list, SYS_RESTART, NULL);
+	system_state = SYSTEM_RESTART;
+	device_shutdown();
+	printk(KERN_EMERG "Starting new kernel\n");
+	machine_shutdown();
+	machine_kexec(image);
+#endif
+}
+EXPORT_SYMBOL_GPL(kernel_kexec);
+
+void kernel_halt(void)
+{
+	notifier_call_chain(&reboot_notifier_list, SYS_HALT, NULL);
+	system_state = SYSTEM_HALT;
+	device_shutdown();
+	printk(KERN_EMERG "System halted.\n");
+	machine_halt();
+}
+EXPORT_SYMBOL_GPL(kernel_halt);
+
+void kernel_power_off(void)
+{
+	notifier_call_chain(&reboot_notifier_list, SYS_POWER_OFF, NULL);
+	system_state = SYSTEM_POWER_OFF;
+	device_shutdown();
+	printk(KERN_EMERG "Power down.\n");
+	machine_power_off();
+}
+EXPORT_SYMBOL_GPL(kernel_power_off);
 
 /*
  * Reboot system call: for obvious reasons only root may call it,
@@ -387,11 +447,7 @@ asmlinkage long sys_reboot(int magic1, i
 	lock_kernel();
 	switch (cmd) {
 	case LINUX_REBOOT_CMD_RESTART:
-		notifier_call_chain(&reboot_notifier_list, SYS_RESTART, NULL);
-		system_state = SYSTEM_RESTART;
-		device_shutdown();
-		printk(KERN_EMERG "Restarting system.\n");
-		machine_restart(NULL);
+		kernel_restart(NULL);
 		break;
 
 	case LINUX_REBOOT_CMD_CAD_ON:
@@ -403,21 +459,13 @@ asmlinkage long sys_reboot(int magic1, i
 		break;
 
 	case LINUX_REBOOT_CMD_HALT:
-		notifier_call_chain(&reboot_notifier_list, SYS_HALT, NULL);
-		system_state = SYSTEM_HALT;
-		device_shutdown();
-		printk(KERN_EMERG "System halted.\n");
-		machine_halt();
+		kernel_halt();
 		unlock_kernel();
 		do_exit(0);
 		break;
 
 	case LINUX_REBOOT_CMD_POWER_OFF:
-		notifier_call_chain(&reboot_notifier_list, SYS_POWER_OFF, NULL);
-		system_state = SYSTEM_POWER_OFF;
-		device_shutdown();
-		printk(KERN_EMERG "Power down.\n");
-		machine_power_off();
+		kernel_power_off();
 		unlock_kernel();
 		do_exit(0);
 		break;
@@ -429,13 +477,14 @@ asmlinkage long sys_reboot(int magic1, i
 		}
 		buffer[sizeof(buffer) - 1] = '\0';
 
-		notifier_call_chain(&reboot_notifier_list, SYS_RESTART, buffer);
-		system_state = SYSTEM_RESTART;
-		device_shutdown();
-		printk(KERN_EMERG "Restarting system with command '%s'.\n", buffer);
-		machine_restart(buffer);
+		kernel_restart(buffer);
 		break;
 
+	case LINUX_REBOOT_CMD_KEXEC:
+		kernel_kexec();
+		unlock_kernel();
+		return -EINVAL;
+
 #ifdef CONFIG_SOFTWARE_SUSPEND
 	case LINUX_REBOOT_CMD_SW_SUSPEND:
 		{
@@ -455,8 +504,7 @@ asmlinkage long sys_reboot(int magic1, i
 
 static void deferred_cad(void *dummy)
 {
-	notifier_call_chain(&reboot_notifier_list, SYS_RESTART, NULL);
-	machine_restart(NULL);
+	kernel_restart(NULL);
 }
 
 /*
@@ -525,7 +573,7 @@ asmlinkage long sys_setregid(gid_t rgid,
 	}
 	if (new_egid != old_egid)
 	{
-		current->mm->dumpable = 0;
+		current->mm->dumpable = suid_dumpable;
 		smp_wmb();
 	}
 	if (rgid != (gid_t) -1 ||
@@ -556,7 +604,7 @@ asmlinkage long sys_setgid(gid_t gid)
 	{
 		if(old_egid != gid)
 		{
-			current->mm->dumpable=0;
+			current->mm->dumpable = suid_dumpable;
 			smp_wmb();
 		}
 		current->gid = current->egid = current->sgid = current->fsgid = gid;
@@ -565,7 +613,7 @@ asmlinkage long sys_setgid(gid_t gid)
 	{
 		if(old_egid != gid)
 		{
-			current->mm->dumpable=0;
+			current->mm->dumpable = suid_dumpable;
 			smp_wmb();
 		}
 		current->egid = current->fsgid = gid;
@@ -596,7 +644,7 @@ static int set_user(uid_t new_ruid, int 
 
 	if(dumpclear)
 	{
-		current->mm->dumpable = 0;
+		current->mm->dumpable = suid_dumpable;
 		smp_wmb();
 	}
 	current->uid = new_ruid;
@@ -653,7 +701,7 @@ asmlinkage long sys_setreuid(uid_t ruid,
 
 	if (new_euid != old_euid)
 	{
-		current->mm->dumpable=0;
+		current->mm->dumpable = suid_dumpable;
 		smp_wmb();
 	}
 	current->fsuid = current->euid = new_euid;
@@ -703,7 +751,7 @@ asmlinkage long sys_setuid(uid_t uid)
 
 	if (old_euid != uid)
 	{
-		current->mm->dumpable = 0;
+		current->mm->dumpable = suid_dumpable;
 		smp_wmb();
 	}
 	current->fsuid = current->euid = uid;
@@ -748,7 +796,7 @@ asmlinkage long sys_setresuid(uid_t ruid
 	if (euid != (uid_t) -1) {
 		if (euid != current->euid)
 		{
-			current->mm->dumpable = 0;
+			current->mm->dumpable = suid_dumpable;
 			smp_wmb();
 		}
 		current->euid = euid;
@@ -798,7 +846,7 @@ asmlinkage long sys_setresgid(gid_t rgid
 	if (egid != (gid_t) -1) {
 		if (egid != current->egid)
 		{
-			current->mm->dumpable = 0;
+			current->mm->dumpable = suid_dumpable;
 			smp_wmb();
 		}
 		current->egid = egid;
@@ -845,7 +893,7 @@ asmlinkage long sys_setfsuid(uid_t uid)
 	{
 		if (uid != old_fsuid)
 		{
-			current->mm->dumpable = 0;
+			current->mm->dumpable = suid_dumpable;
 			smp_wmb();
 		}
 		current->fsuid = uid;
@@ -875,7 +923,7 @@ asmlinkage long sys_setfsgid(gid_t gid)
 	{
 		if (gid != old_fsgid)
 		{
-			current->mm->dumpable = 0;
+			current->mm->dumpable = suid_dumpable;
 			smp_wmb();
 		}
 		current->fsgid = gid;
@@ -894,35 +942,69 @@ asmlinkage long sys_times(struct tms __u
 	 */
 	if (tbuf) {
 		struct tms tmp;
-		struct task_struct *tsk = current;
-		struct task_struct *t;
 		cputime_t utime, stime, cutime, cstime;
 
-		read_lock(&tasklist_lock);
-		utime = tsk->signal->utime;
-		stime = tsk->signal->stime;
-		t = tsk;
-		do {
-			utime = cputime_add(utime, t->utime);
-			stime = cputime_add(stime, t->stime);
-			t = next_thread(t);
-		} while (t != tsk);
-
-		/*
-		 * While we have tasklist_lock read-locked, no dying thread
-		 * can be updating current->signal->[us]time.  Instead,
-		 * we got their counts included in the live thread loop.
-		 * However, another thread can come in right now and
-		 * do a wait call that updates current->signal->c[us]time.
-		 * To make sure we always see that pair updated atomically,
-		 * we take the siglock around fetching them.
-		 */
-		spin_lock_irq(&tsk->sighand->siglock);
-		cutime = tsk->signal->cutime;
-		cstime = tsk->signal->cstime;
-		spin_unlock_irq(&tsk->sighand->siglock);
-		read_unlock(&tasklist_lock);
+#ifdef CONFIG_SMP
+		if (thread_group_empty(current)) {
+			/*
+			 * Single thread case without the use of any locks.
+			 *
+			 * We may race with release_task if two threads are
+			 * executing. However, release task first adds up the
+			 * counters (__exit_signal) before  removing the task
+			 * from the process tasklist (__unhash_process).
+			 * __exit_signal also acquires and releases the
+			 * siglock which results in the proper memory ordering
+			 * so that the list modifications are always visible
+			 * after the counters have been updated.
+			 *
+			 * If the counters have been updated by the second thread
+			 * but the thread has not yet been removed from the list
+			 * then the other branch will be executing which will
+			 * block on tasklist_lock until the exit handling of the
+			 * other task is finished.
+			 *
+			 * This also implies that the sighand->siglock cannot
+			 * be held by another processor. So we can also
+			 * skip acquiring that lock.
+			 */
+			utime = cputime_add(current->signal->utime, current->utime);
+			stime = cputime_add(current->signal->utime, current->stime);
+			cutime = current->signal->cutime;
+			cstime = current->signal->cstime;
+		} else
+#endif
+		{
 
+			/* Process with multiple threads */
+			struct task_struct *tsk = current;
+			struct task_struct *t;
+
+			read_lock(&tasklist_lock);
+			utime = tsk->signal->utime;
+			stime = tsk->signal->stime;
+			t = tsk;
+			do {
+				utime = cputime_add(utime, t->utime);
+				stime = cputime_add(stime, t->stime);
+				t = next_thread(t);
+			} while (t != tsk);
+
+			/*
+			 * While we have tasklist_lock read-locked, no dying thread
+			 * can be updating current->signal->[us]time.  Instead,
+			 * we got their counts included in the live thread loop.
+			 * However, another thread can come in right now and
+			 * do a wait call that updates current->signal->c[us]time.
+			 * To make sure we always see that pair updated atomically,
+			 * we take the siglock around fetching them.
+			 */
+			spin_lock_irq(&tsk->sighand->siglock);
+			cutime = tsk->signal->cutime;
+			cstime = tsk->signal->cstime;
+			spin_unlock_irq(&tsk->sighand->siglock);
+			read_unlock(&tasklist_lock);
+		}
 		tmp.tms_utime = cputime_to_clock_t(utime);
 		tmp.tms_stime = cputime_to_clock_t(stime);
 		tmp.tms_cutime = cputime_to_clock_t(cutime);
@@ -1225,7 +1307,7 @@ static void groups_sort(struct group_inf
 }
 
 /* a simple bsearch */
-static int groups_search(struct group_info *group_info, gid_t grp)
+int groups_search(struct group_info *group_info, gid_t grp)
 {
 	int left, right;
 
@@ -1652,7 +1734,7 @@ asmlinkage long sys_prctl(int option, un
 				error = 1;
 			break;
 		case PR_SET_DUMPABLE:
-			if (arg2 != 0 && arg2 != 1) {
+			if (arg2 < 0 || arg2 > 2) {
 				error = -EINVAL;
 				break;
 			}
diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c
--- a/kernel/sys_ni.c
+++ b/kernel/sys_ni.c
@@ -18,6 +18,8 @@ cond_syscall(sys_acct);
 cond_syscall(sys_lookup_dcookie);
 cond_syscall(sys_swapon);
 cond_syscall(sys_swapoff);
+cond_syscall(sys_kexec_load);
+cond_syscall(compat_sys_kexec_load);
 cond_syscall(sys_init_module);
 cond_syscall(sys_delete_module);
 cond_syscall(sys_socketpair);
@@ -77,6 +79,9 @@ cond_syscall(sys_request_key);
 cond_syscall(sys_keyctl);
 cond_syscall(compat_sys_keyctl);
 cond_syscall(compat_sys_socketcall);
+cond_syscall(sys_inotify_init);
+cond_syscall(sys_inotify_add_watch);
+cond_syscall(sys_inotify_rm_watch);
 
 /* arch-specific weak syscall entries */
 cond_syscall(sys_pciconfig_read);
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -58,6 +58,7 @@ extern int sysctl_overcommit_ratio;
 extern int max_threads;
 extern int sysrq_enabled;
 extern int core_uses_pid;
+extern int suid_dumpable;
 extern char core_pattern[];
 extern int cad_pid;
 extern int pid_max;
@@ -113,6 +114,7 @@ extern int unaligned_enabled;
 extern int sysctl_ieee_emulation_warnings;
 #endif
 extern int sysctl_userprocess_debug;
+extern int spin_retry;
 #endif
 
 extern int sysctl_hz_timer;
@@ -145,6 +147,9 @@ extern ctl_table random_table[];
 #ifdef CONFIG_UNIX98_PTYS
 extern ctl_table pty_table[];
 #endif
+#ifdef CONFIG_INOTIFY
+extern ctl_table inotify_table[];
+#endif
 
 #ifdef HAVE_ARCH_PICK_MMAP_LAYOUT
 int sysctl_legacy_va_layout;
@@ -217,6 +222,7 @@ static ctl_table root_table[] = {
 		.mode		= 0555,
 		.child		= dev_table,
 	},
+
 	{ .ctl_name = 0 }
 };
 
@@ -642,7 +648,16 @@ static ctl_table kern_table[] = {
 		.mode		= 0644,
 		.proc_handler	= &proc_dointvec,
 	},
-
+#if defined(CONFIG_ARCH_S390)
+	{
+		.ctl_name	= KERN_SPIN_RETRY,
+		.procname	= "spin_retry",
+		.data		= &spin_retry,
+		.maxlen		= sizeof (int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec,
+	},
+#endif
 	{ .ctl_name = 0 }
 };
 
@@ -949,7 +964,23 @@ static ctl_table fs_table[] = {
 		.mode		= 0644,
 		.proc_handler	= &proc_dointvec,
 	},
+#ifdef CONFIG_INOTIFY
+	{
+		.ctl_name	= FS_INOTIFY,
+		.procname	= "inotify",
+		.mode		= 0555,
+		.child		= inotify_table,
+	},
+#endif	
 #endif
+	{
+		.ctl_name	= KERN_SETUID_DUMPABLE,
+		.procname	= "suid_dumpable",
+		.data		= &suid_dumpable,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec,
+	},
 	{ .ctl_name = 0 }
 };
 
@@ -959,7 +990,7 @@ static ctl_table debug_table[] = {
 
 static ctl_table dev_table[] = {
 	{ .ctl_name = 0 }
-};  
+};
 
 extern void init_irq_proc (void);
 
@@ -991,8 +1022,7 @@ int do_sysctl(int __user *name, int nlen
 		int error = parse_table(name, nlen, oldval, oldlenp, 
 					newval, newlen, head->ctl_table,
 					&context);
-		if (context)
-			kfree(context);
+		kfree(context);
 		if (error != -ENOTDIR)
 			return error;
 		tmp = tmp->next;
diff --git a/kernel/time.c b/kernel/time.c
--- a/kernel/time.c
+++ b/kernel/time.c
@@ -128,7 +128,7 @@ asmlinkage long sys_gettimeofday(struct 
  * as real UNIX machines always do it. This avoids all headaches about
  * daylight saving times and warping kernel clocks.
  */
-inline static void warp_clock(void)
+static inline void warp_clock(void)
 {
 	write_seqlock_irq(&xtime_lock);
 	wall_to_monotonic.tv_sec -= sys_tz.tz_minuteswest * 60;
diff --git a/kernel/timer.c b/kernel/timer.c
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -57,6 +57,11 @@ static void time_interpolator_update(lon
 #define TVN_MASK (TVN_SIZE - 1)
 #define TVR_MASK (TVR_SIZE - 1)
 
+struct timer_base_s {
+	spinlock_t lock;
+	struct timer_list *running_timer;
+};
+
 typedef struct tvec_s {
 	struct list_head vec[TVN_SIZE];
 } tvec_t;
@@ -66,9 +71,8 @@ typedef struct tvec_root_s {
 } tvec_root_t;
 
 struct tvec_t_base_s {
-	spinlock_t lock;
+	struct timer_base_s t_base;
 	unsigned long timer_jiffies;
-	struct timer_list *running_timer;
 	tvec_root_t tv1;
 	tvec_t tv2;
 	tvec_t tv3;
@@ -77,18 +81,16 @@ struct tvec_t_base_s {
 } ____cacheline_aligned_in_smp;
 
 typedef struct tvec_t_base_s tvec_base_t;
+static DEFINE_PER_CPU(tvec_base_t, tvec_bases);
 
 static inline void set_running_timer(tvec_base_t *base,
 					struct timer_list *timer)
 {
 #ifdef CONFIG_SMP
-	base->running_timer = timer;
+	base->t_base.running_timer = timer;
 #endif
 }
 
-/* Fake initialization */
-static DEFINE_PER_CPU(tvec_base_t, tvec_bases) = { SPIN_LOCK_UNLOCKED };
-
 static void check_timer_failed(struct timer_list *timer)
 {
 	static int whine_count;
@@ -103,7 +105,6 @@ static void check_timer_failed(struct ti
 	/*
 	 * Now fix it up
 	 */
-	spin_lock_init(&timer->lock);
 	timer->magic = TIMER_MAGIC;
 }
 
@@ -156,65 +157,113 @@ static void internal_add_timer(tvec_base
 	list_add_tail(&timer->entry, vec);
 }
 
+typedef struct timer_base_s timer_base_t;
+/*
+ * Used by TIMER_INITIALIZER, we can't use per_cpu(tvec_bases)
+ * at compile time, and we need timer->base to lock the timer.
+ */
+timer_base_t __init_timer_base
+	____cacheline_aligned_in_smp = { .lock = SPIN_LOCK_UNLOCKED };
+EXPORT_SYMBOL(__init_timer_base);
+
+/***
+ * init_timer - initialize a timer.
+ * @timer: the timer to be initialized
+ *
+ * init_timer() must be done to a timer prior calling *any* of the
+ * other timer functions.
+ */
+void fastcall init_timer(struct timer_list *timer)
+{
+	timer->entry.next = NULL;
+	timer->base = &per_cpu(tvec_bases, raw_smp_processor_id()).t_base;
+	timer->magic = TIMER_MAGIC;
+}
+EXPORT_SYMBOL(init_timer);
+
+static inline void detach_timer(struct timer_list *timer,
+					int clear_pending)
+{
+	struct list_head *entry = &timer->entry;
+
+	__list_del(entry->prev, entry->next);
+	if (clear_pending)
+		entry->next = NULL;
+	entry->prev = LIST_POISON2;
+}
+
+/*
+ * We are using hashed locking: holding per_cpu(tvec_bases).t_base.lock
+ * means that all timers which are tied to this base via timer->base are
+ * locked, and the base itself is locked too.
+ *
+ * So __run_timers/migrate_timers can safely modify all timers which could
+ * be found on ->tvX lists.
+ *
+ * When the timer's base is locked, and the timer removed from list, it is
+ * possible to set timer->base = NULL and drop the lock: the timer remains
+ * locked.
+ */
+static timer_base_t *lock_timer_base(struct timer_list *timer,
+					unsigned long *flags)
+{
+	timer_base_t *base;
+
+	for (;;) {
+		base = timer->base;
+		if (likely(base != NULL)) {
+			spin_lock_irqsave(&base->lock, *flags);
+			if (likely(base == timer->base))
+				return base;
+			/* The timer has migrated to another CPU */
+			spin_unlock_irqrestore(&base->lock, *flags);
+		}
+		cpu_relax();
+	}
+}
+
 int __mod_timer(struct timer_list *timer, unsigned long expires)
 {
-	tvec_base_t *old_base, *new_base;
+	timer_base_t *base;
+	tvec_base_t *new_base;
 	unsigned long flags;
 	int ret = 0;
 
 	BUG_ON(!timer->function);
-
 	check_timer(timer);
 
-	spin_lock_irqsave(&timer->lock, flags);
+	base = lock_timer_base(timer, &flags);
+
+	if (timer_pending(timer)) {
+		detach_timer(timer, 0);
+		ret = 1;
+	}
+
 	new_base = &__get_cpu_var(tvec_bases);
-repeat:
-	old_base = timer->base;
 
-	/*
-	 * Prevent deadlocks via ordering by old_base < new_base.
-	 */
-	if (old_base && (new_base != old_base)) {
-		if (old_base < new_base) {
-			spin_lock(&new_base->lock);
-			spin_lock(&old_base->lock);
-		} else {
-			spin_lock(&old_base->lock);
-			spin_lock(&new_base->lock);
-		}
+	if (base != &new_base->t_base) {
 		/*
-		 * The timer base might have been cancelled while we were
-		 * trying to take the lock(s):
+		 * We are trying to schedule the timer on the local CPU.
+		 * However we can't change timer's base while it is running,
+		 * otherwise del_timer_sync() can't detect that the timer's
+		 * handler yet has not finished. This also guarantees that
+		 * the timer is serialized wrt itself.
 		 */
-		if (timer->base != old_base) {
-			spin_unlock(&new_base->lock);
-			spin_unlock(&old_base->lock);
-			goto repeat;
-		}
-	} else {
-		spin_lock(&new_base->lock);
-		if (timer->base != old_base) {
-			spin_unlock(&new_base->lock);
-			goto repeat;
+		if (unlikely(base->running_timer == timer)) {
+			/* The timer remains on a former base */
+			new_base = container_of(base, tvec_base_t, t_base);
+		} else {
+			/* See the comment in lock_timer_base() */
+			timer->base = NULL;
+			spin_unlock(&base->lock);
+			spin_lock(&new_base->t_base.lock);
+			timer->base = &new_base->t_base;
 		}
 	}
 
-	/*
-	 * Delete the previous timeout (if there was any), and install
-	 * the new one:
-	 */
-	if (old_base) {
-		list_del(&timer->entry);
-		ret = 1;
-	}
 	timer->expires = expires;
 	internal_add_timer(new_base, timer);
-	timer->base = new_base;
-
-	if (old_base && (new_base != old_base))
-		spin_unlock(&old_base->lock);
-	spin_unlock(&new_base->lock);
-	spin_unlock_irqrestore(&timer->lock, flags);
+	spin_unlock_irqrestore(&new_base->t_base.lock, flags);
 
 	return ret;
 }
@@ -232,15 +281,15 @@ void add_timer_on(struct timer_list *tim
 {
 	tvec_base_t *base = &per_cpu(tvec_bases, cpu);
   	unsigned long flags;
-  
+
   	BUG_ON(timer_pending(timer) || !timer->function);
 
 	check_timer(timer);
 
-	spin_lock_irqsave(&base->lock, flags);
+	spin_lock_irqsave(&base->t_base.lock, flags);
+	timer->base = &base->t_base;
 	internal_add_timer(base, timer);
-	timer->base = base;
-	spin_unlock_irqrestore(&base->lock, flags);
+	spin_unlock_irqrestore(&base->t_base.lock, flags);
 }
 
 
@@ -295,109 +344,84 @@ EXPORT_SYMBOL(mod_timer);
  */
 int del_timer(struct timer_list *timer)
 {
+	timer_base_t *base;
 	unsigned long flags;
-	tvec_base_t *base;
+	int ret = 0;
 
 	check_timer(timer);
 
-repeat:
- 	base = timer->base;
-	if (!base)
-		return 0;
-	spin_lock_irqsave(&base->lock, flags);
-	if (base != timer->base) {
+	if (timer_pending(timer)) {
+		base = lock_timer_base(timer, &flags);
+		if (timer_pending(timer)) {
+			detach_timer(timer, 1);
+			ret = 1;
+		}
 		spin_unlock_irqrestore(&base->lock, flags);
-		goto repeat;
 	}
-	list_del(&timer->entry);
-	/* Need to make sure that anybody who sees a NULL base also sees the list ops */
-	smp_wmb();
-	timer->base = NULL;
-	spin_unlock_irqrestore(&base->lock, flags);
 
-	return 1;
+	return ret;
 }
 
 EXPORT_SYMBOL(del_timer);
 
 #ifdef CONFIG_SMP
-/***
- * del_timer_sync - deactivate a timer and wait for the handler to finish.
- * @timer: the timer to be deactivated
- *
- * This function only differs from del_timer() on SMP: besides deactivating
- * the timer it also makes sure the handler has finished executing on other
- * CPUs.
- *
- * Synchronization rules: callers must prevent restarting of the timer,
- * otherwise this function is meaningless. It must not be called from
- * interrupt contexts. The caller must not hold locks which would prevent
- * completion of the timer's handler.  Upon exit the timer is not queued and
- * the handler is not running on any CPU.
- *
- * The function returns whether it has deactivated a pending timer or not.
+/*
+ * This function tries to deactivate a timer. Upon successful (ret >= 0)
+ * exit the timer is not queued and the handler is not running on any CPU.
  *
- * del_timer_sync() is slow and complicated because it copes with timer
- * handlers which re-arm the timer (periodic timers).  If the timer handler
- * is known to not do this (a single shot timer) then use
- * del_singleshot_timer_sync() instead.
+ * It must not be called from interrupt contexts.
  */
-int del_timer_sync(struct timer_list *timer)
+int try_to_del_timer_sync(struct timer_list *timer)
 {
-	tvec_base_t *base;
-	int i, ret = 0;
+	timer_base_t *base;
+	unsigned long flags;
+	int ret = -1;
 
-	check_timer(timer);
+	base = lock_timer_base(timer, &flags);
 
-del_again:
-	ret += del_timer(timer);
+	if (base->running_timer == timer)
+		goto out;
 
-	for_each_online_cpu(i) {
-		base = &per_cpu(tvec_bases, i);
-		if (base->running_timer == timer) {
-			while (base->running_timer == timer) {
-				cpu_relax();
-				preempt_check_resched();
-			}
-			break;
-		}
+	ret = 0;
+	if (timer_pending(timer)) {
+		detach_timer(timer, 1);
+		ret = 1;
 	}
-	smp_rmb();
-	if (timer_pending(timer))
-		goto del_again;
+out:
+	spin_unlock_irqrestore(&base->lock, flags);
 
 	return ret;
 }
-EXPORT_SYMBOL(del_timer_sync);
 
 /***
- * del_singleshot_timer_sync - deactivate a non-recursive timer
+ * del_timer_sync - deactivate a timer and wait for the handler to finish.
  * @timer: the timer to be deactivated
  *
- * This function is an optimization of del_timer_sync for the case where the
- * caller can guarantee the timer does not reschedule itself in its timer
- * function.
+ * This function only differs from del_timer() on SMP: besides deactivating
+ * the timer it also makes sure the handler has finished executing on other
+ * CPUs.
  *
  * Synchronization rules: callers must prevent restarting of the timer,
  * otherwise this function is meaningless. It must not be called from
- * interrupt contexts. The caller must not hold locks which wold prevent
- * completion of the timer's handler.  Upon exit the timer is not queued and
- * the handler is not running on any CPU.
+ * interrupt contexts. The caller must not hold locks which would prevent
+ * completion of the timer's handler. The timer's handler must not call
+ * add_timer_on(). Upon exit the timer is not queued and the handler is
+ * not running on any CPU.
  *
  * The function returns whether it has deactivated a pending timer or not.
  */
-int del_singleshot_timer_sync(struct timer_list *timer)
+int del_timer_sync(struct timer_list *timer)
 {
-	int ret = del_timer(timer);
+	check_timer(timer);
 
-	if (!ret) {
-		ret = del_timer_sync(timer);
-		BUG_ON(ret);
+	for (;;) {
+		int ret = try_to_del_timer_sync(timer);
+		if (ret >= 0)
+			return ret;
 	}
-
-	return ret;
 }
-EXPORT_SYMBOL(del_singleshot_timer_sync);
+
+EXPORT_SYMBOL(del_timer_sync);
 #endif
 
 static int cascade(tvec_base_t *base, tvec_t *tv, int index)
@@ -415,7 +439,7 @@ static int cascade(tvec_base_t *base, tv
 		struct timer_list *tmp;
 
 		tmp = list_entry(curr, struct timer_list, entry);
-		BUG_ON(tmp->base != base);
+		BUG_ON(tmp->base != &base->t_base);
 		curr = curr->next;
 		internal_add_timer(base, tmp);
 	}
@@ -437,7 +461,7 @@ static inline void __run_timers(tvec_bas
 {
 	struct timer_list *timer;
 
-	spin_lock_irq(&base->lock);
+	spin_lock_irq(&base->t_base.lock);
 	while (time_after_eq(jiffies, base->timer_jiffies)) {
 		struct list_head work_list = LIST_HEAD_INIT(work_list);
 		struct list_head *head = &work_list;
@@ -453,8 +477,7 @@ static inline void __run_timers(tvec_bas
 			cascade(base, &base->tv5, INDEX(3));
 		++base->timer_jiffies; 
 		list_splice_init(base->tv1.vec + index, &work_list);
-repeat:
-		if (!list_empty(head)) {
+		while (!list_empty(head)) {
 			void (*fn)(unsigned long);
 			unsigned long data;
 
@@ -462,25 +485,26 @@ repeat:
  			fn = timer->function;
  			data = timer->data;
 
-			list_del(&timer->entry);
 			set_running_timer(base, timer);
-			smp_wmb();
-			timer->base = NULL;
-			spin_unlock_irq(&base->lock);
+			detach_timer(timer, 1);
+			spin_unlock_irq(&base->t_base.lock);
 			{
-				u32 preempt_count = preempt_count();
+				int preempt_count = preempt_count();
 				fn(data);
 				if (preempt_count != preempt_count()) {
-					printk("huh, entered %p with %08x, exited with %08x?\n", fn, preempt_count, preempt_count());
+					printk(KERN_WARNING "huh, entered %p "
+					       "with preempt_count %08x, exited"
+					       " with %08x?\n",
+					       fn, preempt_count,
+					       preempt_count());
 					BUG();
 				}
 			}
-			spin_lock_irq(&base->lock);
-			goto repeat;
+			spin_lock_irq(&base->t_base.lock);
 		}
 	}
 	set_running_timer(base, NULL);
-	spin_unlock_irq(&base->lock);
+	spin_unlock_irq(&base->t_base.lock);
 }
 
 #ifdef CONFIG_NO_IDLE_HZ
@@ -499,7 +523,7 @@ unsigned long next_timer_interrupt(void)
 	int i, j;
 
 	base = &__get_cpu_var(tvec_bases);
-	spin_lock(&base->lock);
+	spin_lock(&base->t_base.lock);
 	expires = base->timer_jiffies + (LONG_MAX >> 1);
 	list = 0;
 
@@ -547,7 +571,7 @@ found:
 				expires = nte->expires;
 		}
 	}
-	spin_unlock(&base->lock);
+	spin_unlock(&base->t_base.lock);
 	return expires;
 }
 #endif
@@ -999,7 +1023,7 @@ asmlinkage long sys_getppid(void)
 	parent = me->group_leader->real_parent;
 	for (;;) {
 		pid = parent->tgid;
-#ifdef CONFIG_SMP
+#if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT)
 {
 		struct task_struct *old = parent;
 
@@ -1286,9 +1310,9 @@ static void __devinit init_timers_cpu(in
 {
 	int j;
 	tvec_base_t *base;
-       
+
 	base = &per_cpu(tvec_bases, cpu);
-	spin_lock_init(&base->lock);
+	spin_lock_init(&base->t_base.lock);
 	for (j = 0; j < TVN_SIZE; j++) {
 		INIT_LIST_HEAD(base->tv5.vec + j);
 		INIT_LIST_HEAD(base->tv4.vec + j);
@@ -1302,22 +1326,16 @@ static void __devinit init_timers_cpu(in
 }
 
 #ifdef CONFIG_HOTPLUG_CPU
-static int migrate_timer_list(tvec_base_t *new_base, struct list_head *head)
+static void migrate_timer_list(tvec_base_t *new_base, struct list_head *head)
 {
 	struct timer_list *timer;
 
 	while (!list_empty(head)) {
 		timer = list_entry(head->next, struct timer_list, entry);
-		/* We're locking backwards from __mod_timer order here,
-		   beware deadlock. */
-		if (!spin_trylock(&timer->lock))
-			return 0;
-		list_del(&timer->entry);
+		detach_timer(timer, 0);
+		timer->base = &new_base->t_base;
 		internal_add_timer(new_base, timer);
-		timer->base = new_base;
-		spin_unlock(&timer->lock);
 	}
-	return 1;
 }
 
 static void __devinit migrate_timers(int cpu)
@@ -1331,39 +1349,24 @@ static void __devinit migrate_timers(int
 	new_base = &get_cpu_var(tvec_bases);
 
 	local_irq_disable();
-again:
-	/* Prevent deadlocks via ordering by old_base < new_base. */
-	if (old_base < new_base) {
-		spin_lock(&new_base->lock);
-		spin_lock(&old_base->lock);
-	} else {
-		spin_lock(&old_base->lock);
-		spin_lock(&new_base->lock);
-	}
+	spin_lock(&new_base->t_base.lock);
+	spin_lock(&old_base->t_base.lock);
 
-	if (old_base->running_timer)
+	if (old_base->t_base.running_timer)
 		BUG();
 	for (i = 0; i < TVR_SIZE; i++)
-		if (!migrate_timer_list(new_base, old_base->tv1.vec + i))
-			goto unlock_again;
-	for (i = 0; i < TVN_SIZE; i++)
-		if (!migrate_timer_list(new_base, old_base->tv2.vec + i)
-		    || !migrate_timer_list(new_base, old_base->tv3.vec + i)
-		    || !migrate_timer_list(new_base, old_base->tv4.vec + i)
-		    || !migrate_timer_list(new_base, old_base->tv5.vec + i))
-			goto unlock_again;
-	spin_unlock(&old_base->lock);
-	spin_unlock(&new_base->lock);
+		migrate_timer_list(new_base, old_base->tv1.vec + i);
+	for (i = 0; i < TVN_SIZE; i++) {
+		migrate_timer_list(new_base, old_base->tv2.vec + i);
+		migrate_timer_list(new_base, old_base->tv3.vec + i);
+		migrate_timer_list(new_base, old_base->tv4.vec + i);
+		migrate_timer_list(new_base, old_base->tv5.vec + i);
+	}
+
+	spin_unlock(&old_base->t_base.lock);
+	spin_unlock(&new_base->t_base.lock);
 	local_irq_enable();
 	put_cpu_var(tvec_bases);
-	return;
-
-unlock_again:
-	/* Avoid deadlock with __mod_timer, by backing off. */
-	spin_unlock(&old_base->lock);
-	spin_unlock(&new_base->lock);
-	cpu_relax();
-	goto again;
 }
 #endif /* CONFIG_HOTPLUG_CPU */
 
@@ -1594,7 +1597,7 @@ void msleep(unsigned int msecs)
 EXPORT_SYMBOL(msleep);
 
 /**
- * msleep_interruptible - sleep waiting for waitqueue interruptions
+ * msleep_interruptible - sleep waiting for signals
  * @msecs: Time in milliseconds to sleep for
  */
 unsigned long msleep_interruptible(unsigned int msecs)
diff --git a/kernel/user.c b/kernel/user.c
--- a/kernel/user.c
+++ b/kernel/user.c
@@ -120,6 +120,10 @@ struct user_struct * alloc_uid(uid_t uid
 		atomic_set(&new->processes, 0);
 		atomic_set(&new->files, 0);
 		atomic_set(&new->sigpending, 0);
+#ifdef CONFIG_INOTIFY
+		atomic_set(&new->inotify_watches, 0);
+		atomic_set(&new->inotify_devs, 0);
+#endif
 
 		new->mq_bytes = 0;
 		new->locked_shm = 0;
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -308,8 +308,6 @@ struct workqueue_struct *__create_workqu
 	struct workqueue_struct *wq;
 	struct task_struct *p;
 
-	BUG_ON(strlen(name) > 10);
-
 	wq = kmalloc(sizeof(*wq), GFP_KERNEL);
 	if (!wq)
 		return NULL;
diff --git a/lib/Kconfig b/lib/Kconfig
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -40,6 +40,12 @@ config ZLIB_DEFLATE
 	tristate
 
 #
+# Generic allocator support is selected if needed
+#
+config GENERIC_ALLOCATOR
+	boolean
+
+#
 # reed solomon support is select'ed if needed
 #
 config REED_SOLOMON
@@ -57,5 +63,16 @@ config REED_SOLOMON_ENC16
 config REED_SOLOMON_DEC16
 	boolean
 
-endmenu
+#
+# Textsearch support is select'ed if needed
+#
+config TEXTSEARCH
+	boolean
+
+config TEXTSEARCH_KMP
+	tristate
 
+config TEXTSEARCH_FSM
+	tristate
+
+endmenu
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -141,7 +141,7 @@ config DEBUG_IOREMAP
 
 config DEBUG_FS
 	bool "Debug Filesystem"
-	depends on DEBUG_KERNEL
+	depends on DEBUG_KERNEL && SYSFS
 	help
 	  debugfs is a virtual file system that kernel developers use to put
 	  debugging files into.  Enable this option to be able to read and
diff --git a/lib/Makefile b/lib/Makefile
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -4,11 +4,12 @@
 
 lib-y := errno.o ctype.o string.o vsprintf.o cmdline.o \
 	 bust_spinlocks.o rbtree.o radix-tree.o dump_stack.o \
-	 kobject.o kref.o idr.o div64.o int_sqrt.o \
-	 bitmap.o extable.o kobject_uevent.o prio_tree.o sha1.o \
-	 halfmd4.o
+	 idr.o div64.o int_sqrt.o bitmap.o extable.o prio_tree.o \
+	 sha1.o
 
-obj-y += sort.o parser.o
+lib-y	+= kobject.o kref.o kobject_uevent.o klist.o
+
+obj-y += sort.o parser.o halfmd4.o
 
 ifeq ($(CONFIG_DEBUG_KOBJECT),y)
 CFLAGS_kobject.o += -DDEBUG
@@ -19,6 +20,7 @@ lib-$(CONFIG_RWSEM_GENERIC_SPINLOCK) += 
 lib-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem.o
 lib-$(CONFIG_GENERIC_FIND_NEXT_BIT) += find_next_bit.o
 obj-$(CONFIG_LOCK_KERNEL) += kernel_lock.o
+obj-$(CONFIG_DEBUG_PREEMPT) += smp_processor_id.o
 
 ifneq ($(CONFIG_HAVE_DEC_LOCK),y) 
   lib-y += dec_and_lock.o
@@ -28,11 +30,16 @@ obj-$(CONFIG_CRC_CCITT)	+= crc-ccitt.o
 obj-$(CONFIG_CRC32)	+= crc32.o
 obj-$(CONFIG_LIBCRC32C)	+= libcrc32c.o
 obj-$(CONFIG_GENERIC_IOMAP) += iomap.o
+obj-$(CONFIG_GENERIC_ALLOCATOR) += genalloc.o
 
 obj-$(CONFIG_ZLIB_INFLATE) += zlib_inflate/
 obj-$(CONFIG_ZLIB_DEFLATE) += zlib_deflate/
 obj-$(CONFIG_REED_SOLOMON) += reed_solomon/
 
+obj-$(CONFIG_TEXTSEARCH) += textsearch.o
+obj-$(CONFIG_TEXTSEARCH_KMP) += ts_kmp.o
+obj-$(CONFIG_TEXTSEARCH_FSM) += ts_fsm.o
+
 hostprogs-y	:= gen_crc32table
 clean-files	:= crc32table.h
 
diff --git a/lib/bitmap.c b/lib/bitmap.c
--- a/lib/bitmap.c
+++ b/lib/bitmap.c
@@ -289,7 +289,6 @@ EXPORT_SYMBOL(__bitmap_weight);
 
 #define CHUNKSZ				32
 #define nbits_to_hold_value(val)	fls(val)
-#define roundup_power2(val,modulus)	(((val) + (modulus) - 1) & ~((modulus) - 1))
 #define unhex(c)			(isdigit(c) ? (c - '0') : (toupper(c) - 'A' + 10))
 #define BASEDEC 10		/* fancier cpuset lists input in decimal */
 
@@ -316,7 +315,7 @@ int bitmap_scnprintf(char *buf, unsigned
 	if (chunksz == 0)
 		chunksz = CHUNKSZ;
 
-	i = roundup_power2(nmaskbits, CHUNKSZ) - CHUNKSZ;
+	i = ALIGN(nmaskbits, CHUNKSZ) - CHUNKSZ;
 	for (; i >= 0; i -= CHUNKSZ) {
 		chunkmask = ((1ULL << chunksz) - 1);
 		word = i / BITS_PER_LONG;
diff --git a/lib/crc32.c b/lib/crc32.c
--- a/lib/crc32.c
+++ b/lib/crc32.c
@@ -473,7 +473,7 @@ static u32 test_step(u32 init, unsigned 
 	init = bitreverse(init);
 	crc2 = bitreverse(crc1);
 	if (crc1 != bitreverse(crc2))
-		printf("\nBit reversal fail: 0x%08x -> %0x08x -> 0x%08x\n",
+		printf("\nBit reversal fail: 0x%08x -> 0x%08x -> 0x%08x\n",
 		       crc1, crc2, bitreverse(crc2));
 	crc1 = crc32_le(init, buf, len);
 	if (crc1 != crc2)
diff --git a/lib/genalloc.c b/lib/genalloc.c
new file mode 100644
--- /dev/null
+++ b/lib/genalloc.c
@@ -0,0 +1,188 @@
+/*
+ * Basic general purpose allocator for managing special purpose memory
+ * not managed by the regular kmalloc/kfree interface.
+ * Uses for this includes on-device special memory, uncached memory
+ * etc.
+ *
+ * This code is based on the buddy allocator found in the sym53c8xx_2
+ * driver Copyright (C) 1999-2001  Gerard Roudier <groudier@free.fr>,
+ * and adapted for general purpose use.
+ *
+ * Copyright 2005 (C) Jes Sorensen <jes@trained-monkey.org>
+ *
+ * This source code is licensed under the GNU General Public License,
+ * Version 2.  See the file COPYING for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/stddef.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/spinlock.h>
+#include <linux/genalloc.h>
+
+#include <asm/page.h>
+
+
+struct gen_pool *gen_pool_create(int nr_chunks, int max_chunk_shift,
+				 unsigned long (*fp)(struct gen_pool *),
+				 unsigned long data)
+{
+	struct gen_pool *poolp;
+	unsigned long tmp;
+	int i;
+
+	/*
+	 * This is really an arbitrary limit, +10 is enough for
+	 * IA64_GRANULE_SHIFT, aka 16MB. If anyone needs a large limit
+	 * this can be increased without problems.
+	 */
+	if ((max_chunk_shift > (PAGE_SHIFT + 10)) ||
+	    ((max_chunk_shift < ALLOC_MIN_SHIFT) && max_chunk_shift))
+		return NULL;
+
+	if (!max_chunk_shift)
+		max_chunk_shift = PAGE_SHIFT;
+
+	poolp = kmalloc(sizeof(struct gen_pool), GFP_KERNEL);
+	if (!poolp)
+		return NULL;
+	memset(poolp, 0, sizeof(struct gen_pool));
+	poolp->h = kmalloc(sizeof(struct gen_pool_link) *
+			   (max_chunk_shift - ALLOC_MIN_SHIFT + 1),
+			   GFP_KERNEL);
+	if (!poolp->h) {
+		printk(KERN_WARNING "gen_pool_alloc() failed to allocate\n");
+		kfree(poolp);
+		return NULL;
+	}
+	memset(poolp->h, 0, sizeof(struct gen_pool_link) *
+	       (max_chunk_shift - ALLOC_MIN_SHIFT + 1));
+
+	spin_lock_init(&poolp->lock);
+	poolp->get_new_chunk = fp;
+	poolp->max_chunk_shift = max_chunk_shift;
+	poolp->private = data;
+
+	for (i = 0; i < nr_chunks; i++) {
+		tmp = poolp->get_new_chunk(poolp);
+		printk(KERN_INFO "allocated %lx\n", tmp);
+		if (!tmp)
+			break;
+		gen_pool_free(poolp, tmp, (1 << poolp->max_chunk_shift));
+	}
+
+	return poolp;
+}
+EXPORT_SYMBOL(gen_pool_create);
+
+
+/*
+ *  Simple power of two buddy-like generic allocator.
+ *  Provides naturally aligned memory chunks.
+ */
+unsigned long gen_pool_alloc(struct gen_pool *poolp, int size)
+{
+	int j, i, s, max_chunk_size;
+	unsigned long a, flags;
+	struct gen_pool_link *h = poolp->h;
+
+	max_chunk_size = 1 << poolp->max_chunk_shift;
+
+	if (size > max_chunk_size)
+		return 0;
+
+	i = 0;
+
+	size = max(size, 1 << ALLOC_MIN_SHIFT);
+	s = roundup_pow_of_two(size);
+
+	j = i;
+
+	spin_lock_irqsave(&poolp->lock, flags);
+	while (!h[j].next) {
+		if (s == max_chunk_size) {
+			struct gen_pool_link *ptr;
+			spin_unlock_irqrestore(&poolp->lock, flags);
+			ptr = (struct gen_pool_link *)poolp->get_new_chunk(poolp);
+			spin_lock_irqsave(&poolp->lock, flags);
+			h[j].next = ptr;
+			if (h[j].next)
+				h[j].next->next = NULL;
+			break;
+		}
+		j++;
+		s <<= 1;
+	}
+	a = (unsigned long) h[j].next;
+	if (a) {
+		h[j].next = h[j].next->next;
+		/*
+		 * This should be split into a seperate function doing
+		 * the chunk split in order to support custom
+		 * handling memory not physically accessible by host
+		 */
+		while (j > i) {
+			j -= 1;
+			s >>= 1;
+			h[j].next = (struct gen_pool_link *) (a + s);
+			h[j].next->next = NULL;
+		}
+	}
+	spin_unlock_irqrestore(&poolp->lock, flags);
+	return a;
+}
+EXPORT_SYMBOL(gen_pool_alloc);
+
+
+/*
+ *  Counter-part of the generic allocator.
+ */
+void gen_pool_free(struct gen_pool *poolp, unsigned long ptr, int size)
+{
+	struct gen_pool_link *q;
+	struct gen_pool_link *h = poolp->h;
+	unsigned long a, b, flags;
+	int i, s, max_chunk_size;
+
+	max_chunk_size = 1 << poolp->max_chunk_shift;
+
+	if (size > max_chunk_size)
+		return;
+
+	i = 0;
+
+	size = max(size, 1 << ALLOC_MIN_SHIFT);
+	s = roundup_pow_of_two(size);
+
+	a = ptr;
+
+	spin_lock_irqsave(&poolp->lock, flags);
+	while (1) {
+		if (s == max_chunk_size) {
+			((struct gen_pool_link *)a)->next = h[i].next;
+			h[i].next = (struct gen_pool_link *)a;
+			break;
+		}
+		b = a ^ s;
+		q = &h[i];
+
+		while (q->next && q->next != (struct gen_pool_link *)b)
+			q = q->next;
+
+		if (!q->next) {
+			((struct gen_pool_link *)a)->next = h[i].next;
+			h[i].next = (struct gen_pool_link *)a;
+			break;
+		}
+		q->next = q->next->next;
+		a = a & b;
+		s <<= 1;
+		i++;
+	}
+	spin_unlock_irqrestore(&poolp->lock, flags);
+}
+EXPORT_SYMBOL(gen_pool_free);
diff --git a/lib/idr.c b/lib/idr.c
--- a/lib/idr.c
+++ b/lib/idr.c
@@ -175,7 +175,7 @@ build_up:
 	 * Add a new layer to the top of the tree if the requested
 	 * id is larger than the currently allocated space.
 	 */
-	while ((layers < MAX_LEVEL) && (id >= (1 << (layers*IDR_BITS)))) {
+	while ((layers < (MAX_LEVEL - 1)) && (id >= (1 << (layers*IDR_BITS)))) {
 		layers++;
 		if (!p->count)
 			continue;
@@ -207,7 +207,7 @@ build_up:
 }
 
 /**
- * idr_get_new_above - allocate new idr entry above a start id
+ * idr_get_new_above - allocate new idr entry above or equal to a start id
  * @idp: idr handle
  * @ptr: pointer you want associated with the ide
  * @start_id: id to start search at
diff --git a/lib/inflate.c b/lib/inflate.c
--- a/lib/inflate.c
+++ b/lib/inflate.c
@@ -326,7 +326,7 @@ DEBG("huft1 ");
   {
     *t = (struct huft *)NULL;
     *m = 0;
-    return 0;
+    return 2;
   }
 
 DEBG("huft2 ");
@@ -374,6 +374,7 @@ DEBG("huft5 ");
     if ((j = *p++) != 0)
       v[x[j]++] = i;
   } while (++i < n);
+  n = x[g];                   /* set n to length of v */
 
 DEBG("h6 ");
 
@@ -410,12 +411,13 @@ DEBG1("1 ");
 DEBG1("2 ");
           f -= a + 1;           /* deduct codes from patterns left */
           xp = c + k;
-          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 */
-          }
+          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 */
+            }
         }
 DEBG1("3 ");
         z = 1 << j;             /* table entries for j-bit table */
diff --git a/lib/kernel_lock.c b/lib/kernel_lock.c
--- a/lib/kernel_lock.c
+++ b/lib/kernel_lock.c
@@ -9,61 +9,6 @@
 #include <linux/module.h>
 #include <linux/kallsyms.h>
 
-#if defined(CONFIG_PREEMPT) && defined(__smp_processor_id) && \
-		defined(CONFIG_DEBUG_PREEMPT)
-
-/*
- * Debugging check.
- */
-unsigned int smp_processor_id(void)
-{
-	unsigned long preempt_count = preempt_count();
-	int this_cpu = __smp_processor_id();
-	cpumask_t this_mask;
-
-	if (likely(preempt_count))
-		goto out;
-
-	if (irqs_disabled())
-		goto out;
-
-	/*
-	 * Kernel threads bound to a single CPU can safely use
-	 * smp_processor_id():
-	 */
-	this_mask = cpumask_of_cpu(this_cpu);
-
-	if (cpus_equal(current->cpus_allowed, this_mask))
-		goto out;
-
-	/*
-	 * It is valid to assume CPU-locality during early bootup:
-	 */
-	if (system_state != SYSTEM_RUNNING)
-		goto out;
-
-	/*
-	 * Avoid recursion:
-	 */
-	preempt_disable();
-
-	if (!printk_ratelimit())
-		goto out_enable;
-
-	printk(KERN_ERR "BUG: using smp_processor_id() in preemptible [%08x] code: %s/%d\n", preempt_count(), current->comm, current->pid);
-	print_symbol("caller is %s\n", (long)__builtin_return_address(0));
-	dump_stack();
-
-out_enable:
-	preempt_enable_no_resched();
-out:
-	return this_cpu;
-}
-
-EXPORT_SYMBOL(smp_processor_id);
-
-#endif /* PREEMPT && __smp_processor_id && DEBUG_PREEMPT */
-
 #ifdef CONFIG_PREEMPT_BKL
 /*
  * The 'big kernel semaphore'
diff --git a/lib/klist.c b/lib/klist.c
new file mode 100644
--- /dev/null
+++ b/lib/klist.c
@@ -0,0 +1,265 @@
+/*
+ *	klist.c - Routines for manipulating klists.
+ *
+ *
+ *	This klist interface provides a couple of structures that wrap around 
+ *	struct list_head to provide explicit list "head" (struct klist) and 
+ *	list "node" (struct klist_node) objects. For struct klist, a spinlock
+ *	is included that protects access to the actual list itself. struct 
+ *	klist_node provides a pointer to the klist that owns it and a kref
+ *	reference count that indicates the number of current users of that node
+ *	in the list.
+ *
+ *	The entire point is to provide an interface for iterating over a list
+ *	that is safe and allows for modification of the list during the
+ *	iteration (e.g. insertion and removal), including modification of the
+ *	current node on the list.
+ *
+ *	It works using a 3rd object type - struct klist_iter - that is declared
+ *	and initialized before an iteration. klist_next() is used to acquire the
+ *	next element in the list. It returns NULL if there are no more items.
+ *	Internally, that routine takes the klist's lock, decrements the reference
+ *	count of the previous klist_node and increments the count of the next
+ *	klist_node. It then drops the lock and returns.
+ *
+ *	There are primitives for adding and removing nodes to/from a klist. 
+ *	When deleting, klist_del() will simply decrement the reference count. 
+ *	Only when the count goes to 0 is the node removed from the list. 
+ *	klist_remove() will try to delete the node from the list and block
+ *	until it is actually removed. This is useful for objects (like devices)
+ *	that have been removed from the system and must be freed (but must wait
+ *	until all accessors have finished).
+ *
+ *	Copyright (C) 2005 Patrick Mochel
+ *
+ *	This file is released under the GPL v2.
+ */
+
+#include <linux/klist.h>
+#include <linux/module.h>
+
+
+/**
+ *	klist_init - Initialize a klist structure. 
+ *	@k:	The klist we're initializing.
+ */
+
+void klist_init(struct klist * k)
+{
+	INIT_LIST_HEAD(&k->k_list);
+	spin_lock_init(&k->k_lock);
+}
+
+EXPORT_SYMBOL_GPL(klist_init);
+
+
+static void add_head(struct klist * k, struct klist_node * n)
+{
+	spin_lock(&k->k_lock);
+	list_add(&n->n_node, &k->k_list);
+	spin_unlock(&k->k_lock);
+}
+
+static void add_tail(struct klist * k, struct klist_node * n)
+{
+	spin_lock(&k->k_lock);
+	list_add_tail(&n->n_node, &k->k_list);
+	spin_unlock(&k->k_lock);
+}
+
+
+static void klist_node_init(struct klist * k, struct klist_node * n)
+{
+	INIT_LIST_HEAD(&n->n_node);
+	init_completion(&n->n_removed);
+	kref_init(&n->n_ref);
+	n->n_klist = k;
+}
+
+
+/**
+ *	klist_add_head - Initialize a klist_node and add it to front.
+ *	@k:	klist it's going on.
+ *	@n:	node we're adding.
+ */
+
+void klist_add_head(struct klist * k, struct klist_node * n)
+{
+	klist_node_init(k, n);
+	add_head(k, n);
+}
+
+EXPORT_SYMBOL_GPL(klist_add_head);
+
+
+/**
+ *	klist_add_tail - Initialize a klist_node and add it to back.
+ *	@k:	klist it's going on.
+ *	@n:	node we're adding.
+ */
+
+void klist_add_tail(struct klist * k, struct klist_node * n)
+{
+	klist_node_init(k, n);
+	add_tail(k, n);
+}
+
+EXPORT_SYMBOL_GPL(klist_add_tail);
+
+
+static void klist_release(struct kref * kref)
+{
+	struct klist_node * n = container_of(kref, struct klist_node, n_ref);
+	list_del(&n->n_node);
+	complete(&n->n_removed);
+	n->n_klist = NULL;
+}
+
+static int klist_dec_and_del(struct klist_node * n)
+{
+	return kref_put(&n->n_ref, klist_release);
+}
+
+
+/**
+ *	klist_del - Decrement the reference count of node and try to remove.
+ *	@n:	node we're deleting.
+ */
+
+void klist_del(struct klist_node * n)
+{
+	struct klist * k = n->n_klist;
+
+	spin_lock(&k->k_lock);
+	klist_dec_and_del(n);
+	spin_unlock(&k->k_lock);
+}
+
+EXPORT_SYMBOL_GPL(klist_del);
+
+
+/**
+ *	klist_remove - Decrement the refcount of node and wait for it to go away.
+ *	@n:	node we're removing.
+ */
+
+void klist_remove(struct klist_node * n)
+{
+	struct klist * k = n->n_klist;
+	spin_lock(&k->k_lock);
+	klist_dec_and_del(n);
+	spin_unlock(&k->k_lock);
+	wait_for_completion(&n->n_removed);
+}
+
+EXPORT_SYMBOL_GPL(klist_remove);
+
+
+/**
+ *	klist_node_attached - Say whether a node is bound to a list or not.
+ *	@n:	Node that we're testing.
+ */
+
+int klist_node_attached(struct klist_node * n)
+{
+	return (n->n_klist != NULL);
+}
+
+EXPORT_SYMBOL_GPL(klist_node_attached);
+
+
+/**
+ *	klist_iter_init_node - Initialize a klist_iter structure.
+ *	@k:	klist we're iterating.
+ *	@i:	klist_iter we're filling.
+ *	@n:	node to start with.
+ *
+ *	Similar to klist_iter_init(), but starts the action off with @n, 
+ *	instead of with the list head.
+ */
+
+void klist_iter_init_node(struct klist * k, struct klist_iter * i, struct klist_node * n)
+{
+	i->i_klist = k;
+	i->i_head = &k->k_list;
+	i->i_cur = n;
+}
+
+EXPORT_SYMBOL_GPL(klist_iter_init_node);
+
+
+/**
+ *	klist_iter_init - Iniitalize a klist_iter structure.
+ *	@k:	klist we're iterating.
+ *	@i:	klist_iter structure we're filling.
+ *
+ *	Similar to klist_iter_init_node(), but start with the list head.
+ */
+
+void klist_iter_init(struct klist * k, struct klist_iter * i)
+{
+	klist_iter_init_node(k, i, NULL);
+}
+
+EXPORT_SYMBOL_GPL(klist_iter_init);
+
+
+/**
+ *	klist_iter_exit - Finish a list iteration.
+ *	@i:	Iterator structure.
+ *
+ *	Must be called when done iterating over list, as it decrements the 
+ *	refcount of the current node. Necessary in case iteration exited before
+ *	the end of the list was reached, and always good form.
+ */
+
+void klist_iter_exit(struct klist_iter * i)
+{
+	if (i->i_cur) {
+		klist_del(i->i_cur);
+		i->i_cur = NULL;
+	}
+}
+
+EXPORT_SYMBOL_GPL(klist_iter_exit);
+
+
+static struct klist_node * to_klist_node(struct list_head * n)
+{
+	return container_of(n, struct klist_node, n_node);
+}
+
+
+/**
+ *	klist_next - Ante up next node in list.
+ *	@i:	Iterator structure.
+ *
+ *	First grab list lock. Decrement the reference count of the previous
+ *	node, if there was one. Grab the next node, increment its reference 
+ *	count, drop the lock, and return that next node.
+ */
+
+struct klist_node * klist_next(struct klist_iter * i)
+{
+	struct list_head * next;
+	struct klist_node * knode = NULL;
+
+	spin_lock(&i->i_klist->k_lock);
+	if (i->i_cur) {
+		next = i->i_cur->n_node.next;
+		klist_dec_and_del(i->i_cur);
+	} else
+		next = i->i_head->next;
+
+	if (next != i->i_head) {
+		knode = to_klist_node(next);
+		kref_get(&knode->n_ref);
+	}
+	i->i_cur = knode;
+	spin_unlock(&i->i_klist->k_lock);
+	return knode;
+}
+
+EXPORT_SYMBOL_GPL(klist_next);
+
+
diff --git a/lib/kobject.c b/lib/kobject.c
--- a/lib/kobject.c
+++ b/lib/kobject.c
@@ -279,7 +279,7 @@ EXPORT_SYMBOL(kobject_set_name);
  *	@new_name: object's new name
  */
 
-int kobject_rename(struct kobject * kobj, char *new_name)
+int kobject_rename(struct kobject * kobj, const char *new_name)
 {
 	int error = 0;
 
diff --git a/lib/kobject_uevent.c b/lib/kobject_uevent.c
--- a/lib/kobject_uevent.c
+++ b/lib/kobject_uevent.c
@@ -197,7 +197,7 @@ void kobject_hotplug(struct kobject *kob
 	int i = 0;
 	int retval;
 	char *kobj_path = NULL;
-	char *name = NULL;
+	const char *name = NULL;
 	char *action_string;
 	u64 seq;
 	struct kobject *top_kobj = kobj;
@@ -246,10 +246,10 @@ void kobject_hotplug(struct kobject *kob
 	if (hotplug_ops->name)
 		name = hotplug_ops->name(kset, kobj);
 	if (name == NULL)
-		name = kset->kobj.name;
+		name = kobject_name(&kset->kobj);
 
 	argv [0] = hotplug_path;
-	argv [1] = name;
+	argv [1] = (char *)name; /* won't be changed but 'const' has to go */
 	argv [2] = NULL;
 
 	/* minimal command environment */
diff --git a/lib/radix-tree.c b/lib/radix-tree.c
--- a/lib/radix-tree.c
+++ b/lib/radix-tree.c
@@ -58,7 +58,7 @@ struct radix_tree_path {
 #define RADIX_TREE_INDEX_BITS  (8 /* CHAR_BIT */ * sizeof(unsigned long))
 #define RADIX_TREE_MAX_PATH (RADIX_TREE_INDEX_BITS/RADIX_TREE_MAP_SHIFT + 2)
 
-static unsigned long height_to_maxindex[RADIX_TREE_MAX_PATH];
+static unsigned long height_to_maxindex[RADIX_TREE_MAX_PATH] __read_mostly;
 
 /*
  * Radix tree node cache.
diff --git a/lib/sha1.c b/lib/sha1.c
--- a/lib/sha1.c
+++ b/lib/sha1.c
@@ -41,7 +41,7 @@ void sha_transform(__u32 *digest, const 
 	__u32 a, b, c, d, e, t, i;
 
 	for (i = 0; i < 16; i++)
-		W[i] = be32_to_cpu(((const __u32 *)in)[i]);
+		W[i] = be32_to_cpu(((const __be32 *)in)[i]);
 
 	for (i = 0; i < 64; i++)
 		W[i+16] = rol32(W[i+13] ^ W[i+8] ^ W[i+2] ^ W[i], 1);
diff --git a/lib/smp_processor_id.c b/lib/smp_processor_id.c
new file mode 100644
--- /dev/null
+++ b/lib/smp_processor_id.c
@@ -0,0 +1,55 @@
+/*
+ * lib/smp_processor_id.c
+ *
+ * DEBUG_PREEMPT variant of smp_processor_id().
+ */
+#include <linux/module.h>
+#include <linux/kallsyms.h>
+
+unsigned int debug_smp_processor_id(void)
+{
+	unsigned long preempt_count = preempt_count();
+	int this_cpu = raw_smp_processor_id();
+	cpumask_t this_mask;
+
+	if (likely(preempt_count))
+		goto out;
+
+	if (irqs_disabled())
+		goto out;
+
+	/*
+	 * Kernel threads bound to a single CPU can safely use
+	 * smp_processor_id():
+	 */
+	this_mask = cpumask_of_cpu(this_cpu);
+
+	if (cpus_equal(current->cpus_allowed, this_mask))
+		goto out;
+
+	/*
+	 * It is valid to assume CPU-locality during early bootup:
+	 */
+	if (system_state != SYSTEM_RUNNING)
+		goto out;
+
+	/*
+	 * Avoid recursion:
+	 */
+	preempt_disable();
+
+	if (!printk_ratelimit())
+		goto out_enable;
+
+	printk(KERN_ERR "BUG: using smp_processor_id() in preemptible [%08x] code: %s/%d\n", preempt_count(), current->comm, current->pid);
+	print_symbol("caller is %s\n", (long)__builtin_return_address(0));
+	dump_stack();
+
+out_enable:
+	preempt_enable_no_resched();
+out:
+	return this_cpu;
+}
+
+EXPORT_SYMBOL(debug_smp_processor_id);
+
diff --git a/lib/textsearch.c b/lib/textsearch.c
new file mode 100644
--- /dev/null
+++ b/lib/textsearch.c
@@ -0,0 +1,317 @@
+/*
+ * lib/textsearch.c	Generic text search interface
+ *
+ *		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.
+ *
+ * Authors:	Thomas Graf <tgraf@suug.ch>
+ * 		Pablo Neira Ayuso <pablo@eurodev.net>
+ *
+ * ==========================================================================
+ *
+ * INTRODUCTION
+ *
+ *   The textsearch infrastructure provides text searching facitilies for
+ *   both linear and non-linear data. Individual search algorithms are
+ *   implemented in modules and chosen by the user.
+ *
+ * ARCHITECTURE
+ *
+ *      User
+ *     +----------------+
+ *     |        finish()|<--------------(6)-----------------+
+ *     |get_next_block()|<--------------(5)---------------+ |
+ *     |                |                     Algorithm   | |
+ *     |                |                    +------------------------------+
+ *     |                |                    |  init()   find()   destroy() |
+ *     |                |                    +------------------------------+
+ *     |                |       Core API           ^       ^          ^
+ *     |                |      +---------------+  (2)     (4)        (8)
+ *     |             (1)|----->| prepare()     |---+       |          |
+ *     |             (3)|----->| find()/next() |-----------+          |
+ *     |             (7)|----->| destroy()     |----------------------+
+ *     +----------------+      +---------------+
+ *  
+ *   (1) User configures a search by calling _prepare() specifying the
+ *       search parameters such as the pattern and algorithm name.
+ *   (2) Core requests the algorithm to allocate and initialize a search
+ *       configuration according to the specified parameters.
+ *   (3) User starts the search(es) by calling _find() or _next() to
+ *       fetch subsequent occurrences. A state variable is provided
+ *       to the algorihtm to store persistant variables.
+ *   (4) Core eventually resets the search offset and forwards the find()
+ *       request to the algorithm.
+ *   (5) Algorithm calls get_next_block() provided by the user continously
+ *       to fetch the data to be searched in block by block.
+ *   (6) Algorithm invokes finish() after the last call to get_next_block
+ *       to clean up any leftovers from get_next_block. (Optional)
+ *   (7) User destroys the configuration by calling _destroy().
+ *   (8) Core notifies the algorithm to destroy algorithm specific
+ *       allocations. (Optional)
+ *
+ * USAGE
+ *
+ *   Before a search can be performed, a configuration must be created
+ *   by calling textsearch_prepare() specyfing the searching algorithm and
+ *   the pattern to look for. The returned configuration may then be used
+ *   for an arbitary amount of times and even in parallel as long as a
+ *   separate struct ts_state variable is provided to every instance.
+ *
+ *   The actual search is performed by either calling textsearch_find_-
+ *   continuous() for linear data or by providing an own get_next_block()
+ *   implementation and calling textsearch_find(). Both functions return
+ *   the position of the first occurrence of the patern or UINT_MAX if
+ *   no match was found. Subsequent occurences can be found by calling
+ *   textsearch_next() regardless of the linearity of the data.
+ *
+ *   Once you're done using a configuration it must be given back via
+ *   textsearch_destroy.
+ *
+ * EXAMPLE
+ *
+ *   int pos;
+ *   struct ts_config *conf;
+ *   struct ts_state state;
+ *   const char *pattern = "chicken";
+ *   const char *example = "We dance the funky chicken";
+ *
+ *   conf = textsearch_prepare("kmp", pattern, strlen(pattern),
+ *                             GFP_KERNEL, TS_AUTOLOAD);
+ *   if (IS_ERR(conf)) {
+ *       err = PTR_ERR(conf);
+ *       goto errout;
+ *   }
+ *
+ *   pos = textsearch_find_continuous(conf, &state, example, strlen(example));
+ *   if (pos != UINT_MAX)
+ *       panic("Oh my god, dancing chickens at %d\n", pos);
+ *
+ *   textsearch_destroy(conf);
+ *
+ * ==========================================================================
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/rcupdate.h>
+#include <linux/err.h>
+#include <linux/textsearch.h>
+
+static LIST_HEAD(ts_ops);
+static DEFINE_SPINLOCK(ts_mod_lock);
+
+static inline struct ts_ops *lookup_ts_algo(const char *name)
+{
+	struct ts_ops *o;
+
+	rcu_read_lock();
+	list_for_each_entry_rcu(o, &ts_ops, list) {
+		if (!strcmp(name, o->name)) {
+			if (!try_module_get(o->owner))
+				o = NULL;
+			rcu_read_unlock();
+			return o;
+		}
+	}
+	rcu_read_unlock();
+
+	return NULL;
+}
+
+/**
+ * textsearch_register - register a textsearch module
+ * @ops: operations lookup table
+ *
+ * This function must be called by textsearch modules to announce
+ * their presence. The specified &@ops must have %name set to a
+ * unique identifier and the callbacks find(), init(), get_pattern(),
+ * and get_pattern_len() must be implemented.
+ *
+ * Returns 0 or -EEXISTS if another module has already registered
+ * with same name.
+ */
+int textsearch_register(struct ts_ops *ops)
+{
+	int err = -EEXIST;
+	struct ts_ops *o;
+
+	if (ops->name == NULL || ops->find == NULL || ops->init == NULL ||
+	    ops->get_pattern == NULL || ops->get_pattern_len == NULL)
+		return -EINVAL;
+
+	spin_lock(&ts_mod_lock);
+	list_for_each_entry(o, &ts_ops, list) {
+		if (!strcmp(ops->name, o->name))
+			goto errout;
+	}
+
+	list_add_tail_rcu(&ops->list, &ts_ops);
+	err = 0;
+errout:
+	spin_unlock(&ts_mod_lock);
+	return err;
+}
+
+/**
+ * textsearch_unregister - unregister a textsearch module
+ * @ops: operations lookup table
+ *
+ * This function must be called by textsearch modules to announce
+ * their disappearance for examples when the module gets unloaded.
+ * The &ops parameter must be the same as the one during the
+ * registration.
+ *
+ * Returns 0 on success or -ENOENT if no matching textsearch
+ * registration was found.
+ */
+int textsearch_unregister(struct ts_ops *ops)
+{
+	int err = 0;
+	struct ts_ops *o;
+
+	spin_lock(&ts_mod_lock);
+	list_for_each_entry(o, &ts_ops, list) {
+		if (o == ops) {
+			list_del_rcu(&o->list);
+			goto out;
+		}
+	}
+
+	err = -ENOENT;
+out:
+	spin_unlock(&ts_mod_lock);
+	return err;
+}
+
+struct ts_linear_state
+{
+	unsigned int	len;
+	const void	*data;
+};
+
+static unsigned int get_linear_data(unsigned int consumed, const u8 **dst,
+				    struct ts_config *conf,
+				    struct ts_state *state)
+{
+	struct ts_linear_state *st = (struct ts_linear_state *) state->cb;
+
+	if (likely(consumed < st->len)) {
+		*dst = st->data + consumed;
+		return st->len - consumed;
+	}
+
+	return 0;
+}
+
+/**
+ * textsearch_find_continuous - search a pattern in continuous/linear data
+ * @conf: search configuration
+ * @state: search state
+ * @data: data to search in
+ * @len: length of data
+ *
+ * A simplified version of textsearch_find() for continuous/linear data.
+ * Call textsearch_next() to retrieve subsequent matches.
+ *
+ * Returns the position of first occurrence of the pattern or
+ * UINT_MAX if no occurrence was found.
+ */ 
+unsigned int textsearch_find_continuous(struct ts_config *conf,
+					struct ts_state *state,
+					const void *data, unsigned int len)
+{
+	struct ts_linear_state *st = (struct ts_linear_state *) state->cb;
+
+	conf->get_next_block = get_linear_data;
+	st->data = data;
+	st->len = len;
+
+	return textsearch_find(conf, state);
+}
+
+/**
+ * textsearch_prepare - Prepare a search
+ * @algo: name of search algorithm
+ * @pattern: pattern data
+ * @len: length of pattern
+ * @gfp_mask: allocation mask
+ * @flags: search flags
+ *
+ * Looks up the search algorithm module and creates a new textsearch
+ * configuration for the specified pattern. Upon completion all
+ * necessary refcnts are held and the configuration must be put back
+ * using textsearch_put() after usage.
+ *
+ * Note: The format of the pattern may not be compatible between
+ *       the various search algorithms.
+ *
+ * Returns a new textsearch configuration according to the specified
+ *         parameters or a ERR_PTR().
+ */
+struct ts_config *textsearch_prepare(const char *algo, const void *pattern,
+				     unsigned int len, int gfp_mask, int flags)
+{
+	int err = -ENOENT;
+	struct ts_config *conf;
+	struct ts_ops *ops;
+	
+	ops = lookup_ts_algo(algo);
+#ifdef CONFIG_KMOD
+	/*
+	 * Why not always autoload you may ask. Some users are
+	 * in a situation where requesting a module may deadlock,
+	 * especially when the module is located on a NFS mount.
+	 */
+	if (ops == NULL && flags & TS_AUTOLOAD) {
+		request_module("ts_%s", algo);
+		ops = lookup_ts_algo(algo);
+	}
+#endif
+
+	if (ops == NULL)
+		goto errout;
+
+	conf = ops->init(pattern, len, gfp_mask);
+	if (IS_ERR(conf)) {
+		err = PTR_ERR(conf);
+		goto errout;
+	}
+
+	conf->ops = ops;
+	return conf;
+
+errout:
+	if (ops)
+		module_put(ops->owner);
+		
+	return ERR_PTR(err);
+}
+
+/**
+ * textsearch_destroy - destroy a search configuration
+ * @conf: search configuration
+ *
+ * Releases all references of the configuration and frees
+ * up the memory.
+ */
+void textsearch_destroy(struct ts_config *conf)
+{
+	if (conf->ops) {
+		if (conf->ops->destroy)
+			conf->ops->destroy(conf);
+		module_put(conf->ops->owner);
+	}
+
+	kfree(conf);
+}
+
+EXPORT_SYMBOL(textsearch_register);
+EXPORT_SYMBOL(textsearch_unregister);
+EXPORT_SYMBOL(textsearch_prepare);
+EXPORT_SYMBOL(textsearch_find_continuous);
+EXPORT_SYMBOL(textsearch_destroy);
diff --git a/lib/ts_fsm.c b/lib/ts_fsm.c
new file mode 100644
--- /dev/null
+++ b/lib/ts_fsm.c
@@ -0,0 +1,338 @@
+/*
+ * lib/ts_fsm.c	   A naive finite state machine text search approach
+ *
+ *		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.
+ *
+ * Authors:	Thomas Graf <tgraf@suug.ch>
+ *
+ * ==========================================================================
+ *
+ *   A finite state machine consists of n states (struct ts_fsm_token)
+ *   representing the pattern as a finite automation. The data is read
+ *   sequentially on a octet basis. Every state token specifies the number
+ *   of recurrences and the type of value accepted which can be either a
+ *   specific character or ctype based set of characters. The available
+ *   type of recurrences include 1, (0|1), [0 n], and [1 n].
+ *
+ *   The algorithm differs between strict/non-strict mode specyfing
+ *   whether the pattern has to start at the first octect. Strict mode
+ *   is enabled by default and can be disabled by inserting
+ *   TS_FSM_HEAD_IGNORE as the first token in the chain.
+ *
+ *   The runtime performance of the algorithm should be around O(n),
+ *   however while in strict mode the average runtime can be better.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/ctype.h>
+#include <linux/textsearch.h>
+#include <linux/textsearch_fsm.h>
+
+struct ts_fsm
+{
+	unsigned int		ntokens;
+	struct ts_fsm_token	tokens[0];
+};
+
+/* other values derived from ctype.h */
+#define _A		0x100 /* ascii */
+#define _W		0x200 /* wildcard */
+
+/* Map to _ctype flags and some magic numbers */
+static u16 token_map[TS_FSM_TYPE_MAX+1] = {
+	[TS_FSM_SPECIFIC] = 0,
+	[TS_FSM_WILDCARD] = _W,
+	[TS_FSM_CNTRL]	  = _C,
+	[TS_FSM_LOWER]	  = _L,
+	[TS_FSM_UPPER]	  = _U,
+	[TS_FSM_PUNCT]	  = _P,
+	[TS_FSM_SPACE]	  = _S,
+	[TS_FSM_DIGIT]	  = _D,
+	[TS_FSM_XDIGIT]	  = _D | _X,
+	[TS_FSM_ALPHA]	  = _U | _L,
+	[TS_FSM_ALNUM]	  = _U | _L | _D,
+	[TS_FSM_PRINT]	  = _P | _U | _L | _D | _SP,
+	[TS_FSM_GRAPH]	  = _P | _U | _L | _D,
+	[TS_FSM_ASCII]	  = _A,
+};
+
+static u16 token_lookup_tbl[256] = {
+_W|_A|_C,      _W|_A|_C,     _W|_A|_C,     _W|_A|_C,		/*   0-  3 */
+_W|_A|_C,      _W|_A|_C,     _W|_A|_C,     _W|_A|_C,		/*   4-  7 */
+_W|_A|_C,      _W|_A|_C|_S,  _W|_A|_C|_S,  _W|_A|_C|_S,		/*   8- 11 */
+_W|_A|_C|_S,   _W|_A|_C|_S,  _W|_A|_C,     _W|_A|_C,		/*  12- 15 */
+_W|_A|_C,      _W|_A|_C,     _W|_A|_C,     _W|_A|_C,		/*  16- 19 */
+_W|_A|_C,      _W|_A|_C,     _W|_A|_C,     _W|_A|_C,		/*  20- 23 */
+_W|_A|_C,      _W|_A|_C,     _W|_A|_C,     _W|_A|_C,		/*  24- 27 */
+_W|_A|_C,      _W|_A|_C,     _W|_A|_C,     _W|_A|_C,		/*  28- 31 */
+_W|_A|_S|_SP,  _W|_A|_P,     _W|_A|_P,     _W|_A|_P,		/*  32- 35 */
+_W|_A|_P,      _W|_A|_P,     _W|_A|_P,     _W|_A|_P,		/*  36- 39 */
+_W|_A|_P,      _W|_A|_P,     _W|_A|_P,     _W|_A|_P,		/*  40- 43 */
+_W|_A|_P,      _W|_A|_P,     _W|_A|_P,     _W|_A|_P,		/*  44- 47 */
+_W|_A|_D,      _W|_A|_D,     _W|_A|_D,     _W|_A|_D,		/*  48- 51 */
+_W|_A|_D,      _W|_A|_D,     _W|_A|_D,     _W|_A|_D,		/*  52- 55 */
+_W|_A|_D,      _W|_A|_D,     _W|_A|_P,     _W|_A|_P,		/*  56- 59 */
+_W|_A|_P,      _W|_A|_P,     _W|_A|_P,     _W|_A|_P,		/*  60- 63 */
+_W|_A|_P,      _W|_A|_U|_X,  _W|_A|_U|_X,  _W|_A|_U|_X,		/*  64- 67 */
+_W|_A|_U|_X,   _W|_A|_U|_X,  _W|_A|_U|_X,  _W|_A|_U,		/*  68- 71 */
+_W|_A|_U,      _W|_A|_U,     _W|_A|_U,     _W|_A|_U,		/*  72- 75 */
+_W|_A|_U,      _W|_A|_U,     _W|_A|_U,     _W|_A|_U,		/*  76- 79 */
+_W|_A|_U,      _W|_A|_U,     _W|_A|_U,     _W|_A|_U,		/*  80- 83 */
+_W|_A|_U,      _W|_A|_U,     _W|_A|_U,     _W|_A|_U,		/*  84- 87 */
+_W|_A|_U,      _W|_A|_U,     _W|_A|_U,     _W|_A|_P,		/*  88- 91 */
+_W|_A|_P,      _W|_A|_P,     _W|_A|_P,     _W|_A|_P,		/*  92- 95 */
+_W|_A|_P,      _W|_A|_L|_X,  _W|_A|_L|_X,  _W|_A|_L|_X,		/*  96- 99 */
+_W|_A|_L|_X,   _W|_A|_L|_X,  _W|_A|_L|_X,  _W|_A|_L,		/* 100-103 */
+_W|_A|_L,      _W|_A|_L,     _W|_A|_L,     _W|_A|_L,		/* 104-107 */
+_W|_A|_L,      _W|_A|_L,     _W|_A|_L,     _W|_A|_L,		/* 108-111 */
+_W|_A|_L,      _W|_A|_L,     _W|_A|_L,     _W|_A|_L,		/* 112-115 */
+_W|_A|_L,      _W|_A|_L,     _W|_A|_L,     _W|_A|_L,		/* 116-119 */
+_W|_A|_L,      _W|_A|_L,     _W|_A|_L,     _W|_A|_P,		/* 120-123 */
+_W|_A|_P,      _W|_A|_P,     _W|_A|_P,     _W|_A|_C,		/* 124-127 */
+_W,            _W,           _W,           _W,			/* 128-131 */
+_W,            _W,           _W,           _W,			/* 132-135 */
+_W,            _W,           _W,           _W,			/* 136-139 */
+_W,            _W,           _W,           _W,			/* 140-143 */
+_W,            _W,           _W,           _W,			/* 144-147 */
+_W,            _W,           _W,           _W,			/* 148-151 */
+_W,            _W,           _W,           _W,			/* 152-155 */
+_W,            _W,           _W,           _W,			/* 156-159 */
+_W|_S|_SP,     _W|_P,        _W|_P,        _W|_P,		/* 160-163 */
+_W|_P,         _W|_P,        _W|_P,        _W|_P,		/* 164-167 */
+_W|_P,         _W|_P,        _W|_P,        _W|_P,		/* 168-171 */
+_W|_P,         _W|_P,        _W|_P,        _W|_P,		/* 172-175 */
+_W|_P,         _W|_P,        _W|_P,        _W|_P,		/* 176-179 */
+_W|_P,         _W|_P,        _W|_P,        _W|_P,		/* 180-183 */
+_W|_P,         _W|_P,        _W|_P,        _W|_P,		/* 184-187 */
+_W|_P,         _W|_P,        _W|_P,        _W|_P,		/* 188-191 */
+_W|_U,         _W|_U,        _W|_U,        _W|_U,		/* 192-195 */
+_W|_U,         _W|_U,        _W|_U,        _W|_U,		/* 196-199 */
+_W|_U,         _W|_U,        _W|_U,        _W|_U,		/* 200-203 */
+_W|_U,         _W|_U,        _W|_U,        _W|_U,		/* 204-207 */
+_W|_U,         _W|_U,        _W|_U,        _W|_U,		/* 208-211 */
+_W|_U,         _W|_U,        _W|_U,        _W|_P,		/* 212-215 */
+_W|_U,         _W|_U,        _W|_U,        _W|_U,		/* 216-219 */
+_W|_U,         _W|_U,        _W|_U,        _W|_L,		/* 220-223 */
+_W|_L,         _W|_L,        _W|_L,        _W|_L,		/* 224-227 */
+_W|_L,         _W|_L,        _W|_L,        _W|_L,		/* 228-231 */
+_W|_L,         _W|_L,        _W|_L,        _W|_L,		/* 232-235 */
+_W|_L,         _W|_L,        _W|_L,        _W|_L,		/* 236-239 */
+_W|_L,         _W|_L,        _W|_L,        _W|_L,		/* 240-243 */
+_W|_L,         _W|_L,        _W|_L,        _W|_P,		/* 244-247 */
+_W|_L,         _W|_L,        _W|_L,        _W|_L,		/* 248-251 */
+_W|_L,         _W|_L,        _W|_L,        _W|_L};		/* 252-255 */
+
+static inline int match_token(struct ts_fsm_token *t, u8 d)
+{
+	if (t->type)
+		return (token_lookup_tbl[d] & t->type) != 0;
+	else
+		return t->value == d;
+}
+
+static unsigned int fsm_find(struct ts_config *conf, struct ts_state *state)
+{
+	struct ts_fsm *fsm = ts_config_priv(conf);
+	struct ts_fsm_token *cur = NULL, *next;
+	unsigned int match_start, block_idx = 0, tok_idx;
+	unsigned block_len = 0, strict, consumed = state->offset;
+	const u8 *data;
+
+#define GET_NEXT_BLOCK()		\
+({	consumed += block_idx;		\
+	block_idx = 0;			\
+	block_len = conf->get_next_block(consumed, &data, conf, state); })
+
+#define TOKEN_MISMATCH()		\
+	do {				\
+		if (strict)		\
+			goto no_match;	\
+		block_idx++;		\
+		goto startover;		\
+	} while(0)
+
+#define end_of_data() unlikely(block_idx >= block_len && !GET_NEXT_BLOCK())
+
+	if (end_of_data())
+		goto no_match;
+
+	strict = fsm->tokens[0].recur != TS_FSM_HEAD_IGNORE;
+
+startover:
+	match_start = consumed + block_idx;
+
+	for (tok_idx = 0; tok_idx < fsm->ntokens; tok_idx++) {
+		cur = &fsm->tokens[tok_idx];
+
+		if (likely(tok_idx < (fsm->ntokens - 1)))
+			next = &fsm->tokens[tok_idx + 1];
+		else
+			next = NULL;
+
+		switch (cur->recur) {
+		case TS_FSM_SINGLE:
+			if (end_of_data())
+				goto no_match;
+
+			if (!match_token(cur, data[block_idx]))
+				TOKEN_MISMATCH();
+			break;
+
+		case TS_FSM_PERHAPS:
+			if (end_of_data() ||
+			    !match_token(cur, data[block_idx]))
+				continue;
+			break;
+
+		case TS_FSM_MULTI:
+			if (end_of_data())
+				goto no_match;
+
+			if (!match_token(cur, data[block_idx]))
+				TOKEN_MISMATCH();
+
+			block_idx++;
+			/* fall through */
+
+		case TS_FSM_ANY:
+			if (next == NULL)
+				goto found_match;
+
+			if (end_of_data())
+				continue;
+
+			while (!match_token(next, data[block_idx])) {
+				if (!match_token(cur, data[block_idx]))
+					TOKEN_MISMATCH();
+				block_idx++;
+				if (end_of_data())
+					goto no_match;
+			}
+			continue;
+
+		/*
+		 * Optimization: Prefer small local loop over jumping
+		 * back and forth until garbage at head is munched.
+		 */
+		case TS_FSM_HEAD_IGNORE:
+			if (end_of_data())
+				continue;
+
+			while (!match_token(next, data[block_idx])) {
+				/*
+				 * Special case, don't start over upon
+				 * a mismatch, give the user the
+				 * chance to specify the type of data
+				 * allowed to be ignored.
+				 */
+				if (!match_token(cur, data[block_idx]))
+					goto no_match;
+
+				block_idx++;
+				if (end_of_data())
+					goto no_match;
+			}
+
+			match_start = consumed + block_idx;
+			continue;
+		}
+
+		block_idx++;
+	}
+
+	if (end_of_data())
+		goto found_match;
+
+no_match:
+	return UINT_MAX;
+
+found_match:
+	state->offset = consumed + block_idx;
+	return match_start;
+}
+
+static struct ts_config *fsm_init(const void *pattern, unsigned int len,
+				     int gfp_mask)
+{
+	int i, err = -EINVAL;
+	struct ts_config *conf;
+	struct ts_fsm *fsm;
+	struct ts_fsm_token *tokens = (struct ts_fsm_token *) pattern;
+	unsigned int ntokens = len / sizeof(*tokens);
+	size_t priv_size = sizeof(*fsm) + len;
+
+	if (len  % sizeof(struct ts_fsm_token) || ntokens < 1)
+		goto errout;
+
+	for (i = 0; i < ntokens; i++) {
+		struct ts_fsm_token *t = &tokens[i];
+
+		if (t->type > TS_FSM_TYPE_MAX || t->recur > TS_FSM_RECUR_MAX)
+			goto errout;
+
+		if (t->recur == TS_FSM_HEAD_IGNORE &&
+		    (i != 0 || i == (ntokens - 1)))
+			goto errout;
+	}
+
+	conf = alloc_ts_config(priv_size, gfp_mask);
+	if (IS_ERR(conf))
+		return conf;
+
+	fsm = ts_config_priv(conf);
+	fsm->ntokens = ntokens;
+	memcpy(fsm->tokens, pattern, len);
+
+	for (i = 0; i < fsm->ntokens; i++) {
+		struct ts_fsm_token *t = &fsm->tokens[i];
+		t->type = token_map[t->type];
+	}
+
+	return conf;
+
+errout:
+	return ERR_PTR(err);
+}
+
+static void *fsm_get_pattern(struct ts_config *conf)
+{
+	struct ts_fsm *fsm = ts_config_priv(conf);
+	return fsm->tokens;
+}
+
+static unsigned int fsm_get_pattern_len(struct ts_config *conf)
+{
+	struct ts_fsm *fsm = ts_config_priv(conf);
+	return fsm->ntokens * sizeof(struct ts_fsm_token);
+}
+
+static struct ts_ops fsm_ops = {
+	.name		  = "fsm",
+	.find		  = fsm_find,
+	.init		  = fsm_init,
+	.get_pattern	  = fsm_get_pattern,
+	.get_pattern_len  = fsm_get_pattern_len,
+	.owner		  = THIS_MODULE,
+	.list		  = LIST_HEAD_INIT(fsm_ops.list)
+};
+
+static int __init init_fsm(void)
+{
+	return textsearch_register(&fsm_ops);
+}
+
+static void __exit exit_fsm(void)
+{
+	textsearch_unregister(&fsm_ops);
+}
+
+MODULE_LICENSE("GPL");
+
+module_init(init_fsm);
+module_exit(exit_fsm);
diff --git a/lib/ts_kmp.c b/lib/ts_kmp.c
new file mode 100644
--- /dev/null
+++ b/lib/ts_kmp.c
@@ -0,0 +1,145 @@
+/*
+ * lib/ts_kmp.c		Knuth-Morris-Pratt text search implementation
+ *
+ *		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.
+ *
+ * Authors:	Thomas Graf <tgraf@suug.ch>
+ *
+ * ==========================================================================
+ * 
+ *   Implements a linear-time string-matching algorithm due to Knuth,
+ *   Morris, and Pratt [1]. Their algorithm avoids the explicit
+ *   computation of the transition function DELTA altogether. Its
+ *   matching time is O(n), for n being length(text), using just an
+ *   auxiliary function PI[1..m], for m being length(pattern),
+ *   precomputed from the pattern in time O(m). The array PI allows
+ *   the transition function DELTA to be computed efficiently
+ *   "on the fly" as needed. Roughly speaking, for any state
+ *   "q" = 0,1,...,m and any character "a" in SIGMA, the value
+ *   PI["q"] contains the information that is independent of "a" and
+ *   is needed to compute DELTA("q", "a") [2]. Since the array PI
+ *   has only m entries, whereas DELTA has O(m|SIGMA|) entries, we
+ *   save a factor of |SIGMA| in the preprocessing time by computing
+ *   PI rather than DELTA.
+ *
+ *   [1] Cormen, Leiserson, Rivest, Stein
+ *       Introdcution to Algorithms, 2nd Edition, MIT Press
+ *   [2] See finite automation theory
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/textsearch.h>
+
+struct ts_kmp
+{
+	u8 *		pattern;
+	unsigned int	pattern_len;
+	unsigned int 	prefix_tbl[0];
+};
+
+static unsigned int kmp_find(struct ts_config *conf, struct ts_state *state)
+{
+	struct ts_kmp *kmp = ts_config_priv(conf);
+	unsigned int i, q = 0, text_len, consumed = state->offset;
+	const u8 *text;
+
+	for (;;) {
+		text_len = conf->get_next_block(consumed, &text, conf, state);
+
+		if (unlikely(text_len == 0))
+			break;
+
+		for (i = 0; i < text_len; i++) {
+			while (q > 0 && kmp->pattern[q] != text[i])
+				q = kmp->prefix_tbl[q - 1];
+			if (kmp->pattern[q] == text[i])
+				q++;
+			if (unlikely(q == kmp->pattern_len)) {
+				state->offset = consumed + i + 1;
+				return state->offset - kmp->pattern_len;
+			}
+		}
+
+		consumed += text_len;
+	}
+
+	return UINT_MAX;
+}
+
+static inline void compute_prefix_tbl(const u8 *pattern, unsigned int len,
+				      unsigned int *prefix_tbl)
+{
+	unsigned int k, q;
+
+	for (k = 0, q = 1; q < len; q++) {
+		while (k > 0 && pattern[k] != pattern[q])
+			k = prefix_tbl[k-1];
+		if (pattern[k] == pattern[q])
+			k++;
+		prefix_tbl[q] = k;
+	}
+}
+
+static struct ts_config *kmp_init(const void *pattern, unsigned int len,
+				  int gfp_mask)
+{
+	struct ts_config *conf;
+	struct ts_kmp *kmp;
+	unsigned int prefix_tbl_len = len * sizeof(unsigned int);
+	size_t priv_size = sizeof(*kmp) + len + prefix_tbl_len;
+
+	conf = alloc_ts_config(priv_size, gfp_mask);
+	if (IS_ERR(conf))
+		return conf;
+
+	kmp = ts_config_priv(conf);
+	kmp->pattern_len = len;
+	compute_prefix_tbl(pattern, len, kmp->prefix_tbl);
+	kmp->pattern = (u8 *) kmp->prefix_tbl + prefix_tbl_len;
+	memcpy(kmp->pattern, pattern, len);
+
+	return conf;
+}
+
+static void *kmp_get_pattern(struct ts_config *conf)
+{
+	struct ts_kmp *kmp = ts_config_priv(conf);
+	return kmp->pattern;
+}
+
+static unsigned int kmp_get_pattern_len(struct ts_config *conf)
+{
+	struct ts_kmp *kmp = ts_config_priv(conf);
+	return kmp->pattern_len;
+}
+
+static struct ts_ops kmp_ops = {
+	.name		  = "kmp",
+	.find		  = kmp_find,
+	.init		  = kmp_init,
+	.get_pattern	  = kmp_get_pattern,
+	.get_pattern_len  = kmp_get_pattern_len,
+	.owner		  = THIS_MODULE,
+	.list		  = LIST_HEAD_INIT(kmp_ops.list)
+};
+
+static int __init init_kmp(void)
+{
+	return textsearch_register(&kmp_ops);
+}
+
+static void __exit exit_kmp(void)
+{
+	textsearch_unregister(&kmp_ops);
+}
+
+MODULE_LICENSE("GPL");
+
+module_init(init_kmp);
+module_exit(exit_kmp);
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -269,6 +269,7 @@ int vsnprintf(char *buf, size_t size, co
 	int qualifier;		/* 'h', 'l', or 'L' for integer fields */
 				/* 'z' support added 23/7/1999 S.H.    */
 				/* 'z' changed to 'Z' --davidm 1/25/99 */
+				/* 't' added for ptrdiff_t */
 
 	/* Reject out-of-range values early */
 	if (unlikely((int) size < 0)) {
@@ -339,7 +340,7 @@ int vsnprintf(char *buf, size_t size, co
 		/* get the conversion qualifier */
 		qualifier = -1;
 		if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' ||
-		    *fmt =='Z' || *fmt == 'z') {
+		    *fmt =='Z' || *fmt == 'z' || *fmt == 't') {
 			qualifier = *fmt;
 			++fmt;
 			if (qualifier == 'l' && *fmt == 'l') {
@@ -467,6 +468,8 @@ int vsnprintf(char *buf, size_t size, co
 				num = (signed long) num;
 		} else if (qualifier == 'Z' || qualifier == 'z') {
 			num = va_arg(args, size_t);
+		} else if (qualifier == 't') {
+			num = va_arg(args, ptrdiff_t);
 		} else if (qualifier == 'h') {
 			num = (unsigned short) va_arg(args, int);
 			if (flags & SIGN)
diff --git a/mm/Kconfig b/mm/Kconfig
new file mode 100644
--- /dev/null
+++ b/mm/Kconfig
@@ -0,0 +1,91 @@
+config SELECT_MEMORY_MODEL
+	def_bool y
+	depends on EXPERIMENTAL || ARCH_SELECT_MEMORY_MODEL
+
+choice
+	prompt "Memory model"
+	depends on SELECT_MEMORY_MODEL
+	default DISCONTIGMEM_MANUAL if ARCH_DISCONTIGMEM_DEFAULT
+	default SPARSEMEM_MANUAL if ARCH_SPARSEMEM_DEFAULT
+	default FLATMEM_MANUAL
+
+config FLATMEM_MANUAL
+	bool "Flat Memory"
+	depends on !ARCH_DISCONTIGMEM_ENABLE || ARCH_FLATMEM_ENABLE
+	help
+	  This option allows you to change some of the ways that
+	  Linux manages its memory internally.  Most users will
+	  only have one option here: FLATMEM.  This is normal
+	  and a correct option.
+
+	  Some users of more advanced features like NUMA and
+	  memory hotplug may have different options here.
+	  DISCONTIGMEM is an more mature, better tested system,
+	  but is incompatible with memory hotplug and may suffer
+	  decreased performance over SPARSEMEM.  If unsure between
+	  "Sparse Memory" and "Discontiguous Memory", choose
+	  "Discontiguous Memory".
+
+	  If unsure, choose this option (Flat Memory) over any other.
+
+config DISCONTIGMEM_MANUAL
+	bool "Discontigious Memory"
+	depends on ARCH_DISCONTIGMEM_ENABLE
+	help
+	  This option provides enhanced support for discontiguous
+	  memory systems, over FLATMEM.  These systems have holes
+	  in their physical address spaces, and this option provides
+	  more efficient handling of these holes.  However, the vast
+	  majority of hardware has quite flat address spaces, and
+	  can have degraded performance from extra overhead that
+	  this option imposes.
+
+	  Many NUMA configurations will have this as the only option.
+
+	  If unsure, choose "Flat Memory" over this option.
+
+config SPARSEMEM_MANUAL
+	bool "Sparse Memory"
+	depends on ARCH_SPARSEMEM_ENABLE
+	help
+	  This will be the only option for some systems, including
+	  memory hotplug systems.  This is normal.
+
+	  For many other systems, this will be an alternative to
+	  "Discontigious Memory".  This option provides some potential
+	  performance benefits, along with decreased code complexity,
+	  but it is newer, and more experimental.
+
+	  If unsure, choose "Discontiguous Memory" or "Flat Memory"
+	  over this option.
+
+endchoice
+
+config DISCONTIGMEM
+	def_bool y
+	depends on (!SELECT_MEMORY_MODEL && ARCH_DISCONTIGMEM_ENABLE) || DISCONTIGMEM_MANUAL
+
+config SPARSEMEM
+	def_bool y
+	depends on SPARSEMEM_MANUAL
+
+config FLATMEM
+	def_bool y
+	depends on (!DISCONTIGMEM && !SPARSEMEM) || FLATMEM_MANUAL
+
+config FLAT_NODE_MEM_MAP
+	def_bool y
+	depends on !SPARSEMEM
+
+#
+# Both the NUMA code and DISCONTIGMEM use arrays of pg_data_t's
+# to represent different areas of memory.  This variable allows
+# those dependencies to exist individually.
+#
+config NEED_MULTIPLE_NODES
+	def_bool y
+	depends on DISCONTIGMEM || NUMA
+
+config HAVE_MEMORY_PRESENT
+	def_bool y
+	depends on ARCH_HAVE_MEMORY_PRESENT || SPARSEMEM
diff --git a/mm/Makefile b/mm/Makefile
--- a/mm/Makefile
+++ b/mm/Makefile
@@ -15,6 +15,8 @@ obj-y			:= bootmem.o filemap.o mempool.o
 obj-$(CONFIG_SWAP)	+= page_io.o swap_state.o swapfile.o thrash.o
 obj-$(CONFIG_HUGETLBFS)	+= hugetlb.o
 obj-$(CONFIG_NUMA) 	+= mempolicy.o
+obj-$(CONFIG_SPARSEMEM)	+= sparse.o
 obj-$(CONFIG_SHMEM) += shmem.o
 obj-$(CONFIG_TINY_SHMEM) += tiny-shmem.o
 
+obj-$(CONFIG_FS_XIP) += filemap_xip.o
diff --git a/mm/bootmem.c b/mm/bootmem.c
--- a/mm/bootmem.c
+++ b/mm/bootmem.c
@@ -33,6 +33,14 @@ EXPORT_SYMBOL(max_pfn);		/* This is expo
 				 * dma_get_required_mask(), which uses
 				 * it, can be an inline function */
 
+#ifdef CONFIG_CRASH_DUMP
+/*
+ * If we have booted due to a crash, max_pfn will be a very low value. We need
+ * to know the amount of memory that the previous kernel used.
+ */
+unsigned long saved_max_pfn;
+#endif
+
 /* return the number of _pages_ that will be allocated for the boot bitmap */
 unsigned long __init bootmem_bootmap_pages (unsigned long pages)
 {
@@ -57,7 +65,7 @@ static unsigned long __init init_bootmem
 	pgdat->pgdat_next = pgdat_list;
 	pgdat_list = pgdat;
 
-	mapsize = (mapsize + (sizeof(long) - 1UL)) & ~(sizeof(long) - 1UL);
+	mapsize = ALIGN(mapsize, sizeof(long));
 	bdata->node_bootmem_map = phys_to_virt(mapstart << PAGE_SHIFT);
 	bdata->node_boot_start = (start << PAGE_SHIFT);
 	bdata->node_low_pfn = end;
@@ -178,7 +186,7 @@ __alloc_bootmem_core(struct bootmem_data
 	} else
 		preferred = 0;
 
-	preferred = ((preferred + align - 1) & ~(align - 1)) >> PAGE_SHIFT;
+	preferred = ALIGN(preferred, align) >> PAGE_SHIFT;
 	preferred += offset;
 	areasize = (size+PAGE_SIZE-1)/PAGE_SIZE;
 	incr = align >> PAGE_SHIFT ? : 1;
@@ -219,7 +227,7 @@ found:
 	 */
 	if (align < PAGE_SIZE &&
 	    bdata->last_offset && bdata->last_pos+1 == start) {
-		offset = (bdata->last_offset+align-1) & ~(align-1);
+		offset = ALIGN(bdata->last_offset, align);
 		BUG_ON(offset > PAGE_SIZE);
 		remaining_size = PAGE_SIZE-offset;
 		if (size < remaining_size) {
@@ -256,6 +264,7 @@ found:
 static unsigned long __init free_all_bootmem_core(pg_data_t *pgdat)
 {
 	struct page *page;
+	unsigned long pfn;
 	bootmem_data_t *bdata = pgdat->bdata;
 	unsigned long i, count, total = 0;
 	unsigned long idx;
@@ -266,7 +275,7 @@ static unsigned long __init free_all_boo
 
 	count = 0;
 	/* first extant page of the node */
-	page = virt_to_page(phys_to_virt(bdata->node_boot_start));
+	pfn = bdata->node_boot_start >> PAGE_SHIFT;
 	idx = bdata->node_low_pfn - (bdata->node_boot_start >> PAGE_SHIFT);
 	map = bdata->node_bootmem_map;
 	/* Check physaddr is O(LOG2(BITS_PER_LONG)) page aligned */
@@ -275,9 +284,11 @@ static unsigned long __init free_all_boo
 		gofast = 1;
 	for (i = 0; i < idx; ) {
 		unsigned long v = ~map[i / BITS_PER_LONG];
+
 		if (gofast && v == ~0UL) {
 			int j, order;
 
+			page = pfn_to_page(pfn);
 			count += BITS_PER_LONG;
 			__ClearPageReserved(page);
 			order = ffs(BITS_PER_LONG) - 1;
@@ -292,6 +303,8 @@ static unsigned long __init free_all_boo
 			page += BITS_PER_LONG;
 		} else if (v) {
 			unsigned long m;
+
+			page = pfn_to_page(pfn);
 			for (m = 1; m && i < idx; m<<=1, page++, i++) {
 				if (v & m) {
 					count++;
@@ -302,8 +315,8 @@ static unsigned long __init free_all_boo
 			}
 		} else {
 			i+=BITS_PER_LONG;
-			page += BITS_PER_LONG;
 		}
+		pfn += BITS_PER_LONG;
 	}
 	total += count;
 
diff --git a/mm/fadvise.c b/mm/fadvise.c
--- a/mm/fadvise.c
+++ b/mm/fadvise.c
@@ -43,6 +43,10 @@ asmlinkage long sys_fadvise64_64(int fd,
 		goto out;
 	}
 
+	if (mapping->a_ops->get_xip_page)
+		/* no bad return value, but ignore advice */
+		goto out;
+
 	/* Careful about overflows. Len == 0 means "as much as possible" */
 	endbyte = offset + len;
 	if (!len || endbyte < len)
diff --git a/mm/filemap.c b/mm/filemap.c
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -28,6 +28,7 @@
 #include <linux/blkdev.h>
 #include <linux/security.h>
 #include <linux/syscalls.h>
+#include "filemap.h"
 /*
  * FIXME: remove all knowledge of the buffer layer from the core VM
  */
@@ -1714,32 +1715,7 @@ int remove_suid(struct dentry *dentry)
 }
 EXPORT_SYMBOL(remove_suid);
 
-/*
- * Copy as much as we can into the page and return the number of bytes which
- * were sucessfully copied.  If a fault is encountered then clear the page
- * out to (offset+bytes) and return the number of bytes which were copied.
- */
-static inline size_t
-filemap_copy_from_user(struct page *page, unsigned long offset,
-			const char __user *buf, unsigned bytes)
-{
-	char *kaddr;
-	int left;
-
-	kaddr = kmap_atomic(page, KM_USER0);
-	left = __copy_from_user_inatomic(kaddr + offset, buf, bytes);
-	kunmap_atomic(kaddr, KM_USER0);
-
-	if (left != 0) {
-		/* Do it the slow way */
-		kaddr = kmap(page);
-		left = __copy_from_user(kaddr + offset, buf, bytes);
-		kunmap(page);
-	}
-	return bytes - left;
-}
-
-static size_t
+size_t
 __filemap_copy_from_user_iovec(char *vaddr, 
 			const struct iovec *iov, size_t base, size_t bytes)
 {
@@ -1767,52 +1743,6 @@ __filemap_copy_from_user_iovec(char *vad
 }
 
 /*
- * This has the same sideeffects and return value as filemap_copy_from_user().
- * The difference is that on a fault we need to memset the remainder of the
- * page (out to offset+bytes), to emulate filemap_copy_from_user()'s
- * single-segment behaviour.
- */
-static inline size_t
-filemap_copy_from_user_iovec(struct page *page, unsigned long offset,
-			const struct iovec *iov, size_t base, size_t bytes)
-{
-	char *kaddr;
-	size_t copied;
-
-	kaddr = kmap_atomic(page, KM_USER0);
-	copied = __filemap_copy_from_user_iovec(kaddr + offset, iov,
-						base, bytes);
-	kunmap_atomic(kaddr, KM_USER0);
-	if (copied != bytes) {
-		kaddr = kmap(page);
-		copied = __filemap_copy_from_user_iovec(kaddr + offset, iov,
-							base, bytes);
-		kunmap(page);
-	}
-	return copied;
-}
-
-static inline void
-filemap_set_next_iovec(const struct iovec **iovp, size_t *basep, size_t bytes)
-{
-	const struct iovec *iov = *iovp;
-	size_t base = *basep;
-
-	while (bytes) {
-		int copy = min(bytes, iov->iov_len - base);
-
-		bytes -= copy;
-		base += copy;
-		if (iov->iov_len == base) {
-			iov++;
-			base = 0;
-		}
-	}
-	*iovp = iov;
-	*basep = base;
-}
-
-/*
  * Performs necessary checks before doing a write
  *
  * Can adjust writing position aor amount of bytes to write.
@@ -1827,12 +1757,6 @@ inline int generic_write_checks(struct f
         if (unlikely(*pos < 0))
                 return -EINVAL;
 
-        if (unlikely(file->f_error)) {
-                int err = file->f_error;
-                file->f_error = 0;
-                return err;
-        }
-
 	if (!isblk) {
 		/* FIXME: this is for backwards compatibility with 2.4 */
 		if (file->f_flags & O_APPEND)
@@ -1927,8 +1851,11 @@ generic_file_direct_write(struct kiocb *
 	 * i_sem is held, which protects generic_osync_inode() from
 	 * livelocking.
 	 */
-	if (written >= 0 && file->f_flags & O_SYNC)
-		generic_osync_inode(inode, mapping, OSYNC_METADATA);
+	if (written >= 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) {
+		int err = generic_osync_inode(inode, mapping, OSYNC_METADATA);
+		if (err < 0)
+			written = err;
+	}
 	if (written == count && !is_sync_kiocb(iocb))
 		written = -EIOCBQUEUED;
 	return written;
@@ -2027,7 +1954,9 @@ generic_file_buffered_write(struct kiocb
 				if (unlikely(nr_segs > 1)) {
 					filemap_set_next_iovec(&cur_iov,
 							&iov_base, status);
-					buf = cur_iov->iov_base + iov_base;
+					if (count)
+						buf = cur_iov->iov_base +
+							iov_base;
 				} else {
 					iov_base += status;
 				}
diff --git a/mm/filemap.h b/mm/filemap.h
new file mode 100644
--- /dev/null
+++ b/mm/filemap.h
@@ -0,0 +1,94 @@
+/*
+ *	linux/mm/filemap.h
+ *
+ * Copyright (C) 1994-1999  Linus Torvalds
+ */
+
+#ifndef __FILEMAP_H
+#define __FILEMAP_H
+
+#include <linux/types.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/highmem.h>
+#include <linux/uio.h>
+#include <linux/config.h>
+#include <asm/uaccess.h>
+
+size_t
+__filemap_copy_from_user_iovec(char *vaddr,
+			       const struct iovec *iov,
+			       size_t base,
+			       size_t bytes);
+
+/*
+ * Copy as much as we can into the page and return the number of bytes which
+ * were sucessfully copied.  If a fault is encountered then clear the page
+ * out to (offset+bytes) and return the number of bytes which were copied.
+ */
+static inline size_t
+filemap_copy_from_user(struct page *page, unsigned long offset,
+			const char __user *buf, unsigned bytes)
+{
+	char *kaddr;
+	int left;
+
+	kaddr = kmap_atomic(page, KM_USER0);
+	left = __copy_from_user_inatomic(kaddr + offset, buf, bytes);
+	kunmap_atomic(kaddr, KM_USER0);
+
+	if (left != 0) {
+		/* Do it the slow way */
+		kaddr = kmap(page);
+		left = __copy_from_user(kaddr + offset, buf, bytes);
+		kunmap(page);
+	}
+	return bytes - left;
+}
+
+/*
+ * This has the same sideeffects and return value as filemap_copy_from_user().
+ * The difference is that on a fault we need to memset the remainder of the
+ * page (out to offset+bytes), to emulate filemap_copy_from_user()'s
+ * single-segment behaviour.
+ */
+static inline size_t
+filemap_copy_from_user_iovec(struct page *page, unsigned long offset,
+			const struct iovec *iov, size_t base, size_t bytes)
+{
+	char *kaddr;
+	size_t copied;
+
+	kaddr = kmap_atomic(page, KM_USER0);
+	copied = __filemap_copy_from_user_iovec(kaddr + offset, iov,
+						base, bytes);
+	kunmap_atomic(kaddr, KM_USER0);
+	if (copied != bytes) {
+		kaddr = kmap(page);
+		copied = __filemap_copy_from_user_iovec(kaddr + offset, iov,
+							base, bytes);
+		kunmap(page);
+	}
+	return copied;
+}
+
+static inline void
+filemap_set_next_iovec(const struct iovec **iovp, size_t *basep, size_t bytes)
+{
+	const struct iovec *iov = *iovp;
+	size_t base = *basep;
+
+	while (bytes) {
+		int copy = min(bytes, iov->iov_len - base);
+
+		bytes -= copy;
+		base += copy;
+		if (iov->iov_len == base) {
+			iov++;
+			base = 0;
+		}
+	}
+	*iovp = iov;
+	*basep = base;
+}
+#endif
diff --git a/mm/filemap_xip.c b/mm/filemap_xip.c
new file mode 100644
--- /dev/null
+++ b/mm/filemap_xip.c
@@ -0,0 +1,440 @@
+/*
+ *	linux/mm/filemap_xip.c
+ *
+ * Copyright (C) 2005 IBM Corporation
+ * Author: Carsten Otte <cotte@de.ibm.com>
+ *
+ * derived from linux/mm/filemap.c - Copyright (C) Linus Torvalds
+ *
+ */
+
+#include <linux/fs.h>
+#include <linux/pagemap.h>
+#include <linux/module.h>
+#include <linux/uio.h>
+#include <linux/rmap.h>
+#include <asm/tlbflush.h>
+#include "filemap.h"
+
+/*
+ * This is a file read routine for execute in place files, and uses
+ * the mapping->a_ops->get_xip_page() function for the actual low-level
+ * stuff.
+ *
+ * Note the struct file* is not used at all.  It may be NULL.
+ */
+static void
+do_xip_mapping_read(struct address_space *mapping,
+		    struct file_ra_state *_ra,
+		    struct file *filp,
+		    loff_t *ppos,
+		    read_descriptor_t *desc,
+		    read_actor_t actor)
+{
+	struct inode *inode = mapping->host;
+	unsigned long index, end_index, offset;
+	loff_t isize;
+
+	BUG_ON(!mapping->a_ops->get_xip_page);
+
+	index = *ppos >> PAGE_CACHE_SHIFT;
+	offset = *ppos & ~PAGE_CACHE_MASK;
+
+	isize = i_size_read(inode);
+	if (!isize)
+		goto out;
+
+	end_index = (isize - 1) >> PAGE_CACHE_SHIFT;
+	for (;;) {
+		struct page *page;
+		unsigned long nr, ret;
+
+		/* nr is the maximum number of bytes to copy from this page */
+		nr = PAGE_CACHE_SIZE;
+		if (index >= end_index) {
+			if (index > end_index)
+				goto out;
+			nr = ((isize - 1) & ~PAGE_CACHE_MASK) + 1;
+			if (nr <= offset) {
+				goto out;
+			}
+		}
+		nr = nr - offset;
+
+		page = mapping->a_ops->get_xip_page(mapping,
+			index*(PAGE_SIZE/512), 0);
+		if (!page)
+			goto no_xip_page;
+		if (unlikely(IS_ERR(page))) {
+			if (PTR_ERR(page) == -ENODATA) {
+				/* sparse */
+				page = ZERO_PAGE(0);
+			} else {
+				desc->error = PTR_ERR(page);
+				goto out;
+			}
+		}
+
+		/* If users can be writing to this page using arbitrary
+		 * virtual addresses, take care about potential aliasing
+		 * before reading the page on the kernel side.
+		 */
+		if (mapping_writably_mapped(mapping))
+			flush_dcache_page(page);
+
+		/*
+		 * Ok, we have the page, so now we can copy it to user space...
+		 *
+		 * The actor routine returns how many bytes were actually used..
+		 * NOTE! This may not be the same as how much of a user buffer
+		 * we filled up (we may be padding etc), so we can only update
+		 * "pos" here (the actor routine has to update the user buffer
+		 * pointers and the remaining count).
+		 */
+		ret = actor(desc, page, offset, nr);
+		offset += ret;
+		index += offset >> PAGE_CACHE_SHIFT;
+		offset &= ~PAGE_CACHE_MASK;
+
+		if (ret == nr && desc->count)
+			continue;
+		goto out;
+
+no_xip_page:
+		/* Did not get the page. Report it */
+		desc->error = -EIO;
+		goto out;
+	}
+
+out:
+	*ppos = ((loff_t) index << PAGE_CACHE_SHIFT) + offset;
+	if (filp)
+		file_accessed(filp);
+}
+
+ssize_t
+xip_file_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos)
+{
+	read_descriptor_t desc;
+
+	if (!access_ok(VERIFY_WRITE, buf, len))
+		return -EFAULT;
+
+	desc.written = 0;
+	desc.arg.buf = buf;
+	desc.count = len;
+	desc.error = 0;
+
+	do_xip_mapping_read(filp->f_mapping, &filp->f_ra, filp,
+			    ppos, &desc, file_read_actor);
+
+	if (desc.written)
+		return desc.written;
+	else
+		return desc.error;
+}
+EXPORT_SYMBOL_GPL(xip_file_read);
+
+ssize_t
+xip_file_sendfile(struct file *in_file, loff_t *ppos,
+	     size_t count, read_actor_t actor, void *target)
+{
+	read_descriptor_t desc;
+
+	if (!count)
+		return 0;
+
+	desc.written = 0;
+	desc.count = count;
+	desc.arg.data = target;
+	desc.error = 0;
+
+	do_xip_mapping_read(in_file->f_mapping, &in_file->f_ra, in_file,
+			    ppos, &desc, actor);
+	if (desc.written)
+		return desc.written;
+	return desc.error;
+}
+EXPORT_SYMBOL_GPL(xip_file_sendfile);
+
+/*
+ * __xip_unmap is invoked from xip_unmap and
+ * xip_write
+ *
+ * This function walks all vmas of the address_space and unmaps the
+ * ZERO_PAGE when found at pgoff. Should it go in rmap.c?
+ */
+static void
+__xip_unmap (struct address_space * mapping,
+		     unsigned long pgoff)
+{
+	struct vm_area_struct *vma;
+	struct mm_struct *mm;
+	struct prio_tree_iter iter;
+	unsigned long address;
+	pte_t *pte;
+	pte_t pteval;
+
+	spin_lock(&mapping->i_mmap_lock);
+	vma_prio_tree_foreach(vma, &iter, &mapping->i_mmap, pgoff, pgoff) {
+		mm = vma->vm_mm;
+		address = vma->vm_start +
+			((pgoff - vma->vm_pgoff) << PAGE_SHIFT);
+		BUG_ON(address < vma->vm_start || address >= vma->vm_end);
+		/*
+		 * We need the page_table_lock to protect us from page faults,
+		 * munmap, fork, etc...
+		 */
+		pte = page_check_address(ZERO_PAGE(address), mm,
+					 address);
+		if (!IS_ERR(pte)) {
+			/* Nuke the page table entry. */
+			flush_cache_page(vma, address, pte_pfn(*pte));
+			pteval = ptep_clear_flush(vma, address, pte);
+			BUG_ON(pte_dirty(pteval));
+			pte_unmap(pte);
+			spin_unlock(&mm->page_table_lock);
+		}
+	}
+	spin_unlock(&mapping->i_mmap_lock);
+}
+
+/*
+ * xip_nopage() is invoked via the vma operations vector for a
+ * mapped memory region to read in file data during a page fault.
+ *
+ * This function is derived from filemap_nopage, but used for execute in place
+ */
+static struct page *
+xip_file_nopage(struct vm_area_struct * area,
+		   unsigned long address,
+		   int *type)
+{
+	struct file *file = area->vm_file;
+	struct address_space *mapping = file->f_mapping;
+	struct inode *inode = mapping->host;
+	struct page *page;
+	unsigned long size, pgoff, endoff;
+
+	pgoff = ((address - area->vm_start) >> PAGE_CACHE_SHIFT)
+		+ area->vm_pgoff;
+	endoff = ((area->vm_end - area->vm_start) >> PAGE_CACHE_SHIFT)
+		+ area->vm_pgoff;
+
+	size = (i_size_read(inode) + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
+	if (pgoff >= size) {
+		return NULL;
+	}
+
+	page = mapping->a_ops->get_xip_page(mapping, pgoff*(PAGE_SIZE/512), 0);
+	if (!IS_ERR(page)) {
+		return page;
+	}
+	if (PTR_ERR(page) != -ENODATA)
+		return NULL;
+
+	/* sparse block */
+	if ((area->vm_flags & (VM_WRITE | VM_MAYWRITE)) &&
+	    (area->vm_flags & (VM_SHARED| VM_MAYSHARE)) &&
+	    (!(mapping->host->i_sb->s_flags & MS_RDONLY))) {
+		/* maybe shared writable, allocate new block */
+		page = mapping->a_ops->get_xip_page (mapping,
+			pgoff*(PAGE_SIZE/512), 1);
+		if (IS_ERR(page))
+			return NULL;
+		/* unmap page at pgoff from all other vmas */
+		__xip_unmap(mapping, pgoff);
+	} else {
+		/* not shared and writable, use ZERO_PAGE() */
+		page = ZERO_PAGE(address);
+	}
+
+	return page;
+}
+
+static struct vm_operations_struct xip_file_vm_ops = {
+	.nopage         = xip_file_nopage,
+};
+
+int xip_file_mmap(struct file * file, struct vm_area_struct * vma)
+{
+	BUG_ON(!file->f_mapping->a_ops->get_xip_page);
+
+	file_accessed(file);
+	vma->vm_ops = &xip_file_vm_ops;
+	return 0;
+}
+EXPORT_SYMBOL_GPL(xip_file_mmap);
+
+static ssize_t
+__xip_file_write(struct file *filp, const char __user *buf,
+		  size_t count, loff_t pos, loff_t *ppos)
+{
+	struct address_space * mapping = filp->f_mapping;
+	struct address_space_operations *a_ops = mapping->a_ops;
+	struct inode 	*inode = mapping->host;
+	long		status = 0;
+	struct page	*page;
+	size_t		bytes;
+	ssize_t		written = 0;
+
+	BUG_ON(!mapping->a_ops->get_xip_page);
+
+	do {
+		unsigned long index;
+		unsigned long offset;
+		size_t copied;
+
+		offset = (pos & (PAGE_CACHE_SIZE -1)); /* Within page */
+		index = pos >> PAGE_CACHE_SHIFT;
+		bytes = PAGE_CACHE_SIZE - offset;
+		if (bytes > count)
+			bytes = count;
+
+		/*
+		 * Bring in the user page that we will copy from _first_.
+		 * Otherwise there's a nasty deadlock on copying from the
+		 * same page as we're writing to, without it being marked
+		 * up-to-date.
+		 */
+		fault_in_pages_readable(buf, bytes);
+
+		page = a_ops->get_xip_page(mapping,
+					   index*(PAGE_SIZE/512), 0);
+		if (IS_ERR(page) && (PTR_ERR(page) == -ENODATA)) {
+			/* we allocate a new page unmap it */
+			page = a_ops->get_xip_page(mapping,
+						   index*(PAGE_SIZE/512), 1);
+			if (!IS_ERR(page))
+				/* unmap page at pgoff from all other vmas */
+				__xip_unmap(mapping, index);
+		}
+
+		if (IS_ERR(page)) {
+			status = PTR_ERR(page);
+			break;
+		}
+
+		copied = filemap_copy_from_user(page, offset, buf, bytes);
+		flush_dcache_page(page);
+		if (likely(copied > 0)) {
+			status = copied;
+
+			if (status >= 0) {
+				written += status;
+				count -= status;
+				pos += status;
+				buf += status;
+			}
+		}
+		if (unlikely(copied != bytes))
+			if (status >= 0)
+				status = -EFAULT;
+		if (status < 0)
+			break;
+	} while (count);
+	*ppos = pos;
+	/*
+	 * No need to use i_size_read() here, the i_size
+	 * cannot change under us because we hold i_sem.
+	 */
+	if (pos > inode->i_size) {
+		i_size_write(inode, pos);
+		mark_inode_dirty(inode);
+	}
+
+	return written ? written : status;
+}
+
+ssize_t
+xip_file_write(struct file *filp, const char __user *buf, size_t len,
+	       loff_t *ppos)
+{
+	struct address_space *mapping = filp->f_mapping;
+	struct inode *inode = mapping->host;
+	size_t count;
+	loff_t pos;
+	ssize_t ret;
+
+	down(&inode->i_sem);
+
+	if (!access_ok(VERIFY_READ, buf, len)) {
+		ret=-EFAULT;
+		goto out_up;
+	}
+
+	pos = *ppos;
+	count = len;
+
+	vfs_check_frozen(inode->i_sb, SB_FREEZE_WRITE);
+
+	/* We can write back this queue in page reclaim */
+	current->backing_dev_info = mapping->backing_dev_info;
+
+	ret = generic_write_checks(filp, &pos, &count, S_ISBLK(inode->i_mode));
+	if (ret)
+		goto out_backing;
+	if (count == 0)
+		goto out_backing;
+
+	ret = remove_suid(filp->f_dentry);
+	if (ret)
+		goto out_backing;
+
+	inode_update_time(inode, 1);
+
+	ret = __xip_file_write (filp, buf, count, pos, ppos);
+
+ out_backing:
+	current->backing_dev_info = NULL;
+ out_up:
+	up(&inode->i_sem);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(xip_file_write);
+
+/*
+ * truncate a page used for execute in place
+ * functionality is analog to block_truncate_page but does use get_xip_page
+ * to get the page instead of page cache
+ */
+int
+xip_truncate_page(struct address_space *mapping, loff_t from)
+{
+	pgoff_t index = from >> PAGE_CACHE_SHIFT;
+	unsigned offset = from & (PAGE_CACHE_SIZE-1);
+	unsigned blocksize;
+	unsigned length;
+	struct page *page;
+	void *kaddr;
+
+	BUG_ON(!mapping->a_ops->get_xip_page);
+
+	blocksize = 1 << mapping->host->i_blkbits;
+	length = offset & (blocksize - 1);
+
+	/* Block boundary? Nothing to do */
+	if (!length)
+		return 0;
+
+	length = blocksize - length;
+
+	page = mapping->a_ops->get_xip_page(mapping,
+					    index*(PAGE_SIZE/512), 0);
+	if (!page)
+		return -ENOMEM;
+	if (unlikely(IS_ERR(page))) {
+		if (PTR_ERR(page) == -ENODATA)
+			/* Hole? No need to truncate */
+			return 0;
+		else
+			return PTR_ERR(page);
+	}
+	kaddr = kmap_atomic(page, KM_USER0);
+	memset(kaddr + offset, 0, length);
+	kunmap_atomic(kaddr, KM_USER0);
+
+	flush_dcache_page(page);
+	return 0;
+}
+EXPORT_SYMBOL_GPL(xip_truncate_page);
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -7,10 +7,14 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/mm.h>
-#include <linux/hugetlb.h>
 #include <linux/sysctl.h>
 #include <linux/highmem.h>
 #include <linux/nodemask.h>
+#include <linux/pagemap.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+
+#include <linux/hugetlb.h>
 
 const unsigned long hugetlb_zero = 0, hugetlb_infinity = ~0UL;
 static unsigned long nr_huge_pages, free_huge_pages;
@@ -249,6 +253,81 @@ struct vm_operations_struct hugetlb_vm_o
 	.nopage = hugetlb_nopage,
 };
 
+static pte_t make_huge_pte(struct vm_area_struct *vma, struct page *page)
+{
+	pte_t entry;
+
+	if (vma->vm_flags & VM_WRITE) {
+		entry =
+		    pte_mkwrite(pte_mkdirty(mk_pte(page, vma->vm_page_prot)));
+	} else {
+		entry = pte_wrprotect(mk_pte(page, vma->vm_page_prot));
+	}
+	entry = pte_mkyoung(entry);
+	entry = pte_mkhuge(entry);
+
+	return entry;
+}
+
+int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src,
+			    struct vm_area_struct *vma)
+{
+	pte_t *src_pte, *dst_pte, entry;
+	struct page *ptepage;
+	unsigned long addr = vma->vm_start;
+	unsigned long end = vma->vm_end;
+
+	while (addr < end) {
+		dst_pte = huge_pte_alloc(dst, addr);
+		if (!dst_pte)
+			goto nomem;
+		src_pte = huge_pte_offset(src, addr);
+		BUG_ON(!src_pte || pte_none(*src_pte)); /* prefaulted */
+		entry = *src_pte;
+		ptepage = pte_page(entry);
+		get_page(ptepage);
+		add_mm_counter(dst, rss, HPAGE_SIZE / PAGE_SIZE);
+		set_huge_pte_at(dst, addr, dst_pte, entry);
+		addr += HPAGE_SIZE;
+	}
+	return 0;
+
+nomem:
+	return -ENOMEM;
+}
+
+void unmap_hugepage_range(struct vm_area_struct *vma, unsigned long start,
+			  unsigned long end)
+{
+	struct mm_struct *mm = vma->vm_mm;
+	unsigned long address;
+	pte_t *ptep;
+	pte_t pte;
+	struct page *page;
+
+	WARN_ON(!is_vm_hugetlb_page(vma));
+	BUG_ON(start & ~HPAGE_MASK);
+	BUG_ON(end & ~HPAGE_MASK);
+
+	for (address = start; address < end; address += HPAGE_SIZE) {
+		ptep = huge_pte_offset(mm, address);
+		if (! ptep)
+			/* This can happen on truncate, or if an
+			 * mmap() is aborted due to an error before
+			 * the prefault */
+			continue;
+
+		pte = huge_ptep_get_and_clear(mm, address, ptep);
+		if (pte_none(pte))
+			continue;
+
+		page = pte_page(pte);
+		put_page(page);
+	}
+	add_mm_counter(mm, rss,  -((end - start) >> PAGE_SHIFT));
+	flush_tlb_range(vma, start, end);
+}
+
 void zap_hugepage_range(struct vm_area_struct *vma,
 			unsigned long start, unsigned long length)
 {
@@ -258,3 +337,108 @@ void zap_hugepage_range(struct vm_area_s
 	unmap_hugepage_range(vma, start, start + length);
 	spin_unlock(&mm->page_table_lock);
 }
+
+int hugetlb_prefault(struct address_space *mapping, struct vm_area_struct *vma)
+{
+	struct mm_struct *mm = current->mm;
+	unsigned long addr;
+	int ret = 0;
+
+	WARN_ON(!is_vm_hugetlb_page(vma));
+	BUG_ON(vma->vm_start & ~HPAGE_MASK);
+	BUG_ON(vma->vm_end & ~HPAGE_MASK);
+
+	hugetlb_prefault_arch_hook(mm);
+
+	spin_lock(&mm->page_table_lock);
+	for (addr = vma->vm_start; addr < vma->vm_end; addr += HPAGE_SIZE) {
+		unsigned long idx;
+		pte_t *pte = huge_pte_alloc(mm, addr);
+		struct page *page;
+
+		if (!pte) {
+			ret = -ENOMEM;
+			goto out;
+		}
+		if (! pte_none(*pte))
+			hugetlb_clean_stale_pgtable(pte);
+
+		idx = ((addr - vma->vm_start) >> HPAGE_SHIFT)
+			+ (vma->vm_pgoff >> (HPAGE_SHIFT - PAGE_SHIFT));
+		page = find_get_page(mapping, idx);
+		if (!page) {
+			/* charge the fs quota first */
+			if (hugetlb_get_quota(mapping)) {
+				ret = -ENOMEM;
+				goto out;
+			}
+			page = alloc_huge_page();
+			if (!page) {
+				hugetlb_put_quota(mapping);
+				ret = -ENOMEM;
+				goto out;
+			}
+			ret = add_to_page_cache(page, mapping, idx, GFP_ATOMIC);
+			if (! ret) {
+				unlock_page(page);
+			} else {
+				hugetlb_put_quota(mapping);
+				free_huge_page(page);
+				goto out;
+			}
+		}
+		add_mm_counter(mm, rss, HPAGE_SIZE / PAGE_SIZE);
+		set_huge_pte_at(mm, addr, pte, make_huge_pte(vma, page));
+	}
+out:
+	spin_unlock(&mm->page_table_lock);
+	return ret;
+}
+
+int follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma,
+			struct page **pages, struct vm_area_struct **vmas,
+			unsigned long *position, int *length, int i)
+{
+	unsigned long vpfn, vaddr = *position;
+	int remainder = *length;
+
+	BUG_ON(!is_vm_hugetlb_page(vma));
+
+	vpfn = vaddr/PAGE_SIZE;
+	while (vaddr < vma->vm_end && remainder) {
+
+		if (pages) {
+			pte_t *pte;
+			struct page *page;
+
+			/* Some archs (sparc64, sh*) have multiple
+			 * pte_ts to each hugepage.  We have to make
+			 * sure we get the first, for the page
+			 * indexing below to work. */
+			pte = huge_pte_offset(mm, vaddr & HPAGE_MASK);
+
+			/* hugetlb should be locked, and hence, prefaulted */
+			WARN_ON(!pte || pte_none(*pte));
+
+			page = &pte_page(*pte)[vpfn % (HPAGE_SIZE/PAGE_SIZE)];
+
+			WARN_ON(!PageCompound(page));
+
+			get_page(page);
+			pages[i] = page;
+		}
+
+		if (vmas)
+			vmas[i] = vma;
+
+		vaddr += PAGE_SIZE;
+		++vpfn;
+		--remainder;
+		++i;
+	}
+
+	*length = remainder;
+	*position = vaddr;
+
+	return i;
+}
diff --git a/mm/madvise.c b/mm/madvise.c
--- a/mm/madvise.c
+++ b/mm/madvise.c
@@ -8,17 +8,47 @@
 #include <linux/mman.h>
 #include <linux/pagemap.h>
 #include <linux/syscalls.h>
+#include <linux/mempolicy.h>
 #include <linux/hugetlb.h>
 
 /*
  * We can potentially split a vm area into separate
  * areas, each area with its own behavior.
  */
-static long madvise_behavior(struct vm_area_struct * vma, unsigned long start,
-			     unsigned long end, int behavior)
+static long madvise_behavior(struct vm_area_struct * vma,
+		     struct vm_area_struct **prev,
+		     unsigned long start, unsigned long end, int behavior)
 {
 	struct mm_struct * mm = vma->vm_mm;
 	int error = 0;
+	pgoff_t pgoff;
+	int new_flags = vma->vm_flags & ~VM_READHINTMASK;
+
+	switch (behavior) {
+	case MADV_SEQUENTIAL:
+		new_flags |= VM_SEQ_READ;
+		break;
+	case MADV_RANDOM:
+		new_flags |= VM_RAND_READ;
+		break;
+	default:
+		break;
+	}
+
+	if (new_flags == vma->vm_flags) {
+		*prev = vma;
+		goto success;
+	}
+
+	pgoff = vma->vm_pgoff + ((start - vma->vm_start) >> PAGE_SHIFT);
+	*prev = vma_merge(mm, *prev, start, end, new_flags, vma->anon_vma,
+				vma->vm_file, pgoff, vma_policy(vma));
+	if (*prev) {
+		vma = *prev;
+		goto success;
+	}
+
+	*prev = vma;
 
 	if (start != vma->vm_start) {
 		error = split_vma(mm, vma, start, 1);
@@ -35,22 +65,12 @@ static long madvise_behavior(struct vm_a
 	/*
 	 * vm_flags is protected by the mmap_sem held in write mode.
 	 */
-	VM_ClearReadHint(vma);
-
-	switch (behavior) {
-	case MADV_SEQUENTIAL:
-		vma->vm_flags |= VM_SEQ_READ;
-		break;
-	case MADV_RANDOM:
-		vma->vm_flags |= VM_RAND_READ;
-		break;
-	default:
-		break;
-	}
+	vma->vm_flags = new_flags;
 
 out:
 	if (error == -ENOMEM)
 		error = -EAGAIN;
+success:
 	return error;
 }
 
@@ -58,13 +78,17 @@ out:
  * Schedule all required I/O operations.  Do not wait for completion.
  */
 static long madvise_willneed(struct vm_area_struct * vma,
+			     struct vm_area_struct ** prev,
 			     unsigned long start, unsigned long end)
 {
 	struct file *file = vma->vm_file;
 
-	if (!file)
-		return -EBADF;
+	if (file->f_mapping->a_ops->get_xip_page) {
+		/* no bad return value, but ignore advice */
+		return 0;
+	}
 
+	*prev = vma;
 	start = ((start - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff;
 	if (end > vma->vm_end)
 		end = vma->vm_end;
@@ -95,8 +119,10 @@ static long madvise_willneed(struct vm_a
  * dirty pages is already available as msync(MS_INVALIDATE).
  */
 static long madvise_dontneed(struct vm_area_struct * vma,
+			     struct vm_area_struct ** prev,
 			     unsigned long start, unsigned long end)
 {
+	*prev = vma;
 	if ((vma->vm_flags & VM_LOCKED) || is_vm_hugetlb_page(vma))
 		return -EINVAL;
 
@@ -111,24 +137,29 @@ static long madvise_dontneed(struct vm_a
 	return 0;
 }
 
-static long madvise_vma(struct vm_area_struct * vma, unsigned long start,
-			unsigned long end, int behavior)
+static long
+madvise_vma(struct vm_area_struct *vma, struct vm_area_struct **prev,
+		unsigned long start, unsigned long end, int behavior)
 {
+	struct file *filp = vma->vm_file;
 	long error = -EBADF;
 
+	if (!filp)
+		goto  out;
+
 	switch (behavior) {
 	case MADV_NORMAL:
 	case MADV_SEQUENTIAL:
 	case MADV_RANDOM:
-		error = madvise_behavior(vma, start, end, behavior);
+		error = madvise_behavior(vma, prev, start, end, behavior);
 		break;
 
 	case MADV_WILLNEED:
-		error = madvise_willneed(vma, start, end);
+		error = madvise_willneed(vma, prev, start, end);
 		break;
 
 	case MADV_DONTNEED:
-		error = madvise_dontneed(vma, start, end);
+		error = madvise_dontneed(vma, prev, start, end);
 		break;
 
 	default:
@@ -136,6 +167,7 @@ static long madvise_vma(struct vm_area_s
 		break;
 	}
 		
+out:
 	return error;
 }
 
@@ -175,8 +207,8 @@ static long madvise_vma(struct vm_area_s
  */
 asmlinkage long sys_madvise(unsigned long start, size_t len_in, int behavior)
 {
-	unsigned long end;
-	struct vm_area_struct * vma;
+	unsigned long end, tmp;
+	struct vm_area_struct * vma, *prev;
 	int unmapped_error = 0;
 	int error = -EINVAL;
 	size_t len;
@@ -202,40 +234,42 @@ asmlinkage long sys_madvise(unsigned lon
 	/*
 	 * If the interval [start,end) covers some unmapped address
 	 * ranges, just ignore them, but return -ENOMEM at the end.
+	 * - different from the way of handling in mlock etc.
 	 */
-	vma = find_vma(current->mm, start);
+	vma = find_vma_prev(current->mm, start, &prev);
+	if (!vma && prev)
+		vma = prev->vm_next;
 	for (;;) {
 		/* Still start < end. */
 		error = -ENOMEM;
 		if (!vma)
 			goto out;
 
-		/* Here start < vma->vm_end. */
+		/* Here start < (end|vma->vm_end). */
 		if (start < vma->vm_start) {
 			unmapped_error = -ENOMEM;
 			start = vma->vm_start;
+			if (start >= end)
+				goto out;
 		}
 
-		/* Here vma->vm_start <= start < vma->vm_end. */
-		if (end <= vma->vm_end) {
-			if (start < end) {
-				error = madvise_vma(vma, start, end,
-							behavior);
-				if (error)
-					goto out;
-			}
-			error = unmapped_error;
-			goto out;
-		}
+		/* Here vma->vm_start <= start < (end|vma->vm_end) */
+		tmp = vma->vm_end;
+		if (end < tmp)
+			tmp = end;
 
-		/* Here vma->vm_start <= start < vma->vm_end < end. */
-		error = madvise_vma(vma, start, vma->vm_end, behavior);
+		/* Here vma->vm_start <= start < tmp <= (end|vma->vm_end). */
+		error = madvise_vma(vma, &prev, start, tmp, behavior);
 		if (error)
 			goto out;
-		start = vma->vm_end;
-		vma = vma->vm_next;
+		start = tmp;
+		if (start < prev->vm_end)
+			start = prev->vm_end;
+		error = unmapped_error;
+		if (start >= end)
+			goto out;
+		vma = prev->vm_next;
 	}
-
 out:
 	up_write(&current->mm->mmap_sem);
 	return error;
diff --git a/mm/memory.c b/mm/memory.c
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -58,7 +58,7 @@
 #include <linux/swapops.h>
 #include <linux/elf.h>
 
-#ifndef CONFIG_DISCONTIGMEM
+#ifndef CONFIG_NEED_MULTIPLE_NODES
 /* use the per-pgdat data instead for discontigmem - mbligh */
 unsigned long max_mapnr;
 struct page *mem_map;
@@ -776,8 +776,8 @@ unsigned long zap_page_range(struct vm_a
  * Do a quick page-table lookup for a single page.
  * mm->page_table_lock must be held.
  */
-static struct page *
-__follow_page(struct mm_struct *mm, unsigned long address, int read, int write)
+static struct page *__follow_page(struct mm_struct *mm, unsigned long address,
+			int read, int write, int accessed)
 {
 	pgd_t *pgd;
 	pud_t *pud;
@@ -818,9 +818,11 @@ __follow_page(struct mm_struct *mm, unsi
 		pfn = pte_pfn(pte);
 		if (pfn_valid(pfn)) {
 			page = pfn_to_page(pfn);
-			if (write && !pte_dirty(pte) && !PageDirty(page))
-				set_page_dirty(page);
-			mark_page_accessed(page);
+			if (accessed) {
+				if (write && !pte_dirty(pte) &&!PageDirty(page))
+					set_page_dirty(page);
+				mark_page_accessed(page);
+			}
 			return page;
 		}
 	}
@@ -829,33 +831,21 @@ out:
 	return NULL;
 }
 
-struct page *
+inline struct page *
 follow_page(struct mm_struct *mm, unsigned long address, int write)
 {
-	return __follow_page(mm, address, /*read*/0, write);
-}
-
-int
-check_user_page_readable(struct mm_struct *mm, unsigned long address)
-{
-	return __follow_page(mm, address, /*read*/1, /*write*/0) != NULL;
+	return __follow_page(mm, address, 0, write, 1);
 }
 
-EXPORT_SYMBOL(check_user_page_readable);
-
-/* 
- * Given a physical address, is there a useful struct page pointing to
- * it?  This may become more complex in the future if we start dealing
- * with IO-aperture pages for direct-IO.
+/*
+ * check_user_page_readable() can be called frm niterrupt context by oprofile,
+ * so we need to avoid taking any non-irq-safe locks
  */
-
-static inline struct page *get_page_map(struct page *page)
+int check_user_page_readable(struct mm_struct *mm, unsigned long address)
 {
-	if (!pfn_valid(page_to_pfn(page)))
-		return NULL;
-	return page;
+	return __follow_page(mm, address, 1, 0, 0) != NULL;
 }
-
+EXPORT_SYMBOL(check_user_page_readable);
 
 static inline int
 untouched_anonymous_page(struct mm_struct* mm, struct vm_area_struct *vma,
@@ -887,7 +877,6 @@ untouched_anonymous_page(struct mm_struc
 	return 0;
 }
 
-
 int get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
 		unsigned long start, int len, int write, int force,
 		struct page **pages, struct vm_area_struct **vmas)
@@ -924,9 +913,13 @@ int get_user_pages(struct task_struct *t
 			pud = pud_offset(pgd, pg);
 			BUG_ON(pud_none(*pud));
 			pmd = pmd_offset(pud, pg);
-			BUG_ON(pmd_none(*pmd));
+			if (pmd_none(*pmd))
+				return i ? : -EFAULT;
 			pte = pte_offset_map(pmd, pg);
-			BUG_ON(pte_none(*pte));
+			if (pte_none(*pte)) {
+				pte_unmap(pte);
+				return i ? : -EFAULT;
+			}
 			if (pages) {
 				pages[i] = pte_page(*pte);
 				get_page(pages[i]);
@@ -951,25 +944,37 @@ int get_user_pages(struct task_struct *t
 		}
 		spin_lock(&mm->page_table_lock);
 		do {
-			struct page *map;
-			int lookup_write = write;
+			int write_access = write;
+			struct page *page;
 
 			cond_resched_lock(&mm->page_table_lock);
-			while (!(map = follow_page(mm, start, lookup_write))) {
+			while (!(page = follow_page(mm, start, write_access))) {
+				int ret;
+
 				/*
 				 * Shortcut for anonymous pages. We don't want
 				 * to force the creation of pages tables for
-				 * insanly big anonymously mapped areas that
+				 * insanely big anonymously mapped areas that
 				 * nobody touched so far. This is important
 				 * for doing a core dump for these mappings.
 				 */
-				if (!lookup_write &&
-				    untouched_anonymous_page(mm,vma,start)) {
-					map = ZERO_PAGE(start);
+				if (!write && untouched_anonymous_page(mm,vma,start)) {
+					page = ZERO_PAGE(start);
 					break;
 				}
 				spin_unlock(&mm->page_table_lock);
-				switch (handle_mm_fault(mm,vma,start,write)) {
+				ret = __handle_mm_fault(mm, vma, start, write_access);
+
+				/*
+				 * The VM_FAULT_WRITE bit tells us that do_wp_page has
+				 * broken COW when necessary, even if maybe_mkwrite
+				 * decided not to set pte_write. We can thus safely do
+				 * subsequent page lookups as if they were reads.
+				 */
+				if (ret & VM_FAULT_WRITE)
+					write_access = 0;
+				
+				switch (ret & ~VM_FAULT_WRITE) {
 				case VM_FAULT_MINOR:
 					tsk->min_flt++;
 					break;
@@ -983,41 +988,24 @@ int get_user_pages(struct task_struct *t
 				default:
 					BUG();
 				}
-				/*
-				 * Now that we have performed a write fault
-				 * and surely no longer have a shared page we
-				 * shouldn't write, we shouldn't ignore an
-				 * unwritable page in the page table if
-				 * we are forcing write access.
-				 */
-				lookup_write = write && !force;
 				spin_lock(&mm->page_table_lock);
 			}
 			if (pages) {
-				pages[i] = get_page_map(map);
-				if (!pages[i]) {
-					spin_unlock(&mm->page_table_lock);
-					while (i--)
-						page_cache_release(pages[i]);
-					i = -EFAULT;
-					goto out;
-				}
-				flush_dcache_page(pages[i]);
-				if (!PageReserved(pages[i]))
-					page_cache_get(pages[i]);
+				pages[i] = page;
+				flush_dcache_page(page);
+				if (!PageReserved(page))
+					page_cache_get(page);
 			}
 			if (vmas)
 				vmas[i] = vma;
 			i++;
 			start += PAGE_SIZE;
 			len--;
-		} while(len && start < vma->vm_end);
+		} while (len && start < vma->vm_end);
 		spin_unlock(&mm->page_table_lock);
-	} while(len);
-out:
+	} while (len);
 	return i;
 }
-
 EXPORT_SYMBOL(get_user_pages);
 
 static int zeromap_pte_range(struct mm_struct *mm, pmd_t *pmd,
@@ -1164,7 +1152,7 @@ int remap_pfn_range(struct vm_area_struc
 {
 	pgd_t *pgd;
 	unsigned long next;
-	unsigned long end = addr + size;
+	unsigned long end = addr + PAGE_ALIGN(size);
 	struct mm_struct *mm = vma->vm_mm;
 	int err;
 
@@ -1249,6 +1237,7 @@ static int do_wp_page(struct mm_struct *
 	struct page *old_page, *new_page;
 	unsigned long pfn = pte_pfn(pte);
 	pte_t entry;
+	int ret;
 
 	if (unlikely(!pfn_valid(pfn))) {
 		/*
@@ -1264,7 +1253,7 @@ static int do_wp_page(struct mm_struct *
 	}
 	old_page = pfn_to_page(pfn);
 
-	if (!TestSetPageLocked(old_page)) {
+	if (PageAnon(old_page) && !TestSetPageLocked(old_page)) {
 		int reuse = can_share_swap_page(old_page);
 		unlock_page(old_page);
 		if (reuse) {
@@ -1276,7 +1265,7 @@ static int do_wp_page(struct mm_struct *
 			lazy_mmu_prot_update(entry);
 			pte_unmap(page_table);
 			spin_unlock(&mm->page_table_lock);
-			return VM_FAULT_MINOR;
+			return VM_FAULT_MINOR|VM_FAULT_WRITE;
 		}
 	}
 	pte_unmap(page_table);
@@ -1303,6 +1292,7 @@ static int do_wp_page(struct mm_struct *
 	/*
 	 * Re-check the pte - we dropped the lock
 	 */
+	ret = VM_FAULT_MINOR;
 	spin_lock(&mm->page_table_lock);
 	page_table = pte_offset_map(pmd, address);
 	if (likely(pte_same(*page_table, pte))) {
@@ -1319,12 +1309,13 @@ static int do_wp_page(struct mm_struct *
 
 		/* Free the old page.. */
 		new_page = old_page;
+		ret |= VM_FAULT_WRITE;
 	}
 	pte_unmap(page_table);
 	page_cache_release(new_page);
 	page_cache_release(old_page);
 	spin_unlock(&mm->page_table_lock);
-	return VM_FAULT_MINOR;
+	return ret;
 
 no_new_page:
 	page_cache_release(old_page);
@@ -1483,7 +1474,7 @@ restart:
  * unmap_mapping_range - unmap the portion of all mmaps
  * in the specified address_space corresponding to the specified
  * page range in the underlying file.
- * @address_space: the address space containing mmaps to be unmapped.
+ * @mapping: the address space containing mmaps to be unmapped.
  * @holebegin: byte in first page to unmap, relative to the start of
  * the underlying file.  This will be rounded down to a PAGE_SIZE
  * boundary.  Note that this is different from vmtruncate(), which
@@ -1711,10 +1702,6 @@ static int do_swap_page(struct mm_struct
 	}
 
 	/* The page isn't present yet, go ahead with the fault. */
-		
-	swap_free(entry);
-	if (vm_swap_full())
-		remove_exclusive_swap_page(page);
 
 	inc_mm_counter(mm, rss);
 	pte = mk_pte(page, vma->vm_page_prot);
@@ -1722,12 +1709,16 @@ static int do_swap_page(struct mm_struct
 		pte = maybe_mkwrite(pte_mkdirty(pte), vma);
 		write_access = 0;
 	}
-	unlock_page(page);
 
 	flush_icache_page(vma, page);
 	set_pte_at(mm, address, page_table, pte);
 	page_add_anon_rmap(page, vma, address);
 
+	swap_free(entry);
+	if (vm_swap_full())
+		remove_exclusive_swap_page(page);
+	unlock_page(page);
+
 	if (write_access) {
 		if (do_wp_page(mm, vma, address,
 				page_table, pmd, pte) == VM_FAULT_OOM)
@@ -2016,7 +2007,6 @@ static inline int handle_pte_fault(struc
 	if (write_access) {
 		if (!pte_write(entry))
 			return do_wp_page(mm, vma, address, pte, pmd, entry);
-
 		entry = pte_mkdirty(entry);
 	}
 	entry = pte_mkyoung(entry);
@@ -2031,7 +2021,7 @@ static inline int handle_pte_fault(struc
 /*
  * By the time we get here, we already hold the mm semaphore
  */
-int handle_mm_fault(struct mm_struct *mm, struct vm_area_struct * vma,
+int __handle_mm_fault(struct mm_struct *mm, struct vm_area_struct * vma,
 		unsigned long address, int write_access)
 {
 	pgd_t *pgd;
diff --git a/mm/mempolicy.c b/mm/mempolicy.c
--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -238,46 +238,80 @@ static struct mempolicy *mpol_new(int mo
 }
 
 /* Ensure all existing pages follow the policy. */
-static int
-verify_pages(struct mm_struct *mm,
-	     unsigned long addr, unsigned long end, unsigned long *nodes)
-{
-	while (addr < end) {
-		struct page *p;
-		pte_t *pte;
-		pmd_t *pmd;
-		pud_t *pud;
-		pgd_t *pgd;
-		pgd = pgd_offset(mm, addr);
-		if (pgd_none(*pgd)) {
-			unsigned long next = (addr + PGDIR_SIZE) & PGDIR_MASK;
-			if (next > addr)
-				break;
-			addr = next;
+static int check_pte_range(struct mm_struct *mm, pmd_t *pmd,
+		unsigned long addr, unsigned long end, unsigned long *nodes)
+{
+	pte_t *orig_pte;
+	pte_t *pte;
+
+	spin_lock(&mm->page_table_lock);
+	orig_pte = pte = pte_offset_map(pmd, addr);
+	do {
+		unsigned long pfn;
+		unsigned int nid;
+
+		if (!pte_present(*pte))
 			continue;
-		}
-		pud = pud_offset(pgd, addr);
-		if (pud_none(*pud)) {
-			addr = (addr + PUD_SIZE) & PUD_MASK;
+		pfn = pte_pfn(*pte);
+		if (!pfn_valid(pfn))
 			continue;
-		}
-		pmd = pmd_offset(pud, addr);
-		if (pmd_none(*pmd)) {
-			addr = (addr + PMD_SIZE) & PMD_MASK;
+		nid = pfn_to_nid(pfn);
+		if (!test_bit(nid, nodes))
+			break;
+	} while (pte++, addr += PAGE_SIZE, addr != end);
+	pte_unmap(orig_pte);
+	spin_unlock(&mm->page_table_lock);
+	return addr != end;
+}
+
+static inline int check_pmd_range(struct mm_struct *mm, pud_t *pud,
+		unsigned long addr, unsigned long end, unsigned long *nodes)
+{
+	pmd_t *pmd;
+	unsigned long next;
+
+	pmd = pmd_offset(pud, addr);
+	do {
+		next = pmd_addr_end(addr, end);
+		if (pmd_none_or_clear_bad(pmd))
 			continue;
-		}
-		p = NULL;
-		pte = pte_offset_map(pmd, addr);
-		if (pte_present(*pte))
-			p = pte_page(*pte);
-		pte_unmap(pte);
-		if (p) {
-			unsigned nid = page_to_nid(p);
-			if (!test_bit(nid, nodes))
-				return -EIO;
-		}
-		addr += PAGE_SIZE;
-	}
+		if (check_pte_range(mm, pmd, addr, next, nodes))
+			return -EIO;
+	} while (pmd++, addr = next, addr != end);
+	return 0;
+}
+
+static inline int check_pud_range(struct mm_struct *mm, pgd_t *pgd,
+		unsigned long addr, unsigned long end, unsigned long *nodes)
+{
+	pud_t *pud;
+	unsigned long next;
+
+	pud = pud_offset(pgd, addr);
+	do {
+		next = pud_addr_end(addr, end);
+		if (pud_none_or_clear_bad(pud))
+			continue;
+		if (check_pmd_range(mm, pud, addr, next, nodes))
+			return -EIO;
+	} while (pud++, addr = next, addr != end);
+	return 0;
+}
+
+static inline int check_pgd_range(struct mm_struct *mm,
+		unsigned long addr, unsigned long end, unsigned long *nodes)
+{
+	pgd_t *pgd;
+	unsigned long next;
+
+	pgd = pgd_offset(mm, addr);
+	do {
+		next = pgd_addr_end(addr, end);
+		if (pgd_none_or_clear_bad(pgd))
+			continue;
+		if (check_pud_range(mm, pgd, addr, next, nodes))
+			return -EIO;
+	} while (pgd++, addr = next, addr != end);
 	return 0;
 }
 
@@ -299,7 +333,7 @@ check_range(struct mm_struct *mm, unsign
 		if (prev && prev->vm_end < vma->vm_start)
 			return ERR_PTR(-EFAULT);
 		if ((flags & MPOL_MF_STRICT) && !is_vm_hugetlb_page(vma)) {
-			err = verify_pages(vma->vm_mm,
+			err = check_pgd_range(vma->vm_mm,
 					   vma->vm_start, vma->vm_end, nodes);
 			if (err) {
 				first = ERR_PTR(err);
@@ -409,7 +443,7 @@ asmlinkage long sys_set_mempolicy(int mo
 	struct mempolicy *new;
 	DECLARE_BITMAP(nodes, MAX_NUMNODES);
 
-	if (mode > MPOL_MAX)
+	if (mode < 0 || mode > MPOL_MAX)
 		return -EINVAL;
 	err = get_nodes(nodes, nmask, maxnode, mode);
 	if (err)
@@ -721,7 +755,7 @@ static struct page *alloc_page_interleav
 	zl = NODE_DATA(nid)->node_zonelists + (gfp & GFP_ZONEMASK);
 	page = __alloc_pages(gfp, order, zl);
 	if (page && page_zone(page) == zl->zones[0]) {
-		zl->zones[0]->pageset[get_cpu()].interleave_hit++;
+		zone_pcp(zl->zones[0],get_cpu())->interleave_hit++;
 		put_cpu();
 	}
 	return page;
@@ -1104,11 +1138,11 @@ void mpol_free_shared_policy(struct shar
 	while (next) {
 		n = rb_entry(next, struct sp_node, nd);
 		next = rb_next(&n->nd);
+		rb_erase(&n->nd, &p->root);
 		mpol_free(n->policy);
 		kmem_cache_free(sn_cache, n);
 	}
 	spin_unlock(&p->lock);
-	p->root = RB_ROOT;
 }
 
 /* assumes fs == KERNEL_DS */
diff --git a/mm/mempool.c b/mm/mempool.c
--- a/mm/mempool.c
+++ b/mm/mempool.c
@@ -51,16 +51,23 @@ static void free_pool(mempool_t *pool)
  * functions might sleep - as long as the mempool_alloc function is not called
  * from IRQ contexts.
  */
-mempool_t * mempool_create(int min_nr, mempool_alloc_t *alloc_fn,
+mempool_t *mempool_create(int min_nr, mempool_alloc_t *alloc_fn,
 				mempool_free_t *free_fn, void *pool_data)
 {
-	mempool_t *pool;
+	return  mempool_create_node(min_nr,alloc_fn,free_fn, pool_data,-1);
+}
+EXPORT_SYMBOL(mempool_create);
 
-	pool = kmalloc(sizeof(*pool), GFP_KERNEL);
+mempool_t *mempool_create_node(int min_nr, mempool_alloc_t *alloc_fn,
+			mempool_free_t *free_fn, void *pool_data, int node_id)
+{
+	mempool_t *pool;
+	pool = kmalloc_node(sizeof(*pool), GFP_KERNEL, node_id);
 	if (!pool)
 		return NULL;
 	memset(pool, 0, sizeof(*pool));
-	pool->elements = kmalloc(min_nr * sizeof(void *), GFP_KERNEL);
+	pool->elements = kmalloc_node(min_nr * sizeof(void *),
+					GFP_KERNEL, node_id);
 	if (!pool->elements) {
 		kfree(pool);
 		return NULL;
@@ -87,7 +94,7 @@ mempool_t * mempool_create(int min_nr, m
 	}
 	return pool;
 }
-EXPORT_SYMBOL(mempool_create);
+EXPORT_SYMBOL(mempool_create_node);
 
 /**
  * mempool_resize - resize an existing memory pool
@@ -197,8 +204,8 @@ void * mempool_alloc(mempool_t *pool, un
 {
 	void *element;
 	unsigned long flags;
-	DEFINE_WAIT(wait);
-	int gfp_temp;
+	wait_queue_t wait;
+	unsigned int gfp_temp;
 
 	might_sleep_if(gfp_mask & __GFP_WAIT);
 
@@ -228,6 +235,7 @@ repeat_alloc:
 
 	/* Now start performing page reclaim */
 	gfp_temp = gfp_mask;
+	init_wait(&wait);
 	prepare_to_wait(&pool->wait, &wait, TASK_UNINTERRUPTIBLE);
 	smp_mb();
 	if (!pool->curr_nr)
diff --git a/mm/mmap.c b/mm/mmap.c
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -143,7 +143,11 @@ int __vm_enough_memory(long pages, int c
 	   leave 3% of the size of this process for other processes */
 	allowed -= current->mm->total_vm / 32;
 
-	if (atomic_read(&vm_committed_space) < allowed)
+	/*
+	 * cast `allowed' as a signed long because vm_committed_space
+	 * sometimes has a negative value
+	 */
+	if (atomic_read(&vm_committed_space) < (long)allowed)
 		return 0;
 
 	vm_unacct_memory(pages);
@@ -1175,7 +1179,12 @@ arch_get_unmapped_area(struct file *filp
 		    (!vma || addr + len <= vma->vm_start))
 			return addr;
 	}
-	start_addr = addr = mm->free_area_cache;
+	if (len > mm->cached_hole_size) {
+	        start_addr = addr = mm->free_area_cache;
+	} else {
+	        start_addr = addr = TASK_UNMAPPED_BASE;
+	        mm->cached_hole_size = 0;
+	}
 
 full_search:
 	for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
@@ -1186,7 +1195,9 @@ full_search:
 			 * some holes.
 			 */
 			if (start_addr != TASK_UNMAPPED_BASE) {
-				start_addr = addr = TASK_UNMAPPED_BASE;
+				addr = TASK_UNMAPPED_BASE;
+			        start_addr = addr;
+				mm->cached_hole_size = 0;
 				goto full_search;
 			}
 			return -ENOMEM;
@@ -1198,19 +1209,22 @@ full_search:
 			mm->free_area_cache = addr + len;
 			return addr;
 		}
+		if (addr + mm->cached_hole_size < vma->vm_start)
+		        mm->cached_hole_size = vma->vm_start - addr;
 		addr = vma->vm_end;
 	}
 }
 #endif	
 
-void arch_unmap_area(struct vm_area_struct *area)
+void arch_unmap_area(struct mm_struct *mm, unsigned long addr)
 {
 	/*
 	 * Is this a new hole at the lowest possible address?
 	 */
-	if (area->vm_start >= TASK_UNMAPPED_BASE &&
-			area->vm_start < area->vm_mm->free_area_cache)
-		area->vm_mm->free_area_cache = area->vm_start;
+	if (addr >= TASK_UNMAPPED_BASE && addr < mm->free_area_cache) {
+		mm->free_area_cache = addr;
+		mm->cached_hole_size = ~0UL;
+	}
 }
 
 /*
@@ -1240,6 +1254,12 @@ arch_get_unmapped_area_topdown(struct fi
 			return addr;
 	}
 
+	/* check if free_area_cache is useful for us */
+	if (len <= mm->cached_hole_size) {
+ 	        mm->cached_hole_size = 0;
+ 		mm->free_area_cache = mm->mmap_base;
+ 	}
+
 	/* either no address requested or can't fit in requested address hole */
 	addr = mm->free_area_cache;
 
@@ -1251,6 +1271,9 @@ arch_get_unmapped_area_topdown(struct fi
 			return (mm->free_area_cache = addr-len);
 	}
 
+	if (mm->mmap_base < len)
+		goto bottomup;
+
 	addr = mm->mmap_base-len;
 
 	do {
@@ -1264,38 +1287,45 @@ arch_get_unmapped_area_topdown(struct fi
 			/* remember the address as a hint for next time */
 			return (mm->free_area_cache = addr);
 
+ 		/* remember the largest hole we saw so far */
+ 		if (addr + mm->cached_hole_size < vma->vm_start)
+ 		        mm->cached_hole_size = vma->vm_start - addr;
+
 		/* try just below the current vma->vm_start */
 		addr = vma->vm_start-len;
 	} while (len < vma->vm_start);
 
+bottomup:
 	/*
 	 * A failed mmap() very likely causes application failure,
 	 * so fall back to the bottom-up function here. This scenario
 	 * can happen with large stack limits and large mmap()
 	 * allocations.
 	 */
-	mm->free_area_cache = TASK_UNMAPPED_BASE;
+	mm->cached_hole_size = ~0UL;
+  	mm->free_area_cache = TASK_UNMAPPED_BASE;
 	addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
 	/*
 	 * Restore the topdown base:
 	 */
 	mm->free_area_cache = mm->mmap_base;
+	mm->cached_hole_size = ~0UL;
 
 	return addr;
 }
 #endif
 
-void arch_unmap_area_topdown(struct vm_area_struct *area)
+void arch_unmap_area_topdown(struct mm_struct *mm, unsigned long addr)
 {
 	/*
 	 * Is this a new hole at the highest possible address?
 	 */
-	if (area->vm_end > area->vm_mm->free_area_cache)
-		area->vm_mm->free_area_cache = area->vm_end;
+	if (addr > mm->free_area_cache)
+		mm->free_area_cache = addr;
 
 	/* dont allow allocations above current base */
-	if (area->vm_mm->free_area_cache > area->vm_mm->mmap_base)
-		area->vm_mm->free_area_cache = area->vm_mm->mmap_base;
+	if (mm->free_area_cache > mm->mmap_base)
+		mm->free_area_cache = mm->mmap_base;
 }
 
 unsigned long
@@ -1595,7 +1625,6 @@ static void unmap_vma(struct mm_struct *
 	if (area->vm_flags & VM_LOCKED)
 		area->vm_mm->locked_vm -= len >> PAGE_SHIFT;
 	vm_stat_unaccount(area);
-	area->vm_mm->unmap_area(area);
 	remove_vm_struct(area);
 }
 
@@ -1649,6 +1678,7 @@ detach_vmas_to_be_unmapped(struct mm_str
 {
 	struct vm_area_struct **insertion_point;
 	struct vm_area_struct *tail_vma = NULL;
+	unsigned long addr;
 
 	insertion_point = (prev ? &prev->vm_next : &mm->mmap);
 	do {
@@ -1659,6 +1689,11 @@ detach_vmas_to_be_unmapped(struct mm_str
 	} while (vma && vma->vm_start < end);
 	*insertion_point = vma;
 	tail_vma->vm_next = NULL;
+	if (mm->unmap_area == arch_unmap_area)
+		addr = prev ? prev->vm_end : mm->mmap_base;
+	else
+		addr = vma ?  vma->vm_start : mm->mmap_base;
+	mm->unmap_area(mm, addr);
 	mm->mmap_cache = NULL;		/* Kill the cache. */
 }
 
diff --git a/mm/mremap.c b/mm/mremap.c
--- a/mm/mremap.c
+++ b/mm/mremap.c
@@ -229,6 +229,7 @@ static unsigned long move_vma(struct vm_
 	 * since do_munmap() will decrement it by old_len == new_len
 	 */
 	mm->total_vm += new_len >> PAGE_SHIFT;
+	__vm_stat_account(mm, vma->vm_flags, vma->vm_file, new_len>>PAGE_SHIFT);
 
 	if (do_munmap(mm, old_addr, old_len) < 0) {
 		/* OOM: unable to split vma, just get accounts right */
@@ -243,7 +244,6 @@ static unsigned long move_vma(struct vm_
 			vma->vm_next->vm_flags |= VM_ACCOUNT;
 	}
 
-	__vm_stat_account(mm, vma->vm_flags, vma->vm_file, new_len>>PAGE_SHIFT);
 	if (vm_flags & VM_LOCKED) {
 		mm->locked_vm += new_len >> PAGE_SHIFT;
 		if (new_len > old_len)
diff --git a/mm/msync.c b/mm/msync.c
--- a/mm/msync.c
+++ b/mm/msync.c
@@ -34,6 +34,8 @@ static void sync_pte_range(struct vm_are
 
 		if (!pte_present(*pte))
 			continue;
+		if (!pte_maybe_dirty(*pte))
+			continue;
 		pfn = pte_pfn(*pte);
 		if (!pfn_valid(pfn))
 			continue;
diff --git a/mm/nommu.c b/mm/nommu.c
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -1067,7 +1067,7 @@ unsigned long arch_get_unmapped_area(str
 	return -ENOMEM;
 }
 
-void arch_unmap_area(struct vm_area_struct *area)
+void arch_unmap_area(struct mm_struct *mm, unsigned long addr)
 {
 }
 
@@ -1167,7 +1167,11 @@ int __vm_enough_memory(long pages, int c
 	   leave 3% of the size of this process for other processes */
 	allowed -= current->mm->total_vm / 32;
 
-	if (atomic_read(&vm_committed_space) < allowed)
+	/*
+	 * cast `allowed' as a signed long because vm_committed_space
+	 * sometimes has a negative value
+	 */
+	if (atomic_read(&vm_committed_space) < (long)allowed)
 		return 0;
 
 	vm_unacct_memory(pages);
diff --git a/mm/oom_kill.c b/mm/oom_kill.c
--- a/mm/oom_kill.c
+++ b/mm/oom_kill.c
@@ -253,11 +253,17 @@ static struct mm_struct *oom_kill_proces
  * OR try to be smart about which process to kill. Note that we
  * don't have to be perfect here, we just have to be good.
  */
-void out_of_memory(unsigned int __nocast gfp_mask)
+void out_of_memory(unsigned int __nocast gfp_mask, int order)
 {
 	struct mm_struct *mm = NULL;
 	task_t * p;
 
+	if (printk_ratelimit()) {
+		printk("oom-killer: gfp_mask=0x%x, order=%d\n",
+			gfp_mask, order);
+		show_mem();
+	}
+
 	read_lock(&tasklist_lock);
 retry:
 	p = select_bad_process();
@@ -268,12 +274,9 @@ retry:
 	/* Found nothing?!?! Either we hang forever, or we panic. */
 	if (!p) {
 		read_unlock(&tasklist_lock);
-		show_free_areas();
 		panic("Out of memory and no killable processes...\n");
 	}
 
-	printk("oom-killer: gfp_mask=0x%x\n", gfp_mask);
-	show_free_areas();
 	mm = oom_kill_process(p);
 	if (!mm)
 		goto retry;
diff --git a/mm/page-writeback.c b/mm/page-writeback.c
--- a/mm/page-writeback.c
+++ b/mm/page-writeback.c
@@ -354,7 +354,7 @@ static void background_writeout(unsigned
  * the whole world.  Returns 0 if a pdflush thread was dispatched.  Returns
  * -1 if all pdflush threads were busy.
  */
-int wakeup_bdflush(long nr_pages)
+int wakeup_pdflush(long nr_pages)
 {
 	if (nr_pages == 0) {
 		struct writeback_state wbs;
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -68,7 +68,7 @@ EXPORT_SYMBOL(nr_swap_pages);
  * Used by page_zone() to look up the address of the struct zone whose
  * id is encoded in the upper bits of page->flags
  */
-struct zone *zone_table[1 << (ZONES_SHIFT + NODES_SHIFT)];
+struct zone *zone_table[1 << ZONETABLE_SHIFT];
 EXPORT_SYMBOL(zone_table);
 
 static char *zone_names[MAX_NR_ZONES] = { "DMA", "Normal", "HighMem" };
@@ -105,11 +105,13 @@ static void bad_page(const char *functio
 	printk(KERN_EMERG "Backtrace:\n");
 	dump_stack();
 	printk(KERN_EMERG "Trying to fix it up, but a reboot is needed\n");
-	page->flags &= ~(1 << PG_private	|
+	page->flags &= ~(1 << PG_lru	|
+			1 << PG_private |
 			1 << PG_locked	|
-			1 << PG_lru	|
 			1 << PG_active	|
 			1 << PG_dirty	|
+			1 << PG_reclaim |
+			1 << PG_slab    |
 			1 << PG_swapcache |
 			1 << PG_writeback);
 	set_page_count(page, 0);
@@ -440,14 +442,17 @@ void set_page_refs(struct page *page, in
  */
 static void prep_new_page(struct page *page, int order)
 {
-	if (page->mapping || page_mapcount(page) ||
-	    (page->flags & (
+	if (	page_mapcount(page) ||
+		page->mapping != NULL ||
+		page_count(page) != 0 ||
+		(page->flags & (
+			1 << PG_lru	|
 			1 << PG_private	|
 			1 << PG_locked	|
-			1 << PG_lru	|
 			1 << PG_active	|
 			1 << PG_dirty	|
 			1 << PG_reclaim	|
+			1 << PG_slab    |
 			1 << PG_swapcache |
 			1 << PG_writeback )))
 		bad_page(__FUNCTION__, page);
@@ -511,6 +516,36 @@ static int rmqueue_bulk(struct zone *zon
 	return allocated;
 }
 
+#ifdef CONFIG_NUMA
+/* Called from the slab reaper to drain remote pagesets */
+void drain_remote_pages(void)
+{
+	struct zone *zone;
+	int i;
+	unsigned long flags;
+
+	local_irq_save(flags);
+	for_each_zone(zone) {
+		struct per_cpu_pageset *pset;
+
+		/* Do not drain local pagesets */
+		if (zone->zone_pgdat->node_id == numa_node_id())
+			continue;
+
+		pset = zone->pageset[smp_processor_id()];
+		for (i = 0; i < ARRAY_SIZE(pset->pcp); i++) {
+			struct per_cpu_pages *pcp;
+
+			pcp = &pset->pcp[i];
+			if (pcp->count)
+				pcp->count -= free_pages_bulk(zone, pcp->count,
+						&pcp->list, 0);
+		}
+	}
+	local_irq_restore(flags);
+}
+#endif
+
 #if defined(CONFIG_PM) || defined(CONFIG_HOTPLUG_CPU)
 static void __drain_pages(unsigned int cpu)
 {
@@ -520,7 +555,7 @@ static void __drain_pages(unsigned int c
 	for_each_zone(zone) {
 		struct per_cpu_pageset *pset;
 
-		pset = &zone->pageset[cpu];
+		pset = zone_pcp(zone, cpu);
 		for (i = 0; i < ARRAY_SIZE(pset->pcp); i++) {
 			struct per_cpu_pages *pcp;
 
@@ -583,12 +618,12 @@ static void zone_statistics(struct zonel
 
 	local_irq_save(flags);
 	cpu = smp_processor_id();
-	p = &z->pageset[cpu];
+	p = zone_pcp(z,cpu);
 	if (pg == orig) {
-		z->pageset[cpu].numa_hit++;
+		p->numa_hit++;
 	} else {
 		p->numa_miss++;
-		zonelist->zones[0]->pageset[cpu].numa_foreign++;
+		zone_pcp(zonelist->zones[0], cpu)->numa_foreign++;
 	}
 	if (pg == NODE_DATA(numa_node_id()))
 		p->local_node++;
@@ -615,12 +650,12 @@ static void fastcall free_hot_cold_page(
 	if (PageAnon(page))
 		page->mapping = NULL;
 	free_pages_check(__FUNCTION__, page);
-	pcp = &zone->pageset[get_cpu()].pcp[cold];
+	pcp = &zone_pcp(zone, get_cpu())->pcp[cold];
 	local_irq_save(flags);
-	if (pcp->count >= pcp->high)
-		pcp->count -= free_pages_bulk(zone, pcp->batch, &pcp->list, 0);
 	list_add(&page->lru, &pcp->list);
 	pcp->count++;
+	if (pcp->count >= pcp->high)
+		pcp->count -= free_pages_bulk(zone, pcp->batch, &pcp->list, 0);
 	local_irq_restore(flags);
 	put_cpu();
 }
@@ -659,7 +694,7 @@ buffered_rmqueue(struct zone *zone, int 
 	if (order == 0) {
 		struct per_cpu_pages *pcp;
 
-		pcp = &zone->pageset[get_cpu()].pcp[cold];
+		pcp = &zone_pcp(zone, get_cpu())->pcp[cold];
 		local_irq_save(flags);
 		if (pcp->count <= pcp->low)
 			pcp->count += rmqueue_bulk(zone, 0,
@@ -724,6 +759,16 @@ int zone_watermark_ok(struct zone *z, in
 	return 1;
 }
 
+static inline int
+should_reclaim_zone(struct zone *z, unsigned int gfp_mask)
+{
+	if (!z->reclaim_pages)
+		return 0;
+	if (gfp_mask & __GFP_NORECLAIM)
+		return 0;
+	return 1;
+}
+
 /*
  * This is the 'heart' of the zoned buddy allocator.
  */
@@ -760,17 +805,32 @@ __alloc_pages(unsigned int __nocast gfp_
 
 	classzone_idx = zone_idx(zones[0]);
 
- restart:
+restart:
 	/* Go through the zonelist once, looking for a zone with enough free */
 	for (i = 0; (z = zones[i]) != NULL; i++) {
-
-		if (!zone_watermark_ok(z, order, z->pages_low,
-				       classzone_idx, 0, 0))
-			continue;
+		int do_reclaim = should_reclaim_zone(z, gfp_mask);
 
 		if (!cpuset_zone_allowed(z))
 			continue;
 
+		/*
+		 * If the zone is to attempt early page reclaim then this loop
+		 * will try to reclaim pages and check the watermark a second
+		 * time before giving up and falling back to the next zone.
+		 */
+zone_reclaim_retry:
+		if (!zone_watermark_ok(z, order, z->pages_low,
+				       classzone_idx, 0, 0)) {
+			if (!do_reclaim)
+				continue;
+			else {
+				zone_reclaim(z, gfp_mask, order);
+				/* Only try reclaim once */
+				do_reclaim = 0;
+				goto zone_reclaim_retry;
+			}
+		}
+
 		page = buffered_rmqueue(z, order, gfp_mask);
 		if (page)
 			goto got_pg;
@@ -829,7 +889,7 @@ rebalance:
 	reclaim_state.reclaimed_slab = 0;
 	p->reclaim_state = &reclaim_state;
 
-	did_some_progress = try_to_free_pages(zones, gfp_mask, order);
+	did_some_progress = try_to_free_pages(zones, gfp_mask);
 
 	p->reclaim_state = NULL;
 	p->flags &= ~PF_MEMALLOC;
@@ -837,12 +897,6 @@ rebalance:
 	cond_resched();
 
 	if (likely(did_some_progress)) {
-		/*
-		 * Go through the zonelist yet one more time, keep
-		 * very high watermark here, this is only to catch
-		 * a parallel oom killing, we must fail if we're still
-		 * under heavy pressure.
-		 */
 		for (i = 0; (z = zones[i]) != NULL; i++) {
 			if (!zone_watermark_ok(z, order, z->pages_min,
 					       classzone_idx, can_try_harder,
@@ -876,7 +930,7 @@ rebalance:
 				goto got_pg;
 		}
 
-		out_of_memory(gfp_mask);
+		out_of_memory(gfp_mask, order);
 		goto restart;
 	}
 
@@ -905,6 +959,7 @@ nopage:
 			" order:%d, mode:0x%x\n",
 			p->comm, order, gfp_mask);
 		dump_stack();
+		show_mem();
 	}
 	return NULL;
 got_pg:
@@ -1006,20 +1061,19 @@ unsigned int nr_free_pages_pgdat(pg_data
 
 static unsigned int nr_free_zone_pages(int offset)
 {
-	pg_data_t *pgdat;
+	/* Just pick one node, since fallback list is circular */
+	pg_data_t *pgdat = NODE_DATA(numa_node_id());
 	unsigned int sum = 0;
 
-	for_each_pgdat(pgdat) {
-		struct zonelist *zonelist = pgdat->node_zonelists + offset;
-		struct zone **zonep = zonelist->zones;
-		struct zone *zone;
+	struct zonelist *zonelist = pgdat->node_zonelists + offset;
+	struct zone **zonep = zonelist->zones;
+	struct zone *zone;
 
-		for (zone = *zonep++; zone; zone = *zonep++) {
-			unsigned long size = zone->present_pages;
-			unsigned long high = zone->pages_high;
-			if (size > high)
-				sum += size - high;
-		}
+	for (zone = *zonep++; zone; zone = *zonep++) {
+		unsigned long size = zone->present_pages;
+		unsigned long high = zone->pages_high;
+		if (size > high)
+			sum += size - high;
 	}
 
 	return sum;
@@ -1114,7 +1168,7 @@ void get_full_page_state(struct page_sta
 	__get_page_state(ret, sizeof(*ret) / sizeof(unsigned long));
 }
 
-unsigned long __read_page_state(unsigned offset)
+unsigned long __read_page_state(unsigned long offset)
 {
 	unsigned long ret = 0;
 	int cpu;
@@ -1128,7 +1182,7 @@ unsigned long __read_page_state(unsigned
 	return ret;
 }
 
-void __mod_page_state(unsigned offset, unsigned long delta)
+void __mod_page_state(unsigned long offset, unsigned long delta)
 {
 	unsigned long flags;
 	void* ptr;
@@ -1237,22 +1291,23 @@ void show_free_areas(void)
 			if (!cpu_possible(cpu))
 				continue;
 
-			pageset = zone->pageset + cpu;
+			pageset = zone_pcp(zone, cpu);
 
 			for (temperature = 0; temperature < 2; temperature++)
-				printk("cpu %d %s: low %d, high %d, batch %d\n",
+				printk("cpu %d %s: low %d, high %d, batch %d used:%d\n",
 					cpu,
 					temperature ? "cold" : "hot",
 					pageset->pcp[temperature].low,
 					pageset->pcp[temperature].high,
-					pageset->pcp[temperature].batch);
+					pageset->pcp[temperature].batch,
+					pageset->pcp[temperature].count);
 		}
 	}
 
 	get_page_state(&ps);
 	get_zone_counts(&active, &inactive, &free);
 
-	printk("\nFree pages: %11ukB (%ukB HighMem)\n",
+	printk("Free pages: %11ukB (%ukB HighMem)\n",
 		K(nr_free_pages()),
 		K(nr_free_highpages()));
 
@@ -1587,11 +1642,17 @@ static void __init calculate_zone_totalp
 void __init memmap_init_zone(unsigned long size, int nid, unsigned long zone,
 		unsigned long start_pfn)
 {
-	struct page *start = pfn_to_page(start_pfn);
 	struct page *page;
+	unsigned long end_pfn = start_pfn + size;
+	unsigned long pfn;
 
-	for (page = start; page < (start + size); page++) {
-		set_page_zone(page, NODEZONE(nid, zone));
+	for (pfn = start_pfn; pfn < end_pfn; pfn++, page++) {
+		if (!early_pfn_valid(pfn))
+			continue;
+		if (!early_pfn_in_nid(pfn, nid))
+			continue;
+		page = pfn_to_page(pfn);
+		set_page_links(page, zone, nid, pfn);
 		set_page_count(page, 0);
 		reset_page_mapcount(page);
 		SetPageReserved(page);
@@ -1599,9 +1660,8 @@ void __init memmap_init_zone(unsigned lo
 #ifdef WANT_PAGE_VIRTUAL
 		/* The shift won't overflow because ZONE_NORMAL is below 4G. */
 		if (!is_highmem_idx(zone))
-			set_page_address(page, __va(start_pfn << PAGE_SHIFT));
+			set_page_address(page, __va(pfn << PAGE_SHIFT));
 #endif
-		start_pfn++;
 	}
 }
 
@@ -1615,11 +1675,181 @@ void zone_init_free_lists(struct pglist_
 	}
 }
 
+#define ZONETABLE_INDEX(x, zone_nr)	((x << ZONES_SHIFT) | zone_nr)
+void zonetable_add(struct zone *zone, int nid, int zid, unsigned long pfn,
+		unsigned long size)
+{
+	unsigned long snum = pfn_to_section_nr(pfn);
+	unsigned long end = pfn_to_section_nr(pfn + size);
+
+	if (FLAGS_HAS_NODE)
+		zone_table[ZONETABLE_INDEX(nid, zid)] = zone;
+	else
+		for (; snum <= end; snum++)
+			zone_table[ZONETABLE_INDEX(snum, zid)] = zone;
+}
+
 #ifndef __HAVE_ARCH_MEMMAP_INIT
 #define memmap_init(size, nid, zone, start_pfn) \
 	memmap_init_zone((size), (nid), (zone), (start_pfn))
 #endif
 
+static int __devinit zone_batchsize(struct zone *zone)
+{
+	int batch;
+
+	/*
+	 * The per-cpu-pages pools are set to around 1000th of the
+	 * size of the zone.  But no more than 1/4 of a meg - there's
+	 * no point in going beyond the size of L2 cache.
+	 *
+	 * OK, so we don't know how big the cache is.  So guess.
+	 */
+	batch = zone->present_pages / 1024;
+	if (batch * PAGE_SIZE > 256 * 1024)
+		batch = (256 * 1024) / PAGE_SIZE;
+	batch /= 4;		/* We effectively *= 4 below */
+	if (batch < 1)
+		batch = 1;
+
+	/*
+	 * Clamp the batch to a 2^n - 1 value. Having a power
+	 * of 2 value was found to be more likely to have
+	 * suboptimal cache aliasing properties in some cases.
+	 *
+	 * For example if 2 tasks are alternately allocating
+	 * batches of pages, one task can end up with a lot
+	 * of pages of one half of the possible page colors
+	 * and the other with pages of the other colors.
+	 */
+	batch = (1 << fls(batch + batch/2)) - 1;
+	return batch;
+}
+
+inline void setup_pageset(struct per_cpu_pageset *p, unsigned long batch)
+{
+	struct per_cpu_pages *pcp;
+
+	pcp = &p->pcp[0];		/* hot */
+	pcp->count = 0;
+	pcp->low = 2 * batch;
+	pcp->high = 6 * batch;
+	pcp->batch = max(1UL, 1 * batch);
+	INIT_LIST_HEAD(&pcp->list);
+
+	pcp = &p->pcp[1];		/* cold*/
+	pcp->count = 0;
+	pcp->low = 0;
+	pcp->high = 2 * batch;
+	pcp->batch = max(1UL, 1 * batch);
+	INIT_LIST_HEAD(&pcp->list);
+}
+
+#ifdef CONFIG_NUMA
+/*
+ * Boot pageset table. One per cpu which is going to be used for all
+ * zones and all nodes. The parameters will be set in such a way
+ * that an item put on a list will immediately be handed over to
+ * the buddy list. This is safe since pageset manipulation is done
+ * with interrupts disabled.
+ *
+ * Some NUMA counter updates may also be caught by the boot pagesets.
+ *
+ * The boot_pagesets must be kept even after bootup is complete for
+ * unused processors and/or zones. They do play a role for bootstrapping
+ * hotplugged processors.
+ *
+ * zoneinfo_show() and maybe other functions do
+ * not check if the processor is online before following the pageset pointer.
+ * Other parts of the kernel may not check if the zone is available.
+ */
+static struct per_cpu_pageset
+	boot_pageset[NR_CPUS];
+
+/*
+ * Dynamically allocate memory for the
+ * per cpu pageset array in struct zone.
+ */
+static int __devinit process_zones(int cpu)
+{
+	struct zone *zone, *dzone;
+
+	for_each_zone(zone) {
+
+		zone->pageset[cpu] = kmalloc_node(sizeof(struct per_cpu_pageset),
+					 GFP_KERNEL, cpu_to_node(cpu));
+		if (!zone->pageset[cpu])
+			goto bad;
+
+		setup_pageset(zone->pageset[cpu], zone_batchsize(zone));
+	}
+
+	return 0;
+bad:
+	for_each_zone(dzone) {
+		if (dzone == zone)
+			break;
+		kfree(dzone->pageset[cpu]);
+		dzone->pageset[cpu] = NULL;
+	}
+	return -ENOMEM;
+}
+
+static inline void free_zone_pagesets(int cpu)
+{
+#ifdef CONFIG_NUMA
+	struct zone *zone;
+
+	for_each_zone(zone) {
+		struct per_cpu_pageset *pset = zone_pcp(zone, cpu);
+
+		zone_pcp(zone, cpu) = NULL;
+		kfree(pset);
+	}
+#endif
+}
+
+static int __devinit pageset_cpuup_callback(struct notifier_block *nfb,
+		unsigned long action,
+		void *hcpu)
+{
+	int cpu = (long)hcpu;
+	int ret = NOTIFY_OK;
+
+	switch (action) {
+		case CPU_UP_PREPARE:
+			if (process_zones(cpu))
+				ret = NOTIFY_BAD;
+			break;
+#ifdef CONFIG_HOTPLUG_CPU
+		case CPU_DEAD:
+			free_zone_pagesets(cpu);
+			break;
+#endif
+		default:
+			break;
+	}
+	return ret;
+}
+
+static struct notifier_block pageset_notifier =
+	{ &pageset_cpuup_callback, NULL, 0 };
+
+void __init setup_per_cpu_pageset()
+{
+	int err;
+
+	/* Initialize per_cpu_pageset for cpu 0.
+	 * A cpuup callback will do this for every cpu
+	 * as it comes online
+	 */
+	err = process_zones(smp_processor_id());
+	BUG_ON(err);
+	register_cpu_notifier(&pageset_notifier);
+}
+
+#endif
+
 /*
  * Set up the zone data structures:
  *   - mark all pages reserved
@@ -1630,7 +1860,6 @@ static void __init free_area_init_core(s
 		unsigned long *zones_size, unsigned long *zholes_size)
 {
 	unsigned long i, j;
-	const unsigned long zone_required_alignment = 1UL << (MAX_ORDER-1);
 	int cpu, nid = pgdat->node_id;
 	unsigned long zone_start_pfn = pgdat->node_start_pfn;
 
@@ -1643,7 +1872,6 @@ static void __init free_area_init_core(s
 		unsigned long size, realsize;
 		unsigned long batch;
 
-		zone_table[NODEZONE(nid, j)] = zone;
 		realsize = size = zones_size[j];
 		if (zholes_size)
 			realsize -= zholes_size[j];
@@ -1662,48 +1890,16 @@ static void __init free_area_init_core(s
 
 		zone->temp_priority = zone->prev_priority = DEF_PRIORITY;
 
-		/*
-		 * The per-cpu-pages pools are set to around 1000th of the
-		 * size of the zone.  But no more than 1/4 of a meg - there's
-		 * no point in going beyond the size of L2 cache.
-		 *
-		 * OK, so we don't know how big the cache is.  So guess.
-		 */
-		batch = zone->present_pages / 1024;
-		if (batch * PAGE_SIZE > 256 * 1024)
-			batch = (256 * 1024) / PAGE_SIZE;
-		batch /= 4;		/* We effectively *= 4 below */
-		if (batch < 1)
-			batch = 1;
-
-		/*
-		 * Clamp the batch to a 2^n - 1 value. Having a power
-		 * of 2 value was found to be more likely to have
-		 * suboptimal cache aliasing properties in some cases.
-		 *
-		 * For example if 2 tasks are alternately allocating
-		 * batches of pages, one task can end up with a lot
-		 * of pages of one half of the possible page colors
-		 * and the other with pages of the other colors.
-		 */
-		batch = (1 << fls(batch + batch/2)) - 1;
+		batch = zone_batchsize(zone);
 
 		for (cpu = 0; cpu < NR_CPUS; cpu++) {
-			struct per_cpu_pages *pcp;
-
-			pcp = &zone->pageset[cpu].pcp[0];	/* hot */
-			pcp->count = 0;
-			pcp->low = 2 * batch;
-			pcp->high = 6 * batch;
-			pcp->batch = 1 * batch;
-			INIT_LIST_HEAD(&pcp->list);
-
-			pcp = &zone->pageset[cpu].pcp[1];	/* cold */
-			pcp->count = 0;
-			pcp->low = 0;
-			pcp->high = 2 * batch;
-			pcp->batch = 1 * batch;
-			INIT_LIST_HEAD(&pcp->list);
+#ifdef CONFIG_NUMA
+			/* Early boot. Slab allocator not functional yet */
+			zone->pageset[cpu] = &boot_pageset[cpu];
+			setup_pageset(&boot_pageset[cpu],0);
+#else
+			setup_pageset(zone_pcp(zone,cpu), batch);
+#endif
 		}
 		printk(KERN_DEBUG "  %s zone: %lu pages, LIFO batch:%lu\n",
 				zone_names[j], realsize, batch);
@@ -1713,6 +1909,7 @@ static void __init free_area_init_core(s
 		zone->nr_scan_inactive = 0;
 		zone->nr_active = 0;
 		zone->nr_inactive = 0;
+		atomic_set(&zone->reclaim_in_progress, -1);
 		if (!size)
 			continue;
 
@@ -1735,11 +1932,10 @@ static void __init free_area_init_core(s
 		zone->zone_mem_map = pfn_to_page(zone_start_pfn);
 		zone->zone_start_pfn = zone_start_pfn;
 
-		if ((zone_start_pfn) & (zone_required_alignment-1))
-			printk(KERN_CRIT "BUG: wrong zone alignment, it will crash\n");
-
 		memmap_init(size, nid, j, zone_start_pfn);
 
+		zonetable_add(zone, nid, j, zone_start_pfn, size);
+
 		zone_start_pfn += size;
 
 		zone_init_free_lists(pgdat, zone, zone->spanned_pages);
@@ -1748,24 +1944,30 @@ static void __init free_area_init_core(s
 
 static void __init alloc_node_mem_map(struct pglist_data *pgdat)
 {
-	unsigned long size;
-
 	/* Skip empty nodes */
 	if (!pgdat->node_spanned_pages)
 		return;
 
+#ifdef CONFIG_FLAT_NODE_MEM_MAP
 	/* ia64 gets its own node_mem_map, before this, without bootmem */
 	if (!pgdat->node_mem_map) {
+		unsigned long size;
+		struct page *map;
+
 		size = (pgdat->node_spanned_pages + 1) * sizeof(struct page);
-		pgdat->node_mem_map = alloc_bootmem_node(pgdat, size);
+		map = alloc_remap(pgdat->node_id, size);
+		if (!map)
+			map = alloc_bootmem_node(pgdat, size);
+		pgdat->node_mem_map = map;
 	}
-#ifndef CONFIG_DISCONTIGMEM
+#ifdef CONFIG_FLATMEM
 	/*
 	 * With no DISCONTIG, the global mem_map is just set as node 0's
 	 */
 	if (pgdat == NODE_DATA(0))
 		mem_map = NODE_DATA(0)->node_mem_map;
 #endif
+#endif /* CONFIG_FLAT_NODE_MEM_MAP */
 }
 
 void __init free_area_init_node(int nid, struct pglist_data *pgdat,
@@ -1781,18 +1983,18 @@ void __init free_area_init_node(int nid,
 	free_area_init_core(pgdat, zones_size, zholes_size);
 }
 
-#ifndef CONFIG_DISCONTIGMEM
+#ifndef CONFIG_NEED_MULTIPLE_NODES
 static bootmem_data_t contig_bootmem_data;
 struct pglist_data contig_page_data = { .bdata = &contig_bootmem_data };
 
 EXPORT_SYMBOL(contig_page_data);
+#endif
 
 void __init free_area_init(unsigned long *zones_size)
 {
-	free_area_init_node(0, &contig_page_data, zones_size,
+	free_area_init_node(0, NODE_DATA(0), zones_size,
 			__pa(PAGE_OFFSET) >> PAGE_SHIFT, NULL);
 }
-#endif
 
 #ifdef CONFIG_PROC_FS
 
@@ -1853,6 +2055,115 @@ struct seq_operations fragmentation_op =
 	.show	= frag_show,
 };
 
+/*
+ * Output information about zones in @pgdat.
+ */
+static int zoneinfo_show(struct seq_file *m, void *arg)
+{
+	pg_data_t *pgdat = arg;
+	struct zone *zone;
+	struct zone *node_zones = pgdat->node_zones;
+	unsigned long flags;
+
+	for (zone = node_zones; zone - node_zones < MAX_NR_ZONES; zone++) {
+		int i;
+
+		if (!zone->present_pages)
+			continue;
+
+		spin_lock_irqsave(&zone->lock, flags);
+		seq_printf(m, "Node %d, zone %8s", pgdat->node_id, zone->name);
+		seq_printf(m,
+			   "\n  pages free     %lu"
+			   "\n        min      %lu"
+			   "\n        low      %lu"
+			   "\n        high     %lu"
+			   "\n        active   %lu"
+			   "\n        inactive %lu"
+			   "\n        scanned  %lu (a: %lu i: %lu)"
+			   "\n        spanned  %lu"
+			   "\n        present  %lu",
+			   zone->free_pages,
+			   zone->pages_min,
+			   zone->pages_low,
+			   zone->pages_high,
+			   zone->nr_active,
+			   zone->nr_inactive,
+			   zone->pages_scanned,
+			   zone->nr_scan_active, zone->nr_scan_inactive,
+			   zone->spanned_pages,
+			   zone->present_pages);
+		seq_printf(m,
+			   "\n        protection: (%lu",
+			   zone->lowmem_reserve[0]);
+		for (i = 1; i < ARRAY_SIZE(zone->lowmem_reserve); i++)
+			seq_printf(m, ", %lu", zone->lowmem_reserve[i]);
+		seq_printf(m,
+			   ")"
+			   "\n  pagesets");
+		for (i = 0; i < ARRAY_SIZE(zone->pageset); i++) {
+			struct per_cpu_pageset *pageset;
+			int j;
+
+			pageset = zone_pcp(zone, i);
+			for (j = 0; j < ARRAY_SIZE(pageset->pcp); j++) {
+				if (pageset->pcp[j].count)
+					break;
+			}
+			if (j == ARRAY_SIZE(pageset->pcp))
+				continue;
+			for (j = 0; j < ARRAY_SIZE(pageset->pcp); j++) {
+				seq_printf(m,
+					   "\n    cpu: %i pcp: %i"
+					   "\n              count: %i"
+					   "\n              low:   %i"
+					   "\n              high:  %i"
+					   "\n              batch: %i",
+					   i, j,
+					   pageset->pcp[j].count,
+					   pageset->pcp[j].low,
+					   pageset->pcp[j].high,
+					   pageset->pcp[j].batch);
+			}
+#ifdef CONFIG_NUMA
+			seq_printf(m,
+				   "\n            numa_hit:       %lu"
+				   "\n            numa_miss:      %lu"
+				   "\n            numa_foreign:   %lu"
+				   "\n            interleave_hit: %lu"
+				   "\n            local_node:     %lu"
+				   "\n            other_node:     %lu",
+				   pageset->numa_hit,
+				   pageset->numa_miss,
+				   pageset->numa_foreign,
+				   pageset->interleave_hit,
+				   pageset->local_node,
+				   pageset->other_node);
+#endif
+		}
+		seq_printf(m,
+			   "\n  all_unreclaimable: %u"
+			   "\n  prev_priority:     %i"
+			   "\n  temp_priority:     %i"
+			   "\n  start_pfn:         %lu",
+			   zone->all_unreclaimable,
+			   zone->prev_priority,
+			   zone->temp_priority,
+			   zone->zone_start_pfn);
+		spin_unlock_irqrestore(&zone->lock, flags);
+		seq_putc(m, '\n');
+	}
+	return 0;
+}
+
+struct seq_operations zoneinfo_op = {
+	.start	= frag_start, /* iterate over all zones. The same as in
+			       * fragmentation. */
+	.next	= frag_next,
+	.stop	= frag_stop,
+	.show	= zoneinfo_show,
+};
+
 static char *vmstat_text[] = {
 	"nr_dirty",
 	"nr_writeback",
@@ -2058,10 +2369,10 @@ static void setup_per_zone_pages_min(voi
 				min_pages = 128;
 			zone->pages_min = min_pages;
 		} else {
-			/* if it's a lowmem zone, reserve a number of pages 
+			/* if it's a lowmem zone, reserve a number of pages
 			 * proportionate to the zone's size.
 			 */
-			zone->pages_min = (pages_min * zone->present_pages) / 
+			zone->pages_min = (pages_min * zone->present_pages) /
 			                   lowmem_pages;
 		}
 
diff --git a/mm/page_io.c b/mm/page_io.c
--- a/mm/page_io.c
+++ b/mm/page_io.c
@@ -127,7 +127,7 @@ out:
 	return ret;
 }
 
-#if defined(CONFIG_SOFTWARE_SUSPEND) || defined(CONFIG_PM_DISK)
+#ifdef CONFIG_SOFTWARE_SUSPEND
 /*
  * A scruffy utility function to read or write an arbitrary swap page
  * and wait on the I/O.  The caller must have a ref on the page.
diff --git a/mm/pdflush.c b/mm/pdflush.c
--- a/mm/pdflush.c
+++ b/mm/pdflush.c
@@ -105,7 +105,7 @@ static int __pdflush(struct pdflush_work
 		spin_unlock_irq(&pdflush_lock);
 
 		schedule();
-		if (try_to_freeze(PF_FREEZE)) {
+		if (try_to_freeze()) {
 			spin_lock_irq(&pdflush_lock);
 			continue;
 		}
diff --git a/mm/rmap.c b/mm/rmap.c
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -247,8 +247,8 @@ unsigned long page_address_in_vma(struct
  *
  * On success returns with mapped pte and locked mm->page_table_lock.
  */
-static pte_t *page_check_address(struct page *page, struct mm_struct *mm,
-					unsigned long address)
+pte_t *page_check_address(struct page *page, struct mm_struct *mm,
+			  unsigned long address)
 {
 	pgd_t *pgd;
 	pud_t *pud;
@@ -539,27 +539,6 @@ static int try_to_unmap_one(struct page 
 		goto out_unmap;
 	}
 
-	/*
-	 * Don't pull an anonymous page out from under get_user_pages.
-	 * GUP carefully breaks COW and raises page count (while holding
-	 * page_table_lock, as we have here) to make sure that the page
-	 * cannot be freed.  If we unmap that page here, a user write
-	 * access to the virtual address will bring back the page, but
-	 * its raised count will (ironically) be taken to mean it's not
-	 * an exclusive swap page, do_wp_page will replace it by a copy
-	 * page, and the user never get to see the data GUP was holding
-	 * the original page for.
-	 *
-	 * This test is also useful for when swapoff (unuse_process) has
-	 * to drop page lock: its reference to the page stops existing
-	 * ptes from being unmapped, so swapoff can make progress.
-	 */
-	if (PageSwapCache(page) &&
-	    page_count(page) != page_mapcount(page) + 2) {
-		ret = SWAP_FAIL;
-		goto out_unmap;
-	}
-
 	/* Nuke the page table entry. */
 	flush_cache_page(vma, address, page_to_pfn(page));
 	pteval = ptep_clear_flush(vma, address, pte);
diff --git a/mm/shmem.c b/mm/shmem.c
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -6,8 +6,8 @@
  *		 2000-2001 Christoph Rohland
  *		 2000-2001 SAP AG
  *		 2002 Red Hat Inc.
- * Copyright (C) 2002-2004 Hugh Dickins.
- * Copyright (C) 2002-2004 VERITAS Software Corporation.
+ * Copyright (C) 2002-2005 Hugh Dickins.
+ * Copyright (C) 2002-2005 VERITAS Software Corporation.
  * Copyright (C) 2004 Andi Kleen, SuSE Labs
  *
  * Extended attribute support for tmpfs:
@@ -194,7 +194,7 @@ static DEFINE_SPINLOCK(shmem_swaplist_lo
 static void shmem_free_blocks(struct inode *inode, long pages)
 {
 	struct shmem_sb_info *sbinfo = SHMEM_SB(inode->i_sb);
-	if (sbinfo) {
+	if (sbinfo->max_blocks) {
 		spin_lock(&sbinfo->stat_lock);
 		sbinfo->free_blocks += pages;
 		inode->i_blocks -= pages*BLOCKS_PER_PAGE;
@@ -357,7 +357,7 @@ static swp_entry_t *shmem_swp_alloc(stru
 		 * page (and perhaps indirect index pages) yet to allocate:
 		 * a waste to allocate index if we cannot allocate data.
 		 */
-		if (sbinfo) {
+		if (sbinfo->max_blocks) {
 			spin_lock(&sbinfo->stat_lock);
 			if (sbinfo->free_blocks <= 1) {
 				spin_unlock(&sbinfo->stat_lock);
@@ -677,8 +677,8 @@ static void shmem_delete_inode(struct in
 			spin_unlock(&shmem_swaplist_lock);
 		}
 	}
-	if (sbinfo) {
-		BUG_ON(inode->i_blocks);
+	BUG_ON(inode->i_blocks);
+	if (sbinfo->max_inodes) {
 		spin_lock(&sbinfo->stat_lock);
 		sbinfo->free_inodes++;
 		spin_unlock(&sbinfo->stat_lock);
@@ -1080,7 +1080,7 @@ repeat:
 	} else {
 		shmem_swp_unmap(entry);
 		sbinfo = SHMEM_SB(inode->i_sb);
-		if (sbinfo) {
+		if (sbinfo->max_blocks) {
 			spin_lock(&sbinfo->stat_lock);
 			if (sbinfo->free_blocks == 0 ||
 			    shmem_acct_block(info->flags)) {
@@ -1269,7 +1269,7 @@ shmem_get_inode(struct super_block *sb, 
 	struct shmem_inode_info *info;
 	struct shmem_sb_info *sbinfo = SHMEM_SB(sb);
 
-	if (sbinfo) {
+	if (sbinfo->max_inodes) {
 		spin_lock(&sbinfo->stat_lock);
 		if (!sbinfo->free_inodes) {
 			spin_unlock(&sbinfo->stat_lock);
@@ -1319,7 +1319,7 @@ shmem_get_inode(struct super_block *sb, 
 			mpol_shared_policy_init(&info->policy);
 			break;
 		}
-	} else if (sbinfo) {
+	} else if (sbinfo->max_inodes) {
 		spin_lock(&sbinfo->stat_lock);
 		sbinfo->free_inodes++;
 		spin_unlock(&sbinfo->stat_lock);
@@ -1328,31 +1328,6 @@ shmem_get_inode(struct super_block *sb, 
 }
 
 #ifdef CONFIG_TMPFS
-
-static int shmem_set_size(struct shmem_sb_info *sbinfo,
-			  unsigned long max_blocks, unsigned long max_inodes)
-{
-	int error;
-	unsigned long blocks, inodes;
-
-	spin_lock(&sbinfo->stat_lock);
-	blocks = sbinfo->max_blocks - sbinfo->free_blocks;
-	inodes = sbinfo->max_inodes - sbinfo->free_inodes;
-	error = -EINVAL;
-	if (max_blocks < blocks)
-		goto out;
-	if (max_inodes < inodes)
-		goto out;
-	error = 0;
-	sbinfo->max_blocks  = max_blocks;
-	sbinfo->free_blocks = max_blocks - blocks;
-	sbinfo->max_inodes  = max_inodes;
-	sbinfo->free_inodes = max_inodes - inodes;
-out:
-	spin_unlock(&sbinfo->stat_lock);
-	return error;
-}
-
 static struct inode_operations shmem_symlink_inode_operations;
 static struct inode_operations shmem_symlink_inline_operations;
 
@@ -1607,15 +1582,17 @@ static int shmem_statfs(struct super_blo
 	buf->f_type = TMPFS_MAGIC;
 	buf->f_bsize = PAGE_CACHE_SIZE;
 	buf->f_namelen = NAME_MAX;
-	if (sbinfo) {
-		spin_lock(&sbinfo->stat_lock);
+	spin_lock(&sbinfo->stat_lock);
+	if (sbinfo->max_blocks) {
 		buf->f_blocks = sbinfo->max_blocks;
 		buf->f_bavail = buf->f_bfree = sbinfo->free_blocks;
+	}
+	if (sbinfo->max_inodes) {
 		buf->f_files = sbinfo->max_inodes;
 		buf->f_ffree = sbinfo->free_inodes;
-		spin_unlock(&sbinfo->stat_lock);
 	}
 	/* else leave those fields 0 like simple_statfs */
+	spin_unlock(&sbinfo->stat_lock);
 	return 0;
 }
 
@@ -1672,7 +1649,7 @@ static int shmem_link(struct dentry *old
 	 * but each new link needs a new dentry, pinning lowmem, and
 	 * tmpfs dentries cannot be pruned until they are unlinked.
 	 */
-	if (sbinfo) {
+	if (sbinfo->max_inodes) {
 		spin_lock(&sbinfo->stat_lock);
 		if (!sbinfo->free_inodes) {
 			spin_unlock(&sbinfo->stat_lock);
@@ -1697,7 +1674,7 @@ static int shmem_unlink(struct inode *di
 
 	if (inode->i_nlink > 1 && !S_ISDIR(inode->i_mode)) {
 		struct shmem_sb_info *sbinfo = SHMEM_SB(inode->i_sb);
-		if (sbinfo) {
+		if (sbinfo->max_inodes) {
 			spin_lock(&sbinfo->stat_lock);
 			sbinfo->free_inodes++;
 			spin_unlock(&sbinfo->stat_lock);
@@ -1796,32 +1773,27 @@ static int shmem_symlink(struct inode *d
 	return 0;
 }
 
-static int shmem_follow_link_inline(struct dentry *dentry, struct nameidata *nd)
+static void *shmem_follow_link_inline(struct dentry *dentry, struct nameidata *nd)
 {
 	nd_set_link(nd, (char *)SHMEM_I(dentry->d_inode));
-	return 0;
+	return NULL;
 }
 
-static int shmem_follow_link(struct dentry *dentry, struct nameidata *nd)
+static void *shmem_follow_link(struct dentry *dentry, struct nameidata *nd)
 {
 	struct page *page = NULL;
 	int res = shmem_getpage(dentry->d_inode, 0, &page, SGP_READ, NULL);
 	nd_set_link(nd, res ? ERR_PTR(res) : kmap(page));
-	return 0;
+	return page;
 }
 
-static void shmem_put_link(struct dentry *dentry, struct nameidata *nd)
+static void shmem_put_link(struct dentry *dentry, struct nameidata *nd, void *cookie)
 {
 	if (!IS_ERR(nd_get_link(nd))) {
-		struct page *page;
-
-		page = find_get_page(dentry->d_inode->i_mapping, 0);
-		if (!page)
-			BUG();
+		struct page *page = cookie;
 		kunmap(page);
 		mark_page_accessed(page);
 		page_cache_release(page);
-		page_cache_release(page);
 	}
 }
 
@@ -1921,22 +1893,42 @@ bad_val:
 static int shmem_remount_fs(struct super_block *sb, int *flags, char *data)
 {
 	struct shmem_sb_info *sbinfo = SHMEM_SB(sb);
-	unsigned long max_blocks = 0;
-	unsigned long max_inodes = 0;
+	unsigned long max_blocks = sbinfo->max_blocks;
+	unsigned long max_inodes = sbinfo->max_inodes;
+	unsigned long blocks;
+	unsigned long inodes;
+	int error = -EINVAL;
 
-	if (sbinfo) {
-		max_blocks = sbinfo->max_blocks;
-		max_inodes = sbinfo->max_inodes;
-	}
-	if (shmem_parse_options(data, NULL, NULL, NULL, &max_blocks, &max_inodes))
-		return -EINVAL;
-	/* Keep it simple: disallow limited <-> unlimited remount */
-	if ((max_blocks || max_inodes) == !sbinfo)
-		return -EINVAL;
-	/* But allow the pointless unlimited -> unlimited remount */
-	if (!sbinfo)
-		return 0;
-	return shmem_set_size(sbinfo, max_blocks, max_inodes);
+	if (shmem_parse_options(data, NULL, NULL, NULL,
+				&max_blocks, &max_inodes))
+		return error;
+
+	spin_lock(&sbinfo->stat_lock);
+	blocks = sbinfo->max_blocks - sbinfo->free_blocks;
+	inodes = sbinfo->max_inodes - sbinfo->free_inodes;
+	if (max_blocks < blocks)
+		goto out;
+	if (max_inodes < inodes)
+		goto out;
+	/*
+	 * Those tests also disallow limited->unlimited while any are in
+	 * use, so i_blocks will always be zero when max_blocks is zero;
+	 * but we must separately disallow unlimited->limited, because
+	 * in that case we have no record of how much is already in use.
+	 */
+	if (max_blocks && !sbinfo->max_blocks)
+		goto out;
+	if (max_inodes && !sbinfo->max_inodes)
+		goto out;
+
+	error = 0;
+	sbinfo->max_blocks  = max_blocks;
+	sbinfo->free_blocks = max_blocks - blocks;
+	sbinfo->max_inodes  = max_inodes;
+	sbinfo->free_inodes = max_inodes - inodes;
+out:
+	spin_unlock(&sbinfo->stat_lock);
+	return error;
 }
 #endif
 
@@ -1961,11 +1953,11 @@ static int shmem_fill_super(struct super
 	uid_t uid = current->fsuid;
 	gid_t gid = current->fsgid;
 	int err = -ENOMEM;
-
-#ifdef CONFIG_TMPFS
+	struct shmem_sb_info *sbinfo;
 	unsigned long blocks = 0;
 	unsigned long inodes = 0;
 
+#ifdef CONFIG_TMPFS
 	/*
 	 * Per default we only allow half of the physical ram per
 	 * tmpfs instance, limiting inodes to one per page of lowmem;
@@ -1976,34 +1968,34 @@ static int shmem_fill_super(struct super
 		inodes = totalram_pages - totalhigh_pages;
 		if (inodes > blocks)
 			inodes = blocks;
-
-		if (shmem_parse_options(data, &mode,
-					&uid, &gid, &blocks, &inodes))
+		if (shmem_parse_options(data, &mode, &uid, &gid,
+					&blocks, &inodes))
 			return -EINVAL;
 	}
-
-	if (blocks || inodes) {
-		struct shmem_sb_info *sbinfo;
-		sbinfo = kmalloc(sizeof(struct shmem_sb_info), GFP_KERNEL);
-		if (!sbinfo)
-			return -ENOMEM;
-		sb->s_fs_info = sbinfo;
-		spin_lock_init(&sbinfo->stat_lock);
-		sbinfo->max_blocks = blocks;
-		sbinfo->free_blocks = blocks;
-		sbinfo->max_inodes = inodes;
-		sbinfo->free_inodes = inodes;
-	}
-	sb->s_xattr = shmem_xattr_handlers;
 #else
 	sb->s_flags |= MS_NOUSER;
 #endif
 
+	/* Round up to L1_CACHE_BYTES to resist false sharing */
+	sbinfo = kmalloc(max((int)sizeof(struct shmem_sb_info),
+				L1_CACHE_BYTES), GFP_KERNEL);
+	if (!sbinfo)
+		return -ENOMEM;
+
+	spin_lock_init(&sbinfo->stat_lock);
+	sbinfo->max_blocks = blocks;
+	sbinfo->free_blocks = blocks;
+	sbinfo->max_inodes = inodes;
+	sbinfo->free_inodes = inodes;
+
+	sb->s_fs_info = sbinfo;
 	sb->s_maxbytes = SHMEM_MAX_BYTES;
 	sb->s_blocksize = PAGE_CACHE_SIZE;
 	sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
 	sb->s_magic = TMPFS_MAGIC;
 	sb->s_op = &shmem_ops;
+	sb->s_xattr = shmem_xattr_handlers;
+
 	inode = shmem_get_inode(sb, S_IFDIR | mode, 0);
 	if (!inode)
 		goto failed;
diff --git a/mm/slab.c b/mm/slab.c
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -92,6 +92,7 @@
 #include	<linux/sysctl.h>
 #include	<linux/module.h>
 #include	<linux/rcupdate.h>
+#include	<linux/string.h>
 
 #include	<asm/uaccess.h>
 #include	<asm/cacheflush.h>
@@ -583,7 +584,8 @@ static inline struct array_cache *ac_dat
 	return cachep->array[smp_processor_id()];
 }
 
-static inline kmem_cache_t *__find_general_cachep(size_t size, int gfpflags)
+static inline kmem_cache_t *__find_general_cachep(size_t size,
+						unsigned int __nocast gfpflags)
 {
 	struct cache_sizes *csizep = malloc_sizes;
 
@@ -607,7 +609,8 @@ static inline kmem_cache_t *__find_gener
 	return csizep->cs_cachep;
 }
 
-kmem_cache_t *kmem_find_general_cachep(size_t size, int gfpflags)
+kmem_cache_t *kmem_find_general_cachep(size_t size,
+		unsigned int __nocast gfpflags)
 {
 	return __find_general_cachep(size, gfpflags);
 }
@@ -2099,7 +2102,7 @@ cache_alloc_debugcheck_before(kmem_cache
 #if DEBUG
 static void *
 cache_alloc_debugcheck_after(kmem_cache_t *cachep,
-			unsigned long flags, void *objp, void *caller)
+			unsigned int __nocast flags, void *objp, void *caller)
 {
 	if (!objp)	
 		return objp;
@@ -2371,6 +2374,9 @@ void *kmem_cache_alloc_node(kmem_cache_t
 	struct slab *slabp;
 	kmem_bufctl_t next;
 
+	if (nodeid == -1)
+		return kmem_cache_alloc(cachep, flags);
+
 	for (loop = 0;;loop++) {
 		struct list_head *q;
 
@@ -2438,7 +2444,7 @@ got_slabp:
 }
 EXPORT_SYMBOL(kmem_cache_alloc_node);
 
-void *kmalloc_node(size_t size, int flags, int node)
+void *kmalloc_node(size_t size, unsigned int __nocast flags, int node)
 {
 	kmem_cache_t *cachep;
 
@@ -2620,6 +2626,12 @@ unsigned int kmem_cache_size(kmem_cache_
 }
 EXPORT_SYMBOL(kmem_cache_size);
 
+const char *kmem_cache_name(kmem_cache_t *cachep)
+{
+	return cachep->name;
+}
+EXPORT_SYMBOL_GPL(kmem_cache_name);
+
 struct ccupdate_struct {
 	kmem_cache_t *cachep;
 	struct array_cache *new[NR_CPUS];
@@ -2845,6 +2857,7 @@ next:
 	}
 	check_irq_on();
 	up(&cache_chain_sem);
+	drain_remote_pages();
 	/* Setup the next iteration */
 	schedule_delayed_work(&__get_cpu_var(reap_work), REAPTIMEOUT_CPUC + smp_processor_id());
 }
@@ -3075,3 +3088,26 @@ unsigned int ksize(const void *objp)
 
 	return size;
 }
+
+
+/*
+ * kstrdup - allocate space for and copy an existing string
+ *
+ * @s: the string to duplicate
+ * @gfp: the GFP mask used in the kmalloc() call when allocating memory
+ */
+char *kstrdup(const char *s, unsigned int __nocast gfp)
+{
+	size_t len;
+	char *buf;
+
+	if (!s)
+		return NULL;
+
+	len = strlen(s) + 1;
+	buf = kmalloc(len, gfp);
+	if (buf)
+		memcpy(buf, s, len);
+	return buf;
+}
+EXPORT_SYMBOL(kstrdup);
diff --git a/mm/sparse.c b/mm/sparse.c
new file mode 100644
--- /dev/null
+++ b/mm/sparse.c
@@ -0,0 +1,137 @@
+/*
+ * sparse memory mappings.
+ */
+#include <linux/config.h>
+#include <linux/mm.h>
+#include <linux/mmzone.h>
+#include <linux/bootmem.h>
+#include <linux/module.h>
+#include <asm/dma.h>
+
+/*
+ * Permanent SPARSEMEM data:
+ *
+ * 1) mem_section	- memory sections, mem_map's for valid memory
+ */
+struct mem_section mem_section[NR_MEM_SECTIONS];
+EXPORT_SYMBOL(mem_section);
+
+/* Record a memory area against a node. */
+void memory_present(int nid, unsigned long start, unsigned long end)
+{
+	unsigned long pfn;
+
+	start &= PAGE_SECTION_MASK;
+	for (pfn = start; pfn < end; pfn += PAGES_PER_SECTION) {
+		unsigned long section = pfn_to_section_nr(pfn);
+		if (!mem_section[section].section_mem_map)
+			mem_section[section].section_mem_map = SECTION_MARKED_PRESENT;
+	}
+}
+
+/*
+ * Only used by the i386 NUMA architecures, but relatively
+ * generic code.
+ */
+unsigned long __init node_memmap_size_bytes(int nid, unsigned long start_pfn,
+						     unsigned long end_pfn)
+{
+	unsigned long pfn;
+	unsigned long nr_pages = 0;
+
+	for (pfn = start_pfn; pfn < end_pfn; pfn += PAGES_PER_SECTION) {
+		if (nid != early_pfn_to_nid(pfn))
+			continue;
+
+		if (pfn_valid(pfn))
+			nr_pages += PAGES_PER_SECTION;
+	}
+
+	return nr_pages * sizeof(struct page);
+}
+
+/*
+ * Subtle, we encode the real pfn into the mem_map such that
+ * the identity pfn - section_mem_map will return the actual
+ * physical page frame number.
+ */
+static unsigned long sparse_encode_mem_map(struct page *mem_map, unsigned long pnum)
+{
+	return (unsigned long)(mem_map - (section_nr_to_pfn(pnum)));
+}
+
+/*
+ * We need this if we ever free the mem_maps.  While not implemented yet,
+ * this function is included for parity with its sibling.
+ */
+static __attribute((unused))
+struct page *sparse_decode_mem_map(unsigned long coded_mem_map, unsigned long pnum)
+{
+	return ((struct page *)coded_mem_map) + section_nr_to_pfn(pnum);
+}
+
+static int sparse_init_one_section(struct mem_section *ms,
+		unsigned long pnum, struct page *mem_map)
+{
+	if (!valid_section(ms))
+		return -EINVAL;
+
+	ms->section_mem_map |= sparse_encode_mem_map(mem_map, pnum);
+
+	return 1;
+}
+
+static struct page *sparse_early_mem_map_alloc(unsigned long pnum)
+{
+	struct page *map;
+	int nid = early_pfn_to_nid(section_nr_to_pfn(pnum));
+
+	map = alloc_remap(nid, sizeof(struct page) * PAGES_PER_SECTION);
+	if (map)
+		return map;
+
+	map = alloc_bootmem_node(NODE_DATA(nid),
+			sizeof(struct page) * PAGES_PER_SECTION);
+	if (map)
+		return map;
+
+	printk(KERN_WARNING "%s: allocation failed\n", __FUNCTION__);
+	mem_section[pnum].section_mem_map = 0;
+	return NULL;
+}
+
+/*
+ * Allocate the accumulated non-linear sections, allocate a mem_map
+ * for each and record the physical to section mapping.
+ */
+void sparse_init(void)
+{
+	unsigned long pnum;
+	struct page *map;
+
+	for (pnum = 0; pnum < NR_MEM_SECTIONS; pnum++) {
+		if (!valid_section_nr(pnum))
+			continue;
+
+		map = sparse_early_mem_map_alloc(pnum);
+		if (map)
+			sparse_init_one_section(&mem_section[pnum], pnum, map);
+	}
+}
+
+/*
+ * returns the number of sections whose mem_maps were properly
+ * set.  If this is <=0, then that means that the passed-in
+ * map was not consumed and must be freed.
+ */
+int sparse_add_one_section(unsigned long start_pfn, int nr_pages, struct page *map)
+{
+	struct mem_section *ms = __pfn_to_section(start_pfn);
+
+	if (ms->section_mem_map & SECTION_MARKED_PRESENT)
+		return -EEXIST;
+
+	ms->section_mem_map |= SECTION_MARKED_PRESENT;
+
+	return sparse_init_one_section(ms, pfn_to_section_nr(start_pfn), map);
+}
diff --git a/mm/swapfile.c b/mm/swapfile.c
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -276,61 +276,37 @@ void swap_free(swp_entry_t entry)
 }
 
 /*
- * Check if we're the only user of a swap page,
- * when the page is locked.
+ * How many references to page are currently swapped out?
  */
-static int exclusive_swap_page(struct page *page)
+static inline int page_swapcount(struct page *page)
 {
-	int retval = 0;
-	struct swap_info_struct * p;
+	int count = 0;
+	struct swap_info_struct *p;
 	swp_entry_t entry;
 
 	entry.val = page->private;
 	p = swap_info_get(entry);
 	if (p) {
-		/* Is the only swap cache user the cache itself? */
-		if (p->swap_map[swp_offset(entry)] == 1) {
-			/* Recheck the page count with the swapcache lock held.. */
-			write_lock_irq(&swapper_space.tree_lock);
-			if (page_count(page) == 2)
-				retval = 1;
-			write_unlock_irq(&swapper_space.tree_lock);
-		}
+		/* Subtract the 1 for the swap cache itself */
+		count = p->swap_map[swp_offset(entry)] - 1;
 		swap_info_put(p);
 	}
-	return retval;
+	return count;
 }
 
 /*
  * We can use this swap cache entry directly
  * if there are no other references to it.
- *
- * Here "exclusive_swap_page()" does the real
- * work, but we opportunistically check whether
- * we need to get all the locks first..
  */
 int can_share_swap_page(struct page *page)
 {
-	int retval = 0;
+	int count;
 
-	if (!PageLocked(page))
-		BUG();
-	switch (page_count(page)) {
-	case 3:
-		if (!PagePrivate(page))
-			break;
-		/* Fallthrough */
-	case 2:
-		if (!PageSwapCache(page))
-			break;
-		retval = exclusive_swap_page(page);
-		break;
-	case 1:
-		if (PageReserved(page))
-			break;
-		retval = 1;
-	}
-	return retval;
+	BUG_ON(!PageLocked(page));
+	count = page_mapcount(page);
+	if (count <= 1 && PageSwapCache(page))
+		count += page_swapcount(page);
+	return count == 1;
 }
 
 /*
@@ -529,9 +505,10 @@ static int unuse_mm(struct mm_struct *mm
 
 	if (!down_read_trylock(&mm->mmap_sem)) {
 		/*
-		 * Our reference to the page stops try_to_unmap_one from
-		 * unmapping its ptes, so swapoff can make progress.
+		 * Activate page so shrink_cache is unlikely to unmap its
+		 * ptes while lock is dropped, so swapoff can make progress.
 		 */
+		activate_page(page);
 		unlock_page(page);
 		down_read(&mm->mmap_sem);
 		lock_page(page);
diff --git a/mm/vmscan.c b/mm/vmscan.c
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -74,6 +74,9 @@ struct scan_control {
 
 	int may_writepage;
 
+	/* Can pages be swapped as part of reclaim? */
+	int may_swap;
+
 	/* This context's SWAP_CLUSTER_MAX. If freeing memory for
 	 * suspend, we effectively ignore SWAP_CLUSTER_MAX.
 	 * In this context, it doesn't matter that we scan the
@@ -180,17 +183,20 @@ EXPORT_SYMBOL(remove_shrinker);
  * `lru_pages' represents the number of on-LRU pages in all the zones which
  * are eligible for the caller's allocation attempt.  It is used for balancing
  * slab reclaim versus page reclaim.
+ *
+ * Returns the number of slab objects which we shrunk.
  */
 static int shrink_slab(unsigned long scanned, unsigned int gfp_mask,
 			unsigned long lru_pages)
 {
 	struct shrinker *shrinker;
+	int ret = 0;
 
 	if (scanned == 0)
 		scanned = SWAP_CLUSTER_MAX;
 
 	if (!down_read_trylock(&shrinker_rwsem))
-		return 0;
+		return 1;	/* Assume we'll be able to shrink next time */
 
 	list_for_each_entry(shrinker, &shrinker_list, list) {
 		unsigned long long delta;
@@ -209,10 +215,14 @@ static int shrink_slab(unsigned long sca
 		while (total_scan >= SHRINK_BATCH) {
 			long this_scan = SHRINK_BATCH;
 			int shrink_ret;
+			int nr_before;
 
+			nr_before = (*shrinker->shrinker)(0, gfp_mask);
 			shrink_ret = (*shrinker->shrinker)(this_scan, gfp_mask);
 			if (shrink_ret == -1)
 				break;
+			if (shrink_ret < nr_before)
+				ret += nr_before - shrink_ret;
 			mod_page_state(slabs_scanned, this_scan);
 			total_scan -= this_scan;
 
@@ -222,7 +232,7 @@ static int shrink_slab(unsigned long sca
 		shrinker->nr += total_scan;
 	}
 	up_read(&shrinker_rwsem);
-	return 0;
+	return ret;
 }
 
 /* Called without lock on whether page is mapped, so answer is unstable */
@@ -407,7 +417,7 @@ static int shrink_list(struct list_head 
 		 * Anonymous process memory has backing store?
 		 * Try to allocate it some swap space here.
 		 */
-		if (PageAnon(page) && !PageSwapCache(page)) {
+		if (PageAnon(page) && !PageSwapCache(page) && sc->may_swap) {
 			if (!add_to_swap(page))
 				goto activate_locked;
 		}
@@ -890,7 +900,9 @@ shrink_caches(struct zone **zones, struc
 		if (zone->all_unreclaimable && sc->priority != DEF_PRIORITY)
 			continue;	/* Let kswapd poll it */
 
+		atomic_inc(&zone->reclaim_in_progress);
 		shrink_zone(zone, sc);
+		atomic_dec(&zone->reclaim_in_progress);
 	}
 }
  
@@ -907,8 +919,7 @@ shrink_caches(struct zone **zones, struc
  * holds filesystem locks which prevent writeout this might not work, and the
  * allocation attempt will fail.
  */
-int try_to_free_pages(struct zone **zones,
-		unsigned int gfp_mask, unsigned int order)
+int try_to_free_pages(struct zone **zones, unsigned int gfp_mask)
 {
 	int priority;
 	int ret = 0;
@@ -920,6 +931,7 @@ int try_to_free_pages(struct zone **zone
 
 	sc.gfp_mask = gfp_mask;
 	sc.may_writepage = 0;
+	sc.may_swap = 1;
 
 	inc_page_state(allocstall);
 
@@ -960,7 +972,7 @@ int try_to_free_pages(struct zone **zone
 		 * writeout.  So in laptop mode, write out the whole world.
 		 */
 		if (total_scanned > sc.swap_cluster_max + sc.swap_cluster_max/2) {
-			wakeup_bdflush(laptop_mode ? 0 : total_scanned);
+			wakeup_pdflush(laptop_mode ? 0 : total_scanned);
 			sc.may_writepage = 1;
 		}
 
@@ -1020,6 +1032,7 @@ loop_again:
 	total_reclaimed = 0;
 	sc.gfp_mask = GFP_KERNEL;
 	sc.may_writepage = 0;
+	sc.may_swap = 1;
 	sc.nr_mapped = read_page_state(nr_mapped);
 
 	inc_page_state(pageoutrun);
@@ -1079,6 +1092,7 @@ scan:
 		 */
 		for (i = 0; i <= end_zone; i++) {
 			struct zone *zone = pgdat->node_zones + i;
+			int nr_slab;
 
 			if (zone->present_pages == 0)
 				continue;
@@ -1098,16 +1112,19 @@ scan:
 			sc.nr_reclaimed = 0;
 			sc.priority = priority;
 			sc.swap_cluster_max = nr_pages? nr_pages : SWAP_CLUSTER_MAX;
+			atomic_inc(&zone->reclaim_in_progress);
 			shrink_zone(zone, &sc);
+			atomic_dec(&zone->reclaim_in_progress);
 			reclaim_state->reclaimed_slab = 0;
-			shrink_slab(sc.nr_scanned, GFP_KERNEL, lru_pages);
+			nr_slab = shrink_slab(sc.nr_scanned, GFP_KERNEL,
+						lru_pages);
 			sc.nr_reclaimed += reclaim_state->reclaimed_slab;
 			total_reclaimed += sc.nr_reclaimed;
 			total_scanned += sc.nr_scanned;
 			if (zone->all_unreclaimable)
 				continue;
-			if (zone->pages_scanned >= (zone->nr_active +
-							zone->nr_inactive) * 4)
+			if (nr_slab == 0 && zone->pages_scanned >=
+				    (zone->nr_active + zone->nr_inactive) * 4)
 				zone->all_unreclaimable = 1;
 			/*
 			 * If we've done a decent amount of scanning and
@@ -1199,8 +1216,8 @@ static int kswapd(void *p)
 	order = 0;
 	for ( ; ; ) {
 		unsigned long new_order;
-		if (current->flags & PF_FREEZE)
-			refrigerator(PF_FREEZE);
+
+		try_to_freeze();
 
 		prepare_to_wait(&pgdat->kswapd_wait, &wait, TASK_INTERRUPTIBLE);
 		new_order = pgdat->kswapd_max_order;
@@ -1309,3 +1326,73 @@ static int __init kswapd_init(void)
 }
 
 module_init(kswapd_init)
+
+
+/*
+ * Try to free up some pages from this zone through reclaim.
+ */
+int zone_reclaim(struct zone *zone, unsigned int gfp_mask, unsigned int order)
+{
+	struct scan_control sc;
+	int nr_pages = 1 << order;
+	int total_reclaimed = 0;
+
+	/* The reclaim may sleep, so don't do it if sleep isn't allowed */
+	if (!(gfp_mask & __GFP_WAIT))
+		return 0;
+	if (zone->all_unreclaimable)
+		return 0;
+
+	sc.gfp_mask = gfp_mask;
+	sc.may_writepage = 0;
+	sc.may_swap = 0;
+	sc.nr_mapped = read_page_state(nr_mapped);
+	sc.nr_scanned = 0;
+	sc.nr_reclaimed = 0;
+	/* scan at the highest priority */
+	sc.priority = 0;
+
+	if (nr_pages > SWAP_CLUSTER_MAX)
+		sc.swap_cluster_max = nr_pages;
+	else
+		sc.swap_cluster_max = SWAP_CLUSTER_MAX;
+
+	/* Don't reclaim the zone if there are other reclaimers active */
+	if (!atomic_inc_and_test(&zone->reclaim_in_progress))
+		goto out;
+
+	shrink_zone(zone, &sc);
+	total_reclaimed = sc.nr_reclaimed;
+
+ out:
+	atomic_dec(&zone->reclaim_in_progress);
+	return total_reclaimed;
+}
+
+asmlinkage long sys_set_zone_reclaim(unsigned int node, unsigned int zone,
+				     unsigned int state)
+{
+	struct zone *z;
+	int i;
+
+	if (node >= MAX_NUMNODES || !node_online(node))
+		return -EINVAL;
+
+	/* This will break if we ever add more zones */
+	if (!(zone & (1<<ZONE_DMA|1<<ZONE_NORMAL|1<<ZONE_HIGHMEM)))
+		return -EINVAL;
+
+	for (i = 0; i < MAX_NR_ZONES; i++) {
+		if (!(zone & 1<<i))
+			continue;
+
+		z = &NODE_DATA(node)->node_zones[i];
+
+		if (state)
+			z->reclaim_pages = 1;
+		else
+			z->reclaim_pages = 0;
+	}
+
+	return 0;
+}
diff --git a/net/802/fddi.c b/net/802/fddi.c
--- a/net/802/fddi.c
+++ b/net/802/fddi.c
@@ -122,10 +122,10 @@ static int fddi_rebuild_header(struct sk
  * the proper pointer to the start of packet data (skb->data).
  */
  
-unsigned short fddi_type_trans(struct sk_buff *skb, struct net_device *dev)
+__be16 fddi_type_trans(struct sk_buff *skb, struct net_device *dev)
 {
 	struct fddihdr *fddi = (struct fddihdr *)skb->data;
-	unsigned short type;
+	__be16 type;
 	
 	/*
 	 * Set mac.raw field to point to FC byte, set data field to point
diff --git a/net/802/tr.c b/net/802/tr.c
--- a/net/802/tr.c
+++ b/net/802/tr.c
@@ -251,10 +251,11 @@ void tr_source_route(struct sk_buff *skb
 	unsigned int hash;
 	struct rif_cache *entry;
 	unsigned char *olddata;
+	unsigned long flags;
 	static const unsigned char mcast_func_addr[] 
 		= {0xC0,0x00,0x00,0x04,0x00,0x00};
 	
-	spin_lock_bh(&rif_lock);
+	spin_lock_irqsave(&rif_lock, flags);
 
 	/*
 	 *	Broadcasts are single route as stated in RFC 1042 
@@ -323,7 +324,7 @@ printk("source routing for %02X:%02X:%02
 	else 
 		slack = 18 - ((ntohs(trh->rcf) & TR_RCF_LEN_MASK)>>8);
 	olddata = skb->data;
-	spin_unlock_bh(&rif_lock);
+	spin_unlock_irqrestore(&rif_lock, flags);
 
 	skb_pull(skb, slack);
 	memmove(skb->data, olddata, sizeof(struct trh_hdr) - slack);
@@ -337,10 +338,11 @@ printk("source routing for %02X:%02X:%02
 static void tr_add_rif_info(struct trh_hdr *trh, struct net_device *dev)
 {
 	unsigned int hash, rii_p = 0;
+	unsigned long flags;
 	struct rif_cache *entry;
 
 
-	spin_lock_bh(&rif_lock);
+	spin_lock_irqsave(&rif_lock, flags);
 	
 	/*
 	 *	Firstly see if the entry exists
@@ -378,7 +380,7 @@ printk("adding rif_entry: addr:%02X:%02X
 		if(!entry) 
 		{
 			printk(KERN_DEBUG "tr.c: Couldn't malloc rif cache entry !\n");
-			spin_unlock_bh(&rif_lock);
+			spin_unlock_irqrestore(&rif_lock, flags);
 			return;
 		}
 
@@ -420,7 +422,7 @@ printk("updating rif_entry: addr:%02X:%0
 		    }                                         
            	entry->last_used=jiffies;               
 	}
-	spin_unlock_bh(&rif_lock);
+	spin_unlock_irqrestore(&rif_lock, flags);
 }
 
 /*
@@ -430,9 +432,9 @@ printk("updating rif_entry: addr:%02X:%0
 static void rif_check_expire(unsigned long dummy) 
 {
 	int i;
-	unsigned long next_interval = jiffies + sysctl_tr_rif_timeout/2;
+	unsigned long flags, next_interval = jiffies + sysctl_tr_rif_timeout/2;
 
-	spin_lock_bh(&rif_lock);
+	spin_lock_irqsave(&rif_lock, flags);
 	
 	for(i =0; i < RIF_TABLE_SIZE; i++) {
 		struct rif_cache *entry, **pentry;
@@ -454,7 +456,7 @@ static void rif_check_expire(unsigned lo
 		}
 	}
 	
-	spin_unlock_bh(&rif_lock);
+	spin_unlock_irqrestore(&rif_lock, flags);
 
 	mod_timer(&rif_timer, next_interval);
 
@@ -485,7 +487,7 @@ static struct rif_cache *rif_get_idx(lof
 
 static void *rif_seq_start(struct seq_file *seq, loff_t *pos)
 {
-	spin_lock_bh(&rif_lock);
+	spin_lock_irq(&rif_lock);
 
 	return *pos ? rif_get_idx(*pos - 1) : SEQ_START_TOKEN;
 }
@@ -516,7 +518,7 @@ static void *rif_seq_next(struct seq_fil
 
 static void rif_seq_stop(struct seq_file *seq, void *v)
 {
-	spin_unlock_bh(&rif_lock);
+	spin_unlock_irq(&rif_lock);
 }
 
 static int rif_seq_show(struct seq_file *seq, void *v)
diff --git a/net/8021q/Kconfig b/net/8021q/Kconfig
new file mode 100644
--- /dev/null
+++ b/net/8021q/Kconfig
@@ -0,0 +1,19 @@
+#
+# Configuration for 802.1Q VLAN support
+#
+
+config VLAN_8021Q
+	tristate "802.1Q VLAN Support"
+	---help---
+	  Select this and you will be able to create 802.1Q VLAN interfaces
+	  on your ethernet interfaces.  802.1Q VLAN supports almost
+	  everything a regular ethernet interface does, including
+	  firewalling, bridging, and of course IP traffic.  You will need
+	  the 'vconfig' tool from the VLAN project in order to effectively
+	  use VLANs.  See the VLAN web page for more information:
+	  <http://www.candelatech.com/~greear/vlan.html>
+
+	  To compile this code as a module, choose M here: the module
+	  will be called 8021q.
+
+	  If unsure, say N.
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c
--- a/net/8021q/vlan.c
+++ b/net/8021q/vlan.c
@@ -578,6 +578,14 @@ static int vlan_device_event(struct noti
 			if (!vlandev)
 				continue;
 
+			if (netif_carrier_ok(dev)) {
+				if (!netif_carrier_ok(vlandev))
+					netif_carrier_on(vlandev);
+			} else {
+				if (netif_carrier_ok(vlandev))
+					netif_carrier_off(vlandev);
+			}
+
 			if ((vlandev->state & VLAN_LINK_STATE_MASK) != flgs) {
 				vlandev->state = (vlandev->state &~ VLAN_LINK_STATE_MASK) 
 					| flgs;
diff --git a/net/Kconfig b/net/Kconfig
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -2,7 +2,7 @@
 # Network configuration
 #
 
-menu "Networking support"
+menu "Networking"
 
 config NET
 	bool "Networking support"
@@ -10,7 +10,9 @@ config NET
 	  Unless you really know what you are doing, you should say Y here.
 	  The reason is that some programs need kernel networking support even
 	  when running on a stand-alone machine that isn't connected to any
-	  other computer. If you are upgrading from an older kernel, you
+	  other computer.
+	  
+	  If you are upgrading from an older kernel, you
 	  should consider updating your networking tools too because changes
 	  in the kernel and the tools often go hand in hand. The tools are
 	  contained in the package net-tools, the location and version number
@@ -20,57 +22,14 @@ config NET
 	  recommended to read the NET-HOWTO, available from
 	  <http://www.tldp.org/docs.html#howto>.
 
-menu "Networking options"
-	depends on NET
-
-config PACKET
-	tristate "Packet socket"
-	---help---
-	  The Packet protocol is used by applications which communicate
-	  directly with network devices without an intermediate network
-	  protocol implemented in the kernel, e.g. tcpdump.  If you want them
-	  to work, choose Y.
-
-	  To compile this driver as a module, choose M here: the module will
-	  be called af_packet.
-
-	  If unsure, say Y.
-
-config PACKET_MMAP
-	bool "Packet socket: mmapped IO"
-	depends on PACKET
-	help
-	  If you say Y here, the Packet protocol driver will use an IO
-	  mechanism that results in faster communication.
-
-	  If unsure, say N.
+# Make sure that all config symbols are dependent on NET
+if NET
 
-config UNIX
-	tristate "Unix domain sockets"
-	---help---
-	  If you say Y here, you will include support for Unix domain sockets;
-	  sockets are the standard Unix mechanism for establishing and
-	  accessing network connections.  Many commonly used programs such as
-	  the X Window system and syslog use these sockets even if your
-	  machine is not connected to any network.  Unless you are working on
-	  an embedded system or something similar, you therefore definitely
-	  want to say Y here.
-
-	  To compile this driver as a module, choose M here: the module will be
-	  called unix.  Note that several important services won't work
-	  correctly if you say M here and then neglect to load the module.
-
-	  Say Y unless you know what you are doing.
-
-config NET_KEY
-	tristate "PF_KEY sockets"
-	select XFRM
-	---help---
-	  PF_KEYv2 socket family, compatible to KAME ones.
-	  They are required if you are going to use IPsec tools ported
-	  from KAME.
+menu "Networking options"
 
-	  Say Y unless you know what you are doing.
+source "net/packet/Kconfig"
+source "net/unix/Kconfig"
+source "net/xfrm/Kconfig"
 
 config INET
 	bool "TCP/IP networking"
@@ -94,30 +53,12 @@ config INET
 
 	  Short answer: say Y.
 
+if INET
 source "net/ipv4/Kconfig"
-
-#   IPv6 as module will cause a CRASH if you try to unload it
-config IPV6
-	tristate "The IPv6 protocol"
-	depends on INET
-	default m
-	select CRYPTO if IPV6_PRIVACY
-	select CRYPTO_MD5 if IPV6_PRIVACY
-	---help---
-	  This is complemental support for the IP version 6.
-	  You will still be able to do traditional IPv4 networking as well.
-
-	  For general information about IPv6, see
-	  <http://playground.sun.com/pub/ipng/html/ipng-main.html>.
-	  For Linux IPv6 development information, see <http://www.linux-ipv6.org>.
-	  For specific information about IPv6 under Linux, read the HOWTO at
-	  <http://www.bieringer.de/linux/IPv6/>.
-
-	  To compile this protocol support as a module, choose M here: the 
-	  module will be called ipv6.
-
 source "net/ipv6/Kconfig"
 
+endif # if INET
+
 menuconfig NETFILTER
 	bool "Network packet filtering (replaces ipchains)"
 	---help---
@@ -206,269 +147,16 @@ source "net/bridge/netfilter/Kconfig"
 
 endif
 
-config XFRM
-       bool
-       depends on NET
-
-source "net/xfrm/Kconfig"
-
 source "net/sctp/Kconfig"
-
-config ATM
-	tristate "Asynchronous Transfer Mode (ATM) (EXPERIMENTAL)"
-	depends on EXPERIMENTAL
-	---help---
-	  ATM is a high-speed networking technology for Local Area Networks
-	  and Wide Area Networks.  It uses a fixed packet size and is
-	  connection oriented, allowing for the negotiation of minimum
-	  bandwidth requirements.
-
-	  In order to participate in an ATM network, your Linux box needs an
-	  ATM networking card. If you have that, say Y here and to the driver
-	  of your ATM card below.
-
-	  Note that you need a set of user-space programs to actually make use
-	  of ATM.  See the file <file:Documentation/networking/atm.txt> for
-	  further details.
-
-config ATM_CLIP
-	tristate "Classical IP over ATM (EXPERIMENTAL)"
-	depends on ATM && INET
-	help
-	  Classical IP over ATM for PVCs and SVCs, supporting InARP and
-	  ATMARP. If you want to communication with other IP hosts on your ATM
-	  network, you will typically either say Y here or to "LAN Emulation
-	  (LANE)" below.
-
-config ATM_CLIP_NO_ICMP
-	bool "Do NOT send ICMP if no neighbour (EXPERIMENTAL)"
-	depends on ATM_CLIP
-	help
-	  Normally, an "ICMP host unreachable" message is sent if a neighbour
-	  cannot be reached because there is no VC to it in the kernel's
-	  ATMARP table. This may cause problems when ATMARP table entries are
-	  briefly removed during revalidation. If you say Y here, packets to
-	  such neighbours are silently discarded instead.
-
-config ATM_LANE
-	tristate "LAN Emulation (LANE) support (EXPERIMENTAL)"
-	depends on ATM
-	help
-	  LAN Emulation emulates services of existing LANs across an ATM
-	  network. Besides operating as a normal ATM end station client, Linux
-	  LANE client can also act as an proxy client bridging packets between
-	  ELAN and Ethernet segments. You need LANE if you want to try MPOA.
-
-config ATM_MPOA
-	tristate "Multi-Protocol Over ATM (MPOA) support (EXPERIMENTAL)"
-	depends on ATM && INET && ATM_LANE!=n
-	help
-	  Multi-Protocol Over ATM allows ATM edge devices such as routers,
-	  bridges and ATM attached hosts establish direct ATM VCs across
-	  subnetwork boundaries. These shortcut connections bypass routers
-	  enhancing overall network performance.
-
-config ATM_BR2684
-	tristate "RFC1483/2684 Bridged protocols"
-	depends on ATM && INET
-	help
-	  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.
-
-config ATM_BR2684_IPFILTER
-	bool "Per-VC IP filter kludge"
-	depends on ATM_BR2684
-	help
-	  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.
-
-config BRIDGE
-	tristate "802.1d Ethernet Bridging"
-	---help---
-	  If you say Y here, then your Linux box will be able to act as an
-	  Ethernet bridge, which means that the different Ethernet segments it
-	  is connected to will appear as one Ethernet to the participants.
-	  Several such bridges can work together to create even larger
-	  networks of Ethernets using the IEEE 802.1 spanning tree algorithm.
-	  As this is a standard, Linux bridges will cooperate properly with
-	  other third party bridge products.
-
-	  In order to use the Ethernet bridge, you'll need the bridge
-	  configuration tools; see <file:Documentation/networking/bridge.txt>
-	  for location. Please read the Bridge mini-HOWTO for more
-	  information.
-
-	  If you enable iptables support along with the bridge support then you
-	  turn your bridge into a bridging IP firewall.
-	  iptables will then see the IP packets being bridged, so you need to
-	  take this into account when setting up your firewall rules.
-	  Enabling arptables support when bridging will let arptables see
-	  bridged ARP traffic in the arptables FORWARD chain.
-
-	  To compile this code as a module, choose M here: the module
-	  will be called bridge.
-
-	  If unsure, say N.
-
-config VLAN_8021Q
-	tristate "802.1Q VLAN Support"
-	---help---
-	  Select this and you will be able to create 802.1Q VLAN interfaces
-	  on your ethernet interfaces.  802.1Q VLAN supports almost
-	  everything a regular ethernet interface does, including
-	  firewalling, bridging, and of course IP traffic.  You will need
-	  the 'vconfig' tool from the VLAN project in order to effectively
-	  use VLANs.  See the VLAN web page for more information:
-	  <http://www.candelatech.com/~greear/vlan.html>
-
-	  To compile this code as a module, choose M here: the module
-	  will be called 8021q.
-
-	  If unsure, say N.
-
-config DECNET
-	tristate "DECnet Support"
-	---help---
-	  The DECnet networking protocol was used in many products made by
-	  Digital (now Compaq).  It provides reliable stream and sequenced
-	  packet communications over which run a variety of services similar
-	  to those which run over TCP/IP.
-
-	  To find some tools to use with the kernel layer support, please
-	  look at Patrick Caulfield's web site:
-	  <http://linux-decnet.sourceforge.net/>.
-
-	  More detailed documentation is available in
-	  <file:Documentation/networking/decnet.txt>.
-
-	  Be sure to say Y to "/proc file system support" and "Sysctl support"
-	  below when using DECnet, since you will need sysctl support to aid
-	  in configuration at run time.
-
-	  The DECnet code 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 decnet.
-
+source "net/atm/Kconfig"
+source "net/bridge/Kconfig"
+source "net/8021q/Kconfig"
 source "net/decnet/Kconfig"
-
 source "net/llc/Kconfig"
-
-config IPX
-	tristate "The IPX protocol"
-	select LLC
-	---help---
-	  This is support for the Novell networking protocol, IPX, commonly
-	  used for local networks of Windows machines.  You need it if you
-	  want to access Novell NetWare file or print servers using the Linux
-	  Novell client ncpfs (available from
-	  <ftp://platan.vc.cvut.cz/pub/linux/ncpfs/>) or from
-	  within the Linux DOS emulator DOSEMU (read the DOSEMU-HOWTO,
-	  available from <http://www.tldp.org/docs.html#howto>).  In order
-	  to do the former, you'll also have to say Y to "NCP file system
-	  support", below.
-
-	  IPX is similar in scope to IP, while SPX, which runs on top of IPX,
-	  is similar to TCP. There is also experimental support for SPX in
-	  Linux (see "SPX networking", below).
-
-	  To turn your Linux box into a fully featured NetWare file server and
-	  IPX router, say Y here and fetch either lwared from
-	  <ftp://ibiblio.org/pub/Linux/system/network/daemons/> or
-	  mars_nwe from <ftp://www.compu-art.de/mars_nwe/>. For more
-	  information, read the IPX-HOWTO available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  General information about how to connect Linux, Windows machines and
-	  Macs is on the WWW at <http://www.eats.com/linux_mac_win.html>.
-
-	  The IPX driver would enlarge your kernel by about 16 KB. To compile
-	  this driver as a module, choose M here: the module will be called ipx.
-	  Unless you want to integrate your Linux box with a local Novell
-	  network, say N.
-
 source "net/ipx/Kconfig"
-
-config ATALK
-	tristate "Appletalk protocol support"
-	select LLC
-	---help---
-	  AppleTalk is the protocol that Apple computers can use to communicate
-	  on a network.  If your Linux box is connected to such a network and you
-	  wish to connect to it, say Y.  You will need to use the netatalk package
-	  so that your Linux box can act as a print and file server for Macs as
-	  well as access AppleTalk printers.  Check out
-	  <http://www.zettabyte.net/netatalk/> on the WWW for details.
-	  EtherTalk is the name used for AppleTalk over Ethernet and the
-	  cheaper and slower LocalTalk is AppleTalk over a proprietary Apple
-	  network using serial links.  EtherTalk and LocalTalk are fully
-	  supported by Linux.
-
-	  General information about how to connect Linux, Windows machines and
-	  Macs is on the WWW at <http://www.eats.com/linux_mac_win.html>.  The
-	  NET-3-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>, contains valuable
-	  information as well.
-
-	  To compile this driver as a module, choose M here: the module will be
-	  called appletalk. You almost certainly want to compile it as a
-	  module so you can restart your AppleTalk stack without rebooting
-	  your machine. I hear that the GNU boycott of Apple is over, so
-	  even politically correct people are allowed to say Y here.
-
 source "drivers/net/appletalk/Kconfig"
-
-config X25
-	tristate "CCITT X.25 Packet Layer (EXPERIMENTAL)"
-	depends on EXPERIMENTAL
-	---help---
-	  X.25 is a set of standardized network protocols, similar in scope to
-	  frame relay; the one physical line from your box to the X.25 network
-	  entry point can carry several logical point-to-point connections
-	  (called "virtual circuits") to other computers connected to the X.25
-	  network. Governments, banks, and other organizations tend to use it
-	  to connect to each other or to form Wide Area Networks (WANs). Many
-	  countries have public X.25 networks. X.25 consists of two
-	  protocols: the higher level Packet Layer Protocol (PLP) (say Y here
-	  if you want that) and the lower level data link layer protocol LAPB
-	  (say Y to "LAPB Data Link Driver" below if you want that).
-
-	  You can read more about X.25 at <http://www.sangoma.com/x25.htm> and
-	  <http://www.cisco.com/univercd/cc/td/doc/product/software/ios11/cbook/cx25.htm>.
-	  Information about X.25 for Linux is contained in the files
-	  <file:Documentation/networking/x25.txt> and
-	  <file:Documentation/networking/x25-iface.txt>.
-
-	  One connects to an X.25 network either with a dedicated network card
-	  using the X.21 protocol (not yet supported by Linux) or one can do
-	  X.25 over a standard telephone line using an ordinary modem (say Y
-	  to "X.25 async driver" below) or over Ethernet using an ordinary
-	  Ethernet card and the LAPB over Ethernet (say Y to "LAPB Data Link
-	  Driver" and "LAPB over Ethernet driver" below).
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called x25. If unsure, say N.
-
-config LAPB
-	tristate "LAPB Data Link Driver (EXPERIMENTAL)"
-	depends on EXPERIMENTAL
-	---help---
-	  Link Access Procedure, Balanced (LAPB) is the data link layer (i.e.
-	  the lower) part of the X.25 protocol. It offers a reliable
-	  connection service to exchange data frames with one other host, and
-	  it is used to transport higher level protocols (mostly X.25 Packet
-	  Layer, the higher part of X.25, but others are possible as well).
-	  Usually, LAPB is used with specialized X.21 network cards, but Linux
-	  currently supports LAPB only over Ethernet connections. If you want
-	  to use LAPB connections over Ethernet, say Y here and to "LAPB over
-	  Ethernet driver" below. Read
-	  <file:Documentation/networking/lapb-module.txt> for technical
-	  details.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called lapb.  If unsure, say N.
+source "net/x25/Kconfig"
+source "net/lapb/Kconfig"
 
 config NET_DIVERT
 	bool "Frame Diverter (EXPERIMENTAL)"
@@ -496,107 +184,10 @@ config NET_DIVERT
 
 	  If unsure, say N.
 
-config ECONET
-	tristate "Acorn Econet/AUN protocols (EXPERIMENTAL)"
-	depends on EXPERIMENTAL && INET
-	---help---
-	  Econet is a fairly old and slow networking protocol mainly used by
-	  Acorn computers to access file and print servers. It uses native
-	  Econet network cards. AUN is an implementation of the higher level
-	  parts of Econet that runs over ordinary Ethernet connections, on
-	  top of the UDP packet protocol, which in turn runs on top of the
-	  Internet protocol IP.
-
-	  If you say Y here, you can choose with the next two options whether
-	  to send Econet/AUN traffic over a UDP Ethernet connection or over
-	  a native Econet network card.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called econet.
-
-config ECONET_AUNUDP
-	bool "AUN over UDP"
-	depends on ECONET
-	help
-	  Say Y here if you want to send Econet/AUN traffic over a UDP
-	  connection (UDP is a packet based protocol that runs on top of the
-	  Internet protocol IP) using an ordinary Ethernet network card.
-
-config ECONET_NATIVE
-	bool "Native Econet"
-	depends on ECONET
-	help
-	  Say Y here if you have a native Econet network card installed in
-	  your computer.
-
-config WAN_ROUTER
-	tristate "WAN router"
-	depends on EXPERIMENTAL
-	---help---
-	  Wide Area Networks (WANs), such as X.25, frame relay and leased
-	  lines, are used to interconnect Local Area Networks (LANs) over vast
-	  distances with data transfer rates significantly higher than those
-	  achievable with commonly used asynchronous modem connections.
-	  Usually, a quite expensive external device called a `WAN router' is
-	  needed to connect to a WAN.
-
-	  As an alternative, WAN routing can be built into the Linux kernel.
-	  With relatively inexpensive WAN interface cards available on the
-	  market, a perfectly usable router can be built for less than half
-	  the price of an external router.  If you have one of those cards and
-	  wish to use your Linux box as a WAN router, say Y here and also to
-	  the WAN driver for your card, below.  You will then need the
-	  wan-tools package which is available from <ftp://ftp.sangoma.com/>.
-	  Read <file:Documentation/networking/wan-router.txt> for more
-	  information.
-
-	  To compile WAN routing support as a module, choose M here: the
-	  module will be called wanrouter.
-
-	  If unsure, say N.
-
-menu "QoS and/or fair queueing"
-
-config NET_SCHED
-	bool "QoS and/or fair queueing"
-	---help---
-	  When the kernel has several packets to send out over a network
-	  device, it has to decide which ones to send first, which ones to
-	  delay, and which ones to drop. This is the job of the packet
-	  scheduler, and several different algorithms for how to do this
-	  "fairly" have been proposed.
-
-	  If you say N here, you will get the standard packet scheduler, which
-	  is a FIFO (first come, first served). If you say Y here, you will be
-	  able to choose from among several alternative algorithms which can
-	  then be attached to different network devices. This is useful for
-	  example if some of your network devices are real time devices that
-	  need a certain minimum data flow rate, or if you need to limit the
-	  maximum data flow rate for traffic which matches specified criteria.
-	  This code is considered to be experimental.
-
-	  To administer these schedulers, you'll need the user-level utilities
-	  from the package iproute2+tc at <ftp://ftp.tux.org/pub/net/ip-routing/>.
-	  That package also contains some documentation; for more, check out
-	  <http://snafu.freedom.org/linux2.2/iproute-notes.html>.
-
-	  This Quality of Service (QoS) support will enable you to use
-	  Differentiated Services (diffserv) and Resource Reservation Protocol
-	  (RSVP) on your Linux router if you also say Y to "QoS support",
-	  "Packet classifier API" and to some classifiers below. Documentation
-	  and software is at <http://diffserv.sourceforge.net/>.
-
-	  If you say Y here and to "/proc file system" below, you will be able
-	  to read status information about packet schedulers from the file
-	  /proc/net/psched.
-
-	  The available schedulers are listed in the following questions; you
-	  can say Y to as many as you like. If unsure, say N now.
-
+source "net/econet/Kconfig"
+source "net/wanrouter/Kconfig"
 source "net/sched/Kconfig"
 
-endmenu
-
 menu "Network testing"
 
 config NET_PKTGEN
@@ -618,29 +209,10 @@ endmenu
 
 endmenu
 
-config NETPOLL
-	def_bool NETCONSOLE
-
-config NETPOLL_RX
-	bool "Netpoll support for trapping incoming packets"
-	default n
-	depends on NETPOLL
-
-config NETPOLL_TRAP
-	bool "Netpoll traffic trapping"
-	default n
-	depends on NETPOLL
-
-config NET_POLL_CONTROLLER
-	def_bool NETPOLL
-
 source "net/ax25/Kconfig"
-
 source "net/irda/Kconfig"
-
 source "net/bluetooth/Kconfig"
 
-source "drivers/net/Kconfig"
-
-endmenu
+endif   # if NET
+endmenu # Networking
 
diff --git a/net/appletalk/aarp.c b/net/appletalk/aarp.c
--- a/net/appletalk/aarp.c
+++ b/net/appletalk/aarp.c
@@ -35,6 +35,7 @@
 #include <net/datalink.h>
 #include <net/psnap.h>
 #include <linux/atalk.h>
+#include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
@@ -462,8 +463,7 @@ void aarp_probe_network(struct atalk_ifa
 			aarp_send_probe(atif->dev, &atif->address);
 
 			/* Defer 1/10th */
-			current->state = TASK_INTERRUPTIBLE;
-			schedule_timeout(HZ / 10);
+			msleep(100);
 
 			if (atif->status & ATIF_PROBE_FAIL)
 				break;
@@ -510,9 +510,8 @@ int aarp_proxy_probe_network(struct atal
 		aarp_send_probe(atif->dev, sa);
 
 		/* Defer 1/10th */
-		current->state = TASK_INTERRUPTIBLE;
 		write_unlock_bh(&aarp_lock);
-		schedule_timeout(HZ / 10);
+		msleep(100);
 		write_lock_bh(&aarp_lock);
 
 		if (entry->status & ATIF_PROBE_FAIL)
@@ -565,7 +564,7 @@ int aarp_send_ddp(struct net_device *dev
 			 *	numbers	we just happen to need. Now put the
 			 *	length in the lower two.
 			 */
-			*((__u16 *)skb->data) = htons(skb->len);
+			*((__be16 *)skb->data) = htons(skb->len);
 			ft = 1;
 		}
 		/*
diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c
--- a/net/appletalk/ddp.c
+++ b/net/appletalk/ddp.c
@@ -401,7 +401,7 @@ out_err:
 }
 
 /* Find a match for a specific network:node pair */
-static struct atalk_iface *atalk_find_interface(int net, int node)
+static struct atalk_iface *atalk_find_interface(__be16 net, int node)
 {
 	struct atalk_iface *iface;
 
diff --git a/net/atm/Kconfig b/net/atm/Kconfig
new file mode 100644
--- /dev/null
+++ b/net/atm/Kconfig
@@ -0,0 +1,74 @@
+#
+# Asynchronous Transfer Mode (ATM) (EXPERIMENTAL)
+#
+
+config ATM
+	tristate "Asynchronous Transfer Mode (ATM) (EXPERIMENTAL)"
+	depends on EXPERIMENTAL
+	---help---
+	  ATM is a high-speed networking technology for Local Area Networks
+	  and Wide Area Networks.  It uses a fixed packet size and is
+	  connection oriented, allowing for the negotiation of minimum
+	  bandwidth requirements.
+
+	  In order to participate in an ATM network, your Linux box needs an
+	  ATM networking card. If you have that, say Y here and to the driver
+	  of your ATM card below.
+
+	  Note that you need a set of user-space programs to actually make use
+	  of ATM.  See the file <file:Documentation/networking/atm.txt> for
+	  further details.
+
+config ATM_CLIP
+	tristate "Classical IP over ATM (EXPERIMENTAL)"
+	depends on ATM && INET
+	help
+	  Classical IP over ATM for PVCs and SVCs, supporting InARP and
+	  ATMARP. If you want to communication with other IP hosts on your ATM
+	  network, you will typically either say Y here or to "LAN Emulation
+	  (LANE)" below.
+
+config ATM_CLIP_NO_ICMP
+	bool "Do NOT send ICMP if no neighbour (EXPERIMENTAL)"
+	depends on ATM_CLIP
+	help
+	  Normally, an "ICMP host unreachable" message is sent if a neighbour
+	  cannot be reached because there is no VC to it in the kernel's
+	  ATMARP table. This may cause problems when ATMARP table entries are
+	  briefly removed during revalidation. If you say Y here, packets to
+	  such neighbours are silently discarded instead.
+
+config ATM_LANE
+	tristate "LAN Emulation (LANE) support (EXPERIMENTAL)"
+	depends on ATM
+	help
+	  LAN Emulation emulates services of existing LANs across an ATM
+	  network. Besides operating as a normal ATM end station client, Linux
+	  LANE client can also act as an proxy client bridging packets between
+	  ELAN and Ethernet segments. You need LANE if you want to try MPOA.
+
+config ATM_MPOA
+	tristate "Multi-Protocol Over ATM (MPOA) support (EXPERIMENTAL)"
+	depends on ATM && INET && ATM_LANE!=n
+	help
+	  Multi-Protocol Over ATM allows ATM edge devices such as routers,
+	  bridges and ATM attached hosts establish direct ATM VCs across
+	  subnetwork boundaries. These shortcut connections bypass routers
+	  enhancing overall network performance.
+
+config ATM_BR2684
+	tristate "RFC1483/2684 Bridged protocols"
+	depends on ATM && INET
+	help
+	  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.
+
+config ATM_BR2684_IPFILTER
+	bool "Per-VC IP filter kludge"
+	depends on ATM_BR2684
+	help
+	  This is an experimental mechanism for users who need to terminate a
+	  large number of IP-only vcc's.  Do not enable this unless you are sure
+	  you know what you are doing.
diff --git a/net/atm/br2684.c b/net/atm/br2684.c
--- a/net/atm/br2684.c
+++ b/net/atm/br2684.c
@@ -289,8 +289,7 @@ xmit will add the additional header part
  * 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)
+static inline __be16 br_type_trans(struct sk_buff *skb, struct net_device *dev)
 {
 	struct ethhdr *eth;
 	unsigned char *rawp;
diff --git a/net/atm/svc.c b/net/atm/svc.c
--- a/net/atm/svc.c
+++ b/net/atm/svc.c
@@ -118,10 +118,6 @@ static int svc_bind(struct socket *sock,
 		goto out;
 	}
 	vcc = ATM_SD(sock);
-	if (test_bit(ATM_VF_SESSION, &vcc->flags)) {
-		error = -EINVAL;
-		goto out;
-	}
 	addr = (struct sockaddr_atmsvc *) sockaddr;
 	if (addr->sas_family != AF_ATMSVC) {
 		error = -EAFNOSUPPORT;
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
--- a/net/ax25/af_ax25.c
+++ b/net/ax25/af_ax25.c
@@ -875,12 +875,7 @@ struct sock *ax25_make_new(struct sock *
 	sk->sk_sndbuf   = osk->sk_sndbuf;
 	sk->sk_state    = TCP_ESTABLISHED;
 	sk->sk_sleep    = osk->sk_sleep;
-
-	if (sock_flag(osk, SOCK_DBG))
-		sock_set_flag(sk, SOCK_DBG);
-
-	if (sock_flag(osk, SOCK_ZAPPED))
-		sock_set_flag(sk, SOCK_ZAPPED);
+	sock_copy_flags(sk, osk);
 
 	oax25 = ax25_sk(osk);
 
@@ -1007,7 +1002,8 @@ static int ax25_bind(struct socket *sock
 	struct sock *sk = sock->sk;
 	struct full_sockaddr_ax25 *addr = (struct full_sockaddr_ax25 *)uaddr;
 	ax25_dev *ax25_dev = NULL;
-	ax25_address *call;
+	ax25_uid_assoc *user;
+	ax25_address call;
 	ax25_cb *ax25;
 	int err = 0;
 
@@ -1026,9 +1022,15 @@ static int ax25_bind(struct socket *sock
 	if (addr->fsa_ax25.sax25_family != AF_AX25)
 		return -EINVAL;
 
-	call = ax25_findbyuid(current->euid);
-	if (call == NULL && ax25_uid_policy && !capable(CAP_NET_ADMIN)) {
-		return -EACCES;
+	user = ax25_findbyuid(current->euid);
+	if (user) {
+		call = user->call;
+		ax25_uid_put(user);
+	} else {
+		if (ax25_uid_policy && !capable(CAP_NET_ADMIN))
+			return -EACCES;
+
+		call = addr->fsa_ax25.sax25_call;
 	}
 
 	lock_sock(sk);
@@ -1039,10 +1041,7 @@ static int ax25_bind(struct socket *sock
 		goto out;
 	}
 
-	if (call == NULL)
-		ax25->source_addr = addr->fsa_ax25.sax25_call;
-	else
-		ax25->source_addr = *call;
+	ax25->source_addr = call;
 
 	/*
 	 * User already set interface with SO_BINDTODEVICE
diff --git a/net/ax25/ax25_route.c b/net/ax25/ax25_route.c
--- a/net/ax25/ax25_route.c
+++ b/net/ax25/ax25_route.c
@@ -422,8 +422,8 @@ static inline void ax25_adjust_path(ax25
  */
 int ax25_rt_autobind(ax25_cb *ax25, ax25_address *addr)
 {
+	ax25_uid_assoc *user;
 	ax25_route *ax25_rt;
-	ax25_address *call;
 	int err;
 
 	if ((ax25_rt = ax25_get_route(addr, NULL)) == NULL)
@@ -434,16 +434,18 @@ int ax25_rt_autobind(ax25_cb *ax25, ax25
 		goto put;
 	}
 
-	if ((call = ax25_findbyuid(current->euid)) == NULL) {
+	user = ax25_findbyuid(current->euid);
+	if (user) {
+		ax25->source_addr = user->call;
+		ax25_uid_put(user);
+	} else {
 		if (ax25_uid_policy && !capable(CAP_NET_BIND_SERVICE)) {
 			err = -EPERM;
 			goto put;
 		}
-		call = (ax25_address *)ax25->ax25_dev->dev->dev_addr;
+		ax25->source_addr = *(ax25_address *)ax25->ax25_dev->dev->dev_addr;
 	}
 
-	ax25->source_addr = *call;
-
 	if (ax25_rt->digipeat != NULL) {
 		if ((ax25->digipeat = kmalloc(sizeof(ax25_digi), GFP_ATOMIC)) == NULL) {
 			err = -ENOMEM;
diff --git a/net/ax25/ax25_uid.c b/net/ax25/ax25_uid.c
--- a/net/ax25/ax25_uid.c
+++ b/net/ax25/ax25_uid.c
@@ -28,6 +28,7 @@
 #include <linux/fcntl.h>
 #include <linux/mm.h>
 #include <linux/interrupt.h>
+#include <linux/list.h>
 #include <linux/notifier.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
@@ -41,38 +42,41 @@
  *	Callsign/UID mapper. This is in kernel space for security on multi-amateur machines.
  */
 
-static ax25_uid_assoc *ax25_uid_list;
+HLIST_HEAD(ax25_uid_list);
 static DEFINE_RWLOCK(ax25_uid_lock);
 
 int ax25_uid_policy = 0;
 
-ax25_address *ax25_findbyuid(uid_t uid)
+ax25_uid_assoc *ax25_findbyuid(uid_t uid)
 {
-	ax25_uid_assoc *ax25_uid;
-	ax25_address *res = NULL;
+	ax25_uid_assoc *ax25_uid, *res = NULL;
+	struct hlist_node *node;
 
 	read_lock(&ax25_uid_lock);
-	for (ax25_uid = ax25_uid_list; ax25_uid != NULL; ax25_uid = ax25_uid->next) {
+	ax25_uid_for_each(ax25_uid, node, &ax25_uid_list) {
 		if (ax25_uid->uid == uid) {
-			res = &ax25_uid->call;
+			ax25_uid_hold(ax25_uid);
+			res = ax25_uid;
 			break;
 		}
 	}
 	read_unlock(&ax25_uid_lock);
 
-	return NULL;
+	return res;
 }
 
 int ax25_uid_ioctl(int cmd, struct sockaddr_ax25 *sax)
 {
-	ax25_uid_assoc *s, *ax25_uid;
+	ax25_uid_assoc *ax25_uid;
+	struct hlist_node *node;
+	ax25_uid_assoc *user;
 	unsigned long res;
 
 	switch (cmd) {
 	case SIOCAX25GETUID:
 		res = -ENOENT;
 		read_lock(&ax25_uid_lock);
-		for (ax25_uid = ax25_uid_list; ax25_uid != NULL; ax25_uid = ax25_uid->next) {
+		ax25_uid_for_each(ax25_uid, node, &ax25_uid_list) {
 			if (ax25cmp(&sax->sax25_call, &ax25_uid->call) == 0) {
 				res = ax25_uid->uid;
 				break;
@@ -85,19 +89,22 @@ int ax25_uid_ioctl(int cmd, struct socka
 	case SIOCAX25ADDUID:
 		if (!capable(CAP_NET_ADMIN))
 			return -EPERM;
-		if (ax25_findbyuid(sax->sax25_uid))
+		user = ax25_findbyuid(sax->sax25_uid);
+		if (user) {
+			ax25_uid_put(user);
 			return -EEXIST;
+		}
 		if (sax->sax25_uid == 0)
 			return -EINVAL;
 		if ((ax25_uid = kmalloc(sizeof(*ax25_uid), GFP_KERNEL)) == NULL)
 			return -ENOMEM;
 
+		atomic_set(&ax25_uid->refcount, 1);
 		ax25_uid->uid  = sax->sax25_uid;
 		ax25_uid->call = sax->sax25_call;
 
 		write_lock(&ax25_uid_lock);
-		ax25_uid->next = ax25_uid_list;
-		ax25_uid_list  = ax25_uid;
+		hlist_add_head(&ax25_uid->uid_node, &ax25_uid_list);
 		write_unlock(&ax25_uid_lock);
 
 		return 0;
@@ -106,34 +113,21 @@ int ax25_uid_ioctl(int cmd, struct socka
 		if (!capable(CAP_NET_ADMIN))
 			return -EPERM;
 
+		ax25_uid = NULL;
 		write_lock(&ax25_uid_lock);
-		for (ax25_uid = ax25_uid_list; ax25_uid != NULL; ax25_uid = ax25_uid->next) {
-			if (ax25cmp(&sax->sax25_call, &ax25_uid->call) == 0) {
+		ax25_uid_for_each(ax25_uid, node, &ax25_uid_list) {
+			if (ax25cmp(&sax->sax25_call, &ax25_uid->call) == 0)
 				break;
-			}
 		}
 		if (ax25_uid == NULL) {
 			write_unlock(&ax25_uid_lock);
 			return -ENOENT;
 		}
-		if ((s = ax25_uid_list) == ax25_uid) {
-			ax25_uid_list = s->next;
-			write_unlock(&ax25_uid_lock);
-			kfree(ax25_uid);
-			return 0;
-		}
-		while (s != NULL && s->next != NULL) {
-			if (s->next == ax25_uid) {
-				s->next = ax25_uid->next;
-				write_unlock(&ax25_uid_lock);
-				kfree(ax25_uid);
-				return 0;
-			}
-			s = s->next;
-		}
+		hlist_del_init(&ax25_uid->uid_node);
+		ax25_uid_put(ax25_uid);
 		write_unlock(&ax25_uid_lock);
 
-		return -ENOENT;
+		return 0;
 
 	default:
 		return -EINVAL;
@@ -147,13 +141,11 @@ int ax25_uid_ioctl(int cmd, struct socka
 static void *ax25_uid_seq_start(struct seq_file *seq, loff_t *pos)
 {
 	struct ax25_uid_assoc *pt;
-	int i = 1;
+	struct hlist_node *node;
+	int i = 0;
 
 	read_lock(&ax25_uid_lock);
-	if (*pos == 0)
-		return SEQ_START_TOKEN;
-
-	for (pt = ax25_uid_list; pt != NULL; pt = pt->next) {
+	ax25_uid_for_each(pt, node, &ax25_uid_list) {
 		if (i == *pos)
 			return pt;
 		++i;
@@ -164,8 +156,9 @@ static void *ax25_uid_seq_start(struct s
 static void *ax25_uid_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 {
 	++*pos;
-	return (v == SEQ_START_TOKEN) ? ax25_uid_list : 
-		((struct ax25_uid_assoc *) v)->next;
+
+	return hlist_entry(((ax25_uid_assoc *)v)->uid_node.next,
+	                   ax25_uid_assoc, uid_node);
 }
 
 static void ax25_uid_seq_stop(struct seq_file *seq, void *v)
@@ -179,7 +172,6 @@ static int ax25_uid_seq_show(struct seq_
 		seq_printf(seq, "Policy: %d\n", ax25_uid_policy);
 	else {
 		struct ax25_uid_assoc *pt = v;
-		
 
 		seq_printf(seq, "%6d %s\n", pt->uid, ax2asc(&pt->call));
 	}
@@ -213,16 +205,13 @@ struct file_operations ax25_uid_fops = {
  */
 void __exit ax25_uid_free(void)
 {
-	ax25_uid_assoc *s, *ax25_uid;
+	ax25_uid_assoc *ax25_uid;
+	struct hlist_node *node;
 
 	write_lock(&ax25_uid_lock);
-	ax25_uid = ax25_uid_list;
-	while (ax25_uid != NULL) {
-		s        = ax25_uid;
-		ax25_uid = ax25_uid->next;
-
-		kfree(s);
+	ax25_uid_for_each(ax25_uid, node, &ax25_uid_list) {
+		hlist_del_init(&ax25_uid->uid_node);
+		ax25_uid_put(ax25_uid);
 	}
-	ax25_uid_list = NULL;
 	write_unlock(&ax25_uid_lock);
 }
diff --git a/net/bluetooth/cmtp/core.c b/net/bluetooth/cmtp/core.c
--- a/net/bluetooth/cmtp/core.c
+++ b/net/bluetooth/cmtp/core.c
@@ -213,7 +213,7 @@ static int cmtp_send_frame(struct cmtp_s
 	return kernel_sendmsg(sock, &msg, &iv, 1, len);
 }
 
-static int cmtp_process_transmit(struct cmtp_session *session)
+static void cmtp_process_transmit(struct cmtp_session *session)
 {
 	struct sk_buff *skb, *nskb;
 	unsigned char *hdr;
@@ -223,7 +223,7 @@ static int cmtp_process_transmit(struct 
 
 	if (!(nskb = alloc_skb(session->mtu, GFP_ATOMIC))) {
 		BT_ERR("Can't allocate memory for new frame");
-		return -ENOMEM;
+		return;
 	}
 
 	while ((skb = skb_dequeue(&session->transmit))) {
@@ -275,8 +275,6 @@ static int cmtp_process_transmit(struct 
 	cmtp_send_frame(session, nskb->data, nskb->len);
 
 	kfree_skb(nskb);
-
-	return skb_queue_len(&session->transmit);
 }
 
 static int cmtp_session(void *arg)
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -299,7 +299,6 @@ struct hci_dev *hci_dev_get(int index)
 	read_unlock(&hci_dev_list_lock);
 	return hdev;
 }
-EXPORT_SYMBOL(hci_dev_get);
 
 /* ---- Inquiry support ---- */
 static void inquiry_cache_flush(struct hci_dev *hdev)
@@ -1042,7 +1041,6 @@ int hci_send_cmd(struct hci_dev *hdev, _
 
 	return 0;
 }
-EXPORT_SYMBOL(hci_send_cmd);
 
 /* Get data from the previously sent command */
 void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 ogf, __u16 ocf)
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -1035,9 +1035,11 @@ void hci_si_event(struct hci_dev *hdev, 
 	ev->type = type;
 	memcpy(ev->data, data, dlen);
 
+	bt_cb(skb)->incoming = 1;
+	do_gettimeofday(&skb->stamp);
+
 	skb->pkt_type = HCI_EVENT_PKT;
 	skb->dev = (void *) hdev;
 	hci_send_to_sock(hdev, skb);
 	kfree_skb(skb);
 }
-EXPORT_SYMBOL(hci_si_event);
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c
--- a/net/bluetooth/hidp/core.c
+++ b/net/bluetooth/hidp/core.c
@@ -428,7 +428,7 @@ static int hidp_send_frame(struct socket
 	return kernel_sendmsg(sock, &msg, &iv, 1, len);
 }
 
-static int hidp_process_transmit(struct hidp_session *session)
+static void hidp_process_transmit(struct hidp_session *session)
 {
 	struct sk_buff *skb;
 
@@ -453,9 +453,6 @@ static int hidp_process_transmit(struct 
 		hidp_set_timer(session);
 		kfree_skb(skb);
 	}
-
-	return skb_queue_len(&session->ctrl_transmit) +
-				skb_queue_len(&session->intr_transmit);
 }
 
 static int hidp_session(void *arg)
diff --git a/net/bluetooth/lib.c b/net/bluetooth/lib.c
--- a/net/bluetooth/lib.c
+++ b/net/bluetooth/lib.c
@@ -34,31 +34,6 @@
 
 #include <net/bluetooth/bluetooth.h>
 
-void bt_dump(char *pref, __u8 *buf, int count)
-{
-	char *ptr;
-	char line[100];
-	unsigned int i;
-
-	printk(KERN_INFO "%s: dump, len %d\n", pref, count);
-
-	ptr = line;
-	*ptr = 0;
-	for (i = 0; i < count; i++) {
-		ptr += sprintf(ptr, " %2.2X", buf[i]);
-
-		if (i && !((i + 1) % 20)) {
-			printk(KERN_INFO "%s:%s\n", pref, line);
-			ptr = line;
-			*ptr = 0;
-		}
-	}
-
-	if (line[0])
-		printk(KERN_INFO "%s:%s\n", pref, line);
-}
-EXPORT_SYMBOL(bt_dump);
-
 void baswap(bdaddr_t *dst, bdaddr_t *src)
 {
 	unsigned char *d = (unsigned char *) dst;
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
--- a/net/bluetooth/rfcomm/core.c
+++ b/net/bluetooth/rfcomm/core.c
@@ -389,8 +389,6 @@ static int __rfcomm_dlc_close(struct rfc
 		rfcomm_dlc_unlock(d);
 
 		skb_queue_purge(&d->tx_queue);
-		rfcomm_session_put(s);
-
 		rfcomm_dlc_unlink(d);
 	}
 
@@ -600,8 +598,6 @@ static struct rfcomm_session *rfcomm_ses
 		goto failed;
 	}
 
-	rfcomm_session_hold(s);
-
 	s->initiator = 1;
 
 	bacpy(&addr.l2_bdaddr, dst);
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
--- a/net/bluetooth/rfcomm/sock.c
+++ b/net/bluetooth/rfcomm/sock.c
@@ -590,8 +590,11 @@ static long rfcomm_sock_data_wait(struct
 	for (;;) {
 		set_current_state(TASK_INTERRUPTIBLE);
 
-		if (skb_queue_len(&sk->sk_receive_queue) || sk->sk_err || (sk->sk_shutdown & RCV_SHUTDOWN) ||
-				signal_pending(current) || !timeo)
+		if (!skb_queue_empty(&sk->sk_receive_queue) ||
+		    sk->sk_err ||
+		    (sk->sk_shutdown & RCV_SHUTDOWN) ||
+		    signal_pending(current) ||
+		    !timeo)
 			break;
 
 		set_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c
--- a/net/bluetooth/rfcomm/tty.c
+++ b/net/bluetooth/rfcomm/tty.c
@@ -781,7 +781,7 @@ static int rfcomm_tty_chars_in_buffer(st
 
 	BT_DBG("tty %p dev %p", tty, dev);
 
-	if (skb_queue_len(&dlc->tx_queue))
+	if (!skb_queue_empty(&dlc->tx_queue))
 		return dlc->mtu;
 
 	return 0;
diff --git a/net/bridge/Kconfig b/net/bridge/Kconfig
new file mode 100644
--- /dev/null
+++ b/net/bridge/Kconfig
@@ -0,0 +1,31 @@
+#
+# 802.1d Ethernet Bridging
+#
+
+config BRIDGE
+	tristate "802.1d Ethernet Bridging"
+	---help---
+	  If you say Y here, then your Linux box will be able to act as an
+	  Ethernet bridge, which means that the different Ethernet segments it
+	  is connected to will appear as one Ethernet to the participants.
+	  Several such bridges can work together to create even larger
+	  networks of Ethernets using the IEEE 802.1 spanning tree algorithm.
+	  As this is a standard, Linux bridges will cooperate properly with
+	  other third party bridge products.
+
+	  In order to use the Ethernet bridge, you'll need the bridge
+	  configuration tools; see <file:Documentation/networking/bridge.txt>
+	  for location. Please read the Bridge mini-HOWTO for more
+	  information.
+
+	  If you enable iptables support along with the bridge support then you
+	  turn your bridge into a bridging IP firewall.
+	  iptables will then see the IP packets being bridged, so you need to
+	  take this into account when setting up your firewall rules.
+	  Enabling arptables support when bridging will let arptables see
+	  bridged ARP traffic in the arptables FORWARD chain.
+
+	  To compile this code as a module, choose M here: the module
+	  will be called bridge.
+
+	  If unsure, say N.
diff --git a/net/bridge/br_forward.c b/net/bridge/br_forward.c
--- a/net/bridge/br_forward.c
+++ b/net/bridge/br_forward.c
@@ -57,9 +57,6 @@ int br_forward_finish(struct sk_buff *sk
 static void __br_deliver(const struct net_bridge_port *to, struct sk_buff *skb)
 {
 	skb->dev = to->dev;
-#ifdef CONFIG_NETFILTER_DEBUG
-	skb->nf_debug = 0;
-#endif
 	NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_OUT, skb, NULL, skb->dev,
 			br_forward_finish);
 }
diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c
--- a/net/bridge/br_input.c
+++ b/net/bridge/br_input.c
@@ -23,11 +23,7 @@ const unsigned char bridge_ula[6] = { 0x
 
 static int br_pass_frame_up_finish(struct sk_buff *skb)
 {
-#ifdef CONFIG_NETFILTER_DEBUG
-	skb->nf_debug = 0;
-#endif
 	netif_receive_skb(skb);
-
 	return 0;
 }
 
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
--- a/net/bridge/br_netfilter.c
+++ b/net/bridge/br_netfilter.c
@@ -102,10 +102,6 @@ static int br_nf_pre_routing_finish_ipv6
 {
 	struct nf_bridge_info *nf_bridge = skb->nf_bridge;
 
-#ifdef CONFIG_NETFILTER_DEBUG
-	skb->nf_debug ^= (1 << NF_BR_PRE_ROUTING);
-#endif
-
 	if (nf_bridge->mask & BRNF_PKT_TYPE) {
 		skb->pkt_type = PACKET_OTHERHOST;
 		nf_bridge->mask ^= BRNF_PKT_TYPE;
@@ -182,10 +178,6 @@ static void __br_dnat_complain(void)
  * --Bart, 20021007 (updated) */
 static int br_nf_pre_routing_finish_bridge(struct sk_buff *skb)
 {
-#ifdef CONFIG_NETFILTER_DEBUG
-	skb->nf_debug |= (1 << NF_BR_PRE_ROUTING) | (1 << NF_BR_FORWARD);
-#endif
-
 	if (skb->pkt_type == PACKET_OTHERHOST) {
 		skb->pkt_type = PACKET_HOST;
 		skb->nf_bridge->mask |= BRNF_PKT_TYPE;
@@ -207,10 +199,6 @@ static int br_nf_pre_routing_finish(stru
 	struct iphdr *iph = skb->nh.iph;
 	struct nf_bridge_info *nf_bridge = skb->nf_bridge;
 
-#ifdef CONFIG_NETFILTER_DEBUG
-	skb->nf_debug ^= (1 << NF_BR_PRE_ROUTING);
-#endif
-
 	if (nf_bridge->mask & BRNF_PKT_TYPE) {
 		skb->pkt_type = PACKET_OTHERHOST;
 		nf_bridge->mask ^= BRNF_PKT_TYPE;
@@ -382,9 +370,6 @@ static unsigned int br_nf_pre_routing_ip
 	if (hdr->nexthdr == NEXTHDR_HOP && check_hbh_len(skb))
 			goto inhdr_error;
 
-#ifdef CONFIG_NETFILTER_DEBUG
-	skb->nf_debug ^= (1 << NF_IP6_PRE_ROUTING);
-#endif
 	if ((nf_bridge = nf_bridge_alloc(skb)) == NULL)
 		return NF_DROP;
 	setup_pre_routing(skb);
@@ -468,9 +453,6 @@ static unsigned int br_nf_pre_routing(un
 			skb->ip_summed = CHECKSUM_NONE;
 	}
 
-#ifdef CONFIG_NETFILTER_DEBUG
-	skb->nf_debug ^= (1 << NF_IP_PRE_ROUTING);
-#endif
 	if ((nf_bridge = nf_bridge_alloc(skb)) == NULL)
 		return NF_DROP;
 	setup_pre_routing(skb);
@@ -517,10 +499,6 @@ static int br_nf_forward_finish(struct s
 	struct net_device *in;
 	struct vlan_ethhdr *hdr = vlan_eth_hdr(skb);
 
-#ifdef CONFIG_NETFILTER_DEBUG
-	skb->nf_debug ^= (1 << NF_BR_FORWARD);
-#endif
-
 	if (skb->protocol != __constant_htons(ETH_P_ARP) && !IS_VLAN_ARP) {
 		in = nf_bridge->physindev;
 		if (nf_bridge->mask & BRNF_PKT_TYPE) {
@@ -566,9 +544,6 @@ static unsigned int br_nf_forward_ip(uns
 		(*pskb)->nh.raw += VLAN_HLEN;
 	}
 
-#ifdef CONFIG_NETFILTER_DEBUG
-	skb->nf_debug ^= (1 << NF_BR_FORWARD);
-#endif
 	nf_bridge = skb->nf_bridge;
 	if (skb->pkt_type == PACKET_OTHERHOST) {
 		skb->pkt_type = PACKET_HOST;
@@ -605,10 +580,6 @@ static unsigned int br_nf_forward_arp(un
 		(*pskb)->nh.raw += VLAN_HLEN;
 	}
 
-#ifdef CONFIG_NETFILTER_DEBUG
-	skb->nf_debug ^= (1 << NF_BR_FORWARD);
-#endif
-
 	if (skb->nh.arph->ar_pln != 4) {
 		if (IS_VLAN_ARP) {
 			skb_push(*pskb, VLAN_HLEN);
@@ -627,9 +598,6 @@ static unsigned int br_nf_forward_arp(un
 /* PF_BRIDGE/LOCAL_OUT ***********************************************/
 static int br_nf_local_out_finish(struct sk_buff *skb)
 {
-#ifdef CONFIG_NETFILTER_DEBUG
-	skb->nf_debug &= ~(1 << NF_BR_LOCAL_OUT);
-#endif
 	if (skb->protocol == __constant_htons(ETH_P_8021Q)) {
 		skb_push(skb, VLAN_HLEN);
 		skb->nh.raw -= VLAN_HLEN;
@@ -731,10 +699,6 @@ static unsigned int br_nf_local_out(unsi
 			       realoutdev, br_nf_local_out_finish,
 			       NF_IP_PRI_BRIDGE_SABOTAGE_FORWARD + 1);
 	} else {
-#ifdef CONFIG_NETFILTER_DEBUG
-		skb->nf_debug ^= (1 << NF_IP_LOCAL_OUT);
-#endif
-
 		NF_HOOK_THRESH(pf, NF_IP_LOCAL_OUT, skb, realindev,
 			       realoutdev, br_nf_local_out_finish,
 			       NF_IP_PRI_BRIDGE_SABOTAGE_LOCAL_OUT + 1);
@@ -779,8 +743,6 @@ static unsigned int br_nf_post_routing(u
 		printk(KERN_CRIT "br_netfilter: skb->dst == NULL.");
 		goto print_error;
 	}
-
-	skb->nf_debug ^= (1 << NF_IP_POST_ROUTING);
 #endif
 
 	/* We assume any code from br_dev_queue_push_xmit onwards doesn't care
@@ -882,7 +844,7 @@ static unsigned int ip_sabotage_out(unsi
 		 * doesn't use the bridge parent of the indev by using
 		 * the BRNF_DONT_TAKE_PARENT mask. */
 		if (hook == NF_IP_FORWARD && nf_bridge->physindev == NULL) {
-			nf_bridge->mask &= BRNF_DONT_TAKE_PARENT;
+			nf_bridge->mask |= BRNF_DONT_TAKE_PARENT;
 			nf_bridge->physindev = (struct net_device *)in;
 		}
 #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
diff --git a/net/bridge/netfilter/Kconfig b/net/bridge/netfilter/Kconfig
--- a/net/bridge/netfilter/Kconfig
+++ b/net/bridge/netfilter/Kconfig
@@ -138,7 +138,7 @@ config BRIDGE_EBT_VLAN
 #
 config BRIDGE_EBT_ARPREPLY
 	tristate "ebt: arp reply target support"
-	depends on BRIDGE_NF_EBTABLES
+	depends on BRIDGE_NF_EBTABLES && INET
 	help
 	  This option adds the arp reply target, which allows
 	  automatically sending arp replies to arp requests.
diff --git a/net/bridge/netfilter/ebt_log.c b/net/bridge/netfilter/ebt_log.c
--- a/net/bridge/netfilter/ebt_log.c
+++ b/net/bridge/netfilter/ebt_log.c
@@ -61,8 +61,6 @@ static void ebt_log(const struct sk_buff
 {
 	struct ebt_log_info *info = (struct ebt_log_info *)data;
 	char level_string[4] = "< >";
-	union {struct iphdr iph; struct tcpudphdr ports;
-	       struct arphdr arph; struct arppayload arpp;} u;
 
 	level_string[1] = '0' + info->loglevel;
 	spin_lock_bh(&ebt_log_lock);
@@ -88,7 +86,7 @@ static void ebt_log(const struct sk_buff
 		}
 		printk(" IP SRC=%u.%u.%u.%u IP DST=%u.%u.%u.%u,",
 		   NIPQUAD(ih->saddr), NIPQUAD(ih->daddr));
-		printk(" IP tos=0x%02X, IP proto=%d", u.iph.tos,
+		printk(" IP tos=0x%02X, IP proto=%d", ih->tos,
 		       ih->protocol);
 		if (ih->protocol == IPPROTO_TCP ||
 		    ih->protocol == IPPROTO_UDP) {
@@ -127,7 +125,7 @@ static void ebt_log(const struct sk_buff
 		    ah->ar_pln == sizeof(uint32_t)) {
 			struct arppayload _arpp, *ap;
 
-			ap = skb_header_pointer(skb, sizeof(u.arph),
+			ap = skb_header_pointer(skb, sizeof(_arph),
 						sizeof(_arpp), &_arpp);
 			if (ap == NULL) {
 				printk(" INCOMPLETE ARP payload");
diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
--- a/net/bridge/netfilter/ebtables.c
+++ b/net/bridge/netfilter/ebtables.c
@@ -859,8 +859,7 @@ static int translate_table(struct ebt_re
 		if (repl->valid_hooks & (1 << i))
 			if (check_chainloops(newinfo->hook_entry[i],
 			   cl_s, udc_cnt, i, newinfo->entries)) {
-				if (cl_s)
-					vfree(cl_s);
+				vfree(cl_s);
 				return -EINVAL;
 			}
 
@@ -883,8 +882,7 @@ static int translate_table(struct ebt_re
 		EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size,
 		   ebt_cleanup_entry, &i);
 	}
-	if (cl_s)
-		vfree(cl_s);
+	vfree(cl_s);
 	return ret;
 }
 
@@ -1030,8 +1028,7 @@ static int do_replace(void __user *user,
 	}
 	vfree(table);
 
-	if (counterstmp)
-		vfree(counterstmp);
+	vfree(counterstmp);
 	return ret;
 
 free_unlock:
@@ -1040,8 +1037,7 @@ free_iterate:
 	EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size,
 	   ebt_cleanup_entry, NULL);
 free_counterstmp:
-	if (counterstmp)
-		vfree(counterstmp);
+	vfree(counterstmp);
 	/* can be initialized in translate_table() */
 	if (newinfo->chainstack) {
 		for (i = 0; i < num_possible_cpus(); i++)
@@ -1049,11 +1045,9 @@ free_counterstmp:
 		vfree(newinfo->chainstack);
 	}
 free_entries:
-	if (newinfo->entries)
-		vfree(newinfo->entries);
+	vfree(newinfo->entries);
 free_newinfo:
-	if (newinfo)
-		vfree(newinfo);
+	vfree(newinfo);
 	return ret;
 }
 
@@ -1213,8 +1207,7 @@ void ebt_unregister_table(struct ebt_tab
 	down(&ebt_mutex);
 	LIST_DELETE(&ebt_tables, table);
 	up(&ebt_mutex);
-	if (table->private->entries)
-		vfree(table->private->entries);
+	vfree(table->private->entries);
 	if (table->private->chainstack) {
 		for (i = 0; i < num_possible_cpus(); i++)
 			vfree(table->private->chainstack[i]);
diff --git a/net/compat.c b/net/compat.c
--- a/net/compat.c
+++ b/net/compat.c
@@ -91,20 +91,11 @@ int verify_compat_iovec(struct msghdr *k
 	} else
 		kern_msg->msg_name = NULL;
 
-	if(kern_msg->msg_iovlen > UIO_FASTIOV) {
-		kern_iov = kmalloc(kern_msg->msg_iovlen * sizeof(struct iovec),
-				   GFP_KERNEL);
-		if(!kern_iov)
-			return -ENOMEM;
-	}
-
 	tot_len = iov_from_user_compat_to_kern(kern_iov,
 					  (struct compat_iovec __user *)kern_msg->msg_iov,
 					  kern_msg->msg_iovlen);
 	if(tot_len >= 0)
 		kern_msg->msg_iov = kern_iov;
-	else if(kern_msg->msg_iovlen > UIO_FASTIOV)
-		kfree(kern_iov);
 
 	return tot_len;
 }
diff --git a/net/core/Makefile b/net/core/Makefile
--- a/net/core/Makefile
+++ b/net/core/Makefile
@@ -2,13 +2,15 @@
 # Makefile for the Linux networking core.
 #
 
-obj-y := sock.o skbuff.o iovec.o datagram.o stream.o scm.o gen_stats.o gen_estimator.o
+obj-y := sock.o request_sock.o skbuff.o iovec.o datagram.o stream.o scm.o \
+	 gen_stats.o gen_estimator.o
 
 obj-$(CONFIG_SYSCTL) += sysctl_net_core.o
 
-obj-y		     += flow.o dev.o ethtool.o dev_mcast.o dst.o \
+obj-y		     += dev.o ethtool.o dev_mcast.o dst.o \
 			neighbour.o rtnetlink.o utils.o link_watch.o filter.o
 
+obj-$(CONFIG_XFRM) += flow.o
 obj-$(CONFIG_SYSFS) += net-sysfs.o
 obj-$(CONFIG_NETFILTER) += netfilter.o
 obj-$(CONFIG_NET_DIVERT) += dv.o
diff --git a/net/core/dev.c b/net/core/dev.c
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -115,18 +115,6 @@
 #endif	/* CONFIG_NET_RADIO */
 #include <asm/current.h>
 
-/* This define, if set, will randomly drop a packet when congestion
- * is more than moderate.  It helps fairness in the multi-interface
- * case when one of them is a hog, but it kills performance for the
- * single interface case so it is off now by default.
- */
-#undef RAND_LIE
-
-/* Setting this will sample the queue lengths and thus congestion
- * via a timer instead of as each packet is received.
- */
-#undef OFFLINE_SAMPLE
-
 /*
  *	The list of packet types we will receive (as opposed to discard)
  *	and the routines to invoke.
@@ -159,11 +147,6 @@ static DEFINE_SPINLOCK(ptype_lock);
 static struct list_head ptype_base[16];	/* 16 way hashed list */
 static struct list_head ptype_all;		/* Taps */
 
-#ifdef OFFLINE_SAMPLE
-static void sample_queue(unsigned long dummy);
-static struct timer_list samp_timer = TIMER_INITIALIZER(sample_queue, 0, 0);
-#endif
-
 /*
  * The @dev_base list is protected by @dev_base_lock and the rtln
  * semaphore.
@@ -215,7 +198,7 @@ static struct notifier_block *netdev_cha
  *	Device drivers call our routines to queue packets here. We empty the
  *	queue in the local softnet handler.
  */
-DEFINE_PER_CPU(struct softnet_data, softnet_data) = { 0, };
+DEFINE_PER_CPU(struct softnet_data, softnet_data) = { NULL };
 
 #ifdef CONFIG_SYSFS
 extern int netdev_sysfs_init(void);
@@ -918,8 +901,7 @@ int dev_close(struct net_device *dev)
 	smp_mb__after_clear_bit(); /* Commit netif_running(). */
 	while (test_bit(__LINK_STATE_RX_SCHED, &dev->state)) {
 		/* No hurry. */
-		current->state = TASK_INTERRUPTIBLE;
-		schedule_timeout(1);
+		msleep(1);
 	}
 
 	/*
@@ -1144,7 +1126,7 @@ static inline int illegal_highdma(struct
 extern void skb_release_data(struct sk_buff *);
 
 /* Keep head the same: replace data */
-int __skb_linearize(struct sk_buff *skb, int gfp_mask)
+int __skb_linearize(struct sk_buff *skb, unsigned int __nocast gfp_mask)
 {
 	unsigned int size;
 	u8 *data;
@@ -1363,71 +1345,13 @@ out:
 			Receiver routines
   =======================================================================*/
 
-int netdev_max_backlog = 300;
+int netdev_max_backlog = 1000;
+int netdev_budget = 300;
 int weight_p = 64;            /* old backlog weight */
-/* These numbers are selected based on intuition and some
- * experimentatiom, if you have more scientific way of doing this
- * please go ahead and fix things.
- */
-int no_cong_thresh = 10;
-int no_cong = 20;
-int lo_cong = 100;
-int mod_cong = 290;
 
 DEFINE_PER_CPU(struct netif_rx_stats, netdev_rx_stat) = { 0, };
 
 
-static void get_sample_stats(int cpu)
-{
-#ifdef RAND_LIE
-	unsigned long rd;
-	int rq;
-#endif
-	struct softnet_data *sd = &per_cpu(softnet_data, cpu);
-	int blog = sd->input_pkt_queue.qlen;
-	int avg_blog = sd->avg_blog;
-
-	avg_blog = (avg_blog >> 1) + (blog >> 1);
-
-	if (avg_blog > mod_cong) {
-		/* Above moderate congestion levels. */
-		sd->cng_level = NET_RX_CN_HIGH;
-#ifdef RAND_LIE
-		rd = net_random();
-		rq = rd % netdev_max_backlog;
-		if (rq < avg_blog) /* unlucky bastard */
-			sd->cng_level = NET_RX_DROP;
-#endif
-	} else if (avg_blog > lo_cong) {
-		sd->cng_level = NET_RX_CN_MOD;
-#ifdef RAND_LIE
-		rd = net_random();
-		rq = rd % netdev_max_backlog;
-			if (rq < avg_blog) /* unlucky bastard */
-				sd->cng_level = NET_RX_CN_HIGH;
-#endif
-	} else if (avg_blog > no_cong)
-		sd->cng_level = NET_RX_CN_LOW;
-	else  /* no congestion */
-		sd->cng_level = NET_RX_SUCCESS;
-
-	sd->avg_blog = avg_blog;
-}
-
-#ifdef OFFLINE_SAMPLE
-static void sample_queue(unsigned long dummy)
-{
-/* 10 ms 0r 1ms -- i don't care -- JHS */
-	int next_tick = 1;
-	int cpu = smp_processor_id();
-
-	get_sample_stats(cpu);
-	next_tick += jiffies;
-	mod_timer(&samp_timer, next_tick);
-}
-#endif
-
-
 /**
  *	netif_rx	-	post buffer to the network code
  *	@skb: buffer to post
@@ -1448,7 +1372,6 @@ static void sample_queue(unsigned long d
 
 int netif_rx(struct sk_buff *skb)
 {
-	int this_cpu;
 	struct softnet_data *queue;
 	unsigned long flags;
 
@@ -1464,38 +1387,22 @@ int netif_rx(struct sk_buff *skb)
 	 * short when CPU is congested, but is still operating.
 	 */
 	local_irq_save(flags);
-	this_cpu = smp_processor_id();
 	queue = &__get_cpu_var(softnet_data);
 
 	__get_cpu_var(netdev_rx_stat).total++;
 	if (queue->input_pkt_queue.qlen <= netdev_max_backlog) {
 		if (queue->input_pkt_queue.qlen) {
-			if (queue->throttle)
-				goto drop;
-
 enqueue:
 			dev_hold(skb->dev);
 			__skb_queue_tail(&queue->input_pkt_queue, skb);
-#ifndef OFFLINE_SAMPLE
-			get_sample_stats(this_cpu);
-#endif
 			local_irq_restore(flags);
-			return queue->cng_level;
+			return NET_RX_SUCCESS;
 		}
 
-		if (queue->throttle)
-			queue->throttle = 0;
-
 		netif_rx_schedule(&queue->backlog_dev);
 		goto enqueue;
 	}
 
-	if (!queue->throttle) {
-		queue->throttle = 1;
-		__get_cpu_var(netdev_rx_stat).throttled++;
-	}
-
-drop:
 	__get_cpu_var(netdev_rx_stat).dropped++;
 	local_irq_restore(flags);
 
@@ -1780,8 +1687,6 @@ job_done:
 	smp_mb__before_clear_bit();
 	netif_poll_enable(backlog_dev);
 
-	if (queue->throttle)
-		queue->throttle = 0;
 	local_irq_enable();
 	return 0;
 }
@@ -1790,9 +1695,9 @@ static void net_rx_action(struct softirq
 {
 	struct softnet_data *queue = &__get_cpu_var(softnet_data);
 	unsigned long start_time = jiffies;
-	int budget = netdev_max_backlog;
+	int budget = netdev_budget;
+	void *have;
 
-	
 	local_irq_disable();
 
 	while (!list_empty(&queue->poll_list)) {
@@ -1805,10 +1710,10 @@ static void net_rx_action(struct softirq
 
 		dev = list_entry(queue->poll_list.next,
 				 struct net_device, poll_list);
-		netpoll_poll_lock(dev);
+		have = netpoll_poll_lock(dev);
 
 		if (dev->quota <= 0 || dev->poll(dev, &budget)) {
-			netpoll_poll_unlock(dev);
+			netpoll_poll_unlock(have);
 			local_irq_disable();
 			list_del(&dev->poll_list);
 			list_add_tail(&dev->poll_list, &queue->poll_list);
@@ -1817,7 +1722,7 @@ static void net_rx_action(struct softirq
 			else
 				dev->quota = dev->weight;
 		} else {
-			netpoll_poll_unlock(dev);
+			netpoll_poll_unlock(have);
 			dev_put(dev);
 			local_irq_disable();
 		}
@@ -2055,15 +1960,9 @@ static int softnet_seq_show(struct seq_f
 	struct netif_rx_stats *s = v;
 
 	seq_printf(seq, "%08x %08x %08x %08x %08x %08x %08x %08x %08x\n",
-		   s->total, s->dropped, s->time_squeeze, s->throttled,
-		   s->fastroute_hit, s->fastroute_success, s->fastroute_defer,
-		   s->fastroute_deferred_out,
-#if 0
-		   s->fastroute_latency_reduction
-#else
-		   s->cpu_collision
-#endif
-		  );
+		   s->total, s->dropped, s->time_squeeze, 0,
+		   0, 0, 0, 0, /* was fastroute */
+		   s->cpu_collision );
 	return 0;
 }
 
@@ -2190,10 +2089,11 @@ void dev_set_promiscuity(struct net_devi
 {
 	unsigned short old_flags = dev->flags;
 
-	dev->flags |= IFF_PROMISC;
 	if ((dev->promiscuity += inc) == 0)
 		dev->flags &= ~IFF_PROMISC;
-	if (dev->flags ^ old_flags) {
+	else
+		dev->flags |= IFF_PROMISC;
+	if (dev->flags != old_flags) {
 		dev_mc_upload(dev);
 		printk(KERN_INFO "device %s %s promiscuous mode\n",
 		       dev->name, (dev->flags & IFF_PROMISC) ? "entered" :
@@ -3305,9 +3205,6 @@ static int __init net_dev_init(void)
 
 		queue = &per_cpu(softnet_data, i);
 		skb_queue_head_init(&queue->input_pkt_queue);
-		queue->throttle = 0;
-		queue->cng_level = 0;
-		queue->avg_blog = 10; /* arbitrary non-zero */
 		queue->completion_queue = NULL;
 		INIT_LIST_HEAD(&queue->poll_list);
 		set_bit(__LINK_STATE_START, &queue->backlog_dev.state);
@@ -3316,11 +3213,6 @@ static int __init net_dev_init(void)
 		atomic_set(&queue->backlog_dev.refcnt, 1);
 	}
 
-#ifdef OFFLINE_SAMPLE
-	samp_timer.expires = jiffies + (10 * HZ);
-	add_timer(&samp_timer);
-#endif
-
 	dev_boot_phase = 0;
 
 	open_softirq(NET_TX_SOFTIRQ, net_tx_action, NULL);
diff --git a/net/core/dst.c b/net/core/dst.c
--- a/net/core/dst.c
+++ b/net/core/dst.c
@@ -45,6 +45,7 @@ static struct timer_list dst_gc_timer =
 static void dst_run_gc(unsigned long dummy)
 {
 	int    delayed = 0;
+	int    work_performed;
 	struct dst_entry * dst, **dstp;
 
 	if (!spin_trylock(&dst_lock)) {
@@ -52,9 +53,9 @@ static void dst_run_gc(unsigned long dum
 		return;
 	}
 
-
 	del_timer(&dst_gc_timer);
 	dstp = &dst_garbage_list;
+	work_performed = 0;
 	while ((dst = *dstp) != NULL) {
 		if (atomic_read(&dst->__refcnt)) {
 			dstp = &dst->next;
@@ -62,6 +63,7 @@ static void dst_run_gc(unsigned long dum
 			continue;
 		}
 		*dstp = dst->next;
+		work_performed = 1;
 
 		dst = dst_destroy(dst);
 		if (dst) {
@@ -86,9 +88,14 @@ static void dst_run_gc(unsigned long dum
 		dst_gc_timer_inc = DST_GC_MAX;
 		goto out;
 	}
-	if ((dst_gc_timer_expires += dst_gc_timer_inc) > DST_GC_MAX)
-		dst_gc_timer_expires = DST_GC_MAX;
-	dst_gc_timer_inc += DST_GC_INC;
+	if (!work_performed) {
+		if ((dst_gc_timer_expires += dst_gc_timer_inc) > DST_GC_MAX)
+			dst_gc_timer_expires = DST_GC_MAX;
+		dst_gc_timer_inc += DST_GC_INC;
+	} else {
+		dst_gc_timer_inc = DST_GC_INC;
+		dst_gc_timer_expires = DST_GC_MIN;
+	}
 	dst_gc_timer.expires = jiffies + dst_gc_timer_expires;
 #if RT_CACHE_DEBUG >= 2
 	printk("dst_total: %d/%d %ld\n",
diff --git a/net/core/filter.c b/net/core/filter.c
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -36,7 +36,7 @@
 #include <linux/filter.h>
 
 /* No hurry in this branch */
-static u8 *load_pointer(struct sk_buff *skb, int k)
+static void *__load_pointer(struct sk_buff *skb, int k)
 {
 	u8 *ptr = NULL;
 
@@ -50,6 +50,18 @@ static u8 *load_pointer(struct sk_buff *
 	return NULL;
 }
 
+static inline void *load_pointer(struct sk_buff *skb, int k,
+                                 unsigned int size, void *buffer)
+{
+	if (k >= 0)
+		return skb_header_pointer(skb, k, size, buffer);
+	else {
+		if (k >= SKF_AD_OFF)
+			return NULL;
+		return __load_pointer(skb, k);
+	}
+}
+
 /**
  *	sk_run_filter	- 	run a filter on a socket
  *	@skb: buffer to run the filter on
@@ -64,15 +76,12 @@ static u8 *load_pointer(struct sk_buff *
  
 int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int flen)
 {
-	unsigned char *data = skb->data;
-	/* len is UNSIGNED. Byte wide insns relies only on implicit
-	   type casts to prevent reading arbitrary memory locations.
-	 */
-	unsigned int len = skb->len-skb->data_len;
 	struct sock_filter *fentry;	/* We walk down these */
+	void *ptr;
 	u32 A = 0;	   		/* Accumulator */
 	u32 X = 0;   			/* Index Register */
 	u32 mem[BPF_MEMWORDS];		/* Scratch Memory Store */
+	u32 tmp;
 	int k;
 	int pc;
 
@@ -168,86 +177,35 @@ int sk_run_filter(struct sk_buff *skb, s
 		case BPF_LD|BPF_W|BPF_ABS:
 			k = fentry->k;
  load_w:
-			if (k >= 0 && (unsigned int)(k+sizeof(u32)) <= len) {
-				A = ntohl(*(u32*)&data[k]);
+			ptr = load_pointer(skb, k, 4, &tmp);
+			if (ptr != NULL) {
+				A = ntohl(*(u32 *)ptr);
 				continue;
 			}
-			if (k < 0) {
-				u8 *ptr;
-
-				if (k >= SKF_AD_OFF)
-					break;
-				ptr = load_pointer(skb, k);
-				if (ptr) {
-					A = ntohl(*(u32*)ptr);
-					continue;
-				}
-			} else {
-				u32 _tmp, *p;
-				p = skb_header_pointer(skb, k, 4, &_tmp);
-				if (p != NULL) {
-					A = ntohl(*p);
-					continue;
-				}
-			}
 			return 0;
 		case BPF_LD|BPF_H|BPF_ABS:
 			k = fentry->k;
  load_h:
-			if (k >= 0 && (unsigned int)(k + sizeof(u16)) <= len) {
-				A = ntohs(*(u16*)&data[k]);
+			ptr = load_pointer(skb, k, 2, &tmp);
+			if (ptr != NULL) {
+				A = ntohs(*(u16 *)ptr);
 				continue;
 			}
-			if (k < 0) {
-				u8 *ptr;
-
-				if (k >= SKF_AD_OFF)
-					break;
-				ptr = load_pointer(skb, k);
-				if (ptr) {
-					A = ntohs(*(u16*)ptr);
-					continue;
-				}
-			} else {
-				u16 _tmp, *p;
-				p = skb_header_pointer(skb, k, 2, &_tmp);
-				if (p != NULL) {
-					A = ntohs(*p);
-					continue;
-				}
-			}
 			return 0;
 		case BPF_LD|BPF_B|BPF_ABS:
 			k = fentry->k;
 load_b:
-			if (k >= 0 && (unsigned int)k < len) {
-				A = data[k];
+			ptr = load_pointer(skb, k, 1, &tmp);
+			if (ptr != NULL) {
+				A = *(u8 *)ptr;
 				continue;
 			}
-			if (k < 0) {
-				u8 *ptr;
-
-				if (k >= SKF_AD_OFF)
-					break;
-				ptr = load_pointer(skb, k);
-				if (ptr) {
-					A = *ptr;
-					continue;
-				}
-			} else {
-				u8 _tmp, *p;
-				p = skb_header_pointer(skb, k, 1, &_tmp);
-				if (p != NULL) {
-					A = *p;
-					continue;
-				}
-			}
 			return 0;
 		case BPF_LD|BPF_W|BPF_LEN:
-			A = len;
+			A = skb->len;
 			continue;
 		case BPF_LDX|BPF_W|BPF_LEN:
-			X = len;
+			X = skb->len;
 			continue;
 		case BPF_LD|BPF_W|BPF_IND:
 			k = X + fentry->k;
@@ -259,10 +217,12 @@ load_b:
 			k = X + fentry->k;
 			goto load_b;
 		case BPF_LDX|BPF_B|BPF_MSH:
-			if (fentry->k >= len)
-				return 0;
-			X = (data[fentry->k] & 0xf) << 2;
-			continue;
+			ptr = load_pointer(skb, fentry->k, 1, &tmp);
+			if (ptr != NULL) {
+				X = (*(u8 *)ptr & 0xf) << 2;
+				continue;
+			}
+			return 0;
 		case BPF_LD|BPF_IMM:
 			A = fentry->k;
 			continue;
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -32,6 +32,7 @@
 #include <net/sock.h>
 #include <linux/rtnetlink.h>
 #include <linux/random.h>
+#include <linux/string.h>
 
 #define NEIGH_DEBUG 1
 
@@ -1276,9 +1277,14 @@ struct neigh_parms *neigh_parms_alloc(st
 		INIT_RCU_HEAD(&p->rcu_head);
 		p->reachable_time =
 				neigh_rand_reach_time(p->base_reachable_time);
-		if (dev && dev->neigh_setup && dev->neigh_setup(dev, p)) {
-			kfree(p);
-			return NULL;
+		if (dev) {
+			if (dev->neigh_setup && dev->neigh_setup(dev, p)) {
+				kfree(p);
+				return NULL;
+			}
+
+			dev_hold(dev);
+			p->dev = dev;
 		}
 		p->sysctl_table = NULL;
 		write_lock_bh(&tbl->lock);
@@ -1309,6 +1315,8 @@ void neigh_parms_release(struct neigh_ta
 			*p = parms->next;
 			parms->dead = 1;
 			write_unlock_bh(&tbl->lock);
+			if (parms->dev)
+				dev_put(parms->dev);
 			call_rcu(&parms->rcu_head, neigh_rcu_free_parms);
 			return;
 		}
@@ -1546,21 +1554,330 @@ out:
 	return err;
 }
 
+static int neightbl_fill_parms(struct sk_buff *skb, struct neigh_parms *parms)
+{
+	struct rtattr *nest = NULL;
+	
+	nest = RTA_NEST(skb, NDTA_PARMS);
+
+	if (parms->dev)
+		RTA_PUT_U32(skb, NDTPA_IFINDEX, parms->dev->ifindex);
+
+	RTA_PUT_U32(skb, NDTPA_REFCNT, atomic_read(&parms->refcnt));
+	RTA_PUT_U32(skb, NDTPA_QUEUE_LEN, parms->queue_len);
+	RTA_PUT_U32(skb, NDTPA_PROXY_QLEN, parms->proxy_qlen);
+	RTA_PUT_U32(skb, NDTPA_APP_PROBES, parms->app_probes);
+	RTA_PUT_U32(skb, NDTPA_UCAST_PROBES, parms->ucast_probes);
+	RTA_PUT_U32(skb, NDTPA_MCAST_PROBES, parms->mcast_probes);
+	RTA_PUT_MSECS(skb, NDTPA_REACHABLE_TIME, parms->reachable_time);
+	RTA_PUT_MSECS(skb, NDTPA_BASE_REACHABLE_TIME,
+		      parms->base_reachable_time);
+	RTA_PUT_MSECS(skb, NDTPA_GC_STALETIME, parms->gc_staletime);
+	RTA_PUT_MSECS(skb, NDTPA_DELAY_PROBE_TIME, parms->delay_probe_time);
+	RTA_PUT_MSECS(skb, NDTPA_RETRANS_TIME, parms->retrans_time);
+	RTA_PUT_MSECS(skb, NDTPA_ANYCAST_DELAY, parms->anycast_delay);
+	RTA_PUT_MSECS(skb, NDTPA_PROXY_DELAY, parms->proxy_delay);
+	RTA_PUT_MSECS(skb, NDTPA_LOCKTIME, parms->locktime);
+
+	return RTA_NEST_END(skb, nest);
+
+rtattr_failure:
+	return RTA_NEST_CANCEL(skb, nest);
+}
+
+static int neightbl_fill_info(struct neigh_table *tbl, struct sk_buff *skb,
+			      struct netlink_callback *cb)
+{
+	struct nlmsghdr *nlh;
+	struct ndtmsg *ndtmsg;
+
+	nlh = NLMSG_NEW_ANSWER(skb, cb, RTM_NEWNEIGHTBL, sizeof(struct ndtmsg),
+			       NLM_F_MULTI);
+
+	ndtmsg = NLMSG_DATA(nlh);
+
+	read_lock_bh(&tbl->lock);
+	ndtmsg->ndtm_family = tbl->family;
+	ndtmsg->ndtm_pad1   = 0;
+	ndtmsg->ndtm_pad2   = 0;
+
+	RTA_PUT_STRING(skb, NDTA_NAME, tbl->id);
+	RTA_PUT_MSECS(skb, NDTA_GC_INTERVAL, tbl->gc_interval);
+	RTA_PUT_U32(skb, NDTA_THRESH1, tbl->gc_thresh1);
+	RTA_PUT_U32(skb, NDTA_THRESH2, tbl->gc_thresh2);
+	RTA_PUT_U32(skb, NDTA_THRESH3, tbl->gc_thresh3);
+
+	{
+		unsigned long now = jiffies;
+		unsigned int flush_delta = now - tbl->last_flush;
+		unsigned int rand_delta = now - tbl->last_rand;
+
+		struct ndt_config ndc = {
+			.ndtc_key_len		= tbl->key_len,
+			.ndtc_entry_size	= tbl->entry_size,
+			.ndtc_entries		= atomic_read(&tbl->entries),
+			.ndtc_last_flush	= jiffies_to_msecs(flush_delta),
+			.ndtc_last_rand		= jiffies_to_msecs(rand_delta),
+			.ndtc_hash_rnd		= tbl->hash_rnd,
+			.ndtc_hash_mask		= tbl->hash_mask,
+			.ndtc_hash_chain_gc	= tbl->hash_chain_gc,
+			.ndtc_proxy_qlen	= tbl->proxy_queue.qlen,
+		};
+
+		RTA_PUT(skb, NDTA_CONFIG, sizeof(ndc), &ndc);
+	}
+
+	{
+		int cpu;
+		struct ndt_stats ndst;
+
+		memset(&ndst, 0, sizeof(ndst));
+
+		for (cpu = 0; cpu < NR_CPUS; cpu++) {
+			struct neigh_statistics	*st;
+
+			if (!cpu_possible(cpu))
+				continue;
+
+			st = per_cpu_ptr(tbl->stats, cpu);
+			ndst.ndts_allocs		+= st->allocs;
+			ndst.ndts_destroys		+= st->destroys;
+			ndst.ndts_hash_grows		+= st->hash_grows;
+			ndst.ndts_res_failed		+= st->res_failed;
+			ndst.ndts_lookups		+= st->lookups;
+			ndst.ndts_hits			+= st->hits;
+			ndst.ndts_rcv_probes_mcast	+= st->rcv_probes_mcast;
+			ndst.ndts_rcv_probes_ucast	+= st->rcv_probes_ucast;
+			ndst.ndts_periodic_gc_runs	+= st->periodic_gc_runs;
+			ndst.ndts_forced_gc_runs	+= st->forced_gc_runs;
+		}
+
+		RTA_PUT(skb, NDTA_STATS, sizeof(ndst), &ndst);
+	}
+
+	BUG_ON(tbl->parms.dev);
+	if (neightbl_fill_parms(skb, &tbl->parms) < 0)
+		goto rtattr_failure;
+
+	read_unlock_bh(&tbl->lock);
+	return NLMSG_END(skb, nlh);
+
+rtattr_failure:
+	read_unlock_bh(&tbl->lock);
+	return NLMSG_CANCEL(skb, nlh);
+ 
+nlmsg_failure:
+	return -1;
+}
+
+static int neightbl_fill_param_info(struct neigh_table *tbl,
+				    struct neigh_parms *parms,
+				    struct sk_buff *skb,
+				    struct netlink_callback *cb)
+{
+	struct ndtmsg *ndtmsg;
+	struct nlmsghdr *nlh;
+
+	nlh = NLMSG_NEW_ANSWER(skb, cb, RTM_NEWNEIGHTBL, sizeof(struct ndtmsg),
+			       NLM_F_MULTI);
+
+	ndtmsg = NLMSG_DATA(nlh);
+
+	read_lock_bh(&tbl->lock);
+	ndtmsg->ndtm_family = tbl->family;
+	ndtmsg->ndtm_pad1   = 0;
+	ndtmsg->ndtm_pad2   = 0;
+	RTA_PUT_STRING(skb, NDTA_NAME, tbl->id);
+
+	if (neightbl_fill_parms(skb, parms) < 0)
+		goto rtattr_failure;
+
+	read_unlock_bh(&tbl->lock);
+	return NLMSG_END(skb, nlh);
+
+rtattr_failure:
+	read_unlock_bh(&tbl->lock);
+	return NLMSG_CANCEL(skb, nlh);
+
+nlmsg_failure:
+	return -1;
+}
+ 
+static inline struct neigh_parms *lookup_neigh_params(struct neigh_table *tbl,
+						      int ifindex)
+{
+	struct neigh_parms *p;
+	
+	for (p = &tbl->parms; p; p = p->next)
+		if ((p->dev && p->dev->ifindex == ifindex) ||
+		    (!p->dev && !ifindex))
+			return p;
+
+	return NULL;
+}
+
+int neightbl_set(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
+{
+	struct neigh_table *tbl;
+	struct ndtmsg *ndtmsg = NLMSG_DATA(nlh);
+	struct rtattr **tb = arg;
+	int err = -EINVAL;
+
+	if (!tb[NDTA_NAME - 1] || !RTA_PAYLOAD(tb[NDTA_NAME - 1]))
+		return -EINVAL;
+
+	read_lock(&neigh_tbl_lock);
+	for (tbl = neigh_tables; tbl; tbl = tbl->next) {
+		if (ndtmsg->ndtm_family && tbl->family != ndtmsg->ndtm_family)
+			continue;
+
+		if (!rtattr_strcmp(tb[NDTA_NAME - 1], tbl->id))
+			break;
+	}
+
+	if (tbl == NULL) {
+		err = -ENOENT;
+		goto errout;
+	}
+
+	/* 
+	 * We acquire tbl->lock to be nice to the periodic timers and
+	 * make sure they always see a consistent set of values.
+	 */
+	write_lock_bh(&tbl->lock);
+
+	if (tb[NDTA_THRESH1 - 1])
+		tbl->gc_thresh1 = RTA_GET_U32(tb[NDTA_THRESH1 - 1]);
+
+	if (tb[NDTA_THRESH2 - 1])
+		tbl->gc_thresh2 = RTA_GET_U32(tb[NDTA_THRESH2 - 1]);
+
+	if (tb[NDTA_THRESH3 - 1])
+		tbl->gc_thresh3 = RTA_GET_U32(tb[NDTA_THRESH3 - 1]);
+
+	if (tb[NDTA_GC_INTERVAL - 1])
+		tbl->gc_interval = RTA_GET_MSECS(tb[NDTA_GC_INTERVAL - 1]);
+
+	if (tb[NDTA_PARMS - 1]) {
+		struct rtattr *tbp[NDTPA_MAX];
+		struct neigh_parms *p;
+		u32 ifindex = 0;
+
+		if (rtattr_parse_nested(tbp, NDTPA_MAX, tb[NDTA_PARMS - 1]) < 0)
+			goto rtattr_failure;
+
+		if (tbp[NDTPA_IFINDEX - 1])
+			ifindex = RTA_GET_U32(tbp[NDTPA_IFINDEX - 1]);
+
+		p = lookup_neigh_params(tbl, ifindex);
+		if (p == NULL) {
+			err = -ENOENT;
+			goto rtattr_failure;
+		}
+	
+		if (tbp[NDTPA_QUEUE_LEN - 1])
+			p->queue_len = RTA_GET_U32(tbp[NDTPA_QUEUE_LEN - 1]);
+
+		if (tbp[NDTPA_PROXY_QLEN - 1])
+			p->proxy_qlen = RTA_GET_U32(tbp[NDTPA_PROXY_QLEN - 1]);
+
+		if (tbp[NDTPA_APP_PROBES - 1])
+			p->app_probes = RTA_GET_U32(tbp[NDTPA_APP_PROBES - 1]);
+
+		if (tbp[NDTPA_UCAST_PROBES - 1])
+			p->ucast_probes =
+			   RTA_GET_U32(tbp[NDTPA_UCAST_PROBES - 1]);
+
+		if (tbp[NDTPA_MCAST_PROBES - 1])
+			p->mcast_probes =
+			   RTA_GET_U32(tbp[NDTPA_MCAST_PROBES - 1]);
+
+		if (tbp[NDTPA_BASE_REACHABLE_TIME - 1])
+			p->base_reachable_time =
+			   RTA_GET_MSECS(tbp[NDTPA_BASE_REACHABLE_TIME - 1]);
+
+		if (tbp[NDTPA_GC_STALETIME - 1])
+			p->gc_staletime =
+			   RTA_GET_MSECS(tbp[NDTPA_GC_STALETIME - 1]);
+
+		if (tbp[NDTPA_DELAY_PROBE_TIME - 1])
+			p->delay_probe_time =
+			   RTA_GET_MSECS(tbp[NDTPA_DELAY_PROBE_TIME - 1]);
+
+		if (tbp[NDTPA_RETRANS_TIME - 1])
+			p->retrans_time =
+			   RTA_GET_MSECS(tbp[NDTPA_RETRANS_TIME - 1]);
+
+		if (tbp[NDTPA_ANYCAST_DELAY - 1])
+			p->anycast_delay =
+			   RTA_GET_MSECS(tbp[NDTPA_ANYCAST_DELAY - 1]);
+
+		if (tbp[NDTPA_PROXY_DELAY - 1])
+			p->proxy_delay =
+			   RTA_GET_MSECS(tbp[NDTPA_PROXY_DELAY - 1]);
+
+		if (tbp[NDTPA_LOCKTIME - 1])
+			p->locktime = RTA_GET_MSECS(tbp[NDTPA_LOCKTIME - 1]);
+	}
+
+	err = 0;
+
+rtattr_failure:
+	write_unlock_bh(&tbl->lock);
+errout:
+	read_unlock(&neigh_tbl_lock);
+	return err;
+}
+
+int neightbl_dump_info(struct sk_buff *skb, struct netlink_callback *cb)
+{
+	int idx, family;
+	int s_idx = cb->args[0];
+	struct neigh_table *tbl;
+
+	family = ((struct rtgenmsg *)NLMSG_DATA(cb->nlh))->rtgen_family;
+
+	read_lock(&neigh_tbl_lock);
+	for (tbl = neigh_tables, idx = 0; tbl; tbl = tbl->next) {
+		struct neigh_parms *p;
+
+		if (idx < s_idx || (family && tbl->family != family))
+			continue;
+
+		if (neightbl_fill_info(tbl, skb, cb) <= 0)
+			break;
+
+		for (++idx, p = tbl->parms.next; p; p = p->next, idx++) {
+			if (idx < s_idx)
+				continue;
+
+			if (neightbl_fill_param_info(tbl, p, skb, cb) <= 0)
+				goto out;
+		}
+
+	}
+out:
+	read_unlock(&neigh_tbl_lock);
+	cb->args[0] = idx;
+
+	return skb->len;
+}
 
 static int neigh_fill_info(struct sk_buff *skb, struct neighbour *n,
-			   u32 pid, u32 seq, int event)
+			   u32 pid, u32 seq, int event, unsigned int flags)
 {
 	unsigned long now = jiffies;
 	unsigned char *b = skb->tail;
 	struct nda_cacheinfo ci;
 	int locked = 0;
 	u32 probes;
-	struct nlmsghdr *nlh = NLMSG_PUT(skb, pid, seq, event,
-					 sizeof(struct ndmsg));
+	struct nlmsghdr *nlh = NLMSG_NEW(skb, pid, seq, event,
+					 sizeof(struct ndmsg), flags);
 	struct ndmsg *ndm = NLMSG_DATA(nlh);
 
-	nlh->nlmsg_flags = pid ? NLM_F_MULTI : 0;
 	ndm->ndm_family	 = n->ops->family;
+	ndm->ndm_pad1    = 0;
+	ndm->ndm_pad2    = 0;
 	ndm->ndm_flags	 = n->flags;
 	ndm->ndm_type	 = n->type;
 	ndm->ndm_ifindex = n->dev->ifindex;
@@ -1609,7 +1926,8 @@ static int neigh_dump_table(struct neigh
 				continue;
 			if (neigh_fill_info(skb, n, NETLINK_CB(cb->skb).pid,
 					    cb->nlh->nlmsg_seq,
-					    RTM_NEWNEIGH) <= 0) {
+					    RTM_NEWNEIGH,
+					    NLM_F_MULTI) <= 0) {
 				read_unlock_bh(&tbl->lock);
 				rc = -1;
 				goto out;
@@ -2018,7 +2336,7 @@ void neigh_app_ns(struct neighbour *n)
 	if (!skb)
 		return;
 
-	if (neigh_fill_info(skb, n, 0, 0, RTM_GETNEIGH) < 0) {
+	if (neigh_fill_info(skb, n, 0, 0, RTM_GETNEIGH, 0) < 0) {
 		kfree_skb(skb);
 		return;
 	}
@@ -2037,7 +2355,7 @@ static void neigh_app_notify(struct neig
 	if (!skb)
 		return;
 
-	if (neigh_fill_info(skb, n, 0, 0, RTM_NEWNEIGH) < 0) {
+	if (neigh_fill_info(skb, n, 0, 0, RTM_NEWNEIGH, 0) < 0) {
 		kfree_skb(skb);
 		return;
 	}
@@ -2281,7 +2599,7 @@ int neigh_sysctl_register(struct net_dev
 		t->neigh_vars[17].extra1 = dev;
 	}
 
-	dev_name = net_sysctl_strdup(dev_name_source);
+	dev_name = kstrdup(dev_name_source, GFP_KERNEL);
 	if (!dev_name) {
 		err = -ENOBUFS;
 		goto free;
@@ -2352,6 +2670,8 @@ EXPORT_SYMBOL(neigh_update);
 EXPORT_SYMBOL(neigh_update_hhs);
 EXPORT_SYMBOL(pneigh_enqueue);
 EXPORT_SYMBOL(pneigh_lookup);
+EXPORT_SYMBOL(neightbl_dump_info);
+EXPORT_SYMBOL(neightbl_set);
 
 #ifdef CONFIG_ARPD
 EXPORT_SYMBOL(neigh_app_ns);
diff --git a/net/core/netfilter.c b/net/core/netfilter.c
--- a/net/core/netfilter.c
+++ b/net/core/netfilter.c
@@ -141,136 +141,6 @@ void nf_unregister_sockopt(struct nf_soc
 	up(&nf_sockopt_mutex);
 }
 
-#ifdef CONFIG_NETFILTER_DEBUG
-#include <net/ip.h>
-#include <net/tcp.h>
-#include <linux/netfilter_ipv4.h>
-
-static void debug_print_hooks_ip(unsigned int nf_debug)
-{
-	if (nf_debug & (1 << NF_IP_PRE_ROUTING)) {
-		printk("PRE_ROUTING ");
-		nf_debug ^= (1 << NF_IP_PRE_ROUTING);
-	}
-	if (nf_debug & (1 << NF_IP_LOCAL_IN)) {
-		printk("LOCAL_IN ");
-		nf_debug ^= (1 << NF_IP_LOCAL_IN);
-	}
-	if (nf_debug & (1 << NF_IP_FORWARD)) {
-		printk("FORWARD ");
-		nf_debug ^= (1 << NF_IP_FORWARD);
-	}
-	if (nf_debug & (1 << NF_IP_LOCAL_OUT)) {
-		printk("LOCAL_OUT ");
-		nf_debug ^= (1 << NF_IP_LOCAL_OUT);
-	}
-	if (nf_debug & (1 << NF_IP_POST_ROUTING)) {
-		printk("POST_ROUTING ");
-		nf_debug ^= (1 << NF_IP_POST_ROUTING);
-	}
-	if (nf_debug)
-		printk("Crap bits: 0x%04X", nf_debug);
-	printk("\n");
-}
-
-static void nf_dump_skb(int pf, struct sk_buff *skb)
-{
-	printk("skb: pf=%i %s dev=%s len=%u\n", 
-	       pf,
-	       skb->sk ? "(owned)" : "(unowned)",
-	       skb->dev ? skb->dev->name : "(no dev)",
-	       skb->len);
-	switch (pf) {
-	case PF_INET: {
-		const struct iphdr *ip = skb->nh.iph;
-		__u32 *opt = (__u32 *) (ip + 1);
-		int opti;
-		__u16 src_port = 0, dst_port = 0;
-
-		if (ip->protocol == IPPROTO_TCP
-		    || ip->protocol == IPPROTO_UDP) {
-			struct tcphdr *tcp=(struct tcphdr *)((__u32 *)ip+ip->ihl);
-			src_port = ntohs(tcp->source);
-			dst_port = ntohs(tcp->dest);
-		}
-	
-		printk("PROTO=%d %u.%u.%u.%u:%hu %u.%u.%u.%u:%hu"
-		       " L=%hu S=0x%2.2hX I=%hu F=0x%4.4hX T=%hu",
-		       ip->protocol, NIPQUAD(ip->saddr),
-		       src_port, NIPQUAD(ip->daddr),
-		       dst_port,
-		       ntohs(ip->tot_len), ip->tos, ntohs(ip->id),
-		       ntohs(ip->frag_off), ip->ttl);
-
-		for (opti = 0; opti < (ip->ihl - sizeof(struct iphdr) / 4); opti++)
-			printk(" O=0x%8.8X", *opt++);
-		printk("\n");
-	}
-	}
-}
-
-void nf_debug_ip_local_deliver(struct sk_buff *skb)
-{
-	/* If it's a loopback packet, it must have come through
-	 * NF_IP_LOCAL_OUT, NF_IP_RAW_INPUT, NF_IP_PRE_ROUTING and
-	 * NF_IP_LOCAL_IN.  Otherwise, must have gone through
-	 * NF_IP_RAW_INPUT and NF_IP_PRE_ROUTING.  */
-	if (!skb->dev) {
-		printk("ip_local_deliver: skb->dev is NULL.\n");
-	} else {
-		if (skb->nf_debug != ((1<<NF_IP_PRE_ROUTING)
-				      | (1<<NF_IP_LOCAL_IN))) {
-			printk("ip_local_deliver: bad skb: ");
-			debug_print_hooks_ip(skb->nf_debug);
-			nf_dump_skb(PF_INET, skb);
-		}
-	}
-}
-
-void nf_debug_ip_loopback_xmit(struct sk_buff *newskb)
-{
-	if (newskb->nf_debug != ((1 << NF_IP_LOCAL_OUT)
-				 | (1 << NF_IP_POST_ROUTING))) {
-		printk("ip_dev_loopback_xmit: bad owned skb = %p: ", 
-		       newskb);
-		debug_print_hooks_ip(newskb->nf_debug);
-		nf_dump_skb(PF_INET, newskb);
-	}
-}
-
-void nf_debug_ip_finish_output2(struct sk_buff *skb)
-{
-	/* If it's owned, it must have gone through the
-	 * NF_IP_LOCAL_OUT and NF_IP_POST_ROUTING.
-	 * Otherwise, must have gone through
-	 * NF_IP_PRE_ROUTING, NF_IP_FORWARD and NF_IP_POST_ROUTING.
-	 */
-	if (skb->sk) {
-		if (skb->nf_debug != ((1 << NF_IP_LOCAL_OUT)
-				      | (1 << NF_IP_POST_ROUTING))) {
-			printk("ip_finish_output: bad owned skb = %p: ", skb);
-			debug_print_hooks_ip(skb->nf_debug);
-			nf_dump_skb(PF_INET, skb);
-		}
-	} else {
-		if (skb->nf_debug != ((1 << NF_IP_PRE_ROUTING)
-				      | (1 << NF_IP_FORWARD)
-				      | (1 << NF_IP_POST_ROUTING))) {
-			/* Fragments, entunnelled packets, TCP RSTs
-                           generated by ipt_REJECT will have no
-                           owners, but still may be local */
-			if (skb->nf_debug != ((1 << NF_IP_LOCAL_OUT)
-					      | (1 << NF_IP_POST_ROUTING))){
-				printk("ip_finish_output:"
-				       " bad unowned skb = %p: ",skb);
-				debug_print_hooks_ip(skb->nf_debug);
-				nf_dump_skb(PF_INET, skb);
-			}
-		}
-	}
-}
-#endif /*CONFIG_NETFILTER_DEBUG*/
-
 /* Call get/setsockopt() */
 static int nf_sockopt(struct sock *sk, int pf, int val, 
 		      char __user *opt, int *len, int get)
@@ -488,14 +358,6 @@ int nf_hook_slow(int pf, unsigned int ho
 	/* We may already have this, but read-locks nest anyway */
 	rcu_read_lock();
 
-#ifdef CONFIG_NETFILTER_DEBUG
-	if (unlikely((*pskb)->nf_debug & (1 << hook))) {
-		printk("nf_hook: hook %i already set.\n", hook);
-		nf_dump_skb(pf, *pskb);
-	}
-	(*pskb)->nf_debug |= (1 << hook);
-#endif
-
 	elem = &nf_hooks[pf][hook];
 next_hook:
 	verdict = nf_iterate(&nf_hooks[pf][hook], pskb, hook, indev,
diff --git a/net/core/netpoll.c b/net/core/netpoll.c
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -33,6 +33,7 @@
 #define MAX_UDP_CHUNK 1460
 #define MAX_SKBS 32
 #define MAX_QUEUE_DEPTH (MAX_SKBS / 2)
+#define MAX_RETRIES 20000
 
 static DEFINE_SPINLOCK(skb_list_lock);
 static int nr_skbs;
@@ -130,19 +131,20 @@ static int checksum_udp(struct sk_buff *
  */
 static void poll_napi(struct netpoll *np)
 {
+	struct netpoll_info *npinfo = np->dev->npinfo;
 	int budget = 16;
 
 	if (test_bit(__LINK_STATE_RX_SCHED, &np->dev->state) &&
-	    np->poll_owner != smp_processor_id() &&
-	    spin_trylock(&np->poll_lock)) {
-		np->rx_flags |= NETPOLL_RX_DROP;
+	    npinfo->poll_owner != smp_processor_id() &&
+	    spin_trylock(&npinfo->poll_lock)) {
+		npinfo->rx_flags |= NETPOLL_RX_DROP;
 		atomic_inc(&trapped);
 
 		np->dev->poll(np->dev, &budget);
 
 		atomic_dec(&trapped);
-		np->rx_flags &= ~NETPOLL_RX_DROP;
-		spin_unlock(&np->poll_lock);
+		npinfo->rx_flags &= ~NETPOLL_RX_DROP;
+		spin_unlock(&npinfo->poll_lock);
 	}
 }
 
@@ -245,16 +247,18 @@ repeat:
 static void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb)
 {
 	int status;
+	struct netpoll_info *npinfo;
 
-repeat:
-	if(!np || !np->dev || !netif_running(np->dev)) {
+	if (!np || !np->dev || !netif_running(np->dev)) {
 		__kfree_skb(skb);
 		return;
 	}
 
+	npinfo = np->dev->npinfo;
+
 	/* avoid recursion */
-	if(np->poll_owner == smp_processor_id() ||
-	   np->dev->xmit_lock_owner == smp_processor_id()) {
+	if (npinfo->poll_owner == smp_processor_id() ||
+	    np->dev->xmit_lock_owner == smp_processor_id()) {
 		if (np->drop)
 			np->drop(skb);
 		else
@@ -262,30 +266,37 @@ repeat:
 		return;
 	}
 
-	spin_lock(&np->dev->xmit_lock);
-	np->dev->xmit_lock_owner = smp_processor_id();
+	do {
+		npinfo->tries--;
+		spin_lock(&np->dev->xmit_lock);
+		np->dev->xmit_lock_owner = smp_processor_id();
+
+		/*
+		 * network drivers do not expect to be called if the queue is
+		 * stopped.
+		 */
+		if (netif_queue_stopped(np->dev)) {
+			np->dev->xmit_lock_owner = -1;
+			spin_unlock(&np->dev->xmit_lock);
+			netpoll_poll(np);
+			udelay(50);
+			continue;
+		}
 
-	/*
-	 * network drivers do not expect to be called if the queue is
-	 * stopped.
-	 */
-	if (netif_queue_stopped(np->dev)) {
+		status = np->dev->hard_start_xmit(skb, np->dev);
 		np->dev->xmit_lock_owner = -1;
 		spin_unlock(&np->dev->xmit_lock);
 
-		netpoll_poll(np);
-		goto repeat;
-	}
-
-	status = np->dev->hard_start_xmit(skb, np->dev);
-	np->dev->xmit_lock_owner = -1;
-	spin_unlock(&np->dev->xmit_lock);
+		/* success */
+		if(!status) {
+			npinfo->tries = MAX_RETRIES; /* reset */
+			return;
+		}
 
-	/* transmit busy */
-	if(status) {
+		/* transmit busy */
 		netpoll_poll(np);
-		goto repeat;
-	}
+		udelay(50);
+	} while (npinfo->tries > 0);
 }
 
 void netpoll_send_udp(struct netpoll *np, const char *msg, int len)
@@ -341,14 +352,18 @@ void netpoll_send_udp(struct netpoll *np
 
 static void arp_reply(struct sk_buff *skb)
 {
+	struct netpoll_info *npinfo = skb->dev->npinfo;
 	struct arphdr *arp;
 	unsigned char *arp_ptr;
 	int size, type = ARPOP_REPLY, ptype = ETH_P_ARP;
 	u32 sip, tip;
 	struct sk_buff *send_skb;
-	struct netpoll *np = skb->dev->np;
+	struct netpoll *np = NULL;
 
-	if (!np) return;
+	if (npinfo->rx_np && npinfo->rx_np->dev == skb->dev)
+		np = npinfo->rx_np;
+	if (!np)
+		return;
 
 	/* No arp on this interface */
 	if (skb->dev->flags & IFF_NOARP)
@@ -429,9 +444,9 @@ int __netpoll_rx(struct sk_buff *skb)
 	int proto, len, ulen;
 	struct iphdr *iph;
 	struct udphdr *uh;
-	struct netpoll *np = skb->dev->np;
+	struct netpoll *np = skb->dev->npinfo->rx_np;
 
-	if (!np->rx_hook)
+	if (!np)
 		goto out;
 	if (skb->dev->type != ARPHRD_ETHER)
 		goto out;
@@ -611,9 +626,8 @@ int netpoll_setup(struct netpoll *np)
 {
 	struct net_device *ndev = NULL;
 	struct in_device *in_dev;
-
-	np->poll_lock = SPIN_LOCK_UNLOCKED;
-	np->poll_owner = -1;
+	struct netpoll_info *npinfo;
+	unsigned long flags;
 
 	if (np->dev_name)
 		ndev = dev_get_by_name(np->dev_name);
@@ -624,7 +638,19 @@ int netpoll_setup(struct netpoll *np)
 	}
 
 	np->dev = ndev;
-	ndev->np = np;
+	if (!ndev->npinfo) {
+		npinfo = kmalloc(sizeof(*npinfo), GFP_KERNEL);
+		if (!npinfo)
+			goto release;
+
+		npinfo->rx_flags = 0;
+		npinfo->rx_np = NULL;
+		npinfo->poll_lock = SPIN_LOCK_UNLOCKED;
+		npinfo->poll_owner = -1;
+		npinfo->tries = MAX_RETRIES;
+		npinfo->rx_lock = SPIN_LOCK_UNLOCKED;
+	} else
+		npinfo = ndev->npinfo;
 
 	if (!ndev->poll_controller) {
 		printk(KERN_ERR "%s: %s doesn't support polling, aborting.\n",
@@ -692,13 +718,27 @@ int netpoll_setup(struct netpoll *np)
 		       np->name, HIPQUAD(np->local_ip));
 	}
 
-	if(np->rx_hook)
-		np->rx_flags = NETPOLL_RX_ENABLED;
+	if (np->rx_hook) {
+		spin_lock_irqsave(&npinfo->rx_lock, flags);
+		npinfo->rx_flags |= NETPOLL_RX_ENABLED;
+		npinfo->rx_np = np;
+		spin_unlock_irqrestore(&npinfo->rx_lock, flags);
+	}
+
+	/* fill up the skb queue */
+	refill_skbs();
+
+	/* last thing to do is link it to the net device structure */
+	ndev->npinfo = npinfo;
+
+	/* avoid racing with NAPI reading npinfo */
+	synchronize_rcu();
 
 	return 0;
 
  release:
-	ndev->np = NULL;
+	if (!ndev->npinfo)
+		kfree(npinfo);
 	np->dev = NULL;
 	dev_put(ndev);
 	return -1;
@@ -706,9 +746,20 @@ int netpoll_setup(struct netpoll *np)
 
 void netpoll_cleanup(struct netpoll *np)
 {
-	if (np->dev)
-		np->dev->np = NULL;
-	dev_put(np->dev);
+	struct netpoll_info *npinfo;
+	unsigned long flags;
+
+	if (np->dev) {
+		npinfo = np->dev->npinfo;
+		if (npinfo && npinfo->rx_np == np) {
+			spin_lock_irqsave(&npinfo->rx_lock, flags);
+			npinfo->rx_np = NULL;
+			npinfo->rx_flags &= ~NETPOLL_RX_ENABLED;
+			spin_unlock_irqrestore(&npinfo->rx_lock, flags);
+		}
+		dev_put(np->dev);
+	}
+
 	np->dev = NULL;
 }
 
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -151,7 +151,7 @@
 #include <asm/timex.h>
 
 
-#define VERSION  "pktgen v2.61: Packet Generator for packet performance testing.\n"
+#define VERSION  "pktgen v2.62: Packet Generator for packet performance testing.\n"
 
 /* #define PG_DEBUG(a) a */
 #define PG_DEBUG(a) 
@@ -363,7 +363,7 @@ struct pktgen_thread {
  * All Rights Reserved.
  *
  */
-inline static s64 divremdi3(s64 x, s64 y, int type) 
+static inline s64 divremdi3(s64 x, s64 y, int type)
 {
         u64 a = (x < 0) ? -x : x;
         u64 b = (y < 0) ? -y : y;
@@ -1921,6 +1921,11 @@ static struct sk_buff *fill_packet_ipv4(
 	struct iphdr *iph;
         struct pktgen_hdr *pgh = NULL;
         
+	/* Update any of the values, used when we're incrementing various
+	 * fields.
+	 */
+	mod_cur_headers(pkt_dev);
+
 	skb = alloc_skb(pkt_dev->cur_pkt_size + 64 + 16, GFP_ATOMIC);
 	if (!skb) {
 		sprintf(pkt_dev->result, "No memory");
@@ -1934,11 +1939,6 @@ static struct sk_buff *fill_packet_ipv4(
 	iph = (struct iphdr *)skb_put(skb, sizeof(struct iphdr));
 	udph = (struct udphdr *)skb_put(skb, sizeof(struct udphdr));
 
-        /* Update any of the values, used when we're incrementing various
-         * fields.
-         */
-        mod_cur_headers(pkt_dev);
-
 	memcpy(eth, pkt_dev->hh, 12);
 	*(u16*)&eth[12] = __constant_htons(ETH_P_IP);
 
@@ -2192,7 +2192,12 @@ static struct sk_buff *fill_packet_ipv6(
 	int datalen;
 	struct ipv6hdr *iph;
         struct pktgen_hdr *pgh = NULL;
-        
+
+	/* Update any of the values, used when we're incrementing various
+	 * fields.
+	 */
+	mod_cur_headers(pkt_dev);
+
 	skb = alloc_skb(pkt_dev->cur_pkt_size + 64 + 16, GFP_ATOMIC);
 	if (!skb) {
 		sprintf(pkt_dev->result, "No memory");
@@ -2206,17 +2211,9 @@ static struct sk_buff *fill_packet_ipv6(
 	iph = (struct ipv6hdr *)skb_put(skb, sizeof(struct ipv6hdr));
 	udph = (struct udphdr *)skb_put(skb, sizeof(struct udphdr));
 
-
-        /* Update any of the values, used when we're incrementing various
-         * fields.
-         */
-	mod_cur_headers(pkt_dev);
-
-	
 	memcpy(eth, pkt_dev->hh, 12);
 	*(u16*)&eth[12] = __constant_htons(ETH_P_IPV6);
-	
-        
+
 	datalen = pkt_dev->cur_pkt_size-14- 
 		sizeof(struct ipv6hdr)-sizeof(struct udphdr); /* Eth + IPh + UDPh */
 
diff --git a/net/core/request_sock.c b/net/core/request_sock.c
new file mode 100644
--- /dev/null
+++ b/net/core/request_sock.c
@@ -0,0 +1,64 @@
+/*
+ * NET		Generic infrastructure for Network protocols.
+ *
+ * Authors:	Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ *
+ * 		From code originally in include/net/tcp.h
+ *
+ *		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/random.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+
+#include <net/request_sock.h>
+
+/*
+ * Maximum number of SYN_RECV sockets in queue per LISTEN socket.
+ * One SYN_RECV socket costs about 80bytes on a 32bit machine.
+ * It would be better to replace it with a global counter for all sockets
+ * but then some measure against one socket starving all other sockets
+ * would be needed.
+ *
+ * It was 128 by default. Experiments with real servers show, that
+ * it is absolutely not enough even at 100conn/sec. 256 cures most
+ * of problems. This value is adjusted to 128 for very small machines
+ * (<=32Mb of memory) and to 1024 on normal or better ones (>=256Mb).
+ * Further increasing requires to change hash table size.
+ */
+int sysctl_max_syn_backlog = 256;
+EXPORT_SYMBOL(sysctl_max_syn_backlog);
+
+int reqsk_queue_alloc(struct request_sock_queue *queue,
+		      const int nr_table_entries)
+{
+	const int lopt_size = sizeof(struct listen_sock) +
+			      nr_table_entries * sizeof(struct request_sock *);
+	struct listen_sock *lopt = kmalloc(lopt_size, GFP_KERNEL);
+
+	if (lopt == NULL)
+		return -ENOMEM;
+
+	memset(lopt, 0, lopt_size);
+
+	for (lopt->max_qlen_log = 6;
+	     (1 << lopt->max_qlen_log) < sysctl_max_syn_backlog;
+	     lopt->max_qlen_log++);
+
+	get_random_bytes(&lopt->hash_rnd, sizeof(lopt->hash_rnd));
+	rwlock_init(&queue->syn_wait_lock);
+	queue->rskq_accept_head = queue->rskq_accept_head = NULL;
+
+	write_lock_bh(&queue->syn_wait_lock);
+	queue->listen_opt = lopt;
+	write_unlock_bh(&queue->syn_wait_lock);
+
+	return 0;
+}
+
+EXPORT_SYMBOL(reqsk_queue_alloc);
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -100,6 +100,7 @@ static const int rtm_min[RTM_NR_FAMILIES
 	[RTM_FAM(RTM_NEWPREFIX)]    = NLMSG_LENGTH(sizeof(struct rtgenmsg)),
 	[RTM_FAM(RTM_GETMULTICAST)] = NLMSG_LENGTH(sizeof(struct rtgenmsg)),
 	[RTM_FAM(RTM_GETANYCAST)]   = NLMSG_LENGTH(sizeof(struct rtgenmsg)),
+	[RTM_FAM(RTM_NEWNEIGHTBL)]  = NLMSG_LENGTH(sizeof(struct ndtmsg)),
 };
 
 static const int rta_max[RTM_NR_FAMILIES] =
@@ -113,6 +114,7 @@ static const int rta_max[RTM_NR_FAMILIES
 	[RTM_FAM(RTM_NEWTCLASS)]    = TCA_MAX,
 	[RTM_FAM(RTM_NEWTFILTER)]   = TCA_MAX,
 	[RTM_FAM(RTM_NEWACTION)]    = TCAA_MAX,
+	[RTM_FAM(RTM_NEWNEIGHTBL)]  = NDTA_MAX,
 };
 
 void __rta_fill(struct sk_buff *skb, int attrtype, int attrlen, const void *data)
@@ -124,6 +126,7 @@ void __rta_fill(struct sk_buff *skb, int
 	rta->rta_type = attrtype;
 	rta->rta_len = size;
 	memcpy(RTA_DATA(rta), data, attrlen);
+	memset(RTA_DATA(rta) + attrlen, 0, RTA_ALIGN(size) - size);
 }
 
 size_t rtattr_strlcpy(char *dest, const struct rtattr *rta, size_t size)
@@ -176,16 +179,17 @@ rtattr_failure:
 
 
 static int rtnetlink_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
-				 int type, u32 pid, u32 seq, u32 change)
+				 int type, u32 pid, u32 seq, u32 change, 
+				 unsigned int flags)
 {
 	struct ifinfomsg *r;
 	struct nlmsghdr  *nlh;
 	unsigned char	 *b = skb->tail;
 
-	nlh = NLMSG_PUT(skb, pid, seq, type, sizeof(*r));
-	if (pid) nlh->nlmsg_flags |= NLM_F_MULTI;
+	nlh = NLMSG_NEW(skb, pid, seq, type, sizeof(*r), flags);
 	r = NLMSG_DATA(nlh);
 	r->ifi_family = AF_UNSPEC;
+	r->__ifi_pad = 0;
 	r->ifi_type = dev->type;
 	r->ifi_index = dev->ifindex;
 	r->ifi_flags = dev_get_flags(dev);
@@ -273,7 +277,10 @@ static int rtnetlink_dump_ifinfo(struct 
 	for (dev=dev_base, idx=0; dev; dev = dev->next, idx++) {
 		if (idx < s_idx)
 			continue;
-		if (rtnetlink_fill_ifinfo(skb, dev, RTM_NEWLINK, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq, 0) <= 0)
+		if (rtnetlink_fill_ifinfo(skb, dev, RTM_NEWLINK,
+					  NETLINK_CB(cb->skb).pid,
+					  cb->nlh->nlmsg_seq, 0,
+					  NLM_F_MULTI) <= 0)
 			break;
 	}
 	read_unlock(&dev_base_lock);
@@ -447,7 +454,7 @@ void rtmsg_ifinfo(int type, struct net_d
 	if (!skb)
 		return;
 
-	if (rtnetlink_fill_ifinfo(skb, dev, type, 0, 0, change) < 0) {
+	if (rtnetlink_fill_ifinfo(skb, dev, type, current->pid, 0, change, 0) < 0) {
 		kfree_skb(skb);
 		return;
 	}
@@ -649,14 +656,16 @@ static void rtnetlink_rcv(struct sock *s
 
 static struct rtnetlink_link link_rtnetlink_table[RTM_NR_MSGTYPES] =
 {
-	[RTM_GETLINK  - RTM_BASE] = { .dumpit = rtnetlink_dump_ifinfo },
-	[RTM_SETLINK  - RTM_BASE] = { .doit   = do_setlink	      },
-	[RTM_GETADDR  - RTM_BASE] = { .dumpit = rtnetlink_dump_all    },
-	[RTM_GETROUTE - RTM_BASE] = { .dumpit = rtnetlink_dump_all    },
-	[RTM_NEWNEIGH - RTM_BASE] = { .doit   = neigh_add	      },
-	[RTM_DELNEIGH - RTM_BASE] = { .doit   = neigh_delete	      },
-	[RTM_GETNEIGH - RTM_BASE] = { .dumpit = neigh_dump_info	      },
-	[RTM_GETRULE  - RTM_BASE] = { .dumpit = rtnetlink_dump_all    },
+	[RTM_GETLINK     - RTM_BASE] = { .dumpit = rtnetlink_dump_ifinfo },
+	[RTM_SETLINK     - RTM_BASE] = { .doit   = do_setlink		 },
+	[RTM_GETADDR     - RTM_BASE] = { .dumpit = rtnetlink_dump_all	 },
+	[RTM_GETROUTE    - RTM_BASE] = { .dumpit = rtnetlink_dump_all	 },
+	[RTM_NEWNEIGH    - RTM_BASE] = { .doit   = neigh_add		 },
+	[RTM_DELNEIGH    - RTM_BASE] = { .doit   = neigh_delete		 },
+	[RTM_GETNEIGH    - RTM_BASE] = { .dumpit = neigh_dump_info	 },
+	[RTM_GETRULE     - RTM_BASE] = { .dumpit = rtnetlink_dump_all	 },
+	[RTM_GETNEIGHTBL - RTM_BASE] = { .dumpit = neightbl_dump_info	 },
+	[RTM_SETNEIGHTBL - RTM_BASE] = { .doit   = neightbl_set		 },
 };
 
 static int rtnetlink_event(struct notifier_block *this, unsigned long event, void *ptr)
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -129,7 +129,7 @@ void skb_under_panic(struct sk_buff *skb
  *	Buffers may only be allocated from interrupts using a @gfp_mask of
  *	%GFP_ATOMIC.
  */
-struct sk_buff *alloc_skb(unsigned int size, int gfp_mask)
+struct sk_buff *alloc_skb(unsigned int size, unsigned int __nocast gfp_mask)
 {
 	struct sk_buff *skb;
 	u8 *data;
@@ -182,7 +182,8 @@ nodata:
  *	%GFP_ATOMIC.
  */
 struct sk_buff *alloc_skb_from_cache(kmem_cache_t *cp,
-				     unsigned int size, int gfp_mask)
+				     unsigned int size,
+				     unsigned int __nocast gfp_mask)
 {
 	struct sk_buff *skb;
 	u8 *data;
@@ -322,7 +323,7 @@ void __kfree_skb(struct sk_buff *skb)
  *	%GFP_ATOMIC.
  */
 
-struct sk_buff *skb_clone(struct sk_buff *skb, int gfp_mask)
+struct sk_buff *skb_clone(struct sk_buff *skb, unsigned int __nocast gfp_mask)
 {
 	struct sk_buff *n = kmem_cache_alloc(skbuff_head_cache, gfp_mask);
 
@@ -357,7 +358,6 @@ struct sk_buff *skb_clone(struct sk_buff
 	C(ip_summed);
 	C(priority);
 	C(protocol);
-	C(security);
 	n->destructor = NULL;
 #ifdef CONFIG_NETFILTER
 	C(nfmark);
@@ -365,9 +365,6 @@ struct sk_buff *skb_clone(struct sk_buff
 	C(nfct);
 	nf_conntrack_get(skb->nfct);
 	C(nfctinfo);
-#ifdef CONFIG_NETFILTER_DEBUG
-	C(nf_debug);
-#endif
 #ifdef CONFIG_BRIDGE_NETFILTER
 	C(nf_bridge);
 	nf_bridge_get(skb->nf_bridge);
@@ -380,8 +377,8 @@ struct sk_buff *skb_clone(struct sk_buff
 	C(tc_index);
 #ifdef CONFIG_NET_CLS_ACT
 	n->tc_verd = SET_TC_VERD(skb->tc_verd,0);
-	n->tc_verd = CLR_TC_OK2MUNGE(skb->tc_verd);
-	n->tc_verd = CLR_TC_MUNGED(skb->tc_verd);
+	n->tc_verd = CLR_TC_OK2MUNGE(n->tc_verd);
+	n->tc_verd = CLR_TC_MUNGED(n->tc_verd);
 	C(input_dev);
 	C(tc_classid);
 #endif
@@ -425,16 +422,12 @@ static void copy_skb_header(struct sk_bu
 	new->pkt_type	= old->pkt_type;
 	new->stamp	= old->stamp;
 	new->destructor = NULL;
-	new->security	= old->security;
 #ifdef CONFIG_NETFILTER
 	new->nfmark	= old->nfmark;
 	new->nfcache	= old->nfcache;
 	new->nfct	= old->nfct;
 	nf_conntrack_get(old->nfct);
 	new->nfctinfo	= old->nfctinfo;
-#ifdef CONFIG_NETFILTER_DEBUG
-	new->nf_debug	= old->nf_debug;
-#endif
 #ifdef CONFIG_BRIDGE_NETFILTER
 	new->nf_bridge	= old->nf_bridge;
 	nf_bridge_get(old->nf_bridge);
@@ -468,7 +461,7 @@ static void copy_skb_header(struct sk_bu
  *	header is going to be modified. Use pskb_copy() instead.
  */
 
-struct sk_buff *skb_copy(const struct sk_buff *skb, int gfp_mask)
+struct sk_buff *skb_copy(const struct sk_buff *skb, unsigned int __nocast gfp_mask)
 {
 	int headerlen = skb->data - skb->head;
 	/*
@@ -507,7 +500,7 @@ struct sk_buff *skb_copy(const struct sk
  *	The returned buffer has a reference count of 1.
  */
 
-struct sk_buff *pskb_copy(struct sk_buff *skb, int gfp_mask)
+struct sk_buff *pskb_copy(struct sk_buff *skb, unsigned int __nocast gfp_mask)
 {
 	/*
 	 *	Allocate the copy buffer
@@ -565,7 +558,8 @@ out:
  *	reloaded after call to this function.
  */
 
-int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail, int gfp_mask)
+int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail,
+		     unsigned int __nocast gfp_mask)
 {
 	int i;
 	u8 *data;
@@ -655,7 +649,8 @@ struct sk_buff *skb_realloc_headroom(str
  *	only by netfilter in the cases when checksum is recalculated? --ANK
  */
 struct sk_buff *skb_copy_expand(const struct sk_buff *skb,
-				int newheadroom, int newtailroom, int gfp_mask)
+				int newheadroom, int newtailroom,
+				unsigned int __nocast gfp_mask)
 {
 	/*
 	 *	Allocate the copy buffer
@@ -1506,6 +1501,159 @@ void skb_split(struct sk_buff *skb, stru
 		skb_split_no_header(skb, skb1, len, pos);
 }
 
+/**
+ * skb_prepare_seq_read - Prepare a sequential read of skb data
+ * @skb: the buffer to read
+ * @from: lower offset of data to be read
+ * @to: upper offset of data to be read
+ * @st: state variable
+ *
+ * Initializes the specified state variable. Must be called before
+ * invoking skb_seq_read() for the first time.
+ */
+void skb_prepare_seq_read(struct sk_buff *skb, unsigned int from,
+			  unsigned int to, struct skb_seq_state *st)
+{
+	st->lower_offset = from;
+	st->upper_offset = to;
+	st->root_skb = st->cur_skb = skb;
+	st->frag_idx = st->stepped_offset = 0;
+	st->frag_data = NULL;
+}
+
+/**
+ * skb_seq_read - Sequentially read skb data
+ * @consumed: number of bytes consumed by the caller so far
+ * @data: destination pointer for data to be returned
+ * @st: state variable
+ *
+ * Reads a block of skb data at &consumed relative to the
+ * lower offset specified to skb_prepare_seq_read(). Assigns
+ * the head of the data block to &data and returns the length
+ * of the block or 0 if the end of the skb data or the upper
+ * offset has been reached.
+ *
+ * The caller is not required to consume all of the data
+ * returned, i.e. &consumed is typically set to the number
+ * of bytes already consumed and the next call to
+ * skb_seq_read() will return the remaining part of the block.
+ *
+ * Note: The size of each block of data returned can be arbitary,
+ *       this limitation is the cost for zerocopy seqeuental
+ *       reads of potentially non linear data.
+ *
+ * Note: Fragment lists within fragments are not implemented
+ *       at the moment, state->root_skb could be replaced with
+ *       a stack for this purpose.
+ */
+unsigned int skb_seq_read(unsigned int consumed, const u8 **data,
+			  struct skb_seq_state *st)
+{
+	unsigned int block_limit, abs_offset = consumed + st->lower_offset;
+	skb_frag_t *frag;
+
+	if (unlikely(abs_offset >= st->upper_offset))
+		return 0;
+
+next_skb:
+	block_limit = skb_headlen(st->cur_skb);
+
+	if (abs_offset < block_limit) {
+		*data = st->cur_skb->data + abs_offset;
+		return block_limit - abs_offset;
+	}
+
+	if (st->frag_idx == 0 && !st->frag_data)
+		st->stepped_offset += skb_headlen(st->cur_skb);
+
+	while (st->frag_idx < skb_shinfo(st->cur_skb)->nr_frags) {
+		frag = &skb_shinfo(st->cur_skb)->frags[st->frag_idx];
+		block_limit = frag->size + st->stepped_offset;
+
+		if (abs_offset < block_limit) {
+			if (!st->frag_data)
+				st->frag_data = kmap_skb_frag(frag);
+
+			*data = (u8 *) st->frag_data + frag->page_offset +
+				(abs_offset - st->stepped_offset);
+
+			return block_limit - abs_offset;
+		}
+
+		if (st->frag_data) {
+			kunmap_skb_frag(st->frag_data);
+			st->frag_data = NULL;
+		}
+
+		st->frag_idx++;
+		st->stepped_offset += frag->size;
+	}
+
+	if (st->cur_skb->next) {
+		st->cur_skb = st->cur_skb->next;
+		st->frag_idx = 0;
+		goto next_skb;
+	} else if (st->root_skb == st->cur_skb &&
+		   skb_shinfo(st->root_skb)->frag_list) {
+		st->cur_skb = skb_shinfo(st->root_skb)->frag_list;
+		goto next_skb;
+	}
+
+	return 0;
+}
+
+/**
+ * skb_abort_seq_read - Abort a sequential read of skb data
+ * @st: state variable
+ *
+ * Must be called if skb_seq_read() was not called until it
+ * returned 0.
+ */
+void skb_abort_seq_read(struct skb_seq_state *st)
+{
+	if (st->frag_data)
+		kunmap_skb_frag(st->frag_data);
+}
+
+#define TS_SKB_CB(state)	((struct skb_seq_state *) &((state)->cb))
+
+static unsigned int skb_ts_get_next_block(unsigned int offset, const u8 **text,
+					  struct ts_config *conf,
+					  struct ts_state *state)
+{
+	return skb_seq_read(offset, text, TS_SKB_CB(state));
+}
+
+static void skb_ts_finish(struct ts_config *conf, struct ts_state *state)
+{
+	skb_abort_seq_read(TS_SKB_CB(state));
+}
+
+/**
+ * skb_find_text - Find a text pattern in skb data
+ * @skb: the buffer to look in
+ * @from: search offset
+ * @to: search limit
+ * @config: textsearch configuration
+ * @state: uninitialized textsearch state variable
+ *
+ * Finds a pattern in the skb data according to the specified
+ * textsearch configuration. Use textsearch_next() to retrieve
+ * subsequent occurrences of the pattern. Returns the offset
+ * to the first occurrence or UINT_MAX if no match was found.
+ */
+unsigned int skb_find_text(struct sk_buff *skb, unsigned int from,
+			   unsigned int to, struct ts_config *config,
+			   struct ts_state *state)
+{
+	config->get_next_block = skb_ts_get_next_block;
+	config->finish = skb_ts_finish;
+
+	skb_prepare_seq_read(skb, from, to, TS_SKB_CB(state));
+
+	return textsearch_find(config, state);
+}
+
 void __init skb_init(void)
 {
 	skbuff_head_cache = kmem_cache_create("skbuff_head_cache",
@@ -1544,3 +1692,7 @@ EXPORT_SYMBOL(skb_queue_tail);
 EXPORT_SYMBOL(skb_unlink);
 EXPORT_SYMBOL(skb_append);
 EXPORT_SYMBOL(skb_split);
+EXPORT_SYMBOL(skb_prepare_seq_read);
+EXPORT_SYMBOL(skb_seq_read);
+EXPORT_SYMBOL(skb_abort_seq_read);
+EXPORT_SYMBOL(skb_find_text);
diff --git a/net/core/sock.c b/net/core/sock.c
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -118,6 +118,7 @@
 #include <linux/netdevice.h>
 #include <net/protocol.h>
 #include <linux/skbuff.h>
+#include <net/request_sock.h>
 #include <net/sock.h>
 #include <net/xfrm.h>
 #include <linux/ipsec.h>
@@ -205,13 +206,14 @@ int sock_setsockopt(struct socket *sock,
 	 */
 
 #ifdef SO_DONTLINGER		/* Compatibility item... */
-	switch (optname) {
-		case SO_DONTLINGER:
-			sock_reset_flag(sk, SOCK_LINGER);
-			return 0;
+	if (optname == SO_DONTLINGER) {
+		lock_sock(sk);
+		sock_reset_flag(sk, SOCK_LINGER);
+		release_sock(sk);
+		return 0;
 	}
-#endif	
-		
+#endif
+	
   	if(optlen<sizeof(int))
   		return(-EINVAL);
   	
@@ -621,7 +623,8 @@ lenout:
  *	@prot: struct proto associated with this new sock instance
  *	@zero_it: if we should zero the newly allocated sock
  */
-struct sock *sk_alloc(int family, int priority, struct proto *prot, int zero_it)
+struct sock *sk_alloc(int family, unsigned int __nocast priority,
+		      struct proto *prot, int zero_it)
 {
 	struct sock *sk = NULL;
 	kmem_cache_t *slab = prot->slab;
@@ -749,7 +752,8 @@ unsigned long sock_i_ino(struct sock *sk
 /*
  * Allocate a skb from the socket's send buffer.
  */
-struct sk_buff *sock_wmalloc(struct sock *sk, unsigned long size, int force, int priority)
+struct sk_buff *sock_wmalloc(struct sock *sk, unsigned long size, int force,
+			     unsigned int __nocast priority)
 {
 	if (force || atomic_read(&sk->sk_wmem_alloc) < sk->sk_sndbuf) {
 		struct sk_buff * skb = alloc_skb(size, priority);
@@ -764,7 +768,8 @@ struct sk_buff *sock_wmalloc(struct sock
 /*
  * Allocate a skb from the socket's receive buffer.
  */ 
-struct sk_buff *sock_rmalloc(struct sock *sk, unsigned long size, int force, int priority)
+struct sk_buff *sock_rmalloc(struct sock *sk, unsigned long size, int force,
+			     unsigned int __nocast priority)
 {
 	if (force || atomic_read(&sk->sk_rmem_alloc) < sk->sk_rcvbuf) {
 		struct sk_buff *skb = alloc_skb(size, priority);
@@ -779,7 +784,7 @@ struct sk_buff *sock_rmalloc(struct sock
 /* 
  * Allocate a memory block from the socket's option memory buffer.
  */ 
-void *sock_kmalloc(struct sock *sk, int size, int priority)
+void *sock_kmalloc(struct sock *sk, int size, unsigned int __nocast priority)
 {
 	if ((unsigned)size <= sysctl_optmem_max &&
 	    atomic_read(&sk->sk_omem_alloc) + size < sysctl_optmem_max) {
@@ -1363,6 +1368,7 @@ static LIST_HEAD(proto_list);
 
 int proto_register(struct proto *prot, int alloc_slab)
 {
+	char *request_sock_slab_name;
 	int rc = -ENOBUFS;
 
 	if (alloc_slab) {
@@ -1374,6 +1380,25 @@ int proto_register(struct proto *prot, i
 			       prot->name);
 			goto out;
 		}
+
+		if (prot->rsk_prot != NULL) {
+			static const char mask[] = "request_sock_%s";
+
+			request_sock_slab_name = kmalloc(strlen(prot->name) + sizeof(mask) - 1, GFP_KERNEL);
+			if (request_sock_slab_name == NULL)
+				goto out_free_sock_slab;
+
+			sprintf(request_sock_slab_name, mask, prot->name);
+			prot->rsk_prot->slab = kmem_cache_create(request_sock_slab_name,
+								 prot->rsk_prot->obj_size, 0,
+								 SLAB_HWCACHE_ALIGN, NULL, NULL);
+
+			if (prot->rsk_prot->slab == NULL) {
+				printk(KERN_CRIT "%s: Can't create request sock SLAB cache!\n",
+				       prot->name);
+				goto out_free_request_sock_slab_name;
+			}
+		}
 	}
 
 	write_lock(&proto_list_lock);
@@ -1382,6 +1407,12 @@ int proto_register(struct proto *prot, i
 	rc = 0;
 out:
 	return rc;
+out_free_request_sock_slab_name:
+	kfree(request_sock_slab_name);
+out_free_sock_slab:
+	kmem_cache_destroy(prot->slab);
+	prot->slab = NULL;
+	goto out;
 }
 
 EXPORT_SYMBOL(proto_register);
@@ -1395,6 +1426,14 @@ void proto_unregister(struct proto *prot
 		prot->slab = NULL;
 	}
 
+	if (prot->rsk_prot != NULL && prot->rsk_prot->slab != NULL) {
+		const char *name = kmem_cache_name(prot->rsk_prot->slab);
+
+		kmem_cache_destroy(prot->rsk_prot->slab);
+		kfree(name);
+		prot->rsk_prot->slab = NULL;
+	}
+
 	list_del(&prot->node);
 	write_unlock(&proto_list_lock);
 }
diff --git a/net/core/sysctl_net_core.c b/net/core/sysctl_net_core.c
--- a/net/core/sysctl_net_core.c
+++ b/net/core/sysctl_net_core.c
@@ -13,12 +13,8 @@
 #ifdef CONFIG_SYSCTL
 
 extern int netdev_max_backlog;
+extern int netdev_budget;
 extern int weight_p;
-extern int no_cong_thresh;
-extern int no_cong;
-extern int lo_cong;
-extern int mod_cong;
-extern int netdev_fastroute;
 extern int net_msg_cost;
 extern int net_msg_burst;
 
@@ -35,19 +31,6 @@ extern int sysctl_somaxconn;
 extern char sysctl_divert_version[];
 #endif /* CONFIG_NET_DIVERT */
 
-/*
- * This strdup() is used for creating copies of network 
- * device names to be handed over to sysctl.
- */
- 
-char *net_sysctl_strdup(const char *s)
-{
-	char *rv = kmalloc(strlen(s)+1, GFP_KERNEL);
-	if (rv)
-		strcpy(rv, s);
-	return rv;
-}
-
 ctl_table core_table[] = {
 #ifdef CONFIG_NET
 	{
@@ -99,38 +82,6 @@ ctl_table core_table[] = {
 		.proc_handler	= &proc_dointvec
 	},
 	{
-		.ctl_name	= NET_CORE_NO_CONG_THRESH,
-		.procname	= "no_cong_thresh",
-		.data		= &no_cong_thresh,
-		.maxlen		= sizeof(int),
-		.mode		= 0644,
-		.proc_handler	= &proc_dointvec
-	},
-	{
-		.ctl_name	= NET_CORE_NO_CONG,
-		.procname	= "no_cong",
-		.data		= &no_cong,
-		.maxlen		= sizeof(int),
-		.mode		= 0644,
-		.proc_handler	= &proc_dointvec
-	},
-	{
-		.ctl_name	= NET_CORE_LO_CONG,
-		.procname	= "lo_cong",
-		.data		= &lo_cong,
-		.maxlen		= sizeof(int),
-		.mode		= 0644,
-		.proc_handler	= &proc_dointvec
-	},
-	{
-		.ctl_name	= NET_CORE_MOD_CONG,
-		.procname	= "mod_cong",
-		.data		= &mod_cong,
-		.maxlen		= sizeof(int),
-		.mode		= 0644,
-		.proc_handler	= &proc_dointvec
-	},
-	{
 		.ctl_name	= NET_CORE_MSG_COST,
 		.procname	= "message_cost",
 		.data		= &net_msg_cost,
@@ -174,9 +125,15 @@ ctl_table core_table[] = {
 		.mode		= 0644,
 		.proc_handler	= &proc_dointvec
 	},
+	{
+		.ctl_name	= NET_CORE_BUDGET,
+		.procname	= "netdev_budget",
+		.data		= &netdev_budget,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec
+	},
 	{ .ctl_name = 0 }
 };
 
-EXPORT_SYMBOL(net_sysctl_strdup);
-
 #endif
diff --git a/net/core/utils.c b/net/core/utils.c
--- a/net/core/utils.c
+++ b/net/core/utils.c
@@ -23,10 +23,10 @@
 #include <linux/percpu.h>
 #include <linux/init.h>
 
+#include <asm/byteorder.h>
 #include <asm/system.h>
 #include <asm/uaccess.h>
 
-
 /*
   This is a maximally equidistributed combined Tausworthe generator
   based on code from GNU Scientific Library 1.5 (30 Jun 2004)
@@ -153,3 +153,38 @@ int net_ratelimit(void)
 EXPORT_SYMBOL(net_random);
 EXPORT_SYMBOL(net_ratelimit);
 EXPORT_SYMBOL(net_srandom);
+
+/*
+ * Convert an ASCII string to binary IP.
+ * This is outside of net/ipv4/ because various code that uses IP addresses
+ * is otherwise not dependent on the TCP/IP stack.
+ */
+
+__u32 in_aton(const char *str)
+{
+	unsigned long l;
+	unsigned int val;
+	int i;
+
+	l = 0;
+	for (i = 0; i < 4; i++)
+	{
+		l <<= 8;
+		if (*str != '\0')
+		{
+			val = 0;
+			while (*str != '\0' && *str != '.')
+			{
+				val *= 10;
+				val += *str - '0';
+				str++;
+			}
+			l |= val;
+			if (*str != '\0')
+				str++;
+		}
+	}
+	return(htonl(l));
+}
+
+EXPORT_SYMBOL(in_aton);
diff --git a/net/core/wireless.c b/net/core/wireless.c
--- a/net/core/wireless.c
+++ b/net/core/wireless.c
@@ -2,7 +2,7 @@
  * This file implement the Wireless Extensions APIs.
  *
  * Authors :	Jean Tourrilhes - HPL - <jt@hpl.hp.com>
- * Copyright (c) 1997-2004 Jean Tourrilhes, All Rights Reserved.
+ * Copyright (c) 1997-2005 Jean Tourrilhes, All Rights Reserved.
  *
  * (As all part of the Linux kernel, this file is GPL)
  */
@@ -187,6 +187,12 @@ static const struct iw_ioctl_description
 		.header_type	= IW_HEADER_TYPE_ADDR,
 		.flags		= IW_DESCR_FLAG_DUMP,
 	},
+	[SIOCSIWMLME	- SIOCIWFIRST] = {
+		.header_type	= IW_HEADER_TYPE_POINT,
+		.token_size	= 1,
+		.min_tokens	= sizeof(struct iw_mlme),
+		.max_tokens	= sizeof(struct iw_mlme),
+	},
 	[SIOCGIWAPLIST	- SIOCIWFIRST] = {
 		.header_type	= IW_HEADER_TYPE_POINT,
 		.token_size	= sizeof(struct sockaddr) +
@@ -195,7 +201,10 @@ static const struct iw_ioctl_description
 		.flags		= IW_DESCR_FLAG_NOMAX,
 	},
 	[SIOCSIWSCAN	- SIOCIWFIRST] = {
-		.header_type	= IW_HEADER_TYPE_PARAM,
+		.header_type	= IW_HEADER_TYPE_POINT,
+		.token_size	= 1,
+		.min_tokens	= 0,
+		.max_tokens	= sizeof(struct iw_scan_req),
 	},
 	[SIOCGIWSCAN	- SIOCIWFIRST] = {
 		.header_type	= IW_HEADER_TYPE_POINT,
@@ -273,6 +282,42 @@ static const struct iw_ioctl_description
 	[SIOCGIWPOWER	- SIOCIWFIRST] = {
 		.header_type	= IW_HEADER_TYPE_PARAM,
 	},
+	[SIOCSIWGENIE	- SIOCIWFIRST] = {
+		.header_type	= IW_HEADER_TYPE_POINT,
+		.token_size	= 1,
+		.max_tokens	= IW_GENERIC_IE_MAX,
+	},
+	[SIOCGIWGENIE	- SIOCIWFIRST] = {
+		.header_type	= IW_HEADER_TYPE_POINT,
+		.token_size	= 1,
+		.max_tokens	= IW_GENERIC_IE_MAX,
+	},
+	[SIOCSIWAUTH	- SIOCIWFIRST] = {
+		.header_type	= IW_HEADER_TYPE_PARAM,
+	},
+	[SIOCGIWAUTH	- SIOCIWFIRST] = {
+		.header_type	= IW_HEADER_TYPE_PARAM,
+	},
+	[SIOCSIWENCODEEXT - SIOCIWFIRST] = {
+		.header_type	= IW_HEADER_TYPE_POINT,
+		.token_size	= 1,
+		.min_tokens	= sizeof(struct iw_encode_ext),
+		.max_tokens	= sizeof(struct iw_encode_ext) +
+				  IW_ENCODING_TOKEN_MAX,
+	},
+	[SIOCGIWENCODEEXT - SIOCIWFIRST] = {
+		.header_type	= IW_HEADER_TYPE_POINT,
+		.token_size	= 1,
+		.min_tokens	= sizeof(struct iw_encode_ext),
+		.max_tokens	= sizeof(struct iw_encode_ext) +
+				  IW_ENCODING_TOKEN_MAX,
+	},
+	[SIOCSIWPMKSA - SIOCIWFIRST] = {
+		.header_type	= IW_HEADER_TYPE_POINT,
+		.token_size	= 1,
+		.min_tokens	= sizeof(struct iw_pmksa),
+		.max_tokens	= sizeof(struct iw_pmksa),
+	},
 };
 static const int standard_ioctl_num = (sizeof(standard_ioctl) /
 				       sizeof(struct iw_ioctl_description));
@@ -299,6 +344,31 @@ static const struct iw_ioctl_description
 	[IWEVEXPIRED	- IWEVFIRST] = {
 		.header_type	= IW_HEADER_TYPE_ADDR, 
 	},
+	[IWEVGENIE	- IWEVFIRST] = {
+		.header_type	= IW_HEADER_TYPE_POINT,
+		.token_size	= 1,
+		.max_tokens	= IW_GENERIC_IE_MAX,
+	},
+	[IWEVMICHAELMICFAILURE	- IWEVFIRST] = {
+		.header_type	= IW_HEADER_TYPE_POINT, 
+		.token_size	= 1,
+		.max_tokens	= sizeof(struct iw_michaelmicfailure),
+	},
+	[IWEVASSOCREQIE	- IWEVFIRST] = {
+		.header_type	= IW_HEADER_TYPE_POINT,
+		.token_size	= 1,
+		.max_tokens	= IW_GENERIC_IE_MAX,
+	},
+	[IWEVASSOCRESPIE	- IWEVFIRST] = {
+		.header_type	= IW_HEADER_TYPE_POINT,
+		.token_size	= 1,
+		.max_tokens	= IW_GENERIC_IE_MAX,
+	},
+	[IWEVPMKIDCAND	- IWEVFIRST] = {
+		.header_type	= IW_HEADER_TYPE_POINT,
+		.token_size	= 1,
+		.max_tokens	= sizeof(struct iw_pmkid_cand),
+	},
 };
 static const int standard_event_num = (sizeof(standard_event) /
 				       sizeof(struct iw_ioctl_description));
@@ -1032,6 +1102,7 @@ static inline int rtnetlink_fill_iwinfo(
 	nlh = NLMSG_PUT(skb, 0, 0, type, sizeof(*r));
 	r = NLMSG_DATA(nlh);
 	r->ifi_family = AF_UNSPEC;
+	r->__ifi_pad = 0;
 	r->ifi_type = dev->type;
 	r->ifi_index = dev->ifindex;
 	r->ifi_flags = dev->flags;
diff --git a/net/decnet/Kconfig b/net/decnet/Kconfig
--- a/net/decnet/Kconfig
+++ b/net/decnet/Kconfig
@@ -1,6 +1,29 @@
 #
 # DECnet configuration
 #
+config DECNET
+	tristate "DECnet Support"
+	---help---
+	  The DECnet networking protocol was used in many products made by
+	  Digital (now Compaq).  It provides reliable stream and sequenced
+	  packet communications over which run a variety of services similar
+	  to those which run over TCP/IP.
+
+	  To find some tools to use with the kernel layer support, please
+	  look at Patrick Caulfield's web site:
+	  <http://linux-decnet.sourceforge.net/>.
+
+	  More detailed documentation is available in
+	  <file:Documentation/networking/decnet.txt>.
+
+	  Be sure to say Y to "/proc file system support" and "Sysctl support"
+	  below when using DECnet, since you will need sysctl support to aid
+	  in configuration at run time.
+
+	  The DECnet code 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 decnet.
+
 config DECNET_ROUTER
 	bool "DECnet: router support (EXPERIMENTAL)"
 	depends on DECNET && EXPERIMENTAL
diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c
--- a/net/decnet/af_decnet.c
+++ b/net/decnet/af_decnet.c
@@ -536,7 +536,7 @@ static void dn_keepalive(struct sock *sk
 	 * we are double checking that we are not sending too
 	 * many of these keepalive frames.
 	 */
-	if (skb_queue_len(&scp->other_xmit_queue) == 0)
+	if (skb_queue_empty(&scp->other_xmit_queue))
 		dn_nsp_send_link(sk, DN_NOCHANGE, 0);
 }
 
@@ -1191,7 +1191,7 @@ static unsigned int dn_poll(struct file 
 	struct dn_scp *scp = DN_SK(sk);
 	int mask = datagram_poll(file, sock, wait);
 
-	if (skb_queue_len(&scp->other_receive_queue))
+	if (!skb_queue_empty(&scp->other_receive_queue))
 		mask |= POLLRDBAND;
 
 	return mask;
@@ -1214,7 +1214,7 @@ static int dn_ioctl(struct socket *sock,
 
 	case SIOCATMARK:
 		lock_sock(sk);
-		val = (skb_queue_len(&scp->other_receive_queue) != 0);
+		val = !skb_queue_empty(&scp->other_receive_queue);
 		if (scp->state != DN_RUN)
 			val = -ENOTCONN;
 		release_sock(sk);
@@ -1630,7 +1630,7 @@ static int dn_data_ready(struct sock *sk
 	int len = 0;
 
 	if (flags & MSG_OOB)
-		return skb_queue_len(q) ? 1 : 0;
+		return !skb_queue_empty(q) ? 1 : 0;
 
 	while(skb != (struct sk_buff *)q) {
 		struct dn_skb_cb *cb = DN_SKB_CB(skb);
@@ -1707,7 +1707,7 @@ static int dn_recvmsg(struct kiocb *iocb
 		if (sk->sk_err)
 			goto out;
 
-		if (skb_queue_len(&scp->other_receive_queue)) {
+		if (!skb_queue_empty(&scp->other_receive_queue)) {
 			if (!(flags & MSG_OOB)) {
 				msg->msg_flags |= MSG_OOB;
 				if (!scp->other_report) {
@@ -1876,15 +1876,6 @@ static inline unsigned int dn_current_ms
 	return mss_now;
 }
 
-static int dn_error(struct sock *sk, int flags, int err)
-{
-	if (err == -EPIPE)
-		err = sock_error(sk) ? : -EPIPE;
-	if (err == -EPIPE && !(flags & MSG_NOSIGNAL))
-		send_sig(SIGPIPE, current, 0);
-	return err;
-}
-
 static int dn_sendmsg(struct kiocb *iocb, struct socket *sock,
 	   struct msghdr *msg, size_t size)
 {
@@ -2045,7 +2036,7 @@ out:
 	return sent ? sent : err;
 
 out_err:
-	err = dn_error(sk, flags, err);
+	err = sk_stream_error(sk, flags, err);
 	release_sock(sk);
 	return err;
 }
diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c
--- a/net/decnet/dn_dev.c
+++ b/net/decnet/dn_dev.c
@@ -716,13 +716,13 @@ static int dn_dev_rtm_newaddr(struct sk_
 }
 
 static int dn_dev_fill_ifaddr(struct sk_buff *skb, struct dn_ifaddr *ifa,
-				u32 pid, u32 seq, int event)
+				u32 pid, u32 seq, int event, unsigned int flags)
 {
 	struct ifaddrmsg *ifm;
 	struct nlmsghdr *nlh;
 	unsigned char *b = skb->tail;
 
-	nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(*ifm));
+	nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*ifm), flags);
 	ifm = NLMSG_DATA(nlh);
 
 	ifm->ifa_family = AF_DECnet;
@@ -755,7 +755,7 @@ static void rtmsg_ifa(int event, struct 
 		netlink_set_err(rtnl, 0, RTMGRP_DECnet_IFADDR, ENOBUFS);
 		return;
 	}
-	if (dn_dev_fill_ifaddr(skb, ifa, 0, 0, event) < 0) {
+	if (dn_dev_fill_ifaddr(skb, ifa, 0, 0, event, 0) < 0) {
 		kfree_skb(skb);
 		netlink_set_err(rtnl, 0, RTMGRP_DECnet_IFADDR, EINVAL);
 		return;
@@ -790,7 +790,8 @@ static int dn_dev_dump_ifaddr(struct sk_
 			if (dn_dev_fill_ifaddr(skb, ifa,
 					       NETLINK_CB(cb->skb).pid,
 					       cb->nlh->nlmsg_seq,
-					       RTM_NEWADDR) <= 0)
+					       RTM_NEWADDR,
+					       NLM_F_MULTI) <= 0)
 				goto done;
 		}
 	}
diff --git a/net/decnet/dn_fib.c b/net/decnet/dn_fib.c
--- a/net/decnet/dn_fib.c
+++ b/net/decnet/dn_fib.c
@@ -551,7 +551,8 @@ int dn_fib_dump(struct sk_buff *skb, str
 		if (t < s_t)
 			continue;
 		if (t > s_t)
-			memset(&cb->args[1], 0, sizeof(cb->args)-sizeof(int));
+			memset(&cb->args[1], 0,
+			       sizeof(cb->args) - sizeof(cb->args[0]));
 		tb = dn_fib_get_table(t, 0);
 		if (tb == NULL)
 			continue;
diff --git a/net/decnet/dn_neigh.c b/net/decnet/dn_neigh.c
--- a/net/decnet/dn_neigh.c
+++ b/net/decnet/dn_neigh.c
@@ -101,7 +101,6 @@ struct neigh_table dn_neigh_table = {
 	.id =				"dn_neigh_cache",
 	.parms ={
 		.tbl =			&dn_neigh_table,
-		.entries =		0,
 		.base_reachable_time =	30 * HZ,
 		.retrans_time =	1 * HZ,
 		.gc_staletime =	60 * HZ,
@@ -149,12 +148,12 @@ static int dn_neigh_construct(struct nei
 
 	__neigh_parms_put(neigh->parms);
 	neigh->parms = neigh_parms_clone(parms);
-	rcu_read_unlock();
 
 	if (dn_db->use_long)
 		neigh->ops = &dn_long_ops;
 	else
 		neigh->ops = &dn_short_ops;
+	rcu_read_unlock();
 
 	if (dn->flags & DN_NDFLAG_P3)
 		neigh->ops = &dn_phase3_ops;
diff --git a/net/decnet/dn_nsp_out.c b/net/decnet/dn_nsp_out.c
--- a/net/decnet/dn_nsp_out.c
+++ b/net/decnet/dn_nsp_out.c
@@ -342,7 +342,8 @@ int dn_nsp_xmit_timeout(struct sock *sk)
 
 	dn_nsp_output(sk);
 
-	if (skb_queue_len(&scp->data_xmit_queue) || skb_queue_len(&scp->other_xmit_queue))
+	if (!skb_queue_empty(&scp->data_xmit_queue) ||
+	    !skb_queue_empty(&scp->other_xmit_queue))
 		scp->persist = dn_nsp_persist(sk);
 
 	return 0;
diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c
--- a/net/decnet/dn_route.c
+++ b/net/decnet/dn_route.c
@@ -1465,7 +1465,8 @@ int dn_route_input(struct sk_buff *skb)
 	return dn_route_input_slow(skb);
 }
 
-static int dn_rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq, int event, int nowait)
+static int dn_rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq,
+			   int event, int nowait, unsigned int flags)
 {
 	struct dn_route *rt = (struct dn_route *)skb->dst;
 	struct rtmsg *r;
@@ -1473,9 +1474,8 @@ static int dn_rt_fill_info(struct sk_buf
 	unsigned char *b = skb->tail;
 	struct rta_cacheinfo ci;
 
-	nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(*r));
+	nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*r), flags);
 	r = NLMSG_DATA(nlh);
-	nlh->nlmsg_flags = (nowait && pid) ? NLM_F_MULTI : 0;
 	r->rtm_family = AF_DECnet;
 	r->rtm_dst_len = 16;
 	r->rtm_src_len = 0;
@@ -1596,7 +1596,7 @@ int dn_cache_getroute(struct sk_buff *in
 
 	NETLINK_CB(skb).dst_pid = NETLINK_CB(in_skb).pid;
 
-	err = dn_rt_fill_info(skb, NETLINK_CB(in_skb).pid, nlh->nlmsg_seq, RTM_NEWROUTE, 0);
+	err = dn_rt_fill_info(skb, NETLINK_CB(in_skb).pid, nlh->nlmsg_seq, RTM_NEWROUTE, 0, 0);
 
 	if (err == 0)
 		goto out_free;
@@ -1644,7 +1644,8 @@ int dn_cache_dump(struct sk_buff *skb, s
 				continue;
 			skb->dst = dst_clone(&rt->u.dst);
 			if (dn_rt_fill_info(skb, NETLINK_CB(cb->skb).pid,
-					cb->nlh->nlmsg_seq, RTM_NEWROUTE, 1) <= 0) {
+					cb->nlh->nlmsg_seq, RTM_NEWROUTE, 
+					1, NLM_F_MULTI) <= 0) {
 				dst_release(xchg(&skb->dst, NULL));
 				rcu_read_unlock_bh();
 				goto done;
diff --git a/net/decnet/dn_rules.c b/net/decnet/dn_rules.c
--- a/net/decnet/dn_rules.c
+++ b/net/decnet/dn_rules.c
@@ -342,14 +342,15 @@ static struct notifier_block dn_fib_rule
 	.notifier_call =	dn_fib_rules_event,
 };
 
-static int dn_fib_fill_rule(struct sk_buff *skb, struct dn_fib_rule *r, struct netlink_callback *cb)
+static int dn_fib_fill_rule(struct sk_buff *skb, struct dn_fib_rule *r,
+			    struct netlink_callback *cb, unsigned int flags)
 {
 	struct rtmsg *rtm;
 	struct nlmsghdr *nlh;
 	unsigned char *b = skb->tail;
 
 
-	nlh = NLMSG_PUT(skb, NETLINK_CREDS(cb->skb)->pid, cb->nlh->nlmsg_seq, RTM_NEWRULE, sizeof(*rtm));
+	nlh = NLMSG_NEW_ANSWER(skb, cb, RTM_NEWRULE, sizeof(*rtm), flags);
 	rtm = NLMSG_DATA(nlh);
 	rtm->rtm_family = AF_DECnet;
 	rtm->rtm_dst_len = r->r_dst_len;
@@ -394,7 +395,7 @@ int dn_fib_dump_rules(struct sk_buff *sk
 	for(r = dn_fib_rules, idx = 0; r; r = r->r_next, idx++) {
 		if (idx < s_idx)
 			continue;
-		if (dn_fib_fill_rule(skb, r, cb) < 0)
+		if (dn_fib_fill_rule(skb, r, cb, NLM_F_MULTI) < 0)
 			break;
 	}
 	read_unlock(&dn_fib_rules_lock);
diff --git a/net/decnet/dn_table.c b/net/decnet/dn_table.c
--- a/net/decnet/dn_table.c
+++ b/net/decnet/dn_table.c
@@ -270,13 +270,13 @@ static int dn_fib_nh_match(struct rtmsg 
 
 static int dn_fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
                         u8 tb_id, u8 type, u8 scope, void *dst, int dst_len,
-                        struct dn_fib_info *fi)
+                        struct dn_fib_info *fi, unsigned int flags)
 {
         struct rtmsg *rtm;
         struct nlmsghdr *nlh;
         unsigned char *b = skb->tail;
 
-        nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(*rtm));
+        nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*rtm), flags);
         rtm = NLMSG_DATA(nlh);
         rtm->rtm_family = AF_DECnet;
         rtm->rtm_dst_len = dst_len;
@@ -345,7 +345,7 @@ static void dn_rtmsg_fib(int event, stru
 
         if (dn_fib_dump_info(skb, pid, nlh->nlmsg_seq, event, tb_id, 
                                 f->fn_type, f->fn_scope, &f->fn_key, z, 
-                                DN_FIB_INFO(f)) < 0) {
+                                DN_FIB_INFO(f), 0) < 0) {
                 kfree_skb(skb);
                 return;
         }
@@ -377,7 +377,7 @@ static __inline__ int dn_hash_dump_bucke
 				tb->n, 
 				(f->fn_state & DN_S_ZOMBIE) ? 0 : f->fn_type,
 				f->fn_scope, &f->fn_key, dz->dz_order, 
-				f->fn_info) < 0) {
+				f->fn_info, NLM_F_MULTI) < 0) {
 			cb->args[3] = i;
 			return -1;
 		}
diff --git a/net/econet/Kconfig b/net/econet/Kconfig
new file mode 100644
--- /dev/null
+++ b/net/econet/Kconfig
@@ -0,0 +1,36 @@
+#
+# Acorn Econet/AUN protocols 
+#
+
+config ECONET
+	tristate "Acorn Econet/AUN protocols (EXPERIMENTAL)"
+	depends on EXPERIMENTAL && INET
+	---help---
+	  Econet is a fairly old and slow networking protocol mainly used by
+	  Acorn computers to access file and print servers. It uses native
+	  Econet network cards. AUN is an implementation of the higher level
+	  parts of Econet that runs over ordinary Ethernet connections, on
+	  top of the UDP packet protocol, which in turn runs on top of the
+	  Internet protocol IP.
+
+	  If you say Y here, you can choose with the next two options whether
+	  to send Econet/AUN traffic over a UDP Ethernet connection or over
+	  a native Econet network card.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called econet.
+
+config ECONET_AUNUDP
+	bool "AUN over UDP"
+	depends on ECONET
+	help
+	  Say Y here if you want to send Econet/AUN traffic over a UDP
+	  connection (UDP is a packet based protocol that runs on top of the
+	  Internet protocol IP) using an ordinary Ethernet network card.
+
+config ECONET_NATIVE
+	bool "Native Econet"
+	depends on ECONET
+	help
+	  Say Y here if you have a native Econet network card installed in
+	  your computer.
diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c
--- a/net/ethernet/eth.c
+++ b/net/ethernet/eth.c
@@ -92,10 +92,9 @@ int eth_header(struct sk_buff *skb, stru
 	 *	Set the source hardware address. 
 	 */
 	 
-	if(saddr)
-		memcpy(eth->h_source,saddr,dev->addr_len);
-	else
-		memcpy(eth->h_source,dev->dev_addr,dev->addr_len);
+	if(!saddr)
+		saddr = dev->dev_addr;
+	memcpy(eth->h_source,saddr,dev->addr_len);
 
 	/*
 	 *	Anyway, the loopback-device should never use this function... 
@@ -156,7 +155,7 @@ int eth_rebuild_header(struct sk_buff *s
  *	This is normal practice and works for any 'now in use' protocol.
  */
  
-unsigned short eth_type_trans(struct sk_buff *skb, struct net_device *dev)
+__be16 eth_type_trans(struct sk_buff *skb, struct net_device *dev)
 {
 	struct ethhdr *eth;
 	unsigned char *rawp;
diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig
--- a/net/ipv4/Kconfig
+++ b/net/ipv4/Kconfig
@@ -3,7 +3,6 @@
 #
 config IP_MULTICAST
 	bool "IP: multicasting"
-	depends on INET
 	help
 	  This is code for addressing several networked computers at once,
 	  enlarging your kernel by about 2 KB. You need multicasting if you
@@ -17,7 +16,6 @@ config IP_MULTICAST
 
 config IP_ADVANCED_ROUTER
 	bool "IP: advanced router"
-	depends on INET
 	---help---
 	  If you intend to run your Linux box mostly as a router, i.e. as a
 	  computer that forwards and redistributes network packets, say Y; you
@@ -53,6 +51,40 @@ config IP_ADVANCED_ROUTER
 
 	  If unsure, say N here.
 
+choice 
+	prompt "Choose IP: FIB lookup algorithm (choose FIB_HASH if unsure)"
+	depends on IP_ADVANCED_ROUTER
+	default ASK_IP_FIB_HASH
+
+config ASK_IP_FIB_HASH
+	bool "FIB_HASH"
+	---help---
+	Current FIB is very proven and good enough for most users.
+
+config IP_FIB_TRIE
+	bool "FIB_TRIE"
+	---help---
+	Use new experimental LC-trie as FIB lookup algoritm. 
+        This improves lookup performance if you have a large
+	number of routes.
+
+	LC-trie is a longest matching prefix lookup algorithm which
+	performs better than FIB_HASH for large routing tables.
+	But, it consumes more memory and is more complex.
+	
+	LC-trie is described in:
+	
+ 	IP-address lookup using LC-tries. Stefan Nilsson and Gunnar Karlsson
+ 	IEEE Journal on Selected Areas in Communications, 17(6):1083-1092, June 1999
+	An experimental study of compression methods for dynamic tries
+ 	Stefan Nilsson and Matti Tikkanen. Algorithmica, 33(1):19-33, 2002.
+ 	http://www.nada.kth.se/~snilsson/public/papers/dyntrie2/
+       
+endchoice
+
+config IP_FIB_HASH
+	def_bool ASK_IP_FIB_HASH || !IP_ADVANCED_ROUTER
+
 config IP_MULTIPLE_TABLES
 	bool "IP: policy routing"
 	depends on IP_ADVANCED_ROUTER
@@ -92,7 +124,7 @@ config IP_ROUTE_MULTIPATH
 
 config IP_ROUTE_MULTIPATH_CACHED
 	bool "IP: equal cost multipath with caching support (EXPERIMENTAL)"
-	depends on: IP_ROUTE_MULTIPATH
+	depends on IP_ROUTE_MULTIPATH
 	help
 	  Normally, equal cost multipath routing is not supported by the
 	  routing cache. If you say Y here, alternative routes are cached
@@ -145,7 +177,6 @@ config IP_ROUTE_VERBOSE
 
 config IP_PNP
 	bool "IP: kernel level autoconfiguration"
-	depends on INET
 	help
 	  This enables automatic configuration of IP addresses of devices and
 	  of the routing table during kernel boot, based on either information
@@ -204,8 +235,6 @@ config IP_PNP_RARP
 #   bool '    IP: ARP support' CONFIG_IP_PNP_ARP		
 config NET_IPIP
 	tristate "IP: tunneling"
-	depends on INET
-	select INET_TUNNEL
 	---help---
 	  Tunneling means encapsulating data of one protocol type within
 	  another protocol and sending it over a channel that understands the
@@ -222,8 +251,6 @@ config NET_IPIP
 
 config NET_IPGRE
 	tristate "IP: GRE tunnels over IP"
-	depends on INET
-	select XFRM
 	help
 	  Tunneling means encapsulating data of one protocol type within
 	  another protocol and sending it over a channel that understands the
@@ -281,7 +308,7 @@ config IP_PIMSM_V2
 
 config ARPD
 	bool "IP: ARP daemon support (EXPERIMENTAL)"
-	depends on INET && EXPERIMENTAL
+	depends on EXPERIMENTAL
 	---help---
 	  Normally, the kernel maintains an internal cache which maps IP
 	  addresses to hardware addresses on the local network, so that
@@ -306,7 +333,6 @@ config ARPD
 
 config SYN_COOKIES
 	bool "IP: TCP syncookie support (disabled per default)"
-	depends on INET
 	---help---
 	  Normal TCP/IP networking is open to an attack known as "SYN
 	  flooding". This denial-of-service attack prevents legitimate remote
@@ -343,7 +369,6 @@ config SYN_COOKIES
 
 config INET_AH
 	tristate "IP: AH transformation"
-	depends on INET
 	select XFRM
 	select CRYPTO
 	select CRYPTO_HMAC
@@ -356,7 +381,6 @@ config INET_AH
 
 config INET_ESP
 	tristate "IP: ESP transformation"
-	depends on INET
 	select XFRM
 	select CRYPTO
 	select CRYPTO_HMAC
@@ -370,7 +394,6 @@ config INET_ESP
 
 config INET_IPCOMP
 	tristate "IP: IPComp transformation"
-	depends on INET
 	select XFRM
 	select INET_TUNNEL
 	select CRYPTO
@@ -383,7 +406,6 @@ config INET_IPCOMP
 
 config INET_TUNNEL
 	tristate "IP: tunnel transformation"
-	depends on INET
 	select XFRM
 	---help---
 	  Support for generic IP tunnel transformation, which is required by
@@ -393,7 +415,6 @@ config INET_TUNNEL
 
 config IP_TCPDIAG
 	tristate "IP: TCP socket monitoring interface"
-	depends on INET
 	default y
 	---help---
 	  Support for TCP socket monitoring interface used by native Linux
@@ -407,5 +428,108 @@ config IP_TCPDIAG
 config IP_TCPDIAG_IPV6
 	def_bool (IP_TCPDIAG=y && IPV6=y) || (IP_TCPDIAG=m && IPV6)
 
+config TCP_CONG_ADVANCED
+	bool "TCP: advanced congestion control"
+	---help---
+	  Support for selection of various TCP congestion control
+	  modules.
+
+	  Nearly all users can safely say no here, and a safe default
+	  selection will be made (BIC-TCP with new Reno as a fallback).
+
+	  If unsure, say N.
+
+# TCP Reno is builtin (required as fallback)
+menu "TCP congestion control"
+	depends on TCP_CONG_ADVANCED
+
+config TCP_CONG_BIC
+	tristate "Binary Increase Congestion (BIC) control"
+	default y
+	---help---
+	BIC-TCP is a sender-side only change that ensures a linear RTT
+	fairness under large windows while offering both scalability and
+	bounded TCP-friendliness. The protocol combines two schemes
+	called additive increase and binary search increase. When the
+	congestion window is large, additive increase with a large
+	increment ensures linear RTT fairness as well as good
+	scalability. Under small congestion windows, binary search
+	increase provides TCP friendliness.
+	See http://www.csc.ncsu.edu/faculty/rhee/export/bitcp/
+
+config TCP_CONG_WESTWOOD
+	tristate "TCP Westwood+"
+	default m
+	---help---
+	TCP Westwood+ is a sender-side only modification of the TCP Reno
+	protocol stack that optimizes the performance of TCP congestion
+	control. It is based on end-to-end bandwidth estimation to set
+	congestion window and slow start threshold after a congestion
+	episode. Using this estimation, TCP Westwood+ adaptively sets a
+	slow start threshold and a congestion window which takes into
+	account the bandwidth used  at the time congestion is experienced.
+	TCP Westwood+ significantly increases fairness wrt TCP Reno in
+	wired networks and throughput over wireless links.
+
+config TCP_CONG_HTCP
+        tristate "H-TCP"
+        default m
+	---help---
+	H-TCP is a send-side only modifications of the TCP Reno
+	protocol stack that optimizes the performance of TCP
+	congestion control for high speed network links. It uses a
+	modeswitch to change the alpha and beta parameters of TCP Reno
+	based on network conditions and in a way so as to be fair with
+	other Reno and H-TCP flows.
+
+config TCP_CONG_HSTCP
+	tristate "High Speed TCP"
+	depends on EXPERIMENTAL
+	default n
+	---help---
+	Sally Floyd's High Speed TCP (RFC 3649) congestion control.
+	A modification to TCP's congestion control mechanism for use
+	with large congestion windows. A table indicates how much to
+	increase the congestion window by when an ACK is received.
+ 	For more detail	see http://www.icir.org/floyd/hstcp.html
+
+config TCP_CONG_HYBLA
+	tristate "TCP-Hybla congestion control algorithm"
+	depends on EXPERIMENTAL
+	default n
+	---help---
+	TCP-Hybla is a sender-side only change that eliminates penalization of
+	long-RTT, large-bandwidth connections, like when satellite legs are
+	involved, expecially when sharing a common bottleneck with normal
+	terrestrial connections.
+
+config TCP_CONG_VEGAS
+	tristate "TCP Vegas"
+	depends on EXPERIMENTAL
+	default n
+	---help---
+	TCP Vegas is a sender-side only change to TCP that anticipates
+	the onset of congestion by estimating the bandwidth. TCP Vegas
+	adjusts the sending rate by modifying the congestion
+	window. TCP Vegas should provide less packet loss, but it is
+	not as aggressive as TCP Reno.
+
+config TCP_CONG_SCALABLE
+	tristate "Scalable TCP"
+	depends on EXPERIMENTAL
+	default n
+	---help---
+	Scalable TCP is a sender-side only change to TCP which uses a
+	MIMD congestion control algorithm which has some nice scaling
+	properties, though is known to have fairness issues.
+	See http://www-lce.eng.cam.ac.uk/~ctk21/scalable/
+
+endmenu
+
+config TCP_CONG_BIC
+	tristate
+	depends on !TCP_CONG_ADVANCED
+	default y
+
 source "net/ipv4/ipvs/Kconfig"
 
diff --git a/net/ipv4/Makefile b/net/ipv4/Makefile
--- a/net/ipv4/Makefile
+++ b/net/ipv4/Makefile
@@ -2,13 +2,16 @@
 # Makefile for the Linux TCP/IP (INET) layer.
 #
 
-obj-y     := utils.o route.o inetpeer.o protocol.o \
+obj-y     := route.o inetpeer.o protocol.o \
 	     ip_input.o ip_fragment.o ip_forward.o ip_options.o \
 	     ip_output.o ip_sockglue.o \
-	     tcp.o tcp_input.o tcp_output.o tcp_timer.o tcp_ipv4.o tcp_minisocks.o \
+	     tcp.o tcp_input.o tcp_output.o tcp_timer.o tcp_ipv4.o \
+	     tcp_minisocks.o tcp_cong.o \
 	     datagram.o raw.o udp.o arp.o icmp.o devinet.o af_inet.o igmp.o \
-	     sysctl_net_ipv4.o fib_frontend.o fib_semantics.o fib_hash.o
+	     sysctl_net_ipv4.o fib_frontend.o fib_semantics.o
 
+obj-$(CONFIG_IP_FIB_HASH) += fib_hash.o
+obj-$(CONFIG_IP_FIB_TRIE) += fib_trie.o
 obj-$(CONFIG_PROC_FS) += proc.o
 obj-$(CONFIG_IP_MULTIPLE_TABLES) += fib_rules.o
 obj-$(CONFIG_IP_MROUTE) += ipmr.o
@@ -28,6 +31,13 @@ obj-$(CONFIG_NETFILTER)	+= netfilter/
 obj-$(CONFIG_IP_VS) += ipvs/
 obj-$(CONFIG_IP_TCPDIAG) += tcp_diag.o 
 obj-$(CONFIG_IP_ROUTE_MULTIPATH_CACHED) += multipath.o
+obj-$(CONFIG_TCP_CONG_BIC) += tcp_bic.o
+obj-$(CONFIG_TCP_CONG_WESTWOOD) += tcp_westwood.o
+obj-$(CONFIG_TCP_CONG_HSTCP) += tcp_highspeed.o
+obj-$(CONFIG_TCP_CONG_HYBLA) += tcp_hybla.o
+obj-$(CONFIG_TCP_CONG_HTCP) += tcp_htcp.o
+obj-$(CONFIG_TCP_CONG_VEGAS) += tcp_vegas.o
+obj-$(CONFIG_TCP_CONG_SCALABLE) += tcp_scalable.o
 
 obj-$(CONFIG_XFRM) += xfrm4_policy.o xfrm4_state.o xfrm4_input.o \
 		      xfrm4_output.o
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -1009,6 +1009,15 @@ static int __init init_ipv4_mibs(void)
 static int ipv4_proc_init(void);
 extern void ipfrag_init(void);
 
+/*
+ *	IP protocol layer initialiser
+ */
+
+static struct packet_type ip_packet_type = {
+	.type = __constant_htons(ETH_P_IP),
+	.func = ip_rcv,
+};
+
 static int __init inet_init(void)
 {
 	struct sk_buff *dummy_skb;
@@ -1102,6 +1111,8 @@ static int __init inet_init(void)
 
 	ipfrag_init();
 
+	dev_add_pack(&ip_packet_type);
+
 	rc = 0;
 out:
 	return rc;
@@ -1119,6 +1130,10 @@ module_init(inet_init);
 #ifdef CONFIG_PROC_FS
 extern int  fib_proc_init(void);
 extern void fib_proc_exit(void);
+#ifdef CONFIG_IP_FIB_TRIE
+extern int  fib_stat_proc_init(void);
+extern void fib_stat_proc_exit(void);
+#endif
 extern int  ip_misc_proc_init(void);
 extern int  raw_proc_init(void);
 extern void raw_proc_exit(void);
@@ -1139,11 +1154,19 @@ static int __init ipv4_proc_init(void)
 		goto out_udp;
 	if (fib_proc_init())
 		goto out_fib;
+#ifdef CONFIG_IP_FIB_TRIE
+         if (fib_stat_proc_init())
+                 goto out_fib_stat;
+#endif
 	if (ip_misc_proc_init())
 		goto out_misc;
 out:
 	return rc;
 out_misc:
+#ifdef CONFIG_IP_FIB_TRIE
+ 	fib_stat_proc_exit();
+out_fib_stat:
+#endif
 	fib_proc_exit();
 out_fib:
 	udp4_proc_exit();
diff --git a/net/ipv4/ah4.c b/net/ipv4/ah4.c
--- a/net/ipv4/ah4.c
+++ b/net/ipv4/ah4.c
@@ -200,7 +200,7 @@ static void ah4_err(struct sk_buff *skb,
 	xfrm_state_put(x);
 }
 
-static int ah_init_state(struct xfrm_state *x, void *args)
+static int ah_init_state(struct xfrm_state *x)
 {
 	struct ah_data *ahp = NULL;
 	struct xfrm_algo_desc *aalg_desc;
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -1030,14 +1030,13 @@ static struct notifier_block ip_netdev_n
 };
 
 static int inet_fill_ifaddr(struct sk_buff *skb, struct in_ifaddr *ifa,
-			    u32 pid, u32 seq, int event)
+			    u32 pid, u32 seq, int event, unsigned int flags)
 {
 	struct ifaddrmsg *ifm;
 	struct nlmsghdr  *nlh;
 	unsigned char	 *b = skb->tail;
 
-	nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(*ifm));
-	if (pid) nlh->nlmsg_flags |= NLM_F_MULTI;
+	nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*ifm), flags);
 	ifm = NLMSG_DATA(nlh);
 	ifm->ifa_family = AF_INET;
 	ifm->ifa_prefixlen = ifa->ifa_prefixlen;
@@ -1090,7 +1089,7 @@ static int inet_dump_ifaddr(struct sk_bu
 				continue;
 			if (inet_fill_ifaddr(skb, ifa, NETLINK_CB(cb->skb).pid,
 					     cb->nlh->nlmsg_seq,
-					     RTM_NEWADDR) <= 0) {
+					     RTM_NEWADDR, NLM_F_MULTI) <= 0) {
 				rcu_read_unlock();
 				goto done;
 			}
@@ -1113,7 +1112,7 @@ static void rtmsg_ifa(int event, struct 
 
 	if (!skb)
 		netlink_set_err(rtnl, 0, RTMGRP_IPV4_IFADDR, ENOBUFS);
-	else if (inet_fill_ifaddr(skb, ifa, 0, 0, event) < 0) {
+	else if (inet_fill_ifaddr(skb, ifa, current->pid, 0, event, 0) < 0) {
 		kfree_skb(skb);
 		netlink_set_err(rtnl, 0, RTMGRP_IPV4_IFADDR, EINVAL);
 	} else {
@@ -1472,7 +1471,7 @@ static void devinet_sysctl_register(stru
 	 * by sysctl and we wouldn't want anyone to change it under our feet
 	 * (see SIOCSIFNAME).
 	 */	
-	dev_name = net_sysctl_strdup(dev_name);
+	dev_name = kstrdup(dev_name, GFP_KERNEL);
 	if (!dev_name)
 	    goto free;
 
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
--- a/net/ipv4/esp4.c
+++ b/net/ipv4/esp4.c
@@ -362,7 +362,7 @@ static void esp_destroy(struct xfrm_stat
 	kfree(esp);
 }
 
-static int esp_init_state(struct xfrm_state *x, void *args)
+static int esp_init_state(struct xfrm_state *x)
 {
 	struct esp_data *esp = NULL;
 
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -516,6 +516,60 @@ static void fib_del_ifaddr(struct in_ifa
 #undef BRD1_OK
 }
 
+static void nl_fib_lookup(struct fib_result_nl *frn, struct fib_table *tb )
+{
+	
+	struct fib_result       res;
+	struct flowi            fl = { .nl_u = { .ip4_u = { .daddr = frn->fl_addr, 
+							    .fwmark = frn->fl_fwmark,
+							    .tos = frn->fl_tos,
+							    .scope = frn->fl_scope } } };
+	if (tb) {
+		local_bh_disable();
+
+		frn->tb_id = tb->tb_id;
+		frn->err = tb->tb_lookup(tb, &fl, &res);
+
+		if (!frn->err) {
+			frn->prefixlen = res.prefixlen;
+			frn->nh_sel = res.nh_sel;
+			frn->type = res.type;
+			frn->scope = res.scope;
+		}
+		local_bh_enable();
+	}
+}
+
+static void nl_fib_input(struct sock *sk, int len)
+{
+	struct sk_buff *skb = NULL;
+        struct nlmsghdr *nlh = NULL;
+	struct fib_result_nl *frn;
+	int err;
+	u32 pid;     
+	struct fib_table *tb;
+	
+	skb = skb_recv_datagram(sk, 0, 0, &err);
+	nlh = (struct nlmsghdr *)skb->data;
+	
+	frn = (struct fib_result_nl *) NLMSG_DATA(nlh);
+	tb = fib_get_table(frn->tb_id_in);
+
+	nl_fib_lookup(frn, tb);
+	
+	pid = nlh->nlmsg_pid;           /*pid of sending process */
+	NETLINK_CB(skb).groups = 0;     /* not in mcast group */
+	NETLINK_CB(skb).pid = 0;         /* from kernel */
+	NETLINK_CB(skb).dst_pid = pid;
+	NETLINK_CB(skb).dst_groups = 0;  /* unicast */
+	netlink_unicast(sk, skb, pid, MSG_DONTWAIT);
+}    
+
+static void nl_fib_lookup_init(void)
+{
+      netlink_kernel_create(NETLINK_FIB_LOOKUP, nl_fib_input);
+}
+
 static void fib_disable_ip(struct net_device *dev, int force)
 {
 	if (fib_sync_down(0, dev, force))
@@ -604,6 +658,7 @@ void __init ip_fib_init(void)
 
 	register_netdevice_notifier(&fib_netdev_notifier);
 	register_inetaddr_notifier(&fib_inetaddr_notifier);
+	nl_fib_lookup_init();
 }
 
 EXPORT_SYMBOL(inet_addr_type);
diff --git a/net/ipv4/fib_hash.c b/net/ipv4/fib_hash.c
--- a/net/ipv4/fib_hash.c
+++ b/net/ipv4/fib_hash.c
@@ -703,7 +703,8 @@ fn_hash_dump_bucket(struct sk_buff *skb,
 					  &f->fn_key,
 					  fz->fz_order,
 					  fa->fa_tos,
-					  fa->fa_info) < 0) {
+					  fa->fa_info,
+					  NLM_F_MULTI) < 0) {
 				cb->args[3] = i;
 				return -1;
 			}
diff --git a/net/ipv4/fib_lookup.h b/net/ipv4/fib_lookup.h
--- a/net/ipv4/fib_lookup.h
+++ b/net/ipv4/fib_lookup.h
@@ -30,7 +30,8 @@ extern int fib_nh_match(struct rtmsg *r,
 			struct kern_rta *rta, struct fib_info *fi);
 extern int fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
 			 u8 tb_id, u8 type, u8 scope, void *dst,
-			 int dst_len, u8 tos, struct fib_info *fi);
+			 int dst_len, u8 tos, struct fib_info *fi,
+			 unsigned int);
 extern void rtmsg_fib(int event, u32 key, struct fib_alias *fa,
 		      int z, int tb_id,
 		      struct nlmsghdr *n, struct netlink_skb_parms *req);
diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c
--- a/net/ipv4/fib_rules.c
+++ b/net/ipv4/fib_rules.c
@@ -367,13 +367,14 @@ static struct notifier_block fib_rules_n
 
 static __inline__ int inet_fill_rule(struct sk_buff *skb,
 				     struct fib_rule *r,
-				     struct netlink_callback *cb)
+				     struct netlink_callback *cb,
+				     unsigned int flags)
 {
 	struct rtmsg *rtm;
 	struct nlmsghdr  *nlh;
 	unsigned char	 *b = skb->tail;
 
-	nlh = NLMSG_PUT(skb, NETLINK_CREDS(cb->skb)->pid, cb->nlh->nlmsg_seq, RTM_NEWRULE, sizeof(*rtm));
+	nlh = NLMSG_NEW_ANSWER(skb, cb, RTM_NEWRULE, sizeof(*rtm), flags);
 	rtm = NLMSG_DATA(nlh);
 	rtm->rtm_family = AF_INET;
 	rtm->rtm_dst_len = r->r_dst_len;
@@ -422,7 +423,7 @@ int inet_dump_rules(struct sk_buff *skb,
 	for (r=fib_rules, idx=0; r; r = r->r_next, idx++) {
 		if (idx < s_idx)
 			continue;
-		if (inet_fill_rule(skb, r, cb) < 0)
+		if (inet_fill_rule(skb, r, cb, NLM_F_MULTI) < 0)
 			break;
 	}
 	read_unlock(&fib_rules_lock);
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -276,7 +276,7 @@ void rtmsg_fib(int event, u32 key, struc
 	       struct nlmsghdr *n, struct netlink_skb_parms *req)
 {
 	struct sk_buff *skb;
-	u32 pid = req ? req->pid : 0;
+	u32 pid = req ? req->pid : n->nlmsg_pid;
 	int size = NLMSG_SPACE(sizeof(struct rtmsg)+256);
 
 	skb = alloc_skb(size, GFP_KERNEL);
@@ -286,7 +286,7 @@ void rtmsg_fib(int event, u32 key, struc
 	if (fib_dump_info(skb, pid, n->nlmsg_seq, event, tb_id,
 			  fa->fa_type, fa->fa_scope, &key, z,
 			  fa->fa_tos,
-			  fa->fa_info) < 0) {
+			  fa->fa_info, 0) < 0) {
 		kfree_skb(skb);
 		return;
 	}
@@ -593,10 +593,13 @@ static void fib_hash_move(struct hlist_h
 			  struct hlist_head *new_laddrhash,
 			  unsigned int new_size)
 {
+	struct hlist_head *old_info_hash, *old_laddrhash;
 	unsigned int old_size = fib_hash_size;
-	unsigned int i;
+	unsigned int i, bytes;
 
 	write_lock(&fib_info_lock);
+	old_info_hash = fib_info_hash;
+	old_laddrhash = fib_info_laddrhash;
 	fib_hash_size = new_size;
 
 	for (i = 0; i < old_size; i++) {
@@ -636,6 +639,10 @@ static void fib_hash_move(struct hlist_h
 	fib_info_laddrhash = new_laddrhash;
 
 	write_unlock(&fib_info_lock);
+
+	bytes = old_size * sizeof(struct hlist_head *);
+	fib_hash_free(old_info_hash, bytes);
+	fib_hash_free(old_laddrhash, bytes);
 }
 
 struct fib_info *
@@ -932,13 +939,13 @@ u32 __fib_res_prefsrc(struct fib_result 
 int
 fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
 	      u8 tb_id, u8 type, u8 scope, void *dst, int dst_len, u8 tos,
-	      struct fib_info *fi)
+	      struct fib_info *fi, unsigned int flags)
 {
 	struct rtmsg *rtm;
 	struct nlmsghdr  *nlh;
 	unsigned char	 *b = skb->tail;
 
-	nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(*rtm));
+	nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*rtm), flags);
 	rtm = NLMSG_DATA(nlh);
 	rtm->rtm_family = AF_INET;
 	rtm->rtm_dst_len = dst_len;
@@ -1035,7 +1042,7 @@ fib_convert_rtentry(int cmd, struct nlms
 	}
 
 	nl->nlmsg_flags = NLM_F_REQUEST;
-	nl->nlmsg_pid = 0;
+	nl->nlmsg_pid = current->pid;
 	nl->nlmsg_seq = 0;
 	nl->nlmsg_len = NLMSG_LENGTH(sizeof(*rtm));
 	if (cmd == SIOCDELRT) {
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
new file mode 100644
--- /dev/null
+++ b/net/ipv4/fib_trie.c
@@ -0,0 +1,2612 @@
+/*
+ *   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.
+ *
+ *   Robert Olsson <robert.olsson@its.uu.se> Uppsala Universitet
+ *     & Swedish University of Agricultural Sciences.
+ *
+ *   Jens Laas <jens.laas@data.slu.se> Swedish University of 
+ *     Agricultural Sciences.
+ * 
+ *   Hans Liss <hans.liss@its.uu.se>  Uppsala Universitet
+ *
+ * This work is based on the LPC-trie which is originally descibed in:
+ * 
+ * An experimental study of compression methods for dynamic tries
+ * Stefan Nilsson and Matti Tikkanen. Algorithmica, 33(1):19-33, 2002.
+ * http://www.nada.kth.se/~snilsson/public/papers/dyntrie2/
+ *
+ *
+ * IP-address lookup using LC-tries. Stefan Nilsson and Gunnar Karlsson
+ * IEEE Journal on Selected Areas in Communications, 17(6):1083-1092, June 1999
+ *
+ * Version:	$Id: fib_trie.c,v 1.3 2005/06/08 14:20:01 robert Exp $
+ *
+ *
+ * Code from fib_hash has been reused which includes the following header:
+ *
+ *
+ * INET		An implementation of the TCP/IP protocol suite for the LINUX
+ *		operating system.  INET is implemented using the  BSD Socket
+ *		interface as the means of communication with the user level.
+ *
+ *		IPv4 FIB: lookup engine and maintenance routines.
+ *
+ *
+ * Authors:	Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
+ *
+ *		This program is free software; you can redistribute it and/or
+ *		modify it under the terms of the GNU General Public License
+ *		as published by the Free Software Foundation; either version
+ *		2 of the License, or (at your option) any later version.
+ */
+
+#define VERSION "0.325"
+
+#include <linux/config.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/bitops.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/socket.h>
+#include <linux/sockios.h>
+#include <linux/errno.h>
+#include <linux/in.h>
+#include <linux/inet.h>
+#include <linux/netdevice.h>
+#include <linux/if_arp.h>
+#include <linux/proc_fs.h>
+#include <linux/skbuff.h>
+#include <linux/netlink.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <net/ip.h>
+#include <net/protocol.h>
+#include <net/route.h>
+#include <net/tcp.h>
+#include <net/sock.h>
+#include <net/ip_fib.h>
+#include "fib_lookup.h"
+
+#undef CONFIG_IP_FIB_TRIE_STATS
+#define MAX_CHILDS 16384
+
+#define EXTRACT(p, n, str) ((str)<<(p)>>(32-(n)))
+#define KEYLENGTH (8*sizeof(t_key))
+#define MASK_PFX(k, l) (((l)==0)?0:(k >> (KEYLENGTH-l)) << (KEYLENGTH-l))
+#define TKEY_GET_MASK(offset, bits) (((bits)==0)?0:((t_key)(-1) << (KEYLENGTH - bits) >> offset))
+
+static DEFINE_RWLOCK(fib_lock);
+
+typedef unsigned int t_key;
+
+#define T_TNODE 0
+#define T_LEAF  1
+#define NODE_TYPE_MASK	0x1UL
+#define NODE_PARENT(_node) \
+	((struct tnode *)((_node)->_parent & ~NODE_TYPE_MASK))
+#define NODE_SET_PARENT(_node, _ptr) \
+	((_node)->_parent = (((unsigned long)(_ptr)) | \
+                     ((_node)->_parent & NODE_TYPE_MASK)))
+#define NODE_INIT_PARENT(_node, _type) \
+	((_node)->_parent = (_type))
+#define NODE_TYPE(_node) \
+	((_node)->_parent & NODE_TYPE_MASK)
+
+#define IS_TNODE(n) (!(n->_parent & T_LEAF))
+#define IS_LEAF(n) (n->_parent & T_LEAF)
+
+struct node {
+        t_key key;
+	unsigned long _parent;
+};
+
+struct leaf {
+        t_key key;
+	unsigned long _parent;
+	struct hlist_head list;
+};
+
+struct leaf_info {
+	struct hlist_node hlist;
+	int plen;
+	struct list_head falh;
+};
+
+struct tnode {
+        t_key key;
+	unsigned long _parent;
+        unsigned short pos:5;        /* 2log(KEYLENGTH) bits needed */
+        unsigned short bits:5;       /* 2log(KEYLENGTH) bits needed */
+        unsigned short full_children;  /* KEYLENGTH bits needed */
+        unsigned short empty_children; /* KEYLENGTH bits needed */
+        struct node *child[0];
+};
+
+#ifdef CONFIG_IP_FIB_TRIE_STATS
+struct trie_use_stats {
+	unsigned int gets;
+	unsigned int backtrack;
+	unsigned int semantic_match_passed;
+	unsigned int semantic_match_miss;
+	unsigned int null_node_hit;
+	unsigned int resize_node_skipped;
+};
+#endif
+
+struct trie_stat {
+	unsigned int totdepth;
+	unsigned int maxdepth;
+	unsigned int tnodes;
+	unsigned int leaves;
+	unsigned int nullpointers;
+	unsigned int nodesizes[MAX_CHILDS];
+};
+
+struct trie {
+        struct node *trie;
+#ifdef CONFIG_IP_FIB_TRIE_STATS
+	struct trie_use_stats stats;
+#endif
+        int size;
+	unsigned int revision;
+};
+
+static int trie_debug = 0;
+
+static int tnode_full(struct tnode *tn, struct node *n);
+static void put_child(struct trie *t, struct tnode *tn, int i, struct node *n);
+static void tnode_put_child_reorg(struct tnode *tn, int i, struct node *n, int wasfull);
+static int tnode_child_length(struct tnode *tn);
+static struct node *resize(struct trie *t, struct tnode *tn);
+static struct tnode *inflate(struct trie *t, struct tnode *tn, int *err);
+static struct tnode *halve(struct trie *t, struct tnode *tn, int *err);
+static void tnode_free(struct tnode *tn);
+static void trie_dump_seq(struct seq_file *seq, struct trie *t);
+extern struct fib_alias *fib_find_alias(struct list_head *fah, u8 tos, u32 prio);
+extern int fib_detect_death(struct fib_info *fi, int order,
+                            struct fib_info **last_resort, int *last_idx, int *dflt);
+
+extern void rtmsg_fib(int event, u32 key, struct fib_alias *fa, int z, int tb_id,
+               struct nlmsghdr *n, struct netlink_skb_parms *req);
+
+static kmem_cache_t *fn_alias_kmem;
+static struct trie *trie_local = NULL, *trie_main = NULL;
+
+static void trie_bug(char *err)
+{
+	printk("Trie Bug: %s\n", err);
+	BUG();
+}
+
+static inline struct node *tnode_get_child(struct tnode *tn, int i)
+{
+        if (i >= 1<<tn->bits)
+                trie_bug("tnode_get_child");
+
+        return tn->child[i];
+}
+
+static inline int tnode_child_length(struct tnode *tn)
+{
+        return 1<<tn->bits;
+}
+
+/*
+  _________________________________________________________________
+  | i | i | i | i | i | i | i | N | N | N | S | S | S | S | S | C |
+  ----------------------------------------------------------------
+    0   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15
+
+  _________________________________________________________________
+  | C | C | C | u | u | u | u | u | u | u | u | u | u | u | u | u |
+  -----------------------------------------------------------------
+   16  17  18  19  20  21  22  23  24  25  26  27  28  29  30  31
+
+  tp->pos = 7
+  tp->bits = 3
+  n->pos = 15
+  n->bits=4
+  KEYLENGTH=32
+*/
+
+static inline t_key tkey_extract_bits(t_key a, int offset, int bits)
+{
+        if (offset < KEYLENGTH)
+		return ((t_key)(a << offset)) >> (KEYLENGTH - bits);
+        else
+		return 0;
+}
+
+static inline int tkey_equals(t_key a, t_key b)
+{
+	return a == b;
+}
+
+static inline int tkey_sub_equals(t_key a, int offset, int bits, t_key b)
+{
+	if (bits == 0 || offset >= KEYLENGTH)
+		return 1;
+        bits = bits > KEYLENGTH ? KEYLENGTH : bits;
+        return ((a ^ b) << offset) >> (KEYLENGTH - bits) == 0;
+}
+
+static inline int tkey_mismatch(t_key a, int offset, t_key b)
+{
+	t_key diff = a ^ b;
+	int i = offset;
+
+	if (!diff)
+		return 0;
+	while ((diff << i) >> (KEYLENGTH-1) == 0)
+		i++;
+	return i;
+}
+
+/* Candiate for fib_semantics */
+
+static void fn_free_alias(struct fib_alias *fa)
+{
+	fib_release_info(fa->fa_info);
+	kmem_cache_free(fn_alias_kmem, fa);
+}
+
+/*
+  To understand this stuff, an understanding of keys and all their bits is 
+  necessary. Every node in the trie has a key associated with it, but not 
+  all of the bits in that key are significant.
+
+  Consider a node 'n' and its parent 'tp'.
+
+  If n is a leaf, every bit in its key is significant. Its presence is 
+  necessitaded by path compression, since during a tree traversal (when 
+  searching for a leaf - unless we are doing an insertion) we will completely 
+  ignore all skipped bits we encounter. Thus we need to verify, at the end of 
+  a potentially successful search, that we have indeed been walking the 
+  correct key path.
+
+  Note that we can never "miss" the correct key in the tree if present by 
+  following the wrong path. Path compression ensures that segments of the key 
+  that are the same for all keys with a given prefix are skipped, but the 
+  skipped part *is* identical for each node in the subtrie below the skipped 
+  bit! trie_insert() in this implementation takes care of that - note the 
+  call to tkey_sub_equals() in trie_insert().
+
+  if n is an internal node - a 'tnode' here, the various parts of its key 
+  have many different meanings.
+
+  Example:  
+  _________________________________________________________________
+  | i | i | i | i | i | i | i | N | N | N | S | S | S | S | S | C |
+  -----------------------------------------------------------------
+    0   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15 
+
+  _________________________________________________________________
+  | C | C | C | u | u | u | u | u | u | u | u | u | u | u | u | u |
+  -----------------------------------------------------------------
+   16  17  18  19  20  21  22  23  24  25  26  27  28  29  30  31
+
+  tp->pos = 7
+  tp->bits = 3
+  n->pos = 15
+  n->bits=4
+
+  First, let's just ignore the bits that come before the parent tp, that is 
+  the bits from 0 to (tp->pos-1). They are *known* but at this point we do 
+  not use them for anything.
+
+  The bits from (tp->pos) to (tp->pos + tp->bits - 1) - "N", above - are the
+  index into the parent's child array. That is, they will be used to find 
+  'n' among tp's children.
+
+  The bits from (tp->pos + tp->bits) to (n->pos - 1) - "S" - are skipped bits
+  for the node n.
+
+  All the bits we have seen so far are significant to the node n. The rest 
+  of the bits are really not needed or indeed known in n->key.
+
+  The bits from (n->pos) to (n->pos + n->bits - 1) - "C" - are the index into 
+  n's child array, and will of course be different for each child.
+  
+
+  The rest of the bits, from (n->pos + n->bits) onward, are completely unknown
+  at this point.
+
+*/
+
+static void check_tnode(struct tnode *tn)
+{
+	if (tn && tn->pos+tn->bits > 32) {
+		printk("TNODE ERROR tn=%p, pos=%d, bits=%d\n", tn, tn->pos, tn->bits);
+	}
+}
+
+static int halve_threshold = 25;
+static int inflate_threshold = 50;
+
+static struct leaf *leaf_new(void)
+{
+	struct leaf *l = kmalloc(sizeof(struct leaf),  GFP_KERNEL);
+	if (l) {
+		NODE_INIT_PARENT(l, T_LEAF);
+		INIT_HLIST_HEAD(&l->list);
+	}
+	return l;
+}
+
+static struct leaf_info *leaf_info_new(int plen)
+{
+	struct leaf_info *li = kmalloc(sizeof(struct leaf_info),  GFP_KERNEL);
+	if (li) {
+		li->plen = plen;
+		INIT_LIST_HEAD(&li->falh);
+	}
+	return li;
+}
+
+static inline void free_leaf(struct leaf *l)
+{
+	kfree(l);
+}
+
+static inline void free_leaf_info(struct leaf_info *li)
+{
+	kfree(li);
+}
+
+static struct tnode *tnode_alloc(unsigned int size)
+{
+	if (size <= PAGE_SIZE) {
+		return kmalloc(size, GFP_KERNEL);
+	} else {
+		return (struct tnode *)
+			__get_free_pages(GFP_KERNEL, get_order(size));
+	}
+}
+
+static void __tnode_free(struct tnode *tn)
+{
+	unsigned int size = sizeof(struct tnode) +
+	                    (1<<tn->bits) * sizeof(struct node *);
+
+	if (size <= PAGE_SIZE)
+		kfree(tn);
+	else
+		free_pages((unsigned long)tn, get_order(size));
+}
+
+static struct tnode* tnode_new(t_key key, int pos, int bits)
+{
+	int nchildren = 1<<bits;
+	int sz = sizeof(struct tnode) + nchildren * sizeof(struct node *);
+	struct tnode *tn = tnode_alloc(sz);
+
+	if (tn)  {
+		memset(tn, 0, sz);
+		NODE_INIT_PARENT(tn, T_TNODE);
+		tn->pos = pos;
+		tn->bits = bits;
+		tn->key = key;
+		tn->full_children = 0;
+		tn->empty_children = 1<<bits;
+	}
+
+	if (trie_debug > 0)
+		printk("AT %p s=%u %u\n", tn, (unsigned int) sizeof(struct tnode),
+		       (unsigned int) (sizeof(struct node) * 1<<bits));
+	return tn;
+}
+
+static void tnode_free(struct tnode *tn)
+{
+	if (!tn) {
+		trie_bug("tnode_free\n");
+	}
+	if (IS_LEAF(tn)) {
+		free_leaf((struct leaf *)tn);
+		if (trie_debug > 0 )
+			printk("FL %p \n", tn);
+	}
+	else if (IS_TNODE(tn)) {
+		__tnode_free(tn);
+		if (trie_debug > 0 )
+			printk("FT %p \n", tn);
+	}
+	else {
+		trie_bug("tnode_free\n");
+	}
+}
+
+/*
+ * Check whether a tnode 'n' is "full", i.e. it is an internal node
+ * and no bits are skipped. See discussion in dyntree paper p. 6
+ */
+
+static inline int tnode_full(struct tnode *tn, struct node *n)
+{
+	if (n == NULL || IS_LEAF(n))
+		return 0;
+
+	return ((struct tnode *) n)->pos == tn->pos + tn->bits;
+}
+
+static inline void put_child(struct trie *t, struct tnode *tn, int i, struct node *n)
+{
+	tnode_put_child_reorg(tn, i, n, -1);
+}
+
+ /*
+  * Add a child at position i overwriting the old value.
+  * Update the value of full_children and empty_children.
+  */
+
+static void tnode_put_child_reorg(struct tnode *tn, int i, struct node *n, int wasfull)
+{
+	struct node *chi;
+	int isfull;
+
+	if (i >= 1<<tn->bits) {
+		printk("bits=%d, i=%d\n", tn->bits, i);
+		trie_bug("tnode_put_child_reorg bits");
+	}
+	write_lock_bh(&fib_lock);
+	chi = tn->child[i];
+
+	/* update emptyChildren */
+	if (n == NULL && chi != NULL)
+		tn->empty_children++;
+	else if (n != NULL && chi == NULL)
+		tn->empty_children--;
+
+	/* update fullChildren */
+        if (wasfull == -1)
+		wasfull = tnode_full(tn, chi);
+
+	isfull = tnode_full(tn, n);
+	if (wasfull && !isfull)
+		tn->full_children--;
+
+	else if (!wasfull && isfull)
+		tn->full_children++;
+	if (n)
+		NODE_SET_PARENT(n, tn);
+
+	tn->child[i] = n;
+	write_unlock_bh(&fib_lock);
+}
+
+static struct node *resize(struct trie *t, struct tnode *tn)
+{
+	int i;
+	int err = 0;
+
+ 	if (!tn)
+		return NULL;
+
+	if (trie_debug)
+		printk("In tnode_resize %p inflate_threshold=%d threshold=%d\n",
+		      tn, inflate_threshold, halve_threshold);
+
+	/* No children */
+	if (tn->empty_children == tnode_child_length(tn)) {
+		tnode_free(tn);
+		return NULL;
+	}
+	/* One child */
+	if (tn->empty_children == tnode_child_length(tn) - 1)
+		for (i = 0; i < tnode_child_length(tn); i++) {
+
+			write_lock_bh(&fib_lock);
+			if (tn->child[i] != NULL) {
+
+				/* compress one level */
+				struct node *n = tn->child[i];
+				if (n)
+					NODE_INIT_PARENT(n, NODE_TYPE(n));
+
+				write_unlock_bh(&fib_lock);
+				tnode_free(tn);
+				return n;
+			}
+			write_unlock_bh(&fib_lock);
+		}
+	/*
+	 * Double as long as the resulting node has a number of
+	 * nonempty nodes that are above the threshold.
+	 */
+
+	/*
+	 * From "Implementing a dynamic compressed trie" by Stefan Nilsson of
+	 * the Helsinki University of Technology and Matti Tikkanen of Nokia
+	 * Telecommunications, page 6:
+	 * "A node is doubled if the ratio of non-empty children to all
+	 * children in the *doubled* node is at least 'high'."
+	 *
+	 * 'high' in this instance is the variable 'inflate_threshold'. It
+	 * is expressed as a percentage, so we multiply it with
+	 * tnode_child_length() and instead of multiplying by 2 (since the
+	 * child array will be doubled by inflate()) and multiplying
+	 * the left-hand side by 100 (to handle the percentage thing) we
+	 * multiply the left-hand side by 50.
+	 *
+	 * The left-hand side may look a bit weird: tnode_child_length(tn)
+	 * - tn->empty_children is of course the number of non-null children
+	 * in the current node. tn->full_children is the number of "full"
+	 * children, that is non-null tnodes with a skip value of 0.
+	 * All of those will be doubled in the resulting inflated tnode, so
+	 * we just count them one extra time here.
+	 *
+	 * A clearer way to write this would be:
+	 *
+	 * to_be_doubled = tn->full_children;
+	 * not_to_be_doubled = tnode_child_length(tn) - tn->empty_children -
+	 *     tn->full_children;
+	 *
+	 * new_child_length = tnode_child_length(tn) * 2;
+	 *
+	 * new_fill_factor = 100 * (not_to_be_doubled + 2*to_be_doubled) /
+	 *      new_child_length;
+	 * if (new_fill_factor >= inflate_threshold)
+	 *
+	 * ...and so on, tho it would mess up the while () loop.
+	 *
+	 * anyway,
+	 * 100 * (not_to_be_doubled + 2*to_be_doubled) / new_child_length >=
+	 *      inflate_threshold
+	 *
+	 * avoid a division:
+	 * 100 * (not_to_be_doubled + 2*to_be_doubled) >=
+	 *      inflate_threshold * new_child_length
+	 *
+	 * expand not_to_be_doubled and to_be_doubled, and shorten:
+	 * 100 * (tnode_child_length(tn) - tn->empty_children +
+	 *    tn->full_children ) >= inflate_threshold * new_child_length
+	 *
+	 * expand new_child_length:
+	 * 100 * (tnode_child_length(tn) - tn->empty_children +
+	 *    tn->full_children ) >=
+	 *      inflate_threshold * tnode_child_length(tn) * 2
+	 *
+	 * shorten again:
+	 * 50 * (tn->full_children + tnode_child_length(tn) -
+	 *    tn->empty_children ) >= inflate_threshold *
+	 *    tnode_child_length(tn)
+	 *
+	 */
+
+	check_tnode(tn);
+
+	err = 0;
+	while ((tn->full_children > 0 &&
+	       50 * (tn->full_children + tnode_child_length(tn) - tn->empty_children) >=
+				inflate_threshold * tnode_child_length(tn))) {
+
+		tn = inflate(t, tn, &err);
+
+		if (err) {
+#ifdef CONFIG_IP_FIB_TRIE_STATS
+			t->stats.resize_node_skipped++;
+#endif
+			break;
+		}
+	}
+
+	check_tnode(tn);
+
+	/*
+	 * Halve as long as the number of empty children in this
+	 * node is above threshold.
+	 */
+
+	err = 0;
+	while (tn->bits > 1 &&
+	       100 * (tnode_child_length(tn) - tn->empty_children) <
+	       halve_threshold * tnode_child_length(tn)) {
+
+		tn = halve(t, tn, &err);
+
+		if (err) {
+#ifdef CONFIG_IP_FIB_TRIE_STATS
+			t->stats.resize_node_skipped++;
+#endif
+			break;
+		}
+	}
+
+
+	/* Only one child remains */
+
+	if (tn->empty_children == tnode_child_length(tn) - 1)
+		for (i = 0; i < tnode_child_length(tn); i++) {
+		
+			write_lock_bh(&fib_lock);
+			if (tn->child[i] != NULL) {
+				/* compress one level */
+				struct node *n = tn->child[i];
+
+				if (n)
+					NODE_INIT_PARENT(n, NODE_TYPE(n));
+
+				write_unlock_bh(&fib_lock);
+				tnode_free(tn);
+				return n;
+			}
+			write_unlock_bh(&fib_lock);
+		}
+
+	return (struct node *) tn;
+}
+
+static struct tnode *inflate(struct trie *t, struct tnode *tn, int *err)
+{
+	struct tnode *inode;
+	struct tnode *oldtnode = tn;
+	int olen = tnode_child_length(tn);
+	int i;
+
+  	if (trie_debug)
+		printk("In inflate\n");
+
+	tn = tnode_new(oldtnode->key, oldtnode->pos, oldtnode->bits + 1);
+
+	if (!tn) {
+		*err = -ENOMEM;
+		return oldtnode;
+	}
+
+	/*
+	 * Preallocate and store tnodes before the actual work so we
+	 * don't get into an inconsistent state if memory allocation
+	 * fails. In case of failure we return the oldnode and  inflate
+	 * of tnode is ignored.
+	 */
+		
+	for(i = 0; i < olen; i++) {
+		struct tnode *inode = (struct tnode *) tnode_get_child(oldtnode, i);
+
+		if (inode &&
+		    IS_TNODE(inode) &&
+		    inode->pos == oldtnode->pos + oldtnode->bits &&
+		    inode->bits > 1) {
+			struct tnode *left, *right;
+
+			t_key m = TKEY_GET_MASK(inode->pos, 1);
+
+			left = tnode_new(inode->key&(~m), inode->pos + 1,
+					 inode->bits - 1);
+
+			if (!left) {
+				*err = -ENOMEM;
+				break;
+			}
+		
+			right = tnode_new(inode->key|m, inode->pos + 1,
+					  inode->bits - 1);
+
+			if (!right) {
+				*err = -ENOMEM;
+				break;
+			}
+
+			put_child(t, tn, 2*i, (struct node *) left);
+			put_child(t, tn, 2*i+1, (struct node *) right);
+		}
+	}
+
+	if (*err) {
+		int size = tnode_child_length(tn);
+		int j;
+
+		for(j = 0; j < size; j++)
+			if (tn->child[j])
+				tnode_free((struct tnode *)tn->child[j]);
+
+		tnode_free(tn);
+	
+		*err = -ENOMEM;
+		return oldtnode;
+	}
+
+	for(i = 0; i < olen; i++) {
+		struct node *node = tnode_get_child(oldtnode, i);
+
+		/* An empty child */
+		if (node == NULL)
+			continue;
+
+		/* A leaf or an internal node with skipped bits */
+
+		if (IS_LEAF(node) || ((struct tnode *) node)->pos >
+		   tn->pos + tn->bits - 1) {
+			if (tkey_extract_bits(node->key, oldtnode->pos + oldtnode->bits,
+					     1) == 0)
+				put_child(t, tn, 2*i, node);
+			else
+				put_child(t, tn, 2*i+1, node);
+			continue;
+		}
+
+		/* An internal node with two children */
+		inode = (struct tnode *) node;
+
+		if (inode->bits == 1) {
+			put_child(t, tn, 2*i, inode->child[0]);
+			put_child(t, tn, 2*i+1, inode->child[1]);
+
+			tnode_free(inode);
+		}
+
+			/* An internal node with more than two children */
+		else {
+			struct tnode *left, *right;
+			int size, j;
+
+			/* We will replace this node 'inode' with two new
+			 * ones, 'left' and 'right', each with half of the
+			 * original children. The two new nodes will have
+			 * a position one bit further down the key and this
+			 * means that the "significant" part of their keys
+			 * (see the discussion near the top of this file)
+			 * will differ by one bit, which will be "0" in
+			 * left's key and "1" in right's key. Since we are
+			 * moving the key position by one step, the bit that
+			 * we are moving away from - the bit at position
+			 * (inode->pos) - is the one that will differ between
+			 * left and right. So... we synthesize that bit in the
+			 * two  new keys.
+			 * The mask 'm' below will be a single "one" bit at
+			 * the position (inode->pos)
+			 */
+
+			/* Use the old key, but set the new significant
+			 *   bit to zero.
+			 */
+
+			left = (struct tnode *) tnode_get_child(tn, 2*i);
+			put_child(t, tn, 2*i, NULL);
+
+			if (!left)
+				BUG();
+
+			right = (struct tnode *) tnode_get_child(tn, 2*i+1);
+			put_child(t, tn, 2*i+1, NULL);
+
+			if (!right)
+				BUG();
+
+			size = tnode_child_length(left);
+			for(j = 0; j < size; j++) {
+				put_child(t, left, j, inode->child[j]);
+				put_child(t, right, j, inode->child[j + size]);
+			}
+			put_child(t, tn, 2*i, resize(t, left));
+			put_child(t, tn, 2*i+1, resize(t, right));
+
+			tnode_free(inode);
+		}
+	}
+	tnode_free(oldtnode);
+	return tn;
+}
+
+static struct tnode *halve(struct trie *t, struct tnode *tn, int *err)
+{
+	struct tnode *oldtnode = tn;
+	struct node *left, *right;
+	int i;
+	int olen = tnode_child_length(tn);
+
+	if (trie_debug) printk("In halve\n");
+
+	tn = tnode_new(oldtnode->key, oldtnode->pos, oldtnode->bits - 1);
+
+	if (!tn) {
+		*err = -ENOMEM;
+		return oldtnode;
+	}
+
+	/*
+	 * Preallocate and store tnodes before the actual work so we
+	 * don't get into an inconsistent state if memory allocation
+	 * fails. In case of failure we return the oldnode and halve
+	 * of tnode is ignored.
+	 */
+
+	for(i = 0; i < olen; i += 2) {
+		left = tnode_get_child(oldtnode, i);
+		right = tnode_get_child(oldtnode, i+1);
+
+		/* Two nonempty children */
+		if (left && right)  {
+			struct tnode *newBinNode =
+				tnode_new(left->key, tn->pos + tn->bits, 1);
+
+			if (!newBinNode) {
+				*err = -ENOMEM;
+				break;
+			}
+			put_child(t, tn, i/2, (struct node *)newBinNode);
+		}
+	}
+
+	if (*err) {
+		int size = tnode_child_length(tn);
+		int j;
+
+		for(j = 0; j < size; j++)
+			if (tn->child[j])
+				tnode_free((struct tnode *)tn->child[j]);
+
+		tnode_free(tn);
+	
+		*err = -ENOMEM;
+		return oldtnode;
+	}
+
+	for(i = 0; i < olen; i += 2) {
+		left = tnode_get_child(oldtnode, i);
+		right = tnode_get_child(oldtnode, i+1);
+
+		/* At least one of the children is empty */
+		if (left == NULL) {
+			if (right == NULL)    /* Both are empty */
+				continue;
+			put_child(t, tn, i/2, right);
+		} else if (right == NULL)
+			put_child(t, tn, i/2, left);
+
+		/* Two nonempty children */
+		else {
+			struct tnode *newBinNode =
+				(struct tnode *) tnode_get_child(tn, i/2);
+			put_child(t, tn, i/2, NULL);
+
+			if (!newBinNode)
+				BUG();
+
+			put_child(t, newBinNode, 0, left);
+			put_child(t, newBinNode, 1, right);
+			put_child(t, tn, i/2, resize(t, newBinNode));
+		}
+	}
+	tnode_free(oldtnode);
+	return tn;
+}
+
+static void *trie_init(struct trie *t)
+{
+	if (t) {
+		t->size = 0;
+		t->trie = NULL;
+		t->revision = 0;
+#ifdef CONFIG_IP_FIB_TRIE_STATS
+       		memset(&t->stats, 0, sizeof(struct trie_use_stats));
+#endif
+	}
+	return t;
+}
+
+static struct leaf_info *find_leaf_info(struct hlist_head *head, int plen)
+{
+	struct hlist_node *node;
+	struct leaf_info *li;
+
+	hlist_for_each_entry(li, node, head, hlist) {
+		if (li->plen == plen)
+			return li;
+	}
+	return NULL;
+}
+
+static inline struct list_head * get_fa_head(struct leaf *l, int plen)
+{
+	struct list_head *fa_head = NULL;
+	struct leaf_info *li = find_leaf_info(&l->list, plen);
+
+	if (li)
+		fa_head = &li->falh;
+
+	return fa_head;
+}
+
+static void insert_leaf_info(struct hlist_head *head, struct leaf_info *new)
+{
+	struct leaf_info *li = NULL, *last = NULL;
+	struct hlist_node *node, *tmp;
+
+	write_lock_bh(&fib_lock);
+
+	if (hlist_empty(head))
+		hlist_add_head(&new->hlist, head);
+	else {
+		hlist_for_each_entry_safe(li, node, tmp, head, hlist) {
+		
+			if (new->plen > li->plen)
+				break;
+		
+			last = li;
+		}
+		if (last)
+			hlist_add_after(&last->hlist, &new->hlist);
+		else
+			hlist_add_before(&new->hlist, &li->hlist);
+	}
+	write_unlock_bh(&fib_lock);
+}
+
+static struct leaf *
+fib_find_node(struct trie *t, u32 key)
+{
+	int pos;
+	struct tnode *tn;
+	struct node *n;
+
+	pos = 0;
+	n = t->trie;
+
+	while (n != NULL &&  NODE_TYPE(n) == T_TNODE) {
+		tn = (struct tnode *) n;
+		
+		check_tnode(tn);
+		
+		if (tkey_sub_equals(tn->key, pos, tn->pos-pos, key)) {
+			pos=tn->pos + tn->bits;
+			n = tnode_get_child(tn, tkey_extract_bits(key, tn->pos, tn->bits));
+		}
+		else
+			break;
+	}
+	/* Case we have found a leaf. Compare prefixes */
+
+	if (n != NULL && IS_LEAF(n) && tkey_equals(key, n->key)) {
+		struct leaf *l = (struct leaf *) n;
+		return l;
+	}
+	return NULL;
+}
+
+static struct node *trie_rebalance(struct trie *t, struct tnode *tn)
+{
+	int i = 0;
+	int wasfull;
+	t_key cindex, key;
+	struct tnode *tp = NULL;
+
+	if (!tn)
+		BUG();
+
+	key = tn->key;
+	i = 0;
+
+	while (tn != NULL && NODE_PARENT(tn) != NULL) {
+
+		if (i > 10) {
+			printk("Rebalance tn=%p \n", tn);
+			if (tn) 		printk("tn->parent=%p \n", NODE_PARENT(tn));
+		
+			printk("Rebalance tp=%p \n", tp);
+			if (tp) 		printk("tp->parent=%p \n", NODE_PARENT(tp));
+		}
+
+		if (i > 12) BUG();
+		i++;
+
+		tp = NODE_PARENT(tn);
+		cindex = tkey_extract_bits(key, tp->pos, tp->bits);
+		wasfull = tnode_full(tp, tnode_get_child(tp, cindex));
+		tn = (struct tnode *) resize (t, (struct tnode *)tn);
+		tnode_put_child_reorg((struct tnode *)tp, cindex,(struct node*)tn, wasfull);
+	
+		if (!NODE_PARENT(tn))
+			break;
+
+		tn = NODE_PARENT(tn);
+	}
+	/* Handle last (top) tnode */
+	if (IS_TNODE(tn))
+		tn = (struct tnode*) resize(t, (struct tnode *)tn);
+
+	return (struct node*) tn;
+}
+
+static  struct list_head *
+fib_insert_node(struct trie *t, int *err, u32 key, int plen)
+{
+	int pos, newpos;
+	struct tnode *tp = NULL, *tn = NULL;
+	struct node *n;
+	struct leaf *l;
+	int missbit;
+	struct list_head *fa_head = NULL;
+	struct leaf_info *li;
+	t_key cindex;
+
+	pos = 0;
+	n = t->trie;
+
+	/* If we point to NULL, stop. Either the tree is empty and we should
+	 * just put a new leaf in if, or we have reached an empty child slot,
+	 * and we should just put our new leaf in that.
+	 * If we point to a T_TNODE, check if it matches our key. Note that
+	 * a T_TNODE might be skipping any number of bits - its 'pos' need
+	 * not be the parent's 'pos'+'bits'!
+	 *
+	 * If it does match the current key, get pos/bits from it, extract
+	 * the index from our key, push the T_TNODE and walk the tree.
+	 *
+	 * If it doesn't, we have to replace it with a new T_TNODE.
+	 *
+	 * If we point to a T_LEAF, it might or might not have the same key
+	 * as we do. If it does, just change the value, update the T_LEAF's
+	 * value, and return it.
+	 * If it doesn't, we need to replace it with a T_TNODE.
+	 */
+
+	while (n != NULL &&  NODE_TYPE(n) == T_TNODE) {
+		tn = (struct tnode *) n;
+		
+		check_tnode(tn);
+	
+		if (tkey_sub_equals(tn->key, pos, tn->pos-pos, key)) {
+			tp = tn;
+			pos=tn->pos + tn->bits;
+			n = tnode_get_child(tn, tkey_extract_bits(key, tn->pos, tn->bits));
+
+			if (n && NODE_PARENT(n) != tn) {
+				printk("BUG tn=%p, n->parent=%p\n", tn, NODE_PARENT(n));
+				BUG();
+			}
+		}
+		else
+			break;
+	}
+
+	/*
+	 * n  ----> NULL, LEAF or TNODE
+	 *
+	 * tp is n's (parent) ----> NULL or TNODE
+	 */
+
+	if (tp && IS_LEAF(tp))
+		BUG();
+
+
+	/* Case 1: n is a leaf. Compare prefixes */
+
+	if (n != NULL && IS_LEAF(n) && tkey_equals(key, n->key)) {
+		struct leaf *l = ( struct leaf *)  n;
+	
+		li = leaf_info_new(plen);
+	
+		if (!li) {
+			*err = -ENOMEM;
+			goto err;
+		}
+
+		fa_head = &li->falh;
+		insert_leaf_info(&l->list, li);
+		goto done;
+	}
+	t->size++;
+	l = leaf_new();
+
+	if (!l) {
+		*err = -ENOMEM;
+		goto err;
+	}
+
+	l->key = key;
+	li = leaf_info_new(plen);
+
+	if (!li) {
+		tnode_free((struct tnode *) l);
+		*err = -ENOMEM;
+		goto err;
+	}
+
+	fa_head = &li->falh;
+	insert_leaf_info(&l->list, li);
+
+	/* Case 2: n is NULL, and will just insert a new leaf */
+	if (t->trie && n == NULL) {
+
+		NODE_SET_PARENT(l, tp);
+	
+		if (!tp)
+			BUG();
+
+		else {
+			cindex = tkey_extract_bits(key, tp->pos, tp->bits);
+			put_child(t, (struct tnode *)tp, cindex, (struct node *)l);
+		}
+	}
+	/* Case 3: n is a LEAF or a TNODE and the key doesn't match. */
+	else {
+		/*
+		 *  Add a new tnode here
+		 *  first tnode need some special handling
+		 */
+
+		if (tp)
+			pos=tp->pos+tp->bits;
+		else
+			pos=0;
+		if (n) {
+			newpos = tkey_mismatch(key, pos, n->key);
+			tn = tnode_new(n->key, newpos, 1);
+		}
+		else {
+			newpos = 0;
+			tn = tnode_new(key, newpos, 1); /* First tnode */
+		}
+
+		if (!tn) {
+			free_leaf_info(li);
+			tnode_free((struct tnode *) l);
+			*err = -ENOMEM;
+			goto err;
+		}		
+		
+		NODE_SET_PARENT(tn, tp);
+
+		missbit=tkey_extract_bits(key, newpos, 1);
+		put_child(t, tn, missbit, (struct node *)l);
+		put_child(t, tn, 1-missbit, n);
+
+		if (tp) {
+			cindex = tkey_extract_bits(key, tp->pos, tp->bits);
+			put_child(t, (struct tnode *)tp, cindex, (struct node *)tn);
+		}
+		else {
+			t->trie = (struct node*) tn; /* First tnode */
+			tp = tn;
+		}
+	}
+	if (tp && tp->pos+tp->bits > 32) {
+		printk("ERROR tp=%p pos=%d, bits=%d, key=%0x plen=%d\n",
+		       tp, tp->pos, tp->bits, key, plen);
+	}
+	/* Rebalance the trie */
+	t->trie = trie_rebalance(t, tp);
+done:
+	t->revision++;
+err:;
+	return fa_head;
+}
+
+static int
+fn_trie_insert(struct fib_table *tb, struct rtmsg *r, struct kern_rta *rta,
+	       struct nlmsghdr *nlhdr, struct netlink_skb_parms *req)
+{
+	struct trie *t = (struct trie *) tb->tb_data;
+	struct fib_alias *fa, *new_fa;
+	struct list_head *fa_head = NULL;
+	struct fib_info *fi;
+	int plen = r->rtm_dst_len;
+	int type = r->rtm_type;
+	u8 tos = r->rtm_tos;
+	u32 key, mask;
+	int err;
+	struct leaf *l;
+
+	if (plen > 32)
+		return -EINVAL;
+
+	key = 0;
+	if (rta->rta_dst)
+		memcpy(&key, rta->rta_dst, 4);
+
+	key = ntohl(key);
+
+	if (trie_debug)
+		printk("Insert table=%d %08x/%d\n", tb->tb_id, key, plen);
+
+	mask = ntohl( inet_make_mask(plen) );
+
+	if (key & ~mask)
+		return -EINVAL;
+
+	key = key & mask;
+
+	if  ((fi = fib_create_info(r, rta, nlhdr, &err)) == NULL)
+		goto err;
+
+	l = fib_find_node(t, key);
+	fa = NULL;
+
+	if (l) {
+		fa_head = get_fa_head(l, plen);
+		fa = fib_find_alias(fa_head, tos, fi->fib_priority);
+	}
+
+	/* Now fa, if non-NULL, points to the first fib alias
+	 * with the same keys [prefix,tos,priority], if such key already
+	 * exists or to the node before which we will insert new one.
+	 *
+	 * If fa is NULL, we will need to allocate a new one and
+	 * insert to the head of f.
+	 *
+	 * If f is NULL, no fib node matched the destination key
+	 * and we need to allocate a new one of those as well.
+	 */
+
+	if (fa &&
+	    fa->fa_info->fib_priority == fi->fib_priority) {
+		struct fib_alias *fa_orig;
+
+		err = -EEXIST;
+		if (nlhdr->nlmsg_flags & NLM_F_EXCL)
+			goto out;
+
+		if (nlhdr->nlmsg_flags & NLM_F_REPLACE) {
+			struct fib_info *fi_drop;
+			u8 state;
+
+			write_lock_bh(&fib_lock);
+
+			fi_drop = fa->fa_info;
+			fa->fa_info = fi;
+			fa->fa_type = type;
+			fa->fa_scope = r->rtm_scope;
+			state = fa->fa_state;
+			fa->fa_state &= ~FA_S_ACCESSED;
+
+			write_unlock_bh(&fib_lock);
+
+			fib_release_info(fi_drop);
+			if (state & FA_S_ACCESSED)
+			  rt_cache_flush(-1);
+
+			    goto succeeded;
+		}
+		/* Error if we find a perfect match which
+		 * uses the same scope, type, and nexthop
+		 * information.
+		 */
+		fa_orig = fa;
+		list_for_each_entry(fa, fa_orig->fa_list.prev, fa_list) {
+			if (fa->fa_tos != tos)
+				break;
+			if (fa->fa_info->fib_priority != fi->fib_priority)
+				break;
+			if (fa->fa_type == type &&
+			    fa->fa_scope == r->rtm_scope &&
+			    fa->fa_info == fi) {
+				goto out;
+			}
+		}
+		if (!(nlhdr->nlmsg_flags & NLM_F_APPEND))
+			fa = fa_orig;
+	}
+	err = -ENOENT;
+	if (!(nlhdr->nlmsg_flags&NLM_F_CREATE))
+		goto out;
+
+	err = -ENOBUFS;
+	new_fa = kmem_cache_alloc(fn_alias_kmem, SLAB_KERNEL);
+	if (new_fa == NULL)
+		goto out;
+
+	new_fa->fa_info = fi;
+	new_fa->fa_tos = tos;
+	new_fa->fa_type = type;
+	new_fa->fa_scope = r->rtm_scope;
+	new_fa->fa_state = 0;
+#if 0
+	new_fa->dst = NULL;
+#endif
+	/*
+	 * Insert new entry to the list.
+	 */
+
+	if (!fa_head) {
+		fa_head = fib_insert_node(t, &err, key, plen);
+		err = 0;
+		if (err)
+			goto out_free_new_fa;
+	}
+
+	write_lock_bh(&fib_lock);
+
+	list_add_tail(&new_fa->fa_list,
+		 (fa ? &fa->fa_list : fa_head));
+
+	write_unlock_bh(&fib_lock);
+
+	rt_cache_flush(-1);
+	rtmsg_fib(RTM_NEWROUTE, htonl(key), new_fa, plen, tb->tb_id, nlhdr, req);
+succeeded:
+	return 0;
+
+out_free_new_fa:
+	kmem_cache_free(fn_alias_kmem, new_fa);
+out:
+	fib_release_info(fi);
+err:;
+	return err;
+}
+
+static inline int check_leaf(struct trie *t, struct leaf *l,  t_key key, int *plen, const struct flowi *flp,
+			     struct fib_result *res)
+{
+	int err, i;
+	t_key mask;
+	struct leaf_info *li;
+	struct hlist_head *hhead = &l->list;
+	struct hlist_node *node;
+
+	hlist_for_each_entry(li, node, hhead, hlist) {
+
+		i = li->plen;
+		mask = ntohl(inet_make_mask(i));
+		if (l->key != (key & mask))
+			continue;
+
+		if ((err = fib_semantic_match(&li->falh, flp, res, l->key, mask, i)) <= 0) {
+			*plen = i;
+#ifdef CONFIG_IP_FIB_TRIE_STATS
+			t->stats.semantic_match_passed++;
+#endif
+			return err;
+		}
+#ifdef CONFIG_IP_FIB_TRIE_STATS
+		t->stats.semantic_match_miss++;
+#endif
+	}
+	return 1;
+}
+
+static int
+fn_trie_lookup(struct fib_table *tb, const struct flowi *flp, struct fib_result *res)
+{
+	struct trie *t = (struct trie *) tb->tb_data;
+	int plen, ret = 0;
+	struct node *n;
+	struct tnode *pn;
+	int pos, bits;
+	t_key key=ntohl(flp->fl4_dst);
+	int chopped_off;
+	t_key cindex = 0;
+	int current_prefix_length = KEYLENGTH;
+	n = t->trie;
+
+	read_lock(&fib_lock);
+	if (!n)
+		goto failed;
+
+#ifdef CONFIG_IP_FIB_TRIE_STATS
+	t->stats.gets++;
+#endif
+
+	/* Just a leaf? */
+	if (IS_LEAF(n)) {
+		if ((ret = check_leaf(t, (struct leaf *)n, key, &plen, flp, res)) <= 0)
+			goto found;
+		goto failed;
+	}
+	pn = (struct tnode *) n;
+	chopped_off = 0;
+
+        while (pn) {
+
+		pos = pn->pos;
+		bits = pn->bits;
+
+		if (!chopped_off)
+			cindex = tkey_extract_bits(MASK_PFX(key, current_prefix_length), pos, bits);
+
+		n = tnode_get_child(pn, cindex);
+
+		if (n == NULL) {
+#ifdef CONFIG_IP_FIB_TRIE_STATS
+			t->stats.null_node_hit++;
+#endif
+			goto backtrace;
+		}
+
+		if (IS_TNODE(n)) {
+#define HL_OPTIMIZE
+#ifdef HL_OPTIMIZE
+			struct tnode *cn = (struct tnode *)n;
+			t_key node_prefix, key_prefix, pref_mismatch;
+			int mp;
+
+			/*
+			 * It's a tnode, and we can do some extra checks here if we
+			 * like, to avoid descending into a dead-end branch.
+			 * This tnode is in the parent's child array at index
+			 * key[p_pos..p_pos+p_bits] but potentially with some bits
+			 * chopped off, so in reality the index may be just a
+			 * subprefix, padded with zero at the end.
+			 * We can also take a look at any skipped bits in this
+			 * tnode - everything up to p_pos is supposed to be ok,
+			 * and the non-chopped bits of the index (se previous
+			 * paragraph) are also guaranteed ok, but the rest is
+			 * considered unknown.
+			 *
+			 * The skipped bits are key[pos+bits..cn->pos].
+			 */
+		
+			/* If current_prefix_length < pos+bits, we are already doing
+			 * actual prefix  matching, which means everything from
+			 * pos+(bits-chopped_off) onward must be zero along some
+			 * branch of this subtree - otherwise there is *no* valid
+			 * prefix present. Here we can only check the skipped
+			 * bits. Remember, since we have already indexed into the
+			 * parent's child array, we know that the bits we chopped of
+			 * *are* zero.
+			 */
+
+			/* NOTA BENE: CHECKING ONLY SKIPPED BITS FOR THE NEW NODE HERE */
+		
+			if (current_prefix_length < pos+bits) {
+				if (tkey_extract_bits(cn->key, current_prefix_length,
+						      cn->pos - current_prefix_length) != 0 ||
+				    !(cn->child[0]))
+					goto backtrace;
+			}
+
+			/*
+			 * If chopped_off=0, the index is fully validated and we
+			 * only need to look at the skipped bits for this, the new,
+			 * tnode. What we actually want to do is to find out if
+			 * these skipped bits match our key perfectly, or if we will
+			 * have to count on finding a matching prefix further down,
+			 * because if we do, we would like to have some way of
+			 * verifying the existence of such a prefix at this point.
+			 */
+
+			/* The only thing we can do at this point is to verify that
+			 * any such matching prefix can indeed be a prefix to our
+			 * key, and if the bits in the node we are inspecting that
+			 * do not match our key are not ZERO, this cannot be true.
+			 * Thus, find out where there is a mismatch (before cn->pos)
+			 * and verify that all the mismatching bits are zero in the
+			 * new tnode's key.
+			 */
+
+			/* Note: We aren't very concerned about the piece of the key
+			 * that precede pn->pos+pn->bits, since these have already been
+			 * checked. The bits after cn->pos aren't checked since these are
+			 * by definition "unknown" at this point. Thus, what we want to
+			 * see is if we are about to enter the "prefix matching" state,
+			 * and in that case verify that the skipped bits that will prevail
+			 * throughout this subtree are zero, as they have to be if we are
+			 * to find a matching prefix.
+			 */
+
+			node_prefix = MASK_PFX(cn->key, cn->pos);
+			key_prefix = MASK_PFX(key, cn->pos);
+			pref_mismatch = key_prefix^node_prefix;
+			mp = 0;
+
+			/* In short: If skipped bits in this node do not match the search
+			 * key, enter the "prefix matching" state.directly.
+			 */
+			if (pref_mismatch) {
+				while (!(pref_mismatch & (1<<(KEYLENGTH-1)))) {
+					mp++;
+					pref_mismatch = pref_mismatch <<1;
+				}
+				key_prefix = tkey_extract_bits(cn->key, mp, cn->pos-mp);
+			
+				if (key_prefix != 0)
+					goto backtrace;
+
+				if (current_prefix_length >= cn->pos)
+					current_prefix_length=mp;
+		       }
+#endif
+		       pn = (struct tnode *)n; /* Descend */
+		       chopped_off = 0;
+		       continue;
+		}
+		if (IS_LEAF(n)) {
+			if ((ret = check_leaf(t, (struct leaf *)n, key, &plen, flp, res)) <= 0)
+				goto found;
+	       }
+backtrace:
+		chopped_off++;
+
+		/* As zero don't change the child key (cindex) */
+		while ((chopped_off <= pn->bits) && !(cindex & (1<<(chopped_off-1)))) {
+			chopped_off++;
+		}
+
+		/* Decrease current_... with bits chopped off */
+		if (current_prefix_length > pn->pos + pn->bits - chopped_off)
+			current_prefix_length = pn->pos + pn->bits - chopped_off;
+	
+		/*
+		 * Either we do the actual chop off according or if we have
+		 * chopped off all bits in this tnode walk up to our parent.
+		 */
+
+		if (chopped_off <= pn->bits)
+			cindex &= ~(1 << (chopped_off-1));
+		else {
+			if (NODE_PARENT(pn) == NULL)
+				goto failed;
+		
+			/* Get Child's index */
+			cindex = tkey_extract_bits(pn->key, NODE_PARENT(pn)->pos, NODE_PARENT(pn)->bits);
+			pn = NODE_PARENT(pn);
+			chopped_off = 0;
+
+#ifdef CONFIG_IP_FIB_TRIE_STATS
+			t->stats.backtrack++;
+#endif
+			goto backtrace;
+		}
+	}
+failed:
+	ret = 1;
+found:
+	read_unlock(&fib_lock);
+	return ret;
+}
+
+static int trie_leaf_remove(struct trie *t, t_key key)
+{
+	t_key cindex;
+	struct tnode *tp = NULL;
+	struct node *n = t->trie;
+	struct leaf *l;
+
+	if (trie_debug)
+		printk("entering trie_leaf_remove(%p)\n", n);
+
+	/* Note that in the case skipped bits, those bits are *not* checked!
+	 * When we finish this, we will have NULL or a T_LEAF, and the
+	 * T_LEAF may or may not match our key.
+	 */
+
+        while (n != NULL && IS_TNODE(n)) {
+		struct tnode *tn = (struct tnode *) n;
+		check_tnode(tn);
+		n = tnode_get_child(tn ,tkey_extract_bits(key, tn->pos, tn->bits));
+
+			if (n && NODE_PARENT(n) != tn) {
+				printk("BUG tn=%p, n->parent=%p\n", tn, NODE_PARENT(n));
+				BUG();
+			}
+        }
+	l = (struct leaf *) n;
+
+	if (!n || !tkey_equals(l->key, key))
+		return 0;
+
+	/*
+	 * Key found.
+	 * Remove the leaf and rebalance the tree
+	 */
+
+	t->revision++;
+	t->size--;
+
+	tp = NODE_PARENT(n);
+	tnode_free((struct tnode *) n);
+
+	if (tp) {
+		cindex = tkey_extract_bits(key, tp->pos, tp->bits);
+		put_child(t, (struct tnode *)tp, cindex, NULL);
+		t->trie = trie_rebalance(t, tp);
+	}
+	else
+		t->trie = NULL;
+
+	return 1;
+}
+
+static int
+fn_trie_delete(struct fib_table *tb, struct rtmsg *r, struct kern_rta *rta,
+	       struct nlmsghdr *nlhdr, struct netlink_skb_parms *req)
+{
+	struct trie *t = (struct trie *) tb->tb_data;
+	u32 key, mask;
+	int plen = r->rtm_dst_len;
+	u8 tos = r->rtm_tos;
+	struct fib_alias *fa, *fa_to_delete;
+	struct list_head *fa_head;
+	struct leaf *l;
+
+	if (plen > 32)
+		return -EINVAL;
+
+	key = 0;
+	if (rta->rta_dst)
+		memcpy(&key, rta->rta_dst, 4);
+
+	key = ntohl(key);
+	mask = ntohl( inet_make_mask(plen) );
+
+	if (key & ~mask)
+		return -EINVAL;
+
+	key = key & mask;
+	l = fib_find_node(t, key);
+
+	if (!l)
+		return -ESRCH;
+
+	fa_head = get_fa_head(l, plen);
+	fa = fib_find_alias(fa_head, tos, 0);
+
+	if (!fa)
+		return -ESRCH;
+
+	if (trie_debug)
+		printk("Deleting %08x/%d tos=%d t=%p\n", key, plen, tos, t);
+
+	fa_to_delete = NULL;
+	fa_head = fa->fa_list.prev;
+	list_for_each_entry(fa, fa_head, fa_list) {
+		struct fib_info *fi = fa->fa_info;
+
+		if (fa->fa_tos != tos)
+			break;
+
+		if ((!r->rtm_type ||
+		     fa->fa_type == r->rtm_type) &&
+		    (r->rtm_scope == RT_SCOPE_NOWHERE ||
+		     fa->fa_scope == r->rtm_scope) &&
+		    (!r->rtm_protocol ||
+		     fi->fib_protocol == r->rtm_protocol) &&
+		    fib_nh_match(r, nlhdr, rta, fi) == 0) {
+			fa_to_delete = fa;
+			break;
+		}
+	}
+
+	if (fa_to_delete) {
+		int kill_li = 0;
+		struct leaf_info *li;
+
+		fa = fa_to_delete;
+		rtmsg_fib(RTM_DELROUTE, htonl(key), fa, plen, tb->tb_id, nlhdr, req);
+
+		l = fib_find_node(t, key);
+		li = find_leaf_info(&l->list, plen);
+
+		write_lock_bh(&fib_lock);
+
+		list_del(&fa->fa_list);
+
+		if (list_empty(fa_head)) {
+			hlist_del(&li->hlist);
+			kill_li = 1;
+		}
+		write_unlock_bh(&fib_lock);
+	
+		if (kill_li)
+			free_leaf_info(li);
+
+		if (hlist_empty(&l->list))
+			trie_leaf_remove(t, key);
+
+		if (fa->fa_state & FA_S_ACCESSED)
+			rt_cache_flush(-1);
+
+		fn_free_alias(fa);
+		return 0;
+	}
+	return -ESRCH;
+}
+
+static int trie_flush_list(struct trie *t, struct list_head *head)
+{
+	struct fib_alias *fa, *fa_node;
+	int found = 0;
+
+	list_for_each_entry_safe(fa, fa_node, head, fa_list) {
+		struct fib_info *fi = fa->fa_info;
+	
+		if (fi && (fi->fib_flags&RTNH_F_DEAD)) {
+
+ 			write_lock_bh(&fib_lock);
+			list_del(&fa->fa_list);
+			write_unlock_bh(&fib_lock);
+
+			fn_free_alias(fa);
+			found++;
+		}
+	}
+	return found;
+}
+
+static int trie_flush_leaf(struct trie *t, struct leaf *l)
+{
+	int found = 0;
+	struct hlist_head *lih = &l->list;
+	struct hlist_node *node, *tmp;
+	struct leaf_info *li = NULL;
+
+	hlist_for_each_entry_safe(li, node, tmp, lih, hlist) {
+		
+		found += trie_flush_list(t, &li->falh);
+
+		if (list_empty(&li->falh)) {
+
+ 			write_lock_bh(&fib_lock);
+			hlist_del(&li->hlist);
+			write_unlock_bh(&fib_lock);
+
+			free_leaf_info(li);
+		}
+	}
+	return found;
+}
+
+static struct leaf *nextleaf(struct trie *t, struct leaf *thisleaf)
+{
+	struct node *c = (struct node *) thisleaf;
+	struct tnode *p;
+	int idx;
+
+	if (c == NULL) {
+		if (t->trie == NULL)
+			return NULL;
+
+		if (IS_LEAF(t->trie))          /* trie w. just a leaf */
+			return (struct leaf *) t->trie;
+
+		p = (struct tnode*) t->trie;  /* Start */
+	}
+	else
+		p = (struct tnode *) NODE_PARENT(c);
+
+	while (p) {
+		int pos, last;
+
+		/*  Find the next child of the parent */
+		if (c)
+			pos = 1 + tkey_extract_bits(c->key, p->pos, p->bits);
+		else
+			pos = 0;
+
+		last = 1 << p->bits;
+		for(idx = pos; idx < last ; idx++) {
+			if (p->child[idx]) {
+
+				/* Decend if tnode */
+
+				while (IS_TNODE(p->child[idx])) {
+					p = (struct tnode*) p->child[idx];
+					idx = 0;
+				
+					/* Rightmost non-NULL branch */
+					if (p && IS_TNODE(p))
+						while (p->child[idx] == NULL && idx < (1 << p->bits)) idx++;
+
+					/* Done with this tnode? */
+					if (idx >= (1 << p->bits) || p->child[idx] == NULL )
+						goto up;
+				}
+				return (struct leaf*) p->child[idx];
+			}
+		}
+up:
+		/* No more children go up one step  */
+		c = (struct node*) p;
+		p = (struct tnode *) NODE_PARENT(p);
+	}
+	return NULL; /* Ready. Root of trie */
+}
+
+static int fn_trie_flush(struct fib_table *tb)
+{
+	struct trie *t = (struct trie *) tb->tb_data;
+	struct leaf *ll = NULL, *l = NULL;
+	int found = 0, h;
+
+	t->revision++;
+
+	for (h=0; (l = nextleaf(t, l)) != NULL; h++) {
+		found += trie_flush_leaf(t, l);
+
+		if (ll && hlist_empty(&ll->list))
+			trie_leaf_remove(t, ll->key);
+		ll = l;
+	}
+
+	if (ll && hlist_empty(&ll->list))
+		trie_leaf_remove(t, ll->key);
+
+	if (trie_debug)
+		printk("trie_flush found=%d\n", found);
+	return found;
+}
+
+static int trie_last_dflt=-1;
+
+static void
+fn_trie_select_default(struct fib_table *tb, const struct flowi *flp, struct fib_result *res)
+{
+	struct trie *t = (struct trie *) tb->tb_data;
+	int order, last_idx;
+	struct fib_info *fi = NULL;
+	struct fib_info *last_resort;
+	struct fib_alias *fa = NULL;
+	struct list_head *fa_head;
+	struct leaf *l;
+
+	last_idx = -1;
+	last_resort = NULL;
+	order = -1;
+
+	read_lock(&fib_lock);
+
+	l = fib_find_node(t, 0);
+	if (!l)
+		goto out;
+
+	fa_head = get_fa_head(l, 0);
+	if (!fa_head)
+		goto out;
+
+	if (list_empty(fa_head))
+		goto out;
+
+	list_for_each_entry(fa, fa_head, fa_list) {
+		struct fib_info *next_fi = fa->fa_info;
+	
+		if (fa->fa_scope != res->scope ||
+		    fa->fa_type != RTN_UNICAST)
+			continue;
+	
+		if (next_fi->fib_priority > res->fi->fib_priority)
+			break;
+		if (!next_fi->fib_nh[0].nh_gw ||
+		    next_fi->fib_nh[0].nh_scope != RT_SCOPE_LINK)
+			continue;
+		fa->fa_state |= FA_S_ACCESSED;
+	
+		if (fi == NULL) {
+			if (next_fi != res->fi)
+				break;
+		} else if (!fib_detect_death(fi, order, &last_resort,
+					     &last_idx, &trie_last_dflt)) {
+			if (res->fi)
+				fib_info_put(res->fi);
+			res->fi = fi;
+			atomic_inc(&fi->fib_clntref);
+			trie_last_dflt = order;
+			goto out;
+		}
+		fi = next_fi;
+		order++;
+	}
+	if (order <= 0 || fi == NULL) {
+		trie_last_dflt = -1;
+		goto out;
+	}
+
+	if (!fib_detect_death(fi, order, &last_resort, &last_idx, &trie_last_dflt)) {
+		if (res->fi)
+			fib_info_put(res->fi);
+		res->fi = fi;
+		atomic_inc(&fi->fib_clntref);
+		trie_last_dflt = order;
+		goto out;
+	}
+	if (last_idx >= 0) {
+		if (res->fi)
+			fib_info_put(res->fi);
+		res->fi = last_resort;
+		if (last_resort)
+			atomic_inc(&last_resort->fib_clntref);
+	}
+	trie_last_dflt = last_idx;
+ out:;
+	read_unlock(&fib_lock);
+}
+
+static int fn_trie_dump_fa(t_key key, int plen, struct list_head *fah, struct fib_table *tb,
+			   struct sk_buff *skb, struct netlink_callback *cb)
+{
+	int i, s_i;
+	struct fib_alias *fa;
+
+	u32 xkey=htonl(key);
+
+	s_i=cb->args[3];
+	i = 0;
+
+	list_for_each_entry(fa, fah, fa_list) {
+		if (i < s_i) {
+			i++;
+			continue;
+		}
+		if (fa->fa_info->fib_nh == NULL) {
+			printk("Trie error _fib_nh=NULL in fa[%d] k=%08x plen=%d\n", i, key, plen);
+			i++;
+			continue;
+		}
+		if (fa->fa_info == NULL) {
+			printk("Trie error fa_info=NULL in fa[%d] k=%08x plen=%d\n", i, key, plen);
+			i++;
+			continue;
+		}
+
+		if (fib_dump_info(skb, NETLINK_CB(cb->skb).pid,
+				  cb->nlh->nlmsg_seq,
+				  RTM_NEWROUTE,
+				  tb->tb_id,
+				  fa->fa_type,
+				  fa->fa_scope,
+				  &xkey,
+				  plen,
+				  fa->fa_tos,
+				  fa->fa_info, 0) < 0) {
+			cb->args[3] = i;
+			return -1;
+			}
+		i++;
+	}
+	cb->args[3]=i;
+	return skb->len;
+}
+
+static int fn_trie_dump_plen(struct trie *t, int plen, struct fib_table *tb, struct sk_buff *skb,
+			     struct netlink_callback *cb)
+{
+	int h, s_h;
+	struct list_head *fa_head;
+	struct leaf *l = NULL;
+	s_h=cb->args[2];
+
+	for (h=0; (l = nextleaf(t, l)) != NULL; h++) {
+
+		if (h < s_h)
+			continue;
+		if (h > s_h)
+			memset(&cb->args[3], 0,
+			       sizeof(cb->args) - 3*sizeof(cb->args[0]));
+
+		fa_head = get_fa_head(l, plen);
+	
+		if (!fa_head)
+			continue;
+
+		if (list_empty(fa_head))
+			continue;
+
+		if (fn_trie_dump_fa(l->key, plen, fa_head, tb, skb, cb)<0) {
+			cb->args[2]=h;
+			return -1;
+		}
+	}
+	cb->args[2]=h;
+	return skb->len;
+}
+
+static int fn_trie_dump(struct fib_table *tb, struct sk_buff *skb, struct netlink_callback *cb)
+{
+	int m, s_m;
+	struct trie *t = (struct trie *) tb->tb_data;
+
+	s_m = cb->args[1];
+
+	read_lock(&fib_lock);
+	for (m=0; m<=32; m++) {
+
+		if (m < s_m)
+			continue;
+		if (m > s_m)
+			memset(&cb->args[2], 0,
+			       sizeof(cb->args) - 2*sizeof(cb->args[0]));
+
+		if (fn_trie_dump_plen(t, 32-m, tb, skb, cb)<0) {
+			cb->args[1] = m;
+			goto out;
+		}
+	}
+	read_unlock(&fib_lock);
+	cb->args[1] = m;
+	return skb->len;
+ out:
+	read_unlock(&fib_lock);
+	return -1;
+}
+
+/* Fix more generic FIB names for init later */
+
+#ifdef CONFIG_IP_MULTIPLE_TABLES
+struct fib_table * fib_hash_init(int id)
+#else
+struct fib_table * __init fib_hash_init(int id)
+#endif
+{
+	struct fib_table *tb;
+	struct trie *t;
+
+	if (fn_alias_kmem == NULL)
+		fn_alias_kmem = kmem_cache_create("ip_fib_alias",
+						  sizeof(struct fib_alias),
+						  0, SLAB_HWCACHE_ALIGN,
+						  NULL, NULL);
+
+	tb = kmalloc(sizeof(struct fib_table) + sizeof(struct trie),
+		     GFP_KERNEL);
+	if (tb == NULL)
+		return NULL;
+
+	tb->tb_id = id;
+	tb->tb_lookup = fn_trie_lookup;
+	tb->tb_insert = fn_trie_insert;
+	tb->tb_delete = fn_trie_delete;
+	tb->tb_flush = fn_trie_flush;
+	tb->tb_select_default = fn_trie_select_default;
+	tb->tb_dump = fn_trie_dump;
+	memset(tb->tb_data, 0, sizeof(struct trie));
+
+	t = (struct trie *) tb->tb_data;
+
+	trie_init(t);
+
+	if (id == RT_TABLE_LOCAL)
+                trie_local = t;
+	else if (id == RT_TABLE_MAIN)
+                trie_main = t;
+
+	if (id == RT_TABLE_LOCAL)
+		printk("IPv4 FIB: Using LC-trie version %s\n", VERSION);
+
+	return tb;
+}
+
+/* Trie dump functions */
+
+static void putspace_seq(struct seq_file *seq, int n)
+{
+	while (n--) seq_printf(seq, " ");
+}
+
+static void printbin_seq(struct seq_file *seq, unsigned int v, int bits)
+{
+	while (bits--)
+		seq_printf(seq, "%s", (v & (1<<bits))?"1":"0");
+}
+
+static void printnode_seq(struct seq_file *seq, int indent, struct node *n,
+		   int pend, int cindex, int bits)
+{
+	putspace_seq(seq, indent);
+	if (IS_LEAF(n))
+		seq_printf(seq, "|");
+	else
+		seq_printf(seq, "+");
+	if (bits) {
+		seq_printf(seq, "%d/", cindex);
+		printbin_seq(seq, cindex, bits);
+		seq_printf(seq, ": ");
+	}
+	else
+		seq_printf(seq, "<root>: ");
+	seq_printf(seq, "%s:%p ", IS_LEAF(n)?"Leaf":"Internal node", n);
+
+	if (IS_LEAF(n))
+		seq_printf(seq, "key=%d.%d.%d.%d\n",
+			   n->key >> 24, (n->key >> 16) % 256, (n->key >> 8) % 256, n->key % 256);
+	else {
+		int plen = ((struct tnode *)n)->pos;
+		t_key prf=MASK_PFX(n->key, plen);
+		seq_printf(seq, "key=%d.%d.%d.%d/%d\n",
+			   prf >> 24, (prf >> 16) % 256, (prf >> 8) % 256, prf % 256, plen);
+	}
+	if (IS_LEAF(n)) {
+		struct leaf *l=(struct leaf *)n;
+		struct fib_alias *fa;
+		int i;
+		for (i=32; i>=0; i--)
+		  if (find_leaf_info(&l->list, i)) {
+		
+				struct list_head *fa_head = get_fa_head(l, i);
+			
+				if (!fa_head)
+					continue;
+
+				if (list_empty(fa_head))
+					continue;
+
+				putspace_seq(seq, indent+2);
+				seq_printf(seq, "{/%d...dumping}\n", i);
+
+
+				list_for_each_entry(fa, fa_head, fa_list) {
+					putspace_seq(seq, indent+2);
+					if (fa->fa_info->fib_nh == NULL) {
+						seq_printf(seq, "Error _fib_nh=NULL\n");
+						continue;
+					}
+					if (fa->fa_info == NULL) {
+						seq_printf(seq, "Error fa_info=NULL\n");
+						continue;
+					}
+
+					seq_printf(seq, "{type=%d scope=%d TOS=%d}\n",
+					      fa->fa_type,
+					      fa->fa_scope,
+					      fa->fa_tos);
+				}
+			}
+	}
+	else if (IS_TNODE(n)) {
+		struct tnode *tn = (struct tnode *)n;
+		putspace_seq(seq, indent); seq_printf(seq, "|    ");
+		seq_printf(seq, "{key prefix=%08x/", tn->key&TKEY_GET_MASK(0, tn->pos));
+		printbin_seq(seq, tkey_extract_bits(tn->key, 0, tn->pos), tn->pos);
+		seq_printf(seq, "}\n");
+		putspace_seq(seq, indent); seq_printf(seq, "|    ");
+		seq_printf(seq, "{pos=%d", tn->pos);
+		seq_printf(seq, " (skip=%d bits)", tn->pos - pend);
+		seq_printf(seq, " bits=%d (%u children)}\n", tn->bits, (1 << tn->bits));
+		putspace_seq(seq, indent); seq_printf(seq, "|    ");
+		seq_printf(seq, "{empty=%d full=%d}\n", tn->empty_children, tn->full_children);
+	}
+}
+
+static void trie_dump_seq(struct seq_file *seq, struct trie *t)
+{
+	struct node *n = t->trie;
+	int cindex=0;
+	int indent=1;
+	int pend=0;
+	int depth = 0;
+
+  	read_lock(&fib_lock);
+
+	seq_printf(seq, "------ trie_dump of t=%p ------\n", t);
+	if (n) {
+		printnode_seq(seq, indent, n, pend, cindex, 0);
+		if (IS_TNODE(n)) {
+			struct tnode *tn = (struct tnode *)n;
+			pend = tn->pos+tn->bits;
+			putspace_seq(seq, indent); seq_printf(seq, "\\--\n");
+			indent += 3;
+			depth++;
+
+			while (tn && cindex < (1 << tn->bits)) {
+				if (tn->child[cindex]) {
+				
+					/* Got a child */
+				
+					printnode_seq(seq, indent, tn->child[cindex], pend, cindex, tn->bits);
+					if (IS_LEAF(tn->child[cindex])) {
+						cindex++;
+					
+					}
+					else {
+						/*
+						 * New tnode. Decend one level
+						 */
+					
+						depth++;
+						n = tn->child[cindex];
+						tn = (struct tnode *)n;
+						pend = tn->pos+tn->bits;
+						putspace_seq(seq, indent); seq_printf(seq, "\\--\n");
+						indent+=3;
+						cindex=0;
+					}
+				}
+				else
+					cindex++;
+
+				/*
+				 * Test if we are done
+				 */
+			
+				while (cindex >= (1 << tn->bits)) {
+
+					/*
+					 * Move upwards and test for root
+					 * pop off all traversed  nodes
+					 */
+				
+					if (NODE_PARENT(tn) == NULL) {
+						tn = NULL;
+						n = NULL;
+						break;
+					}
+					else {
+						cindex = tkey_extract_bits(tn->key, NODE_PARENT(tn)->pos, NODE_PARENT(tn)->bits);
+						tn = NODE_PARENT(tn);
+						cindex++;
+						n = (struct node *)tn;
+						pend = tn->pos+tn->bits;
+						indent-=3;
+						depth--;
+					}
+				}
+			}
+		}
+		else n = NULL;
+	}
+	else seq_printf(seq, "------ trie is empty\n");
+
+  	read_unlock(&fib_lock);
+}
+
+static struct trie_stat *trie_stat_new(void)
+{
+	struct trie_stat *s = kmalloc(sizeof(struct trie_stat), GFP_KERNEL);
+	int i;
+
+	if (s) {
+		s->totdepth = 0;
+		s->maxdepth = 0;
+		s->tnodes = 0;
+		s->leaves = 0;
+		s->nullpointers = 0;
+	
+		for(i=0; i< MAX_CHILDS; i++)
+			s->nodesizes[i] = 0;
+	}
+	return s;
+}
+
+static struct trie_stat *trie_collect_stats(struct trie *t)
+{
+	struct node *n = t->trie;
+	struct trie_stat *s = trie_stat_new();
+	int cindex = 0;
+	int indent = 1;
+	int pend = 0;
+	int depth = 0;
+
+	read_lock(&fib_lock);	
+
+	if (s) {
+		if (n) {
+			if (IS_TNODE(n)) {
+				struct tnode *tn = (struct tnode *)n;
+				pend = tn->pos+tn->bits;
+				indent += 3;
+				s->nodesizes[tn->bits]++;
+				depth++;
+
+				while (tn && cindex < (1 << tn->bits)) {
+					if (tn->child[cindex]) {
+						/* Got a child */
+				
+						if (IS_LEAF(tn->child[cindex])) {
+							cindex++;
+					
+							/* stats */
+							if (depth > s->maxdepth)
+								s->maxdepth = depth;
+							s->totdepth += depth;
+							s->leaves++;
+						}
+				
+						else {
+							/*
+							 * New tnode. Decend one level
+							 */
+					
+							s->tnodes++;
+							s->nodesizes[tn->bits]++;
+							depth++;
+					
+							n = tn->child[cindex];
+							tn = (struct tnode *)n;
+							pend = tn->pos+tn->bits;
+
+							indent += 3;
+							cindex = 0;
+						}
+					}
+					else {
+						cindex++;
+						s->nullpointers++;
+					}
+
+					/*
+					 * Test if we are done
+					 */
+			
+					while (cindex >= (1 << tn->bits)) {
+
+						/*
+						 * Move upwards and test for root
+						 * pop off all traversed  nodes
+						 */
+
+					
+						if (NODE_PARENT(tn) == NULL) {
+							tn = NULL;
+							n = NULL;
+							break;
+						}
+						else {
+							cindex = tkey_extract_bits(tn->key, NODE_PARENT(tn)->pos, NODE_PARENT(tn)->bits);
+							tn = NODE_PARENT(tn);
+							cindex++;
+							n = (struct node *)tn;
+							pend = tn->pos+tn->bits;
+							indent -= 3;
+							depth--;
+						}
+ 					}
+				}
+			}
+			else n = NULL;
+		}
+	}
+
+	read_unlock(&fib_lock);	
+	return s;
+}
+
+#ifdef CONFIG_PROC_FS
+
+static struct fib_alias *fib_triestat_get_first(struct seq_file *seq)
+{
+	return NULL;
+}
+
+static struct fib_alias *fib_triestat_get_next(struct seq_file *seq)
+{
+	return NULL;
+}
+
+static void *fib_triestat_seq_start(struct seq_file *seq, loff_t *pos)
+{
+	void *v = NULL;
+
+	if (ip_fib_main_table)
+		v = *pos ? fib_triestat_get_next(seq) : SEQ_START_TOKEN;
+	return v;
+}
+
+static void *fib_triestat_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+	++*pos;
+	return v == SEQ_START_TOKEN ? fib_triestat_get_first(seq) : fib_triestat_get_next(seq);
+}
+
+static void fib_triestat_seq_stop(struct seq_file *seq, void *v)
+{
+
+}
+
+/*
+ *	This outputs /proc/net/fib_triestats
+ *
+ *	It always works in backward compatibility mode.
+ *	The format of the file is not supposed to be changed.
+ */
+
+static void collect_and_show(struct trie *t, struct seq_file *seq)
+{
+	int bytes = 0; /* How many bytes are used, a ref is 4 bytes */
+	int i, max, pointers;
+        struct trie_stat *stat;
+	int avdepth;
+
+	stat = trie_collect_stats(t);
+
+	bytes=0;
+	seq_printf(seq, "trie=%p\n", t);
+
+	if (stat) {
+		if (stat->leaves)
+			avdepth=stat->totdepth*100 / stat->leaves;
+		else
+			avdepth=0;
+		seq_printf(seq, "Aver depth: %d.%02d\n", avdepth / 100, avdepth % 100 );
+		seq_printf(seq, "Max depth: %4d\n", stat->maxdepth);
+			
+		seq_printf(seq, "Leaves: %d\n", stat->leaves);
+		bytes += sizeof(struct leaf) * stat->leaves;
+		seq_printf(seq, "Internal nodes: %d\n", stat->tnodes);
+		bytes += sizeof(struct tnode) * stat->tnodes;
+
+		max = MAX_CHILDS-1;
+
+		while (max >= 0 && stat->nodesizes[max] == 0)
+			max--;
+		pointers = 0;
+
+		for (i = 1; i <= max; i++)
+			if (stat->nodesizes[i] != 0) {
+				seq_printf(seq, "  %d: %d",  i, stat->nodesizes[i]);
+				pointers += (1<<i) * stat->nodesizes[i];
+			}
+		seq_printf(seq, "\n");
+		seq_printf(seq, "Pointers: %d\n", pointers);
+		bytes += sizeof(struct node *) * pointers;
+		seq_printf(seq, "Null ptrs: %d\n", stat->nullpointers);
+		seq_printf(seq, "Total size: %d  kB\n", bytes / 1024);
+
+		kfree(stat);
+	}
+
+#ifdef CONFIG_IP_FIB_TRIE_STATS
+	seq_printf(seq, "Counters:\n---------\n");
+	seq_printf(seq,"gets = %d\n", t->stats.gets);
+	seq_printf(seq,"backtracks = %d\n", t->stats.backtrack);
+	seq_printf(seq,"semantic match passed = %d\n", t->stats.semantic_match_passed);
+	seq_printf(seq,"semantic match miss = %d\n", t->stats.semantic_match_miss);
+	seq_printf(seq,"null node hit= %d\n", t->stats.null_node_hit);
+	seq_printf(seq,"skipped node resize = %d\n", t->stats.resize_node_skipped);
+#ifdef CLEAR_STATS
+	memset(&(t->stats), 0, sizeof(t->stats));
+#endif
+#endif /*  CONFIG_IP_FIB_TRIE_STATS */
+}
+
+static int fib_triestat_seq_show(struct seq_file *seq, void *v)
+{
+	char bf[128];
+
+	if (v == SEQ_START_TOKEN) {
+		seq_printf(seq, "Basic info: size of leaf: %Zd bytes, size of tnode: %Zd bytes.\n",
+			   sizeof(struct leaf), sizeof(struct tnode));
+		if (trie_local)
+			collect_and_show(trie_local, seq);
+
+		if (trie_main)
+			collect_and_show(trie_main, seq);
+	}
+	else {
+		snprintf(bf, sizeof(bf),
+			 "*\t%08X\t%08X", 200, 400);
+	
+		seq_printf(seq, "%-127s\n", bf);
+	}
+	return 0;
+}
+
+static struct seq_operations fib_triestat_seq_ops = {
+	.start = fib_triestat_seq_start,
+	.next  = fib_triestat_seq_next,
+	.stop  = fib_triestat_seq_stop,
+	.show  = fib_triestat_seq_show,
+};
+
+static int fib_triestat_seq_open(struct inode *inode, struct file *file)
+{
+	struct seq_file *seq;
+	int rc = -ENOMEM;
+
+	rc = seq_open(file, &fib_triestat_seq_ops);
+	if (rc)
+		goto out_kfree;
+
+	seq = file->private_data;
+out:
+	return rc;
+out_kfree:
+	goto out;
+}
+
+static struct file_operations fib_triestat_seq_fops = {
+	.owner	= THIS_MODULE,
+	.open	= fib_triestat_seq_open,
+	.read	= seq_read,
+	.llseek	= seq_lseek,
+	.release = seq_release_private,
+};
+
+int __init fib_stat_proc_init(void)
+{
+	if (!proc_net_fops_create("fib_triestat", S_IRUGO, &fib_triestat_seq_fops))
+		return -ENOMEM;
+	return 0;
+}
+
+void __init fib_stat_proc_exit(void)
+{
+	proc_net_remove("fib_triestat");
+}
+
+static struct fib_alias *fib_trie_get_first(struct seq_file *seq)
+{
+	return NULL;
+}
+
+static struct fib_alias *fib_trie_get_next(struct seq_file *seq)
+{
+	return NULL;
+}
+
+static void *fib_trie_seq_start(struct seq_file *seq, loff_t *pos)
+{
+	void *v = NULL;
+
+	if (ip_fib_main_table)
+		v = *pos ? fib_trie_get_next(seq) : SEQ_START_TOKEN;
+	return v;
+}
+
+static void *fib_trie_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+	++*pos;
+	return v == SEQ_START_TOKEN ? fib_trie_get_first(seq) : fib_trie_get_next(seq);
+}
+
+static void fib_trie_seq_stop(struct seq_file *seq, void *v)
+{
+
+}
+
+/*
+ *	This outputs /proc/net/fib_trie.
+ *
+ *	It always works in backward compatibility mode.
+ *	The format of the file is not supposed to be changed.
+ */
+
+static int fib_trie_seq_show(struct seq_file *seq, void *v)
+{
+	char bf[128];
+
+	if (v == SEQ_START_TOKEN) {
+		if (trie_local)
+			trie_dump_seq(seq, trie_local);
+
+		if (trie_main)
+			trie_dump_seq(seq, trie_main);
+	}
+
+	else {
+		snprintf(bf, sizeof(bf),
+			 "*\t%08X\t%08X", 200, 400);
+		seq_printf(seq, "%-127s\n", bf);
+	}
+
+	return 0;
+}
+
+static struct seq_operations fib_trie_seq_ops = {
+	.start = fib_trie_seq_start,
+	.next  = fib_trie_seq_next,
+	.stop  = fib_trie_seq_stop,
+	.show  = fib_trie_seq_show,
+};
+
+static int fib_trie_seq_open(struct inode *inode, struct file *file)
+{
+	struct seq_file *seq;
+	int rc = -ENOMEM;
+
+	rc = seq_open(file, &fib_trie_seq_ops);
+	if (rc)
+		goto out_kfree;
+
+	seq = file->private_data;
+out:
+	return rc;
+out_kfree:
+	goto out;
+}
+
+static struct file_operations fib_trie_seq_fops = {
+	.owner	= THIS_MODULE,
+	.open	= fib_trie_seq_open,
+	.read	= seq_read,
+	.llseek	= seq_lseek,
+	.release= seq_release_private,
+};
+
+int __init fib_proc_init(void)
+{
+	if (!proc_net_fops_create("fib_trie", S_IRUGO, &fib_trie_seq_fops))
+		return -ENOMEM;
+	return 0;
+}
+
+void __init fib_proc_exit(void)
+{
+	proc_net_remove("fib_trie");
+}
+
+#endif /* CONFIG_PROC_FS */
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -349,12 +349,12 @@ static void icmp_push_reply(struct icmp_
 {
 	struct sk_buff *skb;
 
-	ip_append_data(icmp_socket->sk, icmp_glue_bits, icmp_param,
-		       icmp_param->data_len+icmp_param->head_len,
-		       icmp_param->head_len,
-		       ipc, rt, MSG_DONTWAIT);
-
-	if ((skb = skb_peek(&icmp_socket->sk->sk_write_queue)) != NULL) {
+	if (ip_append_data(icmp_socket->sk, icmp_glue_bits, icmp_param,
+		           icmp_param->data_len+icmp_param->head_len,
+		           icmp_param->head_len,
+		           ipc, rt, MSG_DONTWAIT) < 0)
+		ip_flush_pending_frames(icmp_socket->sk);
+	else if ((skb = skb_peek(&icmp_socket->sk->sk_write_queue)) != NULL) {
 		struct icmphdr *icmph = skb->h.icmph;
 		unsigned int csum = 0;
 		struct sk_buff *skb1;
@@ -936,8 +936,7 @@ int icmp_rcv(struct sk_buff *skb)
 	case CHECKSUM_HW:
 		if (!(u16)csum_fold(skb->csum))
 			break;
-		NETDEBUG(if (net_ratelimit())
-				printk(KERN_DEBUG "icmp v4 hw csum failure\n"));
+		LIMIT_NETDEBUG(printk(KERN_DEBUG "icmp v4 hw csum failure\n"));
 	case CHECKSUM_NONE:
 		if ((u16)csum_fold(skb_checksum(skb, 0, skb->len, 0)))
 			goto error;
@@ -970,7 +969,8 @@ int icmp_rcv(struct sk_buff *skb)
 		 *	RFC 1122: 3.2.2.8 An ICMP_TIMESTAMP MAY be silently
 		 *	  discarded if to broadcast/multicast.
 		 */
-		if (icmph->type == ICMP_ECHO &&
+		if ((icmph->type == ICMP_ECHO ||
+		     icmph->type == ICMP_TIMESTAMP) &&
 		    sysctl_icmp_echo_ignore_broadcasts) {
 			goto error;
 		}
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -1615,9 +1615,10 @@ int ip_mc_join_group(struct sock *sk , s
 {
 	int err;
 	u32 addr = imr->imr_multiaddr.s_addr;
-	struct ip_mc_socklist *iml, *i;
+	struct ip_mc_socklist *iml=NULL, *i;
 	struct in_device *in_dev;
 	struct inet_sock *inet = inet_sk(sk);
+	int ifindex;
 	int count = 0;
 
 	if (!MULTICAST(addr))
@@ -1633,37 +1634,30 @@ int ip_mc_join_group(struct sock *sk , s
 		goto done;
 	}
 
-	iml = (struct ip_mc_socklist *)sock_kmalloc(sk, sizeof(*iml), GFP_KERNEL);
-
 	err = -EADDRINUSE;
+	ifindex = imr->imr_ifindex;
 	for (i = inet->mc_list; i; i = i->next) {
-		if (memcmp(&i->multi, imr, sizeof(*imr)) == 0) {
-			/* New style additions are reference counted */
-			if (imr->imr_address.s_addr == 0) {
-				i->count++;
-				err = 0;
-			}
+		if (i->multi.imr_multiaddr.s_addr == addr &&
+		    i->multi.imr_ifindex == ifindex)
 			goto done;
-		}
 		count++;
 	}
 	err = -ENOBUFS;
-	if (iml == NULL || count >= sysctl_igmp_max_memberships)
+	if (count >= sysctl_igmp_max_memberships)
+		goto done;
+	iml = (struct ip_mc_socklist *)sock_kmalloc(sk,sizeof(*iml),GFP_KERNEL);
+	if (iml == NULL)
 		goto done;
+
 	memcpy(&iml->multi, imr, sizeof(*imr));
 	iml->next = inet->mc_list;
-	iml->count = 1;
 	iml->sflist = NULL;
 	iml->sfmode = MCAST_EXCLUDE;
 	inet->mc_list = iml;
 	ip_mc_inc_group(in_dev, addr);
-	iml = NULL;
 	err = 0;
-
 done:
 	rtnl_shunlock();
-	if (iml)
-		sock_kfree_s(sk, iml, sizeof(*iml));
 	return err;
 }
 
@@ -1693,30 +1687,25 @@ int ip_mc_leave_group(struct sock *sk, s
 {
 	struct inet_sock *inet = inet_sk(sk);
 	struct ip_mc_socklist *iml, **imlp;
+	struct in_device *in_dev;
+	u32 group = imr->imr_multiaddr.s_addr;
+	u32 ifindex;
 
 	rtnl_lock();
+	in_dev = ip_mc_find_dev(imr);
+	if (!in_dev) {
+		rtnl_unlock();
+		return -ENODEV;
+	}
+	ifindex = imr->imr_ifindex;
 	for (imlp = &inet->mc_list; (iml = *imlp) != NULL; imlp = &iml->next) {
-		if (iml->multi.imr_multiaddr.s_addr==imr->imr_multiaddr.s_addr &&
-		    iml->multi.imr_address.s_addr==imr->imr_address.s_addr &&
-		    (!imr->imr_ifindex || iml->multi.imr_ifindex==imr->imr_ifindex)) {
-			struct in_device *in_dev;
-
-			in_dev = inetdev_by_index(iml->multi.imr_ifindex);
-			if (in_dev)
-				(void) ip_mc_leave_src(sk, iml, in_dev);
-			if (--iml->count) {
-				rtnl_unlock();
-				if (in_dev)
-					in_dev_put(in_dev);
-				return 0;
-			}
+		if (iml->multi.imr_multiaddr.s_addr == group &&
+		    iml->multi.imr_ifindex == ifindex) {
+			(void) ip_mc_leave_src(sk, iml, in_dev);
 
 			*imlp = iml->next;
 
-			if (in_dev) {
-				ip_mc_dec_group(in_dev, imr->imr_multiaddr.s_addr);
-				in_dev_put(in_dev);
-			}
+			ip_mc_dec_group(in_dev, group);
 			rtnl_unlock();
 			sock_kfree_s(sk, iml, sizeof(*iml));
 			return 0;
@@ -1736,6 +1725,7 @@ int ip_mc_source(int add, int omode, str
 	struct in_device *in_dev = NULL;
 	struct inet_sock *inet = inet_sk(sk);
 	struct ip_sf_socklist *psl;
+	int leavegroup = 0;
 	int i, j, rv;
 
 	if (!MULTICAST(addr))
@@ -1755,15 +1745,20 @@ int ip_mc_source(int add, int omode, str
 	err = -EADDRNOTAVAIL;
 
 	for (pmc=inet->mc_list; pmc; pmc=pmc->next) {
-		if (memcmp(&pmc->multi, mreqs, 2*sizeof(__u32)) == 0)
+		if (pmc->multi.imr_multiaddr.s_addr == imr.imr_multiaddr.s_addr
+		    && pmc->multi.imr_ifindex == imr.imr_ifindex)
 			break;
 	}
-	if (!pmc)		/* must have a prior join */
+	if (!pmc) {		/* must have a prior join */
+		err = -EINVAL;
 		goto done;
+	}
 	/* if a source filter was set, must be the same mode as before */
 	if (pmc->sflist) {
-		if (pmc->sfmode != omode)
+		if (pmc->sfmode != omode) {
+			err = -EINVAL;
 			goto done;
+		}
 	} else if (pmc->sfmode != omode) {
 		/* allow mode switches for empty-set filters */
 		ip_mc_add_src(in_dev, &mreqs->imr_multiaddr, omode, 0, NULL, 0);
@@ -1775,7 +1770,7 @@ int ip_mc_source(int add, int omode, str
 	psl = pmc->sflist;
 	if (!add) {
 		if (!psl)
-			goto done;
+			goto done;	/* err = -EADDRNOTAVAIL */
 		rv = !0;
 		for (i=0; i<psl->sl_count; i++) {
 			rv = memcmp(&psl->sl_addr[i], &mreqs->imr_sourceaddr,
@@ -1784,7 +1779,13 @@ int ip_mc_source(int add, int omode, str
 				break;
 		}
 		if (rv)		/* source not found */
+			goto done;	/* err = -EADDRNOTAVAIL */
+
+		/* special case - (INCLUDE, empty) == LEAVE_GROUP */
+		if (psl->sl_count == 1 && omode == MCAST_INCLUDE) {
+			leavegroup = 1;
 			goto done;
+		}
 
 		/* update the interface filter */
 		ip_mc_del_src(in_dev, &mreqs->imr_multiaddr, omode, 1, 
@@ -1842,18 +1843,21 @@ int ip_mc_source(int add, int omode, str
 		&mreqs->imr_sourceaddr, 1);
 done:
 	rtnl_shunlock();
+	if (leavegroup)
+		return ip_mc_leave_group(sk, &imr);
 	return err;
 }
 
 int ip_mc_msfilter(struct sock *sk, struct ip_msfilter *msf, int ifindex)
 {
-	int err;
+	int err = 0;
 	struct ip_mreqn	imr;
 	u32 addr = msf->imsf_multiaddr;
 	struct ip_mc_socklist *pmc;
 	struct in_device *in_dev;
 	struct inet_sock *inet = inet_sk(sk);
 	struct ip_sf_socklist *newpsl, *psl;
+	int leavegroup = 0;
 
 	if (!MULTICAST(addr))
 		return -EINVAL;
@@ -1872,15 +1876,22 @@ int ip_mc_msfilter(struct sock *sk, stru
 		err = -ENODEV;
 		goto done;
 	}
-	err = -EADDRNOTAVAIL;
+
+	/* special case - (INCLUDE, empty) == LEAVE_GROUP */
+	if (msf->imsf_fmode == MCAST_INCLUDE && msf->imsf_numsrc == 0) {
+		leavegroup = 1;
+		goto done;
+	}
 
 	for (pmc=inet->mc_list; pmc; pmc=pmc->next) {
 		if (pmc->multi.imr_multiaddr.s_addr == msf->imsf_multiaddr &&
 		    pmc->multi.imr_ifindex == imr.imr_ifindex)
 			break;
 	}
-	if (!pmc)		/* must have a prior join */
+	if (!pmc) {		/* must have a prior join */
+		err = -EINVAL;
 		goto done;
+	}
 	if (msf->imsf_numsrc) {
 		newpsl = (struct ip_sf_socklist *)sock_kmalloc(sk,
 				IP_SFLSIZE(msf->imsf_numsrc), GFP_KERNEL);
@@ -1909,8 +1920,11 @@ int ip_mc_msfilter(struct sock *sk, stru
 			0, NULL, 0);
 	pmc->sflist = newpsl;
 	pmc->sfmode = msf->imsf_fmode;
+	err = 0;
 done:
 	rtnl_shunlock();
+	if (leavegroup)
+		err = ip_mc_leave_group(sk, &imr);
 	return err;
 }
 
diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c
--- a/net/ipv4/inetpeer.c
+++ b/net/ipv4/inetpeer.c
@@ -450,10 +450,13 @@ static void peer_check_expire(unsigned l
 	/* Trigger the timer after inet_peer_gc_mintime .. inet_peer_gc_maxtime
 	 * interval depending on the total number of entries (more entries,
 	 * less interval). */
-	peer_periodic_timer.expires = jiffies
-		+ inet_peer_gc_maxtime
-		- (inet_peer_gc_maxtime - inet_peer_gc_mintime) / HZ *
-			peer_total / inet_peer_threshold * HZ;
+	if (peer_total >= inet_peer_threshold)
+		peer_periodic_timer.expires = jiffies + inet_peer_gc_mintime;
+	else
+		peer_periodic_timer.expires = jiffies
+			+ inet_peer_gc_maxtime
+			- (inet_peer_gc_maxtime - inet_peer_gc_mintime) / HZ *
+				peer_total / inet_peer_threshold * HZ;
 	add_timer(&peer_periodic_timer);
 }
 
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c
--- a/net/ipv4/ip_fragment.c
+++ b/net/ipv4/ip_fragment.c
@@ -377,7 +377,7 @@ static struct ipq *ip_frag_create(unsign
 	return ip_frag_intern(hash, qp);
 
 out_nomem:
-	NETDEBUG(if (net_ratelimit()) printk(KERN_ERR "ip_frag_create: no memory left !\n"));
+	LIMIT_NETDEBUG(printk(KERN_ERR "ip_frag_create: no memory left !\n"));
 	return NULL;
 }
 
@@ -625,10 +625,8 @@ static struct sk_buff *ip_frag_reasm(str
 	return head;
 
 out_nomem:
- 	NETDEBUG(if (net_ratelimit())
-	         printk(KERN_ERR 
-			"IP: queue_glue: no memory for gluing queue %p\n",
-			qp));
+ 	LIMIT_NETDEBUG(printk(KERN_ERR "IP: queue_glue: no memory for gluing "
+			      "queue %p\n", qp));
 	goto out_fail;
 out_oversize:
 	if (net_ratelimit())
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -290,7 +290,6 @@ static struct ip_tunnel * ipgre_tunnel_l
 
 	dev_hold(dev);
 	ipgre_tunnel_link(nt);
-	/* Do not decrement MOD_USE_COUNT here. */
 	return nt;
 
 failed:
@@ -1277,12 +1276,28 @@ err1:
 	goto out;
 }
 
-static void ipgre_fini(void)
+static void __exit ipgre_destroy_tunnels(void)
+{
+	int prio;
+
+	for (prio = 0; prio < 4; prio++) {
+		int h;
+		for (h = 0; h < HASH_SIZE; h++) {
+			struct ip_tunnel *t;
+			while ((t = tunnels[prio][h]) != NULL)
+				unregister_netdevice(t->dev);
+		}
+	}
+}
+
+static void __exit ipgre_fini(void)
 {
 	if (inet_del_protocol(&ipgre_protocol, IPPROTO_GRE) < 0)
 		printk(KERN_INFO "ipgre close: can't remove protocol\n");
 
-	unregister_netdev(ipgre_fb_tunnel_dev);
+	rtnl_lock();
+	ipgre_destroy_tunnels();
+	rtnl_unlock();
 }
 
 module_init(ipgre_init);
diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c
--- a/net/ipv4/ip_input.c
+++ b/net/ipv4/ip_input.c
@@ -184,6 +184,7 @@ int ip_call_ra_chain(struct sk_buff *skb
 					raw_rcv(last, skb2);
 			}
 			last = sk;
+			nf_reset(skb);
 		}
 	}
 
@@ -200,10 +201,6 @@ static inline int ip_local_deliver_finis
 {
 	int ihl = skb->nh.iph->ihl*4;
 
-#ifdef CONFIG_NETFILTER_DEBUG
-	nf_debug_ip_local_deliver(skb);
-#endif /*CONFIG_NETFILTER_DEBUG*/
-
 	__skb_pull(skb, ihl);
 
 	/* Free reference early: we don't need it any more, and it may
@@ -286,14 +283,18 @@ static inline int ip_rcv_finish(struct s
 {
 	struct net_device *dev = skb->dev;
 	struct iphdr *iph = skb->nh.iph;
+	int err;
 
 	/*
 	 *	Initialise the virtual path cache for the packet. It describes
 	 *	how the packet travels inside Linux networking.
 	 */ 
 	if (skb->dst == NULL) {
-		if (ip_route_input(skb, iph->daddr, iph->saddr, iph->tos, dev))
+		if ((err = ip_route_input(skb, iph->daddr, iph->saddr, iph->tos, dev))) {
+			if (err == -EHOSTUNREACH)
+				IP_INC_STATS_BH(IPSTATS_MIB_INADDRERRORS);
 			goto drop; 
+		}
 	}
 
 #ifdef CONFIG_NET_CLS_ROUTE
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -107,11 +107,6 @@ static int ip_dev_loopback_xmit(struct s
 	newskb->pkt_type = PACKET_LOOPBACK;
 	newskb->ip_summed = CHECKSUM_UNNECESSARY;
 	BUG_TRAP(newskb->dst);
-
-#ifdef CONFIG_NETFILTER_DEBUG
-	nf_debug_ip_loopback_xmit(newskb);
-#endif
-	nf_reset(newskb);
 	netif_rx(newskb);
 	return 0;
 }
@@ -192,12 +187,6 @@ static inline int ip_finish_output2(stru
 		skb = skb2;
 	}
 
-#ifdef CONFIG_NETFILTER_DEBUG
-	nf_debug_ip_finish_output2(skb);
-#endif /*CONFIG_NETFILTER_DEBUG*/
-
-	nf_reset(skb);
-
 	if (hh) {
 		int hh_alen;
 
@@ -391,7 +380,6 @@ static void ip_copy_metadata(struct sk_b
 	to->pkt_type = from->pkt_type;
 	to->priority = from->priority;
 	to->protocol = from->protocol;
-	to->security = from->security;
 	dst_release(to->dst);
 	to->dst = dst_clone(from->dst);
 	to->dev = from->dev;
@@ -415,9 +403,6 @@ static void ip_copy_metadata(struct sk_b
 	to->nf_bridge = from->nf_bridge;
 	nf_bridge_get(to->nf_bridge);
 #endif
-#ifdef CONFIG_NETFILTER_DEBUG
-	to->nf_debug = from->nf_debug;
-#endif
 #endif
 }
 
@@ -1334,23 +1319,8 @@ void ip_send_reply(struct sock *sk, stru
 	ip_rt_put(rt);
 }
 
-/*
- *	IP protocol layer initialiser
- */
-
-static struct packet_type ip_packet_type = {
-	.type = __constant_htons(ETH_P_IP),
-	.func = ip_rcv,
-};
-
-/*
- *	IP registers the packet type and then calls the subprotocol initialisers
- */
-
 void __init ip_init(void)
 {
-	dev_add_pack(&ip_packet_type);
-
 	ip_rt_init();
 	inet_initpeers();
 
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
--- a/net/ipv4/ip_sockglue.c
+++ b/net/ipv4/ip_sockglue.c
@@ -360,14 +360,14 @@ int ip_recv_error(struct sock *sk, struc
 	err = copied;
 
 	/* Reset and regenerate socket error */
-	spin_lock_irq(&sk->sk_error_queue.lock);
+	spin_lock_bh(&sk->sk_error_queue.lock);
 	sk->sk_err = 0;
 	if ((skb2 = skb_peek(&sk->sk_error_queue)) != NULL) {
 		sk->sk_err = SKB_EXT_ERR(skb2)->ee.ee_errno;
-		spin_unlock_irq(&sk->sk_error_queue.lock);
+		spin_unlock_bh(&sk->sk_error_queue.lock);
 		sk->sk_error_report(sk);
 	} else
-		spin_unlock_irq(&sk->sk_error_queue.lock);
+		spin_unlock_bh(&sk->sk_error_queue.lock);
 
 out_free_skb:	
 	kfree_skb(skb);
@@ -677,11 +677,11 @@ int ip_setsockopt(struct sock *sk, int l
 				mreq.imr_address.s_addr = mreqs.imr_interface;
 				mreq.imr_ifindex = 0;
 				err = ip_mc_join_group(sk, &mreq);
-				if (err)
+				if (err && err != -EADDRINUSE)
 					break;
 				omode = MCAST_INCLUDE;
 				add = 1;
-			} else /*IP_DROP_SOURCE_MEMBERSHIP */ {
+			} else /* IP_DROP_SOURCE_MEMBERSHIP */ {
 				omode = MCAST_INCLUDE;
 				add = 0;
 			}
@@ -754,7 +754,7 @@ int ip_setsockopt(struct sock *sk, int l
 				mreq.imr_address.s_addr = 0;
 				mreq.imr_ifindex = greqs.gsr_interface;
 				err = ip_mc_join_group(sk, &mreq);
-				if (err)
+				if (err && err != -EADDRINUSE)
 					break;
 				greqs.gsr_interface = mreq.imr_ifindex;
 				omode = MCAST_INCLUDE;
@@ -848,6 +848,9 @@ mc_msf_out:
  
 		case IP_IPSEC_POLICY:
 		case IP_XFRM_POLICY:
+			err = -EPERM;
+			if (!capable(CAP_NET_ADMIN))
+				break;
 			err = xfrm_user_policy(sk, optname, optval, optlen);
 			break;
 
diff --git a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c
--- a/net/ipv4/ipcomp.c
+++ b/net/ipv4/ipcomp.c
@@ -236,15 +236,10 @@ static struct xfrm_state *ipcomp_tunnel_
 	t->props.mode = 1;
 	t->props.saddr.a4 = x->props.saddr.a4;
 	t->props.flags = x->props.flags;
-	
-	t->type = xfrm_get_type(IPPROTO_IPIP, t->props.family);
-	if (t->type == NULL)
-		goto error;
-		
-	if (t->type->init_state(t, NULL))
+
+	if (xfrm_init_state(t))
 		goto error;
 
-	t->km.state = XFRM_STATE_VALID;
 	atomic_set(&t->tunnel_users, 1);
 out:
 	return t;
@@ -363,7 +358,7 @@ static struct crypto_tfm **ipcomp_alloc_
 	int cpu;
 
 	/* This can be any valid CPU ID so we don't need locking. */
-	cpu = smp_processor_id();
+	cpu = raw_smp_processor_id();
 
 	list_for_each_entry(pos, &ipcomp_tfms_list, list) {
 		struct crypto_tfm *tfm;
@@ -422,7 +417,7 @@ static void ipcomp_destroy(struct xfrm_s
 	kfree(ipcd);
 }
 
-static int ipcomp_init_state(struct xfrm_state *x, void *args)
+static int ipcomp_init_state(struct xfrm_state *x)
 {
 	int err;
 	struct ipcomp_data *ipcd;
diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c
--- a/net/ipv4/ipconfig.c
+++ b/net/ipv4/ipconfig.c
@@ -1149,8 +1149,10 @@ static int __init ic_dynamic(void)
 		ic_rarp_cleanup();
 #endif
 
-	if (!ic_got_reply)
+	if (!ic_got_reply) {
+		ic_myaddr = INADDR_NONE;
 		return -1;
+	}
 
 	printk("IP-Config: Got %s answer from %u.%u.%u.%u, ",
 		((ic_got_reply & IC_RARP) ? "RARP" 
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c
--- a/net/ipv4/ipip.c
+++ b/net/ipv4/ipip.c
@@ -255,7 +255,6 @@ static struct ip_tunnel * ipip_tunnel_lo
 
 	dev_hold(dev);
 	ipip_tunnel_link(nt);
-	/* Do not decrement MOD_USE_COUNT here. */
 	return nt;
 
 failed:
@@ -273,7 +272,7 @@ static void ipip_tunnel_uninit(struct ne
 	dev_put(dev);
 }
 
-static void ipip_err(struct sk_buff *skb, void *__unused)
+static void ipip_err(struct sk_buff *skb, u32 info)
 {
 #ifndef I_WISH_WORLD_WERE_PERFECT
 
@@ -852,11 +851,39 @@ static int __init ipip_fb_tunnel_init(st
 	return 0;
 }
 
+#ifdef CONFIG_INET_TUNNEL
 static struct xfrm_tunnel ipip_handler = {
 	.handler	=	ipip_rcv,
 	.err_handler	=	ipip_err,
 };
 
+static inline int ipip_register(void)
+{
+	return xfrm4_tunnel_register(&ipip_handler);
+}
+
+static inline int ipip_unregister(void)
+{
+	return xfrm4_tunnel_deregister(&ipip_handler);
+}
+#else
+static struct net_protocol ipip_protocol = {
+	.handler	=	ipip_rcv,
+	.err_handler	=	ipip_err,
+	.no_policy	=	1,
+};
+
+static inline int ipip_register(void)
+{
+	return inet_add_protocol(&ipip_protocol, IPPROTO_IPIP);
+}
+
+static inline int ipip_unregister(void)
+{
+	return inet_del_protocol(&ipip_protocol, IPPROTO_IPIP);
+}
+#endif
+
 static char banner[] __initdata =
 	KERN_INFO "IPv4 over IPv4 tunneling driver\n";
 
@@ -866,7 +893,7 @@ static int __init ipip_init(void)
 
 	printk(banner);
 
-	if (xfrm4_tunnel_register(&ipip_handler) < 0) {
+	if (ipip_register() < 0) {
 		printk(KERN_INFO "ipip init: can't register tunnel\n");
 		return -EAGAIN;
 	}
@@ -888,16 +915,33 @@ static int __init ipip_init(void)
  err2:
 	free_netdev(ipip_fb_tunnel_dev);
  err1:
-	xfrm4_tunnel_deregister(&ipip_handler);
+	ipip_unregister();
 	goto out;
 }
 
+static void __exit ipip_destroy_tunnels(void)
+{
+	int prio;
+
+	for (prio = 1; prio < 4; prio++) {
+		int h;
+		for (h = 0; h < HASH_SIZE; h++) {
+			struct ip_tunnel *t;
+			while ((t = tunnels[prio][h]) != NULL)
+				unregister_netdevice(t->dev);
+		}
+	}
+}
+
 static void __exit ipip_fini(void)
 {
-	if (xfrm4_tunnel_deregister(&ipip_handler) < 0)
+	if (ipip_unregister() < 0)
 		printk(KERN_INFO "ipip close: can't deregister tunnel\n");
 
-	unregister_netdev(ipip_fb_tunnel_dev);
+	rtnl_lock();
+	ipip_destroy_tunnels();
+	unregister_netdevice(ipip_fb_tunnel_dev);
+	rtnl_unlock();
 }
 
 module_init(ipip_init);
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -297,6 +297,7 @@ static int vif_delete(int vifi)
 static void ipmr_destroy_unres(struct mfc_cache *c)
 {
 	struct sk_buff *skb;
+	struct nlmsgerr *e;
 
 	atomic_dec(&cache_resolve_queue_len);
 
@@ -306,7 +307,9 @@ static void ipmr_destroy_unres(struct mf
 			nlh->nlmsg_type = NLMSG_ERROR;
 			nlh->nlmsg_len = NLMSG_LENGTH(sizeof(struct nlmsgerr));
 			skb_trim(skb, nlh->nlmsg_len);
-			((struct nlmsgerr*)NLMSG_DATA(nlh))->error = -ETIMEDOUT;
+			e = NLMSG_DATA(nlh);
+			e->error = -ETIMEDOUT;
+			memset(&e->msg, 0, sizeof(e->msg));
 			netlink_unicast(rtnl, skb, NETLINK_CB(skb).dst_pid, MSG_DONTWAIT);
 		} else
 			kfree_skb(skb);
@@ -359,7 +362,7 @@ out:
 
 /* Fill oifs list. It is called under write locked mrt_lock. */
 
-static void ipmr_update_threshoulds(struct mfc_cache *cache, unsigned char *ttls)
+static void ipmr_update_thresholds(struct mfc_cache *cache, unsigned char *ttls)
 {
 	int vifi;
 
@@ -499,6 +502,7 @@ static struct mfc_cache *ipmr_cache_allo
 static void ipmr_cache_resolve(struct mfc_cache *uc, struct mfc_cache *c)
 {
 	struct sk_buff *skb;
+	struct nlmsgerr *e;
 
 	/*
 	 *	Play the pending entries through our router
@@ -515,7 +519,9 @@ static void ipmr_cache_resolve(struct mf
 				nlh->nlmsg_type = NLMSG_ERROR;
 				nlh->nlmsg_len = NLMSG_LENGTH(sizeof(struct nlmsgerr));
 				skb_trim(skb, nlh->nlmsg_len);
-				((struct nlmsgerr*)NLMSG_DATA(nlh))->error = -EMSGSIZE;
+				e = NLMSG_DATA(nlh);
+				e->error = -EMSGSIZE;
+				memset(&e->msg, 0, sizeof(e->msg));
 			}
 			err = netlink_unicast(rtnl, skb, NETLINK_CB(skb).dst_pid, MSG_DONTWAIT);
 		} else
@@ -721,7 +727,7 @@ static int ipmr_mfc_add(struct mfcctl *m
 	if (c != NULL) {
 		write_lock_bh(&mrt_lock);
 		c->mfc_parent = mfc->mfcc_parent;
-		ipmr_update_threshoulds(c, mfc->mfcc_ttls);
+		ipmr_update_thresholds(c, mfc->mfcc_ttls);
 		if (!mrtsock)
 			c->mfc_flags |= MFC_STATIC;
 		write_unlock_bh(&mrt_lock);
@@ -738,7 +744,7 @@ static int ipmr_mfc_add(struct mfcctl *m
 	c->mfc_origin=mfc->mfcc_origin.s_addr;
 	c->mfc_mcastgrp=mfc->mfcc_mcastgrp.s_addr;
 	c->mfc_parent=mfc->mfcc_parent;
-	ipmr_update_threshoulds(c, mfc->mfcc_ttls);
+	ipmr_update_thresholds(c, mfc->mfcc_ttls);
 	if (!mrtsock)
 		c->mfc_flags |= MFC_STATIC;
 
@@ -1350,6 +1356,7 @@ int ip_mr_input(struct sk_buff *skb)
 			     */
 			    read_lock(&mrt_lock);
 			    if (mroute_socket) {
+				    nf_reset(skb);
 				    raw_rcv(mroute_socket, skb);
 				    read_unlock(&mrt_lock);
 				    return 0;
diff --git a/net/ipv4/ipvs/Kconfig b/net/ipv4/ipvs/Kconfig
--- a/net/ipv4/ipvs/Kconfig
+++ b/net/ipv4/ipvs/Kconfig
@@ -2,11 +2,11 @@
 # IP Virtual Server configuration
 #
 menu	"IP: Virtual Server Configuration"
-	depends on INET && NETFILTER
+	depends on NETFILTER
 
 config	IP_VS
 	tristate "IP virtual server support (EXPERIMENTAL)"
-	depends on INET && NETFILTER
+	depends on NETFILTER
 	---help---
 	  IP Virtual Server support will let you build a high-performance
 	  virtual server based on cluster of two or more real servers. This
diff --git a/net/ipv4/ipvs/ip_vs_conn.c b/net/ipv4/ipvs/ip_vs_conn.c
--- a/net/ipv4/ipvs/ip_vs_conn.c
+++ b/net/ipv4/ipvs/ip_vs_conn.c
@@ -548,7 +548,6 @@ void ip_vs_conn_expire_now(struct ip_vs_
 {
 	if (del_timer(&cp->timer))
 		mod_timer(&cp->timer, jiffies);
-	__ip_vs_conn_put(cp);
 }
 
 
@@ -759,12 +758,11 @@ static inline int todrop_entry(struct ip
 	return 1;
 }
 
-
+/* Called from keventd and must protect itself from softirqs */
 void ip_vs_random_dropentry(void)
 {
 	int idx;
 	struct ip_vs_conn *cp;
-	struct ip_vs_conn *ct;
 
 	/*
 	 * Randomly scan 1/32 of the whole table every second
@@ -775,7 +773,7 @@ void ip_vs_random_dropentry(void)
 		/*
 		 *  Lock is actually needed in this loop.
 		 */
-		ct_write_lock(hash);
+		ct_write_lock_bh(hash);
 
 		list_for_each_entry(cp, &ip_vs_conn_tab[hash], c_list) {
 			if (!cp->cport && !(cp->flags & IP_VS_CONN_F_NO_CPORT))
@@ -801,23 +799,14 @@ void ip_vs_random_dropentry(void)
 					continue;
 			}
 
-			/*
-			 * Drop the entry, and drop its ct if not referenced
-			 */
-			atomic_inc(&cp->refcnt);
-			ct_write_unlock(hash);
-
-			if ((ct = cp->control))
-				atomic_inc(&ct->refcnt);
 			IP_VS_DBG(4, "del connection\n");
 			ip_vs_conn_expire_now(cp);
-			if (ct) {
+			if (cp->control) {
 				IP_VS_DBG(4, "del conn template\n");
-				ip_vs_conn_expire_now(ct);
+				ip_vs_conn_expire_now(cp->control);
 			}
-			ct_write_lock(hash);
 		}
-		ct_write_unlock(hash);
+		ct_write_unlock_bh(hash);
 	}
 }
 
@@ -829,7 +818,6 @@ static void ip_vs_conn_flush(void)
 {
 	int idx;
 	struct ip_vs_conn *cp;
-	struct ip_vs_conn *ct;
 
   flush_again:
 	for (idx=0; idx<IP_VS_CONN_TAB_SIZE; idx++) {
@@ -839,18 +827,13 @@ static void ip_vs_conn_flush(void)
 		ct_write_lock_bh(idx);
 
 		list_for_each_entry(cp, &ip_vs_conn_tab[idx], c_list) {
-			atomic_inc(&cp->refcnt);
-			ct_write_unlock(idx);
 
-			if ((ct = cp->control))
-				atomic_inc(&ct->refcnt);
 			IP_VS_DBG(4, "del connection\n");
 			ip_vs_conn_expire_now(cp);
-			if (ct) {
+			if (cp->control) {
 				IP_VS_DBG(4, "del conn template\n");
-				ip_vs_conn_expire_now(ct);
+				ip_vs_conn_expire_now(cp->control);
 			}
-			ct_write_lock(idx);
 		}
 		ct_write_unlock_bh(idx);
 	}
diff --git a/net/ipv4/ipvs/ip_vs_ctl.c b/net/ipv4/ipvs/ip_vs_ctl.c
--- a/net/ipv4/ipvs/ip_vs_ctl.c
+++ b/net/ipv4/ipvs/ip_vs_ctl.c
@@ -90,7 +90,8 @@ int ip_vs_get_debug_level(void)
 #endif
 
 /*
- *	update_defense_level is called from keventd and from sysctl.
+ *	update_defense_level is called from keventd and from sysctl,
+ *	so it needs to protect itself from softirqs
  */
 static void update_defense_level(void)
 {
@@ -110,6 +111,8 @@ static void update_defense_level(void)
 
 	nomem = (availmem < sysctl_ip_vs_amemthresh);
 
+	local_bh_disable();
+
 	/* drop_entry */
 	spin_lock(&__ip_vs_dropentry_lock);
 	switch (sysctl_ip_vs_drop_entry) {
@@ -206,6 +209,8 @@ static void update_defense_level(void)
 	if (to_change >= 0)
 		ip_vs_protocol_timeout_change(sysctl_ip_vs_secure_tcp>1);
 	write_unlock(&__ip_vs_securetcp_lock);
+
+	local_bh_enable();
 }
 
 
@@ -1360,9 +1365,7 @@ proc_do_defense_mode(ctl_table *table, i
 			/* Restore the correct value */
 			*valp = val;
 		} else {
-			local_bh_disable();
 			update_defense_level();
-			local_bh_enable();
 		}
 	}
 	return rc;
@@ -2059,7 +2062,7 @@ ip_vs_copy_service(struct ip_vs_service_
 	dst->addr = src->addr;
 	dst->port = src->port;
 	dst->fwmark = src->fwmark;
-	strcpy(dst->sched_name, src->scheduler->name);
+	strlcpy(dst->sched_name, src->scheduler->name, sizeof(dst->sched_name));
 	dst->flags = src->flags;
 	dst->timeout = src->timeout / HZ;
 	dst->netmask = src->netmask;
@@ -2080,6 +2083,7 @@ __ip_vs_get_service_entries(const struct
 		list_for_each_entry(svc, &ip_vs_svc_table[idx], s_list) {
 			if (count >= get->num_services)
 				goto out;
+			memset(&entry, 0, sizeof(entry));
 			ip_vs_copy_service(&entry, svc);
 			if (copy_to_user(&uptr->entrytable[count],
 					 &entry, sizeof(entry))) {
@@ -2094,6 +2098,7 @@ __ip_vs_get_service_entries(const struct
 		list_for_each_entry(svc, &ip_vs_svc_fwm_table[idx], f_list) {
 			if (count >= get->num_services)
 				goto out;
+			memset(&entry, 0, sizeof(entry));
 			ip_vs_copy_service(&entry, svc);
 			if (copy_to_user(&uptr->entrytable[count],
 					 &entry, sizeof(entry))) {
@@ -2304,12 +2309,12 @@ do_ip_vs_get_ctl(struct sock *sk, int cm
 		memset(&d, 0, sizeof(d));
 		if (ip_vs_sync_state & IP_VS_STATE_MASTER) {
 			d[0].state = IP_VS_STATE_MASTER;
-			strcpy(d[0].mcast_ifn, ip_vs_master_mcast_ifn);
+			strlcpy(d[0].mcast_ifn, ip_vs_master_mcast_ifn, sizeof(d[0].mcast_ifn));
 			d[0].syncid = ip_vs_master_syncid;
 		}
 		if (ip_vs_sync_state & IP_VS_STATE_BACKUP) {
 			d[1].state = IP_VS_STATE_BACKUP;
-			strcpy(d[1].mcast_ifn, ip_vs_backup_mcast_ifn);
+			strlcpy(d[1].mcast_ifn, ip_vs_backup_mcast_ifn, sizeof(d[1].mcast_ifn));
 			d[1].syncid = ip_vs_backup_syncid;
 		}
 		if (copy_to_user(user, &d, sizeof(d)) != 0)
diff --git a/net/ipv4/ipvs/ip_vs_sync.c b/net/ipv4/ipvs/ip_vs_sync.c
--- a/net/ipv4/ipvs/ip_vs_sync.c
+++ b/net/ipv4/ipvs/ip_vs_sync.c
@@ -839,10 +839,10 @@ int start_sync_thread(int state, char *m
 
 	ip_vs_sync_state |= state;
 	if (state == IP_VS_STATE_MASTER) {
-		strcpy(ip_vs_master_mcast_ifn, mcast_ifn);
+		strlcpy(ip_vs_master_mcast_ifn, mcast_ifn, sizeof(ip_vs_master_mcast_ifn));
 		ip_vs_master_syncid = syncid;
 	} else {
-		strcpy(ip_vs_backup_mcast_ifn, mcast_ifn);
+		strlcpy(ip_vs_backup_mcast_ifn, mcast_ifn, sizeof(ip_vs_backup_mcast_ifn));
 		ip_vs_backup_syncid = syncid;
 	}
 
diff --git a/net/ipv4/ipvs/ip_vs_xmit.c b/net/ipv4/ipvs/ip_vs_xmit.c
--- a/net/ipv4/ipvs/ip_vs_xmit.c
+++ b/net/ipv4/ipvs/ip_vs_xmit.c
@@ -127,7 +127,6 @@ ip_vs_dst_reset(struct ip_vs_dest *dest)
 
 #define IP_VS_XMIT(skb, rt)				\
 do {							\
-	nf_reset_debug(skb);				\
 	(skb)->nfcache |= NFC_IPVS_PROPERTY;		\
 	(skb)->ip_summed = CHECKSUM_NONE;		\
 	NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, (skb), NULL,	\
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -60,7 +60,6 @@ static DECLARE_MUTEX(arpt_mutex);
 
 #define ASSERT_READ_LOCK(x) ARP_NF_ASSERT(down_trylock(&arpt_mutex) != 0)
 #define ASSERT_WRITE_LOCK(x) ARP_NF_ASSERT(down_trylock(&arpt_mutex) != 0)
-#include <linux/netfilter_ipv4/lockhelp.h>
 #include <linux/netfilter_ipv4/listhelp.h>
 
 struct arpt_table_info {
diff --git a/net/ipv4/netfilter/ip_conntrack_amanda.c b/net/ipv4/netfilter/ip_conntrack_amanda.c
--- a/net/ipv4/netfilter/ip_conntrack_amanda.c
+++ b/net/ipv4/netfilter/ip_conntrack_amanda.c
@@ -26,7 +26,6 @@
 #include <net/checksum.h>
 #include <net/udp.h>
 
-#include <linux/netfilter_ipv4/lockhelp.h>
 #include <linux/netfilter_ipv4/ip_conntrack_helper.h>
 #include <linux/netfilter_ipv4/ip_conntrack_amanda.h>
 
@@ -42,7 +41,7 @@ static char *conns[] = { "DATA ", "MESG 
 
 /* This is slow, but it's simple. --RR */
 static char amanda_buffer[65536];
-static DECLARE_LOCK(amanda_buffer_lock);
+static DEFINE_SPINLOCK(amanda_buffer_lock);
 
 unsigned int (*ip_nat_amanda_hook)(struct sk_buff **pskb,
 				   enum ip_conntrack_info ctinfo,
@@ -76,7 +75,7 @@ static int help(struct sk_buff **pskb,
 		return NF_ACCEPT;
 	}
 
-	LOCK_BH(&amanda_buffer_lock);
+	spin_lock_bh(&amanda_buffer_lock);
 	skb_copy_bits(*pskb, dataoff, amanda_buffer, (*pskb)->len - dataoff);
 	data = amanda_buffer;
 	data_limit = amanda_buffer + (*pskb)->len - dataoff;
@@ -102,14 +101,13 @@ static int help(struct sk_buff **pskb,
 		if (port == 0 || len > 5)
 			break;
 
-		exp = ip_conntrack_expect_alloc();
+		exp = ip_conntrack_expect_alloc(ct);
 		if (exp == NULL) {
 			ret = NF_DROP;
 			goto out;
 		}
 
 		exp->expectfn = NULL;
-		exp->master = ct;
 
 		exp->tuple.src.ip = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip;
 		exp->tuple.src.u.tcp.port = 0;
@@ -127,14 +125,13 @@ static int help(struct sk_buff **pskb,
 			ret = ip_nat_amanda_hook(pskb, ctinfo,
 						 tmp - amanda_buffer,
 						 len, exp);
-		else if (ip_conntrack_expect_related(exp) != 0) {
-			ip_conntrack_expect_free(exp);
+		else if (ip_conntrack_expect_related(exp) != 0)
 			ret = NF_DROP;
-		}
+		ip_conntrack_expect_put(exp);
 	}
 
 out:
-	UNLOCK_BH(&amanda_buffer_lock);
+	spin_unlock_bh(&amanda_buffer_lock);
 	return ret;
 }
 
diff --git a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c
--- a/net/ipv4/netfilter/ip_conntrack_core.c
+++ b/net/ipv4/netfilter/ip_conntrack_core.c
@@ -38,10 +38,10 @@
 #include <linux/percpu.h>
 #include <linux/moduleparam.h>
 
-/* This rwlock protects the main hash table, protocol/helper/expected
+/* ip_conntrack_lock protects the main hash table, protocol/helper/expected
    registrations, conntrack timers*/
-#define ASSERT_READ_LOCK(x) MUST_BE_READ_LOCKED(&ip_conntrack_lock)
-#define ASSERT_WRITE_LOCK(x) MUST_BE_WRITE_LOCKED(&ip_conntrack_lock)
+#define ASSERT_READ_LOCK(x)
+#define ASSERT_WRITE_LOCK(x)
 
 #include <linux/netfilter_ipv4/ip_conntrack.h>
 #include <linux/netfilter_ipv4/ip_conntrack_protocol.h>
@@ -57,7 +57,7 @@
 #define DEBUGP(format, args...)
 #endif
 
-DECLARE_RWLOCK(ip_conntrack_lock);
+DEFINE_RWLOCK(ip_conntrack_lock);
 
 /* ip_conntrack_standalone needs this */
 atomic_t ip_conntrack_count = ATOMIC_INIT(0);
@@ -137,19 +137,12 @@ ip_ct_invert_tuple(struct ip_conntrack_t
 
 
 /* ip_conntrack_expect helper functions */
-static void destroy_expect(struct ip_conntrack_expect *exp)
-{
-	ip_conntrack_put(exp->master);
-	IP_NF_ASSERT(!timer_pending(&exp->timeout));
-	kmem_cache_free(ip_conntrack_expect_cachep, exp);
-	CONNTRACK_STAT_INC(expect_delete);
-}
-
 static void unlink_expect(struct ip_conntrack_expect *exp)
 {
-	MUST_BE_WRITE_LOCKED(&ip_conntrack_lock);
+	ASSERT_WRITE_LOCK(&ip_conntrack_lock);
+	IP_NF_ASSERT(!timer_pending(&exp->timeout));
 	list_del(&exp->list);
-	/* Logically in destroy_expect, but we hold the lock here. */
+	CONNTRACK_STAT_INC(expect_delete);
 	exp->master->expecting--;
 }
 
@@ -157,10 +150,10 @@ static void expectation_timed_out(unsign
 {
 	struct ip_conntrack_expect *exp = (void *)ul_expect;
 
-	WRITE_LOCK(&ip_conntrack_lock);
+	write_lock_bh(&ip_conntrack_lock);
 	unlink_expect(exp);
-	WRITE_UNLOCK(&ip_conntrack_lock);
-	destroy_expect(exp);
+	write_unlock_bh(&ip_conntrack_lock);
+	ip_conntrack_expect_put(exp);
 }
 
 /* If an expectation for this connection is found, it gets delete from
@@ -198,7 +191,7 @@ static void remove_expectations(struct i
 	list_for_each_entry_safe(i, tmp, &ip_conntrack_expect_list, list) {
 		if (i->master == ct && del_timer(&i->timeout)) {
 			unlink_expect(i);
-			destroy_expect(i);
+			ip_conntrack_expect_put(i);
 		}
 	}
 }
@@ -209,7 +202,7 @@ clean_from_lists(struct ip_conntrack *ct
 	unsigned int ho, hr;
 	
 	DEBUGP("clean_from_lists(%p)\n", ct);
-	MUST_BE_WRITE_LOCKED(&ip_conntrack_lock);
+	ASSERT_WRITE_LOCK(&ip_conntrack_lock);
 
 	ho = hash_conntrack(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
 	hr = hash_conntrack(&ct->tuplehash[IP_CT_DIR_REPLY].tuple);
@@ -240,7 +233,7 @@ destroy_conntrack(struct nf_conntrack *n
 	if (ip_conntrack_destroyed)
 		ip_conntrack_destroyed(ct);
 
-	WRITE_LOCK(&ip_conntrack_lock);
+	write_lock_bh(&ip_conntrack_lock);
 	/* Expectations will have been removed in clean_from_lists,
 	 * except TFTP can create an expectation on the first packet,
 	 * before connection is in the list, so we need to clean here,
@@ -254,7 +247,7 @@ destroy_conntrack(struct nf_conntrack *n
 	}
 
 	CONNTRACK_STAT_INC(delete);
-	WRITE_UNLOCK(&ip_conntrack_lock);
+	write_unlock_bh(&ip_conntrack_lock);
 
 	if (ct->master)
 		ip_conntrack_put(ct->master);
@@ -268,12 +261,12 @@ static void death_by_timeout(unsigned lo
 {
 	struct ip_conntrack *ct = (void *)ul_conntrack;
 
-	WRITE_LOCK(&ip_conntrack_lock);
+	write_lock_bh(&ip_conntrack_lock);
 	/* Inside lock so preempt is disabled on module removal path.
 	 * Otherwise we can get spurious warnings. */
 	CONNTRACK_STAT_INC(delete_list);
 	clean_from_lists(ct);
-	WRITE_UNLOCK(&ip_conntrack_lock);
+	write_unlock_bh(&ip_conntrack_lock);
 	ip_conntrack_put(ct);
 }
 
@@ -282,7 +275,7 @@ conntrack_tuple_cmp(const struct ip_conn
 		    const struct ip_conntrack_tuple *tuple,
 		    const struct ip_conntrack *ignored_conntrack)
 {
-	MUST_BE_READ_LOCKED(&ip_conntrack_lock);
+	ASSERT_READ_LOCK(&ip_conntrack_lock);
 	return tuplehash_to_ctrack(i) != ignored_conntrack
 		&& ip_ct_tuple_equal(tuple, &i->tuple);
 }
@@ -294,7 +287,7 @@ __ip_conntrack_find(const struct ip_conn
 	struct ip_conntrack_tuple_hash *h;
 	unsigned int hash = hash_conntrack(tuple);
 
-	MUST_BE_READ_LOCKED(&ip_conntrack_lock);
+	ASSERT_READ_LOCK(&ip_conntrack_lock);
 	list_for_each_entry(h, &ip_conntrack_hash[hash], list) {
 		if (conntrack_tuple_cmp(h, tuple, ignored_conntrack)) {
 			CONNTRACK_STAT_INC(found);
@@ -313,11 +306,11 @@ ip_conntrack_find_get(const struct ip_co
 {
 	struct ip_conntrack_tuple_hash *h;
 
-	READ_LOCK(&ip_conntrack_lock);
+	read_lock_bh(&ip_conntrack_lock);
 	h = __ip_conntrack_find(tuple, ignored_conntrack);
 	if (h)
 		atomic_inc(&tuplehash_to_ctrack(h)->ct_general.use);
-	READ_UNLOCK(&ip_conntrack_lock);
+	read_unlock_bh(&ip_conntrack_lock);
 
 	return h;
 }
@@ -352,7 +345,7 @@ __ip_conntrack_confirm(struct sk_buff **
 	IP_NF_ASSERT(!is_confirmed(ct));
 	DEBUGP("Confirming conntrack %p\n", ct);
 
-	WRITE_LOCK(&ip_conntrack_lock);
+	write_lock_bh(&ip_conntrack_lock);
 
 	/* See if there's one in the list already, including reverse:
            NAT could have grabbed it without realizing, since we're
@@ -380,12 +373,12 @@ __ip_conntrack_confirm(struct sk_buff **
 		atomic_inc(&ct->ct_general.use);
 		set_bit(IPS_CONFIRMED_BIT, &ct->status);
 		CONNTRACK_STAT_INC(insert);
-		WRITE_UNLOCK(&ip_conntrack_lock);
+		write_unlock_bh(&ip_conntrack_lock);
 		return NF_ACCEPT;
 	}
 
 	CONNTRACK_STAT_INC(insert_failed);
-	WRITE_UNLOCK(&ip_conntrack_lock);
+	write_unlock_bh(&ip_conntrack_lock);
 
 	return NF_DROP;
 }
@@ -398,9 +391,9 @@ ip_conntrack_tuple_taken(const struct ip
 {
 	struct ip_conntrack_tuple_hash *h;
 
-	READ_LOCK(&ip_conntrack_lock);
+	read_lock_bh(&ip_conntrack_lock);
 	h = __ip_conntrack_find(tuple, ignored_conntrack);
-	READ_UNLOCK(&ip_conntrack_lock);
+	read_unlock_bh(&ip_conntrack_lock);
 
 	return h != NULL;
 }
@@ -419,13 +412,13 @@ static int early_drop(struct list_head *
 	struct ip_conntrack *ct = NULL;
 	int dropped = 0;
 
-	READ_LOCK(&ip_conntrack_lock);
+	read_lock_bh(&ip_conntrack_lock);
 	h = LIST_FIND_B(chain, unreplied, struct ip_conntrack_tuple_hash *);
 	if (h) {
 		ct = tuplehash_to_ctrack(h);
 		atomic_inc(&ct->ct_general.use);
 	}
-	READ_UNLOCK(&ip_conntrack_lock);
+	read_unlock_bh(&ip_conntrack_lock);
 
 	if (!ct)
 		return dropped;
@@ -508,7 +501,7 @@ init_conntrack(const struct ip_conntrack
 	conntrack->timeout.data = (unsigned long)conntrack;
 	conntrack->timeout.function = death_by_timeout;
 
-	WRITE_LOCK(&ip_conntrack_lock);
+	write_lock_bh(&ip_conntrack_lock);
 	exp = find_expectation(tuple);
 
 	if (exp) {
@@ -517,9 +510,14 @@ init_conntrack(const struct ip_conntrack
 		/* Welcome, Mr. Bond.  We've been expecting you... */
 		__set_bit(IPS_EXPECTED_BIT, &conntrack->status);
 		conntrack->master = exp->master;
-#if CONFIG_IP_NF_CONNTRACK_MARK
+#ifdef CONFIG_IP_NF_CONNTRACK_MARK
 		conntrack->mark = exp->master->mark;
 #endif
+#if defined(CONFIG_IP_NF_TARGET_MASQUERADE) || \
+    defined(CONFIG_IP_NF_TARGET_MASQUERADE_MODULE)
+		/* this is ugly, but there is no other place where to put it */
+		conntrack->nat.masq_index = exp->master->nat.masq_index;
+#endif
 		nf_conntrack_get(&conntrack->master->ct_general);
 		CONNTRACK_STAT_INC(expect_new);
 	} else {
@@ -532,12 +530,12 @@ init_conntrack(const struct ip_conntrack
 	list_add(&conntrack->tuplehash[IP_CT_DIR_ORIGINAL].list, &unconfirmed);
 
 	atomic_inc(&ip_conntrack_count);
-	WRITE_UNLOCK(&ip_conntrack_lock);
+	write_unlock_bh(&ip_conntrack_lock);
 
 	if (exp) {
 		if (exp->expectfn)
 			exp->expectfn(conntrack, exp);
-		destroy_expect(exp);
+		ip_conntrack_expect_put(exp);
 	}
 
 	return &conntrack->tuplehash[IP_CT_DIR_ORIGINAL];
@@ -723,20 +721,20 @@ void ip_conntrack_unexpect_related(struc
 {
 	struct ip_conntrack_expect *i;
 
-	WRITE_LOCK(&ip_conntrack_lock);
+	write_lock_bh(&ip_conntrack_lock);
 	/* choose the the oldest expectation to evict */
 	list_for_each_entry_reverse(i, &ip_conntrack_expect_list, list) {
 		if (expect_matches(i, exp) && del_timer(&i->timeout)) {
 			unlink_expect(i);
-			WRITE_UNLOCK(&ip_conntrack_lock);
-			destroy_expect(i);
+			write_unlock_bh(&ip_conntrack_lock);
+			ip_conntrack_expect_put(i);
 			return;
 		}
 	}
-	WRITE_UNLOCK(&ip_conntrack_lock);
+	write_unlock_bh(&ip_conntrack_lock);
 }
 
-struct ip_conntrack_expect *ip_conntrack_expect_alloc(void)
+struct ip_conntrack_expect *ip_conntrack_expect_alloc(struct ip_conntrack *me)
 {
 	struct ip_conntrack_expect *new;
 
@@ -745,30 +743,31 @@ struct ip_conntrack_expect *ip_conntrack
 		DEBUGP("expect_related: OOM allocating expect\n");
 		return NULL;
 	}
-	new->master = NULL;
+	new->master = me;
+	atomic_inc(&new->master->ct_general.use);
+	atomic_set(&new->use, 1);
 	return new;
 }
 
-void ip_conntrack_expect_free(struct ip_conntrack_expect *expect)
+void ip_conntrack_expect_put(struct ip_conntrack_expect *exp)
 {
-	kmem_cache_free(ip_conntrack_expect_cachep, expect);
+	if (atomic_dec_and_test(&exp->use)) {
+		ip_conntrack_put(exp->master);
+		kmem_cache_free(ip_conntrack_expect_cachep, exp);
+	}
 }
 
 static void ip_conntrack_expect_insert(struct ip_conntrack_expect *exp)
 {
-	atomic_inc(&exp->master->ct_general.use);
+	atomic_inc(&exp->use);
 	exp->master->expecting++;
 	list_add(&exp->list, &ip_conntrack_expect_list);
 
-	if (exp->master->helper->timeout) {
-		init_timer(&exp->timeout);
-		exp->timeout.data = (unsigned long)exp;
-		exp->timeout.function = expectation_timed_out;
-		exp->timeout.expires
-			= jiffies + exp->master->helper->timeout * HZ;
-		add_timer(&exp->timeout);
-	} else
-		exp->timeout.function = NULL;
+	init_timer(&exp->timeout);
+	exp->timeout.data = (unsigned long)exp;
+	exp->timeout.function = expectation_timed_out;
+	exp->timeout.expires = jiffies + exp->master->helper->timeout * HZ;
+	add_timer(&exp->timeout);
 
 	CONNTRACK_STAT_INC(expect_create);
 }
@@ -782,7 +781,7 @@ static void evict_oldest_expect(struct i
 		if (i->master == master) {
 			if (del_timer(&i->timeout)) {
 				unlink_expect(i);
-				destroy_expect(i);
+				ip_conntrack_expect_put(i);
 			}
 			break;
 		}
@@ -808,14 +807,12 @@ int ip_conntrack_expect_related(struct i
 	DEBUGP("tuple: "); DUMP_TUPLE(&expect->tuple);
 	DEBUGP("mask:  "); DUMP_TUPLE(&expect->mask);
 
-	WRITE_LOCK(&ip_conntrack_lock);
+	write_lock_bh(&ip_conntrack_lock);
 	list_for_each_entry(i, &ip_conntrack_expect_list, list) {
 		if (expect_matches(i, expect)) {
 			/* Refresh timer: if it's dying, ignore.. */
 			if (refresh_timer(i)) {
 				ret = 0;
-				/* We don't need the one they've given us. */
-				ip_conntrack_expect_free(expect);
 				goto out;
 			}
 		} else if (expect_clash(i, expect)) {
@@ -832,7 +829,7 @@ int ip_conntrack_expect_related(struct i
 	ip_conntrack_expect_insert(expect);
 	ret = 0;
 out:
-	WRITE_UNLOCK(&ip_conntrack_lock);
+	write_unlock_bh(&ip_conntrack_lock);
  	return ret;
 }
 
@@ -841,7 +838,7 @@ out:
 void ip_conntrack_alter_reply(struct ip_conntrack *conntrack,
 			      const struct ip_conntrack_tuple *newreply)
 {
-	WRITE_LOCK(&ip_conntrack_lock);
+	write_lock_bh(&ip_conntrack_lock);
 	/* Should be unconfirmed, so not in hash table yet */
 	IP_NF_ASSERT(!is_confirmed(conntrack));
 
@@ -851,15 +848,15 @@ void ip_conntrack_alter_reply(struct ip_
 	conntrack->tuplehash[IP_CT_DIR_REPLY].tuple = *newreply;
 	if (!conntrack->master && conntrack->expecting == 0)
 		conntrack->helper = ip_ct_find_helper(newreply);
-	WRITE_UNLOCK(&ip_conntrack_lock);
+	write_unlock_bh(&ip_conntrack_lock);
 }
 
 int ip_conntrack_helper_register(struct ip_conntrack_helper *me)
 {
 	BUG_ON(me->timeout == 0);
-	WRITE_LOCK(&ip_conntrack_lock);
+	write_lock_bh(&ip_conntrack_lock);
 	list_prepend(&helpers, me);
-	WRITE_UNLOCK(&ip_conntrack_lock);
+	write_unlock_bh(&ip_conntrack_lock);
 
 	return 0;
 }
@@ -878,14 +875,14 @@ void ip_conntrack_helper_unregister(stru
 	struct ip_conntrack_expect *exp, *tmp;
 
 	/* Need write lock here, to delete helper. */
-	WRITE_LOCK(&ip_conntrack_lock);
+	write_lock_bh(&ip_conntrack_lock);
 	LIST_DELETE(&helpers, me);
 
 	/* Get rid of expectations */
 	list_for_each_entry_safe(exp, tmp, &ip_conntrack_expect_list, list) {
 		if (exp->master->helper == me && del_timer(&exp->timeout)) {
 			unlink_expect(exp);
-			destroy_expect(exp);
+			ip_conntrack_expect_put(exp);
 		}
 	}
 	/* Get rid of expecteds, set helpers to NULL. */
@@ -893,7 +890,7 @@ void ip_conntrack_helper_unregister(stru
 	for (i = 0; i < ip_conntrack_htable_size; i++)
 		LIST_FIND_W(&ip_conntrack_hash[i], unhelp,
 			    struct ip_conntrack_tuple_hash *, me);
-	WRITE_UNLOCK(&ip_conntrack_lock);
+	write_unlock_bh(&ip_conntrack_lock);
 
 	/* Someone could be still looking at the helper in a bh. */
 	synchronize_net();
@@ -925,14 +922,14 @@ void ip_ct_refresh_acct(struct ip_conntr
 		ct->timeout.expires = extra_jiffies;
 		ct_add_counters(ct, ctinfo, skb);
 	} else {
-		WRITE_LOCK(&ip_conntrack_lock);
+		write_lock_bh(&ip_conntrack_lock);
 		/* Need del_timer for race avoidance (may already be dying). */
 		if (del_timer(&ct->timeout)) {
 			ct->timeout.expires = jiffies + extra_jiffies;
 			add_timer(&ct->timeout);
 		}
 		ct_add_counters(ct, ctinfo, skb);
-		WRITE_UNLOCK(&ip_conntrack_lock);
+		write_unlock_bh(&ip_conntrack_lock);
 	}
 }
 
@@ -940,10 +937,6 @@ void ip_ct_refresh_acct(struct ip_conntr
 struct sk_buff *
 ip_ct_gather_frags(struct sk_buff *skb, u_int32_t user)
 {
-#ifdef CONFIG_NETFILTER_DEBUG
-	unsigned int olddebug = skb->nf_debug;
-#endif
-
 	skb_orphan(skb);
 
 	local_bh_disable(); 
@@ -953,12 +946,7 @@ ip_ct_gather_frags(struct sk_buff *skb, 
 	if (skb) {
 		ip_send_check(skb->nh.iph);
 		skb->nfcache |= NFC_ALTERED;
-#ifdef CONFIG_NETFILTER_DEBUG
-		/* Packet path as if nothing had happened. */
-		skb->nf_debug = olddebug;
-#endif
 	}
-
 	return skb;
 }
 
@@ -997,7 +985,7 @@ get_next_corpse(int (*iter)(struct ip_co
 {
 	struct ip_conntrack_tuple_hash *h = NULL;
 
-	WRITE_LOCK(&ip_conntrack_lock);
+	write_lock_bh(&ip_conntrack_lock);
 	for (; *bucket < ip_conntrack_htable_size; (*bucket)++) {
 		h = LIST_FIND_W(&ip_conntrack_hash[*bucket], do_iter,
 				struct ip_conntrack_tuple_hash *, iter, data);
@@ -1009,7 +997,7 @@ get_next_corpse(int (*iter)(struct ip_co
 				struct ip_conntrack_tuple_hash *, iter, data);
 	if (h)
 		atomic_inc(&tuplehash_to_ctrack(h)->ct_general.use);
-	WRITE_UNLOCK(&ip_conntrack_lock);
+	write_unlock_bh(&ip_conntrack_lock);
 
 	return h;
 }
@@ -1124,6 +1112,9 @@ void ip_conntrack_cleanup(void)
 		schedule();
 		goto i_see_dead_people;
 	}
+	/* wait until all references to ip_conntrack_untracked are dropped */
+	while (atomic_read(&ip_conntrack_untracked.ct_general.use) > 1)
+		schedule();
 
 	kmem_cache_destroy(ip_conntrack_cachep);
 	kmem_cache_destroy(ip_conntrack_expect_cachep);
@@ -1201,14 +1192,14 @@ int __init ip_conntrack_init(void)
 	}
 
 	/* Don't NEED lock here, but good form anyway. */
-	WRITE_LOCK(&ip_conntrack_lock);
+	write_lock_bh(&ip_conntrack_lock);
 	for (i = 0; i < MAX_IP_CT_PROTO; i++)
 		ip_ct_protos[i] = &ip_conntrack_generic_protocol;
 	/* Sew in builtin protocols. */
 	ip_ct_protos[IPPROTO_TCP] = &ip_conntrack_protocol_tcp;
 	ip_ct_protos[IPPROTO_UDP] = &ip_conntrack_protocol_udp;
 	ip_ct_protos[IPPROTO_ICMP] = &ip_conntrack_protocol_icmp;
-	WRITE_UNLOCK(&ip_conntrack_lock);
+	write_unlock_bh(&ip_conntrack_lock);
 
 	for (i = 0; i < ip_conntrack_htable_size; i++)
 		INIT_LIST_HEAD(&ip_conntrack_hash[i]);
diff --git a/net/ipv4/netfilter/ip_conntrack_ftp.c b/net/ipv4/netfilter/ip_conntrack_ftp.c
--- a/net/ipv4/netfilter/ip_conntrack_ftp.c
+++ b/net/ipv4/netfilter/ip_conntrack_ftp.c
@@ -16,7 +16,6 @@
 #include <net/checksum.h>
 #include <net/tcp.h>
 
-#include <linux/netfilter_ipv4/lockhelp.h>
 #include <linux/netfilter_ipv4/ip_conntrack_helper.h>
 #include <linux/netfilter_ipv4/ip_conntrack_ftp.h>
 #include <linux/moduleparam.h>
@@ -28,7 +27,7 @@ MODULE_DESCRIPTION("ftp connection track
 /* This is slow, but it's simple. --RR */
 static char ftp_buffer[65536];
 
-static DECLARE_LOCK(ip_ftp_lock);
+static DEFINE_SPINLOCK(ip_ftp_lock);
 
 #define MAX_PORTS 8
 static int ports[MAX_PORTS];
@@ -319,7 +318,7 @@ static int help(struct sk_buff **pskb,
 	}
 	datalen = (*pskb)->len - dataoff;
 
-	LOCK_BH(&ip_ftp_lock);
+	spin_lock_bh(&ip_ftp_lock);
 	fb_ptr = skb_header_pointer(*pskb, dataoff,
 				    (*pskb)->len - dataoff, ftp_buffer);
 	BUG_ON(fb_ptr == NULL);
@@ -377,7 +376,7 @@ static int help(struct sk_buff **pskb,
 	       fb_ptr + matchoff, matchlen, ntohl(th->seq) + matchoff);
 			 
 	/* Allocate expectation which will be inserted */
-	exp = ip_conntrack_expect_alloc();
+	exp = ip_conntrack_expect_alloc(ct);
 	if (exp == NULL) {
 		ret = NF_DROP;
 		goto out;
@@ -404,8 +403,7 @@ static int help(struct sk_buff **pskb,
 		   networks, or the packet filter itself). */
 		if (!loose) {
 			ret = NF_ACCEPT;
-			ip_conntrack_expect_free(exp);
-			goto out_update_nl;
+			goto out_put_expect;
 		}
 		exp->tuple.dst.ip = htonl((array[0] << 24) | (array[1] << 16)
 					 | (array[2] << 8) | array[3]);
@@ -420,7 +418,6 @@ static int help(struct sk_buff **pskb,
 		  { 0xFFFFFFFF, { .tcp = { 0xFFFF } }, 0xFF }});
 
 	exp->expectfn = NULL;
-	exp->master = ct;
 
 	/* Now, NAT might want to mangle the packet, and register the
 	 * (possibly changed) expectation itself. */
@@ -429,20 +426,22 @@ static int help(struct sk_buff **pskb,
 				      matchoff, matchlen, exp, &seq);
 	else {
 		/* Can't expect this?  Best to drop packet now. */
-		if (ip_conntrack_expect_related(exp) != 0) {
-			ip_conntrack_expect_free(exp);
+		if (ip_conntrack_expect_related(exp) != 0)
 			ret = NF_DROP;
-		} else
+		else
 			ret = NF_ACCEPT;
 	}
 
+out_put_expect:
+	ip_conntrack_expect_put(exp);
+
 out_update_nl:
 	/* Now if this ends in \n, update ftp info.  Seq may have been
 	 * adjusted by NAT code. */
 	if (ends_in_nl)
 		update_nl_seq(seq, ct_ftp_info,dir);
  out:
-	UNLOCK_BH(&ip_ftp_lock);
+	spin_unlock_bh(&ip_ftp_lock);
 	return ret;
 }
 
diff --git a/net/ipv4/netfilter/ip_conntrack_irc.c b/net/ipv4/netfilter/ip_conntrack_irc.c
--- a/net/ipv4/netfilter/ip_conntrack_irc.c
+++ b/net/ipv4/netfilter/ip_conntrack_irc.c
@@ -29,7 +29,6 @@
 #include <net/checksum.h>
 #include <net/tcp.h>
 
-#include <linux/netfilter_ipv4/lockhelp.h>
 #include <linux/netfilter_ipv4/ip_conntrack_helper.h>
 #include <linux/netfilter_ipv4/ip_conntrack_irc.h>
 #include <linux/moduleparam.h>
@@ -41,7 +40,7 @@ static int max_dcc_channels = 8;
 static unsigned int dcc_timeout = 300;
 /* This is slow, but it's simple. --RR */
 static char irc_buffer[65536];
-static DECLARE_LOCK(irc_buffer_lock);
+static DEFINE_SPINLOCK(irc_buffer_lock);
 
 unsigned int (*ip_nat_irc_hook)(struct sk_buff **pskb,
 				enum ip_conntrack_info ctinfo,
@@ -141,7 +140,7 @@ static int help(struct sk_buff **pskb,
 	if (dataoff >= (*pskb)->len)
 		return NF_ACCEPT;
 
-	LOCK_BH(&irc_buffer_lock);
+	spin_lock_bh(&irc_buffer_lock);
 	ib_ptr = skb_header_pointer(*pskb, dataoff,
 				    (*pskb)->len - dataoff, irc_buffer);
 	BUG_ON(ib_ptr == NULL);
@@ -198,7 +197,7 @@ static int help(struct sk_buff **pskb,
 				continue;
 			}
 
-			exp = ip_conntrack_expect_alloc();
+			exp = ip_conntrack_expect_alloc(ct);
 			if (exp == NULL) {
 				ret = NF_DROP;
 				goto out;
@@ -222,22 +221,20 @@ static int help(struct sk_buff **pskb,
 				{ { 0, { 0 } },
 				  { 0xFFFFFFFF, { .tcp = { 0xFFFF } }, 0xFF }});
 			exp->expectfn = NULL;
-			exp->master = ct;
 			if (ip_nat_irc_hook)
 				ret = ip_nat_irc_hook(pskb, ctinfo, 
 						      addr_beg_p - ib_ptr,
 						      addr_end_p - addr_beg_p,
 						      exp);
-			else if (ip_conntrack_expect_related(exp) != 0) {
-				ip_conntrack_expect_free(exp);
+			else if (ip_conntrack_expect_related(exp) != 0)
 				ret = NF_DROP;
-			}
+			ip_conntrack_expect_put(exp);
 			goto out;
 		} /* for .. NUM_DCCPROTO */
 	} /* while data < ... */
 
  out:
-	UNLOCK_BH(&irc_buffer_lock);
+	spin_unlock_bh(&irc_buffer_lock);
 	return ret;
 }
 
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_sctp.c b/net/ipv4/netfilter/ip_conntrack_proto_sctp.c
--- a/net/ipv4/netfilter/ip_conntrack_proto_sctp.c
+++ b/net/ipv4/netfilter/ip_conntrack_proto_sctp.c
@@ -26,7 +26,6 @@
 
 #include <linux/netfilter_ipv4/ip_conntrack.h>
 #include <linux/netfilter_ipv4/ip_conntrack_protocol.h>
-#include <linux/netfilter_ipv4/lockhelp.h>
 
 #if 0
 #define DEBUGP(format, ...) printk(format, ## __VA_ARGS__)
@@ -35,7 +34,7 @@
 #endif
 
 /* Protects conntrack->proto.sctp */
-static DECLARE_RWLOCK(sctp_lock);
+static DEFINE_RWLOCK(sctp_lock);
 
 /* FIXME: Examine ipfilter's timeouts and conntrack transitions more
    closely.  They're more complex. --RR 
@@ -199,9 +198,9 @@ static int sctp_print_conntrack(struct s
 	DEBUGP(__FUNCTION__);
 	DEBUGP("\n");
 
-	READ_LOCK(&sctp_lock);
+	read_lock_bh(&sctp_lock);
 	state = conntrack->proto.sctp.state;
-	READ_UNLOCK(&sctp_lock);
+	read_unlock_bh(&sctp_lock);
 
 	return seq_printf(s, "%s ", sctp_conntrack_names[state]);
 }
@@ -343,13 +342,13 @@ static int sctp_packet(struct ip_conntra
 
 	oldsctpstate = newconntrack = SCTP_CONNTRACK_MAX;
 	for_each_sctp_chunk (skb, sch, _sch, offset, count) {
-		WRITE_LOCK(&sctp_lock);
+		write_lock_bh(&sctp_lock);
 
 		/* Special cases of Verification tag check (Sec 8.5.1) */
 		if (sch->type == SCTP_CID_INIT) {
 			/* Sec 8.5.1 (A) */
 			if (sh->vtag != 0) {
-				WRITE_UNLOCK(&sctp_lock);
+				write_unlock_bh(&sctp_lock);
 				return -1;
 			}
 		} else if (sch->type == SCTP_CID_ABORT) {
@@ -357,7 +356,7 @@ static int sctp_packet(struct ip_conntra
 			if (!(sh->vtag == conntrack->proto.sctp.vtag[CTINFO2DIR(ctinfo)])
 				&& !(sh->vtag == conntrack->proto.sctp.vtag
 							[1 - CTINFO2DIR(ctinfo)])) {
-				WRITE_UNLOCK(&sctp_lock);
+				write_unlock_bh(&sctp_lock);
 				return -1;
 			}
 		} else if (sch->type == SCTP_CID_SHUTDOWN_COMPLETE) {
@@ -366,13 +365,13 @@ static int sctp_packet(struct ip_conntra
 				&& !(sh->vtag == conntrack->proto.sctp.vtag
 							[1 - CTINFO2DIR(ctinfo)] 
 					&& (sch->flags & 1))) {
-				WRITE_UNLOCK(&sctp_lock);
+				write_unlock_bh(&sctp_lock);
 				return -1;
 			}
 		} else if (sch->type == SCTP_CID_COOKIE_ECHO) {
 			/* Sec 8.5.1 (D) */
 			if (!(sh->vtag == conntrack->proto.sctp.vtag[CTINFO2DIR(ctinfo)])) {
-				WRITE_UNLOCK(&sctp_lock);
+				write_unlock_bh(&sctp_lock);
 				return -1;
 			}
 		}
@@ -384,7 +383,7 @@ static int sctp_packet(struct ip_conntra
 		if (newconntrack == SCTP_CONNTRACK_MAX) {
 			DEBUGP("ip_conntrack_sctp: Invalid dir=%i ctype=%u conntrack=%u\n",
 			       CTINFO2DIR(ctinfo), sch->type, oldsctpstate);
-			WRITE_UNLOCK(&sctp_lock);
+			write_unlock_bh(&sctp_lock);
 			return -1;
 		}
 
@@ -396,7 +395,7 @@ static int sctp_packet(struct ip_conntra
 			ih = skb_header_pointer(skb, offset + sizeof(sctp_chunkhdr_t),
 			                        sizeof(_inithdr), &_inithdr);
 			if (ih == NULL) {
-					WRITE_UNLOCK(&sctp_lock);
+					write_unlock_bh(&sctp_lock);
 					return -1;
 			}
 			DEBUGP("Setting vtag %x for dir %d\n", 
@@ -405,7 +404,7 @@ static int sctp_packet(struct ip_conntra
 		}
 
 		conntrack->proto.sctp.state = newconntrack;
-		WRITE_UNLOCK(&sctp_lock);
+		write_unlock_bh(&sctp_lock);
 	}
 
 	ip_ct_refresh_acct(conntrack, ctinfo, skb, *sctp_timeouts[newconntrack]);
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
--- a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
+++ b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
@@ -36,7 +36,6 @@
 #include <linux/netfilter_ipv4.h>
 #include <linux/netfilter_ipv4/ip_conntrack.h>
 #include <linux/netfilter_ipv4/ip_conntrack_protocol.h>
-#include <linux/netfilter_ipv4/lockhelp.h>
 
 #if 0
 #define DEBUGP printk
@@ -46,7 +45,7 @@
 #endif
 
 /* Protects conntrack->proto.tcp */
-static DECLARE_RWLOCK(tcp_lock);
+static DEFINE_RWLOCK(tcp_lock);
 
 /* "Be conservative in what you do, 
     be liberal in what you accept from others." 
@@ -330,9 +329,9 @@ static int tcp_print_conntrack(struct se
 {
 	enum tcp_conntrack state;
 
-	READ_LOCK(&tcp_lock);
+	read_lock_bh(&tcp_lock);
 	state = conntrack->proto.tcp.state;
-	READ_UNLOCK(&tcp_lock);
+	read_unlock_bh(&tcp_lock);
 
 	return seq_printf(s, "%s ", tcp_conntrack_names[state]);
 }
@@ -738,14 +737,14 @@ void ip_conntrack_tcp_update(struct sk_b
 
 	end = segment_seq_plus_len(ntohl(tcph->seq), skb->len, iph, tcph);
 	
-	WRITE_LOCK(&tcp_lock);
+	write_lock_bh(&tcp_lock);
 	/*
 	 * We have to worry for the ack in the reply packet only...
 	 */
 	if (after(end, conntrack->proto.tcp.seen[dir].td_end))
 		conntrack->proto.tcp.seen[dir].td_end = end;
 	conntrack->proto.tcp.last_end = end;
-	WRITE_UNLOCK(&tcp_lock);
+	write_unlock_bh(&tcp_lock);
 	DEBUGP("tcp_update: sender end=%u maxend=%u maxwin=%u scale=%i "
 	       "receiver end=%u maxend=%u maxwin=%u scale=%i\n",
 		sender->td_end, sender->td_maxend, sender->td_maxwin,
@@ -857,7 +856,7 @@ static int tcp_packet(struct ip_conntrac
 				sizeof(_tcph), &_tcph);
 	BUG_ON(th == NULL);
 	
-	WRITE_LOCK(&tcp_lock);
+	write_lock_bh(&tcp_lock);
 	old_state = conntrack->proto.tcp.state;
 	dir = CTINFO2DIR(ctinfo);
 	index = get_conntrack_index(th);
@@ -879,7 +878,7 @@ static int tcp_packet(struct ip_conntrac
 			 * that the client cannot but retransmit its SYN and 
 			 * thus initiate a clean new session.
 			 */
-		    	WRITE_UNLOCK(&tcp_lock);
+		    	write_unlock_bh(&tcp_lock);
 			if (LOG_INVALID(IPPROTO_TCP))
 				nf_log_packet(PF_INET, 0, skb, NULL, NULL, 
 					  "ip_ct_tcp: killing out of sync session ");
@@ -894,7 +893,7 @@ static int tcp_packet(struct ip_conntrac
 		conntrack->proto.tcp.last_end = 
 		    segment_seq_plus_len(ntohl(th->seq), skb->len, iph, th);
 		
-		WRITE_UNLOCK(&tcp_lock);
+		write_unlock_bh(&tcp_lock);
 		if (LOG_INVALID(IPPROTO_TCP))
 			nf_log_packet(PF_INET, 0, skb, NULL, NULL, 
 				  "ip_ct_tcp: invalid packet ignored ");
@@ -904,7 +903,7 @@ static int tcp_packet(struct ip_conntrac
 		DEBUGP("ip_ct_tcp: Invalid dir=%i index=%u ostate=%u\n",
 		       dir, get_conntrack_index(th),
 		       old_state);
-		WRITE_UNLOCK(&tcp_lock);
+		write_unlock_bh(&tcp_lock);
 		if (LOG_INVALID(IPPROTO_TCP))
 			nf_log_packet(PF_INET, 0, skb, NULL, NULL, 
 				  "ip_ct_tcp: invalid state ");
@@ -918,13 +917,13 @@ static int tcp_packet(struct ip_conntrac
 		    	     conntrack->proto.tcp.seen[dir].td_end)) {	
 		    	/* Attempt to reopen a closed connection.
 		    	* Delete this connection and look up again. */
-		    	WRITE_UNLOCK(&tcp_lock);
+		    	write_unlock_bh(&tcp_lock);
 		    	if (del_timer(&conntrack->timeout))
 		    		conntrack->timeout.function((unsigned long)
 		    					    conntrack);
 		    	return -NF_REPEAT;
 		} else {
-			WRITE_UNLOCK(&tcp_lock);
+			write_unlock_bh(&tcp_lock);
 			if (LOG_INVALID(IPPROTO_TCP))
 				nf_log_packet(PF_INET, 0, skb, NULL, NULL,
 				              "ip_ct_tcp: invalid SYN");
@@ -949,7 +948,7 @@ static int tcp_packet(struct ip_conntrac
 
 	if (!tcp_in_window(&conntrack->proto.tcp, dir, index, 
 			   skb, iph, th)) {
-		WRITE_UNLOCK(&tcp_lock);
+		write_unlock_bh(&tcp_lock);
 		return -NF_ACCEPT;
 	}
     in_window:
@@ -972,7 +971,7 @@ static int tcp_packet(struct ip_conntrac
 	timeout = conntrack->proto.tcp.retrans >= ip_ct_tcp_max_retrans
 		  && *tcp_timeouts[new_state] > ip_ct_tcp_timeout_max_retrans
 		  ? ip_ct_tcp_timeout_max_retrans : *tcp_timeouts[new_state];
-	WRITE_UNLOCK(&tcp_lock);
+	write_unlock_bh(&tcp_lock);
 
 	if (!test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)) {
 		/* If only reply is a RST, we can consider ourselves not to
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_udp.c b/net/ipv4/netfilter/ip_conntrack_proto_udp.c
--- a/net/ipv4/netfilter/ip_conntrack_proto_udp.c
+++ b/net/ipv4/netfilter/ip_conntrack_proto_udp.c
@@ -120,6 +120,7 @@ static int udp_error(struct sk_buff *skb
 	 * and moreover root might send raw packets.
 	 * FIXME: Source route IP option packets --RR */
 	if (hooknum == NF_IP_PRE_ROUTING
+	    && skb->ip_summed != CHECKSUM_UNNECESSARY
 	    && csum_tcpudp_magic(iph->saddr, iph->daddr, udplen, IPPROTO_UDP,
 			         skb->ip_summed == CHECKSUM_HW ? skb->csum
 			      	 : skb_checksum(skb, iph->ihl*4, udplen, 0))) {
diff --git a/net/ipv4/netfilter/ip_conntrack_standalone.c b/net/ipv4/netfilter/ip_conntrack_standalone.c
--- a/net/ipv4/netfilter/ip_conntrack_standalone.c
+++ b/net/ipv4/netfilter/ip_conntrack_standalone.c
@@ -28,8 +28,8 @@
 #include <net/checksum.h>
 #include <net/ip.h>
 
-#define ASSERT_READ_LOCK(x) MUST_BE_READ_LOCKED(&ip_conntrack_lock)
-#define ASSERT_WRITE_LOCK(x) MUST_BE_WRITE_LOCKED(&ip_conntrack_lock)
+#define ASSERT_READ_LOCK(x)
+#define ASSERT_WRITE_LOCK(x)
 
 #include <linux/netfilter_ipv4/ip_conntrack.h>
 #include <linux/netfilter_ipv4/ip_conntrack_protocol.h>
@@ -119,7 +119,7 @@ static struct list_head *ct_get_idx(stru
 
 static void *ct_seq_start(struct seq_file *seq, loff_t *pos)
 {
-	READ_LOCK(&ip_conntrack_lock);
+	read_lock_bh(&ip_conntrack_lock);
 	return ct_get_idx(seq, *pos);
 }
 
@@ -131,7 +131,7 @@ static void *ct_seq_next(struct seq_file
   
 static void ct_seq_stop(struct seq_file *s, void *v)
 {
-	READ_UNLOCK(&ip_conntrack_lock);
+	read_unlock_bh(&ip_conntrack_lock);
 }
  
 static int ct_seq_show(struct seq_file *s, void *v)
@@ -140,7 +140,7 @@ static int ct_seq_show(struct seq_file *
 	const struct ip_conntrack *conntrack = tuplehash_to_ctrack(hash);
 	struct ip_conntrack_protocol *proto;
 
-	MUST_BE_READ_LOCKED(&ip_conntrack_lock);
+	ASSERT_READ_LOCK(&ip_conntrack_lock);
 	IP_NF_ASSERT(conntrack);
 
 	/* we only want to print DIR_ORIGINAL */
@@ -239,7 +239,7 @@ static void *exp_seq_start(struct seq_fi
 
 	/* strange seq_file api calls stop even if we fail,
 	 * thus we need to grab lock since stop unlocks */
-	READ_LOCK(&ip_conntrack_lock);
+	read_lock_bh(&ip_conntrack_lock);
 
 	if (list_empty(e))
 		return NULL;
@@ -267,7 +267,7 @@ static void *exp_seq_next(struct seq_fil
 
 static void exp_seq_stop(struct seq_file *s, void *v)
 {
-	READ_UNLOCK(&ip_conntrack_lock);
+	read_unlock_bh(&ip_conntrack_lock);
 }
 
 static int exp_seq_show(struct seq_file *s, void *v)
@@ -432,6 +432,13 @@ static unsigned int ip_conntrack_defrag(
 				        const struct net_device *out,
 				        int (*okfn)(struct sk_buff *))
 {
+#if !defined(CONFIG_IP_NF_NAT) && !defined(CONFIG_IP_NF_NAT_MODULE)
+	/* Previously seen (loopback)?  Ignore.  Do this before
+           fragment check. */
+	if ((*pskb)->nfct)
+		return NF_ACCEPT;
+#endif
+
 	/* Gather fragments. */
 	if ((*pskb)->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) {
 		*pskb = ip_ct_gather_frags(*pskb,
@@ -921,22 +928,22 @@ int ip_conntrack_protocol_register(struc
 {
 	int ret = 0;
 
-	WRITE_LOCK(&ip_conntrack_lock);
+	write_lock_bh(&ip_conntrack_lock);
 	if (ip_ct_protos[proto->proto] != &ip_conntrack_generic_protocol) {
 		ret = -EBUSY;
 		goto out;
 	}
 	ip_ct_protos[proto->proto] = proto;
  out:
-	WRITE_UNLOCK(&ip_conntrack_lock);
+	write_unlock_bh(&ip_conntrack_lock);
 	return ret;
 }
 
 void ip_conntrack_protocol_unregister(struct ip_conntrack_protocol *proto)
 {
-	WRITE_LOCK(&ip_conntrack_lock);
+	write_lock_bh(&ip_conntrack_lock);
 	ip_ct_protos[proto->proto] = &ip_conntrack_generic_protocol;
-	WRITE_UNLOCK(&ip_conntrack_lock);
+	write_unlock_bh(&ip_conntrack_lock);
 	
 	/* Somebody could be still looking at the proto in bh. */
 	synchronize_net();
@@ -978,7 +985,7 @@ EXPORT_SYMBOL(ip_ct_refresh_acct);
 EXPORT_SYMBOL(ip_ct_protos);
 EXPORT_SYMBOL(ip_ct_find_proto);
 EXPORT_SYMBOL(ip_conntrack_expect_alloc);
-EXPORT_SYMBOL(ip_conntrack_expect_free);
+EXPORT_SYMBOL(ip_conntrack_expect_put);
 EXPORT_SYMBOL(ip_conntrack_expect_related);
 EXPORT_SYMBOL(ip_conntrack_unexpect_related);
 EXPORT_SYMBOL(ip_conntrack_tuple_taken);
diff --git a/net/ipv4/netfilter/ip_conntrack_tftp.c b/net/ipv4/netfilter/ip_conntrack_tftp.c
--- a/net/ipv4/netfilter/ip_conntrack_tftp.c
+++ b/net/ipv4/netfilter/ip_conntrack_tftp.c
@@ -65,7 +65,7 @@ static int tftp_help(struct sk_buff **ps
 		DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
 		DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_REPLY].tuple);
 
-		exp = ip_conntrack_expect_alloc();
+		exp = ip_conntrack_expect_alloc(ct);
 		if (exp == NULL)
 			return NF_DROP;
 
@@ -75,17 +75,15 @@ static int tftp_help(struct sk_buff **ps
 		exp->mask.dst.u.udp.port = 0xffff;
 		exp->mask.dst.protonum = 0xff;
 		exp->expectfn = NULL;
-		exp->master = ct;
 
 		DEBUGP("expect: ");
 		DUMP_TUPLE(&exp->tuple);
 		DUMP_TUPLE(&exp->mask);
 		if (ip_nat_tftp_hook)
 			ret = ip_nat_tftp_hook(pskb, ctinfo, exp);
-		else if (ip_conntrack_expect_related(exp) != 0) {
-			ip_conntrack_expect_free(exp);
+		else if (ip_conntrack_expect_related(exp) != 0)
 			ret = NF_DROP;
-		}
+		ip_conntrack_expect_put(exp);
 		break;
 	case TFTP_OPCODE_DATA:
 	case TFTP_OPCODE_ACK:
diff --git a/net/ipv4/netfilter/ip_nat_amanda.c b/net/ipv4/netfilter/ip_nat_amanda.c
--- a/net/ipv4/netfilter/ip_nat_amanda.c
+++ b/net/ipv4/netfilter/ip_nat_amanda.c
@@ -56,10 +56,8 @@ static unsigned int help(struct sk_buff 
 			break;
 	}
 
-	if (port == 0) {
-		ip_conntrack_expect_free(exp);
+	if (port == 0)
 		return NF_DROP;
-	}
 
 	sprintf(buffer, "%u", port);
 	ret = ip_nat_mangle_udp_packet(pskb, exp->master, ctinfo,
diff --git a/net/ipv4/netfilter/ip_nat_core.c b/net/ipv4/netfilter/ip_nat_core.c
--- a/net/ipv4/netfilter/ip_nat_core.c
+++ b/net/ipv4/netfilter/ip_nat_core.c
@@ -22,8 +22,8 @@
 #include <linux/udp.h>
 #include <linux/jhash.h>
 
-#define ASSERT_READ_LOCK(x) MUST_BE_READ_LOCKED(&ip_nat_lock)
-#define ASSERT_WRITE_LOCK(x) MUST_BE_WRITE_LOCKED(&ip_nat_lock)
+#define ASSERT_READ_LOCK(x)
+#define ASSERT_WRITE_LOCK(x)
 
 #include <linux/netfilter_ipv4/ip_conntrack.h>
 #include <linux/netfilter_ipv4/ip_conntrack_core.h>
@@ -41,7 +41,7 @@
 #define DEBUGP(format, args...)
 #endif
 
-DECLARE_RWLOCK(ip_nat_lock);
+DEFINE_RWLOCK(ip_nat_lock);
 
 /* Calculated at init based on memory size */
 static unsigned int ip_nat_htable_size;
@@ -65,9 +65,9 @@ static void ip_nat_cleanup_conntrack(str
 	if (!(conn->status & IPS_NAT_DONE_MASK))
 		return;
 
-	WRITE_LOCK(&ip_nat_lock);
+	write_lock_bh(&ip_nat_lock);
 	list_del(&conn->nat.info.bysource);
-	WRITE_UNLOCK(&ip_nat_lock);
+	write_unlock_bh(&ip_nat_lock);
 }
 
 /* We do checksum mangling, so if they were wrong before they're still
@@ -142,7 +142,7 @@ find_appropriate_src(const struct ip_con
 	unsigned int h = hash_by_src(tuple);
 	struct ip_conntrack *ct;
 
-	READ_LOCK(&ip_nat_lock);
+	read_lock_bh(&ip_nat_lock);
 	list_for_each_entry(ct, &bysource[h], nat.info.bysource) {
 		if (same_src(ct, tuple)) {
 			/* Copy source part from reply tuple. */
@@ -151,12 +151,12 @@ find_appropriate_src(const struct ip_con
 			result->dst = tuple->dst;
 
 			if (in_range(result, range)) {
-				READ_UNLOCK(&ip_nat_lock);
+				read_unlock_bh(&ip_nat_lock);
 				return 1;
 			}
 		}
 	}
-	READ_UNLOCK(&ip_nat_lock);
+	read_unlock_bh(&ip_nat_lock);
 	return 0;
 }
 
@@ -297,9 +297,9 @@ ip_nat_setup_info(struct ip_conntrack *c
 		unsigned int srchash
 			= hash_by_src(&conntrack->tuplehash[IP_CT_DIR_ORIGINAL]
 				      .tuple);
-		WRITE_LOCK(&ip_nat_lock);
+		write_lock_bh(&ip_nat_lock);
 		list_add(&info->bysource, &bysource[srchash]);
-		WRITE_UNLOCK(&ip_nat_lock);
+		write_unlock_bh(&ip_nat_lock);
 	}
 
 	/* It's done. */
@@ -474,23 +474,23 @@ int ip_nat_protocol_register(struct ip_n
 {
 	int ret = 0;
 
-	WRITE_LOCK(&ip_nat_lock);
+	write_lock_bh(&ip_nat_lock);
 	if (ip_nat_protos[proto->protonum] != &ip_nat_unknown_protocol) {
 		ret = -EBUSY;
 		goto out;
 	}
 	ip_nat_protos[proto->protonum] = proto;
  out:
-	WRITE_UNLOCK(&ip_nat_lock);
+	write_unlock_bh(&ip_nat_lock);
 	return ret;
 }
 
 /* Noone stores the protocol anywhere; simply delete it. */
 void ip_nat_protocol_unregister(struct ip_nat_protocol *proto)
 {
-	WRITE_LOCK(&ip_nat_lock);
+	write_lock_bh(&ip_nat_lock);
 	ip_nat_protos[proto->protonum] = &ip_nat_unknown_protocol;
-	WRITE_UNLOCK(&ip_nat_lock);
+	write_unlock_bh(&ip_nat_lock);
 
 	/* Someone could be still looking at the proto in a bh. */
 	synchronize_net();
@@ -509,13 +509,13 @@ int __init ip_nat_init(void)
 		return -ENOMEM;
 
 	/* Sew in builtin protocols. */
-	WRITE_LOCK(&ip_nat_lock);
+	write_lock_bh(&ip_nat_lock);
 	for (i = 0; i < MAX_IP_NAT_PROTO; i++)
 		ip_nat_protos[i] = &ip_nat_unknown_protocol;
 	ip_nat_protos[IPPROTO_TCP] = &ip_nat_protocol_tcp;
 	ip_nat_protos[IPPROTO_UDP] = &ip_nat_protocol_udp;
 	ip_nat_protos[IPPROTO_ICMP] = &ip_nat_protocol_icmp;
-	WRITE_UNLOCK(&ip_nat_lock);
+	write_unlock_bh(&ip_nat_lock);
 
 	for (i = 0; i < ip_nat_htable_size; i++) {
 		INIT_LIST_HEAD(&bysource[i]);
diff --git a/net/ipv4/netfilter/ip_nat_ftp.c b/net/ipv4/netfilter/ip_nat_ftp.c
--- a/net/ipv4/netfilter/ip_nat_ftp.c
+++ b/net/ipv4/netfilter/ip_nat_ftp.c
@@ -143,10 +143,8 @@ static unsigned int ip_nat_ftp(struct sk
 			break;
 	}
 
-	if (port == 0) {
-		ip_conntrack_expect_free(exp);
+	if (port == 0)
 		return NF_DROP;
-	}
 
 	if (!mangle[type](pskb, newip, port, matchoff, matchlen, ct, ctinfo,
 			  seq)) {
diff --git a/net/ipv4/netfilter/ip_nat_helper.c b/net/ipv4/netfilter/ip_nat_helper.c
--- a/net/ipv4/netfilter/ip_nat_helper.c
+++ b/net/ipv4/netfilter/ip_nat_helper.c
@@ -28,8 +28,8 @@
 #include <net/tcp.h>
 #include <net/udp.h>
 
-#define ASSERT_READ_LOCK(x) MUST_BE_READ_LOCKED(&ip_nat_lock)
-#define ASSERT_WRITE_LOCK(x) MUST_BE_WRITE_LOCKED(&ip_nat_lock)
+#define ASSERT_READ_LOCK(x)
+#define ASSERT_WRITE_LOCK(x)
 
 #include <linux/netfilter_ipv4/ip_conntrack.h>
 #include <linux/netfilter_ipv4/ip_conntrack_helper.h>
@@ -47,7 +47,7 @@
 #define DUMP_OFFSET(x)
 #endif
 
-static DECLARE_LOCK(ip_nat_seqofs_lock);
+static DEFINE_SPINLOCK(ip_nat_seqofs_lock);
 
 /* Setup TCP sequence correction given this change at this sequence */
 static inline void 
@@ -70,7 +70,7 @@ adjust_tcp_sequence(u32 seq,
 	DEBUGP("ip_nat_resize_packet: Seq_offset before: ");
 	DUMP_OFFSET(this_way);
 
-	LOCK_BH(&ip_nat_seqofs_lock);
+	spin_lock_bh(&ip_nat_seqofs_lock);
 
 	/* SYN adjust. If it's uninitialized, or this is after last
 	 * correction, record it: we don't handle more than one
@@ -82,7 +82,7 @@ adjust_tcp_sequence(u32 seq,
 		    this_way->offset_before = this_way->offset_after;
 		    this_way->offset_after += sizediff;
 	}
-	UNLOCK_BH(&ip_nat_seqofs_lock);
+	spin_unlock_bh(&ip_nat_seqofs_lock);
 
 	DEBUGP("ip_nat_resize_packet: Seq_offset after: ");
 	DUMP_OFFSET(this_way);
@@ -142,9 +142,6 @@ static int enlarge_skb(struct sk_buff **
 	/* Transfer socket to new skb. */
 	if ((*pskb)->sk)
 		skb_set_owner_w(nskb, (*pskb)->sk);
-#ifdef CONFIG_NETFILTER_DEBUG
-	nskb->nf_debug = (*pskb)->nf_debug;
-#endif
 	kfree_skb(*pskb);
 	*pskb = nskb;
 	return 1;
diff --git a/net/ipv4/netfilter/ip_nat_irc.c b/net/ipv4/netfilter/ip_nat_irc.c
--- a/net/ipv4/netfilter/ip_nat_irc.c
+++ b/net/ipv4/netfilter/ip_nat_irc.c
@@ -65,10 +65,8 @@ static unsigned int help(struct sk_buff 
 			break;
 	}
 
-	if (port == 0) {
-		ip_conntrack_expect_free(exp);
+	if (port == 0)
 		return NF_DROP;
-	}
 
 	/*      strlen("\1DCC CHAT chat AAAAAAAA P\1\n")=27
 	 *      strlen("\1DCC SCHAT chat AAAAAAAA P\1\n")=28
diff --git a/net/ipv4/netfilter/ip_nat_proto_icmp.c b/net/ipv4/netfilter/ip_nat_proto_icmp.c
--- a/net/ipv4/netfilter/ip_nat_proto_icmp.c
+++ b/net/ipv4/netfilter/ip_nat_proto_icmp.c
@@ -35,16 +35,17 @@ icmp_unique_tuple(struct ip_conntrack_tu
 		  const struct ip_conntrack *conntrack)
 {
 	static u_int16_t id;
-	unsigned int range_size
-		= (unsigned int)range->max.icmp.id - range->min.icmp.id + 1;
+	unsigned int range_size;
 	unsigned int i;
 
+	range_size = ntohs(range->max.icmp.id) - ntohs(range->min.icmp.id) + 1;
 	/* If no range specified... */
 	if (!(range->flags & IP_NAT_RANGE_PROTO_SPECIFIED))
 		range_size = 0xFFFF;
 
 	for (i = 0; i < range_size; i++, id++) {
-		tuple->src.u.icmp.id = range->min.icmp.id + (id % range_size);
+		tuple->src.u.icmp.id = htons(ntohs(range->min.icmp.id) +
+		                             (id % range_size));
 		if (!ip_nat_used_tuple(tuple, conntrack))
 			return 1;
 	}
diff --git a/net/ipv4/netfilter/ip_nat_proto_tcp.c b/net/ipv4/netfilter/ip_nat_proto_tcp.c
--- a/net/ipv4/netfilter/ip_nat_proto_tcp.c
+++ b/net/ipv4/netfilter/ip_nat_proto_tcp.c
@@ -40,7 +40,8 @@ tcp_unique_tuple(struct ip_conntrack_tup
 		 enum ip_nat_manip_type maniptype,
 		 const struct ip_conntrack *conntrack)
 {
-	static u_int16_t port, *portptr;
+	static u_int16_t port;
+	u_int16_t *portptr;
 	unsigned int range_size, min, i;
 
 	if (maniptype == IP_NAT_MANIP_SRC)
diff --git a/net/ipv4/netfilter/ip_nat_proto_udp.c b/net/ipv4/netfilter/ip_nat_proto_udp.c
--- a/net/ipv4/netfilter/ip_nat_proto_udp.c
+++ b/net/ipv4/netfilter/ip_nat_proto_udp.c
@@ -41,7 +41,8 @@ udp_unique_tuple(struct ip_conntrack_tup
 		 enum ip_nat_manip_type maniptype,
 		 const struct ip_conntrack *conntrack)
 {
-	static u_int16_t port, *portptr;
+	static u_int16_t port;
+	u_int16_t *portptr;
 	unsigned int range_size, min, i;
 
 	if (maniptype == IP_NAT_MANIP_SRC)
diff --git a/net/ipv4/netfilter/ip_nat_rule.c b/net/ipv4/netfilter/ip_nat_rule.c
--- a/net/ipv4/netfilter/ip_nat_rule.c
+++ b/net/ipv4/netfilter/ip_nat_rule.c
@@ -19,8 +19,8 @@
 #include <net/route.h>
 #include <linux/bitops.h>
 
-#define ASSERT_READ_LOCK(x) MUST_BE_READ_LOCKED(&ip_nat_lock)
-#define ASSERT_WRITE_LOCK(x) MUST_BE_WRITE_LOCKED(&ip_nat_lock)
+#define ASSERT_READ_LOCK(x)
+#define ASSERT_WRITE_LOCK(x)
 
 #include <linux/netfilter_ipv4/ip_tables.h>
 #include <linux/netfilter_ipv4/ip_nat.h>
diff --git a/net/ipv4/netfilter/ip_nat_standalone.c b/net/ipv4/netfilter/ip_nat_standalone.c
--- a/net/ipv4/netfilter/ip_nat_standalone.c
+++ b/net/ipv4/netfilter/ip_nat_standalone.c
@@ -31,8 +31,8 @@
 #include <net/checksum.h>
 #include <linux/spinlock.h>
 
-#define ASSERT_READ_LOCK(x) MUST_BE_READ_LOCKED(&ip_nat_lock)
-#define ASSERT_WRITE_LOCK(x) MUST_BE_WRITE_LOCKED(&ip_nat_lock)
+#define ASSERT_READ_LOCK(x)
+#define ASSERT_WRITE_LOCK(x)
 
 #include <linux/netfilter_ipv4/ip_nat.h>
 #include <linux/netfilter_ipv4/ip_nat_rule.h>
@@ -102,6 +102,10 @@ ip_nat_fn(unsigned int hooknum,
 		return NF_ACCEPT;
 	}
 
+	/* Don't try to NAT if this packet is not conntracked */
+	if (ct == &ip_conntrack_untracked)
+		return NF_ACCEPT;
+
 	switch (ctinfo) {
 	case IP_CT_RELATED:
 	case IP_CT_RELATED+IP_CT_IS_REPLY:
@@ -373,7 +377,6 @@ static int init_or_cleanup(int init)
  cleanup_rule_init:
 	ip_nat_rule_cleanup();
  cleanup_nothing:
-	MUST_BE_READ_WRITE_UNLOCKED(&ip_nat_lock);
 	return ret;
 }
 
diff --git a/net/ipv4/netfilter/ip_nat_tftp.c b/net/ipv4/netfilter/ip_nat_tftp.c
--- a/net/ipv4/netfilter/ip_nat_tftp.c
+++ b/net/ipv4/netfilter/ip_nat_tftp.c
@@ -45,10 +45,8 @@ static unsigned int help(struct sk_buff 
 	exp->saved_proto.udp.port = exp->tuple.dst.u.tcp.port;
 	exp->dir = IP_CT_DIR_REPLY;
 	exp->expectfn = ip_nat_follow_master;
-	if (ip_conntrack_expect_related(exp) != 0) {
-		ip_conntrack_expect_free(exp);
+	if (ip_conntrack_expect_related(exp) != 0)
 		return NF_DROP;
-	}
 	return NF_ACCEPT;
 }
 
diff --git a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c
--- a/net/ipv4/netfilter/ip_queue.c
+++ b/net/ipv4/netfilter/ip_queue.c
@@ -214,6 +214,12 @@ ipq_build_packet_message(struct ipq_queu
 		break;
 	
 	case IPQ_COPY_PACKET:
+		if (entry->skb->ip_summed == CHECKSUM_HW &&
+		    (*errp = skb_checksum_help(entry->skb,
+		                               entry->info->outdev == NULL))) {
+			read_unlock_bh(&queue_lock);
+			return NULL;
+		}
 		if (copy_range == 0 || copy_range > entry->skb->len)
 			data_len = entry->skb->len;
 		else
@@ -385,6 +391,7 @@ ipq_mangle_ipv4(ipq_verdict_msg_t *v, st
 	if (!skb_ip_make_writable(&e->skb, v->data_len))
 		return -ENOMEM;
 	memcpy(e->skb->data, v->payload, v->data_len);
+	e->skb->ip_summed = CHECKSUM_NONE;
 	e->skb->nfcache |= NFC_ALTERED;
 
 	/*
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -67,7 +67,6 @@ static DECLARE_MUTEX(ipt_mutex);
 /* Must have mutex */
 #define ASSERT_READ_LOCK(x) IP_NF_ASSERT(down_trylock(&ipt_mutex) != 0)
 #define ASSERT_WRITE_LOCK(x) IP_NF_ASSERT(down_trylock(&ipt_mutex) != 0)
-#include <linux/netfilter_ipv4/lockhelp.h>
 #include <linux/netfilter_ipv4/listhelp.h>
 
 #if 0
diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c
--- a/net/ipv4/netfilter/ipt_CLUSTERIP.c
+++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c
@@ -29,9 +29,8 @@
 #include <linux/netfilter_ipv4/ip_tables.h>
 #include <linux/netfilter_ipv4/ipt_CLUSTERIP.h>
 #include <linux/netfilter_ipv4/ip_conntrack.h>
-#include <linux/netfilter_ipv4/lockhelp.h>
 
-#define CLUSTERIP_VERSION "0.6"
+#define CLUSTERIP_VERSION "0.7"
 
 #define DEBUG_CLUSTERIP
 
@@ -41,6 +40,8 @@
 #define DEBUGP
 #endif
 
+#define ASSERT_READ_LOCK(x)
+
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
 MODULE_DESCRIPTION("iptables target for CLUSTERIP");
@@ -67,7 +68,7 @@ static LIST_HEAD(clusterip_configs);
 
 /* clusterip_lock protects the clusterip_configs list _AND_ the configurable
  * data within all structurses (num_local_nodes, local_nodes[]) */
-static DECLARE_RWLOCK(clusterip_lock);
+static DEFINE_RWLOCK(clusterip_lock);
 
 #ifdef CONFIG_PROC_FS
 static struct file_operations clusterip_proc_fops;
@@ -82,9 +83,9 @@ clusterip_config_get(struct clusterip_co
 static inline void
 clusterip_config_put(struct clusterip_config *c) {
 	if (atomic_dec_and_test(&c->refcount)) {
-		WRITE_LOCK(&clusterip_lock);
+		write_lock_bh(&clusterip_lock);
 		list_del(&c->list);
-		WRITE_UNLOCK(&clusterip_lock);
+		write_unlock_bh(&clusterip_lock);
 		dev_mc_delete(c->dev, c->clustermac, ETH_ALEN, 0);
 		dev_put(c->dev);
 		kfree(c);
@@ -97,7 +98,7 @@ __clusterip_config_find(u_int32_t cluste
 {
 	struct list_head *pos;
 
-	MUST_BE_READ_LOCKED(&clusterip_lock);
+	ASSERT_READ_LOCK(&clusterip_lock);
 	list_for_each(pos, &clusterip_configs) {
 		struct clusterip_config *c = list_entry(pos, 
 					struct clusterip_config, list);
@@ -114,14 +115,14 @@ clusterip_config_find_get(u_int32_t clus
 {
 	struct clusterip_config *c;
 
-	READ_LOCK(&clusterip_lock);
+	read_lock_bh(&clusterip_lock);
 	c = __clusterip_config_find(clusterip);
 	if (!c) {
-		READ_UNLOCK(&clusterip_lock);
+		read_unlock_bh(&clusterip_lock);
 		return NULL;
 	}
 	atomic_inc(&c->refcount);
-	READ_UNLOCK(&clusterip_lock);
+	read_unlock_bh(&clusterip_lock);
 
 	return c;
 }
@@ -160,9 +161,9 @@ clusterip_config_init(struct ipt_cluster
 	c->pde->data = c;
 #endif
 
-	WRITE_LOCK(&clusterip_lock);
+	write_lock_bh(&clusterip_lock);
 	list_add(&c->list, &clusterip_configs);
-	WRITE_UNLOCK(&clusterip_lock);
+	write_unlock_bh(&clusterip_lock);
 
 	return c;
 }
@@ -172,25 +173,25 @@ clusterip_add_node(struct clusterip_conf
 {
 	int i;
 
-	WRITE_LOCK(&clusterip_lock);
+	write_lock_bh(&clusterip_lock);
 
 	if (c->num_local_nodes >= CLUSTERIP_MAX_NODES
 	    || nodenum > CLUSTERIP_MAX_NODES) {
-		WRITE_UNLOCK(&clusterip_lock);
+		write_unlock_bh(&clusterip_lock);
 		return 1;
 	}
 
 	/* check if we alrady have this number in our array */
 	for (i = 0; i < c->num_local_nodes; i++) {
 		if (c->local_nodes[i] == nodenum) {
-			WRITE_UNLOCK(&clusterip_lock);
+			write_unlock_bh(&clusterip_lock);
 			return 1;
 		}
 	}
 
 	c->local_nodes[c->num_local_nodes++] = nodenum;
 
-	WRITE_UNLOCK(&clusterip_lock);
+	write_unlock_bh(&clusterip_lock);
 	return 0;
 }
 
@@ -199,10 +200,10 @@ clusterip_del_node(struct clusterip_conf
 {
 	int i;
 
-	WRITE_LOCK(&clusterip_lock);
+	write_lock_bh(&clusterip_lock);
 
 	if (c->num_local_nodes <= 1 || nodenum > CLUSTERIP_MAX_NODES) {
-		WRITE_UNLOCK(&clusterip_lock);
+		write_unlock_bh(&clusterip_lock);
 		return 1;
 	}
 		
@@ -211,12 +212,12 @@ clusterip_del_node(struct clusterip_conf
 			int size = sizeof(u_int16_t)*(c->num_local_nodes-(i+1));
 			memmove(&c->local_nodes[i], &c->local_nodes[i+1], size);
 			c->num_local_nodes--;
-			WRITE_UNLOCK(&clusterip_lock);
+			write_unlock_bh(&clusterip_lock);
 			return 0;
 		}
 	}
 
-	WRITE_UNLOCK(&clusterip_lock);
+	write_unlock_bh(&clusterip_lock);
 	return 1;
 }
 
@@ -286,21 +287,21 @@ clusterip_responsible(struct clusterip_c
 {
 	int i;
 
-	READ_LOCK(&clusterip_lock);
+	read_lock_bh(&clusterip_lock);
 
 	if (config->num_local_nodes == 0) {
-		READ_UNLOCK(&clusterip_lock);
+		read_unlock_bh(&clusterip_lock);
 		return 0;
 	}
 
 	for (i = 0; i < config->num_local_nodes; i++) {
 		if (config->local_nodes[i] == hash) {
-			READ_UNLOCK(&clusterip_lock);
+			read_unlock_bh(&clusterip_lock);
 			return 1;
 		}
 	}
 
-	READ_UNLOCK(&clusterip_lock);
+	read_unlock_bh(&clusterip_lock);
 
 	return 0;
 }
@@ -338,7 +339,7 @@ target(struct sk_buff **pskb,
 	 * error messages (RELATED) and information requests (see below) */
 	if ((*pskb)->nh.iph->protocol == IPPROTO_ICMP
 	    && (ctinfo == IP_CT_RELATED 
-		|| ctinfo == IP_CT_IS_REPLY+IP_CT_IS_REPLY))
+		|| ctinfo == IP_CT_RELATED+IP_CT_IS_REPLY))
 		return IPT_CONTINUE;
 
 	/* ip_conntrack_icmp guarantees us that we only have ICMP_ECHO, 
@@ -523,8 +524,9 @@ arp_mangle(unsigned int hook,
 	    || arp->ar_pln != 4 || arp->ar_hln != ETH_ALEN)
 		return NF_ACCEPT;
 
-	/* we only want to mangle arp replies */
-	if (arp->ar_op != htons(ARPOP_REPLY))
+	/* we only want to mangle arp requests and replies */
+	if (arp->ar_op != htons(ARPOP_REPLY)
+	    && arp->ar_op != htons(ARPOP_REQUEST))
 		return NF_ACCEPT;
 
 	payload = (void *)(arp+1);
@@ -578,7 +580,7 @@ static void *clusterip_seq_start(struct 
 	struct clusterip_config *c = pde->data;
 	unsigned int *nodeidx;
 
-	READ_LOCK(&clusterip_lock);
+	read_lock_bh(&clusterip_lock);
 	if (*pos >= c->num_local_nodes)
 		return NULL;
 
@@ -608,7 +610,7 @@ static void clusterip_seq_stop(struct se
 {
 	kfree(v);
 
-	READ_UNLOCK(&clusterip_lock);
+	read_unlock_bh(&clusterip_lock);
 }
 
 static int clusterip_seq_show(struct seq_file *s, void *v)
diff --git a/net/ipv4/netfilter/ipt_ECN.c b/net/ipv4/netfilter/ipt_ECN.c
--- a/net/ipv4/netfilter/ipt_ECN.c
+++ b/net/ipv4/netfilter/ipt_ECN.c
@@ -61,16 +61,20 @@ set_ect_tcp(struct sk_buff **pskb, const
 	if (!tcph)
 		return 0;
 
-	if (!(einfo->operation & IPT_ECN_OP_SET_ECE
-	      || tcph->ece == einfo->proto.tcp.ece)
-	    && (!(einfo->operation & IPT_ECN_OP_SET_CWR
-		  || tcph->cwr == einfo->proto.tcp.cwr)))
+	if ((!(einfo->operation & IPT_ECN_OP_SET_ECE) ||
+	     tcph->ece == einfo->proto.tcp.ece) &&
+	    ((!(einfo->operation & IPT_ECN_OP_SET_CWR) ||
+	     tcph->cwr == einfo->proto.tcp.cwr)))
 		return 1;
 
 	if (!skb_ip_make_writable(pskb, (*pskb)->nh.iph->ihl*4+sizeof(*tcph)))
 		return 0;
 	tcph = (void *)(*pskb)->nh.iph + (*pskb)->nh.iph->ihl*4;
 
+	if ((*pskb)->ip_summed == CHECKSUM_HW &&
+	    skb_checksum_help(*pskb, inward))
+		return 0;
+
 	diffs[0] = ((u_int16_t *)tcph)[6];
 	if (einfo->operation & IPT_ECN_OP_SET_ECE)
 		tcph->ece = einfo->proto.tcp.ece;
@@ -79,13 +83,10 @@ set_ect_tcp(struct sk_buff **pskb, const
 	diffs[1] = ((u_int16_t *)tcph)[6];
 	diffs[0] = diffs[0] ^ 0xFFFF;
 
-	if ((*pskb)->ip_summed != CHECKSUM_HW)
+	if ((*pskb)->ip_summed != CHECKSUM_UNNECESSARY)
 		tcph->check = csum_fold(csum_partial((char *)diffs,
 						     sizeof(diffs),
 						     tcph->check^0xFFFF));
-	else
-		if (skb_checksum_help(*pskb, inward))
-			return 0;
 	(*pskb)->nfcache |= NFC_ALTERED;
 	return 1;
 }
diff --git a/net/ipv4/netfilter/ipt_MASQUERADE.c b/net/ipv4/netfilter/ipt_MASQUERADE.c
--- a/net/ipv4/netfilter/ipt_MASQUERADE.c
+++ b/net/ipv4/netfilter/ipt_MASQUERADE.c
@@ -33,7 +33,7 @@ MODULE_DESCRIPTION("iptables MASQUERADE 
 #endif
 
 /* Lock protects masq region inside conntrack */
-static DECLARE_RWLOCK(masq_lock);
+static DEFINE_RWLOCK(masq_lock);
 
 /* FIXME: Multiple targets. --RR */
 static int
@@ -103,9 +103,9 @@ masquerade_target(struct sk_buff **pskb,
 		return NF_DROP;
 	}
 
-	WRITE_LOCK(&masq_lock);
+	write_lock_bh(&masq_lock);
 	ct->nat.masq_index = out->ifindex;
-	WRITE_UNLOCK(&masq_lock);
+	write_unlock_bh(&masq_lock);
 
 	/* Transfer from original range. */
 	newrange = ((struct ip_nat_range)
@@ -122,9 +122,9 @@ device_cmp(struct ip_conntrack *i, void 
 {
 	int ret;
 
-	READ_LOCK(&masq_lock);
+	read_lock_bh(&masq_lock);
 	ret = (i->nat.masq_index == (int)(long)ifindex);
-	READ_UNLOCK(&masq_lock);
+	read_unlock_bh(&masq_lock);
 
 	return ret;
 }
diff --git a/net/ipv4/netfilter/ipt_REJECT.c b/net/ipv4/netfilter/ipt_REJECT.c
--- a/net/ipv4/netfilter/ipt_REJECT.c
+++ b/net/ipv4/netfilter/ipt_REJECT.c
@@ -104,10 +104,12 @@ static inline struct rtable *route_rever
 static void send_reset(struct sk_buff *oldskb, int hook)
 {
 	struct sk_buff *nskb;
+	struct iphdr *iph = oldskb->nh.iph;
 	struct tcphdr _otcph, *oth, *tcph;
 	struct rtable *rt;
 	u_int16_t tmp_port;
 	u_int32_t tmp_addr;
+	unsigned int tcplen;
 	int needs_ack;
 	int hh_len;
 
@@ -124,7 +126,16 @@ static void send_reset(struct sk_buff *o
 	if (oth->rst)
 		return;
 
-	/* FIXME: Check checksum --RR */
+	/* Check checksum */
+	tcplen = oldskb->len - iph->ihl * 4;
+	if (((hook != NF_IP_LOCAL_IN && oldskb->ip_summed != CHECKSUM_HW) ||
+	     (hook == NF_IP_LOCAL_IN &&
+	      oldskb->ip_summed != CHECKSUM_UNNECESSARY)) &&
+	    csum_tcpudp_magic(iph->saddr, iph->daddr, tcplen, IPPROTO_TCP,
+	                      oldskb->ip_summed == CHECKSUM_HW ? oldskb->csum :
+	                      skb_checksum(oldskb, iph->ihl * 4, tcplen, 0)))
+		return;
+
 	if ((rt = route_reverse(oldskb, oth, hook)) == NULL)
 		return;
 
diff --git a/net/ipv4/netfilter/ipt_TCPMSS.c b/net/ipv4/netfilter/ipt_TCPMSS.c
--- a/net/ipv4/netfilter/ipt_TCPMSS.c
+++ b/net/ipv4/netfilter/ipt_TCPMSS.c
@@ -61,6 +61,10 @@ ipt_tcpmss_target(struct sk_buff **pskb,
 	if (!skb_ip_make_writable(pskb, (*pskb)->len))
 		return NF_DROP;
 
+	if ((*pskb)->ip_summed == CHECKSUM_HW &&
+	    skb_checksum_help(*pskb, out == NULL))
+		return NF_DROP;
+
 	iph = (*pskb)->nh.iph;
 	tcplen = (*pskb)->len - iph->ihl*4;
 
@@ -186,9 +190,6 @@ ipt_tcpmss_target(struct sk_buff **pskb,
 	       newmss);
 
  retmodified:
-	/* We never hw checksum SYN packets.  */
-	BUG_ON((*pskb)->ip_summed == CHECKSUM_HW);
-
 	(*pskb)->nfcache |= NFC_UNKNOWN | NFC_ALTERED;
 	return IPT_CONTINUE;
 }
diff --git a/net/ipv4/netfilter/ipt_ULOG.c b/net/ipv4/netfilter/ipt_ULOG.c
--- a/net/ipv4/netfilter/ipt_ULOG.c
+++ b/net/ipv4/netfilter/ipt_ULOG.c
@@ -56,7 +56,6 @@
 #include <linux/netfilter.h>
 #include <linux/netfilter_ipv4/ip_tables.h>
 #include <linux/netfilter_ipv4/ipt_ULOG.h>
-#include <linux/netfilter_ipv4/lockhelp.h>
 #include <net/sock.h>
 #include <linux/bitops.h>
 
@@ -99,8 +98,8 @@ typedef struct {
 
 static ulog_buff_t ulog_buffers[ULOG_MAXNLGROUPS];	/* array of buffers */
 
-static struct sock *nflognl;	/* our socket */
-static DECLARE_LOCK(ulog_lock);	/* spinlock */
+static struct sock *nflognl;		/* our socket */
+static DEFINE_SPINLOCK(ulog_lock);	/* spinlock */
 
 /* send one ulog_buff_t to userspace */
 static void ulog_send(unsigned int nlgroupnum)
@@ -135,9 +134,9 @@ static void ulog_timer(unsigned long dat
 
 	/* lock to protect against somebody modifying our structure
 	 * from ipt_ulog_target at the same time */
-	LOCK_BH(&ulog_lock);
+	spin_lock_bh(&ulog_lock);
 	ulog_send(data);
-	UNLOCK_BH(&ulog_lock);
+	spin_unlock_bh(&ulog_lock);
 }
 
 static struct sk_buff *ulog_alloc_skb(unsigned int size)
@@ -193,7 +192,7 @@ static void ipt_ulog_packet(unsigned int
 
 	ub = &ulog_buffers[groupnum];
 	
-	LOCK_BH(&ulog_lock);
+	spin_lock_bh(&ulog_lock);
 
 	if (!ub->skb) {
 		if (!(ub->skb = ulog_alloc_skb(size)))
@@ -278,7 +277,7 @@ static void ipt_ulog_packet(unsigned int
 		ulog_send(groupnum);
 	}
 
-	UNLOCK_BH(&ulog_lock);
+	spin_unlock_bh(&ulog_lock);
 
 	return;
 
@@ -288,7 +287,7 @@ nlmsg_failure:
 alloc_failure:
 	PRINTR("ipt_ULOG: Error building netlink message\n");
 
-	UNLOCK_BH(&ulog_lock);
+	spin_unlock_bh(&ulog_lock);
 }
 
 static unsigned int ipt_ulog_target(struct sk_buff **pskb,
diff --git a/net/ipv4/netfilter/ipt_hashlimit.c b/net/ipv4/netfilter/ipt_hashlimit.c
--- a/net/ipv4/netfilter/ipt_hashlimit.c
+++ b/net/ipv4/netfilter/ipt_hashlimit.c
@@ -37,7 +37,6 @@
 
 #include <linux/netfilter_ipv4/ip_tables.h>
 #include <linux/netfilter_ipv4/ipt_hashlimit.h>
-#include <linux/netfilter_ipv4/lockhelp.h>
 
 /* FIXME: this is just for IP_NF_ASSERRT */
 #include <linux/netfilter_ipv4/ip_conntrack.h>
@@ -92,7 +91,7 @@ struct ipt_hashlimit_htable {
 	struct hlist_head hash[0];	/* hashtable itself */
 };
 
-static DECLARE_LOCK(hashlimit_lock);	/* protects htables list */
+static DEFINE_SPINLOCK(hashlimit_lock);	/* protects htables list */
 static DECLARE_MUTEX(hlimit_mutex);	/* additional checkentry protection */
 static HLIST_HEAD(hashlimit_htables);
 static kmem_cache_t *hashlimit_cachep;
@@ -233,9 +232,9 @@ static int htable_create(struct ipt_hash
 	hinfo->timer.function = htable_gc;
 	add_timer(&hinfo->timer);
 
-	LOCK_BH(&hashlimit_lock);
+	spin_lock_bh(&hashlimit_lock);
 	hlist_add_head(&hinfo->node, &hashlimit_htables);
-	UNLOCK_BH(&hashlimit_lock);
+	spin_unlock_bh(&hashlimit_lock);
 
 	return 0;
 }
@@ -301,15 +300,15 @@ static struct ipt_hashlimit_htable *htab
 	struct ipt_hashlimit_htable *hinfo;
 	struct hlist_node *pos;
 
-	LOCK_BH(&hashlimit_lock);
+	spin_lock_bh(&hashlimit_lock);
 	hlist_for_each_entry(hinfo, pos, &hashlimit_htables, node) {
 		if (!strcmp(name, hinfo->pde->name)) {
 			atomic_inc(&hinfo->use);
-			UNLOCK_BH(&hashlimit_lock);
+			spin_unlock_bh(&hashlimit_lock);
 			return hinfo;
 		}
 	}
-	UNLOCK_BH(&hashlimit_lock);
+	spin_unlock_bh(&hashlimit_lock);
 
 	return NULL;
 }
@@ -317,9 +316,9 @@ static struct ipt_hashlimit_htable *htab
 static void htable_put(struct ipt_hashlimit_htable *hinfo)
 {
 	if (atomic_dec_and_test(&hinfo->use)) {
-		LOCK_BH(&hashlimit_lock);
+		spin_lock_bh(&hashlimit_lock);
 		hlist_del(&hinfo->node);
-		UNLOCK_BH(&hashlimit_lock);
+		spin_unlock_bh(&hashlimit_lock);
 		htable_destroy(hinfo);
 	}
 }
diff --git a/net/ipv4/netfilter/ipt_helper.c b/net/ipv4/netfilter/ipt_helper.c
--- a/net/ipv4/netfilter/ipt_helper.c
+++ b/net/ipv4/netfilter/ipt_helper.c
@@ -53,7 +53,7 @@ match(const struct sk_buff *skb,
 		return ret;
 	}
 
-	READ_LOCK(&ip_conntrack_lock);
+	read_lock_bh(&ip_conntrack_lock);
 	if (!ct->master->helper) {
 		DEBUGP("ipt_helper: master ct %p has no helper\n", 
 			exp->expectant);
@@ -69,7 +69,7 @@ match(const struct sk_buff *skb,
 		ret ^= !strncmp(ct->master->helper->name, info->name, 
 		                strlen(ct->master->helper->name));
 out_unlock:
-	READ_UNLOCK(&ip_conntrack_lock);
+	read_unlock_bh(&ip_conntrack_lock);
 	return ret;
 }
 
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -259,7 +259,7 @@ int raw_rcv(struct sock *sk, struct sk_b
 	return 0;
 }
 
-static int raw_send_hdrinc(struct sock *sk, void *from, int length,
+static int raw_send_hdrinc(struct sock *sk, void *from, size_t length,
 			struct rtable *rt, 
 			unsigned int flags)
 {
@@ -298,7 +298,7 @@ static int raw_send_hdrinc(struct sock *
 		goto error_fault;
 
 	/* We don't modify invalid header */
-	if (length >= sizeof(*iph) && iph->ihl * 4 <= length) {
+	if (length >= sizeof(*iph) && iph->ihl * 4U <= length) {
 		if (!iph->saddr)
 			iph->saddr = rt->rt_src;
 		iph->check   = 0;
@@ -332,7 +332,7 @@ static void raw_probe_proto_opt(struct f
 	u8 __user *type = NULL;
 	u8 __user *code = NULL;
 	int probed = 0;
-	int i;
+	unsigned int i;
 
 	if (!msg->msg_iov)
 		return;
@@ -384,7 +384,7 @@ static int raw_sendmsg(struct kiocb *ioc
 	int err;
 
 	err = -EMSGSIZE;
-	if (len < 0 || len > 0xFFFF)
+	if (len > 0xFFFF)
 		goto out;
 
 	/*
@@ -514,7 +514,10 @@ done:
 		kfree(ipc.opt);
 	ip_rt_put(rt);
 
-out:	return err < 0 ? err : len;
+out:
+	if (err < 0)
+		return err;
+	return len;
 
 do_confirm:
 	dst_confirm(&rt->u.dst);
@@ -610,7 +613,10 @@ static int raw_recvmsg(struct kiocb *ioc
 		copied = skb->len;
 done:
 	skb_free_datagram(sk, skb);
-out:	return err ? err : copied;
+out:
+	if (err)
+		return err;
+	return copied;
 }
 
 static int raw_init(struct sock *sk)
@@ -691,11 +697,11 @@ static int raw_ioctl(struct sock *sk, in
 			struct sk_buff *skb;
 			int amount = 0;
 
-			spin_lock_irq(&sk->sk_receive_queue.lock);
+			spin_lock_bh(&sk->sk_receive_queue.lock);
 			skb = skb_peek(&sk->sk_receive_queue);
 			if (skb != NULL)
 				amount = skb->len;
-			spin_unlock_irq(&sk->sk_receive_queue.lock);
+			spin_unlock_bh(&sk->sk_receive_queue.lock);
 			return put_user(amount, (int __user *)arg);
 		}
 
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -54,6 +54,7 @@
  *		Marc Boucher	:	routing by fwmark
  *	Robert Olsson		:	Added rt_cache statistics
  *	Arnaldo C. Melo		:	Convert proc stuff to seq_file
+ *	Eric Dumazet		:	hashed spinlocks and rt_check_expire() fixes.
  *
  *		This program is free software; you can redistribute it and/or
  *		modify it under the terms of the GNU General Public License
@@ -70,6 +71,7 @@
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/mm.h>
+#include <linux/bootmem.h>
 #include <linux/string.h>
 #include <linux/socket.h>
 #include <linux/sockios.h>
@@ -201,8 +203,37 @@ __u8 ip_tos2prio[16] = {
 
 struct rt_hash_bucket {
 	struct rtable	*chain;
-	spinlock_t	lock;
-} __attribute__((__aligned__(8)));
+};
+#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
+/*
+ * Instead of using one spinlock for each rt_hash_bucket, we use a table of spinlocks
+ * The size of this table is a power of two and depends on the number of CPUS.
+ */
+#if NR_CPUS >= 32
+#define RT_HASH_LOCK_SZ	4096
+#elif NR_CPUS >= 16
+#define RT_HASH_LOCK_SZ	2048
+#elif NR_CPUS >= 8
+#define RT_HASH_LOCK_SZ	1024
+#elif NR_CPUS >= 4
+#define RT_HASH_LOCK_SZ	512
+#else
+#define RT_HASH_LOCK_SZ	256
+#endif
+
+static spinlock_t	*rt_hash_locks;
+# define rt_hash_lock_addr(slot) &rt_hash_locks[(slot) & (RT_HASH_LOCK_SZ - 1)]
+# define rt_hash_lock_init()	{ \
+		int i; \
+		rt_hash_locks = kmalloc(sizeof(spinlock_t) * RT_HASH_LOCK_SZ, GFP_KERNEL); \
+		if (!rt_hash_locks) panic("IP: failed to allocate rt_hash_locks\n"); \
+		for (i = 0; i < RT_HASH_LOCK_SZ; i++) \
+			spin_lock_init(&rt_hash_locks[i]); \
+		}
+#else
+# define rt_hash_lock_addr(slot) NULL
+# define rt_hash_lock_init()
+#endif
 
 static struct rt_hash_bucket 	*rt_hash_table;
 static unsigned			rt_hash_mask;
@@ -575,19 +606,26 @@ static struct rtable **rt_remove_balance
 /* This runs via a timer and thus is always in BH context. */
 static void rt_check_expire(unsigned long dummy)
 {
-	static int rover;
-	int i = rover, t;
+	static unsigned int rover;
+	unsigned int i = rover, goal;
 	struct rtable *rth, **rthp;
 	unsigned long now = jiffies;
+	u64 mult;
 
-	for (t = ip_rt_gc_interval << rt_hash_log; t >= 0;
-	     t -= ip_rt_gc_timeout) {
+	mult = ((u64)ip_rt_gc_interval) << rt_hash_log;
+	if (ip_rt_gc_timeout > 1)
+		do_div(mult, ip_rt_gc_timeout);
+	goal = (unsigned int)mult;
+	if (goal > rt_hash_mask) goal = rt_hash_mask + 1;
+	for (; goal > 0; goal--) {
 		unsigned long tmo = ip_rt_gc_timeout;
 
 		i = (i + 1) & rt_hash_mask;
 		rthp = &rt_hash_table[i].chain;
 
-		spin_lock(&rt_hash_table[i].lock);
+		if (*rthp == 0)
+			continue;
+		spin_lock(rt_hash_lock_addr(i));
 		while ((rth = *rthp) != NULL) {
 			if (rth->u.dst.expires) {
 				/* Entry is expired even if it is in use */
@@ -620,14 +658,14 @@ static void rt_check_expire(unsigned lon
  			rt_free(rth);
 #endif /* CONFIG_IP_ROUTE_MULTIPATH_CACHED */
 		}
-		spin_unlock(&rt_hash_table[i].lock);
+		spin_unlock(rt_hash_lock_addr(i));
 
 		/* Fallback loop breaker. */
 		if (time_after(jiffies, now))
 			break;
 	}
 	rover = i;
-	mod_timer(&rt_periodic_timer, now + ip_rt_gc_interval);
+	mod_timer(&rt_periodic_timer, jiffies + ip_rt_gc_interval);
 }
 
 /* This can run from both BH and non-BH contexts, the latter
@@ -643,11 +681,11 @@ static void rt_run_flush(unsigned long d
 	get_random_bytes(&rt_hash_rnd, 4);
 
 	for (i = rt_hash_mask; i >= 0; i--) {
-		spin_lock_bh(&rt_hash_table[i].lock);
+		spin_lock_bh(rt_hash_lock_addr(i));
 		rth = rt_hash_table[i].chain;
 		if (rth)
 			rt_hash_table[i].chain = NULL;
-		spin_unlock_bh(&rt_hash_table[i].lock);
+		spin_unlock_bh(rt_hash_lock_addr(i));
 
 		for (; rth; rth = next) {
 			next = rth->u.rt_next;
@@ -780,7 +818,7 @@ static int rt_garbage_collect(void)
 
 			k = (k + 1) & rt_hash_mask;
 			rthp = &rt_hash_table[k].chain;
-			spin_lock_bh(&rt_hash_table[k].lock);
+			spin_lock_bh(rt_hash_lock_addr(k));
 			while ((rth = *rthp) != NULL) {
 				if (!rt_may_expire(rth, tmo, expire)) {
 					tmo >>= 1;
@@ -812,7 +850,7 @@ static int rt_garbage_collect(void)
 				goal--;
 #endif /* CONFIG_IP_ROUTE_MULTIPATH_CACHED */
 			}
-			spin_unlock_bh(&rt_hash_table[k].lock);
+			spin_unlock_bh(rt_hash_lock_addr(k));
 			if (goal <= 0)
 				break;
 		}
@@ -882,7 +920,7 @@ restart:
 
 	rthp = &rt_hash_table[hash].chain;
 
-	spin_lock_bh(&rt_hash_table[hash].lock);
+	spin_lock_bh(rt_hash_lock_addr(hash));
 	while ((rth = *rthp) != NULL) {
 #ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
 		if (!(rth->u.dst.flags & DST_BALANCED) &&
@@ -908,7 +946,7 @@ restart:
 			rth->u.dst.__use++;
 			dst_hold(&rth->u.dst);
 			rth->u.dst.lastuse = now;
-			spin_unlock_bh(&rt_hash_table[hash].lock);
+			spin_unlock_bh(rt_hash_lock_addr(hash));
 
 			rt_drop(rt);
 			*rp = rth;
@@ -949,7 +987,7 @@ restart:
 	if (rt->rt_type == RTN_UNICAST || rt->fl.iif == 0) {
 		int err = arp_bind_neighbour(&rt->u.dst);
 		if (err) {
-			spin_unlock_bh(&rt_hash_table[hash].lock);
+			spin_unlock_bh(rt_hash_lock_addr(hash));
 
 			if (err != -ENOBUFS) {
 				rt_drop(rt);
@@ -990,7 +1028,7 @@ restart:
 	}
 #endif
 	rt_hash_table[hash].chain = rt;
-	spin_unlock_bh(&rt_hash_table[hash].lock);
+	spin_unlock_bh(rt_hash_lock_addr(hash));
 	*rp = rt;
 	return 0;
 }
@@ -1058,7 +1096,7 @@ static void rt_del(unsigned hash, struct
 {
 	struct rtable **rthp;
 
-	spin_lock_bh(&rt_hash_table[hash].lock);
+	spin_lock_bh(rt_hash_lock_addr(hash));
 	ip_rt_put(rt);
 	for (rthp = &rt_hash_table[hash].chain; *rthp;
 	     rthp = &(*rthp)->u.rt_next)
@@ -1067,7 +1105,7 @@ static void rt_del(unsigned hash, struct
 			rt_free(rt);
 			break;
 		}
-	spin_unlock_bh(&rt_hash_table[hash].lock);
+	spin_unlock_bh(rt_hash_lock_addr(hash));
 }
 
 void ip_rt_redirect(u32 old_gw, u32 daddr, u32 new_gw,
@@ -1647,7 +1685,7 @@ static void ip_handle_martian_source(str
 		printk(KERN_WARNING "martian source %u.%u.%u.%u from "
 			"%u.%u.%u.%u, on dev %s\n",
 			NIPQUAD(daddr), NIPQUAD(saddr), dev->name);
-		if (dev->hard_header_len) {
+		if (dev->hard_header_len && skb->mac.raw) {
 			int i;
 			unsigned char *p = skb->mac.raw;
 			printk(KERN_WARNING "ll header: ");
@@ -1767,7 +1805,7 @@ static inline int ip_mkroute_input_def(s
 				       struct in_device *in_dev,
 				       u32 daddr, u32 saddr, u32 tos)
 {
-	struct rtable* rth;
+	struct rtable* rth = NULL;
 	int err;
 	unsigned hash;
 
@@ -1794,7 +1832,7 @@ static inline int ip_mkroute_input(struc
 				   u32 daddr, u32 saddr, u32 tos)
 {
 #ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
-	struct rtable* rth;
+	struct rtable* rth = NULL;
 	unsigned char hop, hopcount, lasthop;
 	int err = -EINVAL;
 	unsigned int hash;
@@ -1909,7 +1947,7 @@ static int ip_route_input_slow(struct sk
 	 */
 	if ((err = fib_lookup(&fl, &res)) != 0) {
 		if (!IN_DEV_FORWARD(in_dev))
-			goto e_inval;
+			goto e_hostunreach;
 		goto no_route;
 	}
 	free_res = 1;
@@ -1933,7 +1971,7 @@ static int ip_route_input_slow(struct sk
 	}
 
 	if (!IN_DEV_FORWARD(in_dev))
-		goto e_inval;
+		goto e_hostunreach;
 	if (res.type != RTN_UNICAST)
 		goto martian_destination;
 
@@ -2025,6 +2063,11 @@ martian_destination:
 			"%u.%u.%u.%u, dev %s\n",
 			NIPQUAD(daddr), NIPQUAD(saddr), dev->name);
 #endif
+
+e_hostunreach:
+        err = -EHOSTUNREACH;
+        goto done;
+
 e_inval:
 	err = -EINVAL;
 	goto done;
@@ -2239,7 +2282,7 @@ static inline int ip_mkroute_output_def(
 					struct net_device *dev_out,
 					unsigned flags)
 {
-	struct rtable *rth;
+	struct rtable *rth = NULL;
 	int err = __mkroute_output(&rth, res, fl, oldflp, dev_out, flags);
 	unsigned hash;
 	if (err == 0) {
@@ -2267,7 +2310,7 @@ static inline int ip_mkroute_output(stru
 	unsigned char hop;
 	unsigned hash;
 	int err = -EINVAL;
-	struct rtable *rth;
+	struct rtable *rth = NULL;
 
 	if (res->fi && res->fi->fib_nhs > 1) {
 		unsigned char hopcount = res->fi->fib_nhs;
@@ -2581,7 +2624,7 @@ int ip_route_output_key(struct rtable **
 }
 
 static int rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
-			int nowait)
+			int nowait, unsigned int flags)
 {
 	struct rtable *rt = (struct rtable*)skb->dst;
 	struct rtmsg *r;
@@ -2591,9 +2634,8 @@ static int rt_fill_info(struct sk_buff *
 #ifdef CONFIG_IP_MROUTE
 	struct rtattr *eptr;
 #endif
-	nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(*r));
+	nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*r), flags);
 	r = NLMSG_DATA(nlh);
-	nlh->nlmsg_flags = (nowait && pid) ? NLM_F_MULTI : 0;
 	r->rtm_family	 = AF_INET;
 	r->rtm_dst_len	= 32;
 	r->rtm_src_len	= 0;
@@ -2744,7 +2786,7 @@ int inet_rtm_getroute(struct sk_buff *in
 	NETLINK_CB(skb).dst_pid = NETLINK_CB(in_skb).pid;
 
 	err = rt_fill_info(skb, NETLINK_CB(in_skb).pid, nlh->nlmsg_seq,
-				RTM_NEWROUTE, 0);
+				RTM_NEWROUTE, 0, 0);
 	if (!err)
 		goto out_free;
 	if (err < 0) {
@@ -2781,8 +2823,8 @@ int ip_rt_dump(struct sk_buff *skb,  str
 				continue;
 			skb->dst = dst_clone(&rt->u.dst);
 			if (rt_fill_info(skb, NETLINK_CB(cb->skb).pid,
-					 cb->nlh->nlmsg_seq,
-					 RTM_NEWROUTE, 1) <= 0) {
+					 cb->nlh->nlmsg_seq, RTM_NEWROUTE, 
+					 1, NLM_F_MULTI) <= 0) {
 				dst_release(xchg(&skb->dst, NULL));
 				rcu_read_unlock_bh();
 				goto done;
@@ -3069,12 +3111,14 @@ __setup("rhash_entries=", set_rhash_entr
 
 int __init ip_rt_init(void)
 {
-	int i, order, goal, rc = 0;
+	int rc = 0;
 
 	rt_hash_rnd = (int) ((num_physpages ^ (num_physpages>>8)) ^
 			     (jiffies ^ (jiffies >> 7)));
 
 #ifdef CONFIG_NET_CLS_ROUTE
+	{
+	int order;
 	for (order = 0;
 	     (PAGE_SIZE << order) < 256 * sizeof(struct ip_rt_acct) * NR_CPUS; order++)
 		/* NOTHING */;
@@ -3082,6 +3126,7 @@ int __init ip_rt_init(void)
 	if (!ip_rt_acct)
 		panic("IP: failed to allocate ip_rt_acct\n");
 	memset(ip_rt_acct, 0, PAGE_SIZE << order);
+	}
 #endif
 
 	ipv4_dst_ops.kmem_cachep = kmem_cache_create("ip_dst_cache",
@@ -3092,36 +3137,19 @@ int __init ip_rt_init(void)
 	if (!ipv4_dst_ops.kmem_cachep)
 		panic("IP: failed to allocate ip_dst_cache\n");
 
-	goal = num_physpages >> (26 - PAGE_SHIFT);
-	if (rhash_entries)
-		goal = (rhash_entries * sizeof(struct rt_hash_bucket)) >> PAGE_SHIFT;
-	for (order = 0; (1UL << order) < goal; order++)
-		/* NOTHING */;
-
-	do {
-		rt_hash_mask = (1UL << order) * PAGE_SIZE /
-			sizeof(struct rt_hash_bucket);
-		while (rt_hash_mask & (rt_hash_mask - 1))
-			rt_hash_mask--;
-		rt_hash_table = (struct rt_hash_bucket *)
-			__get_free_pages(GFP_ATOMIC, order);
-	} while (rt_hash_table == NULL && --order > 0);
-
-	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);
-
-	for (rt_hash_log = 0; (1 << rt_hash_log) != rt_hash_mask; rt_hash_log++)
-		/* NOTHING */;
-
-	rt_hash_mask--;
-	for (i = 0; i <= rt_hash_mask; i++) {
-		spin_lock_init(&rt_hash_table[i].lock);
-		rt_hash_table[i].chain = NULL;
-	}
+	rt_hash_table = (struct rt_hash_bucket *)
+		alloc_large_system_hash("IP route cache",
+					sizeof(struct rt_hash_bucket),
+					rhash_entries,
+					(num_physpages >= 128 * 1024) ?
+						(27 - PAGE_SHIFT) :
+						(29 - PAGE_SHIFT),
+					HASH_HIGHMEM,
+					&rt_hash_log,
+					&rt_hash_mask,
+					0);
+	memset(rt_hash_table, 0, (rt_hash_mask + 1) * sizeof(struct rt_hash_bucket));
+	rt_hash_lock_init();
 
 	ipv4_dst_ops.gc_thresh = (rt_hash_mask + 1);
 	ip_rt_max_size = (rt_hash_mask + 1) * 16;
diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c
--- a/net/ipv4/syncookies.c
+++ b/net/ipv4/syncookies.c
@@ -169,10 +169,10 @@ static inline int cookie_check(struct sk
 	return mssind < NUM_MSS ? msstab[mssind] + 1 : 0;
 }
 
-extern struct or_calltable or_ipv4;
+extern struct request_sock_ops tcp_request_sock_ops;
 
 static inline struct sock *get_cookie_sock(struct sock *sk, struct sk_buff *skb,
-					   struct open_request *req,
+					   struct request_sock *req,
 					   struct dst_entry *dst)
 {
 	struct tcp_sock *tp = tcp_sk(sk);
@@ -182,7 +182,7 @@ static inline struct sock *get_cookie_so
 	if (child)
 		tcp_acceptq_queue(sk, req, child);
 	else
-		tcp_openreq_free(req);
+		reqsk_free(req);
 
 	return child;
 }
@@ -190,10 +190,12 @@ static inline struct sock *get_cookie_so
 struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb,
 			     struct ip_options *opt)
 {
+	struct inet_request_sock *ireq;
+	struct tcp_request_sock *treq;
 	struct tcp_sock *tp = tcp_sk(sk);
 	__u32 cookie = ntohl(skb->h.th->ack_seq) - 1; 
 	struct sock *ret = sk;
-	struct open_request *req; 
+	struct request_sock *req; 
 	int mss; 
 	struct rtable *rt; 
 	__u8 rcv_wscale;
@@ -209,19 +211,20 @@ struct sock *cookie_v4_check(struct sock
 
 	NET_INC_STATS_BH(LINUX_MIB_SYNCOOKIESRECV);
 
-	req = tcp_openreq_alloc();
 	ret = NULL;
+	req = reqsk_alloc(&tcp_request_sock_ops); /* for safety */
 	if (!req)
 		goto out;
 
-	req->rcv_isn		= htonl(skb->h.th->seq) - 1;
-	req->snt_isn		= cookie; 
+	ireq = inet_rsk(req);
+	treq = tcp_rsk(req);
+	treq->rcv_isn		= htonl(skb->h.th->seq) - 1;
+	treq->snt_isn		= cookie; 
 	req->mss		= mss;
- 	req->rmt_port		= skb->h.th->source;
-	req->af.v4_req.loc_addr = skb->nh.iph->daddr;
-	req->af.v4_req.rmt_addr = skb->nh.iph->saddr;
-	req->class		= &or_ipv4; /* for savety */
-	req->af.v4_req.opt	= NULL;
+ 	ireq->rmt_port		= skb->h.th->source;
+	ireq->loc_addr		= skb->nh.iph->daddr;
+	ireq->rmt_addr		= skb->nh.iph->saddr;
+	ireq->opt		= NULL;
 
 	/* We throwed the options of the initial SYN away, so we hope
 	 * the ACK carries the same options again (see RFC1122 4.2.3.8)
@@ -229,17 +232,15 @@ struct sock *cookie_v4_check(struct sock
 	if (opt && opt->optlen) {
 		int opt_size = sizeof(struct ip_options) + opt->optlen;
 
-		req->af.v4_req.opt = kmalloc(opt_size, GFP_ATOMIC);
-		if (req->af.v4_req.opt) {
-			if (ip_options_echo(req->af.v4_req.opt, skb)) {
-				kfree(req->af.v4_req.opt);
-				req->af.v4_req.opt = NULL;
-			}
+		ireq->opt = kmalloc(opt_size, GFP_ATOMIC);
+		if (ireq->opt != NULL && ip_options_echo(ireq->opt, skb)) {
+			kfree(ireq->opt);
+			ireq->opt = NULL;
 		}
 	}
 
-	req->snd_wscale = req->rcv_wscale = req->tstamp_ok = 0;
-	req->wscale_ok	= req->sack_ok = 0; 
+	ireq->snd_wscale = ireq->rcv_wscale = ireq->tstamp_ok = 0;
+	ireq->wscale_ok	 = ireq->sack_ok = 0; 
 	req->expires	= 0UL; 
 	req->retrans	= 0; 
 	
@@ -253,15 +254,15 @@ struct sock *cookie_v4_check(struct sock
 		struct flowi fl = { .nl_u = { .ip4_u =
 					      { .daddr = ((opt && opt->srr) ?
 							  opt->faddr :
-							  req->af.v4_req.rmt_addr),
-						.saddr = req->af.v4_req.loc_addr,
+							  ireq->rmt_addr),
+						.saddr = ireq->loc_addr,
 						.tos = RT_CONN_FLAGS(sk) } },
 				    .proto = IPPROTO_TCP,
 				    .uli_u = { .ports =
 					       { .sport = skb->h.th->dest,
 						 .dport = skb->h.th->source } } };
 		if (ip_route_output_key(&rt, &fl)) {
-			tcp_openreq_free(req);
+			reqsk_free(req);
 			goto out; 
 		}
 	}
@@ -272,7 +273,7 @@ struct sock *cookie_v4_check(struct sock
 				  &req->rcv_wnd, &req->window_clamp, 
 				  0, &rcv_wscale);
 	/* BTW win scale with syncookies is 0 by definition */
-	req->rcv_wscale	  = rcv_wscale; 
+	ireq->rcv_wscale  = rcv_wscale; 
 
 	ret = get_cookie_sock(sk, skb, req, &rt->u.dst);
 out:	return ret;
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -118,6 +118,45 @@ static int ipv4_sysctl_forward_strategy(
 	return 1;
 }
 
+static int proc_tcp_congestion_control(ctl_table *ctl, int write, struct file * filp,
+				       void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+	char val[TCP_CA_NAME_MAX];
+	ctl_table tbl = {
+		.data = val,
+		.maxlen = TCP_CA_NAME_MAX,
+	};
+	int ret;
+
+	tcp_get_default_congestion_control(val);
+
+	ret = proc_dostring(&tbl, write, filp, buffer, lenp, ppos);
+	if (write && ret == 0)
+		ret = tcp_set_default_congestion_control(val);
+	return ret;
+}
+
+int sysctl_tcp_congestion_control(ctl_table *table, int __user *name, int nlen,
+				  void __user *oldval, size_t __user *oldlenp,
+				  void __user *newval, size_t newlen,
+				  void **context)
+{
+	char val[TCP_CA_NAME_MAX];
+	ctl_table tbl = {
+		.data = val,
+		.maxlen = TCP_CA_NAME_MAX,
+	};
+	int ret;
+
+	tcp_get_default_congestion_control(val);
+	ret = sysctl_string(&tbl, name, nlen, oldval, oldlenp, newval, newlen,
+			    context);
+	if (ret == 0 && newval && newlen)
+		ret = tcp_set_default_congestion_control(val);
+	return ret;
+}
+
+
 ctl_table ipv4_table[] = {
         {
 		.ctl_name	= NET_IPV4_TCP_TIMESTAMPS,
@@ -612,70 +651,6 @@ ctl_table ipv4_table[] = {
 		.proc_handler	= &proc_dointvec,
 	},
 	{
-		.ctl_name	= NET_TCP_WESTWOOD, 
-		.procname	= "tcp_westwood",
-		.data		= &sysctl_tcp_westwood,
-		.maxlen		= sizeof(int),
-		.mode		= 0644,
-		.proc_handler	= &proc_dointvec,
-	},
-	{
-		.ctl_name	= NET_TCP_VEGAS,
-		.procname	= "tcp_vegas_cong_avoid",
-		.data		= &sysctl_tcp_vegas_cong_avoid,
-		.maxlen		= sizeof(int),
-		.mode		= 0644,
-		.proc_handler	= &proc_dointvec,
-	},
-	{
-		.ctl_name	= NET_TCP_VEGAS_ALPHA,
-		.procname	= "tcp_vegas_alpha",
-		.data		= &sysctl_tcp_vegas_alpha,
-		.maxlen		= sizeof(int),
-		.mode		= 0644,
-		.proc_handler	= &proc_dointvec,
-	},
-	{
-		.ctl_name	= NET_TCP_VEGAS_BETA,
-		.procname	= "tcp_vegas_beta",
-		.data		= &sysctl_tcp_vegas_beta,
-		.maxlen		= sizeof(int),
-		.mode		= 0644,
-		.proc_handler	= &proc_dointvec,
-	},
-	{
-		.ctl_name	= NET_TCP_VEGAS_GAMMA,
-		.procname	= "tcp_vegas_gamma",
-		.data		= &sysctl_tcp_vegas_gamma,
-		.maxlen		= sizeof(int),
-		.mode		= 0644,
-		.proc_handler	= &proc_dointvec,
-	},
-	{
-		.ctl_name	= NET_TCP_BIC,
-		.procname	= "tcp_bic",
-		.data		= &sysctl_tcp_bic,
-		.maxlen		= sizeof(int),
-		.mode		= 0644,
-		.proc_handler	= &proc_dointvec,
-	},
-	{
-		.ctl_name	= NET_TCP_BIC_FAST_CONVERGENCE,
-		.procname	= "tcp_bic_fast_convergence",
-		.data		= &sysctl_tcp_bic_fast_convergence,
-		.maxlen		= sizeof(int),
-		.mode		= 0644,
-		.proc_handler	= &proc_dointvec,
-	},
-	{
-		.ctl_name	= NET_TCP_BIC_LOW_WINDOW,
-		.procname	= "tcp_bic_low_window",
-		.data		= &sysctl_tcp_bic_low_window,
-		.maxlen		= sizeof(int),
-		.mode		= 0644,
-		.proc_handler	= &proc_dointvec,
-	},
-	{
 		.ctl_name	= NET_TCP_MODERATE_RCVBUF,
 		.procname	= "tcp_moderate_rcvbuf",
 		.data		= &sysctl_tcp_moderate_rcvbuf,
@@ -692,13 +667,14 @@ ctl_table ipv4_table[] = {
 		.proc_handler	= &proc_dointvec,
 	},
 	{
-		.ctl_name	= NET_TCP_BIC_BETA,
-		.procname	= "tcp_bic_beta",
-		.data		= &sysctl_tcp_bic_beta,
-		.maxlen		= sizeof(int),
+		.ctl_name	= NET_TCP_CONG_CONTROL,
+		.procname	= "tcp_congestion_control",
 		.mode		= 0644,
-		.proc_handler	= &proc_dointvec,
+		.maxlen		= TCP_CA_NAME_MAX,
+		.proc_handler	= &proc_tcp_congestion_control,
+		.strategy	= &sysctl_tcp_congestion_control,
 	},
+
 	{ .ctl_name = 0 }
 };
 
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -271,7 +271,6 @@ int sysctl_tcp_fin_timeout = TCP_FIN_TIM
 
 DEFINE_SNMP_STAT(struct tcp_mib, tcp_statistics);
 
-kmem_cache_t *tcp_openreq_cachep;
 kmem_cache_t *tcp_bucket_cachep;
 kmem_cache_t *tcp_timewait_cachep;
 
@@ -317,7 +316,7 @@ EXPORT_SYMBOL(tcp_enter_memory_pressure)
 static __inline__ unsigned int tcp_listen_poll(struct sock *sk,
 					       poll_table *wait)
 {
-	return tcp_sk(sk)->accept_queue ? (POLLIN | POLLRDNORM) : 0;
+	return !reqsk_queue_empty(&tcp_sk(sk)->accept_queue) ? (POLLIN | POLLRDNORM) : 0;
 }
 
 /*
@@ -463,28 +462,15 @@ int tcp_listen_start(struct sock *sk)
 {
 	struct inet_sock *inet = inet_sk(sk);
 	struct tcp_sock *tp = tcp_sk(sk);
-	struct tcp_listen_opt *lopt;
+	int rc = reqsk_queue_alloc(&tp->accept_queue, TCP_SYNQ_HSIZE);
+
+	if (rc != 0)
+		return rc;
 
 	sk->sk_max_ack_backlog = 0;
 	sk->sk_ack_backlog = 0;
-	tp->accept_queue = tp->accept_queue_tail = NULL;
-	rwlock_init(&tp->syn_wait_lock);
 	tcp_delack_init(tp);
 
-	lopt = kmalloc(sizeof(struct tcp_listen_opt), GFP_KERNEL);
-	if (!lopt)
-		return -ENOMEM;
-
-	memset(lopt, 0, sizeof(struct tcp_listen_opt));
-	for (lopt->max_qlen_log = 6; ; lopt->max_qlen_log++)
-		if ((1 << lopt->max_qlen_log) >= sysctl_max_syn_backlog)
-			break;
-	get_random_bytes(&lopt->hash_rnd, 4);
-
-	write_lock_bh(&tp->syn_wait_lock);
-	tp->listen_opt = lopt;
-	write_unlock_bh(&tp->syn_wait_lock);
-
 	/* There is race window here: we announce ourselves listening,
 	 * but this transition is still not validated by get_port().
 	 * It is OK, because this socket enters to hash table only
@@ -501,10 +487,7 @@ int tcp_listen_start(struct sock *sk)
 	}
 
 	sk->sk_state = TCP_CLOSE;
-	write_lock_bh(&tp->syn_wait_lock);
-	tp->listen_opt = NULL;
-	write_unlock_bh(&tp->syn_wait_lock);
-	kfree(lopt);
+	reqsk_queue_destroy(&tp->accept_queue);
 	return -EADDRINUSE;
 }
 
@@ -516,25 +499,23 @@ int tcp_listen_start(struct sock *sk)
 static void tcp_listen_stop (struct sock *sk)
 {
 	struct tcp_sock *tp = tcp_sk(sk);
-	struct tcp_listen_opt *lopt = tp->listen_opt;
-	struct open_request *acc_req = tp->accept_queue;
-	struct open_request *req;
+	struct listen_sock *lopt;
+	struct request_sock *acc_req;
+	struct request_sock *req;
 	int i;
 
 	tcp_delete_keepalive_timer(sk);
 
 	/* make all the listen_opt local to us */
-	write_lock_bh(&tp->syn_wait_lock);
-	tp->listen_opt = NULL;
-	write_unlock_bh(&tp->syn_wait_lock);
-	tp->accept_queue = tp->accept_queue_tail = NULL;
+	lopt = reqsk_queue_yank_listen_sk(&tp->accept_queue);
+	acc_req = reqsk_queue_yank_acceptq(&tp->accept_queue);
 
 	if (lopt->qlen) {
 		for (i = 0; i < TCP_SYNQ_HSIZE; i++) {
 			while ((req = lopt->syn_table[i]) != NULL) {
 				lopt->syn_table[i] = req->dl_next;
 				lopt->qlen--;
-				tcp_openreq_free(req);
+				reqsk_free(req);
 
 		/* Following specs, it would be better either to send FIN
 		 * (and enter FIN-WAIT-1, it is normal close)
@@ -574,7 +555,7 @@ static void tcp_listen_stop (struct sock
 		sock_put(child);
 
 		sk_acceptq_removed(sk);
-		tcp_openreq_fastfree(req);
+		__reqsk_free(req);
 	}
 	BUG_TRAP(!sk->sk_ack_backlog);
 }
@@ -603,7 +584,7 @@ static inline void skb_entail(struct soc
 	sk_charge_skb(sk, skb);
 	if (!sk->sk_send_head)
 		sk->sk_send_head = skb;
-	else if (tp->nonagle&TCP_NAGLE_PUSH)
+	if (tp->nonagle & TCP_NAGLE_PUSH)
 		tp->nonagle &= ~TCP_NAGLE_PUSH; 
 }
 
@@ -634,7 +615,7 @@ static ssize_t do_tcp_sendpages(struct s
 			 size_t psize, int flags)
 {
 	struct tcp_sock *tp = tcp_sk(sk);
-	int mss_now;
+	int mss_now, size_goal;
 	int err;
 	ssize_t copied;
 	long timeo = sock_sndtimeo(sk, flags & MSG_DONTWAIT);
@@ -647,6 +628,7 @@ static ssize_t do_tcp_sendpages(struct s
 	clear_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags);
 
 	mss_now = tcp_current_mss(sk, !(flags&MSG_OOB));
+	size_goal = tp->xmit_size_goal;
 	copied = 0;
 
 	err = -EPIPE;
@@ -660,7 +642,7 @@ static ssize_t do_tcp_sendpages(struct s
 		int offset = poffset % PAGE_SIZE;
 		int size = min_t(size_t, psize, PAGE_SIZE - offset);
 
-		if (!sk->sk_send_head || (copy = mss_now - skb->len) <= 0) {
+		if (!sk->sk_send_head || (copy = size_goal - skb->len) <= 0) {
 new_segment:
 			if (!sk_stream_memory_free(sk))
 				goto wait_for_sndbuf;
@@ -671,7 +653,7 @@ new_segment:
 				goto wait_for_memory;
 
 			skb_entail(sk, tp, skb);
-			copy = mss_now;
+			copy = size_goal;
 		}
 
 		if (copy > size)
@@ -712,7 +694,7 @@ new_segment:
 		if (!(psize -= copy))
 			goto out;
 
-		if (skb->len != mss_now || (flags & MSG_OOB))
+		if (skb->len < mss_now || (flags & MSG_OOB))
 			continue;
 
 		if (forced_push(tp)) {
@@ -732,6 +714,7 @@ wait_for_memory:
 			goto do_error;
 
 		mss_now = tcp_current_mss(sk, !(flags&MSG_OOB));
+		size_goal = tp->xmit_size_goal;
 	}
 
 out:
@@ -773,15 +756,20 @@ ssize_t tcp_sendpage(struct socket *sock
 
 static inline int select_size(struct sock *sk, struct tcp_sock *tp)
 {
-	int tmp = tp->mss_cache_std;
+	int tmp = tp->mss_cache;
 
 	if (sk->sk_route_caps & NETIF_F_SG) {
-		int pgbreak = SKB_MAX_HEAD(MAX_TCP_HEADER);
+		if (sk->sk_route_caps & NETIF_F_TSO)
+			tmp = 0;
+		else {
+			int pgbreak = SKB_MAX_HEAD(MAX_TCP_HEADER);
 
-		if (tmp >= pgbreak &&
-		    tmp <= pgbreak + (MAX_SKB_FRAGS - 1) * PAGE_SIZE)
-			tmp = pgbreak;
+			if (tmp >= pgbreak &&
+			    tmp <= pgbreak + (MAX_SKB_FRAGS - 1) * PAGE_SIZE)
+				tmp = pgbreak;
+		}
 	}
+
 	return tmp;
 }
 
@@ -792,7 +780,7 @@ int tcp_sendmsg(struct kiocb *iocb, stru
 	struct tcp_sock *tp = tcp_sk(sk);
 	struct sk_buff *skb;
 	int iovlen, flags;
-	int mss_now;
+	int mss_now, size_goal;
 	int err, copied;
 	long timeo;
 
@@ -811,6 +799,7 @@ int tcp_sendmsg(struct kiocb *iocb, stru
 	clear_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags);
 
 	mss_now = tcp_current_mss(sk, !(flags&MSG_OOB));
+	size_goal = tp->xmit_size_goal;
 
 	/* Ok commence sending. */
 	iovlen = msg->msg_iovlen;
@@ -833,7 +822,7 @@ int tcp_sendmsg(struct kiocb *iocb, stru
 			skb = sk->sk_write_queue.prev;
 
 			if (!sk->sk_send_head ||
-			    (copy = mss_now - skb->len) <= 0) {
+			    (copy = size_goal - skb->len) <= 0) {
 
 new_segment:
 				/* Allocate new segment. If the interface is SG,
@@ -856,7 +845,7 @@ new_segment:
 					skb->ip_summed = CHECKSUM_HW;
 
 				skb_entail(sk, tp, skb);
-				copy = mss_now;
+				copy = size_goal;
 			}
 
 			/* Try to append data to the end of skb. */
@@ -891,11 +880,6 @@ new_segment:
 					tcp_mark_push(tp, skb);
 					goto new_segment;
 				} else if (page) {
-					/* If page is cached, align
-					 * offset to L1 cache boundary
-					 */
-					off = (off + L1_CACHE_BYTES - 1) &
-					      ~(L1_CACHE_BYTES - 1);
 					if (off == PAGE_SIZE) {
 						put_page(page);
 						TCP_PAGE(sk) = page = NULL;
@@ -956,7 +940,7 @@ new_segment:
 			if ((seglen -= copy) == 0 && iovlen == 0)
 				goto out;
 
-			if (skb->len != mss_now || (flags & MSG_OOB))
+			if (skb->len < mss_now || (flags & MSG_OOB))
 				continue;
 
 			if (forced_push(tp)) {
@@ -976,6 +960,7 @@ wait_for_memory:
 				goto do_error;
 
 			mss_now = tcp_current_mss(sk, !(flags&MSG_OOB));
+			size_goal = tp->xmit_size_goal;
 		}
 	}
 
@@ -1120,7 +1105,7 @@ static void tcp_prequeue_process(struct 
 	struct sk_buff *skb;
 	struct tcp_sock *tp = tcp_sk(sk);
 
-	NET_ADD_STATS_USER(LINUX_MIB_TCPPREQUEUED, skb_queue_len(&tp->ucopy.prequeue));
+	NET_INC_STATS_USER(LINUX_MIB_TCPPREQUEUED);
 
 	/* RX process wants to run with disabled BHs, though it is not
 	 * necessary */
@@ -1345,7 +1330,7 @@ int tcp_recvmsg(struct kiocb *iocb, stru
 
 		cleanup_rbuf(sk, copied);
 
-		if (tp->ucopy.task == user_recv) {
+		if (!sysctl_tcp_low_latency && tp->ucopy.task == user_recv) {
 			/* Install new reader */
 			if (!user_recv && !(flags & (MSG_TRUNC | MSG_PEEK))) {
 				user_recv = current;
@@ -1384,7 +1369,7 @@ int tcp_recvmsg(struct kiocb *iocb, stru
 			 * is not empty. It is more elegant, but eats cycles,
 			 * unfortunately.
 			 */
-			if (skb_queue_len(&tp->ucopy.prequeue))
+			if (!skb_queue_empty(&tp->ucopy.prequeue))
 				goto do_prequeue;
 
 			/* __ Set realtime policy in scheduler __ */
@@ -1409,7 +1394,7 @@ int tcp_recvmsg(struct kiocb *iocb, stru
 			}
 
 			if (tp->rcv_nxt == tp->copied_seq &&
-			    skb_queue_len(&tp->ucopy.prequeue)) {
+			    !skb_queue_empty(&tp->ucopy.prequeue)) {
 do_prequeue:
 				tcp_prequeue_process(sk);
 
@@ -1491,7 +1476,7 @@ skip_copy:
 	} while (len > 0);
 
 	if (user_recv) {
-		if (skb_queue_len(&tp->ucopy.prequeue)) {
+		if (!skb_queue_empty(&tp->ucopy.prequeue)) {
 			int chunk;
 
 			tp->ucopy.len = copied > 0 ? len : 0;
@@ -1868,11 +1853,11 @@ static int wait_for_connect(struct sock 
 		prepare_to_wait_exclusive(sk->sk_sleep, &wait,
 					  TASK_INTERRUPTIBLE);
 		release_sock(sk);
-		if (!tp->accept_queue)
+		if (reqsk_queue_empty(&tp->accept_queue))
 			timeo = schedule_timeout(timeo);
 		lock_sock(sk);
 		err = 0;
-		if (tp->accept_queue)
+		if (!reqsk_queue_empty(&tp->accept_queue))
 			break;
 		err = -EINVAL;
 		if (sk->sk_state != TCP_LISTEN)
@@ -1895,7 +1880,6 @@ static int wait_for_connect(struct sock 
 struct sock *tcp_accept(struct sock *sk, int flags, int *err)
 {
 	struct tcp_sock *tp = tcp_sk(sk);
-	struct open_request *req;
 	struct sock *newsk;
 	int error;
 
@@ -1906,37 +1890,31 @@ struct sock *tcp_accept(struct sock *sk,
 	 */
 	error = -EINVAL;
 	if (sk->sk_state != TCP_LISTEN)
-		goto out;
+		goto out_err;
 
 	/* Find already established connection */
-	if (!tp->accept_queue) {
+	if (reqsk_queue_empty(&tp->accept_queue)) {
 		long timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
 
 		/* If this is a non blocking socket don't sleep */
 		error = -EAGAIN;
 		if (!timeo)
-			goto out;
+			goto out_err;
 
 		error = wait_for_connect(sk, timeo);
 		if (error)
-			goto out;
+			goto out_err;
 	}
 
-	req = tp->accept_queue;
-	if ((tp->accept_queue = req->dl_next) == NULL)
-		tp->accept_queue_tail = NULL;
-
- 	newsk = req->sk;
-	sk_acceptq_removed(sk);
-	tcp_openreq_fastfree(req);
+	newsk = reqsk_queue_get_child(&tp->accept_queue, sk);
 	BUG_TRAP(newsk->sk_state != TCP_SYN_RECV);
-	release_sock(sk);
-	return newsk;
-
 out:
 	release_sock(sk);
+	return newsk;
+out_err:
+	newsk = NULL;
 	*err = error;
-	return NULL;
+	goto out;
 }
 
 /*
@@ -1953,6 +1931,25 @@ int tcp_setsockopt(struct sock *sk, int 
 		return tp->af_specific->setsockopt(sk, level, optname,
 						   optval, optlen);
 
+	/* This is a string value all the others are int's */
+	if (optname == TCP_CONGESTION) {
+		char name[TCP_CA_NAME_MAX];
+
+		if (optlen < 1)
+			return -EINVAL;
+
+		val = strncpy_from_user(name, optval,
+					min(TCP_CA_NAME_MAX-1, optlen));
+		if (val < 0)
+			return -EFAULT;
+		name[val] = 0;
+
+		lock_sock(sk);
+		err = tcp_set_congestion_control(tp, name);
+		release_sock(sk);
+		return err;
+	}
+
 	if (optlen < sizeof(int))
 		return -EINVAL;
 
@@ -2135,7 +2132,7 @@ void tcp_get_info(struct sock *sk, struc
 
 	info->tcpi_rto = jiffies_to_usecs(tp->rto);
 	info->tcpi_ato = jiffies_to_usecs(tp->ack.ato);
-	info->tcpi_snd_mss = tp->mss_cache_std;
+	info->tcpi_snd_mss = tp->mss_cache;
 	info->tcpi_rcv_mss = tp->ack.rcv_mss;
 
 	info->tcpi_unacked = tp->packets_out;
@@ -2185,7 +2182,7 @@ int tcp_getsockopt(struct sock *sk, int 
 
 	switch (optname) {
 	case TCP_MAXSEG:
-		val = tp->mss_cache_std;
+		val = tp->mss_cache;
 		if (!val && ((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN)))
 			val = tp->rx_opt.user_mss;
 		break;
@@ -2237,6 +2234,16 @@ int tcp_getsockopt(struct sock *sk, int 
 	case TCP_QUICKACK:
 		val = !tp->ack.pingpong;
 		break;
+
+	case TCP_CONGESTION:
+		if (get_user(len, optlen))
+			return -EFAULT;
+		len = min_t(unsigned int, len, TCP_CA_NAME_MAX);
+		if (put_user(len, optlen))
+			return -EFAULT;
+		if (copy_to_user(optval, tp->ca_ops->name, len))
+			return -EFAULT;
+		return 0;
 	default:
 		return -ENOPROTOOPT;
 	};
@@ -2250,7 +2257,7 @@ int tcp_getsockopt(struct sock *sk, int 
 
 
 extern void __skb_cb_too_small_for_tcp(int, int);
-extern void tcpdiag_init(void);
+extern struct tcp_congestion_ops tcp_reno;
 
 static __initdata unsigned long thash_entries;
 static int __init set_thash_entries(char *str)
@@ -2271,13 +2278,6 @@ void __init tcp_init(void)
 		__skb_cb_too_small_for_tcp(sizeof(struct tcp_skb_cb),
 					   sizeof(skb->cb));
 
-	tcp_openreq_cachep = kmem_cache_create("tcp_open_request",
-						   sizeof(struct open_request),
-					       0, SLAB_HWCACHE_ALIGN,
-					       NULL, NULL);
-	if (!tcp_openreq_cachep)
-		panic("tcp_init: Cannot alloc open_request cache.");
-
 	tcp_bucket_cachep = kmem_cache_create("tcp_bind_bucket",
 					      sizeof(struct tcp_bind_bucket),
 					      0, SLAB_HWCACHE_ALIGN,
@@ -2366,6 +2366,8 @@ void __init tcp_init(void)
 	printk(KERN_INFO "TCP: Hash tables configured "
 	       "(established %d bind %d)\n",
 	       tcp_ehash_size << 1, tcp_bhash_size);
+
+	tcp_register_congestion_control(&tcp_reno);
 }
 
 EXPORT_SYMBOL(tcp_accept);
@@ -2374,7 +2376,6 @@ EXPORT_SYMBOL(tcp_destroy_sock);
 EXPORT_SYMBOL(tcp_disconnect);
 EXPORT_SYMBOL(tcp_getsockopt);
 EXPORT_SYMBOL(tcp_ioctl);
-EXPORT_SYMBOL(tcp_openreq_cachep);
 EXPORT_SYMBOL(tcp_poll);
 EXPORT_SYMBOL(tcp_read_sock);
 EXPORT_SYMBOL(tcp_recvmsg);
diff --git a/net/ipv4/tcp_bic.c b/net/ipv4/tcp_bic.c
new file mode 100644
--- /dev/null
+++ b/net/ipv4/tcp_bic.c
@@ -0,0 +1,331 @@
+/*
+ * Binary Increase Congestion control for TCP
+ *
+ * This is from the implementation of BICTCP in
+ * Lison-Xu, Kahaled Harfoush, and Injong Rhee.
+ *  "Binary Increase Congestion Control for Fast, Long Distance
+ *  Networks" in InfoComm 2004
+ * Available from:
+ *  http://www.csc.ncsu.edu/faculty/rhee/export/bitcp.pdf
+ *
+ * Unless BIC is enabled and congestion window is large
+ * this behaves the same as the original Reno.
+ */
+
+#include <linux/config.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <net/tcp.h>
+
+
+#define BICTCP_BETA_SCALE    1024	/* Scale factor beta calculation
+					 * max_cwnd = snd_cwnd * beta
+					 */
+#define BICTCP_B		4	 /*
+					  * In binary search,
+					  * go to point (max+min)/N
+					  */
+
+static int fast_convergence = 1;
+static int max_increment = 32;
+static int low_window = 14;
+static int beta = 819;		/* = 819/1024 (BICTCP_BETA_SCALE) */
+static int low_utilization_threshold = 153;
+static int low_utilization_period = 2;
+static int initial_ssthresh = 100;
+static int smooth_part = 20;
+
+module_param(fast_convergence, int, 0644);
+MODULE_PARM_DESC(fast_convergence, "turn on/off fast convergence");
+module_param(max_increment, int, 0644);
+MODULE_PARM_DESC(max_increment, "Limit on increment allowed during binary search");
+module_param(low_window, int, 0644);
+MODULE_PARM_DESC(low_window, "lower bound on congestion window (for TCP friendliness)");
+module_param(beta, int, 0644);
+MODULE_PARM_DESC(beta, "beta for multiplicative increase");
+module_param(low_utilization_threshold, int, 0644);
+MODULE_PARM_DESC(low_utilization_threshold, "percent (scaled by 1024) for low utilization mode");
+module_param(low_utilization_period, int, 0644);
+MODULE_PARM_DESC(low_utilization_period, "if average delay exceeds then goto to low utilization mode (seconds)");
+module_param(initial_ssthresh, int, 0644);
+MODULE_PARM_DESC(initial_ssthresh, "initial value of slow start threshold");
+module_param(smooth_part, int, 0644);
+MODULE_PARM_DESC(smooth_part, "log(B/(B*Smin))/log(B/(B-1))+B, # of RTT from Wmax-B to Wmax");
+
+
+/* BIC TCP Parameters */
+struct bictcp {
+	u32	cnt;		/* increase cwnd by 1 after ACKs */
+	u32 	last_max_cwnd;	/* last maximum snd_cwnd */
+	u32	loss_cwnd;	/* congestion window at last loss */
+	u32	last_cwnd;	/* the last snd_cwnd */
+	u32	last_time;	/* time when updated last_cwnd */
+	u32	delay_min;	/* min delay */
+	u32	delay_max;	/* max delay */
+	u32	last_delay;
+	u8	low_utilization;/* 0: high; 1: low */
+	u32	low_utilization_start;	/* starting time of low utilization detection*/
+	u32	epoch_start;	/* beginning of an epoch */
+#define ACK_RATIO_SHIFT	4
+	u32	delayed_ack;	/* estimate the ratio of Packets/ACKs << 4 */
+};
+
+static inline void bictcp_reset(struct bictcp *ca)
+{
+	ca->cnt = 0;
+	ca->last_max_cwnd = 0;
+	ca->loss_cwnd = 0;
+	ca->last_cwnd = 0;
+	ca->last_time = 0;
+	ca->delay_min = 0;
+	ca->delay_max = 0;
+	ca->last_delay = 0;
+	ca->low_utilization = 0;
+	ca->low_utilization_start = 0;
+	ca->epoch_start = 0;
+	ca->delayed_ack = 2 << ACK_RATIO_SHIFT;
+}
+
+static void bictcp_init(struct tcp_sock *tp)
+{
+	bictcp_reset(tcp_ca(tp));
+	if (initial_ssthresh)
+		tp->snd_ssthresh = initial_ssthresh;
+}
+
+/*
+ * Compute congestion window to use.
+ */
+static inline void bictcp_update(struct bictcp *ca, u32 cwnd)
+{
+	if (ca->last_cwnd == cwnd &&
+	    (s32)(tcp_time_stamp - ca->last_time) <= HZ / 32)
+		return;
+
+	ca->last_cwnd = cwnd;
+	ca->last_time = tcp_time_stamp;
+
+	if (ca->epoch_start == 0) /* record the beginning of an epoch */
+		ca->epoch_start = tcp_time_stamp;
+
+	/* start off normal */
+	if (cwnd <= low_window) {
+		ca->cnt = cwnd;
+		return;
+	}
+
+	/* binary increase */
+	if (cwnd < ca->last_max_cwnd) {
+		__u32 	dist = (ca->last_max_cwnd - cwnd)
+			/ BICTCP_B;
+
+		if (dist > max_increment)
+			/* linear increase */
+			ca->cnt = cwnd / max_increment;
+		else if (dist <= 1U)
+			/* binary search increase */
+			ca->cnt = (cwnd * smooth_part) / BICTCP_B;
+		else
+			/* binary search increase */
+			ca->cnt = cwnd / dist;
+	} else {
+		/* slow start AMD linear increase */
+		if (cwnd < ca->last_max_cwnd + BICTCP_B)
+			/* slow start */
+			ca->cnt = (cwnd * smooth_part) / BICTCP_B;
+		else if (cwnd < ca->last_max_cwnd + max_increment*(BICTCP_B-1))
+			/* slow start */
+			ca->cnt = (cwnd * (BICTCP_B-1))
+				/ cwnd-ca->last_max_cwnd;
+		else
+			/* linear increase */
+			ca->cnt = cwnd / max_increment;
+	}
+
+	/* if in slow start or link utilization is very low */
+	if ( ca->loss_cwnd == 0 ||
+	     (cwnd > ca->loss_cwnd && ca->low_utilization)) {
+		if (ca->cnt > 20) /* increase cwnd 5% per RTT */
+			ca->cnt = 20;
+	}
+
+	ca->cnt = (ca->cnt << ACK_RATIO_SHIFT) / ca->delayed_ack;
+	if (ca->cnt == 0)			/* cannot be zero */
+		ca->cnt = 1;
+}
+
+
+/* Detect low utilization in congestion avoidance */
+static inline void bictcp_low_utilization(struct tcp_sock *tp, int flag)
+{
+	struct bictcp *ca = tcp_ca(tp);
+	u32 dist, delay;
+
+	/* No time stamp */
+	if (!(tp->rx_opt.saw_tstamp && tp->rx_opt.rcv_tsecr) ||
+	     /* Discard delay samples right after fast recovery */
+	     tcp_time_stamp < ca->epoch_start + HZ ||
+	     /* this delay samples may not be accurate */
+	     flag == 0) {
+		ca->last_delay = 0;
+		goto notlow;
+	}
+
+	delay = ca->last_delay<<3;	/* use the same scale as tp->srtt*/
+	ca->last_delay = tcp_time_stamp - tp->rx_opt.rcv_tsecr;
+	if (delay == 0) 		/* no previous delay sample */
+		goto notlow;
+
+	/* first time call or link delay decreases */
+	if (ca->delay_min == 0 || ca->delay_min > delay) {
+		ca->delay_min = ca->delay_max = delay;
+		goto notlow;
+	}
+
+	if (ca->delay_max < delay)
+		ca->delay_max = delay;
+
+	/* utilization is low, if avg delay < dist*threshold
+	   for checking_period time */
+	dist = ca->delay_max - ca->delay_min;
+	if (dist <= ca->delay_min>>6 ||
+	    tp->srtt - ca->delay_min >=  (dist*low_utilization_threshold)>>10)
+		goto notlow;
+
+	if (ca->low_utilization_start == 0) {
+		ca->low_utilization = 0;
+		ca->low_utilization_start = tcp_time_stamp;
+	} else if ((s32)(tcp_time_stamp - ca->low_utilization_start)
+			> low_utilization_period*HZ) {
+		ca->low_utilization = 1;
+	}
+
+	return;
+
+ notlow:
+	ca->low_utilization = 0;
+	ca->low_utilization_start = 0;
+
+}
+
+static void bictcp_cong_avoid(struct tcp_sock *tp, u32 ack,
+			      u32 seq_rtt, u32 in_flight, int data_acked)
+{
+	struct bictcp *ca = tcp_ca(tp);
+
+	bictcp_low_utilization(tp, data_acked);
+
+	if (in_flight < tp->snd_cwnd)
+		return;
+
+	if (tp->snd_cwnd <= tp->snd_ssthresh) {
+		/* In "safe" area, increase. */
+		if (tp->snd_cwnd < tp->snd_cwnd_clamp)
+			tp->snd_cwnd++;
+	} else {
+		bictcp_update(ca, tp->snd_cwnd);
+
+                /* In dangerous area, increase slowly.
+		 * In theory this is tp->snd_cwnd += 1 / tp->snd_cwnd
+		 */
+		if (tp->snd_cwnd_cnt >= ca->cnt) {
+			if (tp->snd_cwnd < tp->snd_cwnd_clamp)
+				tp->snd_cwnd++;
+			tp->snd_cwnd_cnt = 0;
+		} else
+			tp->snd_cwnd_cnt++;
+	}
+
+}
+
+/*
+ *	behave like Reno until low_window is reached,
+ *	then increase congestion window slowly
+ */
+static u32 bictcp_recalc_ssthresh(struct tcp_sock *tp)
+{
+	struct bictcp *ca = tcp_ca(tp);
+
+	ca->epoch_start = 0;	/* end of epoch */
+
+	/* in case of wrong delay_max*/
+	if (ca->delay_min > 0 && ca->delay_max > ca->delay_min)
+		ca->delay_max = ca->delay_min
+			+ ((ca->delay_max - ca->delay_min)* 90) / 100;
+
+	/* Wmax and fast convergence */
+	if (tp->snd_cwnd < ca->last_max_cwnd && fast_convergence)
+		ca->last_max_cwnd = (tp->snd_cwnd * (BICTCP_BETA_SCALE + beta))
+			/ (2 * BICTCP_BETA_SCALE);
+	else
+		ca->last_max_cwnd = tp->snd_cwnd;
+
+	ca->loss_cwnd = tp->snd_cwnd;
+
+
+	if (tp->snd_cwnd <= low_window)
+		return max(tp->snd_cwnd >> 1U, 2U);
+	else
+		return max((tp->snd_cwnd * beta) / BICTCP_BETA_SCALE, 2U);
+}
+
+static u32 bictcp_undo_cwnd(struct tcp_sock *tp)
+{
+	struct bictcp *ca = tcp_ca(tp);
+
+	return max(tp->snd_cwnd, ca->last_max_cwnd);
+}
+
+static u32 bictcp_min_cwnd(struct tcp_sock *tp)
+{
+	return tp->snd_ssthresh;
+}
+
+static void bictcp_state(struct tcp_sock *tp, u8 new_state)
+{
+	if (new_state == TCP_CA_Loss)
+		bictcp_reset(tcp_ca(tp));
+}
+
+/* Track delayed acknowledgement ratio using sliding window
+ * ratio = (15*ratio + sample) / 16
+ */
+static void bictcp_acked(struct tcp_sock *tp, u32 cnt)
+{
+	if (cnt > 0 && 	tp->ca_state == TCP_CA_Open) {
+		struct bictcp *ca = tcp_ca(tp);
+		cnt -= ca->delayed_ack >> ACK_RATIO_SHIFT;
+		ca->delayed_ack += cnt;
+	}
+}
+
+
+static struct tcp_congestion_ops bictcp = {
+	.init		= bictcp_init,
+	.ssthresh	= bictcp_recalc_ssthresh,
+	.cong_avoid	= bictcp_cong_avoid,
+	.set_state	= bictcp_state,
+	.undo_cwnd	= bictcp_undo_cwnd,
+	.min_cwnd	= bictcp_min_cwnd,
+	.pkts_acked     = bictcp_acked,
+	.owner		= THIS_MODULE,
+	.name		= "bic",
+};
+
+static int __init bictcp_register(void)
+{
+	BUG_ON(sizeof(struct bictcp) > TCP_CA_PRIV_SIZE);
+	return tcp_register_congestion_control(&bictcp);
+}
+
+static void __exit bictcp_unregister(void)
+{
+	tcp_unregister_congestion_control(&bictcp);
+}
+
+module_init(bictcp_register);
+module_exit(bictcp_unregister);
+
+MODULE_AUTHOR("Stephen Hemminger");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("BIC TCP");
diff --git a/net/ipv4/tcp_cong.c b/net/ipv4/tcp_cong.c
new file mode 100644
--- /dev/null
+++ b/net/ipv4/tcp_cong.c
@@ -0,0 +1,237 @@
+/*
+ * Plugable TCP congestion control support and newReno
+ * congestion control.
+ * Based on ideas from I/O scheduler suport and Web100.
+ *
+ * Copyright (C) 2005 Stephen Hemminger <shemminger@osdl.org>
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <linux/types.h>
+#include <linux/list.h>
+#include <net/tcp.h>
+
+static DEFINE_SPINLOCK(tcp_cong_list_lock);
+static LIST_HEAD(tcp_cong_list);
+
+/* Simple linear search, don't expect many entries! */
+static struct tcp_congestion_ops *tcp_ca_find(const char *name)
+{
+	struct tcp_congestion_ops *e;
+
+	list_for_each_entry_rcu(e, &tcp_cong_list, list) {
+		if (strcmp(e->name, name) == 0)
+			return e;
+	}
+
+	return NULL;
+}
+
+/*
+ * Attach new congestion control algorthim to the list
+ * of available options.
+ */
+int tcp_register_congestion_control(struct tcp_congestion_ops *ca)
+{
+	int ret = 0;
+
+	/* all algorithms must implement ssthresh and cong_avoid ops */
+	if (!ca->ssthresh || !ca->cong_avoid || !ca->min_cwnd) {
+		printk(KERN_ERR "TCP %s does not implement required ops\n",
+		       ca->name);
+		return -EINVAL;
+	}
+
+	spin_lock(&tcp_cong_list_lock);
+	if (tcp_ca_find(ca->name)) {
+		printk(KERN_NOTICE "TCP %s already registered\n", ca->name);
+		ret = -EEXIST;
+	} else {
+		list_add_rcu(&ca->list, &tcp_cong_list);
+		printk(KERN_INFO "TCP %s registered\n", ca->name);
+	}
+	spin_unlock(&tcp_cong_list_lock);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(tcp_register_congestion_control);
+
+/*
+ * Remove congestion control algorithm, called from
+ * the module's remove function.  Module ref counts are used
+ * to ensure that this can't be done till all sockets using
+ * that method are closed.
+ */
+void tcp_unregister_congestion_control(struct tcp_congestion_ops *ca)
+{
+	spin_lock(&tcp_cong_list_lock);
+	list_del_rcu(&ca->list);
+	spin_unlock(&tcp_cong_list_lock);
+}
+EXPORT_SYMBOL_GPL(tcp_unregister_congestion_control);
+
+/* Assign choice of congestion control. */
+void tcp_init_congestion_control(struct tcp_sock *tp)
+{
+	struct tcp_congestion_ops *ca;
+
+	if (tp->ca_ops != &tcp_init_congestion_ops)
+		return;
+
+	rcu_read_lock();
+	list_for_each_entry_rcu(ca, &tcp_cong_list, list) {
+		if (try_module_get(ca->owner)) {
+			tp->ca_ops = ca;
+			break;
+		}
+
+	}
+	rcu_read_unlock();
+
+	if (tp->ca_ops->init)
+		tp->ca_ops->init(tp);
+}
+
+/* Manage refcounts on socket close. */
+void tcp_cleanup_congestion_control(struct tcp_sock *tp)
+{
+	if (tp->ca_ops->release)
+		tp->ca_ops->release(tp);
+	module_put(tp->ca_ops->owner);
+}
+
+/* Used by sysctl to change default congestion control */
+int tcp_set_default_congestion_control(const char *name)
+{
+	struct tcp_congestion_ops *ca;
+	int ret = -ENOENT;
+
+	spin_lock(&tcp_cong_list_lock);
+	ca = tcp_ca_find(name);
+#ifdef CONFIG_KMOD
+	if (!ca) {
+		spin_unlock(&tcp_cong_list_lock);
+
+		request_module("tcp_%s", name);
+		spin_lock(&tcp_cong_list_lock);
+		ca = tcp_ca_find(name);
+	}
+#endif
+
+	if (ca) {
+		list_move(&ca->list, &tcp_cong_list);
+		ret = 0;
+	}
+	spin_unlock(&tcp_cong_list_lock);
+
+	return ret;
+}
+
+/* Get current default congestion control */
+void tcp_get_default_congestion_control(char *name)
+{
+	struct tcp_congestion_ops *ca;
+	/* We will always have reno... */
+	BUG_ON(list_empty(&tcp_cong_list));
+
+	rcu_read_lock();
+	ca = list_entry(tcp_cong_list.next, struct tcp_congestion_ops, list);
+	strncpy(name, ca->name, TCP_CA_NAME_MAX);
+	rcu_read_unlock();
+}
+
+/* Change congestion control for socket */
+int tcp_set_congestion_control(struct tcp_sock *tp, const char *name)
+{
+	struct tcp_congestion_ops *ca;
+	int err = 0;
+
+	rcu_read_lock();
+	ca = tcp_ca_find(name);
+	if (ca == tp->ca_ops)
+		goto out;
+
+	if (!ca)
+		err = -ENOENT;
+
+	else if (!try_module_get(ca->owner))
+		err = -EBUSY;
+
+	else {
+		tcp_cleanup_congestion_control(tp);
+		tp->ca_ops = ca;
+		if (tp->ca_ops->init)
+			tp->ca_ops->init(tp);
+	}
+ out:
+	rcu_read_unlock();
+	return err;
+}
+
+/*
+ * TCP Reno congestion control
+ * This is special case used for fallback as well.
+ */
+/* This is Jacobson's slow start and congestion avoidance.
+ * SIGCOMM '88, p. 328.
+ */
+void tcp_reno_cong_avoid(struct tcp_sock *tp, u32 ack, u32 rtt, u32 in_flight,
+			 int flag)
+{
+	if (in_flight < tp->snd_cwnd)
+		return;
+
+        if (tp->snd_cwnd <= tp->snd_ssthresh) {
+                /* In "safe" area, increase. */
+		if (tp->snd_cwnd < tp->snd_cwnd_clamp)
+			tp->snd_cwnd++;
+	} else {
+                /* In dangerous area, increase slowly.
+		 * In theory this is tp->snd_cwnd += 1 / tp->snd_cwnd
+		 */
+		if (tp->snd_cwnd_cnt >= tp->snd_cwnd) {
+			if (tp->snd_cwnd < tp->snd_cwnd_clamp)
+				tp->snd_cwnd++;
+			tp->snd_cwnd_cnt = 0;
+		} else
+			tp->snd_cwnd_cnt++;
+	}
+}
+EXPORT_SYMBOL_GPL(tcp_reno_cong_avoid);
+
+/* Slow start threshold is half the congestion window (min 2) */
+u32 tcp_reno_ssthresh(struct tcp_sock *tp)
+{
+	return max(tp->snd_cwnd >> 1U, 2U);
+}
+EXPORT_SYMBOL_GPL(tcp_reno_ssthresh);
+
+/* Lower bound on congestion window. */
+u32 tcp_reno_min_cwnd(struct tcp_sock *tp)
+{
+	return tp->snd_ssthresh/2;
+}
+EXPORT_SYMBOL_GPL(tcp_reno_min_cwnd);
+
+struct tcp_congestion_ops tcp_reno = {
+	.name		= "reno",
+	.owner		= THIS_MODULE,
+	.ssthresh	= tcp_reno_ssthresh,
+	.cong_avoid	= tcp_reno_cong_avoid,
+	.min_cwnd	= tcp_reno_min_cwnd,
+};
+
+/* Initial congestion control used (until SYN)
+ * really reno under another name so we can tell difference
+ * during tcp_set_default_congestion_control
+ */
+struct tcp_congestion_ops tcp_init_congestion_ops  = {
+	.name		= "",
+	.owner		= THIS_MODULE,
+	.ssthresh	= tcp_reno_ssthresh,
+	.cong_avoid	= tcp_reno_cong_avoid,
+	.min_cwnd	= tcp_reno_min_cwnd,
+};
+EXPORT_SYMBOL_GPL(tcp_init_congestion_ops);
diff --git a/net/ipv4/tcp_diag.c b/net/ipv4/tcp_diag.c
--- a/net/ipv4/tcp_diag.c
+++ b/net/ipv4/tcp_diag.c
@@ -42,15 +42,8 @@ struct tcpdiag_entry
 
 static struct sock *tcpnl;
 
-
 #define TCPDIAG_PUT(skb, attrtype, attrlen) \
-({ int rtalen = RTA_LENGTH(attrlen);        \
-   struct rtattr *rta;                      \
-   if (skb_tailroom(skb) < RTA_ALIGN(rtalen)) goto nlmsg_failure; \
-   rta = (void*)__skb_put(skb, RTA_ALIGN(rtalen)); \
-   rta->rta_type = attrtype;                \
-   rta->rta_len = rtalen;                   \
-   RTA_DATA(rta); })
+	RTA_DATA(__RTA_PUT(skb, attrtype, attrlen))
 
 static int tcpdiag_fill(struct sk_buff *skb, struct sock *sk,
 			int ext, u32 pid, u32 seq, u16 nlmsg_flags)
@@ -61,7 +54,6 @@ static int tcpdiag_fill(struct sk_buff *
 	struct nlmsghdr  *nlh;
 	struct tcp_info  *info = NULL;
 	struct tcpdiag_meminfo  *minfo = NULL;
-	struct tcpvegas_info *vinfo = NULL;
 	unsigned char	 *b = skb->tail;
 
 	nlh = NLMSG_PUT(skb, pid, seq, TCPDIAG_GETSOCK, sizeof(*r));
@@ -73,9 +65,11 @@ static int tcpdiag_fill(struct sk_buff *
 		if (ext & (1<<(TCPDIAG_INFO-1)))
 			info = TCPDIAG_PUT(skb, TCPDIAG_INFO, sizeof(*info));
 		
-		if ((tcp_is_westwood(tp) || tcp_is_vegas(tp))
-		    && (ext & (1<<(TCPDIAG_VEGASINFO-1))))
-			vinfo = TCPDIAG_PUT(skb, TCPDIAG_VEGASINFO, sizeof(*vinfo));
+		if (ext & (1<<(TCPDIAG_CONG-1))) {
+			size_t len = strlen(tp->ca_ops->name);
+			strcpy(TCPDIAG_PUT(skb, TCPDIAG_CONG, len+1),
+			       tp->ca_ops->name);
+		}
 	}
 	r->tcpdiag_family = sk->sk_family;
 	r->tcpdiag_state = sk->sk_state;
@@ -166,23 +160,13 @@ static int tcpdiag_fill(struct sk_buff *
 	if (info) 
 		tcp_get_info(sk, info);
 
-	if (vinfo) {
-		if (tcp_is_vegas(tp)) {
-			vinfo->tcpv_enabled = tp->vegas.doing_vegas_now;
-			vinfo->tcpv_rttcnt = tp->vegas.cntRTT;
-			vinfo->tcpv_rtt = jiffies_to_usecs(tp->vegas.baseRTT);
-			vinfo->tcpv_minrtt = jiffies_to_usecs(tp->vegas.minRTT);
-		} else {
-			vinfo->tcpv_enabled = 0;
-			vinfo->tcpv_rttcnt = 0;
-			vinfo->tcpv_rtt = jiffies_to_usecs(tp->westwood.rtt);
-			vinfo->tcpv_minrtt = jiffies_to_usecs(tp->westwood.rtt_min);
-		}
-	}
+	if (sk->sk_state < TCP_TIME_WAIT && tp->ca_ops->get_info)
+		tp->ca_ops->get_info(tp, ext, skb);
 
 	nlh->nlmsg_len = skb->tail - b;
 	return skb->len;
 
+rtattr_failure:
 nlmsg_failure:
 	skb_trim(skb, b - skb->data);
 	return -1;
@@ -455,9 +439,10 @@ static int tcpdiag_dump_sock(struct sk_b
 }
 
 static int tcpdiag_fill_req(struct sk_buff *skb, struct sock *sk,
-			    struct open_request *req,
+			    struct request_sock *req,
 			    u32 pid, u32 seq)
 {
+	const struct inet_request_sock *ireq = inet_rsk(req);
 	struct inet_sock *inet = inet_sk(sk);
 	unsigned char *b = skb->tail;
 	struct tcpdiagmsg *r;
@@ -482,9 +467,9 @@ static int tcpdiag_fill_req(struct sk_bu
 		tmo = 0;
 
 	r->id.tcpdiag_sport = inet->sport;
-	r->id.tcpdiag_dport = req->rmt_port;
-	r->id.tcpdiag_src[0] = req->af.v4_req.loc_addr;
-	r->id.tcpdiag_dst[0] = req->af.v4_req.rmt_addr;
+	r->id.tcpdiag_dport = ireq->rmt_port;
+	r->id.tcpdiag_src[0] = ireq->loc_addr;
+	r->id.tcpdiag_dst[0] = ireq->rmt_addr;
 	r->tcpdiag_expires = jiffies_to_msecs(tmo),
 	r->tcpdiag_rqueue = 0;
 	r->tcpdiag_wqueue = 0;
@@ -493,9 +478,9 @@ static int tcpdiag_fill_req(struct sk_bu
 #ifdef CONFIG_IP_TCPDIAG_IPV6
 	if (r->tcpdiag_family == AF_INET6) {
 		ipv6_addr_copy((struct in6_addr *)r->id.tcpdiag_src,
-			       &req->af.v6_req.loc_addr);
+			       &tcp6_rsk(req)->loc_addr);
 		ipv6_addr_copy((struct in6_addr *)r->id.tcpdiag_dst,
-			       &req->af.v6_req.rmt_addr);
+			       &tcp6_rsk(req)->rmt_addr);
 	}
 #endif
 	nlh->nlmsg_len = skb->tail - b;
@@ -513,7 +498,7 @@ static int tcpdiag_dump_reqs(struct sk_b
 	struct tcpdiag_entry entry;
 	struct tcpdiagreq *r = NLMSG_DATA(cb->nlh);
 	struct tcp_sock *tp = tcp_sk(sk);
-	struct tcp_listen_opt *lopt;
+	struct listen_sock *lopt;
 	struct rtattr *bc = NULL;
 	struct inet_sock *inet = inet_sk(sk);
 	int j, s_j;
@@ -528,9 +513,9 @@ static int tcpdiag_dump_reqs(struct sk_b
 
 	entry.family = sk->sk_family;
 
-	read_lock_bh(&tp->syn_wait_lock);
+	read_lock_bh(&tp->accept_queue.syn_wait_lock);
 
-	lopt = tp->listen_opt;
+	lopt = tp->accept_queue.listen_opt;
 	if (!lopt || !lopt->qlen)
 		goto out;
 
@@ -541,13 +526,15 @@ static int tcpdiag_dump_reqs(struct sk_b
 	}
 
 	for (j = s_j; j < TCP_SYNQ_HSIZE; j++) {
-		struct open_request *req, *head = lopt->syn_table[j];
+		struct request_sock *req, *head = lopt->syn_table[j];
 
 		reqnum = 0;
 		for (req = head; req; reqnum++, req = req->dl_next) {
+			struct inet_request_sock *ireq = inet_rsk(req);
+
 			if (reqnum < s_reqnum)
 				continue;
-			if (r->id.tcpdiag_dport != req->rmt_port &&
+			if (r->id.tcpdiag_dport != ireq->rmt_port &&
 			    r->id.tcpdiag_dport)
 				continue;
 
@@ -555,16 +542,16 @@ static int tcpdiag_dump_reqs(struct sk_b
 				entry.saddr =
 #ifdef CONFIG_IP_TCPDIAG_IPV6
 					(entry.family == AF_INET6) ?
-					req->af.v6_req.loc_addr.s6_addr32 :
+					tcp6_rsk(req)->loc_addr.s6_addr32 :
 #endif
-					&req->af.v4_req.loc_addr;
+					&ireq->loc_addr;
 				entry.daddr = 
 #ifdef CONFIG_IP_TCPDIAG_IPV6
 					(entry.family == AF_INET6) ?
-					req->af.v6_req.rmt_addr.s6_addr32 :
+					tcp6_rsk(req)->rmt_addr.s6_addr32 :
 #endif
-					&req->af.v4_req.rmt_addr;
-				entry.dport = ntohs(req->rmt_port);
+					&ireq->rmt_addr;
+				entry.dport = ntohs(ireq->rmt_port);
 
 				if (!tcpdiag_bc_run(RTA_DATA(bc),
 						    RTA_PAYLOAD(bc), &entry))
@@ -585,7 +572,7 @@ static int tcpdiag_dump_reqs(struct sk_b
 	}
 
 out:
-	read_unlock_bh(&tp->syn_wait_lock);
+	read_unlock_bh(&tp->accept_queue.syn_wait_lock);
 
 	return err;
 }
diff --git a/net/ipv4/tcp_highspeed.c b/net/ipv4/tcp_highspeed.c
new file mode 100644
--- /dev/null
+++ b/net/ipv4/tcp_highspeed.c
@@ -0,0 +1,181 @@
+/*
+ * Sally Floyd's High Speed TCP (RFC 3649) congestion control
+ *
+ * See http://www.icir.org/floyd/hstcp.html
+ *
+ * John Heffner <jheffner@psc.edu>
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <net/tcp.h>
+
+
+/* From AIMD tables from RFC 3649 appendix B,
+ * with fixed-point MD scaled <<8.
+ */
+static const struct hstcp_aimd_val {
+        unsigned int cwnd;
+        unsigned int md;
+} hstcp_aimd_vals[] = {
+ {     38,  128, /*  0.50 */ },
+ {    118,  112, /*  0.44 */ },
+ {    221,  104, /*  0.41 */ },
+ {    347,   98, /*  0.38 */ },
+ {    495,   93, /*  0.37 */ },
+ {    663,   89, /*  0.35 */ },
+ {    851,   86, /*  0.34 */ },
+ {   1058,   83, /*  0.33 */ },
+ {   1284,   81, /*  0.32 */ },
+ {   1529,   78, /*  0.31 */ },
+ {   1793,   76, /*  0.30 */ },
+ {   2076,   74, /*  0.29 */ },
+ {   2378,   72, /*  0.28 */ },
+ {   2699,   71, /*  0.28 */ },
+ {   3039,   69, /*  0.27 */ },
+ {   3399,   68, /*  0.27 */ },
+ {   3778,   66, /*  0.26 */ },
+ {   4177,   65, /*  0.26 */ },
+ {   4596,   64, /*  0.25 */ },
+ {   5036,   62, /*  0.25 */ },
+ {   5497,   61, /*  0.24 */ },
+ {   5979,   60, /*  0.24 */ },
+ {   6483,   59, /*  0.23 */ },
+ {   7009,   58, /*  0.23 */ },
+ {   7558,   57, /*  0.22 */ },
+ {   8130,   56, /*  0.22 */ },
+ {   8726,   55, /*  0.22 */ },
+ {   9346,   54, /*  0.21 */ },
+ {   9991,   53, /*  0.21 */ },
+ {  10661,   52, /*  0.21 */ },
+ {  11358,   52, /*  0.20 */ },
+ {  12082,   51, /*  0.20 */ },
+ {  12834,   50, /*  0.20 */ },
+ {  13614,   49, /*  0.19 */ },
+ {  14424,   48, /*  0.19 */ },
+ {  15265,   48, /*  0.19 */ },
+ {  16137,   47, /*  0.19 */ },
+ {  17042,   46, /*  0.18 */ },
+ {  17981,   45, /*  0.18 */ },
+ {  18955,   45, /*  0.18 */ },
+ {  19965,   44, /*  0.17 */ },
+ {  21013,   43, /*  0.17 */ },
+ {  22101,   43, /*  0.17 */ },
+ {  23230,   42, /*  0.17 */ },
+ {  24402,   41, /*  0.16 */ },
+ {  25618,   41, /*  0.16 */ },
+ {  26881,   40, /*  0.16 */ },
+ {  28193,   39, /*  0.16 */ },
+ {  29557,   39, /*  0.15 */ },
+ {  30975,   38, /*  0.15 */ },
+ {  32450,   38, /*  0.15 */ },
+ {  33986,   37, /*  0.15 */ },
+ {  35586,   36, /*  0.14 */ },
+ {  37253,   36, /*  0.14 */ },
+ {  38992,   35, /*  0.14 */ },
+ {  40808,   35, /*  0.14 */ },
+ {  42707,   34, /*  0.13 */ },
+ {  44694,   33, /*  0.13 */ },
+ {  46776,   33, /*  0.13 */ },
+ {  48961,   32, /*  0.13 */ },
+ {  51258,   32, /*  0.13 */ },
+ {  53677,   31, /*  0.12 */ },
+ {  56230,   30, /*  0.12 */ },
+ {  58932,   30, /*  0.12 */ },
+ {  61799,   29, /*  0.12 */ },
+ {  64851,   28, /*  0.11 */ },
+ {  68113,   28, /*  0.11 */ },
+ {  71617,   27, /*  0.11 */ },
+ {  75401,   26, /*  0.10 */ },
+ {  79517,   26, /*  0.10 */ },
+ {  84035,   25, /*  0.10 */ },
+ {  89053,   24, /*  0.10 */ },
+};
+
+#define HSTCP_AIMD_MAX	ARRAY_SIZE(hstcp_aimd_vals)
+
+struct hstcp {
+	u32	ai;
+};
+
+static void hstcp_init(struct tcp_sock *tp)
+{
+	struct hstcp *ca = tcp_ca(tp);
+
+	ca->ai = 0;
+
+	/* Ensure the MD arithmetic works.  This is somewhat pedantic,
+	 * since I don't think we will see a cwnd this large. :) */
+	tp->snd_cwnd_clamp = min_t(u32, tp->snd_cwnd_clamp, 0xffffffff/128);
+}
+
+static void hstcp_cong_avoid(struct tcp_sock *tp, u32 adk, u32 rtt,
+			     u32 in_flight, int good)
+{
+	struct hstcp *ca = tcp_ca(tp);
+
+	if (in_flight < tp->snd_cwnd)
+		return;
+
+	if (tp->snd_cwnd <= tp->snd_ssthresh) {
+		if (tp->snd_cwnd < tp->snd_cwnd_clamp)
+			tp->snd_cwnd++;
+	} else {
+		/* Update AIMD parameters */
+		if (tp->snd_cwnd > hstcp_aimd_vals[ca->ai].cwnd) {
+			while (tp->snd_cwnd > hstcp_aimd_vals[ca->ai].cwnd &&
+			       ca->ai < HSTCP_AIMD_MAX)
+				ca->ai++;
+		} else if (tp->snd_cwnd < hstcp_aimd_vals[ca->ai].cwnd) {
+			while (tp->snd_cwnd > hstcp_aimd_vals[ca->ai].cwnd &&
+			       ca->ai > 0)
+				ca->ai--;
+		}
+
+		/* Do additive increase */
+		if (tp->snd_cwnd < tp->snd_cwnd_clamp) {
+			tp->snd_cwnd_cnt += ca->ai;
+			if (tp->snd_cwnd_cnt >= tp->snd_cwnd) {
+				tp->snd_cwnd++;
+				tp->snd_cwnd_cnt -= tp->snd_cwnd;
+			}
+		}
+	}
+}
+
+static u32 hstcp_ssthresh(struct tcp_sock *tp)
+{
+	struct hstcp *ca = tcp_ca(tp);
+
+	/* Do multiplicative decrease */
+	return max(tp->snd_cwnd - ((tp->snd_cwnd * hstcp_aimd_vals[ca->ai].md) >> 8), 2U);
+}
+
+
+static struct tcp_congestion_ops tcp_highspeed = {
+	.init		= hstcp_init,
+	.ssthresh	= hstcp_ssthresh,
+	.cong_avoid	= hstcp_cong_avoid,
+	.min_cwnd	= tcp_reno_min_cwnd,
+
+	.owner		= THIS_MODULE,
+	.name		= "highspeed"
+};
+
+static int __init hstcp_register(void)
+{
+	BUG_ON(sizeof(struct hstcp) > TCP_CA_PRIV_SIZE);
+	return tcp_register_congestion_control(&tcp_highspeed);
+}
+
+static void __exit hstcp_unregister(void)
+{
+	tcp_unregister_congestion_control(&tcp_highspeed);
+}
+
+module_init(hstcp_register);
+module_exit(hstcp_unregister);
+
+MODULE_AUTHOR("John Heffner");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("High Speed TCP");
diff --git a/net/ipv4/tcp_htcp.c b/net/ipv4/tcp_htcp.c
new file mode 100644
--- /dev/null
+++ b/net/ipv4/tcp_htcp.c
@@ -0,0 +1,289 @@
+/*
+ * H-TCP congestion control. The algorithm is detailed in:
+ * R.N.Shorten, D.J.Leith:
+ *   "H-TCP: TCP for high-speed and long-distance networks"
+ *   Proc. PFLDnet, Argonne, 2004.
+ * http://www.hamilton.ie/net/htcp3.pdf
+ */
+
+#include <linux/config.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <net/tcp.h>
+
+#define ALPHA_BASE	(1<<7)  /* 1.0 with shift << 7 */
+#define BETA_MIN	(1<<6)  /* 0.5 with shift << 7 */
+#define BETA_MAX	102	/* 0.8 with shift << 7 */
+
+static int use_rtt_scaling = 1;
+module_param(use_rtt_scaling, int, 0644);
+MODULE_PARM_DESC(use_rtt_scaling, "turn on/off RTT scaling");
+
+static int use_bandwidth_switch = 1;
+module_param(use_bandwidth_switch, int, 0644);
+MODULE_PARM_DESC(use_bandwidth_switch, "turn on/off bandwidth switcher");
+
+struct htcp {
+	u16	alpha;		/* Fixed point arith, << 7 */
+	u8	beta;           /* Fixed point arith, << 7 */
+	u8	modeswitch;     /* Delay modeswitch until we had at least one congestion event */
+	u8	ccount;		/* Number of RTTs since last congestion event */
+	u8	undo_ccount;
+	u16	packetcount;
+	u32	minRTT;
+	u32	maxRTT;
+	u32	snd_cwnd_cnt2;
+
+	u32	undo_maxRTT;
+	u32	undo_old_maxB;
+
+	/* Bandwidth estimation */
+	u32	minB;
+	u32	maxB;
+	u32	old_maxB;
+	u32	Bi;
+	u32	lasttime;
+};
+
+static inline void htcp_reset(struct htcp *ca)
+{
+	ca->undo_ccount = ca->ccount;
+	ca->undo_maxRTT = ca->maxRTT;
+	ca->undo_old_maxB = ca->old_maxB;
+
+	ca->ccount = 0;
+	ca->snd_cwnd_cnt2 = 0;
+}
+
+static u32 htcp_cwnd_undo(struct tcp_sock *tp)
+{
+	struct htcp *ca = tcp_ca(tp);
+	ca->ccount = ca->undo_ccount;
+	ca->maxRTT = ca->undo_maxRTT;
+	ca->old_maxB = ca->undo_old_maxB;
+	return max(tp->snd_cwnd, (tp->snd_ssthresh<<7)/ca->beta);
+}
+
+static inline void measure_rtt(struct tcp_sock *tp)
+{
+	struct htcp *ca = tcp_ca(tp);
+	u32 srtt = tp->srtt>>3;
+
+	/* keep track of minimum RTT seen so far, minRTT is zero at first */
+	if (ca->minRTT > srtt || !ca->minRTT)
+		ca->minRTT = srtt;
+
+	/* max RTT */
+	if (tp->ca_state == TCP_CA_Open && tp->snd_ssthresh < 0xFFFF && ca->ccount > 3) {
+		if (ca->maxRTT < ca->minRTT)
+			ca->maxRTT = ca->minRTT;
+		if (ca->maxRTT < srtt && srtt <= ca->maxRTT+HZ/50)
+			ca->maxRTT = srtt;
+	}
+}
+
+static void measure_achieved_throughput(struct tcp_sock *tp, u32 pkts_acked)
+{
+	struct htcp *ca = tcp_ca(tp);
+	u32 now = tcp_time_stamp;
+
+	/* achieved throughput calculations */
+	if (tp->ca_state != TCP_CA_Open && tp->ca_state != TCP_CA_Disorder) {
+		ca->packetcount = 0;
+		ca->lasttime = now;
+		return;
+	}
+
+	ca->packetcount += pkts_acked;
+
+	if (ca->packetcount >= tp->snd_cwnd - (ca->alpha>>7? : 1)
+			&& now - ca->lasttime >= ca->minRTT
+			&& ca->minRTT > 0) {
+		__u32 cur_Bi = ca->packetcount*HZ/(now - ca->lasttime);
+		if (ca->ccount <= 3) {
+			/* just after backoff */
+			ca->minB = ca->maxB = ca->Bi = cur_Bi;
+		} else {
+			ca->Bi = (3*ca->Bi + cur_Bi)/4;
+			if (ca->Bi > ca->maxB)
+				ca->maxB = ca->Bi;
+			if (ca->minB > ca->maxB)
+				ca->minB = ca->maxB;
+		}
+		ca->packetcount = 0;
+		ca->lasttime = now;
+	}
+}
+
+static inline void htcp_beta_update(struct htcp *ca, u32 minRTT, u32 maxRTT)
+{
+	if (use_bandwidth_switch) {
+		u32 maxB = ca->maxB;
+		u32 old_maxB = ca->old_maxB;
+		ca->old_maxB = ca->maxB;
+
+		if (!between(5*maxB, 4*old_maxB, 6*old_maxB)) {
+			ca->beta = BETA_MIN;
+			ca->modeswitch = 0;
+			return;
+		}
+	}
+
+	if (ca->modeswitch && minRTT > max(HZ/100, 1) && maxRTT) {
+		ca->beta = (minRTT<<7)/maxRTT;
+		if (ca->beta < BETA_MIN)
+			ca->beta = BETA_MIN;
+		else if (ca->beta > BETA_MAX)
+			ca->beta = BETA_MAX;
+	} else {
+		ca->beta = BETA_MIN;
+		ca->modeswitch = 1;
+	}
+}
+
+static inline void htcp_alpha_update(struct htcp *ca)
+{
+	u32 minRTT = ca->minRTT;
+	u32 factor = 1;
+	u32 diff = ca->ccount * minRTT; /* time since last backoff */
+
+	if (diff > HZ) {
+		diff -= HZ;
+		factor = 1+ ( 10*diff + ((diff/2)*(diff/2)/HZ) )/HZ;
+	}
+
+	if (use_rtt_scaling && minRTT) {
+		u32 scale = (HZ<<3)/(10*minRTT);
+		scale = min(max(scale, 1U<<2), 10U<<3); /* clamping ratio to interval [0.5,10]<<3 */
+		factor = (factor<<3)/scale;
+		if (!factor)
+			factor = 1;
+	}
+
+	ca->alpha = 2*factor*((1<<7)-ca->beta);
+	if (!ca->alpha)
+		ca->alpha = ALPHA_BASE;
+}
+
+/* After we have the rtt data to calculate beta, we'd still prefer to wait one
+ * rtt before we adjust our beta to ensure we are working from a consistent
+ * data.
+ *
+ * This function should be called when we hit a congestion event since only at
+ * that point do we really have a real sense of maxRTT (the queues en route
+ * were getting just too full now).
+ */
+static void htcp_param_update(struct tcp_sock *tp)
+{
+	struct htcp *ca = tcp_ca(tp);
+	u32 minRTT = ca->minRTT;
+	u32 maxRTT = ca->maxRTT;
+
+	htcp_beta_update(ca, minRTT, maxRTT);
+	htcp_alpha_update(ca);
+
+	/* add slowly fading memory for maxRTT to accommodate routing changes etc */
+	if (minRTT > 0 && maxRTT > minRTT)
+		ca->maxRTT = minRTT + ((maxRTT-minRTT)*95)/100;
+}
+
+static u32 htcp_recalc_ssthresh(struct tcp_sock *tp)
+{
+	struct htcp *ca = tcp_ca(tp);
+	htcp_param_update(tp);
+	return max((tp->snd_cwnd * ca->beta) >> 7, 2U);
+}
+
+static void htcp_cong_avoid(struct tcp_sock *tp, u32 ack, u32 rtt,
+			    u32 in_flight, int data_acked)
+{
+	struct htcp *ca = tcp_ca(tp);
+
+	if (in_flight < tp->snd_cwnd)
+		return;
+
+        if (tp->snd_cwnd <= tp->snd_ssthresh) {
+                /* In "safe" area, increase. */
+		if (tp->snd_cwnd < tp->snd_cwnd_clamp)
+			tp->snd_cwnd++;
+	} else {
+		measure_rtt(tp);
+
+		/* keep track of number of round-trip times since last backoff event */
+		if (ca->snd_cwnd_cnt2++ > tp->snd_cwnd) {
+			ca->ccount++;
+			ca->snd_cwnd_cnt2 = 0;
+			htcp_alpha_update(ca);
+		}
+
+                /* In dangerous area, increase slowly.
+		 * In theory this is tp->snd_cwnd += alpha / tp->snd_cwnd
+		 */
+		if ((tp->snd_cwnd_cnt++ * ca->alpha)>>7 >= tp->snd_cwnd) {
+			if (tp->snd_cwnd < tp->snd_cwnd_clamp)
+				tp->snd_cwnd++;
+			tp->snd_cwnd_cnt = 0;
+			ca->ccount++;
+		}
+	}
+}
+
+/* Lower bound on congestion window. */
+static u32 htcp_min_cwnd(struct tcp_sock *tp)
+{
+	return tp->snd_ssthresh;
+}
+
+
+static void htcp_init(struct tcp_sock *tp)
+{
+	struct htcp *ca = tcp_ca(tp);
+
+	memset(ca, 0, sizeof(struct htcp));
+	ca->alpha = ALPHA_BASE;
+	ca->beta = BETA_MIN;
+}
+
+static void htcp_state(struct tcp_sock *tp, u8 new_state)
+{
+	switch (new_state) {
+	case TCP_CA_CWR:
+	case TCP_CA_Recovery:
+	case TCP_CA_Loss:
+		htcp_reset(tcp_ca(tp));
+		break;
+	}
+}
+
+static struct tcp_congestion_ops htcp = {
+	.init		= htcp_init,
+	.ssthresh	= htcp_recalc_ssthresh,
+	.min_cwnd	= htcp_min_cwnd,
+	.cong_avoid	= htcp_cong_avoid,
+	.set_state	= htcp_state,
+	.undo_cwnd	= htcp_cwnd_undo,
+	.pkts_acked	= measure_achieved_throughput,
+	.owner		= THIS_MODULE,
+	.name		= "htcp",
+};
+
+static int __init htcp_register(void)
+{
+	BUG_ON(sizeof(struct htcp) > TCP_CA_PRIV_SIZE);
+	BUILD_BUG_ON(BETA_MIN >= BETA_MAX);
+	if (!use_bandwidth_switch)
+		htcp.pkts_acked = NULL;
+	return tcp_register_congestion_control(&htcp);
+}
+
+static void __exit htcp_unregister(void)
+{
+	tcp_unregister_congestion_control(&htcp);
+}
+
+module_init(htcp_register);
+module_exit(htcp_unregister);
+
+MODULE_AUTHOR("Baruch Even");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("H-TCP");
diff --git a/net/ipv4/tcp_hybla.c b/net/ipv4/tcp_hybla.c
new file mode 100644
--- /dev/null
+++ b/net/ipv4/tcp_hybla.c
@@ -0,0 +1,187 @@
+/*
+ * TCP HYBLA
+ *
+ * TCP-HYBLA Congestion control algorithm, based on:
+ *   C.Caini, R.Firrincieli, "TCP-Hybla: A TCP Enhancement
+ *   for Heterogeneous Networks",
+ *   International Journal on satellite Communications,
+ *				       September 2004
+ *    Daniele Lacamera
+ *    root at danielinux.net
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <net/tcp.h>
+
+/* Tcp Hybla structure. */
+struct hybla {
+	u8    hybla_en;
+	u32   snd_cwnd_cents; /* Keeps increment values when it is <1, <<7 */
+	u32   rho;	      /* Rho parameter, integer part  */
+	u32   rho2;	      /* Rho * Rho, integer part */
+	u32   rho_3ls;	      /* Rho parameter, <<3 */
+	u32   rho2_7ls;	      /* Rho^2, <<7	*/
+	u32   minrtt;	      /* Minimum smoothed round trip time value seen */
+};
+
+/* Hybla reference round trip time (default= 1/40 sec = 25 ms),
+   expressed in jiffies */
+static int rtt0 = 25;
+module_param(rtt0, int, 0644);
+MODULE_PARM_DESC(rtt0, "reference rout trip time (ms)");
+
+
+/* This is called to refresh values for hybla parameters */
+static inline void hybla_recalc_param (struct tcp_sock *tp)
+{
+	struct hybla *ca = tcp_ca(tp);
+
+	ca->rho_3ls = max_t(u32, tp->srtt / msecs_to_jiffies(rtt0), 8);
+	ca->rho = ca->rho_3ls >> 3;
+	ca->rho2_7ls = (ca->rho_3ls * ca->rho_3ls) << 1;
+	ca->rho2 = ca->rho2_7ls >>7;
+}
+
+static void hybla_init(struct tcp_sock *tp)
+{
+	struct hybla *ca = tcp_ca(tp);
+
+	ca->rho = 0;
+	ca->rho2 = 0;
+	ca->rho_3ls = 0;
+	ca->rho2_7ls = 0;
+	ca->snd_cwnd_cents = 0;
+	ca->hybla_en = 1;
+	tp->snd_cwnd = 2;
+	tp->snd_cwnd_clamp = 65535;
+
+	/* 1st Rho measurement based on initial srtt */
+	hybla_recalc_param(tp);
+
+	/* set minimum rtt as this is the 1st ever seen */
+	ca->minrtt = tp->srtt;
+	tp->snd_cwnd = ca->rho;
+}
+
+static void hybla_state(struct tcp_sock *tp, u8 ca_state)
+{
+	struct hybla *ca = tcp_ca(tp);
+
+	ca->hybla_en = (ca_state == TCP_CA_Open);
+}
+
+static inline u32 hybla_fraction(u32 odds)
+{
+	static const u32 fractions[] = {
+		128, 139, 152, 165, 181, 197, 215, 234,
+	};
+
+	return (odds < ARRAY_SIZE(fractions)) ? fractions[odds] : 128;
+}
+
+/* TCP Hybla main routine.
+ * This is the algorithm behavior:
+ *     o Recalc Hybla parameters if min_rtt has changed
+ *     o Give cwnd a new value based on the model proposed
+ *     o remember increments <1
+ */
+static void hybla_cong_avoid(struct tcp_sock *tp, u32 ack, u32 rtt,
+			    u32 in_flight, int flag)
+{
+	struct hybla *ca = tcp_ca(tp);
+	u32 increment, odd, rho_fractions;
+	int is_slowstart = 0;
+
+	/*  Recalculate rho only if this srtt is the lowest */
+	if (tp->srtt < ca->minrtt){
+		hybla_recalc_param(tp);
+		ca->minrtt = tp->srtt;
+	}
+
+	if (!ca->hybla_en)
+		return tcp_reno_cong_avoid(tp, ack, rtt, in_flight, flag);
+
+	if (in_flight < tp->snd_cwnd)
+		return;
+
+	if (ca->rho == 0)
+		hybla_recalc_param(tp);
+
+	rho_fractions = ca->rho_3ls - (ca->rho << 3);
+
+	if (tp->snd_cwnd < tp->snd_ssthresh) {
+		/*
+		 * slow start
+		 *      INC = 2^RHO - 1
+		 * This is done by splitting the rho parameter
+		 * into 2 parts: an integer part and a fraction part.
+		 * Inrement<<7 is estimated by doing:
+		 *	       [2^(int+fract)]<<7
+		 * that is equal to:
+		 *	       (2^int)	*  [(2^fract) <<7]
+		 * 2^int is straightly computed as 1<<int,
+		 * while we will use hybla_slowstart_fraction_increment() to
+		 * calculate 2^fract in a <<7 value.
+		 */
+		is_slowstart = 1;
+		increment = ((1 << ca->rho) * hybla_fraction(rho_fractions))
+			- 128;
+	} else {
+		/*
+		 * congestion avoidance
+		 * INC = RHO^2 / W
+		 * as long as increment is estimated as (rho<<7)/window
+		 * it already is <<7 and we can easily count its fractions.
+		 */
+		increment = ca->rho2_7ls / tp->snd_cwnd;
+		if (increment < 128)
+			tp->snd_cwnd_cnt++;
+	}
+
+	odd = increment % 128;
+	tp->snd_cwnd += increment >> 7;
+	ca->snd_cwnd_cents += odd;
+
+	/* check when fractions goes >=128 and increase cwnd by 1. */
+	while(ca->snd_cwnd_cents >= 128) {
+		tp->snd_cwnd++;
+		ca->snd_cwnd_cents -= 128;
+		tp->snd_cwnd_cnt = 0;
+	}
+
+	/* clamp down slowstart cwnd to ssthresh value. */
+	if (is_slowstart)
+		tp->snd_cwnd = min(tp->snd_cwnd, tp->snd_ssthresh);
+
+	tp->snd_cwnd = min_t(u32, tp->snd_cwnd, tp->snd_cwnd_clamp);
+}
+
+static struct tcp_congestion_ops tcp_hybla = {
+	.init		= hybla_init,
+	.ssthresh	= tcp_reno_ssthresh,
+	.min_cwnd	= tcp_reno_min_cwnd,
+	.cong_avoid	= hybla_cong_avoid,
+	.set_state	= hybla_state,
+
+	.owner		= THIS_MODULE,
+	.name		= "hybla"
+};
+
+static int __init hybla_register(void)
+{
+	BUG_ON(sizeof(struct hybla) > TCP_CA_PRIV_SIZE);
+	return tcp_register_congestion_control(&tcp_hybla);
+}
+
+static void __exit hybla_unregister(void)
+{
+	tcp_unregister_congestion_control(&tcp_hybla);
+}
+
+module_init(hybla_register);
+module_exit(hybla_unregister);
+
+MODULE_AUTHOR("Daniele Lacamera");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("TCP Hybla");
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -61,7 +61,6 @@
  *		Panu Kuhlberg:		Experimental audit of TCP (re)transmission
  *					engine. Lots of bugs are found.
  *		Pasi Sarolahti:		F-RTO for dealing with spurious RTOs
- *		Angelo Dell'Aera:	TCP Westwood+ support
  */
 
 #include <linux/config.h>
@@ -88,23 +87,9 @@ int sysctl_tcp_rfc1337;
 int sysctl_tcp_max_orphans = NR_FILE;
 int sysctl_tcp_frto;
 int sysctl_tcp_nometrics_save;
-int sysctl_tcp_westwood;
-int sysctl_tcp_vegas_cong_avoid;
 
 int sysctl_tcp_moderate_rcvbuf = 1;
 
-/* Default values of the Vegas variables, in fixed-point representation
- * with V_PARAM_SHIFT bits to the right of the binary point.
- */
-#define V_PARAM_SHIFT 1
-int sysctl_tcp_vegas_alpha = 1<<V_PARAM_SHIFT;
-int sysctl_tcp_vegas_beta  = 3<<V_PARAM_SHIFT;
-int sysctl_tcp_vegas_gamma = 1<<V_PARAM_SHIFT;
-int sysctl_tcp_bic = 1;
-int sysctl_tcp_bic_fast_convergence = 1;
-int sysctl_tcp_bic_low_window = 14;
-int sysctl_tcp_bic_beta = 819;		/* = 819/1024 (BICTCP_BETA_SCALE) */
-
 #define FLAG_DATA		0x01 /* Incoming frame contained data.		*/
 #define FLAG_WIN_UPDATE		0x02 /* Incoming ACK was a window update.	*/
 #define FLAG_DATA_ACKED		0x04 /* This ACK acknowledged new data.		*/
@@ -333,15 +318,6 @@ static void tcp_init_buffer_space(struct
 	tp->snd_cwnd_stamp = tcp_time_stamp;
 }
 
-static void init_bictcp(struct tcp_sock *tp)
-{
-	tp->bictcp.cnt = 0;
-
-	tp->bictcp.last_max_cwnd = 0;
-	tp->bictcp.last_cwnd = 0;
-	tp->bictcp.last_stamp = 0;
-}
-
 /* 5. Recalculate window clamp after socket hit its memory bounds. */
 static void tcp_clamp_window(struct sock *sk, struct tcp_sock *tp)
 {
@@ -558,45 +534,6 @@ static void tcp_event_data_recv(struct s
 		tcp_grow_window(sk, tp, skb);
 }
 
-/* When starting a new connection, pin down the current choice of 
- * congestion algorithm.
- */
-void tcp_ca_init(struct tcp_sock *tp)
-{
-	if (sysctl_tcp_westwood) 
-		tp->adv_cong = TCP_WESTWOOD;
-	else if (sysctl_tcp_bic)
-		tp->adv_cong = TCP_BIC;
-	else if (sysctl_tcp_vegas_cong_avoid) {
-		tp->adv_cong = TCP_VEGAS;
-		tp->vegas.baseRTT = 0x7fffffff;
-		tcp_vegas_enable(tp);
-	} 
-}
-
-/* Do RTT sampling needed for Vegas.
- * Basically we:
- *   o min-filter RTT samples from within an RTT to get the current
- *     propagation delay + queuing delay (we are min-filtering to try to
- *     avoid the effects of delayed ACKs)
- *   o min-filter RTT samples from a much longer window (forever for now)
- *     to find the propagation delay (baseRTT)
- */
-static inline void vegas_rtt_calc(struct tcp_sock *tp, __u32 rtt)
-{
-	__u32 vrtt = rtt + 1; /* Never allow zero rtt or baseRTT */
-
-	/* Filter to find propagation delay: */
-	if (vrtt < tp->vegas.baseRTT) 
-		tp->vegas.baseRTT = vrtt;
-
-	/* Find the min RTT during the last RTT to find
-	 * the current prop. delay + queuing delay:
-	 */
-	tp->vegas.minRTT = min(tp->vegas.minRTT, vrtt);
-	tp->vegas.cntRTT++;
-}
-
 /* Called to compute a smoothed rtt estimate. The data fed to this
  * routine either comes from timestamps, or from segments that were
  * known _not_ to have been retransmitted [see Karn/Partridge
@@ -606,13 +543,10 @@ static inline void vegas_rtt_calc(struct
  * To save cycles in the RFC 1323 implementation it was better to break
  * it up into three procedures. -- erics
  */
-static void tcp_rtt_estimator(struct tcp_sock *tp, __u32 mrtt)
+static void tcp_rtt_estimator(struct tcp_sock *tp, __u32 mrtt, u32 *usrtt)
 {
 	long m = mrtt; /* RTT */
 
-	if (tcp_vegas_enabled(tp))
-		vegas_rtt_calc(tp, mrtt);
-
 	/*	The following amusing code comes from Jacobson's
 	 *	article in SIGCOMM '88.  Note that rtt and mdev
 	 *	are scaled versions of rtt and mean deviation.
@@ -670,7 +604,8 @@ static void tcp_rtt_estimator(struct tcp
 		tp->rtt_seq = tp->snd_nxt;
 	}
 
-	tcp_westwood_update_rtt(tp, tp->srtt >> 3);
+	if (tp->ca_ops->rtt_sample)
+		tp->ca_ops->rtt_sample(tp, *usrtt);
 }
 
 /* Calculate rto without backoff.  This is the second half of Van Jacobson's
@@ -805,10 +740,10 @@ __u32 tcp_init_cwnd(struct tcp_sock *tp,
 	__u32 cwnd = (dst ? dst_metric(dst, RTAX_INITCWND) : 0);
 
 	if (!cwnd) {
-		if (tp->mss_cache_std > 1460)
+		if (tp->mss_cache > 1460)
 			cwnd = 2;
 		else
-			cwnd = (tp->mss_cache_std > 1095) ? 3 : 4;
+			cwnd = (tp->mss_cache > 1095) ? 3 : 4;
 	}
 	return min_t(__u32, cwnd, tp->snd_cwnd_clamp);
 }
@@ -979,7 +914,7 @@ tcp_sacktag_write_queue(struct sock *sk,
 	if (sk->sk_route_caps & NETIF_F_TSO) {
 		sk->sk_route_caps &= ~NETIF_F_TSO;
 		sock_set_flag(sk, SOCK_NO_LARGESEND);
-		tp->mss_cache = tp->mss_cache_std;
+		tp->mss_cache = tp->mss_cache;
 	}
 
 	if (!tp->sacked_out)
@@ -1142,7 +1077,7 @@ tcp_sacktag_write_queue(struct sock *sk,
 			    (IsFack(tp) ||
 			     !before(lost_retrans,
 				     TCP_SKB_CB(skb)->ack_seq + tp->reordering *
-				     tp->mss_cache_std))) {
+				     tp->mss_cache))) {
 				TCP_SKB_CB(skb)->sacked &= ~TCPCB_SACKED_RETRANS;
 				tp->retrans_out -= tcp_skb_pcount(skb);
 
@@ -1185,8 +1120,8 @@ void tcp_enter_frto(struct sock *sk)
             tp->snd_una == tp->high_seq ||
             (tp->ca_state == TCP_CA_Loss && !tp->retransmits)) {
 		tp->prior_ssthresh = tcp_current_ssthresh(tp);
-		if (!tcp_westwood_ssthresh(tp))
-			tp->snd_ssthresh = tcp_recalc_ssthresh(tp);
+		tp->snd_ssthresh = tp->ca_ops->ssthresh(tp);
+		tcp_ca_event(tp, CA_EVENT_FRTO);
 	}
 
 	/* Have to clear retransmission markers here to keep the bookkeeping
@@ -1252,8 +1187,6 @@ static void tcp_enter_frto_loss(struct s
 	tcp_set_ca_state(tp, TCP_CA_Loss);
 	tp->high_seq = tp->frto_highmark;
 	TCP_ECN_queue_cwr(tp);
-
-	init_bictcp(tp);
 }
 
 void tcp_clear_retrans(struct tcp_sock *tp)
@@ -1283,7 +1216,8 @@ void tcp_enter_loss(struct sock *sk, int
 	if (tp->ca_state <= TCP_CA_Disorder || tp->snd_una == tp->high_seq ||
 	    (tp->ca_state == TCP_CA_Loss && !tp->retransmits)) {
 		tp->prior_ssthresh = tcp_current_ssthresh(tp);
-		tp->snd_ssthresh = tcp_recalc_ssthresh(tp);
+		tp->snd_ssthresh = tp->ca_ops->ssthresh(tp);
+		tcp_ca_event(tp, CA_EVENT_LOSS);
 	}
 	tp->snd_cwnd	   = 1;
 	tp->snd_cwnd_cnt   = 0;
@@ -1596,28 +1530,14 @@ static inline void tcp_moderate_cwnd(str
 }
 
 /* Decrease cwnd each second ack. */
-
 static void tcp_cwnd_down(struct tcp_sock *tp)
 {
 	int decr = tp->snd_cwnd_cnt + 1;
-	__u32 limit;
-
-	/*
-	 * TCP Westwood
-	 * Here limit is evaluated as BWestimation*RTTmin (for obtaining it
-	 * in packets we use mss_cache). If sysctl_tcp_westwood is off
-	 * tcp_westwood_bw_rttmin() returns 0. In such case snd_ssthresh is
-	 * still used as usual. It prevents other strange cases in which
-	 * BWE*RTTmin could assume value 0. It should not happen but...
-	 */
-
-	if (!(limit = tcp_westwood_bw_rttmin(tp)))
-		limit = tp->snd_ssthresh/2;
 
 	tp->snd_cwnd_cnt = decr&1;
 	decr >>= 1;
 
-	if (decr && tp->snd_cwnd > limit)
+	if (decr && tp->snd_cwnd > tp->ca_ops->min_cwnd(tp))
 		tp->snd_cwnd -= decr;
 
 	tp->snd_cwnd = min(tp->snd_cwnd, tcp_packets_in_flight(tp)+1);
@@ -1654,8 +1574,8 @@ static void DBGUNDO(struct sock *sk, str
 static void tcp_undo_cwr(struct tcp_sock *tp, int undo)
 {
 	if (tp->prior_ssthresh) {
-		if (tcp_is_bic(tp))
-			tp->snd_cwnd = max(tp->snd_cwnd, tp->bictcp.last_max_cwnd);
+		if (tp->ca_ops->undo_cwnd)
+			tp->snd_cwnd = tp->ca_ops->undo_cwnd(tp);
 		else
 			tp->snd_cwnd = max(tp->snd_cwnd, tp->snd_ssthresh<<1);
 
@@ -1767,11 +1687,9 @@ static int tcp_try_undo_loss(struct sock
 
 static inline void tcp_complete_cwr(struct tcp_sock *tp)
 {
-	if (tcp_westwood_cwnd(tp)) 
-		tp->snd_ssthresh = tp->snd_cwnd;
-	else
-		tp->snd_cwnd = min(tp->snd_cwnd, tp->snd_ssthresh);
+	tp->snd_cwnd = min(tp->snd_cwnd, tp->snd_ssthresh);
 	tp->snd_cwnd_stamp = tcp_time_stamp;
+	tcp_ca_event(tp, CA_EVENT_COMPLETE_CWR);
 }
 
 static void tcp_try_to_open(struct sock *sk, struct tcp_sock *tp, int flag)
@@ -1946,7 +1864,7 @@ tcp_fastretrans_alert(struct sock *sk, u
 		if (tp->ca_state < TCP_CA_CWR) {
 			if (!(flag&FLAG_ECE))
 				tp->prior_ssthresh = tcp_current_ssthresh(tp);
-			tp->snd_ssthresh = tcp_recalc_ssthresh(tp);
+			tp->snd_ssthresh = tp->ca_ops->ssthresh(tp);
 			TCP_ECN_queue_cwr(tp);
 		}
 
@@ -1963,7 +1881,7 @@ tcp_fastretrans_alert(struct sock *sk, u
 /* Read draft-ietf-tcplw-high-performance before mucking
  * with this code. (Superceeds RFC1323)
  */
-static void tcp_ack_saw_tstamp(struct tcp_sock *tp, int flag)
+static void tcp_ack_saw_tstamp(struct tcp_sock *tp, u32 *usrtt, int flag)
 {
 	__u32 seq_rtt;
 
@@ -1983,13 +1901,13 @@ static void tcp_ack_saw_tstamp(struct tc
 	 * in window is lost... Voila.	 			--ANK (010210)
 	 */
 	seq_rtt = tcp_time_stamp - tp->rx_opt.rcv_tsecr;
-	tcp_rtt_estimator(tp, seq_rtt);
+	tcp_rtt_estimator(tp, seq_rtt, usrtt);
 	tcp_set_rto(tp);
 	tp->backoff = 0;
 	tcp_bound_rto(tp);
 }
 
-static void tcp_ack_no_tstamp(struct tcp_sock *tp, u32 seq_rtt, int flag)
+static void tcp_ack_no_tstamp(struct tcp_sock *tp, u32 seq_rtt, u32 *usrtt, int flag)
 {
 	/* We don't have a timestamp. Can only use
 	 * packets that are not retransmitted to determine
@@ -2003,338 +1921,29 @@ static void tcp_ack_no_tstamp(struct tcp
 	if (flag & FLAG_RETRANS_DATA_ACKED)
 		return;
 
-	tcp_rtt_estimator(tp, seq_rtt);
+	tcp_rtt_estimator(tp, seq_rtt, usrtt);
 	tcp_set_rto(tp);
 	tp->backoff = 0;
 	tcp_bound_rto(tp);
 }
 
 static inline void tcp_ack_update_rtt(struct tcp_sock *tp,
-				      int flag, s32 seq_rtt)
+				      int flag, s32 seq_rtt, u32 *usrtt)
 {
 	/* Note that peer MAY send zero echo. In this case it is ignored. (rfc1323) */
 	if (tp->rx_opt.saw_tstamp && tp->rx_opt.rcv_tsecr)
-		tcp_ack_saw_tstamp(tp, flag);
+		tcp_ack_saw_tstamp(tp, usrtt, flag);
 	else if (seq_rtt >= 0)
-		tcp_ack_no_tstamp(tp, seq_rtt, flag);
+		tcp_ack_no_tstamp(tp, seq_rtt, usrtt, flag);
 }
 
-/*
- * Compute congestion window to use.
- *
- * This is from the implementation of BICTCP in
- * Lison-Xu, Kahaled Harfoush, and Injog Rhee.
- *  "Binary Increase Congestion Control for Fast, Long Distance
- *  Networks" in InfoComm 2004
- * Available from:
- *  http://www.csc.ncsu.edu/faculty/rhee/export/bitcp.pdf
- *
- * Unless BIC is enabled and congestion window is large
- * this behaves the same as the original Reno.
- */
-static inline __u32 bictcp_cwnd(struct tcp_sock *tp)
-{
-	/* orignal Reno behaviour */
-	if (!tcp_is_bic(tp))
-		return tp->snd_cwnd;
-
-	if (tp->bictcp.last_cwnd == tp->snd_cwnd &&
-	   (s32)(tcp_time_stamp - tp->bictcp.last_stamp) <= (HZ>>5))
-		return tp->bictcp.cnt;
-
-	tp->bictcp.last_cwnd = tp->snd_cwnd;
-	tp->bictcp.last_stamp = tcp_time_stamp;
-      
-	/* start off normal */
-	if (tp->snd_cwnd <= sysctl_tcp_bic_low_window)
-		tp->bictcp.cnt = tp->snd_cwnd;
-
-	/* binary increase */
-	else if (tp->snd_cwnd < tp->bictcp.last_max_cwnd) {
-		__u32 	dist = (tp->bictcp.last_max_cwnd - tp->snd_cwnd)
-			/ BICTCP_B;
-
-		if (dist > BICTCP_MAX_INCREMENT)
-			/* linear increase */
-			tp->bictcp.cnt = tp->snd_cwnd / BICTCP_MAX_INCREMENT;
-		else if (dist <= 1U)
-			/* binary search increase */
-			tp->bictcp.cnt = tp->snd_cwnd * BICTCP_FUNC_OF_MIN_INCR
-				/ BICTCP_B;
-		else
-			/* binary search increase */
-			tp->bictcp.cnt = tp->snd_cwnd / dist;
-	} else {
-		/* slow start amd linear increase */
-		if (tp->snd_cwnd < tp->bictcp.last_max_cwnd + BICTCP_B)
-			/* slow start */
-			tp->bictcp.cnt = tp->snd_cwnd * BICTCP_FUNC_OF_MIN_INCR
-				/ BICTCP_B;
-		else if (tp->snd_cwnd < tp->bictcp.last_max_cwnd
-			 		+ BICTCP_MAX_INCREMENT*(BICTCP_B-1))
-			/* slow start */
-			tp->bictcp.cnt = tp->snd_cwnd * (BICTCP_B-1)
-				/ (tp->snd_cwnd-tp->bictcp.last_max_cwnd);
-		else
-			/* linear increase */
-			tp->bictcp.cnt = tp->snd_cwnd / BICTCP_MAX_INCREMENT;
-	}
-	return tp->bictcp.cnt;
-}
-
-/* This is Jacobson's slow start and congestion avoidance. 
- * SIGCOMM '88, p. 328.
- */
-static inline void reno_cong_avoid(struct tcp_sock *tp)
+static inline void tcp_cong_avoid(struct tcp_sock *tp, u32 ack, u32 rtt,
+				  u32 in_flight, int good)
 {
-        if (tp->snd_cwnd <= tp->snd_ssthresh) {
-                /* In "safe" area, increase. */
-		if (tp->snd_cwnd < tp->snd_cwnd_clamp)
-			tp->snd_cwnd++;
-	} else {
-                /* In dangerous area, increase slowly.
-		 * In theory this is tp->snd_cwnd += 1 / tp->snd_cwnd
-		 */
-		if (tp->snd_cwnd_cnt >= bictcp_cwnd(tp)) {
-			if (tp->snd_cwnd < tp->snd_cwnd_clamp)
-				tp->snd_cwnd++;
-			tp->snd_cwnd_cnt=0;
-		} else
-			tp->snd_cwnd_cnt++;
-        }
+	tp->ca_ops->cong_avoid(tp, ack, rtt, in_flight, good);
 	tp->snd_cwnd_stamp = tcp_time_stamp;
 }
 
-/* This is based on the congestion detection/avoidance scheme described in
- *    Lawrence S. Brakmo and Larry L. Peterson.
- *    "TCP Vegas: End to end congestion avoidance on a global internet."
- *    IEEE Journal on Selected Areas in Communication, 13(8):1465--1480,
- *    October 1995. Available from:
- *	ftp://ftp.cs.arizona.edu/xkernel/Papers/jsac.ps
- *
- * See http://www.cs.arizona.edu/xkernel/ for their implementation.
- * The main aspects that distinguish this implementation from the
- * Arizona Vegas implementation are:
- *   o We do not change the loss detection or recovery mechanisms of
- *     Linux in any way. Linux already recovers from losses quite well,
- *     using fine-grained timers, NewReno, and FACK.
- *   o To avoid the performance penalty imposed by increasing cwnd
- *     only every-other RTT during slow start, we increase during
- *     every RTT during slow start, just like Reno.
- *   o Largely to allow continuous cwnd growth during slow start,
- *     we use the rate at which ACKs come back as the "actual"
- *     rate, rather than the rate at which data is sent.
- *   o To speed convergence to the right rate, we set the cwnd
- *     to achieve the right ("actual") rate when we exit slow start.
- *   o To filter out the noise caused by delayed ACKs, we use the
- *     minimum RTT sample observed during the last RTT to calculate
- *     the actual rate.
- *   o When the sender re-starts from idle, it waits until it has
- *     received ACKs for an entire flight of new data before making
- *     a cwnd adjustment decision. The original Vegas implementation
- *     assumed senders never went idle.
- */
-static void vegas_cong_avoid(struct tcp_sock *tp, u32 ack, u32 seq_rtt)
-{
-	/* The key players are v_beg_snd_una and v_beg_snd_nxt.
-	 *
-	 * These are so named because they represent the approximate values
-	 * of snd_una and snd_nxt at the beginning of the current RTT. More
-	 * precisely, they represent the amount of data sent during the RTT.
-	 * At the end of the RTT, when we receive an ACK for v_beg_snd_nxt,
-	 * we will calculate that (v_beg_snd_nxt - v_beg_snd_una) outstanding
-	 * bytes of data have been ACKed during the course of the RTT, giving
-	 * an "actual" rate of:
-	 *
-	 *     (v_beg_snd_nxt - v_beg_snd_una) / (rtt duration)
-	 *
-	 * Unfortunately, v_beg_snd_una is not exactly equal to snd_una,
-	 * because delayed ACKs can cover more than one segment, so they
-	 * don't line up nicely with the boundaries of RTTs.
-	 *
-	 * Another unfortunate fact of life is that delayed ACKs delay the
-	 * advance of the left edge of our send window, so that the number
-	 * of bytes we send in an RTT is often less than our cwnd will allow.
-	 * So we keep track of our cwnd separately, in v_beg_snd_cwnd.
-	 */
-
-	if (after(ack, tp->vegas.beg_snd_nxt)) {
-		/* Do the Vegas once-per-RTT cwnd adjustment. */
-		u32 old_wnd, old_snd_cwnd;
-
-		
-		/* Here old_wnd is essentially the window of data that was
-		 * sent during the previous RTT, and has all
-		 * been acknowledged in the course of the RTT that ended
-		 * with the ACK we just received. Likewise, old_snd_cwnd
-		 * is the cwnd during the previous RTT.
-		 */
-		old_wnd = (tp->vegas.beg_snd_nxt - tp->vegas.beg_snd_una) /
-			tp->mss_cache_std;
-		old_snd_cwnd = tp->vegas.beg_snd_cwnd;
-
-		/* Save the extent of the current window so we can use this
-		 * at the end of the next RTT.
-		 */
-		tp->vegas.beg_snd_una  = tp->vegas.beg_snd_nxt;
-		tp->vegas.beg_snd_nxt  = tp->snd_nxt;
-		tp->vegas.beg_snd_cwnd = tp->snd_cwnd;
-
-		/* Take into account the current RTT sample too, to
-		 * decrease the impact of delayed acks. This double counts
-		 * this sample since we count it for the next window as well,
-		 * but that's not too awful, since we're taking the min,
-		 * rather than averaging.
-		 */
-		vegas_rtt_calc(tp, seq_rtt);
-
-		/* We do the Vegas calculations only if we got enough RTT
-		 * samples that we can be reasonably sure that we got
-		 * at least one RTT sample that wasn't from a delayed ACK.
-		 * If we only had 2 samples total,
-		 * then that means we're getting only 1 ACK per RTT, which
-		 * means they're almost certainly delayed ACKs.
-		 * If  we have 3 samples, we should be OK.
-		 */
-
-		if (tp->vegas.cntRTT <= 2) {
-			/* We don't have enough RTT samples to do the Vegas
-			 * calculation, so we'll behave like Reno.
-			 */
-			if (tp->snd_cwnd > tp->snd_ssthresh)
-				tp->snd_cwnd++;
-		} else {
-			u32 rtt, target_cwnd, diff;
-
-			/* We have enough RTT samples, so, using the Vegas
-			 * algorithm, we determine if we should increase or
-			 * decrease cwnd, and by how much.
-			 */
-
-			/* Pluck out the RTT we are using for the Vegas
-			 * calculations. This is the min RTT seen during the
-			 * last RTT. Taking the min filters out the effects
-			 * of delayed ACKs, at the cost of noticing congestion
-			 * a bit later.
-			 */
-			rtt = tp->vegas.minRTT;
-
-			/* Calculate the cwnd we should have, if we weren't
-			 * going too fast.
-			 *
-			 * This is:
-			 *     (actual rate in segments) * baseRTT
-			 * We keep it as a fixed point number with
-			 * V_PARAM_SHIFT bits to the right of the binary point.
-			 */
-			target_cwnd = ((old_wnd * tp->vegas.baseRTT)
-				       << V_PARAM_SHIFT) / rtt;
-
-			/* Calculate the difference between the window we had,
-			 * and the window we would like to have. This quantity
-			 * is the "Diff" from the Arizona Vegas papers.
-			 *
-			 * Again, this is a fixed point number with
-			 * V_PARAM_SHIFT bits to the right of the binary
-			 * point.
-			 */
-			diff = (old_wnd << V_PARAM_SHIFT) - target_cwnd;
-
-			if (tp->snd_cwnd < tp->snd_ssthresh) {
-				/* Slow start.  */
-				if (diff > sysctl_tcp_vegas_gamma) {
-					/* Going too fast. Time to slow down
-					 * and switch to congestion avoidance.
-					 */
-					tp->snd_ssthresh = 2;
-
-					/* Set cwnd to match the actual rate
-					 * exactly:
-					 *   cwnd = (actual rate) * baseRTT
-					 * Then we add 1 because the integer
-					 * truncation robs us of full link
-					 * utilization.
-					 */
-					tp->snd_cwnd = min(tp->snd_cwnd,
-							   (target_cwnd >>
-							    V_PARAM_SHIFT)+1);
-
-				}
-			} else {
-				/* Congestion avoidance. */
-				u32 next_snd_cwnd;
-
-				/* Figure out where we would like cwnd
-				 * to be.
-				 */
-				if (diff > sysctl_tcp_vegas_beta) {
-					/* The old window was too fast, so
-					 * we slow down.
-					 */
-					next_snd_cwnd = old_snd_cwnd - 1;
-				} else if (diff < sysctl_tcp_vegas_alpha) {
-					/* We don't have enough extra packets
-					 * in the network, so speed up.
-					 */
-					next_snd_cwnd = old_snd_cwnd + 1;
-				} else {
-					/* Sending just as fast as we
-					 * should be.
-					 */
-					next_snd_cwnd = old_snd_cwnd;
-				}
-
-				/* Adjust cwnd upward or downward, toward the
-				 * desired value.
-				 */
-				if (next_snd_cwnd > tp->snd_cwnd)
-					tp->snd_cwnd++;
-				else if (next_snd_cwnd < tp->snd_cwnd)
-					tp->snd_cwnd--;
-			}
-		}
-
-		/* Wipe the slate clean for the next RTT. */
-		tp->vegas.cntRTT = 0;
-		tp->vegas.minRTT = 0x7fffffff;
-	}
-
-	/* The following code is executed for every ack we receive,
-	 * except for conditions checked in should_advance_cwnd()
-	 * before the call to tcp_cong_avoid(). Mainly this means that
-	 * we only execute this code if the ack actually acked some
-	 * data.
-	 */
-
-	/* If we are in slow start, increase our cwnd in response to this ACK.
-	 * (If we are not in slow start then we are in congestion avoidance,
-	 * and adjust our congestion window only once per RTT. See the code
-	 * above.)
-	 */
-	if (tp->snd_cwnd <= tp->snd_ssthresh) 
-		tp->snd_cwnd++;
-
-	/* to keep cwnd from growing without bound */
-	tp->snd_cwnd = min_t(u32, tp->snd_cwnd, tp->snd_cwnd_clamp);
-
-	/* Make sure that we are never so timid as to reduce our cwnd below
-	 * 2 MSS.
-	 *
-	 * Going below 2 MSS would risk huge delayed ACKs from our receiver.
-	 */
-	tp->snd_cwnd = max(tp->snd_cwnd, 2U);
-
-	tp->snd_cwnd_stamp = tcp_time_stamp;
-}
-
-static inline void tcp_cong_avoid(struct tcp_sock *tp, u32 ack, u32 seq_rtt)
-{
-	if (tcp_vegas_enabled(tp))
-		vegas_cong_avoid(tp, ack, seq_rtt);
-	else
-		reno_cong_avoid(tp);
-}
-
 /* Restart timer after forward progress on connection.
  * RFC2988 recommends to restart timer to now+rto.
  */
@@ -2348,15 +1957,6 @@ static inline void tcp_ack_packets_out(s
 	}
 }
 
-/* There is one downside to this scheme.  Although we keep the
- * ACK clock ticking, adjusting packet counters and advancing
- * congestion window, we do not liberate socket send buffer
- * space.
- *
- * Mucking with skb->truesize and sk->sk_wmem_alloc et al.
- * then making a write space wakeup callback is a possible
- * future enhancement.  WARNING: it is not trivial to make.
- */
 static int tcp_tso_acked(struct sock *sk, struct sk_buff *skb,
 			 __u32 now, __s32 *seq_rtt)
 {
@@ -2415,13 +2015,18 @@ static int tcp_tso_acked(struct sock *sk
 
 
 /* Remove acknowledged frames from the retransmission queue. */
-static int tcp_clean_rtx_queue(struct sock *sk, __s32 *seq_rtt_p)
+static int tcp_clean_rtx_queue(struct sock *sk, __s32 *seq_rtt_p, s32 *seq_usrtt)
 {
 	struct tcp_sock *tp = tcp_sk(sk);
 	struct sk_buff *skb;
 	__u32 now = tcp_time_stamp;
 	int acked = 0;
 	__s32 seq_rtt = -1;
+	struct timeval usnow;
+	u32 pkts_acked = 0;
+
+	if (seq_usrtt)
+		do_gettimeofday(&usnow);
 
 	while ((skb = skb_peek(&sk->sk_write_queue)) &&
 	       skb != sk->sk_send_head) {
@@ -2433,7 +2038,8 @@ static int tcp_clean_rtx_queue(struct so
 		 * the other end.
 		 */
 		if (after(scb->end_seq, tp->snd_una)) {
-			if (tcp_skb_pcount(skb) > 1)
+			if (tcp_skb_pcount(skb) > 1 &&
+			    after(tp->snd_una, scb->seq))
 				acked |= tcp_tso_acked(sk, skb,
 						       now, &seq_rtt);
 			break;
@@ -2448,6 +2054,7 @@ static int tcp_clean_rtx_queue(struct so
 		 */
 		if (!(scb->flags & TCPCB_FLAG_SYN)) {
 			acked |= FLAG_DATA_ACKED;
+			++pkts_acked;
 		} else {
 			acked |= FLAG_SYN_ACKED;
 			tp->retrans_stamp = 0;
@@ -2461,6 +2068,10 @@ static int tcp_clean_rtx_queue(struct so
 				seq_rtt = -1;
 			} else if (seq_rtt < 0)
 				seq_rtt = now - scb->when;
+			if (seq_usrtt)
+				*seq_usrtt = (usnow.tv_sec - skb->stamp.tv_sec) * 1000000
+					+ (usnow.tv_usec - skb->stamp.tv_usec);
+
 			if (sacked & TCPCB_SACKED_ACKED)
 				tp->sacked_out -= tcp_skb_pcount(skb);
 			if (sacked & TCPCB_LOST)
@@ -2479,8 +2090,11 @@ static int tcp_clean_rtx_queue(struct so
 	}
 
 	if (acked&FLAG_ACKED) {
-		tcp_ack_update_rtt(tp, acked, seq_rtt);
+		tcp_ack_update_rtt(tp, acked, seq_rtt, seq_usrtt);
 		tcp_ack_packets_out(sk, tp);
+
+		if (tp->ca_ops->pkts_acked)
+			tp->ca_ops->pkts_acked(tp, pkts_acked);
 	}
 
 #if FASTRETRANS_DEBUG > 0
@@ -2624,257 +2238,6 @@ static void tcp_process_frto(struct sock
 	tp->frto_counter = (tp->frto_counter + 1) % 3;
 }
 
-/*
- * TCP Westwood+
- */
-
-/*
- * @init_westwood
- * This function initializes fields used in TCP Westwood+. We can't
- * get no information about RTTmin at this time so we simply set it to
- * TCP_WESTWOOD_INIT_RTT. This value was chosen to be too conservative
- * since in this way we're sure it will be updated in a consistent
- * way as soon as possible. It will reasonably happen within the first
- * RTT period of the connection lifetime.
- */
-
-static void init_westwood(struct sock *sk)
-{
-        struct tcp_sock *tp = tcp_sk(sk);
-
-        tp->westwood.bw_ns_est = 0;
-        tp->westwood.bw_est = 0;
-        tp->westwood.accounted = 0;
-        tp->westwood.cumul_ack = 0;
-        tp->westwood.rtt_win_sx = tcp_time_stamp;
-        tp->westwood.rtt = TCP_WESTWOOD_INIT_RTT;
-        tp->westwood.rtt_min = TCP_WESTWOOD_INIT_RTT;
-        tp->westwood.snd_una = tp->snd_una;
-}
-
-/*
- * @westwood_do_filter
- * Low-pass filter. Implemented using constant coeffients.
- */
-
-static inline __u32 westwood_do_filter(__u32 a, __u32 b)
-{
-	return (((7 * a) + b) >> 3);
-}
-
-static void westwood_filter(struct sock *sk, __u32 delta)
-{
-	struct tcp_sock *tp = tcp_sk(sk);
-
-	tp->westwood.bw_ns_est =
-		westwood_do_filter(tp->westwood.bw_ns_est, 
-				   tp->westwood.bk / delta);
-	tp->westwood.bw_est =
-		westwood_do_filter(tp->westwood.bw_est,
-				   tp->westwood.bw_ns_est);
-}
-
-/* 
- * @westwood_update_rttmin
- * It is used to update RTTmin. In this case we MUST NOT use
- * WESTWOOD_RTT_MIN minimum bound since we could be on a LAN!
- */
-
-static inline __u32 westwood_update_rttmin(const struct sock *sk)
-{
-	const struct tcp_sock *tp = tcp_sk(sk);
-	__u32 rttmin = tp->westwood.rtt_min;
-
-	if (tp->westwood.rtt != 0 &&
-	    (tp->westwood.rtt < tp->westwood.rtt_min || !rttmin))
-		rttmin = tp->westwood.rtt;
-
-	return rttmin;
-}
-
-/*
- * @westwood_acked
- * Evaluate increases for dk. 
- */
-
-static inline __u32 westwood_acked(const struct sock *sk)
-{
-	const struct tcp_sock *tp = tcp_sk(sk);
-
-	return tp->snd_una - tp->westwood.snd_una;
-}
-
-/*
- * @westwood_new_window
- * It evaluates if we are receiving data inside the same RTT window as
- * when we started.
- * Return value:
- * It returns 0 if we are still evaluating samples in the same RTT
- * window, 1 if the sample has to be considered in the next window.
- */
-
-static int westwood_new_window(const struct sock *sk)
-{
-	const struct tcp_sock *tp = tcp_sk(sk);
-	__u32 left_bound;
-	__u32 rtt;
-	int ret = 0;
-
-	left_bound = tp->westwood.rtt_win_sx;
-	rtt = max(tp->westwood.rtt, (u32) TCP_WESTWOOD_RTT_MIN);
-
-	/*
-	 * A RTT-window has passed. Be careful since if RTT is less than
-	 * 50ms we don't filter but we continue 'building the sample'.
-	 * This minimum limit was choosen since an estimation on small
-	 * time intervals is better to avoid...
-	 * Obvioulsy on a LAN we reasonably will always have
-	 * right_bound = left_bound + WESTWOOD_RTT_MIN
-         */
-
-	if ((left_bound + rtt) < tcp_time_stamp)
-		ret = 1;
-
-	return ret;
-}
-
-/*
- * @westwood_update_window
- * It updates RTT evaluation window if it is the right moment to do
- * it. If so it calls filter for evaluating bandwidth. 
- */
-
-static void __westwood_update_window(struct sock *sk, __u32 now)
-{
-	struct tcp_sock *tp = tcp_sk(sk);
-	__u32 delta = now - tp->westwood.rtt_win_sx;
-
-        if (delta) {
-		if (tp->westwood.rtt)
-			westwood_filter(sk, delta);
-
-		tp->westwood.bk = 0;
-		tp->westwood.rtt_win_sx = tcp_time_stamp;
-	}
-}
-
-
-static void westwood_update_window(struct sock *sk, __u32 now)
-{
-	if (westwood_new_window(sk)) 
-		__westwood_update_window(sk, now);
-}
-
-/*
- * @__tcp_westwood_fast_bw
- * It is called when we are in fast path. In particular it is called when
- * header prediction is successfull. In such case infact update is
- * straight forward and doesn't need any particular care.
- */
-
-static void __tcp_westwood_fast_bw(struct sock *sk, struct sk_buff *skb)
-{
-	struct tcp_sock *tp = tcp_sk(sk);
-
-	westwood_update_window(sk, tcp_time_stamp);
-
-	tp->westwood.bk += westwood_acked(sk);
-	tp->westwood.snd_una = tp->snd_una;
-	tp->westwood.rtt_min = westwood_update_rttmin(sk);
-}
-
-static inline void tcp_westwood_fast_bw(struct sock *sk, struct sk_buff *skb)
-{
-        if (tcp_is_westwood(tcp_sk(sk)))
-                __tcp_westwood_fast_bw(sk, skb);
-}
-
-
-/*
- * @westwood_dupack_update
- * It updates accounted and cumul_ack when receiving a dupack.
- */
-
-static void westwood_dupack_update(struct sock *sk)
-{
-	struct tcp_sock *tp = tcp_sk(sk);
-
-	tp->westwood.accounted += tp->mss_cache_std;
-	tp->westwood.cumul_ack = tp->mss_cache_std;
-}
-
-static inline int westwood_may_change_cumul(struct tcp_sock *tp)
-{
-	return (tp->westwood.cumul_ack > tp->mss_cache_std);
-}
-
-static inline void westwood_partial_update(struct tcp_sock *tp)
-{
-	tp->westwood.accounted -= tp->westwood.cumul_ack;
-	tp->westwood.cumul_ack = tp->mss_cache_std;
-}
-
-static inline void westwood_complete_update(struct tcp_sock *tp)
-{
-	tp->westwood.cumul_ack -= tp->westwood.accounted;
-	tp->westwood.accounted = 0;
-}
-
-/*
- * @westwood_acked_count
- * This function evaluates cumul_ack for evaluating dk in case of
- * delayed or partial acks.
- */
-
-static inline __u32 westwood_acked_count(struct sock *sk)
-{
-	struct tcp_sock *tp = tcp_sk(sk);
-
-	tp->westwood.cumul_ack = westwood_acked(sk);
-
-        /* If cumul_ack is 0 this is a dupack since it's not moving
-         * tp->snd_una.
-         */
-        if (!(tp->westwood.cumul_ack))
-                westwood_dupack_update(sk);
-
-        if (westwood_may_change_cumul(tp)) {
-		/* Partial or delayed ack */
-		if (tp->westwood.accounted >= tp->westwood.cumul_ack)
-			westwood_partial_update(tp);
-		else
-			westwood_complete_update(tp);
-	}
-
-	tp->westwood.snd_una = tp->snd_una;
-
-	return tp->westwood.cumul_ack;
-}
-
-
-/*
- * @__tcp_westwood_slow_bw
- * It is called when something is going wrong..even if there could
- * be no problems! Infact a simple delayed packet may trigger a
- * dupack. But we need to be careful in such case.
- */
-
-static void __tcp_westwood_slow_bw(struct sock *sk, struct sk_buff *skb)
-{
-	struct tcp_sock *tp = tcp_sk(sk);
-
-	westwood_update_window(sk, tcp_time_stamp);
-
-	tp->westwood.bk += westwood_acked_count(sk);
-	tp->westwood.rtt_min = westwood_update_rttmin(sk);
-}
-
-static inline void tcp_westwood_slow_bw(struct sock *sk, struct sk_buff *skb)
-{
-        if (tcp_is_westwood(tcp_sk(sk)))
-                __tcp_westwood_slow_bw(sk, skb);
-}
-
 /* This routine deals with incoming acks, but not outgoing ones. */
 static int tcp_ack(struct sock *sk, struct sk_buff *skb, int flag)
 {
@@ -2884,6 +2247,7 @@ static int tcp_ack(struct sock *sk, stru
 	u32 ack = TCP_SKB_CB(skb)->ack_seq;
 	u32 prior_in_flight;
 	s32 seq_rtt;
+	s32 seq_usrtt = 0;
 	int prior_packets;
 
 	/* If the ack is newer than sent or older than previous acks
@@ -2902,9 +2266,10 @@ static int tcp_ack(struct sock *sk, stru
 		 */
 		tcp_update_wl(tp, ack, ack_seq);
 		tp->snd_una = ack;
-		tcp_westwood_fast_bw(sk, skb);
 		flag |= FLAG_WIN_UPDATE;
 
+		tcp_ca_event(tp, CA_EVENT_FAST_ACK);
+
 		NET_INC_STATS_BH(LINUX_MIB_TCPHPACKS);
 	} else {
 		if (ack_seq != TCP_SKB_CB(skb)->end_seq)
@@ -2920,7 +2285,7 @@ static int tcp_ack(struct sock *sk, stru
 		if (TCP_ECN_rcv_ecn_echo(tp, skb->h.th))
 			flag |= FLAG_ECE;
 
-		tcp_westwood_slow_bw(sk,skb);
+		tcp_ca_event(tp, CA_EVENT_SLOW_ACK);
 	}
 
 	/* We passed data and got it acked, remove any soft error
@@ -2935,22 +2300,20 @@ static int tcp_ack(struct sock *sk, stru
 	prior_in_flight = tcp_packets_in_flight(tp);
 
 	/* See if we can take anything off of the retransmit queue. */
-	flag |= tcp_clean_rtx_queue(sk, &seq_rtt);
+	flag |= tcp_clean_rtx_queue(sk, &seq_rtt,
+				    tp->ca_ops->rtt_sample ? &seq_usrtt : NULL);
 
 	if (tp->frto_counter)
 		tcp_process_frto(sk, prior_snd_una);
 
 	if (tcp_ack_is_dubious(tp, flag)) {
 		/* Advanve CWND, if state allows this. */
-		if ((flag & FLAG_DATA_ACKED) &&
-		    (tcp_vegas_enabled(tp) || prior_in_flight >= tp->snd_cwnd) &&
-		    tcp_may_raise_cwnd(tp, flag))
-			tcp_cong_avoid(tp, ack, seq_rtt);
+		if ((flag & FLAG_DATA_ACKED) && tcp_may_raise_cwnd(tp, flag))
+			tcp_cong_avoid(tp, ack,  seq_rtt, prior_in_flight, 0);
 		tcp_fastretrans_alert(sk, prior_snd_una, prior_packets, flag);
 	} else {
-		if ((flag & FLAG_DATA_ACKED) && 
-		    (tcp_vegas_enabled(tp) || prior_in_flight >= tp->snd_cwnd))
-			tcp_cong_avoid(tp, ack, seq_rtt);
+		if ((flag & FLAG_DATA_ACKED))
+			tcp_cong_avoid(tp, ack, seq_rtt, prior_in_flight, 1);
 	}
 
 	if ((flag & FLAG_FORWARD_PROGRESS) || !(flag&FLAG_NOT_DUP))
@@ -3439,7 +2802,7 @@ static void tcp_sack_remove(struct tcp_s
 	int this_sack;
 
 	/* Empty ofo queue, hence, all the SACKs are eaten. Clear. */
-	if (skb_queue_len(&tp->out_of_order_queue) == 0) {
+	if (skb_queue_empty(&tp->out_of_order_queue)) {
 		tp->rx_opt.num_sacks = 0;
 		tp->rx_opt.eff_sacks = tp->rx_opt.dsack;
 		return;
@@ -3572,13 +2935,13 @@ queue_and_out:
 		if(th->fin)
 			tcp_fin(skb, sk, th);
 
-		if (skb_queue_len(&tp->out_of_order_queue)) {
+		if (!skb_queue_empty(&tp->out_of_order_queue)) {
 			tcp_ofo_queue(sk);
 
 			/* RFC2581. 4.2. SHOULD send immediate ACK, when
 			 * gap in queue is filled.
 			 */
-			if (!skb_queue_len(&tp->out_of_order_queue))
+			if (skb_queue_empty(&tp->out_of_order_queue))
 				tp->ack.pingpong = 0;
 		}
 
@@ -3886,9 +3249,8 @@ static int tcp_prune_queue(struct sock *
 	 * This must not ever occur. */
 
 	/* First, purge the out_of_order queue. */
-	if (skb_queue_len(&tp->out_of_order_queue)) {
-		NET_ADD_STATS_BH(LINUX_MIB_OFOPRUNED, 
-				 skb_queue_len(&tp->out_of_order_queue));
+	if (!skb_queue_empty(&tp->out_of_order_queue)) {
+		NET_INC_STATS_BH(LINUX_MIB_OFOPRUNED);
 		__skb_queue_purge(&tp->out_of_order_queue);
 
 		/* Reset SACK state.  A conforming SACK implementation will
@@ -3937,6 +3299,28 @@ void tcp_cwnd_application_limited(struct
 	tp->snd_cwnd_stamp = tcp_time_stamp;
 }
 
+static inline int tcp_should_expand_sndbuf(struct sock *sk, struct tcp_sock *tp)
+{
+	/* If the user specified a specific send buffer setting, do
+	 * not modify it.
+	 */
+	if (sk->sk_userlocks & SOCK_SNDBUF_LOCK)
+		return 0;
+
+	/* If we are under global TCP memory pressure, do not expand.  */
+	if (tcp_memory_pressure)
+		return 0;
+
+	/* If we are under soft global TCP memory pressure, do not expand.  */
+	if (atomic_read(&tcp_memory_allocated) >= sysctl_tcp_mem[0])
+		return 0;
+
+	/* If we filled the congestion window, do not expand.  */
+	if (tp->packets_out >= tp->snd_cwnd)
+		return 0;
+
+	return 1;
+}
 
 /* When incoming ACK allowed to free some skb from write_queue,
  * we remember this event in flag SOCK_QUEUE_SHRUNK and wake up socket
@@ -3948,11 +3332,8 @@ static void tcp_new_space(struct sock *s
 {
 	struct tcp_sock *tp = tcp_sk(sk);
 
-	if (tp->packets_out < tp->snd_cwnd &&
-	    !(sk->sk_userlocks & SOCK_SNDBUF_LOCK) &&
-	    !tcp_memory_pressure &&
-	    atomic_read(&tcp_memory_allocated) < sysctl_tcp_mem[0]) {
- 		int sndmem = max_t(u32, tp->rx_opt.mss_clamp, tp->mss_cache_std) +
+	if (tcp_should_expand_sndbuf(sk, tp)) {
+ 		int sndmem = max_t(u32, tp->rx_opt.mss_clamp, tp->mss_cache) +
 			MAX_TCP_HEADER + 16 + sizeof(struct sk_buff),
 		    demanded = max_t(unsigned int, tp->snd_cwnd,
 						   tp->reordering + 1);
@@ -3975,22 +3356,9 @@ static inline void tcp_check_space(struc
 	}
 }
 
-static void __tcp_data_snd_check(struct sock *sk, struct sk_buff *skb)
-{
-	struct tcp_sock *tp = tcp_sk(sk);
-
-	if (after(TCP_SKB_CB(skb)->end_seq, tp->snd_una + tp->snd_wnd) ||
-	    tcp_packets_in_flight(tp) >= tp->snd_cwnd ||
-	    tcp_write_xmit(sk, tp->nonagle))
-		tcp_check_probe_timer(sk, tp);
-}
-
-static __inline__ void tcp_data_snd_check(struct sock *sk)
+static __inline__ void tcp_data_snd_check(struct sock *sk, struct tcp_sock *tp)
 {
-	struct sk_buff *skb = sk->sk_send_head;
-
-	if (skb != NULL)
-		__tcp_data_snd_check(sk, skb);
+	tcp_push_pending_frames(sk, tp);
 	tcp_check_space(sk);
 }
 
@@ -4284,7 +3652,7 @@ int tcp_rcv_established(struct sock *sk,
 				 */
 				tcp_ack(sk, skb, 0);
 				__kfree_skb(skb); 
-				tcp_data_snd_check(sk);
+				tcp_data_snd_check(sk, tp);
 				return 0;
 			} else { /* Header too small */
 				TCP_INC_STATS_BH(TCP_MIB_INERRS);
@@ -4350,7 +3718,7 @@ int tcp_rcv_established(struct sock *sk,
 			if (TCP_SKB_CB(skb)->ack_seq != tp->snd_una) {
 				/* Well, only one small jumplet in fast path... */
 				tcp_ack(sk, skb, FLAG_DATA);
-				tcp_data_snd_check(sk);
+				tcp_data_snd_check(sk, tp);
 				if (!tcp_ack_scheduled(tp))
 					goto no_ack;
 			}
@@ -4428,7 +3796,7 @@ step5:
 	/* step 7: process the segment text */
 	tcp_data_queue(sk, skb);
 
-	tcp_data_snd_check(sk);
+	tcp_data_snd_check(sk, tp);
 	tcp_ack_snd_check(sk);
 	return 0;
 
@@ -4552,6 +3920,8 @@ static int tcp_rcv_synsent_state_process
 
 		tcp_init_metrics(sk);
 
+		tcp_init_congestion_control(tp);
+
 		/* Prevent spurious tcp_cwnd_restart() on first data
 		 * packet.
 		 */
@@ -4708,9 +4078,6 @@ int tcp_rcv_state_process(struct sock *s
 			if(tp->af_specific->conn_request(sk, skb) < 0)
 				return 1;
 
-			init_westwood(sk);
-			init_bictcp(tp);
-
 			/* Now we have several options: In theory there is 
 			 * nothing else in the frame. KA9Q has an option to 
 			 * send data with the syn, BSD accepts data with the
@@ -4732,9 +4099,6 @@ int tcp_rcv_state_process(struct sock *s
 		goto discard;
 
 	case TCP_SYN_SENT:
-		init_westwood(sk);
-		init_bictcp(tp);
-
 		queued = tcp_rcv_synsent_state_process(sk, skb, th, len);
 		if (queued >= 0)
 			return queued;
@@ -4742,7 +4106,7 @@ int tcp_rcv_state_process(struct sock *s
 		/* Do step6 onward by hand. */
 		tcp_urg(sk, skb, th);
 		__kfree_skb(skb);
-		tcp_data_snd_check(sk);
+		tcp_data_snd_check(sk, tp);
 		return 0;
 	}
 
@@ -4816,7 +4180,7 @@ int tcp_rcv_state_process(struct sock *s
 				 */
 				if (tp->rx_opt.saw_tstamp && tp->rx_opt.rcv_tsecr &&
 				    !tp->srtt)
-					tcp_ack_saw_tstamp(tp, 0);
+					tcp_ack_saw_tstamp(tp, 0, 0);
 
 				if (tp->rx_opt.tstamp_ok)
 					tp->advmss -= TCPOLEN_TSTAMP_ALIGNED;
@@ -4828,6 +4192,8 @@ int tcp_rcv_state_process(struct sock *s
 
 				tcp_init_metrics(sk);
 
+				tcp_init_congestion_control(tp);
+
 				/* Prevent spurious tcp_cwnd_restart() on
 				 * first data packet.
 				 */
@@ -4931,7 +4297,7 @@ int tcp_rcv_state_process(struct sock *s
 
 	/* tcp_data could move socket to TIME-WAIT */
 	if (sk->sk_state != TCP_CLOSE) {
-		tcp_data_snd_check(sk);
+		tcp_data_snd_check(sk, tp);
 		tcp_ack_snd_check(sk);
 	}
 
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -36,7 +36,7 @@
  *					ACK bit.
  *		Andi Kleen :		Implemented fast path mtu discovery.
  *	     				Fixed many serious bugs in the
- *					open_request handling and moved
+ *					request_sock handling and moved
  *					most of it into the af independent code.
  *					Added tail drop and some other bugfixes.
  *					Added new listen sematics.
@@ -242,9 +242,14 @@ static int tcp_v4_get_port(struct sock *
 		tcp_port_rover = rover;
 		spin_unlock(&tcp_portalloc_lock);
 
-		/* Exhausted local port range during search? */
+		/* Exhausted local port range during search?  It is not
+		 * possible for us to be holding one of the bind hash
+		 * locks if this test triggers, because if 'remaining'
+		 * drops to zero, we broke out of the do/while loop at
+		 * the top level, not from the 'break;' statement.
+		 */
 		ret = 1;
-		if (remaining <= 0)
+		if (unlikely(remaining <= 0))
 			goto fail;
 
 		/* OK, here is the one we will use.  HEAD is
@@ -869,21 +874,23 @@ static __inline__ u32 tcp_v4_synq_hash(u
 	return (jhash_2words(raddr, (u32) rport, rnd) & (TCP_SYNQ_HSIZE - 1));
 }
 
-static struct open_request *tcp_v4_search_req(struct tcp_sock *tp,
-					      struct open_request ***prevp,
+static struct request_sock *tcp_v4_search_req(struct tcp_sock *tp,
+					      struct request_sock ***prevp,
 					      __u16 rport,
 					      __u32 raddr, __u32 laddr)
 {
-	struct tcp_listen_opt *lopt = tp->listen_opt;
-	struct open_request *req, **prev;
+	struct listen_sock *lopt = tp->accept_queue.listen_opt;
+	struct request_sock *req, **prev;
 
 	for (prev = &lopt->syn_table[tcp_v4_synq_hash(raddr, rport, lopt->hash_rnd)];
 	     (req = *prev) != NULL;
 	     prev = &req->dl_next) {
-		if (req->rmt_port == rport &&
-		    req->af.v4_req.rmt_addr == raddr &&
-		    req->af.v4_req.loc_addr == laddr &&
-		    TCP_INET_FAMILY(req->class->family)) {
+		const struct inet_request_sock *ireq = inet_rsk(req);
+
+		if (ireq->rmt_port == rport &&
+		    ireq->rmt_addr == raddr &&
+		    ireq->loc_addr == laddr &&
+		    TCP_INET_FAMILY(req->rsk_ops->family)) {
 			BUG_TRAP(!req->sk);
 			*prevp = prev;
 			break;
@@ -893,21 +900,13 @@ static struct open_request *tcp_v4_searc
 	return req;
 }
 
-static void tcp_v4_synq_add(struct sock *sk, struct open_request *req)
+static void tcp_v4_synq_add(struct sock *sk, struct request_sock *req)
 {
 	struct tcp_sock *tp = tcp_sk(sk);
-	struct tcp_listen_opt *lopt = tp->listen_opt;
-	u32 h = tcp_v4_synq_hash(req->af.v4_req.rmt_addr, req->rmt_port, lopt->hash_rnd);
-
-	req->expires = jiffies + TCP_TIMEOUT_INIT;
-	req->retrans = 0;
-	req->sk = NULL;
-	req->dl_next = lopt->syn_table[h];
-
-	write_lock(&tp->syn_wait_lock);
-	lopt->syn_table[h] = req;
-	write_unlock(&tp->syn_wait_lock);
+	struct listen_sock *lopt = tp->accept_queue.listen_opt;
+	u32 h = tcp_v4_synq_hash(inet_rsk(req)->rmt_addr, inet_rsk(req)->rmt_port, lopt->hash_rnd);
 
+	reqsk_queue_hash_req(&tp->accept_queue, h, req, TCP_TIMEOUT_INIT);
 	tcp_synq_added(sk);
 }
 
@@ -1050,7 +1049,7 @@ void tcp_v4_err(struct sk_buff *skb, u32
 	}
 
 	switch (sk->sk_state) {
-		struct open_request *req, **prev;
+		struct request_sock *req, **prev;
 	case TCP_LISTEN:
 		if (sock_owned_by_user(sk))
 			goto out;
@@ -1065,7 +1064,7 @@ void tcp_v4_err(struct sk_buff *skb, u32
 		 */
 		BUG_TRAP(!req->sk);
 
-		if (seq != req->snt_isn) {
+		if (seq != tcp_rsk(req)->snt_isn) {
 			NET_INC_STATS_BH(LINUX_MIB_OUTOFWINDOWICMPS);
 			goto out;
 		}
@@ -1254,28 +1253,29 @@ static void tcp_v4_timewait_ack(struct s
 	tcp_tw_put(tw);
 }
 
-static void tcp_v4_or_send_ack(struct sk_buff *skb, struct open_request *req)
+static void tcp_v4_reqsk_send_ack(struct sk_buff *skb, struct request_sock *req)
 {
-	tcp_v4_send_ack(skb, req->snt_isn + 1, req->rcv_isn + 1, req->rcv_wnd,
+	tcp_v4_send_ack(skb, tcp_rsk(req)->snt_isn + 1, tcp_rsk(req)->rcv_isn + 1, req->rcv_wnd,
 			req->ts_recent);
 }
 
 static struct dst_entry* tcp_v4_route_req(struct sock *sk,
-					  struct open_request *req)
+					  struct request_sock *req)
 {
 	struct rtable *rt;
-	struct ip_options *opt = req->af.v4_req.opt;
+	const struct inet_request_sock *ireq = inet_rsk(req);
+	struct ip_options *opt = inet_rsk(req)->opt;
 	struct flowi fl = { .oif = sk->sk_bound_dev_if,
 			    .nl_u = { .ip4_u =
 				      { .daddr = ((opt && opt->srr) ?
 						  opt->faddr :
-						  req->af.v4_req.rmt_addr),
-					.saddr = req->af.v4_req.loc_addr,
+						  ireq->rmt_addr),
+					.saddr = ireq->loc_addr,
 					.tos = RT_CONN_FLAGS(sk) } },
 			    .proto = IPPROTO_TCP,
 			    .uli_u = { .ports =
 				       { .sport = inet_sk(sk)->sport,
-					 .dport = req->rmt_port } } };
+					 .dport = ireq->rmt_port } } };
 
 	if (ip_route_output_flow(&rt, &fl, sk, 0)) {
 		IP_INC_STATS_BH(IPSTATS_MIB_OUTNOROUTES);
@@ -1291,12 +1291,13 @@ static struct dst_entry* tcp_v4_route_re
 
 /*
  *	Send a SYN-ACK after having received an ACK.
- *	This still operates on a open_request only, not on a big
+ *	This still operates on a request_sock only, not on a big
  *	socket.
  */
-static int tcp_v4_send_synack(struct sock *sk, struct open_request *req,
+static int tcp_v4_send_synack(struct sock *sk, struct request_sock *req,
 			      struct dst_entry *dst)
 {
+	const struct inet_request_sock *ireq = inet_rsk(req);
 	int err = -1;
 	struct sk_buff * skb;
 
@@ -1310,14 +1311,14 @@ static int tcp_v4_send_synack(struct soc
 		struct tcphdr *th = skb->h.th;
 
 		th->check = tcp_v4_check(th, skb->len,
-					 req->af.v4_req.loc_addr,
-					 req->af.v4_req.rmt_addr,
+					 ireq->loc_addr,
+					 ireq->rmt_addr,
 					 csum_partial((char *)th, skb->len,
 						      skb->csum));
 
-		err = ip_build_and_send_pkt(skb, sk, req->af.v4_req.loc_addr,
-					    req->af.v4_req.rmt_addr,
-					    req->af.v4_req.opt);
+		err = ip_build_and_send_pkt(skb, sk, ireq->loc_addr,
+					    ireq->rmt_addr,
+					    ireq->opt);
 		if (err == NET_XMIT_CN)
 			err = 0;
 	}
@@ -1328,12 +1329,12 @@ out:
 }
 
 /*
- *	IPv4 open_request destructor.
+ *	IPv4 request_sock destructor.
  */
-static void tcp_v4_or_free(struct open_request *req)
+static void tcp_v4_reqsk_destructor(struct request_sock *req)
 {
-	if (req->af.v4_req.opt)
-		kfree(req->af.v4_req.opt);
+	if (inet_rsk(req)->opt)
+		kfree(inet_rsk(req)->opt);
 }
 
 static inline void syn_flood_warning(struct sk_buff *skb)
@@ -1349,7 +1350,7 @@ static inline void syn_flood_warning(str
 }
 
 /*
- * Save and compile IPv4 options into the open_request if needed.
+ * Save and compile IPv4 options into the request_sock if needed.
  */
 static inline struct ip_options *tcp_v4_save_options(struct sock *sk,
 						     struct sk_buff *skb)
@@ -1370,33 +1371,20 @@ static inline struct ip_options *tcp_v4_
 	return dopt;
 }
 
-/*
- * Maximum number of SYN_RECV sockets in queue per LISTEN socket.
- * One SYN_RECV socket costs about 80bytes on a 32bit machine.
- * It would be better to replace it with a global counter for all sockets
- * but then some measure against one socket starving all other sockets
- * would be needed.
- *
- * It was 128 by default. Experiments with real servers show, that
- * it is absolutely not enough even at 100conn/sec. 256 cures most
- * of problems. This value is adjusted to 128 for very small machines
- * (<=32Mb of memory) and to 1024 on normal or better ones (>=256Mb).
- * Further increasing requires to change hash table size.
- */
-int sysctl_max_syn_backlog = 256;
-
-struct or_calltable or_ipv4 = {
+struct request_sock_ops tcp_request_sock_ops = {
 	.family		=	PF_INET,
+	.obj_size	=	sizeof(struct tcp_request_sock),
 	.rtx_syn_ack	=	tcp_v4_send_synack,
-	.send_ack	=	tcp_v4_or_send_ack,
-	.destructor	=	tcp_v4_or_free,
+	.send_ack	=	tcp_v4_reqsk_send_ack,
+	.destructor	=	tcp_v4_reqsk_destructor,
 	.send_reset	=	tcp_v4_send_reset,
 };
 
 int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
 {
+	struct inet_request_sock *ireq;
 	struct tcp_options_received tmp_opt;
-	struct open_request *req;
+	struct request_sock *req;
 	__u32 saddr = skb->nh.iph->saddr;
 	__u32 daddr = skb->nh.iph->daddr;
 	__u32 isn = TCP_SKB_CB(skb)->when;
@@ -1433,7 +1421,7 @@ int tcp_v4_conn_request(struct sock *sk,
 	if (sk_acceptq_is_full(sk) && tcp_synq_young(sk) > 1)
 		goto drop;
 
-	req = tcp_openreq_alloc();
+	req = reqsk_alloc(&tcp_request_sock_ops);
 	if (!req)
 		goto drop;
 
@@ -1461,10 +1449,10 @@ int tcp_v4_conn_request(struct sock *sk,
 
 	tcp_openreq_init(req, &tmp_opt, skb);
 
-	req->af.v4_req.loc_addr = daddr;
-	req->af.v4_req.rmt_addr = saddr;
-	req->af.v4_req.opt = tcp_v4_save_options(sk, skb);
-	req->class = &or_ipv4;
+	ireq = inet_rsk(req);
+	ireq->loc_addr = daddr;
+	ireq->rmt_addr = saddr;
+	ireq->opt = tcp_v4_save_options(sk, skb);
 	if (!want_cookie)
 		TCP_ECN_create_request(req, skb->h.th);
 
@@ -1511,32 +1499,31 @@ int tcp_v4_conn_request(struct sock *sk,
 			 * to destinations, already remembered
 			 * to the moment of synflood.
 			 */
-			NETDEBUG(if (net_ratelimit()) \
-					printk(KERN_DEBUG "TCP: drop open "
-							  "request from %u.%u."
-							  "%u.%u/%u\n", \
-					       NIPQUAD(saddr),
-					       ntohs(skb->h.th->source)));
+			LIMIT_NETDEBUG(printk(KERN_DEBUG "TCP: drop open "
+					      "request from %u.%u."
+					      "%u.%u/%u\n",
+					      NIPQUAD(saddr),
+					      ntohs(skb->h.th->source)));
 			dst_release(dst);
 			goto drop_and_free;
 		}
 
 		isn = tcp_v4_init_sequence(sk, skb);
 	}
-	req->snt_isn = isn;
+	tcp_rsk(req)->snt_isn = isn;
 
 	if (tcp_v4_send_synack(sk, req, dst))
 		goto drop_and_free;
 
 	if (want_cookie) {
-	   	tcp_openreq_free(req);
+	   	reqsk_free(req);
 	} else {
 		tcp_v4_synq_add(sk, req);
 	}
 	return 0;
 
 drop_and_free:
-	tcp_openreq_free(req);
+	reqsk_free(req);
 drop:
 	TCP_INC_STATS_BH(TCP_MIB_ATTEMPTFAILS);
 	return 0;
@@ -1548,9 +1535,10 @@ drop:
  * now create the new socket.
  */
 struct sock *tcp_v4_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
-				  struct open_request *req,
+				  struct request_sock *req,
 				  struct dst_entry *dst)
 {
+	struct inet_request_sock *ireq;
 	struct inet_sock *newinet;
 	struct tcp_sock *newtp;
 	struct sock *newsk;
@@ -1570,11 +1558,12 @@ struct sock *tcp_v4_syn_recv_sock(struct
 
 	newtp		      = tcp_sk(newsk);
 	newinet		      = inet_sk(newsk);
-	newinet->daddr	      = req->af.v4_req.rmt_addr;
-	newinet->rcv_saddr    = req->af.v4_req.loc_addr;
-	newinet->saddr	      = req->af.v4_req.loc_addr;
-	newinet->opt	      = req->af.v4_req.opt;
-	req->af.v4_req.opt    = NULL;
+	ireq		      = inet_rsk(req);
+	newinet->daddr	      = ireq->rmt_addr;
+	newinet->rcv_saddr    = ireq->loc_addr;
+	newinet->saddr	      = ireq->loc_addr;
+	newinet->opt	      = ireq->opt;
+	ireq->opt	      = NULL;
 	newinet->mc_index     = tcp_v4_iif(skb);
 	newinet->mc_ttl	      = skb->nh.iph->ttl;
 	newtp->ext_header_len = 0;
@@ -1605,9 +1594,9 @@ static struct sock *tcp_v4_hnd_req(struc
 	struct iphdr *iph = skb->nh.iph;
 	struct tcp_sock *tp = tcp_sk(sk);
 	struct sock *nsk;
-	struct open_request **prev;
+	struct request_sock **prev;
 	/* Find possible connection requests. */
-	struct open_request *req = tcp_v4_search_req(tp, &prev, th->source,
+	struct request_sock *req = tcp_v4_search_req(tp, &prev, th->source,
 						     iph->saddr, iph->daddr);
 	if (req)
 		return tcp_check_req(sk, skb, req, prev);
@@ -1642,8 +1631,7 @@ static int tcp_v4_checksum_init(struct s
 				  skb->nh.iph->daddr, skb->csum))
 			return 0;
 
-		NETDEBUG(if (net_ratelimit())
-				printk(KERN_DEBUG "hw tcp v4 csum failed\n"));
+		LIMIT_NETDEBUG(printk(KERN_DEBUG "hw tcp v4 csum failed\n"));
 		skb->ip_summed = CHECKSUM_NONE;
 	}
 	if (skb->len <= 76) {
@@ -2060,9 +2048,10 @@ static int tcp_v4_init_sock(struct sock 
 	 */
 	tp->snd_ssthresh = 0x7fffffff;	/* Infinity */
 	tp->snd_cwnd_clamp = ~0;
-	tp->mss_cache_std = tp->mss_cache = 536;
+	tp->mss_cache = 536;
 
 	tp->reordering = sysctl_tcp_reordering;
+	tp->ca_ops = &tcp_init_congestion_ops;
 
 	sk->sk_state = TCP_CLOSE;
 
@@ -2085,6 +2074,8 @@ int tcp_v4_destroy_sock(struct sock *sk)
 
 	tcp_clear_xmit_timers(sk);
 
+	tcp_cleanup_congestion_control(tp);
+
 	/* Cleanup up the write buffer. */
   	sk_stream_writequeue_purge(sk);
 
@@ -2144,13 +2135,13 @@ static void *listening_get_next(struct s
 	++st->num;
 
 	if (st->state == TCP_SEQ_STATE_OPENREQ) {
-		struct open_request *req = cur;
+		struct request_sock *req = cur;
 
 	       	tp = tcp_sk(st->syn_wait_sk);
 		req = req->dl_next;
 		while (1) {
 			while (req) {
-				if (req->class->family == st->family) {
+				if (req->rsk_ops->family == st->family) {
 					cur = req;
 					goto out;
 				}
@@ -2159,17 +2150,17 @@ static void *listening_get_next(struct s
 			if (++st->sbucket >= TCP_SYNQ_HSIZE)
 				break;
 get_req:
-			req = tp->listen_opt->syn_table[st->sbucket];
+			req = tp->accept_queue.listen_opt->syn_table[st->sbucket];
 		}
 		sk	  = sk_next(st->syn_wait_sk);
 		st->state = TCP_SEQ_STATE_LISTENING;
-		read_unlock_bh(&tp->syn_wait_lock);
+		read_unlock_bh(&tp->accept_queue.syn_wait_lock);
 	} else {
 	       	tp = tcp_sk(sk);
-		read_lock_bh(&tp->syn_wait_lock);
-		if (tp->listen_opt && tp->listen_opt->qlen)
+		read_lock_bh(&tp->accept_queue.syn_wait_lock);
+		if (reqsk_queue_len(&tp->accept_queue))
 			goto start_req;
-		read_unlock_bh(&tp->syn_wait_lock);
+		read_unlock_bh(&tp->accept_queue.syn_wait_lock);
 		sk = sk_next(sk);
 	}
 get_sk:
@@ -2179,8 +2170,8 @@ get_sk:
 			goto out;
 		}
 	       	tp = tcp_sk(sk);
-		read_lock_bh(&tp->syn_wait_lock);
-		if (tp->listen_opt && tp->listen_opt->qlen) {
+		read_lock_bh(&tp->accept_queue.syn_wait_lock);
+		if (reqsk_queue_len(&tp->accept_queue)) {
 start_req:
 			st->uid		= sock_i_uid(sk);
 			st->syn_wait_sk = sk;
@@ -2188,7 +2179,7 @@ start_req:
 			st->sbucket	= 0;
 			goto get_req;
 		}
-		read_unlock_bh(&tp->syn_wait_lock);
+		read_unlock_bh(&tp->accept_queue.syn_wait_lock);
 	}
 	if (++st->bucket < TCP_LHTABLE_SIZE) {
 		sk = sk_head(&tcp_listening_hash[st->bucket]);
@@ -2375,7 +2366,7 @@ static void tcp_seq_stop(struct seq_file
 	case TCP_SEQ_STATE_OPENREQ:
 		if (v) {
 			struct tcp_sock *tp = tcp_sk(st->syn_wait_sk);
-			read_unlock_bh(&tp->syn_wait_lock);
+			read_unlock_bh(&tp->accept_queue.syn_wait_lock);
 		}
 	case TCP_SEQ_STATE_LISTENING:
 		if (v != SEQ_START_TOKEN)
@@ -2451,18 +2442,19 @@ void tcp_proc_unregister(struct tcp_seq_
 	memset(afinfo->seq_fops, 0, sizeof(*afinfo->seq_fops)); 
 }
 
-static void get_openreq4(struct sock *sk, struct open_request *req,
+static void get_openreq4(struct sock *sk, struct request_sock *req,
 			 char *tmpbuf, int i, int uid)
 {
+	const struct inet_request_sock *ireq = inet_rsk(req);
 	int ttd = req->expires - jiffies;
 
 	sprintf(tmpbuf, "%4d: %08X:%04X %08X:%04X"
 		" %02X %08X:%08X %02X:%08lX %08X %5d %8d %u %d %p",
 		i,
-		req->af.v4_req.loc_addr,
+		ireq->loc_addr,
 		ntohs(inet_sk(sk)->sport),
-		req->af.v4_req.rmt_addr,
-		ntohs(req->rmt_port),
+		ireq->rmt_addr,
+		ntohs(ireq->rmt_port),
 		TCP_SYN_RECV,
 		0, 0, /* could print option size, but that is af dependent. */
 		1,    /* timers active (only the expire timer) */
@@ -2618,6 +2610,7 @@ struct proto tcp_prot = {
 	.sysctl_rmem		= sysctl_tcp_rmem,
 	.max_header		= MAX_TCP_HEADER,
 	.obj_size		= sizeof(struct tcp_sock),
+	.rsk_prot		= &tcp_request_sock_ops,
 };
 
 
@@ -2660,7 +2653,6 @@ EXPORT_SYMBOL(tcp_proc_register);
 EXPORT_SYMBOL(tcp_proc_unregister);
 #endif
 EXPORT_SYMBOL(sysctl_local_port_range);
-EXPORT_SYMBOL(sysctl_max_syn_backlog);
 EXPORT_SYMBOL(sysctl_tcp_low_latency);
 EXPORT_SYMBOL(sysctl_tcp_tw_reuse);
 
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c
--- a/net/ipv4/tcp_minisocks.c
+++ b/net/ipv4/tcp_minisocks.c
@@ -684,7 +684,7 @@ out:
  * Actually, we could lots of memory writes here. tp of listening
  * socket contains all necessary default parameters.
  */
-struct sock *tcp_create_openreq_child(struct sock *sk, struct open_request *req, struct sk_buff *skb)
+struct sock *tcp_create_openreq_child(struct sock *sk, struct request_sock *req, struct sk_buff *skb)
 {
 	/* allocate the newsk from the same slab of the master sock,
 	 * if not, at sk_free time we'll try to free it from the wrong
@@ -692,6 +692,8 @@ struct sock *tcp_create_openreq_child(st
 	struct sock *newsk = sk_alloc(PF_INET, GFP_ATOMIC, sk->sk_prot, 0);
 
 	if(newsk != NULL) {
+		struct inet_request_sock *ireq = inet_rsk(req);
+		struct tcp_request_sock *treq = tcp_rsk(req);
 		struct tcp_sock *newtp;
 		struct sk_filter *filter;
 
@@ -703,7 +705,7 @@ struct sock *tcp_create_openreq_child(st
 		tcp_sk(newsk)->bind_hash = NULL;
 
 		/* Clone the TCP header template */
-		inet_sk(newsk)->dport = req->rmt_port;
+		inet_sk(newsk)->dport = ireq->rmt_port;
 
 		sock_lock_init(newsk);
 		bh_lock_sock(newsk);
@@ -739,14 +741,14 @@ struct sock *tcp_create_openreq_child(st
 		/* Now setup tcp_sock */
 		newtp = tcp_sk(newsk);
 		newtp->pred_flags = 0;
-		newtp->rcv_nxt = req->rcv_isn + 1;
-		newtp->snd_nxt = req->snt_isn + 1;
-		newtp->snd_una = req->snt_isn + 1;
-		newtp->snd_sml = req->snt_isn + 1;
+		newtp->rcv_nxt = treq->rcv_isn + 1;
+		newtp->snd_nxt = treq->snt_isn + 1;
+		newtp->snd_una = treq->snt_isn + 1;
+		newtp->snd_sml = treq->snt_isn + 1;
 
 		tcp_prequeue_init(newtp);
 
-		tcp_init_wl(newtp, req->snt_isn, req->rcv_isn);
+		tcp_init_wl(newtp, treq->snt_isn, treq->rcv_isn);
 
 		newtp->retransmits = 0;
 		newtp->backoff = 0;
@@ -772,13 +774,15 @@ struct sock *tcp_create_openreq_child(st
 		newtp->frto_counter = 0;
 		newtp->frto_highmark = 0;
 
+		newtp->ca_ops = &tcp_reno;
+
 		tcp_set_ca_state(newtp, TCP_CA_Open);
 		tcp_init_xmit_timers(newsk);
 		skb_queue_head_init(&newtp->out_of_order_queue);
-		newtp->rcv_wup = req->rcv_isn + 1;
-		newtp->write_seq = req->snt_isn + 1;
+		newtp->rcv_wup = treq->rcv_isn + 1;
+		newtp->write_seq = treq->snt_isn + 1;
 		newtp->pushed_seq = newtp->write_seq;
-		newtp->copied_seq = req->rcv_isn + 1;
+		newtp->copied_seq = treq->rcv_isn + 1;
 
 		newtp->rx_opt.saw_tstamp = 0;
 
@@ -788,10 +792,8 @@ struct sock *tcp_create_openreq_child(st
 		newtp->probes_out = 0;
 		newtp->rx_opt.num_sacks = 0;
 		newtp->urg_data = 0;
-		newtp->listen_opt = NULL;
-		newtp->accept_queue = newtp->accept_queue_tail = NULL;
-		/* Deinitialize syn_wait_lock to trap illegal accesses. */
-		memset(&newtp->syn_wait_lock, 0, sizeof(newtp->syn_wait_lock));
+		/* Deinitialize accept_queue to trap illegal accesses. */
+		memset(&newtp->accept_queue, 0, sizeof(newtp->accept_queue));
 
 		/* Back to base struct sock members. */
 		newsk->sk_err = 0;
@@ -808,18 +810,18 @@ struct sock *tcp_create_openreq_child(st
 		newsk->sk_socket = NULL;
 		newsk->sk_sleep = NULL;
 
-		newtp->rx_opt.tstamp_ok = req->tstamp_ok;
-		if((newtp->rx_opt.sack_ok = req->sack_ok) != 0) {
+		newtp->rx_opt.tstamp_ok = ireq->tstamp_ok;
+		if((newtp->rx_opt.sack_ok = ireq->sack_ok) != 0) {
 			if (sysctl_tcp_fack)
 				newtp->rx_opt.sack_ok |= 2;
 		}
 		newtp->window_clamp = req->window_clamp;
 		newtp->rcv_ssthresh = req->rcv_wnd;
 		newtp->rcv_wnd = req->rcv_wnd;
-		newtp->rx_opt.wscale_ok = req->wscale_ok;
+		newtp->rx_opt.wscale_ok = ireq->wscale_ok;
 		if (newtp->rx_opt.wscale_ok) {
-			newtp->rx_opt.snd_wscale = req->snd_wscale;
-			newtp->rx_opt.rcv_wscale = req->rcv_wscale;
+			newtp->rx_opt.snd_wscale = ireq->snd_wscale;
+			newtp->rx_opt.rcv_wscale = ireq->rcv_wscale;
 		} else {
 			newtp->rx_opt.snd_wscale = newtp->rx_opt.rcv_wscale = 0;
 			newtp->window_clamp = min(newtp->window_clamp, 65535U);
@@ -842,8 +844,6 @@ struct sock *tcp_create_openreq_child(st
 		if (newtp->ecn_flags&TCP_ECN_OK)
 			sock_set_flag(newsk, SOCK_NO_LARGESEND);
 
-		tcp_ca_init(newtp);
-
 		TCP_INC_STATS_BH(TCP_MIB_PASSIVEOPENS);
 	}
 	return newsk;
@@ -851,12 +851,12 @@ struct sock *tcp_create_openreq_child(st
 
 /* 
  *	Process an incoming packet for SYN_RECV sockets represented
- *	as an open_request.
+ *	as a request_sock.
  */
 
 struct sock *tcp_check_req(struct sock *sk,struct sk_buff *skb,
-			   struct open_request *req,
-			   struct open_request **prev)
+			   struct request_sock *req,
+			   struct request_sock **prev)
 {
 	struct tcphdr *th = skb->h.th;
 	struct tcp_sock *tp = tcp_sk(sk);
@@ -881,7 +881,7 @@ struct sock *tcp_check_req(struct sock *
 	}
 
 	/* Check for pure retransmitted SYN. */
-	if (TCP_SKB_CB(skb)->seq == req->rcv_isn &&
+	if (TCP_SKB_CB(skb)->seq == tcp_rsk(req)->rcv_isn &&
 	    flg == TCP_FLAG_SYN &&
 	    !paws_reject) {
 		/*
@@ -901,7 +901,7 @@ struct sock *tcp_check_req(struct sock *
 		 * Enforce "SYN-ACK" according to figure 8, figure 6
 		 * of RFC793, fixed by RFC1122.
 		 */
-		req->class->rtx_syn_ack(sk, req, NULL);
+		req->rsk_ops->rtx_syn_ack(sk, req, NULL);
 		return NULL;
 	}
 
@@ -959,7 +959,7 @@ struct sock *tcp_check_req(struct sock *
 	 * Invalid ACK: reset will be sent by listening socket
 	 */
 	if ((flg & TCP_FLAG_ACK) &&
-	    (TCP_SKB_CB(skb)->ack_seq != req->snt_isn+1))
+	    (TCP_SKB_CB(skb)->ack_seq != tcp_rsk(req)->snt_isn + 1))
 		return sk;
 
 	/* Also, it would be not so bad idea to check rcv_tsecr, which
@@ -970,10 +970,10 @@ struct sock *tcp_check_req(struct sock *
 	/* RFC793: "first check sequence number". */
 
 	if (paws_reject || !tcp_in_window(TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb)->end_seq,
-					  req->rcv_isn+1, req->rcv_isn+1+req->rcv_wnd)) {
+					  tcp_rsk(req)->rcv_isn + 1, tcp_rsk(req)->rcv_isn + 1 + req->rcv_wnd)) {
 		/* Out of window: send ACK and drop. */
 		if (!(flg & TCP_FLAG_RST))
-			req->class->send_ack(skb, req);
+			req->rsk_ops->send_ack(skb, req);
 		if (paws_reject)
 			NET_INC_STATS_BH(LINUX_MIB_PAWSESTABREJECTED);
 		return NULL;
@@ -981,12 +981,12 @@ struct sock *tcp_check_req(struct sock *
 
 	/* In sequence, PAWS is OK. */
 
-	if (tmp_opt.saw_tstamp && !after(TCP_SKB_CB(skb)->seq, req->rcv_isn+1))
+	if (tmp_opt.saw_tstamp && !after(TCP_SKB_CB(skb)->seq, tcp_rsk(req)->rcv_isn + 1))
 			req->ts_recent = tmp_opt.rcv_tsval;
 
-		if (TCP_SKB_CB(skb)->seq == req->rcv_isn) {
+		if (TCP_SKB_CB(skb)->seq == tcp_rsk(req)->rcv_isn) {
 			/* Truncate SYN, it is out of window starting
-			   at req->rcv_isn+1. */
+			   at tcp_rsk(req)->rcv_isn + 1. */
 			flg &= ~TCP_FLAG_SYN;
 		}
 
@@ -1003,8 +1003,8 @@ struct sock *tcp_check_req(struct sock *
 			return NULL;
 
 		/* If TCP_DEFER_ACCEPT is set, drop bare ACK. */
-		if (tp->defer_accept && TCP_SKB_CB(skb)->end_seq == req->rcv_isn+1) {
-			req->acked = 1;
+		if (tp->defer_accept && TCP_SKB_CB(skb)->end_seq == tcp_rsk(req)->rcv_isn + 1) {
+			inet_rsk(req)->acked = 1;
 			return NULL;
 		}
 
@@ -1026,14 +1026,14 @@ struct sock *tcp_check_req(struct sock *
 
 	listen_overflow:
 		if (!sysctl_tcp_abort_on_overflow) {
-			req->acked = 1;
+			inet_rsk(req)->acked = 1;
 			return NULL;
 		}
 
 	embryonic_reset:
 		NET_INC_STATS_BH(LINUX_MIB_EMBRYONICRSTS);
 		if (!(flg & TCP_FLAG_RST))
-			req->class->send_reset(skb);
+			req->rsk_ops->send_reset(skb);
 
 		tcp_synq_drop(sk, req, prev);
 		return NULL;
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -49,7 +49,7 @@ int sysctl_tcp_retrans_collapse = 1;
  * will allow a single TSO frame to consume.  Building TSO frames
  * which are too large can cause TCP streams to be bursty.
  */
-int sysctl_tcp_tso_win_divisor = 8;
+int sysctl_tcp_tso_win_divisor = 3;
 
 static inline void update_send_head(struct sock *sk, struct tcp_sock *tp,
 				    struct sk_buff *skb)
@@ -111,8 +111,7 @@ static void tcp_cwnd_restart(struct tcp_
 	u32 restart_cwnd = tcp_init_cwnd(tp, dst);
 	u32 cwnd = tp->snd_cwnd;
 
-	if (tcp_is_vegas(tp)) 
-		tcp_vegas_enable(tp);
+	tcp_ca_event(tp, CA_EVENT_CWND_RESTART);
 
 	tp->snd_ssthresh = tcp_current_ssthresh(tp);
 	restart_cwnd = min(restart_cwnd, cwnd);
@@ -141,11 +140,11 @@ static inline void tcp_event_data_sent(s
 		tp->ack.pingpong = 1;
 }
 
-static __inline__ void tcp_event_ack_sent(struct sock *sk)
+static __inline__ void tcp_event_ack_sent(struct sock *sk, unsigned int pkts)
 {
 	struct tcp_sock *tp = tcp_sk(sk);
 
-	tcp_dec_quickack_mode(tp);
+	tcp_dec_quickack_mode(tp, pkts);
 	tcp_clear_xmit_timer(sk, TCP_TIME_DACK);
 }
 
@@ -280,6 +279,10 @@ static int tcp_transmit_skb(struct sock 
 #define SYSCTL_FLAG_WSCALE	0x2
 #define SYSCTL_FLAG_SACK	0x4
 
+		/* If congestion control is doing timestamping */
+		if (tp->ca_ops->rtt_sample)
+			do_gettimeofday(&skb->stamp);
+
 		sysctl_flags = 0;
 		if (tcb->flags & TCPCB_FLAG_SYN) {
 			tcp_header_size = sizeof(struct tcphdr) + TCPOLEN_MSS;
@@ -304,17 +307,8 @@ static int tcp_transmit_skb(struct sock 
 					    (tp->rx_opt.eff_sacks * TCPOLEN_SACK_PERBLOCK));
 		}
 		
-		/*
-		 * If the connection is idle and we are restarting,
-		 * then we don't want to do any Vegas calculations
-		 * until we get fresh RTT samples.  So when we
-		 * restart, we reset our Vegas state to a clean
-		 * slate. After we get acks for this flight of
-		 * packets, _then_ we can make Vegas calculations
-		 * again.
-		 */
-		if (tcp_is_vegas(tp) && tcp_packets_in_flight(tp) == 0)
-			tcp_vegas_enable(tp);
+		if (tcp_packets_in_flight(tp) == 0)
+			tcp_ca_event(tp, CA_EVENT_TX_START);
 
 		th = (struct tcphdr *) skb_push(skb, tcp_header_size);
 		skb->h.th = th;
@@ -361,7 +355,7 @@ static int tcp_transmit_skb(struct sock 
 		tp->af_specific->send_check(sk, th, skb->len, skb);
 
 		if (tcb->flags & TCPCB_FLAG_ACK)
-			tcp_event_ack_sent(sk);
+			tcp_event_ack_sent(sk, tcp_skb_pcount(skb));
 
 		if (skb->len != tcp_header_size)
 			tcp_event_data_sent(tp, skb, sk);
@@ -409,42 +403,9 @@ static void tcp_queue_skb(struct sock *s
 		sk->sk_send_head = skb;
 }
 
-static inline void tcp_tso_set_push(struct sk_buff *skb)
-{
-	/* Force push to be on for any TSO frames to workaround
-	 * problems with busted implementations like Mac OS-X that
-	 * hold off socket receive wakeups until push is seen.
-	 */
-	if (tcp_skb_pcount(skb) > 1)
-		TCP_SKB_CB(skb)->flags |= TCPCB_FLAG_PSH;
-}
-
-/* Send _single_ skb sitting at the send head. This function requires
- * true push pending frames to setup probe timer etc.
- */
-void tcp_push_one(struct sock *sk, unsigned cur_mss)
-{
-	struct tcp_sock *tp = tcp_sk(sk);
-	struct sk_buff *skb = sk->sk_send_head;
-
-	if (tcp_snd_test(sk, skb, cur_mss, TCP_NAGLE_PUSH)) {
-		/* Send it out now. */
-		TCP_SKB_CB(skb)->when = tcp_time_stamp;
-		tcp_tso_set_push(skb);
-		if (!tcp_transmit_skb(sk, skb_clone(skb, sk->sk_allocation))) {
-			sk->sk_send_head = NULL;
-			tp->snd_nxt = TCP_SKB_CB(skb)->end_seq;
-			tcp_packets_out_inc(sk, tp, skb);
-			return;
-		}
-	}
-}
-
-void tcp_set_skb_tso_segs(struct sock *sk, struct sk_buff *skb)
+static void tcp_set_skb_tso_segs(struct sock *sk, struct sk_buff *skb, unsigned int mss_now)
 {
-	struct tcp_sock *tp = tcp_sk(sk);
-
-	if (skb->len <= tp->mss_cache_std ||
+	if (skb->len <= mss_now ||
 	    !(sk->sk_route_caps & NETIF_F_TSO)) {
 		/* Avoid the costly divide in the normal
 		 * non-TSO case.
@@ -454,10 +415,10 @@ void tcp_set_skb_tso_segs(struct sock *s
 	} else {
 		unsigned int factor;
 
-		factor = skb->len + (tp->mss_cache_std - 1);
-		factor /= tp->mss_cache_std;
+		factor = skb->len + (mss_now - 1);
+		factor /= mss_now;
 		skb_shinfo(skb)->tso_segs = factor;
-		skb_shinfo(skb)->tso_size = tp->mss_cache_std;
+		skb_shinfo(skb)->tso_size = mss_now;
 	}
 }
 
@@ -466,7 +427,7 @@ void tcp_set_skb_tso_segs(struct sock *s
  * packet to the list.  This won't be called frequently, I hope. 
  * Remember, these are still headerless SKBs at this point.
  */
-static int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len)
+static int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len, unsigned int mss_now)
 {
 	struct tcp_sock *tp = tcp_sk(sk);
 	struct sk_buff *buff;
@@ -521,6 +482,7 @@ static int tcp_fragment(struct sock *sk,
 	 * skbs, which it never sent before. --ANK
 	 */
 	TCP_SKB_CB(buff)->when = TCP_SKB_CB(skb)->when;
+	buff->stamp = skb->stamp;
 
 	if (TCP_SKB_CB(skb)->sacked & TCPCB_LOST) {
 		tp->lost_out -= tcp_skb_pcount(skb);
@@ -528,8 +490,8 @@ static int tcp_fragment(struct sock *sk,
 	}
 
 	/* Fix up tso_factor for both original and new SKB.  */
-	tcp_set_skb_tso_segs(sk, skb);
-	tcp_set_skb_tso_segs(sk, buff);
+	tcp_set_skb_tso_segs(sk, skb, mss_now);
+	tcp_set_skb_tso_segs(sk, buff, mss_now);
 
 	if (TCP_SKB_CB(skb)->sacked & TCPCB_LOST) {
 		tp->lost_out += tcp_skb_pcount(skb);
@@ -542,6 +504,7 @@ static int tcp_fragment(struct sock *sk,
 	}
 
 	/* Link BUFF into the send queue. */
+	skb_header_release(buff);
 	__skb_append(skb, buff);
 
 	return 0;
@@ -604,7 +567,7 @@ int tcp_trim_head(struct sock *sk, struc
 	 * factor and mss.
 	 */
 	if (tcp_skb_pcount(skb) > 1)
-		tcp_set_skb_tso_segs(sk, skb);
+		tcp_set_skb_tso_segs(sk, skb, tcp_current_mss(sk, 1));
 
 	return 0;
 }
@@ -662,7 +625,7 @@ unsigned int tcp_sync_mss(struct sock *s
 
 	/* And store cached results */
 	tp->pmtu_cookie = pmtu;
-	tp->mss_cache = tp->mss_cache_std = mss_now;
+	tp->mss_cache = mss_now;
 
 	return mss_now;
 }
@@ -674,59 +637,317 @@ unsigned int tcp_sync_mss(struct sock *s
  * cannot be large. However, taking into account rare use of URG, this
  * is not a big flaw.
  */
-
-unsigned int tcp_current_mss(struct sock *sk, int large)
+unsigned int tcp_current_mss(struct sock *sk, int large_allowed)
 {
 	struct tcp_sock *tp = tcp_sk(sk);
 	struct dst_entry *dst = __sk_dst_get(sk);
-	unsigned int do_large, mss_now;
+	u32 mss_now;
+	u16 xmit_size_goal;
+	int doing_tso = 0;
+
+	mss_now = tp->mss_cache;
+
+	if (large_allowed &&
+	    (sk->sk_route_caps & NETIF_F_TSO) &&
+	    !tp->urg_mode)
+		doing_tso = 1;
 
-	mss_now = tp->mss_cache_std;
 	if (dst) {
 		u32 mtu = dst_mtu(dst);
 		if (mtu != tp->pmtu_cookie)
 			mss_now = tcp_sync_mss(sk, mtu);
 	}
 
-	do_large = (large &&
-		    (sk->sk_route_caps & NETIF_F_TSO) &&
-		    !tp->urg_mode);
+	if (tp->rx_opt.eff_sacks)
+		mss_now -= (TCPOLEN_SACK_BASE_ALIGNED +
+			    (tp->rx_opt.eff_sacks * TCPOLEN_SACK_PERBLOCK));
 
-	if (do_large) {
-		unsigned int large_mss, factor, limit;
+	xmit_size_goal = mss_now;
 
-		large_mss = 65535 - tp->af_specific->net_header_len -
+	if (doing_tso) {
+		xmit_size_goal = 65535 -
+			tp->af_specific->net_header_len -
 			tp->ext_header_len - tp->tcp_header_len;
 
-		if (tp->max_window && large_mss > (tp->max_window>>1))
-			large_mss = max((tp->max_window>>1),
-					68U - tp->tcp_header_len);
-
-		factor = large_mss / mss_now;
-
-		/* Always keep large mss multiple of real mss, but
-		 * do not exceed 1/tso_win_divisor of the congestion window
-		 * so we can keep the ACK clock ticking and minimize
-		 * bursting.
-		 */
-		limit = tp->snd_cwnd;
-		if (sysctl_tcp_tso_win_divisor)
-			limit /= sysctl_tcp_tso_win_divisor;
-		limit = max(1U, limit);
-		if (factor > limit)
-			factor = limit;
-
-		tp->mss_cache = mss_now * factor;
+		if (tp->max_window &&
+		    (xmit_size_goal > (tp->max_window >> 1)))
+			xmit_size_goal = max((tp->max_window >> 1),
+					     68U - tp->tcp_header_len);
 
-		mss_now = tp->mss_cache;
+		xmit_size_goal -= (xmit_size_goal % mss_now);
 	}
+	tp->xmit_size_goal = xmit_size_goal;
 
-	if (tp->rx_opt.eff_sacks)
-		mss_now -= (TCPOLEN_SACK_BASE_ALIGNED +
-			    (tp->rx_opt.eff_sacks * TCPOLEN_SACK_PERBLOCK));
 	return mss_now;
 }
 
+/* Congestion window validation. (RFC2861) */
+
+static inline void tcp_cwnd_validate(struct sock *sk, struct tcp_sock *tp)
+{
+	__u32 packets_out = tp->packets_out;
+
+	if (packets_out >= tp->snd_cwnd) {
+		/* Network is feed fully. */
+		tp->snd_cwnd_used = 0;
+		tp->snd_cwnd_stamp = tcp_time_stamp;
+	} else {
+		/* Network starves. */
+		if (tp->packets_out > tp->snd_cwnd_used)
+			tp->snd_cwnd_used = tp->packets_out;
+
+		if ((s32)(tcp_time_stamp - tp->snd_cwnd_stamp) >= tp->rto)
+			tcp_cwnd_application_limited(sk);
+	}
+}
+
+static unsigned int tcp_window_allows(struct tcp_sock *tp, struct sk_buff *skb, unsigned int mss_now, unsigned int cwnd)
+{
+	u32 window, cwnd_len;
+
+	window = (tp->snd_una + tp->snd_wnd - TCP_SKB_CB(skb)->seq);
+	cwnd_len = mss_now * cwnd;
+	return min(window, cwnd_len);
+}
+
+/* Can at least one segment of SKB be sent right now, according to the
+ * congestion window rules?  If so, return how many segments are allowed.
+ */
+static inline unsigned int tcp_cwnd_test(struct tcp_sock *tp, struct sk_buff *skb)
+{
+	u32 in_flight, cwnd;
+
+	/* Don't be strict about the congestion window for the final FIN.  */
+	if (TCP_SKB_CB(skb)->flags & TCPCB_FLAG_FIN)
+		return 1;
+
+	in_flight = tcp_packets_in_flight(tp);
+	cwnd = tp->snd_cwnd;
+	if (in_flight < cwnd)
+		return (cwnd - in_flight);
+
+	return 0;
+}
+
+/* This must be invoked the first time we consider transmitting
+ * SKB onto the wire.
+ */
+static inline int tcp_init_tso_segs(struct sock *sk, struct sk_buff *skb, unsigned int mss_now)
+{
+	int tso_segs = tcp_skb_pcount(skb);
+
+	if (!tso_segs ||
+	    (tso_segs > 1 &&
+	     skb_shinfo(skb)->tso_size != mss_now)) {
+		tcp_set_skb_tso_segs(sk, skb, mss_now);
+		tso_segs = tcp_skb_pcount(skb);
+	}
+	return tso_segs;
+}
+
+static inline int tcp_minshall_check(const struct tcp_sock *tp)
+{
+	return after(tp->snd_sml,tp->snd_una) &&
+		!after(tp->snd_sml, tp->snd_nxt);
+}
+
+/* Return 0, if packet can be sent now without violation Nagle's rules:
+ * 1. It is full sized.
+ * 2. Or it contains FIN. (already checked by caller)
+ * 3. Or TCP_NODELAY was set.
+ * 4. Or TCP_CORK is not set, and all sent packets are ACKed.
+ *    With Minshall's modification: all sent small packets are ACKed.
+ */
+
+static inline int tcp_nagle_check(const struct tcp_sock *tp,
+				  const struct sk_buff *skb, 
+				  unsigned mss_now, int nonagle)
+{
+	return (skb->len < mss_now &&
+		((nonagle&TCP_NAGLE_CORK) ||
+		 (!nonagle &&
+		  tp->packets_out &&
+		  tcp_minshall_check(tp))));
+}
+
+/* Return non-zero if the Nagle test allows this packet to be
+ * sent now.
+ */
+static inline int tcp_nagle_test(struct tcp_sock *tp, struct sk_buff *skb,
+				 unsigned int cur_mss, int nonagle)
+{
+	/* Nagle rule does not apply to frames, which sit in the middle of the
+	 * write_queue (they have no chances to get new data).
+	 *
+	 * This is implemented in the callers, where they modify the 'nonagle'
+	 * argument based upon the location of SKB in the send queue.
+	 */
+	if (nonagle & TCP_NAGLE_PUSH)
+		return 1;
+
+	/* Don't use the nagle rule for urgent data (or for the final FIN).  */
+	if (tp->urg_mode ||
+	    (TCP_SKB_CB(skb)->flags & TCPCB_FLAG_FIN))
+		return 1;
+
+	if (!tcp_nagle_check(tp, skb, cur_mss, nonagle))
+		return 1;
+
+	return 0;
+}
+
+/* Does at least the first segment of SKB fit into the send window? */
+static inline int tcp_snd_wnd_test(struct tcp_sock *tp, struct sk_buff *skb, unsigned int cur_mss)
+{
+	u32 end_seq = TCP_SKB_CB(skb)->end_seq;
+
+	if (skb->len > cur_mss)
+		end_seq = TCP_SKB_CB(skb)->seq + cur_mss;
+
+	return !after(end_seq, tp->snd_una + tp->snd_wnd);
+}
+
+/* This checks if the data bearing packet SKB (usually sk->sk_send_head)
+ * should be put on the wire right now.  If so, it returns the number of
+ * packets allowed by the congestion window.
+ */
+static unsigned int tcp_snd_test(struct sock *sk, struct sk_buff *skb,
+				 unsigned int cur_mss, int nonagle)
+{
+	struct tcp_sock *tp = tcp_sk(sk);
+	unsigned int cwnd_quota;
+
+	tcp_init_tso_segs(sk, skb, cur_mss);
+
+	if (!tcp_nagle_test(tp, skb, cur_mss, nonagle))
+		return 0;
+
+	cwnd_quota = tcp_cwnd_test(tp, skb);
+	if (cwnd_quota &&
+	    !tcp_snd_wnd_test(tp, skb, cur_mss))
+		cwnd_quota = 0;
+
+	return cwnd_quota;
+}
+
+static inline int tcp_skb_is_last(const struct sock *sk, 
+				  const struct sk_buff *skb)
+{
+	return skb->next == (struct sk_buff *)&sk->sk_write_queue;
+}
+
+int tcp_may_send_now(struct sock *sk, struct tcp_sock *tp)
+{
+	struct sk_buff *skb = sk->sk_send_head;
+
+	return (skb &&
+		tcp_snd_test(sk, skb, tcp_current_mss(sk, 1),
+			     (tcp_skb_is_last(sk, skb) ?
+			      TCP_NAGLE_PUSH :
+			      tp->nonagle)));
+}
+
+/* Trim TSO SKB to LEN bytes, put the remaining data into a new packet
+ * which is put after SKB on the list.  It is very much like
+ * tcp_fragment() except that it may make several kinds of assumptions
+ * in order to speed up the splitting operation.  In particular, we
+ * know that all the data is in scatter-gather pages, and that the
+ * packet has never been sent out before (and thus is not cloned).
+ */
+static int tso_fragment(struct sock *sk, struct sk_buff *skb, unsigned int len, unsigned int mss_now)
+{
+	struct sk_buff *buff;
+	int nlen = skb->len - len;
+	u16 flags;
+
+	/* All of a TSO frame must be composed of paged data.  */
+	if (skb->len != skb->data_len)
+		return tcp_fragment(sk, skb, len, mss_now);
+
+	buff = sk_stream_alloc_pskb(sk, 0, 0, GFP_ATOMIC);
+	if (unlikely(buff == NULL))
+		return -ENOMEM;
+
+	buff->truesize = nlen;
+	skb->truesize -= nlen;
+
+	/* Correct the sequence numbers. */
+	TCP_SKB_CB(buff)->seq = TCP_SKB_CB(skb)->seq + len;
+	TCP_SKB_CB(buff)->end_seq = TCP_SKB_CB(skb)->end_seq;
+	TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(buff)->seq;
+
+	/* PSH and FIN should only be set in the second packet. */
+	flags = TCP_SKB_CB(skb)->flags;
+	TCP_SKB_CB(skb)->flags = flags & ~(TCPCB_FLAG_FIN|TCPCB_FLAG_PSH);
+	TCP_SKB_CB(buff)->flags = flags;
+
+	/* This packet was never sent out yet, so no SACK bits. */
+	TCP_SKB_CB(buff)->sacked = 0;
+
+	buff->ip_summed = skb->ip_summed = CHECKSUM_HW;
+	skb_split(skb, buff, len);
+
+	/* Fix up tso_factor for both original and new SKB.  */
+	tcp_set_skb_tso_segs(sk, skb, mss_now);
+	tcp_set_skb_tso_segs(sk, buff, mss_now);
+
+	/* Link BUFF into the send queue. */
+	skb_header_release(buff);
+	__skb_append(skb, buff);
+
+	return 0;
+}
+
+/* Try to defer sending, if possible, in order to minimize the amount
+ * of TSO splitting we do.  View it as a kind of TSO Nagle test.
+ *
+ * This algorithm is from John Heffner.
+ */
+static int tcp_tso_should_defer(struct sock *sk, struct tcp_sock *tp, struct sk_buff *skb)
+{
+	u32 send_win, cong_win, limit, in_flight;
+
+	if (TCP_SKB_CB(skb)->flags & TCPCB_FLAG_FIN)
+		return 0;
+
+	if (tp->ca_state != TCP_CA_Open)
+		return 0;
+
+	in_flight = tcp_packets_in_flight(tp);
+
+	BUG_ON(tcp_skb_pcount(skb) <= 1 ||
+	       (tp->snd_cwnd <= in_flight));
+
+	send_win = (tp->snd_una + tp->snd_wnd) - TCP_SKB_CB(skb)->seq;
+
+	/* From in_flight test above, we know that cwnd > in_flight.  */
+	cong_win = (tp->snd_cwnd - in_flight) * tp->mss_cache;
+
+	limit = min(send_win, cong_win);
+
+	if (sysctl_tcp_tso_win_divisor) {
+		u32 chunk = min(tp->snd_wnd, tp->snd_cwnd * tp->mss_cache);
+
+		/* If at least some fraction of a window is available,
+		 * just use it.
+		 */
+		chunk /= sysctl_tcp_tso_win_divisor;
+		if (limit >= chunk)
+			return 0;
+	} else {
+		/* Different approach, try not to defer past a single
+		 * ACK.  Receiver should ACK every other full sized
+		 * frame, so if we have space for more than 3 frames
+		 * then send now.
+		 */
+		if (limit > tcp_max_burst(tp) * tp->mss_cache)
+			return 0;
+	}
+
+	/* Ok, it looks like it is advisable to defer.  */
+	return 1;
+}
+
 /* This routine writes packets to the network.  It advances the
  * send_head.  This happens as incoming acks open up the remote
  * window for us.
@@ -734,57 +955,142 @@ unsigned int tcp_current_mss(struct sock
  * Returns 1, if no segments are in flight and we have queued segments, but
  * cannot send anything now because of SWS or another problem.
  */
-int tcp_write_xmit(struct sock *sk, int nonagle)
+static int tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle)
 {
 	struct tcp_sock *tp = tcp_sk(sk);
-	unsigned int mss_now;
+	struct sk_buff *skb;
+	unsigned int tso_segs, sent_pkts;
+	int cwnd_quota;
 
 	/* If we are closed, the bytes will have to remain here.
 	 * In time closedown will finish, we empty the write queue and all
 	 * will be happy.
 	 */
-	if (sk->sk_state != TCP_CLOSE) {
-		struct sk_buff *skb;
-		int sent_pkts = 0;
+	if (unlikely(sk->sk_state == TCP_CLOSE))
+		return 0;
 
-		/* Account for SACKS, we may need to fragment due to this.
-		 * It is just like the real MSS changing on us midstream.
-		 * We also handle things correctly when the user adds some
-		 * IP options mid-stream.  Silly to do, but cover it.
-		 */
-		mss_now = tcp_current_mss(sk, 1);
+	sent_pkts = 0;
+	while ((skb = sk->sk_send_head)) {
+		unsigned int limit;
 
-		while ((skb = sk->sk_send_head) &&
-		       tcp_snd_test(sk, skb, mss_now,
-			       	    tcp_skb_is_last(sk, skb) ? nonagle :
-				    			       TCP_NAGLE_PUSH)) {
-			if (skb->len > mss_now) {
-				if (tcp_fragment(sk, skb, mss_now))
-					break;
-			}
+		tso_segs = tcp_init_tso_segs(sk, skb, mss_now);
+		BUG_ON(!tso_segs);
 
-			TCP_SKB_CB(skb)->when = tcp_time_stamp;
-			tcp_tso_set_push(skb);
-			if (tcp_transmit_skb(sk, skb_clone(skb, GFP_ATOMIC)))
+		cwnd_quota = tcp_cwnd_test(tp, skb);
+		if (!cwnd_quota)
+			break;
+
+		if (unlikely(!tcp_snd_wnd_test(tp, skb, mss_now)))
+			break;
+
+		if (tso_segs == 1) {
+			if (unlikely(!tcp_nagle_test(tp, skb, mss_now,
+						     (tcp_skb_is_last(sk, skb) ?
+						      nonagle : TCP_NAGLE_PUSH))))
 				break;
+		} else {
+			if (tcp_tso_should_defer(sk, tp, skb))
+				break;
+		}
 
-			/* Advance the send_head.  This one is sent out.
-			 * This call will increment packets_out.
-			 */
-			update_send_head(sk, tp, skb);
+		limit = mss_now;
+		if (tso_segs > 1) {
+			limit = tcp_window_allows(tp, skb,
+						  mss_now, cwnd_quota);
+
+			if (skb->len < limit) {
+				unsigned int trim = skb->len % mss_now;
 
-			tcp_minshall_update(tp, mss_now, skb);
-			sent_pkts = 1;
+				if (trim)
+					limit = skb->len - trim;
+			}
 		}
 
-		if (sent_pkts) {
-			tcp_cwnd_validate(sk, tp);
-			return 0;
+		if (skb->len > limit &&
+		    unlikely(tso_fragment(sk, skb, limit, mss_now)))
+			break;
+
+		TCP_SKB_CB(skb)->when = tcp_time_stamp;
+
+		if (unlikely(tcp_transmit_skb(sk, skb_clone(skb, GFP_ATOMIC))))
+			break;
+
+		/* Advance the send_head.  This one is sent out.
+		 * This call will increment packets_out.
+		 */
+		update_send_head(sk, tp, skb);
+
+		tcp_minshall_update(tp, mss_now, skb);
+		sent_pkts++;
+	}
+
+	if (likely(sent_pkts)) {
+		tcp_cwnd_validate(sk, tp);
+		return 0;
+	}
+	return !tp->packets_out && sk->sk_send_head;
+}
+
+/* Push out any pending frames which were held back due to
+ * TCP_CORK or attempt at coalescing tiny packets.
+ * The socket must be locked by the caller.
+ */
+void __tcp_push_pending_frames(struct sock *sk, struct tcp_sock *tp,
+			       unsigned int cur_mss, int nonagle)
+{
+	struct sk_buff *skb = sk->sk_send_head;
+
+	if (skb) {
+		if (tcp_write_xmit(sk, cur_mss, nonagle))
+			tcp_check_probe_timer(sk, tp);
+	}
+}
+
+/* Send _single_ skb sitting at the send head. This function requires
+ * true push pending frames to setup probe timer etc.
+ */
+void tcp_push_one(struct sock *sk, unsigned int mss_now)
+{
+	struct tcp_sock *tp = tcp_sk(sk);
+	struct sk_buff *skb = sk->sk_send_head;
+	unsigned int tso_segs, cwnd_quota;
+
+	BUG_ON(!skb || skb->len < mss_now);
+
+	tso_segs = tcp_init_tso_segs(sk, skb, mss_now);
+	cwnd_quota = tcp_snd_test(sk, skb, mss_now, TCP_NAGLE_PUSH);
+
+	if (likely(cwnd_quota)) {
+		unsigned int limit;
+
+		BUG_ON(!tso_segs);
+
+		limit = mss_now;
+		if (tso_segs > 1) {
+			limit = tcp_window_allows(tp, skb,
+						  mss_now, cwnd_quota);
+
+			if (skb->len < limit) {
+				unsigned int trim = skb->len % mss_now;
+
+				if (trim)
+					limit = skb->len - trim;
+			}
 		}
 
-		return !tp->packets_out && sk->sk_send_head;
+		if (skb->len > limit &&
+		    unlikely(tso_fragment(sk, skb, limit, mss_now)))
+			return;
+
+		/* Send it out now. */
+		TCP_SKB_CB(skb)->when = tcp_time_stamp;
+
+		if (likely(!tcp_transmit_skb(sk, skb_clone(skb, sk->sk_allocation)))) {
+			update_send_head(sk, tp, skb);
+			tcp_cwnd_validate(sk, tp);
+			return;
+		}
 	}
-	return 0;
 }
 
 /* This function returns the amount that we can raise the
@@ -1044,7 +1350,6 @@ int tcp_retransmit_skb(struct sock *sk, 
 		if (sk->sk_route_caps & NETIF_F_TSO) {
 			sk->sk_route_caps &= ~NETIF_F_TSO;
 			sock_set_flag(sk, SOCK_NO_LARGESEND);
-			tp->mss_cache = tp->mss_cache_std;
 		}
 
 		if (tcp_trim_head(sk, skb, tp->snd_una - TCP_SKB_CB(skb)->seq))
@@ -1062,15 +1367,21 @@ int tcp_retransmit_skb(struct sock *sk, 
 
 	if (skb->len > cur_mss) {
 		int old_factor = tcp_skb_pcount(skb);
-		int new_factor;
+		int diff;
 
-		if (tcp_fragment(sk, skb, cur_mss))
+		if (tcp_fragment(sk, skb, cur_mss, cur_mss))
 			return -ENOMEM; /* We'll try again later. */
 
 		/* New SKB created, account for it. */
-		new_factor = tcp_skb_pcount(skb);
-		tp->packets_out -= old_factor - new_factor;
-		tp->packets_out += tcp_skb_pcount(skb->next);
+		diff = old_factor - tcp_skb_pcount(skb) -
+		       tcp_skb_pcount(skb->next);
+		tp->packets_out -= diff;
+
+		if (diff > 0) {
+			tp->fackets_out -= diff;
+			if ((int)tp->fackets_out < 0)
+				tp->fackets_out = 0;
+		}
 	}
 
 	/* Collapse two adjacent packets if worthwhile and we can. */
@@ -1106,7 +1417,6 @@ int tcp_retransmit_skb(struct sock *sk, 
 	 * is still in somebody's hands, else make a clone.
 	 */
 	TCP_SKB_CB(skb)->when = tcp_time_stamp;
-	tcp_tso_set_push(skb);
 
 	err = tcp_transmit_skb(sk, (skb_cloned(skb) ?
 				    pskb_copy(skb, GFP_ATOMIC):
@@ -1290,7 +1600,7 @@ void tcp_send_fin(struct sock *sk)
  * was unread data in the receive queue.  This behavior is recommended
  * by draft-ietf-tcpimpl-prob-03.txt section 3.10.  -DaveM
  */
-void tcp_send_active_reset(struct sock *sk, int priority)
+void tcp_send_active_reset(struct sock *sk, unsigned int __nocast priority)
 {
 	struct tcp_sock *tp = tcp_sk(sk);
 	struct sk_buff *skb;
@@ -1356,8 +1666,9 @@ int tcp_send_synack(struct sock *sk)
  * Prepare a SYN-ACK.
  */
 struct sk_buff * tcp_make_synack(struct sock *sk, struct dst_entry *dst,
-				 struct open_request *req)
+				 struct request_sock *req)
 {
+	struct inet_request_sock *ireq = inet_rsk(req);
 	struct tcp_sock *tp = tcp_sk(sk);
 	struct tcphdr *th;
 	int tcp_header_size;
@@ -1373,47 +1684,47 @@ struct sk_buff * tcp_make_synack(struct 
 	skb->dst = dst_clone(dst);
 
 	tcp_header_size = (sizeof(struct tcphdr) + TCPOLEN_MSS +
-			   (req->tstamp_ok ? TCPOLEN_TSTAMP_ALIGNED : 0) +
-			   (req->wscale_ok ? TCPOLEN_WSCALE_ALIGNED : 0) +
+			   (ireq->tstamp_ok ? TCPOLEN_TSTAMP_ALIGNED : 0) +
+			   (ireq->wscale_ok ? TCPOLEN_WSCALE_ALIGNED : 0) +
 			   /* SACK_PERM is in the place of NOP NOP of TS */
-			   ((req->sack_ok && !req->tstamp_ok) ? TCPOLEN_SACKPERM_ALIGNED : 0));
+			   ((ireq->sack_ok && !ireq->tstamp_ok) ? TCPOLEN_SACKPERM_ALIGNED : 0));
 	skb->h.th = th = (struct tcphdr *) skb_push(skb, tcp_header_size);
 
 	memset(th, 0, sizeof(struct tcphdr));
 	th->syn = 1;
 	th->ack = 1;
 	if (dst->dev->features&NETIF_F_TSO)
-		req->ecn_ok = 0;
+		ireq->ecn_ok = 0;
 	TCP_ECN_make_synack(req, th);
 	th->source = inet_sk(sk)->sport;
-	th->dest = req->rmt_port;
-	TCP_SKB_CB(skb)->seq = req->snt_isn;
+	th->dest = ireq->rmt_port;
+	TCP_SKB_CB(skb)->seq = tcp_rsk(req)->snt_isn;
 	TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(skb)->seq + 1;
 	TCP_SKB_CB(skb)->sacked = 0;
 	skb_shinfo(skb)->tso_segs = 1;
 	skb_shinfo(skb)->tso_size = 0;
 	th->seq = htonl(TCP_SKB_CB(skb)->seq);
-	th->ack_seq = htonl(req->rcv_isn + 1);
+	th->ack_seq = htonl(tcp_rsk(req)->rcv_isn + 1);
 	if (req->rcv_wnd == 0) { /* ignored for retransmitted syns */
 		__u8 rcv_wscale; 
 		/* Set this up on the first call only */
 		req->window_clamp = tp->window_clamp ? : dst_metric(dst, RTAX_WINDOW);
 		/* tcp_full_space because it is guaranteed to be the first packet */
 		tcp_select_initial_window(tcp_full_space(sk), 
-			dst_metric(dst, RTAX_ADVMSS) - (req->tstamp_ok ? TCPOLEN_TSTAMP_ALIGNED : 0),
+			dst_metric(dst, RTAX_ADVMSS) - (ireq->tstamp_ok ? TCPOLEN_TSTAMP_ALIGNED : 0),
 			&req->rcv_wnd,
 			&req->window_clamp,
-			req->wscale_ok,
+			ireq->wscale_ok,
 			&rcv_wscale);
-		req->rcv_wscale = rcv_wscale; 
+		ireq->rcv_wscale = rcv_wscale; 
 	}
 
 	/* RFC1323: The window in SYN & SYN/ACK segments is never scaled. */
 	th->window = htons(req->rcv_wnd);
 
 	TCP_SKB_CB(skb)->when = tcp_time_stamp;
-	tcp_syn_build_options((__u32 *)(th + 1), dst_metric(dst, RTAX_ADVMSS), req->tstamp_ok,
-			      req->sack_ok, req->wscale_ok, req->rcv_wscale,
+	tcp_syn_build_options((__u32 *)(th + 1), dst_metric(dst, RTAX_ADVMSS), ireq->tstamp_ok,
+			      ireq->sack_ok, ireq->wscale_ok, ireq->rcv_wscale,
 			      TCP_SKB_CB(skb)->when,
 			      req->ts_recent);
 
@@ -1448,7 +1759,6 @@ static inline void tcp_connect_init(stru
 		tp->window_clamp = dst_metric(dst, RTAX_WINDOW);
 	tp->advmss = dst_metric(dst, RTAX_ADVMSS);
 	tcp_initialize_rcv_mss(sk);
-	tcp_ca_init(tp);
 
 	tcp_select_initial_window(tcp_full_space(sk),
 				  tp->advmss - (tp->rx_opt.ts_recent_stamp ? tp->tcp_header_len - sizeof(struct tcphdr) : 0),
@@ -1502,7 +1812,6 @@ int tcp_connect(struct sock *sk)
 	TCP_SKB_CB(buff)->end_seq = tp->write_seq;
 	tp->snd_nxt = tp->write_seq;
 	tp->pushed_seq = tp->write_seq;
-	tcp_ca_init(tp);
 
 	/* Send it off. */
 	TCP_SKB_CB(buff)->when = tcp_time_stamp;
@@ -1669,21 +1978,19 @@ int tcp_write_wakeup(struct sock *sk)
 			    skb->len > mss) {
 				seg_size = min(seg_size, mss);
 				TCP_SKB_CB(skb)->flags |= TCPCB_FLAG_PSH;
-				if (tcp_fragment(sk, skb, seg_size))
+				if (tcp_fragment(sk, skb, seg_size, mss))
 					return -1;
 				/* SWS override triggered forced fragmentation.
 				 * Disable TSO, the connection is too sick. */
 				if (sk->sk_route_caps & NETIF_F_TSO) {
 					sock_set_flag(sk, SOCK_NO_LARGESEND);
 					sk->sk_route_caps &= ~NETIF_F_TSO;
-					tp->mss_cache = tp->mss_cache_std;
 				}
 			} else if (!tcp_skb_pcount(skb))
-				tcp_set_skb_tso_segs(sk, skb);
+				tcp_set_skb_tso_segs(sk, skb, mss);
 
 			TCP_SKB_CB(skb)->flags |= TCPCB_FLAG_PSH;
 			TCP_SKB_CB(skb)->when = tcp_time_stamp;
-			tcp_tso_set_push(skb);
 			err = tcp_transmit_skb(sk, skb_clone(skb, GFP_ATOMIC));
 			if (!err) {
 				update_send_head(sk, tp, skb);
diff --git a/net/ipv4/tcp_scalable.c b/net/ipv4/tcp_scalable.c
new file mode 100644
--- /dev/null
+++ b/net/ipv4/tcp_scalable.c
@@ -0,0 +1,68 @@
+/* Tom Kelly's Scalable TCP
+ *
+ * See htt://www-lce.eng.cam.ac.uk/~ctk21/scalable/
+ *
+ * John Heffner <jheffner@sc.edu>
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <net/tcp.h>
+
+/* These factors derived from the recommended values in the aer:
+ * .01 and and 7/8. We use 50 instead of 100 to account for
+ * delayed ack.
+ */
+#define TCP_SCALABLE_AI_CNT	50U
+#define TCP_SCALABLE_MD_SCALE	3
+
+static void tcp_scalable_cong_avoid(struct tcp_sock *tp, u32 ack, u32 rtt,
+				    u32 in_flight, int flag)
+{
+	if (in_flight < tp->snd_cwnd)
+		return;
+
+	if (tp->snd_cwnd <= tp->snd_ssthresh) {
+		tp->snd_cwnd++;
+	} else {
+		tp->snd_cwnd_cnt++;
+		if (tp->snd_cwnd_cnt > min(tp->snd_cwnd, TCP_SCALABLE_AI_CNT)){
+			tp->snd_cwnd++;
+			tp->snd_cwnd_cnt = 0;
+		}
+	}
+	tp->snd_cwnd = min_t(u32, tp->snd_cwnd, tp->snd_cwnd_clamp);
+	tp->snd_cwnd_stamp = tcp_time_stamp;
+}
+
+static u32 tcp_scalable_ssthresh(struct tcp_sock *tp)
+{
+	return max(tp->snd_cwnd - (tp->snd_cwnd>>TCP_SCALABLE_MD_SCALE), 2U);
+}
+
+
+static struct tcp_congestion_ops tcp_scalable = {
+	.ssthresh	= tcp_scalable_ssthresh,
+	.cong_avoid	= tcp_scalable_cong_avoid,
+	.min_cwnd	= tcp_reno_min_cwnd,
+
+	.owner		= THIS_MODULE,
+	.name		= "scalable",
+};
+
+static int __init tcp_scalable_register(void)
+{
+	return tcp_register_congestion_control(&tcp_scalable);
+}
+
+static void __exit tcp_scalable_unregister(void)
+{
+	tcp_unregister_congestion_control(&tcp_scalable);
+}
+
+module_init(tcp_scalable_register);
+module_exit(tcp_scalable_unregister);
+
+MODULE_AUTHOR("John Heffner");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Scalable TCP");
diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c
--- a/net/ipv4/tcp_timer.c
+++ b/net/ipv4/tcp_timer.c
@@ -231,11 +231,10 @@ static void tcp_delack_timer(unsigned lo
 	}
 	tp->ack.pending &= ~TCP_ACK_TIMER;
 
-	if (skb_queue_len(&tp->ucopy.prequeue)) {
+	if (!skb_queue_empty(&tp->ucopy.prequeue)) {
 		struct sk_buff *skb;
 
-		NET_ADD_STATS_BH(LINUX_MIB_TCPSCHEDULERFAILED, 
-				 skb_queue_len(&tp->ucopy.prequeue));
+		NET_INC_STATS_BH(LINUX_MIB_TCPSCHEDULERFAILED);
 
 		while ((skb = __skb_dequeue(&tp->ucopy.prequeue)) != NULL)
 			sk->sk_backlog_rcv(sk, skb);
@@ -464,11 +463,11 @@ out_unlock:
 static void tcp_synack_timer(struct sock *sk)
 {
 	struct tcp_sock *tp = tcp_sk(sk);
-	struct tcp_listen_opt *lopt = tp->listen_opt;
+	struct listen_sock *lopt = tp->accept_queue.listen_opt;
 	int max_retries = tp->syn_retries ? : sysctl_tcp_synack_retries;
 	int thresh = max_retries;
 	unsigned long now = jiffies;
-	struct open_request **reqp, *req;
+	struct request_sock **reqp, *req;
 	int i, budget;
 
 	if (lopt == NULL || lopt->qlen == 0)
@@ -513,8 +512,8 @@ static void tcp_synack_timer(struct sock
 		while ((req = *reqp) != NULL) {
 			if (time_after_eq(now, req->expires)) {
 				if ((req->retrans < thresh ||
-				     (req->acked && req->retrans < max_retries))
-				    && !req->class->rtx_syn_ack(sk, req, NULL)) {
+				     (inet_rsk(req)->acked && req->retrans < max_retries))
+				    && !req->rsk_ops->rtx_syn_ack(sk, req, NULL)) {
 					unsigned long timeo;
 
 					if (req->retrans++ == 0)
@@ -527,13 +526,9 @@ static void tcp_synack_timer(struct sock
 				}
 
 				/* Drop this request */
-				write_lock(&tp->syn_wait_lock);
-				*reqp = req->dl_next;
-				write_unlock(&tp->syn_wait_lock);
-				lopt->qlen--;
-				if (req->retrans == 0)
-					lopt->qlen_young--;
-				tcp_openreq_free(req);
+				tcp_synq_unlink(tp, req, reqp);
+				reqsk_queue_removed(&tp->accept_queue, req);
+				reqsk_free(req);
 				continue;
 			}
 			reqp = &req->dl_next;
diff --git a/net/ipv4/tcp_vegas.c b/net/ipv4/tcp_vegas.c
new file mode 100644
--- /dev/null
+++ b/net/ipv4/tcp_vegas.c
@@ -0,0 +1,411 @@
+/*
+ * TCP Vegas congestion control
+ *
+ * This is based on the congestion detection/avoidance scheme described in
+ *    Lawrence S. Brakmo and Larry L. Peterson.
+ *    "TCP Vegas: End to end congestion avoidance on a global internet."
+ *    IEEE Journal on Selected Areas in Communication, 13(8):1465--1480,
+ *    October 1995. Available from:
+ *	ftp://ftp.cs.arizona.edu/xkernel/Papers/jsac.ps
+ *
+ * See http://www.cs.arizona.edu/xkernel/ for their implementation.
+ * The main aspects that distinguish this implementation from the
+ * Arizona Vegas implementation are:
+ *   o We do not change the loss detection or recovery mechanisms of
+ *     Linux in any way. Linux already recovers from losses quite well,
+ *     using fine-grained timers, NewReno, and FACK.
+ *   o To avoid the performance penalty imposed by increasing cwnd
+ *     only every-other RTT during slow start, we increase during
+ *     every RTT during slow start, just like Reno.
+ *   o Largely to allow continuous cwnd growth during slow start,
+ *     we use the rate at which ACKs come back as the "actual"
+ *     rate, rather than the rate at which data is sent.
+ *   o To speed convergence to the right rate, we set the cwnd
+ *     to achieve the right ("actual") rate when we exit slow start.
+ *   o To filter out the noise caused by delayed ACKs, we use the
+ *     minimum RTT sample observed during the last RTT to calculate
+ *     the actual rate.
+ *   o When the sender re-starts from idle, it waits until it has
+ *     received ACKs for an entire flight of new data before making
+ *     a cwnd adjustment decision. The original Vegas implementation
+ *     assumed senders never went idle.
+ */
+
+#include <linux/config.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/tcp_diag.h>
+
+#include <net/tcp.h>
+
+/* Default values of the Vegas variables, in fixed-point representation
+ * with V_PARAM_SHIFT bits to the right of the binary point.
+ */
+#define V_PARAM_SHIFT 1
+static int alpha = 1<<V_PARAM_SHIFT;
+static int beta  = 3<<V_PARAM_SHIFT;
+static int gamma = 1<<V_PARAM_SHIFT;
+
+module_param(alpha, int, 0644);
+MODULE_PARM_DESC(alpha, "lower bound of packets in network (scale by 2)");
+module_param(beta, int, 0644);
+MODULE_PARM_DESC(beta, "upper bound of packets in network (scale by 2)");
+module_param(gamma, int, 0644);
+MODULE_PARM_DESC(gamma, "limit on increase (scale by 2)");
+
+
+/* Vegas variables */
+struct vegas {
+	u32	beg_snd_nxt;	/* right edge during last RTT */
+	u32	beg_snd_una;	/* left edge  during last RTT */
+	u32	beg_snd_cwnd;	/* saves the size of the cwnd */
+	u8	doing_vegas_now;/* if true, do vegas for this RTT */
+	u16	cntRTT;		/* # of RTTs measured within last RTT */
+	u32	minRTT;		/* min of RTTs measured within last RTT (in usec) */
+	u32	baseRTT;	/* the min of all Vegas RTT measurements seen (in usec) */
+};
+
+/* There are several situations when we must "re-start" Vegas:
+ *
+ *  o when a connection is established
+ *  o after an RTO
+ *  o after fast recovery
+ *  o when we send a packet and there is no outstanding
+ *    unacknowledged data (restarting an idle connection)
+ *
+ * In these circumstances we cannot do a Vegas calculation at the
+ * end of the first RTT, because any calculation we do is using
+ * stale info -- both the saved cwnd and congestion feedback are
+ * stale.
+ *
+ * Instead we must wait until the completion of an RTT during
+ * which we actually receive ACKs.
+ */
+static inline void vegas_enable(struct tcp_sock *tp)
+{
+	struct vegas *vegas = tcp_ca(tp);
+
+	/* Begin taking Vegas samples next time we send something. */
+	vegas->doing_vegas_now = 1;
+
+	/* Set the beginning of the next send window. */
+	vegas->beg_snd_nxt = tp->snd_nxt;
+
+	vegas->cntRTT = 0;
+	vegas->minRTT = 0x7fffffff;
+}
+
+/* Stop taking Vegas samples for now. */
+static inline void vegas_disable(struct tcp_sock *tp)
+{
+	struct vegas *vegas = tcp_ca(tp);
+
+	vegas->doing_vegas_now = 0;
+}
+
+static void tcp_vegas_init(struct tcp_sock *tp)
+{
+	struct vegas *vegas = tcp_ca(tp);
+
+	vegas->baseRTT = 0x7fffffff;
+	vegas_enable(tp);
+}
+
+/* Do RTT sampling needed for Vegas.
+ * Basically we:
+ *   o min-filter RTT samples from within an RTT to get the current
+ *     propagation delay + queuing delay (we are min-filtering to try to
+ *     avoid the effects of delayed ACKs)
+ *   o min-filter RTT samples from a much longer window (forever for now)
+ *     to find the propagation delay (baseRTT)
+ */
+static void tcp_vegas_rtt_calc(struct tcp_sock *tp, u32 usrtt)
+{
+	struct vegas *vegas = tcp_ca(tp);
+	u32 vrtt = usrtt + 1; /* Never allow zero rtt or baseRTT */
+
+	/* Filter to find propagation delay: */
+	if (vrtt < vegas->baseRTT)
+		vegas->baseRTT = vrtt;
+
+	/* Find the min RTT during the last RTT to find
+	 * the current prop. delay + queuing delay:
+	 */
+	vegas->minRTT = min(vegas->minRTT, vrtt);
+	vegas->cntRTT++;
+}
+
+static void tcp_vegas_state(struct tcp_sock *tp, u8 ca_state)
+{
+
+	if (ca_state == TCP_CA_Open)
+		vegas_enable(tp);
+	else
+		vegas_disable(tp);
+}
+
+/*
+ * If the connection is idle and we are restarting,
+ * then we don't want to do any Vegas calculations
+ * until we get fresh RTT samples.  So when we
+ * restart, we reset our Vegas state to a clean
+ * slate. After we get acks for this flight of
+ * packets, _then_ we can make Vegas calculations
+ * again.
+ */
+static void tcp_vegas_cwnd_event(struct tcp_sock *tp, enum tcp_ca_event event)
+{
+	if (event == CA_EVENT_CWND_RESTART ||
+	    event == CA_EVENT_TX_START)
+		tcp_vegas_init(tp);
+}
+
+static void tcp_vegas_cong_avoid(struct tcp_sock *tp, u32 ack,
+				 u32 seq_rtt, u32 in_flight, int flag)
+{
+	struct vegas *vegas = tcp_ca(tp);
+
+	if (!vegas->doing_vegas_now)
+		return tcp_reno_cong_avoid(tp, ack, seq_rtt, in_flight, flag);
+
+	/* The key players are v_beg_snd_una and v_beg_snd_nxt.
+	 *
+	 * These are so named because they represent the approximate values
+	 * of snd_una and snd_nxt at the beginning of the current RTT. More
+	 * precisely, they represent the amount of data sent during the RTT.
+	 * At the end of the RTT, when we receive an ACK for v_beg_snd_nxt,
+	 * we will calculate that (v_beg_snd_nxt - v_beg_snd_una) outstanding
+	 * bytes of data have been ACKed during the course of the RTT, giving
+	 * an "actual" rate of:
+	 *
+	 *     (v_beg_snd_nxt - v_beg_snd_una) / (rtt duration)
+	 *
+	 * Unfortunately, v_beg_snd_una is not exactly equal to snd_una,
+	 * because delayed ACKs can cover more than one segment, so they
+	 * don't line up nicely with the boundaries of RTTs.
+	 *
+	 * Another unfortunate fact of life is that delayed ACKs delay the
+	 * advance of the left edge of our send window, so that the number
+	 * of bytes we send in an RTT is often less than our cwnd will allow.
+	 * So we keep track of our cwnd separately, in v_beg_snd_cwnd.
+	 */
+
+	if (after(ack, vegas->beg_snd_nxt)) {
+		/* Do the Vegas once-per-RTT cwnd adjustment. */
+		u32 old_wnd, old_snd_cwnd;
+
+
+		/* Here old_wnd is essentially the window of data that was
+		 * sent during the previous RTT, and has all
+		 * been acknowledged in the course of the RTT that ended
+		 * with the ACK we just received. Likewise, old_snd_cwnd
+		 * is the cwnd during the previous RTT.
+		 */
+		old_wnd = (vegas->beg_snd_nxt - vegas->beg_snd_una) /
+			tp->mss_cache;
+		old_snd_cwnd = vegas->beg_snd_cwnd;
+
+		/* Save the extent of the current window so we can use this
+		 * at the end of the next RTT.
+		 */
+		vegas->beg_snd_una  = vegas->beg_snd_nxt;
+		vegas->beg_snd_nxt  = tp->snd_nxt;
+		vegas->beg_snd_cwnd = tp->snd_cwnd;
+
+		/* Take into account the current RTT sample too, to
+		 * decrease the impact of delayed acks. This double counts
+		 * this sample since we count it for the next window as well,
+		 * but that's not too awful, since we're taking the min,
+		 * rather than averaging.
+		 */
+		tcp_vegas_rtt_calc(tp, seq_rtt*1000);
+
+		/* We do the Vegas calculations only if we got enough RTT
+		 * samples that we can be reasonably sure that we got
+		 * at least one RTT sample that wasn't from a delayed ACK.
+		 * If we only had 2 samples total,
+		 * then that means we're getting only 1 ACK per RTT, which
+		 * means they're almost certainly delayed ACKs.
+		 * If  we have 3 samples, we should be OK.
+		 */
+
+		if (vegas->cntRTT <= 2) {
+			/* We don't have enough RTT samples to do the Vegas
+			 * calculation, so we'll behave like Reno.
+			 */
+			if (tp->snd_cwnd > tp->snd_ssthresh)
+				tp->snd_cwnd++;
+		} else {
+			u32 rtt, target_cwnd, diff;
+
+			/* We have enough RTT samples, so, using the Vegas
+			 * algorithm, we determine if we should increase or
+			 * decrease cwnd, and by how much.
+			 */
+
+			/* Pluck out the RTT we are using for the Vegas
+			 * calculations. This is the min RTT seen during the
+			 * last RTT. Taking the min filters out the effects
+			 * of delayed ACKs, at the cost of noticing congestion
+			 * a bit later.
+			 */
+			rtt = vegas->minRTT;
+
+			/* Calculate the cwnd we should have, if we weren't
+			 * going too fast.
+			 *
+			 * This is:
+			 *     (actual rate in segments) * baseRTT
+			 * We keep it as a fixed point number with
+			 * V_PARAM_SHIFT bits to the right of the binary point.
+			 */
+			target_cwnd = ((old_wnd * vegas->baseRTT)
+				       << V_PARAM_SHIFT) / rtt;
+
+			/* Calculate the difference between the window we had,
+			 * and the window we would like to have. This quantity
+			 * is the "Diff" from the Arizona Vegas papers.
+			 *
+			 * Again, this is a fixed point number with
+			 * V_PARAM_SHIFT bits to the right of the binary
+			 * point.
+			 */
+			diff = (old_wnd << V_PARAM_SHIFT) - target_cwnd;
+
+			if (tp->snd_cwnd < tp->snd_ssthresh) {
+				/* Slow start.  */
+				if (diff > gamma) {
+					/* Going too fast. Time to slow down
+					 * and switch to congestion avoidance.
+					 */
+					tp->snd_ssthresh = 2;
+
+					/* Set cwnd to match the actual rate
+					 * exactly:
+					 *   cwnd = (actual rate) * baseRTT
+					 * Then we add 1 because the integer
+					 * truncation robs us of full link
+					 * utilization.
+					 */
+					tp->snd_cwnd = min(tp->snd_cwnd,
+							   (target_cwnd >>
+							    V_PARAM_SHIFT)+1);
+
+				}
+			} else {
+				/* Congestion avoidance. */
+				u32 next_snd_cwnd;
+
+				/* Figure out where we would like cwnd
+				 * to be.
+				 */
+				if (diff > beta) {
+					/* The old window was too fast, so
+					 * we slow down.
+					 */
+					next_snd_cwnd = old_snd_cwnd - 1;
+				} else if (diff < alpha) {
+					/* We don't have enough extra packets
+					 * in the network, so speed up.
+					 */
+					next_snd_cwnd = old_snd_cwnd + 1;
+				} else {
+					/* Sending just as fast as we
+					 * should be.
+					 */
+					next_snd_cwnd = old_snd_cwnd;
+				}
+
+				/* Adjust cwnd upward or downward, toward the
+				 * desired value.
+				 */
+				if (next_snd_cwnd > tp->snd_cwnd)
+					tp->snd_cwnd++;
+				else if (next_snd_cwnd < tp->snd_cwnd)
+					tp->snd_cwnd--;
+			}
+		}
+
+		/* Wipe the slate clean for the next RTT. */
+		vegas->cntRTT = 0;
+		vegas->minRTT = 0x7fffffff;
+	}
+
+	/* The following code is executed for every ack we receive,
+	 * except for conditions checked in should_advance_cwnd()
+	 * before the call to tcp_cong_avoid(). Mainly this means that
+	 * we only execute this code if the ack actually acked some
+	 * data.
+	 */
+
+	/* If we are in slow start, increase our cwnd in response to this ACK.
+	 * (If we are not in slow start then we are in congestion avoidance,
+	 * and adjust our congestion window only once per RTT. See the code
+	 * above.)
+	 */
+	if (tp->snd_cwnd <= tp->snd_ssthresh)
+		tp->snd_cwnd++;
+
+	/* to keep cwnd from growing without bound */
+	tp->snd_cwnd = min_t(u32, tp->snd_cwnd, tp->snd_cwnd_clamp);
+
+	/* Make sure that we are never so timid as to reduce our cwnd below
+	 * 2 MSS.
+	 *
+	 * Going below 2 MSS would risk huge delayed ACKs from our receiver.
+	 */
+	tp->snd_cwnd = max(tp->snd_cwnd, 2U);
+}
+
+/* Extract info for Tcp socket info provided via netlink. */
+static void tcp_vegas_get_info(struct tcp_sock *tp, u32 ext,
+			       struct sk_buff *skb)
+{
+	const struct vegas *ca = tcp_ca(tp);
+	if (ext & (1<<(TCPDIAG_VEGASINFO-1))) {
+		struct tcpvegas_info *info;
+
+		info = RTA_DATA(__RTA_PUT(skb, TCPDIAG_VEGASINFO,
+					  sizeof(*info)));
+
+		info->tcpv_enabled = ca->doing_vegas_now;
+		info->tcpv_rttcnt = ca->cntRTT;
+		info->tcpv_rtt = ca->baseRTT;
+		info->tcpv_minrtt = ca->minRTT;
+	rtattr_failure:	;
+	}
+}
+
+static struct tcp_congestion_ops tcp_vegas = {
+	.init		= tcp_vegas_init,
+	.ssthresh	= tcp_reno_ssthresh,
+	.cong_avoid	= tcp_vegas_cong_avoid,
+	.min_cwnd	= tcp_reno_min_cwnd,
+	.rtt_sample	= tcp_vegas_rtt_calc,
+	.set_state	= tcp_vegas_state,
+	.cwnd_event	= tcp_vegas_cwnd_event,
+	.get_info	= tcp_vegas_get_info,
+
+	.owner		= THIS_MODULE,
+	.name		= "vegas",
+};
+
+static int __init tcp_vegas_register(void)
+{
+	BUG_ON(sizeof(struct vegas) > TCP_CA_PRIV_SIZE);
+	tcp_register_congestion_control(&tcp_vegas);
+	return 0;
+}
+
+static void __exit tcp_vegas_unregister(void)
+{
+	tcp_unregister_congestion_control(&tcp_vegas);
+}
+
+module_init(tcp_vegas_register);
+module_exit(tcp_vegas_unregister);
+
+MODULE_AUTHOR("Stephen Hemminger");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("TCP Vegas");
diff --git a/net/ipv4/tcp_westwood.c b/net/ipv4/tcp_westwood.c
new file mode 100644
--- /dev/null
+++ b/net/ipv4/tcp_westwood.c
@@ -0,0 +1,259 @@
+/*
+ * TCP Westwood+
+ *
+ *	Angelo Dell'Aera:	TCP Westwood+ support
+ */
+
+#include <linux/config.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/tcp_diag.h>
+#include <net/tcp.h>
+
+/* TCP Westwood structure */
+struct westwood {
+	u32    bw_ns_est;        /* first bandwidth estimation..not too smoothed 8) */
+	u32    bw_est;           /* bandwidth estimate */
+	u32    rtt_win_sx;       /* here starts a new evaluation... */
+	u32    bk;
+	u32    snd_una;          /* used for evaluating the number of acked bytes */
+	u32    cumul_ack;
+	u32    accounted;
+	u32    rtt;
+	u32    rtt_min;          /* minimum observed RTT */
+};
+
+
+/* TCP Westwood functions and constants */
+#define TCP_WESTWOOD_RTT_MIN   (HZ/20)	/* 50ms */
+#define TCP_WESTWOOD_INIT_RTT  (20*HZ)	/* maybe too conservative?! */
+
+/*
+ * @tcp_westwood_create
+ * This function initializes fields used in TCP Westwood+,
+ * it is called after the initial SYN, so the sequence numbers
+ * are correct but new passive connections we have no
+ * information about RTTmin at this time so we simply set it to
+ * TCP_WESTWOOD_INIT_RTT. This value was chosen to be too conservative
+ * since in this way we're sure it will be updated in a consistent
+ * way as soon as possible. It will reasonably happen within the first
+ * RTT period of the connection lifetime.
+ */
+static void tcp_westwood_init(struct tcp_sock *tp)
+{
+	struct westwood *w = tcp_ca(tp);
+
+	w->bk = 0;
+        w->bw_ns_est = 0;
+        w->bw_est = 0;
+        w->accounted = 0;
+        w->cumul_ack = 0;
+	w->rtt_min = w->rtt = TCP_WESTWOOD_INIT_RTT;
+	w->rtt_win_sx = tcp_time_stamp;
+	w->snd_una = tp->snd_una;
+}
+
+/*
+ * @westwood_do_filter
+ * Low-pass filter. Implemented using constant coefficients.
+ */
+static inline u32 westwood_do_filter(u32 a, u32 b)
+{
+	return (((7 * a) + b) >> 3);
+}
+
+static inline void westwood_filter(struct westwood *w, u32 delta)
+{
+	w->bw_ns_est = westwood_do_filter(w->bw_ns_est, w->bk / delta);
+	w->bw_est = westwood_do_filter(w->bw_est, w->bw_ns_est);
+}
+
+/*
+ * @westwood_pkts_acked
+ * Called after processing group of packets.
+ * but all westwood needs is the last sample of srtt.
+ */
+static void tcp_westwood_pkts_acked(struct tcp_sock *tp, u32 cnt)
+{
+	struct westwood *w = tcp_ca(tp);
+	if (cnt > 0)
+		w->rtt = tp->srtt >> 3;
+}
+
+/*
+ * @westwood_update_window
+ * It updates RTT evaluation window if it is the right moment to do
+ * it. If so it calls filter for evaluating bandwidth.
+ */
+static void westwood_update_window(struct tcp_sock *tp)
+{
+	struct westwood *w = tcp_ca(tp);
+	s32 delta = tcp_time_stamp - w->rtt_win_sx;
+
+	/*
+	 * See if a RTT-window has passed.
+	 * Be careful since if RTT is less than
+	 * 50ms we don't filter but we continue 'building the sample'.
+	 * This minimum limit was chosen since an estimation on small
+	 * time intervals is better to avoid...
+	 * Obviously on a LAN we reasonably will always have
+	 * right_bound = left_bound + WESTWOOD_RTT_MIN
+	 */
+	if (w->rtt && delta > max_t(u32, w->rtt, TCP_WESTWOOD_RTT_MIN)) {
+		westwood_filter(w, delta);
+
+		w->bk = 0;
+		w->rtt_win_sx = tcp_time_stamp;
+	}
+}
+
+/*
+ * @westwood_fast_bw
+ * It is called when we are in fast path. In particular it is called when
+ * header prediction is successful. In such case in fact update is
+ * straight forward and doesn't need any particular care.
+ */
+static inline void westwood_fast_bw(struct tcp_sock *tp)
+{
+	struct westwood *w = tcp_ca(tp);
+
+	westwood_update_window(tp);
+
+	w->bk += tp->snd_una - w->snd_una;
+	w->snd_una = tp->snd_una;
+	w->rtt_min = min(w->rtt, w->rtt_min);
+}
+
+/*
+ * @westwood_acked_count
+ * This function evaluates cumul_ack for evaluating bk in case of
+ * delayed or partial acks.
+ */
+static inline u32 westwood_acked_count(struct tcp_sock *tp)
+{
+	struct westwood *w = tcp_ca(tp);
+
+	w->cumul_ack = tp->snd_una - w->snd_una;
+
+        /* If cumul_ack is 0 this is a dupack since it's not moving
+         * tp->snd_una.
+         */
+        if (!w->cumul_ack) {
+		w->accounted += tp->mss_cache;
+		w->cumul_ack = tp->mss_cache;
+	}
+
+        if (w->cumul_ack > tp->mss_cache) {
+		/* Partial or delayed ack */
+		if (w->accounted >= w->cumul_ack) {
+			w->accounted -= w->cumul_ack;
+			w->cumul_ack = tp->mss_cache;
+		} else {
+			w->cumul_ack -= w->accounted;
+			w->accounted = 0;
+		}
+	}
+
+	w->snd_una = tp->snd_una;
+
+	return w->cumul_ack;
+}
+
+static inline u32 westwood_bw_rttmin(const struct tcp_sock *tp)
+{
+	struct westwood *w = tcp_ca(tp);
+	return max_t(u32, (w->bw_est * w->rtt_min) / tp->mss_cache, 2);
+}
+
+/*
+ * TCP Westwood
+ * Here limit is evaluated as Bw estimation*RTTmin (for obtaining it
+ * in packets we use mss_cache). Rttmin is guaranteed to be >= 2
+ * so avoids ever returning 0.
+ */
+static u32 tcp_westwood_cwnd_min(struct tcp_sock *tp)
+{
+	return westwood_bw_rttmin(tp);
+}
+
+static void tcp_westwood_event(struct tcp_sock *tp, enum tcp_ca_event event)
+{
+	struct westwood *w = tcp_ca(tp);
+
+	switch(event) {
+	case CA_EVENT_FAST_ACK:
+		westwood_fast_bw(tp);
+		break;
+
+	case CA_EVENT_COMPLETE_CWR:
+		tp->snd_cwnd = tp->snd_ssthresh = westwood_bw_rttmin(tp);
+		break;
+
+	case CA_EVENT_FRTO:
+		tp->snd_ssthresh = westwood_bw_rttmin(tp);
+		break;
+
+	case CA_EVENT_SLOW_ACK:
+		westwood_update_window(tp);
+		w->bk += westwood_acked_count(tp);
+		w->rtt_min = min(w->rtt, w->rtt_min);
+		break;
+
+	default:
+		/* don't care */
+		break;
+	}
+}
+
+
+/* Extract info for Tcp socket info provided via netlink. */
+static void tcp_westwood_info(struct tcp_sock *tp, u32 ext,
+			      struct sk_buff *skb)
+{
+	const struct westwood *ca = tcp_ca(tp);
+	if (ext & (1<<(TCPDIAG_VEGASINFO-1))) {
+		struct rtattr *rta;
+		struct tcpvegas_info *info;
+
+		rta = __RTA_PUT(skb, TCPDIAG_VEGASINFO, sizeof(*info));
+		info = RTA_DATA(rta);
+		info->tcpv_enabled = 1;
+		info->tcpv_rttcnt = 0;
+		info->tcpv_rtt = jiffies_to_usecs(ca->rtt);
+		info->tcpv_minrtt = jiffies_to_usecs(ca->rtt_min);
+	rtattr_failure:	;
+	}
+}
+
+
+static struct tcp_congestion_ops tcp_westwood = {
+	.init		= tcp_westwood_init,
+	.ssthresh	= tcp_reno_ssthresh,
+	.cong_avoid	= tcp_reno_cong_avoid,
+	.min_cwnd	= tcp_westwood_cwnd_min,
+	.cwnd_event	= tcp_westwood_event,
+	.get_info	= tcp_westwood_info,
+	.pkts_acked	= tcp_westwood_pkts_acked,
+
+	.owner		= THIS_MODULE,
+	.name		= "westwood"
+};
+
+static int __init tcp_westwood_register(void)
+{
+	BUG_ON(sizeof(struct westwood) > TCP_CA_PRIV_SIZE);
+	return tcp_register_congestion_control(&tcp_westwood);
+}
+
+static void __exit tcp_westwood_unregister(void)
+{
+	tcp_unregister_congestion_control(&tcp_westwood);
+}
+
+module_init(tcp_westwood_register);
+module_exit(tcp_westwood_unregister);
+
+MODULE_AUTHOR("Stephen Hemminger, Angelo Dell'Aera");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("TCP Westwood+");
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -628,7 +628,7 @@ back_from_confirm:
 		/* ... which is an evident application bug. --ANK */
 		release_sock(sk);
 
-		NETDEBUG(if (net_ratelimit()) printk(KERN_DEBUG "udp cork app bug 2\n"));
+		LIMIT_NETDEBUG(printk(KERN_DEBUG "udp cork app bug 2\n"));
 		err = -EINVAL;
 		goto out;
 	}
@@ -693,7 +693,7 @@ static int udp_sendpage(struct sock *sk,
 	if (unlikely(!up->pending)) {
 		release_sock(sk);
 
-		NETDEBUG(if (net_ratelimit()) printk(KERN_DEBUG "udp cork app bug 3\n"));
+		LIMIT_NETDEBUG(printk(KERN_DEBUG "udp cork app bug 3\n"));
 		return -EINVAL;
 	}
 
@@ -1102,7 +1102,7 @@ static int udp_checksum_init(struct sk_b
 		skb->ip_summed = CHECKSUM_UNNECESSARY;
 		if (!udp_check(uh, ulen, saddr, daddr, skb->csum))
 			return 0;
-		NETDEBUG(if (net_ratelimit()) printk(KERN_DEBUG "udp v4 hw csum failure.\n"));
+		LIMIT_NETDEBUG(printk(KERN_DEBUG "udp v4 hw csum failure.\n"));
 		skb->ip_summed = CHECKSUM_NONE;
 	}
 	if (skb->ip_summed != CHECKSUM_UNNECESSARY)
@@ -1181,14 +1181,13 @@ int udp_rcv(struct sk_buff *skb)
 	return(0);
 
 short_packet:
-	NETDEBUG(if (net_ratelimit())
-		printk(KERN_DEBUG "UDP: short packet: From %u.%u.%u.%u:%u %d/%d to %u.%u.%u.%u:%u\n",
-			NIPQUAD(saddr),
-			ntohs(uh->source),
-			ulen,
-			len,
-			NIPQUAD(daddr),
-			ntohs(uh->dest)));
+	LIMIT_NETDEBUG(printk(KERN_DEBUG "UDP: short packet: From %u.%u.%u.%u:%u %d/%d to %u.%u.%u.%u:%u\n",
+			      NIPQUAD(saddr),
+			      ntohs(uh->source),
+			      ulen,
+			      len,
+			      NIPQUAD(daddr),
+			      ntohs(uh->dest)));
 no_header:
 	UDP_INC_STATS_BH(UDP_MIB_INERRORS);
 	kfree_skb(skb);
@@ -1199,13 +1198,12 @@ csum_error:
 	 * RFC1122: OK.  Discards the bad packet silently (as far as 
 	 * the network is concerned, anyway) as per 4.1.3.4 (MUST). 
 	 */
-	NETDEBUG(if (net_ratelimit())
-		 printk(KERN_DEBUG "UDP: bad checksum. From %d.%d.%d.%d:%d to %d.%d.%d.%d:%d ulen %d\n",
-			NIPQUAD(saddr),
-			ntohs(uh->source),
-			NIPQUAD(daddr),
-			ntohs(uh->dest),
-			ulen));
+	LIMIT_NETDEBUG(printk(KERN_DEBUG "UDP: bad checksum. From %d.%d.%d.%d:%d to %d.%d.%d.%d:%d ulen %d\n",
+			      NIPQUAD(saddr),
+			      ntohs(uh->source),
+			      NIPQUAD(daddr),
+			      ntohs(uh->dest),
+			      ulen));
 drop:
 	UDP_INC_STATS_BH(UDP_MIB_INERRORS);
 	kfree_skb(skb);
diff --git a/net/ipv4/utils.c b/net/ipv4/utils.c
deleted file mode 100644
--- a/net/ipv4/utils.c
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * INET		An implementation of the TCP/IP protocol suite for the LINUX
- *		operating system.  INET is implemented using the  BSD Socket
- *		interface as the means of communication with the user level.
- *
- *		Various kernel-resident INET utility functions; mainly
- *		for format conversion and debugging output.
- *
- * Version:	$Id: utils.c,v 1.8 2000/10/03 07:29:01 anton Exp $
- *
- * Author:	Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
- *
- * Fixes:
- *		Alan Cox	:	verify_area check.
- *		Alan Cox	:	removed old debugging.
- *		Andi Kleen	:	add net_ratelimit()  
- *
- *		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/types.h>
-#include <asm/byteorder.h>
-
-/*
- *	Convert an ASCII string to binary IP. 
- */
- 
-__u32 in_aton(const char *str)
-{
-	unsigned long l;
-	unsigned int val;
-	int i;
-
-	l = 0;
-	for (i = 0; i < 4; i++) 
-	{
-		l <<= 8;
-		if (*str != '\0') 
-		{
-			val = 0;
-			while (*str != '\0' && *str != '.') 
-			{
-				val *= 10;
-				val += *str - '0';
-				str++;
-			}
-			l |= val;
-			if (*str != '\0') 
-				str++;
-		}
-	}
-	return(htonl(l));
-}
-
-EXPORT_SYMBOL(in_aton);
diff --git a/net/ipv4/xfrm4_output.c b/net/ipv4/xfrm4_output.c
--- a/net/ipv4/xfrm4_output.c
+++ b/net/ipv4/xfrm4_output.c
@@ -33,6 +33,7 @@ static void xfrm4_encap(struct sk_buff *
 	struct dst_entry *dst = skb->dst;
 	struct xfrm_state *x = dst->xfrm;
 	struct iphdr *iph, *top_iph;
+	int flags;
 
 	iph = skb->nh.iph;
 	skb->h.ipiph = iph;
@@ -51,10 +52,13 @@ static void xfrm4_encap(struct sk_buff *
 
 	/* DS disclosed */
 	top_iph->tos = INET_ECN_encapsulate(iph->tos, iph->tos);
-	if (x->props.flags & XFRM_STATE_NOECN)
+
+	flags = x->props.flags;
+	if (flags & XFRM_STATE_NOECN)
 		IP_ECN_clear(top_iph);
 
-	top_iph->frag_off = iph->frag_off & htons(IP_DF);
+	top_iph->frag_off = (flags & XFRM_STATE_NOPMTUDISC) ?
+		0 : (iph->frag_off & htons(IP_DF));
 	if (!top_iph->frag_off)
 		__ip_select_ident(top_iph, dst, 0);
 
diff --git a/net/ipv4/xfrm4_state.c b/net/ipv4/xfrm4_state.c
--- a/net/ipv4/xfrm4_state.c
+++ b/net/ipv4/xfrm4_state.c
@@ -7,12 +7,20 @@
  *
  */
 
+#include <net/ip.h>
 #include <net/xfrm.h>
 #include <linux/pfkeyv2.h>
 #include <linux/ipsec.h>
 
 static struct xfrm_state_afinfo xfrm4_state_afinfo;
 
+static int xfrm4_init_flags(struct xfrm_state *x)
+{
+	if (ipv4_config.no_pmtu_disc)
+		x->props.flags |= XFRM_STATE_NOPMTUDISC;
+	return 0;
+}
+
 static void
 __xfrm4_init_tempsel(struct xfrm_state *x, struct flowi *fl,
 		     struct xfrm_tmpl *tmpl,
@@ -109,6 +117,7 @@ __xfrm4_find_acq(u8 mode, u32 reqid, u8 
 static struct xfrm_state_afinfo xfrm4_state_afinfo = {
 	.family			= AF_INET,
 	.lock			= RW_LOCK_UNLOCKED,
+	.init_flags		= xfrm4_init_flags,
 	.init_tempsel		= __xfrm4_init_tempsel,
 	.state_lookup		= __xfrm4_state_lookup,
 	.find_acq		= __xfrm4_find_acq,
diff --git a/net/ipv4/xfrm4_tunnel.c b/net/ipv4/xfrm4_tunnel.c
--- a/net/ipv4/xfrm4_tunnel.c
+++ b/net/ipv4/xfrm4_tunnel.c
@@ -78,13 +78,12 @@ static int ipip_rcv(struct sk_buff *skb)
 static void ipip_err(struct sk_buff *skb, u32 info)
 {
 	struct xfrm_tunnel *handler = ipip_handler;
-	u32 arg = info;
 
 	if (handler)
-		handler->err_handler(skb, &arg);
+		handler->err_handler(skb, info);
 }
 
-static int ipip_init_state(struct xfrm_state *x, void *args)
+static int ipip_init_state(struct xfrm_state *x)
 {
 	if (!x->props.mode)
 		return -EINVAL;
diff --git a/net/ipv6/Kconfig b/net/ipv6/Kconfig
--- a/net/ipv6/Kconfig
+++ b/net/ipv6/Kconfig
@@ -1,6 +1,26 @@
 #
 # IPv6 configuration
-# 
+#
+
+#   IPv6 as module will cause a CRASH if you try to unload it
+config IPV6
+	tristate "The IPv6 protocol"
+	default m
+	select CRYPTO if IPV6_PRIVACY
+	select CRYPTO_MD5 if IPV6_PRIVACY
+	---help---
+	  This is complemental support for the IP version 6.
+	  You will still be able to do traditional IPv4 networking as well.
+
+	  For general information about IPv6, see
+	  <http://playground.sun.com/pub/ipng/html/ipng-main.html>.
+	  For Linux IPv6 development information, see <http://www.linux-ipv6.org>.
+	  For specific information about IPv6 under Linux, read the HOWTO at
+	  <http://www.bieringer.de/linux/IPv6/>.
+
+	  To compile this protocol support as a module, choose M here: the 
+	  module will be called ipv6.
+
 config IPV6_PRIVACY
 	bool "IPv6: Privacy Extensions (RFC 3041) support"
 	depends on IPV6
@@ -71,7 +91,6 @@ config INET6_TUNNEL
 config IPV6_TUNNEL
 	tristate "IPv6: IPv6-in-IPv6 tunnel"
 	depends on IPV6
-	select INET6_TUNNEL
 	---help---
 	  Support for IPv6-in-IPv6 tunnels described in RFC 2473.
 
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -57,6 +57,7 @@
 #endif
 #include <linux/delay.h>
 #include <linux/notifier.h>
+#include <linux/string.h>
 
 #include <net/sock.h>
 #include <net/snmp.h>
@@ -131,7 +132,7 @@ static void addrconf_leave_anycast(struc
 
 static int addrconf_ifdown(struct net_device *dev, int how);
 
-static void addrconf_dad_start(struct inet6_ifaddr *ifp, int flags);
+static void addrconf_dad_start(struct inet6_ifaddr *ifp, u32 flags);
 static void addrconf_dad_timer(unsigned long data);
 static void addrconf_dad_completed(struct inet6_ifaddr *ifp);
 static void addrconf_rs_timer(unsigned long data);
@@ -492,7 +493,7 @@ void inet6_ifa_finish_destroy(struct ine
 
 static struct inet6_ifaddr *
 ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr, int pfxlen,
-	      int scope, unsigned flags)
+	      int scope, u32 flags)
 {
 	struct inet6_ifaddr *ifa = NULL;
 	struct rt6_info *rt;
@@ -695,7 +696,7 @@ static void ipv6_del_addr(struct inet6_i
 
 		if (rt && ((rt->rt6i_flags & (RTF_GATEWAY | RTF_DEFAULT)) == 0)) {
 			if (onlink == 0) {
-				ip6_del_rt(rt, NULL, NULL);
+				ip6_del_rt(rt, NULL, NULL, NULL);
 				rt = NULL;
 			} else if (!(rt->rt6i_flags & RTF_EXPIRES)) {
 				rt->rt6i_expires = expires;
@@ -1320,7 +1321,7 @@ static int __ipv6_try_regen_rndid(struct
 
 static void
 addrconf_prefix_route(struct in6_addr *pfx, int plen, struct net_device *dev,
-		      unsigned long expires, unsigned flags)
+		      unsigned long expires, u32 flags)
 {
 	struct in6_rtmsg rtmsg;
 
@@ -1340,7 +1341,7 @@ addrconf_prefix_route(struct in6_addr *p
 	if (dev->type == ARPHRD_SIT && (dev->flags&IFF_POINTOPOINT))
 		rtmsg.rtmsg_flags |= RTF_NONEXTHOP;
 
-	ip6_route_add(&rtmsg, NULL, NULL);
+	ip6_route_add(&rtmsg, NULL, NULL, NULL);
 }
 
 /* Create "default" multicast route to the interface */
@@ -1357,7 +1358,7 @@ static void addrconf_add_mroute(struct n
 	rtmsg.rtmsg_ifindex = dev->ifindex;
 	rtmsg.rtmsg_flags = RTF_UP;
 	rtmsg.rtmsg_type = RTMSG_NEWROUTE;
-	ip6_route_add(&rtmsg, NULL, NULL);
+	ip6_route_add(&rtmsg, NULL, NULL, NULL);
 }
 
 static void sit_route_add(struct net_device *dev)
@@ -1374,7 +1375,7 @@ static void sit_route_add(struct net_dev
 	rtmsg.rtmsg_flags	= RTF_UP|RTF_NONEXTHOP;
 	rtmsg.rtmsg_ifindex	= dev->ifindex;
 
-	ip6_route_add(&rtmsg, NULL, NULL);
+	ip6_route_add(&rtmsg, NULL, NULL, NULL);
 }
 
 static void addrconf_add_lroute(struct net_device *dev)
@@ -1467,7 +1468,7 @@ void addrconf_prefix_rcv(struct net_devi
 		if (rt && ((rt->rt6i_flags & (RTF_GATEWAY | RTF_DEFAULT)) == 0)) {
 			if (rt->rt6i_flags&RTF_EXPIRES) {
 				if (valid_lft == 0) {
-					ip6_del_rt(rt, NULL, NULL);
+					ip6_del_rt(rt, NULL, NULL, NULL);
 					rt = NULL;
 				} else {
 					rt->rt6i_expires = rt_expires;
@@ -2229,7 +2230,7 @@ out:
 /*
  *	Duplicate Address Detection
  */
-static void addrconf_dad_start(struct inet6_ifaddr *ifp, int flags)
+static void addrconf_dad_start(struct inet6_ifaddr *ifp, u32 flags)
 {
 	struct inet6_dev *idev = ifp->idev;
 	struct net_device *dev = idev->dev;
@@ -2622,15 +2623,14 @@ inet6_rtm_newaddr(struct sk_buff *skb, s
 }
 
 static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa,
-			     u32 pid, u32 seq, int event)
+			     u32 pid, u32 seq, int event, unsigned int flags)
 {
 	struct ifaddrmsg *ifm;
 	struct nlmsghdr  *nlh;
 	struct ifa_cacheinfo ci;
 	unsigned char	 *b = skb->tail;
 
-	nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(*ifm));
-	if (pid) nlh->nlmsg_flags |= NLM_F_MULTI;
+	nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*ifm), flags);
 	ifm = NLMSG_DATA(nlh);
 	ifm->ifa_family = AF_INET6;
 	ifm->ifa_prefixlen = ifa->prefix_len;
@@ -2672,15 +2672,14 @@ rtattr_failure:
 }
 
 static int inet6_fill_ifmcaddr(struct sk_buff *skb, struct ifmcaddr6 *ifmca,
-				u32 pid, u32 seq, int event)
+				u32 pid, u32 seq, int event, u16 flags)
 {
 	struct ifaddrmsg *ifm;
 	struct nlmsghdr  *nlh;
 	struct ifa_cacheinfo ci;
 	unsigned char	 *b = skb->tail;
 
-	nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(*ifm));
-	if (pid) nlh->nlmsg_flags |= NLM_F_MULTI;
+	nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*ifm), flags);
 	ifm = NLMSG_DATA(nlh);
 	ifm->ifa_family = AF_INET6;	
 	ifm->ifa_prefixlen = 128;
@@ -2709,15 +2708,14 @@ rtattr_failure:
 }
 
 static int inet6_fill_ifacaddr(struct sk_buff *skb, struct ifacaddr6 *ifaca,
-				u32 pid, u32 seq, int event)
+				u32 pid, u32 seq, int event, unsigned int flags)
 {
 	struct ifaddrmsg *ifm;
 	struct nlmsghdr  *nlh;
 	struct ifa_cacheinfo ci;
 	unsigned char	 *b = skb->tail;
 
-	nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(*ifm));
-	if (pid) nlh->nlmsg_flags |= NLM_F_MULTI;
+	nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*ifm), flags);
 	ifm = NLMSG_DATA(nlh);
 	ifm->ifa_family = AF_INET6;	
 	ifm->ifa_prefixlen = 128;
@@ -2779,28 +2777,17 @@ static int inet6_dump_addr(struct sk_buf
 		read_lock_bh(&idev->lock);
 		switch (type) {
 		case UNICAST_ADDR:
-			/* unicast address */
+			/* unicast address incl. temp addr */
 			for (ifa = idev->addr_list; ifa;
 			     ifa = ifa->if_next, ip_idx++) {
 				if (ip_idx < s_ip_idx)
 					continue;
 				if ((err = inet6_fill_ifaddr(skb, ifa, 
 				    NETLINK_CB(cb->skb).pid, 
-				    cb->nlh->nlmsg_seq, RTM_NEWADDR)) <= 0)
+				    cb->nlh->nlmsg_seq, RTM_NEWADDR,
+				    NLM_F_MULTI)) <= 0)
 					goto done;
 			}
-			/* temp addr */
-#ifdef CONFIG_IPV6_PRIVACY
-			for (ifa = idev->tempaddr_list; ifa; 
-			     ifa = ifa->tmp_next, ip_idx++) {
-				if (ip_idx < s_ip_idx)
-					continue;
-				if ((err = inet6_fill_ifaddr(skb, ifa, 
-				    NETLINK_CB(cb->skb).pid, 
-				    cb->nlh->nlmsg_seq, RTM_NEWADDR)) <= 0) 
-					goto done;
-			}
-#endif
 			break;
 		case MULTICAST_ADDR:
 			/* multicast address */
@@ -2810,7 +2797,8 @@ static int inet6_dump_addr(struct sk_buf
 					continue;
 				if ((err = inet6_fill_ifmcaddr(skb, ifmca, 
 				    NETLINK_CB(cb->skb).pid, 
-				    cb->nlh->nlmsg_seq, RTM_GETMULTICAST)) <= 0)
+				    cb->nlh->nlmsg_seq, RTM_GETMULTICAST,
+				    NLM_F_MULTI)) <= 0)
 					goto done;
 			}
 			break;
@@ -2822,7 +2810,8 @@ static int inet6_dump_addr(struct sk_buf
 					continue;
 				if ((err = inet6_fill_ifacaddr(skb, ifaca, 
 				    NETLINK_CB(cb->skb).pid, 
-				    cb->nlh->nlmsg_seq, RTM_GETANYCAST)) <= 0) 
+				    cb->nlh->nlmsg_seq, RTM_GETANYCAST,
+				    NLM_F_MULTI)) <= 0) 
 					goto done;
 			}
 			break;
@@ -2872,7 +2861,7 @@ static void inet6_ifa_notify(int event, 
 		netlink_set_err(rtnl, 0, RTMGRP_IPV6_IFADDR, ENOBUFS);
 		return;
 	}
-	if (inet6_fill_ifaddr(skb, ifa, 0, 0, event) < 0) {
+	if (inet6_fill_ifaddr(skb, ifa, current->pid, 0, event, 0) < 0) {
 		kfree_skb(skb);
 		netlink_set_err(rtnl, 0, RTMGRP_IPV6_IFADDR, EINVAL);
 		return;
@@ -2907,7 +2896,7 @@ static void inline ipv6_store_devconf(st
 }
 
 static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev, 
-			     u32 pid, u32 seq, int event)
+			     u32 pid, u32 seq, int event, unsigned int flags)
 {
 	struct net_device	*dev = idev->dev;
 	__s32			*array = NULL;
@@ -2918,10 +2907,10 @@ static int inet6_fill_ifinfo(struct sk_b
 	__u32			mtu = dev->mtu;
 	struct ifla_cacheinfo	ci;
 
-	nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(*r));
-	if (pid) nlh->nlmsg_flags |= NLM_F_MULTI;
+	nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*r), flags);
 	r = NLMSG_DATA(nlh);
 	r->ifi_family = AF_INET6;
+	r->__ifi_pad = 0;
 	r->ifi_type = dev->type;
 	r->ifi_index = dev->ifindex;
 	r->ifi_flags = dev_get_flags(dev);
@@ -2986,7 +2975,7 @@ static int inet6_dump_ifinfo(struct sk_b
 		if ((idev = in6_dev_get(dev)) == NULL)
 			continue;
 		err = inet6_fill_ifinfo(skb, idev, NETLINK_CB(cb->skb).pid, 
-				cb->nlh->nlmsg_seq, RTM_NEWLINK);
+				cb->nlh->nlmsg_seq, RTM_NEWLINK, NLM_F_MULTI);
 		in6_dev_put(idev);
 		if (err <= 0)
 			break;
@@ -3008,7 +2997,7 @@ void inet6_ifinfo_notify(int event, stru
 		netlink_set_err(rtnl, 0, RTMGRP_IPV6_IFINFO, ENOBUFS);
 		return;
 	}
-	if (inet6_fill_ifinfo(skb, idev, 0, 0, event) < 0) {
+	if (inet6_fill_ifinfo(skb, idev, current->pid, 0, event, 0) < 0) {
 		kfree_skb(skb);
 		netlink_set_err(rtnl, 0, RTMGRP_IPV6_IFINFO, EINVAL);
 		return;
@@ -3018,23 +3007,23 @@ void inet6_ifinfo_notify(int event, stru
 }
 
 static int inet6_fill_prefix(struct sk_buff *skb, struct inet6_dev *idev,
-			struct prefix_info *pinfo, u32 pid, u32 seq, int event)
+			struct prefix_info *pinfo, u32 pid, u32 seq, 
+			int event, unsigned int flags)
 {
 	struct prefixmsg	*pmsg;
 	struct nlmsghdr 	*nlh;
 	unsigned char		*b = skb->tail;
 	struct prefix_cacheinfo	ci;
 
-	nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(*pmsg));
-	
-	if (pid) 
-		nlh->nlmsg_flags |= NLM_F_MULTI;
-	
+	nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*pmsg), flags);
 	pmsg = NLMSG_DATA(nlh);
 	pmsg->prefix_family = AF_INET6;
+	pmsg->prefix_pad1 = 0;
+	pmsg->prefix_pad2 = 0;
 	pmsg->prefix_ifindex = idev->dev->ifindex;
 	pmsg->prefix_len = pinfo->prefix_len;
 	pmsg->prefix_type = pinfo->type;
+	pmsg->prefix_pad3 = 0;
 	
 	pmsg->prefix_flags = 0;
 	if (pinfo->onlink)
@@ -3068,7 +3057,7 @@ static void inet6_prefix_notify(int even
 		netlink_set_err(rtnl, 0, RTMGRP_IPV6_PREFIX, ENOBUFS);
 		return;
 	}
-	if (inet6_fill_prefix(skb, idev, pinfo, 0, 0, event) < 0) {
+	if (inet6_fill_prefix(skb, idev, pinfo, current->pid, 0, event, 0) < 0) {
 		kfree_skb(skb);
 		netlink_set_err(rtnl, 0, RTMGRP_IPV6_PREFIX, EINVAL);
 		return;
@@ -3097,7 +3086,7 @@ static void __ipv6_ifa_notify(int event,
 	switch (event) {
 	case RTM_NEWADDR:
 		dst_hold(&ifp->rt->u.dst);
-		if (ip6_ins_rt(ifp->rt, NULL, NULL))
+		if (ip6_ins_rt(ifp->rt, NULL, NULL, NULL))
 			dst_release(&ifp->rt->u.dst);
 		if (ifp->idev->cnf.forwarding)
 			addrconf_join_anycast(ifp);
@@ -3107,7 +3096,7 @@ static void __ipv6_ifa_notify(int event,
 			addrconf_leave_anycast(ifp);
 		addrconf_leave_solict(ifp->idev, &ifp->addr);
 		dst_hold(&ifp->rt->u.dst);
-		if (ip6_del_rt(ifp->rt, NULL, NULL))
+		if (ip6_del_rt(ifp->rt, NULL, NULL, NULL))
 			dst_free(&ifp->rt->u.dst);
 		else
 			dst_release(&ifp->rt->u.dst);
@@ -3440,7 +3429,7 @@ static void addrconf_sysctl_register(str
 	 * by sysctl and we wouldn't want anyone to change it under our feet
 	 * (see SIOCSIFNAME).
 	 */	
-	dev_name = net_sysctl_strdup(dev_name);
+	dev_name = kstrdup(dev_name, GFP_KERNEL);
 	if (!dev_name)
 	    goto free;
 
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -774,7 +774,6 @@ static int __init inet6_init(void)
 	if (if6_proc_init())
 		goto proc_if6_fail;
 #endif
-	ipv6_packet_init();
 	ip6_route_init();
 	ip6_flowlabel_init();
 	err = addrconf_init();
@@ -791,6 +790,8 @@ static int __init inet6_init(void)
 	/* Init v6 transport protocols. */
 	udpv6_init();
 	tcpv6_init();
+
+	ipv6_packet_init();
 	err = 0;
 out:
 	return err;
@@ -798,7 +799,6 @@ out:
 addrconf_fail:
 	ip6_flowlabel_cleanup();
 	ip6_route_cleanup();
-	ipv6_packet_cleanup();
 #ifdef CONFIG_PROC_FS
 	if6_proc_exit();
 proc_if6_fail:
diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c
--- a/net/ipv6/ah6.c
+++ b/net/ipv6/ah6.c
@@ -339,7 +339,7 @@ static void ah6_err(struct sk_buff *skb,
 	xfrm_state_put(x);
 }
 
-static int ah6_init_state(struct xfrm_state *x, void *args)
+static int ah6_init_state(struct xfrm_state *x)
 {
 	struct ah_data *ahp = NULL;
 	struct xfrm_algo_desc *aalg_desc;
diff --git a/net/ipv6/anycast.c b/net/ipv6/anycast.c
--- a/net/ipv6/anycast.c
+++ b/net/ipv6/anycast.c
@@ -337,7 +337,7 @@ int ipv6_dev_ac_inc(struct net_device *d
 	write_unlock_bh(&idev->lock);
 
 	dst_hold(&rt->u.dst);
-	if (ip6_ins_rt(rt, NULL, NULL))
+	if (ip6_ins_rt(rt, NULL, NULL, NULL))
 		dst_release(&rt->u.dst);
 
 	addrconf_join_solict(dev, &aca->aca_addr);
@@ -380,7 +380,7 @@ int __ipv6_dev_ac_dec(struct inet6_dev *
 	addrconf_leave_solict(idev, &aca->aca_addr);
 
 	dst_hold(&aca->aca_rt->u.dst);
-	if (ip6_del_rt(aca->aca_rt, NULL, NULL))
+	if (ip6_del_rt(aca->aca_rt, NULL, NULL, NULL))
 		dst_free(&aca->aca_rt->u.dst);
 	else
 		dst_release(&aca->aca_rt->u.dst);
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c
--- a/net/ipv6/datagram.c
+++ b/net/ipv6/datagram.c
@@ -353,14 +353,14 @@ int ipv6_recv_error(struct sock *sk, str
 	err = copied;
 
 	/* Reset and regenerate socket error */
-	spin_lock_irq(&sk->sk_error_queue.lock);
+	spin_lock_bh(&sk->sk_error_queue.lock);
 	sk->sk_err = 0;
 	if ((skb2 = skb_peek(&sk->sk_error_queue)) != NULL) {
 		sk->sk_err = SKB_EXT_ERR(skb2)->ee.ee_errno;
-		spin_unlock_irq(&sk->sk_error_queue.lock);
+		spin_unlock_bh(&sk->sk_error_queue.lock);
 		sk->sk_error_report(sk);
 	} else {
-		spin_unlock_irq(&sk->sk_error_queue.lock);
+		spin_unlock_bh(&sk->sk_error_queue.lock);
 	}
 
 out_free_skb:	
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
--- a/net/ipv6/esp6.c
+++ b/net/ipv6/esp6.c
@@ -296,7 +296,7 @@ static void esp6_destroy(struct xfrm_sta
 	kfree(esp);
 }
 
-static int esp6_init_state(struct xfrm_state *x, void *args)
+static int esp6_init_state(struct xfrm_state *x)
 {
 	struct esp_data *esp = NULL;
 
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -394,7 +394,7 @@ insert_above:
  */
 
 static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt,
-    struct nlmsghdr *nlh)
+		struct nlmsghdr *nlh,  struct netlink_skb_parms *req)
 {
 	struct rt6_info *iter = NULL;
 	struct rt6_info **ins;
@@ -449,7 +449,7 @@ out:
 	*ins = rt;
 	rt->rt6i_node = fn;
 	atomic_inc(&rt->rt6i_ref);
-	inet6_rt_notify(RTM_NEWROUTE, rt, nlh);
+	inet6_rt_notify(RTM_NEWROUTE, rt, nlh, req);
 	rt6_stats.fib_rt_entries++;
 
 	if ((fn->fn_flags & RTN_RTINFO) == 0) {
@@ -479,7 +479,8 @@ void fib6_force_start_gc(void)
  *	with source addr info in sub-trees
  */
 
-int fib6_add(struct fib6_node *root, struct rt6_info *rt, struct nlmsghdr *nlh, void *_rtattr)
+int fib6_add(struct fib6_node *root, struct rt6_info *rt, 
+		struct nlmsghdr *nlh, void *_rtattr, struct netlink_skb_parms *req)
 {
 	struct fib6_node *fn;
 	int err = -ENOMEM;
@@ -552,7 +553,7 @@ int fib6_add(struct fib6_node *root, str
 	}
 #endif
 
-	err = fib6_add_rt2node(fn, rt, nlh);
+	err = fib6_add_rt2node(fn, rt, nlh, req);
 
 	if (err == 0) {
 		fib6_start_gc(rt);
@@ -859,7 +860,7 @@ static struct fib6_node * fib6_repair_tr
 }
 
 static void fib6_del_route(struct fib6_node *fn, struct rt6_info **rtp,
-    struct nlmsghdr *nlh, void *_rtattr)
+    struct nlmsghdr *nlh, void *_rtattr, struct netlink_skb_parms *req)
 {
 	struct fib6_walker_t *w;
 	struct rt6_info *rt = *rtp;
@@ -915,11 +916,11 @@ static void fib6_del_route(struct fib6_n
 		if (atomic_read(&rt->rt6i_ref) != 1) BUG();
 	}
 
-	inet6_rt_notify(RTM_DELROUTE, rt, nlh);
+	inet6_rt_notify(RTM_DELROUTE, rt, nlh, req);
 	rt6_release(rt);
 }
 
-int fib6_del(struct rt6_info *rt, struct nlmsghdr *nlh, void *_rtattr)
+int fib6_del(struct rt6_info *rt, struct nlmsghdr *nlh, void *_rtattr, struct netlink_skb_parms *req)
 {
 	struct fib6_node *fn = rt->rt6i_node;
 	struct rt6_info **rtp;
@@ -944,7 +945,7 @@ int fib6_del(struct rt6_info *rt, struct
 
 	for (rtp = &fn->leaf; *rtp; rtp = &(*rtp)->u.next) {
 		if (*rtp == rt) {
-			fib6_del_route(fn, rtp, nlh, _rtattr);
+			fib6_del_route(fn, rtp, nlh, _rtattr, req);
 			return 0;
 		}
 	}
@@ -1073,7 +1074,7 @@ static int fib6_clean_node(struct fib6_w
 		res = c->func(rt, c->arg);
 		if (res < 0) {
 			w->leaf = rt;
-			res = fib6_del(rt, NULL, NULL);
+			res = fib6_del(rt, NULL, NULL, NULL);
 			if (res) {
 #if RT6_DEBUG >= 2
 				printk(KERN_DEBUG "fib6_clean_node: del failed: rt=%p@%p err=%d\n", rt, rt->rt6i_node, res);
diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c
--- a/net/ipv6/ip6_flowlabel.c
+++ b/net/ipv6/ip6_flowlabel.c
@@ -244,7 +244,6 @@ struct ipv6_txoptions *fl6_merge_options
 		opt_space->opt_nflen = 0;
 	}
 	opt_space->dst1opt = fopt->dst1opt;
-	opt_space->auth = fopt->auth;
 	opt_space->opt_flen = fopt->opt_flen;
 	return opt_space;
 }
diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c
--- a/net/ipv6/ip6_input.c
+++ b/net/ipv6/ip6_input.c
@@ -198,12 +198,13 @@ resubmit:
 		if (!raw_sk) {
 			if (xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) {
 				IP6_INC_STATS_BH(IPSTATS_MIB_INUNKNOWNPROTOS);
-				icmpv6_param_prob(skb, ICMPV6_UNK_NEXTHDR, nhoff);
+				icmpv6_send(skb, ICMPV6_PARAMPROB,
+				            ICMPV6_UNK_NEXTHDR, nhoff,
+				            skb->dev);
 			}
-		} else {
+		} else
 			IP6_INC_STATS_BH(IPSTATS_MIB_INDELIVERS);
-			kfree_skb(skb);
-		}
+		kfree_skb(skb);
 	}
 	rcu_read_unlock();
 	return 0;
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -465,7 +465,6 @@ static void ip6_copy_metadata(struct sk_
 	to->pkt_type = from->pkt_type;
 	to->priority = from->priority;
 	to->protocol = from->protocol;
-	to->security = from->security;
 	dst_release(to->dst);
 	to->dst = dst_clone(from->dst);
 	to->dev = from->dev;
@@ -484,9 +483,6 @@ static void ip6_copy_metadata(struct sk_
 	to->nf_bridge = from->nf_bridge;
 	nf_bridge_get(to->nf_bridge);
 #endif
-#ifdef CONFIG_NETFILTER_DEBUG
-	to->nf_debug = from->nf_debug;
-#endif
 #endif
 }
 
@@ -796,13 +792,8 @@ int ip6_dst_lookup(struct sock *sk, stru
 	if (ipv6_addr_any(&fl->fl6_src)) {
 		err = ipv6_get_saddr(*dst, &fl->fl6_dst, &fl->fl6_src);
 
-		if (err) {
-#if IP6_DEBUG >= 2
-			printk(KERN_DEBUG "ip6_dst_lookup: "
-			       "no available source address\n");
-#endif
+		if (err)
 			goto out_err_release;
-		}
 	}
 
 	return 0;
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -1110,11 +1110,39 @@ ip6ip6_fb_tnl_dev_init(struct net_device
 	return 0;
 }
 
+#ifdef CONFIG_INET6_TUNNEL
 static struct xfrm6_tunnel ip6ip6_handler = {
-	.handler = ip6ip6_rcv,
-	.err_handler = ip6ip6_err,
+	.handler	= ip6ip6_rcv,
+	.err_handler	= ip6ip6_err,
 };
 
+static inline int ip6ip6_register(void)
+{
+	return xfrm6_tunnel_register(&ip6ip6_handler);
+}
+
+static inline int ip6ip6_unregister(void)
+{
+	return xfrm6_tunnel_deregister(&ip6ip6_handler);
+}
+#else
+static struct inet6_protocol xfrm6_tunnel_protocol = {
+	.handler	= ip6ip6_rcv,
+	.err_handler	= ip6ip6_err,
+	.flags		= INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL,
+};
+
+static inline int ip6ip6_register(void)
+{
+	return inet6_add_protocol(&xfrm6_tunnel_protocol, IPPROTO_IPV6);
+}
+
+static inline int ip6ip6_unregister(void)
+{
+	return inet6_del_protocol(&xfrm6_tunnel_protocol, IPPROTO_IPV6);
+}
+#endif
+
 /**
  * ip6_tunnel_init - register protocol and reserve needed resources
  *
@@ -1125,7 +1153,7 @@ static int __init ip6_tunnel_init(void)
 {
 	int  err;
 
-	if (xfrm6_tunnel_register(&ip6ip6_handler) < 0) {
+	if (ip6ip6_register() < 0) {
 		printk(KERN_ERR "ip6ip6 init: can't register tunnel\n");
 		return -EAGAIN;
 	}
@@ -1144,7 +1172,7 @@ static int __init ip6_tunnel_init(void)
 	}
 	return 0;
 fail:
-	xfrm6_tunnel_deregister(&ip6ip6_handler);
+	ip6ip6_unregister();
 	return err;
 }
 
@@ -1154,7 +1182,7 @@ fail:
 
 static void __exit ip6_tunnel_cleanup(void)
 {
-	if (xfrm6_tunnel_deregister(&ip6ip6_handler) < 0)
+	if (ip6ip6_unregister() < 0)
 		printk(KERN_INFO "ip6ip6 close: can't deregister tunnel\n");
 
 	unregister_netdev(ip6ip6_fb_tnl_dev);
diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c
--- a/net/ipv6/ipcomp6.c
+++ b/net/ipv6/ipcomp6.c
@@ -234,14 +234,9 @@ static struct xfrm_state *ipcomp6_tunnel
 	t->props.mode = 1;
 	memcpy(t->props.saddr.a6, x->props.saddr.a6, sizeof(struct in6_addr));
 
-	t->type = xfrm_get_type(IPPROTO_IPV6, t->props.family);
-	if (t->type == NULL)
+	if (xfrm_init_state(t))
 		goto error;
 
-	if (t->type->init_state(t, NULL))
-		goto error;
-
-	t->km.state = XFRM_STATE_VALID;
 	atomic_set(&t->tunnel_users, 1);
 
 out:
@@ -359,7 +354,7 @@ static struct crypto_tfm **ipcomp6_alloc
 	int cpu;
 
 	/* This can be any valid CPU ID so we don't need locking. */
-	cpu = smp_processor_id();
+	cpu = raw_smp_processor_id();
 
 	list_for_each_entry(pos, &ipcomp6_tfms_list, list) {
 		struct crypto_tfm *tfm;
@@ -420,7 +415,7 @@ static void ipcomp6_destroy(struct xfrm_
 	xfrm6_tunnel_free_spi((xfrm_address_t *)&x->props.saddr);
 }
 
-static int ipcomp6_init_state(struct xfrm_state *x, void *args)
+static int ipcomp6_init_state(struct xfrm_state *x)
 {
 	int err;
 	struct ipcomp_data *ipcd;
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -423,11 +423,12 @@ done:
 			psin6 = (struct sockaddr_in6 *)&greqs.gsr_group;
 			retv = ipv6_sock_mc_join(sk, greqs.gsr_interface,
 				&psin6->sin6_addr);
-			if (retv)
+			/* prior join w/ different source is ok */
+			if (retv && retv != -EADDRINUSE)
 				break;
 			omode = MCAST_INCLUDE;
 			add = 1;
-		} else /*IP_DROP_SOURCE_MEMBERSHIP */ {
+		} else /* MCAST_LEAVE_SOURCE_GROUP */ {
 			omode = MCAST_INCLUDE;
 			add = 0;
 		}
@@ -503,6 +504,9 @@ done:
 		break;
 	case IPV6_IPSEC_POLICY:
 	case IPV6_XFRM_POLICY:
+		retv = -EPERM;
+		if (!capable(CAP_NET_ADMIN))
+			break;
 		retv = xfrm_user_policy(sk, optname, optval, optlen);
 		break;
 
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -188,6 +188,16 @@ int ipv6_sock_mc_join(struct sock *sk, i
 	if (!ipv6_addr_is_multicast(addr))
 		return -EINVAL;
 
+	read_lock_bh(&ipv6_sk_mc_lock);
+	for (mc_lst=np->ipv6_mc_list; mc_lst; mc_lst=mc_lst->next) {
+		if ((ifindex == 0 || mc_lst->ifindex == ifindex) &&
+		    ipv6_addr_equal(&mc_lst->addr, addr)) {
+			read_unlock_bh(&ipv6_sk_mc_lock);
+			return -EADDRINUSE;
+		}
+	}
+	read_unlock_bh(&ipv6_sk_mc_lock);
+
 	mc_lst = sock_kmalloc(sk, sizeof(struct ipv6_mc_socklist), GFP_KERNEL);
 
 	if (mc_lst == NULL)
@@ -271,7 +281,7 @@ int ipv6_sock_mc_drop(struct sock *sk, i
 	}
 	write_unlock_bh(&ipv6_sk_mc_lock);
 
-	return -ENOENT;
+	return -EADDRNOTAVAIL;
 }
 
 static struct inet6_dev *ip6_mc_find_dev(struct in6_addr *group, int ifindex)
@@ -349,6 +359,7 @@ int ip6_mc_source(int add, int omode, st
 	struct ipv6_pinfo *inet6 = inet6_sk(sk);
 	struct ip6_sf_socklist *psl;
 	int i, j, rv;
+	int leavegroup = 0;
 	int err;
 
 	if (pgsr->gsr_group.ss_family != AF_INET6 ||
@@ -368,18 +379,23 @@ int ip6_mc_source(int add, int omode, st
 
 	err = -EADDRNOTAVAIL;
 
+	read_lock_bh(&ipv6_sk_mc_lock);
 	for (pmc=inet6->ipv6_mc_list; pmc; pmc=pmc->next) {
 		if (pgsr->gsr_interface && pmc->ifindex != pgsr->gsr_interface)
 			continue;
 		if (ipv6_addr_equal(&pmc->addr, group))
 			break;
 	}
-	if (!pmc)		/* must have a prior join */
+	if (!pmc) {		/* must have a prior join */
+		err = -EINVAL;
 		goto done;
+	}
 	/* if a source filter was set, must be the same mode as before */
 	if (pmc->sflist) {
-		if (pmc->sfmode != omode)
+		if (pmc->sfmode != omode) {
+			err = -EINVAL;
 			goto done;
+		}
 	} else if (pmc->sfmode != omode) {
 		/* allow mode switches for empty-set filters */
 		ip6_mc_add_src(idev, group, omode, 0, NULL, 0);
@@ -390,7 +406,7 @@ int ip6_mc_source(int add, int omode, st
 	psl = pmc->sflist;
 	if (!add) {
 		if (!psl)
-			goto done;
+			goto done;	/* err = -EADDRNOTAVAIL */
 		rv = !0;
 		for (i=0; i<psl->sl_count; i++) {
 			rv = memcmp(&psl->sl_addr[i], source,
@@ -399,7 +415,13 @@ int ip6_mc_source(int add, int omode, st
 				break;
 		}
 		if (rv)		/* source not found */
+			goto done;	/* err = -EADDRNOTAVAIL */
+
+		/* special case - (INCLUDE, empty) == LEAVE_GROUP */
+		if (psl->sl_count == 1 && omode == MCAST_INCLUDE) {
+			leavegroup = 1;
 			goto done;
+		}
 
 		/* update the interface filter */
 		ip6_mc_del_src(idev, group, omode, 1, source, 1);
@@ -453,9 +475,12 @@ int ip6_mc_source(int add, int omode, st
 	/* update the interface list */
 	ip6_mc_add_src(idev, group, omode, 1, source, 1);
 done:
+	read_unlock_bh(&ipv6_sk_mc_lock);
 	read_unlock_bh(&idev->lock);
 	in6_dev_put(idev);
 	dev_put(dev);
+	if (leavegroup)
+		return ipv6_sock_mc_drop(sk, pgsr->gsr_interface, group);
 	return err;
 }
 
@@ -467,6 +492,7 @@ int ip6_mc_msfilter(struct sock *sk, str
 	struct inet6_dev *idev;
 	struct ipv6_pinfo *inet6 = inet6_sk(sk);
 	struct ip6_sf_socklist *newpsl, *psl;
+	int leavegroup = 0;
 	int i, err;
 
 	group = &((struct sockaddr_in6 *)&gsf->gf_group)->sin6_addr;
@@ -482,7 +508,12 @@ int ip6_mc_msfilter(struct sock *sk, str
 	if (!idev)
 		return -ENODEV;
 	dev = idev->dev;
-	err = -EADDRNOTAVAIL;
+
+	err = 0;
+	if (gsf->gf_fmode == MCAST_INCLUDE && gsf->gf_numsrc == 0) {
+		leavegroup = 1;
+		goto done;
+	}
 
 	for (pmc=inet6->ipv6_mc_list; pmc; pmc=pmc->next) {
 		if (pmc->ifindex != gsf->gf_interface)
@@ -490,8 +521,10 @@ int ip6_mc_msfilter(struct sock *sk, str
 		if (ipv6_addr_equal(&pmc->addr, group))
 			break;
 	}
-	if (!pmc)		/* must have a prior join */
+	if (!pmc) {		/* must have a prior join */
+		err = -EINVAL;
 		goto done;
+	}
 	if (gsf->gf_numsrc) {
 		newpsl = (struct ip6_sf_socklist *)sock_kmalloc(sk,
 				IP6_SFLSIZE(gsf->gf_numsrc), GFP_ATOMIC);
@@ -523,10 +556,13 @@ int ip6_mc_msfilter(struct sock *sk, str
 		(void) ip6_mc_del_src(idev, group, pmc->sfmode, 0, NULL, 0);
 	pmc->sflist = newpsl;
 	pmc->sfmode = gsf->gf_fmode;
+	err = 0;
 done:
 	read_unlock_bh(&idev->lock);
 	in6_dev_put(idev);
 	dev_put(dev);
+	if (leavegroup)
+		err = ipv6_sock_mc_drop(sk, gsf->gf_interface, group);
 	return err;
 }
 
@@ -1280,15 +1316,6 @@ static struct sk_buff *mld_newpack(struc
 		return NULL;
 
 	skb_reserve(skb, LL_RESERVED_SPACE(dev));
-	if (dev->hard_header) {
-		unsigned char ha[MAX_ADDR_LEN];
-
-		ndisc_mc_map(&mld2_all_mcr, ha, dev, 1);
-		if (dev->hard_header(skb, dev, ETH_P_IPV6,ha,NULL,size) < 0) {
-			kfree_skb(skb);
-			return NULL;
-		}
-	}
 
 	if (ipv6_get_lladdr(dev, &addr_buf)) {
 		/* <draft-ietf-magma-mld-source-05.txt>:
@@ -1312,6 +1339,30 @@ static struct sk_buff *mld_newpack(struc
 	return skb;
 }
 
+static inline int mld_dev_queue_xmit2(struct sk_buff *skb)
+{
+	struct net_device *dev = skb->dev;
+
+	if (dev->hard_header) {
+		unsigned char ha[MAX_ADDR_LEN];
+		int err;
+
+		ndisc_mc_map(&skb->nh.ipv6h->daddr, ha, dev, 1);
+		err = dev->hard_header(skb, dev, ETH_P_IPV6, ha, NULL, skb->len);
+		if (err < 0) {
+			kfree_skb(skb);
+			return err;
+		}
+	}
+	return dev_queue_xmit(skb);
+}
+
+static inline int mld_dev_queue_xmit(struct sk_buff *skb)
+{
+	return NF_HOOK(PF_INET6, NF_IP6_POST_ROUTING, skb, NULL, skb->dev,
+	               mld_dev_queue_xmit2);
+}
+
 static void mld_sendpack(struct sk_buff *skb)
 {
 	struct ipv6hdr *pip6 = skb->nh.ipv6h;
@@ -1329,7 +1380,7 @@ static void mld_sendpack(struct sk_buff 
 	pmr->csum = csum_ipv6_magic(&pip6->saddr, &pip6->daddr, mldlen,
 		IPPROTO_ICMPV6, csum_partial(skb->h.raw, mldlen, 0));
 	err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dev,
-		dev_queue_xmit);
+		mld_dev_queue_xmit);
 	if (!err) {
 		ICMP6_INC_STATS(idev,ICMP6_MIB_OUTMSGS);
 		IP6_INC_STATS(IPSTATS_MIB_OUTMCASTPKTS);
@@ -1635,12 +1686,6 @@ static void igmp6_send(struct in6_addr *
 	}
 
 	skb_reserve(skb, LL_RESERVED_SPACE(dev));
-	if (dev->hard_header) {
-		unsigned char ha[MAX_ADDR_LEN];
-		ndisc_mc_map(snd_addr, ha, dev, 1);
-		if (dev->hard_header(skb, dev, ETH_P_IPV6, ha, NULL, full_len) < 0)
-			goto out;
-	}
 
 	if (ipv6_get_lladdr(dev, &addr_buf)) {
 		/* <draft-ietf-magma-mld-source-05.txt>:
@@ -1668,7 +1713,7 @@ static void igmp6_send(struct in6_addr *
 	idev = in6_dev_get(skb->dev);
 
 	err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dev,
-		dev_queue_xmit);
+		mld_dev_queue_xmit);
 	if (!err) {
 		if (type == ICMPV6_MGM_REDUCTION)
 			ICMP6_INC_STATS(idev, ICMP6_MIB_OUTGROUPMEMBREDUCTIONS);
@@ -1682,10 +1727,6 @@ static void igmp6_send(struct in6_addr *
 	if (likely(idev != NULL))
 		in6_dev_put(idev);
 	return;
-
-out:
-	IP6_INC_STATS(IPSTATS_MIB_OUTDISCARDS);
-	kfree_skb(skb);
 }
 
 static int ip6_mc_del1_src(struct ifmcaddr6 *pmc, int sfmode,
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -955,7 +955,7 @@ static void ndisc_recv_na(struct sk_buff
 			struct rt6_info *rt;
 			rt = rt6_get_dflt_router(saddr, dev);
 			if (rt)
-				ip6_del_rt(rt, NULL, NULL);
+				ip6_del_rt(rt, NULL, NULL, NULL);
 		}
 
 out:
@@ -1096,7 +1096,7 @@ static void ndisc_router_discovery(struc
 
 	if (rt && lifetime == 0) {
 		neigh_clone(neigh);
-		ip6_del_rt(rt, NULL, NULL);
+		ip6_del_rt(rt, NULL, NULL, NULL);
 		rt = NULL;
 	}
 
diff --git a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c
--- a/net/ipv6/netfilter/ip6_queue.c
+++ b/net/ipv6/netfilter/ip6_queue.c
@@ -76,7 +76,9 @@ static DECLARE_MUTEX(ipqnl_sem);
 static void
 ipq_issue_verdict(struct ipq_queue_entry *entry, int verdict)
 {
+	local_bh_disable();
 	nf_reinject(entry->skb, entry->info, verdict);
+	local_bh_enable();
 	kfree(entry);
 }
 
@@ -209,6 +211,12 @@ ipq_build_packet_message(struct ipq_queu
 		break;
 	
 	case IPQ_COPY_PACKET:
+		if (entry->skb->ip_summed == CHECKSUM_HW &&
+		    (*errp = skb_checksum_help(entry->skb,
+		                               entry->info->outdev == NULL))) {
+			read_unlock_bh(&queue_lock);
+			return NULL;
+		}
 		if (copy_range == 0 || copy_range > entry->skb->len)
 			data_len = entry->skb->len;
 		else
@@ -379,6 +387,7 @@ ipq_mangle_ipv6(ipq_verdict_msg_t *v, st
 	if (!skb_ip_make_writable(&e->skb, v->data_len))
 		return -ENOMEM;
 	memcpy(e->skb->data, v->payload, v->data_len);
+	e->skb->ip_summed = CHECKSUM_NONE;
 	e->skb->nfcache |= NFC_ALTERED;
 
 	/*
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -71,7 +71,6 @@ static DECLARE_MUTEX(ip6t_mutex);
 /* Must have mutex */
 #define ASSERT_READ_LOCK(x) IP_NF_ASSERT(down_trylock(&ip6t_mutex) != 0)
 #define ASSERT_WRITE_LOCK(x) IP_NF_ASSERT(down_trylock(&ip6t_mutex) != 0)
-#include <linux/netfilter_ipv4/lockhelp.h>
 #include <linux/netfilter_ipv4/listhelp.h>
 
 #if 0
diff --git a/net/ipv6/netfilter/ip6t_LOG.c b/net/ipv6/netfilter/ip6t_LOG.c
--- a/net/ipv6/netfilter/ip6t_LOG.c
+++ b/net/ipv6/netfilter/ip6t_LOG.c
@@ -366,8 +366,6 @@ ip6t_log_packet(unsigned int hooknum,
 		const char *level_string,
 		const char *prefix)
 {
-	struct ipv6hdr *ipv6h = skb->nh.ipv6h;
-
 	spin_lock_bh(&log_lock);
 	printk(level_string);
 	printk("%sIN=%s OUT=%s ",
@@ -375,41 +373,30 @@ ip6t_log_packet(unsigned int hooknum,
 		in ? in->name : "",
 		out ? out->name : "");
 	if (in && !out) {
+		unsigned int len;
 		/* MAC logging for input chain only. */
 		printk("MAC=");
-		if (skb->dev && skb->dev->hard_header_len && skb->mac.raw != (void*)ipv6h) {
-			if (skb->dev->type != ARPHRD_SIT){
-			  int i;
-			  unsigned char *p = skb->mac.raw;
-			  for (i = 0; i < skb->dev->hard_header_len; i++,p++)
-				printk("%02x%c", *p,
-			       		i==skb->dev->hard_header_len - 1
-			       		? ' ':':');
-			} else {
-			  int i;
-			  unsigned char *p = skb->mac.raw;
-			  if ( p - (ETH_ALEN*2+2) > skb->head ){
-			    p -= (ETH_ALEN+2);
-			    for (i = 0; i < (ETH_ALEN); i++,p++)
-				printk("%02x%s", *p,
-					i == ETH_ALEN-1 ? "->" : ":");
-			    p -= (ETH_ALEN*2);
-			    for (i = 0; i < (ETH_ALEN); i++,p++)
-				printk("%02x%c", *p,
-					i == ETH_ALEN-1 ? ' ' : ':');
-			  }
-			  
-			  if ((skb->dev->addr_len == 4) &&
-			      skb->dev->hard_header_len > 20){
-			    printk("TUNNEL=");
-			    p = skb->mac.raw + 12;
-			    for (i = 0; i < 4; i++,p++)
-				printk("%3d%s", *p,
-					i == 3 ? "->" : ".");
-			    for (i = 0; i < 4; i++,p++)
-				printk("%3d%c", *p,
-					i == 3 ? ' ' : '.');
-			  }
+		if (skb->dev && (len = skb->dev->hard_header_len) &&
+		    skb->mac.raw != skb->nh.raw) {
+			unsigned char *p = skb->mac.raw;
+			int i;
+
+			if (skb->dev->type == ARPHRD_SIT &&
+			    (p -= ETH_HLEN) < skb->head)
+				p = NULL;
+
+			if (p != NULL) {
+				for (i = 0; i < len; i++)
+					printk("%02x%s", p[i],
+					       i == len - 1 ? "" : ":");
+			}
+			printk(" ");
+
+			if (skb->dev->type == ARPHRD_SIT) {
+				struct iphdr *iph = (struct iphdr *)skb->mac.raw;
+				printk("TUNNEL=%u.%u.%u.%u->%u.%u.%u.%u ",
+				       NIPQUAD(iph->saddr),
+				       NIPQUAD(iph->daddr));
 			}
 		} else
 			printk(" ");
diff --git a/net/ipv6/netfilter/ip6table_raw.c b/net/ipv6/netfilter/ip6table_raw.c
--- a/net/ipv6/netfilter/ip6table_raw.c
+++ b/net/ipv6/netfilter/ip6table_raw.c
@@ -129,13 +129,15 @@ static struct nf_hook_ops ip6t_ops[] = {
 	  .hook = ip6t_hook, 
 	  .pf = PF_INET6,
 	  .hooknum = NF_IP6_PRE_ROUTING,
-	  .priority = NF_IP6_PRI_FIRST
+	  .priority = NF_IP6_PRI_FIRST,
+	  .owner = THIS_MODULE,
 	},
 	{
 	  .hook = ip6t_hook, 
 	  .pf = PF_INET6, 
 	  .hooknum = NF_IP6_LOCAL_OUT,
-	  .priority = NF_IP6_PRI_FIRST
+	  .priority = NF_IP6_PRI_FIRST,
+	  .owner = THIS_MODULE,
 	},
 };
 
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -328,6 +328,8 @@ int rawv6_rcv(struct sock *sk, struct sk
 
 	if (skb->ip_summed != CHECKSUM_UNNECESSARY) {
 		if (skb->ip_summed == CHECKSUM_HW) {
+			skb_postpull_rcsum(skb, skb->nh.raw,
+			                   skb->h.raw - skb->nh.raw);
 			skb->ip_summed = CHECKSUM_UNNECESSARY;
 			if (csum_ipv6_magic(&skb->nh.ipv6h->saddr,
 					    &skb->nh.ipv6h->daddr,
@@ -434,12 +436,12 @@ csum_copy_err:
 	/* Clear queue. */
 	if (flags&MSG_PEEK) {
 		int clear = 0;
-		spin_lock_irq(&sk->sk_receive_queue.lock);
+		spin_lock_bh(&sk->sk_receive_queue.lock);
 		if (skb == skb_peek(&sk->sk_receive_queue)) {
 			__skb_unlink(skb, &sk->sk_receive_queue);
 			clear = 1;
 		}
-		spin_unlock_irq(&sk->sk_receive_queue.lock);
+		spin_unlock_bh(&sk->sk_receive_queue.lock);
 		if (clear)
 			kfree_skb(skb);
 	}
@@ -971,11 +973,11 @@ static int rawv6_ioctl(struct sock *sk, 
 			struct sk_buff *skb;
 			int amount = 0;
 
-			spin_lock_irq(&sk->sk_receive_queue.lock);
+			spin_lock_bh(&sk->sk_receive_queue.lock);
 			skb = skb_peek(&sk->sk_receive_queue);
 			if (skb != NULL)
 				amount = skb->tail - skb->h.raw;
-			spin_unlock_irq(&sk->sk_receive_queue.lock);
+			spin_unlock_bh(&sk->sk_receive_queue.lock);
 			return put_user(amount, (int __user *)arg);
 		}
 
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -384,12 +384,13 @@ struct rt6_info *rt6_lookup(struct in6_a
    be destroyed.
  */
 
-int ip6_ins_rt(struct rt6_info *rt, struct nlmsghdr *nlh, void *_rtattr)
+int ip6_ins_rt(struct rt6_info *rt, struct nlmsghdr *nlh,
+		void *_rtattr, struct netlink_skb_parms *req)
 {
 	int err;
 
 	write_lock_bh(&rt6_lock);
-	err = fib6_add(&ip6_routing_table, rt, nlh, _rtattr);
+	err = fib6_add(&ip6_routing_table, rt, nlh, _rtattr, req);
 	write_unlock_bh(&rt6_lock);
 
 	return err;
@@ -400,7 +401,7 @@ int ip6_ins_rt(struct rt6_info *rt, stru
  */
 
 static struct rt6_info *rt6_cow(struct rt6_info *ort, struct in6_addr *daddr,
-				struct in6_addr *saddr)
+				struct in6_addr *saddr, struct netlink_skb_parms *req)
 {
 	int err;
 	struct rt6_info *rt;
@@ -432,7 +433,7 @@ static struct rt6_info *rt6_cow(struct r
 
 		dst_hold(&rt->u.dst);
 
-		err = ip6_ins_rt(rt, NULL, NULL);
+		err = ip6_ins_rt(rt, NULL, NULL, req);
 		if (err == 0)
 			return rt;
 
@@ -491,7 +492,8 @@ restart:
 		read_unlock_bh(&rt6_lock);
 
 		nrt = rt6_cow(rt, &skb->nh.ipv6h->daddr,
-			      &skb->nh.ipv6h->saddr);
+			      &skb->nh.ipv6h->saddr,
+			      &NETLINK_CB(skb));
 
 		dst_release(&rt->u.dst);
 		rt = nrt;
@@ -551,7 +553,7 @@ restart:
 		dst_hold(&rt->u.dst);
 		read_unlock_bh(&rt6_lock);
 
-		nrt = rt6_cow(rt, &fl->fl6_dst, &fl->fl6_src);
+		nrt = rt6_cow(rt, &fl->fl6_dst, &fl->fl6_src, NULL);
 
 		dst_release(&rt->u.dst);
 		rt = nrt;
@@ -598,7 +600,7 @@ static struct dst_entry *ip6_negative_ad
 
 	if (rt) {
 		if (rt->rt6i_flags & RTF_CACHE)
-			ip6_del_rt(rt, NULL, NULL);
+			ip6_del_rt(rt, NULL, NULL, NULL);
 		else
 			dst_release(dst);
 	}
@@ -787,7 +789,8 @@ int ipv6_get_hoplimit(struct net_device 
  *
  */
 
-int ip6_route_add(struct in6_rtmsg *rtmsg, struct nlmsghdr *nlh, void *_rtattr)
+int ip6_route_add(struct in6_rtmsg *rtmsg, struct nlmsghdr *nlh, 
+		void *_rtattr, struct netlink_skb_parms *req)
 {
 	int err;
 	struct rtmsg *r;
@@ -974,7 +977,7 @@ install_route:
 		rt->u.dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(dst_mtu(&rt->u.dst));
 	rt->u.dst.dev = dev;
 	rt->rt6i_idev = idev;
-	return ip6_ins_rt(rt, nlh, _rtattr);
+	return ip6_ins_rt(rt, nlh, _rtattr, req);
 
 out:
 	if (dev)
@@ -986,7 +989,7 @@ out:
 	return err;
 }
 
-int ip6_del_rt(struct rt6_info *rt, struct nlmsghdr *nlh, void *_rtattr)
+int ip6_del_rt(struct rt6_info *rt, struct nlmsghdr *nlh, void *_rtattr, struct netlink_skb_parms *req)
 {
 	int err;
 
@@ -994,7 +997,7 @@ int ip6_del_rt(struct rt6_info *rt, stru
 
 	rt6_reset_dflt_pointer(NULL);
 
-	err = fib6_del(rt, nlh, _rtattr);
+	err = fib6_del(rt, nlh, _rtattr, req);
 	dst_release(&rt->u.dst);
 
 	write_unlock_bh(&rt6_lock);
@@ -1002,7 +1005,7 @@ int ip6_del_rt(struct rt6_info *rt, stru
 	return err;
 }
 
-static int ip6_route_del(struct in6_rtmsg *rtmsg, struct nlmsghdr *nlh, void *_rtattr)
+static int ip6_route_del(struct in6_rtmsg *rtmsg, struct nlmsghdr *nlh, void *_rtattr, struct netlink_skb_parms *req)
 {
 	struct fib6_node *fn;
 	struct rt6_info *rt;
@@ -1029,7 +1032,7 @@ static int ip6_route_del(struct in6_rtms
 			dst_hold(&rt->u.dst);
 			read_unlock_bh(&rt6_lock);
 
-			return ip6_del_rt(rt, nlh, _rtattr);
+			return ip6_del_rt(rt, nlh, _rtattr, req);
 		}
 	}
 	read_unlock_bh(&rt6_lock);
@@ -1136,11 +1139,11 @@ source_ok:
 	nrt->u.dst.metrics[RTAX_MTU-1] = ipv6_get_mtu(neigh->dev);
 	nrt->u.dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(dst_mtu(&nrt->u.dst));
 
-	if (ip6_ins_rt(nrt, NULL, NULL))
+	if (ip6_ins_rt(nrt, NULL, NULL, NULL))
 		goto out;
 
 	if (rt->rt6i_flags&RTF_CACHE) {
-		ip6_del_rt(rt, NULL, NULL);
+		ip6_del_rt(rt, NULL, NULL, NULL);
 		return;
 	}
 
@@ -1204,7 +1207,7 @@ void rt6_pmtu_discovery(struct in6_addr 
 	   2. It is gatewayed route or NONEXTHOP route. Action: clone it.
 	 */
 	if (!rt->rt6i_nexthop && !(rt->rt6i_flags & RTF_NONEXTHOP)) {
-		nrt = rt6_cow(rt, daddr, saddr);
+		nrt = rt6_cow(rt, daddr, saddr, NULL);
 		if (!nrt->u.dst.error) {
 			nrt->u.dst.metrics[RTAX_MTU-1] = pmtu;
 			if (allfrag)
@@ -1232,7 +1235,7 @@ void rt6_pmtu_discovery(struct in6_addr 
 		nrt->u.dst.metrics[RTAX_MTU-1] = pmtu;
 		if (allfrag)
 			nrt->u.dst.metrics[RTAX_FEATURES-1] |= RTAX_FEATURE_ALLFRAG;
-		ip6_ins_rt(nrt, NULL, NULL);
+		ip6_ins_rt(nrt, NULL, NULL, NULL);
 	}
 
 out:
@@ -1305,7 +1308,7 @@ struct rt6_info *rt6_add_dflt_router(str
 
 	rtmsg.rtmsg_ifindex = dev->ifindex;
 
-	ip6_route_add(&rtmsg, NULL, NULL);
+	ip6_route_add(&rtmsg, NULL, NULL, NULL);
 	return rt6_get_dflt_router(gwaddr, dev);
 }
 
@@ -1323,7 +1326,7 @@ restart:
 
 			read_unlock_bh(&rt6_lock);
 
-			ip6_del_rt(rt, NULL, NULL);
+			ip6_del_rt(rt, NULL, NULL, NULL);
 
 			goto restart;
 		}
@@ -1349,10 +1352,10 @@ int ipv6_route_ioctl(unsigned int cmd, v
 		rtnl_lock();
 		switch (cmd) {
 		case SIOCADDRT:
-			err = ip6_route_add(&rtmsg, NULL, NULL);
+			err = ip6_route_add(&rtmsg, NULL, NULL, NULL);
 			break;
 		case SIOCDELRT:
-			err = ip6_route_del(&rtmsg, NULL, NULL);
+			err = ip6_route_del(&rtmsg, NULL, NULL, NULL);
 			break;
 		default:
 			err = -EINVAL;
@@ -1546,7 +1549,7 @@ int inet6_rtm_delroute(struct sk_buff *s
 
 	if (inet6_rtm_to_rtmsg(r, arg, &rtmsg))
 		return -EINVAL;
-	return ip6_route_del(&rtmsg, nlh, arg);
+	return ip6_route_del(&rtmsg, nlh, arg, &NETLINK_CB(skb));
 }
 
 int inet6_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
@@ -1556,7 +1559,7 @@ int inet6_rtm_newroute(struct sk_buff *s
 
 	if (inet6_rtm_to_rtmsg(r, arg, &rtmsg))
 		return -EINVAL;
-	return ip6_route_add(&rtmsg, nlh, arg);
+	return ip6_route_add(&rtmsg, nlh, arg, &NETLINK_CB(skb));
 }
 
 struct rt6_rtnl_dump_arg
@@ -1566,11 +1569,9 @@ struct rt6_rtnl_dump_arg
 };
 
 static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt,
-			 struct in6_addr *dst,
-			 struct in6_addr *src,
-			 int iif,
-			 int type, u32 pid, u32 seq,
-			 struct nlmsghdr *in_nlh, int prefix)
+			 struct in6_addr *dst, struct in6_addr *src,
+			 int iif, int type, u32 pid, u32 seq,
+			 int prefix, unsigned int flags)
 {
 	struct rtmsg *rtm;
 	struct nlmsghdr  *nlh;
@@ -1584,11 +1585,7 @@ static int rt6_fill_node(struct sk_buff 
 		}
 	}
 
-	if (!pid && in_nlh) {
-		pid = in_nlh->nlmsg_pid;
-	}
-
-	nlh = NLMSG_PUT(skb, pid, seq, type, sizeof(*rtm));
+	nlh = NLMSG_NEW(skb, pid, seq, type, sizeof(*rtm), flags);
 	rtm = NLMSG_DATA(nlh);
 	rtm->rtm_family = AF_INET6;
 	rtm->rtm_dst_len = rt->rt6i_dst.plen;
@@ -1674,7 +1671,7 @@ static int rt6_dump_route(struct rt6_inf
 
 	return rt6_fill_node(arg->skb, rt, NULL, NULL, 0, RTM_NEWROUTE,
 		     NETLINK_CB(arg->cb->skb).pid, arg->cb->nlh->nlmsg_seq,
-		     NULL, prefix);
+		     prefix, NLM_F_MULTI);
 }
 
 static int fib6_dump_node(struct fib6_walker_t *w)
@@ -1822,7 +1819,7 @@ int inet6_rtm_getroute(struct sk_buff *i
 			    &fl.fl6_dst, &fl.fl6_src,
 			    iif,
 			    RTM_NEWROUTE, NETLINK_CB(in_skb).pid,
-			    nlh->nlmsg_seq, nlh, 0);
+			    nlh->nlmsg_seq, 0, 0);
 	if (err < 0) {
 		err = -EMSGSIZE;
 		goto out_free;
@@ -1838,17 +1835,25 @@ out_free:
 	goto out;	
 }
 
-void inet6_rt_notify(int event, struct rt6_info *rt, struct nlmsghdr *nlh)
+void inet6_rt_notify(int event, struct rt6_info *rt, struct nlmsghdr *nlh, 
+			struct netlink_skb_parms *req)
 {
 	struct sk_buff *skb;
 	int size = NLMSG_SPACE(sizeof(struct rtmsg)+256);
+	u32 pid = current->pid;
+	u32 seq = 0;
 
+	if (req)
+		pid = req->pid;
+	if (nlh)
+		seq = nlh->nlmsg_seq;
+	
 	skb = alloc_skb(size, gfp_any());
 	if (!skb) {
 		netlink_set_err(rtnl, 0, RTMGRP_IPV6_ROUTE, ENOBUFS);
 		return;
 	}
-	if (rt6_fill_node(skb, rt, NULL, NULL, 0, event, 0, 0, nlh, 0) < 0) {
+	if (rt6_fill_node(skb, rt, NULL, NULL, 0, event, pid, seq, 0, 0) < 0) {
 		kfree_skb(skb);
 		netlink_set_err(rtnl, 0, RTMGRP_IPV6_ROUTE, EINVAL);
 		return;
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -195,7 +195,6 @@ static struct ip_tunnel * ipip6_tunnel_l
 	dev_hold(dev);
 
 	ipip6_tunnel_link(nt);
-	/* Do not decrement MOD_USE_COUNT here. */
 	return nt;
 
 failed:
@@ -794,10 +793,28 @@ static struct net_protocol sit_protocol 
 	.err_handler	=	ipip6_err,
 };
 
+static void __exit sit_destroy_tunnels(void)
+{
+	int prio;
+
+	for (prio = 1; prio < 4; prio++) {
+		int h;
+		for (h = 0; h < HASH_SIZE; h++) {
+			struct ip_tunnel *t;
+			while ((t = tunnels[prio][h]) != NULL)
+				unregister_netdevice(t->dev);
+		}
+	}
+}
+
 void __exit sit_cleanup(void)
 {
 	inet_del_protocol(&sit_protocol, IPPROTO_IPV6);
-	unregister_netdev(ipip6_fb_tunnel_dev);
+
+	rtnl_lock();
+	sit_destroy_tunnels();
+	unregister_netdevice(ipip6_fb_tunnel_dev);
+	rtnl_unlock();
 }
 
 int __init sit_init(void)
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -65,7 +65,7 @@
 #include <linux/seq_file.h>
 
 static void	tcp_v6_send_reset(struct sk_buff *skb);
-static void	tcp_v6_or_send_ack(struct sk_buff *skb, struct open_request *req);
+static void	tcp_v6_reqsk_send_ack(struct sk_buff *skb, struct request_sock *req);
 static void	tcp_v6_send_check(struct sock *sk, struct tcphdr *th, int len, 
 				  struct sk_buff *skb);
 
@@ -158,9 +158,14 @@ static int tcp_v6_get_port(struct sock *
 		tcp_port_rover = rover;
 		spin_unlock(&tcp_portalloc_lock);
 
-		/* Exhausted local port range during search? */
+		/* Exhausted local port range during search?  It is not
+		 * possible for us to be holding one of the bind hash
+		 * locks if this test triggers, because if 'remaining'
+		 * drops to zero, we broke out of the do/while loop at
+		 * the top level, not from the 'break;' statement.
+		 */
 		ret = 1;
-		if (remaining <= 0)
+		if (unlikely(remaining <= 0))
 			goto fail;
 
 		/* OK, here is the one we will use. */
@@ -394,24 +399,26 @@ static u32 tcp_v6_synq_hash(struct in6_a
 	return c & (TCP_SYNQ_HSIZE - 1);
 }
 
-static struct open_request *tcp_v6_search_req(struct tcp_sock *tp,
-					      struct open_request ***prevp,
+static struct request_sock *tcp_v6_search_req(struct tcp_sock *tp,
+					      struct request_sock ***prevp,
 					      __u16 rport,
 					      struct in6_addr *raddr,
 					      struct in6_addr *laddr,
 					      int iif)
 {
-	struct tcp_listen_opt *lopt = tp->listen_opt;
-	struct open_request *req, **prev;  
+	struct listen_sock *lopt = tp->accept_queue.listen_opt;
+	struct request_sock *req, **prev;  
 
 	for (prev = &lopt->syn_table[tcp_v6_synq_hash(raddr, rport, lopt->hash_rnd)];
 	     (req = *prev) != NULL;
 	     prev = &req->dl_next) {
-		if (req->rmt_port == rport &&
-		    req->class->family == AF_INET6 &&
-		    ipv6_addr_equal(&req->af.v6_req.rmt_addr, raddr) &&
-		    ipv6_addr_equal(&req->af.v6_req.loc_addr, laddr) &&
-		    (!req->af.v6_req.iif || req->af.v6_req.iif == iif)) {
+		const struct tcp6_request_sock *treq = tcp6_rsk(req);
+
+		if (inet_rsk(req)->rmt_port == rport &&
+		    req->rsk_ops->family == AF_INET6 &&
+		    ipv6_addr_equal(&treq->rmt_addr, raddr) &&
+		    ipv6_addr_equal(&treq->loc_addr, laddr) &&
+		    (!treq->iif || treq->iif == iif)) {
 			BUG_TRAP(req->sk == NULL);
 			*prevp = prev;
 			return req;
@@ -906,9 +913,9 @@ static void tcp_v6_err(struct sk_buff *s
 
 	icmpv6_err_convert(type, code, &err);
 
-	/* Might be for an open_request */
+	/* Might be for an request_sock */
 	switch (sk->sk_state) {
-		struct open_request *req, **prev;
+		struct request_sock *req, **prev;
 	case TCP_LISTEN:
 		if (sock_owned_by_user(sk))
 			goto out;
@@ -923,7 +930,7 @@ static void tcp_v6_err(struct sk_buff *s
 		 */
 		BUG_TRAP(req->sk == NULL);
 
-		if (seq != req->snt_isn) {
+		if (seq != tcp_rsk(req)->snt_isn) {
 			NET_INC_STATS_BH(LINUX_MIB_OUTOFWINDOWICMPS);
 			goto out;
 		}
@@ -957,9 +964,10 @@ out:
 }
 
 
-static int tcp_v6_send_synack(struct sock *sk, struct open_request *req,
+static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req,
 			      struct dst_entry *dst)
 {
+	struct tcp6_request_sock *treq = tcp6_rsk(req);
 	struct ipv6_pinfo *np = inet6_sk(sk);
 	struct sk_buff * skb;
 	struct ipv6_txoptions *opt = NULL;
@@ -969,19 +977,19 @@ static int tcp_v6_send_synack(struct soc
 
 	memset(&fl, 0, sizeof(fl));
 	fl.proto = IPPROTO_TCP;
-	ipv6_addr_copy(&fl.fl6_dst, &req->af.v6_req.rmt_addr);
-	ipv6_addr_copy(&fl.fl6_src, &req->af.v6_req.loc_addr);
+	ipv6_addr_copy(&fl.fl6_dst, &treq->rmt_addr);
+	ipv6_addr_copy(&fl.fl6_src, &treq->loc_addr);
 	fl.fl6_flowlabel = 0;
-	fl.oif = req->af.v6_req.iif;
-	fl.fl_ip_dport = req->rmt_port;
+	fl.oif = treq->iif;
+	fl.fl_ip_dport = inet_rsk(req)->rmt_port;
 	fl.fl_ip_sport = inet_sk(sk)->sport;
 
 	if (dst == NULL) {
 		opt = np->opt;
 		if (opt == NULL &&
 		    np->rxopt.bits.srcrt == 2 &&
-		    req->af.v6_req.pktopts) {
-			struct sk_buff *pktopts = req->af.v6_req.pktopts;
+		    treq->pktopts) {
+			struct sk_buff *pktopts = treq->pktopts;
 			struct inet6_skb_parm *rxopt = IP6CB(pktopts);
 			if (rxopt->srcrt)
 				opt = ipv6_invert_rthdr(sk, (struct ipv6_rt_hdr*)(pktopts->nh.raw + rxopt->srcrt));
@@ -1008,10 +1016,10 @@ static int tcp_v6_send_synack(struct soc
 		struct tcphdr *th = skb->h.th;
 
 		th->check = tcp_v6_check(th, skb->len,
-					 &req->af.v6_req.loc_addr, &req->af.v6_req.rmt_addr,
+					 &treq->loc_addr, &treq->rmt_addr,
 					 csum_partial((char *)th, skb->len, skb->csum));
 
-		ipv6_addr_copy(&fl.fl6_dst, &req->af.v6_req.rmt_addr);
+		ipv6_addr_copy(&fl.fl6_dst, &treq->rmt_addr);
 		err = ip6_xmit(sk, skb, &fl, opt, 0);
 		if (err == NET_XMIT_CN)
 			err = 0;
@@ -1024,17 +1032,18 @@ done:
 	return err;
 }
 
-static void tcp_v6_or_free(struct open_request *req)
+static void tcp_v6_reqsk_destructor(struct request_sock *req)
 {
-	if (req->af.v6_req.pktopts)
-		kfree_skb(req->af.v6_req.pktopts);
+	if (tcp6_rsk(req)->pktopts)
+		kfree_skb(tcp6_rsk(req)->pktopts);
 }
 
-static struct or_calltable or_ipv6 = {
+static struct request_sock_ops tcp6_request_sock_ops = {
 	.family		=	AF_INET6,
+	.obj_size	=	sizeof(struct tcp6_request_sock),
 	.rtx_syn_ack	=	tcp_v6_send_synack,
-	.send_ack	=	tcp_v6_or_send_ack,
-	.destructor	=	tcp_v6_or_free,
+	.send_ack	=	tcp_v6_reqsk_send_ack,
+	.destructor	=	tcp_v6_reqsk_destructor,
 	.send_reset	=	tcp_v6_send_reset
 };
 
@@ -1219,15 +1228,15 @@ static void tcp_v6_timewait_ack(struct s
 	tcp_tw_put(tw);
 }
 
-static void tcp_v6_or_send_ack(struct sk_buff *skb, struct open_request *req)
+static void tcp_v6_reqsk_send_ack(struct sk_buff *skb, struct request_sock *req)
 {
-	tcp_v6_send_ack(skb, req->snt_isn+1, req->rcv_isn+1, req->rcv_wnd, req->ts_recent);
+	tcp_v6_send_ack(skb, tcp_rsk(req)->snt_isn + 1, tcp_rsk(req)->rcv_isn + 1, req->rcv_wnd, req->ts_recent);
 }
 
 
 static struct sock *tcp_v6_hnd_req(struct sock *sk,struct sk_buff *skb)
 {
-	struct open_request *req, **prev;
+	struct request_sock *req, **prev;
 	struct tcphdr *th = skb->h.th;
 	struct tcp_sock *tp = tcp_sk(sk);
 	struct sock *nsk;
@@ -1260,21 +1269,13 @@ static struct sock *tcp_v6_hnd_req(struc
 	return sk;
 }
 
-static void tcp_v6_synq_add(struct sock *sk, struct open_request *req)
+static void tcp_v6_synq_add(struct sock *sk, struct request_sock *req)
 {
 	struct tcp_sock *tp = tcp_sk(sk);
-	struct tcp_listen_opt *lopt = tp->listen_opt;
-	u32 h = tcp_v6_synq_hash(&req->af.v6_req.rmt_addr, req->rmt_port, lopt->hash_rnd);
-
-	req->sk = NULL;
-	req->expires = jiffies + TCP_TIMEOUT_INIT;
-	req->retrans = 0;
-	req->dl_next = lopt->syn_table[h];
-
-	write_lock(&tp->syn_wait_lock);
-	lopt->syn_table[h] = req;
-	write_unlock(&tp->syn_wait_lock);
+	struct listen_sock *lopt = tp->accept_queue.listen_opt;
+	u32 h = tcp_v6_synq_hash(&tcp6_rsk(req)->rmt_addr, inet_rsk(req)->rmt_port, lopt->hash_rnd);
 
+	reqsk_queue_hash_req(&tp->accept_queue, h, req, TCP_TIMEOUT_INIT);
 	tcp_synq_added(sk);
 }
 
@@ -1284,10 +1285,11 @@ static void tcp_v6_synq_add(struct sock 
  */
 static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
 {
+	struct tcp6_request_sock *treq;
 	struct ipv6_pinfo *np = inet6_sk(sk);
 	struct tcp_options_received tmp_opt;
 	struct tcp_sock *tp = tcp_sk(sk);
-	struct open_request *req = NULL;
+	struct request_sock *req = NULL;
 	__u32 isn = TCP_SKB_CB(skb)->when;
 
 	if (skb->protocol == htons(ETH_P_IP))
@@ -1308,7 +1310,7 @@ static int tcp_v6_conn_request(struct so
 	if (sk_acceptq_is_full(sk) && tcp_synq_young(sk) > 1)
 		goto drop;
 
-	req = tcp_openreq_alloc();
+	req = reqsk_alloc(&tcp6_request_sock_ops);
 	if (req == NULL)
 		goto drop;
 
@@ -1321,28 +1323,28 @@ static int tcp_v6_conn_request(struct so
 	tmp_opt.tstamp_ok = tmp_opt.saw_tstamp;
 	tcp_openreq_init(req, &tmp_opt, skb);
 
-	req->class = &or_ipv6;
-	ipv6_addr_copy(&req->af.v6_req.rmt_addr, &skb->nh.ipv6h->saddr);
-	ipv6_addr_copy(&req->af.v6_req.loc_addr, &skb->nh.ipv6h->daddr);
+	treq = tcp6_rsk(req);
+	ipv6_addr_copy(&treq->rmt_addr, &skb->nh.ipv6h->saddr);
+	ipv6_addr_copy(&treq->loc_addr, &skb->nh.ipv6h->daddr);
 	TCP_ECN_create_request(req, skb->h.th);
-	req->af.v6_req.pktopts = NULL;
+	treq->pktopts = NULL;
 	if (ipv6_opt_accepted(sk, skb) ||
 	    np->rxopt.bits.rxinfo ||
 	    np->rxopt.bits.rxhlim) {
 		atomic_inc(&skb->users);
-		req->af.v6_req.pktopts = skb;
+		treq->pktopts = skb;
 	}
-	req->af.v6_req.iif = sk->sk_bound_dev_if;
+	treq->iif = sk->sk_bound_dev_if;
 
 	/* So that link locals have meaning */
 	if (!sk->sk_bound_dev_if &&
-	    ipv6_addr_type(&req->af.v6_req.rmt_addr) & IPV6_ADDR_LINKLOCAL)
-		req->af.v6_req.iif = tcp_v6_iif(skb);
+	    ipv6_addr_type(&treq->rmt_addr) & IPV6_ADDR_LINKLOCAL)
+		treq->iif = tcp_v6_iif(skb);
 
 	if (isn == 0) 
 		isn = tcp_v6_init_sequence(sk,skb);
 
-	req->snt_isn = isn;
+	tcp_rsk(req)->snt_isn = isn;
 
 	if (tcp_v6_send_synack(sk, req, NULL))
 		goto drop;
@@ -1353,16 +1355,17 @@ static int tcp_v6_conn_request(struct so
 
 drop:
 	if (req)
-		tcp_openreq_free(req);
+		reqsk_free(req);
 
 	TCP_INC_STATS_BH(TCP_MIB_ATTEMPTFAILS);
 	return 0; /* don't send reset */
 }
 
 static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
-					  struct open_request *req,
+					  struct request_sock *req,
 					  struct dst_entry *dst)
 {
+	struct tcp6_request_sock *treq = tcp6_rsk(req);
 	struct ipv6_pinfo *newnp, *np = inet6_sk(sk);
 	struct tcp6_sock *newtcp6sk;
 	struct inet_sock *newinet;
@@ -1426,10 +1429,10 @@ static struct sock * tcp_v6_syn_recv_soc
 		goto out_overflow;
 
 	if (np->rxopt.bits.srcrt == 2 &&
-	    opt == NULL && req->af.v6_req.pktopts) {
-		struct inet6_skb_parm *rxopt = IP6CB(req->af.v6_req.pktopts);
+	    opt == NULL && treq->pktopts) {
+		struct inet6_skb_parm *rxopt = IP6CB(treq->pktopts);
 		if (rxopt->srcrt)
-			opt = ipv6_invert_rthdr(sk, (struct ipv6_rt_hdr*)(req->af.v6_req.pktopts->nh.raw+rxopt->srcrt));
+			opt = ipv6_invert_rthdr(sk, (struct ipv6_rt_hdr *)(treq->pktopts->nh.raw + rxopt->srcrt));
 	}
 
 	if (dst == NULL) {
@@ -1438,16 +1441,16 @@ static struct sock * tcp_v6_syn_recv_soc
 
 		memset(&fl, 0, sizeof(fl));
 		fl.proto = IPPROTO_TCP;
-		ipv6_addr_copy(&fl.fl6_dst, &req->af.v6_req.rmt_addr);
+		ipv6_addr_copy(&fl.fl6_dst, &treq->rmt_addr);
 		if (opt && opt->srcrt) {
 			struct rt0_hdr *rt0 = (struct rt0_hdr *) opt->srcrt;
 			ipv6_addr_copy(&final, &fl.fl6_dst);
 			ipv6_addr_copy(&fl.fl6_dst, rt0->addr);
 			final_p = &final;
 		}
-		ipv6_addr_copy(&fl.fl6_src, &req->af.v6_req.loc_addr);
+		ipv6_addr_copy(&fl.fl6_src, &treq->loc_addr);
 		fl.oif = sk->sk_bound_dev_if;
-		fl.fl_ip_dport = req->rmt_port;
+		fl.fl_ip_dport = inet_rsk(req)->rmt_port;
 		fl.fl_ip_sport = inet_sk(sk)->sport;
 
 		if (ip6_dst_lookup(sk, &dst, &fl))
@@ -1482,10 +1485,10 @@ static struct sock * tcp_v6_syn_recv_soc
 
 	memcpy(newnp, np, sizeof(struct ipv6_pinfo));
 
-	ipv6_addr_copy(&newnp->daddr, &req->af.v6_req.rmt_addr);
-	ipv6_addr_copy(&newnp->saddr, &req->af.v6_req.loc_addr);
-	ipv6_addr_copy(&newnp->rcv_saddr, &req->af.v6_req.loc_addr);
-	newsk->sk_bound_dev_if = req->af.v6_req.iif;
+	ipv6_addr_copy(&newnp->daddr, &treq->rmt_addr);
+	ipv6_addr_copy(&newnp->saddr, &treq->loc_addr);
+	ipv6_addr_copy(&newnp->rcv_saddr, &treq->loc_addr);
+	newsk->sk_bound_dev_if = treq->iif;
 
 	/* Now IPv6 options... 
 
@@ -1498,11 +1501,10 @@ static struct sock * tcp_v6_syn_recv_soc
 
 	/* Clone pktoptions received with SYN */
 	newnp->pktoptions = NULL;
-	if (req->af.v6_req.pktopts) {
-		newnp->pktoptions = skb_clone(req->af.v6_req.pktopts,
-					      GFP_ATOMIC);
-		kfree_skb(req->af.v6_req.pktopts);
-		req->af.v6_req.pktopts = NULL;
+	if (treq->pktopts != NULL) {
+		newnp->pktoptions = skb_clone(treq->pktopts, GFP_ATOMIC);
+		kfree_skb(treq->pktopts);
+		treq->pktopts = NULL;
 		if (newnp->pktoptions)
 			skb_set_owner_r(newnp->pktoptions, newsk);
 	}
@@ -2021,14 +2023,14 @@ static int tcp_v6_init_sock(struct sock 
 	 */
 	tp->snd_ssthresh = 0x7fffffff;
 	tp->snd_cwnd_clamp = ~0;
-	tp->mss_cache_std = tp->mss_cache = 536;
+	tp->mss_cache = 536;
 
 	tp->reordering = sysctl_tcp_reordering;
 
 	sk->sk_state = TCP_CLOSE;
 
 	tp->af_specific = &ipv6_specific;
-
+	tp->ca_ops = &tcp_init_congestion_ops;
 	sk->sk_write_space = sk_stream_write_space;
 	sock_set_flag(sk, SOCK_USE_WRITE_QUEUE);
 
@@ -2050,7 +2052,7 @@ static int tcp_v6_destroy_sock(struct so
 
 /* Proc filesystem TCPv6 sock list dumping. */
 static void get_openreq6(struct seq_file *seq, 
-			 struct sock *sk, struct open_request *req, int i, int uid)
+			 struct sock *sk, struct request_sock *req, int i, int uid)
 {
 	struct in6_addr *dest, *src;
 	int ttd = req->expires - jiffies;
@@ -2058,8 +2060,8 @@ static void get_openreq6(struct seq_file
 	if (ttd < 0)
 		ttd = 0;
 
-	src = &req->af.v6_req.loc_addr;
-	dest = &req->af.v6_req.rmt_addr;
+	src = &tcp6_rsk(req)->loc_addr;
+	dest = &tcp6_rsk(req)->rmt_addr;
 	seq_printf(seq,
 		   "%4d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X "
 		   "%02X %08X:%08X %02X:%08lX %08X %5d %8d %d %d %p\n",
@@ -2069,7 +2071,7 @@ static void get_openreq6(struct seq_file
 		   ntohs(inet_sk(sk)->sport),
 		   dest->s6_addr32[0], dest->s6_addr32[1],
 		   dest->s6_addr32[2], dest->s6_addr32[3],
-		   ntohs(req->rmt_port),
+		   ntohs(inet_rsk(req)->rmt_port),
 		   TCP_SYN_RECV,
 		   0,0, /* could print option size, but that is af dependent. */
 		   1,   /* timers active (only the expire timer) */  
@@ -2239,6 +2241,7 @@ struct proto tcpv6_prot = {
 	.sysctl_rmem		= sysctl_tcp_rmem,
 	.max_header		= MAX_TCP_HEADER,
 	.obj_size		= sizeof(struct tcp6_sock),
+	.rsk_prot		= &tcp6_request_sock_ops,
 };
 
 static struct inet6_protocol tcpv6_protocol = {
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -300,12 +300,12 @@ csum_copy_err:
 	/* Clear queue. */
 	if (flags&MSG_PEEK) {
 		int clear = 0;
-		spin_lock_irq(&sk->sk_receive_queue.lock);
+		spin_lock_bh(&sk->sk_receive_queue.lock);
 		if (skb == skb_peek(&sk->sk_receive_queue)) {
 			__skb_unlink(skb, &sk->sk_receive_queue);
 			clear = 1;
 		}
-		spin_unlock_irq(&sk->sk_receive_queue.lock);
+		spin_unlock_bh(&sk->sk_receive_queue.lock);
 		if (clear)
 			kfree_skb(skb);
 	}
diff --git a/net/ipv6/xfrm6_tunnel.c b/net/ipv6/xfrm6_tunnel.c
--- a/net/ipv6/xfrm6_tunnel.c
+++ b/net/ipv6/xfrm6_tunnel.c
@@ -466,7 +466,7 @@ static void xfrm6_tunnel_err(struct sk_b
 	return;
 }
 
-static int xfrm6_tunnel_init_state(struct xfrm_state *x, void *args)
+static int xfrm6_tunnel_init_state(struct xfrm_state *x)
 {
 	if (!x->props.mode)
 		return -EINVAL;
diff --git a/net/ipx/Kconfig b/net/ipx/Kconfig
--- a/net/ipx/Kconfig
+++ b/net/ipx/Kconfig
@@ -1,6 +1,39 @@
 #
 # IPX configuration
 #
+config IPX
+	tristate "The IPX protocol"
+	select LLC
+	---help---
+	  This is support for the Novell networking protocol, IPX, commonly
+	  used for local networks of Windows machines.  You need it if you
+	  want to access Novell NetWare file or print servers using the Linux
+	  Novell client ncpfs (available from
+	  <ftp://platan.vc.cvut.cz/pub/linux/ncpfs/>) or from
+	  within the Linux DOS emulator DOSEMU (read the DOSEMU-HOWTO,
+	  available from <http://www.tldp.org/docs.html#howto>).  In order
+	  to do the former, you'll also have to say Y to "NCP file system
+	  support", below.
+
+	  IPX is similar in scope to IP, while SPX, which runs on top of IPX,
+	  is similar to TCP. There is also experimental support for SPX in
+	  Linux (see "SPX networking", below).
+
+	  To turn your Linux box into a fully featured NetWare file server and
+	  IPX router, say Y here and fetch either lwared from
+	  <ftp://ibiblio.org/pub/Linux/system/network/daemons/> or
+	  mars_nwe from <ftp://www.compu-art.de/mars_nwe/>. For more
+	  information, read the IPX-HOWTO available from
+	  <http://www.tldp.org/docs.html#howto>.
+
+	  General information about how to connect Linux, Windows machines and
+	  Macs is on the WWW at <http://www.eats.com/linux_mac_win.html>.
+
+	  The IPX driver would enlarge your kernel by about 16 KB. To compile
+	  this driver as a module, choose M here: the module will be called ipx.
+	  Unless you want to integrate your Linux box with a local Novell
+	  network, say N.
+
 config IPX_INTERN
 	bool "IPX: Full internal IPX network"
 	depends on IPX
diff --git a/net/irda/irlap.c b/net/irda/irlap.c
--- a/net/irda/irlap.c
+++ b/net/irda/irlap.c
@@ -445,9 +445,8 @@ void irlap_disconnect_request(struct irl
 	IRDA_ASSERT(self->magic == LAP_MAGIC, return;);
 
 	/* Don't disconnect until all data frames are successfully sent */
-	if (skb_queue_len(&self->txq) > 0) {
+	if (!skb_queue_empty(&self->txq)) {
 		self->disconnect_pending = TRUE;
-
 		return;
 	}
 
diff --git a/net/irda/irlap_event.c b/net/irda/irlap_event.c
--- a/net/irda/irlap_event.c
+++ b/net/irda/irlap_event.c
@@ -191,7 +191,7 @@ static void irlap_start_poll_timer(struc
 	 * Send out the RR frames faster if our own transmit queue is empty, or
 	 * if the peer is busy. The effect is a much faster conversation
 	 */
-	if ((skb_queue_len(&self->txq) == 0) || (self->remote_busy)) {
+	if (skb_queue_empty(&self->txq) || self->remote_busy) {
 		if (self->fast_RR == TRUE) {
 			/*
 			 *  Assert that the fast poll timer has not reached the
@@ -263,7 +263,7 @@ void irlap_do_event(struct irlap_cb *sel
 		IRDA_DEBUG(2, "%s() : queue len = %d\n", __FUNCTION__,
 			   skb_queue_len(&self->txq));
 
-		if (skb_queue_len(&self->txq)) {
+		if (!skb_queue_empty(&self->txq)) {
 			/* Prevent race conditions with irlap_data_request() */
 			self->local_busy = TRUE;
 
@@ -1074,7 +1074,7 @@ static int irlap_state_xmit_p(struct irl
 #else	/* CONFIG_IRDA_DYNAMIC_WINDOW */
 			/* Window has been adjusted for the max packet
 			 * size, so much simpler... - Jean II */
-			nextfit = (skb_queue_len(&self->txq) > 0);
+			nextfit = !skb_queue_empty(&self->txq);
 #endif	/* CONFIG_IRDA_DYNAMIC_WINDOW */
 			/*
 			 *  Send data with poll bit cleared only if window > 1
@@ -1814,7 +1814,7 @@ static int irlap_state_xmit_s(struct irl
 #else	/* CONFIG_IRDA_DYNAMIC_WINDOW */
 			/* Window has been adjusted for the max packet
 			 * size, so much simpler... - Jean II */
-			nextfit = (skb_queue_len(&self->txq) > 0);
+			nextfit = !skb_queue_empty(&self->txq);
 #endif /* CONFIG_IRDA_DYNAMIC_WINDOW */
 			/*
 			 *  Send data with final bit cleared only if window > 1
@@ -1937,7 +1937,7 @@ static int irlap_state_nrm_s(struct irla
 				irlap_data_indication(self, skb, FALSE);
 
 				/* Any pending data requests?  */
-				if ((skb_queue_len(&self->txq) > 0) &&
+				if (!skb_queue_empty(&self->txq) &&
 				    (self->window > 0))
 				{
 					self->ack_required = TRUE;
@@ -2038,7 +2038,7 @@ static int irlap_state_nrm_s(struct irla
 			/*
 			 *  Any pending data requests?
 			 */
-			if ((skb_queue_len(&self->txq) > 0) &&
+			if (!skb_queue_empty(&self->txq) &&
 			    (self->window > 0) && !self->remote_busy)
 			{
 				irlap_data_indication(self, skb, TRUE);
@@ -2069,7 +2069,7 @@ static int irlap_state_nrm_s(struct irla
 		 */
 		nr_status = irlap_validate_nr_received(self, info->nr);
 		if (nr_status == NR_EXPECTED) {
-			if ((skb_queue_len( &self->txq) > 0) &&
+			if (!skb_queue_empty(&self->txq) &&
 			    (self->window > 0)) {
 				self->remote_busy = FALSE;
 
diff --git a/net/irda/irlap_frame.c b/net/irda/irlap_frame.c
--- a/net/irda/irlap_frame.c
+++ b/net/irda/irlap_frame.c
@@ -1018,11 +1018,10 @@ void irlap_resend_rejected_frames(struct
 	/*
 	 *  We can now fill the window with additional data frames
 	 */
-	while (skb_queue_len( &self->txq) > 0) {
+	while (!skb_queue_empty(&self->txq)) {
 
 		IRDA_DEBUG(0, "%s(), sending additional frames!\n", __FUNCTION__);
-		if ((skb_queue_len( &self->txq) > 0) &&
-		    (self->window > 0)) {
+		if (self->window > 0) {
 			skb = skb_dequeue( &self->txq);
 			IRDA_ASSERT(skb != NULL, return;);
 
@@ -1031,8 +1030,7 @@ void irlap_resend_rejected_frames(struct
 			 *  bit cleared
 			 */
 			if ((self->window > 1) &&
-			    skb_queue_len(&self->txq) > 0)
-			{
+			    !skb_queue_empty(&self->txq)) {
 				irlap_send_data_primary(self, skb);
 			} else {
 				irlap_send_data_primary_poll(self, skb);
diff --git a/net/irda/irttp.c b/net/irda/irttp.c
--- a/net/irda/irttp.c
+++ b/net/irda/irttp.c
@@ -1513,7 +1513,7 @@ int irttp_disconnect_request(struct tsap
 	/*
 	 *  Check if there is still data segments in the transmit queue
 	 */
-	if (skb_queue_len(&self->tx_queue) > 0) {
+	if (!skb_queue_empty(&self->tx_queue)) {
 		if (priority == P_HIGH) {
 			/*
 			 *  No need to send the queued data, if we are
diff --git a/net/key/af_key.c b/net/key/af_key.c
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -656,13 +656,18 @@ static struct sk_buff * pfkey_xfrm_state
 	sa->sadb_sa_exttype = SADB_EXT_SA;
 	sa->sadb_sa_spi = x->id.spi;
 	sa->sadb_sa_replay = x->props.replay_window;
-	sa->sadb_sa_state = SADB_SASTATE_DYING;
-	if (x->km.state == XFRM_STATE_VALID && !x->km.dying)
-		sa->sadb_sa_state = SADB_SASTATE_MATURE;
-	else if (x->km.state == XFRM_STATE_ACQ)
+	switch (x->km.state) {
+	case XFRM_STATE_VALID:
+		sa->sadb_sa_state = x->km.dying ?
+			SADB_SASTATE_DYING : SADB_SASTATE_MATURE;
+		break;
+	case XFRM_STATE_ACQ:
 		sa->sadb_sa_state = SADB_SASTATE_LARVAL;
-	else if (x->km.state == XFRM_STATE_EXPIRED)
+		break;
+	default:
 		sa->sadb_sa_state = SADB_SASTATE_DEAD;
+		break;
+	}
 	sa->sadb_sa_auth = 0;
 	if (x->aalg) {
 		struct xfrm_algo_desc *a = xfrm_aalg_get_byname(x->aalg->alg_name, 0);
@@ -685,6 +690,8 @@ static struct sk_buff * pfkey_xfrm_state
 		sa->sadb_sa_flags |= SADB_SAFLAGS_NOECN;
 	if (x->props.flags & XFRM_STATE_DECAP_DSCP)
 		sa->sadb_sa_flags |= SADB_SAFLAGS_DECAP_DSCP;
+	if (x->props.flags & XFRM_STATE_NOPMTUDISC)
+		sa->sadb_sa_flags |= SADB_SAFLAGS_NOPMTUDISC;
 
 	/* hard time */
 	if (hsc & 2) {
@@ -969,6 +976,8 @@ static struct xfrm_state * pfkey_msg2xfr
 		x->props.flags |= XFRM_STATE_NOECN;
 	if (sa->sadb_sa_flags & SADB_SAFLAGS_DECAP_DSCP)
 		x->props.flags |= XFRM_STATE_DECAP_DSCP;
+	if (sa->sadb_sa_flags & SADB_SAFLAGS_NOPMTUDISC)
+		x->props.flags |= XFRM_STATE_NOPMTUDISC;
 
 	lifetime = (struct sadb_lifetime*) ext_hdrs[SADB_EXT_LIFETIME_HARD-1];
 	if (lifetime != NULL) {
@@ -1091,17 +1100,11 @@ static struct xfrm_state * pfkey_msg2xfr
 		}
 	}
 
-	x->type = xfrm_get_type(proto, x->props.family);
-	if (x->type == NULL) {
-		err = -ENOPROTOOPT;
-		goto out;
-	}
-	if (x->type->init_state(x, NULL)) {
-		err = -EINVAL;
+	err = xfrm_init_state(x);
+	if (err)
 		goto out;
-	}
+
 	x->km.seq = hdr->sadb_msg_seq;
-	x->km.state = XFRM_STATE_VALID;
 	return x;
 
 out:
@@ -1240,13 +1243,78 @@ static int pfkey_acquire(struct sock *sk
 	return 0;
 }
 
+static inline int event2poltype(int event)
+{
+	switch (event) {
+	case XFRM_MSG_DELPOLICY:
+		return SADB_X_SPDDELETE;
+	case XFRM_MSG_NEWPOLICY:
+		return SADB_X_SPDADD;
+	case XFRM_MSG_UPDPOLICY:
+		return SADB_X_SPDUPDATE;
+	case XFRM_MSG_POLEXPIRE:
+	//	return SADB_X_SPDEXPIRE;
+	default:
+		printk("pfkey: Unknown policy event %d\n", event);
+		break;
+	}
+
+	return 0;
+}
+
+static inline int event2keytype(int event)
+{
+	switch (event) {
+	case XFRM_MSG_DELSA:
+		return SADB_DELETE;
+	case XFRM_MSG_NEWSA:
+		return SADB_ADD;
+	case XFRM_MSG_UPDSA:
+		return SADB_UPDATE;
+	case XFRM_MSG_EXPIRE:
+		return SADB_EXPIRE;
+	default:
+		printk("pfkey: Unknown SA event %d\n", event);
+		break;
+	}
+
+	return 0;
+}
+
+/* ADD/UPD/DEL */
+static int key_notify_sa(struct xfrm_state *x, struct km_event *c)
+{
+	struct sk_buff *skb;
+	struct sadb_msg *hdr;
+	int hsc = 3;
+
+	if (c->event == XFRM_MSG_DELSA)
+		hsc = 0;
+
+	skb = pfkey_xfrm_state2msg(x, 0, hsc);
+
+	if (IS_ERR(skb))
+		return PTR_ERR(skb);
+
+	hdr = (struct sadb_msg *) skb->data;
+	hdr->sadb_msg_version = PF_KEY_V2;
+	hdr->sadb_msg_type = event2keytype(c->event);
+	hdr->sadb_msg_satype = pfkey_proto2satype(x->id.proto);
+	hdr->sadb_msg_errno = 0;
+	hdr->sadb_msg_reserved = 0;
+	hdr->sadb_msg_seq = c->seq;
+	hdr->sadb_msg_pid = c->pid;
+
+	pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_ALL, NULL);
+
+	return 0;
+}
 
 static int pfkey_add(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs)
 {
-	struct sk_buff *out_skb;
-	struct sadb_msg *out_hdr;
 	struct xfrm_state *x;
 	int err;
+	struct km_event c;
 
 	xfrm_probe_algs();
 	
@@ -1254,6 +1322,7 @@ static int pfkey_add(struct sock *sk, st
 	if (IS_ERR(x))
 		return PTR_ERR(x);
 
+	xfrm_state_hold(x);
 	if (hdr->sadb_msg_type == SADB_ADD)
 		err = xfrm_state_add(x);
 	else
@@ -1262,30 +1331,26 @@ static int pfkey_add(struct sock *sk, st
 	if (err < 0) {
 		x->km.state = XFRM_STATE_DEAD;
 		xfrm_state_put(x);
-		return err;
+		goto out;
 	}
 
-	out_skb = pfkey_xfrm_state2msg(x, 0, 3);
-	if (IS_ERR(out_skb))
-		return  PTR_ERR(out_skb); /* XXX Should we return 0 here ? */
-
-	out_hdr = (struct sadb_msg *) out_skb->data;
-	out_hdr->sadb_msg_version = hdr->sadb_msg_version;
-	out_hdr->sadb_msg_type = hdr->sadb_msg_type;
-	out_hdr->sadb_msg_satype = pfkey_proto2satype(x->id.proto);
-	out_hdr->sadb_msg_errno = 0;
-	out_hdr->sadb_msg_reserved = 0;
-	out_hdr->sadb_msg_seq = hdr->sadb_msg_seq;
-	out_hdr->sadb_msg_pid = hdr->sadb_msg_pid;
-
-	pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ALL, sk);
-
-	return 0;
+	if (hdr->sadb_msg_type == SADB_ADD)
+		c.event = XFRM_MSG_NEWSA;
+	else
+		c.event = XFRM_MSG_UPDSA;
+	c.seq = hdr->sadb_msg_seq;
+	c.pid = hdr->sadb_msg_pid;
+	km_state_notify(x, &c);
+out:
+	xfrm_state_put(x);
+	return err;
 }
 
 static int pfkey_delete(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs)
 {
 	struct xfrm_state *x;
+	struct km_event c;
+	int err;
 
 	if (!ext_hdrs[SADB_EXT_SA-1] ||
 	    !present_and_same_family(ext_hdrs[SADB_EXT_ADDRESS_SRC-1],
@@ -1301,13 +1366,19 @@ static int pfkey_delete(struct sock *sk,
 		return -EPERM;
 	}
 	
-	xfrm_state_delete(x);
-	xfrm_state_put(x);
+	err = xfrm_state_delete(x);
+	if (err < 0) {
+		xfrm_state_put(x);
+		return err;
+	}
 
-	pfkey_broadcast(skb_clone(skb, GFP_KERNEL), GFP_KERNEL, 
-			BROADCAST_ALL, sk);
+	c.seq = hdr->sadb_msg_seq;
+	c.pid = hdr->sadb_msg_pid;
+	c.event = XFRM_MSG_DELSA;
+	km_state_notify(x, &c);
+	xfrm_state_put(x);
 
-	return 0;
+	return err;
 }
 
 static int pfkey_get(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs)
@@ -1445,28 +1516,42 @@ static int pfkey_register(struct sock *s
 	return 0;
 }
 
+static int key_notify_sa_flush(struct km_event *c)
+{
+	struct sk_buff *skb;
+	struct sadb_msg *hdr;
+
+	skb = alloc_skb(sizeof(struct sadb_msg) + 16, GFP_ATOMIC);
+	if (!skb)
+		return -ENOBUFS;
+	hdr = (struct sadb_msg *) skb_put(skb, sizeof(struct sadb_msg));
+	hdr->sadb_msg_satype = pfkey_proto2satype(c->data.proto);
+	hdr->sadb_msg_seq = c->seq;
+	hdr->sadb_msg_pid = c->pid;
+	hdr->sadb_msg_version = PF_KEY_V2;
+	hdr->sadb_msg_errno = (uint8_t) 0;
+	hdr->sadb_msg_len = (sizeof(struct sadb_msg) / sizeof(uint64_t));
+
+	pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_ALL, NULL);
+
+	return 0;
+}
+
 static int pfkey_flush(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs)
 {
 	unsigned proto;
-	struct sk_buff *skb_out;
-	struct sadb_msg *hdr_out;
+	struct km_event c;
 
 	proto = pfkey_satype2proto(hdr->sadb_msg_satype);
 	if (proto == 0)
 		return -EINVAL;
 
-	skb_out = alloc_skb(sizeof(struct sadb_msg) + 16, GFP_KERNEL);
-	if (!skb_out)
-		return -ENOBUFS;
-
 	xfrm_state_flush(proto);
-
-	hdr_out = (struct sadb_msg *) skb_put(skb_out, sizeof(struct sadb_msg));
-	pfkey_hdr_dup(hdr_out, hdr);
-	hdr_out->sadb_msg_errno = (uint8_t) 0;
-	hdr_out->sadb_msg_len = (sizeof(struct sadb_msg) / sizeof(uint64_t));
-
-	pfkey_broadcast(skb_out, GFP_KERNEL, BROADCAST_ALL, NULL);
+	c.data.proto = proto;
+	c.seq = hdr->sadb_msg_seq;
+	c.pid = hdr->sadb_msg_pid;
+	c.event = XFRM_MSG_FLUSHSA;
+	km_state_notify(NULL, &c);
 
 	return 0;
 }
@@ -1859,6 +1944,35 @@ static void pfkey_xfrm_policy2msg(struct
 	hdr->sadb_msg_reserved = atomic_read(&xp->refcnt);
 }
 
+static int key_notify_policy(struct xfrm_policy *xp, int dir, struct km_event *c)
+{
+	struct sk_buff *out_skb;
+	struct sadb_msg *out_hdr;
+	int err;
+
+	out_skb = pfkey_xfrm_policy2msg_prep(xp);
+	if (IS_ERR(out_skb)) {
+		err = PTR_ERR(out_skb);
+		goto out;
+	}
+	pfkey_xfrm_policy2msg(out_skb, xp, dir);
+
+	out_hdr = (struct sadb_msg *) out_skb->data;
+	out_hdr->sadb_msg_version = PF_KEY_V2;
+
+	if (c->data.byid && c->event == XFRM_MSG_DELPOLICY)
+		out_hdr->sadb_msg_type = SADB_X_SPDDELETE2;
+	else
+		out_hdr->sadb_msg_type = event2poltype(c->event);
+	out_hdr->sadb_msg_errno = 0;
+	out_hdr->sadb_msg_seq = c->seq;
+	out_hdr->sadb_msg_pid = c->pid;
+	pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ALL, NULL);
+out:
+	return 0;
+
+}
+
 static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs)
 {
 	int err;
@@ -1866,8 +1980,7 @@ static int pfkey_spdadd(struct sock *sk,
 	struct sadb_address *sa;
 	struct sadb_x_policy *pol;
 	struct xfrm_policy *xp;
-	struct sk_buff *out_skb;
-	struct sadb_msg *out_hdr;
+	struct km_event c;
 
 	if (!present_and_same_family(ext_hdrs[SADB_EXT_ADDRESS_SRC-1],
 				     ext_hdrs[SADB_EXT_ADDRESS_DST-1]) ||
@@ -1935,31 +2048,23 @@ static int pfkey_spdadd(struct sock *sk,
 	    (err = parse_ipsecrequests(xp, pol)) < 0)
 		goto out;
 
-	out_skb = pfkey_xfrm_policy2msg_prep(xp);
-	if (IS_ERR(out_skb)) {
-		err =  PTR_ERR(out_skb);
-		goto out;
-	}
-
 	err = xfrm_policy_insert(pol->sadb_x_policy_dir-1, xp,
 				 hdr->sadb_msg_type != SADB_X_SPDUPDATE);
 	if (err) {
-		kfree_skb(out_skb);
-		goto out;
+		kfree(xp);
+		return err;
 	}
 
-	pfkey_xfrm_policy2msg(out_skb, xp, pol->sadb_x_policy_dir-1);
+	if (hdr->sadb_msg_type == SADB_X_SPDUPDATE)
+		c.event = XFRM_MSG_UPDPOLICY;
+	else 
+		c.event = XFRM_MSG_NEWPOLICY;
 
-	xfrm_pol_put(xp);
+	c.seq = hdr->sadb_msg_seq;
+	c.pid = hdr->sadb_msg_pid;
 
-	out_hdr = (struct sadb_msg *) out_skb->data;
-	out_hdr->sadb_msg_version = hdr->sadb_msg_version;
-	out_hdr->sadb_msg_type = hdr->sadb_msg_type;
-	out_hdr->sadb_msg_satype = 0;
-	out_hdr->sadb_msg_errno = 0;
-	out_hdr->sadb_msg_seq = hdr->sadb_msg_seq;
-	out_hdr->sadb_msg_pid = hdr->sadb_msg_pid;
-	pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ALL, sk);
+	km_policy_notify(xp, pol->sadb_x_policy_dir-1, &c);
+	xfrm_pol_put(xp);
 	return 0;
 
 out:
@@ -1973,9 +2078,8 @@ static int pfkey_spddelete(struct sock *
 	struct sadb_address *sa;
 	struct sadb_x_policy *pol;
 	struct xfrm_policy *xp;
-	struct sk_buff *out_skb;
-	struct sadb_msg *out_hdr;
 	struct xfrm_selector sel;
+	struct km_event c;
 
 	if (!present_and_same_family(ext_hdrs[SADB_EXT_ADDRESS_SRC-1],
 				     ext_hdrs[SADB_EXT_ADDRESS_DST-1]) ||
@@ -2010,25 +2114,40 @@ static int pfkey_spddelete(struct sock *
 
 	err = 0;
 
+	c.seq = hdr->sadb_msg_seq;
+	c.pid = hdr->sadb_msg_pid;
+	c.event = XFRM_MSG_DELPOLICY;
+	km_policy_notify(xp, pol->sadb_x_policy_dir-1, &c);
+
+	xfrm_pol_put(xp);
+	return err;
+}
+
+static int key_pol_get_resp(struct sock *sk, struct xfrm_policy *xp, struct sadb_msg *hdr, int dir)
+{
+	int err;
+	struct sk_buff *out_skb;
+	struct sadb_msg *out_hdr;
+	err = 0;
+
 	out_skb = pfkey_xfrm_policy2msg_prep(xp);
 	if (IS_ERR(out_skb)) {
 		err =  PTR_ERR(out_skb);
 		goto out;
 	}
-	pfkey_xfrm_policy2msg(out_skb, xp, pol->sadb_x_policy_dir-1);
+	pfkey_xfrm_policy2msg(out_skb, xp, dir);
 
 	out_hdr = (struct sadb_msg *) out_skb->data;
 	out_hdr->sadb_msg_version = hdr->sadb_msg_version;
-	out_hdr->sadb_msg_type = SADB_X_SPDDELETE;
+	out_hdr->sadb_msg_type = hdr->sadb_msg_type;
 	out_hdr->sadb_msg_satype = 0;
 	out_hdr->sadb_msg_errno = 0;
 	out_hdr->sadb_msg_seq = hdr->sadb_msg_seq;
 	out_hdr->sadb_msg_pid = hdr->sadb_msg_pid;
-	pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ALL, sk);
+	pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ONE, sk);
 	err = 0;
 
 out:
-	xfrm_pol_put(xp);
 	return err;
 }
 
@@ -2037,8 +2156,7 @@ static int pfkey_spdget(struct sock *sk,
 	int err;
 	struct sadb_x_policy *pol;
 	struct xfrm_policy *xp;
-	struct sk_buff *out_skb;
-	struct sadb_msg *out_hdr;
+	struct km_event c;
 
 	if ((pol = ext_hdrs[SADB_X_EXT_POLICY-1]) == NULL)
 		return -EINVAL;
@@ -2050,24 +2168,16 @@ static int pfkey_spdget(struct sock *sk,
 
 	err = 0;
 
-	out_skb = pfkey_xfrm_policy2msg_prep(xp);
-	if (IS_ERR(out_skb)) {
-		err =  PTR_ERR(out_skb);
-		goto out;
+	c.seq = hdr->sadb_msg_seq;
+	c.pid = hdr->sadb_msg_pid;
+	if (hdr->sadb_msg_type == SADB_X_SPDDELETE2) {
+		c.data.byid = 1;
+		c.event = XFRM_MSG_DELPOLICY;
+		km_policy_notify(xp, pol->sadb_x_policy_dir-1, &c);
+	} else {
+		err = key_pol_get_resp(sk, xp, hdr, pol->sadb_x_policy_dir-1);
 	}
-	pfkey_xfrm_policy2msg(out_skb, xp, pol->sadb_x_policy_dir-1);
 
-	out_hdr = (struct sadb_msg *) out_skb->data;
-	out_hdr->sadb_msg_version = hdr->sadb_msg_version;
-	out_hdr->sadb_msg_type = hdr->sadb_msg_type;
-	out_hdr->sadb_msg_satype = 0;
-	out_hdr->sadb_msg_errno = 0;
-	out_hdr->sadb_msg_seq = hdr->sadb_msg_seq;
-	out_hdr->sadb_msg_pid = hdr->sadb_msg_pid;
-	pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ALL, sk);
-	err = 0;
-
-out:
 	xfrm_pol_put(xp);
 	return err;
 }
@@ -2102,22 +2212,34 @@ static int pfkey_spddump(struct sock *sk
 	return xfrm_policy_walk(dump_sp, &data);
 }
 
-static int pfkey_spdflush(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs)
+static int key_notify_policy_flush(struct km_event *c)
 {
 	struct sk_buff *skb_out;
-	struct sadb_msg *hdr_out;
+	struct sadb_msg *hdr;
 
-	skb_out = alloc_skb(sizeof(struct sadb_msg) + 16, GFP_KERNEL);
+	skb_out = alloc_skb(sizeof(struct sadb_msg) + 16, GFP_ATOMIC);
 	if (!skb_out)
 		return -ENOBUFS;
+	hdr = (struct sadb_msg *) skb_put(skb_out, sizeof(struct sadb_msg));
+	hdr->sadb_msg_seq = c->seq;
+	hdr->sadb_msg_pid = c->pid;
+	hdr->sadb_msg_version = PF_KEY_V2;
+	hdr->sadb_msg_errno = (uint8_t) 0;
+	hdr->sadb_msg_len = (sizeof(struct sadb_msg) / sizeof(uint64_t));
+	pfkey_broadcast(skb_out, GFP_ATOMIC, BROADCAST_ALL, NULL);
+	return 0;
 
-	xfrm_policy_flush();
+}
 
-	hdr_out = (struct sadb_msg *) skb_put(skb_out, sizeof(struct sadb_msg));
-	pfkey_hdr_dup(hdr_out, hdr);
-	hdr_out->sadb_msg_errno = (uint8_t) 0;
-	hdr_out->sadb_msg_len = (sizeof(struct sadb_msg) / sizeof(uint64_t));
-	pfkey_broadcast(skb_out, GFP_KERNEL, BROADCAST_ALL, NULL);
+static int pfkey_spdflush(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs)
+{
+	struct km_event c;
+
+	xfrm_policy_flush();
+	c.event = XFRM_MSG_FLUSHPOLICY;
+	c.pid = hdr->sadb_msg_pid;
+	c.seq = hdr->sadb_msg_seq;
+	km_policy_notify(NULL, 0, &c);
 
 	return 0;
 }
@@ -2317,11 +2439,23 @@ static void dump_esp_combs(struct sk_buf
 	}
 }
 
-static int pfkey_send_notify(struct xfrm_state *x, int hard)
+static int key_notify_policy_expire(struct xfrm_policy *xp, struct km_event *c)
+{
+	return 0;
+}
+
+static int key_notify_sa_expire(struct xfrm_state *x, struct km_event *c)
 {
 	struct sk_buff *out_skb;
 	struct sadb_msg *out_hdr;
-	int hsc = (hard ? 2 : 1);
+	int hard;
+	int hsc;
+
+	hard = c->data.hard;
+	if (hard)
+		hsc = 2;
+	else
+		hsc = 1;
 
 	out_skb = pfkey_xfrm_state2msg(x, 0, hsc);
 	if (IS_ERR(out_skb))
@@ -2340,6 +2474,44 @@ static int pfkey_send_notify(struct xfrm
 	return 0;
 }
 
+static int pfkey_send_notify(struct xfrm_state *x, struct km_event *c)
+{
+	switch (c->event) {
+	case XFRM_MSG_EXPIRE:
+		return key_notify_sa_expire(x, c);
+	case XFRM_MSG_DELSA:
+	case XFRM_MSG_NEWSA:
+	case XFRM_MSG_UPDSA:
+		return key_notify_sa(x, c);
+	case XFRM_MSG_FLUSHSA:
+		return key_notify_sa_flush(c);
+	default:
+		printk("pfkey: Unknown SA event %d\n", c->event);
+		break;
+	}
+
+	return 0;
+}
+
+static int pfkey_send_policy_notify(struct xfrm_policy *xp, int dir, struct km_event *c)
+{
+	switch (c->event) {
+	case XFRM_MSG_POLEXPIRE:
+		return key_notify_policy_expire(xp, c);
+	case XFRM_MSG_DELPOLICY:
+	case XFRM_MSG_NEWPOLICY:
+	case XFRM_MSG_UPDPOLICY:
+		return key_notify_policy(xp, dir, c);
+	case XFRM_MSG_FLUSHPOLICY:
+		return key_notify_policy_flush(c);
+	default:
+		printk("pfkey: Unknown policy event %d\n", c->event);
+		break;
+	}
+
+	return 0;
+}
+
 static u32 get_acqseq(void)
 {
 	u32 res;
@@ -2856,6 +3028,7 @@ static struct xfrm_mgr pfkeyv2_mgr =
 	.acquire	= pfkey_send_acquire,
 	.compile_policy	= pfkey_compile_policy,
 	.new_mapping	= pfkey_send_new_mapping,
+	.notify_policy	= pfkey_send_policy_notify,
 };
 
 static void __exit ipsec_pfkey_exit(void)
diff --git a/net/lapb/Kconfig b/net/lapb/Kconfig
new file mode 100644
--- /dev/null
+++ b/net/lapb/Kconfig
@@ -0,0 +1,22 @@
+#
+# LAPB Data Link Drive
+#
+
+config LAPB
+	tristate "LAPB Data Link Driver (EXPERIMENTAL)"
+	depends on EXPERIMENTAL
+	---help---
+	  Link Access Procedure, Balanced (LAPB) is the data link layer (i.e.
+	  the lower) part of the X.25 protocol. It offers a reliable
+	  connection service to exchange data frames with one other host, and
+	  it is used to transport higher level protocols (mostly X.25 Packet
+	  Layer, the higher part of X.25, but others are possible as well).
+	  Usually, LAPB is used with specialized X.21 network cards, but Linux
+	  currently supports LAPB only over Ethernet connections. If you want
+	  to use LAPB connections over Ethernet, say Y here and to "LAPB over
+	  Ethernet driver" below. Read
+	  <file:Documentation/networking/lapb-module.txt> for technical
+	  details.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called lapb.  If unsure, say N.
diff --git a/net/llc/llc_c_ev.c b/net/llc/llc_c_ev.c
--- a/net/llc/llc_c_ev.c
+++ b/net/llc/llc_c_ev.c
@@ -84,7 +84,7 @@ static u16 llc_util_nr_inside_tx_window(
 	if (llc->dev->flags & IFF_LOOPBACK)
 		goto out;
 	rc = 1;
-	if (!skb_queue_len(&llc->pdu_unack_q))
+	if (skb_queue_empty(&llc->pdu_unack_q))
 		goto out;
 	skb = skb_peek(&llc->pdu_unack_q);
 	pdu = llc_pdu_sn_hdr(skb);
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -315,8 +315,8 @@ err:
 static void netlink_remove(struct sock *sk)
 {
 	netlink_table_grab();
-	nl_table[sk->sk_protocol].hash.entries--;
-	sk_del_node_init(sk);
+	if (sk_del_node_init(sk))
+		nl_table[sk->sk_protocol].hash.entries--;
 	if (nlk_sk(sk)->groups)
 		__sk_del_bind_node(sk);
 	netlink_table_ungrab();
@@ -429,7 +429,12 @@ retry:
 	err = netlink_insert(sk, pid);
 	if (err == -EADDRINUSE)
 		goto retry;
-	return 0;
+
+	/* If 2 threads race to autobind, that is fine.  */
+	if (err == -EBUSY)
+		err = 0;
+
+	return err;
 }
 
 static inline int netlink_capable(struct socket *sock, unsigned int flag) 
@@ -643,7 +648,8 @@ void netlink_detachskb(struct sock *sk, 
 	sock_put(sk);
 }
 
-static inline struct sk_buff *netlink_trim(struct sk_buff *skb, int allocation)
+static inline struct sk_buff *netlink_trim(struct sk_buff *skb,
+					   unsigned int __nocast allocation)
 {
 	int delta;
 
@@ -712,7 +718,7 @@ struct netlink_broadcast_data {
 	int failure;
 	int congested;
 	int delivered;
-	int allocation;
+	unsigned int allocation;
 	struct sk_buff *skb, *skb2;
 };
 
@@ -853,7 +859,7 @@ static inline void netlink_rcv_wake(stru
 {
 	struct netlink_sock *nlk = nlk_sk(sk);
 
-	if (!skb_queue_len(&sk->sk_receive_queue))
+	if (skb_queue_empty(&sk->sk_receive_queue))
 		clear_bit(0, &nlk->state);
 	if (!test_bit(0, &nlk->state))
 		wake_up_interruptible(&nlk->wait);
@@ -1095,8 +1101,7 @@ static int netlink_dump(struct sock *sk)
 		return 0;
 	}
 
-	nlh = __nlmsg_put(skb, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq, NLMSG_DONE, sizeof(int));
-	nlh->nlmsg_flags |= NLM_F_MULTI;
+	nlh = NLMSG_NEW_ANSWER(skb, cb, NLMSG_DONE, sizeof(len), NLM_F_MULTI);
 	memcpy(NLMSG_DATA(nlh), &len, sizeof(len));
 	skb_queue_tail(&sk->sk_receive_queue, skb);
 	sk->sk_data_ready(sk, skb->len);
@@ -1107,6 +1112,9 @@ static int netlink_dump(struct sock *sk)
 
 	netlink_destroy_callback(cb);
 	return 0;
+
+nlmsg_failure:
+	return -ENOBUFS;
 }
 
 int netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
@@ -1178,7 +1186,7 @@ void netlink_ack(struct sk_buff *in_skb,
 	}
 
 	rep = __nlmsg_put(skb, NETLINK_CB(in_skb).pid, nlh->nlmsg_seq,
-			  NLMSG_ERROR, sizeof(struct nlmsgerr));
+			  NLMSG_ERROR, sizeof(struct nlmsgerr), 0);
 	errmsg = NLMSG_DATA(rep);
 	errmsg->error = err;
 	memcpy(&errmsg->msg, nlh, err ? nlh->nlmsg_len : sizeof(struct nlmsghdr));
diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c
--- a/net/netrom/af_netrom.c
+++ b/net/netrom/af_netrom.c
@@ -459,12 +459,7 @@ static struct sock *nr_make_new(struct s
 	sk->sk_sndbuf   = osk->sk_sndbuf;
 	sk->sk_state    = TCP_ESTABLISHED;
 	sk->sk_sleep    = osk->sk_sleep;
-
-	if (sock_flag(osk, SOCK_ZAPPED))
-		sock_set_flag(sk, SOCK_ZAPPED);
-
-	if (sock_flag(osk, SOCK_DBG))
-		sock_set_flag(sk, SOCK_DBG);
+	sock_copy_flags(sk, osk);
 
 	skb_queue_head_init(&nr->ack_queue);
 	skb_queue_head_init(&nr->reseq_queue);
@@ -541,7 +536,8 @@ static int nr_bind(struct socket *sock, 
 	struct nr_sock *nr = nr_sk(sk);
 	struct full_sockaddr_ax25 *addr = (struct full_sockaddr_ax25 *)uaddr;
 	struct net_device *dev;
-	ax25_address *user, *source;
+	ax25_uid_assoc *user;
+	ax25_address *source;
 
 	lock_sock(sk);
 	if (!sock_flag(sk, SOCK_ZAPPED)) {
@@ -580,16 +576,19 @@ static int nr_bind(struct socket *sock, 
 	} else {
 		source = &addr->fsa_ax25.sax25_call;
 
-		if ((user = ax25_findbyuid(current->euid)) == NULL) {
+		user = ax25_findbyuid(current->euid);
+		if (user) {
+			nr->user_addr   = user->call;
+			ax25_uid_put(user);
+		} else {
 			if (ax25_uid_policy && !capable(CAP_NET_BIND_SERVICE)) {
 				release_sock(sk);
 				dev_put(dev);
 				return -EPERM;
 			}
-			user = source;
+			nr->user_addr   = *source;
 		}
 
-		nr->user_addr   = *user;
 		nr->source_addr = *source;
 	}
 
@@ -609,7 +608,8 @@ static int nr_connect(struct socket *soc
 	struct sock *sk = sock->sk;
 	struct nr_sock *nr = nr_sk(sk);
 	struct sockaddr_ax25 *addr = (struct sockaddr_ax25 *)uaddr;
-	ax25_address *user, *source = NULL;
+	ax25_address *source = NULL;
+	ax25_uid_assoc *user;
 	struct net_device *dev;
 
 	lock_sock(sk);
@@ -650,16 +650,19 @@ static int nr_connect(struct socket *soc
 		}
 		source = (ax25_address *)dev->dev_addr;
 
-		if ((user = ax25_findbyuid(current->euid)) == NULL) {
+		user = ax25_findbyuid(current->euid);
+		if (user) {
+			nr->user_addr   = user->call;
+			ax25_uid_put(user);
+		} else {
 			if (ax25_uid_policy && !capable(CAP_NET_ADMIN)) {
 				dev_put(dev);
 				release_sock(sk);
 				return -EPERM;
 			}
-			user = source;
+			nr->user_addr   = *source;
 		}
 
-		nr->user_addr   = *user;
 		nr->source_addr = *source;
 		nr->device      = dev;
 
diff --git a/net/packet/Kconfig b/net/packet/Kconfig
new file mode 100644
--- /dev/null
+++ b/net/packet/Kconfig
@@ -0,0 +1,26 @@
+#
+# Packet configuration
+#
+
+config PACKET
+	tristate "Packet socket"
+	---help---
+	  The Packet protocol is used by applications which communicate
+	  directly with network devices without an intermediate network
+	  protocol implemented in the kernel, e.g. tcpdump.  If you want them
+	  to work, choose Y.
+
+	  To compile this driver as a module, choose M here: the module will
+	  be called af_packet.
+
+	  If unsure, say Y.
+
+config PACKET_MMAP
+	bool "Packet socket: mmapped IO"
+	depends on PACKET
+	help
+	  If you say Y here, the Packet protocol driver will use an IO
+	  mechanism that results in faster communication.
+
+	  If unsure, say N.
+
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -274,6 +274,9 @@ static int packet_rcv_spkt(struct sk_buf
 	dst_release(skb->dst);
 	skb->dst = NULL;
 
+	/* drop conntrack reference */
+	nf_reset(skb);
+
 	spkt = (struct sockaddr_pkt*)skb->cb;
 
 	skb_push(skb, skb->data-skb->mac.raw);
@@ -517,6 +520,9 @@ static int packet_rcv(struct sk_buff *sk
 	dst_release(skb->dst);
 	skb->dst = NULL;
 
+	/* drop conntrack reference */
+	nf_reset(skb);
+
 	spin_lock(&sk->sk_receive_queue.lock);
 	po->stats.tp_packets++;
 	__skb_queue_tail(&sk->sk_receive_queue, skb);
diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c
--- a/net/rose/af_rose.c
+++ b/net/rose/af_rose.c
@@ -556,12 +556,7 @@ static struct sock *rose_make_new(struct
 	sk->sk_sndbuf   = osk->sk_sndbuf;
 	sk->sk_state    = TCP_ESTABLISHED;
 	sk->sk_sleep    = osk->sk_sleep;
-
-	if (sock_flag(osk, SOCK_ZAPPED))
-		sock_set_flag(sk, SOCK_ZAPPED);
-
-	if (sock_flag(osk, SOCK_DBG))
-		sock_set_flag(sk, SOCK_DBG);
+	sock_copy_flags(sk, osk);
 
 	init_timer(&rose->timer);
 	init_timer(&rose->idletimer);
@@ -631,7 +626,8 @@ static int rose_bind(struct socket *sock
 	struct rose_sock *rose = rose_sk(sk);
 	struct sockaddr_rose *addr = (struct sockaddr_rose *)uaddr;
 	struct net_device *dev;
-	ax25_address *user, *source;
+	ax25_address *source;
+	ax25_uid_assoc *user;
 	int n;
 
 	if (!sock_flag(sk, SOCK_ZAPPED))
@@ -656,14 +652,17 @@ static int rose_bind(struct socket *sock
 
 	source = &addr->srose_call;
 
-	if ((user = ax25_findbyuid(current->euid)) == NULL) {
+	user = ax25_findbyuid(current->euid);
+	if (user) {
+		rose->source_call = user->call;
+		ax25_uid_put(user);
+	} else {
 		if (ax25_uid_policy && !capable(CAP_NET_BIND_SERVICE))
 			return -EACCES;
-		user = source;
+		rose->source_call   = *source;
 	}
 
 	rose->source_addr   = addr->srose_addr;
-	rose->source_call   = *user;
 	rose->device        = dev;
 	rose->source_ndigis = addr->srose_ndigis;
 
@@ -690,8 +689,8 @@ static int rose_connect(struct socket *s
 	struct rose_sock *rose = rose_sk(sk);
 	struct sockaddr_rose *addr = (struct sockaddr_rose *)uaddr;
 	unsigned char cause, diagnostic;
-	ax25_address *user;
 	struct net_device *dev;
+	ax25_uid_assoc *user;
 	int n;
 
 	if (sk->sk_state == TCP_ESTABLISHED && sock->state == SS_CONNECTING) {
@@ -741,12 +740,14 @@ static int rose_connect(struct socket *s
 		if ((dev = rose_dev_first()) == NULL)
 			return -ENETUNREACH;
 
-		if ((user = ax25_findbyuid(current->euid)) == NULL)
+		user = ax25_findbyuid(current->euid);
+		if (!user)
 			return -EINVAL;
 
 		memcpy(&rose->source_addr, dev->dev_addr, ROSE_ADDR_LEN);
-		rose->source_call = *user;
+		rose->source_call = user->call;
 		rose->device      = dev;
+		ax25_uid_put(user);
 
 		rose_insert_socket(sk);		/* Finish the bind */
 	}
diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c
--- a/net/rose/rose_route.c
+++ b/net/rose/rose_route.c
@@ -994,8 +994,10 @@ int rose_route_frame(struct sk_buff *skb
 	 *	1. The frame isn't for us,
 	 *	2. It isn't "owned" by any existing route.
 	 */
-	if (frametype != ROSE_CALL_REQUEST)	/* XXX */
-		return 0;
+	if (frametype != ROSE_CALL_REQUEST) {	/* XXX */
+		res = 0;
+		goto out;
+	}
 
 	len  = (((skb->data[3] >> 4) & 0x0F) + 1) / 2;
 	len += (((skb->data[3] >> 0) & 0x0F) + 1) / 2;
diff --git a/net/rxrpc/krxiod.c b/net/rxrpc/krxiod.c
--- a/net/rxrpc/krxiod.c
+++ b/net/rxrpc/krxiod.c
@@ -138,7 +138,7 @@ static int rxrpc_krxiod(void *arg)
 
 		_debug("### End Work");
 
-		try_to_freeze(PF_FREEZE);
+		try_to_freeze();
 
                 /* discard pending signals */
 		rxrpc_discard_my_signals();
diff --git a/net/rxrpc/krxsecd.c b/net/rxrpc/krxsecd.c
--- a/net/rxrpc/krxsecd.c
+++ b/net/rxrpc/krxsecd.c
@@ -107,7 +107,7 @@ static int rxrpc_krxsecd(void *arg)
 
 		_debug("### End Inbound Calls");
 
-		try_to_freeze(PF_FREEZE);
+		try_to_freeze();
 
                 /* discard pending signals */
 		rxrpc_discard_my_signals();
diff --git a/net/rxrpc/krxtimod.c b/net/rxrpc/krxtimod.c
--- a/net/rxrpc/krxtimod.c
+++ b/net/rxrpc/krxtimod.c
@@ -90,7 +90,7 @@ static int krxtimod(void *arg)
 			complete_and_exit(&krxtimod_dead, 0);
 		}
 
-		try_to_freeze(PF_FREEZE);
+		try_to_freeze();
 
 		/* discard pending signals */
 		rxrpc_discard_my_signals();
diff --git a/net/sched/Kconfig b/net/sched/Kconfig
--- a/net/sched/Kconfig
+++ b/net/sched/Kconfig
@@ -1,6 +1,43 @@
 #
 # Traffic control configuration.
 # 
+
+menuconfig NET_SCHED
+	bool "QoS and/or fair queueing"
+	---help---
+	  When the kernel has several packets to send out over a network
+	  device, it has to decide which ones to send first, which ones to
+	  delay, and which ones to drop. This is the job of the packet
+	  scheduler, and several different algorithms for how to do this
+	  "fairly" have been proposed.
+
+	  If you say N here, you will get the standard packet scheduler, which
+	  is a FIFO (first come, first served). If you say Y here, you will be
+	  able to choose from among several alternative algorithms which can
+	  then be attached to different network devices. This is useful for
+	  example if some of your network devices are real time devices that
+	  need a certain minimum data flow rate, or if you need to limit the
+	  maximum data flow rate for traffic which matches specified criteria.
+	  This code is considered to be experimental.
+
+	  To administer these schedulers, you'll need the user-level utilities
+	  from the package iproute2+tc at <ftp://ftp.tux.org/pub/net/ip-routing/>.
+	  That package also contains some documentation; for more, check out
+	  <http://snafu.freedom.org/linux2.2/iproute-notes.html>.
+
+	  This Quality of Service (QoS) support will enable you to use
+	  Differentiated Services (diffserv) and Resource Reservation Protocol
+	  (RSVP) on your Linux router if you also say Y to "QoS support",
+	  "Packet classifier API" and to some classifiers below. Documentation
+	  and software is at <http://diffserv.sourceforge.net/>.
+
+	  If you say Y here and to "/proc file system" below, you will be able
+	  to read status information about packet schedulers from the file
+	  /proc/net/psched.
+
+	  The available schedulers are listed in the following questions; you
+	  can say Y to as many as you like. If unsure, say N now.
+
 choice
 	prompt "Packet scheduler clock source"
 	depends on NET_SCHED
@@ -449,6 +486,19 @@ config NET_EMATCH_META
 	  To compile this code as a module, choose M here: the
 	  module will be called em_meta.
 
+config NET_EMATCH_TEXT
+	tristate "Textsearch"
+	depends on NET_EMATCH
+	select TEXTSEARCH
+	select TEXTSEARCH_KMP
+	select TEXTSEARCH_FSM
+	---help---
+	  Say Y here if you want to be ablt to classify packets based on
+	  textsearch comparisons.
+
+	  To compile this code as a module, choose M here: the
+	  module will be called em_text.
+
 config NET_CLS_ACT
 	bool "Packet ACTION"
 	depends on EXPERIMENTAL && NET_CLS && NET_QOS
diff --git a/net/sched/Makefile b/net/sched/Makefile
--- a/net/sched/Makefile
+++ b/net/sched/Makefile
@@ -4,7 +4,7 @@
 
 obj-y	:= sch_generic.o
 
-obj-$(CONFIG_NET_SCHED)		+= sch_api.o sch_fifo.o
+obj-$(CONFIG_NET_SCHED)		+= sch_api.o sch_fifo.o sch_blackhole.o
 obj-$(CONFIG_NET_CLS)		+= cls_api.o
 obj-$(CONFIG_NET_CLS_ACT)	+= act_api.o
 obj-$(CONFIG_NET_ACT_POLICE)	+= police.o
@@ -40,3 +40,4 @@ obj-$(CONFIG_NET_EMATCH_CMP)	+= em_cmp.o
 obj-$(CONFIG_NET_EMATCH_NBYTE)	+= em_nbyte.o
 obj-$(CONFIG_NET_EMATCH_U32)	+= em_u32.o
 obj-$(CONFIG_NET_EMATCH_META)	+= em_meta.o
+obj-$(CONFIG_NET_EMATCH_TEXT)	+= em_text.o
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -428,17 +428,19 @@ errout:
 
 static int
 tca_get_fill(struct sk_buff *skb, struct tc_action *a, u32 pid, u32 seq,
-             unsigned flags, int event, int bind, int ref)
+             u16 flags, int event, int bind, int ref)
 {
 	struct tcamsg *t;
 	struct nlmsghdr *nlh;
 	unsigned char *b = skb->tail;
 	struct rtattr *x;
 
-	nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(*t));
-	nlh->nlmsg_flags = flags;
+	nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*t), flags);
+
 	t = NLMSG_DATA(nlh);
 	t->tca_family = AF_UNSPEC;
+	t->tca__pad1 = 0;
+	t->tca__pad2 = 0;
 	
 	x = (struct rtattr*) skb->tail;
 	RTA_PUT(skb, TCA_ACT_TAB, 0, NULL);
@@ -580,6 +582,8 @@ static int tca_action_flush(struct rtatt
 	nlh = NLMSG_PUT(skb, pid, n->nlmsg_seq, RTM_DELACTION, sizeof(*t));
 	t = NLMSG_DATA(nlh);
 	t->tca_family = AF_UNSPEC;
+	t->tca__pad1 = 0;
+	t->tca__pad2 = 0;
 
 	x = (struct rtattr *) skb->tail;
 	RTA_PUT(skb, TCA_ACT_TAB, 0, NULL);
@@ -669,7 +673,7 @@ err:
 }
 
 static int tcf_add_notify(struct tc_action *a, u32 pid, u32 seq, int event,
-                          unsigned flags)
+                          u16 flags)
 {
 	struct tcamsg *t;
 	struct nlmsghdr *nlh;
@@ -684,11 +688,12 @@ static int tcf_add_notify(struct tc_acti
 
 	b = (unsigned char *)skb->tail;
 
-	nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(*t));
-	nlh->nlmsg_flags = flags;
+	nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*t), flags);
 	t = NLMSG_DATA(nlh);
 	t->tca_family = AF_UNSPEC;
-	
+	t->tca__pad1 = 0;
+	t->tca__pad2 = 0;
+
 	x = (struct rtattr*) skb->tail;
 	RTA_PUT(skb, TCA_ACT_TAB, 0, NULL);
 
@@ -843,6 +848,8 @@ tc_dump_action(struct sk_buff *skb, stru
 	                cb->nlh->nlmsg_type, sizeof(*t));
 	t = NLMSG_DATA(nlh);
 	t->tca_family = AF_UNSPEC;
+	t->tca__pad1 = 0;
+	t->tca__pad2 = 0;
 
 	x = (struct rtattr *) skb->tail;
 	RTA_PUT(skb, TCA_ACT_TAB, 0, NULL);
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -322,16 +322,17 @@ errout:
 
 static int
 tcf_fill_node(struct sk_buff *skb, struct tcf_proto *tp, unsigned long fh,
-	      u32 pid, u32 seq, unsigned flags, int event)
+	      u32 pid, u32 seq, u16 flags, int event)
 {
 	struct tcmsg *tcm;
 	struct nlmsghdr  *nlh;
 	unsigned char	 *b = skb->tail;
 
-	nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(*tcm));
-	nlh->nlmsg_flags = flags;
+	nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*tcm), flags);
 	tcm = NLMSG_DATA(nlh);
 	tcm->tcm_family = AF_UNSPEC;
+	tcm->tcm__pad1 = 0;
+	tcm->tcm__pad1 = 0;
 	tcm->tcm_ifindex = tp->q->dev->ifindex;
 	tcm->tcm_parent = tp->classid;
 	tcm->tcm_info = TC_H_MAKE(tp->prio, tp->protocol);
diff --git a/net/sched/cls_rsvp.h b/net/sched/cls_rsvp.h
--- a/net/sched/cls_rsvp.h
+++ b/net/sched/cls_rsvp.h
@@ -618,6 +618,7 @@ static int rsvp_dump(struct tcf_proto *t
 	pinfo.protocol = s->protocol;
 	pinfo.tunnelid = s->tunnelid;
 	pinfo.tunnelhdr = f->tunnelhdr;
+	pinfo.pad = 0;
 	RTA_PUT(skb, TCA_RSVP_PINFO, sizeof(pinfo), &pinfo);
 	if (f->res.classid)
 		RTA_PUT(skb, TCA_RSVP_CLASSID, 4, &f->res.classid);
diff --git a/net/sched/em_meta.c b/net/sched/em_meta.c
--- a/net/sched/em_meta.c
+++ b/net/sched/em_meta.c
@@ -27,17 +27,17 @@
  * 	         lvalue                                   rvalue
  * 	      +-----------+                           +-----------+
  * 	      | type: INT |                           | type: INT |
- * 	 def  | id: INDEV |                           | id: VALUE |
+ * 	 def  | id: DEV   |                           | id: VALUE |
  * 	      | data:     |                           | data: 3   |
  * 	      +-----------+                           +-----------+
  * 	            |                                       |
- * 	            ---> meta_ops[INT][INDEV](...)          |
+ * 	            ---> meta_ops[INT][DEV](...)            |
  *	                      |                             |
  * 	            -----------                             |
  * 	            V                                       V
  * 	      +-----------+                           +-----------+
  * 	      | type: INT |                           | type: INT |
- * 	 obj  | id: INDEV |                           | id: VALUE |
+ * 	 obj  | id: DEV |                             | id: VALUE |
  * 	      | data: 2   |<--data got filled out     | data: 3   |
  * 	      +-----------+                           +-----------+
  * 	            |                                         |
@@ -170,26 +170,6 @@ META_COLLECTOR(var_dev)
 	*err = var_dev(skb->dev, dst);
 }
 
-META_COLLECTOR(int_indev)
-{
-	*err = int_dev(skb->input_dev, dst);
-}
-
-META_COLLECTOR(var_indev)
-{
-	*err = var_dev(skb->input_dev, dst);
-}
-
-META_COLLECTOR(int_realdev)
-{
-	*err = int_dev(skb->real_dev, dst);
-}
-
-META_COLLECTOR(var_realdev)
-{
-	*err = var_dev(skb->real_dev, dst);
-}
-
 /**************************************************************************
  * skb attributes
  **************************************************************************/
@@ -205,11 +185,6 @@ META_COLLECTOR(int_protocol)
 	dst->value = skb->protocol;
 }
 
-META_COLLECTOR(int_security)
-{
-	dst->value = skb->security;
-}
-
 META_COLLECTOR(int_pkttype)
 {
 	dst->value = skb->pkt_type;
@@ -234,12 +209,14 @@ META_COLLECTOR(int_maclen)
  * Netfilter
  **************************************************************************/
 
-#ifdef CONFIG_NETFILTER
 META_COLLECTOR(int_nfmark)
 {
+#ifdef CONFIG_NETFILTER
 	dst->value = skb->nfmark;
-}
+#else
+	dst->value = 0;
 #endif
+}
 
 /**************************************************************************
  * Traffic Control
@@ -250,31 +227,21 @@ META_COLLECTOR(int_tcindex)
 	dst->value = skb->tc_index;
 }
 
-#ifdef CONFIG_NET_CLS_ACT
-META_COLLECTOR(int_tcverd)
-{
-	dst->value = skb->tc_verd;
-}
-
-META_COLLECTOR(int_tcclassid)
-{
-	dst->value = skb->tc_classid;
-}
-#endif
-
 /**************************************************************************
  * Routing
  **************************************************************************/
 
-#ifdef CONFIG_NET_CLS_ROUTE
 META_COLLECTOR(int_rtclassid)
 {
 	if (unlikely(skb->dst == NULL))
 		*err = -1;
 	else
+#ifdef CONFIG_NET_CLS_ROUTE
 		dst->value = skb->dst->tclassid;
-}
+#else
+		dst->value = 0;
 #endif
+}
 
 META_COLLECTOR(int_rtiif)
 {
@@ -510,8 +477,6 @@ struct meta_ops
 static struct meta_ops __meta_ops[TCF_META_TYPE_MAX+1][TCF_META_ID_MAX+1] = {
 	[TCF_META_TYPE_VAR] = {
 		[META_ID(DEV)]			= META_FUNC(var_dev),
-		[META_ID(INDEV)]		= META_FUNC(var_indev),
-		[META_ID(REALDEV)]		= META_FUNC(var_realdev),
 		[META_ID(SK_BOUND_IF)] 		= META_FUNC(var_sk_bound_if),
 	},
 	[TCF_META_TYPE_INT] = {
@@ -520,26 +485,15 @@ static struct meta_ops __meta_ops[TCF_ME
 		[META_ID(LOADAVG_1)]		= META_FUNC(int_loadavg_1),
 		[META_ID(LOADAVG_2)]		= META_FUNC(int_loadavg_2),
 		[META_ID(DEV)]			= META_FUNC(int_dev),
-		[META_ID(INDEV)]		= META_FUNC(int_indev),
-		[META_ID(REALDEV)]		= META_FUNC(int_realdev),
 		[META_ID(PRIORITY)]		= META_FUNC(int_priority),
 		[META_ID(PROTOCOL)]		= META_FUNC(int_protocol),
-		[META_ID(SECURITY)]		= META_FUNC(int_security),
 		[META_ID(PKTTYPE)]		= META_FUNC(int_pkttype),
 		[META_ID(PKTLEN)]		= META_FUNC(int_pktlen),
 		[META_ID(DATALEN)]		= META_FUNC(int_datalen),
 		[META_ID(MACLEN)]		= META_FUNC(int_maclen),
-#ifdef CONFIG_NETFILTER
 		[META_ID(NFMARK)]		= META_FUNC(int_nfmark),
-#endif
 		[META_ID(TCINDEX)]		= META_FUNC(int_tcindex),
-#ifdef CONFIG_NET_CLS_ACT
-		[META_ID(TCVERDICT)]		= META_FUNC(int_tcverd),
-		[META_ID(TCCLASSID)]		= META_FUNC(int_tcclassid),
-#endif
-#ifdef CONFIG_NET_CLS_ROUTE
 		[META_ID(RTCLASSID)]		= META_FUNC(int_rtclassid),
-#endif
 		[META_ID(RTIIF)]		= META_FUNC(int_rtiif),
 		[META_ID(SK_FAMILY)]		= META_FUNC(int_sk_family),
 		[META_ID(SK_STATE)]		= META_FUNC(int_sk_state),
diff --git a/net/sched/em_text.c b/net/sched/em_text.c
new file mode 100644
--- /dev/null
+++ b/net/sched/em_text.c
@@ -0,0 +1,154 @@
+/*
+ * net/sched/em_text.c	Textsearch ematch
+ *
+ *		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.
+ *
+ * Authors:	Thomas Graf <tgraf@suug.ch>
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/skbuff.h>
+#include <linux/textsearch.h>
+#include <linux/tc_ematch/tc_em_text.h>
+#include <net/pkt_cls.h>
+
+struct text_match
+{
+	u16			from_offset;
+	u16			to_offset;
+	u8			from_layer;
+	u8			to_layer;
+	struct ts_config	*config;
+};
+
+#define EM_TEXT_PRIV(m) ((struct text_match *) (m)->data)
+
+static int em_text_match(struct sk_buff *skb, struct tcf_ematch *m,
+			 struct tcf_pkt_info *info)
+{
+	struct text_match *tm = EM_TEXT_PRIV(m);
+	int from, to;
+	struct ts_state state;
+
+	from = tcf_get_base_ptr(skb, tm->from_layer) - skb->data;
+	from += tm->from_offset;
+
+	to = tcf_get_base_ptr(skb, tm->to_layer) - skb->data;
+	to += tm->to_offset;
+
+	return skb_find_text(skb, from, to, tm->config, &state) != UINT_MAX;
+}
+
+static int em_text_change(struct tcf_proto *tp, void *data, int len,
+			  struct tcf_ematch *m)
+{
+	struct text_match *tm;
+	struct tcf_em_text *conf = data;
+	struct ts_config *ts_conf;
+	int flags = 0;
+
+	if (len < sizeof(*conf) || len < (sizeof(*conf) + conf->pattern_len))
+		return -EINVAL;
+
+	if (conf->from_layer > conf->to_layer)
+		return -EINVAL;
+
+	if (conf->from_layer == conf->to_layer &&
+	    conf->from_offset > conf->to_offset)
+		return -EINVAL;
+
+retry:
+	ts_conf = textsearch_prepare(conf->algo, (u8 *) conf + sizeof(*conf),
+				     conf->pattern_len, GFP_KERNEL, flags);
+
+	if (flags & TS_AUTOLOAD)
+		rtnl_lock();
+
+	if (IS_ERR(ts_conf)) {
+		if (PTR_ERR(ts_conf) == -ENOENT && !(flags & TS_AUTOLOAD)) {
+			rtnl_unlock();
+			flags |= TS_AUTOLOAD;
+			goto retry;
+		} else
+			return PTR_ERR(ts_conf);
+	} else if (flags & TS_AUTOLOAD) {
+		textsearch_destroy(ts_conf);
+		return -EAGAIN;
+	}
+
+	tm = kmalloc(sizeof(*tm), GFP_KERNEL);
+	if (tm == NULL) {
+		textsearch_destroy(ts_conf);
+		return -ENOBUFS;
+	}
+
+	tm->from_offset = conf->from_offset;
+	tm->to_offset   = conf->to_offset;
+	tm->from_layer  = conf->from_layer;
+	tm->to_layer    = conf->to_layer;
+	tm->config      = ts_conf;
+
+	m->datalen = sizeof(*tm);
+	m->data = (unsigned long) tm;
+
+	return 0;
+}
+
+static void em_text_destroy(struct tcf_proto *tp, struct tcf_ematch *m)
+{
+	textsearch_destroy(EM_TEXT_PRIV(m)->config);
+}
+
+static int em_text_dump(struct sk_buff *skb, struct tcf_ematch *m)
+{
+	struct text_match *tm = EM_TEXT_PRIV(m);
+	struct tcf_em_text conf;
+
+	strncpy(conf.algo, tm->config->ops->name, sizeof(conf.algo) - 1);
+	conf.from_offset = tm->from_offset;
+	conf.to_offset = tm->to_offset;
+	conf.from_layer = tm->from_layer;
+	conf.to_layer = tm->to_layer;
+	conf.pattern_len = textsearch_get_pattern_len(tm->config);
+	conf.pad = 0;
+
+	RTA_PUT_NOHDR(skb, sizeof(conf), &conf);
+	RTA_APPEND(skb, conf.pattern_len, textsearch_get_pattern(tm->config));
+	return 0;
+
+rtattr_failure:
+	return -1;
+}		
+
+static struct tcf_ematch_ops em_text_ops = {
+	.kind	  = TCF_EM_TEXT,
+	.change	  = em_text_change,
+	.match	  = em_text_match,
+	.destroy  = em_text_destroy,
+	.dump	  = em_text_dump,
+	.owner	  = THIS_MODULE,
+	.link	  = LIST_HEAD_INIT(em_text_ops.link)
+};
+
+static int __init init_em_text(void)
+{
+	return tcf_em_register(&em_text_ops);
+}
+
+static void __exit exit_em_text(void) 
+{
+	tcf_em_unregister(&em_text_ops);
+}
+
+MODULE_LICENSE("GPL");
+
+module_init(init_em_text);
+module_exit(exit_em_text);
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -399,10 +399,8 @@ qdisc_create(struct net_device *dev, u32
 {
 	int err;
 	struct rtattr *kind = tca[TCA_KIND-1];
-	void *p = NULL;
 	struct Qdisc *sch;
 	struct Qdisc_ops *ops;
-	int size;
 
 	ops = qdisc_lookup_ops(kind);
 #ifdef CONFIG_KMOD
@@ -437,64 +435,55 @@ qdisc_create(struct net_device *dev, u32
 	if (ops == NULL)
 		goto err_out;
 
-	/* ensure that the Qdisc and the private data are 32-byte aligned */
-	size = ((sizeof(*sch) + QDISC_ALIGN_CONST) & ~QDISC_ALIGN_CONST);
-	size += ops->priv_size + QDISC_ALIGN_CONST;
-
-	p = kmalloc(size, GFP_KERNEL);
-	err = -ENOBUFS;
-	if (!p)
+	sch = qdisc_alloc(dev, ops);
+	if (IS_ERR(sch)) {
+		err = PTR_ERR(sch);
 		goto err_out2;
-	memset(p, 0, size);
-	sch = (struct Qdisc *)(((unsigned long)p + QDISC_ALIGN_CONST)
-	                       & ~QDISC_ALIGN_CONST);
-	sch->padded = (char *)sch - (char *)p;
-
-	INIT_LIST_HEAD(&sch->list);
-	skb_queue_head_init(&sch->q);
+	}
 
-	if (handle == TC_H_INGRESS)
+	if (handle == TC_H_INGRESS) {
 		sch->flags |= TCQ_F_INGRESS;
-
-	sch->ops = ops;
-	sch->enqueue = ops->enqueue;
-	sch->dequeue = ops->dequeue;
-	sch->dev = dev;
-	dev_hold(dev);
-	atomic_set(&sch->refcnt, 1);
-	sch->stats_lock = &dev->queue_lock;
-	if (handle == 0) {
+		handle = TC_H_MAKE(TC_H_INGRESS, 0);
+	} else if (handle == 0) {
 		handle = qdisc_alloc_handle(dev);
 		err = -ENOMEM;
 		if (handle == 0)
 			goto err_out3;
 	}
 
-	if (handle == TC_H_INGRESS)
-                sch->handle =TC_H_MAKE(TC_H_INGRESS, 0);
-        else
-                sch->handle = handle;
+	sch->handle = handle;
 
 	if (!ops->init || (err = ops->init(sch, tca[TCA_OPTIONS-1])) == 0) {
+#ifdef CONFIG_NET_ESTIMATOR
+		if (tca[TCA_RATE-1]) {
+			err = gen_new_estimator(&sch->bstats, &sch->rate_est,
+						sch->stats_lock,
+						tca[TCA_RATE-1]);
+			if (err) {
+				/*
+				 * Any broken qdiscs that would require
+				 * a ops->reset() here? The qdisc was never
+				 * in action so it shouldn't be necessary.
+				 */
+				if (ops->destroy)
+					ops->destroy(sch);
+				goto err_out3;
+			}
+		}
+#endif
 		qdisc_lock_tree(dev);
 		list_add_tail(&sch->list, &dev->qdisc_list);
 		qdisc_unlock_tree(dev);
 
-#ifdef CONFIG_NET_ESTIMATOR
-		if (tca[TCA_RATE-1])
-			gen_new_estimator(&sch->bstats, &sch->rate_est,
-				sch->stats_lock, tca[TCA_RATE-1]);
-#endif
 		return sch;
 	}
 err_out3:
 	dev_put(dev);
+	kfree((char *) sch - sch->padded);
 err_out2:
 	module_put(ops->owner);
 err_out:
 	*errp = err;
-	if (p)
-		kfree(p);
 	return NULL;
 }
 
@@ -760,17 +749,18 @@ graft:
 }
 
 static int tc_fill_qdisc(struct sk_buff *skb, struct Qdisc *q, u32 clid,
-			 u32 pid, u32 seq, unsigned flags, int event)
+			 u32 pid, u32 seq, u16 flags, int event)
 {
 	struct tcmsg *tcm;
 	struct nlmsghdr  *nlh;
 	unsigned char	 *b = skb->tail;
 	struct gnet_dump d;
 
-	nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(*tcm));
-	nlh->nlmsg_flags = flags;
+	nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*tcm), flags);
 	tcm = NLMSG_DATA(nlh);
 	tcm->tcm_family = AF_UNSPEC;
+	tcm->tcm__pad1 = 0;
+	tcm->tcm__pad2 = 0;
 	tcm->tcm_ifindex = q->dev->ifindex;
 	tcm->tcm_parent = clid;
 	tcm->tcm_handle = q->handle;
@@ -997,7 +987,7 @@ out:
 
 static int tc_fill_tclass(struct sk_buff *skb, struct Qdisc *q,
 			  unsigned long cl,
-			  u32 pid, u32 seq, unsigned flags, int event)
+			  u32 pid, u32 seq, u16 flags, int event)
 {
 	struct tcmsg *tcm;
 	struct nlmsghdr  *nlh;
@@ -1005,8 +995,7 @@ static int tc_fill_tclass(struct sk_buff
 	struct gnet_dump d;
 	struct Qdisc_class_ops *cl_ops = q->ops->cl_ops;
 
-	nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(*tcm));
-	nlh->nlmsg_flags = flags;
+	nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*tcm), flags);
 	tcm = NLMSG_DATA(nlh);
 	tcm->tcm_family = AF_UNSPEC;
 	tcm->tcm_ifindex = q->dev->ifindex;
diff --git a/net/sched/sch_blackhole.c b/net/sched/sch_blackhole.c
new file mode 100644
--- /dev/null
+++ b/net/sched/sch_blackhole.c
@@ -0,0 +1,54 @@
+/*
+ * net/sched/sch_blackhole.c	Black hole queue
+ *
+ *		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.
+ *
+ * Authors:	Thomas Graf <tgraf@suug.ch>
+ *
+ * Note: Quantum tunneling is not supported.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
+#include <net/pkt_sched.h>
+
+static int blackhole_enqueue(struct sk_buff *skb, struct Qdisc *sch)
+{
+	qdisc_drop(skb, sch);
+	return NET_XMIT_SUCCESS;
+}
+
+static struct sk_buff *blackhole_dequeue(struct Qdisc *sch)
+{
+	return NULL;
+}
+
+static struct Qdisc_ops blackhole_qdisc_ops = {
+	.id		= "blackhole",
+	.priv_size	= 0,
+	.enqueue	= blackhole_enqueue,
+	.dequeue	= blackhole_dequeue,
+	.owner		= THIS_MODULE,
+};
+
+static int __init blackhole_module_init(void)
+{
+	return register_qdisc(&blackhole_qdisc_ops);
+}
+
+static void __exit blackhole_module_exit(void)
+{
+	unregister_qdisc(&blackhole_qdisc_ops);
+}
+
+module_init(blackhole_module_init)
+module_exit(blackhole_module_exit)
+
+MODULE_LICENSE("GPL");
diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c
--- a/net/sched/sch_cbq.c
+++ b/net/sched/sch_cbq.c
@@ -1528,6 +1528,7 @@ static __inline__ int cbq_dump_ovl(struc
 
 	opt.strategy = cl->ovl_strategy;
 	opt.priority2 = cl->priority2+1;
+	opt.pad = 0;
 	opt.penalty = (cl->penalty*1000)/HZ;
 	RTA_PUT(skb, TCA_CBQ_OVL_STRATEGY, sizeof(opt), &opt);
 	return skb->len;
@@ -1563,6 +1564,8 @@ static __inline__ int cbq_dump_police(st
 
 	if (cl->police) {
 		opt.police = cl->police;
+		opt.__res1 = 0;
+		opt.__res2 = 0;
 		RTA_PUT(skb, TCA_CBQ_POLICE, sizeof(opt), &opt);
 	}
 	return skb->len;
diff --git a/net/sched/sch_dsmark.c b/net/sched/sch_dsmark.c
--- a/net/sched/sch_dsmark.c
+++ b/net/sched/sch_dsmark.c
@@ -31,7 +31,7 @@
 #endif
 
 
-#define PRIV(sch) qdisc_priv(sch)
+#define PRIV(sch) ((struct dsmark_qdisc_data *) qdisc_priv(sch))
 
 
 /*
@@ -55,24 +55,38 @@
 struct dsmark_qdisc_data {
 	struct Qdisc		*q;
 	struct tcf_proto	*filter_list;
-	__u8			*mask;	/* "owns" the array */
-	__u8			*value;
-	__u16			indices;
-	__u32			default_index;	/* index range is 0...0xffff */
+	u8			*mask;	/* "owns" the array */
+	u8			*value;
+	u16			indices;
+	u32			default_index;	/* index range is 0...0xffff */
 	int			set_tc_index;
 };
 
+static inline int dsmark_valid_indices(u16 indices)
+{
+	while (indices != 1) {
+		if (indices & 1)
+			return 0;
+		indices >>= 1;
+	}
+ 
+	return 1;
+}
 
-/* ------------------------- Class/flow operations ------------------------- */
+static inline int dsmark_valid_index(struct dsmark_qdisc_data *p, u16 index)
+{
+	return (index <= p->indices && index > 0);
+}
 
+/* ------------------------- Class/flow operations ------------------------- */
 
-static int dsmark_graft(struct Qdisc *sch,unsigned long arg,
-    struct Qdisc *new,struct Qdisc **old)
+static int dsmark_graft(struct Qdisc *sch, unsigned long arg,
+			struct Qdisc *new, struct Qdisc **old)
 {
 	struct dsmark_qdisc_data *p = PRIV(sch);
 
-	DPRINTK("dsmark_graft(sch %p,[qdisc %p],new %p,old %p)\n",sch,p,new,
-	    old);
+	DPRINTK("dsmark_graft(sch %p,[qdisc %p],new %p,old %p)\n",
+		sch, p, new, old);
 
 	if (new == NULL) {
 		new = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops);
@@ -81,91 +95,95 @@ static int dsmark_graft(struct Qdisc *sc
 	}
 
 	sch_tree_lock(sch);
-	*old = xchg(&p->q,new);
-	if (*old)
-		qdisc_reset(*old);
+	*old = xchg(&p->q, new);
+	qdisc_reset(*old);
 	sch->q.qlen = 0;
-	sch_tree_unlock(sch); /* @@@ move up ? */
+	sch_tree_unlock(sch);
+
         return 0;
 }
 
-
 static struct Qdisc *dsmark_leaf(struct Qdisc *sch, unsigned long arg)
 {
-	struct dsmark_qdisc_data *p = PRIV(sch);
-
-	return p->q;
+	return PRIV(sch)->q;
 }
 
-
-static unsigned long dsmark_get(struct Qdisc *sch,u32 classid)
+static unsigned long dsmark_get(struct Qdisc *sch, u32 classid)
 {
-	struct dsmark_qdisc_data *p __attribute__((unused)) = PRIV(sch);
+	DPRINTK("dsmark_get(sch %p,[qdisc %p],classid %x)\n",
+		sch, PRIV(sch), classid);
 
-	DPRINTK("dsmark_get(sch %p,[qdisc %p],classid %x)\n",sch,p,classid);
-	return TC_H_MIN(classid)+1;
+	return TC_H_MIN(classid) + 1;
 }
 
-
 static unsigned long dsmark_bind_filter(struct Qdisc *sch,
-    unsigned long parent, u32 classid)
+					unsigned long parent, u32 classid)
 {
-	return dsmark_get(sch,classid);
+	return dsmark_get(sch, classid);
 }
 
-
 static void dsmark_put(struct Qdisc *sch, unsigned long cl)
 {
 }
 
-
 static int dsmark_change(struct Qdisc *sch, u32 classid, u32 parent,
-    struct rtattr **tca, unsigned long *arg)
+			 struct rtattr **tca, unsigned long *arg)
 {
 	struct dsmark_qdisc_data *p = PRIV(sch);
 	struct rtattr *opt = tca[TCA_OPTIONS-1];
 	struct rtattr *tb[TCA_DSMARK_MAX];
+	int err = -EINVAL;
+	u8 mask = 0;
 
 	DPRINTK("dsmark_change(sch %p,[qdisc %p],classid %x,parent %x),"
-	    "arg 0x%lx\n",sch,p,classid,parent,*arg);
-	if (*arg > p->indices)
-		return -ENOENT;
-	if (!opt || rtattr_parse_nested(tb, TCA_DSMARK_MAX, opt))
-		return -EINVAL;
-	if (tb[TCA_DSMARK_MASK-1]) {
-		if (!RTA_PAYLOAD(tb[TCA_DSMARK_MASK-1]))
-			return -EINVAL;
-		p->mask[*arg-1] = *(__u8 *) RTA_DATA(tb[TCA_DSMARK_MASK-1]);
-	}
-	if (tb[TCA_DSMARK_VALUE-1]) {
-		if (!RTA_PAYLOAD(tb[TCA_DSMARK_VALUE-1]))
-			return -EINVAL;
-		p->value[*arg-1] = *(__u8 *) RTA_DATA(tb[TCA_DSMARK_VALUE-1]);
+		"arg 0x%lx\n", sch, p, classid, parent, *arg);
+
+	if (!dsmark_valid_index(p, *arg)) {
+		err = -ENOENT;
+		goto rtattr_failure;
 	}
-	return 0;
-}
 
+	if (!opt || rtattr_parse_nested(tb, TCA_DSMARK_MAX, opt))
+		goto rtattr_failure;
+
+	if (tb[TCA_DSMARK_MASK-1])
+		mask = RTA_GET_U8(tb[TCA_DSMARK_MASK-1]);
+
+	if (tb[TCA_DSMARK_VALUE-1])
+		p->value[*arg-1] = RTA_GET_U8(tb[TCA_DSMARK_VALUE-1]);
+		
+	if (tb[TCA_DSMARK_MASK-1])
+		p->mask[*arg-1] = mask;
 
-static int dsmark_delete(struct Qdisc *sch,unsigned long arg)
+	err = 0;
+
+rtattr_failure:
+	return err;
+}
+
+static int dsmark_delete(struct Qdisc *sch, unsigned long arg)
 {
 	struct dsmark_qdisc_data *p = PRIV(sch);
 
-	if (!arg || arg > p->indices)
+	if (!dsmark_valid_index(p, arg))
 		return -EINVAL;
+	
 	p->mask[arg-1] = 0xff;
 	p->value[arg-1] = 0;
+
 	return 0;
 }
 
-
 static void dsmark_walk(struct Qdisc *sch,struct qdisc_walker *walker)
 {
 	struct dsmark_qdisc_data *p = PRIV(sch);
 	int i;
 
-	DPRINTK("dsmark_walk(sch %p,[qdisc %p],walker %p)\n",sch,p,walker);
+	DPRINTK("dsmark_walk(sch %p,[qdisc %p],walker %p)\n", sch, p, walker);
+
 	if (walker->stop)
 		return;
+
 	for (i = 0; i < p->indices; i++) {
 		if (p->mask[i] == 0xff && !p->value[i])
 			goto ignore;
@@ -180,26 +198,20 @@ ignore:		
         }
 }
 
-
 static struct tcf_proto **dsmark_find_tcf(struct Qdisc *sch,unsigned long cl)
 {
-	struct dsmark_qdisc_data *p = PRIV(sch);
-
-	return &p->filter_list;
+	return &PRIV(sch)->filter_list;
 }
 
-
 /* --------------------------- Qdisc operations ---------------------------- */
 
-
 static int dsmark_enqueue(struct sk_buff *skb,struct Qdisc *sch)
 {
 	struct dsmark_qdisc_data *p = PRIV(sch);
-	struct tcf_result res;
-	int result;
-	int ret = NET_XMIT_POLICED;
+	int err;
+
+	D2PRINTK("dsmark_enqueue(skb %p,sch %p,[qdisc %p])\n", skb, sch, p);
 
-	D2PRINTK("dsmark_enqueue(skb %p,sch %p,[qdisc %p])\n",skb,sch,p);
 	if (p->set_tc_index) {
 		/* FIXME: Safe with non-linear skbs? --RR */
 		switch (skb->protocol) {
@@ -216,17 +228,21 @@ static int dsmark_enqueue(struct sk_buff
 				break;
 		};
 	}
-	result = TC_POLICE_OK; /* be nice to gcc */
-	if (TC_H_MAJ(skb->priority) == sch->handle) {
+
+	if (TC_H_MAJ(skb->priority) == sch->handle)
 		skb->tc_index = TC_H_MIN(skb->priority);
-	} else {
-		result = tc_classify(skb,p->filter_list,&res);
-		D2PRINTK("result %d class 0x%04x\n",result,res.classid);
+	else {
+		struct tcf_result res;
+		int result = tc_classify(skb, p->filter_list, &res);
+
+		D2PRINTK("result %d class 0x%04x\n", result, res.classid);
+
 		switch (result) {
 #ifdef CONFIG_NET_CLS_POLICE
 			case TC_POLICE_SHOT:
 				kfree_skb(skb);
-				break;
+				sch->qstats.drops++;
+				return NET_XMIT_POLICED;
 #if 0
 			case TC_POLICE_RECLASSIFY:
 				/* FIXME: what to do here ??? */
@@ -243,43 +259,45 @@ static int dsmark_enqueue(struct sk_buff
 				break;
 		};
 	}
-	if (
-#ifdef CONFIG_NET_CLS_POLICE
-	    result == TC_POLICE_SHOT ||
-#endif
 
-	    ((ret = p->q->enqueue(skb,p->q)) != 0)) {
+	err = p->q->enqueue(skb,p->q);
+	if (err != NET_XMIT_SUCCESS) {
 		sch->qstats.drops++;
-		return ret;
+		return err;
 	}
+
 	sch->bstats.bytes += skb->len;
 	sch->bstats.packets++;
 	sch->q.qlen++;
-	return ret;
-}
 
+	return NET_XMIT_SUCCESS;
+}
 
 static struct sk_buff *dsmark_dequeue(struct Qdisc *sch)
 {
 	struct dsmark_qdisc_data *p = PRIV(sch);
 	struct sk_buff *skb;
-	int index;
+	u32 index;
+
+	D2PRINTK("dsmark_dequeue(sch %p,[qdisc %p])\n", sch, p);
 
-	D2PRINTK("dsmark_dequeue(sch %p,[qdisc %p])\n",sch,p);
 	skb = p->q->ops->dequeue(p->q);
-	if (!skb)
+	if (skb == NULL)
 		return NULL;
+
 	sch->q.qlen--;
-	index = skb->tc_index & (p->indices-1);
-	D2PRINTK("index %d->%d\n",skb->tc_index,index);
+
+	index = skb->tc_index & (p->indices - 1);
+	D2PRINTK("index %d->%d\n", skb->tc_index, index);
+
 	switch (skb->protocol) {
 		case __constant_htons(ETH_P_IP):
-			ipv4_change_dsfield(skb->nh.iph,
-			    p->mask[index],p->value[index]);
+			ipv4_change_dsfield(skb->nh.iph, p->mask[index],
+					    p->value[index]);
 			break;
 		case __constant_htons(ETH_P_IPV6):
-			ipv6_change_dsfield(skb->nh.ipv6h,
-			    p->mask[index],p->value[index]);
+			ipv6_change_dsfield(skb->nh.ipv6h, p->mask[index],
+					    p->value[index]);
 			break;
 		default:
 			/*
@@ -293,152 +311,162 @@ static struct sk_buff *dsmark_dequeue(st
 				       htons(skb->protocol));
 			break;
 	};
+
 	return skb;
 }
 
-
 static int dsmark_requeue(struct sk_buff *skb,struct Qdisc *sch)
 {
-	int ret;
 	struct dsmark_qdisc_data *p = PRIV(sch);
+	int err;
 
-	D2PRINTK("dsmark_requeue(skb %p,sch %p,[qdisc %p])\n",skb,sch,p);
-        if ((ret = p->q->ops->requeue(skb, p->q)) == 0) {
-		sch->q.qlen++;
-		sch->qstats.requeues++;
-		return 0;
+	D2PRINTK("dsmark_requeue(skb %p,sch %p,[qdisc %p])\n", skb, sch, p);
+
+	err = p->q->ops->requeue(skb, p->q);
+	if (err != NET_XMIT_SUCCESS) {
+		sch->qstats.drops++;
+		return err;
 	}
-	sch->qstats.drops++;
-	return ret;
-}
 
+	sch->q.qlen++;
+	sch->qstats.requeues++;
+
+	return NET_XMIT_SUCCESS;
+}
 
 static unsigned int dsmark_drop(struct Qdisc *sch)
 {
 	struct dsmark_qdisc_data *p = PRIV(sch);
 	unsigned int len;
 	
-	DPRINTK("dsmark_reset(sch %p,[qdisc %p])\n",sch,p);
-	if (!p->q->ops->drop)
-		return 0;
-	if (!(len = p->q->ops->drop(p->q)))
+	DPRINTK("dsmark_reset(sch %p,[qdisc %p])\n", sch, p);
+
+	if (p->q->ops->drop == NULL)
 		return 0;
-	sch->q.qlen--;
+
+	len = p->q->ops->drop(p->q);
+	if (len)
+		sch->q.qlen--;
+
 	return len;
 }
 
-
-static int dsmark_init(struct Qdisc *sch,struct rtattr *opt)
+static int dsmark_init(struct Qdisc *sch, struct rtattr *opt)
 {
 	struct dsmark_qdisc_data *p = PRIV(sch);
 	struct rtattr *tb[TCA_DSMARK_MAX];
-	__u16 tmp;
+	int err = -EINVAL;
+	u32 default_index = NO_DEFAULT_INDEX;
+	u16 indices;
+	u8 *mask;
 
-	DPRINTK("dsmark_init(sch %p,[qdisc %p],opt %p)\n",sch,p,opt);
-	if (!opt ||
-	    rtattr_parse(tb,TCA_DSMARK_MAX,RTA_DATA(opt),RTA_PAYLOAD(opt)) < 0 ||
-	    !tb[TCA_DSMARK_INDICES-1] ||
-	    RTA_PAYLOAD(tb[TCA_DSMARK_INDICES-1]) < sizeof(__u16))
-                return -EINVAL;
-	p->indices = *(__u16 *) RTA_DATA(tb[TCA_DSMARK_INDICES-1]);
-	if (!p->indices)
-		return -EINVAL;
-	for (tmp = p->indices; tmp != 1; tmp >>= 1) {
-		if (tmp & 1)
-			return -EINVAL;
-	}
-	p->default_index = NO_DEFAULT_INDEX;
-	if (tb[TCA_DSMARK_DEFAULT_INDEX-1]) {
-		if (RTA_PAYLOAD(tb[TCA_DSMARK_DEFAULT_INDEX-1]) < sizeof(__u16))
-			return -EINVAL;
-		p->default_index =
-		    *(__u16 *) RTA_DATA(tb[TCA_DSMARK_DEFAULT_INDEX-1]);
+	DPRINTK("dsmark_init(sch %p,[qdisc %p],opt %p)\n", sch, p, opt);
+
+	if (!opt || rtattr_parse_nested(tb, TCA_DSMARK_MAX, opt) < 0)
+		goto errout;
+
+	indices = RTA_GET_U16(tb[TCA_DSMARK_INDICES-1]);
+	if (!indices || !dsmark_valid_indices(indices))
+		goto errout;
+
+	if (tb[TCA_DSMARK_DEFAULT_INDEX-1])
+		default_index = RTA_GET_U16(tb[TCA_DSMARK_DEFAULT_INDEX-1]);
+
+	mask = kmalloc(indices * 2, GFP_KERNEL);
+	if (mask == NULL) {
+		err = -ENOMEM;
+		goto errout;
 	}
-	p->set_tc_index = !!tb[TCA_DSMARK_SET_TC_INDEX-1];
-	p->mask = kmalloc(p->indices*2,GFP_KERNEL);
-	if (!p->mask)
-		return -ENOMEM;
-	p->value = p->mask+p->indices;
-	memset(p->mask,0xff,p->indices);
-	memset(p->value,0,p->indices);
-	if (!(p->q = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops)))
+
+	p->mask = mask;
+	memset(p->mask, 0xff, indices);
+
+	p->value = p->mask + indices;
+	memset(p->value, 0, indices);
+
+	p->indices = indices;
+	p->default_index = default_index;
+	p->set_tc_index = RTA_GET_FLAG(tb[TCA_DSMARK_SET_TC_INDEX-1]);
+
+	p->q = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops);
+	if (p->q == NULL)
 		p->q = &noop_qdisc;
-	DPRINTK("dsmark_init: qdisc %p\n",&p->q);
-	return 0;
-}
 
+	DPRINTK("dsmark_init: qdisc %p\n", p->q);
+
+	err = 0;
+errout:
+rtattr_failure:
+	return err;
+}
 
 static void dsmark_reset(struct Qdisc *sch)
 {
 	struct dsmark_qdisc_data *p = PRIV(sch);
 
-	DPRINTK("dsmark_reset(sch %p,[qdisc %p])\n",sch,p);
+	DPRINTK("dsmark_reset(sch %p,[qdisc %p])\n", sch, p);
 	qdisc_reset(p->q);
 	sch->q.qlen = 0;
 }
 
-
 static void dsmark_destroy(struct Qdisc *sch)
 {
 	struct dsmark_qdisc_data *p = PRIV(sch);
 	struct tcf_proto *tp;
 
-	DPRINTK("dsmark_destroy(sch %p,[qdisc %p])\n",sch,p);
+	DPRINTK("dsmark_destroy(sch %p,[qdisc %p])\n", sch, p);
+
 	while (p->filter_list) {
 		tp = p->filter_list;
 		p->filter_list = tp->next;
 		tcf_destroy(tp);
 	}
+
 	qdisc_destroy(p->q);
 	kfree(p->mask);
 }
 
-
 static int dsmark_dump_class(struct Qdisc *sch, unsigned long cl,
-    struct sk_buff *skb, struct tcmsg *tcm)
+			     struct sk_buff *skb, struct tcmsg *tcm)
 {
 	struct dsmark_qdisc_data *p = PRIV(sch);
-	unsigned char *b = skb->tail;
-	struct rtattr *rta;
+	struct rtattr *opts = NULL;
+
+	DPRINTK("dsmark_dump_class(sch %p,[qdisc %p],class %ld\n", sch, p, cl);
 
-	DPRINTK("dsmark_dump_class(sch %p,[qdisc %p],class %ld\n",sch,p,cl);
-	if (!cl || cl > p->indices)
+	if (!dsmark_valid_index(p, cl))
 		return -EINVAL;
-	tcm->tcm_handle = TC_H_MAKE(TC_H_MAJ(sch->handle),cl-1);
-	rta = (struct rtattr *) b;
-	RTA_PUT(skb,TCA_OPTIONS,0,NULL);
-	RTA_PUT(skb,TCA_DSMARK_MASK,1,&p->mask[cl-1]);
-	RTA_PUT(skb,TCA_DSMARK_VALUE,1,&p->value[cl-1]);
-	rta->rta_len = skb->tail-b;
-	return skb->len;
+
+	tcm->tcm_handle = TC_H_MAKE(TC_H_MAJ(sch->handle), cl-1);
+
+	opts = RTA_NEST(skb, TCA_OPTIONS);
+	RTA_PUT_U8(skb,TCA_DSMARK_MASK, p->mask[cl-1]);
+	RTA_PUT_U8(skb,TCA_DSMARK_VALUE, p->value[cl-1]);
+
+	return RTA_NEST_END(skb, opts);
 
 rtattr_failure:
-	skb_trim(skb,b-skb->data);
-	return -1;
+	return RTA_NEST_CANCEL(skb, opts);
 }
 
 static int dsmark_dump(struct Qdisc *sch, struct sk_buff *skb)
 {
 	struct dsmark_qdisc_data *p = PRIV(sch);
-	unsigned char *b = skb->tail;
-	struct rtattr *rta;
+	struct rtattr *opts = NULL;
 
-	rta = (struct rtattr *) b;
-	RTA_PUT(skb,TCA_OPTIONS,0,NULL);
-	RTA_PUT(skb,TCA_DSMARK_INDICES,sizeof(__u16),&p->indices);
-	if (p->default_index != NO_DEFAULT_INDEX) {
-		__u16 tmp = p->default_index;
+	opts = RTA_NEST(skb, TCA_OPTIONS);
+	RTA_PUT_U16(skb, TCA_DSMARK_INDICES, p->indices);
+
+	if (p->default_index != NO_DEFAULT_INDEX)
+		RTA_PUT_U16(skb, TCA_DSMARK_DEFAULT_INDEX, p->default_index);
 
-		RTA_PUT(skb,TCA_DSMARK_DEFAULT_INDEX, sizeof(__u16), &tmp);
-	}
 	if (p->set_tc_index)
-		RTA_PUT(skb, TCA_DSMARK_SET_TC_INDEX, 0, NULL);
-	rta->rta_len = skb->tail-b;
-	return skb->len;
+		RTA_PUT_FLAG(skb, TCA_DSMARK_SET_TC_INDEX);
+
+	return RTA_NEST_END(skb, opts);
 
 rtattr_failure:
-	skb_trim(skb,b-skb->data);
-	return -1;
+	return RTA_NEST_CANCEL(skb, opts);
 }
 
 static struct Qdisc_class_ops dsmark_class_ops = {
@@ -476,10 +504,13 @@ static int __init dsmark_module_init(voi
 {
 	return register_qdisc(&dsmark_qdisc_ops);
 }
+
 static void __exit dsmark_module_exit(void) 
 {
 	unregister_qdisc(&dsmark_qdisc_ops);
 }
+
 module_init(dsmark_module_init)
 module_exit(dsmark_module_exit)
+
 MODULE_LICENSE("GPL");
diff --git a/net/sched/sch_fifo.c b/net/sched/sch_fifo.c
--- a/net/sched/sch_fifo.c
+++ b/net/sched/sch_fifo.c
@@ -11,131 +11,38 @@
 
 #include <linux/config.h>
 #include <linux/module.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <linux/bitops.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/socket.h>
-#include <linux/sockios.h>
-#include <linux/in.h>
 #include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/if_ether.h>
-#include <linux/inet.h>
 #include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/notifier.h>
-#include <net/ip.h>
-#include <net/route.h>
 #include <linux/skbuff.h>
-#include <net/sock.h>
 #include <net/pkt_sched.h>
 
 /* 1 band FIFO pseudo-"scheduler" */
 
 struct fifo_sched_data
 {
-	unsigned limit;
+	u32 limit;
 };
 
-static int
-bfifo_enqueue(struct sk_buff *skb, struct Qdisc* sch)
+static int bfifo_enqueue(struct sk_buff *skb, struct Qdisc* sch)
 {
 	struct fifo_sched_data *q = qdisc_priv(sch);
 
-	if (sch->qstats.backlog + skb->len <= q->limit) {
-		__skb_queue_tail(&sch->q, skb);
-		sch->qstats.backlog += skb->len;
-		sch->bstats.bytes += skb->len;
-		sch->bstats.packets++;
-		return 0;
-	}
-	sch->qstats.drops++;
-#ifdef CONFIG_NET_CLS_POLICE
-	if (sch->reshape_fail==NULL || sch->reshape_fail(skb, sch))
-#endif
-		kfree_skb(skb);
-	return NET_XMIT_DROP;
-}
-
-static int
-bfifo_requeue(struct sk_buff *skb, struct Qdisc* sch)
-{
-	__skb_queue_head(&sch->q, skb);
-	sch->qstats.backlog += skb->len;
-	sch->qstats.requeues++;
-	return 0;
-}
-
-static struct sk_buff *
-bfifo_dequeue(struct Qdisc* sch)
-{
-	struct sk_buff *skb;
-
-	skb = __skb_dequeue(&sch->q);
-	if (skb)
-		sch->qstats.backlog -= skb->len;
-	return skb;
-}
-
-static unsigned int 
-fifo_drop(struct Qdisc* sch)
-{
-	struct sk_buff *skb;
-
-	skb = __skb_dequeue_tail(&sch->q);
-	if (skb) {
-		unsigned int len = skb->len;
-		sch->qstats.backlog -= len;
-		kfree_skb(skb);
-		return len;
-	}
-	return 0;
-}
+	if (likely(sch->qstats.backlog + skb->len <= q->limit))
+		return qdisc_enqueue_tail(skb, sch);
 
-static void
-fifo_reset(struct Qdisc* sch)
-{
-	skb_queue_purge(&sch->q);
-	sch->qstats.backlog = 0;
+	return qdisc_reshape_fail(skb, sch);
 }
 
-static int
-pfifo_enqueue(struct sk_buff *skb, struct Qdisc* sch)
+static int pfifo_enqueue(struct sk_buff *skb, struct Qdisc* sch)
 {
 	struct fifo_sched_data *q = qdisc_priv(sch);
 
-	if (sch->q.qlen < q->limit) {
-		__skb_queue_tail(&sch->q, skb);
-		sch->bstats.bytes += skb->len;
-		sch->bstats.packets++;
-		return 0;
-	}
-	sch->qstats.drops++;
-#ifdef CONFIG_NET_CLS_POLICE
-	if (sch->reshape_fail==NULL || sch->reshape_fail(skb, sch))
-#endif
-		kfree_skb(skb);
-	return NET_XMIT_DROP;
-}
+	if (likely(skb_queue_len(&sch->q) < q->limit))
+		return qdisc_enqueue_tail(skb, sch);
 
-static int
-pfifo_requeue(struct sk_buff *skb, struct Qdisc* sch)
-{
-	__skb_queue_head(&sch->q, skb);
-	sch->qstats.requeues++;
-	return 0;
-}
-
-
-static struct sk_buff *
-pfifo_dequeue(struct Qdisc* sch)
-{
-	return __skb_dequeue(&sch->q);
+	return qdisc_reshape_fail(skb, sch);
 }
 
 static int fifo_init(struct Qdisc *sch, struct rtattr *opt)
@@ -143,66 +50,59 @@ static int fifo_init(struct Qdisc *sch, 
 	struct fifo_sched_data *q = qdisc_priv(sch);
 
 	if (opt == NULL) {
-		unsigned int limit = sch->dev->tx_queue_len ? : 1;
+		u32 limit = sch->dev->tx_queue_len ? : 1;
 
 		if (sch->ops == &bfifo_qdisc_ops)
-			q->limit = limit*sch->dev->mtu;
-		else	
-			q->limit = limit;
+			limit *= sch->dev->mtu;
+
+		q->limit = limit;
 	} else {
 		struct tc_fifo_qopt *ctl = RTA_DATA(opt);
-		if (opt->rta_len < RTA_LENGTH(sizeof(*ctl)))
+
+		if (RTA_PAYLOAD(opt) < sizeof(*ctl))
 			return -EINVAL;
+
 		q->limit = ctl->limit;
 	}
+
 	return 0;
 }
 
 static int fifo_dump(struct Qdisc *sch, struct sk_buff *skb)
 {
 	struct fifo_sched_data *q = qdisc_priv(sch);
-	unsigned char	 *b = skb->tail;
-	struct tc_fifo_qopt opt;
+	struct tc_fifo_qopt opt = { .limit = q->limit };
 
-	opt.limit = q->limit;
 	RTA_PUT(skb, TCA_OPTIONS, sizeof(opt), &opt);
-
 	return skb->len;
 
 rtattr_failure:
-	skb_trim(skb, b - skb->data);
 	return -1;
 }
 
 struct Qdisc_ops pfifo_qdisc_ops = {
-	.next		=	NULL,
-	.cl_ops		=	NULL,
 	.id		=	"pfifo",
 	.priv_size	=	sizeof(struct fifo_sched_data),
 	.enqueue	=	pfifo_enqueue,
-	.dequeue	=	pfifo_dequeue,
-	.requeue	=	pfifo_requeue,
-	.drop		=	fifo_drop,
+	.dequeue	=	qdisc_dequeue_head,
+	.requeue	=	qdisc_requeue,
+	.drop		=	qdisc_queue_drop,
 	.init		=	fifo_init,
-	.reset		=	fifo_reset,
-	.destroy	=	NULL,
+	.reset		=	qdisc_reset_queue,
 	.change		=	fifo_init,
 	.dump		=	fifo_dump,
 	.owner		=	THIS_MODULE,
 };
 
 struct Qdisc_ops bfifo_qdisc_ops = {
-	.next		=	NULL,
-	.cl_ops		=	NULL,
 	.id		=	"bfifo",
 	.priv_size	=	sizeof(struct fifo_sched_data),
 	.enqueue	=	bfifo_enqueue,
-	.dequeue	=	bfifo_dequeue,
-	.requeue	=	bfifo_requeue,
-	.drop		=	fifo_drop,
+	.dequeue	=	qdisc_dequeue_head,
+	.requeue	=	qdisc_requeue,
+	.drop		=	qdisc_queue_drop,
 	.init		=	fifo_init,
-	.reset		=	fifo_reset,
-	.destroy	=	NULL,
+	.reset		=	qdisc_reset_queue,
 	.change		=	fifo_init,
 	.dump		=	fifo_dump,
 	.owner		=	THIS_MODULE,
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -243,31 +243,27 @@ static void dev_watchdog_down(struct net
    cheaper.
  */
 
-static int
-noop_enqueue(struct sk_buff *skb, struct Qdisc * qdisc)
+static int noop_enqueue(struct sk_buff *skb, struct Qdisc * qdisc)
 {
 	kfree_skb(skb);
 	return NET_XMIT_CN;
 }
 
-static struct sk_buff *
-noop_dequeue(struct Qdisc * qdisc)
+static struct sk_buff *noop_dequeue(struct Qdisc * qdisc)
 {
 	return NULL;
 }
 
-static int
-noop_requeue(struct sk_buff *skb, struct Qdisc* qdisc)
+static int noop_requeue(struct sk_buff *skb, struct Qdisc* qdisc)
 {
 	if (net_ratelimit())
-		printk(KERN_DEBUG "%s deferred output. It is buggy.\n", skb->dev->name);
+		printk(KERN_DEBUG "%s deferred output. It is buggy.\n",
+		       skb->dev->name);
 	kfree_skb(skb);
 	return NET_XMIT_CN;
 }
 
 struct Qdisc_ops noop_qdisc_ops = {
-	.next		=	NULL,
-	.cl_ops		=	NULL,
 	.id		=	"noop",
 	.priv_size	=	0,
 	.enqueue	=	noop_enqueue,
@@ -285,8 +281,6 @@ struct Qdisc noop_qdisc = {
 };
 
 static struct Qdisc_ops noqueue_qdisc_ops = {
-	.next		=	NULL,
-	.cl_ops		=	NULL,
 	.id		=	"noqueue",
 	.priv_size	=	0,
 	.enqueue	=	noop_enqueue,
@@ -311,97 +305,86 @@ static const u8 prio2band[TC_PRIO_MAX+1]
    generic prio+fifo combination.
  */
 
-static int
-pfifo_fast_enqueue(struct sk_buff *skb, struct Qdisc* qdisc)
+#define PFIFO_FAST_BANDS 3
+
+static inline struct sk_buff_head *prio2list(struct sk_buff *skb,
+					     struct Qdisc *qdisc)
 {
 	struct sk_buff_head *list = qdisc_priv(qdisc);
+	return list + prio2band[skb->priority & TC_PRIO_MAX];
+}
 
-	list += prio2band[skb->priority&TC_PRIO_MAX];
+static int pfifo_fast_enqueue(struct sk_buff *skb, struct Qdisc* qdisc)
+{
+	struct sk_buff_head *list = prio2list(skb, qdisc);
 
-	if (list->qlen < qdisc->dev->tx_queue_len) {
-		__skb_queue_tail(list, skb);
+	if (skb_queue_len(list) < qdisc->dev->tx_queue_len) {
 		qdisc->q.qlen++;
-		qdisc->bstats.bytes += skb->len;
-		qdisc->bstats.packets++;
-		return 0;
+		return __qdisc_enqueue_tail(skb, qdisc, list);
 	}
-	qdisc->qstats.drops++;
-	kfree_skb(skb);
-	return NET_XMIT_DROP;
+
+	return qdisc_drop(skb, qdisc);
 }
 
-static struct sk_buff *
-pfifo_fast_dequeue(struct Qdisc* qdisc)
+static struct sk_buff *pfifo_fast_dequeue(struct Qdisc* qdisc)
 {
 	int prio;
 	struct sk_buff_head *list = qdisc_priv(qdisc);
-	struct sk_buff *skb;
 
-	for (prio = 0; prio < 3; prio++, list++) {
-		skb = __skb_dequeue(list);
-		if (skb) {
+	for (prio = 0; prio < PFIFO_FAST_BANDS; prio++) {
+		if (!skb_queue_empty(list + prio)) {
 			qdisc->q.qlen--;
-			return skb;
+			return __qdisc_dequeue_head(qdisc, list + prio);
 		}
 	}
+
 	return NULL;
 }
 
-static int
-pfifo_fast_requeue(struct sk_buff *skb, struct Qdisc* qdisc)
+static int pfifo_fast_requeue(struct sk_buff *skb, struct Qdisc* qdisc)
 {
-	struct sk_buff_head *list = qdisc_priv(qdisc);
-
-	list += prio2band[skb->priority&TC_PRIO_MAX];
-
-	__skb_queue_head(list, skb);
 	qdisc->q.qlen++;
-	qdisc->qstats.requeues++;
-	return 0;
+	return __qdisc_requeue(skb, qdisc, prio2list(skb, qdisc));
 }
 
-static void
-pfifo_fast_reset(struct Qdisc* qdisc)
+static void pfifo_fast_reset(struct Qdisc* qdisc)
 {
 	int prio;
 	struct sk_buff_head *list = qdisc_priv(qdisc);
 
-	for (prio=0; prio < 3; prio++)
-		skb_queue_purge(list+prio);
+	for (prio = 0; prio < PFIFO_FAST_BANDS; prio++)
+		__qdisc_reset_queue(qdisc, list + prio);
+
+	qdisc->qstats.backlog = 0;
 	qdisc->q.qlen = 0;
 }
 
 static int pfifo_fast_dump(struct Qdisc *qdisc, struct sk_buff *skb)
 {
-	unsigned char	 *b = skb->tail;
-	struct tc_prio_qopt opt;
+	struct tc_prio_qopt opt = { .bands = PFIFO_FAST_BANDS };
 
-	opt.bands = 3; 
 	memcpy(&opt.priomap, prio2band, TC_PRIO_MAX+1);
 	RTA_PUT(skb, TCA_OPTIONS, sizeof(opt), &opt);
 	return skb->len;
 
 rtattr_failure:
-	skb_trim(skb, b - skb->data);
 	return -1;
 }
 
 static int pfifo_fast_init(struct Qdisc *qdisc, struct rtattr *opt)
 {
-	int i;
+	int prio;
 	struct sk_buff_head *list = qdisc_priv(qdisc);
 
-	for (i=0; i<3; i++)
-		skb_queue_head_init(list+i);
+	for (prio = 0; prio < PFIFO_FAST_BANDS; prio++)
+		skb_queue_head_init(list + prio);
 
 	return 0;
 }
 
 static struct Qdisc_ops pfifo_fast_ops = {
-	.next		=	NULL,
-	.cl_ops		=	NULL,
 	.id		=	"pfifo_fast",
-	.priv_size	=	3 * sizeof(struct sk_buff_head),
+	.priv_size	=	PFIFO_FAST_BANDS * sizeof(struct sk_buff_head),
 	.enqueue	=	pfifo_fast_enqueue,
 	.dequeue	=	pfifo_fast_dequeue,
 	.requeue	=	pfifo_fast_requeue,
@@ -411,24 +394,23 @@ static struct Qdisc_ops pfifo_fast_ops =
 	.owner		=	THIS_MODULE,
 };
 
-struct Qdisc * qdisc_create_dflt(struct net_device *dev, struct Qdisc_ops *ops)
+struct Qdisc *qdisc_alloc(struct net_device *dev, struct Qdisc_ops *ops)
 {
 	void *p;
 	struct Qdisc *sch;
-	int size;
+	unsigned int size;
+	int err = -ENOBUFS;
 
 	/* ensure that the Qdisc and the private data are 32-byte aligned */
-	size = ((sizeof(*sch) + QDISC_ALIGN_CONST) & ~QDISC_ALIGN_CONST);
-	size += ops->priv_size + QDISC_ALIGN_CONST;
+	size = QDISC_ALIGN(sizeof(*sch));
+	size += ops->priv_size + (QDISC_ALIGNTO - 1);
 
 	p = kmalloc(size, GFP_KERNEL);
 	if (!p)
-		return NULL;
+		goto errout;
 	memset(p, 0, size);
-
-	sch = (struct Qdisc *)(((unsigned long)p + QDISC_ALIGN_CONST) 
-			       & ~QDISC_ALIGN_CONST);
-	sch->padded = (char *)sch - (char *)p;
+	sch = (struct Qdisc *) QDISC_ALIGN((unsigned long) p);
+	sch->padded = (char *) sch - (char *) p;
 
 	INIT_LIST_HEAD(&sch->list);
 	skb_queue_head_init(&sch->q);
@@ -439,11 +421,25 @@ struct Qdisc * qdisc_create_dflt(struct 
 	dev_hold(dev);
 	sch->stats_lock = &dev->queue_lock;
 	atomic_set(&sch->refcnt, 1);
+
+	return sch;
+errout:
+	return ERR_PTR(-err);
+}
+
+struct Qdisc * qdisc_create_dflt(struct net_device *dev, struct Qdisc_ops *ops)
+{
+	struct Qdisc *sch;
+	
+	sch = qdisc_alloc(dev, ops);
+	if (IS_ERR(sch))
+		goto errout;
+
 	if (!ops->init || ops->init(sch, NULL) == 0)
 		return sch;
 
-	dev_put(dev);
-	kfree(p);
+	qdisc_destroy(sch);
+errout:
 	return NULL;
 }
 
@@ -607,6 +603,7 @@ EXPORT_SYMBOL(__netdev_watchdog_up);
 EXPORT_SYMBOL(noop_qdisc);
 EXPORT_SYMBOL(noop_qdisc_ops);
 EXPORT_SYMBOL(qdisc_create_dflt);
+EXPORT_SYMBOL(qdisc_alloc);
 EXPORT_SYMBOL(qdisc_destroy);
 EXPORT_SYMBOL(qdisc_reset);
 EXPORT_SYMBOL(qdisc_restart);
diff --git a/net/sched/sch_red.c b/net/sched/sch_red.c
--- a/net/sched/sch_red.c
+++ b/net/sched/sch_red.c
@@ -385,7 +385,7 @@ static int red_change(struct Qdisc *sch,
 	memcpy(q->Stab, RTA_DATA(tb[TCA_RED_STAB-1]), 256);
 
 	q->qcount = -1;
-	if (skb_queue_len(&sch->q) == 0)
+	if (skb_queue_empty(&sch->q))
 		PSCHED_SET_PASTPERFECT(q->qidlestart);
 	sch_tree_unlock(sch);
 	return 0;
diff --git a/net/sctp/associola.c b/net/sctp/associola.c
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -71,7 +71,7 @@ static struct sctp_association *sctp_ass
 					  const struct sctp_endpoint *ep,
 					  const struct sock *sk,
 					  sctp_scope_t scope,
-					  int gfp)
+					  unsigned int __nocast gfp)
 {
 	struct sctp_sock *sp;
 	int i;
@@ -191,10 +191,6 @@ static struct sctp_association *sctp_ass
 	asoc->last_cwr_tsn = asoc->ctsn_ack_point;
 	asoc->unack_data = 0;
 
-	SCTP_DEBUG_PRINTK("myctsnap for %s INIT as 0x%x.\n",
-			  asoc->ep->debug_name,
-			  asoc->ctsn_ack_point);
-
 	/* ADDIP Section 4.1 Asconf Chunk Procedures
 	 *
 	 * When an endpoint has an ASCONF signaled change to be sent to the
@@ -207,10 +203,11 @@ static struct sctp_association *sctp_ass
 	 */
 	asoc->addip_serial = asoc->c.initial_tsn;
 
-	skb_queue_head_init(&asoc->addip_chunks);
+	INIT_LIST_HEAD(&asoc->addip_chunk_list);
 
 	/* Make an empty list of remote transport addresses.  */
 	INIT_LIST_HEAD(&asoc->peer.transport_addr_list);
+	asoc->peer.transport_count = 0;
 
 	/* RFC 2960 5.1 Normal Establishment of an Association
 	 *
@@ -275,7 +272,8 @@ fail_init:
 /* Allocate and initialize a new association */
 struct sctp_association *sctp_association_new(const struct sctp_endpoint *ep,
 					 const struct sock *sk,
-					 sctp_scope_t scope, int gfp)
+					 sctp_scope_t scope,
+					 unsigned int __nocast gfp)
 {
 	struct sctp_association *asoc;
 
@@ -288,6 +286,7 @@ struct sctp_association *sctp_associatio
 
 	asoc->base.malloced = 1;
 	SCTP_DBG_OBJCNT_INC(assoc);
+	SCTP_DEBUG_PRINTK("Created asoc %p\n", asoc);
 
 	return asoc;
 
@@ -356,6 +355,8 @@ void sctp_association_free(struct sctp_a
 		sctp_transport_free(transport);
 	}
 
+	asoc->peer.transport_count = 0;
+
 	/* Free any cached ASCONF_ACK chunk. */
 	if (asoc->addip_last_asconf_ack)
 		sctp_chunk_free(asoc->addip_last_asconf_ack);
@@ -400,7 +401,7 @@ void sctp_assoc_set_primary(struct sctp_
 	/* If the primary path is changing, assume that the
 	 * user wants to use this new path.
 	 */
-	if (transport->active)
+	if (transport->state != SCTP_INACTIVE)
 		asoc->peer.active_path = transport;
 
 	/*
@@ -428,10 +429,58 @@ void sctp_assoc_set_primary(struct sctp_
 	transport->cacc.next_tsn_at_change = asoc->next_tsn;
 }
 
+/* Remove a transport from an association.  */
+void sctp_assoc_rm_peer(struct sctp_association *asoc,
+			struct sctp_transport *peer)
+{
+	struct list_head	*pos;
+	struct sctp_transport	*transport;
+
+	SCTP_DEBUG_PRINTK_IPADDR("sctp_assoc_rm_peer:association %p addr: ",
+				 " port: %d\n",
+				 asoc,
+				 (&peer->ipaddr),
+				 peer->ipaddr.v4.sin_port);
+
+	/* If we are to remove the current retran_path, update it
+	 * to the next peer before removing this peer from the list.
+	 */
+	if (asoc->peer.retran_path == peer)
+		sctp_assoc_update_retran_path(asoc);
+
+	/* Remove this peer from the list. */
+	list_del(&peer->transports);
+
+	/* Get the first transport of asoc. */
+	pos = asoc->peer.transport_addr_list.next;
+	transport = list_entry(pos, struct sctp_transport, transports);
+
+	/* Update any entries that match the peer to be deleted. */
+	if (asoc->peer.primary_path == peer)
+		sctp_assoc_set_primary(asoc, transport);
+	if (asoc->peer.active_path == peer)
+		asoc->peer.active_path = transport;
+	if (asoc->peer.last_data_from == peer)
+		asoc->peer.last_data_from = transport;
+
+	/* If we remove the transport an INIT was last sent to, set it to
+	 * NULL. Combined with the update of the retran path above, this
+	 * will cause the next INIT to be sent to the next available
+	 * transport, maintaining the cycle.
+	 */
+	if (asoc->init_last_sent_to == peer)
+		asoc->init_last_sent_to = NULL;
+
+	asoc->peer.transport_count--;
+
+	sctp_transport_free(peer);
+}
+
 /* Add a transport address to an association.  */
 struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc,
 					   const union sctp_addr *addr,
-					   int gfp)
+					   const unsigned int __nocast gfp,
+					   const int peer_state)
 {
 	struct sctp_transport *peer;
 	struct sctp_sock *sp;
@@ -442,14 +491,25 @@ struct sctp_transport *sctp_assoc_add_pe
 	/* AF_INET and AF_INET6 share common port field. */
 	port = addr->v4.sin_port;
 
+	SCTP_DEBUG_PRINTK_IPADDR("sctp_assoc_add_peer:association %p addr: ",
+				 " port: %d state:%s\n",
+				 asoc,
+				 addr,
+				 addr->v4.sin_port,
+				 peer_state == SCTP_UNKNOWN?"UNKNOWN":"ACTIVE");
+
 	/* Set the port if it has not been set yet.  */
 	if (0 == asoc->peer.port)
 		asoc->peer.port = port;
 
 	/* Check to see if this is a duplicate. */
 	peer = sctp_assoc_lookup_paddr(asoc, addr);
-	if (peer)
+	if (peer) {
+		if (peer_state == SCTP_ACTIVE &&
+		    peer->state == SCTP_UNKNOWN)
+		     peer->state = SCTP_ACTIVE;
 		return peer;
+	}
 
 	peer = sctp_transport_new(addr, gfp);
 	if (!peer)
@@ -516,8 +576,12 @@ struct sctp_transport *sctp_assoc_add_pe
 	/* Set the transport's RTO.initial value */
 	peer->rto = asoc->rto_initial;
 
+	/* Set the peer's active state. */
+	peer->state = peer_state;
+
 	/* Attach the remote transport to our asoc.  */
 	list_add_tail(&peer->transports, &asoc->peer.transport_addr_list);
+	asoc->peer.transport_count++;
 
 	/* If we do not yet have a primary path, set one.  */
 	if (!asoc->peer.primary_path) {
@@ -525,8 +589,9 @@ struct sctp_transport *sctp_assoc_add_pe
 		asoc->peer.retran_path = peer;
 	}
 
-	if (asoc->peer.active_path == asoc->peer.retran_path)
+	if (asoc->peer.active_path == asoc->peer.retran_path) {
 		asoc->peer.retran_path = peer;
+	}
 
 	return peer;
 }
@@ -537,37 +602,16 @@ void sctp_assoc_del_peer(struct sctp_ass
 {
 	struct list_head	*pos;
 	struct list_head	*temp;
-	struct sctp_transport	*peer = NULL;
 	struct sctp_transport	*transport;
 
 	list_for_each_safe(pos, temp, &asoc->peer.transport_addr_list) {
 		transport = list_entry(pos, struct sctp_transport, transports);
 		if (sctp_cmp_addr_exact(addr, &transport->ipaddr)) {
-			peer = transport;
-			list_del(pos);
+			/* Do book keeping for removing the peer and free it. */
+			sctp_assoc_rm_peer(asoc, transport);
 			break;
 		}
 	}
-
-	/* The address we want delete is not in the association. */
-	if (!peer)
-		return;
-
-	/* Get the first transport of asoc. */ 
-	pos = asoc->peer.transport_addr_list.next;
-	transport = list_entry(pos, struct sctp_transport, transports);
-
-	/* Update any entries that match the peer to be deleted. */  
-	if (asoc->peer.primary_path == peer)
-		sctp_assoc_set_primary(asoc, transport);
-	if (asoc->peer.active_path == peer)
-		asoc->peer.active_path = transport;
-	if (asoc->peer.retran_path == peer)
-		asoc->peer.retran_path = transport;
-	if (asoc->peer.last_data_from == peer)
-		asoc->peer.last_data_from = transport;
-
-	sctp_transport_free(peer);
 }
 
 /* Lookup a transport by address. */
@@ -608,12 +652,12 @@ void sctp_assoc_control_transport(struct
 	/* Record the transition on the transport.  */
 	switch (command) {
 	case SCTP_TRANSPORT_UP:
-		transport->active = SCTP_ACTIVE;
+		transport->state = SCTP_ACTIVE;
 		spc_state = SCTP_ADDR_AVAILABLE;
 		break;
 
 	case SCTP_TRANSPORT_DOWN:
-		transport->active = SCTP_INACTIVE;
+		transport->state = SCTP_INACTIVE;
 		spc_state = SCTP_ADDR_UNREACHABLE;
 		break;
 
@@ -643,7 +687,7 @@ void sctp_assoc_control_transport(struct
 	list_for_each(pos, &asoc->peer.transport_addr_list) {
 		t = list_entry(pos, struct sctp_transport, transports);
 
-		if (!t->active)
+		if (t->state == SCTP_INACTIVE)
 			continue;
 		if (!first || t->last_time_heard > first->last_time_heard) {
 			second = first;
@@ -663,7 +707,7 @@ void sctp_assoc_control_transport(struct
 	 * [If the primary is active but not most recent, bump the most
 	 * recently used transport.]
 	 */
-	if (asoc->peer.primary_path->active &&
+	if (asoc->peer.primary_path->state != SCTP_INACTIVE &&
 	    first != asoc->peer.primary_path) {
 		second = first;
 		first = asoc->peer.primary_path;
@@ -958,7 +1002,7 @@ void sctp_assoc_update(struct sctp_assoc
 					   transports);
 			if (!sctp_assoc_lookup_paddr(asoc, &trans->ipaddr))
 				sctp_assoc_add_peer(asoc, &trans->ipaddr,
-						    GFP_ATOMIC);
+						    GFP_ATOMIC, SCTP_ACTIVE);
 		}
 
 		asoc->ctsn_ack_point = asoc->next_tsn - 1;
@@ -998,7 +1042,7 @@ void sctp_assoc_update_retran_path(struc
 
 		/* Try to find an active transport. */
 
-		if (t->active) {
+		if (t->state != SCTP_INACTIVE) {
 			break;
 		} else {
 			/* Keep track of the next transport in case
@@ -1019,6 +1063,40 @@ void sctp_assoc_update_retran_path(struc
 	}
 
 	asoc->peer.retran_path = t;
+
+	SCTP_DEBUG_PRINTK_IPADDR("sctp_assoc_update_retran_path:association"
+				 " %p addr: ",
+				 " port: %d\n",
+				 asoc,
+				 (&t->ipaddr),
+				 t->ipaddr.v4.sin_port);
+}
+
+/* Choose the transport for sending a INIT packet.  */
+struct sctp_transport *sctp_assoc_choose_init_transport(
+	struct sctp_association *asoc)
+{
+	struct sctp_transport *t;
+
+	/* Use the retran path. If the last INIT was sent over the
+	 * retran path, update the retran path and use it.
+	 */
+	if (!asoc->init_last_sent_to) {
+		t = asoc->peer.active_path;
+	} else {
+		if (asoc->init_last_sent_to == asoc->peer.retran_path)
+			sctp_assoc_update_retran_path(asoc);
+		t = asoc->peer.retran_path;
+	}
+
+	SCTP_DEBUG_PRINTK_IPADDR("sctp_assoc_update_retran_path:association"
+				 " %p addr: ",
+				 " port: %d\n",
+				 asoc,
+				 (&t->ipaddr),
+				 t->ipaddr.v4.sin_port);
+
+	return t;
 }
 
 /* Choose the transport for sending a SHUTDOWN packet.  */
@@ -1152,7 +1230,8 @@ void sctp_assoc_rwnd_decrease(struct sct
 /* Build the bind address list for the association based on info from the
  * local endpoint and the remote peer.
  */
-int sctp_assoc_set_bind_addr_from_ep(struct sctp_association *asoc, int gfp)
+int sctp_assoc_set_bind_addr_from_ep(struct sctp_association *asoc,
+				     unsigned int __nocast gfp)
 {
 	sctp_scope_t scope;
 	int flags;
@@ -1174,7 +1253,8 @@ int sctp_assoc_set_bind_addr_from_ep(str
 
 /* Build the association's bind address list from the cookie.  */
 int sctp_assoc_set_bind_addr_from_cookie(struct sctp_association *asoc,
-					 struct sctp_cookie *cookie, int gfp)
+					 struct sctp_cookie *cookie,
+					 unsigned int __nocast gfp)
 {
 	int var_size2 = ntohs(cookie->peer_init->chunk_hdr.length);
 	int var_size3 = cookie->raw_addr_list_len;
diff --git a/net/sctp/bind_addr.c b/net/sctp/bind_addr.c
--- a/net/sctp/bind_addr.c
+++ b/net/sctp/bind_addr.c
@@ -53,7 +53,8 @@
 
 /* Forward declarations for internal helpers. */
 static int sctp_copy_one_addr(struct sctp_bind_addr *, union sctp_addr *,
-			      sctp_scope_t scope, int gfp, int flags);
+			      sctp_scope_t scope, unsigned int __nocast gfp,
+			      int flags);
 static void sctp_bind_addr_clean(struct sctp_bind_addr *);
 
 /* First Level Abstractions. */
@@ -63,7 +64,8 @@ static void sctp_bind_addr_clean(struct 
  */
 int sctp_bind_addr_copy(struct sctp_bind_addr *dest, 
 			const struct sctp_bind_addr *src,
-			sctp_scope_t scope, int gfp, int flags)
+			sctp_scope_t scope, unsigned int __nocast gfp,
+			int flags)
 {
 	struct sctp_sockaddr_entry *addr;
 	struct list_head *pos;
@@ -144,7 +146,7 @@ void sctp_bind_addr_free(struct sctp_bin
 
 /* Add an address to the bind address list in the SCTP_bind_addr structure. */
 int sctp_add_bind_addr(struct sctp_bind_addr *bp, union sctp_addr *new,
-		       int gfp)
+		       unsigned int __nocast gfp)
 {
 	struct sctp_sockaddr_entry *addr;
 
@@ -197,7 +199,8 @@ int sctp_del_bind_addr(struct sctp_bind_
  * The second argument is the return value for the length.
  */
 union sctp_params sctp_bind_addrs_to_raw(const struct sctp_bind_addr *bp,
-					 int *addrs_len, int gfp)
+					 int *addrs_len,
+					 unsigned int __nocast gfp)
 {
 	union sctp_params addrparms;
 	union sctp_params retval;
@@ -249,7 +252,7 @@ end_raw:
  * address parameters).
  */
 int sctp_raw_to_bind_addrs(struct sctp_bind_addr *bp, __u8 *raw_addr_list,
-			   int addrs_len, __u16 port, int gfp)
+			   int addrs_len, __u16 port, unsigned int __nocast gfp)
 {
 	union sctp_addr_param *rawaddr;
 	struct sctp_paramhdr *param;
@@ -347,7 +350,8 @@ union sctp_addr *sctp_find_unmatch_addr(
 /* Copy out addresses from the global local address list. */
 static int sctp_copy_one_addr(struct sctp_bind_addr *dest, 
 			      union sctp_addr *addr,
-			      sctp_scope_t scope, int gfp, int flags)
+			      sctp_scope_t scope, unsigned int __nocast gfp,
+			      int flags)
 {
 	int error = 0;
 
diff --git a/net/sctp/chunk.c b/net/sctp/chunk.c
--- a/net/sctp/chunk.c
+++ b/net/sctp/chunk.c
@@ -62,7 +62,7 @@ static void sctp_datamsg_init(struct sct
 }
 
 /* Allocate and initialize datamsg. */
-SCTP_STATIC struct sctp_datamsg *sctp_datamsg_new(int gfp)
+SCTP_STATIC struct sctp_datamsg *sctp_datamsg_new(unsigned int __nocast gfp)
 {
 	struct sctp_datamsg *msg;
 	msg = kmalloc(sizeof(struct sctp_datamsg), gfp);
diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c
--- a/net/sctp/endpointola.c
+++ b/net/sctp/endpointola.c
@@ -67,7 +67,8 @@ static void sctp_endpoint_bh_rcv(struct 
  * Initialize the base fields of the endpoint structure.
  */
 static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep,
-						struct sock *sk, int gfp)
+						struct sock *sk,
+						unsigned int __nocast gfp)
 {
 	struct sctp_sock *sp = sctp_sk(sk);
 	memset(ep, 0, sizeof(struct sctp_endpoint));
@@ -102,9 +103,9 @@ static struct sctp_endpoint *sctp_endpoi
 	/* Set up the base timeout information.  */
 	ep->timeouts[SCTP_EVENT_TIMEOUT_NONE] = 0;
 	ep->timeouts[SCTP_EVENT_TIMEOUT_T1_COOKIE] =
-		SCTP_DEFAULT_TIMEOUT_T1_COOKIE;
+		msecs_to_jiffies(sp->rtoinfo.srto_initial);
 	ep->timeouts[SCTP_EVENT_TIMEOUT_T1_INIT] =
-		SCTP_DEFAULT_TIMEOUT_T1_INIT;
+		msecs_to_jiffies(sp->rtoinfo.srto_initial);
 	ep->timeouts[SCTP_EVENT_TIMEOUT_T2_SHUTDOWN] =
 		msecs_to_jiffies(sp->rtoinfo.srto_initial);
 	ep->timeouts[SCTP_EVENT_TIMEOUT_T3_RTX] = 0;
@@ -117,12 +118,9 @@ static struct sctp_endpoint *sctp_endpoi
         ep->timeouts[SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD]
 		= 5 * msecs_to_jiffies(sp->rtoinfo.srto_max);
 
-	ep->timeouts[SCTP_EVENT_TIMEOUT_HEARTBEAT] =
-		SCTP_DEFAULT_TIMEOUT_HEARTBEAT;
-	ep->timeouts[SCTP_EVENT_TIMEOUT_SACK] =
-		SCTP_DEFAULT_TIMEOUT_SACK;
-	ep->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE] =
-		sp->autoclose * HZ;
+	ep->timeouts[SCTP_EVENT_TIMEOUT_HEARTBEAT] = 0;
+	ep->timeouts[SCTP_EVENT_TIMEOUT_SACK] = sctp_sack_timeout;
+	ep->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE] = sp->autoclose * HZ;
 
 	/* Use SCTP specific send buffer space queues.  */
 	ep->sndbuf_policy = sctp_sndbuf_policy;
@@ -134,14 +132,14 @@ static struct sctp_endpoint *sctp_endpoi
 	ep->last_key = ep->current_key = 0;
 	ep->key_changed_at = jiffies;
 
-	ep->debug_name = "unnamedEndpoint";
 	return ep;
 }
 
 /* Create a sctp_endpoint with all that boring stuff initialized.
  * Returns NULL if there isn't enough memory.
  */
-struct sctp_endpoint *sctp_endpoint_new(struct sock *sk, int gfp)
+struct sctp_endpoint *sctp_endpoint_new(struct sock *sk,
+					unsigned int __nocast gfp)
 {
 	struct sctp_endpoint *ep;
 
diff --git a/net/sctp/input.c b/net/sctp/input.c
--- a/net/sctp/input.c
+++ b/net/sctp/input.c
@@ -115,6 +115,17 @@ static void sctp_rcv_set_owner_r(struct 
 	atomic_add(sizeof(struct sctp_chunk),&sk->sk_rmem_alloc);
 }
 
+struct sctp_input_cb {
+	union {
+		struct inet_skb_parm	h4;
+#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
+		struct inet6_skb_parm	h6;
+#endif
+	} header;
+	struct sctp_chunk *chunk;
+};
+#define SCTP_INPUT_CB(__skb)	((struct sctp_input_cb *)&((__skb)->cb[0]))
+
 /*
  * This is the routine which IP calls when receiving an SCTP packet.
  */
@@ -243,6 +254,7 @@ int sctp_rcv(struct sk_buff *skb)
 		ret = -ENOMEM;
 		goto discard_release;
 	}
+	SCTP_INPUT_CB(skb)->chunk = chunk;
 
 	sctp_rcv_set_owner_r(skb,sk);
 
@@ -265,9 +277,9 @@ int sctp_rcv(struct sk_buff *skb)
 	sctp_bh_lock_sock(sk);
 
 	if (sock_owned_by_user(sk))
-		sk_add_backlog(sk, (struct sk_buff *) chunk);
+		sk_add_backlog(sk, skb);
 	else
-		sctp_backlog_rcv(sk, (struct sk_buff *) chunk);
+		sctp_backlog_rcv(sk, skb);
 
 	/* Release the sock and any reference counts we took in the
 	 * lookup calls.
@@ -302,14 +314,8 @@ discard_release:
  */
 int sctp_backlog_rcv(struct sock *sk, struct sk_buff *skb)
 {
-	struct sctp_chunk *chunk;
-	struct sctp_inq *inqueue;
-
-	/* One day chunk will live inside the skb, but for
-	 * now this works.
-	 */
-	chunk = (struct sctp_chunk *) skb;
-	inqueue = &chunk->rcvr->inqueue;
+	struct sctp_chunk *chunk = SCTP_INPUT_CB(skb)->chunk;
+	struct sctp_inq *inqueue = &chunk->rcvr->inqueue;
 
 	sctp_inq_push(inqueue, chunk);
         return 0;
@@ -345,7 +351,6 @@ void sctp_icmp_frag_needed(struct sock *
  *
  */
 void sctp_icmp_proto_unreachable(struct sock *sk,
-                           struct sctp_endpoint *ep,
                            struct sctp_association *asoc,
                            struct sctp_transport *t)
 {
@@ -353,7 +358,7 @@ void sctp_icmp_proto_unreachable(struct 
 
 	sctp_do_sm(SCTP_EVENT_T_OTHER,
 		   SCTP_ST_OTHER(SCTP_EVENT_ICMP_PROTO_UNREACH),
-		   asoc->state, asoc->ep, asoc, NULL,
+		   asoc->state, asoc->ep, asoc, t,
 		   GFP_ATOMIC);
 
 }
@@ -361,7 +366,6 @@ void sctp_icmp_proto_unreachable(struct 
 /* Common lookup code for icmp/icmpv6 error handler. */
 struct sock *sctp_err_lookup(int family, struct sk_buff *skb,
 			     struct sctphdr *sctphdr,
-			     struct sctp_endpoint **epp,
 			     struct sctp_association **app,
 			     struct sctp_transport **tpp)
 {
@@ -369,11 +373,10 @@ struct sock *sctp_err_lookup(int family,
 	union sctp_addr daddr;
 	struct sctp_af *af;
 	struct sock *sk = NULL;
-	struct sctp_endpoint *ep = NULL;
 	struct sctp_association *asoc = NULL;
 	struct sctp_transport *transport = NULL;
 
-	*app = NULL; *epp = NULL; *tpp = NULL;
+	*app = NULL; *tpp = NULL;
 
 	af = sctp_get_af_specific(family);
 	if (unlikely(!af)) {
@@ -388,26 +391,15 @@ struct sock *sctp_err_lookup(int family,
 	 * packet.
 	 */
 	asoc = __sctp_lookup_association(&saddr, &daddr, &transport);
-	if (!asoc) {
-		/* If there is no matching association, see if it matches any
-		 * endpoint. This may happen for an ICMP error generated in
-		 * response to an INIT_ACK.
-		 */
-		ep = __sctp_rcv_lookup_endpoint(&daddr);
-		if (!ep) {
-			return NULL;
-		}
-	}
+	if (!asoc)
+		return NULL;
 
-	if (asoc) {
-		sk = asoc->base.sk;
+	sk = asoc->base.sk;
 
-		if (ntohl(sctphdr->vtag) != asoc->c.peer_vtag) {
-			ICMP_INC_STATS_BH(ICMP_MIB_INERRORS);
-			goto out;
-		}
-	} else
-		sk = ep->base.sk;
+	if (ntohl(sctphdr->vtag) != asoc->c.peer_vtag) {
+		ICMP_INC_STATS_BH(ICMP_MIB_INERRORS);
+		goto out;
+	}
 
 	sctp_bh_lock_sock(sk);
 
@@ -417,7 +409,6 @@ struct sock *sctp_err_lookup(int family,
 	if (sock_owned_by_user(sk))
 		NET_INC_STATS_BH(LINUX_MIB_LOCKDROPPEDICMPS);
 
-	*epp = ep;
 	*app = asoc;
 	*tpp = transport;
 	return sk;
@@ -426,21 +417,16 @@ out:
 	sock_put(sk);
 	if (asoc)
 		sctp_association_put(asoc);
-	if (ep)
-		sctp_endpoint_put(ep);
 	return NULL;
 }
 
 /* Common cleanup code for icmp/icmpv6 error handler. */
-void sctp_err_finish(struct sock *sk, struct sctp_endpoint *ep,
-		     struct sctp_association *asoc)
+void sctp_err_finish(struct sock *sk, struct sctp_association *asoc)
 {
 	sctp_bh_unlock_sock(sk);
 	sock_put(sk);
 	if (asoc)
 		sctp_association_put(asoc);
-	if (ep)
-		sctp_endpoint_put(ep);
 }
 
 /*
@@ -465,7 +451,6 @@ void sctp_v4_err(struct sk_buff *skb, __
 	int type = skb->h.icmph->type;
 	int code = skb->h.icmph->code;
 	struct sock *sk;
-	struct sctp_endpoint *ep;
 	struct sctp_association *asoc;
 	struct sctp_transport *transport;
 	struct inet_sock *inet;
@@ -482,7 +467,7 @@ void sctp_v4_err(struct sk_buff *skb, __
 	savesctp  = skb->h.raw;
 	skb->nh.iph = iph;
 	skb->h.raw = (char *)sh;
-	sk = sctp_err_lookup(AF_INET, skb, sh, &ep, &asoc, &transport);
+	sk = sctp_err_lookup(AF_INET, skb, sh, &asoc, &transport);
 	/* Put back, the original pointers. */
 	skb->nh.raw = saveip;
 	skb->h.raw = savesctp;
@@ -509,7 +494,7 @@ void sctp_v4_err(struct sk_buff *skb, __
 		}
 		else {
 			if (ICMP_PROT_UNREACH == code) {
-				sctp_icmp_proto_unreachable(sk, ep, asoc,
+				sctp_icmp_proto_unreachable(sk, asoc,
 							    transport);
 				goto out_unlock;
 			}
@@ -538,7 +523,7 @@ void sctp_v4_err(struct sk_buff *skb, __
 	}
 
 out_unlock:
-	sctp_err_finish(sk, ep, asoc);
+	sctp_err_finish(sk, asoc);
 }
 
 /*
diff --git a/net/sctp/inqueue.c b/net/sctp/inqueue.c
--- a/net/sctp/inqueue.c
+++ b/net/sctp/inqueue.c
@@ -50,7 +50,7 @@
 /* Initialize an SCTP inqueue.  */
 void sctp_inq_init(struct sctp_inq *queue)
 {
-	skb_queue_head_init(&queue->in);
+	INIT_LIST_HEAD(&queue->in_chunk_list);
 	queue->in_progress = NULL;
 
 	/* Create a task for delivering data.  */
@@ -62,11 +62,13 @@ void sctp_inq_init(struct sctp_inq *queu
 /* Release the memory associated with an SCTP inqueue.  */
 void sctp_inq_free(struct sctp_inq *queue)
 {
-	struct sctp_chunk *chunk;
+	struct sctp_chunk *chunk, *tmp;
 
 	/* Empty the queue.  */
-	while ((chunk = (struct sctp_chunk *) skb_dequeue(&queue->in)) != NULL)
+	list_for_each_entry_safe(chunk, tmp, &queue->in_chunk_list, list) {
+		list_del_init(&chunk->list);
 		sctp_chunk_free(chunk);
+	}
 
 	/* If there is a packet which is currently being worked on,
 	 * free it as well.
@@ -92,7 +94,7 @@ void sctp_inq_push(struct sctp_inq *q, s
 	 * Eventually, we should clean up inqueue to not rely
 	 * on the BH related data structures.
 	 */
-	skb_queue_tail(&(q->in), (struct sk_buff *) packet);
+	list_add_tail(&packet->list, &q->in_chunk_list);
 	q->immediate.func(q->immediate.data);
 }
 
@@ -131,12 +133,16 @@ struct sctp_chunk *sctp_inq_pop(struct s
 
 	/* Do we need to take the next packet out of the queue to process? */
 	if (!chunk) {
+		struct list_head *entry;
+
 		/* Is the queue empty?  */
-        	if (skb_queue_empty(&queue->in))
+		if (list_empty(&queue->in_chunk_list))
 			return NULL;
 
+		entry = queue->in_chunk_list.next;
 		chunk = queue->in_progress =
-			(struct sctp_chunk *) skb_dequeue(&queue->in);
+			list_entry(entry, struct sctp_chunk, list);
+		list_del_init(entry);
 
 		/* This is the first chunk in the packet.  */
 		chunk->singleton = 1;
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -91,7 +91,6 @@ SCTP_STATIC void sctp_v6_err(struct sk_b
 	struct ipv6hdr *iph = (struct ipv6hdr *)skb->data;
 	struct sctphdr *sh = (struct sctphdr *)(skb->data + offset);
 	struct sock *sk;
-	struct sctp_endpoint *ep;
 	struct sctp_association *asoc;
 	struct sctp_transport *transport;
 	struct ipv6_pinfo *np;
@@ -105,7 +104,7 @@ SCTP_STATIC void sctp_v6_err(struct sk_b
 	savesctp  = skb->h.raw;
 	skb->nh.ipv6h = iph;
 	skb->h.raw = (char *)sh;
-	sk = sctp_err_lookup(AF_INET6, skb, sh, &ep, &asoc, &transport);
+	sk = sctp_err_lookup(AF_INET6, skb, sh, &asoc, &transport);
 	/* Put back, the original pointers. */
 	skb->nh.raw = saveip;
 	skb->h.raw = savesctp;
@@ -124,7 +123,7 @@ SCTP_STATIC void sctp_v6_err(struct sk_b
 		goto out_unlock;
 	case ICMPV6_PARAMPROB:
 		if (ICMPV6_UNK_NEXTHDR == code) {
-			sctp_icmp_proto_unreachable(sk, ep, asoc, transport);
+			sctp_icmp_proto_unreachable(sk, asoc, transport);
 			goto out_unlock;
 		}
 		break;
@@ -142,7 +141,7 @@ SCTP_STATIC void sctp_v6_err(struct sk_b
 	}
 
 out_unlock:
-	sctp_err_finish(sk, ep, asoc);
+	sctp_err_finish(sk, asoc);
 out:
 	if (likely(idev != NULL))
 		in6_dev_put(idev);
diff --git a/net/sctp/objcnt.c b/net/sctp/objcnt.c
--- a/net/sctp/objcnt.c
+++ b/net/sctp/objcnt.c
@@ -127,8 +127,12 @@ done:
 /* Initialize the objcount in the proc filesystem.  */
 void sctp_dbg_objcnt_init(void)
 {
-	create_proc_read_entry("sctp_dbg_objcnt", 0, proc_net_sctp,
+	struct proc_dir_entry *ent;
+	ent = create_proc_read_entry("sctp_dbg_objcnt", 0, proc_net_sctp,
 			       sctp_dbg_objcnt_read, NULL);
+	if (!ent)
+		printk(KERN_WARNING 
+			"sctp_dbg_objcnt: Unable to create /proc entry.\n");
 }
 
 /* Cleanup the objcount entry in the proc filesystem.  */
diff --git a/net/sctp/output.c b/net/sctp/output.c
--- a/net/sctp/output.c
+++ b/net/sctp/output.c
@@ -108,7 +108,7 @@ struct sctp_packet *sctp_packet_init(str
 	packet->transport = transport;
 	packet->source_port = sport;
 	packet->destination_port = dport;
-	skb_queue_head_init(&packet->chunks);
+	INIT_LIST_HEAD(&packet->chunk_list);
 	if (asoc) {
 		struct sctp_sock *sp = sctp_sk(asoc->base.sk);	
 		overhead = sp->pf->af->net_header_len; 
@@ -129,12 +129,14 @@ struct sctp_packet *sctp_packet_init(str
 /* Free a packet.  */
 void sctp_packet_free(struct sctp_packet *packet)
 {
-	struct sctp_chunk *chunk;
+	struct sctp_chunk *chunk, *tmp;
 
 	SCTP_DEBUG_PRINTK("%s: packet:%p\n", __FUNCTION__, packet);
 
-        while ((chunk = (struct sctp_chunk *)__skb_dequeue(&packet->chunks)) != NULL)
+	list_for_each_entry_safe(chunk, tmp, &packet->chunk_list, list) {
+		list_del_init(&chunk->list);
 		sctp_chunk_free(chunk);
+	}
 
 	if (packet->malloced)
 		kfree(packet);
@@ -276,7 +278,7 @@ append:
 		packet->has_sack = 1;
 
 	/* It is OK to send this chunk.  */
-	__skb_queue_tail(&packet->chunks, (struct sk_buff *)chunk);
+	list_add_tail(&chunk->list, &packet->chunk_list);
 	packet->size += chunk_len;
 	chunk->transport = packet->transport;
 finish:
@@ -295,7 +297,7 @@ int sctp_packet_transmit(struct sctp_pac
 	struct sctphdr *sh;
 	__u32 crc32;
 	struct sk_buff *nskb;
-	struct sctp_chunk *chunk;
+	struct sctp_chunk *chunk, *tmp;
 	struct sock *sk;
 	int err = 0;
 	int padding;		/* How much padding do we need?  */
@@ -305,11 +307,11 @@ int sctp_packet_transmit(struct sctp_pac
 	SCTP_DEBUG_PRINTK("%s: packet:%p\n", __FUNCTION__, packet);
 
 	/* Do NOT generate a chunkless packet. */
-	chunk = (struct sctp_chunk *)skb_peek(&packet->chunks);
-	if (unlikely(!chunk))
+	if (list_empty(&packet->chunk_list))
 		return err;
 
 	/* Set up convenience variables... */
+	chunk = list_entry(packet->chunk_list.next, struct sctp_chunk, list);
 	sk = chunk->skb->sk;
 
 	/* Allocate the new skb.  */
@@ -370,7 +372,8 @@ int sctp_packet_transmit(struct sctp_pac
 	 * [This whole comment explains WORD_ROUND() below.]
 	 */
 	SCTP_DEBUG_PRINTK("***sctp_transmit_packet***\n");
-	while ((chunk = (struct sctp_chunk *)__skb_dequeue(&packet->chunks)) != NULL) {
+	list_for_each_entry_safe(chunk, tmp, &packet->chunk_list, list) {
+		list_del_init(&chunk->list);
 		if (sctp_chunk_is_data(chunk)) {
 
 			if (!chunk->has_tsn) {
@@ -511,7 +514,8 @@ err:
 	 * will get resent or dropped later.
 	 */
 
-	while ((chunk = (struct sctp_chunk *)__skb_dequeue(&packet->chunks)) != NULL) {
+	list_for_each_entry_safe(chunk, tmp, &packet->chunk_list, list) {
+		list_del_init(&chunk->list);
 		if (!sctp_chunk_is_data(chunk))
     			sctp_chunk_free(chunk);
 	}
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c
--- a/net/sctp/outqueue.c
+++ b/net/sctp/outqueue.c
@@ -75,7 +75,7 @@ static void sctp_generate_fwdtsn(struct 
 static inline void sctp_outq_head_data(struct sctp_outq *q,
 					struct sctp_chunk *ch)
 {
-	__skb_queue_head(&q->out, (struct sk_buff *)ch);
+	list_add(&ch->list, &q->out_chunk_list);
 	q->out_qlen += ch->skb->len;
 	return;
 }
@@ -83,17 +83,22 @@ static inline void sctp_outq_head_data(s
 /* Take data from the front of the queue. */
 static inline struct sctp_chunk *sctp_outq_dequeue_data(struct sctp_outq *q)
 {
-	struct sctp_chunk *ch;
-	ch = (struct sctp_chunk *)__skb_dequeue(&q->out);
-	if (ch)
+	struct sctp_chunk *ch = NULL;
+
+	if (!list_empty(&q->out_chunk_list)) {
+		struct list_head *entry = q->out_chunk_list.next;
+
+		ch = list_entry(entry, struct sctp_chunk, list);
+		list_del_init(entry);
 		q->out_qlen -= ch->skb->len;
+	}
 	return ch;
 }
 /* Add data chunk to the end of the queue. */
 static inline void sctp_outq_tail_data(struct sctp_outq *q,
 				       struct sctp_chunk *ch)
 {
-	__skb_queue_tail(&q->out, (struct sk_buff *)ch);
+	list_add_tail(&ch->list, &q->out_chunk_list);
 	q->out_qlen += ch->skb->len;
 	return;
 }
@@ -197,8 +202,8 @@ static inline int sctp_cacc_skip(struct 
 void sctp_outq_init(struct sctp_association *asoc, struct sctp_outq *q)
 {
 	q->asoc = asoc;
-	skb_queue_head_init(&q->out);
-	skb_queue_head_init(&q->control);
+	INIT_LIST_HEAD(&q->out_chunk_list);
+	INIT_LIST_HEAD(&q->control_chunk_list);
 	INIT_LIST_HEAD(&q->retransmit);
 	INIT_LIST_HEAD(&q->sacked);
 	INIT_LIST_HEAD(&q->abandoned);
@@ -217,7 +222,7 @@ void sctp_outq_teardown(struct sctp_outq
 {
 	struct sctp_transport *transport;
 	struct list_head *lchunk, *pos, *temp;
-	struct sctp_chunk *chunk;
+	struct sctp_chunk *chunk, *tmp;
 
 	/* Throw away unacknowledged chunks. */
 	list_for_each(pos, &q->asoc->peer.transport_addr_list) {
@@ -269,8 +274,10 @@ void sctp_outq_teardown(struct sctp_outq
 	q->error = 0;
 
 	/* Throw away any leftover control chunks. */
-	while ((chunk = (struct sctp_chunk *) skb_dequeue(&q->control)) != NULL)
+	list_for_each_entry_safe(chunk, tmp, &q->control_chunk_list, list) {
+		list_del_init(&chunk->list);
 		sctp_chunk_free(chunk);
+	}
 }
 
 /* Free the outqueue structure and any related pending chunks.  */
@@ -333,7 +340,7 @@ int sctp_outq_tail(struct sctp_outq *q, 
 			break;
 		};
 	} else {
-		__skb_queue_tail(&q->control, (struct sk_buff *) chunk);
+		list_add_tail(&chunk->list, &q->control_chunk_list);
 		SCTP_INC_STATS(SCTP_MIB_OUTCTRLCHUNKS);
 	}
 
@@ -650,10 +657,9 @@ int sctp_outq_flush(struct sctp_outq *q,
 	__u16 sport = asoc->base.bind_addr.port;
 	__u16 dport = asoc->peer.port;
 	__u32 vtag = asoc->peer.i.init_tag;
-	struct sk_buff_head *queue;
 	struct sctp_transport *transport = NULL;
 	struct sctp_transport *new_transport;
-	struct sctp_chunk *chunk;
+	struct sctp_chunk *chunk, *tmp;
 	sctp_xmit_t status;
 	int error = 0;
 	int start_timer = 0;
@@ -675,16 +681,17 @@ int sctp_outq_flush(struct sctp_outq *q,
 	 *   ...
 	 */
 
-	queue = &q->control;
-	while ((chunk = (struct sctp_chunk *)skb_dequeue(queue)) != NULL) {
+	list_for_each_entry_safe(chunk, tmp, &q->control_chunk_list, list) {
+		list_del_init(&chunk->list);
+
 		/* Pick the right transport to use. */
 		new_transport = chunk->transport;
 
 		if (!new_transport) {
 			new_transport = asoc->peer.active_path;
-		} else if (!new_transport->active) {
-			/* If the chunk is Heartbeat or Heartbeat Ack, 
-			 * send it to chunk->transport, even if it's 
+		} else if (new_transport->state == SCTP_INACTIVE) {
+			/* If the chunk is Heartbeat or Heartbeat Ack,
+			 * send it to chunk->transport, even if it's
 			 * inactive.
 			 *
 			 * 3.3.6 Heartbeat Acknowledgement:
@@ -814,8 +821,6 @@ int sctp_outq_flush(struct sctp_outq *q,
 
 		/* Finally, transmit new packets.  */
 		start_timer = 0;
-		queue = &q->out;
-
 		while ((chunk = sctp_outq_dequeue_data(q)) != NULL) {
 			/* RFC 2960 6.5 Every DATA chunk MUST carry a valid
 			 * stream identifier.
@@ -840,7 +845,8 @@ int sctp_outq_flush(struct sctp_outq *q,
 			 * Otherwise, we want to use the active path.
 			 */
 			new_transport = chunk->transport;
-			if (!new_transport || !new_transport->active)
+			if (!new_transport ||
+			    new_transport->state == SCTP_INACTIVE)
 				new_transport = asoc->peer.active_path;
 
 			/* Change packets if necessary.  */
@@ -1148,8 +1154,9 @@ int sctp_outq_sack(struct sctp_outq *q, 
 	/* See if all chunks are acked.
 	 * Make sure the empty queue handler will get run later.
 	 */
-	q->empty = skb_queue_empty(&q->out) && skb_queue_empty(&q->control) &&
-			list_empty(&q->retransmit);
+	q->empty = (list_empty(&q->out_chunk_list) &&
+		    list_empty(&q->control_chunk_list) &&
+		    list_empty(&q->retransmit));
 	if (!q->empty)
 		goto finish;
 
@@ -1454,7 +1461,7 @@ static void sctp_check_transmitted(struc
 			/* Mark the destination transport address as
 			 * active if it is not so marked.
 			 */
-			if (!transport->active) {
+			if (transport->state == SCTP_INACTIVE) {
 				sctp_assoc_control_transport(
 					transport->asoc,
 					transport,
@@ -1678,9 +1685,9 @@ static void sctp_generate_fwdtsn(struct 
 		if (TSN_lte(tsn, ctsn)) {
 			list_del_init(lchunk);
 			if (!chunk->tsn_gap_acked) {
-			chunk->transport->flight_size -=
-						 sctp_data_size(chunk);
-			q->outstanding_bytes -= sctp_data_size(chunk);
+				chunk->transport->flight_size -=
+					sctp_data_size(chunk);
+				q->outstanding_bytes -= sctp_data_size(chunk);
 			}
 			sctp_chunk_free(chunk);
 		} else {
@@ -1728,7 +1735,7 @@ static void sctp_generate_fwdtsn(struct 
 					      nskips, &ftsn_skip_arr[0]); 
 
 	if (ftsn_chunk) {
-		__skb_queue_tail(&q->control, (struct sk_buff *)ftsn_chunk);
+		list_add_tail(&ftsn_chunk->list, &q->control_chunk_list);
 		SCTP_INC_STATS(SCTP_MIB_OUTCTRLCHUNKS);
 	}
 }
diff --git a/net/sctp/proc.c b/net/sctp/proc.c
--- a/net/sctp/proc.c
+++ b/net/sctp/proc.c
@@ -57,6 +57,7 @@ static struct snmp_mib sctp_snmp_list[] 
 	SNMP_MIB_ITEM("SctpReasmUsrMsgs", SCTP_MIB_REASMUSRMSGS),
 	SNMP_MIB_ITEM("SctpOutSCTPPacks", SCTP_MIB_OUTSCTPPACKS),
 	SNMP_MIB_ITEM("SctpInSCTPPacks", SCTP_MIB_INSCTPPACKS),
+	SNMP_MIB_SENTINEL
 };
 
 /* Return the current value of a particular entry in the mib by adding its
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -219,7 +219,7 @@ static void sctp_free_local_addr_list(vo
 
 /* Copy the local addresses which are valid for 'scope' into 'bp'.  */
 int sctp_copy_local_addr_list(struct sctp_bind_addr *bp, sctp_scope_t scope,
-			      int gfp, int copy_flags)
+			      unsigned int __nocast gfp, int copy_flags)
 {
 	struct sctp_sockaddr_entry *addr;
 	int error = 0;
@@ -1050,7 +1050,10 @@ SCTP_STATIC __init int sctp_init(void)
 	sctp_sndbuf_policy		= 0;
 
 	/* HB.interval              - 30 seconds */
-	sctp_hb_interval		= 30 * HZ;
+	sctp_hb_interval		= SCTP_DEFAULT_TIMEOUT_HEARTBEAT;
+
+	/* delayed SACK timeout */
+	sctp_sack_timeout		= SCTP_DEFAULT_TIMEOUT_SACK;
 
 	/* Implementation specific variables. */
 
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -78,7 +78,7 @@ static sctp_cookie_param_t *sctp_pack_co
 static int sctp_process_param(struct sctp_association *asoc,
 			      union sctp_params param,
 			      const union sctp_addr *peer_addr,
-			      int gfp);
+			      unsigned int __nocast gfp);
 
 /* What was the inbound interface for this chunk? */
 int sctp_chunk_iif(const struct sctp_chunk *chunk)
@@ -174,7 +174,7 @@ void  sctp_init_cause(struct sctp_chunk 
  */
 struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc,
 			     const struct sctp_bind_addr *bp,
-			     int gfp, int vparam_len)
+			     unsigned int __nocast gfp, int vparam_len)
 {
 	sctp_inithdr_t init;
 	union sctp_params addrs;
@@ -261,7 +261,7 @@ nodata:
 
 struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc,
 				 const struct sctp_chunk *chunk,
-				 int gfp, int unkparam_len)
+				 unsigned int __nocast gfp, int unkparam_len)
 {
 	sctp_inithdr_t initack;
 	struct sctp_chunk *retval;
@@ -1003,6 +1003,7 @@ struct sctp_chunk *sctp_chunkify(struct 
 		SCTP_DEBUG_PRINTK("chunkifying skb %p w/o an sk\n", skb);
 	}
 
+	INIT_LIST_HEAD(&retval->list);
 	retval->skb		= skb;
 	retval->asoc		= (struct sctp_association *)asoc;
 	retval->resent  	= 0;
@@ -1116,8 +1117,7 @@ static void sctp_chunk_destroy(struct sc
 /* Possibly, free the chunk.  */
 void sctp_chunk_free(struct sctp_chunk *chunk)
 {
-	/* Make sure that we are not on any list.  */
-	skb_unlink((struct sk_buff *) chunk);
+	BUG_ON(!list_empty(&chunk->list));
 	list_del_init(&chunk->transmitted_list);
 
 	/* Release our reference on the message tracker. */
@@ -1233,7 +1233,8 @@ void sctp_chunk_assign_tsn(struct sctp_c
 
 /* Create a CLOSED association to use with an incoming packet.  */
 struct sctp_association *sctp_make_temp_asoc(const struct sctp_endpoint *ep,
-					struct sctp_chunk *chunk, int gfp)
+					struct sctp_chunk *chunk,
+					unsigned int __nocast gfp)
 {
 	struct sctp_association *asoc;
 	struct sk_buff *skb;
@@ -1348,7 +1349,7 @@ nodata:
 struct sctp_association *sctp_unpack_cookie(
 	const struct sctp_endpoint *ep,
 	const struct sctp_association *asoc,
-	struct sctp_chunk *chunk, int gfp,
+	struct sctp_chunk *chunk, unsigned int __nocast gfp,
 	int *error, struct sctp_chunk **errp)
 {
 	struct sctp_association *retval = NULL;
@@ -1812,7 +1813,7 @@ int sctp_verify_init(const struct sctp_a
  */
 int sctp_process_init(struct sctp_association *asoc, sctp_cid_t cid,
 		      const union sctp_addr *peer_addr,
-		      sctp_init_chunk_t *peer_init, int gfp)
+		      sctp_init_chunk_t *peer_init, unsigned int __nocast gfp)
 {
 	union sctp_params param;
 	struct sctp_transport *transport;
@@ -1830,7 +1831,7 @@ int sctp_process_init(struct sctp_associ
 	 * be a a better choice than any of the embedded addresses.
 	 */
 	if (peer_addr)
-		if(!sctp_assoc_add_peer(asoc, peer_addr, gfp))
+		if(!sctp_assoc_add_peer(asoc, peer_addr, gfp, SCTP_ACTIVE))
 			goto nomem;
 
 	/* Process the initialization parameters.  */
@@ -1841,6 +1842,14 @@ int sctp_process_init(struct sctp_associ
                         goto clean_up;
 	}
 
+	/* Walk list of transports, removing transports in the UNKNOWN state. */
+	list_for_each_safe(pos, temp, &asoc->peer.transport_addr_list) {
+		transport = list_entry(pos, struct sctp_transport, transports);
+		if (transport->state == SCTP_UNKNOWN) {
+			sctp_assoc_rm_peer(asoc, transport);
+		}
+	}
+
 	/* The fixed INIT headers are always in network byte
 	 * order.
 	 */
@@ -1906,7 +1915,8 @@ int sctp_process_init(struct sctp_associ
 	 * stream sequence number shall be set to 0.
 	 */
 
-	/* Allocate storage for the negotiated streams if it is not a temporary 	 * association.
+	/* Allocate storage for the negotiated streams if it is not a temporary
+ 	 * association.
 	 */
 	if (!asoc->temp) {
 		int assoc_id;
@@ -1952,6 +1962,9 @@ clean_up:
 		list_del_init(pos);
 		sctp_transport_free(transport);
 	}
+
+	asoc->peer.transport_count = 0;
+
 nomem:
 	return 0;
 }
@@ -1971,7 +1984,7 @@ nomem:
 static int sctp_process_param(struct sctp_association *asoc,
 			      union sctp_params param,
 			      const union sctp_addr *peer_addr,
-			      int gfp)
+			      unsigned int __nocast gfp)
 {
 	union sctp_addr addr;
 	int i;
@@ -1995,7 +2008,7 @@ static int sctp_process_param(struct sct
 		af->from_addr_param(&addr, param.addr, asoc->peer.port, 0);
 		scope = sctp_scope(peer_addr);
 		if (sctp_in_scope(&addr, scope))
-			if (!sctp_assoc_add_peer(asoc, &addr, gfp))
+			if (!sctp_assoc_add_peer(asoc, &addr, gfp, SCTP_ACTIVE))
 				return 0;
 		break;
 
@@ -2396,7 +2409,7 @@ static __u16 sctp_process_asconf_param(s
 	 	 * Due to Resource Shortage'.
 	 	 */
 
-		peer = sctp_assoc_add_peer(asoc, &addr, GFP_ATOMIC);
+		peer = sctp_assoc_add_peer(asoc, &addr, GFP_ATOMIC, SCTP_ACTIVE);
 		if (!peer)
 			return SCTP_ERROR_RSRC_LOW;
 
@@ -2727,8 +2740,12 @@ int sctp_process_asconf_ack(struct sctp_
 	asoc->addip_last_asconf = NULL;
 
 	/* Send the next asconf chunk from the addip chunk queue. */
-	asconf = (struct sctp_chunk *)__skb_dequeue(&asoc->addip_chunks);
-	if (asconf) {
+	if (!list_empty(&asoc->addip_chunk_list)) {
+		struct list_head *entry = asoc->addip_chunk_list.next;
+		asconf = list_entry(entry, struct sctp_chunk, list);
+
+		list_del_init(entry);
+
 		/* Hold the chunk until an ASCONF_ACK is received. */
 		sctp_chunk_hold(asconf);
 		if (sctp_primitive_ASCONF(asoc, asconf))
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
--- a/net/sctp/sm_sideeffect.c
+++ b/net/sctp/sm_sideeffect.c
@@ -63,7 +63,7 @@ static int sctp_cmd_interpreter(sctp_eve
 				void *event_arg,
 			 	sctp_disposition_t status,
 				sctp_cmd_seq_t *commands,
-				int gfp);
+				unsigned int __nocast gfp);
 static int sctp_side_effects(sctp_event_t event_type, sctp_subtype_t subtype,
 			     sctp_state_t state,
 			     struct sctp_endpoint *ep,
@@ -71,7 +71,7 @@ static int sctp_side_effects(sctp_event_
 			     void *event_arg,
 			     sctp_disposition_t status,
 			     sctp_cmd_seq_t *commands,
-			     int gfp);
+			     unsigned int __nocast gfp);
 
 /********************************************************************
  * Helper functions
@@ -414,11 +414,13 @@ static void sctp_do_8_2_transport_strike
 	 */
 	asoc->overall_error_count++;
 
-	if (transport->active &&
+	if (transport->state != SCTP_INACTIVE &&
 	    (transport->error_count++ >= transport->max_retrans)) {
-		SCTP_DEBUG_PRINTK("transport_strike: transport "
-				  "IP:%d.%d.%d.%d failed.\n",
-				  NIPQUAD(transport->ipaddr.v4.sin_addr));
+		SCTP_DEBUG_PRINTK_IPADDR("transport_strike:association %p",
+					 " transport IP: port:%d failed.\n",
+					 asoc,
+					 (&transport->ipaddr),
+					 transport->ipaddr.v4.sin_port);
 		sctp_assoc_control_transport(asoc, transport,
 					     SCTP_TRANSPORT_DOWN,
 					     SCTP_FAILED_THRESHOLD);
@@ -495,7 +497,8 @@ static void sctp_cmd_assoc_failed(sctp_c
 static int sctp_cmd_process_init(sctp_cmd_seq_t *commands,
 				 struct sctp_association *asoc,
 				 struct sctp_chunk *chunk,
-				 sctp_init_chunk_t *peer_init, int gfp)
+				 sctp_init_chunk_t *peer_init,
+				 unsigned int __nocast gfp)
 {
 	int error;
 
@@ -593,7 +596,7 @@ static void sctp_cmd_transport_on(sctp_c
 	/* Mark the destination transport address as active if it is not so
 	 * marked.
 	 */
-	if (!t->active)
+	if (t->state == SCTP_INACTIVE)
 		sctp_assoc_control_transport(asoc, t, SCTP_TRANSPORT_UP,
 					     SCTP_HEARTBEAT_SUCCESS);
 
@@ -665,8 +668,11 @@ static void sctp_cmd_new_state(sctp_cmd_
 
 	asoc->state = state;
 
+	SCTP_DEBUG_PRINTK("sctp_cmd_new_state: asoc %p[%s]\n",
+			  asoc, sctp_state_tbl[state]);
+
 	if (sctp_style(sk, TCP)) {
-		/* Change the sk->sk_state of a TCP-style socket that has 
+		/* Change the sk->sk_state of a TCP-style socket that has
 		 * sucessfully completed a connect() call.
 		 */
 		if (sctp_state(asoc, ESTABLISHED) && sctp_sstate(sk, CLOSED))
@@ -678,6 +684,16 @@ static void sctp_cmd_new_state(sctp_cmd_
 			sk->sk_shutdown |= RCV_SHUTDOWN;
 	}
 
+	if (sctp_state(asoc, COOKIE_WAIT)) {
+		/* Reset init timeouts since they may have been
+		 * increased due to timer expirations.
+		 */
+		asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_INIT] =
+			asoc->ep->timeouts[SCTP_EVENT_TIMEOUT_T1_INIT];
+		asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_COOKIE] =
+			asoc->ep->timeouts[SCTP_EVENT_TIMEOUT_T1_COOKIE];
+	}
+
 	if (sctp_state(asoc, ESTABLISHED) ||
 	    sctp_state(asoc, CLOSED) ||
 	    sctp_state(asoc, SHUTDOWN_RECEIVED)) {
@@ -837,7 +853,7 @@ int sctp_do_sm(sctp_event_t event_type, 
 	       struct sctp_endpoint *ep,
 	       struct sctp_association *asoc,
 	       void *event_arg,
-	       int gfp)
+	       unsigned int __nocast gfp)
 {
 	sctp_cmd_seq_t commands;
 	const sctp_sm_table_entry_t *state_fn;
@@ -882,7 +898,7 @@ static int sctp_side_effects(sctp_event_
 			     void *event_arg,
 			     sctp_disposition_t status,
 			     sctp_cmd_seq_t *commands,
-			     int gfp)
+			     unsigned int __nocast gfp)
 {
 	int error;
 
@@ -970,7 +986,7 @@ static int sctp_cmd_interpreter(sctp_eve
 				void *event_arg,
 			 	sctp_disposition_t status,
 				sctp_cmd_seq_t *commands,
-				int gfp)
+				unsigned int __nocast gfp)
 {
 	int error = 0;
 	int force;
@@ -1120,10 +1136,10 @@ static int sctp_cmd_interpreter(sctp_eve
 			 * to be executed only during failed attempts of
 			 * association establishment.
 			 */
-			if ((asoc->peer.retran_path != 
-			     asoc->peer.primary_path) && 
-			    (asoc->counters[SCTP_COUNTER_INIT_ERROR] > 0)) {
-				sctp_add_cmd_sf(commands, 
+			if ((asoc->peer.retran_path !=
+			     asoc->peer.primary_path) &&
+			    (asoc->init_err_counter > 0)) {
+				sctp_add_cmd_sf(commands,
 				                SCTP_CMD_FORCE_PRIM_RETRAN,
 						SCTP_NULL());
 			}
@@ -1237,18 +1253,67 @@ static int sctp_cmd_interpreter(sctp_eve
 				sctp_association_put(asoc);
 			break;
 
+		case SCTP_CMD_INIT_CHOOSE_TRANSPORT:
+			chunk = cmd->obj.ptr;
+			t = sctp_assoc_choose_init_transport(asoc);
+			asoc->init_last_sent_to = t;
+			chunk->transport = t;
+			t->init_sent_count++;
+			break;
+
 		case SCTP_CMD_INIT_RESTART:
 			/* Do the needed accounting and updates
 			 * associated with restarting an initialization
-			 * timer.
+			 * timer. Only multiply the timeout by two if
+			 * all transports have been tried at the current
+			 * timeout.
 			 */
-			asoc->counters[SCTP_COUNTER_INIT_ERROR]++;
-			asoc->timeouts[cmd->obj.to] *= 2;
-			if (asoc->timeouts[cmd->obj.to] >
+			t = asoc->init_last_sent_to;
+			asoc->init_err_counter++;
+
+			if (t->init_sent_count > (asoc->init_cycle + 1)) {
+				asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_INIT] *= 2;
+				if (asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_INIT] >
+				    asoc->max_init_timeo) {
+					asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_INIT] =
+						asoc->max_init_timeo;
+				}
+				asoc->init_cycle++;
+				SCTP_DEBUG_PRINTK(
+					"T1 INIT Timeout adjustment"
+					" init_err_counter: %d"
+					" cycle: %d"
+					" timeout: %d\n",
+					asoc->init_err_counter,
+					asoc->init_cycle,
+					asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_INIT]);
+			}
+
+			sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART,
+					SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT));
+			break;
+
+		case SCTP_CMD_COOKIEECHO_RESTART:
+			/* Do the needed accounting and updates
+			 * associated with restarting an initialization
+			 * timer. Only multiply the timeout by two if
+			 * all transports have been tried at the current
+			 * timeout.
+			 */
+			asoc->init_err_counter++;
+
+			asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_COOKIE] *= 2;
+			if (asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_COOKIE] >
 			    asoc->max_init_timeo) {
-				asoc->timeouts[cmd->obj.to] =
+				asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_COOKIE] =
 					asoc->max_init_timeo;
 			}
+			SCTP_DEBUG_PRINTK(
+				"T1 COOKIE Timeout adjustment"
+				" init_err_counter: %d"
+				" timeout: %d\n",
+				asoc->init_err_counter,
+				asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_COOKIE]);
 
 			/* If we've sent any data bundled with
 			 * COOKIE-ECHO we need to resend.
@@ -1261,7 +1326,7 @@ static int sctp_cmd_interpreter(sctp_eve
 
 			sctp_add_cmd_sf(commands,
 					SCTP_CMD_TIMER_RESTART,
-					SCTP_TO(cmd->obj.to));
+					SCTP_TO(SCTP_EVENT_TIMEOUT_T1_COOKIE));
 			break;
 
 		case SCTP_CMD_INIT_FAILED:
@@ -1273,12 +1338,13 @@ static int sctp_cmd_interpreter(sctp_eve
 					      subtype, chunk, cmd->obj.u32);
 			break;
 
-		case SCTP_CMD_COUNTER_INC:
-			asoc->counters[cmd->obj.counter]++;
+		case SCTP_CMD_INIT_COUNTER_INC:
+			asoc->init_err_counter++;
 			break;
 
-		case SCTP_CMD_COUNTER_RESET:
-			asoc->counters[cmd->obj.counter] = 0;
+		case SCTP_CMD_INIT_COUNTER_RESET:
+			asoc->init_err_counter = 0;
+			asoc->init_cycle = 0;
 			break;
 
 		case SCTP_CMD_REPORT_DUP:
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -92,6 +92,17 @@ static sctp_disposition_t sctp_sf_shut_8
 					     sctp_cmd_seq_t *commands);
 static struct sctp_sackhdr *sctp_sm_pull_sack(struct sctp_chunk *chunk);
 
+static sctp_disposition_t sctp_stop_t1_and_abort(sctp_cmd_seq_t *commands,
+					   __u16 error,
+					   const struct sctp_association *asoc,
+					   struct sctp_transport *transport);
+
+static sctp_disposition_t sctp_sf_violation_chunklen(
+				     const struct sctp_endpoint *ep,
+				     const struct sctp_association *asoc,
+				     const sctp_subtype_t type,
+				     void *arg,
+				     sctp_cmd_seq_t *commands);
 
 /* Small helper function that checks if the chunk length
  * is of the appropriate length.  The 'required_length' argument
@@ -533,6 +544,9 @@ sctp_disposition_t sctp_sf_do_5_1C_ack(c
 	sctp_add_cmd_sf(commands, SCTP_CMD_PEER_INIT,
 			SCTP_PEER_INIT(initchunk));
 
+	/* Reset init error count upon receipt of INIT-ACK.  */
+	sctp_add_cmd_sf(commands, SCTP_CMD_INIT_COUNTER_RESET, SCTP_NULL());
+
 	/* 5.1 C) "A" shall stop the T1-init timer and leave
 	 * COOKIE-WAIT state.  "A" shall then ... start the T1-cookie
 	 * timer, and enter the COOKIE-ECHOED state.
@@ -775,8 +789,7 @@ sctp_disposition_t sctp_sf_do_5_1E_ca(co
 	 * from the COOKIE-ECHOED state to the COOKIE-WAIT
 	 * state is performed.
 	 */
-	sctp_add_cmd_sf(commands, SCTP_CMD_COUNTER_RESET,
-	                SCTP_COUNTER(SCTP_COUNTER_INIT_ERROR));
+	sctp_add_cmd_sf(commands, SCTP_CMD_INIT_COUNTER_RESET, SCTP_NULL());
 
 	/* RFC 2960 5.1 Normal Establishment of an Association
 	 *
@@ -1019,10 +1032,22 @@ sctp_disposition_t sctp_sf_backbeat_8_3(
 	link = sctp_assoc_lookup_paddr(asoc, &from_addr);
 
 	/* This should never happen, but lets log it if so.  */
-	if (!link) {
-		printk(KERN_WARNING
-		       "%s: Could not find address %d.%d.%d.%d\n",
-		       __FUNCTION__, NIPQUAD(from_addr.v4.sin_addr));
+	if (unlikely(!link)) {
+		if (from_addr.sa.sa_family == AF_INET6) {
+			printk(KERN_WARNING
+			       "%s association %p could not find address "
+			       "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n",
+			       __FUNCTION__,
+			       asoc,
+			       NIP6(from_addr.v6.sin6_addr));
+		} else {
+			printk(KERN_WARNING
+			       "%s association %p could not find address "
+			       "%u.%u.%u.%u\n",
+			       __FUNCTION__,
+			       asoc,
+			       NIPQUAD(from_addr.v4.sin_addr.s_addr));
+		}
 		return SCTP_DISPOSITION_DISCARD;
 	}
 
@@ -2095,9 +2120,7 @@ static sctp_disposition_t sctp_sf_do_5_2
 	sctp_errhdr_t *err;
 	struct sctp_chunk *reply;
 	struct sctp_bind_addr *bp;
-	int attempts;
-
-	attempts = asoc->counters[SCTP_COUNTER_INIT_ERROR] + 1;
+	int attempts = asoc->init_err_counter + 1;
 
 	if (attempts >= asoc->max_init_attempts) {
 		sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED,
@@ -2157,8 +2180,7 @@ static sctp_disposition_t sctp_sf_do_5_2
 	/* Cast away the const modifier, as we want to just
 	 * rerun it through as a sideffect.
 	 */
-	sctp_add_cmd_sf(commands, SCTP_CMD_COUNTER_INC,
-			SCTP_COUNTER(SCTP_COUNTER_INIT_ERROR));
+	sctp_add_cmd_sf(commands, SCTP_CMD_INIT_COUNTER_INC, SCTP_NULL());
 
 	sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
 			SCTP_TO(SCTP_EVENT_TIMEOUT_T1_COOKIE));
@@ -2281,8 +2303,7 @@ sctp_disposition_t sctp_sf_cookie_wait_a
 	if (len >= sizeof(struct sctp_chunkhdr) + sizeof(struct sctp_errhdr))
 		error = ((sctp_errhdr_t *)chunk->skb->data)->cause;
 
- 	sctp_stop_t1_and_abort(commands, error);
-	return SCTP_DISPOSITION_ABORT;
+	return sctp_stop_t1_and_abort(commands, error, asoc, chunk->transport);
 }
 
 /*
@@ -2294,8 +2315,8 @@ sctp_disposition_t sctp_sf_cookie_wait_i
 					void *arg,
 					sctp_cmd_seq_t *commands)
 {
-	sctp_stop_t1_and_abort(commands, SCTP_ERROR_NO_ERROR);
- 	return SCTP_DISPOSITION_ABORT;
+	return sctp_stop_t1_and_abort(commands, SCTP_ERROR_NO_ERROR, asoc,
+				      (struct sctp_transport *)arg);
 }
 
 /*
@@ -2318,8 +2339,12 @@ sctp_disposition_t sctp_sf_cookie_echoed
  *
  * This is common code called by several sctp_sf_*_abort() functions above.
  */
-void sctp_stop_t1_and_abort(sctp_cmd_seq_t *commands, __u16 error)
+static sctp_disposition_t sctp_stop_t1_and_abort(sctp_cmd_seq_t *commands,
+					   __u16 error,
+					   const struct sctp_association *asoc,
+					   struct sctp_transport *transport)
 {
+	SCTP_DEBUG_PRINTK("ABORT received (INIT).\n");
 	sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
 			SCTP_STATE(SCTP_STATE_CLOSED));
 	SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
@@ -2328,6 +2353,7 @@ void sctp_stop_t1_and_abort(sctp_cmd_seq
 	/* CMD_INIT_FAILED will DELETE_TCB. */
 	sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED,
 			SCTP_U32(error));
+	return SCTP_DISPOSITION_ABORT;
 }
 
 /*
@@ -3672,7 +3698,8 @@ sctp_disposition_t sctp_sf_violation(con
  *
  * Generate an  ABORT chunk and terminate the association.
  */
-sctp_disposition_t sctp_sf_violation_chunklen(const struct sctp_endpoint *ep,
+static sctp_disposition_t sctp_sf_violation_chunklen(
+				     const struct sctp_endpoint *ep,
 				     const struct sctp_association *asoc,
 				     const sctp_subtype_t type,
 				     void *arg,
@@ -3805,6 +3832,10 @@ sctp_disposition_t sctp_sf_do_prm_asoc(c
 	sctp_add_cmd_sf(commands, SCTP_CMD_NEW_ASOC,
 			SCTP_ASOC((struct sctp_association *) asoc));
 
+	/* Choose transport for INIT. */
+	sctp_add_cmd_sf(commands, SCTP_CMD_INIT_CHOOSE_TRANSPORT,
+			SCTP_CHUNK(repl));
+
 	/* After sending the INIT, "A" starts the T1-init timer and
 	 * enters the COOKIE-WAIT state.
 	 */
@@ -4589,7 +4620,7 @@ sctp_disposition_t sctp_sf_do_6_2_sack(c
 }
 
 /*
- * sctp_sf_t1_timer_expire
+ * sctp_sf_t1_init_timer_expire
  *
  * Section: 4 Note: 2
  * Verification Tag:
@@ -4603,7 +4634,59 @@ sctp_disposition_t sctp_sf_do_6_2_sack(c
  *     endpoint MUST abort the initialization process and report the
  *     error to SCTP user.
  *
- *   3) If the T1-cookie timer expires, the endpoint MUST retransmit
+ * Outputs
+ * (timers, events)
+ *
+ */
+sctp_disposition_t sctp_sf_t1_init_timer_expire(const struct sctp_endpoint *ep,
+					   const struct sctp_association *asoc,
+					   const sctp_subtype_t type,
+					   void *arg,
+					   sctp_cmd_seq_t *commands)
+{
+	struct sctp_chunk *repl = NULL;
+	struct sctp_bind_addr *bp;
+	int attempts = asoc->init_err_counter + 1;
+
+	SCTP_DEBUG_PRINTK("Timer T1 expired (INIT).\n");
+
+	if (attempts < asoc->max_init_attempts) {
+		bp = (struct sctp_bind_addr *) &asoc->base.bind_addr;
+		repl = sctp_make_init(asoc, bp, GFP_ATOMIC, 0);
+		if (!repl)
+			return SCTP_DISPOSITION_NOMEM;
+
+		/* Choose transport for INIT. */
+		sctp_add_cmd_sf(commands, SCTP_CMD_INIT_CHOOSE_TRANSPORT,
+				SCTP_CHUNK(repl));
+
+		/* Issue a sideeffect to do the needed accounting. */
+		sctp_add_cmd_sf(commands, SCTP_CMD_INIT_RESTART,
+				SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT));
+
+		sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl));
+	} else {
+		SCTP_DEBUG_PRINTK("Giving up on INIT, attempts: %d"
+				  " max_init_attempts: %d\n",
+				  attempts, asoc->max_init_attempts);
+		sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED,
+				SCTP_U32(SCTP_ERROR_NO_ERROR));
+		return SCTP_DISPOSITION_DELETE_TCB;
+	}
+
+	return SCTP_DISPOSITION_CONSUME;
+}
+
+/*
+ * sctp_sf_t1_cookie_timer_expire
+ *
+ * Section: 4 Note: 2
+ * Verification Tag:
+ * Inputs
+ * (endpoint, asoc)
+ *
+ *  RFC 2960 Section 4 Notes
+ *  3) If the T1-cookie timer expires, the endpoint MUST retransmit
  *     COOKIE ECHO and re-start the T1-cookie timer without changing
  *     state.  This MUST be repeated up to 'Max.Init.Retransmits' times.
  *     After that, the endpoint MUST abort the initialization process and
@@ -4613,46 +4696,26 @@ sctp_disposition_t sctp_sf_do_6_2_sack(c
  * (timers, events)
  *
  */
-sctp_disposition_t sctp_sf_t1_timer_expire(const struct sctp_endpoint *ep,
+sctp_disposition_t sctp_sf_t1_cookie_timer_expire(const struct sctp_endpoint *ep,
 					   const struct sctp_association *asoc,
 					   const sctp_subtype_t type,
 					   void *arg,
 					   sctp_cmd_seq_t *commands)
 {
-	struct sctp_chunk *repl;
-	struct sctp_bind_addr *bp;
-	sctp_event_timeout_t timer = (sctp_event_timeout_t) arg;
-	int timeout;
-	int attempts;
-
-	timeout = asoc->timeouts[timer];
-	attempts = asoc->counters[SCTP_COUNTER_INIT_ERROR] + 1;
-	repl = NULL;
+	struct sctp_chunk *repl = NULL;
+	int attempts = asoc->init_err_counter + 1;
 
-	SCTP_DEBUG_PRINTK("Timer T1 expired.\n");
+	SCTP_DEBUG_PRINTK("Timer T1 expired (COOKIE-ECHO).\n");
 
 	if (attempts < asoc->max_init_attempts) {
-		switch (timer) {
-		case SCTP_EVENT_TIMEOUT_T1_INIT:
-			bp = (struct sctp_bind_addr *) &asoc->base.bind_addr;
-			repl = sctp_make_init(asoc, bp, GFP_ATOMIC, 0);
-			break;
-
-		case SCTP_EVENT_TIMEOUT_T1_COOKIE:
-			repl = sctp_make_cookie_echo(asoc, NULL);
-			break;
-
-		default:
-			BUG();
-			break;
-		};
-
+		repl = sctp_make_cookie_echo(asoc, NULL);
 		if (!repl)
-			goto nomem;
+			return SCTP_DISPOSITION_NOMEM;
 
 		/* Issue a sideeffect to do the needed accounting. */
-		sctp_add_cmd_sf(commands, SCTP_CMD_INIT_RESTART,
-				SCTP_TO(timer));
+		sctp_add_cmd_sf(commands, SCTP_CMD_COOKIEECHO_RESTART,
+				SCTP_TO(SCTP_EVENT_TIMEOUT_T1_COOKIE));
+
 		sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl));
 	} else {
 		sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED,
@@ -4661,9 +4724,6 @@ sctp_disposition_t sctp_sf_t1_timer_expi
 	}
 
 	return SCTP_DISPOSITION_CONSUME;
-
-nomem:
-	return SCTP_DISPOSITION_NOMEM;
 }
 
 /* RFC2960 9.2 If the timer expires, the endpoint must re-send the SHUTDOWN
diff --git a/net/sctp/sm_statetable.c b/net/sctp/sm_statetable.c
--- a/net/sctp/sm_statetable.c
+++ b/net/sctp/sm_statetable.c
@@ -783,7 +783,8 @@ static const sctp_sm_table_entry_t other
 	/* SCTP_STATE_COOKIE_WAIT */ \
 	{.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
 	/* SCTP_STATE_COOKIE_ECHOED */ \
-	{.fn = sctp_sf_t1_timer_expire, .name = "sctp_sf_t1_timer_expire"}, \
+	{.fn = sctp_sf_t1_cookie_timer_expire, \
+	 .name = "sctp_sf_t1_cookie_timer_expire"}, \
 	/* SCTP_STATE_ESTABLISHED */ \
 	{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
 	/* SCTP_STATE_SHUTDOWN_PENDING */ \
@@ -802,7 +803,8 @@ static const sctp_sm_table_entry_t other
 	/* SCTP_STATE_CLOSED */ \
 	{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
 	/* SCTP_STATE_COOKIE_WAIT */ \
-	{.fn = sctp_sf_t1_timer_expire, .name = "sctp_sf_t1_timer_expire"}, \
+	{.fn = sctp_sf_t1_init_timer_expire, \
+	 .name = "sctp_sf_t1_init_timer_expire"}, \
 	/* SCTP_STATE_COOKIE_ECHOED */ \
 	{.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
 	/* SCTP_STATE_ESTABLISHED */ \
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -262,18 +262,18 @@ static struct sctp_transport *sctp_addr_
  *             sockaddr_in6 [RFC 2553]),
  *   addr_len - the size of the address structure.
  */
-SCTP_STATIC int sctp_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
+SCTP_STATIC int sctp_bind(struct sock *sk, struct sockaddr *addr, int addr_len)
 {
 	int retval = 0;
 
 	sctp_lock_sock(sk);
 
-	SCTP_DEBUG_PRINTK("sctp_bind(sk: %p, uaddr: %p, addr_len: %d)\n",
-			  sk, uaddr, addr_len);
+	SCTP_DEBUG_PRINTK("sctp_bind(sk: %p, addr: %p, addr_len: %d)\n",
+			  sk, addr, addr_len);
 
 	/* Disallow binding twice. */
 	if (!sctp_sk(sk)->ep->base.bind_addr.port)
-		retval = sctp_do_bind(sk, (union sctp_addr *)uaddr,
+		retval = sctp_do_bind(sk, (union sctp_addr *)addr,
 				      addr_len);
 	else
 		retval = -EINVAL;
@@ -318,23 +318,27 @@ SCTP_STATIC int sctp_do_bind(struct sock
 	unsigned short snum;
 	int ret = 0;
 
-	SCTP_DEBUG_PRINTK("sctp_do_bind(sk: %p, newaddr: %p, len: %d)\n",
-			  sk, addr, len);
-
 	/* Common sockaddr verification. */
 	af = sctp_sockaddr_af(sp, addr, len);
-	if (!af)
+	if (!af) {
+		SCTP_DEBUG_PRINTK("sctp_do_bind(sk: %p, newaddr: %p, len: %d) EINVAL\n",
+				  sk, addr, len);
 		return -EINVAL;
+	}
+
+	snum = ntohs(addr->v4.sin_port);
+
+	SCTP_DEBUG_PRINTK_IPADDR("sctp_do_bind(sk: %p, new addr: ",
+				 ", port: %d, new port: %d, len: %d)\n",
+				 sk,
+				 addr,
+				 bp->port, snum,
+				 len);
 
 	/* PF specific bind() address verification. */
 	if (!sp->pf->bind_verify(sp, addr))
 		return -EADDRNOTAVAIL;
 
-	snum= ntohs(addr->v4.sin_port);
-
-	SCTP_DEBUG_PRINTK("sctp_do_bind: port: %d, new port: %d\n",
-			  bp->port, snum);
-
 	/* We must either be unbound, or bind to the same port.  */
 	if (bp->port && (snum != bp->port)) {
 		SCTP_DEBUG_PRINTK("sctp_do_bind:"
@@ -402,7 +406,7 @@ static int sctp_send_asconf(struct sctp_
 	 * transmission.
 	 */	
 	if (asoc->addip_last_asconf) {
-		__skb_queue_tail(&asoc->addip_chunks, (struct sk_buff *)chunk);
+		list_add_tail(&chunk->list, &asoc->addip_chunk_list);
 		goto out;	
 	}
 
@@ -816,7 +820,8 @@ out:
  *
  * Basically do nothing but copying the addresses from user to kernel
  * land and invoking either sctp_bindx_add() or sctp_bindx_rem() on the sk.
- * This is used for tunneling the sctp_bindx() request through sctp_setsockopt() * from userspace.
+ * This is used for tunneling the sctp_bindx() request through sctp_setsockopt()
+ * from userspace.
  *
  * We don't use copy_from_user() for optimization: we first do the
  * sanity checks (buffer size -fast- and access check-healthy
@@ -913,6 +918,243 @@ out:
 	return err;
 }
 
+/* __sctp_connect(struct sock* sk, struct sockaddr *kaddrs, int addrs_size)
+ *
+ * Common routine for handling connect() and sctp_connectx().
+ * Connect will come in with just a single address.
+ */
+static int __sctp_connect(struct sock* sk,
+			  struct sockaddr *kaddrs,
+			  int addrs_size)
+{
+	struct sctp_sock *sp;
+	struct sctp_endpoint *ep;
+	struct sctp_association *asoc = NULL;
+	struct sctp_association *asoc2;
+	struct sctp_transport *transport;
+	union sctp_addr to;
+	struct sctp_af *af;
+	sctp_scope_t scope;
+	long timeo;
+	int err = 0;
+	int addrcnt = 0;
+	int walk_size = 0;
+	struct sockaddr *sa_addr;
+	void *addr_buf;
+
+	sp = sctp_sk(sk);
+	ep = sp->ep;
+
+	/* connect() cannot be done on a socket that is already in ESTABLISHED
+	 * state - UDP-style peeled off socket or a TCP-style socket that
+	 * is already connected.
+	 * It cannot be done even on a TCP-style listening socket.
+	 */
+	if (sctp_sstate(sk, ESTABLISHED) ||
+	    (sctp_style(sk, TCP) && sctp_sstate(sk, LISTENING))) {
+		err = -EISCONN;
+		goto out_free;
+	}
+
+	/* Walk through the addrs buffer and count the number of addresses. */
+	addr_buf = kaddrs;
+	while (walk_size < addrs_size) {
+		sa_addr = (struct sockaddr *)addr_buf;
+		af = sctp_get_af_specific(sa_addr->sa_family);
+
+		/* If the address family is not supported or if this address
+		 * causes the address buffer to overflow return EINVAL.
+		 */
+		if (!af || (walk_size + af->sockaddr_len) > addrs_size) {
+			err = -EINVAL;
+			goto out_free;
+		}
+
+		err = sctp_verify_addr(sk, (union sctp_addr *)sa_addr,
+				       af->sockaddr_len);
+		if (err)
+			goto out_free;
+
+		memcpy(&to, sa_addr, af->sockaddr_len);
+		to.v4.sin_port = ntohs(to.v4.sin_port);
+
+		/* Check if there already is a matching association on the
+		 * endpoint (other than the one created here).
+		 */
+		asoc2 = sctp_endpoint_lookup_assoc(ep, &to, &transport);
+		if (asoc2 && asoc2 != asoc) {
+			if (asoc2->state >= SCTP_STATE_ESTABLISHED)
+				err = -EISCONN;
+			else
+				err = -EALREADY;
+			goto out_free;
+		}
+
+		/* If we could not find a matching association on the endpoint,
+		 * make sure that there is no peeled-off association matching
+		 * the peer address even on another socket.
+		 */
+		if (sctp_endpoint_is_peeled_off(ep, &to)) {
+			err = -EADDRNOTAVAIL;
+			goto out_free;
+		}
+
+		if (!asoc) {
+			/* If a bind() or sctp_bindx() is not called prior to
+			 * an sctp_connectx() call, the system picks an
+			 * ephemeral port and will choose an address set
+			 * equivalent to binding with a wildcard address.
+			 */
+			if (!ep->base.bind_addr.port) {
+				if (sctp_autobind(sk)) {
+					err = -EAGAIN;
+					goto out_free;
+				}
+			}
+
+			scope = sctp_scope(&to);
+			asoc = sctp_association_new(ep, sk, scope, GFP_KERNEL);
+			if (!asoc) {
+				err = -ENOMEM;
+				goto out_free;
+			}
+		}
+
+		/* Prime the peer's transport structures.  */
+		transport = sctp_assoc_add_peer(asoc, &to, GFP_KERNEL,
+						SCTP_UNKNOWN);
+		if (!transport) {
+			err = -ENOMEM;
+			goto out_free;
+		}
+
+		addrcnt++;
+		addr_buf += af->sockaddr_len;
+		walk_size += af->sockaddr_len;
+	}
+
+	err = sctp_assoc_set_bind_addr_from_ep(asoc, GFP_KERNEL);
+	if (err < 0) {
+		goto out_free;
+	}
+
+	err = sctp_primitive_ASSOCIATE(asoc, NULL);
+	if (err < 0) {
+		goto out_free;
+	}
+
+	/* Initialize sk's dport and daddr for getpeername() */
+	inet_sk(sk)->dport = htons(asoc->peer.port);
+	af = sctp_get_af_specific(to.sa.sa_family);
+	af->to_sk_daddr(&to, sk);
+
+	timeo = sock_sndtimeo(sk, sk->sk_socket->file->f_flags & O_NONBLOCK);
+	err = sctp_wait_for_connect(asoc, &timeo);
+
+	/* Don't free association on exit. */
+	asoc = NULL;
+
+out_free:
+
+	SCTP_DEBUG_PRINTK("About to exit __sctp_connect() free asoc: %p"
+		          " kaddrs: %p err: %d\n",
+	                  asoc, kaddrs, err);
+	if (asoc)
+		sctp_association_free(asoc);
+	return err;
+}
+
+/* Helper for tunneling sctp_connectx() requests through sctp_setsockopt()
+ *
+ * API 8.9
+ * int sctp_connectx(int sd, struct sockaddr *addrs, int addrcnt);
+ *
+ * If sd is an IPv4 socket, the addresses passed must be IPv4 addresses.
+ * If the sd is an IPv6 socket, the addresses passed can either be IPv4
+ * or IPv6 addresses.
+ *
+ * A single address may be specified as INADDR_ANY or IN6ADDR_ANY, see
+ * Section 3.1.2 for this usage.
+ *
+ * addrs is a pointer to an array of one or more socket addresses. Each
+ * address is contained in its appropriate structure (i.e. struct
+ * sockaddr_in or struct sockaddr_in6) the family of the address type
+ * must be used to distengish the address length (note that this
+ * representation is termed a "packed array" of addresses). The caller
+ * specifies the number of addresses in the array with addrcnt.
+ *
+ * On success, sctp_connectx() returns 0. On failure, sctp_connectx() returns
+ * -1, and sets errno to the appropriate error code.
+ *
+ * For SCTP, the port given in each socket address must be the same, or
+ * sctp_connectx() will fail, setting errno to EINVAL.
+ *
+ * An application can use sctp_connectx to initiate an association with
+ * an endpoint that is multi-homed.  Much like sctp_bindx() this call
+ * allows a caller to specify multiple addresses at which a peer can be
+ * reached.  The way the SCTP stack uses the list of addresses to set up
+ * the association is implementation dependant.  This function only
+ * specifies that the stack will try to make use of all the addresses in
+ * the list when needed.
+ *
+ * Note that the list of addresses passed in is only used for setting up
+ * the association.  It does not necessarily equal the set of addresses
+ * the peer uses for the resulting association.  If the caller wants to
+ * find out the set of peer addresses, it must use sctp_getpaddrs() to
+ * retrieve them after the association has been set up.
+ *
+ * Basically do nothing but copying the addresses from user to kernel
+ * land and invoking either sctp_connectx(). This is used for tunneling
+ * the sctp_connectx() request through sctp_setsockopt() from userspace.
+ *
+ * We don't use copy_from_user() for optimization: we first do the
+ * sanity checks (buffer size -fast- and access check-healthy
+ * pointer); if all of those succeed, then we can alloc the memory
+ * (expensive operation) needed to copy the data to kernel. Then we do
+ * the copying without checking the user space area
+ * (__copy_from_user()).
+ *
+ * On exit there is no need to do sockfd_put(), sys_setsockopt() does
+ * it.
+ *
+ * sk        The sk of the socket
+ * addrs     The pointer to the addresses in user land
+ * addrssize Size of the addrs buffer
+ *
+ * Returns 0 if ok, <0 errno code on error.
+ */
+SCTP_STATIC int sctp_setsockopt_connectx(struct sock* sk,
+				      struct sockaddr __user *addrs,
+				      int addrs_size)
+{
+	int err = 0;
+	struct sockaddr *kaddrs;
+
+	SCTP_DEBUG_PRINTK("%s - sk %p addrs %p addrs_size %d\n",
+			  __FUNCTION__, sk, addrs, addrs_size);
+
+	if (unlikely(addrs_size <= 0))
+		return -EINVAL;
+
+	/* Check the user passed a healthy pointer.  */
+	if (unlikely(!access_ok(VERIFY_READ, addrs, addrs_size)))
+		return -EFAULT;
+
+	/* Alloc space for the address array in kernel memory.  */
+	kaddrs = (struct sockaddr *)kmalloc(addrs_size, GFP_KERNEL);
+	if (unlikely(!kaddrs))
+		return -ENOMEM;
+
+	if (__copy_from_user(kaddrs, addrs, addrs_size)) {
+		err = -EFAULT;
+	} else {
+		err = __sctp_connect(sk, kaddrs, addrs_size);
+	}
+
+	kfree(kaddrs);
+	return err;
+}
+
 /* API 3.1.4 close() - UDP Style Syntax
  * Applications use close() to perform graceful shutdown (as described in
  * Section 10.1 of [SCTP]) on ALL the associations currently represented
@@ -1095,7 +1337,7 @@ SCTP_STATIC int sctp_sendmsg(struct kioc
 	sp = sctp_sk(sk);
 	ep = sp->ep;
 
-	SCTP_DEBUG_PRINTK("Using endpoint: %s.\n", ep->debug_name);
+	SCTP_DEBUG_PRINTK("Using endpoint: %p.\n", ep);
 
 	/* We cannot send a message over a TCP-style listening socket. */
 	if (sctp_style(sk, TCP) && sctp_sstate(sk, LISTENING)) {
@@ -1306,7 +1548,7 @@ SCTP_STATIC int sctp_sendmsg(struct kioc
 		}
 
 		/* Prime the peer's transport structures.  */
-		transport = sctp_assoc_add_peer(asoc, &to, GFP_KERNEL);
+		transport = sctp_assoc_add_peer(asoc, &to, GFP_KERNEL, SCTP_UNKNOWN);
 		if (!transport) {
 			err = -ENOMEM;
 			goto out_free;
@@ -2208,6 +2450,12 @@ SCTP_STATIC int sctp_setsockopt(struct s
 					       optlen, SCTP_BINDX_REM_ADDR);
 		break;
 
+	case SCTP_SOCKOPT_CONNECTX:
+		/* 'optlen' is the size of the addresses buffer. */
+		retval = sctp_setsockopt_connectx(sk, (struct sockaddr __user *)optval,
+					       optlen);
+		break;
+
 	case SCTP_DISABLE_FRAGMENTS:
 		retval = sctp_setsockopt_disable_fragments(sk, optval, optlen);
 		break;
@@ -2283,112 +2531,29 @@ out_nounlock:
  *
  * len: the size of the address.
  */
-SCTP_STATIC int sctp_connect(struct sock *sk, struct sockaddr *uaddr,
+SCTP_STATIC int sctp_connect(struct sock *sk, struct sockaddr *addr,
 			     int addr_len)
 {
-	struct sctp_sock *sp;
-	struct sctp_endpoint *ep;
-	struct sctp_association *asoc;
-	struct sctp_transport *transport;
-	union sctp_addr to;
-	struct sctp_af *af;
-	sctp_scope_t scope;
-	long timeo;
 	int err = 0;
+	struct sctp_af *af;
 
 	sctp_lock_sock(sk);
 
-	SCTP_DEBUG_PRINTK("%s - sk: %p, sockaddr: %p, addr_len: %d)\n",
-			  __FUNCTION__, sk, uaddr, addr_len);
-
-	sp = sctp_sk(sk);
-	ep = sp->ep;
-
-	/* connect() cannot be done on a socket that is already in ESTABLISHED
-	 * state - UDP-style peeled off socket or a TCP-style socket that
-	 * is already connected.
-	 * It cannot be done even on a TCP-style listening socket.
-	 */
-	if (sctp_sstate(sk, ESTABLISHED) ||
-	    (sctp_style(sk, TCP) && sctp_sstate(sk, LISTENING))) {
-		err = -EISCONN;
-		goto out_unlock;
-	}
-
-	err = sctp_verify_addr(sk, (union sctp_addr *)uaddr, addr_len);
-	if (err)
-		goto out_unlock;
-
-	if (addr_len > sizeof(to))
-		addr_len = sizeof(to);
-	memcpy(&to, uaddr, addr_len);
-	to.v4.sin_port = ntohs(to.v4.sin_port);
-
-	asoc = sctp_endpoint_lookup_assoc(ep, &to, &transport);
-	if (asoc) {
-		if (asoc->state >= SCTP_STATE_ESTABLISHED)
-			err = -EISCONN;
-		else
-			err = -EALREADY;
-		goto out_unlock;
-	}
-
-	/* If we could not find a matching association on the endpoint,
-	 * make sure that there is no peeled-off association matching the
-	 * peer address even on another socket.
-	 */
-	if (sctp_endpoint_is_peeled_off(ep, &to)) {
-		err = -EADDRNOTAVAIL;
-		goto out_unlock;
-	}
-
-	/* If a bind() or sctp_bindx() is not called prior to a connect()
-	 * call, the system picks an ephemeral port and will choose an address
-	 * set equivalent to binding with a wildcard address.
-	 */
-	if (!ep->base.bind_addr.port) {
-		if (sctp_autobind(sk)) {
-			err = -EAGAIN;
-			goto out_unlock;
-		}
-	}
+	SCTP_DEBUG_PRINTK("%s - sk: %p, sockaddr: %p, addr_len: %d\n",
+			  __FUNCTION__, sk, addr, addr_len);
 
-	scope = sctp_scope(&to);
-	asoc = sctp_association_new(ep, sk, scope, GFP_KERNEL);
-	if (!asoc) {
-		err = -ENOMEM;
-		goto out_unlock;
-  	}
-
-	/* Prime the peer's transport structures.  */
-	transport = sctp_assoc_add_peer(asoc, &to, GFP_KERNEL);
-	if (!transport) {
-		sctp_association_free(asoc);
-		goto out_unlock;
-	}
-	err = sctp_assoc_set_bind_addr_from_ep(asoc, GFP_KERNEL);
-	if (err < 0) {
-		sctp_association_free(asoc);
-		goto out_unlock;
-	}
-
-	err = sctp_primitive_ASSOCIATE(asoc, NULL);
-	if (err < 0) {
-		sctp_association_free(asoc);
-		goto out_unlock;
+	/* Validate addr_len before calling common connect/connectx routine. */
+	af = sctp_get_af_specific(addr->sa_family);
+	if (!af || addr_len < af->sockaddr_len) {
+		err = -EINVAL;
+	} else {
+		/* Pass correct addr len to common routine (so it knows there
+		 * is only one address being passed.
+		 */
+		err = __sctp_connect(sk, addr, af->sockaddr_len);
 	}
 
-	/* Initialize sk's dport and daddr for getpeername() */
-	inet_sk(sk)->dport = htons(asoc->peer.port);
-	af = sctp_get_af_specific(to.sa.sa_family);
-	af->to_sk_daddr(&to, sk);
-
-	timeo = sock_sndtimeo(sk, sk->sk_socket->file->f_flags & O_NONBLOCK);
-	err = sctp_wait_for_connect(asoc, &timeo);
-
-out_unlock:
 	sctp_release_sock(sk);
-
 	return err;
 }
 
@@ -2677,12 +2842,15 @@ static int sctp_getsockopt_sctp_status(s
 	/* Map ipv4 address into v4-mapped-on-v6 address.  */
 	sctp_get_pf_specific(sk->sk_family)->addr_v4map(sctp_sk(sk),
 		(union sctp_addr *)&status.sstat_primary.spinfo_address);
-	status.sstat_primary.spinfo_state = transport->active;
+	status.sstat_primary.spinfo_state = transport->state;
 	status.sstat_primary.spinfo_cwnd = transport->cwnd;
 	status.sstat_primary.spinfo_srtt = transport->srtt;
 	status.sstat_primary.spinfo_rto = jiffies_to_msecs(transport->rto);
 	status.sstat_primary.spinfo_mtu = transport->pmtu;
 
+	if (status.sstat_primary.spinfo_state == SCTP_UNKNOWN)
+		status.sstat_primary.spinfo_state = SCTP_ACTIVE;
+
 	if (put_user(len, optlen)) {
 		retval = -EFAULT;
 		goto out;
@@ -2733,12 +2901,15 @@ static int sctp_getsockopt_peer_addr_inf
 		return -EINVAL;
 
 	pinfo.spinfo_assoc_id = sctp_assoc2id(transport->asoc);
-	pinfo.spinfo_state = transport->active;
+	pinfo.spinfo_state = transport->state;
 	pinfo.spinfo_cwnd = transport->cwnd;
 	pinfo.spinfo_srtt = transport->srtt;
 	pinfo.spinfo_rto = jiffies_to_msecs(transport->rto);
 	pinfo.spinfo_mtu = transport->pmtu;
 
+	if (pinfo.spinfo_state == SCTP_UNKNOWN)
+		pinfo.spinfo_state = SCTP_ACTIVE;
+
 	if (put_user(len, optlen)) {
 		retval = -EFAULT;
 		goto out;
@@ -3591,7 +3762,8 @@ SCTP_STATIC int sctp_getsockopt(struct s
 	int retval = 0;
 	int len;
 
-	SCTP_DEBUG_PRINTK("sctp_getsockopt(sk: %p, ...)\n", sk);
+	SCTP_DEBUG_PRINTK("sctp_getsockopt(sk: %p... optname: %d)\n",
+			  sk, optname);
 
 	/* I can hardly begin to describe how wrong this is.  This is
 	 * so broken as to be worse than useless.  The API draft
@@ -4368,15 +4540,11 @@ static struct sk_buff *sctp_skb_recv_dat
 		 *  However, this function was corrent in any case. 8)
 		 */
 		if (flags & MSG_PEEK) {
-			unsigned long cpu_flags;
-
-			sctp_spin_lock_irqsave(&sk->sk_receive_queue.lock,
-					       cpu_flags);
+			spin_lock_bh(&sk->sk_receive_queue.lock);
 			skb = skb_peek(&sk->sk_receive_queue);
 			if (skb)
 				atomic_inc(&skb->users);
-			sctp_spin_unlock_irqrestore(&sk->sk_receive_queue.lock,
-						    cpu_flags);
+			spin_unlock_bh(&sk->sk_receive_queue.lock);
 		} else {
 			skb = skb_dequeue(&sk->sk_receive_queue);
 		}
@@ -4600,8 +4768,7 @@ out:
 	return err;
 
 do_error:
-	if (asoc->counters[SCTP_COUNTER_INIT_ERROR] + 1 >=
-					 	asoc->max_init_attempts)
+	if (asoc->init_err_counter + 1 >= asoc->max_init_attempts)
 		err = -ETIMEDOUT;
 	else
 		err = -ECONNREFUSED;
diff --git a/net/sctp/ssnmap.c b/net/sctp/ssnmap.c
--- a/net/sctp/ssnmap.c
+++ b/net/sctp/ssnmap.c
@@ -57,7 +57,8 @@ static inline size_t sctp_ssnmap_size(__
 /* Create a new sctp_ssnmap.
  * Allocate room to store at least 'len' contiguous TSNs.
  */
-struct sctp_ssnmap *sctp_ssnmap_new(__u16 in, __u16 out, int gfp)
+struct sctp_ssnmap *sctp_ssnmap_new(__u16 in, __u16 out,
+				    unsigned int __nocast gfp)
 {
 	struct sctp_ssnmap *retval;
 	int size;
diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c
--- a/net/sctp/sysctl.c
+++ b/net/sctp/sysctl.c
@@ -47,6 +47,8 @@
 static ctl_handler sctp_sysctl_jiffies_ms;
 static long rto_timer_min = 1;
 static long rto_timer_max = 86400000; /* One day */
+static long sack_timer_min = 1;
+static long sack_timer_max = 500;
 
 static ctl_table sctp_table[] = {
 	{
@@ -187,6 +189,17 @@ static ctl_table sctp_table[] = {
 		.mode		= 0644,
 		.proc_handler	= &proc_dointvec
 	},
+	{
+		.ctl_name	= NET_SCTP_SACK_TIMEOUT,
+		.procname	= "sack_timeout",
+		.data		= &sctp_sack_timeout,
+		.maxlen		= sizeof(long),
+		.mode		= 0644,
+		.proc_handler	= &proc_doulongvec_ms_jiffies_minmax,
+		.strategy	= &sctp_sysctl_jiffies_ms,
+		.extra1         = &sack_timer_min,
+		.extra2         = &sack_timer_max,
+	},
 	{ .ctl_name = 0 }
 };
 
diff --git a/net/sctp/transport.c b/net/sctp/transport.c
--- a/net/sctp/transport.c
+++ b/net/sctp/transport.c
@@ -57,7 +57,7 @@
 /* Initialize a new transport from provided memory.  */
 static struct sctp_transport *sctp_transport_init(struct sctp_transport *peer,
 						  const union sctp_addr *addr,
-						  int gfp)
+						  unsigned int __nocast gfp)
 {
 	/* Copy in the address.  */
 	peer->ipaddr = *addr;
@@ -83,7 +83,9 @@ static struct sctp_transport *sctp_trans
 	peer->last_time_used = jiffies;
 	peer->last_time_ecne_reduced = jiffies;
 
-	peer->active = SCTP_ACTIVE;
+	peer->init_sent_count = 0;
+
+	peer->state = SCTP_ACTIVE;
 	peer->hb_allowed = 0;
 
 	/* Initialize the default path max_retrans.  */
@@ -101,7 +103,6 @@ static struct sctp_transport *sctp_trans
 
 	/* Set up the heartbeat timer. */
 	init_timer(&peer->hb_timer);
-	peer->hb_interval = SCTP_DEFAULT_TIMEOUT_HEARTBEAT;
 	peer->hb_timer.function = sctp_generate_heartbeat_event;
 	peer->hb_timer.data = (unsigned long)peer;
 
@@ -120,7 +121,8 @@ static struct sctp_transport *sctp_trans
 }
 
 /* Allocate and initialize a new transport.  */
-struct sctp_transport *sctp_transport_new(const union sctp_addr *addr, int gfp)
+struct sctp_transport *sctp_transport_new(const union sctp_addr *addr,
+					  unsigned int __nocast gfp)
 {
         struct sctp_transport *transport;
 
diff --git a/net/sctp/ulpevent.c b/net/sctp/ulpevent.c
--- a/net/sctp/ulpevent.c
+++ b/net/sctp/ulpevent.c
@@ -74,7 +74,7 @@ SCTP_STATIC void sctp_ulpevent_init(stru
 
 /* Create a new sctp_ulpevent.  */
 SCTP_STATIC struct sctp_ulpevent *sctp_ulpevent_new(int size, int msg_flags,
-						    int gfp)
+						    unsigned int __nocast gfp)
 {
 	struct sctp_ulpevent *event;
 	struct sk_buff *skb;
@@ -136,7 +136,7 @@ static inline void sctp_ulpevent_release
 struct sctp_ulpevent  *sctp_ulpevent_make_assoc_change(
 	const struct sctp_association *asoc,
 	__u16 flags, __u16 state, __u16 error, __u16 outbound,
-	__u16 inbound, int gfp)
+	__u16 inbound, unsigned int __nocast gfp)
 {
 	struct sctp_ulpevent *event;
 	struct sctp_assoc_change *sac;
@@ -237,7 +237,7 @@ fail:
 struct sctp_ulpevent *sctp_ulpevent_make_peer_addr_change(
 	const struct sctp_association *asoc,
 	const struct sockaddr_storage *aaddr,
-	int flags, int state, int error, int gfp)
+	int flags, int state, int error, unsigned int __nocast gfp)
 {
 	struct sctp_ulpevent *event;
 	struct sctp_paddr_change  *spc;
@@ -350,7 +350,7 @@ fail:
  */
 struct sctp_ulpevent *sctp_ulpevent_make_remote_error(
 	const struct sctp_association *asoc, struct sctp_chunk *chunk,
-	__u16 flags, int gfp)
+	__u16 flags, unsigned int __nocast gfp)
 {
 	struct sctp_ulpevent *event;
 	struct sctp_remote_error *sre;
@@ -448,7 +448,7 @@ fail:
  */
 struct sctp_ulpevent *sctp_ulpevent_make_send_failed(
 	const struct sctp_association *asoc, struct sctp_chunk *chunk,
-	__u16 flags, __u32 error, int gfp)
+	__u16 flags, __u32 error, unsigned int __nocast gfp)
 {
 	struct sctp_ulpevent *event;
 	struct sctp_send_failed *ssf;
@@ -557,7 +557,7 @@ fail:
  */
 struct sctp_ulpevent *sctp_ulpevent_make_shutdown_event(
 	const struct sctp_association *asoc,
-	__u16 flags, int gfp)
+	__u16 flags, unsigned int __nocast gfp)
 {
 	struct sctp_ulpevent *event;
 	struct sctp_shutdown_event *sse;
@@ -620,7 +620,7 @@ fail:
  * 5.3.1.6 SCTP_ADAPTION_INDICATION
  */
 struct sctp_ulpevent *sctp_ulpevent_make_adaption_indication(
-	const struct sctp_association *asoc, int gfp)
+	const struct sctp_association *asoc, unsigned int __nocast gfp)
 {
 	struct sctp_ulpevent *event;
 	struct sctp_adaption_event *sai;
@@ -657,7 +657,7 @@ fail:
  */
 struct sctp_ulpevent *sctp_ulpevent_make_rcvmsg(struct sctp_association *asoc,
 						struct sctp_chunk *chunk,
-						int gfp)
+						unsigned int __nocast gfp)
 {
 	struct sctp_ulpevent *event = NULL;
 	struct sk_buff *skb;
@@ -718,7 +718,8 @@ fail:
  *   various events.
  */
 struct sctp_ulpevent *sctp_ulpevent_make_pdapi(
-	const struct sctp_association *asoc, __u32 indication, int gfp)
+	const struct sctp_association *asoc, __u32 indication,
+	unsigned int __nocast gfp)
 {
 	struct sctp_ulpevent *event;
 	struct sctp_pdapi_event *pd;
diff --git a/net/sctp/ulpqueue.c b/net/sctp/ulpqueue.c
--- a/net/sctp/ulpqueue.c
+++ b/net/sctp/ulpqueue.c
@@ -100,7 +100,7 @@ void sctp_ulpq_free(struct sctp_ulpq *ul
 
 /* Process an incoming DATA chunk.  */
 int sctp_ulpq_tail_data(struct sctp_ulpq *ulpq, struct sctp_chunk *chunk,
-			int gfp)
+			unsigned int __nocast gfp)
 {
 	struct sk_buff_head temp;
 	sctp_data_chunk_t *hdr;
@@ -778,7 +778,8 @@ static __u16 sctp_ulpq_renege_frags(stru
 
 /* Partial deliver the first message as there is pressure on rwnd. */
 void sctp_ulpq_partial_delivery(struct sctp_ulpq *ulpq,
-				struct sctp_chunk *chunk, int gfp)
+				struct sctp_chunk *chunk,
+				unsigned int __nocast gfp)
 {
 	struct sctp_ulpevent *event;
 	struct sctp_association *asoc;
@@ -802,7 +803,7 @@ void sctp_ulpq_partial_delivery(struct s
 
 /* Renege some packets to make room for an incoming chunk.  */
 void sctp_ulpq_renege(struct sctp_ulpq *ulpq, struct sctp_chunk *chunk,
-		      int gfp)
+		      unsigned int __nocast gfp)
 {
 	struct sctp_association *asoc;
 	__u16 needed, freed;
@@ -841,7 +842,7 @@ void sctp_ulpq_renege(struct sctp_ulpq *
 /* Notify the application if an association is aborted and in
  * partial delivery mode.  Send up any pending received messages.
  */
-void sctp_ulpq_abort_pd(struct sctp_ulpq *ulpq, int gfp)
+void sctp_ulpq_abort_pd(struct sctp_ulpq *ulpq, unsigned int __nocast gfp)
 {
 	struct sctp_ulpevent *ev = NULL;
 	struct sock *sk;
diff --git a/net/socket.c b/net/socket.c
--- a/net/socket.c
+++ b/net/socket.c
@@ -81,6 +81,7 @@
 #include <linux/syscalls.h>
 #include <linux/compat.h>
 #include <linux/kmod.h>
+#include <linux/audit.h>
 
 #ifdef CONFIG_NET_RADIO
 #include <linux/wireless.h>		/* Note : will define WIRELESS_EXT */
@@ -226,7 +227,7 @@ int move_addr_to_kernel(void __user *uad
 		return 0;
 	if(copy_from_user(kaddr,uaddr,ulen))
 		return -EFAULT;
-	return 0;
+	return audit_sockaddr(ulen, kaddr);
 }
 
 /**
@@ -382,9 +383,8 @@ int sock_map_fd(struct socket *sock)
 			goto out;
 		}
 
-		sprintf(name, "[%lu]", SOCK_INODE(sock)->i_ino);
+		this.len = sprintf(name, "[%lu]", SOCK_INODE(sock)->i_ino);
 		this.name = name;
-		this.len = strlen(name);
 		this.hash = SOCK_INODE(sock)->i_ino;
 
 		file->f_dentry = d_alloc(sock_mnt->mnt_sb->s_root, &this);
@@ -1906,7 +1906,11 @@ asmlinkage long sys_socketcall(int call,
 	/* copy_from_user should be SMP safe. */
 	if (copy_from_user(a, args, nargs[call]))
 		return -EFAULT;
-		
+
+	err = audit_socketcall(nargs[call]/sizeof(unsigned long), a);
+	if (err)
+		return err;
+
 	a0=a[0];
 	a1=a[1];
 	
diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c
--- a/net/sunrpc/auth.c
+++ b/net/sunrpc/auth.c
@@ -66,10 +66,10 @@ rpcauth_create(rpc_authflavor_t pseudofl
 	u32			flavor = pseudoflavor_to_flavor(pseudoflavor);
 
 	if (flavor >= RPC_AUTH_MAXFLAVOR || !(ops = auth_flavors[flavor]))
-		return NULL;
+		return ERR_PTR(-EINVAL);
 	auth = ops->create(clnt, pseudoflavor);
-	if (!auth)
-		return NULL;
+	if (IS_ERR(auth))
+		return auth;
 	if (clnt->cl_auth)
 		rpcauth_destroy(clnt->cl_auth);
 	clnt->cl_auth = auth;
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
--- a/net/sunrpc/auth_gss/auth_gss.c
+++ b/net/sunrpc/auth_gss/auth_gss.c
@@ -660,14 +660,16 @@ gss_create(struct rpc_clnt *clnt, rpc_au
 {
 	struct gss_auth *gss_auth;
 	struct rpc_auth * auth;
+	int err = -ENOMEM; /* XXX? */
 
 	dprintk("RPC:      creating GSS authenticator for client %p\n",clnt);
 
 	if (!try_module_get(THIS_MODULE))
-		return NULL;
+		return ERR_PTR(err);
 	if (!(gss_auth = kmalloc(sizeof(*gss_auth), GFP_KERNEL)))
 		goto out_dec;
 	gss_auth->client = clnt;
+	err = -EINVAL;
 	gss_auth->mech = gss_mech_get_by_pseudoflavor(flavor);
 	if (!gss_auth->mech) {
 		printk(KERN_WARNING "%s: Pseudoflavor %d not found!",
@@ -675,9 +677,8 @@ gss_create(struct rpc_clnt *clnt, rpc_au
 		goto err_free;
 	}
 	gss_auth->service = gss_pseudoflavor_to_service(gss_auth->mech, flavor);
-	/* FIXME: Will go away once privacy support is merged in */
-	if (gss_auth->service == RPC_GSS_SVC_PRIVACY)
-		gss_auth->service = RPC_GSS_SVC_INTEGRITY;
+	if (gss_auth->service == 0)
+		goto err_put_mech;
 	INIT_LIST_HEAD(&gss_auth->upcalls);
 	spin_lock_init(&gss_auth->lock);
 	auth = &gss_auth->rpc_auth;
@@ -687,15 +688,18 @@ gss_create(struct rpc_clnt *clnt, rpc_au
 	auth->au_flavor = flavor;
 	atomic_set(&auth->au_count, 1);
 
-	if (rpcauth_init_credcache(auth, GSS_CRED_EXPIRE) < 0)
+	err = rpcauth_init_credcache(auth, GSS_CRED_EXPIRE);
+	if (err)
 		goto err_put_mech;
 
 	snprintf(gss_auth->path, sizeof(gss_auth->path), "%s/%s",
 			clnt->cl_pathname,
 			gss_auth->mech->gm_name);
 	gss_auth->dentry = rpc_mkpipe(gss_auth->path, clnt, &gss_upcall_ops, RPC_PIPE_WAIT_FOR_OPEN);
-	if (IS_ERR(gss_auth->dentry))
+	if (IS_ERR(gss_auth->dentry)) {
+		err = PTR_ERR(gss_auth->dentry);
 		goto err_put_mech;
+	}
 
 	return auth;
 err_put_mech:
@@ -704,7 +708,7 @@ err_free:
 	kfree(gss_auth);
 out_dec:
 	module_put(THIS_MODULE);
-	return NULL;
+	return ERR_PTR(err);
 }
 
 static void
diff --git a/net/sunrpc/auth_gss/gss_krb5_crypto.c b/net/sunrpc/auth_gss/gss_krb5_crypto.c
--- a/net/sunrpc/auth_gss/gss_krb5_crypto.c
+++ b/net/sunrpc/auth_gss/gss_krb5_crypto.c
@@ -185,9 +185,7 @@ make_checksum(s32 cksumtype, char *heade
 			sg->page = body->pages[i];
 			sg->offset = offset;
 			sg->length = thislen;
-			kmap(sg->page); /* XXX kmap_atomic? */
 			crypto_digest_update(tfm, sg, 1);
-			kunmap(sg->page);
 			len -= thislen;
 			i++;
 			offset = 0;
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -97,12 +97,13 @@ rpc_setup_pipedir(struct rpc_clnt *clnt,
  * made to sleep too long.
  */
 struct rpc_clnt *
-rpc_create_client(struct rpc_xprt *xprt, char *servname,
+rpc_new_client(struct rpc_xprt *xprt, char *servname,
 		  struct rpc_program *program, u32 vers,
 		  rpc_authflavor_t flavor)
 {
 	struct rpc_version	*version;
 	struct rpc_clnt		*clnt = NULL;
+	struct rpc_auth		*auth;
 	int err;
 	int len;
 
@@ -157,10 +158,11 @@ rpc_create_client(struct rpc_xprt *xprt,
 	if (err < 0)
 		goto out_no_path;
 
-	err = -ENOMEM;
-	if (!rpcauth_create(flavor, clnt)) {
+	auth = rpcauth_create(flavor, clnt);
+	if (IS_ERR(auth)) {
 		printk(KERN_INFO "RPC: Couldn't create auth handle (flavor %u)\n",
 				flavor);
+		err = PTR_ERR(auth);
 		goto out_no_auth;
 	}
 
@@ -178,6 +180,37 @@ out_no_path:
 		kfree(clnt->cl_server);
 	kfree(clnt);
 out_err:
+	xprt_destroy(xprt);
+	return ERR_PTR(err);
+}
+
+/**
+ * Create an RPC client
+ * @xprt - pointer to xprt struct
+ * @servname - name of server
+ * @info - rpc_program
+ * @version - rpc_program version
+ * @authflavor - rpc_auth flavour to use
+ *
+ * Creates an RPC client structure, then pings the server in order to
+ * determine if it is up, and if it supports this program and version.
+ *
+ * This function should never be called by asynchronous tasks such as
+ * the portmapper.
+ */
+struct rpc_clnt *rpc_create_client(struct rpc_xprt *xprt, char *servname,
+		struct rpc_program *info, u32 version, rpc_authflavor_t authflavor)
+{
+	struct rpc_clnt *clnt;
+	int err;
+	
+	clnt = rpc_new_client(xprt, servname, info, version, authflavor);
+	if (IS_ERR(clnt))
+		return clnt;
+	err = rpc_ping(clnt, RPC_TASK_SOFT|RPC_TASK_NOINTR);
+	if (err == 0)
+		return clnt;
+	rpc_shutdown_client(clnt);
 	return ERR_PTR(err);
 }
 
@@ -208,6 +241,8 @@ rpc_clone_client(struct rpc_clnt *clnt)
 	rpc_init_rtt(&new->cl_rtt_default, clnt->cl_xprt->timeout.to_initval);
 	if (new->cl_auth)
 		atomic_inc(&new->cl_auth->au_count);
+	new->cl_pmap		= &new->cl_pmap_default;
+	rpc_init_wait_queue(&new->cl_pmap_default.pm_bindwait, "bindwait");
 	return new;
 out_no_clnt:
 	printk(KERN_INFO "RPC: out of memory in %s\n", __FUNCTION__);
@@ -296,6 +331,44 @@ rpc_release_client(struct rpc_clnt *clnt
 		rpc_destroy_client(clnt);
 }
 
+/**
+ * rpc_bind_new_program - bind a new RPC program to an existing client
+ * @old - old rpc_client
+ * @program - rpc program to set
+ * @vers - rpc program version
+ *
+ * Clones the rpc client and sets up a new RPC program. This is mainly
+ * of use for enabling different RPC programs to share the same transport.
+ * The Sun NFSv2/v3 ACL protocol can do this.
+ */
+struct rpc_clnt *rpc_bind_new_program(struct rpc_clnt *old,
+				      struct rpc_program *program,
+				      int vers)
+{
+	struct rpc_clnt *clnt;
+	struct rpc_version *version;
+	int err;
+
+	BUG_ON(vers >= program->nrvers || !program->version[vers]);
+	version = program->version[vers];
+	clnt = rpc_clone_client(old);
+	if (IS_ERR(clnt))
+		goto out;
+	clnt->cl_procinfo = version->procs;
+	clnt->cl_maxproc  = version->nrprocs;
+	clnt->cl_protname = program->name;
+	clnt->cl_prog     = program->number;
+	clnt->cl_vers     = version->number;
+	clnt->cl_stats    = program->stats;
+	err = rpc_ping(clnt, RPC_TASK_SOFT|RPC_TASK_NOINTR);
+	if (err != 0) {
+		rpc_shutdown_client(clnt);
+		clnt = ERR_PTR(err);
+	}
+out:	
+	return clnt;
+}
+
 /*
  * Default callback for async RPC calls
  */
@@ -305,38 +378,41 @@ rpc_default_callback(struct rpc_task *ta
 }
 
 /*
- *	Export the signal mask handling for aysnchronous code that
+ *	Export the signal mask handling for synchronous code that
  *	sleeps on RPC calls
  */
+#define RPC_INTR_SIGNALS (sigmask(SIGINT) | sigmask(SIGQUIT) | sigmask(SIGKILL))
  
+static void rpc_save_sigmask(sigset_t *oldset, int intr)
+{
+	unsigned long	sigallow = 0;
+	sigset_t sigmask;
+
+	/* Block all signals except those listed in sigallow */
+	if (intr)
+		sigallow |= RPC_INTR_SIGNALS;
+	siginitsetinv(&sigmask, sigallow);
+	sigprocmask(SIG_BLOCK, &sigmask, oldset);
+}
+
+static inline void rpc_task_sigmask(struct rpc_task *task, sigset_t *oldset)
+{
+	rpc_save_sigmask(oldset, !RPC_TASK_UNINTERRUPTIBLE(task));
+}
+
+static inline void rpc_restore_sigmask(sigset_t *oldset)
+{
+	sigprocmask(SIG_SETMASK, oldset, NULL);
+}
+
 void rpc_clnt_sigmask(struct rpc_clnt *clnt, sigset_t *oldset)
 {
-	unsigned long	sigallow = sigmask(SIGKILL);
-	unsigned long	irqflags;
-	
-	/* Turn off various signals */
-	if (clnt->cl_intr) {
-		struct k_sigaction *action = current->sighand->action;
-		if (action[SIGINT-1].sa.sa_handler == SIG_DFL)
-			sigallow |= sigmask(SIGINT);
-		if (action[SIGQUIT-1].sa.sa_handler == SIG_DFL)
-			sigallow |= sigmask(SIGQUIT);
-	}
-	spin_lock_irqsave(&current->sighand->siglock, irqflags);
-	*oldset = current->blocked;
-	siginitsetinv(&current->blocked, sigallow & ~oldset->sig[0]);
-	recalc_sigpending();
-	spin_unlock_irqrestore(&current->sighand->siglock, irqflags);
+	rpc_save_sigmask(oldset, clnt->cl_intr);
 }
 
 void rpc_clnt_sigunmask(struct rpc_clnt *clnt, sigset_t *oldset)
 {
-	unsigned long	irqflags;
-	
-	spin_lock_irqsave(&current->sighand->siglock, irqflags);
-	current->blocked = *oldset;
-	recalc_sigpending();
-	spin_unlock_irqrestore(&current->sighand->siglock, irqflags);
+	rpc_restore_sigmask(oldset);
 }
 
 /*
@@ -354,26 +430,26 @@ int rpc_call_sync(struct rpc_clnt *clnt,
 
 	BUG_ON(flags & RPC_TASK_ASYNC);
 
-	rpc_clnt_sigmask(clnt, &oldset);		
-
 	status = -ENOMEM;
 	task = rpc_new_task(clnt, NULL, flags);
 	if (task == NULL)
 		goto out;
 
+	/* Mask signals on RPC calls _and_ GSS_AUTH upcalls */
+	rpc_task_sigmask(task, &oldset);
+
 	rpc_call_setup(task, msg, 0);
 
 	/* Set up the call info struct and execute the task */
-	if (task->tk_status == 0)
+	if (task->tk_status == 0) {
 		status = rpc_execute(task);
-	else {
+	} else {
 		status = task->tk_status;
 		rpc_release_task(task);
 	}
 
+	rpc_restore_sigmask(&oldset);
 out:
-	rpc_clnt_sigunmask(clnt, &oldset);		
-
 	return status;
 }
 
@@ -394,8 +470,6 @@ rpc_call_async(struct rpc_clnt *clnt, st
 
 	flags |= RPC_TASK_ASYNC;
 
-	rpc_clnt_sigmask(clnt, &oldset);		
-
 	/* Create/initialize a new RPC task */
 	if (!callback)
 		callback = rpc_default_callback;
@@ -404,6 +478,9 @@ rpc_call_async(struct rpc_clnt *clnt, st
 		goto out;
 	task->tk_calldata = data;
 
+	/* Mask signals on GSS_AUTH upcalls */
+	rpc_task_sigmask(task, &oldset);		
+
 	rpc_call_setup(task, msg, 0);
 
 	/* Set up the call info struct and execute the task */
@@ -413,9 +490,8 @@ rpc_call_async(struct rpc_clnt *clnt, st
 	else
 		rpc_release_task(task);
 
+	rpc_restore_sigmask(&oldset);		
 out:
-	rpc_clnt_sigunmask(clnt, &oldset);		
-
 	return status;
 }
 
@@ -593,7 +669,7 @@ call_allocate(struct rpc_task *task)
 		return;
 	printk(KERN_INFO "RPC: buffer allocation failed for task %p\n", task); 
 
-	if (RPC_IS_ASYNC(task) || !(task->tk_client->cl_intr && signalled())) {
+	if (RPC_IS_ASYNC(task) || !signalled()) {
 		xprt_release(task);
 		task->tk_action = call_reserve;
 		rpc_delay(task, HZ>>4);
@@ -957,7 +1033,9 @@ call_header(struct rpc_task *task)
 	*p++ = htonl(clnt->cl_prog);	/* program number */
 	*p++ = htonl(clnt->cl_vers);	/* program version */
 	*p++ = htonl(task->tk_msg.rpc_proc->p_proc);	/* procedure */
-	return rpcauth_marshcred(task, p);
+	p = rpcauth_marshcred(task, p);
+	req->rq_slen = xdr_adjust_iovec(&req->rq_svec[0], p);
+	return p;
 }
 
 /*
@@ -986,10 +1064,11 @@ call_verify(struct rpc_task *task)
 			case RPC_AUTH_ERROR:
 				break;
 			case RPC_MISMATCH:
-				printk(KERN_WARNING "%s: RPC call version mismatch!\n", __FUNCTION__);
-				goto out_eio;
+				dprintk("%s: RPC call version mismatch!\n", __FUNCTION__);
+				error = -EPROTONOSUPPORT;
+				goto out_err;
 			default:
-				printk(KERN_WARNING "%s: RPC call rejected, unknown error: %x\n", __FUNCTION__, n);
+				dprintk("%s: RPC call rejected, unknown error: %x\n", __FUNCTION__, n);
 				goto out_eio;
 		}
 		if (--len < 0)
@@ -1040,23 +1119,26 @@ call_verify(struct rpc_task *task)
 	case RPC_SUCCESS:
 		return p;
 	case RPC_PROG_UNAVAIL:
-		printk(KERN_WARNING "RPC: call_verify: program %u is unsupported by server %s\n",
+		dprintk("RPC: call_verify: program %u is unsupported by server %s\n",
 				(unsigned int)task->tk_client->cl_prog,
 				task->tk_client->cl_server);
-		goto out_eio;
+		error = -EPFNOSUPPORT;
+		goto out_err;
 	case RPC_PROG_MISMATCH:
-		printk(KERN_WARNING "RPC: call_verify: program %u, version %u unsupported by server %s\n",
+		dprintk("RPC: call_verify: program %u, version %u unsupported by server %s\n",
 				(unsigned int)task->tk_client->cl_prog,
 				(unsigned int)task->tk_client->cl_vers,
 				task->tk_client->cl_server);
-		goto out_eio;
+		error = -EPROTONOSUPPORT;
+		goto out_err;
 	case RPC_PROC_UNAVAIL:
-		printk(KERN_WARNING "RPC: call_verify: proc %p unsupported by program %u, version %u on server %s\n",
+		dprintk("RPC: call_verify: proc %p unsupported by program %u, version %u on server %s\n",
 				task->tk_msg.rpc_proc,
 				task->tk_client->cl_prog,
 				task->tk_client->cl_vers,
 				task->tk_client->cl_server);
-		goto out_eio;
+		error = -EOPNOTSUPP;
+		goto out_err;
 	case RPC_GARBAGE_ARGS:
 		dprintk("RPC: %4d %s: server saw garbage\n", task->tk_pid, __FUNCTION__);
 		break;			/* retry */
@@ -1069,7 +1151,7 @@ out_retry:
 	task->tk_client->cl_stats->rpcgarbage++;
 	if (task->tk_garb_retry) {
 		task->tk_garb_retry--;
-		dprintk(KERN_WARNING "RPC %s: retrying %4d\n", __FUNCTION__, task->tk_pid);
+		dprintk("RPC %s: retrying %4d\n", __FUNCTION__, task->tk_pid);
 		task->tk_action = call_bind;
 		return NULL;
 	}
@@ -1083,3 +1165,30 @@ out_overflow:
 	printk(KERN_WARNING "RPC %s: server reply was truncated.\n", __FUNCTION__);
 	goto out_retry;
 }
+
+static int rpcproc_encode_null(void *rqstp, u32 *data, void *obj)
+{
+	return 0;
+}
+
+static int rpcproc_decode_null(void *rqstp, u32 *data, void *obj)
+{
+	return 0;
+}
+
+static struct rpc_procinfo rpcproc_null = {
+	.p_encode = rpcproc_encode_null,
+	.p_decode = rpcproc_decode_null,
+};
+
+int rpc_ping(struct rpc_clnt *clnt, int flags)
+{
+	struct rpc_message msg = {
+		.rpc_proc = &rpcproc_null,
+	};
+	int err;
+	msg.rpc_cred = authnull_ops.lookup_cred(NULL, NULL, 0);
+	err = rpc_call_sync(clnt, &msg, flags);
+	put_rpccred(msg.rpc_cred);
+	return err;
+}
diff --git a/net/sunrpc/pmap_clnt.c b/net/sunrpc/pmap_clnt.c
--- a/net/sunrpc/pmap_clnt.c
+++ b/net/sunrpc/pmap_clnt.c
@@ -53,6 +53,9 @@ rpc_getport(struct rpc_task *task, struc
 			task->tk_pid, clnt->cl_server,
 			map->pm_prog, map->pm_vers, map->pm_prot);
 
+	/* Autobind on cloned rpc clients is discouraged */
+	BUG_ON(clnt->cl_parent != clnt);
+
 	spin_lock(&pmap_lock);
 	if (map->pm_binding) {
 		rpc_sleep_on(&map->pm_bindwait, task, NULL, NULL);
@@ -207,12 +210,10 @@ pmap_create(char *hostname, struct socka
 	xprt->addr.sin_port = htons(RPC_PMAP_PORT);
 
 	/* printk("pmap: create clnt\n"); */
-	clnt = rpc_create_client(xprt, hostname,
+	clnt = rpc_new_client(xprt, hostname,
 				&pmap_program, RPC_PMAP_VERSION,
 				RPC_AUTH_UNIX);
-	if (IS_ERR(clnt)) {
-		xprt_destroy(xprt);
-	} else {
+	if (!IS_ERR(clnt)) {
 		clnt->cl_softrtry = 1;
 		clnt->cl_chatty   = 1;
 		clnt->cl_oneshot  = 1;
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
--- a/net/sunrpc/sched.c
+++ b/net/sunrpc/sched.c
@@ -290,7 +290,7 @@ static void rpc_make_runnable(struct rpc
 			return;
 		}
 	} else
-		wake_up(&task->u.tk_wait.waitq);
+		wake_up_bit(&task->tk_runstate, RPC_TASK_QUEUED);
 }
 
 /*
@@ -555,6 +555,38 @@ __rpc_atrun(struct rpc_task *task)
 }
 
 /*
+ * Helper that calls task->tk_exit if it exists and then returns
+ * true if we should exit __rpc_execute.
+ */
+static inline int __rpc_do_exit(struct rpc_task *task)
+{
+	if (task->tk_exit != NULL) {
+		lock_kernel();
+		task->tk_exit(task);
+		unlock_kernel();
+		/* If tk_action is non-null, we should restart the call */
+		if (task->tk_action != NULL) {
+			if (!RPC_ASSASSINATED(task)) {
+				/* Release RPC slot and buffer memory */
+				xprt_release(task);
+				rpc_free(task);
+				return 0;
+			}
+			printk(KERN_ERR "RPC: dead task tried to walk away.\n");
+		}
+	}
+	return 1;
+}
+
+static int rpc_wait_bit_interruptible(void *word)
+{
+	if (signal_pending(current))
+		return -ERESTARTSYS;
+	schedule();
+	return 0;
+}
+
+/*
  * This is the RPC `scheduler' (or rather, the finite state machine).
  */
 static int __rpc_execute(struct rpc_task *task)
@@ -566,8 +598,7 @@ static int __rpc_execute(struct rpc_task
 
 	BUG_ON(RPC_IS_QUEUED(task));
 
- restarted:
-	while (1) {
+	for (;;) {
 		/*
 		 * Garbage collection of pending timers...
 		 */
@@ -600,11 +631,12 @@ static int __rpc_execute(struct rpc_task
 		 * by someone else.
 		 */
 		if (!RPC_IS_QUEUED(task)) {
-			if (!task->tk_action)
+			if (task->tk_action != NULL) {
+				lock_kernel();
+				task->tk_action(task);
+				unlock_kernel();
+			} else if (__rpc_do_exit(task))
 				break;
-			lock_kernel();
-			task->tk_action(task);
-			unlock_kernel();
 		}
 
 		/*
@@ -624,44 +656,26 @@ static int __rpc_execute(struct rpc_task
 
 		/* sync task: sleep here */
 		dprintk("RPC: %4d sync task going to sleep\n", task->tk_pid);
-		if (RPC_TASK_UNINTERRUPTIBLE(task)) {
-			__wait_event(task->u.tk_wait.waitq, !RPC_IS_QUEUED(task));
-		} else {
-			__wait_event_interruptible(task->u.tk_wait.waitq, !RPC_IS_QUEUED(task), status);
+		/* Note: Caller should be using rpc_clnt_sigmask() */
+		status = out_of_line_wait_on_bit(&task->tk_runstate,
+				RPC_TASK_QUEUED, rpc_wait_bit_interruptible,
+				TASK_INTERRUPTIBLE);
+		if (status == -ERESTARTSYS) {
 			/*
 			 * When a sync task receives a signal, it exits with
 			 * -ERESTARTSYS. In order to catch any callbacks that
 			 * clean up after sleeping on some queue, we don't
 			 * break the loop here, but go around once more.
 			 */
-			if (status == -ERESTARTSYS) {
-				dprintk("RPC: %4d got signal\n", task->tk_pid);
-				task->tk_flags |= RPC_TASK_KILLED;
-				rpc_exit(task, -ERESTARTSYS);
-				rpc_wake_up_task(task);
-			}
+			dprintk("RPC: %4d got signal\n", task->tk_pid);
+			task->tk_flags |= RPC_TASK_KILLED;
+			rpc_exit(task, -ERESTARTSYS);
+			rpc_wake_up_task(task);
 		}
 		rpc_set_running(task);
 		dprintk("RPC: %4d sync task resuming\n", task->tk_pid);
 	}
 
-	if (task->tk_exit) {
-		lock_kernel();
-		task->tk_exit(task);
-		unlock_kernel();
-		/* If tk_action is non-null, the user wants us to restart */
-		if (task->tk_action) {
-			if (!RPC_ASSASSINATED(task)) {
-				/* Release RPC slot and buffer memory */
-				if (task->tk_rqstp)
-					xprt_release(task);
-				rpc_free(task);
-				goto restarted;
-			}
-			printk(KERN_ERR "RPC: dead task tries to walk away.\n");
-		}
-	}
-
 	dprintk("RPC: %4d exit() = %d\n", task->tk_pid, task->tk_status);
 	status = task->tk_status;
 
@@ -759,8 +773,6 @@ void rpc_init_task(struct rpc_task *task
 
 	/* Initialize workqueue for async tasks */
 	task->tk_workqueue = rpciod_workqueue;
-	if (!RPC_IS_ASYNC(task))
-		init_waitqueue_head(&task->u.tk_wait.waitq);
 
 	if (clnt) {
 		atomic_inc(&clnt->cl_users);
diff --git a/net/sunrpc/sunrpc_syms.c b/net/sunrpc/sunrpc_syms.c
--- a/net/sunrpc/sunrpc_syms.c
+++ b/net/sunrpc/sunrpc_syms.c
@@ -41,7 +41,9 @@ EXPORT_SYMBOL(rpc_release_task);
 
 /* RPC client functions */
 EXPORT_SYMBOL(rpc_create_client);
+EXPORT_SYMBOL(rpc_new_client);
 EXPORT_SYMBOL(rpc_clone_client);
+EXPORT_SYMBOL(rpc_bind_new_program);
 EXPORT_SYMBOL(rpc_destroy_client);
 EXPORT_SYMBOL(rpc_shutdown_client);
 EXPORT_SYMBOL(rpc_release_client);
@@ -61,7 +63,6 @@ EXPORT_SYMBOL(rpc_mkpipe);
 
 /* Client transport */
 EXPORT_SYMBOL(xprt_create_proto);
-EXPORT_SYMBOL(xprt_destroy);
 EXPORT_SYMBOL(xprt_set_timeout);
 EXPORT_SYMBOL(xprt_udp_slot_table_entries);
 EXPORT_SYMBOL(xprt_tcp_slot_table_entries);
@@ -129,6 +130,10 @@ EXPORT_SYMBOL(xdr_encode_netobj);
 EXPORT_SYMBOL(xdr_encode_pages);
 EXPORT_SYMBOL(xdr_inline_pages);
 EXPORT_SYMBOL(xdr_shift_buf);
+EXPORT_SYMBOL(xdr_encode_word);
+EXPORT_SYMBOL(xdr_decode_word);
+EXPORT_SYMBOL(xdr_encode_array2);
+EXPORT_SYMBOL(xdr_decode_array2);
 EXPORT_SYMBOL(xdr_buf_from_iov);
 EXPORT_SYMBOL(xdr_buf_subsegment);
 EXPORT_SYMBOL(xdr_buf_read_netobj);
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -35,20 +35,24 @@ svc_create(struct svc_program *prog, uns
 	if (!(serv = (struct svc_serv *) kmalloc(sizeof(*serv), GFP_KERNEL)))
 		return NULL;
 	memset(serv, 0, sizeof(*serv));
+	serv->sv_name      = prog->pg_name;
 	serv->sv_program   = prog;
 	serv->sv_nrthreads = 1;
 	serv->sv_stats     = prog->pg_stats;
 	serv->sv_bufsz	   = bufsize? bufsize : 4096;
-	prog->pg_lovers = prog->pg_nvers-1;
 	xdrsize = 0;
-	for (vers=0; vers<prog->pg_nvers ; vers++)
-		if (prog->pg_vers[vers]) {
-			prog->pg_hivers = vers;
-			if (prog->pg_lovers > vers)
-				prog->pg_lovers = vers;
-			if (prog->pg_vers[vers]->vs_xdrsize > xdrsize)
-				xdrsize = prog->pg_vers[vers]->vs_xdrsize;
-		}
+	while (prog) {
+		prog->pg_lovers = prog->pg_nvers-1;
+		for (vers=0; vers<prog->pg_nvers ; vers++)
+			if (prog->pg_vers[vers]) {
+				prog->pg_hivers = vers;
+				if (prog->pg_lovers > vers)
+					prog->pg_lovers = vers;
+				if (prog->pg_vers[vers]->vs_xdrsize > xdrsize)
+					xdrsize = prog->pg_vers[vers]->vs_xdrsize;
+			}
+		prog = prog->pg_next;
+	}
 	serv->sv_xdrsize   = xdrsize;
 	INIT_LIST_HEAD(&serv->sv_threads);
 	INIT_LIST_HEAD(&serv->sv_sockets);
@@ -56,8 +60,6 @@ svc_create(struct svc_program *prog, uns
 	INIT_LIST_HEAD(&serv->sv_permsocks);
 	spin_lock_init(&serv->sv_lock);
 
-	serv->sv_name      = prog->pg_name;
-
 	/* Remove any stale portmap registrations */
 	svc_register(serv, 0, 0);
 
@@ -281,6 +283,7 @@ svc_process(struct svc_serv *serv, struc
 	rqstp->rq_res.len = 0;
 	rqstp->rq_res.page_base = 0;
 	rqstp->rq_res.page_len = 0;
+	rqstp->rq_res.buflen = PAGE_SIZE;
 	rqstp->rq_res.tail[0].iov_len = 0;
 	/* tcp needs a space for the record length... */
 	if (rqstp->rq_prot == IPPROTO_TCP)
@@ -338,7 +341,10 @@ svc_process(struct svc_serv *serv, struc
 		goto sendit;
 	}
 		
-	if (prog != progp->pg_prog)
+	for (progp = serv->sv_program; progp; progp = progp->pg_next)
+		if (prog == progp->pg_prog)
+			break;
+	if (progp == NULL)
 		goto err_bad_prog;
 
 	if (vers >= progp->pg_nvers ||
@@ -451,11 +457,7 @@ err_bad_auth:
 	goto sendit;
 
 err_bad_prog:
-#ifdef RPC_PARANOIA
-	if (prog != 100227 || progp->pg_prog != 100003)
-		printk("svc: unknown program %d (me %d)\n", prog, progp->pg_prog);
-	/* else it is just a Solaris client seeing if ACLs are supported */
-#endif
+	dprintk("svc: unknown program %d\n", prog);
 	serv->sv_stats->rpcbadfmt++;
 	svc_putu32(resv, rpc_prog_unavail);
 	goto sendit;
diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c
--- a/net/sunrpc/svcauth_unix.c
+++ b/net/sunrpc/svcauth_unix.c
@@ -8,6 +8,7 @@
 #include <linux/err.h>
 #include <linux/seq_file.h>
 #include <linux/hash.h>
+#include <linux/string.h>
 
 #define RPCDBG_FACILITY	RPCDBG_AUTH
 
@@ -20,14 +21,6 @@
  */
 
 
-static char *strdup(char *s)
-{
-	char *rv = kmalloc(strlen(s)+1, GFP_KERNEL);
-	if (rv)
-		strcpy(rv, s);
-	return rv;
-}
-
 struct unix_domain {
 	struct auth_domain	h;
 	int	addr_changes;
@@ -55,7 +48,7 @@ struct auth_domain *unix_domain_find(cha
 	if (new == NULL)
 		return NULL;
 	cache_init(&new->h.h);
-	new->h.name = strdup(name);
+	new->h.name = kstrdup(name, GFP_KERNEL);
 	new->h.flavour = RPC_AUTH_UNIX;
 	new->addr_changes = 0;
 	new->h.h.expiry_time = NEVER;
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -586,7 +586,7 @@ svc_udp_recvfrom(struct svc_rqst *rqstp)
 	}
 	if (skb->stamp.tv_sec == 0) {
 		skb->stamp.tv_sec = xtime.tv_sec; 
-		skb->stamp.tv_usec = xtime.tv_nsec * 1000; 
+		skb->stamp.tv_usec = xtime.tv_nsec / NSEC_PER_USEC; 
 		/* Don't enable netstamp, sunrpc doesn't 
 		   need that much accuracy */
 	}
@@ -1185,8 +1185,8 @@ svc_recv(struct svc_serv *serv, struct s
 	arg->page_len = (pages-2)*PAGE_SIZE;
 	arg->len = (pages-1)*PAGE_SIZE;
 	arg->tail[0].iov_len = 0;
-	
-	try_to_freeze(PF_FREEZE);
+
+	try_to_freeze();
 	if (signalled())
 		return -EINTR;
 
@@ -1227,7 +1227,7 @@ svc_recv(struct svc_serv *serv, struct s
 
 		schedule_timeout(timeout);
 
-		try_to_freeze(PF_FREEZE);
+		try_to_freeze();
 
 		spin_lock_bh(&serv->sv_lock);
 		remove_wait_queue(&rqstp->rq_wait, &wait);
diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c
--- a/net/sunrpc/xdr.c
+++ b/net/sunrpc/xdr.c
@@ -176,21 +176,23 @@ xdr_inline_pages(struct xdr_buf *xdr, un
 	xdr->buflen += len;
 }
 
-void
+ssize_t
 xdr_partial_copy_from_skb(struct xdr_buf *xdr, unsigned int base,
 			  skb_reader_t *desc,
 			  skb_read_actor_t copy_actor)
 {
 	struct page	**ppage = xdr->pages;
 	unsigned int	len, pglen = xdr->page_len;
+	ssize_t		copied = 0;
 	int		ret;
 
 	len = xdr->head[0].iov_len;
 	if (base < len) {
 		len -= base;
 		ret = copy_actor(desc, (char *)xdr->head[0].iov_base + base, len);
+		copied += ret;
 		if (ret != len || !desc->count)
-			return;
+			goto out;
 		base = 0;
 	} else
 		base -= len;
@@ -210,6 +212,17 @@ xdr_partial_copy_from_skb(struct xdr_buf
 	do {
 		char *kaddr;
 
+		/* ACL likes to be lazy in allocating pages - ACLs
+		 * are small by default but can get huge. */
+		if (unlikely(*ppage == NULL)) {
+			*ppage = alloc_page(GFP_ATOMIC);
+			if (unlikely(*ppage == NULL)) {
+				if (copied == 0)
+					copied = -ENOMEM;
+				goto out;
+			}
+		}
+
 		len = PAGE_CACHE_SIZE;
 		kaddr = kmap_atomic(*ppage, KM_SKB_SUNRPC_DATA);
 		if (base) {
@@ -225,14 +238,17 @@ xdr_partial_copy_from_skb(struct xdr_buf
 		}
 		flush_dcache_page(*ppage);
 		kunmap_atomic(kaddr, KM_SKB_SUNRPC_DATA);
+		copied += ret;
 		if (ret != len || !desc->count)
-			return;
+			goto out;
 		ppage++;
 	} while ((pglen -= len) != 0);
 copy_tail:
 	len = xdr->tail[0].iov_len;
 	if (base < len)
-		copy_actor(desc, (char *)xdr->tail[0].iov_base + base, len - base);
+		copied += copy_actor(desc, (char *)xdr->tail[0].iov_base + base, len - base);
+out:
+	return copied;
 }
 
 
@@ -616,12 +632,24 @@ xdr_shift_buf(struct xdr_buf *buf, size_
 void xdr_init_encode(struct xdr_stream *xdr, struct xdr_buf *buf, uint32_t *p)
 {
 	struct kvec *iov = buf->head;
+	int scratch_len = buf->buflen - buf->page_len - buf->tail[0].iov_len;
 
+	BUG_ON(scratch_len < 0);
 	xdr->buf = buf;
 	xdr->iov = iov;
-	xdr->end = (uint32_t *)((char *)iov->iov_base + iov->iov_len);
-	buf->len = iov->iov_len = (char *)p - (char *)iov->iov_base;
-	xdr->p = p;
+	xdr->p = (uint32_t *)((char *)iov->iov_base + iov->iov_len);
+	xdr->end = (uint32_t *)((char *)iov->iov_base + scratch_len);
+	BUG_ON(iov->iov_len > scratch_len);
+
+	if (p != xdr->p && p != NULL) {
+		size_t len;
+
+		BUG_ON(p < xdr->p || p > xdr->end);
+		len = (char *)p - (char *)xdr->p;
+		xdr->p = p;
+		buf->len += len;
+		iov->iov_len += len;
+	}
 }
 EXPORT_SYMBOL(xdr_init_encode);
 
@@ -859,8 +887,34 @@ out:
 	return status;
 }
 
-static int
-read_u32_from_xdr_buf(struct xdr_buf *buf, int base, u32 *obj)
+/* obj is assumed to point to allocated memory of size at least len: */
+int
+write_bytes_to_xdr_buf(struct xdr_buf *buf, int base, void *obj, int len)
+{
+	struct xdr_buf subbuf;
+	int this_len;
+	int status;
+
+	status = xdr_buf_subsegment(buf, &subbuf, base, len);
+	if (status)
+		goto out;
+	this_len = min(len, (int)subbuf.head[0].iov_len);
+	memcpy(subbuf.head[0].iov_base, obj, this_len);
+	len -= this_len;
+	obj += this_len;
+	this_len = min(len, (int)subbuf.page_len);
+	if (this_len)
+		_copy_to_pages(subbuf.pages, subbuf.page_base, obj, this_len);
+	len -= this_len;
+	obj += this_len;
+	this_len = min(len, (int)subbuf.tail[0].iov_len);
+	memcpy(subbuf.tail[0].iov_base, obj, this_len);
+out:
+	return status;
+}
+
+int
+xdr_decode_word(struct xdr_buf *buf, int base, u32 *obj)
 {
 	u32	raw;
 	int	status;
@@ -872,6 +926,14 @@ read_u32_from_xdr_buf(struct xdr_buf *bu
 	return 0;
 }
 
+int
+xdr_encode_word(struct xdr_buf *buf, int base, u32 obj)
+{
+	u32	raw = htonl(obj);
+
+	return write_bytes_to_xdr_buf(buf, base, &raw, sizeof(obj));
+}
+
 /* If the netobj starting offset bytes from the start of xdr_buf is contained
  * entirely in the head or the tail, set object to point to it; otherwise
  * try to find space for it at the end of the tail, copy it there, and
@@ -882,7 +944,7 @@ xdr_buf_read_netobj(struct xdr_buf *buf,
 	u32	tail_offset = buf->head[0].iov_len + buf->page_len;
 	u32	obj_end_offset;
 
-	if (read_u32_from_xdr_buf(buf, offset, &obj->len))
+	if (xdr_decode_word(buf, offset, &obj->len))
 		goto out;
 	obj_end_offset = offset + 4 + obj->len;
 
@@ -915,3 +977,220 @@ xdr_buf_read_netobj(struct xdr_buf *buf,
 out:
 	return -1;
 }
+
+/* Returns 0 on success, or else a negative error code. */
+static int
+xdr_xcode_array2(struct xdr_buf *buf, unsigned int base,
+		 struct xdr_array2_desc *desc, int encode)
+{
+	char *elem = NULL, *c;
+	unsigned int copied = 0, todo, avail_here;
+	struct page **ppages = NULL;
+	int err;
+
+	if (encode) {
+		if (xdr_encode_word(buf, base, desc->array_len) != 0)
+			return -EINVAL;
+	} else {
+		if (xdr_decode_word(buf, base, &desc->array_len) != 0 ||
+		    desc->array_len > desc->array_maxlen ||
+		    (unsigned long) base + 4 + desc->array_len *
+				    desc->elem_size > buf->len)
+			return -EINVAL;
+	}
+	base += 4;
+
+	if (!desc->xcode)
+		return 0;
+
+	todo = desc->array_len * desc->elem_size;
+
+	/* process head */
+	if (todo && base < buf->head->iov_len) {
+		c = buf->head->iov_base + base;
+		avail_here = min_t(unsigned int, todo,
+				   buf->head->iov_len - base);
+		todo -= avail_here;
+
+		while (avail_here >= desc->elem_size) {
+			err = desc->xcode(desc, c);
+			if (err)
+				goto out;
+			c += desc->elem_size;
+			avail_here -= desc->elem_size;
+		}
+		if (avail_here) {
+			if (!elem) {
+				elem = kmalloc(desc->elem_size, GFP_KERNEL);
+				err = -ENOMEM;
+				if (!elem)
+					goto out;
+			}
+			if (encode) {
+				err = desc->xcode(desc, elem);
+				if (err)
+					goto out;
+				memcpy(c, elem, avail_here);
+			} else
+				memcpy(elem, c, avail_here);
+			copied = avail_here;
+		}
+		base = buf->head->iov_len;  /* align to start of pages */
+	}
+
+	/* process pages array */
+	base -= buf->head->iov_len;
+	if (todo && base < buf->page_len) {
+		unsigned int avail_page;
+
+		avail_here = min(todo, buf->page_len - base);
+		todo -= avail_here;
+
+		base += buf->page_base;
+		ppages = buf->pages + (base >> PAGE_CACHE_SHIFT);
+		base &= ~PAGE_CACHE_MASK;
+		avail_page = min_t(unsigned int, PAGE_CACHE_SIZE - base,
+					avail_here);
+		c = kmap(*ppages) + base;
+
+		while (avail_here) {
+			avail_here -= avail_page;
+			if (copied || avail_page < desc->elem_size) {
+				unsigned int l = min(avail_page,
+					desc->elem_size - copied);
+				if (!elem) {
+					elem = kmalloc(desc->elem_size,
+						       GFP_KERNEL);
+					err = -ENOMEM;
+					if (!elem)
+						goto out;
+				}
+				if (encode) {
+					if (!copied) {
+						err = desc->xcode(desc, elem);
+						if (err)
+							goto out;
+					}
+					memcpy(c, elem + copied, l);
+					copied += l;
+					if (copied == desc->elem_size)
+						copied = 0;
+				} else {
+					memcpy(elem + copied, c, l);
+					copied += l;
+					if (copied == desc->elem_size) {
+						err = desc->xcode(desc, elem);
+						if (err)
+							goto out;
+						copied = 0;
+					}
+				}
+				avail_page -= l;
+				c += l;
+			}
+			while (avail_page >= desc->elem_size) {
+				err = desc->xcode(desc, c);
+				if (err)
+					goto out;
+				c += desc->elem_size;
+				avail_page -= desc->elem_size;
+			}
+			if (avail_page) {
+				unsigned int l = min(avail_page,
+					    desc->elem_size - copied);
+				if (!elem) {
+					elem = kmalloc(desc->elem_size,
+						       GFP_KERNEL);
+					err = -ENOMEM;
+					if (!elem)
+						goto out;
+				}
+				if (encode) {
+					if (!copied) {
+						err = desc->xcode(desc, elem);
+						if (err)
+							goto out;
+					}
+					memcpy(c, elem + copied, l);
+					copied += l;
+					if (copied == desc->elem_size)
+						copied = 0;
+				} else {
+					memcpy(elem + copied, c, l);
+					copied += l;
+					if (copied == desc->elem_size) {
+						err = desc->xcode(desc, elem);
+						if (err)
+							goto out;
+						copied = 0;
+					}
+				}
+			}
+			if (avail_here) {
+				kunmap(*ppages);
+				ppages++;
+				c = kmap(*ppages);
+			}
+
+			avail_page = min(avail_here,
+				 (unsigned int) PAGE_CACHE_SIZE);
+		}
+		base = buf->page_len;  /* align to start of tail */
+	}
+
+	/* process tail */
+	base -= buf->page_len;
+	if (todo) {
+		c = buf->tail->iov_base + base;
+		if (copied) {
+			unsigned int l = desc->elem_size - copied;
+
+			if (encode)
+				memcpy(c, elem + copied, l);
+			else {
+				memcpy(elem + copied, c, l);
+				err = desc->xcode(desc, elem);
+				if (err)
+					goto out;
+			}
+			todo -= l;
+			c += l;
+		}
+		while (todo) {
+			err = desc->xcode(desc, c);
+			if (err)
+				goto out;
+			c += desc->elem_size;
+			todo -= desc->elem_size;
+		}
+	}
+	err = 0;
+
+out:
+	if (elem)
+		kfree(elem);
+	if (ppages)
+		kunmap(*ppages);
+	return err;
+}
+
+int
+xdr_decode_array2(struct xdr_buf *buf, unsigned int base,
+		  struct xdr_array2_desc *desc)
+{
+	if (base >= buf->len)
+		return -EINVAL;
+
+	return xdr_xcode_array2(buf, base, desc, 0);
+}
+
+int
+xdr_encode_array2(struct xdr_buf *buf, unsigned int base,
+		  struct xdr_array2_desc *desc)
+{
+	if ((unsigned long) base + 4 + desc->array_len * desc->elem_size >
+	    buf->head->iov_len + buf->page_len + buf->tail->iov_len)
+		return -EINVAL;
+
+	return xdr_xcode_array2(buf, base, desc, 1);
+}
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -145,8 +145,6 @@ __xprt_lock_write(struct rpc_xprt *xprt,
 	if (test_and_set_bit(XPRT_LOCKED, &xprt->sockstate)) {
 		if (task == xprt->snd_task)
 			return 1;
-		if (task == NULL)
-			return 0;
 		goto out_sleep;
 	}
 	if (xprt->nocong || __xprt_get_cong(xprt, task)) {
@@ -569,8 +567,11 @@ void xprt_connect(struct rpc_task *task)
 		if (xprt->sock != NULL)
 			schedule_delayed_work(&xprt->sock_connect,
 					RPC_REESTABLISH_TIMEOUT);
-		else
+		else {
 			schedule_work(&xprt->sock_connect);
+			if (!RPC_IS_ASYNC(task))
+				flush_scheduled_work();
+		}
 	}
 	return;
  out_write:
@@ -725,7 +726,8 @@ csum_partial_copy_to_xdr(struct xdr_buf 
 		goto no_checksum;
 
 	desc.csum = csum_partial(skb->data, desc.offset, skb->csum);
-	xdr_partial_copy_from_skb(xdr, 0, &desc, skb_read_and_csum_bits);
+	if (xdr_partial_copy_from_skb(xdr, 0, &desc, skb_read_and_csum_bits) < 0)
+		return -1;
 	if (desc.offset != skb->len) {
 		unsigned int csum2;
 		csum2 = skb_checksum(skb, desc.offset, skb->len - desc.offset, 0);
@@ -737,7 +739,8 @@ csum_partial_copy_to_xdr(struct xdr_buf 
 		return -1;
 	return 0;
 no_checksum:
-	xdr_partial_copy_from_skb(xdr, 0, &desc, skb_read_bits);
+	if (xdr_partial_copy_from_skb(xdr, 0, &desc, skb_read_bits) < 0)
+		return -1;
 	if (desc.count)
 		return -1;
 	return 0;
@@ -821,10 +824,15 @@ tcp_copy_data(skb_reader_t *desc, void *
 {
 	if (len > desc->count)
 		len = desc->count;
-	if (skb_copy_bits(desc->skb, desc->offset, p, len))
+	if (skb_copy_bits(desc->skb, desc->offset, p, len)) {
+		dprintk("RPC:      failed to copy %zu bytes from skb. %zu bytes remain\n",
+				len, desc->count);
 		return 0;
+	}
 	desc->offset += len;
 	desc->count -= len;
+	dprintk("RPC:      copied %zu bytes from skb. %zu bytes remain\n",
+			len, desc->count);
 	return len;
 }
 
@@ -863,6 +871,8 @@ tcp_read_fraghdr(struct rpc_xprt *xprt, 
 static void
 tcp_check_recm(struct rpc_xprt *xprt)
 {
+	dprintk("RPC:      xprt = %p, tcp_copied = %lu, tcp_offset = %u, tcp_reclen = %u, tcp_flags = %lx\n",
+			xprt, xprt->tcp_copied, xprt->tcp_offset, xprt->tcp_reclen, xprt->tcp_flags);
 	if (xprt->tcp_offset == xprt->tcp_reclen) {
 		xprt->tcp_flags |= XPRT_COPY_RECM;
 		xprt->tcp_offset = 0;
@@ -907,6 +917,7 @@ tcp_read_request(struct rpc_xprt *xprt, 
 	struct rpc_rqst *req;
 	struct xdr_buf *rcvbuf;
 	size_t len;
+	ssize_t r;
 
 	/* Find and lock the request corresponding to this xid */
 	spin_lock(&xprt->sock_lock);
@@ -927,15 +938,40 @@ tcp_read_request(struct rpc_xprt *xprt, 
 		len = xprt->tcp_reclen - xprt->tcp_offset;
 		memcpy(&my_desc, desc, sizeof(my_desc));
 		my_desc.count = len;
-		xdr_partial_copy_from_skb(rcvbuf, xprt->tcp_copied,
+		r = xdr_partial_copy_from_skb(rcvbuf, xprt->tcp_copied,
 					  &my_desc, tcp_copy_data);
-		desc->count -= len;
-		desc->offset += len;
+		desc->count -= r;
+		desc->offset += r;
 	} else
-		xdr_partial_copy_from_skb(rcvbuf, xprt->tcp_copied,
+		r = xdr_partial_copy_from_skb(rcvbuf, xprt->tcp_copied,
 					  desc, tcp_copy_data);
-	xprt->tcp_copied += len;
-	xprt->tcp_offset += len;
+
+	if (r > 0) {
+		xprt->tcp_copied += r;
+		xprt->tcp_offset += r;
+	}
+	if (r != len) {
+		/* Error when copying to the receive buffer,
+		 * usually because we weren't able to allocate
+		 * additional buffer pages. All we can do now
+		 * is turn off XPRT_COPY_DATA, so the request
+		 * will not receive any additional updates,
+		 * and time out.
+		 * Any remaining data from this record will
+		 * be discarded.
+		 */
+		xprt->tcp_flags &= ~XPRT_COPY_DATA;
+		dprintk("RPC:      XID %08x truncated request\n",
+				ntohl(xprt->tcp_xid));
+		dprintk("RPC:      xprt = %p, tcp_copied = %lu, tcp_offset = %u, tcp_reclen = %u\n",
+				xprt, xprt->tcp_copied, xprt->tcp_offset, xprt->tcp_reclen);
+		goto out;
+	}
+
+	dprintk("RPC:      XID %08x read %Zd bytes\n",
+			ntohl(xprt->tcp_xid), r);
+	dprintk("RPC:      xprt = %p, tcp_copied = %lu, tcp_offset = %u, tcp_reclen = %u\n",
+			xprt, xprt->tcp_copied, xprt->tcp_offset, xprt->tcp_reclen);
 
 	if (xprt->tcp_copied == req->rq_private_buf.buflen)
 		xprt->tcp_flags &= ~XPRT_COPY_DATA;
@@ -944,6 +980,7 @@ tcp_read_request(struct rpc_xprt *xprt, 
 			xprt->tcp_flags &= ~XPRT_COPY_DATA;
 	}
 
+out:
 	if (!(xprt->tcp_flags & XPRT_COPY_DATA)) {
 		dprintk("RPC: %4d received reply complete\n",
 				req->rq_task->tk_pid);
@@ -967,6 +1004,7 @@ tcp_read_discard(struct rpc_xprt *xprt, 
 	desc->count -= len;
 	desc->offset += len;
 	xprt->tcp_offset += len;
+	dprintk("RPC:      discarded %Zu bytes\n", len);
 	tcp_check_recm(xprt);
 }
 
@@ -1064,8 +1102,7 @@ tcp_state_change(struct sock *sk)
 	case TCP_SYN_RECV:
 		break;
 	default:
-		if (xprt_test_and_clear_connected(xprt))
-			rpc_wake_up_status(&xprt->pending, -ENOTCONN);
+		xprt_disconnect(xprt);
 		break;
 	}
  out:
@@ -1203,6 +1240,8 @@ xprt_transmit(struct rpc_task *task)
 			list_add_tail(&req->rq_list, &xprt->recv);
 			spin_unlock_bh(&xprt->sock_lock);
 			xprt_reset_majortimeo(req);
+			/* Turn off autodisconnect */
+			del_singleshot_timer_sync(&xprt->timer);
 		}
 	} else if (!req->rq_bytes_sent)
 		return;
@@ -1333,8 +1372,6 @@ xprt_reserve(struct rpc_task *task)
 		spin_lock(&xprt->xprt_lock);
 		do_xprt_reserve(task);
 		spin_unlock(&xprt->xprt_lock);
-		if (task->tk_rqstp)
-			del_timer_sync(&xprt->timer);
 	}
 }
 
@@ -1649,6 +1686,10 @@ xprt_shutdown(struct rpc_xprt *xprt)
 	rpc_wake_up(&xprt->backlog);
 	wake_up(&xprt->cong_wait);
 	del_timer_sync(&xprt->timer);
+
+	/* synchronously wait for connect worker to finish */
+	cancel_delayed_work(&xprt->sock_connect);
+	flush_scheduled_work();
 }
 
 /*
diff --git a/net/unix/Kconfig b/net/unix/Kconfig
new file mode 100644
--- /dev/null
+++ b/net/unix/Kconfig
@@ -0,0 +1,21 @@
+#
+# Unix Domain Sockets
+#
+
+config UNIX
+	tristate "Unix domain sockets"
+	---help---
+	  If you say Y here, you will include support for Unix domain sockets;
+	  sockets are the standard Unix mechanism for establishing and
+	  accessing network connections.  Many commonly used programs such as
+	  the X Window system and syslog use these sockets even if your
+	  machine is not connected to any network.  Unless you are working on
+	  an embedded system or something similar, you therefore definitely
+	  want to say Y here.
+
+	  To compile this driver as a module, choose M here: the module will be
+	  called unix.  Note that several important services won't work
+	  correctly if you say M here and then neglect to load the module.
+
+	  Say Y unless you know what you are doing.
+
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -302,7 +302,7 @@ static void unix_write_space(struct sock
  * may receive messages only from that peer. */
 static void unix_dgram_disconnected(struct sock *sk, struct sock *other)
 {
-	if (skb_queue_len(&sk->sk_receive_queue)) {
+	if (!skb_queue_empty(&sk->sk_receive_queue)) {
 		skb_queue_purge(&sk->sk_receive_queue);
 		wake_up_interruptible_all(&unix_sk(sk)->peer_wait);
 
@@ -1619,7 +1619,7 @@ static long unix_stream_data_wait(struct
 	for (;;) {
 		prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
 
-		if (skb_queue_len(&sk->sk_receive_queue) ||
+		if (!skb_queue_empty(&sk->sk_receive_queue) ||
 		    sk->sk_err ||
 		    (sk->sk_shutdown & RCV_SHUTDOWN) ||
 		    signal_pending(current) ||
diff --git a/net/wanrouter/Kconfig b/net/wanrouter/Kconfig
new file mode 100644
--- /dev/null
+++ b/net/wanrouter/Kconfig
@@ -0,0 +1,29 @@
+#
+# Configuration for WAN router
+#
+
+config WAN_ROUTER
+	tristate "WAN router"
+	depends on EXPERIMENTAL
+	---help---
+	  Wide Area Networks (WANs), such as X.25, frame relay and leased
+	  lines, are used to interconnect Local Area Networks (LANs) over vast
+	  distances with data transfer rates significantly higher than those
+	  achievable with commonly used asynchronous modem connections.
+	  Usually, a quite expensive external device called a `WAN router' is
+	  needed to connect to a WAN.
+
+	  As an alternative, WAN routing can be built into the Linux kernel.
+	  With relatively inexpensive WAN interface cards available on the
+	  market, a perfectly usable router can be built for less than half
+	  the price of an external router.  If you have one of those cards and
+	  wish to use your Linux box as a WAN router, say Y here and also to
+	  the WAN driver for your card, below.  You will then need the
+	  wan-tools package which is available from <ftp://ftp.sangoma.com/>.
+	  Read <file:Documentation/networking/wan-router.txt> for more
+	  information.
+
+	  To compile WAN routing support as a module, choose M here: the
+	  module will be called wanrouter.
+
+	  If unsure, say N.
diff --git a/net/wanrouter/wanmain.c b/net/wanrouter/wanmain.c
--- a/net/wanrouter/wanmain.c
+++ b/net/wanrouter/wanmain.c
@@ -358,10 +358,10 @@ int wanrouter_encapsulate(struct sk_buff
  */
 
 
-unsigned short wanrouter_type_trans(struct sk_buff *skb, struct net_device *dev)
+__be16 wanrouter_type_trans(struct sk_buff *skb, struct net_device *dev)
 {
 	int cnt = skb->data[0] ? 0 : 1;	/* there may be a pad present */
-	unsigned short ethertype;
+	__be16 ethertype;
 
 	switch (skb->data[cnt]) {
 	case NLPID_IP:		/* IP datagramm */
@@ -379,7 +379,7 @@ unsigned short wanrouter_type_trans(stru
 				skb->data[cnt+3], dev->name);
 			return 0;
 		}
-		ethertype = *((unsigned short*)&skb->data[cnt+4]);
+		ethertype = *((__be16*)&skb->data[cnt+4]);
 		cnt += 6;
 		break;
 
diff --git a/net/x25/Kconfig b/net/x25/Kconfig
new file mode 100644
--- /dev/null
+++ b/net/x25/Kconfig
@@ -0,0 +1,36 @@
+#
+# CCITT X.25 Packet Layer
+#
+
+config X25
+	tristate "CCITT X.25 Packet Layer (EXPERIMENTAL)"
+	depends on EXPERIMENTAL
+	---help---
+	  X.25 is a set of standardized network protocols, similar in scope to
+	  frame relay; the one physical line from your box to the X.25 network
+	  entry point can carry several logical point-to-point connections
+	  (called "virtual circuits") to other computers connected to the X.25
+	  network. Governments, banks, and other organizations tend to use it
+	  to connect to each other or to form Wide Area Networks (WANs). Many
+	  countries have public X.25 networks. X.25 consists of two
+	  protocols: the higher level Packet Layer Protocol (PLP) (say Y here
+	  if you want that) and the lower level data link layer protocol LAPB
+	  (say Y to "LAPB Data Link Driver" below if you want that).
+
+	  You can read more about X.25 at <http://www.sangoma.com/x25.htm> and
+	  <http://www.cisco.com/univercd/cc/td/doc/product/software/ios11/cbook/cx25.htm>.
+	  Information about X.25 for Linux is contained in the files
+	  <file:Documentation/networking/x25.txt> and
+	  <file:Documentation/networking/x25-iface.txt>.
+
+	  One connects to an X.25 network either with a dedicated network card
+	  using the X.21 protocol (not yet supported by Linux) or one can do
+	  X.25 over a standard telephone line using an ordinary modem (say Y
+	  to "X.25 async driver" below) or over Ethernet using an ordinary
+	  Ethernet card and the LAPB over Ethernet (say Y to "LAPB Data Link
+	  Driver" and "LAPB over Ethernet driver" below).
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called x25. If unsure, say N.
+
+
diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c
--- a/net/x25/af_x25.c
+++ b/net/x25/af_x25.c
@@ -29,6 +29,10 @@
  *	2000-11-14	Henner Eisen    Closing datalink from NETDEV_GOING_DOWN
  *	2002-10-06	Arnaldo C. Melo Get rid of cli/sti, move proc stuff to
  *					x25_proc.c, using seq_file
+ *	2005-04-02	Shaun Pereira	Selective sub address matching
+ *					with call user data
+ *	2005-04-15	Shaun Pereira	Fast select with no restriction on
+ *					response
  */
 
 #include <linux/config.h>
@@ -219,7 +223,8 @@ static void x25_insert_socket(struct soc
  *	Note: if a listening socket has cud set it must only get calls
  *	with matching cud.
  */
-static struct sock *x25_find_listener(struct x25_address *addr, struct x25_calluserdata *calluserdata)
+static struct sock *x25_find_listener(struct x25_address *addr,
+					struct sk_buff *skb)
 {
 	struct sock *s;
 	struct sock *next_best;
@@ -230,22 +235,23 @@ static struct sock *x25_find_listener(st
 
 	sk_for_each(s, node, &x25_list)
 		if ((!strcmp(addr->x25_addr,
-			     x25_sk(s)->source_addr.x25_addr) ||
-		     !strcmp(addr->x25_addr,
-			     null_x25_address.x25_addr)) &&
-		     s->sk_state == TCP_LISTEN) {
-
+			x25_sk(s)->source_addr.x25_addr) ||
+				!strcmp(addr->x25_addr,
+					null_x25_address.x25_addr)) &&
+					s->sk_state == TCP_LISTEN) {
 			/*
 			 * Found a listening socket, now check the incoming
 			 * call user data vs this sockets call user data
 			 */
-			if (x25_check_calluserdata(&x25_sk(s)->calluserdata, calluserdata)) {
-				sock_hold(s);
-				goto found;
-			}
-			if (x25_sk(s)->calluserdata.cudlength == 0) {
+			if(skb->len > 0 && x25_sk(s)->cudmatchlength > 0) {
+			 	if((memcmp(x25_sk(s)->calluserdata.cuddata,
+			 		skb->data,
+					x25_sk(s)->cudmatchlength)) == 0) {
+					sock_hold(s);
+					goto found;
+				 }
+			} else
 				next_best = s;
-			}
 		}
 	if (next_best) {
 		s = next_best;
@@ -497,6 +503,9 @@ static int x25_create(struct socket *soc
 	x25->t23   = sysctl_x25_clear_request_timeout;
 	x25->t2    = sysctl_x25_ack_holdback_timeout;
 	x25->state = X25_STATE_0;
+	x25->cudmatchlength = 0;
+	x25->accptapprv = X25_DENY_ACCPT_APPRV;		/* normally no cud  */
+							/* on call accept   */
 
 	x25->facilities.winsize_in  = X25_DEFAULT_WINDOW_SIZE;
 	x25->facilities.winsize_out = X25_DEFAULT_WINDOW_SIZE;
@@ -545,6 +554,8 @@ static struct sock *x25_make_new(struct 
 	x25->t2         = ox25->t2;
 	x25->facilities = ox25->facilities;
 	x25->qbitincl   = ox25->qbitincl;
+	x25->cudmatchlength = ox25->cudmatchlength;
+	x25->accptapprv = ox25->accptapprv;
 
 	x25_init_timers(sk);
 out:
@@ -822,7 +833,6 @@ int x25_rx_call_request(struct sk_buff *
 	struct x25_sock *makex25;
 	struct x25_address source_addr, dest_addr;
 	struct x25_facilities facilities;
-	struct x25_calluserdata calluserdata;
 	int len, rc;
 
 	/*
@@ -845,19 +855,10 @@ int x25_rx_call_request(struct sk_buff *
 	skb_pull(skb,len);
 
 	/*
-	 *	Incoming Call User Data.
-	 */
-	if (skb->len >= 0) {
-		memcpy(calluserdata.cuddata, skb->data, skb->len);
-		calluserdata.cudlength = skb->len;
-	}
-
-	skb_push(skb,len);
-
-	/*
 	 *	Find a listener for the particular address/cud pair.
 	 */
-	sk = x25_find_listener(&source_addr,&calluserdata);
+	sk = x25_find_listener(&source_addr,skb);
+	skb_push(skb,len);
 
 	/*
 	 *	We can't accept the Call Request.
@@ -900,11 +901,23 @@ int x25_rx_call_request(struct sk_buff *
 	makex25->neighbour     = nb;
 	makex25->facilities    = facilities;
 	makex25->vc_facil_mask = x25_sk(sk)->vc_facil_mask;
-	makex25->calluserdata  = calluserdata;
-
-	x25_write_internal(make, X25_CALL_ACCEPTED);
+	/* ensure no reverse facil on accept */
+	makex25->vc_facil_mask &= ~X25_MASK_REVERSE;
+	makex25->cudmatchlength = x25_sk(sk)->cudmatchlength;
+
+	/* Normally all calls are accepted immediatly */
+	if(makex25->accptapprv & X25_DENY_ACCPT_APPRV) {
+		x25_write_internal(make, X25_CALL_ACCEPTED);
+		makex25->state = X25_STATE_3;
+	}
 
-	makex25->state = X25_STATE_3;
+	/*
+	 *	Incoming Call User Data.
+	 */
+	if (skb->len >= 0) {
+		memcpy(makex25->calluserdata.cuddata, skb->data, skb->len);
+		makex25->calluserdata.cudlength = skb->len;
+	}
 
 	sk->sk_ack_backlog++;
 
@@ -1288,7 +1301,8 @@ static int x25_ioctl(struct socket *sock
 			if (facilities.throughput < 0x03 ||
 			    facilities.throughput > 0xDD)
 				break;
-			if (facilities.reverse && facilities.reverse != 1)
+			if (facilities.reverse &&
+				(facilities.reverse | 0x81)!= 0x81)
 				break;
 			x25->facilities = facilities;
 			rc = 0;
@@ -1325,6 +1339,44 @@ static int x25_ioctl(struct socket *sock
 			break;
 		}
 
+		case SIOCX25SCUDMATCHLEN: {
+			struct x25_subaddr sub_addr;
+			rc = -EINVAL;
+			if(sk->sk_state != TCP_CLOSE)
+				break;
+			rc = -EFAULT;
+			if (copy_from_user(&sub_addr, argp,
+					sizeof(sub_addr)))
+				break;
+		 	rc = -EINVAL;
+			if(sub_addr.cudmatchlength > X25_MAX_CUD_LEN)
+				break;
+			x25->cudmatchlength = sub_addr.cudmatchlength;
+			rc = 0;
+			break;
+		}
+
+		case SIOCX25CALLACCPTAPPRV: {
+			rc = -EINVAL;
+			if (sk->sk_state != TCP_CLOSE)
+				break;
+			x25->accptapprv = X25_ALLOW_ACCPT_APPRV;
+			rc = 0;
+			break;
+		}
+
+		case SIOCX25SENDCALLACCPT:  {
+			rc = -EINVAL;
+			if (sk->sk_state != TCP_ESTABLISHED)
+				break;
+			if (x25->accptapprv)	/* must call accptapprv above */
+				break;
+			x25_write_internal(sk, X25_CALL_ACCEPTED);
+			x25->state = X25_STATE_3;
+			rc = 0;
+			break;
+		}
+
  		default:
 			rc = dev_ioctl(cmd, argp);
 			break;
diff --git a/net/x25/x25_facilities.c b/net/x25/x25_facilities.c
--- a/net/x25/x25_facilities.c
+++ b/net/x25/x25_facilities.c
@@ -17,6 +17,8 @@
  *	X.25 001	Split from x25_subr.c
  *	mar/20/00	Daniela Squassoni Disabling/enabling of facilities 
  *					  negotiation.
+ *	apr/14/05	Shaun Pereira - Allow fast select with no restriction
+ *					on response.
  */
 
 #include <linux/kernel.h>
@@ -43,9 +45,31 @@ int x25_parse_facilities(struct sk_buff 
 		case X25_FAC_CLASS_A:
 			switch (*p) {
 			case X25_FAC_REVERSE:
-				facilities->reverse = p[1] & 0x01;
-				*vc_fac_mask |= X25_MASK_REVERSE;
-				break;
+				if((p[1] & 0x81) == 0x81) {
+					facilities->reverse = p[1] & 0x81;
+					*vc_fac_mask |= X25_MASK_REVERSE;
+					break;
+				}
+
+				if((p[1] & 0x01) == 0x01) {
+					facilities->reverse = p[1] & 0x01;
+					*vc_fac_mask |= X25_MASK_REVERSE;
+					break;
+				}
+
+				if((p[1] & 0x80) == 0x80) {
+					facilities->reverse = p[1] & 0x80;
+					*vc_fac_mask |= X25_MASK_REVERSE;
+					break;
+				}
+
+				if(p[1] == 0x00) {
+					facilities->reverse
+						= X25_DEFAULT_REVERSE;
+					*vc_fac_mask |= X25_MASK_REVERSE;
+					break;
+				}
+
 			case X25_FAC_THROUGHPUT:
 				facilities->throughput = p[1];
 				*vc_fac_mask |= X25_MASK_THROUGHPUT;
@@ -122,7 +146,7 @@ int x25_create_facilities(unsigned char 
 
 	if (facilities->reverse && (facil_mask & X25_MASK_REVERSE)) {
 		*p++ = X25_FAC_REVERSE;
-		*p++ = !!facilities->reverse;
+		*p++ = facilities->reverse;
 	}
 
 	if (facilities->throughput && (facil_mask & X25_MASK_THROUGHPUT)) {
@@ -171,7 +195,7 @@ int x25_negotiate_facilities(struct sk_b
 	/*
 	 *	They want reverse charging, we won't accept it.
 	 */
-	if (theirs.reverse && ours->reverse) {
+	if ((theirs.reverse & 0x01 ) && (ours->reverse & 0x01)) {
 		SOCK_DEBUG(sk, "X.25: rejecting reverse charging request");
 		return -1;
 	}
diff --git a/net/x25/x25_subr.c b/net/x25/x25_subr.c
--- a/net/x25/x25_subr.c
+++ b/net/x25/x25_subr.c
@@ -19,6 +19,8 @@
  *	mar/20/00	Daniela Squassoni Disabling/enabling of facilities
  *					  negotiation.
  *	jun/24/01	Arnaldo C. Melo	  use skb_queue_purge, cleanups
+ *	apr/04/15	Shaun Pereira		Fast select with no
+ *						restriction on response.
  */
 
 #include <linux/kernel.h>
@@ -127,8 +129,12 @@ void x25_write_internal(struct sock *sk,
 			len += 1 + X25_ADDR_LEN + X25_MAX_FAC_LEN +
 			       X25_MAX_CUD_LEN;
 			break;
-		case X25_CALL_ACCEPTED:
-			len += 1 + X25_MAX_FAC_LEN + X25_MAX_CUD_LEN;
+		case X25_CALL_ACCEPTED: /* fast sel with no restr on resp */
+			if(x25->facilities.reverse & 0x80) {
+				len += 1 + X25_MAX_FAC_LEN + X25_MAX_CUD_LEN;
+			} else {
+				len += 1 + X25_MAX_FAC_LEN;
+			}
 			break;
 		case X25_CLEAR_REQUEST:
 		case X25_RESET_REQUEST:
@@ -203,9 +209,16 @@ void x25_write_internal(struct sock *sk,
 							x25->vc_facil_mask);
 			dptr    = skb_put(skb, len);
 			memcpy(dptr, facilities, len);
-			dptr = skb_put(skb, x25->calluserdata.cudlength);
-			memcpy(dptr, x25->calluserdata.cuddata,
-			       x25->calluserdata.cudlength);
+
+			/* fast select with no restriction on response
+				allows call user data. Userland must
+				ensure it is ours and not theirs */
+			if(x25->facilities.reverse & 0x80) {
+				dptr = skb_put(skb,
+					x25->calluserdata.cudlength);
+				memcpy(dptr, x25->calluserdata.cuddata,
+				       x25->calluserdata.cudlength);
+			}
 			x25->calluserdata.cudlength = 0;
 			break;
 
@@ -354,21 +367,3 @@ void x25_check_rbuf(struct sock *sk)
 	}
 }
 
-/*
- * Compare 2 calluserdata structures, used to find correct listening sockets
- * when call user data is used.
- */
-int x25_check_calluserdata(struct x25_calluserdata *ours, struct x25_calluserdata *theirs)
-{
-	int i;
-	if (ours->cudlength != theirs->cudlength)
-		return 0;
-
-	for (i=0;i<ours->cudlength;i++) {
-		if (ours->cuddata[i] != theirs->cuddata[i]) {
-			return 0;
-		}
-	}
-	return 1;
-}
-
diff --git a/net/xfrm/Kconfig b/net/xfrm/Kconfig
--- a/net/xfrm/Kconfig
+++ b/net/xfrm/Kconfig
@@ -1,6 +1,10 @@
 #
 # XFRM configuration
 #
+config XFRM
+       bool
+       depends on NET
+
 config XFRM_USER
 	tristate "IPsec user configuration interface"
 	depends on INET && XFRM
@@ -10,3 +14,14 @@ config XFRM_USER
 
 	  If unsure, say Y.
 
+config NET_KEY
+	tristate "PF_KEY sockets"
+	select XFRM
+	---help---
+	  PF_KEYv2 socket family, compatible to KAME ones.
+	  They are required if you are going to use IPsec tools ported
+	  from KAME.
+
+	  Say Y unless you know what you are doing.
+
+
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -118,7 +118,6 @@ retry:
 	xfrm_policy_put_afinfo(afinfo);
 	return type;
 }
-EXPORT_SYMBOL(xfrm_get_type);
 
 int xfrm_dst_lookup(struct xfrm_dst **dst, struct flowi *fl, 
 		    unsigned short family)
@@ -216,8 +215,8 @@ out:
 
 expired:
 	read_unlock(&xp->lock);
-	km_policy_expired(xp, dir, 1);
-	xfrm_policy_delete(xp, dir);
+	if (!xfrm_policy_delete(xp, dir))
+		km_policy_expired(xp, dir, 1);
 	xfrm_pol_put(xp);
 }
 
@@ -555,7 +554,7 @@ static struct xfrm_policy *__xfrm_policy
 	return NULL;
 }
 
-void xfrm_policy_delete(struct xfrm_policy *pol, int dir)
+int xfrm_policy_delete(struct xfrm_policy *pol, int dir)
 {
 	write_lock_bh(&xfrm_policy_lock);
 	pol = __xfrm_policy_unlink(pol, dir);
@@ -564,7 +563,9 @@ void xfrm_policy_delete(struct xfrm_poli
 		if (dir < XFRM_POLICY_MAX)
 			atomic_inc(&flow_cache_genid);
 		xfrm_policy_kill(pol);
+		return 0;
 	}
+	return -ENOENT;
 }
 
 int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol)
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -50,7 +50,7 @@ static DEFINE_SPINLOCK(xfrm_state_gc_loc
 
 static int xfrm_state_gc_flush_bundles;
 
-static void __xfrm_state_delete(struct xfrm_state *x);
+static int __xfrm_state_delete(struct xfrm_state *x);
 
 static struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned short family);
 static void xfrm_state_put_afinfo(struct xfrm_state_afinfo *afinfo);
@@ -154,6 +154,7 @@ static void xfrm_timer_handler(unsigned 
 			next = tmo;
 	}
 
+	x->km.dying = warn;
 	if (warn)
 		km_state_expired(x, 0);
 resched:
@@ -169,9 +170,8 @@ expired:
 		next = 2;
 		goto resched;
 	}
-	if (x->id.spi != 0)
+	if (!__xfrm_state_delete(x) && x->id.spi)
 		km_state_expired(x, 1);
-	__xfrm_state_delete(x);
 
 out:
 	spin_unlock(&x->lock);
@@ -215,8 +215,10 @@ void __xfrm_state_destroy(struct xfrm_st
 }
 EXPORT_SYMBOL(__xfrm_state_destroy);
 
-static void __xfrm_state_delete(struct xfrm_state *x)
+static int __xfrm_state_delete(struct xfrm_state *x)
 {
+	int err = -ESRCH;
+
 	if (x->km.state != XFRM_STATE_DEAD) {
 		x->km.state = XFRM_STATE_DEAD;
 		spin_lock(&xfrm_state_lock);
@@ -245,14 +247,21 @@ static void __xfrm_state_delete(struct x
 		 * is what we are dropping here.
 		 */
 		atomic_dec(&x->refcnt);
+		err = 0;
 	}
+
+	return err;
 }
 
-void xfrm_state_delete(struct xfrm_state *x)
+int xfrm_state_delete(struct xfrm_state *x)
 {
+	int err;
+
 	spin_lock_bh(&x->lock);
-	__xfrm_state_delete(x);
+	err = __xfrm_state_delete(x);
 	spin_unlock_bh(&x->lock);
+
+	return err;
 }
 EXPORT_SYMBOL(xfrm_state_delete);
 
@@ -557,16 +566,18 @@ int xfrm_state_check_expire(struct xfrm_
 
 	if (x->curlft.bytes >= x->lft.hard_byte_limit ||
 	    x->curlft.packets >= x->lft.hard_packet_limit) {
-		km_state_expired(x, 1);
-		if (!mod_timer(&x->timer, jiffies + XFRM_ACQ_EXPIRES*HZ))
+		x->km.state = XFRM_STATE_EXPIRED;
+		if (!mod_timer(&x->timer, jiffies))
 			xfrm_state_hold(x);
 		return -EINVAL;
 	}
 
 	if (!x->km.dying &&
 	    (x->curlft.bytes >= x->lft.soft_byte_limit ||
-	     x->curlft.packets >= x->lft.soft_packet_limit))
+	     x->curlft.packets >= x->lft.soft_packet_limit)) {
+		x->km.dying = 1;
 		km_state_expired(x, 0);
+	}
 	return 0;
 }
 EXPORT_SYMBOL(xfrm_state_check_expire);
@@ -796,34 +807,56 @@ EXPORT_SYMBOL(xfrm_replay_advance);
 static struct list_head xfrm_km_list = LIST_HEAD_INIT(xfrm_km_list);
 static DEFINE_RWLOCK(xfrm_km_lock);
 
-static void km_state_expired(struct xfrm_state *x, int hard)
+void km_policy_notify(struct xfrm_policy *xp, int dir, struct km_event *c)
 {
 	struct xfrm_mgr *km;
 
-	if (hard)
-		x->km.state = XFRM_STATE_EXPIRED;
-	else
-		x->km.dying = 1;
+	read_lock(&xfrm_km_lock);
+	list_for_each_entry(km, &xfrm_km_list, list)
+		if (km->notify_policy)
+			km->notify_policy(xp, dir, c);
+	read_unlock(&xfrm_km_lock);
+}
 
+void km_state_notify(struct xfrm_state *x, struct km_event *c)
+{
+	struct xfrm_mgr *km;
 	read_lock(&xfrm_km_lock);
 	list_for_each_entry(km, &xfrm_km_list, list)
-		km->notify(x, hard);
+		if (km->notify)
+			km->notify(x, c);
 	read_unlock(&xfrm_km_lock);
+}
+
+EXPORT_SYMBOL(km_policy_notify);
+EXPORT_SYMBOL(km_state_notify);
+
+static void km_state_expired(struct xfrm_state *x, int hard)
+{
+	struct km_event c;
+
+	c.data.hard = hard;
+	c.event = XFRM_MSG_EXPIRE;
+	km_state_notify(x, &c);
 
 	if (hard)
 		wake_up(&km_waitq);
 }
 
+/*
+ * We send to all registered managers regardless of failure
+ * We are happy with one success
+*/
 static int km_query(struct xfrm_state *x, struct xfrm_tmpl *t, struct xfrm_policy *pol)
 {
-	int err = -EINVAL;
+	int err = -EINVAL, acqret;
 	struct xfrm_mgr *km;
 
 	read_lock(&xfrm_km_lock);
 	list_for_each_entry(km, &xfrm_km_list, list) {
-		err = km->acquire(x, t, pol, XFRM_POLICY_OUT);
-		if (!err)
-			break;
+		acqret = km->acquire(x, t, pol, XFRM_POLICY_OUT);
+		if (!acqret)
+			err = acqret;
 	}
 	read_unlock(&xfrm_km_lock);
 	return err;
@@ -848,13 +881,11 @@ EXPORT_SYMBOL(km_new_mapping);
 
 void km_policy_expired(struct xfrm_policy *pol, int dir, int hard)
 {
-	struct xfrm_mgr *km;
+	struct km_event c;
 
-	read_lock(&xfrm_km_lock);
-	list_for_each_entry(km, &xfrm_km_list, list)
-		if (km->notify_policy)
-			km->notify_policy(pol, dir, hard);
-	read_unlock(&xfrm_km_lock);
+	c.data.hard = hard;
+	c.event = XFRM_MSG_POLEXPIRE;
+	km_policy_notify(pol, dir, &c);
 
 	if (hard)
 		wake_up(&km_waitq);
@@ -1024,6 +1055,43 @@ int xfrm_state_mtu(struct xfrm_state *x,
 }
 
 EXPORT_SYMBOL(xfrm_state_mtu);
+
+int xfrm_init_state(struct xfrm_state *x)
+{
+	struct xfrm_state_afinfo *afinfo;
+	int family = x->props.family;
+	int err;
+
+	err = -EAFNOSUPPORT;
+	afinfo = xfrm_state_get_afinfo(family);
+	if (!afinfo)
+		goto error;
+
+	err = 0;
+	if (afinfo->init_flags)
+		err = afinfo->init_flags(x);
+
+	xfrm_state_put_afinfo(afinfo);
+
+	if (err)
+		goto error;
+
+	err = -EPROTONOSUPPORT;
+	x->type = xfrm_get_type(x->id.proto, family);
+	if (x->type == NULL)
+		goto error;
+
+	err = x->type->init_state(x);
+	if (err)
+		goto error;
+
+	x->km.state = XFRM_STATE_VALID;
+
+error:
+	return err;
+}
+
+EXPORT_SYMBOL(xfrm_init_state);
  
 void __init xfrm_state_init(void)
 {
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -249,17 +249,10 @@ static struct xfrm_state *xfrm_state_con
 	if ((err = attach_encap_tmpl(&x->encap, xfrma[XFRMA_ENCAP-1])))
 		goto error;
 
-	err = -ENOENT;
-	x->type = xfrm_get_type(x->id.proto, x->props.family);
-	if (x->type == NULL)
-		goto error;
-
-	err = x->type->init_state(x, NULL);
+	err = xfrm_init_state(x);
 	if (err)
 		goto error;
 
-	x->curlft.add_time = (unsigned long) xtime.tv_sec;
-	x->km.state = XFRM_STATE_VALID;
 	x->km.seq = p->seq;
 
 	return x;
@@ -277,6 +270,7 @@ static int xfrm_add_sa(struct sk_buff *s
 	struct xfrm_usersa_info *p = NLMSG_DATA(nlh);
 	struct xfrm_state *x;
 	int err;
+	struct km_event c;
 
 	err = verify_newsa_info(p, (struct rtattr **) xfrma);
 	if (err)
@@ -286,6 +280,7 @@ static int xfrm_add_sa(struct sk_buff *s
 	if (!x)
 		return err;
 
+	xfrm_state_hold(x);
 	if (nlh->nlmsg_type == XFRM_MSG_NEWSA)
 		err = xfrm_state_add(x);
 	else
@@ -294,14 +289,24 @@ static int xfrm_add_sa(struct sk_buff *s
 	if (err < 0) {
 		x->km.state = XFRM_STATE_DEAD;
 		xfrm_state_put(x);
+		goto out;
 	}
 
+	c.seq = nlh->nlmsg_seq;
+	c.pid = nlh->nlmsg_pid;
+	c.event = nlh->nlmsg_type;
+
+	km_state_notify(x, &c);
+out:
+	xfrm_state_put(x);
 	return err;
 }
 
 static int xfrm_del_sa(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma)
 {
 	struct xfrm_state *x;
+	int err;
+	struct km_event c;
 	struct xfrm_usersa_id *p = NLMSG_DATA(nlh);
 
 	x = xfrm_state_lookup(&p->daddr, p->spi, p->proto, p->family);
@@ -313,10 +318,19 @@ static int xfrm_del_sa(struct sk_buff *s
 		return -EPERM;
 	}
 
-	xfrm_state_delete(x);
+	err = xfrm_state_delete(x);
+	if (err < 0) {
+		xfrm_state_put(x);
+		return err;
+	}
+
+	c.seq = nlh->nlmsg_seq;
+	c.pid = nlh->nlmsg_pid;
+	c.event = nlh->nlmsg_type;
+	km_state_notify(x, &c);
 	xfrm_state_put(x);
 
-	return 0;
+	return err;
 }
 
 static void copy_to_user_state(struct xfrm_state *x, struct xfrm_usersa_info *p)
@@ -681,6 +695,7 @@ static int xfrm_add_policy(struct sk_buf
 {
 	struct xfrm_userpolicy_info *p = NLMSG_DATA(nlh);
 	struct xfrm_policy *xp;
+	struct km_event c;
 	int err;
 	int excl;
 
@@ -692,6 +707,10 @@ static int xfrm_add_policy(struct sk_buf
 	if (!xp)
 		return err;
 
+	/* shouldnt excl be based on nlh flags??
+	 * Aha! this is anti-netlink really i.e  more pfkey derived
+	 * in netlink excl is a flag and you wouldnt need
+	 * a type XFRM_MSG_UPDPOLICY - JHS */
 	excl = nlh->nlmsg_type == XFRM_MSG_NEWPOLICY;
 	err = xfrm_policy_insert(p->dir, xp, excl);
 	if (err) {
@@ -699,6 +718,11 @@ static int xfrm_add_policy(struct sk_buf
 		return err;
 	}
 
+	c.event = nlh->nlmsg_type;
+	c.seq = nlh->nlmsg_seq;
+	c.pid = nlh->nlmsg_pid;
+	km_policy_notify(xp, p->dir, &c);
+
 	xfrm_pol_put(xp);
 
 	return 0;
@@ -816,6 +840,7 @@ static int xfrm_get_policy(struct sk_buf
 	struct xfrm_policy *xp;
 	struct xfrm_userpolicy_id *p;
 	int err;
+	struct km_event c;
 	int delete;
 
 	p = NLMSG_DATA(nlh);
@@ -843,6 +868,12 @@ static int xfrm_get_policy(struct sk_buf
 					      NETLINK_CB(skb).pid,
 					      MSG_DONTWAIT);
 		}
+	} else {
+		c.data.byid = p->index;
+		c.event = nlh->nlmsg_type;
+		c.seq = nlh->nlmsg_seq;
+		c.pid = nlh->nlmsg_pid;
+		km_policy_notify(xp, p->dir, &c);
 	}
 
 	xfrm_pol_put(xp);
@@ -852,15 +883,28 @@ static int xfrm_get_policy(struct sk_buf
 
 static int xfrm_flush_sa(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma)
 {
+	struct km_event c;
 	struct xfrm_usersa_flush *p = NLMSG_DATA(nlh);
 
 	xfrm_state_flush(p->proto);
+	c.data.proto = p->proto;
+	c.event = nlh->nlmsg_type;
+	c.seq = nlh->nlmsg_seq;
+	c.pid = nlh->nlmsg_pid;
+	km_state_notify(NULL, &c);
+
 	return 0;
 }
 
 static int xfrm_flush_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma)
 {
+	struct km_event c;
+
 	xfrm_policy_flush();
+	c.event = nlh->nlmsg_type;
+	c.seq = nlh->nlmsg_seq;
+	c.pid = nlh->nlmsg_pid;
+	km_policy_notify(NULL, 0, &c);
 	return 0;
 }
 
@@ -1069,15 +1113,16 @@ nlmsg_failure:
 	return -1;
 }
 
-static int xfrm_send_state_notify(struct xfrm_state *x, int hard)
+static int xfrm_exp_state_notify(struct xfrm_state *x, struct km_event *c)
 {
 	struct sk_buff *skb;
+	int len = NLMSG_LENGTH(sizeof(struct xfrm_user_expire));
 
-	skb = alloc_skb(sizeof(struct xfrm_user_expire) + 16, GFP_ATOMIC);
+	skb = alloc_skb(len, GFP_ATOMIC);
 	if (skb == NULL)
 		return -ENOMEM;
 
-	if (build_expire(skb, x, hard) < 0)
+	if (build_expire(skb, x, c->data.hard) < 0)
 		BUG();
 
 	NETLINK_CB(skb).dst_groups = XFRMGRP_EXPIRE;
@@ -1085,6 +1130,131 @@ static int xfrm_send_state_notify(struct
 	return netlink_broadcast(xfrm_nl, skb, 0, XFRMGRP_EXPIRE, GFP_ATOMIC);
 }
 
+static int xfrm_notify_sa_flush(struct km_event *c)
+{
+	struct xfrm_usersa_flush *p;
+	struct nlmsghdr *nlh;
+	struct sk_buff *skb;
+	unsigned char *b;
+	int len = NLMSG_LENGTH(sizeof(struct xfrm_usersa_flush));
+
+	skb = alloc_skb(len, GFP_ATOMIC);
+	if (skb == NULL)
+		return -ENOMEM;
+	b = skb->tail;
+
+	nlh = NLMSG_PUT(skb, c->pid, c->seq,
+			XFRM_MSG_FLUSHSA, sizeof(*p));
+	nlh->nlmsg_flags = 0;
+
+	p = NLMSG_DATA(nlh);
+	p->proto = c->data.proto;
+
+	nlh->nlmsg_len = skb->tail - b;
+
+	return netlink_broadcast(xfrm_nl, skb, 0, XFRMGRP_SA, GFP_ATOMIC);
+
+nlmsg_failure:
+	kfree_skb(skb);
+	return -1;
+}
+
+static int inline xfrm_sa_len(struct xfrm_state *x)
+{
+	int l = 0;
+	if (x->aalg)
+		l += RTA_SPACE(sizeof(*x->aalg) + (x->aalg->alg_key_len+7)/8);
+	if (x->ealg)
+		l += RTA_SPACE(sizeof(*x->ealg) + (x->ealg->alg_key_len+7)/8);
+	if (x->calg)
+		l += RTA_SPACE(sizeof(*x->calg));
+	if (x->encap)
+		l += RTA_SPACE(sizeof(*x->encap));
+
+	return l;
+}
+
+static int xfrm_notify_sa(struct xfrm_state *x, struct km_event *c)
+{
+	struct xfrm_usersa_info *p;
+	struct xfrm_usersa_id *id;
+	struct nlmsghdr *nlh;
+	struct sk_buff *skb;
+	unsigned char *b;
+	int len = xfrm_sa_len(x);
+	int headlen;
+
+	headlen = sizeof(*p);
+	if (c->event == XFRM_MSG_DELSA) {
+		len += RTA_SPACE(headlen);
+		headlen = sizeof(*id);
+	}
+	len += NLMSG_SPACE(headlen);
+
+	skb = alloc_skb(len, GFP_ATOMIC);
+	if (skb == NULL)
+		return -ENOMEM;
+	b = skb->tail;
+
+	nlh = NLMSG_PUT(skb, c->pid, c->seq, c->event, headlen);
+	nlh->nlmsg_flags = 0;
+
+	p = NLMSG_DATA(nlh);
+	if (c->event == XFRM_MSG_DELSA) {
+		id = NLMSG_DATA(nlh);
+		memcpy(&id->daddr, &x->id.daddr, sizeof(id->daddr));
+		id->spi = x->id.spi;
+		id->family = x->props.family;
+		id->proto = x->id.proto;
+
+		p = RTA_DATA(__RTA_PUT(skb, XFRMA_SA, sizeof(*p)));
+	}
+
+	copy_to_user_state(x, p);
+
+	if (x->aalg)
+		RTA_PUT(skb, XFRMA_ALG_AUTH,
+			sizeof(*(x->aalg))+(x->aalg->alg_key_len+7)/8, x->aalg);
+	if (x->ealg)
+		RTA_PUT(skb, XFRMA_ALG_CRYPT,
+			sizeof(*(x->ealg))+(x->ealg->alg_key_len+7)/8, x->ealg);
+	if (x->calg)
+		RTA_PUT(skb, XFRMA_ALG_COMP, sizeof(*(x->calg)), x->calg);
+
+	if (x->encap)
+		RTA_PUT(skb, XFRMA_ENCAP, sizeof(*x->encap), x->encap);
+
+	nlh->nlmsg_len = skb->tail - b;
+
+	return netlink_broadcast(xfrm_nl, skb, 0, XFRMGRP_SA, GFP_ATOMIC);
+
+nlmsg_failure:
+rtattr_failure:
+	kfree_skb(skb);
+	return -1;
+}
+
+static int xfrm_send_state_notify(struct xfrm_state *x, struct km_event *c)
+{
+
+	switch (c->event) {
+	case XFRM_MSG_EXPIRE:
+		return xfrm_exp_state_notify(x, c);
+	case XFRM_MSG_DELSA:
+	case XFRM_MSG_UPDSA:
+	case XFRM_MSG_NEWSA:
+		return xfrm_notify_sa(x, c);
+	case XFRM_MSG_FLUSHSA:
+		return xfrm_notify_sa_flush(c);
+	default:
+		 printk("xfrm_user: Unknown SA event %d\n", c->event);
+		 break;
+	}
+
+	return 0;
+
+}
+
 static int build_acquire(struct sk_buff *skb, struct xfrm_state *x,
 			 struct xfrm_tmpl *xt, struct xfrm_policy *xp,
 			 int dir)
@@ -1180,6 +1350,9 @@ static struct xfrm_policy *xfrm_compile_
 	if (nr > XFRM_MAX_DEPTH)
 		return NULL;
 
+	if (p->dir > XFRM_POLICY_OUT)
+		return NULL;
+
 	xp = xfrm_policy_alloc(GFP_KERNEL);
 	if (xp == NULL) {
 		*dir = -ENOBUFS;
@@ -1218,7 +1391,7 @@ nlmsg_failure:
 	return -1;
 }
 
-static int xfrm_send_policy_notify(struct xfrm_policy *xp, int dir, int hard)
+static int xfrm_exp_policy_notify(struct xfrm_policy *xp, int dir, struct km_event *c)
 {
 	struct sk_buff *skb;
 	size_t len;
@@ -1229,7 +1402,7 @@ static int xfrm_send_policy_notify(struc
 	if (skb == NULL)
 		return -ENOMEM;
 
-	if (build_polexpire(skb, xp, dir, hard) < 0)
+	if (build_polexpire(skb, xp, dir, c->data.hard) < 0)
 		BUG();
 
 	NETLINK_CB(skb).dst_groups = XFRMGRP_EXPIRE;
@@ -1237,6 +1410,103 @@ static int xfrm_send_policy_notify(struc
 	return netlink_broadcast(xfrm_nl, skb, 0, XFRMGRP_EXPIRE, GFP_ATOMIC);
 }
 
+static int xfrm_notify_policy(struct xfrm_policy *xp, int dir, struct km_event *c)
+{
+	struct xfrm_userpolicy_info *p;
+	struct xfrm_userpolicy_id *id;
+	struct nlmsghdr *nlh;
+	struct sk_buff *skb;
+	unsigned char *b;
+	int len = RTA_SPACE(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr);
+	int headlen;
+
+	headlen = sizeof(*p);
+	if (c->event == XFRM_MSG_DELPOLICY) {
+		len += RTA_SPACE(headlen);
+		headlen = sizeof(*id);
+	}
+	len += NLMSG_SPACE(headlen);
+
+	skb = alloc_skb(len, GFP_ATOMIC);
+	if (skb == NULL)
+		return -ENOMEM;
+	b = skb->tail;
+
+	nlh = NLMSG_PUT(skb, c->pid, c->seq, c->event, headlen);
+
+	p = NLMSG_DATA(nlh);
+	if (c->event == XFRM_MSG_DELPOLICY) {
+		id = NLMSG_DATA(nlh);
+		memset(id, 0, sizeof(*id));
+		id->dir = dir;
+		if (c->data.byid)
+			id->index = xp->index;
+		else
+			memcpy(&id->sel, &xp->selector, sizeof(id->sel));
+
+		p = RTA_DATA(__RTA_PUT(skb, XFRMA_POLICY, sizeof(*p)));
+	}
+
+	nlh->nlmsg_flags = 0;
+
+	copy_to_user_policy(xp, p, dir);
+	if (copy_to_user_tmpl(xp, skb) < 0)
+		goto nlmsg_failure;
+
+	nlh->nlmsg_len = skb->tail - b;
+
+	return netlink_broadcast(xfrm_nl, skb, 0, XFRMGRP_POLICY, GFP_ATOMIC);
+
+nlmsg_failure:
+rtattr_failure:
+	kfree_skb(skb);
+	return -1;
+}
+
+static int xfrm_notify_policy_flush(struct km_event *c)
+{
+	struct nlmsghdr *nlh;
+	struct sk_buff *skb;
+	unsigned char *b;
+	int len = NLMSG_LENGTH(0);
+
+	skb = alloc_skb(len, GFP_ATOMIC);
+	if (skb == NULL)
+		return -ENOMEM;
+	b = skb->tail;
+
+
+	nlh = NLMSG_PUT(skb, c->pid, c->seq, XFRM_MSG_FLUSHPOLICY, 0);
+
+	nlh->nlmsg_len = skb->tail - b;
+
+	return netlink_broadcast(xfrm_nl, skb, 0, XFRMGRP_POLICY, GFP_ATOMIC);
+
+nlmsg_failure:
+	kfree_skb(skb);
+	return -1;
+}
+
+static int xfrm_send_policy_notify(struct xfrm_policy *xp, int dir, struct km_event *c)
+{
+
+	switch (c->event) {
+	case XFRM_MSG_NEWPOLICY:
+	case XFRM_MSG_UPDPOLICY:
+	case XFRM_MSG_DELPOLICY:
+		return xfrm_notify_policy(xp, dir, c);
+	case XFRM_MSG_FLUSHPOLICY:
+		return xfrm_notify_policy_flush(c);
+	case XFRM_MSG_POLEXPIRE:
+		return xfrm_exp_policy_notify(xp, dir, c);
+	default:
+		printk("xfrm_user: Unknown Policy event %d\n", c->event);
+	}
+
+	return 0;
+
+}
+
 static struct xfrm_mgr netlink_mgr = {
 	.id		= "netlink",
 	.notify		= xfrm_send_state_notify,
diff --git a/scripts/Lindent b/scripts/Lindent
--- a/scripts/Lindent
+++ b/scripts/Lindent
@@ -1,2 +1,2 @@
 #!/bin/sh
-indent -kr -i8 -ts8 -sob -l80 -ss -ncs "$@"
+indent -npro -kr -i8 -ts8 -sob -l80 -ss -ncs "$@"
diff --git a/scripts/Makefile.build b/scripts/Makefile.build
--- a/scripts/Makefile.build
+++ b/scripts/Makefile.build
@@ -176,10 +176,10 @@ endif
 define rule_cc_o_c
 	$(if $($(quiet)cmd_checksrc),echo '  $($(quiet)cmd_checksrc)';)   \
 	$(cmd_checksrc)							  \
-	$(if $($(quiet)cmd_cc_o_c),echo '  $($(quiet)cmd_cc_o_c)';)	  \
+	$(if $($(quiet)cmd_cc_o_c),echo '  $(subst ','\'',$($(quiet)cmd_cc_o_c))';)  \
 	$(cmd_cc_o_c);							  \
 	$(cmd_modversions)						  \
-	scripts/basic/fixdep $(depfile) $@ '$(cmd_cc_o_c)' > $(@D)/.$(@F).tmp;  \
+	scripts/basic/fixdep $(depfile) $@ '$(subst ','\'',$(cmd_cc_o_c))' > $(@D)/.$(@F).tmp;  \
 	rm -f $(depfile);						  \
 	mv -f $(@D)/.$(@F).tmp $(@D)/.$(@F).cmd
 endef
diff --git a/scripts/basic/docproc.c b/scripts/basic/docproc.c
--- a/scripts/basic/docproc.c
+++ b/scripts/basic/docproc.c
@@ -52,7 +52,7 @@ FILEONLY *internalfunctions;
 FILEONLY *externalfunctions;
 FILEONLY *symbolsonly;
 
-typedef void FILELINE(char * file, signed char * line);
+typedef void FILELINE(char * file, char * line);
 FILELINE * singlefunctions;
 FILELINE * entity_system;
 
@@ -148,9 +148,9 @@ struct symfile * filename_exist(char * f
  * Files are separated by tabs.
  */
 void adddep(char * file)		   { printf("\t%s", file); }
-void adddep2(char * file, signed char * line)     { line = line; adddep(file); }
+void adddep2(char * file, char * line)     { line = line; adddep(file); }
 void noaction(char * line)		   { line = line; }
-void noaction2(char * file, signed char * line)   { file = file; line = line; }
+void noaction2(char * file, char * line)   { file = file; line = line; }
 
 /* Echo the line without further action */
 void printline(char * line)               { printf("%s", line); }
@@ -179,8 +179,8 @@ void find_export_symbols(char * filename
 			perror(real_filename);
 		}
 		while(fgets(line, MAXLINESZ, fp)) {
-			signed char *p;
-			signed char *e;
+			char *p;
+			char *e;
 			if (((p = strstr(line, "EXPORT_SYMBOL_GPL")) != 0) ||
                             ((p = strstr(line, "EXPORT_SYMBOL")) != 0)) {
 				/* Skip EXPORT_SYMBOL{_GPL} */
@@ -253,7 +253,7 @@ void extfunc(char * filename) { docfunct
  * Call kernel-doc with the following parameters:
  * kernel-doc -docbook -function function1 [-function function2]
  */
-void singfunc(char * filename, signed char * line)
+void singfunc(char * filename, char * line)
 {
 	char *vec[200]; /* Enough for specific functions */
         int i, idx = 0;
@@ -290,7 +290,7 @@ void singfunc(char * filename, signed ch
 void parse_file(FILE *infile)
 {
 	char line[MAXLINESZ];
-	signed char * s;
+	char * s;
 	while(fgets(line, MAXLINESZ, infile)) {
 		if (line[0] == '!') {
 			s = line + 2;
diff --git a/scripts/basic/fixdep.c b/scripts/basic/fixdep.c
--- a/scripts/basic/fixdep.c
+++ b/scripts/basic/fixdep.c
@@ -212,23 +212,23 @@ void use_config(char *m, int slen)
 		if (*p == '_')
 			*p = '/';
 		else
-			*p = tolower((unsigned char)*p);
+			*p = tolower((int)*p);
 	}
 	printf("    $(wildcard include/config/%s.h) \\\n", s);
 }
 
-void parse_config_file(signed char *map, size_t len)
+void parse_config_file(char *map, size_t len)
 {
 	int *end = (int *) (map + len);
 	/* start at +1, so that p can never be < map */
 	int *m   = (int *) map + 1;
-	signed char *p, *q;
+	char *p, *q;
 
 	for (; m < end; m++) {
-		if (*m == INT_CONF) { p = (signed char *) m  ; goto conf; }
-		if (*m == INT_ONFI) { p = (signed char *) m-1; goto conf; }
-		if (*m == INT_NFIG) { p = (signed char *) m-2; goto conf; }
-		if (*m == INT_FIG_) { p = (signed char *) m-3; goto conf; }
+		if (*m == INT_CONF) { p = (char *) m  ; goto conf; }
+		if (*m == INT_ONFI) { p = (char *) m-1; goto conf; }
+		if (*m == INT_NFIG) { p = (char *) m-2; goto conf; }
+		if (*m == INT_FIG_) { p = (char *) m-3; goto conf; }
 		continue;
 	conf:
 		if (p > map + len - 7)
@@ -291,9 +291,9 @@ void do_config_file(char *filename)
 
 void parse_dep_file(void *map, size_t len)
 {
-	signed char *m = map;
-	signed char *end = m + len;
-	signed char *p;
+	char *m = map;
+	char *end = m + len;
+	char *p;
 	char s[PATH_MAX];
 
 	p = strchr(m, ':');
diff --git a/scripts/basic/split-include.c b/scripts/basic/split-include.c
--- a/scripts/basic/split-include.c
+++ b/scripts/basic/split-include.c
@@ -104,7 +104,7 @@ int main(int argc, const char * argv [])
     /* Read config lines. */
     while (fgets(line, buffer_size, fp_config))
     {
-	const signed char * str_config;
+	const char * str_config;
 	int is_same;
 	int itarget;
 
diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c
--- a/scripts/kconfig/conf.c
+++ b/scripts/kconfig/conf.c
@@ -31,14 +31,14 @@ char *defconfig_file;
 static int indent = 1;
 static int valid_stdin = 1;
 static int conf_cnt;
-static signed char line[128];
+static char line[128];
 static struct menu *rootEntry;
 
 static char nohelp_text[] = N_("Sorry, no help available for this option yet.\n");
 
-static void strip(signed char *str)
+static void strip(char *str)
 {
-	signed char *p = str;
+	char *p = str;
 	int l;
 
 	while ((isspace(*p)))
diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c
--- a/scripts/kconfig/confdata.c
+++ b/scripts/kconfig/confdata.c
@@ -27,10 +27,10 @@ const char *conf_confnames[] = {
 	NULL,
 };
 
-static char *conf_expand_value(const signed char *in)
+static char *conf_expand_value(const char *in)
 {
 	struct symbol *sym;
-	const signed char *src;
+	const char *src;
 	static char res_value[SYMBOL_MAXLENGTH];
 	char *dst, name[SYMBOL_MAXLENGTH];
 
diff --git a/scripts/kconfig/gconf.c b/scripts/kconfig/gconf.c
--- a/scripts/kconfig/gconf.c
+++ b/scripts/kconfig/gconf.c
@@ -178,17 +178,31 @@ const char *dbg_print_ptype(int val)
 }
 
 
-/* Main Window Initialization */
+void replace_button_icon(GladeXML * xml, GdkDrawable * window,
+			 GtkStyle * style, gchar * btn_name, gchar ** xpm)
+{
+	GdkPixmap *pixmap;
+	GdkBitmap *mask;
+	GtkToolButton *button;
+	GtkWidget *image;
 
+	pixmap = gdk_pixmap_create_from_xpm_d(window, &mask,
+					      &style->bg[GTK_STATE_NORMAL],
+					      xpm);
+
+	button = GTK_TOOL_BUTTON(glade_xml_get_widget(xml, btn_name));
+	image = gtk_image_new_from_pixmap(pixmap, mask);
+	gtk_widget_show(image);
+	gtk_tool_button_set_icon_widget(button, image);
+}
 
+/* Main Window Initialization */
 void init_main_window(const gchar * glade_file)
 {
 	GladeXML *xml;
 	GtkWidget *widget;
 	GtkTextBuffer *txtbuf;
 	char title[256];
-	GdkPixmap *pixmap;
-	GdkBitmap *mask;
 	GtkStyle *style;
 
 	xml = glade_xml_new(glade_file, "window1", NULL);
@@ -221,36 +235,22 @@ void init_main_window(const gchar * glad
 	style = gtk_widget_get_style(main_wnd);
 	widget = glade_xml_get_widget(xml, "toolbar1");
 
-	pixmap = gdk_pixmap_create_from_xpm_d(main_wnd->window, &mask,
-					      &style->bg[GTK_STATE_NORMAL],
-					      (gchar **) xpm_single_view);
-	gtk_image_set_from_pixmap(GTK_IMAGE
-				  (((GtkToolbarChild
-				     *) (g_list_nth(GTK_TOOLBAR(widget)->
-						    children,
-						    5)->data))->icon),
-				  pixmap, mask);
-	pixmap =
-	    gdk_pixmap_create_from_xpm_d(main_wnd->window, &mask,
-					 &style->bg[GTK_STATE_NORMAL],
-					 (gchar **) xpm_split_view);
-	gtk_image_set_from_pixmap(GTK_IMAGE
-				  (((GtkToolbarChild
-				     *) (g_list_nth(GTK_TOOLBAR(widget)->
-						    children,
-						    6)->data))->icon),
-				  pixmap, mask);
-	pixmap =
-	    gdk_pixmap_create_from_xpm_d(main_wnd->window, &mask,
-					 &style->bg[GTK_STATE_NORMAL],
-					 (gchar **) xpm_tree_view);
-	gtk_image_set_from_pixmap(GTK_IMAGE
-				  (((GtkToolbarChild
-				     *) (g_list_nth(GTK_TOOLBAR(widget)->
-						    children,
-						    7)->data))->icon),
-				  pixmap, mask);
+#if 0	/* Use stock Gtk icons instead */
+	replace_button_icon(xml, main_wnd->window, style,
+			    "button1", (gchar **) xpm_back);
+	replace_button_icon(xml, main_wnd->window, style,
+			    "button2", (gchar **) xpm_load);
+	replace_button_icon(xml, main_wnd->window, style,
+			    "button3", (gchar **) xpm_save);
+#endif
+	replace_button_icon(xml, main_wnd->window, style,
+			    "button4", (gchar **) xpm_single_view);
+	replace_button_icon(xml, main_wnd->window, style,
+			    "button5", (gchar **) xpm_split_view);
+	replace_button_icon(xml, main_wnd->window, style,
+			    "button6", (gchar **) xpm_tree_view);
 
+#if 0
 	switch (view_mode) {
 	case SINGLE_VIEW:
 		widget = glade_xml_get_widget(xml, "button4");
@@ -265,7 +265,7 @@ void init_main_window(const gchar * glad
 		g_signal_emit_by_name(widget, "clicked");
 		break;
 	}
-
+#endif
 	txtbuf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_w));
 	tag1 = gtk_text_buffer_create_tag(txtbuf, "mytag1",
 					  "foreground", "red",
@@ -322,7 +322,7 @@ void init_left_tree(void)
 	gtk_tree_view_set_model(view, model1);
 	gtk_tree_view_set_headers_visible(view, TRUE);
 	gtk_tree_view_set_rules_hint(view, FALSE);
-	
+
 	column = gtk_tree_view_column_new();
 	gtk_tree_view_append_column(view, column);
 	gtk_tree_view_column_set_title(column, _("Options"));
@@ -334,11 +334,11 @@ void init_left_tree(void)
 					    renderer,
 					    "active", COL_BTNACT,
 					    "inconsistent", COL_BTNINC,
-					    "visible", COL_BTNVIS, 
+					    "visible", COL_BTNVIS,
 					    "radio", COL_BTNRAD, NULL);
 	renderer = gtk_cell_renderer_text_new();
 	gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column),
-					renderer, FALSE);	
+					renderer, FALSE);
 	gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column),
 					    renderer,
 					    "text", COL_OPTION,
@@ -386,7 +386,7 @@ void init_right_tree(void)
 					    renderer,
 					    "active", COL_BTNACT,
 					    "inconsistent", COL_BTNINC,
-					    "visible", COL_BTNVIS, 
+					    "visible", COL_BTNVIS,
 					    "radio", COL_BTNRAD, NULL);
 	/*g_signal_connect(G_OBJECT(renderer), "toggled",
 	   G_CALLBACK(renderer_toggled), NULL); */
@@ -806,7 +806,7 @@ void on_license1_activate(GtkMenuItem * 
 }
 
 
-void on_back_pressed(GtkButton * button, gpointer user_data)
+void on_back_clicked(GtkButton * button, gpointer user_data)
 {
 	enum prop_type ptype;
 
@@ -821,13 +821,13 @@ void on_back_pressed(GtkButton * button,
 }
 
 
-void on_load_pressed(GtkButton * button, gpointer user_data)
+void on_load_clicked(GtkButton * button, gpointer user_data)
 {
 	on_load1_activate(NULL, user_data);
 }
 
 
-void on_save_pressed(GtkButton * button, gpointer user_data)
+void on_save_clicked(GtkButton * button, gpointer user_data)
 {
 	on_save1_activate(NULL, user_data);
 }
@@ -850,9 +850,12 @@ void on_split_clicked(GtkButton * button
 	gtk_widget_show(tree1_w);
 	gtk_window_get_default_size(GTK_WINDOW(main_wnd), &w, &h);
 	gtk_paned_set_position(GTK_PANED(hpaned), w / 2);
-	if (tree2)	
+	if (tree2)
 		gtk_tree_store_clear(tree2);
 	display_list();
+
+	/* Disable back btn, like in full mode. */
+	gtk_widget_set_sensitive(back_btn, FALSE);
 }
 
 
@@ -868,13 +871,13 @@ void on_full_clicked(GtkButton * button,
 }
 
 
-void on_collapse_pressed(GtkButton * button, gpointer user_data)
+void on_collapse_clicked(GtkButton * button, gpointer user_data)
 {
 	gtk_tree_view_collapse_all(GTK_TREE_VIEW(tree2_w));
 }
 
 
-void on_expand_pressed(GtkButton * button, gpointer user_data)
+void on_expand_clicked(GtkButton * button, gpointer user_data)
 {
 	gtk_tree_view_expand_all(GTK_TREE_VIEW(tree2_w));
 }
@@ -1242,13 +1245,13 @@ static gchar **fill_row(struct menu *men
 			row[COL_VALUE] =
 			    g_strdup(menu_get_prompt(def_menu));
 	}
-	if(sym->flags & SYMBOL_CHOICEVAL)
+	if (sym->flags & SYMBOL_CHOICEVAL)
 		row[COL_BTNRAD] = GINT_TO_POINTER(TRUE);
 
 	stype = sym_get_type(sym);
 	switch (stype) {
 	case S_BOOLEAN:
-		if(GPOINTER_TO_INT(row[COL_PIXVIS]) == FALSE)
+		if (GPOINTER_TO_INT(row[COL_PIXVIS]) == FALSE)
 			row[COL_BTNVIS] = GINT_TO_POINTER(TRUE);
 		if (sym_is_choice(sym))
 			break;
@@ -1423,7 +1426,7 @@ static void update_tree(struct menu *src
 								 child2);
 				gtk_tree_store_remove(tree2, &tmp);
 				if (!valid)
-					return;	// next parent 
+					return;	// next parent
 				else
 					goto reparse;	// next child
 			} else
@@ -1448,7 +1451,7 @@ static void update_tree(struct menu *src
 								 child2);
 				gtk_tree_store_remove(tree2, &tmp);
 				if (!valid)
-					return;	// next parent 
+					return;	// next parent
 				else
 					goto reparse;	// next child
 			}
@@ -1486,12 +1489,12 @@ static void display_tree(struct menu *me
 		if (sym)
 			sym->flags &= ~SYMBOL_CHANGED;
 
-		if ((view_mode == SPLIT_VIEW) && !(child->flags & MENU_ROOT) &&
-		    (tree == tree1))
+		if ((view_mode == SPLIT_VIEW)
+		    && !(child->flags & MENU_ROOT) && (tree == tree1))
 			continue;
 
-		if ((view_mode == SPLIT_VIEW) && (child->flags & MENU_ROOT) &&
-		    (tree == tree2))
+		if ((view_mode == SPLIT_VIEW) && (child->flags & MENU_ROOT)
+		    && (tree == tree2))
 			continue;
 
 		if (menu_is_visible(child) || show_all)
@@ -1513,11 +1516,12 @@ static void display_tree(struct menu *me
 		    && (tree == tree2))
 			continue;
 /*
-		if (((menu != &rootmenu) && !(menu->flags & MENU_ROOT)) ||
-		    (view_mode == FULL_VIEW)
+                if (((menu != &rootmenu) && !(menu->flags & MENU_ROOT))
+		    || (view_mode == FULL_VIEW)
 		    || (view_mode == SPLIT_VIEW))*/
 		if (((view_mode == SINGLE_VIEW) && (menu->flags & MENU_ROOT))
-		    || (view_mode == FULL_VIEW) || (view_mode == SPLIT_VIEW)) {
+		    || (view_mode == FULL_VIEW)
+		    || (view_mode == SPLIT_VIEW)) {
 			indent++;
 			display_tree(child);
 			indent--;
@@ -1530,9 +1534,9 @@ static void display_tree_part(void)
 {
 	if (tree2)
 		gtk_tree_store_clear(tree2);
-	if(view_mode == SINGLE_VIEW)
+	if (view_mode == SINGLE_VIEW)
 		display_tree(current);
- 	else if(view_mode == SPLIT_VIEW)
+	else if (view_mode == SPLIT_VIEW)
 		display_tree(browsed);
 	gtk_tree_view_expand_all(GTK_TREE_VIEW(tree2_w));
 }
@@ -1551,24 +1555,22 @@ static void display_list(void)
 
 void fixup_rootmenu(struct menu *menu)
 {
-        struct menu *child;
-        static int menu_cnt = 0;
+	struct menu *child;
+	static int menu_cnt = 0;
 
-        menu->flags |= MENU_ROOT;
-        for (child = menu->list; child; child = child->next) {
-                if (child->prompt && child->prompt->type == P_MENU) {
-                        menu_cnt++;
-                        fixup_rootmenu(child);
-                        menu_cnt--;
-                } else if (!menu_cnt)
-                        fixup_rootmenu(child);
-        }
+	menu->flags |= MENU_ROOT;
+	for (child = menu->list; child; child = child->next) {
+		if (child->prompt && child->prompt->type == P_MENU) {
+			menu_cnt++;
+			fixup_rootmenu(child);
+			menu_cnt--;
+		} else if (!menu_cnt)
+			fixup_rootmenu(child);
+	}
 }
 
 
 /* Main */
-
-
 int main(int ac, char *av[])
 {
 	const char *name;
diff --git a/scripts/kconfig/gconf.glade b/scripts/kconfig/gconf.glade
--- a/scripts/kconfig/gconf.glade
+++ b/scripts/kconfig/gconf.glade
@@ -13,6 +13,11 @@
   <property name="default_height">480</property>
   <property name="resizable">True</property>
   <property name="destroy_with_parent">False</property>
+  <property name="decorated">True</property>
+  <property name="skip_taskbar_hint">False</property>
+  <property name="skip_pager_hint">False</property>
+  <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
+  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
   <signal name="destroy" handler="on_window1_destroy" object="window1"/>
   <signal name="size_request" handler="on_window1_size_request" object="vpaned1" last_modification_time="Fri, 11 Jan 2002 16:17:11 GMT"/>
   <signal name="delete_event" handler="on_window1_delete_event" object="window1" last_modification_time="Sun, 09 Mar 2003 19:42:46 GMT"/>
@@ -46,7 +51,7 @@
 		      <accelerator key="L" modifiers="GDK_CONTROL_MASK" signal="activate"/>
 
 		      <child internal-child="image">
-			<widget class="GtkImage" id="image27">
+			<widget class="GtkImage" id="image39">
 			  <property name="visible">True</property>
 			  <property name="stock">gtk-open</property>
 			  <property name="icon_size">1</property>
@@ -69,7 +74,7 @@
 		      <accelerator key="S" modifiers="GDK_CONTROL_MASK" signal="activate"/>
 
 		      <child internal-child="image">
-			<widget class="GtkImage" id="image28">
+			<widget class="GtkImage" id="image40">
 			  <property name="visible">True</property>
 			  <property name="stock">gtk-save</property>
 			  <property name="icon_size">1</property>
@@ -91,7 +96,7 @@
 		      <signal name="activate" handler="on_save_as1_activate"/>
 
 		      <child internal-child="image">
-			<widget class="GtkImage" id="image29">
+			<widget class="GtkImage" id="image41">
 			  <property name="visible">True</property>
 			  <property name="stock">gtk-save-as</property>
 			  <property name="icon_size">1</property>
@@ -105,7 +110,7 @@
 		  </child>
 
 		  <child>
-		    <widget class="GtkMenuItem" id="separator1">
+		    <widget class="GtkSeparatorMenuItem" id="separator1">
 		      <property name="visible">True</property>
 		    </widget>
 		  </child>
@@ -119,7 +124,7 @@
 		      <accelerator key="Q" modifiers="GDK_CONTROL_MASK" signal="activate"/>
 
 		      <child internal-child="image">
-			<widget class="GtkImage" id="image30">
+			<widget class="GtkImage" id="image42">
 			  <property name="visible">True</property>
 			  <property name="stock">gtk-quit</property>
 			  <property name="icon_size">1</property>
@@ -179,7 +184,7 @@
 		  </child>
 
 		  <child>
-		    <widget class="GtkMenuItem" id="separator2">
+		    <widget class="GtkSeparatorMenuItem" id="separator2">
 		      <property name="visible">True</property>
 		    </widget>
 		  </child>
@@ -228,7 +233,7 @@
 		      <accelerator key="I" modifiers="GDK_CONTROL_MASK" signal="activate"/>
 
 		      <child internal-child="image">
-			<widget class="GtkImage" id="image31">
+			<widget class="GtkImage" id="image43">
 			  <property name="visible">True</property>
 			  <property name="stock">gtk-dialog-question</property>
 			  <property name="icon_size">1</property>
@@ -250,7 +255,7 @@
 		      <accelerator key="A" modifiers="GDK_CONTROL_MASK" signal="activate"/>
 
 		      <child internal-child="image">
-			<widget class="GtkImage" id="image32">
+			<widget class="GtkImage" id="image44">
 			  <property name="visible">True</property>
 			  <property name="stock">gtk-properties</property>
 			  <property name="icon_size">1</property>
@@ -271,7 +276,7 @@
 		      <signal name="activate" handler="on_license1_activate" last_modification_time="Fri, 15 Nov 2002 20:26:30 GMT"/>
 
 		      <child internal-child="image">
-			<widget class="GtkImage" id="image33">
+			<widget class="GtkImage" id="image45">
 			  <property name="visible">True</property>
 			  <property name="stock">gtk-justify-fill</property>
 			  <property name="icon_size">1</property>
@@ -308,109 +313,207 @@
 	      <property name="orientation">GTK_ORIENTATION_HORIZONTAL</property>
 	      <property name="toolbar_style">GTK_TOOLBAR_BOTH</property>
 	      <property name="tooltips">True</property>
+	      <property name="show_arrow">True</property>
 
 	      <child>
-		<widget class="button" id="button1">
+		<widget class="GtkToolButton" id="button1">
 		  <property name="visible">True</property>
 		  <property name="tooltip" translatable="yes">Goes up of one level (single view)</property>
 		  <property name="label" translatable="yes">Back</property>
 		  <property name="use_underline">True</property>
-		  <property name="stock_pixmap">gtk-undo</property>
-		  <signal name="pressed" handler="on_back_pressed"/>
+		  <property name="stock_id">gtk-undo</property>
+		  <property name="visible_horizontal">True</property>
+		  <property name="visible_vertical">True</property>
+		  <property name="is_important">False</property>
+		  <signal name="clicked" handler="on_back_clicked"/>
 		</widget>
+		<packing>
+		  <property name="expand">False</property>
+		  <property name="homogeneous">True</property>
+		</packing>
 	      </child>
 
 	      <child>
-		<widget class="GtkVSeparator" id="vseparator1">
+		<widget class="GtkToolItem" id="toolitem1">
 		  <property name="visible">True</property>
+		  <property name="visible_horizontal">True</property>
+		  <property name="visible_vertical">True</property>
+		  <property name="is_important">False</property>
+
+		  <child>
+		    <widget class="GtkVSeparator" id="vseparator1">
+		      <property name="visible">True</property>
+		    </widget>
+		  </child>
 		</widget>
+		<packing>
+		  <property name="expand">False</property>
+		  <property name="homogeneous">False</property>
+		</packing>
 	      </child>
 
 	      <child>
-		<widget class="button" id="button2">
+		<widget class="GtkToolButton" id="button2">
 		  <property name="visible">True</property>
 		  <property name="tooltip" translatable="yes">Load a config file</property>
 		  <property name="label" translatable="yes">Load</property>
 		  <property name="use_underline">True</property>
-		  <property name="stock_pixmap">gtk-open</property>
-		  <signal name="pressed" handler="on_load_pressed"/>
+		  <property name="stock_id">gtk-open</property>
+		  <property name="visible_horizontal">True</property>
+		  <property name="visible_vertical">True</property>
+		  <property name="is_important">False</property>
+		  <signal name="clicked" handler="on_load_clicked"/>
 		</widget>
+		<packing>
+		  <property name="expand">False</property>
+		  <property name="homogeneous">True</property>
+		</packing>
 	      </child>
 
 	      <child>
-		<widget class="button" id="button3">
+		<widget class="GtkToolButton" id="button3">
 		  <property name="visible">True</property>
 		  <property name="tooltip" translatable="yes">Save a config file</property>
 		  <property name="label" translatable="yes">Save</property>
 		  <property name="use_underline">True</property>
-		  <property name="stock_pixmap">gtk-save</property>
-		  <signal name="pressed" handler="on_save_pressed"/>
+		  <property name="stock_id">gtk-save</property>
+		  <property name="visible_horizontal">True</property>
+		  <property name="visible_vertical">True</property>
+		  <property name="is_important">False</property>
+		  <signal name="clicked" handler="on_save_clicked"/>
 		</widget>
+		<packing>
+		  <property name="expand">False</property>
+		  <property name="homogeneous">True</property>
+		</packing>
 	      </child>
 
 	      <child>
-		<widget class="GtkVSeparator" id="vseparator2">
+		<widget class="GtkToolItem" id="toolitem2">
 		  <property name="visible">True</property>
+		  <property name="visible_horizontal">True</property>
+		  <property name="visible_vertical">True</property>
+		  <property name="is_important">False</property>
+
+		  <child>
+		    <widget class="GtkVSeparator" id="vseparator2">
+		      <property name="visible">True</property>
+		    </widget>
+		  </child>
 		</widget>
+		<packing>
+		  <property name="expand">False</property>
+		  <property name="homogeneous">False</property>
+		</packing>
 	      </child>
 
 	      <child>
-		<widget class="button" id="button4">
+		<widget class="GtkToolButton" id="button4">
 		  <property name="visible">True</property>
 		  <property name="tooltip" translatable="yes">Single view</property>
 		  <property name="label" translatable="yes">Single</property>
 		  <property name="use_underline">True</property>
-		  <property name="stock_pixmap">gtk-missing-image</property>
+		  <property name="stock_id">gtk-missing-image</property>
+		  <property name="visible_horizontal">True</property>
+		  <property name="visible_vertical">True</property>
+		  <property name="is_important">False</property>
 		  <signal name="clicked" handler="on_single_clicked" last_modification_time="Sun, 12 Jan 2003 14:28:39 GMT"/>
 		</widget>
+		<packing>
+		  <property name="expand">False</property>
+		  <property name="homogeneous">True</property>
+		</packing>
 	      </child>
 
 	      <child>
-		<widget class="button" id="button5">
+		<widget class="GtkToolButton" id="button5">
 		  <property name="visible">True</property>
 		  <property name="tooltip" translatable="yes">Split view</property>
 		  <property name="label" translatable="yes">Split</property>
 		  <property name="use_underline">True</property>
-		  <property name="stock_pixmap">gtk-missing-image</property>
+		  <property name="stock_id">gtk-missing-image</property>
+		  <property name="visible_horizontal">True</property>
+		  <property name="visible_vertical">True</property>
+		  <property name="is_important">False</property>
 		  <signal name="clicked" handler="on_split_clicked" last_modification_time="Sun, 12 Jan 2003 14:28:45 GMT"/>
 		</widget>
+		<packing>
+		  <property name="expand">False</property>
+		  <property name="homogeneous">True</property>
+		</packing>
 	      </child>
 
 	      <child>
-		<widget class="button" id="button6">
+		<widget class="GtkToolButton" id="button6">
 		  <property name="visible">True</property>
 		  <property name="tooltip" translatable="yes">Full view</property>
 		  <property name="label" translatable="yes">Full</property>
 		  <property name="use_underline">True</property>
-		  <property name="stock_pixmap">gtk-missing-image</property>
+		  <property name="stock_id">gtk-missing-image</property>
+		  <property name="visible_horizontal">True</property>
+		  <property name="visible_vertical">True</property>
+		  <property name="is_important">False</property>
 		  <signal name="clicked" handler="on_full_clicked" last_modification_time="Sun, 12 Jan 2003 14:28:50 GMT"/>
 		</widget>
+		<packing>
+		  <property name="expand">False</property>
+		  <property name="homogeneous">True</property>
+		</packing>
 	      </child>
 
 	      <child>
-		<widget class="GtkVSeparator" id="vseparator3">
+		<widget class="GtkToolItem" id="toolitem3">
 		  <property name="visible">True</property>
+		  <property name="visible_horizontal">True</property>
+		  <property name="visible_vertical">True</property>
+		  <property name="is_important">False</property>
+
+		  <child>
+		    <widget class="GtkVSeparator" id="vseparator3">
+		      <property name="visible">True</property>
+		    </widget>
+		  </child>
 		</widget>
+		<packing>
+		  <property name="expand">False</property>
+		  <property name="homogeneous">False</property>
+		</packing>
 	      </child>
 
 	      <child>
-		<widget class="button" id="button7">
+		<widget class="GtkToolButton" id="button7">
 		  <property name="visible">True</property>
 		  <property name="tooltip" translatable="yes">Collapse the whole tree in the right frame</property>
 		  <property name="label" translatable="yes">Collapse</property>
 		  <property name="use_underline">True</property>
-		  <signal name="pressed" handler="on_collapse_pressed"/>
+		  <property name="stock_id">gtk-remove</property>
+		  <property name="visible_horizontal">True</property>
+		  <property name="visible_vertical">True</property>
+		  <property name="is_important">False</property>
+		  <signal name="clicked" handler="on_collapse_clicked"/>
 		</widget>
+		<packing>
+		  <property name="expand">False</property>
+		  <property name="homogeneous">True</property>
+		</packing>
 	      </child>
 
 	      <child>
-		<widget class="button" id="button8">
+		<widget class="GtkToolButton" id="button8">
 		  <property name="visible">True</property>
 		  <property name="tooltip" translatable="yes">Expand the whole tree in the right frame</property>
 		  <property name="label" translatable="yes">Expand</property>
 		  <property name="use_underline">True</property>
-		  <signal name="pressed" handler="on_expand_pressed"/>
+		  <property name="stock_id">gtk-add</property>
+		  <property name="visible_horizontal">True</property>
+		  <property name="visible_vertical">True</property>
+		  <property name="is_important">False</property>
+		  <signal name="clicked" handler="on_expand_clicked"/>
 		</widget>
+		<packing>
+		  <property name="expand">False</property>
+		  <property name="homogeneous">True</property>
+		</packing>
 	      </child>
 	    </widget>
 	  </child>
@@ -432,8 +535,8 @@
 	  <child>
 	    <widget class="GtkScrolledWindow" id="scrolledwindow1">
 	      <property name="visible">True</property>
-	      <property name="hscrollbar_policy">GTK_POLICY_ALWAYS</property>
-	      <property name="vscrollbar_policy">GTK_POLICY_ALWAYS</property>
+	      <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+	      <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
 	      <property name="shadow_type">GTK_SHADOW_IN</property>
 	      <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
 
@@ -466,8 +569,8 @@
 	      <child>
 		<widget class="GtkScrolledWindow" id="scrolledwindow2">
 		  <property name="visible">True</property>
-		  <property name="hscrollbar_policy">GTK_POLICY_ALWAYS</property>
-		  <property name="vscrollbar_policy">GTK_POLICY_ALWAYS</property>
+		  <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+		  <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
 		  <property name="shadow_type">GTK_SHADOW_IN</property>
 		  <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
 
@@ -496,7 +599,7 @@
 		<widget class="GtkScrolledWindow" id="scrolledwindow3">
 		  <property name="visible">True</property>
 		  <property name="hscrollbar_policy">GTK_POLICY_NEVER</property>
-		  <property name="vscrollbar_policy">GTK_POLICY_ALWAYS</property>
+		  <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
 		  <property name="shadow_type">GTK_SHADOW_IN</property>
 		  <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
 
@@ -505,6 +608,8 @@
 		      <property name="visible">True</property>
 		      <property name="can_focus">True</property>
 		      <property name="editable">False</property>
+		      <property name="overwrite">False</property>
+		      <property name="accepts_tab">True</property>
 		      <property name="justification">GTK_JUSTIFY_LEFT</property>
 		      <property name="wrap_mode">GTK_WRAP_WORD</property>
 		      <property name="cursor_visible">True</property>
diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c
--- a/scripts/kconfig/mconf.c
+++ b/scripts/kconfig/mconf.c
@@ -20,6 +20,7 @@
 #include <string.h>
 #include <termios.h>
 #include <unistd.h>
+#include <locale.h>
 
 #define LKC_DIRECT_LINK
 #include "lkc.h"
@@ -254,8 +255,8 @@ search_help[] = N_(
 	"          USB$ => find all CONFIG_ symbols ending with USB\n"
 	"\n");
 
-static signed char buf[4096], *bufptr = buf;
-static signed char input_buf[4096];
+static char buf[4096], *bufptr = buf;
+static char input_buf[4096];
 static char filename[PATH_MAX+1] = ".config";
 static char *args[1024], **argptr = args;
 static int indent;
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -25,6 +25,8 @@ typedef Elf64_Addr	kernel_ulong_t;
 #include <stdint.h>
 #endif
 
+#include <ctype.h>
+
 typedef uint32_t	__u32;
 typedef uint16_t	__u16;
 typedef unsigned char	__u8;
@@ -287,6 +289,58 @@ static int do_pnp_card_entry(const char 
 	return 1;
 }
 
+/* Looks like: pcmcia:mNcNfNfnNpfnNvaNvbNvcNvdN. */
+static int do_pcmcia_entry(const char *filename,
+			   struct pcmcia_device_id *id, char *alias)
+{
+	unsigned int i;
+
+	id->manf_id = TO_NATIVE(id->manf_id);
+	id->card_id = TO_NATIVE(id->card_id);
+	id->func_id = TO_NATIVE(id->func_id);
+	id->function = TO_NATIVE(id->function);
+	id->device_no = TO_NATIVE(id->device_no);
+	for (i=0; i<4; i++) {
+		id->prod_id_hash[i] = TO_NATIVE(id->prod_id_hash[i]);
+       }
+
+       strcpy(alias, "pcmcia:");
+       ADD(alias, "m", id->match_flags & PCMCIA_DEV_ID_MATCH_MANF_ID,
+	   id->manf_id);
+       ADD(alias, "c", id->match_flags & PCMCIA_DEV_ID_MATCH_CARD_ID,
+	   id->card_id);
+       ADD(alias, "f", id->match_flags & PCMCIA_DEV_ID_MATCH_FUNC_ID,
+	   id->func_id);
+       ADD(alias, "fn", id->match_flags & PCMCIA_DEV_ID_MATCH_FUNCTION,
+	   id->function);
+       ADD(alias, "pfn", id->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO,
+	   id->device_no);
+       ADD(alias, "pa", id->match_flags & PCMCIA_DEV_ID_MATCH_PROD_ID1, id->prod_id_hash[0]);
+       ADD(alias, "pb", id->match_flags & PCMCIA_DEV_ID_MATCH_PROD_ID2, id->prod_id_hash[1]);
+       ADD(alias, "pc", id->match_flags & PCMCIA_DEV_ID_MATCH_PROD_ID3, id->prod_id_hash[2]);
+       ADD(alias, "pd", id->match_flags & PCMCIA_DEV_ID_MATCH_PROD_ID4, id->prod_id_hash[3]);
+
+       return 1;
+}
+
+
+
+static int do_of_entry (const char *filename, struct of_device_id *of, char *alias)
+{
+    char *tmp;
+    sprintf (alias, "of:N%sT%sC%s",
+                    of->name[0] ? of->name : "*",
+                    of->type[0] ? of->type : "*",
+                    of->compatible[0] ? of->compatible : "*");
+
+    /* Replace all whitespace with underscores */
+    for (tmp = alias; tmp && *tmp; tmp++)
+        if (isspace (*tmp))
+            *tmp = '_';
+
+    return 1;
+}
+
 /* Ignore any prefix, eg. v850 prepends _ */
 static inline int sym_is(const char *symbol, const char *name)
 {
@@ -362,6 +416,13 @@ void handle_moddevtable(struct module *m
 	else if (sym_is(symname, "__mod_pnp_card_device_table"))
 		do_table(symval, sym->st_size, sizeof(struct pnp_card_device_id),
 			 do_pnp_card_entry, mod);
+	else if (sym_is(symname, "__mod_pcmcia_device_table"))
+		do_table(symval, sym->st_size, sizeof(struct pcmcia_device_id),
+			 do_pcmcia_entry, mod);
+        else if (sym_is(symname, "__mod_of_device_table"))
+		do_table(symval, sym->st_size, sizeof(struct of_device_id),
+			 do_of_entry, mod);
+
 }
 
 /* Now add out buffered information to the generated C source */
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -359,11 +359,16 @@ handle_modversions(struct module *mod, s
 		/* ignore __this_module, it will be resolved shortly */
 		if (strcmp(symname, MODULE_SYMBOL_PREFIX "__this_module") == 0)
 			break;
-#ifdef STT_REGISTER
+/* cope with newer glibc (2.3.4 or higher) STT_ definition in elf.h */
+#if defined(STT_REGISTER) || defined(STT_SPARC_REGISTER)
+/* add compatibility with older glibc */
+#ifndef STT_SPARC_REGISTER
+#define STT_SPARC_REGISTER STT_REGISTER
+#endif
 		if (info->hdr->e_machine == EM_SPARC ||
 		    info->hdr->e_machine == EM_SPARCV9) {
 			/* Ignore register directives. */
-			if (ELF_ST_TYPE(sym->st_info) == STT_REGISTER)
+			if (ELF_ST_TYPE(sym->st_info) == STT_SPARC_REGISTER)
 				break;
 		}
 #endif
diff --git a/security/commoncap.c b/security/commoncap.c
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -149,7 +149,7 @@ void cap_bprm_apply_creds (struct linux_
 
 	if (bprm->e_uid != current->uid || bprm->e_gid != current->gid ||
 	    !cap_issubset (new_permitted, current->cap_permitted)) {
-		current->mm->dumpable = 0;
+		current->mm->dumpable = suid_dumpable;
 
 		if (unsafe & ~LSM_UNSAFE_PTRACE_CAP) {
 			if (!capable(CAP_SETUID)) {
diff --git a/security/dummy.c b/security/dummy.c
--- a/security/dummy.c
+++ b/security/dummy.c
@@ -130,7 +130,7 @@ static void dummy_bprm_free_security (st
 static void dummy_bprm_apply_creds (struct linux_binprm *bprm, int unsafe)
 {
 	if (bprm->e_uid != current->uid || bprm->e_gid != current->gid) {
-		current->mm->dumpable = 0;
+		current->mm->dumpable = suid_dumpable;
 
 		if ((unsafe & ~LSM_UNSAFE_PTRACE_CAP) && !capable(CAP_SETUID)) {
 			bprm->e_uid = current->uid;
diff --git a/security/keys/Makefile b/security/keys/Makefile
--- a/security/keys/Makefile
+++ b/security/keys/Makefile
@@ -7,8 +7,9 @@ obj-y := \
 	keyring.o \
 	keyctl.o \
 	process_keys.o \
-	user_defined.o \
-	request_key.o
+	request_key.o \
+	request_key_auth.o \
+	user_defined.o
 
 obj-$(CONFIG_KEYS_COMPAT) += compat.o
 obj-$(CONFIG_PROC_FS) += proc.o
diff --git a/security/keys/compat.c b/security/keys/compat.c
--- a/security/keys/compat.c
+++ b/security/keys/compat.c
@@ -1,6 +1,6 @@
 /* compat.c: 32-bit compatibility syscall for 64-bit systems
  *
- * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Copyright (C) 2004-5 Red Hat, Inc. All Rights Reserved.
  * Written by David Howells (dhowells@redhat.com)
  *
  * This program is free software; you can redistribute it and/or
@@ -24,7 +24,7 @@
  * - if you can, you should call sys_keyctl directly
  */
 asmlinkage long compat_sys_keyctl(u32 option,
-			      u32 arg2, u32 arg3, u32 arg4, u32 arg5)
+				  u32 arg2, u32 arg3, u32 arg4, u32 arg5)
 {
 	switch (option) {
 	case KEYCTL_GET_KEYRING_ID:
@@ -71,6 +71,9 @@ asmlinkage long compat_sys_keyctl(u32 op
 	case KEYCTL_NEGATE:
 		return keyctl_negate_key(arg2, arg3, arg4);
 
+	case KEYCTL_SET_REQKEY_KEYRING:
+		return keyctl_set_reqkey_keyring(arg2);
+
 	default:
 		return -EOPNOTSUPP;
 	}
diff --git a/security/keys/internal.h b/security/keys/internal.h
--- a/security/keys/internal.h
+++ b/security/keys/internal.h
@@ -1,6 +1,6 @@
 /* internal.h: authentication token and access key management internal defs
  *
- * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
+ * Copyright (C) 2003-5 Red Hat, Inc. All Rights Reserved.
  * Written by David Howells (dhowells@redhat.com)
  *
  * This program is free software; you can redistribute it and/or
@@ -15,6 +15,16 @@
 #include <linux/key.h>
 #include <linux/key-ui.h>
 
+#if 0
+#define kenter(FMT, a...)	printk("==> %s("FMT")\n",__FUNCTION__ , ## a)
+#define kleave(FMT, a...)	printk("<== %s()"FMT"\n",__FUNCTION__ , ## a)
+#define kdebug(FMT, a...)	printk(FMT"\n" , ## a)
+#else
+#define kenter(FMT, a...)	do {} while(0)
+#define kleave(FMT, a...)	do {} while(0)
+#define kdebug(FMT, a...)	do {} while(0)
+#endif
+
 extern struct key_type key_type_dead;
 extern struct key_type key_type_user;
 
@@ -66,20 +76,46 @@ extern struct key *__keyring_search_one(
 					const char *description,
 					key_perm_t perm);
 
+extern struct key *keyring_search_instkey(struct key *keyring,
+					  key_serial_t target_id);
+
 typedef int (*key_match_func_t)(const struct key *, const void *);
 
 extern struct key *keyring_search_aux(struct key *keyring,
+				      struct task_struct *tsk,
 				      struct key_type *type,
 				      const void *description,
 				      key_match_func_t match);
 
-extern struct key *search_process_keyrings_aux(struct key_type *type,
-					       const void *description,
-					       key_match_func_t match);
+extern struct key *search_process_keyrings(struct key_type *type,
+					   const void *description,
+					   key_match_func_t match,
+					   struct task_struct *tsk);
 
 extern struct key *find_keyring_by_name(const char *name, key_serial_t bound);
 
 extern int install_thread_keyring(struct task_struct *tsk);
+extern int install_process_keyring(struct task_struct *tsk);
+
+extern struct key *request_key_and_link(struct key_type *type,
+					const char *description,
+					const char *callout_info,
+					struct key *dest_keyring);
+
+/*
+ * request_key authorisation
+ */
+struct request_key_auth {
+	struct key		*target_key;
+	struct task_struct	*context;
+	pid_t			pid;
+};
+
+extern struct key_type key_type_request_key_auth;
+extern struct key *request_key_auth_new(struct key *target,
+					struct key **_rkakey);
+
+extern struct key *key_get_instantiation_authkey(key_serial_t target_id);
 
 /*
  * keyctl functions
@@ -100,6 +136,7 @@ extern long keyctl_setperm_key(key_seria
 extern long keyctl_instantiate_key(key_serial_t, const void __user *,
 				   size_t, key_serial_t);
 extern long keyctl_negate_key(key_serial_t, unsigned, key_serial_t);
+extern long keyctl_set_reqkey_keyring(int);
 
 
 /*
diff --git a/security/keys/key.c b/security/keys/key.c
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -1,6 +1,6 @@
 /* key.c: basic authentication token and access key management
  *
- * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Copyright (C) 2004-5 Red Hat, Inc. All Rights Reserved.
  * Written by David Howells (dhowells@redhat.com)
  *
  * This program is free software; you can redistribute it and/or
@@ -294,7 +294,6 @@ struct key *key_alloc(struct key_type *t
 	}
 
 	atomic_set(&key->usage, 1);
-	rwlock_init(&key->lock);
 	init_rwsem(&key->sem);
 	key->type = type;
 	key->user = user;
@@ -308,7 +307,7 @@ struct key *key_alloc(struct key_type *t
 	key->payload.data = NULL;
 
 	if (!not_in_quota)
-		key->flags |= KEY_FLAG_IN_QUOTA;
+		key->flags |= 1 << KEY_FLAG_IN_QUOTA;
 
 	memset(&key->type_data, 0, sizeof(key->type_data));
 
@@ -359,7 +358,7 @@ int key_payload_reserve(struct key *key,
 	key_check(key);
 
 	/* contemplate the quota adjustment */
-	if (delta != 0 && key->flags & KEY_FLAG_IN_QUOTA) {
+	if (delta != 0 && test_bit(KEY_FLAG_IN_QUOTA, &key->flags)) {
 		spin_lock(&key->user->lock);
 
 		if (delta > 0 &&
@@ -392,7 +391,8 @@ EXPORT_SYMBOL(key_payload_reserve);
 static int __key_instantiate_and_link(struct key *key,
 				      const void *data,
 				      size_t datalen,
-				      struct key *keyring)
+				      struct key *keyring,
+				      struct key *instkey)
 {
 	int ret, awaken;
 
@@ -405,27 +405,25 @@ static int __key_instantiate_and_link(st
 	down_write(&key_construction_sem);
 
 	/* can't instantiate twice */
-	if (!(key->flags & KEY_FLAG_INSTANTIATED)) {
+	if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) {
 		/* instantiate the key */
 		ret = key->type->instantiate(key, data, datalen);
 
 		if (ret == 0) {
 			/* mark the key as being instantiated */
-			write_lock(&key->lock);
-
 			atomic_inc(&key->user->nikeys);
-			key->flags |= KEY_FLAG_INSTANTIATED;
+			set_bit(KEY_FLAG_INSTANTIATED, &key->flags);
 
-			if (key->flags & KEY_FLAG_USER_CONSTRUCT) {
-				key->flags &= ~KEY_FLAG_USER_CONSTRUCT;
+			if (test_and_clear_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags))
 				awaken = 1;
-			}
-
-			write_unlock(&key->lock);
 
 			/* and link it into the destination keyring */
 			if (keyring)
 				ret = __key_link(keyring, key);
+
+			/* disable the authorisation key */
+			if (instkey)
+				key_revoke(instkey);
 		}
 	}
 
@@ -446,19 +444,21 @@ static int __key_instantiate_and_link(st
 int key_instantiate_and_link(struct key *key,
 			     const void *data,
 			     size_t datalen,
-			     struct key *keyring)
+			     struct key *keyring,
+			     struct key *instkey)
 {
 	int ret;
 
 	if (keyring)
 		down_write(&keyring->sem);
 
-	ret = __key_instantiate_and_link(key, data, datalen, keyring);
+	ret = __key_instantiate_and_link(key, data, datalen, keyring, instkey);
 
 	if (keyring)
 		up_write(&keyring->sem);
 
 	return ret;
+
 } /* end key_instantiate_and_link() */
 
 EXPORT_SYMBOL(key_instantiate_and_link);
@@ -469,7 +469,8 @@ EXPORT_SYMBOL(key_instantiate_and_link);
  */
 int key_negate_and_link(struct key *key,
 			unsigned timeout,
-			struct key *keyring)
+			struct key *keyring,
+			struct key *instkey)
 {
 	struct timespec now;
 	int ret, awaken;
@@ -486,26 +487,26 @@ int key_negate_and_link(struct key *key,
 	down_write(&key_construction_sem);
 
 	/* can't instantiate twice */
-	if (!(key->flags & KEY_FLAG_INSTANTIATED)) {
+	if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) {
 		/* mark the key as being negatively instantiated */
-		write_lock(&key->lock);
-
 		atomic_inc(&key->user->nikeys);
-		key->flags |= KEY_FLAG_INSTANTIATED | KEY_FLAG_NEGATIVE;
+		set_bit(KEY_FLAG_NEGATIVE, &key->flags);
+		set_bit(KEY_FLAG_INSTANTIATED, &key->flags);
 		now = current_kernel_time();
 		key->expiry = now.tv_sec + timeout;
 
-		if (key->flags & KEY_FLAG_USER_CONSTRUCT) {
-			key->flags &= ~KEY_FLAG_USER_CONSTRUCT;
+		if (test_and_clear_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags))
 			awaken = 1;
-		}
 
-		write_unlock(&key->lock);
 		ret = 0;
 
 		/* and link it into the destination keyring */
 		if (keyring)
 			ret = __key_link(keyring, key);
+
+		/* disable the authorisation key */
+		if (instkey)
+			key_revoke(instkey);
 	}
 
 	up_write(&key_construction_sem);
@@ -553,8 +554,10 @@ static void key_cleanup(void *data)
 	rb_erase(&key->serial_node, &key_serial_tree);
 	spin_unlock(&key_serial_lock);
 
+	key_check(key);
+
 	/* deal with the user's key tracking and quota */
-	if (key->flags & KEY_FLAG_IN_QUOTA) {
+	if (test_bit(KEY_FLAG_IN_QUOTA, &key->flags)) {
 		spin_lock(&key->user->lock);
 		key->user->qnkeys--;
 		key->user->qnbytes -= key->quotalen;
@@ -562,7 +565,7 @@ static void key_cleanup(void *data)
 	}
 
 	atomic_dec(&key->user->nkeys);
-	if (key->flags & KEY_FLAG_INSTANTIATED)
+	if (test_bit(KEY_FLAG_INSTANTIATED, &key->flags))
 		atomic_dec(&key->user->nikeys);
 
 	key_user_put(key->user);
@@ -631,9 +634,9 @@ struct key *key_lookup(key_serial_t id)
 	goto error;
 
  found:
-	/* pretent doesn't exist if it's dead */
+	/* pretend it doesn't exist if it's dead */
 	if (atomic_read(&key->usage) == 0 ||
-	    (key->flags & KEY_FLAG_DEAD) ||
+	    test_bit(KEY_FLAG_DEAD, &key->flags) ||
 	    key->type == &key_type_dead)
 		goto not_found;
 
@@ -708,12 +711,9 @@ static inline struct key *__key_update(s
 
 	ret = key->type->update(key, payload, plen);
 
-	if (ret == 0) {
+	if (ret == 0)
 		/* updating a negative key instantiates it */
-		write_lock(&key->lock);
-		key->flags &= ~KEY_FLAG_NEGATIVE;
-		write_unlock(&key->lock);
-	}
+		clear_bit(KEY_FLAG_NEGATIVE, &key->flags);
 
 	up_write(&key->sem);
 
@@ -793,7 +793,7 @@ struct key *key_create_or_update(struct 
 	}
 
 	/* instantiate it and link it into the target keyring */
-	ret = __key_instantiate_and_link(key, payload, plen, keyring);
+	ret = __key_instantiate_and_link(key, payload, plen, keyring, NULL);
 	if (ret < 0) {
 		key_put(key);
 		key = ERR_PTR(ret);
@@ -841,12 +841,9 @@ int key_update(struct key *key, const vo
 		down_write(&key->sem);
 		ret = key->type->update(key, payload, plen);
 
-		if (ret == 0) {
+		if (ret == 0)
 			/* updating a negative key instantiates it */
-			write_lock(&key->lock);
-			key->flags &= ~KEY_FLAG_NEGATIVE;
-			write_unlock(&key->lock);
-		}
+			clear_bit(KEY_FLAG_NEGATIVE, &key->flags);
 
 		up_write(&key->sem);
 	}
@@ -892,10 +889,7 @@ struct key *key_duplicate(struct key *so
 		goto error2;
 
 	atomic_inc(&key->user->nikeys);
-
-	write_lock(&key->lock);
-	key->flags |= KEY_FLAG_INSTANTIATED;
-	write_unlock(&key->lock);
+	set_bit(KEY_FLAG_INSTANTIATED, &key->flags);
 
  error_k:
 	up_read(&key_types_sem);
@@ -922,9 +916,7 @@ void key_revoke(struct key *key)
 	/* make sure no one's trying to change or use the key when we mark
 	 * it */
 	down_write(&key->sem);
-	write_lock(&key->lock);
-	key->flags |= KEY_FLAG_REVOKED;
-	write_unlock(&key->lock);
+	set_bit(KEY_FLAG_REVOKED, &key->flags);
 	up_write(&key->sem);
 
 } /* end key_revoke() */
@@ -975,24 +967,33 @@ void unregister_key_type(struct key_type
 	/* withdraw the key type */
 	list_del_init(&ktype->link);
 
-	/* need to withdraw all keys of this type */
+	/* mark all the keys of this type dead */
 	spin_lock(&key_serial_lock);
 
 	for (_n = rb_first(&key_serial_tree); _n; _n = rb_next(_n)) {
 		key = rb_entry(_n, struct key, serial_node);
 
-		if (key->type != ktype)
-			continue;
+		if (key->type == ktype)
+			key->type = &key_type_dead;
+	}
+
+	spin_unlock(&key_serial_lock);
+
+	/* make sure everyone revalidates their keys */
+	synchronize_rcu();
+
+	/* we should now be able to destroy the payloads of all the keys of
+	 * this type with impunity */
+	spin_lock(&key_serial_lock);
+
+	for (_n = rb_first(&key_serial_tree); _n; _n = rb_next(_n)) {
+		key = rb_entry(_n, struct key, serial_node);
 
-		write_lock(&key->lock);
-		key->type = &key_type_dead;
-		write_unlock(&key->lock);
-
-		/* there shouldn't be anyone looking at the description or
-		 * payload now */
-		if (ktype->destroy)
-			ktype->destroy(key);
-		memset(&key->payload, 0xbd, sizeof(key->payload));
+		if (key->type == ktype) {
+			if (ktype->destroy)
+				ktype->destroy(key);
+			memset(&key->payload, 0xbd, sizeof(key->payload));
+		}
 	}
 
 	spin_unlock(&key_serial_lock);
@@ -1037,4 +1038,5 @@ void __init key_init(void)
 
 	/* link the two root keyrings together */
 	key_link(&root_session_keyring, &root_user_keyring);
+
 } /* end key_init() */
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
--- a/security/keys/keyctl.c
+++ b/security/keys/keyctl.c
@@ -1,6 +1,6 @@
 /* keyctl.c: userspace keyctl operations
  *
- * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Copyright (C) 2004-5 Red Hat, Inc. All Rights Reserved.
  * Written by David Howells (dhowells@redhat.com)
  *
  * This program is free software; you can redistribute it and/or
@@ -49,6 +49,10 @@ asmlinkage long sys_add_key(const char _
 		goto error;
 	type[31] = '\0';
 
+	ret = -EPERM;
+	if (type[0] == '.')
+		goto error;
+
 	ret = -EFAULT;
 	dlen = strnlen_user(_description, PAGE_SIZE - 1);
 	if (dlen <= 0)
@@ -82,7 +86,7 @@ asmlinkage long sys_add_key(const char _
 	}
 
 	/* find the target keyring (which must be writable) */
-	keyring = lookup_user_key(ringid, 1, 0, KEY_WRITE);
+	keyring = lookup_user_key(NULL, ringid, 1, 0, KEY_WRITE);
 	if (IS_ERR(keyring)) {
 		ret = PTR_ERR(keyring);
 		goto error3;
@@ -137,6 +141,10 @@ asmlinkage long sys_request_key(const ch
 		goto error;
 	type[31] = '\0';
 
+	ret = -EPERM;
+	if (type[0] == '.')
+		goto error;
+
 	/* pull the description into kernel space */
 	ret = -EFAULT;
 	dlen = strnlen_user(_description, PAGE_SIZE - 1);
@@ -181,7 +189,7 @@ asmlinkage long sys_request_key(const ch
 	/* get the destination keyring if specified */
 	dest = NULL;
 	if (destringid) {
-		dest = lookup_user_key(destringid, 1, 0, KEY_WRITE);
+		dest = lookup_user_key(NULL, destringid, 1, 0, KEY_WRITE);
 		if (IS_ERR(dest)) {
 			ret = PTR_ERR(dest);
 			goto error3;
@@ -196,23 +204,15 @@ asmlinkage long sys_request_key(const ch
 	}
 
 	/* do the search */
-	key = request_key(ktype, description, callout_info);
+	key = request_key_and_link(ktype, description, callout_info, dest);
 	if (IS_ERR(key)) {
 		ret = PTR_ERR(key);
 		goto error5;
 	}
 
-	/* link the resulting key to the destination keyring */
-	if (dest) {
-		ret = key_link(dest, key);
-		if (ret < 0)
-			goto error6;
-	}
-
 	ret = key->serial;
 
- error6:
-	key_put(key);
+ 	key_put(key);
  error5:
 	key_type_put(ktype);
  error4:
@@ -237,7 +237,7 @@ long keyctl_get_keyring_ID(key_serial_t 
 	struct key *key;
 	long ret;
 
-	key = lookup_user_key(id, create, 0, KEY_SEARCH);
+	key = lookup_user_key(NULL, id, create, 0, KEY_SEARCH);
 	if (IS_ERR(key)) {
 		ret = PTR_ERR(key);
 		goto error;
@@ -324,7 +324,7 @@ long keyctl_update_key(key_serial_t id,
 	}
 
 	/* find the target key (which must be writable) */
-	key = lookup_user_key(id, 0, 0, KEY_WRITE);
+	key = lookup_user_key(NULL, id, 0, 0, KEY_WRITE);
 	if (IS_ERR(key)) {
 		ret = PTR_ERR(key);
 		goto error2;
@@ -352,7 +352,7 @@ long keyctl_revoke_key(key_serial_t id)
 	struct key *key;
 	long ret;
 
-	key = lookup_user_key(id, 0, 0, KEY_WRITE);
+	key = lookup_user_key(NULL, id, 0, 0, KEY_WRITE);
 	if (IS_ERR(key)) {
 		ret = PTR_ERR(key);
 		goto error;
@@ -363,7 +363,7 @@ long keyctl_revoke_key(key_serial_t id)
 
 	key_put(key);
  error:
-	return 0;
+	return ret;
 
 } /* end keyctl_revoke_key() */
 
@@ -378,7 +378,7 @@ long keyctl_keyring_clear(key_serial_t r
 	struct key *keyring;
 	long ret;
 
-	keyring = lookup_user_key(ringid, 1, 0, KEY_WRITE);
+	keyring = lookup_user_key(NULL, ringid, 1, 0, KEY_WRITE);
 	if (IS_ERR(keyring)) {
 		ret = PTR_ERR(keyring);
 		goto error;
@@ -404,13 +404,13 @@ long keyctl_keyring_link(key_serial_t id
 	struct key *keyring, *key;
 	long ret;
 
-	keyring = lookup_user_key(ringid, 1, 0, KEY_WRITE);
+	keyring = lookup_user_key(NULL, ringid, 1, 0, KEY_WRITE);
 	if (IS_ERR(keyring)) {
 		ret = PTR_ERR(keyring);
 		goto error;
 	}
 
-	key = lookup_user_key(id, 1, 0, KEY_LINK);
+	key = lookup_user_key(NULL, id, 1, 0, KEY_LINK);
 	if (IS_ERR(key)) {
 		ret = PTR_ERR(key);
 		goto error2;
@@ -438,13 +438,13 @@ long keyctl_keyring_unlink(key_serial_t 
 	struct key *keyring, *key;
 	long ret;
 
-	keyring = lookup_user_key(ringid, 0, 0, KEY_WRITE);
+	keyring = lookup_user_key(NULL, ringid, 0, 0, KEY_WRITE);
 	if (IS_ERR(keyring)) {
 		ret = PTR_ERR(keyring);
 		goto error;
 	}
 
-	key = lookup_user_key(id, 0, 0, 0);
+	key = lookup_user_key(NULL, id, 0, 0, 0);
 	if (IS_ERR(key)) {
 		ret = PTR_ERR(key);
 		goto error2;
@@ -475,16 +475,29 @@ long keyctl_describe_key(key_serial_t ke
 			 char __user *buffer,
 			 size_t buflen)
 {
-	struct key *key;
+	struct key *key, *instkey;
 	char *tmpbuf;
 	long ret;
 
-	key = lookup_user_key(keyid, 0, 1, KEY_VIEW);
+	key = lookup_user_key(NULL, keyid, 0, 1, KEY_VIEW);
 	if (IS_ERR(key)) {
+		/* viewing a key under construction is permitted if we have the
+		 * authorisation token handy */
+		if (PTR_ERR(key) == -EACCES) {
+			instkey = key_get_instantiation_authkey(keyid);
+			if (!IS_ERR(instkey)) {
+				key_put(instkey);
+				key = lookup_user_key(NULL, keyid, 0, 1, 0);
+				if (!IS_ERR(key))
+					goto okay;
+			}
+		}
+
 		ret = PTR_ERR(key);
 		goto error;
 	}
 
+okay:
 	/* calculate how much description we're going to return */
 	ret = -ENOMEM;
 	tmpbuf = kmalloc(PAGE_SIZE, GFP_KERNEL);
@@ -568,7 +581,7 @@ long keyctl_keyring_search(key_serial_t 
 		goto error2;
 
 	/* get the keyring at which to begin the search */
-	keyring = lookup_user_key(ringid, 0, 0, KEY_SEARCH);
+	keyring = lookup_user_key(NULL, ringid, 0, 0, KEY_SEARCH);
 	if (IS_ERR(keyring)) {
 		ret = PTR_ERR(keyring);
 		goto error2;
@@ -577,7 +590,7 @@ long keyctl_keyring_search(key_serial_t 
 	/* get the destination keyring if specified */
 	dest = NULL;
 	if (destringid) {
-		dest = lookup_user_key(destringid, 1, 0, KEY_WRITE);
+		dest = lookup_user_key(NULL, destringid, 1, 0, KEY_WRITE);
 		if (IS_ERR(dest)) {
 			ret = PTR_ERR(dest);
 			goto error3;
@@ -656,24 +669,25 @@ long keyctl_read_key(key_serial_t keyid,
 	long ret;
 
 	/* find the key first */
-	key = lookup_user_key(keyid, 0, 0, 0);
+	key = lookup_user_key(NULL, keyid, 0, 0, 0);
 	if (!IS_ERR(key)) {
 		/* see if we can read it directly */
 		if (key_permission(key, KEY_READ))
 			goto can_read_key;
 
-		/* can't; see if it's searchable from this process's
-		 * keyrings */
-		ret = -ENOKEY;
-		if (key_permission(key, KEY_SEARCH)) {
-			/* okay - we do have search permission on the key
-			 * itself, but do we have the key? */
-			skey = search_process_keyrings_aux(key->type, key,
-							   keyctl_read_key_same);
-			if (!IS_ERR(skey))
-				goto can_read_key2;
-		}
+		/* we can't; see if it's searchable from this process's
+		 * keyrings
+		 * - we automatically take account of the fact that it may be
+		 *   dangling off an instantiation key
+		 */
+		skey = search_process_keyrings(key->type, key,
+					       keyctl_read_key_same, current);
+		if (!IS_ERR(skey))
+			goto can_read_key2;
 
+		ret = PTR_ERR(skey);
+		if (ret == -EAGAIN)
+			ret = -EACCES;
 		goto error2;
 	}
 
@@ -719,7 +733,7 @@ long keyctl_chown_key(key_serial_t id, u
 	if (uid == (uid_t) -1 && gid == (gid_t) -1)
 		goto error;
 
-	key = lookup_user_key(id, 1, 1, 0);
+	key = lookup_user_key(NULL, id, 1, 1, 0);
 	if (IS_ERR(key)) {
 		ret = PTR_ERR(key);
 		goto error;
@@ -728,7 +742,6 @@ long keyctl_chown_key(key_serial_t id, u
 	/* make the changes with the locks held to prevent chown/chown races */
 	ret = -EACCES;
 	down_write(&key->sem);
-	write_lock(&key->lock);
 
 	if (!capable(CAP_SYS_ADMIN)) {
 		/* only the sysadmin can chown a key to some other UID */
@@ -755,7 +768,6 @@ long keyctl_chown_key(key_serial_t id, u
 	ret = 0;
 
  no_access:
-	write_unlock(&key->lock);
 	up_write(&key->sem);
 	key_put(key);
  error:
@@ -778,32 +790,25 @@ long keyctl_setperm_key(key_serial_t id,
 	if (perm & ~(KEY_USR_ALL | KEY_GRP_ALL | KEY_OTH_ALL))
 		goto error;
 
-	key = lookup_user_key(id, 1, 1, 0);
+	key = lookup_user_key(NULL, id, 1, 1, 0);
 	if (IS_ERR(key)) {
 		ret = PTR_ERR(key);
 		goto error;
 	}
 
-	/* make the changes with the locks held to prevent chown/chmod
-	 * races */
+	/* make the changes with the locks held to prevent chown/chmod races */
 	ret = -EACCES;
 	down_write(&key->sem);
-	write_lock(&key->lock);
-
-	/* if we're not the sysadmin, we can only chmod a key that we
-	 * own */
-	if (!capable(CAP_SYS_ADMIN) && key->uid != current->fsuid)
-		goto no_access;
 
-	/* changing the permissions mask */
-	key->perm = perm;
-	ret = 0;
+	/* if we're not the sysadmin, we can only change a key that we own */
+	if (capable(CAP_SYS_ADMIN) || key->uid == current->fsuid) {
+		key->perm = perm;
+		ret = 0;
+	}
 
- no_access:
-	write_unlock(&key->lock);
 	up_write(&key->sem);
 	key_put(key);
- error:
+error:
 	return ret;
 
 } /* end keyctl_setperm_key() */
@@ -818,7 +823,8 @@ long keyctl_instantiate_key(key_serial_t
 			    size_t plen,
 			    key_serial_t ringid)
 {
-	struct key *key, *keyring;
+	struct request_key_auth *rka;
+	struct key *instkey, *keyring;
 	void *payload;
 	long ret;
 
@@ -840,18 +846,21 @@ long keyctl_instantiate_key(key_serial_t
 			goto error2;
 	}
 
-	/* find the target key (which must be writable) */
-	key = lookup_user_key(id, 0, 1, KEY_WRITE);
-	if (IS_ERR(key)) {
-		ret = PTR_ERR(key);
+	/* find the instantiation authorisation key */
+	instkey = key_get_instantiation_authkey(id);
+	if (IS_ERR(instkey)) {
+		ret = PTR_ERR(instkey);
 		goto error2;
 	}
 
-	/* find the destination keyring if present (which must also be
-	 * writable) */
+	rka = instkey->payload.data;
+
+	/* find the destination keyring amongst those belonging to the
+	 * requesting task */
 	keyring = NULL;
 	if (ringid) {
-		keyring = lookup_user_key(ringid, 1, 0, KEY_WRITE);
+		keyring = lookup_user_key(rka->context, ringid, 1, 0,
+					  KEY_WRITE);
 		if (IS_ERR(keyring)) {
 			ret = PTR_ERR(keyring);
 			goto error3;
@@ -859,11 +868,12 @@ long keyctl_instantiate_key(key_serial_t
 	}
 
 	/* instantiate the key and link it into a keyring */
-	ret = key_instantiate_and_link(key, payload, plen, keyring);
+	ret = key_instantiate_and_link(rka->target_key, payload, plen,
+				       keyring, instkey);
 
 	key_put(keyring);
  error3:
-	key_put(key);
+	key_put(instkey);
  error2:
 	kfree(payload);
  error:
@@ -878,21 +888,24 @@ long keyctl_instantiate_key(key_serial_t
  */
 long keyctl_negate_key(key_serial_t id, unsigned timeout, key_serial_t ringid)
 {
-	struct key *key, *keyring;
+	struct request_key_auth *rka;
+	struct key *instkey, *keyring;
 	long ret;
 
-	/* find the target key (which must be writable) */
-	key = lookup_user_key(id, 0, 1, KEY_WRITE);
-	if (IS_ERR(key)) {
-		ret = PTR_ERR(key);
+	/* find the instantiation authorisation key */
+	instkey = key_get_instantiation_authkey(id);
+	if (IS_ERR(instkey)) {
+		ret = PTR_ERR(instkey);
 		goto error;
 	}
 
+	rka = instkey->payload.data;
+
 	/* find the destination keyring if present (which must also be
 	 * writable) */
 	keyring = NULL;
 	if (ringid) {
-		keyring = lookup_user_key(ringid, 1, 0, KEY_WRITE);
+		keyring = lookup_user_key(NULL, ringid, 1, 0, KEY_WRITE);
 		if (IS_ERR(keyring)) {
 			ret = PTR_ERR(keyring);
 			goto error2;
@@ -900,11 +913,11 @@ long keyctl_negate_key(key_serial_t id, 
 	}
 
 	/* instantiate the key and link it into a keyring */
-	ret = key_negate_and_link(key, timeout, keyring);
+	ret = key_negate_and_link(rka->target_key, timeout, keyring, instkey);
 
 	key_put(keyring);
  error2:
-	key_put(key);
+	key_put(instkey);
  error:
 	return ret;
 
@@ -912,6 +925,44 @@ long keyctl_negate_key(key_serial_t id, 
 
 /*****************************************************************************/
 /*
+ * set the default keyring in which request_key() will cache keys
+ * - return the old setting
+ */
+long keyctl_set_reqkey_keyring(int reqkey_defl)
+{
+	int ret;
+
+	switch (reqkey_defl) {
+	case KEY_REQKEY_DEFL_THREAD_KEYRING:
+		ret = install_thread_keyring(current);
+		if (ret < 0)
+			return ret;
+		goto set;
+
+	case KEY_REQKEY_DEFL_PROCESS_KEYRING:
+		ret = install_process_keyring(current);
+		if (ret < 0)
+			return ret;
+
+	case KEY_REQKEY_DEFL_DEFAULT:
+	case KEY_REQKEY_DEFL_SESSION_KEYRING:
+	case KEY_REQKEY_DEFL_USER_KEYRING:
+	case KEY_REQKEY_DEFL_USER_SESSION_KEYRING:
+	set:
+		current->jit_keyring = reqkey_defl;
+
+	case KEY_REQKEY_DEFL_NO_CHANGE:
+		return current->jit_keyring;
+
+	case KEY_REQKEY_DEFL_GROUP_KEYRING:
+	default:
+		return -EINVAL;
+	}
+
+} /* end keyctl_set_reqkey_keyring() */
+
+/*****************************************************************************/
+/*
  * the key control system call
  */
 asmlinkage long sys_keyctl(int option, unsigned long arg2, unsigned long arg3,
@@ -980,6 +1031,9 @@ asmlinkage long sys_keyctl(int option, u
 					 (unsigned) arg3,
 					 (key_serial_t) arg4);
 
+	case KEYCTL_SET_REQKEY_KEYRING:
+		return keyctl_set_reqkey_keyring(arg2);
+
 	default:
 		return -EOPNOTSUPP;
 	}
diff --git a/security/keys/keyring.c b/security/keys/keyring.c
--- a/security/keys/keyring.c
+++ b/security/keys/keyring.c
@@ -1,6 +1,6 @@
 /* keyring.c: keyring handling
  *
- * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Copyright (C) 2004-5 Red Hat, Inc. All Rights Reserved.
  * Written by David Howells (dhowells@redhat.com)
  *
  * This program is free software; you can redistribute it and/or
@@ -129,13 +129,20 @@ static int keyring_duplicate(struct key 
 	int loop, ret;
 
 	const unsigned limit =
-		(PAGE_SIZE - sizeof(*klist)) / sizeof(struct key);
+		(PAGE_SIZE - sizeof(*klist)) / sizeof(struct key *);
 
 	ret = 0;
-	sklist = source->payload.subscriptions;
 
-	if (sklist && sklist->nkeys > 0) {
+	/* find out how many keys are currently linked */
+	rcu_read_lock();
+	sklist = rcu_dereference(source->payload.subscriptions);
+	max = 0;
+	if (sklist)
 		max = sklist->nkeys;
+	rcu_read_unlock();
+
+	/* allocate a new payload and stuff load with key links */
+	if (max > 0) {
 		BUG_ON(max > limit);
 
 		max = (max + 3) & ~3;
@@ -143,21 +150,27 @@ static int keyring_duplicate(struct key 
 			max = limit;
 
 		ret = -ENOMEM;
-		size = sizeof(*klist) + sizeof(struct key) * max;
+		size = sizeof(*klist) + sizeof(struct key *) * max;
 		klist = kmalloc(size, GFP_KERNEL);
 		if (!klist)
 			goto error;
 
+		/* set links */
+		rcu_read_lock();
+		sklist = rcu_dereference(source->payload.subscriptions);
+
 		klist->maxkeys = max;
 		klist->nkeys = sklist->nkeys;
 		memcpy(klist->keys,
 		       sklist->keys,
-		       sklist->nkeys * sizeof(struct key));
+		       sklist->nkeys * sizeof(struct key *));
 
 		for (loop = klist->nkeys - 1; loop >= 0; loop--)
 			atomic_inc(&klist->keys[loop]->usage);
 
-		keyring->payload.subscriptions = klist;
+		rcu_read_unlock();
+
+		rcu_assign_pointer(keyring->payload.subscriptions, klist);
 		ret = 0;
 	}
 
@@ -188,11 +201,15 @@ static void keyring_destroy(struct key *
 
 	if (keyring->description) {
 		write_lock(&keyring_name_lock);
-		list_del(&keyring->type_data.link);
+
+		if (keyring->type_data.link.next != NULL &&
+		    !list_empty(&keyring->type_data.link))
+			list_del(&keyring->type_data.link);
+
 		write_unlock(&keyring_name_lock);
 	}
 
-	klist = keyring->payload.subscriptions;
+	klist = rcu_dereference(keyring->payload.subscriptions);
 	if (klist) {
 		for (loop = klist->nkeys - 1; loop >= 0; loop--)
 			key_put(klist->keys[loop]);
@@ -216,17 +233,20 @@ static void keyring_describe(const struc
 		seq_puts(m, "[anon]");
 	}
 
-	klist = keyring->payload.subscriptions;
+	rcu_read_lock();
+	klist = rcu_dereference(keyring->payload.subscriptions);
 	if (klist)
 		seq_printf(m, ": %u/%u", klist->nkeys, klist->maxkeys);
 	else
 		seq_puts(m, ": empty");
+	rcu_read_unlock();
 
 } /* end keyring_describe() */
 
 /*****************************************************************************/
 /*
  * read a list of key IDs from the keyring's contents
+ * - the keyring's semaphore is read-locked
  */
 static long keyring_read(const struct key *keyring,
 			 char __user *buffer, size_t buflen)
@@ -237,7 +257,7 @@ static long keyring_read(const struct ke
 	int loop, ret;
 
 	ret = 0;
-	klist = keyring->payload.subscriptions;
+	klist = rcu_dereference(keyring->payload.subscriptions);
 
 	if (klist) {
 		/* calculate how much data we could return */
@@ -292,7 +312,7 @@ struct key *keyring_alloc(const char *de
 			    uid, gid, KEY_USR_ALL, not_in_quota);
 
 	if (!IS_ERR(keyring)) {
-		ret = key_instantiate_and_link(keyring, NULL, 0, dest);
+		ret = key_instantiate_and_link(keyring, NULL, 0, dest, NULL);
 		if (ret < 0) {
 			key_put(keyring);
 			keyring = ERR_PTR(ret);
@@ -310,17 +330,18 @@ struct key *keyring_alloc(const char *de
  * - we only find keys on which we have search permission
  * - we use the supplied match function to see if the description (or other
  *   feature of interest) matches
- * - we readlock the keyrings as we search down the tree
+ * - we rely on RCU to prevent the keyring lists from disappearing on us
  * - we return -EAGAIN if we didn't find any matching key
  * - we return -ENOKEY if we only found negative matching keys
  */
 struct key *keyring_search_aux(struct key *keyring,
+			       struct task_struct *context,
 			       struct key_type *type,
 			       const void *description,
 			       key_match_func_t match)
 {
 	struct {
-		struct key *keyring;
+		struct keyring_list *keylist;
 		int kix;
 	} stack[KEYRING_SEARCH_MAX_DEPTH];
 
@@ -328,13 +349,15 @@ struct key *keyring_search_aux(struct ke
 	struct timespec now;
 	struct key *key;
 	long err;
-	int sp, psp, kix;
+	int sp, kix;
 
 	key_check(keyring);
 
+	rcu_read_lock();
+
 	/* top keyring must have search permission to begin the search */
 	key = ERR_PTR(-EACCES);
-	if (!key_permission(keyring, KEY_SEARCH))
+	if (!key_task_permission(keyring, context, KEY_SEARCH))
 		goto error;
 
 	key = ERR_PTR(-ENOTDIR);
@@ -347,11 +370,10 @@ struct key *keyring_search_aux(struct ke
 
 	/* start processing a new keyring */
  descend:
-	read_lock(&keyring->lock);
-	if (keyring->flags & KEY_FLAG_REVOKED)
+	if (test_bit(KEY_FLAG_REVOKED, &keyring->flags))
 		goto not_this_keyring;
 
-	keylist = keyring->payload.subscriptions;
+	keylist = rcu_dereference(keyring->payload.subscriptions);
 	if (!keylist)
 		goto not_this_keyring;
 
@@ -364,7 +386,7 @@ struct key *keyring_search_aux(struct ke
 			continue;
 
 		/* skip revoked keys and expired keys */
-		if (key->flags & KEY_FLAG_REVOKED)
+		if (test_bit(KEY_FLAG_REVOKED, &key->flags))
 			continue;
 
 		if (key->expiry && now.tv_sec >= key->expiry)
@@ -375,11 +397,11 @@ struct key *keyring_search_aux(struct ke
 			continue;
 
 		/* key must have search permissions */
-		if (!key_permission(key, KEY_SEARCH))
+		if (!key_task_permission(key, context, KEY_SEARCH))
 			continue;
 
 		/* we set a different error code if we find a negative key */
-		if (key->flags & KEY_FLAG_NEGATIVE) {
+		if (test_bit(KEY_FLAG_NEGATIVE, &key->flags)) {
 			err = -ENOKEY;
 			continue;
 		}
@@ -390,48 +412,37 @@ struct key *keyring_search_aux(struct ke
 	/* search through the keyrings nested in this one */
 	kix = 0;
  ascend:
-	while (kix < keylist->nkeys) {
+	for (; kix < keylist->nkeys; kix++) {
 		key = keylist->keys[kix];
 		if (key->type != &key_type_keyring)
-			goto next;
+			continue;
 
 		/* recursively search nested keyrings
 		 * - only search keyrings for which we have search permission
 		 */
 		if (sp >= KEYRING_SEARCH_MAX_DEPTH)
-			goto next;
-
-		if (!key_permission(key, KEY_SEARCH))
-			goto next;
+			continue;
 
-		/* evade loops in the keyring tree */
-		for (psp = 0; psp < sp; psp++)
-			if (stack[psp].keyring == keyring)
-				goto next;
+		if (!key_task_permission(key, context, KEY_SEARCH))
+			continue;
 
 		/* stack the current position */
-		stack[sp].keyring = keyring;
+		stack[sp].keylist = keylist;
 		stack[sp].kix = kix;
 		sp++;
 
 		/* begin again with the new keyring */
 		keyring = key;
 		goto descend;
-
-	next:
-		kix++;
 	}
 
 	/* the keyring we're looking at was disqualified or didn't contain a
 	 * matching key */
  not_this_keyring:
-	read_unlock(&keyring->lock);
-
 	if (sp > 0) {
 		/* resume the processing of a keyring higher up in the tree */
 		sp--;
-		keyring = stack[sp].keyring;
-		keylist = keyring->payload.subscriptions;
+		keylist = stack[sp].keylist;
 		kix = stack[sp].kix + 1;
 		goto ascend;
 	}
@@ -442,16 +453,9 @@ struct key *keyring_search_aux(struct ke
 	/* we found a viable match */
  found:
 	atomic_inc(&key->usage);
-	read_unlock(&keyring->lock);
-
-	/* unwind the keyring stack */
-	while (sp > 0) {
-		sp--;
-		read_unlock(&stack[sp].keyring->lock);
-	}
-
 	key_check(key);
  error:
+	rcu_read_unlock();
 	return key;
 
 } /* end keyring_search_aux() */
@@ -469,7 +473,11 @@ struct key *keyring_search(struct key *k
 			   struct key_type *type,
 			   const char *description)
 {
-	return keyring_search_aux(keyring, type, description, type->match);
+	if (!type->match)
+		return ERR_PTR(-ENOKEY);
+
+	return keyring_search_aux(keyring, current,
+				  type, description, type->match);
 
 } /* end keyring_search() */
 
@@ -489,15 +497,18 @@ struct key *__keyring_search_one(struct 
 	struct key *key;
 	int loop;
 
-	klist = keyring->payload.subscriptions;
+	rcu_read_lock();
+
+	klist = rcu_dereference(keyring->payload.subscriptions);
 	if (klist) {
 		for (loop = 0; loop < klist->nkeys; loop++) {
 			key = klist->keys[loop];
 
 			if (key->type == ktype &&
-			    key->type->match(key, description) &&
+			    (!key->type->match ||
+			     key->type->match(key, description)) &&
 			    key_permission(key, perm) &&
-			    !(key->flags & KEY_FLAG_REVOKED)
+			    !test_bit(KEY_FLAG_REVOKED, &key->flags)
 			    )
 				goto found;
 		}
@@ -509,12 +520,58 @@ struct key *__keyring_search_one(struct 
  found:
 	atomic_inc(&key->usage);
  error:
+	rcu_read_unlock();
 	return key;
 
 } /* end __keyring_search_one() */
 
 /*****************************************************************************/
 /*
+ * search for an instantiation authorisation key matching a target key
+ * - the RCU read lock must be held by the caller
+ * - a target_id of zero specifies any valid token
+ */
+struct key *keyring_search_instkey(struct key *keyring,
+				   key_serial_t target_id)
+{
+	struct request_key_auth *rka;
+	struct keyring_list *klist;
+	struct key *instkey;
+	int loop;
+
+	klist = rcu_dereference(keyring->payload.subscriptions);
+	if (klist) {
+		for (loop = 0; loop < klist->nkeys; loop++) {
+			instkey = klist->keys[loop];
+
+			if (instkey->type != &key_type_request_key_auth)
+				continue;
+
+			rka = instkey->payload.data;
+			if (target_id && rka->target_key->serial != target_id)
+				continue;
+
+			/* the auth key is revoked during instantiation */
+			if (!test_bit(KEY_FLAG_REVOKED, &instkey->flags))
+				goto found;
+
+			instkey = ERR_PTR(-EKEYREVOKED);
+			goto error;
+		}
+	}
+
+	instkey = ERR_PTR(-EACCES);
+	goto error;
+
+found:
+	atomic_inc(&instkey->usage);
+error:
+	return instkey;
+
+} /* end keyring_search_instkey() */
+
+/*****************************************************************************/
+/*
  * find a keyring with the specified name
  * - all named keyrings are searched
  * - only find keyrings with search permission for the process
@@ -540,7 +597,7 @@ struct key *find_keyring_by_name(const c
 				    &keyring_name_hash[bucket],
 				    type_data.link
 				    ) {
-			if (keyring->flags & KEY_FLAG_REVOKED)
+			if (test_bit(KEY_FLAG_REVOKED, &keyring->flags))
 				continue;
 
 			if (strcmp(keyring->description, name) != 0)
@@ -579,7 +636,7 @@ struct key *find_keyring_by_name(const c
 static int keyring_detect_cycle(struct key *A, struct key *B)
 {
 	struct {
-		struct key *subtree;
+		struct keyring_list *keylist;
 		int kix;
 	} stack[KEYRING_SEARCH_MAX_DEPTH];
 
@@ -587,20 +644,21 @@ static int keyring_detect_cycle(struct k
 	struct key *subtree, *key;
 	int sp, kix, ret;
 
+	rcu_read_lock();
+
 	ret = -EDEADLK;
 	if (A == B)
-		goto error;
+		goto cycle_detected;
 
 	subtree = B;
 	sp = 0;
 
 	/* start processing a new keyring */
  descend:
-	read_lock(&subtree->lock);
-	if (subtree->flags & KEY_FLAG_REVOKED)
+	if (test_bit(KEY_FLAG_REVOKED, &subtree->flags))
 		goto not_this_keyring;
 
-	keylist = subtree->payload.subscriptions;
+	keylist = rcu_dereference(subtree->payload.subscriptions);
 	if (!keylist)
 		goto not_this_keyring;
 	kix = 0;
@@ -619,7 +677,7 @@ static int keyring_detect_cycle(struct k
 				goto too_deep;
 
 			/* stack the current position */
-			stack[sp].subtree = subtree;
+			stack[sp].keylist = keylist;
 			stack[sp].kix = kix;
 			sp++;
 
@@ -632,13 +690,10 @@ static int keyring_detect_cycle(struct k
 	/* the keyring we're looking at was disqualified or didn't contain a
 	 * matching key */
  not_this_keyring:
-	read_unlock(&subtree->lock);
-
 	if (sp > 0) {
 		/* resume the checking of a keyring higher up in the tree */
 		sp--;
-		subtree = stack[sp].subtree;
-		keylist = subtree->payload.subscriptions;
+		keylist = stack[sp].keylist;
 		kix = stack[sp].kix + 1;
 		goto ascend;
 	}
@@ -646,30 +701,36 @@ static int keyring_detect_cycle(struct k
 	ret = 0; /* no cycles detected */
 
  error:
+	rcu_read_unlock();
 	return ret;
 
  too_deep:
 	ret = -ELOOP;
-	goto error_unwind;
+	goto error;
+
  cycle_detected:
 	ret = -EDEADLK;
- error_unwind:
-	read_unlock(&subtree->lock);
-
-	/* unwind the keyring stack */
-	while (sp > 0) {
-		sp--;
-		read_unlock(&stack[sp].subtree->lock);
-	}
-
 	goto error;
 
 } /* end keyring_detect_cycle() */
 
 /*****************************************************************************/
 /*
+ * dispose of a keyring list after the RCU grace period
+ */
+static void keyring_link_rcu_disposal(struct rcu_head *rcu)
+{
+	struct keyring_list *klist =
+		container_of(rcu, struct keyring_list, rcu);
+
+	kfree(klist);
+
+} /* end keyring_link_rcu_disposal() */
+
+/*****************************************************************************/
+/*
  * link a key into to a keyring
- * - must be called with the keyring's semaphore held
+ * - must be called with the keyring's semaphore write-locked
  */
 int __key_link(struct key *keyring, struct key *key)
 {
@@ -679,7 +740,7 @@ int __key_link(struct key *keyring, stru
 	int ret;
 
 	ret = -EKEYREVOKED;
-	if (keyring->flags & KEY_FLAG_REVOKED)
+	if (test_bit(KEY_FLAG_REVOKED, &keyring->flags))
 		goto error;
 
 	ret = -ENOTDIR;
@@ -710,9 +771,10 @@ int __key_link(struct key *keyring, stru
 		/* there's sufficient slack space to add directly */
 		atomic_inc(&key->usage);
 
-		write_lock(&keyring->lock);
-		klist->keys[klist->nkeys++] = key;
-		write_unlock(&keyring->lock);
+		klist->keys[klist->nkeys] = key;
+		smp_wmb();
+		klist->nkeys++;
+		smp_wmb();
 
 		ret = 0;
 	}
@@ -723,7 +785,9 @@ int __key_link(struct key *keyring, stru
 			max += klist->maxkeys;
 
 		ret = -ENFILE;
-		size = sizeof(*klist) + sizeof(*key) * max;
+		if (max > 65535)
+			goto error3;
+		size = sizeof(*klist) + sizeof(struct key *) * max;
 		if (size > PAGE_SIZE)
 			goto error3;
 
@@ -743,14 +807,13 @@ int __key_link(struct key *keyring, stru
 
 		/* add the key into the new space */
 		atomic_inc(&key->usage);
-
-		write_lock(&keyring->lock);
-		keyring->payload.subscriptions = nklist;
 		nklist->keys[nklist->nkeys++] = key;
-		write_unlock(&keyring->lock);
+
+		rcu_assign_pointer(keyring->payload.subscriptions, nklist);
 
 		/* dispose of the old keyring list */
-		kfree(klist);
+		if (klist)
+			call_rcu(&klist->rcu, keyring_link_rcu_disposal);
 
 		ret = 0;
 	}
@@ -791,11 +854,26 @@ EXPORT_SYMBOL(key_link);
 
 /*****************************************************************************/
 /*
+ * dispose of a keyring list after the RCU grace period, freeing the unlinked
+ * key
+ */
+static void keyring_unlink_rcu_disposal(struct rcu_head *rcu)
+{
+	struct keyring_list *klist =
+		container_of(rcu, struct keyring_list, rcu);
+
+	key_put(klist->keys[klist->delkey]);
+	kfree(klist);
+
+} /* end keyring_unlink_rcu_disposal() */
+
+/*****************************************************************************/
+/*
  * unlink the first link to a key from a keyring
  */
 int key_unlink(struct key *keyring, struct key *key)
 {
-	struct keyring_list *klist;
+	struct keyring_list *klist, *nklist;
 	int loop, ret;
 
 	key_check(keyring);
@@ -819,31 +897,46 @@ int key_unlink(struct key *keyring, stru
 	ret = -ENOENT;
 	goto error;
 
- key_is_present:
+key_is_present:
+	/* we need to copy the key list for RCU purposes */
+	nklist = kmalloc(sizeof(*klist) +
+			 sizeof(struct key *) * klist->maxkeys,
+			 GFP_KERNEL);
+	if (!nklist)
+		goto nomem;
+	nklist->maxkeys = klist->maxkeys;
+	nklist->nkeys = klist->nkeys - 1;
+
+	if (loop > 0)
+		memcpy(&nklist->keys[0],
+		       &klist->keys[0],
+		       loop * sizeof(struct key *));
+
+	if (loop < nklist->nkeys)
+		memcpy(&nklist->keys[loop],
+		       &klist->keys[loop + 1],
+		       (nklist->nkeys - loop) * sizeof(struct key *));
+
 	/* adjust the user's quota */
 	key_payload_reserve(keyring,
 			    keyring->datalen - KEYQUOTA_LINK_BYTES);
 
-	/* shuffle down the key pointers
-	 * - it might be worth shrinking the allocated memory, but that runs
-	 *   the risk of ENOMEM as we would have to copy
-	 */
-	write_lock(&keyring->lock);
-
-	klist->nkeys--;
-	if (loop < klist->nkeys)
-		memcpy(&klist->keys[loop],
-		       &klist->keys[loop + 1],
-		       (klist->nkeys - loop) * sizeof(struct key *));
-
-	write_unlock(&keyring->lock);
+	rcu_assign_pointer(keyring->payload.subscriptions, nklist);
 
 	up_write(&keyring->sem);
-	key_put(key);
+
+	/* schedule for later cleanup */
+	klist->delkey = loop;
+	call_rcu(&klist->rcu, keyring_unlink_rcu_disposal);
+
 	ret = 0;
 
- error:
+error:
 	return ret;
+nomem:
+	ret = -ENOMEM;
+	up_write(&keyring->sem);
+	goto error;
 
 } /* end key_unlink() */
 
@@ -851,13 +944,32 @@ EXPORT_SYMBOL(key_unlink);
 
 /*****************************************************************************/
 /*
+ * dispose of a keyring list after the RCU grace period, releasing the keys it
+ * links to
+ */
+static void keyring_clear_rcu_disposal(struct rcu_head *rcu)
+{
+	struct keyring_list *klist;
+	int loop;
+
+	klist = container_of(rcu, struct keyring_list, rcu);
+
+	for (loop = klist->nkeys - 1; loop >= 0; loop--)
+		key_put(klist->keys[loop]);
+
+	kfree(klist);
+
+} /* end keyring_clear_rcu_disposal() */
+
+/*****************************************************************************/
+/*
  * clear the specified process keyring
  * - implements keyctl(KEYCTL_CLEAR)
  */
 int keyring_clear(struct key *keyring)
 {
 	struct keyring_list *klist;
-	int loop, ret;
+	int ret;
 
 	ret = -ENOTDIR;
 	if (keyring->type == &key_type_keyring) {
@@ -870,20 +982,15 @@ int keyring_clear(struct key *keyring)
 			key_payload_reserve(keyring,
 					    sizeof(struct keyring_list));
 
-			write_lock(&keyring->lock);
-			keyring->payload.subscriptions = NULL;
-			write_unlock(&keyring->lock);
+			rcu_assign_pointer(keyring->payload.subscriptions,
+					   NULL);
 		}
 
 		up_write(&keyring->sem);
 
 		/* free the keys after the locks have been dropped */
-		if (klist) {
-			for (loop = klist->nkeys - 1; loop >= 0; loop--)
-				key_put(klist->keys[loop]);
-
-			kfree(klist);
-		}
+		if (klist)
+			call_rcu(&klist->rcu, keyring_clear_rcu_disposal);
 
 		ret = 0;
 	}
diff --git a/security/keys/proc.c b/security/keys/proc.c
--- a/security/keys/proc.c
+++ b/security/keys/proc.c
@@ -140,7 +140,7 @@ static int proc_keys_show(struct seq_fil
 
 	now = current_kernel_time();
 
-	read_lock(&key->lock);
+	rcu_read_lock();
 
 	/* come up with a suitable timeout value */
 	if (key->expiry == 0) {
@@ -164,14 +164,17 @@ static int proc_keys_show(struct seq_fil
 			sprintf(xbuf, "%luw", timo / (60*60*24*7));
 	}
 
+#define showflag(KEY, LETTER, FLAG) \
+	(test_bit(FLAG,	&(KEY)->flags) ? LETTER : '-')
+
 	seq_printf(m, "%08x %c%c%c%c%c%c %5d %4s %06x %5d %5d %-9.9s ",
 		   key->serial,
-		   key->flags & KEY_FLAG_INSTANTIATED	? 'I' : '-',
-		   key->flags & KEY_FLAG_REVOKED	? 'R' : '-',
-		   key->flags & KEY_FLAG_DEAD		? 'D' : '-',
-		   key->flags & KEY_FLAG_IN_QUOTA	? 'Q' : '-',
-		   key->flags & KEY_FLAG_USER_CONSTRUCT	? 'U' : '-',
-		   key->flags & KEY_FLAG_NEGATIVE	? 'N' : '-',
+		   showflag(key, 'I', KEY_FLAG_INSTANTIATED),
+		   showflag(key, 'R', KEY_FLAG_REVOKED),
+		   showflag(key, 'D', KEY_FLAG_DEAD),
+		   showflag(key, 'Q', KEY_FLAG_IN_QUOTA),
+		   showflag(key, 'U', KEY_FLAG_USER_CONSTRUCT),
+		   showflag(key, 'N', KEY_FLAG_NEGATIVE),
 		   atomic_read(&key->usage),
 		   xbuf,
 		   key->perm,
@@ -179,11 +182,13 @@ static int proc_keys_show(struct seq_fil
 		   key->gid,
 		   key->type->name);
 
+#undef showflag
+
 	if (key->type->describe)
 		key->type->describe(key, m);
 	seq_putc(m, '\n');
 
-	read_unlock(&key->lock);
+	rcu_read_unlock();
 
 	return 0;
 
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c
--- a/security/keys/process_keys.c
+++ b/security/keys/process_keys.c
@@ -1,6 +1,6 @@
 /* process_keys.c: management of a process's keyrings
  *
- * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Copyright (C) 2004-5 Red Hat, Inc. All Rights Reserved.
  * Written by David Howells (dhowells@redhat.com)
  *
  * This program is free software; you can redistribute it and/or
@@ -38,10 +38,9 @@ struct key root_user_keyring = {
 	.serial		= 2,
 	.type		= &key_type_keyring,
 	.user		= &root_key_user,
-	.lock		= RW_LOCK_UNLOCKED,
 	.sem		= __RWSEM_INITIALIZER(root_user_keyring.sem),
 	.perm		= KEY_USR_ALL,
-	.flags		= KEY_FLAG_INSTANTIATED,
+	.flags		= 1 << KEY_FLAG_INSTANTIATED,
 	.description	= "_uid.0",
 #ifdef KEY_DEBUGGING
 	.magic		= KEY_DEBUG_MAGIC,
@@ -54,10 +53,9 @@ struct key root_session_keyring = {
 	.serial		= 1,
 	.type		= &key_type_keyring,
 	.user		= &root_key_user,
-	.lock		= RW_LOCK_UNLOCKED,
 	.sem		= __RWSEM_INITIALIZER(root_session_keyring.sem),
 	.perm		= KEY_USR_ALL,
-	.flags		= KEY_FLAG_INSTANTIATED,
+	.flags		= 1 << KEY_FLAG_INSTANTIATED,
 	.description	= "_uid_ses.0",
 #ifdef KEY_DEBUGGING
 	.magic		= KEY_DEBUG_MAGIC,
@@ -167,7 +165,7 @@ int install_thread_keyring(struct task_s
 /*
  * make sure a process keyring is installed
  */
-static int install_process_keyring(struct task_struct *tsk)
+int install_process_keyring(struct task_struct *tsk)
 {
 	unsigned long flags;
 	struct key *keyring;
@@ -183,7 +181,7 @@ static int install_process_keyring(struc
 			goto error;
 		}
 
-		/* attach or swap keyrings */
+		/* attach keyring */
 		spin_lock_irqsave(&tsk->sighand->siglock, flags);
 		if (!tsk->signal->process_keyring) {
 			tsk->signal->process_keyring = keyring;
@@ -229,12 +227,14 @@ static int install_session_keyring(struc
 
 	/* install the keyring */
 	spin_lock_irqsave(&tsk->sighand->siglock, flags);
-	old = tsk->signal->session_keyring;
-	tsk->signal->session_keyring = keyring;
+	old = rcu_dereference(tsk->signal->session_keyring);
+	rcu_assign_pointer(tsk->signal->session_keyring, keyring);
 	spin_unlock_irqrestore(&tsk->sighand->siglock, flags);
 
 	ret = 0;
 
+	/* we're using RCU on the pointer */
+	synchronize_rcu();
 	key_put(old);
  error:
 	return ret;
@@ -247,8 +247,6 @@ static int install_session_keyring(struc
  */
 int copy_thread_group_keys(struct task_struct *tsk)
 {
-	unsigned long flags;
-
 	key_check(current->thread_group->session_keyring);
 	key_check(current->thread_group->process_keyring);
 
@@ -256,10 +254,10 @@ int copy_thread_group_keys(struct task_s
 	tsk->signal->process_keyring = NULL;
 
 	/* same session keyring */
-	spin_lock_irqsave(&current->sighand->siglock, flags);
+	rcu_read_lock();
 	tsk->signal->session_keyring =
-		key_get(current->signal->session_keyring);
-	spin_unlock_irqrestore(&current->sighand->siglock, flags);
+		key_get(rcu_dereference(current->signal->session_keyring));
+	rcu_read_unlock();
 
 	return 0;
 
@@ -349,9 +347,7 @@ void key_fsuid_changed(struct task_struc
 	/* update the ownership of the thread keyring */
 	if (tsk->thread_keyring) {
 		down_write(&tsk->thread_keyring->sem);
-		write_lock(&tsk->thread_keyring->lock);
 		tsk->thread_keyring->uid = tsk->fsuid;
-		write_unlock(&tsk->thread_keyring->lock);
 		up_write(&tsk->thread_keyring->sem);
 	}
 
@@ -366,9 +362,7 @@ void key_fsgid_changed(struct task_struc
 	/* update the ownership of the thread keyring */
 	if (tsk->thread_keyring) {
 		down_write(&tsk->thread_keyring->sem);
-		write_lock(&tsk->thread_keyring->lock);
 		tsk->thread_keyring->gid = tsk->fsgid;
-		write_unlock(&tsk->thread_keyring->lock);
 		up_write(&tsk->thread_keyring->sem);
 	}
 
@@ -382,13 +376,13 @@ void key_fsgid_changed(struct task_struc
  * - we return -EAGAIN if we didn't find any matching key
  * - we return -ENOKEY if we found only negative matching keys
  */
-struct key *search_process_keyrings_aux(struct key_type *type,
-					const void *description,
-					key_match_func_t match)
+struct key *search_process_keyrings(struct key_type *type,
+				    const void *description,
+				    key_match_func_t match,
+				    struct task_struct *context)
 {
-	struct task_struct *tsk = current;
-	unsigned long flags;
-	struct key *key, *ret, *err, *tmp;
+	struct request_key_auth *rka;
+	struct key *key, *ret, *err, *instkey;
 
 	/* we want to return -EAGAIN or -ENOKEY if any of the keyrings were
 	 * searchable, but we failed to find a key or we found a negative key;
@@ -402,9 +396,9 @@ struct key *search_process_keyrings_aux(
 	err = ERR_PTR(-EAGAIN);
 
 	/* search the thread keyring first */
-	if (tsk->thread_keyring) {
-		key = keyring_search_aux(tsk->thread_keyring, type,
-					 description, match);
+	if (context->thread_keyring) {
+		key = keyring_search_aux(context->thread_keyring,
+					 context, type, description, match);
 		if (!IS_ERR(key))
 			goto found;
 
@@ -422,9 +416,9 @@ struct key *search_process_keyrings_aux(
 	}
 
 	/* search the process keyring second */
-	if (tsk->signal->process_keyring) {
-		key = keyring_search_aux(tsk->signal->process_keyring,
-					 type, description, match);
+	if (context->signal->process_keyring) {
+		key = keyring_search_aux(context->signal->process_keyring,
+					 context, type, description, match);
 		if (!IS_ERR(key))
 			goto found;
 
@@ -441,52 +435,93 @@ struct key *search_process_keyrings_aux(
 		}
 	}
 
-	/* search the session keyring last */
-	spin_lock_irqsave(&tsk->sighand->siglock, flags);
+	/* search the session keyring */
+	if (context->signal->session_keyring) {
+		rcu_read_lock();
+		key = keyring_search_aux(
+			rcu_dereference(context->signal->session_keyring),
+			context, type, description, match);
+		rcu_read_unlock();
 
-	tmp = tsk->signal->session_keyring;
-	if (!tmp)
-		tmp = tsk->user->session_keyring;
-	atomic_inc(&tmp->usage);
+		if (!IS_ERR(key))
+			goto found;
 
-	spin_unlock_irqrestore(&tsk->sighand->siglock, flags);
+		switch (PTR_ERR(key)) {
+		case -EAGAIN: /* no key */
+			if (ret)
+				break;
+		case -ENOKEY: /* negative key */
+			ret = key;
+			break;
+		default:
+			err = key;
+			break;
+		}
+
+		/* if this process has a session keyring and that has an
+		 * instantiation authorisation key in the bottom level, then we
+		 * also search the keyrings of the process mentioned there */
+		if (context != current)
+			goto no_key;
+
+		rcu_read_lock();
+		instkey = __keyring_search_one(
+			rcu_dereference(context->signal->session_keyring),
+			&key_type_request_key_auth, NULL, 0);
+		rcu_read_unlock();
+
+		if (IS_ERR(instkey))
+			goto no_key;
+
+		rka = instkey->payload.data;
+
+		key = search_process_keyrings(type, description, match,
+					      rka->context);
+		key_put(instkey);
+
+		if (!IS_ERR(key))
+			goto found;
 
-	key = keyring_search_aux(tmp, type, description, match);
-	key_put(tmp);
-	if (!IS_ERR(key))
-		goto found;
-
-	switch (PTR_ERR(key)) {
-	case -EAGAIN: /* no key */
-		if (ret)
+		switch (PTR_ERR(key)) {
+		case -EAGAIN: /* no key */
+			if (ret)
+				break;
+		case -ENOKEY: /* negative key */
+			ret = key;
 			break;
-	case -ENOKEY: /* negative key */
-		ret = key;
-		break;
-	default:
-		err = key;
-		break;
+		default:
+			err = key;
+			break;
+		}
 	}
+	/* or search the user-session keyring */
+	else {
+		key = keyring_search_aux(context->user->session_keyring,
+					 context, type, description, match);
+		if (!IS_ERR(key))
+			goto found;
 
+		switch (PTR_ERR(key)) {
+		case -EAGAIN: /* no key */
+			if (ret)
+				break;
+		case -ENOKEY: /* negative key */
+			ret = key;
+			break;
+		default:
+			err = key;
+			break;
+		}
+	}
+
+
+no_key:
 	/* no key - decide on the error we're going to go for */
 	key = ret ? ret : err;
 
- found:
+found:
 	return key;
 
-} /* end search_process_keyrings_aux() */
-
-/*****************************************************************************/
-/*
- * search the process keyrings for the first matching key
- * - we return -EAGAIN if we didn't find any matching key
- * - we return -ENOKEY if we found only negative matching keys
- */
-struct key *search_process_keyrings(struct key_type *type,
-				    const char *description)
-{
-	return search_process_keyrings_aux(type, description, type->match);
-
 } /* end search_process_keyrings() */
 
 /*****************************************************************************/
@@ -495,72 +530,73 @@ struct key *search_process_keyrings(stru
  * - don't create special keyrings unless so requested
  * - partially constructed keys aren't found unless requested
  */
-struct key *lookup_user_key(key_serial_t id, int create, int partial,
-			    key_perm_t perm)
+struct key *lookup_user_key(struct task_struct *context, key_serial_t id,
+			    int create, int partial, key_perm_t perm)
 {
-	struct task_struct *tsk = current;
-	unsigned long flags;
 	struct key *key;
 	int ret;
 
+	if (!context)
+		context = current;
+
 	key = ERR_PTR(-ENOKEY);
 
 	switch (id) {
 	case KEY_SPEC_THREAD_KEYRING:
-		if (!tsk->thread_keyring) {
+		if (!context->thread_keyring) {
 			if (!create)
 				goto error;
 
-			ret = install_thread_keyring(tsk);
+			ret = install_thread_keyring(context);
 			if (ret < 0) {
 				key = ERR_PTR(ret);
 				goto error;
 			}
 		}
 
-		key = tsk->thread_keyring;
+		key = context->thread_keyring;
 		atomic_inc(&key->usage);
 		break;
 
 	case KEY_SPEC_PROCESS_KEYRING:
-		if (!tsk->signal->process_keyring) {
+		if (!context->signal->process_keyring) {
 			if (!create)
 				goto error;
 
-			ret = install_process_keyring(tsk);
+			ret = install_process_keyring(context);
 			if (ret < 0) {
 				key = ERR_PTR(ret);
 				goto error;
 			}
 		}
 
-		key = tsk->signal->process_keyring;
+		key = context->signal->process_keyring;
 		atomic_inc(&key->usage);
 		break;
 
 	case KEY_SPEC_SESSION_KEYRING:
-		if (!tsk->signal->session_keyring) {
+		if (!context->signal->session_keyring) {
 			/* always install a session keyring upon access if one
 			 * doesn't exist yet */
 			ret = install_session_keyring(
-			       tsk, tsk->user->session_keyring);
+			       context, context->user->session_keyring);
 			if (ret < 0)
 				goto error;
 		}
 
-		spin_lock_irqsave(&tsk->sighand->siglock, flags);
-		key = tsk->signal->session_keyring;
+		rcu_read_lock();
+		key = rcu_dereference(context->signal->session_keyring);
 		atomic_inc(&key->usage);
-		spin_unlock_irqrestore(&tsk->sighand->siglock, flags);
+		rcu_read_unlock();
 		break;
 
 	case KEY_SPEC_USER_KEYRING:
-		key = tsk->user->uid_keyring;
+		key = context->user->uid_keyring;
 		atomic_inc(&key->usage);
 		break;
 
 	case KEY_SPEC_USER_SESSION_KEYRING:
-		key = tsk->user->session_keyring;
+		key = context->user->session_keyring;
 		atomic_inc(&key->usage);
 		break;
 
@@ -580,7 +616,7 @@ struct key *lookup_user_key(key_serial_t
 		break;
 	}
 
-	/* check the status and permissions */
+	/* check the status */
 	if (perm) {
 		ret = key_validate(key);
 		if (ret < 0)
@@ -588,11 +624,13 @@ struct key *lookup_user_key(key_serial_t
 	}
 
 	ret = -EIO;
-	if (!partial && !(key->flags & KEY_FLAG_INSTANTIATED))
+	if (!partial && !test_bit(KEY_FLAG_INSTANTIATED, &key->flags))
 		goto invalid_key;
 
+	/* check the permissions */
 	ret = -EACCES;
-	if (!key_permission(key, perm))
+
+	if (!key_task_permission(key, context, perm))
 		goto invalid_key;
 
  error:
@@ -615,7 +653,6 @@ struct key *lookup_user_key(key_serial_t
 long join_session_keyring(const char *name)
 {
 	struct task_struct *tsk = current;
-	unsigned long flags;
 	struct key *keyring;
 	long ret;
 
@@ -625,9 +662,9 @@ long join_session_keyring(const char *na
 		if (ret < 0)
 			goto error;
 
-		spin_lock_irqsave(&tsk->sighand->siglock, flags);
-		ret = tsk->signal->session_keyring->serial;
-		spin_unlock_irqrestore(&tsk->sighand->siglock, flags);
+		rcu_read_lock();
+		ret = rcu_dereference(tsk->signal->session_keyring)->serial;
+		rcu_read_unlock();
 		goto error;
 	}
 
@@ -641,7 +678,7 @@ long join_session_keyring(const char *na
 		keyring = keyring_alloc(name, tsk->uid, tsk->gid, 0, NULL);
 		if (IS_ERR(keyring)) {
 			ret = PTR_ERR(keyring);
-			goto error;
+			goto error2;
 		}
 	}
 	else if (IS_ERR(keyring)) {
diff --git a/security/keys/request_key.c b/security/keys/request_key.c
--- a/security/keys/request_key.c
+++ b/security/keys/request_key.c
@@ -1,6 +1,6 @@
 /* request_key.c: request a key from userspace
  *
- * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Copyright (C) 2004-5 Red Hat, Inc. All Rights Reserved.
  * Written by David Howells (dhowells@redhat.com)
  *
  * This program is free software; you can redistribute it and/or
@@ -13,6 +13,7 @@
 #include <linux/sched.h>
 #include <linux/kmod.h>
 #include <linux/err.h>
+#include <linux/keyctl.h>
 #include "internal.h"
 
 struct key_construction {
@@ -27,18 +28,26 @@ DECLARE_WAIT_QUEUE_HEAD(request_key_cons
 /*
  * request userspace finish the construction of a key
  * - execute "/sbin/request-key <op> <key> <uid> <gid> <keyring> <keyring> <keyring> <info>"
- * - if callout_info is an empty string, it'll be rendered as a "-" instead
  */
 static int call_request_key(struct key *key,
 			    const char *op,
 			    const char *callout_info)
 {
 	struct task_struct *tsk = current;
-	unsigned long flags;
 	key_serial_t prkey, sskey;
+	struct key *session_keyring, *rkakey;
 	char *argv[10], *envp[3], uid_str[12], gid_str[12];
 	char key_str[12], keyring_str[3][12];
-	int i;
+	int ret, i;
+
+	kenter("{%d},%s,%s", key->serial, op, callout_info);
+
+	/* generate a new session keyring with an auth key in it */
+	session_keyring = request_key_auth_new(key, &rkakey);
+	if (IS_ERR(session_keyring)) {
+		ret = PTR_ERR(session_keyring);
+		goto error;
+	}
 
 	/* record the UID and GID */
 	sprintf(uid_str, "%d", current->fsuid);
@@ -55,17 +64,17 @@ static int call_request_key(struct key *
 	if (tsk->signal->process_keyring)
 		prkey = tsk->signal->process_keyring->serial;
 
-	sskey = 0;
-	spin_lock_irqsave(&tsk->sighand->siglock, flags);
-	if (tsk->signal->session_keyring)
-		sskey = tsk->signal->session_keyring->serial;
-	spin_unlock_irqrestore(&tsk->sighand->siglock, flags);
-
+	sprintf(keyring_str[1], "%d", prkey);
 
-	if (!sskey)
+	if (tsk->signal->session_keyring) {
+		rcu_read_lock();
+		sskey = rcu_dereference(tsk->signal->session_keyring)->serial;
+		rcu_read_unlock();
+	}
+	else {
 		sskey = tsk->user->session_keyring->serial;
+	}
 
-	sprintf(keyring_str[1], "%d", prkey);
 	sprintf(keyring_str[2], "%d", sskey);
 
 	/* set up a minimal environment */
@@ -84,11 +93,20 @@ static int call_request_key(struct key *
 	argv[i++] = keyring_str[0];
 	argv[i++] = keyring_str[1];
 	argv[i++] = keyring_str[2];
-	argv[i++] = callout_info[0] ? (char *) callout_info : "-";
+	argv[i++] = (char *) callout_info;
 	argv[i] = NULL;
 
 	/* do it */
-	return call_usermodehelper(argv[0], argv, envp, 1);
+	ret = call_usermodehelper_keys(argv[0], argv, envp, session_keyring, 1);
+
+	/* dispose of the special keys */
+	key_revoke(rkakey);
+	key_put(rkakey);
+	key_put(session_keyring);
+
+ error:
+	kleave(" = %d", ret);
+	return ret;
 
 } /* end call_request_key() */
 
@@ -105,7 +123,9 @@ static struct key *__request_key_constru
 	struct key_construction cons;
 	struct timespec now;
 	struct key *key;
-	int ret, negative;
+	int ret, negated;
+
+	kenter("%s,%s,%s", type->name, description, callout_info);
 
 	/* create a key and add it to the queue */
 	key = key_alloc(type, description,
@@ -113,9 +133,7 @@ static struct key *__request_key_constru
 	if (IS_ERR(key))
 		goto alloc_failed;
 
-	write_lock(&key->lock);
-	key->flags |= KEY_FLAG_USER_CONSTRUCT;
-	write_unlock(&key->lock);
+	set_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags);
 
 	cons.key = key;
 	list_add_tail(&cons.link, &key->user->consq);
@@ -130,7 +148,7 @@ static struct key *__request_key_constru
 
 	/* if the key wasn't instantiated, then we want to give an error */
 	ret = -ENOKEY;
-	if (!(key->flags & KEY_FLAG_INSTANTIATED))
+	if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags))
 		goto request_failed;
 
 	down_write(&key_construction_sem);
@@ -139,12 +157,13 @@ static struct key *__request_key_constru
 
 	/* also give an error if the key was negatively instantiated */
  check_not_negative:
-	if (key->flags & KEY_FLAG_NEGATIVE) {
+	if (test_bit(KEY_FLAG_NEGATIVE, &key->flags)) {
 		key_put(key);
 		key = ERR_PTR(-ENOKEY);
 	}
 
  out:
+	kleave(" = %p", key);
 	return key;
 
  request_failed:
@@ -152,24 +171,23 @@ static struct key *__request_key_constru
 	 * - remove from construction queue
 	 * - mark the key as dead
 	 */
-	negative = 0;
+	negated = 0;
 	down_write(&key_construction_sem);
 
 	list_del(&cons.link);
 
-	write_lock(&key->lock);
-	key->flags &= ~KEY_FLAG_USER_CONSTRUCT;
-
 	/* check it didn't get instantiated between the check and the down */
-	if (!(key->flags & KEY_FLAG_INSTANTIATED)) {
-		key->flags |= KEY_FLAG_INSTANTIATED | KEY_FLAG_NEGATIVE;
-		negative = 1;
+	if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) {
+		set_bit(KEY_FLAG_NEGATIVE, &key->flags);
+		set_bit(KEY_FLAG_INSTANTIATED, &key->flags);
+		negated = 1;
 	}
 
-	write_unlock(&key->lock);
+	clear_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags);
+
 	up_write(&key_construction_sem);
 
-	if (!negative)
+	if (!negated)
 		goto check_not_negative; /* surprisingly, the key got
 					  * instantiated */
 
@@ -178,13 +196,12 @@ static struct key *__request_key_constru
 	key->expiry = now.tv_sec + key_negative_timeout;
 
 	if (current->signal->session_keyring) {
-		unsigned long flags;
 		struct key *keyring;
 
-		spin_lock_irqsave(&current->sighand->siglock, flags);
-		keyring = current->signal->session_keyring;
+		rcu_read_lock();
+		keyring = rcu_dereference(current->signal->session_keyring);
 		atomic_inc(&keyring->usage);
-		spin_unlock_irqrestore(&current->sighand->siglock, flags);
+		rcu_read_unlock();
 
 		key_link(keyring, key);
 		key_put(keyring);
@@ -220,6 +237,9 @@ static struct key *request_key_construct
 
 	DECLARE_WAITQUEUE(myself, current);
 
+	kenter("%s,%s,{%d},%s",
+	       type->name, description, user->uid, callout_info);
+
 	/* see if there's such a key under construction already */
 	down_write(&key_construction_sem);
 
@@ -236,6 +256,7 @@ static struct key *request_key_construct
 	/* see about getting userspace to construct the key */
 	key = __request_key_construction(type, description, callout_info);
  error:
+	kleave(" = %p", key);
 	return key;
 
 	/* someone else has the same key under construction
@@ -249,8 +270,10 @@ static struct key *request_key_construct
 	add_wait_queue(&request_key_conswq, &myself);
 
 	for (;;) {
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		if (!(ckey->flags & KEY_FLAG_USER_CONSTRUCT))
+		set_current_state(TASK_INTERRUPTIBLE);
+		if (!test_bit(KEY_FLAG_USER_CONSTRUCT, &ckey->flags))
+			break;
+		if (signal_pending(current))
 			break;
 		schedule();
 	}
@@ -271,21 +294,83 @@ static struct key *request_key_construct
 
 /*****************************************************************************/
 /*
+ * link a freshly minted key to an appropriate destination keyring
+ */
+static void request_key_link(struct key *key, struct key *dest_keyring)
+{
+	struct task_struct *tsk = current;
+	struct key *drop = NULL;
+
+	kenter("{%d},%p", key->serial, dest_keyring);
+
+	/* find the appropriate keyring */
+	if (!dest_keyring) {
+		switch (tsk->jit_keyring) {
+		case KEY_REQKEY_DEFL_DEFAULT:
+		case KEY_REQKEY_DEFL_THREAD_KEYRING:
+			dest_keyring = tsk->thread_keyring;
+			if (dest_keyring)
+				break;
+
+		case KEY_REQKEY_DEFL_PROCESS_KEYRING:
+			dest_keyring = tsk->signal->process_keyring;
+			if (dest_keyring)
+				break;
+
+		case KEY_REQKEY_DEFL_SESSION_KEYRING:
+			rcu_read_lock();
+			dest_keyring = key_get(
+				rcu_dereference(tsk->signal->session_keyring));
+			rcu_read_unlock();
+			drop = dest_keyring;
+
+			if (dest_keyring)
+				break;
+
+		case KEY_REQKEY_DEFL_USER_SESSION_KEYRING:
+			dest_keyring = current->user->session_keyring;
+			break;
+
+		case KEY_REQKEY_DEFL_USER_KEYRING:
+			dest_keyring = current->user->uid_keyring;
+			break;
+
+		case KEY_REQKEY_DEFL_GROUP_KEYRING:
+		default:
+			BUG();
+		}
+	}
+
+	/* and attach the key to it */
+	key_link(dest_keyring, key);
+
+	key_put(drop);
+
+	kleave("");
+
+} /* end request_key_link() */
+
+/*****************************************************************************/
+/*
  * request a key
  * - search the process's keyrings
  * - check the list of keys being created or updated
- * - call out to userspace for a key if requested (supplementary info can be
- *   passed)
+ * - call out to userspace for a key if supplementary info was provided
+ * - cache the key in an appropriate keyring
  */
-struct key *request_key(struct key_type *type,
-			const char *description,
-			const char *callout_info)
+struct key *request_key_and_link(struct key_type *type,
+				 const char *description,
+				 const char *callout_info,
+				 struct key *dest_keyring)
 {
 	struct key_user *user;
 	struct key *key;
 
+	kenter("%s,%s,%s,%p",
+	       type->name, description, callout_info, dest_keyring);
+
 	/* search all the process keyrings for a key */
-	key = search_process_keyrings_aux(type, description, type->match);
+	key = search_process_keyrings(type, description, type->match, current);
 
 	if (PTR_ERR(key) == -EAGAIN) {
 		/* the search failed, but the keyrings were searchable, so we
@@ -296,12 +381,13 @@ struct key *request_key(struct key_type 
 
 		/* - get hold of the user's construction queue */
 		user = key_user_lookup(current->fsuid);
-		if (!user) {
-			key = ERR_PTR(-ENOMEM);
-			goto error;
-		}
+		if (!user)
+			goto nomem;
+
+		do {
+			if (signal_pending(current))
+				goto interrupted;
 
-		for (;;) {
 			/* ask userspace (returns NULL if it waited on a key
 			 * being constructed) */
 			key = request_key_construction(type, description,
@@ -311,18 +397,46 @@ struct key *request_key(struct key_type 
 
 			/* someone else made the key we want, so we need to
 			 * search again as it might now be available to us */
-			key = search_process_keyrings_aux(type, description,
-							  type->match);
-			if (PTR_ERR(key) != -EAGAIN)
-				break;
-		}
+			key = search_process_keyrings(type, description,
+						      type->match, current);
+
+		} while (PTR_ERR(key) == -EAGAIN);
 
 		key_user_put(user);
+
+		/* link the new key into the appropriate keyring */
+		if (!IS_ERR(key))
+			request_key_link(key, dest_keyring);
 	}
 
- error:
+error:
+	kleave(" = %p", key);
 	return key;
 
+nomem:
+	key = ERR_PTR(-ENOMEM);
+	goto error;
+
+interrupted:
+	key_user_put(user);
+	key = ERR_PTR(-EINTR);
+	goto error;
+
+} /* end request_key_and_link() */
+
+/*****************************************************************************/
+/*
+ * request a key
+ * - search the process's keyrings
+ * - check the list of keys being created or updated
+ * - call out to userspace for a key if supplementary info was provided
+ */
+struct key *request_key(struct key_type *type,
+			const char *description,
+			const char *callout_info)
+{
+	return request_key_and_link(type, description, callout_info, NULL);
+
 } /* end request_key() */
 
 EXPORT_SYMBOL(request_key);
@@ -339,7 +453,8 @@ int key_validate(struct key *key)
 	if (key) {
 		/* check it's still accessible */
 		ret = -EKEYREVOKED;
-		if (key->flags & (KEY_FLAG_REVOKED | KEY_FLAG_DEAD))
+		if (test_bit(KEY_FLAG_REVOKED, &key->flags) ||
+		    test_bit(KEY_FLAG_DEAD, &key->flags))
 			goto error;
 
 		/* check it hasn't expired */
diff --git a/security/keys/request_key_auth.c b/security/keys/request_key_auth.c
new file mode 100644
--- /dev/null
+++ b/security/keys/request_key_auth.c
@@ -0,0 +1,180 @@
+/* request_key_auth.c: request key authorisation controlling key def
+ *
+ * Copyright (C) 2005 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@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.
+ */
+
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/err.h>
+#include <linux/seq_file.h>
+#include "internal.h"
+
+static int request_key_auth_instantiate(struct key *, const void *, size_t);
+static void request_key_auth_describe(const struct key *, struct seq_file *);
+static void request_key_auth_destroy(struct key *);
+
+/*
+ * the request-key authorisation key type definition
+ */
+struct key_type key_type_request_key_auth = {
+	.name		= ".request_key_auth",
+	.def_datalen	= sizeof(struct request_key_auth),
+	.instantiate	= request_key_auth_instantiate,
+	.describe	= request_key_auth_describe,
+	.destroy	= request_key_auth_destroy,
+};
+
+/*****************************************************************************/
+/*
+ * instantiate a request-key authorisation record
+ */
+static int request_key_auth_instantiate(struct key *key,
+					const void *data,
+					size_t datalen)
+{
+	struct request_key_auth *rka, *irka;
+	struct key *instkey;
+	int ret;
+
+	ret = -ENOMEM;
+	rka = kmalloc(sizeof(*rka), GFP_KERNEL);
+	if (rka) {
+		/* see if the calling process is already servicing the key
+		 * request of another process */
+		instkey = key_get_instantiation_authkey(0);
+		if (!IS_ERR(instkey)) {
+			/* it is - use that instantiation context here too */
+			irka = instkey->payload.data;
+			rka->context = irka->context;
+			rka->pid = irka->pid;
+			key_put(instkey);
+		}
+		else {
+			/* it isn't - use this process as the context */
+			rka->context = current;
+			rka->pid = current->pid;
+		}
+
+		rka->target_key = key_get((struct key *) data);
+		key->payload.data = rka;
+		ret = 0;
+	}
+
+	return ret;
+
+} /* end request_key_auth_instantiate() */
+
+/*****************************************************************************/
+/*
+ *
+ */
+static void request_key_auth_describe(const struct key *key,
+				      struct seq_file *m)
+{
+	struct request_key_auth *rka = key->payload.data;
+
+	seq_puts(m, "key:");
+	seq_puts(m, key->description);
+	seq_printf(m, " pid:%d", rka->pid);
+
+} /* end request_key_auth_describe() */
+
+/*****************************************************************************/
+/*
+ * destroy an instantiation authorisation token key
+ */
+static void request_key_auth_destroy(struct key *key)
+{
+	struct request_key_auth *rka = key->payload.data;
+
+	kenter("{%d}", key->serial);
+
+	key_put(rka->target_key);
+
+} /* end request_key_auth_destroy() */
+
+/*****************************************************************************/
+/*
+ * create a session keyring to be for the invokation of /sbin/request-key and
+ * stick an authorisation token in it
+ */
+struct key *request_key_auth_new(struct key *target, struct key **_rkakey)
+{
+	struct key *keyring, *rkakey = NULL;
+	char desc[20];
+	int ret;
+
+	kenter("%d,", target->serial);
+
+	/* allocate a new session keyring */
+	sprintf(desc, "_req.%u", target->serial);
+
+	keyring = keyring_alloc(desc, current->fsuid, current->fsgid, 1, NULL);
+	if (IS_ERR(keyring)) {
+		kleave("= %ld", PTR_ERR(keyring));
+		return keyring;
+	}
+
+	/* allocate the auth key */
+	sprintf(desc, "%x", target->serial);
+
+	rkakey = key_alloc(&key_type_request_key_auth, desc,
+			   current->fsuid, current->fsgid,
+			   KEY_USR_VIEW, 1);
+	if (IS_ERR(rkakey)) {
+		key_put(keyring);
+		kleave("= %ld", PTR_ERR(rkakey));
+		return rkakey;
+	}
+
+	/* construct and attach to the keyring */
+	ret = key_instantiate_and_link(rkakey, target, 0, keyring, NULL);
+	if (ret < 0) {
+		key_revoke(rkakey);
+		key_put(rkakey);
+		key_put(keyring);
+		kleave("= %d", ret);
+		return ERR_PTR(ret);
+	}
+
+	*_rkakey = rkakey;
+	kleave(" = {%d} ({%d})", keyring->serial, rkakey->serial);
+	return keyring;
+
+} /* end request_key_auth_new() */
+
+/*****************************************************************************/
+/*
+ * get the authorisation key for instantiation of a specific key if attached to
+ * the current process's keyrings
+ * - this key is inserted into a keyring and that is set as /sbin/request-key's
+ *   session keyring
+ * - a target_id of zero specifies any valid token
+ */
+struct key *key_get_instantiation_authkey(key_serial_t target_id)
+{
+	struct task_struct *tsk = current;
+	struct key *instkey;
+
+	/* we must have our own personal session keyring */
+	if (!tsk->signal->session_keyring)
+		return ERR_PTR(-EACCES);
+
+	/* and it must contain a suitable request authorisation key
+	 * - lock RCU against session keyring changing
+	 */
+	rcu_read_lock();
+
+	instkey = keyring_search_instkey(
+		rcu_dereference(tsk->signal->session_keyring), target_id);
+
+	rcu_read_unlock();
+	return instkey;
+
+} /* end key_get_instantiation_authkey() */
diff --git a/security/keys/user_defined.c b/security/keys/user_defined.c
--- a/security/keys/user_defined.c
+++ b/security/keys/user_defined.c
@@ -42,12 +42,21 @@ struct key_type key_type_user = {
 	.read		= user_read,
 };
 
+struct user_key_payload {
+	struct rcu_head	rcu;		/* RCU destructor */
+	unsigned short	datalen;	/* length of this data */
+	char		data[0];	/* actual data */
+};
+
+EXPORT_SYMBOL_GPL(key_type_user);
+
 /*****************************************************************************/
 /*
  * instantiate a user defined key
  */
 static int user_instantiate(struct key *key, const void *data, size_t datalen)
 {
+	struct user_key_payload *upayload;
 	int ret;
 
 	ret = -EINVAL;
@@ -58,13 +67,15 @@ static int user_instantiate(struct key *
 	if (ret < 0)
 		goto error;
 
-	/* attach the data */
 	ret = -ENOMEM;
-	key->payload.data = kmalloc(datalen, GFP_KERNEL);
-	if (!key->payload.data)
+	upayload = kmalloc(sizeof(*upayload) + datalen, GFP_KERNEL);
+	if (!upayload)
 		goto error;
 
-	memcpy(key->payload.data, data, datalen);
+	/* attach the data */
+	upayload->datalen = datalen;
+	memcpy(upayload->data, data, datalen);
+	rcu_assign_pointer(key->payload.data, upayload);
 	ret = 0;
 
  error:
@@ -75,18 +86,25 @@ static int user_instantiate(struct key *
 /*****************************************************************************/
 /*
  * duplicate a user defined key
+ * - both keys' semaphores are locked against further modification
+ * - the new key cannot yet be accessed
  */
 static int user_duplicate(struct key *key, const struct key *source)
 {
+	struct user_key_payload *upayload, *spayload;
 	int ret;
 
 	/* just copy the payload */
 	ret = -ENOMEM;
-	key->payload.data = kmalloc(source->datalen, GFP_KERNEL);
+	upayload = kmalloc(sizeof(*upayload) + source->datalen, GFP_KERNEL);
+	if (upayload) {
+		spayload = rcu_dereference(source->payload.data);
+		BUG_ON(source->datalen != spayload->datalen);
+
+		upayload->datalen = key->datalen = spayload->datalen;
+		memcpy(upayload->data, spayload->data, key->datalen);
 
-	if (key->payload.data) {
-		key->datalen = source->datalen;
-		memcpy(key->payload.data, source->payload.data, source->datalen);
+		key->payload.data = upayload;
 		ret = 0;
 	}
 
@@ -96,40 +114,54 @@ static int user_duplicate(struct key *ke
 
 /*****************************************************************************/
 /*
+ * dispose of the old data from an updated user defined key
+ */
+static void user_update_rcu_disposal(struct rcu_head *rcu)
+{
+	struct user_key_payload *upayload;
+
+	upayload = container_of(rcu, struct user_key_payload, rcu);
+
+	kfree(upayload);
+
+} /* end user_update_rcu_disposal() */
+
+/*****************************************************************************/
+/*
  * update a user defined key
+ * - the key's semaphore is write-locked
  */
 static int user_update(struct key *key, const void *data, size_t datalen)
 {
-	void *new, *zap;
+	struct user_key_payload *upayload, *zap;
 	int ret;
 
 	ret = -EINVAL;
 	if (datalen <= 0 || datalen > 32767 || !data)
 		goto error;
 
-	/* copy the data */
+	/* construct a replacement payload */
 	ret = -ENOMEM;
-	new = kmalloc(datalen, GFP_KERNEL);
-	if (!new)
+	upayload = kmalloc(sizeof(*upayload) + datalen, GFP_KERNEL);
+	if (!upayload)
 		goto error;
 
-	memcpy(new, data, datalen);
+	upayload->datalen = datalen;
+	memcpy(upayload->data, data, datalen);
 
 	/* check the quota and attach the new data */
-	zap = new;
-	write_lock(&key->lock);
+	zap = upayload;
 
 	ret = key_payload_reserve(key, datalen);
 
 	if (ret == 0) {
 		/* attach the new data, displacing the old */
 		zap = key->payload.data;
-		key->payload.data = new;
+		rcu_assign_pointer(key->payload.data, upayload);
 		key->expiry = 0;
 	}
 
-	write_unlock(&key->lock);
-	kfree(zap);
+	call_rcu(&zap->rcu, user_update_rcu_disposal);
 
  error:
 	return ret;
@@ -152,13 +184,15 @@ static int user_match(const struct key *
  */
 static void user_destroy(struct key *key)
 {
-	kfree(key->payload.data);
+	struct user_key_payload *upayload = key->payload.data;
+
+	kfree(upayload);
 
 } /* end user_destroy() */
 
 /*****************************************************************************/
 /*
- * describe the user
+ * describe the user key
  */
 static void user_describe(const struct key *key, struct seq_file *m)
 {
@@ -171,18 +205,23 @@ static void user_describe(const struct k
 /*****************************************************************************/
 /*
  * read the key data
+ * - the key's semaphore is read-locked
  */
 static long user_read(const struct key *key,
 		      char __user *buffer, size_t buflen)
 {
-	long ret = key->datalen;
+	struct user_key_payload *upayload;
+	long ret;
+
+	upayload = rcu_dereference(key->payload.data);
+	ret = upayload->datalen;
 
 	/* we can return the data as is */
 	if (buffer && buflen > 0) {
-		if (buflen > key->datalen)
-			buflen = key->datalen;
+		if (buflen > upayload->datalen)
+			buflen = upayload->datalen;
 
-		if (copy_to_user(buffer, key->payload.data, buflen) != 0)
+		if (copy_to_user(buffer, upayload->data, buflen) != 0)
 			ret = -EFAULT;
 	}
 
diff --git a/security/seclvl.c b/security/seclvl.c
--- a/security/seclvl.c
+++ b/security/seclvl.c
@@ -155,7 +155,7 @@ seclvl_attr_store(struct kobject *kobj,
 	struct seclvl_obj *obj = container_of(kobj, struct seclvl_obj, kobj);
 	struct seclvl_attribute *attribute =
 	    container_of(attr, struct seclvl_attribute, attr);
-	return (attribute->store ? attribute->store(obj, buf, len) : 0);
+	return attribute->store ? attribute->store(obj, buf, len) : -EIO;
 }
 
 static ssize_t
@@ -164,7 +164,7 @@ seclvl_attr_show(struct kobject *kobj, s
 	struct seclvl_obj *obj = container_of(kobj, struct seclvl_obj, kobj);
 	struct seclvl_attribute *attribute =
 	    container_of(attr, struct seclvl_attribute, attr);
-	return (attribute->show ? attribute->show(obj, buf) : 0);
+	return attribute->show ? attribute->show(obj, buf) : -EIO;
 }
 
 /**
diff --git a/security/selinux/avc.c b/security/selinux/avc.c
--- a/security/selinux/avc.c
+++ b/security/selinux/avc.c
@@ -242,7 +242,7 @@ void __init avc_init(void)
 	avc_node_cachep = kmem_cache_create("avc_node", sizeof(struct avc_node),
 					     0, SLAB_PANIC, NULL, NULL);
 
-	audit_log(current->audit_context, "AVC INITIALIZED\n");
+	audit_log(current->audit_context, AUDIT_KERNEL, "AVC INITIALIZED\n");
 }
 
 int avc_get_hash_stats(char *page)
@@ -532,6 +532,7 @@ void avc_audit(u32 ssid, u32 tsid,
                u16 tclass, u32 requested,
                struct av_decision *avd, int result, struct avc_audit_data *a)
 {
+	struct task_struct *tsk = current;
 	struct inode *inode = NULL;
 	u32 denied, audited;
 	struct audit_buffer *ab;
@@ -549,12 +550,18 @@ void avc_audit(u32 ssid, u32 tsid,
 			return;
 	}
 
-	ab = audit_log_start(current->audit_context);
+	ab = audit_log_start(current->audit_context, AUDIT_AVC);
 	if (!ab)
 		return;		/* audit_panic has been called */
 	audit_log_format(ab, "avc:  %s ", denied ? "denied" : "granted");
 	avc_dump_av(ab, tclass,audited);
 	audit_log_format(ab, " for ");
+	if (a && a->tsk)
+		tsk = a->tsk;
+	if (tsk && tsk->pid) {
+		audit_log_format(ab, " pid=%d comm=", tsk->pid);
+		audit_log_untrustedstring(ab, tsk->comm);
+	}
 	if (a) {
 		switch (a->type) {
 		case AVC_AUDIT_DATA_IPC:
@@ -566,21 +573,18 @@ void avc_audit(u32 ssid, u32 tsid,
 		case AVC_AUDIT_DATA_FS:
 			if (a->u.fs.dentry) {
 				struct dentry *dentry = a->u.fs.dentry;
-				if (a->u.fs.mnt) {
-					audit_log_d_path(ab, "path=", dentry,
-							a->u.fs.mnt);
-				} else {
-					audit_log_format(ab, " name=%s",
-							 dentry->d_name.name);
-				}
+				if (a->u.fs.mnt)
+					audit_avc_path(dentry, a->u.fs.mnt);
+				audit_log_format(ab, " name=");
+				audit_log_untrustedstring(ab, dentry->d_name.name);
 				inode = dentry->d_inode;
 			} else if (a->u.fs.inode) {
 				struct dentry *dentry;
 				inode = a->u.fs.inode;
 				dentry = d_find_alias(inode);
 				if (dentry) {
-					audit_log_format(ab, " name=%s",
-							 dentry->d_name.name);
+					audit_log_format(ab, " name=");
+					audit_log_untrustedstring(ab, dentry->d_name.name);
 					dput(dentry);
 				}
 			}
@@ -623,22 +627,20 @@ void avc_audit(u32 ssid, u32 tsid,
 				case AF_UNIX:
 					u = unix_sk(sk);
 					if (u->dentry) {
-						audit_log_d_path(ab, "path=",
-							u->dentry, u->mnt);
+						audit_avc_path(u->dentry, u->mnt);
+						audit_log_format(ab, " name=");
+						audit_log_untrustedstring(ab, u->dentry->d_name.name);
 						break;
 					}
 					if (!u->addr)
 						break;
 					len = u->addr->len-sizeof(short);
 					p = &u->addr->name->sun_path[0];
+					audit_log_format(ab, " path=");
 					if (*p)
-						audit_log_format(ab,
-							"path=%*.*s", len,
-							len, p);
+						audit_log_untrustedstring(ab, p);
 					else
-						audit_log_format(ab,
-							"path=@%*.*s", len-1,
-							len-1, p+1);
+						audit_log_hex(ab, p, len);
 					break;
 				}
 			}
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -68,6 +68,7 @@
 #include <linux/personality.h>
 #include <linux/sysctl.h>
 #include <linux/audit.h>
+#include <linux/string.h>
 
 #include "avc.h"
 #include "objsec.h"
@@ -825,7 +826,8 @@ static int inode_doinit_with_dentry(stru
 			sid = sbsec->def_sid;
 			rc = 0;
 		} else {
-			rc = security_context_to_sid(context, rc, &sid);
+			rc = security_context_to_sid_default(context, rc, &sid,
+			                                     sbsec->def_sid);
 			if (rc) {
 				printk(KERN_WARNING "%s:  context_to_sid(%s) "
 				       "returned %d for dev=%s ino=%ld\n",
@@ -1658,9 +1660,8 @@ static int selinux_bprm_secureexec (stru
 
 static void selinux_bprm_free_security(struct linux_binprm *bprm)
 {
-	struct bprm_security_struct *bsec = bprm->security;
+	kfree(bprm->security);
 	bprm->security = NULL;
-	kfree(bsec);
 }
 
 extern struct vfsmount *selinuxfs_mount;
@@ -1944,7 +1945,8 @@ static int selinux_sb_copy_data(struct f
 		}
 	} while (*in_end++);
 
-	copy_page(in_save, nosec_save);
+	strcpy(in_save, nosec_save);
+	free_page((unsigned long)nosec_save);
 out:
 	return rc;
 }
@@ -2476,6 +2478,17 @@ static int selinux_file_mprotect(struct 
 		prot = reqprot;
 
 #ifndef CONFIG_PPC32
+	if ((prot & PROT_EXEC) && !(vma->vm_flags & VM_EXECUTABLE) &&
+	   (vma->vm_start >= vma->vm_mm->start_brk &&
+	    vma->vm_end <= vma->vm_mm->brk)) {
+	    	/*
+		 * We are making an executable mapping in the brk region.
+		 * This has an additional execheap check.
+		 */
+		rc = task_has_perm(current, current, PROCESS__EXECHEAP);
+		if (rc)
+			return rc;
+	}
 	if (vma->vm_file != NULL && vma->anon_vma != NULL && (prot & PROT_EXEC)) {
 		/*
 		 * We are making executable a file mapping that has
@@ -2487,6 +2500,16 @@ static int selinux_file_mprotect(struct 
 		if (rc)
 			return rc;
 	}
+	if (!vma->vm_file && (prot & PROT_EXEC) &&
+		vma->vm_start <= vma->vm_mm->start_stack &&
+		vma->vm_end >= vma->vm_mm->start_stack) {
+		/* Attempt to make the process stack executable.
+		 * This has an additional execstack check.
+		 */
+		rc = task_has_perm(current, current, PROCESS__EXECSTACK);
+		if (rc)
+			return rc;
+	}
 #endif
 
 	return file_map_prot_check(vma->vm_file, prot, vma->vm_flags&VM_SHARED);
@@ -3103,12 +3126,12 @@ static int selinux_socket_connect(struct
 
 		if (sk->sk_family == PF_INET) {
 			addr4 = (struct sockaddr_in *)address;
-			if (addrlen != sizeof(struct sockaddr_in))
+			if (addrlen < sizeof(struct sockaddr_in))
 				return -EINVAL;
 			snum = ntohs(addr4->sin_port);
 		} else {
 			addr6 = (struct sockaddr_in6 *)address;
-			if (addrlen != sizeof(struct sockaddr_in6))
+			if (addrlen < SIN6_LEN_RFC2133)
 				return -EINVAL;
 			snum = ntohs(addr6->sin6_port);
 		}
@@ -3419,7 +3442,7 @@ static int selinux_nlmsg_perm(struct soc
 	err = selinux_nlmsg_lookup(isec->sclass, nlh->nlmsg_type, &perm);
 	if (err) {
 		if (err == -EINVAL) {
-			audit_log(current->audit_context,
+			audit_log(current->audit_context, AUDIT_SELINUX_ERR,
 				  "SELinux:  unrecognized netlink message"
 				  " type=%hu for sclass=%hu\n",
 				  nlh->nlmsg_type, isec->sclass);
diff --git a/security/selinux/include/av_perm_to_string.h b/security/selinux/include/av_perm_to_string.h
--- a/security/selinux/include/av_perm_to_string.h
+++ b/security/selinux/include/av_perm_to_string.h
@@ -70,6 +70,8 @@
    S_(SECCLASS_PROCESS, PROCESS__DYNTRANSITION, "dyntransition")
    S_(SECCLASS_PROCESS, PROCESS__SETCURRENT, "setcurrent")
    S_(SECCLASS_PROCESS, PROCESS__EXECMEM, "execmem")
+   S_(SECCLASS_PROCESS, PROCESS__EXECSTACK, "execstack")
+   S_(SECCLASS_PROCESS, PROCESS__EXECHEAP, "execheap")
    S_(SECCLASS_MSGQ, MSGQ__ENQUEUE, "enqueue")
    S_(SECCLASS_MSG, MSG__SEND, "send")
    S_(SECCLASS_MSG, MSG__RECEIVE, "receive")
diff --git a/security/selinux/include/av_permissions.h b/security/selinux/include/av_permissions.h
--- a/security/selinux/include/av_permissions.h
+++ b/security/selinux/include/av_permissions.h
@@ -465,6 +465,8 @@
 #define PROCESS__DYNTRANSITION                    0x00800000UL
 #define PROCESS__SETCURRENT                       0x01000000UL
 #define PROCESS__EXECMEM                          0x02000000UL
+#define PROCESS__EXECSTACK                        0x04000000UL
+#define PROCESS__EXECHEAP                         0x08000000UL
 
 #define IPC__CREATE                               0x00000001UL
 #define IPC__DESTROY                              0x00000002UL
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -65,6 +65,8 @@ int security_sid_to_context(u32 sid, cha
 int security_context_to_sid(char *scontext, u32 scontext_len,
 	u32 *out_sid);
 
+int security_context_to_sid_default(char *scontext, u32 scontext_len, u32 *out_sid, u32 def_sid);
+
 int security_get_user_sids(u32 callsid, char *username,
 			   u32 **sids, u32 *nel);
 
diff --git a/security/selinux/nlmsgtab.c b/security/selinux/nlmsgtab.c
--- a/security/selinux/nlmsgtab.c
+++ b/security/selinux/nlmsgtab.c
@@ -63,6 +63,8 @@ static struct nlmsg_perm nlmsg_route_per
 	{ RTM_GETPREFIX,	NETLINK_ROUTE_SOCKET__NLMSG_READ  },
 	{ RTM_GETMULTICAST,	NETLINK_ROUTE_SOCKET__NLMSG_READ  },
 	{ RTM_GETANYCAST,	NETLINK_ROUTE_SOCKET__NLMSG_READ  },
+	{ RTM_GETNEIGHTBL,	NETLINK_ROUTE_SOCKET__NLMSG_READ  },
+	{ RTM_SETNEIGHTBL,	NETLINK_ROUTE_SOCKET__NLMSG_WRITE },
 };
 
 static struct nlmsg_perm nlmsg_firewall_perms[] =
@@ -97,6 +99,7 @@ static struct nlmsg_perm nlmsg_audit_per
 	{ AUDIT_ADD,		NETLINK_AUDIT_SOCKET__NLMSG_WRITE    },
 	{ AUDIT_DEL,		NETLINK_AUDIT_SOCKET__NLMSG_WRITE    },
 	{ AUDIT_USER,		NETLINK_AUDIT_SOCKET__NLMSG_RELAY    },
+	{ AUDIT_SIGNAL_INFO,	NETLINK_AUDIT_SOCKET__NLMSG_READ     },
 };
 
 
@@ -141,8 +144,13 @@ int selinux_nlmsg_lookup(u16 sclass, u16
 		break;
 
 	case SECCLASS_NETLINK_AUDIT_SOCKET:
-		err = nlmsg_perm(nlmsg_type, perm, nlmsg_audit_perms,
-				 sizeof(nlmsg_audit_perms));
+		if (nlmsg_type >= AUDIT_FIRST_USER_MSG &&
+		    nlmsg_type <= AUDIT_LAST_USER_MSG) {
+			*perm = NETLINK_AUDIT_SOCKET__NLMSG_RELAY;
+		} else {
+			err = nlmsg_perm(nlmsg_type, perm, nlmsg_audit_perms,
+					 sizeof(nlmsg_audit_perms));
+		}
 		break;
 
 	/* No messaging from userspace, or class unknown/unhandled */
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -951,8 +951,7 @@ static int sel_make_bools(void)
 	u32 sid;
 
 	/* remove any existing files */
-	if (bool_pending_values)
-		kfree(bool_pending_values);
+	kfree(bool_pending_values);
 
 	sel_remove_bools(dir);
 
@@ -997,10 +996,8 @@ static int sel_make_bools(void)
 out:
 	free_page((unsigned long)page);
 	if (names) {
-		for (i = 0; i < num; i++) {
-			if (names[i])
-				kfree(names[i]);
-		}
+		for (i = 0; i < num; i++)
+			kfree(names[i]);
 		kfree(names);
 	}
 	return ret;
diff --git a/security/selinux/ss/conditional.c b/security/selinux/ss/conditional.c
--- a/security/selinux/ss/conditional.c
+++ b/security/selinux/ss/conditional.c
@@ -166,16 +166,14 @@ static void cond_list_destroy(struct con
 
 void cond_policydb_destroy(struct policydb *p)
 {
-	if (p->bool_val_to_struct != NULL)
-		kfree(p->bool_val_to_struct);
+	kfree(p->bool_val_to_struct);
 	avtab_destroy(&p->te_cond_avtab);
 	cond_list_destroy(p->cond_list);
 }
 
 int cond_init_bool_indexes(struct policydb *p)
 {
-	if (p->bool_val_to_struct)
-		kfree(p->bool_val_to_struct);
+	kfree(p->bool_val_to_struct);
 	p->bool_val_to_struct = (struct cond_bool_datum**)
 		kmalloc(p->p_bools.nprim * sizeof(struct cond_bool_datum*), GFP_KERNEL);
 	if (!p->bool_val_to_struct)
@@ -185,8 +183,7 @@ int cond_init_bool_indexes(struct policy
 
 int cond_destroy_bool(void *key, void *datum, void *p)
 {
-	if (key)
-		kfree(key);
+	kfree(key);
 	kfree(datum);
 	return 0;
 }
diff --git a/security/selinux/ss/mls.c b/security/selinux/ss/mls.c
--- a/security/selinux/ss/mls.c
+++ b/security/selinux/ss/mls.c
@@ -15,6 +15,7 @@
 #include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/errno.h>
+#include "sidtab.h"
 #include "mls.h"
 #include "policydb.h"
 #include "services.h"
@@ -208,6 +209,26 @@ int mls_context_isvalid(struct policydb 
 }
 
 /*
+ * Copies the MLS range from `src' into `dst'.
+ */
+static inline int mls_copy_context(struct context *dst,
+				   struct context *src)
+{
+	int l, rc = 0;
+
+	/* Copy the MLS range from the source context */
+	for (l = 0; l < 2; l++) {
+		dst->range.level[l].sens = src->range.level[l].sens;
+		rc = ebitmap_cpy(&dst->range.level[l].cat,
+				 &src->range.level[l].cat);
+		if (rc)
+			break;
+	}
+
+	return rc;
+}
+
+/*
  * Set the MLS fields in the security context structure
  * `context' based on the string representation in
  * the string `*scontext'.  Update `*scontext' to
@@ -216,10 +237,20 @@ int mls_context_isvalid(struct policydb 
  *
  * This function modifies the string in place, inserting
  * NULL characters to terminate the MLS fields.
+ *
+ * If a def_sid is provided and no MLS field is present,
+ * copy the MLS field of the associated default context.
+ * Used for upgraded to MLS systems where objects may lack
+ * MLS fields.
+ *
+ * Policy read-lock must be held for sidtab lookup.
+ *
  */
 int mls_context_to_sid(char oldc,
 		       char **scontext,
-		       struct context *context)
+		       struct context *context,
+		       struct sidtab *s,
+		       u32 def_sid)
 {
 
 	char delim;
@@ -231,9 +262,23 @@ int mls_context_to_sid(char oldc,
 	if (!selinux_mls_enabled)
 		return 0;
 
-	/* No MLS component to the security context. */
-	if (!oldc)
+	/*
+	 * No MLS component to the security context, try and map to
+	 * default if provided.
+	 */
+	if (!oldc) {
+		struct context *defcon;
+
+		if (def_sid == SECSID_NULL)
+			goto out;
+
+		defcon = sidtab_search(s, def_sid);
+		if (!defcon)
+			goto out;
+
+		rc = mls_copy_context(context, defcon);
 		goto out;
+	}
 
 	/* Extract low sensitivity. */
 	scontextp = p = *scontext;
@@ -334,26 +379,6 @@ out:
 }
 
 /*
- * Copies the MLS range from `src' into `dst'.
- */
-static inline int mls_copy_context(struct context *dst,
-				   struct context *src)
-{
-	int l, rc = 0;
-
-	/* Copy the MLS range from the source context */
-	for (l = 0; l < 2; l++) {
-		dst->range.level[l].sens = src->range.level[l].sens;
-		rc = ebitmap_cpy(&dst->range.level[l].cat,
-				 &src->range.level[l].cat);
-		if (rc)
-			break;
-	}
-
-	return rc;
-}
-
-/*
  * Copies the effective MLS range from `src' into `dst'.
  */
 static inline int mls_scopy_context(struct context *dst,
diff --git a/security/selinux/ss/mls.h b/security/selinux/ss/mls.h
--- a/security/selinux/ss/mls.h
+++ b/security/selinux/ss/mls.h
@@ -23,7 +23,9 @@ int mls_context_isvalid(struct policydb 
 
 int mls_context_to_sid(char oldc,
 	               char **scontext,
-		       struct context *context);
+		       struct context *context,
+		       struct sidtab *s,
+		       u32 def_sid);
 
 int mls_convert_context(struct policydb *oldp,
 			struct policydb *newp,
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
--- a/security/selinux/ss/policydb.c
+++ b/security/selinux/ss/policydb.c
@@ -590,17 +590,12 @@ void policydb_destroy(struct policydb *p
 		hashtab_destroy(p->symtab[i].table);
 	}
 
-	for (i = 0; i < SYM_NUM; i++) {
-		if (p->sym_val_to_name[i])
-			kfree(p->sym_val_to_name[i]);
-	}
+	for (i = 0; i < SYM_NUM; i++)
+		kfree(p->sym_val_to_name[i]);
 
-	if (p->class_val_to_struct)
-		kfree(p->class_val_to_struct);
-	if (p->role_val_to_struct)
-		kfree(p->role_val_to_struct);
-	if (p->user_val_to_struct)
-		kfree(p->user_val_to_struct);
+	kfree(p->class_val_to_struct);
+	kfree(p->role_val_to_struct);
+	kfree(p->user_val_to_struct);
 
 	avtab_destroy(&p->te_avtab);
 
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -365,7 +365,7 @@ static int security_validtrans_handle_fa
 		goto out;
 	if (context_struct_to_string(tcontext, &t, &tlen) < 0)
 		goto out;
-	audit_log(current->audit_context,
+	audit_log(current->audit_context, AUDIT_SELINUX_ERR,
 	          "security_validate_transition:  denied for"
 	          " oldcontext=%s newcontext=%s taskcontext=%s tclass=%s",
 	          o, n, t, policydb.p_class_val_to_name[tclass-1]);
@@ -601,18 +601,7 @@ out:
 
 }
 
-/**
- * security_context_to_sid - Obtain a SID for a given security context.
- * @scontext: security context
- * @scontext_len: length in bytes
- * @sid: security identifier, SID
- *
- * Obtains a SID associated with the security context that
- * has the string representation specified by @scontext.
- * Returns -%EINVAL if the context is invalid, -%ENOMEM if insufficient
- * memory is available, or 0 on success.
- */
-int security_context_to_sid(char *scontext, u32 scontext_len, u32 *sid)
+static int security_context_to_sid_core(char *scontext, u32 scontext_len, u32 *sid, u32 def_sid)
 {
 	char *scontext2;
 	struct context context;
@@ -703,7 +692,7 @@ int security_context_to_sid(char *sconte
 
 	context.type = typdatum->value;
 
-	rc = mls_context_to_sid(oldc, &p, &context);
+	rc = mls_context_to_sid(oldc, &p, &context, &sidtab, def_sid);
 	if (rc)
 		goto out_unlock;
 
@@ -727,6 +716,46 @@ out:
 	return rc;
 }
 
+/**
+ * security_context_to_sid - Obtain a SID for a given security context.
+ * @scontext: security context
+ * @scontext_len: length in bytes
+ * @sid: security identifier, SID
+ *
+ * Obtains a SID associated with the security context that
+ * has the string representation specified by @scontext.
+ * Returns -%EINVAL if the context is invalid, -%ENOMEM if insufficient
+ * memory is available, or 0 on success.
+ */
+int security_context_to_sid(char *scontext, u32 scontext_len, u32 *sid)
+{
+	return security_context_to_sid_core(scontext, scontext_len,
+	                                    sid, SECSID_NULL);
+}
+
+/**
+ * security_context_to_sid_default - Obtain a SID for a given security context,
+ * falling back to specified default if needed.
+ *
+ * @scontext: security context
+ * @scontext_len: length in bytes
+ * @sid: security identifier, SID
+ * @def_sid: default SID to assign on errror
+ *
+ * Obtains a SID associated with the security context that
+ * has the string representation specified by @scontext.
+ * The default SID is passed to the MLS layer to be used to allow
+ * kernel labeling of the MLS field if the MLS field is not present
+ * (for upgrading to MLS without full relabel).
+ * Returns -%EINVAL if the context is invalid, -%ENOMEM if insufficient
+ * memory is available, or 0 on success.
+ */
+int security_context_to_sid_default(char *scontext, u32 scontext_len, u32 *sid, u32 def_sid)
+{
+	return security_context_to_sid_core(scontext, scontext_len,
+	                                    sid, def_sid);
+}
+
 static int compute_sid_handle_invalid_context(
 	struct context *scontext,
 	struct context *tcontext,
@@ -742,7 +771,7 @@ static int compute_sid_handle_invalid_co
 		goto out;
 	if (context_struct_to_string(newcontext, &n, &nlen) < 0)
 		goto out;
-	audit_log(current->audit_context,
+	audit_log(current->audit_context, AUDIT_SELINUX_ERR,
 		  "security_compute_sid:  invalid context %s"
 		  " for scontext=%s"
 		  " tcontext=%s"
@@ -1705,11 +1734,9 @@ out:
 err:
 	if (*names) {
 		for (i = 0; i < *len; i++)
-			if ((*names)[i])
-				kfree((*names)[i]);
+			kfree((*names)[i]);
 	}
-	if (*values)
-		kfree(*values);
+	kfree(*values);
 	goto out;
 }
 
diff --git a/sound/Kconfig b/sound/Kconfig
--- a/sound/Kconfig
+++ b/sound/Kconfig
@@ -42,6 +42,11 @@ menu "Advanced Linux Sound Architecture"
 config SND
 	tristate "Advanced Linux Sound Architecture"
 	depends on SOUND
+	help
+	  Say 'Y' or 'M' to enable ALSA (Advanced Linux Sound Architecture),
+	  the new base sound system.
+
+	  For more information, see <http://www.alsa-project.org/>
 
 source "sound/core/Kconfig"
 
@@ -72,7 +77,7 @@ source "sound/parisc/Kconfig"
 endmenu
 
 menu "Open Sound System"
-	depends on SOUND!=n && (BROKEN || (!SPARC32 && !SPARC64))
+	depends on SOUND!=n
 
 config SOUND_PRIME
 	tristate "Open Sound System (DEPRECATED)"
diff --git a/sound/arm/Kconfig b/sound/arm/Kconfig
--- a/sound/arm/Kconfig
+++ b/sound/arm/Kconfig
@@ -14,5 +14,23 @@ config SND_SA11XX_UDA1341
 	  To compile this driver as a module, choose M here: the module
 	  will be called snd-sa11xx-uda1341.
 
-endmenu
+config SND_ARMAACI
+	tristate "ARM PrimeCell PL041 AC Link support"
+	depends on SND && ARM_AMBA
+	select SND_PCM
+	select SND_AC97_CODEC
+
+config SND_PXA2XX_PCM
+	tristate
+	select SND_PCM
 
+config SND_PXA2XX_AC97
+	tristate "AC97 driver for the Intel PXA2xx chip"
+	depends on ARCH_PXA && SND
+	select SND_PXA2XX_PCM
+	select SND_AC97_CODEC
+	help
+	  Say Y or M if you want to support any AC97 codec attached to
+	  the PXA2xx AC97 interface.
+
+endmenu
diff --git a/sound/arm/Makefile b/sound/arm/Makefile
--- a/sound/arm/Makefile
+++ b/sound/arm/Makefile
@@ -3,6 +3,11 @@
 #
 
 snd-sa11xx-uda1341-objs := sa11xx-uda1341.o
+snd-aaci-objs			:= aaci.o devdma.o
+snd-pxa2xx-pcm-objs := pxa2xx-pcm.o
+snd-pxa2xx-ac97-objs := pxa2xx-ac97.o
 
-# Toplevel Module Dependency
 obj-$(CONFIG_SND_SA11XX_UDA1341) += snd-sa11xx-uda1341.o 
+obj-$(CONFIG_SND_ARMAACI)	+= snd-aaci.o
+obj-$(CONFIG_SND_PXA2XX_PCM) += snd-pxa2xx-pcm.o
+obj-$(CONFIG_SND_PXA2XX_AC97) += snd-pxa2xx-ac97.o
diff --git a/sound/arm/aaci.c b/sound/arm/aaci.c
new file mode 100644
--- /dev/null
+++ b/sound/arm/aaci.c
@@ -0,0 +1,968 @@
+/*
+ *  linux/sound/arm/aaci.c - ARM PrimeCell AACI PL041 driver
+ *
+ *  Copyright (C) 2003 Deep Blue Solutions Ltd, 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 version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Documentation: ARM DDI 0173B
+ */
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/device.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/err.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/hardware/amba.h>
+
+#include <sound/driver.h>
+#include <sound/core.h>
+#include <sound/initval.h>
+#include <sound/ac97_codec.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+
+#include "aaci.h"
+#include "devdma.h"
+
+#define DRIVER_NAME	"aaci-pl041"
+
+/*
+ * PM support is not complete.  Turn it off.
+ */
+#undef CONFIG_PM
+
+static void aaci_ac97_select_codec(struct aaci *aaci, ac97_t *ac97)
+{
+	u32 v, maincr = aaci->maincr | MAINCR_SCRA(ac97->num);
+
+	/*
+	 * Ensure that the slot 1/2 RX registers are empty.
+	 */
+	v = readl(aaci->base + AACI_SLFR);
+	if (v & SLFR_2RXV)
+		readl(aaci->base + AACI_SL2RX);
+	if (v & SLFR_1RXV)
+		readl(aaci->base + AACI_SL1RX);
+
+	writel(maincr, aaci->base + AACI_MAINCR);
+}
+
+/*
+ * P29:
+ *  The recommended use of programming the external codec through slot 1
+ *  and slot 2 data is to use the channels during setup routines and the
+ *  slot register at any other time.  The data written into slot 1, slot 2
+ *  and slot 12 registers is transmitted only when their corresponding
+ *  SI1TxEn, SI2TxEn and SI12TxEn bits are set in the AACI_MAINCR
+ *  register.
+ */
+static void aaci_ac97_write(ac97_t *ac97, unsigned short reg, unsigned short val)
+{
+	struct aaci *aaci = ac97->private_data;
+	u32 v;
+
+	if (ac97->num >= 4)
+		return;
+
+	down(&aaci->ac97_sem);
+
+	aaci_ac97_select_codec(aaci, ac97);
+
+	/*
+	 * P54: You must ensure that AACI_SL2TX is always written
+	 * to, if required, before data is written to AACI_SL1TX.
+	 */
+	writel(val << 4, aaci->base + AACI_SL2TX);
+	writel(reg << 12, aaci->base + AACI_SL1TX);
+
+	/*
+	 * Wait for the transmission of both slots to complete.
+	 */
+	do {
+		v = readl(aaci->base + AACI_SLFR);
+	} while (v & (SLFR_1TXB|SLFR_2TXB));
+
+	up(&aaci->ac97_sem);
+}
+
+/*
+ * Read an AC'97 register.
+ */
+static unsigned short aaci_ac97_read(ac97_t *ac97, unsigned short reg)
+{
+	struct aaci *aaci = ac97->private_data;
+	u32 v;
+
+	if (ac97->num >= 4)
+		return ~0;
+
+	down(&aaci->ac97_sem);
+
+	aaci_ac97_select_codec(aaci, ac97);
+
+	/*
+	 * Write the register address to slot 1.
+	 */
+	writel((reg << 12) | (1 << 19), aaci->base + AACI_SL1TX);
+
+	/*
+	 * Wait for the transmission to complete.
+	 */
+	do {
+		v = readl(aaci->base + AACI_SLFR);
+	} while (v & SLFR_1TXB);
+
+	/*
+	 * Give the AC'97 codec more than enough time
+	 * to respond. (42us = ~2 frames at 48kHz.)
+	 */
+	udelay(42);
+
+	/*
+	 * Wait for slot 2 to indicate data.
+	 */
+	do {
+		cond_resched();
+		v = readl(aaci->base + AACI_SLFR) & (SLFR_1RXV|SLFR_2RXV);
+	} while (v != (SLFR_1RXV|SLFR_2RXV));
+
+	v = readl(aaci->base + AACI_SL1RX) >> 12;
+	if (v == reg) {
+		v = readl(aaci->base + AACI_SL2RX) >> 4;
+	} else {
+		dev_err(&aaci->dev->dev,
+			"wrong ac97 register read back (%x != %x)\n",
+			v, reg);
+		v = ~0;
+	}
+
+	up(&aaci->ac97_sem);
+	return v;
+}
+
+static inline void aaci_chan_wait_ready(struct aaci_runtime *aacirun)
+{
+	u32 val;
+	int timeout = 5000;
+
+	do {
+		val = readl(aacirun->base + AACI_SR);
+	} while (val & (SR_TXB|SR_RXB) && timeout--);
+}
+
+
+
+/*
+ * Interrupt support.
+ */
+static void aaci_fifo_irq(struct aaci *aaci, u32 mask)
+{
+	if (mask & ISR_URINTR) {
+		writel(ICLR_TXUEC1, aaci->base + AACI_INTCLR);
+	}
+
+	if (mask & ISR_TXINTR) {
+		struct aaci_runtime *aacirun = &aaci->playback;
+		void *ptr;
+
+		if (!aacirun->substream || !aacirun->start) {
+			dev_warn(&aaci->dev->dev, "TX interrupt???");
+			writel(0, aacirun->base + AACI_IE);
+			return;
+		}
+
+		ptr = aacirun->ptr;
+		do {
+			unsigned int len = aacirun->fifosz;
+			u32 val;
+
+			if (aacirun->bytes <= 0) {
+				aacirun->bytes += aacirun->period;
+				aacirun->ptr = ptr;
+				spin_unlock(&aaci->lock);
+				snd_pcm_period_elapsed(aacirun->substream);
+				spin_lock(&aaci->lock);
+			}
+			if (!(aacirun->cr & TXCR_TXEN))
+				break;
+
+			val = readl(aacirun->base + AACI_SR);
+			if (!(val & SR_TXHE))
+				break;
+			if (!(val & SR_TXFE))
+				len >>= 1;
+
+			aacirun->bytes -= len;
+
+			/* writing 16 bytes at a time */
+			for ( ; len > 0; len -= 16) {
+				asm(
+					"ldmia	%0!, {r0, r1, r2, r3}\n\t"
+					"stmia	%1, {r0, r1, r2, r3}"
+					: "+r" (ptr)
+					: "r" (aacirun->fifo)
+					: "r0", "r1", "r2", "r3", "cc");
+
+				if (ptr >= aacirun->end)
+					ptr = aacirun->start;
+			}
+		} while (1);
+
+		aacirun->ptr = ptr;
+	}
+}
+
+static irqreturn_t aaci_irq(int irq, void *devid, struct pt_regs *regs)
+{
+	struct aaci *aaci = devid;
+	u32 mask;
+	int i;
+
+	spin_lock(&aaci->lock);
+	mask = readl(aaci->base + AACI_ALLINTS);
+	if (mask) {
+		u32 m = mask;
+		for (i = 0; i < 4; i++, m >>= 7) {
+			if (m & 0x7f) {
+				aaci_fifo_irq(aaci, m);
+			}
+		}
+	}
+	spin_unlock(&aaci->lock);
+
+	return mask ? IRQ_HANDLED : IRQ_NONE;
+}
+
+
+
+/*
+ * ALSA support.
+ */
+
+struct aaci_stream {
+	unsigned char codec_idx;
+	unsigned char rate_idx;
+};
+
+static struct aaci_stream aaci_streams[] = {
+	[ACSTREAM_FRONT] = {
+		.codec_idx	= 0,
+		.rate_idx	= AC97_RATES_FRONT_DAC,
+	},
+	[ACSTREAM_SURROUND] = {
+		.codec_idx	= 0,
+		.rate_idx	= AC97_RATES_SURR_DAC,
+	},
+	[ACSTREAM_LFE] = {
+		.codec_idx	= 0,
+		.rate_idx	= AC97_RATES_LFE_DAC,
+	},
+};
+
+static inline unsigned int aaci_rate_mask(struct aaci *aaci, int streamid)
+{
+	struct aaci_stream *s = aaci_streams + streamid;
+	return aaci->ac97_bus->codec[s->codec_idx]->rates[s->rate_idx];
+}
+
+static unsigned int rate_list[] = {
+	5512, 8000, 11025, 16000, 22050, 32000, 44100,
+	48000, 64000, 88200, 96000, 176400, 192000
+};
+
+/*
+ * Double-rate rule: we can support double rate iff channels == 2
+ *  (unimplemented)
+ */
+static int
+aaci_rule_rate_by_channels(snd_pcm_hw_params_t *p, snd_pcm_hw_rule_t *rule)
+{
+	struct aaci *aaci = rule->private;
+	unsigned int rate_mask = SNDRV_PCM_RATE_8000_48000|SNDRV_PCM_RATE_5512;
+	snd_interval_t *c = hw_param_interval(p, SNDRV_PCM_HW_PARAM_CHANNELS);
+
+	switch (c->max) {
+	case 6:
+		rate_mask &= aaci_rate_mask(aaci, ACSTREAM_LFE);
+	case 4:
+		rate_mask &= aaci_rate_mask(aaci, ACSTREAM_SURROUND);
+	case 2:
+		rate_mask &= aaci_rate_mask(aaci, ACSTREAM_FRONT);
+	}
+
+	return snd_interval_list(hw_param_interval(p, rule->var),
+				 ARRAY_SIZE(rate_list), rate_list,
+				 rate_mask);
+}
+
+static snd_pcm_hardware_t aaci_hw_info = {
+	.info			= SNDRV_PCM_INFO_MMAP |
+				  SNDRV_PCM_INFO_MMAP_VALID |
+				  SNDRV_PCM_INFO_INTERLEAVED |
+				  SNDRV_PCM_INFO_BLOCK_TRANSFER |
+				  SNDRV_PCM_INFO_RESUME,
+
+	/*
+	 * ALSA doesn't support 18-bit or 20-bit packed into 32-bit
+	 * words.  It also doesn't support 12-bit at all.
+	 */
+	.formats		= SNDRV_PCM_FMTBIT_S16_LE,
+
+	/* should this be continuous or knot? */
+	.rates			= SNDRV_PCM_RATE_CONTINUOUS,
+	.rate_max		= 48000,
+	.rate_min		= 4000,
+	.channels_min		= 2,
+	.channels_max		= 6,
+	.buffer_bytes_max	= 64 * 1024,
+	.period_bytes_min	= 256,
+	.period_bytes_max	= PAGE_SIZE,
+	.periods_min		= 4,
+	.periods_max		= PAGE_SIZE / 16,
+};
+
+static int aaci_pcm_open(struct aaci *aaci, snd_pcm_substream_t *substream,
+			 struct aaci_runtime *aacirun)
+{
+	snd_pcm_runtime_t *runtime = substream->runtime;
+	int ret;
+
+	aacirun->substream = substream;
+	runtime->private_data = aacirun;
+	runtime->hw = aaci_hw_info;
+
+	/*
+	 * FIXME: ALSA specifies fifo_size in bytes.  If we're in normal
+	 * mode, each 32-bit word contains one sample.  If we're in
+	 * compact mode, each 32-bit word contains two samples, effectively
+	 * halving the FIFO size.  However, we don't know for sure which
+	 * we'll be using at this point.  We set this to the lower limit.
+	 */
+	runtime->hw.fifo_size = aaci->fifosize * 2;
+
+	/*
+	 * Add rule describing hardware rate dependency
+	 * on the number of channels.
+	 */
+	ret = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
+				  aaci_rule_rate_by_channels, aaci,
+				  SNDRV_PCM_HW_PARAM_CHANNELS,
+				  SNDRV_PCM_HW_PARAM_RATE, -1);
+	if (ret)
+		goto out;
+
+	ret = request_irq(aaci->dev->irq[0], aaci_irq, SA_SHIRQ|SA_INTERRUPT,
+			  DRIVER_NAME, aaci);
+	if (ret)
+		goto out;
+
+	return 0;
+
+ out:
+	return ret;
+}
+
+
+/*
+ * Common ALSA stuff
+ */
+static int aaci_pcm_close(snd_pcm_substream_t *substream)
+{
+	struct aaci *aaci = substream->private_data;
+	struct aaci_runtime *aacirun = substream->runtime->private_data;
+
+	WARN_ON(aacirun->cr & TXCR_TXEN);
+
+	aacirun->substream = NULL;
+	free_irq(aaci->dev->irq[0], aaci);
+
+	return 0;
+}
+
+static int aaci_pcm_hw_free(snd_pcm_substream_t *substream)
+{
+	struct aaci_runtime *aacirun = substream->runtime->private_data;
+
+	/*
+	 * This must not be called with the device enabled.
+	 */
+	WARN_ON(aacirun->cr & TXCR_TXEN);
+
+	if (aacirun->pcm_open)
+		snd_ac97_pcm_close(aacirun->pcm);
+	aacirun->pcm_open = 0;
+
+	/*
+	 * Clear out the DMA and any allocated buffers.
+	 */
+	devdma_hw_free(NULL, substream);
+
+	return 0;
+}
+
+static int aaci_pcm_hw_params(snd_pcm_substream_t *substream,
+			      struct aaci_runtime *aacirun,
+			      snd_pcm_hw_params_t *params)
+{
+	int err;
+
+	aaci_pcm_hw_free(substream);
+
+	err = devdma_hw_alloc(NULL, substream,
+			      params_buffer_bytes(params));
+	if (err < 0)
+		goto out;
+
+	err = snd_ac97_pcm_open(aacirun->pcm, params_rate(params),
+				params_channels(params),
+				aacirun->pcm->r[0].slots);
+	if (err)
+		goto out;
+
+	aacirun->pcm_open = 1;
+
+ out:
+	return err;
+}
+
+static int aaci_pcm_prepare(snd_pcm_substream_t *substream)
+{
+	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct aaci_runtime *aacirun = runtime->private_data;
+
+	aacirun->start	= (void *)runtime->dma_area;
+	aacirun->end	= aacirun->start + runtime->dma_bytes;
+	aacirun->ptr	= aacirun->start;
+	aacirun->period	=
+	aacirun->bytes	= frames_to_bytes(runtime, runtime->period_size);
+
+	return 0;
+}
+
+static snd_pcm_uframes_t aaci_pcm_pointer(snd_pcm_substream_t *substream)
+{
+	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct aaci_runtime *aacirun = runtime->private_data;
+	ssize_t bytes = aacirun->ptr - aacirun->start;
+
+	return bytes_to_frames(runtime, bytes);
+}
+
+static int aaci_pcm_mmap(snd_pcm_substream_t *substream, struct vm_area_struct *vma)
+{
+	return devdma_mmap(NULL, substream, vma);
+}
+
+
+/*
+ * Playback specific ALSA stuff
+ */
+static const u32 channels_to_txmask[] = {
+	[2] = TXCR_TX3 | TXCR_TX4,
+	[4] = TXCR_TX3 | TXCR_TX4 | TXCR_TX7 | TXCR_TX8,
+	[6] = TXCR_TX3 | TXCR_TX4 | TXCR_TX7 | TXCR_TX8 | TXCR_TX6 | TXCR_TX9,
+};
+
+/*
+ * We can support two and four channel audio.  Unfortunately
+ * six channel audio requires a non-standard channel ordering:
+ *   2 -> FL(3), FR(4)
+ *   4 -> FL(3), FR(4), SL(7), SR(8)
+ *   6 -> FL(3), FR(4), SL(7), SR(8), C(6), LFE(9) (required)
+ *        FL(3), FR(4), C(6), SL(7), SR(8), LFE(9) (actual)
+ * This requires an ALSA configuration file to correct.
+ */
+static unsigned int channel_list[] = { 2, 4, 6 };
+
+static int
+aaci_rule_channels(snd_pcm_hw_params_t *p, snd_pcm_hw_rule_t *rule)
+{
+	struct aaci *aaci = rule->private;
+	unsigned int chan_mask = 1 << 0, slots;
+
+	/*
+	 * pcms[0] is the our 5.1 PCM instance.
+	 */
+	slots = aaci->ac97_bus->pcms[0].r[0].slots;
+	if (slots & (1 << AC97_SLOT_PCM_SLEFT)) {
+		chan_mask |= 1 << 1;
+		if (slots & (1 << AC97_SLOT_LFE))
+			chan_mask |= 1 << 2;
+	}
+
+	return snd_interval_list(hw_param_interval(p, rule->var),
+				 ARRAY_SIZE(channel_list), channel_list,
+				 chan_mask);
+}
+
+static int aaci_pcm_playback_open(snd_pcm_substream_t *substream)
+{
+	struct aaci *aaci = substream->private_data;
+	int ret;
+
+	/*
+	 * Add rule describing channel dependency.
+	 */
+	ret = snd_pcm_hw_rule_add(substream->runtime, 0,
+				  SNDRV_PCM_HW_PARAM_CHANNELS,
+				  aaci_rule_channels, aaci,
+				  SNDRV_PCM_HW_PARAM_CHANNELS, -1);
+	if (ret)
+		return ret;
+
+	return aaci_pcm_open(aaci, substream, &aaci->playback);
+}
+
+static int aaci_pcm_playback_hw_params(snd_pcm_substream_t *substream,
+				       snd_pcm_hw_params_t *params)
+{
+	struct aaci *aaci = substream->private_data;
+	struct aaci_runtime *aacirun = substream->runtime->private_data;
+	unsigned int channels = params_channels(params);
+	int ret;
+
+	WARN_ON(channels >= ARRAY_SIZE(channels_to_txmask) ||
+		!channels_to_txmask[channels]);
+
+	ret = aaci_pcm_hw_params(substream, aacirun, params);
+
+	/*
+	 * Enable FIFO, compact mode, 16 bits per sample.
+	 * FIXME: double rate slots?
+	 */
+	if (ret >= 0) {
+		aacirun->cr = TXCR_FEN | TXCR_COMPACT | TXCR_TSZ16;
+		aacirun->cr |= channels_to_txmask[channels];
+
+		aacirun->fifosz	= aaci->fifosize * 4;
+		if (aacirun->cr & TXCR_COMPACT)
+			aacirun->fifosz >>= 1;
+	}
+	return ret;
+}
+
+static void aaci_pcm_playback_stop(struct aaci_runtime *aacirun)
+{
+	u32 ie;
+
+	ie = readl(aacirun->base + AACI_IE);
+	ie &= ~(IE_URIE|IE_TXIE);
+	writel(ie, aacirun->base + AACI_IE);
+	aacirun->cr &= ~TXCR_TXEN;
+	aaci_chan_wait_ready(aacirun);
+	writel(aacirun->cr, aacirun->base + AACI_TXCR);
+}
+
+static void aaci_pcm_playback_start(struct aaci_runtime *aacirun)
+{
+	u32 ie;
+
+	aaci_chan_wait_ready(aacirun);
+	aacirun->cr |= TXCR_TXEN;
+
+	ie = readl(aacirun->base + AACI_IE);
+	ie |= IE_URIE | IE_TXIE;
+	writel(ie, aacirun->base + AACI_IE);
+	writel(aacirun->cr, aacirun->base + AACI_TXCR);
+}
+
+static int aaci_pcm_playback_trigger(snd_pcm_substream_t *substream, int cmd)
+{
+	struct aaci *aaci = substream->private_data;
+	struct aaci_runtime *aacirun = substream->runtime->private_data;
+	unsigned long flags;
+	int ret = 0;
+
+	spin_lock_irqsave(&aaci->lock, flags);
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+		aaci_pcm_playback_start(aacirun);
+		break;
+
+	case SNDRV_PCM_TRIGGER_RESUME:
+		aaci_pcm_playback_start(aacirun);
+		break;
+
+	case SNDRV_PCM_TRIGGER_STOP:
+		aaci_pcm_playback_stop(aacirun);
+		break;
+
+	case SNDRV_PCM_TRIGGER_SUSPEND:
+		aaci_pcm_playback_stop(aacirun);
+		break;
+
+	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+		break;
+
+	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+		break;
+
+	default:
+		ret = -EINVAL;
+	}
+	spin_unlock_irqrestore(&aaci->lock, flags);
+
+	return ret;
+}
+
+static snd_pcm_ops_t aaci_playback_ops = {
+	.open		= aaci_pcm_playback_open,
+	.close		= aaci_pcm_close,
+	.ioctl		= snd_pcm_lib_ioctl,
+	.hw_params	= aaci_pcm_playback_hw_params,
+	.hw_free	= aaci_pcm_hw_free,
+	.prepare	= aaci_pcm_prepare,
+	.trigger	= aaci_pcm_playback_trigger,
+	.pointer	= aaci_pcm_pointer,
+	.mmap		= aaci_pcm_mmap,
+};
+
+
+
+/*
+ * Power Management.
+ */
+#ifdef CONFIG_PM
+static int aaci_do_suspend(snd_card_t *card, unsigned int state)
+{
+	struct aaci *aaci = card->private_data;
+	if (aaci->card->power_state != SNDRV_CTL_POWER_D3cold) {
+		snd_pcm_suspend_all(aaci->pcm);
+		snd_power_change_state(aaci->card, SNDRV_CTL_POWER_D3cold);
+	}
+	return 0;
+}
+
+static int aaci_do_resume(snd_card_t *card, unsigned int state)
+{
+	struct aaci *aaci = card->private_data;
+	if (aaci->card->power_state != SNDRV_CTL_POWER_D0) {
+		snd_power_change_state(aaci->card, SNDRV_CTL_POWER_D0);
+	}
+	return 0;
+}
+
+static int aaci_suspend(struct amba_device *dev, u32 state)
+{
+	snd_card_t *card = amba_get_drvdata(dev);
+	return card ? aaci_do_suspend(card) : 0;
+}
+
+static int aaci_resume(struct amba_device *dev)
+{
+	snd_card_t *card = amba_get_drvdata(dev);
+	return card ? aaci_do_resume(card) : 0;
+}
+#else
+#define aaci_do_suspend		NULL
+#define aaci_do_resume		NULL
+#define aaci_suspend		NULL
+#define aaci_resume		NULL
+#endif
+
+
+static struct ac97_pcm ac97_defs[] __devinitdata = {
+	[0] = {		/* Front PCM */
+		.exclusive = 1,
+		.r = {
+			[0] = {
+				.slots	= (1 << AC97_SLOT_PCM_LEFT) |
+					  (1 << AC97_SLOT_PCM_RIGHT) |
+					  (1 << AC97_SLOT_PCM_CENTER) |
+					  (1 << AC97_SLOT_PCM_SLEFT) |
+					  (1 << AC97_SLOT_PCM_SRIGHT) |
+					  (1 << AC97_SLOT_LFE),
+			},
+		},
+	},
+	[1] = {	/* PCM in */
+		.stream = 1,
+		.exclusive = 1,
+		.r = {
+			[0] = {
+				.slots	= (1 << AC97_SLOT_PCM_LEFT) |
+					  (1 << AC97_SLOT_PCM_RIGHT),
+			},
+		},
+	},
+	[2] = {	/* Mic in */
+		.stream = 1,
+		.exclusive = 1,
+		.r = {
+			[0] = {
+				.slots	= (1 << AC97_SLOT_MIC),
+			},
+		},
+	}
+};
+
+static ac97_bus_ops_t aaci_bus_ops = {
+	.write	= aaci_ac97_write,
+	.read	= aaci_ac97_read,
+};
+
+static int __devinit aaci_probe_ac97(struct aaci *aaci)
+{
+	ac97_template_t ac97_template;
+	ac97_bus_t *ac97_bus;
+	ac97_t *ac97;
+	int ret;
+
+	/*
+	 * Assert AACIRESET for 2us
+	 */
+	writel(0, aaci->base + AACI_RESET);
+	udelay(2);
+	writel(RESET_NRST, aaci->base + AACI_RESET);
+
+	/*
+	 * Give the AC'97 codec more than enough time
+	 * to wake up. (42us = ~2 frames at 48kHz.)
+	 */
+	udelay(42);
+
+	ret = snd_ac97_bus(aaci->card, 0, &aaci_bus_ops, aaci, &ac97_bus);
+	if (ret)
+		goto out;
+
+	ac97_bus->clock = 48000;
+	aaci->ac97_bus = ac97_bus;
+
+	memset(&ac97_template, 0, sizeof(ac97_template_t));
+	ac97_template.private_data = aaci;
+	ac97_template.num = 0;
+	ac97_template.scaps = AC97_SCAP_SKIP_MODEM;
+
+	ret = snd_ac97_mixer(ac97_bus, &ac97_template, &ac97);
+	if (ret)
+		goto out;
+
+	/*
+	 * Disable AC97 PC Beep input on audio codecs.
+	 */
+	if (ac97_is_audio(ac97))
+		snd_ac97_write_cache(ac97, AC97_PC_BEEP, 0x801e);
+
+	ret = snd_ac97_pcm_assign(ac97_bus, ARRAY_SIZE(ac97_defs), ac97_defs);
+	if (ret)
+		goto out;
+
+	aaci->playback.pcm = &ac97_bus->pcms[0];
+
+ out:
+	return ret;
+}
+
+static void aaci_free_card(snd_card_t *card)
+{
+	struct aaci *aaci = card->private_data;
+	if (aaci->base)
+		iounmap(aaci->base);
+}
+
+static struct aaci * __devinit aaci_init_card(struct amba_device *dev)
+{
+	struct aaci *aaci;
+	snd_card_t *card;
+
+	card = snd_card_new(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
+			    THIS_MODULE, sizeof(struct aaci));
+	if (card == NULL)
+		return ERR_PTR(-ENOMEM);
+
+	card->private_free = aaci_free_card;
+	snd_card_set_pm_callback(card, aaci_do_suspend, aaci_do_resume, NULL);
+
+	strlcpy(card->driver, DRIVER_NAME, sizeof(card->driver));
+	strlcpy(card->shortname, "ARM AC'97 Interface", sizeof(card->shortname));
+	snprintf(card->longname, sizeof(card->longname),
+		 "%s at 0x%08lx, irq %d",
+		 card->shortname, dev->res.start, dev->irq[0]);
+
+	aaci = card->private_data;
+	init_MUTEX(&aaci->ac97_sem);
+	spin_lock_init(&aaci->lock);
+	aaci->card = card;
+	aaci->dev = dev;
+
+	/* Set MAINCR to allow slot 1 and 2 data IO */
+	aaci->maincr = MAINCR_IE | MAINCR_SL1RXEN | MAINCR_SL1TXEN |
+		       MAINCR_SL2RXEN | MAINCR_SL2TXEN;
+
+	return aaci;
+}
+
+static int __devinit aaci_init_pcm(struct aaci *aaci)
+{
+	snd_pcm_t *pcm;
+	int ret;
+
+	ret = snd_pcm_new(aaci->card, "AACI AC'97", 0, 1, 0, &pcm);
+	if (ret == 0) {
+		aaci->pcm = pcm;
+		pcm->private_data = aaci;
+		pcm->info_flags = 0;
+
+		strlcpy(pcm->name, DRIVER_NAME, sizeof(pcm->name));
+
+		snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &aaci_playback_ops);
+	}
+
+	return ret;
+}
+
+static unsigned int __devinit aaci_size_fifo(struct aaci *aaci)
+{
+	void *base = aaci->base + AACI_CSCH1;
+	int i;
+
+	writel(TXCR_FEN | TXCR_TSZ16 | TXCR_TXEN, base + AACI_TXCR);
+
+	for (i = 0; !(readl(base + AACI_SR) & SR_TXFF) && i < 4096; i++)
+		writel(0, aaci->base + AACI_DR1);
+
+	writel(0, base + AACI_TXCR);
+
+	/*
+	 * Re-initialise the AACI after the FIFO depth test, to
+	 * ensure that the FIFOs are empty.  Unfortunately, merely
+	 * disabling the channel doesn't clear the FIFO.
+	 */
+	writel(aaci->maincr & ~MAINCR_IE, aaci->base + AACI_MAINCR);
+	writel(aaci->maincr, aaci->base + AACI_MAINCR);
+
+	/*
+	 * If we hit 4096, we failed.  Go back to the specified
+	 * fifo depth.
+	 */
+	if (i == 4096)
+		i = 8;
+
+	return i;
+}
+
+static int __devinit aaci_probe(struct amba_device *dev, void *id)
+{
+	struct aaci *aaci;
+	int ret, i;
+
+	ret = amba_request_regions(dev, NULL);
+	if (ret)
+		return ret;
+
+	aaci = aaci_init_card(dev);
+	if (IS_ERR(aaci)) {
+		ret = PTR_ERR(aaci);
+		goto out;
+	}
+
+	aaci->base = ioremap(dev->res.start, SZ_4K);
+	if (!aaci->base) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	/*
+	 * Playback uses AACI channel 0
+	 */
+	aaci->playback.base = aaci->base + AACI_CSCH1;
+	aaci->playback.fifo = aaci->base + AACI_DR1;
+
+	for (i = 0; i < 4; i++) {
+		void *base = aaci->base + i * 0x14;
+
+		writel(0, base + AACI_IE);
+		writel(0, base + AACI_TXCR);
+		writel(0, base + AACI_RXCR);
+	}
+
+	writel(0x1fff, aaci->base + AACI_INTCLR);
+	writel(aaci->maincr, aaci->base + AACI_MAINCR);
+
+	/*
+	 * Size the FIFOs.
+	 */
+	aaci->fifosize = aaci_size_fifo(aaci);
+
+	ret = aaci_probe_ac97(aaci);
+	if (ret)
+		goto out;
+
+	ret = aaci_init_pcm(aaci);
+	if (ret)
+		goto out;
+
+	ret = snd_card_register(aaci->card);
+	if (ret == 0) {
+		dev_info(&dev->dev, "%s, fifo %d\n", aaci->card->longname,
+			aaci->fifosize);
+		amba_set_drvdata(dev, aaci->card);
+		return ret;
+	}
+
+ out:
+	if (aaci)
+		snd_card_free(aaci->card);
+	amba_release_regions(dev);
+	return ret;
+}
+
+static int __devexit aaci_remove(struct amba_device *dev)
+{
+	snd_card_t *card = amba_get_drvdata(dev);
+
+	amba_set_drvdata(dev, NULL);
+
+	if (card) {
+		struct aaci *aaci = card->private_data;
+		writel(0, aaci->base + AACI_MAINCR);
+
+		snd_card_free(card);
+		amba_release_regions(dev);
+	}
+
+	return 0;
+}
+
+static struct amba_id aaci_ids[] = {
+	{
+		.id	= 0x00041041,
+		.mask	= 0x000fffff,
+	},
+	{ 0, 0 },
+};
+
+static struct amba_driver aaci_driver = {
+	.drv		= {
+		.name	= DRIVER_NAME,
+	},
+	.probe		= aaci_probe,
+	.remove		= __devexit_p(aaci_remove),
+	.suspend	= aaci_suspend,
+	.resume		= aaci_resume,
+	.id_table	= aaci_ids,
+};
+
+static int __init aaci_init(void)
+{
+	return amba_driver_register(&aaci_driver);
+}
+
+static void __exit aaci_exit(void)
+{
+	amba_driver_unregister(&aaci_driver);
+}
+
+module_init(aaci_init);
+module_exit(aaci_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("ARM PrimeCell PL041 Advanced Audio CODEC Interface driver");
diff --git a/sound/arm/aaci.h b/sound/arm/aaci.h
new file mode 100644
--- /dev/null
+++ b/sound/arm/aaci.h
@@ -0,0 +1,246 @@
+/*
+ *  linux/sound/arm/aaci.c - ARM PrimeCell AACI PL041 driver
+ *
+ *  Copyright (C) 2003 Deep Blue Solutions, Ltd, 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 version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef AACI_H
+#define AACI_H
+
+/*
+ * Control and status register offsets
+ *  P39.
+ */
+#define AACI_CSCH1	0x000
+#define AACI_CSCH2	0x014
+#define AACI_CSCH3	0x028
+#define AACI_CSCH4	0x03c
+
+#define AACI_RXCR	0x000	/* 29 bits Control Rx FIFO */
+#define AACI_TXCR	0x004	/* 17 bits Control Tx FIFO */
+#define AACI_SR		0x008	/* 12 bits Status */
+#define AACI_ISR	0x00c	/* 7 bits  Int Status */
+#define AACI_IE 	0x010	/* 7 bits  Int Enable */
+
+/*
+ * Other registers
+ */
+#define AACI_SL1RX	0x050
+#define AACI_SL1TX	0x054
+#define AACI_SL2RX	0x058
+#define AACI_SL2TX	0x05c
+#define AACI_SL12RX	0x060
+#define AACI_SL12TX	0x064
+#define AACI_SLFR	0x068	/* slot flags */
+#define AACI_SLISTAT	0x06c	/* slot interrupt status */
+#define AACI_SLIEN	0x070	/* slot interrupt enable */
+#define AACI_INTCLR	0x074	/* interrupt clear */
+#define AACI_MAINCR	0x078	/* main control */
+#define AACI_RESET	0x07c	/* reset control */
+#define AACI_SYNC	0x080	/* sync control */
+#define AACI_ALLINTS	0x084	/* all fifo interrupt status */
+#define AACI_MAINFR	0x088	/* main flag register */
+#define AACI_DR1	0x090	/* data read/written fifo 1 */
+#define AACI_DR2	0x0b0	/* data read/written fifo 2 */
+#define AACI_DR3	0x0d0	/* data read/written fifo 3 */
+#define AACI_DR4	0x0f0	/* data read/written fifo 4 */
+
+/*
+ * transmit fifo control register. P48
+ */
+#define TXCR_FEN	(1 << 16)	/* fifo enable */
+#define TXCR_COMPACT	(1 << 15)	/* compact mode */
+#define TXCR_TSZ16	(0 << 13)	/* 16 bits */
+#define TXCR_TSZ18	(1 << 13)	/* 18 bits */
+#define TXCR_TSZ20	(2 << 13)	/* 20 bits */
+#define TXCR_TSZ12	(3 << 13)	/* 12 bits */
+#define TXCR_TX12	(1 << 12)	/* transmits slot 12 */
+#define TXCR_TX11	(1 << 11)	/* transmits slot 12 */
+#define TXCR_TX10	(1 << 10)	/* transmits slot 12 */
+#define TXCR_TX9	(1 << 9)	/* transmits slot 12 */
+#define TXCR_TX8	(1 << 8)	/* transmits slot 12 */
+#define TXCR_TX7	(1 << 7)	/* transmits slot 12 */
+#define TXCR_TX6	(1 << 6)	/* transmits slot 12 */
+#define TXCR_TX5	(1 << 5)	/* transmits slot 12 */
+#define TXCR_TX4	(1 << 4)	/* transmits slot 12 */
+#define TXCR_TX3	(1 << 3)	/* transmits slot 12 */
+#define TXCR_TX2	(1 << 2)	/* transmits slot 12 */
+#define TXCR_TX1	(1 << 1)	/* transmits slot 12 */
+#define TXCR_TXEN	(1 << 0)	/* transmit enable */
+
+/*
+ * status register bits. P49
+ */
+#define SR_RXTOFE	(1 << 11)	/* rx timeout fifo empty */
+#define SR_TXTO		(1 << 10)	/* rx timeout fifo nonempty */
+#define SR_TXU		(1 << 9)	/* tx underrun */
+#define SR_RXO		(1 << 8)	/* rx overrun */
+#define SR_TXB		(1 << 7)	/* tx busy */
+#define SR_RXB		(1 << 6)	/* rx busy */
+#define SR_TXFF		(1 << 5)	/* tx fifo full */
+#define SR_RXFF		(1 << 4)	/* rx fifo full */
+#define SR_TXHE		(1 << 3)	/* tx fifo half empty */
+#define SR_RXHF		(1 << 2)	/* rx fifo half full */
+#define SR_TXFE		(1 << 1)	/* tx fifo empty */
+#define SR_RXFE		(1 << 0)	/* rx fifo empty */
+
+/*
+ * interrupt status register bits.
+ */
+#define ISR_RXTOFEINTR	(1 << 6)	/* rx fifo empty */
+#define ISR_URINTR	(1 << 5)	/* tx underflow */
+#define ISR_ORINTR	(1 << 4)	/* rx overflow */
+#define ISR_RXINTR	(1 << 3)	/* rx fifo */
+#define ISR_TXINTR	(1 << 2)	/* tx fifo intr */
+#define ISR_RXTOINTR	(1 << 1)	/* tx timeout */
+#define ISR_TXCINTR	(1 << 0)	/* tx complete */
+
+/*
+ * interrupt enable register bits.
+ */
+#define IE_RXTOIE	(1 << 6)
+#define IE_URIE		(1 << 5)
+#define IE_ORIE		(1 << 4)
+#define IE_RXIE		(1 << 3)
+#define IE_TXIE		(1 << 2)
+#define IE_RXTIE	(1 << 1)
+#define IE_TXCIE	(1 << 0)
+
+/*
+ * interrupt status. P51
+ */
+#define ISR_RXTOFE	(1 << 6)	/* rx timeout fifo empty */
+#define ISR_UR		(1 << 5)	/* tx fifo underrun */
+#define ISR_OR		(1 << 4)	/* rx fifo overrun */
+#define ISR_RX		(1 << 3)	/* rx interrupt status */
+#define ISR_TX		(1 << 2)	/* tx interrupt status */
+#define ISR_RXTO	(1 << 1)	/* rx timeout */
+#define ISR_TXC		(1 << 0)	/* tx complete */
+
+/*
+ * interrupt enable. P52
+ */
+#define IE_RXTOFE	(1 << 6)	/* rx timeout fifo empty */
+#define IE_UR		(1 << 5)	/* tx fifo underrun */
+#define IE_OR		(1 << 4)	/* rx fifo overrun */
+#define IE_RX		(1 << 3)	/* rx interrupt status */
+#define IE_TX		(1 << 2)	/* tx interrupt status */
+#define IE_RXTO		(1 << 1)	/* rx timeout */
+#define IE_TXC		(1 << 0)	/* tx complete */
+
+/*
+ * slot flag register bits. P56
+ */
+#define SLFR_RWIS	(1 << 13)	/* raw wake-up interrupt status */
+#define SLFR_RGPIOINTR	(1 << 12)	/* raw gpio interrupt */
+#define SLFR_12TXE	(1 << 11)	/* slot 12 tx empty */
+#define SLFR_12RXV	(1 << 10)	/* slot 12 rx valid */
+#define SLFR_2TXE	(1 << 9)	/* slot 2 tx empty */
+#define SLFR_2RXV	(1 << 8)	/* slot 2 rx valid */
+#define SLFR_1TXE	(1 << 7)	/* slot 1 tx empty */
+#define SLFR_1RXV	(1 << 6)	/* slot 1 rx valid */
+#define SLFR_12TXB	(1 << 5)	/* slot 12 tx busy */
+#define SLFR_12RXB	(1 << 4)	/* slot 12 rx busy */
+#define SLFR_2TXB	(1 << 3)	/* slot 2 tx busy */
+#define SLFR_2RXB	(1 << 2)	/* slot 2 rx busy */
+#define SLFR_1TXB	(1 << 1)	/* slot 1 tx busy */
+#define SLFR_1RXB	(1 << 0)	/* slot 1 rx busy */
+
+/*
+ * Interrupt clear register.
+ */
+#define ICLR_RXTOFEC4	(1 << 12)
+#define ICLR_RXTOFEC3	(1 << 11)
+#define ICLR_RXTOFEC2	(1 << 10)
+#define ICLR_RXTOFEC1	(1 << 9)
+#define ICLR_TXUEC4	(1 << 8)
+#define ICLR_TXUEC3	(1 << 7)
+#define ICLR_TXUEC2	(1 << 6)
+#define ICLR_TXUEC1	(1 << 5)
+#define ICLR_RXOEC4	(1 << 4)
+#define ICLR_RXOEC3	(1 << 3)
+#define ICLR_RXOEC2	(1 << 2)
+#define ICLR_RXOEC1	(1 << 1)
+#define ICLR_WISC	(1 << 0)
+
+/*
+ * Main control register bits. P62
+ */
+#define MAINCR_SCRA(x)	((x) << 10)	/* secondary codec reg access */
+#define MAINCR_DMAEN	(1 << 9)	/* dma enable */
+#define MAINCR_SL12TXEN	(1 << 8)	/* slot 12 transmit enable */
+#define MAINCR_SL12RXEN	(1 << 7)	/* slot 12 receive enable */
+#define MAINCR_SL2TXEN	(1 << 6)	/* slot 2 transmit enable */
+#define MAINCR_SL2RXEN	(1 << 5)	/* slot 2 receive enable */
+#define MAINCR_SL1TXEN	(1 << 4)	/* slot 1 transmit enable */
+#define MAINCR_SL1RXEN	(1 << 3)	/* slot 1 receive enable */
+#define MAINCR_LPM	(1 << 2)	/* low power mode */
+#define MAINCR_LOOPBK	(1 << 1)	/* loopback */
+#define MAINCR_IE	(1 << 0)	/* aaci interface enable */
+
+/*
+ * Reset register bits. P65
+ */
+#define RESET_NRST	(1 << 0)
+
+/*
+ * Sync register bits. P65
+ */
+#define SYNC_FORCE	(1 << 0)
+
+/*
+ * Main flag register bits. P66
+ */
+#define MAINFR_TXB	(1 << 1)	/* transmit busy */
+#define MAINFR_RXB	(1 << 0)	/* receive busy */
+
+
+
+struct aaci_runtime {
+	void			*base;
+	void			*fifo;
+
+	struct ac97_pcm		*pcm;
+	int			pcm_open;
+
+	u32			cr;
+	snd_pcm_substream_t	*substream;
+
+	/*
+	 * PIO support
+	 */
+	void			*start;
+	void			*end;
+	void			*ptr;
+	int			bytes;
+	unsigned int		period;
+	unsigned int		fifosz;
+};
+
+struct aaci {
+	struct amba_device	*dev;
+	snd_card_t		*card;
+	void			*base;
+	unsigned int		fifosize;
+
+	/* AC'97 */
+	struct semaphore	ac97_sem;
+	ac97_bus_t		*ac97_bus;
+
+	u32			maincr;
+	spinlock_t		lock;
+
+	struct aaci_runtime	playback;
+	struct aaci_runtime	capture;
+
+	snd_pcm_t		*pcm;
+};
+
+#define ACSTREAM_FRONT		0
+#define ACSTREAM_SURROUND	1
+#define ACSTREAM_LFE		2
+
+#endif
diff --git a/sound/arm/devdma.c b/sound/arm/devdma.c
new file mode 100644
--- /dev/null
+++ b/sound/arm/devdma.c
@@ -0,0 +1,81 @@
+/*
+ *  linux/sound/arm/devdma.c
+ *
+ *  Copyright (C) 2003-2004 Russell King, 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 version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  ARM DMA shim for ALSA.
+ */
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+
+#include <sound/driver.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+
+#include "devdma.h"
+
+void devdma_hw_free(struct device *dev, snd_pcm_substream_t *substream)
+{
+	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_dma_buffer *buf = runtime->dma_buffer_p;
+
+	if (runtime->dma_area == NULL)
+		return;
+
+	if (buf != &substream->dma_buffer) {
+		dma_free_coherent(buf->dev.dev, buf->bytes, buf->area, buf->addr);
+		kfree(runtime->dma_buffer_p);
+	}
+
+	snd_pcm_set_runtime_buffer(substream, NULL);
+}
+
+int devdma_hw_alloc(struct device *dev, snd_pcm_substream_t *substream, size_t size)
+{
+	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_dma_buffer *buf = runtime->dma_buffer_p;
+	int ret = 0;
+
+	if (buf) {
+		if (buf->bytes >= size)
+			goto out;
+		devdma_hw_free(dev, substream);
+	}
+
+	if (substream->dma_buffer.area != NULL && substream->dma_buffer.bytes >= size) {
+		buf = &substream->dma_buffer;
+	} else {
+		buf = kmalloc(sizeof(struct snd_dma_buffer), GFP_KERNEL);
+		if (!buf)
+			goto nomem;
+
+		buf->dev.type = SNDRV_DMA_TYPE_DEV;
+		buf->dev.dev = dev;
+		buf->area = dma_alloc_coherent(dev, size, &buf->addr, GFP_KERNEL);
+		buf->bytes = size;
+		buf->private_data = NULL;
+
+		if (!buf->area)
+			goto free;
+	}
+	snd_pcm_set_runtime_buffer(substream, buf);
+	ret = 1;
+ out:
+	runtime->dma_bytes = size;
+	return ret;
+
+ free:
+	kfree(buf);
+ nomem:
+	return -ENOMEM;
+}
+
+int devdma_mmap(struct device *dev, snd_pcm_substream_t *substream, struct vm_area_struct *vma)
+{
+	snd_pcm_runtime_t *runtime = substream->runtime;
+	return dma_mmap_coherent(dev, vma, runtime->dma_area, runtime->dma_addr, runtime->dma_bytes);
+}
diff --git a/sound/arm/devdma.h b/sound/arm/devdma.h
new file mode 100644
--- /dev/null
+++ b/sound/arm/devdma.h
@@ -0,0 +1,3 @@
+void devdma_hw_free(struct device *dev, snd_pcm_substream_t *substream);
+int devdma_hw_alloc(struct device *dev, snd_pcm_substream_t *substream, size_t size);
+int devdma_mmap(struct device *dev, snd_pcm_substream_t *substream, struct vm_area_struct *vma);
diff --git a/sound/arm/pxa2xx-ac97.c b/sound/arm/pxa2xx-ac97.c
new file mode 100644
--- /dev/null
+++ b/sound/arm/pxa2xx-ac97.c
@@ -0,0 +1,410 @@
+/*
+ * linux/sound/pxa2xx-ac97.c -- AC97 support for the Intel PXA2xx chip.
+ *
+ * Author:	Nicolas Pitre
+ * Created:	Dec 02, 2004
+ * Copyright:	MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/wait.h>
+#include <linux/delay.h>
+
+#include <sound/driver.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/ac97_codec.h>
+#include <sound/initval.h>
+
+#include <asm/irq.h>
+#include <asm/semaphore.h>
+#include <asm/hardware.h>
+#include <asm/arch/pxa-regs.h>
+#include <asm/arch/audio.h>
+
+#include "pxa2xx-pcm.h"
+
+
+static DECLARE_MUTEX(car_mutex);
+static DECLARE_WAIT_QUEUE_HEAD(gsr_wq);
+static volatile long gsr_bits;
+
+static unsigned short pxa2xx_ac97_read(ac97_t *ac97, unsigned short reg)
+{
+	unsigned short val = -1;
+	volatile u32 *reg_addr;
+
+	down(&car_mutex);
+	if (CAR & CAR_CAIP) {
+		printk(KERN_CRIT"%s: CAR_CAIP already set\n", __FUNCTION__);
+		goto out;
+	}
+
+	/* set up primary or secondary codec space */
+	reg_addr = (ac97->num & 1) ? &SAC_REG_BASE : &PAC_REG_BASE;
+	reg_addr += (reg >> 1);
+
+	/* start read access across the ac97 link */
+	gsr_bits = 0;
+	val = *reg_addr;
+	if (reg == AC97_GPIO_STATUS)
+		goto out;
+	wait_event_timeout(gsr_wq, gsr_bits & GSR_SDONE, 1);
+	if (!gsr_bits & GSR_SDONE) {
+		printk(KERN_ERR "%s: read error (ac97_reg=%d GSR=%#lx)\n",
+				__FUNCTION__, reg, gsr_bits);
+		val = -1;
+		goto out;
+	}
+
+	/* valid data now */
+	gsr_bits = 0;
+	val = *reg_addr;			
+	/* but we've just started another cycle... */
+	wait_event_timeout(gsr_wq, gsr_bits & GSR_SDONE, 1);
+
+out:	up(&car_mutex);
+	return val;
+}
+
+static void pxa2xx_ac97_write(ac97_t *ac97, unsigned short reg, unsigned short val)
+{
+	volatile u32 *reg_addr;
+
+	down(&car_mutex);
+
+	if (CAR & CAR_CAIP) {
+		printk(KERN_CRIT "%s: CAR_CAIP already set\n", __FUNCTION__);
+		goto out;
+	}
+
+	/* set up primary or secondary codec space */
+	reg_addr = (ac97->num & 1) ? &SAC_REG_BASE : &PAC_REG_BASE;
+	reg_addr += (reg >> 1);
+	gsr_bits = 0;
+	*reg_addr = val;
+	wait_event_timeout(gsr_wq, gsr_bits & GSR_CDONE, 1);
+	if (!gsr_bits & GSR_SDONE)
+		printk(KERN_ERR "%s: write error (ac97_reg=%d GSR=%#lx)\n",
+				__FUNCTION__, reg, gsr_bits);
+
+out:	up(&car_mutex);
+}
+
+static void pxa2xx_ac97_reset(ac97_t *ac97)
+{
+	/* First, try cold reset */
+	GCR &=  GCR_COLD_RST;  /* clear everything but nCRST */
+	GCR &= ~GCR_COLD_RST;  /* then assert nCRST */
+
+	gsr_bits = 0;
+#ifdef CONFIG_PXA27x
+	/* PXA27x Developers Manual section 13.5.2.2.1 */
+	pxa_set_cken(1 << 31, 1);
+	udelay(5);
+	pxa_set_cken(1 << 31, 0);
+	GCR = GCR_COLD_RST;
+	udelay(50);
+#else
+	GCR = GCR_COLD_RST;
+	GCR |= GCR_CDONE_IE|GCR_SDONE_IE;
+	wait_event_timeout(gsr_wq, gsr_bits & (GSR_PCR | GSR_SCR), 1);
+#endif
+
+	if (!((GSR | gsr_bits) & (GSR_PCR | GSR_SCR))) {
+		printk(KERN_INFO "%s: cold reset timeout (GSR=%#lx)\n",
+				 __FUNCTION__, gsr_bits);
+
+		/* let's try warm reset */
+		gsr_bits = 0;
+#ifdef CONFIG_PXA27x
+		/* warm reset broken on Bulverde,
+		   so manually keep AC97 reset high */
+		pxa_gpio_mode(113 | GPIO_OUT | GPIO_DFLT_HIGH); 
+		udelay(10);
+		GCR |= GCR_WARM_RST;
+		pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT);
+		udelay(50);
+#else
+		GCR |= GCR_WARM_RST|GCR_PRIRDY_IEN|GCR_SECRDY_IEN;;
+		wait_event_timeout(gsr_wq, gsr_bits & (GSR_PCR | GSR_SCR), 1);
+#endif			
+
+		if (!((GSR | gsr_bits) & (GSR_PCR | GSR_SCR)))
+			printk(KERN_INFO "%s: warm reset timeout (GSR=%#lx)\n",
+					 __FUNCTION__, gsr_bits);
+	}
+
+	GCR &= ~(GCR_PRIRDY_IEN|GCR_SECRDY_IEN);
+	GCR |= GCR_SDONE_IE|GCR_CDONE_IE;
+}
+
+static irqreturn_t pxa2xx_ac97_irq(int irq, void *dev_id, struct pt_regs *regs)
+{
+	long status;
+
+	status = GSR;
+	if (status) {
+		GSR = status;
+		gsr_bits |= status;
+		wake_up(&gsr_wq);
+
+#ifdef CONFIG_PXA27x
+		/* Although we don't use those we still need to clear them
+		   since they tend to spuriously trigger when MMC is used
+		   (hardware bug? go figure)... */
+		MISR = MISR_EOC;
+		PISR = PISR_EOC;
+		MCSR = MCSR_EOC;
+#endif
+
+		return IRQ_HANDLED;
+	}
+
+	return IRQ_NONE;
+}
+
+static ac97_bus_ops_t pxa2xx_ac97_ops = {
+	.read	= pxa2xx_ac97_read,
+	.write	= pxa2xx_ac97_write,
+	.reset	= pxa2xx_ac97_reset,
+};
+
+static pxa2xx_pcm_dma_params_t pxa2xx_ac97_pcm_out = {
+	.name			= "AC97 PCM out",
+	.dev_addr		= __PREG(PCDR),
+	.drcmr			= &DRCMRTXPCDR,
+	.dcmd			= DCMD_INCSRCADDR | DCMD_FLOWTRG |
+				  DCMD_BURST32 | DCMD_WIDTH4,
+};
+
+static pxa2xx_pcm_dma_params_t pxa2xx_ac97_pcm_in = {
+	.name			= "AC97 PCM in",
+	.dev_addr		= __PREG(PCDR),
+	.drcmr			= &DRCMRRXPCDR,
+	.dcmd			= DCMD_INCTRGADDR | DCMD_FLOWSRC |
+				  DCMD_BURST32 | DCMD_WIDTH4,
+};
+
+static snd_pcm_t *pxa2xx_ac97_pcm;
+static ac97_t *pxa2xx_ac97_ac97;
+
+static int pxa2xx_ac97_pcm_startup(snd_pcm_substream_t *substream)
+{
+	snd_pcm_runtime_t *runtime = substream->runtime;
+	pxa2xx_audio_ops_t *platform_ops;
+	int r;
+
+	runtime->hw.channels_min = 2;
+	runtime->hw.channels_max = 2;
+
+	r = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
+	    AC97_RATES_FRONT_DAC : AC97_RATES_ADC;
+	runtime->hw.rates = pxa2xx_ac97_ac97->rates[r];
+	snd_pcm_limit_hw_rates(runtime);
+
+       	platform_ops = substream->pcm->card->dev->platform_data;
+	if (platform_ops && platform_ops->startup)
+		return platform_ops->startup(substream, platform_ops->priv);
+	else
+		return 0;
+}
+
+static void pxa2xx_ac97_pcm_shutdown(snd_pcm_substream_t *substream)
+{
+	pxa2xx_audio_ops_t *platform_ops;
+
+       	platform_ops = substream->pcm->card->dev->platform_data;
+	if (platform_ops && platform_ops->shutdown)
+		platform_ops->shutdown(substream, platform_ops->priv);
+}
+
+static int pxa2xx_ac97_pcm_prepare(snd_pcm_substream_t *substream)
+{
+	snd_pcm_runtime_t *runtime = substream->runtime;
+	int reg = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
+		  AC97_PCM_FRONT_DAC_RATE : AC97_PCM_LR_ADC_RATE;
+	return snd_ac97_set_rate(pxa2xx_ac97_ac97, reg, runtime->rate);
+}
+
+static pxa2xx_pcm_client_t pxa2xx_ac97_pcm_client = {
+	.playback_params	= &pxa2xx_ac97_pcm_out,
+	.capture_params		= &pxa2xx_ac97_pcm_in,
+	.startup		= pxa2xx_ac97_pcm_startup,
+	.shutdown		= pxa2xx_ac97_pcm_shutdown,
+	.prepare		= pxa2xx_ac97_pcm_prepare,
+};
+
+#ifdef CONFIG_PM
+
+static int pxa2xx_ac97_do_suspend(snd_card_t *card, unsigned int state)
+{
+	if (card->power_state != SNDRV_CTL_POWER_D3cold) {
+		pxa2xx_audio_ops_t *platform_ops = card->dev->platform_data;
+		snd_pcm_suspend_all(pxa2xx_ac97_pcm);
+		snd_ac97_suspend(pxa2xx_ac97_ac97);
+		snd_power_change_state(card, SNDRV_CTL_POWER_D3cold);
+		if (platform_ops && platform_ops->suspend)
+			platform_ops->suspend(platform_ops->priv);
+		GCR |= GCR_ACLINK_OFF;
+		pxa_set_cken(CKEN2_AC97, 0);
+	}
+
+	return 0;
+}
+
+static int pxa2xx_ac97_do_resume(snd_card_t *card, unsigned int state)
+{
+	if (card->power_state != SNDRV_CTL_POWER_D0) {
+		pxa2xx_audio_ops_t *platform_ops = card->dev->platform_data;
+		pxa_set_cken(CKEN2_AC97, 1);
+		if (platform_ops && platform_ops->resume)
+			platform_ops->resume(platform_ops->priv);
+		snd_ac97_resume(pxa2xx_ac97_ac97);
+		snd_power_change_state(card, SNDRV_CTL_POWER_D0);
+	}
+
+	return 0;
+}
+
+static int pxa2xx_ac97_suspend(struct device *_dev, u32 state, u32 level)
+{
+	snd_card_t *card = dev_get_drvdata(_dev);
+	int ret = 0;
+
+	if (card && level == SUSPEND_DISABLE)
+		ret = pxa2xx_ac97_do_suspend(card, SNDRV_CTL_POWER_D3cold);
+
+	return ret;
+}
+
+static int pxa2xx_ac97_resume(struct device *_dev, u32 level)
+{
+	snd_card_t *card = dev_get_drvdata(_dev);
+	int ret = 0;
+
+	if (card && level == RESUME_ENABLE)
+		ret = pxa2xx_ac97_do_resume(card, SNDRV_CTL_POWER_D0);
+
+	return ret;
+}
+
+#else
+#define pxa2xx_ac97_suspend	NULL
+#define pxa2xx_ac97_resume	NULL
+#endif
+
+static int pxa2xx_ac97_probe(struct device *dev)
+{
+	snd_card_t *card;
+	ac97_bus_t *ac97_bus;
+	ac97_template_t ac97_template;
+	int ret;
+
+	ret = -ENOMEM;
+	card = snd_card_new(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
+			    THIS_MODULE, 0);
+	if (!card)
+		goto err;
+
+	card->dev = dev;
+	strncpy(card->driver, dev->driver->name, sizeof(card->driver));
+
+	ret = pxa2xx_pcm_new(card, &pxa2xx_ac97_pcm_client, &pxa2xx_ac97_pcm);
+	if (ret)
+		goto err;
+
+	ret = request_irq(IRQ_AC97, pxa2xx_ac97_irq, 0, "AC97", NULL);
+	if (ret < 0)
+		goto err;
+
+	pxa_gpio_mode(GPIO31_SYNC_AC97_MD);
+	pxa_gpio_mode(GPIO30_SDATA_OUT_AC97_MD);
+	pxa_gpio_mode(GPIO28_BITCLK_AC97_MD);
+	pxa_gpio_mode(GPIO29_SDATA_IN_AC97_MD);
+#ifdef CONFIG_PXA27x
+	/* Use GPIO 113 as AC97 Reset on Bulverde */
+	pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT);
+#endif
+	pxa_set_cken(CKEN2_AC97, 1);
+
+	ret = snd_ac97_bus(card, 0, &pxa2xx_ac97_ops, NULL, &ac97_bus);
+	if (ret)
+		goto err;
+	memset(&ac97_template, 0, sizeof(ac97_template));
+	ret = snd_ac97_mixer(ac97_bus, &ac97_template, &pxa2xx_ac97_ac97);
+	if (ret)
+		goto err;
+
+	snprintf(card->shortname, sizeof(card->shortname),
+		 "%s", snd_ac97_get_short_name(pxa2xx_ac97_ac97));
+	snprintf(card->longname, sizeof(card->longname),
+		 "%s (%s)", dev->driver->name, card->mixername);
+
+	snd_card_set_pm_callback(card, pxa2xx_ac97_do_suspend,
+				 pxa2xx_ac97_do_resume, NULL);
+	ret = snd_card_register(card);
+	if (ret == 0) {
+		dev_set_drvdata(dev, card);
+		return 0;
+	}
+
+ err:
+	if (card)
+		snd_card_free(card);
+	if (CKEN & CKEN2_AC97) {
+		GCR |= GCR_ACLINK_OFF;
+		free_irq(IRQ_AC97, NULL);
+		pxa_set_cken(CKEN2_AC97, 0);
+	}
+	return ret;
+}
+
+static int pxa2xx_ac97_remove(struct device *dev)
+{
+	snd_card_t *card = dev_get_drvdata(dev);
+
+	if (card) {
+		snd_card_free(card);
+		dev_set_drvdata(dev, NULL);
+		GCR |= GCR_ACLINK_OFF;
+		free_irq(IRQ_AC97, NULL);
+		pxa_set_cken(CKEN2_AC97, 0);
+	}
+
+	return 0;
+}
+
+static struct device_driver pxa2xx_ac97_driver = {
+	.name		= "pxa2xx-ac97",
+	.bus		= &platform_bus_type,
+	.probe		= pxa2xx_ac97_probe,
+	.remove		= pxa2xx_ac97_remove,
+	.suspend	= pxa2xx_ac97_suspend,
+	.resume		= pxa2xx_ac97_resume,
+};
+
+static int __init pxa2xx_ac97_init(void)
+{
+	return driver_register(&pxa2xx_ac97_driver);
+}
+
+static void __exit pxa2xx_ac97_exit(void)
+{
+	driver_unregister(&pxa2xx_ac97_driver);
+}
+
+module_init(pxa2xx_ac97_init);
+module_exit(pxa2xx_ac97_exit);
+
+MODULE_AUTHOR("Nicolas Pitre");
+MODULE_DESCRIPTION("AC97 driver for the Intel PXA2xx chip");
+MODULE_LICENSE("GPL");
diff --git a/sound/arm/pxa2xx-pcm.c b/sound/arm/pxa2xx-pcm.c
new file mode 100644
--- /dev/null
+++ b/sound/arm/pxa2xx-pcm.c
@@ -0,0 +1,367 @@
+/*
+ * linux/sound/arm/pxa2xx-pcm.c -- ALSA PCM interface for the Intel PXA2xx chip
+ *
+ * Author:	Nicolas Pitre
+ * Created:	Nov 30, 2004
+ * Copyright:	(C) 2004 MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/slab.h>
+#include <linux/dma-mapping.h>
+
+#include <sound/driver.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+
+#include <asm/dma.h>
+#include <asm/hardware.h>
+#include <asm/arch/pxa-regs.h>
+
+#include "pxa2xx-pcm.h"
+
+
+static const snd_pcm_hardware_t pxa2xx_pcm_hardware = {
+	.info			= SNDRV_PCM_INFO_MMAP |
+				  SNDRV_PCM_INFO_MMAP_VALID |
+				  SNDRV_PCM_INFO_INTERLEAVED |
+				  SNDRV_PCM_INFO_PAUSE,
+	.formats		= SNDRV_PCM_FMTBIT_S16_LE,
+	.period_bytes_min	= 32,
+	.period_bytes_max	= 8192 - 32,
+	.periods_min		= 1,
+	.periods_max		= PAGE_SIZE/sizeof(pxa_dma_desc),
+	.buffer_bytes_max	= 128 * 1024,
+	.fifo_size		= 32,
+};
+
+struct pxa2xx_runtime_data {
+	int dma_ch;
+	pxa2xx_pcm_dma_params_t *params;
+	pxa_dma_desc *dma_desc_array;
+	dma_addr_t dma_desc_array_phys;
+};
+
+static int pxa2xx_pcm_hw_params(snd_pcm_substream_t *substream,
+				snd_pcm_hw_params_t *params)
+{
+	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct pxa2xx_runtime_data *rtd = runtime->private_data;
+	size_t totsize = params_buffer_bytes(params);
+	size_t period = params_period_bytes(params);
+	pxa_dma_desc *dma_desc;
+	dma_addr_t dma_buff_phys, next_desc_phys;
+
+	snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
+	runtime->dma_bytes = totsize;
+
+	dma_desc = rtd->dma_desc_array;
+	next_desc_phys = rtd->dma_desc_array_phys;
+	dma_buff_phys = runtime->dma_addr;
+	do {
+		next_desc_phys += sizeof(pxa_dma_desc);
+		dma_desc->ddadr = next_desc_phys;
+		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+			dma_desc->dsadr = dma_buff_phys;
+			dma_desc->dtadr = rtd->params->dev_addr;
+		} else {
+			dma_desc->dsadr = rtd->params->dev_addr;
+			dma_desc->dtadr = dma_buff_phys;
+		}
+		if (period > totsize)
+			period = totsize;
+		dma_desc->dcmd = rtd->params->dcmd | period | DCMD_ENDIRQEN;
+		dma_desc++;
+		dma_buff_phys += period;
+	} while (totsize -= period);
+	dma_desc[-1].ddadr = rtd->dma_desc_array_phys;
+
+	return 0;
+}
+
+static int pxa2xx_pcm_hw_free(snd_pcm_substream_t *substream)
+{
+	struct pxa2xx_runtime_data *rtd = substream->runtime->private_data;
+
+	*rtd->params->drcmr = 0;
+	snd_pcm_set_runtime_buffer(substream, NULL);
+	return 0;
+}
+
+static int pxa2xx_pcm_prepare(snd_pcm_substream_t *substream)
+{
+	pxa2xx_pcm_client_t *client = substream->private_data;
+	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct pxa2xx_runtime_data *rtd = runtime->private_data;
+
+	DCSR(rtd->dma_ch) &= ~DCSR_RUN;
+	DCSR(rtd->dma_ch) = 0;
+	DCMD(rtd->dma_ch) = 0;
+	*rtd->params->drcmr = rtd->dma_ch | DRCMR_MAPVLD;
+
+	return client->prepare(substream);
+}
+
+static int pxa2xx_pcm_trigger(snd_pcm_substream_t *substream, int cmd)
+{
+	struct pxa2xx_runtime_data *rtd = substream->runtime->private_data;
+	int ret = 0;
+
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+		DDADR(rtd->dma_ch) = rtd->dma_desc_array_phys;
+		DCSR(rtd->dma_ch) = DCSR_RUN;
+		break;
+
+	case SNDRV_PCM_TRIGGER_STOP:
+	case SNDRV_PCM_TRIGGER_SUSPEND:
+	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+		DCSR(rtd->dma_ch) &= ~DCSR_RUN;
+		break;
+
+	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+		DCSR(rtd->dma_ch) |= DCSR_RUN;
+		break;
+
+	default:
+		ret = -EINVAL;
+	}
+
+	return ret;
+}
+
+static void pxa2xx_pcm_dma_irq(int dma_ch, void *dev_id, struct pt_regs *regs)
+{
+	snd_pcm_substream_t *substream = dev_id;
+	struct pxa2xx_runtime_data *rtd = substream->runtime->private_data;
+	int dcsr;
+
+	dcsr = DCSR(dma_ch);
+	DCSR(dma_ch) = dcsr & ~DCSR_STOPIRQEN;
+
+	if (dcsr & DCSR_ENDINTR) {
+		snd_pcm_period_elapsed(substream);
+	} else {
+		printk( KERN_ERR "%s: DMA error on channel %d (DCSR=%#x)\n",
+			rtd->params->name, dma_ch, dcsr );
+		snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
+	}
+}
+
+static snd_pcm_uframes_t pxa2xx_pcm_pointer(snd_pcm_substream_t *substream)
+{
+	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct pxa2xx_runtime_data *rtd = runtime->private_data;
+	dma_addr_t ptr = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
+			 DSADR(rtd->dma_ch) : DTADR(rtd->dma_ch);
+	snd_pcm_uframes_t x = bytes_to_frames(runtime, ptr - runtime->dma_addr);
+	if (x == runtime->buffer_size)
+		x = 0;
+	return x;
+}
+
+static int
+pxa2xx_pcm_hw_rule_mult32(snd_pcm_hw_params_t *params, snd_pcm_hw_rule_t *rule)
+{
+	snd_interval_t *i = hw_param_interval(params, rule->var);
+	int changed = 0;
+
+	if (i->min & 31) {
+		i->min = (i->min & ~31) + 32;
+		i->openmin = 0;
+		changed = 1;
+	}
+
+	if (i->max & 31) {
+		i->max &= ~31;
+		i->openmax = 0;
+		changed = 1;
+	}
+
+	return changed;
+}
+
+static int pxa2xx_pcm_open(snd_pcm_substream_t *substream)
+{
+	pxa2xx_pcm_client_t *client = substream->private_data;
+	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct pxa2xx_runtime_data *rtd;
+	int ret;
+
+	runtime->hw = pxa2xx_pcm_hardware;
+
+	/*
+	 * For mysterious reasons (and despite what the manual says)
+	 * playback samples are lost if the DMA count is not a multiple
+	 * of the DMA burst size.  Let's add a rule to enforce that.
+	 */
+	ret = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
+				  pxa2xx_pcm_hw_rule_mult32, NULL,
+				  SNDRV_PCM_HW_PARAM_PERIOD_BYTES, -1);
+	if (ret)
+		goto out;
+	ret = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
+				  pxa2xx_pcm_hw_rule_mult32, NULL,
+				  SNDRV_PCM_HW_PARAM_BUFFER_BYTES, -1);
+	if (ret)
+		goto out;
+
+	ret = -ENOMEM;
+	rtd = kmalloc(sizeof(*rtd), GFP_KERNEL);
+	if (!rtd)
+		goto out;
+	rtd->dma_desc_array =
+		dma_alloc_writecombine(substream->pcm->card->dev, PAGE_SIZE,
+				       &rtd->dma_desc_array_phys, GFP_KERNEL);
+	if (!rtd->dma_desc_array)
+		goto err1;
+
+	rtd->params = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
+		      client->playback_params : client->capture_params;
+	ret = pxa_request_dma(rtd->params->name, DMA_PRIO_LOW,
+			      pxa2xx_pcm_dma_irq, substream);
+	if (ret < 0)
+		goto err2;
+	rtd->dma_ch = ret;
+
+	runtime->private_data = rtd;
+	ret = client->startup(substream);
+	if (!ret)
+		goto out;
+
+	pxa_free_dma(rtd->dma_ch);
+ err2:
+	dma_free_writecombine(substream->pcm->card->dev, PAGE_SIZE,
+			      rtd->dma_desc_array, rtd->dma_desc_array_phys);
+ err1:
+	kfree(rtd);
+ out:
+	return ret;
+}
+
+static int pxa2xx_pcm_close(snd_pcm_substream_t *substream)
+{
+	pxa2xx_pcm_client_t *client = substream->private_data;
+	struct pxa2xx_runtime_data *rtd = substream->runtime->private_data;
+
+	pxa_free_dma(rtd->dma_ch);
+	client->shutdown(substream);
+	dma_free_writecombine(substream->pcm->card->dev, PAGE_SIZE,
+			      rtd->dma_desc_array, rtd->dma_desc_array_phys);
+	kfree(rtd);
+	return 0;
+}
+
+static int
+pxa2xx_pcm_mmap(snd_pcm_substream_t *substream, struct vm_area_struct *vma)
+{
+	snd_pcm_runtime_t *runtime = substream->runtime;
+	return dma_mmap_writecombine(substream->pcm->card->dev, vma,
+				     runtime->dma_area,
+				     runtime->dma_addr,
+				     runtime->dma_bytes);
+}
+
+static snd_pcm_ops_t pxa2xx_pcm_ops = {
+	.open		= pxa2xx_pcm_open,
+	.close		= pxa2xx_pcm_close,
+	.ioctl		= snd_pcm_lib_ioctl,
+	.hw_params	= pxa2xx_pcm_hw_params,
+	.hw_free	= pxa2xx_pcm_hw_free,
+	.prepare	= pxa2xx_pcm_prepare,
+	.trigger	= pxa2xx_pcm_trigger,
+	.pointer	= pxa2xx_pcm_pointer,
+	.mmap		= pxa2xx_pcm_mmap,
+};
+
+static int pxa2xx_pcm_preallocate_dma_buffer(snd_pcm_t *pcm, int stream)
+{
+	snd_pcm_substream_t *substream = pcm->streams[stream].substream;
+	struct snd_dma_buffer *buf = &substream->dma_buffer;
+	size_t size = pxa2xx_pcm_hardware.buffer_bytes_max;
+	buf->dev.type = SNDRV_DMA_TYPE_DEV;
+	buf->dev.dev = pcm->card->dev;
+	buf->private_data = NULL;
+	buf->area = dma_alloc_writecombine(pcm->card->dev, size,
+					   &buf->addr, GFP_KERNEL);
+	if (!buf->area)
+		return -ENOMEM;
+	buf->bytes = size;
+	return 0;
+}
+
+static void pxa2xx_pcm_free_dma_buffers(snd_pcm_t *pcm)
+{
+	snd_pcm_substream_t *substream;
+	struct snd_dma_buffer *buf;
+	int stream;
+
+	for (stream = 0; stream < 2; stream++) {
+		substream = pcm->streams[stream].substream;
+		if (!substream)
+			continue;
+		buf = &substream->dma_buffer;
+		if (!buf->area)
+			continue;
+		dma_free_writecombine(pcm->card->dev, buf->bytes,
+				      buf->area, buf->addr);
+		buf->area = NULL;
+	}
+}
+
+static u64 pxa2xx_pcm_dmamask = 0xffffffff;
+
+int pxa2xx_pcm_new(snd_card_t *card, pxa2xx_pcm_client_t *client, snd_pcm_t **rpcm)
+{
+	snd_pcm_t *pcm;
+	int play = client->playback_params ? 1 : 0;
+	int capt = client->capture_params ? 1 : 0;
+	int ret;
+
+	ret = snd_pcm_new(card, "PXA2xx-PCM", 0, play, capt, &pcm);
+	if (ret)
+		goto out;
+
+	pcm->private_data = client;
+	pcm->private_free = pxa2xx_pcm_free_dma_buffers;
+
+	if (!card->dev->dma_mask)
+		card->dev->dma_mask = &pxa2xx_pcm_dmamask;
+	if (!card->dev->coherent_dma_mask)
+		card->dev->coherent_dma_mask = 0xffffffff;
+
+	if (play) {
+		int stream = SNDRV_PCM_STREAM_PLAYBACK;
+		snd_pcm_set_ops(pcm, stream, &pxa2xx_pcm_ops);
+		ret = pxa2xx_pcm_preallocate_dma_buffer(pcm, stream);
+		if (ret)
+			goto out;
+	}
+	if (capt) {
+		int stream = SNDRV_PCM_STREAM_CAPTURE;
+		snd_pcm_set_ops(pcm, stream, &pxa2xx_pcm_ops);
+		ret = pxa2xx_pcm_preallocate_dma_buffer(pcm, stream);
+		if (ret)
+			goto out;
+	}
+
+	if (rpcm)
+		*rpcm = pcm;
+	ret = 0;
+
+ out:
+	return ret;
+}
+
+EXPORT_SYMBOL(pxa2xx_pcm_new);
+
+MODULE_AUTHOR("Nicolas Pitre");
+MODULE_DESCRIPTION("Intel PXA2xx PCM DMA module");
+MODULE_LICENSE("GPL");
diff --git a/sound/arm/pxa2xx-pcm.h b/sound/arm/pxa2xx-pcm.h
new file mode 100644
--- /dev/null
+++ b/sound/arm/pxa2xx-pcm.h
@@ -0,0 +1,29 @@
+/*
+ * linux/sound/arm/pxa2xx-pcm.h -- ALSA PCM interface for the Intel PXA2xx chip
+ *
+ * Author:	Nicolas Pitre
+ * Created:	Nov 30, 2004
+ * Copyright:	MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+typedef struct {
+	char *name;			/* stream identifier */
+	u32 dcmd;			/* DMA descriptor dcmd field */
+	volatile u32 *drcmr;		/* the DMA request channel to use */
+	u32 dev_addr;			/* device physical address for DMA */
+} pxa2xx_pcm_dma_params_t;
+	
+typedef struct {
+	pxa2xx_pcm_dma_params_t *playback_params;
+	pxa2xx_pcm_dma_params_t *capture_params;
+	int (*startup)(snd_pcm_substream_t *);
+	void (*shutdown)(snd_pcm_substream_t *);
+	int (*prepare)(snd_pcm_substream_t *);
+} pxa2xx_pcm_client_t;
+
+extern int pxa2xx_pcm_new(snd_card_t *, pxa2xx_pcm_client_t *, snd_pcm_t **);
+
diff --git a/sound/core/Makefile b/sound/core/Makefile
--- a/sound/core/Makefile
+++ b/sound/core/Makefile
@@ -5,7 +5,7 @@
 
 snd-objs     := sound.o init.o memory.o info.o control.o misc.o \
                 device.o wrappers.o
-ifeq ($(CONFIG_ISA),y)
+ifeq ($(CONFIG_ISA_DMA_API),y)
 snd-objs     += isadma.o
 endif
 ifeq ($(CONFIG_SND_OSSEMUL),y)
diff --git a/sound/core/control.c b/sound/core/control.c
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -215,7 +215,7 @@ snd_kcontrol_t *snd_ctl_new(snd_kcontrol
  *
  * Returns the pointer of the newly generated instance, or NULL on failure.
  */
-snd_kcontrol_t *snd_ctl_new1(snd_kcontrol_new_t * ncontrol, void *private_data)
+snd_kcontrol_t *snd_ctl_new1(const snd_kcontrol_new_t * ncontrol, void *private_data)
 {
 	snd_kcontrol_t kctl;
 	unsigned int access;
@@ -1102,7 +1102,7 @@ static long snd_ctl_ioctl(struct file *f
 		}
 	}
 	up_read(&snd_ioctl_rwsem);
-	snd_printd("unknown ioctl = 0x%x\n", cmd);
+	snd_printdd("unknown ioctl = 0x%x\n", cmd);
 	return -ENOTTY;
 }
 
diff --git a/sound/core/device.c b/sound/core/device.c
--- a/sound/core/device.c
+++ b/sound/core/device.c
@@ -28,7 +28,7 @@
 /**
  * snd_device_new - create an ALSA device component
  * @card: the card instance
- * @type: the device type, SNDRV_DEV_TYPE_XXX
+ * @type: the device type, SNDRV_DEV_XXX
  * @device_data: the data pointer of this device
  * @ops: the operator table
  *
@@ -46,7 +46,9 @@ int snd_device_new(snd_card_t *card, snd
 {
 	snd_device_t *dev;
 
-	snd_assert(card != NULL && device_data != NULL && ops != NULL, return -ENXIO);
+	snd_assert(card != NULL, return -ENXIO);
+	snd_assert(device_data != NULL, return -ENXIO);
+	snd_assert(ops != NULL, return -ENXIO);
 	dev = kcalloc(1, sizeof(*dev), GFP_KERNEL);
 	if (dev == NULL)
 		return -ENOMEM;
@@ -102,7 +104,7 @@ int snd_device_free(snd_card_t *card, vo
 }
 
 /**
- * snd_device_free - disconnect the device
+ * snd_device_disconnect - disconnect the device
  * @card: the card instance
  * @device_data: the data pointer to disconnect
  *
@@ -118,7 +120,7 @@ int snd_device_disconnect(snd_card_t *ca
 {
 	struct list_head *list;
 	snd_device_t *dev;
-	
+
 	snd_assert(card != NULL, return -ENXIO);
 	snd_assert(device_data != NULL, return -ENXIO);
 	list_for_each(list, &card->devices) {
@@ -154,8 +156,9 @@ int snd_device_register(snd_card_t *card
 	struct list_head *list;
 	snd_device_t *dev;
 	int err;
-	
-	snd_assert(card != NULL && device_data != NULL, return -ENXIO);
+
+	snd_assert(card != NULL, return -ENXIO);
+	snd_assert(device_data != NULL, return -ENXIO);
 	list_for_each(list, &card->devices) {
 		dev = snd_device(list);
 		if (dev->device_data != device_data)
diff --git a/sound/core/info.c b/sound/core/info.c
--- a/sound/core/info.c
+++ b/sound/core/info.c
@@ -24,6 +24,7 @@
 #include <linux/vmalloc.h>
 #include <linux/time.h>
 #include <linux/smp_lock.h>
+#include <linux/string.h>
 #include <sound/core.h>
 #include <sound/minors.h>
 #include <sound/info.h>
@@ -701,7 +702,7 @@ int snd_info_get_line(snd_info_buffer_t 
 }
 
 /**
- * snd_info_get_line - parse a string token
+ * snd_info_get_str - parse a string token
  * @dest: the buffer to store the string token
  * @src: the original string
  * @len: the max. length of token - 1
@@ -754,7 +755,7 @@ static snd_info_entry_t *snd_info_create
 	entry = kcalloc(1, sizeof(*entry), GFP_KERNEL);
 	if (entry == NULL)
 		return NULL;
-	entry->name = snd_kmalloc_strdup(name, GFP_KERNEL);
+	entry->name = kstrdup(name, GFP_KERNEL);
 	if (entry->name == NULL) {
 		kfree(entry);
 		return NULL;
@@ -938,7 +939,8 @@ int snd_info_unregister(snd_info_entry_t
 {
 	struct proc_dir_entry *root;
 
-	snd_assert(entry != NULL && entry->p != NULL, return -ENXIO);
+	snd_assert(entry != NULL, return -ENXIO);
+	snd_assert(entry->p != NULL, return -ENXIO);
 	root = entry->parent == NULL ? snd_proc_root : entry->parent->p;
 	snd_assert(root, return -ENXIO);
 	down(&info_mutex);
diff --git a/sound/core/info_oss.c b/sound/core/info_oss.c
--- a/sound/core/info_oss.c
+++ b/sound/core/info_oss.c
@@ -22,6 +22,7 @@
 #include <sound/driver.h>
 #include <linux/slab.h>
 #include <linux/time.h>
+#include <linux/string.h>
 #include <sound/core.h>
 #include <sound/minors.h>
 #include <sound/info.h>
@@ -51,7 +52,7 @@ int snd_oss_info_register(int dev, int n
 			x = NULL;
 		}
 	} else {
-		x = snd_kmalloc_strdup(string, GFP_KERNEL);
+		x = kstrdup(string, GFP_KERNEL);
 		if (x == NULL) {
 			up(&strings);
 			return -ENOMEM;
diff --git a/sound/core/memalloc.c b/sound/core/memalloc.c
--- a/sound/core/memalloc.c
+++ b/sound/core/memalloc.c
@@ -28,6 +28,7 @@
 #include <linux/pci.h>
 #include <linux/slab.h>
 #include <linux/mm.h>
+#include <asm/uaccess.h>
 #include <linux/dma-mapping.h>
 #include <linux/moduleparam.h>
 #include <asm/semaphore.h>
@@ -46,13 +47,6 @@ MODULE_LICENSE("GPL");
 #define SNDRV_CARDS	8
 #endif
 
-/* FIXME: so far only some PCI devices have the preallocation table */
-#ifdef CONFIG_PCI
-static int enable[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = 1};
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable cards to allocate buffers.");
-#endif
-
 /*
  */
 
@@ -111,7 +105,8 @@ struct snd_mem_list {
  */
 
 static void *snd_dma_hack_alloc_coherent(struct device *dev, size_t size,
-					 dma_addr_t *dma_handle, int flags)
+					 dma_addr_t *dma_handle,
+					 unsigned int __nocast flags)
 {
 	void *ret;
 	u64 dma_mask, coherent_dma_mask;
@@ -451,9 +446,13 @@ size_t snd_dma_get_reserved_buf(struct s
 	list_for_each(p, &mem_list_head) {
 		mem = list_entry(p, struct snd_mem_list, list);
 		if (mem->id == id &&
-		    ! memcmp(&mem->buffer.dev, &dmab->dev, sizeof(dmab->dev))) {
+		    (mem->buffer.dev.dev == NULL || dmab->dev.dev == NULL ||
+		     ! memcmp(&mem->buffer.dev, &dmab->dev, sizeof(dmab->dev)))) {
+			struct device *dev = dmab->dev.dev;
 			list_del(p);
 			*dmab = mem->buffer;
+			if (dmab->dev.dev == NULL)
+				dmab->dev.dev = dev;
 			kfree(mem);
 			up(&list_mutex);
 			return dmab->bytes;
@@ -508,91 +507,13 @@ static void free_all_reserved_pages(void
 }
 
 
-
-/*
- * allocation of buffers for pre-defined devices
- */
-
-#ifdef CONFIG_PCI
-/* FIXME: for pci only - other bus? */
-struct prealloc_dev {
-	unsigned short vendor;
-	unsigned short device;
-	unsigned long dma_mask;
-	unsigned int size;
-	unsigned int buffers;
-};
-
-#define HAMMERFALL_BUFFER_SIZE    (16*1024*4*(26+1)+0x10000)
-
-static struct prealloc_dev prealloc_devices[] __initdata = {
-	{
-		/* hammerfall */
-		.vendor = 0x10ee,
-		.device = 0x3fc4,
-		.dma_mask = 0xffffffff,
-		.size = HAMMERFALL_BUFFER_SIZE,
-		.buffers = 2
-	},
-	{
-		/* HDSP */
-		.vendor = 0x10ee,
-		.device = 0x3fc5,
-		.dma_mask = 0xffffffff,
-		.size = HAMMERFALL_BUFFER_SIZE,
-		.buffers = 2
-	},
-	{ }, /* terminator */
-};
-
-static void __init preallocate_cards(void)
-{
-	struct pci_dev *pci = NULL;
-	int card;
-
-	card = 0;
-
-	while ((pci = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pci)) != NULL) {
-		struct prealloc_dev *dev;
-		unsigned int i;
-		if (card >= SNDRV_CARDS)
-			break;
-		for (dev = prealloc_devices; dev->vendor; dev++) {
-			if (dev->vendor == pci->vendor && dev->device == pci->device)
-				break;
-		}
-		if (! dev->vendor)
-			continue;
-		if (! enable[card++]) {
-			printk(KERN_DEBUG "snd-page-alloc: skipping card %d, device %04x:%04x\n", card, pci->vendor, pci->device);
-			continue;
-		}
-			
-		if (pci_set_dma_mask(pci, dev->dma_mask) < 0 ||
-		    pci_set_consistent_dma_mask(pci, dev->dma_mask) < 0) {
-			printk(KERN_ERR "snd-page-alloc: cannot set DMA mask %lx for pci %04x:%04x\n", dev->dma_mask, dev->vendor, dev->device);
-			continue;
-		}
-		for (i = 0; i < dev->buffers; i++) {
-			struct snd_dma_buffer dmab;
-			memset(&dmab, 0, sizeof(dmab));
-			if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
-						dev->size, &dmab) < 0)
-				printk(KERN_WARNING "snd-page-alloc: cannot allocate buffer pages (size = %d)\n", dev->size);
-			else
-				snd_dma_reserve_buf(&dmab, snd_dma_pci_buf_id(pci));
-		}
-	}
-}
-#else
-#define preallocate_cards()	/* NOP */
-#endif
-
-
 #ifdef CONFIG_PROC_FS
 /*
  * proc file interface
  */
+#define SND_MEM_PROC_FILE	"driver/snd-page-alloc"
+struct proc_dir_entry *snd_mem_proc;
+
 static int snd_mem_proc_read(char *page, char **start, off_t off,
 			     int count, int *eof, void *data)
 {
@@ -621,6 +542,97 @@ static int snd_mem_proc_read(char *page,
 	up(&list_mutex);
 	return len;
 }
+
+/* FIXME: for pci only - other bus? */
+#ifdef CONFIG_PCI
+#define gettoken(bufp) strsep(bufp, " \t\n")
+
+static int snd_mem_proc_write(struct file *file, const char __user *buffer,
+			      unsigned long count, void *data)
+{
+	char buf[128];
+	char *token, *p;
+
+	if (count > ARRAY_SIZE(buf) - 1)
+		count = ARRAY_SIZE(buf) - 1;
+	if (copy_from_user(buf, buffer, count))
+		return -EFAULT;
+	buf[ARRAY_SIZE(buf) - 1] = '\0';
+
+	p = buf;
+	token = gettoken(&p);
+	if (! token || *token == '#')
+		return (int)count;
+	if (strcmp(token, "add") == 0) {
+		char *endp;
+		int vendor, device, size, buffers;
+		long mask;
+		int i, alloced;
+		struct pci_dev *pci;
+
+		if ((token = gettoken(&p)) == NULL ||
+		    (vendor = simple_strtol(token, NULL, 0)) <= 0 ||
+		    (token = gettoken(&p)) == NULL ||
+		    (device = simple_strtol(token, NULL, 0)) <= 0 ||
+		    (token = gettoken(&p)) == NULL ||
+		    (mask = simple_strtol(token, NULL, 0)) < 0 ||
+		    (token = gettoken(&p)) == NULL ||
+		    (size = memparse(token, &endp)) < 64*1024 ||
+		    size > 16*1024*1024 /* too big */ ||
+		    (token = gettoken(&p)) == NULL ||
+		    (buffers = simple_strtol(token, NULL, 0)) <= 0 ||
+		    buffers > 4) {
+			printk(KERN_ERR "snd-page-alloc: invalid proc write format\n");
+			return (int)count;
+		}
+		vendor &= 0xffff;
+		device &= 0xffff;
+
+		alloced = 0;
+		pci = NULL;
+		while ((pci = pci_find_device(vendor, device, pci)) != NULL) {
+			if (mask > 0 && mask < 0xffffffff) {
+				if (pci_set_dma_mask(pci, mask) < 0 ||
+				    pci_set_consistent_dma_mask(pci, mask) < 0) {
+					printk(KERN_ERR "snd-page-alloc: cannot set DMA mask %lx for pci %04x:%04x\n", mask, vendor, device);
+					return (int)count;
+				}
+			}
+			for (i = 0; i < buffers; i++) {
+				struct snd_dma_buffer dmab;
+				memset(&dmab, 0, sizeof(dmab));
+				if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
+							size, &dmab) < 0) {
+					printk(KERN_ERR "snd-page-alloc: cannot allocate buffer pages (size = %d)\n", size);
+					return (int)count;
+				}
+				snd_dma_reserve_buf(&dmab, snd_dma_pci_buf_id(pci));
+			}
+			alloced++;
+		}
+		if (! alloced) {
+			for (i = 0; i < buffers; i++) {
+				struct snd_dma_buffer dmab;
+				memset(&dmab, 0, sizeof(dmab));
+				/* FIXME: We can allocate only in ZONE_DMA
+				 * without a device pointer!
+				 */
+				if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, NULL,
+							size, &dmab) < 0) {
+					printk(KERN_ERR "snd-page-alloc: cannot allocate buffer pages (size = %d)\n", size);
+					break;
+				}
+				snd_dma_reserve_buf(&dmab, (unsigned int)((vendor << 16) | device));
+			}
+		}
+	} else if (strcmp(token, "erase") == 0)
+		/* FIXME: need for releasing each buffer chunk? */
+		free_all_reserved_pages();
+	else
+		printk(KERN_ERR "snd-page-alloc: invalid proc cmd\n");
+	return (int)count;
+}
+#endif /* CONFIG_PCI */
 #endif /* CONFIG_PROC_FS */
 
 /*
@@ -630,15 +642,21 @@ static int snd_mem_proc_read(char *page,
 static int __init snd_mem_init(void)
 {
 #ifdef CONFIG_PROC_FS
-	create_proc_read_entry("driver/snd-page-alloc", 0, NULL, snd_mem_proc_read, NULL);
+	snd_mem_proc = create_proc_entry(SND_MEM_PROC_FILE, 0644, NULL);
+	if (snd_mem_proc) {
+		snd_mem_proc->read_proc = snd_mem_proc_read;
+#ifdef CONFIG_PCI
+		snd_mem_proc->write_proc = snd_mem_proc_write;
+#endif
+	}
 #endif
-	preallocate_cards();
 	return 0;
 }
 
 static void __exit snd_mem_exit(void)
 {
-	remove_proc_entry("driver/snd-page-alloc", NULL);
+	if (snd_mem_proc)
+		remove_proc_entry(SND_MEM_PROC_FILE, NULL);
 	free_all_reserved_pages();
 	if (snd_allocated_pages > 0)
 		printk(KERN_ERR "snd-malloc: Memory leak?  pages not freed = %li\n", snd_allocated_pages);
diff --git a/sound/core/memory.c b/sound/core/memory.c
--- a/sound/core/memory.c
+++ b/sound/core/memory.c
@@ -89,7 +89,7 @@ void snd_memory_done(void)
 	}
 }
 
-static void *__snd_kmalloc(size_t size, int flags, void *caller)
+static void *__snd_kmalloc(size_t size, unsigned int __nocast flags, void *caller)
 {
 	unsigned long cpu_flags;
 	struct snd_alloc_track *t;
@@ -111,12 +111,12 @@ static void *__snd_kmalloc(size_t size, 
 }
 
 #define _snd_kmalloc(size, flags) __snd_kmalloc((size), (flags), __builtin_return_address(0));
-void *snd_hidden_kmalloc(size_t size, int flags)
+void *snd_hidden_kmalloc(size_t size, unsigned int __nocast flags)
 {
 	return _snd_kmalloc(size, flags);
 }
 
-void *snd_hidden_kcalloc(size_t n, size_t size, int flags)
+void *snd_hidden_kcalloc(size_t n, size_t size, unsigned int __nocast flags)
 {
 	void *ret = NULL;
 	if (n != 0 && size > INT_MAX / n)
@@ -184,6 +184,20 @@ void snd_hidden_vfree(void *obj)
 	snd_wrapper_vfree(obj);
 }
 
+char *snd_hidden_kstrdup(const char *s, unsigned int __nocast flags)
+{
+	int len;
+	char *buf;
+
+	if (!s) return NULL;
+
+	len = strlen(s) + 1;
+	buf = _snd_kmalloc(len, flags);
+	if (buf)
+		memcpy(buf, s, len);
+	return buf;
+}
+
 static void snd_memory_info_read(snd_info_entry_t *entry, snd_info_buffer_t * buffer)
 {
 	snd_iprintf(buffer, "kmalloc: %li bytes\n", snd_alloc_kmalloc);
@@ -214,36 +228,9 @@ int __exit snd_memory_info_done(void)
 	return 0;
 }
 
-#else
-
-#define _snd_kmalloc kmalloc
-
 #endif /* CONFIG_SND_DEBUG_MEMORY */
 
 /**
- * snd_kmalloc_strdup - copy the string
- * @string: the original string
- * @flags: allocation conditions, GFP_XXX
- *
- * Allocates a memory chunk via kmalloc() and copies the string to it.
- *
- * Returns the pointer, or NULL if no enoguh memory.
- */
-char *snd_kmalloc_strdup(const char *string, int flags)
-{
-	size_t len;
-	char *ptr;
-
-	if (!string)
-		return NULL;
-	len = strlen(string) + 1;
-	ptr = _snd_kmalloc(len, flags);
-	if (ptr)
-		memcpy(ptr, string, len);
-	return ptr;
-}
-
-/**
  * copy_to_user_fromio - copy data from mmio-space to user-space
  * @dst: the destination pointer on user-space
  * @src: the source pointer on mmio
diff --git a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c
--- a/sound/core/oss/mixer_oss.c
+++ b/sound/core/oss/mixer_oss.c
@@ -24,6 +24,7 @@
 #include <linux/smp_lock.h>
 #include <linux/slab.h>
 #include <linux/time.h>
+#include <linux/string.h>
 #include <sound/core.h>
 #include <sound/minors.h>
 #include <sound/control.h>
@@ -1137,7 +1138,7 @@ static void snd_mixer_oss_proc_write(snd
 			goto __unlock;
 		}
 		tbl->oss_id = ch;
-		tbl->name = snd_kmalloc_strdup(str, GFP_KERNEL);
+		tbl->name = kstrdup(str, GFP_KERNEL);
 		if (! tbl->name) {
 			kfree(tbl);
 			goto __unlock;
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -33,6 +33,7 @@
 #include <linux/time.h>
 #include <linux/vmalloc.h>
 #include <linux/moduleparam.h>
+#include <linux/string.h>
 #include <sound/core.h>
 #include <sound/minors.h>
 #include <sound/pcm.h>
@@ -125,17 +126,26 @@ int snd_pcm_plugin_append(snd_pcm_plugin
 static long snd_pcm_oss_bytes(snd_pcm_substream_t *substream, long frames)
 {
 	snd_pcm_runtime_t *runtime = substream->runtime;
-	snd_pcm_uframes_t buffer_size = snd_pcm_lib_buffer_bytes(substream);
-	frames = frames_to_bytes(runtime, frames);
+	long buffer_size = snd_pcm_lib_buffer_bytes(substream);
+	long bytes = frames_to_bytes(runtime, frames);
 	if (buffer_size == runtime->oss.buffer_bytes)
-		return frames;
-	return (runtime->oss.buffer_bytes * frames) / buffer_size;
+		return bytes;
+#if BITS_PER_LONG >= 64
+	return runtime->oss.buffer_bytes * bytes / buffer_size;
+#else
+	{
+		u64 bsize = (u64)runtime->oss.buffer_bytes * (u64)bytes;
+		u32 rem;
+		div64_32(&bsize, buffer_size, &rem);
+		return (long)bsize;
+	}
+#endif
 }
 
 static long snd_pcm_alsa_frames(snd_pcm_substream_t *substream, long bytes)
 {
 	snd_pcm_runtime_t *runtime = substream->runtime;
-	snd_pcm_uframes_t buffer_size = snd_pcm_lib_buffer_bytes(substream);
+	long buffer_size = snd_pcm_lib_buffer_bytes(substream);
 	if (buffer_size == runtime->oss.buffer_bytes)
 		return bytes_to_frames(runtime, bytes);
 	return bytes_to_frames(runtime, (buffer_size * bytes) / runtime->oss.buffer_bytes);
@@ -464,7 +474,8 @@ static int snd_pcm_oss_change_params(snd
 	sw_params->tstamp_mode = SNDRV_PCM_TSTAMP_NONE;
 	sw_params->period_step = 1;
 	sw_params->sleep_min = 0;
-	sw_params->avail_min = 1;
+	sw_params->avail_min = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
+		1 : runtime->period_size;
 	sw_params->xfer_align = 1;
 	if (atomic_read(&runtime->mmap_count) ||
 	    (substream->oss.setup && substream->oss.setup->nosilence)) {
@@ -1527,12 +1538,15 @@ static int snd_pcm_oss_get_ptr(snd_pcm_o
 			snd_pcm_oss_simulate_fill(substream, delay);
 		info.bytes = snd_pcm_oss_bytes(substream, runtime->status->hw_ptr) & INT_MAX;
 	} else {
-		delay = snd_pcm_oss_bytes(substream, delay) + fixup;
-		info.blocks = delay / runtime->oss.period_bytes;
-		if (stream == SNDRV_PCM_STREAM_PLAYBACK)
+		delay = snd_pcm_oss_bytes(substream, delay);
+		if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
+			info.blocks = (runtime->oss.buffer_bytes - delay - fixup) / runtime->oss.period_bytes;
 			info.bytes = (runtime->oss.bytes - delay) & INT_MAX;
-		else
+		} else {
+			delay += fixup;
+			info.blocks = delay / runtime->oss.period_bytes;
 			info.bytes = (runtime->oss.bytes + delay) & INT_MAX;
+		}
 	}
 	if (copy_to_user(_info, &info, sizeof(info)))
 		return -EFAULT;
@@ -2347,7 +2361,7 @@ static void snd_pcm_oss_proc_write(snd_i
 					for (setup1 = pstr->oss.setup_list; setup1->next; setup1 = setup1->next);
 					setup1->next = setup;
 				}
-				template.task_name = snd_kmalloc_strdup(task_name, GFP_KERNEL);
+				template.task_name = kstrdup(task_name, GFP_KERNEL);
 			} else {
 				buffer->error = -ENOMEM;
 			}
diff --git a/sound/core/oss/pcm_plugin.c b/sound/core/oss/pcm_plugin.c
--- a/sound/core/oss/pcm_plugin.c
+++ b/sound/core/oss/pcm_plugin.c
@@ -663,10 +663,7 @@ static int snd_pcm_plug_playback_channel
 		bitset_t *dstmask = bs;
 		int err;
 		bitset_one(dstmask, schannels);
-		if (plugin == NULL) {
-			bitset_and(client_vmask, dstmask, schannels);
-			return 0;
-		}
+
 		while (1) {
 			err = plugin->src_channels_mask(plugin, dstmask, &srcmask);
 			if (err < 0)
diff --git a/sound/core/pcm.c b/sound/core/pcm.c
--- a/sound/core/pcm.c
+++ b/sound/core/pcm.c
@@ -451,6 +451,7 @@ static int snd_pcm_stream_proc_init(snd_
 		entry->c.text.read = snd_pcm_xrun_debug_read;
 		entry->c.text.write_size = 64;
 		entry->c.text.write = snd_pcm_xrun_debug_write;
+		entry->mode |= S_IWUSR;
 		entry->private_data = pstr;
 		if (snd_info_register(entry) < 0) {
 			snd_info_free_entry(entry);
@@ -1048,7 +1049,6 @@ EXPORT_SYMBOL(snd_pcm_release_substream)
 EXPORT_SYMBOL(snd_pcm_format_name);
   /* pcm_native.c */
 EXPORT_SYMBOL(snd_pcm_link_rwlock);
-EXPORT_SYMBOL(snd_pcm_start);
 #ifdef CONFIG_PM
 EXPORT_SYMBOL(snd_pcm_suspend);
 EXPORT_SYMBOL(snd_pcm_suspend_all);
@@ -1068,6 +1068,7 @@ EXPORT_SYMBOL(snd_pcm_format_little_endi
 EXPORT_SYMBOL(snd_pcm_format_big_endian);
 EXPORT_SYMBOL(snd_pcm_format_width);
 EXPORT_SYMBOL(snd_pcm_format_physical_width);
+EXPORT_SYMBOL(snd_pcm_format_size);
 EXPORT_SYMBOL(snd_pcm_format_silence_64);
 EXPORT_SYMBOL(snd_pcm_format_set_silence);
 EXPORT_SYMBOL(snd_pcm_build_linear_format);
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -1143,7 +1143,8 @@ int snd_pcm_hw_constraint_pow2(snd_pcm_r
 #define INT_MIN ((int)((unsigned int)INT_MAX+1))
 #endif
 
-void _snd_pcm_hw_param_any(snd_pcm_hw_params_t *params, snd_pcm_hw_param_t var)
+static void _snd_pcm_hw_param_any(snd_pcm_hw_params_t *params,
+				  snd_pcm_hw_param_t var)
 {
 	if (hw_is_mask(var)) {
 		snd_mask_any(hw_param_mask(params, var));
@@ -1160,6 +1161,7 @@ void _snd_pcm_hw_param_any(snd_pcm_hw_pa
 	snd_BUG();
 }
 
+#if 0
 /**
  * snd_pcm_hw_param_any
  */
@@ -1169,6 +1171,7 @@ int snd_pcm_hw_param_any(snd_pcm_t *pcm,
 	_snd_pcm_hw_param_any(params, var);
 	return snd_pcm_hw_refine(pcm, params);
 }
+#endif  /*  0  */
 
 void _snd_pcm_hw_params_any(snd_pcm_hw_params_t *params)
 {
@@ -1181,6 +1184,7 @@ void _snd_pcm_hw_params_any(snd_pcm_hw_p
 	params->info = ~0U;
 }
 
+#if 0
 /**
  * snd_pcm_hw_params_any
  *
@@ -1191,6 +1195,7 @@ int snd_pcm_hw_params_any(snd_pcm_t *pcm
 	_snd_pcm_hw_params_any(params);
 	return snd_pcm_hw_refine(pcm, params);
 }
+#endif  /*  0  */
 
 /**
  * snd_pcm_hw_param_value
@@ -1198,8 +1203,8 @@ int snd_pcm_hw_params_any(snd_pcm_t *pcm
  * Return the value for field PAR if it's fixed in configuration space 
  *  defined by PARAMS. Return -EINVAL otherwise
  */
-int snd_pcm_hw_param_value(const snd_pcm_hw_params_t *params,
-			   snd_pcm_hw_param_t var, int *dir)
+static int snd_pcm_hw_param_value(const snd_pcm_hw_params_t *params,
+				  snd_pcm_hw_param_t var, int *dir)
 {
 	if (hw_is_mask(var)) {
 		const snd_mask_t *mask = hw_param_mask_c(params, var);
@@ -1296,6 +1301,7 @@ int _snd_pcm_hw_param_setinteger(snd_pcm
 	return changed;
 }
 	
+#if 0
 /**
  * snd_pcm_hw_param_setinteger
  *
@@ -1317,9 +1323,10 @@ int snd_pcm_hw_param_setinteger(snd_pcm_
 	}
 	return 0;
 }
+#endif  /*  0  */
 
-int _snd_pcm_hw_param_first(snd_pcm_hw_params_t *params,
-			    snd_pcm_hw_param_t var)
+static int _snd_pcm_hw_param_first(snd_pcm_hw_params_t *params,
+				   snd_pcm_hw_param_t var)
 {
 	int changed;
 	if (hw_is_mask(var))
@@ -1345,9 +1352,9 @@ int _snd_pcm_hw_param_first(snd_pcm_hw_p
  * values > minimum. Reduce configuration space accordingly.
  * Return the minimum.
  */
-int snd_pcm_hw_param_first(snd_pcm_t *pcm, 
-			   snd_pcm_hw_params_t *params, 
-			   snd_pcm_hw_param_t var, int *dir)
+static int snd_pcm_hw_param_first(snd_pcm_t *pcm, 
+				  snd_pcm_hw_params_t *params, 
+				  snd_pcm_hw_param_t var, int *dir)
 {
 	int changed = _snd_pcm_hw_param_first(params, var);
 	if (changed < 0)
@@ -1359,8 +1366,8 @@ int snd_pcm_hw_param_first(snd_pcm_t *pc
 	return snd_pcm_hw_param_value(params, var, dir);
 }
 
-int _snd_pcm_hw_param_last(snd_pcm_hw_params_t *params,
-			   snd_pcm_hw_param_t var)
+static int _snd_pcm_hw_param_last(snd_pcm_hw_params_t *params,
+				  snd_pcm_hw_param_t var)
 {
 	int changed;
 	if (hw_is_mask(var))
@@ -1386,9 +1393,9 @@ int _snd_pcm_hw_param_last(snd_pcm_hw_pa
  * values < maximum. Reduce configuration space accordingly.
  * Return the maximum.
  */
-int snd_pcm_hw_param_last(snd_pcm_t *pcm, 
-			  snd_pcm_hw_params_t *params,
-			  snd_pcm_hw_param_t var, int *dir)
+static int snd_pcm_hw_param_last(snd_pcm_t *pcm, 
+				 snd_pcm_hw_params_t *params,
+				 snd_pcm_hw_param_t var, int *dir)
 {
 	int changed = _snd_pcm_hw_param_last(params, var);
 	if (changed < 0)
@@ -1437,8 +1444,9 @@ int _snd_pcm_hw_param_min(snd_pcm_hw_par
  * values < VAL. Reduce configuration space accordingly.
  * Return new minimum or -EINVAL if the configuration space is empty
  */
-int snd_pcm_hw_param_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
-			 snd_pcm_hw_param_t var, unsigned int val, int *dir)
+static int snd_pcm_hw_param_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
+				snd_pcm_hw_param_t var, unsigned int val,
+				int *dir)
 {
 	int changed = _snd_pcm_hw_param_min(params, var, val, dir ? *dir : 0);
 	if (changed < 0)
@@ -1451,8 +1459,9 @@ int snd_pcm_hw_param_min(snd_pcm_t *pcm,
 	return snd_pcm_hw_param_value_min(params, var, dir);
 }
 
-int _snd_pcm_hw_param_max(snd_pcm_hw_params_t *params,
-			   snd_pcm_hw_param_t var, unsigned int val, int dir)
+static int _snd_pcm_hw_param_max(snd_pcm_hw_params_t *params,
+				 snd_pcm_hw_param_t var, unsigned int val,
+				 int dir)
 {
 	int changed;
 	int open = 0;
@@ -1490,8 +1499,9 @@ int _snd_pcm_hw_param_max(snd_pcm_hw_par
  *  values >= VAL + 1. Reduce configuration space accordingly.
  *  Return new maximum or -EINVAL if the configuration space is empty
  */
-int snd_pcm_hw_param_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
-			  snd_pcm_hw_param_t var, unsigned int val, int *dir)
+static int snd_pcm_hw_param_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
+				snd_pcm_hw_param_t var, unsigned int val,
+				int *dir)
 {
 	int changed = _snd_pcm_hw_param_max(params, var, val, dir ? *dir : 0);
 	if (changed < 0)
@@ -2564,9 +2574,6 @@ snd_pcm_sframes_t snd_pcm_lib_readv(snd_
 EXPORT_SYMBOL(snd_interval_refine);
 EXPORT_SYMBOL(snd_interval_list);
 EXPORT_SYMBOL(snd_interval_ratnum);
-EXPORT_SYMBOL(snd_interval_muldivk);
-EXPORT_SYMBOL(snd_interval_mulkdiv);
-EXPORT_SYMBOL(snd_interval_div);
 EXPORT_SYMBOL(_snd_pcm_hw_params_any);
 EXPORT_SYMBOL(_snd_pcm_hw_param_min);
 EXPORT_SYMBOL(_snd_pcm_hw_param_set);
@@ -2580,7 +2587,6 @@ EXPORT_SYMBOL(snd_pcm_hw_param_last);
 EXPORT_SYMBOL(snd_pcm_hw_param_near);
 EXPORT_SYMBOL(snd_pcm_hw_param_set);
 EXPORT_SYMBOL(snd_pcm_hw_refine);
-EXPORT_SYMBOL(snd_pcm_hw_params);
 EXPORT_SYMBOL(snd_pcm_hw_constraints_init);
 EXPORT_SYMBOL(snd_pcm_hw_constraints_complete);
 EXPORT_SYMBOL(snd_pcm_hw_constraint_list);
diff --git a/sound/core/pcm_memory.c b/sound/core/pcm_memory.c
--- a/sound/core/pcm_memory.c
+++ b/sound/core/pcm_memory.c
@@ -204,6 +204,7 @@ static int snd_pcm_lib_preallocate_pages
 		entry->c.text.read = snd_pcm_lib_preallocate_proc_read;
 		entry->c.text.write_size = 64;
 		entry->c.text.write = snd_pcm_lib_preallocate_proc_write;
+		entry->mode |= S_IWUSR;
 		entry->private_data = substream;
 		if (snd_info_register(entry) < 0) {
 			snd_info_free_entry(entry);
diff --git a/sound/core/pcm_misc.c b/sound/core/pcm_misc.c
--- a/sound/core/pcm_misc.c
+++ b/sound/core/pcm_misc.c
@@ -270,22 +270,6 @@ int snd_pcm_format_big_endian(snd_pcm_fo
 }
 
 /**
- * snd_pcm_format_cpu_endian - Check the PCM format is CPU-endian
- * @format: the format to check
- *
- * Returns 1 if the given PCM format is CPU-endian, 0 if
- * opposite, or a negative error code if endian not specified.
- */
-int snd_pcm_format_cpu_endian(snd_pcm_format_t format)
-{
-#ifdef SNDRV_LITTLE_ENDIAN
-	return snd_pcm_format_little_endian(format);
-#else
-	return snd_pcm_format_big_endian(format);
-#endif
-}
-
-/**
  * snd_pcm_format_width - return the bit-width of the format
  * @format: the format to check
  *
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -337,8 +337,8 @@ out:
 	return err;
 }
 
-int snd_pcm_hw_params(snd_pcm_substream_t *substream,
-		      snd_pcm_hw_params_t *params)
+static int snd_pcm_hw_params(snd_pcm_substream_t *substream,
+			     snd_pcm_hw_params_t *params)
 {
 	snd_pcm_runtime_t *runtime;
 	int err;
@@ -1368,43 +1368,32 @@ static int snd_pcm_drain(snd_pcm_substre
 	if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
 		return -EBADFD;
 
-	down_read(&snd_pcm_link_rwsem);
 	snd_power_lock(card);
 	if (runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) {
 		result = snd_power_wait(card, SNDRV_CTL_POWER_D0, substream->ffile);
-		if (result < 0)
-			goto _unlock;
+		if (result < 0) {
+			snd_power_unlock(card);
+			return result;
+		}
 	}
 
 	/* allocate temporary record for drain sync */
+	down_read(&snd_pcm_link_rwsem);
 	if (snd_pcm_stream_linked(substream)) {
 		drec = kmalloc(substream->group->count * sizeof(*drec), GFP_KERNEL);
 		if (! drec) {
-			result = -ENOMEM;
-			goto _unlock;
+			up_read(&snd_pcm_link_rwsem);
+			snd_power_unlock(card);
+			return -ENOMEM;
 		}
 	} else
 		drec = &drec_tmp;
 
-	snd_pcm_stream_lock_irq(substream);
-	/* resume pause */
-	if (runtime->status->state == SNDRV_PCM_STATE_PAUSED)
-		snd_pcm_pause(substream, 0);
-
-	/* pre-start/stop - all running streams are changed to DRAINING state */
-	result = snd_pcm_action(&snd_pcm_action_drain_init, substream, 0);
-	if (result < 0)
-		goto _end;
-
-	/* check streams with PLAYBACK & DRAINING */
+	/* count only playback streams */
 	num_drecs = 0;
 	snd_pcm_group_for_each(pos, substream) {
 		snd_pcm_substream_t *s = snd_pcm_group_substream_entry(pos);
 		runtime = s->runtime;
-		if (runtime->status->state != SNDRV_PCM_STATE_DRAINING) {
-			runtime->status->state = SNDRV_PCM_STATE_SETUP;
-			continue;
-		}
 		if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) {
 			d = &drec[num_drecs++];
 			d->substream = s;
@@ -1418,9 +1407,21 @@ static int snd_pcm_drain(snd_pcm_substre
 				runtime->stop_threshold = runtime->buffer_size;
 		}
 	}
-
+	up_read(&snd_pcm_link_rwsem);
 	if (! num_drecs)
-		goto _end;
+		goto _error;
+
+	snd_pcm_stream_lock_irq(substream);
+	/* resume pause */
+	if (runtime->status->state == SNDRV_PCM_STATE_PAUSED)
+		snd_pcm_pause(substream, 0);
+
+	/* pre-start/stop - all running streams are changed to DRAINING state */
+	result = snd_pcm_action(&snd_pcm_action_drain_init, substream, 0);
+	if (result < 0) {
+		snd_pcm_stream_unlock_irq(substream);
+		goto _error;
+	}
 
 	for (;;) {
 		long tout;
@@ -1428,6 +1429,15 @@ static int snd_pcm_drain(snd_pcm_substre
 			result = -ERESTARTSYS;
 			break;
 		}
+		/* all finished? */
+		for (i = 0; i < num_drecs; i++) {
+			runtime = drec[i].substream->runtime;
+			if (runtime->status->state == SNDRV_PCM_STATE_DRAINING)
+				break;
+		}
+		if (i == num_drecs)
+			break; /* yes, all drained */
+
 		set_current_state(TASK_INTERRUPTIBLE);
 		snd_pcm_stream_unlock_irq(substream);
 		snd_power_unlock(card);
@@ -1444,15 +1454,11 @@ static int snd_pcm_drain(snd_pcm_substre
 			}
 			break;
 		}
-		/* all finished? */
-		for (i = 0; i < num_drecs; i++) {
-			runtime = drec[i].substream->runtime;
-			if (runtime->status->state == SNDRV_PCM_STATE_DRAINING)
-				break;
-		}
-		if (i == num_drecs)
-			break;
 	}
+
+	snd_pcm_stream_unlock_irq(substream);
+
+ _error:
 	for (i = 0; i < num_drecs; i++) {
 		d = &drec[i];
 		runtime = d->substream->runtime;
@@ -1460,13 +1466,9 @@ static int snd_pcm_drain(snd_pcm_substre
 		runtime->stop_threshold = d->stop_threshold;
 	}
 
- _end:
-	snd_pcm_stream_unlock_irq(substream);
 	if (drec != &drec_tmp)
 		kfree(drec);
- _unlock:
 	snd_power_unlock(card);
-	up_read(&snd_pcm_link_rwsem);
 
 	return result;
 }
diff --git a/sound/core/seq/Makefile b/sound/core/seq/Makefile
--- a/sound/core/seq/Makefile
+++ b/sound/core/seq/Makefile
@@ -38,7 +38,7 @@ obj-$(CONFIG_SND_VIRMIDI) += snd-seq-vir
 obj-$(call sequencer,$(CONFIG_SND_RAWMIDI)) += snd-seq-midi.o snd-seq-midi-event.o
 obj-$(call sequencer,$(CONFIG_SND_OPL3_LIB)) += snd-seq-midi-event.o snd-seq-midi-emul.o snd-seq-instr.o
 obj-$(call sequencer,$(CONFIG_SND_OPL4_LIB)) += snd-seq-midi-event.o snd-seq-midi-emul.o snd-seq-instr.o
-obj-$(call sequencer,$(CONFIG_SND_GUS_SYNTH)) += snd-seq-instr.o
+obj-$(call sequencer,$(CONFIG_SND_GUS_SYNTH)) += snd-seq-midi-emul.o snd-seq-instr.o
 obj-$(call sequencer,$(CONFIG_SND_SBAWE)) += snd-seq-midi-emul.o snd-seq-virmidi.o
 obj-$(call sequencer,$(CONFIG_SND_EMU10K1)) += snd-seq-midi-emul.o snd-seq-virmidi.o
 obj-$(call sequencer,$(CONFIG_SND_TRIDENT)) += snd-seq-midi-emul.o snd-seq-instr.o
diff --git a/sound/core/seq/instr/ainstr_gf1.c b/sound/core/seq/instr/ainstr_gf1.c
--- a/sound/core/seq/instr/ainstr_gf1.c
+++ b/sound/core/seq/instr/ainstr_gf1.c
@@ -50,7 +50,8 @@ static int snd_seq_gf1_copy_wave_from_st
 {
 	gf1_wave_t *wp, *prev;
 	gf1_xwave_t xp;
-	int err, gfp_mask;
+	int err;
+	unsigned int gfp_mask;
 	unsigned int real_size;
 	
 	gfp_mask = atomic ? GFP_ATOMIC : GFP_KERNEL;
diff --git a/sound/core/seq/instr/ainstr_iw.c b/sound/core/seq/instr/ainstr_iw.c
--- a/sound/core/seq/instr/ainstr_iw.c
+++ b/sound/core/seq/instr/ainstr_iw.c
@@ -58,7 +58,7 @@ static int snd_seq_iwffff_copy_env_from_
 					       iwffff_xenv_t *ex,
 					       char __user **data,
 					       long *len,
-					       int gfp_mask)
+					       unsigned int __nocast gfp_mask)
 {
 	__u32 stype;
 	iwffff_env_record_t *rp, *rp_last;
@@ -128,7 +128,8 @@ static int snd_seq_iwffff_copy_wave_from
 {
 	iwffff_wave_t *wp, *prev;
 	iwffff_xwave_t xp;
-	int err, gfp_mask;
+	int err;
+	unsigned int gfp_mask;
 	unsigned int real_size;
 	
 	gfp_mask = atomic ? GFP_ATOMIC : GFP_KERNEL;
@@ -234,7 +235,8 @@ static int snd_seq_iwffff_put(void *priv
 	iwffff_xinstrument_t ix;
 	iwffff_layer_t *lp, *prev_lp;
 	iwffff_xlayer_t lx;
-	int err, gfp_mask;
+	int err;
+	unsigned int gfp_mask;
 
 	if (cmd != SNDRV_SEQ_INSTR_PUT_CMD_CREATE)
 		return -EINVAL;
diff --git a/sound/core/seq/oss/seq_oss_device.h b/sound/core/seq/oss/seq_oss_device.h
--- a/sound/core/seq/oss/seq_oss_device.h
+++ b/sound/core/seq/oss/seq_oss_device.h
@@ -158,21 +158,21 @@ void snd_seq_oss_readq_info_read(seq_oss
 #define is_nonblock_mode(mode)	((mode) & SNDRV_SEQ_OSS_FILE_NONBLOCK)
 
 /* dispatch event */
-inline static int
+static inline int
 snd_seq_oss_dispatch(seq_oss_devinfo_t *dp, snd_seq_event_t *ev, int atomic, int hop)
 {
 	return snd_seq_kernel_client_dispatch(dp->cseq, ev, atomic, hop);
 }
 
 /* ioctl */
-inline static int
+static inline int
 snd_seq_oss_control(seq_oss_devinfo_t *dp, unsigned int type, void *arg)
 {
 	return snd_seq_kernel_client_ctl(dp->cseq, type, arg);
 }
 
 /* fill the addresses in header */
-inline static void
+static inline void
 snd_seq_oss_fill_addr(seq_oss_devinfo_t *dp, snd_seq_event_t *ev,
 		     int dest_client, int dest_port)
 {
diff --git a/sound/core/seq/oss/seq_oss_synth.c b/sound/core/seq/oss/seq_oss_synth.c
--- a/sound/core/seq/oss/seq_oss_synth.c
+++ b/sound/core/seq/oss/seq_oss_synth.c
@@ -325,14 +325,10 @@ snd_seq_oss_synth_cleanup(seq_oss_devinf
 			}
 			snd_use_lock_free(&rec->use_lock);
 		}
-		if (info->sysex) {
-			kfree(info->sysex);
-			info->sysex = NULL;
-		}
-		if (info->ch) {
-			kfree(info->ch);
-			info->ch = NULL;
-		}
+		kfree(info->sysex);
+		info->sysex = NULL;
+		kfree(info->ch);
+		info->ch = NULL;
 	}
 	dp->synth_opened = 0;
 	dp->max_synthdev = 0;
@@ -418,14 +414,10 @@ snd_seq_oss_synth_reset(seq_oss_devinfo_
 					  dp->file_mode) < 0) {
 			midi_synth_dev.opened--;
 			info->opened = 0;
-			if (info->sysex) {
-				kfree(info->sysex);
-				info->sysex = NULL;
-			}
-			if (info->ch) {
-				kfree(info->ch);
-				info->ch = NULL;
-			}
+			kfree(info->sysex);
+			info->sysex = NULL;
+			kfree(info->ch);
+			info->ch = NULL;
 		}
 		return;
 	}
diff --git a/sound/core/seq/seq_dummy.c b/sound/core/seq/seq_dummy.c
--- a/sound/core/seq/seq_dummy.c
+++ b/sound/core/seq/seq_dummy.c
@@ -140,10 +140,7 @@ dummy_input(snd_seq_event_t *ev, int dir
 static void
 dummy_free(void *private_data)
 {
-	snd_seq_dummy_port_t *p;
-
-	p = private_data;
-	kfree(p);
+	kfree(private_data);
 }
 
 /*
diff --git a/sound/core/seq/seq_memory.c b/sound/core/seq/seq_memory.c
--- a/sound/core/seq/seq_memory.c
+++ b/sound/core/seq/seq_memory.c
@@ -36,12 +36,12 @@
 #define semaphore_of(fp)	((fp)->f_dentry->d_inode->i_sem)
 
 
-inline static int snd_seq_pool_available(pool_t *pool)
+static inline int snd_seq_pool_available(pool_t *pool)
 {
 	return pool->total_elements - atomic_read(&pool->counter);
 }
 
-inline static int snd_seq_output_ok(pool_t *pool)
+static inline int snd_seq_output_ok(pool_t *pool)
 {
 	return snd_seq_pool_available(pool) >= pool->room;
 }
diff --git a/sound/core/seq/seq_midi.c b/sound/core/seq/seq_midi.c
--- a/sound/core/seq/seq_midi.c
+++ b/sound/core/seq/seq_midi.c
@@ -134,7 +134,7 @@ static int event_process_midi(snd_seq_ev
 	seq_midisynth_t *msynth = (seq_midisynth_t *) private_data;
 	unsigned char msg[10];	/* buffer for constructing midi messages */
 	snd_rawmidi_substream_t *substream;
-	int res;
+	int len;
 
 	snd_assert(msynth != NULL, return -EINVAL);
 	substream = msynth->output_rfile.output;
@@ -146,20 +146,16 @@ static int event_process_midi(snd_seq_ev
 			snd_printd("seq_midi: invalid sysex event flags = 0x%x\n", ev->flags);
 			return 0;
 		}
-		res = snd_seq_dump_var_event(ev, (snd_seq_dump_func_t)dump_midi, substream);
+		snd_seq_dump_var_event(ev, (snd_seq_dump_func_t)dump_midi, substream);
 		snd_midi_event_reset_decode(msynth->parser);
-		if (res < 0)
-			return res;
 	} else {
 		if (msynth->parser == NULL)
 			return -EIO;
-		res = snd_midi_event_decode(msynth->parser, msg, sizeof(msg), ev);
-		if (res < 0)
-			return res;
-		if ((res = dump_midi(substream, msg, res)) < 0) {
+		len = snd_midi_event_decode(msynth->parser, msg, sizeof(msg), ev);
+		if (len < 0)
+			return 0;
+		if (dump_midi(substream, msg, len) < 0)
 			snd_midi_event_reset_decode(msynth->parser);
-			return res;
-		}
 	}
 	return 0;
 }
@@ -414,6 +410,8 @@ snd_seq_midisynth_register_port(snd_seq_
 	if (newclient)
 		synths[card->number] = client;
 	up(&register_mutex);
+	kfree(info);
+	kfree(port);
 	return 0;	/* success */
 
       __nomem:
diff --git a/sound/core/seq/seq_midi_event.c b/sound/core/seq/seq_midi_event.c
--- a/sound/core/seq/seq_midi_event.c
+++ b/sound/core/seq/seq_midi_event.c
@@ -146,7 +146,7 @@ void snd_midi_event_free(snd_midi_event_
 /*
  * initialize record
  */
-inline static void reset_encode(snd_midi_event_t *dev)
+static inline void reset_encode(snd_midi_event_t *dev)
 {
 	dev->read = 0;
 	dev->qlen = 0;
@@ -171,11 +171,13 @@ void snd_midi_event_reset_decode(snd_mid
 	spin_unlock_irqrestore(&dev->lock, flags);
 }
 
+#if 0
 void snd_midi_event_init(snd_midi_event_t *dev)
 {
 	snd_midi_event_reset_encode(dev);
 	snd_midi_event_reset_decode(dev);
 }
+#endif  /*  0  */
 
 void snd_midi_event_no_status(snd_midi_event_t *dev, int on)
 {
@@ -185,6 +187,7 @@ void snd_midi_event_no_status(snd_midi_e
 /*
  * resize buffer
  */
+#if 0
 int snd_midi_event_resize_buffer(snd_midi_event_t *dev, int bufsize)
 {
 	unsigned char *new_buf, *old_buf;
@@ -204,6 +207,7 @@ int snd_midi_event_resize_buffer(snd_mid
 	kfree(old_buf);
 	return 0;
 }
+#endif  /*  0  */
 
 /*
  *  read bytes and encode to sequencer event if finished
@@ -517,8 +521,6 @@ static int extra_decode_xrpn(snd_midi_ev
  
 EXPORT_SYMBOL(snd_midi_event_new);
 EXPORT_SYMBOL(snd_midi_event_free);
-EXPORT_SYMBOL(snd_midi_event_resize_buffer);
-EXPORT_SYMBOL(snd_midi_event_init);
 EXPORT_SYMBOL(snd_midi_event_reset_encode);
 EXPORT_SYMBOL(snd_midi_event_reset_decode);
 EXPORT_SYMBOL(snd_midi_event_no_status);
diff --git a/sound/core/seq/seq_queue.c b/sound/core/seq/seq_queue.c
--- a/sound/core/seq/seq_queue.c
+++ b/sound/core/seq/seq_queue.c
@@ -672,7 +672,8 @@ static void queue_broadcast_event(queue_
  * process a received queue-control event.
  * this function is exported for seq_sync.c.
  */
-void snd_seq_queue_process_event(queue_t *q, snd_seq_event_t *ev, int atomic, int hop)
+static void snd_seq_queue_process_event(queue_t *q, snd_seq_event_t *ev,
+					int atomic, int hop)
 {
 	switch (ev->type) {
 	case SNDRV_SEQ_EVENT_START:
diff --git a/sound/core/seq/seq_queue.h b/sound/core/seq/seq_queue.h
--- a/sound/core/seq/seq_queue.h
+++ b/sound/core/seq/seq_queue.h
@@ -111,7 +111,6 @@ int snd_seq_queue_use(int queueid, int c
 int snd_seq_queue_is_used(int queueid, int client);
 
 int snd_seq_control_queue(snd_seq_event_t *ev, int atomic, int hop);
-void snd_seq_queue_process_event(queue_t *q, snd_seq_event_t *ev, int atomic, int hop);
 
 /*
  * 64bit division - for sync stuff..
diff --git a/sound/core/seq/seq_timer.c b/sound/core/seq/seq_timer.c
--- a/sound/core/seq/seq_timer.c
+++ b/sound/core/seq/seq_timer.c
@@ -36,7 +36,8 @@ extern int seq_default_timer_resolution;
 
 #define SKEW_BASE	0x10000	/* 16bit shift */
 
-void snd_seq_timer_set_tick_resolution(seq_timer_tick_t *tick, int tempo, int ppq, int nticks)
+static void snd_seq_timer_set_tick_resolution(seq_timer_tick_t *tick,
+					      int tempo, int ppq, int nticks)
 {
 	if (tempo < 1000000)
 		tick->resolution = (tempo * 1000) / ppq;
diff --git a/sound/core/seq/seq_timer.h b/sound/core/seq/seq_timer.h
--- a/sound/core/seq/seq_timer.h
+++ b/sound/core/seq/seq_timer.h
@@ -64,8 +64,6 @@ extern seq_timer_t *snd_seq_timer_new(vo
 /* delete timer (destructor) */
 extern void snd_seq_timer_delete(seq_timer_t **tmr);
 
-void snd_seq_timer_set_tick_resolution(seq_timer_tick_t *tick, int tempo, int ppq, int nticks);
-
 /* */
 static inline void snd_seq_timer_update_tick(seq_timer_tick_t *tick, unsigned long resolution)
 {
diff --git a/sound/core/seq/seq_virmidi.c b/sound/core/seq/seq_virmidi.c
--- a/sound/core/seq/seq_virmidi.c
+++ b/sound/core/seq/seq_virmidi.c
@@ -110,7 +110,7 @@ static int snd_virmidi_dev_receive_event
  * handler of a remote port which is attached to the virmidi via
  * SNDRV_VIRMIDI_SEQ_ATTACH.
  */
-/* exported */
+#if 0
 int snd_virmidi_receive(snd_rawmidi_t *rmidi, snd_seq_event_t *ev)
 {
 	snd_virmidi_dev_t *rdev;
@@ -118,6 +118,7 @@ int snd_virmidi_receive(snd_rawmidi_t *r
 	rdev = rmidi->private_data;
 	return snd_virmidi_dev_receive_event(rdev, ev);
 }
+#endif  /*  0  */
 
 /*
  * event handler of virmidi port
@@ -384,7 +385,7 @@ static int snd_virmidi_dev_attach_seq(sn
 	info->client = client;
 	info->type = KERNEL_CLIENT;
 	sprintf(info->name, "%s %d-%d", rdev->rmidi->name, rdev->card->number, rdev->device);
-	snd_seq_kernel_client_ctl(client, SNDRV_SEQ_IOCTL_SET_CLIENT_INFO, &info);
+	snd_seq_kernel_client_ctl(client, SNDRV_SEQ_IOCTL_SET_CLIENT_INFO, info);
 
 	/* create a port */
 	memset(pinfo, 0, sizeof(*pinfo));
@@ -405,7 +406,7 @@ static int snd_virmidi_dev_attach_seq(sn
 	pcallbacks.unuse = snd_virmidi_unuse;
 	pcallbacks.event_input = snd_virmidi_event_input;
 	pinfo->kernel = &pcallbacks;
-	err = snd_seq_kernel_client_ctl(client, SNDRV_SEQ_IOCTL_CREATE_PORT, &pinfo);
+	err = snd_seq_kernel_client_ctl(client, SNDRV_SEQ_IOCTL_CREATE_PORT, pinfo);
 	if (err < 0) {
 		snd_seq_delete_kernel_client(client);
 		rdev->client = -1;
@@ -548,4 +549,3 @@ module_init(alsa_virmidi_init)
 module_exit(alsa_virmidi_exit)
 
 EXPORT_SYMBOL(snd_virmidi_new);
-EXPORT_SYMBOL(snd_virmidi_receive);
diff --git a/sound/core/sound.c b/sound/core/sound.c
--- a/sound/core/sound.c
+++ b/sound/core/sound.c
@@ -64,7 +64,7 @@ static struct list_head snd_minors_hash[
 
 static DECLARE_MUTEX(sound_mutex);
 
-extern struct class_simple *sound_class;
+extern struct class *sound_class;
 
 
 #ifdef CONFIG_KMOD
@@ -231,7 +231,7 @@ int snd_register_device(int type, snd_ca
 		devfs_mk_cdev(MKDEV(major, minor), S_IFCHR | device_mode, "snd/%s", name);
 	if (card)
 		device = card->dev;
-	class_simple_device_add(sound_class, MKDEV(major, minor), device, name);
+	class_device_create(sound_class, MKDEV(major, minor), device, "%s", name);
 
 	up(&sound_mutex);
 	return 0;
@@ -263,7 +263,7 @@ int snd_unregister_device(int type, snd_
 
 	if (strncmp(mptr->name, "controlC", 8) || card->number >= cards_limit) /* created in sound.c */
 		devfs_remove("snd/%s", mptr->name);
-	class_simple_device_remove(MKDEV(major, minor));
+	class_device_destroy(sound_class, MKDEV(major, minor));
 
 	list_del(&mptr->list);
 	up(&sound_mutex);
@@ -399,8 +399,8 @@ EXPORT_SYMBOL(snd_hidden_kcalloc);
 EXPORT_SYMBOL(snd_hidden_kfree);
 EXPORT_SYMBOL(snd_hidden_vmalloc);
 EXPORT_SYMBOL(snd_hidden_vfree);
+EXPORT_SYMBOL(snd_hidden_kstrdup);
 #endif
-EXPORT_SYMBOL(snd_kmalloc_strdup);
 EXPORT_SYMBOL(copy_to_user_fromio);
 EXPORT_SYMBOL(copy_from_user_toio);
   /* init.c */
@@ -431,9 +431,8 @@ EXPORT_SYMBOL(snd_card_pci_resume);
 EXPORT_SYMBOL(snd_device_new);
 EXPORT_SYMBOL(snd_device_register);
 EXPORT_SYMBOL(snd_device_free);
-EXPORT_SYMBOL(snd_device_free_all);
   /* isadma.c */
-#ifdef CONFIG_ISA
+#ifdef CONFIG_ISA_DMA_API
 EXPORT_SYMBOL(snd_dma_program);
 EXPORT_SYMBOL(snd_dma_disable);
 EXPORT_SYMBOL(snd_dma_pointer);
diff --git a/sound/core/timer.c b/sound/core/timer.c
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -26,6 +26,7 @@
 #include <linux/slab.h>
 #include <linux/time.h>
 #include <linux/moduleparam.h>
+#include <linux/string.h>
 #include <sound/core.h>
 #include <sound/timer.h>
 #include <sound/control.h>
@@ -69,6 +70,7 @@ typedef struct {
 	struct timespec tstamp;		/* trigger tstamp */
 	wait_queue_head_t qchange_sleep;
 	struct fasync_struct *fasync;
+	struct semaphore tread_sem;
 } snd_timer_user_t;
 
 /* list of timers */
@@ -99,7 +101,7 @@ static snd_timer_instance_t *snd_timer_i
 	timeri = kcalloc(1, sizeof(*timeri), GFP_KERNEL);
 	if (timeri == NULL)
 		return NULL;
-	timeri->owner = snd_kmalloc_strdup(owner, GFP_KERNEL);
+	timeri->owner = kstrdup(owner, GFP_KERNEL);
 	if (! timeri->owner) {
 		kfree(timeri);
 		return NULL;
@@ -844,7 +846,7 @@ int snd_timer_dev_register(snd_device_t 
 	return 0;
 }
 
-int snd_timer_unregister(snd_timer_t *timer)
+static int snd_timer_unregister(snd_timer_t *timer)
 {
 	struct list_head *p, *n;
 	snd_timer_instance_t *ti;
@@ -945,11 +947,6 @@ struct snd_timer_system_private {
 	unsigned long correction;
 };
 
-unsigned int snd_timer_system_resolution(void)
-{
-	return 1000000000L / HZ;
-}
-
 static void snd_timer_s_function(unsigned long data)
 {
 	snd_timer_t *timer = (snd_timer_t *)data;
@@ -1208,6 +1205,7 @@ static int snd_timer_user_open(struct in
 		return -ENOMEM;
 	spin_lock_init(&tu->qlock);
 	init_waitqueue_head(&tu->qchange_sleep);
+	init_MUTEX(&tu->tread_sem);
 	tu->ticks = 1;
 	tu->queue_size = 128;
 	tu->queue = (snd_timer_read_t *)kmalloc(tu->queue_size * sizeof(snd_timer_read_t), GFP_KERNEL);
@@ -1454,46 +1452,51 @@ static int snd_timer_user_tselect(struct
 	snd_timer_user_t *tu;
 	snd_timer_select_t tselect;
 	char str[32];
-	int err;
+	int err = 0;
 	
 	tu = file->private_data;
-	if (tu->timeri)
+	down(&tu->tread_sem);
+	if (tu->timeri) {
 		snd_timer_close(tu->timeri);
-	if (copy_from_user(&tselect, _tselect, sizeof(tselect)))
-		return -EFAULT;
+		tu->timeri = NULL;
+	}
+	if (copy_from_user(&tselect, _tselect, sizeof(tselect))) {
+		err = -EFAULT;
+		goto __err;
+	}
 	sprintf(str, "application %i", current->pid);
 	if (tselect.id.dev_class != SNDRV_TIMER_CLASS_SLAVE)
 		tselect.id.dev_sclass = SNDRV_TIMER_SCLASS_APPLICATION;
 	if ((err = snd_timer_open(&tu->timeri, str, &tselect.id, current->pid)) < 0)
-		return err;
+		goto __err;
 
-	if (tu->queue) {
-		kfree(tu->queue);
-		tu->queue = NULL;
-	}
-	if (tu->tqueue) {
-		kfree(tu->tqueue);
-		tu->tqueue = NULL;
-	}
+	kfree(tu->queue);
+	tu->queue = NULL;
+	kfree(tu->tqueue);
+	tu->tqueue = NULL;
 	if (tu->tread) {
 		tu->tqueue = (snd_timer_tread_t *)kmalloc(tu->queue_size * sizeof(snd_timer_tread_t), GFP_KERNEL);
-		if (tu->tqueue == NULL) {
-			snd_timer_close(tu->timeri);
-			return -ENOMEM;
-		}
+		if (tu->tqueue == NULL)
+			err = -ENOMEM;
 	} else {
 		tu->queue = (snd_timer_read_t *)kmalloc(tu->queue_size * sizeof(snd_timer_read_t), GFP_KERNEL);
-		if (tu->queue == NULL) {
-			snd_timer_close(tu->timeri);
-			return -ENOMEM;
-		}
+		if (tu->queue == NULL)
+			err = -ENOMEM;
 	}
 	
-	tu->timeri->flags |= SNDRV_TIMER_IFLG_FAST;
-	tu->timeri->callback = tu->tread ? snd_timer_user_tinterrupt : snd_timer_user_interrupt;
-	tu->timeri->ccallback = snd_timer_user_ccallback;
-	tu->timeri->callback_data = (void *)tu;
-	return 0;
+      	if (err < 0) {
+		snd_timer_close(tu->timeri);
+      		tu->timeri = NULL;
+      	} else {
+		tu->timeri->flags |= SNDRV_TIMER_IFLG_FAST;
+		tu->timeri->callback = tu->tread ? snd_timer_user_tinterrupt : snd_timer_user_interrupt;
+		tu->timeri->ccallback = snd_timer_user_ccallback;
+		tu->timeri->callback_data = (void *)tu;
+	}
+
+      __err:
+      	up(&tu->tread_sem);
+	return err;
 }
 
 static int snd_timer_user_info(struct file *file, snd_timer_info_t __user *_info)
@@ -1669,6 +1672,23 @@ static int snd_timer_user_continue(struc
 	return (err = snd_timer_continue(tu->timeri)) < 0 ? err : 0;
 }
 
+static int snd_timer_user_pause(struct file *file)
+{
+	int err;
+	snd_timer_user_t *tu;
+		
+	tu = file->private_data;
+	snd_assert(tu->timeri != NULL, return -ENXIO);
+	return (err = snd_timer_pause(tu->timeri)) < 0 ? err : 0;
+}
+
+enum {
+	SNDRV_TIMER_IOCTL_START_OLD = _IO('T', 0x20),
+	SNDRV_TIMER_IOCTL_STOP_OLD = _IO('T', 0x21),
+	SNDRV_TIMER_IOCTL_CONTINUE_OLD = _IO('T', 0x22),
+	SNDRV_TIMER_IOCTL_PAUSE_OLD = _IO('T', 0x23),
+};
+
 static long snd_timer_user_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
 	snd_timer_user_t *tu;
@@ -1685,11 +1705,17 @@ static long snd_timer_user_ioctl(struct 
 	{
 		int xarg;
 		
-		if (tu->timeri)		/* too late */
+		down(&tu->tread_sem);
+		if (tu->timeri)	{	/* too late */
+			up(&tu->tread_sem);
 			return -EBUSY;
-		if (get_user(xarg, p))
+		}
+		if (get_user(xarg, p)) {
+			up(&tu->tread_sem);
 			return -EFAULT;
+		}
 		tu->tread = xarg ? 1 : 0;
+		up(&tu->tread_sem);
 		return 0;
 	}
 	case SNDRV_TIMER_IOCTL_GINFO:
@@ -1707,11 +1733,17 @@ static long snd_timer_user_ioctl(struct 
 	case SNDRV_TIMER_IOCTL_STATUS:
 		return snd_timer_user_status(file, argp);
 	case SNDRV_TIMER_IOCTL_START:
+	case SNDRV_TIMER_IOCTL_START_OLD:
 		return snd_timer_user_start(file);
 	case SNDRV_TIMER_IOCTL_STOP:
+	case SNDRV_TIMER_IOCTL_STOP_OLD:
 		return snd_timer_user_stop(file);
 	case SNDRV_TIMER_IOCTL_CONTINUE:
+	case SNDRV_TIMER_IOCTL_CONTINUE_OLD:
 		return snd_timer_user_continue(file);
+	case SNDRV_TIMER_IOCTL_PAUSE:
+	case SNDRV_TIMER_IOCTL_PAUSE_OLD:
+		return snd_timer_user_pause(file);
 	}
 	return -ENOTTY;
 }
@@ -1898,4 +1930,3 @@ EXPORT_SYMBOL(snd_timer_global_free);
 EXPORT_SYMBOL(snd_timer_global_register);
 EXPORT_SYMBOL(snd_timer_global_unregister);
 EXPORT_SYMBOL(snd_timer_interrupt);
-EXPORT_SYMBOL(snd_timer_system_resolution);
diff --git a/sound/core/timer_compat.c b/sound/core/timer_compat.c
--- a/sound/core/timer_compat.c
+++ b/sound/core/timer_compat.c
@@ -106,8 +106,13 @@ static long snd_timer_user_ioctl_compat(
 	case SNDRV_TIMER_IOCTL_SELECT:
 	case SNDRV_TIMER_IOCTL_PARAMS:
 	case SNDRV_TIMER_IOCTL_START:
+	case SNDRV_TIMER_IOCTL_START_OLD:
 	case SNDRV_TIMER_IOCTL_STOP:
+	case SNDRV_TIMER_IOCTL_STOP_OLD:
 	case SNDRV_TIMER_IOCTL_CONTINUE:
+	case SNDRV_TIMER_IOCTL_CONTINUE_OLD:
+	case SNDRV_TIMER_IOCTL_PAUSE:
+	case SNDRV_TIMER_IOCTL_PAUSE_OLD:
 	case SNDRV_TIMER_IOCTL_NEXT_DEVICE:
 		return snd_timer_user_ioctl(file, cmd, (unsigned long)argp);
 	case SNDRV_TIMER_IOCTL_INFO32:
diff --git a/sound/core/wrappers.c b/sound/core/wrappers.c
--- a/sound/core/wrappers.c
+++ b/sound/core/wrappers.c
@@ -27,7 +27,7 @@
 #include <linux/fs.h>
 
 #ifdef CONFIG_SND_DEBUG_MEMORY
-void *snd_wrapper_kmalloc(size_t size, int flags)
+void *snd_wrapper_kmalloc(size_t size, unsigned int __nocast flags)
 {
 	return kmalloc(size, flags);
 }
diff --git a/sound/drivers/serial-u16550.c b/sound/drivers/serial-u16550.c
--- a/sound/drivers/serial-u16550.c
+++ b/sound/drivers/serial-u16550.c
@@ -168,7 +168,7 @@ typedef struct _snd_uart16550 {
 
 static snd_card_t *snd_serial_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
 
-inline static void snd_uart16550_add_timer(snd_uart16550_t *uart)
+static inline void snd_uart16550_add_timer(snd_uart16550_t *uart)
 {
 	if (! uart->timer_running) {
 		/* timer 38600bps * 10bit * 16byte */
@@ -178,7 +178,7 @@ inline static void snd_uart16550_add_tim
 	}
 }
 
-inline static void snd_uart16550_del_timer(snd_uart16550_t *uart)
+static inline void snd_uart16550_del_timer(snd_uart16550_t *uart)
 {
 	if (uart->timer_running) {
 		del_timer(&uart->buffer_timer);
@@ -187,7 +187,7 @@ inline static void snd_uart16550_del_tim
 }
 
 /* This macro is only used in snd_uart16550_io_loop */
-inline static void snd_uart16550_buffer_output(snd_uart16550_t *uart)
+static inline void snd_uart16550_buffer_output(snd_uart16550_t *uart)
 {
 	unsigned short buff_out = uart->buff_out;
 	if( uart->buff_in_count > 0 ) {
@@ -579,7 +579,7 @@ static int snd_uart16550_output_close(sn
 	return 0;
 };
 
-inline static int snd_uart16550_buffer_can_write( snd_uart16550_t *uart, int Num )
+static inline int snd_uart16550_buffer_can_write( snd_uart16550_t *uart, int Num )
 {
 	if( uart->buff_in_count + Num < TX_BUFF_SIZE )
 		return 1;
@@ -587,7 +587,7 @@ inline static int snd_uart16550_buffer_c
 		return 0;
 }
 
-inline static int snd_uart16550_write_buffer(snd_uart16550_t *uart, unsigned char byte)
+static inline int snd_uart16550_write_buffer(snd_uart16550_t *uart, unsigned char byte)
 {
 	unsigned short buff_in = uart->buff_in;
 	if( uart->buff_in_count < TX_BUFF_SIZE ) {
diff --git a/sound/drivers/vx/vx_pcm.c b/sound/drivers/vx/vx_pcm.c
--- a/sound/drivers/vx/vx_pcm.c
+++ b/sound/drivers/vx/vx_pcm.c
@@ -1264,14 +1264,10 @@ static void snd_vx_pcm_free(snd_pcm_t *p
 {
 	vx_core_t *chip = pcm->private_data;
 	chip->pcm[pcm->device] = NULL;
-	if (chip->playback_pipes) {
-		kfree(chip->playback_pipes);
-		chip->playback_pipes = NULL;
-	}
-	if (chip->capture_pipes) {
-		kfree(chip->capture_pipes);
-		chip->capture_pipes = NULL;
-	}
+	kfree(chip->playback_pipes);
+	chip->playback_pipes = NULL;
+	kfree(chip->capture_pipes);
+	chip->capture_pipes = NULL;
 }
 
 /*
diff --git a/sound/drivers/vx/vx_uer.c b/sound/drivers/vx/vx_uer.c
--- a/sound/drivers/vx/vx_uer.c
+++ b/sound/drivers/vx/vx_uer.c
@@ -162,34 +162,24 @@ static int vx_read_uer_status(vx_core_t 
 
 static int vx_calc_clock_from_freq(vx_core_t *chip, int freq)
 {
-#define XX_FECH48000                    0x0000004B
-#define XX_FECH32000                    0x00000171
-#define XX_FECH24000                    0x0000024B
-#define XX_FECH16000                    0x00000371
-#define XX_FECH12000                    0x0000044B
-#define XX_FECH8000                     0x00000571
-#define XX_FECH44100                    0x0000007F
-#define XX_FECH29400                    0x0000016F
-#define XX_FECH22050                    0x0000027F
-#define XX_FECH14000                    0x000003EF
-#define XX_FECH11025                    0x0000047F
-#define XX_FECH7350                     0x000005BF
-
-	switch (freq) {
-	case 48000:     return XX_FECH48000;
-	case 44100:     return XX_FECH44100;
-	case 32000:     return XX_FECH32000;
-	case 29400:     return XX_FECH29400;
-	case 24000:     return XX_FECH24000;
-	case 22050:     return XX_FECH22050;
-	case 16000:     return XX_FECH16000;
-	case 14000:     return XX_FECH14000;
-	case 12000:     return XX_FECH12000;
-	case 11025:     return XX_FECH11025;
-	case 8000:      return XX_FECH8000;
-	case 7350:      return XX_FECH7350;
-	default:        return freq;   /* The value is already correct */
-	}
+	int hexfreq;
+
+	snd_assert(freq > 0, return 0);
+
+	hexfreq = (28224000 * 10) / freq;
+	hexfreq = (hexfreq + 5) / 10;
+
+	/* max freq = 55125 Hz */
+	snd_assert(hexfreq > 0x00000200, return 0);
+
+	if (hexfreq <= 0x03ff)
+		return hexfreq - 0x00000201;
+	if (hexfreq <= 0x07ff) 
+		return (hexfreq / 2) - 1;
+	if (hexfreq <= 0x0fff)
+		return (hexfreq / 4) + 0x000001ff;
+
+	return 0x5fe; 	/* min freq = 6893 Hz */
 }
 
 
diff --git a/sound/i2c/other/ak4114.c b/sound/i2c/other/ak4114.c
--- a/sound/i2c/other/ak4114.c
+++ b/sound/i2c/other/ak4114.c
@@ -554,7 +554,6 @@ int snd_ak4114_check_rate_and_errors(ak4
 		if (snd_pcm_running(ak4114->capture_substream)) {
 			// printk("rate changed (%i <- %i)\n", runtime->rate, res);
 			snd_pcm_stop(ak4114->capture_substream, SNDRV_PCM_STATE_DRAINING);
-			wake_up(&runtime->sleep);
 			res = 1;
 		}
 		snd_pcm_stream_unlock_irqrestore(ak4114->capture_substream, _flags);
diff --git a/sound/i2c/tea6330t.c b/sound/i2c/tea6330t.c
--- a/sound/i2c/tea6330t.c
+++ b/sound/i2c/tea6330t.c
@@ -266,8 +266,7 @@ TEA6330T_TREBLE("Tone Control - Treble",
 
 static void snd_tea6330_free(snd_i2c_device_t *device)
 {
-	tea6330t_t *tea = device->private_data;
-	kfree(tea);
+	kfree(device->private_data);
 }
                                         
 int snd_tea6330t_update_mixer(snd_card_t * card,
diff --git a/sound/isa/Kconfig b/sound/isa/Kconfig
--- a/sound/isa/Kconfig
+++ b/sound/isa/Kconfig
@@ -1,7 +1,7 @@
 # ALSA ISA drivers
 
 menu "ISA devices"
-	depends on SND!=n && ISA
+	depends on SND!=n && ISA && ISA_DMA_API
 
 config SND_AD1848_LIB
         tristate
@@ -179,6 +179,7 @@ config SND_INTERWAVE_STB
 	select SND_RAWMIDI
 	select SND_CS4231_LIB
 	select SND_GUS_SYNTH
+	select ISAPNP
 	help
 	  Say Y here to include support for AMD InterWave based
 	  soundcards with a TEA6330T bass and treble regulator
diff --git a/sound/isa/ad1816a/ad1816a.c b/sound/isa/ad1816a/ad1816a.c
--- a/sound/isa/ad1816a/ad1816a.c
+++ b/sound/isa/ad1816a/ad1816a.c
@@ -83,6 +83,8 @@ struct snd_card_ad1816a {
 static struct pnp_card_device_id snd_ad1816a_pnpids[] = {
 	/* Analog Devices AD1815 */
 	{ .id = "ADS7150", .devs = { { .id = "ADS7150" }, { .id = "ADS7151" } } },
+	/* Analog Device AD1816? */
+	{ .id = "ADS7180", .devs = { { .id = "ADS7180" }, { .id = "ADS7181" } } },
 	/* Analog Devices AD1816A - added by Kenneth Platz <kxp@atl.hp.com> */
 	{ .id = "ADS7181", .devs = { { .id = "ADS7180" }, { .id = "ADS7181" } } },
 	/* Analog Devices AD1816A - Aztech/Newcom SC-16 3D */
diff --git a/sound/isa/cs423x/cs4236.c b/sound/isa/cs423x/cs4236.c
--- a/sound/isa/cs423x/cs4236.c
+++ b/sound/isa/cs423x/cs4236.c
@@ -349,8 +349,7 @@ static int __devinit snd_card_cs4236_pnp
 		pnp_init_resource_table(cfg);
 		if (mpu_port[dev] != SNDRV_AUTO_PORT)
 			pnp_resource_change(&cfg->port_resource[0], mpu_port[dev], 2);
-		if (mpu_irq[dev] != SNDRV_AUTO_IRQ && mpu_irq[dev] >= 0 &&
-		    pnp_irq_valid(pdev, 0))
+		if (mpu_irq[dev] != SNDRV_AUTO_IRQ && mpu_irq[dev] >= 0)
 			pnp_resource_change(&cfg->irq_resource[0], mpu_irq[dev], 1);
 		err = pnp_manual_config_dev(pdev, cfg, 0);
 		if (err < 0)
diff --git a/sound/isa/gus/gus_io.c b/sound/isa/gus/gus_io.c
--- a/sound/isa/gus/gus_io.c
+++ b/sound/isa/gus/gus_io.c
@@ -244,6 +244,8 @@ unsigned short snd_gf1_i_look16(snd_gus_
 	return res;
 }
 
+#if 0
+
 void snd_gf1_i_adlib_write(snd_gus_card_t * gus,
 		           unsigned char reg,
 		           unsigned char data)
@@ -265,6 +267,8 @@ void snd_gf1_i_write_addr(snd_gus_card_t
 	spin_unlock_irqrestore(&gus->reg_lock, flags);
 }
 
+#endif  /*  0  */
+
 unsigned int snd_gf1_i_read_addr(snd_gus_card_t * gus,
 				 unsigned char reg, short w_16bit)
 {
@@ -329,6 +333,8 @@ unsigned char snd_gf1_peek(snd_gus_card_
 	return res;
 }
 
+#if 0
+
 void snd_gf1_pokew(snd_gus_card_t * gus, unsigned int addr, unsigned short data)
 {
 	unsigned long flags;
@@ -405,9 +411,7 @@ void snd_gf1_dram_setmem(snd_gus_card_t 
 	spin_unlock_irqrestore(&gus->reg_lock, flags);
 }
 
-/*
-
- */
+#endif  /*  0  */
 
 void snd_gf1_select_active_voices(snd_gus_card_t * gus)
 {
@@ -469,6 +473,8 @@ void snd_gf1_print_voice_registers(snd_g
 		printk(" -%i- GF1  pan                    = 0x%x\n", voice, snd_gf1_i_read8(gus, 0x0c));
 }
 
+#if 0
+
 void snd_gf1_print_global_registers(snd_gus_card_t * gus)
 {
 	unsigned char global_mode = 0x00;
@@ -528,4 +534,6 @@ void snd_gf1_peek_print_block(snd_gus_ca
 	}
 }
 
+#endif  /*  0  */
+
 #endif
diff --git a/sound/isa/gus/gus_main.c b/sound/isa/gus/gus_main.c
--- a/sound/isa/gus/gus_main.c
+++ b/sound/isa/gus/gus_main.c
@@ -417,11 +417,13 @@ static int snd_gus_check_version(snd_gus
 	return 0;
 }
 
+#if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE))
 static void snd_gus_seq_dev_free(snd_seq_device_t *seq_dev)
 {
 	snd_gus_card_t *gus = seq_dev->private_data;
 	gus->seq_dev = NULL;
 }
+#endif
 
 int snd_gus_initialize(snd_gus_card_t *gus)
 {
@@ -459,7 +461,6 @@ EXPORT_SYMBOL(snd_gf1_write16);
 EXPORT_SYMBOL(snd_gf1_look16);
 EXPORT_SYMBOL(snd_gf1_i_write8);
 EXPORT_SYMBOL(snd_gf1_i_look8);
-EXPORT_SYMBOL(snd_gf1_i_write16);
 EXPORT_SYMBOL(snd_gf1_i_look16);
 EXPORT_SYMBOL(snd_gf1_dram_addr);
 EXPORT_SYMBOL(snd_gf1_write_addr);
@@ -470,8 +471,6 @@ EXPORT_SYMBOL(snd_gf1_alloc_voice);
 EXPORT_SYMBOL(snd_gf1_free_voice);
 EXPORT_SYMBOL(snd_gf1_ctrl_stop);
 EXPORT_SYMBOL(snd_gf1_stop_voice);
-EXPORT_SYMBOL(snd_gf1_start);
-EXPORT_SYMBOL(snd_gf1_stop);
   /* gus_mixer.c */
 EXPORT_SYMBOL(snd_gf1_new_mixer);
   /* gus_pcm.c */
diff --git a/sound/isa/gus/gus_mem.c b/sound/isa/gus/gus_mem.c
--- a/sound/isa/gus/gus_mem.c
+++ b/sound/isa/gus/gus_mem.c
@@ -21,6 +21,7 @@
 
 #include <sound/driver.h>
 #include <linux/slab.h>
+#include <linux/string.h>
 #include <sound/core.h>
 #include <sound/gus.h>
 #include <sound/info.h>
@@ -39,8 +40,8 @@ void snd_gf1_mem_lock(snd_gf1_mem_t * al
 	}
 }
 
-snd_gf1_mem_block_t *snd_gf1_mem_xalloc(snd_gf1_mem_t * alloc,
-				        snd_gf1_mem_block_t * block)
+static snd_gf1_mem_block_t *snd_gf1_mem_xalloc(snd_gf1_mem_t * alloc,
+					       snd_gf1_mem_block_t * block)
 {
 	snd_gf1_mem_block_t *pblock, *nblock;
 
@@ -105,8 +106,8 @@ int snd_gf1_mem_xfree(snd_gf1_mem_t * al
 	return 0;
 }
 
-snd_gf1_mem_block_t *snd_gf1_mem_look(snd_gf1_mem_t * alloc,
-				      unsigned int address)
+static snd_gf1_mem_block_t *snd_gf1_mem_look(snd_gf1_mem_t * alloc,
+					     unsigned int address)
 {
 	snd_gf1_mem_block_t *block;
 
@@ -118,8 +119,8 @@ snd_gf1_mem_block_t *snd_gf1_mem_look(sn
 	return NULL;
 }
 
-snd_gf1_mem_block_t *snd_gf1_mem_share(snd_gf1_mem_t * alloc,
-				       unsigned int *share_id)
+static snd_gf1_mem_block_t *snd_gf1_mem_share(snd_gf1_mem_t * alloc,
+					      unsigned int *share_id)
 {
 	snd_gf1_mem_block_t *block;
 
@@ -213,7 +214,7 @@ snd_gf1_mem_block_t *snd_gf1_mem_alloc(s
 	if (share_id != NULL)
 		memcpy(&block.share_id, share_id, sizeof(block.share_id));
 	block.owner = owner;
-	block.name = snd_kmalloc_strdup(name, GFP_KERNEL);
+	block.name = kstrdup(name, GFP_KERNEL);
 	nblock = snd_gf1_mem_xalloc(alloc, &block);
 	snd_gf1_mem_lock(alloc, 1);
 	return nblock;
@@ -253,13 +254,13 @@ int snd_gf1_mem_init(snd_gus_card_t * gu
 	if (gus->gf1.enh_mode) {
 		block.ptr = 0;
 		block.size = 1024;
-		block.name = snd_kmalloc_strdup("InterWave LFOs", GFP_KERNEL);
+		block.name = kstrdup("InterWave LFOs", GFP_KERNEL);
 		if (snd_gf1_mem_xalloc(alloc, &block) == NULL)
 			return -ENOMEM;
 	}
 	block.ptr = gus->gf1.default_voice_address;
 	block.size = 4;
-	block.name = snd_kmalloc_strdup("Voice default (NULL's)", GFP_KERNEL);
+	block.name = kstrdup("Voice default (NULL's)", GFP_KERNEL);
 	if (snd_gf1_mem_xalloc(alloc, &block) == NULL)
 		return -ENOMEM;
 #ifdef CONFIG_SND_DEBUG
diff --git a/sound/isa/gus/gus_pcm.c b/sound/isa/gus/gus_pcm.c
--- a/sound/isa/gus/gus_pcm.c
+++ b/sound/isa/gus/gus_pcm.c
@@ -656,8 +656,7 @@ static snd_pcm_hardware_t snd_gf1_pcm_ca
 
 static void snd_gf1_pcm_playback_free(snd_pcm_runtime_t *runtime)
 {
-	gus_pcm_private_t * pcmp = runtime->private_data;
-	kfree(pcmp);
+	kfree(runtime->private_data);
 }
 
 static int snd_gf1_pcm_playback_open(snd_pcm_substream_t *substream)
diff --git a/sound/isa/gus/gus_reset.c b/sound/isa/gus/gus_reset.c
--- a/sound/isa/gus/gus_reset.c
+++ b/sound/isa/gus/gus_reset.c
@@ -161,7 +161,8 @@ void snd_gf1_stop_voice(snd_gus_card_t *
 #endif
 }
 
-void snd_gf1_clear_voices(snd_gus_card_t * gus, unsigned short v_min, unsigned short v_max)
+static void snd_gf1_clear_voices(snd_gus_card_t * gus, unsigned short v_min,
+				 unsigned short v_max)
 {
 	unsigned long flags;
 	unsigned int daddr;
diff --git a/sound/isa/gus/gus_synth.c b/sound/isa/gus/gus_synth.c
--- a/sound/isa/gus/gus_synth.c
+++ b/sound/isa/gus/gus_synth.c
@@ -99,7 +99,8 @@ static void snd_gus_synth_free_private_i
 	snd_seq_instr_list_free_cond(p->gus->gf1.ilist, &ifree, client, 0);
 }
  
-int snd_gus_synth_event_input(snd_seq_event_t *ev, int direct, void *private_data, int atomic, int hop)
+static int snd_gus_synth_event_input(snd_seq_event_t *ev, int direct,
+				     void *private_data, int atomic, int hop)
 {
 	snd_gus_port_t * p = (snd_gus_port_t *) private_data;
 	
diff --git a/sound/isa/gus/gus_tables.h b/sound/isa/gus/gus_tables.h
--- a/sound/isa/gus/gus_tables.h
+++ b/sound/isa/gus/gus_tables.h
@@ -23,6 +23,8 @@
 
 #ifdef __GUS_TABLES_ALLOC__
 
+#if 0
+
 unsigned int snd_gf1_scale_table[SNDRV_GF1_SCALE_TABLE_SIZE] =
 {
       8372,      8870,      9397,      9956,     10548,     11175,
@@ -49,6 +51,8 @@ unsigned int snd_gf1_scale_table[SNDRV_G
   12123977,  12844906
 };
 
+#endif  /*  0  */
+
 unsigned short snd_gf1_atten_table[SNDRV_GF1_ATTEN_TABLE_SIZE] = {
   4095 /* 0   */,1789 /* 1   */,1533 /* 2   */,1383 /* 3   */,1277 /* 4   */,
   1195 /* 5   */,1127 /* 6   */,1070 /* 7   */,1021 /* 8   */,978  /* 9   */,
diff --git a/sound/isa/gus/gus_volume.c b/sound/isa/gus/gus_volume.c
--- a/sound/isa/gus/gus_volume.c
+++ b/sound/isa/gus/gus_volume.c
@@ -55,6 +55,8 @@ unsigned short snd_gf1_lvol_to_gvol_raw(
 	return (e << 8) | m;
 }
 
+#if 0
+
 unsigned int snd_gf1_gvol_to_lvol_raw(unsigned short gf1_vol)
 {
 	unsigned int rvol;
@@ -108,6 +110,8 @@ unsigned int snd_gf1_calc_ramp_rate(snd_
 	return (range << 6) | (increment & 0x3f);
 }
 
+#endif  /*  0  */
+
 unsigned short snd_gf1_translate_freq(snd_gus_card_t * gus, unsigned int freq16)
 {
 	freq16 >>= 3;
@@ -120,6 +124,8 @@ unsigned short snd_gf1_translate_freq(sn
 	return ((freq16 << 9) + (gus->gf1.playback_freq >> 1)) / gus->gf1.playback_freq;
 }
 
+#if 0
+
 short snd_gf1_compute_vibrato(short cents, unsigned short fc_register)
 {
 	static short vibrato_table[] =
@@ -208,3 +214,5 @@ unsigned short snd_gf1_compute_freq(unsi
 	}
 	return (unsigned short) fc;
 }
+
+#endif  /*  0  */
diff --git a/sound/isa/sb/emu8000_patch.c b/sound/isa/sb/emu8000_patch.c
--- a/sound/isa/sb/emu8000_patch.c
+++ b/sound/isa/sb/emu8000_patch.c
@@ -128,7 +128,7 @@ snd_emu8000_write_wait(emu8000_t *emu)
  * This is therefore much slower than need be, but is at least
  * working.
  */
-inline static void
+static inline void
 write_word(emu8000_t *emu, int *offset, unsigned short data)
 {
 	if (emu8000_reset_addr) {
diff --git a/sound/isa/sb/sb_mixer.c b/sound/isa/sb/sb_mixer.c
--- a/sound/isa/sb/sb_mixer.c
+++ b/sound/isa/sb/sb_mixer.c
@@ -688,7 +688,7 @@ static struct sbmix_elem snd_als4000_ctl
 	SB_SINGLE("3D PowerOff Switch", SB_ALS4000_3D_TIME_DELAY, 4, 0x01);
 static struct sbmix_elem snd_als4000_ctl_3d_delay =
 	SB_SINGLE("3D Delay", SB_ALS4000_3D_TIME_DELAY, 0, 0x0f);
-#if NOT_AVAILABLE
+#ifdef NOT_AVAILABLE
 static struct sbmix_elem snd_als4000_ctl_fmdac =
 	SB_SINGLE("FMDAC Switch (Option ?)", SB_ALS4000_FMDAC, 0, 0x01);
 static struct sbmix_elem snd_als4000_ctl_qsound =
@@ -723,7 +723,7 @@ static struct sbmix_elem *snd_als4000_co
 	&snd_als4000_ctl_3d_output_ratio,
 	&snd_als4000_ctl_3d_delay,
 	&snd_als4000_ctl_3d_poweroff_switch,
-#if NOT_AVAILABLE
+#ifdef NOT_AVAILABLE
 	&snd_als4000_ctl_fmdac,
 	&snd_als4000_ctl_qsound,
 #endif
diff --git a/sound/isa/wavefront/wavefront_fx.c b/sound/isa/wavefront/wavefront_fx.c
--- a/sound/isa/wavefront/wavefront_fx.c
+++ b/sound/isa/wavefront/wavefront_fx.c
@@ -34,7 +34,7 @@
 
 /* weird stuff, derived from port I/O tracing with dosemu */
 
-unsigned char page_zero[] __initdata = {
+static unsigned char page_zero[] __initdata = {
 0x01, 0x7c, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf5, 0x00,
 0x11, 0x00, 0x20, 0x00, 0x32, 0x00, 0x40, 0x00, 0x13, 0x00, 0x00,
 0x00, 0x14, 0x02, 0x76, 0x00, 0x60, 0x00, 0x80, 0x02, 0x00, 0x00,
@@ -61,7 +61,7 @@ unsigned char page_zero[] __initdata = {
 0x1d, 0x02, 0xdf
 };
 
-unsigned char page_one[] __initdata = {
+static unsigned char page_one[] __initdata = {
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x19, 0x00,
 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xd8, 0x00, 0x00,
 0x02, 0x20, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x01,
@@ -88,7 +88,7 @@ unsigned char page_one[] __initdata = {
 0x60, 0x00, 0x1b
 };
 
-unsigned char page_two[] __initdata = {
+static unsigned char page_two[] __initdata = {
 0xc4, 0x00, 0x44, 0x07, 0x44, 0x00, 0x40, 0x25, 0x01, 0x06, 0xc4,
 0x07, 0x40, 0x25, 0x01, 0x00, 0x46, 0x46, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -103,7 +103,7 @@ unsigned char page_two[] __initdata = {
 0x46, 0x05, 0x46, 0x07, 0x46, 0x07, 0x44
 };
 
-unsigned char page_three[] __initdata = {
+static unsigned char page_three[] __initdata = {
 0x07, 0x40, 0x00, 0x00, 0x00, 0x47, 0x00, 0x40, 0x00, 0x40, 0x06,
 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -118,7 +118,7 @@ unsigned char page_three[] __initdata = 
 0x02, 0x00, 0x42, 0x00, 0xc0, 0x00, 0x40
 };
 
-unsigned char page_four[] __initdata = {
+static unsigned char page_four[] __initdata = {
 0x63, 0x03, 0x26, 0x02, 0x2c, 0x00, 0x24, 0x00, 0x2e, 0x02, 0x02,
 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -133,7 +133,7 @@ unsigned char page_four[] __initdata = {
 0x02, 0x62, 0x02, 0x20, 0x01, 0x21, 0x01
 };
 
-unsigned char page_six[] __initdata = {
+static unsigned char page_six[] __initdata = {
 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x04, 0x00, 0x00, 0x06, 0x00,
 0x00, 0x08, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x0e,
 0x00, 0x00, 0x10, 0x00, 0x00, 0x12, 0x00, 0x00, 0x14, 0x00, 0x00,
@@ -154,7 +154,7 @@ unsigned char page_six[] __initdata = {
 0x80, 0x00, 0x7e, 0x80, 0x80
 };
 
-unsigned char page_seven[] __initdata = {
+static unsigned char page_seven[] __initdata = {
 0x0f, 0xff, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
 0x08, 0x00, 0x00, 0x00, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x0f,
@@ -181,7 +181,7 @@ unsigned char page_seven[] __initdata = 
 0x00, 0x02, 0x00
 };
 
-unsigned char page_zero_v2[] __initdata = {
+static unsigned char page_zero_v2[] __initdata = {
 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -193,7 +193,7 @@ unsigned char page_zero_v2[] __initdata 
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
 };
 
-unsigned char page_one_v2[] __initdata = {
+static unsigned char page_one_v2[] __initdata = {
 0x01, 0xc0, 0x01, 0xfa, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -205,21 +205,21 @@ unsigned char page_one_v2[] __initdata =
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
 };
 
-unsigned char page_two_v2[] __initdata = {
+static unsigned char page_two_v2[] __initdata = {
 0x46, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00
 };
-unsigned char page_three_v2[] __initdata = {
+static unsigned char page_three_v2[] __initdata = {
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00
 };
-unsigned char page_four_v2[] __initdata = {
+static unsigned char page_four_v2[] __initdata = {
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -227,7 +227,7 @@ unsigned char page_four_v2[] __initdata 
 0x00, 0x00, 0x00, 0x00
 };
 
-unsigned char page_seven_v2[] __initdata = {
+static unsigned char page_seven_v2[] __initdata = {
 0x0f, 0xff, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -239,7 +239,7 @@ unsigned char page_seven_v2[] __initdata
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
 };
 
-unsigned char mod_v2[] __initdata = {
+static unsigned char mod_v2[] __initdata = {
 0x01, 0x00, 0x02, 0x00, 0x01, 0x01, 0x02, 0x00, 0x01, 0x02, 0x02,
 0x00, 0x01, 0x03, 0x02, 0x00, 0x01, 0x04, 0x02, 0x00, 0x01, 0x05,
 0x02, 0x00, 0x01, 0x06, 0x02, 0x00, 0x01, 0x07, 0x02, 0x00, 0xb0,
@@ -269,7 +269,7 @@ unsigned char mod_v2[] __initdata = {
 0x02, 0x01, 0x01, 0x04, 0x02, 0x01, 0x01, 0x05, 0x02, 0x01, 0x01,
 0x06, 0x02, 0x01, 0x01, 0x07, 0x02, 0x01
 };
-unsigned char coefficients[] __initdata = {
+static unsigned char coefficients[] __initdata = {
 0x07, 0x46, 0x00, 0x00, 0x07, 0x49, 0x00, 0x00, 0x00, 0x4b, 0x03,
 0x11, 0x00, 0x4d, 0x01, 0x32, 0x07, 0x46, 0x00, 0x00, 0x07, 0x49,
 0x00, 0x00, 0x07, 0x40, 0x00, 0x00, 0x07, 0x41, 0x00, 0x00, 0x01,
@@ -305,14 +305,14 @@ unsigned char coefficients[] __initdata 
 0x06, 0x6c, 0x4c, 0x6c, 0x06, 0x50, 0x52, 0xe2, 0x06, 0x42, 0x02,
 0xba
 };
-unsigned char coefficients2[] __initdata = {
+static unsigned char coefficients2[] __initdata = {
 0x07, 0x46, 0x00, 0x00, 0x07, 0x49, 0x00, 0x00, 0x07, 0x45, 0x0f,
 0xff, 0x07, 0x48, 0x0f, 0xff, 0x07, 0x7b, 0x04, 0xcc, 0x07, 0x7d,
 0x04, 0xcc, 0x07, 0x7c, 0x00, 0x00, 0x07, 0x7e, 0x00, 0x00, 0x07,
 0x46, 0x00, 0x00, 0x07, 0x49, 0x00, 0x00, 0x07, 0x47, 0x00, 0x00,
 0x07, 0x4a, 0x00, 0x00, 0x07, 0x4c, 0x00, 0x00, 0x07, 0x4e, 0x00, 0x00
 };
-unsigned char coefficients3[] __initdata = {
+static unsigned char coefficients3[] __initdata = {
 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x28, 0x00, 0x51, 0x00,
 0x51, 0x00, 0x7a, 0x00, 0x7a, 0x00, 0xa3, 0x00, 0xa3, 0x00, 0xcc,
 0x00, 0xcc, 0x00, 0xf5, 0x00, 0xf5, 0x01, 0x1e, 0x01, 0x1e, 0x01,
diff --git a/sound/oss/Kconfig b/sound/oss/Kconfig
--- a/sound/oss/Kconfig
+++ b/sound/oss/Kconfig
@@ -6,7 +6,7 @@
 # Prompt user for primary drivers.
 config SOUND_BT878
 	tristate "BT878 audio dma"
-	depends on SOUND_PRIME!=n && SOUND
+	depends on SOUND_PRIME && PCI
 	---help---
 	  Audio DMA support for bt878 based grabber boards.  As you might have
 	  already noticed, bt878 is listed with two functions in /proc/pci.
@@ -22,7 +22,7 @@ config SOUND_BT878
 
 config SOUND_CMPCI
 	tristate "C-Media PCI (CMI8338/8738)"
-	depends on SOUND_PRIME!=n && SOUND && PCI
+	depends on SOUND_PRIME && PCI
 	help
 	  Say Y or M if you have a PCI sound card using the CMI8338
 	  or the CMI8738 chipset.  Data on these chips are available at
@@ -52,7 +52,7 @@ config SOUND_CMPCI_MIDI
 
 config SOUND_CMPCI_JOYSTICK
 	bool "Enable joystick"
-	depends on SOUND_CMPCI && X86
+	depends on SOUND_CMPCI && X86 && (GAMEPORT=y || SOUND_CMPCI=GAMEPORT)
 	help
 	  Say Y here in order to enable the joystick port on a sound card using
 	  the CMI8338 or the CMI8738 chipset.  You need to config the
@@ -61,7 +61,7 @@ config SOUND_CMPCI_JOYSTICK
 
 config SOUND_EMU10K1
 	tristate "Creative SBLive! (EMU10K1)"
-	depends on SOUND_PRIME!=n && SOUND && PCI
+	depends on SOUND_PRIME && PCI
 	---help---
 	  Say Y or M if you have a PCI sound card using the EMU10K1 chipset,
 	  such as the Creative SBLive!, SB PCI512 or Emu-APS.
@@ -80,14 +80,14 @@ config SOUND_EMU10K1
 
 config MIDI_EMU10K1
 	bool "Creative SBLive! MIDI (EXPERIMENTAL)"
-	depends on SOUND_EMU10K1 && EXPERIMENTAL
+	depends on SOUND_EMU10K1 && EXPERIMENTAL && ISA_DMA_API
 	help
 	  Say Y if you want to be able to use the OSS /dev/sequencer
 	  interface.  This code is still experimental.
 
 config SOUND_FUSION
 	tristate "Crystal SoundFusion (CS4280/461x)"
-	depends on SOUND_PRIME!=n && SOUND
+	depends on SOUND_PRIME && PCI
 	help
 	  This module drives the Crystal SoundFusion devices (CS4280/46xx
 	  series) when wired as native sound drivers with AC97 codecs.  If
@@ -95,14 +95,14 @@ config SOUND_FUSION
 
 config SOUND_CS4281
 	tristate "Crystal Sound CS4281"
-	depends on SOUND_PRIME!=n && SOUND
+	depends on SOUND_PRIME && PCI
 	help
 	  Picture and feature list at
 	  <http://www.pcbroker.com/crystal4281.html>.
 
 config SOUND_BCM_CS4297A
 	tristate "Crystal Sound CS4297a (for Swarm)"
-	depends on SOUND_PRIME!=n && SIBYTE_SWARM && SOUND
+	depends on SOUND_PRIME && SIBYTE_SWARM
 	help
 	  The BCM91250A has a Crystal CS4297a on synchronous serial
 	  port B (in addition to the DB-9 serial port).  Say Y or M
@@ -112,7 +112,7 @@ config SOUND_BCM_CS4297A
 
 config SOUND_ES1370
 	tristate "Ensoniq AudioPCI (ES1370)"
-	depends on SOUND_PRIME!=n && SOUND && PCI
+	depends on SOUND_PRIME && PCI
 	help
 	  Say Y or M if you have a PCI sound card utilizing the Ensoniq
 	  ES1370 chipset, such as Ensoniq's AudioPCI (non-97). To find
@@ -125,7 +125,7 @@ config SOUND_ES1370
 
 config SOUND_ES1371
 	tristate "Creative Ensoniq AudioPCI 97 (ES1371)"
-	depends on SOUND_PRIME!=n && SOUND && PCI
+	depends on SOUND_PRIME && PCI
 	help
 	  Say Y or M if you have a PCI sound card utilizing the Ensoniq
 	  ES1371 chipset, such as Ensoniq's AudioPCI97. To find out if
@@ -138,7 +138,7 @@ config SOUND_ES1371
 
 config SOUND_ESSSOLO1
 	tristate "ESS Technology Solo1" 
-	depends on SOUND_PRIME!=n && SOUND && PCI
+	depends on SOUND_PRIME && PCI
 	help
 	  Say Y or M if you have a PCI sound card utilizing the ESS Technology
 	  Solo1 chip. To find out if your sound card uses a
@@ -149,7 +149,7 @@ config SOUND_ESSSOLO1
 
 config SOUND_MAESTRO
 	tristate "ESS Maestro, Maestro2, Maestro2E driver"
-	depends on SOUND_PRIME!=n && SOUND && PCI
+	depends on SOUND_PRIME && PCI
 	help
 	  Say Y or M if you have a sound system driven by ESS's Maestro line
 	  of PCI sound chips.  These include the Maestro 1, Maestro 2, and
@@ -158,28 +158,28 @@ config SOUND_MAESTRO
 
 config SOUND_MAESTRO3
 	tristate "ESS Maestro3/Allegro driver (EXPERIMENTAL)"
-	depends on SOUND_PRIME!=n && SOUND && PCI && EXPERIMENTAL
+	depends on SOUND_PRIME && PCI && EXPERIMENTAL
 	help
 	  Say Y or M if you have a sound system driven by ESS's Maestro 3
 	  PCI sound chip.
 
 config SOUND_ICH
 	tristate "Intel ICH (i8xx) audio support"
-	depends on SOUND_PRIME!=n && PCI
+	depends on SOUND_PRIME && PCI
 	help
 	  Support for integral audio in Intel's I/O Controller Hub (ICH)
 	  chipset, as used on the 810/820/840 motherboards.
 
 config SOUND_HARMONY
 	tristate "PA Harmony audio driver"
-	depends on GSC_LASI && SOUND_PRIME!=n
+	depends on GSC_LASI && SOUND_PRIME
 	help
 	  Say 'Y' or 'M' to include support for Harmony soundchip
 	  on HP 712, 715/new and many other GSC based machines.
 
 config SOUND_SONICVIBES
 	tristate "S3 SonicVibes"
-	depends on SOUND_PRIME!=n && SOUND
+	depends on SOUND_PRIME && PCI
 	help
 	  Say Y or M if you have a PCI sound card utilizing the S3
 	  SonicVibes chipset. To find out if your sound card uses a
@@ -190,7 +190,7 @@ config SOUND_SONICVIBES
 
 config SOUND_VWSND
 	tristate "SGI Visual Workstation Sound"
-	depends on SOUND_PRIME!=n && X86_VISWS && SOUND
+	depends on SOUND_PRIME && X86_VISWS
 	help
 	  Say Y or M if you have an SGI Visual Workstation and you want to be
 	  able to use its on-board audio.  Read
@@ -199,18 +199,18 @@ config SOUND_VWSND
 
 config SOUND_HAL2
 	tristate "SGI HAL2 sound (EXPERIMENTAL)"
-	depends on SOUND_PRIME!=n && SOUND && SGI_IP22 && EXPERIMENTAL
+	depends on SOUND_PRIME && SGI_IP22 && EXPERIMENTAL
 	help
 	  Say Y or M if you have an SGI Indy system and want to be able to
 	  use it's on-board A2 audio system.
 
 config SOUND_IT8172
 	tristate "IT8172G Sound"
-	depends on SOUND_PRIME!=n && (MIPS_ITE8172 || MIPS_IVR) && SOUND
+	depends on SOUND_PRIME && (MIPS_ITE8172 || MIPS_IVR)
 
 config SOUND_VRC5477
 	tristate "NEC Vrc5477 AC97 sound"
-	depends on SOUND_PRIME!=n && DDB5477 && SOUND
+	depends on SOUND_PRIME && DDB5477
 	help
 	  Say Y here to enable sound support for the NEC Vrc5477 chip, an
 	  integrated, multi-function controller chip for MIPS CPUs.  Works
@@ -218,15 +218,15 @@ config SOUND_VRC5477
 
 config SOUND_AU1000
 	tristate "Au1000 Sound"
-	depends on SOUND_PRIME!=n && (SOC_AU1000 || SOC_AU1100 || SOC_AU1500) && SOUND
+	depends on SOUND_PRIME && (SOC_AU1000 || SOC_AU1100 || SOC_AU1500)
 
 config SOUND_AU1550_AC97
 	tristate "Au1550 AC97 Sound"
-	depends on SOUND_PRIME!=n && SOC_AU1550 && SOUND
+	depends on SOUND_PRIME && SOC_AU1550
 
 config SOUND_TRIDENT
 	tristate "Trident 4DWave DX/NX, SiS 7018 or ALi 5451 PCI Audio Core"
-	depends on SOUND_PRIME!=n && SOUND
+	depends on SOUND_PRIME && PCI
 	---help---
 	  Say Y or M if you have a PCI sound card utilizing the Trident
 	  4DWave-DX/NX chipset or your mother board chipset has SiS 7018
@@ -267,7 +267,7 @@ config SOUND_TRIDENT
 
 config SOUND_MSNDCLAS
 	tristate "Support for Turtle Beach MultiSound Classic, Tahiti, Monterey"
-	depends on SOUND_PRIME!=n && SOUND && (m || !STANDALONE)
+	depends on SOUND_PRIME && (m || !STANDALONE)
 	help
 	  Say M here if you have a Turtle Beach MultiSound Classic, Tahiti or
 	  Monterey (not for the Pinnacle or Fiji).
@@ -331,7 +331,7 @@ config MSNDCLAS_IO
 
 config SOUND_MSNDPIN
 	tristate "Support for Turtle Beach MultiSound Pinnacle, Fiji"
-	depends on SOUND_PRIME!=n && SOUND && (m || !STANDALONE)
+	depends on SOUND_PRIME && (m || !STANDALONE)
 	help
 	  Say M here if you have a Turtle Beach MultiSound Pinnacle or Fiji.
 	  See <file:Documentation/sound/oss/MultiSound> for important information
@@ -492,7 +492,7 @@ config MSND_FIFOSIZE
 
 config SOUND_VIA82CXXX
 	tristate "VIA 82C686 Audio Codec"
-	depends on SOUND_PRIME!=n && PCI
+	depends on SOUND_PRIME && PCI
 	help
 	  Say Y here to include support for the audio codec found on VIA
 	  82Cxxx-based chips. Typically these are built into a motherboard.
@@ -503,7 +503,7 @@ config SOUND_VIA82CXXX
 
 config MIDI_VIA82CXXX
 	bool "VIA 82C686 MIDI"
-	depends on SOUND_VIA82CXXX
+	depends on SOUND_VIA82CXXX && ISA_DMA_API
 	help
 	  Answer Y to use the MIDI interface of the Via686. You may need to
 	  enable this in the BIOS before it will work. This is for connection
@@ -512,7 +512,7 @@ config MIDI_VIA82CXXX
 
 config SOUND_OSS
 	tristate "OSS sound modules"
-	depends on SOUND_PRIME!=n && SOUND
+	depends on SOUND_PRIME && ISA_DMA_API
 	help
 	  OSS is the Open Sound System suite of sound card drivers.  They make
 	  sound programming easier since they provide a common API.  Say Y or
@@ -1077,7 +1077,7 @@ config SOUND_WAVEARTIST
 
 config SOUND_TVMIXER
 	tristate "TV card (bt848) mixer support"
-	depends on SOUND_PRIME!=n && SOUND && I2C
+	depends on SOUND_PRIME && I2C
 	help
 	  Support for audio mixer facilities on the BT848 TV frame-grabber
 	  card.
@@ -1088,11 +1088,11 @@ config SOUND_KAHLUA
 
 config SOUND_ALI5455
 	tristate "ALi5455 audio support"
-	depends on SOUND_PRIME!=n && PCI
+	depends on SOUND_PRIME && PCI
 
 config SOUND_FORTE
 	tristate "ForteMedia FM801 driver"
-	depends on SOUND_PRIME!=n && PCI
+	depends on SOUND_PRIME && PCI
 	help
 	  Say Y or M if you want driver support for the ForteMedia FM801 PCI
 	  audio controller (Abit AU10, Genius Sound Maker, HP Workstation
@@ -1100,7 +1100,7 @@ config SOUND_FORTE
 
 config SOUND_RME96XX
 	tristate "RME Hammerfall (RME96XX) support"
-	depends on SOUND_PRIME!=n && PCI
+	depends on SOUND_PRIME && PCI
 	help
 	  Say Y or M if you have a Hammerfall or Hammerfall light
 	  multichannel card from RME. If you want to access advanced
@@ -1108,11 +1108,11 @@ config SOUND_RME96XX
 
 config SOUND_AD1980
 	tristate "AD1980 front/back switch plugin"
-	depends on SOUND_PRIME!=n
+	depends on SOUND_PRIME
 
 config SOUND_SH_DAC_AUDIO
 	tristate "SuperH DAC audio support"
-	depends on SOUND_PRIME!=n && SOUND && CPU_SH3
+	depends on SOUND_PRIME && CPU_SH3
 
 config SOUND_SH_DAC_AUDIO_CHANNEL
 	int "    DAC channel"
diff --git a/sound/oss/Makefile b/sound/oss/Makefile
--- a/sound/oss/Makefile
+++ b/sound/oss/Makefile
@@ -80,7 +80,7 @@ obj-$(CONFIG_SOUND_ALI5455)	+= ali5455.o
 obj-$(CONFIG_SOUND_IT8172)	+= ite8172.o ac97_codec.o
 obj-$(CONFIG_SOUND_FORTE)	+= forte.o ac97_codec.o
 
-obj-$(CONFIG_SOUND_AD1980)	+= ac97_plugin_ad1980.o
+obj-$(CONFIG_SOUND_AD1980)	+= ac97_plugin_ad1980.o ac97_codec.o
 obj-$(CONFIG_SOUND_WM97XX)	+= ac97_plugin_wm97xx.o
 
 ifeq ($(CONFIG_MIDI_EMU10K1),y)
diff --git a/sound/oss/ad1816.c b/sound/oss/ad1816.c
--- a/sound/oss/ad1816.c
+++ b/sound/oss/ad1816.c
@@ -592,7 +592,7 @@ typedef struct mixer_def mixer_ent;
   {{reg_l, pola_l, pos_l, len_l}, {reg_r, pola_r, pos_r, len_r}}
 
 
-mixer_ent mix_devices[SOUND_MIXER_NRDEVICES][2] = {
+static mixer_ent mix_devices[SOUND_MIXER_NRDEVICES][2] = {
 MIX_ENT(SOUND_MIXER_VOLUME,	14, 1, 8, 5,	14, 1, 0, 5),
 MIX_ENT(SOUND_MIXER_BASS,	 0, 0, 0, 0,	 0, 0, 0, 0),
 MIX_ENT(SOUND_MIXER_TREBLE,	 0, 0, 0, 0,	 0, 0, 0, 0),
diff --git a/sound/oss/ad1848.c b/sound/oss/ad1848.c
--- a/sound/oss/ad1848.c
+++ b/sound/oss/ad1848.c
@@ -2178,8 +2178,7 @@ void ad1848_unload(int io_base, int irq,
 		
 	if (devc != NULL)
 	{
-		if(audio_devs[dev]->portc!=NULL)
-			kfree(audio_devs[dev]->portc);
+		kfree(audio_devs[dev]->portc);
 		release_region(devc->base, 4);
 
 		if (!share_dma)
diff --git a/sound/oss/ad1889.c b/sound/oss/ad1889.c
--- a/sound/oss/ad1889.c
+++ b/sound/oss/ad1889.c
@@ -277,8 +277,7 @@ static void ad1889_free_dev(ad1889_dev_t
 
 	for (j = 0; j < AD_MAX_STATES; j++) {
 		dmabuf = &dev->state[j].dmabuf;
-		if (dmabuf->rawbuf != NULL) 
-			kfree(dmabuf->rawbuf);
+		kfree(dmabuf->rawbuf);
 	}
 
 	kfree(dev);
diff --git a/sound/oss/cmpci.c b/sound/oss/cmpci.c
--- a/sound/oss/cmpci.c
+++ b/sound/oss/cmpci.c
@@ -123,6 +123,7 @@
 #include <linux/smp_lock.h>
 #include <linux/bitops.h>
 #include <linux/wait.h>
+#include <linux/dma-mapping.h>
 
 #include <asm/io.h>
 #include <asm/page.h>
@@ -3058,7 +3059,7 @@ static int __devinit cm_probe(struct pci
 		return -ENODEV;
 	if (pcidev->irq == 0)
 		return -ENODEV;
-	i = pci_set_dma_mask(pcidev, 0xffffffff);
+	i = pci_set_dma_mask(pcidev, DMA_32BIT_MASK);
 	if (i) {
 		printk(KERN_WARNING "cmpci: architecture does not support 32bit PCI busmaster DMA\n");
 		return i;
diff --git a/sound/oss/cs46xx.c b/sound/oss/cs46xx.c
--- a/sound/oss/cs46xx.c
+++ b/sound/oss/cs46xx.c
@@ -4174,7 +4174,7 @@ static int cs_ioctl_mixdev(struct inode 
 				list_for_each(entry, &cs46xx_devs)
 				{
 					card = list_entry(entry, struct cs_card, list);
-					cs46xx_suspend(card, 0);
+					cs46xx_suspend(card, PMSG_ON);
 				}
 
 			}
@@ -5749,7 +5749,7 @@ static int cs46xx_pm_callback(struct pm_
 			case PM_SUSPEND:
 				CS_DBGOUT(CS_PM, 2, printk(KERN_INFO
 					"cs46xx: PM suspend request\n"));
-				if(cs46xx_suspend(card, 0))
+				if(cs46xx_suspend(card, PMSG_SUSPEND))
 				{
 				    CS_DBGOUT(CS_ERROR, 2, printk(KERN_INFO
 					"cs46xx: PM suspend request refused\n"));
@@ -5779,7 +5779,7 @@ static int cs46xx_suspend_tbl(struct pci
 	struct cs_card *s = PCI_GET_DRIVER_DATA(pcidev);
 	CS_DBGOUT(CS_PM | CS_FUNCTION, 2, 
 		printk(KERN_INFO "cs46xx: cs46xx_suspend_tbl request\n"));
-	cs46xx_suspend(s, 0);
+	cs46xx_suspend(s, state);
 	return 0;
 }
 
diff --git a/sound/oss/dmasound/dmasound_awacs.c b/sound/oss/dmasound/dmasound_awacs.c
--- a/sound/oss/dmasound/dmasound_awacs.c
+++ b/sound/oss/dmasound/dmasound_awacs.c
@@ -255,7 +255,7 @@ static int awacs_burgundy_read_mvolume(u
 
 static volatile struct dbdma_cmd *emergency_dbdma_cmd;
 
-#ifdef CONFIG_PMAC_PBOOK
+#ifdef CONFIG_PM
 /*
  * Stuff for restoring after a sleep.
  */
@@ -263,7 +263,7 @@ static int awacs_sleep_notify(struct pmu
 struct pmu_sleep_notifier awacs_sleep_notifier = {
 	awacs_sleep_notify, SLEEP_LEVEL_SOUND,
 };
-#endif /* CONFIG_PMAC_PBOOK */
+#endif /* CONFIG_PM */
 
 /* for (soft) sample rate translations */
 int expand_bal;		/* Balance factor for expanding (not volume!) */
@@ -671,15 +671,11 @@ static void PMacIrqCleanup(void)
 	release_OF_resource(awacs_node, 1);
 	release_OF_resource(awacs_node, 2);
 
-	if (awacs_tx_cmd_space)
-		kfree(awacs_tx_cmd_space);
-	if (awacs_rx_cmd_space)
-		kfree(awacs_rx_cmd_space);
-	if (beep_dbdma_cmd_space)
-		kfree(beep_dbdma_cmd_space);
-	if (beep_buf)
-		kfree(beep_buf);
-#ifdef CONFIG_PMAC_PBOOK
+	kfree(awacs_tx_cmd_space);
+	kfree(awacs_rx_cmd_space);
+	kfree(beep_dbdma_cmd_space);
+	kfree(beep_buf);
+#ifdef CONFIG_PM
 	pmu_unregister_sleep_notifier(&awacs_sleep_notifier);
 #endif
 }
@@ -1419,7 +1415,7 @@ load_awacs(void)
 	}
 }
 
-#ifdef CONFIG_PMAC_PBOOK
+#ifdef CONFIG_PM
 /*
  * Save state when going to sleep, restore it afterwards.
  */
@@ -1555,13 +1551,13 @@ static int awacs_sleep_notify(struct pmu
 	}
 	return PBOOK_SLEEP_OK;
 }
-#endif /* CONFIG_PMAC_PBOOK */
+#endif /* CONFIG_PM */
 
 
 /* All the burgundy functions: */
 
 /* Waits for busy flag to clear */
-inline static void
+static inline void
 awacs_burgundy_busy_wait(void)
 {
 	int count = 50; /* > 2 samples at 44k1 */
@@ -1569,7 +1565,7 @@ awacs_burgundy_busy_wait(void)
 		udelay(1) ;
 }
 
-inline static void
+static inline void
 awacs_burgundy_extend_wait(void)
 {
 	int count = 50 ; /* > 2 samples at 44k1 */
@@ -2301,8 +2297,7 @@ if (count <= 0)
 #endif
 
 	if ((write_sq.max_count + 1) > number_of_tx_cmd_buffers) {
-		if (awacs_tx_cmd_space)
-			kfree(awacs_tx_cmd_space);
+		kfree(awacs_tx_cmd_space);
 		number_of_tx_cmd_buffers = 0;
 
 		/* we need nbufs + 1 (for the loop) and we should request + 1
@@ -2360,8 +2355,7 @@ if (count <= 0)
 #endif
 
 	if ((read_sq.max_count+1) > number_of_rx_cmd_buffers ) {
-		if (awacs_rx_cmd_space)
-			kfree(awacs_rx_cmd_space);
+		kfree(awacs_rx_cmd_space);
 		number_of_rx_cmd_buffers = 0;
 
 		/* we need nbufs + 1 (for the loop) and we should request + 1 again
@@ -2805,7 +2799,7 @@ __init setup_beep(void)
 	beep_buf = (short *) kmalloc(BEEP_BUFLEN * 4, GFP_KERNEL);
 	if (beep_buf == NULL) {
 		printk(KERN_ERR "dmasound_pmac: no memory for beep buffer\n");
-		if( beep_dbdma_cmd_space ) kfree(beep_dbdma_cmd_space) ;
+		kfree(beep_dbdma_cmd_space) ;
 		return -ENOMEM ;
 	}
 	return 0 ;
@@ -3059,9 +3053,9 @@ printk("dmasound_pmac: Awacs/Screamer Co
 	if ((res=setup_beep()))
 		return res ;
 
-#ifdef CONFIG_PMAC_PBOOK
+#ifdef CONFIG_PM
 	pmu_register_sleep_notifier(&awacs_sleep_notifier);
-#endif /* CONFIG_PMAC_PBOOK */
+#endif /* CONFIG_PM */
 
 	/* Powerbooks have odd ways of enabling inputs such as
 	   an expansion-bay CD or sound from an internal modem
diff --git a/sound/oss/emu10k1/midi.c b/sound/oss/emu10k1/midi.c
--- a/sound/oss/emu10k1/midi.c
+++ b/sound/oss/emu10k1/midi.c
@@ -523,10 +523,8 @@ void emu10k1_seq_midi_close(int dev)
 	card = midi_devs[dev]->devc;
 	emu10k1_mpuout_close(card);
 
-	if (card->seq_mididev) {
-		kfree(card->seq_mididev);
-		card->seq_mididev = NULL;
-	}
+	kfree(card->seq_mididev);
+	card->seq_mididev = NULL;
 }
 
 int emu10k1_seq_midi_out(int dev, unsigned char midi_byte)
diff --git a/sound/oss/emu10k1/passthrough.c b/sound/oss/emu10k1/passthrough.c
--- a/sound/oss/emu10k1/passthrough.c
+++ b/sound/oss/emu10k1/passthrough.c
@@ -213,8 +213,7 @@ void emu10k1_pt_stop(struct emu10k1_card
 				sblive_writeptr(card, SPCS0 + i, 0, pt->old_spcs[i]);
 		}
 		pt->state = PT_STATE_INACTIVE;
-		if(pt->buf)
-			kfree(pt->buf);
+		kfree(pt->buf);
 	}
 }
 
diff --git a/sound/oss/es1370.c b/sound/oss/es1370.c
--- a/sound/oss/es1370.c
+++ b/sound/oss/es1370.c
@@ -156,11 +156,16 @@
 #include <linux/spinlock.h>
 #include <linux/gameport.h>
 #include <linux/wait.h>
+#include <linux/dma-mapping.h>
 
 #include <asm/io.h>
 #include <asm/page.h>
 #include <asm/uaccess.h>
 
+#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
+#define SUPPORT_JOYSTICK
+#endif
+
 /* --------------------------------------------------------------------- */
 
 #undef OSS_DOCUMENTED_MIXER_SEMANTICS
@@ -384,7 +389,10 @@ struct es1370_state {
 		unsigned char obuf[MIDIOUTBUF];
 	} midi;
 
+#ifdef SUPPORT_JOYSTICK
 	struct gameport *gameport;
+#endif
+
 	struct semaphore sem;
 };
 
@@ -2553,10 +2561,55 @@ static struct initvol {
 	{ SOUND_MIXER_WRITE_OGAIN, 0x4040 }
 };
 
+#ifdef SUPPORT_JOYSTICK
+
+static int __devinit es1370_register_gameport(struct es1370_state *s)
+{
+	struct gameport *gp;
+
+	if (!request_region(0x200, JOY_EXTENT, "es1370")) {
+		printk(KERN_ERR "es1370: joystick io port 0x200 in use\n");
+		return -EBUSY;
+	}
+
+	s->gameport = gp = gameport_allocate_port();
+	if (!gp) {
+		printk(KERN_ERR "es1370: can not allocate memory for gameport\n");
+		release_region(0x200, JOY_EXTENT);
+		return -ENOMEM;
+	}
+
+	gameport_set_name(gp, "ESS1370");
+	gameport_set_phys(gp, "pci%s/gameport0", pci_name(s->dev));
+	gp->dev.parent = &s->dev->dev;
+	gp->io = 0x200;
+
+	s->ctrl |= CTRL_JYSTK_EN;
+	outl(s->ctrl, s->io + ES1370_REG_CONTROL);
+
+	gameport_register_port(gp);
+
+	return 0;
+}
+
+static inline void es1370_unregister_gameport(struct es1370_state *s)
+{
+	if (s->gameport) {
+		int gpio = s->gameport->io;
+		gameport_unregister_port(s->gameport);
+		release_region(gpio, JOY_EXTENT);
+
+	}
+}
+
+#else
+static inline int es1370_register_gameport(struct es1370_state *s) { return -ENOSYS; }
+static inline void es1370_unregister_gameport(struct es1370_state *s) { }
+#endif /* SUPPORT_JOYSTICK */
+
 static int __devinit es1370_probe(struct pci_dev *pcidev, const struct pci_device_id *pciid)
 {
 	struct es1370_state *s;
-	struct gameport *gp = NULL;
 	mm_segment_t fs;
 	int i, val, ret;
 
@@ -2569,7 +2622,7 @@ static int __devinit es1370_probe(struct
 		return -ENODEV;
 	if (pcidev->irq == 0) 
 		return -ENODEV;
-	i = pci_set_dma_mask(pcidev, 0xffffffff);
+	i = pci_set_dma_mask(pcidev, DMA_32BIT_MASK);
 	if (i) {
 		printk(KERN_WARNING "es1370: architecture does not support 32bit PCI busmaster DMA\n");
 		return i;
@@ -2605,28 +2658,14 @@ static int __devinit es1370_probe(struct
 	/* note: setting CTRL_SERR_DIS is reported to break
 	 * mic bias setting (by Kim.Berts@fisub.mail.abb.com) */
 	s->ctrl = CTRL_CDC_EN | (DAC2_SRTODIV(8000) << CTRL_SH_PCLKDIV) | (1 << CTRL_SH_WTSRSEL);
-	if (!request_region(0x200, JOY_EXTENT, "es1370")) {
-		printk(KERN_ERR "es1370: joystick io port 0x200 in use\n");
-	} else if (!(s->gameport = gp = gameport_allocate_port())) {
-		printk(KERN_ERR "es1370: can not allocate memory for gameport\n");
-		release_region(0x200, JOY_EXTENT);
-	} else {
-		gameport_set_name(gp, "ESS1370");
-		gameport_set_phys(gp, "pci%s/gameport0", pci_name(s->dev));
-		gp->dev.parent = &s->dev->dev;
-		gp->io = 0x200;
-		s->ctrl |= CTRL_JYSTK_EN;
-	}
 	if (lineout[devindex])
 		s->ctrl |= CTRL_XCTL0;
 	if (micbias[devindex])
 		s->ctrl |= CTRL_XCTL1;
 	s->sctrl = 0;
-	printk(KERN_INFO "es1370: found adapter at io %#lx irq %u\n"
-	       KERN_INFO "es1370: features: joystick %s, line %s, mic impedance %s\n",
-	       s->io, s->irq, (s->ctrl & CTRL_JYSTK_EN) ? "on" : "off",
-	       (s->ctrl & CTRL_XCTL0) ? "out" : "in",
-		       (s->ctrl & CTRL_XCTL1) ? "1" : "0");
+	printk(KERN_INFO "es1370: adapter at io %#lx irq %u, line %s, mic impedance %s\n",
+	       s->io, s->irq, (s->ctrl & CTRL_XCTL0) ? "out" : "in",
+	       (s->ctrl & CTRL_XCTL1) ? "1" : "0");
 	/* register devices */
 	if ((s->dev_audio = register_sound_dsp(&es1370_audio_fops, -1)) < 0) {
 		ret = s->dev_audio;
@@ -2672,9 +2711,7 @@ static int __devinit es1370_probe(struct
 	}
 	set_fs(fs);
 
-	/* register gameport */
-	if (gp)
-		gameport_register_port(gp);
+	es1370_register_gameport(s);
 
 	/* store it in the driver field */
 	pci_set_drvdata(pcidev, s);
@@ -2696,10 +2733,6 @@ static int __devinit es1370_probe(struct
  err_dev1:
 	printk(KERN_ERR "es1370: cannot register misc device\n");
 	free_irq(s->irq, s);
-	if (s->gameport) {
-		release_region(s->gameport->io, JOY_EXTENT);
-		gameport_free_port(s->gameport);
-	}
  err_irq:
 	release_region(s->io, ES1370_EXTENT);
  err_region:
@@ -2718,11 +2751,7 @@ static void __devexit es1370_remove(stru
 	outl(0, s->io+ES1370_REG_SERIAL_CONTROL); /* clear serial interrupts */
 	synchronize_irq(s->irq);
 	free_irq(s->irq, s);
-	if (s->gameport) {
-		int gpio = s->gameport->io;
-		gameport_unregister_port(s->gameport);
-		release_region(gpio, JOY_EXTENT);
-	}
+	es1370_unregister_gameport(s);
 	release_region(s->io, ES1370_EXTENT);
 	unregister_sound_dsp(s->dev_audio);
 	unregister_sound_mixer(s->dev_mixer);
diff --git a/sound/oss/es1371.c b/sound/oss/es1371.c
--- a/sound/oss/es1371.c
+++ b/sound/oss/es1371.c
@@ -128,11 +128,16 @@
 #include <linux/ac97_codec.h>
 #include <linux/gameport.h>
 #include <linux/wait.h>
+#include <linux/dma-mapping.h>
 
 #include <asm/io.h>
 #include <asm/page.h>
 #include <asm/uaccess.h>
 
+#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
+#define SUPPORT_JOYSTICK
+#endif
+
 /* --------------------------------------------------------------------- */
 
 #undef OSS_DOCUMENTED_MIXER_SEMANTICS
@@ -453,7 +458,10 @@ struct es1371_state {
 		unsigned char obuf[MIDIOUTBUF];
 	} midi;
 
+#ifdef SUPPORT_JOYSTICK
 	struct gameport *gameport;
+#endif
+
 	struct semaphore sem;
 };
 
@@ -2786,12 +2794,63 @@ static struct
 	{ PCI_ANY_ID, PCI_ANY_ID }
 };
 
+#ifdef SUPPORT_JOYSTICK
+
+static int __devinit es1371_register_gameport(struct es1371_state *s)
+{
+	struct gameport *gp;
+	int gpio;
+
+	for (gpio = 0x218; gpio >= 0x200; gpio -= 0x08)
+		if (request_region(gpio, JOY_EXTENT, "es1371"))
+			break;
+
+	if (gpio < 0x200) {
+		printk(KERN_ERR PFX "no free joystick address found\n");
+		return -EBUSY;
+	}
+
+	s->gameport = gp = gameport_allocate_port();
+	if (!gp) {
+		printk(KERN_ERR PFX "can not allocate memory for gameport\n");
+		release_region(gpio, JOY_EXTENT);
+		return -ENOMEM;
+	}
+
+	gameport_set_name(gp, "ESS1371 Gameport");
+	gameport_set_phys(gp, "isa%04x/gameport0", gpio);
+	gp->dev.parent = &s->dev->dev;
+	gp->io = gpio;
+
+	s->ctrl |= CTRL_JYSTK_EN | (((gpio >> 3) & CTRL_JOY_MASK) << CTRL_JOY_SHIFT);
+	outl(s->ctrl, s->io + ES1371_REG_CONTROL);
+
+	gameport_register_port(gp);
+
+	return 0;
+}
+
+static inline void es1371_unregister_gameport(struct es1371_state *s)
+{
+	if (s->gameport) {
+		int gpio = s->gameport->io;
+		gameport_unregister_port(s->gameport);
+		release_region(gpio, JOY_EXTENT);
+
+	}
+}
+
+#else
+static inline int es1371_register_gameport(struct es1371_state *s) { return -ENOSYS; }
+static inline void es1371_unregister_gameport(struct es1371_state *s) { }
+#endif /* SUPPORT_JOYSTICK */
+
+
 static int __devinit es1371_probe(struct pci_dev *pcidev, const struct pci_device_id *pciid)
 {
 	struct es1371_state *s;
-	struct gameport *gp;
 	mm_segment_t fs;
-	int i, gpio, val, res = -1;
+	int i, val, res = -1;
 	int idx;
 	unsigned long tmo;
 	signed long tmo2;
@@ -2804,7 +2863,7 @@ static int __devinit es1371_probe(struct
 		return -ENODEV;
 	if (pcidev->irq == 0) 
 		return -ENODEV;
-	i = pci_set_dma_mask(pcidev, 0xffffffff);
+	i = pci_set_dma_mask(pcidev, DMA_32BIT_MASK);
 	if (i) {
 		printk(KERN_WARNING "es1371: architecture does not support 32bit PCI busmaster DMA\n");
 		return i;
@@ -2882,23 +2941,6 @@ static int __devinit es1371_probe(struct
 		}
 	}
 
-	for (gpio = 0x218; gpio >= 0x200; gpio -= 0x08)
-		if (request_region(gpio, JOY_EXTENT, "es1371"))
-			break;
-
-	if (gpio < 0x200) {
-		printk(KERN_ERR PFX "no free joystick address found\n");
-	} else if (!(s->gameport = gp = gameport_allocate_port())) {
-		printk(KERN_ERR PFX "can not allocate memory for gameport\n");
-		release_region(gpio, JOY_EXTENT);
-	} else {
-		gameport_set_name(gp, "ESS1371 Gameport");
-		gameport_set_phys(gp, "isa%04x/gameport0", gpio);
-		gp->dev.parent = &s->dev->dev;
-		gp->io = gpio;
-		s->ctrl |= CTRL_JYSTK_EN | (((gpio >> 3) & CTRL_JOY_MASK) << CTRL_JOY_SHIFT);
-	}
-
 	s->sctrl = 0;
 	cssr = 0;
 	s->spdif_volume = -1;
@@ -2968,9 +3010,7 @@ static int __devinit es1371_probe(struct
 	/* turn on S/PDIF output driver if requested */
 	outl(cssr, s->io+ES1371_REG_STATUS);
 
-	/* register gameport */
-	if (s->gameport)
-		gameport_register_port(s->gameport);
+	es1371_register_gameport(s);
 
 	/* store it in the driver field */
 	pci_set_drvdata(pcidev, s);
@@ -2979,13 +3019,9 @@ static int __devinit es1371_probe(struct
 	/* increment devindex */
 	if (devindex < NR_DEVICE-1)
 		devindex++;
-       	return 0;
+	return 0;
 
  err_gp:
-	if (s->gameport) {
-		release_region(s->gameport->io, JOY_EXTENT);
-		gameport_free_port(s->gameport);
-	}
 #ifdef ES1371_DEBUG
 	if (s->ps)
 		remove_proc_entry("es1371", NULL);
@@ -3024,11 +3060,7 @@ static void __devexit es1371_remove(stru
 	outl(0, s->io+ES1371_REG_SERIAL_CONTROL); /* clear serial interrupts */
 	synchronize_irq(s->irq);
 	free_irq(s->irq, s);
-	if (s->gameport) {
-		int gpio = s->gameport->io;
-		gameport_unregister_port(s->gameport);
-		release_region(gpio, JOY_EXTENT);
-	}
+	es1371_unregister_gameport(s);
 	release_region(s->io, ES1371_EXTENT);
 	unregister_sound_dsp(s->dev_audio);
 	unregister_sound_mixer(s->codec->dev_mixer);
diff --git a/sound/oss/esssolo1.c b/sound/oss/esssolo1.c
--- a/sound/oss/esssolo1.c
+++ b/sound/oss/esssolo1.c
@@ -104,6 +104,7 @@
 #include <linux/smp_lock.h>
 #include <linux/gameport.h>
 #include <linux/wait.h>
+#include <linux/dma-mapping.h>
 
 #include <asm/io.h>
 #include <asm/page.h>
@@ -149,6 +150,10 @@
 
 #define FMODE_DMFM 0x10
 
+#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
+#define SUPPORT_JOYSTICK 1
+#endif
+
 static struct pci_driver solo1_driver;
 
 /* --------------------------------------------------------------------- */
@@ -226,7 +231,9 @@ struct solo1_state {
 		unsigned char obuf[MIDIOUTBUF];
 	} midi;
 
+#if SUPPORT_JOYSTICK
 	struct gameport *gameport;
+#endif
 };
 
 /* --------------------------------------------------------------------- */
@@ -2280,6 +2287,7 @@ solo1_resume(struct pci_dev *pci_dev) {
 	return 0;
 }
 
+#ifdef SUPPORT_JOYSTICK
 static int __devinit solo1_register_gameport(struct solo1_state *s, int io_port)
 {
 	struct gameport *gp;
@@ -2306,6 +2314,19 @@ static int __devinit solo1_register_game
 	return 0;
 }
 
+static inline void solo1_unregister_gameport(struct solo1_state *s)
+{
+	if (s->gameport) {
+		int gpio = s->gameport->io;
+		gameport_unregister_port(s->gameport);
+		release_region(gpio, GAMEPORT_EXTENT);
+	}
+}
+#else
+static inline int solo1_register_gameport(struct solo1_state *s, int io_port) { return -ENOSYS; }
+static inline void solo1_unregister_gameport(struct solo1_state *s) { }
+#endif /* SUPPORT_JOYSTICK */
+
 static int __devinit solo1_probe(struct pci_dev *pcidev, const struct pci_device_id *pciid)
 {
 	struct solo1_state *s;
@@ -2326,7 +2347,7 @@ static int __devinit solo1_probe(struct 
 	 * to 24 bits first, then 32 bits (playback only) if that fails.
 	 */
 	if (pci_set_dma_mask(pcidev, 0x00ffffff) &&
-	    pci_set_dma_mask(pcidev, 0xffffffff)) {
+	    pci_set_dma_mask(pcidev, DMA_32BIT_MASK)) {
 		printk(KERN_WARNING "solo1: architecture does not support 24bit or 32bit PCI busmaster DMA\n");
 		return -ENODEV;
 	}
@@ -2437,11 +2458,7 @@ static void __devexit solo1_remove(struc
 	synchronize_irq(s->irq);
 	pci_write_config_word(s->dev, 0x60, 0); /* turn off DDMA controller address space */
 	free_irq(s->irq, s);
-	if (s->gameport) {
-		int gpio = s->gameport->io;
-		gameport_unregister_port(s->gameport);
-		release_region(gpio, GAMEPORT_EXTENT);
-	}
+	solo1_unregister_gameport(s);
 	release_region(s->iobase, IOBASE_EXTENT);
 	release_region(s->sbbase+FMSYNTH_EXTENT, SBBASE_EXTENT-FMSYNTH_EXTENT);
 	release_region(s->ddmabase, DDMABASE_EXTENT);
diff --git a/sound/oss/i810_audio.c b/sound/oss/i810_audio.c
--- a/sound/oss/i810_audio.c
+++ b/sound/oss/i810_audio.c
@@ -3430,9 +3430,9 @@ out_iospace:
 		release_mem_region(card->iobase_mmio_phys, 256);
 	}
 out_pio:	
-	release_region(card->iobase, 64);
-out_region2:
 	release_region(card->ac97base, 256);
+out_region2:
+	release_region(card->iobase, 64);
 out_region1:
 	pci_free_consistent(pci_dev, sizeof(struct i810_channel)*NR_HW_CH,
 	    card->channel, card->chandma);
diff --git a/sound/oss/mad16.c b/sound/oss/mad16.c
--- a/sound/oss/mad16.c
+++ b/sound/oss/mad16.c
@@ -50,9 +50,12 @@
 #include "sb.h"
 #include "mpu401.h"
 
+#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
+#define SUPPORT_JOYSTICK 1
+#endif
+
 static int      mad16_conf;
 static int      mad16_cdsel;
-static struct gameport *gameport;
 static DEFINE_SPINLOCK(lock);
 
 #define C928	1
@@ -902,6 +905,10 @@ static int __initdata irq_map[16] =
 	-1, -1, -1, -1
 };
 
+#ifdef SUPPORT_JOYSTICK
+
+static struct gameport *gameport;
+
 static int __devinit mad16_register_gameport(int io_port)
 {
 	if (!request_region(io_port, 1, "mad16 gameport")) {
@@ -925,6 +932,20 @@ static int __devinit mad16_register_game
 	return 0;
 }
 
+static inline void mad16_unregister_gameport(void)
+{
+	if (gameport) {
+		/* the gameport was initialized so we must free it up */
+		gameport_unregister_port(gameport);
+		gameport = NULL;
+		release_region(0x201, 1);
+	}
+}
+#else
+static inline int mad16_register_gameport(int io_port) { return -ENOSYS; }
+static inline void mad16_unregister_gameport(void) { }
+#endif
+
 static int __devinit init_mad16(void)
 {
 	int dmatype = 0;
@@ -1060,12 +1081,7 @@ static void __exit cleanup_mad16(void)
 {
 	if (found_mpu)
 		unload_mad16_mpu(&cfg_mpu);
-	if (gameport) {
-		/* the gameport was initialized so we must free it up */
-		gameport_unregister_port(gameport);
-		gameport = NULL;
-		release_region(0x201, 1);
-	}
+	mad16_unregister_gameport();
 	unload_mad16(&cfg);
 	release_region(MC0_PORT, 12);
 }
diff --git a/sound/oss/maestro.c b/sound/oss/maestro.c
--- a/sound/oss/maestro.c
+++ b/sound/oss/maestro.c
@@ -2356,7 +2356,7 @@ ess_read(struct file *file, char __user 
 	}
 
 rec_return_free:
-	if(combbuf) kfree(combbuf);
+	kfree(combbuf);
 	return ret;
 }
 
diff --git a/sound/oss/mpu401.c b/sound/oss/mpu401.c
--- a/sound/oss/mpu401.c
+++ b/sound/oss/mpu401.c
@@ -1240,8 +1240,7 @@ void unload_mpu401(struct address_info *
 		p=mpu401_synth_operations[n];
 		sound_unload_mididev(n);
 		sound_unload_timerdev(hw_config->slots[2]);
-		if(p)
-			kfree(p);
+		kfree(p);
 	}
 }
 
diff --git a/sound/oss/nm256.h b/sound/oss/nm256.h
--- a/sound/oss/nm256.h
+++ b/sound/oss/nm256.h
@@ -128,9 +128,6 @@ struct nm256_info 
     struct nm256_info *next_card;
 };
 
-/* Debug flag--bigger numbers mean more output. */
-extern int nm256_debug;
-
 /* The BIOS signature. */
 #define NM_SIGNATURE 0x4e4d0000
 /* Signature mask. */
@@ -284,7 +281,7 @@ nm256_readBuffer8 (struct nm256_info *ca
 }
 
 /* Returns a non-zero value if we should use the coefficient cache. */
-extern int nm256_cachedCoefficients (struct nm256_info *card);
+static int nm256_cachedCoefficients (struct nm256_info *card);
 
 #endif
 
diff --git a/sound/oss/nm256_audio.c b/sound/oss/nm256_audio.c
--- a/sound/oss/nm256_audio.c
+++ b/sound/oss/nm256_audio.c
@@ -28,12 +28,13 @@
 #include <linux/delay.h>
 #include <linux/spinlock.h>
 #include "sound_config.h"
-#include "nm256.h"
-#include "nm256_coeff.h"
 
-int nm256_debug;
+static int nm256_debug;
 static int force_load;
 
+#include "nm256.h"
+#include "nm256_coeff.h"
+
 /* 
  * The size of the playback reserve.  When the playback buffer has less
  * than NM256_PLAY_WMARK_SIZE bytes to output, we request a new
@@ -138,7 +139,7 @@ static int usecache;
 static int buffertop;
 
 /* Check to see if we're using the bank of cached coefficients. */
-int
+static int
 nm256_cachedCoefficients (struct nm256_info *card)
 {
     return usecache;
diff --git a/sound/oss/nm256_coeff.h b/sound/oss/nm256_coeff.h
--- a/sound/oss/nm256_coeff.h
+++ b/sound/oss/nm256_coeff.h
@@ -4650,7 +4650,7 @@ nm256_loadAllCoefficients (struct nm256_
     card->coeffsCurrent = 1;
 }
 
-void
+static void
 nm256_loadCoefficient (struct nm256_info *card, int which, int number)
 {
     static u16 addrs[3] = { 0x1c, 0x21c, 0x408 };
diff --git a/sound/oss/pss.c b/sound/oss/pss.c
--- a/sound/oss/pss.c
+++ b/sound/oss/pss.c
@@ -714,7 +714,7 @@ static int __init attach_pss(struct addr
 	 
 	disable_all_emulations();
 
-#if YOU_REALLY_WANT_TO_ALLOCATE_THESE_RESOURCES
+#ifdef YOU_REALLY_WANT_TO_ALLOCATE_THESE_RESOURCES
 	if (sound_alloc_dma(hw_config->dma, "PSS"))
 	{
 		printk("pss.c: Can't allocate DMA channel.\n");
diff --git a/sound/oss/rme96xx.c b/sound/oss/rme96xx.c
--- a/sound/oss/rme96xx.c
+++ b/sound/oss/rme96xx.c
@@ -807,7 +807,7 @@ static void* busmaster_malloc(int size) 
                 struct page* page, *last_page;
 
                 page = virt_to_page(buf);
-                last_page = virt_to_page(buf + (1 << pg));
+                last_page = page + (1 << pg);
                 DBG(printk("setting reserved bit\n"));
                 while (page < last_page) {
 			SetPageReserved(page);
@@ -1750,9 +1750,7 @@ static unsigned int rme96xx_poll(struct 
 
 
 static struct file_operations rme96xx_audio_fops = {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
 	.owner	 = THIS_MODULE,
-#endif
 	.read	 = rme96xx_read,
 	.write	 = rme96xx_write,
 	.poll	 = rme96xx_poll,
@@ -1852,9 +1850,7 @@ static int rme96xx_mixer_release(struct 
 }
 
 static /*const*/ struct file_operations rme96xx_mixer_fops = {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
 	.owner	 = THIS_MODULE,
-#endif
 	.ioctl	 = rme96xx_mixer_ioctl,
 	.open	 = rme96xx_mixer_open,
 	.release = rme96xx_mixer_release,
diff --git a/sound/oss/sb_common.c b/sound/oss/sb_common.c
--- a/sound/oss/sb_common.c
+++ b/sound/oss/sb_common.c
@@ -915,8 +915,8 @@ void sb_dsp_unload(struct address_info *
 	}
 	else
 		release_region(hw_config->io_base, 16);
-	if(detected_devc)
-		kfree(detected_devc);
+
+	kfree(detected_devc);
 }
 
 /*
diff --git a/sound/oss/sonicvibes.c b/sound/oss/sonicvibes.c
--- a/sound/oss/sonicvibes.c
+++ b/sound/oss/sonicvibes.c
@@ -122,6 +122,9 @@
 
 #include "dm.h"
 
+#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
+#define SUPPORT_JOYSTICK 1
+#endif
 
 /* --------------------------------------------------------------------- */
 
@@ -365,7 +368,9 @@ struct sv_state {
 		unsigned char obuf[MIDIOUTBUF];
 	} midi;
 
+#if SUPPORT_JOYSTICK
 	struct gameport *gameport;
+#endif
 };
 
 /* --------------------------------------------------------------------- */
@@ -2485,6 +2490,7 @@ static struct initvol {
 #define RSRCISIOREGION(dev,num) (pci_resource_start((dev), (num)) != 0 && \
 				 (pci_resource_flags((dev), (num)) & IORESOURCE_IO))
 
+#ifdef SUPPORT_JOYSTICK
 static int __devinit sv_register_gameport(struct sv_state *s, int io_port)
 {
 	struct gameport *gp;
@@ -2511,6 +2517,19 @@ static int __devinit sv_register_gamepor
 	return 0;
 }
 
+static inline void sv_unregister_gameport(struct sv_state *s)
+{
+	if (s->gameport) {
+		int gpio = s->gameport->io;
+		gameport_unregister_port(s->gameport);
+		release_region(gpio, SV_EXTENT_GAME);
+	}
+}
+#else
+static inline int sv_register_gameport(struct sv_state *s, int io_port) { return -ENOSYS; }
+static inline void sv_unregister_gameport(struct sv_state *s) { }
+#endif /* SUPPORT_JOYSTICK */
+
 static int __devinit sv_probe(struct pci_dev *pcidev, const struct pci_device_id *pciid)
 {
 	static char __devinitdata sv_ddma_name[] = "S3 Inc. SonicVibes DDMA Controller";
@@ -2711,11 +2730,7 @@ static void __devexit sv_remove(struct p
 	/*outb(0, s->iodmaa + SV_DMA_RESET);*/
 	/*outb(0, s->iodmac + SV_DMA_RESET);*/
 	free_irq(s->irq, s);
-	if (s->gameport) {
-		int gpio = s->gameport->io;
-		gameport_unregister_port(s->gameport);
-		release_region(gpio, SV_EXTENT_GAME);
-	}
+	sv_unregister_gameport(s);
 	release_region(s->iodmac, SV_EXTENT_DMA);
 	release_region(s->iodmaa, SV_EXTENT_DMA);
 	release_region(s->ioenh, SV_EXTENT_ENH);
diff --git a/sound/oss/soundcard.c b/sound/oss/soundcard.c
--- a/sound/oss/soundcard.c
+++ b/sound/oss/soundcard.c
@@ -73,7 +73,7 @@ static char     dma_alloc_map[MAX_DMA_CH
 
 
 unsigned long seq_time = 0;	/* Time for /dev/sequencer */
-extern struct class_simple *sound_class;
+extern struct class *sound_class;
 
 /*
  * Table for configurable mixer volume handling
@@ -567,9 +567,9 @@ static int __init oss_init(void)
 		devfs_mk_cdev(MKDEV(SOUND_MAJOR, dev_list[i].minor),
 				S_IFCHR | dev_list[i].mode,
 				"sound/%s", dev_list[i].name);
-		class_simple_device_add(sound_class, 
-					MKDEV(SOUND_MAJOR, dev_list[i].minor),
-					NULL, "%s", dev_list[i].name);
+		class_device_create(sound_class,
+				    MKDEV(SOUND_MAJOR, dev_list[i].minor),
+				    NULL, "%s", dev_list[i].name);
 
 		if (!dev_list[i].num)
 			continue;
@@ -579,10 +579,9 @@ static int __init oss_init(void)
 						dev_list[i].minor + (j*0x10)),
 					S_IFCHR | dev_list[i].mode,
 					"sound/%s%d", dev_list[i].name, j);
-			class_simple_device_add(sound_class,
-					MKDEV(SOUND_MAJOR, dev_list[i].minor + (j*0x10)),
-					NULL,
-					"%s%d", dev_list[i].name, j);
+			class_device_create(sound_class,
+					    MKDEV(SOUND_MAJOR, dev_list[i].minor + (j*0x10)),
+					    NULL, "%s%d", dev_list[i].name, j);
 		}
 	}
 
@@ -598,12 +597,12 @@ static void __exit oss_cleanup(void)
 
 	for (i = 0; i < sizeof (dev_list) / sizeof *dev_list; i++) {
 		devfs_remove("sound/%s", dev_list[i].name);
-		class_simple_device_remove(MKDEV(SOUND_MAJOR, dev_list[i].minor));
+		class_device_destroy(sound_class, MKDEV(SOUND_MAJOR, dev_list[i].minor));
 		if (!dev_list[i].num)
 			continue;
 		for (j = 1; j < *dev_list[i].num; j++) {
 			devfs_remove("sound/%s%d", dev_list[i].name, j);
-			class_simple_device_remove(MKDEV(SOUND_MAJOR, dev_list[i].minor + (j*0x10)));
+			class_device_destroy(sound_class, MKDEV(SOUND_MAJOR, dev_list[i].minor + (j*0x10)));
 		}
 	}
 	
diff --git a/sound/oss/sscape.c b/sound/oss/sscape.c
--- a/sound/oss/sscape.c
+++ b/sound/oss/sscape.c
@@ -991,7 +991,6 @@ static void __init sscape_pnp_init_hw(ss
 	unsigned i;
 	static	char code_file_name[23] = "/sndscape/sndscape.cox";
 	
-	int sscape_sb_enable		= 0;
 	int sscape_joystic_enable	= 0x7f;
 	int sscape_mic_enable		= 0;
 	int sscape_ext_midi		= 0;		
@@ -1015,14 +1014,9 @@ static void __init sscape_pnp_init_hw(ss
 	sscape_write( devc, 2, devc->ic_type == IC_ODIE ? 0x70 : 0x40);
 	sscape_write( devc, 3, ( devc -> dma << 4) | 0x80);
 
-	if ( sscape_sb_enable )
-		sscape_write (devc, 4, 0xF0 | (sb_irq << 2) | midi_irq);
-	else	
-		sscape_write (devc, 4, 0xF0 | (midi_irq<<2) | midi_irq);
+	sscape_write (devc, 4, 0xF0 | (midi_irq<<2) | midi_irq);
 
 	i = 0x10; //sscape_read(devc, 9) & (devc->ic_type == IC_ODIE ? 0xf0 : 0xc0);
-	if ( sscape_sb_enable )
-		i |= devc->ic_type == IC_ODIE ? 0x05 : 0x07;	    
 	if (sscape_joystic_enable) i |= 8;
 	
 	sscape_write (devc, 9, i);
diff --git a/sound/oss/trident.c b/sound/oss/trident.c
--- a/sound/oss/trident.c
+++ b/sound/oss/trident.c
@@ -228,6 +228,10 @@
 
 #define DRIVER_VERSION "0.14.10j-2.6"
 
+#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
+#define SUPPORT_JOYSTICK 1
+#endif
+
 /* magic numbers to protect our data structures */
 #define TRIDENT_CARD_MAGIC	0x5072696E	/* "Prin" */
 #define TRIDENT_STATE_MAGIC	0x63657373	/* "cess" */
@@ -4252,24 +4256,25 @@ trident_ac97_init(struct trident_card *c
 	return num_ac97 + 1;
 }
 
+#ifdef SUPPORT_JOYSTICK
 /* Gameport functions for the cards ADC gameport */
 
-static unsigned char
-trident_game_read(struct gameport *gameport)
+static unsigned char trident_game_read(struct gameport *gameport)
 {
 	struct trident_card *card = gameport->port_data;
+
 	return inb(TRID_REG(card, T4D_GAME_LEG));
 }
 
-static void
-trident_game_trigger(struct gameport *gameport)
+static void trident_game_trigger(struct gameport *gameport)
 {
 	struct trident_card *card = gameport->port_data;
+
 	outb(0xff, TRID_REG(card, T4D_GAME_LEG));
 }
 
-static int
-trident_game_cooked_read(struct gameport *gameport, int *axes, int *buttons)
+static int trident_game_cooked_read(struct gameport *gameport,
+				    int *axes, int *buttons)
 {
 	struct trident_card *card = gameport->port_data;
 	int i;
@@ -4285,8 +4290,7 @@ trident_game_cooked_read(struct gameport
 	return 0;
 }
 
-static int
-trident_game_open(struct gameport *gameport, int mode)
+static int trident_game_open(struct gameport *gameport, int mode)
 {
 	struct trident_card *card = gameport->port_data;
 
@@ -4305,8 +4309,7 @@ trident_game_open(struct gameport *gamep
 	return 0;
 }
 
-static int __devinit
-trident_register_gameport(struct trident_card *card)
+static int __devinit trident_register_gameport(struct trident_card *card)
 {
 	struct gameport *gp;
 
@@ -4330,6 +4333,17 @@ trident_register_gameport(struct trident
 	return 0;
 }
 
+static inline void trident_unregister_gameport(struct trident_card *card)
+{
+	if (card->gameport)
+		gameport_unregister_port(card->gameport);
+}
+
+#else
+static inline int trident_register_gameport(struct trident_card *card) { return -ENOSYS; }
+static inline void trident_unregister_gameport(struct trident_card *card) { }
+#endif /* SUPPORT_JOYSTICK */
+
 /* install the driver, we do not allocate hardware channel nor DMA buffer */ 
 /* now, they are defered until "ACCESS" time (in prog_dmabuf called by */ 
 /* open/read/write/ioctl/mmap) */
@@ -4569,8 +4583,7 @@ trident_remove(struct pci_dev *pci_dev)
 	}
 
 	/* Unregister gameport */
-	if (card->gameport)
-		gameport_unregister_port(card->gameport);
+	trident_unregister_gameport(card);
 
 	/* Kill interrupts, and SP/DIF */
 	trident_disable_loop_interrupts(card);
diff --git a/sound/oss/v_midi.c b/sound/oss/v_midi.c
--- a/sound/oss/v_midi.c
+++ b/sound/oss/v_midi.c
@@ -39,8 +39,6 @@ static void *midi_mem = NULL;
  */
 
 
-void            (*midi_input_intr) (int dev, unsigned char data);
-
 static int v_midi_open (int dev, int mode,
 	      void            (*input) (int dev, unsigned char data),
 	      void            (*output) (int dev)
diff --git a/sound/oss/via82cxxx_audio.c b/sound/oss/via82cxxx_audio.c
--- a/sound/oss/via82cxxx_audio.c
+++ b/sound/oss/via82cxxx_audio.c
@@ -35,6 +35,7 @@
 #include <linux/smp_lock.h>
 #include <linux/ioport.h>
 #include <linux/delay.h>
+#include <linux/dma-mapping.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
 #include <asm/semaphore.h>
@@ -3391,10 +3392,10 @@ static int __devinit via_init_one (struc
 	if (rc)
 		goto err_out_disable;
 
-	rc = pci_set_dma_mask(pdev, 0xffffffffULL);
+	rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
 	if (rc)
 		goto err_out_res;
-	rc = pci_set_consistent_dma_mask(pdev, 0xffffffffULL);
+	rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
 	if (rc)
 		goto err_out_res;
 
diff --git a/sound/oss/vidc.h b/sound/oss/vidc.h
--- a/sound/oss/vidc.h
+++ b/sound/oss/vidc.h
@@ -10,10 +10,6 @@
  *  VIDC sound function prototypes
  */
 
-/* vidc.c */
-
-extern int vidc_busy;
-
 /* vidc_fill.S */
 
 /*
diff --git a/sound/oss/wavfront.c b/sound/oss/wavfront.c
--- a/sound/oss/wavfront.c
+++ b/sound/oss/wavfront.c
@@ -151,11 +151,11 @@ static int (*midi_load_patch) (int devno
 
 /*** Module-accessible parameters ***************************************/
 
-int wf_raw;     /* we normally check for "raw state" to firmware
-		   loading. if set, then during driver loading, the
-		   state of the board is ignored, and we reset the
-		   board and load the firmware anyway.
-		*/
+static int wf_raw;     /* we normally check for "raw state" to firmware
+			   loading. if set, then during driver loading, the
+			   state of the board is ignored, and we reset the
+			   board and load the firmware anyway.
+			*/
 		   
 static int fx_raw = 1; /* if this is zero, we'll leave the FX processor in
 		          whatever state it is when the driver is loaded.
@@ -2911,7 +2911,7 @@ int __init detect_wffx (void)
 	return 0;
 }	
 
-void
+static void
 wffx_mute (int onoff)
     
 {
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig
--- a/sound/pci/Kconfig
+++ b/sound/pci/Kconfig
@@ -274,6 +274,19 @@ config SND_HDSP
 	  To compile this driver as a module, choose M here: the module
 	  will be called snd-hdsp.
 
+config SND_HDSPM
+	tristate "RME Hammerfall DSP MADI"
+	depends on SND
+	select SND_HWDEP
+	select SND_RAWMIDI
+	select SND_PCM
+	help
+	  Say Y here to include support for RME Hammerfall DSP MADI
+	  soundcards.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-hdspm.
+
 config SND_TRIDENT
 	tristate "Trident 4D-Wave DX/NX; SiS 7018"
 	depends on SND
@@ -301,7 +314,7 @@ config SND_YMFPCI
 
 config SND_ALS4000
 	tristate "Avance Logic ALS4000"
-	depends on SND
+	depends on SND && ISA_DMA_API
 	select SND_OPL3_LIB
 	select SND_MPU401_UART
 	select SND_PCM
diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c
--- a/sound/pci/ac97/ac97_codec.c
+++ b/sound/pci/ac97/ac97_codec.c
@@ -120,6 +120,7 @@ static const ac97_codec_id_t snd_ac97_co
 { 0x414c4770, 0xfffffff0, "ALC203",		NULL,		NULL },
 { 0x434d4941, 0xffffffff, "CMI9738",		patch_cm9738,	NULL },
 { 0x434d4961, 0xffffffff, "CMI9739",		patch_cm9739,	NULL },
+{ 0x434d4969, 0xffffffff, "CMI9780",		patch_cm9780,	NULL },
 { 0x434d4978, 0xffffffff, "CMI9761",		patch_cm9761,	NULL },
 { 0x434d4982, 0xffffffff, "CMI9761",		patch_cm9761,	NULL },
 { 0x434d4983, 0xffffffff, "CMI9761",		patch_cm9761,	NULL },
@@ -149,7 +150,7 @@ static const ac97_codec_id_t snd_ac97_co
 { 0x4e534331, 0xffffffff, "LM4549",		NULL,		NULL },
 { 0x4e534350, 0xffffffff, "LM4550",		NULL,		NULL },
 { 0x50534304, 0xffffffff, "UCB1400",		NULL,		NULL },
-{ 0x53494c20, 0xffffffe0, "Si3036,8",		NULL,		mpatch_si3036 },
+{ 0x53494c20, 0xffffffe0, "Si3036,8",		mpatch_si3036,	mpatch_si3036, AC97_MODEM_PATCH },
 { 0x54524102, 0xffffffff, "TR28022",		NULL,		NULL },
 { 0x54524106, 0xffffffff, "TR28026",		NULL,		NULL },
 { 0x54524108, 0xffffffff, "TR28028",		patch_tritech_tr28028,	NULL }, // added by xin jin [07/09/99]
@@ -366,6 +367,7 @@ int snd_ac97_update(ac97_t *ac97, unsign
 		ac97->regs[reg] = value;
 		ac97->bus->ops->write(ac97, reg, value);
 	}
+	set_bit(reg, ac97->reg_accessed);
 	up(&ac97->reg_mutex);
 	return change;
 }
@@ -409,6 +411,7 @@ int snd_ac97_update_bits_nolock(ac97_t *
 		ac97->regs[reg] = new;
 		ac97->bus->ops->write(ac97, reg, new);
 	}
+	set_bit(reg, ac97->reg_accessed);
 	return change;
 }
 
@@ -462,12 +465,14 @@ int snd_ac97_get_enum_double(snd_kcontro
 {
 	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
 	struct ac97_enum *e = (struct ac97_enum *)kcontrol->private_value;
-	unsigned short val;
+	unsigned short val, bitmask;
 	
+	for (bitmask = 1; bitmask < e->mask; bitmask <<= 1)
+		;
 	val = snd_ac97_read_cache(ac97, e->reg);
-	ucontrol->value.enumerated.item[0] = (val >> e->shift_l) & (e->mask - 1);
+	ucontrol->value.enumerated.item[0] = (val >> e->shift_l) & (bitmask - 1);
 	if (e->shift_l != e->shift_r)
-		ucontrol->value.enumerated.item[1] = (val >> e->shift_r) & (e->mask - 1);
+		ucontrol->value.enumerated.item[1] = (val >> e->shift_r) & (bitmask - 1);
 
 	return 0;
 }
@@ -477,17 +482,19 @@ int snd_ac97_put_enum_double(snd_kcontro
 	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
 	struct ac97_enum *e = (struct ac97_enum *)kcontrol->private_value;
 	unsigned short val;
-	unsigned short mask;
+	unsigned short mask, bitmask;
 	
+	for (bitmask = 1; bitmask < e->mask; bitmask <<= 1)
+		;
 	if (ucontrol->value.enumerated.item[0] > e->mask - 1)
 		return -EINVAL;
 	val = ucontrol->value.enumerated.item[0] << e->shift_l;
-	mask = (e->mask - 1) << e->shift_l;
+	mask = (bitmask - 1) << e->shift_l;
 	if (e->shift_l != e->shift_r) {
 		if (ucontrol->value.enumerated.item[1] > e->mask - 1)
 			return -EINVAL;
 		val |= ucontrol->value.enumerated.item[1] << e->shift_r;
-		mask |= (e->mask - 1) << e->shift_r;
+		mask |= (bitmask - 1) << e->shift_r;
 	}
 	return snd_ac97_update_bits(ac97, e->reg, mask, val);
 }
@@ -658,14 +665,14 @@ AC97_SINGLE("LFE Playback Switch", AC97_
 AC97_SINGLE("LFE Playback Volume", AC97_CENTER_LFE_MASTER, 8, 31, 1)
 };
 
-static const snd_kcontrol_new_t snd_ac97_controls_surround[2] = {
-AC97_DOUBLE("Surround Playback Switch", AC97_SURROUND_MASTER, 15, 7, 1, 1),
-AC97_DOUBLE("Surround Playback Volume", AC97_SURROUND_MASTER, 8, 0, 31, 1),
-};
-
 static const snd_kcontrol_new_t snd_ac97_control_eapd =
 AC97_SINGLE("External Amplifier", AC97_POWERDOWN, 15, 1, 1);
 
+static const snd_kcontrol_new_t snd_ac97_controls_modem_switches[2] = {
+AC97_SINGLE("Off-hook Switch", AC97_GPIO_STATUS, 0, 1, 0),
+AC97_SINGLE("Caller ID Switch", AC97_GPIO_STATUS, 2, 1, 0)
+};
+
 /* change the existing EAPD control as inverted */
 static void set_inv_eapd(ac97_t *ac97, snd_kcontrol_t *kctl)
 {
@@ -1071,10 +1078,15 @@ static void check_volume_resolution(ac97
 	for (i = 0 ; i < ARRAY_SIZE(cbit); i++) {
 		unsigned short val;
 		snd_ac97_write(ac97, reg, 0x8080 | cbit[i] | (cbit[i] << 8));
+		/* Do the read twice due to buffers on some ac97 codecs.
+		 * e.g. The STAC9704 returns exactly what you wrote the the register
+		 * if you read it immediately. This causes the detect routine to fail.
+		 */
 		val = snd_ac97_read(ac97, reg);
-		if (! *lo_max && (val & cbit[i]))
+		val = snd_ac97_read(ac97, reg);
+		if (! *lo_max && (val & 0x7f) == cbit[i])
 			*lo_max = max[i];
-		if (! *hi_max && (val & (cbit[i] << 8)))
+		if (! *hi_max && ((val >> 8) & 0x7f) == cbit[i])
 			*hi_max = max[i];
 		if (*lo_max && *hi_max)
 			break;
@@ -1526,13 +1538,25 @@ static int snd_ac97_mixer_build(ac97_t *
 
 static int snd_ac97_modem_build(snd_card_t * card, ac97_t * ac97)
 {
-	/* TODO */
+	int err, idx;
+
 	//printk("AC97_GPIO_CFG = %x\n",snd_ac97_read(ac97,AC97_GPIO_CFG));
 	snd_ac97_write(ac97, AC97_GPIO_CFG, 0xffff & ~(AC97_GPIO_LINE1_OH));
 	snd_ac97_write(ac97, AC97_GPIO_POLARITY, 0xffff & ~(AC97_GPIO_LINE1_OH));
 	snd_ac97_write(ac97, AC97_GPIO_STICKY, 0xffff);
 	snd_ac97_write(ac97, AC97_GPIO_WAKEUP, 0x0);
 	snd_ac97_write(ac97, AC97_MISC_AFE, 0x0);
+
+	/* build modem switches */
+	for (idx = 0; idx < ARRAY_SIZE(snd_ac97_controls_modem_switches); idx++)
+		if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_modem_switches[idx], ac97))) < 0)
+			return err;
+
+	/* build chip specific controls */
+	if (ac97->build_ops->build_specific)
+		if ((err = ac97->build_ops->build_specific(ac97)) < 0)
+			return err;
+
 	return 0;
 }
 
@@ -1872,7 +1896,11 @@ int snd_ac97_mixer(ac97_bus_t *bus, ac97
 			goto __access_ok;
 	}
 
-	snd_ac97_write(ac97, AC97_RESET, 0);	/* reset to defaults */
+	/* reset to defaults */
+	if (!(ac97->scaps & AC97_SCAP_SKIP_AUDIO))
+		snd_ac97_write(ac97, AC97_RESET, 0);
+	if (!(ac97->scaps & AC97_SCAP_SKIP_MODEM))
+		snd_ac97_write(ac97, AC97_EXTENDED_MID, 0);
 	if (bus->ops->wait)
 		bus->ops->wait(ac97);
 	else {
@@ -1964,21 +1992,21 @@ int snd_ac97_mixer(ac97_bus_t *bus, ac97
 		/* note: it's important to set the rate at first */
 		tmp = AC97_MEA_GPIO;
 		if (ac97->ext_mid & AC97_MEI_LINE1) {
-			snd_ac97_write_cache(ac97, AC97_LINE1_RATE, 12000);
+			snd_ac97_write_cache(ac97, AC97_LINE1_RATE, 8000);
 			tmp |= AC97_MEA_ADC1 | AC97_MEA_DAC1;
 		}
 		if (ac97->ext_mid & AC97_MEI_LINE2) {
-			snd_ac97_write_cache(ac97, AC97_LINE2_RATE, 12000);
+			snd_ac97_write_cache(ac97, AC97_LINE2_RATE, 8000);
 			tmp |= AC97_MEA_ADC2 | AC97_MEA_DAC2;
 		}
 		if (ac97->ext_mid & AC97_MEI_HANDSET) {
-			snd_ac97_write_cache(ac97, AC97_HANDSET_RATE, 12000);
+			snd_ac97_write_cache(ac97, AC97_HANDSET_RATE, 8000);
 			tmp |= AC97_MEA_HADC | AC97_MEA_HDAC;
 		}
-		snd_ac97_write_cache(ac97, AC97_EXTENDED_MSTATUS, 0xff00 & ~(tmp << 8));
+		snd_ac97_write_cache(ac97, AC97_EXTENDED_MSTATUS, 0);
 		udelay(100);
 		/* nothing should be in powerdown mode */
-		snd_ac97_write_cache(ac97, AC97_EXTENDED_MSTATUS, 0xff00 & ~(tmp << 8));
+		snd_ac97_write_cache(ac97, AC97_EXTENDED_MSTATUS, 0);
 		end_time = jiffies + (HZ / 10);
 		do {
 			if ((snd_ac97_read(ac97, AC97_EXTENDED_MSTATUS) & tmp) == tmp)
@@ -2203,7 +2231,7 @@ void snd_ac97_restore_iec958(ac97_t *ac9
  */
 void snd_ac97_resume(ac97_t *ac97)
 {
-	int i;
+	unsigned long end_time;
 
 	if (ac97->bus->ops->reset) {
 		ac97->bus->ops->reset(ac97);
@@ -2221,26 +2249,26 @@ void snd_ac97_resume(ac97_t *ac97)
 	snd_ac97_write(ac97, AC97_POWERDOWN, ac97->regs[AC97_POWERDOWN]);
 	if (ac97_is_audio(ac97)) {
 		ac97->bus->ops->write(ac97, AC97_MASTER, 0x8101);
-		for (i = HZ/10; i >= 0; i--) {
+		end_time = jiffies + msecs_to_jiffies(100);
+		do {
 			if (snd_ac97_read(ac97, AC97_MASTER) == 0x8101)
 				break;
 			set_current_state(TASK_UNINTERRUPTIBLE);
 			schedule_timeout(1);
-		}
+		} while (time_after_eq(end_time, jiffies));
 		/* FIXME: extra delay */
 		ac97->bus->ops->write(ac97, AC97_MASTER, 0x8000);
-		if (snd_ac97_read(ac97, AC97_MASTER) != 0x8000) {
-			set_current_state(TASK_UNINTERRUPTIBLE);
-			schedule_timeout(HZ/4);
-		}
+		if (snd_ac97_read(ac97, AC97_MASTER) != 0x8000)
+			msleep(250);
 	} else {
-		for (i = HZ/10; i >= 0; i--) {
+		end_time = jiffies + msecs_to_jiffies(100);
+		do {
 			unsigned short val = snd_ac97_read(ac97, AC97_EXTENDED_MID);
 			if (val != 0xffff && (val & 1) != 0)
 				break;
 			set_current_state(TASK_UNINTERRUPTIBLE);
 			schedule_timeout(1);
-		}
+		} while (time_after_eq(end_time, jiffies));
 	}
 __reset_ready:
 
@@ -2521,11 +2549,11 @@ int snd_ac97_tune_hardware(ac97_t *ac97,
 		return result;
 	}
 
-	for (; quirk->vendor; quirk++) {
-		if (quirk->vendor != ac97->subsystem_vendor)
+	for (; quirk->subvendor; quirk++) {
+		if (quirk->subvendor != ac97->subsystem_vendor)
 			continue;
-		if ((! quirk->mask && quirk->device == ac97->subsystem_device) ||
-		    quirk->device == (quirk->mask & ac97->subsystem_device)) {
+		if ((! quirk->mask && quirk->subdevice == ac97->subsystem_device) ||
+		    quirk->subdevice == (quirk->mask & ac97->subsystem_device)) {
 			if (quirk->codec_id && quirk->codec_id != ac97->id)
 				continue;
 			snd_printdd("ac97 quirk for %s (%04x:%04x)\n", quirk->name, ac97->subsystem_vendor, ac97->subsystem_device);
diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c
--- a/sound/pci/ac97/ac97_patch.c
+++ b/sound/pci/ac97/ac97_patch.c
@@ -64,6 +64,116 @@ static int ac97_update_bits_page(ac97_t 
 	return ret;
 }
 
+/*
+ * shared line-in/mic controls
+ */
+static int ac97_enum_text_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo,
+			       const char **texts, unsigned int nums)
+{
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+	uinfo->count = 1;
+	uinfo->value.enumerated.items = nums;
+	if (uinfo->value.enumerated.item > nums - 1)
+		uinfo->value.enumerated.item = nums - 1;
+	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
+	return 0;
+}
+
+static int ac97_surround_jack_mode_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+{
+	static const char *texts[] = { "Shared", "Independent" };
+	return ac97_enum_text_info(kcontrol, uinfo, texts, 2);
+}
+
+static int ac97_surround_jack_mode_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
+
+	ucontrol->value.enumerated.item[0] = ac97->indep_surround;
+	return 0;
+}
+
+static int ac97_surround_jack_mode_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
+	unsigned char indep = !!ucontrol->value.enumerated.item[0];
+
+	if (indep != ac97->indep_surround) {
+		ac97->indep_surround = indep;
+		if (ac97->build_ops->update_jacks)
+			ac97->build_ops->update_jacks(ac97);
+		return 1;
+	}
+	return 0;
+}
+
+static int ac97_channel_mode_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+{
+	static const char *texts[] = { "2ch", "4ch", "6ch" };
+	if (kcontrol->private_value)
+		return ac97_enum_text_info(kcontrol, uinfo, texts, 2); /* 4ch only */
+	return ac97_enum_text_info(kcontrol, uinfo, texts, 3);
+}
+
+static int ac97_channel_mode_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
+
+	ucontrol->value.enumerated.item[0] = ac97->channel_mode;
+	return 0;
+}
+
+static int ac97_channel_mode_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
+	unsigned char mode = ucontrol->value.enumerated.item[0];
+
+	if (mode != ac97->channel_mode) {
+		ac97->channel_mode = mode;
+		if (ac97->build_ops->update_jacks)
+			ac97->build_ops->update_jacks(ac97);
+		return 1;
+	}
+	return 0;
+}
+
+#define AC97_SURROUND_JACK_MODE_CTL \
+	{ \
+		.iface	= SNDRV_CTL_ELEM_IFACE_MIXER, \
+		.name	= "Surround Jack Mode", \
+		.info = ac97_surround_jack_mode_info, \
+		.get = ac97_surround_jack_mode_get, \
+		.put = ac97_surround_jack_mode_put, \
+	}
+#define AC97_CHANNEL_MODE_CTL \
+	{ \
+		.iface	= SNDRV_CTL_ELEM_IFACE_MIXER, \
+		.name	= "Channel Mode", \
+		.info = ac97_channel_mode_info, \
+		.get = ac97_channel_mode_get, \
+		.put = ac97_channel_mode_put, \
+	}
+#define AC97_CHANNEL_MODE_4CH_CTL \
+	{ \
+		.iface	= SNDRV_CTL_ELEM_IFACE_MIXER, \
+		.name	= "Channel Mode", \
+		.info = ac97_channel_mode_info, \
+		.get = ac97_channel_mode_get, \
+		.put = ac97_channel_mode_put, \
+		.private_value = 1, \
+	}
+
+static inline int is_shared_linein(ac97_t *ac97)
+{
+	return ! ac97->indep_surround && ac97->channel_mode >= 1;
+}
+
+static inline int is_shared_micin(ac97_t *ac97)
+{
+	return ! ac97->indep_surround && ac97->channel_mode >= 2;
+}
+
+
 /* The following snd_ac97_ymf753_... items added by David Shust (dshust@shustring.com) */
 
 /* It is possible to indicate to the Yamaha YMF753 the type of speakers being used. */
@@ -1390,6 +1500,16 @@ static int snd_ac97_ad1888_downmix_put(s
 				    AC97_AD198X_DMIX0 | AC97_AD198X_DMIX1, val);
 }
 
+static void ad1888_update_jacks(ac97_t *ac97)
+{
+	/* shared Line-In */
+	snd_ac97_update_bits(ac97, AC97_AD_MISC, 1 << 12,
+			     is_shared_linein(ac97) ? 0 : 1 << 12);
+	/* shared Mic */
+	snd_ac97_update_bits(ac97, AC97_AD_MISC, 1 << 11,
+			     is_shared_micin(ac97) ? 0 : 1 << 11);
+}
+
 static const snd_kcontrol_new_t snd_ac97_ad1888_controls[] = {
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -1406,8 +1526,11 @@ static const snd_kcontrol_new_t snd_ac97
 		.get = snd_ac97_ad1888_downmix_get,
 		.put = snd_ac97_ad1888_downmix_put
 	},
-	AC97_SINGLE("Surround Jack as Input", AC97_AD_MISC, 12, 1, 0),
-	AC97_SINGLE("Center/LFE Jack as Input", AC97_AD_MISC, 11, 1, 0),
+	AC97_SURROUND_JACK_MODE_CTL,
+	AC97_CHANNEL_MODE_CTL,
+
+	AC97_SINGLE("Headphone Jack Sense", AC97_AD_JACK_SPDIF, 10, 1, 0),
+	AC97_SINGLE("Line Jack Sense", AC97_AD_JACK_SPDIF, 12, 1, 0),
 };
 
 static int patch_ad1888_specific(ac97_t *ac97)
@@ -1422,8 +1545,9 @@ static struct snd_ac97_build_ops patch_a
 	.build_post_spdif = patch_ad198x_post_spdif,
 	.build_specific = patch_ad1888_specific,
 #ifdef CONFIG_PM
-	.resume = ad18xx_resume
+	.resume = ad18xx_resume,
 #endif
+	.update_jacks = ad1888_update_jacks,
 };
 
 int patch_ad1888(ac97_t * ac97)
@@ -1459,8 +1583,9 @@ static struct snd_ac97_build_ops patch_a
 	.build_post_spdif = patch_ad198x_post_spdif,
 	.build_specific = patch_ad1980_specific,
 #ifdef CONFIG_PM
-	.resume = ad18xx_resume
+	.resume = ad18xx_resume,
 #endif
+	.update_jacks = ad1888_update_jacks,
 };
 
 int patch_ad1980(ac97_t * ac97)
@@ -1471,10 +1596,21 @@ int patch_ad1980(ac97_t * ac97)
 }
 
 static const snd_kcontrol_new_t snd_ac97_ad1985_controls[] = {
-	AC97_SINGLE("Center/LFE Jack as Mic", AC97_AD_SERIAL_CFG, 9, 1, 0),
 	AC97_SINGLE("Exchange Center/LFE", AC97_AD_SERIAL_CFG, 3, 1, 0)
 };
 
+static void ad1985_update_jacks(ac97_t *ac97)
+{
+	/* shared Line-In */
+	snd_ac97_update_bits(ac97, AC97_AD_MISC, 1 << 12,
+			     is_shared_linein(ac97) ? 0 : 1 << 12);
+	/* shared Mic */
+	snd_ac97_update_bits(ac97, AC97_AD_MISC, 1 << 11,
+			     is_shared_micin(ac97) ? 0 : 1 << 11);
+	snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 1 << 9,
+			     is_shared_micin(ac97) ? 0 : 1 << 9);
+}
+
 static int patch_ad1985_specific(ac97_t *ac97)
 {
 	int err;
@@ -1488,8 +1624,9 @@ static struct snd_ac97_build_ops patch_a
 	.build_post_spdif = patch_ad198x_post_spdif,
 	.build_specific = patch_ad1985_specific,
 #ifdef CONFIG_PM
-	.resume = ad18xx_resume
+	.resume = ad18xx_resume,
 #endif
+	.update_jacks = ad1985_update_jacks,
 };
 
 int patch_ad1985(ac97_t * ac97)
@@ -1521,31 +1658,25 @@ int patch_ad1985(ac97_t * ac97)
 /*
  * realtek ALC65x/850 codecs
  */
-static int snd_ac97_alc650_mic_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t * ucontrol)
+static void alc650_update_jacks(ac97_t *ac97)
 {
-        ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
-        ucontrol->value.integer.value[0] = (ac97->regs[AC97_ALC650_MULTICH] >> 10) & 1;
-        return 0;
-}
-
-static int snd_ac97_alc650_mic_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t * ucontrol)
-{
-        ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
-	int change, val;
-	val = !!(snd_ac97_read(ac97, AC97_ALC650_MULTICH) & (1 << 10));
-	change = (ucontrol->value.integer.value[0] != val);
-	if (change) {
-		/* disable/enable vref */
-		snd_ac97_update_bits(ac97, AC97_ALC650_CLOCK, 1 << 12,
-				     ucontrol->value.integer.value[0] ? (1 << 12) : 0);
-		/* turn on/off center-on-mic */
-		snd_ac97_update_bits(ac97, AC97_ALC650_MULTICH, 1 << 10,
-				     ucontrol->value.integer.value[0] ? (1 << 10) : 0);
-		/* GPIO0 high for mic */
-		snd_ac97_update_bits(ac97, AC97_ALC650_GPIO_STATUS, 0x100,
-				     ucontrol->value.integer.value[0] ? 0 : 0x100);
-        }
-        return change;
+	int shared;
+	
+	/* shared Line-In */
+	shared = is_shared_linein(ac97);
+	snd_ac97_update_bits(ac97, AC97_ALC650_MULTICH, 1 << 9,
+			     shared ? (1 << 9) : 0);
+	/* update shared Mic */
+	shared = is_shared_micin(ac97);
+	/* disable/enable vref */
+	snd_ac97_update_bits(ac97, AC97_ALC650_CLOCK, 1 << 12,
+			     shared ? (1 << 12) : 0);
+	/* turn on/off center-on-mic */
+	snd_ac97_update_bits(ac97, AC97_ALC650_MULTICH, 1 << 10,
+			     shared ? (1 << 10) : 0);
+	/* GPIO0 high for mic */
+	snd_ac97_update_bits(ac97, AC97_ALC650_GPIO_STATUS, 0x100,
+			     shared ? 0 : 0x100);
 }
 
 static const snd_kcontrol_new_t snd_ac97_controls_alc650[] = {
@@ -1558,8 +1689,8 @@ static const snd_kcontrol_new_t snd_ac97
 	/* 6: Independent Master Volume Right */
 	/* 7: Independent Master Volume Left */
 	/* 8: reserved */
-	AC97_SINGLE("Line-In As Surround", AC97_ALC650_MULTICH, 9, 1, 0),
-	/* 10: mic, see below */
+	/* 9: Line-In/Surround share */
+	/* 10: Mic/CLFE share */
 	/* 11-13: in IEC958 controls */
 	AC97_SINGLE("Swap Surround Slot", AC97_ALC650_MULTICH, 14, 1, 0),
 #if 0 /* always set in patch_alc650 */
@@ -1570,14 +1701,8 @@ static const snd_kcontrol_new_t snd_ac97
 	AC97_SINGLE("Center/LFE DAC Switch", AC97_ALC650_LFE_DAC_VOL, 15, 1, 1),
 	AC97_DOUBLE("Center/LFE DAC Volume", AC97_ALC650_LFE_DAC_VOL, 8, 0, 31, 1),
 #endif
-	{
-		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-		.name = "Mic As Center/LFE",
-		.info = snd_ac97_info_volsw,
-		.get = snd_ac97_alc650_mic_get,
-		.put = snd_ac97_alc650_mic_put,
-		.private_value = AC97_SINGLE_VALUE(0, 0, 1, 0) /* only mask needed */
-	},
+	AC97_SURROUND_JACK_MODE_CTL,
+	AC97_CHANNEL_MODE_CTL,
 };
 
 static const snd_kcontrol_new_t snd_ac97_spdif_controls_alc650[] = {
@@ -1601,7 +1726,8 @@ static int patch_alc650_specific(ac97_t 
 }
 
 static struct snd_ac97_build_ops patch_alc650_ops = {
-	.build_specific	= patch_alc650_specific
+	.build_specific	= patch_alc650_specific,
+	.update_jacks = alc650_update_jacks
 };
 
 int patch_alc650(ac97_t * ac97)
@@ -1659,37 +1785,27 @@ int patch_alc650(ac97_t * ac97)
 	return 0;
 }
 
-static int snd_ac97_alc655_mic_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t * ucontrol)
-{
-        ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
-        ucontrol->value.integer.value[0] = (ac97->regs[AC97_ALC650_MULTICH] >> 10) & 1;
-        return 0;
-}
-
-static int snd_ac97_alc655_mic_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t * ucontrol)
+static void alc655_update_jacks(ac97_t *ac97)
 {
-        ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
-
+	int shared;
+	
+	/* shared Line-In */
+	shared = is_shared_linein(ac97);
+	ac97_update_bits_page(ac97, AC97_ALC650_MULTICH, 1 << 9,
+			      shared ? (1 << 9) : 0, 0);
+	/* update shared mic */
+	shared = is_shared_micin(ac97);
 	/* misc control; vrefout disable */
 	snd_ac97_update_bits(ac97, AC97_ALC650_CLOCK, 1 << 12,
-			     ucontrol->value.integer.value[0] ? (1 << 12) : 0);
-	return ac97_update_bits_page(ac97, AC97_ALC650_MULTICH, 1 << 10,
-				     ucontrol->value.integer.value[0] ? (1 << 10) : 0,
-				     0);
+			     shared ? (1 << 12) : 0);
+	ac97_update_bits_page(ac97, AC97_ALC650_MULTICH, 1 << 10,
+			      shared ? (1 << 10) : 0, 0);
 }
 
-
 static const snd_kcontrol_new_t snd_ac97_controls_alc655[] = {
 	AC97_PAGE_SINGLE("Duplicate Front", AC97_ALC650_MULTICH, 0, 1, 0, 0),
-	AC97_PAGE_SINGLE("Line-In As Surround", AC97_ALC650_MULTICH, 9, 1, 0, 0),
-	{
-		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-		.name = "Mic As Center/LFE",
-		.info = snd_ac97_info_volsw,
-		.get = snd_ac97_alc655_mic_get,
-		.put = snd_ac97_alc655_mic_put,
-		.private_value = AC97_SINGLE_VALUE(0, 0, 1, 0) /* only mask needed */
-	},
+	AC97_SURROUND_JACK_MODE_CTL,
+	AC97_CHANNEL_MODE_CTL,
 };
 
 static int alc655_iec958_route_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
@@ -1759,7 +1875,8 @@ static int patch_alc655_specific(ac97_t 
 }
 
 static struct snd_ac97_build_ops patch_alc655_ops = {
-	.build_specific	= patch_alc655_specific
+	.build_specific	= patch_alc655_specific,
+	.update_jacks = alc655_update_jacks
 };
 
 int patch_alc655(ac97_t * ac97)
@@ -1798,63 +1915,33 @@ int patch_alc655(ac97_t * ac97)
 #define AC97_ALC850_JACK_SELECT	0x76
 #define AC97_ALC850_MISC1	0x7a
 
-static int ac97_alc850_surround_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t * ucontrol)
+static void alc850_update_jacks(ac97_t *ac97)
 {
-        ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
-        ucontrol->value.integer.value[0] = ((ac97->regs[AC97_ALC850_JACK_SELECT] >> 12) & 7) == 2;
-        return 0;
-}
-
-static int ac97_alc850_surround_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t * ucontrol)
-{
-        ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
-
+	int shared;
+	
+	/* shared Line-In */
+	shared = is_shared_linein(ac97);
 	/* SURR 1kOhm (bit4), Amp (bit5) */
 	snd_ac97_update_bits(ac97, AC97_ALC850_MISC1, (1<<4)|(1<<5),
-			     ucontrol->value.integer.value[0] ? (1<<5) : (1<<4));
+			     shared ? (1<<5) : (1<<4));
 	/* LINE-IN = 0, SURROUND = 2 */
-	return snd_ac97_update_bits(ac97, AC97_ALC850_JACK_SELECT, 7 << 12,
-				    ucontrol->value.integer.value[0] ? (2<<12) : (0<<12));
-}
-
-static int ac97_alc850_mic_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t * ucontrol)
-{
-        ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
-        ucontrol->value.integer.value[0] = ((ac97->regs[AC97_ALC850_JACK_SELECT] >> 4) & 7) == 2;
-        return 0;
-}
-
-static int ac97_alc850_mic_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t * ucontrol)
-{
-        ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
-
+	snd_ac97_update_bits(ac97, AC97_ALC850_JACK_SELECT, 7 << 12,
+			     shared ? (2<<12) : (0<<12));
+	/* update shared mic */
+	shared = is_shared_micin(ac97);
 	/* Vref disable (bit12), 1kOhm (bit13) */
 	snd_ac97_update_bits(ac97, AC97_ALC850_MISC1, (1<<12)|(1<<13),
-			     ucontrol->value.integer.value[0] ? (1<<12) : (1<<13));
+			     shared ? (1<<12) : (1<<13));
 	/* MIC-IN = 1, CENTER-LFE = 2 */
-	return snd_ac97_update_bits(ac97, AC97_ALC850_JACK_SELECT, 7 << 4,
-				    ucontrol->value.integer.value[0] ? (2<<4) : (1<<4));
+	snd_ac97_update_bits(ac97, AC97_ALC850_JACK_SELECT, 7 << 4,
+			     shared ? (2<<4) : (1<<4));
 }
 
 static const snd_kcontrol_new_t snd_ac97_controls_alc850[] = {
 	AC97_PAGE_SINGLE("Duplicate Front", AC97_ALC650_MULTICH, 0, 1, 0, 0),
-	{
-		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-		.name = "Line-In As Surround",
-		.info = snd_ac97_info_volsw,
-		.get = ac97_alc850_surround_get,
-		.put = ac97_alc850_surround_put,
-		.private_value = AC97_SINGLE_VALUE(0, 0, 1, 0) /* only mask needed */
-	},
-	{
-		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-		.name = "Mic As Center/LFE",
-		.info = snd_ac97_info_volsw,
-		.get = ac97_alc850_mic_get,
-		.put = ac97_alc850_mic_put,
-		.private_value = AC97_SINGLE_VALUE(0, 0, 1, 0) /* only mask needed */
-	},
-
+	AC97_SINGLE("Mic Front Input Switch", AC97_ALC850_JACK_SELECT, 15, 1, 1),
+	AC97_SURROUND_JACK_MODE_CTL,
+	AC97_CHANNEL_MODE_CTL,
 };
 
 static int patch_alc850_specific(ac97_t *ac97)
@@ -1871,7 +1958,8 @@ static int patch_alc850_specific(ac97_t 
 }
 
 static struct snd_ac97_build_ops patch_alc850_ops = {
-	.build_specific	= patch_alc850_specific
+	.build_specific	= patch_alc850_specific,
+	.update_jacks = alc850_update_jacks
 };
 
 int patch_alc850(ac97_t *ac97)
@@ -1911,9 +1999,17 @@ int patch_alc850(ac97_t *ac97)
 /*
  * C-Media CM97xx codecs
  */
+static void cm9738_update_jacks(ac97_t *ac97)
+{
+	/* shared Line-In */
+	snd_ac97_update_bits(ac97, AC97_CM9738_VENDOR_CTRL, 1 << 10,
+			     is_shared_linein(ac97) ? (1 << 10) : 0);
+}
+
 static const snd_kcontrol_new_t snd_ac97_cm9738_controls[] = {
-	AC97_SINGLE("Line-In As Surround", AC97_CM9738_VENDOR_CTRL, 10, 1, 0),
 	AC97_SINGLE("Duplicate Front", AC97_CM9738_VENDOR_CTRL, 13, 1, 0),
+	AC97_SURROUND_JACK_MODE_CTL,
+	AC97_CHANNEL_MODE_4CH_CTL,
 };
 
 static int patch_cm9738_specific(ac97_t * ac97)
@@ -1922,7 +2018,8 @@ static int patch_cm9738_specific(ac97_t 
 }
 
 static struct snd_ac97_build_ops patch_cm9738_ops = {
-	.build_specific	= patch_cm9738_specific
+	.build_specific	= patch_cm9738_specific,
+	.update_jacks = cm9738_update_jacks
 };
 
 int patch_cm9738(ac97_t * ac97)
@@ -1986,34 +2083,19 @@ static const snd_kcontrol_new_t snd_ac97
 	/* BIT 8: SPD32 - 32bit SPDIF - not supported yet */
 };
 
-static int snd_ac97_cm9739_center_mic_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
-{
-	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
-	if (ac97->regs[AC97_CM9739_MULTI_CHAN] & 0x1000)
-		ucontrol->value.integer.value[0] = 1;
-	else
-		ucontrol->value.integer.value[0] = 0;
-	return 0;
-}
-
-static int snd_ac97_cm9739_center_mic_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static void cm9739_update_jacks(ac97_t *ac97)
 {
-	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
-	return snd_ac97_update_bits(ac97, AC97_CM9739_MULTI_CHAN, 0x3000,
-				    ucontrol->value.integer.value[0] ? 
-				    0x1000 : 0x2000);
+	/* shared Line-In */
+	snd_ac97_update_bits(ac97, AC97_CM9739_MULTI_CHAN, 1 << 10,
+			     is_shared_linein(ac97) ? (1 << 10) : 0);
+	/* shared Mic */
+	snd_ac97_update_bits(ac97, AC97_CM9739_MULTI_CHAN, 0x3000,
+			     is_shared_micin(ac97) ? 0x1000 : 0x2000);
 }
 
 static const snd_kcontrol_new_t snd_ac97_cm9739_controls[] = {
-	AC97_SINGLE("Line-In As Surround", AC97_CM9739_MULTI_CHAN, 10, 1, 0),
-	{
-		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-		.name = "Mic As Center/LFE",
-		.info = snd_ac97_info_volsw,
-		.get = snd_ac97_cm9739_center_mic_get,
-		.put = snd_ac97_cm9739_center_mic_put,
-		.private_value = AC97_SINGLE_VALUE(0, 0, 1, 0) /* only mask needed */
-	},
+	AC97_SURROUND_JACK_MODE_CTL,
+	AC97_CHANNEL_MODE_CTL,
 };
 
 static int patch_cm9739_specific(ac97_t * ac97)
@@ -2028,7 +2110,8 @@ static int patch_cm9739_post_spdif(ac97_
 
 static struct snd_ac97_build_ops patch_cm9739_ops = {
 	.build_specific	= patch_cm9739_specific,
-	.build_post_spdif = patch_cm9739_post_spdif
+	.build_post_spdif = patch_cm9739_post_spdif,
+	.update_jacks = cm9739_update_jacks
 };
 
 int patch_cm9739(ac97_t * ac97)
@@ -2087,71 +2170,97 @@ int patch_cm9739(ac97_t * ac97)
 }
 
 #define AC97_CM9761_MULTI_CHAN	0x64
+#define AC97_CM9761_FUNC	0x66
 #define AC97_CM9761_SPDIF_CTRL	0x6c
 
-static int snd_ac97_cm9761_linein_rear_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
-{
-	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
-	if (ac97->regs[AC97_CM9739_MULTI_CHAN] & 0x0400)
-		ucontrol->value.integer.value[0] = 1;
-	else
-		ucontrol->value.integer.value[0] = 0;
-	return 0;
-}
-
-static int snd_ac97_cm9761_linein_rear_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static void cm9761_update_jacks(ac97_t *ac97)
 {
-	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
-	unsigned short vals[2][2] = {
+	unsigned short surr_vals[2][2] = {
 		{ 0x0008, 0x0400 }, /* off, on */
 		{ 0x0000, 0x0408 }, /* off, on (9761-82 rev.B) */
 	};
-	return snd_ac97_update_bits(ac97, AC97_CM9739_MULTI_CHAN, 0x0408,
-				    vals[ac97->spec.dev_flags][!!ucontrol->value.integer.value[0]]);
+	unsigned short clfe_vals[2][2] = {
+		{ 0x2000, 0x1880 }, /* off, on */
+		{ 0x1000, 0x2880 }, /* off, on (9761-82 rev.B) */
+	};
+
+	/* shared Line-In */
+	snd_ac97_update_bits(ac97, AC97_CM9761_MULTI_CHAN, 0x0408,
+			     surr_vals[ac97->spec.dev_flags][is_shared_linein(ac97)]);
+	/* shared Mic */
+	snd_ac97_update_bits(ac97, AC97_CM9761_MULTI_CHAN, 0x3880,
+			     clfe_vals[ac97->spec.dev_flags][is_shared_micin(ac97)]);
+}
+
+static const snd_kcontrol_new_t snd_ac97_cm9761_controls[] = {
+	AC97_SURROUND_JACK_MODE_CTL,
+	AC97_CHANNEL_MODE_CTL,
+};
+
+static int cm9761_spdif_out_source_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+{
+	static char *texts[] = { "AC-Link", "ADC", "SPDIF-In" };
+
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+	uinfo->count = 1;
+	uinfo->value.enumerated.items = 3;
+	if (uinfo->value.enumerated.item > 2)
+		uinfo->value.enumerated.item = 2;
+	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
+	return 0;
 }
 
-static int snd_ac97_cm9761_center_mic_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int cm9761_spdif_out_source_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
 {
 	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
-	if (ac97->regs[AC97_CM9739_MULTI_CHAN] & 0x1000)
-		ucontrol->value.integer.value[0] = 1;
+
+	if (ac97->regs[AC97_CM9761_FUNC] & 0x1)
+		ucontrol->value.enumerated.item[0] = 2; /* SPDIF-loopback */
+	else if (ac97->regs[AC97_CM9761_SPDIF_CTRL] & 0x2)
+		ucontrol->value.enumerated.item[0] = 1; /* ADC loopback */
 	else
-		ucontrol->value.integer.value[0] = 0;
-	if (ac97->spec.dev_flags) /* 9761-82 rev.B */
-		ucontrol->value.integer.value[0] = !ucontrol->value.integer.value[0];
+		ucontrol->value.enumerated.item[0] = 0; /* AC-link */
 	return 0;
 }
 
-static int snd_ac97_cm9761_center_mic_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int cm9761_spdif_out_source_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
 {
 	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
-	unsigned short vals[2][2] = {
-		{ 0x2000, 0x1880 }, /* off, on */
-		{ 0x1000, 0x2880 }, /* off, on (9761-82 rev.B) */
-	};
-	return snd_ac97_update_bits(ac97, AC97_CM9739_MULTI_CHAN, 0x3880,
-				    vals[ac97->spec.dev_flags][!!ucontrol->value.integer.value[0]]);
+
+	if (ucontrol->value.enumerated.item[0] == 2)
+		return snd_ac97_update_bits(ac97, AC97_CM9761_FUNC, 0x1, 0x1);
+	snd_ac97_update_bits(ac97, AC97_CM9761_FUNC, 0x1, 0);
+	return snd_ac97_update_bits(ac97, AC97_CM9761_SPDIF_CTRL, 0x2,
+				    ucontrol->value.enumerated.item[0] == 1 ? 0x2 : 0);
 }
 
-static const snd_kcontrol_new_t snd_ac97_cm9761_controls[] = {
-	{
-		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-		.name = "Line-In As Surround",
-		.info = snd_ac97_info_volsw,
-		.get = snd_ac97_cm9761_linein_rear_get,
-		.put = snd_ac97_cm9761_linein_rear_put,
-		.private_value = AC97_SINGLE_VALUE(0, 0, 1, 0) /* only mask needed */
-	},
-	{
-		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-		.name = "Mic As Center/LFE",
-		.info = snd_ac97_info_volsw,
-		.get = snd_ac97_cm9761_center_mic_get,
-		.put = snd_ac97_cm9761_center_mic_put,
-		.private_value = AC97_SINGLE_VALUE(0, 0, 1, 0) /* only mask needed */
+static const char *cm9761_dac_clock[] = { "AC-Link", "SPDIF-In", "Both" };
+static const struct ac97_enum cm9761_dac_clock_enum =
+	AC97_ENUM_SINGLE(AC97_CM9761_SPDIF_CTRL, 9, 3, cm9761_dac_clock);
+
+static const snd_kcontrol_new_t snd_ac97_cm9761_controls_spdif[] = {
+	{ /* BIT 1: SPDIFS */
+		.iface	= SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name	= SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
+		.info = cm9761_spdif_out_source_info,
+		.get = cm9761_spdif_out_source_get,
+		.put = cm9761_spdif_out_source_put,
 	},
+	/* BIT 2: IG_SPIV */
+	AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,NONE) "Valid Switch", AC97_CM9761_SPDIF_CTRL, 2, 1, 0),
+	/* BIT 3: SPI2F */
+	AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,NONE) "Monitor", AC97_CM9761_SPDIF_CTRL, 3, 1, 0), 
+	/* BIT 4: SPI2SDI */
+	AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), AC97_CM9761_SPDIF_CTRL, 4, 1, 0),
+	/* BIT 9-10: DAC_CTL */
+	AC97_ENUM("DAC Clock Source", cm9761_dac_clock_enum),
 };
 
+static int patch_cm9761_post_spdif(ac97_t * ac97)
+{
+	return patch_build_controls(ac97, snd_ac97_cm9761_controls_spdif, ARRAY_SIZE(snd_ac97_cm9761_controls_spdif));
+}
+
 static int patch_cm9761_specific(ac97_t * ac97)
 {
 	return patch_build_controls(ac97, snd_ac97_cm9761_controls, ARRAY_SIZE(snd_ac97_cm9761_controls));
@@ -2159,7 +2268,8 @@ static int patch_cm9761_specific(ac97_t 
 
 static struct snd_ac97_build_ops patch_cm9761_ops = {
 	.build_specific	= patch_cm9761_specific,
-	.build_post_spdif = patch_cm9739_post_spdif /* hope it's identical... */
+	.build_post_spdif = patch_cm9761_post_spdif,
+	.update_jacks = cm9761_update_jacks
 };
 
 int patch_cm9761(ac97_t *ac97)
@@ -2193,24 +2303,25 @@ int patch_cm9761(ac97_t *ac97)
 	/* to be sure: we overwrite the ext status bits */
 	snd_ac97_write_cache(ac97, AC97_EXTENDED_STATUS, 0x05c0);
 	/* Don't set 0x0200 here.  This results in the silent analog output */
-	snd_ac97_write_cache(ac97, AC97_CM9761_SPDIF_CTRL, 0x0009);
+	snd_ac97_write_cache(ac97, AC97_CM9761_SPDIF_CTRL, 0x0001); /* enable spdif-in */
 	ac97->rates[AC97_RATES_SPDIF] = SNDRV_PCM_RATE_48000; /* 48k only */
 
 	/* set-up multi channel */
 	/* bit 15: pc master beep off
-	 * bit 14: ??
+	 * bit 14: pin47 = EAPD/SPDIF
 	 * bit 13: vref ctl [= cm9739]
-	 * bit 12: center/mic [= cm9739] (reverted on rev B)
-	 * bit 11: ?? (mic/center/lfe) (reverted on rev B)
-	 * bit 10: suddound/line [= cm9739]
-	 * bit  9: mix 2 surround
-	 * bit  8: ?
-	 * bit  7: ?? (mic/center/lfe)
-	 * bit  4: ?? (front)
-	 * bit  3: ?? (line-in/rear share) (revereted with rev B)
-	 * bit  2: ?? (surround)
-	 * bit  1: front mic
-	 * bit  0: mic boost
+	 * bit 12: CLFE control (reverted on rev B)
+	 * bit 11: Mic/center share (reverted on rev B)
+	 * bit 10: suddound/line share
+	 * bit  9: Analog-in mix -> surround
+	 * bit  8: Analog-in mix -> CLFE
+	 * bit  7: Mic/LFE share (mic/center/lfe)
+	 * bit  5: vref select (9761A)
+	 * bit  4: front control
+	 * bit  3: surround control (revereted with rev B)
+	 * bit  2: front mic
+	 * bit  1: stereo mic
+	 * bit  0: mic boost level (0=20dB, 1=30dB)
 	 */
 
 #if 0
@@ -2230,6 +2341,47 @@ int patch_cm9761(ac97_t *ac97)
 	return 0;
 }
        
+#define AC97_CM9780_SIDE	0x60
+#define AC97_CM9780_JACK	0x62
+#define AC97_CM9780_MIXER	0x64
+#define AC97_CM9780_MULTI_CHAN	0x66
+#define AC97_CM9780_SPDIF	0x6c
+
+static const char *cm9780_ch_select[] = { "Front", "Side", "Center/LFE", "Rear" };
+static const struct ac97_enum cm9780_ch_select_enum =
+	AC97_ENUM_SINGLE(AC97_CM9780_MULTI_CHAN, 6, 4, cm9780_ch_select);
+static const snd_kcontrol_new_t cm9780_controls[] = {
+	AC97_DOUBLE("Side Playback Switch", AC97_CM9780_SIDE, 15, 7, 1, 1),
+	AC97_DOUBLE("Side Playback Volume", AC97_CM9780_SIDE, 8, 0, 31, 0),
+	AC97_ENUM("Side Playback Route", cm9780_ch_select_enum),
+};
+
+static int patch_cm9780_specific(ac97_t *ac97)
+{
+	return patch_build_controls(ac97, cm9780_controls, ARRAY_SIZE(cm9780_controls));
+}
+
+static struct snd_ac97_build_ops patch_cm9780_ops = {
+	.build_specific	= patch_cm9780_specific,
+	.build_post_spdif = patch_cm9761_post_spdif	/* identical with CM9761 */
+};
+
+int patch_cm9780(ac97_t *ac97)
+{
+	unsigned short val;
+
+	ac97->build_ops = &patch_cm9780_ops;
+
+	/* enable spdif */
+	if (ac97->ext_id & AC97_EI_SPDIF) {
+		ac97->rates[AC97_RATES_SPDIF] = SNDRV_PCM_RATE_48000; /* 48k only */
+		val = snd_ac97_read(ac97, AC97_CM9780_SPDIF);
+		val |= 0x1; /* SPDI_EN */
+		snd_ac97_write_cache(ac97, AC97_CM9780_SPDIF, val);
+	}
+
+	return 0;
+}
 
 /*
  * VIA VT1616 codec
@@ -2263,9 +2415,21 @@ int patch_vt1616(ac97_t * ac97)
 	return 0;
 }
 
+/*
+ */
+static void it2646_update_jacks(ac97_t *ac97)
+{
+	/* shared Line-In */
+	snd_ac97_update_bits(ac97, 0x76, 1 << 9,
+			     is_shared_linein(ac97) ? (1<<9) : 0);
+	/* shared Mic */
+	snd_ac97_update_bits(ac97, 0x76, 1 << 10,
+			     is_shared_micin(ac97) ? (1<<10) : 0);
+}
+
 static const snd_kcontrol_new_t snd_ac97_controls_it2646[] = {
-	AC97_SINGLE("Line-In As Surround", 0x76, 9, 1, 0),
-	AC97_SINGLE("Mic As Center/LFE", 0x76, 10, 1, 0),
+	AC97_SURROUND_JACK_MODE_CTL,
+	AC97_CHANNEL_MODE_CTL,
 };
 
 static const snd_kcontrol_new_t snd_ac97_spdif_controls_it2646[] = {
@@ -2285,7 +2449,8 @@ static int patch_it2646_specific(ac97_t 
 }
 
 static struct snd_ac97_build_ops patch_it2646_ops = {
-	.build_specific	= patch_it2646_specific
+	.build_specific	= patch_it2646_specific,
+	.update_jacks = it2646_update_jacks
 };
 
 int patch_it2646(ac97_t * ac97)
@@ -2297,12 +2462,29 @@ int patch_it2646(ac97_t * ac97)
 	return 0;
 }
 
-/* Si3036/8 specific registers */
+/*
+ * Si3036 codec
+ */
+
 #define AC97_SI3036_CHIP_ID     0x5a
+#define AC97_SI3036_LINE_CFG    0x5c
+
+static const snd_kcontrol_new_t snd_ac97_controls_si3036[] = {
+AC97_DOUBLE("Modem Speaker Volume", 0x5c, 14, 12, 3, 1)
+};
+
+static int patch_si3036_specific(ac97_t * ac97)
+{
+	return patch_build_controls(ac97, snd_ac97_controls_si3036, ARRAY_SIZE(snd_ac97_controls_si3036));
+}
+
+static struct snd_ac97_build_ops patch_si3036_ops = {
+	.build_specific	= patch_si3036_specific,
+};
 
 int mpatch_si3036(ac97_t * ac97)
 {
-	//printk("mpatch_si3036: chip id = %x\n", snd_ac97_read(ac97, 0x5a));
+	ac97->build_ops = &patch_si3036_ops;
 	snd_ac97_write_cache(ac97, 0x5c, 0xf210 );
 	snd_ac97_write_cache(ac97, 0x68, 0);
 	return 0;
diff --git a/sound/pci/ac97/ac97_patch.h b/sound/pci/ac97/ac97_patch.h
--- a/sound/pci/ac97/ac97_patch.h
+++ b/sound/pci/ac97/ac97_patch.h
@@ -54,6 +54,7 @@ int patch_alc850(ac97_t * ac97);
 int patch_cm9738(ac97_t * ac97);
 int patch_cm9739(ac97_t * ac97);
 int patch_cm9761(ac97_t * ac97);
+int patch_cm9780(ac97_t * ac97);
 int patch_vt1616(ac97_t * ac97);
 int patch_it2646(ac97_t * ac97);
 int mpatch_si3036(ac97_t * ac97);
diff --git a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c
--- a/sound/pci/ali5451/ali5451.c
+++ b/sound/pci/ali5451/ali5451.c
@@ -98,6 +98,8 @@ MODULE_PARM_DESC(spdif, "Support SPDIF I
 #define ALI_LEF_CHANNEL		23
 #define ALI_SURR_LEFT_CHANNEL	26
 #define ALI_SURR_RIGHT_CHANNEL	25
+#define ALI_MODEM_IN_CHANNEL    21
+#define ALI_MODEM_OUT_CHANNEL   20
 
 #define	SNDRV_ALI_VOICE_TYPE_PCM	01
 #define SNDRV_ALI_VOICE_TYPE_OTH	02
@@ -122,7 +124,15 @@ MODULE_PARM_DESC(spdif, "Support SPDIF I
 
 #define ALI_SCTRL		0x48
 #define   ALI_SPDIF_OUT_ENABLE		0x20
+#define   ALI_SCTRL_LINE_IN2		(1 << 9)
+#define   ALI_SCTRL_GPIO_IN2		(1 << 13)
+#define   ALI_SCTRL_LINE_OUT_EN 	(1 << 20)
+#define   ALI_SCTRL_GPIO_OUT_EN 	(1 << 23)
+#define   ALI_SCTRL_CODEC1_READY	(1 << 24)
+#define   ALI_SCTRL_CODEC2_READY	(1 << 25)
 #define ALI_AC97_GPIO		0x4c
+#define   ALI_AC97_GPIO_ENABLE		0x8000
+#define   ALI_AC97_GPIO_DATA_SHIFT	16
 #define ALI_SPDIF_CS		0x70
 #define ALI_SPDIF_CTRL		0x74
 #define   ALI_SPDIF_IN_FUNC_ENABLE	0x02
@@ -143,6 +153,7 @@ MODULE_PARM_DESC(spdif, "Support SPDIF I
 	#define TARGET_REACHED		0x00008000
 	#define MIXER_OVERFLOW		0x00000800
 	#define MIXER_UNDERFLOW		0x00000400
+	#define GPIO_IRQ		0x01000000
 #define ALI_SBBL_SBCL           0xc0
 #define ALI_SBCTRL_SBE2R_SBDD   0xc4
 #define ALI_STIMER		0xc8
@@ -162,6 +173,9 @@ MODULE_PARM_DESC(spdif, "Support SPDIF I
 
 #define ALI_REG(codec, x) ((codec)->port + x)
 
+#define MAX_CODECS 2
+
+
 typedef struct snd_stru_ali ali_t;
 typedef struct snd_ali_stru_voice snd_ali_voice_t;
 
@@ -245,7 +259,7 @@ struct snd_stru_ali {
 	struct pci_dev	*pci_m7101;
 
 	snd_card_t	*card;
-	snd_pcm_t	*pcm;
+	snd_pcm_t	*pcm[MAX_CODECS];
 	alidev_t	synth;
 	snd_ali_channel_control_t chregs;
 
@@ -255,8 +269,10 @@ struct snd_stru_ali {
 	unsigned int spurious_irq_count;
 	unsigned int spurious_irq_max_delta;
 
+	unsigned int num_of_codecs;
+
 	ac97_bus_t *ac97_bus;
-	ac97_t *ac97;
+	ac97_t *ac97[MAX_CODECS];
 	unsigned short	ac97_ext_id;
 	unsigned short	ac97_ext_status;
 
@@ -383,7 +399,7 @@ static int snd_ali_codec_ready(	ali_t *c
 	unsigned long end_time;
 	unsigned int res;
 	
-	end_time = jiffies + 10 * (HZ >> 2);
+	end_time = jiffies + 10 * msecs_to_jiffies(250);
 	do {
 		res = snd_ali_5451_peek(codec,port);
 		if (! (res & 0x8000))
@@ -406,7 +422,7 @@ static int snd_ali_stimer_ready(ali_t *c
 	dwChk1 = snd_ali_5451_peek(codec, ALI_STIMER);
 	dwChk2 = snd_ali_5451_peek(codec, ALI_STIMER);
 
-	end_time = jiffies + 10 * (HZ >> 2);
+	end_time = jiffies + 10 * msecs_to_jiffies(250);
 	do {
 		dwChk2 = snd_ali_5451_peek(codec, ALI_STIMER);
 		if (dwChk2 != dwChk1)
@@ -489,7 +505,12 @@ static void snd_ali_codec_write(ac97_t *
 	ali_t *codec = ac97->private_data;
 
 	snd_ali_printk("codec_write: reg=%xh data=%xh.\n", reg, val);
-	snd_ali_codec_poke(codec, 0, reg, val);
+	if(reg == AC97_GPIO_STATUS) {
+		outl((val << ALI_AC97_GPIO_DATA_SHIFT)|ALI_AC97_GPIO_ENABLE,
+			ALI_REG(codec, ALI_AC97_GPIO));
+		return;
+	}
+	snd_ali_codec_poke(codec, ac97->num, reg, val);
 	return ;
 }
 
@@ -499,7 +520,7 @@ static unsigned short snd_ali_codec_read
 	ali_t *codec = ac97->private_data;
 
 	snd_ali_printk("codec_read reg=%xh.\n", reg);
-	return (snd_ali_codec_peek(codec, 0, reg));
+	return (snd_ali_codec_peek(codec, ac97->num, reg));
 }
 
 /*
@@ -1051,7 +1072,7 @@ static irqreturn_t snd_ali_card_interrup
 }
 
 
-static snd_ali_voice_t *snd_ali_alloc_voice(ali_t * codec, int type, int rec)
+static snd_ali_voice_t *snd_ali_alloc_voice(ali_t * codec, int type, int rec, int channel)
 {
 	snd_ali_voice_t *pvoice = NULL;
 	unsigned long flags;
@@ -1061,7 +1082,8 @@ static snd_ali_voice_t *snd_ali_alloc_vo
 
 	spin_lock_irqsave(&codec->voice_alloc, flags);
 	if (type == SNDRV_ALI_VOICE_TYPE_PCM) {
-		idx = snd_ali_find_free_channel(codec,rec);
+		idx = channel > 0 ? snd_ali_alloc_pcm_channel(codec, channel) :
+			snd_ali_find_free_channel(codec,rec);
 		if(idx < 0) {
 			snd_printk("ali_alloc_voice: err.\n");
 			spin_unlock_irqrestore(&codec->voice_alloc, flags);
@@ -1297,7 +1319,7 @@ static int snd_ali_playback_hw_params(sn
 
 	if (params_buffer_size(hw_params)/2 != params_period_size(hw_params)) {
 		if (evoice == NULL) {
-			evoice = snd_ali_alloc_voice(codec, SNDRV_ALI_VOICE_TYPE_PCM, 0);
+			evoice = snd_ali_alloc_voice(codec, SNDRV_ALI_VOICE_TYPE_PCM, 0, -1);
 			if (evoice == NULL)
 				return -ENOMEM;
 			pvoice->extra = evoice;
@@ -1328,13 +1350,13 @@ static int snd_ali_playback_hw_free(snd_
 	return 0;
 }
 
-static int snd_ali_capture_hw_params(snd_pcm_substream_t * substream,
+static int snd_ali_hw_params(snd_pcm_substream_t * substream,
 				 snd_pcm_hw_params_t * hw_params)
 {
 	return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
 }
 
-static int snd_ali_capture_hw_free(snd_pcm_substream_t * substream)
+static int snd_ali_hw_free(snd_pcm_substream_t * substream)
 {
 	return snd_pcm_lib_free_pages(substream);
 }
@@ -1428,7 +1450,7 @@ static int snd_ali_playback_prepare(snd_
 }
 
 
-static int snd_ali_capture_prepare(snd_pcm_substream_t * substream)
+static int snd_ali_prepare(snd_pcm_substream_t * substream)
 {
 	ali_t *codec = snd_pcm_substream_chip(substream);
 	snd_pcm_runtime_t *runtime = substream->runtime;
@@ -1446,11 +1468,13 @@ static int snd_ali_capture_prepare(snd_p
 
 	spin_lock_irqsave(&codec->reg_lock, flags);
 
-	snd_ali_printk("capture_prepare...\n");
+	snd_ali_printk("ali_prepare...\n");
 
 	snd_ali_enable_special_channel(codec,pvoice->number);
 
-	Delta = snd_ali_convert_rate(runtime->rate, 1);
+	Delta = (pvoice->number == ALI_MODEM_IN_CHANNEL ||
+		 pvoice->number == ALI_MODEM_OUT_CHANNEL) ? 
+		0x1000 : snd_ali_convert_rate(runtime->rate, pvoice->mode);
 
 	// Prepare capture intr channel
 	if (pvoice->number == ALI_SPDIF_IN_CHANNEL) {
@@ -1534,7 +1558,7 @@ static snd_pcm_uframes_t snd_ali_playbac
 }
 
 
-static snd_pcm_uframes_t snd_ali_capture_pointer(snd_pcm_substream_t *substream)
+static snd_pcm_uframes_t snd_ali_pointer(snd_pcm_substream_t *substream)
 {
 	ali_t *codec = snd_pcm_substream_chip(substream);
 	snd_pcm_runtime_t *runtime = substream->runtime;
@@ -1616,7 +1640,8 @@ static void snd_ali_pcm_free_substream(s
 	}
 }
 
-static int snd_ali_playback_open(snd_pcm_substream_t * substream)
+static int snd_ali_open(snd_pcm_substream_t * substream, int rec, int channel,
+		snd_pcm_hardware_t *phw)
 {
 	ali_t *codec = snd_pcm_substream_chip(substream);
 	snd_pcm_runtime_t *runtime = substream->runtime;
@@ -1624,7 +1649,7 @@ static int snd_ali_playback_open(snd_pcm
 	unsigned long flags = 0;
 
 	spin_lock_irqsave(&codec->reg_lock, flags);
-	pvoice = snd_ali_alloc_voice(codec, SNDRV_ALI_VOICE_TYPE_PCM, 0);
+	pvoice = snd_ali_alloc_voice(codec, SNDRV_ALI_VOICE_TYPE_PCM, rec, channel);
 	if (pvoice == NULL) {
 		spin_unlock_irqrestore(&codec->reg_lock, flags);
 		return -EAGAIN;
@@ -1636,49 +1661,31 @@ static int snd_ali_playback_open(snd_pcm
 	runtime->private_data = pvoice;
 	runtime->private_free = snd_ali_pcm_free_substream;
 
-	runtime->hw = snd_ali_playback;
+	runtime->hw = *phw;
 	snd_pcm_set_sync(substream);
 	snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 64*1024);
 	return 0;
 }
 
+static int snd_ali_playback_open(snd_pcm_substream_t * substream)
+{
+	return snd_ali_open(substream, 0, -1, &snd_ali_playback);
+}
 
 static int snd_ali_capture_open(snd_pcm_substream_t * substream)
 {
-	ali_t *codec = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	snd_ali_voice_t *pvoice;
-	unsigned long flags;
-
-	spin_lock_irqsave(&codec->reg_lock, flags);
-	pvoice = snd_ali_alloc_voice(codec, SNDRV_ALI_VOICE_TYPE_PCM, 1);
-	if (pvoice == NULL) {
-		spin_unlock_irqrestore(&codec->reg_lock, flags);
-		return -EAGAIN;
-	}
-	pvoice->codec = codec;
-	spin_unlock_irqrestore(&codec->reg_lock, flags);
-
-	pvoice->substream = substream;
-	runtime->private_data = pvoice;
-	runtime->private_free = snd_ali_pcm_free_substream;
-	runtime->hw = snd_ali_capture;
-	snd_pcm_set_sync(substream);
-	snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 64*1024);
-	return 0;
+	return snd_ali_open(substream, 1, -1, &snd_ali_capture);
 }
 
-
 static int snd_ali_playback_close(snd_pcm_substream_t * substream)
 {
 	return 0;
 }
 
-static int snd_ali_capture_close(snd_pcm_substream_t * substream)
+static int snd_ali_close(snd_pcm_substream_t * substream)
 {
 	ali_t *codec = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	snd_ali_voice_t *pvoice = (snd_ali_voice_t *) runtime->private_data;
+	snd_ali_voice_t *pvoice = (snd_ali_voice_t *) substream->runtime->private_data;
 
 	snd_ali_disable_special_channel(codec,pvoice->number);
 
@@ -1698,29 +1705,121 @@ static snd_pcm_ops_t snd_ali_playback_op
 
 static snd_pcm_ops_t snd_ali_capture_ops = {
 	.open =		snd_ali_capture_open,
-	.close =	snd_ali_capture_close,
+	.close =	snd_ali_close,
 	.ioctl =	snd_ali_ioctl,
-	.hw_params =	snd_ali_capture_hw_params,
-	.hw_free =	snd_ali_capture_hw_free,
-	.prepare =	snd_ali_capture_prepare,
+	.hw_params =	snd_ali_hw_params,
+	.hw_free =	snd_ali_hw_free,
+	.prepare =	snd_ali_prepare,
+	.trigger =	snd_ali_trigger,
+	.pointer =	snd_ali_pointer,
+};
+
+/*
+ * Modem PCM
+ */
+
+static int snd_ali_modem_hw_params(snd_pcm_substream_t * substream,
+				 snd_pcm_hw_params_t * hw_params)
+{
+	ali_t *chip = snd_pcm_substream_chip(substream);
+	unsigned int modem_num = chip->num_of_codecs - 1;
+	snd_ac97_write(chip->ac97[modem_num], AC97_LINE1_RATE, params_rate(hw_params));
+	snd_ac97_write(chip->ac97[modem_num], AC97_LINE1_LEVEL, 0);
+	return snd_ali_hw_params(substream, hw_params);
+}
+
+static snd_pcm_hardware_t snd_ali_modem =
+{
+	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
+				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
+				 SNDRV_PCM_INFO_MMAP_VALID |
+				 SNDRV_PCM_INFO_RESUME |
+				 SNDRV_PCM_INFO_SYNC_START),
+	.formats =		SNDRV_PCM_FMTBIT_S16_LE,
+	.rates =		SNDRV_PCM_RATE_KNOT|SNDRV_PCM_RATE_8000|SNDRV_PCM_RATE_16000,
+	.rate_min =		8000,
+	.rate_max =		16000,
+	.channels_min =		1,
+	.channels_max =		1,
+	.buffer_bytes_max =	(256*1024),
+	.period_bytes_min =	64,
+	.period_bytes_max =	(256*1024),
+	.periods_min =		1,
+	.periods_max =		1024,
+	.fifo_size =		0,
+};
+
+static int snd_ali_modem_open(snd_pcm_substream_t * substream, int rec, int channel)
+{
+	static unsigned int rates [] = {8000,9600,12000,16000};
+	static snd_pcm_hw_constraint_list_t hw_constraint_rates = {
+		.count = ARRAY_SIZE(rates),
+		.list = rates,
+		.mask = 0,
+	};
+	int err = snd_ali_open(substream, rec, channel, &snd_ali_modem);
+	if (err)
+		return err;
+	return snd_pcm_hw_constraint_list(substream->runtime, 0,
+			SNDRV_PCM_HW_PARAM_RATE, &hw_constraint_rates);
+}
+
+static int snd_ali_modem_playback_open(snd_pcm_substream_t * substream)
+{
+	return snd_ali_modem_open(substream, 0, ALI_MODEM_OUT_CHANNEL);
+}
+
+static int snd_ali_modem_capture_open(snd_pcm_substream_t * substream)
+{
+	return snd_ali_modem_open(substream, 1, ALI_MODEM_IN_CHANNEL);
+}
+
+static snd_pcm_ops_t snd_ali_modem_playback_ops = {
+	.open =		snd_ali_modem_playback_open,
+	.close =	snd_ali_close,
+	.ioctl =	snd_pcm_lib_ioctl,
+	.hw_params =	snd_ali_modem_hw_params,
+	.hw_free =	snd_ali_hw_free,
+	.prepare =	snd_ali_prepare,
+	.trigger =	snd_ali_trigger,
+	.pointer =	snd_ali_pointer,
+};
+
+static snd_pcm_ops_t snd_ali_modem_capture_ops = {
+	.open =		snd_ali_modem_capture_open,
+	.close =	snd_ali_close,
+	.ioctl =	snd_pcm_lib_ioctl,
+	.hw_params =	snd_ali_modem_hw_params,
+	.hw_free =	snd_ali_hw_free,
+	.prepare =	snd_ali_prepare,
 	.trigger =	snd_ali_trigger,
-	.pointer =	snd_ali_capture_pointer,
+	.pointer =	snd_ali_pointer,
+};
+
+
+struct ali_pcm_description {
+	char *name;
+	unsigned int playback_num;
+	unsigned int capture_num;
+	snd_pcm_ops_t *playback_ops;
+	snd_pcm_ops_t *capture_ops;
 };
 
 
 static void snd_ali_pcm_free(snd_pcm_t *pcm)
 {
 	ali_t *codec = pcm->private_data;
-	codec->pcm = NULL;
+	codec->pcm[pcm->device] = NULL;
 }
 
-static int __devinit snd_ali_pcm(ali_t * codec, int device, snd_pcm_t ** rpcm)
+
+static int __devinit snd_ali_pcm(ali_t * codec, int device, struct ali_pcm_description *desc)
 {
 	snd_pcm_t *pcm;
 	int err;
 
-	if (rpcm) *rpcm = NULL;
-	err = snd_pcm_new(codec->card, "ALI 5451", device, ALI_CHANNELS, 1, &pcm);
+	err = snd_pcm_new(codec->card, desc->name, device,
+			  desc->playback_num, desc->capture_num, &pcm);
 	if (err < 0) {
 		snd_printk("snd_ali_pcm: err called snd_pcm_new.\n");
 		return err;
@@ -1728,20 +1827,36 @@ static int __devinit snd_ali_pcm(ali_t *
 	pcm->private_data = codec;
 	pcm->private_free = snd_ali_pcm_free;
 	pcm->info_flags = 0;
-	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ali_playback_ops);
-	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_ali_capture_ops);
+	if (desc->playback_ops)
+		snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, desc->playback_ops);
+	if (desc->capture_ops)
+		snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, desc->capture_ops);
 
 	snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
 					      snd_dma_pci_data(codec->pci), 64*1024, 128*1024);
 
 	pcm->info_flags = 0;
 	pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX;
-	strcpy(pcm->name, "ALI 5451");
-	codec->pcm = pcm;
-	if (rpcm) *rpcm = pcm;
+	strcpy(pcm->name, desc->name);
+	codec->pcm[0] = pcm;
 	return 0;
 }
 
+struct ali_pcm_description ali_pcms[] = {
+	{ "ALI 5451", ALI_CHANNELS, 1, &snd_ali_playback_ops, &snd_ali_capture_ops },
+	{ "ALI 5451 modem", 1, 1, &snd_ali_modem_playback_ops, &snd_ali_modem_capture_ops }
+};
+
+static int __devinit snd_ali_build_pcms(ali_t *codec)
+{
+	int i, err;
+	for(i = 0 ; i < codec->num_of_codecs && i < ARRAY_SIZE(ali_pcms) ; i++)
+		if((err = snd_ali_pcm(codec, i, &ali_pcms[i])) < 0)
+			return err;
+	return 0;
+}
+
+
 #define ALI5451_SPDIF(xname, xindex, value) \
 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex,\
 .info = snd_ali5451_spdif_info, .get = snd_ali5451_spdif_get, \
@@ -1860,14 +1975,14 @@ static void snd_ali_mixer_free_ac97_bus(
 static void snd_ali_mixer_free_ac97(ac97_t *ac97)
 {
 	ali_t *codec = ac97->private_data;
-	codec->ac97 = NULL;
+	codec->ac97[ac97->num] = NULL;
 }
 
 static int __devinit snd_ali_mixer(ali_t * codec)
 {
 	ac97_template_t ac97;
 	unsigned int idx;
-	int err;
+	int i, err;
 	static ac97_bus_ops_t ops = {
 		.write = snd_ali_codec_write,
 		.read = snd_ali_codec_read,
@@ -1880,10 +1995,16 @@ static int __devinit snd_ali_mixer(ali_t
 	memset(&ac97, 0, sizeof(ac97));
 	ac97.private_data = codec;
 	ac97.private_free = snd_ali_mixer_free_ac97;
-	if ((err = snd_ac97_mixer(codec->ac97_bus, &ac97, &codec->ac97)) < 0) {
-		snd_printk("ali mixer creating error.\n");
+
+	for ( i = 0 ; i < codec->num_of_codecs ; i++) {
+		ac97.num = i;
+		if ((err = snd_ac97_mixer(codec->ac97_bus, &ac97, &codec->ac97[i])) < 0) {
+			snd_printk("ali mixer %d creating error.\n", i);
+			if(i == 0)
 		return err;
 	}
+	}
+
 	if (codec->spdif_support) {
 		for(idx = 0; idx < ARRAY_SIZE(snd_ali5451_mixer_spdif); idx++) {
 			err=snd_ctl_add(codec->card, snd_ctl_new1(&snd_ali5451_mixer_spdif[idx], codec));
@@ -1904,8 +2025,12 @@ static int ali_suspend(snd_card_t *card,
 	if (! im)
 		return 0;
 
-	snd_pcm_suspend_all(chip->pcm);
-	snd_ac97_suspend(chip->ac97);
+	for(i = 0 ; i < chip->num_of_codecs ; i++) {
+		if (chip->pcm[i])
+			snd_pcm_suspend_all(chip->pcm[i]);
+		if(chip->ac97[i])
+			snd_ac97_suspend(chip->ac97[i]);
+	}
 
 	spin_lock_irq(&chip->reg_lock);
 	
@@ -1969,7 +2094,9 @@ static int ali_resume(snd_card_t *card)
 	
 	spin_unlock_irq(&chip->reg_lock);
 
-	snd_ac97_resume(chip->ac97);
+	for(i = 0 ; i < chip->num_of_codecs ; i++)
+		if(chip->ac97[i])
+			snd_ac97_resume(chip->ac97[i]);
 	
 	return 0;
 }
@@ -2036,11 +2163,37 @@ static int snd_ali_chip_init(ali_t *code
 		codec->spdif_mask = 0x00000002;
 	}
 
+	codec->num_of_codecs = 1;
+
+	/* secondary codec - modem */
+	if (inl(ALI_REG(codec, ALI_SCTRL)) & ALI_SCTRL_CODEC2_READY) {
+		codec->num_of_codecs++;
+		outl(inl(ALI_REG(codec, ALI_SCTRL)) |
+			(ALI_SCTRL_LINE_IN2|ALI_SCTRL_GPIO_IN2|ALI_SCTRL_LINE_OUT_EN),
+			ALI_REG(codec, ALI_SCTRL));
+	}
+
 	snd_ali_printk("chip initialize succeed.\n");
 	return 0;
 
 }
 
+/* proc for register dump */
+static void snd_ali_proc_read(snd_info_entry_t *entry, snd_info_buffer_t *buf)
+{
+	ali_t *codec = entry->private_data;
+	int i;
+	for(i = 0 ; i < 256 ; i+= 4)
+		snd_iprintf(buf, "%02x: %08x\n", i, inl(ALI_REG(codec, i)));
+}
+
+static void __devinit snd_ali_proc_init(ali_t *codec)
+{
+	snd_info_entry_t *entry;
+	if(!snd_card_proc_new(codec->card, "ali5451", &entry))
+		snd_info_set_text_ops(entry, codec, 1024, snd_ali_proc_read);
+}
+
 static int __devinit snd_ali_resources(ali_t *codec)
 {
 	int err;
@@ -2233,11 +2386,13 @@ static int __devinit snd_ali_probe(struc
 	}
 	
 	snd_ali_printk("pcm building ...\n");
-	if ((err = snd_ali_pcm(codec, 0, NULL)) < 0) {
+	if ((err = snd_ali_build_pcms(codec)) < 0) {
 		snd_card_free(card);
 		return err;
 	}
 
+	snd_ali_proc_init(codec);
+
 	strcpy(card->driver, "ALI5451");
 	strcpy(card->shortname, "ALI 5451");
 	
@@ -2270,7 +2425,7 @@ static struct pci_driver driver = {
 
 static int __init alsa_card_ali_init(void)
 {
-	return pci_module_init(&driver);
+	return pci_register_driver(&driver);
 }
 
 static void __exit alsa_card_ali_exit(void)
diff --git a/sound/pci/als4000.c b/sound/pci/als4000.c
--- a/sound/pci/als4000.c
+++ b/sound/pci/als4000.c
@@ -367,7 +367,7 @@ static irqreturn_t snd_als4000_interrupt
 	if ((gcr_status & 0x40) && (chip->capture_substream)) /* capturing */
 		snd_pcm_period_elapsed(chip->capture_substream);
 	if ((gcr_status & 0x10) && (chip->rmidi)) /* MPU401 interrupt */
-		snd_mpu401_uart_interrupt(irq, chip->rmidi, regs);
+		snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data, regs);
 	/* release the gcr */
 	outb(gcr_status, chip->alt_port + 0xe);
 	
@@ -777,7 +777,7 @@ static struct pci_driver driver = {
 
 static int __init alsa_card_als4000_init(void)
 {
-	return pci_module_init(&driver);
+	return pci_register_driver(&driver);
 }
 
 static void __exit alsa_card_als4000_exit(void)
diff --git a/sound/pci/atiixp.c b/sound/pci/atiixp.c
--- a/sound/pci/atiixp.c
+++ b/sound/pci/atiixp.c
@@ -1334,8 +1334,8 @@ static irqreturn_t snd_atiixp_interrupt(
 
 static struct ac97_quirk ac97_quirks[] __devinitdata = {
 	{
-		.vendor = 0x103c,
-		.device = 0x006b,
+		.subvendor = 0x103c,
+		.subdevice = 0x006b,
 		.name = "HP Pavilion ZV5030US",
 		.type = AC97_TUNE_MUTE_LED
 	},
@@ -1645,7 +1645,7 @@ static struct pci_driver driver = {
 
 static int __init alsa_card_atiixp_init(void)
 {
-	return pci_module_init(&driver);
+	return pci_register_driver(&driver);
 }
 
 static void __exit alsa_card_atiixp_exit(void)
diff --git a/sound/pci/atiixp_modem.c b/sound/pci/atiixp_modem.c
--- a/sound/pci/atiixp_modem.c
+++ b/sound/pci/atiixp_modem.c
@@ -265,6 +265,7 @@ struct snd_atiixp {
  */
 static struct pci_device_id snd_atiixp_ids[] = {
 	{ 0x1002, 0x434d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* SB200 */
+	{ 0x1002, 0x4378, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* SB400 */
 	{ 0, }
 };
 
@@ -463,6 +464,11 @@ static unsigned short snd_atiixp_ac97_re
 static void snd_atiixp_ac97_write(ac97_t *ac97, unsigned short reg, unsigned short val)
 {
 	atiixp_t *chip = ac97->private_data;
+	if (reg == AC97_GPIO_STATUS) {
+		atiixp_write(chip, MODEM_OUT_GPIO,
+			(val << ATI_REG_MODEM_OUT_GPIO_DATA_SHIFT) | ATI_REG_MODEM_OUT_GPIO_EN);
+		return;
+	}
 	snd_atiixp_codec_write(chip, ac97->num, reg, val);
 }
 
@@ -663,44 +669,33 @@ static int snd_atiixp_pcm_trigger(snd_pc
 {
 	atiixp_t *chip = snd_pcm_substream_chip(substream);
 	atiixp_dma_t *dma = (atiixp_dma_t *)substream->runtime->private_data;
-	unsigned int reg = 0;
-	int i;
+	int err = 0;
 
 	snd_assert(dma->ops->enable_transfer && dma->ops->flush_dma, return -EINVAL);
 
-	if (cmd != SNDRV_PCM_TRIGGER_START && cmd != SNDRV_PCM_TRIGGER_STOP)
-		return -EINVAL;
-
 	spin_lock(&chip->reg_lock);
-
-	/* hook off/on: via GPIO_OUT */
-	for (i = 0; i < NUM_ATI_CODECS; i++) {
-		if (chip->ac97[i]) {
-			reg = snd_ac97_read(chip->ac97[i], AC97_GPIO_STATUS);
-			break;
-	}
-	}
-	if(cmd == SNDRV_PCM_TRIGGER_START)
-		reg |= AC97_GPIO_LINE1_OH;
-	else
-		reg &= ~AC97_GPIO_LINE1_OH;
-	reg = (reg << ATI_REG_MODEM_OUT_GPIO_DATA_SHIFT) | ATI_REG_MODEM_OUT_GPIO_EN ;
-	atiixp_write(chip, MODEM_OUT_GPIO, reg);
-
-	if (cmd == SNDRV_PCM_TRIGGER_START) {
+	switch(cmd) {
+	case SNDRV_PCM_TRIGGER_START:
 		dma->ops->enable_transfer(chip, 1);
 		dma->running = 1;
-	} else {
+		break;
+	case SNDRV_PCM_TRIGGER_STOP:
 		dma->ops->enable_transfer(chip, 0);
 		dma->running = 0;
+		break;
+	default:
+		err = -EINVAL;
+		break;
 	}
+	if (! err) {
 	snd_atiixp_check_bus_busy(chip);
 	if (cmd == SNDRV_PCM_TRIGGER_STOP) {
 		dma->ops->flush_dma(chip);
 		snd_atiixp_check_bus_busy(chip);
 	}
+	}
 	spin_unlock(&chip->reg_lock);
-	return 0;
+	return err;
 }
 
 
@@ -1332,7 +1327,7 @@ static struct pci_driver driver = {
 
 static int __init alsa_card_atiixp_init(void)
 {
-	return pci_module_init(&driver);
+	return pci_register_driver(&driver);
 }
 
 static void __exit alsa_card_atiixp_exit(void)
diff --git a/sound/pci/au88x0/au88x0.c b/sound/pci/au88x0/au88x0.c
--- a/sound/pci/au88x0/au88x0.c
+++ b/sound/pci/au88x0/au88x0.c
@@ -375,7 +375,7 @@ static struct pci_driver driver = {
 // initialization of the module
 static int __init alsa_card_vortex_init(void)
 {
-	return pci_module_init(&driver);
+	return pci_register_driver(&driver);
 }
 
 // clean up the module
diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c
--- a/sound/pci/azt3328.c
+++ b/sound/pci/azt3328.c
@@ -1520,7 +1520,7 @@ static int __init alsa_card_azf3328_init
 {
 	int err;
 	snd_azf3328_dbgcallenter();
-	err = pci_module_init(&driver);
+	err = pci_register_driver(&driver);
 	snd_azf3328_dbgcallleave();
 	return err;
 }
diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c
--- a/sound/pci/bt87x.c
+++ b/sound/pci/bt87x.c
@@ -798,13 +798,15 @@ static struct {
 	{0x270f, 0xfc00}, /* Chaintech Digitop DST-1000 DVB-S */
 };
 
+static struct pci_driver driver;
+
 /* return the rate of the card, or a negative value if it's blacklisted */
 static int __devinit snd_bt87x_detect_card(struct pci_dev *pci)
 {
 	int i;
 	const struct pci_device_id *supported;
 
-	supported = pci_match_device(snd_bt87x_ids, pci);
+	supported = pci_match_device(&driver, pci);
 	if (supported)
 		return supported->driver_data;
 
@@ -918,7 +920,7 @@ static int __init alsa_card_bt87x_init(v
 {
 	if (load_all)
 		driver.id_table = snd_bt87x_default_ids;
-	return pci_module_init(&driver);
+	return pci_register_driver(&driver);
 }
 
 static void __exit alsa_card_bt87x_exit(void)
diff --git a/sound/pci/ca0106/ca0106.h b/sound/pci/ca0106/ca0106.h
--- a/sound/pci/ca0106/ca0106.h
+++ b/sound/pci/ca0106/ca0106.h
@@ -1,7 +1,7 @@
 /*
  *  Copyright (c) 2004 James Courtier-Dutton <James@superbug.demon.co.uk>
  *  Driver CA0106 chips. e.g. Sound Blaster Audigy LS and Live 24bit
- *  Version: 0.0.20
+ *  Version: 0.0.21
  *
  *  FEATURES currently supported:
  *    See ca0106_main.c for features.
@@ -45,6 +45,8 @@
  *    Added I2C and SPI registers. Filled in interrupt enable.
  *  0.0.20
  *    Added GPIO info for SB Live 24bit.
+ *  0.0.21
+ *   Implement support for Line-in capture on SB Live 24bit.
  *
  *
  *  This code was initally based on code from ALSA's emu10k1x.c which is:
@@ -152,7 +154,7 @@
 						 * bit 9 0 = Mute / 1 = Analog out.
 						 * bit 10 0 = Line-in / 1 = Mic-in.
 						 * bit 11 0 = ? / 1 = ?
-						 * bit 12 0 = ? / 1 = ?
+						 * bit 12 0 = 48 Khz / 1 = 96 Khz Analog out on SB Live 24bit.
 						 * bit 13 0 = ? / 1 = ?
 						 * bit 14 0 = Mute / 1 = Analog out
 						 * bit 15 0 = ? / 1 = ?
@@ -475,9 +477,56 @@
 						/* Causes interrupts based on timer intervals. */
 #define SPI			0x7a		/* SPI: Serial Interface Register */
 #define I2C_A			0x7b		/* I2C Address. 32 bit */
-#define I2C_0			0x7c		/* I2C Data Port 0. 32 bit */
-#define I2C_1			0x7d		/* I2C Data Port 1. 32 bit */
-
+#define I2C_D0			0x7c		/* I2C Data Port 0. 32 bit */
+#define I2C_D1			0x7d		/* I2C Data Port 1. 32 bit */
+//I2C values
+#define I2C_A_ADC_ADD_MASK	0x000000fe	//The address is a 7 bit address
+#define I2C_A_ADC_RW_MASK	0x00000001	//bit mask for R/W
+#define I2C_A_ADC_TRANS_MASK	0x00000010  	//Bit mask for I2c address DAC value
+#define I2C_A_ADC_ABORT_MASK	0x00000020	//Bit mask for I2C transaction abort flag
+#define I2C_A_ADC_LAST_MASK	0x00000040	//Bit mask for Last word transaction
+#define I2C_A_ADC_BYTE_MASK	0x00000080	//Bit mask for Byte Mode
+
+#define I2C_A_ADC_ADD		0x00000034	//This is the Device address for ADC 
+#define I2C_A_ADC_READ		0x00000001	//To perform a read operation
+#define I2C_A_ADC_START		0x00000100	//Start I2C transaction
+#define I2C_A_ADC_ABORT		0x00000200	//I2C transaction abort
+#define I2C_A_ADC_LAST		0x00000400	//I2C last transaction
+#define I2C_A_ADC_BYTE		0x00000800	//I2C one byte mode
+
+#define I2C_D_ADC_REG_MASK	0xfe000000  	//ADC address register 
+#define I2C_D_ADC_DAT_MASK	0x01ff0000  	//ADC data register
+
+#define ADC_TIMEOUT		0x00000007	//ADC Timeout Clock Disable
+#define ADC_IFC_CTRL		0x0000000b	//ADC Interface Control
+#define ADC_MASTER		0x0000000c	//ADC Master Mode Control
+#define ADC_POWER		0x0000000d	//ADC PowerDown Control
+#define ADC_ATTEN_ADCL		0x0000000e	//ADC Attenuation ADCL
+#define ADC_ATTEN_ADCR		0x0000000f	//ADC Attenuation ADCR
+#define ADC_ALC_CTRL1		0x00000010	//ADC ALC Control 1
+#define ADC_ALC_CTRL2		0x00000011	//ADC ALC Control 2
+#define ADC_ALC_CTRL3		0x00000012	//ADC ALC Control 3
+#define ADC_NOISE_CTRL		0x00000013	//ADC Noise Gate Control
+#define ADC_LIMIT_CTRL		0x00000014	//ADC Limiter Control
+#define ADC_MUX			0x00000015  	//ADC Mux offset
+
+#if 0
+/* FIXME: Not tested yet. */
+#define ADC_GAIN_MASK		0x000000ff	//Mask for ADC Gain
+#define ADC_ZERODB		0x000000cf	//Value to set ADC to 0dB
+#define ADC_MUTE_MASK		0x000000c0	//Mask for ADC mute
+#define ADC_MUTE		0x000000c0	//Value to mute ADC
+#define ADC_OSR			0x00000008	//Mask for ADC oversample rate select
+#define ADC_TIMEOUT_DISABLE	0x00000008	//Value and mask to disable Timeout clock
+#define ADC_HPF_DISABLE		0x00000100	//Value and mask to disable High pass filter
+#define ADC_TRANWIN_MASK	0x00000070	//Mask for Length of Transient Window
+#endif
+
+#define ADC_MUX_MASK		0x0000000f	//Mask for ADC Mux
+#define ADC_MUX_MIC		0x00000002	//Value to select Mic at ADC Mux
+#define ADC_MUX_LINEIN		0x00000004	//Value to select LineIn at ADC Mux
+#define ADC_MUX_PHONE		0x00000001	//Value to select TAD at ADC Mux (Not used)
+#define ADC_MUX_AUX		0x00000008	//Value to select Aux at ADC Mux
 
 #define SET_CHANNEL 0  /* Testing channel outputs 0=Front, 1=Center/LFE, 2=Unknown, 3=Rear */
 #define PCM_FRONT_CHANNEL 0
@@ -508,9 +557,18 @@ struct snd_ca0106_pcm {
 	unsigned short running;
 };
 
+typedef struct {
+        u32 serial;
+        char * name;
+        int ac97;
+	int gpio_type;
+	int i2c_adc;
+} ca0106_details_t;
+
 // definition of the chip-specific record
 struct snd_ca0106 {
 	snd_card_t *card;
+	ca0106_details_t *details;
 	struct pci_dev *pci;
 
 	unsigned long port;
@@ -531,6 +589,7 @@ struct snd_ca0106 {
 	u32 spdif_bits[4];             /* s/pdif out setup */
 	int spdif_enable;
 	int capture_source;
+	int capture_mic_line_in;
 
 	struct snd_dma_buffer buffer;
 };
@@ -547,3 +606,6 @@ void snd_ca0106_ptr_write(ca0106_t *emu,
 				   unsigned int chn, 
 				   unsigned int data);
 
+int snd_ca0106_i2c_write(ca0106_t *emu, u32 reg, u32 value);
+
+
diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c
--- a/sound/pci/ca0106/ca0106_main.c
+++ b/sound/pci/ca0106/ca0106_main.c
@@ -1,7 +1,7 @@
 /*
  *  Copyright (c) 2004 James Courtier-Dutton <James@superbug.demon.co.uk>
  *  Driver CA0106 chips. e.g. Sound Blaster Audigy LS and Live 24bit
- *  Version: 0.0.22
+ *  Version: 0.0.23
  *
  *  FEATURES currently supported:
  *    Front, Rear and Center/LFE.
@@ -77,6 +77,8 @@
  *    Add SPDIF capture using optional digital I/O module for SB Live 24bit. (Analog capture does not yet work.)
  *  0.0.22
  *    Add support for MSI K8N Diamond Motherboard with onboard SB Live 24bit without AC97. From kiksen, bug #901
+ *  0.0.23
+ *    Implement support for Line-in capture on SB Live 24bit.
  *
  *  BUGS:
  *    Some stability problems when unloading the snd-ca0106 kernel module.
@@ -136,6 +138,7 @@
 #include <linux/pci.h>
 #include <linux/slab.h>
 #include <linux/moduleparam.h>
+#include <linux/dma-mapping.h>
 #include <sound/core.h>
 #include <sound/initval.h>
 #include <sound/pcm.h>
@@ -161,18 +164,32 @@ MODULE_PARM_DESC(enable, "Enable the CA0
 
 #include "ca0106.h"
 
-typedef struct {
-	u32 serial;
-	char * name;
-} ca0106_names_t;
-
-static ca0106_names_t ca0106_chip_names[] = {
-	 { 0x10021102, "AudigyLS [SB0310]"} , 
-	 { 0x10051102, "AudigyLS [SB0310b]"} , /* Unknown AudigyLS that also says SB0310 on it */
-	 { 0x10061102, "Live! 7.1 24bit [SB0410]"} , /* New Sound Blaster Live! 7.1 24bit. This does not have an AC97. 53SB041000001 */
-	 { 0x10071102, "Live! 7.1 24bit [SB0413]"} , /* New Dell Sound Blaster Live! 7.1 24bit. This does not have an AC97.  */
-	 { 0x10091462, "MSI K8N Diamond MB [SB0438]"}, /* MSI K8N Diamond Motherboard with onboard SB Live 24bit without AC97 */
-	 { 0, "AudigyLS [Unknown]" }
+static ca0106_details_t ca0106_chip_details[] = {
+	 /* AudigyLS[SB0310] */
+	 { .serial = 0x10021102,
+	   .name   = "AudigyLS [SB0310]",
+	   .ac97   = 1 } , 
+	 /* Unknown AudigyLS that also says SB0310 on it */
+	 { .serial = 0x10051102,
+	   .name   = "AudigyLS [SB0310b]",
+	   .ac97   = 1 } ,
+	 /* New Sound Blaster Live! 7.1 24bit. This does not have an AC97. 53SB041000001 */
+	 { .serial = 0x10061102,
+	   .name   = "Live! 7.1 24bit [SB0410]",
+	   .gpio_type = 1,
+	   .i2c_adc = 1 } ,
+	 /* New Dell Sound Blaster Live! 7.1 24bit. This does not have an AC97.  */
+	 { .serial = 0x10071102,
+	   .name   = "Live! 7.1 24bit [SB0413]",
+	   .gpio_type = 1,
+	   .i2c_adc = 1 } ,
+	 /* MSI K8N Diamond Motherboard with onboard SB Live 24bit without AC97 */
+	 { .serial = 0x10091462,
+	   .name   = "MSI K8N Diamond MB [SB0438]",
+	   .gpio_type = 1,
+	   .i2c_adc = 1 } ,
+	 { .serial = 0,
+	   .name   = "AudigyLS [Unknown]" }
 };
 
 /* hardware definition */
@@ -200,10 +217,10 @@ static snd_pcm_hardware_t snd_ca0106_cap
 				 SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
 				 SNDRV_PCM_INFO_MMAP_VALID),
-	.formats =		SNDRV_PCM_FMTBIT_S16_LE,
-	.rates =		SNDRV_PCM_RATE_48000,
-	.rate_min =		48000,
-	.rate_max =		48000,
+	.formats =		SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE,
+	.rates =		SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000,
+	.rate_min =		44100,
+	.rate_max =		192000,
 	.channels_min =		2,
 	.channels_max =		2,
 	.buffer_bytes_max =	((65536 - 64) * 8),
@@ -246,6 +263,62 @@ void snd_ca0106_ptr_write(ca0106_t *emu,
 	spin_unlock_irqrestore(&emu->emu_lock, flags);
 }
 
+int snd_ca0106_i2c_write(ca0106_t *emu,
+				u32 reg,
+				u32 value)
+{
+	u32 tmp;
+	int timeout=0;
+	int status;
+	int retry;
+	if ((reg > 0x7f) || (value > 0x1ff))
+	{
+                snd_printk("i2c_write: invalid values.\n");
+		return -EINVAL;
+	}
+
+	tmp = reg << 25 | value << 16;
+	/* Not sure what this I2C channel controls. */
+	/* snd_ca0106_ptr_write(emu, I2C_D0, 0, tmp); */
+
+	/* This controls the I2C connected to the WM8775 ADC Codec */
+	snd_ca0106_ptr_write(emu, I2C_D1, 0, tmp);
+
+	for(retry=0;retry<10;retry++)
+	{
+		/* Send the data to i2c */
+		tmp = snd_ca0106_ptr_read(emu, I2C_A, 0);
+		tmp = tmp & ~(I2C_A_ADC_READ|I2C_A_ADC_LAST|I2C_A_ADC_START|I2C_A_ADC_ADD_MASK);
+		tmp = tmp | (I2C_A_ADC_LAST|I2C_A_ADC_START|I2C_A_ADC_ADD);
+		snd_ca0106_ptr_write(emu, I2C_A, 0, tmp);
+
+		/* Wait till the transaction ends */
+		while(1)
+		{
+			status = snd_ca0106_ptr_read(emu, I2C_A, 0);
+                	//snd_printk("I2C:status=0x%x\n", status);
+			timeout++;
+			if((status & I2C_A_ADC_START)==0)
+				break;
+
+			if(timeout>1000)
+				break;
+		}
+		//Read back and see if the transaction is successful
+		if((status & I2C_A_ADC_ABORT)==0)
+			break;
+	}
+
+	if(retry==10)
+	{
+                snd_printk("Writing to ADC failed!\n");
+		return -EINVAL;
+	}
+    
+    	return 0;
+}
+
+
 static void snd_ca0106_intr_enable(ca0106_t *emu, unsigned int intrenb)
 {
 	unsigned long flags;
@@ -259,11 +332,7 @@ static void snd_ca0106_intr_enable(ca010
 
 static void snd_ca0106_pcm_free_substream(snd_pcm_runtime_t *runtime)
 {
-	ca0106_pcm_t *epcm = runtime->private_data;
-  
-	if (epcm) {
-		kfree(epcm);
-	}
+	kfree(runtime->private_data);
 }
 
 /* open_playback callback */
@@ -538,6 +607,61 @@ static int snd_ca0106_pcm_prepare_captur
 	snd_pcm_runtime_t *runtime = substream->runtime;
 	ca0106_pcm_t *epcm = runtime->private_data;
 	int channel = epcm->channel_id;
+	u32 hcfg_mask = HCFG_CAPTURE_S32_LE;
+	u32 hcfg_set = 0x00000000;
+	u32 hcfg;
+	u32 over_sampling=0x2;
+	u32 reg71_mask = 0x0000c000 ; /* Global. Set ADC rate. */
+	u32 reg71_set = 0;
+	u32 reg71;
+	
+        //snd_printk("prepare:channel_number=%d, rate=%d, format=0x%x, channels=%d, buffer_size=%ld, period_size=%ld, periods=%u, frames_to_bytes=%d\n",channel, runtime->rate, runtime->format, runtime->channels, runtime->buffer_size, runtime->period_size, runtime->periods, frames_to_bytes(runtime, 1));
+        //snd_printk("dma_addr=%x, dma_area=%p, table_base=%p\n",runtime->dma_addr, runtime->dma_area, table_base);
+	//snd_printk("dma_addr=%x, dma_area=%p, dma_bytes(size)=%x\n",emu->buffer.addr, emu->buffer.area, emu->buffer.bytes);
+	/* reg71 controls ADC rate. */
+	switch (runtime->rate) {
+	case 44100:
+		reg71_set = 0x00004000;
+		break;
+        case 48000:
+		reg71_set = 0; 
+		break;
+	case 96000:
+		reg71_set = 0x00008000;
+		over_sampling=0xa;
+		break;
+	case 192000:
+		reg71_set = 0x0000c000; 
+		over_sampling=0xa;
+		break;
+	default:
+		reg71_set = 0; 
+		break;
+	}
+	/* Format is a global setting */
+	/* FIXME: Only let the first channel accessed set this. */
+	switch (runtime->format) {
+	case SNDRV_PCM_FORMAT_S16_LE:
+		hcfg_set = 0;
+		break;
+	case SNDRV_PCM_FORMAT_S32_LE:
+		hcfg_set = HCFG_CAPTURE_S32_LE;
+		break;
+	default:
+		hcfg_set = 0;
+		break;
+	}
+	hcfg = inl(emu->port + HCFG) ;
+	hcfg = (hcfg & ~hcfg_mask) | hcfg_set;
+	outl(hcfg, emu->port + HCFG);
+	reg71 = snd_ca0106_ptr_read(emu, 0x71, 0);
+	reg71 = (reg71 & ~reg71_mask) | reg71_set;
+	snd_ca0106_ptr_write(emu, 0x71, 0, reg71);
+        if (emu->details->i2c_adc == 1) { /* The SB0410 and SB0413 use I2C to control ADC. */
+	        snd_ca0106_i2c_write(emu, ADC_MASTER, over_sampling); /* Adjust the over sampler to better suit the capture rate. */
+	}
+
+
         //printk("prepare:channel_number=%d, rate=%d, format=0x%x, channels=%d, buffer_size=%ld, period_size=%ld, frames_to_bytes=%d\n",channel, runtime->rate, runtime->format, runtime->channels, runtime->buffer_size, runtime->period_size,  frames_to_bytes(runtime, 1));
 	snd_ca0106_ptr_write(emu, 0x13, channel, 0);
 	snd_ca0106_ptr_write(emu, CAPTURE_DMA_ADDR, channel, runtime->dma_addr);
@@ -810,6 +934,7 @@ static int snd_ca0106_ac97(ca0106_t *chi
 
 	memset(&ac97, 0, sizeof(ac97));
 	ac97.private_data = chip;
+	ac97.scaps = AC97_SCAP_NO_SPDIF;
 	return snd_ac97_mixer(pbus, &ac97, &chip->ac97);
 }
 
@@ -993,6 +1118,7 @@ static int __devinit snd_ca0106_create(s
 					 ca0106_t **rchip)
 {
 	ca0106_t *chip;
+	ca0106_details_t *c;
 	int err;
 	int ch;
 	static snd_device_ops_t ops = {
@@ -1003,8 +1129,8 @@ static int __devinit snd_ca0106_create(s
   
 	if ((err = pci_enable_device(pci)) < 0)
 		return err;
-	if (pci_set_dma_mask(pci, 0xffffffffUL) < 0 ||
-	    pci_set_consistent_dma_mask(pci, 0xffffffffUL) < 0) {
+	if (pci_set_dma_mask(pci, DMA_32BIT_MASK) < 0 ||
+	    pci_set_consistent_dma_mask(pci, DMA_32BIT_MASK) < 0) {
 		printk(KERN_ERR "error to set 32bit mask DMA\n");
 		pci_disable_device(pci);
 		return -ENXIO;
@@ -1054,6 +1180,15 @@ static int __devinit snd_ca0106_create(s
 	printk(KERN_INFO "Model %04x Rev %08x Serial %08x\n", chip->model,
 	       chip->revision, chip->serial);
 #endif
+	strcpy(card->driver, "CA0106");
+	strcpy(card->shortname, "CA0106");
+
+	for (c=ca0106_chip_details; c->serial; c++) {
+		if (c->serial == chip->serial) break;
+	}
+	chip->details = c;
+	sprintf(card->longname, "%s at 0x%lx irq %i",
+		c->name, chip->port, chip->irq);
 
 	outl(0, chip->port + INTE);
 
@@ -1113,7 +1248,7 @@ static int __devinit snd_ca0106_create(s
 	//snd_ca0106_ptr_write(chip, SPDIF_SELECT2, 0, 0xf0f003f); /* OSS drivers set this. */
 	/* Analog or Digital output */
 	snd_ca0106_ptr_write(chip, SPDIF_SELECT1, 0, 0xf);
-	snd_ca0106_ptr_write(chip, SPDIF_SELECT2, 0, 0x000b0000); /* 0x0b000000 for digital, 0x000b0000 for analog, from win2000 drivers */
+	snd_ca0106_ptr_write(chip, SPDIF_SELECT2, 0, 0x000f0000); /* 0x0b000000 for digital, 0x000b0000 for analog, from win2000 drivers. Use 0x000f0000 for surround71 */
 	chip->spdif_enable = 0; /* Set digital SPDIF output off */
 	chip->capture_source = 3; /* Set CAPTURE_SOURCE */
 	//snd_ca0106_ptr_write(chip, 0x45, 0, 0); /* Analogue out */
@@ -1138,13 +1273,11 @@ static int __devinit snd_ca0106_create(s
         snd_ca0106_ptr_write(chip, CAPTURE_SOURCE, 0x0, 0x333300e4); /* Select MIC, Line in, TAD in, AUX in */
 	chip->capture_source = 3; /* Set CAPTURE_SOURCE */
 
-        if ((chip->serial == 0x10061102) || 
-	    (chip->serial == 0x10071102) ||
-	    (chip->serial == 0x10091462)) { /* The SB0410 and SB0413 use GPIO differently. */
+        if (chip->details->gpio_type == 1) { /* The SB0410 and SB0413 use GPIO differently. */
 		/* FIXME: Still need to find out what the other GPIO bits do. E.g. For digital spdif out. */
 		outl(0x0, chip->port+GPIO);
 		//outl(0x00f0e000, chip->port+GPIO); /* Analog */
-		outl(0x005f4300, chip->port+GPIO); /* Analog */
+		outl(0x005f5301, chip->port+GPIO); /* Analog */
 	} else {
 		outl(0x0, chip->port+GPIO);
 		outl(0x005f03a3, chip->port+GPIO); /* Analog */
@@ -1157,6 +1290,10 @@ static int __devinit snd_ca0106_create(s
 	//outl(0x00000009, chip->port+HCFG);
 	outl(HCFG_AC97 | HCFG_AUDIOENABLE, chip->port+HCFG); /* AC97 2.0, Enable outputs. */
 
+        if (chip->details->i2c_adc == 1) { /* The SB0410 and SB0413 use I2C to control ADC. */
+	        snd_ca0106_i2c_write(chip, ADC_MUX, ADC_MUX_LINEIN); /* Enable Line-in capture. MIC in currently untested. */
+	}
+
 	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL,
 				  chip, &ops)) < 0) {
 		snd_ca0106_free(chip);
@@ -1172,7 +1309,6 @@ static int __devinit snd_ca0106_probe(st
 	static int dev;
 	snd_card_t *card;
 	ca0106_t *chip;
-	ca0106_names_t *c;
 	int err;
 
 	if (dev >= SNDRV_CARDS)
@@ -1207,9 +1343,7 @@ static int __devinit snd_ca0106_probe(st
 		snd_card_free(card);
 		return err;
 	}
-        if ((chip->serial != 0x10061102) && 
-	    (chip->serial != 0x10071102) && 
-	    (chip->serial != 0x10091462) ) { /* The SB0410 and SB0413 do not have an ac97 chip. */
+        if (chip->details->ac97 == 1) { /* The SB0410 and SB0413 do not have an AC97 chip. */
 		if ((err = snd_ca0106_ac97(chip)) < 0) {
 			snd_card_free(card);
 			return err;
@@ -1222,15 +1356,6 @@ static int __devinit snd_ca0106_probe(st
 
 	snd_ca0106_proc_init(chip);
 
-	strcpy(card->driver, "CA0106");
-	strcpy(card->shortname, "CA0106");
-
-	for (c=ca0106_chip_names; c->serial; c++) {
-		if (c->serial == chip->serial) break;
-	}
-	sprintf(card->longname, "%s at 0x%lx irq %i",
-		c->name, chip->port, chip->irq);
-
 	if ((err = snd_card_register(card)) < 0) {
 		snd_card_free(card);
 		return err;
@@ -1267,7 +1392,7 @@ static int __init alsa_card_ca0106_init(
 {
 	int err;
 
-	if ((err = pci_module_init(&driver)) > 0)
+	if ((err = pci_register_driver(&driver)) > 0)
 		return err;
 
 	return 0;
diff --git a/sound/pci/ca0106/ca0106_mixer.c b/sound/pci/ca0106/ca0106_mixer.c
--- a/sound/pci/ca0106/ca0106_mixer.c
+++ b/sound/pci/ca0106/ca0106_mixer.c
@@ -1,7 +1,7 @@
 /*
  *  Copyright (c) 2004 James Courtier-Dutton <James@superbug.demon.co.uk>
  *  Driver CA0106 chips. e.g. Sound Blaster Audigy LS and Live 24bit
- *  Version: 0.0.16
+ *  Version: 0.0.17
  *
  *  FEATURES currently supported:
  *    See ca0106_main.c for features.
@@ -37,6 +37,8 @@
  *    Separated ca0106.c into separate functional .c files.
  *  0.0.16
  *    Modified Copyright message.
+ *  0.0.17
+ *    Implement Mic and Line in Capture.
  *
  *  This code was initally based on code from ALSA's emu10k1x.c which is:
  *  Copyright (c) by Francisco Moraes <fmoraes@nc.rr.com>
@@ -113,7 +115,7 @@ static int snd_ca0106_shared_spdif_put(s
 		} else {
 			/* Analog */
 			snd_ca0106_ptr_write(emu, SPDIF_SELECT1, 0, 0xf);
-			snd_ca0106_ptr_write(emu, SPDIF_SELECT2, 0, 0x000b0000);
+			snd_ca0106_ptr_write(emu, SPDIF_SELECT2, 0, 0x000f0000);
 			snd_ca0106_ptr_write(emu, CAPTURE_CONTROL, 0,
 				snd_ca0106_ptr_read(emu, CAPTURE_CONTROL, 0) | 0x1000);
 			mask = inl(emu->port + GPIO) | 0x101;
@@ -183,6 +185,65 @@ static snd_kcontrol_new_t snd_ca0106_cap
 	.put =		snd_ca0106_capture_source_put
 };
 
+static int snd_ca0106_capture_mic_line_in_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+{
+	static char *texts[2] = { "Line in", "Mic in" };
+
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+	uinfo->count = 1;
+	uinfo->value.enumerated.items = 2;
+	if (uinfo->value.enumerated.item > 1)
+                uinfo->value.enumerated.item = 1;
+	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
+	return 0;
+}
+
+static int snd_ca0106_capture_mic_line_in_get(snd_kcontrol_t * kcontrol,
+					snd_ctl_elem_value_t * ucontrol)
+{
+	ca0106_t *emu = snd_kcontrol_chip(kcontrol);
+
+	ucontrol->value.enumerated.item[0] = emu->capture_mic_line_in;
+	return 0;
+}
+
+static int snd_ca0106_capture_mic_line_in_put(snd_kcontrol_t * kcontrol,
+					snd_ctl_elem_value_t * ucontrol)
+{
+	ca0106_t *emu = snd_kcontrol_chip(kcontrol);
+	unsigned int val;
+	int change = 0;
+	u32 tmp;
+
+	val = ucontrol->value.enumerated.item[0] ;
+	change = (emu->capture_mic_line_in != val);
+	if (change) {
+		emu->capture_mic_line_in = val;
+		if (val) {
+			snd_ca0106_i2c_write(emu, ADC_MUX, ADC_MUX_PHONE); /* Mute input */
+			tmp = inl(emu->port+GPIO) & ~0x400;
+			tmp = tmp | 0x400;
+			outl(tmp, emu->port+GPIO);
+			snd_ca0106_i2c_write(emu, ADC_MUX, ADC_MUX_MIC);
+		} else {
+			snd_ca0106_i2c_write(emu, ADC_MUX, ADC_MUX_PHONE); /* Mute input */
+			tmp = inl(emu->port+GPIO) & ~0x400;
+			outl(tmp, emu->port+GPIO);
+			snd_ca0106_i2c_write(emu, ADC_MUX, ADC_MUX_LINEIN);
+		}
+	}
+        return change;
+}
+
+static snd_kcontrol_new_t snd_ca0106_capture_mic_line_in __devinitdata =
+{
+	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
+	.name =		"Mic/Line in Capture",
+	.info =		snd_ca0106_capture_mic_line_in_info,
+	.get =		snd_ca0106_capture_mic_line_in_get,
+	.put =		snd_ca0106_capture_mic_line_in_put
+};
+
 static int snd_ca0106_spdif_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
@@ -437,7 +498,7 @@ static snd_kcontrol_new_t snd_ca0106_vol
 static snd_kcontrol_new_t snd_ca0106_volume_control_analog_unknown =
 {
         .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
-        .name =         "Analog Unknown Volume",
+        .name =         "Analog Side Volume",
         .info =         snd_ca0106_volume_info,
         .get =          snd_ca0106_volume_get_analog_unknown,
         .put =          snd_ca0106_volume_put_analog_unknown
@@ -620,10 +681,11 @@ int __devinit snd_ca0106_mixer(ca0106_t 
 		return -ENOMEM;
 	if ((err = snd_ctl_add(card, kctl)))
 		return err;
-	if ((kctl = ctl_find(card, SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT))) != NULL) {
-		/* already defined by ac97, remove it */
-		/* FIXME: or do we need both controls? */
-		remove_ctl(card, SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT));
+	if (emu->details->i2c_adc == 1) {
+		if ((kctl = snd_ctl_new1(&snd_ca0106_capture_mic_line_in, emu)) == NULL)
+			return -ENOMEM;
+		if ((err = snd_ctl_add(card, kctl)))
+			return err;
 	}
 	if ((kctl = snd_ctl_new1(&snd_ca0106_spdif_control, emu)) == NULL)
 		return -ENOMEM;
diff --git a/sound/pci/ca0106/ca0106_proc.c b/sound/pci/ca0106/ca0106_proc.c
--- a/sound/pci/ca0106/ca0106_proc.c
+++ b/sound/pci/ca0106/ca0106_proc.c
@@ -1,7 +1,7 @@
 /*
  *  Copyright (c) 2004 James Courtier-Dutton <James@superbug.demon.co.uk>
  *  Driver CA0106 chips. e.g. Sound Blaster Audigy LS and Live 24bit
- *  Version: 0.0.17
+ *  Version: 0.0.18
  *
  *  FEATURES currently supported:
  *    See ca0106_main.c for features.
@@ -39,7 +39,9 @@
  *    Modified Copyright message.
  *  0.0.17
  *    Add iec958 file in proc file system to show status of SPDIF in.
- *    
+ *  0.0.18
+ *    Implement support for Line-in capture on SB Live 24bit.
+ *
  *  This code was initally based on code from ALSA's emu10k1x.c which is:
  *  Copyright (c) by Francisco Moraes <fmoraes@nc.rr.com>
  *
@@ -95,7 +97,7 @@ static struct snd_ca0106_category_str sn
 };
 
 
-void snd_ca0106_proc_dump_iec958( snd_info_buffer_t *buffer, u32 value)
+static void snd_ca0106_proc_dump_iec958( snd_info_buffer_t *buffer, u32 value)
 {
 	int i;
 	u32 status[4];
@@ -407,6 +409,20 @@ static void snd_ca0106_proc_reg_write(sn
         }
 }
 
+static void snd_ca0106_proc_i2c_write(snd_info_entry_t *entry, 
+				       snd_info_buffer_t * buffer)
+{
+	ca0106_t *emu = entry->private_data;
+        char line[64];
+        unsigned int reg, val;
+        while (!snd_info_get_line(buffer, line, sizeof(line))) {
+                if (sscanf(line, "%x %x", &reg, &val) != 2)
+                        continue;
+                if ((reg <= 0x7f) || (val <= 0x1ff)) {
+                        snd_ca0106_i2c_write(emu, reg, val);
+		}
+        }
+}
 
 int __devinit snd_ca0106_proc_init(ca0106_t * emu)
 {
@@ -418,6 +434,7 @@ int __devinit snd_ca0106_proc_init(ca010
 		snd_info_set_text_ops(entry, emu, 1024, snd_ca0106_proc_reg_read32);
 		entry->c.text.write_size = 64;
 		entry->c.text.write = snd_ca0106_proc_reg_write32;
+		entry->mode |= S_IWUSR;
 	}
 	if(! snd_card_proc_new(emu->card, "ca0106_reg16", &entry))
 		snd_info_set_text_ops(entry, emu, 1024, snd_ca0106_proc_reg_read16);
@@ -427,6 +444,14 @@ int __devinit snd_ca0106_proc_init(ca010
 		snd_info_set_text_ops(entry, emu, 1024, snd_ca0106_proc_reg_read1);
 		entry->c.text.write_size = 64;
 		entry->c.text.write = snd_ca0106_proc_reg_write;
+		entry->mode |= S_IWUSR;
+//		entry->private_data = emu;
+	}
+	if(! snd_card_proc_new(emu->card, "ca0106_i2c", &entry)) {
+		snd_info_set_text_ops(entry, emu, 1024, snd_ca0106_proc_i2c_write);
+		entry->c.text.write_size = 64;
+		entry->c.text.write = snd_ca0106_proc_i2c_write;
+		entry->mode |= S_IWUSR;
 //		entry->private_data = emu;
 	}
 	if(! snd_card_proc_new(emu->card, "ca0106_regs2", &entry)) 
diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c
--- a/sound/pci/cmipci.c
+++ b/sound/pci/cmipci.c
@@ -306,7 +306,7 @@ MODULE_PARM_DESC(joystick_port, "Joystic
 #define CM_REG_FM_PCI		0x50
 
 /*
- * for CMI-8338 .. this is not valid for CMI-8738.
+ * access from SB-mixer port
  */
 #define CM_REG_EXTENT_IND	0xf0
 #define CM_VPHONE_MASK		0xe0	/* Phone volume control (0-3) << 5 */
@@ -315,6 +315,7 @@ MODULE_PARM_DESC(joystick_port, "Joystic
 #define CM_VSPKM		0x08	/* Speaker mute control, default high */
 #define CM_RLOOPREN		0x04    /* Rec. R-channel enable */
 #define CM_RLOOPLEN		0x02	/* Rec. L-channel enable */
+#define CM_VADMIC3		0x01	/* Mic record boost */
 
 /*
  * CMI-8338 spec ver 0.5 (this is not valid for CMI-8738):
@@ -488,71 +489,83 @@ struct snd_stru_cmipci {
 
 
 /* read/write operations for dword register */
-inline static void snd_cmipci_write(cmipci_t *cm, unsigned int cmd, unsigned int data)
+static inline void snd_cmipci_write(cmipci_t *cm, unsigned int cmd, unsigned int data)
 {
 	outl(data, cm->iobase + cmd);
 }
-inline static unsigned int snd_cmipci_read(cmipci_t *cm, unsigned int cmd)
+
+static inline unsigned int snd_cmipci_read(cmipci_t *cm, unsigned int cmd)
 {
 	return inl(cm->iobase + cmd);
 }
 
 /* read/write operations for word register */
-inline static void snd_cmipci_write_w(cmipci_t *cm, unsigned int cmd, unsigned short data)
+static inline void snd_cmipci_write_w(cmipci_t *cm, unsigned int cmd, unsigned short data)
 {
 	outw(data, cm->iobase + cmd);
 }
-inline static unsigned short snd_cmipci_read_w(cmipci_t *cm, unsigned int cmd)
+
+static inline unsigned short snd_cmipci_read_w(cmipci_t *cm, unsigned int cmd)
 {
 	return inw(cm->iobase + cmd);
 }
 
 /* read/write operations for byte register */
-inline static void snd_cmipci_write_b(cmipci_t *cm, unsigned int cmd, unsigned char data)
+static inline void snd_cmipci_write_b(cmipci_t *cm, unsigned int cmd, unsigned char data)
 {
 	outb(data, cm->iobase + cmd);
 }
 
-inline static unsigned char snd_cmipci_read_b(cmipci_t *cm, unsigned int cmd)
+static inline unsigned char snd_cmipci_read_b(cmipci_t *cm, unsigned int cmd)
 {
 	return inb(cm->iobase + cmd);
 }
 
 /* bit operations for dword register */
-static void snd_cmipci_set_bit(cmipci_t *cm, unsigned int cmd, unsigned int flag)
+static int snd_cmipci_set_bit(cmipci_t *cm, unsigned int cmd, unsigned int flag)
 {
-	unsigned int val;
-	val = inl(cm->iobase + cmd);
+	unsigned int val, oval;
+	val = oval = inl(cm->iobase + cmd);
 	val |= flag;
+	if (val == oval)
+		return 0;
 	outl(val, cm->iobase + cmd);
+	return 1;
 }
 
-static void snd_cmipci_clear_bit(cmipci_t *cm, unsigned int cmd, unsigned int flag)
+static int snd_cmipci_clear_bit(cmipci_t *cm, unsigned int cmd, unsigned int flag)
 {
-	unsigned int val;
-	val = inl(cm->iobase + cmd);
+	unsigned int val, oval;
+	val = oval = inl(cm->iobase + cmd);
 	val &= ~flag;
+	if (val == oval)
+		return 0;
 	outl(val, cm->iobase + cmd);
+	return 1;
 }
 
-#if 0 // not used
 /* bit operations for byte register */
-static void snd_cmipci_set_bit_b(cmipci_t *cm, unsigned int cmd, unsigned char flag)
+static int snd_cmipci_set_bit_b(cmipci_t *cm, unsigned int cmd, unsigned char flag)
 {
-	unsigned char val;
-	val = inb(cm->iobase + cmd);
+	unsigned char val, oval;
+	val = oval = inb(cm->iobase + cmd);
 	val |= flag;
+	if (val == oval)
+		return 0;
 	outb(val, cm->iobase + cmd);
+	return 1;
 }
 
-static void snd_cmipci_clear_bit_b(cmipci_t *cm, unsigned int cmd, unsigned char flag)
+static int snd_cmipci_clear_bit_b(cmipci_t *cm, unsigned int cmd, unsigned char flag)
 {
-	unsigned char val;
-	val = inb(cm->iobase + cmd);
+	unsigned char val, oval;
+	val = oval = inb(cm->iobase + cmd);
 	val &= ~flag;
+	if (val == oval)
+		return 0;
 	outb(val, cm->iobase + cmd);
+	return 1;
 }
-#endif
 
 
 /*
@@ -2123,8 +2136,12 @@ static snd_kcontrol_new_t snd_cmipci_mix
 	CMIPCI_MIXER_VOL_STEREO("Aux Playback Volume", CM_REG_AUX_VOL, 4, 0, 15),
 	CMIPCI_MIXER_SW_STEREO("Aux Playback Switch", CM_REG_MIXER2, CM_VAUXLM_SHIFT, CM_VAUXRM_SHIFT, 0),
 	CMIPCI_MIXER_SW_STEREO("Aux Capture Switch", CM_REG_MIXER2, CM_RAUXLEN_SHIFT, CM_RAUXREN_SHIFT, 0),
-	CMIPCI_MIXER_SW_MONO("Mic Boost", CM_REG_MIXER2, CM_MICGAINZ_SHIFT, 1),
+	CMIPCI_MIXER_SW_MONO("Mic Boost Playback Switch", CM_REG_MIXER2, CM_MICGAINZ_SHIFT, 1),
 	CMIPCI_MIXER_VOL_MONO("Mic Capture Volume", CM_REG_MIXER2, CM_VADMIC_SHIFT, 7),
+	CMIPCI_SB_VOL_MONO("Phone Playback Volume", CM_REG_EXTENT_IND, 5, 7),
+	CMIPCI_DOUBLE("Phone Playback Switch", CM_REG_EXTENT_IND, CM_REG_EXTENT_IND, 4, 4, 1, 0, 0),
+	CMIPCI_DOUBLE("PC Speaker Playnack Switch", CM_REG_EXTENT_IND, CM_REG_EXTENT_IND, 3, 3, 1, 0, 0),
+	CMIPCI_DOUBLE("Mic Boost Capture Switch", CM_REG_EXTENT_IND, CM_REG_EXTENT_IND, 0, 0, 1, 0, 0),
 };
 
 /*
@@ -2250,8 +2267,8 @@ DEFINE_SWITCH_ARG(exchange_dac, CM_REG_M
 DEFINE_SWITCH_ARG(exchange_dac, CM_REG_MISC_CTRL, CM_XCHGDAC, CM_XCHGDAC, 0, 0);
 #endif
 DEFINE_BIT_SWITCH_ARG(fourch, CM_REG_MISC_CTRL, CM_N4SPK3D, 0, 0);
-DEFINE_BIT_SWITCH_ARG(line_rear, CM_REG_MIXER1, CM_SPK4, 1, 0);
-DEFINE_BIT_SWITCH_ARG(line_bass, CM_REG_LEGACY_CTRL, CM_LINE_AS_BASS, 0, 0);
+// DEFINE_BIT_SWITCH_ARG(line_rear, CM_REG_MIXER1, CM_SPK4, 1, 0);
+// DEFINE_BIT_SWITCH_ARG(line_bass, CM_REG_LEGACY_CTRL, CM_LINE_AS_BASS, 0, 0);
 // DEFINE_BIT_SWITCH_ARG(joystick, CM_REG_FUNCTRL1, CM_JYSTK_EN, 0, 0); /* now module option */
 DEFINE_SWITCH_ARG(modem, CM_REG_MISC_CTRL, CM_FLINKON|CM_FLINKOFF, CM_FLINKON, 0, 0);
 
@@ -2300,10 +2317,114 @@ static int snd_cmipci_spdout_enable_put(
 }
 
 
+static int snd_cmipci_line_in_mode_info(snd_kcontrol_t *kcontrol,
+					snd_ctl_elem_info_t *uinfo)
+{
+	cmipci_t *cm = snd_kcontrol_chip(kcontrol);
+	static char *texts[3] = { "Line-In", "Rear Output", "Bass Output" };
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+	uinfo->count = 1;
+	uinfo->value.enumerated.items = cm->chip_version >= 39 ? 3 : 2;
+	if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
+		uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
+	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
+	return 0;
+}
+
+static inline unsigned int get_line_in_mode(cmipci_t *cm)
+{
+	unsigned int val;
+	if (cm->chip_version >= 39) {
+		val = snd_cmipci_read(cm, CM_REG_LEGACY_CTRL);
+		if (val & CM_LINE_AS_BASS)
+			return 2;
+	}
+	val = snd_cmipci_read_b(cm, CM_REG_MIXER1);
+	if (val & CM_SPK4)
+		return 1;
+	return 0;
+}
+
+static int snd_cmipci_line_in_mode_get(snd_kcontrol_t *kcontrol,
+				       snd_ctl_elem_value_t *ucontrol)
+{
+	cmipci_t *cm = snd_kcontrol_chip(kcontrol);
+
+	spin_lock_irq(&cm->reg_lock);
+	ucontrol->value.enumerated.item[0] = get_line_in_mode(cm);
+	spin_unlock_irq(&cm->reg_lock);
+	return 0;
+}
+
+static int snd_cmipci_line_in_mode_put(snd_kcontrol_t *kcontrol,
+				       snd_ctl_elem_value_t *ucontrol)
+{
+	cmipci_t *cm = snd_kcontrol_chip(kcontrol);
+	int change;
+
+	spin_lock_irq(&cm->reg_lock);
+	if (ucontrol->value.enumerated.item[0] == 2)
+		change = snd_cmipci_set_bit(cm, CM_REG_LEGACY_CTRL, CM_LINE_AS_BASS);
+	else
+		change = snd_cmipci_clear_bit(cm, CM_REG_LEGACY_CTRL, CM_LINE_AS_BASS);
+	if (ucontrol->value.enumerated.item[0] == 1)
+		change |= snd_cmipci_set_bit_b(cm, CM_REG_MIXER1, CM_SPK4);
+	else
+		change |= snd_cmipci_clear_bit_b(cm, CM_REG_MIXER1, CM_SPK4);
+	spin_unlock_irq(&cm->reg_lock);
+	return change;
+}
+
+static int snd_cmipci_mic_in_mode_info(snd_kcontrol_t *kcontrol,
+				       snd_ctl_elem_info_t *uinfo)
+{
+	static char *texts[2] = { "Mic-In", "Center/LFE Output" };
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+	uinfo->count = 1;
+	uinfo->value.enumerated.items = 2;
+	if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
+		uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
+	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
+	return 0;
+}
+
+static int snd_cmipci_mic_in_mode_get(snd_kcontrol_t *kcontrol,
+				      snd_ctl_elem_value_t *ucontrol)
+{
+	cmipci_t *cm = snd_kcontrol_chip(kcontrol);
+	/* same bit as spdi_phase */
+	spin_lock_irq(&cm->reg_lock);
+	ucontrol->value.enumerated.item[0] = 
+		(snd_cmipci_read_b(cm, CM_REG_MISC) & CM_SPDIF_INVERSE) ? 1 : 0;
+	spin_unlock_irq(&cm->reg_lock);
+	return 0;
+}
+
+static int snd_cmipci_mic_in_mode_put(snd_kcontrol_t *kcontrol,
+				      snd_ctl_elem_value_t *ucontrol)
+{
+	cmipci_t *cm = snd_kcontrol_chip(kcontrol);
+	int change;
+
+	spin_lock_irq(&cm->reg_lock);
+	if (ucontrol->value.enumerated.item[0])
+		change = snd_cmipci_set_bit_b(cm, CM_REG_MISC, CM_SPDIF_INVERSE);
+	else
+		change = snd_cmipci_clear_bit_b(cm, CM_REG_MISC, CM_SPDIF_INVERSE);
+	spin_unlock_irq(&cm->reg_lock);
+	return change;
+}
+
 /* both for CM8338/8738 */
 static snd_kcontrol_new_t snd_cmipci_mixer_switches[] __devinitdata = {
 	DEFINE_MIXER_SWITCH("Four Channel Mode", fourch),
-	DEFINE_MIXER_SWITCH("Line-In As Rear", line_rear),
+	{
+		.name = "Line-In Mode",
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.info = snd_cmipci_line_in_mode_info,
+		.get = snd_cmipci_line_in_mode_get,
+		.put = snd_cmipci_line_in_mode_put,
+	},
 };
 
 /* for non-multichannel chips */
@@ -2341,10 +2462,15 @@ static snd_kcontrol_new_t snd_cmipci_old
 
 /* only for model 039 or later */
 static snd_kcontrol_new_t snd_cmipci_extra_mixer_switches[] __devinitdata = {
-	DEFINE_MIXER_SWITCH("Line-In As Bass", line_bass),
 	DEFINE_MIXER_SWITCH("IEC958 In Select", spdif_in_sel2),
 	DEFINE_MIXER_SWITCH("IEC958 In Phase Inverse", spdi_phase2),
-	DEFINE_MIXER_SWITCH("Mic As Center/LFE", spdi_phase), /* same bit as spdi_phase */
+	{
+		.name = "Mic-In Mode",
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.info = snd_cmipci_mic_in_mode_info,
+		.get = snd_cmipci_mic_in_mode_get,
+		.put = snd_cmipci_mic_in_mode_put,
+	}
 };
 
 /* card control switches */
@@ -2944,7 +3070,7 @@ static struct pci_driver driver = {
 	
 static int __init alsa_card_cmipci_init(void)
 {
-	return pci_module_init(&driver);
+	return pci_register_driver(&driver);
 }
 
 static void __exit alsa_card_cmipci_exit(void)
diff --git a/sound/pci/cs4281.c b/sound/pci/cs4281.c
--- a/sound/pci/cs4281.c
+++ b/sound/pci/cs4281.c
@@ -206,7 +206,10 @@ MODULE_PARM_DESC(dual_codec, "Secondary 
 
 #define BA0_PMCS		0x0344	/* Power Management Control/Status */
 #define BA0_CWPR		0x03e0	/* Configuration Write Protect */
+
 #define BA0_EPPMC		0x03e4	/* Extended PCI Power Management Control */
+#define BA0_EPPMC_FPDN		(1<<14) /* Full Power DowN */
+
 #define BA0_GPIOR		0x03e8	/* GPIO Pin Interface Register */
 
 #define BA0_SPMC		0x03ec	/* Serial Port Power Management Control (& ASDIN2 enable) */
@@ -539,7 +542,7 @@ static void snd_cs4281_delay(unsigned in
 	}
 }
 
-inline static void snd_cs4281_delay_long(void)
+static inline void snd_cs4281_delay_long(void)
 {
 	set_current_state(TASK_UNINTERRUPTIBLE);
 	schedule_timeout(1);
@@ -1335,11 +1338,6 @@ static inline int snd_cs4281_create_game
 static inline void snd_cs4281_free_gameport(cs4281_t *chip) { }
 #endif /* CONFIG_GAMEPORT || (MODULE && CONFIG_GAMEPORT_MODULE) */
 
-
-/*
-
- */
-
 static int snd_cs4281_free(cs4281_t *chip)
 {
 	snd_cs4281_free_gameport(chip);
@@ -1461,6 +1459,11 @@ static int snd_cs4281_chip_init(cs4281_t
 	int timeout;
 	int retry_count = 2;
 
+	/* Having EPPMC.FPDN=1 prevent proper chip initialisation */
+	tmp = snd_cs4281_peekBA0(chip, BA0_EPPMC);
+	if (tmp & BA0_EPPMC_FPDN)
+		snd_cs4281_pokeBA0(chip, BA0_EPPMC, tmp & ~BA0_EPPMC_FPDN);
+
       __retry:
 	tmp = snd_cs4281_peekBA0(chip, BA0_CFLR);
 	if (tmp != BA0_CFLR_DEFAULT) {
@@ -2124,7 +2127,7 @@ static struct pci_driver driver = {
 	
 static int __init alsa_card_cs4281_init(void)
 {
-	return pci_module_init(&driver);
+	return pci_register_driver(&driver);
 }
 
 static void __exit alsa_card_cs4281_exit(void)
diff --git a/sound/pci/cs46xx/cs46xx.c b/sound/pci/cs46xx/cs46xx.c
--- a/sound/pci/cs46xx/cs46xx.c
+++ b/sound/pci/cs46xx/cs46xx.c
@@ -171,7 +171,7 @@ static struct pci_driver driver = {
 
 static int __init alsa_card_cs46xx_init(void)
 {
-	return pci_module_init(&driver);
+	return pci_register_driver(&driver);
 }
 
 static void __exit alsa_card_cs46xx_exit(void)
diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c
--- a/sound/pci/cs46xx/cs46xx_lib.c
+++ b/sound/pci/cs46xx/cs46xx_lib.c
@@ -1295,8 +1295,7 @@ static snd_pcm_hw_constraint_list_t hw_c
 
 static void snd_cs46xx_pcm_free_substream(snd_pcm_runtime_t *runtime)
 {
-	cs46xx_pcm_t * cpcm = runtime->private_data;
-	kfree(cpcm);
+	kfree(runtime->private_data);
 }
 
 static int _cs46xx_playback_open_channel (snd_pcm_substream_t * substream,int pcm_channel_id)
@@ -2401,8 +2400,7 @@ static void snd_cs46xx_codec_reset (ac97
 		if ((err = snd_ac97_read(ac97, AC97_REC_GAIN)) == 0x8a05)
 			return;
 
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(HZ/100);
+		msleep(10);
 	} while (time_after_eq(end_time, jiffies));
 
 	snd_printk("CS46xx secondary codec dont respond!\n");  
@@ -2436,8 +2434,7 @@ static int __devinit cs46xx_detect_codec
 			err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97[codec]);
 			return err;
 		}
-		set_current_state(TASK_INTERRUPTIBLE);
-		schedule_timeout(HZ/100);
+		msleep(10);
 	}
 	snd_printdd("snd_cs46xx: codec %d detection timeout\n", codec);
 	return -ENXIO;
@@ -3019,8 +3016,7 @@ static int snd_cs46xx_chip_init(cs46xx_t
 	/*
          *  Wait until the PLL has stabilized.
 	 */
-	set_current_state(TASK_UNINTERRUPTIBLE);
-	schedule_timeout(HZ/10); /* 100ms */
+	msleep(100);
 
 	/*
 	 *  Turn on clocking of the core so that we can setup the serial ports.
@@ -3073,8 +3069,7 @@ static int snd_cs46xx_chip_init(cs46xx_t
 		 */
 		if (snd_cs46xx_peekBA0(chip, BA0_ACSTS) & ACSTS_CRDY)
 			goto ok1;
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout((HZ+99)/100);
+		msleep(10);
 	}
 
 
@@ -3123,8 +3118,7 @@ static int snd_cs46xx_chip_init(cs46xx_t
 		 */
 		if ((snd_cs46xx_peekBA0(chip, BA0_ACISV) & (ACISV_ISV3 | ACISV_ISV4)) == (ACISV_ISV3 | ACISV_ISV4))
 			goto ok2;
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout((HZ+99)/100);
+		msleep(10);
 	}
 
 #ifndef CONFIG_SND_CS46XX_NEW_DSP
diff --git a/sound/pci/emu10k1/emu10k1.c b/sound/pci/emu10k1/emu10k1.c
--- a/sound/pci/emu10k1/emu10k1.c
+++ b/sound/pci/emu10k1/emu10k1.c
@@ -52,6 +52,7 @@ static int seq_ports[SNDRV_CARDS] = {[0 
 static int max_synth_voices[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 64};
 static int max_buffer_size[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 128};
 static int enable_ir[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0};
+static uint subsystem[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; /* Force card subsystem model */
 
 module_param_array(index, int, NULL, 0444);
 MODULE_PARM_DESC(index, "Index value for the EMU10K1 soundcard.");
@@ -71,7 +72,8 @@ module_param_array(max_buffer_size, int,
 MODULE_PARM_DESC(max_buffer_size, "Maximum sample buffer size in MB.");
 module_param_array(enable_ir, bool, NULL, 0444);
 MODULE_PARM_DESC(enable_ir, "Enable IR.");
-
+module_param_array(subsystem, uint, NULL, 0444);
+MODULE_PARM_DESC(subsystem, "Force card subsystem model.");
 /*
  * Class 0401: 1102:0008 (rev 00) Subsystem: 1102:1001 -> Audigy2 Value  Model:SB0400
  */
@@ -122,7 +124,7 @@ static int __devinit snd_card_emu10k1_pr
 		max_buffer_size[dev] = 1024;
 	if ((err = snd_emu10k1_create(card, pci, extin[dev], extout[dev],
 				      (long)max_buffer_size[dev] * 1024 * 1024,
-				      enable_ir[dev],
+				      enable_ir[dev], subsystem[dev],
 				      &emu)) < 0) {
 		snd_card_free(card);
 		return err;
@@ -140,7 +142,7 @@ static int __devinit snd_card_emu10k1_pr
 		return err;
 	}
 	/* This stores the periods table. */
-	if (emu->audigy && emu->revision == 4) { /* P16V */	
+	if (emu->card_capabilities->ca0151_chip) { /* P16V */	
 		if(snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci), 1024, &emu->p16v_buffer) < 0) {
 			snd_p16v_free(emu);
 			return -ENOMEM;
@@ -161,7 +163,7 @@ static int __devinit snd_card_emu10k1_pr
 		snd_card_free(card);
 		return err;
 	}
-	if (emu->audigy && emu->revision == 4) { /* P16V */	
+	if (emu->card_capabilities->ca0151_chip) { /* P16V */	
 		if ((err = snd_p16v_pcm(emu, 4, NULL)) < 0) {
 			snd_card_free(card);
 			return err;
@@ -228,7 +230,7 @@ static struct pci_driver driver = {
 
 static int __init alsa_card_emu10k1_init(void)
 {
-	return pci_module_init(&driver);
+	return pci_register_driver(&driver);
 }
 
 static void __exit alsa_card_emu10k1_exit(void)
diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c
--- a/sound/pci/emu10k1/emu10k1_main.c
+++ b/sound/pci/emu10k1/emu10k1_main.c
@@ -170,7 +170,7 @@ static int __devinit snd_emu10k1_init(em
 			SPCS_GENERATIONSTATUS | 0x00001200 |
 			0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT);
 
-	if (emu->audigy && emu->revision == 4) { /* audigy2 */
+	if (emu->card_capabilities->ca0151_chip) { /* audigy2 */
 		/* Hacks for Alice3 to work independent of haP16V driver */
 		u32 tmp;
 
@@ -189,9 +189,9 @@ static int __devinit snd_emu10k1_init(em
 		/* Enabled Phased (8-channel) P16V playback */
 		outl(0x0201, emu->port + HCFG2);
 		/* Set playback routing. */
-		snd_emu10k1_ptr_write(emu, CAPTURE_P16V_SOURCE, 0, 78e4);
+		snd_emu10k1_ptr20_write(emu, CAPTURE_P16V_SOURCE, 0, 0x78e4);
 	}
-	if (emu->audigy && (emu->serial == 0x10011102) ) { /* audigy2 Value */
+	if (emu->card_capabilities->ca0108_chip) { /* audigy2 Value */
 		/* Hacks for Alice3 to work independent of haP16V driver */
 		u32 tmp;
 
@@ -253,6 +253,8 @@ static int __devinit snd_emu10k1_init(em
 			     HCFG_AUTOMUTE | HCFG_JOYENABLE, emu->port + HCFG);
 		else
 			outl(HCFG_AUTOMUTE | HCFG_JOYENABLE, emu->port + HCFG);
+	/* FIXME: Remove all these emu->model and replace it with a card recognition parameter,
+	 * e.g. card_capabilities->joystick */
 	} else if (emu->model == 0x20 ||
 	    emu->model == 0xc400 ||
 	    (emu->model == 0x21 && emu->revision < 6))
@@ -299,12 +301,12 @@ static int __devinit snd_emu10k1_init(em
 	if (emu->audigy) {
 		outl(inl(emu->port + A_IOCFG) & ~0x44, emu->port + A_IOCFG);
  
-		if (emu->revision == 4) { /* audigy2 */
+		if (emu->card_capabilities->ca0151_chip) { /* audigy2 */
 			/* Unmute Analog now.  Set GPO6 to 1 for Apollo.
 			 * This has to be done after init ALice3 I2SOut beyond 48KHz.
 			 * So, sequence is important. */
 			outl(inl(emu->port + A_IOCFG) | 0x0040, emu->port + A_IOCFG);
-		} else if (emu->serial == 0x10011102) { /* audigy2 value */
+		} else if (emu->card_capabilities->ca0108_chip) { /* audigy2 value */
 			/* Unmute Analog now. */
 			outl(inl(emu->port + A_IOCFG) | 0x0060, emu->port + A_IOCFG);
 		} else {
@@ -600,7 +602,7 @@ static int snd_emu10k1_free(emu10k1_t *e
 	if (emu->port)
 		pci_release_regions(emu->pci);
 	pci_disable_device(emu->pci);
-	if (emu->audigy && emu->revision == 4) /* P16V */	
+	if (emu->card_capabilities->ca0151_chip) /* P16V */	
 		snd_p16v_free(emu);
 	kfree(emu);
 	return 0;
@@ -612,21 +614,33 @@ static int snd_emu10k1_dev_free(snd_devi
 	return snd_emu10k1_free(emu);
 }
 
-/* vendor, device, subsystem, emu10k1_chip, emu10k2_chip, ca0102_chip, ca0108_chip, ca0151_chip, spk71, spdif_bug, ac97_chip, ecard, driver, name */
-
 static emu_chip_details_t emu_chip_details[] = {
 	/* Audigy 2 Value AC3 out does not work yet. Need to find out how to turn off interpolators.*/
+	/* Tested by James@superbug.co.uk 3rd July 2005 */
 	{.vendor = 0x1102, .device = 0x0008, .subsystem = 0x10011102,
 	 .driver = "Audigy2", .name = "Audigy 2 Value [SB0400]", 
+	 .id = "Audigy2",
 	 .emu10k2_chip = 1,
 	 .ca0108_chip = 1,
-	 .spk71 = 1} ,
+	 .spk71 = 1,
+	 .ac97_chip = 1} ,
 	{.vendor = 0x1102, .device = 0x0008, 
 	 .driver = "Audigy2", .name = "Audigy 2 Value [Unknown]", 
+	 .id = "Audigy2",
 	 .emu10k2_chip = 1,
-	 .ca0108_chip = 1} ,
+	 .ca0108_chip = 1,
+	 .ac97_chip = 1} ,
+	/* Tested by James@superbug.co.uk 8th July 2005. No sound available yet. */
+	{.vendor = 0x1102, .device = 0x0004, .subsystem = 0x40011102,
+	 .driver = "Audigy2", .name = "E-mu 1212m [4001]", 
+	 .id = "EMU1212m",
+	 .emu10k2_chip = 1,
+	 .ca0102_chip = 1,
+	 .ecard = 1} ,
+	/* Tested by James@superbug.co.uk 3rd July 2005 */
 	{.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20071102,
 	 .driver = "Audigy2", .name = "Audigy 4 PRO [SB0380]", 
+	 .id = "Audigy2",
 	 .emu10k2_chip = 1,
 	 .ca0102_chip = 1,
 	 .ca0151_chip = 1,
@@ -635,6 +649,7 @@ static emu_chip_details_t emu_chip_detai
 	 .ac97_chip = 1} ,
 	{.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20021102,
 	 .driver = "Audigy2", .name = "Audigy 2 ZS [SB0350]", 
+	 .id = "Audigy2",
 	 .emu10k2_chip = 1,
 	 .ca0102_chip = 1,
 	 .ca0151_chip = 1,
@@ -643,6 +658,7 @@ static emu_chip_details_t emu_chip_detai
 	 .ac97_chip = 1} ,
 	{.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20011102,
 	 .driver = "Audigy2", .name = "Audigy 2 ZS [2001]", 
+	 .id = "Audigy2",
 	 .emu10k2_chip = 1,
 	 .ca0102_chip = 1,
 	 .ca0151_chip = 1,
@@ -651,6 +667,7 @@ static emu_chip_details_t emu_chip_detai
 	 .ac97_chip = 1} ,
 	{.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10071102,
 	 .driver = "Audigy2", .name = "Audigy 2 [SB0240]", 
+	 .id = "Audigy2",
 	 .emu10k2_chip = 1,
 	 .ca0102_chip = 1,
 	 .ca0151_chip = 1,
@@ -659,35 +676,160 @@ static emu_chip_details_t emu_chip_detai
 	 .ac97_chip = 1} ,
 	{.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10051102,
 	 .driver = "Audigy2", .name = "Audigy 2 EX [1005]", 
+	 .id = "Audigy2",
 	 .emu10k2_chip = 1,
 	 .ca0102_chip = 1,
 	 .ca0151_chip = 1,
 	 .spdif_bug = 1} ,
 	{.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10021102,
 	 .driver = "Audigy2", .name = "Audigy 2 Platinum [SB0240P]", 
+	 .id = "Audigy2",
 	 .emu10k2_chip = 1,
 	 .ca0102_chip = 1,
 	 .ca0151_chip = 1,
 	 .spk71 = 1,
 	 .spdif_bug = 1,
 	 .ac97_chip = 1} ,
+	{.vendor = 0x1102, .device = 0x0004, .revision = 0x04,
+	 .driver = "Audigy2", .name = "Audigy 2 [Unknown]",
+	 .id = "Audigy2",
+	 .emu10k2_chip = 1,
+	 .ca0102_chip = 1,
+	 .ca0151_chip = 1,
+	 .spdif_bug = 1,
+	 .ac97_chip = 1} ,
+	{.vendor = 0x1102, .device = 0x0004, .subsystem = 0x00531102,
+	 .driver = "Audigy", .name = "Audigy 1 [SB0090]", 
+	 .id = "Audigy",
+	 .emu10k2_chip = 1,
+	 .ca0102_chip = 1,
+	 .ac97_chip = 1} ,
+	{.vendor = 0x1102, .device = 0x0004, .subsystem = 0x00521102,
+	 .driver = "Audigy", .name = "Audigy 1 ES [SB0160]", 
+	 .id = "Audigy",
+	 .emu10k2_chip = 1,
+	 .ca0102_chip = 1,
+	 .spdif_bug = 1,
+	 .ac97_chip = 1} ,
+	{.vendor = 0x1102, .device = 0x0004, .subsystem = 0x00511102,
+	 .driver = "Audigy", .name = "Audigy 1 [SB0090]", 
+	 .id = "Audigy",
+	 .emu10k2_chip = 1,
+	 .ca0102_chip = 1,
+	 .ac97_chip = 1} ,
 	{.vendor = 0x1102, .device = 0x0004,
-	 .driver = "Audigy", .name = "Audigy 1 or 2 [Unknown]", 
+	 .driver = "Audigy", .name = "Audigy 1 [Unknown]", 
+	 .id = "Audigy",
 	 .emu10k2_chip = 1,
 	 .ca0102_chip = 1,
-	 .spdif_bug = 1} ,
-	{.vendor = 0x1102, .device = 0x0002, .subsystem = 0x40011102,
-	 .driver = "EMU10K1", .name = "E-mu APS [4001]", 
+	 .ac97_chip = 1} ,
+	{.vendor = 0x1102, .device = 0x0002, .subsystem = 0x806B1102,
+	 .driver = "EMU10K1", .name = "SBLive! [SB0105]", 
+	 .id = "Live",
 	 .emu10k1_chip = 1,
-	 .ecard = 1} ,
+	 .ac97_chip = 1,
+	 .sblive51 = 1} ,
+	{.vendor = 0x1102, .device = 0x0002, .subsystem = 0x806A1102,
+	 .driver = "EMU10K1", .name = "SBLive! Value [SB0103]", 
+	 .id = "Live",
+	 .emu10k1_chip = 1,
+	 .ac97_chip = 1,
+	 .sblive51 = 1} ,
+	{.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80691102,
+	 .driver = "EMU10K1", .name = "SBLive! Value [SB0101]", 
+	 .id = "Live",
+	 .emu10k1_chip = 1,
+	 .ac97_chip = 1,
+	 .sblive51 = 1} ,
 	{.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80641102,
 	 .driver = "EMU10K1", .name = "SB Live 5.1", 
+	 .id = "Live",
+	 .emu10k1_chip = 1,
+	 .ac97_chip = 1,
+	 .sblive51 = 1} ,
+	{.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80611102,
+	 .driver = "EMU10K1", .name = "SBLive! Player 5.1 [SB0060]", 
+	 .id = "Live",
+	 .emu10k1_chip = 1,
+	 .ac97_chip = 1,
+	 .sblive51 = 1} ,
+	{.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80511102,
+	 .driver = "EMU10K1", .name = "SBLive! Value [CT4850]", 
+	 .id = "Live",
+	 .emu10k1_chip = 1,
+	 .ac97_chip = 1,
+	 .sblive51 = 1} ,
+	{.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80401102,
+	 .driver = "EMU10K1", .name = "SBLive! Platinum [CT4760P]", 
+	 .id = "Live",
 	 .emu10k1_chip = 1,
 	 .ac97_chip = 1} ,
+	{.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80321102,
+	 .driver = "EMU10K1", .name = "SBLive! Value [CT4871]", 
+	 .id = "Live",
+	 .emu10k1_chip = 1,
+	 .ac97_chip = 1,
+	 .sblive51 = 1} ,
+	{.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80311102,
+	 .driver = "EMU10K1", .name = "SBLive! Value [CT4831]", 
+	 .id = "Live",
+	 .emu10k1_chip = 1,
+	 .ac97_chip = 1,
+	 .sblive51 = 1} ,
+	{.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80281102,
+	 .driver = "EMU10K1", .name = "SBLive! Value [CT4870]", 
+	 .id = "Live",
+	 .emu10k1_chip = 1,
+	 .ac97_chip = 1,
+	 .sblive51 = 1} ,
+	/* Tested by James@superbug.co.uk 3rd July 2005 */
+	{.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80271102,
+	 .driver = "EMU10K1", .name = "SBLive! Value [CT4832]", 
+	 .id = "Live",
+	 .emu10k1_chip = 1,
+	 .ac97_chip = 1,
+	 .sblive51 = 1} ,
+	{.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80261102,
+	 .driver = "EMU10K1", .name = "SBLive! Value [CT4830]", 
+	 .id = "Live",
+	 .emu10k1_chip = 1,
+	 .ac97_chip = 1,
+	 .sblive51 = 1} ,
+	{.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80231102,
+	 .driver = "EMU10K1", .name = "SB PCI512 [CT4790]", 
+	 .id = "Live",
+	 .emu10k1_chip = 1,
+	 .ac97_chip = 1,
+	 .sblive51 = 1} ,
+	{.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80221102,
+	 .driver = "EMU10K1", .name = "SBLive! Value [CT4780]", 
+	 .id = "Live",
+	 .emu10k1_chip = 1,
+	 .ac97_chip = 1,
+	 .sblive51 = 1} ,
+	{.vendor = 0x1102, .device = 0x0002, .subsystem = 0x40011102,
+	 .driver = "EMU10K1", .name = "E-mu APS [4001]", 
+	 .id = "APS",
+	 .emu10k1_chip = 1,
+	 .ecard = 1} ,
+	{.vendor = 0x1102, .device = 0x0002, .subsystem = 0x00211102,
+	 .driver = "EMU10K1", .name = "SBLive! [CT4620]", 
+	 .id = "Live",
+	 .emu10k1_chip = 1,
+	 .ac97_chip = 1,
+	 .sblive51 = 1} ,
+	{.vendor = 0x1102, .device = 0x0002, .subsystem = 0x00201102,
+	 .driver = "EMU10K1", .name = "SBLive! Value [CT4670]", 
+	 .id = "Live",
+	 .emu10k1_chip = 1,
+	 .ac97_chip = 1,
+	 .sblive51 = 1} ,
 	{.vendor = 0x1102, .device = 0x0002,
 	 .driver = "EMU10K1", .name = "SB Live [Unknown]", 
+	 .id = "Live",
 	 .emu10k1_chip = 1,
-	 .ac97_chip = 1} ,
+	 .ac97_chip = 1,
+	 .sblive51 = 1} ,
 	{ } /* terminator */
 };
 
@@ -697,6 +839,7 @@ int __devinit snd_emu10k1_create(snd_car
 		       unsigned short extout_mask,
 		       long max_cache_bytes,
 		       int enable_ir,
+		       uint subsystem,
 		       emu10k1_t ** remu)
 {
 	emu10k1_t *emu;
@@ -738,13 +881,21 @@ int __devinit snd_emu10k1_create(snd_car
 	emu->revision = revision;
 	pci_read_config_dword(pci, PCI_SUBSYSTEM_VENDOR_ID, &emu->serial);
 	pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &emu->model);
-	emu->card_type = EMU10K1_CARD_CREATIVE;
 	snd_printdd("vendor=0x%x, device=0x%x, subsystem_vendor_id=0x%x, subsystem_id=0x%x\n",pci->vendor, pci->device, emu->serial, emu->model);
 
 	for (c = emu_chip_details; c->vendor; c++) {
 		if (c->vendor == pci->vendor && c->device == pci->device) {
-			if (c->subsystem == emu->serial) break;
-			if (c->subsystem == 0) break;
+			if (subsystem) {
+				if (c->subsystem && (c->subsystem == subsystem) ) {
+					break;
+				} else continue;
+			} else {
+				if (c->subsystem && (c->subsystem != emu->serial) )
+					continue;
+				if (c->revision && c->revision != emu->revision)
+					continue;
+			}
+			break;
 		}
 	}
 	if (c->vendor == 0) {
@@ -754,11 +905,32 @@ int __devinit snd_emu10k1_create(snd_car
 		return -ENOENT;
 	}
 	emu->card_capabilities = c;
-	if (c->subsystem != 0)
+	if (c->subsystem && !subsystem)
 		snd_printdd("Sound card name=%s\n", c->name);
-	else
-		snd_printdd("Sound card name=%s, vendor=0x%x, device=0x%x, subsystem=0x%x\n", c->name, pci->vendor, pci->device, emu->serial);
+	else if (subsystem) 
+		snd_printdd("Sound card name=%s, vendor=0x%x, device=0x%x, subsystem=0x%x. Forced to subsytem=0x%x\n",
+		       	c->name, pci->vendor, pci->device, emu->serial, c->subsystem);
+	else 
+		snd_printdd("Sound card name=%s, vendor=0x%x, device=0x%x, subsystem=0x%x.\n",
+		      	c->name, pci->vendor, pci->device, emu->serial);
 	
+	if (!*card->id && c->id) {
+		int i, n = 0;
+		strlcpy(card->id, c->id, sizeof(card->id));
+		for (;;) {
+			for (i = 0; i < snd_ecards_limit; i++) {
+				if (snd_cards[i] && !strcmp(snd_cards[i]->id, card->id))
+					break;
+			}
+			if (i >= snd_ecards_limit)
+				break;
+			n++;
+			if (n >= SNDRV_CARDS)
+				break;
+			snprintf(card->id, sizeof(card->id), "%s_%d", c->id, n);
+		}
+	}
+
 	is_audigy = emu->audigy = c->emu10k2_chip;
 
 	/* set the DMA transfer mask */
@@ -816,15 +988,6 @@ int __devinit snd_emu10k1_create(snd_car
 
 	pci_set_master(pci);
 
-	if (c->ecard) {
-		emu->card_type = EMU10K1_CARD_EMUAPS;
-		emu->APS = 1;
-	}
-	if (! c->ac97_chip)
-		emu->no_ac97 = 1;
-	
-	emu->spk71 = c->spk71;
-	
 	emu->fx8010.fxbus_mask = 0x303f;
 	if (extin_mask == 0)
 		extin_mask = 0x3fcf;
@@ -833,7 +996,7 @@ int __devinit snd_emu10k1_create(snd_car
 	emu->fx8010.extin_mask = extin_mask;
 	emu->fx8010.extout_mask = extout_mask;
 
-	if (emu->APS) {
+	if (emu->card_capabilities->ecard) {
 		if ((err = snd_emu10k1_ecard_init(emu)) < 0) {
 			snd_emu10k1_free(emu);
 			return err;
diff --git a/sound/pci/emu10k1/emu10k1x.c b/sound/pci/emu10k1/emu10k1x.c
--- a/sound/pci/emu10k1/emu10k1x.c
+++ b/sound/pci/emu10k1/emu10k1x.c
@@ -361,10 +361,7 @@ static void snd_emu10k1x_gpio_write(emu1
 
 static void snd_emu10k1x_pcm_free_substream(snd_pcm_runtime_t *runtime)
 {
-	emu10k1x_pcm_t *epcm = runtime->private_data;
-  
-	if (epcm)
-		kfree(epcm);
+	kfree(runtime->private_data);
 }
 
 static void snd_emu10k1x_pcm_interrupt(emu10k1x_t *emu, emu10k1x_voice_t *voice)
@@ -1075,6 +1072,7 @@ static int __devinit snd_emu10k1x_proc_i
 		snd_info_set_text_ops(entry, emu, 1024, snd_emu10k1x_proc_reg_read);
 		entry->c.text.write_size = 64;
 		entry->c.text.write = snd_emu10k1x_proc_reg_write;
+		entry->mode |= S_IWUSR;
 		entry->private_data = emu;
 	}
 	
@@ -1627,7 +1625,7 @@ static int __init alsa_card_emu10k1x_ini
 {
 	int err;
 
-	if ((err = pci_module_init(&driver)) > 0)
+	if ((err = pci_register_driver(&driver)) > 0)
 		return err;
 
 	return 0;
diff --git a/sound/pci/emu10k1/emufx.c b/sound/pci/emu10k1/emufx.c
--- a/sound/pci/emu10k1/emufx.c
+++ b/sound/pci/emu10k1/emufx.c
@@ -1077,7 +1077,7 @@ static int __devinit _snd_emu10k1_audigy
 	gpr += 2;
 	
 	/* PCM Side Playback (independent from stereo mix) */
-	if (emu->spk71) {
+	if (emu->card_capabilities->spk71) {
 		A_OP(icode, &ptr, iMAC0, A_GPR(playback+6), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_SIDE));
 		A_OP(icode, &ptr, iMAC0, A_GPR(playback+7), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_SIDE));
 		snd_emu10k1_init_stereo_control(&controls[nctl++], "PCM Side Playback Volume", gpr, 100);
@@ -1145,14 +1145,14 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_G
 	A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_SPDIF_CD_L);
 	A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_SPDIF_CD_R);
 	snd_emu10k1_init_stereo_control(&controls[nctl++],
-					emu->no_ac97 ? "CD Playback Volume" : "Audigy CD Playback Volume",
+					emu->card_capabilities->ac97_chip ? "Audigy CD Playback Volume" : "CD Playback Volume",
 					gpr, 0);
 	gpr += 2;
 	/* Audigy CD Capture Volume */
 	A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_SPDIF_CD_L);
 	A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_SPDIF_CD_R);
 	snd_emu10k1_init_stereo_control(&controls[nctl++],
-					emu->no_ac97 ? "CD Capture Volume" : "Audigy CD Capture Volume",
+					emu->card_capabilities->ac97_chip ? "Audigy CD Capture Volume" : "CD Capture Volume",
 					gpr, 0);
 	gpr += 2;
 
@@ -1171,14 +1171,14 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_G
 	A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_LINE2_L);
 	A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_LINE2_R);
 	snd_emu10k1_init_stereo_control(&controls[nctl++],
-					emu->no_ac97 ? "Line Playback Volume" : "Line2 Playback Volume",
+					emu->card_capabilities->ac97_chip ? "Line2 Playback Volume" : "Line Playback Volume",
 					gpr, 0);
 	gpr += 2;
 	/* Line2 Capture Volume */
 	A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_LINE2_L);
 	A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_LINE2_R);
 	snd_emu10k1_init_stereo_control(&controls[nctl++],
-					emu->no_ac97 ? "Line Capture Volume" : "Line2 Capture Volume",
+					emu->card_capabilities->ac97_chip ? "Line2 Capture Volume" : "Line Capture Volume",
 					gpr, 0);
 	gpr += 2;
         
@@ -1197,14 +1197,14 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_G
 	A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_AUX2_L);
 	A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_AUX2_R);
 	snd_emu10k1_init_stereo_control(&controls[nctl++],
-					emu->no_ac97 ? "Aux Playback Volume" : "Aux2 Playback Volume",
+					emu->card_capabilities->ac97_chip ? "Aux2 Playback Volume" : "Aux Playback Volume",
 					gpr, 0);
 	gpr += 2;
 	/* Aux2 Capture Volume */
 	A_ADD_VOLUME_IN(capture, gpr, A_EXTIN_AUX2_L);
 	A_ADD_VOLUME_IN(capture+1, gpr+1, A_EXTIN_AUX2_R);
 	snd_emu10k1_init_stereo_control(&controls[nctl++],
-					emu->no_ac97 ? "Aux Capture Volume" : "Aux2 Capture Volume",
+					emu->card_capabilities->ac97_chip ? "Aux2 Capture Volume" : "Aux Capture Volume",
 					gpr, 0);
 	gpr += 2;
 	
@@ -1232,7 +1232,7 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_G
 	snd_emu10k1_init_mono_control(&controls[nctl++], "LFE Playback Volume", gpr, 0);
 	gpr++;
 	
-	if (emu->spk71) {
+	if (emu->card_capabilities->spk71) {
 		/* Stereo Mix Side Playback */
 		A_OP(icode, &ptr, iMAC0, A_GPR(playback+6), A_GPR(playback+6), A_GPR(gpr), A_GPR(stereo_mix));
 		A_OP(icode, &ptr, iMAC0, A_GPR(playback+7), A_GPR(playback+7), A_GPR(gpr+1), A_GPR(stereo_mix+1));
@@ -1266,7 +1266,7 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_G
 	A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 3), A_GPR(playback + 3), A_C_00000000, A_C_00000000); /* rear right */
 	A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 4), A_GPR(playback + 4), A_C_00000000, A_C_00000000); /* center */
 	A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), A_GPR(playback + 5), A_C_00000000, A_C_00000000); /* LFE */
-	if (emu->spk71) {
+	if (emu->card_capabilities->spk71) {
 		A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 6), A_GPR(playback + 6), A_C_00000000, A_C_00000000); /* side left */
 		A_OP(icode, &ptr, iACC3, A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 7), A_GPR(playback + 7), A_C_00000000, A_C_00000000); /* side right */
 	}
@@ -1359,7 +1359,7 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_G
 	A_PUT_STEREO_OUTPUT(A_EXTOUT_AREAR_L, A_EXTOUT_AREAR_R, playback+2 + SND_EMU10K1_PLAYBACK_CHANNELS);
 	A_PUT_OUTPUT(A_EXTOUT_ACENTER, playback+4 + SND_EMU10K1_PLAYBACK_CHANNELS);
 	A_PUT_OUTPUT(A_EXTOUT_ALFE, playback+5 + SND_EMU10K1_PLAYBACK_CHANNELS);
-	if (emu->spk71)
+	if (emu->card_capabilities->spk71)
 		A_PUT_STEREO_OUTPUT(A_EXTOUT_ASIDE_L, A_EXTOUT_ASIDE_R, playback+6 + SND_EMU10K1_PLAYBACK_CHANNELS);
 
 	/* headphone */
@@ -1982,22 +1982,27 @@ static int __devinit _snd_emu10k1_init_e
 		OP(icode, &ptr, iACC3, EXTOUT(EXTOUT_MIC_CAP), GPR(capture + 2), C_00000000, C_00000000);
 
 	/* EFX capture - capture the 16 EXTINS */
-	OP(icode, &ptr, iACC3, FXBUS2(14), C_00000000, C_00000000, EXTIN(0));
-	OP(icode, &ptr, iACC3, FXBUS2(15), C_00000000, C_00000000, EXTIN(1));
-	OP(icode, &ptr, iACC3, FXBUS2(0), C_00000000, C_00000000, EXTIN(2));
-	OP(icode, &ptr, iACC3, FXBUS2(3), C_00000000, C_00000000, EXTIN(3));
-	/* Dont connect anything to FXBUS2 1 and 2.  These are shared with 
-	 * Center/LFE on the SBLive 5.1.  The kX driver only changes the 
-	 * routing when it detects an SBLive 5.1.
-	 *
-	 * Since only 14 of the 16 EXTINs are used, this is not a big problem.  
-	 * We route AC97L and R to FX capture 14 and 15, SPDIF CD in to FX capture 
-	 * 0 and 3, then the rest of the EXTINs to the corresponding FX capture 
-	 * channel.
-	 */
-	for (z = 4; z < 14; z++) {
-		OP(icode, &ptr, iACC3, FXBUS2(z), C_00000000, C_00000000, EXTIN(z));
+	if (emu->card_capabilities->sblive51) {
+		/* On the Live! 5.1, FXBUS2(1) and FXBUS(2) are shared with EXTOUT_ACENTER
+		 * and EXTOUT_ALFE, so we can't connect inputs to them for multitrack recording.
+		 *
+		 * Since only 14 of the 16 EXTINs are used, this is not a big problem.  
+		 * We route AC97L and R to FX capture 14 and 15, SPDIF CD in to FX capture 
+		 * 0 and 3, then the rest of the EXTINs to the corresponding FX capture 
+		 * channel.  Multitrack recorders will still see the center/lfe output signal 
+		 * on the second and third channels.
+		 */
+		OP(icode, &ptr, iACC3, FXBUS2(14), C_00000000, C_00000000, EXTIN(0));
+		OP(icode, &ptr, iACC3, FXBUS2(15), C_00000000, C_00000000, EXTIN(1));
+		OP(icode, &ptr, iACC3, FXBUS2(0), C_00000000, C_00000000, EXTIN(2));
+		OP(icode, &ptr, iACC3, FXBUS2(3), C_00000000, C_00000000, EXTIN(3));
+		for (z = 4; z < 14; z++)
+			OP(icode, &ptr, iACC3, FXBUS2(z), C_00000000, C_00000000, EXTIN(z));
+	} else {
+		for (z = 0; z < 16; z++)
+			OP(icode, &ptr, iACC3, FXBUS2(z), C_00000000, C_00000000, EXTIN(z));
 	}
+	    
 
 	if (gpr > tmp) {
 		snd_BUG();
@@ -2128,7 +2133,6 @@ static int snd_emu10k1_fx8010_info(emu10
 	int res;
 
 	memset(info, 0, sizeof(info));
-	info->card = emu->card_type;
 	info->internal_tram_size = emu->fx8010.itram_size;
 	info->external_tram_size = emu->fx8010.etram_pages.bytes / 2;
 	fxbus = fxbuses;
diff --git a/sound/pci/emu10k1/emumixer.c b/sound/pci/emu10k1/emumixer.c
--- a/sound/pci/emu10k1/emumixer.c
+++ b/sound/pci/emu10k1/emumixer.c
@@ -68,6 +68,7 @@ static int snd_emu10k1_spdif_get_mask(sn
 	return 0;
 }
 
+#if 0
 static int snd_audigy_spdif_output_rate_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
 {
 	static char *texts[] = {"44100", "48000", "96000"};
@@ -152,6 +153,7 @@ static snd_kcontrol_new_t snd_audigy_spd
 	.get =          snd_audigy_spdif_output_rate_get,
 	.put =          snd_audigy_spdif_output_rate_put
 };
+#endif
 
 static int snd_emu10k1_spdif_put(snd_kcontrol_t * kcontrol,
                                  snd_ctl_elem_value_t * ucontrol)
@@ -791,7 +793,7 @@ int __devinit snd_emu10k1_mixer(emu10k1_
 		NULL
 	};
 
-	if (!emu->no_ac97) {
+	if (emu->card_capabilities->ac97_chip) {
 		ac97_bus_t *pbus;
 		ac97_template_t ac97;
 		static ac97_bus_ops_t ops = {
@@ -833,7 +835,7 @@ int __devinit snd_emu10k1_mixer(emu10k1_
 		for (; *c; c++)
 			remove_ctl(card, *c);
 	} else {
-		if (emu->APS)
+		if (emu->card_capabilities->ecard)
 			strcpy(emu->card->mixername, "EMU APS");
 		else if (emu->audigy)
 			strcpy(emu->card->mixername, "SB Audigy");
@@ -918,7 +920,7 @@ int __devinit snd_emu10k1_mixer(emu10k1_
 		mix->attn[0] = 0xffff;
 	}
 	
-	if (! emu->APS) { /* FIXME: APS has these controls? */
+	if (! emu->card_capabilities->ecard) { /* FIXME: APS has these controls? */
 		/* sb live! and audigy */
 		if ((kctl = snd_ctl_new1(&snd_emu10k1_spdif_mask_control, emu)) == NULL)
 			return -ENOMEM;
@@ -935,18 +937,20 @@ int __devinit snd_emu10k1_mixer(emu10k1_
 			return -ENOMEM;
 		if ((err = snd_ctl_add(card, kctl)))
 			return err;
+#if 0
 		if ((kctl = snd_ctl_new1(&snd_audigy_spdif_output_rate, emu)) == NULL)
 			return -ENOMEM;
 		if ((err = snd_ctl_add(card, kctl)))
 			return err;
-	} else if (! emu->APS) {
+#endif
+	} else if (! emu->card_capabilities->ecard) {
 		/* sb live! */
 		if ((kctl = snd_ctl_new1(&snd_emu10k1_shared_spdif, emu)) == NULL)
 			return -ENOMEM;
 		if ((err = snd_ctl_add(card, kctl)))
 			return err;
 	}
-	if (emu->audigy && emu->revision == 4) { /* P16V */
+	if (emu->card_capabilities->ca0151_chip) { /* P16V */
 		if ((err = snd_p16v_mixer(emu)))
 			return err;
 	}
diff --git a/sound/pci/emu10k1/emupcm.c b/sound/pci/emu10k1/emupcm.c
--- a/sound/pci/emu10k1/emupcm.c
+++ b/sound/pci/emu10k1/emupcm.c
@@ -262,7 +262,7 @@ static unsigned int emu10k1_select_inter
  *
  * returns: cache invalidate size in samples
  */
-static int inline emu10k1_ccis(int stereo, int w_16)
+static inline int emu10k1_ccis(int stereo, int w_16)
 {
 	if (w_16) {
 		return stereo ? 24 : 26;
@@ -991,9 +991,7 @@ static void snd_emu10k1_pcm_efx_mixer_no
 
 static void snd_emu10k1_pcm_free_substream(snd_pcm_runtime_t *runtime)
 {
-	emu10k1_pcm_t *epcm = runtime->private_data;
-
-	kfree(epcm);
+	kfree(runtime->private_data);
 }
 
 static int snd_emu10k1_efx_playback_close(snd_pcm_substream_t * substream)
diff --git a/sound/pci/emu10k1/emuproc.c b/sound/pci/emu10k1/emuproc.c
--- a/sound/pci/emu10k1/emuproc.c
+++ b/sound/pci/emu10k1/emuproc.c
@@ -30,6 +30,7 @@
 #include <linux/init.h>
 #include <sound/core.h>
 #include <sound/emu10k1.h>
+#include "p16v.h"
 
 static void snd_emu10k1_proc_spdif_status(emu10k1_t * emu,
 					  snd_info_buffer_t * buffer,
@@ -44,28 +45,34 @@ static void snd_emu10k1_proc_spdif_statu
 	unsigned int status, rate = 0;
 	
 	status = snd_emu10k1_ptr_read(emu, status_reg, 0);
-	if (rate_reg > 0)
-		rate = snd_emu10k1_ptr_read(emu, rate_reg, 0);
 
 	snd_iprintf(buffer, "\n%s\n", title);
 
-	snd_iprintf(buffer, "Professional Mode     : %s\n", (status & SPCS_PROFESSIONAL) ? "yes" : "no");
-	snd_iprintf(buffer, "Not Audio Data        : %s\n", (status & SPCS_NOTAUDIODATA) ? "yes" : "no");
-	snd_iprintf(buffer, "Copyright             : %s\n", (status & SPCS_COPYRIGHT) ? "yes" : "no");
-	snd_iprintf(buffer, "Emphasis              : %s\n", emphasis[(status & SPCS_EMPHASISMASK) >> 3]);
-	snd_iprintf(buffer, "Mode                  : %i\n", (status & SPCS_MODEMASK) >> 6);
-	snd_iprintf(buffer, "Category Code         : 0x%x\n", (status & SPCS_CATEGORYCODEMASK) >> 8);
-	snd_iprintf(buffer, "Generation Status     : %s\n", status & SPCS_GENERATIONSTATUS ? "original" : "copy");
-	snd_iprintf(buffer, "Source Mask           : %i\n", (status & SPCS_SOURCENUMMASK) >> 16);
-	snd_iprintf(buffer, "Channel Number        : %s\n", channel[(status & SPCS_CHANNELNUMMASK) >> 20]);
-	snd_iprintf(buffer, "Sample Rate           : %iHz\n", samplerate[(status & SPCS_SAMPLERATEMASK) >> 24]);
-	snd_iprintf(buffer, "Clock Accuracy        : %s\n", clkaccy[(status & SPCS_CLKACCYMASK) >> 28]);
-
-	if (rate_reg > 0) {
-		snd_iprintf(buffer, "S/PDIF Locked         : %s\n", rate & SRCS_SPDIFLOCKED ? "on" : "off");
-		snd_iprintf(buffer, "Rate Locked           : %s\n", rate & SRCS_RATELOCKED ? "on" : "off");
-		snd_iprintf(buffer, "Estimated Sample Rate : 0x%x\n", rate & SRCS_ESTSAMPLERATE);
+	if (status != 0xffffffff) {
+		snd_iprintf(buffer, "Professional Mode     : %s\n", (status & SPCS_PROFESSIONAL) ? "yes" : "no");
+		snd_iprintf(buffer, "Not Audio Data        : %s\n", (status & SPCS_NOTAUDIODATA) ? "yes" : "no");
+		snd_iprintf(buffer, "Copyright             : %s\n", (status & SPCS_COPYRIGHT) ? "yes" : "no");
+		snd_iprintf(buffer, "Emphasis              : %s\n", emphasis[(status & SPCS_EMPHASISMASK) >> 3]);
+		snd_iprintf(buffer, "Mode                  : %i\n", (status & SPCS_MODEMASK) >> 6);
+		snd_iprintf(buffer, "Category Code         : 0x%x\n", (status & SPCS_CATEGORYCODEMASK) >> 8);
+		snd_iprintf(buffer, "Generation Status     : %s\n", status & SPCS_GENERATIONSTATUS ? "original" : "copy");
+		snd_iprintf(buffer, "Source Mask           : %i\n", (status & SPCS_SOURCENUMMASK) >> 16);
+		snd_iprintf(buffer, "Channel Number        : %s\n", channel[(status & SPCS_CHANNELNUMMASK) >> 20]);
+		snd_iprintf(buffer, "Sample Rate           : %iHz\n", samplerate[(status & SPCS_SAMPLERATEMASK) >> 24]);
+		snd_iprintf(buffer, "Clock Accuracy        : %s\n", clkaccy[(status & SPCS_CLKACCYMASK) >> 28]);
+
+		if (rate_reg > 0) {
+			rate = snd_emu10k1_ptr_read(emu, rate_reg, 0);
+			snd_iprintf(buffer, "S/PDIF Valid          : %s\n", rate & SRCS_SPDIFVALID ? "on" : "off");
+			snd_iprintf(buffer, "S/PDIF Locked         : %s\n", rate & SRCS_SPDIFLOCKED ? "on" : "off");
+			snd_iprintf(buffer, "Rate Locked           : %s\n", rate & SRCS_RATELOCKED ? "on" : "off");
+			/* From ((Rate * 48000 ) / 262144); */
+			snd_iprintf(buffer, "Estimated Sample Rate : %d\n", ((rate & 0xFFFFF ) * 375) >> 11); 
+		}
+	} else {
+		snd_iprintf(buffer, "No signal detected.\n");
 	}
+
 }
 
 static void snd_emu10k1_proc_read(snd_info_entry_t *entry, 
@@ -182,7 +189,7 @@ static void snd_emu10k1_proc_read(snd_in
 	
 	snd_iprintf(buffer, "EMU10K1\n\n");
 	snd_iprintf(buffer, "Card                  : %s\n",
-		    emu->audigy ? "Audigy" : (emu->APS ? "EMU APS" : "Creative"));
+		    emu->audigy ? "Audigy" : (emu->card_capabilities->ecard ? "EMU APS" : "Creative"));
 	snd_iprintf(buffer, "Internal TRAM (words) : 0x%x\n", emu->fx8010.itram_size);
 	snd_iprintf(buffer, "External TRAM (words) : 0x%x\n", (int)emu->fx8010.etram_pages.bytes / 2);
 	snd_iprintf(buffer, "\n");
@@ -223,15 +230,35 @@ static void snd_emu10k1_proc_read(snd_in
 	snd_iprintf(buffer, "\nAll FX Outputs        :\n");
 	for (idx = 0; idx < (emu->audigy ? 64 : 32); idx++)
 		snd_iprintf(buffer, "  Output %02i [%s]\n", idx, outputs[idx]);
-	snd_emu10k1_proc_spdif_status(emu, buffer, "S/PDIF Output 0", SPCS0, -1);
-	snd_emu10k1_proc_spdif_status(emu, buffer, "S/PDIF Output 1", SPCS1, -1);
-	snd_emu10k1_proc_spdif_status(emu, buffer, "S/PDIF Output 2/3", SPCS2, -1);
-	snd_emu10k1_proc_spdif_status(emu, buffer, "CD-ROM S/PDIF", CDCS, CDSRCS);
-	snd_emu10k1_proc_spdif_status(emu, buffer, "General purpose S/PDIF", GPSCS, GPSRCS);
+}
+
+static void snd_emu10k1_proc_spdif_read(snd_info_entry_t *entry, 
+				  snd_info_buffer_t * buffer)
+{
+	emu10k1_t *emu = entry->private_data;
+	snd_emu10k1_proc_spdif_status(emu, buffer, "CD-ROM S/PDIF In", CDCS, CDSRCS);
+	snd_emu10k1_proc_spdif_status(emu, buffer, "Optical or Coax S/PDIF In", GPSCS, GPSRCS);
+#if 0
 	val = snd_emu10k1_ptr_read(emu, ZVSRCS, 0);
 	snd_iprintf(buffer, "\nZoomed Video\n");
 	snd_iprintf(buffer, "Rate Locked           : %s\n", val & SRCS_RATELOCKED ? "on" : "off");
 	snd_iprintf(buffer, "Estimated Sample Rate : 0x%x\n", val & SRCS_ESTSAMPLERATE);
+#endif
+}
+
+static void snd_emu10k1_proc_rates_read(snd_info_entry_t *entry, 
+				  snd_info_buffer_t * buffer)
+{
+	static int samplerate[8] = { 44100, 48000, 96000, 192000, 4, 5, 6, 7 };
+	emu10k1_t *emu = entry->private_data;
+	unsigned int val, tmp, n;
+	val = snd_emu10k1_ptr20_read(emu, CAPTURE_RATE_STATUS, 0);
+	tmp = (val >> 16) & 0x8;
+	for (n=0;n<4;n++) {
+		tmp = val >> (16 + (n*4));
+		if (tmp & 0x8) snd_iprintf(buffer, "Channel %d: Rate=%d\n", n, samplerate[tmp & 0x7]);
+		else snd_iprintf(buffer, "Channel %d: No input\n", n);
+	}
 }
 
 static void snd_emu10k1_proc_acode_read(snd_info_entry_t *entry, 
@@ -500,32 +527,46 @@ int __devinit snd_emu10k1_proc_init(emu1
 		snd_info_set_text_ops(entry, emu, 1024, snd_emu_proc_io_reg_read);
 		entry->c.text.write_size = 64;
 		entry->c.text.write = snd_emu_proc_io_reg_write;
+		entry->mode |= S_IWUSR;
 	}
 	if (! snd_card_proc_new(emu->card, "ptr_regs00a", &entry)) {
 		snd_info_set_text_ops(entry, emu, 65536, snd_emu_proc_ptr_reg_read00a);
 		entry->c.text.write_size = 64;
 		entry->c.text.write = snd_emu_proc_ptr_reg_write00;
+		entry->mode |= S_IWUSR;
 	}
 	if (! snd_card_proc_new(emu->card, "ptr_regs00b", &entry)) {
 		snd_info_set_text_ops(entry, emu, 65536, snd_emu_proc_ptr_reg_read00b);
 		entry->c.text.write_size = 64;
 		entry->c.text.write = snd_emu_proc_ptr_reg_write00;
+		entry->mode |= S_IWUSR;
 	}
 	if (! snd_card_proc_new(emu->card, "ptr_regs20a", &entry)) {
 		snd_info_set_text_ops(entry, emu, 65536, snd_emu_proc_ptr_reg_read20a);
 		entry->c.text.write_size = 64;
 		entry->c.text.write = snd_emu_proc_ptr_reg_write20;
+		entry->mode |= S_IWUSR;
 	}
 	if (! snd_card_proc_new(emu->card, "ptr_regs20b", &entry)) {
 		snd_info_set_text_ops(entry, emu, 65536, snd_emu_proc_ptr_reg_read20b);
 		entry->c.text.write_size = 64;
 		entry->c.text.write = snd_emu_proc_ptr_reg_write20;
+		entry->mode |= S_IWUSR;
 	}
 #endif
 	
 	if (! snd_card_proc_new(emu->card, "emu10k1", &entry))
 		snd_info_set_text_ops(entry, emu, 2048, snd_emu10k1_proc_read);
 
+	if (emu->card_capabilities->emu10k2_chip) {
+		if (! snd_card_proc_new(emu->card, "spdif-in", &entry))
+			snd_info_set_text_ops(entry, emu, 2048, snd_emu10k1_proc_spdif_read);
+	}
+	if (emu->card_capabilities->ca0151_chip) {
+		if (! snd_card_proc_new(emu->card, "capture-rates", &entry))
+			snd_info_set_text_ops(entry, emu, 2048, snd_emu10k1_proc_rates_read);
+	}
+
 	if (! snd_card_proc_new(emu->card, "voices", &entry))
 		snd_info_set_text_ops(entry, emu, 2048, snd_emu10k1_proc_voices_read);
 
diff --git a/sound/pci/emu10k1/irq.c b/sound/pci/emu10k1/irq.c
--- a/sound/pci/emu10k1/irq.c
+++ b/sound/pci/emu10k1/irq.c
@@ -37,7 +37,7 @@ irqreturn_t snd_emu10k1_interrupt(int ir
 	int handled = 0;
 
 	while ((status = inl(emu->port + IPR)) != 0) {
-		// printk("irq - status = 0x%x\n", status);
+		//printk("emu10k1 irq - status = 0x%x\n", status);
 		orig_status = status;
 		handled = 1;
 		if (status & IPR_PCIERROR) {
@@ -147,9 +147,36 @@ irqreturn_t snd_emu10k1_interrupt(int ir
 				snd_emu10k1_intr_disable(emu, INTE_FXDSPENABLE);
 			status &= ~IPR_FXDSP;
 		}
+		if (status & IPR_P16V) {
+			while ((status2 = inl(emu->port + IPR2)) != 0) {
+				u32 mask = INTE2_PLAYBACK_CH_0_LOOP;  /* Full Loop */
+				emu10k1_voice_t *pvoice = &(emu->p16v_voices[0]);
+				emu10k1_voice_t *cvoice = &(emu->p16v_capture_voice);
+
+				//printk(KERN_INFO "status2=0x%x\n", status2);
+				orig_status2 = status2;
+				if(status2 & mask) {
+					if(pvoice->use) {
+						snd_pcm_period_elapsed(pvoice->epcm->substream);
+					} else { 
+						snd_printk(KERN_ERR "p16v: status: 0x%08x, mask=0x%08x, pvoice=%p, use=%d\n", status2, mask, pvoice, pvoice->use);
+					}
+				}
+				if(status2 & 0x110000) {
+					//printk(KERN_INFO "capture int found\n");
+					if(cvoice->use) {
+						//printk(KERN_INFO "capture period_elapsed\n");
+						snd_pcm_period_elapsed(cvoice->epcm->substream);
+					}
+				}
+				outl(orig_status2, emu->port + IPR2); /* ack all */
+			}
+			status &= ~IPR_P16V;
+		}
+
 		if (status) {
 			unsigned int bits;
-			//snd_printk(KERN_ERR "emu10k1: unhandled interrupt: 0x%08x\n", status);
+			snd_printk(KERN_ERR "emu10k1: unhandled interrupt: 0x%08x\n", status);
 			//make sure any interrupts we don't handle are disabled:
 			bits = INTE_FXDSPENABLE |
 				INTE_PCIERRORENABLE |
@@ -170,20 +197,5 @@ irqreturn_t snd_emu10k1_interrupt(int ir
 		}
 		outl(orig_status, emu->port + IPR); /* ack all */
 	}
-	if (emu->audigy && emu->revision == 4) { /* P16V */	
-		while ((status2 = inl(emu->port + IPR2)) != 0) {
-			u32 mask = INTE2_PLAYBACK_CH_0_LOOP;  /* Full Loop */
-			emu10k1_voice_t *pvoice = &(emu->p16v_voices[0]);
-			orig_status2 = status2;
-			if(status2 & mask) {
-				if(pvoice->use) {
-					snd_pcm_period_elapsed(pvoice->epcm->substream);
-				} else { 
-					snd_printk(KERN_ERR "p16v: status: 0x%08x, mask=0x%08x, pvoice=%p, use=%d\n", status2, mask, pvoice, pvoice->use);
-				}
-			}
-			outl(orig_status2, emu->port + IPR2); /* ack all */
-		}
-	}
 	return IRQ_RETVAL(handled);
 }
diff --git a/sound/pci/emu10k1/memory.c b/sound/pci/emu10k1/memory.c
--- a/sound/pci/emu10k1/memory.c
+++ b/sound/pci/emu10k1/memory.c
@@ -495,7 +495,7 @@ static int synth_free_pages(emu10k1_t *e
 }
 
 /* calculate buffer pointer from offset address */
-inline static void *offset_ptr(emu10k1_t *emu, int page, int offset)
+static inline void *offset_ptr(emu10k1_t *emu, int page, int offset)
 {
 	char *ptr;
 	snd_assert(page >= 0 && page < emu->max_cache_pages, return NULL);
diff --git a/sound/pci/emu10k1/p16v.c b/sound/pci/emu10k1/p16v.c
--- a/sound/pci/emu10k1/p16v.c
+++ b/sound/pci/emu10k1/p16v.c
@@ -1,7 +1,7 @@
 /*
  *  Copyright (c) by James Courtier-Dutton <James@superbug.demon.co.uk>
  *  Driver p16v chips
- *  Version: 0.22
+ *  Version: 0.25
  *
  *  FEATURES currently supported:
  *    Output fixed at S32_LE, 2 channel to hw:0,0
@@ -41,7 +41,15 @@
  *    Integrated with snd-emu10k1 driver.
  *  0.22
  *    Removed #if 0 ... #endif
- *
+ *  0.23
+ *    Implement different capture rates.
+ *  0.24
+ *    Implement different capture source channels.
+ *    e.g. When HD Capture source is set to SPDIF,
+ *    setting HD Capture channel to 0 captures from CDROM digital input.
+ *    setting HD Capture channel to 1 captures from SPDIF in.
+ *  0.25
+ *    Include capture buffer sizes.
  *
  *  BUGS:
  *    Some stability problems when unloading the snd-p16v kernel module.
@@ -119,22 +127,41 @@ static snd_pcm_hardware_t snd_p16v_playb
 				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
 				 SNDRV_PCM_INFO_MMAP_VALID),
 	.formats =		SNDRV_PCM_FMTBIT_S32_LE, /* Only supports 24-bit samples padded to 32 bits. */
-	.rates =		SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_48000 ,
-	.rate_min =		48000,
+	.rates =		SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_44100, 
+	.rate_min =		44100,
 	.rate_max =		192000,
 	.channels_min =		8, 
 	.channels_max =		8,
-	.buffer_bytes_max =	(32*1024),
+	.buffer_bytes_max =	((65536 - 64) * 8),
 	.period_bytes_min =	64,
-	.period_bytes_max =	(16*1024),
+	.period_bytes_max =	(65536 - 64),
 	.periods_min =		2,
 	.periods_max =		8,
 	.fifo_size =		0,
 };
 
+static snd_pcm_hardware_t snd_p16v_capture_hw = {
+	.info =			(SNDRV_PCM_INFO_MMAP |
+				 SNDRV_PCM_INFO_INTERLEAVED |
+				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
+				 SNDRV_PCM_INFO_MMAP_VALID),
+	.formats =		SNDRV_PCM_FMTBIT_S32_LE,
+	.rates =		SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_44100, 
+	.rate_min =		44100,
+	.rate_max =		192000,
+	.channels_min =		2,
+	.channels_max =		2,
+	.buffer_bytes_max =	(65536 - 64),
+	.period_bytes_min =	64,
+	.period_bytes_max =	(65536 - 128) >> 1,  /* size has to be N*64 bytes */
+	.periods_min =		2,
+	.periods_max =		2,
+	.fifo_size =		0,
+};
+
 static void snd_p16v_pcm_free_substream(snd_pcm_runtime_t *runtime)
 {
-	snd_pcm_t *epcm = runtime->private_data;
+	emu10k1_pcm_t *epcm = runtime->private_data;
   
 	if (epcm) {
         	//snd_printk("epcm free: %p\n", epcm);
@@ -178,15 +205,63 @@ static int snd_p16v_pcm_open_playback_ch
 
 	return 0;
 }
+/* open_capture callback */
+static int snd_p16v_pcm_open_capture_channel(snd_pcm_substream_t *substream, int channel_id)
+{
+	emu10k1_t *emu = snd_pcm_substream_chip(substream);
+	emu10k1_voice_t *channel = &(emu->p16v_capture_voice);
+	emu10k1_pcm_t *epcm;
+	snd_pcm_runtime_t *runtime = substream->runtime;
+	int err;
+
+	epcm = kcalloc(1, sizeof(*epcm), GFP_KERNEL);
+	//snd_printk("epcm kcalloc: %p\n", epcm);
+
+	if (epcm == NULL)
+		return -ENOMEM;
+	epcm->emu = emu;
+	epcm->substream = substream;
+	//snd_printk("epcm device=%d, channel_id=%d\n", substream->pcm->device, channel_id);
+
+	runtime->private_data = epcm;
+	runtime->private_free = snd_p16v_pcm_free_substream;
+  
+	runtime->hw = snd_p16v_capture_hw;
+
+	channel->emu = emu;
+	channel->number = channel_id;
+
+	channel->use=1;
+	//snd_printk("p16v: open channel_id=%d, channel=%p, use=0x%x\n", channel_id, channel, channel->use);
+	//printk("open:channel_id=%d, chip=%p, channel=%p\n",channel_id, chip, channel);
+	//channel->interrupt = snd_p16v_pcm_channel_interrupt;
+	channel->epcm=epcm;
+	if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
+		return err;
+
+	return 0;
+}
+
 
 /* close callback */
 static int snd_p16v_pcm_close_playback(snd_pcm_substream_t *substream)
 {
 	emu10k1_t *emu = snd_pcm_substream_chip(substream);
 	//snd_pcm_runtime_t *runtime = substream->runtime;
-        //emu10k1_pcm_t *epcm = runtime->private_data;
-        emu->p16v_voices[substream->pcm->device - emu->p16v_device_offset].use=0;
-/* FIXME: maybe zero others */
+	//emu10k1_pcm_t *epcm = runtime->private_data;
+	emu->p16v_voices[substream->pcm->device - emu->p16v_device_offset].use=0;
+	/* FIXME: maybe zero others */
+	return 0;
+}
+
+/* close callback */
+static int snd_p16v_pcm_close_capture(snd_pcm_substream_t *substream)
+{
+	emu10k1_t *emu = snd_pcm_substream_chip(substream);
+	//snd_pcm_runtime_t *runtime = substream->runtime;
+	//emu10k1_pcm_t *epcm = runtime->private_data;
+	emu->p16v_capture_voice.use=0;
+	/* FIXME: maybe zero others */
 	return 0;
 }
 
@@ -195,36 +270,55 @@ static int snd_p16v_pcm_open_playback_fr
 	return snd_p16v_pcm_open_playback_channel(substream, PCM_FRONT_CHANNEL);
 }
 
+static int snd_p16v_pcm_open_capture(snd_pcm_substream_t *substream)
+{
+	// Only using channel 0 for now, but the card has 2 channels.
+	return snd_p16v_pcm_open_capture_channel(substream, 0);
+}
+
 /* hw_params callback */
 static int snd_p16v_pcm_hw_params_playback(snd_pcm_substream_t *substream,
 				      snd_pcm_hw_params_t * hw_params)
 {
 	int result;
-        //snd_printk("hw_params alloc: substream=%p\n", substream);
 	result = snd_pcm_lib_malloc_pages(substream,
 					params_buffer_bytes(hw_params));
-        //snd_printk("hw_params alloc: result=%d\n", result);
-	//dump_stack();
 	return result;
 }
 
+/* hw_params callback */
+static int snd_p16v_pcm_hw_params_capture(snd_pcm_substream_t *substream,
+				      snd_pcm_hw_params_t * hw_params)
+{
+	int result;
+	result = snd_pcm_lib_malloc_pages(substream,
+					params_buffer_bytes(hw_params));
+	return result;
+}
+
+
 /* hw_free callback */
 static int snd_p16v_pcm_hw_free_playback(snd_pcm_substream_t *substream)
 {
 	int result;
-        //snd_printk("hw_params free: substream=%p\n", substream);
 	result = snd_pcm_lib_free_pages(substream);
-        //snd_printk("hw_params free: result=%d\n", result);
-	//dump_stack();
 	return result;
 }
 
+/* hw_free callback */
+static int snd_p16v_pcm_hw_free_capture(snd_pcm_substream_t *substream)
+{
+	int result;
+	result = snd_pcm_lib_free_pages(substream);
+	return result;
+}
+
+
 /* prepare playback callback */
 static int snd_p16v_pcm_prepare_playback(snd_pcm_substream_t *substream)
 {
 	emu10k1_t *emu = snd_pcm_substream_chip(substream);
 	snd_pcm_runtime_t *runtime = substream->runtime;
-	//emu10k1_pcm_t *epcm = runtime->private_data;
 	int channel = substream->pcm->device - emu->p16v_device_offset;
 	u32 *table_base = (u32 *)(emu->p16v_buffer.area+(8*16*channel));
 	u32 period_size_bytes = frames_to_bytes(runtime, runtime->period_size);
@@ -237,23 +331,21 @@ static int snd_p16v_pcm_prepare_playback
 	tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, channel);
         switch (runtime->rate) {
 	case 44100:
-	  snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0xe000) | 0x8000); /* FIXME: This will change the capture rate as well! */
-	  break;
-	case 48000:
-	  snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0xe000) | 0x0000); /* FIXME: This will change the capture rate as well! */
+	  snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0xe0e0) | 0x8080);
 	  break;
 	case 96000:
-	  snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0xe000) | 0x4000); /* FIXME: This will change the capture rate as well! */
+	  snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0xe0e0) | 0x4040);
 	  break;
 	case 192000:
-	  snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0xe000) | 0x2000); /* FIXME: This will change the capture rate as well! */
+	  snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0xe0e0) | 0x2020);
 	  break;
+	case 48000:
 	default:
-	  snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, 0x0000); /* FIXME: This will change the capture rate as well! */
+	  snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0xe0e0) | 0x0000);
 	  break;
 	}
 	/* FIXME: Check emu->buffer.size before actually writing to it. */
-        for(i=0; i < runtime->periods; i++) {
+	for(i=0; i < runtime->periods; i++) {
 		table_base[i*2]=runtime->dma_addr+(i*period_size_bytes);
 		table_base[(i*2)+1]=period_size_bytes<<16;
 	}
@@ -262,7 +354,8 @@ static int snd_p16v_pcm_prepare_playback
 	snd_emu10k1_ptr20_write(emu, PLAYBACK_LIST_SIZE, channel, (runtime->periods - 1) << 19);
 	snd_emu10k1_ptr20_write(emu, PLAYBACK_LIST_PTR, channel, 0);
 	snd_emu10k1_ptr20_write(emu, PLAYBACK_DMA_ADDR, channel, runtime->dma_addr);
-	snd_emu10k1_ptr20_write(emu, PLAYBACK_PERIOD_SIZE, channel, frames_to_bytes(runtime, runtime->period_size)<<16); // buffer size in bytes
+	//snd_emu10k1_ptr20_write(emu, PLAYBACK_PERIOD_SIZE, channel, frames_to_bytes(runtime, runtime->period_size)<<16); // buffer size in bytes
+	snd_emu10k1_ptr20_write(emu, PLAYBACK_PERIOD_SIZE, channel, 0); // buffer size in bytes
 	snd_emu10k1_ptr20_write(emu, PLAYBACK_POINTER, channel, 0);
 	snd_emu10k1_ptr20_write(emu, 0x07, channel, 0x0);
 	snd_emu10k1_ptr20_write(emu, 0x08, channel, 0);
@@ -270,6 +363,41 @@ static int snd_p16v_pcm_prepare_playback
 	return 0;
 }
 
+/* prepare capture callback */
+static int snd_p16v_pcm_prepare_capture(snd_pcm_substream_t *substream)
+{
+	emu10k1_t *emu = snd_pcm_substream_chip(substream);
+	snd_pcm_runtime_t *runtime = substream->runtime;
+	int channel = substream->pcm->device - emu->p16v_device_offset;
+	u32 tmp;
+	//printk("prepare capture:channel_number=%d, rate=%d, format=0x%x, channels=%d, buffer_size=%ld, period_size=%ld, frames_to_bytes=%d\n",channel, runtime->rate, runtime->format, runtime->channels, runtime->buffer_size, runtime->period_size,  frames_to_bytes(runtime, 1));
+	tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, channel);
+        switch (runtime->rate) {
+	case 44100:
+	  snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0x0e00) | 0x0800);
+	  break;
+	case 96000:
+	  snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0x0e00) | 0x0400);
+	  break;
+	case 192000:
+	  snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0x0e00) | 0x0200);
+	  break;
+	case 48000:
+	default:
+	  snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0x0e00) | 0x0000);
+	  break;
+	}
+	/* FIXME: Check emu->buffer.size before actually writing to it. */
+	snd_emu10k1_ptr20_write(emu, 0x13, channel, 0);
+	snd_emu10k1_ptr20_write(emu, CAPTURE_DMA_ADDR, channel, runtime->dma_addr);
+	snd_emu10k1_ptr20_write(emu, CAPTURE_BUFFER_SIZE, channel, frames_to_bytes(runtime, runtime->buffer_size)<<16); // buffer size in bytes
+	snd_emu10k1_ptr20_write(emu, CAPTURE_POINTER, channel, 0);
+	//snd_emu10k1_ptr20_write(emu, CAPTURE_SOURCE, 0x0, 0x333300e4); /* Select MIC or Line in */
+	//snd_emu10k1_ptr20_write(emu, EXTENDED_INT_MASK, 0, snd_emu10k1_ptr20_read(emu, EXTENDED_INT_MASK, 0) | (0x110000<<channel));
+
+	return 0;
+}
+
 static void snd_p16v_intr_enable(emu10k1_t *emu, unsigned int intrenb)
 {
 	unsigned long flags;
@@ -345,6 +473,36 @@ static int snd_p16v_pcm_trigger_playback
 	return result;
 }
 
+/* trigger_capture callback */
+static int snd_p16v_pcm_trigger_capture(snd_pcm_substream_t *substream,
+                                   int cmd)
+{
+	emu10k1_t *emu = snd_pcm_substream_chip(substream);
+	snd_pcm_runtime_t *runtime = substream->runtime;
+	emu10k1_pcm_t *epcm = runtime->private_data;
+	int channel = 0;
+	int result = 0;
+	u32 inte = INTE2_CAPTURE_CH_0_LOOP | INTE2_CAPTURE_CH_0_HALF_LOOP;
+
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+		snd_p16v_intr_enable(emu, inte);
+		snd_emu10k1_ptr20_write(emu, BASIC_INTERRUPT, 0, snd_emu10k1_ptr20_read(emu, BASIC_INTERRUPT, 0)|(0x100<<channel));
+		epcm->running = 1;
+		break;
+	case SNDRV_PCM_TRIGGER_STOP:
+		snd_emu10k1_ptr20_write(emu, BASIC_INTERRUPT, 0, snd_emu10k1_ptr20_read(emu, BASIC_INTERRUPT, 0) & ~(0x100<<channel));
+		snd_p16v_intr_disable(emu, inte);
+		//snd_emu10k1_ptr20_write(emu, EXTENDED_INT_MASK, 0, snd_emu10k1_ptr20_read(emu, EXTENDED_INT_MASK, 0) & ~(0x110000<<channel));
+		epcm->running = 0;
+		break;
+	default:
+		result = -EINVAL;
+		break;
+	}
+	return result;
+}
+
 /* pointer_playback callback */
 static snd_pcm_uframes_t
 snd_p16v_pcm_pointer_playback(snd_pcm_substream_t *substream)
@@ -370,6 +528,31 @@ snd_p16v_pcm_pointer_playback(snd_pcm_su
 	return ptr;
 }
 
+/* pointer_capture callback */
+static snd_pcm_uframes_t
+snd_p16v_pcm_pointer_capture(snd_pcm_substream_t *substream)
+{
+	emu10k1_t *emu = snd_pcm_substream_chip(substream);
+	snd_pcm_runtime_t *runtime = substream->runtime;
+	emu10k1_pcm_t *epcm = runtime->private_data;
+	snd_pcm_uframes_t ptr, ptr1, ptr2 = 0;
+	int channel = 0;
+
+	if (!epcm->running)
+		return 0;
+
+	ptr1 = snd_emu10k1_ptr20_read(emu, CAPTURE_POINTER, channel);
+	ptr2 = bytes_to_frames(runtime, ptr1);
+	ptr=ptr2;
+	if (ptr >= runtime->buffer_size) {
+		ptr -= runtime->buffer_size;
+		printk("buffer capture limited!\n");
+	}
+	//printk("ptr1 = 0x%lx, ptr2=0x%lx, ptr=0x%lx, buffer_size = 0x%x, period_size = 0x%x, bits=%d, rate=%d\n", ptr1, ptr2, ptr, (int)runtime->buffer_size, (int)runtime->period_size, (int)runtime->frame_bits, (int)runtime->rate);
+
+	return ptr;
+}
+
 /* operators */
 static snd_pcm_ops_t snd_p16v_playback_front_ops = {
 	.open =        snd_p16v_pcm_open_playback_front,
@@ -382,6 +565,18 @@ static snd_pcm_ops_t snd_p16v_playback_f
 	.pointer =     snd_p16v_pcm_pointer_playback,
 };
 
+static snd_pcm_ops_t snd_p16v_capture_ops = {
+	.open =        snd_p16v_pcm_open_capture,
+	.close =       snd_p16v_pcm_close_capture,
+	.ioctl =       snd_pcm_lib_ioctl,
+	.hw_params =   snd_p16v_pcm_hw_params_capture,
+	.hw_free =     snd_p16v_pcm_hw_free_capture,
+	.prepare =     snd_p16v_pcm_prepare_capture,
+	.trigger =     snd_p16v_pcm_trigger_capture,
+	.pointer =     snd_p16v_pcm_pointer_capture,
+};
+
+
 int snd_p16v_free(emu10k1_t *chip)
 {
 	// release the data
@@ -405,20 +600,22 @@ int snd_p16v_pcm(emu10k1_t *emu, int dev
 	snd_pcm_t *pcm;
 	snd_pcm_substream_t *substream;
 	int err;
-        int capture=0;
+        int capture=1;
   
 	//snd_printk("snd_p16v_pcm called. device=%d\n", device);
 	emu->p16v_device_offset = device;
 	if (rpcm)
 		*rpcm = NULL;
-        //if (device == 0) capture=1; 
+
 	if ((err = snd_pcm_new(emu->card, "p16v", device, 1, capture, &pcm)) < 0)
 		return err;
   
 	pcm->private_data = emu;
 	pcm->private_free = snd_p16v_pcm_free;
-
+	// Single playback 8 channel device.
+	// Single capture 2 channel device.
 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_p16v_playback_front_ops);
+	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_p16v_capture_ops);
 
 	pcm->info_flags = 0;
 	pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX;
@@ -431,7 +628,7 @@ int snd_p16v_pcm(emu10k1_t *emu, int dev
 		if ((err = snd_pcm_lib_preallocate_pages(substream, 
 							 SNDRV_DMA_TYPE_DEV, 
 							 snd_dma_pci_data(emu->pci), 
-							 64*1024, 64*1024)) < 0) /* FIXME: 32*1024 for sound buffer, between 32and64 for Periods table. */
+							 ((65536 - 64) * 8), ((65536 - 64) * 8))) < 0) 
 			return err;
 		//snd_printk("preallocate playback substream: err=%d\n", err);
 	}
@@ -442,7 +639,7 @@ int snd_p16v_pcm(emu10k1_t *emu, int dev
  		if ((err = snd_pcm_lib_preallocate_pages(substream, 
 	                                           SNDRV_DMA_TYPE_DEV, 
 	                                           snd_dma_pci_data(emu->pci), 
-	                                           64*1024, 64*1024)) < 0)
+	                                           65536 - 64, 65536 - 64)) < 0)
 			return err;
 		//snd_printk("preallocate capture substream: err=%d\n", err);
 	}
@@ -625,7 +822,7 @@ static int snd_p16v_volume_put_analog_un
 static snd_kcontrol_new_t snd_p16v_volume_control_analog_front =
 {
         .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
-        .name =         "HD Analog Front Volume",
+        .name =         "HD Analog Front Playback Volume",
         .info =         snd_p16v_volume_info,
         .get =          snd_p16v_volume_get_analog_front,
         .put =          snd_p16v_volume_put_analog_front
@@ -634,7 +831,7 @@ static snd_kcontrol_new_t snd_p16v_volum
 static snd_kcontrol_new_t snd_p16v_volume_control_analog_center_lfe =
 {
         .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
-        .name =         "HD Analog Center/LFE Volume",
+        .name =         "HD Analog Center/LFE Playback Volume",
         .info =         snd_p16v_volume_info,
         .get =          snd_p16v_volume_get_analog_center_lfe,
         .put =          snd_p16v_volume_put_analog_center_lfe
@@ -643,7 +840,7 @@ static snd_kcontrol_new_t snd_p16v_volum
 static snd_kcontrol_new_t snd_p16v_volume_control_analog_unknown =
 {
         .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
-        .name =         "HD Analog Unknown Volume",
+        .name =         "HD Analog Unknown Playback Volume",
         .info =         snd_p16v_volume_info,
         .get =          snd_p16v_volume_get_analog_unknown,
         .put =          snd_p16v_volume_put_analog_unknown
@@ -652,7 +849,7 @@ static snd_kcontrol_new_t snd_p16v_volum
 static snd_kcontrol_new_t snd_p16v_volume_control_analog_rear =
 {
         .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
-        .name =         "HD Analog Rear Volume",
+        .name =         "HD Analog Rear Playback Volume",
         .info =         snd_p16v_volume_info,
         .get =          snd_p16v_volume_get_analog_rear,
         .put =          snd_p16v_volume_put_analog_rear
@@ -661,7 +858,7 @@ static snd_kcontrol_new_t snd_p16v_volum
 static snd_kcontrol_new_t snd_p16v_volume_control_spdif_front =
 {
         .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
-        .name =         "HD SPDIF Front Volume",
+        .name =         "HD SPDIF Front Playback Volume",
         .info =         snd_p16v_volume_info,
         .get =          snd_p16v_volume_get_spdif_front,
         .put =          snd_p16v_volume_put_spdif_front
@@ -670,7 +867,7 @@ static snd_kcontrol_new_t snd_p16v_volum
 static snd_kcontrol_new_t snd_p16v_volume_control_spdif_center_lfe =
 {
         .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
-        .name =         "HD SPDIF Center/LFE Volume",
+        .name =         "HD SPDIF Center/LFE Playback Volume",
         .info =         snd_p16v_volume_info,
         .get =          snd_p16v_volume_get_spdif_center_lfe,
         .put =          snd_p16v_volume_put_spdif_center_lfe
@@ -679,7 +876,7 @@ static snd_kcontrol_new_t snd_p16v_volum
 static snd_kcontrol_new_t snd_p16v_volume_control_spdif_unknown =
 {
         .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
-        .name =         "HD SPDIF Unknown Volume",
+        .name =         "HD SPDIF Unknown Playback Volume",
         .info =         snd_p16v_volume_info,
         .get =          snd_p16v_volume_get_spdif_unknown,
         .put =          snd_p16v_volume_put_spdif_unknown
@@ -688,12 +885,112 @@ static snd_kcontrol_new_t snd_p16v_volum
 static snd_kcontrol_new_t snd_p16v_volume_control_spdif_rear =
 {
         .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
-        .name =         "HD SPDIF Rear Volume",
+        .name =         "HD SPDIF Rear Playback Volume",
         .info =         snd_p16v_volume_info,
         .get =          snd_p16v_volume_get_spdif_rear,
         .put =          snd_p16v_volume_put_spdif_rear
 };
 
+static int snd_p16v_capture_source_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+{
+	static char *texts[8] = { "SPDIF", "I2S", "SRC48", "SRCMulti_SPDIF", "SRCMulti_I2S", "CDIF", "FX", "AC97" };
+
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+	uinfo->count = 1;
+	uinfo->value.enumerated.items = 8;
+	if (uinfo->value.enumerated.item > 7)
+                uinfo->value.enumerated.item = 7;
+	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
+	return 0;
+}
+
+static int snd_p16v_capture_source_get(snd_kcontrol_t * kcontrol,
+					snd_ctl_elem_value_t * ucontrol)
+{
+	emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
+
+	ucontrol->value.enumerated.item[0] = emu->p16v_capture_source;
+	return 0;
+}
+
+static int snd_p16v_capture_source_put(snd_kcontrol_t * kcontrol,
+					snd_ctl_elem_value_t * ucontrol)
+{
+	emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
+	unsigned int val;
+	int change = 0;
+	u32 mask;
+	u32 source;
+
+	val = ucontrol->value.enumerated.item[0] ;
+	change = (emu->p16v_capture_source != val);
+	if (change) {
+		emu->p16v_capture_source = val;
+		source = (val << 28) | (val << 24) | (val << 20) | (val << 16);
+		mask = snd_emu10k1_ptr20_read(emu, BASIC_INTERRUPT, 0) & 0xffff;
+		snd_emu10k1_ptr20_write(emu, BASIC_INTERRUPT, 0, source | mask);
+	}
+        return change;
+}
+
+static snd_kcontrol_new_t snd_p16v_capture_source __devinitdata =
+{
+	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
+	.name =		"HD source Capture",
+	.info =		snd_p16v_capture_source_info,
+	.get =		snd_p16v_capture_source_get,
+	.put =		snd_p16v_capture_source_put
+};
+
+static int snd_p16v_capture_channel_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+{
+	static char *texts[4] = { "0", "1", "2", "3",  };
+
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+	uinfo->count = 1;
+	uinfo->value.enumerated.items = 4;
+	if (uinfo->value.enumerated.item > 3)
+                uinfo->value.enumerated.item = 3;
+	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
+	return 0;
+}
+
+static int snd_p16v_capture_channel_get(snd_kcontrol_t * kcontrol,
+					snd_ctl_elem_value_t * ucontrol)
+{
+	emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
+
+	ucontrol->value.enumerated.item[0] = emu->p16v_capture_channel;
+	return 0;
+}
+
+static int snd_p16v_capture_channel_put(snd_kcontrol_t * kcontrol,
+					snd_ctl_elem_value_t * ucontrol)
+{
+	emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
+	unsigned int val;
+	int change = 0;
+	u32 tmp;
+
+	val = ucontrol->value.enumerated.item[0] ;
+	change = (emu->p16v_capture_channel != val);
+	if (change) {
+		emu->p16v_capture_channel = val;
+		tmp = snd_emu10k1_ptr20_read(emu, CAPTURE_P16V_SOURCE, 0) & 0xfffc;
+		snd_emu10k1_ptr20_write(emu, CAPTURE_P16V_SOURCE, 0, tmp | val);
+	}
+        return change;
+}
+
+static snd_kcontrol_new_t snd_p16v_capture_channel __devinitdata =
+{
+	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
+	.name =		"HD channel Capture",
+	.info =		snd_p16v_capture_channel_info,
+	.get =		snd_p16v_capture_channel_get,
+	.put =		snd_p16v_capture_channel_put
+};
+
 int snd_p16v_mixer(emu10k1_t *emu)
 {
         int err;
@@ -731,6 +1028,14 @@ int snd_p16v_mixer(emu10k1_t *emu)
                 return -ENOMEM;
         if ((err = snd_ctl_add(card, kctl)))
                 return err;
+        if ((kctl = snd_ctl_new1(&snd_p16v_capture_source, emu)) == NULL)
+                return -ENOMEM;
+        if ((err = snd_ctl_add(card, kctl)))
+                return err;
+        if ((kctl = snd_ctl_new1(&snd_p16v_capture_channel, emu)) == NULL)
+                return -ENOMEM;
+        if ((err = snd_ctl_add(card, kctl)))
+                return err;
         return 0;
 }
 
diff --git a/sound/pci/ens1370.c b/sound/pci/ens1370.c
--- a/sound/pci/ens1370.c
+++ b/sound/pci/ens1370.c
@@ -685,6 +685,15 @@ static unsigned short snd_es1371_codec_r
 	return 0;
 }
 
+static void snd_es1371_codec_wait(ac97_t *ac97)
+{
+	msleep(750);
+	snd_es1371_codec_read(ac97, AC97_RESET);
+	snd_es1371_codec_read(ac97, AC97_VENDOR_ID1);
+	snd_es1371_codec_read(ac97, AC97_VENDOR_ID2);
+	msleep(50);
+}
+
 static void snd_es1371_adc_rate(ensoniq_t * ensoniq, unsigned int rate)
 {
 	unsigned int n, truncm, freq, result;
@@ -1585,6 +1594,7 @@ static int snd_ensoniq_1371_mixer(ensoni
 	static ac97_bus_ops_t ops = {
 		.write = snd_es1371_codec_write,
 		.read = snd_es1371_codec_read,
+		.wait = snd_es1371_codec_wait,
 	};
 
 	if ((err = snd_ac97_bus(card, 0, &ops, NULL, &pbus)) < 0)
@@ -2008,21 +2018,11 @@ static int __devinit snd_ensoniq_create(
 		if (pci->vendor == es1371_ac97_reset_hack[idx].vid &&
 		    pci->device == es1371_ac97_reset_hack[idx].did &&
 		    ensoniq->rev == es1371_ac97_reset_hack[idx].rev) {
-		        unsigned long tmo;
-			signed long tmo2;
-
 			ensoniq->cssr |= ES_1371_ST_AC97_RST;
 			outl(ensoniq->cssr, ES_REG(ensoniq, STATUS));
 			/* need to delay around 20ms(bleech) to give
 			some CODECs enough time to wakeup */
-			tmo = jiffies + (HZ / 50) + 1;
-			while (1) {
-				tmo2 = tmo - jiffies;
-				if (tmo2 <= 0)
-					break;
-				set_current_state(TASK_UNINTERRUPTIBLE);
-				schedule_timeout(tmo2);
-			}
+			msleep(20);
 			break;
 		}
 	/* AC'97 warm reset to start the bitclk */
@@ -2401,7 +2401,7 @@ static struct pci_driver driver = {
 	
 static int __init alsa_card_ens137x_init(void)
 {
-	return pci_module_init(&driver);
+	return pci_register_driver(&driver);
 }
 
 static void __exit alsa_card_ens137x_exit(void)
diff --git a/sound/pci/es1938.c b/sound/pci/es1938.c
--- a/sound/pci/es1938.c
+++ b/sound/pci/es1938.c
@@ -1761,7 +1761,7 @@ static struct pci_driver driver = {
 
 static int __init alsa_card_es1938_init(void)
 {
-	return pci_module_init(&driver);
+	return pci_register_driver(&driver);
 }
 
 static void __exit alsa_card_es1938_exit(void)
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c
--- a/sound/pci/es1968.c
+++ b/sound/pci/es1968.c
@@ -636,7 +636,7 @@ static void __maestro_write(es1968_t *ch
 	chip->maestro_map[reg] = data;
 }
 
-inline static void maestro_write(es1968_t *chip, u16 reg, u16 data)
+static inline void maestro_write(es1968_t *chip, u16 reg, u16 data)
 {
 	unsigned long flags;
 	spin_lock_irqsave(&chip->reg_lock, flags);
@@ -654,7 +654,7 @@ static u16 __maestro_read(es1968_t *chip
 	return chip->maestro_map[reg];
 }
 
-inline static u16 maestro_read(es1968_t *chip, u16 reg)
+static inline u16 maestro_read(es1968_t *chip, u16 reg)
 {
 	unsigned long flags;
 	u16 result;
@@ -664,11 +664,6 @@ inline static u16 maestro_read(es1968_t 
 	return result;
 }
 
-#define big_mdelay(msec) do {\
-	set_current_state(TASK_UNINTERRUPTIBLE);\
-	schedule_timeout(((msec) * HZ + 999) / 1000);\
-} while (0)
-	
 /* Wait for the codec bus to be free */
 static int snd_es1968_ac97_wait(es1968_t *chip)
 {
@@ -755,7 +750,7 @@ static void __apu_set_register(es1968_t 
 	apu_data_set(chip, data);
 }
 
-inline static void apu_set_register(es1968_t *chip, u16 channel, u8 reg, u16 data)
+static inline void apu_set_register(es1968_t *chip, u16 channel, u8 reg, u16 data)
 {
 	unsigned long flags;
 	spin_lock_irqsave(&chip->reg_lock, flags);
@@ -771,7 +766,7 @@ static u16 __apu_get_register(es1968_t *
 	return __maestro_read(chip, IDR0_DATA_PORT);
 }
 
-inline static u16 apu_get_register(es1968_t *chip, u16 channel, u8 reg)
+static inline u16 apu_get_register(es1968_t *chip, u16 channel, u8 reg)
 {
 	unsigned long flags;
 	u16 v;
@@ -957,7 +952,7 @@ static u32 snd_es1968_compute_rate(es196
 }
 
 /* get current pointer */
-inline static unsigned int
+static inline unsigned int
 snd_es1968_get_dma_ptr(es1968_t *chip, esschan_t *es)
 {
 	unsigned int offset;
@@ -978,7 +973,7 @@ static void snd_es1968_apu_set_freq(es19
 }
 
 /* spin lock held */
-inline static void snd_es1968_trigger_apu(es1968_t *esm, int apu, int mode)
+static inline void snd_es1968_trigger_apu(es1968_t *esm, int apu, int mode)
 {
 	/* set the APU mode */
 	__apu_set_register(esm, apu, 0,
@@ -1809,8 +1804,7 @@ static void __devinit es1968_measure_clo
 	snd_es1968_trigger_apu(chip, apu, ESM_APU_16BITLINEAR);
 	do_gettimeofday(&start_time);
 	spin_unlock_irq(&chip->reg_lock);
-	set_current_state(TASK_UNINTERRUPTIBLE);
-	schedule_timeout(HZ / 20); /* 50 msec */
+	msleep(50);
 	spin_lock_irq(&chip->reg_lock);
 	offset = __apu_get_register(chip, apu, 5);
 	do_gettimeofday(&stop_time);
@@ -2093,7 +2087,7 @@ static void snd_es1968_ac97_reset(es1968
 	outw(0x0000, ioaddr + 0x60);	/* write 0 to gpio 0 */
 	udelay(20);
 	outw(0x0001, ioaddr + 0x60);	/* write 1 to gpio 1 */
-	big_mdelay(20);
+	msleep(20);
 
 	outw(save_68 | 0x1, ioaddr + 0x68);	/* now restore .. */
 	outw((inw(ioaddr + 0x38) & 0xfffc) | 0x1, ioaddr + 0x38);
@@ -2109,7 +2103,7 @@ static void snd_es1968_ac97_reset(es1968
 	outw(0x0001, ioaddr + 0x60);	/* write 1 to gpio */
 	udelay(20);
 	outw(0x0009, ioaddr + 0x60);	/* write 9 to gpio */
-	big_mdelay(500);
+	msleep(500);
 	//outw(inw(ioaddr + 0x38) & 0xfffc, ioaddr + 0x38);
 	outw(inw(ioaddr + 0x3a) & 0xfffc, ioaddr + 0x3a);
 	outw(inw(ioaddr + 0x3c) & 0xfffc, ioaddr + 0x3c);
@@ -2135,7 +2129,7 @@ static void snd_es1968_ac97_reset(es1968
 
 		if (w > 10000) {
 			outb(inb(ioaddr + 0x37) | 0x08, ioaddr + 0x37);	/* do a software reset */
-			big_mdelay(500);	/* oh my.. */
+			msleep(500);	/* oh my.. */
 			outb(inb(ioaddr + 0x37) & ~0x08,
 				ioaddr + 0x37);
 			udelay(1);
@@ -2559,6 +2553,7 @@ static struct ess_device_list pm_whiteli
 	{ TYPE_MAESTRO2E, 0x103c },
 	{ TYPE_MAESTRO2E, 0x1179 },
 	{ TYPE_MAESTRO2E, 0x14c0 },	/* HP omnibook 4150 */
+	{ TYPE_MAESTRO2E, 0x1558 },
 };
 
 static struct ess_device_list mpu_blacklist[] __devinitdata = {
@@ -2795,7 +2790,7 @@ static struct pci_driver driver = {
 
 static int __init alsa_card_es1968_init(void)
 {
-	return pci_module_init(&driver);
+	return pci_register_driver(&driver);
 }
 
 static void __exit alsa_card_es1968_exit(void)
diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c
--- a/sound/pci/fm801.c
+++ b/sound/pci/fm801.c
@@ -195,6 +195,7 @@ struct _snd_fm801 {
 
 static struct pci_device_id snd_fm801_ids[] = {
 	{ 0x1319, 0x0801, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0, },   /* FM801 */
+	{ 0x5213, 0x0510, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0, },   /* Gallant Odyssey Sound 4 */
 	{ 0, }
 };
 
@@ -1468,7 +1469,7 @@ static struct pci_driver driver = {
 
 static int __init alsa_card_fm801_init(void)
 {
-	return pci_module_init(&driver);
+	return pci_register_driver(&driver);
 }
 
 static void __exit alsa_card_fm801_exit(void)
diff --git a/sound/pci/hda/Makefile b/sound/pci/hda/Makefile
--- a/sound/pci/hda/Makefile
+++ b/sound/pci/hda/Makefile
@@ -1,5 +1,5 @@
 snd-hda-intel-objs := hda_intel.o
-snd-hda-codec-objs := hda_codec.o hda_generic.o patch_realtek.o patch_cmedia.o patch_analog.o
+snd-hda-codec-objs := hda_codec.o hda_generic.o patch_realtek.o patch_cmedia.o patch_analog.o patch_sigmatel.o
 ifdef CONFIG_PROC_FS
 snd-hda-codec-objs += hda_proc.o
 endif
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -49,8 +49,10 @@ struct hda_vendor_id {
 /* codec vendor labels */
 static struct hda_vendor_id hda_vendor_ids[] = {
 	{ 0x10ec, "Realtek" },
+	{ 0x11d4, "Analog Devices" },
 	{ 0x13f6, "C-Media" },
 	{ 0x434d, "C-Media" },
+	{ 0x8384, "SigmaTel" },
 	{} /* terminator */
 };
 
@@ -508,7 +510,7 @@ int snd_hda_codec_new(struct hda_bus *bu
 	/* FIXME: support for multiple AFGs? */
 	codec->afg = look_for_afg_node(codec);
 	if (! codec->afg) {
-		snd_printk(KERN_ERR "hda_codec: no AFG node found\n");
+		snd_printdd("hda_codec: no AFG node found\n");
 		snd_hda_codec_free(codec);
 		return -ENODEV;
 	}
@@ -548,6 +550,9 @@ int snd_hda_codec_new(struct hda_bus *bu
 void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid, u32 stream_tag,
 				int channel_id, int format)
 {
+	if (! nid)
+		return;
+
 	snd_printdd("hda_codec_setup_stream: NID=0x%x, stream=0x%x, channel=%d, format=0x%x\n",
 		    nid, stream_tag, channel_id, format);
 	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CHANNEL_STREAMID,
@@ -561,9 +566,10 @@ void snd_hda_codec_setup_stream(struct h
  * amp access functions
  */
 
-#define HDA_HASH_KEY(nid,dir,idx) (u32)((nid) + (idx) * 32 + (dir) * 64)
+/* FIXME: more better hash key? */
+#define HDA_HASH_KEY(nid,dir,idx) (u32)((nid) + ((idx) << 16) + ((dir) << 24))
 #define INFO_AMP_CAPS	(1<<0)
-#define INFO_AMP_VOL	(1<<1)
+#define INFO_AMP_VOL(ch)	(1 << (1 + (ch)))
 
 /* initialize the hash table */
 static void init_amp_hash(struct hda_codec *codec)
@@ -622,28 +628,29 @@ static u32 query_amp_caps(struct hda_cod
 
 /*
  * read the current volume to info
- * if the cache exists, read from the cache.
+ * if the cache exists, read the cache value.
  */
-static void get_vol_mute(struct hda_codec *codec, struct hda_amp_info *info,
+static unsigned int get_vol_mute(struct hda_codec *codec, struct hda_amp_info *info,
 			 hda_nid_t nid, int ch, int direction, int index)
 {
 	u32 val, parm;
 
-	if (info->status & (INFO_AMP_VOL << ch))
-		return;
+	if (info->status & INFO_AMP_VOL(ch))
+		return info->vol[ch];
 
 	parm = ch ? AC_AMP_GET_RIGHT : AC_AMP_GET_LEFT;
 	parm |= direction == HDA_OUTPUT ? AC_AMP_GET_OUTPUT : AC_AMP_GET_INPUT;
 	parm |= index;
 	val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_AMP_GAIN_MUTE, parm);
 	info->vol[ch] = val & 0xff;
-	info->status |= INFO_AMP_VOL << ch;
+	info->status |= INFO_AMP_VOL(ch);
+	return info->vol[ch];
 }
 
 /*
- * write the current volume in info to the h/w
+ * write the current volume in info to the h/w and update the cache
  */
-static void put_vol_mute(struct hda_codec *codec,
+static void put_vol_mute(struct hda_codec *codec, struct hda_amp_info *info,
 			 hda_nid_t nid, int ch, int direction, int index, int val)
 {
 	u32 parm;
@@ -653,30 +660,34 @@ static void put_vol_mute(struct hda_code
 	parm |= index << AC_AMP_SET_INDEX_SHIFT;
 	parm |= val;
 	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, parm);
+	info->vol[ch] = val;
 }
 
 /*
- * read/write AMP value.  The volume is between 0 to 0x7f, 0x80 = mute bit.
+ * read AMP value.  The volume is between 0 to 0x7f, 0x80 = mute bit.
  */
-int snd_hda_codec_amp_read(struct hda_codec *codec, hda_nid_t nid, int ch, int direction, int index)
+static int snd_hda_codec_amp_read(struct hda_codec *codec, hda_nid_t nid, int ch, int direction, int index)
 {
 	struct hda_amp_info *info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, index));
 	if (! info)
 		return 0;
-	get_vol_mute(codec, info, nid, ch, direction, index);
-	return info->vol[ch];
+	return get_vol_mute(codec, info, nid, ch, direction, index);
 }
 
-int snd_hda_codec_amp_write(struct hda_codec *codec, hda_nid_t nid, int ch, int direction, int idx, int val)
+/*
+ * update the AMP value, mask = bit mask to set, val = the value
+ */
+static int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch, int direction, int idx, int mask, int val)
 {
 	struct hda_amp_info *info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, idx));
+
 	if (! info)
 		return 0;
-	get_vol_mute(codec, info, nid, ch, direction, idx);
+	val &= mask;
+	val |= get_vol_mute(codec, info, nid, ch, direction, idx) & ~mask;
 	if (info->vol[ch] == val && ! codec->in_resume)
 		return 0;
-	put_vol_mute(codec, nid, ch, direction, idx, val);
-	info->vol[ch] = val;
+	put_vol_mute(codec, info, nid, ch, direction, idx, val);
 	return 1;
 }
 
@@ -735,21 +746,15 @@ int snd_hda_mixer_amp_volume_put(snd_kco
 	int chs = get_amp_channels(kcontrol);
 	int dir = get_amp_direction(kcontrol);
 	int idx = get_amp_index(kcontrol);
-	int val;
 	long *valp = ucontrol->value.integer.value;
 	int change = 0;
 
-	if (chs & 1) {
-		val = *valp & 0x7f;
-		val |= snd_hda_codec_amp_read(codec, nid, 0, dir, idx) & 0x80;
-		change = snd_hda_codec_amp_write(codec, nid, 0, dir, idx, val);
-		valp++;
-	}
-	if (chs & 2) {
-		val = *valp & 0x7f;
-		val |= snd_hda_codec_amp_read(codec, nid, 1, dir, idx) & 0x80;
-		change |= snd_hda_codec_amp_write(codec, nid, 1, dir, idx, val);
-	}
+	if (chs & 1)
+		change = snd_hda_codec_amp_update(codec, nid, 0, dir, idx,
+						  0x7f, *valp);
+	if (chs & 2)
+		change |= snd_hda_codec_amp_update(codec, nid, 1, dir, idx,
+						   0x7f, valp[1]);
 	return change;
 }
 
@@ -788,21 +793,15 @@ int snd_hda_mixer_amp_switch_put(snd_kco
 	int chs = get_amp_channels(kcontrol);
 	int dir = get_amp_direction(kcontrol);
 	int idx = get_amp_index(kcontrol);
-	int val;
 	long *valp = ucontrol->value.integer.value;
 	int change = 0;
 
-	if (chs & 1) {
-		val = snd_hda_codec_amp_read(codec, nid, 0, dir, idx) & 0x7f;
-		val |= *valp ? 0 : 0x80;
-		change = snd_hda_codec_amp_write(codec, nid, 0, dir, idx, val);
-		valp++;
-	}
-	if (chs & 2) {
-		val = snd_hda_codec_amp_read(codec, nid, 1, dir, idx) & 0x7f;
-		val |= *valp ? 0 : 0x80;
-		change = snd_hda_codec_amp_write(codec, nid, 1, dir, idx, val);
-	}
+	if (chs & 1)
+		change = snd_hda_codec_amp_update(codec, nid, 0, dir, idx,
+						  0x80, *valp ? 0 : 0x80);
+	if (chs & 2)
+		change |= snd_hda_codec_amp_update(codec, nid, 1, dir, idx,
+						   0x80, valp[1] ? 0 : 0x80);
 	return change;
 }
 
@@ -1448,10 +1447,6 @@ static int set_pcm_default_values(struct
 		snd_assert(info->nid, return -EINVAL);
 		info->ops.prepare = hda_pcm_default_prepare;
 	}
-	if (info->ops.prepare == NULL) {
-		snd_assert(info->nid, return -EINVAL);
-		info->ops.prepare = hda_pcm_default_prepare;
-	}
 	if (info->ops.cleanup == NULL) {
 		snd_assert(info->nid, return -EINVAL);
 		info->ops.cleanup = hda_pcm_default_cleanup;
@@ -1525,12 +1520,12 @@ int snd_hda_build_pcms(struct hda_bus *b
  *
  * If no entries are matching, the function returns a negative value.
  */
-int snd_hda_check_board_config(struct hda_codec *codec, struct hda_board_config *tbl)
+int snd_hda_check_board_config(struct hda_codec *codec, const struct hda_board_config *tbl)
 {
-	struct hda_board_config *c;
+	const struct hda_board_config *c;
 
 	if (codec->bus->modelname) {
-		for (c = tbl; c->modelname || c->pci_vendor; c++) {
+		for (c = tbl; c->modelname || c->pci_subvendor; c++) {
 			if (c->modelname &&
 			    ! strcmp(codec->bus->modelname, c->modelname)) {
 				snd_printd(KERN_INFO "hda_codec: model '%s' is selected\n", c->modelname);
@@ -1543,9 +1538,10 @@ int snd_hda_check_board_config(struct hd
 		u16 subsystem_vendor, subsystem_device;
 		pci_read_config_word(codec->bus->pci, PCI_SUBSYSTEM_VENDOR_ID, &subsystem_vendor);
 		pci_read_config_word(codec->bus->pci, PCI_SUBSYSTEM_ID, &subsystem_device);
-		for (c = tbl; c->modelname || c->pci_vendor; c++) {
-			if (c->pci_vendor == subsystem_vendor &&
-			    c->pci_device == subsystem_device)
+		for (c = tbl; c->modelname || c->pci_subvendor; c++) {
+			if (c->pci_subvendor == subsystem_vendor &&
+			    (! c->pci_subdevice /* all match */||
+			     (c->pci_subdevice == subsystem_device)))
 				return c->config;
 		}
 	}
@@ -1687,11 +1683,12 @@ int snd_hda_multi_out_analog_prepare(str
 		snd_hda_codec_setup_stream(codec, mout->hp_nid, stream_tag, 0, format);
 	/* surrounds */
 	for (i = 1; i < mout->num_dacs; i++) {
-		if (i == HDA_REAR && chs == 2) /* copy front to rear */
-			snd_hda_codec_setup_stream(codec, nids[i], stream_tag, 0, format);
-		else if (chs >= (i + 1) * 2) /* independent out */
+		if (chs >= (i + 1) * 2) /* independent out */
 			snd_hda_codec_setup_stream(codec, nids[i], stream_tag, i * 2,
 						   format);
+		else /* copy front */
+			snd_hda_codec_setup_stream(codec, nids[i], stream_tag, 0,
+						   format);
 	}
 	return 0;
 }
@@ -1717,6 +1714,105 @@ int snd_hda_multi_out_analog_cleanup(str
 	return 0;
 }
 
+/*
+ * Helper for automatic ping configuration
+ */
+/* parse all pin widgets and store the useful pin nids to cfg */
+int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *cfg)
+{
+	hda_nid_t nid, nid_start;
+	int i, j, nodes;
+	short seq, sequences[4], assoc_line_out;
+
+	memset(cfg, 0, sizeof(*cfg));
+
+	memset(sequences, 0, sizeof(sequences));
+	assoc_line_out = 0;
+
+	nodes = snd_hda_get_sub_nodes(codec, codec->afg, &nid_start);
+	for (nid = nid_start; nid < nodes + nid_start; nid++) {
+		unsigned int wid_caps = snd_hda_param_read(codec, nid,
+							   AC_PAR_AUDIO_WIDGET_CAP);
+		unsigned int wid_type = (wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
+		unsigned int def_conf;
+		short assoc, loc;
+
+		/* read all default configuration for pin complex */
+		if (wid_type != AC_WID_PIN)
+			continue;
+		def_conf = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONFIG_DEFAULT, 0);
+		if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE)
+			continue;
+		loc = get_defcfg_location(def_conf);
+		switch (get_defcfg_device(def_conf)) {
+		case AC_JACK_LINE_OUT:
+		case AC_JACK_SPEAKER:
+			seq = get_defcfg_sequence(def_conf);
+			assoc = get_defcfg_association(def_conf);
+			if (! assoc)
+				continue;
+			if (! assoc_line_out)
+				assoc_line_out = assoc;
+			else if (assoc_line_out != assoc)
+				continue;
+			if (cfg->line_outs >= ARRAY_SIZE(cfg->line_out_pins))
+				continue;
+			cfg->line_out_pins[cfg->line_outs] = nid;
+			sequences[cfg->line_outs] = seq;
+			cfg->line_outs++;
+			break;
+		case AC_JACK_HP_OUT:
+			cfg->hp_pin = nid;
+			break;
+		case AC_JACK_MIC_IN:
+			if (loc == AC_JACK_LOC_FRONT)
+				cfg->input_pins[AUTO_PIN_FRONT_MIC] = nid;
+			else
+				cfg->input_pins[AUTO_PIN_MIC] = nid;
+			break;
+		case AC_JACK_LINE_IN:
+			if (loc == AC_JACK_LOC_FRONT)
+				cfg->input_pins[AUTO_PIN_FRONT_LINE] = nid;
+			else
+				cfg->input_pins[AUTO_PIN_LINE] = nid;
+			break;
+		case AC_JACK_CD:
+			cfg->input_pins[AUTO_PIN_CD] = nid;
+			break;
+		case AC_JACK_AUX:
+			cfg->input_pins[AUTO_PIN_AUX] = nid;
+			break;
+		case AC_JACK_SPDIF_OUT:
+			cfg->dig_out_pin = nid;
+			break;
+		case AC_JACK_SPDIF_IN:
+			cfg->dig_in_pin = nid;
+			break;
+		}
+	}
+
+	/* sort by sequence */
+	for (i = 0; i < cfg->line_outs; i++)
+		for (j = i + 1; j < cfg->line_outs; j++)
+			if (sequences[i] > sequences[j]) {
+				seq = sequences[i];
+				sequences[i] = sequences[j];
+				sequences[j] = seq;
+				nid = cfg->line_out_pins[i];
+				cfg->line_out_pins[i] = cfg->line_out_pins[j];
+				cfg->line_out_pins[j] = nid;
+			}
+
+	/* Swap surround and CLFE: the association order is front/CLFE/surr/back */
+	if (cfg->line_outs >= 3) {
+		nid = cfg->line_out_pins[1];
+		cfg->line_out_pins[1] = cfg->line_out_pins[2];
+		cfg->line_out_pins[2] = nid;
+	}
+
+	return 0;
+}
+
 #ifdef CONFIG_PM
 /*
  * power management
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -75,6 +75,9 @@ enum {
 #define AC_VERB_GET_DIGI_CONVERT		0x0f0d
 #define AC_VERB_GET_VOLUME_KNOB_CONTROL		0x0f0f
 /* f10-f1a: GPIO */
+#define AC_VERB_GET_GPIO_DATA			0x0f15
+#define AC_VERB_GET_GPIO_MASK			0x0f16
+#define AC_VERB_GET_GPIO_DIRECTION		0x0f17
 #define AC_VERB_GET_CONFIG_DEFAULT		0x0f1c
 
 /*
@@ -97,6 +100,9 @@ enum {
 #define AC_VERB_SET_DIGI_CONVERT_1		0x70d
 #define AC_VERB_SET_DIGI_CONVERT_2		0x70e
 #define AC_VERB_SET_VOLUME_KNOB_CONTROL		0x70f
+#define AC_VERB_SET_GPIO_DATA			0x715
+#define AC_VERB_SET_GPIO_MASK			0x716
+#define AC_VERB_SET_GPIO_DIRECTION		0x717
 #define AC_VERB_SET_CONFIG_DEFAULT_BYTES_0	0x71c
 #define AC_VERB_SET_CONFIG_DEFAULT_BYTES_1	0x71d
 #define AC_VERB_SET_CONFIG_DEFAULT_BYTES_2	0x71e
@@ -176,16 +182,15 @@ enum {
 #define AC_PINCAP_OUT			(1<<4)	/* output capable */
 #define AC_PINCAP_IN			(1<<5)	/* input capable */
 #define AC_PINCAP_BALANCE		(1<<6)	/* balanced I/O capable */
-#define AC_PINCAP_VREF			(7<<8)
+#define AC_PINCAP_VREF			(0x37<<8)
 #define AC_PINCAP_VREF_SHIFT		8
 #define AC_PINCAP_EAPD			(1<<16)	/* EAPD capable */
-/* Vref status (used in pin cap and pin ctl) */
-#define AC_PIN_VREF_HIZ			(1<<0)	/* Hi-Z */
-#define AC_PIN_VREF_50			(1<<1)	/* 50% */
-#define AC_PIN_VREF_GRD			(1<<2)	/* ground */
-#define AC_PIN_VREF_80			(1<<4)	/* 80% */
-#define AC_PIN_VREF_100			(1<<5)	/* 100% */
-
+/* Vref status (used in pin cap) */
+#define AC_PINCAP_VREF_HIZ		(1<<0)	/* Hi-Z */
+#define AC_PINCAP_VREF_50		(1<<1)	/* 50% */
+#define AC_PINCAP_VREF_GRD		(1<<2)	/* ground */
+#define AC_PINCAP_VREF_80		(1<<4)	/* 80% */
+#define AC_PINCAP_VREF_100		(1<<5)	/* 100% */
 
 /* Amplifier capabilities */
 #define AC_AMPCAP_OFFSET		(0x7f<<0)  /* 0dB offset */
@@ -248,14 +253,24 @@ enum {
 
 /* Pin widget control - 8bit */
 #define AC_PINCTL_VREFEN		(0x7<<0)
+#define AC_PINCTL_VREF_HIZ		0	/* Hi-Z */
+#define AC_PINCTL_VREF_50		1	/* 50% */
+#define AC_PINCTL_VREF_GRD		2	/* ground */
+#define AC_PINCTL_VREF_80		4	/* 80% */
+#define AC_PINCTL_VREF_100		5	/* 100% */
 #define AC_PINCTL_IN_EN			(1<<5)
 #define AC_PINCTL_OUT_EN		(1<<6)
 #define AC_PINCTL_HP_EN			(1<<7)
 
+/* Unsolicited response - 8bit */
+#define AC_USRSP_EN			(1<<7)
+
 /* configuration default - 32bit */
 #define AC_DEFCFG_SEQUENCE		(0xf<<0)
 #define AC_DEFCFG_DEF_ASSOC		(0xf<<4)
+#define AC_DEFCFG_ASSOC_SHIFT		4
 #define AC_DEFCFG_MISC			(0xf<<8)
+#define AC_DEFCFG_MISC_SHIFT		8
 #define AC_DEFCFG_COLOR			(0xf<<12)
 #define AC_DEFCFG_COLOR_SHIFT		12
 #define AC_DEFCFG_CONN_TYPE		(0xf<<16)
@@ -413,7 +428,7 @@ struct hda_bus {
 
 	/* codec linked list */
 	struct list_head codec_list;
-	struct hda_codec *caddr_tbl[HDA_MAX_CODEC_ADDRESS]; /* caddr -> codec */
+	struct hda_codec *caddr_tbl[HDA_MAX_CODEC_ADDRESS + 1]; /* caddr -> codec */
 
 	struct semaphore cmd_mutex;
 
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
--- a/sound/pci/hda/hda_generic.c
+++ b/sound/pci/hda/hda_generic.c
@@ -44,7 +44,7 @@ struct hda_gnode {
 	struct list_head list;
 };
 
-/* pathc-specific record */
+/* patch-specific record */
 struct hda_gspec {
 	struct hda_gnode *dac_node;	/* DAC node */
 	struct hda_gnode *out_pin_node;	/* Output pin (Line-Out) node */
@@ -68,8 +68,8 @@ struct hda_gspec {
 /*
  * retrieve the default device type from the default config value
  */
-#define get_defcfg_type(node) (((node)->def_cfg & AC_DEFCFG_DEVICE) >> AC_DEFCFG_DEVICE_SHIFT)
-#define get_defcfg_location(node) (((node)->def_cfg & AC_DEFCFG_LOCATION) >> AC_DEFCFG_LOCATION_SHIFT)
+#define defcfg_type(node) (((node)->def_cfg & AC_DEFCFG_DEVICE) >> AC_DEFCFG_DEVICE_SHIFT)
+#define defcfg_location(node) (((node)->def_cfg & AC_DEFCFG_LOCATION) >> AC_DEFCFG_LOCATION_SHIFT)
 
 /*
  * destructor
@@ -323,7 +323,7 @@ static struct hda_gnode *parse_output_ja
 		if (! (node->pin_caps & AC_PINCAP_OUT))
 			continue;
 		if (jack_type >= 0) {
-			if (jack_type != get_defcfg_type(node))
+			if (jack_type != defcfg_type(node))
 				continue;
 			if (node->wid_caps & AC_WCAP_DIGITAL)
 				continue; /* skip SPDIF */
@@ -418,15 +418,15 @@ static int capture_source_put(snd_kcontr
  */
 static const char *get_input_type(struct hda_gnode *node, unsigned int *pinctl)
 {
-	unsigned int location = get_defcfg_location(node);
-	switch (get_defcfg_type(node)) {
+	unsigned int location = defcfg_location(node);
+	switch (defcfg_type(node)) {
 	case AC_JACK_LINE_IN:
 		if ((location & 0x0f) == AC_JACK_LOC_FRONT)
 			return "Front Line";
 		return "Line";
 	case AC_JACK_CD:
 		if (pinctl)
-			*pinctl |= AC_PIN_VREF_GRD;
+			*pinctl |= AC_PINCTL_VREF_GRD;
 		return "CD";
 	case AC_JACK_AUX:
 		if ((location & 0x0f) == AC_JACK_LOC_FRONT)
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -51,6 +51,7 @@ static int index[SNDRV_CARDS] = SNDRV_DE
 static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
 static char *model[SNDRV_CARDS];
+static int position_fix[SNDRV_CARDS];
 
 module_param_array(index, int, NULL, 0444);
 MODULE_PARM_DESC(index, "Index value for Intel HD audio interface.");
@@ -60,12 +61,17 @@ module_param_array(enable, bool, NULL, 0
 MODULE_PARM_DESC(enable, "Enable Intel HD audio interface.");
 module_param_array(model, charp, NULL, 0444);
 MODULE_PARM_DESC(model, "Use the given board model.");
+module_param_array(position_fix, int, NULL, 0444);
+MODULE_PARM_DESC(position_fix, "Fix DMA pointer (0 = FIFO size, 1 = none, 2 = POSBUF).");
 
 MODULE_LICENSE("GPL");
 MODULE_SUPPORTED_DEVICE("{{Intel, ICH6},"
 			 "{Intel, ICH6M},"
 			 "{Intel, ICH7},"
-			 "{Intel, ESB2}}");
+			 "{Intel, ESB2},"
+			 "{ATI, SB450},"
+			 "{VIA, VT8251},"
+			 "{VIA, VT8237A}}");
 MODULE_DESCRIPTION("Intel HDA driver");
 
 #define SFX	"hda-intel: "
@@ -150,7 +156,7 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO
 
 /* STATESTS int mask: SD2,SD1,SD0 */
 #define STATESTS_INT_MASK	0x07
-#define AZX_MAX_CODECS		3
+#define AZX_MAX_CODECS		4
 
 /* SD_CTL bits */
 #define SD_CTL_STREAM_RESET	0x01	/* stream reset bit */
@@ -172,6 +178,9 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO
 #define ICH6_INT_CTRL_EN	0x40000000	/* controller interrupt enable bit */
 #define ICH6_INT_GLOBAL_EN	0x80000000	/* global interrupt enable bit */
 
+/* GCTL unsolicited response enable bit */
+#define ICH6_GCTL_UREN		(1<<8)
+
 /* GCTL reset bit */
 #define ICH6_GCTL_RESET		(1<<0)
 
@@ -183,6 +192,18 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO
 #define ICH6_MAX_CORB_ENTRIES	256
 #define ICH6_MAX_RIRB_ENTRIES	256
 
+/* position fix mode */
+enum {
+	POS_FIX_FIFO,
+	POS_FIX_NONE,
+	POS_FIX_POSBUF
+};
+
+/* Defines for ATI HD Audio support in SB450 south bridge */
+#define ATI_SB450_HDAUDIO_PCI_DEVICE_ID     0x437b
+#define ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR   0x42
+#define ATI_SB450_HDAUDIO_ENABLE_SNOOP      0x02
+
 
 /*
  * Use CORB/RIRB for communication from/to codecs.
@@ -191,12 +212,6 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO
 #define USE_CORB_RIRB
 
 /*
- * Define this if use the position buffer instead of reading SD_LPIB
- * It's not used as default since SD_LPIB seems to give more accurate position
- */
-/* #define USE_POSBUF */
-
-/*
  */
 
 typedef struct snd_azx azx_t;
@@ -271,6 +286,10 @@ struct snd_azx {
 	struct snd_dma_buffer bdl;
 	struct snd_dma_buffer rb;
 	struct snd_dma_buffer posbuf;
+
+	/* flags */
+	int position_fix;
+	unsigned int initialized: 1;
 };
 
 /*
@@ -546,6 +565,9 @@ static int azx_reset(azx_t *chip)
 		return -EBUSY;
 	}
 
+	/* Accept unsolicited responses */
+	azx_writel(chip, GCTL, azx_readl(chip, GCTL) | ICH6_GCTL_UREN);
+
 	/* detect codecs */
 	if (! chip->codec_mask) {
 		chip->codec_mask = azx_readw(chip, STATESTS);
@@ -638,7 +660,7 @@ static void azx_stream_stop(azx_t *chip,
  */
 static void azx_init_chip(azx_t *chip)
 {
-	unsigned char tcsel_reg;
+	unsigned char tcsel_reg, ati_misc_cntl2;
 
 	/* Clear bits 0-2 of PCI register TCSEL (at offset 0x44)
 	 * TCSEL == Traffic Class Select Register, which sets PCI express QOS
@@ -657,11 +679,20 @@ static void azx_init_chip(azx_t *chip)
 	/* initialize the codec command I/O */
 	azx_init_cmd_io(chip);
 
-#ifdef USE_POSBUF
-	/* program the position buffer */
-	azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr);
-	azx_writel(chip, DPUBASE, upper_32bit(chip->posbuf.addr));
-#endif
+	if (chip->position_fix == POS_FIX_POSBUF) {
+		/* program the position buffer */
+		azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr);
+		azx_writel(chip, DPUBASE, upper_32bit(chip->posbuf.addr));
+	}
+
+	/* For ATI SB450 azalia HD audio, we need to enable snoop */
+	if (chip->pci->vendor == PCI_VENDOR_ID_ATI && 
+	    chip->pci->device == ATI_SB450_HDAUDIO_PCI_DEVICE_ID) {
+		pci_read_config_byte(chip->pci, ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR, 
+				     &ati_misc_cntl2);
+		pci_write_config_byte(chip->pci, ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR, 
+				      (ati_misc_cntl2 & 0xf8) | ATI_SB450_HDAUDIO_ENABLE_SNOOP);
+	}
 }
 
 
@@ -791,11 +822,12 @@ static int azx_setup_controller(azx_t *c
 	/* upper BDL address */
 	azx_sd_writel(azx_dev, SD_BDLPU, upper_32bit(azx_dev->bdl_addr));
 
-#ifdef USE_POSBUF
-	/* enable the position buffer */
-	if (! (azx_readl(chip, DPLBASE) & ICH6_DPLBASE_ENABLE))
-		azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr | ICH6_DPLBASE_ENABLE);
-#endif
+	if (chip->position_fix == POS_FIX_POSBUF) {
+		/* enable the position buffer */
+		if (! (azx_readl(chip, DPLBASE) & ICH6_DPLBASE_ENABLE))
+			azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr | ICH6_DPLBASE_ENABLE);
+	}
+
 	/* set the interrupt enable bits in the descriptor control register */
 	azx_sd_writel(azx_dev, SD_CTL, azx_sd_readl(azx_dev, SD_CTL) | SD_INT_MASK);
 
@@ -1036,16 +1068,20 @@ static int azx_pcm_trigger(snd_pcm_subst
 
 static snd_pcm_uframes_t azx_pcm_pointer(snd_pcm_substream_t *substream)
 {
+	struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
+	azx_t *chip = apcm->chip;
 	azx_dev_t *azx_dev = get_azx_dev(substream);
 	unsigned int pos;
 
-#ifdef USE_POSBUF
-	/* use the position buffer */
-	pos = *azx_dev->posbuf;
-#else
-	/* read LPIB */
-	pos = azx_sd_readl(azx_dev, SD_LPIB) + azx_dev->fifo_size;
-#endif
+	if (chip->position_fix == POS_FIX_POSBUF) {
+		/* use the position buffer */
+		pos = *azx_dev->posbuf;
+	} else {
+		/* read LPIB */
+		pos = azx_sd_readl(azx_dev, SD_LPIB);
+		if (chip->position_fix == POS_FIX_FIFO)
+			pos += azx_dev->fifo_size;
+	}
 	if (pos >= azx_dev->bufsize)
 		pos = 0;
 	return bytes_to_frames(substream->runtime, pos);
@@ -1155,9 +1191,8 @@ static int __devinit azx_init_stream(azx
 		azx_dev_t *azx_dev = &chip->azx_dev[i];
 		azx_dev->bdl = (u32 *)(chip->bdl.area + off);
 		azx_dev->bdl_addr = chip->bdl.addr + off;
-#ifdef USE_POSBUF
-		azx_dev->posbuf = (volatile u32 *)(chip->posbuf.area + i * 8);
-#endif
+		if (chip->position_fix == POS_FIX_POSBUF)
+			azx_dev->posbuf = (volatile u32 *)(chip->posbuf.area + i * 8);
 		/* offset: SDI0=0x80, SDI1=0xa0, ... SDO3=0x160 */
 		azx_dev->sd_addr = chip->remap_addr + (0x20 * i + 0x80);
 		/* int mask: SDI0=0x01, SDI1=0x02, ... SDO3=0x80 */
@@ -1207,7 +1242,7 @@ static int azx_resume(snd_card_t *card)
  */
 static int azx_free(azx_t *chip)
 {
-	if (chip->remap_addr) {
+	if (chip->initialized) {
 		int i;
 
 		for (i = 0; i < MAX_ICH6_DEV; i++)
@@ -1237,10 +1272,8 @@ static int azx_free(azx_t *chip)
 		snd_dma_free_pages(&chip->bdl);
 	if (chip->rb.area)
 		snd_dma_free_pages(&chip->rb);
-#ifdef USE_POSBUF
 	if (chip->posbuf.area)
 		snd_dma_free_pages(&chip->posbuf);
-#endif
 	pci_release_regions(chip->pci);
 	pci_disable_device(chip->pci);
 	kfree(chip);
@@ -1256,7 +1289,8 @@ static int azx_dev_free(snd_device_t *de
 /*
  * constructor
  */
-static int __devinit azx_create(snd_card_t *card, struct pci_dev *pci, azx_t **rchip)
+static int __devinit azx_create(snd_card_t *card, struct pci_dev *pci,
+				int posfix, azx_t **rchip)
 {
 	azx_t *chip;
 	int err = 0;
@@ -1283,6 +1317,8 @@ static int __devinit azx_create(snd_card
 	chip->pci = pci;
 	chip->irq = -1;
 
+	chip->position_fix = posfix;
+
 	if ((err = pci_request_regions(pci, "ICH HD audio")) < 0) {
 		kfree(chip);
 		pci_disable_device(pci);
@@ -1314,14 +1350,14 @@ static int __devinit azx_create(snd_card
 		snd_printk(KERN_ERR SFX "cannot allocate BDL\n");
 		goto errout;
 	}
-#ifdef USE_POSBUF
-	/* allocate memory for the position buffer */
-	if ((err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci),
-				       MAX_ICH6_DEV * 8, &chip->posbuf)) < 0) {
-		snd_printk(KERN_ERR SFX "cannot allocate posbuf\n");
-		goto errout;
+	if (chip->position_fix == POS_FIX_POSBUF) {
+		/* allocate memory for the position buffer */
+		if ((err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci),
+					       MAX_ICH6_DEV * 8, &chip->posbuf)) < 0) {
+			snd_printk(KERN_ERR SFX "cannot allocate posbuf\n");
+			goto errout;
+		}
 	}
-#endif
 	/* allocate CORB/RIRB */
 	if ((err = azx_alloc_cmd_io(chip)) < 0)
 		goto errout;
@@ -1332,6 +1368,8 @@ static int __devinit azx_create(snd_card
 	/* initialize chip */
 	azx_init_chip(chip);
 
+	chip->initialized = 1;
+
 	/* codec detection */
 	if (! chip->codec_mask) {
 		snd_printk(KERN_ERR SFX "no codecs found!\n");
@@ -1372,7 +1410,7 @@ static int __devinit azx_probe(struct pc
 		return -ENOMEM;
 	}
 
-	if ((err = azx_create(card, pci, &chip)) < 0) {
+	if ((err = azx_create(card, pci, position_fix[dev], &chip)) < 0) {
 		snd_card_free(card);
 		return err;
 	}
@@ -1424,6 +1462,9 @@ static struct pci_device_id azx_ids[] = 
 	{ 0x8086, 0x2668, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* ICH6 */
 	{ 0x8086, 0x27d8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* ICH7 */
 	{ 0x8086, 0x269a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* ESB2 */
+	{ 0x1002, 0x437b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* ATI SB450 */
+	{ 0x1106, 0x3288, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* VIA VT8251/VT8237A */
+	{ 0x10b9, 0x5461, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* ALI 5461? */
 	{ 0, }
 };
 MODULE_DEVICE_TABLE(pci, azx_ids);
@@ -1439,7 +1480,7 @@ static struct pci_driver driver = {
 
 static int __init alsa_card_azx_init(void)
 {
-	return pci_module_init(&driver);
+	return pci_register_driver(&driver);
 }
 
 static void __exit alsa_card_azx_exit(void)
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
--- a/sound/pci/hda/hda_local.h
+++ b/sound/pci/hda/hda_local.h
@@ -126,11 +126,11 @@ static inline int snd_hda_codec_proc_new
 struct hda_board_config {
 	const char *modelname;
 	int config;
-	unsigned short pci_vendor;
-	unsigned short pci_device;
+	unsigned short pci_subvendor;
+	unsigned short pci_subdevice;
 };
 
-int snd_hda_check_board_config(struct hda_codec *codec, struct hda_board_config *tbl);
+int snd_hda_check_board_config(struct hda_codec *codec, const struct hda_board_config *tbl);
 int snd_hda_add_new_ctls(struct hda_codec *codec, snd_kcontrol_new_t *knew);
 
 /*
@@ -158,4 +158,35 @@ struct hda_bus_unsolicited {
 	struct work_struct work;
 };
 
+/*
+ * Helper for automatic ping configuration
+ */
+
+enum {
+	AUTO_PIN_MIC,
+	AUTO_PIN_FRONT_MIC,
+	AUTO_PIN_LINE,
+	AUTO_PIN_FRONT_LINE,
+	AUTO_PIN_CD,
+	AUTO_PIN_AUX,
+	AUTO_PIN_LAST
+};
+
+struct auto_pin_cfg {
+	int line_outs;
+	hda_nid_t line_out_pins[4]; /* sorted in the order of Front/Surr/CLFE/Side */
+	hda_nid_t hp_pin;
+	hda_nid_t input_pins[AUTO_PIN_LAST];
+	hda_nid_t dig_out_pin;
+	hda_nid_t dig_in_pin;
+};
+
+#define get_defcfg_connect(cfg) ((cfg & AC_DEFCFG_PORT_CONN) >> AC_DEFCFG_PORT_CONN_SHIFT)
+#define get_defcfg_association(cfg) ((cfg & AC_DEFCFG_DEF_ASSOC) >> AC_DEFCFG_ASSOC_SHIFT)
+#define get_defcfg_location(cfg) ((cfg & AC_DEFCFG_LOCATION) >> AC_DEFCFG_LOCATION_SHIFT)
+#define get_defcfg_sequence(cfg) (cfg & AC_DEFCFG_SEQUENCE)
+#define get_defcfg_device(cfg) ((cfg & AC_DEFCFG_DEVICE) >> AC_DEFCFG_DEVICE_SHIFT)
+
+int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *cfg);
+
 #endif /* __SOUND_HDA_LOCAL_H */
diff --git a/sound/pci/hda/hda_patch.h b/sound/pci/hda/hda_patch.h
--- a/sound/pci/hda/hda_patch.h
+++ b/sound/pci/hda/hda_patch.h
@@ -8,10 +8,13 @@ extern struct hda_codec_preset snd_hda_p
 extern struct hda_codec_preset snd_hda_preset_cmedia[];
 /* Analog Devices codecs */
 extern struct hda_codec_preset snd_hda_preset_analog[];
+/* SigmaTel codecs */
+extern struct hda_codec_preset snd_hda_preset_sigmatel[];
 
 static const struct hda_codec_preset *hda_preset_tables[] = {
 	snd_hda_preset_realtek,
 	snd_hda_preset_cmedia,
 	snd_hda_preset_analog,
+	snd_hda_preset_sigmatel,
 	NULL
 };
diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c
--- a/sound/pci/hda/hda_proc.c
+++ b/sound/pci/hda/hda_proc.c
@@ -68,21 +68,27 @@ static void print_amp_caps(snd_info_buff
 
 static void print_amp_vals(snd_info_buffer_t *buffer,
 			   struct hda_codec *codec, hda_nid_t nid,
-			   int dir, int stereo)
+			   int dir, int stereo, int indices)
 {
 	unsigned int val;
-	if (stereo) {
+	int i;
+
+	if (dir == HDA_OUTPUT)
+		dir = AC_AMP_GET_OUTPUT;
+	else
+		dir = AC_AMP_GET_INPUT;
+	for (i = 0; i < indices; i++) {
+		snd_iprintf(buffer, " [");
+		if (stereo) {
+			val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_AMP_GAIN_MUTE,
+						 AC_AMP_GET_LEFT | dir | i);
+			snd_iprintf(buffer, "0x%02x ", val);
+		}
 		val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_AMP_GAIN_MUTE,
-					  AC_AMP_GET_LEFT |
-					 (dir == HDA_OUTPUT ? AC_AMP_GET_OUTPUT :
-					  AC_AMP_GET_INPUT));
-		snd_iprintf(buffer, "0x%02x ", val);
+					 AC_AMP_GET_RIGHT | dir | i);
+		snd_iprintf(buffer, "0x%02x]", val);
 	}
-	val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_AMP_GAIN_MUTE,
-				 AC_AMP_GET_RIGHT |
-				 (dir == HDA_OUTPUT ? AC_AMP_GET_OUTPUT :
-				  AC_AMP_GET_INPUT));
-	snd_iprintf(buffer, "0x%02x\n", val);
+	snd_iprintf(buffer, "\n");
 }
 
 static void print_pcm_caps(snd_info_buffer_t *buffer,
@@ -157,6 +163,7 @@ static const char *get_jack_color(u32 cf
 static void print_pin_caps(snd_info_buffer_t *buffer,
 			   struct hda_codec *codec, hda_nid_t nid)
 {
+	static char *jack_conns[4] = { "Jack", "N/A", "Fixed", "Both" };
 	static char *jack_types[16] = {
 		"Line Out", "Speaker", "HP Out", "CD",
 		"SPDIF Out", "Digital Out", "Modem Line", "Modem Hand",
@@ -176,7 +183,8 @@ static void print_pin_caps(snd_info_buff
 		snd_iprintf(buffer, " HP");
 	snd_iprintf(buffer, "\n");
 	caps = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONFIG_DEFAULT, 0);
-	snd_iprintf(buffer, "  Pin Default 0x%08x: %s at %s %s\n", caps,
+	snd_iprintf(buffer, "  Pin Default 0x%08x: [%s] %s at %s %s\n", caps,
+		    jack_conns[(caps & AC_DEFCFG_PORT_CONN) >> AC_DEFCFG_PORT_CONN_SHIFT],
 		    jack_types[(caps & AC_DEFCFG_DEVICE) >> AC_DEFCFG_DEVICE_SHIFT],
 		    jack_locations[(caps >> (AC_DEFCFG_LOCATION_SHIFT + 4)) & 3],
 		    get_jack_location(caps));
@@ -215,6 +223,9 @@ static void print_codec_info(snd_info_en
 		unsigned int wid_caps = snd_hda_param_read(codec, nid,
 							   AC_PAR_AUDIO_WIDGET_CAP);
 		unsigned int wid_type = (wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
+		int conn_len = 0; 
+		hda_nid_t conn[HDA_MAX_CONNECTIONS];
+
 		snd_iprintf(buffer, "Node 0x%02x [%s] wcaps 0x%x:", nid,
 			    get_wid_type_name(wid_type), wid_caps);
 		if (wid_caps & AC_WCAP_STEREO)
@@ -229,19 +240,23 @@ static void print_codec_info(snd_info_en
 			snd_iprintf(buffer, " Amp-Out");
 		snd_iprintf(buffer, "\n");
 
+		if (wid_caps & AC_WCAP_CONN_LIST)
+			conn_len = snd_hda_get_connections(codec, nid, conn,
+							   HDA_MAX_CONNECTIONS);
+
 		if (wid_caps & AC_WCAP_IN_AMP) {
 			snd_iprintf(buffer, "  Amp-In caps: ");
 			print_amp_caps(buffer, codec, nid, HDA_INPUT);
 			snd_iprintf(buffer, "  Amp-In vals: ");
 			print_amp_vals(buffer, codec, nid, HDA_INPUT,
-				       wid_caps & AC_WCAP_STEREO);
+				       wid_caps & AC_WCAP_STEREO, conn_len);
 		}
 		if (wid_caps & AC_WCAP_OUT_AMP) {
 			snd_iprintf(buffer, "  Amp-Out caps: ");
 			print_amp_caps(buffer, codec, nid, HDA_OUTPUT);
 			snd_iprintf(buffer, "  Amp-Out vals: ");
 			print_amp_vals(buffer, codec, nid, HDA_OUTPUT,
-				       wid_caps & AC_WCAP_STEREO);
+				       wid_caps & AC_WCAP_STEREO, 1);
 		}
 
 		if (wid_type == AC_WID_PIN) {
@@ -265,14 +280,17 @@ static void print_codec_info(snd_info_en
 		}
 
 		if (wid_caps & AC_WCAP_CONN_LIST) {
-			hda_nid_t conn[HDA_MAX_CONNECTIONS];
-			int c, conn_len;
-			conn_len = snd_hda_get_connections(codec, nid, conn,
-							   HDA_MAX_CONNECTIONS);
+			int c, curr = -1;
+			if (conn_len > 1 && wid_type != AC_WID_AUD_MIX)
+				curr = snd_hda_codec_read(codec, nid, 0,
+					AC_VERB_GET_CONNECT_SEL, 0);
 			snd_iprintf(buffer, "  Connection: %d\n", conn_len);
 			snd_iprintf(buffer, "    ");
-			for (c = 0; c < conn_len; c++)
+			for (c = 0; c < conn_len; c++) {
 				snd_iprintf(buffer, " 0x%02x", conn[c]);
+				if (c == curr)
+					snd_iprintf(buffer, "*");
+			}
 			snd_iprintf(buffer, "\n");
 		}
 	}
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -1,5 +1,5 @@
 /*
- * HD audio interface patch for AD1986A
+ * HD audio interface patch for AD1981HD, AD1983, AD1986A
  *
  * Copyright (c) 2005 Takashi Iwai <tiwai@suse.de>
  *
@@ -27,13 +27,239 @@
 #include "hda_codec.h"
 #include "hda_local.h"
 
-struct ad1986a_spec {
+struct ad198x_spec {
 	struct semaphore amp_mutex;	/* PCM volume/mute control mutex */
 	struct hda_multi_out multiout;	/* playback */
+	hda_nid_t adc_nid;
+	const struct hda_input_mux *input_mux;
 	unsigned int cur_mux;		/* capture source */
+	unsigned int spdif_route;
+	snd_kcontrol_new_t *mixers;
+	const struct hda_verb *init_verbs;
 	struct hda_pcm pcm_rec[2];	/* PCM information */
 };
 
+/*
+ * input MUX handling (common part)
+ */
+static int ad198x_mux_enum_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+{
+	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct ad198x_spec *spec = codec->spec;
+
+	return snd_hda_input_mux_info(spec->input_mux, uinfo);
+}
+
+static int ad198x_mux_enum_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct ad198x_spec *spec = codec->spec;
+
+	ucontrol->value.enumerated.item[0] = spec->cur_mux;
+	return 0;
+}
+
+static int ad198x_mux_enum_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct ad198x_spec *spec = codec->spec;
+
+	return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
+				     spec->adc_nid, &spec->cur_mux);
+}
+
+/*
+ * initialization (common callbacks)
+ */
+static int ad198x_init(struct hda_codec *codec)
+{
+	struct ad198x_spec *spec = codec->spec;
+	snd_hda_sequence_write(codec, spec->init_verbs);
+	return 0;
+}
+
+static int ad198x_build_controls(struct hda_codec *codec)
+{
+	struct ad198x_spec *spec = codec->spec;
+	int err;
+
+	err = snd_hda_add_new_ctls(codec, spec->mixers);
+	if (err < 0)
+		return err;
+	if (spec->multiout.dig_out_nid)
+		err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid);
+	if (err < 0)
+		return err;
+	return 0;
+}
+
+/*
+ * Analog playback callbacks
+ */
+static int ad198x_playback_pcm_open(struct hda_pcm_stream *hinfo,
+				    struct hda_codec *codec,
+				    snd_pcm_substream_t *substream)
+{
+	struct ad198x_spec *spec = codec->spec;
+	return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream);
+}
+
+static int ad198x_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
+				       struct hda_codec *codec,
+				       unsigned int stream_tag,
+				       unsigned int format,
+				       snd_pcm_substream_t *substream)
+{
+	struct ad198x_spec *spec = codec->spec;
+	return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag,
+						format, substream);
+}
+
+static int ad198x_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
+				       struct hda_codec *codec,
+				       snd_pcm_substream_t *substream)
+{
+	struct ad198x_spec *spec = codec->spec;
+	return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
+}
+
+/*
+ * Digital out
+ */
+static int ad198x_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
+					struct hda_codec *codec,
+					snd_pcm_substream_t *substream)
+{
+	struct ad198x_spec *spec = codec->spec;
+	return snd_hda_multi_out_dig_open(codec, &spec->multiout);
+}
+
+static int ad198x_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
+					 struct hda_codec *codec,
+					 snd_pcm_substream_t *substream)
+{
+	struct ad198x_spec *spec = codec->spec;
+	return snd_hda_multi_out_dig_close(codec, &spec->multiout);
+}
+
+/*
+ * Analog capture
+ */
+static int ad198x_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
+				      struct hda_codec *codec,
+				      unsigned int stream_tag,
+				      unsigned int format,
+				      snd_pcm_substream_t *substream)
+{
+	struct ad198x_spec *spec = codec->spec;
+	snd_hda_codec_setup_stream(codec, spec->adc_nid, stream_tag, 0, format);
+	return 0;
+}
+
+static int ad198x_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
+				      struct hda_codec *codec,
+				      snd_pcm_substream_t *substream)
+{
+	struct ad198x_spec *spec = codec->spec;
+	snd_hda_codec_setup_stream(codec, spec->adc_nid, 0, 0, 0);
+	return 0;
+}
+
+
+/*
+ */
+static struct hda_pcm_stream ad198x_pcm_analog_playback = {
+	.substreams = 1,
+	.channels_min = 2,
+	.channels_max = 6,
+	.nid = 0, /* fill later */
+	.ops = {
+		.open = ad198x_playback_pcm_open,
+		.prepare = ad198x_playback_pcm_prepare,
+		.cleanup = ad198x_playback_pcm_cleanup
+	},
+};
+
+static struct hda_pcm_stream ad198x_pcm_analog_capture = {
+	.substreams = 2,
+	.channels_min = 2,
+	.channels_max = 2,
+	.nid = 0, /* fill later */
+	.ops = {
+		.prepare = ad198x_capture_pcm_prepare,
+		.cleanup = ad198x_capture_pcm_cleanup
+	},
+};
+
+static struct hda_pcm_stream ad198x_pcm_digital_playback = {
+	.substreams = 1,
+	.channels_min = 2,
+	.channels_max = 2,
+	.nid = 0, /* fill later */
+	.ops = {
+		.open = ad198x_dig_playback_pcm_open,
+		.close = ad198x_dig_playback_pcm_close
+	},
+};
+
+static int ad198x_build_pcms(struct hda_codec *codec)
+{
+	struct ad198x_spec *spec = codec->spec;
+	struct hda_pcm *info = spec->pcm_rec;
+
+	codec->num_pcms = 1;
+	codec->pcm_info = info;
+
+	info->name = "AD198x Analog";
+	info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ad198x_pcm_analog_playback;
+	info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->multiout.max_channels;
+	info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
+	info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad198x_pcm_analog_capture;
+	info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nid;
+
+	if (spec->multiout.dig_out_nid) {
+		info++;
+		codec->num_pcms++;
+		info->name = "AD198x Digital";
+		info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ad198x_pcm_digital_playback;
+		info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
+	}
+
+	return 0;
+}
+
+static void ad198x_free(struct hda_codec *codec)
+{
+	kfree(codec->spec);
+}
+
+#ifdef CONFIG_PM
+static int ad198x_resume(struct hda_codec *codec)
+{
+	struct ad198x_spec *spec = codec->spec;
+
+	ad198x_init(codec);
+	snd_hda_resume_ctls(codec, spec->mixers);
+	snd_hda_resume_spdif_out(codec);
+	return 0;
+}
+#endif
+
+static struct hda_codec_ops ad198x_patch_ops = {
+	.build_controls = ad198x_build_controls,
+	.build_pcms = ad198x_build_pcms,
+	.init = ad198x_init,
+	.free = ad198x_free,
+#ifdef CONFIG_PM
+	.resume = ad198x_resume,
+#endif
+};
+
+
+/*
+ * AD1986A specific
+ */
+
 #define AD1986A_SPDIF_OUT	0x02
 #define AD1986A_FRONT_DAC	0x03
 #define AD1986A_SURR_DAC	0x04
@@ -68,7 +294,7 @@ static struct hda_input_mux ad1986a_capt
 static int ad1986a_pcm_amp_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
-	struct ad1986a_spec *ad = codec->spec;
+	struct ad198x_spec *ad = codec->spec;
 
 	down(&ad->amp_mutex);
 	snd_hda_mixer_amp_volume_get(kcontrol, ucontrol);
@@ -79,7 +305,7 @@ static int ad1986a_pcm_amp_vol_get(snd_k
 static int ad1986a_pcm_amp_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
-	struct ad1986a_spec *ad = codec->spec;
+	struct ad198x_spec *ad = codec->spec;
 	int i, change = 0;
 
 	down(&ad->amp_mutex);
@@ -92,12 +318,12 @@ static int ad1986a_pcm_amp_vol_put(snd_k
 	return change;
 }
 
-#define ad1986a_pcm_amp_sw_info		snd_hda_mixer_amp_volume_info
+#define ad1986a_pcm_amp_sw_info		snd_hda_mixer_amp_switch_info
 
 static int ad1986a_pcm_amp_sw_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
-	struct ad1986a_spec *ad = codec->spec;
+	struct ad198x_spec *ad = codec->spec;
 
 	down(&ad->amp_mutex);
 	snd_hda_mixer_amp_switch_get(kcontrol, ucontrol);
@@ -108,7 +334,7 @@ static int ad1986a_pcm_amp_sw_get(snd_kc
 static int ad1986a_pcm_amp_sw_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
-	struct ad1986a_spec *ad = codec->spec;
+	struct ad198x_spec *ad = codec->spec;
 	int i, change = 0;
 
 	down(&ad->amp_mutex);
@@ -122,32 +348,6 @@ static int ad1986a_pcm_amp_sw_put(snd_kc
 }
 
 /*
- * input MUX handling
- */
-static int ad1986a_mux_enum_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
-{
-	return snd_hda_input_mux_info(&ad1986a_capture_source, uinfo);
-}
-
-static int ad1986a_mux_enum_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
-{
-	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
-	struct ad1986a_spec *spec = codec->spec;
-
-	ucontrol->value.enumerated.item[0] = spec->cur_mux;
-	return 0;
-}
-
-static int ad1986a_mux_enum_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
-{
-	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
-	struct ad1986a_spec *spec = codec->spec;
-
-	return snd_hda_input_mux_put(codec, &ad1986a_capture_source, ucontrol,
-				     AD1986A_ADC, &spec->cur_mux);
-}
-
-/*
  * mixers
  */
 static snd_kcontrol_new_t ad1986a_mixers[] = {
@@ -194,9 +394,9 @@ static snd_kcontrol_new_t ad1986a_mixers
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name = "Capture Source",
-		.info = ad1986a_mux_enum_info,
-		.get = ad1986a_mux_enum_get,
-		.put = ad1986a_mux_enum_put,
+		.info = ad198x_mux_enum_info,
+		.get = ad198x_mux_enum_get,
+		.put = ad198x_mux_enum_put,
 	},
 	HDA_CODEC_MUTE("Stereo Downmix Switch", 0x09, 0x0, HDA_OUTPUT),
 	{ } /* end */
@@ -241,183 +441,328 @@ static struct hda_verb ad1986a_init_verb
 	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
 	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
 	{0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
+	/* HP Pin */
+	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
+	/* Front, Surround, CLFE Pins */
+	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
+	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
+	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
+	/* Mono Pin */
+	{0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
+	/* Mic Pin */
+	{0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
+	/* Line, Aux, CD, Beep-In Pin */
+	{0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
+	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
+	{0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
+	{0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
+	{0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
 	{ } /* end */
 };
 
 
-static int ad1986a_init(struct hda_codec *codec)
+static int patch_ad1986a(struct hda_codec *codec)
 {
-	snd_hda_sequence_write(codec, ad1986a_init_verbs);
-	return 0;
-}
+	struct ad198x_spec *spec;
 
-static int ad1986a_build_controls(struct hda_codec *codec)
-{
-	int err;
+	spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
+	if (spec == NULL)
+		return -ENOMEM;
+
+	init_MUTEX(&spec->amp_mutex);
+	codec->spec = spec;
+
+	spec->multiout.max_channels = 6;
+	spec->multiout.num_dacs = ARRAY_SIZE(ad1986a_dac_nids);
+	spec->multiout.dac_nids = ad1986a_dac_nids;
+	spec->multiout.dig_out_nid = AD1986A_SPDIF_OUT;
+	spec->adc_nid = AD1986A_ADC;
+	spec->input_mux = &ad1986a_capture_source;
+	spec->mixers = ad1986a_mixers;
+	spec->init_verbs = ad1986a_init_verbs;
+
+	codec->patch_ops = ad198x_patch_ops;
 
-	err = snd_hda_add_new_ctls(codec, ad1986a_mixers);
-	if (err < 0)
-		return err;
-	err = snd_hda_create_spdif_out_ctls(codec, AD1986A_SPDIF_OUT);
-	if (err < 0)
-		return err;
 	return 0;
 }
 
 /*
- * Analog playback callbacks
+ * AD1983 specific
  */
-static int ad1986a_playback_pcm_open(struct hda_pcm_stream *hinfo,
-				     struct hda_codec *codec,
-				     snd_pcm_substream_t *substream)
-{
-	struct ad1986a_spec *spec = codec->spec;
-	return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream);
-}
 
-static int ad1986a_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
-					struct hda_codec *codec,
-					unsigned int stream_tag,
-					unsigned int format,
-					snd_pcm_substream_t *substream)
-{
-	struct ad1986a_spec *spec = codec->spec;
-	return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag,
-						format, substream);
-}
+#define AD1983_SPDIF_OUT	0x02
+#define AD1983_DAC		0x03
+#define AD1983_ADC		0x04
 
-static int ad1986a_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
-					struct hda_codec *codec,
-					snd_pcm_substream_t *substream)
-{
-	struct ad1986a_spec *spec = codec->spec;
-	return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
-}
+static hda_nid_t ad1983_dac_nids[1] = { AD1983_DAC };
+
+static struct hda_input_mux ad1983_capture_source = {
+	.num_items = 4,
+	.items = {
+		{ "Mic", 0x0 },
+		{ "Line", 0x1 },
+		{ "Mix", 0x2 },
+		{ "Mix Mono", 0x3 },
+	},
+};
 
 /*
- * Digital out
+ * SPDIF playback route
  */
-static int ad1986a_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
-					 struct hda_codec *codec,
-					 snd_pcm_substream_t *substream)
+static int ad1983_spdif_route_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
 {
-	struct ad1986a_spec *spec = codec->spec;
-	return snd_hda_multi_out_dig_open(codec, &spec->multiout);
-}
+	static char *texts[] = { "PCM", "ADC" };
 
-static int ad1986a_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
-					  struct hda_codec *codec,
-					  snd_pcm_substream_t *substream)
-{
-	struct ad1986a_spec *spec = codec->spec;
-	return snd_hda_multi_out_dig_close(codec, &spec->multiout);
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+	uinfo->count = 1;
+	uinfo->value.enumerated.items = 2;
+	if (uinfo->value.enumerated.item > 1)
+		uinfo->value.enumerated.item = 1;
+	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
+	return 0;
 }
 
-/*
- * Analog capture
- */
-static int ad1986a_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
-				       struct hda_codec *codec,
-				       unsigned int stream_tag,
-				       unsigned int format,
-				       snd_pcm_substream_t *substream)
+static int ad1983_spdif_route_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
 {
-	snd_hda_codec_setup_stream(codec, AD1986A_ADC, stream_tag, 0, format);
+	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct ad198x_spec *spec = codec->spec;
+
+	ucontrol->value.enumerated.item[0] = spec->spdif_route;
 	return 0;
 }
 
-static int ad1986a_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
-				       struct hda_codec *codec,
-				       snd_pcm_substream_t *substream)
+static int ad1983_spdif_route_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
 {
-	snd_hda_codec_setup_stream(codec, AD1986A_ADC, 0, 0, 0);
+	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct ad198x_spec *spec = codec->spec;
+
+	if (spec->spdif_route != ucontrol->value.enumerated.item[0]) {
+		spec->spdif_route = ucontrol->value.enumerated.item[0];
+		snd_hda_codec_write(codec, spec->multiout.dig_out_nid, 0,
+				    AC_VERB_SET_CONNECT_SEL, spec->spdif_route);
+		return 1;
+	}
 	return 0;
 }
 
-
-/*
- */
-static struct hda_pcm_stream ad1986a_pcm_analog_playback = {
-	.substreams = 1,
-	.channels_min = 2,
-	.channels_max = 6,
-	.nid = AD1986A_FRONT_DAC, /* NID to query formats and rates */
-	.ops = {
-		.open = ad1986a_playback_pcm_open,
-		.prepare = ad1986a_playback_pcm_prepare,
-		.cleanup = ad1986a_playback_pcm_cleanup
+static snd_kcontrol_new_t ad1983_mixers[] = {
+	HDA_CODEC_VOLUME("Front Playback Volume", 0x05, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE("Front Playback Switch", 0x05, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x06, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE("Headphone Playback Switch", 0x06, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x07, 1, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x07, 1, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME("Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE("Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME("Line Playback Volume", 0x13, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE("Line Playback Switch", 0x13, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME_MONO("PC Speaker Playback Volume", 0x10, 1, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE_MONO("PC Speaker Playback Switch", 0x10, 1, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME("Mic Boost", 0x0c, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT),
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Capture Source",
+		.info = ad198x_mux_enum_info,
+		.get = ad198x_mux_enum_get,
+		.put = ad198x_mux_enum_put,
 	},
-};
-
-static struct hda_pcm_stream ad1986a_pcm_analog_capture = {
-	.substreams = 2,
-	.channels_min = 2,
-	.channels_max = 2,
-	.nid = AD1986A_ADC, /* NID to query formats and rates */
-	.ops = {
-		.prepare = ad1986a_capture_pcm_prepare,
-		.cleanup = ad1986a_capture_pcm_cleanup
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "IEC958 Playback Route",
+		.info = ad1983_spdif_route_info,
+		.get = ad1983_spdif_route_get,
+		.put = ad1983_spdif_route_put,
 	},
+	{ } /* end */
 };
 
-static struct hda_pcm_stream ad1986a_pcm_digital_playback = {
-	.substreams = 1,
-	.channels_min = 2,
-	.channels_max = 2,
-	.nid = AD1986A_SPDIF_OUT, 
-	.ops = {
-		.open = ad1986a_dig_playback_pcm_open,
-		.close = ad1986a_dig_playback_pcm_close
-	},
+static struct hda_verb ad1983_init_verbs[] = {
+	/* Front, HP, Mono; mute as default */
+	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
+	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
+	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
+	/* Beep, PCM, Mic, Line-In: mute */
+	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
+	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
+	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
+	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
+	/* Front, HP selectors; from Mix */
+	{0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
+	{0x06, AC_VERB_SET_CONNECT_SEL, 0x01},
+	/* Mono selector; from Mix */
+	{0x0b, AC_VERB_SET_CONNECT_SEL, 0x03},
+	/* Mic selector; Mic */
+	{0x0c, AC_VERB_SET_CONNECT_SEL, 0x0},
+	/* Line-in selector: Line-in */
+	{0x0d, AC_VERB_SET_CONNECT_SEL, 0x0},
+	/* Mic boost: 0dB */
+	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
+	/* Record selector: mic */
+	{0x15, AC_VERB_SET_CONNECT_SEL, 0x0},
+	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
+	/* SPDIF route: PCM */
+	{0x02, AC_VERB_SET_CONNECT_SEL, 0x0},
+	/* Front Pin */
+	{0x05, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
+	/* HP Pin */
+	{0x06, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
+	/* Mono Pin */
+	{0x07, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
+	/* Mic Pin */
+	{0x08, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
+	/* Line Pin */
+	{0x09, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
+	{ } /* end */
 };
 
-static int ad1986a_build_pcms(struct hda_codec *codec)
+static int patch_ad1983(struct hda_codec *codec)
 {
-	struct ad1986a_spec *spec = codec->spec;
-	struct hda_pcm *info = spec->pcm_rec;
+	struct ad198x_spec *spec;
 
-	codec->num_pcms = 2;
-	codec->pcm_info = info;
+	spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
+	if (spec == NULL)
+		return -ENOMEM;
 
-	info->name = "AD1986A Analog";
-	info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ad1986a_pcm_analog_playback;
-	info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad1986a_pcm_analog_capture;
-	info++;
+	init_MUTEX(&spec->amp_mutex);
+	codec->spec = spec;
+
+	spec->multiout.max_channels = 2;
+	spec->multiout.num_dacs = ARRAY_SIZE(ad1983_dac_nids);
+	spec->multiout.dac_nids = ad1983_dac_nids;
+	spec->multiout.dig_out_nid = AD1983_SPDIF_OUT;
+	spec->adc_nid = AD1983_ADC;
+	spec->input_mux = &ad1983_capture_source;
+	spec->mixers = ad1983_mixers;
+	spec->init_verbs = ad1983_init_verbs;
+	spec->spdif_route = 0;
 
-	info->name = "AD1986A Digital";
-	info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ad1986a_pcm_digital_playback;
+	codec->patch_ops = ad198x_patch_ops;
 
 	return 0;
 }
 
-static void ad1986a_free(struct hda_codec *codec)
-{
-	kfree(codec->spec);
-}
 
-#ifdef CONFIG_PM
-static int ad1986a_resume(struct hda_codec *codec)
-{
-	ad1986a_init(codec);
-	snd_hda_resume_ctls(codec, ad1986a_mixers);
-	snd_hda_resume_spdif_out(codec);
-	return 0;
-}
-#endif
+/*
+ * AD1981 HD specific
+ */
 
-static struct hda_codec_ops ad1986a_patch_ops = {
-	.build_controls = ad1986a_build_controls,
-	.build_pcms = ad1986a_build_pcms,
-	.init = ad1986a_init,
-	.free = ad1986a_free,
-#ifdef CONFIG_PM
-	.resume = ad1986a_resume,
-#endif
+#define AD1981_SPDIF_OUT	0x02
+#define AD1981_DAC		0x03
+#define AD1981_ADC		0x04
+
+static hda_nid_t ad1981_dac_nids[1] = { AD1981_DAC };
+
+/* 0x0c, 0x09, 0x0e, 0x0f, 0x19, 0x05, 0x18, 0x17 */
+static struct hda_input_mux ad1981_capture_source = {
+	.num_items = 7,
+	.items = {
+		{ "Front Mic", 0x0 },
+		{ "Line", 0x1 },
+		{ "Mix", 0x2 },
+		{ "Mix Mono", 0x3 },
+		{ "CD", 0x4 },
+		{ "Mic", 0x6 },
+		{ "Aux", 0x7 },
+	},
 };
 
-static int patch_ad1986a(struct hda_codec *codec)
+static snd_kcontrol_new_t ad1981_mixers[] = {
+	HDA_CODEC_VOLUME("Front Playback Volume", 0x05, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE("Front Playback Switch", 0x05, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x06, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE("Headphone Playback Switch", 0x06, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x07, 1, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x07, 1, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME("Line Playback Volume", 0x13, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE("Line Playback Switch", 0x13, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME("Aux Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE("Aux Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME("Mic Playback Volume", 0x1c, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE("Mic Playback Switch", 0x1c, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME_MONO("PC Speaker Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE_MONO("PC Speaker Playback Switch", 0x0d, 1, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME("Front Mic Boost", 0x08, 0x0, HDA_INPUT),
+	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x0, HDA_INPUT),
+	HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT),
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Capture Source",
+		.info = ad198x_mux_enum_info,
+		.get = ad198x_mux_enum_get,
+		.put = ad198x_mux_enum_put,
+	},
+	/* identical with AD1983 */
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "IEC958 Playback Route",
+		.info = ad1983_spdif_route_info,
+		.get = ad1983_spdif_route_get,
+		.put = ad1983_spdif_route_put,
+	},
+	{ } /* end */
+};
+
+static struct hda_verb ad1981_init_verbs[] = {
+	/* Front, HP, Mono; mute as default */
+	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
+	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
+	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
+	/* Beep, PCM, Front Mic, Line, Rear Mic, Aux, CD-In: mute */
+	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
+	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
+	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
+	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
+	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
+	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
+	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
+	/* Front, HP selectors; from Mix */
+	{0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
+	{0x06, AC_VERB_SET_CONNECT_SEL, 0x01},
+	/* Mono selector; from Mix */
+	{0x0b, AC_VERB_SET_CONNECT_SEL, 0x03},
+	/* Mic Mixer; select Front Mic */
+	{0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
+	{0x1f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
+	/* Mic boost: 0dB */
+	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
+	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
+	/* Record selector: Front mic */
+	{0x15, AC_VERB_SET_CONNECT_SEL, 0x0},
+	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
+	/* SPDIF route: PCM */
+	{0x02, AC_VERB_SET_CONNECT_SEL, 0x0},
+	/* Front Pin */
+	{0x05, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
+	/* HP Pin */
+	{0x06, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
+	/* Mono Pin */
+	{0x07, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
+	/* Front & Rear Mic Pins */
+	{0x08, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
+	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
+	/* Line Pin */
+	{0x09, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
+	/* Digital Beep */
+	{0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
+	/* Line-Out as Input: disabled */
+	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
+	{ } /* end */
+};
+
+static int patch_ad1981(struct hda_codec *codec)
 {
-	struct ad1986a_spec *spec;
+	struct ad198x_spec *spec;
 
 	spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
 	if (spec == NULL)
@@ -426,20 +771,28 @@ static int patch_ad1986a(struct hda_code
 	init_MUTEX(&spec->amp_mutex);
 	codec->spec = spec;
 
-	spec->multiout.max_channels = 6;
-	spec->multiout.num_dacs = ARRAY_SIZE(ad1986a_dac_nids);
-	spec->multiout.dac_nids = ad1986a_dac_nids;
-	spec->multiout.dig_out_nid = AD1986A_SPDIF_OUT;
+	spec->multiout.max_channels = 2;
+	spec->multiout.num_dacs = ARRAY_SIZE(ad1981_dac_nids);
+	spec->multiout.dac_nids = ad1981_dac_nids;
+	spec->multiout.dig_out_nid = AD1981_SPDIF_OUT;
+	spec->adc_nid = AD1981_ADC;
+	spec->input_mux = &ad1981_capture_source;
+	spec->mixers = ad1981_mixers;
+	spec->init_verbs = ad1981_init_verbs;
+	spec->spdif_route = 0;
 
-	codec->patch_ops = ad1986a_patch_ops;
+	codec->patch_ops = ad198x_patch_ops;
 
 	return 0;
 }
 
+
 /*
  * patch entries
  */
 struct hda_codec_preset snd_hda_preset_analog[] = {
+	{ .id = 0x11d41981, .name = "AD1981", .patch = patch_ad1981 },
+	{ .id = 0x11d41983, .name = "AD1983", .patch = patch_ad1983 },
 	{ .id = 0x11d41986, .name = "AD1986A", .patch = patch_ad1986a },
 	{} /* terminator */
 };
diff --git a/sound/pci/hda/patch_cmedia.c b/sound/pci/hda/patch_cmedia.c
--- a/sound/pci/hda/patch_cmedia.c
+++ b/sound/pci/hda/patch_cmedia.c
@@ -29,6 +29,7 @@
 #include <sound/core.h>
 #include "hda_codec.h"
 #include "hda_local.h"
+#define NUM_PINS	11
 
 
 /* board config type */
@@ -38,6 +39,7 @@ enum {
 	CMI_FULL,	/* back 6-jack + front-panel 2-jack */
 	CMI_FULL_DIG,	/* back 6-jack + front-panel 2-jack + digital I/O */
 	CMI_ALLOUT,	/* back 5-jack + front-panel 2-jack + digital out */
+	CMI_AUTO,	/* let driver guess it */
 };
 
 struct cmi_spec {
@@ -48,6 +50,8 @@ struct cmi_spec {
 
 	/* playback */
 	struct hda_multi_out multiout;
+	hda_nid_t dac_nids[4];		/* NID for each DAC */
+	int num_dacs;
 
 	/* capture */
 	hda_nid_t *adc_nids;
@@ -63,7 +67,29 @@ struct cmi_spec {
 	const struct cmi_channel_mode *channel_modes;
 
 	struct hda_pcm pcm_rec[2];	/* PCM information */
-};
+
+	/* pin deafault configuration */
+	hda_nid_t pin_nid[NUM_PINS];
+	unsigned int def_conf[NUM_PINS];
+	unsigned int pin_def_confs;
+
+	/* multichannel pins */
+	hda_nid_t multich_pin[4];	/* max 8-channel */
+	struct hda_verb multi_init[9];	/* 2 verbs for each pin + terminator */
+};
+
+/* amp values */
+#define AMP_IN_MUTE(idx)	(0x7080 | ((idx)<<8))
+#define AMP_IN_UNMUTE(idx)	(0x7000 | ((idx)<<8))
+#define AMP_OUT_MUTE	0xb080
+#define AMP_OUT_UNMUTE	0xb000
+#define AMP_OUT_ZERO	0xb000
+/* pinctl values */
+#define PIN_IN		0x20
+#define PIN_VREF80	0x24
+#define PIN_VREF50	0x21
+#define PIN_OUT		0x40
+#define PIN_HP		0xc0
 
 /*
  * input MUX
@@ -102,9 +128,9 @@ static int cmi_mux_enum_put(snd_kcontrol
 /* 3-stack / 2 channel */
 static struct hda_verb cmi9880_ch2_init[] = {
 	/* set line-in PIN for input */
-	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
+	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
 	/* set mic PIN for input, also enable vref */
-	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
+	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
 	/* route front PCM (DAC1) to HP */
 	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
 	{}
@@ -113,9 +139,9 @@ static struct hda_verb cmi9880_ch2_init[
 /* 3-stack / 6 channel */
 static struct hda_verb cmi9880_ch6_init[] = {
 	/* set line-in PIN for output */
-	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
+	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
 	/* set mic PIN for output */
-	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
+	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
 	/* route front PCM (DAC1) to HP */
 	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
 	{}
@@ -124,9 +150,9 @@ static struct hda_verb cmi9880_ch6_init[
 /* 3-stack+front / 8 channel */
 static struct hda_verb cmi9880_ch8_init[] = {
 	/* set line-in PIN for output */
-	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
+	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
 	/* set mic PIN for output */
-	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
+	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
 	/* route rear-surround PCM (DAC4) to HP */
 	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x03 },
 	{}
@@ -269,25 +295,27 @@ static hda_nid_t cmi9880_adc_nids[2] = {
  */
 static struct hda_verb cmi9880_basic_init[] = {
 	/* port-D for line out (rear panel) */
-	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
+	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
 	/* port-E for HP out (front panel) */
-	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
+	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
 	/* route front PCM to HP */
 	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
 	/* port-A for surround (rear panel) */
-	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
+	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
 	/* port-G for CLFE (rear panel) */
-	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
+	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
+	{ 0x1f, AC_VERB_SET_CONNECT_SEL, 0x02 },
 	/* port-H for side (rear panel) */
-	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
+	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
+	{ 0x20, AC_VERB_SET_CONNECT_SEL, 0x01 },
 	/* port-C for line-in (rear panel) */
-	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
+	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
 	/* port-B for mic-in (rear panel) with vref */
-	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
+	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
 	/* port-F for mic-in (front panel) with vref */
-	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
+	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
 	/* CD-in */
-	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
+	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
 	/* route front mic to ADC1/2 */
 	{ 0x08, AC_VERB_SET_CONNECT_SEL, 0x05 },
 	{ 0x09, AC_VERB_SET_CONNECT_SEL, 0x05 },
@@ -296,23 +324,27 @@ static struct hda_verb cmi9880_basic_ini
 
 static struct hda_verb cmi9880_allout_init[] = {
 	/* port-D for line out (rear panel) */
-	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
+	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
 	/* port-E for HP out (front panel) */
-	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
+	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
 	/* route front PCM to HP */
 	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
 	/* port-A for side (rear panel) */
-	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
+	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
 	/* port-G for CLFE (rear panel) */
-	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
+	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
+	{ 0x1f, AC_VERB_SET_CONNECT_SEL, 0x02 },
+	/* port-H for side (rear panel) */
+	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
+	{ 0x20, AC_VERB_SET_CONNECT_SEL, 0x01 },
 	/* port-C for surround (rear panel) */
-	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
+	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
 	/* port-B for mic-in (rear panel) with vref */
-	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
+	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
 	/* port-F for mic-in (front panel) with vref */
-	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
+	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
 	/* CD-in */
-	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
+	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
 	/* route front mic to ADC1/2 */
 	{ 0x08, AC_VERB_SET_CONNECT_SEL, 0x05 },
 	{ 0x09, AC_VERB_SET_CONNECT_SEL, 0x05 },
@@ -347,6 +379,80 @@ static int cmi9880_build_controls(struct
 	return 0;
 }
 
+/* fill in the multi_dac_nids table, which will decide
+   which audio widget to use for each channel */
+static int cmi9880_fill_multi_dac_nids(struct hda_codec *codec, const struct auto_pin_cfg *cfg)
+{
+	struct cmi_spec *spec = codec->spec;
+	hda_nid_t nid;
+	int assigned[4];
+	int i, j;
+
+	/* clear the table, only one c-media dac assumed here */
+	memset(spec->dac_nids, 0, sizeof(spec->dac_nids));
+	memset(assigned, 0, sizeof(assigned));
+	/* check the pins we found */
+	for (i = 0; i < cfg->line_outs; i++) {
+		nid = cfg->line_out_pins[i];
+		/* nid 0x0b~0x0e is hardwired to audio widget 0x3~0x6 */
+		if (nid >= 0x0b && nid <= 0x0e) {
+			spec->dac_nids[i] = (nid - 0x0b) + 0x03;
+			assigned[nid - 0x0b] = 1;
+		}
+	}
+	/* left pin can be connect to any audio widget */
+	for (i = 0; i < cfg->line_outs; i++) {
+		nid = cfg->line_out_pins[i];
+		if (nid <= 0x0e)
+			continue;
+		/* search for an empty channel */
+		for (j = 0; j < cfg->line_outs; j++) {
+			if (! assigned[j]) {
+				spec->dac_nids[i] = j + 0x03;
+				assigned[j] = 1;
+				break;
+			}
+		}
+	}
+	spec->num_dacs = cfg->line_outs;
+	return 0;
+}
+
+/* create multi_init table, which is used for multichannel initialization */
+static int cmi9880_fill_multi_init(struct hda_codec *codec, const struct auto_pin_cfg *cfg)
+{
+	struct cmi_spec *spec = codec->spec;
+	hda_nid_t nid;
+	int i, j, k, len;
+
+	/* clear the table, only one c-media dac assumed here */
+	memset(spec->multi_init, 0, sizeof(spec->multi_init));
+	for (j = 0, i = 0; i < cfg->line_outs; i++) {
+		hda_nid_t conn[4];
+		nid = cfg->line_out_pins[i];
+		/* set as output */
+		spec->multi_init[j].nid = nid;
+		spec->multi_init[j].verb = AC_VERB_SET_PIN_WIDGET_CONTROL;
+		spec->multi_init[j].param = PIN_OUT;
+		j++;
+		if (nid > 0x0e) {
+			/* set connection */
+			spec->multi_init[j].nid = nid;
+			spec->multi_init[j].verb = AC_VERB_SET_CONNECT_SEL;
+			spec->multi_init[j].param = 0;
+			/* find the index in connect list */
+			len = snd_hda_get_connections(codec, nid, conn, 4);
+			for (k = 0; k < len; k++)
+				if (conn[k] == spec->dac_nids[i]) {
+					spec->multi_init[j].param = k;
+					break;
+				}
+			j++;
+		}
+	}
+	return 0;
+}
+
 static int cmi9880_init(struct hda_codec *codec)
 {
 	struct cmi_spec *spec = codec->spec;
@@ -354,6 +460,8 @@ static int cmi9880_init(struct hda_codec
 		snd_hda_sequence_write(codec, cmi9880_allout_init);
 	else
 		snd_hda_sequence_write(codec, cmi9880_basic_init);
+	if (spec->board_config == CMI_AUTO)
+		snd_hda_sequence_write(codec, spec->multi_init);
 	return 0;
 }
 
@@ -540,6 +648,7 @@ static struct hda_board_config cmi9880_c
 	{ .modelname = "full", .config = CMI_FULL },
 	{ .modelname = "full_dig", .config = CMI_FULL_DIG },
 	{ .modelname = "allout", .config = CMI_ALLOUT },
+	{ .modelname = "auto", .config = CMI_AUTO },
 	{} /* terminator */
 };
 
@@ -564,10 +673,14 @@ static int patch_cmi9880(struct hda_code
 	codec->spec = spec;
 	spec->board_config = snd_hda_check_board_config(codec, cmi9880_cfg_tbl);
 	if (spec->board_config < 0) {
-		snd_printd(KERN_INFO "hda_codec: Unknown model for CMI9880\n");
-		spec->board_config = CMI_FULL_DIG; /* try everything */
+		snd_printdd(KERN_INFO "hda_codec: Unknown model for CMI9880\n");
+		spec->board_config = CMI_AUTO; /* try everything */
 	}
 
+	/* copy default DAC NIDs */
+	memcpy(spec->dac_nids, cmi9880_dac_nids, sizeof(spec->dac_nids));
+	spec->num_dacs = 4;
+
 	switch (spec->board_config) {
 	case CMI_MINIMAL:
 	case CMI_MIN_FP:
@@ -599,10 +712,58 @@ static int patch_cmi9880(struct hda_code
 		spec->input_mux = &cmi9880_no_line_mux;
 		spec->multiout.dig_out_nid = CMI_DIG_OUT_NID;
 		break;
+	case CMI_AUTO:
+		{
+		unsigned int port_e, port_f, port_g, port_h;
+		unsigned int port_spdifi, port_spdifo;
+		struct auto_pin_cfg cfg;
+
+		/* collect pin default configuration */
+		port_e = snd_hda_codec_read(codec, 0x0f, 0, AC_VERB_GET_CONFIG_DEFAULT, 0);
+		port_f = snd_hda_codec_read(codec, 0x10, 0, AC_VERB_GET_CONFIG_DEFAULT, 0);
+		spec->front_panel = 1;
+		if (get_defcfg_connect(port_e) == AC_JACK_PORT_NONE ||
+		    get_defcfg_connect(port_f) == AC_JACK_PORT_NONE) {
+			port_g = snd_hda_codec_read(codec, 0x1f, 0, AC_VERB_GET_CONFIG_DEFAULT, 0);
+			port_h = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_CONFIG_DEFAULT, 0);
+			spec->surr_switch = 1;
+			/* no front panel */
+			if (get_defcfg_connect(port_g) == AC_JACK_PORT_NONE ||
+			    get_defcfg_connect(port_h) == AC_JACK_PORT_NONE) {
+				/* no optional rear panel */
+				spec->board_config = CMI_MINIMAL;
+				spec->front_panel = 0;
+				spec->num_ch_modes = 2;
+			} else {
+				spec->board_config = CMI_MIN_FP;
+				spec->num_ch_modes = 3;
+			}
+			spec->channel_modes = cmi9880_channel_modes;
+			spec->input_mux = &cmi9880_basic_mux;
+			spec->multiout.max_channels = cmi9880_channel_modes[0].channels;
+		} else {
+			spec->input_mux = &cmi9880_basic_mux;
+			port_spdifi = snd_hda_codec_read(codec, 0x13, 0, AC_VERB_GET_CONFIG_DEFAULT, 0);
+			port_spdifo = snd_hda_codec_read(codec, 0x12, 0, AC_VERB_GET_CONFIG_DEFAULT, 0);
+			if (get_defcfg_connect(port_spdifo) != AC_JACK_PORT_NONE)
+				spec->multiout.dig_out_nid = CMI_DIG_OUT_NID;
+			if (get_defcfg_connect(port_spdifi) != AC_JACK_PORT_NONE)
+				spec->dig_in_nid = CMI_DIG_IN_NID;
+			spec->multiout.max_channels = 8;
+		}
+		snd_hda_parse_pin_def_config(codec, &cfg);
+		if (cfg.line_outs) {
+			spec->multiout.max_channels = cfg.line_outs * 2;
+			cmi9880_fill_multi_dac_nids(codec, &cfg);
+			cmi9880_fill_multi_init(codec, &cfg);
+		} else
+			snd_printd("patch_cmedia: cannot detect association in defcfg\n");
+		break;
+		}
 	}
 
-	spec->multiout.num_dacs = 4;
-	spec->multiout.dac_nids = cmi9880_dac_nids;
+	spec->multiout.num_dacs = spec->num_dacs;
+	spec->multiout.dac_nids = spec->dac_nids;
 
 	spec->adc_nids = cmi9880_adc_nids;
 
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -33,38 +33,74 @@
 
 /* ALC880 board config type */
 enum {
-	ALC880_MINIMAL,
 	ALC880_3ST,
 	ALC880_3ST_DIG,
 	ALC880_5ST,
 	ALC880_5ST_DIG,
 	ALC880_W810,
+	ALC880_Z71V,
+	ALC880_AUTO,
+	ALC880_6ST,
+	ALC880_6ST_DIG,
+	ALC880_F1734,
+	ALC880_ASUS,
+	ALC880_ASUS_DIG,
+	ALC880_ASUS_W1V,
+	ALC880_UNIWILL_DIG,
+#ifdef CONFIG_SND_DEBUG
+	ALC880_TEST,
+#endif
+	ALC880_MODEL_LAST /* last tag */
 };
 
+/* ALC260 models */
+enum {
+	ALC260_BASIC,
+	ALC260_HP,
+	ALC260_MODEL_LAST /* last tag */
+};
+
+/* amp values */
+#define AMP_IN_MUTE(idx)	(0x7080 | ((idx)<<8))
+#define AMP_IN_UNMUTE(idx)	(0x7000 | ((idx)<<8))
+#define AMP_OUT_MUTE	0xb080
+#define AMP_OUT_UNMUTE	0xb000
+#define AMP_OUT_ZERO	0xb000
+/* pinctl values */
+#define PIN_IN		0x20
+#define PIN_VREF80	0x24
+#define PIN_VREF50	0x21
+#define PIN_OUT		0x40
+#define PIN_HP		0xc0
+
 struct alc_spec {
 	/* codec parameterization */
-	unsigned int front_panel: 1;
-
-	snd_kcontrol_new_t* mixers[2];
+	snd_kcontrol_new_t *mixers[3];	/* mixer arrays */
 	unsigned int num_mixers;
 
-	struct hda_verb *init_verbs;
+	const struct hda_verb *init_verbs[3];	/* initialization verbs
+						 * don't forget NULL termination!
+						 */
+	unsigned int num_init_verbs;
 
-	char* stream_name_analog;
+	char *stream_name_analog;	/* analog PCM stream */
 	struct hda_pcm_stream *stream_analog_playback;
 	struct hda_pcm_stream *stream_analog_capture;
 
-	char* stream_name_digital;
+	char *stream_name_digital;	/* digital PCM stream */ 
 	struct hda_pcm_stream *stream_digital_playback;
 	struct hda_pcm_stream *stream_digital_capture;
 
 	/* playback */
-	struct hda_multi_out multiout;
+	struct hda_multi_out multiout;	/* playback set-up
+					 * max_channels, dacs must be set
+					 * dig_out_nid and hp_nid are optional
+					 */
 
 	/* capture */
 	unsigned int num_adc_nids;
 	hda_nid_t *adc_nids;
-	hda_nid_t dig_in_nid;
+	hda_nid_t dig_in_nid;		/* digital-in NID; optional */
 
 	/* capture source */
 	const struct hda_input_mux *input_mux;
@@ -75,61 +111,18 @@ struct alc_spec {
 	int num_channel_mode;
 
 	/* PCM information */
-	struct hda_pcm pcm_rec[2];
-};
-
-/* DAC/ADC assignment */
-
-static hda_nid_t alc880_dac_nids[4] = {
-	/* front, rear, clfe, rear_surr */
-	0x02, 0x05, 0x04, 0x03
-};
-
-static hda_nid_t alc880_w810_dac_nids[3] = {
-	/* front, rear/surround, clfe */
-	0x02, 0x03, 0x04
-};
+	struct hda_pcm pcm_rec[2];	/* used in alc_build_pcms() */
 
-static hda_nid_t alc880_adc_nids[3] = {
-	/* ADC0-2 */
-	0x07, 0x08, 0x09,
-};
-
-#define ALC880_DIGOUT_NID	0x06
-#define ALC880_DIGIN_NID	0x0a
-
-static hda_nid_t alc260_dac_nids[1] = {
-	/* front */
-	0x02,
-};
-
-static hda_nid_t alc260_adc_nids[2] = {
-	/* ADC0-1 */
-	0x04, 0x05,
-};
-
-#define ALC260_DIGOUT_NID	0x03
-#define ALC260_DIGIN_NID	0x06
+	struct semaphore bind_mutex;	/* for bound controls */
 
-static struct hda_input_mux alc880_capture_source = {
-	.num_items = 4,
-	.items = {
-		{ "Mic", 0x0 },
-		{ "Front Mic", 0x3 },
-		{ "Line", 0x2 },
-		{ "CD", 0x4 },
-	},
+	/* dynamic controls, init_verbs and input_mux */
+	struct auto_pin_cfg autocfg;
+	unsigned int num_kctl_alloc, num_kctl_used;
+	snd_kcontrol_new_t *kctl_alloc;
+	struct hda_input_mux private_imux;
+	hda_nid_t private_dac_nids[4];
 };
 
-static struct hda_input_mux alc260_capture_source = {
-	.num_items = 4,
-	.items = {
-		{ "Mic", 0x0 },
-		{ "Front Mic", 0x1 },
-		{ "Line", 0x2 },
-		{ "CD", 0x4 },
-	},
-};
 
 /*
  * input MUX handling
@@ -160,6 +153,7 @@ static int alc_mux_enum_put(snd_kcontrol
 				     spec->adc_nids[adc_idx], &spec->cur_mux[adc_idx]);
 }
 
+
 /*
  * channel mode setting
  */
@@ -168,135 +162,18 @@ struct alc_channel_mode {
 	const struct hda_verb *sequence;
 };
 
-
-/*
- * channel source setting (2/6 channel selection for 3-stack)
- */
-
-/*
- * set the path ways for 2 channel output
- * need to set the codec line out and mic 1 pin widgets to inputs
- */
-static struct hda_verb alc880_threestack_ch2_init[] = {
-	/* set pin widget 1Ah (line in) for input */
-	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
-	/* set pin widget 18h (mic1) for input, for mic also enable the vref */
-	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
-	/* mute the output for Line In PW */
-	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
-	/* mute for Mic1 PW */
-	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
-	{ } /* end */
-};
-
-/*
- * 6ch mode
- * need to set the codec line out and mic 1 pin widgets to outputs
- */
-static struct hda_verb alc880_threestack_ch6_init[] = {
-	/* set pin widget 1Ah (line in) for output */
-	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
-	/* set pin widget 18h (mic1) for output */
-	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
-	/* unmute the output for Line In PW */
-	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000 },
-	/* unmute for Mic1 PW */
-	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000 },
-	/* for rear channel output using Line In 1
-	 * set select widget connection (nid = 0x12) - to summer node
-	 * for rear NID = 0x0f...offset 3 in connection list
-	 */
-	{ 0x12, AC_VERB_SET_CONNECT_SEL, 0x3 },
-	/* for Mic1 - retask for center/lfe */
-	/* set select widget connection (nid = 0x10) - to summer node for
-	 * front CLFE NID = 0x0e...offset 2 in connection list
-	 */
-	{ 0x10, AC_VERB_SET_CONNECT_SEL, 0x2 },
-	{ } /* end */
-};
-
-static struct alc_channel_mode alc880_threestack_modes[2] = {
-	{ 2, alc880_threestack_ch2_init },
-	{ 6, alc880_threestack_ch6_init },
-};
-
-
-/*
- * channel source setting (6/8 channel selection for 5-stack)
- */
-
-/* set the path ways for 6 channel output
- * need to set the codec line out and mic 1 pin widgets to inputs
- */
-static struct hda_verb alc880_fivestack_ch6_init[] = {
-	/* set pin widget 1Ah (line in) for input */
-	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
-	/* mute the output for Line In PW */
-	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
-	{ } /* end */
-};
-
-/* need to set the codec line out and mic 1 pin widgets to outputs */
-static struct hda_verb alc880_fivestack_ch8_init[] = {
-	/* set pin widget 1Ah (line in) for output */
-	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
-	/* unmute the output for Line In PW */
-	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000 },
-	/* output for surround channel output using Line In 1 */
-	/* set select widget connection (nid = 0x12) - to summer node
-	 * for surr_rear NID = 0x0d...offset 1 in connection list
-	 */
-	{ 0x12, AC_VERB_SET_CONNECT_SEL, 0x1 },
-	{ } /* end */
-};
-
-static struct alc_channel_mode alc880_fivestack_modes[2] = {
-	{ 6, alc880_fivestack_ch6_init },
-	{ 8, alc880_fivestack_ch8_init },
-};
-
-/*
- * channel source setting for W810 system
- *
- * W810 has rear IO for:
- * Front (DAC 02)
- * Surround (DAC 03)
- * Center/LFE (DAC 04)
- * Digital out (06)
- *
- * The system also has a pair of internal speakers, and a headphone jack.
- * These are both connected to Line2 on the codec, hence to DAC 02.
- * 
- * There is a variable resistor to control the speaker or headphone
- * volume. This is a hardware-only device without a software API.
- *
- * Plugging headphones in will disable the internal speakers. This is
- * implemented in hardware, not via the driver using jack sense. In
- * a similar fashion, plugging into the rear socket marked "front" will
- * disable both the speakers and headphones.
- *
- * For input, there's a microphone jack, and an "audio in" jack.
- * These may not do anything useful with this driver yet, because I
- * haven't setup any initialization verbs for these yet...
- */
-
-static struct alc_channel_mode alc880_w810_modes[1] = {
-	{ 6, NULL }
-};
-
-/*
- */
 static int alc880_ch_mode_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct alc_spec *spec = codec->spec;
+	int items = kcontrol->private_value ? (int)kcontrol->private_value : 2;
 
 	snd_assert(spec->channel_mode, return -ENXIO);
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
 	uinfo->count = 1;
-	uinfo->value.enumerated.items = 2;
-	if (uinfo->value.enumerated.item >= 2)
-		uinfo->value.enumerated.item = 1;
+	uinfo->value.enumerated.items = items;
+	if (uinfo->value.enumerated.item >= items)
+		uinfo->value.enumerated.item = items - 1;
 	sprintf(uinfo->value.enumerated.name, "%dch",
 		spec->channel_mode[uinfo->value.enumerated.item].channels);
 	return 0;
@@ -306,10 +183,16 @@ static int alc880_ch_mode_get(snd_kcontr
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct alc_spec *spec = codec->spec;
+	int items = kcontrol->private_value ? (int)kcontrol->private_value : 2;
+	int i;
 
 	snd_assert(spec->channel_mode, return -ENXIO);
-	ucontrol->value.enumerated.item[0] =
-		(spec->multiout.max_channels == spec->channel_mode[0].channels) ? 0 : 1;
+	for (i = 0; i < items; i++) {
+		if (spec->multiout.max_channels == spec->channel_mode[i].channels) {
+			ucontrol->value.enumerated.item[0] = i;
+			break;
+		}
+	}
 	return 0;
 }
 
@@ -335,21 +218,149 @@ static int alc880_ch_mode_put(snd_kcontr
 
 
 /*
+ * bound volume controls
+ *
+ * bind multiple volumes (# indices, from 0)
+ */
+
+#define AMP_VAL_IDX_SHIFT	19
+#define AMP_VAL_IDX_MASK	(0x0f<<19)
+
+static int alc_bind_switch_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+{
+	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct alc_spec *spec = codec->spec;
+	unsigned long pval;
+
+	down(&spec->bind_mutex);
+	pval = kcontrol->private_value;
+	kcontrol->private_value = pval & ~AMP_VAL_IDX_MASK; /* index 0 */
+	snd_hda_mixer_amp_switch_info(kcontrol, uinfo);
+	kcontrol->private_value = pval;
+	up(&spec->bind_mutex);
+	return 0;
+}
+
+static int alc_bind_switch_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct alc_spec *spec = codec->spec;
+	unsigned long pval;
+
+	down(&spec->bind_mutex);
+	pval = kcontrol->private_value;
+	kcontrol->private_value = pval & ~AMP_VAL_IDX_MASK; /* index 0 */
+	snd_hda_mixer_amp_switch_get(kcontrol, ucontrol);
+	kcontrol->private_value = pval;
+	up(&spec->bind_mutex);
+	return 0;
+}
+
+static int alc_bind_switch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct alc_spec *spec = codec->spec;
+	unsigned long pval;
+	int i, indices, change = 0;
+
+	down(&spec->bind_mutex);
+	pval = kcontrol->private_value;
+	indices = (pval & AMP_VAL_IDX_MASK) >> AMP_VAL_IDX_SHIFT;
+	for (i = 0; i < indices; i++) {
+		kcontrol->private_value = (pval & ~AMP_VAL_IDX_MASK) | (i << AMP_VAL_IDX_SHIFT);
+		change |= snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
+	}
+	kcontrol->private_value = pval;
+	up(&spec->bind_mutex);
+	return change;
+}
+
+#define ALC_BIND_MUTE_MONO(xname, nid, channel, indices, direction) \
+	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
+	  .info = alc_bind_switch_info, \
+	  .get = alc_bind_switch_get, \
+	  .put = alc_bind_switch_put, \
+	  .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, indices, direction) }
+
+#define ALC_BIND_MUTE(xname,nid,indices,dir) ALC_BIND_MUTE_MONO(xname,nid,3,indices,dir)
+
+
+/*
+ * ALC880 3-stack model
+ *
+ * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
+ * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18, F-Mic = 0x1b
+ *                 HP = 0x19
  */
 
-/* 3-stack mode
- * Pin assignment: Front=0x14, Line-In/Rear=0x1a, Mic/CLFE=0x18, F-Mic=0x1b
- *                 HP=0x19
+static hda_nid_t alc880_dac_nids[4] = {
+	/* front, rear, clfe, rear_surr */
+	0x02, 0x05, 0x04, 0x03
+};
+
+static hda_nid_t alc880_adc_nids[3] = {
+	/* ADC0-2 */
+	0x07, 0x08, 0x09,
+};
+
+/* The datasheet says the node 0x07 is connected from inputs,
+ * but it shows zero connection in the real implementation on some devices.
  */
-static snd_kcontrol_new_t alc880_base_mixer[] = {
+static hda_nid_t alc880_adc_nids_alt[2] = {
+	/* ADC1-2 */
+	0x08, 0x09,
+};
+
+#define ALC880_DIGOUT_NID	0x06
+#define ALC880_DIGIN_NID	0x0a
+
+static struct hda_input_mux alc880_capture_source = {
+	.num_items = 4,
+	.items = {
+		{ "Mic", 0x0 },
+		{ "Front Mic", 0x3 },
+		{ "Line", 0x2 },
+		{ "CD", 0x4 },
+	},
+};
+
+/* channel source setting (2/6 channel selection for 3-stack) */
+/* 2ch mode */
+static struct hda_verb alc880_threestack_ch2_init[] = {
+	/* set line-in to input, mute it */
+	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
+	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
+	/* set mic-in to input vref 80%, mute it */
+	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
+	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
+	{ } /* end */
+};
+
+/* 6ch mode */
+static struct hda_verb alc880_threestack_ch6_init[] = {
+	/* set line-in to output, unmute it */
+	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
+	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
+	/* set mic-in to output, unmute it */
+	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
+	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
+	{ } /* end */
+};
+
+static struct alc_channel_mode alc880_threestack_modes[2] = {
+	{ 2, alc880_threestack_ch2_init },
+	{ 6, alc880_threestack_ch6_init },
+};
+
+static snd_kcontrol_new_t alc880_three_stack_mixer[] = {
 	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
-	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
+	ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
 	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
-	HDA_CODEC_MUTE("Surround Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
+	ALC_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
 	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
 	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
-	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x18, 1, 0x0, HDA_OUTPUT),
-	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x18, 2, 0x0, HDA_OUTPUT),
+	ALC_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
+	ALC_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
 	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
 	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
 	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
@@ -360,25 +371,7 @@ static snd_kcontrol_new_t alc880_base_mi
 	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
 	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
 	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
-	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
 	HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
-	HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
-	HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
-	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
-	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
-	{
-		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-		/* The multiple "Capture Source" controls confuse alsamixer
-		 * So call somewhat different..
-		 * FIXME: the controls appear in the "playback" view!
-		 */
-		/* .name = "Capture Source", */
-		.name = "Input Source",
-		.count = 2,
-		.info = alc_mux_enum_info,
-		.get = alc_mux_enum_get,
-		.put = alc_mux_enum_put,
-	},
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name = "Channel Mode",
@@ -389,37 +382,14 @@ static snd_kcontrol_new_t alc880_base_mi
 	{ } /* end */
 };
 
-/* 5-stack mode
- * Pin assignment: Front=0x14, Rear=0x17, CLFE=0x16
- *                 Line-In/Side=0x1a, Mic=0x18, F-Mic=0x1b, HP=0x19
- */
-static snd_kcontrol_new_t alc880_five_stack_mixer[] = {
-	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
-	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
-	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
-	HDA_CODEC_MUTE("Surround Playback Switch", 0x17, 0x0, HDA_OUTPUT),
-	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
-	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
-	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x16, 1, 0x0, HDA_OUTPUT),
-	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
-	HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
-	HDA_CODEC_MUTE("Side Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
-	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
-	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
-	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
-	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
-	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
-	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
-	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
-	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
-	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
-	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
-	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
-	HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
+/* capture mixer elements */
+static snd_kcontrol_new_t alc880_capture_mixer[] = {
 	HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
 	HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
 	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
 	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
+	HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
+	HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		/* The multiple "Capture Source" controls confuse alsamixer
@@ -428,37 +398,20 @@ static snd_kcontrol_new_t alc880_five_st
 		 */
 		/* .name = "Capture Source", */
 		.name = "Input Source",
-		.count = 2,
+		.count = 3,
 		.info = alc_mux_enum_info,
 		.get = alc_mux_enum_get,
 		.put = alc_mux_enum_put,
 	},
-	{
-		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-		.name = "Channel Mode",
-		.info = alc880_ch_mode_info,
-		.get = alc880_ch_mode_get,
-		.put = alc880_ch_mode_put,
-	},
 	{ } /* end */
 };
 
-static snd_kcontrol_new_t alc880_w810_base_mixer[] = {
-	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
-	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
-	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
-	HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT),
-	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
-	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
-	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x16, 1, 0x0, HDA_OUTPUT),
-	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
-	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
-	HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
-	HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
-	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
-	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
-	HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
-	HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
+/* capture mixer elements (in case NID 0x07 not available) */
+static snd_kcontrol_new_t alc880_capture_alt_mixer[] = {
+	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
+	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
+	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
+	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		/* The multiple "Capture Source" controls confuse alsamixer
@@ -467,7 +420,7 @@ static snd_kcontrol_new_t alc880_w810_ba
 		 */
 		/* .name = "Capture Source", */
 		.name = "Input Source",
-		.count = 3,
+		.count = 2,
 		.info = alc_mux_enum_info,
 		.get = alc_mux_enum_get,
 		.put = alc_mux_enum_put,
@@ -475,7 +428,268 @@ static snd_kcontrol_new_t alc880_w810_ba
 	{ } /* end */
 };
 
+
+
+/*
+ * ALC880 5-stack model
+ *
+ * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d), Side = 0x02 (0xd)
+ * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
+ *                 Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
+ */
+
+/* additional mixers to alc880_three_stack_mixer */
+static snd_kcontrol_new_t alc880_five_stack_mixer[] = {
+	HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
+	ALC_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
+	{ } /* end */
+};
+
+/* channel source setting (6/8 channel selection for 5-stack) */
+/* 6ch mode */
+static struct hda_verb alc880_fivestack_ch6_init[] = {
+	/* set line-in to input, mute it */
+	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
+	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
+	{ } /* end */
+};
+
+/* 8ch mode */
+static struct hda_verb alc880_fivestack_ch8_init[] = {
+	/* set line-in to output, unmute it */
+	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
+	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
+	{ } /* end */
+};
+
+static struct alc_channel_mode alc880_fivestack_modes[2] = {
+	{ 6, alc880_fivestack_ch6_init },
+	{ 8, alc880_fivestack_ch8_init },
+};
+
+
+/*
+ * ALC880 6-stack model
+ *
+ * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e), Side = 0x05 (0x0f)
+ * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
+ *   Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
+ */
+
+static hda_nid_t alc880_6st_dac_nids[4] = {
+	/* front, rear, clfe, rear_surr */
+	0x02, 0x03, 0x04, 0x05
+};	
+
+static struct hda_input_mux alc880_6stack_capture_source = {
+	.num_items = 4,
+	.items = {
+		{ "Mic", 0x0 },
+		{ "Front Mic", 0x1 },
+		{ "Line", 0x2 },
+		{ "CD", 0x4 },
+	},
+};
+
+/* fixed 8-channels */
+static struct alc_channel_mode alc880_sixstack_modes[1] = {
+	{ 8, NULL },
+};
+
+static snd_kcontrol_new_t alc880_six_stack_mixer[] = {
+	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
+	ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
+	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
+	ALC_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
+	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
+	ALC_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
+	ALC_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
+	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
+	ALC_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
+	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
+	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
+	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
+	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
+	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
+	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
+	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
+	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
+	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
+	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Channel Mode",
+		.info = alc880_ch_mode_info,
+		.get = alc880_ch_mode_get,
+		.put = alc880_ch_mode_put,
+	},
+	{ } /* end */
+};
+
+
+/*
+ * ALC880 W810 model
+ *
+ * W810 has rear IO for:
+ * Front (DAC 02)
+ * Surround (DAC 03)
+ * Center/LFE (DAC 04)
+ * Digital out (06)
+ *
+ * The system also has a pair of internal speakers, and a headphone jack.
+ * These are both connected to Line2 on the codec, hence to DAC 02.
+ * 
+ * There is a variable resistor to control the speaker or headphone
+ * volume. This is a hardware-only device without a software API.
+ *
+ * Plugging headphones in will disable the internal speakers. This is
+ * implemented in hardware, not via the driver using jack sense. In
+ * a similar fashion, plugging into the rear socket marked "front" will
+ * disable both the speakers and headphones.
+ *
+ * For input, there's a microphone jack, and an "audio in" jack.
+ * These may not do anything useful with this driver yet, because I
+ * haven't setup any initialization verbs for these yet...
+ */
+
+static hda_nid_t alc880_w810_dac_nids[3] = {
+	/* front, rear/surround, clfe */
+	0x02, 0x03, 0x04
+};
+
+/* fixed 6 channels */
+static struct alc_channel_mode alc880_w810_modes[1] = {
+	{ 6, NULL }
+};
+
+/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
+static snd_kcontrol_new_t alc880_w810_base_mixer[] = {
+	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
+	ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
+	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
+	ALC_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
+	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
+	ALC_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
+	ALC_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
+	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
+	{ } /* end */
+};
+
+
+/*
+ * Z710V model
+ *
+ * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
+ * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?), Line = 0x1a
+ */
+
+static hda_nid_t alc880_z71v_dac_nids[1] = {
+	0x02
+};
+#define ALC880_Z71V_HP_DAC	0x03
+
+/* fixed 2 channels */
+static struct alc_channel_mode alc880_2_jack_modes[1] = {
+	{ 2, NULL }
+};
+
+static snd_kcontrol_new_t alc880_z71v_mixer[] = {
+	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
+	ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
+	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
+	ALC_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
+	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
+	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
+	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
+	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
+	{ } /* end */
+};
+
+
+/* FIXME! */
+/*
+ * ALC880 F1734 model
+ *
+ * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
+ * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
+ */
+
+static hda_nid_t alc880_f1734_dac_nids[1] = {
+	0x03
+};
+#define ALC880_F1734_HP_DAC	0x02
+
+static snd_kcontrol_new_t alc880_f1734_mixer[] = {
+	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
+	ALC_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
+	HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
+	ALC_BIND_MUTE("Internal Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
+	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
+	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
+	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
+	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
+	{ } /* end */
+};
+
+
+/* FIXME! */
+/*
+ * ALC880 ASUS model
+ *
+ * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
+ * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
+ *  Mic = 0x18, Line = 0x1a
+ */
+
+#define alc880_asus_dac_nids	alc880_w810_dac_nids	/* identical with w810 */
+#define alc880_asus_modes	alc880_threestack_modes	/* 2/6 channel mode */
+
+static snd_kcontrol_new_t alc880_asus_mixer[] = {
+	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
+	ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
+	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
+	ALC_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
+	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
+	ALC_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
+	ALC_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
+	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
+	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
+	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
+	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
+	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
+	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Channel Mode",
+		.info = alc880_ch_mode_info,
+		.get = alc880_ch_mode_get,
+		.put = alc880_ch_mode_put,
+	},
+	{ } /* end */
+};
+
+/* FIXME! */
+/*
+ * ALC880 ASUS W1V model
+ *
+ * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
+ * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
+ *  Mic = 0x18, Line = 0x1a, Line2 = 0x1b
+ */
+
+/* additional mixers to alc880_asus_mixer */
+static snd_kcontrol_new_t alc880_asus_w1v_mixer[] = {
+	HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
+	HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
+	{ } /* end */
+};
+
+
 /*
+ * build control elements
  */
 static int alc_build_controls(struct hda_codec *codec)
 {
@@ -502,227 +716,297 @@ static int alc_build_controls(struct hda
 	return 0;
 }
 
+
 /*
  * initialize the codec volumes, etc
  */
 
-static struct hda_verb alc880_init_verbs_three_stack[] = {
-	/* Line In pin widget for input */
-	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
-	/* CD pin widget for input */
-	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
-	/* Mic1 (rear panel) pin widget for input and vref at 80% */
-	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
-	/* Mic2 (front panel) pin widget for input and vref at 80% */
-	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
-	/* unmute amp left and right */
-	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
-	/* set connection select to line in (default select for this ADC) */
-	{0x07, AC_VERB_SET_CONNECT_SEL, 0x02},
-	/* unmute front mixer amp left (volume = 0) */
-	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
-	/* mute pin widget amp left and right (no gain on this amp) */
-	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
-	/* unmute rear mixer amp left and right (volume = 0) */
-	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
-	/* mute pin widget amp left and right (no gain on this amp) */
-	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
-	/* unmute rear mixer amp left and right (volume = 0) */
-	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
-	/* mute pin widget amp left and right (no gain on this amp) */
-	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
-
-	/* using rear surround as the path for headphone output */
-	/* unmute rear surround mixer amp left and right (volume = 0) */
-	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
-	/* PASD 3 stack boards use the Mic 2 as the headphone output */
-	/* need to program the selector associated with the Mic 2 pin widget to
-	 * surround path (index 0x01) for headphone output */
-	{0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
-	/* mute pin widget amp left and right (no gain on this amp) */
-	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
-	/* need to retask the Mic 2 pin widget to output */
-	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
+/*
+ * generic initialization of ADC, input mixers and output mixers
+ */
+static struct hda_verb alc880_volume_init_verbs[] = {
+	/*
+	 * Unmute ADC0-2 and set the default input to mic-in
+	 */
+	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
+	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
+	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
+	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 
-	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) for mixer widget(nid=0x0B)
-	 * to support the input path of analog loopback
+	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
+	 * mixer widget
 	 * Note: PASD motherboards uses the Line In 2 as the input for front panel
 	 * mic (mic 2)
 	 */
-	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03 */
-	/* unmute CD */
-	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
-	/* unmute Line In */
-	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
-	/* unmute Mic 1 */
-	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
-	/* unmute Line In 2 (for PASD boards Mic 2) */
-	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
-
-	/* Unmute input amps for the line out paths to support the output path of
-	 * analog loopback
-	 * the mixers on the output path has 2 inputs, one from the DAC and one
-	 * from the mixer
+	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
+	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
+	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
+	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
+
+	/*
+	 * Set up output mixers (0x0c - 0x0f)
 	 */
-	/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
-	/* Unmute Front out path */
-	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
-	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
-	/* Unmute Surround (used as HP) out path */
-	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
-	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
-	/* Unmute C/LFE out path */
-	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
-	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))}, /* mute */
-	/* Unmute rear Surround out path */
-	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
-	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
+	/* set vol=0 to output mixers */
+	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
+	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
+	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
+	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
+	/* set up input amps for analog loopback */
+	/* Amp Indices: DAC = 0, mixer = 1 */
+	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
+	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
+	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
+	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
 
 	{ }
 };
 
-static struct hda_verb alc880_init_verbs_five_stack[] = {
-	/* Line In pin widget for input */
-	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
-	/* CD pin widget for input */
-	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
-	/* Mic1 (rear panel) pin widget for input and vref at 80% */
-	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
-	/* Mic2 (front panel) pin widget for input and vref at 80% */
-	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
-	/* unmute amp left and right */
-	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
-	/* set connection select to line in (default select for this ADC) */
-	{0x07, AC_VERB_SET_CONNECT_SEL, 0x02},
-	/* unmute front mixer amp left and right (volume = 0) */
-	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
-	/* mute pin widget amp left and right (no gain on this amp) */
-	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
-	/* five rear and clfe */
-	/* unmute rear mixer amp left and right (volume = 0)  */
-	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
-	/* mute pin widget amp left and right (no gain on this amp) */
-	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
-	/* unmute clfe mixer amp left and right (volume = 0) */
-	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
-	/* mute pin widget amp left and right (no gain on this amp) */
-	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
-
-	/* using rear surround as the path for headphone output */
-	/* unmute rear surround mixer amp left and right (volume = 0) */
-	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
-	/* PASD 3 stack boards use the Mic 2 as the headphone output */
-	/* need to program the selector associated with the Mic 2 pin widget to
-	 * surround path (index 0x01) for headphone output
+/*
+ * 3-stack pin configuration:
+ * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
+ */
+static struct hda_verb alc880_pin_3stack_init_verbs[] = {
+	/*
+	 * preset connection lists of input pins
+	 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
 	 */
-	{0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
-	/* mute pin widget amp left and right (no gain on this amp) */
-	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
-	/* need to retask the Mic 2 pin widget to output */
-	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
+	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
+	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
+	{0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
 
-	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) for mixer
-	 * widget(nid=0x0B) to support the input path of analog loopback
+	/*
+	 * Set pin mode and muting
 	 */
-	/* Note: PASD motherboards uses the Line In 2 as the input for front panel mic (mic 2) */
-	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03*/
-	/* unmute CD */
-	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
-	/* unmute Line In */
-	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
-	/* unmute Mic 1 */
-	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
-	/* unmute Line In 2 (for PASD boards Mic 2) */
-	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
-
-	/* Unmute input amps for the line out paths to support the output path of
-	 * analog loopback
-	 * the mixers on the output path has 2 inputs, one from the DAC and
-	 * one from the mixer
-	 */
-	/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
-	/* Unmute Front out path */
-	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
-	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
-	/* Unmute Surround (used as HP) out path */
-	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
-	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
-	/* Unmute C/LFE out path */
-	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
-	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))}, /* mute */
-	/* Unmute rear Surround out path */
-	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
-	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
+	/* set front pin widgets 0x14 for output */
+	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	/* Mic1 (rear panel) pin widget for input and vref at 80% */
+	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
+	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+	/* Mic2 (as headphone out) for HP output */
+	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	/* Line In pin widget for input */
+	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+	/* Line2 (as front mic) pin widget for input and vref at 80% */
+	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
+	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+	/* CD pin widget for input */
+	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
 
 	{ }
 };
 
-static struct hda_verb alc880_w810_init_verbs[] = {
-	/* front channel selector/amp: input 0: DAC: unmuted, (no volume selection) */
-	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
-
-	/* front channel selector/amp: input 1: capture mix: muted, (no volume selection) */
-	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7180},
-
-	/* front channel selector/amp: output 0: unmuted, max volume */
-	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
-
-	/* front out pin: muted, (no volume selection)  */
-	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
-
-	/* front out pin: NOT headphone enable, out enable, vref disabled */
-	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
-
+/*
+ * 5-stack pin configuration:
+ * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
+ * line-in/side = 0x1a, f-mic = 0x1b
+ */
+static struct hda_verb alc880_pin_5stack_init_verbs[] = {
+	/*
+	 * preset connection lists of input pins
+	 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
+	 */
+	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
+	{0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
 
-	/* surround channel selector/amp: input 0: DAC: unmuted, (no volume selection) */
-	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
+	/*
+	 * Set pin mode and muting
+	 */
+	/* set pin widgets 0x14-0x17 for output */
+	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+	/* unmute pins for output (no gain on this amp) */
+	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 
-	/* surround channel selector/amp: input 1: capture mix: muted, (no volume selection) */
-	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7180},
+	/* Mic1 (rear panel) pin widget for input and vref at 80% */
+	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
+	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+	/* Mic2 (as headphone out) for HP output */
+	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	/* Line In pin widget for input */
+	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+	/* Line2 (as front mic) pin widget for input and vref at 80% */
+	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
+	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+	/* CD pin widget for input */
+	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
 
-	/* surround channel selector/amp: output 0: unmuted, max volume */
-	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
+	{ }
+};
 
-	/* surround out pin: muted, (no volume selection)  */
-	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
+/*
+ * W810 pin configuration:
+ * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
+ */
+static struct hda_verb alc880_pin_w810_init_verbs[] = {
+	/* hphone/speaker input selector: front DAC */
+	{0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
 
-	/* surround out pin: NOT headphone enable, out enable, vref disabled */
-	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
+	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 
+	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
 
-	/* c/lfe channel selector/amp: input 0: DAC: unmuted, (no volume selection) */
-	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
+	{ }
+};
 
-	/* c/lfe channel selector/amp: input 1: capture mix: muted, (no volume selection) */
-	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, 0x7180},
+/*
+ * Z71V pin configuration:
+ * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
+ */
+static struct hda_verb alc880_pin_z71v_init_verbs[] = {
+	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+
+	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
+	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
+	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
 
-	/* c/lfe channel selector/amp: output 0: unmuted, max volume */
-	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
+	{ }
+};
 
-	/* c/lfe out pin: muted, (no volume selection)  */
-	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
+/*
+ * 6-stack pin configuration:
+ * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18, f-mic = 0x19,
+ * line = 0x1a, HP = 0x1b
+ */
+static struct hda_verb alc880_pin_6stack_init_verbs[] = {
+	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
+
+	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+
+	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
+	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
+	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+	
+	{ }
+};
 
-	/* c/lfe out pin: NOT headphone enable, out enable, vref disabled */
-	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
+/* FIXME! */
+/*
+ * F1734 pin configuration:
+ * HP = 0x14, speaker-out = 0x15, mic = 0x18
+ */
+static struct hda_verb alc880_pin_f1734_init_verbs[] = {
+	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
+	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
+	{0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
+	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
+
+	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+
+	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
+	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
+	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
 
+	{ }
+};
 
-	/* hphone/speaker input selector: front DAC */
-	{0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
+/* FIXME! */
+/*
+ * ASUS pin configuration:
+ * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
+ */
+static struct hda_verb alc880_pin_asus_init_verbs[] = {
+	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
+	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
+	{0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
+	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
+
+	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+
+	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
+	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
+	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+	
+	{ }
+};
 
-	/* hphone/speaker out pin: muted, (no volume selection)  */
-	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
+/* Enable GPIO mask and set output */
+static struct hda_verb alc880_gpio1_init_verbs[] = {
+	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
+	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
+	{0x01, AC_VERB_SET_GPIO_DATA, 0x01},
+};
 
-	/* hphone/speaker out pin: NOT headphone enable, out enable, vref disabled */
-	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
+/* Enable GPIO mask and set output */
+static struct hda_verb alc880_gpio2_init_verbs[] = {
+	{0x01, AC_VERB_SET_GPIO_MASK, 0x02},
+	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
+	{0x01, AC_VERB_SET_GPIO_DATA, 0x02},
+};
 
 
-	{ }
-};
+/*
+ */
 
 static int alc_init(struct hda_codec *codec)
 {
 	struct alc_spec *spec = codec->spec;
-	snd_hda_sequence_write(codec, spec->init_verbs);
+	unsigned int i;
+
+	for (i = 0; i < spec->num_init_verbs; i++)
+		snd_hda_sequence_write(codec, spec->init_verbs[i]);
 	return 0;
 }
 
@@ -736,9 +1020,8 @@ static int alc_resume(struct hda_codec *
 	int i;
 
 	alc_init(codec);
-	for (i = 0; i < spec->num_mixers; i++) {
+	for (i = 0; i < spec->num_mixers; i++)
 		snd_hda_resume_ctls(codec, spec->mixers[i]);
-	}
 	if (spec->multiout.dig_out_nid)
 		snd_hda_resume_spdif_out(codec);
 	if (spec->dig_in_nid)
@@ -778,296 +1061,1085 @@ static int alc880_playback_pcm_cleanup(s
 	return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
 }
 
-/*
- * Digital out
- */
-static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
-					struct hda_codec *codec,
-					snd_pcm_substream_t *substream)
+/*
+ * Digital out
+ */
+static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
+					struct hda_codec *codec,
+					snd_pcm_substream_t *substream)
+{
+	struct alc_spec *spec = codec->spec;
+	return snd_hda_multi_out_dig_open(codec, &spec->multiout);
+}
+
+static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
+					 struct hda_codec *codec,
+					 snd_pcm_substream_t *substream)
+{
+	struct alc_spec *spec = codec->spec;
+	return snd_hda_multi_out_dig_close(codec, &spec->multiout);
+}
+
+/*
+ * Analog capture
+ */
+static int alc880_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
+				      struct hda_codec *codec,
+				      unsigned int stream_tag,
+				      unsigned int format,
+				      snd_pcm_substream_t *substream)
+{
+	struct alc_spec *spec = codec->spec;
+
+	snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
+				   stream_tag, 0, format);
+	return 0;
+}
+
+static int alc880_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
+				      struct hda_codec *codec,
+				      snd_pcm_substream_t *substream)
+{
+	struct alc_spec *spec = codec->spec;
+
+	snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number], 0, 0, 0);
+	return 0;
+}
+
+
+/*
+ */
+static struct hda_pcm_stream alc880_pcm_analog_playback = {
+	.substreams = 1,
+	.channels_min = 2,
+	.channels_max = 8,
+	/* NID is set in alc_build_pcms */
+	.ops = {
+		.open = alc880_playback_pcm_open,
+		.prepare = alc880_playback_pcm_prepare,
+		.cleanup = alc880_playback_pcm_cleanup
+	},
+};
+
+static struct hda_pcm_stream alc880_pcm_analog_capture = {
+	.substreams = 2,
+	.channels_min = 2,
+	.channels_max = 2,
+	/* NID is set in alc_build_pcms */
+	.ops = {
+		.prepare = alc880_capture_pcm_prepare,
+		.cleanup = alc880_capture_pcm_cleanup
+	},
+};
+
+static struct hda_pcm_stream alc880_pcm_digital_playback = {
+	.substreams = 1,
+	.channels_min = 2,
+	.channels_max = 2,
+	/* NID is set in alc_build_pcms */
+	.ops = {
+		.open = alc880_dig_playback_pcm_open,
+		.close = alc880_dig_playback_pcm_close
+	},
+};
+
+static struct hda_pcm_stream alc880_pcm_digital_capture = {
+	.substreams = 1,
+	.channels_min = 2,
+	.channels_max = 2,
+	/* NID is set in alc_build_pcms */
+};
+
+static int alc_build_pcms(struct hda_codec *codec)
+{
+	struct alc_spec *spec = codec->spec;
+	struct hda_pcm *info = spec->pcm_rec;
+	int i;
+
+	codec->num_pcms = 1;
+	codec->pcm_info = info;
+
+	info->name = spec->stream_name_analog;
+	info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
+	info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
+	info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
+	info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
+
+	info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
+	for (i = 0; i < spec->num_channel_mode; i++) {
+		if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
+		    info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
+		}
+	}
+
+	if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
+		codec->num_pcms++;
+		info++;
+		info->name = spec->stream_name_digital;
+		if (spec->multiout.dig_out_nid) {
+			info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
+			info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
+		}
+		if (spec->dig_in_nid) {
+			info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
+			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
+		}
+	}
+
+	return 0;
+}
+
+static void alc_free(struct hda_codec *codec)
+{
+	struct alc_spec *spec = codec->spec;
+	unsigned int i;
+
+	if (! spec)
+		return;
+
+	if (spec->kctl_alloc) {
+		for (i = 0; i < spec->num_kctl_used; i++)
+			kfree(spec->kctl_alloc[i].name);
+		kfree(spec->kctl_alloc);
+	}
+	kfree(spec);
+}
+
+/*
+ */
+static struct hda_codec_ops alc_patch_ops = {
+	.build_controls = alc_build_controls,
+	.build_pcms = alc_build_pcms,
+	.init = alc_init,
+	.free = alc_free,
+#ifdef CONFIG_PM
+	.resume = alc_resume,
+#endif
+};
+
+
+/*
+ * Test configuration for debugging
+ *
+ * Almost all inputs/outputs are enabled.  I/O pins can be configured via
+ * enum controls.
+ */
+#ifdef CONFIG_SND_DEBUG
+static hda_nid_t alc880_test_dac_nids[4] = {
+	0x02, 0x03, 0x04, 0x05
+};
+
+static struct hda_input_mux alc880_test_capture_source = {
+	.num_items = 5,
+	.items = {
+		{ "In-1", 0x0 },
+		{ "In-2", 0x1 },
+		{ "In-3", 0x2 },
+		{ "In-4", 0x3 },
+		{ "CD", 0x4 },
+	},
+};
+
+static struct alc_channel_mode alc880_test_modes[4] = {
+	{ 2, NULL },
+	{ 4, NULL },
+	{ 6, NULL },
+	{ 8, NULL },
+};
+
+static int alc_test_pin_ctl_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+{
+	static char *texts[] = {
+		"N/A", "Line Out", "HP Out",
+		"In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
+	};
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+	uinfo->count = 1;
+	uinfo->value.enumerated.items = 8;
+	if (uinfo->value.enumerated.item >= 8)
+		uinfo->value.enumerated.item = 7;
+	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
+	return 0;
+}
+
+static int alc_test_pin_ctl_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
+	unsigned int pin_ctl, item = 0;
+
+	pin_ctl = snd_hda_codec_read(codec, nid, 0,
+				     AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
+	if (pin_ctl & AC_PINCTL_OUT_EN) {
+		if (pin_ctl & AC_PINCTL_HP_EN)
+			item = 2;
+		else
+			item = 1;
+	} else if (pin_ctl & AC_PINCTL_IN_EN) {
+		switch (pin_ctl & AC_PINCTL_VREFEN) {
+		case AC_PINCTL_VREF_HIZ: item = 3; break;
+		case AC_PINCTL_VREF_50:  item = 4; break;
+		case AC_PINCTL_VREF_GRD: item = 5; break;
+		case AC_PINCTL_VREF_80:  item = 6; break;
+		case AC_PINCTL_VREF_100: item = 7; break;
+		}
+	}
+	ucontrol->value.enumerated.item[0] = item;
+	return 0;
+}
+
+static int alc_test_pin_ctl_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
+	static unsigned int ctls[] = {
+		0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
+		AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
+		AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
+		AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
+		AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
+		AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
+	};
+	unsigned int old_ctl, new_ctl;
+
+	old_ctl = snd_hda_codec_read(codec, nid, 0,
+				     AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
+	new_ctl = ctls[ucontrol->value.enumerated.item[0]];
+	if (old_ctl != new_ctl) {
+		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, new_ctl);
+		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
+				    ucontrol->value.enumerated.item[0] >= 3 ? 0xb080 : 0xb000);
+		return 1;
+	}
+	return 0;
+}
+
+static int alc_test_pin_src_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+{
+	static char *texts[] = {
+		"Front", "Surround", "CLFE", "Side"
+	};
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+	uinfo->count = 1;
+	uinfo->value.enumerated.items = 4;
+	if (uinfo->value.enumerated.item >= 4)
+		uinfo->value.enumerated.item = 3;
+	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
+	return 0;
+}
+
+static int alc_test_pin_src_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
+	unsigned int sel;
+
+	sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
+	ucontrol->value.enumerated.item[0] = sel & 3;
+	return 0;
+}
+
+static int alc_test_pin_src_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
+	unsigned int sel;
+
+	sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
+	if (ucontrol->value.enumerated.item[0] != sel) {
+		sel = ucontrol->value.enumerated.item[0] & 3;
+		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, sel);
+		return 1;
+	}
+	return 0;
+}
+
+#define PIN_CTL_TEST(xname,nid) {			\
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,	\
+			.name = xname,		       \
+			.info = alc_test_pin_ctl_info, \
+			.get = alc_test_pin_ctl_get,   \
+			.put = alc_test_pin_ctl_put,   \
+			.private_value = nid	       \
+			}
+
+#define PIN_SRC_TEST(xname,nid) {			\
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,	\
+			.name = xname,		       \
+			.info = alc_test_pin_src_info, \
+			.get = alc_test_pin_src_get,   \
+			.put = alc_test_pin_src_put,   \
+			.private_value = nid	       \
+			}
+
+static snd_kcontrol_new_t alc880_test_mixer[] = {
+	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
+	ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
+	ALC_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
+	ALC_BIND_MUTE("CLFE Playback Volume", 0x0e, 2, HDA_INPUT),
+	ALC_BIND_MUTE("Side Playback Volume", 0x0f, 2, HDA_INPUT),
+	PIN_CTL_TEST("Front Pin Mode", 0x14),
+	PIN_CTL_TEST("Surround Pin Mode", 0x15),
+	PIN_CTL_TEST("CLFE Pin Mode", 0x16),
+	PIN_CTL_TEST("Side Pin Mode", 0x17),
+	PIN_CTL_TEST("In-1 Pin Mode", 0x18),
+	PIN_CTL_TEST("In-2 Pin Mode", 0x19),
+	PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
+	PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
+	PIN_SRC_TEST("In-1 Pin Source", 0x18),
+	PIN_SRC_TEST("In-2 Pin Source", 0x19),
+	PIN_SRC_TEST("In-3 Pin Source", 0x1a),
+	PIN_SRC_TEST("In-4 Pin Source", 0x1b),
+	HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
+	HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
+	HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
+	HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
+	HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
+	HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
+	HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
+	HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
+	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
+	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
+	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
+	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
+	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
+	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Input Source",
+		.count = 2,
+		.info = alc_mux_enum_info,
+		.get = alc_mux_enum_get,
+		.put = alc_mux_enum_put,
+	},
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Channel Mode",
+		.info = alc880_ch_mode_info,
+		.get = alc880_ch_mode_get,
+		.put = alc880_ch_mode_put,
+	},
+	{ } /* end */
+};
+
+static struct hda_verb alc880_test_init_verbs[] = {
+	/* Unmute inputs of 0x0c - 0x0f */
+	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+	/* Vol output for 0x0c-0x0f */
+	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
+	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
+	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
+	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
+	/* Set output pins 0x14-0x17 */
+	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+	/* Unmute output pins 0x14-0x17 */
+	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	/* Set input pins 0x18-0x1c */
+	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
+	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
+	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+	/* Mute input pins 0x18-0x1b */
+	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+	/* ADC set up */
+	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
+	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
+	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
+	/* Analog input/passthru */
+	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
+	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
+	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
+	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
+	{ }
+};
+#endif
+
+/*
+ */
+
+static struct hda_board_config alc880_cfg_tbl[] = {
+	/* Back 3 jack, front 2 jack */
+	{ .modelname = "3stack", .config = ALC880_3ST },
+	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe200, .config = ALC880_3ST },
+	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe201, .config = ALC880_3ST },
+	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe202, .config = ALC880_3ST },
+	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe203, .config = ALC880_3ST },
+	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe204, .config = ALC880_3ST },
+	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe205, .config = ALC880_3ST },
+	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe206, .config = ALC880_3ST },
+	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe207, .config = ALC880_3ST },
+	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe208, .config = ALC880_3ST },
+	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe209, .config = ALC880_3ST },
+	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe20a, .config = ALC880_3ST },
+	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe20b, .config = ALC880_3ST },
+	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe20c, .config = ALC880_3ST },
+	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe20d, .config = ALC880_3ST },
+	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe20e, .config = ALC880_3ST },
+	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe20f, .config = ALC880_3ST },
+	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe210, .config = ALC880_3ST },
+	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe211, .config = ALC880_3ST },
+	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe214, .config = ALC880_3ST },
+	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe302, .config = ALC880_3ST },
+	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe303, .config = ALC880_3ST },
+	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe304, .config = ALC880_3ST },
+	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe306, .config = ALC880_3ST },
+	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe307, .config = ALC880_3ST },
+	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe404, .config = ALC880_3ST },
+	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xa101, .config = ALC880_3ST },
+	{ .pci_subvendor = 0x107b, .pci_subdevice = 0x3031, .config = ALC880_3ST },
+	{ .pci_subvendor = 0x107b, .pci_subdevice = 0x4036, .config = ALC880_3ST },
+	{ .pci_subvendor = 0x107b, .pci_subdevice = 0x4037, .config = ALC880_3ST },
+	{ .pci_subvendor = 0x107b, .pci_subdevice = 0x4038, .config = ALC880_3ST },
+	{ .pci_subvendor = 0x107b, .pci_subdevice = 0x4040, .config = ALC880_3ST },
+	{ .pci_subvendor = 0x107b, .pci_subdevice = 0x4041, .config = ALC880_3ST },
+
+	/* Back 3 jack, front 2 jack (Internal add Aux-In) */
+	{ .pci_subvendor = 0x1025, .pci_subdevice = 0xe310, .config = ALC880_3ST },
+	{ .pci_subvendor = 0x104d, .pci_subdevice = 0x81d6, .config = ALC880_3ST }, 
+
+	/* Back 3 jack plus 1 SPDIF out jack, front 2 jack */
+	{ .modelname = "3stack-digout", .config = ALC880_3ST_DIG },
+	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe308, .config = ALC880_3ST_DIG },
+
+	/* Back 3 jack plus 1 SPDIF out jack, front 2 jack (Internal add Aux-In)*/
+	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe305, .config = ALC880_3ST_DIG },
+	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xd402, .config = ALC880_3ST_DIG },
+	{ .pci_subvendor = 0x1025, .pci_subdevice = 0xe309, .config = ALC880_3ST_DIG },
+
+	/* Back 5 jack, front 2 jack */
+	{ .modelname = "5stack", .config = ALC880_5ST },
+	{ .pci_subvendor = 0x107b, .pci_subdevice = 0x3033, .config = ALC880_5ST },
+	{ .pci_subvendor = 0x107b, .pci_subdevice = 0x4039, .config = ALC880_5ST },
+	{ .pci_subvendor = 0x107b, .pci_subdevice = 0x3032, .config = ALC880_5ST },
+	{ .pci_subvendor = 0x103c, .pci_subdevice = 0x2a09, .config = ALC880_5ST },
+	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x814e, .config = ALC880_5ST },
+
+	/* Back 5 jack plus 1 SPDIF out jack, front 2 jack */
+	{ .modelname = "5stack-digout", .config = ALC880_5ST_DIG },
+	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe224, .config = ALC880_5ST_DIG },
+	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe400, .config = ALC880_5ST_DIG },
+	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe401, .config = ALC880_5ST_DIG },
+	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe402, .config = ALC880_5ST_DIG },
+	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xd400, .config = ALC880_5ST_DIG },
+	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xd401, .config = ALC880_5ST_DIG },
+	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xa100, .config = ALC880_5ST_DIG },
+	{ .pci_subvendor = 0x1565, .pci_subdevice = 0x8202, .config = ALC880_5ST_DIG },
+	{ .pci_subvendor = 0x1019, .pci_subdevice = 0xa880, .config = ALC880_5ST_DIG },
+	/* { .pci_subvendor = 0x1019, .pci_subdevice = 0xa884, .config = ALC880_5ST_DIG }, */ /* conflict with 6stack */
+	{ .pci_subvendor = 0x1695, .pci_subdevice = 0x400d, .config = ALC880_5ST_DIG },
+	/* note subvendor = 0 below */
+	/* { .pci_subvendor = 0x0000, .pci_subdevice = 0x8086, .config = ALC880_5ST_DIG }, */
+
+	{ .modelname = "w810", .config = ALC880_W810 },
+	{ .pci_subvendor = 0x161f, .pci_subdevice = 0x203d, .config = ALC880_W810 },
+
+	{ .modelname = "z71v", .config = ALC880_Z71V },
+	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x1964, .config = ALC880_Z71V },
+
+	{ .modelname = "6stack", .config = ALC880_6ST },
+	{ .pci_subvendor = 0x1019, .pci_subdevice = 0xa884, .config = ALC880_6ST }, /* Acer APFV */
+
+	{ .modelname = "6stack-digout", .config = ALC880_6ST_DIG },
+	{ .pci_subvendor = 0x2668, .pci_subdevice = 0x8086, .config = ALC880_6ST_DIG },
+	{ .pci_subvendor = 0x8086, .pci_subdevice = 0x2668, .config = ALC880_6ST_DIG },
+	{ .pci_subvendor = 0x1462, .pci_subdevice = 0x1150, .config = ALC880_6ST_DIG },
+	{ .pci_subvendor = 0xe803, .pci_subdevice = 0x1019, .config = ALC880_6ST_DIG },
+
+	{ .modelname = "asus", .config = ALC880_ASUS },
+	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x1964, .config = ALC880_ASUS_DIG },
+	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x1973, .config = ALC880_ASUS_DIG },
+	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x19b3, .config = ALC880_ASUS_DIG },
+	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x1113, .config = ALC880_ASUS_DIG },
+	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x1993, .config = ALC880_ASUS },
+	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x10c3, .config = ALC880_ASUS_DIG },
+	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x1133, .config = ALC880_ASUS },
+	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x1123, .config = ALC880_ASUS_DIG },
+	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x1143, .config = ALC880_ASUS },
+	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x10b3, .config = ALC880_ASUS_W1V },
+
+	{ .modelname = "uniwill", .config = ALC880_UNIWILL_DIG },
+	{ .pci_subvendor = 0x1584, .pci_subdevice = 0x9050, .config = ALC880_UNIWILL_DIG },	
+
+	{ .modelname = "F1734", .config = ALC880_F1734 },
+	{ .pci_subvendor = 0x1734, .pci_subdevice = 0x107c, .config = ALC880_F1734 },
+
+#ifdef CONFIG_SND_DEBUG
+	{ .modelname = "test", .config = ALC880_TEST },
+#endif
+
+	{}
+};
+
+/*
+ * configuration template - to be copied to the spec instance
+ */
+struct alc_config_preset {
+	snd_kcontrol_new_t *mixers[4];
+	const struct hda_verb *init_verbs[4];
+	unsigned int num_dacs;
+	hda_nid_t *dac_nids;
+	hda_nid_t dig_out_nid;		/* optional */
+	hda_nid_t hp_nid;		/* optional */
+	unsigned int num_adc_nids;
+	hda_nid_t *adc_nids;
+	unsigned int num_channel_mode;
+	const struct alc_channel_mode *channel_mode;
+	const struct hda_input_mux *input_mux;
+};
+
+static struct alc_config_preset alc880_presets[] = {
+	[ALC880_3ST] = {
+		.mixers = { alc880_three_stack_mixer },
+		.init_verbs = { alc880_volume_init_verbs, alc880_pin_3stack_init_verbs },
+		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
+		.dac_nids = alc880_dac_nids,
+		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
+		.channel_mode = alc880_threestack_modes,
+		.input_mux = &alc880_capture_source,
+	},
+	[ALC880_3ST_DIG] = {
+		.mixers = { alc880_three_stack_mixer },
+		.init_verbs = { alc880_volume_init_verbs, alc880_pin_3stack_init_verbs },
+		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
+		.dac_nids = alc880_dac_nids,
+		.dig_out_nid = ALC880_DIGOUT_NID,
+		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
+		.channel_mode = alc880_threestack_modes,
+		.input_mux = &alc880_capture_source,
+	},
+	[ALC880_5ST] = {
+		.mixers = { alc880_three_stack_mixer, alc880_five_stack_mixer},
+		.init_verbs = { alc880_volume_init_verbs, alc880_pin_5stack_init_verbs },
+		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
+		.dac_nids = alc880_dac_nids,
+		.num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
+		.channel_mode = alc880_fivestack_modes,
+		.input_mux = &alc880_capture_source,
+	},
+	[ALC880_5ST_DIG] = {
+		.mixers = { alc880_three_stack_mixer, alc880_five_stack_mixer },
+		.init_verbs = { alc880_volume_init_verbs, alc880_pin_5stack_init_verbs },
+		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
+		.dac_nids = alc880_dac_nids,
+		.dig_out_nid = ALC880_DIGOUT_NID,
+		.num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
+		.channel_mode = alc880_fivestack_modes,
+		.input_mux = &alc880_capture_source,
+	},
+	[ALC880_6ST] = {
+		.mixers = { alc880_six_stack_mixer },
+		.init_verbs = { alc880_volume_init_verbs, alc880_pin_6stack_init_verbs },
+		.num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
+		.dac_nids = alc880_6st_dac_nids,
+		.num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
+		.channel_mode = alc880_sixstack_modes,
+		.input_mux = &alc880_6stack_capture_source,
+	},
+	[ALC880_6ST_DIG] = {
+		.mixers = { alc880_six_stack_mixer },
+		.init_verbs = { alc880_volume_init_verbs, alc880_pin_6stack_init_verbs },
+		.num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
+		.dac_nids = alc880_6st_dac_nids,
+		.dig_out_nid = ALC880_DIGOUT_NID,
+		.num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
+		.channel_mode = alc880_sixstack_modes,
+		.input_mux = &alc880_6stack_capture_source,
+	},
+	[ALC880_W810] = {
+		.mixers = { alc880_w810_base_mixer },
+		.init_verbs = { alc880_volume_init_verbs, alc880_pin_w810_init_verbs,
+				alc880_gpio2_init_verbs },
+		.num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
+		.dac_nids = alc880_w810_dac_nids,
+		.dig_out_nid = ALC880_DIGOUT_NID,
+		.num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
+		.channel_mode = alc880_w810_modes,
+		.input_mux = &alc880_capture_source,
+	},
+	[ALC880_Z71V] = {
+		.mixers = { alc880_z71v_mixer },
+		.init_verbs = { alc880_volume_init_verbs, alc880_pin_z71v_init_verbs },
+		.num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
+		.dac_nids = alc880_z71v_dac_nids,
+		.dig_out_nid = ALC880_DIGOUT_NID,
+		.hp_nid = 0x03,
+		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
+		.channel_mode = alc880_2_jack_modes,
+		.input_mux = &alc880_capture_source,
+	},
+	[ALC880_F1734] = {
+		.mixers = { alc880_f1734_mixer },
+		.init_verbs = { alc880_volume_init_verbs, alc880_pin_f1734_init_verbs },
+		.num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
+		.dac_nids = alc880_f1734_dac_nids,
+		.hp_nid = 0x02,
+		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
+		.channel_mode = alc880_2_jack_modes,
+		.input_mux = &alc880_capture_source,
+	},
+	[ALC880_ASUS] = {
+		.mixers = { alc880_asus_mixer },
+		.init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs,
+				alc880_gpio1_init_verbs },
+		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
+		.dac_nids = alc880_asus_dac_nids,
+		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
+		.channel_mode = alc880_asus_modes,
+		.input_mux = &alc880_capture_source,
+	},
+	[ALC880_ASUS_DIG] = {
+		.mixers = { alc880_asus_mixer },
+		.init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs,
+				alc880_gpio1_init_verbs },
+		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
+		.dac_nids = alc880_asus_dac_nids,
+		.dig_out_nid = ALC880_DIGOUT_NID,
+		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
+		.channel_mode = alc880_asus_modes,
+		.input_mux = &alc880_capture_source,
+	},
+	[ALC880_ASUS_W1V] = {
+		.mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
+		.init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs,
+				alc880_gpio1_init_verbs },
+		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
+		.dac_nids = alc880_asus_dac_nids,
+		.dig_out_nid = ALC880_DIGOUT_NID,
+		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
+		.channel_mode = alc880_asus_modes,
+		.input_mux = &alc880_capture_source,
+	},
+	[ALC880_UNIWILL_DIG] = {
+		.mixers = { alc880_asus_mixer },
+		.init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs },
+		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
+		.dac_nids = alc880_asus_dac_nids,
+		.dig_out_nid = ALC880_DIGOUT_NID,
+		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
+		.channel_mode = alc880_asus_modes,
+		.input_mux = &alc880_capture_source,
+	},
+#ifdef CONFIG_SND_DEBUG
+	[ALC880_TEST] = {
+		.mixers = { alc880_test_mixer },
+		.init_verbs = { alc880_test_init_verbs },
+		.num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
+		.dac_nids = alc880_test_dac_nids,
+		.dig_out_nid = ALC880_DIGOUT_NID,
+		.num_channel_mode = ARRAY_SIZE(alc880_test_modes),
+		.channel_mode = alc880_test_modes,
+		.input_mux = &alc880_test_capture_source,
+	},
+#endif
+};
+
+/*
+ * Automatic parse of I/O pins from the BIOS configuration
+ */
+
+#define NUM_CONTROL_ALLOC	32
+#define NUM_VERB_ALLOC		32
+
+enum {
+	ALC_CTL_WIDGET_VOL,
+	ALC_CTL_WIDGET_MUTE,
+	ALC_CTL_BIND_MUTE,
+};
+static snd_kcontrol_new_t alc880_control_templates[] = {
+	HDA_CODEC_VOLUME(NULL, 0, 0, 0),
+	HDA_CODEC_MUTE(NULL, 0, 0, 0),
+	ALC_BIND_MUTE(NULL, 0, 0, 0),
+};
+
+/* add dynamic controls */
+static int add_control(struct alc_spec *spec, int type, const char *name, unsigned long val)
+{
+	snd_kcontrol_new_t *knew;
+
+	if (spec->num_kctl_used >= spec->num_kctl_alloc) {
+		int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;
+
+		knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL); /* array + terminator */
+		if (! knew)
+			return -ENOMEM;
+		if (spec->kctl_alloc) {
+			memcpy(knew, spec->kctl_alloc, sizeof(*knew) * spec->num_kctl_alloc);
+			kfree(spec->kctl_alloc);
+		}
+		spec->kctl_alloc = knew;
+		spec->num_kctl_alloc = num;
+	}
+
+	knew = &spec->kctl_alloc[spec->num_kctl_used];
+	*knew = alc880_control_templates[type];
+	knew->name = kstrdup(name, GFP_KERNEL);
+	if (! knew->name)
+		return -ENOMEM;
+	knew->private_value = val;
+	spec->num_kctl_used++;
+	return 0;
+}
+
+#define alc880_is_fixed_pin(nid)	((nid) >= 0x14 && (nid) <= 0x17)
+#define alc880_fixed_pin_idx(nid)	((nid) - 0x14)
+#define alc880_is_multi_pin(nid)	((nid) >= 0x18)
+#define alc880_multi_pin_idx(nid)	((nid) - 0x18)
+#define alc880_is_input_pin(nid)	((nid) >= 0x18)
+#define alc880_input_pin_idx(nid)	((nid) - 0x18)
+#define alc880_idx_to_dac(nid)		((nid) + 0x02)
+#define alc880_dac_to_idx(nid)		((nid) - 0x02)
+#define alc880_idx_to_mixer(nid)	((nid) + 0x0c)
+#define alc880_idx_to_selector(nid)	((nid) + 0x10)
+#define ALC880_PIN_CD_NID		0x1c
+
+/* fill in the dac_nids table from the parsed pin configuration */
+static int alc880_auto_fill_dac_nids(struct alc_spec *spec, const struct auto_pin_cfg *cfg)
+{
+	hda_nid_t nid;
+	int assigned[4];
+	int i, j;
+
+	memset(assigned, 0, sizeof(assigned));
+	spec->multiout.dac_nids = spec->private_dac_nids;
+
+	/* check the pins hardwired to audio widget */
+	for (i = 0; i < cfg->line_outs; i++) {
+		nid = cfg->line_out_pins[i];
+		if (alc880_is_fixed_pin(nid)) {
+			int idx = alc880_fixed_pin_idx(nid);
+			spec->multiout.dac_nids[i] = alc880_dac_to_idx(idx);
+			assigned[idx] = 1;
+		}
+	}
+	/* left pins can be connect to any audio widget */
+	for (i = 0; i < cfg->line_outs; i++) {
+		nid = cfg->line_out_pins[i];
+		if (alc880_is_fixed_pin(nid))
+			continue;
+		/* search for an empty channel */
+		for (j = 0; j < cfg->line_outs; j++) {
+			if (! assigned[j]) {
+				spec->multiout.dac_nids[i] = alc880_idx_to_dac(j);
+				assigned[j] = 1;
+				break;
+			}
+		}
+	}
+	spec->multiout.num_dacs = cfg->line_outs;
+	return 0;
+}
+
+/* add playback controls from the parsed DAC table */
+static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec, const struct auto_pin_cfg *cfg)
+{
+	char name[32];
+	static const char *chname[4] = { "Front", "Surround", NULL /*CLFE*/, "Side" };
+	hda_nid_t nid;
+	int i, err;
+
+	for (i = 0; i < cfg->line_outs; i++) {
+		if (! spec->multiout.dac_nids[i])
+			continue;
+		nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
+		if (i == 2) {
+			/* Center/LFE */
+			if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Center Playback Volume",
+					       HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT))) < 0)
+				return err;
+			if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "LFE Playback Volume",
+					       HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0)
+				return err;
+			if ((err = add_control(spec, ALC_CTL_BIND_MUTE, "Center Playback Switch",
+					       HDA_COMPOSE_AMP_VAL(nid, 1, 2, HDA_INPUT))) < 0)
+				return err;
+			if ((err = add_control(spec, ALC_CTL_BIND_MUTE, "LFE Playback Switch",
+					       HDA_COMPOSE_AMP_VAL(nid, 2, 2, HDA_INPUT))) < 0)
+				return err;
+		} else {
+			sprintf(name, "%s Playback Volume", chname[i]);
+			if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
+					       HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
+				return err;
+			sprintf(name, "%s Playback Switch", chname[i]);
+			if ((err = add_control(spec, ALC_CTL_BIND_MUTE, name,
+					       HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT))) < 0)
+				return err;
+		}
+	}
+
+	return 0;
+}
+
+/* add playback controls for HP output */
+static int alc880_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
+{
+	hda_nid_t nid;
+	int err;
+
+	if (! pin)
+		return 0;
+
+	if (alc880_is_fixed_pin(pin)) {
+		nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
+		if (! spec->multiout.dac_nids[0]) {
+			/* use this as the primary output */
+			spec->multiout.dac_nids[0] = nid;
+			if (! spec->multiout.num_dacs)
+				spec->multiout.num_dacs = 1;
+		} else 
+			/* specify the DAC as the extra HP output */
+			spec->multiout.hp_nid = nid;
+		/* control HP volume/switch on the output mixer amp */
+		nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
+		if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Headphone Playback Volume",
+				       HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
+			return err;
+		if ((err = add_control(spec, ALC_CTL_BIND_MUTE, "Headphone Playback Switch",
+				       HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT))) < 0)
+			return err;
+	} else if (alc880_is_multi_pin(pin)) {
+		/* set manual connection */
+		if (! spec->multiout.dac_nids[0]) {
+			/* use this as the primary output */
+			spec->multiout.dac_nids[0] = alc880_idx_to_dac(alc880_multi_pin_idx(pin));
+			if (! spec->multiout.num_dacs)
+				spec->multiout.num_dacs = 1;
+		}
+		/* we have only a switch on HP-out PIN */
+		if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Headphone Playback Switch",
+				       HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT))) < 0)
+			return err;
+	}
+	return 0;
+}
+
+/* create input playback/capture controls for the given pin */
+static int new_analog_input(struct alc_spec *spec, hda_nid_t pin, const char *ctlname)
+{
+	char name[32];
+	int err, idx;
+
+	sprintf(name, "%s Playback Volume", ctlname);
+	idx = alc880_input_pin_idx(pin);
+	if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
+			       HDA_COMPOSE_AMP_VAL(0x0b, 3, idx, HDA_INPUT))) < 0)
+		return err;
+	sprintf(name, "%s Playback Switch", ctlname);
+	if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
+			       HDA_COMPOSE_AMP_VAL(0x0b, 3, idx, HDA_INPUT))) < 0)
+		return err;
+	return 0;
+}
+
+/* create playback/capture controls for input pins */
+static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec, const struct auto_pin_cfg *cfg)
 {
-	struct alc_spec *spec = codec->spec;
-	return snd_hda_multi_out_dig_open(codec, &spec->multiout);
+	static char *labels[AUTO_PIN_LAST] = {
+		"Mic", "Front Mic", "Line", "Front Line", "CD", "Aux"
+	};
+	struct hda_input_mux *imux = &spec->private_imux;
+	int i, err;
+
+	for (i = 0; i < AUTO_PIN_LAST; i++) {
+		if (alc880_is_input_pin(cfg->input_pins[i])) {
+			err = new_analog_input(spec, cfg->input_pins[i], labels[i]);
+			if (err < 0)
+				return err;
+			imux->items[imux->num_items].label = labels[i];
+			imux->items[imux->num_items].index = alc880_input_pin_idx(cfg->input_pins[i]);
+			imux->num_items++;
+		}
+	}
+	return 0;
 }
 
-static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
-					 struct hda_codec *codec,
-					 snd_pcm_substream_t *substream)
+static void alc880_auto_set_output_and_unmute(struct hda_codec *codec, hda_nid_t nid, int pin_type,
+					      int dac_idx)
 {
-	struct alc_spec *spec = codec->spec;
-	return snd_hda_multi_out_dig_close(codec, &spec->multiout);
+	/* set as output */
+	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
+	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
+	/* need the manual connection? */
+	if (alc880_is_multi_pin(nid)) {
+		struct alc_spec *spec = codec->spec;
+		int idx = alc880_multi_pin_idx(nid);
+		snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
+				    AC_VERB_SET_CONNECT_SEL,
+				    alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
+	}
 }
 
-/*
- * Analog capture
- */
-static int alc880_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
-				      struct hda_codec *codec,
-				      unsigned int stream_tag,
-				      unsigned int format,
-				      snd_pcm_substream_t *substream)
+static void alc880_auto_init_multi_out(struct hda_codec *codec)
 {
 	struct alc_spec *spec = codec->spec;
+	int i;
 
-	snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
-				   stream_tag, 0, format);
-	return 0;
+	for (i = 0; i < spec->autocfg.line_outs; i++) {
+		hda_nid_t nid = spec->autocfg.line_out_pins[i];
+		alc880_auto_set_output_and_unmute(codec, nid, PIN_OUT, i);
+	}
 }
 
-static int alc880_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
-				      struct hda_codec *codec,
-				      snd_pcm_substream_t *substream)
+static void alc880_auto_init_hp_out(struct hda_codec *codec)
 {
 	struct alc_spec *spec = codec->spec;
+	hda_nid_t pin;
 
-	snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number], 0, 0, 0);
-	return 0;
+	pin = spec->autocfg.hp_pin;
+	if (pin) /* connect to front */
+		alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
 }
 
-
-/*
- */
-static struct hda_pcm_stream alc880_pcm_analog_playback = {
-	.substreams = 1,
-	.channels_min = 2,
-	.channels_max = 8,
-	.nid = 0x02, /* NID to query formats and rates */
-	.ops = {
-		.open = alc880_playback_pcm_open,
-		.prepare = alc880_playback_pcm_prepare,
-		.cleanup = alc880_playback_pcm_cleanup
-	},
-};
-
-static struct hda_pcm_stream alc880_pcm_analog_capture = {
-	.substreams = 2,
-	.channels_min = 2,
-	.channels_max = 2,
-	.nid = 0x07, /* NID to query formats and rates */
-	.ops = {
-		.prepare = alc880_capture_pcm_prepare,
-		.cleanup = alc880_capture_pcm_cleanup
-	},
-};
-
-static struct hda_pcm_stream alc880_pcm_digital_playback = {
-	.substreams = 1,
-	.channels_min = 2,
-	.channels_max = 2,
-	/* NID is set in alc_build_pcms */
-	.ops = {
-		.open = alc880_dig_playback_pcm_open,
-		.close = alc880_dig_playback_pcm_close
-	},
-};
-
-static struct hda_pcm_stream alc880_pcm_digital_capture = {
-	.substreams = 1,
-	.channels_min = 2,
-	.channels_max = 2,
-	/* NID is set in alc_build_pcms */
-};
-
-static int alc_build_pcms(struct hda_codec *codec)
+static void alc880_auto_init_analog_input(struct hda_codec *codec)
 {
 	struct alc_spec *spec = codec->spec;
-	struct hda_pcm *info = spec->pcm_rec;
 	int i;
 
-	codec->num_pcms = 1;
-	codec->pcm_info = info;
-
-	info->name = spec->stream_name_analog;
-	info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
-	info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
-
-	info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
-	for (i = 0; i < spec->num_channel_mode; i++) {
-		if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
-		    info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
-		}
-	}
-
-	if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
-		codec->num_pcms++;
-		info++;
-		info->name = spec->stream_name_digital;
-		if (spec->multiout.dig_out_nid) {
-			info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
-			info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
-		}
-		if (spec->dig_in_nid) {
-			info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
-			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
+	for (i = 0; i < AUTO_PIN_LAST; i++) {
+		hda_nid_t nid = spec->autocfg.input_pins[i];
+		if (alc880_is_input_pin(nid)) {
+			snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
+					    i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN);
+			if (nid != ALC880_PIN_CD_NID)
+				snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
+						    AMP_OUT_MUTE);
 		}
 	}
-
-	return 0;
 }
 
-static void alc_free(struct hda_codec *codec)
+/* parse the BIOS configuration and set up the alc_spec */
+/* return 1 if successful, 0 if the proper config is not found, or a negative error code */
+static int alc880_parse_auto_config(struct hda_codec *codec)
 {
-	kfree(codec->spec);
-}
-
-/*
- */
-static struct hda_codec_ops alc_patch_ops = {
-	.build_controls = alc_build_controls,
-	.build_pcms = alc_build_pcms,
-	.init = alc_init,
-	.free = alc_free,
-#ifdef CONFIG_PM
-	.resume = alc_resume,
-#endif
-};
+	struct alc_spec *spec = codec->spec;
+	int err;
 
-/*
- */
+	if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg)) < 0)
+		return err;
+	if ((err = alc880_auto_fill_dac_nids(spec, &spec->autocfg)) < 0)
+		return err;
+	if (! spec->autocfg.line_outs && ! spec->autocfg.hp_pin)
+		return 0; /* can't find valid BIOS pin config */
+	if ((err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 ||
+	    (err = alc880_auto_create_hp_ctls(spec, spec->autocfg.hp_pin)) < 0 ||
+	    (err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0)
+		return err;
 
-static struct hda_board_config alc880_cfg_tbl[] = {
-	/* Back 3 jack, front 2 jack */
-	{ .modelname = "3stack", .config = ALC880_3ST },
-	{ .pci_vendor = 0x8086, .pci_device = 0xe200, .config = ALC880_3ST },
-	{ .pci_vendor = 0x8086, .pci_device = 0xe201, .config = ALC880_3ST },
-	{ .pci_vendor = 0x8086, .pci_device = 0xe202, .config = ALC880_3ST },
-	{ .pci_vendor = 0x8086, .pci_device = 0xe203, .config = ALC880_3ST },
-	{ .pci_vendor = 0x8086, .pci_device = 0xe204, .config = ALC880_3ST },
-	{ .pci_vendor = 0x8086, .pci_device = 0xe205, .config = ALC880_3ST },
-	{ .pci_vendor = 0x8086, .pci_device = 0xe206, .config = ALC880_3ST },
-	{ .pci_vendor = 0x8086, .pci_device = 0xe207, .config = ALC880_3ST },
-	{ .pci_vendor = 0x8086, .pci_device = 0xe208, .config = ALC880_3ST },
-	{ .pci_vendor = 0x8086, .pci_device = 0xe209, .config = ALC880_3ST },
-	{ .pci_vendor = 0x8086, .pci_device = 0xe20a, .config = ALC880_3ST },
-	{ .pci_vendor = 0x8086, .pci_device = 0xe20b, .config = ALC880_3ST },
-	{ .pci_vendor = 0x8086, .pci_device = 0xe20c, .config = ALC880_3ST },
-	{ .pci_vendor = 0x8086, .pci_device = 0xe20d, .config = ALC880_3ST },
-	{ .pci_vendor = 0x8086, .pci_device = 0xe20e, .config = ALC880_3ST },
-	{ .pci_vendor = 0x8086, .pci_device = 0xe20f, .config = ALC880_3ST },
-	{ .pci_vendor = 0x8086, .pci_device = 0xe210, .config = ALC880_3ST },
-	{ .pci_vendor = 0x8086, .pci_device = 0xe211, .config = ALC880_3ST },
-	{ .pci_vendor = 0x8086, .pci_device = 0xe214, .config = ALC880_3ST },
-	{ .pci_vendor = 0x8086, .pci_device = 0xe302, .config = ALC880_3ST },
-	{ .pci_vendor = 0x8086, .pci_device = 0xe303, .config = ALC880_3ST },
-	{ .pci_vendor = 0x8086, .pci_device = 0xe304, .config = ALC880_3ST },
-	{ .pci_vendor = 0x8086, .pci_device = 0xe306, .config = ALC880_3ST },
-	{ .pci_vendor = 0x8086, .pci_device = 0xe307, .config = ALC880_3ST },
-	{ .pci_vendor = 0x8086, .pci_device = 0xe404, .config = ALC880_3ST },
-	{ .pci_vendor = 0x8086, .pci_device = 0xa101, .config = ALC880_3ST },
-	{ .pci_vendor = 0x107b, .pci_device = 0x3031, .config = ALC880_3ST },
-	{ .pci_vendor = 0x107b, .pci_device = 0x4036, .config = ALC880_3ST },
-	{ .pci_vendor = 0x107b, .pci_device = 0x4037, .config = ALC880_3ST },
-	{ .pci_vendor = 0x107b, .pci_device = 0x4038, .config = ALC880_3ST },
-	{ .pci_vendor = 0x107b, .pci_device = 0x4040, .config = ALC880_3ST },
-	{ .pci_vendor = 0x107b, .pci_device = 0x4041, .config = ALC880_3ST },
+	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
 
-	/* Back 3 jack, front 2 jack (Internal add Aux-In) */
-	{ .pci_vendor = 0x1025, .pci_device = 0xe310, .config = ALC880_3ST },
+	if (spec->autocfg.dig_out_pin)
+		spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
+	if (spec->autocfg.dig_in_pin)
+		spec->dig_in_nid = ALC880_DIGIN_NID;
 
-	/* Back 3 jack plus 1 SPDIF out jack, front 2 jack */
-	{ .modelname = "3stack-digout", .config = ALC880_3ST_DIG },
-	{ .pci_vendor = 0x8086, .pci_device = 0xe308, .config = ALC880_3ST_DIG },
+	if (spec->kctl_alloc)
+		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
 
-	/* Back 3 jack plus 1 SPDIF out jack, front 2 jack (Internal add Aux-In)*/
-	{ .pci_vendor = 0x8086, .pci_device = 0xe305, .config = ALC880_3ST_DIG },
-	{ .pci_vendor = 0x8086, .pci_device = 0xd402, .config = ALC880_3ST_DIG },
-	{ .pci_vendor = 0x1025, .pci_device = 0xe309, .config = ALC880_3ST_DIG },
+	spec->init_verbs[spec->num_init_verbs++] = alc880_volume_init_verbs;
 
-	/* Back 5 jack, front 2 jack */
-	{ .modelname = "5stack", .config = ALC880_5ST },
-	{ .pci_vendor = 0x107b, .pci_device = 0x3033, .config = ALC880_5ST },
-	{ .pci_vendor = 0x107b, .pci_device = 0x4039, .config = ALC880_5ST },
-	{ .pci_vendor = 0x107b, .pci_device = 0x3032, .config = ALC880_5ST },
-	{ .pci_vendor = 0x103c, .pci_device = 0x2a09, .config = ALC880_5ST },
+	spec->input_mux = &spec->private_imux;
 
-	/* Back 5 jack plus 1 SPDIF out jack, front 2 jack */
-	{ .modelname = "5stack-digout", .config = ALC880_5ST_DIG },
-	{ .pci_vendor = 0x8086, .pci_device = 0xe224, .config = ALC880_5ST_DIG },
-	{ .pci_vendor = 0x8086, .pci_device = 0xe400, .config = ALC880_5ST_DIG },
-	{ .pci_vendor = 0x8086, .pci_device = 0xe401, .config = ALC880_5ST_DIG },
-	{ .pci_vendor = 0x8086, .pci_device = 0xe402, .config = ALC880_5ST_DIG },
-	{ .pci_vendor = 0x8086, .pci_device = 0xd400, .config = ALC880_5ST_DIG },
-	{ .pci_vendor = 0x8086, .pci_device = 0xd401, .config = ALC880_5ST_DIG },
-	{ .pci_vendor = 0x8086, .pci_device = 0xa100, .config = ALC880_5ST_DIG },
-	{ .pci_vendor = 0x1565, .pci_device = 0x8202, .config = ALC880_5ST_DIG },
+	return 1;
+}
 
-	{ .modelname = "w810", .config = ALC880_W810 },
-	{ .pci_vendor = 0x161f, .pci_device = 0x203d, .config = ALC880_W810 },
+/* init callback for auto-configuration model -- overriding the default init */
+static int alc880_auto_init(struct hda_codec *codec)
+{
+	alc_init(codec);
+	alc880_auto_init_multi_out(codec);
+	alc880_auto_init_hp_out(codec);
+	alc880_auto_init_analog_input(codec);
+	return 0;
+}
 
-	{}
-};
+/*
+ * OK, here we have finally the patch for ALC880
+ */
 
 static int patch_alc880(struct hda_codec *codec)
 {
 	struct alc_spec *spec;
 	int board_config;
+	int i, err;
 
 	spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
 	if (spec == NULL)
 		return -ENOMEM;
 
+	init_MUTEX(&spec->bind_mutex);
 	codec->spec = spec;
 
 	board_config = snd_hda_check_board_config(codec, alc880_cfg_tbl);
-	if (board_config < 0) {
-		snd_printd(KERN_INFO "hda_codec: Unknown model for ALC880\n");
-		board_config = ALC880_MINIMAL;
+	if (board_config < 0 || board_config >= ALC880_MODEL_LAST) {
+		printk(KERN_INFO "hda_codec: Unknown model for ALC880, trying auto-probe from BIOS...\n");
+		board_config = ALC880_AUTO;
 	}
 
-	switch (board_config) {
-	case ALC880_W810:
-		spec->mixers[spec->num_mixers] = alc880_w810_base_mixer;
-		spec->num_mixers++;
-		break;
-	case ALC880_5ST:
-	case ALC880_5ST_DIG:
-		spec->mixers[spec->num_mixers] = alc880_five_stack_mixer;
-		spec->num_mixers++;
-		break;
-	default:
-		spec->mixers[spec->num_mixers] = alc880_base_mixer;
-		spec->num_mixers++;
-		break;
+	if (board_config == ALC880_AUTO) {
+		/* automatic parse from the BIOS config */
+		err = alc880_parse_auto_config(codec);
+		if (err < 0) {
+			alc_free(codec);
+			return err;
+		} else if (! err) {
+			printk(KERN_INFO "hda_codec: Cannot set up configuration from BIOS.  Using 3-stack mode...\n");
+			board_config = ALC880_3ST;
+		}
 	}
 
-	switch (board_config) {
-	case ALC880_3ST_DIG:
-	case ALC880_5ST_DIG:
-	case ALC880_W810:
-		spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
-		break;
-	default:
-		break;
-	}
+	if (board_config != ALC880_AUTO) {
+		/* set up from the preset table */
+		const struct alc_config_preset *preset;
+
+		preset = &alc880_presets[board_config];
+
+		for (i = 0; preset->mixers[i]; i++) {
+			snd_assert(spec->num_mixers < ARRAY_SIZE(spec->mixers), break);
+			spec->mixers[spec->num_mixers++] = preset->mixers[i];
+		}
+		for (i = 0; preset->init_verbs[i]; i++) {
+			snd_assert(spec->num_init_verbs < ARRAY_SIZE(spec->init_verbs), break);
+			spec->init_verbs[spec->num_init_verbs++] = preset->init_verbs[i];
+		}
 
-	switch (board_config) {
-	case ALC880_3ST:
-	case ALC880_3ST_DIG:
-	case ALC880_5ST:
-	case ALC880_5ST_DIG:
-	case ALC880_W810:
-		spec->front_panel = 1;
-		break;
-	default:
-		break;
-	}
+		spec->channel_mode = preset->channel_mode;
+		spec->num_channel_mode = preset->num_channel_mode;
 
-	switch (board_config) {
-	case ALC880_5ST:
-	case ALC880_5ST_DIG:
-		spec->init_verbs = alc880_init_verbs_five_stack;
-		spec->channel_mode = alc880_fivestack_modes;
-		spec->num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes);
-		break;
-	case ALC880_W810:
-		spec->init_verbs = alc880_w810_init_verbs;
-		spec->channel_mode = alc880_w810_modes;
-		spec->num_channel_mode = ARRAY_SIZE(alc880_w810_modes);
-		break;
-	default:
-		spec->init_verbs = alc880_init_verbs_three_stack;
-		spec->channel_mode = alc880_threestack_modes;
-		spec->num_channel_mode = ARRAY_SIZE(alc880_threestack_modes);
-		break;
+		spec->multiout.max_channels = spec->channel_mode[0].channels;
+
+		spec->multiout.num_dacs = preset->num_dacs;
+		spec->multiout.dac_nids = preset->dac_nids;
+		spec->multiout.dig_out_nid = preset->dig_out_nid;
+		spec->multiout.hp_nid = preset->hp_nid;
+
+		spec->input_mux = preset->input_mux;
+
+		spec->num_adc_nids = preset->num_adc_nids;
+		spec->adc_nids = preset->adc_nids;
 	}
 
 	spec->stream_name_analog = "ALC880 Analog";
@@ -1078,34 +2150,64 @@ static int patch_alc880(struct hda_codec
 	spec->stream_digital_playback = &alc880_pcm_digital_playback;
 	spec->stream_digital_capture = &alc880_pcm_digital_capture;
 
-	spec->multiout.max_channels = spec->channel_mode[0].channels;
-
-	switch (board_config) {
-	case ALC880_W810:
-		spec->multiout.num_dacs = ARRAY_SIZE(alc880_w810_dac_nids);
-		spec->multiout.dac_nids = alc880_w810_dac_nids;
-		// No dedicated headphone socket - it's shared with built-in speakers.
-		break;
-	default:
-		spec->multiout.num_dacs = ARRAY_SIZE(alc880_dac_nids);
-		spec->multiout.dac_nids = alc880_dac_nids;
-		spec->multiout.hp_nid = 0x03; /* rear-surround NID */
-		break;
+	if (! spec->adc_nids && spec->input_mux) {
+		/* check whether NID 0x07 is valid */
+		unsigned int wcap = snd_hda_param_read(codec, alc880_adc_nids[0],
+						       AC_PAR_AUDIO_WIDGET_CAP);
+		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
+		if (wcap != AC_WID_AUD_IN) {
+			spec->adc_nids = alc880_adc_nids_alt;
+			spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
+			spec->mixers[spec->num_mixers] = alc880_capture_alt_mixer;
+			spec->num_mixers++;
+		} else {
+			spec->adc_nids = alc880_adc_nids;
+			spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
+			spec->mixers[spec->num_mixers] = alc880_capture_mixer;
+			spec->num_mixers++;
+		}
 	}
 
-	spec->input_mux = &alc880_capture_source;
-	spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
-	spec->adc_nids = alc880_adc_nids;
-
 	codec->patch_ops = alc_patch_ops;
+	if (board_config == ALC880_AUTO)
+		codec->patch_ops.init = alc880_auto_init;
 
 	return 0;
 }
 
+
 /*
  * ALC260 support
  */
 
+static hda_nid_t alc260_dac_nids[1] = {
+	/* front */
+	0x02,
+};
+
+static hda_nid_t alc260_adc_nids[1] = {
+	/* ADC0 */
+	0x04,
+};
+
+static hda_nid_t alc260_hp_adc_nids[1] = {
+	/* ADC1 */
+	0x05,
+};
+
+#define ALC260_DIGOUT_NID	0x03
+#define ALC260_DIGIN_NID	0x06
+
+static struct hda_input_mux alc260_capture_source = {
+	.num_items = 4,
+	.items = {
+		{ "Mic", 0x0 },
+		{ "Front Mic", 0x1 },
+		{ "Line", 0x2 },
+		{ "CD", 0x4 },
+	},
+};
+
 /*
  * This is just place-holder, so there's something for alc_build_pcms to look
  * at when it calculates the maximum number of channels. ALC260 has no mixer
@@ -1116,11 +2218,9 @@ static struct alc_channel_mode alc260_mo
 	{ 2, NULL },
 };
 
-snd_kcontrol_new_t alc260_base_mixer[] = {
+static snd_kcontrol_new_t alc260_base_mixer[] = {
 	HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
-	/* use LINE2 for the output */
-	/* HDA_CODEC_MUTE("Front Playback Switch", 0x0f, 0x0, HDA_OUTPUT), */
-	HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
+	ALC_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
 	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
 	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
 	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
@@ -1132,9 +2232,9 @@ snd_kcontrol_new_t alc260_base_mixer[] =
 	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT),
 	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT),
 	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
-	HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
+	ALC_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
 	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
-	HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
+	ALC_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_OUTPUT),
 	HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT),
 	HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT),
 	{
@@ -1147,60 +2247,91 @@ snd_kcontrol_new_t alc260_base_mixer[] =
 	{ } /* end */
 };
 
+static snd_kcontrol_new_t alc260_hp_mixer[] = {
+	HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
+	ALC_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
+	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
+	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
+	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
+	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
+	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
+	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
+	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
+	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
+	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
+	ALC_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
+	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
+	ALC_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_OUTPUT),
+	HDA_CODEC_VOLUME("Capture Volume", 0x05, 0x0, HDA_INPUT),
+	HDA_CODEC_MUTE("Capture Switch", 0x05, 0x0, HDA_INPUT),
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Capture Source",
+		.info = alc_mux_enum_info,
+		.get = alc_mux_enum_get,
+		.put = alc_mux_enum_put,
+	},
+	{ } /* end */
+};
+
 static struct hda_verb alc260_init_verbs[] = {
 	/* Line In pin widget for input */
-	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
+	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
 	/* CD pin widget for input */
-	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
+	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
 	/* Mic1 (rear panel) pin widget for input and vref at 80% */
-	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
+	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
 	/* Mic2 (front panel) pin widget for input and vref at 80% */
-	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
+	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
 	/* LINE-2 is used for line-out in rear */
-	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
+	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 	/* select line-out */
 	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
 	/* LINE-OUT pin */
-	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
+	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 	/* enable HP */
-	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
+	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
 	/* enable Mono */
-	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
-	/* unmute amp left and right */
-	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
+	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+	/* mute capture amp left and right */
+	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 	/* set connection select to line in (default select for this ADC) */
 	{0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
-	/* unmute Line-Out mixer amp left and right (volume = 0) */
-	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
-	/* mute pin widget amp left and right (no gain on this amp) */
-	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
-	/* unmute HP mixer amp left and right (volume = 0) */
-	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
-	/* mute pin widget amp left and right (no gain on this amp) */
-	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
-	/* unmute Mono mixer amp left and right (volume = 0) */
-	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
-	/* mute pin widget amp left and right (no gain on this amp) */
-	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
-	/* mute LINE-2 out */
-	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
+	/* mute capture amp left and right */
+	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	/* set connection select to line in (default select for this ADC) */
+	{0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
+	/* set vol=0 Line-Out mixer amp left and right */
+	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
+	/* unmute pin widget amp left and right (no gain on this amp) */
+	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	/* set vol=0 HP mixer amp left and right */
+	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
+	/* unmute pin widget amp left and right (no gain on this amp) */
+	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	/* set vol=0 Mono mixer amp left and right */
+	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
+	/* unmute pin widget amp left and right (no gain on this amp) */
+	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	/* unmute LINE-2 out pin */
+	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03 */
-	/* unmute CD */
-	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
-	/* unmute Line In */
-	{0x07,  AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
-	/* unmute Mic */
-	{0x07,  AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
+	/* mute CD */
+	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
+	/* mute Line In */
+	{0x07,  AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
+	/* mute Mic */
+	{0x07,  AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 	/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
-	/* Unmute Front out path */
-	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
-	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
-	/* Unmute Headphone out path */
-	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
-	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
-	/* Unmute Mono out path */
-	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
-	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
+	/* mute Front out path */
+	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
+	/* mute Headphone out path */
+	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
+	/* mute Mono out path */
+	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
 	{ }
 };
 
@@ -1208,30 +2339,52 @@ static struct hda_pcm_stream alc260_pcm_
 	.substreams = 1,
 	.channels_min = 2,
 	.channels_max = 2,
-	.nid = 0x2,
 };
 
 static struct hda_pcm_stream alc260_pcm_analog_capture = {
 	.substreams = 1,
 	.channels_min = 2,
 	.channels_max = 2,
-	.nid = 0x4,
+};
+
+static struct hda_board_config alc260_cfg_tbl[] = {
+	{ .modelname = "hp", .config = ALC260_HP },
+	{ .pci_subvendor = 0x103c, .config = ALC260_HP },
+	{}
 };
 
 static int patch_alc260(struct hda_codec *codec)
 {
 	struct alc_spec *spec;
+	int board_config;
 
 	spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
 	if (spec == NULL)
 		return -ENOMEM;
 
+	init_MUTEX(&spec->bind_mutex);
 	codec->spec = spec;
 
-	spec->mixers[spec->num_mixers] = alc260_base_mixer;
-	spec->num_mixers++;
+	board_config = snd_hda_check_board_config(codec, alc260_cfg_tbl);
+	if (board_config < 0 || board_config >= ALC260_MODEL_LAST) {
+		snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260\n");
+		board_config = ALC260_BASIC;
+	}
+
+	switch (board_config) {
+	case ALC260_HP:
+		spec->mixers[spec->num_mixers] = alc260_hp_mixer;
+		spec->num_mixers++;
+		break;
+	default:
+		spec->mixers[spec->num_mixers] = alc260_base_mixer;
+		spec->num_mixers++;
+		break;
+	}
+
+	spec->init_verbs[0] = alc260_init_verbs;
+	spec->num_init_verbs = 1;
 
-	spec->init_verbs = alc260_init_verbs;
 	spec->channel_mode = alc260_modes;
 	spec->num_channel_mode = ARRAY_SIZE(alc260_modes);
 
@@ -1244,14 +2397,23 @@ static int patch_alc260(struct hda_codec
 	spec->multiout.dac_nids = alc260_dac_nids;
 
 	spec->input_mux = &alc260_capture_source;
-	spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
-	spec->adc_nids = alc260_adc_nids;
+	switch (board_config) {
+	case ALC260_HP:
+		spec->num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids);
+		spec->adc_nids = alc260_hp_adc_nids;
+		break;
+	default:
+		spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
+		spec->adc_nids = alc260_adc_nids;
+		break;
+	}
 
 	codec->patch_ops = alc_patch_ops;
 
 	return 0;
 }
 
+
 /*
  * ALC882 support
  *
@@ -1324,15 +2486,15 @@ static int alc882_mux_enum_put(snd_kcont
  */
 static snd_kcontrol_new_t alc882_base_mixer[] = {
 	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
-	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
+	ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
 	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
-	HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT),
+	ALC_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
 	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
 	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
-	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x16, 1, 0x0, HDA_OUTPUT),
-	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
+	ALC_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
+	ALC_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_OUTPUT),
 	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
-	HDA_CODEC_MUTE("Side Playback Switch", 0x17, 0x0, HDA_OUTPUT),
+	ALC_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
 	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
 	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
 	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
@@ -1364,89 +2526,80 @@ static snd_kcontrol_new_t alc882_base_mi
 
 static struct hda_verb alc882_init_verbs[] = {
 	/* Front mixer: unmute input/output amp left and right (volume = 0) */
-	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
-	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
+	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
+	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
 	/* Rear mixer */
-	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
-	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
+	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
+	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
 	/* CLFE mixer */
-	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
-	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
+	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
+	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
 	/* Side mixer */
-	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
-	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
-
-	/* Front Pin: to output mode */
-	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
-	/* Front Pin: mute amp left and right (no volume) */
-	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
-	/* select Front mixer (0x0c, index 0) */
+	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
+	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
+
+	/* Front Pin: output 0 (0x0c) */
+	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
-	/* Rear Pin */
-	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
-	/* Rear Pin: mute amp left and right (no volume) */
-	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
-	/* select Rear mixer (0x0d, index 1) */
+	/* Rear Pin: output 1 (0x0d) */
+	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
-	/* CLFE Pin */
-	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
-	/* CLFE Pin: mute amp left and right (no volume) */
-	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
-	/* select CLFE mixer (0x0e, index 2) */
+	/* CLFE Pin: output 2 (0x0e) */
+	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 	{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
-	/* Side Pin */
-	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
-	/* Side Pin: mute amp left and right (no volume) */
-	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
-	/* select Side mixer (0x0f, index 3) */
+	/* Side Pin: output 3 (0x0f) */
+	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
-	/* Headphone Pin */
-	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
-	/* Headphone Pin: mute amp left and right (no volume) */
-	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
-	/* select Front mixer (0x0c, index 0) */
+	/* Mic (rear) pin: input vref at 80% */
+	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
+	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+	/* Front Mic pin: input vref at 80% */
+	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
+	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+	/* Line In pin: input */
+	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+	/* Line-2 In: Headphone output (output 0 - 0x0c) */
+	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
-	/* Mic (rear) pin widget for input and vref at 80% */
-	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
-	/* Front Mic pin widget for input and vref at 80% */
-	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
-	/* Line In pin widget for input */
-	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
 	/* CD pin widget for input */
-	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
+	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
 
 	/* FIXME: use matrix-type input source selection */
 	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
 	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
-	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
-	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
-	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
-	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
+	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
+	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
+	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
 	/* Input mixer2 */
-	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
-	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
-	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
-	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
+	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
+	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
+	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
 	/* Input mixer3 */
-	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
-	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
-	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
-	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
-	/* ADC1: unmute amp left and right */
-	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
-	/* ADC2: unmute amp left and right */
-	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
-	/* ADC3: unmute amp left and right */
-	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
-
-	/* Unmute front loopback */
-	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
-	/* Unmute rear loopback */
-	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
-	/* Mute CLFE loopback */
-	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
-	/* Unmute side loopback */
-	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
+	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
+	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
+	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
+	/* ADC1: mute amp left and right */
+	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
+	/* ADC2: mute amp left and right */
+	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
+	/* ADC3: mute amp left and right */
+	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
 
 	{ }
 };
@@ -1459,6 +2612,7 @@ static int patch_alc882(struct hda_codec
 	if (spec == NULL)
 		return -ENOMEM;
 
+	init_MUTEX(&spec->bind_mutex);
 	codec->spec = spec;
 
 	spec->mixers[spec->num_mixers] = alc882_base_mixer;
@@ -1466,8 +2620,9 @@ static int patch_alc882(struct hda_codec
 
 	spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
 	spec->dig_in_nid = ALC880_DIGIN_NID;
-	spec->front_panel = 1;
-	spec->init_verbs = alc882_init_verbs;
+	spec->init_verbs[0] = alc882_init_verbs;
+	spec->num_init_verbs = 1;
+
 	spec->channel_mode = alc882_ch_modes;
 	spec->num_channel_mode = ARRAY_SIZE(alc882_ch_modes);
 
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
new file mode 100644
--- /dev/null
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -0,0 +1,1004 @@
+/*
+ * Universal Interface for Intel High Definition Audio Codec
+ *
+ * HD audio interface patch for SigmaTel STAC92xx
+ *
+ * Copyright (c) 2005 Embedded Alley Solutions, Inc.
+ * <matt@embeddedalley.com>
+ *
+ * Based on patch_cmedia.c and patch_realtek.c
+ * Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
+ *
+ *  This driver 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 driver 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 <sound/driver.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/pci.h>
+#include <sound/core.h>
+#include <sound/asoundef.h>
+#include "hda_codec.h"
+#include "hda_local.h"
+
+#undef STAC_TEST
+
+#define NUM_CONTROL_ALLOC	32
+#define STAC_HP_EVENT		0x37
+#define STAC_UNSOL_ENABLE 	(AC_USRSP_EN | STAC_HP_EVENT)
+
+struct sigmatel_spec {
+	snd_kcontrol_new_t *mixers[4];
+	unsigned int num_mixers;
+
+	unsigned int surr_switch: 1;
+
+	/* playback */
+	struct hda_multi_out multiout;
+	hda_nid_t dac_nids[4];
+
+	/* capture */
+	hda_nid_t *adc_nids;
+	unsigned int num_adcs;
+	hda_nid_t *mux_nids;
+	unsigned int num_muxes;
+	hda_nid_t dig_in_nid;
+
+#ifdef STAC_TEST
+	/* pin widgets */
+	hda_nid_t *pin_nids;
+	unsigned int num_pins;
+	unsigned int *pin_configs;
+#endif
+
+	/* codec specific stuff */
+	struct hda_verb *init;
+	snd_kcontrol_new_t *mixer;
+
+	/* capture source */
+	struct hda_input_mux *input_mux;
+	unsigned int cur_mux[2];
+
+	/* channel mode */
+	unsigned int num_ch_modes;
+	unsigned int cur_ch_mode;
+
+	struct hda_pcm pcm_rec[2];	/* PCM information */
+
+	/* dynamic controls and input_mux */
+	struct auto_pin_cfg autocfg;
+	unsigned int num_kctl_alloc, num_kctl_used;
+	snd_kcontrol_new_t *kctl_alloc;
+	struct hda_input_mux private_imux;
+};
+
+static hda_nid_t stac9200_adc_nids[1] = {
+        0x03,
+};
+
+static hda_nid_t stac9200_mux_nids[1] = {
+        0x0c,
+};
+
+static hda_nid_t stac9200_dac_nids[1] = {
+        0x02,
+};
+
+static hda_nid_t stac922x_adc_nids[2] = {
+        0x06, 0x07,
+};
+
+static hda_nid_t stac922x_mux_nids[2] = {
+        0x12, 0x13,
+};
+
+#ifdef STAC_TEST
+static hda_nid_t stac9200_pin_nids[8] = {
+	0x08, 0x09, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12,
+};
+
+static hda_nid_t stac922x_pin_nids[10] = {
+	0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
+	0x0f, 0x10, 0x11, 0x15, 0x1b,
+};
+#endif
+
+static int stac92xx_mux_enum_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+{
+	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct sigmatel_spec *spec = codec->spec;
+	return snd_hda_input_mux_info(spec->input_mux, uinfo);
+}
+
+static int stac92xx_mux_enum_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct sigmatel_spec *spec = codec->spec;
+	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
+
+	ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
+	return 0;
+}
+
+static int stac92xx_mux_enum_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct sigmatel_spec *spec = codec->spec;
+	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
+
+	return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
+				     spec->mux_nids[adc_idx], &spec->cur_mux[adc_idx]);
+}
+
+static struct hda_verb stac9200_core_init[] = {
+	/* set dac0mux for dac converter */
+	{ 0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
+	{}
+};
+
+static struct hda_verb stac922x_core_init[] = {
+	/* set master volume and direct control */	
+	{ 0x16, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
+	{}
+};
+
+static int stac922x_channel_modes[3] = {2, 6, 8};
+
+static int stac922x_ch_mode_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+{
+	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct sigmatel_spec *spec = codec->spec;
+
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+	uinfo->count = 1;
+	uinfo->value.enumerated.items = spec->num_ch_modes;
+	if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
+		uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
+	sprintf(uinfo->value.enumerated.name, "%dch",
+		stac922x_channel_modes[uinfo->value.enumerated.item]);
+	return 0;
+}
+
+static int stac922x_ch_mode_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct sigmatel_spec *spec = codec->spec;
+
+	ucontrol->value.enumerated.item[0] = spec->cur_ch_mode;
+	return 0;
+}
+
+static int stac922x_ch_mode_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct sigmatel_spec *spec = codec->spec;
+
+	if (ucontrol->value.enumerated.item[0] >= spec->num_ch_modes)
+		ucontrol->value.enumerated.item[0] = spec->num_ch_modes;
+	if (ucontrol->value.enumerated.item[0] == spec->cur_ch_mode &&
+	    ! codec->in_resume)
+		return 0;
+
+	spec->cur_ch_mode = ucontrol->value.enumerated.item[0];
+	spec->multiout.max_channels = stac922x_channel_modes[spec->cur_ch_mode];
+
+	return 1;
+}
+
+static snd_kcontrol_new_t stac9200_mixer[] = {
+	HDA_CODEC_VOLUME("Master Playback Volume", 0xb, 0, HDA_OUTPUT),
+	HDA_CODEC_MUTE("Master Playback Switch", 0xb, 0, HDA_OUTPUT),
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Input Source",
+		.count = 1,
+		.info = stac92xx_mux_enum_info,
+		.get = stac92xx_mux_enum_get,
+		.put = stac92xx_mux_enum_put,
+	},
+	HDA_CODEC_VOLUME("Capture Volume", 0x0a, 0, HDA_OUTPUT),
+	HDA_CODEC_MUTE("Capture Switch", 0x0a, 0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME("Capture Mux Volume", 0x0c, 0, HDA_OUTPUT),
+	{ } /* end */
+};
+
+/* This needs to be generated dynamically based on sequence */
+static snd_kcontrol_new_t stac922x_mixer[] = {
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Input Source",
+		.count = 1,
+		.info = stac92xx_mux_enum_info,
+		.get = stac92xx_mux_enum_get,
+		.put = stac92xx_mux_enum_put,
+	},
+	HDA_CODEC_VOLUME("Capture Volume", 0x17, 0x0, HDA_INPUT),
+	HDA_CODEC_MUTE("Capture Switch", 0x17, 0x0, HDA_INPUT),
+	HDA_CODEC_VOLUME("Mux Capture Volume", 0x12, 0x0, HDA_OUTPUT),
+	{ } /* end */
+};
+
+static snd_kcontrol_new_t stac922x_ch_mode_mixer[] = {
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Channel Mode",
+		.info = stac922x_ch_mode_info,
+		.get = stac922x_ch_mode_get,
+		.put = stac922x_ch_mode_put,
+	},
+	{ } /* end */
+};
+
+static int stac92xx_build_controls(struct hda_codec *codec)
+{
+	struct sigmatel_spec *spec = codec->spec;
+	int err;
+	int i;
+
+	err = snd_hda_add_new_ctls(codec, spec->mixer);
+	if (err < 0)
+		return err;
+
+	for (i = 0; i < spec->num_mixers; i++) {
+		err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
+		if (err < 0)
+			return err;
+	}
+
+	if (spec->surr_switch) {
+		err = snd_hda_add_new_ctls(codec, stac922x_ch_mode_mixer);
+		if (err < 0)
+			return err;
+	}
+	if (spec->multiout.dig_out_nid) {
+		err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid);
+		if (err < 0)
+			return err;
+	}
+	if (spec->dig_in_nid) {
+		err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
+		if (err < 0)
+			return err;
+	}
+	return 0;	
+}
+
+#ifdef STAC_TEST
+static unsigned int stac9200_pin_configs[8] = {
+	0x01c47010, 0x01447010, 0x0221401f, 0x01114010,
+	0x02a19020, 0x01a19021, 0x90100140, 0x01813122,
+};
+
+static unsigned int stac922x_pin_configs[10] = {
+	0x01014010, 0x01014011, 0x01014012, 0x0221401f,
+	0x01813122, 0x01014014, 0x01441030, 0x01c41030,
+	0x40000100, 0x40000100,
+};
+
+static void stac92xx_set_config_regs(struct hda_codec *codec)
+{
+	int i;
+	struct sigmatel_spec *spec = codec->spec;
+	unsigned int pin_cfg;
+
+	for (i=0; i < spec->num_pins; i++) {
+		snd_hda_codec_write(codec, spec->pin_nids[i], 0,
+				    AC_VERB_SET_CONFIG_DEFAULT_BYTES_0,
+				    spec->pin_configs[i] & 0x000000ff);
+		snd_hda_codec_write(codec, spec->pin_nids[i], 0,
+				    AC_VERB_SET_CONFIG_DEFAULT_BYTES_1,
+				    (spec->pin_configs[i] & 0x0000ff00) >> 8);
+		snd_hda_codec_write(codec, spec->pin_nids[i], 0,
+				    AC_VERB_SET_CONFIG_DEFAULT_BYTES_2,
+				    (spec->pin_configs[i] & 0x00ff0000) >> 16);
+		snd_hda_codec_write(codec, spec->pin_nids[i], 0,
+				    AC_VERB_SET_CONFIG_DEFAULT_BYTES_3,
+				    spec->pin_configs[i] >> 24);
+		pin_cfg = snd_hda_codec_read(codec, spec->pin_nids[i], 0,
+					     AC_VERB_GET_CONFIG_DEFAULT,
+					     0x00);	
+		printk("pin nid %2.2x pin config %8.8x\n", spec->pin_nids[i], pin_cfg);
+	}
+}
+#endif
+
+/*
+ * Analog playback callbacks
+ */
+static int stac92xx_playback_pcm_open(struct hda_pcm_stream *hinfo,
+				      struct hda_codec *codec,
+				      snd_pcm_substream_t *substream)
+{
+	struct sigmatel_spec *spec = codec->spec;
+	return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream);
+}
+
+/*
+ * set up the i/o for analog out
+ * when the digital out is available, copy the front out to digital out, too.
+ */
+static int stac92xx_multi_out_analog_prepare(struct hda_codec *codec, struct hda_multi_out *mout,
+				     unsigned int stream_tag,
+				     unsigned int format,
+				     snd_pcm_substream_t *substream)
+{
+	hda_nid_t *nids = mout->dac_nids;
+	int chs = substream->runtime->channels;
+	int i;
+
+	down(&codec->spdif_mutex);
+	if (mout->dig_out_nid && mout->dig_out_used != HDA_DIG_EXCLUSIVE) {
+		if (chs == 2 &&
+		    snd_hda_is_supported_format(codec, mout->dig_out_nid, format) &&
+		    ! (codec->spdif_status & IEC958_AES0_NONAUDIO)) {
+			mout->dig_out_used = HDA_DIG_ANALOG_DUP;
+			/* setup digital receiver */
+			snd_hda_codec_setup_stream(codec, mout->dig_out_nid,
+						   stream_tag, 0, format);
+		} else {
+			mout->dig_out_used = 0;
+			snd_hda_codec_setup_stream(codec, mout->dig_out_nid, 0, 0, 0);
+		}
+	}
+	up(&codec->spdif_mutex);
+
+	/* front */
+	snd_hda_codec_setup_stream(codec, nids[HDA_FRONT], stream_tag, 0, format);
+	if (mout->hp_nid)
+		/* headphone out will just decode front left/right (stereo) */
+		snd_hda_codec_setup_stream(codec, mout->hp_nid, stream_tag, 0, format);
+	/* surrounds */
+	if (mout->max_channels > 2)
+		for (i = 1; i < mout->num_dacs; i++) {
+			if ((mout->max_channels == 6) && (i == 3))
+				break;
+			if (chs >= (i + 1) * 2) /* independent out */
+				snd_hda_codec_setup_stream(codec, nids[i], stream_tag, i * 2,
+						format);
+			else /* copy front */
+				snd_hda_codec_setup_stream(codec, nids[i], stream_tag, 0,
+						format);
+		}
+	return 0;
+}
+
+
+static int stac92xx_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
+					 struct hda_codec *codec,
+					 unsigned int stream_tag,
+					 unsigned int format,
+					 snd_pcm_substream_t *substream)
+{
+	struct sigmatel_spec *spec = codec->spec;
+	return stac92xx_multi_out_analog_prepare(codec, &spec->multiout, stream_tag,
+						format, substream);
+}
+
+static int stac92xx_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
+					struct hda_codec *codec,
+					snd_pcm_substream_t *substream)
+{
+	struct sigmatel_spec *spec = codec->spec;
+	return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
+}
+
+/*
+ * Digital playback callbacks
+ */
+static int stac92xx_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
+					  struct hda_codec *codec,
+					  snd_pcm_substream_t *substream)
+{
+	struct sigmatel_spec *spec = codec->spec;
+	return snd_hda_multi_out_dig_open(codec, &spec->multiout);
+}
+
+static int stac92xx_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
+					   struct hda_codec *codec,
+					   snd_pcm_substream_t *substream)
+{
+	struct sigmatel_spec *spec = codec->spec;
+	return snd_hda_multi_out_dig_close(codec, &spec->multiout);
+}
+
+
+/*
+ * Analog capture callbacks
+ */
+static int stac92xx_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
+					struct hda_codec *codec,
+					unsigned int stream_tag,
+					unsigned int format,
+					snd_pcm_substream_t *substream)
+{
+	struct sigmatel_spec *spec = codec->spec;
+
+	snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
+                                   stream_tag, 0, format);
+	return 0;
+}
+
+static int stac92xx_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
+					struct hda_codec *codec,
+					snd_pcm_substream_t *substream)
+{
+	struct sigmatel_spec *spec = codec->spec;
+
+	snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number], 0, 0, 0);
+	return 0;
+}
+
+static struct hda_pcm_stream stac92xx_pcm_digital_playback = {
+	.substreams = 1,
+	.channels_min = 2,
+	.channels_max = 2,
+	/* NID is set in stac92xx_build_pcms */
+	.ops = {
+		.open = stac92xx_dig_playback_pcm_open,
+		.close = stac92xx_dig_playback_pcm_close
+	},
+};
+
+static struct hda_pcm_stream stac92xx_pcm_digital_capture = {
+	.substreams = 1,
+	.channels_min = 2,
+	.channels_max = 2,
+	/* NID is set in stac92xx_build_pcms */
+};
+
+static struct hda_pcm_stream stac92xx_pcm_analog_playback = {
+	.substreams = 1,
+	.channels_min = 2,
+	.channels_max = 8,
+	.nid = 0x02, /* NID to query formats and rates */
+	.ops = {
+		.open = stac92xx_playback_pcm_open,
+		.prepare = stac92xx_playback_pcm_prepare,
+		.cleanup = stac92xx_playback_pcm_cleanup
+	},
+};
+
+static struct hda_pcm_stream stac92xx_pcm_analog_capture = {
+	.substreams = 2,
+	.channels_min = 2,
+	.channels_max = 2,
+	.nid = 0x06, /* NID to query formats and rates */
+	.ops = {
+		.prepare = stac92xx_capture_pcm_prepare,
+		.cleanup = stac92xx_capture_pcm_cleanup
+	},
+};
+
+static int stac92xx_build_pcms(struct hda_codec *codec)
+{
+	struct sigmatel_spec *spec = codec->spec;
+	struct hda_pcm *info = spec->pcm_rec;
+
+	codec->num_pcms = 1;
+	codec->pcm_info = info;
+
+	info->name = "STAC92xx Analog";
+	info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_analog_playback;
+	info->stream[SNDRV_PCM_STREAM_CAPTURE] = stac92xx_pcm_analog_capture;
+
+	if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
+		codec->num_pcms++;
+		info++;
+		info->name = "STAC92xx Digital";
+		if (spec->multiout.dig_out_nid) {
+			info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_digital_playback;
+			info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
+		}
+		if (spec->dig_in_nid) {
+			info->stream[SNDRV_PCM_STREAM_CAPTURE] = stac92xx_pcm_digital_capture;
+			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
+		}
+	}
+
+	return 0;
+}
+
+enum {
+	STAC_CTL_WIDGET_VOL,
+	STAC_CTL_WIDGET_MUTE,
+};
+
+static snd_kcontrol_new_t stac92xx_control_templates[] = {
+	HDA_CODEC_VOLUME(NULL, 0, 0, 0),
+	HDA_CODEC_MUTE(NULL, 0, 0, 0),
+};
+
+/* add dynamic controls */
+static int stac92xx_add_control(struct sigmatel_spec *spec, int type, const char *name, unsigned long val)
+{
+	snd_kcontrol_new_t *knew;
+
+	if (spec->num_kctl_used >= spec->num_kctl_alloc) {
+		int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;
+
+		knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL); /* array + terminator */
+		if (! knew)
+			return -ENOMEM;
+		if (spec->kctl_alloc) {
+			memcpy(knew, spec->kctl_alloc, sizeof(*knew) * spec->num_kctl_alloc);
+			kfree(spec->kctl_alloc);
+		}
+		spec->kctl_alloc = knew;
+		spec->num_kctl_alloc = num;
+	}
+
+	knew = &spec->kctl_alloc[spec->num_kctl_used];
+	*knew = stac92xx_control_templates[type];
+	knew->name = kstrdup(name, GFP_KERNEL);
+	if (! knew->name)
+		return -ENOMEM;
+	knew->private_value = val;
+	spec->num_kctl_used++;
+	return 0;
+}
+
+/* fill in the dac_nids table from the parsed pin configuration */
+static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec, const struct auto_pin_cfg *cfg)
+{
+	struct sigmatel_spec *spec = codec->spec;
+	hda_nid_t nid;
+	int i;
+
+	/* check the pins hardwired to audio widget */
+	for (i = 0; i < cfg->line_outs; i++) {
+		nid = cfg->line_out_pins[i];
+		spec->multiout.dac_nids[i] = snd_hda_codec_read(codec, nid, 0,
+					AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
+	}
+
+	spec->multiout.num_dacs = cfg->line_outs;
+
+	return 0;
+}
+
+/* add playback controls from the parsed DAC table */
+static int stac92xx_auto_create_multi_out_ctls(struct sigmatel_spec *spec, const struct auto_pin_cfg *cfg)
+{
+	char name[32];
+	static const char *chname[4] = { "Front", "Surround", NULL /*CLFE*/, "Side" };
+	hda_nid_t nid;
+	int i, err;
+
+	for (i = 0; i < cfg->line_outs; i++) {
+		if (! spec->multiout.dac_nids[i])
+			continue;
+
+		nid = spec->multiout.dac_nids[i];
+
+		if (i == 2) {
+			/* Center/LFE */
+			if ((err = stac92xx_add_control(spec, STAC_CTL_WIDGET_VOL, "Center Playback Volume",
+					       HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT))) < 0)
+				return err;
+			if ((err = stac92xx_add_control(spec, STAC_CTL_WIDGET_VOL, "LFE Playback Volume",
+					       HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0)
+				return err;
+			if ((err = stac92xx_add_control(spec, STAC_CTL_WIDGET_MUTE, "Center Playback Switch",
+					       HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT))) < 0)
+				return err;
+			if ((err = stac92xx_add_control(spec, STAC_CTL_WIDGET_MUTE, "LFE Playback Switch",
+					       HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0)
+				return err;
+		} else {
+			sprintf(name, "%s Playback Volume", chname[i]);
+			if ((err = stac92xx_add_control(spec, STAC_CTL_WIDGET_VOL, name,
+					       HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
+				return err;
+			sprintf(name, "%s Playback Switch", chname[i]);
+			if ((err = stac92xx_add_control(spec, STAC_CTL_WIDGET_MUTE, name,
+					       HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
+				return err;
+		}
+	}
+
+	return 0;
+}
+
+/* add playback controls for HP output */
+static int stac92xx_auto_create_hp_ctls(struct hda_codec *codec, struct auto_pin_cfg *cfg)
+{
+	struct sigmatel_spec *spec = codec->spec;
+	hda_nid_t pin = cfg->hp_pin;
+	hda_nid_t nid;
+	int i, err;
+	unsigned int wid_caps;
+
+	if (! pin)
+		return 0;
+
+	wid_caps = snd_hda_param_read(codec, pin, AC_PAR_AUDIO_WIDGET_CAP);
+	if (wid_caps & AC_WCAP_UNSOL_CAP)
+		/* Enable unsolicited responses on the HP widget */
+		snd_hda_codec_write(codec, pin, 0,
+				AC_VERB_SET_UNSOLICITED_ENABLE,
+				STAC_UNSOL_ENABLE);
+
+	nid = snd_hda_codec_read(codec, pin, 0, AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
+	for (i = 0; i < cfg->line_outs; i++) {
+		if (! spec->multiout.dac_nids[i])
+			continue;
+		if (spec->multiout.dac_nids[i] == nid)
+			return 0;
+	}
+
+	spec->multiout.hp_nid = nid;
+
+	/* control HP volume/switch on the output mixer amp */
+	if ((err = stac92xx_add_control(spec, STAC_CTL_WIDGET_VOL, "Headphone Playback Volume",
+					HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
+		return err;
+	if ((err = stac92xx_add_control(spec, STAC_CTL_WIDGET_MUTE, "Headphone Playback Switch",
+					HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
+		return err;
+
+	return 0;
+}
+
+/* create playback/capture controls for input pins */
+static int stac92xx_auto_create_analog_input_ctls(struct hda_codec *codec, const struct auto_pin_cfg *cfg)
+{
+	struct sigmatel_spec *spec = codec->spec;
+	static char *labels[AUTO_PIN_LAST] = {
+		"Mic", "Front Mic", "Line", "Front Line", "CD", "Aux"
+	};
+	struct hda_input_mux *imux = &spec->private_imux;
+	hda_nid_t con_lst[HDA_MAX_NUM_INPUTS];
+	int i, j, k;
+
+	for (i = 0; i < AUTO_PIN_LAST; i++) {
+		int index = -1;
+		if (cfg->input_pins[i]) {
+			imux->items[imux->num_items].label = labels[i];
+
+			for (j=0; j<spec->num_muxes; j++) {
+				int num_cons = snd_hda_get_connections(codec, spec->mux_nids[j], con_lst, HDA_MAX_NUM_INPUTS);
+				for (k=0; k<num_cons; k++)
+					if (con_lst[k] == cfg->input_pins[i]) {
+						index = k;
+					 	break;
+					}
+				if (index >= 0)
+					break;
+			}
+			imux->items[imux->num_items].index = index;
+			imux->num_items++;
+		}
+	}
+
+	return 0;
+}
+
+static void stac92xx_auto_set_pinctl(struct hda_codec *codec, hda_nid_t nid, int pin_type)
+
+{
+	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
+}
+
+static void stac92xx_auto_init_multi_out(struct hda_codec *codec)
+{
+	struct sigmatel_spec *spec = codec->spec;
+	int i;
+
+	for (i = 0; i < spec->autocfg.line_outs; i++) {
+		hda_nid_t nid = spec->autocfg.line_out_pins[i];
+		stac92xx_auto_set_pinctl(codec, nid, AC_PINCTL_OUT_EN);
+	}
+}
+
+static void stac92xx_auto_init_hp_out(struct hda_codec *codec)
+{
+	struct sigmatel_spec *spec = codec->spec;
+	hda_nid_t pin;
+
+	pin = spec->autocfg.hp_pin;
+	if (pin) /* connect to front */
+		stac92xx_auto_set_pinctl(codec, pin, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN);
+}
+
+static int stac922x_parse_auto_config(struct hda_codec *codec)
+{
+	struct sigmatel_spec *spec = codec->spec;
+	int err;
+
+	if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg)) < 0)
+		return err;
+	if ((err = stac92xx_auto_fill_dac_nids(codec, &spec->autocfg)) < 0)
+		return err;
+	if (! spec->autocfg.line_outs && ! spec->autocfg.hp_pin)
+		return 0; /* can't find valid pin config */
+
+	if ((err = stac92xx_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 ||
+	    (err = stac92xx_auto_create_hp_ctls(codec, &spec->autocfg)) < 0 ||
+	    (err = stac92xx_auto_create_analog_input_ctls(codec, &spec->autocfg)) < 0)
+		return err;
+
+	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
+	if (spec->multiout.max_channels > 2) {
+		spec->surr_switch = 1;
+		spec->cur_ch_mode = 1;
+		spec->num_ch_modes = 2;
+		if (spec->multiout.max_channels == 8) {
+			spec->cur_ch_mode++;
+			spec->num_ch_modes++;
+		}
+	}
+
+	if (spec->autocfg.dig_out_pin) {
+		spec->multiout.dig_out_nid = 0x08;
+		stac92xx_auto_set_pinctl(codec, spec->autocfg.dig_out_pin, AC_PINCTL_OUT_EN);
+	}
+	if (spec->autocfg.dig_in_pin) {
+		spec->dig_in_nid = 0x09;
+		stac92xx_auto_set_pinctl(codec, spec->autocfg.dig_in_pin, AC_PINCTL_IN_EN);
+	}
+
+	if (spec->kctl_alloc)
+		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
+
+	spec->input_mux = &spec->private_imux;
+
+	return 1;
+}
+
+static int stac9200_parse_auto_config(struct hda_codec *codec)
+{
+	struct sigmatel_spec *spec = codec->spec;
+	int err;
+
+	if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg)) < 0)
+		return err;
+
+	if ((err = stac92xx_auto_create_analog_input_ctls(codec, &spec->autocfg)) < 0)
+		return err;
+
+	if (spec->autocfg.dig_out_pin) {
+		spec->multiout.dig_out_nid = 0x05;
+		stac92xx_auto_set_pinctl(codec, spec->autocfg.dig_out_pin, AC_PINCTL_OUT_EN);
+	}
+	if (spec->autocfg.dig_in_pin) {
+		spec->dig_in_nid = 0x04;
+		stac92xx_auto_set_pinctl(codec, spec->autocfg.dig_in_pin, AC_PINCTL_IN_EN);
+	}
+
+	if (spec->kctl_alloc)
+		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
+
+	spec->input_mux = &spec->private_imux;
+
+	return 1;
+}
+
+static int stac92xx_init_pstate(struct hda_codec *codec)
+{
+       hda_nid_t nid, nid_start;
+       int nodes;
+
+	snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_POWER_STATE, 0x00);
+
+       nodes = snd_hda_get_sub_nodes(codec, codec->afg, &nid_start);
+       for (nid = nid_start; nid < nodes + nid_start; nid++) {
+               unsigned int wid_caps = snd_hda_param_read(codec, nid,
+                                                  AC_PAR_AUDIO_WIDGET_CAP);
+		if (wid_caps & AC_WCAP_POWER)
+			snd_hda_codec_write(codec, nid, 0,
+                                    AC_VERB_SET_POWER_STATE, 0x00);
+	}
+
+	mdelay(100);
+
+	return 0;
+}
+
+static int stac92xx_init(struct hda_codec *codec)
+{
+	struct sigmatel_spec *spec = codec->spec;
+
+	stac92xx_init_pstate(codec);
+
+	snd_hda_sequence_write(codec, spec->init);
+
+	stac92xx_auto_init_multi_out(codec);
+	stac92xx_auto_init_hp_out(codec);
+
+	return 0;
+}
+
+static void stac92xx_free(struct hda_codec *codec)
+{
+	struct sigmatel_spec *spec = codec->spec;
+	int i;
+
+	if (! spec)
+		return;
+
+	if (spec->kctl_alloc) {
+		for (i = 0; i < spec->num_kctl_used; i++)
+			kfree(spec->kctl_alloc[i].name);
+		kfree(spec->kctl_alloc);
+	}
+
+	kfree(spec);
+}
+
+static void stac92xx_set_pinctl(struct hda_codec *codec, hda_nid_t nid,
+				unsigned int flag)
+{
+	unsigned int pin_ctl = snd_hda_codec_read(codec, nid,
+			0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00);
+	snd_hda_codec_write(codec, nid, 0,
+			AC_VERB_SET_PIN_WIDGET_CONTROL,
+			pin_ctl | flag);
+}
+
+static void stac92xx_reset_pinctl(struct hda_codec *codec, hda_nid_t nid,
+				  unsigned int flag)
+{
+	unsigned int pin_ctl = snd_hda_codec_read(codec, nid,
+			0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00);
+	snd_hda_codec_write(codec, nid, 0,
+			AC_VERB_SET_PIN_WIDGET_CONTROL,
+			pin_ctl & ~flag);
+}
+
+static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res)
+{
+	struct sigmatel_spec *spec = codec->spec;
+	struct auto_pin_cfg *cfg = &spec->autocfg;
+	int i, presence;
+
+	if ((res >> 26) != STAC_HP_EVENT)
+		return;
+
+	presence = snd_hda_codec_read(codec, cfg->hp_pin, 0,
+			AC_VERB_GET_PIN_SENSE, 0x00) >> 31;
+
+	if (presence) {
+		/* disable lineouts, enable hp */
+		for (i = 0; i < cfg->line_outs; i++)
+			stac92xx_reset_pinctl(codec, cfg->line_out_pins[i],
+						AC_PINCTL_OUT_EN);
+		stac92xx_set_pinctl(codec, cfg->hp_pin, AC_PINCTL_OUT_EN);
+	} else {
+		/* enable lineouts, disable hp */
+		for (i = 0; i < cfg->line_outs; i++)
+			stac92xx_set_pinctl(codec, cfg->line_out_pins[i],
+						AC_PINCTL_OUT_EN);
+		stac92xx_reset_pinctl(codec, cfg->hp_pin, AC_PINCTL_OUT_EN);
+	}
+} 
+
+#ifdef CONFIG_PM
+static int stac92xx_resume(struct hda_codec *codec)
+{
+	struct sigmatel_spec *spec = codec->spec;
+	int i;
+
+	stac92xx_init(codec);
+	for (i = 0; i < spec->num_mixers; i++)
+		snd_hda_resume_ctls(codec, spec->mixers[i]);
+	if (spec->multiout.dig_out_nid)
+		snd_hda_resume_spdif_out(codec);
+	if (spec->dig_in_nid)
+		snd_hda_resume_spdif_in(codec);
+
+	return 0;
+}
+#endif
+
+static struct hda_codec_ops stac92xx_patch_ops = {
+	.build_controls = stac92xx_build_controls,
+	.build_pcms = stac92xx_build_pcms,
+	.init = stac92xx_init,
+	.free = stac92xx_free,
+	.unsol_event = stac92xx_unsol_event,
+#ifdef CONFIG_PM
+	.resume = stac92xx_resume,
+#endif
+};
+
+static int patch_stac9200(struct hda_codec *codec)
+{
+	struct sigmatel_spec *spec;
+	int err;
+
+	spec  = kcalloc(1, sizeof(*spec), GFP_KERNEL);
+	if (spec == NULL)
+		return -ENOMEM;
+
+	codec->spec = spec;
+
+#ifdef STAC_TEST
+	spec->pin_nids = stac9200_pin_nids;
+	spec->num_pins = 8;
+	spec->pin_configs = stac9200_pin_configs;
+	stac92xx_set_config_regs(codec);
+#endif
+	spec->multiout.max_channels = 2;
+	spec->multiout.num_dacs = 1;
+	spec->multiout.dac_nids = stac9200_dac_nids;
+	spec->adc_nids = stac9200_adc_nids;
+	spec->mux_nids = stac9200_mux_nids;
+	spec->num_muxes = 1;
+
+	spec->init = stac9200_core_init;
+	spec->mixer = stac9200_mixer;
+
+	err = stac9200_parse_auto_config(codec);
+	if (err < 0) {
+		stac92xx_free(codec);
+		return err;
+	}
+
+	codec->patch_ops = stac92xx_patch_ops;
+
+	return 0;
+}
+
+static int patch_stac922x(struct hda_codec *codec)
+{
+	struct sigmatel_spec *spec;
+	int err;
+
+	spec  = kcalloc(1, sizeof(*spec), GFP_KERNEL);
+	if (spec == NULL)
+		return -ENOMEM;
+
+	codec->spec = spec;
+
+#ifdef STAC_TEST
+	spec->num_pins = 10;
+	spec->pin_nids = stac922x_pin_nids;
+	spec->pin_configs = stac922x_pin_configs;
+	stac92xx_set_config_regs(codec);
+#endif
+	spec->adc_nids = stac922x_adc_nids;
+	spec->mux_nids = stac922x_mux_nids;
+	spec->num_muxes = 2;
+
+	spec->init = stac922x_core_init;
+	spec->mixer = stac922x_mixer;
+
+	spec->multiout.dac_nids = spec->dac_nids;
+
+	err = stac922x_parse_auto_config(codec);
+	if (err < 0) {
+		stac92xx_free(codec);
+		return err;
+	}
+
+	codec->patch_ops = stac92xx_patch_ops;
+
+	return 0;
+}
+
+/*
+ * patch entries
+ */
+struct hda_codec_preset snd_hda_preset_sigmatel[] = {
+ 	{ .id = 0x83847690, .name = "STAC9200", .patch = patch_stac9200 },
+ 	{ .id = 0x83847882, .name = "STAC9220 A1", .patch = patch_stac922x },
+ 	{ .id = 0x83847680, .name = "STAC9221 A1", .patch = patch_stac922x },
+ 	{ .id = 0x83847880, .name = "STAC9220 A2", .patch = patch_stac922x },
+ 	{ .id = 0x83847681, .name = "STAC9220D/9223D A2", .patch = patch_stac922x },
+ 	{ .id = 0x83847682, .name = "STAC9221 A2", .patch = patch_stac922x },
+ 	{ .id = 0x83847683, .name = "STAC9221D A2", .patch = patch_stac922x },
+	{} /* terminator */
+};
diff --git a/sound/pci/ice1712/amp.c b/sound/pci/ice1712/amp.c
--- a/sound/pci/ice1712/amp.c
+++ b/sound/pci/ice1712/amp.c
@@ -30,16 +30,39 @@
 #include <sound/core.h>
 
 #include "ice1712.h"
+#include "envy24ht.h"
 #include "amp.h"
 
+static void wm_put(ice1712_t *ice, int reg, unsigned short val)
+{
+	unsigned short cval;
+	cval = (reg << 9) | val;
+	snd_vt1724_write_i2c(ice, WM_DEV, cval >> 8, cval & 0xff);
+}
 
 static int __devinit snd_vt1724_amp_init(ice1712_t *ice)
 {
+	static unsigned short wm_inits[] = {
+		WM_ATTEN_L,	0x0000,	/* 0 db */
+		WM_ATTEN_R,	0x0000,	/* 0 db */
+		WM_DAC_CTRL,	0x0008,	/* 24bit I2S */
+		WM_INT_CTRL,	0x0001, /* 24bit I2S */	
+	};
+
+	unsigned int i;
+
 	/* only use basic functionality for now */
 
 	ice->num_total_dacs = 2;	/* only PSDOUT0 is connected */
 	ice->num_total_adcs = 2;
 
+	/* Chaintech AV-710 has another codecs, which need initialization */
+	/* initialize WM8728 codec */
+	if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AV710) {
+		for (i = 0; i < ARRAY_SIZE(wm_inits); i += 2)
+			wm_put(ice, wm_inits[i], wm_inits[i+1]);
+	}
+
 	return 0;
 }
 
@@ -54,6 +77,13 @@ static int __devinit snd_vt1724_amp_add_
 /* entry point */
 struct snd_ice1712_card_info snd_vt1724_amp_cards[] __devinitdata = {
 	{
+		.subvendor = VT1724_SUBDEVICE_AV710,
+		.name = "Chaintech AV-710",
+		.model = "av710",
+		.chip_init = snd_vt1724_amp_init,
+		.build_controls = snd_vt1724_amp_add_controls,
+	},
+	{
 		.subvendor = VT1724_SUBDEVICE_AUDIO2000,
 		.name = "AMP Ltd AUDIO2000",
 		.model = "amp2000",
diff --git a/sound/pci/ice1712/amp.h b/sound/pci/ice1712/amp.h
--- a/sound/pci/ice1712/amp.h
+++ b/sound/pci/ice1712/amp.h
@@ -24,9 +24,23 @@
  *
  */      
 
-#define  AMP_AUDIO2000_DEVICE_DESC 	       "{AMP Ltd,AUDIO2000},"
+#define  AMP_AUDIO2000_DEVICE_DESC 	       "{AMP Ltd,AUDIO2000},"\
+					       "{Chaintech,AV-710},"
 
+#if 0
 #define VT1724_SUBDEVICE_AUDIO2000	0x12142417	/* Advanced Micro Peripherals Ltd AUDIO2000 */
+#else
+#define VT1724_SUBDEVICE_AUDIO2000	0x00030003	/* a dummy ID for AMP Audio2000 */
+#endif
+#define VT1724_SUBDEVICE_AV710		0x12142417	/* AV710 - the same ID with Audio2000! */
+
+/* WM8728 on I2C for AV710 */
+#define WM_DEV		0x36
+
+#define WM_ATTEN_L	0x00
+#define WM_ATTEN_R	0x01
+#define WM_DAC_CTRL	0x02
+#define WM_INT_CTRL	0x03
 
 extern struct snd_ice1712_card_info  snd_vt1724_amp_cards[];
 
diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c
--- a/sound/pci/ice1712/ice1712.c
+++ b/sound/pci/ice1712/ice1712.c
@@ -2748,7 +2748,7 @@ static struct pci_driver driver = {
 
 static int __init alsa_card_ice1712_init(void)
 {
-	return pci_module_init(&driver);
+	return pci_register_driver(&driver);
 }
 
 static void __exit alsa_card_ice1712_exit(void)
diff --git a/sound/pci/ice1712/ice1712.h b/sound/pci/ice1712/ice1712.h
--- a/sound/pci/ice1712/ice1712.h
+++ b/sound/pci/ice1712/ice1712.h
@@ -373,6 +373,11 @@ struct _snd_ice1712 {
 			unsigned short master[2];
 			unsigned short vol[8];
 		} aureon;
+		/* AC97 register cache for Phase28 */
+		struct phase28_spec {
+			unsigned short master[2];
+			unsigned short vol[8];
+		} phase28;
 		/* Hoontech-specific setting */
 		struct hoontech_spec {
 			unsigned char boxbits[4];
diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c
--- a/sound/pci/ice1712/ice1724.c
+++ b/sound/pci/ice1712/ice1724.c
@@ -2328,7 +2328,7 @@ static struct pci_driver driver = {
 
 static int __init alsa_card_ice1724_init(void)
 {
-	return pci_module_init(&driver);
+	return pci_register_driver(&driver);
 }
 
 static void __exit alsa_card_ice1724_exit(void)
diff --git a/sound/pci/ice1712/phase.c b/sound/pci/ice1712/phase.c
--- a/sound/pci/ice1712/phase.c
+++ b/sound/pci/ice1712/phase.c
@@ -45,6 +45,47 @@
 #include "envy24ht.h"
 #include "phase.h"
 
+/* WM8770 registers */
+#define WM_DAC_ATTEN		0x00	/* DAC1-8 analog attenuation */
+#define WM_DAC_MASTER_ATTEN	0x08	/* DAC master analog attenuation */
+#define WM_DAC_DIG_ATTEN	0x09	/* DAC1-8 digital attenuation */
+#define WM_DAC_DIG_MASTER_ATTEN	0x11	/* DAC master digital attenuation */
+#define WM_PHASE_SWAP		0x12	/* DAC phase */
+#define WM_DAC_CTRL1		0x13	/* DAC control bits */
+#define WM_MUTE			0x14	/* mute controls */
+#define WM_DAC_CTRL2		0x15	/* de-emphasis and zefo-flag */
+#define WM_INT_CTRL		0x16	/* interface control */
+#define WM_MASTER		0x17	/* master clock and mode */
+#define WM_POWERDOWN		0x18	/* power-down controls */
+#define WM_ADC_GAIN		0x19	/* ADC gain L(19)/R(1a) */
+#define WM_ADC_MUX		0x1b	/* input MUX */
+#define WM_OUT_MUX1		0x1c	/* output MUX */
+#define WM_OUT_MUX2		0x1e	/* output MUX */
+#define WM_RESET		0x1f	/* software reset */
+
+
+/*
+ * Logarithmic volume values for WM8770
+ * Computed as 20 * Log10(255 / x)
+ */
+static unsigned char wm_vol[256] = {
+	127, 48, 42, 39, 36, 34, 33, 31, 30, 29, 28, 27, 27, 26, 25, 25, 24, 24, 23,
+	23, 22, 22, 21, 21, 21, 20, 20, 20, 19, 19, 19, 18, 18, 18, 18, 17, 17, 17,
+	17, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, 14, 14, 14, 14, 14, 13, 13, 13,
+	13, 13, 13, 13, 12, 12, 12, 12, 12, 12, 12, 11, 11, 11, 11, 11, 11, 11, 11,
+	11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8,
+	8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6,
+	6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+	5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3,
+	3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 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, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0
+};
+
+#define WM_VOL_MAX	(sizeof(wm_vol) - 1)
+#define WM_VOL_MUTE	0x8000
+
 static akm4xxx_t akm_phase22 __devinitdata = {
 	.type = SND_AK4524,
 	.num_dacs = 2,
@@ -124,6 +165,684 @@ static unsigned char phase22_eeprom[] __
 	0x00,	/* GPIO_STATE2 */
 };
 
+static unsigned char phase28_eeprom[] __devinitdata = {
+	0x0b,	/* SYSCONF: clock 512, spdif-in/ADC, 4DACs */
+	0x80,	/* ACLINK: I2S */
+	0xfc,	/* I2S: vol, 96k, 24bit, 192k */
+	0xc3,	/* SPDIF: out-en, out-int, spdif-in */
+	0xff,	/* GPIO_DIR */
+	0xff,	/* GPIO_DIR1 */
+	0x5f,	/* GPIO_DIR2 */
+	0x00,	/* GPIO_MASK */
+	0x00,	/* GPIO_MASK1 */
+	0x00,	/* GPIO_MASK2 */
+	0x00,	/* GPIO_STATE */
+	0x00,	/* GPIO_STATE1 */
+	0x00,	/* GPIO_STATE2 */
+};
+
+/*
+ * write data in the SPI mode
+ */
+static void phase28_spi_write(ice1712_t *ice, unsigned int cs, unsigned int data, int bits)
+{
+	unsigned int tmp;
+	int i;
+
+	tmp = snd_ice1712_gpio_read(ice);
+
+	snd_ice1712_gpio_set_mask(ice, ~(PHASE28_WM_RW|PHASE28_SPI_MOSI|PHASE28_SPI_CLK|
+					 PHASE28_WM_CS));
+	tmp |= PHASE28_WM_RW;
+	tmp &= ~cs;
+	snd_ice1712_gpio_write(ice, tmp);
+	udelay(1);
+
+	for (i = bits - 1; i >= 0; i--) {
+		tmp &= ~PHASE28_SPI_CLK;
+		snd_ice1712_gpio_write(ice, tmp);
+		udelay(1);
+		if (data & (1 << i))
+			tmp |= PHASE28_SPI_MOSI;
+		else
+			tmp &= ~PHASE28_SPI_MOSI;
+		snd_ice1712_gpio_write(ice, tmp);
+		udelay(1);
+		tmp |= PHASE28_SPI_CLK;
+		snd_ice1712_gpio_write(ice, tmp);
+		udelay(1);
+	}
+
+	tmp &= ~PHASE28_SPI_CLK;
+	tmp |= cs;
+	snd_ice1712_gpio_write(ice, tmp);
+	udelay(1);
+	tmp |= PHASE28_SPI_CLK;
+	snd_ice1712_gpio_write(ice, tmp);
+	udelay(1);
+}
+
+/*
+ * get the current register value of WM codec
+ */
+static unsigned short wm_get(ice1712_t *ice, int reg)
+{
+	reg <<= 1;
+	return ((unsigned short)ice->akm[0].images[reg] << 8) |
+		ice->akm[0].images[reg + 1];
+}
+
+/*
+ * set the register value of WM codec
+ */
+static void wm_put_nocache(ice1712_t *ice, int reg, unsigned short val)
+{
+	phase28_spi_write(ice, PHASE28_WM_CS, (reg << 9) | (val & 0x1ff), 16);
+}
+
+/*
+ * set the register value of WM codec and remember it
+ */
+static void wm_put(ice1712_t *ice, int reg, unsigned short val)
+{
+	wm_put_nocache(ice, reg, val);
+	reg <<= 1;
+	ice->akm[0].images[reg] = val >> 8;
+	ice->akm[0].images[reg + 1] = val;
+}
+
+static void wm_set_vol(ice1712_t *ice, unsigned int index, unsigned short vol, unsigned short master)
+{
+	unsigned char nvol;
+
+	if ((master & WM_VOL_MUTE) || (vol & WM_VOL_MUTE))
+		nvol = 0;
+	else
+		nvol = 127 - wm_vol[(((vol & ~WM_VOL_MUTE) * (master & ~WM_VOL_MUTE)) / 127) & WM_VOL_MAX];
+
+	wm_put(ice, index, nvol);
+	wm_put_nocache(ice, index, 0x180 | nvol);
+}
+
+/*
+ * DAC mute control
+ */
+#define wm_pcm_mute_info	phase28_mono_bool_info
+
+static int wm_pcm_mute_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+
+	down(&ice->gpio_mutex);
+	ucontrol->value.integer.value[0] = (wm_get(ice, WM_MUTE) & 0x10) ? 0 : 1;
+	up(&ice->gpio_mutex);
+	return 0;
+}
+
+static int wm_pcm_mute_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+{
+	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	unsigned short nval, oval;
+	int change;
+
+	snd_ice1712_save_gpio_status(ice);
+	oval = wm_get(ice, WM_MUTE);
+	nval = (oval & ~0x10) | (ucontrol->value.integer.value[0] ? 0 : 0x10);
+	if ((change = (nval != oval)))
+		wm_put(ice, WM_MUTE, nval);
+	snd_ice1712_restore_gpio_status(ice);
+
+	return change;
+}
+
+/*
+ * Master volume attenuation mixer control
+ */
+static int wm_master_vol_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+{
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+	uinfo->count = 2;
+	uinfo->value.integer.min = 0;
+	uinfo->value.integer.max = WM_VOL_MAX;
+	return 0;
+}
+
+static int wm_master_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	int i;
+	for (i=0; i<2; i++)
+		ucontrol->value.integer.value[i] = ice->spec.phase28.master[i] & ~WM_VOL_MUTE;
+	return 0;
+}
+
+static int wm_master_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	int ch, change = 0;
+
+	snd_ice1712_save_gpio_status(ice);
+	for (ch = 0; ch < 2; ch++) {
+		if (ucontrol->value.integer.value[ch] != ice->spec.phase28.master[ch]) {
+			int dac;
+			ice->spec.phase28.master[ch] &= WM_VOL_MUTE;
+			ice->spec.phase28.master[ch] |= ucontrol->value.integer.value[ch];
+			for (dac = 0; dac < ice->num_total_dacs; dac += 2)
+				wm_set_vol(ice, WM_DAC_ATTEN + dac + ch,
+					   ice->spec.phase28.vol[dac + ch],
+					   ice->spec.phase28.master[ch]);
+			change = 1;
+		}
+	}
+	snd_ice1712_restore_gpio_status(ice);
+	return change;
+}
+
+static int __devinit phase28_init(ice1712_t *ice)
+{
+	static unsigned short wm_inits_phase28[] = {
+		/* These come first to reduce init pop noise */
+		0x1b, 0x044,		/* ADC Mux (AC'97 source) */
+		0x1c, 0x00B,		/* Out Mux1 (VOUT1 = DAC+AUX, VOUT2 = DAC) */
+		0x1d, 0x009,		/* Out Mux2 (VOUT2 = DAC, VOUT3 = DAC) */
+
+		0x18, 0x000,		/* All power-up */
+
+		0x16, 0x122,		/* I2S, normal polarity, 24bit */
+		0x17, 0x022,		/* 256fs, slave mode */
+		0x00, 0,		/* DAC1 analog mute */
+		0x01, 0,		/* DAC2 analog mute */
+		0x02, 0,		/* DAC3 analog mute */
+		0x03, 0,		/* DAC4 analog mute */
+		0x04, 0,		/* DAC5 analog mute */
+		0x05, 0,		/* DAC6 analog mute */
+		0x06, 0,		/* DAC7 analog mute */
+		0x07, 0,		/* DAC8 analog mute */
+		0x08, 0x100,		/* master analog mute */
+		0x09, 0xff,		/* DAC1 digital full */
+		0x0a, 0xff,		/* DAC2 digital full */
+		0x0b, 0xff,		/* DAC3 digital full */
+		0x0c, 0xff,		/* DAC4 digital full */
+		0x0d, 0xff,		/* DAC5 digital full */
+		0x0e, 0xff,		/* DAC6 digital full */
+		0x0f, 0xff,		/* DAC7 digital full */
+		0x10, 0xff,		/* DAC8 digital full */
+		0x11, 0x1ff,		/* master digital full */
+		0x12, 0x000,		/* phase normal */
+		0x13, 0x090,		/* unmute DAC L/R */
+		0x14, 0x000,		/* all unmute */
+		0x15, 0x000,		/* no deemphasis, no ZFLG */
+		0x19, 0x000,		/* -12dB ADC/L */
+		0x1a, 0x000,		/* -12dB ADC/R */
+		(unsigned short)-1
+	};
+
+	unsigned int tmp;
+	akm4xxx_t *ak;
+	unsigned short *p;
+	int i;
+
+	ice->num_total_dacs = 8;
+	ice->num_total_adcs = 2;
+
+	// Initialize analog chips
+	ak = ice->akm = kcalloc(1, sizeof(akm4xxx_t), GFP_KERNEL);
+	if (!ak)
+		return -ENOMEM;
+	ice->akm_codecs = 1;
+
+	snd_ice1712_gpio_set_dir(ice, 0x5fffff); /* fix this for the time being */
+
+	/* reset the wm codec as the SPI mode */
+	snd_ice1712_save_gpio_status(ice);
+	snd_ice1712_gpio_set_mask(ice, ~(PHASE28_WM_RESET|PHASE28_WM_CS|PHASE28_HP_SEL));
+
+	tmp = snd_ice1712_gpio_read(ice);
+	tmp &= ~PHASE28_WM_RESET;
+	snd_ice1712_gpio_write(ice, tmp);
+	udelay(1);
+	tmp |= PHASE28_WM_CS;
+	snd_ice1712_gpio_write(ice, tmp);
+	udelay(1);
+	tmp |= PHASE28_WM_RESET;
+	snd_ice1712_gpio_write(ice, tmp);
+	udelay(1);
+
+	p = wm_inits_phase28;
+	for (; *p != (unsigned short)-1; p += 2)
+		wm_put(ice, p[0], p[1]);
+
+	snd_ice1712_restore_gpio_status(ice);
+
+	ice->spec.phase28.master[0] = WM_VOL_MUTE;
+	ice->spec.phase28.master[1] = WM_VOL_MUTE;
+	for (i = 0; i < ice->num_total_dacs; i++) {
+		ice->spec.phase28.vol[i] = WM_VOL_MUTE;
+		wm_set_vol(ice, i, ice->spec.phase28.vol[i], ice->spec.phase28.master[i % 2]);
+	}
+
+	return 0;
+}
+
+/*
+ * DAC volume attenuation mixer control
+ */
+static int wm_vol_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+{
+	int voices = kcontrol->private_value >> 8;
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+	uinfo->count = voices;
+	uinfo->value.integer.min = 0;		/* mute (-101dB) */
+	uinfo->value.integer.max = 0x7F;	/* 0dB */
+	return 0;
+}
+
+static int wm_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	int i, ofs, voices;
+
+	voices = kcontrol->private_value >> 8;
+	ofs = kcontrol->private_value & 0xff;
+	for (i = 0; i < voices; i++)
+		ucontrol->value.integer.value[i] = ice->spec.phase28.vol[ofs+i] & ~WM_VOL_MUTE;
+	return 0;
+}
+
+static int wm_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	int i, idx, ofs, voices;
+	int change = 0;
+
+	voices = kcontrol->private_value >> 8;
+	ofs = kcontrol->private_value & 0xff;
+	snd_ice1712_save_gpio_status(ice);
+	for (i = 0; i < voices; i++) {
+		idx  = WM_DAC_ATTEN + ofs + i;
+		if (ucontrol->value.integer.value[i] != ice->spec.phase28.vol[ofs+i]) {
+			ice->spec.phase28.vol[ofs+i] &= WM_VOL_MUTE;
+			ice->spec.phase28.vol[ofs+i] |= ucontrol->value.integer.value[i];
+			wm_set_vol(ice, idx, ice->spec.phase28.vol[ofs+i],
+				   ice->spec.phase28.master[i]);
+			change = 1;
+		}
+	}
+	snd_ice1712_restore_gpio_status(ice);
+	return change;
+}
+
+/*
+ * WM8770 mute control
+ */
+static int wm_mute_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) {
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
+	uinfo->count = kcontrol->private_value >> 8;
+	uinfo->value.integer.min = 0;
+	uinfo->value.integer.max = 1;
+	return 0;
+}
+
+static int wm_mute_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	int voices, ofs, i;
+
+	voices = kcontrol->private_value >> 8;
+	ofs = kcontrol->private_value & 0xFF;
+
+	for (i = 0; i < voices; i++)
+		ucontrol->value.integer.value[i] = (ice->spec.phase28.vol[ofs+i] & WM_VOL_MUTE) ? 0 : 1;
+	return 0;
+}
+
+static int wm_mute_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+{
+	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	int change = 0, voices, ofs, i;
+
+	voices = kcontrol->private_value >> 8;
+	ofs = kcontrol->private_value & 0xFF;
+
+	snd_ice1712_save_gpio_status(ice);
+	for (i = 0; i < voices; i++) {
+		int val = (ice->spec.phase28.vol[ofs + i] & WM_VOL_MUTE) ? 0 : 1;
+		if (ucontrol->value.integer.value[i] != val) {
+			ice->spec.phase28.vol[ofs + i] &= ~WM_VOL_MUTE;
+			ice->spec.phase28.vol[ofs + i] |=
+				ucontrol->value.integer.value[i] ? 0 : WM_VOL_MUTE;
+			wm_set_vol(ice, ofs + i, ice->spec.phase28.vol[ofs + i],
+				   ice->spec.phase28.master[i]);
+			change = 1;
+		}
+	}
+	snd_ice1712_restore_gpio_status(ice);
+
+	return change;
+}
+
+/*
+ * WM8770 master mute control
+ */
+static int wm_master_mute_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) {
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
+	uinfo->count = 2;
+	uinfo->value.integer.min = 0;
+	uinfo->value.integer.max = 1;
+	return 0;
+}
+
+static int wm_master_mute_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+
+	ucontrol->value.integer.value[0] = (ice->spec.phase28.master[0] & WM_VOL_MUTE) ? 0 : 1;
+	ucontrol->value.integer.value[1] = (ice->spec.phase28.master[1] & WM_VOL_MUTE) ? 0 : 1;
+	return 0;
+}
+
+static int wm_master_mute_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+{
+	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	int change = 0, i;
+
+	snd_ice1712_save_gpio_status(ice);
+	for (i = 0; i < 2; i++) {
+		int val = (ice->spec.phase28.master[i] & WM_VOL_MUTE) ? 0 : 1;
+		if (ucontrol->value.integer.value[i] != val) {
+			int dac;
+			ice->spec.phase28.master[i] &= ~WM_VOL_MUTE;
+			ice->spec.phase28.master[i] |=
+				ucontrol->value.integer.value[i] ? 0 : WM_VOL_MUTE;
+			for (dac = 0; dac < ice->num_total_dacs; dac += 2)
+				wm_set_vol(ice, WM_DAC_ATTEN + dac + i,
+					   ice->spec.phase28.vol[dac + i],
+					   ice->spec.phase28.master[i]);
+			change = 1;
+		}
+	}
+	snd_ice1712_restore_gpio_status(ice);
+
+	return change;
+}
+
+/* digital master volume */
+#define PCM_0dB 0xff
+#define PCM_RES 128	/* -64dB */
+#define PCM_MIN (PCM_0dB - PCM_RES)
+static int wm_pcm_vol_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+{
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+	uinfo->count = 1;
+	uinfo->value.integer.min = 0;		/* mute (-64dB) */
+	uinfo->value.integer.max = PCM_RES;	/* 0dB */
+	return 0;
+}
+
+static int wm_pcm_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	unsigned short val;
+
+	down(&ice->gpio_mutex);
+	val = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff;
+	val = val > PCM_MIN ? (val - PCM_MIN) : 0;
+	ucontrol->value.integer.value[0] = val;
+	up(&ice->gpio_mutex);
+	return 0;
+}
+
+static int wm_pcm_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	unsigned short ovol, nvol;
+	int change = 0;
+
+	snd_ice1712_save_gpio_status(ice);
+	nvol = ucontrol->value.integer.value[0];
+	nvol = (nvol ? (nvol + PCM_MIN) : 0) & 0xff;
+	ovol = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff;
+	if (ovol != nvol) {
+		wm_put(ice, WM_DAC_DIG_MASTER_ATTEN, nvol); /* prelatch */
+		wm_put_nocache(ice, WM_DAC_DIG_MASTER_ATTEN, nvol | 0x100); /* update */
+		change = 1;
+	}
+	snd_ice1712_restore_gpio_status(ice);
+	return change;
+}
+
+/*
+ */
+static int phase28_mono_bool_info(snd_kcontrol_t *k, snd_ctl_elem_info_t *uinfo)
+{
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
+	uinfo->count = 1;
+	uinfo->value.integer.min = 0;
+	uinfo->value.integer.max = 1;
+	return 0;
+}
+
+/*
+ * Deemphasis
+ */
+#define phase28_deemp_info	phase28_mono_bool_info
+
+static int phase28_deemp_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	ucontrol->value.integer.value[0] = (wm_get(ice, WM_DAC_CTRL2) & 0xf) == 0xf;
+	return 0;
+}
+
+static int phase28_deemp_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	int temp, temp2;
+	temp2 = temp = wm_get(ice, WM_DAC_CTRL2);
+	if (ucontrol->value.integer.value[0])
+		temp |= 0xf;
+	else
+		temp &= ~0xf;
+	if (temp != temp2) {
+		wm_put(ice, WM_DAC_CTRL2, temp);
+		return 1;
+	}
+	return 0;
+}
+
+/*
+ * ADC Oversampling
+ */
+static int phase28_oversampling_info(snd_kcontrol_t *k, snd_ctl_elem_info_t *uinfo)
+{
+	static char *texts[2] = { "128x", "64x"	};
+
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+	uinfo->count = 1;
+	uinfo->value.enumerated.items = 2;
+
+	if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
+		uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
+	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
+
+        return 0;
+}
+
+static int phase28_oversampling_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	ucontrol->value.enumerated.item[0] = (wm_get(ice, WM_MASTER) & 0x8) == 0x8;
+	return 0;
+}
+
+static int phase28_oversampling_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	int temp, temp2;
+	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+
+	temp2 = temp = wm_get(ice, WM_MASTER);
+
+	if (ucontrol->value.enumerated.item[0])
+		temp |= 0x8;
+	else
+		temp &= ~0x8;
+
+	if (temp != temp2) {
+		wm_put(ice, WM_MASTER, temp);
+		return 1;
+	}
+	return 0;
+}
+
+static snd_kcontrol_new_t phase28_dac_controls[] __devinitdata = {
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Master Playback Switch",
+		.info = wm_master_mute_info,
+		.get = wm_master_mute_get,
+		.put = wm_master_mute_put
+	},
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Master Playback Volume",
+		.info = wm_master_vol_info,
+		.get = wm_master_vol_get,
+		.put = wm_master_vol_put
+	},
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Front Playback Switch",
+		.info = wm_mute_info,
+		.get = wm_mute_get,
+		.put = wm_mute_put,
+		.private_value = (2 << 8) | 0
+	},
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Front Playback Volume",
+		.info = wm_vol_info,
+		.get = wm_vol_get,
+		.put = wm_vol_put,
+		.private_value = (2 << 8) | 0
+	},
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Rear Playback Switch",
+		.info = wm_mute_info,
+		.get = wm_mute_get,
+		.put = wm_mute_put,
+		.private_value = (2 << 8) | 2
+	},
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Rear Playback Volume",
+		.info = wm_vol_info,
+		.get = wm_vol_get,
+		.put = wm_vol_put,
+		.private_value = (2 << 8) | 2
+	},
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Center Playback Switch",
+		.info = wm_mute_info,
+		.get = wm_mute_get,
+		.put = wm_mute_put,
+		.private_value = (1 << 8) | 4
+	},
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Center Playback Volume",
+		.info = wm_vol_info,
+		.get = wm_vol_get,
+		.put = wm_vol_put,
+		.private_value = (1 << 8) | 4
+	},
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "LFE Playback Switch",
+		.info = wm_mute_info,
+		.get = wm_mute_get,
+		.put = wm_mute_put,
+		.private_value = (1 << 8) | 5
+	},
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "LFE Playback Volume",
+		.info = wm_vol_info,
+		.get = wm_vol_get,
+		.put = wm_vol_put,
+		.private_value = (1 << 8) | 5
+	},
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Side Playback Switch",
+		.info = wm_mute_info,
+		.get = wm_mute_get,
+		.put = wm_mute_put,
+		.private_value = (2 << 8) | 6
+	},
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Side Playback Volume",
+		.info = wm_vol_info,
+		.get = wm_vol_get,
+		.put = wm_vol_put,
+		.private_value = (2 << 8) | 6
+	}
+};
+
+static snd_kcontrol_new_t wm_controls[] __devinitdata = {
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "PCM Playback Switch",
+		.info = wm_pcm_mute_info,
+		.get = wm_pcm_mute_get,
+		.put = wm_pcm_mute_put
+	},
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "PCM Playback Volume",
+		.info = wm_pcm_vol_info,
+		.get = wm_pcm_vol_get,
+		.put = wm_pcm_vol_put
+	},
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "DAC Deemphasis Switch",
+		.info = phase28_deemp_info,
+		.get = phase28_deemp_get,
+		.put = phase28_deemp_put
+	},
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "ADC Oversampling",
+		.info = phase28_oversampling_info,
+		.get = phase28_oversampling_get,
+		.put = phase28_oversampling_put
+	}
+};
+
+static int __devinit phase28_add_controls(ice1712_t *ice)
+{
+	unsigned int i, counts;
+	int err;
+
+	counts = ARRAY_SIZE(phase28_dac_controls);
+	for (i = 0; i < counts; i++) {
+		err = snd_ctl_add(ice->card, snd_ctl_new1(&phase28_dac_controls[i], ice));
+		if (err < 0)
+			return err;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(wm_controls); i++) {
+		err = snd_ctl_add(ice->card, snd_ctl_new1(&wm_controls[i], ice));
+		if (err < 0)
+			return err;
+	}
+
+	return 0;
+}
+
 struct snd_ice1712_card_info snd_vt1724_phase_cards[] __devinitdata = {
 	{
 		.subvendor = VT1724_SUBDEVICE_PHASE22,
@@ -134,5 +853,14 @@ struct snd_ice1712_card_info snd_vt1724_
 		.eeprom_size = sizeof(phase22_eeprom),
 		.eeprom_data = phase22_eeprom,
 	},
+	{
+		.subvendor = VT1724_SUBDEVICE_PHASE28,
+		.name = "Terratec PHASE 28",
+		.model = "phase28",
+		.chip_init = phase28_init,
+		.build_controls = phase28_add_controls,
+		.eeprom_size = sizeof(phase28_eeprom),
+		.eeprom_data = phase28_eeprom,
+	},
 	{ } /* terminator */
 };
diff --git a/sound/pci/ice1712/phase.h b/sound/pci/ice1712/phase.h
--- a/sound/pci/ice1712/phase.h
+++ b/sound/pci/ice1712/phase.h
@@ -24,11 +24,28 @@
  *
  */      
 
-#define PHASE_DEVICE_DESC "{Terratec,Phase 22},"
+#define PHASE_DEVICE_DESC "{Terratec,Phase 22},"\
+                          "{Terratec,Phase 28},"
 
 #define VT1724_SUBDEVICE_PHASE22	0x3b155011
+#define VT1724_SUBDEVICE_PHASE28	0x3b154911
 
 /* entry point */
 extern struct snd_ice1712_card_info snd_vt1724_phase_cards[];
 
+/* PHASE28 GPIO bits */
+#define PHASE28_SPI_MISO	(1 << 21)
+#define PHASE28_WM_RESET	(1 << 20)
+#define PHASE28_SPI_CLK		(1 << 19)
+#define PHASE28_SPI_MOSI	(1 << 18)
+#define PHASE28_WM_RW		(1 << 17)
+#define PHASE28_AC97_RESET	(1 << 16)
+#define PHASE28_DIGITAL_SEL1	(1 << 15)
+#define PHASE28_HP_SEL		(1 << 14)
+#define PHASE28_WM_CS		(1 << 12)
+#define PHASE28_AC97_COMMIT	(1 << 11)
+#define PHASE28_AC97_ADDR	(1 << 10)
+#define PHASE28_AC97_DATA_LOW	(1 << 9)
+#define PHASE28_AC97_DATA_HIGH	(1 << 8)
+#define PHASE28_AC97_DATA_MASK	0xFF
 #endif /* __SOUND_PHASE */
diff --git a/sound/pci/ice1712/vt1720_mobo.c b/sound/pci/ice1712/vt1720_mobo.c
--- a/sound/pci/ice1712/vt1720_mobo.c
+++ b/sound/pci/ice1712/vt1720_mobo.c
@@ -110,6 +110,15 @@ struct snd_ice1712_card_info snd_vt1720_
 		.eeprom_size = sizeof(k8x800_eeprom),
 		.eeprom_data = k8x800_eeprom,
 	},
+	{
+		.subvendor = VT1720_SUBDEVICE_SN25P,
+		.name = "Shuttle SN25P",
+		/* identical with k8x800 */
+		.chip_init = k8x800_init,
+		.build_controls = k8x800_add_controls,
+		.eeprom_size = sizeof(k8x800_eeprom),
+		.eeprom_data = k8x800_eeprom,
+	},
 	{ } /* terminator */
 };
 
diff --git a/sound/pci/ice1712/vt1720_mobo.h b/sound/pci/ice1712/vt1720_mobo.h
--- a/sound/pci/ice1712/vt1720_mobo.h
+++ b/sound/pci/ice1712/vt1720_mobo.h
@@ -27,12 +27,14 @@
 #define VT1720_MOBO_DEVICE_DESC        "{Albatron,K8X800 Pro II},"\
 				       "{Chaintech,ZNF3-150},"\
 				       "{Chaintech,ZNF3-250},"\
-				       "{Chaintech,9CJS},"
+				       "{Chaintech,9CJS},"\
+				       "{Shuttle,SN25P},"
 
 #define VT1720_SUBDEVICE_K8X800		0xf217052c
 #define VT1720_SUBDEVICE_ZNF3_150	0x0f2741f6
 #define VT1720_SUBDEVICE_ZNF3_250	0x0f2745f6
 #define VT1720_SUBDEVICE_9CJS		0x0f272327
+#define VT1720_SUBDEVICE_SN25P		0x97123650
 
 extern struct snd_ice1712_card_info  snd_vt1720_mobo_cards[];
 
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
--- a/sound/pci/intel8x0.c
+++ b/sound/pci/intel8x0.c
@@ -424,6 +424,7 @@ struct _snd_intel8x0 {
 	unsigned xbox: 1;		/* workaround for Xbox AC'97 detection */
 
 	int spdif_idx;	/* SPDIF BAR index; *_SPBAR or -1 if use PCMOUT */
+	unsigned int sdm_saved;	/* SDM reg value */
 
 	ac97_bus_t *ac97_bus;
 	ac97_t *ac97[3];
@@ -1725,229 +1726,235 @@ static struct ac97_pcm ac97_pcm_defs[] _
 
 static struct ac97_quirk ac97_quirks[] __devinitdata = {
 	{
-		.vendor = 0x0e11,
-		.device = 0x008a,
+		.subvendor = 0x0e11,
+		.subdevice = 0x008a,
 		.name = "Compaq Evo W4000",	/* AD1885 */
 		.type = AC97_TUNE_HP_ONLY
 	},
 	{
-		.vendor = 0x0e11,
-		.device = 0x00b8,
+		.subvendor = 0x0e11,
+		.subdevice = 0x00b8,
 		.name = "Compaq Evo D510C",
 		.type = AC97_TUNE_HP_ONLY
 	},
         {
-		.vendor = 0x0e11,
-		.device = 0x0860,
+		.subvendor = 0x0e11,
+		.subdevice = 0x0860,
 		.name = "HP/Compaq nx7010",
 		.type = AC97_TUNE_MUTE_LED
         },
 	{
-		.vendor = 0x1014,
-		.device = 0x1f00,
+		.subvendor = 0x1014,
+		.subdevice = 0x1f00,
 		.name = "MS-9128",
 		.type = AC97_TUNE_ALC_JACK
 	},
 	{
-		.vendor = 0x1028,
-		.device = 0x00d8,
+		.subvendor = 0x1028,
+		.subdevice = 0x00d8,
 		.name = "Dell Precision 530",	/* AD1885 */
 		.type = AC97_TUNE_HP_ONLY
 	},
 	{
-		.vendor = 0x1028,
-		.device = 0x010d,
+		.subvendor = 0x1028,
+		.subdevice = 0x010d,
 		.name = "Dell",	/* which model?  AD1885 */
 		.type = AC97_TUNE_HP_ONLY
 	},
 	{
-		.vendor = 0x1028,
-		.device = 0x0126,
+		.subvendor = 0x1028,
+		.subdevice = 0x0126,
 		.name = "Dell Optiplex GX260",	/* AD1981A */
 		.type = AC97_TUNE_HP_ONLY
 	},
 	{
-		.vendor = 0x1028,
-		.device = 0x012c,
+		.subvendor = 0x1028,
+		.subdevice = 0x012c,
 		.name = "Dell Precision 650",	/* AD1981A */
 		.type = AC97_TUNE_HP_ONLY
 	},
 	{
-		.vendor = 0x1028,
-		.device = 0x012d,
+		.subvendor = 0x1028,
+		.subdevice = 0x012d,
 		.name = "Dell Precision 450",	/* AD1981B*/
 		.type = AC97_TUNE_HP_ONLY
 	},
 	{
-		.vendor = 0x1028,
-		.device = 0x0147,
+		.subvendor = 0x1028,
+		.subdevice = 0x0147,
 		.name = "Dell",	/* which model?  AD1981B*/
 		.type = AC97_TUNE_HP_ONLY
 	},
 	{
-		.vendor = 0x1028,
-		.device = 0x0163,
+		.subvendor = 0x1028,
+		.subdevice = 0x0163,
 		.name = "Dell Unknown",	/* STAC9750/51 */
 		.type = AC97_TUNE_HP_ONLY
 	},
 	{
-		.vendor = 0x103c,
-		.device = 0x006d,
+		.subvendor = 0x103c,
+		.subdevice = 0x006d,
 		.name = "HP zv5000",
 		.type = AC97_TUNE_MUTE_LED	/*AD1981B*/
 	},
 	{	/* FIXME: which codec? */
-		.vendor = 0x103c,
-		.device = 0x00c3,
+		.subvendor = 0x103c,
+		.subdevice = 0x00c3,
 		.name = "HP xw6000",
 		.type = AC97_TUNE_HP_ONLY
 	},
 	{
-		.vendor = 0x103c,
-		.device = 0x088c,
+		.subvendor = 0x103c,
+		.subdevice = 0x088c,
 		.name = "HP nc8000",
 		.type = AC97_TUNE_MUTE_LED
 	},
 	{
-		.vendor = 0x103c,
-		.device = 0x0890,
+		.subvendor = 0x103c,
+		.subdevice = 0x0890,
 		.name = "HP nc6000",
 		.type = AC97_TUNE_MUTE_LED
 	},
 	{
-		.vendor = 0x103c,
-		.device = 0x129d,
+		.subvendor = 0x103c,
+		.subdevice = 0x129d,
 		.name = "HP xw8000",
 		.type = AC97_TUNE_HP_ONLY
 	},
 	{
-		.vendor = 0x103c,
-		.device = 0x12f1,
+		.subvendor = 0x103c,
+		.subdevice = 0x12f1,
 		.name = "HP xw8200",	/* AD1981B*/
 		.type = AC97_TUNE_HP_ONLY
 	},
 	{
-		.vendor = 0x103c,
-		.device = 0x12f2,
+		.subvendor = 0x103c,
+		.subdevice = 0x12f2,
 		.name = "HP xw6200",
 		.type = AC97_TUNE_HP_ONLY
 	},
 	{
-		.vendor = 0x103c,
-		.device = 0x3008,
+		.subvendor = 0x103c,
+		.subdevice = 0x3008,
 		.name = "HP xw4200",	/* AD1981B*/
 		.type = AC97_TUNE_HP_ONLY
 	},
 	{
-		.vendor = 0x104d,
-		.device = 0x8197,
+		.subvendor = 0x104d,
+		.subdevice = 0x8197,
 		.name = "Sony S1XP",
 		.type = AC97_TUNE_INV_EAPD
 	},
  	{
-		.vendor = 0x1043,
-		.device = 0x80f3,
+		.subvendor = 0x1043,
+		.subdevice = 0x80f3,
 		.name = "ASUS ICH5/AD1985",
 		.type = AC97_TUNE_AD_SHARING
 	},
 	{
-		.vendor = 0x10cf,
-		.device = 0x11c3,
+		.subvendor = 0x10cf,
+		.subdevice = 0x11c3,
 		.name = "Fujitsu-Siemens E4010",
 		.type = AC97_TUNE_HP_ONLY
 	},
 	{
-		.vendor = 0x10cf,
-		.device = 0x1253,
+		.subvendor = 0x10cf,
+		.subdevice = 0x1225,
+		.name = "Fujitsu-Siemens T3010",
+		.type = AC97_TUNE_HP_ONLY
+	},
+	{
+		.subvendor = 0x10cf,
+		.subdevice = 0x1253,
 		.name = "Fujitsu S6210",	/* STAC9750/51 */
 		.type = AC97_TUNE_HP_ONLY
 	},
 	{
-		.vendor = 0x10f1,
-		.device = 0x2665,
+		.subvendor = 0x10f1,
+		.subdevice = 0x2665,
 		.name = "Fujitsu-Siemens Celsius",	/* AD1981? */
 		.type = AC97_TUNE_HP_ONLY
 	},
 	{
-		.vendor = 0x10f1,
-		.device = 0x2885,
+		.subvendor = 0x10f1,
+		.subdevice = 0x2885,
 		.name = "AMD64 Mobo",	/* ALC650 */
 		.type = AC97_TUNE_HP_ONLY
 	},
 	{
-		.vendor = 0x110a,
-		.device = 0x0056,
+		.subvendor = 0x110a,
+		.subdevice = 0x0056,
 		.name = "Fujitsu-Siemens Scenic",	/* AD1981? */
 		.type = AC97_TUNE_HP_ONLY
 	},
 	{
-		.vendor = 0x11d4,
-		.device = 0x5375,
+		.subvendor = 0x11d4,
+		.subdevice = 0x5375,
 		.name = "ADI AD1985 (discrete)",
 		.type = AC97_TUNE_HP_ONLY
 	},
 	{
-		.vendor = 0x1462,
-		.device = 0x5470,
+		.subvendor = 0x1462,
+		.subdevice = 0x5470,
 		.name = "MSI P4 ATX 645 Ultra",
 		.type = AC97_TUNE_HP_ONLY
 	},
 	{
-		.vendor = 0x1734,
-		.device = 0x0088,
+		.subvendor = 0x1734,
+		.subdevice = 0x0088,
 		.name = "Fujitsu-Siemens D1522",	/* AD1981 */
 		.type = AC97_TUNE_HP_ONLY
 	},
 	{
-		.vendor = 0x8086,
-		.device = 0x2000,
+		.subvendor = 0x8086,
+		.subdevice = 0x2000,
 		.mask = 0xfff0,
 		.name = "Intel ICH5/AD1985",
 		.type = AC97_TUNE_AD_SHARING
 	},
 	{
-		.vendor = 0x8086,
-		.device = 0x4000,
+		.subvendor = 0x8086,
+		.subdevice = 0x4000,
 		.mask = 0xfff0,
 		.name = "Intel ICH5/AD1985",
 		.type = AC97_TUNE_AD_SHARING
 	},
 	{
-		.vendor = 0x8086,
-		.device = 0x4856,
+		.subvendor = 0x8086,
+		.subdevice = 0x4856,
 		.name = "Intel D845WN (82801BA)",
 		.type = AC97_TUNE_SWAP_HP
 	},
 	{
-		.vendor = 0x8086,
-		.device = 0x4d44,
+		.subvendor = 0x8086,
+		.subdevice = 0x4d44,
 		.name = "Intel D850EMV2",	/* AD1885 */
 		.type = AC97_TUNE_HP_ONLY
 	},
 	{
-		.vendor = 0x8086,
-		.device = 0x4d56,
+		.subvendor = 0x8086,
+		.subdevice = 0x4d56,
 		.name = "Intel ICH/AD1885",
 		.type = AC97_TUNE_HP_ONLY
 	},
 	{
-		.vendor = 0x8086,
-		.device = 0x6000,
+		.subvendor = 0x8086,
+		.subdevice = 0x6000,
 		.mask = 0xfff0,
 		.name = "Intel ICH5/AD1985",
 		.type = AC97_TUNE_AD_SHARING
 	},
 	{
-		.vendor = 0x8086,
-		.device = 0xe000,
+		.subvendor = 0x8086,
+		.subdevice = 0xe000,
 		.mask = 0xfff0,
 		.name = "Intel ICH5/AD1985",
 		.type = AC97_TUNE_AD_SHARING
 	},
 #if 0 /* FIXME: this seems wrong on most boards */
 	{
-		.vendor = 0x8086,
-		.device = 0xa000,
+		.subvendor = 0x8086,
+		.subdevice = 0xa000,
 		.mask = 0xfff0,
 		.name = "Intel ICH5/AD1985",
 		.type = AC97_TUNE_HP_ONLY
@@ -2367,6 +2374,11 @@ static int intel8x0_suspend(snd_card_t *
 	for (i = 0; i < 3; i++)
 		if (chip->ac97[i])
 			snd_ac97_suspend(chip->ac97[i]);
+	if (chip->device_type == DEVICE_INTEL_ICH4)
+		chip->sdm_saved = igetbyte(chip, ICHREG(SDM));
+
+	if (chip->irq >= 0)
+		free_irq(chip->irq, (void *)chip);
 	pci_disable_device(chip->pci);
 	return 0;
 }
@@ -2378,7 +2390,19 @@ static int intel8x0_resume(snd_card_t *c
 
 	pci_enable_device(chip->pci);
 	pci_set_master(chip->pci);
-	snd_intel8x0_chip_init(chip, 0);
+	request_irq(chip->irq, snd_intel8x0_interrupt, SA_INTERRUPT|SA_SHIRQ, card->shortname, (void *)chip);
+	synchronize_irq(chip->irq);
+	snd_intel8x0_chip_init(chip, 1);
+
+	/* re-initialize mixer stuff */
+	if (chip->device_type == DEVICE_INTEL_ICH4) {
+		/* enable separate SDINs for ICH4 */
+		iputbyte(chip, ICHREG(SDM), chip->sdm_saved);
+		/* use slot 10/11 for SPDIF */
+		iputdword(chip, ICHREG(GLOB_CNT),
+			  (igetdword(chip, ICHREG(GLOB_CNT)) & ~ICH_PCM_SPDIF_MASK) |
+			  ICH_PCM_SPDIF_1011);
+	}
 
 	/* refill nocache */
 	if (chip->fix_nocache)
@@ -2445,8 +2469,7 @@ static void __devinit intel8x0_measure_a
 	}
 	do_gettimeofday(&start_time);
 	spin_unlock_irq(&chip->reg_lock);
-	set_current_state(TASK_UNINTERRUPTIBLE);
-	schedule_timeout(HZ / 20);
+	msleep(50);
 	spin_lock_irq(&chip->reg_lock);
 	/* check the position */
 	pos = ichdev->fragsize1;
@@ -2849,7 +2872,7 @@ static struct pci_driver driver = {
 
 static int __init alsa_card_intel8x0_init(void)
 {
-	return pci_module_init(&driver);
+	return pci_register_driver(&driver);
 }
 
 static void __exit alsa_card_intel8x0_exit(void)
diff --git a/sound/pci/intel8x0m.c b/sound/pci/intel8x0m.c
--- a/sound/pci/intel8x0m.c
+++ b/sound/pci/intel8x0m.c
@@ -35,7 +35,6 @@
 #include <sound/pcm.h>
 #include <sound/ac97_codec.h>
 #include <sound/info.h>
-#include <sound/control.h>
 #include <sound/initval.h>
 
 MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
@@ -292,60 +291,9 @@ static struct pci_device_id snd_intel8x0
 #endif
 	{ 0, }
 };
-static int snd_intel8x0m_switch_default_get(snd_kcontrol_t *kcontrol,
-					    snd_ctl_elem_value_t *ucontrol);
-static int snd_intel8x0m_switch_default_put(snd_kcontrol_t *kcontrol,
-					    snd_ctl_elem_value_t *ucontrol);
-static int snd_intel8x0m_switch_default_info(snd_kcontrol_t *kcontrol,
-					     snd_ctl_elem_info_t *uinfo);
-
-#define PRIVATE_VALUE_INITIALIZER(r,m) (((r) & 0xffff) << 16 | ((m) & 0xffff))
-#define PRIVATE_VALUE_MASK(control) ((control)->private_value & 0xffff)
-#define PRIVATE_VALUE_REG(control) (((control)->private_value >> 16) & 0xffff)
-
-static snd_kcontrol_new_t snd_intel8x0m_mixer_switches[] __devinitdata = {
-  { .name  = "Off-hook Switch",
-    .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-    .info  = snd_intel8x0m_switch_default_info,
-    .get   = snd_intel8x0m_switch_default_get,
-    .put   = snd_intel8x0m_switch_default_put,
-    .private_value = PRIVATE_VALUE_INITIALIZER(AC97_GPIO_STATUS,AC97_GPIO_LINE1_OH)
-  }
-};
 
 MODULE_DEVICE_TABLE(pci, snd_intel8x0m_ids);
 
-static int snd_intel8x0m_switch_default_info(snd_kcontrol_t *kcontrol,
-					     snd_ctl_elem_info_t *uinfo)
-{
-	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
-	uinfo->count = 1;
-	uinfo->value.integer.min = 0;
-	uinfo->value.integer.max = 1;
-	return 0;
-}
-
-static int snd_intel8x0m_switch_default_get(snd_kcontrol_t *kcontrol,
-					    snd_ctl_elem_value_t *ucontrol)
-{
-	unsigned short mask = PRIVATE_VALUE_MASK(kcontrol);
-	unsigned short reg = PRIVATE_VALUE_REG(kcontrol);
-	intel8x0_t *chip = snd_kcontrol_chip(kcontrol);
-	unsigned int status;
-	status = snd_ac97_read(chip->ac97, reg) & mask ? 1 : 0;
-	ucontrol->value.integer.value[0] = status;
-	return 0;
-}
-static int snd_intel8x0m_switch_default_put(snd_kcontrol_t *kcontrol,
-					    snd_ctl_elem_value_t *ucontrol)
-{
-	unsigned short mask = PRIVATE_VALUE_MASK(kcontrol);
-	unsigned short reg = PRIVATE_VALUE_REG(kcontrol);
-	intel8x0_t *chip = snd_kcontrol_chip(kcontrol);
-	unsigned short new_status = ucontrol->value.integer.value[0] ? mask : ~mask;
-	return snd_ac97_update_bits(chip->ac97, reg,
-				    mask, new_status);
-}
 /*
  *  Lowlevel I/O - busmaster
  */
@@ -500,6 +448,8 @@ static unsigned short snd_intel8x0_codec
 			res = 0xffff;
 		}
 	}
+	if (reg == AC97_GPIO_STATUS)
+		iagetword(chip, 0); /* clear semaphore */
 	return res;
 }
 
@@ -698,21 +648,6 @@ static snd_pcm_uframes_t snd_intel8x0_pc
 	return bytes_to_frames(substream->runtime, ptr);
 }
 
-static int snd_intel8x0m_pcm_trigger(snd_pcm_substream_t *substream, int cmd)
-{
-	/* hook off/on on start/stop */
-	/* Moved this to mixer control */
-	switch (cmd) {
-	case SNDRV_PCM_TRIGGER_START:
-		break;
-	case SNDRV_PCM_TRIGGER_STOP:
-		break;
-	default:
-		return -EINVAL;
-	}
-	return snd_intel8x0_pcm_trigger(substream,cmd);
-}
-
 static int snd_intel8x0m_pcm_prepare(snd_pcm_substream_t * substream)
 {
 	intel8x0_t *chip = snd_pcm_substream_chip(substream);
@@ -808,7 +743,7 @@ static snd_pcm_ops_t snd_intel8x0m_playb
 	.hw_params =	snd_intel8x0_hw_params,
 	.hw_free =	snd_intel8x0_hw_free,
 	.prepare =	snd_intel8x0m_pcm_prepare,
-	.trigger =	snd_intel8x0m_pcm_trigger,
+	.trigger =	snd_intel8x0_pcm_trigger,
 	.pointer =	snd_intel8x0_pcm_pointer,
 };
 
@@ -819,7 +754,7 @@ static snd_pcm_ops_t snd_intel8x0m_captu
 	.hw_params =	snd_intel8x0_hw_params,
 	.hw_free =	snd_intel8x0_hw_free,
 	.prepare =	snd_intel8x0m_pcm_prepare,
-	.trigger =	snd_intel8x0m_pcm_trigger,
+	.trigger =	snd_intel8x0_pcm_trigger,
 	.pointer =	snd_intel8x0_pcm_pointer,
 };
 
@@ -947,7 +882,6 @@ static int __devinit snd_intel8x0_mixer(
 	ac97_t *x97;
 	int err;
 	unsigned int glob_sta = 0;
-	unsigned int idx;
 	static ac97_bus_ops_t ops = {
 		.write = snd_intel8x0_codec_write,
 		.read = snd_intel8x0_codec_read,
@@ -983,10 +917,6 @@ static int __devinit snd_intel8x0_mixer(
 		chip->ichd[ICHD_MDMIN].ac97 = x97;
 		chip->ichd[ICHD_MDMOUT].ac97 = x97;
 	}
-	for (idx = 0; idx < ARRAY_SIZE(snd_intel8x0m_mixer_switches); idx++) {
-		if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_intel8x0m_mixer_switches[idx], chip))) < 0)
-			goto __err;
-	}
 
 	chip->in_ac97_init = 0;
 	return 0;
@@ -1450,7 +1380,7 @@ static struct pci_driver driver = {
 
 static int __init alsa_card_intel8x0m_init(void)
 {
-	return pci_module_init(&driver);
+	return pci_register_driver(&driver);
 }
 
 static void __exit alsa_card_intel8x0m_exit(void)
diff --git a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c
--- a/sound/pci/korg1212/korg1212.c
+++ b/sound/pci/korg1212/korg1212.c
@@ -2541,7 +2541,7 @@ static struct pci_driver driver = {
 
 static int __init alsa_card_korg1212_init(void)
 {
-	return pci_module_init(&driver);
+	return pci_register_driver(&driver);
 }
 
 static void __exit alsa_card_korg1212_exit(void)
diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c
--- a/sound/pci/maestro3.c
+++ b/sound/pci/maestro3.c
@@ -779,6 +779,12 @@ struct m3_quirk {
 				   (e.g. for IrDA on Dell Inspirons) */
 };
 
+struct m3_hv_quirk {
+	u16 vendor, device, subsystem_vendor, subsystem_device;
+	u32 config;		/* ALLEGRO_CONFIG hardware volume bits */
+	int is_omnibook;	/* Do HP OmniBook GPIO magic? */
+};
+
 struct m3_list {
 	int curlen;
 	int mem_addr;
@@ -828,6 +834,7 @@ struct snd_m3 {
 
 	struct pci_dev *pci;
 	struct m3_quirk *quirk;
+	struct m3_hv_quirk *hv_quirk;
 
 	int dacs_active;
 	int timer_users;
@@ -851,6 +858,11 @@ struct snd_m3 {
 	m3_dma_t *substreams;
 
 	spinlock_t reg_lock;
+	spinlock_t ac97_lock;
+
+	snd_kcontrol_t *master_switch;
+	snd_kcontrol_t *master_volume;
+	struct tasklet_struct hwvol_tq;
 
 #ifdef CONFIG_PM
 	u16 *suspend_mem;
@@ -968,32 +980,92 @@ static struct m3_quirk m3_quirk_list[] =
 	{ NULL }
 };
 
+/* These values came from the Windows driver. */
+static struct m3_hv_quirk m3_hv_quirk_list[] = {
+	/* Allegro chips */
+	{ 0x125D, 0x1988, 0x0E11, 0x002E, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 },
+	{ 0x125D, 0x1988, 0x0E11, 0x0094, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 },
+	{ 0x125D, 0x1988, 0x0E11, 0xB112, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 },
+	{ 0x125D, 0x1988, 0x0E11, 0xB114, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 },
+	{ 0x125D, 0x1988, 0x103C, 0x0012, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 },
+	{ 0x125D, 0x1988, 0x103C, 0x0018, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 },
+	{ 0x125D, 0x1988, 0x103C, 0x001C, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 },
+	{ 0x125D, 0x1988, 0x103C, 0x001D, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 },
+	{ 0x125D, 0x1988, 0x103C, 0x001E, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 },
+	{ 0x125D, 0x1988, 0x107B, 0x3350, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 },
+	{ 0x125D, 0x1988, 0x10F7, 0x8338, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 },
+	{ 0x125D, 0x1988, 0x10F7, 0x833C, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 },
+	{ 0x125D, 0x1988, 0x10F7, 0x833D, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 },
+	{ 0x125D, 0x1988, 0x10F7, 0x833E, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 },
+	{ 0x125D, 0x1988, 0x10F7, 0x833F, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 },
+	{ 0x125D, 0x1988, 0x13BD, 0x1018, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 },
+	{ 0x125D, 0x1988, 0x13BD, 0x1019, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 },
+	{ 0x125D, 0x1988, 0x13BD, 0x101A, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 },
+	{ 0x125D, 0x1988, 0x14FF, 0x0F03, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 },
+	{ 0x125D, 0x1988, 0x14FF, 0x0F04, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 },
+	{ 0x125D, 0x1988, 0x14FF, 0x0F05, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 },
+	{ 0x125D, 0x1988, 0x156D, 0xB400, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 },
+	{ 0x125D, 0x1988, 0x156D, 0xB795, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 },
+	{ 0x125D, 0x1988, 0x156D, 0xB797, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 },
+	{ 0x125D, 0x1988, 0x156D, 0xC700, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 },
+	{ 0x125D, 0x1988, 0x1033, 0x80F1, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE, 0 },
+	{ 0x125D, 0x1988, 0x103C, 0x001A, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE, 0 }, /* HP OmniBook 6100 */
+	{ 0x125D, 0x1988, 0x107B, 0x340A, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE, 0 },
+	{ 0x125D, 0x1988, 0x107B, 0x3450, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE, 0 },
+	{ 0x125D, 0x1988, 0x109F, 0x3134, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE, 0 },
+	{ 0x125D, 0x1988, 0x109F, 0x3161, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE, 0 },
+	{ 0x125D, 0x1988, 0x144D, 0x3280, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE, 0 },
+	{ 0x125D, 0x1988, 0x144D, 0x3281, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE, 0 },
+	{ 0x125D, 0x1988, 0x144D, 0xC002, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE, 0 },
+	{ 0x125D, 0x1988, 0x144D, 0xC003, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE, 0 },
+	{ 0x125D, 0x1988, 0x1509, 0x1740, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE, 0 },
+	{ 0x125D, 0x1988, 0x1610, 0x0010, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE, 0 },
+	{ 0x125D, 0x1988, 0x1042, 0x1042, HV_CTRL_ENABLE, 0 },
+	{ 0x125D, 0x1988, 0x107B, 0x9500, HV_CTRL_ENABLE, 0 },
+	{ 0x125D, 0x1988, 0x14FF, 0x0F06, HV_CTRL_ENABLE, 0 },
+	{ 0x125D, 0x1988, 0x1558, 0x8586, HV_CTRL_ENABLE, 0 },
+	{ 0x125D, 0x1988, 0x161F, 0x2011, HV_CTRL_ENABLE, 0 },
+	/* Maestro3 chips */
+	{ 0x125D, 0x1998, 0x103C, 0x000E, HV_CTRL_ENABLE, 0 },
+	{ 0x125D, 0x1998, 0x103C, 0x0010, HV_CTRL_ENABLE, 1 }, /* HP OmniBook 6000 */
+	{ 0x125D, 0x1998, 0x103C, 0x0011, HV_CTRL_ENABLE, 1 }, /* HP OmniBook 500 */
+	{ 0x125D, 0x1998, 0x103C, 0x001B, HV_CTRL_ENABLE, 0 },
+	{ 0x125D, 0x1998, 0x104D, 0x80A6, HV_CTRL_ENABLE, 0 },
+	{ 0x125D, 0x1998, 0x104D, 0x80AA, HV_CTRL_ENABLE, 0 },
+	{ 0x125D, 0x1998, 0x107B, 0x5300, HV_CTRL_ENABLE, 0 },
+	{ 0x125D, 0x1998, 0x110A, 0x1998, HV_CTRL_ENABLE, 0 },
+	{ 0x125D, 0x1998, 0x13BD, 0x1015, HV_CTRL_ENABLE, 0 },
+	{ 0x125D, 0x1998, 0x13BD, 0x101C, HV_CTRL_ENABLE, 0 },
+	{ 0x125D, 0x1998, 0x13BD, 0x1802, HV_CTRL_ENABLE, 0 },
+	{ 0x125D, 0x1998, 0x1599, 0x0715, HV_CTRL_ENABLE, 0 },
+	{ 0x125D, 0x1998, 0x5643, 0x5643, HV_CTRL_ENABLE, 0 },
+	{ 0x125D, 0x199A, 0x144D, 0x3260, HV_CTRL_ENABLE | REDUCED_DEBOUNCE, 0 },
+	{ 0x125D, 0x199A, 0x144D, 0x3261, HV_CTRL_ENABLE | REDUCED_DEBOUNCE, 0 },
+	{ 0x125D, 0x199A, 0x144D, 0xC000, HV_CTRL_ENABLE | REDUCED_DEBOUNCE, 0 },
+	{ 0x125D, 0x199A, 0x144D, 0xC001, HV_CTRL_ENABLE | REDUCED_DEBOUNCE, 0 },
+	{ 0 }
+};
 
 /*
  * lowlevel functions
  */
 
-#define big_mdelay(msec) do {\
-	set_current_state(TASK_UNINTERRUPTIBLE);\
-	schedule_timeout(((msec) * HZ) / 1000);\
-} while (0)
-	
-inline static void snd_m3_outw(m3_t *chip, u16 value, unsigned long reg)
+static inline void snd_m3_outw(m3_t *chip, u16 value, unsigned long reg)
 {
 	outw(value, chip->iobase + reg);
 }
 
-inline static u16 snd_m3_inw(m3_t *chip, unsigned long reg)
+static inline u16 snd_m3_inw(m3_t *chip, unsigned long reg)
 {
 	return inw(chip->iobase + reg);
 }
 
-inline static void snd_m3_outb(m3_t *chip, u8 value, unsigned long reg)
+static inline void snd_m3_outb(m3_t *chip, u8 value, unsigned long reg)
 {
 	outb(value, chip->iobase + reg);
 }
 
-inline static u8 snd_m3_inb(m3_t *chip, unsigned long reg)
+static inline u8 snd_m3_inb(m3_t *chip, unsigned long reg)
 {
 	return inb(chip->iobase + reg);
 }
@@ -1019,7 +1091,7 @@ static void snd_m3_assp_write(m3_t *chip
 static void snd_m3_assp_halt(m3_t *chip)
 {
 	chip->reset_state = snd_m3_inb(chip, DSP_PORT_CONTROL_REG_B) & ~REGB_STOP_CLOCK;
-	big_mdelay(10);
+	msleep(10);
 	snd_m3_outb(chip, chip->reset_state & ~REGB_ENABLE_RESET, DSP_PORT_CONTROL_REG_B);
 }
 
@@ -1565,6 +1637,68 @@ static void snd_m3_update_ptr(m3_t *chip
 	}
 }
 
+static void snd_m3_update_hw_volume(unsigned long private_data)
+{
+	m3_t *chip = (m3_t *) private_data;
+	int x, val;
+	unsigned long flags;
+
+	/* Figure out which volume control button was pushed,
+	   based on differences from the default register
+	   values. */
+	x = inb(chip->iobase + SHADOW_MIX_REG_VOICE) & 0xee;
+
+	/* Reset the volume control registers. */
+	outb(0x88, chip->iobase + SHADOW_MIX_REG_VOICE);
+	outb(0x88, chip->iobase + HW_VOL_COUNTER_VOICE);
+	outb(0x88, chip->iobase + SHADOW_MIX_REG_MASTER);
+	outb(0x88, chip->iobase + HW_VOL_COUNTER_MASTER);
+
+	if (!chip->master_switch || !chip->master_volume)
+		return;
+
+	/* FIXME: we can't call snd_ac97_* functions since here is in tasklet. */
+	spin_lock_irqsave(&chip->ac97_lock, flags);
+
+	val = chip->ac97->regs[AC97_MASTER_VOL];
+	switch (x) {
+	case 0x88:
+		/* mute */
+		val ^= 0x8000;
+		chip->ac97->regs[AC97_MASTER_VOL] = val;
+		outw(val, chip->iobase + CODEC_DATA);
+		outb(AC97_MASTER_VOL, chip->iobase + CODEC_COMMAND);
+		snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
+			       &chip->master_switch->id);
+		break;
+	case 0xaa:
+		/* volume up */
+		if ((val & 0x7f) > 0)
+			val--;
+		if ((val & 0x7f00) > 0)
+			val -= 0x0100;
+		chip->ac97->regs[AC97_MASTER_VOL] = val;
+		outw(val, chip->iobase + CODEC_DATA);
+		outb(AC97_MASTER_VOL, chip->iobase + CODEC_COMMAND);
+		snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
+			       &chip->master_volume->id);
+		break;
+	case 0x66:
+		/* volume down */
+		if ((val & 0x7f) < 0x1f)
+			val++;
+		if ((val & 0x7f00) < 0x1f00)
+			val += 0x0100;
+		chip->ac97->regs[AC97_MASTER_VOL] = val;
+		outw(val, chip->iobase + CODEC_DATA);
+		outb(AC97_MASTER_VOL, chip->iobase + CODEC_COMMAND);
+		snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
+			       &chip->master_volume->id);
+		break;
+	}
+	spin_unlock_irqrestore(&chip->ac97_lock, flags);
+}
+
 static irqreturn_t
 snd_m3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
@@ -1576,7 +1710,10 @@ snd_m3_interrupt(int irq, void *dev_id, 
 
 	if (status == 0xff)
 		return IRQ_NONE;
-   
+
+	if (status & HV_INT_PENDING)
+		tasklet_hi_schedule(&chip->hwvol_tq);
+
 	/*
 	 * ack an assp int if its running
 	 * and has an int pending
@@ -1605,7 +1742,7 @@ snd_m3_interrupt(int irq, void *dev_id, 
 #endif
 
 	/* ack ints */
-	snd_m3_outw(chip, HOST_INT_STATUS, status);
+	outb(status, chip->iobase + HOST_INT_STATUS);
 
 	return IRQ_HANDLED;
 }
@@ -1842,24 +1979,32 @@ static unsigned short
 snd_m3_ac97_read(ac97_t *ac97, unsigned short reg)
 {
 	m3_t *chip = ac97->private_data;
+	unsigned long flags;
+	unsigned short data;
 
 	if (snd_m3_ac97_wait(chip))
 		return 0xffff;
+	spin_lock_irqsave(&chip->ac97_lock, flags);
 	snd_m3_outb(chip, 0x80 | (reg & 0x7f), CODEC_COMMAND);
 	if (snd_m3_ac97_wait(chip))
 		return 0xffff;
-	return snd_m3_inw(chip, CODEC_DATA);
+	data = snd_m3_inw(chip, CODEC_DATA);
+	spin_unlock_irqrestore(&chip->ac97_lock, flags);
+	return data;
 }
 
 static void
 snd_m3_ac97_write(ac97_t *ac97, unsigned short reg, unsigned short val)
 {
 	m3_t *chip = ac97->private_data;
+	unsigned long flags;
 
 	if (snd_m3_ac97_wait(chip))
 		return;
+	spin_lock_irqsave(&chip->ac97_lock, flags);
 	snd_m3_outw(chip, val, CODEC_DATA);
 	snd_m3_outb(chip, reg & 0x7f, CODEC_COMMAND);
+	spin_unlock_irqrestore(&chip->ac97_lock, flags);
 }
 
 
@@ -1958,9 +2103,9 @@ static void snd_m3_ac97_reset(m3_t *chip
 	 */
 	tmp = inw(io + RING_BUS_CTRL_A);
 	outw(RAC_SDFS_ENABLE|LAC_SDFS_ENABLE, io + RING_BUS_CTRL_A);
-	big_mdelay(20);
+	msleep(20);
 	outw(tmp, io + RING_BUS_CTRL_A);
-	big_mdelay(50);
+	msleep(50);
 #endif
 }
 
@@ -1968,6 +2113,7 @@ static int __devinit snd_m3_mixer(m3_t *
 {
 	ac97_bus_t *pbus;
 	ac97_template_t ac97;
+	snd_ctl_elem_id_t id;
 	int err;
 	static ac97_bus_ops_t ops = {
 		.write = snd_m3_ac97_write,
@@ -1988,6 +2134,15 @@ static int __devinit snd_m3_mixer(m3_t *
 	schedule_timeout(HZ / 10);
 	snd_ac97_write(chip->ac97, AC97_PCM, 0);
 
+	memset(&id, 0, sizeof(id));
+	id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
+	strcpy(id.name, "Master Playback Switch");
+	chip->master_switch = snd_ctl_find_id(chip->card, &id);
+	memset(&id, 0, sizeof(id));
+	id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
+	strcpy(id.name, "Master Playback Volume");
+	chip->master_volume = snd_ctl_find_id(chip->card, &id);
+
 	return 0;
 }
 
@@ -2293,6 +2448,7 @@ static int
 snd_m3_chip_init(m3_t *chip)
 {
 	struct pci_dev *pcidev = chip->pci;
+	unsigned long io = chip->iobase;
 	u32 n;
 	u16 w;
 	u8 t; /* makes as much sense as 'n', no? */
@@ -2303,8 +2459,27 @@ snd_m3_chip_init(m3_t *chip)
 	       DISABLE_LEGACY);
 	pci_write_config_word(pcidev, PCI_LEGACY_AUDIO_CTRL, w);
 
+	if (chip->hv_quirk && chip->hv_quirk->is_omnibook) {
+		/*
+		 * Volume buttons on some HP OmniBook laptops don't work
+		 * correctly. This makes them work for the most part.
+		 *
+		 * Volume up and down buttons on the laptop side work.
+		 * Fn+cursor_up (volme up) works.
+		 * Fn+cursor_down (volume down) doesn't work.
+		 * Fn+F7 (mute) works acts as volume up.
+		 */
+		outw(~(GPI_VOL_DOWN|GPI_VOL_UP), io + GPIO_MASK);
+		outw(inw(io + GPIO_DIRECTION) & ~(GPI_VOL_DOWN|GPI_VOL_UP), io + GPIO_DIRECTION);
+		outw((GPI_VOL_DOWN|GPI_VOL_UP), io + GPIO_DATA);
+		outw(0xffff, io + GPIO_MASK);
+	}
 	pci_read_config_dword(pcidev, PCI_ALLEGRO_CONFIG, &n);
-	n &= REDUCED_DEBOUNCE;
+	n &= ~(HV_CTRL_ENABLE | REDUCED_DEBOUNCE | HV_BUTTON_FROM_GD);
+	if (chip->hv_quirk)
+		n |= chip->hv_quirk->config;
+	/* For some reason we must always use reduced debounce. */
+	n |= REDUCED_DEBOUNCE;
 	n |= PM_CTRL_ENABLE | CLK_DIV_BY_49 | USE_PCI_TIMING;
 	pci_write_config_dword(pcidev, PCI_ALLEGRO_CONFIG, n);
 
@@ -2332,6 +2507,12 @@ snd_m3_chip_init(m3_t *chip)
 
 	outb(RUN_ASSP, chip->iobase + ASSP_CONTROL_B); 
 
+	outb(0x00, io + HARDWARE_VOL_CTRL);
+	outb(0x88, io + SHADOW_MIX_REG_VOICE);
+	outb(0x88, io + HW_VOL_COUNTER_VOICE);
+	outb(0x88, io + SHADOW_MIX_REG_MASTER);
+	outb(0x88, io + HW_VOL_COUNTER_MASTER);
+
 	return 0;
 } 
 
@@ -2339,9 +2520,13 @@ static void
 snd_m3_enable_ints(m3_t *chip)
 {
 	unsigned long io = chip->iobase;
+	unsigned short val;
 
 	/* TODO: MPU401 not supported yet */
-	outw(ASSP_INT_ENABLE /*| MPU401_INT_ENABLE*/, io + HOST_INT_CTRL);
+	val = ASSP_INT_ENABLE /*| MPU401_INT_ENABLE*/;
+	if (chip->hv_quirk && (chip->hv_quirk->config & HV_CTRL_ENABLE))
+		val |= HV_INT_ENABLE;
+	outw(val, io + HOST_INT_CTRL);
 	outb(inb(io + ASSP_CONTROL_C) | ASSP_HOST_INT_ENABLE,
 	     io + ASSP_CONTROL_C);
 }
@@ -2367,7 +2552,7 @@ static int snd_m3_free(m3_t *chip)
 		kfree(chip->substreams);
 	}
 	if (chip->iobase) {
-		snd_m3_outw(chip, HOST_INT_CTRL, 0); /* disable ints */
+		outw(0, chip->iobase + HOST_INT_CTRL); /* disable ints */
 	}
 
 #ifdef CONFIG_PM
@@ -2403,7 +2588,7 @@ static int m3_suspend(snd_card_t *card, 
 	snd_pcm_suspend_all(chip->pcm);
 	snd_ac97_suspend(chip->ac97);
 
-	big_mdelay(10); /* give the assp a chance to idle.. */
+	msleep(10); /* give the assp a chance to idle.. */
 
 	snd_m3_assp_halt(chip);
 
@@ -2486,7 +2671,7 @@ snd_m3_create(snd_card_t *card, struct p
 	m3_t *chip;
 	int i, err;
 	struct m3_quirk *quirk;
-	u16 subsystem_vendor, subsystem_device;
+	struct m3_hv_quirk *hv_quirk;
 	static snd_device_ops_t ops = {
 		.dev_free =	snd_m3_dev_free,
 	};
@@ -2511,6 +2696,8 @@ snd_m3_create(snd_card_t *card, struct p
 	}
 
 	spin_lock_init(&chip->reg_lock);
+	spin_lock_init(&chip->ac97_lock);
+
 	switch (pci->device) {
 	case PCI_DEVICE_ID_ESS_ALLEGRO:
 	case PCI_DEVICE_ID_ESS_ALLEGRO_1:
@@ -2524,18 +2711,25 @@ snd_m3_create(snd_card_t *card, struct p
 	chip->pci = pci;
 	chip->irq = -1;
 
-	pci_read_config_word(pci, PCI_SUBSYSTEM_VENDOR_ID, &subsystem_vendor);
-	pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &subsystem_device);
-
 	for (quirk = m3_quirk_list; quirk->vendor; quirk++) {
-		if (subsystem_vendor == quirk->vendor &&
-		    subsystem_device == quirk->device) {
+		if (pci->subsystem_vendor == quirk->vendor &&
+		    pci->subsystem_device == quirk->device) {
 			printk(KERN_INFO "maestro3: enabled hack for '%s'\n", quirk->name);
 			chip->quirk = quirk;
 			break;
 		}
 	}
 
+	for (hv_quirk = m3_hv_quirk_list; hv_quirk->vendor; hv_quirk++) {
+		if (pci->vendor == hv_quirk->vendor &&
+		    pci->device == hv_quirk->device &&
+		    pci->subsystem_vendor == hv_quirk->subsystem_vendor &&
+		    pci->subsystem_device == hv_quirk->subsystem_device) {
+			chip->hv_quirk = hv_quirk;
+			break;
+		}
+	}
+
 	chip->external_amp = enable_amp;
 	if (amp_gpio >= 0 && amp_gpio <= 0x0f)
 		chip->amp_gpio = amp_gpio;
@@ -2572,6 +2766,8 @@ snd_m3_create(snd_card_t *card, struct p
 	snd_m3_assp_init(chip);
 	snd_m3_amp_enable(chip, 1);
 
+	tasklet_init(&chip->hwvol_tq, snd_m3_update_hw_volume, (unsigned long)chip);
+
 	if (request_irq(pci->irq, snd_m3_interrupt, SA_INTERRUPT|SA_SHIRQ,
 			card->driver, (void *)chip)) {
 		snd_printk("unable to grab IRQ %d\n", pci->irq);
@@ -2702,7 +2898,7 @@ static struct pci_driver driver = {
 	
 static int __init alsa_card_m3_init(void)
 {
-	return pci_module_init(&driver);
+	return pci_register_driver(&driver);
 }
 
 static void __exit alsa_card_m3_exit(void)
diff --git a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c
--- a/sound/pci/mixart/mixart.c
+++ b/sound/pci/mixart/mixart.c
@@ -445,9 +445,9 @@ static int snd_mixart_trigger(snd_pcm_su
 
 static int mixart_sync_nonblock_events(mixart_mgr_t *mgr)
 {
-	int timeout = HZ;
+	unsigned long timeout = jiffies + HZ;
 	while (atomic_read(&mgr->msg_processed) > 0) {
-		if (! timeout--) {
+		if (time_after(jiffies, timeout)) {
 			snd_printk(KERN_ERR "mixart: cannot process nonblock events!\n");
 			return -EBUSY;
 		}
@@ -1431,7 +1431,7 @@ static struct pci_driver driver = {
 
 static int __init alsa_card_mixart_init(void)
 {
-	return pci_module_init(&driver);
+	return pci_register_driver(&driver);
 }
 
 static void __exit alsa_card_mixart_exit(void)
diff --git a/sound/pci/nm256/nm256.c b/sound/pci/nm256/nm256.c
--- a/sound/pci/nm256/nm256.c
+++ b/sound/pci/nm256/nm256.c
@@ -285,43 +285,43 @@ MODULE_DEVICE_TABLE(pci, snd_nm256_ids);
  * lowlvel stuffs
  */
 
-inline static u8
+static inline u8
 snd_nm256_readb(nm256_t *chip, int offset)
 {
 	return readb(chip->cport + offset);
 }
 
-inline static u16
+static inline u16
 snd_nm256_readw(nm256_t *chip, int offset)
 {
 	return readw(chip->cport + offset);
 }
 
-inline static u32
+static inline u32
 snd_nm256_readl(nm256_t *chip, int offset)
 {
 	return readl(chip->cport + offset);
 }
 
-inline static void
+static inline void
 snd_nm256_writeb(nm256_t *chip, int offset, u8 val)
 {
 	writeb(val, chip->cport + offset);
 }
 
-inline static void
+static inline void
 snd_nm256_writew(nm256_t *chip, int offset, u16 val)
 {
 	writew(val, chip->cport + offset);
 }
 
-inline static void
+static inline void
 snd_nm256_writel(nm256_t *chip, int offset, u32 val)
 {
 	writel(val, chip->cport + offset);
 }
 
-inline static void
+static inline void
 snd_nm256_write_buffer(nm256_t *chip, void *src, int offset, int size)
 {
 	offset -= chip->buffer_start;
@@ -926,7 +926,7 @@ snd_nm256_init_chip(nm256_t *chip)
 }
 
 
-inline static void
+static inline void
 snd_nm256_intr_check(nm256_t *chip)
 {
 	if (chip->badintrcount++ > 1000) {
@@ -1645,7 +1645,7 @@ static struct pci_driver driver = {
 
 static int __init alsa_card_nm256_init(void)
 {
-	return pci_module_init(&driver);
+	return pci_register_driver(&driver);
 }
 
 static void __exit alsa_card_nm256_exit(void)
diff --git a/sound/pci/rme32.c b/sound/pci/rme32.c
--- a/sound/pci/rme32.c
+++ b/sound/pci/rme32.c
@@ -2031,7 +2031,7 @@ static struct pci_driver driver = {
 
 static int __init alsa_card_rme32_init(void)
 {
-	return pci_module_init(&driver);
+	return pci_register_driver(&driver);
 }
 
 static void __exit alsa_card_rme32_exit(void)
diff --git a/sound/pci/rme96.c b/sound/pci/rme96.c
--- a/sound/pci/rme96.c
+++ b/sound/pci/rme96.c
@@ -2437,7 +2437,7 @@ static struct pci_driver driver = {
 
 static int __init alsa_card_rme96_init(void)
 {
-	return pci_module_init(&driver);
+	return pci_register_driver(&driver);
 }
 
 static void __exit alsa_card_rme96_exit(void)
diff --git a/sound/pci/rme9652/Makefile b/sound/pci/rme9652/Makefile
--- a/sound/pci/rme9652/Makefile
+++ b/sound/pci/rme9652/Makefile
@@ -5,7 +5,9 @@
 
 snd-rme9652-objs := rme9652.o
 snd-hdsp-objs := hdsp.o
+snd-hdspm-objs := hdspm.o
 
 # Toplevel Module Dependency
 obj-$(CONFIG_SND_RME9652) += snd-rme9652.o
 obj-$(CONFIG_SND_HDSP) += snd-hdsp.o
+obj-$(CONFIG_SND_HDSPM) +=snd-hdspm.o
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
--- a/sound/pci/rme9652/hdsp.c
+++ b/sound/pci/rme9652/hdsp.c
@@ -445,6 +445,7 @@ struct _hdsp {
 	u32                   control2_register;     /* cached value */
 	u32                   creg_spdif;
 	u32                   creg_spdif_stream;
+	int                   clock_source_locked;
 	char                 *card_name;	     /* digiface/multiface */
 	HDSP_IO_Type          io_type;               /* ditto, but for code use */
         unsigned short        firmware_rev;
@@ -559,18 +560,22 @@ static int snd_hammerfall_get_buffer(str
 {
 	dmab->dev.type = SNDRV_DMA_TYPE_DEV;
 	dmab->dev.dev = snd_dma_pci_data(pci);
-	if (! snd_dma_get_reserved_buf(dmab, snd_dma_pci_buf_id(pci))) {
-		if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
-					size, dmab) < 0)
-			return -ENOMEM;
+	if (snd_dma_get_reserved_buf(dmab, snd_dma_pci_buf_id(pci))) {
+		if (dmab->bytes >= size)
+			return 0;
 	}
+	if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
+				size, dmab) < 0)
+		return -ENOMEM;
 	return 0;
 }
 
 static void snd_hammerfall_free_buffer(struct snd_dma_buffer *dmab, struct pci_dev *pci)
 {
-	if (dmab->area)
+	if (dmab->area) {
+		dmab->dev.dev = NULL; /* make it anonymous */
 		snd_dma_reserve_buf(dmab, snd_dma_pci_buf_id(pci));
+	}
 }
 
 
@@ -674,8 +679,7 @@ static int snd_hdsp_load_firmware_from_c
 		}
 
 		if ((1000 / HZ) < 3000) {
-			set_current_state(TASK_UNINTERRUPTIBLE);
-			schedule_timeout((3000 * HZ + 999) / 1000);
+			ssleep(3);
 		} else {
 			mdelay(3000);
 		}
@@ -2091,6 +2095,34 @@ static int snd_hdsp_put_clock_source(snd
 	return change;
 }
 
+static int snd_hdsp_info_clock_source_lock(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+{
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
+	uinfo->count = 1;
+	uinfo->value.integer.min = 0;
+	uinfo->value.integer.max = 1;
+	return 0;
+}
+
+static int snd_hdsp_get_clock_source_lock(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+{
+	hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
+	
+	ucontrol->value.integer.value[0] = hdsp->clock_source_locked;
+	return 0;
+}
+
+static int snd_hdsp_put_clock_source_lock(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+{
+	hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
+	int change;
+
+	change = (int)ucontrol->value.integer.value[0] != hdsp->clock_source_locked;
+	if (change)
+		hdsp->clock_source_locked = ucontrol->value.integer.value[0];
+	return change;
+}
+
 #define HDSP_DA_GAIN(xname, xindex) \
 { .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \
   .name = xname, \
@@ -3113,6 +3145,15 @@ HDSP_SPDIF_EMPHASIS("IEC958 Emphasis Bit
 HDSP_SPDIF_NON_AUDIO("IEC958 Non-audio Bit", 0),
 /* 'Sample Clock Source' complies with the alsa control naming scheme */ 
 HDSP_CLOCK_SOURCE("Sample Clock Source", 0),
+{
+	/* FIXME: should be PCM or MIXER? */
+	/* .iface = SNDRV_CTL_ELEM_IFACE_PCM, */
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	.name = "Sample Clock Source Locking",
+	.info = snd_hdsp_info_clock_source_lock,
+	.get = snd_hdsp_get_clock_source_lock,
+	.put = snd_hdsp_put_clock_source_lock,
+},
 HDSP_SYSTEM_CLOCK_MODE("System Clock Mode", 0),
 HDSP_PREF_SYNC_REF("Preferred Sync Reference", 0),
 HDSP_AUTOSYNC_REF("AutoSync Reference", 0),
@@ -3345,6 +3386,7 @@ snd_hdsp_proc_read(snd_info_entry_t *ent
 	snd_iprintf (buffer, "System Clock Mode: %s\n", system_clock_mode);
 
 	snd_iprintf (buffer, "System Clock Frequency: %d\n", hdsp->system_sample_rate);
+	snd_iprintf (buffer, "System Clock Locked: %s\n", hdsp->clock_source_locked ? "Yes" : "No");
 		
 	snd_iprintf(buffer, "\n");
 
@@ -3849,13 +3891,14 @@ static int snd_hdsp_hw_params(snd_pcm_su
 	 */
 
 	spin_lock_irq(&hdsp->lock);
-	if ((err = hdsp_set_rate(hdsp, params_rate(params), 0)) < 0) {
-		spin_unlock_irq(&hdsp->lock);
-		_snd_pcm_hw_param_setempty(params, SNDRV_PCM_HW_PARAM_RATE);
-		return err;
-	} else {
-		spin_unlock_irq(&hdsp->lock);
+	if (! hdsp->clock_source_locked) {
+		if ((err = hdsp_set_rate(hdsp, params_rate(params), 0)) < 0) {
+			spin_unlock_irq(&hdsp->lock);
+			_snd_pcm_hw_param_setempty(params, SNDRV_PCM_HW_PARAM_RATE);
+			return err;
+		}
 	}
+	spin_unlock_irq(&hdsp->lock);
 
 	if ((err = hdsp_set_interrupt_interval(hdsp, params_period_size(params))) < 0) {
 		_snd_pcm_hw_param_setempty(params, SNDRV_PCM_HW_PARAM_PERIOD_SIZE);
@@ -4280,13 +4323,17 @@ static int snd_hdsp_playback_open(snd_pc
 
 	snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
 	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, &hdsp_hw_constraints_period_sizes);
-	if (hdsp->io_type == H9632) {
-		runtime->hw.channels_min = hdsp->qs_out_channels;
-		runtime->hw.channels_max = hdsp->ss_out_channels;
+	if (hdsp->clock_source_locked) {
+		runtime->hw.rate_min = runtime->hw.rate_max = hdsp->system_sample_rate;
+	} else if (hdsp->io_type == H9632) {
 		runtime->hw.rate_max = 192000;
 		runtime->hw.rates = SNDRV_PCM_RATE_KNOT;
 		snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hdsp_hw_constraints_9632_sample_rates);
 	}
+	if (hdsp->io_type == H9632) {
+		runtime->hw.channels_min = hdsp->qs_out_channels;
+		runtime->hw.channels_max = hdsp->ss_out_channels;
+	}	
 	
 	snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
 			     snd_hdsp_hw_rule_out_channels, hdsp,
@@ -4912,19 +4959,9 @@ static int __devinit hdsp_request_fw_loa
 		release_firmware(fw);
 		return -EINVAL;
 	}
-#ifdef SNDRV_BIG_ENDIAN
-	{
-		int i;
-		u32 *src = (u32*)fw->data;
-		for (i = 0; i < ARRAY_SIZE(hdsp->firmware_cache); i++, src++)
-			hdsp->firmware_cache[i] = ((*src & 0x000000ff) << 16) |
-				((*src & 0x0000ff00) << 8)  |
-				((*src & 0x00ff0000) >> 8)  |
-				((*src & 0xff000000) >> 16);
-	}
-#else
+
 	memcpy(hdsp->firmware_cache, fw->data, sizeof(hdsp->firmware_cache));
-#endif
+
 	release_firmware(fw);
 		
 	hdsp->state |= HDSP_FirmwareCached;
@@ -5042,8 +5079,7 @@ static int __devinit snd_hdsp_create(snd
 	if (!is_9652 && !is_9632) {
 		/* we wait 2 seconds to let freshly inserted cardbus cards do their hardware init */
  		if ((1000 / HZ) < 2000) {
-			set_current_state(TASK_UNINTERRUPTIBLE);
-			schedule_timeout((2000 * HZ + 999) / 1000);
+			ssleep(2);
 		} else {
 			mdelay(2000);
 		}
@@ -5194,7 +5230,7 @@ static struct pci_driver driver = {
 
 static int __init alsa_card_hdsp_init(void)
 {
-	return pci_module_init(&driver);
+	return pci_register_driver(&driver);
 }
 
 static void __exit alsa_card_hdsp_exit(void)
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c
new file mode 100644
--- /dev/null
+++ b/sound/pci/rme9652/hdspm.c
@@ -0,0 +1,3671 @@
+/*   -*- linux-c -*-
+ *
+ *   ALSA driver for RME Hammerfall DSP MADI audio interface(s)
+ *
+ *      Copyright (c) 2003 Winfried Ritsch (IEM)
+ *      code based on hdsp.c   Paul Davis
+ *                             Marcus Andersson
+ *                             Thomas Charbonnel
+ *
+ *   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 <sound/driver.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/moduleparam.h>
+#include <linux/slab.h>
+#include <linux/pci.h>
+#include <asm/io.h>
+
+#include <sound/core.h>
+#include <sound/control.h>
+#include <sound/pcm.h>
+#include <sound/info.h>
+#include <sound/asoundef.h>
+#include <sound/rawmidi.h>
+#include <sound/hwdep.h>
+#include <sound/initval.h>
+
+#include <sound/hdspm.h>
+
+static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;	  /* Index 0-MAX */
+static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	  /* ID for this card */
+static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;/* Enable this card */
+
+/* Disable precise pointer at start */
+static int precise_ptr[SNDRV_CARDS];
+
+/* Send all playback to line outs */
+static int line_outs_monitor[SNDRV_CARDS];
+
+/* Enable Analog Outs on Channel 63/64 by default */
+static int enable_monitor[SNDRV_CARDS];
+
+module_param_array(index, int, NULL, 0444);
+MODULE_PARM_DESC(index, "Index value for RME HDSPM interface.");
+
+module_param_array(id, charp, NULL, 0444);
+MODULE_PARM_DESC(id, "ID string for RME HDSPM interface.");
+
+module_param_array(enable, bool, NULL, 0444);
+MODULE_PARM_DESC(enable, "Enable/disable specific HDSPM soundcards.");
+
+module_param_array(precise_ptr, bool, NULL, 0444);
+MODULE_PARM_DESC(precise_ptr, "Enable precise pointer, or disable.");
+
+module_param_array(line_outs_monitor, bool, NULL, 0444);
+MODULE_PARM_DESC(line_outs_monitor,
+		 "Send playback streams to analog outs by default.");
+
+module_param_array(enable_monitor, bool, NULL, 0444);
+MODULE_PARM_DESC(enable_monitor,
+		 "Enable Analog Out on Channel 63/64 by default.");
+
+MODULE_AUTHOR
+      ("Winfried Ritsch <ritsch_AT_iem.at>, Paul Davis <paul@linuxaudiosystems.com>, "
+       "Marcus Andersson, Thomas Charbonnel <thomas@undata.org>");
+MODULE_DESCRIPTION("RME HDSPM");
+MODULE_LICENSE("GPL");
+MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
+
+/* --- Write registers. --- 
+  These are defined as byte-offsets from the iobase value.  */
+
+#define HDSPM_controlRegister	     64
+#define HDSPM_interruptConfirmation  96
+#define HDSPM_control2Reg	     256  /* not in specs ???????? */
+#define HDSPM_midiDataOut0  	     352  /* just believe in old code */
+#define HDSPM_midiDataOut1  	     356
+
+/* DMA enable for 64 channels, only Bit 0 is relevant */
+#define HDSPM_outputEnableBase       512  /* 512-767  input  DMA */ 
+#define HDSPM_inputEnableBase        768  /* 768-1023 output DMA */
+
+/* 16 page addresses for each of the 64 channels DMA buffer in and out 
+   (each 64k=16*4k) Buffer must be 4k aligned (which is default i386 ????) */
+#define HDSPM_pageAddressBufferOut       8192
+#define HDSPM_pageAddressBufferIn        (HDSPM_pageAddressBufferOut+64*16*4)
+
+#define HDSPM_MADI_mixerBase    32768	/* 32768-65535 for 2x64x64 Fader */
+
+#define HDSPM_MATRIX_MIXER_SIZE  8192	/* = 2*64*64 * 4 Byte => 32kB */
+
+/* --- Read registers. ---
+   These are defined as byte-offsets from the iobase value */
+#define HDSPM_statusRegister    0
+#define HDSPM_statusRegister2  96
+
+#define HDSPM_midiDataIn0     360
+#define HDSPM_midiDataIn1     364
+
+/* status is data bytes in MIDI-FIFO (0-128) */
+#define HDSPM_midiStatusOut0  384	
+#define HDSPM_midiStatusOut1  388	
+#define HDSPM_midiStatusIn0   392	
+#define HDSPM_midiStatusIn1   396	
+
+
+/* the meters are regular i/o-mapped registers, but offset
+   considerably from the rest. the peak registers are reset
+   when read; the least-significant 4 bits are full-scale counters; 
+   the actual peak value is in the most-significant 24 bits.
+*/
+#define HDSPM_MADI_peakrmsbase 	4096	/* 4096-8191 2x64x32Bit Meters */
+
+/* --- Control Register bits --------- */
+#define HDSPM_Start                (1<<0) /* start engine */
+
+#define HDSPM_Latency0             (1<<1) /* buffer size = 2^n */
+#define HDSPM_Latency1             (1<<2) /* where n is defined */
+#define HDSPM_Latency2             (1<<3) /* by Latency{2,1,0} */
+
+#define HDSPM_ClockModeMaster      (1<<4) /* 1=Master, 0=Slave/Autosync */
+
+#define HDSPM_AudioInterruptEnable (1<<5) /* what do you think ? */
+
+#define HDSPM_Frequency0  (1<<6)  /* 0=44.1kHz/88.2kHz 1=48kHz/96kHz */
+#define HDSPM_Frequency1  (1<<7)  /* 0=32kHz/64kHz */
+#define HDSPM_DoubleSpeed (1<<8)  /* 0=normal speed, 1=double speed */
+#define HDSPM_QuadSpeed   (1<<31) /* quad speed bit, not implemented now */
+
+#define HDSPM_TX_64ch     (1<<10) /* Output 64channel MODE=1,
+				     56channelMODE=0 */
+
+#define HDSPM_AutoInp     (1<<11) /* Auto Input (takeover) == Safe Mode, 
+                                     0=off, 1=on  */
+
+#define HDSPM_InputSelect0 (1<<14) /* Input select 0= optical, 1=coax */
+#define HDSPM_InputSelect1 (1<<15) /* should be 0 */
+
+#define HDSPM_SyncRef0     (1<<16) /* 0=WOrd, 1=MADI */
+#define HDSPM_SyncRef1     (1<<17) /* should be 0 */
+
+#define HDSPM_clr_tms      (1<<19) /* clear track marker, do not use 
+                                      AES additional bits in
+				      lower 5 Audiodatabits ??? */
+
+#define HDSPM_Midi0InterruptEnable (1<<22)
+#define HDSPM_Midi1InterruptEnable (1<<23)
+
+#define HDSPM_LineOut (1<<24) /* Analog Out on channel 63/64 on=1, mute=0 */
+
+
+/* --- bit helper defines */
+#define HDSPM_LatencyMask    (HDSPM_Latency0|HDSPM_Latency1|HDSPM_Latency2)
+#define HDSPM_FrequencyMask  (HDSPM_Frequency0|HDSPM_Frequency1)
+#define HDSPM_InputMask      (HDSPM_InputSelect0|HDSPM_InputSelect1)
+#define HDSPM_InputOptical   0
+#define HDSPM_InputCoaxial   (HDSPM_InputSelect0)
+#define HDSPM_SyncRefMask    (HDSPM_SyncRef0|HDSPM_SyncRef1)
+#define HDSPM_SyncRef_Word   0
+#define HDSPM_SyncRef_MADI   (HDSPM_SyncRef0)
+
+#define HDSPM_SYNC_FROM_WORD 0	/* Preferred sync reference */
+#define HDSPM_SYNC_FROM_MADI 1	/* choices - used by "pref_sync_ref" */
+
+#define HDSPM_Frequency32KHz    HDSPM_Frequency0
+#define HDSPM_Frequency44_1KHz  HDSPM_Frequency1
+#define HDSPM_Frequency48KHz   (HDSPM_Frequency1|HDSPM_Frequency0)
+#define HDSPM_Frequency64KHz   (HDSPM_DoubleSpeed|HDSPM_Frequency0)
+#define HDSPM_Frequency88_2KHz (HDSPM_DoubleSpeed|HDSPM_Frequency1)
+#define HDSPM_Frequency96KHz   (HDSPM_DoubleSpeed|HDSPM_Frequency1|HDSPM_Frequency0)
+
+/* --- for internal discrimination */
+#define HDSPM_CLOCK_SOURCE_AUTOSYNC          0	/* Sample Clock Sources */
+#define HDSPM_CLOCK_SOURCE_INTERNAL_32KHZ    1
+#define HDSPM_CLOCK_SOURCE_INTERNAL_44_1KHZ  2
+#define HDSPM_CLOCK_SOURCE_INTERNAL_48KHZ    3
+#define HDSPM_CLOCK_SOURCE_INTERNAL_64KHZ    4
+#define HDSPM_CLOCK_SOURCE_INTERNAL_88_2KHZ  5
+#define HDSPM_CLOCK_SOURCE_INTERNAL_96KHZ    6
+#define HDSPM_CLOCK_SOURCE_INTERNAL_128KHZ   7
+#define HDSPM_CLOCK_SOURCE_INTERNAL_176_4KHZ 8
+#define HDSPM_CLOCK_SOURCE_INTERNAL_192KHZ   9
+
+/* Synccheck Status */
+#define HDSPM_SYNC_CHECK_NO_LOCK 0
+#define HDSPM_SYNC_CHECK_LOCK    1
+#define HDSPM_SYNC_CHECK_SYNC	 2
+
+/* AutoSync References - used by "autosync_ref" control switch */
+#define HDSPM_AUTOSYNC_FROM_WORD      0
+#define HDSPM_AUTOSYNC_FROM_MADI      1
+#define HDSPM_AUTOSYNC_FROM_NONE      2
+
+/* Possible sources of MADI input */
+#define HDSPM_OPTICAL 0		/* optical   */
+#define HDSPM_COAXIAL 1		/* BNC */
+
+#define hdspm_encode_latency(x)       (((x)<<1) & HDSPM_LatencyMask)
+#define hdspm_decode_latency(x)       (((x) & HDSPM_LatencyMask)>>1)
+
+#define hdspm_encode_in(x) (((x)&0x3)<<14)
+#define hdspm_decode_in(x) (((x)>>14)&0x3)
+
+/* --- control2 register bits --- */
+#define HDSPM_TMS             (1<<0)
+#define HDSPM_TCK             (1<<1)
+#define HDSPM_TDI             (1<<2)
+#define HDSPM_JTAG            (1<<3)
+#define HDSPM_PWDN            (1<<4)
+#define HDSPM_PROGRAM	      (1<<5)
+#define HDSPM_CONFIG_MODE_0   (1<<6)
+#define HDSPM_CONFIG_MODE_1   (1<<7)
+/*#define HDSPM_VERSION_BIT     (1<<8) not defined any more*/
+#define HDSPM_BIGENDIAN_MODE  (1<<9)
+#define HDSPM_RD_MULTIPLE     (1<<10)
+
+/* --- Status Register bits --- */
+#define HDSPM_audioIRQPending    (1<<0)	/* IRQ is high and pending */
+#define HDSPM_RX_64ch            (1<<1)	/* Input 64chan. MODE=1, 56chn. MODE=0 */
+#define HDSPM_AB_int             (1<<2)	/* InputChannel Opt=0, Coax=1 (like inp0) */
+#define HDSPM_madiLock           (1<<3)	/* MADI Locked =1, no=0 */
+
+#define HDSPM_BufferPositionMask 0x000FFC0 /* Bit 6..15 : h/w buffer pointer */
+                                           /* since 64byte accurate last 6 bits 
+                                              are not used */
+
+#define HDSPM_madiSync          (1<<18) /* MADI is in sync */
+#define HDSPM_DoubleSpeedStatus (1<<19) /* (input) card in double speed */
+
+#define HDSPM_madiFreq0         (1<<22)	/* system freq 0=error */
+#define HDSPM_madiFreq1         (1<<23)	/* 1=32, 2=44.1 3=48 */
+#define HDSPM_madiFreq2         (1<<24)	/* 4=64, 5=88.2 6=96 */
+#define HDSPM_madiFreq3         (1<<25)	/* 7=128, 8=176.4 9=192 */
+
+#define HDSPM_BufferID          (1<<26)	/* (Double)Buffer ID toggles with Interrupt */
+#define HDSPM_midi0IRQPending   (1<<30)	/* MIDI IRQ is pending  */
+#define HDSPM_midi1IRQPending   (1<<31)	/* and aktiv */
+
+/* --- status bit helpers */
+#define HDSPM_madiFreqMask  (HDSPM_madiFreq0|HDSPM_madiFreq1|HDSPM_madiFreq2|HDSPM_madiFreq3)
+#define HDSPM_madiFreq32    (HDSPM_madiFreq0)
+#define HDSPM_madiFreq44_1  (HDSPM_madiFreq1)
+#define HDSPM_madiFreq48    (HDSPM_madiFreq0|HDSPM_madiFreq1)
+#define HDSPM_madiFreq64    (HDSPM_madiFreq2)
+#define HDSPM_madiFreq88_2  (HDSPM_madiFreq0|HDSPM_madiFreq2)
+#define HDSPM_madiFreq96    (HDSPM_madiFreq1|HDSPM_madiFreq2)
+#define HDSPM_madiFreq128   (HDSPM_madiFreq0|HDSPM_madiFreq1|HDSPM_madiFreq2)
+#define HDSPM_madiFreq176_4 (HDSPM_madiFreq3)
+#define HDSPM_madiFreq192   (HDSPM_madiFreq3|HDSPM_madiFreq0)
+
+/* Status2 Register bits */
+
+#define HDSPM_version0 (1<<0)	/* not realy defined but I guess */
+#define HDSPM_version1 (1<<1)	/* in former cards it was ??? */
+#define HDSPM_version2 (1<<2)
+
+#define HDSPM_wcLock (1<<3)	/* Wordclock is detected and locked */
+#define HDSPM_wcSync (1<<4)	/* Wordclock is in sync with systemclock */
+
+#define HDSPM_wc_freq0 (1<<5)	/* input freq detected via autosync  */
+#define HDSPM_wc_freq1 (1<<6)	/* 001=32, 010==44.1, 011=48, */
+#define HDSPM_wc_freq2 (1<<7)	/* 100=64, 101=88.2, 110=96, */
+/* missing Bit   for               111=128, 1000=176.4, 1001=192 */
+
+#define HDSPM_SelSyncRef0 (1<<8)	/* Sync Source in slave mode */
+#define HDSPM_SelSyncRef1 (1<<9)	/* 000=word, 001=MADI, */
+#define HDSPM_SelSyncRef2 (1<<10)	/* 111=no valid signal */
+
+#define HDSPM_wc_valid (HDSPM_wcLock|HDSPM_wcSync)
+
+#define HDSPM_wcFreqMask  (HDSPM_wc_freq0|HDSPM_wc_freq1|HDSPM_wc_freq2)
+#define HDSPM_wcFreq32    (HDSPM_wc_freq0)
+#define HDSPM_wcFreq44_1  (HDSPM_wc_freq1)
+#define HDSPM_wcFreq48    (HDSPM_wc_freq0|HDSPM_wc_freq1)
+#define HDSPM_wcFreq64    (HDSPM_wc_freq2)
+#define HDSPM_wcFreq88_2  (HDSPM_wc_freq0|HDSPM_wc_freq2)
+#define HDSPM_wcFreq96    (HDSPM_wc_freq1|HDSPM_wc_freq2)
+
+
+#define HDSPM_SelSyncRefMask       (HDSPM_SelSyncRef0|HDSPM_SelSyncRef1|HDSPM_SelSyncRef2)
+#define HDSPM_SelSyncRef_WORD      0
+#define HDSPM_SelSyncRef_MADI      (HDSPM_SelSyncRef0)
+#define HDSPM_SelSyncRef_NVALID    (HDSPM_SelSyncRef0|HDSPM_SelSyncRef1|HDSPM_SelSyncRef2)
+
+/* Mixer Values */
+#define UNITY_GAIN          32768	/* = 65536/2 */
+#define MINUS_INFINITY_GAIN 0
+
+/* PCI info */
+#ifndef PCI_VENDOR_ID_XILINX
+#define PCI_VENDOR_ID_XILINX		0x10ee
+#endif
+#ifndef PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP
+#define PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP 0x3fc5
+#endif
+#ifndef PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP_MADI
+#define PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP_MADI 0x3fc6
+#endif
+
+
+/* Number of channels for different Speed Modes */
+#define MADI_SS_CHANNELS       64
+#define MADI_DS_CHANNELS       32
+#define MADI_QS_CHANNELS       16
+
+/* the size of a substream (1 mono data stream) */
+#define HDSPM_CHANNEL_BUFFER_SAMPLES  (16*1024)
+#define HDSPM_CHANNEL_BUFFER_BYTES    (4*HDSPM_CHANNEL_BUFFER_SAMPLES)
+
+/* the size of the area we need to allocate for DMA transfers. the
+   size is the same regardless of the number of channels, and
+   also the latency to use. 
+   for one direction !!!
+*/
+#define HDSPM_DMA_AREA_BYTES (HDSPM_MAX_CHANNELS * HDSPM_CHANNEL_BUFFER_BYTES)
+#define HDSPM_DMA_AREA_KILOBYTES (HDSPM_DMA_AREA_BYTES/1024)
+
+typedef struct _hdspm hdspm_t;
+typedef struct _hdspm_midi hdspm_midi_t;
+
+struct _hdspm_midi {
+	hdspm_t *hdspm;
+	int id;
+	snd_rawmidi_t *rmidi;
+	snd_rawmidi_substream_t *input;
+	snd_rawmidi_substream_t *output;
+	char istimer;		/* timer in use */
+	struct timer_list timer;
+	spinlock_t lock;
+	int pending;
+};
+
+struct _hdspm {
+        spinlock_t lock;
+        snd_pcm_substream_t *capture_substream;	 /* only one playback */
+        snd_pcm_substream_t *playback_substream; /* and/or capture stream */
+
+	char *card_name;	     /* for procinfo */
+	unsigned short firmware_rev; /* dont know if relevant */
+
+	int precise_ptr;	/* use precise pointers, to be tested */
+	int monitor_outs;	/* set up monitoring outs init flag */
+
+	u32 control_register;	/* cached value */
+	u32 control2_register;	/* cached value */
+
+	hdspm_midi_t midi[2];
+	struct tasklet_struct midi_tasklet;
+
+	size_t period_bytes;
+	unsigned char ss_channels;	/* channels of card in single speed */
+	unsigned char ds_channels;	/* Double Speed */
+	unsigned char qs_channels;	/* Quad Speed */
+
+	unsigned char *playback_buffer;	/* suitably aligned address */
+	unsigned char *capture_buffer;	/* suitably aligned address */
+
+	pid_t capture_pid;	/* process id which uses capture */
+	pid_t playback_pid;	/* process id which uses capture */
+	int running;		/* running status */
+
+	int last_external_sample_rate;	/* samplerate mystic ... */
+	int last_internal_sample_rate;
+	int system_sample_rate;
+
+	char *channel_map;	/* channel map for DS and Quadspeed */
+
+	int dev;		/* Hardware vars... */
+	int irq;
+	unsigned long port;
+	void __iomem *iobase;
+
+	int irq_count;		/* for debug */
+
+	snd_card_t *card;	/* one card */
+	snd_pcm_t *pcm;		/* has one pcm */
+	snd_hwdep_t *hwdep;	/* and a hwdep for additional ioctl */
+	struct pci_dev *pci;	/* and an pci info */
+
+	/* Mixer vars */
+	snd_kcontrol_t *playback_mixer_ctls[HDSPM_MAX_CHANNELS];	/* fast alsa mixer */
+	snd_kcontrol_t *input_mixer_ctls[HDSPM_MAX_CHANNELS];	/* but input to much, so not used */
+	hdspm_mixer_t *mixer;	/* full mixer accessable over mixer ioctl or hwdep-device */
+
+};
+
+/* These tables map the ALSA channels 1..N to the channels that we
+   need to use in order to find the relevant channel buffer. RME
+   refer to this kind of mapping as between "the ADAT channel and
+   the DMA channel." We index it using the logical audio channel,
+   and the value is the DMA channel (i.e. channel buffer number)
+   where the data for that channel can be read/written from/to.
+*/
+
+static char channel_map_madi_ss[HDSPM_MAX_CHANNELS] = {
+   0, 1, 2, 3, 4, 5, 6, 7,
+   8, 9, 10, 11, 12, 13, 14, 15,
+   16, 17, 18, 19, 20, 21, 22, 23,
+   24, 25, 26, 27, 28, 29, 30, 31,
+   32, 33, 34, 35, 36, 37, 38, 39,
+   40, 41, 42, 43, 44, 45, 46, 47,
+   48, 49, 50, 51, 52, 53, 54, 55,
+   56, 57, 58, 59, 60, 61, 62, 63
+};
+
+static char channel_map_madi_ds[HDSPM_MAX_CHANNELS] = {
+  0, 2, 4, 6, 8, 10, 12, 14,
+  16, 18, 20, 22, 24, 26, 28, 30,
+  32, 34, 36, 38, 40, 42, 44, 46,
+  48, 50, 52, 54, 56, 58, 60, 62,
+  -1, -1, -1, -1, -1, -1, -1, -1,
+  -1, -1, -1, -1, -1, -1, -1, -1,
+  -1, -1, -1, -1, -1, -1, -1, -1,
+  -1, -1, -1, -1, -1, -1, -1, -1
+};
+
+static char channel_map_madi_qs[HDSPM_MAX_CHANNELS] = {
+  0,   4,  8, 12, 16, 20, 24,  28,  
+  32, 36, 40, 44, 48, 52, 56,  60
+  -1, -1, -1, -1, -1, -1, -1, -1,  
+  -1, -1, -1, -1, -1, -1, -1, -1,  
+  -1, -1, -1, -1, -1, -1, -1, -1, 
+  -1, -1, -1, -1, -1, -1, -1, -1, 
+  -1, -1, -1, -1, -1, -1, -1, -1, 
+  -1, -1, -1, -1, -1, -1, -1, -1
+};
+
+
+static struct pci_device_id snd_hdspm_ids[] = {
+	{
+	 .vendor = PCI_VENDOR_ID_XILINX,
+	 .device = PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP_MADI,
+	 .subvendor = PCI_ANY_ID,
+	 .subdevice = PCI_ANY_ID,
+	 .class = 0,
+	 .class_mask = 0,
+	 .driver_data = 0},
+	{0,}
+};
+
+MODULE_DEVICE_TABLE(pci, snd_hdspm_ids);
+
+/* prototypes */
+static int __devinit snd_hdspm_create_alsa_devices(snd_card_t * card,
+						   hdspm_t * hdspm);
+static int __devinit snd_hdspm_create_pcm(snd_card_t * card,
+					  hdspm_t * hdspm);
+
+static inline void snd_hdspm_initialize_midi_flush(hdspm_t * hdspm);
+static int hdspm_update_simple_mixer_controls(hdspm_t * hdspm);
+static int hdspm_autosync_ref(hdspm_t * hdspm);
+static int snd_hdspm_set_defaults(hdspm_t * hdspm);
+static void hdspm_set_sgbuf(hdspm_t * hdspm, struct snd_sg_buf *sgbuf,
+			     unsigned int reg, int channels);
+
+/* Write/read to/from HDSPM with Adresses in Bytes
+   not words but only 32Bit writes are allowed */
+
+static inline void hdspm_write(hdspm_t * hdspm, unsigned int reg,
+			       unsigned int val)
+{
+	writel(val, hdspm->iobase + reg);
+}
+
+static inline unsigned int hdspm_read(hdspm_t * hdspm, unsigned int reg)
+{
+	return readl(hdspm->iobase + reg);
+}
+
+/* for each output channel (chan) I have an Input (in) and Playback (pb) Fader 
+   mixer is write only on hardware so we have to cache him for read 
+   each fader is a u32, but uses only the first 16 bit */
+
+static inline int hdspm_read_in_gain(hdspm_t * hdspm, unsigned int chan,
+				     unsigned int in)
+{
+	if (chan > HDSPM_MIXER_CHANNELS || in > HDSPM_MIXER_CHANNELS)
+		return 0;
+
+	return hdspm->mixer->ch[chan].in[in];
+}
+
+static inline int hdspm_read_pb_gain(hdspm_t * hdspm, unsigned int chan,
+				     unsigned int pb)
+{
+	if (chan > HDSPM_MIXER_CHANNELS || pb > HDSPM_MIXER_CHANNELS)
+		return 0;
+	return hdspm->mixer->ch[chan].pb[pb];
+}
+
+static inline int hdspm_write_in_gain(hdspm_t * hdspm, unsigned int chan,
+				      unsigned int in, unsigned short data)
+{
+	if (chan >= HDSPM_MIXER_CHANNELS || in >= HDSPM_MIXER_CHANNELS)
+		return -1;
+
+	hdspm_write(hdspm,
+		    HDSPM_MADI_mixerBase +
+		    ((in + 128 * chan) * sizeof(u32)),
+		    (hdspm->mixer->ch[chan].in[in] = data & 0xFFFF));
+	return 0;
+}
+
+static inline int hdspm_write_pb_gain(hdspm_t * hdspm, unsigned int chan,
+				      unsigned int pb, unsigned short data)
+{
+	if (chan >= HDSPM_MIXER_CHANNELS || pb >= HDSPM_MIXER_CHANNELS)
+		return -1;
+
+	hdspm_write(hdspm,
+		    HDSPM_MADI_mixerBase +
+		    ((64 + pb + 128 * chan) * sizeof(u32)),
+		    (hdspm->mixer->ch[chan].pb[pb] = data & 0xFFFF));
+	return 0;
+}
+
+
+/* enable DMA for specific channels, now available for DSP-MADI */
+static inline void snd_hdspm_enable_in(hdspm_t * hdspm, int i, int v)
+{
+	hdspm_write(hdspm, HDSPM_inputEnableBase + (4 * i), v);
+}
+
+static inline void snd_hdspm_enable_out(hdspm_t * hdspm, int i, int v)
+{
+	hdspm_write(hdspm, HDSPM_outputEnableBase + (4 * i), v);
+}
+
+/* check if same process is writing and reading */
+static inline int snd_hdspm_use_is_exclusive(hdspm_t * hdspm)
+{
+	unsigned long flags;
+	int ret = 1;
+
+	spin_lock_irqsave(&hdspm->lock, flags);
+	if ((hdspm->playback_pid != hdspm->capture_pid) &&
+	    (hdspm->playback_pid >= 0) && (hdspm->capture_pid >= 0)) {
+		ret = 0;
+	}
+	spin_unlock_irqrestore(&hdspm->lock, flags);
+	return ret;
+}
+
+/* check for external sample rate */
+static inline int hdspm_external_sample_rate(hdspm_t * hdspm)
+{
+	unsigned int status2 = hdspm_read(hdspm, HDSPM_statusRegister2);
+	unsigned int status = hdspm_read(hdspm, HDSPM_statusRegister);
+	unsigned int rate_bits;
+	int rate = 0;
+
+	/* if wordclock has synced freq and wordclock is valid */
+	if ((status2 & HDSPM_wcLock) != 0 &&
+	    (status & HDSPM_SelSyncRef0) == 0) {
+
+		rate_bits = status2 & HDSPM_wcFreqMask;
+
+		switch (rate_bits) {
+		case HDSPM_wcFreq32:
+			rate = 32000;
+			break;
+		case HDSPM_wcFreq44_1:
+			rate = 44100;
+			break;
+		case HDSPM_wcFreq48:
+			rate = 48000;
+			break;
+		case HDSPM_wcFreq64:
+			rate = 64000;
+			break;
+		case HDSPM_wcFreq88_2:
+			rate = 88200;
+			break;
+		case HDSPM_wcFreq96:
+			rate = 96000;
+			break;
+			/* Quadspeed Bit missing ???? */
+		default:
+			rate = 0;
+			break;
+		}
+	}
+
+	/* if rate detected and Syncref is Word than have it, word has priority to MADI */
+	if (rate != 0
+	    && (status2 & HDSPM_SelSyncRefMask) == HDSPM_SelSyncRef_WORD)
+		return rate;
+
+	/* maby a madi input (which is taken if sel sync is madi) */
+	if (status & HDSPM_madiLock) {
+		rate_bits = status & HDSPM_madiFreqMask;
+
+		switch (rate_bits) {
+		case HDSPM_madiFreq32:
+			rate = 32000;
+			break;
+		case HDSPM_madiFreq44_1:
+			rate = 44100;
+			break;
+		case HDSPM_madiFreq48:
+			rate = 48000;
+			break;
+		case HDSPM_madiFreq64:
+			rate = 64000;
+			break;
+		case HDSPM_madiFreq88_2:
+			rate = 88200;
+			break;
+		case HDSPM_madiFreq96:
+			rate = 96000;
+			break;
+		case HDSPM_madiFreq128:
+			rate = 128000;
+			break;
+		case HDSPM_madiFreq176_4:
+			rate = 176400;
+			break;
+		case HDSPM_madiFreq192:
+			rate = 192000;
+			break;
+		default:
+			rate = 0;
+			break;
+		}
+	}
+	return rate;
+}
+
+/* Latency function */
+static inline void hdspm_compute_period_size(hdspm_t * hdspm)
+{
+	hdspm->period_bytes =
+	    1 << ((hdspm_decode_latency(hdspm->control_register) + 8));
+}
+
+static snd_pcm_uframes_t hdspm_hw_pointer(hdspm_t * hdspm)
+{
+	int position;
+
+	position = hdspm_read(hdspm, HDSPM_statusRegister);
+
+	if (!hdspm->precise_ptr) {
+		return (position & HDSPM_BufferID) ? (hdspm->period_bytes /
+						      4) : 0;
+	}
+
+	/* hwpointer comes in bytes and is 64Bytes accurate (by docu since PCI Burst)
+	   i have experimented that it is at most 64 Byte to much for playing 
+	   so substraction of 64 byte should be ok for ALSA, but use it only
+	   for application where you know what you do since if you come to
+	   near with record pointer it can be a disaster */
+
+	position &= HDSPM_BufferPositionMask;
+	position = ((position - 64) % (2 * hdspm->period_bytes)) / 4;
+
+	return position;
+}
+
+
+static inline void hdspm_start_audio(hdspm_t * s)
+{
+	s->control_register |= (HDSPM_AudioInterruptEnable | HDSPM_Start);
+	hdspm_write(s, HDSPM_controlRegister, s->control_register);
+}
+
+static inline void hdspm_stop_audio(hdspm_t * s)
+{
+	s->control_register &= ~(HDSPM_Start | HDSPM_AudioInterruptEnable);
+	hdspm_write(s, HDSPM_controlRegister, s->control_register);
+}
+
+/* should I silence all or only opened ones ? doit all for first even is 4MB*/
+static inline void hdspm_silence_playback(hdspm_t * hdspm)
+{
+	int i;
+	int n = hdspm->period_bytes;
+	void *buf = hdspm->playback_buffer;
+
+	snd_assert(buf != NULL, return);
+
+	for (i = 0; i < HDSPM_MAX_CHANNELS; i++) {
+		memset(buf, 0, n);
+		buf += HDSPM_CHANNEL_BUFFER_BYTES;
+	}
+}
+
+static int hdspm_set_interrupt_interval(hdspm_t * s, unsigned int frames)
+{
+	int n;
+
+	spin_lock_irq(&s->lock);
+
+	frames >>= 7;
+	n = 0;
+	while (frames) {
+		n++;
+		frames >>= 1;
+	}
+	s->control_register &= ~HDSPM_LatencyMask;
+	s->control_register |= hdspm_encode_latency(n);
+
+	hdspm_write(s, HDSPM_controlRegister, s->control_register);
+
+	hdspm_compute_period_size(s);
+
+	spin_unlock_irq(&s->lock);
+
+	return 0;
+}
+
+
+/* dummy set rate lets see what happens */
+static int hdspm_set_rate(hdspm_t * hdspm, int rate, int called_internally)
+{
+	int reject_if_open = 0;
+	int current_rate;
+	int rate_bits;
+	int not_set = 0;
+
+	/* ASSUMPTION: hdspm->lock is either set, or there is no need for
+	   it (e.g. during module initialization).
+	 */
+
+	if (!(hdspm->control_register & HDSPM_ClockModeMaster)) {
+
+	        /* SLAVE --- */ 
+		if (called_internally) {
+
+        	  /* request from ctl or card initialization 
+	             just make a warning an remember setting 
+		     for future master mode switching */
+    
+			snd_printk
+			    (KERN_WARNING "HDSPM: Warning: device is not running as a clock master.\n");
+			not_set = 1;
+		} else {
+
+			/* hw_param request while in AutoSync mode */
+			int external_freq =
+			    hdspm_external_sample_rate(hdspm);
+
+			if ((hdspm_autosync_ref(hdspm) ==
+			     HDSPM_AUTOSYNC_FROM_NONE)) {
+
+				snd_printk(KERN_WARNING "HDSPM: Detected no Externel Sync \n");
+				not_set = 1;
+
+			} else if (rate != external_freq) {
+
+				snd_printk
+				    (KERN_WARNING "HDSPM: Warning: No AutoSync source for requested rate\n");
+				not_set = 1;
+			}
+		}
+	}
+
+	current_rate = hdspm->system_sample_rate;
+
+	/* Changing between Singe, Double and Quad speed is not
+	   allowed if any substreams are open. This is because such a change
+	   causes a shift in the location of the DMA buffers and a reduction
+	   in the number of available buffers.
+
+	   Note that a similar but essentially insoluble problem exists for
+	   externally-driven rate changes. All we can do is to flag rate
+	   changes in the read/write routines.  
+	 */
+
+	switch (rate) {
+	case 32000:
+		if (current_rate > 48000) {
+			reject_if_open = 1;
+		}
+		rate_bits = HDSPM_Frequency32KHz;
+		break;
+	case 44100:
+		if (current_rate > 48000) {
+			reject_if_open = 1;
+		}
+		rate_bits = HDSPM_Frequency44_1KHz;
+		break;
+	case 48000:
+		if (current_rate > 48000) {
+			reject_if_open = 1;
+		}
+		rate_bits = HDSPM_Frequency48KHz;
+		break;
+	case 64000:
+		if (current_rate <= 48000) {
+			reject_if_open = 1;
+		}
+		rate_bits = HDSPM_Frequency64KHz;
+		break;
+	case 88200:
+		if (current_rate <= 48000) {
+			reject_if_open = 1;
+		}
+		rate_bits = HDSPM_Frequency88_2KHz;
+		break;
+	case 96000:
+		if (current_rate <= 48000) {
+			reject_if_open = 1;
+		}
+		rate_bits = HDSPM_Frequency96KHz;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	if (reject_if_open
+	    && (hdspm->capture_pid >= 0 || hdspm->playback_pid >= 0)) {
+		snd_printk
+		    (KERN_ERR "HDSPM: cannot change between single- and double-speed mode (capture PID = %d, playback PID = %d)\n",
+		     hdspm->capture_pid, hdspm->playback_pid);
+		return -EBUSY;
+	}
+
+	hdspm->control_register &= ~HDSPM_FrequencyMask;
+	hdspm->control_register |= rate_bits;
+	hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
+
+	if (rate > 64000)
+		hdspm->channel_map = channel_map_madi_qs;
+	else if (rate > 48000)
+		hdspm->channel_map = channel_map_madi_ds;
+	else 
+		hdspm->channel_map = channel_map_madi_ss;
+
+	hdspm->system_sample_rate = rate;
+
+	if (not_set != 0)
+		return -1;
+
+	return 0;
+}
+
+/* mainly for init to 0 on load */
+static void all_in_all_mixer(hdspm_t * hdspm, int sgain)
+{
+	int i, j;
+	unsigned int gain =
+	    (sgain > UNITY_GAIN) ? UNITY_GAIN : (sgain < 0) ? 0 : sgain;
+
+	for (i = 0; i < HDSPM_MIXER_CHANNELS; i++)
+		for (j = 0; j < HDSPM_MIXER_CHANNELS; j++) {
+			hdspm_write_in_gain(hdspm, i, j, gain);
+			hdspm_write_pb_gain(hdspm, i, j, gain);
+		}
+}
+
+/*----------------------------------------------------------------------------
+   MIDI
+  ----------------------------------------------------------------------------*/
+
+static inline unsigned char snd_hdspm_midi_read_byte (hdspm_t *hdspm, int id)
+{
+	/* the hardware already does the relevant bit-mask with 0xff */
+	if (id)
+		return hdspm_read(hdspm, HDSPM_midiDataIn1);
+	else
+		return hdspm_read(hdspm, HDSPM_midiDataIn0);
+}
+
+static inline void snd_hdspm_midi_write_byte (hdspm_t *hdspm, int id, int val)
+{
+	/* the hardware already does the relevant bit-mask with 0xff */
+	if (id)
+		return hdspm_write(hdspm, HDSPM_midiDataOut1, val);
+	else
+		return hdspm_write(hdspm, HDSPM_midiDataOut0, val);
+}
+
+static inline int snd_hdspm_midi_input_available (hdspm_t *hdspm, int id)
+{
+	if (id)
+		return (hdspm_read(hdspm, HDSPM_midiStatusIn1) & 0xff);
+	else
+		return (hdspm_read(hdspm, HDSPM_midiStatusIn0) & 0xff);
+}
+
+static inline int snd_hdspm_midi_output_possible (hdspm_t *hdspm, int id)
+{
+	int fifo_bytes_used;
+
+	if (id)
+		fifo_bytes_used = hdspm_read(hdspm, HDSPM_midiStatusOut1) & 0xff;
+	else
+		fifo_bytes_used = hdspm_read(hdspm, HDSPM_midiStatusOut0) & 0xff;
+
+	if (fifo_bytes_used < 128)
+		return  128 - fifo_bytes_used;
+	else
+		return 0;
+}
+
+static inline void snd_hdspm_flush_midi_input (hdspm_t *hdspm, int id)
+{
+	while (snd_hdspm_midi_input_available (hdspm, id))
+		snd_hdspm_midi_read_byte (hdspm, id);
+}
+
+static int snd_hdspm_midi_output_write (hdspm_midi_t *hmidi)
+{
+	unsigned long flags;
+	int n_pending;
+	int to_write;
+	int i;
+	unsigned char buf[128];
+
+	/* Output is not interrupt driven */
+		
+	spin_lock_irqsave (&hmidi->lock, flags);
+	if (hmidi->output) {
+		if (!snd_rawmidi_transmit_empty (hmidi->output)) {
+			if ((n_pending = snd_hdspm_midi_output_possible (hmidi->hdspm, hmidi->id)) > 0) {
+				if (n_pending > (int)sizeof (buf))
+					n_pending = sizeof (buf);
+				
+				if ((to_write = snd_rawmidi_transmit (hmidi->output, buf, n_pending)) > 0) {
+					for (i = 0; i < to_write; ++i) 
+						snd_hdspm_midi_write_byte (hmidi->hdspm, hmidi->id, buf[i]);
+				}
+			}
+		}
+	}
+	spin_unlock_irqrestore (&hmidi->lock, flags);
+	return 0;
+}
+
+static int snd_hdspm_midi_input_read (hdspm_midi_t *hmidi)
+{
+	unsigned char buf[128]; /* this buffer is designed to match the MIDI input FIFO size */
+	unsigned long flags;
+	int n_pending;
+	int i;
+
+	spin_lock_irqsave (&hmidi->lock, flags);
+	if ((n_pending = snd_hdspm_midi_input_available (hmidi->hdspm, hmidi->id)) > 0) {
+		if (hmidi->input) {
+			if (n_pending > (int)sizeof (buf)) {
+				n_pending = sizeof (buf);
+			}
+			for (i = 0; i < n_pending; ++i) {
+				buf[i] = snd_hdspm_midi_read_byte (hmidi->hdspm, hmidi->id);
+			}
+			if (n_pending) {
+				snd_rawmidi_receive (hmidi->input, buf, n_pending);
+			}
+		} else {
+			/* flush the MIDI input FIFO */
+			while (n_pending--) {
+				snd_hdspm_midi_read_byte (hmidi->hdspm, hmidi->id);
+			}
+		}
+	}
+	hmidi->pending = 0;
+	if (hmidi->id) {
+		hmidi->hdspm->control_register |= HDSPM_Midi1InterruptEnable;
+	} else {
+		hmidi->hdspm->control_register |= HDSPM_Midi0InterruptEnable;
+	}
+	hdspm_write(hmidi->hdspm, HDSPM_controlRegister, hmidi->hdspm->control_register);
+	spin_unlock_irqrestore (&hmidi->lock, flags);
+	return snd_hdspm_midi_output_write (hmidi);
+}
+
+static void snd_hdspm_midi_input_trigger(snd_rawmidi_substream_t * substream, int up)
+{
+	hdspm_t *hdspm;
+	hdspm_midi_t *hmidi;
+	unsigned long flags;
+	u32 ie;
+
+	hmidi = (hdspm_midi_t *) substream->rmidi->private_data;
+	hdspm = hmidi->hdspm;
+	ie = hmidi->id ? HDSPM_Midi1InterruptEnable : HDSPM_Midi0InterruptEnable;
+	spin_lock_irqsave (&hdspm->lock, flags);
+	if (up) {
+		if (!(hdspm->control_register & ie)) {
+			snd_hdspm_flush_midi_input (hdspm, hmidi->id);
+			hdspm->control_register |= ie;
+		}
+	} else {
+		hdspm->control_register &= ~ie;
+	}
+
+	hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
+	spin_unlock_irqrestore (&hdspm->lock, flags);
+}
+
+static void snd_hdspm_midi_output_timer(unsigned long data)
+{
+	hdspm_midi_t *hmidi = (hdspm_midi_t *) data;
+	unsigned long flags;
+	
+	snd_hdspm_midi_output_write(hmidi);
+	spin_lock_irqsave (&hmidi->lock, flags);
+
+	/* this does not bump hmidi->istimer, because the
+	   kernel automatically removed the timer when it
+	   expired, and we are now adding it back, thus
+	   leaving istimer wherever it was set before.  
+	*/
+
+	if (hmidi->istimer) {
+		hmidi->timer.expires = 1 + jiffies;
+		add_timer(&hmidi->timer);
+	}
+
+	spin_unlock_irqrestore (&hmidi->lock, flags);
+}
+
+static void snd_hdspm_midi_output_trigger(snd_rawmidi_substream_t * substream, int up)
+{
+	hdspm_midi_t *hmidi;
+	unsigned long flags;
+
+	hmidi = (hdspm_midi_t *) substream->rmidi->private_data;
+	spin_lock_irqsave (&hmidi->lock, flags);
+	if (up) {
+		if (!hmidi->istimer) {
+			init_timer(&hmidi->timer);
+			hmidi->timer.function = snd_hdspm_midi_output_timer;
+			hmidi->timer.data = (unsigned long) hmidi;
+			hmidi->timer.expires = 1 + jiffies;
+			add_timer(&hmidi->timer);
+			hmidi->istimer++;
+		}
+	} else {
+		if (hmidi->istimer && --hmidi->istimer <= 0) {
+			del_timer (&hmidi->timer);
+		}
+	}
+	spin_unlock_irqrestore (&hmidi->lock, flags);
+	if (up)
+		snd_hdspm_midi_output_write(hmidi);
+}
+
+static int snd_hdspm_midi_input_open(snd_rawmidi_substream_t * substream)
+{
+	hdspm_midi_t *hmidi;
+
+	hmidi = (hdspm_midi_t *) substream->rmidi->private_data;
+	spin_lock_irq (&hmidi->lock);
+	snd_hdspm_flush_midi_input (hmidi->hdspm, hmidi->id);
+	hmidi->input = substream;
+	spin_unlock_irq (&hmidi->lock);
+
+	return 0;
+}
+
+static int snd_hdspm_midi_output_open(snd_rawmidi_substream_t * substream)
+{
+	hdspm_midi_t *hmidi;
+
+	hmidi = (hdspm_midi_t *) substream->rmidi->private_data;
+	spin_lock_irq (&hmidi->lock);
+	hmidi->output = substream;
+	spin_unlock_irq (&hmidi->lock);
+
+	return 0;
+}
+
+static int snd_hdspm_midi_input_close(snd_rawmidi_substream_t * substream)
+{
+	hdspm_midi_t *hmidi;
+
+	snd_hdspm_midi_input_trigger (substream, 0);
+
+	hmidi = (hdspm_midi_t *) substream->rmidi->private_data;
+	spin_lock_irq (&hmidi->lock);
+	hmidi->input = NULL;
+	spin_unlock_irq (&hmidi->lock);
+
+	return 0;
+}
+
+static int snd_hdspm_midi_output_close(snd_rawmidi_substream_t * substream)
+{
+	hdspm_midi_t *hmidi;
+
+	snd_hdspm_midi_output_trigger (substream, 0);
+
+	hmidi = (hdspm_midi_t *) substream->rmidi->private_data;
+	spin_lock_irq (&hmidi->lock);
+	hmidi->output = NULL;
+	spin_unlock_irq (&hmidi->lock);
+
+	return 0;
+}
+
+snd_rawmidi_ops_t snd_hdspm_midi_output =
+{
+	.open =		snd_hdspm_midi_output_open,
+	.close =	snd_hdspm_midi_output_close,
+	.trigger =	snd_hdspm_midi_output_trigger,
+};
+
+snd_rawmidi_ops_t snd_hdspm_midi_input =
+{
+	.open =		snd_hdspm_midi_input_open,
+	.close =	snd_hdspm_midi_input_close,
+	.trigger =	snd_hdspm_midi_input_trigger,
+};
+
+static int __devinit snd_hdspm_create_midi (snd_card_t *card, hdspm_t *hdspm, int id)
+{
+	int err;
+	char buf[32];
+
+	hdspm->midi[id].id = id;
+	hdspm->midi[id].rmidi = NULL;
+	hdspm->midi[id].input = NULL;
+	hdspm->midi[id].output = NULL;
+	hdspm->midi[id].hdspm = hdspm;
+	hdspm->midi[id].istimer = 0;
+	hdspm->midi[id].pending = 0;
+	spin_lock_init (&hdspm->midi[id].lock);
+
+	sprintf (buf, "%s MIDI %d", card->shortname, id+1);
+	if ((err = snd_rawmidi_new (card, buf, id, 1, 1, &hdspm->midi[id].rmidi)) < 0)
+		return err;
+
+	sprintf (hdspm->midi[id].rmidi->name, "%s MIDI %d", card->id, id+1);
+	hdspm->midi[id].rmidi->private_data = &hdspm->midi[id];
+
+	snd_rawmidi_set_ops (hdspm->midi[id].rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_hdspm_midi_output);
+	snd_rawmidi_set_ops (hdspm->midi[id].rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_hdspm_midi_input);
+
+	hdspm->midi[id].rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT |
+		SNDRV_RAWMIDI_INFO_INPUT |
+		SNDRV_RAWMIDI_INFO_DUPLEX;
+
+	return 0;
+}
+
+
+static void hdspm_midi_tasklet(unsigned long arg)
+{
+	hdspm_t *hdspm = (hdspm_t *)arg;
+	
+	if (hdspm->midi[0].pending)
+		snd_hdspm_midi_input_read (&hdspm->midi[0]);
+	if (hdspm->midi[1].pending)
+		snd_hdspm_midi_input_read (&hdspm->midi[1]);
+} 
+
+
+/*-----------------------------------------------------------------------------
+  Status Interface
+  ----------------------------------------------------------------------------*/
+
+/* get the system sample rate which is set */
+
+#define HDSPM_SYSTEM_SAMPLE_RATE(xname, xindex) \
+{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \
+  .name = xname, \
+  .index = xindex, \
+  .access = SNDRV_CTL_ELEM_ACCESS_READ, \
+  .info = snd_hdspm_info_system_sample_rate, \
+  .get = snd_hdspm_get_system_sample_rate \
+}
+
+static int snd_hdspm_info_system_sample_rate(snd_kcontrol_t * kcontrol,
+					     snd_ctl_elem_info_t * uinfo)
+{
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+	uinfo->count = 1;
+	return 0;
+}
+
+static int snd_hdspm_get_system_sample_rate(snd_kcontrol_t * kcontrol,
+					    snd_ctl_elem_value_t *
+					    ucontrol)
+{
+	hdspm_t *hdspm = snd_kcontrol_chip(kcontrol);
+
+	ucontrol->value.enumerated.item[0] = hdspm->system_sample_rate;
+	return 0;
+}
+
+#define HDSPM_AUTOSYNC_SAMPLE_RATE(xname, xindex) \
+{ .iface = SNDRV_CTL_ELEM_IFACE_PCM, \
+  .name = xname, \
+  .index = xindex, \
+  .access = SNDRV_CTL_ELEM_ACCESS_READ, \
+  .info = snd_hdspm_info_autosync_sample_rate, \
+  .get = snd_hdspm_get_autosync_sample_rate \
+}
+
+static int snd_hdspm_info_autosync_sample_rate(snd_kcontrol_t * kcontrol,
+					       snd_ctl_elem_info_t * uinfo)
+{
+	static char *texts[] = { "32000", "44100", "48000",
+		"64000", "88200", "96000",
+		"128000", "176400", "192000",
+		"None"
+	};
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+	uinfo->count = 1;
+	uinfo->value.enumerated.items = 10;
+	if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
+		uinfo->value.enumerated.item =
+		    uinfo->value.enumerated.items - 1;
+	strcpy(uinfo->value.enumerated.name,
+	       texts[uinfo->value.enumerated.item]);
+	return 0;
+}
+
+static int snd_hdspm_get_autosync_sample_rate(snd_kcontrol_t * kcontrol,
+					      snd_ctl_elem_value_t *
+					      ucontrol)
+{
+	hdspm_t *hdspm = snd_kcontrol_chip(kcontrol);
+
+	switch (hdspm_external_sample_rate(hdspm)) {
+	case 32000:
+		ucontrol->value.enumerated.item[0] = 0;
+		break;
+	case 44100:
+		ucontrol->value.enumerated.item[0] = 1;
+		break;
+	case 48000:
+		ucontrol->value.enumerated.item[0] = 2;
+		break;
+	case 64000:
+		ucontrol->value.enumerated.item[0] = 3;
+		break;
+	case 88200:
+		ucontrol->value.enumerated.item[0] = 4;
+		break;
+	case 96000:
+		ucontrol->value.enumerated.item[0] = 5;
+		break;
+	case 128000:
+		ucontrol->value.enumerated.item[0] = 6;
+		break;
+	case 176400:
+		ucontrol->value.enumerated.item[0] = 7;
+		break;
+	case 192000:
+		ucontrol->value.enumerated.item[0] = 8;
+		break;
+
+	default:
+		ucontrol->value.enumerated.item[0] = 9;
+	}
+	return 0;
+}
+
+#define HDSPM_SYSTEM_CLOCK_MODE(xname, xindex) \
+{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \
+  .name = xname, \
+  .index = xindex, \
+  .access = SNDRV_CTL_ELEM_ACCESS_READ, \
+  .info = snd_hdspm_info_system_clock_mode, \
+  .get = snd_hdspm_get_system_clock_mode, \
+}
+
+
+
+static int hdspm_system_clock_mode(hdspm_t * hdspm)
+{
+        /* Always reflect the hardware info, rme is never wrong !!!! */
+
+	if (hdspm->control_register & HDSPM_ClockModeMaster)
+		return 0;
+	return 1;
+}
+
+static int snd_hdspm_info_system_clock_mode(snd_kcontrol_t * kcontrol,
+					    snd_ctl_elem_info_t * uinfo)
+{
+	static char *texts[] = { "Master", "Slave" };
+
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+	uinfo->count = 1;
+	uinfo->value.enumerated.items = 2;
+	if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
+		uinfo->value.enumerated.item =
+		    uinfo->value.enumerated.items - 1;
+	strcpy(uinfo->value.enumerated.name,
+	       texts[uinfo->value.enumerated.item]);
+	return 0;
+}
+
+static int snd_hdspm_get_system_clock_mode(snd_kcontrol_t * kcontrol,
+					   snd_ctl_elem_value_t * ucontrol)
+{
+	hdspm_t *hdspm = snd_kcontrol_chip(kcontrol);
+
+	ucontrol->value.enumerated.item[0] =
+	    hdspm_system_clock_mode(hdspm);
+	return 0;
+}
+
+#define HDSPM_CLOCK_SOURCE(xname, xindex) \
+{ .iface = SNDRV_CTL_ELEM_IFACE_PCM, \
+  .name = xname, \
+  .index = xindex, \
+  .info = snd_hdspm_info_clock_source, \
+  .get = snd_hdspm_get_clock_source, \
+  .put = snd_hdspm_put_clock_source \
+}
+
+static int hdspm_clock_source(hdspm_t * hdspm)
+{
+	if (hdspm->control_register & HDSPM_ClockModeMaster) {
+		switch (hdspm->system_sample_rate) {
+		case 32000:
+			return 1;
+		case 44100:
+			return 2;
+		case 48000:
+			return 3;
+		case 64000:
+			return 4;
+		case 88200:
+			return 5;
+		case 96000:
+			return 6;
+		case 128000:
+			return 7;
+		case 176400:
+			return 8;
+		case 192000:
+			return 9;
+		default:
+			return 3;
+		}
+	} else {
+		return 0;
+	}
+}
+
+static int hdspm_set_clock_source(hdspm_t * hdspm, int mode)
+{
+	int rate;
+	switch (mode) {
+
+	case HDSPM_CLOCK_SOURCE_AUTOSYNC:
+		if (hdspm_external_sample_rate(hdspm) != 0) {
+			hdspm->control_register &= ~HDSPM_ClockModeMaster;
+			hdspm_write(hdspm, HDSPM_controlRegister,
+				    hdspm->control_register);
+			return 0;
+		}
+		return -1;
+	case HDSPM_CLOCK_SOURCE_INTERNAL_32KHZ:
+		rate = 32000;
+		break;
+	case HDSPM_CLOCK_SOURCE_INTERNAL_44_1KHZ:
+		rate = 44100;
+		break;
+	case HDSPM_CLOCK_SOURCE_INTERNAL_48KHZ:
+		rate = 48000;
+		break;
+	case HDSPM_CLOCK_SOURCE_INTERNAL_64KHZ:
+		rate = 64000;
+		break;
+	case HDSPM_CLOCK_SOURCE_INTERNAL_88_2KHZ:
+		rate = 88200;
+		break;
+	case HDSPM_CLOCK_SOURCE_INTERNAL_96KHZ:
+		rate = 96000;
+		break;
+	case HDSPM_CLOCK_SOURCE_INTERNAL_128KHZ:
+		rate = 128000;
+		break;
+	case HDSPM_CLOCK_SOURCE_INTERNAL_176_4KHZ:
+		rate = 176400;
+		break;
+	case HDSPM_CLOCK_SOURCE_INTERNAL_192KHZ:
+		rate = 192000;
+		break;
+
+	default:
+		rate = 44100;
+	}
+	hdspm->control_register |= HDSPM_ClockModeMaster;
+	hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
+	hdspm_set_rate(hdspm, rate, 1);
+	return 0;
+}
+
+static int snd_hdspm_info_clock_source(snd_kcontrol_t * kcontrol,
+				       snd_ctl_elem_info_t * uinfo)
+{
+	static char *texts[] = { "AutoSync",
+		"Internal 32.0 kHz", "Internal 44.1 kHz",
+		    "Internal 48.0 kHz",
+		"Internal 64.0 kHz", "Internal 88.2 kHz",
+		    "Internal 96.0 kHz",
+		"Internal 128.0 kHz", "Internal 176.4 kHz",
+		    "Internal 192.0 kHz"
+	};
+
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+	uinfo->count = 1;
+	uinfo->value.enumerated.items = 10;
+
+	if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
+		uinfo->value.enumerated.item =
+		    uinfo->value.enumerated.items - 1;
+
+	strcpy(uinfo->value.enumerated.name,
+	       texts[uinfo->value.enumerated.item]);
+
+	return 0;
+}
+
+static int snd_hdspm_get_clock_source(snd_kcontrol_t * kcontrol,
+				      snd_ctl_elem_value_t * ucontrol)
+{
+	hdspm_t *hdspm = snd_kcontrol_chip(kcontrol);
+
+	ucontrol->value.enumerated.item[0] = hdspm_clock_source(hdspm);
+	return 0;
+}
+
+static int snd_hdspm_put_clock_source(snd_kcontrol_t * kcontrol,
+				      snd_ctl_elem_value_t * ucontrol)
+{
+	hdspm_t *hdspm = snd_kcontrol_chip(kcontrol);
+	int change;
+	int val;
+
+	if (!snd_hdspm_use_is_exclusive(hdspm))
+		return -EBUSY;
+	val = ucontrol->value.enumerated.item[0];
+	if (val < 0)
+		val = 0;
+	if (val > 6)
+		val = 6;
+	spin_lock_irq(&hdspm->lock);
+	if (val != hdspm_clock_source(hdspm))
+		change = (hdspm_set_clock_source(hdspm, val) == 0) ? 1 : 0;
+	else
+		change = 0;
+	spin_unlock_irq(&hdspm->lock);
+	return change;
+}
+
+#define HDSPM_PREF_SYNC_REF(xname, xindex) \
+{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \
+  .name = xname, \
+  .index = xindex, \
+  .info = snd_hdspm_info_pref_sync_ref, \
+  .get = snd_hdspm_get_pref_sync_ref, \
+  .put = snd_hdspm_put_pref_sync_ref \
+}
+
+static int hdspm_pref_sync_ref(hdspm_t * hdspm)
+{
+	/* Notice that this looks at the requested sync source,
+	   not the one actually in use.
+	 */
+	switch (hdspm->control_register & HDSPM_SyncRefMask) {
+	case HDSPM_SyncRef_Word:
+		return HDSPM_SYNC_FROM_WORD;
+	case HDSPM_SyncRef_MADI:
+		return HDSPM_SYNC_FROM_MADI;
+	}
+
+	return HDSPM_SYNC_FROM_WORD;
+}
+
+static int hdspm_set_pref_sync_ref(hdspm_t * hdspm, int pref)
+{
+	hdspm->control_register &= ~HDSPM_SyncRefMask;
+
+	switch (pref) {
+	case HDSPM_SYNC_FROM_MADI:
+		hdspm->control_register |= HDSPM_SyncRef_MADI;
+		break;
+	case HDSPM_SYNC_FROM_WORD:
+		hdspm->control_register |= HDSPM_SyncRef_Word;
+		break;
+	default:
+		return -1;
+	}
+	hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
+	return 0;
+}
+
+static int snd_hdspm_info_pref_sync_ref(snd_kcontrol_t * kcontrol,
+					snd_ctl_elem_info_t * uinfo)
+{
+	static char *texts[] = { "Word", "MADI" };
+
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+	uinfo->count = 1;
+
+	uinfo->value.enumerated.items = 2;
+
+	if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
+		uinfo->value.enumerated.item =
+		    uinfo->value.enumerated.items - 1;
+	strcpy(uinfo->value.enumerated.name,
+	       texts[uinfo->value.enumerated.item]);
+	return 0;
+}
+
+static int snd_hdspm_get_pref_sync_ref(snd_kcontrol_t * kcontrol,
+				       snd_ctl_elem_value_t * ucontrol)
+{
+	hdspm_t *hdspm = snd_kcontrol_chip(kcontrol);
+
+	ucontrol->value.enumerated.item[0] = hdspm_pref_sync_ref(hdspm);
+	return 0;
+}
+
+static int snd_hdspm_put_pref_sync_ref(snd_kcontrol_t * kcontrol,
+				       snd_ctl_elem_value_t * ucontrol)
+{
+	hdspm_t *hdspm = snd_kcontrol_chip(kcontrol);
+	int change, max;
+	unsigned int val;
+
+	max = 2;
+
+	if (!snd_hdspm_use_is_exclusive(hdspm))
+		return -EBUSY;
+
+	val = ucontrol->value.enumerated.item[0] % max;
+
+	spin_lock_irq(&hdspm->lock);
+	change = (int) val != hdspm_pref_sync_ref(hdspm);
+	hdspm_set_pref_sync_ref(hdspm, val);
+	spin_unlock_irq(&hdspm->lock);
+	return change;
+}
+
+#define HDSPM_AUTOSYNC_REF(xname, xindex) \
+{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \
+  .name = xname, \
+  .index = xindex, \
+  .access = SNDRV_CTL_ELEM_ACCESS_READ, \
+  .info = snd_hdspm_info_autosync_ref, \
+  .get = snd_hdspm_get_autosync_ref, \
+}
+
+static int hdspm_autosync_ref(hdspm_t * hdspm)
+{
+	/* This looks at the autosync selected sync reference */
+	unsigned int status2 = hdspm_read(hdspm, HDSPM_statusRegister2);
+
+	switch (status2 & HDSPM_SelSyncRefMask) {
+
+	case HDSPM_SelSyncRef_WORD:
+		return HDSPM_AUTOSYNC_FROM_WORD;
+
+	case HDSPM_SelSyncRef_MADI:
+		return HDSPM_AUTOSYNC_FROM_MADI;
+
+	case HDSPM_SelSyncRef_NVALID:
+		return HDSPM_AUTOSYNC_FROM_NONE;
+
+	default:
+		return 0;
+	}
+
+	return 0;
+}
+
+static int snd_hdspm_info_autosync_ref(snd_kcontrol_t * kcontrol,
+				       snd_ctl_elem_info_t * uinfo)
+{
+	static char *texts[] = { "WordClock", "MADI", "None" };
+
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+	uinfo->count = 1;
+	uinfo->value.enumerated.items = 3;
+	if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
+		uinfo->value.enumerated.item =
+		    uinfo->value.enumerated.items - 1;
+	strcpy(uinfo->value.enumerated.name,
+	       texts[uinfo->value.enumerated.item]);
+	return 0;
+}
+
+static int snd_hdspm_get_autosync_ref(snd_kcontrol_t * kcontrol,
+				      snd_ctl_elem_value_t * ucontrol)
+{
+	hdspm_t *hdspm = snd_kcontrol_chip(kcontrol);
+
+	ucontrol->value.enumerated.item[0] = hdspm_pref_sync_ref(hdspm);
+	return 0;
+}
+
+#define HDSPM_LINE_OUT(xname, xindex) \
+{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \
+  .name = xname, \
+  .index = xindex, \
+  .info = snd_hdspm_info_line_out, \
+  .get = snd_hdspm_get_line_out, \
+  .put = snd_hdspm_put_line_out \
+}
+
+static int hdspm_line_out(hdspm_t * hdspm)
+{
+	return (hdspm->control_register & HDSPM_LineOut) ? 1 : 0;
+}
+
+
+static int hdspm_set_line_output(hdspm_t * hdspm, int out)
+{
+	if (out)
+		hdspm->control_register |= HDSPM_LineOut;
+	else
+		hdspm->control_register &= ~HDSPM_LineOut;
+	hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
+
+	return 0;
+}
+
+static int snd_hdspm_info_line_out(snd_kcontrol_t * kcontrol,
+				   snd_ctl_elem_info_t * uinfo)
+{
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
+	uinfo->count = 1;
+	uinfo->value.integer.min = 0;
+	uinfo->value.integer.max = 1;
+	return 0;
+}
+
+static int snd_hdspm_get_line_out(snd_kcontrol_t * kcontrol,
+				  snd_ctl_elem_value_t * ucontrol)
+{
+	hdspm_t *hdspm = snd_kcontrol_chip(kcontrol);
+
+	spin_lock_irq(&hdspm->lock);
+	ucontrol->value.integer.value[0] = hdspm_line_out(hdspm);
+	spin_unlock_irq(&hdspm->lock);
+	return 0;
+}
+
+static int snd_hdspm_put_line_out(snd_kcontrol_t * kcontrol,
+				  snd_ctl_elem_value_t * ucontrol)
+{
+	hdspm_t *hdspm = snd_kcontrol_chip(kcontrol);
+	int change;
+	unsigned int val;
+
+	if (!snd_hdspm_use_is_exclusive(hdspm))
+		return -EBUSY;
+	val = ucontrol->value.integer.value[0] & 1;
+	spin_lock_irq(&hdspm->lock);
+	change = (int) val != hdspm_line_out(hdspm);
+	hdspm_set_line_output(hdspm, val);
+	spin_unlock_irq(&hdspm->lock);
+	return change;
+}
+
+#define HDSPM_TX_64(xname, xindex) \
+{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \
+  .name = xname, \
+  .index = xindex, \
+  .info = snd_hdspm_info_tx_64, \
+  .get = snd_hdspm_get_tx_64, \
+  .put = snd_hdspm_put_tx_64 \
+}
+
+static int hdspm_tx_64(hdspm_t * hdspm)
+{
+	return (hdspm->control_register & HDSPM_TX_64ch) ? 1 : 0;
+}
+
+static int hdspm_set_tx_64(hdspm_t * hdspm, int out)
+{
+	if (out)
+		hdspm->control_register |= HDSPM_TX_64ch;
+	else
+		hdspm->control_register &= ~HDSPM_TX_64ch;
+	hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
+
+	return 0;
+}
+
+static int snd_hdspm_info_tx_64(snd_kcontrol_t * kcontrol,
+				snd_ctl_elem_info_t * uinfo)
+{
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
+	uinfo->count = 1;
+	uinfo->value.integer.min = 0;
+	uinfo->value.integer.max = 1;
+	return 0;
+}
+
+static int snd_hdspm_get_tx_64(snd_kcontrol_t * kcontrol,
+			       snd_ctl_elem_value_t * ucontrol)
+{
+	hdspm_t *hdspm = snd_kcontrol_chip(kcontrol);
+
+	spin_lock_irq(&hdspm->lock);
+	ucontrol->value.integer.value[0] = hdspm_tx_64(hdspm);
+	spin_unlock_irq(&hdspm->lock);
+	return 0;
+}
+
+static int snd_hdspm_put_tx_64(snd_kcontrol_t * kcontrol,
+			       snd_ctl_elem_value_t * ucontrol)
+{
+	hdspm_t *hdspm = snd_kcontrol_chip(kcontrol);
+	int change;
+	unsigned int val;
+
+	if (!snd_hdspm_use_is_exclusive(hdspm))
+		return -EBUSY;
+	val = ucontrol->value.integer.value[0] & 1;
+	spin_lock_irq(&hdspm->lock);
+	change = (int) val != hdspm_tx_64(hdspm);
+	hdspm_set_tx_64(hdspm, val);
+	spin_unlock_irq(&hdspm->lock);
+	return change;
+}
+
+#define HDSPM_C_TMS(xname, xindex) \
+{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \
+  .name = xname, \
+  .index = xindex, \
+  .info = snd_hdspm_info_c_tms, \
+  .get = snd_hdspm_get_c_tms, \
+  .put = snd_hdspm_put_c_tms \
+}
+
+static int hdspm_c_tms(hdspm_t * hdspm)
+{
+	return (hdspm->control_register & HDSPM_clr_tms) ? 1 : 0;
+}
+
+static int hdspm_set_c_tms(hdspm_t * hdspm, int out)
+{
+	if (out)
+		hdspm->control_register |= HDSPM_clr_tms;
+	else
+		hdspm->control_register &= ~HDSPM_clr_tms;
+	hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
+
+	return 0;
+}
+
+static int snd_hdspm_info_c_tms(snd_kcontrol_t * kcontrol,
+				snd_ctl_elem_info_t * uinfo)
+{
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
+	uinfo->count = 1;
+	uinfo->value.integer.min = 0;
+	uinfo->value.integer.max = 1;
+	return 0;
+}
+
+static int snd_hdspm_get_c_tms(snd_kcontrol_t * kcontrol,
+			       snd_ctl_elem_value_t * ucontrol)
+{
+	hdspm_t *hdspm = snd_kcontrol_chip(kcontrol);
+
+	spin_lock_irq(&hdspm->lock);
+	ucontrol->value.integer.value[0] = hdspm_c_tms(hdspm);
+	spin_unlock_irq(&hdspm->lock);
+	return 0;
+}
+
+static int snd_hdspm_put_c_tms(snd_kcontrol_t * kcontrol,
+			       snd_ctl_elem_value_t * ucontrol)
+{
+	hdspm_t *hdspm = snd_kcontrol_chip(kcontrol);
+	int change;
+	unsigned int val;
+
+	if (!snd_hdspm_use_is_exclusive(hdspm))
+		return -EBUSY;
+	val = ucontrol->value.integer.value[0] & 1;
+	spin_lock_irq(&hdspm->lock);
+	change = (int) val != hdspm_c_tms(hdspm);
+	hdspm_set_c_tms(hdspm, val);
+	spin_unlock_irq(&hdspm->lock);
+	return change;
+}
+
+#define HDSPM_SAFE_MODE(xname, xindex) \
+{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \
+  .name = xname, \
+  .index = xindex, \
+  .info = snd_hdspm_info_safe_mode, \
+  .get = snd_hdspm_get_safe_mode, \
+  .put = snd_hdspm_put_safe_mode \
+}
+
+static int hdspm_safe_mode(hdspm_t * hdspm)
+{
+	return (hdspm->control_register & HDSPM_AutoInp) ? 1 : 0;
+}
+
+static int hdspm_set_safe_mode(hdspm_t * hdspm, int out)
+{
+	if (out)
+		hdspm->control_register |= HDSPM_AutoInp;
+	else
+		hdspm->control_register &= ~HDSPM_AutoInp;
+	hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
+
+	return 0;
+}
+
+static int snd_hdspm_info_safe_mode(snd_kcontrol_t * kcontrol,
+				    snd_ctl_elem_info_t * uinfo)
+{
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
+	uinfo->count = 1;
+	uinfo->value.integer.min = 0;
+	uinfo->value.integer.max = 1;
+	return 0;
+}
+
+static int snd_hdspm_get_safe_mode(snd_kcontrol_t * kcontrol,
+				   snd_ctl_elem_value_t * ucontrol)
+{
+	hdspm_t *hdspm = snd_kcontrol_chip(kcontrol);
+
+	spin_lock_irq(&hdspm->lock);
+	ucontrol->value.integer.value[0] = hdspm_safe_mode(hdspm);
+	spin_unlock_irq(&hdspm->lock);
+	return 0;
+}
+
+static int snd_hdspm_put_safe_mode(snd_kcontrol_t * kcontrol,
+				   snd_ctl_elem_value_t * ucontrol)
+{
+	hdspm_t *hdspm = snd_kcontrol_chip(kcontrol);
+	int change;
+	unsigned int val;
+
+	if (!snd_hdspm_use_is_exclusive(hdspm))
+		return -EBUSY;
+	val = ucontrol->value.integer.value[0] & 1;
+	spin_lock_irq(&hdspm->lock);
+	change = (int) val != hdspm_safe_mode(hdspm);
+	hdspm_set_safe_mode(hdspm, val);
+	spin_unlock_irq(&hdspm->lock);
+	return change;
+}
+
+#define HDSPM_INPUT_SELECT(xname, xindex) \
+{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \
+  .name = xname, \
+  .index = xindex, \
+  .info = snd_hdspm_info_input_select, \
+  .get = snd_hdspm_get_input_select, \
+  .put = snd_hdspm_put_input_select \
+}
+
+static int hdspm_input_select(hdspm_t * hdspm)
+{
+	return (hdspm->control_register & HDSPM_InputSelect0) ? 1 : 0;
+}
+
+static int hdspm_set_input_select(hdspm_t * hdspm, int out)
+{
+	if (out)
+		hdspm->control_register |= HDSPM_InputSelect0;
+	else
+		hdspm->control_register &= ~HDSPM_InputSelect0;
+	hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
+
+	return 0;
+}
+
+static int snd_hdspm_info_input_select(snd_kcontrol_t * kcontrol,
+				       snd_ctl_elem_info_t * uinfo)
+{
+	static char *texts[] = { "optical", "coaxial" };
+
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+	uinfo->count = 1;
+	uinfo->value.enumerated.items = 2;
+
+	if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
+		uinfo->value.enumerated.item =
+		    uinfo->value.enumerated.items - 1;
+	strcpy(uinfo->value.enumerated.name,
+	       texts[uinfo->value.enumerated.item]);
+
+	return 0;
+}
+
+static int snd_hdspm_get_input_select(snd_kcontrol_t * kcontrol,
+				      snd_ctl_elem_value_t * ucontrol)
+{
+	hdspm_t *hdspm = snd_kcontrol_chip(kcontrol);
+
+	spin_lock_irq(&hdspm->lock);
+	ucontrol->value.enumerated.item[0] = hdspm_input_select(hdspm);
+	spin_unlock_irq(&hdspm->lock);
+	return 0;
+}
+
+static int snd_hdspm_put_input_select(snd_kcontrol_t * kcontrol,
+				      snd_ctl_elem_value_t * ucontrol)
+{
+	hdspm_t *hdspm = snd_kcontrol_chip(kcontrol);
+	int change;
+	unsigned int val;
+
+	if (!snd_hdspm_use_is_exclusive(hdspm))
+		return -EBUSY;
+	val = ucontrol->value.integer.value[0] & 1;
+	spin_lock_irq(&hdspm->lock);
+	change = (int) val != hdspm_input_select(hdspm);
+	hdspm_set_input_select(hdspm, val);
+	spin_unlock_irq(&hdspm->lock);
+	return change;
+}
+
+/*           Simple Mixer
+  deprecated since to much faders ???
+  MIXER interface says output (source, destination, value)
+   where source > MAX_channels are playback channels 
+   on MADICARD 
+  - playback mixer matrix: [channelout+64] [output] [value]
+  - input(thru) mixer matrix: [channelin] [output] [value]
+  (better do 2 kontrols for seperation ?)
+*/
+
+#define HDSPM_MIXER(xname, xindex) \
+{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \
+  .name = xname, \
+  .index = xindex, \
+  .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \
+		 SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
+  .info = snd_hdspm_info_mixer, \
+  .get = snd_hdspm_get_mixer, \
+  .put = snd_hdspm_put_mixer \
+}
+
+static int snd_hdspm_info_mixer(snd_kcontrol_t * kcontrol,
+				snd_ctl_elem_info_t * uinfo)
+{
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+	uinfo->count = 3;
+	uinfo->value.integer.min = 0;
+	uinfo->value.integer.max = 65535;
+	uinfo->value.integer.step = 1;
+	return 0;
+}
+
+static int snd_hdspm_get_mixer(snd_kcontrol_t * kcontrol,
+			       snd_ctl_elem_value_t * ucontrol)
+{
+	hdspm_t *hdspm = snd_kcontrol_chip(kcontrol);
+	int source;
+	int destination;
+
+	source = ucontrol->value.integer.value[0];
+	if (source < 0)
+		source = 0;
+	else if (source >= 2 * HDSPM_MAX_CHANNELS)
+		source = 2 * HDSPM_MAX_CHANNELS - 1;
+
+	destination = ucontrol->value.integer.value[1];
+	if (destination < 0)
+		destination = 0;
+	else if (destination >= HDSPM_MAX_CHANNELS)
+		destination = HDSPM_MAX_CHANNELS - 1;
+
+	spin_lock_irq(&hdspm->lock);
+	if (source >= HDSPM_MAX_CHANNELS)
+		ucontrol->value.integer.value[2] =
+		    hdspm_read_pb_gain(hdspm, destination,
+				       source - HDSPM_MAX_CHANNELS);
+	else
+		ucontrol->value.integer.value[2] =
+		    hdspm_read_in_gain(hdspm, destination, source);
+
+	spin_unlock_irq(&hdspm->lock);
+
+	return 0;
+}
+
+static int snd_hdspm_put_mixer(snd_kcontrol_t * kcontrol,
+			       snd_ctl_elem_value_t * ucontrol)
+{
+	hdspm_t *hdspm = snd_kcontrol_chip(kcontrol);
+	int change;
+	int source;
+	int destination;
+	int gain;
+
+	if (!snd_hdspm_use_is_exclusive(hdspm))
+		return -EBUSY;
+
+	source = ucontrol->value.integer.value[0];
+	destination = ucontrol->value.integer.value[1];
+
+	if (source < 0 || source >= 2 * HDSPM_MAX_CHANNELS)
+		return -1;
+	if (destination < 0 || destination >= HDSPM_MAX_CHANNELS)
+		return -1;
+
+	gain = ucontrol->value.integer.value[2];
+
+	spin_lock_irq(&hdspm->lock);
+
+	if (source >= HDSPM_MAX_CHANNELS)
+		change = gain != hdspm_read_pb_gain(hdspm, destination,
+						    source -
+						    HDSPM_MAX_CHANNELS);
+	else
+		change =
+		    gain != hdspm_read_in_gain(hdspm, destination, source);
+
+	if (change) {
+		if (source >= HDSPM_MAX_CHANNELS)
+			hdspm_write_pb_gain(hdspm, destination,
+					    source - HDSPM_MAX_CHANNELS,
+					    gain);
+		else
+			hdspm_write_in_gain(hdspm, destination, source,
+					    gain);
+	}
+	spin_unlock_irq(&hdspm->lock);
+
+	return change;
+}
+
+/* The simple mixer control(s) provide gain control for the
+   basic 1:1 mappings of playback streams to output
+   streams. 
+*/
+
+#define HDSPM_PLAYBACK_MIXER \
+{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
+  .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_WRITE | \
+		 SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
+  .info = snd_hdspm_info_playback_mixer, \
+  .get = snd_hdspm_get_playback_mixer, \
+  .put = snd_hdspm_put_playback_mixer \
+}
+
+static int snd_hdspm_info_playback_mixer(snd_kcontrol_t * kcontrol,
+					 snd_ctl_elem_info_t * uinfo)
+{
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+	uinfo->count = 1;
+	uinfo->value.integer.min = 0;
+	uinfo->value.integer.max = 65536;
+	uinfo->value.integer.step = 1;
+	return 0;
+}
+
+static int snd_hdspm_get_playback_mixer(snd_kcontrol_t * kcontrol,
+					snd_ctl_elem_value_t * ucontrol)
+{
+	hdspm_t *hdspm = snd_kcontrol_chip(kcontrol);
+	int channel;
+	int mapped_channel;
+
+	channel = ucontrol->id.index - 1;
+
+	snd_assert(channel >= 0
+		   || channel < HDSPM_MAX_CHANNELS, return -EINVAL);
+
+	if ((mapped_channel = hdspm->channel_map[channel]) < 0)
+		return -EINVAL;
+
+	spin_lock_irq(&hdspm->lock);
+	ucontrol->value.integer.value[0] =
+	    hdspm_read_pb_gain(hdspm, mapped_channel, mapped_channel);
+	spin_unlock_irq(&hdspm->lock);
+
+	/*    snd_printdd("get pb mixer index %d, channel %d, mapped_channel %d, value %d\n",
+	   ucontrol->id.index,        channel, mapped_channel,  ucontrol->value.integer.value[0]); 
+	 */
+
+	return 0;
+}
+
+static int snd_hdspm_put_playback_mixer(snd_kcontrol_t * kcontrol,
+					snd_ctl_elem_value_t * ucontrol)
+{
+	hdspm_t *hdspm = snd_kcontrol_chip(kcontrol);
+	int change;
+	int channel;
+	int mapped_channel;
+	int gain;
+
+	if (!snd_hdspm_use_is_exclusive(hdspm))
+		return -EBUSY;
+
+	channel = ucontrol->id.index - 1;
+
+	snd_assert(channel >= 0
+		   || channel < HDSPM_MAX_CHANNELS, return -EINVAL);
+
+	if ((mapped_channel = hdspm->channel_map[channel]) < 0)
+		return -EINVAL;
+
+	gain = ucontrol->value.integer.value[0];
+
+	spin_lock_irq(&hdspm->lock);
+	change =
+	    gain != hdspm_read_pb_gain(hdspm, mapped_channel,
+				       mapped_channel);
+	if (change)
+		hdspm_write_pb_gain(hdspm, mapped_channel, mapped_channel,
+				    gain);
+	spin_unlock_irq(&hdspm->lock);
+	return change;
+}
+
+#define HDSPM_WC_SYNC_CHECK(xname, xindex) \
+{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \
+  .name = xname, \
+  .index = xindex, \
+  .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
+  .info = snd_hdspm_info_sync_check, \
+  .get = snd_hdspm_get_wc_sync_check \
+}
+
+static int snd_hdspm_info_sync_check(snd_kcontrol_t * kcontrol,
+				     snd_ctl_elem_info_t * uinfo)
+{
+	static char *texts[] = { "No Lock", "Lock", "Sync" };
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+	uinfo->count = 1;
+	uinfo->value.enumerated.items = 3;
+	if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
+		uinfo->value.enumerated.item =
+		    uinfo->value.enumerated.items - 1;
+	strcpy(uinfo->value.enumerated.name,
+	       texts[uinfo->value.enumerated.item]);
+	return 0;
+}
+
+static int hdspm_wc_sync_check(hdspm_t * hdspm)
+{
+	int status2 = hdspm_read(hdspm, HDSPM_statusRegister2);
+	if (status2 & HDSPM_wcLock) {
+		if (status2 & HDSPM_wcSync)
+			return 2;
+		else
+			return 1;
+	}
+	return 0;
+}
+
+static int snd_hdspm_get_wc_sync_check(snd_kcontrol_t * kcontrol,
+				       snd_ctl_elem_value_t * ucontrol)
+{
+	hdspm_t *hdspm = snd_kcontrol_chip(kcontrol);
+
+	ucontrol->value.enumerated.item[0] = hdspm_wc_sync_check(hdspm);
+	return 0;
+}
+
+
+#define HDSPM_MADI_SYNC_CHECK(xname, xindex) \
+{ .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \
+  .name = xname, \
+  .index = xindex, \
+  .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
+  .info = snd_hdspm_info_sync_check, \
+  .get = snd_hdspm_get_madisync_sync_check \
+}
+
+static int hdspm_madisync_sync_check(hdspm_t * hdspm)
+{
+	int status = hdspm_read(hdspm, HDSPM_statusRegister);
+	if (status & HDSPM_madiLock) {
+		if (status & HDSPM_madiSync)
+			return 2;
+		else
+			return 1;
+	}
+	return 0;
+}
+
+static int snd_hdspm_get_madisync_sync_check(snd_kcontrol_t * kcontrol,
+					     snd_ctl_elem_value_t *
+					     ucontrol)
+{
+	hdspm_t *hdspm = snd_kcontrol_chip(kcontrol);
+
+	ucontrol->value.enumerated.item[0] =
+	    hdspm_madisync_sync_check(hdspm);
+	return 0;
+}
+
+
+
+
+static snd_kcontrol_new_t snd_hdspm_controls[] = {
+
+	HDSPM_MIXER("Mixer", 0),
+/* 'Sample Clock Source' complies with the alsa control naming scheme */
+	HDSPM_CLOCK_SOURCE("Sample Clock Source", 0),
+
+	HDSPM_SYSTEM_CLOCK_MODE("System Clock Mode", 0),
+	HDSPM_PREF_SYNC_REF("Preferred Sync Reference", 0),
+	HDSPM_AUTOSYNC_REF("AutoSync Reference", 0),
+	HDSPM_SYSTEM_SAMPLE_RATE("System Sample Rate", 0),
+/* 'External Rate' complies with the alsa control naming scheme */
+	HDSPM_AUTOSYNC_SAMPLE_RATE("External Rate", 0),
+	HDSPM_WC_SYNC_CHECK("Word Clock Lock Status", 0),
+	HDSPM_MADI_SYNC_CHECK("MADI Sync Lock Status", 0),
+	HDSPM_LINE_OUT("Line Out", 0),
+	HDSPM_TX_64("TX 64 channels mode", 0),
+	HDSPM_C_TMS("Clear Track Marker", 0),
+	HDSPM_SAFE_MODE("Safe Mode", 0),
+	HDSPM_INPUT_SELECT("Input Select", 0),
+};
+
+static snd_kcontrol_new_t snd_hdspm_playback_mixer = HDSPM_PLAYBACK_MIXER;
+
+
+static int hdspm_update_simple_mixer_controls(hdspm_t * hdspm)
+{
+	int i;
+
+	for (i = hdspm->ds_channels; i < hdspm->ss_channels; ++i) {
+		if (hdspm->system_sample_rate > 48000) {
+			hdspm->playback_mixer_ctls[i]->vd[0].access =
+			    SNDRV_CTL_ELEM_ACCESS_INACTIVE |
+			    SNDRV_CTL_ELEM_ACCESS_READ |
+			    SNDRV_CTL_ELEM_ACCESS_VOLATILE;
+		} else {
+			hdspm->playback_mixer_ctls[i]->vd[0].access =
+			    SNDRV_CTL_ELEM_ACCESS_READWRITE |
+			    SNDRV_CTL_ELEM_ACCESS_VOLATILE;
+		}
+		snd_ctl_notify(hdspm->card, SNDRV_CTL_EVENT_MASK_VALUE |
+			       SNDRV_CTL_EVENT_MASK_INFO,
+			       &hdspm->playback_mixer_ctls[i]->id);
+	}
+
+	return 0;
+}
+
+
+static int snd_hdspm_create_controls(snd_card_t * card, hdspm_t * hdspm)
+{
+	unsigned int idx, limit;
+	int err;
+	snd_kcontrol_t *kctl;
+
+	/* add control list first */
+
+	for (idx = 0; idx < ARRAY_SIZE(snd_hdspm_controls); idx++) {
+		if ((err =
+		     snd_ctl_add(card, kctl =
+				 snd_ctl_new1(&snd_hdspm_controls[idx],
+					      hdspm))) < 0) {
+			return err;
+		}
+	}
+
+	/* Channel playback mixer as default control 
+	   Note: the whole matrix would be 128*HDSPM_MIXER_CHANNELS Faders, thats to big for any alsamixer 
+	   they are accesible via special IOCTL on hwdep
+	   and the mixer 2dimensional mixer control */
+
+	snd_hdspm_playback_mixer.name = "Chn";
+	limit = HDSPM_MAX_CHANNELS;
+
+	/* The index values are one greater than the channel ID so that alsamixer
+	   will display them correctly. We want to use the index for fast lookup
+	   of the relevant channel, but if we use it at all, most ALSA software
+	   does the wrong thing with it ...
+	 */
+
+	for (idx = 0; idx < limit; ++idx) {
+		snd_hdspm_playback_mixer.index = idx + 1;
+		if ((err = snd_ctl_add(card,
+				       kctl =
+				       snd_ctl_new1
+				       (&snd_hdspm_playback_mixer,
+					hdspm)))) {
+			return err;
+		}
+		hdspm->playback_mixer_ctls[idx] = kctl;
+	}
+
+	return 0;
+}
+
+/*------------------------------------------------------------
+   /proc interface 
+ ------------------------------------------------------------*/
+
+static void
+snd_hdspm_proc_read(snd_info_entry_t * entry, snd_info_buffer_t * buffer)
+{
+	hdspm_t *hdspm = (hdspm_t *) entry->private_data;
+	unsigned int status;
+	unsigned int status2;
+	char *pref_sync_ref;
+	char *autosync_ref;
+	char *system_clock_mode;
+	char *clock_source;
+	char *insel;
+	char *syncref;
+	int x, x2;
+
+	status = hdspm_read(hdspm, HDSPM_statusRegister);
+	status2 = hdspm_read(hdspm, HDSPM_statusRegister2);
+
+	snd_iprintf(buffer, "%s (Card #%d) Rev.%x Status2first3bits: %x\n",
+		    hdspm->card_name, hdspm->card->number + 1,
+		    hdspm->firmware_rev,
+		    (status2 & HDSPM_version0) |
+		    (status2 & HDSPM_version1) | (status2 &
+						  HDSPM_version2));
+
+	snd_iprintf(buffer, "IRQ: %d Registers bus: 0x%lx VM: 0x%lx\n",
+		    hdspm->irq, hdspm->port, (unsigned long)hdspm->iobase);
+
+	snd_iprintf(buffer, "--- System ---\n");
+
+	snd_iprintf(buffer,
+		    "IRQ Pending: Audio=%d, MIDI0=%d, MIDI1=%d, IRQcount=%d\n",
+		    status & HDSPM_audioIRQPending,
+		    (status & HDSPM_midi0IRQPending) ? 1 : 0,
+		    (status & HDSPM_midi1IRQPending) ? 1 : 0,
+		    hdspm->irq_count);
+	snd_iprintf(buffer,
+		    "HW pointer: id = %d, rawptr = %d (%d->%d) estimated= %ld (bytes)\n",
+		    ((status & HDSPM_BufferID) ? 1 : 0),
+		    (status & HDSPM_BufferPositionMask),
+		    (status & HDSPM_BufferPositionMask) % (2 *
+							   (int)hdspm->
+							   period_bytes),
+		    ((status & HDSPM_BufferPositionMask) -
+		     64) % (2 * (int)hdspm->period_bytes),
+		    (long) hdspm_hw_pointer(hdspm) * 4);
+
+	snd_iprintf(buffer,
+		    "MIDI FIFO: Out1=0x%x, Out2=0x%x, In1=0x%x, In2=0x%x \n",
+		    hdspm_read(hdspm, HDSPM_midiStatusOut0) & 0xFF,
+		    hdspm_read(hdspm, HDSPM_midiStatusOut1) & 0xFF,
+		    hdspm_read(hdspm, HDSPM_midiStatusIn0) & 0xFF,
+		    hdspm_read(hdspm, HDSPM_midiStatusIn1) & 0xFF);
+	snd_iprintf(buffer,
+		    "Register: ctrl1=0x%x, ctrl2=0x%x, status1=0x%x, status2=0x%x\n",
+		    hdspm->control_register, hdspm->control2_register,
+		    status, status2);
+
+	snd_iprintf(buffer, "--- Settings ---\n");
+
+	x = 1 << (6 +
+		  hdspm_decode_latency(hdspm->
+				       control_register &
+				       HDSPM_LatencyMask));
+
+	snd_iprintf(buffer,
+		    "Size (Latency): %d samples (2 periods of %lu bytes)\n",
+		    x, (unsigned long) hdspm->period_bytes);
+
+	snd_iprintf(buffer, "Line out: %s,   Precise Pointer: %s\n",
+		    (hdspm->
+		     control_register & HDSPM_LineOut) ? "on " : "off",
+		    (hdspm->precise_ptr) ? "on" : "off");
+
+	switch (hdspm->control_register & HDSPM_InputMask) {
+	case HDSPM_InputOptical:
+		insel = "Optical";
+		break;
+	case HDSPM_InputCoaxial:
+		insel = "Coaxial";
+		break;
+	default:
+		insel = "Unkown";
+	}
+
+	switch (hdspm->control_register & HDSPM_SyncRefMask) {
+	case HDSPM_SyncRef_Word:
+		syncref = "WordClock";
+		break;
+	case HDSPM_SyncRef_MADI:
+		syncref = "MADI";
+		break;
+	default:
+		syncref = "Unkown";
+	}
+	snd_iprintf(buffer, "Inputsel = %s, SyncRef = %s\n", insel,
+		    syncref);
+
+	snd_iprintf(buffer,
+		    "ClearTrackMarker = %s, Transmit in %s Channel Mode, Auto Input %s\n",
+		    (hdspm->
+		     control_register & HDSPM_clr_tms) ? "on" : "off",
+		    (hdspm->
+		     control_register & HDSPM_TX_64ch) ? "64" : "56",
+		    (hdspm->
+		     control_register & HDSPM_AutoInp) ? "on" : "off");
+
+	switch (hdspm_clock_source(hdspm)) {
+	case HDSPM_CLOCK_SOURCE_AUTOSYNC:
+		clock_source = "AutoSync";
+		break;
+	case HDSPM_CLOCK_SOURCE_INTERNAL_32KHZ:
+		clock_source = "Internal 32 kHz";
+		break;
+	case HDSPM_CLOCK_SOURCE_INTERNAL_44_1KHZ:
+		clock_source = "Internal 44.1 kHz";
+		break;
+	case HDSPM_CLOCK_SOURCE_INTERNAL_48KHZ:
+		clock_source = "Internal 48 kHz";
+		break;
+	case HDSPM_CLOCK_SOURCE_INTERNAL_64KHZ:
+		clock_source = "Internal 64 kHz";
+		break;
+	case HDSPM_CLOCK_SOURCE_INTERNAL_88_2KHZ:
+		clock_source = "Internal 88.2 kHz";
+		break;
+	case HDSPM_CLOCK_SOURCE_INTERNAL_96KHZ:
+		clock_source = "Internal 96 kHz";
+		break;
+	default:
+		clock_source = "Error";
+	}
+	snd_iprintf(buffer, "Sample Clock Source: %s\n", clock_source);
+	if (!(hdspm->control_register & HDSPM_ClockModeMaster)) {
+		system_clock_mode = "Slave";
+	} else {
+		system_clock_mode = "Master";
+	}
+	snd_iprintf(buffer, "System Clock Mode: %s\n", system_clock_mode);
+
+	switch (hdspm_pref_sync_ref(hdspm)) {
+	case HDSPM_SYNC_FROM_WORD:
+		pref_sync_ref = "Word Clock";
+		break;
+	case HDSPM_SYNC_FROM_MADI:
+		pref_sync_ref = "MADI Sync";
+		break;
+	default:
+		pref_sync_ref = "XXXX Clock";
+		break;
+	}
+	snd_iprintf(buffer, "Preferred Sync Reference: %s\n",
+		    pref_sync_ref);
+
+	snd_iprintf(buffer, "System Clock Frequency: %d\n",
+		    hdspm->system_sample_rate);
+
+
+	snd_iprintf(buffer, "--- Status:\n");
+
+	x = status & HDSPM_madiSync;
+	x2 = status2 & HDSPM_wcSync;
+
+	snd_iprintf(buffer, "Inputs MADI=%s, WordClock=%s\n",
+		    (status & HDSPM_madiLock) ? (x ? "Sync" : "Lock") :
+		    "NoLock",
+		    (status2 & HDSPM_wcLock) ? (x2 ? "Sync" : "Lock") :
+		    "NoLock");
+
+	switch (hdspm_autosync_ref(hdspm)) {
+	case HDSPM_AUTOSYNC_FROM_WORD:
+		autosync_ref = "Word Clock";
+		break;
+	case HDSPM_AUTOSYNC_FROM_MADI:
+		autosync_ref = "MADI Sync";
+		break;
+	case HDSPM_AUTOSYNC_FROM_NONE:
+		autosync_ref = "Input not valid";
+		break;
+	default:
+		autosync_ref = "---";
+		break;
+	}
+	snd_iprintf(buffer,
+		    "AutoSync: Reference= %s, Freq=%d (MADI = %d, Word = %d)\n",
+		    autosync_ref, hdspm_external_sample_rate(hdspm),
+		    (status & HDSPM_madiFreqMask) >> 22,
+		    (status2 & HDSPM_wcFreqMask) >> 5);
+
+	snd_iprintf(buffer, "Input: %s, Mode=%s\n",
+		    (status & HDSPM_AB_int) ? "Coax" : "Optical",
+		    (status & HDSPM_RX_64ch) ? "64 channels" :
+		    "56 channels");
+
+	snd_iprintf(buffer, "\n");
+}
+
+static void __devinit snd_hdspm_proc_init(hdspm_t * hdspm)
+{
+	snd_info_entry_t *entry;
+
+	if (!snd_card_proc_new(hdspm->card, "hdspm", &entry))
+		snd_info_set_text_ops(entry, hdspm, 1024,
+				      snd_hdspm_proc_read);
+}
+
+/*------------------------------------------------------------
+   hdspm intitialize 
+ ------------------------------------------------------------*/
+
+static int snd_hdspm_set_defaults(hdspm_t * hdspm)
+{
+	unsigned int i;
+
+	/* ASSUMPTION: hdspm->lock is either held, or there is no need to
+	   hold it (e.g. during module initalization).
+	 */
+
+	/* set defaults:       */
+
+	hdspm->control_register = HDSPM_ClockModeMaster |	/* Master Cloack Mode on */
+	    hdspm_encode_latency(7) |	/* latency maximum = 8192 samples */
+	    HDSPM_InputCoaxial |	/* Input Coax not Optical */
+	    HDSPM_SyncRef_MADI |	/* Madi is syncclock */
+	    HDSPM_LineOut |	/* Analog output in */
+	    HDSPM_TX_64ch |	/* transmit in 64ch mode */
+	    HDSPM_AutoInp;	/* AutoInput chossing (takeover) */
+
+	/* ! HDSPM_Frequency0|HDSPM_Frequency1 = 44.1khz */
+	/* !  HDSPM_DoubleSpeed HDSPM_QuadSpeed = normal speed */
+	/* ! HDSPM_clr_tms = do not clear bits in track marks */
+
+	hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
+
+#ifdef SNDRV_BIG_ENDIAN
+	hdspm->control2_register = HDSPM_BIGENDIAN_MODE;
+#else
+	hdspm->control2_register = 0;
+#endif
+
+	hdspm_write(hdspm, HDSPM_control2Reg, hdspm->control2_register);
+	hdspm_compute_period_size(hdspm);
+
+	/* silence everything */
+
+	all_in_all_mixer(hdspm, 0 * UNITY_GAIN);
+
+	if (line_outs_monitor[hdspm->dev]) {
+
+		snd_printk(KERN_INFO "HDSPM: sending all playback streams to line outs.\n");
+
+		for (i = 0; i < HDSPM_MIXER_CHANNELS; i++) {
+			if (hdspm_write_pb_gain(hdspm, i, i, UNITY_GAIN))
+				return -EIO;
+		}
+	}
+
+	/* set a default rate so that the channel map is set up. */
+	hdspm->channel_map = channel_map_madi_ss;
+	hdspm_set_rate(hdspm, 44100, 1);
+
+	return 0;
+}
+
+
+/*------------------------------------------------------------
+   interupt 
+ ------------------------------------------------------------*/
+
+static irqreturn_t snd_hdspm_interrupt(int irq, void *dev_id,
+				       struct pt_regs *regs)
+{
+	hdspm_t *hdspm = (hdspm_t *) dev_id;
+	unsigned int status;
+	int audio;
+	int midi0;
+	int midi1;
+	unsigned int midi0status;
+	unsigned int midi1status;
+	int schedule = 0;
+
+	status = hdspm_read(hdspm, HDSPM_statusRegister);
+
+	audio = status & HDSPM_audioIRQPending;
+	midi0 = status & HDSPM_midi0IRQPending;
+	midi1 = status & HDSPM_midi1IRQPending;
+
+	if (!audio && !midi0 && !midi1)
+		return IRQ_NONE;
+
+	hdspm_write(hdspm, HDSPM_interruptConfirmation, 0);
+	hdspm->irq_count++;
+
+	midi0status = hdspm_read(hdspm, HDSPM_midiStatusIn0) & 0xff;
+	midi1status = hdspm_read(hdspm, HDSPM_midiStatusIn1) & 0xff;
+
+	if (audio) {
+
+		if (hdspm->capture_substream)
+			snd_pcm_period_elapsed(hdspm->pcm->
+					       streams
+					       [SNDRV_PCM_STREAM_CAPTURE].
+					       substream);
+
+		if (hdspm->playback_substream)
+			snd_pcm_period_elapsed(hdspm->pcm->
+					       streams
+					       [SNDRV_PCM_STREAM_PLAYBACK].
+					       substream);
+	}
+
+	if (midi0 && midi0status) {
+		/* we disable interrupts for this input until processing is done */
+		hdspm->control_register &= ~HDSPM_Midi0InterruptEnable;
+		hdspm_write(hdspm, HDSPM_controlRegister,
+			    hdspm->control_register);
+		hdspm->midi[0].pending = 1;
+		schedule = 1;
+	}
+	if (midi1 && midi1status) {
+		/* we disable interrupts for this input until processing is done */
+		hdspm->control_register &= ~HDSPM_Midi1InterruptEnable;
+		hdspm_write(hdspm, HDSPM_controlRegister,
+			    hdspm->control_register);
+		hdspm->midi[1].pending = 1;
+		schedule = 1;
+	}
+	if (schedule)
+		tasklet_hi_schedule(&hdspm->midi_tasklet);
+	return IRQ_HANDLED;
+}
+
+/*------------------------------------------------------------
+   pcm interface 
+  ------------------------------------------------------------*/
+
+
+static snd_pcm_uframes_t snd_hdspm_hw_pointer(snd_pcm_substream_t *
+					      substream)
+{
+	hdspm_t *hdspm = snd_pcm_substream_chip(substream);
+	return hdspm_hw_pointer(hdspm);
+}
+
+static char *hdspm_channel_buffer_location(hdspm_t * hdspm,
+					   int stream, int channel)
+{
+	int mapped_channel;
+
+	snd_assert(channel >= 0
+		   || channel < HDSPM_MAX_CHANNELS, return NULL);
+
+	if ((mapped_channel = hdspm->channel_map[channel]) < 0)
+		return NULL;
+
+	if (stream == SNDRV_PCM_STREAM_CAPTURE) {
+		return hdspm->capture_buffer +
+		    mapped_channel * HDSPM_CHANNEL_BUFFER_BYTES;
+	} else {
+		return hdspm->playback_buffer +
+		    mapped_channel * HDSPM_CHANNEL_BUFFER_BYTES;
+	}
+}
+
+
+/* dont know why need it ??? */
+static int snd_hdspm_playback_copy(snd_pcm_substream_t * substream,
+				   int channel, snd_pcm_uframes_t pos,
+				   void __user *src, snd_pcm_uframes_t count)
+{
+	hdspm_t *hdspm = snd_pcm_substream_chip(substream);
+	char *channel_buf;
+
+	snd_assert(pos + count <= HDSPM_CHANNEL_BUFFER_BYTES / 4,
+		   return -EINVAL);
+
+	channel_buf = hdspm_channel_buffer_location(hdspm,
+						    substream->pstr->
+						    stream, channel);
+
+	snd_assert(channel_buf != NULL, return -EIO);
+
+	return copy_from_user(channel_buf + pos * 4, src, count * 4);
+}
+
+static int snd_hdspm_capture_copy(snd_pcm_substream_t * substream,
+				  int channel, snd_pcm_uframes_t pos,
+				  void __user *dst, snd_pcm_uframes_t count)
+{
+	hdspm_t *hdspm = snd_pcm_substream_chip(substream);
+	char *channel_buf;
+
+	snd_assert(pos + count <= HDSPM_CHANNEL_BUFFER_BYTES / 4,
+		   return -EINVAL);
+
+	channel_buf = hdspm_channel_buffer_location(hdspm,
+						    substream->pstr->
+						    stream, channel);
+	snd_assert(channel_buf != NULL, return -EIO);
+	return copy_to_user(dst, channel_buf + pos * 4, count * 4);
+}
+
+static int snd_hdspm_hw_silence(snd_pcm_substream_t * substream,
+				int channel, snd_pcm_uframes_t pos,
+				snd_pcm_uframes_t count)
+{
+	hdspm_t *hdspm = snd_pcm_substream_chip(substream);
+	char *channel_buf;
+
+	channel_buf =
+	    hdspm_channel_buffer_location(hdspm, substream->pstr->stream,
+					  channel);
+	snd_assert(channel_buf != NULL, return -EIO);
+	memset(channel_buf + pos * 4, 0, count * 4);
+	return 0;
+}
+
+static int snd_hdspm_reset(snd_pcm_substream_t * substream)
+{
+	snd_pcm_runtime_t *runtime = substream->runtime;
+	hdspm_t *hdspm = snd_pcm_substream_chip(substream);
+	snd_pcm_substream_t *other;
+
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+		other = hdspm->capture_substream;
+	else
+		other = hdspm->playback_substream;
+
+	if (hdspm->running)
+		runtime->status->hw_ptr = hdspm_hw_pointer(hdspm);
+	else
+		runtime->status->hw_ptr = 0;
+	if (other) {
+		struct list_head *pos;
+		snd_pcm_substream_t *s;
+		snd_pcm_runtime_t *oruntime = other->runtime;
+		snd_pcm_group_for_each(pos, substream) {
+			s = snd_pcm_group_substream_entry(pos);
+			if (s == other) {
+				oruntime->status->hw_ptr =
+				    runtime->status->hw_ptr;
+				break;
+			}
+		}
+	}
+	return 0;
+}
+
+static int snd_hdspm_hw_params(snd_pcm_substream_t * substream,
+			       snd_pcm_hw_params_t * params)
+{
+	hdspm_t *hdspm = snd_pcm_substream_chip(substream);
+	int err;
+	int i;
+	pid_t this_pid;
+	pid_t other_pid;
+	struct snd_sg_buf *sgbuf;
+
+
+	spin_lock_irq(&hdspm->lock);
+
+	if (substream->pstr->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+		this_pid = hdspm->playback_pid;
+		other_pid = hdspm->capture_pid;
+	} else {
+		this_pid = hdspm->capture_pid;
+		other_pid = hdspm->playback_pid;
+	}
+
+	if ((other_pid > 0) && (this_pid != other_pid)) {
+
+		/* The other stream is open, and not by the same
+		   task as this one. Make sure that the parameters
+		   that matter are the same.
+		 */
+
+		if (params_rate(params) != hdspm->system_sample_rate) {
+			spin_unlock_irq(&hdspm->lock);
+			_snd_pcm_hw_param_setempty(params,
+						   SNDRV_PCM_HW_PARAM_RATE);
+			return -EBUSY;
+		}
+
+		if (params_period_size(params) != hdspm->period_bytes / 4) {
+			spin_unlock_irq(&hdspm->lock);
+			_snd_pcm_hw_param_setempty(params,
+						   SNDRV_PCM_HW_PARAM_PERIOD_SIZE);
+			return -EBUSY;
+		}
+
+	}
+	/* We're fine. */
+	spin_unlock_irq(&hdspm->lock);
+
+	/* how to make sure that the rate matches an externally-set one ?   */
+
+	spin_lock_irq(&hdspm->lock);
+	if ((err = hdspm_set_rate(hdspm, params_rate(params), 0)) < 0) {
+		spin_unlock_irq(&hdspm->lock);
+		_snd_pcm_hw_param_setempty(params,
+					   SNDRV_PCM_HW_PARAM_RATE);
+		return err;
+	}
+	spin_unlock_irq(&hdspm->lock);
+
+	if ((err =
+	     hdspm_set_interrupt_interval(hdspm,
+					  params_period_size(params))) <
+	    0) {
+		_snd_pcm_hw_param_setempty(params,
+					   SNDRV_PCM_HW_PARAM_PERIOD_SIZE);
+		return err;
+	}
+
+	/* Memory allocation, takashi's method, dont know if we should spinlock  */
+	/* malloc all buffer even if not enabled to get sure */
+	/* malloc only needed bytes */
+	err =
+	    snd_pcm_lib_malloc_pages(substream,
+				     HDSPM_CHANNEL_BUFFER_BYTES *
+				     params_channels(params));
+	if (err < 0)
+		return err;
+
+	sgbuf = snd_pcm_substream_sgbuf(substream);
+
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+
+		hdspm_set_sgbuf(hdspm, sgbuf, HDSPM_pageAddressBufferOut,
+				params_channels(params));
+
+		for (i = 0; i < params_channels(params); ++i)
+			snd_hdspm_enable_out(hdspm, i, 1);
+
+		hdspm->playback_buffer =
+		    (unsigned char *) substream->runtime->dma_area;
+	} else {
+		hdspm_set_sgbuf(hdspm, sgbuf, HDSPM_pageAddressBufferIn,
+				params_channels(params));
+
+		for (i = 0; i < params_channels(params); ++i)
+			snd_hdspm_enable_in(hdspm, i, 1);
+
+		hdspm->capture_buffer =
+		    (unsigned char *) substream->runtime->dma_area;
+	}
+	return 0;
+}
+
+static int snd_hdspm_hw_free(snd_pcm_substream_t * substream)
+{
+	int i;
+	hdspm_t *hdspm = snd_pcm_substream_chip(substream);
+
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+
+		/* params_channels(params) should be enough, 
+		   but to get sure in case of error */
+		for (i = 0; i < HDSPM_MAX_CHANNELS; ++i)
+			snd_hdspm_enable_out(hdspm, i, 0);
+
+		hdspm->playback_buffer = NULL;
+	} else {
+		for (i = 0; i < HDSPM_MAX_CHANNELS; ++i)
+			snd_hdspm_enable_in(hdspm, i, 0);
+
+		hdspm->capture_buffer = NULL;
+
+	}
+
+	snd_pcm_lib_free_pages(substream);
+
+	return 0;
+}
+
+static int snd_hdspm_channel_info(snd_pcm_substream_t * substream,
+				  snd_pcm_channel_info_t * info)
+{
+	hdspm_t *hdspm = snd_pcm_substream_chip(substream);
+	int mapped_channel;
+
+	snd_assert(info->channel < HDSPM_MAX_CHANNELS, return -EINVAL);
+
+	if ((mapped_channel = hdspm->channel_map[info->channel]) < 0)
+		return -EINVAL;
+
+	info->offset = mapped_channel * HDSPM_CHANNEL_BUFFER_BYTES;
+	info->first = 0;
+	info->step = 32;
+	return 0;
+}
+
+static int snd_hdspm_ioctl(snd_pcm_substream_t * substream,
+			   unsigned int cmd, void *arg)
+{
+	switch (cmd) {
+	case SNDRV_PCM_IOCTL1_RESET:
+		{
+			return snd_hdspm_reset(substream);
+		}
+
+	case SNDRV_PCM_IOCTL1_CHANNEL_INFO:
+		{
+			snd_pcm_channel_info_t *info = arg;
+			return snd_hdspm_channel_info(substream, info);
+		}
+	default:
+		break;
+	}
+
+	return snd_pcm_lib_ioctl(substream, cmd, arg);
+}
+
+static int snd_hdspm_trigger(snd_pcm_substream_t * substream, int cmd)
+{
+	hdspm_t *hdspm = snd_pcm_substream_chip(substream);
+	snd_pcm_substream_t *other;
+	int running;
+
+	spin_lock(&hdspm->lock);
+	running = hdspm->running;
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+		running |= 1 << substream->stream;
+		break;
+	case SNDRV_PCM_TRIGGER_STOP:
+		running &= ~(1 << substream->stream);
+		break;
+	default:
+		snd_BUG();
+		spin_unlock(&hdspm->lock);
+		return -EINVAL;
+	}
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+		other = hdspm->capture_substream;
+	else
+		other = hdspm->playback_substream;
+
+	if (other) {
+		struct list_head *pos;
+		snd_pcm_substream_t *s;
+		snd_pcm_group_for_each(pos, substream) {
+			s = snd_pcm_group_substream_entry(pos);
+			if (s == other) {
+				snd_pcm_trigger_done(s, substream);
+				if (cmd == SNDRV_PCM_TRIGGER_START)
+					running |= 1 << s->stream;
+				else
+					running &= ~(1 << s->stream);
+				goto _ok;
+			}
+		}
+		if (cmd == SNDRV_PCM_TRIGGER_START) {
+			if (!(running & (1 << SNDRV_PCM_STREAM_PLAYBACK))
+			    && substream->stream ==
+			    SNDRV_PCM_STREAM_CAPTURE)
+				hdspm_silence_playback(hdspm);
+		} else {
+			if (running &&
+			    substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+				hdspm_silence_playback(hdspm);
+		}
+	} else {
+		if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
+			hdspm_silence_playback(hdspm);
+	}
+      _ok:
+	snd_pcm_trigger_done(substream, substream);
+	if (!hdspm->running && running)
+		hdspm_start_audio(hdspm);
+	else if (hdspm->running && !running)
+		hdspm_stop_audio(hdspm);
+	hdspm->running = running;
+	spin_unlock(&hdspm->lock);
+
+	return 0;
+}
+
+static int snd_hdspm_prepare(snd_pcm_substream_t * substream)
+{
+	return 0;
+}
+
+static unsigned int period_sizes[] =
+    { 64, 128, 256, 512, 1024, 2048, 4096, 8192 };
+
+static snd_pcm_hardware_t snd_hdspm_playback_subinfo = {
+	.info = (SNDRV_PCM_INFO_MMAP |
+		 SNDRV_PCM_INFO_MMAP_VALID |
+		 SNDRV_PCM_INFO_NONINTERLEAVED |
+		 SNDRV_PCM_INFO_SYNC_START | SNDRV_PCM_INFO_DOUBLE),
+	.formats = SNDRV_PCM_FMTBIT_S32_LE,
+	.rates = (SNDRV_PCM_RATE_32000 |
+		  SNDRV_PCM_RATE_44100 |
+		  SNDRV_PCM_RATE_48000 |
+		  SNDRV_PCM_RATE_64000 |
+		  SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000),
+	.rate_min = 32000,
+	.rate_max = 96000,
+	.channels_min = 1,
+	.channels_max = HDSPM_MAX_CHANNELS,
+	.buffer_bytes_max =
+	    HDSPM_CHANNEL_BUFFER_BYTES * HDSPM_MAX_CHANNELS,
+	.period_bytes_min = (64 * 4),
+	.period_bytes_max = (8192 * 4) * HDSPM_MAX_CHANNELS,
+	.periods_min = 2,
+	.periods_max = 2,
+	.fifo_size = 0
+};
+
+static snd_pcm_hardware_t snd_hdspm_capture_subinfo = {
+	.info = (SNDRV_PCM_INFO_MMAP |
+		 SNDRV_PCM_INFO_MMAP_VALID |
+		 SNDRV_PCM_INFO_NONINTERLEAVED |
+		 SNDRV_PCM_INFO_SYNC_START),
+	.formats = SNDRV_PCM_FMTBIT_S32_LE,
+	.rates = (SNDRV_PCM_RATE_32000 |
+		  SNDRV_PCM_RATE_44100 |
+		  SNDRV_PCM_RATE_48000 |
+		  SNDRV_PCM_RATE_64000 |
+		  SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000),
+	.rate_min = 32000,
+	.rate_max = 96000,
+	.channels_min = 1,
+	.channels_max = HDSPM_MAX_CHANNELS,
+	.buffer_bytes_max =
+	    HDSPM_CHANNEL_BUFFER_BYTES * HDSPM_MAX_CHANNELS,
+	.period_bytes_min = (64 * 4),
+	.period_bytes_max = (8192 * 4) * HDSPM_MAX_CHANNELS,
+	.periods_min = 2,
+	.periods_max = 2,
+	.fifo_size = 0
+};
+
+static snd_pcm_hw_constraint_list_t hw_constraints_period_sizes = {
+	.count = ARRAY_SIZE(period_sizes),
+	.list = period_sizes,
+	.mask = 0
+};
+
+
+static int snd_hdspm_hw_rule_channels_rate(snd_pcm_hw_params_t * params,
+					   snd_pcm_hw_rule_t * rule)
+{
+	hdspm_t *hdspm = rule->private;
+	snd_interval_t *c =
+	    hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
+	snd_interval_t *r =
+	    hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
+
+	if (r->min > 48000) {
+		snd_interval_t t = {
+			.min = 1,
+			.max = hdspm->ds_channels,
+			.integer = 1,
+		};
+		return snd_interval_refine(c, &t);
+	} else if (r->max < 64000) {
+		snd_interval_t t = {
+			.min = 1,
+			.max = hdspm->ss_channels,
+			.integer = 1,
+		};
+		return snd_interval_refine(c, &t);
+	}
+	return 0;
+}
+
+static int snd_hdspm_hw_rule_rate_channels(snd_pcm_hw_params_t * params,
+					   snd_pcm_hw_rule_t * rule)
+{
+	hdspm_t *hdspm = rule->private;
+	snd_interval_t *c =
+	    hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
+	snd_interval_t *r =
+	    hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
+
+	if (c->min <= hdspm->ss_channels) {
+		snd_interval_t t = {
+			.min = 32000,
+			.max = 48000,
+			.integer = 1,
+		};
+		return snd_interval_refine(r, &t);
+	} else if (c->max > hdspm->ss_channels) {
+		snd_interval_t t = {
+			.min = 64000,
+			.max = 96000,
+			.integer = 1,
+		};
+
+		return snd_interval_refine(r, &t);
+	}
+	return 0;
+}
+
+static int snd_hdspm_playback_open(snd_pcm_substream_t * substream)
+{
+	hdspm_t *hdspm = snd_pcm_substream_chip(substream);
+	snd_pcm_runtime_t *runtime = substream->runtime;
+
+	snd_printdd("Open device substream %d\n", substream->stream);
+
+	spin_lock_irq(&hdspm->lock);
+
+	snd_pcm_set_sync(substream);
+
+	runtime->hw = snd_hdspm_playback_subinfo;
+
+	if (hdspm->capture_substream == NULL)
+		hdspm_stop_audio(hdspm);
+
+	hdspm->playback_pid = current->pid;
+	hdspm->playback_substream = substream;
+
+	spin_unlock_irq(&hdspm->lock);
+
+	snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
+
+	snd_pcm_hw_constraint_list(runtime, 0,
+				   SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
+				   &hw_constraints_period_sizes);
+
+	snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
+			    snd_hdspm_hw_rule_channels_rate, hdspm,
+			    SNDRV_PCM_HW_PARAM_RATE, -1);
+
+	snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
+			    snd_hdspm_hw_rule_rate_channels, hdspm,
+			    SNDRV_PCM_HW_PARAM_CHANNELS, -1);
+
+	return 0;
+}
+
+static int snd_hdspm_playback_release(snd_pcm_substream_t * substream)
+{
+	hdspm_t *hdspm = snd_pcm_substream_chip(substream);
+
+	spin_lock_irq(&hdspm->lock);
+
+	hdspm->playback_pid = -1;
+	hdspm->playback_substream = NULL;
+
+	spin_unlock_irq(&hdspm->lock);
+
+	return 0;
+}
+
+
+static int snd_hdspm_capture_open(snd_pcm_substream_t * substream)
+{
+	hdspm_t *hdspm = snd_pcm_substream_chip(substream);
+	snd_pcm_runtime_t *runtime = substream->runtime;
+
+	spin_lock_irq(&hdspm->lock);
+	snd_pcm_set_sync(substream);
+	runtime->hw = snd_hdspm_capture_subinfo;
+
+	if (hdspm->playback_substream == NULL)
+		hdspm_stop_audio(hdspm);
+
+	hdspm->capture_pid = current->pid;
+	hdspm->capture_substream = substream;
+
+	spin_unlock_irq(&hdspm->lock);
+
+	snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
+	snd_pcm_hw_constraint_list(runtime, 0,
+				   SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
+				   &hw_constraints_period_sizes);
+
+	snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
+			    snd_hdspm_hw_rule_channels_rate, hdspm,
+			    SNDRV_PCM_HW_PARAM_RATE, -1);
+
+	snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
+			    snd_hdspm_hw_rule_rate_channels, hdspm,
+			    SNDRV_PCM_HW_PARAM_CHANNELS, -1);
+	return 0;
+}
+
+static int snd_hdspm_capture_release(snd_pcm_substream_t * substream)
+{
+	hdspm_t *hdspm = snd_pcm_substream_chip(substream);
+
+	spin_lock_irq(&hdspm->lock);
+
+	hdspm->capture_pid = -1;
+	hdspm->capture_substream = NULL;
+
+	spin_unlock_irq(&hdspm->lock);
+	return 0;
+}
+
+static int snd_hdspm_hwdep_dummy_op(snd_hwdep_t * hw, struct file *file)
+{
+	/* we have nothing to initialize but the call is required */
+	return 0;
+}
+
+
+static int snd_hdspm_hwdep_ioctl(snd_hwdep_t * hw, struct file *file,
+				 unsigned int cmd, unsigned long arg)
+{
+	hdspm_t *hdspm = (hdspm_t *) hw->private_data;
+	struct sndrv_hdspm_mixer_ioctl mixer;
+	hdspm_config_info_t info;
+	hdspm_version_t hdspm_version;
+	struct sndrv_hdspm_peak_rms_ioctl rms;
+
+	switch (cmd) {
+
+		
+	case SNDRV_HDSPM_IOCTL_GET_PEAK_RMS:
+		if (copy_from_user(&rms, (void __user *)arg, sizeof(rms)))
+			return -EFAULT;
+		/* maybe there is a chance to memorymap in future so dont touch just copy */
+		if(copy_to_user_fromio((void __user *)rms.peak,
+				       hdspm->iobase+HDSPM_MADI_peakrmsbase,
+				       sizeof(hdspm_peak_rms_t)) != 0 )
+			return -EFAULT;
+
+		break;
+		
+
+	case SNDRV_HDSPM_IOCTL_GET_CONFIG_INFO:
+
+		spin_lock_irq(&hdspm->lock);
+		info.pref_sync_ref =
+		    (unsigned char) hdspm_pref_sync_ref(hdspm);
+		info.wordclock_sync_check =
+		    (unsigned char) hdspm_wc_sync_check(hdspm);
+
+		info.system_sample_rate = hdspm->system_sample_rate;
+		info.autosync_sample_rate =
+		    hdspm_external_sample_rate(hdspm);
+		info.system_clock_mode =
+		    (unsigned char) hdspm_system_clock_mode(hdspm);
+		info.clock_source =
+		    (unsigned char) hdspm_clock_source(hdspm);
+		info.autosync_ref =
+		    (unsigned char) hdspm_autosync_ref(hdspm);
+		info.line_out = (unsigned char) hdspm_line_out(hdspm);
+		info.passthru = 0;
+		spin_unlock_irq(&hdspm->lock);
+		if (copy_to_user((void __user *) arg, &info, sizeof(info)))
+			return -EFAULT;
+		break;
+
+	case SNDRV_HDSPM_IOCTL_GET_VERSION:
+		hdspm_version.firmware_rev = hdspm->firmware_rev;
+		if (copy_to_user((void __user *) arg, &hdspm_version,
+				 sizeof(hdspm_version)))
+			return -EFAULT;
+		break;
+
+	case SNDRV_HDSPM_IOCTL_GET_MIXER:
+		if (copy_from_user(&mixer, (void __user *)arg, sizeof(mixer)))
+			return -EFAULT;
+		if (copy_to_user
+		    ((void __user *)mixer.mixer, hdspm->mixer, sizeof(hdspm_mixer_t)))
+			return -EFAULT;
+		break;
+
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static snd_pcm_ops_t snd_hdspm_playback_ops = {
+	.open = snd_hdspm_playback_open,
+	.close = snd_hdspm_playback_release,
+	.ioctl = snd_hdspm_ioctl,
+	.hw_params = snd_hdspm_hw_params,
+	.hw_free = snd_hdspm_hw_free,
+	.prepare = snd_hdspm_prepare,
+	.trigger = snd_hdspm_trigger,
+	.pointer = snd_hdspm_hw_pointer,
+	.copy = snd_hdspm_playback_copy,
+	.silence = snd_hdspm_hw_silence,
+	.page = snd_pcm_sgbuf_ops_page,
+};
+
+static snd_pcm_ops_t snd_hdspm_capture_ops = {
+	.open = snd_hdspm_capture_open,
+	.close = snd_hdspm_capture_release,
+	.ioctl = snd_hdspm_ioctl,
+	.hw_params = snd_hdspm_hw_params,
+	.hw_free = snd_hdspm_hw_free,
+	.prepare = snd_hdspm_prepare,
+	.trigger = snd_hdspm_trigger,
+	.pointer = snd_hdspm_hw_pointer,
+	.copy = snd_hdspm_capture_copy,
+	.page = snd_pcm_sgbuf_ops_page,
+};
+
+static int __devinit snd_hdspm_create_hwdep(snd_card_t * card,
+					    hdspm_t * hdspm)
+{
+	snd_hwdep_t *hw;
+	int err;
+
+	if ((err = snd_hwdep_new(card, "HDSPM hwdep", 0, &hw)) < 0)
+		return err;
+
+	hdspm->hwdep = hw;
+	hw->private_data = hdspm;
+	strcpy(hw->name, "HDSPM hwdep interface");
+
+	hw->ops.open = snd_hdspm_hwdep_dummy_op;
+	hw->ops.ioctl = snd_hdspm_hwdep_ioctl;
+	hw->ops.release = snd_hdspm_hwdep_dummy_op;
+
+	return 0;
+}
+
+
+/*------------------------------------------------------------
+   memory interface 
+ ------------------------------------------------------------*/
+static int __devinit snd_hdspm_preallocate_memory(hdspm_t * hdspm)
+{
+	int err;
+	snd_pcm_t *pcm;
+	size_t wanted;
+
+	pcm = hdspm->pcm;
+
+	wanted = HDSPM_DMA_AREA_BYTES + 4096;	/* dont know why, but it works */
+
+	if ((err =
+	     snd_pcm_lib_preallocate_pages_for_all(pcm,
+	     					   SNDRV_DMA_TYPE_DEV_SG,
+						   snd_dma_pci_data(hdspm->pci),
+						   wanted,
+						   wanted)) < 0) {
+		snd_printdd("Could not preallocate %d  Bytes\n", wanted);
+
+		return err;
+	} else
+		snd_printdd(" Preallocated %d  Bytes\n", wanted);
+
+	return 0;
+}
+
+static int snd_hdspm_memory_free(hdspm_t * hdspm)
+{
+	snd_printdd("memory_free_for_all %p\n", hdspm->pcm);
+
+	snd_pcm_lib_preallocate_free_for_all(hdspm->pcm);
+	return 0;
+}
+
+
+static void hdspm_set_sgbuf(hdspm_t * hdspm, struct snd_sg_buf *sgbuf,
+			     unsigned int reg, int channels)
+{
+	int i;
+	for (i = 0; i < (channels * 16); i++)
+		hdspm_write(hdspm, reg + 4 * i,
+			    snd_pcm_sgbuf_get_addr(sgbuf,
+						   (size_t) 4096 * i));
+}
+
+/* ------------- ALSA Devices ---------------------------- */
+static int __devinit snd_hdspm_create_pcm(snd_card_t * card,
+					  hdspm_t * hdspm)
+{
+	snd_pcm_t *pcm;
+	int err;
+
+	if ((err = snd_pcm_new(card, hdspm->card_name, 0, 1, 1, &pcm)) < 0)
+		return err;
+
+	hdspm->pcm = pcm;
+	pcm->private_data = hdspm;
+	strcpy(pcm->name, hdspm->card_name);
+
+	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
+			&snd_hdspm_playback_ops);
+	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
+			&snd_hdspm_capture_ops);
+
+	pcm->info_flags = SNDRV_PCM_INFO_JOINT_DUPLEX;
+
+	if ((err = snd_hdspm_preallocate_memory(hdspm)) < 0)
+		return err;
+
+	return 0;
+}
+
+static inline void snd_hdspm_initialize_midi_flush(hdspm_t * hdspm)
+{
+	snd_hdspm_flush_midi_input(hdspm, 0);
+	snd_hdspm_flush_midi_input(hdspm, 1);
+}
+
+static int __devinit snd_hdspm_create_alsa_devices(snd_card_t * card,
+						   hdspm_t * hdspm)
+{
+	int err;
+
+	snd_printdd("Create card...\n");
+	if ((err = snd_hdspm_create_pcm(card, hdspm)) < 0)
+		return err;
+
+	if ((err = snd_hdspm_create_midi(card, hdspm, 0)) < 0)
+		return err;
+
+	if ((err = snd_hdspm_create_midi(card, hdspm, 1)) < 0)
+		return err;
+
+	if ((err = snd_hdspm_create_controls(card, hdspm)) < 0)
+		return err;
+
+	if ((err = snd_hdspm_create_hwdep(card, hdspm)) < 0)
+		return err;
+
+	snd_printdd("proc init...\n");
+	snd_hdspm_proc_init(hdspm);
+
+	hdspm->system_sample_rate = -1;
+	hdspm->last_external_sample_rate = -1;
+	hdspm->last_internal_sample_rate = -1;
+	hdspm->playback_pid = -1;
+	hdspm->capture_pid = -1;
+	hdspm->capture_substream = NULL;
+	hdspm->playback_substream = NULL;
+
+	snd_printdd("Set defaults...\n");
+	if ((err = snd_hdspm_set_defaults(hdspm)) < 0)
+		return err;
+
+	snd_printdd("Update mixer controls...\n");
+	hdspm_update_simple_mixer_controls(hdspm);
+
+	snd_printdd("Initializeing complete ???\n");
+
+	if ((err = snd_card_register(card)) < 0) {
+		snd_printk(KERN_ERR "HDSPM: error registering card\n");
+		return err;
+	}
+
+	snd_printdd("... yes now\n");
+
+	return 0;
+}
+
+static int __devinit snd_hdspm_create(snd_card_t * card, hdspm_t * hdspm,
+				      int precise_ptr, int enable_monitor)
+{
+	struct pci_dev *pci = hdspm->pci;
+	int err;
+	int i;
+
+	unsigned long io_extent;
+
+	hdspm->irq = -1;
+	hdspm->irq_count = 0;
+
+	hdspm->midi[0].rmidi = NULL;
+	hdspm->midi[1].rmidi = NULL;
+	hdspm->midi[0].input = NULL;
+	hdspm->midi[1].input = NULL;
+	hdspm->midi[0].output = NULL;
+	hdspm->midi[1].output = NULL;
+	spin_lock_init(&hdspm->midi[0].lock);
+	spin_lock_init(&hdspm->midi[1].lock);
+	hdspm->iobase = NULL;
+	hdspm->control_register = 0;
+	hdspm->control2_register = 0;
+
+	hdspm->playback_buffer = NULL;
+	hdspm->capture_buffer = NULL;
+
+	for (i = 0; i < HDSPM_MAX_CHANNELS; ++i)
+		hdspm->playback_mixer_ctls[i] = NULL;
+	hdspm->mixer = NULL;
+
+	hdspm->card = card;
+
+	spin_lock_init(&hdspm->lock);
+
+	tasklet_init(&hdspm->midi_tasklet,
+		     hdspm_midi_tasklet, (unsigned long) hdspm);
+
+	pci_read_config_word(hdspm->pci,
+			     PCI_CLASS_REVISION, &hdspm->firmware_rev);
+
+	strcpy(card->driver, "HDSPM");
+	strcpy(card->mixername, "Xilinx FPGA");
+	hdspm->card_name = "RME HDSPM MADI";
+
+	if ((err = pci_enable_device(pci)) < 0)
+		return err;
+
+	pci_set_master(hdspm->pci);
+
+	if ((err = pci_request_regions(pci, "hdspm")) < 0)
+		return err;
+
+	hdspm->port = pci_resource_start(pci, 0);
+	io_extent = pci_resource_len(pci, 0);
+
+	snd_printdd("grabbed memory region 0x%lx-0x%lx\n",
+		   hdspm->port, hdspm->port + io_extent - 1);
+
+
+	if ((hdspm->iobase = ioremap_nocache(hdspm->port, io_extent)) == NULL) {
+		snd_printk(KERN_ERR "HDSPM: unable to remap region 0x%lx-0x%lx\n",
+			   hdspm->port, hdspm->port + io_extent - 1);
+		return -EBUSY;
+	}
+	snd_printdd("remapped region (0x%lx) 0x%lx-0x%lx\n",
+		   (unsigned long)hdspm->iobase, hdspm->port,
+		   hdspm->port + io_extent - 1);
+
+	if (request_irq(pci->irq, snd_hdspm_interrupt,
+			SA_INTERRUPT | SA_SHIRQ, "hdspm",
+			(void *) hdspm)) {
+		snd_printk(KERN_ERR "HDSPM: unable to use IRQ %d\n", pci->irq);
+		return -EBUSY;
+	}
+
+	snd_printdd("use IRQ %d\n", pci->irq);
+
+	hdspm->irq = pci->irq;
+	hdspm->precise_ptr = precise_ptr;
+
+	hdspm->monitor_outs = enable_monitor;
+
+	snd_printdd("kmalloc Mixer memory of %d Bytes\n",
+		   sizeof(hdspm_mixer_t));
+	if ((hdspm->mixer =
+	     (hdspm_mixer_t *) kmalloc(sizeof(hdspm_mixer_t), GFP_KERNEL))
+	    == NULL) {
+		snd_printk(KERN_ERR "HDSPM: unable to kmalloc Mixer memory of %d Bytes\n",
+			   (int)sizeof(hdspm_mixer_t));
+		return err;
+	}
+
+	hdspm->ss_channels = MADI_SS_CHANNELS;
+	hdspm->ds_channels = MADI_DS_CHANNELS;
+	hdspm->qs_channels = MADI_QS_CHANNELS;
+
+	snd_printdd("create alsa devices.\n");
+	if ((err = snd_hdspm_create_alsa_devices(card, hdspm)) < 0)
+		return err;
+
+	snd_hdspm_initialize_midi_flush(hdspm);
+
+	return 0;
+}
+
+static int snd_hdspm_free(hdspm_t * hdspm)
+{
+
+	if (hdspm->port) {
+
+		/* stop th audio, and cancel all interrupts */
+		hdspm->control_register &=
+		    ~(HDSPM_Start | HDSPM_AudioInterruptEnable
+		      | HDSPM_Midi0InterruptEnable |
+		      HDSPM_Midi1InterruptEnable);
+		hdspm_write(hdspm, HDSPM_controlRegister,
+			    hdspm->control_register);
+	}
+
+	if (hdspm->irq >= 0)
+		free_irq(hdspm->irq, (void *) hdspm);
+
+
+	if (hdspm->mixer)
+		kfree(hdspm->mixer);
+
+	if (hdspm->iobase)
+		iounmap(hdspm->iobase);
+
+	snd_hdspm_memory_free(hdspm);
+
+	if (hdspm->port)
+		pci_release_regions(hdspm->pci);
+
+	pci_disable_device(hdspm->pci);
+	return 0;
+}
+
+static void snd_hdspm_card_free(snd_card_t * card)
+{
+	hdspm_t *hdspm = (hdspm_t *) card->private_data;
+
+	if (hdspm)
+		snd_hdspm_free(hdspm);
+}
+
+static int __devinit snd_hdspm_probe(struct pci_dev *pci,
+				     const struct pci_device_id *pci_id)
+{
+	static int dev;
+	hdspm_t *hdspm;
+	snd_card_t *card;
+	int err;
+
+	if (dev >= SNDRV_CARDS)
+		return -ENODEV;
+	if (!enable[dev]) {
+		dev++;
+		return -ENOENT;
+	}
+
+	if (!(card = snd_card_new(index[dev], id[dev],
+				  THIS_MODULE, sizeof(hdspm_t))))
+		return -ENOMEM;
+
+	hdspm = (hdspm_t *) card->private_data;
+	card->private_free = snd_hdspm_card_free;
+	hdspm->dev = dev;
+	hdspm->pci = pci;
+
+	if ((err =
+	     snd_hdspm_create(card, hdspm, precise_ptr[dev],
+			      enable_monitor[dev])) < 0) {
+		snd_card_free(card);
+		return err;
+	}
+
+	strcpy(card->shortname, "HDSPM MADI");
+	sprintf(card->longname, "%s at 0x%lx, irq %d", hdspm->card_name,
+		hdspm->port, hdspm->irq);
+
+	if ((err = snd_card_register(card)) < 0) {
+		snd_card_free(card);
+		return err;
+	}
+
+	pci_set_drvdata(pci, card);
+
+	dev++;
+	return 0;
+}
+
+static void __devexit snd_hdspm_remove(struct pci_dev *pci)
+{
+	snd_card_free(pci_get_drvdata(pci));
+	pci_set_drvdata(pci, NULL);
+}
+
+static struct pci_driver driver = {
+	.name = "RME Hammerfall DSP MADI",
+	.id_table = snd_hdspm_ids,
+	.probe = snd_hdspm_probe,
+	.remove = __devexit_p(snd_hdspm_remove),
+};
+
+
+static int __init alsa_card_hdspm_init(void)
+{
+	return pci_register_driver(&driver);
+}
+
+static void __exit alsa_card_hdspm_exit(void)
+{
+	pci_unregister_driver(&driver);
+}
+
+module_init(alsa_card_hdspm_init)
+module_exit(alsa_card_hdspm_exit)
diff --git a/sound/pci/rme9652/rme9652.c b/sound/pci/rme9652/rme9652.c
--- a/sound/pci/rme9652/rme9652.c
+++ b/sound/pci/rme9652/rme9652.c
@@ -303,18 +303,22 @@ static int snd_hammerfall_get_buffer(str
 {
 	dmab->dev.type = SNDRV_DMA_TYPE_DEV;
 	dmab->dev.dev = snd_dma_pci_data(pci);
-	if (! snd_dma_get_reserved_buf(dmab, snd_dma_pci_buf_id(pci))) {
-		if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
-					size, dmab) < 0)
-			return -ENOMEM;
+	if (snd_dma_get_reserved_buf(dmab, snd_dma_pci_buf_id(pci))) {
+		if (dmab->bytes >= size)
+			return 0;
 	}
+	if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
+				size, dmab) < 0)
+		return -ENOMEM;
 	return 0;
 }
 
 static void snd_hammerfall_free_buffer(struct snd_dma_buffer *dmab, struct pci_dev *pci)
 {
-	if (dmab->area)
+	if (dmab->area) {
+		dmab->dev.dev = NULL; /* make it anonymous */
 		snd_dma_reserve_buf(dmab, snd_dma_pci_buf_id(pci));
+	}
 }
 
 
@@ -1466,7 +1470,7 @@ static int snd_rme9652_get_tc_valid(snd_
 	return 0;
 }
 
-#if ALSA_HAS_STANDARD_WAY_OF_RETURNING_TIMECODE
+#ifdef ALSA_HAS_STANDARD_WAY_OF_RETURNING_TIMECODE
 
 /* FIXME: this routine needs a port to the new control API --jk */
 
@@ -2664,7 +2668,7 @@ static struct pci_driver driver = {
 
 static int __init alsa_card_hammerfall_init(void)
 {
-	return pci_module_init(&driver);
+	return pci_register_driver(&driver);
 }
 
 static void __exit alsa_card_hammerfall_exit(void)
diff --git a/sound/pci/sonicvibes.c b/sound/pci/sonicvibes.c
--- a/sound/pci/sonicvibes.c
+++ b/sound/pci/sonicvibes.c
@@ -1522,7 +1522,7 @@ static struct pci_driver driver = {
 
 static int __init alsa_card_sonicvibes_init(void)
 {
-	return pci_module_init(&driver);
+	return pci_register_driver(&driver);
 }
 
 static void __exit alsa_card_sonicvibes_exit(void)
diff --git a/sound/pci/trident/trident.c b/sound/pci/trident/trident.c
--- a/sound/pci/trident/trident.c
+++ b/sound/pci/trident/trident.c
@@ -143,7 +143,8 @@ static int __devinit snd_trident_probe(s
 			return err;
 		}
 	}
-	if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_TRID4DWAVE,
+	if (trident->device != TRIDENT_DEVICE_ID_SI7018 &&
+	    (err = snd_mpu401_uart_new(card, 0, MPU401_HW_TRID4DWAVE,
 				       trident->midi_port, 1,
 				       trident->irq, 0, &trident->rmidi)) < 0) {
 		snd_card_free(card);
@@ -184,7 +185,7 @@ static struct pci_driver driver = {
 
 static int __init alsa_card_trident_init(void)
 {
-	return pci_module_init(&driver);
+	return pci_register_driver(&driver);
 }
 
 static void __exit alsa_card_trident_exit(void)
diff --git a/sound/pci/trident/trident_main.c b/sound/pci/trident/trident_main.c
--- a/sound/pci/trident/trident_main.c
+++ b/sound/pci/trident/trident_main.c
@@ -472,6 +472,7 @@ void snd_trident_write_voice_regs(triden
 		break;
 	default:
 		snd_BUG();
+		return;
 	}
 
 	outb(voice->number, TRID_REG(trident, T4D_LFO_GC_CIR));
@@ -3152,8 +3153,7 @@ static int snd_trident_gameport_open(str
 	switch (mode) {
 		case GAMEPORT_MODE_COOKED:
 			outb(GAMEPORT_MODE_ADC, TRID_REG(chip, GAMEPORT_GCR));
-			set_current_state(TASK_UNINTERRUPTIBLE);
-			schedule_timeout(1 + 20 * HZ / 1000); /* 20msec */
+			msleep(20);
 			return 0;
 		case GAMEPORT_MODE_RAW:
 			outb(0, TRID_REG(chip, GAMEPORT_GCR));
@@ -3204,7 +3204,7 @@ static inline void snd_trident_free_game
 /*
  * delay for 1 tick
  */
-inline static void do_delay(trident_t *chip)
+static inline void do_delay(trident_t *chip)
 {
 	set_current_state(TASK_UNINTERRUPTIBLE);
 	schedule_timeout(1);
diff --git a/sound/pci/trident/trident_memory.c b/sound/pci/trident/trident_memory.c
--- a/sound/pci/trident/trident_memory.c
+++ b/sound/pci/trident/trident_memory.c
@@ -118,7 +118,7 @@ static inline void set_silent_tlb(triden
 #endif /* PAGE_SIZE */
 
 /* calculate buffer pointer from offset address */
-inline static void *offset_ptr(trident_t *trident, int offset)
+static inline void *offset_ptr(trident_t *trident, int offset)
 {
 	char *ptr;
 	ptr = page_to_ptr(trident, get_aligned_page(offset));
diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c
--- a/sound/pci/via82xx.c
+++ b/sound/pci/via82xx.c
@@ -101,7 +101,7 @@ MODULE_PARM_DESC(ac97_clock, "AC'97 code
 module_param_array(ac97_quirk, charp, NULL, 0444);
 MODULE_PARM_DESC(ac97_quirk, "AC'97 workaround for strange hardware.");
 module_param_array(dxs_support, int, NULL, 0444);
-MODULE_PARM_DESC(dxs_support, "Support for DXS channels (0 = auto, 1 = enable, 2 = disable, 3 = 48k only, 4 = no VRA)");
+MODULE_PARM_DESC(dxs_support, "Support for DXS channels (0 = auto, 1 = enable, 2 = disable, 3 = 48k only, 4 = no VRA, 5 = enable any sample rate)");
 
 
 /* pci ids */
@@ -302,6 +302,7 @@ DEFINE_VIA_REGSET(CAPTURE_8233, 0x60);
 #define VIA_DXS_DISABLE	2
 #define VIA_DXS_48K	3
 #define VIA_DXS_NO_VRA	4
+#define VIA_DXS_SRC	5
 
 
 /*
@@ -380,6 +381,7 @@ struct _snd_via82xx {
 	struct via_rate_lock rates[2]; /* playback and capture */
 	unsigned int dxs_fixed: 1;	/* DXS channel accepts only 48kHz */
 	unsigned int no_vra: 1;		/* no need to set VRA on DXS channels */
+	unsigned int dxs_src: 1;	/* use full SRC capabilities of DXS */
 	unsigned int spdif_on: 1;	/* only spdif rates work to external DACs */
 
 	snd_pcm_t *pcms[2];
@@ -489,10 +491,8 @@ static int clean_via_table(viadev_t *dev
 		snd_dma_free_pages(&dev->table);
 		dev->table.area = NULL;
 	}
-	if (dev->idx_table) {
-		kfree(dev->idx_table);
-		dev->idx_table = NULL;
-	}
+	kfree(dev->idx_table);
+	dev->idx_table = NULL;
 	return 0;
 }
 
@@ -547,8 +547,7 @@ static void snd_via82xx_codec_wait(ac97_
 	int err;
 	err = snd_via82xx_codec_ready(chip, ac97->num);
 	/* here we need to wait fairly for long time.. */
-	set_current_state(TASK_UNINTERRUPTIBLE);
-	schedule_timeout(HZ/2);
+	msleep(500);
 }
 
 static void snd_via82xx_codec_write(ac97_t *ac97,
@@ -924,15 +923,17 @@ static int snd_via8233_playback_prepare(
 	via82xx_t *chip = snd_pcm_substream_chip(substream);
 	viadev_t *viadev = (viadev_t *)substream->runtime->private_data;
 	snd_pcm_runtime_t *runtime = substream->runtime;
+	int ac97_rate = chip->dxs_src ? 48000 : runtime->rate;
 	int rate_changed;
 	u32 rbits;
 
-	if ((rate_changed = via_lock_rate(&chip->rates[0], runtime->rate)) < 0)
+	if ((rate_changed = via_lock_rate(&chip->rates[0], ac97_rate)) < 0)
 		return rate_changed;
 	if (rate_changed) {
 		snd_ac97_set_rate(chip->ac97, AC97_PCM_FRONT_DAC_RATE,
 				  chip->no_vra ? 48000 : runtime->rate);
-		snd_ac97_set_rate(chip->ac97, AC97_SPDIF, runtime->rate);
+		snd_ac97_set_rate(chip->ac97, AC97_SPDIF,
+				  chip->no_vra ? 48000 : runtime->rate);
 	}
 	if (runtime->rate == 48000)
 		rbits = 0xfffff;
@@ -1074,6 +1075,12 @@ static int snd_via82xx_pcm_open(via82xx_
 		/* fixed DXS playback rate */
 		runtime->hw.rates = SNDRV_PCM_RATE_48000;
 		runtime->hw.rate_min = runtime->hw.rate_max = 48000;
+	} else if (chip->dxs_src && viadev->reg_offset < 0x40) {
+		/* use full SRC capabilities of DXS */
+		runtime->hw.rates = (SNDRV_PCM_RATE_CONTINUOUS |
+				     SNDRV_PCM_RATE_8000_48000);
+		runtime->hw.rate_min = 8000;
+		runtime->hw.rate_max = 48000;
 	} else if (! ratep->rate) {
 		int idx = viadev->direction ? AC97_RATES_ADC : AC97_RATES_FRONT_DAC;
 		runtime->hw.rates = chip->ac97->rates[idx];
@@ -1550,51 +1557,51 @@ static void snd_via82xx_mixer_free_ac97(
 
 static struct ac97_quirk ac97_quirks[] = {
 	{
-		.vendor = 0x1106,
-		.device = 0x4161,
+		.subvendor = 0x1106,
+		.subdevice = 0x4161,
 		.codec_id = 0x56494161, /* VT1612A */
 		.name = "Soltek SL-75DRV5",
 		.type = AC97_TUNE_NONE
 	},
 	{	/* FIXME: which codec? */
-		.vendor = 0x1106,
-		.device = 0x4161,
+		.subvendor = 0x1106,
+		.subdevice = 0x4161,
 		.name = "ASRock K7VT2",
 		.type = AC97_TUNE_HP_ONLY
 	},
 	{
-		.vendor = 0x1019,
-		.device = 0x0a81,
+		.subvendor = 0x1019,
+		.subdevice = 0x0a81,
 		.name = "ECS K7VTA3",
 		.type = AC97_TUNE_HP_ONLY
 	},
 	{
-		.vendor = 0x1019,
-		.device = 0x0a85,
+		.subvendor = 0x1019,
+		.subdevice = 0x0a85,
 		.name = "ECS L7VMM2",
 		.type = AC97_TUNE_HP_ONLY
 	},
 	{
-		.vendor = 0x1849,
-		.device = 0x3059,
+		.subvendor = 0x1849,
+		.subdevice = 0x3059,
 		.name = "ASRock K7VM2",
 		.type = AC97_TUNE_HP_ONLY	/* VT1616 */
 	},
 	{
-		.vendor = 0x14cd,
-		.device = 0x7002,
+		.subvendor = 0x14cd,
+		.subdevice = 0x7002,
 		.name = "Unknown",
 		.type = AC97_TUNE_ALC_JACK
 	},
 	{
-		.vendor = 0x1071,
-		.device = 0x8590,
+		.subvendor = 0x1071,
+		.subdevice = 0x8590,
 		.name = "Mitac Mobo",
 		.type = AC97_TUNE_ALC_JACK
 	},
 	{
-		.vendor = 0x161f,
-		.device = 0x202b,
+		.subvendor = 0x161f,
+		.subdevice = 0x202b,
 		.name = "Arima Notebook",
 		.type = AC97_TUNE_HP_ONLY,
 	},
@@ -1839,7 +1846,7 @@ static void __devinit snd_via82xx_proc_i
 static int snd_via82xx_chip_init(via82xx_t *chip)
 {
 	unsigned int val;
-	int max_count;
+	unsigned long end_time;
 	unsigned char pval;
 
 #if 0 /* broken on K7M? */
@@ -1881,14 +1888,14 @@ static int snd_via82xx_chip_init(via82xx
 	}
 
 	/* wait until codec ready */
-	max_count = ((3 * HZ) / 4) + 1;
+	end_time = jiffies + msecs_to_jiffies(750);
 	do {
 		pci_read_config_byte(chip->pci, VIA_ACLINK_STAT, &pval);
 		if (pval & VIA_ACLINK_C00_READY) /* primary codec ready */
 			break;
 		set_current_state(TASK_UNINTERRUPTIBLE);
 		schedule_timeout(1);
-	} while (--max_count > 0);
+	} while (time_before(jiffies, end_time));
 
 	if ((val = snd_via82xx_codec_xread(chip)) & VIA_REG_AC97_BUSY)
 		snd_printk("AC'97 codec is not ready [0x%x]\n", val);
@@ -1897,7 +1904,7 @@ static int snd_via82xx_chip_init(via82xx
 	snd_via82xx_codec_xwrite(chip, VIA_REG_AC97_READ |
 				 VIA_REG_AC97_SECONDARY_VALID |
 				 (VIA_REG_AC97_CODEC_ID_SECONDARY << VIA_REG_AC97_CODEC_ID_SHIFT));
-	max_count = ((3 * HZ) / 4) + 1;
+	end_time = jiffies + msecs_to_jiffies(750);
 	snd_via82xx_codec_xwrite(chip, VIA_REG_AC97_READ |
 				 VIA_REG_AC97_SECONDARY_VALID |
 				 (VIA_REG_AC97_CODEC_ID_SECONDARY << VIA_REG_AC97_CODEC_ID_SHIFT));
@@ -1908,7 +1915,7 @@ static int snd_via82xx_chip_init(via82xx
 		}
 		set_current_state(TASK_INTERRUPTIBLE);
 		schedule_timeout(1);
-	} while (--max_count > 0);
+	} while (time_before(jiffies, end_time));
 	/* This is ok, the most of motherboards have only one codec */
 
       __ac97_ok2:
@@ -2132,8 +2139,8 @@ static struct via823x_info via823x_cards
  * auto detection of DXS channel supports.
  */
 struct dxs_whitelist {
-	unsigned short vendor;
-	unsigned short device; 
+	unsigned short subvendor;
+	unsigned short subdevice; 
 	unsigned short mask; 
 	short action;	/* new dxs_support value */
 };
@@ -2141,38 +2148,45 @@ struct dxs_whitelist {
 static int __devinit check_dxs_list(struct pci_dev *pci)
 {
 	static struct dxs_whitelist whitelist[] = {
-		{ .vendor = 0x1005, .device = 0x4710, .action = VIA_DXS_ENABLE }, /* Avance Logic Mobo */
-		{ .vendor = 0x1019, .device = 0x0996, .action = VIA_DXS_48K },
-		{ .vendor = 0x1019, .device = 0x0a81, .action = VIA_DXS_NO_VRA }, /* ECS K7VTA3 v8.0 */
-		{ .vendor = 0x1019, .device = 0x0a85, .action = VIA_DXS_NO_VRA }, /* ECS L7VMM2 */
-		{ .vendor = 0x1025, .device = 0x0033, .action = VIA_DXS_NO_VRA }, /* Acer Inspire 1353LM */
-		{ .vendor = 0x1043, .device = 0x8095, .action = VIA_DXS_NO_VRA }, /* ASUS A7V8X (FIXME: possibly VIA_DXS_ENABLE?)*/
-		{ .vendor = 0x1043, .device = 0x80a1, .action = VIA_DXS_NO_VRA }, /* ASUS A7V8-X */
-		{ .vendor = 0x1043, .device = 0x80b0, .action = VIA_DXS_NO_VRA }, /* ASUS A7V600 & K8V*/ 
-		{ .vendor = 0x1071, .device = 0x8375, .action = VIA_DXS_NO_VRA }, /* Vobis/Yakumo/Mitac notebook */
-		{ .vendor = 0x10cf, .device = 0x118e, .action = VIA_DXS_ENABLE }, /* FSC laptop */
-		{ .vendor = 0x1106, .device = 0x4161, .action = VIA_DXS_NO_VRA }, /* ASRock K7VT2 */
-		{ .vendor = 0x1106, .device = 0x4552, .action = VIA_DXS_NO_VRA }, /* QDI Kudoz 7X/600-6AL */
-		{ .vendor = 0x1106, .device = 0xaa01, .action = VIA_DXS_NO_VRA }, /* EPIA MII */
-		{ .vendor = 0x1297, .device = 0xa232, .action = VIA_DXS_ENABLE }, /* Shuttle ?? */
-		{ .vendor = 0x1297, .device = 0xc160, .action = VIA_DXS_ENABLE }, /* Shuttle SK41G */
-		{ .vendor = 0x1458, .device = 0xa002, .action = VIA_DXS_ENABLE }, /* Gigabyte GA-7VAXP */
-		{ .vendor = 0x1462, .device = 0x3800, .action = VIA_DXS_ENABLE }, /* MSI KT266 */
-		{ .vendor = 0x1462, .device = 0x5901, .action = VIA_DXS_NO_VRA }, /* MSI KT6 Delta-SR */
-		{ .vendor = 0x1462, .device = 0x7023, .action = VIA_DXS_NO_VRA }, /* MSI K8T Neo2-FI */
-		{ .vendor = 0x1462, .device = 0x7120, .action = VIA_DXS_ENABLE }, /* MSI KT4V */
-		{ .vendor = 0x147b, .device = 0x1401, .action = VIA_DXS_ENABLE }, /* ABIT KD7(-RAID) */
-		{ .vendor = 0x147b, .device = 0x1411, .action = VIA_DXS_ENABLE }, /* ABIT VA-20 */
-		{ .vendor = 0x147b, .device = 0x1413, .action = VIA_DXS_ENABLE }, /* ABIT KV8 Pro */
-		{ .vendor = 0x147b, .device = 0x1415, .action = VIA_DXS_NO_VRA }, /* Abit AV8 */
-		{ .vendor = 0x14ff, .device = 0x0403, .action = VIA_DXS_ENABLE }, /* Twinhead mobo */
-		{ .vendor = 0x1584, .device = 0x8120, .action = VIA_DXS_ENABLE }, /* Gericom/Targa/Vobis/Uniwill laptop */
-		{ .vendor = 0x1584, .device = 0x8123, .action = VIA_DXS_NO_VRA }, /* Uniwill (Targa Visionary XP-210) */
-		{ .vendor = 0x161f, .device = 0x202b, .action = VIA_DXS_NO_VRA }, /* Amira Note book */
-		{ .vendor = 0x161f, .device = 0x2032, .action = VIA_DXS_48K }, /* m680x machines */
-		{ .vendor = 0x1631, .device = 0xe004, .action = VIA_DXS_ENABLE }, /* Easy Note 3174, Packard Bell */
-		{ .vendor = 0x1695, .device = 0x3005, .action = VIA_DXS_ENABLE }, /* EPoX EP-8K9A */
-		{ .vendor = 0x1849, .device = 0x3059, .action = VIA_DXS_NO_VRA }, /* ASRock K7VM2 */
+		{ .subvendor = 0x1005, .subdevice = 0x4710, .action = VIA_DXS_ENABLE }, /* Avance Logic Mobo */
+		{ .subvendor = 0x1019, .subdevice = 0x0996, .action = VIA_DXS_48K },
+		{ .subvendor = 0x1019, .subdevice = 0x0a81, .action = VIA_DXS_NO_VRA }, /* ECS K7VTA3 v8.0 */
+		{ .subvendor = 0x1019, .subdevice = 0x0a85, .action = VIA_DXS_NO_VRA }, /* ECS L7VMM2 */
+		{ .subvendor = 0x1025, .subdevice = 0x0033, .action = VIA_DXS_NO_VRA }, /* Acer Inspire 1353LM */
+		{ .subvendor = 0x1043, .subdevice = 0x8095, .action = VIA_DXS_NO_VRA }, /* ASUS A7V8X (FIXME: possibly VIA_DXS_ENABLE?)*/
+		{ .subvendor = 0x1043, .subdevice = 0x80a1, .action = VIA_DXS_NO_VRA }, /* ASUS A7V8-X */
+		{ .subvendor = 0x1043, .subdevice = 0x80b0, .action = VIA_DXS_NO_VRA }, /* ASUS A7V600 & K8V*/ 
+		{ .subvendor = 0x1043, .subdevice = 0x812a, .action = VIA_DXS_SRC    }, /* ASUS A8V Deluxe */ 
+		{ .subvendor = 0x1071, .subdevice = 0x8375, .action = VIA_DXS_NO_VRA }, /* Vobis/Yakumo/Mitac notebook */
+		{ .subvendor = 0x1071, .subdevice = 0x8399, .action = VIA_DXS_NO_VRA }, /* Umax AB 595T (VIA K8N800A - VT8237) */
+		{ .subvendor = 0x10cf, .subdevice = 0x118e, .action = VIA_DXS_ENABLE }, /* FSC laptop */
+		{ .subvendor = 0x1106, .subdevice = 0x4161, .action = VIA_DXS_NO_VRA }, /* ASRock K7VT2 */
+		{ .subvendor = 0x1106, .subdevice = 0x4552, .action = VIA_DXS_NO_VRA }, /* QDI Kudoz 7X/600-6AL */
+		{ .subvendor = 0x1106, .subdevice = 0xaa01, .action = VIA_DXS_NO_VRA }, /* EPIA MII */
+		{ .subvendor = 0x1106, .subdevice = 0xc001, .action = VIA_DXS_SRC }, /* Insight P4-ITX */
+		{ .subvendor = 0x1297, .subdevice = 0xa232, .action = VIA_DXS_ENABLE }, /* Shuttle ?? */
+		{ .subvendor = 0x1297, .subdevice = 0xc160, .action = VIA_DXS_ENABLE }, /* Shuttle SK41G */
+		{ .subvendor = 0x1458, .subdevice = 0xa002, .action = VIA_DXS_ENABLE }, /* Gigabyte GA-7VAXP */
+		{ .subvendor = 0x1462, .subdevice = 0x0080, .action = VIA_DXS_SRC }, /* MSI K8T Neo-FIS2R */
+		{ .subvendor = 0x1462, .subdevice = 0x3800, .action = VIA_DXS_ENABLE }, /* MSI KT266 */
+		{ .subvendor = 0x1462, .subdevice = 0x5901, .action = VIA_DXS_NO_VRA }, /* MSI KT6 Delta-SR */
+		{ .subvendor = 0x1462, .subdevice = 0x7023, .action = VIA_DXS_NO_VRA }, /* MSI K8T Neo2-FI */
+		{ .subvendor = 0x1462, .subdevice = 0x7120, .action = VIA_DXS_ENABLE }, /* MSI KT4V */
+		{ .subvendor = 0x147b, .subdevice = 0x1401, .action = VIA_DXS_ENABLE }, /* ABIT KD7(-RAID) */
+		{ .subvendor = 0x147b, .subdevice = 0x1411, .action = VIA_DXS_ENABLE }, /* ABIT VA-20 */
+		{ .subvendor = 0x147b, .subdevice = 0x1413, .action = VIA_DXS_ENABLE }, /* ABIT KV8 Pro */
+		{ .subvendor = 0x147b, .subdevice = 0x1415, .action = VIA_DXS_NO_VRA }, /* Abit AV8 */
+		{ .subvendor = 0x14ff, .subdevice = 0x0403, .action = VIA_DXS_ENABLE }, /* Twinhead mobo */
+		{ .subvendor = 0x14ff, .subdevice = 0x0408, .action = VIA_DXS_SRC }, /* Twinhead laptop */
+		{ .subvendor = 0x1584, .subdevice = 0x8120, .action = VIA_DXS_ENABLE }, /* Gericom/Targa/Vobis/Uniwill laptop */
+		{ .subvendor = 0x1584, .subdevice = 0x8123, .action = VIA_DXS_NO_VRA }, /* Uniwill (Targa Visionary XP-210) */
+		{ .subvendor = 0x161f, .subdevice = 0x202b, .action = VIA_DXS_NO_VRA }, /* Amira Note book */
+		{ .subvendor = 0x161f, .subdevice = 0x2032, .action = VIA_DXS_48K }, /* m680x machines */
+		{ .subvendor = 0x1631, .subdevice = 0xe004, .action = VIA_DXS_ENABLE }, /* Easy Note 3174, Packard Bell */
+		{ .subvendor = 0x1695, .subdevice = 0x3005, .action = VIA_DXS_ENABLE }, /* EPoX EP-8K9A */
+		{ .subvendor = 0x1849, .subdevice = 0x3059, .action = VIA_DXS_NO_VRA }, /* ASRock K7VM2 */
+		{ .subvendor = 0x1919, .subdevice = 0x200a, .action = VIA_DXS_NO_VRA }, /* Soltek SL-K8Tpro-939 */
+		{ .subvendor = 0x4005, .subdevice = 0x4710, .action = VIA_DXS_SRC },	/* MSI K7T266 Pro2 (MS-6380 V2.0) BIOS 3.7 */
 		{ } /* terminator */
 	};
 	struct dxs_whitelist *w;
@@ -2182,14 +2196,14 @@ static int __devinit check_dxs_list(stru
 	pci_read_config_word(pci, PCI_SUBSYSTEM_VENDOR_ID, &subsystem_vendor);
 	pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &subsystem_device);
 
-	for (w = whitelist; w->vendor; w++) {
-		if (w->vendor != subsystem_vendor)
+	for (w = whitelist; w->subvendor; w++) {
+		if (w->subvendor != subsystem_vendor)
 			continue;
 		if (w->mask) {
-			if ((w->mask & subsystem_device) == w->device)
+			if ((w->mask & subsystem_device) == w->subdevice)
 				return w->action;
 		} else {
-			if (subsystem_device == w->device)
+			if (subsystem_device == w->subdevice)
 				return w->action;
 		}
 	}
@@ -2198,8 +2212,9 @@ static int __devinit check_dxs_list(stru
 	 * not detected, try 48k rate only to be sure.
 	 */
 	printk(KERN_INFO "via82xx: Assuming DXS channels with 48k fixed sample rate.\n");
-	printk(KERN_INFO "         Please try dxs_support=1 or dxs_support=4 option\n");
+	printk(KERN_INFO "         Please try dxs_support=5 option\n");
 	printk(KERN_INFO "         and report if it works on your machine.\n");
+	printk(KERN_INFO "         For more details, read ALSA-Configuration.txt.\n");
 	return VIA_DXS_48K;
 };
 
@@ -2288,6 +2303,10 @@ static int __devinit snd_via82xx_probe(s
 				chip->dxs_fixed = 1;
 			else if (dxs_support[dev] == VIA_DXS_NO_VRA)
 				chip->no_vra = 1;
+			else if (dxs_support[dev] == VIA_DXS_SRC) {
+				chip->no_vra = 1;
+				chip->dxs_src = 1;
+			}
 		}
 		if ((err = snd_via8233_init_misc(chip, dev)) < 0)
 			goto __error;
@@ -2334,7 +2353,7 @@ static struct pci_driver driver = {
 
 static int __init alsa_card_via82xx_init(void)
 {
-	return pci_module_init(&driver);
+	return pci_register_driver(&driver);
 }
 
 static void __exit alsa_card_via82xx_exit(void)
diff --git a/sound/pci/via82xx_modem.c b/sound/pci/via82xx_modem.c
--- a/sound/pci/via82xx_modem.c
+++ b/sound/pci/via82xx_modem.c
@@ -352,10 +352,8 @@ static int clean_via_table(viadev_t *dev
 		snd_dma_free_pages(&dev->table);
 		dev->table.area = NULL;
 	}
-	if (dev->idx_table) {
-		kfree(dev->idx_table);
-		dev->idx_table = NULL;
-	}
+	kfree(dev->idx_table);
+	dev->idx_table = NULL;
 	return 0;
 }
 
@@ -410,8 +408,7 @@ static void snd_via82xx_codec_wait(ac97_
 	int err;
 	err = snd_via82xx_codec_ready(chip, ac97->num);
 	/* here we need to wait fairly for long time.. */
-	set_current_state(TASK_UNINTERRUPTIBLE);
-	schedule_timeout(HZ/2);
+	msleep(500);
 }
 
 static void snd_via82xx_codec_write(ac97_t *ac97,
@@ -420,7 +417,10 @@ static void snd_via82xx_codec_write(ac97
 {
 	via82xx_t *chip = ac97->private_data;
 	unsigned int xval;
-	
+	if(reg == AC97_GPIO_STATUS) {
+		outl(val, VIAREG(chip, GPI_STATUS));
+		return;
+	}	
 	xval = !ac97->num ? VIA_REG_AC97_CODEC_ID_PRIMARY : VIA_REG_AC97_CODEC_ID_SECONDARY;
 	xval <<= VIA_REG_AC97_CODEC_ID_SHIFT;
 	xval |= reg << VIA_REG_AC97_CMD_SHIFT;
@@ -544,25 +544,6 @@ static int snd_via82xx_pcm_trigger(snd_p
 	return 0;
 }
 
-static int snd_via82xx_modem_pcm_trigger(snd_pcm_substream_t * substream, int cmd)
-{
-	via82xx_t *chip = snd_pcm_substream_chip(substream);
-	unsigned int val = 0;
-	switch (cmd) {
-	case SNDRV_PCM_TRIGGER_START:
-		val = snd_ac97_read(chip->ac97, AC97_GPIO_STATUS);
-		outl(val|AC97_GPIO_LINE1_OH, VIAREG(chip, GPI_STATUS));
-		break;
-	case SNDRV_PCM_TRIGGER_STOP:
-		val = snd_ac97_read(chip->ac97, AC97_GPIO_STATUS);
-		outl(val&~AC97_GPIO_LINE1_OH, VIAREG(chip, GPI_STATUS));
-		break;
-	default:
-		break;
-	}
-	return snd_via82xx_pcm_trigger(substream, cmd);
-}
-
 /*
  * pointer callbacks
  */
@@ -806,7 +787,7 @@ static snd_pcm_ops_t snd_via686_playback
 	.hw_params =	snd_via82xx_hw_params,
 	.hw_free =	snd_via82xx_hw_free,
 	.prepare =	snd_via82xx_pcm_prepare,
-	.trigger =	snd_via82xx_modem_pcm_trigger,
+	.trigger =	snd_via82xx_pcm_trigger,
 	.pointer =	snd_via686_pcm_pointer,
 	.page =		snd_pcm_sgbuf_ops_page,
 };
@@ -819,7 +800,7 @@ static snd_pcm_ops_t snd_via686_capture_
 	.hw_params =	snd_via82xx_hw_params,
 	.hw_free =	snd_via82xx_hw_free,
 	.prepare =	snd_via82xx_pcm_prepare,
-	.trigger =	snd_via82xx_modem_pcm_trigger,
+	.trigger =	snd_via82xx_pcm_trigger,
 	.pointer =	snd_via686_pcm_pointer,
 	.page =		snd_pcm_sgbuf_ops_page,
 };
@@ -938,10 +919,10 @@ static void __devinit snd_via82xx_proc_i
  *
  */
 
-static int __devinit snd_via82xx_chip_init(via82xx_t *chip)
+static int snd_via82xx_chip_init(via82xx_t *chip)
 {
 	unsigned int val;
-	int max_count;
+	unsigned long end_time;
 	unsigned char pval;
 
 	pci_read_config_byte(chip->pci, VIA_MC97_CTRL, &pval);
@@ -980,14 +961,14 @@ static int __devinit snd_via82xx_chip_in
 	}
 
 	/* wait until codec ready */
-	max_count = ((3 * HZ) / 4) + 1;
+	end_time = jiffies + msecs_to_jiffies(750);
 	do {
 		pci_read_config_byte(chip->pci, VIA_ACLINK_STAT, &pval);
 		if (pval & VIA_ACLINK_C00_READY) /* primary codec ready */
 			break;
 		set_current_state(TASK_UNINTERRUPTIBLE);
 		schedule_timeout(1);
-	} while (--max_count > 0);
+	} while (time_before(jiffies, end_time));
 
 	if ((val = snd_via82xx_codec_xread(chip)) & VIA_REG_AC97_BUSY)
 		snd_printk("AC'97 codec is not ready [0x%x]\n", val);
@@ -995,7 +976,7 @@ static int __devinit snd_via82xx_chip_in
 	snd_via82xx_codec_xwrite(chip, VIA_REG_AC97_READ |
 				 VIA_REG_AC97_SECONDARY_VALID |
 				 (VIA_REG_AC97_CODEC_ID_SECONDARY << VIA_REG_AC97_CODEC_ID_SHIFT));
-	max_count = ((3 * HZ) / 4) + 1;
+	end_time = jiffies + msecs_to_jiffies(750);
 	snd_via82xx_codec_xwrite(chip, VIA_REG_AC97_READ |
 				 VIA_REG_AC97_SECONDARY_VALID |
 				 (VIA_REG_AC97_CODEC_ID_SECONDARY << VIA_REG_AC97_CODEC_ID_SHIFT));
@@ -1006,7 +987,7 @@ static int __devinit snd_via82xx_chip_in
 		}
 		set_current_state(TASK_INTERRUPTIBLE);
 		schedule_timeout(1);
-	} while (--max_count > 0);
+	} while (time_before(jiffies, end_time));
 	/* This is ok, the most of motherboards have only one codec */
 
       __ac97_ok2:
@@ -1233,7 +1214,7 @@ static struct pci_driver driver = {
 
 static int __init alsa_card_via82xx_init(void)
 {
-	return pci_module_init(&driver);
+	return pci_register_driver(&driver);
 }
 
 static void __exit alsa_card_via82xx_exit(void)
diff --git a/sound/pci/vx222/vx222.c b/sound/pci/vx222/vx222.c
--- a/sound/pci/vx222/vx222.c
+++ b/sound/pci/vx222/vx222.c
@@ -260,7 +260,7 @@ static struct pci_driver driver = {
 
 static int __init alsa_card_vx222_init(void)
 {
-	return pci_module_init(&driver);
+	return pci_register_driver(&driver);
 }
 
 static void __exit alsa_card_vx222_exit(void)
diff --git a/sound/pci/vx222/vx222_ops.c b/sound/pci/vx222/vx222_ops.c
--- a/sound/pci/vx222/vx222_ops.c
+++ b/sound/pci/vx222/vx222_ops.c
@@ -82,7 +82,7 @@ static int vx2_reg_index[VX_REG_MAX] = {
 	[VX_GPIOC]	= 0,	/* on the PLX */
 };
 
-inline static unsigned long vx2_reg_addr(vx_core_t *_chip, int reg)
+static inline unsigned long vx2_reg_addr(vx_core_t *_chip, int reg)
 {
 	struct snd_vx222 *chip = (struct snd_vx222 *)_chip;
 	return chip->port[vx2_reg_index[reg]] + vx2_reg_offset[reg];
@@ -235,7 +235,7 @@ static void vx2_setup_pseudo_dma(vx_core
 /*
  * vx_release_pseudo_dma - disable the pseudo-DMA mode
  */
-inline static void vx2_release_pseudo_dma(vx_core_t *chip)
+static inline void vx2_release_pseudo_dma(vx_core_t *chip)
 {
 	/* HREQ pin disabled. */
 	vx_outl(chip, ICR, 0);
diff --git a/sound/pci/ymfpci/ymfpci.c b/sound/pci/ymfpci/ymfpci.c
--- a/sound/pci/ymfpci/ymfpci.c
+++ b/sound/pci/ymfpci/ymfpci.c
@@ -360,7 +360,7 @@ static struct pci_driver driver = {
 
 static int __init alsa_card_ymfpci_init(void)
 {
-	return pci_module_init(&driver);
+	return pci_register_driver(&driver);
 }
 
 static void __exit alsa_card_ymfpci_exit(void)
diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c
--- a/sound/pci/ymfpci/ymfpci_main.c
+++ b/sound/pci/ymfpci/ymfpci_main.c
@@ -84,16 +84,16 @@ static inline void snd_ymfpci_writel(ymf
 
 static int snd_ymfpci_codec_ready(ymfpci_t *chip, int secondary)
 {
-	signed long end_time;
+	unsigned long end_time;
 	u32 reg = secondary ? YDSXGR_SECSTATUSADR : YDSXGR_PRISTATUSADR;
 	
-	end_time = (jiffies + ((3 * HZ) / 4)) + 1;
+	end_time = jiffies + msecs_to_jiffies(750);
 	do {
 		if ((snd_ymfpci_readw(chip, reg) & 0x8000) == 0)
 			return 0;
 		set_current_state(TASK_UNINTERRUPTIBLE);
 		schedule_timeout(1);
-	} while (end_time - (signed long)jiffies >= 0);
+	} while (time_before(jiffies, end_time));
 	snd_printk("codec_ready: codec %i is not ready [0x%x]\n", secondary, snd_ymfpci_readw(chip, reg));
 	return -EBUSY;
 }
@@ -829,9 +829,7 @@ static snd_pcm_hardware_t snd_ymfpci_cap
 
 static void snd_ymfpci_pcm_free_substream(snd_pcm_runtime_t *runtime)
 {
-	ymfpci_pcm_t *ypcm = runtime->private_data;
-	
-	kfree(ypcm);
+	kfree(runtime->private_data);
 }
 
 static int snd_ymfpci_playback_open_1(snd_pcm_substream_t * substream)
@@ -1421,17 +1419,15 @@ static snd_kcontrol_new_t snd_ymfpci_dre
 
 static int snd_ymfpci_info_single(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
 {
-	unsigned int mask = 1;
-
 	switch (kcontrol->private_value) {
 	case YDSXGR_SPDIFOUTCTRL: break;
 	case YDSXGR_SPDIFINCTRL: break;
 	default: return -EINVAL;
 	}
-	uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 1;
 	uinfo->value.integer.min = 0;
-	uinfo->value.integer.max = mask;
+	uinfo->value.integer.max = 1;
 	return 0;
 }
 
@@ -1439,7 +1435,7 @@ static int snd_ymfpci_get_single(snd_kco
 {
 	ymfpci_t *chip = snd_kcontrol_chip(kcontrol);
 	int reg = kcontrol->private_value;
-	unsigned int shift = 0, mask = 1, invert = 0;
+	unsigned int shift = 0, mask = 1;
 	
 	switch (kcontrol->private_value) {
 	case YDSXGR_SPDIFOUTCTRL: break;
@@ -1447,8 +1443,6 @@ static int snd_ymfpci_get_single(snd_kco
 	default: return -EINVAL;
 	}
 	ucontrol->value.integer.value[0] = (snd_ymfpci_readl(chip, reg) >> shift) & mask;
-	if (invert)
-		ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
 	return 0;
 }
 
@@ -1456,7 +1450,7 @@ static int snd_ymfpci_put_single(snd_kco
 {
 	ymfpci_t *chip = snd_kcontrol_chip(kcontrol);
 	int reg = kcontrol->private_value;
-	unsigned int shift = 0, mask = 1, invert = 0;
+	unsigned int shift = 0, mask = 1;
 	int change;
 	unsigned int val, oval;
 	
@@ -1466,8 +1460,6 @@ static int snd_ymfpci_put_single(snd_kco
 	default: return -EINVAL;
 	}
 	val = (ucontrol->value.integer.value[0] & mask);
-	if (invert)
-		val = mask - val;
 	val <<= shift;
 	spin_lock_irq(&chip->reg_lock);
 	oval = snd_ymfpci_readl(chip, reg);
@@ -1487,14 +1479,13 @@ static int snd_ymfpci_put_single(snd_kco
 static int snd_ymfpci_info_double(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
 {
 	unsigned int reg = kcontrol->private_value;
-	unsigned int mask = 16383;
 
 	if (reg < 0x80 || reg >= 0xc0)
 		return -EINVAL;
-	uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 2;
 	uinfo->value.integer.min = 0;
-	uinfo->value.integer.max = mask;
+	uinfo->value.integer.max = 16383;
 	return 0;
 }
 
@@ -1502,7 +1493,7 @@ static int snd_ymfpci_get_double(snd_kco
 {
 	ymfpci_t *chip = snd_kcontrol_chip(kcontrol);
 	unsigned int reg = kcontrol->private_value;
-	unsigned int shift_left = 0, shift_right = 16, mask = 16383, invert = 0;
+	unsigned int shift_left = 0, shift_right = 16, mask = 16383;
 	unsigned int val;
 	
 	if (reg < 0x80 || reg >= 0xc0)
@@ -1512,10 +1503,6 @@ static int snd_ymfpci_get_double(snd_kco
 	spin_unlock_irq(&chip->reg_lock);
 	ucontrol->value.integer.value[0] = (val >> shift_left) & mask;
 	ucontrol->value.integer.value[1] = (val >> shift_right) & mask;
-	if (invert) {
-		ucontrol->value.integer.value[0] = mask - ucontrol->value.integer.value[0];
-		ucontrol->value.integer.value[1] = mask - ucontrol->value.integer.value[1];
-	}
 	return 0;
 }
 
@@ -1523,7 +1510,7 @@ static int snd_ymfpci_put_double(snd_kco
 {
 	ymfpci_t *chip = snd_kcontrol_chip(kcontrol);
 	unsigned int reg = kcontrol->private_value;
-	unsigned int shift_left = 0, shift_right = 16, mask = 16383, invert = 0;
+	unsigned int shift_left = 0, shift_right = 16, mask = 16383;
 	int change;
 	unsigned int val1, val2, oval;
 	
@@ -1531,10 +1518,6 @@ static int snd_ymfpci_put_double(snd_kco
 		return -EINVAL;
 	val1 = ucontrol->value.integer.value[0] & mask;
 	val2 = ucontrol->value.integer.value[1] & mask;
-	if (invert) {
-		val1 = mask - val1;
-		val2 = mask - val2;
-	}
 	val1 <<= shift_left;
 	val2 <<= shift_right;
 	spin_lock_irq(&chip->reg_lock);
diff --git a/sound/pcmcia/Kconfig b/sound/pcmcia/Kconfig
--- a/sound/pcmcia/Kconfig
+++ b/sound/pcmcia/Kconfig
@@ -8,23 +8,12 @@ config SND_VXPOCKET
 	depends on SND && PCMCIA && ISA
 	select SND_VX_LIB
 	help
-	  Say Y here to include support for Digigram VXpocket
-	  soundcards.
+	  Say Y here to include support for Digigram VXpocket and
+	  VXpocket 440 soundcards.
 
 	  To compile this driver as a module, choose M here: the module
 	  will be called snd-vxpocket.
 
-config SND_VXP440
-	tristate "Digigram VXpocket 440"
-	depends on SND && PCMCIA && ISA
-	select SND_VX_LIB
-	help
-	  Say Y here to include support for Digigram VXpocket 440
-	  soundcards.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called snd-vxp440.
-
 config SND_PDAUDIOCF
 	tristate "Sound Core PDAudioCF"
 	depends on SND && PCMCIA && ISA
diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf.c b/sound/pcmcia/pdaudiocf/pdaudiocf.c
--- a/sound/pcmcia/pdaudiocf/pdaudiocf.c
+++ b/sound/pcmcia/pdaudiocf/pdaudiocf.c
@@ -22,7 +22,6 @@
 #include <sound/core.h>
 #include <linux/slab.h>
 #include <linux/moduleparam.h>
-#include <pcmcia/version.h>
 #include <pcmcia/ciscode.h>
 #include <pcmcia/cisreg.h>
 #include "pdaudiocf.h"
@@ -171,14 +170,6 @@ static dev_link_t *snd_pdacf_attach(void
 
 	/* Register with Card Services */
 	client_reg.dev_info = &dev_info;
-	client_reg.EventMask = 
-		CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL
-#ifdef CONFIG_PM
-		| CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET
-		| CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME
-#endif
-		;
-	client_reg.event_handler = &pdacf_event;
 	client_reg.Version = 0x0210;
 	client_reg.event_callback_args.client_data = link;
 
@@ -380,13 +371,21 @@ static int pdacf_event(event_t event, in
 /*
  * Module entry points
  */
+static struct pcmcia_device_id snd_pdacf_ids[] = {
+	PCMCIA_DEVICE_MANF_CARD(0x015d, 0x4c45),
+	PCMCIA_DEVICE_NULL
+};
+MODULE_DEVICE_TABLE(pcmcia, snd_pdacf_ids);
+
 static struct pcmcia_driver pdacf_cs_driver = {
-	.owner          = THIS_MODULE,
-	.drv            = {
-		.name   = "snd-pdaudiocf",
+	.owner		= THIS_MODULE,
+	.drv		= {
+		.name	= "snd-pdaudiocf",
 	},
-	.attach         = snd_pdacf_attach,
-	.detach         = snd_pdacf_detach
+	.attach		= snd_pdacf_attach,
+	.event		= pdacf_event,
+	.detach		= snd_pdacf_detach,
+	.id_table	= snd_pdacf_ids,
 };
 
 static int __init init_pdacf(void)
diff --git a/sound/pcmcia/vx/Makefile b/sound/pcmcia/vx/Makefile
--- a/sound/pcmcia/vx/Makefile
+++ b/sound/pcmcia/vx/Makefile
@@ -3,9 +3,6 @@
 # Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
 #
 
-snd-vx-cs-objs := vx_entry.o vxp_ops.o vxp_mixer.o
-snd-vxpocket-objs := vxpocket.o
-snd-vxp440-objs := vxp440.o
+snd-vxpocket-objs := vxpocket.o vxp_ops.o vxp_mixer.o
 
-obj-$(CONFIG_SND_VXPOCKET) += snd-vxpocket.o snd-vx-cs.o
-obj-$(CONFIG_SND_VXP440) += snd-vxp440.o snd-vx-cs.o
+obj-$(CONFIG_SND_VXPOCKET) += snd-vxpocket.o
diff --git a/sound/pcmcia/vx/vx_entry.c b/sound/pcmcia/vx/vx_entry.c
deleted file mode 100644
--- a/sound/pcmcia/vx/vx_entry.c
+++ /dev/null
@@ -1,384 +0,0 @@
-/*
- * Driver for Digigram VXpocket soundcards
- *
- * PCMCIA entry part
- *
- * Copyright (c) 2002 by Takashi Iwai <tiwai@suse.de>
- *
- *   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 <sound/driver.h>
-#include <sound/core.h>
-#include "vxpocket.h"
-#include <pcmcia/ciscode.h>
-#include <pcmcia/cisreg.h>
-
-
-MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>");
-MODULE_DESCRIPTION("Common routines for Digigram PCMCIA VX drivers");
-MODULE_LICENSE("GPL");
-
-/*
- * prototypes
- */
-static void vxpocket_config(dev_link_t *link);
-static int vxpocket_event(event_t event, int priority, event_callback_args_t *args);
-
-
-static void vxpocket_release(dev_link_t *link)
-{
-	if (link->state & DEV_CONFIG) {
-		/* release cs resources */
-		pcmcia_release_configuration(link->handle);
-		pcmcia_release_io(link->handle, &link->io);
-		pcmcia_release_irq(link->handle, &link->irq);
-		link->state &= ~DEV_CONFIG;
-	}
-}
-
-/*
- * destructor
- */
-static int snd_vxpocket_free(vx_core_t *chip)
-{
-	struct snd_vxpocket *vxp = (struct snd_vxpocket *)chip;
-	struct snd_vxp_entry *hw;
-	dev_link_t *link = &vxp->link;
-
-	vxpocket_release(link);
-
-	/* Break the link with Card Services */
-	if (link->handle)
-		pcmcia_deregister_client(link->handle);
-
-	hw = vxp->hw_entry;
-	if (hw)
-		hw->card_list[vxp->index] = NULL;
-	chip->card = NULL;
-	if (chip->dev)
-		kfree(chip->dev);
-
-	snd_vx_free_firmware(chip);
-	kfree(chip);
-	return 0;
-}
-
-static int snd_vxpocket_dev_free(snd_device_t *device)
-{
-	vx_core_t *chip = device->device_data;
-	return snd_vxpocket_free(chip);
-}
-
-/*
- * snd_vxpocket_attach - attach callback for cs
- * @hw: the hardware information
- */
-dev_link_t *snd_vxpocket_attach(struct snd_vxp_entry *hw)
-{
-	client_reg_t client_reg;	/* Register with cardmgr */
-	dev_link_t *link;		/* Info for cardmgr */
-	int i, ret;
-	vx_core_t *chip;
-	struct snd_vxpocket *vxp;
-	snd_card_t *card;
-	static snd_device_ops_t ops = {
-		.dev_free =	snd_vxpocket_dev_free,
-	};
-
-	snd_printdd(KERN_DEBUG "vxpocket_attach called\n");
-	/* find an empty slot from the card list */
-	for (i = 0; i < SNDRV_CARDS; i++) {
-		if (! hw->card_list[i])
-			break;
-	}
-	if (i >= SNDRV_CARDS) {
-		snd_printk(KERN_ERR "vxpocket: too many cards found\n");
-		return NULL;
-	}
-	if (! hw->enable_table[i])
-		return NULL; /* disabled explicitly */
-
-	/* ok, create a card instance */
-	card = snd_card_new(hw->index_table[i], hw->id_table[i], THIS_MODULE, 0);
-	if (card == NULL) {
-		snd_printk(KERN_ERR "vxpocket: cannot create a card instance\n");
-		return NULL;
-	}
-
-	chip = snd_vx_create(card, hw->hardware, hw->ops,
-			     sizeof(struct snd_vxpocket) - sizeof(vx_core_t));
-	if (! chip)
-		return NULL;
-
-#ifdef SND_VX_FW_LOADER
-	/* fake a device here since pcmcia doesn't give a valid device... */
-	chip->dev = kcalloc(1, sizeof(*chip->dev), GFP_KERNEL);
-	if (! chip->dev) {
-		snd_printk(KERN_ERR "vxp: can't malloc chip->dev\n");
-		kfree(chip);
-		snd_card_free(card);
-		return NULL;
-	}
-	device_initialize(chip->dev);
-	sprintf(chip->dev->bus_id, "vxpocket%d", i);
-#endif
-
-	if (snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops) < 0) {
-		kfree(chip);
-		snd_card_free(card);
-		return NULL;
-	}
-
-	vxp = (struct snd_vxpocket *)chip;
-	vxp->index = i;
-	vxp->hw_entry = hw;
-	chip->ibl.size = hw->ibl[i];
-	hw->card_list[i] = chip;
-
-	link = &vxp->link;
-	link->priv = chip;
-
-	link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
-	link->io.NumPorts1 = 16;
-
-	link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
-	// link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
-
-	link->irq.IRQInfo1 = IRQ_LEVEL_ID;
-	link->irq.Handler = &snd_vx_irq_handler;
-	link->irq.Instance = chip;
-
-	link->conf.Attributes = CONF_ENABLE_IRQ;
-	link->conf.Vcc = 50;
-	link->conf.IntType = INT_MEMORY_AND_IO;
-	link->conf.ConfigIndex = 1;
-	link->conf.Present = PRESENT_OPTION;
-
-	/* Register with Card Services */
-	memset(&client_reg, 0, sizeof(client_reg));
-	client_reg.dev_info = hw->dev_info;
-	client_reg.EventMask = 
-		CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL
-#ifdef CONFIG_PM
-		| CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET
-		| CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME
-#endif
-		;
-	client_reg.event_handler = &vxpocket_event;
-	client_reg.Version = 0x0210;
-	client_reg.event_callback_args.client_data = link;
-
-	ret = pcmcia_register_client(&link->handle, &client_reg);
-	if (ret != CS_SUCCESS) {
-		cs_error(link->handle, RegisterClient, ret);
-		snd_card_free(card);
-		return NULL;
-	}
-
-	/* Chain drivers */
-	link->next = hw->dev_list;
-	hw->dev_list = link;
-
-	/* snd_card_set_pm_callback(card, snd_vxpocket_suspend, snd_vxpocket_resume, chip); */
-
-	return link;
-}
-
-
-/**
- * snd_vxpocket_assign_resources - initialize the hardware and card instance.
- * @port: i/o port for the card
- * @irq: irq number for the card
- *
- * this function assigns the specified port and irq, boot the card,
- * create pcm and control instances, and initialize the rest hardware.
- *
- * returns 0 if successful, or a negative error code.
- */
-static int snd_vxpocket_assign_resources(vx_core_t *chip, int port, int irq)
-{
-	int err;
-	snd_card_t *card = chip->card;
-	struct snd_vxpocket *vxp = (struct snd_vxpocket *)chip;
-
-	snd_printdd(KERN_DEBUG "vxpocket assign resources: port = 0x%x, irq = %d\n", port, irq);
-	vxp->port = port;
-
-	sprintf(card->shortname, "Digigram %s", card->driver);
-	sprintf(card->longname, "%s at 0x%x, irq %i",
-		card->shortname, port, irq);
-
-	chip->irq = irq;
-
-	if ((err = snd_vx_setup_firmware(chip)) < 0)
-		return err;
-
-	return 0;
-}
-
-
-/*
- * snd_vxpocket_detach - detach callback for cs
- * @hw: the hardware information
- */
-void snd_vxpocket_detach(struct snd_vxp_entry *hw, dev_link_t *link)
-{
-	vx_core_t *chip;
-
-	if (! link)
-		return;
-
-	chip = link->priv;
-
-	snd_printdd(KERN_DEBUG "vxpocket_detach called\n");
-	/* Remove the interface data from the linked list */
-	if (hw) {
-		dev_link_t **linkp;
-		/* Locate device structure */
-		for (linkp = &hw->dev_list; *linkp; linkp = &(*linkp)->next)
-			if (*linkp == link) {
-				*linkp = link->next;
-				break;
-			}
-	}
-	chip->chip_status |= VX_STAT_IS_STALE; /* to be sure */
-	snd_card_disconnect(chip->card);
-	snd_card_free_in_thread(chip->card);
-}
-
-/*
- * configuration callback
- */
-
-#define CS_CHECK(fn, ret) \
-do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
-static void vxpocket_config(dev_link_t *link)
-{
-	client_handle_t handle = link->handle;
-	vx_core_t *chip = link->priv;
-	struct snd_vxpocket *vxp = (struct snd_vxpocket *)chip;
-	tuple_t tuple;
-	cisparse_t *parse = NULL;
-	u_short buf[32];
-	int last_fn, last_ret;
-
-	snd_printdd(KERN_DEBUG "vxpocket_config called\n");
-	parse = kmalloc(sizeof(*parse), GFP_KERNEL);
-	if (! parse) {
-		snd_printk(KERN_ERR "vx: cannot allocate\n");
-		return;
-	}
-	tuple.Attributes = 0;
-	tuple.TupleData = (cisdata_t *)buf;
-	tuple.TupleDataMax = sizeof(buf);
-	tuple.TupleOffset = 0;
-	tuple.DesiredTuple = CISTPL_CONFIG;
-	CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
-	CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
-	CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, parse));
-	link->conf.ConfigBase = parse->config.base;
-	link->conf.Present = parse->config.rmask[0];
-
-	/* Configure card */
-	link->state |= DEV_CONFIG;
-
-	CS_CHECK(RequestIO, pcmcia_request_io(handle, &link->io));
-	CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq));
-	CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf));
-
-	if (snd_vxpocket_assign_resources(chip, link->io.BasePort1, link->irq.AssignedIRQ) < 0)
-		goto failed;
-
-	link->dev = &vxp->node;
-	link->state &= ~DEV_CONFIG_PENDING;
-	kfree(parse);
-	return;
-
-cs_failed:
-	cs_error(link->handle, last_fn, last_ret);
-failed:
-	pcmcia_release_configuration(link->handle);
-	pcmcia_release_io(link->handle, &link->io);
-	pcmcia_release_irq(link->handle, &link->irq);
-	link->state &= ~DEV_CONFIG;
-	kfree(parse);
-}
-
-
-/*
- * event callback
- */
-static int vxpocket_event(event_t event, int priority, event_callback_args_t *args)
-{
-	dev_link_t *link = args->client_data;
-	vx_core_t *chip = link->priv;
-
-	switch (event) {
-	case CS_EVENT_CARD_REMOVAL:
-		snd_printdd(KERN_DEBUG "CARD_REMOVAL..\n");
-		link->state &= ~DEV_PRESENT;
-		if (link->state & DEV_CONFIG) {
-			chip->chip_status |= VX_STAT_IS_STALE;
-		}
-		break;
-	case CS_EVENT_CARD_INSERTION:
-		snd_printdd(KERN_DEBUG "CARD_INSERTION..\n");
-		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-		vxpocket_config(link);
-		break;
-#ifdef CONFIG_PM
-	case CS_EVENT_PM_SUSPEND:
-		snd_printdd(KERN_DEBUG "SUSPEND\n");
-		link->state |= DEV_SUSPEND;
-		if (chip && chip->card->pm_suspend) {
-			snd_printdd(KERN_DEBUG "snd_vx_suspend calling\n");
-			chip->card->pm_suspend(chip->card, PMSG_SUSPEND);
-		}
-		/* Fall through... */
-	case CS_EVENT_RESET_PHYSICAL:
-		snd_printdd(KERN_DEBUG "RESET_PHYSICAL\n");
-		if (link->state & DEV_CONFIG)
-			pcmcia_release_configuration(link->handle);
-		break;
-	case CS_EVENT_PM_RESUME:
-		snd_printdd(KERN_DEBUG "RESUME\n");
-		link->state &= ~DEV_SUSPEND;
-		/* Fall through... */
-	case CS_EVENT_CARD_RESET:
-		snd_printdd(KERN_DEBUG "CARD_RESET\n");
-		if (DEV_OK(link)) {
-			//struct snd_vxpocket *vxp = (struct snd_vxpocket *)chip;
-			snd_printdd(KERN_DEBUG "requestconfig...\n");
-			pcmcia_request_configuration(link->handle, &link->conf);
-			if (chip && chip->card->pm_resume) {
-				snd_printdd(KERN_DEBUG "calling snd_vx_resume\n");
-				chip->card->pm_resume(chip->card);
-			}
-		}
-		snd_printdd(KERN_DEBUG "resume done!\n");
-		break;
-#endif
-	}
-	return 0;
-}
-
-/*
- * exported stuffs
- */
-EXPORT_SYMBOL(snd_vxpocket_ops);
-EXPORT_SYMBOL(snd_vxpocket_attach);
-EXPORT_SYMBOL(snd_vxpocket_detach);
diff --git a/sound/pcmcia/vx/vxp440.c b/sound/pcmcia/vx/vxp440.c
deleted file mode 100644
--- a/sound/pcmcia/vx/vxp440.c
+++ /dev/null
@@ -1,14 +0,0 @@
-#define COMPILE_VXP440
-
-/*
- add the following as /etc/pcmcia/vxp440.conf:
-
-  device "snd-vxp440"
-    class "audio" module "snd-vxp440"
-
-  card "Digigram VX-POCKET440"
-    manfid 0x01f1, 0x0100
-    bind "snd-vxp440"
-*/
-
-#include "vxpocket.c"
diff --git a/sound/pcmcia/vx/vxp_ops.c b/sound/pcmcia/vx/vxp_ops.c
--- a/sound/pcmcia/vx/vxp_ops.c
+++ b/sound/pcmcia/vx/vxp_ops.c
@@ -49,7 +49,7 @@ static int vxp_reg_offset[VX_REG_MAX] = 
 };
 
 
-inline static unsigned long vxp_reg_addr(vx_core_t *_chip, int reg)
+static inline unsigned long vxp_reg_addr(vx_core_t *_chip, int reg)
 {
 	struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip;
 	return chip->port + vxp_reg_offset[reg];
diff --git a/sound/pcmcia/vx/vxpocket.c b/sound/pcmcia/vx/vxpocket.c
--- a/sound/pcmcia/vx/vxpocket.c
+++ b/sound/pcmcia/vx/vxpocket.c
@@ -18,39 +18,23 @@
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  */
 
-/*
- please add the following as /etc/pcmcia/vxpocket.conf:
- 
-  device "snd-vxpocket"
-     class "audio" module "snd-vxpocket"
-
-  card "Digigram VX-POCKET"
-    manfid 0x01f1, 0x0100
-    bind "snd-vxpocket"
-
- */
 
 #include <sound/driver.h>
 #include <linux/init.h>
 #include <linux/moduleparam.h>
 #include <sound/core.h>
-#include <pcmcia/version.h>
 #include "vxpocket.h"
+#include <pcmcia/ciscode.h>
+#include <pcmcia/cisreg.h>
 #include <sound/initval.h>
 
 /*
  */
 
-#ifdef COMPILE_VXP440
-#define CARD_NAME	"VXPocket440"
-#else
-#define CARD_NAME	"VXPocket"
-#endif
-
 MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>");
-MODULE_DESCRIPTION("Digigram " CARD_NAME);
+MODULE_DESCRIPTION("Digigram VXPocket");
 MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{Digigram," CARD_NAME "}}");
+MODULE_SUPPORTED_DEVICE("{{Digigram,VXPocket},{Digigram,VXPocket440}}");
 
 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;	/* Index 0-MAX */
 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	/* ID for this card */
@@ -58,95 +42,425 @@ static int enable[SNDRV_CARDS] = SNDRV_D
 static int ibl[SNDRV_CARDS];
 
 module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard.");
+MODULE_PARM_DESC(index, "Index value for VXPocket soundcard.");
 module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for " CARD_NAME " soundcard.");
+MODULE_PARM_DESC(id, "ID string for VXPocket soundcard.");
 module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable " CARD_NAME " soundcard.");
+MODULE_PARM_DESC(enable, "Enable VXPocket soundcard.");
 module_param_array(ibl, int, NULL, 0444);
-MODULE_PARM_DESC(ibl, "Capture IBL size for " CARD_NAME " soundcard.");
+MODULE_PARM_DESC(ibl, "Capture IBL size for VXPocket soundcard.");
  
 
 /*
  */
 
-#ifdef COMPILE_VXP440
+static unsigned int card_alloc;
+static dev_link_t *dev_list;		/* Linked list of devices */
+static dev_info_t dev_info = "snd-vxpocket";
 
-/* 1 DSP, 1 sync UER, 1 sync World Clock (NIY) */
-/* SMPTE (NIY) */
-/* 2 stereo analog input (line/micro) */
-/* 2 stereo analog output */
-/* Only output levels can be modified */
-/* UER, but only for the first two inputs and outputs. */
-
-#define NUM_CODECS	2
-#define CARD_TYPE	VX_TYPE_VXP440
-#define DEV_INFO	"snd-vxp440"
-
-#else
-
-/* 1 DSP, 1 sync UER */
-/* 1 programmable clock (NIY) */
-/* 1 stereo analog input (line/micro) */
-/* 1 stereo analog output */
-/* Only output levels can be modified */
-
-#define NUM_CODECS	1
-#define CARD_TYPE	VX_TYPE_VXPOCKET
-#define DEV_INFO	"snd-vxpocket"
 
-#endif
+static int vxpocket_event(event_t event, int priority, event_callback_args_t *args);
+
 
-static dev_info_t dev_info = DEV_INFO;
+/*
+ */
+static void vxpocket_release(dev_link_t *link)
+{
+	if (link->state & DEV_CONFIG) {
+		/* release cs resources */
+		pcmcia_release_configuration(link->handle);
+		pcmcia_release_io(link->handle, &link->io);
+		pcmcia_release_irq(link->handle, &link->irq);
+		link->state &= ~DEV_CONFIG;
+	}
+	if (link->handle) {
+		/* Break the link with Card Services */
+		pcmcia_deregister_client(link->handle);
+		link->handle = NULL;
+	}
+}
 
-static struct snd_vx_hardware vxp_hw = {
-	.name = CARD_NAME,
-	.type = CARD_TYPE,
+/*
+ * destructor, called from snd_card_free_in_thread()
+ */
+static int snd_vxpocket_dev_free(snd_device_t *device)
+{
+	vx_core_t *chip = device->device_data;
+
+	snd_vx_free_firmware(chip);
+	kfree(chip);
+	return 0;
+}
+
+
+/*
+ * Hardware information
+ */
+
+/* VX-pocket V2
+ *
+ * 1 DSP, 1 sync UER
+ * 1 programmable clock (NIY)
+ * 1 stereo analog input (line/micro)
+ * 1 stereo analog output
+ * Only output levels can be modified
+ */
+
+static struct snd_vx_hardware vxpocket_hw = {
+	.name = "VXPocket",
+	.type = VX_TYPE_VXPOCKET,
 
 	/* hardware specs */
-	.num_codecs = NUM_CODECS,
-	.num_ins = NUM_CODECS,
-	.num_outs = NUM_CODECS,
+	.num_codecs = 1,
+	.num_ins = 1,
+	.num_outs = 1,
 	.output_level_max = VX_ANALOG_OUT_LEVEL_MAX,
 };	
 
-static struct snd_vxp_entry hw_entry = {
-	.dev_info = &dev_info,
+/* VX-pocket 440
+ *
+ * 1 DSP, 1 sync UER, 1 sync World Clock (NIY)
+ * SMPTE (NIY)
+ * 2 stereo analog input (line/micro)
+ * 2 stereo analog output
+ * Only output levels can be modified
+ * UER, but only for the first two inputs and outputs.
+ */
+
+static struct snd_vx_hardware vxp440_hw = {
+	.name = "VXPocket440",
+	.type = VX_TYPE_VXP440,
+
+	/* hardware specs */
+	.num_codecs = 2,
+	.num_ins = 2,
+	.num_outs = 2,
+	.output_level_max = VX_ANALOG_OUT_LEVEL_MAX,
+};	
+
+
+/*
+ * create vxpocket instance
+ */
+static struct snd_vxpocket *snd_vxpocket_new(snd_card_t *card, int ibl)
+{
+	client_reg_t client_reg;	/* Register with cardmgr */
+	dev_link_t *link;		/* Info for cardmgr */
+	vx_core_t *chip;
+	struct snd_vxpocket *vxp;
+	int ret;
+	static snd_device_ops_t ops = {
+		.dev_free =	snd_vxpocket_dev_free,
+	};
+
+	chip = snd_vx_create(card, &vxpocket_hw, &snd_vxpocket_ops,
+			     sizeof(struct snd_vxpocket) - sizeof(vx_core_t));
+	if (! chip)
+		return NULL;
+
+	if (snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops) < 0) {
+		kfree(chip);
+		return NULL;
+	}
+	chip->ibl.size = ibl;
+
+	vxp = (struct snd_vxpocket *)chip;
+
+	link = &vxp->link;
+	link->priv = chip;
+
+	link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+	link->io.NumPorts1 = 16;
+
+	link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
+
+	link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+	link->irq.Handler = &snd_vx_irq_handler;
+	link->irq.Instance = chip;
+
+	link->conf.Attributes = CONF_ENABLE_IRQ;
+	link->conf.Vcc = 50;
+	link->conf.IntType = INT_MEMORY_AND_IO;
+	link->conf.ConfigIndex = 1;
+	link->conf.Present = PRESENT_OPTION;
+
+	/* Register with Card Services */
+	memset(&client_reg, 0, sizeof(client_reg));
+	client_reg.dev_info = &dev_info;
+	client_reg.EventMask = 
+		CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL
+#ifdef CONFIG_PM
+		| CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET
+		| CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME
+#endif
+		;
+	client_reg.event_handler = &vxpocket_event;
+	client_reg.Version = 0x0210;
+	client_reg.event_callback_args.client_data = link;
+
+	ret = pcmcia_register_client(&link->handle, &client_reg);
+	if (ret != CS_SUCCESS) {
+		cs_error(link->handle, RegisterClient, ret);
+		return NULL;
+	}
+
+	return vxp;
+}
+
+
+/**
+ * snd_vxpocket_assign_resources - initialize the hardware and card instance.
+ * @port: i/o port for the card
+ * @irq: irq number for the card
+ *
+ * this function assigns the specified port and irq, boot the card,
+ * create pcm and control instances, and initialize the rest hardware.
+ *
+ * returns 0 if successful, or a negative error code.
+ */
+static int snd_vxpocket_assign_resources(vx_core_t *chip, int port, int irq)
+{
+	int err;
+	snd_card_t *card = chip->card;
+	struct snd_vxpocket *vxp = (struct snd_vxpocket *)chip;
+
+	snd_printdd(KERN_DEBUG "vxpocket assign resources: port = 0x%x, irq = %d\n", port, irq);
+	vxp->port = port;
+
+	sprintf(card->shortname, "Digigram %s", card->driver);
+	sprintf(card->longname, "%s at 0x%x, irq %i",
+		card->shortname, port, irq);
+
+	chip->irq = irq;
+
+	if ((err = snd_vx_setup_firmware(chip)) < 0)
+		return err;
+
+	return 0;
+}
+
+
+/*
+ * configuration callback
+ */
+
+#define CS_CHECK(fn, ret) \
+do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
+
+static void vxpocket_config(dev_link_t *link)
+{
+	client_handle_t handle = link->handle;
+	vx_core_t *chip = link->priv;
+	struct snd_vxpocket *vxp = (struct snd_vxpocket *)chip;
+	tuple_t tuple;
+	cisparse_t *parse;
+	u_short buf[32];
+	int last_fn, last_ret;
+
+	snd_printdd(KERN_DEBUG "vxpocket_config called\n");
+	parse = kmalloc(sizeof(*parse), GFP_KERNEL);
+	if (! parse) {
+		snd_printk(KERN_ERR "vx: cannot allocate\n");
+		return;
+	}
+	tuple.Attributes = 0;
+	tuple.TupleData = (cisdata_t *)buf;
+	tuple.TupleDataMax = sizeof(buf);
+	tuple.TupleOffset = 0;
+	tuple.DesiredTuple = CISTPL_CONFIG;
+	CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
+	CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
+	CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, parse));
+	link->conf.ConfigBase = parse->config.base;
+	link->conf.Present = parse->config.rmask[0];
+
+	/* redefine hardware record according to the VERSION1 string */
+	tuple.DesiredTuple = CISTPL_VERS_1;
+	CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
+	CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
+	CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, parse));
+	if (! strcmp(parse->version_1.str + parse->version_1.ofs[1], "VX-POCKET")) {
+		snd_printdd("VX-pocket is detected\n");
+	} else {
+		snd_printdd("VX-pocket 440 is detected\n");
+		/* overwrite the hardware information */
+		chip->hw = &vxp440_hw;
+		chip->type = vxp440_hw.type;
+		strcpy(chip->card->driver, vxp440_hw.name);
+	}
+
+	/* Configure card */
+	link->state |= DEV_CONFIG;
+
+	CS_CHECK(RequestIO, pcmcia_request_io(handle, &link->io));
+	CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq));
+	CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf));
+
+	chip->dev = &handle_to_dev(link->handle);
+
+	if (snd_vxpocket_assign_resources(chip, link->io.BasePort1, link->irq.AssignedIRQ) < 0)
+		goto failed;
+
+	link->dev = &vxp->node;
+	link->state &= ~DEV_CONFIG_PENDING;
+	kfree(parse);
+	return;
+
+cs_failed:
+	cs_error(link->handle, last_fn, last_ret);
+failed:
+	pcmcia_release_configuration(link->handle);
+	pcmcia_release_io(link->handle, &link->io);
+	pcmcia_release_irq(link->handle, &link->irq);
+	link->state &= ~DEV_CONFIG;
+	kfree(parse);
+}
+
+
+/*
+ * event callback
+ */
+static int vxpocket_event(event_t event, int priority, event_callback_args_t *args)
+{
+	dev_link_t *link = args->client_data;
+	vx_core_t *chip = link->priv;
+
+	switch (event) {
+	case CS_EVENT_CARD_REMOVAL:
+		snd_printdd(KERN_DEBUG "CARD_REMOVAL..\n");
+		link->state &= ~DEV_PRESENT;
+		if (link->state & DEV_CONFIG)
+			chip->chip_status |= VX_STAT_IS_STALE;
+		break;
+	case CS_EVENT_CARD_INSERTION:
+		snd_printdd(KERN_DEBUG "CARD_INSERTION..\n");
+		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+		vxpocket_config(link);
+		break;
+#ifdef CONFIG_PM
+	case CS_EVENT_PM_SUSPEND:
+		snd_printdd(KERN_DEBUG "SUSPEND\n");
+		link->state |= DEV_SUSPEND;
+		if (chip && chip->card->pm_suspend) {
+			snd_printdd(KERN_DEBUG "snd_vx_suspend calling\n");
+			chip->card->pm_suspend(chip->card, PMSG_SUSPEND);
+		}
+		/* Fall through... */
+	case CS_EVENT_RESET_PHYSICAL:
+		snd_printdd(KERN_DEBUG "RESET_PHYSICAL\n");
+		if (link->state & DEV_CONFIG)
+			pcmcia_release_configuration(link->handle);
+		break;
+	case CS_EVENT_PM_RESUME:
+		snd_printdd(KERN_DEBUG "RESUME\n");
+		link->state &= ~DEV_SUSPEND;
+		/* Fall through... */
+	case CS_EVENT_CARD_RESET:
+		snd_printdd(KERN_DEBUG "CARD_RESET\n");
+		if (DEV_OK(link)) {
+			//struct snd_vxpocket *vxp = (struct snd_vxpocket *)chip;
+			snd_printdd(KERN_DEBUG "requestconfig...\n");
+			pcmcia_request_configuration(link->handle, &link->conf);
+			if (chip && chip->card->pm_resume) {
+				snd_printdd(KERN_DEBUG "calling snd_vx_resume\n");
+				chip->card->pm_resume(chip->card);
+			}
+		}
+		snd_printdd(KERN_DEBUG "resume done!\n");
+		break;
+#endif
+	}
+	return 0;
+}
 
-	/* module parameters */
-	.index_table = index,
-	.id_table = id,
-	.enable_table = enable,
-	.ibl = ibl,
-
-	/* h/w config */
-	.hardware = &vxp_hw,
-	.ops = &snd_vxpocket_ops,
-};
 
 /*
  */
 static dev_link_t *vxp_attach(void)
 {
-	return snd_vxpocket_attach(&hw_entry);
+	snd_card_t *card;
+	struct snd_vxpocket *vxp;
+	int i;
+
+	/* find an empty slot from the card list */
+	for (i = 0; i < SNDRV_CARDS; i++) {
+		if (! card_alloc & (1 << i))
+			break;
+	}
+	if (i >= SNDRV_CARDS) {
+		snd_printk(KERN_ERR "vxpocket: too many cards found\n");
+		return NULL;
+	}
+	if (! enable[i])
+		return NULL; /* disabled explicitly */
+
+	/* ok, create a card instance */
+	card = snd_card_new(index[i], id[i], THIS_MODULE, 0);
+	if (card == NULL) {
+		snd_printk(KERN_ERR "vxpocket: cannot create a card instance\n");
+		return NULL;
+	}
+
+	vxp = snd_vxpocket_new(card, ibl[i]);
+	if (! vxp) {
+		snd_card_free(card);
+		return NULL;
+	}
+
+	vxp->index = index[i];
+	card_alloc |= 1 << i;
+
+	/* Chain drivers */
+	vxp->link.next = dev_list;
+	dev_list = &vxp->link;
+
+	return &vxp->link;
 }
 
 static void vxp_detach(dev_link_t *link)
 {
-	snd_vxpocket_detach(&hw_entry, link);
+	struct snd_vxpocket *vxp;
+	vx_core_t *chip;
+	dev_link_t **linkp;
+
+	if (! link)
+		return;
+
+	vxp = link->priv;
+	chip = (vx_core_t *)vxp;
+	card_alloc &= ~(1 << vxp->index);
+
+	/* Remove the interface data from the linked list */
+	for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
+		if (*linkp == link) {
+			*linkp = link->next;
+			break;
+		}
+
+	chip->chip_status |= VX_STAT_IS_STALE; /* to be sure */
+	snd_card_disconnect(chip->card);
+	vxpocket_release(link);
+	snd_card_free_in_thread(chip->card);
 }
 
 /*
  * Module entry points
  */
 
+static struct pcmcia_device_id vxp_ids[] = {
+	PCMCIA_DEVICE_MANF_CARD(0x01f1, 0x0100),
+	PCMCIA_DEVICE_NULL
+};
+MODULE_DEVICE_TABLE(pcmcia, vxp_ids);
+
 static struct pcmcia_driver vxp_cs_driver = {
 	.owner		= THIS_MODULE,
 	.drv		= {
-		.name	= DEV_INFO,
+		.name	= "snd-vxpocket",
 	},
 	.attach		= vxp_attach,
-	.detach		= vxp_detach
+	.detach		= vxp_detach,
+	.id_table	= vxp_ids,
 };
 
 static int __init init_vxpocket(void)
@@ -157,7 +471,7 @@ static int __init init_vxpocket(void)
 static void __exit exit_vxpocket(void)
 {
 	pcmcia_unregister_driver(&vxp_cs_driver);
-	BUG_ON(hw_entry.dev_list != NULL);
+	BUG_ON(dev_list != NULL);
 }
 
 module_init(init_vxpocket);
diff --git a/sound/pcmcia/vx/vxpocket.h b/sound/pcmcia/vx/vxpocket.h
--- a/sound/pcmcia/vx/vxpocket.h
+++ b/sound/pcmcia/vx/vxpocket.h
@@ -28,24 +28,6 @@
 #include <pcmcia/cistpl.h>
 #include <pcmcia/ds.h>
 
-struct snd_vxp_entry {
-	dev_info_t *dev_info;
-
-	/* module parameters */
-	int *index_table;
-	char **id_table;
-	int *enable_table;
-	int *ibl;
-
-	/* h/w config */
-	struct snd_vx_hardware *hardware;
-	struct snd_vx_ops *ops;
-
-	/* slots */
-	vx_core_t *card_list[SNDRV_CARDS];
-	dev_link_t *dev_list;		/* Linked list of devices */
-};
-
 struct snd_vxpocket {
 
 	vx_core_t core;
@@ -57,8 +39,7 @@ struct snd_vxpocket {
 	unsigned int regCDSP;	/* current CDSP register */
 	unsigned int regDIALOG;	/* current DIALOG register */
 
-	int index;
-	struct snd_vxp_entry *hw_entry;
+	int index;	/* card index */
 
 	/* pcmcia stuff */
 	dev_link_t link;
@@ -70,12 +51,6 @@ extern struct snd_vx_ops snd_vxpocket_op
 void vx_set_mic_boost(vx_core_t *chip, int boost);
 void vx_set_mic_level(vx_core_t *chip, int level);
 
-/*
- * pcmcia stuff
- */
-dev_link_t *snd_vxpocket_attach(struct snd_vxp_entry *hw);
-void snd_vxpocket_detach(struct snd_vxp_entry *hw, dev_link_t *link);
-
 int vxp_add_mic_controls(vx_core_t *chip);
 
 /* Constants used to access the CDSP register (0x08). */
diff --git a/sound/ppc/awacs.c b/sound/ppc/awacs.c
--- a/sound/ppc/awacs.c
+++ b/sound/ppc/awacs.c
@@ -90,7 +90,7 @@ snd_pmac_awacs_write_noreg(pmac_t *chip,
 	snd_pmac_awacs_write(chip, val | (reg << 12));
 }
 
-#ifdef CONFIG_PMAC_PBOOK
+#ifdef CONFIG_PM
 /* Recalibrate chip */
 static void screamer_recalibrate(pmac_t *chip)
 {
@@ -103,7 +103,7 @@ static void screamer_recalibrate(pmac_t 
 	snd_pmac_awacs_write_noreg(chip, 1, chip->awacs_reg[1]);
 	if (chip->manufacturer == 0x1)
 		/* delay for broken crystal part */
-		big_mdelay(750);
+		msleep(750);
 	snd_pmac_awacs_write_noreg(chip, 1,
 				   chip->awacs_reg[1] | MASK_RECALIBRATE | MASK_CMUTE | MASK_AMUTE);
 	snd_pmac_awacs_write_noreg(chip, 1, chip->awacs_reg[1]);
@@ -642,7 +642,7 @@ static void awacs_restore_all_regs(pmac_
 	}
 }
 
-#ifdef CONFIG_PMAC_PBOOK
+#ifdef CONFIG_PM
 static void snd_pmac_awacs_suspend(pmac_t *chip)
 {
 	snd_pmac_awacs_write_noreg(chip, 1, (chip->awacs_reg[1]
@@ -653,10 +653,10 @@ static void snd_pmac_awacs_resume(pmac_t
 {
 	if (machine_is_compatible("PowerBook3,1")
 	    || machine_is_compatible("PowerBook3,2")) {
-		big_mdelay(100);
+		msleep(100);
 		snd_pmac_awacs_write_reg(chip, 1,
 			chip->awacs_reg[1] & ~MASK_PAROUT);
-		big_mdelay(300);
+		msleep(300);
 	}
 
 	awacs_restore_all_regs(chip);
@@ -676,7 +676,7 @@ static void snd_pmac_awacs_resume(pmac_t
 	}
 #endif
 }
-#endif /* CONFIG_PMAC_PBOOK */
+#endif /* CONFIG_PM */
 
 #ifdef PMAC_SUPPORT_AUTOMUTE
 /*
@@ -883,7 +883,7 @@ snd_pmac_awacs_init(pmac_t *chip)
 	 * set lowlevel callbacks
 	 */
 	chip->set_format = snd_pmac_awacs_set_format;
-#ifdef CONFIG_PMAC_PBOOK
+#ifdef CONFIG_PM
 	chip->suspend = snd_pmac_awacs_suspend;
 	chip->resume = snd_pmac_awacs_resume;
 #endif
diff --git a/sound/ppc/burgundy.c b/sound/ppc/burgundy.c
--- a/sound/ppc/burgundy.c
+++ b/sound/ppc/burgundy.c
@@ -30,7 +30,7 @@
 
 
 /* Waits for busy flag to clear */
-inline static void
+static inline void
 snd_pmac_burgundy_busy_wait(pmac_t *chip)
 {
 	int timeout = 50;
@@ -40,7 +40,7 @@ snd_pmac_burgundy_busy_wait(pmac_t *chip
 		printk(KERN_DEBUG "burgundy_busy_wait: timeout\n");
 }
 
-inline static void
+static inline void
 snd_pmac_burgundy_extend_wait(pmac_t *chip)
 {
 	int timeout;
diff --git a/sound/ppc/daca.c b/sound/ppc/daca.c
--- a/sound/ppc/daca.c
+++ b/sound/ppc/daca.c
@@ -218,7 +218,7 @@ static snd_kcontrol_new_t daca_mixers[] 
 };
 
 
-#ifdef CONFIG_PMAC_PBOOK
+#ifdef CONFIG_PM
 static void daca_resume(pmac_t *chip)
 {
 	pmac_daca_t *mix = chip->mixer_data;
@@ -227,7 +227,7 @@ static void daca_resume(pmac_t *chip)
 				  mix->amp_on ? 0x05 : 0x04);
 	daca_set_volume(mix);
 }
-#endif /* CONFIG_PMAC_PBOOK */
+#endif /* CONFIG_PM */
 
 
 static void daca_cleanup(pmac_t *chip)
@@ -275,7 +275,7 @@ int __init snd_pmac_daca_init(pmac_t *ch
 			return err;
 	}
 
-#ifdef CONFIG_PMAC_PBOOK
+#ifdef CONFIG_PM
 	chip->resume = daca_resume;
 #endif
 
diff --git a/sound/ppc/pmac.c b/sound/ppc/pmac.c
--- a/sound/ppc/pmac.c
+++ b/sound/ppc/pmac.c
@@ -36,7 +36,7 @@
 #include <asm/pci-bridge.h>
 
 
-#if defined(CONFIG_PM) && defined(CONFIG_PMAC_PBOOK)
+#ifdef CONFIG_PM
 static int snd_pmac_register_sleep_notifier(pmac_t *chip);
 static int snd_pmac_unregister_sleep_notifier(pmac_t *chip);
 static int snd_pmac_suspend(snd_card_t *card, pm_message_t state);
@@ -153,7 +153,7 @@ static pmac_stream_t *snd_pmac_get_strea
 /*
  * wait while run status is on
  */
-inline static void
+static inline void
 snd_pmac_wait_ack(pmac_stream_t *rec)
 {
 	int timeout = 50000;
@@ -177,7 +177,7 @@ static void snd_pmac_pcm_set_format(pmac
 /*
  * stop the DMA transfer
  */
-inline static void snd_pmac_dma_stop(pmac_stream_t *rec)
+static inline void snd_pmac_dma_stop(pmac_stream_t *rec)
 {
 	out_le32(&rec->dma->control, (RUN|WAKE|FLUSH|PAUSE) << 16);
 	snd_pmac_wait_ack(rec);
@@ -186,7 +186,7 @@ inline static void snd_pmac_dma_stop(pma
 /*
  * set the command pointer address
  */
-inline static void snd_pmac_dma_set_command(pmac_stream_t *rec, pmac_dbdma_t *cmd)
+static inline void snd_pmac_dma_set_command(pmac_stream_t *rec, pmac_dbdma_t *cmd)
 {
 	out_le32(&rec->dma->cmdptr, cmd->addr);
 }
@@ -194,7 +194,7 @@ inline static void snd_pmac_dma_set_comm
 /*
  * start the DMA
  */
-inline static void snd_pmac_dma_run(pmac_stream_t *rec, int status)
+static inline void snd_pmac_dma_run(pmac_stream_t *rec, int status)
 {
 	out_le32(&rec->dma->control, status | (status << 16));
 }
@@ -765,7 +765,8 @@ snd_pmac_ctrl_intr(int irq, void *devid,
  */
 static void snd_pmac_sound_feature(pmac_t *chip, int enable)
 {
-	ppc_md.feature_call(PMAC_FTR_SOUND_CHIP_ENABLE, chip->node, 0, enable);
+	if (ppc_md.feature_call)
+		ppc_md.feature_call(PMAC_FTR_SOUND_CHIP_ENABLE, chip->node, 0, enable);
 }
 
 /*
@@ -782,7 +783,7 @@ static int snd_pmac_free(pmac_t *chip)
 	}
 
 	snd_pmac_sound_feature(chip, 0);
-#if defined(CONFIG_PM) && defined(CONFIG_PMAC_PBOOK)
+#ifdef CONFIG_PM
 	snd_pmac_unregister_sleep_notifier(chip);
 #endif
 
@@ -1292,7 +1293,7 @@ int __init snd_pmac_new(snd_card_t *card
 	/* Reset dbdma channels */
 	snd_pmac_dbdma_reset(chip);
 
-#if defined(CONFIG_PM) && defined(CONFIG_PMAC_PBOOK)
+#ifdef CONFIG_PM
 	/* add sleep notifier */
 	if (! snd_pmac_register_sleep_notifier(chip))
 		snd_card_set_pm_callback(chip->card, snd_pmac_suspend, snd_pmac_resume, chip);
@@ -1316,7 +1317,7 @@ int __init snd_pmac_new(snd_card_t *card
  * sleep notify for powerbook
  */
 
-#if defined(CONFIG_PM) && defined(CONFIG_PMAC_PBOOK)
+#ifdef CONFIG_PM
 
 /*
  * Save state when going to sleep, restore it afterwards.
@@ -1414,4 +1415,5 @@ static int snd_pmac_unregister_sleep_not
 	return 0;
 }
 
-#endif /* CONFIG_PM && CONFIG_PMAC_PBOOK */
+#endif /* CONFIG_PM */
+
diff --git a/sound/ppc/pmac.h b/sound/ppc/pmac.h
--- a/sound/ppc/pmac.h
+++ b/sound/ppc/pmac.h
@@ -167,7 +167,7 @@ struct snd_pmac {
 	void (*set_format)(pmac_t *chip);
 	void (*update_automute)(pmac_t *chip, int do_notify);
 	int (*detect_headphone)(pmac_t *chip);
-#ifdef CONFIG_PMAC_PBOOK
+#ifdef CONFIG_PM
 	void (*suspend)(pmac_t *chip);
 	void (*resume)(pmac_t *chip);
 #endif
@@ -212,9 +212,4 @@ int snd_pmac_boolean_mono_info(snd_kcont
 
 int snd_pmac_add_automute(pmac_t *chip);
 
-#define big_mdelay(msec) do {\
-	set_current_state(TASK_UNINTERRUPTIBLE);\
-	schedule_timeout(((msec) * HZ + 999) / 1000);\
-} while (0)
-
 #endif /* __PMAC_H */
diff --git a/sound/ppc/tumbler.c b/sound/ppc/tumbler.c
--- a/sound/ppc/tumbler.c
+++ b/sound/ppc/tumbler.c
@@ -945,7 +945,7 @@ static void device_change_handler(void *
 			check_mute(chip, &mix->line_mute, 0, mix->auto_mute_notify,
 				   chip->lineout_sw_ctl);
 		if (mix->anded_reset)
-			big_mdelay(10);
+			msleep(10);
 		check_mute(chip, &mix->amp_mute, 1, mix->auto_mute_notify,
 			   chip->speaker_sw_ctl);
 		mix->drc_enable = 0;
@@ -954,7 +954,7 @@ static void device_change_handler(void *
 		check_mute(chip, &mix->amp_mute, 0, mix->auto_mute_notify,
 			   chip->speaker_sw_ctl);
 		if (mix->anded_reset)
-			big_mdelay(10);
+			msleep(10);
 		check_mute(chip, &mix->hp_mute, 1, mix->auto_mute_notify,
 			   chip->master_sw_ctl);
 		if (mix->line_mute.addr != 0)
@@ -1109,26 +1109,26 @@ static void tumbler_reset_audio(pmac_t *
 		DBG("(I) codec anded reset !\n");
 		write_audio_gpio(&mix->hp_mute, 0);
 		write_audio_gpio(&mix->amp_mute, 0);
-		big_mdelay(200);
+		msleep(200);
 		write_audio_gpio(&mix->hp_mute, 1);
 		write_audio_gpio(&mix->amp_mute, 1);
-		big_mdelay(100);
+		msleep(100);
 		write_audio_gpio(&mix->hp_mute, 0);
 		write_audio_gpio(&mix->amp_mute, 0);
-		big_mdelay(100);
+		msleep(100);
 	} else {
 		DBG("(I) codec normal reset !\n");
 
 		write_audio_gpio(&mix->audio_reset, 0);
-		big_mdelay(200);
+		msleep(200);
 		write_audio_gpio(&mix->audio_reset, 1);
-		big_mdelay(100);
+		msleep(100);
 		write_audio_gpio(&mix->audio_reset, 0);
-		big_mdelay(100);
+		msleep(100);
 	}
 }
 
-#ifdef CONFIG_PMAC_PBOOK
+#ifdef CONFIG_PM
 /* suspend mixer */
 static void tumbler_suspend(pmac_t *chip)
 {
@@ -1370,7 +1370,7 @@ int __init snd_pmac_tumbler_init(pmac_t 
 	if ((err = snd_ctl_add(chip->card, chip->drc_sw_ctl)) < 0)
 		return err;
 
-#ifdef CONFIG_PMAC_PBOOK
+#ifdef CONFIG_PM
 	chip->suspend = tumbler_suspend;
 	chip->resume = tumbler_resume;
 #endif
diff --git a/sound/sound_core.c b/sound/sound_core.c
--- a/sound/sound_core.c
+++ b/sound/sound_core.c
@@ -65,7 +65,7 @@ extern int msnd_classic_init(void);
 extern int msnd_pinnacle_init(void);
 #endif
 
-struct class_simple *sound_class;
+struct class *sound_class;
 EXPORT_SYMBOL(sound_class);
 
 /*
@@ -174,7 +174,7 @@ static int sound_insert_unit(struct soun
 
 	devfs_mk_cdev(MKDEV(SOUND_MAJOR, s->unit_minor),
 			S_IFCHR | mode, s->name);
-	class_simple_device_add(sound_class, MKDEV(SOUND_MAJOR, s->unit_minor),
+	class_device_create(sound_class, MKDEV(SOUND_MAJOR, s->unit_minor),
 				NULL, s->name+6);
 	return r;
 
@@ -198,7 +198,7 @@ static void sound_remove_unit(struct sou
 	spin_unlock(&sound_loader_lock);
 	if (p) {
 		devfs_remove(p->name);
-		class_simple_device_remove(MKDEV(SOUND_MAJOR, p->unit_minor));
+		class_device_destroy(sound_class, MKDEV(SOUND_MAJOR, p->unit_minor));
 		kfree(p);
 	}
 }
@@ -562,7 +562,7 @@ static void __exit cleanup_soundcore(voi
 	   empty */
 	unregister_chrdev(SOUND_MAJOR, "sound");
 	devfs_remove("sound");
-	class_simple_destroy(sound_class);
+	class_destroy(sound_class);
 }
 
 static int __init init_soundcore(void)
@@ -572,7 +572,7 @@ static int __init init_soundcore(void)
 		return -EBUSY;
 	}
 	devfs_mk_dir ("sound");
-	sound_class = class_simple_create(THIS_MODULE, "sound");
+	sound_class = class_create(THIS_MODULE, "sound");
 	if (IS_ERR(sound_class))
 		return PTR_ERR(sound_class);
 
diff --git a/sound/sparc/Kconfig b/sound/sparc/Kconfig
--- a/sound/sparc/Kconfig
+++ b/sound/sparc/Kconfig
@@ -7,12 +7,30 @@ config SND_SUN_AMD7930
 	tristate "Sun AMD7930"
 	depends on SBUS && SND
 	select SND_PCM
+	help
+	  Say Y here to include support for AMD7930 sound device on Sun.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-sun-amd7930.
 
-#  dep_tristate 'Sun DBRI' CONFIG_SND_SUN_DBRI $CONFIG_SND
 config SND_SUN_CS4231
 	tristate "Sun CS4231"
 	depends on SND
 	select SND_PCM
+	help
+	  Say Y here to include support for CS4231 sound device on Sun.
 
-endmenu
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-sun-cs4231.
+
+config SND_SUN_DBRI
+	tristate "Sun DBRI"
+	depends on SND && SBUS
+	select SND_PCM
+	help
+	  Say Y here to include support for DBRI sound device on Sun.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-sun-dbri.
 
+endmenu
diff --git a/sound/sparc/Makefile b/sound/sparc/Makefile
--- a/sound/sparc/Makefile
+++ b/sound/sparc/Makefile
@@ -4,9 +4,9 @@
 #
 
 snd-sun-amd7930-objs := amd7930.o
-#snd-sun-dbri-objs := dbri.o
 snd-sun-cs4231-objs := cs4231.o
+snd-sun-dbri-objs := dbri.o
 
 obj-$(CONFIG_SND_SUN_AMD7930) += snd-sun-amd7930.o
-#obj-$(CONFIG_SND_SUN_DBRI) += snd-sun-dbri.o
 obj-$(CONFIG_SND_SUN_CS4231) += snd-sun-cs4231.o
+obj-$(CONFIG_SND_SUN_DBRI) += snd-sun-dbri.o
diff --git a/sound/sparc/dbri.c b/sound/sparc/dbri.c
new file mode 100644
--- /dev/null
+++ b/sound/sparc/dbri.c
@@ -0,0 +1,2729 @@
+/*
+ * Driver for DBRI sound chip found on Sparcs.
+ * Copyright (C) 2004 Martin Habets (mhabets@users.sourceforge.net)
+ *
+ * Based entirely upon drivers/sbus/audio/dbri.c which is:
+ * Copyright (C) 1997 Rudolf Koenig (rfkoenig@immd4.informatik.uni-erlangen.de)
+ * Copyright (C) 1998, 1999 Brent Baccala (baccala@freesoft.org)
+ *
+ * This is the lowlevel driver for the DBRI & MMCODEC duo used for ISDN & AUDIO
+ * on Sun SPARCstation 10, 20, LX and Voyager models.
+ *
+ * - DBRI: AT&T T5900FX Dual Basic Rates ISDN Interface. It is a 32 channel
+ *   data time multiplexer with ISDN support (aka T7259)
+ *   Interfaces: SBus,ISDN NT & TE, CHI, 4 bits parallel.
+ *   CHI: (spelled ki) Concentration Highway Interface (AT&T or Intel bus ?).
+ *   Documentation:
+ *   - "STP 4000SBus Dual Basic Rate ISDN (DBRI) Tranceiver" from
+ *     Sparc Technology Business (courtesy of Sun Support)
+ *   - Data sheet of the T7903, a newer but very similar ISA bus equivalent
+ *     available from the Lucent (formarly AT&T microelectronics) home
+ *     page.
+ *   - http://www.freesoft.org/Linux/DBRI/
+ * - MMCODEC: Crystal Semiconductor CS4215 16 bit Multimedia Audio Codec
+ *   Interfaces: CHI, Audio In & Out, 2 bits parallel
+ *   Documentation: from the Crystal Semiconductor home page.
+ *
+ * The DBRI is a 32 pipe machine, each pipe can transfer some bits between
+ * memory and a serial device (long pipes, nr 0-15) or between two serial
+ * devices (short pipes, nr 16-31), or simply send a fixed data to a serial
+ * device (short pipes).
+ * A timeslot defines the bit-offset and nr of bits read from a serial device.
+ * The timeslots are linked to 6 circular lists, one for each direction for
+ * each serial device (NT,TE,CHI). A timeslot is associated to 1 or 2 pipes
+ * (the second one is a monitor/tee pipe, valid only for serial input).
+ *
+ * The mmcodec is connected via the CHI bus and needs the data & some
+ * parameters (volume, balance, output selection) timemultiplexed in 8 byte
+ * chunks. It also has a control mode, which serves for audio format setting.
+ *
+ * Looking at the CS4215 data sheet it is easy to set up 2 or 4 codecs on
+ * the same CHI bus, so I thought perhaps it is possible to use the onboard
+ * & the speakerbox codec simultanously, giving 2 (not very independent :-)
+ * audio devices. But the SUN HW group decided against it, at least on my
+ * LX the speakerbox connector has at least 1 pin missing and 1 wrongly
+ * connected.
+ */
+
+#include <sound/driver.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/info.h>
+#include <sound/control.h>
+#include <sound/initval.h>
+
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <asm/sbus.h>
+#include <asm/atomic.h>
+
+MODULE_AUTHOR("Rudolf Koenig, Brent Baccala and Martin Habets");
+MODULE_DESCRIPTION("Sun DBRI");
+MODULE_LICENSE("GPL");
+MODULE_SUPPORTED_DEVICE("{{Sun,DBRI}}");
+
+static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;	/* Index 0-MAX */
+static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	/* ID for this card */
+static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;	/* Enable this card */
+
+module_param_array(index, int, NULL, 0444);
+MODULE_PARM_DESC(index, "Index value for Sun DBRI soundcard.");
+module_param_array(id, charp, NULL, 0444);
+MODULE_PARM_DESC(id, "ID string for Sun DBRI soundcard.");
+module_param_array(enable, bool, NULL, 0444);
+MODULE_PARM_DESC(enable, "Enable Sun DBRI soundcard.");
+
+#define DBRI_DEBUG
+
+#define D_INT	(1<<0)
+#define D_GEN	(1<<1)
+#define D_CMD	(1<<2)
+#define D_MM	(1<<3)
+#define D_USR	(1<<4)
+#define D_DESC	(1<<5)
+
+static int dbri_debug = 0;
+module_param(dbri_debug, int, 0444);
+MODULE_PARM_DESC(dbri_debug, "Debug value for Sun DBRI soundcard.");
+
+#ifdef DBRI_DEBUG
+static char *cmds[] = {
+	"WAIT", "PAUSE", "JUMP", "IIQ", "REX", "SDP", "CDP", "DTS",
+	"SSP", "CHI", "NT", "TE", "CDEC", "TEST", "CDM", "RESRV"
+};
+
+#define dprintk(a, x...) if(dbri_debug & a) printk(KERN_DEBUG x)
+
+#define DBRI_CMD(cmd, intr, value) ((cmd << 28) |			\
+				    (1 << 27) | \
+				    value)
+#else
+#define dprintk(a, x...)
+
+#define DBRI_CMD(cmd, intr, value) ((cmd << 28) |			\
+				    (intr << 27) | \
+				    value)
+#endif				/* DBRI_DEBUG */
+
+/***************************************************************************
+	CS4215 specific definitions and structures
+****************************************************************************/
+
+struct cs4215 {
+	__u8 data[4];		/* Data mode: Time slots 5-8 */
+	__u8 ctrl[4];		/* Ctrl mode: Time slots 1-4 */
+	__u8 onboard;
+	__u8 offset;		/* Bit offset from frame sync to time slot 1 */
+	volatile __u32 status;
+	volatile __u32 version;
+	__u8 precision;		/* In bits, either 8 or 16 */
+	__u8 channels;		/* 1 or 2 */
+};
+
+/*
+ * Control mode first 
+ */
+
+/* Time Slot 1, Status register */
+#define CS4215_CLB	(1<<2)	/* Control Latch Bit */
+#define CS4215_OLB	(1<<3)	/* 1: line: 2.0V, speaker 4V */
+				/* 0: line: 2.8V, speaker 8V */
+#define CS4215_MLB	(1<<4)	/* 1: Microphone: 20dB gain disabled */
+#define CS4215_RSRVD_1  (1<<5)
+
+/* Time Slot 2, Data Format Register */
+#define CS4215_DFR_LINEAR16	0
+#define CS4215_DFR_ULAW		1
+#define CS4215_DFR_ALAW		2
+#define CS4215_DFR_LINEAR8	3
+#define CS4215_DFR_STEREO	(1<<2)
+static struct {
+	unsigned short freq;
+	unsigned char xtal;
+	unsigned char csval;
+} CS4215_FREQ[] = {
+	{  8000, (1 << 4), (0 << 3) },
+	{ 16000, (1 << 4), (1 << 3) },
+	{ 27429, (1 << 4), (2 << 3) },	/* Actually 24428.57 */
+	{ 32000, (1 << 4), (3 << 3) },
+     /* {    NA, (1 << 4), (4 << 3) }, */
+     /* {    NA, (1 << 4), (5 << 3) }, */
+	{ 48000, (1 << 4), (6 << 3) },
+	{  9600, (1 << 4), (7 << 3) },
+	{  5513, (2 << 4), (0 << 3) },	/* Actually 5512.5 */
+	{ 11025, (2 << 4), (1 << 3) },
+	{ 18900, (2 << 4), (2 << 3) },
+	{ 22050, (2 << 4), (3 << 3) },
+	{ 37800, (2 << 4), (4 << 3) },
+	{ 44100, (2 << 4), (5 << 3) },
+	{ 33075, (2 << 4), (6 << 3) },
+	{  6615, (2 << 4), (7 << 3) },
+	{ 0, 0, 0}
+};
+
+#define CS4215_HPF	(1<<7)	/* High Pass Filter, 1: Enabled */
+
+#define CS4215_12_MASK	0xfcbf	/* Mask off reserved bits in slot 1 & 2 */
+
+/* Time Slot 3, Serial Port Control register */
+#define CS4215_XEN	(1<<0)	/* 0: Enable serial output */
+#define CS4215_XCLK	(1<<1)	/* 1: Master mode: Generate SCLK */
+#define CS4215_BSEL_64	(0<<2)	/* Bitrate: 64 bits per frame */
+#define CS4215_BSEL_128	(1<<2)
+#define CS4215_BSEL_256	(2<<2)
+#define CS4215_MCK_MAST (0<<4)	/* Master clock */
+#define CS4215_MCK_XTL1 (1<<4)	/* 24.576 MHz clock source */
+#define CS4215_MCK_XTL2 (2<<4)	/* 16.9344 MHz clock source */
+#define CS4215_MCK_CLK1 (3<<4)	/* Clockin, 256 x Fs */
+#define CS4215_MCK_CLK2 (4<<4)	/* Clockin, see DFR */
+
+/* Time Slot 4, Test Register */
+#define CS4215_DAD	(1<<0)	/* 0:Digital-Dig loop, 1:Dig-Analog-Dig loop */
+#define CS4215_ENL	(1<<1)	/* Enable Loopback Testing */
+
+/* Time Slot 5, Parallel Port Register */
+/* Read only here and the same as the in data mode */
+
+/* Time Slot 6, Reserved  */
+
+/* Time Slot 7, Version Register  */
+#define CS4215_VERSION_MASK 0xf	/* Known versions 0/C, 1/D, 2/E */
+
+/* Time Slot 8, Reserved  */
+
+/*
+ * Data mode
+ */
+/* Time Slot 1-2: Left Channel Data, 2-3: Right Channel Data  */
+
+/* Time Slot 5, Output Setting  */
+#define CS4215_LO(v)	v	/* Left Output Attenuation 0x3f: -94.5 dB */
+#define CS4215_LE	(1<<6)	/* Line Out Enable */
+#define CS4215_HE	(1<<7)	/* Headphone Enable */
+
+/* Time Slot 6, Output Setting  */
+#define CS4215_RO(v)	v	/* Right Output Attenuation 0x3f: -94.5 dB */
+#define CS4215_SE	(1<<6)	/* Speaker Enable */
+#define CS4215_ADI	(1<<7)	/* A/D Data Invalid: Busy in calibration */
+
+/* Time Slot 7, Input Setting */
+#define CS4215_LG(v)	v	/* Left Gain Setting 0xf: 22.5 dB */
+#define CS4215_IS	(1<<4)	/* Input Select: 1=Microphone, 0=Line */
+#define CS4215_OVR	(1<<5)	/* 1: Overrange condition occurred */
+#define CS4215_PIO0	(1<<6)	/* Parallel I/O 0 */
+#define CS4215_PIO1	(1<<7)
+
+/* Time Slot 8, Input Setting */
+#define CS4215_RG(v)	v	/* Right Gain Setting 0xf: 22.5 dB */
+#define CS4215_MA(v)	(v<<4)	/* Monitor Path Attenuation 0xf: mute */
+
+/***************************************************************************
+		DBRI specific definitions and structures
+****************************************************************************/
+
+/* DBRI main registers */
+#define REG0	0x00UL		/* Status and Control */
+#define REG1	0x04UL		/* Mode and Interrupt */
+#define REG2	0x08UL		/* Parallel IO */
+#define REG3	0x0cUL		/* Test */
+#define REG8	0x20UL		/* Command Queue Pointer */
+#define REG9	0x24UL		/* Interrupt Queue Pointer */
+
+#define DBRI_NO_CMDS	64
+#define DBRI_NO_INTS	1	/* Note: the value of this define was
+				 * originally 2.  The ringbuffer to store
+				 * interrupts in dma is currently broken.
+				 * This is a temporary fix until the ringbuffer
+				 * is fixed.
+				 */
+#define DBRI_INT_BLK	64
+#define DBRI_NO_DESCS	64
+#define DBRI_NO_PIPES	32
+
+#define DBRI_MM_ONB	1
+#define DBRI_MM_SB	2
+
+#define DBRI_REC	0
+#define DBRI_PLAY	1
+#define DBRI_NO_STREAMS	2
+
+/* One transmit/receive descriptor */
+struct dbri_mem {
+	volatile __u32 word1;
+	volatile __u32 ba;	/* Transmit/Receive Buffer Address */
+	volatile __u32 nda;	/* Next Descriptor Address */
+	volatile __u32 word4;
+};
+
+/* This structure is in a DMA region where it can accessed by both
+ * the CPU and the DBRI
+ */
+struct dbri_dma {
+	volatile s32 cmd[DBRI_NO_CMDS];	/* Place for commands       */
+	volatile s32 intr[DBRI_NO_INTS * DBRI_INT_BLK];	/* Interrupt field  */
+	struct dbri_mem desc[DBRI_NO_DESCS];	/* Xmit/receive descriptors */
+};
+
+#define dbri_dma_off(member, elem)	\
+	((u32)(unsigned long)		\
+	 (&(((struct dbri_dma *)0)->member[elem])))
+
+enum in_or_out { PIPEinput, PIPEoutput };
+
+struct dbri_pipe {
+	u32 sdp;		/* SDP command word */
+	enum in_or_out direction;
+	int nextpipe;		/* Next pipe in linked list */
+	int prevpipe;
+	int cycle;		/* Offset of timeslot (bits) */
+	int length;		/* Length of timeslot (bits) */
+	int first_desc;		/* Index of first descriptor */
+	int desc;		/* Index of active descriptor */
+	volatile __u32 *recv_fixed_ptr;	/* Ptr to receive fixed data */
+};
+
+struct dbri_desc {
+	int inuse;		/* Boolean flag */
+	int next;		/* Index of next desc, or -1 */
+	unsigned int len;
+};
+
+/* Per stream (playback or record) information */
+typedef struct dbri_streaminfo {
+	snd_pcm_substream_t *substream;
+	u32 dvma_buffer;	/* Device view of Alsa DMA buffer */
+	int left;		/* # of bytes left in DMA buffer  */
+	int size;		/* Size of DMA buffer             */
+	size_t offset;		/* offset in user buffer          */
+	int pipe;		/* Data pipe used                 */
+	int left_gain;		/* mixer elements                 */
+	int right_gain;
+	int balance;
+} dbri_streaminfo_t;
+
+/* This structure holds the information for both chips (DBRI & CS4215) */
+typedef struct snd_dbri {
+	snd_card_t *card;	/* ALSA card */
+	snd_pcm_t *pcm;
+
+	int regs_size, irq;	/* Needed for unload */
+	struct sbus_dev *sdev;	/* SBUS device info */
+	spinlock_t lock;
+
+	volatile struct dbri_dma *dma;	/* Pointer to our DMA block */
+	u32 dma_dvma;		/* DBRI visible DMA address */
+
+	void __iomem *regs;	/* dbri HW regs */
+	int dbri_version;	/* 'e' and up is OK */
+	int dbri_irqp;		/* intr queue pointer */
+	int wait_seen;
+
+	struct dbri_pipe pipes[DBRI_NO_PIPES];	/* DBRI's 32 data pipes */
+	struct dbri_desc descs[DBRI_NO_DESCS];
+
+	int chi_in_pipe;
+	int chi_out_pipe;
+	int chi_bpf;
+
+	struct cs4215 mm;	/* mmcodec special info */
+				/* per stream (playback/record) info */
+	struct dbri_streaminfo stream_info[DBRI_NO_STREAMS];
+
+	struct snd_dbri *next;
+} snd_dbri_t;
+
+/* Needed for the ALSA macros to work */
+#define chip_t snd_dbri_t
+
+#define DBRI_MAX_VOLUME		63	/* Output volume */
+#define DBRI_MAX_GAIN		15	/* Input gain */
+#define DBRI_RIGHT_BALANCE	255
+#define DBRI_MID_BALANCE	(DBRI_RIGHT_BALANCE >> 1)
+
+/* DBRI Reg0 - Status Control Register - defines. (Page 17) */
+#define D_P		(1<<15)	/* Program command & queue pointer valid */
+#define D_G		(1<<14)	/* Allow 4-Word SBus Burst */
+#define D_S		(1<<13)	/* Allow 16-Word SBus Burst */
+#define D_E		(1<<12)	/* Allow 8-Word SBus Burst */
+#define D_X		(1<<7)	/* Sanity Timer Disable */
+#define D_T		(1<<6)	/* Permit activation of the TE interface */
+#define D_N		(1<<5)	/* Permit activation of the NT interface */
+#define D_C		(1<<4)	/* Permit activation of the CHI interface */
+#define D_F		(1<<3)	/* Force Sanity Timer Time-Out */
+#define D_D		(1<<2)	/* Disable Master Mode */
+#define D_H		(1<<1)	/* Halt for Analysis */
+#define D_R		(1<<0)	/* Soft Reset */
+
+/* DBRI Reg1 - Mode and Interrupt Register - defines. (Page 18) */
+#define D_LITTLE_END	(1<<8)	/* Byte Order */
+#define D_BIG_END	(0<<8)	/* Byte Order */
+#define D_MRR		(1<<4)	/* Multiple Error Ack on SBus (readonly) */
+#define D_MLE		(1<<3)	/* Multiple Late Error on SBus (readonly) */
+#define D_LBG		(1<<2)	/* Lost Bus Grant on SBus (readonly) */
+#define D_MBE		(1<<1)	/* Burst Error on SBus (readonly) */
+#define D_IR		(1<<0)	/* Interrupt Indicator (readonly) */
+
+/* DBRI Reg2 - Parallel IO Register - defines. (Page 18) */
+#define D_ENPIO3	(1<<7)	/* Enable Pin 3 */
+#define D_ENPIO2	(1<<6)	/* Enable Pin 2 */
+#define D_ENPIO1	(1<<5)	/* Enable Pin 1 */
+#define D_ENPIO0	(1<<4)	/* Enable Pin 0 */
+#define D_ENPIO		(0xf0)	/* Enable all the pins */
+#define D_PIO3		(1<<3)	/* Pin 3: 1: Data mode, 0: Ctrl mode */
+#define D_PIO2		(1<<2)	/* Pin 2: 1: Onboard PDN */
+#define D_PIO1		(1<<1)	/* Pin 1: 0: Reset */
+#define D_PIO0		(1<<0)	/* Pin 0: 1: Speakerbox PDN */
+
+/* DBRI Commands (Page 20) */
+#define D_WAIT		0x0	/* Stop execution */
+#define D_PAUSE		0x1	/* Flush long pipes */
+#define D_JUMP		0x2	/* New command queue */
+#define D_IIQ		0x3	/* Initialize Interrupt Queue */
+#define D_REX		0x4	/* Report command execution via interrupt */
+#define D_SDP		0x5	/* Setup Data Pipe */
+#define D_CDP		0x6	/* Continue Data Pipe (reread NULL Pointer) */
+#define D_DTS		0x7	/* Define Time Slot */
+#define D_SSP		0x8	/* Set short Data Pipe */
+#define D_CHI		0x9	/* Set CHI Global Mode */
+#define D_NT		0xa	/* NT Command */
+#define D_TE		0xb	/* TE Command */
+#define D_CDEC		0xc	/* Codec setup */
+#define D_TEST		0xd	/* No comment */
+#define D_CDM		0xe	/* CHI Data mode command */
+
+/* Special bits for some commands */
+#define D_PIPE(v)      ((v)<<0)	/* Pipe Nr: 0-15 long, 16-21 short */
+
+/* Setup Data Pipe */
+/* IRM */
+#define D_SDP_2SAME	(1<<18)	/* Report 2nd time in a row value rcvd */
+#define D_SDP_CHANGE	(2<<18)	/* Report any changes */
+#define D_SDP_EVERY	(3<<18)	/* Report any changes */
+#define D_SDP_EOL	(1<<17)	/* EOL interrupt enable */
+#define D_SDP_IDLE	(1<<16)	/* HDLC idle interrupt enable */
+
+/* Pipe data MODE */
+#define D_SDP_MEM	(0<<13)	/* To/from memory */
+#define D_SDP_HDLC	(2<<13)
+#define D_SDP_HDLC_D	(3<<13)	/* D Channel (prio control) */
+#define D_SDP_SER	(4<<13)	/* Serial to serial */
+#define D_SDP_FIXED	(6<<13)	/* Short only */
+#define D_SDP_MODE(v)	((v)&(7<<13))
+
+#define D_SDP_TO_SER	(1<<12)	/* Direction */
+#define D_SDP_FROM_SER	(0<<12)	/* Direction */
+#define D_SDP_MSB	(1<<11)	/* Bit order within Byte */
+#define D_SDP_LSB	(0<<11)	/* Bit order within Byte */
+#define D_SDP_P		(1<<10)	/* Pointer Valid */
+#define D_SDP_A		(1<<8)	/* Abort */
+#define D_SDP_C		(1<<7)	/* Clear */
+
+/* Define Time Slot */
+#define D_DTS_VI	(1<<17)	/* Valid Input Time-Slot Descriptor */
+#define D_DTS_VO	(1<<16)	/* Valid Output Time-Slot Descriptor */
+#define D_DTS_INS	(1<<15)	/* Insert Time Slot */
+#define D_DTS_DEL	(0<<15)	/* Delete Time Slot */
+#define D_DTS_PRVIN(v) ((v)<<10)	/* Previous In Pipe */
+#define D_DTS_PRVOUT(v)        ((v)<<5)	/* Previous Out Pipe */
+
+/* Time Slot defines */
+#define D_TS_LEN(v)	((v)<<24)	/* Number of bits in this time slot */
+#define D_TS_CYCLE(v)	((v)<<14)	/* Bit Count at start of TS */
+#define D_TS_DI		(1<<13)	/* Data Invert */
+#define D_TS_1CHANNEL	(0<<10)	/* Single Channel / Normal mode */
+#define D_TS_MONITOR	(2<<10)	/* Monitor pipe */
+#define D_TS_NONCONTIG	(3<<10)	/* Non contiguous mode */
+#define D_TS_ANCHOR	(7<<10)	/* Starting short pipes */
+#define D_TS_MON(v)    ((v)<<5)	/* Monitor Pipe */
+#define D_TS_NEXT(v)   ((v)<<0)	/* Pipe Nr: 0-15 long, 16-21 short */
+
+/* Concentration Highway Interface Modes */
+#define D_CHI_CHICM(v)	((v)<<16)	/* Clock mode */
+#define D_CHI_IR	(1<<15)	/* Immediate Interrupt Report */
+#define D_CHI_EN	(1<<14)	/* CHIL Interrupt enabled */
+#define D_CHI_OD	(1<<13)	/* Open Drain Enable */
+#define D_CHI_FE	(1<<12)	/* Sample CHIFS on Rising Frame Edge */
+#define D_CHI_FD	(1<<11)	/* Frame Drive */
+#define D_CHI_BPF(v)	((v)<<0)	/* Bits per Frame */
+
+/* NT: These are here for completeness */
+#define D_NT_FBIT	(1<<17)	/* Frame Bit */
+#define D_NT_NBF	(1<<16)	/* Number of bad frames to loose framing */
+#define D_NT_IRM_IMM	(1<<15)	/* Interrupt Report & Mask: Immediate */
+#define D_NT_IRM_EN	(1<<14)	/* Interrupt Report & Mask: Enable */
+#define D_NT_ISNT	(1<<13)	/* Configfure interface as NT */
+#define D_NT_FT		(1<<12)	/* Fixed Timing */
+#define D_NT_EZ		(1<<11)	/* Echo Channel is Zeros */
+#define D_NT_IFA	(1<<10)	/* Inhibit Final Activation */
+#define D_NT_ACT	(1<<9)	/* Activate Interface */
+#define D_NT_MFE	(1<<8)	/* Multiframe Enable */
+#define D_NT_RLB(v)	((v)<<5)	/* Remote Loopback */
+#define D_NT_LLB(v)	((v)<<2)	/* Local Loopback */
+#define D_NT_FACT	(1<<1)	/* Force Activation */
+#define D_NT_ABV	(1<<0)	/* Activate Bipolar Violation */
+
+/* Codec Setup */
+#define D_CDEC_CK(v)	((v)<<24)	/* Clock Select */
+#define D_CDEC_FED(v)	((v)<<12)	/* FSCOD Falling Edge Delay */
+#define D_CDEC_RED(v)	((v)<<0)	/* FSCOD Rising Edge Delay */
+
+/* Test */
+#define D_TEST_RAM(v)	((v)<<16)	/* RAM Pointer */
+#define D_TEST_SIZE(v)	((v)<<11)	/* */
+#define D_TEST_ROMONOFF	0x5	/* Toggle ROM opcode monitor on/off */
+#define D_TEST_PROC	0x6	/* MicroProcessor test */
+#define D_TEST_SER	0x7	/* Serial-Controller test */
+#define D_TEST_RAMREAD	0x8	/* Copy from Ram to system memory */
+#define D_TEST_RAMWRITE	0x9	/* Copy into Ram from system memory */
+#define D_TEST_RAMBIST	0xa	/* RAM Built-In Self Test */
+#define D_TEST_MCBIST	0xb	/* Microcontroller Built-In Self Test */
+#define D_TEST_DUMP	0xe	/* ROM Dump */
+
+/* CHI Data Mode */
+#define D_CDM_THI	(1<<8)	/* Transmit Data on CHIDR Pin */
+#define D_CDM_RHI	(1<<7)	/* Receive Data on CHIDX Pin */
+#define D_CDM_RCE	(1<<6)	/* Receive on Rising Edge of CHICK */
+#define D_CDM_XCE	(1<<2)	/* Transmit Data on Rising Edge of CHICK */
+#define D_CDM_XEN	(1<<1)	/* Transmit Highway Enable */
+#define D_CDM_REN	(1<<0)	/* Receive Highway Enable */
+
+/* The Interrupts */
+#define D_INTR_BRDY	1	/* Buffer Ready for processing */
+#define D_INTR_MINT	2	/* Marked Interrupt in RD/TD */
+#define D_INTR_IBEG	3	/* Flag to idle transition detected (HDLC) */
+#define D_INTR_IEND	4	/* Idle to flag transition detected (HDLC) */
+#define D_INTR_EOL	5	/* End of List */
+#define D_INTR_CMDI	6	/* Command has bean read */
+#define D_INTR_XCMP	8	/* Transmission of frame complete */
+#define D_INTR_SBRI	9	/* BRI status change info */
+#define D_INTR_FXDT	10	/* Fixed data change */
+#define D_INTR_CHIL	11	/* CHI lost frame sync (channel 36 only) */
+#define D_INTR_COLL	11	/* Unrecoverable D-Channel collision */
+#define D_INTR_DBYT	12	/* Dropped by frame slip */
+#define D_INTR_RBYT	13	/* Repeated by frame slip */
+#define D_INTR_LINT	14	/* Lost Interrupt */
+#define D_INTR_UNDR	15	/* DMA underrun */
+
+#define D_INTR_TE	32
+#define D_INTR_NT	34
+#define D_INTR_CHI	36
+#define D_INTR_CMD	38
+
+#define D_INTR_GETCHAN(v)	(((v)>>24) & 0x3f)
+#define D_INTR_GETCODE(v)	(((v)>>20) & 0xf)
+#define D_INTR_GETCMD(v)	(((v)>>16) & 0xf)
+#define D_INTR_GETVAL(v)	((v) & 0xffff)
+#define D_INTR_GETRVAL(v)	((v) & 0xfffff)
+
+#define D_P_0		0	/* TE receive anchor */
+#define D_P_1		1	/* TE transmit anchor */
+#define D_P_2		2	/* NT transmit anchor */
+#define D_P_3		3	/* NT receive anchor */
+#define D_P_4		4	/* CHI send data */
+#define D_P_5		5	/* CHI receive data */
+#define D_P_6		6	/* */
+#define D_P_7		7	/* */
+#define D_P_8		8	/* */
+#define D_P_9		9	/* */
+#define D_P_10		10	/* */
+#define D_P_11		11	/* */
+#define D_P_12		12	/* */
+#define D_P_13		13	/* */
+#define D_P_14		14	/* */
+#define D_P_15		15	/* */
+#define D_P_16		16	/* CHI anchor pipe */
+#define D_P_17		17	/* CHI send */
+#define D_P_18		18	/* CHI receive */
+#define D_P_19		19	/* CHI receive */
+#define D_P_20		20	/* CHI receive */
+#define D_P_21		21	/* */
+#define D_P_22		22	/* */
+#define D_P_23		23	/* */
+#define D_P_24		24	/* */
+#define D_P_25		25	/* */
+#define D_P_26		26	/* */
+#define D_P_27		27	/* */
+#define D_P_28		28	/* */
+#define D_P_29		29	/* */
+#define D_P_30		30	/* */
+#define D_P_31		31	/* */
+
+/* Transmit descriptor defines */
+#define DBRI_TD_F	(1<<31)	/* End of Frame */
+#define DBRI_TD_D	(1<<30)	/* Do not append CRC */
+#define DBRI_TD_CNT(v)	((v)<<16)	/* Number of valid bytes in the buffer */
+#define DBRI_TD_B	(1<<15)	/* Final interrupt */
+#define DBRI_TD_M	(1<<14)	/* Marker interrupt */
+#define DBRI_TD_I	(1<<13)	/* Transmit Idle Characters */
+#define DBRI_TD_FCNT(v)	(v)	/* Flag Count */
+#define DBRI_TD_UNR	(1<<3)	/* Underrun: transmitter is out of data */
+#define DBRI_TD_ABT	(1<<2)	/* Abort: frame aborted */
+#define DBRI_TD_TBC	(1<<0)	/* Transmit buffer Complete */
+#define DBRI_TD_STATUS(v)       ((v)&0xff)	/* Transmit status */
+			/* Maximum buffer size per TD: almost 8Kb */
+#define DBRI_TD_MAXCNT	((1 << 13) - 1)
+
+/* Receive descriptor defines */
+#define DBRI_RD_F	(1<<31)	/* End of Frame */
+#define DBRI_RD_C	(1<<30)	/* Completed buffer */
+#define DBRI_RD_B	(1<<15)	/* Final interrupt */
+#define DBRI_RD_M	(1<<14)	/* Marker interrupt */
+#define DBRI_RD_BCNT(v)	(v)	/* Buffer size */
+#define DBRI_RD_CRC	(1<<7)	/* 0: CRC is correct */
+#define DBRI_RD_BBC	(1<<6)	/* 1: Bad Byte received */
+#define DBRI_RD_ABT	(1<<5)	/* Abort: frame aborted */
+#define DBRI_RD_OVRN	(1<<3)	/* Overrun: data lost */
+#define DBRI_RD_STATUS(v)      ((v)&0xff)	/* Receive status */
+#define DBRI_RD_CNT(v) (((v)>>16)&0x1fff)	/* Valid bytes in the buffer */
+
+/* stream_info[] access */
+/* Translate the ALSA direction into the array index */
+#define DBRI_STREAMNO(substream)				\
+		(substream->stream == 				\
+		 SNDRV_PCM_STREAM_PLAYBACK? DBRI_PLAY: DBRI_REC)
+
+/* Return a pointer to dbri_streaminfo */
+#define DBRI_STREAM(dbri, substream)	&dbri->stream_info[DBRI_STREAMNO(substream)]
+
+static snd_dbri_t *dbri_list = NULL;	/* All DBRI devices */
+
+/*
+ * Short data pipes transmit LSB first. The CS4215 receives MSB first. Grrr.
+ * So we have to reverse the bits. Note: not all bit lengths are supported
+ */
+static __u32 reverse_bytes(__u32 b, int len)
+{
+	switch (len) {
+	case 32:
+		b = ((b & 0xffff0000) >> 16) | ((b & 0x0000ffff) << 16);
+	case 16:
+		b = ((b & 0xff00ff00) >> 8) | ((b & 0x00ff00ff) << 8);
+	case 8:
+		b = ((b & 0xf0f0f0f0) >> 4) | ((b & 0x0f0f0f0f) << 4);
+	case 4:
+		b = ((b & 0xcccccccc) >> 2) | ((b & 0x33333333) << 2);
+	case 2:
+		b = ((b & 0xaaaaaaaa) >> 1) | ((b & 0x55555555) << 1);
+	case 1:
+	case 0:
+		break;
+	default:
+		printk(KERN_ERR "DBRI reverse_bytes: unsupported length\n");
+	};
+
+	return b;
+}
+
+/*
+****************************************************************************
+************** DBRI initialization and command synchronization *************
+****************************************************************************
+
+Commands are sent to the DBRI by building a list of them in memory,
+then writing the address of the first list item to DBRI register 8.
+The list is terminated with a WAIT command, which can generate a
+CPU interrupt if required.
+
+Since the DBRI can run in parallel with the CPU, several means of
+synchronization present themselves.  The original scheme (Rudolf's)
+was to set a flag when we "cmdlock"ed the DBRI, clear the flag when
+an interrupt signaled completion, and wait on a wait_queue if a routine
+attempted to cmdlock while the flag was set.  The problems arose when
+we tried to cmdlock from inside an interrupt handler, which might
+cause scheduling in an interrupt (if we waited), etc, etc
+
+A more sophisticated scheme might involve a circular command buffer
+or an array of command buffers.  A routine could fill one with
+commands and link it onto a list.  When a interrupt signaled
+completion of the current command buffer, look on the list for
+the next one.
+
+I've decided to implement something much simpler - after each command,
+the CPU waits for the DBRI to finish the command by polling the P bit
+in DBRI register 0.  I've tried to implement this in such a way
+that might make implementing a more sophisticated scheme easier.
+
+Every time a routine wants to write commands to the DBRI, it must
+first call dbri_cmdlock() and get an initial pointer into dbri->dma->cmd
+in return.  After the commands have been writen, dbri_cmdsend() is
+called with the final pointer value.
+
+*/
+
+enum dbri_lock_t { NoGetLock, GetLock };
+
+static volatile s32 *dbri_cmdlock(snd_dbri_t * dbri, enum dbri_lock_t get)
+{
+#ifndef SMP
+	if ((get == GetLock) && spin_is_locked(&dbri->lock)) {
+		printk(KERN_ERR "DBRI: cmdlock called while in spinlock.");
+	}
+#endif
+
+	/*if (get == GetLock) spin_lock(&dbri->lock); */
+	return &dbri->dma->cmd[0];
+}
+
+static void dbri_process_interrupt_buffer(snd_dbri_t *);
+
+static void dbri_cmdsend(snd_dbri_t * dbri, volatile s32 * cmd)
+{
+	int MAXLOOPS = 1000000;
+	int maxloops = MAXLOOPS;
+	volatile s32 *ptr;
+
+	for (ptr = &dbri->dma->cmd[0]; ptr < cmd; ptr++) {
+		dprintk(D_CMD, "cmd: %lx:%08x\n", (unsigned long)ptr, *ptr);
+	}
+
+	if ((cmd - &dbri->dma->cmd[0]) >= DBRI_NO_CMDS - 1) {
+		printk("DBRI: Command buffer overflow! (bug in driver)\n");
+		/* Ignore the last part. */
+		cmd = &dbri->dma->cmd[DBRI_NO_CMDS - 3];
+	}
+
+	*(cmd++) = DBRI_CMD(D_PAUSE, 0, 0);
+	*(cmd++) = DBRI_CMD(D_WAIT, 1, 0);
+	dbri->wait_seen = 0;
+	sbus_writel(dbri->dma_dvma, dbri->regs + REG8);
+	while ((--maxloops) > 0 && (sbus_readl(dbri->regs + REG0) & D_P))
+		barrier();
+	if (maxloops == 0) {
+		printk(KERN_ERR "DBRI: Chip never completed command buffer\n");
+		dprintk(D_CMD, "DBRI: Chip never completed command buffer\n");
+	} else {
+		while ((--maxloops) > 0 && (!dbri->wait_seen))
+			dbri_process_interrupt_buffer(dbri);
+		if (maxloops == 0) {
+			printk(KERN_ERR "DBRI: Chip never acked WAIT\n");
+			dprintk(D_CMD, "DBRI: Chip never acked WAIT\n");
+		} else {
+			dprintk(D_CMD, "Chip completed command "
+				"buffer (%d)\n", MAXLOOPS - maxloops);
+		}
+	}
+
+	/*spin_unlock(&dbri->lock); */
+}
+
+/* Lock must be held when calling this */
+static void dbri_reset(snd_dbri_t * dbri)
+{
+	int i;
+
+	dprintk(D_GEN, "reset 0:%x 2:%x 8:%x 9:%x\n",
+		sbus_readl(dbri->regs + REG0),
+		sbus_readl(dbri->regs + REG2),
+		sbus_readl(dbri->regs + REG8), sbus_readl(dbri->regs + REG9));
+
+	sbus_writel(D_R, dbri->regs + REG0);	/* Soft Reset */
+	for (i = 0; (sbus_readl(dbri->regs + REG0) & D_R) && i < 64; i++)
+		udelay(10);
+}
+
+/* Lock must not be held before calling this */
+static void dbri_initialize(snd_dbri_t * dbri)
+{
+	volatile s32 *cmd;
+	u32 dma_addr, tmp;
+	unsigned long flags;
+	int n;
+
+	spin_lock_irqsave(&dbri->lock, flags);
+
+	dbri_reset(dbri);
+
+	cmd = dbri_cmdlock(dbri, NoGetLock);
+	dprintk(D_GEN, "init: cmd: %p, int: %p\n",
+		&dbri->dma->cmd[0], &dbri->dma->intr[0]);
+
+	/*
+	 * Initialize the interrupt ringbuffer.
+	 */
+	for (n = 0; n < DBRI_NO_INTS - 1; n++) {
+		dma_addr = dbri->dma_dvma;
+		dma_addr += dbri_dma_off(intr, ((n + 1) & DBRI_INT_BLK));
+		dbri->dma->intr[n * DBRI_INT_BLK] = dma_addr;
+	}
+	dma_addr = dbri->dma_dvma + dbri_dma_off(intr, 0);
+	dbri->dma->intr[n * DBRI_INT_BLK] = dma_addr;
+	dbri->dbri_irqp = 1;
+
+	/* Initialize pipes */
+	for (n = 0; n < DBRI_NO_PIPES; n++)
+		dbri->pipes[n].desc = dbri->pipes[n].first_desc = -1;
+
+	/* We should query the openprom to see what burst sizes this
+	 * SBus supports.  For now, just disable all SBus bursts */
+	tmp = sbus_readl(dbri->regs + REG0);
+	tmp &= ~(D_G | D_S | D_E);
+	sbus_writel(tmp, dbri->regs + REG0);
+
+	/*
+	 * Set up the interrupt queue
+	 */
+	dma_addr = dbri->dma_dvma + dbri_dma_off(intr, 0);
+	*(cmd++) = DBRI_CMD(D_IIQ, 0, 0);
+	*(cmd++) = dma_addr;
+
+	dbri_cmdsend(dbri, cmd);
+	spin_unlock_irqrestore(&dbri->lock, flags);
+}
+
+/*
+****************************************************************************
+************************** DBRI data pipe management ***********************
+****************************************************************************
+
+While DBRI control functions use the command and interrupt buffers, the
+main data path takes the form of data pipes, which can be short (command
+and interrupt driven), or long (attached to DMA buffers).  These functions
+provide a rudimentary means of setting up and managing the DBRI's pipes,
+but the calling functions have to make sure they respect the pipes' linked
+list ordering, among other things.  The transmit and receive functions
+here interface closely with the transmit and receive interrupt code.
+
+*/
+static int pipe_active(snd_dbri_t * dbri, int pipe)
+{
+	return ((pipe >= 0) && (dbri->pipes[pipe].desc != -1));
+}
+
+/* reset_pipe(dbri, pipe)
+ *
+ * Called on an in-use pipe to clear anything being transmitted or received
+ * Lock must be held before calling this.
+ */
+static void reset_pipe(snd_dbri_t * dbri, int pipe)
+{
+	int sdp;
+	int desc;
+	volatile int *cmd;
+
+	if (pipe < 0 || pipe > 31) {
+		printk("DBRI: reset_pipe called with illegal pipe number\n");
+		return;
+	}
+
+	sdp = dbri->pipes[pipe].sdp;
+	if (sdp == 0) {
+		printk("DBRI: reset_pipe called on uninitialized pipe\n");
+		return;
+	}
+
+	cmd = dbri_cmdlock(dbri, NoGetLock);
+	*(cmd++) = DBRI_CMD(D_SDP, 0, sdp | D_SDP_C | D_SDP_P);
+	*(cmd++) = 0;
+	dbri_cmdsend(dbri, cmd);
+
+	desc = dbri->pipes[pipe].first_desc;
+	while (desc != -1) {
+		dbri->descs[desc].inuse = 0;
+		desc = dbri->descs[desc].next;
+	}
+
+	dbri->pipes[pipe].desc = -1;
+	dbri->pipes[pipe].first_desc = -1;
+}
+
+/* FIXME: direction as an argument? */
+static void setup_pipe(snd_dbri_t * dbri, int pipe, int sdp)
+{
+	if (pipe < 0 || pipe > 31) {
+		printk("DBRI: setup_pipe called with illegal pipe number\n");
+		return;
+	}
+
+	if ((sdp & 0xf800) != sdp) {
+		printk("DBRI: setup_pipe called with strange SDP value\n");
+		/* sdp &= 0xf800; */
+	}
+
+	/* If this is a fixed receive pipe, arrange for an interrupt
+	 * every time its data changes
+	 */
+	if (D_SDP_MODE(sdp) == D_SDP_FIXED && !(sdp & D_SDP_TO_SER))
+		sdp |= D_SDP_CHANGE;
+
+	sdp |= D_PIPE(pipe);
+	dbri->pipes[pipe].sdp = sdp;
+	dbri->pipes[pipe].desc = -1;
+	dbri->pipes[pipe].first_desc = -1;
+	if (sdp & D_SDP_TO_SER)
+		dbri->pipes[pipe].direction = PIPEoutput;
+	else
+		dbri->pipes[pipe].direction = PIPEinput;
+
+	reset_pipe(dbri, pipe);
+}
+
+/* FIXME: direction not needed */
+static void link_time_slot(snd_dbri_t * dbri, int pipe,
+			   enum in_or_out direction, int basepipe,
+			   int length, int cycle)
+{
+	volatile s32 *cmd;
+	int val;
+	int prevpipe;
+	int nextpipe;
+
+	if (pipe < 0 || pipe > 31 || basepipe < 0 || basepipe > 31) {
+		printk
+		    ("DBRI: link_time_slot called with illegal pipe number\n");
+		return;
+	}
+
+	if (dbri->pipes[pipe].sdp == 0 || dbri->pipes[basepipe].sdp == 0) {
+		printk("DBRI: link_time_slot called on uninitialized pipe\n");
+		return;
+	}
+
+	/* Deal with CHI special case:
+	 * "If transmission on edges 0 or 1 is desired, then cycle n
+	 *  (where n = # of bit times per frame...) must be used."
+	 *                  - DBRI data sheet, page 11
+	 */
+	if (basepipe == 16 && direction == PIPEoutput && cycle == 0)
+		cycle = dbri->chi_bpf;
+
+	if (basepipe == pipe) {
+		prevpipe = pipe;
+		nextpipe = pipe;
+	} else {
+		/* We're not initializing a new linked list (basepipe != pipe),
+		 * so run through the linked list and find where this pipe
+		 * should be sloted in, based on its cycle.  CHI confuses
+		 * things a bit, since it has a single anchor for both its
+		 * transmit and receive lists.
+		 */
+		if (basepipe == 16) {
+			if (direction == PIPEinput) {
+				prevpipe = dbri->chi_in_pipe;
+			} else {
+				prevpipe = dbri->chi_out_pipe;
+			}
+		} else {
+			prevpipe = basepipe;
+		}
+
+		nextpipe = dbri->pipes[prevpipe].nextpipe;
+
+		while (dbri->pipes[nextpipe].cycle < cycle
+		       && dbri->pipes[nextpipe].nextpipe != basepipe) {
+			prevpipe = nextpipe;
+			nextpipe = dbri->pipes[nextpipe].nextpipe;
+		}
+	}
+
+	if (prevpipe == 16) {
+		if (direction == PIPEinput) {
+			dbri->chi_in_pipe = pipe;
+		} else {
+			dbri->chi_out_pipe = pipe;
+		}
+	} else {
+		dbri->pipes[prevpipe].nextpipe = pipe;
+	}
+
+	dbri->pipes[pipe].nextpipe = nextpipe;
+	dbri->pipes[pipe].cycle = cycle;
+	dbri->pipes[pipe].length = length;
+
+	cmd = dbri_cmdlock(dbri, NoGetLock);
+
+	if (direction == PIPEinput) {
+		val = D_DTS_VI | D_DTS_INS | D_DTS_PRVIN(prevpipe) | pipe;
+		*(cmd++) = DBRI_CMD(D_DTS, 0, val);
+		*(cmd++) =
+		    D_TS_LEN(length) | D_TS_CYCLE(cycle) | D_TS_NEXT(nextpipe);
+		*(cmd++) = 0;
+	} else {
+		val = D_DTS_VO | D_DTS_INS | D_DTS_PRVOUT(prevpipe) | pipe;
+		*(cmd++) = DBRI_CMD(D_DTS, 0, val);
+		*(cmd++) = 0;
+		*(cmd++) =
+		    D_TS_LEN(length) | D_TS_CYCLE(cycle) | D_TS_NEXT(nextpipe);
+	}
+
+	dbri_cmdsend(dbri, cmd);
+}
+
+static void unlink_time_slot(snd_dbri_t * dbri, int pipe,
+			     enum in_or_out direction, int prevpipe,
+			     int nextpipe)
+{
+	volatile s32 *cmd;
+	int val;
+
+	if (pipe < 0 || pipe > 31 || prevpipe < 0 || prevpipe > 31) {
+		printk
+		    ("DBRI: unlink_time_slot called with illegal pipe number\n");
+		return;
+	}
+
+	cmd = dbri_cmdlock(dbri, NoGetLock);
+
+	if (direction == PIPEinput) {
+		val = D_DTS_VI | D_DTS_DEL | D_DTS_PRVIN(prevpipe) | pipe;
+		*(cmd++) = DBRI_CMD(D_DTS, 0, val);
+		*(cmd++) = D_TS_NEXT(nextpipe);
+		*(cmd++) = 0;
+	} else {
+		val = D_DTS_VO | D_DTS_DEL | D_DTS_PRVOUT(prevpipe) | pipe;
+		*(cmd++) = DBRI_CMD(D_DTS, 0, val);
+		*(cmd++) = 0;
+		*(cmd++) = D_TS_NEXT(nextpipe);
+	}
+
+	dbri_cmdsend(dbri, cmd);
+}
+
+/* xmit_fixed() / recv_fixed()
+ *
+ * Transmit/receive data on a "fixed" pipe - i.e, one whose contents are not
+ * expected to change much, and which we don't need to buffer.
+ * The DBRI only interrupts us when the data changes (receive pipes),
+ * or only changes the data when this function is called (transmit pipes).
+ * Only short pipes (numbers 16-31) can be used in fixed data mode.
+ *
+ * These function operate on a 32-bit field, no matter how large
+ * the actual time slot is.  The interrupt handler takes care of bit
+ * ordering and alignment.  An 8-bit time slot will always end up
+ * in the low-order 8 bits, filled either MSB-first or LSB-first,
+ * depending on the settings passed to setup_pipe()
+ */
+static void xmit_fixed(snd_dbri_t * dbri, int pipe, unsigned int data)
+{
+	volatile s32 *cmd;
+
+	if (pipe < 16 || pipe > 31) {
+		printk("DBRI: xmit_fixed: Illegal pipe number\n");
+		return;
+	}
+
+	if (D_SDP_MODE(dbri->pipes[pipe].sdp) == 0) {
+		printk("DBRI: xmit_fixed: Uninitialized pipe %d\n", pipe);
+		return;
+	}
+
+	if (D_SDP_MODE(dbri->pipes[pipe].sdp) != D_SDP_FIXED) {
+		printk("DBRI: xmit_fixed: Non-fixed pipe %d\n", pipe);
+		return;
+	}
+
+	if (!(dbri->pipes[pipe].sdp & D_SDP_TO_SER)) {
+		printk("DBRI: xmit_fixed: Called on receive pipe %d\n", pipe);
+		return;
+	}
+
+	/* DBRI short pipes always transmit LSB first */
+
+	if (dbri->pipes[pipe].sdp & D_SDP_MSB)
+		data = reverse_bytes(data, dbri->pipes[pipe].length);
+
+	cmd = dbri_cmdlock(dbri, GetLock);
+
+	*(cmd++) = DBRI_CMD(D_SSP, 0, pipe);
+	*(cmd++) = data;
+
+	dbri_cmdsend(dbri, cmd);
+}
+
+static void recv_fixed(snd_dbri_t * dbri, int pipe, volatile __u32 * ptr)
+{
+	if (pipe < 16 || pipe > 31) {
+		printk("DBRI: recv_fixed called with illegal pipe number\n");
+		return;
+	}
+
+	if (D_SDP_MODE(dbri->pipes[pipe].sdp) != D_SDP_FIXED) {
+		printk("DBRI: recv_fixed called on non-fixed pipe %d\n", pipe);
+		return;
+	}
+
+	if (dbri->pipes[pipe].sdp & D_SDP_TO_SER) {
+		printk("DBRI: recv_fixed called on transmit pipe %d\n", pipe);
+		return;
+	}
+
+	dbri->pipes[pipe].recv_fixed_ptr = ptr;
+}
+
+/* setup_descs()
+ *
+ * Setup transmit/receive data on a "long" pipe - i.e, one associated
+ * with a DMA buffer.
+ *
+ * Only pipe numbers 0-15 can be used in this mode.
+ *
+ * This function takes a stream number pointing to a data buffer,
+ * and work by building chains of descriptors which identify the
+ * data buffers.  Buffers too large for a single descriptor will
+ * be spread across multiple descriptors.
+ */
+static int setup_descs(snd_dbri_t * dbri, int streamno, unsigned int period)
+{
+	dbri_streaminfo_t *info = &dbri->stream_info[streamno];
+	__u32 dvma_buffer;
+	int desc = 0;
+	int len;
+	int first_desc = -1;
+	int last_desc = -1;
+
+	if (info->pipe < 0 || info->pipe > 15) {
+		printk("DBRI: setup_descs: Illegal pipe number\n");
+		return -2;
+	}
+
+	if (dbri->pipes[info->pipe].sdp == 0) {
+		printk("DBRI: setup_descs: Uninitialized pipe %d\n",
+		       info->pipe);
+		return -2;
+	}
+
+	dvma_buffer = info->dvma_buffer;
+	len = info->size;
+
+	if (streamno == DBRI_PLAY) {
+		if (!(dbri->pipes[info->pipe].sdp & D_SDP_TO_SER)) {
+			printk("DBRI: setup_descs: Called on receive pipe %d\n",
+			       info->pipe);
+			return -2;
+		}
+	} else {
+		if (dbri->pipes[info->pipe].sdp & D_SDP_TO_SER) {
+			printk
+			    ("DBRI: setup_descs: Called on transmit pipe %d\n",
+			     info->pipe);
+			return -2;
+		}
+		/* Should be able to queue multiple buffers to receive on a pipe */
+		if (pipe_active(dbri, info->pipe)) {
+			printk("DBRI: recv_on_pipe: Called on active pipe %d\n",
+			       info->pipe);
+			return -2;
+		}
+
+		/* Make sure buffer size is multiple of four */
+		len &= ~3;
+	}
+
+	while (len > 0) {
+		int mylen;
+
+		for (; desc < DBRI_NO_DESCS; desc++) {
+			if (!dbri->descs[desc].inuse)
+				break;
+		}
+		if (desc == DBRI_NO_DESCS) {
+			printk("DBRI: setup_descs: No descriptors\n");
+			return -1;
+		}
+
+		if (len > DBRI_TD_MAXCNT) {
+			mylen = DBRI_TD_MAXCNT;	/* 8KB - 1 */
+		} else {
+			mylen = len;
+		}
+		if (mylen > period) {
+			mylen = period;
+		}
+
+		dbri->descs[desc].inuse = 1;
+		dbri->descs[desc].next = -1;
+		dbri->dma->desc[desc].ba = dvma_buffer;
+		dbri->dma->desc[desc].nda = 0;
+
+		if (streamno == DBRI_PLAY) {
+			dbri->descs[desc].len = mylen;
+			dbri->dma->desc[desc].word1 = DBRI_TD_CNT(mylen);
+			dbri->dma->desc[desc].word4 = 0;
+			if (first_desc != -1)
+				dbri->dma->desc[desc].word1 |= DBRI_TD_M;
+		} else {
+			dbri->descs[desc].len = 0;
+			dbri->dma->desc[desc].word1 = 0;
+			dbri->dma->desc[desc].word4 =
+			    DBRI_RD_B | DBRI_RD_BCNT(mylen);
+		}
+
+		if (first_desc == -1) {
+			first_desc = desc;
+		} else {
+			dbri->descs[last_desc].next = desc;
+			dbri->dma->desc[last_desc].nda =
+			    dbri->dma_dvma + dbri_dma_off(desc, desc);
+		}
+
+		last_desc = desc;
+		dvma_buffer += mylen;
+		len -= mylen;
+	}
+
+	if (first_desc == -1 || last_desc == -1) {
+		printk("DBRI: setup_descs: Not enough descriptors available\n");
+		return -1;
+	}
+
+	dbri->dma->desc[last_desc].word1 &= ~DBRI_TD_M;
+	if (streamno == DBRI_PLAY) {
+		dbri->dma->desc[last_desc].word1 |=
+		    DBRI_TD_I | DBRI_TD_F | DBRI_TD_B;
+	}
+	dbri->pipes[info->pipe].first_desc = first_desc;
+	dbri->pipes[info->pipe].desc = first_desc;
+
+	for (desc = first_desc; desc != -1; desc = dbri->descs[desc].next) {
+		dprintk(D_DESC, "DESC %d: %08x %08x %08x %08x\n",
+			desc,
+			dbri->dma->desc[desc].word1,
+			dbri->dma->desc[desc].ba,
+			dbri->dma->desc[desc].nda, dbri->dma->desc[desc].word4);
+	}
+	return 0;
+}
+
+/*
+****************************************************************************
+************************** DBRI - CHI interface ****************************
+****************************************************************************
+
+The CHI is a four-wire (clock, frame sync, data in, data out) time-division
+multiplexed serial interface which the DBRI can operate in either master
+(give clock/frame sync) or slave (take clock/frame sync) mode.
+
+*/
+
+enum master_or_slave { CHImaster, CHIslave };
+
+static void reset_chi(snd_dbri_t * dbri, enum master_or_slave master_or_slave,
+		      int bits_per_frame)
+{
+	volatile s32 *cmd;
+	int val;
+	static int chi_initialized = 0;	/* FIXME: mutex? */
+
+	if (!chi_initialized) {
+
+		cmd = dbri_cmdlock(dbri, GetLock);
+
+		/* Set CHI Anchor: Pipe 16 */
+
+		val = D_DTS_VI | D_DTS_INS | D_DTS_PRVIN(16) | D_PIPE(16);
+		*(cmd++) = DBRI_CMD(D_DTS, 0, val);
+		*(cmd++) = D_TS_ANCHOR | D_TS_NEXT(16);
+		*(cmd++) = 0;
+
+		val = D_DTS_VO | D_DTS_INS | D_DTS_PRVOUT(16) | D_PIPE(16);
+		*(cmd++) = DBRI_CMD(D_DTS, 0, val);
+		*(cmd++) = 0;
+		*(cmd++) = D_TS_ANCHOR | D_TS_NEXT(16);
+
+		dbri->pipes[16].sdp = 1;
+		dbri->pipes[16].nextpipe = 16;
+		dbri->chi_in_pipe = 16;
+		dbri->chi_out_pipe = 16;
+
+#if 0
+		chi_initialized++;
+#endif
+	} else {
+		int pipe;
+
+		for (pipe = dbri->chi_in_pipe;
+		     pipe != 16; pipe = dbri->pipes[pipe].nextpipe) {
+			unlink_time_slot(dbri, pipe, PIPEinput,
+					 16, dbri->pipes[pipe].nextpipe);
+		}
+		for (pipe = dbri->chi_out_pipe;
+		     pipe != 16; pipe = dbri->pipes[pipe].nextpipe) {
+			unlink_time_slot(dbri, pipe, PIPEoutput,
+					 16, dbri->pipes[pipe].nextpipe);
+		}
+
+		dbri->chi_in_pipe = 16;
+		dbri->chi_out_pipe = 16;
+
+		cmd = dbri_cmdlock(dbri, GetLock);
+	}
+
+	if (master_or_slave == CHIslave) {
+		/* Setup DBRI for CHI Slave - receive clock, frame sync (FS)
+		 *
+		 * CHICM  = 0 (slave mode, 8 kHz frame rate)
+		 * IR     = give immediate CHI status interrupt
+		 * EN     = give CHI status interrupt upon change
+		 */
+		*(cmd++) = DBRI_CMD(D_CHI, 0, D_CHI_CHICM(0));
+	} else {
+		/* Setup DBRI for CHI Master - generate clock, FS
+		 *
+		 * BPF                          =  bits per 8 kHz frame
+		 * 12.288 MHz / CHICM_divisor   = clock rate
+		 * FD  =  1 - drive CHIFS on rising edge of CHICK
+		 */
+		int clockrate = bits_per_frame * 8;
+		int divisor = 12288 / clockrate;
+
+		if (divisor > 255 || divisor * clockrate != 12288)
+			printk("DBRI: illegal bits_per_frame in setup_chi\n");
+
+		*(cmd++) = DBRI_CMD(D_CHI, 0, D_CHI_CHICM(divisor) | D_CHI_FD
+				    | D_CHI_BPF(bits_per_frame));
+	}
+
+	dbri->chi_bpf = bits_per_frame;
+
+	/* CHI Data Mode
+	 *
+	 * RCE   =  0 - receive on falling edge of CHICK
+	 * XCE   =  1 - transmit on rising edge of CHICK
+	 * XEN   =  1 - enable transmitter
+	 * REN   =  1 - enable receiver
+	 */
+
+	*(cmd++) = DBRI_CMD(D_PAUSE, 0, 0);
+	*(cmd++) = DBRI_CMD(D_CDM, 0, D_CDM_XCE | D_CDM_XEN | D_CDM_REN);
+
+	dbri_cmdsend(dbri, cmd);
+}
+
+/*
+****************************************************************************
+*********************** CS4215 audio codec management **********************
+****************************************************************************
+
+In the standard SPARC audio configuration, the CS4215 codec is attached
+to the DBRI via the CHI interface and few of the DBRI's PIO pins.
+
+*/
+static void cs4215_setup_pipes(snd_dbri_t * dbri)
+{
+	/*
+	 * Data mode:
+	 * Pipe  4: Send timeslots 1-4 (audio data)
+	 * Pipe 20: Send timeslots 5-8 (part of ctrl data)
+	 * Pipe  6: Receive timeslots 1-4 (audio data)
+	 * Pipe 21: Receive timeslots 6-7. We can only receive 20 bits via
+	 *          interrupt, and the rest of the data (slot 5 and 8) is
+	 *          not relevant for us (only for doublechecking).
+	 *
+	 * Control mode:
+	 * Pipe 17: Send timeslots 1-4 (slots 5-8 are readonly)
+	 * Pipe 18: Receive timeslot 1 (clb).
+	 * Pipe 19: Receive timeslot 7 (version). 
+	 */
+
+	setup_pipe(dbri, 4, D_SDP_MEM | D_SDP_TO_SER | D_SDP_MSB);
+	setup_pipe(dbri, 20, D_SDP_FIXED | D_SDP_TO_SER | D_SDP_MSB);
+	setup_pipe(dbri, 6, D_SDP_MEM | D_SDP_FROM_SER | D_SDP_MSB);
+	setup_pipe(dbri, 21, D_SDP_FIXED | D_SDP_FROM_SER | D_SDP_MSB);
+
+	setup_pipe(dbri, 17, D_SDP_FIXED | D_SDP_TO_SER | D_SDP_MSB);
+	setup_pipe(dbri, 18, D_SDP_FIXED | D_SDP_FROM_SER | D_SDP_MSB);
+	setup_pipe(dbri, 19, D_SDP_FIXED | D_SDP_FROM_SER | D_SDP_MSB);
+}
+
+static int cs4215_init_data(struct cs4215 *mm)
+{
+	/*
+	 * No action, memory resetting only.
+	 *
+	 * Data Time Slot 5-8
+	 * Speaker,Line and Headphone enable. Gain set to the half.
+	 * Input is mike.
+	 */
+	mm->data[0] = CS4215_LO(0x20) | CS4215_HE | CS4215_LE;
+	mm->data[1] = CS4215_RO(0x20) | CS4215_SE;
+	mm->data[2] = CS4215_LG(0x8) | CS4215_IS | CS4215_PIO0 | CS4215_PIO1;
+	mm->data[3] = CS4215_RG(0x8) | CS4215_MA(0xf);
+
+	/*
+	 * Control Time Slot 1-4
+	 * 0: Default I/O voltage scale
+	 * 1: 8 bit ulaw, 8kHz, mono, high pass filter disabled
+	 * 2: Serial enable, CHI master, 128 bits per frame, clock 1
+	 * 3: Tests disabled
+	 */
+	mm->ctrl[0] = CS4215_RSRVD_1 | CS4215_MLB;
+	mm->ctrl[1] = CS4215_DFR_ULAW | CS4215_FREQ[0].csval;
+	mm->ctrl[2] = CS4215_XCLK | CS4215_BSEL_128 | CS4215_FREQ[0].xtal;
+	mm->ctrl[3] = 0;
+
+	mm->status = 0;
+	mm->version = 0xff;
+	mm->precision = 8;	/* For ULAW */
+	mm->channels = 2;
+
+	return 0;
+}
+
+static void cs4215_setdata(snd_dbri_t * dbri, int muted)
+{
+	if (muted) {
+		dbri->mm.data[0] |= 63;
+		dbri->mm.data[1] |= 63;
+		dbri->mm.data[2] &= ~15;
+		dbri->mm.data[3] &= ~15;
+	} else {
+		/* Start by setting the playback attenuation. */
+		dbri_streaminfo_t *info = &dbri->stream_info[DBRI_PLAY];
+		int left_gain = info->left_gain % 64;
+		int right_gain = info->right_gain % 64;
+
+		if (info->balance < DBRI_MID_BALANCE) {
+			right_gain *= info->balance;
+			right_gain /= DBRI_MID_BALANCE;
+		} else {
+			left_gain *= DBRI_RIGHT_BALANCE - info->balance;
+			left_gain /= DBRI_MID_BALANCE;
+		}
+
+		dbri->mm.data[0] &= ~0x3f;	/* Reset the volume bits */
+		dbri->mm.data[1] &= ~0x3f;
+		dbri->mm.data[0] |= (DBRI_MAX_VOLUME - left_gain);
+		dbri->mm.data[1] |= (DBRI_MAX_VOLUME - right_gain);
+
+		/* Now set the recording gain. */
+		info = &dbri->stream_info[DBRI_REC];
+		left_gain = info->left_gain % 16;
+		right_gain = info->right_gain % 16;
+		dbri->mm.data[2] |= CS4215_LG(left_gain);
+		dbri->mm.data[3] |= CS4215_RG(right_gain);
+	}
+
+	xmit_fixed(dbri, 20, *(int *)dbri->mm.data);
+}
+
+/*
+ * Set the CS4215 to data mode.
+ */
+static void cs4215_open(snd_dbri_t * dbri)
+{
+	int data_width;
+	u32 tmp;
+
+	dprintk(D_MM, "cs4215_open: %d channels, %d bits\n",
+		dbri->mm.channels, dbri->mm.precision);
+
+	/* Temporarily mute outputs, and wait 1/8000 sec (125 us)
+	 * to make sure this takes.  This avoids clicking noises.
+	 */
+
+	cs4215_setdata(dbri, 1);
+	udelay(125);
+
+	/*
+	 * Data mode:
+	 * Pipe  4: Send timeslots 1-4 (audio data)
+	 * Pipe 20: Send timeslots 5-8 (part of ctrl data)
+	 * Pipe  6: Receive timeslots 1-4 (audio data)
+	 * Pipe 21: Receive timeslots 6-7. We can only receive 20 bits via
+	 *          interrupt, and the rest of the data (slot 5 and 8) is
+	 *          not relevant for us (only for doublechecking).
+	 *
+	 * Just like in control mode, the time slots are all offset by eight
+	 * bits.  The CS4215, it seems, observes TSIN (the delayed signal)
+	 * even if it's the CHI master.  Don't ask me...
+	 */
+	tmp = sbus_readl(dbri->regs + REG0);
+	tmp &= ~(D_C);		/* Disable CHI */
+	sbus_writel(tmp, dbri->regs + REG0);
+
+	/* Switch CS4215 to data mode - set PIO3 to 1 */
+	sbus_writel(D_ENPIO | D_PIO1 | D_PIO3 |
+		    (dbri->mm.onboard ? D_PIO0 : D_PIO2), dbri->regs + REG2);
+
+	reset_chi(dbri, CHIslave, 128);
+
+	/* Note: this next doesn't work for 8-bit stereo, because the two
+	 * channels would be on timeslots 1 and 3, with 2 and 4 idle.
+	 * (See CS4215 datasheet Fig 15)
+	 *
+	 * DBRI non-contiguous mode would be required to make this work.
+	 */
+	data_width = dbri->mm.channels * dbri->mm.precision;
+
+	link_time_slot(dbri, 20, PIPEoutput, 16, 32, dbri->mm.offset + 32);
+	link_time_slot(dbri, 4, PIPEoutput, 16, data_width, dbri->mm.offset);
+	link_time_slot(dbri, 6, PIPEinput, 16, data_width, dbri->mm.offset);
+	link_time_slot(dbri, 21, PIPEinput, 16, 16, dbri->mm.offset + 40);
+
+	/* FIXME: enable CHI after _setdata? */
+	tmp = sbus_readl(dbri->regs + REG0);
+	tmp |= D_C;		/* Enable CHI */
+	sbus_writel(tmp, dbri->regs + REG0);
+
+	cs4215_setdata(dbri, 0);
+}
+
+/*
+ * Send the control information (i.e. audio format)
+ */
+static int cs4215_setctrl(snd_dbri_t * dbri)
+{
+	int i, val;
+	u32 tmp;
+
+	/* FIXME - let the CPU do something useful during these delays */
+
+	/* Temporarily mute outputs, and wait 1/8000 sec (125 us)
+	 * to make sure this takes.  This avoids clicking noises.
+	 */
+
+	cs4215_setdata(dbri, 1);
+	udelay(125);
+
+	/*
+	 * Enable Control mode: Set DBRI's PIO3 (4215's D/~C) to 0, then wait
+	 * 12 cycles <= 12/(5512.5*64) sec = 34.01 usec
+	 */
+	val = D_ENPIO | D_PIO1 | (dbri->mm.onboard ? D_PIO0 : D_PIO2);
+	sbus_writel(val, dbri->regs + REG2);
+	dprintk(D_MM, "cs4215_setctrl: reg2=0x%x\n", val);
+	udelay(34);
+
+	/* In Control mode, the CS4215 is a slave device, so the DBRI must
+	 * operate as CHI master, supplying clocking and frame synchronization.
+	 *
+	 * In Data mode, however, the CS4215 must be CHI master to insure
+	 * that its data stream is synchronous with its codec.
+	 *
+	 * The upshot of all this?  We start by putting the DBRI into master
+	 * mode, program the CS4215 in Control mode, then switch the CS4215
+	 * into Data mode and put the DBRI into slave mode.  Various timing
+	 * requirements must be observed along the way.
+	 *
+	 * Oh, and one more thing, on a SPARCStation 20 (and maybe
+	 * others?), the addressing of the CS4215's time slots is
+	 * offset by eight bits, so we add eight to all the "cycle"
+	 * values in the Define Time Slot (DTS) commands.  This is
+	 * done in hardware by a TI 248 that delays the DBRI->4215
+	 * frame sync signal by eight clock cycles.  Anybody know why?
+	 */
+	tmp = sbus_readl(dbri->regs + REG0);
+	tmp &= ~D_C;		/* Disable CHI */
+	sbus_writel(tmp, dbri->regs + REG0);
+
+	reset_chi(dbri, CHImaster, 128);
+
+	/*
+	 * Control mode:
+	 * Pipe 17: Send timeslots 1-4 (slots 5-8 are readonly)
+	 * Pipe 18: Receive timeslot 1 (clb).
+	 * Pipe 19: Receive timeslot 7 (version). 
+	 */
+
+	link_time_slot(dbri, 17, PIPEoutput, 16, 32, dbri->mm.offset);
+	link_time_slot(dbri, 18, PIPEinput, 16, 8, dbri->mm.offset);
+	link_time_slot(dbri, 19, PIPEinput, 16, 8, dbri->mm.offset + 48);
+
+	/* Wait for the chip to echo back CLB (Control Latch Bit) as zero */
+	dbri->mm.ctrl[0] &= ~CS4215_CLB;
+	xmit_fixed(dbri, 17, *(int *)dbri->mm.ctrl);
+
+	tmp = sbus_readl(dbri->regs + REG0);
+	tmp |= D_C;		/* Enable CHI */
+	sbus_writel(tmp, dbri->regs + REG0);
+
+	for (i = 64; ((dbri->mm.status & 0xe4) != 0x20); --i) {
+		udelay(125);
+	}
+	if (i == 0) {
+		dprintk(D_MM, "CS4215 didn't respond to CLB (0x%02x)\n",
+			dbri->mm.status);
+		return -1;
+	}
+
+	/* Disable changes to our copy of the version number, as we are about
+	 * to leave control mode.
+	 */
+	recv_fixed(dbri, 19, NULL);
+
+	/* Terminate CS4215 control mode - data sheet says
+	 * "Set CLB=1 and send two more frames of valid control info"
+	 */
+	dbri->mm.ctrl[0] |= CS4215_CLB;
+	xmit_fixed(dbri, 17, *(int *)dbri->mm.ctrl);
+
+	/* Two frames of control info @ 8kHz frame rate = 250 us delay */
+	udelay(250);
+
+	cs4215_setdata(dbri, 0);
+
+	return 0;
+}
+
+/*
+ * Setup the codec with the sampling rate, audio format and number of
+ * channels.
+ * As part of the process we resend the settings for the data
+ * timeslots as well.
+ */
+static int cs4215_prepare(snd_dbri_t * dbri, unsigned int rate,
+			  snd_pcm_format_t format, unsigned int channels)
+{
+	int freq_idx;
+	int ret = 0;
+
+	/* Lookup index for this rate */
+	for (freq_idx = 0; CS4215_FREQ[freq_idx].freq != 0; freq_idx++) {
+		if (CS4215_FREQ[freq_idx].freq == rate)
+			break;
+	}
+	if (CS4215_FREQ[freq_idx].freq != rate) {
+		printk(KERN_WARNING "DBRI: Unsupported rate %d Hz\n", rate);
+		return -1;
+	}
+
+	switch (format) {
+	case SNDRV_PCM_FORMAT_MU_LAW:
+		dbri->mm.ctrl[1] = CS4215_DFR_ULAW;
+		dbri->mm.precision = 8;
+		break;
+	case SNDRV_PCM_FORMAT_A_LAW:
+		dbri->mm.ctrl[1] = CS4215_DFR_ALAW;
+		dbri->mm.precision = 8;
+		break;
+	case SNDRV_PCM_FORMAT_U8:
+		dbri->mm.ctrl[1] = CS4215_DFR_LINEAR8;
+		dbri->mm.precision = 8;
+		break;
+	case SNDRV_PCM_FORMAT_S16_BE:
+		dbri->mm.ctrl[1] = CS4215_DFR_LINEAR16;
+		dbri->mm.precision = 16;
+		break;
+	default:
+		printk(KERN_WARNING "DBRI: Unsupported format %d\n", format);
+		return -1;
+	}
+
+	/* Add rate parameters */
+	dbri->mm.ctrl[1] |= CS4215_FREQ[freq_idx].csval;
+	dbri->mm.ctrl[2] = CS4215_XCLK |
+	    CS4215_BSEL_128 | CS4215_FREQ[freq_idx].xtal;
+
+	dbri->mm.channels = channels;
+	/* Stereo bit: 8 bit stereo not working yet. */
+	if ((channels > 1) && (dbri->mm.precision == 16))
+		dbri->mm.ctrl[1] |= CS4215_DFR_STEREO;
+
+	ret = cs4215_setctrl(dbri);
+	if (ret == 0)
+		cs4215_open(dbri);	/* set codec to data mode */
+
+	return ret;
+}
+
+/*
+ *
+ */
+static int cs4215_init(snd_dbri_t * dbri)
+{
+	u32 reg2 = sbus_readl(dbri->regs + REG2);
+	dprintk(D_MM, "cs4215_init: reg2=0x%x\n", reg2);
+
+	/* Look for the cs4215 chips */
+	if (reg2 & D_PIO2) {
+		dprintk(D_MM, "Onboard CS4215 detected\n");
+		dbri->mm.onboard = 1;
+	}
+	if (reg2 & D_PIO0) {
+		dprintk(D_MM, "Speakerbox detected\n");
+		dbri->mm.onboard = 0;
+
+		if (reg2 & D_PIO2) {
+			printk(KERN_INFO "DBRI: Using speakerbox / "
+			       "ignoring onboard mmcodec.\n");
+			sbus_writel(D_ENPIO2, dbri->regs + REG2);
+		}
+	}
+
+	if (!(reg2 & (D_PIO0 | D_PIO2))) {
+		printk(KERN_ERR "DBRI: no mmcodec found.\n");
+		return -EIO;
+	}
+
+	cs4215_setup_pipes(dbri);
+
+	cs4215_init_data(&dbri->mm);
+
+	/* Enable capture of the status & version timeslots. */
+	recv_fixed(dbri, 18, &dbri->mm.status);
+	recv_fixed(dbri, 19, &dbri->mm.version);
+
+	dbri->mm.offset = dbri->mm.onboard ? 0 : 8;
+	if (cs4215_setctrl(dbri) == -1 || dbri->mm.version == 0xff) {
+		dprintk(D_MM, "CS4215 failed probe at offset %d\n",
+			dbri->mm.offset);
+		return -EIO;
+	}
+	dprintk(D_MM, "Found CS4215 at offset %d\n", dbri->mm.offset);
+
+	return 0;
+}
+
+/*
+****************************************************************************
+*************************** DBRI interrupt handler *************************
+****************************************************************************
+
+The DBRI communicates with the CPU mainly via a circular interrupt
+buffer.  When an interrupt is signaled, the CPU walks through the
+buffer and calls dbri_process_one_interrupt() for each interrupt word.
+Complicated interrupts are handled by dedicated functions (which
+appear first in this file).  Any pending interrupts can be serviced by
+calling dbri_process_interrupt_buffer(), which works even if the CPU's
+interrupts are disabled.  This function is used by dbri_cmdsend()
+to make sure we're synced up with the chip after each command sequence,
+even if we're running cli'ed.
+
+*/
+
+/* xmit_descs()
+ *
+ * Transmit the current TD's for recording/playing, if needed.
+ * For playback, ALSA has filled the DMA memory with new data (we hope).
+ */
+static void xmit_descs(unsigned long data)
+{
+	snd_dbri_t *dbri = (snd_dbri_t *) data;
+	dbri_streaminfo_t *info;
+	volatile s32 *cmd;
+	unsigned long flags;
+	int first_td;
+
+	if (dbri == NULL)
+		return;		/* Disabled */
+
+	/* First check the recording stream for buffer overflow */
+	info = &dbri->stream_info[DBRI_REC];
+	spin_lock_irqsave(&dbri->lock, flags);
+
+	if ((info->left >= info->size) && (info->pipe >= 0)) {
+		first_td = dbri->pipes[info->pipe].first_desc;
+
+		dprintk(D_DESC, "xmit_descs rec @ TD %d\n", first_td);
+
+		/* Stream could be closed by the time we run. */
+		if (first_td < 0) {
+			goto play;
+		}
+
+		cmd = dbri_cmdlock(dbri, NoGetLock);
+		*(cmd++) = DBRI_CMD(D_SDP, 0,
+				    dbri->pipes[info->pipe].sdp
+				    | D_SDP_P | D_SDP_EVERY | D_SDP_C);
+		*(cmd++) = dbri->dma_dvma + dbri_dma_off(desc, first_td);
+		dbri_cmdsend(dbri, cmd);
+
+		/* Reset our admin of the pipe & bytes read. */
+		dbri->pipes[info->pipe].desc = first_td;
+		info->left = 0;
+	}
+
+play:
+	spin_unlock_irqrestore(&dbri->lock, flags);
+
+	/* Now check the playback stream for buffer underflow */
+	info = &dbri->stream_info[DBRI_PLAY];
+	spin_lock_irqsave(&dbri->lock, flags);
+
+	if ((info->left <= 0) && (info->pipe >= 0)) {
+		first_td = dbri->pipes[info->pipe].first_desc;
+
+		dprintk(D_DESC, "xmit_descs play @ TD %d\n", first_td);
+
+		/* Stream could be closed by the time we run. */
+		if (first_td < 0) {
+			spin_unlock_irqrestore(&dbri->lock, flags);
+			return;
+		}
+
+		cmd = dbri_cmdlock(dbri, NoGetLock);
+		*(cmd++) = DBRI_CMD(D_SDP, 0,
+				    dbri->pipes[info->pipe].sdp
+				    | D_SDP_P | D_SDP_EVERY | D_SDP_C);
+		*(cmd++) = dbri->dma_dvma + dbri_dma_off(desc, first_td);
+		dbri_cmdsend(dbri, cmd);
+
+		/* Reset our admin of the pipe & bytes written. */
+		dbri->pipes[info->pipe].desc = first_td;
+		info->left = info->size;
+	}
+	spin_unlock_irqrestore(&dbri->lock, flags);
+}
+
+DECLARE_TASKLET(xmit_descs_task, xmit_descs, 0);
+
+/* transmission_complete_intr()
+ *
+ * Called by main interrupt handler when DBRI signals transmission complete
+ * on a pipe (interrupt triggered by the B bit in a transmit descriptor).
+ *
+ * Walks through the pipe's list of transmit buffer descriptors, releasing
+ * each one's DMA buffer (if present), flagging the descriptor available,
+ * and signaling its callback routine (if present), before proceeding
+ * to the next one.  Stops when the first descriptor is found without
+ * TBC (Transmit Buffer Complete) set, or we've run through them all.
+ */
+
+static void transmission_complete_intr(snd_dbri_t * dbri, int pipe)
+{
+	dbri_streaminfo_t *info;
+	int td;
+	int status;
+
+	info = &dbri->stream_info[DBRI_PLAY];
+
+	td = dbri->pipes[pipe].desc;
+	while (td >= 0) {
+		if (td >= DBRI_NO_DESCS) {
+			printk(KERN_ERR "DBRI: invalid td on pipe %d\n", pipe);
+			return;
+		}
+
+		status = DBRI_TD_STATUS(dbri->dma->desc[td].word4);
+		if (!(status & DBRI_TD_TBC)) {
+			break;
+		}
+
+		dprintk(D_INT, "TD %d, status 0x%02x\n", td, status);
+
+		dbri->dma->desc[td].word4 = 0;	/* Reset it for next time. */
+		info->offset += dbri->descs[td].len;
+		info->left -= dbri->descs[td].len;
+
+		/* On the last TD, transmit them all again. */
+		if (dbri->descs[td].next == -1) {
+			if (info->left > 0) {
+				printk(KERN_WARNING
+				       "%d bytes left after last transfer.\n",
+				       info->left);
+				info->left = 0;
+			}
+			tasklet_schedule(&xmit_descs_task);
+		}
+
+		td = dbri->descs[td].next;
+		dbri->pipes[pipe].desc = td;
+	}
+
+	/* Notify ALSA */
+	if (spin_is_locked(&dbri->lock)) {
+		spin_unlock(&dbri->lock);
+		snd_pcm_period_elapsed(info->substream);
+		spin_lock(&dbri->lock);
+	} else
+		snd_pcm_period_elapsed(info->substream);
+}
+
+static void reception_complete_intr(snd_dbri_t * dbri, int pipe)
+{
+	dbri_streaminfo_t *info;
+	int rd = dbri->pipes[pipe].desc;
+	s32 status;
+
+	if (rd < 0 || rd >= DBRI_NO_DESCS) {
+		printk(KERN_ERR "DBRI: invalid rd on pipe %d\n", pipe);
+		return;
+	}
+
+	dbri->descs[rd].inuse = 0;
+	dbri->pipes[pipe].desc = dbri->descs[rd].next;
+	status = dbri->dma->desc[rd].word1;
+	dbri->dma->desc[rd].word1 = 0;	/* Reset it for next time. */
+
+	info = &dbri->stream_info[DBRI_REC];
+	info->offset += DBRI_RD_CNT(status);
+	info->left += DBRI_RD_CNT(status);
+
+	/* FIXME: Check status */
+
+	dprintk(D_INT, "Recv RD %d, status 0x%02x, len %d\n",
+		rd, DBRI_RD_STATUS(status), DBRI_RD_CNT(status));
+
+	/* On the last TD, transmit them all again. */
+	if (dbri->descs[rd].next == -1) {
+		if (info->left > info->size) {
+			printk(KERN_WARNING
+			       "%d bytes recorded in %d size buffer.\n",
+			       info->left, info->size);
+		}
+		tasklet_schedule(&xmit_descs_task);
+	}
+
+	/* Notify ALSA */
+	if (spin_is_locked(&dbri->lock)) {
+		spin_unlock(&dbri->lock);
+		snd_pcm_period_elapsed(info->substream);
+		spin_lock(&dbri->lock);
+	} else
+		snd_pcm_period_elapsed(info->substream);
+}
+
+static void dbri_process_one_interrupt(snd_dbri_t * dbri, int x)
+{
+	int val = D_INTR_GETVAL(x);
+	int channel = D_INTR_GETCHAN(x);
+	int command = D_INTR_GETCMD(x);
+	int code = D_INTR_GETCODE(x);
+#ifdef DBRI_DEBUG
+	int rval = D_INTR_GETRVAL(x);
+#endif
+
+	if (channel == D_INTR_CMD) {
+		dprintk(D_CMD, "INTR: Command: %-5s  Value:%d\n",
+			cmds[command], val);
+	} else {
+		dprintk(D_INT, "INTR: Chan:%d Code:%d Val:%#x\n",
+			channel, code, rval);
+	}
+
+	if (channel == D_INTR_CMD && command == D_WAIT) {
+		dbri->wait_seen++;
+		return;
+	}
+
+	switch (code) {
+	case D_INTR_BRDY:
+		reception_complete_intr(dbri, channel);
+		break;
+	case D_INTR_XCMP:
+	case D_INTR_MINT:
+		transmission_complete_intr(dbri, channel);
+		break;
+	case D_INTR_UNDR:
+		/* UNDR - Transmission underrun
+		 * resend SDP command with clear pipe bit (C) set
+		 */
+		{
+			volatile s32 *cmd;
+
+			int pipe = channel;
+			int td = dbri->pipes[pipe].desc;
+
+			dbri->dma->desc[td].word4 = 0;
+			cmd = dbri_cmdlock(dbri, NoGetLock);
+			*(cmd++) = DBRI_CMD(D_SDP, 0,
+					    dbri->pipes[pipe].sdp
+					    | D_SDP_P | D_SDP_C | D_SDP_2SAME);
+			*(cmd++) = dbri->dma_dvma + dbri_dma_off(desc, td);
+			dbri_cmdsend(dbri, cmd);
+		}
+		break;
+	case D_INTR_FXDT:
+		/* FXDT - Fixed data change */
+		if (dbri->pipes[channel].sdp & D_SDP_MSB)
+			val = reverse_bytes(val, dbri->pipes[channel].length);
+
+		if (dbri->pipes[channel].recv_fixed_ptr)
+			*(dbri->pipes[channel].recv_fixed_ptr) = val;
+		break;
+	default:
+		if (channel != D_INTR_CMD)
+			printk(KERN_WARNING
+			       "DBRI: Ignored Interrupt: %d (0x%x)\n", code, x);
+	}
+}
+
+/* dbri_process_interrupt_buffer advances through the DBRI's interrupt
+ * buffer until it finds a zero word (indicating nothing more to do
+ * right now).  Non-zero words require processing and are handed off
+ * to dbri_process_one_interrupt AFTER advancing the pointer.  This
+ * order is important since we might recurse back into this function
+ * and need to make sure the pointer has been advanced first.
+ */
+static void dbri_process_interrupt_buffer(snd_dbri_t * dbri)
+{
+	s32 x;
+
+	while ((x = dbri->dma->intr[dbri->dbri_irqp]) != 0) {
+		dbri->dma->intr[dbri->dbri_irqp] = 0;
+		dbri->dbri_irqp++;
+		if (dbri->dbri_irqp == (DBRI_NO_INTS * DBRI_INT_BLK))
+			dbri->dbri_irqp = 1;
+		else if ((dbri->dbri_irqp & (DBRI_INT_BLK - 1)) == 0)
+			dbri->dbri_irqp++;
+
+		dbri_process_one_interrupt(dbri, x);
+	}
+}
+
+static irqreturn_t snd_dbri_interrupt(int irq, void *dev_id,
+				      struct pt_regs *regs)
+{
+	snd_dbri_t *dbri = dev_id;
+	static int errcnt = 0;
+	int x;
+
+	if (dbri == NULL)
+		return IRQ_NONE;
+	spin_lock(&dbri->lock);
+
+	/*
+	 * Read it, so the interrupt goes away.
+	 */
+	x = sbus_readl(dbri->regs + REG1);
+
+	if (x & (D_MRR | D_MLE | D_LBG | D_MBE)) {
+		u32 tmp;
+
+		if (x & D_MRR)
+			printk(KERN_ERR
+			       "DBRI: Multiple Error Ack on SBus reg1=0x%x\n",
+			       x);
+		if (x & D_MLE)
+			printk(KERN_ERR
+			       "DBRI: Multiple Late Error on SBus reg1=0x%x\n",
+			       x);
+		if (x & D_LBG)
+			printk(KERN_ERR
+			       "DBRI: Lost Bus Grant on SBus reg1=0x%x\n", x);
+		if (x & D_MBE)
+			printk(KERN_ERR
+			       "DBRI: Burst Error on SBus reg1=0x%x\n", x);
+
+		/* Some of these SBus errors cause the chip's SBus circuitry
+		 * to be disabled, so just re-enable and try to keep going.
+		 *
+		 * The only one I've seen is MRR, which will be triggered
+		 * if you let a transmit pipe underrun, then try to CDP it.
+		 *
+		 * If these things persist, we should probably reset
+		 * and re-init the chip.
+		 */
+		if ((++errcnt) % 10 == 0) {
+			dprintk(D_INT, "Interrupt errors exceeded.\n");
+			dbri_reset(dbri);
+		} else {
+			tmp = sbus_readl(dbri->regs + REG0);
+			tmp &= ~(D_D);
+			sbus_writel(tmp, dbri->regs + REG0);
+		}
+	}
+
+	dbri_process_interrupt_buffer(dbri);
+
+	/* FIXME: Write 0 into regs to ACK interrupt */
+
+	spin_unlock(&dbri->lock);
+
+	return IRQ_HANDLED;
+}
+
+/****************************************************************************
+		PCM Interface
+****************************************************************************/
+static snd_pcm_hardware_t snd_dbri_pcm_hw = {
+	.info			= (SNDRV_PCM_INFO_MMAP |
+				   SNDRV_PCM_INFO_INTERLEAVED |
+				   SNDRV_PCM_INFO_BLOCK_TRANSFER |
+				   SNDRV_PCM_INFO_MMAP_VALID),
+	.formats		= SNDRV_PCM_FMTBIT_MU_LAW |
+				  SNDRV_PCM_FMTBIT_A_LAW |
+				  SNDRV_PCM_FMTBIT_U8 |
+				  SNDRV_PCM_FMTBIT_S16_BE,
+	.rates			= SNDRV_PCM_RATE_8000_48000,
+	.rate_min		= 8000,
+	.rate_max		= 48000,
+	.channels_min		= 1,
+	.channels_max		= 2,
+	.buffer_bytes_max	= (64 * 1024),
+	.period_bytes_min	= 1,
+	.period_bytes_max	= DBRI_TD_MAXCNT,
+	.periods_min		= 1,
+	.periods_max		= 1024,
+};
+
+static int snd_dbri_open(snd_pcm_substream_t * substream)
+{
+	snd_dbri_t *dbri = snd_pcm_substream_chip(substream);
+	snd_pcm_runtime_t *runtime = substream->runtime;
+	dbri_streaminfo_t *info = DBRI_STREAM(dbri, substream);
+	unsigned long flags;
+
+	dprintk(D_USR, "open audio output.\n");
+	runtime->hw = snd_dbri_pcm_hw;
+
+	spin_lock_irqsave(&dbri->lock, flags);
+	info->substream = substream;
+	info->left = 0;
+	info->offset = 0;
+	info->dvma_buffer = 0;
+	info->pipe = -1;
+	spin_unlock_irqrestore(&dbri->lock, flags);
+
+	cs4215_open(dbri);
+
+	return 0;
+}
+
+static int snd_dbri_close(snd_pcm_substream_t * substream)
+{
+	snd_dbri_t *dbri = snd_pcm_substream_chip(substream);
+	dbri_streaminfo_t *info = DBRI_STREAM(dbri, substream);
+
+	dprintk(D_USR, "close audio output.\n");
+	info->substream = NULL;
+	info->left = 0;
+	info->offset = 0;
+
+	return 0;
+}
+
+static int snd_dbri_hw_params(snd_pcm_substream_t * substream,
+			      snd_pcm_hw_params_t * hw_params)
+{
+	snd_pcm_runtime_t *runtime = substream->runtime;
+	snd_dbri_t *dbri = snd_pcm_substream_chip(substream);
+	dbri_streaminfo_t *info = DBRI_STREAM(dbri, substream);
+	int direction;
+	int ret;
+
+	/* set sampling rate, audio format and number of channels */
+	ret = cs4215_prepare(dbri, params_rate(hw_params),
+			     params_format(hw_params),
+			     params_channels(hw_params));
+	if (ret != 0)
+		return ret;
+
+	if ((ret = snd_pcm_lib_malloc_pages(substream,
+				params_buffer_bytes(hw_params))) < 0) {
+		snd_printk(KERN_ERR "malloc_pages failed with %d\n", ret);
+		return ret;
+	}
+
+	/* hw_params can get called multiple times. Only map the DMA once.
+	 */
+	if (info->dvma_buffer == 0) {
+		if (DBRI_STREAMNO(substream) == DBRI_PLAY)
+			direction = SBUS_DMA_TODEVICE;
+		else
+			direction = SBUS_DMA_FROMDEVICE;
+
+		info->dvma_buffer = sbus_map_single(dbri->sdev,
+					runtime->dma_area,
+					params_buffer_bytes(hw_params),
+					direction);
+	}
+
+	direction = params_buffer_bytes(hw_params);
+	dprintk(D_USR, "hw_params: %d bytes, dvma=%x\n",
+		direction, info->dvma_buffer);
+	return 0;
+}
+
+static int snd_dbri_hw_free(snd_pcm_substream_t * substream)
+{
+	snd_dbri_t *dbri = snd_pcm_substream_chip(substream);
+	dbri_streaminfo_t *info = DBRI_STREAM(dbri, substream);
+	int direction;
+	dprintk(D_USR, "hw_free.\n");
+
+	/* hw_free can get called multiple times. Only unmap the DMA once.
+	 */
+	if (info->dvma_buffer) {
+		if (DBRI_STREAMNO(substream) == DBRI_PLAY)
+			direction = SBUS_DMA_TODEVICE;
+		else
+			direction = SBUS_DMA_FROMDEVICE;
+
+		sbus_unmap_single(dbri->sdev, info->dvma_buffer,
+				  substream->runtime->buffer_size, direction);
+		info->dvma_buffer = 0;
+	}
+	info->pipe = -1;
+
+	return snd_pcm_lib_free_pages(substream);
+}
+
+static int snd_dbri_prepare(snd_pcm_substream_t * substream)
+{
+	snd_dbri_t *dbri = snd_pcm_substream_chip(substream);
+	dbri_streaminfo_t *info = DBRI_STREAM(dbri, substream);
+	snd_pcm_runtime_t *runtime = substream->runtime;
+	int ret;
+
+	info->size = snd_pcm_lib_buffer_bytes(substream);
+	if (DBRI_STREAMNO(substream) == DBRI_PLAY)
+		info->pipe = 4;	/* Send pipe */
+	else {
+		info->pipe = 6;	/* Receive pipe */
+		info->left = info->size;	/* To trigger submittal */
+	}
+
+	spin_lock_irq(&dbri->lock);
+
+	/* Setup the all the transmit/receive desciptors to cover the
+	 * whole DMA buffer.
+	 */
+	ret = setup_descs(dbri, DBRI_STREAMNO(substream),
+			  snd_pcm_lib_period_bytes(substream));
+
+	runtime->stop_threshold = DBRI_TD_MAXCNT / runtime->channels;
+
+	spin_unlock_irq(&dbri->lock);
+
+	dprintk(D_USR, "prepare audio output. %d bytes\n", info->size);
+	return ret;
+}
+
+static int snd_dbri_trigger(snd_pcm_substream_t * substream, int cmd)
+{
+	snd_dbri_t *dbri = snd_pcm_substream_chip(substream);
+	dbri_streaminfo_t *info = DBRI_STREAM(dbri, substream);
+	int ret = 0;
+
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+		dprintk(D_USR, "start audio, period is %d bytes\n",
+			(int)snd_pcm_lib_period_bytes(substream));
+		/* Enable & schedule the tasklet that re-submits the TDs. */
+		xmit_descs_task.data = (unsigned long)dbri;
+		tasklet_schedule(&xmit_descs_task);
+		break;
+	case SNDRV_PCM_TRIGGER_STOP:
+		dprintk(D_USR, "stop audio.\n");
+		/* Make the tasklet bail out immediately. */
+		xmit_descs_task.data = 0;
+		reset_pipe(dbri, info->pipe);
+		break;
+	default:
+		ret = -EINVAL;
+	}
+
+	return ret;
+}
+
+static snd_pcm_uframes_t snd_dbri_pointer(snd_pcm_substream_t * substream)
+{
+	snd_dbri_t *dbri = snd_pcm_substream_chip(substream);
+	dbri_streaminfo_t *info = DBRI_STREAM(dbri, substream);
+	snd_pcm_uframes_t ret;
+
+	ret = bytes_to_frames(substream->runtime, info->offset)
+		% substream->runtime->buffer_size;
+	dprintk(D_USR, "I/O pointer: %ld frames, %d bytes left.\n",
+		ret, info->left);
+	return ret;
+}
+
+static snd_pcm_ops_t snd_dbri_ops = {
+	.open = snd_dbri_open,
+	.close = snd_dbri_close,
+	.ioctl = snd_pcm_lib_ioctl,
+	.hw_params = snd_dbri_hw_params,
+	.hw_free = snd_dbri_hw_free,
+	.prepare = snd_dbri_prepare,
+	.trigger = snd_dbri_trigger,
+	.pointer = snd_dbri_pointer,
+};
+
+static int __devinit snd_dbri_pcm(snd_dbri_t * dbri)
+{
+	snd_pcm_t *pcm;
+	int err;
+
+	if ((err = snd_pcm_new(dbri->card,
+			       /* ID */		    "sun_dbri",
+			       /* device */	    0,
+			       /* playback count */ 1,
+			       /* capture count */  1, &pcm)) < 0)
+		return err;
+	snd_assert(pcm != NULL, return -EINVAL);
+
+	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_dbri_ops);
+	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_dbri_ops);
+
+	pcm->private_data = dbri;
+	pcm->info_flags = 0;
+	strcpy(pcm->name, dbri->card->shortname);
+	dbri->pcm = pcm;
+
+	if ((err = snd_pcm_lib_preallocate_pages_for_all(pcm,
+			SNDRV_DMA_TYPE_CONTINUOUS,
+			snd_dma_continuous_data(GFP_KERNEL),
+			64 * 1024, 64 * 1024)) < 0) {
+		return err;
+	}
+
+	return 0;
+}
+
+/*****************************************************************************
+			Mixer interface
+*****************************************************************************/
+
+static int snd_cs4215_info_volume(snd_kcontrol_t * kcontrol,
+				  snd_ctl_elem_info_t * uinfo)
+{
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+	uinfo->count = 2;
+	uinfo->value.integer.min = 0;
+	if (kcontrol->private_value == DBRI_PLAY) {
+		uinfo->value.integer.max = DBRI_MAX_VOLUME;
+	} else {
+		uinfo->value.integer.max = DBRI_MAX_GAIN;
+	}
+	return 0;
+}
+
+static int snd_cs4215_get_volume(snd_kcontrol_t * kcontrol,
+				 snd_ctl_elem_value_t * ucontrol)
+{
+	snd_dbri_t *dbri = snd_kcontrol_chip(kcontrol);
+	dbri_streaminfo_t *info;
+	snd_assert(dbri != NULL, return -EINVAL);
+	info = &dbri->stream_info[kcontrol->private_value];
+	snd_assert(info != NULL, return -EINVAL);
+
+	ucontrol->value.integer.value[0] = info->left_gain;
+	ucontrol->value.integer.value[1] = info->right_gain;
+	return 0;
+}
+
+static int snd_cs4215_put_volume(snd_kcontrol_t * kcontrol,
+				 snd_ctl_elem_value_t * ucontrol)
+{
+	snd_dbri_t *dbri = snd_kcontrol_chip(kcontrol);
+	dbri_streaminfo_t *info = &dbri->stream_info[kcontrol->private_value];
+	unsigned long flags;
+	int changed = 0;
+
+	if (info->left_gain != ucontrol->value.integer.value[0]) {
+		info->left_gain = ucontrol->value.integer.value[0];
+		changed = 1;
+	}
+	if (info->right_gain != ucontrol->value.integer.value[1]) {
+		info->right_gain = ucontrol->value.integer.value[1];
+		changed = 1;
+	}
+	if (changed == 1) {
+		/* First mute outputs, and wait 1/8000 sec (125 us)
+		 * to make sure this takes.  This avoids clicking noises.
+		 */
+		spin_lock_irqsave(&dbri->lock, flags);
+
+		cs4215_setdata(dbri, 1);
+		udelay(125);
+		cs4215_setdata(dbri, 0);
+
+		spin_unlock_irqrestore(&dbri->lock, flags);
+	}
+	return changed;
+}
+
+static int snd_cs4215_info_single(snd_kcontrol_t * kcontrol,
+				  snd_ctl_elem_info_t * uinfo)
+{
+	int mask = (kcontrol->private_value >> 16) & 0xff;
+
+	uinfo->type = (mask == 1) ?
+	    SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
+	uinfo->count = 1;
+	uinfo->value.integer.min = 0;
+	uinfo->value.integer.max = mask;
+	return 0;
+}
+
+static int snd_cs4215_get_single(snd_kcontrol_t * kcontrol,
+				 snd_ctl_elem_value_t * ucontrol)
+{
+	snd_dbri_t *dbri = snd_kcontrol_chip(kcontrol);
+	int elem = kcontrol->private_value & 0xff;
+	int shift = (kcontrol->private_value >> 8) & 0xff;
+	int mask = (kcontrol->private_value >> 16) & 0xff;
+	int invert = (kcontrol->private_value >> 24) & 1;
+	snd_assert(dbri != NULL, return -EINVAL);
+
+	if (elem < 4) {
+		ucontrol->value.integer.value[0] =
+		    (dbri->mm.data[elem] >> shift) & mask;
+	} else {
+		ucontrol->value.integer.value[0] =
+		    (dbri->mm.ctrl[elem - 4] >> shift) & mask;
+	}
+
+	if (invert == 1) {
+		ucontrol->value.integer.value[0] =
+		    mask - ucontrol->value.integer.value[0];
+	}
+	return 0;
+}
+
+static int snd_cs4215_put_single(snd_kcontrol_t * kcontrol,
+				 snd_ctl_elem_value_t * ucontrol)
+{
+	snd_dbri_t *dbri = snd_kcontrol_chip(kcontrol);
+	unsigned long flags;
+	int elem = kcontrol->private_value & 0xff;
+	int shift = (kcontrol->private_value >> 8) & 0xff;
+	int mask = (kcontrol->private_value >> 16) & 0xff;
+	int invert = (kcontrol->private_value >> 24) & 1;
+	int changed = 0;
+	unsigned short val;
+	snd_assert(dbri != NULL, return -EINVAL);
+
+	val = (ucontrol->value.integer.value[0] & mask);
+	if (invert == 1)
+		val = mask - val;
+	val <<= shift;
+
+	if (elem < 4) {
+		dbri->mm.data[elem] = (dbri->mm.data[elem] &
+				       ~(mask << shift)) | val;
+		changed = (val != dbri->mm.data[elem]);
+	} else {
+		dbri->mm.ctrl[elem - 4] = (dbri->mm.ctrl[elem - 4] &
+					   ~(mask << shift)) | val;
+		changed = (val != dbri->mm.ctrl[elem - 4]);
+	}
+
+	dprintk(D_GEN, "put_single: mask=0x%x, changed=%d, "
+		"mixer-value=%ld, mm-value=0x%x\n",
+		mask, changed, ucontrol->value.integer.value[0],
+		dbri->mm.data[elem & 3]);
+
+	if (changed) {
+		/* First mute outputs, and wait 1/8000 sec (125 us)
+		 * to make sure this takes.  This avoids clicking noises.
+		 */
+		spin_lock_irqsave(&dbri->lock, flags);
+
+		cs4215_setdata(dbri, 1);
+		udelay(125);
+		cs4215_setdata(dbri, 0);
+
+		spin_unlock_irqrestore(&dbri->lock, flags);
+	}
+	return changed;
+}
+
+/* Entries 0-3 map to the 4 data timeslots, entries 4-7 map to the 4 control
+   timeslots. Shift is the bit offset in the timeslot, mask defines the
+   number of bits. invert is a boolean for use with attenuation.
+ */
+#define CS4215_SINGLE(xname, entry, shift, mask, invert) \
+{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
+  .info = snd_cs4215_info_single, \
+  .get = snd_cs4215_get_single, .put = snd_cs4215_put_single, \
+  .private_value = entry | (shift << 8) | (mask << 16) | (invert << 24) },
+
+static snd_kcontrol_new_t dbri_controls[] __devinitdata = {
+	{
+	 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	 .name  = "Playback Volume",
+	 .info  = snd_cs4215_info_volume,
+	 .get   = snd_cs4215_get_volume,
+	 .put   = snd_cs4215_put_volume,
+	 .private_value = DBRI_PLAY,
+	 },
+	CS4215_SINGLE("Headphone switch", 0, 7, 1, 0)
+	CS4215_SINGLE("Line out switch", 0, 6, 1, 0)
+	CS4215_SINGLE("Speaker switch", 1, 6, 1, 0)
+	{
+	 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	 .name  = "Capture Volume",
+	 .info  = snd_cs4215_info_volume,
+	 .get   = snd_cs4215_get_volume,
+	 .put   = snd_cs4215_put_volume,
+	 .private_value = DBRI_REC,
+	 },
+	/* FIXME: mic/line switch */
+	CS4215_SINGLE("Line in switch", 2, 4, 1, 0)
+	CS4215_SINGLE("High Pass Filter switch", 5, 7, 1, 0)
+	CS4215_SINGLE("Monitor Volume", 3, 4, 0xf, 1)
+	CS4215_SINGLE("Mic boost", 4, 4, 1, 1)
+};
+
+#define NUM_CS4215_CONTROLS (sizeof(dbri_controls)/sizeof(snd_kcontrol_new_t))
+
+static int __init snd_dbri_mixer(snd_dbri_t * dbri)
+{
+	snd_card_t *card;
+	int idx, err;
+
+	snd_assert(dbri != NULL && dbri->card != NULL, return -EINVAL);
+
+	card = dbri->card;
+	strcpy(card->mixername, card->shortname);
+
+	for (idx = 0; idx < NUM_CS4215_CONTROLS; idx++) {
+		if ((err = snd_ctl_add(card,
+				       snd_ctl_new1(&dbri_controls[idx],
+						    dbri))) < 0)
+			return err;
+	}
+
+	for (idx = DBRI_REC; idx < DBRI_NO_STREAMS; idx++) {
+		dbri->stream_info[idx].left_gain = 0;
+		dbri->stream_info[idx].right_gain = 0;
+		dbri->stream_info[idx].balance = DBRI_MID_BALANCE;
+	}
+
+	return 0;
+}
+
+/****************************************************************************
+			/proc interface
+****************************************************************************/
+static void dbri_regs_read(snd_info_entry_t * entry, snd_info_buffer_t * buffer)
+{
+	snd_dbri_t *dbri = entry->private_data;
+
+	snd_iprintf(buffer, "REG0: 0x%x\n", sbus_readl(dbri->regs + REG0));
+	snd_iprintf(buffer, "REG2: 0x%x\n", sbus_readl(dbri->regs + REG2));
+	snd_iprintf(buffer, "REG8: 0x%x\n", sbus_readl(dbri->regs + REG8));
+	snd_iprintf(buffer, "REG9: 0x%x\n", sbus_readl(dbri->regs + REG9));
+}
+
+#ifdef DBRI_DEBUG
+static void dbri_debug_read(snd_info_entry_t * entry,
+			    snd_info_buffer_t * buffer)
+{
+	snd_dbri_t *dbri = entry->private_data;
+	int pipe;
+	snd_iprintf(buffer, "debug=%d\n", dbri_debug);
+
+	snd_iprintf(buffer, "CHI pipe in=%d, out=%d\n",
+		    dbri->chi_in_pipe, dbri->chi_out_pipe);
+	for (pipe = 0; pipe < 32; pipe++) {
+		if (pipe_active(dbri, pipe)) {
+			struct dbri_pipe *pptr = &dbri->pipes[pipe];
+			snd_iprintf(buffer,
+				    "Pipe %d: %s SDP=0x%x desc=%d, "
+				    "len=%d @ %d prev: %d next %d\n",
+				    pipe,
+				    (pptr->direction ==
+				     PIPEinput ? "input" : "output"), pptr->sdp,
+				    pptr->desc, pptr->length, pptr->cycle,
+				    pptr->prevpipe, pptr->nextpipe);
+		}
+	}
+}
+
+static void dbri_debug_write(snd_info_entry_t * entry,
+			     snd_info_buffer_t * buffer)
+{
+	char line[80];
+	int i;
+
+	if (snd_info_get_line(buffer, line, 80) == 0) {
+		sscanf(line, "%d\n", &i);
+		dbri_debug = i & 0x3f;
+	}
+}
+#endif
+
+void snd_dbri_proc(snd_dbri_t * dbri)
+{
+	snd_info_entry_t *entry;
+	int err;
+
+	err = snd_card_proc_new(dbri->card, "regs", &entry);
+	snd_info_set_text_ops(entry, dbri, 1024, dbri_regs_read);
+
+#ifdef DBRI_DEBUG
+	err = snd_card_proc_new(dbri->card, "debug", &entry);
+	snd_info_set_text_ops(entry, dbri, 4096, dbri_debug_read);
+	entry->mode = S_IFREG | S_IRUGO | S_IWUSR; /* Writable for root */
+	entry->c.text.write_size = 256;
+	entry->c.text.write = dbri_debug_write;
+#endif
+}
+
+/*
+****************************************************************************
+**************************** Initialization ********************************
+****************************************************************************
+*/
+static void snd_dbri_free(snd_dbri_t * dbri);
+
+static int __init snd_dbri_create(snd_card_t * card,
+				  struct sbus_dev *sdev,
+				  struct linux_prom_irqs *irq, int dev)
+{
+	snd_dbri_t *dbri = card->private_data;
+	int err;
+
+	spin_lock_init(&dbri->lock);
+	dbri->card = card;
+	dbri->sdev = sdev;
+	dbri->irq = irq->pri;
+	dbri->dbri_version = sdev->prom_name[9];
+
+	dbri->dma = sbus_alloc_consistent(sdev, sizeof(struct dbri_dma),
+					  &dbri->dma_dvma);
+	memset((void *)dbri->dma, 0, sizeof(struct dbri_dma));
+
+	dprintk(D_GEN, "DMA Cmd Block 0x%p (0x%08x)\n",
+		dbri->dma, dbri->dma_dvma);
+
+	/* Map the registers into memory. */
+	dbri->regs_size = sdev->reg_addrs[0].reg_size;
+	dbri->regs = sbus_ioremap(&sdev->resource[0], 0,
+				  dbri->regs_size, "DBRI Registers");
+	if (!dbri->regs) {
+		printk(KERN_ERR "DBRI: could not allocate registers\n");
+		sbus_free_consistent(sdev, sizeof(struct dbri_dma),
+				     (void *)dbri->dma, dbri->dma_dvma);
+		return -EIO;
+	}
+
+	err = request_irq(dbri->irq, snd_dbri_interrupt, SA_SHIRQ,
+			  "DBRI audio", dbri);
+	if (err) {
+		printk(KERN_ERR "DBRI: Can't get irq %d\n", dbri->irq);
+		sbus_iounmap(dbri->regs, dbri->regs_size);
+		sbus_free_consistent(sdev, sizeof(struct dbri_dma),
+				     (void *)dbri->dma, dbri->dma_dvma);
+		return err;
+	}
+
+	/* Do low level initialization of the DBRI and CS4215 chips */
+	dbri_initialize(dbri);
+	err = cs4215_init(dbri);
+	if (err) {
+		snd_dbri_free(dbri);
+		return err;
+	}
+
+	dbri->next = dbri_list;
+	dbri_list = dbri;
+
+	return 0;
+}
+
+static void snd_dbri_free(snd_dbri_t * dbri)
+{
+	dprintk(D_GEN, "snd_dbri_free\n");
+	dbri_reset(dbri);
+
+	if (dbri->irq)
+		free_irq(dbri->irq, dbri);
+
+	if (dbri->regs)
+		sbus_iounmap(dbri->regs, dbri->regs_size);
+
+	if (dbri->dma)
+		sbus_free_consistent(dbri->sdev, sizeof(struct dbri_dma),
+				     (void *)dbri->dma, dbri->dma_dvma);
+}
+
+static int __init dbri_attach(int prom_node, struct sbus_dev *sdev)
+{
+	snd_dbri_t *dbri;
+	struct linux_prom_irqs irq;
+	struct resource *rp;
+	snd_card_t *card;
+	static int dev = 0;
+	int err;
+
+	if (sdev->prom_name[9] < 'e') {
+		printk(KERN_ERR "DBRI: unsupported chip version %c found.\n",
+		       sdev->prom_name[9]);
+		return -EIO;
+	}
+
+	if (dev >= SNDRV_CARDS)
+		return -ENODEV;
+	if (!enable[dev]) {
+		dev++;
+		return -ENOENT;
+	}
+
+	prom_getproperty(prom_node, "intr", (char *)&irq, sizeof(irq));
+
+	card = snd_card_new(index[dev], id[dev], THIS_MODULE,
+			    sizeof(snd_dbri_t));
+	if (card == NULL)
+		return -ENOMEM;
+
+	strcpy(card->driver, "DBRI");
+	strcpy(card->shortname, "Sun DBRI");
+	rp = &sdev->resource[0];
+	sprintf(card->longname, "%s at 0x%02lx:0x%08lx, irq %s",
+		card->shortname,
+		rp->flags & 0xffL, rp->start, __irq_itoa(irq.pri));
+
+	if ((err = snd_dbri_create(card, sdev, &irq, dev)) < 0) {
+		snd_card_free(card);
+		return err;
+	}
+
+	dbri = (snd_dbri_t *) card->private_data;
+	if ((err = snd_dbri_pcm(dbri)) < 0) {
+		snd_dbri_free(dbri);
+		snd_card_free(card);
+		return err;
+	}
+
+	if ((err = snd_dbri_mixer(dbri)) < 0) {
+		snd_dbri_free(dbri);
+		snd_card_free(card);
+		return err;
+	}
+
+	/* /proc file handling */
+	snd_dbri_proc(dbri);
+
+	if ((err = snd_card_register(card)) < 0) {
+		snd_dbri_free(dbri);
+		snd_card_free(card);
+		return err;
+	}
+
+	printk(KERN_INFO "audio%d at %p (irq %d) is DBRI(%c)+CS4215(%d)\n",
+	       dev, dbri->regs,
+	       dbri->irq, dbri->dbri_version, dbri->mm.version);
+	dev++;
+
+	return 0;
+}
+
+/* Probe for the dbri chip and then attach the driver. */
+static int __init dbri_init(void)
+{
+	struct sbus_bus *sbus;
+	struct sbus_dev *sdev;
+	int found = 0;
+
+	/* Probe each SBUS for the DBRI chip(s). */
+	for_all_sbusdev(sdev, sbus) {
+		/*
+		 * The version is coded in the last character
+		 */
+		if (!strncmp(sdev->prom_name, "SUNW,DBRI", 9)) {
+			dprintk(D_GEN, "DBRI: Found %s in SBUS slot %d\n",
+				sdev->prom_name, sdev->slot);
+
+			if (dbri_attach(sdev->prom_node, sdev) == 0)
+				found++;
+		}
+	}
+
+	return (found > 0) ? 0 : -EIO;
+}
+
+static void __exit dbri_exit(void)
+{
+	snd_dbri_t *this = dbri_list;
+
+	while (this != NULL) {
+		snd_dbri_t *next = this->next;
+		snd_card_t *card = this->card;
+
+		snd_dbri_free(this);
+		snd_card_free(card);
+		this = next;
+	}
+	dbri_list = NULL;
+}
+
+module_init(dbri_init);
+module_exit(dbri_exit);
diff --git a/sound/synth/emux/emux.c b/sound/synth/emux/emux.c
--- a/sound/synth/emux/emux.c
+++ b/sound/synth/emux/emux.c
@@ -22,6 +22,7 @@
 #include <linux/wait.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
+#include <linux/string.h>
 #include <sound/core.h>
 #include <sound/emux_synth.h>
 #include <linux/init.h>
@@ -76,7 +77,7 @@ int snd_emux_register(snd_emux_t *emu, s
 	snd_assert(name != NULL, return -EINVAL);
 
 	emu->card = card;
-	emu->name = snd_kmalloc_strdup(name, GFP_KERNEL);
+	emu->name = kstrdup(name, GFP_KERNEL);
 	emu->voices = kcalloc(emu->max_voices, sizeof(snd_emux_voice_t), GFP_KERNEL);
 	if (emu->voices == NULL)
 		return -ENOMEM;
diff --git a/sound/synth/emux/emux_effect.c b/sound/synth/emux/emux_effect.c
--- a/sound/synth/emux/emux_effect.c
+++ b/sound/synth/emux/emux_effect.c
@@ -291,10 +291,8 @@ snd_emux_create_effect(snd_emux_port_t *
 void
 snd_emux_delete_effect(snd_emux_port_t *p)
 {
-	if (p->effect) {
-		kfree(p->effect);
-		p->effect = NULL;
-	}
+	kfree(p->effect);
+	p->effect = NULL;
 }
 
 void
diff --git a/sound/usb/Kconfig b/sound/usb/Kconfig
--- a/sound/usb/Kconfig
+++ b/sound/usb/Kconfig
@@ -6,6 +6,7 @@ menu "USB devices"
 config SND_USB_AUDIO
 	tristate "USB Audio/MIDI driver"
 	depends on SND && USB
+	select SND_HWDEP
 	select SND_RAWMIDI
 	select SND_PCM
 	help
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c
--- a/sound/usb/usbaudio.c
+++ b/sound/usb/usbaudio.c
@@ -98,7 +98,7 @@ MODULE_PARM_DESC(async_unlink, "Use asyn
 #define MAX_PACKS	10
 #define MAX_PACKS_HS	(MAX_PACKS * 8)	/* in high speed mode */
 #define MAX_URBS	5	/* max. 20ms long packets */
-#define SYNC_URBS	2	/* always two urbs for sync */
+#define SYNC_URBS	4	/* always four urbs for sync */
 #define MIN_PACKS_URB	1	/* minimum 1 packet per urb */
 
 typedef struct snd_usb_substream snd_usb_substream_t;
@@ -153,6 +153,7 @@ struct snd_usb_substream {
 	unsigned int format;     /* USB data format */
 	unsigned int datapipe;   /* the data i/o pipe */
 	unsigned int syncpipe;   /* 1 - async out or adaptive in */
+	unsigned int datainterval;	/* log_2 of data packet interval */
 	unsigned int syncinterval;  /* P for adaptive mode, 0 otherwise */
 	unsigned int freqn;      /* nominal sampling rate in fs/fps in Q16.16 format */
 	unsigned int freqm;      /* momentary sampling rate in fs/fps in Q16.16 format */
@@ -177,7 +178,7 @@ struct snd_usb_substream {
 	unsigned int nurbs;			/* # urbs */
 	snd_urb_ctx_t dataurb[MAX_URBS];	/* data urb table */
 	snd_urb_ctx_t syncurb[SYNC_URBS];	/* sync urb table */
-	char syncbuf[SYNC_URBS * MAX_PACKS * 4]; /* sync buffer; it's so small - let's get static */
+	char syncbuf[SYNC_URBS * 4];	/* sync buffer; it's so small - let's get static */
 	char *tmpbuf;			/* temporary buffer for playback */
 
 	u64 formats;			/* format bitmasks (all or'ed) */
@@ -212,7 +213,7 @@ static snd_usb_audio_t *usb_chip[SNDRV_C
  * convert a sampling rate into our full speed format (fs/1000 in Q16.16)
  * this will overflow at approx 524 kHz
  */
-inline static unsigned get_usb_full_speed_rate(unsigned int rate)
+static inline unsigned get_usb_full_speed_rate(unsigned int rate)
 {
 	return ((rate << 13) + 62) / 125;
 }
@@ -221,19 +222,19 @@ inline static unsigned get_usb_full_spee
  * convert a sampling rate into USB high speed format (fs/8000 in Q16.16)
  * this will overflow at approx 4 MHz
  */
-inline static unsigned get_usb_high_speed_rate(unsigned int rate)
+static inline unsigned get_usb_high_speed_rate(unsigned int rate)
 {
 	return ((rate << 10) + 62) / 125;
 }
 
 /* convert our full speed USB rate into sampling rate in Hz */
-inline static unsigned get_full_speed_hz(unsigned int usb_rate)
+static inline unsigned get_full_speed_hz(unsigned int usb_rate)
 {
 	return (usb_rate * 125 + (1 << 12)) >> 13;
 }
 
 /* convert our high speed USB rate into sampling rate in Hz */
-inline static unsigned get_high_speed_hz(unsigned int usb_rate)
+static inline unsigned get_high_speed_hz(unsigned int usb_rate)
 {
 	return (usb_rate * 125 + (1 << 9)) >> 10;
 }
@@ -251,17 +252,13 @@ static int prepare_capture_sync_urb(snd_
 {
 	unsigned char *cp = urb->transfer_buffer;
 	snd_urb_ctx_t *ctx = (snd_urb_ctx_t *)urb->context;
-	int i, offs;
 
-	urb->number_of_packets = ctx->packets;
 	urb->dev = ctx->subs->dev; /* we need to set this at each time */
-	for (i = offs = 0; i < urb->number_of_packets; i++, offs += 4, cp += 4) {
-		urb->iso_frame_desc[i].length = 3;
-		urb->iso_frame_desc[i].offset = offs;
-		cp[0] = subs->freqn >> 2;
-		cp[1] = subs->freqn >> 10;
-		cp[2] = subs->freqn >> 18;
-	}
+	urb->iso_frame_desc[0].length = 3;
+	urb->iso_frame_desc[0].offset = 0;
+	cp[0] = subs->freqn >> 2;
+	cp[1] = subs->freqn >> 10;
+	cp[2] = subs->freqn >> 18;
 	return 0;
 }
 
@@ -277,18 +274,14 @@ static int prepare_capture_sync_urb_hs(s
 {
 	unsigned char *cp = urb->transfer_buffer;
 	snd_urb_ctx_t *ctx = (snd_urb_ctx_t *)urb->context;
-	int i, offs;
 
-	urb->number_of_packets = ctx->packets;
 	urb->dev = ctx->subs->dev; /* we need to set this at each time */
-	for (i = offs = 0; i < urb->number_of_packets; i++, offs += 4, cp += 4) {
-		urb->iso_frame_desc[i].length = 4;
-		urb->iso_frame_desc[i].offset = offs;
-		cp[0] = subs->freqn;
-		cp[1] = subs->freqn >> 8;
-		cp[2] = subs->freqn >> 16;
-		cp[3] = subs->freqn >> 24;
-	}
+	urb->iso_frame_desc[0].length = 4;
+	urb->iso_frame_desc[0].offset = 0;
+	cp[0] = subs->freqn;
+	cp[1] = subs->freqn >> 8;
+	cp[2] = subs->freqn >> 16;
+	cp[3] = subs->freqn >> 24;
 	return 0;
 }
 
@@ -418,15 +411,11 @@ static int prepare_playback_sync_urb(snd
 				     snd_pcm_runtime_t *runtime,
 				     struct urb *urb)
 {
-	int i, offs;
 	snd_urb_ctx_t *ctx = (snd_urb_ctx_t *)urb->context;
 
-	urb->number_of_packets = ctx->packets;
 	urb->dev = ctx->subs->dev; /* we need to set this at each time */
-	for (i = offs = 0; i < urb->number_of_packets; i++, offs += 4) {
-		urb->iso_frame_desc[i].length = 3;
-		urb->iso_frame_desc[i].offset = offs;
-	}
+	urb->iso_frame_desc[0].length = 3;
+	urb->iso_frame_desc[0].offset = 0;
 	return 0;
 }
 
@@ -440,15 +429,11 @@ static int prepare_playback_sync_urb_hs(
 					snd_pcm_runtime_t *runtime,
 					struct urb *urb)
 {
-	int i, offs;
 	snd_urb_ctx_t *ctx = (snd_urb_ctx_t *)urb->context;
 
-	urb->number_of_packets = ctx->packets;
 	urb->dev = ctx->subs->dev; /* we need to set this at each time */
-	for (i = offs = 0; i < urb->number_of_packets; i++, offs += 4) {
-		urb->iso_frame_desc[i].length = 4;
-		urb->iso_frame_desc[i].offset = offs;
-	}
+	urb->iso_frame_desc[0].length = 4;
+	urb->iso_frame_desc[0].offset = 0;
 	return 0;
 }
 
@@ -462,31 +447,17 @@ static int retire_playback_sync_urb(snd_
 				    snd_pcm_runtime_t *runtime,
 				    struct urb *urb)
 {
-	int i;
-	unsigned int f, found;
-	unsigned char *cp = urb->transfer_buffer;
+	unsigned int f;
 	unsigned long flags;
 
-	found = 0;
-	for (i = 0; i < urb->number_of_packets; i++, cp += 4) {
-		if (urb->iso_frame_desc[i].status ||
-		    urb->iso_frame_desc[i].actual_length < 3)
-			continue;
-		f = combine_triple(cp) << 2;
-#if 0
-		if (f < subs->freqn - (subs->freqn>>3) || f > subs->freqmax) {
-			snd_printd(KERN_WARNING "requested frequency %d (%u,%03uHz) out of range (current nominal %d (%u,%03uHz))\n",
-				   f, f >> 14, (f & ((1 << 14) - 1) * 1000) / ((1 << 14) - 1),
-				   subs->freqn, subs->freqn >> 14, (subs->freqn & ((1 << 14) - 1) * 1000) / ((1 << 14) - 1));
-			continue;
+	if (urb->iso_frame_desc[0].status == 0 &&
+	    urb->iso_frame_desc[0].actual_length == 3) {
+		f = combine_triple((u8*)urb->transfer_buffer) << 2;
+		if (f >= subs->freqn - subs->freqn / 8 && f <= subs->freqmax) {
+			spin_lock_irqsave(&subs->lock, flags);
+			subs->freqm = f;
+			spin_unlock_irqrestore(&subs->lock, flags);
 		}
-#endif
-		found = f;
-	}
-	if (found) {
-		spin_lock_irqsave(&subs->lock, flags);
-		subs->freqm = found;
-		spin_unlock_irqrestore(&subs->lock, flags);
 	}
 
 	return 0;
@@ -502,22 +473,17 @@ static int retire_playback_sync_urb_hs(s
 				       snd_pcm_runtime_t *runtime,
 				       struct urb *urb)
 {
-	int i;
-	unsigned int found;
-	unsigned char *cp = urb->transfer_buffer;
+	unsigned int f;
 	unsigned long flags;
 
-	found = 0;
-	for (i = 0; i < urb->number_of_packets; i++, cp += 4) {
-		if (urb->iso_frame_desc[i].status ||
-		    urb->iso_frame_desc[i].actual_length < 4)
-			continue;
-		found = combine_quad(cp) & 0x0fffffff;
-	}
-	if (found) {
-		spin_lock_irqsave(&subs->lock, flags);
-		subs->freqm = found;
-		spin_unlock_irqrestore(&subs->lock, flags);
+	if (urb->iso_frame_desc[0].status == 0 &&
+	    urb->iso_frame_desc[0].actual_length == 4) {
+		f = combine_quad((u8*)urb->transfer_buffer) & 0x0fffffff;
+		if (f >= subs->freqn - subs->freqn / 8 && f <= subs->freqmax) {
+			spin_lock_irqsave(&subs->lock, flags);
+			subs->freqm = f;
+			spin_unlock_irqrestore(&subs->lock, flags);
+		}
 	}
 
 	return 0;
@@ -553,7 +519,8 @@ static int prepare_playback_urb(snd_usb_
 		if (subs->fill_max)
 			counts = subs->maxframesize; /* fixed */
 		else {
-			subs->phase = (subs->phase & 0xffff) + subs->freqm;
+			subs->phase = (subs->phase & 0xffff)
+				+ (subs->freqm << subs->datainterval);
 			counts = subs->phase >> 16;
 			if (counts > subs->maxframesize)
 				counts = subs->maxframesize;
@@ -600,6 +567,8 @@ static int prepare_playback_urb(snd_usb_
 		/* set the buffer pointer */
 		urb->transfer_buffer = runtime->dma_area + subs->hwptr * stride;
 		subs->hwptr += offs;
+		if (subs->hwptr == runtime->buffer_size)
+			subs->hwptr = 0;
 	}
 	spin_unlock_irqrestore(&subs->lock, flags);
 	urb->transfer_buffer_length = offs * stride;
@@ -823,7 +792,7 @@ static int start_urbs(snd_usb_substream_
  */
 static int wait_clear_urbs(snd_usb_substream_t *subs)
 {
-	int timeout = HZ;
+	unsigned long end_time = jiffies + msecs_to_jiffies(1000);
 	unsigned int i;
 	int alive;
 
@@ -843,7 +812,7 @@ static int wait_clear_urbs(snd_usb_subst
 			break;
 		set_current_state(TASK_UNINTERRUPTIBLE);
 		schedule_timeout(1);
-	} while (--timeout > 0);
+	} while (time_before(jiffies, end_time));
 	if (alive)
 		snd_printk(KERN_ERR "timeout: still %d active urbs..\n", alive);
 	return 0;
@@ -892,10 +861,8 @@ static void release_urb_ctx(snd_urb_ctx_
 		usb_free_urb(u->urb);
 		u->urb = NULL;
 	}
-	if (u->buf) {
-		kfree(u->buf);
-		u->buf = NULL;
-	}
+	kfree(u->buf);
+	u->buf = NULL;
 }
 
 /*
@@ -913,10 +880,8 @@ static void release_substream_urbs(snd_u
 		release_urb_ctx(&subs->dataurb[i]);
 	for (i = 0; i < SYNC_URBS; i++)
 		release_urb_ctx(&subs->syncurb[i]);
-	if (subs->tmpbuf) {
-		kfree(subs->tmpbuf);
-		subs->tmpbuf = NULL;
-	}
+	kfree(subs->tmpbuf);
+	subs->tmpbuf = NULL;
 	subs->nurbs = 0;
 }
 
@@ -936,16 +901,19 @@ static int init_substream_urbs(snd_usb_s
 	else
 		subs->freqn = get_usb_high_speed_rate(rate);
 	subs->freqm = subs->freqn;
-	subs->freqmax = subs->freqn + (subs->freqn >> 2); /* max. allowed frequency */
-	subs->phase = 0;
-
-	/* calculate the max. size of packet */
-	maxsize = ((subs->freqmax + 0xffff) * (frame_bits >> 3)) >> 16;
-	if (subs->maxpacksize && maxsize > subs->maxpacksize) {
-		//snd_printd(KERN_DEBUG "maxsize %d is greater than defined size %d\n",
-		//	   maxsize, subs->maxpacksize);
+	/* calculate max. frequency */
+	if (subs->maxpacksize) {
+		/* whatever fits into a max. size packet */
 		maxsize = subs->maxpacksize;
+		subs->freqmax = (maxsize / (frame_bits >> 3))
+				<< (16 - subs->datainterval);
+	} else {
+		/* no max. packet size: just take 25% higher than nominal */
+		subs->freqmax = subs->freqn + (subs->freqn >> 2);
+		maxsize = ((subs->freqmax + 0xffff) * (frame_bits >> 3))
+				>> (16 - subs->datainterval);
 	}
+	subs->phase = 0;
 
 	if (subs->fill_max)
 		subs->curpacksize = subs->maxpacksize;
@@ -955,7 +923,7 @@ static int init_substream_urbs(snd_usb_s
 	if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL)
 		urb_packs = nrpacks;
 	else
-		urb_packs = nrpacks * 8;
+		urb_packs = (nrpacks * 8) >> subs->datainterval;
 
 	/* allocate a temporary buffer for playback */
 	if (is_playback) {
@@ -1028,7 +996,7 @@ static int init_substream_urbs(snd_usb_s
 		u->urb->pipe = subs->datapipe;
 		u->urb->transfer_flags = URB_ISO_ASAP;
 		u->urb->number_of_packets = u->packets;
-		u->urb->interval = 1;
+		u->urb->interval = 1 << subs->datainterval;
 		u->urb->context = u;
 		u->urb->complete = snd_usb_complete_callback(snd_complete_urb);
 	}
@@ -1039,22 +1007,19 @@ static int init_substream_urbs(snd_usb_s
 			snd_urb_ctx_t *u = &subs->syncurb[i];
 			u->index = i;
 			u->subs = subs;
-			u->packets = nrpacks;
-			u->urb = usb_alloc_urb(u->packets, GFP_KERNEL);
+			u->packets = 1;
+			u->urb = usb_alloc_urb(1, GFP_KERNEL);
 			if (! u->urb) {
 				release_substream_urbs(subs, 0);
 				return -ENOMEM;
 			}
-			u->urb->transfer_buffer = subs->syncbuf + i * nrpacks * 4;
-			u->urb->transfer_buffer_length = nrpacks * 4;
+			u->urb->transfer_buffer = subs->syncbuf + i * 4;
+			u->urb->transfer_buffer_length = 4;
 			u->urb->dev = subs->dev;
 			u->urb->pipe = subs->syncpipe;
 			u->urb->transfer_flags = URB_ISO_ASAP;
-			u->urb->number_of_packets = u->packets;
-			if (snd_usb_get_speed(subs->dev) == USB_SPEED_HIGH)
-				u->urb->interval = 8;
-			else
-				u->urb->interval = 1;
+			u->urb->number_of_packets = 1;
+			u->urb->interval = 1 << subs->syncinterval;
 			u->urb->context = u;
 			u->urb->complete = snd_usb_complete_callback(snd_complete_sync_urb);
 		}
@@ -1235,6 +1200,12 @@ static int set_format(snd_usb_substream_
 		subs->datapipe = usb_sndisocpipe(dev, ep);
 	else
 		subs->datapipe = usb_rcvisocpipe(dev, ep);
+	if (snd_usb_get_speed(subs->dev) == USB_SPEED_HIGH &&
+	    get_endpoint(alts, 0)->bInterval >= 1 &&
+	    get_endpoint(alts, 0)->bInterval <= 4)
+		subs->datainterval = get_endpoint(alts, 0)->bInterval - 1;
+	else
+		subs->datainterval = 0;
 	subs->syncpipe = subs->syncinterval = 0;
 	subs->maxpacksize = fmt->maxpacksize;
 	subs->fill_max = 0;
@@ -1272,7 +1243,17 @@ static int set_format(snd_usb_substream_
 			subs->syncpipe = usb_rcvisocpipe(dev, ep);
 		else
 			subs->syncpipe = usb_sndisocpipe(dev, ep);
-		subs->syncinterval = get_endpoint(alts, 1)->bRefresh;
+		if (get_endpoint(alts, 1)->bLength >= USB_DT_ENDPOINT_AUDIO_SIZE &&
+		    get_endpoint(alts, 1)->bRefresh >= 1 &&
+		    get_endpoint(alts, 1)->bRefresh <= 9)
+			subs->syncinterval = get_endpoint(alts, 1)->bRefresh;
+		else if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL)
+			subs->syncinterval = 1;
+		else if (get_endpoint(alts, 1)->bInterval >= 1 &&
+			 get_endpoint(alts, 1)->bInterval <= 16)
+			subs->syncinterval = get_endpoint(alts, 1)->bInterval - 1;
+		else
+			subs->syncinterval = 3;
 	}
 
 	/* always fill max packet size */
@@ -1990,10 +1971,11 @@ static void proc_dump_substream_status(s
 			snd_iprintf(buffer, "%d ", subs->dataurb[i].packets);
 		snd_iprintf(buffer, "]\n");
 		snd_iprintf(buffer, "    Packet Size = %d\n", subs->curpacksize);
-		snd_iprintf(buffer, "    Momentary freq = %u Hz\n",
+		snd_iprintf(buffer, "    Momentary freq = %u Hz (%#x.%04x)\n",
 			    snd_usb_get_speed(subs->dev) == USB_SPEED_FULL
 			    ? get_full_speed_hz(subs->freqm)
-			    : get_high_speed_hz(subs->freqm));
+			    : get_high_speed_hz(subs->freqm),
+			    subs->freqm >> 16, subs->freqm & 0xffff);
 	} else {
 		snd_iprintf(buffer, "  Status: Stop\n");
 	}
@@ -2183,17 +2165,15 @@ static int add_audio_endpoint(snd_usb_au
 /*
  * check if the device uses big-endian samples
  */
-static int is_big_endian_format(struct usb_device *dev, struct audioformat *fp)
+static int is_big_endian_format(snd_usb_audio_t *chip, struct audioformat *fp)
 {
-	/* M-Audio */
-	if (le16_to_cpu(dev->descriptor.idVendor) == 0x0763) {
-		/* Quattro: captured data only */
-		if (le16_to_cpu(dev->descriptor.idProduct) == 0x2001 &&
-		    fp->endpoint & USB_DIR_IN)
-			return 1;
-		/* Audiophile USB */
-		if (le16_to_cpu(dev->descriptor.idProduct) == 0x2003)
+	switch (chip->usb_id) {
+	case USB_ID(0x0763, 0x2001): /* M-Audio Quattro: captured data only */
+		if (fp->endpoint & USB_DIR_IN)
 			return 1;
+		break;
+	case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */
+		return 1;
 	}
 	return 0;
 }
@@ -2207,7 +2187,7 @@ static int is_big_endian_format(struct u
  * @format: the format tag (wFormatTag)
  * @fmt: the format type descriptor
  */
-static int parse_audio_format_i_type(struct usb_device *dev, struct audioformat *fp,
+static int parse_audio_format_i_type(snd_usb_audio_t *chip, struct audioformat *fp,
 				     int format, unsigned char *fmt)
 {
 	int pcm_format;
@@ -2220,12 +2200,12 @@ static int parse_audio_format_i_type(str
 	switch (format) {
 	case 0: /* some devices don't define this correctly... */
 		snd_printdd(KERN_INFO "%d:%u:%d : format type 0 is detected, processed as PCM\n",
-			    dev->devnum, fp->iface, fp->altsetting);
+			    chip->dev->devnum, fp->iface, fp->altsetting);
 		/* fall-through */
 	case USB_AUDIO_FORMAT_PCM:
 		if (sample_width > sample_bytes * 8) {
 			snd_printk(KERN_INFO "%d:%u:%d : sample bitwidth %d in over sample bytes %d\n",
-				   dev->devnum, fp->iface, fp->altsetting,
+				   chip->dev->devnum, fp->iface, fp->altsetting,
 				   sample_width, sample_bytes);
 		}
 		/* check the format byte size */
@@ -2234,13 +2214,13 @@ static int parse_audio_format_i_type(str
 			pcm_format = SNDRV_PCM_FORMAT_S8;
 			break;
 		case 2:
-			if (is_big_endian_format(dev, fp))
+			if (is_big_endian_format(chip, fp))
 				pcm_format = SNDRV_PCM_FORMAT_S16_BE; /* grrr, big endian!! */
 			else
 				pcm_format = SNDRV_PCM_FORMAT_S16_LE;
 			break;
 		case 3:
-			if (is_big_endian_format(dev, fp))
+			if (is_big_endian_format(chip, fp))
 				pcm_format = SNDRV_PCM_FORMAT_S24_3BE; /* grrr, big endian!! */
 			else
 				pcm_format = SNDRV_PCM_FORMAT_S24_3LE;
@@ -2250,14 +2230,14 @@ static int parse_audio_format_i_type(str
 			break;
 		default:
 			snd_printk(KERN_INFO "%d:%u:%d : unsupported sample bitwidth %d in %d bytes\n",
-				   dev->devnum, fp->iface, fp->altsetting, sample_width, sample_bytes);
+				   chip->dev->devnum, fp->iface,
+				   fp->altsetting, sample_width, sample_bytes);
 			break;
 		}
 		break;
 	case USB_AUDIO_FORMAT_PCM8:
 		/* Dallas DS4201 workaround */
-		if (le16_to_cpu(dev->descriptor.idVendor) == 0x04fa &&
-		    le16_to_cpu(dev->descriptor.idProduct) == 0x4201)
+		if (chip->usb_id == USB_ID(0x04fa, 0x4201))
 			pcm_format = SNDRV_PCM_FORMAT_S8;
 		else
 			pcm_format = SNDRV_PCM_FORMAT_U8;
@@ -2273,7 +2253,7 @@ static int parse_audio_format_i_type(str
 		break;
 	default:
 		snd_printk(KERN_INFO "%d:%u:%d : unsupported format type %d\n",
-			   dev->devnum, fp->iface, fp->altsetting, format);
+			   chip->dev->devnum, fp->iface, fp->altsetting, format);
 		break;
 	}
 	return pcm_format;
@@ -2290,13 +2270,13 @@ static int parse_audio_format_i_type(str
  * @offset: the start offset of descriptor pointing the rate type
  *          (7 for type I and II, 8 for type II)
  */
-static int parse_audio_format_rates(struct usb_device *dev, struct audioformat *fp,
+static int parse_audio_format_rates(snd_usb_audio_t *chip, struct audioformat *fp,
 				    unsigned char *fmt, int offset)
 {
 	int nr_rates = fmt[offset];
 	if (fmt[0] < offset + 1 + 3 * (nr_rates ? nr_rates : 2)) {
 		snd_printk(KERN_ERR "%d:%u:%d : invalid FORMAT_TYPE desc\n",
-				   dev->devnum, fp->iface, fp->altsetting);
+				   chip->dev->devnum, fp->iface, fp->altsetting);
 		return -1;
 	}
 
@@ -2343,7 +2323,7 @@ static int parse_audio_format_rates(stru
 /*
  * parse the format type I and III descriptors
  */
-static int parse_audio_format_i(struct usb_device *dev, struct audioformat *fp,
+static int parse_audio_format_i(snd_usb_audio_t *chip, struct audioformat *fp,
 				int format, unsigned char *fmt)
 {
 	int pcm_format;
@@ -2355,7 +2335,7 @@ static int parse_audio_format_i(struct u
 		 */
 		pcm_format = SNDRV_PCM_FORMAT_S16_LE;
 	} else {
-		pcm_format = parse_audio_format_i_type(dev, fp, format, fmt);
+		pcm_format = parse_audio_format_i_type(chip, fp, format, fmt);
 		if (pcm_format < 0)
 			return -1;
 	}
@@ -2363,16 +2343,16 @@ static int parse_audio_format_i(struct u
 	fp->channels = fmt[4];
 	if (fp->channels < 1) {
 		snd_printk(KERN_ERR "%d:%u:%d : invalid channels %d\n",
-			   dev->devnum, fp->iface, fp->altsetting, fp->channels);
+			   chip->dev->devnum, fp->iface, fp->altsetting, fp->channels);
 		return -1;
 	}
-	return parse_audio_format_rates(dev, fp, fmt, 7);
+	return parse_audio_format_rates(chip, fp, fmt, 7);
 }
 
 /*
  * prase the format type II descriptor
  */
-static int parse_audio_format_ii(struct usb_device *dev, struct audioformat *fp,
+static int parse_audio_format_ii(snd_usb_audio_t *chip, struct audioformat *fp,
 				 int format, unsigned char *fmt)
 {
 	int brate, framesize;
@@ -2387,7 +2367,7 @@ static int parse_audio_format_ii(struct 
 		break;
 	default:
 		snd_printd(KERN_INFO "%d:%u:%d : unknown format tag 0x%x is detected.  processed as MPEG.\n",
-			   dev->devnum, fp->iface, fp->altsetting, format);
+			   chip->dev->devnum, fp->iface, fp->altsetting, format);
 		fp->format = SNDRV_PCM_FORMAT_MPEG;
 		break;
 	}
@@ -2396,10 +2376,10 @@ static int parse_audio_format_ii(struct 
 	framesize = combine_word(&fmt[6]); /* fmt[6,7]: wSamplesPerFrame */
 	snd_printd(KERN_INFO "found format II with max.bitrate = %d, frame size=%d\n", brate, framesize);
 	fp->frame_size = framesize;
-	return parse_audio_format_rates(dev, fp, fmt, 8); /* fmt[8..] sample rates */
+	return parse_audio_format_rates(chip, fp, fmt, 8); /* fmt[8..] sample rates */
 }
 
-static int parse_audio_format(struct usb_device *dev, struct audioformat *fp,
+static int parse_audio_format(snd_usb_audio_t *chip, struct audioformat *fp,
 			      int format, unsigned char *fmt, int stream)
 {
 	int err;
@@ -2407,30 +2387,30 @@ static int parse_audio_format(struct usb
 	switch (fmt[3]) {
 	case USB_FORMAT_TYPE_I:
 	case USB_FORMAT_TYPE_III:
-		err = parse_audio_format_i(dev, fp, format, fmt);
+		err = parse_audio_format_i(chip, fp, format, fmt);
 		break;
 	case USB_FORMAT_TYPE_II:
-		err = parse_audio_format_ii(dev, fp, format, fmt);
+		err = parse_audio_format_ii(chip, fp, format, fmt);
 		break;
 	default:
 		snd_printd(KERN_INFO "%d:%u:%d : format type %d is not supported yet\n",
-			   dev->devnum, fp->iface, fp->altsetting, fmt[3]);
+			   chip->dev->devnum, fp->iface, fp->altsetting, fmt[3]);
 		return -1;
 	}
 	fp->fmt_type = fmt[3];
 	if (err < 0)
 		return err;
 #if 1
-	/* FIXME: temporary hack for extigy */
+	/* FIXME: temporary hack for extigy/audigy 2 nx */
 	/* extigy apparently supports sample rates other than 48k
 	 * but not in ordinary way.  so we enable only 48k atm.
 	 */
-	if (le16_to_cpu(dev->descriptor.idVendor) == 0x041e && 
-	    le16_to_cpu(dev->descriptor.idProduct) == 0x3000) {
+	if (chip->usb_id == USB_ID(0x041e, 0x3000) ||
+	    chip->usb_id == USB_ID(0x041e, 0x3020)) {
 		if (fmt[3] == USB_FORMAT_TYPE_I &&
-		    stream == SNDRV_PCM_STREAM_PLAYBACK &&
-		    fp->rates != SNDRV_PCM_RATE_48000)
-			return -1; /* use 48k only */
+		    fp->rates != SNDRV_PCM_RATE_48000 &&
+		    fp->rates != SNDRV_PCM_RATE_96000)
+			return -1;
 	}
 #endif
 	return 0;
@@ -2522,46 +2502,43 @@ static int parse_audio_endpoints(snd_usb
 		fp->altset_idx = i;
 		fp->endpoint = get_endpoint(alts, 0)->bEndpointAddress;
 		fp->ep_attr = get_endpoint(alts, 0)->bmAttributes;
-		/* FIXME: decode wMaxPacketSize of high bandwith endpoints */
 		fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize);
+		if (snd_usb_get_speed(dev) == USB_SPEED_HIGH)
+			fp->maxpacksize = (((fp->maxpacksize >> 11) & 3) + 1)
+					* (fp->maxpacksize & 0x7ff);
 		fp->attributes = csep[3];
 
 		/* some quirks for attributes here */
 
-		/* workaround for AudioTrak Optoplay */
-		if (le16_to_cpu(dev->descriptor.idVendor) == 0x0a92 &&
-		    le16_to_cpu(dev->descriptor.idProduct) == 0x0053) {
+		switch (chip->usb_id) {
+		case USB_ID(0x0a92, 0x0053): /* AudioTrak Optoplay */
 			/* Optoplay sets the sample rate attribute although
 			 * it seems not supporting it in fact.
 			 */
 			fp->attributes &= ~EP_CS_ATTR_SAMPLE_RATE;
-		}
-
-		/* workaround for M-Audio Audiophile USB */
-		if (le16_to_cpu(dev->descriptor.idVendor) == 0x0763 &&
-		    le16_to_cpu(dev->descriptor.idProduct) == 0x2003) {
+			break;
+		case USB_ID(0x041e, 0x3020): /* Creative SB Audigy 2 NX */
+		case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */
 			/* doesn't set the sample rate attribute, but supports it */
 			fp->attributes |= EP_CS_ATTR_SAMPLE_RATE;
-		}
-
+			break;
+		case USB_ID(0x047f, 0x0ca1): /* plantronics headset */
+		case USB_ID(0x077d, 0x07af): /* Griffin iMic (note that there is
+						an older model 77d:223) */
 		/*
 		 * plantronics headset and Griffin iMic have set adaptive-in
 		 * although it's really not...
 		 */
-		if ((le16_to_cpu(dev->descriptor.idVendor) == 0x047f &&
-		     le16_to_cpu(dev->descriptor.idProduct) == 0x0ca1) ||
-		    /* Griffin iMic (note that there is an older model 77d:223) */
-		    (le16_to_cpu(dev->descriptor.idVendor) == 0x077d &&
-		     le16_to_cpu(dev->descriptor.idProduct) == 0x07af)) {
 			fp->ep_attr &= ~EP_ATTR_MASK;
 			if (stream == SNDRV_PCM_STREAM_PLAYBACK)
 				fp->ep_attr |= EP_ATTR_ADAPTIVE;
 			else
 				fp->ep_attr |= EP_ATTR_SYNC;
+			break;
 		}
 
 		/* ok, let's parse further... */
-		if (parse_audio_format(dev, fp, format, fmt, stream) < 0) {
+		if (parse_audio_format(chip, fp, format, fmt, stream) < 0) {
 			kfree(fp->rate_table);
 			kfree(fp);
 			continue;
@@ -2587,7 +2564,7 @@ static int parse_audio_endpoints(snd_usb
  * disconnect streams
  * called from snd_usb_audio_disconnect()
  */
-static void snd_usb_stream_disconnect(struct list_head *head, struct usb_driver *driver)
+static void snd_usb_stream_disconnect(struct list_head *head)
 {
 	int idx;
 	snd_usb_stream_t *as;
@@ -2758,7 +2735,8 @@ static int create_standard_interface_qui
  * to detect the sample rate is by looking at wMaxPacketSize.
  */
 static int create_ua700_ua25_quirk(snd_usb_audio_t *chip,
-				   struct usb_interface *iface)
+				   struct usb_interface *iface,
+				   const snd_usb_audio_quirk_t *quirk)
 {
 	static const struct audioformat ua_format = {
 		.format = SNDRV_PCM_FORMAT_S24_3LE,
@@ -2796,7 +2774,7 @@ static int create_ua700_ua25_quirk(snd_u
 			.type = QUIRK_MIDI_FIXED_ENDPOINT,
 			.data = &ua25_ep
 		};
-		if (le16_to_cpu(chip->dev->descriptor.idProduct) == 0x002b)
+		if (chip->usb_id == USB_ID(0x0582, 0x002b))
 			return snd_usb_create_midi_interface(chip, iface,
 							     &ua700_quirk);
 		else
@@ -2849,7 +2827,9 @@ static int create_ua700_ua25_quirk(snd_u
 /*
  * Create a stream for an Edirol UA-1000 interface.
  */
-static int create_ua1000_quirk(snd_usb_audio_t *chip, struct usb_interface *iface)
+static int create_ua1000_quirk(snd_usb_audio_t *chip,
+			       struct usb_interface *iface,
+			       const snd_usb_audio_quirk_t *quirk)
 {
 	static const struct audioformat ua1000_format = {
 		.format = SNDRV_PCM_FORMAT_S32_LE,
@@ -2926,6 +2906,13 @@ static int create_composite_quirk(snd_us
 	return 0;
 }
 
+static int ignore_interface_quirk(snd_usb_audio_t *chip,
+				  struct usb_interface *iface,
+				  const snd_usb_audio_quirk_t *quirk)
+{
+	return 0;
+}
+
 
 /*
  * boot quirks
@@ -2959,6 +2946,22 @@ static int snd_usb_extigy_boot_quirk(str
 	return 0;
 }
 
+static int snd_usb_audigy2nx_boot_quirk(struct usb_device *dev)
+{
+	u8 buf = 1;
+
+	snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), 0x2a,
+			USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_OTHER,
+			0, 0, &buf, 1, 1000);
+	if (buf == 0) {
+		snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), 0x29,
+				USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
+				1, 2000, NULL, 0, 1000);
+		return -ENODEV;
+	}
+	return 0;
+}
+
 
 /*
  * audio-interface quirks
@@ -2972,28 +2975,28 @@ static int snd_usb_create_quirk(snd_usb_
 				struct usb_interface *iface,
 				const snd_usb_audio_quirk_t *quirk)
 {
-	switch (quirk->type) {
-	case QUIRK_MIDI_FIXED_ENDPOINT:
-	case QUIRK_MIDI_YAMAHA:
-	case QUIRK_MIDI_MIDIMAN:
-	case QUIRK_MIDI_NOVATION:
-	case QUIRK_MIDI_MOTU:
-	case QUIRK_MIDI_EMAGIC:
-		return snd_usb_create_midi_interface(chip, iface, quirk);
-	case QUIRK_COMPOSITE:
-		return create_composite_quirk(chip, iface, quirk);
-	case QUIRK_AUDIO_FIXED_ENDPOINT:
-		return create_fixed_stream_quirk(chip, iface, quirk);
-	case QUIRK_AUDIO_STANDARD_INTERFACE:
-	case QUIRK_MIDI_STANDARD_INTERFACE:
-		return create_standard_interface_quirk(chip, iface, quirk);
-	case QUIRK_AUDIO_EDIROL_UA700_UA25:
-		return create_ua700_ua25_quirk(chip, iface);
-	case QUIRK_AUDIO_EDIROL_UA1000:
-		return create_ua1000_quirk(chip, iface);
-	case QUIRK_IGNORE_INTERFACE:
-		return 0;
-	default:
+	typedef int (*quirk_func_t)(snd_usb_audio_t *, struct usb_interface *,
+				    const snd_usb_audio_quirk_t *);
+	static const quirk_func_t quirk_funcs[] = {
+		[QUIRK_IGNORE_INTERFACE] = ignore_interface_quirk,
+		[QUIRK_COMPOSITE] = create_composite_quirk,
+		[QUIRK_MIDI_STANDARD_INTERFACE] = snd_usb_create_midi_interface,
+		[QUIRK_MIDI_FIXED_ENDPOINT] = snd_usb_create_midi_interface,
+		[QUIRK_MIDI_YAMAHA] = snd_usb_create_midi_interface,
+		[QUIRK_MIDI_MIDIMAN] = snd_usb_create_midi_interface,
+		[QUIRK_MIDI_NOVATION] = snd_usb_create_midi_interface,
+		[QUIRK_MIDI_RAW] = snd_usb_create_midi_interface,
+		[QUIRK_MIDI_EMAGIC] = snd_usb_create_midi_interface,
+		[QUIRK_MIDI_MIDITECH] = snd_usb_create_midi_interface,
+		[QUIRK_AUDIO_STANDARD_INTERFACE] = create_standard_interface_quirk,
+		[QUIRK_AUDIO_FIXED_ENDPOINT] = create_fixed_stream_quirk,
+		[QUIRK_AUDIO_EDIROL_UA700_UA25] = create_ua700_ua25_quirk,
+		[QUIRK_AUDIO_EDIROL_UA1000] = create_ua1000_quirk,
+	};
+
+	if (quirk->type < QUIRK_TYPE_COUNT) {
+		return quirk_funcs[quirk->type](chip, iface, quirk);
+	} else {
 		snd_printd(KERN_ERR "invalid quirk type %d\n", quirk->type);
 		return -ENXIO;
 	}
@@ -3015,8 +3018,8 @@ static void proc_audio_usbid_read(snd_in
 	snd_usb_audio_t *chip = entry->private_data;
 	if (! chip->shutdown)
 		snd_iprintf(buffer, "%04x:%04x\n", 
-			    le16_to_cpu(chip->dev->descriptor.idVendor),
-			    le16_to_cpu(chip->dev->descriptor.idProduct));
+			    USB_ID_VENDOR(chip->usb_id),
+			    USB_ID_PRODUCT(chip->usb_id));
 }
 
 static void snd_usb_audio_create_proc(snd_usb_audio_t *chip)
@@ -3086,8 +3089,11 @@ static int snd_usb_audio_create(struct u
 	chip->index = idx;
 	chip->dev = dev;
 	chip->card = card;
+	chip->usb_id = USB_ID(le16_to_cpu(dev->descriptor.idVendor),
+			      le16_to_cpu(dev->descriptor.idProduct));
 	INIT_LIST_HEAD(&chip->pcm_list);
 	INIT_LIST_HEAD(&chip->midi_list);
+	INIT_LIST_HEAD(&chip->mixer_list);
 
 	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
 		snd_usb_audio_free(chip);
@@ -3097,8 +3103,7 @@ static int snd_usb_audio_create(struct u
 
 	strcpy(card->driver, "USB-Audio");
 	sprintf(component, "USB%04x:%04x",
-		le16_to_cpu(dev->descriptor.idVendor),
-		le16_to_cpu(dev->descriptor.idProduct));
+		USB_ID_VENDOR(chip->usb_id), USB_ID_PRODUCT(chip->usb_id));
 	snd_component_add(card, component);
 
 	/* retrieve the device string as shortname */
@@ -3110,8 +3115,8 @@ static int snd_usb_audio_create(struct u
       			       card->shortname, sizeof(card->shortname)) <= 0) {
 			/* no name available from anywhere, so use ID */
 			sprintf(card->shortname, "USB Device %#04x:%#04x",
-				le16_to_cpu(dev->descriptor.idVendor),
-				le16_to_cpu(dev->descriptor.idProduct));
+				USB_ID_VENDOR(chip->usb_id),
+				USB_ID_PRODUCT(chip->usb_id));
 		}
 	}
 
@@ -3142,8 +3147,6 @@ static int snd_usb_audio_create(struct u
 
 	snd_usb_audio_create_proc(chip);
 
-	snd_card_set_dev(card, &dev->dev);
-
 	*rchip = chip;
 	return 0;
 }
@@ -3169,21 +3172,28 @@ static void *snd_usb_audio_probe(struct 
 	snd_usb_audio_t *chip;
 	struct usb_host_interface *alts;
 	int ifnum;
+	u32 id;
 
 	alts = &intf->altsetting[0];
 	ifnum = get_iface_desc(alts)->bInterfaceNumber;
+	id = USB_ID(le16_to_cpu(dev->descriptor.idVendor),
+		    le16_to_cpu(dev->descriptor.idProduct));
 
 	if (quirk && quirk->ifnum >= 0 && ifnum != quirk->ifnum)
 		goto __err_val;
 
 	/* SB Extigy needs special boot-up sequence */
 	/* if more models come, this will go to the quirk list. */
-	if (le16_to_cpu(dev->descriptor.idVendor) == 0x041e && 
-	    le16_to_cpu(dev->descriptor.idProduct) == 0x3000) {
+	if (id == USB_ID(0x041e, 0x3000)) {
 		if (snd_usb_extigy_boot_quirk(dev, intf) < 0)
 			goto __err_val;
 		config = dev->actconfig;
 	}
+	/* SB Audigy 2 NX needs its own boot-up magic, too */
+	if (id == USB_ID(0x041e, 0x3020)) {
+		if (snd_usb_audigy2nx_boot_quirk(dev) < 0)
+			goto __err_val;
+	}
 
 	/*
 	 * found a config.  now register to ALSA
@@ -3213,11 +3223,12 @@ static void *snd_usb_audio_probe(struct 
 		}
 		for (i = 0; i < SNDRV_CARDS; i++)
 			if (enable[i] && ! usb_chip[i] &&
-			    (vid[i] == -1 || vid[i] == le16_to_cpu(dev->descriptor.idVendor)) &&
-			    (pid[i] == -1 || pid[i] == le16_to_cpu(dev->descriptor.idProduct))) {
+			    (vid[i] == -1 || vid[i] == USB_ID_VENDOR(id)) &&
+			    (pid[i] == -1 || pid[i] == USB_ID_PRODUCT(id))) {
 				if (snd_usb_audio_create(dev, i, quirk, &chip) < 0) {
 					goto __error;
 				}
+				snd_card_set_dev(chip->card, &intf->dev);
 				break;
 			}
 		if (! chip) {
@@ -3281,11 +3292,15 @@ static void snd_usb_audio_disconnect(str
 		snd_card_disconnect(card);
 		/* release the pcm resources */
 		list_for_each(p, &chip->pcm_list) {
-			snd_usb_stream_disconnect(p, &usb_audio_driver);
+			snd_usb_stream_disconnect(p);
 		}
 		/* release the midi resources */
 		list_for_each(p, &chip->midi_list) {
-			snd_usbmidi_disconnect(p, &usb_audio_driver);
+			snd_usbmidi_disconnect(p);
+		}
+		/* release mixer resources */
+		list_for_each(p, &chip->mixer_list) {
+			snd_usb_mixer_disconnect(p);
 		}
 		usb_chip[chip->index] = NULL;
 		up(&register_mutex);
diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h
--- a/sound/usb/usbaudio.h
+++ b/sound/usb/usbaudio.h
@@ -118,6 +118,11 @@
 /* maximum number of endpoints per interface */
 #define MIDI_MAX_ENDPOINTS 2
 
+/* handling of USB vendor/product ID pairs as 32-bit numbers */
+#define USB_ID(vendor, product) (((vendor) << 16) | (product))
+#define USB_ID_VENDOR(id) ((id) >> 16)
+#define USB_ID_PRODUCT(id) ((u16)(id))
+
 /*
  */
 
@@ -127,6 +132,7 @@ struct snd_usb_audio {
 	int index;
 	struct usb_device *dev;
 	snd_card_t *card;
+	u32 usb_id;
 	int shutdown;
 	int num_interfaces;
 
@@ -136,7 +142,7 @@ struct snd_usb_audio {
 	struct list_head midi_list;	/* list of midi interfaces */
 	int next_midi_device;
 
-	unsigned int ignore_ctl_error;	/* for mixer */
+	struct list_head mixer_list;	/* list of mixer interfaces */
 };
 
 /*
@@ -147,20 +153,24 @@ struct snd_usb_audio {
 #define QUIRK_NO_INTERFACE		-2
 #define QUIRK_ANY_INTERFACE		-1
 
-/* quirk type */
-#define QUIRK_MIDI_FIXED_ENDPOINT	0
-#define QUIRK_MIDI_YAMAHA		1
-#define QUIRK_MIDI_MIDIMAN		2
-#define QUIRK_COMPOSITE			3
-#define QUIRK_AUDIO_FIXED_ENDPOINT	4
-#define QUIRK_AUDIO_STANDARD_INTERFACE	5
-#define QUIRK_MIDI_STANDARD_INTERFACE	6
-#define QUIRK_AUDIO_EDIROL_UA700_UA25	7
-#define QUIRK_AUDIO_EDIROL_UA1000	8
-#define QUIRK_IGNORE_INTERFACE		9
-#define QUIRK_MIDI_NOVATION		10
-#define QUIRK_MIDI_MOTU			11
-#define QUIRK_MIDI_EMAGIC		12
+enum quirk_type {
+	QUIRK_IGNORE_INTERFACE,
+	QUIRK_COMPOSITE,
+	QUIRK_MIDI_STANDARD_INTERFACE,
+	QUIRK_MIDI_FIXED_ENDPOINT,
+	QUIRK_MIDI_YAMAHA,
+	QUIRK_MIDI_MIDIMAN,
+	QUIRK_MIDI_NOVATION,
+	QUIRK_MIDI_RAW,
+	QUIRK_MIDI_EMAGIC,
+	QUIRK_MIDI_MIDITECH,
+	QUIRK_AUDIO_STANDARD_INTERFACE,
+	QUIRK_AUDIO_FIXED_ENDPOINT,
+	QUIRK_AUDIO_EDIROL_UA700_UA25,
+	QUIRK_AUDIO_EDIROL_UA1000,
+
+	QUIRK_TYPE_COUNT
+};
 
 typedef struct snd_usb_audio_quirk snd_usb_audio_quirk_t;
 typedef struct snd_usb_midi_endpoint_info snd_usb_midi_endpoint_info_t;
@@ -169,7 +179,7 @@ struct snd_usb_audio_quirk {
 	const char *vendor_name;
 	const char *product_name;
 	int16_t ifnum;
-	int16_t type;
+	uint16_t type;
 	const void *data;
 };
 
@@ -199,11 +209,13 @@ struct snd_usb_midi_endpoint_info {
 
 /* for QUIRK_IGNORE_INTERFACE, data is NULL */
 
-/* for QUIRK_MIDI_NOVATION and _MOTU, data is NULL */
+/* for QUIRK_MIDI_NOVATION and _RAW, data is NULL */
 
 /* for QUIRK_MIDI_EMAGIC, data points to a snd_usb_midi_endpoint_info
  * structure (out_cables and in_cables only) */
 
+/* for QUIRK_MIDI_MIDITECH, data is NULL */
+
 /*
  */
 
@@ -219,11 +231,12 @@ void *snd_usb_find_csint_desc(void *desc
 int snd_usb_ctl_msg(struct usb_device *dev, unsigned int pipe, __u8 request, __u8 requesttype, __u16 value, __u16 index, void *data, __u16 size, int timeout);
 
 int snd_usb_create_mixer(snd_usb_audio_t *chip, int ctrlif);
+void snd_usb_mixer_disconnect(struct list_head *p);
 
 int snd_usb_create_midi_interface(snd_usb_audio_t *chip, struct usb_interface *iface, const snd_usb_audio_quirk_t *quirk);
 void snd_usbmidi_input_stop(struct list_head* p);
 void snd_usbmidi_input_start(struct list_head* p);
-void snd_usbmidi_disconnect(struct list_head *p, struct usb_driver *driver);
+void snd_usbmidi_disconnect(struct list_head *p);
 
 /*
  * retrieve usb_interface descriptor from the host interface
diff --git a/sound/usb/usbmidi.c b/sound/usb/usbmidi.c
--- a/sound/usb/usbmidi.c
+++ b/sound/usb/usbmidi.c
@@ -524,16 +524,16 @@ static struct usb_protocol_ops snd_usbmi
 };
 
 /*
- * Mark of the Unicorn USB MIDI protocol: raw MIDI.
+ * "raw" protocol: used by the MOTU FastLane.
  */
 
-static void snd_usbmidi_motu_input(snd_usb_midi_in_endpoint_t* ep,
-				   uint8_t* buffer, int buffer_length)
+static void snd_usbmidi_raw_input(snd_usb_midi_in_endpoint_t* ep,
+				  uint8_t* buffer, int buffer_length)
 {
 	snd_usbmidi_input_data(ep, 0, buffer, buffer_length);
 }
 
-static void snd_usbmidi_motu_output(snd_usb_midi_out_endpoint_t* ep)
+static void snd_usbmidi_raw_output(snd_usb_midi_out_endpoint_t* ep)
 {
 	int count;
 
@@ -549,9 +549,9 @@ static void snd_usbmidi_motu_output(snd_
 	ep->urb->transfer_buffer_length = count;
 }
 
-static struct usb_protocol_ops snd_usbmidi_motu_ops = {
-	.input = snd_usbmidi_motu_input,
-	.output = snd_usbmidi_motu_output,
+static struct usb_protocol_ops snd_usbmidi_raw_ops = {
+	.input = snd_usbmidi_raw_input,
+	.output = snd_usbmidi_raw_output,
 };
 
 /*
@@ -912,7 +912,7 @@ static void snd_usbmidi_free(snd_usb_mid
 /*
  * Unlinks all URBs (must be done before the usb_device is deleted).
  */
-void snd_usbmidi_disconnect(struct list_head* p, struct usb_driver *driver)
+void snd_usbmidi_disconnect(struct list_head* p)
 {
 	snd_usb_midi_t* umidi;
 	int i;
@@ -955,88 +955,87 @@ static snd_rawmidi_substream_t* snd_usbm
  * such as internal control or synthesizer ports.
  */
 static struct {
-	__u16 vendor;
-	__u16 product;
+	u32 id;
 	int port;
 	const char *name_format;
 } snd_usbmidi_port_names[] = {
 	/* Roland UA-100 */
-	{0x0582, 0x0000, 2, "%s Control"},
+	{ USB_ID(0x0582, 0x0000), 2, "%s Control" },
 	/* Roland SC-8850 */
-	{0x0582, 0x0003, 0, "%s Part A"},
-	{0x0582, 0x0003, 1, "%s Part B"},
-	{0x0582, 0x0003, 2, "%s Part C"},
-	{0x0582, 0x0003, 3, "%s Part D"},
-	{0x0582, 0x0003, 4, "%s MIDI 1"},
-	{0x0582, 0x0003, 5, "%s MIDI 2"},
+	{ USB_ID(0x0582, 0x0003), 0, "%s Part A" },
+	{ USB_ID(0x0582, 0x0003), 1, "%s Part B" },
+	{ USB_ID(0x0582, 0x0003), 2, "%s Part C" },
+	{ USB_ID(0x0582, 0x0003), 3, "%s Part D" },
+	{ USB_ID(0x0582, 0x0003), 4, "%s MIDI 1" },
+	{ USB_ID(0x0582, 0x0003), 5, "%s MIDI 2" },
 	/* Roland U-8 */
-	{0x0582, 0x0004, 0, "%s MIDI"},
-	{0x0582, 0x0004, 1, "%s Control"},
+	{ USB_ID(0x0582, 0x0004), 0, "%s MIDI" },
+	{ USB_ID(0x0582, 0x0004), 1, "%s Control" },
 	/* Roland SC-8820 */
-	{0x0582, 0x0007, 0, "%s Part A"},
-	{0x0582, 0x0007, 1, "%s Part B"},
-	{0x0582, 0x0007, 2, "%s MIDI"},
+	{ USB_ID(0x0582, 0x0007), 0, "%s Part A" },
+	{ USB_ID(0x0582, 0x0007), 1, "%s Part B" },
+	{ USB_ID(0x0582, 0x0007), 2, "%s MIDI" },
 	/* Roland SK-500 */
-	{0x0582, 0x000b, 0, "%s Part A"},
-	{0x0582, 0x000b, 1, "%s Part B"},
-	{0x0582, 0x000b, 2, "%s MIDI"},
+	{ USB_ID(0x0582, 0x000b), 0, "%s Part A" },
+	{ USB_ID(0x0582, 0x000b), 1, "%s Part B" },
+	{ USB_ID(0x0582, 0x000b), 2, "%s MIDI" },
 	/* Roland SC-D70 */
-	{0x0582, 0x000c, 0, "%s Part A"},
-	{0x0582, 0x000c, 1, "%s Part B"},
-	{0x0582, 0x000c, 2, "%s MIDI"},
+	{ USB_ID(0x0582, 0x000c), 0, "%s Part A" },
+	{ USB_ID(0x0582, 0x000c), 1, "%s Part B" },
+	{ USB_ID(0x0582, 0x000c), 2, "%s MIDI" },
 	/* Edirol UM-880 */
-	{0x0582, 0x0014, 8, "%s Control"},
+	{ USB_ID(0x0582, 0x0014), 8, "%s Control" },
 	/* Edirol SD-90 */
-	{0x0582, 0x0016, 0, "%s Part A"},
-	{0x0582, 0x0016, 1, "%s Part B"},
-	{0x0582, 0x0016, 2, "%s MIDI 1"},
-	{0x0582, 0x0016, 3, "%s MIDI 2"},
+	{ USB_ID(0x0582, 0x0016), 0, "%s Part A" },
+	{ USB_ID(0x0582, 0x0016), 1, "%s Part B" },
+	{ USB_ID(0x0582, 0x0016), 2, "%s MIDI 1" },
+	{ USB_ID(0x0582, 0x0016), 3, "%s MIDI 2" },
 	/* Edirol UM-550 */
-	{0x0582, 0x0023, 5, "%s Control"},
+	{ USB_ID(0x0582, 0x0023), 5, "%s Control" },
 	/* Edirol SD-20 */
-	{0x0582, 0x0027, 0, "%s Part A"},
-	{0x0582, 0x0027, 1, "%s Part B"},
-	{0x0582, 0x0027, 2, "%s MIDI"},
+	{ USB_ID(0x0582, 0x0027), 0, "%s Part A" },
+	{ USB_ID(0x0582, 0x0027), 1, "%s Part B" },
+	{ USB_ID(0x0582, 0x0027), 2, "%s MIDI" },
 	/* Edirol SD-80 */
-	{0x0582, 0x0029, 0, "%s Part A"},
-	{0x0582, 0x0029, 1, "%s Part B"},
-	{0x0582, 0x0029, 2, "%s MIDI 1"},
-	{0x0582, 0x0029, 3, "%s MIDI 2"},
+	{ USB_ID(0x0582, 0x0029), 0, "%s Part A" },
+	{ USB_ID(0x0582, 0x0029), 1, "%s Part B" },
+	{ USB_ID(0x0582, 0x0029), 2, "%s MIDI 1" },
+	{ USB_ID(0x0582, 0x0029), 3, "%s MIDI 2" },
 	/* Edirol UA-700 */
-	{0x0582, 0x002b, 0, "%s MIDI"},
-	{0x0582, 0x002b, 1, "%s Control"},
+	{ USB_ID(0x0582, 0x002b), 0, "%s MIDI" },
+	{ USB_ID(0x0582, 0x002b), 1, "%s Control" },
 	/* Roland VariOS */
-	{0x0582, 0x002f, 0, "%s MIDI"},
-	{0x0582, 0x002f, 1, "%s External MIDI"},
-	{0x0582, 0x002f, 2, "%s Sync"},
+	{ USB_ID(0x0582, 0x002f), 0, "%s MIDI" },
+	{ USB_ID(0x0582, 0x002f), 1, "%s External MIDI" },
+	{ USB_ID(0x0582, 0x002f), 2, "%s Sync" },
 	/* Edirol PCR */
-	{0x0582, 0x0033, 0, "%s MIDI"},
-	{0x0582, 0x0033, 1, "%s 1"},
-	{0x0582, 0x0033, 2, "%s 2"},
+	{ USB_ID(0x0582, 0x0033), 0, "%s MIDI" },
+	{ USB_ID(0x0582, 0x0033), 1, "%s 1" },
+	{ USB_ID(0x0582, 0x0033), 2, "%s 2" },
 	/* BOSS GS-10 */
-	{0x0582, 0x003b, 0, "%s MIDI"},
-	{0x0582, 0x003b, 1, "%s Control"},
+	{ USB_ID(0x0582, 0x003b), 0, "%s MIDI" },
+	{ USB_ID(0x0582, 0x003b), 1, "%s Control" },
 	/* Edirol UA-1000 */
-	{0x0582, 0x0044, 0, "%s MIDI"},
-	{0x0582, 0x0044, 1, "%s Control"},
+	{ USB_ID(0x0582, 0x0044), 0, "%s MIDI" },
+	{ USB_ID(0x0582, 0x0044), 1, "%s Control" },
 	/* Edirol UR-80 */
-	{0x0582, 0x0048, 0, "%s MIDI"},
-	{0x0582, 0x0048, 1, "%s 1"},
-	{0x0582, 0x0048, 2, "%s 2"},
+	{ USB_ID(0x0582, 0x0048), 0, "%s MIDI" },
+	{ USB_ID(0x0582, 0x0048), 1, "%s 1" },
+	{ USB_ID(0x0582, 0x0048), 2, "%s 2" },
 	/* Edirol PCR-A */
-	{0x0582, 0x004d, 0, "%s MIDI"},
-	{0x0582, 0x004d, 1, "%s 1"},
-	{0x0582, 0x004d, 2, "%s 2"},
+	{ USB_ID(0x0582, 0x004d), 0, "%s MIDI" },
+	{ USB_ID(0x0582, 0x004d), 1, "%s 1" },
+	{ USB_ID(0x0582, 0x004d), 2, "%s 2" },
 	/* M-Audio MidiSport 8x8 */
-	{0x0763, 0x1031, 8, "%s Control"},
-	{0x0763, 0x1033, 8, "%s Control"},
+	{ USB_ID(0x0763, 0x1031), 8, "%s Control" },
+	{ USB_ID(0x0763, 0x1033), 8, "%s Control" },
 	/* MOTU Fastlane */
-	{0x07fd, 0x0001, 0, "%s MIDI A"},
-	{0x07fd, 0x0001, 1, "%s MIDI B"},
+	{ USB_ID(0x07fd, 0x0001), 0, "%s MIDI A" },
+	{ USB_ID(0x07fd, 0x0001), 1, "%s MIDI B" },
 	/* Emagic Unitor8/AMT8/MT4 */
-	{0x086a, 0x0001, 8, "%s Broadcast"},
-	{0x086a, 0x0002, 8, "%s Broadcast"},
-	{0x086a, 0x0003, 4, "%s Broadcast"},
+	{ USB_ID(0x086a, 0x0001), 8, "%s Broadcast" },
+	{ USB_ID(0x086a, 0x0002), 8, "%s Broadcast" },
+	{ USB_ID(0x086a, 0x0003), 4, "%s Broadcast" },
 };
 
 static void snd_usbmidi_init_substream(snd_usb_midi_t* umidi,
@@ -1044,7 +1043,6 @@ static void snd_usbmidi_init_substream(s
 				       snd_rawmidi_substream_t** rsubstream)
 {
 	int i;
-	__u16 vendor, product;
 	const char *name_format;
 
 	snd_rawmidi_substream_t* substream = snd_usbmidi_find_substream(umidi, stream, number);
@@ -1055,11 +1053,8 @@ static void snd_usbmidi_init_substream(s
 
 	/* TODO: read port name from jack descriptor */
 	name_format = "%s MIDI %d";
-	vendor = le16_to_cpu(umidi->chip->dev->descriptor.idVendor);
-	product = le16_to_cpu(umidi->chip->dev->descriptor.idProduct);
 	for (i = 0; i < ARRAY_SIZE(snd_usbmidi_port_names); ++i) {
-		if (snd_usbmidi_port_names[i].vendor == vendor &&
-		    snd_usbmidi_port_names[i].product == product &&
+		if (snd_usbmidi_port_names[i].id == umidi->chip->usb_id &&
 		    snd_usbmidi_port_names[i].port == number) {
 			name_format = snd_usbmidi_port_names[i].name_format;
 			break;
@@ -1226,9 +1221,12 @@ static int snd_usbmidi_detect_endpoints(
 	struct usb_endpoint_descriptor* epd;
 	int i, out_eps = 0, in_eps = 0;
 
-	if (le16_to_cpu(umidi->chip->dev->descriptor.idVendor) == 0x0582)
+	if (USB_ID_VENDOR(umidi->chip->usb_id) == 0x0582)
 		snd_usbmidi_switch_roland_altsetting(umidi);
 
+	if (endpoint[0].out_ep || endpoint[0].in_ep)
+		return 0;	
+
 	intf = umidi->iface;
 	if (!intf || intf->num_altsetting < 1)
 		return -ENOENT;
@@ -1507,8 +1505,8 @@ int snd_usb_create_midi_interface(snd_us
 			umidi->usb_protocol_ops = &snd_usbmidi_novation_ops;
 			err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
 			break;
-		case QUIRK_MIDI_MOTU:
-			umidi->usb_protocol_ops = &snd_usbmidi_motu_ops;
+		case QUIRK_MIDI_RAW:
+			umidi->usb_protocol_ops = &snd_usbmidi_raw_ops;
 			err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
 			break;
 		case QUIRK_MIDI_EMAGIC:
@@ -1517,6 +1515,9 @@ int snd_usb_create_midi_interface(snd_us
 			       sizeof(snd_usb_midi_endpoint_info_t));
 			err = snd_usbmidi_detect_endpoints(umidi, &endpoints[0], 1);
 			break;
+		case QUIRK_MIDI_MIDITECH:
+			err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
+			break;
 		default:
 			snd_printd(KERN_ERR "invalid quirk type %d\n", quirk->type);
 			err = -ENXIO;
diff --git a/sound/usb/usbmixer.c b/sound/usb/usbmixer.c
--- a/sound/usb/usbmixer.c
+++ b/sound/usb/usbmixer.c
@@ -35,10 +35,11 @@
 #include <linux/usb.h>
 #include <sound/core.h>
 #include <sound/control.h>
+#include <sound/hwdep.h>
+#include <sound/info.h>
 
 #include "usbaudio.h"
 
-
 /*
  */
 
@@ -50,6 +51,31 @@ typedef struct usb_audio_term usb_audio_
 typedef struct usb_mixer_elem_info usb_mixer_elem_info_t;
 
 
+struct usb_mixer_interface {
+	snd_usb_audio_t *chip;
+	unsigned int ctrlif;
+	struct list_head list;
+	unsigned int ignore_ctl_error;
+	struct urb *urb;
+	usb_mixer_elem_info_t **id_elems; /* array[256], indexed by unit id */
+
+	/* Sound Blaster remote control stuff */
+	enum {
+		RC_NONE,
+		RC_EXTIGY,
+		RC_AUDIGY2NX,
+	} rc_type;
+	unsigned long rc_hwdep_open;
+	u32 rc_code;
+	wait_queue_head_t rc_waitq;
+	struct urb *rc_urb;
+	struct usb_ctrlrequest *rc_setup_packet;
+	u8 rc_buffer[6];
+
+	u8 audigy2nx_leds[3];
+};
+
+
 struct usb_audio_term {
 	int id;
 	int type;
@@ -62,26 +88,26 @@ struct usbmix_name_map;
 
 struct usb_mixer_build {
 	snd_usb_audio_t *chip;
+	struct usb_mixer_interface *mixer;
 	unsigned char *buffer;
 	unsigned int buflen;
-	unsigned int ctrlif;
-	unsigned short vendor;
-	unsigned short product;
-	DECLARE_BITMAP(unitbitmap, 32*32);
+	DECLARE_BITMAP(unitbitmap, 256);
 	usb_audio_term_t oterm;
 	const struct usbmix_name_map *map;
+	const struct usbmix_selector_map *selector_map;
 };
 
 struct usb_mixer_elem_info {
-	snd_usb_audio_t *chip;
-	unsigned int ctrlif;
+	struct usb_mixer_interface *mixer;
+	usb_mixer_elem_info_t *next_id_elem; /* list of controls with same id */
+	snd_ctl_elem_id_t *elem_id;
 	unsigned int id;
 	unsigned int control;	/* CS or ICN (high byte) */
 	unsigned int cmask; /* channel mask bitmap: 0 = master */
 	int channels;
 	int val_type;
 	int min, max, res;
-	unsigned int initialized: 1;
+	u8 initialized;
 };
 
 
@@ -187,6 +213,21 @@ static int check_ignored_ctl(mixer_build
 	return 0;
 }
 
+/* get the mapped selector source name */
+static int check_mapped_selector_name(mixer_build_t *state, int unitid,
+				      int index, char *buf, int buflen)
+{
+	const struct usbmix_selector_map *p;
+
+	if (! state->selector_map)
+		return 0;
+	for (p = state->selector_map; p->id; p++) {
+		if (p->id == unitid && index < p->count)
+			return strlcpy(buf, p->names[index], buflen);
+	}
+	return 0;
+}
+
 /*
  * find an audio control unit with the given unit id
  */
@@ -301,16 +342,18 @@ static int get_ctl_value(usb_mixer_elem_
 	int timeout = 10;
 
 	while (timeout-- > 0) {
-		if (snd_usb_ctl_msg(cval->chip->dev, usb_rcvctrlpipe(cval->chip->dev, 0),
+		if (snd_usb_ctl_msg(cval->mixer->chip->dev,
+				    usb_rcvctrlpipe(cval->mixer->chip->dev, 0),
 				    request,
 				    USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
-				    validx, cval->ctrlif | (cval->id << 8),
+				    validx, cval->mixer->ctrlif | (cval->id << 8),
 				    buf, val_len, 100) >= 0) {
 			*value_ret = convert_signed_value(cval, snd_usb_combine_bytes(buf, val_len));
 			return 0;
 		}
 	}
-	snd_printdd(KERN_ERR "cannot get ctl value: req = 0x%x, wValue = 0x%x, wIndex = 0x%x, type = %d\n", request, validx, cval->ctrlif | (cval->id << 8), cval->val_type);
+	snd_printdd(KERN_ERR "cannot get ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n",
+		    request, validx, cval->mixer->ctrlif | (cval->id << 8), cval->val_type);
 	return -EINVAL;
 }
 
@@ -320,7 +363,7 @@ static int get_cur_ctl_value(usb_mixer_e
 }
 
 /* channel = 0: master, 1 = first channel */
-inline static int get_cur_mix_value(usb_mixer_elem_info_t *cval, int channel, int *value)
+static inline int get_cur_mix_value(usb_mixer_elem_info_t *cval, int channel, int *value)
 {
 	return get_ctl_value(cval, GET_CUR, (cval->control << 8) | channel, value);
 }
@@ -339,13 +382,15 @@ static int set_ctl_value(usb_mixer_elem_
 	buf[0] = value_set & 0xff;
 	buf[1] = (value_set >> 8) & 0xff;
 	while (timeout -- > 0)
-		if (snd_usb_ctl_msg(cval->chip->dev, usb_sndctrlpipe(cval->chip->dev, 0),
+		if (snd_usb_ctl_msg(cval->mixer->chip->dev,
+				    usb_sndctrlpipe(cval->mixer->chip->dev, 0),
 				    request,
 				    USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT,
-				    validx, cval->ctrlif | (cval->id << 8),
+				    validx, cval->mixer->ctrlif | (cval->id << 8),
 				    buf, val_len, 100) >= 0)
 			return 0;
-	snd_printdd(KERN_ERR "cannot set ctl value: req = 0x%x, wValue = 0x%x, wIndex = 0x%x, type = %d, data = 0x%x/0x%x\n", request, validx, cval->ctrlif | (cval->id << 8), cval->val_type, buf[0], buf[1]);
+	snd_printdd(KERN_ERR "cannot set ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d, data = %#x/%#x\n",
+		    request, validx, cval->mixer->ctrlif | (cval->id << 8), cval->val_type, buf[0], buf[1]);
 	return -EINVAL;
 }
 
@@ -354,7 +399,7 @@ static int set_cur_ctl_value(usb_mixer_e
 	return set_ctl_value(cval, SET_CUR, validx, value);
 }
 
-inline static int set_cur_mix_value(usb_mixer_elem_info_t *cval, int channel, int value)
+static inline int set_cur_mix_value(usb_mixer_elem_info_t *cval, int channel, int value)
 {
 	return set_ctl_value(cval, SET_CUR, (cval->control << 8) | channel, value);
 }
@@ -385,16 +430,22 @@ static int check_matrix_bitmap(unsigned 
  * if failed, give up and free the control instance.
  */
 
-static int add_control_to_empty(snd_card_t *card, snd_kcontrol_t *kctl)
+static int add_control_to_empty(mixer_build_t *state, snd_kcontrol_t *kctl)
 {
+	usb_mixer_elem_info_t *cval = kctl->private_data;
 	int err;
-	while (snd_ctl_find_id(card, &kctl->id))
+
+	while (snd_ctl_find_id(state->chip->card, &kctl->id))
 		kctl->id.index++;
-	if ((err = snd_ctl_add(card, kctl)) < 0) {
+	if ((err = snd_ctl_add(state->chip->card, kctl)) < 0) {
 		snd_printd(KERN_ERR "cannot add control (err = %d)\n", err);
 		snd_ctl_free_one(kctl);
+		return err;
 	}
-	return err;
+	cval->elem_id = &kctl->id;
+	cval->next_id_elem = state->mixer->id_elems[cval->id];
+	state->mixer->id_elems[cval->id] = cval;
+	return 0;
 }
 
 
@@ -572,10 +623,8 @@ static struct usb_feature_control_info a
 /* private_free callback */
 static void usb_mixer_elem_free(snd_kcontrol_t *kctl)
 {
-	if (kctl->private_data) {
-		kfree(kctl->private_data);
-		kctl->private_data = NULL;
-	}
+	kfree(kctl->private_data);
+	kctl->private_data = NULL;
 }
 
 
@@ -608,7 +657,8 @@ static int get_min_max(usb_mixer_elem_in
 		}
 		if (get_ctl_value(cval, GET_MAX, (cval->control << 8) | minchn, &cval->max) < 0 ||
 		    get_ctl_value(cval, GET_MIN, (cval->control << 8) | minchn, &cval->min) < 0) {
-			snd_printd(KERN_ERR "%d:%d: cannot get min/max values for control %d (id %d)\n", cval->id, cval->ctrlif, cval->control, cval->id);
+			snd_printd(KERN_ERR "%d:%d: cannot get min/max values for control %d (id %d)\n",
+				   cval->id, cval->mixer->ctrlif, cval->control, cval->id);
 			return -EINVAL;
 		}
 		if (get_ctl_value(cval, GET_RES, (cval->control << 8) | minchn, &cval->res) < 0) {
@@ -668,7 +718,7 @@ static int mixer_ctl_feature_get(snd_kco
 			if (cval->cmask & (1 << c)) {
 				err = get_cur_mix_value(cval, c + 1, &val);
 				if (err < 0) {
-					if (cval->chip->ignore_ctl_error) {
+					if (cval->mixer->ignore_ctl_error) {
 						ucontrol->value.integer.value[0] = cval->min;
 						return 0;
 					}
@@ -684,7 +734,7 @@ static int mixer_ctl_feature_get(snd_kco
 		/* master channel */
 		err = get_cur_mix_value(cval, 0, &val);
 		if (err < 0) {
-			if (cval->chip->ignore_ctl_error) {
+			if (cval->mixer->ignore_ctl_error) {
 				ucontrol->value.integer.value[0] = cval->min;
 				return 0;
 			}
@@ -710,7 +760,7 @@ static int mixer_ctl_feature_put(snd_kco
 			if (cval->cmask & (1 << c)) {
 				err = get_cur_mix_value(cval, c + 1, &oval);
 				if (err < 0) {
-					if (cval->chip->ignore_ctl_error)
+					if (cval->mixer->ignore_ctl_error)
 						return 0;
 					return err;
 				}
@@ -727,7 +777,7 @@ static int mixer_ctl_feature_put(snd_kco
 	} else {
 		/* master channel */
 		err = get_cur_mix_value(cval, 0, &oval);
-		if (err < 0 && cval->chip->ignore_ctl_error)
+		if (err < 0 && cval->mixer->ignore_ctl_error)
 			return 0;
 		if (err < 0)
 			return err;
@@ -779,8 +829,7 @@ static void build_feature_ctl(mixer_buil
 		snd_printk(KERN_ERR "cannot malloc kcontrol\n");
 		return;
 	}
-	cval->chip = state->chip;
-	cval->ctrlif = state->ctrlif;
+	cval->mixer = state->mixer;
 	cval->id = unitid;
 	cval->control = control;
 	cval->cmask = ctl_mask;
@@ -855,16 +904,21 @@ static void build_feature_ctl(mixer_buil
 	/* note that detection between firmware 2.1.1.7 (N101) and later 2.1.1.21 */
 	/* is not very clear from datasheets */
 	/* I hope that the min value is -15360 for newer firmware --jk */
-	if (((state->vendor == 0x471 && (state->product == 0x104 || state->product == 0x105 || state->product == 0x101)) ||
-	     (state->vendor == 0x672 && state->product == 0x1041)) && !strcmp(kctl->id.name, "PCM Playback Volume") &&
-	     cval->min == -15616) {
-		snd_printk("USB Audio: using volume control quirk for the UDA1321/N101 chip\n");
-		cval->max = -256;
+	switch (state->chip->usb_id) {
+	case USB_ID(0x0471, 0x0101):
+	case USB_ID(0x0471, 0x0104):
+	case USB_ID(0x0471, 0x0105):
+	case USB_ID(0x0672, 0x1041):
+		if (!strcmp(kctl->id.name, "PCM Playback Volume") &&
+		    cval->min == -15616) {
+			snd_printk("using volume control quirk for the UDA1321/N101 chip\n");
+			cval->max = -256;
+		}
 	}
 
 	snd_printdd(KERN_INFO "[%d] FU [%s] ch = %d, val = %d/%d/%d\n",
 		    cval->id, kctl->id.name, cval->channels, cval->min, cval->max, cval->res);
-	add_control_to_empty(state->chip->card, kctl);
+	add_control_to_empty(state, kctl);
 }
 
 
@@ -947,8 +1001,7 @@ static void build_mixer_unit_ctl(mixer_b
 	if (! cval)
 		return;
 
-	cval->chip = state->chip;
-	cval->ctrlif = state->ctrlif;
+	cval->mixer = state->mixer;
 	cval->id = unitid;
 	cval->control = in_ch + 1; /* based on 1 */
 	cval->val_type = USB_MIXER_S16;
@@ -979,7 +1032,7 @@ static void build_mixer_unit_ctl(mixer_b
 
 	snd_printdd(KERN_INFO "[%d] MU [%s] ch = %d, val = %d/%d\n",
 		    cval->id, kctl->id.name, cval->channels, cval->min, cval->max);
-	add_control_to_empty(state->chip->card, kctl);
+	add_control_to_empty(state, kctl);
 }
 
 
@@ -1042,7 +1095,7 @@ static int mixer_ctl_procunit_get(snd_kc
 	int err, val;
 
 	err = get_cur_ctl_value(cval, cval->control << 8, &val);
-	if (err < 0 && cval->chip->ignore_ctl_error) {
+	if (err < 0 && cval->mixer->ignore_ctl_error) {
 		ucontrol->value.integer.value[0] = cval->min;
 		return 0;
 	}
@@ -1061,7 +1114,7 @@ static int mixer_ctl_procunit_put(snd_kc
 
 	err = get_cur_ctl_value(cval, cval->control << 8, &oval);
 	if (err < 0) {
-		if (cval->chip->ignore_ctl_error)
+		if (cval->mixer->ignore_ctl_error)
 			return 0;
 		return err;
 	}
@@ -1179,9 +1232,6 @@ static int build_audio_procunit(mixer_bu
 	}
 
 	type = combine_word(&dsc[4]);
-	if (! type)
-		return 0; /* undefined? */
-
 	for (info = list; info && info->type; info++)
 		if (info->type == type)
 			break;
@@ -1199,8 +1249,7 @@ static int build_audio_procunit(mixer_bu
 			snd_printk(KERN_ERR "cannot malloc kcontrol\n");
 			return -ENOMEM;
 		}
-		cval->chip = state->chip;
-		cval->ctrlif = state->ctrlif;
+		cval->mixer = state->mixer;
 		cval->id = unitid;
 		cval->control = valinfo->control;
 		cval->val_type = valinfo->val_type;
@@ -1241,7 +1290,7 @@ static int build_audio_procunit(mixer_bu
 
 		snd_printdd(KERN_INFO "[%d] PU [%s] ch = %d, val = %d/%d\n",
 			    cval->id, kctl->id.name, cval->channels, cval->min, cval->max);
-		if ((err = add_control_to_empty(state->chip->card, kctl)) < 0)
+		if ((err = add_control_to_empty(state, kctl)) < 0)
 			return err;
 	}
 	return 0;
@@ -1289,7 +1338,7 @@ static int mixer_ctl_selector_get(snd_kc
 
 	err = get_cur_ctl_value(cval, 0, &val);
 	if (err < 0) {
-		if (cval->chip->ignore_ctl_error) {
+		if (cval->mixer->ignore_ctl_error) {
 			ucontrol->value.enumerated.item[0] = 0;
 			return 0;
 		}
@@ -1308,7 +1357,7 @@ static int mixer_ctl_selector_put(snd_kc
 
 	err = get_cur_ctl_value(cval, 0, &oval);
 	if (err < 0) {
-		if (cval->chip->ignore_ctl_error)
+		if (cval->mixer->ignore_ctl_error)
 			return 0;
 		return err;
 	}
@@ -1386,8 +1435,7 @@ static int parse_audio_selector_unit(mix
 		snd_printk(KERN_ERR "cannot malloc kcontrol\n");
 		return -ENOMEM;
 	}
-	cval->chip = state->chip;
-	cval->ctrlif = state->ctrlif;
+	cval->mixer = state->mixer;
 	cval->id = unitid;
 	cval->val_type = USB_MIXER_U8;
 	cval->channels = 1;
@@ -1415,7 +1463,9 @@ static int parse_audio_selector_unit(mix
 			kfree(cval);
 			return -ENOMEM;
 		}
-		if (check_input_term(state, desc[5 + i], &iterm) >= 0)
+		len = check_mapped_selector_name(state, unitid, i, namelist[i],
+						 MAX_ITEM_NAME_LEN);
+		if (! len && check_input_term(state, desc[5 + i], &iterm) >= 0)
 			len = get_term_name(state, &iterm, namelist[i], MAX_ITEM_NAME_LEN, 0);
 		if (! len)
 			sprintf(namelist[i], "Input %d", i);
@@ -1450,7 +1500,7 @@ static int parse_audio_selector_unit(mix
 
 	snd_printdd(KERN_INFO "[%d] SU [%s] items = %d\n",
 		    cval->id, kctl->id.name, num_ins);
-	if ((err = add_control_to_empty(state->chip->card, kctl)) < 0)
+	if ((err = add_control_to_empty(state, kctl)) < 0)
 		return err;
 
 	return 0;
@@ -1493,41 +1543,55 @@ static int parse_audio_unit(mixer_build_
 	}
 }
 
+static void snd_usb_mixer_free(struct usb_mixer_interface *mixer)
+{
+	kfree(mixer->id_elems);
+	if (mixer->urb) {
+		kfree(mixer->urb->transfer_buffer);
+		usb_free_urb(mixer->urb);
+	}
+	if (mixer->rc_urb)
+		usb_free_urb(mixer->rc_urb);
+	kfree(mixer->rc_setup_packet);
+	kfree(mixer);
+}
+
+static int snd_usb_mixer_dev_free(snd_device_t *device)
+{
+	struct usb_mixer_interface *mixer = device->device_data;
+	snd_usb_mixer_free(mixer);
+	return 0;
+}
+
 /*
  * create mixer controls
  *
  * walk through all OUTPUT_TERMINAL descriptors to search for mixers
  */
-int snd_usb_create_mixer(snd_usb_audio_t *chip, int ctrlif)
+static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer)
 {
 	unsigned char *desc;
 	mixer_build_t state;
 	int err;
 	const struct usbmix_ctl_map *map;
-	struct usb_device_descriptor *dev = &chip->dev->descriptor;
-	struct usb_host_interface *hostif = &usb_ifnum_to_if(chip->dev, ctrlif)->altsetting[0];
-
-	strcpy(chip->card->mixername, "USB Mixer");
+	struct usb_host_interface *hostif;
 
+	hostif = &usb_ifnum_to_if(mixer->chip->dev, mixer->ctrlif)->altsetting[0];
 	memset(&state, 0, sizeof(state));
-	state.chip = chip;
+	state.chip = mixer->chip;
+	state.mixer = mixer;
 	state.buffer = hostif->extra;
 	state.buflen = hostif->extralen;
-	state.ctrlif = ctrlif;
-	state.vendor = le16_to_cpu(dev->idVendor);
-	state.product = le16_to_cpu(dev->idProduct);
 
 	/* check the mapping table */
-	for (map = usbmix_ctl_maps; map->vendor; map++) {
-		if (map->vendor == state.vendor && map->product == state.product) {
+	for (map = usbmix_ctl_maps; map->id; map++) {
+		if (map->id == state.chip->usb_id) {
 			state.map = map->map;
-			chip->ignore_ctl_error = map->ignore_ctl_error;
+			state.selector_map = map->selector_map;
+			mixer->ignore_ctl_error = map->ignore_ctl_error;
 			break;
 		}
 	}
-#ifdef IGNORE_CTL_ERROR
-	chip->ignore_ctl_error = 1;
-#endif
 
 	desc = NULL;
 	while ((desc = snd_usb_find_csint_desc(hostif->extra, hostif->extralen, desc, OUTPUT_TERMINAL)) != NULL) {
@@ -1543,3 +1607,393 @@ int snd_usb_create_mixer(snd_usb_audio_t
 	}
 	return 0;
 }
+
+static void snd_usb_mixer_notify_id(struct usb_mixer_interface *mixer,
+				    int unitid)
+{
+	usb_mixer_elem_info_t *info;
+
+	for (info = mixer->id_elems[unitid]; info; info = info->next_id_elem)
+		snd_ctl_notify(mixer->chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
+			       info->elem_id);
+}
+
+static void snd_usb_mixer_memory_change(struct usb_mixer_interface *mixer,
+					int unitid)
+{
+	if (mixer->rc_type == RC_NONE)
+		return;
+	/* unit ids specific to Extigy/Audigy 2 NX: */
+	switch (unitid) {
+	case 0: /* remote control */
+		mixer->rc_urb->dev = mixer->chip->dev;
+		usb_submit_urb(mixer->rc_urb, GFP_ATOMIC);
+		break;
+	case 4: /* digital in jack */
+	case 7: /* line in jacks */
+	case 19: /* speaker out jacks */
+	case 20: /* headphones out jack */
+		break;
+	default:
+		snd_printd(KERN_DEBUG "memory change in unknown unit %d\n", unitid);
+		break;
+	}
+}
+
+static void snd_usb_mixer_status_complete(struct urb *urb, struct pt_regs *regs)
+{
+	struct usb_mixer_interface *mixer = urb->context;
+
+	if (urb->status == 0) {
+		u8 *buf = urb->transfer_buffer;
+		int i;
+
+		for (i = urb->actual_length; i >= 2; buf += 2, i -= 2) {
+			snd_printd(KERN_DEBUG "status interrupt: %02x %02x\n",
+				   buf[0], buf[1]);
+			/* ignore any notifications not from the control interface */
+			if ((buf[0] & 0x0f) != 0)
+				continue;
+			if (!(buf[0] & 0x40))
+				snd_usb_mixer_notify_id(mixer, buf[1]);
+			else
+				snd_usb_mixer_memory_change(mixer, buf[1]);
+		}
+	}
+	if (urb->status != -ENOENT && urb->status != -ECONNRESET) {
+		urb->dev = mixer->chip->dev;
+		usb_submit_urb(urb, GFP_ATOMIC);
+	}
+}
+
+/* create the handler for the optional status interrupt endpoint */
+static int snd_usb_mixer_status_create(struct usb_mixer_interface *mixer)
+{
+	struct usb_host_interface *hostif;
+	struct usb_endpoint_descriptor *ep;
+	void *transfer_buffer;
+	int buffer_length;
+	unsigned int epnum;
+
+	hostif = &usb_ifnum_to_if(mixer->chip->dev, mixer->ctrlif)->altsetting[0];
+	/* we need one interrupt input endpoint */
+	if (get_iface_desc(hostif)->bNumEndpoints < 1)
+		return 0;
+	ep = get_endpoint(hostif, 0);
+	if ((ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) != USB_DIR_IN ||
+	    (ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT)
+		return 0;
+
+	epnum = ep->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
+	buffer_length = le16_to_cpu(ep->wMaxPacketSize);
+	transfer_buffer = kmalloc(buffer_length, GFP_KERNEL);
+	if (!transfer_buffer)
+		return -ENOMEM;
+	mixer->urb = usb_alloc_urb(0, GFP_KERNEL);
+	if (!mixer->urb) {
+		kfree(transfer_buffer);
+		return -ENOMEM;
+	}
+	usb_fill_int_urb(mixer->urb, mixer->chip->dev,
+			 usb_rcvintpipe(mixer->chip->dev, epnum),
+			 transfer_buffer, buffer_length,
+			 snd_usb_mixer_status_complete, mixer, ep->bInterval);
+	usb_submit_urb(mixer->urb, GFP_KERNEL);
+	return 0;
+}
+
+static void snd_usb_soundblaster_remote_complete(struct urb *urb,
+						 struct pt_regs *regs)
+{
+	struct usb_mixer_interface *mixer = urb->context;
+	/*
+	 * format of remote control data:
+	 * Extigy:	xx 00
+	 * Audigy 2 NX:	06 80 xx 00 00 00
+	 */
+	int offset = mixer->rc_type == RC_EXTIGY ? 0 : 2;
+	u32 code;
+
+	if (urb->status < 0 || urb->actual_length <= offset)
+		return;
+	code = mixer->rc_buffer[offset];
+	/* the Mute button actually changes the mixer control */
+	if (code == 13)
+		snd_usb_mixer_notify_id(mixer, 18);
+	mixer->rc_code = code;
+	wmb();
+	wake_up(&mixer->rc_waitq);
+}
+
+static int snd_usb_sbrc_hwdep_open(snd_hwdep_t *hw, struct file *file)
+{
+	struct usb_mixer_interface *mixer = hw->private_data;
+
+	if (test_and_set_bit(0, &mixer->rc_hwdep_open))
+		return -EBUSY;
+	return 0;
+}
+
+static int snd_usb_sbrc_hwdep_release(snd_hwdep_t *hw, struct file *file)
+{
+	struct usb_mixer_interface *mixer = hw->private_data;
+
+	clear_bit(0, &mixer->rc_hwdep_open);
+	smp_mb__after_clear_bit();
+	return 0;
+}
+
+static long snd_usb_sbrc_hwdep_read(snd_hwdep_t *hw, char __user *buf,
+				     long count, loff_t *offset)
+{
+	struct usb_mixer_interface *mixer = hw->private_data;
+	int err;
+	u32 rc_code;
+
+	if (count != 1 && count != 4)
+		return -EINVAL;
+	err = wait_event_interruptible(mixer->rc_waitq,
+				       (rc_code = xchg(&mixer->rc_code, 0)) != 0);
+	if (err == 0) {
+		if (count == 1)
+			err = put_user(rc_code, buf);
+		else
+			err = put_user(rc_code, (u32 __user *)buf);
+	}
+	return err < 0 ? err : count;
+}
+
+static unsigned int snd_usb_sbrc_hwdep_poll(snd_hwdep_t *hw, struct file *file,
+					    poll_table *wait)
+{
+	struct usb_mixer_interface *mixer = hw->private_data;
+
+	poll_wait(file, &mixer->rc_waitq, wait);
+	return mixer->rc_code ? POLLIN | POLLRDNORM : 0;
+}
+
+static int snd_usb_soundblaster_remote_init(struct usb_mixer_interface *mixer)
+{
+	snd_hwdep_t *hwdep;
+	int err, len;
+
+	switch (mixer->chip->usb_id) {
+	case USB_ID(0x041e, 0x3000):
+		mixer->rc_type = RC_EXTIGY;
+		len = 2;
+		break;
+	case USB_ID(0x041e, 0x3020):
+		mixer->rc_type = RC_AUDIGY2NX;
+		len = 6;
+		break;
+	default:
+		return 0;
+	}
+
+	init_waitqueue_head(&mixer->rc_waitq);
+	err = snd_hwdep_new(mixer->chip->card, "SB remote control", 0, &hwdep);
+	if (err < 0)
+		return err;
+	snprintf(hwdep->name, sizeof(hwdep->name),
+		 "%s remote control", mixer->chip->card->shortname);
+	hwdep->iface = SNDRV_HWDEP_IFACE_SB_RC;
+	hwdep->private_data = mixer;
+	hwdep->ops.read = snd_usb_sbrc_hwdep_read;
+	hwdep->ops.open = snd_usb_sbrc_hwdep_open;
+	hwdep->ops.release = snd_usb_sbrc_hwdep_release;
+	hwdep->ops.poll = snd_usb_sbrc_hwdep_poll;
+
+	mixer->rc_urb = usb_alloc_urb(0, GFP_KERNEL);
+	if (!mixer->rc_urb)
+		return -ENOMEM;
+	mixer->rc_setup_packet = kmalloc(sizeof(*mixer->rc_setup_packet), GFP_KERNEL);
+	if (!mixer->rc_setup_packet) {
+		usb_free_urb(mixer->rc_urb);
+		mixer->rc_urb = NULL;
+		return -ENOMEM;
+	}
+	mixer->rc_setup_packet->bRequestType =
+		USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE;
+	mixer->rc_setup_packet->bRequest = GET_MEM;
+	mixer->rc_setup_packet->wValue = cpu_to_le16(0);
+	mixer->rc_setup_packet->wIndex = cpu_to_le16(0);
+	mixer->rc_setup_packet->wLength = cpu_to_le16(len);
+	usb_fill_control_urb(mixer->rc_urb, mixer->chip->dev,
+			     usb_rcvctrlpipe(mixer->chip->dev, 0),
+			     (u8*)mixer->rc_setup_packet, mixer->rc_buffer, len,
+			     snd_usb_soundblaster_remote_complete, mixer);
+	return 0;
+}
+
+static int snd_audigy2nx_led_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+{
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
+	uinfo->count = 1;
+	uinfo->value.integer.min = 0;
+	uinfo->value.integer.max = 1;
+	return 0;
+}
+
+static int snd_audigy2nx_led_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
+	int index = kcontrol->private_value;
+
+	ucontrol->value.integer.value[0] = mixer->audigy2nx_leds[index];
+	return 0;
+}
+
+static int snd_audigy2nx_led_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
+	int index = kcontrol->private_value;
+	int value = ucontrol->value.integer.value[0];
+	int err, changed;
+
+	if (value > 1)
+		return -EINVAL;
+	changed = value != mixer->audigy2nx_leds[index];
+	err = snd_usb_ctl_msg(mixer->chip->dev,
+			      usb_sndctrlpipe(mixer->chip->dev, 0), 0x24,
+			      USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
+			      value, index + 2, NULL, 0, 100);
+	if (err < 0)
+		return err;
+	mixer->audigy2nx_leds[index] = value;
+	return changed;
+}
+
+static snd_kcontrol_new_t snd_audigy2nx_controls[] = {
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "CMSS LED Switch",
+		.info = snd_audigy2nx_led_info,
+		.get = snd_audigy2nx_led_get,
+		.put = snd_audigy2nx_led_put,
+		.private_value = 0,
+	},
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Power LED Switch",
+		.info = snd_audigy2nx_led_info,
+		.get = snd_audigy2nx_led_get,
+		.put = snd_audigy2nx_led_put,
+		.private_value = 1,
+	},
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Dolby Digital LED Switch",
+		.info = snd_audigy2nx_led_info,
+		.get = snd_audigy2nx_led_get,
+		.put = snd_audigy2nx_led_put,
+		.private_value = 2,
+	},
+};
+
+static int snd_audigy2nx_controls_create(struct usb_mixer_interface *mixer)
+{
+	int i, err;
+
+	for (i = 0; i < ARRAY_SIZE(snd_audigy2nx_controls); ++i) {
+		err = snd_ctl_add(mixer->chip->card,
+				  snd_ctl_new1(&snd_audigy2nx_controls[i], mixer));
+		if (err < 0)
+			return err;
+	}
+	mixer->audigy2nx_leds[1] = 1; /* Power LED is on by default */
+	return 0;
+}
+
+static void snd_audigy2nx_proc_read(snd_info_entry_t *entry,
+				    snd_info_buffer_t *buffer)
+{
+	static const struct {
+		int unitid;
+		const char *name;
+	} jacks[] = {
+		{4,  "dig in "},
+		{7,  "line in"},
+		{19, "spk out"},
+		{20, "hph out"},
+	};
+	struct usb_mixer_interface *mixer = entry->private_data;
+	int i, err;
+	u8 buf[3];
+
+	snd_iprintf(buffer, "%s jacks\n\n", mixer->chip->card->shortname);
+	for (i = 0; i < ARRAY_SIZE(jacks); ++i) {
+		snd_iprintf(buffer, "%s: ", jacks[i].name);
+		err = snd_usb_ctl_msg(mixer->chip->dev,
+				      usb_rcvctrlpipe(mixer->chip->dev, 0),
+				      GET_MEM, USB_DIR_IN | USB_TYPE_CLASS |
+				      USB_RECIP_INTERFACE, 0,
+				      jacks[i].unitid << 8, buf, 3, 100);
+		if (err == 3 && buf[0] == 3)
+			snd_iprintf(buffer, "%02x %02x\n", buf[1], buf[2]);
+		else
+			snd_iprintf(buffer, "?\n");
+	}
+}
+
+int snd_usb_create_mixer(snd_usb_audio_t *chip, int ctrlif)
+{
+	static snd_device_ops_t dev_ops = {
+		.dev_free = snd_usb_mixer_dev_free
+	};
+	struct usb_mixer_interface *mixer;
+	int err;
+
+	strcpy(chip->card->mixername, "USB Mixer");
+
+	mixer = kcalloc(1, sizeof(*mixer), GFP_KERNEL);
+	if (!mixer)
+		return -ENOMEM;
+	mixer->chip = chip;
+	mixer->ctrlif = ctrlif;
+#ifdef IGNORE_CTL_ERROR
+	mixer->ignore_ctl_error = 1;
+#endif
+	mixer->id_elems = kcalloc(256, sizeof(*mixer->id_elems), GFP_KERNEL);
+	if (!mixer->id_elems) {
+		kfree(mixer);
+		return -ENOMEM;
+	}
+
+	if ((err = snd_usb_mixer_controls(mixer)) < 0 ||
+	    (err = snd_usb_mixer_status_create(mixer)) < 0)
+		goto _error;
+
+	if ((err = snd_usb_soundblaster_remote_init(mixer)) < 0)
+		goto _error;
+
+	if (mixer->chip->usb_id == USB_ID(0x041e, 0x3020)) {
+		snd_info_entry_t *entry;
+
+		if ((err = snd_audigy2nx_controls_create(mixer)) < 0)
+			goto _error;
+		if (!snd_card_proc_new(chip->card, "audigy2nx", &entry))
+			snd_info_set_text_ops(entry, mixer, 1024,
+					      snd_audigy2nx_proc_read);
+	}
+
+	err = snd_device_new(chip->card, SNDRV_DEV_LOWLEVEL, mixer, &dev_ops);
+	if (err < 0)
+		goto _error;
+	list_add(&mixer->list, &chip->mixer_list);
+	return 0;
+
+_error:
+	snd_usb_mixer_free(mixer);
+	return err;
+}
+
+void snd_usb_mixer_disconnect(struct list_head *p)
+{
+	struct usb_mixer_interface *mixer;
+	
+	mixer = list_entry(p, struct usb_mixer_interface, list);
+	if (mixer->urb)
+		usb_kill_urb(mixer->urb);
+	if (mixer->rc_urb)
+		usb_kill_urb(mixer->rc_urb);
+}
diff --git a/sound/usb/usbmixer_maps.c b/sound/usb/usbmixer_maps.c
--- a/sound/usb/usbmixer_maps.c
+++ b/sound/usb/usbmixer_maps.c
@@ -26,10 +26,16 @@ struct usbmix_name_map {
 	int control;
 };
 
+struct usbmix_selector_map {
+	int id;
+	int count;
+	const char **names;
+};
+
 struct usbmix_ctl_map {
-	int vendor;
-	int product;
+	u32 id;
 	const struct usbmix_name_map *map;
+	const struct usbmix_selector_map *selector_map;
 	int ignore_ctl_error;
 };
 
@@ -91,6 +97,96 @@ static struct usbmix_name_map extigy_map
 	{ 0 } /* terminator */
 };
 
+/* Sound Blaster MP3+ controls mapping
+ * The default mixer channels have totally misleading names,
+ * e.g. no Master and fake PCM volume
+ *			Pavel Mihaylov <bin@bash.info>
+ */
+static struct usbmix_name_map mp3plus_map[] = {
+	/* 1: IT pcm */
+	/* 2: IT mic */
+	/* 3: IT line */
+	/* 4: IT digital in */
+	/* 5: OT digital out */
+	/* 6: OT speaker */
+	/* 7: OT pcm capture */
+	{ 8, "Capture Input Source" }, /* FU, default PCM Capture Source */
+		/* (Mic, Input 1 = Line input, Input 2 = Optical input) */
+	{ 9, "Master Playback" }, /* FU, default Speaker 1 */
+	/* { 10, "Mic Capture", 1 }, */ /* FU, Mic Capture */
+	/* { 10, "Mic Capture", 2 }, */ /* FU, Mic Capture */
+	{ 10, "Mic Boost", 7 }, /* FU, default Auto Gain Input */
+	{ 11, "Line Capture" }, /* FU, default PCM Capture */
+	{ 12, "Digital In Playback" }, /* FU, default PCM 1 */
+	/* { 13, "Mic Playback" }, */ /* FU, default Mic Playback */
+	{ 14, "Line Playback" }, /* FU, default Speaker */
+	/* 15: MU */
+	{ 0 } /* terminator */
+};
+
+/* Topology of SB Audigy 2 NX
+
+          +----------------------------->EU[27]--+
+          |                                      v
+          | +----------------------------------->SU[29]---->FU[22]-->Dig_OUT[24]
+          | |                                    ^
+USB_IN[1]-+------------+              +->EU[17]->+->FU[11]-+
+            |          v              |          v         |
+Dig_IN[4]---+->FU[6]-->MU[16]->FU[18]-+->EU[21]->SU[31]----->FU[30]->Hph_OUT[20]
+            |          ^              |                    |
+Lin_IN[7]-+--->FU[8]---+              +->EU[23]->FU[28]------------->Spk_OUT[19]
+          | |                                              v
+          +--->FU[12]------------------------------------->SU[14]--->USB_OUT[15]
+            |                                              ^
+            +->FU[13]--------------------------------------+
+*/
+static struct usbmix_name_map audigy2nx_map[] = {
+	/* 1: IT pcm playback */
+	/* 4: IT digital in */
+	{ 6, "Digital In Playback" }, /* FU */
+	/* 7: IT line in */
+	{ 8, "Line Playback" }, /* FU */
+	{ 11, "What-U-Hear Capture" }, /* FU */
+	{ 12, "Line Capture" }, /* FU */
+	{ 13, "Digital In Capture" }, /* FU */
+	{ 14, "Capture Source" }, /* SU */
+	/* 15: OT pcm capture */
+	/* 16: MU w/o controls */
+	{ 17, NULL }, /* DISABLED: EU (for what?) */
+	{ 18, "Master Playback" }, /* FU */
+	/* 19: OT speaker */
+	/* 20: OT headphone */
+	{ 21, NULL }, /* DISABLED: EU (for what?) */
+	{ 22, "Digital Out Playback" }, /* FU */
+	{ 23, NULL }, /* DISABLED: EU (for what?) */
+	/* 24: OT digital out */
+	{ 27, NULL }, /* DISABLED: EU (for what?) */
+	{ 28, "Speaker Playback" }, /* FU */
+	{ 29, "Digital Out Source" }, /* SU */
+	{ 30, "Headphone Playback" }, /* FU */
+	{ 31, "Headphone Source" }, /* SU */
+	{ 0 } /* terminator */
+};
+
+static struct usbmix_selector_map audigy2nx_selectors[] = {
+	{
+		.id = 14, /* Capture Source */
+		.count = 3,
+		.names = (const char*[]) {"Line", "Digital In", "What-U-Hear"}
+	},
+	{
+		.id = 29, /* Digital Out Source */
+		.count = 3,
+		.names = (const char*[]) {"Front", "PCM", "Digital In"}
+	},
+	{
+		.id = 31, /* Headphone Source */
+		.count = 2,
+		.names = (const char*[]) {"Front", "Side"}
+	},
+	{ 0 } /* terminator */
+};
+
 /* LineX FM Transmitter entry - needed to bypass controls bug */
 static struct usbmix_name_map linex_map[] = {
 	/* 1: IT pcm */
@@ -127,9 +223,29 @@ static struct usbmix_name_map justlink_m
  */
 
 static struct usbmix_ctl_map usbmix_ctl_maps[] = {
-	{ 0x41e, 0x3000, extigy_map, 1 },
-	{ 0x8bb, 0x2702, linex_map, 1 },
-	{ 0xc45, 0x1158, justlink_map, 0 },
+	{
+		.id = USB_ID(0x041e, 0x3000),
+		.map = extigy_map,
+		.ignore_ctl_error = 1,
+	},
+	{
+		.id = USB_ID(0x041e, 0x3010),
+		.map = mp3plus_map,
+	},
+	{
+		.id = USB_ID(0x041e, 0x3020),
+		.map = audigy2nx_map,
+		.selector_map = audigy2nx_selectors,
+	},
+	{
+		.id = USB_ID(0x08bb, 0x2702),
+		.map = linex_map,
+		.ignore_ctl_error = 1,
+	},
+	{
+		.id = USB_ID(0x0c45, 0x1158),
+		.map = justlink_map,
+	},
 	{ 0 } /* terminator */
 };
 
diff --git a/sound/usb/usbquirks.h b/sound/usb/usbquirks.h
--- a/sound/usb/usbquirks.h
+++ b/sound/usb/usbquirks.h
@@ -116,6 +116,7 @@ YAMAHA_DEVICE(0x1039, NULL),
 YAMAHA_DEVICE(0x103a, NULL),
 YAMAHA_DEVICE(0x103b, NULL),
 YAMAHA_DEVICE(0x103c, NULL),
+YAMAHA_DEVICE(0x103d, NULL),
 YAMAHA_DEVICE(0x2000, "DGP-7"),
 YAMAHA_DEVICE(0x2001, "DGP-5"),
 YAMAHA_DEVICE(0x2002, NULL),
@@ -203,11 +204,28 @@ YAMAHA_DEVICE(0x7010, "UB99"),
 	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
 		.vendor_name = "EDIROL",
 		.product_name = "UM-4",
-		.ifnum = 2,
-		.type = QUIRK_MIDI_FIXED_ENDPOINT,
-		.data = & (const snd_usb_midi_endpoint_info_t) {
-			.out_cables = 0x000f,
-			.in_cables  = 0x000f
+		.ifnum = QUIRK_ANY_INTERFACE,
+		.type = QUIRK_COMPOSITE,
+		.data = (const snd_usb_audio_quirk_t[]) {
+			{
+				.ifnum = 0,
+				.type = QUIRK_IGNORE_INTERFACE
+			},
+			{
+				.ifnum = 1,
+				.type = QUIRK_IGNORE_INTERFACE
+			},
+			{
+				.ifnum = 2,
+				.type = QUIRK_MIDI_FIXED_ENDPOINT,
+				.data = & (const snd_usb_midi_endpoint_info_t) {
+					.out_cables = 0x000f,
+					.in_cables  = 0x000f
+				}
+			},
+			{
+				.ifnum = -1
+			}
 		}
 	}
 },
@@ -216,11 +234,28 @@ YAMAHA_DEVICE(0x7010, "UB99"),
 	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
 		.vendor_name = "Roland",
 		.product_name = "SC-8850",
-		.ifnum = 2,
-		.type = QUIRK_MIDI_FIXED_ENDPOINT,
-		.data = & (const snd_usb_midi_endpoint_info_t) {
-			.out_cables = 0x003f,
-			.in_cables  = 0x003f
+		.ifnum = QUIRK_ANY_INTERFACE,
+		.type = QUIRK_COMPOSITE,
+		.data = (const snd_usb_audio_quirk_t[]) {
+			{
+				.ifnum = 0,
+				.type = QUIRK_IGNORE_INTERFACE
+			},
+			{
+				.ifnum = 1,
+				.type = QUIRK_IGNORE_INTERFACE
+			},
+			{
+				.ifnum = 2,
+				.type = QUIRK_MIDI_FIXED_ENDPOINT,
+				.data = & (const snd_usb_midi_endpoint_info_t) {
+					.out_cables = 0x003f,
+					.in_cables  = 0x003f
+				}
+			},
+			{
+				.ifnum = -1
+			}
 		}
 	}
 },
@@ -229,11 +264,28 @@ YAMAHA_DEVICE(0x7010, "UB99"),
 	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
 		.vendor_name = "Roland",
 		.product_name = "U-8",
-		.ifnum = 2,
-		.type = QUIRK_MIDI_FIXED_ENDPOINT,
-		.data = & (const snd_usb_midi_endpoint_info_t) {
-			.out_cables = 0x0005,
-			.in_cables  = 0x0005
+		.ifnum = QUIRK_ANY_INTERFACE,
+		.type = QUIRK_COMPOSITE,
+		.data = (const snd_usb_audio_quirk_t[]) {
+			{
+				.ifnum = 0,
+				.type = QUIRK_IGNORE_INTERFACE
+			},
+			{
+				.ifnum = 1,
+				.type = QUIRK_IGNORE_INTERFACE
+			},
+			{
+				.ifnum = 2,
+				.type = QUIRK_MIDI_FIXED_ENDPOINT,
+				.data = & (const snd_usb_midi_endpoint_info_t) {
+					.out_cables = 0x0005,
+					.in_cables  = 0x0005
+				}
+			},
+			{
+				.ifnum = -1
+			}
 		}
 	}
 },
@@ -242,11 +294,28 @@ YAMAHA_DEVICE(0x7010, "UB99"),
 	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
 		.vendor_name = "EDIROL",
 		.product_name = "UM-2",
-		.ifnum = 2,
-		.type = QUIRK_MIDI_FIXED_ENDPOINT,
-		.data = & (const snd_usb_midi_endpoint_info_t) {
-			.out_cables = 0x0003,
-			.in_cables  = 0x0003
+		.ifnum = QUIRK_ANY_INTERFACE,
+		.type = QUIRK_COMPOSITE,
+		.data = (const snd_usb_audio_quirk_t[]) {
+			{
+				.ifnum = 0,
+				.type = QUIRK_IGNORE_INTERFACE
+			},
+			{
+				.ifnum = 1,
+				.type = QUIRK_IGNORE_INTERFACE
+			},
+			{
+				.ifnum = 2,
+				.type = QUIRK_MIDI_FIXED_ENDPOINT,
+				.data = & (const snd_usb_midi_endpoint_info_t) {
+					.out_cables = 0x0003,
+					.in_cables  = 0x0003
+				}
+			},
+			{
+				.ifnum = -1
+			}
 		}
 	}
 },
@@ -255,11 +324,28 @@ YAMAHA_DEVICE(0x7010, "UB99"),
 	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
 		.vendor_name = "Roland",
 		.product_name = "SC-8820",
-		.ifnum = 2,
-		.type = QUIRK_MIDI_FIXED_ENDPOINT,
-		.data = & (const snd_usb_midi_endpoint_info_t) {
-			.out_cables = 0x0013,
-			.in_cables  = 0x0013
+		.ifnum = QUIRK_ANY_INTERFACE,
+		.type = QUIRK_COMPOSITE,
+		.data = (const snd_usb_audio_quirk_t[]) {
+			{
+				.ifnum = 0,
+				.type = QUIRK_IGNORE_INTERFACE
+			},
+			{
+				.ifnum = 1,
+				.type = QUIRK_IGNORE_INTERFACE
+			},
+			{
+				.ifnum = 2,
+				.type = QUIRK_MIDI_FIXED_ENDPOINT,
+				.data = & (const snd_usb_midi_endpoint_info_t) {
+					.out_cables = 0x0013,
+					.in_cables  = 0x0013
+				}
+			},
+			{
+				.ifnum = -1
+			}
 		}
 	}
 },
@@ -268,11 +354,28 @@ YAMAHA_DEVICE(0x7010, "UB99"),
 	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
 		.vendor_name = "Roland",
 		.product_name = "PC-300",
-		.ifnum = 2,
-		.type = QUIRK_MIDI_FIXED_ENDPOINT,
-		.data = & (const snd_usb_midi_endpoint_info_t) {
-			.out_cables = 0x0001,
-			.in_cables  = 0x0001
+		.ifnum = QUIRK_ANY_INTERFACE,
+		.type = QUIRK_COMPOSITE,
+		.data = (const snd_usb_audio_quirk_t[]) {
+			{
+				.ifnum = 0,
+				.type = QUIRK_IGNORE_INTERFACE
+			},
+			{
+				.ifnum = 1,
+				.type = QUIRK_IGNORE_INTERFACE
+			},
+			{
+				.ifnum = 2,
+				.type = QUIRK_MIDI_FIXED_ENDPOINT,
+				.data = & (const snd_usb_midi_endpoint_info_t) {
+					.out_cables = 0x0001,
+					.in_cables  = 0x0001
+				}
+			},
+			{
+				.ifnum = -1
+			}
 		}
 	}
 },
@@ -281,11 +384,28 @@ YAMAHA_DEVICE(0x7010, "UB99"),
 	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
 		.vendor_name = "EDIROL",
 		.product_name = "UM-1",
-		.ifnum = 2,
-		.type = QUIRK_MIDI_FIXED_ENDPOINT,
-		.data = & (const snd_usb_midi_endpoint_info_t) {
-			.out_cables = 0x0001,
-			.in_cables  = 0x0001
+		.ifnum = QUIRK_ANY_INTERFACE,
+		.type = QUIRK_COMPOSITE,
+		.data = (const snd_usb_audio_quirk_t[]) {
+			{
+				.ifnum = 0,
+				.type = QUIRK_IGNORE_INTERFACE
+			},
+			{
+				.ifnum = 1,
+				.type = QUIRK_IGNORE_INTERFACE
+			},
+			{
+				.ifnum = 2,
+				.type = QUIRK_MIDI_FIXED_ENDPOINT,
+				.data = & (const snd_usb_midi_endpoint_info_t) {
+					.out_cables = 0x0001,
+					.in_cables  = 0x0001
+				}
+			},
+			{
+				.ifnum = -1
+			}
 		}
 	}
 },
@@ -294,11 +414,28 @@ YAMAHA_DEVICE(0x7010, "UB99"),
 	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
 		.vendor_name = "Roland",
 		.product_name = "SK-500",
-		.ifnum = 2,
-		.type = QUIRK_MIDI_FIXED_ENDPOINT,
-		.data = & (const snd_usb_midi_endpoint_info_t) {
-			.out_cables = 0x0013,
-			.in_cables  = 0x0013
+		.ifnum = QUIRK_ANY_INTERFACE,
+		.type = QUIRK_COMPOSITE,
+		.data = (const snd_usb_audio_quirk_t[]) {
+			{
+				.ifnum = 0,
+				.type = QUIRK_IGNORE_INTERFACE
+			},
+			{
+				.ifnum = 1,
+				.type = QUIRK_IGNORE_INTERFACE
+			},
+			{
+				.ifnum = 2,
+				.type = QUIRK_MIDI_FIXED_ENDPOINT,
+				.data = & (const snd_usb_midi_endpoint_info_t) {
+					.out_cables = 0x0013,
+					.in_cables  = 0x0013
+				}
+			},
+			{
+				.ifnum = -1
+			}
 		}
 	}
 },
@@ -421,11 +558,28 @@ YAMAHA_DEVICE(0x7010, "UB99"),
 	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
 		.vendor_name = "EDIROL",
 		.product_name = "SD-90",
-		.ifnum = 2,
-		.type = QUIRK_MIDI_FIXED_ENDPOINT,
-		.data = & (const snd_usb_midi_endpoint_info_t) {
-			.out_cables = 0x000f,
-			.in_cables  = 0x000f
+		.ifnum = QUIRK_ANY_INTERFACE,
+		.type = QUIRK_COMPOSITE,
+		.data = (const snd_usb_audio_quirk_t[]) {
+			{
+				.ifnum = 0,
+				.type = QUIRK_IGNORE_INTERFACE
+			},
+			{
+				.ifnum = 1,
+				.type = QUIRK_IGNORE_INTERFACE
+			},
+			{
+				.ifnum = 2,
+				.type = QUIRK_MIDI_FIXED_ENDPOINT,
+				.data = & (const snd_usb_midi_endpoint_info_t) {
+					.out_cables = 0x000f,
+					.in_cables  = 0x000f
+				}
+			},
+			{
+				.ifnum = -1
+			}
 		}
 	}
 },
@@ -434,11 +588,28 @@ YAMAHA_DEVICE(0x7010, "UB99"),
 	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
 		.vendor_name = "Roland",
 		.product_name = "MMP-2",
-		.ifnum = 2,
-		.type = QUIRK_MIDI_FIXED_ENDPOINT,
-		.data = & (const snd_usb_midi_endpoint_info_t) {
-			.out_cables = 0x0001,
-			.in_cables  = 0x0001
+		.ifnum = QUIRK_ANY_INTERFACE,
+		.type = QUIRK_COMPOSITE,
+		.data = (const snd_usb_audio_quirk_t[]) {
+			{
+				.ifnum = 0,
+				.type = QUIRK_IGNORE_INTERFACE
+			},
+			{
+				.ifnum = 1,
+				.type = QUIRK_IGNORE_INTERFACE
+			},
+			{
+				.ifnum = 2,
+				.type = QUIRK_MIDI_FIXED_ENDPOINT,
+				.data = & (const snd_usb_midi_endpoint_info_t) {
+					.out_cables = 0x0001,
+					.in_cables  = 0x0001
+				}
+			},
+			{
+				.ifnum = -1
+			}
 		}
 	}
 },
@@ -609,15 +780,33 @@ YAMAHA_DEVICE(0x7010, "UB99"),
 	}
 },
 {
+	/*
+	 * This quirk is for the "Advanced Driver" mode.  If off, the GS-10
+	 * has ID 0x003c and is standard compliant, but has only 16-bit PCM
+	 * and no MIDI.
+	 */
 	USB_DEVICE_VENDOR_SPEC(0x0582, 0x003b),
 	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
 		.vendor_name = "BOSS",
 		.product_name = "GS-10",
-		.ifnum = 3,
-		.type = QUIRK_MIDI_FIXED_ENDPOINT,
-		.data = & (const snd_usb_midi_endpoint_info_t) {
-			.out_cables = 0x0003,
-			.in_cables  = 0x0003
+		.ifnum = QUIRK_ANY_INTERFACE,
+		.type = QUIRK_COMPOSITE,
+		.data = & (const snd_usb_audio_quirk_t[]) {
+			{
+				.ifnum = 1,
+				.type = QUIRK_AUDIO_STANDARD_INTERFACE
+			},
+			{
+				.ifnum = 2,
+				.type = QUIRK_AUDIO_STANDARD_INTERFACE
+			},
+			{
+				.ifnum = 3,
+				.type = QUIRK_MIDI_STANDARD_INTERFACE
+			},
+			{
+				.ifnum = -1
+			}
 		}
 	}
 },
@@ -1071,7 +1260,12 @@ YAMAHA_DEVICE(0x7010, "UB99"),
 /* Mark of the Unicorn devices */
 {
 	/* thanks to Robert A. Lerche <ral 'at' msbit.com> */
-	USB_DEVICE(0x07fd, 0x0001),
+	.match_flags = USB_DEVICE_ID_MATCH_VENDOR |
+		       USB_DEVICE_ID_MATCH_PRODUCT |
+		       USB_DEVICE_ID_MATCH_DEV_SUBCLASS,
+	.idVendor = 0x07fd,
+	.idProduct = 0x0001,
+	.bDeviceSubClass = 2,
 	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
 		.vendor_name = "MOTU",
 		.product_name = "Fastlane",
@@ -1080,7 +1274,7 @@ YAMAHA_DEVICE(0x7010, "UB99"),
 		.data = & (const snd_usb_audio_quirk_t[]) {
 			{
 				.ifnum = 0,
-				.type = QUIRK_MIDI_MOTU
+				.type = QUIRK_MIDI_RAW
 			},
 			{
 				.ifnum = 1,
@@ -1185,6 +1379,25 @@ YAMAHA_DEVICE(0x7010, "UB99"),
 },
 
 {
+	USB_DEVICE(0x4752, 0x0011),
+	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+		.vendor_name = "Miditech",
+		.product_name = "Midistart-2",
+		.ifnum = 0,
+		.type = QUIRK_MIDI_MIDITECH
+	}
+},
+{
+	USB_DEVICE(0x7104, 0x2202),
+	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+		.vendor_name = "Miditech",
+		.product_name = "MidiStudio-2",
+		.ifnum = 0,
+		.type = QUIRK_MIDI_MIDITECH
+	}
+},
+
+{
 	/*
 	 * Some USB MIDI devices don't have an audio control interface,
 	 * so we have to grab MIDI streaming interfaces here.
diff --git a/sound/usb/usx2y/usX2Yhwdep.c b/sound/usb/usx2y/usX2Yhwdep.c
--- a/sound/usb/usx2y/usX2Yhwdep.c
+++ b/sound/usb/usx2y/usX2Yhwdep.c
@@ -232,8 +232,7 @@ static int snd_usX2Y_hwdep_dsp_load(snd_
 	if (err)
 		return err;
 	if (dsp->index == 1) {
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(HZ/4);			// give the device some time 
+		msleep(250);				// give the device some time
 		err = usX2Y_AsyncSeq04_init(priv);
 		if (err) {
 			snd_printk("usX2Y_AsyncSeq04_init error \n");
diff --git a/sound/usb/usx2y/usbusx2y.c b/sound/usb/usx2y/usbusx2y.c
--- a/sound/usb/usx2y/usbusx2y.c
+++ b/sound/usb/usx2y/usbusx2y.c
@@ -442,7 +442,7 @@ static void usX2Y_usb_disconnect(struct 
 		snd_card_disconnect((snd_card_t*)ptr);
 		/* release the midi resources */
 		list_for_each(p, &usX2Y->chip.midi_list) {
-			snd_usbmidi_disconnect(p, &snd_usX2Y_usb_driver);
+			snd_usbmidi_disconnect(p);
 		}
 		if (usX2Y->us428ctls_sharedmem) 
 			wake_up(&usX2Y->us428ctls_wait_queue_head);
diff --git a/sound/usb/usx2y/usbusx2yaudio.c b/sound/usb/usx2y/usbusx2yaudio.c
--- a/sound/usb/usx2y/usbusx2yaudio.c
+++ b/sound/usb/usx2y/usbusx2yaudio.c
@@ -401,10 +401,8 @@ static void usX2Y_urbs_release(snd_usX2Y
 	for (i = 0; i < NRURBS; i++)
 		usX2Y_urb_release(subs->urb + i, subs != subs->usX2Y->subs[SNDRV_PCM_STREAM_PLAYBACK]);
 
-	if (subs->tmpbuf) {
-		kfree(subs->tmpbuf);
-		subs->tmpbuf = NULL;
-	}
+	kfree(subs->tmpbuf);
+	subs->tmpbuf = NULL;
 }
 /*
  * initialize a substream's urbs
diff --git a/sound/usb/usx2y/usx2yhwdeppcm.c b/sound/usb/usx2y/usx2yhwdeppcm.c
--- a/sound/usb/usx2y/usx2yhwdeppcm.c
+++ b/sound/usb/usx2y/usx2yhwdeppcm.c
@@ -50,6 +50,7 @@
    Currently rawusb dma pcm buffer transport (this file) is only available to snd-usb-usx2y. 
 */
 
+#include <linux/delay.h>
 #include "usbusx2yaudio.c"
 
 #if defined(USX2Y_NRPACKS_VARIABLE) || (!defined(USX2Y_NRPACKS_VARIABLE) &&  USX2Y_NRPACKS == 1)
@@ -520,11 +521,8 @@ static int snd_usX2Y_usbpcm_prepare(snd_
 		usX2Y->hwdep_pcm_shm->playback_iso_start = -1;
 		if (atomic_read(&subs->state) < state_PREPARED) {
 			while (usX2Y_iso_frames_per_buffer(runtime, usX2Y) > usX2Y->hwdep_pcm_shm->captured_iso_frames) {
-				signed long timeout;
 				snd_printd("Wait: iso_frames_per_buffer=%i,captured_iso_frames=%i\n", usX2Y_iso_frames_per_buffer(runtime, usX2Y), usX2Y->hwdep_pcm_shm->captured_iso_frames);
-				set_current_state(TASK_INTERRUPTIBLE);
-				timeout = schedule_timeout(HZ/100 + 1);
-				if (signal_pending(current)) {
+				if (msleep_interruptible(10)) {
 					err = -ERESTARTSYS;
 					goto up_prepare_mutex;
 				}
